diff --git a/.ci/create-changes-html.sh b/.ci/create-changes-html.sh index 80335ea1613..0e80d0d2814 100755 --- a/.ci/create-changes-html.sh +++ b/.ci/create-changes-html.sh @@ -1,11 +1,12 @@ #!/bin/sh if [ $# != 2 ]; then - echo >&2 "usage: $0 BASE_DOC_COMMIT DOC_REPO" - echo >&2 "creates CHANGES.html in the current directory" - echo >&2 "for the diffs of DOC_REPO against BASE_DOC_COMMIT" + echo >&2 "Usage: $0 DIFF_TEXT DOC_REPO" + echo >&2 "This script generates a CHANGES.html file in the current directory" + echo >&2 "and adds anchor targets in the documents within DOC_REPO" + echo >&2 "based on the diff hunks in the DIFF_TEXT file." exit 1 fi -BASE_DOC_COMMIT="$1" +DIFF_TEXT="$1" DOC_REPOSITORY="$2" # Create CHANGES.html @@ -24,26 +25,27 @@ const diffSite = 'https://pianomister.github.io/diffsite' const diffParagraphs = document.querySelectorAll('p.diff'); diffParagraphs.forEach(paragraph => { const rootURL = window.location.origin; - const docAnchor = paragraph.querySelector('a'); // first "a" element + const docAnchor = paragraph.querySelector('a'); const url = new URL(docAnchor.href); const path = url.pathname; const anchor = document.createElement('a'); anchor.href = diffSite + '/?url1=' + rootURL + path + '&url2=' + baseDocURL + path; anchor.textContent = 'compare with the base'; anchor.setAttribute('target', '_blank'); + paragraph.innerHTML += '  '; paragraph.appendChild(anchor); - paragraph.innerHTML += ' '; - const hunkAnchors = paragraph.querySelectorAll('a.hunk'); - hunkAnchors.forEach(hunkAnchor => { + const hunks = paragraph.parentNode.querySelectorAll('p.hunk'); + hunks.forEach(hunk => { + const hunkAnchor = hunk.querySelector('a'); const url = new URL(hunkAnchor.href); const path = url.pathname; const pathHash = path + url.hash.replace('#', '%23'); const anchor = document.createElement('a'); anchor.href = diffSite + '/?url1=' + rootURL + pathHash + '&url2=' + baseDocURL + path; - anchor.textContent = hunkAnchor.textContent; + anchor.textContent = 'compare with the base'; anchor.setAttribute('target', '_blank'); - paragraph.appendChild(anchor); - paragraph.innerHTML += ' '; + hunk.innerHTML += '  '; + hunk.appendChild(anchor); }); }); }); @@ -51,42 +53,62 @@ diffParagraphs.forEach(paragraph => { EOF echo '' >> CHANGES.html echo '' >> CHANGES.html -(cd $DOC_REPOSITORY && git diff $BASE_DOC_COMMIT -- "*.html") > diff.txt python3 - << EOF import os, re, html -with open('diff.txt', 'r') as f: +from itertools import chain +with open('$DIFF_TEXT', 'r') as f: diff_text = f.read() diff_blocks = re.split(r'^(?=diff --git)', diff_text, flags=re.MULTILINE) out_blocks = [] for block in diff_blocks: match = re.search(r'^diff --git a/(.*) b/\1', block, flags=re.MULTILINE) if match: - doc = match.group(1) - file_path = os.path.join('$DOC_REPOSITORY', doc) + path = match.group(1) + file_path = os.path.join('$DOC_REPOSITORY', path) try: with open(file_path, 'r') as file: content = file.readlines() except FileNotFoundError: content = [] count = 0 + hunks = [] + hunk_lines = [] + in_hunk = False for line in block.splitlines(): if line.startswith('@@ -'): + if hunk_lines: + hunks.append('
'
+                                 + html.escape('\n'.join(hunk_lines)).strip()
+                                 + '
') + hunk_lines = [] search_result = re.search(r'@@ -(\d+),(\d+) \+(\d+),(\d+)', line) if search_result: - line_number = int(search_result.group(3)) - for i in range(line_number - 1, -1, -1): - if content[i].startswith('<'): + line_number = int(search_result.group(3)) - 1 + span = int(search_result.group(4)) + for i in chain(range(line_number, line_number + span), range(line_number - 1, -1, -1)): + try: + ln = content[i] + except IndexError: + continue + for idx, char in enumerate(ln): + if not char.isspace(): + break + else: + idx = len(ln) + if ln.startswith('<', idx) and not ln.startswith('' + content[i] + content[i] = ln[:idx] + f'' + ln[idx:] + hunks.append(f'

hunk #{count}

') break + hunk_lines.append(line) + if hunk_lines: + hunks.append('
'
+                          + html.escape('\n'.join(hunk_lines)).strip()
+                          + '
') if content: with open(file_path, 'w') as file: file.writelines(content) - path = doc - hunks = ' '.join(f'#{i + 1}' for i in range(count)) - out_blocks.append(f'

{doc} ' + hunks + ' 

' - + '\n
'
-                            + html.escape(block).strip() + '
') + out_blocks.append(f'

{path}

\n' + '\n'.join(hunks) + '\n
') output_text = '\n'.join(out_blocks) with open('diff.html', 'w') as f: f.write(output_text) @@ -94,4 +116,4 @@ EOF cat diff.html >> CHANGES.html echo '' >> CHANGES.html echo '' >> CHANGES.html -rm diff.txt diff.html +rm diff.html diff --git a/.ci/retrofit-worktree.sh b/.ci/retrofit-worktree.sh index 4c283f7ff4a..782d3ba44b7 100755 --- a/.ci/retrofit-worktree.sh +++ b/.ci/retrofit-worktree.sh @@ -43,4 +43,4 @@ git worktree add --detach $WORKTREE_NAME rm -rf $WORKTREE_DIRECTORY/.git && mv $WORKTREE_NAME/.git $WORKTREE_DIRECTORY/ rm -rf $WORKTREE_NAME && ln -s $WORKTREE_DIRECTORY $WORKTREE_NAME if [ ! -f $WORKTREE_NAME/.gitignore ]; then cp .gitignore $WORKTREE_NAME/; fi -(cd $WORKTREE_NAME && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git checkout new && git status) +(cd $WORKTREE_NAME && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git checkout -f new && git clean -fd && git status) diff --git a/.ci/set_labels_by_changes.sh b/.ci/set_labels_by_changes.sh deleted file mode 100644 index d71444014dc..00000000000 --- a/.ci/set_labels_by_changes.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash - -# cd to the PR directory -cd $PR_MOUNT_DIR -PR_BASE_SHA=$(git merge-base $BASE_SHA $PR_HEAD_SHA) - -echo "set_labels_by_changes.sh called with environment:" -echo "BASE SHA: $PR_BASE_SHA" -echo "HEAD SHA: $PR_HEAD_SHA" -echo "SMALL THRESHOLD $SMALL_THRESHOLD" -echo "MODERATE THERESHOLD: $MODERATE_THRESHOLD" -echo "LARGE THRESHOLD: $LARGE_THRESHOLD" - -# get all the changes made and changed files -CHANGES=$(git diff --ignore-all-space $PR_BASE_SHA $PR_HEAD_SHA) - -# ignore blank lines -CHANGES=$(echo "$CHANGES" | grep -vE '^[\+\-]\s*$') - -# ignore non necessary lines from git diff -CHANGES=$(echo "$CHANGES" | grep -E '^[+\-]' | grep -vE '^\+\+\+|^\-\-\-') - -# count total no of lines -CHANGES=$(echo "$CHANGES" | wc -l) - -echo "CHANGES MADE: $CHANGES" - -AUTH_HEADER="Authorization: Bearer $GITHUB_TOKEN" - -MINIMAL="v: minimal" -SMALL="v: small" -MODERATE="v: moderate" -LARGE="v: large" - -DELETE_LABELS=("$MINIMAL" "$SMALL" "$MODERATE" "$LARGE") - -if [ "$CHANGES" -gt "$LARGE_THRESHOLD" ]; then - SIZE_LABEL="$LARGE" -elif [ "$CHANGES" -gt "$MODERATE_THRESHOLD" ]; then - SIZE_LABEL="$MODERATE" -elif [ "$CHANGES" -gt "$SMALL_THRESHOLD" ]; then - SIZE_LABEL="$SMALL" -else - SIZE_LABEL="$MINIMAL" -fi - -DELETE_LABELS=("${DELETE_LABELS[@]//${SIZE_LABEL}/}") - -# API for adding labels on the Pull Request -API_URL="https://api.github.com/repos/$REPOSITORY/issues/$PR_NUMBER/labels" - -echo "Adding label: ${SIZE_LABEL[@]}" -for LABEL in "${SIZE_LABEL[@]}"; do - curl -X POST \ - -H "$AUTH_HEADER" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -d "{\"labels\":[\"$LABEL\"]}" \ - "$API_URL" >/dev/null -done - -echo "Deleting Labels:" - -for DELETE_LABEL in "${DELETE_LABELS[@]}"; do - ENCODED_LABEL=$(echo "$DELETE_LABEL" | sed 's/ /%20/g') - curl -X DELETE \ - -H "Accept: application/vnd.github+json" \ - -H "$AUTH_HEADER" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "$API_URL/$ENCODED_LABEL" >/dev/null -done diff --git a/.ci/write-dockerfile.sh b/.ci/write-dockerfile.sh index 3a4ae5b152d..cfd4fb20810 100755 --- a/.ci/write-dockerfile.sh +++ b/.ci/write-dockerfile.sh @@ -35,7 +35,7 @@ STRIP_COMMENTS="sed s/#.*//;" SAGE_ROOT=. export PATH="$SAGE_ROOT"/build/bin:$PATH SYSTEM_PACKAGES=$EXTRA_SYSTEM_PACKAGES -SYSTEM_CONFIGURE_ARGS="--enable-option-checking " +SYSTEM_CONFIGURE_ARGS=" --enable-option-checking" for SPKG in $(sage-package list --has-file=spkg-configure.m4 $SAGE_PACKAGE_LIST_ARGS) $EXTRA_SAGE_PACKAGES; do SYSTEM_PACKAGE=$(sage-get-system-packages $SYSTEM $SPKG) if [ -n "${SYSTEM_PACKAGE}" ]; then @@ -45,17 +45,24 @@ for SPKG in $(sage-package list --has-file=spkg-configure.m4 $SAGE_PACKAGE_LIST_ # shell-quote package if necessary SYSTEM_PACKAGES+=$(printf " %q" "$a") done - SYSTEM_CONFIGURE_ARGS+="--with-system-${SPKG}=${WITH_SYSTEM_SPKG} " + # Check if SPKG is not a dummy package + if [[ $SPKG != _* ]]; then + SYSTEM_CONFIGURE_ARGS+=" --with-system-${SPKG}=${WITH_SYSTEM_SPKG}" + fi fi done echo "# Automatically generated by SAGE_ROOT/.ci/write-dockerfile.sh" echo "# the :comments: separate the generated file into sections" echo "# to simplify writing scripts that customize this file" -ADD="ADD $__CHOWN" +if [ -z "$__CHOWN" ]; then + ADD="ADD" +else + ADD="ADD $__CHOWN" +fi RUN=RUN cat < /dev/null; then \ - (yes | unminimize) || echo "(ignored)"; \ - rm -f "\$(command -v unminimize)"; \ - fi +RUN if command -v unminimize > /dev/null; then (yes | unminimize) || echo "(ignored)"; rm -f "\$(command -v unminimize)"; fi EOF if [ -n "$DIST_UPGRADE" ]; then cat <> /sage/.gitignore && \ - printf '/src\n!/src/doc/bootstrap\n!/src/bin\n!/src/*.m4\n!/src/*.toml\n!/src/VERSION.txt\n' >> /new/.gitignore && \ - if ! (cd /new && /.ci/retrofit-worktree.sh worktree-image /sage); then \ - echo "retrofit-worktree.sh failed, falling back to replacing /sage"; \ - for a in local logs; do \ - if [ -d /sage/\$a ]; then mv /sage/\$a /new/; fi; \ - done; \ - rm -rf /sage; \ - mv /new /sage; \ - fi; \ - else \ - mv /new /sage; \ +RUN if [ -d /sage ]; then \\ + echo "### Incremental build from \$(cat /sage/VERSION.txt)" && \\ + printf '/src/*\n!/src/doc/bootstrap\n!/src/bin\n!/src/*.m4\n!/src/*.toml\n!/src/VERSION.txt\n' >> /sage/.gitignore && \\ + printf '/src/*\n!/src/doc/bootstrap\n!/src/bin\n!/src/*.m4\n!/src/*.toml\n!/src/VERSION.txt\n' >> /new/.gitignore && \\ + if ! (cd /new && /.ci/retrofit-worktree.sh worktree-image /sage); then \\ + echo "retrofit-worktree.sh failed, falling back to replacing /sage"; \\ + for a in local logs; do \\ + if [ -d /sage/\$a ]; then mv /sage/\$a /new/; fi; \\ + done; \\ + rm -rf /sage; \\ + mv /new /sage; \\ + fi; \\ + else \\ + mv /new /sage; \\ fi WORKDIR /sage - ARG BOOTSTRAP="${BOOTSTRAP-./bootstrap}" -$RUN sh -x -c "\${BOOTSTRAP}" $ENDRUN $THEN_SAVE_STATUS +$RUN sh -x -c "\${BOOTSTRAP}"$ENDRUN$THEN_SAVE_STATUS -FROM bootstrapped as configured +FROM bootstrapped AS configured #:configuring: -RUN $CHECK_STATUS_THEN mkdir -p logs/pkgs; rm -f config.log; ln -s logs/pkgs/config.log config.log +RUN$CHECK_STATUS_THEN mkdir -p logs/pkgs; rm -f config.log; ln -s logs/pkgs/config.log config.log ARG CONFIGURE_ARGS="${CONFIGURE_ARGS:---enable-build-as-root}" EOF if [ ${WITH_SYSTEM_SPKG} = "force" ]; then cat <> $GITHUB_OUTPUT + echo "build_targets=$uninstall_targets reconfigure $build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT else - echo "build_targets=$build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT + echo "build_targets=$build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT fi cat $GITHUB_OUTPUT + - uses: actions/checkout@v4 with: ref: ${{ github.base_ref }} path: worktree-base if: github.base_ref && steps.changed-files.outputs.pkgs_all_changed_files + - name: Compute metrics run: | export PATH=build/bin:$PATH @@ -140,6 +163,7 @@ jobs: else sage-package metrics :all: fi + - name: Install test prerequisites # From docker.yml run: | @@ -147,6 +171,7 @@ jobs: sudo DEBIAN_FRONTEND=noninteractive apt-get install tox sudo apt-get clean df -h + - name: Merge CI fixes from sagemath/sage # From docker.yml # This step needs to happen after the commit sha is put in DOCKER_TAG @@ -176,7 +201,7 @@ jobs: - name: Build Docker image id: image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: # push and load may not be set together at the moment # @@ -254,9 +279,11 @@ jobs: remove-haskell: true remove-codeql: true remove-docker-images: true + - name: Checkout id: checkout uses: actions/checkout@v4 + - name: Install test prerequisites # From docker.yml run: | @@ -264,6 +291,7 @@ jobs: sudo DEBIAN_FRONTEND=noninteractive apt-get install tox sudo apt-get clean df -h + - name: Merge CI fixes from sagemath/sage # From docker.yml # This step needs to happen after the commit sha is put in DOCKER_TAG @@ -291,7 +319,7 @@ jobs: - name: Build Docker image id: image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: push: true load: false @@ -352,9 +380,11 @@ jobs: remove-haskell: true remove-codeql: true remove-docker-images: true + - name: Checkout id: checkout uses: actions/checkout@v4 + - name: Install test prerequisites # From docker.yml run: | @@ -362,6 +392,7 @@ jobs: sudo DEBIAN_FRONTEND=noninteractive apt-get install tox sudo apt-get clean df -h + - name: Merge CI fixes from sagemath/sage # From docker.yml # This step needs to happen after the commit sha is put in DOCKER_TAG @@ -389,7 +420,7 @@ jobs: - name: Build Docker image id: image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: push: true load: false @@ -442,8 +473,11 @@ jobs: if: (success() || failure()) && steps.container.outcome == 'success' uses: actions/upload-artifact@v4 with: + # The path .coverage is a directory that contains the combined coverage + # data file .coverage, which is a hidden file because of the leading dot name: coverage-${{ steps.copy-coverage.outputs.tests_id }} path: .coverage + include-hidden-files: true coverage-report: runs-on: ubuntu-latest @@ -466,9 +500,11 @@ jobs: remove-haskell: true remove-codeql: true remove-docker-images: true + - name: Checkout id: checkout uses: actions/checkout@v4 + - name: Install test prerequisites # From docker.yml run: | @@ -476,6 +512,7 @@ jobs: sudo DEBIAN_FRONTEND=noninteractive apt-get install tox sudo apt-get clean df -h + - name: Merge CI fixes from sagemath/sage # From docker.yml # This step needs to happen after the commit sha is put in DOCKER_TAG @@ -503,7 +540,7 @@ jobs: - name: Build Docker image id: image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: push: true load: false @@ -530,11 +567,11 @@ jobs: # Combining - name: Download coverage artifacts + if: (success() || failure()) && steps.container.outcome == 'success' uses: actions/download-artifact@v4 with: path: .coverage pattern: coverage-* - if: (success() || failure()) && steps.container.outcome == 'success' - name: Coverage report if: (success() || failure()) && steps.container.outcome == 'success' diff --git a/.github/workflows/ci-linux-incremental.yml b/.github/workflows/ci-linux-incremental.yml index ce468ff3a42..8606e7a4ca5 100644 --- a/.github/workflows/ci-linux-incremental.yml +++ b/.github/workflows/ci-linux-incremental.yml @@ -46,7 +46,7 @@ jobs: - uses: actions/checkout@v4 - name: Get all packages that have changed id: changed-files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@v45 with: files_yaml: | configures: @@ -60,9 +60,9 @@ jobs: uninstall_targets=$(echo $(for a in '' ${{ steps.changed-files.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([a-z0-9][_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u)) build_targets=$(echo $(for a in '' ${{ steps.changed-files.outputs.pkgs_all_changed_files }}; do SPKG=$(echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([a-z0-9][-_.a-z0-9]*)/[^ ]* *,\2,;'); if [ -f "build/pkgs/$SPKG/checksums.ini" -o -f "build/pkgs/$SPKG/requirements.txt" -o -f "build/pkgs/$SPKG/spkg-install" ]; then echo "$SPKG-ensure"; fi; done | sort -u)) if [ -n "$uninstall_targets" ]; then - echo "build_targets=$uninstall_targets reconfigure $build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT + echo "build_targets=$uninstall_targets reconfigure $build_targets" >> $GITHUB_OUTPUT else - echo "build_targets=$build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT + echo "build_targets=$build_targets" >> $GITHUB_OUTPUT fi cat $GITHUB_OUTPUT - uses: actions/checkout@v4 @@ -92,7 +92,7 @@ jobs: from_docker_target: "with-targets" from_docker_tag: "dev" docker_targets: "with-targets" - targets: "${{needs.changed_files.outputs.build_targets}} doc-html ptest-nodoc" + targets: "${{needs.changed_files.outputs.build_targets}} ci-build-with-fallback doc-html ptest-nodoc" tox_system_factors: >- ["ubuntu-focal", "ubuntu-noble", @@ -108,6 +108,29 @@ jobs: docker_push_repository: ghcr.io/${{ github.repository }}/ max_parallel: 8 + constraints_pkgs-norequirements: + needs: [changed_files] + uses: ./.github/workflows/docker.yml + with: + # Build incrementally from published Docker image + incremental: true + free_disk_space: true + from_docker_repository: ghcr.io/sagemath/sage/ + from_docker_target: "with-targets-pre" + from_docker_tag: "dev" + docker_targets: "with-targets-pre" + targets_pre: "${{needs.changed_files.outputs.build_targets}} all-sage-local python3-ensure tox-ensure sagelib-tox-sagepython-constraints_pkgs-norequirements" + tox_system_factors: >- + ["ubuntu-focal", + "ubuntu-noble", + "debian-bookworm", + "fedora-40", + "debian-bullseye-i386"] + tox_packages_factors: >- + ["standard"] + docker_push_repository: ghcr.io/${{ github.repository }}/ + max_parallel: 16 + site: needs: [changed_files] uses: ./.github/workflows/docker.yml @@ -124,7 +147,8 @@ jobs: # with only a small number of test failures as of 10.2.rc0 tox_system_factors: >- ["gentoo-python3.11", - "archlinux-latest"] + "archlinux-latest", + "fedora-40"] tox_packages_factors: >- ["standard-sitepackages"] docker_push_repository: ghcr.io/${{ github.repository }}/ diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 0ce9a1f142b..ca4607e3cc3 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -34,7 +34,7 @@ permissions: jobs: - # standard-pre and standard (without ptest) for the default platform (used by build.yml etc.) + # standard (without ptest) for the default platform (used by build.yml etc.) default: uses: ./.github/workflows/docker.yml with: @@ -54,24 +54,27 @@ jobs: # All platforms. This duplicates the default platform, but why not, # it makes it more robust regarding random timeouts. - standard-pre: + standard: if: ${{ success() || failure() }} uses: ./.github/workflows/docker.yml with: # Build from scratch - docker_targets: "with-system-packages configured with-targets-pre" + free_disk_space: true + docker_targets: "with-system-packages configured with-targets-pre with-targets with-targets-optional" # FIXME: duplicated from env.TARGETS targets_pre: all-sage-local + targets: build doc-html + targets_optional: ptest tox_packages_factors: >- ["standard"] docker_push_repository: ghcr.io/${{ github.repository }}/ - # Make sure that all "standard-pre" jobs can start simultaneously, + # Make sure that all "standard" jobs can start simultaneously, # so that runners are available by the time that "default" starts. max_parallel: 50 - standard: + standard-constraints_pkgs-norequirements: if: ${{ success() || failure() }} - needs: [standard-pre] + needs: [standard] uses: ./.github/workflows/docker.yml with: # Build incrementally from previous stage (pre) @@ -79,20 +82,15 @@ jobs: free_disk_space: true from_docker_repository: ghcr.io/${{ github.repository }}/ from_docker_target: "with-targets-pre" - docker_targets: "with-targets with-targets-optional" - # FIXME: duplicated from env.TARGETS - targets: build doc-html - targets_optional: ptest + docker_targets: "with-targets-pre" + targets_pre: all-sage-local python3-ensure tox-ensure sagelib-tox-sagepython-constraints_pkgs-norequirements tox_packages_factors: >- ["standard"] - docker_push_repository: ghcr.io/${{ github.repository }}/ - # Reduce from 30 to 20 because it runs in parallel with 'standard-sitepackages' - # and 'minimal-pre' below - max_parallel: 20 + max_parallel: 15 standard-sitepackages: if: ${{ success() || failure() }} - needs: [standard-pre] + needs: [standard] uses: ./.github/workflows/docker.yml with: # Build incrementally from previous stage (pre) @@ -116,8 +114,7 @@ jobs: "debian-sid", "linuxmint-21.1", "linuxmint-21.2", - "fedora-38", - "fedora-39", + "fedora-40", "centos-stream-9-python3.9", "almalinux-8-python3.9", "gentoo-python3.10", @@ -129,38 +126,22 @@ jobs: docker_push_repository: ghcr.io/${{ github.repository }}/ max_parallel: 8 - minimal-pre: - if: ${{ success() || failure() }} - uses: ./.github/workflows/docker.yml - with: - # Build from scratch - docker_targets: "with-system-packages configured with-targets-pre" - # FIXME: duplicated from env.TARGETS - targets_pre: all-sage-local - tox_packages_factors: >- - ["minimal"] - docker_push_repository: ghcr.io/${{ github.repository }}/ - # Reduced from 30 because it may run in parallel with 'standard' and 'standard-sitepackages' above. - # Calibrated for clogging the job pipeline until the "default" job has finished. - max_parallel: 24 - minimal: if: ${{ success() || failure() }} - needs: [minimal-pre] uses: ./.github/workflows/docker.yml with: - # Build incrementally from previous stage (pre) - incremental: true + # Build from scratch free_disk_space: true - from_docker_repository: ghcr.io/${{ github.repository }}/ - from_docker_target: "with-targets-pre" - docker_targets: "with-targets with-targets-optional" + docker_targets: "with-system-packages configured with-targets-pre with-targets with-targets-optional" # FIXME: duplicated from env.TARGETS + targets_pre: all-sage-local targets: build doc-html targets_optional: ptest tox_packages_factors: >- ["minimal"] docker_push_repository: ghcr.io/${{ github.repository }}/ + # Reduced from 30 because it may run in parallel with 'standard' and 'standard-sitepackages' above. + # Calibrated for clogging the job pipeline until the "default" job has finished. max_parallel: 24 maximal-pre: @@ -177,7 +158,7 @@ jobs: ["maximal"] docker_push_repository: ghcr.io/${{ github.repository }}/ - optional-0-o: + optional: if: ${{ success() || failure() }} needs: [maximal-pre] uses: ./.github/workflows/docker.yml @@ -189,42 +170,12 @@ jobs: tox_packages_factors: >- ["maximal"] docker_targets: "with-targets-optional" - # [0-9a-o] excludes _, in particular package _develop - targets_optional: '$(echo $(export PATH=build/bin:$PATH && sage-package list :optional: --has-file "spkg-install.in|spkg-install|requirements.txt" --no-file "huge|has_nonfree_dependencies" | grep -v sagemath_doc | grep ^[0-9a-o]))' - - - optional-p-z: - if: ${{ success() || failure() }} - needs: [optional-0-o] - uses: ./.github/workflows/docker.yml - with: - incremental: true - free_disk_space: true - from_docker_repository: ghcr.io/${{ github.repository }}/ - from_docker_target: "with-targets-pre" - tox_packages_factors: >- - ["maximal"] - docker_targets: "with-targets-optional" - # [0-9a-o] excludes _, in particular package _develop - targets_optional: '$(echo $(export PATH=build/bin:$PATH && sage-package list :optional: --has-file "spkg-install.in|spkg-install|requirements.txt" --no-file "huge|has_nonfree_dependencies" | grep -v sagemath_doc | grep ^[p-z]))' - - experimental-0-o: - if: ${{ success() || failure() }} - needs: [optional-p-z] - uses: ./.github/workflows/docker.yml - with: - incremental: true - free_disk_space: true - from_docker_repository: ghcr.io/${{ github.repository }}/ - from_docker_target: "with-targets-pre" - tox_packages_factors: >- - ["maximal"] - docker_targets: "with-targets-optional" - targets_optional: '$(echo $(export PATH=build/bin:$PATH && sage-package list :experimental: --has-file "spkg-install.in|spkg-install|requirements.txt" --no-file "huge|has_nonfree_dependencies" | grep -v sagemath_doc | grep ^[0-9a-o]))' + # We remove packages starting with _, in particular package _develop + targets_optional: '$(echo $(export PATH=build/bin:$PATH && sage-package list :optional: --has-file "spkg-install.in|spkg-install|requirements.txt" --no-file "huge|has_nonfree_dependencies" | grep -v sagemath_doc | grep -v ^_))' - experimental-p-z: + experimental: if: ${{ success() || failure() }} - needs: [experimental-0-o] + needs: [optional] uses: ./.github/workflows/docker.yml with: incremental: true @@ -234,4 +185,4 @@ jobs: tox_packages_factors: >- ["maximal"] docker_targets: "with-targets-optional" - targets_optional: '$(echo $(export PATH=build/bin:$PATH && sage-package list :experimental: --has-file "spkg-install.in|spkg-install|requirements.txt" --no-file "huge|has_nonfree_dependencies" | grep -v sagemath_doc | grep ^[p-z]))' + targets_optional: '$(echo $(export PATH=build/bin:$PATH && sage-package list :experimental: --has-file "spkg-install.in|spkg-install|requirements.txt" --no-file "huge|has_nonfree_dependencies" | grep -v sagemath_doc))' diff --git a/.github/workflows/ci-meson.yml b/.github/workflows/ci-meson.yml new file mode 100644 index 00000000000..3ecccb4c16c --- /dev/null +++ b/.github/workflows/ci-meson.yml @@ -0,0 +1,79 @@ +name: Build & Test using Meson + +on: + push: + branches: + - master + - develop + pull_request: + workflow_dispatch: + # Allow to run manually + +concurrency: + # Cancel previous runs of this workflow for the same branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Conda (${{ matrix.os }}, Python ${{ matrix.python }}) + runs-on: ${{ matrix.os }}-latest + + strategy: + fail-fast: false + matrix: + os: [ubuntu] + python: ['3.9', '3.10', '3.11'] + + steps: + - uses: actions/checkout@v4 + + - name: Merge CI fixes from sagemath/sage + run: | + .ci/merge-fixes.sh + env: + GH_TOKEN: ${{ github.token }} + + - name: Cache conda packages + uses: actions/cache@v4 + with: + path: ~/conda_pkgs_dir + key: + ${{ runner.os }}-conda-${{ hashFiles('src/environment-3.11-linux.yml') }} + + - name: Compiler cache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ runner.os }}-meson-${{ matrix.python }} + + - name: Setup Conda environment + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python }} + miniforge-version: latest + use-mamba: true + channels: conda-forge + channel-priority: true + activate-environment: sage + environment-file: src/environment-${{ matrix.python }}-${{ startsWith(matrix.os, 'macos') && (startsWith(runner.arch, 'ARM') && 'macos' || 'macos-x86_64') || 'linux' }}.yml + + - name: Print Conda environment + shell: bash -l {0} + run: | + conda info + conda list + + - name: Build + shell: bash -l {0} + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + export CC="ccache $CC" + export CXX="ccache $CXX" + pip install --no-build-isolation --config-settings=builddir=builddir . -v + + - name: Test + shell: bash -l {0} + run: | + # We don't install sage_setup, so don't try to test it + rm -R ./src/sage_setup/ + ./sage -t --all -p4 diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 3d4028dfe78..538b44d1431 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -76,24 +76,6 @@ jobs: upstream name: release_dist - release: - - needs: release_dist - runs-on: ubuntu-latest - if: (success() || failure()) && github.repository == 'sagemath/sage' && startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') - steps: - - uses: actions/download-artifact@v4 - with: - name: release_dist - - uses: softprops/action-gh-release@v2 - with: - generate_release_notes: true - files: | - dist/* - upstream/* - permissions: - contents: write - sdists_for_pypi: runs-on: ubuntu-latest @@ -124,6 +106,29 @@ jobs: verbose: true if: env.CAN_DEPLOY == 'true' + release: + + needs: [release_dist, sdists_for_pypi] + runs-on: ubuntu-latest + if: (success() || failure()) && github.repository == 'sagemath/sage' && startsWith(github.ref, 'refs/tags/') + steps: + - uses: actions/download-artifact@v4 + with: + name: release_dist + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }} + files: | + dist/* + upstream/* + permissions: + contents: write + noarch_wheels_for_pypi: runs-on: ubuntu-latest @@ -155,41 +160,48 @@ jobs: if: env.CAN_DEPLOY == 'true' build_wheels: - name: Build wheels on ${{ matrix.os }}, arch ${{ matrix.arch }} + name: wheels ${{ matrix.build }}*_${{ matrix.arch }} runs-on: ${{ matrix.os }} needs: sdists_for_pypi strategy: fail-fast: false matrix: + os: [ubuntu-latest] + arch: [x86_64, i686, aarch64] + build: [manylinux, musllinux] include: - - os: ubuntu-latest - arch: x86_64 - - os: ubuntu-latest - arch: i686 - os: macos-13 arch: x86_64 + build: macosx - os: macos-14 arch: arm64 + build: macosx env: CAN_DEPLOY: ${{ secrets.SAGEMATH_PYPI_API_TOKEN != '' }} # SPKGs to install as system packages SPKGS: _bootstrap _prereq # Non-Python packages to install as spkgs TARGETS_PRE: gmp mpfr mpc bliss coxeter3 mcqd meataxe sirocco boost_cropped tdlib + CIBW_BUILD: "*${{ matrix.build }}*" # Disable building PyPy wheels on all platforms - # Disable musllinux until #33083 provides alpine package information - CIBW_SKIP: "pp* *-musllinux*" + CIBW_SKIP: "pp*" # CIBW_ARCHS: ${{ matrix.arch }} # https://cibuildwheel.readthedocs.io/en/stable/options/#requires-python CIBW_PROJECT_REQUIRES_PYTHON: ">=3.9, <3.13" # Environment during wheel build - CIBW_ENVIRONMENT: "PATH=$(pwd)/prefix/bin:$PATH CPATH=$(pwd)/prefix/include:$CPATH LIBRARY_PATH=$(pwd)/prefix/lib:$LIBRARY_PATH LD_LIBRARY_PATH=$(pwd)/prefix/lib:$LD_LIBRARY_PATH PKG_CONFIG_PATH=$(pwd)/prefix/share/pkgconfig:$PKG_CONFIG_PATH ACLOCAL_PATH=/usr/share/aclocal PIP_CONSTRAINT=$(pwd)/constraints.txt" + CIBW_ENVIRONMENT: "PATH=$(pwd)/prefix/bin:$PATH CPATH=$(pwd)/prefix/include:$CPATH LIBRARY_PATH=$(pwd)/prefix/lib:$LIBRARY_PATH LD_LIBRARY_PATH=$(pwd)/prefix/lib:$LD_LIBRARY_PATH PKG_CONFIG_PATH=$(pwd)/prefix/share/pkgconfig:$PKG_CONFIG_PATH ACLOCAL_PATH=/usr/share/aclocal PIP_CONSTRAINT=$(pwd)/constraints.txt PIP_FIND_LINKS=file://$(pwd)/wheelhouse SAGE_NUM_THREADS=6" # Use 'build', not 'pip wheel' CIBW_BUILD_FRONTEND: build steps: - uses: actions/checkout@v4 + - name: Set up QEMU + if: runner.os == 'Linux' && matrix.arch != 'x86_64' && matrix.arch != 'i686' + uses: docker/setup-qemu-action@v3 + with: + platforms: all + - uses: actions/download-artifact@v4 with: name: dist @@ -209,7 +221,7 @@ jobs: eval $(sage-print-system-package-command auto --sudo --yes --no-install-recommends --spkg install _bootstrap) ./bootstrap - - name: Build platform wheels + - name: Unpack and prepare # We build the wheels from the sdists so that MANIFEST filtering becomes effective. # But we must run cibuildwheel with the unpacked source directory, not a tarball, # so that SAGE_ROOT is copied into the build containers. @@ -223,21 +235,44 @@ jobs: # # omit sagemath-{meataxe,sirocco} for now -- needs sagemath-modules run: | - "${{ steps.python.outputs.python-path }}" -m pip install pipx + "${{ steps.python.outputs.python-path }}" -m pip install cibuildwheel==2.18.0 export PATH=build/bin:$PATH - export CIBW_BEFORE_ALL="( $(sage-print-system-package-command debian --yes --no-install-recommends install $(sage-get-system-packages debian $SPKGS)) || $(sage-print-system-package-command fedora --yes --no-install-recommends install $(sage-get-system-packages fedora $SPKGS | sed s/pkg-config/pkgconfig/)) || ( $(sage-print-system-package-command homebrew --yes --no-install-recommends install $(sage-get-system-packages homebrew $SPKGS)) || echo error ignored) ) && if cp /host/sage-\$AUDITWHEEL_PLAT/config.status . 2>/dev/null; then chmod +x config.status; fi && if [ -x ./config.status ]; then ./config.status; else ./configure --enable-build-as-root ${{ startsWith(matrix.os, 'ubuntu') && '--prefix=/host/sage-\$AUDITWHEEL_PLAT' || '' }} && cp config.status prefix/; fi && MAKE=\"make -j6\" make V=0 $TARGETS_PRE && (echo \"sage_conf @ file://\$(pwd)/pkgs/sage-conf\" && echo \"sage_setup @ file://\$(pwd)/pkgs/sage-setup\") > constraints.txt" + echo CIBW_BEFORE_ALL="( $(sage-print-system-package-command debian --yes --no-install-recommends install $(sage-get-system-packages debian $SPKGS)) || $(sage-print-system-package-command fedora --yes --no-install-recommends install $(sage-get-system-packages fedora $SPKGS | sed s/pkg-config/pkgconfig/)) || ( $(sage-print-system-package-command homebrew --yes --no-install-recommends install $(sage-get-system-packages homebrew $SPKGS)) || $(sage-print-system-package-command alpine --yes --no-install-recommends install $(sage-get-system-packages alpine $SPKGS)) || echo error ignored) ) && if cp /host/sage-\$AUDITWHEEL_PLAT/config.status . 2>/dev/null; then chmod +x config.status; fi && if [ -x ./config.status ]; then ./config.status; else ./configure --enable-build-as-root ${{ startsWith(matrix.os, 'ubuntu') && '--prefix=/host/sage-\$AUDITWHEEL_PLAT' || '' }} && cp config.status prefix/; fi && MAKE=\"make -j6\" make V=0 $TARGETS_PRE && (echo \"sage_conf @ file://\$(pwd)/pkgs/sage-conf\" && echo \"sage_setup @ file://\$(pwd)/pkgs/sage-setup\") > constraints.txt" >> "$GITHUB_ENV" mkdir -p unpacked - for pkg in sagemath*objects sagemath*categories sagemath*bliss sagemath*coxeter3 sagemath*mcqd sagemath*tdlib; do - case "$pkg:${{ matrix.arch }}" in - sagemath*tdlib:i686) continue;; # broken - boost-related - esac - (cd unpacked && tar xfz - ) < dist/$pkg*.tar.gz - "${{ steps.python.outputs.python-path }}" -m pipx run cibuildwheel==2.18.0 unpacked/$pkg* + for sdist in dist/$pkg*.tar.gz; do + (cd unpacked && tar xfz - ) < $sdist done + - name: sagemath-objects + run: | + "${{ steps.python.outputs.python-path }}" -m cibuildwheel unpacked/sagemath*objects* + + - name: sagemath-categories + run: | + "${{ steps.python.outputs.python-path }}" -m cibuildwheel unpacked/sagemath*categories* + + - name: sagemath-bliss + run: | + "${{ steps.python.outputs.python-path }}" -m cibuildwheel unpacked/sagemath*bliss* + + - name: sagemath-coxeter3 + run: | + "${{ steps.python.outputs.python-path }}" -m cibuildwheel unpacked/sagemath*coxeter3* + + - name: sagemath-mcqd + run: | + "${{ steps.python.outputs.python-path }}" -m cibuildwheel unpacked/sagemath*mcqd* + + - name: sagemath-tdlib + run: | + case "${{ matrix.arch }}" in + i686) ;; # broken - boost-related + *) "${{ steps.python.outputs.python-path }}" -m cibuildwheel unpacked/sagemath*tdlib* + esac + - uses: actions/upload-artifact@v4 with: - name: ${{ matrix.os }}-${{ matrix.arch }}-wheels + name: ${{ matrix.os }}-${{ matrix.build }}-${{ matrix.arch }}-wheels path: ./wheelhouse/*.whl upload_wheels: @@ -250,7 +285,7 @@ jobs: - uses: actions/download-artifact@v4 with: - pattern: "*-*-wheels" + pattern: "*-*-*-wheels" path: wheelhouse merge-multiple: true diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index 0c1085138b1..dce25a132c9 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -84,7 +84,7 @@ jobs: - name: Build Docker image id: image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: # push and load may not be set together at the moment push: true diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index ec533d56476..9deab60f8be 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -95,7 +95,7 @@ jobs: - name: Build Docker image id: image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: # push and load may not be set together at the moment push: true @@ -153,7 +153,9 @@ jobs: find . -name "*.html" | xargs sed -i -e '/class="sidebar-brand-text"/ s/Sage [0-9a-z.]* /Sage '"$new_version"' /' \ -e '/;,\;; d') + -e '\;; d' \ + -e 's;#L[0-9]*";";' \ + && true) # Create git repo from old doc (cd doc && \ git init && \ @@ -199,16 +201,21 @@ jobs: find . -name "*.html" | xargs sed -i -e '/This is documentation/ s/ built with GitHub PR .* for development/ for development/' \ -e '/;,\;; d' \ + -e 's;#L[0-9]*";";' \ && git commit -a -m 'wipe-out') # Since HEAD is at commit 'wipe-out', HEAD~1 is commit 'new' (new doc), HEAD~2 is commit 'old' (old doc) - .ci/create-changes-html.sh $(cd doc && git rev-parse HEAD~2) doc - # Restore the new doc with changes made in create-changes-html.sh but dropping changes by "wipe out" - (cd doc && git stash -q && git checkout -q -f HEAD~1 && git stash pop -q) + (cd doc && git diff $(git rev-parse HEAD~2) -- "*.html") > diff.txt + # Restore the new doc dropping changes by "wipe out" + (cd doc && git checkout -q -f HEAD~1) + .ci/create-changes-html.sh diff.txt doc # Sometimes rm -rf .git errors out because of some diehard hidden files # So we simply move it out of the doc directory (cd doc && mv .git ../git && mv .gitattributes ../gitattributes) mv CHANGES.html doc fi + # Create the robots.txt file to discourage web crawlers from indexing doc preview webpages + echo "User-agent: *" > doc/robots.txt + echo "Disallow: /" >> doc/robots.txt # Zip everything for increased performance zip -r doc.zip doc diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ebde1bfde8e..4f3d1441544 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -47,8 +47,9 @@ on: "fedora-38", "fedora-39", "fedora-40", - "centos-7-devtoolset-gcc_11", - "centos-stream-9-python3.9", + "fedora-41", + "centos-stream-9", + "centos-stream-9-python3.12", "almalinux-8-python3.9", "almalinux-9-python3.11", "gentoo-python3.10", @@ -243,9 +244,16 @@ jobs: # The arcane "find" command is a replacement for "pkill make", # which we use because pkill is not installed in the "minimal" package # configuration on many platforms. + # + # The "sed" command strips away timestamps from "docker build" (buildkit) + # such as "#25 1211.0" at the beginning of each line. The timestamps are + # redundant because GH Actions provides timestamps for each line already. + # Stripping the timestamps from the beginnings of lines also allows + # GitHub Actions to recognize workflow commands such as ::error etc. + # run: | (sleep ${{ inputs.timeout }}; for id in $(docker ps -q); do docker exec $id find /proc -maxdepth 2 -name cmdline -exec bash -c "grep -l [m][a][k][e] {} | cut -d/ -f3 | xargs --no-run-if-empty kill" \;; done) & - set -o pipefail; EXTRA_DOCKER_BUILD_ARGS="--build-arg NUMPROC=9 --build-arg USE_MAKEFLAGS=\"-k V=0 SAGE_NUM_THREADS=5\"" 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::|;" + set -o pipefail; EXTRA_DOCKER_BUILD_ARGS="--build-arg NUMPROC=9 --build-arg USE_MAKEFLAGS=\"-k V=0 SAGE_NUM_THREADS=5\"" tox -e $TOX_ENV -- $TARGETS 2>&1 | sed -E --unbuffered "s/^#[0-9]+ [0-9]+[.][0-9]+ //;/^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" diff --git a/.github/workflows/docker_hub.yml b/.github/workflows/docker_hub.yml index bb5b5232284..ed07bc2f03e 100644 --- a/.github/workflows/docker_hub.yml +++ b/.github/workflows/docker_hub.yml @@ -82,7 +82,7 @@ jobs: if: env.JOB_DONE == 'false' && env.CAN_LOGIN == 'true' - name: Build and push make-build - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . file: docker/Dockerfile diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml deleted file mode 100644 index 63f70bb6531..00000000000 --- a/.github/workflows/pr-labeler.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This action automatically labels Pull-Requests -# based on files edited and no of lines changed. -name: Size Labeler / Checker -on: - pull_request_target: - types: - - opened - - reopened - - synchronize - - ready_for_review - - review_requested - - edited -jobs: - label-changes: - if: vars.SMALL_THRESHOLD && vars.MODERATE_THRESHOLD && vars.LARGE_THRESHOLD && github.event.pull_request.draft == false - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - # checkout the .ci directory of the develop branch of the main repository sagemath/sage - - name: Checkout the main repo - uses: actions/checkout@v4 - with: - sparse-checkout: | - .ci - # Check out the pull request repository and mount it at path / - - name: Checkout the pull request repo - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - repository: ${{ github.event.pull_request.head.repo.full_name }} - path: ${{ github.event.pull_request.head.repo.name }} - - - name: Add labels based on size - run: | - git fetch origin $BASE_REF - chmod a+x .ci/set_labels_by_changes.sh - .ci/set_labels_by_changes.sh - env: - BASE_REF: ${{ github.base_ref }} - PR_MOUNT_DIR: ${{ github.event.pull_request.head.repo.name }} - BASE_SHA: ${{ github.event.pull_request.base.sha }} - PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - REPOSITORY: ${{ github.repository }} - PR_REPO: ${{ github.event.pull_request.head.repo.name }} - PR_NUMBER: ${{ github.event.pull_request.number}} - SMALL_THRESHOLD: ${{ vars.SMALL_THRESHOLD }} - MODERATE_THRESHOLD: ${{ vars.MODERATE_THRESHOLD }} - LARGE_THRESHOLD: ${{ vars.LARGE_THRESHOLD }} diff --git a/.gitignore b/.gitignore index 1d7eacdf9e4..7d8c2f0adc4 100644 --- a/.gitignore +++ b/.gitignore @@ -146,10 +146,12 @@ __pycache__/ # Generated by sage_setup.autogen /src/sage/ext/interpreters +!/src/sage/ext/interpreters/meson.build # Generated Cython files *.so **/*.so +**/*.so.old /src/cython_debug # Most C and C++ files are generated by Cython and should not # be included in the sdist. @@ -261,6 +263,7 @@ build/pkgs/wheel/version_requirements.txt /src/doc/en/reference/*/sage_docbuild /src/doc/en/reference/sage /src/doc/en/reference/spkg/*.rst +!/src/doc/en/reference/spkg/index.rst /src/doc/output /src/doc/en/installation/*.txt /src/doc/en/reference/repl/*.txt @@ -298,3 +301,171 @@ src/.coverage/ # git worktree worktree* **/worktree* + +# Meson build directory +builddir +builddir-* +build-install +build/cp* + +# Meson temporary files +src/sage/interfaces/__init__.py +src/sage/crypto/block_cipher/__init__.py +src/sage/crypto/public_key/__init__.py +src/sage/logic/__init__.py +src/sage/parallel/__init__.py +src/sage/dynamics/cellular_automata/__init__.py +src/sage/dynamics/arithmetic_dynamics/__init__.py +src/sage/dynamics/__init__.py +src/sage/dynamics/complex_dynamics/__init__.py +src/sage/knots/__init__.py +src/sage/topology/__init__.py +src/sage/functions/__init__.py +src/sage/manifolds/subsets/__init__.py +src/sage/manifolds/__init__.py +src/sage/manifolds/differentiable/examples/__init__.py +src/sage/manifolds/differentiable/__init__.py +src/sage/coding/source_coding/__init__.py +src/sage/coding/guruswami_sudan/__init__.py +src/sage/coding/__init__.py +src/sage/coding/codecan/__init__.py +src/sage/games/__init__.py +src/sage/quivers/__init__.py +src/sage/schemes/cyclic_covers/__init__.py +src/sage/schemes/plane_conics/__init__.py +src/sage/schemes/curves/__init__.py +src/sage/schemes/plane_quartics/__init__.py +src/sage/schemes/jacobians/__init__.py +src/sage/schemes/toric/sheaf/__init__.py +src/sage/schemes/toric/__init__.py +src/sage/schemes/product_projective/__init__.py +src/sage/schemes/elliptic_curves/__init__.py +src/sage/schemes/riemann_surfaces/__init__.py +src/sage/schemes/hyperelliptic_curves/__init__.py +src/sage/schemes/berkovich/__init__.py +src/sage/schemes/generic/__init__.py +src/sage/schemes/projective/__init__.py +src/sage/schemes/__init__.py +src/sage/schemes/affine/__init__.py +src/sage/modular/hecke/__init__.py +src/sage/modular/pollack_stevens/__init__.py +src/sage/modular/overconvergent/__init__.py +src/sage/modular/modform/__init__.py +src/sage/modular/quasimodform/__init__.py +src/sage/modular/modsym/__init__.py +src/sage/modular/local_comp/__init__.py +src/sage/modular/quatalg/__init__.py +src/sage/modular/ssmod/__init__.py +src/sage/modular/abvar/__init__.py +src/sage/modular/__init__.py +src/sage/modular/btquotients/__init__.py +src/sage/modular/arithgroup/__init__.py +src/sage/modular/modform_hecketriangle/__init__.py +src/sage/combinat/cluster_algebra_quiver/__init__.py +src/sage/combinat/root_system/__init__.py +src/sage/combinat/species/__init__.py +src/sage/combinat/designs/__init__.py +src/sage/combinat/posets/__init__.py +src/sage/combinat/matrices/__init__.py +src/sage/combinat/rigged_configurations/__init__.py +src/sage/combinat/ncsf_qsym/__init__.py +src/sage/combinat/path_tableaux/__init__.py +src/sage/combinat/sf/__init__.py +src/sage/combinat/__init__.py +src/sage/combinat/chas/__init__.py +src/sage/combinat/ncsym/__init__.py +src/sage/combinat/words/__init__.py +src/sage/combinat/crystals/__init__.py +src/sage/tensor/modules/__init__.py +src/sage/tensor/__init__.py +src/sage/groups/matrix_gps/__init__.py +src/sage/groups/semimonomial_transformations/__init__.py +src/sage/groups/perm_gps/partn_ref2/__init__.py +src/sage/groups/perm_gps/partn_ref/__init__.py +src/sage/groups/perm_gps/__init__.py +src/sage/groups/__init__.py +src/sage/groups/affine_gps/__init__.py +src/sage/groups/abelian_gps/__init__.py +src/sage/groups/additive_abelian/__init__.py +src/sage/groups/lie_gps/__init__.py +src/sage/groups/misc_gps/__init__.py +src/sage/symbolic/__init__.py +src/sage/symbolic/integration/__init__.py +src/sage/lfunctions/__init__.py +src/sage/arith/__init__.py +src/sage/ext/__init__.py +src/sage/categories/examples/__init__.py +src/sage/categories/__init__.py +src/sage/modules/fg_pid/__init__.py +src/sage/modules/__init__.py +src/sage/modules/with_basis/__init__.py +src/sage/modules/fp_graded/steenrod/__init__.py +src/sage/modules/fp_graded/__init__.py +src/sage/misc/__init__.py +src/sage/rings/convert/__init__.py +src/sage/rings/invariants/__init__.py +src/sage/rings/finite_rings/__init__.py +src/sage/rings/function_field/__init__.py +src/sage/rings/function_field/drinfeld_modules/__init__.py +src/sage/rings/semirings/__init__.py +src/sage/rings/number_field/__init__.py +src/sage/rings/__init__.py +src/sage/rings/padics/__init__.py +src/sage/rings/valuation/__init__.py +src/sage/rings/asymptotic/__init__.py +src/sage/rings/polynomial/weil/__init__.py +src/sage/rings/polynomial/__init__.py +src/sage/rings/polynomial/padics/__init__.py +src/sage/monoids/__init__.py +src/sage/matrix/__init__.py +src/sage/matroids/__init__.py +src/sage/interacts/__init__.py +src/sage/__init__.py +src/sage/plot/__init__.py +src/sage/plot/plot3d/__init__.py +src/sage/typeset/__init__.py +src/sage/algebras/lie_conformal_algebras/__init__.py +src/sage/algebras/fusion_rings/__init__.py +src/sage/algebras/letterplace/__init__.py +src/sage/algebras/quatalg/__init__.py +src/sage/algebras/steenrod/__init__.py +src/sage/algebras/finite_dimensional_algebras/__init__.py +src/sage/algebras/__init__.py +src/sage/algebras/hecke_algebras/__init__.py +src/sage/algebras/lie_algebras/__init__.py +src/sage/algebras/quantum_groups/__init__.py +src/sage/quadratic_forms/genera/__init__.py +src/sage/quadratic_forms/__init__.py +src/sage/game_theory/__init__.py +src/sage/sandpiles/__init__.py +src/sage/sat/__init__.py +src/sage/homology/__init__.py +src/sage/geometry/riemannian_manifolds/__init__.py +src/sage/geometry/hyperplane_arrangement/__init__.py +src/sage/geometry/triangulation/__init__.py +src/sage/geometry/polyhedron/modules/__init__.py +src/sage/geometry/polyhedron/__init__.py +src/sage/geometry/polyhedron/combinatorial_polyhedron/__init__.py +src/sage/geometry/__init__.py +src/sage/geometry/hyperbolic_space/__init__.py +src/sage/sets/__init__.py +src/sage/probability/__init__.py +src/sage/numerical/backends/__init__.py +src/sage/numerical/__init__.py +src/sage/data_structures/__init__.py +src/sage/graphs/graph_decompositions/__init__.py +src/sage/graphs/generators/__init__.py +src/sage/graphs/__init__.py +src/sage/graphs/base/__init__.py +src/sage/databases/__init__.py +src/sage/stats/hmm/__init__.py +src/sage/stats/__init__.py +src/sage/stats/distributions/__init__.py +src/sage/libs/gap/__init__.py +src/sage/libs/mpfi/__init__.py +src/sage/libs/__init__.py +src/sage/libs/polybori/__init__.py +src/sage/libs/mpfr/__init__.py +src/sage/libs/mpc/__init__.py +src/sage/calculus/transforms/__init__.py +src/sage/calculus/__init__.py diff --git a/.upstream.d/20-github.com-sagemath-sage-releases b/.upstream.d/20-github.com-sagemath-sage-releases index db4fdc08b38..399ee84dbd6 100644 --- a/.upstream.d/20-github.com-sagemath-sage-releases +++ b/.upstream.d/20-github.com-sagemath-sage-releases @@ -1,5 +1,5 @@ # Upstream packages as uploaded as GitHub release assets. # This file is automatically updated by the sage-update-version script. +https://github.com/sagemath/sage/releases/download/10.5/ https://github.com/sagemath/sage/releases/download/10.4/ https://github.com/sagemath/sage/releases/download/10.3/ -https://github.com/sagemath/sage/releases/download/10.2/ diff --git a/.vscode/settings.json b/.vscode/settings.json index 86eac03ffe9..052b55fe189 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,7 +15,8 @@ "pkgs/sage-conf_pypi/sage_root": true, "pkgs/sage-docbuild/sage_docbuild": true, "pkgs/sage-setup/sage_setup": true, - "pkgs/sagemath-*/sage": true + "pkgs/sagemath-*/sage": true, + "pkgs/sagemath-*/sage_setup": true }, "python.testing.pytestEnabled": true, "python.testing.pytestArgs": [ diff --git a/CITATION.cff b/CITATION.cff index e2b61cecf34..a3fbfd7caed 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.4 +version: 10.5.beta8 doi: 10.5281/zenodo.8042260 -date-released: 2024-07-19 +date-released: 2024-10-26 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/Makefile b/Makefile index 00989597a11..53d2c689843 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,7 @@ distclean: build-clean bootstrap-clean: rm -rf config/install-sh config/compile config/config.guess config/config.sub config/missing configure build/make/Makefile-auto.in rm -f src/doc/en/installation/*.txt - rm -rf src/doc/en/reference/spkg/*.rst + find src/doc/en/reference/spkg -name index.rst -prune -o -maxdepth 1 -name "*.rst" -exec rm -f {} \+ for a in environment environment-optional src/environment src/environment-dev src/environment-optional; do rm -f $$a.yml $$a-3.[89].yml $$a-3.1[0-9].yml; done rm -f src/Pipfile rm -f src/requirements.txt diff --git a/README.md b/README.md index 23d10cca6d5..af91374fe19 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ virtualization). Detailed information on supported platforms for a specific version of Sage can be found in the section _Availability and installation help_ of the -[release tour](https://wiki.sagemath.org/ReleaseTours) for this version. +[release tour for this version](https://github.com/sagemath/sage/releases). We highly appreciate contributions to Sage that fix portability bugs and help port Sage to new platforms; let us know at the [sage-devel @@ -92,7 +92,7 @@ below](#sagemath-docker-images)) or other virtualization solutions. [macOS] Preparing the Platform ------------------------------ -- If your Mac uses the Apple Silicon (M1, M2, M3; arm64) architecture and +- If your Mac uses the Apple Silicon (M1, M2, M3, M4; arm64) architecture and you set up your Mac by transferring files from an older Mac, make sure that the directory ``/usr/local`` does not contain an old copy of Homebrew (or other software) for the x86_64 architecture that you may have copied @@ -489,8 +489,8 @@ Troubleshooting --------------- If you have problems building Sage, check the Sage Installation Guide, -as well as the version-specific Sage Installation FAQ in the [Sage Release -Tour](https://wiki.sagemath.org/ReleaseTours) corresponding to the +as well as the version-specific installation help in the [release +tour](https://github.com/sagemath/sage/releases) corresponding to the version that you are installing. Please do not hesitate to ask for help in the [SageMath forum diff --git a/VERSION.txt b/VERSION.txt index c6c45714210..5f39e0b41df 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.4, Release Date: 2024-07-19 +SageMath version 10.5.beta8, Release Date: 2024-10-26 diff --git a/bootstrap b/bootstrap index 3a3d7fd1ec3..5f04a1e208c 100755 --- a/bootstrap +++ b/bootstrap @@ -225,7 +225,7 @@ save () { config/install-sh config/compile config/config.guess config/config.sub config/missing \ build/make/Makefile-auto.in \ src/doc/en/installation/*.txt \ - src/doc/en/reference/spkg/*.rst \ + $(find src/doc/en/reference/spkg -name index.rst -prune -o -maxdepth 1 -name "*.rst" -print) \ environment-3.[89].yml environment-3.1[0-9].yml \ src/environment-3.[89].yml src/environment-3.1[0-9].yml \ environment-optional-3.[89].yml environment-optional-3.1[0-9].yml \ diff --git a/bootstrap-conda b/bootstrap-conda index c64e2a72b6c..27e657281f9 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -99,6 +99,9 @@ echo >&2 $0:$LINENO: generate conda environment files ) > environment-template.yml ( sed 's/name: sage-build/name: sage/' environment-template.yml + echo " - meson" + echo " - meson-python" + echo " - pytest" echo " # Additional packages providing all dependencies for the Sage library" for pkg in $SAGELIB_SYSTEM_PACKAGES; do echo " - $pkg" diff --git a/build/bin/sage-logger b/build/bin/sage-logger index 419a2231478..42218fbbb3e 100755 --- a/build/bin/sage-logger +++ b/build/bin/sage-logger @@ -118,9 +118,14 @@ if [ -n "$SAGE_SILENT_BUILD" -a ${use_prefix} = true ]; then ( exec>> $logfile 2>&1; time_cmd "$cmd"; status=$?; report_time; exit $status ) status=$? if [[ $status != 0 ]]; then - echo " [$logname] error installing, exit status $status. End of log file:" - tail -n 120 "$logfile" | sed "/Please email sage-devel/,$ d;s;^; [$logname] ;" >&2 - echo " [$logname] Full log file: $logfile" + if [ -n "$GITHUB_ACTIONS" ]; then + echo " [$logname] error installing, exit status $status. Log file:" + sed "s;^; [$logname] ;" "$logfile" >&2 + else + echo " [$logname] error installing, exit status $status. End of log file:" + tail -n 120 "$logfile" | sed "/Please email sage-devel/,$ d;s;^; [$logname] ;" >&2 + echo " [$logname] Full log file: $logfile" + fi else time=$(report_time) if [ -n "$time" ]; then diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 790dbbeb232..6af5214c27f 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -149,24 +149,6 @@ exit_with_error_msg() exit 1 } -lookup_param() -{ - local param=$1 - local file=$2 - # Ignore errors if the file does not exist - sed -n "s/^${param} *= *//p" $file 2>/dev/null -} - -write_to_tty() -{ - # Try writing to terminal. Suppress the possible error message - if ! ( cat > /dev/tty ) 2> /dev/null ; then - # Fall back to writing to stdout - cat - return 1 - fi -} - # Handle -n, -t, -q options for recursive make # See Issue #12016. if echo "$MAKE $MAKEFLAGS -$MAKEFLAGS" |grep '[ ]-[A-Za-z]*[qnt]' >/dev/null; then @@ -293,7 +275,7 @@ if echo "$PKG_SRC" | grep / >/dev/null; then exit 1 fi PKG_NAME="$PKG_SRC" -PKG_BASE=`echo "$PKG_NAME" | sed 's/-.*//'` # strip version number +export PKG_BASE=`echo "$PKG_NAME" | sed 's/-.*//'` # strip version number case $# in 1) @@ -320,23 +302,20 @@ export SAGE_SPKG_WHEELS="$SAGE_INST_LOCAL/var/lib/sage/wheels" # PKG_SRC should look like "package-VERSION" or just "package". # VERSION, if provided, must match the version in build/pkgs. PKG_VER="${PKG_NAME#${PKG_BASE}}" -PKG_VER="${PKG_VER#-}" -PKG_SCRIPTS="$SAGE_ROOT/build/pkgs/$PKG_BASE" -LOCAL_PKG_VER=`cat $PKG_SCRIPTS/package-version.txt 2>/dev/null || echo none` -PKG_VER="$LOCAL_PKG_VER" +export PKG_VER="${PKG_VER#-}" +eval $(sage-package properties --format=shell $PKG_BASE) +eval PKG_SCRIPTS=\$path_$PKG_BASE \ + PKG_TYPE=\$type_$PKG_BASE \ + PKG_SRC_TYPE=\$source_$PKG_BASE \ + LOCAL_PKG_VER=\$version_with_patchlevel_$PKG_BASE if [ -n "$PKG_VER" -a "$PKG_VER" != "$LOCAL_PKG_VER" ]; then echo >&2 "Error: Selecting a different version of a package is no longer supported" exit 1 fi if [ -z "$PKG_VER" ]; then - PKG_NAME="${PKG_BASE}" + export PKG_NAME="${PKG_BASE}" else - PKG_NAME="${PKG_BASE}-${PKG_VER}" -fi -PKG_BASE_VER=`echo $PKG_VER | sed 's/\.p[0-9][0-9]*$//'` -if [ -f "$PKG_SCRIPTS/checksums.ini" ]; then - # Normal/wheel package - PKG_NAME_UPSTREAM=`lookup_param tarball "$PKG_SCRIPTS/checksums.ini"` + export PKG_NAME="${PKG_BASE}-${PKG_VER}" fi # Set the $SAGE_DESTDIR variable to be passed to the spkg-install @@ -356,20 +335,20 @@ WRAPPED_SCRIPTS="build install preinst pipinst postinst $INSTALLED_SCRIPTS" warning_for_experimental_packages() { ############################ -if [ x`cat "$PKG_SCRIPTS/type"` = x"experimental" ]; then - if [ $YES != 1 -a -n "$PKG_NAME_UPSTREAM" ]; then +case "$PKG_TYPE:$PKG_SRC_TYPE" in + experimental:normal|experimental:wheel) + if [ $YES != 1 ]; then echo "Error: The package $PKG_NAME is marked as experimental." echo "Use 'sage -i -y $PKG_BASE' to force installation of this package" echo "or use the configure option --enable-experimental-packages" exit 1 - fi -fi + fi;; +esac } ############################## warning_for_experimental_packages ensure_pkg_src() { ############################################### -if [ ! -f "$PKG_SRC" ]; then - if [ -n "$PKG_NAME_UPSTREAM" ]; then - # Normal or wheel package +case "$PKG_SRC_TYPE" in + normal|wheel) PKG_SRC=$(sage-package download $SAGE_DOWNLOAD_FILE_OPTIONS $PKG_BASE) || exit_with_error_msg "Error downloading tarball of $PKG_BASE" # Do a final check that PKG_SRC is a file with an absolute path cd / @@ -378,21 +357,37 @@ if [ ! -f "$PKG_SRC" ]; then echo >&2 "This shouldn't happen, it is a bug in the sage-spkg script." exit 1 fi - fi -fi - -# Go back to SAGE_ROOT where we have less chance of completely messing -# up the system if we do something wrong. -cd "$SAGE_ROOT" || exit $? -# If SAGE_SPKG_COPY_UPSTREAM is set, it should be the name of a directory -# to which all upstream files are copied. This is used in sage-sdist. -if [ -n "$SAGE_SPKG_COPY_UPSTREAM" -a -n "$PKG_NAME_UPSTREAM" ]; then - mkdir -p "$SAGE_SPKG_COPY_UPSTREAM" && cp -p "$PKG_SRC" "$SAGE_SPKG_COPY_UPSTREAM" - if [ $? -ne 0 ]; then - exit_with_error_msg "Error copying upstream tarball to directory '$SAGE_SPKG_COPY_UPSTREAM'" - fi -fi + # Go back to SAGE_ROOT where we have less chance of completely messing + # up the system if we do something wrong. + cd "$SAGE_ROOT" || exit $? + + # If SAGE_SPKG_COPY_UPSTREAM is set, it should be the name of a directory + # to which all upstream files are copied. This is used in sage-sdist. + if [ -n "$SAGE_SPKG_COPY_UPSTREAM" ]; then + mkdir -p "$SAGE_SPKG_COPY_UPSTREAM" && cp -p "$PKG_SRC" "$SAGE_SPKG_COPY_UPSTREAM" + if [ $? -ne 0 ]; then + error_msg "Error copying upstream tarball to directory '$SAGE_SPKG_COPY_UPSTREAM'" + exit 1 + fi + fi + ;; + none) + echo >&2 + echo >&2 "Note: $PKG_BASE is a dummy package that the Sage distribution uses" + echo >&2 "to provide information about equivalent system packages." + echo >&2 "It cannot be installed using the Sage distribution." + echo >&2 "Please install it manually, for example using the system packages" + echo >&2 "recommended at the end of a run of './configure'" + echo >&2 "See below for package-specific information." + echo >&2 + sage-spkg-info $PKG_BASE + echo >&2 + echo >&2 "Error: $PKG_BASE is a dummy package and " + echo >&2 "cannot be installed using the Sage distribution." + exit 1 + ;; +esac } ################################################# ensure_pkg_src setup_directories() { ############################################ @@ -438,8 +433,8 @@ extract_the_package() { ########################################## cd "$SAGE_BUILD_DIR" || exit $? echo "Setting up build directory $SAGE_BUILD_DIR/$PKG_NAME" -if [ -z "$PKG_NAME_UPSTREAM" ]; then - # Not a normal or wheel package. +case "$PKG_SRC_TYPE" in + script) # Transplant the 'src' symlink, copy scripts. mkdir -p "$PKG_NAME" if [ -d "$PKG_SCRIPTS"/src ]; then @@ -453,8 +448,9 @@ if [ -z "$PKG_NAME_UPSTREAM" ]; then fi done cd "$PKG_NAME" || exit $? -else - # Normal or wheel package, copy whole directory, resolving symlinks + ;; + normal|wheel) + # Copy whole directory, resolving symlinks cp -RLp "$PKG_SCRIPTS" "$PKG_NAME" cd "$PKG_NAME" || exit $? case "$PKG_SRC" in @@ -476,7 +472,11 @@ else cd .. ;; esac -fi + ;; + *) + error_msg "Unhandled source type $PKG_SRC_TYPE" + ;; +esac if [ "$SAGE_KEEP_BUILT_SPKGS" = "yes" ]; then touch .keep fi @@ -604,13 +604,14 @@ esac # Poison the proxy variable to forbid downloads in spkg-install # for normal packages -if [ -n "$PKG_NAME_UPSTREAM" ]; then - # Normal/wheel package +case $PKG_SRC_TYPE in + normal|wheel) export http_proxy=http://192.0.2.0:5187/ export https_proxy=$http_proxy export ftp_proxy=$http_proxy export rsync_proxy=$http_proxy -fi + ;; +esac # Make sage-logger show the full logs unset SAGE_SILENT_BUILD diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 7a13e5a9e23..420dadb9364 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -741,7 +741,7 @@ $(1)-$(4)-no-deps: echo "Error: The installation tree $(4) has been disabled" 2>&1; \ echo "$$($(4)_DISABLED_MESSAGE)" 2>&1; \ exit 1; \ - elif [ -x '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install' -o -r '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install.in' ]; then \ + else \ rm -rf '$$($(4))/var/lib/sage/scripts/$(1)'; \ cd '$$(SAGE_ROOT)/build/pkgs/$(1)' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ @@ -749,29 +749,10 @@ $(1)-$(4)-no-deps: . '$$(SAGE_ROOT)/src/bin/sage-env' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env-config' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env' && \ - PKG_BASE="$(1)" \ - PKG_VER="$(2)" \ - PKG_NAME="$(1)-$(2)" \ - SAGE_SPKG_WHEELS=$$($(4))/var/lib/sage/wheels \ - SAGE_SPKG_SCRIPTS=$$($(4))/var/lib/sage/scripts \ - SAGE_INST_LOCAL=$$($(4)) \ SAGE_CHECK=$$(SAGE_CHECK_$(1)) \ sage-logger -p 'SAGE_CHECK=$$(SAGE_CHECK_$(1)) PATH=$$(SAGE_SRC)/bin:$$($(4))/bin:$$$$PATH $$(SAGE_SPKG) $$(SAGE_SPKG_OPTIONS) \ $(if $(filter $(1),$(TOOLCHAIN_DEPS)),--keep-existing) \ $(1)-$(2) $$($(4))' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ - else ( \ - echo; \ - echo "Note: $(1) is a dummy package that the Sage distribution uses"; \ - echo "to provide information about equivalent system packages."; \ - echo "It cannot be installed using the Sage distribution."; \ - echo "Please install it manually, for example using the system packages"; \ - echo "recommended at the end of a run of './configure'"; \ - echo "See below for package-specific information."; \ - echo; \ - $$(SAGE_ROOT)/build/bin/sage-spkg-info $(1); \ - echo; \ - echo "Error: $(1) is a dummy package and "; \ - echo "cannot be installed using the Sage distribution." ) | sage-logger -p 'cat; exit 1' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ fi $(1)-no-deps: $(1)-$(4)-no-deps @@ -798,12 +779,14 @@ $(1)-sdist: FORCE python_build sage_setup cython . '$$(SAGE_ROOT)/src/bin/sage-env' && \ '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-src' -# Recursive tox invocation (note - we do not set the environment here). +# Recursive tox invocation # Setting SAGE_SPKG_WHEELS is for the benefit of sagelib's tox.ini $(1)-tox-%: FORCE $(AM_V_at)cd '$$(SAGE_ROOT)/build/pkgs/$(1)/src' && \ - export PATH="$$(SAGE_ORIG_PATH)" && \ - SAGE_SPKG_WHEELS=$$(SAGE_LOCAL)/var/lib/sage/wheels \ + . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ + . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ + . '$$(SAGE_ROOT)/src/bin/sage-env' && \ + SAGE_SPKG_WHEELS=$$(SAGE_VENV)/var/lib/sage/wheels \ tox -v -v -v -e $$* .PHONY: $(1) $(1)-uninstall $(1)-clean $(1)-build-deps $(1)-no-deps $(1)-clean diff --git a/build/pkgs/4ti2/distros/fedora.txt b/build/pkgs/4ti2/distros/fedora.txt index 252f9efdbd4..b8cd8817e37 100644 --- a/build/pkgs/4ti2/distros/fedora.txt +++ b/build/pkgs/4ti2/distros/fedora.txt @@ -1 +1,2 @@ 4ti2 +4ti2-devel diff --git a/build/pkgs/_python3.10/distros/fedora.txt b/build/pkgs/_python3.10/distros/fedora.txt index 02cc9cf73d1..8d607cac749 100644 --- a/build/pkgs/_python3.10/distros/fedora.txt +++ b/build/pkgs/_python3.10/distros/fedora.txt @@ -1,2 +1,3 @@ python3.10 python3.10-devel +python3.10-setuptools diff --git a/build/pkgs/_python3.11/distros/fedora.txt b/build/pkgs/_python3.11/distros/fedora.txt index 7fe5c300aed..439583212d6 100644 --- a/build/pkgs/_python3.11/distros/fedora.txt +++ b/build/pkgs/_python3.11/distros/fedora.txt @@ -1,2 +1,3 @@ python3.11 python3.11-devel +python3.11-setuptools diff --git a/build/pkgs/_python3.12/distros/fedora.txt b/build/pkgs/_python3.12/distros/fedora.txt index c3e29a02d27..bfc5e84864c 100644 --- a/build/pkgs/_python3.12/distros/fedora.txt +++ b/build/pkgs/_python3.12/distros/fedora.txt @@ -1,2 +1,3 @@ python3.12 python3.12-devel +python3.12-setuptools diff --git a/build/pkgs/_python3.9/distros/fedora.txt b/build/pkgs/_python3.9/distros/fedora.txt index 334e29fce37..466ad79cab3 100644 --- a/build/pkgs/_python3.9/distros/fedora.txt +++ b/build/pkgs/_python3.9/distros/fedora.txt @@ -1,3 +1,4 @@ python3.9 python3.9-devel # Except on centos-stream-8 and almalinux-8, where it is called python39 and python39-devel; we special-case this in tox.ini +python3.9-setuptools diff --git a/build/pkgs/beautifulsoup4/distros/fedora.txt b/build/pkgs/beautifulsoup4/distros/fedora.txt index 2e8f9a66b24..dc3b2b6ed9e 100644 --- a/build/pkgs/beautifulsoup4/distros/fedora.txt +++ b/build/pkgs/beautifulsoup4/distros/fedora.txt @@ -1 +1 @@ -python-beautifulsoup4 +python3-beautifulsoup4 diff --git a/build/pkgs/beniget/distros/fedora.txt b/build/pkgs/beniget/distros/fedora.txt new file mode 100644 index 00000000000..90ac5122f63 --- /dev/null +++ b/build/pkgs/beniget/distros/fedora.txt @@ -0,0 +1 @@ +python3-beniget diff --git a/build/pkgs/biopython/distros/fedora.txt b/build/pkgs/biopython/distros/fedora.txt new file mode 100644 index 00000000000..49a99dcc80b --- /dev/null +++ b/build/pkgs/biopython/distros/fedora.txt @@ -0,0 +1 @@ +python3-biopython diff --git a/build/pkgs/bleach/distros/fedora.txt b/build/pkgs/bleach/distros/fedora.txt index c5422ccff0c..6d37c4c79f0 100644 --- a/build/pkgs/bleach/distros/fedora.txt +++ b/build/pkgs/bleach/distros/fedora.txt @@ -1 +1 @@ -python-bleach +python3-bleach diff --git a/build/pkgs/boost_cropped/patches/integral_wrapper.patch b/build/pkgs/boost_cropped/patches/integral_wrapper.patch new file mode 100644 index 00000000000..387b87c05c3 --- /dev/null +++ b/build/pkgs/boost_cropped/patches/integral_wrapper.patch @@ -0,0 +1,13 @@ +diff --git a/boost/mpl/aux_/integral_wrapper.hpp b/boost/mpl/aux_/integral_wrapper.hpp +index 6bc05f7..4f3f696 100644 +--- a/boost/mpl/aux_/integral_wrapper.hpp ++++ b/boost/mpl/aux_/integral_wrapper.hpp +@@ -56,7 +56,7 @@ struct AUX_WRAPPER_NAME + // have to #ifdef here: some compilers don't like the 'N + 1' form (MSVC), + // while some other don't like 'value + 1' (Borland), and some don't like + // either +-#if BOOST_WORKAROUND(__EDG_VERSION__, <= 243) ++#if BOOST_WORKAROUND(__EDG_VERSION__, <= 243) || __clang_major__ >= 16 + private: + BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, next_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1))); + BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, prior_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1))); diff --git a/build/pkgs/ccache/distros/fedora.txt b/build/pkgs/ccache/distros/fedora.txt new file mode 100644 index 00000000000..812b9efc0c5 --- /dev/null +++ b/build/pkgs/ccache/distros/fedora.txt @@ -0,0 +1 @@ +ccache diff --git a/build/pkgs/cddlib/distros/fedora.txt b/build/pkgs/cddlib/distros/fedora.txt index f9afcc0b330..e80835cf4c4 100644 --- a/build/pkgs/cddlib/distros/fedora.txt +++ b/build/pkgs/cddlib/distros/fedora.txt @@ -1 +1,2 @@ cddlib +cddlib-devel diff --git a/build/pkgs/certifi/distros/fedora.txt b/build/pkgs/certifi/distros/fedora.txt index be421c8b4b2..f585a823bf3 100644 --- a/build/pkgs/certifi/distros/fedora.txt +++ b/build/pkgs/certifi/distros/fedora.txt @@ -1 +1 @@ -python-certifi +python3-certifi diff --git a/build/pkgs/cffi/distros/fedora.txt b/build/pkgs/cffi/distros/fedora.txt new file mode 100644 index 00000000000..68ec4dda5ba --- /dev/null +++ b/build/pkgs/cffi/distros/fedora.txt @@ -0,0 +1 @@ +python3-cffi diff --git a/build/pkgs/charset_normalizer/distros/fedora.txt b/build/pkgs/charset_normalizer/distros/fedora.txt new file mode 100644 index 00000000000..0d65ed70186 --- /dev/null +++ b/build/pkgs/charset_normalizer/distros/fedora.txt @@ -0,0 +1 @@ +python3-charset-normalizer diff --git a/build/pkgs/cmake/spkg-configure.m4 b/build/pkgs/cmake/spkg-configure.m4 index 6149f49a7c5..62e04ffe135 100644 --- a/build/pkgs/cmake/spkg-configure.m4 +++ b/build/pkgs/cmake/spkg-configure.m4 @@ -1,5 +1,5 @@ SAGE_SPKG_CONFIGURE([cmake], [dnl - AC_CACHE_CHECK([for cmake >= 3.18], [ac_cv_path_CMAKE], [dnl + AC_CACHE_CHECK([for cmake >= 3.22], [ac_cv_path_CMAKE], [dnl dnl Do not accept cmake installed via https://pypi.org/project/cmake/ dnl in the default user scheme; it will not work in our venv because dnl we set PYTHONUSERBASE in sage-env. @@ -8,7 +8,7 @@ SAGE_SPKG_CONFIGURE([cmake], [dnl cmake_version=`$ac_path_CMAKE --version 2>&1 \ | $SED -n -e 's/cmake version *\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\)/\1/p'` AS_IF([test -n "$cmake_version"], [dnl - AX_COMPARE_VERSION([$cmake_version], [ge], [3.18], [dnl + AX_COMPARE_VERSION([$cmake_version], [ge], [3.22], [dnl ac_cv_path_CMAKE="$ac_path_CMAKE" ac_path_CMAKE_found=: ]) diff --git a/build/pkgs/cocoalib/distros/fedora.txt b/build/pkgs/cocoalib/distros/fedora.txt new file mode 100644 index 00000000000..8eaa0438abe --- /dev/null +++ b/build/pkgs/cocoalib/distros/fedora.txt @@ -0,0 +1,2 @@ +cocoalib +cocoalib-devel diff --git a/build/pkgs/comm/fedora.txt b/build/pkgs/comm/fedora.txt new file mode 100644 index 00000000000..8e049b4f279 --- /dev/null +++ b/build/pkgs/comm/fedora.txt @@ -0,0 +1 @@ +python3-comm diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 491a8866372..23e8fc18c65 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=282c4b485888da0c9e2ce72c1c2b08f2df47480b -sha256=ddb46580851222af6d0f3bc8f997c47792cccb5a875dd22d130bb5b1acb8731e +sha1=03b46d88cb544ac683290487e94680de94d1ff50 +sha256=b687b542cfcce2a6865f7aa7164ea77ab00f082ef5cc8ef885e9dfb33c04679d diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 53e8ec388c9..f638ae2138f 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -3c279ec5712e0fa35c5733e03e010970727d7189 +9a5d35a91d40c9ef83fa4976f266d706028f0596 diff --git a/build/pkgs/contourpy/distros/fedora.txt b/build/pkgs/contourpy/distros/fedora.txt new file mode 100644 index 00000000000..be8588038ac --- /dev/null +++ b/build/pkgs/contourpy/distros/fedora.txt @@ -0,0 +1 @@ +python3-contourpy diff --git a/build/pkgs/cppy/distros/fedora.txt b/build/pkgs/cppy/distros/fedora.txt new file mode 100644 index 00000000000..43b5e0ef3fc --- /dev/null +++ b/build/pkgs/cppy/distros/fedora.txt @@ -0,0 +1 @@ +python3-cppy diff --git a/build/pkgs/csdp/distros/fedora.txt b/build/pkgs/csdp/distros/fedora.txt new file mode 100644 index 00000000000..81b063c46f1 --- /dev/null +++ b/build/pkgs/csdp/distros/fedora.txt @@ -0,0 +1,3 @@ +csdp +csdp-devel +csdp-tools diff --git a/build/pkgs/cvxopt/distros/fedora.txt b/build/pkgs/cvxopt/distros/fedora.txt index f15770f0506..2bb6ad1e834 100644 --- a/build/pkgs/cvxopt/distros/fedora.txt +++ b/build/pkgs/cvxopt/distros/fedora.txt @@ -1 +1 @@ -python-cvxopt +python3-cvxopt diff --git a/build/pkgs/cycler/distros/fedora.txt b/build/pkgs/cycler/distros/fedora.txt index 5727259aca6..c77685dd417 100644 --- a/build/pkgs/cycler/distros/fedora.txt +++ b/build/pkgs/cycler/distros/fedora.txt @@ -1 +1 @@ -python-cycler +python3-cycler diff --git a/build/pkgs/cypari/checksums.ini b/build/pkgs/cypari/checksums.ini index 8bedd4cf52d..d183b3c567a 100644 --- a/build/pkgs/cypari/checksums.ini +++ b/build/pkgs/cypari/checksums.ini @@ -1,4 +1,4 @@ tarball=cypari2-VERSION.tar.gz -sha1=4cb5fc43899852b7fc0c0175e610318c38f0caac -sha256=1a25865c34f20b1dc95830798e34ab6436e278b8e0c80dc7bf0ab34c5db03ab8 +sha1=4e9f14d218bc1cea29e03a2ceec9bf3dfbfd5eb3 +sha256=817606bf661b71d33e1d012421907a4f8fb09dd81b7d3e3ae179b3978020bbf1 upstream_url=https://pypi.io/packages/source/c/cypari2/cypari2-VERSION.tar.gz diff --git a/build/pkgs/cypari/dependencies b/build/pkgs/cypari/dependencies index 69dfe7e7d8a..cbf047c8027 100644 --- a/build/pkgs/cypari/dependencies +++ b/build/pkgs/cypari/dependencies @@ -1,4 +1,4 @@ - cython pari cysignals | $(PYTHON_TOOLCHAIN) $(PYTHON) +pari cysignals | $(PYTHON_TOOLCHAIN) cython $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/cypari/package-version.txt b/build/pkgs/cypari/package-version.txt index cd57a8b95d6..ccbccc3dc62 100644 --- a/build/pkgs/cypari/package-version.txt +++ b/build/pkgs/cypari/package-version.txt @@ -1 +1 @@ -2.1.5 +2.2.0 diff --git a/build/pkgs/cypari/patches/trashcan.patch b/build/pkgs/cypari/patches/trashcan.patch deleted file mode 100644 index f4918d4cd39..00000000000 --- a/build/pkgs/cypari/patches/trashcan.patch +++ /dev/null @@ -1,47 +0,0 @@ -commit 78e6dcf937c960c51132132e14f86bddbbe5b7d9 -Author: Jeroen Demeyer -Date: Tue Feb 19 11:50:49 2019 +0100 - - Use the trashcan for Gen - -diff --git a/cypari2/gen.pxd b/cypari2/gen.pxd -index 2ac0669..664d57d 100644 ---- a/cypari2/gen.pxd -+++ b/cypari2/gen.pxd -@@ -1,3 +1,4 @@ -+cimport cython - from cpython.object cimport PyObject - from .types cimport GEN, pari_sp - -diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx -index d268cf1..687f5b2 100644 ---- a/cypari2/gen.pyx -+++ b/cypari2/gen.pyx -@@ -135,6 +135,7 @@ cdef extern from *: - GEN new_nfeltup(GEN nf, GEN x, GEN zknf) - - -+@cython.trashcan(True) - cdef class Gen(Gen_base): - """ - Wrapper for a PARI ``GEN`` with memory management. -diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx -index ba82438..d13bc45 100644 ---- a/cypari2/pari_instance.pyx -+++ b/cypari2/pari_instance.pyx -@@ -243,6 +243,15 @@ Reset default precision for the following tests: - - >>> pari.set_real_precision_bits(53) - -+Test the trashcan mechanism (without the trashcan, this would cause -+a stack overflow): -+ -+>>> pari.allocatemem(2**27, silent=True) -+>>> L = [pari(i) for i in range(2**20)] -+>>> x = pari.Pi() -+>>> del L -+>>> del x -+ - Test that interrupts work properly: - - >>> pari.allocatemem(8000000, 2**29) diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index 9393fe60b7f..e463df31628 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,4 +1,4 @@ -tarball=Cython-VERSION.tar.gz -sha1=83d6428e3bb7869f44f92ed75d7dff867c2a38ce -sha256=dcc96739331fb854dcf503f94607576cfe8488066c61ca50dfd55836f132de99 -upstream_url=https://pypi.io/packages/source/C/Cython/Cython-VERSION.tar.gz +tarball=cython-VERSION.tar.gz +sha1=f692b0c6f209b75b6bbd69bdbd57fac23785c23e +sha256=7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff +upstream_url=https://pypi.io/packages/source/c/cython/cython-VERSION.tar.gz diff --git a/build/pkgs/cython/distros/fedora.txt b/build/pkgs/cython/distros/fedora.txt index 002d1b93c6f..a91271fa321 100644 --- a/build/pkgs/cython/distros/fedora.txt +++ b/build/pkgs/cython/distros/fedora.txt @@ -1 +1 @@ -Cython +python3-cython diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index a909317fe5a..778bf95c00f 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -3.0.10 +3.0.11 diff --git a/build/pkgs/dateutil/distros/fedora.txt b/build/pkgs/dateutil/distros/fedora.txt index 0f08daace31..2f46170765c 100644 --- a/build/pkgs/dateutil/distros/fedora.txt +++ b/build/pkgs/dateutil/distros/fedora.txt @@ -1 +1 @@ -python-dateutil +python3-dateutil diff --git a/build/pkgs/decorator/distros/fedora.txt b/build/pkgs/decorator/distros/fedora.txt index 079560412f1..46c478e1513 100644 --- a/build/pkgs/decorator/distros/fedora.txt +++ b/build/pkgs/decorator/distros/fedora.txt @@ -1 +1 @@ -python-decorator +python3-decorator diff --git a/build/pkgs/defusedxml/distros/fedora.txt b/build/pkgs/defusedxml/distros/fedora.txt new file mode 100644 index 00000000000..9788c955af5 --- /dev/null +++ b/build/pkgs/defusedxml/distros/fedora.txt @@ -0,0 +1 @@ +python3-defusedxml diff --git a/build/pkgs/docutils/checksums.ini b/build/pkgs/docutils/checksums.ini index ebcc15cc5a1..472701e55d7 100644 --- a/build/pkgs/docutils/checksums.ini +++ b/build/pkgs/docutils/checksums.ini @@ -1,4 +1,4 @@ tarball=docutils-VERSION-py3-none-any.whl -sha1=2bac2b2e9f4cc6d832588457c5f69bac79d80239 -sha256=96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 +sha1=a2120453cdb1498128183696711261dd5f328068 +sha256=dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 upstream_url=https://pypi.io/packages/py3/d/docutils/docutils-VERSION-py3-none-any.whl diff --git a/build/pkgs/docutils/distros/fedora.txt b/build/pkgs/docutils/distros/fedora.txt new file mode 100644 index 00000000000..a4bb792a5a4 --- /dev/null +++ b/build/pkgs/docutils/distros/fedora.txt @@ -0,0 +1 @@ +python3-docutils diff --git a/build/pkgs/docutils/package-version.txt b/build/pkgs/docutils/package-version.txt index 847e9aef6d1..59dad104b0b 100644 --- a/build/pkgs/docutils/package-version.txt +++ b/build/pkgs/docutils/package-version.txt @@ -1 +1 @@ -0.20.1 +0.21.2 diff --git a/build/pkgs/dot2tex/distros/fedora.txt b/build/pkgs/dot2tex/distros/fedora.txt new file mode 100644 index 00000000000..4d0a832a550 --- /dev/null +++ b/build/pkgs/dot2tex/distros/fedora.txt @@ -0,0 +1 @@ +dot2tex diff --git a/build/pkgs/eclib/spkg-configure.m4 b/build/pkgs/eclib/spkg-configure.m4 index 133b44bfdc1..ba5c22fa090 100644 --- a/build/pkgs/eclib/spkg-configure.m4 +++ b/build/pkgs/eclib/spkg-configure.m4 @@ -2,7 +2,7 @@ SAGE_SPKG_CONFIGURE([eclib], [ SAGE_SPKG_DEPCHECK([ntl pari flint], [ dnl use existing eclib only if the version reported by pkg-config is recent enough m4_pushdef([SAGE_ECLIB_VER],["20231212"]) - PKG_CHECK_MODULES([ECLIB], [eclib = SAGE_ECLIB_VER], [ + PKG_CHECK_MODULES([ECLIB], [eclib >= SAGE_ECLIB_VER], [ AC_CACHE_CHECK([for mwrank version == SAGE_ECLIB_VER], [ac_cv_path_MWRANK], [ AC_PATH_PROGS_FEATURE_CHECK([MWRANK], [mwrank], [ mwrank_version=`$ac_path_MWRANK -V 2>&1` diff --git a/build/pkgs/ecm/checksums.ini b/build/pkgs/ecm/checksums.ini index f2221539308..3f78010aaf2 100644 --- a/build/pkgs/ecm/checksums.ini +++ b/build/pkgs/ecm/checksums.ini @@ -1,4 +1,4 @@ tarball=ecm-VERSION.tar.gz -sha1=f35d225d1d44f9b8ad420bf9b50a92582f681337 -sha256=c721dd22e557c4a5dac9ac7e156a400cd2298812dd1f9b56e89966de01471ba8 -upstream_url=https://gitlab.inria.fr/zimmerma/ecm/uploads/89f6f0d65d3e980cef33dc922004e4b2/ecm-VERSION.tar.gz +sha1=257e1c327cd6de1097b7036c7ec358fe3dbfa4ad +sha256=7d20ece61ab6a20ad85f2c18064cabd77dc46a96ff894b5220dbb16e4666e8a5 +upstream_url=https://gitlab.inria.fr/zimmerma/ecm/uploads/ad3e5019fef98819ceae58b78f4cce93/ecm-VERSION.tar.gz diff --git a/build/pkgs/ecm/package-version.txt b/build/pkgs/ecm/package-version.txt index 2be8aeb6b14..024b4b9b53a 100644 --- a/build/pkgs/ecm/package-version.txt +++ b/build/pkgs/ecm/package-version.txt @@ -1 +1 @@ -7.0.5 +7.0.6 diff --git a/build/pkgs/editables/distros/fedora.txt b/build/pkgs/editables/distros/fedora.txt new file mode 100644 index 00000000000..359d9f1d8c8 --- /dev/null +++ b/build/pkgs/editables/distros/fedora.txt @@ -0,0 +1 @@ +python3-editables diff --git a/build/pkgs/entrypoints/distros/fedora.txt b/build/pkgs/entrypoints/distros/fedora.txt new file mode 100644 index 00000000000..6e1b57c91e7 --- /dev/null +++ b/build/pkgs/entrypoints/distros/fedora.txt @@ -0,0 +1 @@ +python3-entrypoints diff --git a/build/pkgs/exceptiongroup/checksums.ini b/build/pkgs/exceptiongroup/checksums.ini index 62cef9ee502..d42fab6a958 100644 --- a/build/pkgs/exceptiongroup/checksums.ini +++ b/build/pkgs/exceptiongroup/checksums.ini @@ -1,4 +1,4 @@ tarball=exceptiongroup-VERSION-py3-none-any.whl -sha1=4114f66482c6e55856d9bd6a4780ce716bd550cd -sha256=5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad +sha1=fd04443cb88d35ee59387ba20f62761ea5546a7d +sha256=3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b upstream_url=https://pypi.io/packages/py3/e/exceptiongroup/exceptiongroup-VERSION-py3-none-any.whl diff --git a/build/pkgs/exceptiongroup/package-version.txt b/build/pkgs/exceptiongroup/package-version.txt index 6085e946503..23aa8390630 100644 --- a/build/pkgs/exceptiongroup/package-version.txt +++ b/build/pkgs/exceptiongroup/package-version.txt @@ -1 +1 @@ -1.2.1 +1.2.2 diff --git a/build/pkgs/execnet/SPKG.rst b/build/pkgs/execnet/SPKG.rst new file mode 100644 index 00000000000..d97a2f90f88 --- /dev/null +++ b/build/pkgs/execnet/SPKG.rst @@ -0,0 +1,16 @@ +execnet: Rapid multi-Python deployment +====================================== + +Description +----------- + +Rapid multi-Python deployment + +License +------- + +Upstream Contact +---------------- + +https://pypi.org/project/execnet/ + diff --git a/build/pkgs/execnet/checksums.ini b/build/pkgs/execnet/checksums.ini new file mode 100644 index 00000000000..ee938e17c8b --- /dev/null +++ b/build/pkgs/execnet/checksums.ini @@ -0,0 +1,4 @@ +tarball=execnet-VERSION-py3-none-any.whl +sha1=3a3b88b478a03a9c9933a7bdaea3224a118cc121 +sha256=26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc +upstream_url=https://pypi.io/packages/py3/e/execnet/execnet-VERSION-py3-none-any.whl diff --git a/build/pkgs/valgrind/dependencies b/build/pkgs/execnet/dependencies similarity index 78% rename from build/pkgs/valgrind/dependencies rename to build/pkgs/execnet/dependencies index 4f00de20375..644ad35f773 100644 --- a/build/pkgs/valgrind/dependencies +++ b/build/pkgs/execnet/dependencies @@ -1,4 +1,4 @@ -# no dependencies + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/execnet/package-version.txt b/build/pkgs/execnet/package-version.txt new file mode 100644 index 00000000000..3e3c2f1e5ed --- /dev/null +++ b/build/pkgs/execnet/package-version.txt @@ -0,0 +1 @@ +2.1.1 diff --git a/build/pkgs/execnet/type b/build/pkgs/execnet/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/execnet/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/execnet/version_requirements.txt b/build/pkgs/execnet/version_requirements.txt new file mode 100644 index 00000000000..f6485f9af7d --- /dev/null +++ b/build/pkgs/execnet/version_requirements.txt @@ -0,0 +1 @@ +execnet diff --git a/build/pkgs/executing/distros/fedora.txt b/build/pkgs/executing/distros/fedora.txt new file mode 100644 index 00000000000..4504024d6da --- /dev/null +++ b/build/pkgs/executing/distros/fedora.txt @@ -0,0 +1 @@ +python3-executing diff --git a/build/pkgs/fastjsonschema/distros/fedora.txt b/build/pkgs/fastjsonschema/distros/fedora.txt index 7a8bdf5369b..aba120db917 100644 --- a/build/pkgs/fastjsonschema/distros/fedora.txt +++ b/build/pkgs/fastjsonschema/distros/fedora.txt @@ -1 +1 @@ -python-fastjsonschema +python3-fastjsonschema diff --git a/build/pkgs/ffmpeg/distros/fedora.txt b/build/pkgs/ffmpeg/distros/fedora.txt index 2034a7b9f77..f5f02b5af1b 100644 --- a/build/pkgs/ffmpeg/distros/fedora.txt +++ b/build/pkgs/ffmpeg/distros/fedora.txt @@ -1,3 +1,5 @@ # ffmpeg is not in the standard Fedora repository # Need "RPM Fusion Free" #ffmpeg +ffmpeg-free +ffmpeg-free-devel diff --git a/build/pkgs/flit_core/distros/fedora.txt b/build/pkgs/flit_core/distros/fedora.txt new file mode 100644 index 00000000000..587eaa96e19 --- /dev/null +++ b/build/pkgs/flit_core/distros/fedora.txt @@ -0,0 +1 @@ +python3-flit-core diff --git a/build/pkgs/fonttools/distros/fedora.txt b/build/pkgs/fonttools/distros/fedora.txt new file mode 100644 index 00000000000..cf25e11afc2 --- /dev/null +++ b/build/pkgs/fonttools/distros/fedora.txt @@ -0,0 +1 @@ +python3-fonttools diff --git a/build/pkgs/fpylll/checksums.ini b/build/pkgs/fpylll/checksums.ini index 5cbc7e3bc08..5f258e7518e 100644 --- a/build/pkgs/fpylll/checksums.ini +++ b/build/pkgs/fpylll/checksums.ini @@ -1,4 +1,4 @@ tarball=fpylll-VERSION.tar.gz -sha1=f23835208fc048028c849bb5b566f2fe631df7f4 -sha256=623b4619b6da9fed9ba26b1ac7e8d8e620a06d2a5f7095ee67985c7160d3c3a4 +sha1=c0bcf8c5583ebf614da9b26710a2c835d498bf34 +sha256=dfd9529a26c50993a2a716177debd7994312219070574cad31b35b4f0c040a19 upstream_url=https://pypi.io/packages/source/f/fpylll/fpylll-VERSION.tar.gz diff --git a/build/pkgs/fpylll/dependencies b/build/pkgs/fpylll/dependencies index 4837249bcfa..03eb318a449 100644 --- a/build/pkgs/fpylll/dependencies +++ b/build/pkgs/fpylll/dependencies @@ -1,4 +1,4 @@ - cython cysignals numpy fplll | $(PYTHON) + cython cysignals numpy fplll | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/fpylll/package-version.txt b/build/pkgs/fpylll/package-version.txt index a918a2aa18d..ee6cdce3c29 100644 --- a/build/pkgs/fpylll/package-version.txt +++ b/build/pkgs/fpylll/package-version.txt @@ -1 +1 @@ -0.6.0 +0.6.1 diff --git a/build/pkgs/free_fonts/distros/fedora.txt b/build/pkgs/free_fonts/distros/fedora.txt index 435c13a9578..9f7b4c7ddec 100644 --- a/build/pkgs/free_fonts/distros/fedora.txt +++ b/build/pkgs/free_fonts/distros/fedora.txt @@ -1,3 +1,4 @@ gnu-free-mono-fonts gnu-free-sans-fonts gnu-free-serif-fonts +texlive-gnu-freefont diff --git a/build/pkgs/fricas/checksums.ini b/build/pkgs/fricas/checksums.ini index 1790c649eb3..183c35bb94d 100644 --- a/build/pkgs/fricas/checksums.ini +++ b/build/pkgs/fricas/checksums.ini @@ -1,4 +1,4 @@ tarball=fricas-VERSION-full.tar.bz2 -sha1=2f1e1bbbad7e04a7114ffbd93eeedadc5db32272 -sha256=fc2112ad45ba7b45ac423165f32bd5b244622107a1e4e1d56b9136f96746f2a0 +sha1=c5104c92808ff01a02ecdd3f412d44da3b2c21fb +sha256=32b87461ef079659e97247ad0a771ec8cf0d5a0f934788d67d37fb7acf63f9c4 upstream_url=https://github.com/fricas/fricas/releases/download/VERSION/fricas-VERSION-full.tar.bz2 diff --git a/build/pkgs/fricas/package-version.txt b/build/pkgs/fricas/package-version.txt index 0c00f610817..17e63e7affd 100644 --- a/build/pkgs/fricas/package-version.txt +++ b/build/pkgs/fricas/package-version.txt @@ -1 +1 @@ -1.3.10 +1.3.11 diff --git a/build/pkgs/frobby/distros/fedora.txt b/build/pkgs/frobby/distros/fedora.txt new file mode 100644 index 00000000000..96768b37be5 --- /dev/null +++ b/build/pkgs/frobby/distros/fedora.txt @@ -0,0 +1,3 @@ +frobby +libfrobby +libfrobby-devel diff --git a/build/pkgs/furo/checksums.ini b/build/pkgs/furo/checksums.ini index b6feae79dad..eaeef993c08 100644 --- a/build/pkgs/furo/checksums.ini +++ b/build/pkgs/furo/checksums.ini @@ -1,4 +1,4 @@ tarball=furo-VERSION-py3-none-any.whl -sha1=21afca1ac0f309541bfd5b89e61097a1bd4b681e -sha256=513092538537dc5c596691da06e3c370714ec99bc438680edc1debffb73e5bfc +sha1=de4aa7aff48696580d62abed717bf1c309af10f5 +sha256=b192c7c1f59805494c8ed606d9375fdac6e6ba8178e747e72bc116745fb7e13f upstream_url=https://pypi.io/packages/py3/f/furo/furo-VERSION-py3-none-any.whl diff --git a/build/pkgs/furo/distros/fedora.txt b/build/pkgs/furo/distros/fedora.txt index d274c983622..cf3eeefa6e7 100644 --- a/build/pkgs/furo/distros/fedora.txt +++ b/build/pkgs/furo/distros/fedora.txt @@ -1 +1 @@ -python-furo +python3-furo diff --git a/build/pkgs/furo/package-version.txt b/build/pkgs/furo/package-version.txt index 0b9bb54f90d..e5180600d9a 100644 --- a/build/pkgs/furo/package-version.txt +++ b/build/pkgs/furo/package-version.txt @@ -1 +1 @@ -2023.9.10 +2024.7.18 diff --git a/build/pkgs/furo/version_requirements.txt b/build/pkgs/furo/version_requirements.txt index a95ae18b4f9..acdc1d6ef56 100644 --- a/build/pkgs/furo/version_requirements.txt +++ b/build/pkgs/furo/version_requirements.txt @@ -1 +1 @@ -furo +furo >= 2024.7.18 diff --git a/build/pkgs/gap/SPKG.rst b/build/pkgs/gap/SPKG.rst index 2f59f140a01..a5a1dbc1782 100644 --- a/build/pkgs/gap/SPKG.rst +++ b/build/pkgs/gap/SPKG.rst @@ -25,26 +25,3 @@ Upstream Contact https://www.gap-system.org Mailing list at https://mail.gap-system.org/mailman/listinfo/gap - -Special Update/Build Instructions ---------------------------------- - -This is a stripped-down version of GAP. The downloading of the sources -and removal of unneeded parts is done by the script spkg-src. When you -update GAP, please also update and use the spkg-src script. - -- Do we really want to copy everything from the build directory??? - - You need the full GAP tree to compile/install many GAP packages. - -- There's apparently a command missing (in ``spkg-install``) building - the - (HTML?) documentation. Earlier changelog entries as well as the - description - above state the documentation was removed from the upstream - sources... - Since the (pre-)built HTML documentation is currently included, I've - commented out some lines in that part of ``spkg-install``. -leif - -Patches -~~~~~~~ diff --git a/build/pkgs/gap/checksums.ini b/build/pkgs/gap/checksums.ini index 2b1170e52d9..3704072d609 100644 --- a/build/pkgs/gap/checksums.ini +++ b/build/pkgs/gap/checksums.ini @@ -1,4 +1,4 @@ tarball=gap-VERSION.tar.gz -sha1=a6e36f3f874a2c46f51561402634497eab705cca -sha256=672308745eb78a222494ee8dd6786edd5bc331456fcc6456ac064bdb28d587a8 +sha1=cf91834954849dbaeae17079a4c4565bc28d03a8 +sha256=9794dbdba6fb998e0a2d0aa8ce21fc8848ad3d3f9cc9993b0b8e20be7e1dbeba upstream_url=https://github.com/gap-system/gap/releases/download/vVERSION/gap-VERSION.tar.gz diff --git a/build/pkgs/gap/distros/conda.txt b/build/pkgs/gap/distros/conda.txt index 7f5f5034610..401c67cba31 100644 --- a/build/pkgs/gap/distros/conda.txt +++ b/build/pkgs/gap/distros/conda.txt @@ -1 +1 @@ -gap-defaults>=4.12.2,<4.13.0 +gap-defaults diff --git a/build/pkgs/gap/distros/fedora.txt b/build/pkgs/gap/distros/fedora.txt index 6c561683bf4..7b8424662a7 100644 --- a/build/pkgs/gap/distros/fedora.txt +++ b/build/pkgs/gap/distros/fedora.txt @@ -1,5 +1,72 @@ +# some packages are missing in Fedora gap gap-core gap-devel gap-libs libgap +xgap +gap-pkg-ace +gap-pkg-aclib +gap-pkg-alnuth +gap-pkg-anupq +gap-pkg-atlasrep +gap-pkg-autodoc +gap-pkg-automata +gap-pkg-autpgrp +gap-pkg-browse +gap-pkg-caratinterface +gap-pkg-circle +gap-pkg-congruence +gap-pkg-crisp +gap-pkg-crypting +gap-pkg-crystcat +gap-pkg-curlinterface +gap-pkg-cvec +gap-pkg-datastructures +gap-pkg-digraphs +gap-pkg-edim +gap-pkg-ferret +gap-pkg-fga +gap-pkg-fining +gap-pkg-float +gap-pkg-format +gap-pkg-forms +gap-pkg-fplsa +gap-pkg-fr +gap-pkg-francy +gap-pkg-genss +gap-pkg-groupoids +gap-pkg-grpconst +gap-pkg-images +gap-pkg-io +gap-pkg-irredsol +gap-pkg-json +gap-pkg-jupyterviz +gap-pkg-lpres +gap-pkg-nq +gap-pkg-openmath +gap-pkg-orb +gap-pkg-permut +gap-pkg-polenta +gap-pkg-polycyclic +gap-pkg-primgrp +gap-pkg-profiling +gap-pkg-radiroot +gap-pkg-recog +gap-pkg-resclasses +gap-pkg-scscp +gap-pkg-semigroups +gap-pkg-singular +gap-pkg-smallgrp +gap-pkg-smallsemi +gap-pkg-sophus +gap-pkg-spinsym +gap-pkg-standardff +gap-pkg-tomlib +gap-pkg-transgrp +gap-pkg-transgrp-data +gap-pkg-utils +gap-pkg-uuid +gap-pkg-xmod +gap-pkg-zeromqinterface + diff --git a/build/pkgs/gap/distros/gentoo.txt b/build/pkgs/gap/distros/gentoo.txt new file mode 100644 index 00000000000..ea64ec957e5 --- /dev/null +++ b/build/pkgs/gap/distros/gentoo.txt @@ -0,0 +1 @@ +sci-mathematics/gap diff --git a/build/pkgs/gap/package-version.txt b/build/pkgs/gap/package-version.txt index f1cd7de1de5..56d2fb548a2 100644 --- a/build/pkgs/gap/package-version.txt +++ b/build/pkgs/gap/package-version.txt @@ -1 +1 @@ -4.12.2 +4.13.1 diff --git a/build/pkgs/gap/patches/0001-Makefile.rules-Darwin-Remove-use-of-single_module-ob.patch b/build/pkgs/gap/patches/0001-Makefile.rules-Darwin-Remove-use-of-single_module-ob.patch new file mode 100644 index 00000000000..46f5e36f109 --- /dev/null +++ b/build/pkgs/gap/patches/0001-Makefile.rules-Darwin-Remove-use-of-single_module-ob.patch @@ -0,0 +1,29 @@ +From 89b95994807970d90671e1e02cc03ddca4cf0a10 Mon Sep 17 00:00:00 2001 +From: Matthias Koeppe +Date: Sat, 8 Jun 2024 14:01:16 -0700 +Subject: [PATCH] Makefile.rules [Darwin]: Remove use of '-single_module' + (obsolete), activate '-install_name' + +--- + Makefile.rules | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/Makefile.rules b/Makefile.rules +index 8bfd3dba0..adfed731f 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -446,10 +446,7 @@ else ifneq (,$(findstring darwin,$(host_os))) + LINK_SHLIB_FLAGS = -dynamiclib + LINK_SHLIB_FLAGS += -compatibility_version $(LIBGAP_COMPAT_VER) + LINK_SHLIB_FLAGS += -current_version $(LIBGAP_CURRENT_VER) +- LINK_SHLIB_FLAGS += -Wl,-single_module +- +- # TODO: set install_name, at least for installed version of the lib? +- #LINK_SHLIB_FLAGS += -install_name $(libdir)/$(LIBGAP_FULL) ++ LINK_SHLIB_FLAGS += -install_name $(libdir)/$(LIBGAP_FULL) + + GAP_CPPFLAGS += -DPIC + GAP_CFLAGS += -fno-common +-- +2.42.0 + diff --git a/build/pkgs/gap/patches/gap-4.13.1-hash-fixes.patch b/build/pkgs/gap/patches/gap-4.13.1-hash-fixes.patch new file mode 100644 index 00000000000..c99b39ab91c --- /dev/null +++ b/build/pkgs/gap/patches/gap-4.13.1-hash-fixes.patch @@ -0,0 +1,178 @@ +diff --git a/lib/dicthf.gi b/lib/dicthf.gi +index 5ee7341..e4349ac 100644 +--- a/lib/dicthf.gi ++++ b/lib/dicthf.gi +@@ -152,16 +152,37 @@ end); + ## + InstallMethod(SparseIntKey,"for bounded tuples",true, + [ IsList,IsList and IsCyclotomicCollection ], 0, +-function(m,v) +-local c; +- if Length(m)<>3 or m[1]<>"BoundedTuples" then ++function(m, v) ++ if Length(m)<> 3 or m[1]<>"BoundedTuples" then + TryNextMethod(); + fi; +- c:=[1,Maximum(m[2])+1]; +- return function(a) +- return a*c; ++ # Due to the way BoundedTuples are presently implemented we expect the input ++ # to the hash function to always be a list of positive immediate integers. This means ++ # that using HashKeyWholeBag should be safe. ++ return function(x) ++ Assert(1, IsPositionsList(x)); ++ if not IsPlistRep(x) then ++ x := AsPlist(x); ++ fi; ++ return HashKeyWholeBag(x, 1); + end; + ++ # alternative code w/o HashKeyBag ++ ## build a weight vector to distinguish lists. Make entries large while staying clearly within ++ ## immediate int (2^55 replacing 2^60, since we take subsequent primes). ++ #step:=NextPrimeInt(QuoInt(2^55,Maximum(m[2])*m[3])); ++ #weights:=[1]; ++ #len:=Length(v); ++ ## up to 56 full, then increasingly reduce ++ #len:=Minimum(len,8*RootInt(len)); ++ #while Length(weights)0 and ForAll(pnt,IsPosInt) and ++ ForAll(acts,IsPerm) and + (act=OnSets or act=OnPoints or act=OnRight or act=\^)) then + TryNextMethod(); + fi; +diff --git a/lib/vecmat.gi b/lib/vecmat.gi +index 017c3c6..93ba828 100644 +--- a/lib/vecmat.gi ++++ b/lib/vecmat.gi +@@ -2142,7 +2142,8 @@ InstallMethod(DomainForAction,"matrix/matrix",IsElmsCollsX, + function(pnt,acts,act) + local l,f; + if (not ForAll(acts,IsMatrix)) or +- (act<>OnPoints and act<>OnSubspacesByCanonicalBasis and act<>OnRight) then ++ (act<>OnPoints and act<>OnSubspacesByCanonicalBasis and act<>OnRight and act<>OnSets and ++ act<>OnTuples) then + TryNextMethod(); # strange operation, might extend the domain + fi; + l:=NaturalActedSpace(acts,pnt); +diff --git a/tst/testbugfix/2024-09-14-actdomain.tst b/tst/testbugfix/2024-09-14-actdomain.tst +new file mode 100644 +index 0000000..84f8b50 +--- /dev/null ++++ b/tst/testbugfix/2024-09-14-actdomain.tst +@@ -0,0 +1,85 @@ ++# Fix #5786 and error reported by Len Soicher in support list ++gap> gg:=SpecialUnitaryGroup(4,2);; ++gap> hl:=Z(2)*[ ++> [0,0,1,0], ++> [1,1,0,0], ++> [0,1,0,1], ++> [0,1,1,0], ++> [1,1,0,1]];; ++gap> o:=Orbit(gg,Set(hl),OnSets);; ++gap> Length(o); ++216 ++gap> set:=[ 1,10,15,24,29,33,38,40,44,59, 60, 63, 69, 74, 77,79,85, 86, 90, ++> 95, 99, 103, 105, 110, 122, 125, 143, 148, 149, 153, 162, 165, 174, 182, ++> 185, 191, 197, 198, 202, 218, 223, 227, 228, 235, 236, 240, 243, 248, ++> 254, ++> 256, 259, 270, 275, 288, 291, 295, 298, 302, 305, 310, 312, 315, 325, ++> 329, ++> 333, 340, 341, 350, 356, 366, 369, 381, 385, 390, 397, 402, 412, 414, ++> 419, ++> 421, 425, 428, 433, 436, 445, 447, 451, 452, 453, 454, 461, 466, 474, ++> 479, ++> 481, 489, 490, 493, 497, 507, 509, 512, 513, 519, 521 ];; ++gap> gp:=Group( ++> ( 1,340,124,306,216,492,100, 25,108,270,220,332)( 2,138, 54,161,132,159,198, ++> 336,439,269, 89,419)( 3,467,177,404,505,437,379,312,481,271,223,135) ++> ( 4,510, 79,504,259,234,378,251,272,268,360,303)( 5,278,176,191,231,275,263, ++> 190,230,146,265,192)( 6,486,126,523,490,448,375,237,288,400,243,329) ++> ( 7,131,123,516, 48,392,350,333,418, 16,139,175)( 8,289,125,386,241, 29,376, ++> 334,242,417,442,331)( 9,430, 32, 59,446,367,377,335,411,416,515,330) ++> ( 10,391, 56,407,475,414,200,328,165,473, 86,119)( 11,368, 35,390,522,408,199, ++> 415,440,326, 87,503)( 12,412, 55,457,399,245,201, 33,438,431, 88,317) ++> ( 13,471, 40,348,452,292, 43,346,373, 77, 41,347)( 14,137,174,162, 60, 69,321, ++> 487, 61,158,322,370)( 15,101,114,109,130,160,488,489,352,351,420, 17) ++> ( 18,339,167,290,202,385, 99, 22, 90,323,217,129)( 19, 26, 93,304, 96,342) ++> ( 20,338,166,305,215,141, 97, 24, 51,150,219,507)( 21,337, 63,186,214,424, 98, ++> 23,107,382,218,349)( 27, 91,445,451,525, 67,519,239,144,203,155,353) ++> ( 28,324,444,128, 70,428,496,238,286,300,283, 64)( 30,236,287,441,387,354) ++> ( 31,345,366,517, 45,344,413,521, 46,248,244,121)( 34,314,394,402,222,447, 81, ++> 282,262,173,246,435)( 36,482,178,364,148,495,179,363,140,102,113,111) ++> ( 37,253,273,168,294,302,226,183, 72,480,154,233)( 38,483,520,393,403,465,362, ++> 298,143,356,153,369)( 39,157,320,472)( 42,228,277,264)( 44,343,147,501) ++> ( 47, 73,308,380,184,389,310,327,163,295,151,425)( 49,221,456, 80,474,260,405, ++> 325,164,524,152,449)( 50,479,365,477,461,459,497,169,296,247,134,117) ++> ( 52,361,299,285,355,188,423,464,434,453,133,118)( 53,257,509, 68,511,458,293, ++> 204,384,374, 75, 82)( 57,116,112,149,514,396,470,485,493,249,421,120) ++> ( 58,500,266,250,429,122)( 62,156,319,311)( 65,187,225,357,127, 71,388,235, ++> 460,252,274,371)( 66,106,462,291,205,383,372, 76, 92,410,280,498) ++> ( 74,401,381,476,409,281,171,104,297,307,426,182)( 78, 84,261,256,180,436,512, ++> 313,181,491,224,499)( 83,466,255,508,506,395,469,422,142,103,115,110) ++> ( 85,468,258,502,267,136)( 94,341)( 95,211)(105,478,195,432,518,316,197,484, ++> 494,455,196,170)(145,513,359,232,227,254)(172,209,398,207,279,206) ++> (185,194,309,443)(189,406,463,318,450,427,433,454,315,301,284,358) ++> (193,229,276,240)(208,397)(210,213,212) ++> ,( 1,379,148, 48,128,430,416)( 2, 34,338, 35,235,131,521)( 3,512,352, 47, ++> 318,289,237)( 4,272,506, 49,434,486,282)( 5,524,485, 10,483,340, 55) ++> ( 6,458, 36,487, 60,121, 16)( 7,313,140,336,127,435,270)( 8, 85,147,489, ++> 98,201,417)( 9,469, 94,488,129,329,400)( 11,291, 26, 54,234,473,169) ++> ( 12,207,339, 56,233,503,515)( 13,426,337, 40,232,295,500)( 14, 32,414, 27, ++> 167,130,472)( 15, 33,188, 38,382,109,501)( 17, 31,459, 37,496,132,517) ++> ( 18,263,294,446,451,134,497)( 19,198,525,241,441,244,470)( 20,100,199,490, ++> 242,429,413)( 21,378,403,216,523,421, 58)( 22,124,159, 77, 63,123,292) ++> ( 23,176,275,431,168, 86,293)( 24,177,492,326,104,151,290)( 25, 79,437,269, ++> 163,152,144)( 28,462,150,162, 62,120,415)( 29,239, 83,311, 61,117,260) ++> ( 30,452,149,370, 39,122,389)( 41,468, 73,254,277,432,371)( 42,210,319,502, ++> 373,205,283)( 43,387,194,212,320,508, 99)( 44,396,349,331,399,250,420) ++> ( 45,411,461,375,475,377,418)( 46,344,409,519,522,477,419)( 50,253,278,433, ++> 231, 88,422)( 51,482,138,358,229,463,381)( 52, 91,467,221,230,518,484) ++> ( 53,390,510,494,228,454, 92)( 57,310,460,118,259,367,363)( 59,281,227,274, ++> 505,402,215)( 64,125,245, 76, 93,160,471)( 65,126,408, 75,166, 69,264) ++> ( 66,302,186,116,257,424,327)( 67,187,297,479,217,425,171)( 68,303,296,345, ++> 280,226,273)( 70,240,359,366,364, 97,200)( 71,265,360,394,393,133,423) ++> ( 72,251,146,164,268, 87,312)( 74,252,276,406,513, 89,181)( 78,395,158,185, ++> 315,287,333)( 80,136,351,156,316,286,334)( 81,511,350,184,317,288,335) ++> ( 82,261,392,183,105,309,238)( 84,224,439,182,284,193,236)( 90,466,391,357, ++> 443,170,465)( 95,321,509,353,203,243,197)( 96,516,498,354,300,246,401) ++> (101,405,453,464,154,112,341)(102,139,450,208,388,365,111)(103,440,520,285, ++> 192,266,343)(106,308,218,119,262,448,298)(107,219,368,356,442,301,209) ++> (108,514,412,355,376,474,222)(110,495,137,478,361,444,380)(113,255,342,175, ++> 173,247,305)(114,256,141,328,153,307,304)(115,258,385,325,172,214,306) ++> (135,493,157,455,362,445,407)(142,346,189,398,323,161,499)(143,190,145,436, ++> 271,165,314)(155,195,211,174,404,374,204)(178,507,332,330,248,249,179) ++> (180,372,202,386,196,213,322)(191,267,491,384,438,279,225)(206,428,299,369, ++> 480,220,449)(223,481,383,427,397,324,504)(347,457,447,410,348,456,476));; ++gap> Length(Orbit(gp,set,OnSets)); ++241920 +diff --git a/tst/teststandard/hash2.tst b/tst/teststandard/hash2.tst +index 6bfa4d3..d47452e 100644 +--- a/tst/teststandard/hash2.tst ++++ b/tst/teststandard/hash2.tst +@@ -32,4 +32,8 @@ gap> Length(Orbit(h,h.1[1],OnRight)); + 2079 + gap> Length(Orbit(h,h.2^5,OnPoints)); + 693 ++gap> Length(Orbit(SymmetricGroup(14), [1 .. 7], OnSets)); ++3432 ++gap> Length(Orbit(SymmetricGroup(16), [1 .. 8], OnSets)); ++12870 + gap> STOP_TEST( "hash2.tst", 1); diff --git a/build/pkgs/gap/spkg-check.in b/build/pkgs/gap/spkg-check.in index d2fccda6e04..6dc12ca9266 100644 --- a/build/pkgs/gap/spkg-check.in +++ b/build/pkgs/gap/spkg-check.in @@ -10,7 +10,8 @@ cd pkg/io make cd ../.. -make testinstall +# This is the same as 'dev/ci.sh testinstall' (but dev/ci.sh is not part of the GAP tarball) +./gap tst/testinstall.g if [[ $? -ne 0 ]]; then exit 1 fi diff --git a/build/pkgs/gap/spkg-configure.m4 b/build/pkgs/gap/spkg-configure.m4 index d4c3680b430..d52d2c20b8c 100644 --- a/build/pkgs/gap/spkg-configure.m4 +++ b/build/pkgs/gap/spkg-configure.m4 @@ -2,8 +2,8 @@ SAGE_SPKG_CONFIGURE([gap], [ # Default to installing the SPKG, if the check is run at all. sage_spkg_install_gap=yes - m4_pushdef([GAP_MINVER],["4.12.2"]) - m4_pushdef([GAP_LTVER],["4.13.0"]) + m4_pushdef([GAP_MINVER],["4.13.0"]) + m4_pushdef([GAP_LTVER],["5.0.0"]) SAGE_SPKG_DEPCHECK([ncurses readline zlib], [ AC_PATH_PROG(GAP, gap) diff --git a/build/pkgs/gap_jupyter/distros/fedora.txt b/build/pkgs/gap_jupyter/distros/fedora.txt new file mode 100644 index 00000000000..0ceec7c99a4 --- /dev/null +++ b/build/pkgs/gap_jupyter/distros/fedora.txt @@ -0,0 +1 @@ +gap-pkg-jupyterkernel diff --git a/build/pkgs/gap_packages/distros/fedora.txt b/build/pkgs/gap_packages/distros/fedora.txt new file mode 100644 index 00000000000..24d6af73b6b --- /dev/null +++ b/build/pkgs/gap_packages/distros/fedora.txt @@ -0,0 +1,27 @@ +gap-pkg-cohomolo +gap-pkg-corelg +gap-pkg-crime +gap-pkg-cryst +gap-pkg-ctbllib +gap-pkg-design +gap-pkg-factint +GAPDoc +gap-pkg-gbnp +gap-pkg-grape +gap-pkg-guava +gap-pkg-hap +gap-pkg-hapcryst +gap-pkg-hecke +gap-pkg-laguna +gap-pkg-liealgdb +gap-pkg-liepring +gap-pkg-liering +gap-pkg-loops +gap-pkg-mapclass +gap-pkg-polymaking +gap-pkg-qpa +gap-pkg-quagroup +gap-pkg-repsn +gap-pkg-sla +gap-pkg-sonata +gap-pkg-toric diff --git a/build/pkgs/gast/distros/fedora.txt b/build/pkgs/gast/distros/fedora.txt new file mode 100644 index 00000000000..40cddc76e37 --- /dev/null +++ b/build/pkgs/gast/distros/fedora.txt @@ -0,0 +1 @@ +python3-gast diff --git a/build/pkgs/gc/checksums.ini b/build/pkgs/gc/checksums.ini index ede35b376a2..109f63bce95 100644 --- a/build/pkgs/gc/checksums.ini +++ b/build/pkgs/gc/checksums.ini @@ -1,4 +1,4 @@ tarball=gc-VERSION.tar.gz -sha1=3f543532c47e592a8f5ea6f7a529c8ed7465a5c7 -sha256=b9183fe49d4c44c7327992f626f8eaa1d8b14de140f243edb1c9dcff7719a7fc +sha1=1c8d7bde86aa98df957563982f38c583c2c6707f +sha256=7649020621cb26325e1fb5c8742590d92fb48ce5c259b502faf7d9fb5dabb160 upstream_url=https://github.com/ivmai/bdwgc/releases/download/vVERSION/gc-VERSION.tar.gz diff --git a/build/pkgs/gc/package-version.txt b/build/pkgs/gc/package-version.txt index d00d9ba64a3..fc10bd4825e 100644 --- a/build/pkgs/gc/package-version.txt +++ b/build/pkgs/gc/package-version.txt @@ -1 +1 @@ -8.2.6 +8.2.8 diff --git a/build/pkgs/gcc/SPKG.rst b/build/pkgs/gcc/SPKG.rst index 1f90eb0bf67..7e01df5bea8 100644 --- a/build/pkgs/gcc/SPKG.rst +++ b/build/pkgs/gcc/SPKG.rst @@ -61,9 +61,9 @@ you need a recent version of Xcode. (Installing the ``gfortran`` SPKG becomes a no-op in this case.) -Building Sage from source on Apple Silicon (M1/M2) requires the use of -Apple's Command Line Tools, and those tools include a suitable -compiler. Sage's ``gcc`` SPKG is not suitable for M1/M2; building it +Building Sage from source on Apple Silicon (M1, M2, M3, M4; arm64) requires +the use of Apple's Command Line Tools, and those tools include a suitable +compiler. Sage's ``gcc`` SPKG is not suitable for Apple Silicon; building it will likely fail. License diff --git a/build/pkgs/gcc/checksums.ini b/build/pkgs/gcc/checksums.ini index 272d516f07d..f9c9ba9f3a8 100644 --- a/build/pkgs/gcc/checksums.ini +++ b/build/pkgs/gcc/checksums.ini @@ -1,4 +1,4 @@ tarball=gcc-VERSION.tar.xz -sha1=5f95b6d042fb37d45c6cbebfc91decfbc4fb493c -sha256=e275e76442a6067341a27f04c5c6b83d8613144004c0413528863dc6b5c743da +sha1=6501872415823c95d48be28853ce3ebd6c1040c4 +sha256=0845e9621c9543a13f484e94584a49ffc0129970e9914624235fc1d061a0c083 upstream_url=https://mirrors.kernel.org/gnu/gcc/gcc-VERSION/gcc-VERSION.tar.xz diff --git a/build/pkgs/gcc/package-version.txt b/build/pkgs/gcc/package-version.txt index 67aee23940e..ac565bc1cab 100644 --- a/build/pkgs/gcc/package-version.txt +++ b/build/pkgs/gcc/package-version.txt @@ -1 +1 @@ -13.2.0 +13.3.0 diff --git a/build/pkgs/gcc/patches/68057560ff1fc0fb2df38c2f9627a20c9a8da5c5.patch b/build/pkgs/gcc/patches/68057560ff1fc0fb2df38c2f9627a20c9a8da5c5.patch deleted file mode 100644 index 0672eb2936e..00000000000 --- a/build/pkgs/gcc/patches/68057560ff1fc0fb2df38c2f9627a20c9a8da5c5.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Francois-Xavier Coudert -Date: Thu, 7 Mar 2024 13:36:03 +0000 (+0100) -Subject: Include safe-ctype.h after C++ standard headers, to avoid over-poisoning -X-Git-Url: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff_plain;h=68057560ff1fc0fb2df38c2f9627a20c9a8da5c5 - -Include safe-ctype.h after C++ standard headers, to avoid over-poisoning - -When building gcc's C++ sources against recent libc++, the poisoning of -the ctype macros due to including safe-ctype.h before including C++ -standard headers such as , , etc, causes many compilation -errors, similar to: - - In file included from /home/dim/src/gcc/master/gcc/gensupport.cc:23: - In file included from /home/dim/src/gcc/master/gcc/system.h:233: - In file included from /usr/include/c++/v1/vector:321: - In file included from - /usr/include/c++/v1/__format/formatter_bool.h:20: - In file included from - /usr/include/c++/v1/__format/formatter_integral.h:32: - In file included from /usr/include/c++/v1/locale:202: - /usr/include/c++/v1/__locale:546:5: error: '__abi_tag__' attribute - only applies to structs, variables, functions, and namespaces - 546 | _LIBCPP_INLINE_VISIBILITY - | ^ - /usr/include/c++/v1/__config:813:37: note: expanded from macro - '_LIBCPP_INLINE_VISIBILITY' - 813 | # define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI - | ^ - /usr/include/c++/v1/__config:792:26: note: expanded from macro - '_LIBCPP_HIDE_FROM_ABI' - 792 | - __attribute__((__abi_tag__(_LIBCPP_TOSTRING( - _LIBCPP_VERSIONED_IDENTIFIER)))) - | ^ - In file included from /home/dim/src/gcc/master/gcc/gensupport.cc:23: - In file included from /home/dim/src/gcc/master/gcc/system.h:233: - In file included from /usr/include/c++/v1/vector:321: - In file included from - /usr/include/c++/v1/__format/formatter_bool.h:20: - In file included from - /usr/include/c++/v1/__format/formatter_integral.h:32: - In file included from /usr/include/c++/v1/locale:202: - /usr/include/c++/v1/__locale:547:37: error: expected ';' at end of - declaration list - 547 | char_type toupper(char_type __c) const - | ^ - /usr/include/c++/v1/__locale:553:48: error: too many arguments - provided to function-like macro invocation - 553 | const char_type* toupper(char_type* __low, const - char_type* __high) const - | ^ - /home/dim/src/gcc/master/gcc/../include/safe-ctype.h:146:9: note: - macro 'toupper' defined here - 146 | #define toupper(c) do_not_use_toupper_with_safe_ctype - | ^ - -This is because libc++ uses different transitive includes than -libstdc++, and some of those transitive includes pull in various ctype -declarations (typically via ). - -There was already a special case for including before -safe-ctype.h, so move the rest of the C++ standard header includes to -the same location, to fix the problem. - - PR middle-end/111632 - -gcc/ChangeLog: - - * system.h: Include safe-ctype.h after C++ standard headers. - -Signed-off-by: Dimitry Andric -(cherry picked from commit 9970b576b7e4ae337af1268395ff221348c4b34a) ---- - -diff --git a/gcc/system.h b/gcc/system.h -index 33e9d4211150..03ab33ac960f 100644 ---- a/gcc/system.h -+++ b/gcc/system.h -@@ -194,27 +194,8 @@ extern int fprintf_unlocked (FILE *, const char *, ...); - #undef fread_unlocked - #undef fwrite_unlocked - --/* Include before "safe-ctype.h" to avoid GCC poisoning -- the ctype macros through safe-ctype.h */ -- --#ifdef __cplusplus --#ifdef INCLUDE_STRING --# include --#endif --#endif -- --/* There are an extraordinary number of issues with . -- The last straw is that it varies with the locale. Use libiberty's -- replacement instead. */ --#include "safe-ctype.h" -- --#include -- --#include -- --#if !defined (errno) && defined (HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO --extern int errno; --#endif -+/* Include C++ standard headers before "safe-ctype.h" to avoid GCC -+ poisoning the ctype macros through safe-ctype.h */ - - #ifdef __cplusplus - #if defined (INCLUDE_ALGORITHM) || !defined (HAVE_SWAP_IN_UTILITY) -@@ -229,6 +210,9 @@ extern int errno; - #ifdef INCLUDE_SET - # include - #endif -+#ifdef INCLUDE_STRING -+# include -+#endif - #ifdef INCLUDE_VECTOR - # include - #endif -@@ -245,6 +229,19 @@ extern int errno; - # include - #endif - -+/* There are an extraordinary number of issues with . -+ The last straw is that it varies with the locale. Use libiberty's -+ replacement instead. */ -+#include "safe-ctype.h" -+ -+#include -+ -+#include -+ -+#if !defined (errno) && defined (HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO -+extern int errno; -+#endif -+ - /* Some of glibc's string inlines cause warnings. Plus we'd rather - rely on (and therefore test) GCC's string builtins. */ - #define __NO_STRING_INLINES diff --git a/build/pkgs/gcc/patches/e95ab9e60ce1d9aa7751d79291133fd5af9209d7.patch b/build/pkgs/gcc/patches/e95ab9e60ce1d9aa7751d79291133fd5af9209d7.patch deleted file mode 100644 index 6fb61b58ed2..00000000000 --- a/build/pkgs/gcc/patches/e95ab9e60ce1d9aa7751d79291133fd5af9209d7.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Francois-Xavier Coudert -Date: Sat, 16 Mar 2024 08:50:00 +0000 (+0100) -Subject: libcc1: fix include -X-Git-Url: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff_plain;h=e95ab9e60ce1d9aa7751d79291133fd5af9209d7 - -libcc1: fix include - -Use INCLUDE_VECTOR before including system.h, instead of directly -including , to avoid running into poisoned identifiers. - -Signed-off-by: Dimitry Andric - - PR middle-end/111632 - -libcc1/ChangeLog: - - * libcc1plugin.cc: Fix include. - * libcp1plugin.cc: Fix include. - -(cherry picked from commit 5213047b1d50af63dfabb5e5649821a6cb157e33) ---- - -diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc -index 7e0fecae1456..44bcf56698ee 100644 ---- a/libcc1/libcc1plugin.cc -+++ b/libcc1/libcc1plugin.cc -@@ -32,6 +32,7 @@ - #undef PACKAGE_VERSION - - #define INCLUDE_MEMORY -+#define INCLUDE_VECTOR - #include "gcc-plugin.h" - #include "system.h" - #include "coretypes.h" -@@ -69,8 +70,6 @@ - #include "gcc-c-interface.h" - #include "context.hh" - --#include -- - using namespace cc1_plugin; - - -diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc -index 8d394c0cfdb8..9586a2afdb47 100644 ---- a/libcc1/libcp1plugin.cc -+++ b/libcc1/libcp1plugin.cc -@@ -33,6 +33,7 @@ - #undef PACKAGE_VERSION - - #define INCLUDE_MEMORY -+#define INCLUDE_VECTOR - #include "gcc-plugin.h" - #include "system.h" - #include "coretypes.h" -@@ -71,8 +72,6 @@ - #include "rpc.hh" - #include "context.hh" - --#include -- - using namespace cc1_plugin; - - diff --git a/build/pkgs/gcc/patches/gcc-13-homebrew.patch b/build/pkgs/gcc/patches/gcc-13-homebrew.patch deleted file mode 100644 index 8cedce8bc46..00000000000 --- a/build/pkgs/gcc/patches/gcc-13-homebrew.patch +++ /dev/null @@ -1,71 +0,0 @@ -Patch included in https://github.com/Homebrew/homebrew-core/blob/50d9d78a4a09b42807b0a8f74f1f2f8933051a7b/Formula/g/gcc@13.rb - -diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x -index 416d2c2e3a4..e52f11d8460 100644 ---- a/fixincludes/fixincl.x -+++ b/fixincludes/fixincl.x -@@ -2,11 +2,11 @@ - * - * DO NOT EDIT THIS FILE (fixincl.x) - * -- * It has been AutoGen-ed January 22, 2023 at 09:03:29 PM by AutoGen 5.18.12 -+ * It has been AutoGen-ed August 17, 2023 at 10:16:38 AM by AutoGen 5.18.12 - * From the definitions inclhack.def - * and the template file fixincl - */ --/* DO NOT SVN-MERGE THIS FILE, EITHER Sun Jan 22 21:03:29 CET 2023 -+/* DO NOT SVN-MERGE THIS FILE, EITHER Thu Aug 17 10:16:38 CEST 2023 - * - * You must regenerate it. Use the ./genfixes script. - * -@@ -3674,7 +3674,7 @@ tSCC* apzDarwin_Flt_Eval_MethodMachs[] = { - * content selection pattern - do fix if pattern found - */ - tSCC zDarwin_Flt_Eval_MethodSelect0[] = -- "^#if __FLT_EVAL_METHOD__ == 0$"; -+ "^#if __FLT_EVAL_METHOD__ == 0( \\|\\| __FLT_EVAL_METHOD__ == -1)?$"; - - #define DARWIN_FLT_EVAL_METHOD_TEST_CT 1 - static tTestDesc aDarwin_Flt_Eval_MethodTests[] = { -@@ -3685,7 +3685,7 @@ static tTestDesc aDarwin_Flt_Eval_MethodTests[] = { - */ - static const char* apzDarwin_Flt_Eval_MethodPatch[] = { - "format", -- "#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 16", -+ "%0 || __FLT_EVAL_METHOD__ == 16", - (char*)NULL }; - - /* * * * * * * * * * * * * * * * * * * * * * * * * * -diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def -index 45e0cbc0c10..19e0ea2df66 100644 ---- a/fixincludes/inclhack.def -+++ b/fixincludes/inclhack.def -@@ -1819,10 +1819,11 @@ fix = { - hackname = darwin_flt_eval_method; - mach = "*-*-darwin*"; - files = math.h; -- select = "^#if __FLT_EVAL_METHOD__ == 0$"; -+ select = "^#if __FLT_EVAL_METHOD__ == 0( \\|\\| __FLT_EVAL_METHOD__ == -1)?$"; - c_fix = format; -- c_fix_arg = "#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 16"; -- test_text = "#if __FLT_EVAL_METHOD__ == 0"; -+ c_fix_arg = "%0 || __FLT_EVAL_METHOD__ == 16"; -+ test_text = "#if __FLT_EVAL_METHOD__ == 0\n" -+ "#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == -1"; - }; - - /* -diff --git a/fixincludes/tests/base/math.h b/fixincludes/tests/base/math.h -index 29b67579748..7b92f29a409 100644 ---- a/fixincludes/tests/base/math.h -+++ b/fixincludes/tests/base/math.h -@@ -32,6 +32,7 @@ - - #if defined( DARWIN_FLT_EVAL_METHOD_CHECK ) - #if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 16 -+#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == -1 || __FLT_EVAL_METHOD__ == 16 - #endif /* DARWIN_FLT_EVAL_METHOD_CHECK */ - - --- -2.39.3 diff --git a/build/pkgs/gcc/patches/gcc-13.2.0-arm.patch b/build/pkgs/gcc/patches/gcc-13_3_0.patch similarity index 70% rename from build/pkgs/gcc/patches/gcc-13.2.0-arm.patch rename to build/pkgs/gcc/patches/gcc-13_3_0.patch index 0a3688f7d90..f121fdb6461 100644 --- a/build/pkgs/gcc/patches/gcc-13.2.0-arm.patch +++ b/build/pkgs/gcc/patches/gcc-13_3_0.patch @@ -1,5 +1,5 @@ diff --git a/Makefile.def b/Makefile.def -index 35e994eb77e..9b4a8a2bf7a 100644 +index 35e994e..9b4a8a2 100644 --- a/Makefile.def +++ b/Makefile.def @@ -47,7 +47,8 @@ host_modules= { module= fixincludes; bootstrap=true; @@ -13,7 +13,7 @@ index 35e994eb77e..9b4a8a2bf7a 100644 // Work around in-tree gmp configure bug with missing flex. extra_configure_flags='--disable-shared LEX="touch lex.yy.c" @host_libs_picflag@'; diff --git a/Makefile.in b/Makefile.in -index 06a9398e172..0973ec3a71d 100644 +index 205d3c3..fdfd3d7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -12016,7 +12016,7 @@ configure-gcc: @@ -115,11 +115,8 @@ index 06a9398e172..0973ec3a71d 100644 @endif gcc-bootstrap -diff --git a/aclocal.m4 b/aclocal.m4 -new file mode 100644 -index 00000000000..e69de29bb2d diff --git a/c++tools/Makefile.in b/c++tools/Makefile.in -index 77bda3d56dc..dcb1029e064 100644 +index 77bda3d..dcb1029 100644 --- a/c++tools/Makefile.in +++ b/c++tools/Makefile.in @@ -29,8 +29,9 @@ AUTOCONF := @AUTOCONF@ @@ -152,7 +149,7 @@ index 77bda3d56dc..dcb1029e064 100644 # copy to gcc dir so tests there can run all::../gcc/g++-mapper-server$(exeext) diff --git a/c++tools/configure b/c++tools/configure -index 742816e4253..88087009383 100755 +index 742816e..8808700 100755 --- a/c++tools/configure +++ b/c++tools/configure @@ -627,7 +627,8 @@ get_gcc_base_ver @@ -205,7 +202,7 @@ index 742816e4253..88087009383 100755 # Check if O_CLOEXEC is defined by fcntl diff --git a/c++tools/configure.ac b/c++tools/configure.ac -index 23e98c8e721..44dfaccbbfa 100644 +index 23e98c8..44dfacc 100644 --- a/c++tools/configure.ac +++ b/c++tools/configure.ac @@ -102,8 +102,15 @@ fi @@ -227,7 +224,7 @@ index 23e98c8e721..44dfaccbbfa 100644 # Check if O_CLOEXEC is defined by fcntl AC_CACHE_CHECK(for O_CLOEXEC, ac_cv_o_cloexec, [ diff --git a/configure b/configure -index 117a7ef23f2..ee9dd18d2a3 100755 +index 117a7ef..c721ee4 100755 --- a/configure +++ b/configure @@ -687,7 +687,10 @@ extra_host_zlib_configure_flags @@ -257,7 +254,16 @@ index 117a7ef23f2..ee9dd18d2a3 100755 --enable-host-shared build host code as shared libraries --enable-stage1-languages[=all] choose additional languages to build during stage1. -@@ -8414,6 +8419,20 @@ else +@@ -3451,6 +3456,8 @@ esac + + # Disable libffi for some systems. + case "${target}" in ++ aarch64*-*-darwin2*) ++ ;; + powerpc-*-darwin*) + ;; + i[3456789]86-*-darwin*) +@@ -8414,6 +8421,20 @@ else fi fi @@ -278,7 +284,7 @@ index 117a7ef23f2..ee9dd18d2a3 100755 # GCC GRAPHITE dependency isl. -@@ -8645,6 +8664,39 @@ fi +@@ -8645,6 +8666,39 @@ fi @@ -318,7 +324,7 @@ index 117a7ef23f2..ee9dd18d2a3 100755 # Enable --enable-host-shared. # Checked early to determine whether jit is an 'all' language # Check whether --enable-host-shared was given. -@@ -8654,26 +8706,57 @@ if test "${enable_host_shared+set}" = set; then : +@@ -8654,26 +8708,57 @@ if test "${enable_host_shared+set}" = set; then : x86_64-*-darwin* | aarch64-*-darwin*) if test x$host_shared != xyes ; then # PIC is the default, and actually cannot be switched off. @@ -380,10 +386,19 @@ index 117a7ef23f2..ee9dd18d2a3 100755 fi diff --git a/configure.ac b/configure.ac -index b3e9bbd2aa5..4d390f86c7e 100644 +index b3e9bbd..a75c9e8 100644 --- a/configure.ac +++ b/configure.ac -@@ -1806,6 +1806,20 @@ AC_ARG_WITH(boot-ldflags, +@@ -710,6 +710,8 @@ esac + + # Disable libffi for some systems. + case "${target}" in ++ aarch64*-*-darwin2*) ++ ;; + powerpc-*-darwin*) + ;; + i[[3456789]]86-*-darwin*) +@@ -1806,6 +1808,20 @@ AC_ARG_WITH(boot-ldflags, if test "$poststage1_libs" = ""; then poststage1_ldflags="-static-libstdc++ -static-libgcc" fi]) @@ -404,7 +419,7 @@ index b3e9bbd2aa5..4d390f86c7e 100644 AC_SUBST(poststage1_ldflags) # GCC GRAPHITE dependency isl. -@@ -1891,6 +1905,36 @@ AC_ARG_ENABLE(linker-plugin-flags, +@@ -1891,6 +1907,36 @@ AC_ARG_ENABLE(linker-plugin-flags, extra_linker_plugin_flags=) AC_SUBST(extra_linker_plugin_flags) @@ -441,7 +456,7 @@ index b3e9bbd2aa5..4d390f86c7e 100644 # Enable --enable-host-shared. # Checked early to determine whether jit is an 'all' language AC_ARG_ENABLE(host-shared, -@@ -1901,23 +1945,52 @@ AC_ARG_ENABLE(host-shared, +@@ -1901,23 +1947,52 @@ AC_ARG_ENABLE(host-shared, x86_64-*-darwin* | aarch64-*-darwin*) if test x$host_shared != xyes ; then # PIC is the default, and actually cannot be switched off. @@ -498,7 +513,7 @@ index b3e9bbd2aa5..4d390f86c7e 100644 fi AC_SUBST(host_libs_picflag) diff --git a/fixincludes/Makefile.in b/fixincludes/Makefile.in -index 1937dcaa32d..e6ce41dba39 100644 +index 1937dca..e6ce41d 100644 --- a/fixincludes/Makefile.in +++ b/fixincludes/Makefile.in @@ -73,7 +73,7 @@ default : all @@ -542,7 +557,7 @@ index 1937dcaa32d..e6ce41dba39 100644 $(ALLOBJ) : $(HDR) fixincl.o : fixincl.c $(srcdir)/fixincl.x diff --git a/fixincludes/configure b/fixincludes/configure -index bdcc41f6ddc..a5e995f5316 100755 +index bdcc41f..b2759ee 100755 --- a/fixincludes/configure +++ b/fixincludes/configure @@ -623,6 +623,8 @@ ac_subst_vars='LTLIBOBJS @@ -570,15 +585,7 @@ index bdcc41f6ddc..a5e995f5316 100755 --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer -@@ -3022,6 +3026,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - # --------------------------- - # _LT_COMPILER_PIC - -+enable_darwin_at_rpath_$1=no - - # _LT_LINKER_SHLIBS([TAGNAME]) - # ---------------------------- -@@ -3044,7 +3049,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +@@ -3044,7 +3048,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # the compiler configuration to `libtool'. # _LT_LANG_CXX_CONFIG @@ -586,7 +593,7 @@ index bdcc41f6ddc..a5e995f5316 100755 # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose -@@ -4835,6 +4839,15 @@ $as_echo "#define SEPARATE_FIX_PROC 1" >>confdefs.h +@@ -4835,6 +4838,15 @@ $as_echo "#define SEPARATE_FIX_PROC 1" >>confdefs.h fi @@ -603,7 +610,7 @@ index bdcc41f6ddc..a5e995f5316 100755 vax-dec-bsd* ) diff --git a/fixincludes/configure.ac b/fixincludes/configure.ac -index ef2227e3c93..4e78511d20f 100644 +index ef2227e..4e78511 100644 --- a/fixincludes/configure.ac +++ b/fixincludes/configure.ac @@ -68,6 +68,14 @@ if test $TARGET = twoprocess; then @@ -622,7 +629,7 @@ index ef2227e3c93..4e78511d20f 100644 vax-dec-bsd* ) AC_DEFINE(exit, xexit, [Define to xexit if the host system does not support atexit]) diff --git a/gcc/Makefile.in b/gcc/Makefile.in -index 775aaa1b3c4..2b0d8f9cd01 100644 +index 775aaa1..740199c 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -158,6 +158,9 @@ LDFLAGS = @LDFLAGS@ @@ -730,14 +737,14 @@ index 775aaa1b3c4..2b0d8f9cd01 100644 echo "set COMPAT_OPTIONS \"$(COMPAT_OPTIONS)\"" >> ./site.tmp; \ else true; \ fi -+ @if test "x@enable_darwin_at_rpath@" = "xyes" ; then \ ++ @if test "X@ENABLE_DARWIN_AT_RPATH_TRUE@" != "X#" ; then \ + echo "set ENABLE_DARWIN_AT_RPATH 1" >> ./site.tmp; \ + fi @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./site.tmp @cat ./site.tmp > site.exp @cat site.bak | sed \ diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 -index 6be36df5190..126e09bbcd1 100644 +index 6be36df..126e09b 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -12,6 +12,56 @@ @@ -798,7 +805,7 @@ index 6be36df5190..126e09bbcd1 100644 m4_include([../ltoptions.m4]) m4_include([../ltsugar.m4]) diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in -index 9507f2f0920..2b9b0de8273 100644 +index 9507f2f..2b9b0de 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -72,7 +72,8 @@ else @@ -830,7 +837,7 @@ index 9507f2f0920..2b9b0de8273 100644 include $(srcdir)/ada/Make-generated.in diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in -index da6a56fcec8..51a4bf17038 100644 +index da6a56f..51a4bf1 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -91,6 +91,7 @@ LS = ls @@ -880,21 +887,539 @@ index da6a56fcec8..51a4bf17038 100644 $(THREADSLIB) -Wl,libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) cd $(RTSDIR); $(LN_S) libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ libgnat$(soext) +diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc +index 4389ff9..0fe5d2a 100644 +--- a/gcc/analyzer/kf.cc ++++ b/gcc/analyzer/kf.cc +@@ -1081,7 +1081,7 @@ register_known_functions (known_function_manager &kfm) + like this: + extern int *___errno(void) __attribute__((__const__)); + #define errno (*(___errno())) +- and OS X like this: ++ and macOS like this: + extern int * __error(void); + #define errno (*__error()) + and similarly __errno for newlib. +diff --git a/gcc/builtins.cc b/gcc/builtins.cc +index 1bfdc59..1122527 100644 +--- a/gcc/builtins.cc ++++ b/gcc/builtins.cc +@@ -5501,6 +5501,13 @@ expand_builtin_trap (void) + static void + expand_builtin_unreachable (void) + { ++ /* If the target wants a trap in place of the fall-through, use that. */ ++ if (targetm.unreachable_should_trap ()) ++ { ++ expand_builtin_trap (); ++ return; ++ } ++ + /* Use gimple_build_builtin_unreachable or builtin_decl_unreachable + to avoid this. */ + gcc_checking_assert (!sanitize_flags_p (SANITIZE_UNREACHABLE)); +@@ -7958,6 +7965,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, + case BUILT_IN_ADJUST_DESCRIPTOR: + return expand_builtin_adjust_descriptor (exp); + ++ case BUILT_IN_GCC_NESTED_PTR_CREATED: ++ case BUILT_IN_GCC_NESTED_PTR_DELETED: ++ break; /* At present, no expansion, just call the function. */ ++ + case BUILT_IN_FORK: + case BUILT_IN_EXECL: + case BUILT_IN_EXECV: diff --git a/gcc/builtins.def b/gcc/builtins.def -index 4ad95a12f83..922219963e3 100644 +index 4ad95a1..448cf83 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -1067,6 +1067,8 @@ DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline") DEF_BUILTIN_STUB (BUILT_IN_INIT_DESCRIPTOR, "__builtin_init_descriptor") DEF_BUILTIN_STUB (BUILT_IN_ADJUST_DESCRIPTOR, "__builtin_adjust_descriptor") DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto") -+DEF_BUILTIN_STUB (BUILT_IN_NESTED_PTR_CREATED, "__builtin_nested_func_ptr_created") -+DEF_BUILTIN_STUB (BUILT_IN_NESTED_PTR_DELETED, "__builtin_nested_func_ptr_deleted") ++DEF_EXT_LIB_BUILTIN (BUILT_IN_GCC_NESTED_PTR_CREATED, "__gcc_nested_func_ptr_created", BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LIST) ++DEF_EXT_LIB_BUILTIN (BUILT_IN_GCC_NESTED_PTR_DELETED, "__gcc_nested_func_ptr_deleted", BT_FN_VOID, ATTR_NOTHROW_LIST) /* Implementing __builtin_setjmp. */ DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup") +diff --git a/gcc/c/c-lang.cc b/gcc/c/c-lang.cc +index b4e0c8c..11e7aaa 100644 +--- a/gcc/c/c-lang.cc ++++ b/gcc/c/c-lang.cc +@@ -61,6 +61,15 @@ c_get_sarif_source_language (const char *) + return "c"; + } + ++/* Implement c-family hook to register language-specific features for ++ __has_{feature,extension}. */ ++ ++void ++c_family_register_lang_features () ++{ ++ c_register_features (); ++} ++ + #if CHECKING_P + + namespace selftest { +diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc +index e4aed61..fad4662 100644 +--- a/gcc/c/c-objc-common.cc ++++ b/gcc/c/c-objc-common.cc +@@ -34,6 +34,38 @@ along with GCC; see the file COPYING3. If not see + static bool c_tree_printer (pretty_printer *, text_info *, const char *, + int, bool, bool, bool, bool *, const char **); + ++/* Info for C language features which can be queried through ++ __has_{feature,extension}. */ ++ ++struct c_feature_info ++{ ++ const char *ident; ++ const int *enable_flag; ++}; ++ ++static const c_feature_info c_feature_table[] = ++{ ++ { "c_alignas", &flag_isoc11 }, ++ { "c_alignof", &flag_isoc11 }, ++ { "c_atomic", &flag_isoc11 }, ++ { "c_generic_selections", &flag_isoc11 }, ++ { "c_static_assert", &flag_isoc11 }, ++ { "c_thread_local", &flag_isoc11 } ++}; ++ ++/* Register features specific to the C language. */ ++ ++void ++c_register_features () ++{ ++ for (unsigned i = 0; i < ARRAY_SIZE (c_feature_table); i++) ++ { ++ const c_feature_info *info = c_feature_table + i; ++ const bool feat_p = !info->enable_flag || *info->enable_flag; ++ c_common_register_feature (info->ident, feat_p); ++ } ++} ++ + bool + c_missing_noreturn_ok_p (tree decl) + { +diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h +index d31dacb..34dc23a 100644 +--- a/gcc/c/c-objc-common.h ++++ b/gcc/c/c-objc-common.h +@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see + #ifndef GCC_C_OBJC_COMMON + #define GCC_C_OBJC_COMMON + ++/* Implemented in c-objc-common.cc. */ ++extern void c_register_features (); ++ + /* Lang hooks that are shared between C and ObjC are defined here. Hooks + specific to C or ObjC go in c-lang.cc and objc/objc-lang.cc, respectively. */ + +diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc +index 3627a3f..5abc6e8 100644 +--- a/gcc/c/c-parser.cc ++++ b/gcc/c/c-parser.cc +@@ -217,6 +217,9 @@ struct GTY(()) c_parser { + should translate them to the execution character set (false + inside attributes). */ + BOOL_BITFIELD translate_strings_p : 1; ++ /* True if we want to lex arbitrary number-like sequences as their ++ string representation. */ ++ BOOL_BITFIELD lex_number_as_string : 1; + + /* Objective-C specific parser/lexer information. */ + +@@ -291,10 +294,10 @@ c_lex_one_token (c_parser *parser, c_token *token, bool raw = false) + + if (raw || vec_safe_length (parser->raw_tokens) == 0) + { ++ int lex_flags = parser->lex_joined_string ? 0 : C_LEX_STRING_NO_JOIN; ++ lex_flags |= parser->lex_number_as_string ? C_LEX_NUMBER_AS_STRING : 0; + token->type = c_lex_with_flags (&token->value, &token->location, +- &token->flags, +- (parser->lex_joined_string +- ? 0 : C_LEX_STRING_NO_JOIN)); ++ &token->flags, lex_flags); + token->id_kind = C_ID_NONE; + token->keyword = RID_MAX; + token->pragma_kind = PRAGMA_NONE; +@@ -4993,6 +4996,88 @@ c_parser_gnu_attribute_any_word (c_parser *parser) + return attr_name; + } + ++/* Handle parsing clang-form attribute arguments, where we need to adjust ++ the parsing rules to relate to a specific attribute. */ ++ ++static tree ++c_parser_clang_attribute_arguments (c_parser *parser, tree /*attr_id*/) ++{ ++ /* We can, if required, alter the parsing on the basis of the attribute. ++ At present, we handle the availability attr, where ach entry can be : ++ identifier ++ identifier=N.MM.Z ++ identifier="string" ++ followed by ',' or ) for the last entry*/ ++ ++ tree attr_args = NULL_TREE; ++ do ++ { ++ tree name = NULL_TREE; ++ tree value = NULL_TREE; ++ ++ if (c_parser_next_token_is (parser, CPP_NAME) ++ && c_parser_peek_token (parser)->id_kind == C_ID_ID) ++ { ++ name = c_parser_peek_token (parser)->value; ++ c_parser_consume_token (parser); ++ } ++ else if (c_parser_next_token_is (parser, CPP_COMMA)) ++ name = error_mark_node; /* Comma handled below. */ ++ else ++ { ++ bool saved_join_state = parser->lex_joined_string; ++ parser->lex_number_as_string = 1; ++ parser->lex_joined_string = 1; ++ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, ++ "expected an attribute keyword"); ++ parser->lex_number_as_string = 0; ++ parser->lex_joined_string = saved_join_state; ++ return error_mark_node; ++ } ++ if (c_parser_next_token_is (parser, CPP_EQ)) ++ { ++ c_parser_consume_token (parser); /* eat the '=' */ ++ /* We need to bludgeon the lexer into not trying to interpret the ++ xx.yy.zz form, since that just looks like a malformed float. ++ Also, as a result of macro processing, we can have strig literals ++ that are in multiple pieces so, for this specific part of the ++ parse, we need to join strings. */ ++ bool saved_join_state = parser->lex_joined_string; ++ parser->lex_number_as_string = 1; ++ parser->lex_joined_string = 1; ++ /* So look at the next token, expecting a string, or something that ++ looks initially like a number, but might be a version number. */ ++ c_parser_peek_token (parser); ++ /* Done with the funky number parsing. */ ++ parser->lex_number_as_string = 0; ++ parser->lex_joined_string = saved_join_state; ++ if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN) ++ && c_parser_next_token_is_not (parser, CPP_COMMA)) ++ { ++ value = c_parser_peek_token (parser)->value; ++ /* ???: check for error mark and early-return? */ ++ c_parser_consume_token (parser); ++ } ++ /* else value is absent. */ ++ } ++ else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN) ++ && c_parser_next_token_is_not (parser, CPP_COMMA)) ++ { ++ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, ++ "expected %<,%> or %<=%>"); ++ return error_mark_node; ++ } ++ if (c_parser_next_token_is (parser, CPP_COMMA)) ++ c_parser_consume_token (parser); /* Just skip the comma. */ ++ tree t = tree_cons (value, name, NULL); ++ if (!attr_args) ++ attr_args = t; ++ else ++ chainon (attr_args, t); ++ } while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)); ++ return attr_args; ++} ++ + /* Parse attribute arguments. This is a common form of syntax + covering all currently valid GNU and standard attributes. + +@@ -5158,9 +5243,13 @@ c_parser_gnu_attribute (c_parser *parser, tree attrs, + attrs = chainon (attrs, attr); + return attrs; + } +- c_parser_consume_token (parser); ++ c_parser_consume_token (parser); /* The '('. */ + +- tree attr_args ++ tree attr_args; ++ if (attribute_clang_form_p (attr_name)) ++ attr_args = c_parser_clang_attribute_arguments (parser, attr_name); ++ else ++ attr_args + = c_parser_attribute_arguments (parser, + attribute_takes_identifier_p (attr_name), + false, +diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc +index 6770991..a0adac1 100644 +--- a/gcc/c-family/c-attribs.cc ++++ b/gcc/c-family/c-attribs.cc +@@ -607,6 +607,18 @@ attribute_takes_identifier_p (const_tree attr_id) + return targetm.attribute_takes_identifier_p (attr_id); + } + ++/* Returns TRUE iff the attribute indicated by ATTR_ID needs its ++ arguments converted to string constants. */ ++ ++bool ++attribute_clang_form_p (const_tree attr_id) ++{ ++ const struct attribute_spec *spec = lookup_attribute_spec (attr_id); ++ if (spec && !strcmp ("availability", spec->name)) ++ return true; ++ return false; ++} ++ + /* Verify that argument value POS at position ARGNO to attribute NAME + applied to function FN (which is either a function declaration or function + type) refers to a function parameter at position POS and the expected type +diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc +index 303d7f1..e3c3fae 100644 +--- a/gcc/c-family/c-common.cc ++++ b/gcc/c-family/c-common.cc +@@ -311,6 +311,44 @@ const struct fname_var_t fname_vars[] = + {NULL, 0, 0}, + }; + ++/* Flags to restrict availability of generic features that ++ are known to __has_{feature,extension}. */ ++ ++enum ++{ ++ HF_FLAG_NONE = 0, ++ HF_FLAG_EXT = 1, /* Available only as an extension. */ ++ HF_FLAG_SANITIZE = 2, /* Availability depends on sanitizer flags. */ ++}; ++ ++/* Info for generic features which can be queried through ++ __has_{feature,extension}. */ ++ ++struct hf_feature_info ++{ ++ const char *ident; ++ unsigned flags; ++ unsigned mask; ++}; ++ ++/* Table of generic features which can be queried through ++ __has_{feature,extension}. */ ++ ++static constexpr hf_feature_info has_feature_table[] = ++{ ++ { "address_sanitizer", HF_FLAG_SANITIZE, SANITIZE_ADDRESS }, ++ { "thread_sanitizer", HF_FLAG_SANITIZE, SANITIZE_THREAD }, ++ { "leak_sanitizer", HF_FLAG_SANITIZE, SANITIZE_LEAK }, ++ { "hwaddress_sanitizer", HF_FLAG_SANITIZE, SANITIZE_HWADDRESS }, ++ { "undefined_behavior_sanitizer", HF_FLAG_SANITIZE, SANITIZE_UNDEFINED }, ++ { "attribute_deprecated_with_message", HF_FLAG_NONE, 0 }, ++ { "attribute_unavailable_with_message", HF_FLAG_NONE, 0 }, ++ { "enumerator_attributes", HF_FLAG_NONE, 0 }, ++ { "tls", HF_FLAG_NONE, 0 }, ++ { "gnu_asm_goto_with_outputs", HF_FLAG_EXT, 0 }, ++ { "gnu_asm_goto_with_outputs_full", HF_FLAG_EXT, 0 } ++}; ++ + /* Global visibility options. */ + struct visibility_flags visibility_options; + +@@ -9552,4 +9590,63 @@ c_strict_flex_array_level_of (tree array_field) + return strict_flex_array_level; + } + ++/* Map from identifiers to booleans. Value is true for features, and ++ false for extensions. Used to implement __has_{feature,extension}. */ ++ ++using feature_map_t = hash_map ; ++static feature_map_t *feature_map; ++ ++/* Register a feature for __has_{feature,extension}. FEATURE_P is true ++ if the feature identified by NAME is a feature (as opposed to an ++ extension). */ ++ ++void ++c_common_register_feature (const char *name, bool feature_p) ++{ ++ bool dup = feature_map->put (get_identifier (name), feature_p); ++ gcc_checking_assert (!dup); ++} ++ ++/* Lazily initialize hash table for __has_{feature,extension}, ++ dispatching to the appropriate front end to register language-specific ++ features. */ ++ ++static void ++init_has_feature () ++{ ++ gcc_checking_assert (!feature_map); ++ feature_map = new feature_map_t; ++ ++ for (unsigned i = 0; i < ARRAY_SIZE (has_feature_table); i++) ++ { ++ const hf_feature_info *info = has_feature_table + i; ++ ++ if ((info->flags & HF_FLAG_SANITIZE) && !(flag_sanitize & info->mask)) ++ continue; ++ ++ const bool feature_p = !(info->flags & HF_FLAG_EXT); ++ c_common_register_feature (info->ident, feature_p); ++ } ++ ++ /* Register language-specific features. */ ++ c_family_register_lang_features (); ++} ++ ++/* If STRICT_P is true, evaluate __has_feature (IDENT). ++ Otherwise, evaluate __has_extension (IDENT). */ ++ ++bool ++has_feature_p (const char *ident, bool strict_p) ++{ ++ if (!feature_map) ++ init_has_feature (); ++ ++ tree name = canonicalize_attr_name (get_identifier (ident)); ++ bool *feat_p = feature_map->get (name); ++ if (!feat_p) ++ return false; ++ ++ return !strict_p || *feat_p; ++} ++ + #include "gt-c-family-c-common.h" +diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h +index f96350b..41d69d4 100644 +--- a/gcc/c-family/c-common.h ++++ b/gcc/c-family/c-common.h +@@ -1121,6 +1121,14 @@ extern bool c_cpp_diagnostic (cpp_reader *, enum cpp_diagnostic_level, + ATTRIBUTE_GCC_DIAG(5,0); + extern int c_common_has_attribute (cpp_reader *, bool); + extern int c_common_has_builtin (cpp_reader *); ++extern int c_common_has_feature (cpp_reader *, bool); ++ ++/* Implemented by each front end in *-lang.cc. */ ++extern void c_family_register_lang_features (); ++ ++/* Implemented in c-family/c-common.cc. */ ++extern void c_common_register_feature (const char *, bool); ++extern bool has_feature_p (const char *, bool); + + extern bool parse_optimize_options (tree, bool); + +@@ -1529,6 +1537,7 @@ extern void check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val, + /* In c-attribs.cc. */ + extern bool attribute_takes_identifier_p (const_tree); + extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *); ++extern bool attribute_clang_form_p (const_tree); + extern tree handle_unused_attribute (tree *, tree, tree, int, bool *); + extern tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *); + extern int parse_tm_stmt_attr (tree, int); +diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc +index 0acfdaa..2a504a9 100644 +--- a/gcc/c-family/c-lex.cc ++++ b/gcc/c-family/c-lex.cc +@@ -82,6 +82,7 @@ init_c_lex (void) + cb->read_pch = c_common_read_pch; + cb->has_attribute = c_common_has_attribute; + cb->has_builtin = c_common_has_builtin; ++ cb->has_feature = c_common_has_feature; + cb->get_source_date_epoch = cb_get_source_date_epoch; + cb->get_suggestion = cb_get_suggestion; + cb->remap_filename = remap_macro_filename; +@@ -457,16 +458,16 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax) + return result; + } + +-/* Callback for has_builtin. */ ++/* Helper for __has_{builtin,feature,extension}. */ + +-int +-c_common_has_builtin (cpp_reader *pfile) ++static const char * ++c_common_lex_availability_macro (cpp_reader *pfile, const char *builtin) + { + const cpp_token *token = get_token_no_padding (pfile); + if (token->type != CPP_OPEN_PAREN) + { + cpp_error (pfile, CPP_DL_ERROR, +- "missing '(' after \"__has_builtin\""); ++ "missing '(' after \"__has_%s\"", builtin); + return 0; + } + +@@ -486,7 +487,7 @@ c_common_has_builtin (cpp_reader *pfile) + else + { + cpp_error (pfile, CPP_DL_ERROR, +- "macro \"__has_builtin\" requires an identifier"); ++ "macro \"__has_%s\" requires an identifier", builtin); + if (token->type == CPP_CLOSE_PAREN) + return 0; + } +@@ -505,9 +506,38 @@ c_common_has_builtin (cpp_reader *pfile) + break; + } + ++ return name; ++} ++ ++/* Callback for has_builtin. */ ++ ++int ++c_common_has_builtin (cpp_reader *pfile) ++{ ++ const char *name = c_common_lex_availability_macro (pfile, "builtin"); ++ if (!name) ++ return 0; ++ + return names_builtin_p (name); + } + ++/* Callback for has_feature. STRICT_P is true for has_feature and false ++ for has_extension. */ ++ ++int ++c_common_has_feature (cpp_reader *pfile, bool strict_p) ++{ ++ const char *builtin = strict_p ? "feature" : "extension"; ++ const char *name = c_common_lex_availability_macro (pfile, builtin); ++ if (!name) ++ return 0; ++ ++ /* If -pedantic-errors is given, __has_extension is equivalent to ++ __has_feature. */ ++ strict_p |= flag_pedantic_errors; ++ return has_feature_p (name, strict_p); ++} ++ + + /* Read a token and return its type. Fill *VALUE with its value, if + applicable. Fill *CPP_FLAGS with the token's flags, if it is +@@ -539,6 +569,21 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, + + case CPP_NUMBER: + { ++ /* If the user wants number-like entities to be returned as a raw ++ string, then don't try to classify them, which emits unwanted ++ diagnostics. */ ++ if (lex_flags & C_LEX_NUMBER_AS_STRING) ++ { ++ /* build_string adds a trailing NUL at [len]. */ ++ tree num_string = build_string (tok->val.str.len + 1, ++ (const char *) tok->val.str.text); ++ TREE_TYPE (num_string) = char_array_type_node; ++ *value = num_string; ++ /* We will effectively note this as CPP_N_INVALID, because we ++ made no checks here. */ ++ break; ++ } ++ + const char *suffix = NULL; + unsigned int flags = cpp_classify_number (parse_in, tok, &suffix, *loc); + diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc -index c68a2a27469..a600d40c87e 100644 +index c68a2a2..a600d40 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1070,7 +1070,7 @@ c_common_post_options (const char **pfilename) @@ -906,8 +1431,58 @@ index c68a2a27469..a600d40c87e 100644 { /* Lazy TLS initialization for a variable in another TU requires alias and weak reference support. */ +diff --git a/gcc/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc +index 4aa2bef..a1488c6 100644 +--- a/gcc/c-family/c-ppoutput.cc ++++ b/gcc/c-family/c-ppoutput.cc +@@ -162,6 +162,7 @@ init_pp_output (FILE *out_stream) + + cb->has_attribute = c_common_has_attribute; + cb->has_builtin = c_common_has_builtin; ++ cb->has_feature = c_common_has_feature; + cb->get_source_date_epoch = cb_get_source_date_epoch; + cb->remap_filename = remap_macro_filename; + +diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h +index 9cc95ab..3e86a16 100644 +--- a/gcc/c-family/c-pragma.h ++++ b/gcc/c-family/c-pragma.h +@@ -272,6 +272,9 @@ extern enum cpp_ttype pragma_lex (tree *, location_t *loc = NULL); + #define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings + nor translate them into execution + character set. */ ++#define C_LEX_NUMBER_AS_STRING 4 /* Do not classify a number, but ++ instead return it as a raw ++ string. */ + + /* This is not actually available to pragma parsers. It's merely a + convenient location to declare this function for c-lex, after +diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt +index a750389..c7e6620 100644 +--- a/gcc/c-family/c.opt ++++ b/gcc/c-family/c.opt +@@ -1484,6 +1484,10 @@ Wsubobject-linkage + C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1) + Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage. + ++Welaborated-enum-base ++C++ ObjC++ Var(warn_elaborated_enum_base) Warning Init(1) ++Warn if an additional enum-base is used in an elaborated-type-specifier. ++ + Wduplicate-decl-specifier + C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall) + Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier. +@@ -1967,7 +1971,7 @@ Implement resolution of DR 150 for matching of template template arguments. + + fnext-runtime + ObjC ObjC++ LTO RejectNegative Var(flag_next_runtime) +-Generate code for NeXT (Apple Mac OS X) runtime environment. ++Generate code for NeXT (Apple macOS) runtime environment. + + fnil-receivers + ObjC ObjC++ Var(flag_nil_receivers) Init(1) diff --git a/gcc/calls.cc b/gcc/calls.cc -index 4d7f6c3d291..cc8594a04e8 100644 +index 53b0f58..b58990f 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -1367,7 +1367,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, @@ -920,7 +1495,25 @@ index 4d7f6c3d291..cc8594a04e8 100644 if (pass_by_reference (args_so_far_pnt, arg)) { const bool callee_copies -@@ -1540,6 +1541,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, +@@ -1487,10 +1488,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, + + unsignedp = TYPE_UNSIGNED (type); + arg.type = type; +- arg.mode +- = promote_function_mode (type, TYPE_MODE (type), &unsignedp, +- fndecl ? TREE_TYPE (fndecl) : fntype, 0); +- ++ arg.mode = TYPE_MODE (type); ++// arg.mode ++// = promote_function_mode (type, TYPE_MODE (type), &unsignedp, ++// fndecl ? TREE_TYPE (fndecl) : fntype, 0); ++ arg.mode = promote_function_mode (args_so_far, arg, ++ fndecl ? TREE_TYPE (fndecl) : fntype, ++ &unsignedp, 0); + args[i].unsignedp = unsignedp; + args[i].mode = arg.mode; + +@@ -1540,6 +1544,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, #endif reg_parm_stack_space, args[i].pass_on_stack ? 0 : args[i].partial, @@ -928,7 +1521,15 @@ index 4d7f6c3d291..cc8594a04e8 100644 fndecl, args_size, &args[i].locate); #ifdef BLOCK_REG_PADDING else -@@ -4260,6 +4262,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, +@@ -4076,6 +4081,7 @@ split_complex_types (tree types) + return types; + } + ++extern void debug_tree (tree); + /* Output a library call to function ORGFUN (a SYMBOL_REF rtx) + for a value of mode OUTMODE, + with NARGS different arguments, passed as ARGS. +@@ -4261,6 +4267,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, argvec[count].reg != 0, #endif reg_parm_stack_space, 0, @@ -936,7 +1537,26 @@ index 4d7f6c3d291..cc8594a04e8 100644 NULL_TREE, &args_size, &argvec[count].locate); if (argvec[count].reg == 0 || argvec[count].partial != 0 -@@ -4351,6 +4354,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, +@@ -4331,8 +4338,16 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, + val = force_operand (XEXP (slot, 0), NULL_RTX); + } + +- arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p, +- NULL_TREE, 0); ++// arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p, ++// NULL_TREE, 0); ++ tree t = arg.type; ++if (t) ++ debug_tree (t); ++gcc_assert (!t); ++ arg.type = NULL_TREE; ++ arg.mode = promote_function_mode (args_so_far, arg, NULL_TREE, ++ &unsigned_p, 0); ++ arg.type = t; + argvec[count].mode = arg.mode; + argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val, + unsigned_p); +@@ -4352,6 +4367,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, argvec[count].reg != 0, #endif reg_parm_stack_space, argvec[count].partial, @@ -945,7 +1565,7 @@ index 4d7f6c3d291..cc8594a04e8 100644 args_size.constant += argvec[count].locate.size.constant; gcc_assert (!argvec[count].locate.size.var); diff --git a/gcc/calls.h b/gcc/calls.h -index c7f8c5e4b39..42a1774fe84 100644 +index c7f8c5e..42a1774 100644 --- a/gcc/calls.h +++ b/gcc/calls.h @@ -35,24 +35,43 @@ class function_arg_info @@ -1006,22 +1626,162 @@ index c7f8c5e4b39..42a1774fe84 100644 /* True if we have decided to pass the argument by reference, in which case the function_arg_info describes a pointer to the original argument. */ unsigned int pass_by_reference : 1; -diff --git a/gcc/common.opt b/gcc/common.opt -index 862c474d3c8..1277203d550 100644 ---- a/gcc/common.opt -+++ b/gcc/common.opt -@@ -2212,6 +2212,10 @@ foffload-abi= - Common Joined RejectNegative Enum(offload_abi) - -foffload-abi=[lp64|ilp32] Set the ABI to use in an offload compiler. +diff --git a/gcc/collect2.cc b/gcc/collect2.cc +index 63b9a0c..1d7d9a4 100644 +--- a/gcc/collect2.cc ++++ b/gcc/collect2.cc +@@ -73,7 +73,7 @@ along with GCC; see the file COPYING3. If not see + In a cross-compiler, this means you need a cross nm, + but that is not quite as unpleasant as special headers. */ + +-#if !defined (OBJECT_FORMAT_COFF) ++#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_MACHO) + #define OBJECT_FORMAT_NONE + #endif + +@@ -107,7 +107,7 @@ along with GCC; see the file COPYING3. If not see + + #endif /* OBJECT_FORMAT_COFF */ + +-#ifdef OBJECT_FORMAT_NONE ++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO) -+foff-stack-trampolines -+Common RejectNegative Var(flag_off_stack_trampolines) Init(OFF_STACK_TRAMPOLINES_INIT) -+Generate trampolines in executable memory rather than executable stack. + /* Default flags to pass to nm. */ + #ifndef NM_FLAGS +@@ -525,7 +525,7 @@ static const char *const target_machine = TARGET_MACHINE; + + Return 0 if not found, otherwise return its name, allocated with malloc. */ + +-#ifdef OBJECT_FORMAT_NONE ++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO) + + /* Add an entry for the object file NAME to object file list LIST. + New entries are added at the end of the list. The original pointer +@@ -764,6 +764,12 @@ do_link (char **ld_argv, const char *atsuffix) + } + } + ++#if defined (OBJECT_FORMAT_MACHO) ++# define LLD_NAME "ld64.lld" ++#else ++# define LLD_NAME "ld.lld" ++#endif + - Enum - Name(offload_abi) Type(enum offload_abi) UnknownError(unknown offload ABI %qs) + /* Main program. */ + + int +@@ -777,16 +783,19 @@ main (int argc, char **argv) + USE_BFD_LD, + USE_LLD_LD, + USE_MOLD_LD, ++ USE_CLASSIC_LD, + USE_LD_MAX + } selected_linker = USE_DEFAULT_LD; ++ + static const char *const ld_suffixes[USE_LD_MAX] = + { + "ld", + PLUGIN_LD_SUFFIX, + "ld.gold", + "ld.bfd", +- "ld.lld", +- "ld.mold" ++ LLD_NAME, ++ "ld.mold", ++ "ld-classic" + }; + static const char *const real_ld_suffix = "real-ld"; + static const char *const collect_ld_suffix = "collect-ld"; +@@ -953,14 +962,22 @@ main (int argc, char **argv) + if (selected_linker == USE_DEFAULT_LD) + selected_linker = USE_PLUGIN_LD; + } ++#if !defined (OBJECT_FORMAT_MACHO) + else if (strcmp (argv[i], "-fuse-ld=bfd") == 0) + selected_linker = USE_BFD_LD; + else if (strcmp (argv[i], "-fuse-ld=gold") == 0) + selected_linker = USE_GOLD_LD; ++#endif + else if (strcmp (argv[i], "-fuse-ld=lld") == 0) + selected_linker = USE_LLD_LD; + else if (strcmp (argv[i], "-fuse-ld=mold") == 0) + selected_linker = USE_MOLD_LD; ++#if defined (OBJECT_FORMAT_MACHO) ++ else if (strcmp (argv[i], "-fuse-ld=classic") == 0) ++ selected_linker = USE_CLASSIC_LD; ++#endif ++ else if (strcmp (argv[i], "-fuse-ld=") == 0) ++ selected_linker = USE_DEFAULT_LD; + else if (startswith (argv[i], "-o")) + { + /* Parse the output filename if it's given so that we can make +@@ -1052,7 +1069,8 @@ main (int argc, char **argv) + ld_file_name = 0; + #ifdef DEFAULT_LINKER + if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD || +- selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD) ++ selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD || ++ selected_linker == USE_CLASSIC_LD) + { + char *linker_name; + # ifdef HOST_EXECUTABLE_SUFFIX +@@ -2266,7 +2284,7 @@ write_aix_file (FILE *stream, struct id *list) + } + #endif + +-#ifdef OBJECT_FORMAT_NONE ++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO) + + /* Check to make sure the file is an LTO object file. */ + +diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc +index 20bc4e1..5058d2f 100644 +--- a/gcc/common/config/aarch64/aarch64-common.cc ++++ b/gcc/common/config/aarch64/aarch64-common.cc +@@ -301,8 +301,12 @@ aarch64_get_extension_string_for_isa_flags + + However, assemblers with Armv8-R AArch64 support should not have this + issue, so we don't need this fix when targeting Armv8-R. */ +- auto explicit_flags = (!(current_flags & AARCH64_FL_V8R) +- ? AARCH64_FL_CRC : 0); ++ aarch64_feature_flags explicit_flags = ++#ifndef DISABLE_AARCH64_AS_CRC_BUGFIX ++ (!(current_flags & AARCH64_ISA_V8R) ? AARCH64_FL_CRC : 0); ++#else ++ 0; ++#endif + + /* Add the features in isa_flags & ~current_flags using the smallest + possible number of extensions. We can do this by iterating over the +@@ -331,7 +335,10 @@ aarch64_get_extension_string_for_isa_flags + if (added & opt.flag_canonical) + { + outstr += "+"; +- outstr += opt.name; ++ if (startswith (opt.name, "rdm")) ++ outstr += "rdm"; ++ else ++ outstr += opt.name; + } -@@ -2794,6 +2798,10 @@ fstack-usage + /* Remove the features in current_flags & ~isa_flags. If the feature does +@@ -344,7 +351,10 @@ aarch64_get_extension_string_for_isa_flags + { + current_flags &= ~opt.flags_off; + outstr += "+no"; +- outstr += opt.name; ++ if (startswith (opt.name, "rdm")) ++ outstr += "rdm"; ++ else ++ outstr += opt.name; + } + + return outstr; +diff --git a/gcc/common.opt b/gcc/common.opt +index b055c7b..cf32af4 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -2794,6 +2794,10 @@ fstack-usage Common RejectNegative Var(flag_stack_usage) Output stack usage information on a per-function basis. @@ -1032,98 +1792,58 @@ index 862c474d3c8..1277203d550 100644 fstrength-reduce Common Ignore Does nothing. Preserved for backward compatibility. -@@ -2862,7 +2870,7 @@ Common Var(flag_tracer) Optimization +@@ -2862,10 +2866,25 @@ Common Var(flag_tracer) Optimization Perform superblock formation via tail duplication. ftrampolines -Common Var(flag_trampolines) Init(0) -+Common Var(flag_trampolines) Init(OFF_STACK_TRAMPOLINES_INIT) ++Common Var(flag_trampolines) Init(HEAP_TRAMPOLINES_INIT) For targets that normally need trampolines for nested functions, always generate them instead of using descriptors. -diff --git a/gcc/config.gcc b/gcc/config.gcc -index 648b3dc2110..bac8b7c55b0 100644 ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -1125,6 +1125,26 @@ case ${target} in - ;; - esac - -+# Defaults that need fixing. -+# Figure out if we need to enable -foff-stack-trampolines by default -+case ${target} in -+aarch64*-*-darwin2*) -+ # This only applies to arm64 Darwin variadic funtions. -+ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1" -+ # This is required; executable stack is forbidden. -+ tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=1" -+ ;; -+*-*-darwin2*) -+ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" -+ # Currently, we do this for macOS 11 and above. -+ tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=1" -+ ;; -+*) -+ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" -+ tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=0" -+ ;; -+esac ++ftrampoline-impl= ++Common Joined RejectNegative Enum(trampoline_impl) Var(flag_trampoline_impl) Init(HEAP_TRAMPOLINES_INIT ? TRAMPOLINE_IMPL_HEAP : TRAMPOLINE_IMPL_STACK) ++Whether trampolines are generated in executable memory rather than ++executable stack. + - case ${target} in - aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) - tm_file="${tm_file} elfos.h newlib-stdint.h" -@@ -1163,6 +1183,11 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) - done - TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'` - ;; -+aarch64-*-darwin* ) -+ tm_file="${tm_file} aarch64/aarch64-errata.h" -+ tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-darwin" -+ tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1" -+ ;; - aarch64*-*-freebsd*) - tm_file="${tm_file} elfos.h ${fbsd_tm_file}" - tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-freebsd.h" -diff --git a/gcc/config.in b/gcc/config.in -index 4cad077bfbe..428ca236a52 100644 ---- a/gcc/config.in -+++ b/gcc/config.in -@@ -49,6 +49,19 @@ - #endif - - -+/* Specify a runpath directory, additional to those provided by the compiler -+ */ -+#ifndef USED_FOR_TARGET -+#undef DARWIN_ADD_RPATH -+#endif ++Enum ++Name(trampoline_impl) Type(enum trampoline_impl) UnknownError(unknown trampoline implementation %qs) + ++EnumValue ++Enum(trampoline_impl) String(stack) Value(TRAMPOLINE_IMPL_STACK) + -+/* Should add an extra runpath directory */ -+#ifndef USED_FOR_TARGET -+#undef DARWIN_DO_EXTRA_RPATH -+#endif ++EnumValue ++Enum(trampoline_impl) String(heap) Value(TRAMPOLINE_IMPL_HEAP) + + - /* Define to enable the use of a default assembler. */ - #ifndef USED_FOR_TARGET - #undef DEFAULT_ASSEMBLER + ; Zero means that floating-point math operations cannot generate a + ; (user-visible) trap. This is the case, for example, in nonstop + ; IEEE 754 arithmetic. +@@ -3123,6 +3142,10 @@ fuse-ld=mold + Common Driver Negative(fuse-ld=mold) + Use the Modern linker (MOLD) linker instead of the default linker. + ++fuse-ld=classic ++Common Driver Negative(fuse-ld=classic) ++Use the ld-classic linker instead of the default linker. ++ + fuse-linker-plugin + Common Undocumented Var(flag_use_linker_plugin) + diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc -index dd9f1150165..d73da323037 100644 +index 8ad8284..567fb10 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc -@@ -785,6 +785,10 @@ enum aarch64_builtins +@@ -785,6 +785,8 @@ enum aarch64_builtins AARCH64_RBIT, AARCH64_RBITL, AARCH64_RBITLL, + /* OS-specific */ + AARCH64_BUILTIN_CFSTRING, -+ AARCH64_BUILTIN_HUGE_VALQ, -+ AARCH64_BUILTIN_INFQ, AARCH64_BUILTIN_MAX }; -@@ -920,6 +924,9 @@ tree aarch64_fp16_ptr_type_node = NULL_TREE; +@@ -920,6 +922,9 @@ tree aarch64_fp16_ptr_type_node = NULL_TREE; /* Back-end node type for brain float (bfloat) types. */ tree aarch64_bf16_ptr_type_node = NULL_TREE; @@ -1133,7 +1853,7 @@ index dd9f1150165..d73da323037 100644 /* Wrapper around add_builtin_function. NAME is the name of the built-in function, TYPE is the function type, CODE is the function subcode (relative to AARCH64_BUILTIN_GENERAL), and ATTRS is the function -@@ -1695,6 +1702,40 @@ aarch64_init_bf16_types (void) +@@ -1695,6 +1700,29 @@ aarch64_init_bf16_types (void) aarch64_bf16_ptr_type_node = build_pointer_type (bfloat16_type_node); } @@ -1142,39 +1862,28 @@ index dd9f1150165..d73da323037 100644 +static void +aarch64_init_float128_types (void) +{ -+ tree ftype, fndecl; -+ -+ /* Populate the float128 node if it is not already done so that the FEs -+ know it is available. */ -+ if (float128_type_node == NULL_TREE) ++ /* The __float128 type. The node has already been created as ++ _Float128, so for C we only need to register the __float128 name for ++ it. For C++, we create a distinct type which will mangle differently ++ (g) vs. _Float128 (DF128_) and behave backwards compatibly. */ ++ if (float128t_type_node == NULL_TREE) + { -+ float128_type_node = make_node (REAL_TYPE); -+ TYPE_PRECISION (float128_type_node) = 128; -+ SET_TYPE_MODE (float128_type_node, TFmode); -+ layout_type (float128_type_node); ++ float128t_type_node = make_node (REAL_TYPE); ++ TYPE_PRECISION (float128t_type_node) ++ = TYPE_PRECISION (float128_type_node); ++ SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node)); ++ layout_type (float128t_type_node); + } ++ lang_hooks.types.register_builtin_type (float128t_type_node, "__float128"); + -+ lang_hooks.types.register_builtin_type (float128_type_node, "__float128"); -+ aarch64_float128_ptr_type_node = build_pointer_type (float128_type_node); -+ -+ ftype = build_function_type_list (float128_type_node, NULL_TREE); -+ -+ fndecl = aarch64_general_add_builtin ("__builtin_huge_valq", ftype, -+ AARCH64_BUILTIN_HUGE_VALQ); -+ TREE_READONLY (fndecl) = 1; -+ aarch64_builtin_decls[AARCH64_BUILTIN_HUGE_VALQ] = fndecl; -+ -+ fndecl = aarch64_general_add_builtin ("__builtin_infq", ftype, -+ AARCH64_BUILTIN_INFQ); -+ TREE_READONLY (fndecl) = 1; -+ aarch64_builtin_decls[AARCH64_BUILTIN_INFQ] = fndecl; ++ aarch64_float128_ptr_type_node = build_pointer_type (float128t_type_node); +} + + /* Pointer authentication builtins that will become NOP on legacy platform. Currently, these builtins are for internal use only (libgcc EH unwinder). */ -@@ -1983,8 +2024,9 @@ aarch64_general_init_builtins (void) +@@ -1983,8 +2011,9 @@ aarch64_general_init_builtins (void) aarch64_init_fpsr_fpcr_builtins (); aarch64_init_fp16_types (); @@ -1185,7 +1894,7 @@ index dd9f1150165..d73da323037 100644 { aarch64_simd_switcher simd; -@@ -2021,6 +2063,14 @@ aarch64_general_init_builtins (void) +@@ -2021,6 +2050,14 @@ aarch64_general_init_builtins (void) handle_arm_acle_h (); } @@ -1200,37 +1909,61 @@ index dd9f1150165..d73da323037 100644 /* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group. */ tree aarch64_general_builtin_decl (unsigned code, bool) -@@ -2912,6 +2962,15 @@ aarch64_general_fold_builtin (unsigned int fcode, tree type, - if (aarch64_fold_builtin_lane_check (args[0], args[1], args[2])) - return void_node; - break; -+ case AARCH64_BUILTIN_HUGE_VALQ: -+ case AARCH64_BUILTIN_INFQ: -+ { -+ gcc_assert (n_args == 0); -+ REAL_VALUE_TYPE inf; -+ real_inf (&inf); -+ return build_real (type, inf); -+ } -+ break; - default: - break; - } diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc -index 578ec6f45b0..1601887c86f 100644 +index 578ec6f..56c83ac 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc -@@ -359,4 +359,8 @@ aarch64_register_pragmas (void) - targetm.check_builtin_call = aarch64_check_builtin_call; - - c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64); +@@ -224,6 +224,16 @@ aarch64_cpu_cpp_builtins (cpp_reader *pfile) + { + aarch64_define_unconditional_macros (pfile); + aarch64_update_cpp_builtins (pfile); ++ ++ if (TARGET_MACHO) ++ { ++ builtin_define ("__builtin_copysignq=__builtin_copysignf128"); ++ builtin_define ("__builtin_fabsq=__builtin_fabsf128"); ++ builtin_define ("__builtin_huge_valq=__builtin_huge_valf128"); ++ builtin_define ("__builtin_infq=__builtin_inff128"); ++ builtin_define ("__builtin_nanq=__builtin_nanf128"); ++ builtin_define ("__builtin_nansq=__builtin_nansf128"); ++ } + } + + /* Hook to validate the current #pragma GCC target and set the state, and +@@ -359,4 +369,8 @@ aarch64_register_pragmas (void) + targetm.check_builtin_call = aarch64_check_builtin_call; + + c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64); + +#ifdef REGISTER_SUBTARGET_PRAGMAS + REGISTER_SUBTARGET_PRAGMAS (); +#endif } +diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def +index fdda069..2dc4ae6 100644 +--- a/gcc/config/aarch64/aarch64-cores.def ++++ b/gcc/config/aarch64/aarch64-cores.def +@@ -165,6 +165,18 @@ AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, V8_2A, (F + /* Armv8-R Architecture Processors. */ + AARCH64_CORE("cortex-r82", cortexr82, cortexa53, V8R, (), cortexa53, 0x41, 0xd15, -1) + ++/* Apple (A12 and M) cores. ++ Apple implementer ID from xnu, ++ guesses for part #, guesses for scheduler ident, generic_armv8_a for costs. ++ A12 seems mostly 8.3, ++ M1 seems to be 8.4 + extras (see comments in option-extensions about f16fml), ++ M2 mostly 8.5 but with missing mandatory features. ++ M3 is pretty much the same as M2. */ ++AARCH64_CORE("apple-a12", applea12, cortexa53, V8_3A, (), cortexa53, 0x61, 0x12, -1) ++AARCH64_CORE("apple-m1", applem1, cortexa57, V8_4A, (F16, SB, SSBS), cortexa73, 0x61, 0x23, -1) ++AARCH64_CORE("apple-m2", applem2, cortexa57, V8_4A, (I8MM, BF16, F16, SB, SSBS), cortexa73, 0x61, 0x23, -1) ++AARCH64_CORE("apple-m3", applem3, cortexa57, V8_4A, (I8MM, BF16, F16, SB, SSBS), cortexa73, 0x61, 0x23, -1) ++ + /* Armv9.0-A Architecture Processors. */ + + /* Arm ('A') cores. */ diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h -index e727e207367..e6a4be70752 100644 +index 32716f6..a107f9e 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -109,6 +109,14 @@ enum aarch64_symbol_type @@ -1256,15 +1989,19 @@ index e727e207367..e6a4be70752 100644 bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode); unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in); unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in); -@@ -898,6 +907,7 @@ void aarch64_expand_vector_init (rtx, rtx); - void aarch64_sve_expand_vector_init (rtx, rtx); - void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, - const_tree, unsigned, bool = false); -+void aarch64_init_cumulative_incoming_args (CUMULATIVE_ARGS *, const_tree, rtx); - void aarch64_init_expanders (void); - void aarch64_emit_call_insn (rtx); - void aarch64_register_pragmas (void); -@@ -970,6 +980,7 @@ void aarch64_override_options_internal (struct gcc_options *); +@@ -775,7 +784,11 @@ bool aarch64_is_extend_from_extract (scalar_int_mode, rtx, rtx); + bool aarch64_is_long_call_p (rtx); + bool aarch64_is_noplt_call_p (rtx); + bool aarch64_label_mentioned_p (rtx); ++#if TARGET_MACHO ++void aarch64_darwin_declare_function_name (FILE *, const char*, tree ); ++#else + void aarch64_declare_function_name (FILE *, const char*, tree); ++#endif + void aarch64_asm_output_alias (FILE *, const tree, const tree); + void aarch64_asm_output_external (FILE *, tree, const char*); + bool aarch64_legitimate_pic_operand_p (rtx); +@@ -971,6 +984,7 @@ void aarch64_override_options_internal (struct gcc_options *); const char *aarch64_general_mangle_builtin_type (const_tree); void aarch64_general_init_builtins (void); @@ -1272,8 +2009,19 @@ index e727e207367..e6a4be70752 100644 tree aarch64_general_fold_builtin (unsigned int, tree, unsigned int, tree *); gimple *aarch64_general_gimple_fold_builtin (unsigned int, gcall *, gimple_stmt_iterator *); +diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md +index 9d46d38..3c3aa72 100644 +--- a/gcc/config/aarch64/aarch64-tune.md ++++ b/gcc/config/aarch64/aarch64-tune.md +@@ -1,5 +1,5 @@ + ;; -*- buffer-read-only: t -*- + ;; Generated automatically by gentune.sh from aarch64-cores.def + (define_attr "tune" +- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,cobalt100,neoversev2,demeter" ++ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,applea12,applem1,applem2,applem3,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,cobalt100,neoversev2,demeter" + (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc -index f5db5379543..25443d35141 100644 +index b8a4ab1..d2f5034 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -295,8 +295,10 @@ static bool aarch64_vfp_is_call_or_return_candidate (machine_mode, @@ -1287,16 +2035,16 @@ index f5db5379543..25443d35141 100644 static void aarch64_override_options_after_change (void); static bool aarch64_vector_mode_supported_p (machine_mode); static int aarch64_address_cost (rtx, machine_mode, addr_space_t, bool); -@@ -2803,6 +2805,9 @@ static const struct attribute_spec aarch64_attribute_table[] = - { "Advanced SIMD type", 1, 1, false, true, false, true, NULL, NULL }, - { "SVE type", 3, 3, false, true, false, true, NULL, NULL }, - { "SVE sizeless type", 0, 0, false, true, false, true, NULL, NULL }, +@@ -2795,6 +2797,9 @@ static const struct attribute_spec aarch64_attribute_table[] = + { + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, + affects_type_identity, handler, exclude } */ +#ifdef SUBTARGET_ATTRIBUTE_TABLE + SUBTARGET_ATTRIBUTE_TABLE, +#endif - { NULL, 0, 0, false, false, false, false, NULL, NULL } - }; - + { "aarch64_vector_pcs", 0, 0, false, true, true, true, + handle_aarch64_vector_pcs_attribute, NULL }, + { "arm_sve_vector_bits", 1, 1, false, true, false, true, @@ -3949,7 +3954,7 @@ aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode) if (known_le (GET_MODE_SIZE (mode), 8)) return true; @@ -1388,6 +2136,15 @@ index f5db5379543..25443d35141 100644 /* Given MODE and TYPE of a function argument, return the alignment in bits. The idea is to suppress any stronger alignment requested by +@@ -7481,7 +7509,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type, + if (integer_zerop (TYPE_SIZE (type))) + return 0; + +- gcc_assert (TYPE_MODE (type) == mode); ++ gcc_assert (TARGET_MACHO || TYPE_MODE (type) == mode); + + if (!AGGREGATE_TYPE_P (type)) + { @@ -7641,6 +7669,14 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) Both behaviors were wrong, but in different cases. */ @@ -1492,18 +2249,12 @@ index f5db5379543..25443d35141 100644 return; } -@@ -7853,7 +7922,6 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) +@@ -7853,7 +7922,81 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) /* The argument is passed on stack; record the needed number of words for this argument and align the total size if necessary. */ on_stack: - pcum->aapcs_stack_words = size / UNITS_PER_WORD; - - if (warn_pcs_change - && abi_break_packed -@@ -7862,6 +7930,83 @@ on_stack: - inform (input_location, "parameter passing for argument of type " - "%qT changed in GCC 13.1", type); - ++ + if (TARGET_MACHO) + { + /* Darwin does not round up the allocation for smaller entities to 8 @@ -1522,7 +2273,7 @@ index f5db5379543..25443d35141 100644 + change nor the warning should fire here (i.e. we do not need to check + if 16byte entities alter the stack size). */ + -+gcc_checking_assert (arg.named == pcum->named_p); ++ gcc_checking_assert (arg.named == pcum->named_p); + pcum->darwinpcs_arg_padding = BITS_PER_UNIT; + if (!pcum->named_p + || TREE_CODE (type) == COMPLEX_TYPE @@ -1578,7 +2329,13 @@ index f5db5379543..25443d35141 100644 + } + return; + } -+ + + if (warn_pcs_change + && abi_break_packed +@@ -7862,6 +8005,8 @@ on_stack: + inform (input_location, "parameter passing for argument of type " + "%qT changed in GCC 13.1", type); + + /* size was already rounded up to PARM_BOUNDARY. */ + pcum->aapcs_stack_words = size / UNITS_PER_WORD; if (alignment == 16 * BITS_PER_UNIT) @@ -1769,7 +2526,7 @@ index f5db5379543..25443d35141 100644 } /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ -@@ -11030,6 +11306,7 @@ aarch64_classify_address (struct aarch64_address_info *info, +@@ -11091,6 +11367,7 @@ aarch64_classify_address (struct aarch64_address_info *info, /* load literal: pc-relative constant pool entry. Only supported for SI mode or larger. */ info->type = ADDRESS_SYMBOLIC; @@ -1777,7 +2534,7 @@ index f5db5379543..25443d35141 100644 if (!load_store_pair_p && GET_MODE_SIZE (mode).is_constant (&const_size) -@@ -11037,6 +11314,7 @@ aarch64_classify_address (struct aarch64_address_info *info, +@@ -11098,6 +11375,7 @@ aarch64_classify_address (struct aarch64_address_info *info, { poly_int64 offset; rtx sym = strip_offset_and_salt (x, &offset); @@ -1785,7 +2542,7 @@ index f5db5379543..25443d35141 100644 return ((LABEL_REF_P (sym) || (SYMBOL_REF_P (sym) && CONSTANT_POOL_ADDRESS_P (sym) -@@ -11054,10 +11332,13 @@ aarch64_classify_address (struct aarch64_address_info *info, +@@ -11115,10 +11393,13 @@ aarch64_classify_address (struct aarch64_address_info *info, poly_int64 offset; HOST_WIDE_INT const_offset; rtx sym = strip_offset_and_salt (info->offset, &offset); @@ -1800,7 +2557,7 @@ index f5db5379543..25443d35141 100644 { /* The symbol and offset must be aligned to the access size. */ unsigned int align; -@@ -11107,6 +11388,55 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) +@@ -11168,6 +11449,55 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) if (!res) return false; @@ -1856,7 +2613,7 @@ index f5db5379543..25443d35141 100644 /* ... except writeback forms. */ return addr.type != ADDRESS_REG_WB; } -@@ -11820,6 +12150,144 @@ sizetochar (int size) +@@ -11881,6 +12211,144 @@ sizetochar (int size) } } @@ -2001,11 +2758,11 @@ index f5db5379543..25443d35141 100644 /* Print operand X to file F in a target specific manner according to CODE. The acceptable formatting commands given by CODE are: 'c': An integer or symbol address without a preceding # -@@ -11888,6 +12356,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) +@@ -11949,6 +12417,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) } break; -+ case 'K': ++ case 'J': + output_macho_postfix_expr (f, x, "PAGEOFF"); + break; + case 'O': @@ -2014,7 +2771,7 @@ index f5db5379543..25443d35141 100644 case 'e': { x = unwrap_const_vec_duplicate (x); -@@ -12211,7 +12685,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) +@@ -12272,7 +12746,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) case 'A': if (GET_CODE (x) == HIGH) x = XEXP (x, 0); @@ -2023,26 +2780,23 @@ index f5db5379543..25443d35141 100644 switch (aarch64_classify_symbolic_expression (x)) { case SYMBOL_SMALL_GOT_4G: -@@ -12242,9 +12716,29 @@ aarch64_print_operand (FILE *f, rtx x, int code) +@@ -12303,9 +12777,26 @@ aarch64_print_operand (FILE *f, rtx x, int code) break; } output_addr_const (asm_out_file, x); +#endif +#if TARGET_MACHO -+ // FIXME update classify symbolic expression to handle macho. + switch (aarch64_classify_symbolic_expression (x)) + { + case SYMBOL_MO_SMALL_PCR: + output_macho_postfix_expr (asm_out_file, x, "PAGE"); -+// asm_fprintf (asm_out_file, "@PAGE;mopcr"); + break; + case SYMBOL_MO_SMALL_GOT: + output_macho_postfix_expr (asm_out_file, x, "GOTPAGE"); -+// asm_fprintf (asm_out_file, "@GOTPAGE;mosg"); + break; + default: -+ output_macho_postfix_expr (asm_out_file, x, "BLEAH"); -+// asm_fprintf (asm_out_file, "@BLEAH"); ++ /* large code model unimplemented. */ ++ gcc_unreachable (); + break; + } +#endif @@ -2053,7 +2807,7 @@ index f5db5379543..25443d35141 100644 switch (aarch64_classify_symbolic_expression (x)) { case SYMBOL_SMALL_GOT_4G: -@@ -12282,10 +12776,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) +@@ -12343,10 +12834,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) default: break; } @@ -2066,7 +2820,7 @@ index f5db5379543..25443d35141 100644 switch (aarch64_classify_symbolic_expression (x)) { case SYMBOL_TLSLE24: -@@ -12294,6 +12790,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) +@@ -12355,6 +12848,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) default: break; } @@ -2074,14 +2828,13 @@ index f5db5379543..25443d35141 100644 output_addr_const (asm_out_file, x); break; -@@ -12443,8 +12940,14 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, +@@ -12504,8 +12998,13 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, break; case ADDRESS_LO_SUM: +#if TARGET_MACHO + asm_fprintf (f, "[%s, #", reg_names [REGNO (addr.base)]); + output_macho_postfix_expr (f, addr.offset, "PAGEOFF"); -+// output_addr_const (f, addr.offset); +#else asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]); output_addr_const (f, addr.offset); @@ -2089,7 +2842,34 @@ index f5db5379543..25443d35141 100644 asm_fprintf (f, "]"); return true; -@@ -12942,6 +13445,8 @@ aarch64_asm_output_labelref (FILE* f, const char *name) +@@ -12786,6 +13285,26 @@ aarch64_secondary_memory_needed (machine_mode mode, reg_class_t class1, + return false; + } + ++#if TARGET_MACHO ++/* Implement TARGET_FRAME_POINTER_REQUIRED. */ ++ ++static bool ++aarch64_darwin_frame_pointer_required () ++{ ++ if (crtl->calls_eh_return) ++ return true; ++ ++ /* Not used in leaf functions (unless forced). */ ++ if (flag_omit_leaf_frame_pointer && leaf_function_p ()) ++ return false; ++ ++ /* NOTE: We are allowing the user to force omission of the frame ++ pointer, (despite that it is not ABI-compliant). */ ++ ++ return flag_omit_frame_pointer != 1; ++} ++#endif ++ + static bool + aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) + { +@@ -13003,6 +13522,8 @@ aarch64_asm_output_labelref (FILE* f, const char *name) asm_fprintf (f, "%U%s", name); } @@ -2098,7 +2878,7 @@ index f5db5379543..25443d35141 100644 static void aarch64_elf_asm_constructor (rtx symbol, int priority) { -@@ -12981,6 +13486,7 @@ aarch64_elf_asm_destructor (rtx symbol, int priority) +@@ -13042,6 +13563,7 @@ aarch64_elf_asm_destructor (rtx symbol, int priority) assemble_aligned_integer (POINTER_BYTES, symbol); } } @@ -2106,11 +2886,11 @@ index f5db5379543..25443d35141 100644 const char* aarch64_output_casesi (rtx *operands) -@@ -13084,7 +13590,11 @@ aarch64_select_rtx_section (machine_mode mode, +@@ -13145,7 +13667,11 @@ aarch64_select_rtx_section (machine_mode mode, if (aarch64_can_use_per_function_literal_pools_p ()) return function_section (current_function_decl); -+#ifdef TARGET_MACHO ++#if TARGET_MACHO + return machopic_select_rtx_section (mode, x, align); +#else return default_elf_select_rtx_section (mode, x, align); @@ -2118,7 +2898,7 @@ index f5db5379543..25443d35141 100644 } /* Implement ASM_OUTPUT_POOL_EPILOGUE. */ -@@ -15308,15 +15818,17 @@ aarch64_init_builtins () +@@ -15369,15 +15895,17 @@ aarch64_init_builtins () { aarch64_general_init_builtins (); aarch64_sve::init_builtins (); @@ -2139,7 +2919,7 @@ index f5db5379543..25443d35141 100644 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; tree type = TREE_TYPE (TREE_TYPE (fndecl)); -@@ -18500,10 +19012,14 @@ initialize_aarch64_code_model (struct gcc_options *opts) +@@ -18561,10 +19089,14 @@ initialize_aarch64_code_model (struct gcc_options *opts) } break; case AARCH64_CMODEL_LARGE: @@ -2147,7 +2927,7 @@ index f5db5379543..25443d35141 100644 + if (TARGET_MACHO) + /* We need to implement fPIC here (arm64_32 also accepts the large + model). */ -+ ; ++ sorry ("code model %qs not supported yet", "large"); + else if (opts->x_flag_pic) sorry ("code model %qs with %<-f%s%>", "large", opts->x_flag_pic > 1 ? "PIC" : "pic"); @@ -2156,7 +2936,7 @@ index f5db5379543..25443d35141 100644 sorry ("code model %qs not supported in ilp32 mode", "large"); break; case AARCH64_CMODEL_TINY_PIC: -@@ -19389,7 +19905,9 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) +@@ -19450,7 +19982,9 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) case AARCH64_CMODEL_SMALL_SPIC: case AARCH64_CMODEL_SMALL_PIC: case AARCH64_CMODEL_SMALL: @@ -2167,7 +2947,7 @@ index f5db5379543..25443d35141 100644 default: gcc_unreachable (); -@@ -19425,10 +19943,22 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) +@@ -19486,10 +20020,22 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) return SYMBOL_TINY_ABSOLUTE; @@ -2191,7 +2971,7 @@ index f5db5379543..25443d35141 100644 if ((flag_pic || SYMBOL_REF_WEAK (x)) && !aarch64_symbol_binds_local_p (x)) return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC -@@ -19440,7 +19970,8 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) +@@ -19501,7 +20047,8 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) || offset_within_block_p (x, offset))) return SYMBOL_FORCE_TO_MEM; @@ -2201,7 +2981,7 @@ index f5db5379543..25443d35141 100644 case AARCH64_CMODEL_LARGE: /* This is alright even in PIC code as the constant -@@ -19570,7 +20101,10 @@ static GTY(()) tree va_list_type; +@@ -19631,7 +20178,10 @@ static GTY(()) tree va_list_type; void *__vr_top; int __gr_offs; int __vr_offs; @@ -2213,7 +2993,7 @@ index f5db5379543..25443d35141 100644 static tree aarch64_build_builtin_va_list (void) -@@ -19578,6 +20112,13 @@ aarch64_build_builtin_va_list (void) +@@ -19639,6 +20189,13 @@ aarch64_build_builtin_va_list (void) tree va_list_name; tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; @@ -2227,7 +3007,7 @@ index f5db5379543..25443d35141 100644 /* Create the type. */ va_list_type = lang_hooks.types.make_type (RECORD_TYPE); /* Give it the required name. */ -@@ -19649,6 +20190,13 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) +@@ -19710,6 +20267,13 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) int vr_save_area_size = cfun->va_list_fpr_size; int vr_offset; @@ -2241,7 +3021,7 @@ index f5db5379543..25443d35141 100644 cum = &crtl->args.info; if (cfun->va_list_gpr_size) gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD, -@@ -19739,6 +20287,9 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, +@@ -19800,6 +20364,9 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, HOST_WIDE_INT size, rsize, adjust, align; tree t, u, cond1, cond2; @@ -2251,7 +3031,7 @@ index f5db5379543..25443d35141 100644 indirect_p = pass_va_arg_by_reference (type); if (indirect_p) type = build_pointer_type (type); -@@ -19929,8 +20480,18 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, +@@ -19990,8 +20557,18 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, field_ptr_t = double_ptr_type_node; break; case E_TFmode: @@ -2272,7 +3052,7 @@ index f5db5379543..25443d35141 100644 break; case E_SDmode: field_t = dfloat32_type_node; -@@ -20013,6 +20574,9 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, +@@ -20074,6 +20651,9 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, int gr_saved = cfun->va_list_gpr_size; int vr_saved = cfun->va_list_fpr_size; @@ -2282,7 +3062,7 @@ index f5db5379543..25443d35141 100644 /* The caller has advanced CUM up to, but not beyond, the last named argument. Advance a local copy of CUM past the last "real" named argument, to find out how many registers are left over. */ -@@ -20845,6 +21409,12 @@ aarch64_autovectorize_vector_modes (vector_modes *modes, bool) +@@ -20906,6 +21486,12 @@ aarch64_autovectorize_vector_modes (vector_modes *modes, bool) static const char * aarch64_mangle_type (const_tree type) { @@ -2295,18 +3075,20 @@ index f5db5379543..25443d35141 100644 /* The AArch64 ABI documents say that "__va_list" has to be mangled as if it is in the "std" namespace. */ if (lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) -@@ -20861,6 +21431,10 @@ aarch64_mangle_type (const_tree type) +@@ -20922,6 +21508,12 @@ aarch64_mangle_type (const_tree type) return "Dh"; } -+ /* __float128 */ -+ if (TYPE_MODE (type) == TFmode) ++ /* __float128 is mangled as "g" on darwin. _Float128 is not mangled here, ++ but handled in common code (as "DF128_"). */ ++ if (TARGET_MACHO && TYPE_MODE (type) == TFmode ++ && TYPE_MAIN_VARIANT (type) == float128t_type_node) + return "g"; + /* Mangle AArch64-specific internal types. TYPE_NAME is non-NULL_TREE for builtin types. */ if (TYPE_NAME (type) != NULL) -@@ -21554,7 +22128,8 @@ aarch64_mov_operand_p (rtx x, machine_mode mode) +@@ -21615,7 +22207,8 @@ aarch64_mov_operand_p (rtx x, machine_mode mode) /* GOT accesses are valid moves. */ if (SYMBOL_REF_P (x) @@ -2316,17 +3098,84 @@ index f5db5379543..25443d35141 100644 return true; if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x)) -@@ -22746,7 +23321,9 @@ aarch64_declare_function_name (FILE *stream, const char* name, +@@ -22759,12 +23352,8 @@ aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name) + static std::string aarch64_last_printed_arch_string; + static std::string aarch64_last_printed_tune_string; + +-/* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used +- by the function fndecl. */ +- +-void +-aarch64_declare_function_name (FILE *stream, const char* name, +- tree fndecl) ++static void ++aarch64_function_options_preamble (tree fndecl) + { + tree target_parts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + +@@ -22803,15 +23392,60 @@ aarch64_declare_function_name (FILE *stream, const char* name, + this_tune->name); + aarch64_last_printed_tune_string = this_tune->name; + } ++} ++ ++/* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used ++ by the function fndecl. */ + ++#if TARGET_MACHO ++void ++aarch64_darwin_declare_function_name (FILE *stream, const char* name, ++ tree fndecl) ++{ ++ gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL); ++ gcc_checking_assert (!DECL_COMMON (fndecl)); ++ ++ /* Update .arch and .tune as needed. */ ++ aarch64_function_options_preamble (fndecl); ++ ++ /* Darwin does not emit pcs variant info. */ ++ ++ rtx decl_rtx = XEXP (DECL_RTL (fndecl), 0); ++ if (GET_CODE (decl_rtx) != SYMBOL_REF) ++ name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); ++ ++ if (! DECL_WEAK (fndecl) ++ && ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl)) ++ || DECL_INITIAL (fndecl))) ++ machopic_define_symbol (DECL_RTL (fndecl)); ++ if ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl)) ++ || DECL_INITIAL (fndecl)) ++ (* targetm.encode_section_info) (fndecl, DECL_RTL (fndecl), false); ++ ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl); ++ ++ cfun->machine->label_is_assembled = true; ++} ++ ++#else ++ ++void ++aarch64_declare_function_name (FILE *stream, const char* name, ++ tree fndecl) ++{ ++ /* Update .arch and .tune as needed. */ ++ aarch64_function_options_preamble (fndecl); ++ /* Emit any necessary pcs information. */ aarch64_asm_output_variant_pcs (stream, fndecl, name); /* Don't forget the type directive for ELF. */ +#ifdef ASM_OUTPUT_TYPE_DIRECTIVE ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function"); +- ASM_OUTPUT_LABEL (stream, name); +#endif - ASM_OUTPUT_LABEL (stream, name); ++ ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl); cfun->machine->label_is_assembled = true; -@@ -22807,12 +23384,17 @@ aarch64_output_patchable_area (unsigned int patch_area_size, bool record_p) + } ++#endif + + /* Implement PRINT_PATCHABLE_FUNCTION_ENTRY. */ + +@@ -22868,12 +23502,17 @@ aarch64_output_patchable_area (unsigned int patch_area_size, bool record_p) /* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */ void @@ -2345,7 +3194,28 @@ index f5db5379543..25443d35141 100644 } /* Implement ASM_OUTPUT_EXTERNAL. Output .variant_pcs for undefined -@@ -23436,6 +24018,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, +@@ -22919,6 +23558,9 @@ aarch64_start_file (void) + aarch64_last_printed_arch_string.c_str ()); + + default_file_start (); ++#if TARGET_MACHO ++ darwin_file_start (); ++#endif + } + + /* Emit load exclusive. */ +@@ -23396,6 +24038,10 @@ aarch64_float_const_representable_p (rtx x) + || REAL_VALUE_MINUS_ZERO (r)) + return false; + ++ /* For BFmode, only handle 0.0. */ ++ if (GET_MODE (x) == BFmode) ++ return real_iszero (&r, false); ++ + /* Extract exponent. */ + r = real_value_abs (&r); + exponent = REAL_EXP (&r); +@@ -23499,6 +24145,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, } gcc_assert (CONST_INT_P (info.u.mov.value)); @@ -2362,7 +3232,7 @@ index f5db5379543..25443d35141 100644 if (which == AARCH64_CHECK_MOV) { -@@ -23444,16 +24036,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, +@@ -23507,16 +24163,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, ? "msl" : "lsl"); if (lane_count == 1) snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX, @@ -2382,7 +3252,7 @@ index f5db5379543..25443d35141 100644 } else { -@@ -23462,12 +24054,12 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, +@@ -23525,12 +24181,12 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, if (info.u.mov.shift) snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count, @@ -2397,7 +3267,7 @@ index f5db5379543..25443d35141 100644 } return templ; } -@@ -26664,7 +27256,8 @@ aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode) +@@ -26728,7 +27384,8 @@ aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode) } /* Implement TARGET_SCALAR_MODE_SUPPORTED_P - return TRUE @@ -2407,7 +3277,7 @@ index f5db5379543..25443d35141 100644 static bool aarch64_scalar_mode_supported_p (scalar_mode mode) -@@ -26672,7 +27265,7 @@ aarch64_scalar_mode_supported_p (scalar_mode mode) +@@ -26736,7 +27393,7 @@ aarch64_scalar_mode_supported_p (scalar_mode mode) if (DECIMAL_FLOAT_MODE_P (mode)) return default_decimal_float_supported_p (); @@ -2416,7 +3286,7 @@ index f5db5379543..25443d35141 100644 ? true : default_scalar_mode_supported_p (mode)); } -@@ -27402,19 +27995,37 @@ aarch64_sls_emit_shared_blr_thunks (FILE *out_file) +@@ -27476,19 +28133,37 @@ aarch64_sls_emit_shared_blr_thunks (FILE *out_file) continue; const char *name = indirect_symbol_names[regnum]; @@ -2457,7 +3327,68 @@ index f5db5379543..25443d35141 100644 } } -@@ -27607,6 +28218,15 @@ aarch64_run_selftests (void) +@@ -27519,6 +28194,60 @@ aarch64_indirect_call_asm (rtx addr) + return ""; + } + ++#if TARGET_MACHO ++/* This handles the promotion of function return values. ++ It also handles function args under two specific curcumstances: ++ - called from combine with a register argument ++ - caller for a libcall with type == NULL. ++ The remaining cases for argument promotion are handled with access to ++ cumulative args data, below. */ ++machine_mode ++aarch64_darwin_promote_fn_mode (const_tree type, machine_mode mode, ++ int *punsignedp, ++ const_tree funtype ATTRIBUTE_UNUSED, ++ int for_return ATTRIBUTE_UNUSED) ++{ ++ /* With the amended use of promote using cargs, the only cases that arrive ++ here with for_return == 0 are from combine (where the value is definitely ++ in a register) and for libcalls, where type == NULL. We want to promote ++ function return values in the callee, so this becomes pretty much ++ unconditional now. */ ++ if (type != NULL_TREE) ++ return promote_mode (type, mode, punsignedp); ++ return mode; ++} ++ ++/* Ensure that we only promote the mode of named parms when they are passed in ++ a register. Named values passed on the stack retain their original mode and ++ alignment. */ ++machine_mode ++aarch64_darwin_promote_function_mode_ca (cumulative_args_t ca, ++ function_arg_info arg, ++ const_tree funtype ATTRIBUTE_UNUSED, ++ int *punsignedp, ++ int for_return ATTRIBUTE_UNUSED) ++{ ++ tree type = arg.type; ++ machine_mode mode = arg.mode; ++ machine_mode new_mode = promote_mode (type, mode, punsignedp); ++ if (new_mode == mode || arg.named == false ++ || GET_MODE_CLASS (new_mode) != MODE_INT ++ || known_gt (GET_MODE_SIZE (new_mode), 4)) ++ return new_mode; ++ ++ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); ++ /* Make sure that changes in assumption do not get missed. */ ++ gcc_checking_assert (for_return == 0 && new_mode == SImode ++ && !pcum->aapcs_arg_processed); ++ /* We have a named integer value that fits in a reg; if there's one available ++ then promote the value. */ ++ if (pcum->aapcs_ncrn < 8) ++ return new_mode; ++ return mode; ++} ++ ++#endif ++ + /* Target-specific selftests. */ + + #if CHECKING_P +@@ -27681,6 +28410,15 @@ aarch64_run_selftests (void) #undef TARGET_ASM_ALIGNED_SI_OP #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" @@ -2473,7 +3404,7 @@ index f5db5379543..25443d35141 100644 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ hook_bool_const_tree_hwi_hwi_const_tree_true -@@ -27693,6 +28313,12 @@ aarch64_run_selftests (void) +@@ -27767,6 +28505,12 @@ aarch64_run_selftests (void) #undef TARGET_FUNCTION_ARG_BOUNDARY #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary @@ -2486,7 +3417,7 @@ index f5db5379543..25443d35141 100644 #undef TARGET_FUNCTION_ARG_PADDING #define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding -@@ -28017,7 +28643,7 @@ aarch64_libgcc_floating_mode_supported_p +@@ -28091,7 +28835,7 @@ aarch64_libgcc_floating_mode_supported_p /* The architecture reserves bits 0 and 1 so use bit 2 for descriptors. */ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS @@ -2495,8 +3426,20 @@ index f5db5379543..25443d35141 100644 #undef TARGET_HARD_REGNO_NREGS #define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs +@@ -28181,6 +28925,11 @@ aarch64_libgcc_floating_mode_supported_p + #undef TARGET_CONST_ANCHOR + #define TARGET_CONST_ANCHOR 0x1000000 + ++#if TARGET_MACHO ++#undef TARGET_FRAME_POINTER_REQUIRED ++#define TARGET_FRAME_POINTER_REQUIRED aarch64_darwin_frame_pointer_required ++#endif ++ + struct gcc_target targetm = TARGET_INITIALIZER; + + #include "gt-aarch64.h" diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h -index 73b09e20508..d11c0ba21b4 100644 +index cfeaf46..81d5658 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -65,6 +65,10 @@ @@ -2523,7 +3466,7 @@ index 73b09e20508..d11c0ba21b4 100644 /* Defined by the ABI */ #define WCHAR_TYPE "unsigned int" #define WCHAR_TYPE_SIZE 32 -@@ -934,6 +944,24 @@ typedef struct +@@ -944,6 +954,24 @@ typedef struct aapcs_reg == NULL_RTX. */ int aapcs_stack_size; /* The total size (in words, per 8 byte) of the stack arg area so far. */ @@ -2548,7 +3491,7 @@ index 73b09e20508..d11c0ba21b4 100644 bool silent_p; /* True if we should act silently, rather than raise an error for invalid calls. */ } CUMULATIVE_ARGS; -@@ -1232,8 +1260,13 @@ extern const char *aarch64_rewrite_mcpu (int argc, const char **argv); +@@ -1242,8 +1270,13 @@ extern const char *aarch64_rewrite_mcpu (int argc, const char **argv); #define ASM_CPU_SPEC \ MCPU_TO_MARCH_SPEC @@ -2563,7 +3506,7 @@ index 73b09e20508..d11c0ba21b4 100644 #define ASM_OUTPUT_POOL_EPILOGUE aarch64_asm_output_pool_epilogue -@@ -1246,6 +1279,10 @@ extern GTY(()) tree aarch64_fp16_ptr_type_node; +@@ -1256,6 +1289,10 @@ extern GTY(()) tree aarch64_fp16_ptr_type_node; bfloat16_type_node. Defined in aarch64-builtins.cc. */ extern GTY(()) tree aarch64_bf16_ptr_type_node; @@ -2575,14 +3518,14 @@ index 73b09e20508..d11c0ba21b4 100644 So in order to unwind a function using a frame pointer, the very first function that is unwound must save the frame pointer. That way the frame diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md -index 36d0bb3f718..454c0fc1a8e 100644 +index 922cc98..5c7c815 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -304,6 +304,7 @@ UNSPEC_LD1RO UNSPEC_SALT_ADDR UNSPECV_PATCHABLE_AREA -+ UNSPEC_MACHOPIC_OFFSET ++ UNSPEC_MACHOPIC_OFFSET ; Common to Mach-O ports. ]) (define_c_enum "unspecv" [ @@ -2624,7 +3567,7 @@ index 36d0bb3f718..454c0fc1a8e 100644 (define_insn "trap" [(trap_if (const_int 1) (const_int 8))] "" -@@ -1304,7 +1336,7 @@ +@@ -1322,7 +1354,7 @@ ldr\\t%s0, %1 str\\t%w1, %0 str\\t%s1, %0 @@ -2633,7 +3576,7 @@ index 36d0bb3f718..454c0fc1a8e 100644 adr\\t%x0, %c1 adrp\\t%x0, %A1 fmov\\t%s0, %w1 -@@ -1342,7 +1374,7 @@ +@@ -1360,7 +1392,7 @@ ldr\\t%d0, %1 str\\t%x1, %0 str\\t%d1, %0 @@ -2642,20 +3585,60 @@ index 36d0bb3f718..454c0fc1a8e 100644 adr\\t%x0, %c1 adrp\\t%x0, %A1 fmov\\t%d0, %x1 -@@ -7019,7 +7051,10 @@ +@@ -1799,16 +1831,16 @@ + (set_attr "arch" "*,fp")] + ) + +-(define_insn "load_pair_dw_tftf" +- [(set (match_operand:TF 0 "register_operand" "=w") +- (match_operand:TF 1 "aarch64_mem_pair_operand" "Ump")) +- (set (match_operand:TF 2 "register_operand" "=w") +- (match_operand:TF 3 "memory_operand" "m"))] ++(define_insn "load_pair_dw_" ++ [(set (match_operand:TX 0 "register_operand" "=w") ++ (match_operand:TX 1 "aarch64_mem_pair_operand" "Ump")) ++ (set (match_operand:TX2 2 "register_operand" "=w") ++ (match_operand:TX2 3 "memory_operand" "m"))] + "TARGET_SIMD + && rtx_equal_p (XEXP (operands[3], 0), + plus_constant (Pmode, + XEXP (operands[1], 0), +- GET_MODE_SIZE (TFmode)))" ++ GET_MODE_SIZE (mode)))" + "ldp\\t%q0, %q2, %z1" + [(set_attr "type" "neon_ldp_q") + (set_attr "fp" "yes")] +@@ -1849,11 +1881,11 @@ + (set_attr "arch" "*,fp")] + ) + +-(define_insn "store_pair_dw_tftf" +- [(set (match_operand:TF 0 "aarch64_mem_pair_operand" "=Ump") +- (match_operand:TF 1 "register_operand" "w")) +- (set (match_operand:TF 2 "memory_operand" "=m") +- (match_operand:TF 3 "register_operand" "w"))] ++(define_insn "store_pair_dw_" ++ [(set (match_operand:TX 0 "aarch64_mem_pair_operand" "=Ump") ++ (match_operand:TX 1 "register_operand" "w")) ++ (set (match_operand:TX2 2 "memory_operand" "=m") ++ (match_operand:TX2 3 "register_operand" "w"))] + "TARGET_SIMD && + rtx_equal_p (XEXP (operands[2], 0), + plus_constant (Pmode, +@@ -7045,7 +7077,10 @@ (lo_sum:P (match_operand:P 1 "register_operand" "r") (match_operand 2 "aarch64_valid_symref" "S")))] "" - "add\\t%0, %1, :lo12:%c2" + { return TARGET_MACHO -+ ? "add\\t%0, %1, %K2;momd" ++ ? "add\\t%0, %1, %J2;" + : "add\\t%0, %1, :lo12:%c2"; + } [(set_attr "type" "alu_imm")] ) diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt -index 1d7967db9c0..cc97d7263ba 100644 +index 1d7967d..cc97d72 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -158,6 +158,13 @@ Enum(aarch64_abi) String(ilp32) Value(AARCH64_ABI_ILP32) @@ -2673,7 +3656,7 @@ index 1d7967db9c0..cc97d7263ba 100644 Target Save Var(pcrelative_literal_loads) Init(2) Save PC relative literal loads. diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md -index 5b20abc27e5..9c6a631c6fb 100644 +index 5b20abc..9c6a631 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -168,7 +168,9 @@ @@ -2699,12 +3682,12 @@ index 5b20abc27e5..9c6a631c6fb 100644 (define_constraint "vgb" "@internal A constraint that matches an immediate offset valid for SVE LD1B -diff --git a/gcc/config/aarch64/darwin.h b/gcc/config/aarch64/darwin.h +diff --git b/gcc/config/aarch64/darwin.h b/gcc/config/aarch64/darwin.h new file mode 100644 -index 00000000000..5609c569dc1 +index 0000000..08febf1 --- /dev/null +++ b/gcc/config/aarch64/darwin.h -@@ -0,0 +1,279 @@ +@@ -0,0 +1,289 @@ +/* Target definitions for Arm64/Aarch64 running on macOS/iOS. + +Copyright The GNU Toolchain Authors. @@ -2733,15 +3716,20 @@ index 00000000000..5609c569dc1 +#undef DARWIN_ARM64 +#define DARWIN_ARM64 1 + -+/* FIXME FIXME FIXME - these are mostly guesses right now. */ -+ -+/* FIXME: this is only used in generic code in darwin.c. */ ++/* This is used in generic code in darwin.cc (at present, we have no support ++ for the arm64_32 target). */ +#undef TARGET_64BIT +#define TARGET_64BIT 1 + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + ++#undef TARGET_PROMOTE_FUNCTION_MODE ++#define TARGET_PROMOTE_FUNCTION_MODE aarch64_darwin_promote_fn_mode ++ ++#undef TARGET_PROMOTE_FUNCTION_MODE_CA ++#define TARGET_PROMOTE_FUNCTION_MODE_CA aarch64_darwin_promote_function_mode_ca ++ +/* NOTE that arm64_32 is a valid thing and corresponds to darwinpcs + and TARGET_ILP32, but we are not implementing that for now. */ +#define TARGET_OS_CPP_BUILTINS() \ @@ -2752,8 +3740,7 @@ index 00000000000..5609c569dc1 + darwin_cpp_builtins (pfile); \ + } while (0) + -+/* In Darwin's arm64 ABI, chars are signed, for consistency with other Darwin -+ architectures. */ ++/* In Darwin's Arm64 ABI, chars are signed. */ + +#undef DEFAULT_SIGNED_CHAR +#define DEFAULT_SIGNED_CHAR 1 @@ -2761,21 +3748,18 @@ index 00000000000..5609c569dc1 +#undef LONG_DOUBLE_TYPE_SIZE +#define LONG_DOUBLE_TYPE_SIZE 64 + -+/* Disable custom function descriptors on Darwin, it breaks ABI. */ ++/* Disable custom function descriptors on Darwin (we use heap-based ++ trampolines). */ +#undef AARCH64_CUSTOM_FUNCTION_TEST +#define AARCH64_CUSTOM_FUNCTION_TEST 0 + -+/* Non-PIE executables are forbidden by the aarch64-darwin security model; ++/* Non-PIE executables are forbidden by the Arm64-darwin security model; + remove the option from link-lines since they just produce a warning from + ld64 and are then ignored anyway. */ +#undef DARWIN_NOPIE_SPEC +#define DARWIN_NOPIE_SPEC \ +" % ++# include ++#endif ++ ++ ++#if TARGET_MACHO ++ ++/* Default architecture to use if -mcpu=native did not detect a known CPU. */ ++#define DEFAULT_ARCH "apple-m1" ++ ++/* macOS does not have /proc/cpuinfo and needs a different approach, ++ based on sysctl. It is much simpler. */ ++ ++const char * ++host_detect_local_cpu (ATTRIBUTE_UNUSED int argc, ATTRIBUTE_UNUSED const char **argv) ++{ ++ bool arch = false; ++ bool tune = false; ++ bool cpu = false; ++ const char *res = NULL; ++ uint32_t family; ++ size_t len = sizeof(family); ++ ++ gcc_assert (argc); ++ if (!argv[0]) ++ return NULL; ++ ++ /* Are we processing -march, mtune or mcpu? */ ++ arch = strcmp (argv[0], "arch") == 0; ++ if (!arch) ++ tune = strcmp (argv[0], "tune") == 0; ++ if (!arch && !tune) ++ cpu = strcmp (argv[0], "cpu") == 0; ++ if (!arch && !tune && !cpu) ++ return NULL; ++ ++ sysctlbyname("hw.cpufamily", &family, &len, NULL, 0); ++ ++ switch (family) ++ { ++ case 0x07d34b9f: // Vortex, Tempest ++ res = "apple-a12"; ++ break; ++ case 0x573b5eec: ++ case 0x1b588bb3: // Firestorm, Icestorm ++ res = "apple-m1"; ++ break; ++ case 0xda33d83d: // Blizzard, Avalanche ++ res = "apple-m2"; ++ break; ++ case 0xfa33415e: // Ibiza (M3) ++ case 0x5f4dea93: // Lobos (M3 Pro) ++ case 0x72015832: // Palma (M3 Max) ++ res = "apple-m3"; ++ break; ++ default: ++ res = DEFAULT_ARCH; ++ } ++ ++ if (res) ++ return concat ("-m", argv[0], "=", res, NULL); ++ else ++ return NULL; ++} ++ ++#else ++ + struct aarch64_arch_extension + { + const char *ext; +@@ -468,3 +536,4 @@ not_found: + } + } + ++#endif diff --git a/gcc/config/aarch64/falkor-tag-collision-avoidance.cc b/gcc/config/aarch64/falkor-tag-collision-avoidance.cc -index 39e3f5c2d1b..78790cd1d15 100644 +index 39e3f5c..9b3357f 100644 --- a/gcc/config/aarch64/falkor-tag-collision-avoidance.cc +++ b/gcc/config/aarch64/falkor-tag-collision-avoidance.cc @@ -740,7 +740,7 @@ dump_insn_list (const rtx &t, const insn_info_list_t &insn_info, @@ -2993,12 +4070,26 @@ index 39e3f5c2d1b..78790cd1d15 100644 { gcc_assert (dump_file); - fprintf (dump_file, "Tag 0x%lx ::\n", INTVAL (t)); -+ fprintf (dump_file, "Tag 0x%lx ::\n", (long unsigned int)INTVAL (t)); ++ fprintf (dump_file, "Tag 0x" HOST_WIDE_INT_PRINT_HEX_PURE " ::\n", INTVAL (t)); for (unsigned i = 0; i < insn_info.length (); i++) dump_insn_slim (dump_file, insn_info[i]->insn); +diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md +index 86a196d..0708a92 100644 +--- a/gcc/config/aarch64/iterators.md ++++ b/gcc/config/aarch64/iterators.md +@@ -316,6 +316,9 @@ + ;; TX plus V16QImode. + (define_mode_iterator TX_V16QI [TI TF TD V16QI]) + ++;; Duplicate of TX above ++(define_mode_iterator TX2 [TI TF TD]) ++ + (define_mode_iterator VTX [TI TF TD V16QI V8HI V4SI V2DI V8HF V4SF V2DF V8BF]) + + ;; Advanced SIMD opaque structure modes. diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md -index 3f5f4df8c46..4c3498dfe2c 100644 +index 3f5f4df..4c3498d 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -277,9 +277,24 @@ @@ -3026,9 +4117,9 @@ index 3f5f4df8c46..4c3498dfe2c 100644 return (aarch64_classify_symbolic_expression (op) != SYMBOL_FORCE_TO_MEM); }) -diff --git a/gcc/config/aarch64/t-aarch64-darwin b/gcc/config/aarch64/t-aarch64-darwin +diff --git b/gcc/config/aarch64/t-aarch64-darwin b/gcc/config/aarch64/t-aarch64-darwin new file mode 100644 -index 00000000000..9754e87ebcf +index 0000000..e2b8ad9 --- /dev/null +++ b/gcc/config/aarch64/t-aarch64-darwin @@ -0,0 +1,25 @@ @@ -3054,14 +4145,54 @@ index 00000000000..9754e87ebcf +LIB1ASMSRC = aarch64/lib1funcs.asm +LIB1ASMFUNCS = _aarch64_sync_cache_range + -+# FIXME - figure out what multilib provisions we should make for ++# TODO - figure out what multilib provisions we should make for +# a) arm64e +# b) arm64_32 +diff --git a/gcc/config/darwin-c.cc b/gcc/config/darwin-c.cc +index 579b9fa..10d5fb1 100644 +--- a/gcc/config/darwin-c.cc ++++ b/gcc/config/darwin-c.cc +@@ -555,7 +555,7 @@ find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp) + return 0; + } + +-/* Given an OS X version VERSION_STR, return it as a statically-allocated array ++/* Given an macOS version VERSION_STR, return it as a statically-allocated array + of three integers. If VERSION_STR is invalid, return NULL. + + VERSION_STR must consist of one, two, or three tokens, each separated by +@@ -612,7 +612,7 @@ parse_version (const char *version_str) + return version_array; + } + +-/* Given VERSION -- a three-component OS X version represented as an array of ++/* Given VERSION -- a three-component macOS version represented as an array of + non-negative integers -- return a statically-allocated string suitable for + the legacy __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. If VERSION + is invalid and cannot be coerced into a valid form, return NULL. +@@ -645,7 +645,7 @@ version_as_legacy_macro (const unsigned long *version) + return result; + } + +-/* Given VERSION -- a three-component OS X version represented as an array of ++/* Given VERSION -- a three-component macOS version represented as an array of + non-negative integers -- return a statically-allocated string suitable for + the modern __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. If VERSION + is invalid, return NULL. +@@ -675,7 +675,7 @@ version_as_modern_macro (const unsigned long *version) + + /* Return the value of darwin_macosx_version_min, suitably formatted for the + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. Values representing +- OS X 10.9 and earlier are encoded using the legacy four-character format, ++ macOS 10.9 and earlier are encoded using the legacy four-character format, + while 10.10 and later use a modern six-character format. (For example, + "10.9" produces "1090", and "10.10.1" produces "101001".) If + darwin_macosx_version_min is invalid and cannot be coerced into a valid diff --git a/gcc/config/darwin-driver.cc b/gcc/config/darwin-driver.cc -index 9c1dcc3d794..a4d7cfe7376 100644 +index 9c1dcc3..b2f39af 100644 --- a/gcc/config/darwin-driver.cc +++ b/gcc/config/darwin-driver.cc -@@ -268,14 +268,21 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -268,10 +268,13 @@ darwin_driver_init (unsigned int *decoded_options_count, bool seenX86_64 = false; bool seenPPC = false; bool seenPPC64 = false; @@ -3075,15 +4206,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 const char *vers_string = NULL; bool seen_version_min = false; bool seen_sysroot_p = false; - bool noexport_p = true; -+#ifdef RPATH_SETS_NODEFAULT -+ bool seen_rpath_p = false; -+ bool seen_nodefaultrpaths_p = false; -+#endif - - for (i = 1; i < *decoded_options_count; i++) - { -@@ -296,6 +303,12 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -296,6 +299,12 @@ darwin_driver_init (unsigned int *decoded_options_count, seenPPC = true; else if (!strcmp ((*decoded_options)[i].arg, "ppc64")) seenPPC64 = true; @@ -3096,7 +4219,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 else error ("this compiler does not support %qs", (*decoded_options)[i].arg); -@@ -309,7 +322,7 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -309,7 +318,7 @@ darwin_driver_init (unsigned int *decoded_options_count, --i; --*decoded_options_count; break; @@ -3105,7 +4228,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 case OPT_m32: seenM32 = true; break; -@@ -317,6 +330,7 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -317,6 +326,7 @@ darwin_driver_init (unsigned int *decoded_options_count, case OPT_m64: seenM64 = true; break; @@ -3113,24 +4236,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 case OPT_mmacosx_version_min_: seen_version_min = true; -@@ -349,8 +363,16 @@ darwin_driver_init (unsigned int *decoded_options_count, - gcc_checking_assert ((*decoded_options)[i].arg); - if (startswith ((*decoded_options)[i].arg, "-exported_symbol")) - noexport_p = false; -+#ifdef RPATH_SETS_NODEFAULT -+ else if (strncmp ((*decoded_options)[i].arg, "-rpath", 6) == 0) -+ seen_rpath_p = true; -+#endif - break; - -+#ifdef RPATH_SETS_NODEFAULT -+ case OPT_nodefaultrpaths: -+ seen_nodefaultrpaths_p = true; -+#endif - default: - break; - } -@@ -366,6 +388,9 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -366,6 +376,9 @@ darwin_driver_init (unsigned int *decoded_options_count, if (seenPPC || seenPPC64) warning (0, "this compiler does not support PowerPC" " (%<-arch%> option ignored)"); @@ -3140,7 +4246,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 if (seenX86) { if (seenX86_64 || seenM64) -@@ -389,6 +414,9 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -389,6 +402,9 @@ darwin_driver_init (unsigned int *decoded_options_count, if (seenX86 || seenX86_64) warning (0, "this compiler does not support x86" " (%<-arch%> option ignored)"); @@ -3150,7 +4256,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 if (seenPPC) { if (seenPPC64 || seenM64) -@@ -408,12 +436,20 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -408,12 +424,20 @@ darwin_driver_init (unsigned int *decoded_options_count, if (! seenM64) /* Add -m64 if the User didn't. */ appendM64 = true; } @@ -3171,7 +4277,7 @@ index 9c1dcc3d794..a4d7cfe7376 100644 if (appendM32 || appendM64) { ++*decoded_options_count; -@@ -423,6 +459,7 @@ darwin_driver_init (unsigned int *decoded_options_count, +@@ -423,6 +447,7 @@ darwin_driver_init (unsigned int *decoded_options_count, generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER, &(*decoded_options)[*decoded_options_count - 1]); } @@ -3179,28 +4285,72 @@ index 9c1dcc3d794..a4d7cfe7376 100644 if (!seen_sysroot_p) { -@@ -490,4 +527,16 @@ darwin_driver_init (unsigned int *decoded_options_count, - generate_option (OPT_nodefaultexport, NULL, 1, CL_DRIVER, - &(*decoded_options)[*decoded_options_count - 1]); +@@ -440,7 +465,7 @@ darwin_driver_init (unsigned int *decoded_options_count, + } } -+ -+#ifdef RPATH_SETS_NODEFAULT -+ if (seen_rpath_p && !seen_nodefaultrpaths_p) -+ { -+ ++*decoded_options_count; -+ *decoded_options = XRESIZEVEC (struct cl_decoded_option, -+ *decoded_options, -+ *decoded_options_count); -+ generate_option (OPT_nodefaultrpaths, NULL, 1, CL_DRIVER, -+ &(*decoded_options)[*decoded_options_count - 1]); -+ } -+#endif - } + +- /* We will need to know the OS X version we're trying to build for here ++ /* We will need to know the macOS version we're trying to build for here + so that we can figure out the mechanism and source for the sysroot to + be used. */ + if (!seen_version_min) +diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h +index 9df358e..babc888 100644 +--- a/gcc/config/darwin-protos.h ++++ b/gcc/config/darwin-protos.h +@@ -86,9 +86,12 @@ extern void darwin_asm_lto_end (void); + extern void darwin_mark_decl_preserved (const char *); + + extern tree darwin_handle_kext_attribute (tree *, tree, tree, int, bool *); +-extern tree darwin_handle_weak_import_attribute (tree *node, tree name, +- tree args, int flags, +- bool * no_add_attrs); ++extern tree darwin_handle_weak_import_attribute (tree *, tree, tree, int, ++ bool *); ++extern tree darwin_handle_availability_attribute (tree *, tree, tree, ++ int, bool *); ++extern bool darwin_attribute_takes_identifier_p (const_tree); ++ + extern void machopic_output_stub (FILE *, const char *, const char *); + extern void darwin_globalize_label (FILE *, const char *); + extern void darwin_assemble_visibility (tree, int); +@@ -124,6 +127,7 @@ extern void darwin_enter_string_into_cfstring_table (tree); + extern void darwin_asm_output_anchor (rtx symbol); + extern bool darwin_use_anchors_for_symbol_p (const_rtx symbol); + extern bool darwin_kextabi_p (void); ++extern bool darwin_unreachable_traps_p (void); + extern void darwin_override_options (void); + extern void darwin_patch_builtins (void); + extern void darwin_rename_builtins (void); diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc -index ced2f7e40a6..0915548477e 100644 +index 1471dbb..e95520f 100644 --- a/gcc/config/darwin.cc +++ b/gcc/config/darwin.cc -@@ -118,7 +118,7 @@ static bool ld_init_term_start_labels = false; +@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see + #include "cfghooks.h" + #include "df.h" + #include "memmodel.h" ++#include "c-family/c-common.h" /* enum rid. */ + #include "tm_p.h" + #include "stringpool.h" + #include "attribs.h" +@@ -49,6 +50,7 @@ along with GCC; see the file COPYING3. If not see + #include "optabs.h" + #include "flags.h" + #include "opts.h" ++#include "c-family/c-objc.h" /* for objc_method_decl(). */ + + /* Fix and Continue. + +@@ -102,6 +104,7 @@ int darwin_running_cxx; + + /* Some code-gen now depends on OS major version numbers (at least). */ + int generating_for_darwin_version ; ++unsigned long current_os_version = 0; + + /* For older linkers we need to emit special sections (marked 'coalesced') for + for weak or single-definition items. */ +@@ -131,7 +134,7 @@ struct { section * darwin_sections[NUM_DARWIN_SECTIONS]; /* While we transition to using in-tests instead of ifdef'd code. */ @@ -3209,7 +4359,7 @@ index ced2f7e40a6..0915548477e 100644 #define gen_macho_high(m,a,b) (a) #define gen_macho_low(m,a,b,c) (a) #endif -@@ -1052,6 +1052,7 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg) +@@ -1065,6 +1068,7 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg) return pic_ref; } @@ -3217,7 +4367,7 @@ index ced2f7e40a6..0915548477e 100644 /* Callbacks to output the stub or non-lazy pointers. Each works on the item in *SLOT,if it has been used. DATA is the FILE* for assembly output. -@@ -1207,6 +1208,7 @@ machopic_finish (FILE *out_file) +@@ -1220,6 +1224,7 @@ machopic_finish (FILE *out_file) machopic_indirections->traverse_noresize (out_file); } @@ -3225,114 +4375,647 @@ index ced2f7e40a6..0915548477e 100644 int machopic_operand_p (rtx op) -@@ -2240,6 +2242,8 @@ darwin_emit_except_table_label (FILE *file) - rtx - darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis)) - { -+ if (DARWIN_ARM64) -+ return orig; - if (DARWIN_PPC == 0 && TARGET_64BIT) - return orig; - -@@ -3060,7 +3064,12 @@ darwin_file_end (void) - fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags); - } +@@ -2155,6 +2160,122 @@ darwin_handle_kext_attribute (tree *node, tree name, + return NULL_TREE; + } -+#if !DARWIN_ARM64 - machopic_finish (asm_out_file); -+#else -+ gcc_checking_assert (!machopic_indirections); -+#endif ++enum version_components { MAJOR, MINOR, TINY }; + - if (flag_apple_kext) - { - /* These sections are only used for kernel code. */ -diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h -index 1b538c73593..7fb3ec40755 100644 ---- a/gcc/config/darwin.h -+++ b/gcc/config/darwin.h -@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - - #define DARWIN_X86 0 - #define DARWIN_PPC 0 -+#define DARWIN_ARM64 0 - - #define OBJECT_FORMAT_MACHO 1 - -@@ -303,6 +304,31 @@ extern GTY(()) int darwin_ms_struct; - #define DARWIN_CC1_SPEC \ - "% 10.11 mmacosx-version-min= -lgcc_s.1.1) \ -+ %:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) " -+#endif ++/* Parse a version number in x.y.z form and validate it as a macOS ++ version. Ideally, we'd put this in a common place usable by the ++ Darwin backend. */ + -+/* We might elect to add a path even when this compiler does not use embedded -+ run paths, so that we can use libraries from an alternate compiler that is -+ using embedded runpaths. */ -+#if DARWIN_DO_EXTRA_RPATH -+# define DARWIN_EXTRA_RPATH \ -+"%{!r:%{!nostdlib:%{!nodefaultrpaths:\ -+ %:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ -+ %:version-compare(>= 10.5 mmacosx-version-min= " DARWIN_ADD_RPATH ") \ -+ }}}" -+#else -+# define DARWIN_EXTRA_RPATH "" -+#endif ++static bool ++parse_version (unsigned version_array[3], const char *version_str) ++{ ++ size_t version_len; ++ char *end, last = '\0', delimiter = '.', alt_delim = '_'; + - #define SUBSUBTARGET_OVERRIDE_OPTIONS \ - do { \ - darwin_override_options (); \ -@@ -396,7 +422,9 @@ extern GTY(()) int darwin_ms_struct; - DARWIN_NOPIE_SPEC \ - DARWIN_RDYNAMIC \ - DARWIN_NOCOMPACT_UNWIND \ -- "}}}}}}} % 10.6 mmacosx-version-min= -lgcc_eh) \ - %:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w); \ - shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: \ -- %:version-compare(!> 10.11 mmacosx-version-min= -lgcc_s.1.1) \ -- %:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) \ -+ " DARWIN_SHARED_LIBGCC " \ - %:version-compare(!> 10.3.9 mmacosx-version-min= -lgcc_eh) \ - %:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \ - %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5); \ -@@ -547,7 +574,8 @@ extern GTY(()) int darwin_ms_struct; - { "darwin_crt2", DARWIN_CRT2_SPEC }, \ - { "darwin_crt3", DARWIN_CRT3_SPEC }, \ - { "darwin_dylib1", DARWIN_DYLIB1_SPEC }, \ -- { "darwin_bundle1", DARWIN_BUNDLE1_SPEC }, -+ { "darwin_bundle1", DARWIN_BUNDLE1_SPEC }, \ -+ { "darwin_rpaths", DARWIN_RPATH_SPEC }, - - #define DARWIN_CRT1_SPEC \ - "%:version-compare(!> 10.5 mmacosx-version-min= -lcrt1.o) \ -@@ -573,6 +601,17 @@ extern GTY(()) int darwin_ms_struct; - "%{!static:%:version-compare(< 10.6 mmacosx-version-min= -lbundle1.o) \ ++ if (!version_str) ++ return false; ++ ++ /* Handle the odd situation in which we get STRING_CST which contain the ++ starting and ending quotes. */ ++ if (version_str[0] == '"') ++ { ++ version_str++; ++ version_len = strrchr (&version_str[1], '"') - version_str; ++ last = '"'; ++ } ++ else ++ version_len = strlen (version_str); ++ ++ if (version_len < 1) ++ return false; ++ ++ /* Version string must consist of digits and periods only. */ ++ if (strspn (version_str, "0123456789._") != version_len) ++ return false; ++ ++ if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1])) ++ return false; ++ ++ version_array[MAJOR] = strtoul (version_str, &end, 10); ++ if (*end == '_') ++ { ++ delimiter = '_'; ++ alt_delim = '.'; ++ } ++ version_str = end + ((*end == delimiter) ? 1 : 0); ++ if (version_array[MAJOR] == 100000) ++ return true; ++ if (version_array[MAJOR] > 99) ++ return false; ++ ++ /* Version string must not contain adjacent delimiters. */ ++ if (*version_str == delimiter || *version_str == alt_delim) ++ return false; ++ ++ version_array[MINOR] = strtoul (version_str, &end, 10); ++ if (*end == alt_delim) ++ return false; ++ version_str = end + ((*end == delimiter) ? 1 : 0); ++ if (version_array[MINOR] > 99) ++ return false; ++ ++ version_array[TINY] = strtoul (version_str, &end, 10); ++ if (version_array[TINY] > 99) ++ return false; ++ ++ /* Version string must contain no more than three tokens. */ ++ if (*end != last) ++ return false; ++ ++ return true; ++} ++ ++/* Turn a version expressed as maj.min.tiny into an unsigned long ++ integer representing the value used in macOS availability macros. */ ++ ++static unsigned long ++version_from_version_array (unsigned vers[3]) ++{ ++ unsigned long res = 0; ++ /* There seems to be a special "unknown" value. */ ++ if (vers[0] == 100000) ++ return 999999; ++ ++ /* Here, we follow the 'modern' / 'legacy' numbering scheme for versions. */ ++ if (vers[0] > 10 || vers[1] >= 10) ++ res = vers[0] * 10000 + vers[1] * 100 + vers[2]; ++ else ++ { ++ res = vers[0] * 100; ++ if (vers[1] > 9) ++ res += 90; ++ else ++ res += vers[1] * 10; ++ if (vers[2] > 9) ++ res += 9; ++ else ++ res += vers[1]; ++ } ++ return res; ++} ++ ++/* Extract a macOS version from an availability attribute argument. */ ++ ++static unsigned long ++os_version_from_avail_value (tree value) ++{ ++ unsigned long res = 0; ++ unsigned vers[3] = {0,0,0}; ++ if (TREE_CODE (value) == STRING_CST) ++ { ++ if (parse_version (&vers[0], TREE_STRING_POINTER (value))) ++ res = version_from_version_array (&vers[0]); ++ } ++ else ++ gcc_unreachable (); ++ return res; ++} ++ + /* Handle a "weak_import" attribute; arguments as in + struct attribute_spec.handler. */ + +@@ -2176,6 +2297,231 @@ darwin_handle_weak_import_attribute (tree *node, tree name, + return NULL_TREE; + } + ++#define NUM_AV_OSES 13 ++const char *availability_os[NUM_AV_OSES] ++ = { "macos", "macosx", "ios", "tvos", "watchos", "driverkit", "swift", ++ "maccatalyst", "macCatalyst", "xros", "visionos", "android", "zos" }; ++ ++#define NUM_AV_CLAUSES 6 ++const char *availability_clause[NUM_AV_CLAUSES] ++ = { "unavailable", "introduced", "deprecated", "obsoleted", "message", ++ "replacement" }; ++ ++/* Validate and act upon the arguments to an 'availability' attribute. */ ++ ++tree ++darwin_handle_availability_attribute (tree *node, tree name, tree args, ++ int flags, bool * no_add_attrs) ++{ ++ tree decl = *node; ++ *no_add_attrs = true; ++ ++ if (!decl || (!TYPE_P (decl) && !DECL_P (decl))) ++ { ++ warning (OPT_Wattributes, "%qE attribute ignored", name); ++ return NULL_TREE; ++ } ++ else if (decl == error_mark_node) ++ return NULL_TREE; ++ ++ location_t loc = DECL_SOURCE_LOCATION (decl); ++ if (args == NULL_TREE) ++ { ++ error_at (loc, "%qE attribute requires at least one argument", ++ name); ++ return NULL_TREE; ++ } ++ else if (args == error_mark_node) ++ return NULL_TREE; ++ ++ /* The first argument must name a supported OS - although we could choose ++ to ignore any OS we don't recognise. */ ++ gcc_checking_assert (TREE_CODE (args) == TREE_LIST); ++ tree platform = TREE_VALUE (args); ++ if (platform == error_mark_node) ++ return NULL_TREE; ++ ++ gcc_checking_assert (TREE_CODE (platform) == IDENTIFIER_NODE); ++ bool platform_ok = false; ++ unsigned plat_num = 0; ++ for (; plat_num < (unsigned) NUM_AV_OSES; plat_num++) ++ if (strcmp (availability_os[plat_num], IDENTIFIER_POINTER (platform)) == 0) ++ { ++ platform_ok = true; ++ break; ++ } ++ if (!platform_ok) ++ { ++ error_at (input_location, ++ "platform %qE is not recognised for the % " ++ "attribute", platform); ++ return NULL_TREE; ++ } ++ else if (plat_num > 1) /* We only compile for macos so far. */ ++ return NULL_TREE; ++ ++ /* We might be dealing with an object or type. */ ++ tree target_decl = NULL_TREE; ++ tree type = NULL_TREE; ++ bool warn = false; ++ if (DECL_P (*node)) ++ { ++ type = TREE_TYPE (decl); ++ ++ if (TREE_CODE (decl) == TYPE_DECL ++ || TREE_CODE (decl) == PARM_DECL ++ || VAR_OR_FUNCTION_DECL_P (decl) ++ || TREE_CODE (decl) == FIELD_DECL ++ || TREE_CODE (decl) == CONST_DECL ++ /*|| objc_method_decl (TREE_CODE (decl))*/) ++ target_decl = decl; ++ else ++ warn = true; ++ } ++ else if (TYPE_P (*node)) ++ type = target_decl = *node; ++ else ++ warn = true; ++ ++ tree what = NULL_TREE; ++ if (warn) ++ { ++ if (type && TYPE_NAME (type)) ++ { ++ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ++ what = TYPE_NAME (*node); ++ else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ++ && DECL_NAME (TYPE_NAME (type))) ++ what = DECL_NAME (TYPE_NAME (type)); ++ } ++ if (what) ++ warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what); ++ else ++ warning (OPT_Wattributes, "%qE attribute ignored", name); ++ return NULL_TREE; ++ } ++ ++ /* Now we have to parse the availability clauses. */ ++ tree msg = NULL_TREE; ++ tree replacement = NULL_TREE; ++ bool unavailable = false; ++ unsigned introduced = 1000; ++ unsigned deprecated = current_os_version + 1; ++ unsigned obsoleted = current_os_version + 1; ++ for (tree arg = TREE_CHAIN (args); arg; arg = TREE_CHAIN (arg)) ++ { ++ tree clause_name = TREE_VALUE (arg); ++ tree clause_value = TREE_PURPOSE (arg); ++ if (clause_name == error_mark_node ++ || clause_value == error_mark_node) ++ continue; ++ unsigned clause_num = 0; ++ for (; clause_num < (unsigned) NUM_AV_CLAUSES; clause_num++) ++ if (strcmp (availability_clause[clause_num], ++ IDENTIFIER_POINTER (clause_name)) == 0) ++ break; ++ switch (clause_num) ++ { ++ default: ++ error_at (input_location, ++ "clause %qE is not recognised for the % " ++ "attribute", clause_name); ++ break; ++ case 0: ++ unavailable = true; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ if (!clause_value) ++ error_at (input_location, "%<%E=%> requires a value", clause_name); ++ else ++ { ++ unsigned version = os_version_from_avail_value (clause_value); ++ if (version == 0) ++ error_at (input_location, "the value %qE provided to %qE is " ++ "not a valid OS version", clause_value, clause_name); ++ else if (clause_num == 1) ++ introduced = version; ++ else if (clause_num == 2) ++ deprecated = version; ++ else if (clause_num == 3) ++ obsoleted = version; ++ } ++ break; ++ case 4: ++ case 5: ++ if (!clause_value || TREE_CODE (clause_value) != STRING_CST) ++ error_at (input_location, "%<%E=%> requires a string", clause_name); ++ else if (clause_num == 4) ++ msg = clause_value; ++ else ++ replacement = clause_value; ++ break; ++ } ++ } ++ /* Now figure out what to do. */ ++ tree maybe_text = NULL_TREE; ++ if (replacement) ++ maybe_text = tree_cons (NULL_TREE, replacement, NULL_TREE); ++ else if (msg) ++ maybe_text = tree_cons (NULL_TREE, msg, NULL_TREE); ++ ++ if (unavailable || current_os_version >= obsoleted) ++ { ++ TREE_UNAVAILABLE (*node) = true; ++ /* We do not handle the availability attribute at diagnostics-time, so ++ if we want the informational messages, then attach them to additional ++ attributes for the deprecation or unavailability. TODO; maybe we can ++ fabricate the composite here. */ ++ if (maybe_text) ++ { ++ *no_add_attrs = false; ++ tree new_attr = tree_cons (get_identifier ("unavailable"), ++ maybe_text, NULL_TREE); ++ /* This is the actual consequence of the evaluation. */ ++ if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) ++ { ++ *node = build_variant_type_copy (*node); ++ TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node), ++ new_attr); ++ } ++ else ++ DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node), ++ new_attr); ++ } ++ } ++ else if (current_os_version > deprecated) ++ { ++ TREE_DEPRECATED (*node) = true; ++ if (maybe_text) ++ { ++ *no_add_attrs = false; ++ tree new_attr = tree_cons (get_identifier ("deprecated"), ++ maybe_text, NULL_TREE); ++ /* This is the actual consequence of the evaluation. */ ++ if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) ++ { ++ *node = build_variant_type_copy (*node); ++ TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node), ++ new_attr); ++ } ++ else ++ DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node), ++ new_attr); ++ } ++ } ++ else if (current_os_version < introduced) ++ *no_add_attrs = false; ++ return NULL_TREE; ++} ++ ++bool ++darwin_attribute_takes_identifier_p (const_tree attr_id) ++{ ++ return is_attribute_p ("availability", attr_id); ++} ++ + /* Emit a label for an FDE, making it global and/or weak if appropriate. + The third parameter is nonzero if this is for exception handling. + The fourth parameter is nonzero if this is just a placeholder for an +@@ -2267,6 +2613,8 @@ darwin_emit_except_table_label (FILE *file) + rtx + darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis)) + { ++ if (DARWIN_ARM64) ++ return orig; + if (DARWIN_PPC == 0 && TARGET_64BIT) + return orig; + +@@ -3115,7 +3463,12 @@ darwin_file_end (void) + fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags); + } + ++#if !DARWIN_ARM64 + machopic_finish (asm_out_file); ++#else ++ gcc_checking_assert (!machopic_indirections); ++#endif ++ + if (flag_apple_kext) + { + /* These sections are only used for kernel code. */ +@@ -3291,6 +3644,13 @@ darwin_kextabi_p (void) { + return flag_apple_kext; + } + ++/* True, iff we want to map __builtin_unreachable to a trap. */ ++ ++bool ++darwin_unreachable_traps_p (void) { ++ return darwin_unreachable_traps; ++} ++ + void + darwin_override_options (void) + { +@@ -3311,7 +3671,14 @@ darwin_override_options (void) + generating_for_darwin_version = 8; + + /* Earlier versions are not specifically accounted, until required. */ ++ unsigned vers[3] = {0,0,0}; ++ if (!parse_version (vers, darwin_macosx_version_min)) ++ error_at (UNKNOWN_LOCATION, "how did we get a bad OS version? (%s)", ++ darwin_macosx_version_min); ++ current_os_version = version_from_version_array (vers); + } ++ else ++ current_os_version = 1058; + + /* Some codegen needs to account for the capabilities of the target + linker. */ +diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h +index 5c6c38d..fcf9eff 100644 +--- a/gcc/config/darwin.h ++++ b/gcc/config/darwin.h +@@ -1,4 +1,4 @@ +-/* Target definitions for Darwin (Mac OS X) systems. ++/* Target definitions for Darwin (macOS) systems. + Copyright (C) 1989-2023 Free Software Foundation, Inc. + Contributed by Apple Computer Inc. + +@@ -27,7 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define CONFIG_DARWIN_H + + /* The definitions in this file are common to all processor types +- running Darwin, which is the kernel for Mac OS X. Darwin is ++ running Darwin, which is the kernel for macOS. Darwin is + basically a BSD user layer laid over a Mach kernel, then evolved + for many years (at NeXT) in parallel with other Unix systems. So + while the runtime is a somewhat idiosyncratic Mach-based thing, +@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + + #define DARWIN_X86 0 + #define DARWIN_PPC 0 ++#define DARWIN_ARM64 0 + + #define OBJECT_FORMAT_MACHO 1 + +@@ -133,10 +134,9 @@ extern GTY(()) int darwin_ms_struct; + cases where these driver opts are used multiple times, or to control + operations on more than one command (e.g. dynamiclib). These are handled + specially and we then add %= 10.7 mmacosx-version-min= -no_pie) }" + + #define DARWIN_CC1_SPEC \ +- "% 10.11 mmacosx-version-min= -lgcc_s.1.1)" ++# define DARWIN_SHARED_WEAK_ADDS \ ++"%{%:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w): \ ++ " DARWIN_HEAP_T_LIB "}" ++#endif ++ ++ ++/* We might elect to add a path even when this compiler does not use embedded ++ run paths, so that we can use libraries from an alternate compiler that is ++ using embedded runpaths. */ ++#if DARWIN_DO_EXTRA_RPATH ++# define DARWIN_EXTRA_RPATH \ ++"%{!r:%{!nostdlib:%{!nodefaultrpaths:\ ++ %:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ ++ %:version-compare(>= 10.5 mmacosx-version-min= " DARWIN_ADD_RPATH ") \ ++ }}}" ++#else ++# define DARWIN_EXTRA_RPATH "" ++#endif + + #define SUBSUBTARGET_OVERRIDE_OPTIONS \ + do { \ +@@ -336,7 +372,8 @@ extern GTY(()) int darwin_ms_struct; + */ + + #define DARWIN_NOCOMPACT_UNWIND \ +-" %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind) " ++"%{!fuse-ld=lld: \ ++ %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind)}" + + /* In Darwin linker specs we can put -lcrt0.o and ld will search the library + path for crt0.o or -lcrtx.a and it will search for libcrtx.a. As for +@@ -356,10 +393,12 @@ extern GTY(()) int darwin_ms_struct; + #define LINK_COMMAND_SPEC_A \ + "%{!c:%{!E:%{!S:%{!M:%{!MM:%{!fsyntax-only:%{!fdump=*: \ + %(linker)" \ ++ DARWIN_LD_DEMANGLE \ + LINK_PLUGIN_SPEC \ + "%{flto*:% 10.6 mmacosx-version-min= -lgcc_eh); \ + shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: \ +- %:version-compare(!> 10.11 mmacosx-version-min= -lgcc_s.1.1) \ ++ " DARWIN_SHARED_LIBGCC " \ + %:version-compare(!> 10.3.9 mmacosx-version-min= -lgcc_eh) \ + %:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \ + %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \ +@@ -520,18 +561,19 @@ extern GTY(()) int darwin_ms_struct; + + #define DARWIN_WEAK_CRTS \ + "%{static-libgcc|static: \ +- %:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w) ; \ +- shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: \ +- %:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) ; \ +- : -lemutls_w \ ++ %{%:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w): \ ++ " DARWIN_HEAP_T_LIB "} ; \ ++ shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: " \ ++ DARWIN_SHARED_WEAK_ADDS " ; \ ++ : -lemutls_w " DARWIN_HEAP_T_LIB " \ + }" + + /* We specify crt0.o as -lcrt0.o so that ld will search the library path. */ + + #undef STARTFILE_SPEC + #define STARTFILE_SPEC \ +-"%{dynamiclib: %(darwin_dylib1) %{fgnu-tm: -lcrttms.o}} \ +- %{!dynamiclib:%{bundle:%(darwin_bundle1)} \ ++"%{dynamiclib|shared: %(darwin_dylib1) %{fgnu-tm: -lcrttms.o}} \ ++ %{!dynamiclib:%{!shared:%{bundle:%(darwin_bundle1)} \ + %{!bundle:%{pg:%{static:-lgcrt0.o} \ + %{!static:%{object:-lgcrt0.o} \ + %{!object:%{preload:-lgcrt0.o} \ +@@ -542,8 +584,8 @@ extern GTY(()) int darwin_ms_struct; + %{!static:%{object:-lcrt0.o} \ + %{!object:%{preload:-lcrt0.o} \ + %{!preload: %(darwin_crt1) \ +- %(darwin_crt2)}}}}}} \ +- %(darwin_crt3) % 10.5 mmacosx-version-min= -lcrt1.o) \ +@@ -580,6 +623,16 @@ extern GTY(()) int darwin_ms_struct; + "%{!static:%:version-compare(< 10.6 mmacosx-version-min= -lbundle1.o) \ %{fgnu-tm: -lcrttms.o}}" +#if DARWIN_AT_RPATH -+/* A default rpath, that picks up dependent libraries installed in the same ++/* A default rpath, that picks up dependent libraries installed in the same + director as one being loaded. */ +#define DARWIN_RPATH_SPEC \ + "%:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ -+ %:version-compare(>= 10.5 mmacosx-version-min= @loader_path) \ -+ %P " ++ %{%:version-compare(>= 10.5 mmacosx-version-min= @loader_path): %P }" +#else +#define DARWIN_RPATH_SPEC "" +#endif @@ -3340,11 +5023,47 @@ index 1b538c73593..7fb3ec40755 100644 #ifdef HAVE_AS_MMACOSX_VERSION_MIN_OPTION /* Emit macosx version (but only major). */ #define ASM_MMACOSX_VERSION_MIN_SPEC \ +@@ -927,7 +980,12 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS]; + { "apple_kext_compatibility", 0, 0, false, true, false, false, \ + darwin_handle_kext_attribute, NULL }, \ + { "weak_import", 0, 0, true, false, false, false, \ +- darwin_handle_weak_import_attribute, NULL } ++ darwin_handle_weak_import_attribute, NULL }, \ ++ { "availability", 0, -1, true, false, false, false, \ ++ darwin_handle_availability_attribute, NULL } ++ ++#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P ++#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P darwin_attribute_takes_identifier_p + + /* Make local constant labels linker-visible, so that if one follows a + weak_global constant, ld64 will be able to separate the atoms. */ +@@ -1175,6 +1233,10 @@ void add_framework_path (char *); + #define TARGET_N_FORMAT_TYPES 1 + #define TARGET_FORMAT_TYPES darwin_additional_format_types + ++/* We want __builtin_unreachable to be expanded as a trap instruction. */ ++#undef TARGET_UNREACHABLE_SHOULD_TRAP ++#define TARGET_UNREACHABLE_SHOULD_TRAP darwin_unreachable_traps_p ++ + #ifndef USED_FOR_TARGET + extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **); + #define GCC_DRIVER_HOST_INITIALIZATION \ diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt -index d655aaef2fb..ff624ffd82a 100644 +index d655aae..97b1a74 100644 --- a/gcc/config/darwin.opt +++ b/gcc/config/darwin.opt -@@ -241,6 +241,10 @@ nodefaultexport +@@ -91,6 +91,10 @@ mtarget-linker + Target RejectNegative Joined Separate Var(darwin_target_linker) Init(LD64_VERSION) + -mtarget-linker Specify that ld64 is the toolchain linker for the current invocation. + ++munreachable-traps ++Target Var(darwin_unreachable_traps) Init(1) ++When set (the default) this makes __builtin_unreachable render as a trap. ++ + ; Driver options. + + all_load +@@ -241,6 +245,10 @@ nodefaultexport Driver RejectNegative Do not add a default symbol exports to modules or dynamic libraries. @@ -3356,10 +5075,20 @@ index d655aaef2fb..ff624ffd82a 100644 Driver RejectNegative (Obsolete after 10.3.9) Set MH_NOPREFIXBINDING, in an executable. diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h -index 588bd669bdd..b6c9a94c3a0 100644 +index 588bd66..657ea47 100644 --- a/gcc/config/i386/darwin.h +++ b/gcc/config/i386/darwin.h -@@ -308,3 +308,10 @@ along with GCC; see the file COPYING3. If not see +@@ -121,6 +121,9 @@ along with GCC; see the file COPYING3. If not see + #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC + #endif + ++#undef DARWIN_HEAP_T_LIB ++#define DARWIN_HEAP_T_LIB " -lheapt_w " ++ + #undef SUBTARGET_EXTRA_SPECS + #define SUBTARGET_EXTRA_SPECS \ + DARWIN_EXTRA_SPECS \ +@@ -308,3 +311,9 @@ along with GCC; see the file COPYING3. If not see #define CLEAR_INSN_CACHE(beg, end) \ extern void sys_icache_invalidate(void *start, size_t len); \ sys_icache_invalidate ((beg), (size_t)((end)-(beg))) @@ -3368,13 +5097,12 @@ index 588bd669bdd..b6c9a94c3a0 100644 + trampolines. */ +#undef X86_CUSTOM_FUNCTION_TEST +#define X86_CUSTOM_FUNCTION_TEST \ -+ (!flag_off_stack_trampolines && !flag_trampolines) ? 1 : 0 -+ ++ (flag_trampolines && flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) ? 0 : 1 diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc -index a551b8b9d9b..dd9f22b440f 100644 +index 4991841..be6d408 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc -@@ -25189,7 +25189,7 @@ ix86_libgcc_floating_mode_supported_p +@@ -25245,7 +25245,7 @@ ix86_libgcc_floating_mode_supported_p #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS @@ -3384,7 +5112,7 @@ index a551b8b9d9b..dd9f22b440f 100644 #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h -index 27b9783cae8..f97d3027da3 100644 +index 539083f..77644b0 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -754,6 +754,12 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); @@ -3400,8 +5128,165 @@ index 27b9783cae8..f97d3027da3 100644 /* C++ stores the virtual bit in the lowest bit of function pointers. */ #define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_pfn +diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h +index 4d5d6f6..3a2e480 100644 +--- a/gcc/config/rs6000/darwin.h ++++ b/gcc/config/rs6000/darwin.h +@@ -98,7 +98,7 @@ + Include libmx when targeting Darwin 7.0 and above, but before libSystem, + since the functions are actually in libSystem but for 7.x compatibility + we want them to be looked for in libmx first. +- Include libSystemStubs when compiling against 10.3 - 10.5 SDKs (we assume ++ Include libSystemStubs when compiling against 10.3 - 10.6 SDKs (we assume + this is the case when targetting these) - but not for 64-bit long double. + Don't do either for m64, the library is either a dummy or non-existent. + */ +@@ -107,12 +107,15 @@ + #define LIB_SPEC \ + "%{!static: \ + %{!m64:%{!mlong-double-64: \ +- %{pg:%:version-compare(>< 10.3 10.5 mmacosx-version-min= -lSystemStubs_profile)} \ +- %{!pg:%:version-compare(>< 10.3 10.5 mmacosx-version-min= -lSystemStubs)} \ ++ %{pg:%:version-compare(>< 10.3 10.7 mmacosx-version-min= -lSystemStubs_profile)} \ ++ %{!pg:%:version-compare(>< 10.3 10.7 mmacosx-version-min= -lSystemStubs)} \ + %:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)}} \ + -lSystem \ + }" + ++#undef DARWIN_HEAP_T_LIB ++#define DARWIN_HEAP_T_LIB " " ++ + /* We want -fPIC by default, unless we're using -static to compile for + the kernel or some such. The "-faltivec" option should have been + called "-maltivec" all along. */ +diff --git a/gcc/config.gcc b/gcc/config.gcc +index c3b73d0..1b80761 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -1125,6 +1125,26 @@ case ${target} in + ;; + esac + ++# Figure out if we need to enable heap trampolines ++# and variadic functions handling. ++case ${target} in ++aarch64*-*-darwin2*) ++ # This applies to arm64 Darwin variadic funtions. ++ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1" ++ # Executable stack is forbidden. ++ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1" ++ ;; ++*-*-darwin2*) ++ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" ++ # Currently, we do this for macOS 11 and above. ++ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1" ++ ;; ++*) ++ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" ++ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=0" ++ ;; ++esac ++ + case ${target} in + aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) + tm_file="${tm_file} elfos.h newlib-stdint.h" +@@ -1164,6 +1184,14 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) + done + TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'` + ;; ++aarch64-*-darwin* ) ++ tm_file="${tm_file} aarch64/aarch64-errata.h" ++ tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-darwin" ++ tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1" ++ tm_defines="${tm_defines} DISABLE_AARCH64_AS_CRC_BUGFIX=1" ++ # Choose a default CPU version that will work for all current releases. ++ with_cpu=${with_cpu:-apple-m1} ++ ;; + aarch64*-*-freebsd*) + tm_file="${tm_file} elfos.h ${fbsd_tm_file}" + tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-freebsd.h" +@@ -4125,8 +4153,8 @@ case "${target}" in + fi + for which in cpu arch tune; do + eval "val=\$with_$which" +- base_val=`echo $val | sed -e 's/\+.*//'` +- ext_val=`echo $val | sed -e 's/[a-z0-9.-]\+//'` ++ base_val=`echo $val | sed -E -e 's/\+.*//'` ++ ext_val=`echo $val | sed -E -e 's/[a-z0-9.-]+//'` + + if [ $which = arch ]; then + def=aarch64-arches.def +@@ -4158,9 +4186,9 @@ case "${target}" in + + while [ x"$ext_val" != x ] + do +- ext_val=`echo $ext_val | sed -e 's/\+//'` +- ext=`echo $ext_val | sed -e 's/\+.*//'` +- base_ext=`echo $ext | sed -e 's/^no//'` ++ ext_val=`echo $ext_val | sed -E -e 's/\+//'` ++ ext=`echo $ext_val | sed -E -e 's/\+.*//'` ++ base_ext=`echo $ext | sed -E -e 's/^no//'` + opt_line=`echo -e "$options_parsed" | \ + grep "^\"$base_ext\""` + +@@ -4171,7 +4199,7 @@ case "${target}" in + echo "Unknown extension used in --with-$which=$val" 1>&2 + exit 1 + fi +- ext_val=`echo $ext_val | sed -e 's/[a-z0-9]\+//'` ++ ext_val=`echo $ext_val | sed -E -e 's/[a-z0-9]+//'` + done + + true +diff --git a/gcc/config.in b/gcc/config.in +index 5281a12..b70b0be 100644 +--- a/gcc/config.in ++++ b/gcc/config.in +@@ -49,6 +49,19 @@ + #endif + + ++/* Specify a runpath directory, additional to those provided by the compiler ++ */ ++#ifndef USED_FOR_TARGET ++#undef DARWIN_ADD_RPATH ++#endif ++ ++ ++/* Should add an extra runpath directory */ ++#ifndef USED_FOR_TARGET ++#undef DARWIN_DO_EXTRA_RPATH ++#endif ++ ++ + /* Define to enable the use of a default assembler. */ + #ifndef USED_FOR_TARGET + #undef DEFAULT_ASSEMBLER +@@ -634,8 +647,7 @@ + #endif + + +-/* Define if your Mac OS X assembler supports -mllvm -x86-pad-for-align=false. +- */ ++/* Define if your macOS assembler supports -mllvm -x86-pad-for-align=false. */ + #ifndef USED_FOR_TARGET + #undef HAVE_AS_MLLVM_X86_PAD_FOR_ALIGN + #endif +@@ -2201,6 +2213,12 @@ + #endif + + ++/* Define to 1 if ld64 supports '-demangle'. */ ++#ifndef USED_FOR_TARGET ++#undef LD64_HAS_DEMANGLE ++#endif ++ ++ + /* Define to 1 if ld64 supports '-export_dynamic'. */ + #ifndef USED_FOR_TARGET + #undef LD64_HAS_EXPORT_DYNAMIC diff --git a/gcc/configure b/gcc/configure -index c7b26d1927d..f4bd9c5d5f1 100755 +index ade0af2..4af01a0 100755 --- a/gcc/configure +++ b/gcc/configure @@ -632,10 +632,10 @@ ac_includes_default="\ @@ -3418,7 +5303,14 @@ index c7b26d1927d..f4bd9c5d5f1 100755 enable_host_shared enable_plugin pluginlibs -@@ -740,6 +740,8 @@ ORIGINAL_PLUGIN_LD_FOR_TARGET +@@ -735,11 +735,15 @@ ORIGINAL_NM_FOR_TARGET + gcc_cv_nm + ORIGINAL_LD_GOLD_FOR_TARGET + ORIGINAL_LD_BFD_FOR_TARGET ++ORIGINAL_CLASSIC_LD_FOR_TARGET ++ORIGINAL_LLD_FOR_TARGET + ORIGINAL_LD_FOR_TARGET + ORIGINAL_PLUGIN_LD_FOR_TARGET gcc_cv_ld ORIGINAL_AS_FOR_TARGET gcc_cv_as @@ -3427,7 +5319,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 enable_fast_install objdir OTOOL64 -@@ -1003,6 +1005,8 @@ enable_static +@@ -1004,6 +1008,8 @@ enable_static with_pic enable_fast_install enable_libtool_lock @@ -3436,7 +5328,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 enable_ld enable_gold with_plugin_ld -@@ -1028,6 +1032,7 @@ enable_link_serialization +@@ -1029,6 +1035,7 @@ enable_link_serialization enable_version_specific_runtime_libs enable_plugin enable_host_shared @@ -3444,16 +5336,17 @@ index c7b26d1927d..f4bd9c5d5f1 100755 enable_libquadmath_support with_linker_hash_style with_diagnostics_color -@@ -1736,6 +1741,8 @@ Optional Features: +@@ -1742,6 +1749,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-ld[=ARG] build ld [ARG={default,yes,no}] --enable-gold[=ARG] build gold [ARG={default,yes,no}] --enable-gnu-indirect-function -@@ -1790,6 +1797,7 @@ Optional Features: +@@ -1796,6 +1806,7 @@ Optional Features: in a compiler-specific directory --enable-plugin enable plugin support --enable-host-shared build host code as shared libraries @@ -3461,7 +5354,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 --disable-libquadmath-support disable libquadmath support for Fortran --enable-default-pie enable Position Independent Executable as default -@@ -1854,6 +1862,9 @@ Optional Packages: +@@ -1860,6 +1871,9 @@ Optional Packages: --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] @@ -3471,80 +5364,58 @@ index c7b26d1927d..f4bd9c5d5f1 100755 --with-plugin-ld=[ARG] specify the plugin linker --with-glibc-version=M.N assume GCC used with glibc version M.N or later -@@ -3753,33 +3764,59 @@ gcc_gxx_libcxx_include_dir= +@@ -3759,20 +3773,19 @@ gcc_gxx_libcxx_include_dir= # Check whether --with-gxx-libcxx-include-dir was given. if test "${with_gxx_libcxx_include_dir+set}" = set; then : - withval=$with_gxx_libcxx_include_dir; case "${withval}" in -yes) as_fn_error $? "bad value ${withval} given for libc++ include directory" "$LINENO" 5 ;; --no) ;; -*) gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;; -esac + withval=$with_gxx_libcxx_include_dir; gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir fi -+# --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option. -+# if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option. + # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option. + # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option. +# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use +# the default path within the installation. -+# if --with-gxx-libcxx-include-dir is unset we enable the stdlib option + # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option +-# based on the platform (to be available on platform versions where it is the +# based on the platform (to be available on platform versions where it is the -+# default for the system tools). We also use a default path within the compiler + # default for the system tools). We also use a default path within the compiler +-# install tree. +-# Otherwise, we use the path provided and enable the stdlib option. +# install tree. +# Otherwise, we use the path provided and enable the stdlib option. # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we # check to see if the latter starts with the former and, upon success, compute - # gcc_gxx_libcxx_include_dir as relative to the sysroot. - gcc_gxx_libcxx_include_dir_add_sysroot=0 -- -+gcc_enable_stdlib_opt=0 - if test x${gcc_gxx_libcxx_include_dir} != x; then -+ if test x${gcc_gxx_libcxx_include_dir} = xno; then -+ # set defaults for the dir, but the option is disabled anyway. -+ gcc_gxx_libcxx_include_dir= -+ elif test x${gcc_gxx_libcxx_include_dir} = xyes; then -+ # set defaults for the dir, and enable. -+ gcc_gxx_libcxx_include_dir= -+ gcc_enable_stdlib_opt=1 -+ else -+ gcc_enable_stdlib_opt=1 -+ fi -+else -+ case $target in -+ *-darwin1[1-9]* | *-darwin2*) -+ # Default this on for Darwin versions which default to libcxx, -+ # and embed the path in the compiler install so that we get a -+ # self-contained toolchain. -+ gcc_enable_stdlib_opt=1 -+ ;; -+ *) ;; -+ esac -+fi - --$as_echo "#define ENABLE_STDLIB_OPTION 1" >>confdefs.h -+cat >>confdefs.h <<_ACEOF -+#define ENABLE_STDLIB_OPTION $gcc_enable_stdlib_opt -+_ACEOF - --else -- $as_echo "#define ENABLE_STDLIB_OPTION 0" >>confdefs.h - --fi --# ??? This logic must match libstdc++-v3/acinclude.m4:GLIBCXX_EXPORT_INSTALL_INFO. -+# Sysroot behaviour as for gxx-include-dir - if test x${gcc_gxx_libcxx_include_dir} = x; then -+ # default path,embedded in the compiler tree. -+ libcxx_incdir='include/c++/v1' - if test x${enable_version_specific_runtime_libs} = xyes; then -- gcc_gxx_libcxx_include_dir='${libsubdir}/libc++_include/c++/v1' -+ gcc_gxx_libcxx_include_dir='${libsubdir}/$libcxx_incdir' + # gcc_gxx_libcxx_include_dir as relative to the sysroot. +@@ -3780,16 +3793,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0 + gcc_enable_stdlib_opt=0 + if test x${gcc_gxx_libcxx_include_dir} != x; then + if test x${gcc_gxx_libcxx_include_dir} = xno; then +- # set defaults for the dir, but the option is disabled anyway. ++ # set defaults for the dir, but the option is disabled anyway. + gcc_gxx_libcxx_include_dir= ++ elif test x${gcc_gxx_libcxx_include_dir} = xyes; then ++ # set defaults for the dir, and enable. ++ gcc_gxx_libcxx_include_dir= ++ gcc_enable_stdlib_opt=1 else -- libcxx_incdir='libc++_include/c++/$(version)/v1' - if test x$host != x$target; then - libcxx_incdir="$target_alias/$libcxx_incdir" - fi -@@ -16295,7 +16332,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } + gcc_enable_stdlib_opt=1 + fi + else + case $target in + *-darwin1[1-9]* | *-darwin2*) +- # Default this on for Darwin versions which default to libcxx, +- # and embed the path in the compiler install so that we get a ++ # Default this on for Darwin versions which default to libcxx, ++ # and embed the path in the compiler install so that we get a + # self-contained toolchain. + gcc_enable_stdlib_opt=1 + ;; +@@ -16341,7 +16358,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -3553,7 +5424,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -18000,6 +18037,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -18046,6 +18063,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -3603,7 +5474,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -18017,9 +18097,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -18063,9 +18123,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -3619,25 +5490,25 @@ index c7b26d1927d..f4bd9c5d5f1 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -19825,7 +19909,7 @@ else +@@ -19871,7 +19935,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF --#line 19828 "configure" -+#line 19912 "configure" +-#line 19874 "configure" ++#line 19938 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -19931,7 +20015,7 @@ else +@@ -19977,7 +20041,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF --#line 19934 "configure" -+#line 20018 "configure" +-#line 19980 "configure" ++#line 20044 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -20807,6 +20891,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -20853,6 +20917,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -3687,7 +5558,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -20824,12 +20951,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -20870,12 +20977,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -3711,7 +5582,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -23200,6 +23335,35 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +@@ -23246,6 +23361,35 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu @@ -3747,7 +5618,69 @@ index c7b26d1927d..f4bd9c5d5f1 100755 # Identify the assembler which will work hand-in-glove with the newly # built GCC, so that we can examine its features. This is the assembler # which will be driven by the driver program. -@@ -32062,13 +32226,17 @@ fi +@@ -23522,6 +23666,14 @@ fi + $as_echo "$gold_non_default" >&6; } + + ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld ++if test x"$ld64_flag" = x"yes"; then ++ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld ++else ++ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld ++fi ++ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic ++ ++ + + case "$ORIGINAL_LD_FOR_TARGET" in + ./collect-ld | ./collect-ld$build_exeext) ;; +@@ -30638,6 +30790,7 @@ if test x"$ld64_flag" = x"yes"; then + # Set defaults for possibly untestable items. + gcc_cv_ld64_export_dynamic=0 + gcc_cv_ld64_platform_version=0 ++ gcc_cv_ld64_demangle=0 + + if test "$build" = "$host"; then + darwin_try_test=1 +@@ -30661,6 +30814,9 @@ $as_echo_n "checking ld64 specified version... " >&6; } + gcc_cv_ld64_major=`echo "$gcc_cv_ld64_version" | sed -e 's/\..*//'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_major" >&5 + $as_echo "$gcc_cv_ld64_major" >&6; } ++ if test "$gcc_cv_ld64_major" -ge 97; then ++ gcc_cv_ld64_demangle=1 ++ fi + if test "$gcc_cv_ld64_major" -ge 236; then + gcc_cv_ld64_export_dynamic=1 + fi +@@ -30678,6 +30834,15 @@ $as_echo_n "checking linker version... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_version" >&5 + $as_echo "$gcc_cv_ld64_version" >&6; } + ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -demangle support" >&5 ++$as_echo_n "checking linker for -demangle support... " >&6; } ++ gcc_cv_ld64_demangle=1 ++ if $gcc_cv_ld -demangle < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then ++ gcc_cv_ld64_demangle=0 ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_demangle" >&5 ++$as_echo "$gcc_cv_ld64_demangle" >&6; } ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -export_dynamic support" >&5 + $as_echo_n "checking linker for -export_dynamic support... " >&6; } + gcc_cv_ld64_export_dynamic=1 +@@ -30706,6 +30871,12 @@ _ACEOF + fi + + ++cat >>confdefs.h <<_ACEOF ++#define LD64_HAS_DEMANGLE $gcc_cv_ld64_demangle ++_ACEOF ++ ++ ++ + cat >>confdefs.h <<_ACEOF + #define LD64_HAS_EXPORT_DYNAMIC $gcc_cv_ld64_export_dynamic + _ACEOF +@@ -32251,13 +32422,17 @@ fi # Enable --enable-host-shared # Check whether --enable-host-shared was given. if test "${enable_host_shared+set}" = set; then : @@ -3768,7 +5701,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 # Check whether --enable-libquadmath-support was given. -@@ -32222,10 +32390,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +@@ -32411,10 +32586,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_c_no_fpie" >&5 $as_echo "$gcc_cv_c_no_fpie" >&6; } @@ -3779,7 +5712,7 @@ index c7b26d1927d..f4bd9c5d5f1 100755 # Check if -no-pie works. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -no-pie option" >&5 -@@ -32250,10 +32414,27 @@ rm -f core conftest.err conftest.$ac_objext \ +@@ -32439,11 +32610,28 @@ rm -f core conftest.err conftest.$ac_objext \ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_no_pie" >&5 $as_echo "$gcc_cv_no_pie" >&6; } @@ -3794,22 +5727,23 @@ index c7b26d1927d..f4bd9c5d5f1 100755 + PICFLAG=-fno-PIE +else + PICFLAG= - fi - ++fi ++ +if test x$enable_host_pie = xyes; then + LD_PICFLAG=-pie +elif test x$gcc_cv_no_pie = xyes; then + LD_PICFLAG=-no-pie +else + LD_PICFLAG= -+fi -+ + fi + + + + - # Enable Intel CET on Intel CET enabled host if jit is enabled. # Check whether --enable-cet was given. -@@ -32737,6 +32918,10 @@ LTLIBOBJS=$ac_ltlibobjs + if test "${enable_cet+set}" = set; then : +@@ -32926,6 +33114,10 @@ LTLIBOBJS=$ac_ltlibobjs @@ -3821,78 +5755,59 @@ index c7b26d1927d..f4bd9c5d5f1 100755 : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/gcc/configure.ac b/gcc/configure.ac -index 09082e8ccae..d181e41154c 100644 +index bf8ff4d..8c2ff47 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac -@@ -235,29 +235,54 @@ gcc_gxx_libcxx_include_dir= +@@ -235,18 +235,17 @@ gcc_gxx_libcxx_include_dir= AC_ARG_WITH(gxx-libcxx-include-dir, [AS_HELP_STRING([--with-gxx-libcxx-include-dir=DIR], [specifies directory to find libc++ header files])], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for libc++ include directory) ;; --no) ;; -*) gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;; -esac]) -- +[gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir]) -+ -+# --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option. -+# if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option. + + # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option. + # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option. +# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use +# the default path within the installation. -+# if --with-gxx-libcxx-include-dir is unset we enable the stdlib option + # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option +-# based on the platform (to be available on platform versions where it is the +# based on the platform (to be available on platform versions where it is the -+# default for the system tools). We also use a default path within the compiler + # default for the system tools). We also use a default path within the compiler +-# install tree. +-# Otherwise, we use the path provided and enable the stdlib option. +# install tree. +# Otherwise, we use the path provided and enable the stdlib option. # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we # check to see if the latter starts with the former and, upon success, compute # gcc_gxx_libcxx_include_dir as relative to the sysroot. - gcc_gxx_libcxx_include_dir_add_sysroot=0 -- -+gcc_enable_stdlib_opt=0 +@@ -254,16 +253,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0 + gcc_enable_stdlib_opt=0 if test x${gcc_gxx_libcxx_include_dir} != x; then -- AC_DEFINE(ENABLE_STDLIB_OPTION, 1, -- [Define if the -stdlib= option should be enabled.]) -+ if test x${gcc_gxx_libcxx_include_dir} = xno; then + if test x${gcc_gxx_libcxx_include_dir} = xno; then +- # set defaults for the dir, but the option is disabled anyway. + # set defaults for the dir, but the option is disabled anyway. + gcc_gxx_libcxx_include_dir= + elif test x${gcc_gxx_libcxx_include_dir} = xyes; then + # set defaults for the dir, and enable. -+ gcc_gxx_libcxx_include_dir= + gcc_gxx_libcxx_include_dir= + gcc_enable_stdlib_opt=1 -+ else -+ gcc_enable_stdlib_opt=1 -+ fi + else + gcc_enable_stdlib_opt=1 + fi else -- AC_DEFINE(ENABLE_STDLIB_OPTION, 0) -+ case $target in -+ *-darwin1[[1-9]]* | *-darwin2*) + case $target in + *-darwin1[[1-9]]* | *-darwin2*) +- # Default this on for Darwin versions which default to libcxx, +- # and embed the path in the compiler install so that we get a + # Default this on for Darwin versions which default to libcxx, + # and embed the path in the compiler install so that we get a -+ # self-contained toolchain. -+ gcc_enable_stdlib_opt=1 -+ ;; -+ *) ;; -+ esac - fi --# ??? This logic must match libstdc++-v3/acinclude.m4:GLIBCXX_EXPORT_INSTALL_INFO. -+AC_DEFINE_UNQUOTED(ENABLE_STDLIB_OPTION, $gcc_enable_stdlib_opt, -+ [Define if the -stdlib= option should be enabled.]) -+ -+# Sysroot behaviour as for gxx-include-dir - if test x${gcc_gxx_libcxx_include_dir} = x; then -+ # default path,embedded in the compiler tree. -+ libcxx_incdir='include/c++/v1' - if test x${enable_version_specific_runtime_libs} = xyes; then -- gcc_gxx_libcxx_include_dir='${libsubdir}/libc++_include/c++/v1' -+ gcc_gxx_libcxx_include_dir='${libsubdir}/$libcxx_incdir' - else -- libcxx_incdir='libc++_include/c++/$(version)/v1' - if test x$host != x$target; then - libcxx_incdir="$target_alias/$libcxx_incdir" - fi -@@ -2586,6 +2611,21 @@ AC_PROG_LIBTOOL + # self-contained toolchain. + gcc_enable_stdlib_opt=1 + ;; +@@ -2625,6 +2628,21 @@ AC_PROG_LIBTOOL AC_SUBST(objdir) AC_SUBST(enable_fast_install) @@ -3914,7 +5829,74 @@ index 09082e8ccae..d181e41154c 100644 # Identify the assembler which will work hand-in-glove with the newly # built GCC, so that we can examine its features. This is the assembler # which will be driven by the driver program. -@@ -7400,11 +7440,14 @@ fi +@@ -2797,7 +2815,15 @@ fi + AC_MSG_RESULT($gold_non_default) + + ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld ++if test x"$ld64_flag" = x"yes"; then ++ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld ++else ++ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld ++fi ++ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic + AC_SUBST(ORIGINAL_LD_FOR_TARGET) ++AC_SUBST(ORIGINAL_LLD_FOR_TARGET) ++AC_SUBST(ORIGINAL_CLASSIC_LD_FOR_TARGET) + case "$ORIGINAL_LD_FOR_TARGET" in + ./collect-ld | ./collect-ld$build_exeext) ;; + *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;; +@@ -4793,7 +4819,7 @@ foo: nop + gcc_cv_as_mllvm_x86_pad_for_align, + [-mllvm -x86-pad-for-align=false], [.text],, + [AC_DEFINE(HAVE_AS_MLLVM_X86_PAD_FOR_ALIGN, 1, +- [Define if your Mac OS X assembler supports -mllvm -x86-pad-for-align=false.])]) ++ [Define if your macOS assembler supports -mllvm -x86-pad-for-align=false.])]) + ;; + esac + +@@ -6273,6 +6299,7 @@ if test x"$ld64_flag" = x"yes"; then + # Set defaults for possibly untestable items. + gcc_cv_ld64_export_dynamic=0 + gcc_cv_ld64_platform_version=0 ++ gcc_cv_ld64_demangle=0 + + if test "$build" = "$host"; then + darwin_try_test=1 +@@ -6294,6 +6321,9 @@ if test x"$ld64_flag" = x"yes"; then + AC_MSG_CHECKING(ld64 specified version) + gcc_cv_ld64_major=`echo "$gcc_cv_ld64_version" | sed -e 's/\..*//'` + AC_MSG_RESULT($gcc_cv_ld64_major) ++ if test "$gcc_cv_ld64_major" -ge 97; then ++ gcc_cv_ld64_demangle=1 ++ fi + if test "$gcc_cv_ld64_major" -ge 236; then + gcc_cv_ld64_export_dynamic=1 + fi +@@ -6309,6 +6339,13 @@ if test x"$ld64_flag" = x"yes"; then + fi + AC_MSG_RESULT($gcc_cv_ld64_version) + ++ AC_MSG_CHECKING(linker for -demangle support) ++ gcc_cv_ld64_demangle=1 ++ if $gcc_cv_ld -demangle < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then ++ gcc_cv_ld64_demangle=0 ++ fi ++ AC_MSG_RESULT($gcc_cv_ld64_demangle) ++ + AC_MSG_CHECKING(linker for -export_dynamic support) + gcc_cv_ld64_export_dynamic=1 + if $gcc_cv_ld -export_dynamic < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then +@@ -6329,6 +6366,9 @@ if test x"$ld64_flag" = x"yes"; then + [Define to ld64 version.]) + fi + ++ AC_DEFINE_UNQUOTED(LD64_HAS_DEMANGLE, $gcc_cv_ld64_demangle, ++ [Define to 1 if ld64 supports '-demangle'.]) ++ + AC_DEFINE_UNQUOTED(LD64_HAS_EXPORT_DYNAMIC, $gcc_cv_ld64_export_dynamic, + [Define to 1 if ld64 supports '-export_dynamic'.]) + +@@ -7479,11 +7519,14 @@ fi # Enable --enable-host-shared AC_ARG_ENABLE(host-shared, [AS_HELP_STRING([--enable-host-shared], @@ -3932,7 +5914,7 @@ index 09082e8ccae..d181e41154c 100644 AC_ARG_ENABLE(libquadmath-support, [AS_HELP_STRING([--disable-libquadmath-support], -@@ -7526,10 +7569,6 @@ AC_CACHE_CHECK([for -fno-PIE option], +@@ -7605,10 +7648,6 @@ AC_CACHE_CHECK([for -fno-PIE option], [gcc_cv_c_no_fpie=yes], [gcc_cv_c_no_fpie=no]) CXXFLAGS="$saved_CXXFLAGS"]) @@ -3943,7 +5925,7 @@ index 09082e8ccae..d181e41154c 100644 # Check if -no-pie works. AC_CACHE_CHECK([for -no-pie option], -@@ -7540,10 +7579,27 @@ AC_CACHE_CHECK([for -no-pie option], +@@ -7619,10 +7658,27 @@ AC_CACHE_CHECK([for -no-pie option], [gcc_cv_no_pie=yes], [gcc_cv_no_pie=no]) LDFLAGS="$saved_LDFLAGS"]) @@ -3974,11 +5956,218 @@ index 09082e8ccae..d181e41154c 100644 # Enable Intel CET on Intel CET enabled host if jit is enabled. GCC_CET_HOST_FLAGS(CET_HOST_FLAGS) +diff --git a/gcc/coretypes.h b/gcc/coretypes.h +index ca8837c..7e022a4 100644 +--- a/gcc/coretypes.h ++++ b/gcc/coretypes.h +@@ -199,6 +199,12 @@ enum tls_model { + TLS_MODEL_LOCAL_EXEC + }; + ++/* Types of trampoline implementation. */ ++enum trampoline_impl { ++ TRAMPOLINE_IMPL_STACK, ++ TRAMPOLINE_IMPL_HEAP ++}; ++ + /* Types of ABI for an offload compiler. */ + enum offload_abi { + OFFLOAD_ABI_UNSET, +diff --git a/gcc/cp/cp-lang.cc b/gcc/cp/cp-lang.cc +index 2f54146..84200a9 100644 +--- a/gcc/cp/cp-lang.cc ++++ b/gcc/cp/cp-lang.cc +@@ -121,6 +121,15 @@ objcp_tsubst_copy_and_build (tree /*t*/, + return NULL_TREE; + } + ++/* Implement c-family hook to add language-specific features ++ for __has_{feature,extension}. */ ++ ++void ++c_family_register_lang_features () ++{ ++ cp_register_features (); ++} ++ + static const char * + cxx_dwarf_name (tree t, int verbosity) + { +diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc +index 93b027b..10b9b35 100644 +--- a/gcc/cp/cp-objcp-common.cc ++++ b/gcc/cp/cp-objcp-common.cc +@@ -23,10 +23,153 @@ along with GCC; see the file COPYING3. If not see + #include "coretypes.h" + #include "cp-tree.h" + #include "cp-objcp-common.h" ++#include "c-family/c-common.h" + #include "dwarf2.h" + #include "stringpool.h" + #include "contracts.h" + ++/* Class to determine whether a given C++ language feature is available. ++ Used to implement __has_{feature,extension}. */ ++ ++struct cp_feature_selector ++{ ++ enum ++ { ++ DIALECT, ++ FLAG ++ } kind; ++ ++ enum class result ++ { ++ NONE, ++ EXT, ++ FEAT ++ }; ++ ++ union ++ { ++ const int *enable_flag; ++ struct { ++ enum cxx_dialect feat; ++ enum cxx_dialect ext; ++ } dialect; ++ }; ++ ++ constexpr cp_feature_selector (const int *flag) ++ : kind (FLAG), enable_flag (flag) {} ++ constexpr cp_feature_selector (enum cxx_dialect feat, ++ enum cxx_dialect ext) ++ : kind (DIALECT), dialect{feat, ext} {} ++ constexpr cp_feature_selector (enum cxx_dialect feat) ++ : cp_feature_selector (feat, feat) {} ++ ++ inline result has_feature () const; ++}; ++ ++/* Check whether this language feature is available as a feature, ++ extension, or not at all. */ ++ ++cp_feature_selector::result ++cp_feature_selector::has_feature () const ++{ ++ switch (kind) ++ { ++ case DIALECT: ++ if (cxx_dialect >= dialect.feat) ++ return result::FEAT; ++ else if (cxx_dialect >= dialect.ext) ++ return result::EXT; ++ else ++ return result::NONE; ++ case FLAG: ++ return *enable_flag ? result::FEAT : result::NONE; ++ } ++ ++ gcc_unreachable (); ++} ++ ++/* Information about a C++ language feature which can be queried ++ through __has_{feature,extension}. IDENT is the name of the feature, ++ and SELECTOR encodes how to compute whether the feature is available. */ ++ ++struct cp_feature_info ++{ ++ const char *ident; ++ cp_feature_selector selector; ++}; ++ ++/* Table of features for __has_{feature,extension}. */ ++ ++static constexpr cp_feature_info cp_feature_table[] = ++{ ++ { "cxx_exceptions", &flag_exceptions }, ++ { "cxx_rtti", &flag_rtti }, ++ { "cxx_access_control_sfinae", { cxx11, cxx98 } }, ++ { "cxx_alias_templates", cxx11 }, ++ { "cxx_alignas", cxx11 }, ++ { "cxx_alignof", cxx11 }, ++ { "cxx_attributes", cxx11 }, ++ { "cxx_constexpr", cxx11 }, ++ { "cxx_decltype", cxx11 }, ++ { "cxx_decltype_incomplete_return_types", cxx11 }, ++ { "cxx_default_function_template_args", cxx11 }, ++ { "cxx_defaulted_functions", cxx11 }, ++ { "cxx_delegating_constructors", cxx11 }, ++ { "cxx_deleted_functions", cxx11 }, ++ { "cxx_explicit_conversions", cxx11 }, ++ { "cxx_generalized_initializers", cxx11 }, ++ { "cxx_implicit_moves", cxx11 }, ++ { "cxx_inheriting_constructors", cxx11 }, ++ { "cxx_inline_namespaces", { cxx11, cxx98 } }, ++ { "cxx_lambdas", cxx11 }, ++ { "cxx_local_type_template_args", cxx11 }, ++ { "cxx_noexcept", cxx11 }, ++ { "cxx_nonstatic_member_init", cxx11 }, ++ { "cxx_nullptr", cxx11 }, ++ { "cxx_override_control", cxx11 }, ++ { "cxx_reference_qualified_functions", cxx11 }, ++ { "cxx_range_for", cxx11 }, ++ { "cxx_raw_string_literals", cxx11 }, ++ { "cxx_rvalue_references", cxx11 }, ++ { "cxx_static_assert", cxx11 }, ++ { "cxx_thread_local", cxx11 }, ++ { "cxx_auto_type", cxx11 }, ++ { "cxx_strong_enums", cxx11 }, ++ { "cxx_trailing_return", cxx11 }, ++ { "cxx_unicode_literals", cxx11 }, ++ { "cxx_unrestricted_unions", cxx11 }, ++ { "cxx_user_literals", cxx11 }, ++ { "cxx_variadic_templates", { cxx11, cxx98 } }, ++ { "cxx_binary_literals", { cxx14, cxx98 } }, ++ { "cxx_contextual_conversions", { cxx14, cxx98 } }, ++ { "cxx_decltype_auto", cxx14 }, ++ { "cxx_aggregate_nsdmi", cxx14 }, ++ { "cxx_init_captures", { cxx14, cxx11 } }, ++ { "cxx_generic_lambdas", cxx14 }, ++ { "cxx_relaxed_constexpr", cxx14 }, ++ { "cxx_return_type_deduction", cxx14 }, ++ { "cxx_variable_templates", cxx14 }, ++ { "modules", &flag_modules }, ++}; ++ ++/* Register C++ language features for __has_{feature,extension}. */ ++ ++void ++cp_register_features () ++{ ++ using result = cp_feature_selector::result; ++ ++ for (unsigned i = 0; i < ARRAY_SIZE (cp_feature_table); i++) ++ { ++ const cp_feature_info *info = cp_feature_table + i; ++ const auto res = info->selector.has_feature (); ++ if (res == result::NONE) ++ continue; ++ ++ c_common_register_feature (info->ident, res == result::FEAT); ++ } ++} ++ + /* Special routine to get the alias set for C++. */ + + alias_set_type +diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h +index 80893aa..9d4d873 100644 +--- a/gcc/cp/cp-objcp-common.h ++++ b/gcc/cp/cp-objcp-common.h +@@ -34,6 +34,7 @@ extern tree cp_classtype_as_base (const_tree); + extern tree cp_get_global_decls (); + extern tree cp_pushdecl (tree); + extern void cp_register_dumps (gcc::dump_manager *); ++extern void cp_register_features (); + extern bool cp_handle_option (size_t, const char *, HOST_WIDE_INT, int, + location_t, const struct cl_option_handlers *); + extern tree cxx_make_type_hook (tree_code); diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc -index 1dd3c2b13bc..3d75d0099ed 100644 +index 36e1f2c..213e52c 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc -@@ -3703,9 +3703,8 @@ get_tls_init_fn (tree var) +@@ -3712,9 +3712,8 @@ get_tls_init_fn (tree var) if (!flag_extern_tls_init && DECL_EXTERNAL (var)) return NULL_TREE; @@ -3990,7 +6179,7 @@ index 1dd3c2b13bc..3d75d0099ed 100644 return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var)); tree sname = mangle_tls_init_fn (var); -@@ -3868,6 +3867,25 @@ generate_tls_wrapper (tree fn) +@@ -3877,6 +3876,25 @@ generate_tls_wrapper (tree fn) expand_or_defer_fn (finish_function (/*inline_p=*/false)); } @@ -4016,7 +6205,7 @@ index 1dd3c2b13bc..3d75d0099ed 100644 /* Start a global constructor or destructor function. */ static tree -@@ -4657,22 +4675,24 @@ handle_tls_init (void) +@@ -4666,22 +4684,24 @@ handle_tls_init (void) finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR, boolean_true_node, tf_warning_or_error)); @@ -4048,7 +6237,7 @@ index 1dd3c2b13bc..3d75d0099ed 100644 } } -@@ -4680,6 +4700,30 @@ handle_tls_init (void) +@@ -4689,6 +4709,30 @@ handle_tls_init (void) finish_if_stmt (if_stmt); finish_function_body (body); expand_or_defer_fn (finish_function (/*inline_p=*/false)); @@ -4079,7 +6268,7 @@ index 1dd3c2b13bc..3d75d0099ed 100644 } /* We're at the end of compilation, so generate any mangling aliases that -@@ -5098,7 +5142,14 @@ c_parse_final_cleanups (void) +@@ -5107,7 +5151,14 @@ c_parse_final_cleanups (void) } if (!DECL_INITIAL (decl) && decl_tls_wrapper_p (decl)) @@ -4095,9 +6284,293 @@ index 1dd3c2b13bc..3d75d0099ed 100644 if (!DECL_SAVED_TREE (decl)) continue; -diff --git a/gcc/cumulative-args.h b/gcc/cumulative-args.h +diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc +index 4e67da6..1f1b762 100644 +--- a/gcc/cp/parser.cc ++++ b/gcc/cp/parser.cc +@@ -694,6 +694,91 @@ cp_lexer_handle_early_pragma (cp_lexer *lexer) + static cp_parser *cp_parser_new (cp_lexer *); + static GTY (()) cp_parser *the_parser; + ++/* Context-sensitive parse-checking for clang-style attributes. */ ++ ++enum clang_attr_state { ++ CA_NONE = 0, ++ CA_ATTR, ++ CA_BR1, CA_BR2, ++ CA_LIST, ++ CA_LIST_ARGS, ++ CA_IS_CA, ++ CA_CA_ARGS, ++ CA_LIST_CONT ++}; ++ ++/* State machine tracking context of attribute lexing. */ ++ ++static enum clang_attr_state ++cp_lexer_attribute_state (cp_token& token, enum clang_attr_state attr_state) ++{ ++ /* Implement a context-sensitive parser for clang attributes. ++ We detect __attribute__((clang_style_attribute (ARGS))) and lex the ++ args ARGS with the following differences from GNU attributes: ++ (a) number-like values are lexed as strings [this allows lexing XX.YY.ZZ ++ version numbers]. ++ (b) we concatenate strings, since clang attributes allow this too. */ ++ switch (attr_state) ++ { ++ case CA_NONE: ++ if (token.type == CPP_KEYWORD ++ && token.keyword == RID_ATTRIBUTE) ++ attr_state = CA_ATTR; ++ break; ++ case CA_ATTR: ++ if (token.type == CPP_OPEN_PAREN) ++ attr_state = CA_BR1; ++ else ++ attr_state = CA_NONE; ++ break; ++ case CA_BR1: ++ if (token.type == CPP_OPEN_PAREN) ++ attr_state = CA_BR2; ++ else ++ attr_state = CA_NONE; ++ break; ++ case CA_BR2: ++ if (token.type == CPP_NAME) ++ { ++ tree identifier = (token.type == CPP_KEYWORD) ++ /* For keywords, use the canonical spelling, not the ++ parsed identifier. */ ++ ? ridpointers[(int) token.keyword] ++ : token.u.value; ++ identifier = canonicalize_attr_name (identifier); ++ if (attribute_clang_form_p (identifier)) ++ attr_state = CA_IS_CA; ++ else ++ attr_state = CA_LIST; ++ } ++ else ++ attr_state = CA_NONE; ++ break; ++ case CA_IS_CA: ++ case CA_LIST: ++ if (token.type == CPP_COMMA) ++ attr_state = CA_BR2; /* Back to the list outer. */ ++ else if (token.type == CPP_OPEN_PAREN) ++ attr_state = attr_state == CA_IS_CA ? CA_CA_ARGS ++ : CA_LIST_ARGS; ++ else ++ attr_state = CA_NONE; ++ break; ++ case CA_CA_ARGS: /* We will special-case args in this state. */ ++ case CA_LIST_ARGS: ++ if (token.type == CPP_CLOSE_PAREN) ++ attr_state = CA_LIST_CONT; ++ break; ++ case CA_LIST_CONT: ++ if (token.type == CPP_COMMA) ++ attr_state = CA_BR2; /* Back to the list outer. */ ++ else ++ attr_state = CA_NONE; ++ break; ++ } ++ return attr_state; ++} ++ + /* Create a new main C++ lexer, the lexer that gets tokens from the + preprocessor, and also create the main parser. */ + +@@ -710,6 +795,8 @@ cp_lexer_new_main (void) + c_common_no_more_pch (); + + cp_lexer *lexer = cp_lexer_alloc (); ++ enum clang_attr_state attr_state = CA_NONE; ++ + /* Put the first token in the buffer. */ + cp_token *tok = lexer->buffer->quick_push (token); + +@@ -733,8 +820,14 @@ cp_lexer_new_main (void) + if (tok->type == CPP_PRAGMA_EOL) + cp_lexer_handle_early_pragma (lexer); + ++ attr_state = cp_lexer_attribute_state (*tok, attr_state); + tok = vec_safe_push (lexer->buffer, cp_token ()); +- cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok); ++ unsigned int flags = C_LEX_STRING_NO_JOIN; ++ /* If we are processing clang-style attribute args, lex numbers as ++ potential version strings; NN .. NN.MM .. NN.MM.OO */ ++ if (attr_state == CA_CA_ARGS) ++ flags |= C_LEX_NUMBER_AS_STRING; ++ cp_lexer_get_preprocessor_token (flags, tok); + } + + lexer->next_token = lexer->buffer->address (); +@@ -936,7 +1029,7 @@ cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token) + { + static int is_extern_c = 0; + +- /* Get a new token from the preprocessor. */ ++ /* Get a new token from the preprocessor. */ + token->type + = c_lex_with_flags (&token->u.value, &token->location, &token->flags, + flags); +@@ -20992,11 +21085,13 @@ cp_parser_enum_specifier (cp_parser* parser) + + /* Check for the `:' that denotes a specified underlying type in C++0x. + Note that a ':' could also indicate a bitfield width, however. */ ++ location_t colon_loc = UNKNOWN_LOCATION; + if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + { + cp_decl_specifier_seq type_specifiers; + + /* Consume the `:'. */ ++ colon_loc = cp_lexer_peek_token (parser->lexer)->location; + cp_lexer_consume_token (parser->lexer); + + auto tdf +@@ -21045,10 +21140,13 @@ cp_parser_enum_specifier (cp_parser* parser) + && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) + { + if (has_underlying_type) +- cp_parser_commit_to_tentative_parse (parser); +- cp_parser_error (parser, "expected %<;%> or %<{%>"); +- if (has_underlying_type) +- return error_mark_node; ++ pedwarn (colon_loc, ++ OPT_Welaborated_enum_base, ++ "declaration of enumeration with " ++ "fixed underlying type and no enumerator list is " ++ "only permitted as a standalone declaration"); ++ else ++ cp_parser_error (parser, "expected %<;%> or %<{%>"); + } + } + +@@ -29051,6 +29149,91 @@ cp_parser_gnu_attributes_opt (cp_parser* parser) + return attributes; + } + ++/* Parse the arguments list for a clang attribute. */ ++static tree ++cp_parser_clang_attribute (cp_parser *parser, tree/*attr_id*/) ++{ ++ /* Each entry can be : ++ identifier ++ identifier=N.MM.Z ++ identifier="string" ++ followed by ',' or ) for the last entry*/ ++ ++ matching_parens parens; ++ if (!parens.require_open (parser)) ++ return NULL; ++ ++ bool save_translate_strings_p = parser->translate_strings_p; ++ parser->translate_strings_p = false; ++ tree attr_args = NULL_TREE; ++ cp_token *token; ++ do ++ { ++ tree name = NULL_TREE; ++ tree value = NULL_TREE; ++ ++ token = cp_lexer_peek_token (parser->lexer); ++ if (token->type == CPP_NAME) ++ name = token->u.value; ++ else if (token->type == CPP_KEYWORD) ++ name = ridpointers[(int) token->keyword]; ++ else if (token->flags & NAMED_OP) ++ name = get_identifier (cpp_type2name (token->type, token->flags)); ++ else ++ { ++ /* FIXME: context-sensitive for that attrib. */ ++ error_at (token->location, "expected an attribute keyword"); ++ cp_parser_skip_to_closing_parenthesis (parser, ++ /*recovering=*/true, ++ /*or_comma=*/false, ++ /*consume_paren=*/false); ++ attr_args = error_mark_node; ++ break; ++ } ++ cp_lexer_consume_token (parser->lexer); ++ ++ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) ++ { ++ cp_lexer_consume_token (parser->lexer); /* eat the '=' */ ++ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN) ++ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) ++ { ++ token = cp_lexer_peek_token (parser->lexer); ++ if (token->type == CPP_STRING) ++ value = cp_parser_string_literal (parser, /*translate=*/false, ++ /*wide_ok=*/false); ++ else ++ { ++ value = token->u.value; ++ cp_lexer_consume_token (parser->lexer); ++ } ++ } ++ /* else value is missing. */ ++ } ++ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN) ++ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) ++ { ++ error_at (token->location, "expected %<,%>, %<=%> or %<)%>"); ++ cp_parser_skip_to_closing_parenthesis (parser, ++ /*recovering=*/true, ++ /*or_comma=*/false, ++ /*consume_paren=*/false); ++ attr_args = error_mark_node; ++ break; ++ } ++ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) ++ cp_lexer_consume_token (parser->lexer); ++ tree t = tree_cons (value, name, NULL_TREE); ++ attr_args = chainon (attr_args, t); ++ } while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)); ++ ++ parser->translate_strings_p = save_translate_strings_p; ++ if (!parens.require_close (parser)) ++ return error_mark_node; ++ ++ return attr_args; ++} ++ + /* Parse a GNU attribute-list. + + attribute-list: +@@ -29110,9 +29293,12 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */) + + /* Peek at the next token. */ + token = cp_lexer_peek_token (parser->lexer); +- /* If it's an `(', then parse the attribute arguments. */ +- if (token->type == CPP_OPEN_PAREN) ++ if (token->type == CPP_OPEN_PAREN ++ && attribute_clang_form_p (identifier)) ++ arguments = cp_parser_clang_attribute (parser, identifier); ++ else if (token->type == CPP_OPEN_PAREN) + { ++ /* If it's an `(', then parse the attribute arguments. */ + vec *vec; + int attr_flag = (attribute_takes_identifier_p (identifier) + ? id_attr : normal_attr); +@@ -29129,12 +29315,12 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */) + arguments = build_tree_list_vec (vec); + release_tree_vector (vec); + } +- /* Save the arguments away. */ +- TREE_VALUE (attribute) = arguments; + } + + if (arguments != error_mark_node) + { ++ /* Save the arguments away. */ ++ TREE_VALUE (attribute) = arguments; + /* Add this attribute to the list. */ + TREE_CHAIN (attribute) = attribute_list; + attribute_list = attribute; +diff --git b/gcc/cumulative-args.h b/gcc/cumulative-args.h new file mode 100644 -index 00000000000..b60928e37f9 +index 0000000..b60928e --- /dev/null +++ b/gcc/cumulative-args.h @@ -0,0 +1,20 @@ @@ -4122,7 +6595,7 @@ index 00000000000..b60928e37f9 + +#endif /* GCC_CUMULATIVE_ARGS_H */ diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in -index 1679fb81097..4fbf2096416 100644 +index 1679fb8..4fbf209 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -64,7 +64,7 @@ ALL_DFLAGS = $(DFLAGS-$@) $(GDCFLAGS) -fversion=IN_GCC $(CHECKING_DFLAGS) \ @@ -4134,8 +6607,102 @@ index 1679fb81097..4fbf2096416 100644 DCOMPILE = $(DCOMPILE.base) -MT $@ -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).TPo DPOSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(*F).TPo $(@D)/$(DEPDIR)/$(*F).Po DLINKER = $(GDC) $(NO_PIE_FLAG) -lstdc++ +diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi +index 758805d..f8f002c 100644 +--- a/gcc/doc/contrib.texi ++++ b/gcc/doc/contrib.texi +@@ -1515,7 +1515,7 @@ Gael Thomas for @code{VMClassLoader} boot packages support suggestions. + + @item + Andreas Tobler for Darwin and Solaris testing and fixing, @code{Qt4} +-support for Darwin/OS X, @code{Graphics2D} support, @code{gtk+} ++support for Darwin / macOS, @code{Graphics2D} support, @code{gtk+} + updates. + + @item +diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi +index b0a2ce3..f57278d 100644 +--- a/gcc/doc/cpp.texi ++++ b/gcc/doc/cpp.texi +@@ -3198,6 +3198,8 @@ directive}: @samp{#if}, @samp{#ifdef} or @samp{#ifndef}. + * @code{__has_cpp_attribute}:: + * @code{__has_c_attribute}:: + * @code{__has_builtin}:: ++* @code{__has_feature}:: ++* @code{__has_extension}:: + * @code{__has_include}:: + @end menu + +@@ -3560,6 +3562,45 @@ the operator is as follows: + #endif + @end smallexample + ++@node @code{__has_feature} ++@subsection @code{__has_feature} ++@cindex @code{__has_feature} ++ ++The special operator @code{__has_feature (@var{operand})} may be used in ++constant integer contexts and in preprocessor @samp{#if} and @samp{#elif} ++expressions to test whether the identifier given in @var{operand} is recognized ++as a feature supported by GCC given the current options and, in the case of ++standard language features, whether the feature is available in the chosen ++version of the language standard. ++ ++Note that @code{__has_feature} and @code{__has_extension} are not recommended ++for use in new code, and are only provided for compatibility with Clang. For ++details of which identifiers are accepted by these function-like macros, see ++@w{@uref{https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension, ++the Clang documentation}}. ++ ++@node @code{__has_extension} ++@subsection @code{__has_extension} ++@cindex @code{__has_extension} ++ ++The special operator @code{__has_extension (@var{operand})} may be used in ++constant integer contexts and in preprocessor @samp{#if} and @samp{#elif} ++expressions to test whether the identifier given in @var{operand} is recognized ++as an extension supported by GCC given the current options. In any given ++context, the features accepted by @code{__has_extension} are a strict superset ++of those accepted by @code{__has_feature}. Unlike @code{__has_feature}, ++@code{__has_extension} tests whether a given feature is available regardless of ++strict language standards conformance. ++ ++If the @option{-pedantic-errors} flag is given, @code{__has_extension} is ++equivalent to @code{__has_feature}. ++ ++Note that @code{__has_feature} and @code{__has_extension} are not recommended ++for use in new code, and are only provided for compatibility with Clang. For ++details of which identifiers are accepted by these function-like macros, see ++@w{@uref{https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension, ++the Clang documentation}}. ++ + @node @code{__has_include} + @subsection @code{__has_include} + @cindex @code{__has_include} +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index d6fcd61..a163750 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -23797,7 +23797,7 @@ attribute, do change the value of preprocessor macros like + + The following pragmas are available for all architectures running the + Darwin operating system. These are useful for compatibility with other +-Mac OS compilers. ++macOS compilers. + + @table @code + @cindex pragma, mark +@@ -24976,7 +24976,7 @@ compiled separately. + @end table + + G++ implements the Borland model on targets where the linker supports it, +-including ELF targets (such as GNU/Linux), Mac OS X and Microsoft Windows. ++including ELF targets (such as GNU/Linux), macOS and Microsoft Windows. + Otherwise G++ implements neither automatic model. + + You have the following options for dealing with template instantiations: diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi -index b30d3691fe6..93d5236f7b3 100644 +index b30d369..de05d1c 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1075,14 +1075,26 @@ code. @@ -4167,21 +6734,155 @@ index b30d3691fe6..93d5236f7b3 100644 @item @anchor{with-gnu-as}--with-gnu-as Specify that the compiler should assume that the assembler it finds is the GNU assembler. However, this does not modify +@@ -1790,6 +1802,12 @@ particularly useful if you intend to use several versions of GCC in + parallel. The default is @samp{yes} for @samp{libada}, and @samp{no} for + the remaining libraries. + ++@item --with-darwin-extra-rpath ++This is provided to allow distributions to add a single additional ++runpath on Darwin / macOS systems. This allows for cases where the ++installed GCC library directories are then symlinked to a common ++directory outside of the GCC installation. ++ + @item @anchor{WithAixSoname}--with-aix-soname=@samp{aix}, @samp{svr4} or @samp{both} + Traditional AIX shared library versioning (versioned @code{Shared Object} + files as members of unversioned @code{Archive Library} files named diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi -index de40f62e219..f735557aed0 100644 +index 792ce28..cedffc5 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi -@@ -707,7 +707,8 @@ Objective-C and Objective-C++ Dialects}. +@@ -254,7 +254,8 @@ in the following sections. + -Wdelete-non-virtual-dtor -Wno-deprecated-array-compare + -Wdeprecated-copy -Wdeprecated-copy-dtor + -Wno-deprecated-enum-enum-conversion -Wno-deprecated-enum-float-conversion +--Weffc++ -Wno-exceptions -Wextra-semi -Wno-inaccessible-base ++-Weffc++ -Wno-elaborated-enum-base ++-Wno-exceptions -Wextra-semi -Wno-inaccessible-base + -Wno-inherited-variadic-ctor -Wno-init-list-lifetime + -Winvalid-constexpr -Winvalid-imported-macros + -Wno-invalid-offsetof -Wno-literal-suffix +@@ -706,8 +707,9 @@ Objective-C and Objective-C++ Dialects}. + -freg-struct-return -fshort-enums -fshort-wchar -fverbose-asm -fpack-struct[=@var{n}] -fleading-underscore -ftls-model=@var{model} - -fstack-reuse=@var{reuse_level} +--fstack-reuse=@var{reuse_level} --ftrampolines -ftrapv -fwrapv -+-fstack-use-cumulative-args -+-ftrampolines -foff-stack-trampolines -ftrapv -fwrapv ++-fstack-reuse=@var{reuse_level} -fstack-use-cumulative-args ++-ftrampolines -ftrampoline-impl=@r{[}stack@r{|}heap@r{]} ++-ftrapv -fwrapv -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]} -fstrict-volatile-bitfields -fsync-libcalls} -@@ -18160,6 +18161,17 @@ the behavior of older compilers in which temporaries' stack space is +@@ -914,7 +916,7 @@ Objective-C and Objective-C++ Dialects}. + -iframework + -image_base -init -install_name -keep_private_externs + -multi_module -multiply_defined -multiply_defined_unused +--noall_load -no_dead_strip_inits_and_terms ++-noall_load -no_dead_strip_inits_and_terms -nodefaultrpaths + -nofixprebinding -nomultidefs -noprebind -noseglinkedit + -pagezero_size -prebind -prebind_all_twolevel_modules + -private_bundle -read_only_relocs -sectalign +@@ -927,7 +929,7 @@ Objective-C and Objective-C++ Dialects}. + -twolevel_namespace -umbrella -undefined + -unexported_symbols_list -weak_reference_mismatches + -whatsloaded -F -gused -gfull -mmacosx-version-min=@var{version} +--mkernel -mone-byte-bool} ++-mkernel -mone-byte-bool -munreachable-traps} + + @emph{DEC Alpha Options} + @gccoptlist{-mno-fp-regs -msoft-float +@@ -3839,6 +3841,15 @@ bool b = e <= 3.7; + @option{-std=c++20}. In pre-C++20 dialects, this warning can be enabled + by @option{-Wenum-conversion}. + ++@opindex Welaborated-enum-base ++@opindex Wno-elaborated-enum-base ++@item -Wno-elaborated-enum-base ++For C++11 and above, warn if an (invalid) additional enum-base is used ++in an elaborated-type-specifier. That is, if an enum with given ++underlying type and no enumerator list is used in a declaration other ++than just a standalone declaration of the enum. Enabled by default. This ++warning is upgraded to an error with -pedantic-errors. ++ + @opindex Winit-list-lifetime + @opindex Wno-init-list-lifetime + @item -Wno-init-list-lifetime @r{(C++ and Objective-C++ only)} +@@ -4802,7 +4813,7 @@ Use @var{class-name} as the name of the class to instantiate for each + literal string specified with the syntax @code{@@"@dots{}"}. The default + class name is @code{NXConstantString} if the GNU runtime is being used, and + @code{NSConstantString} if the NeXT runtime is being used (see below). On +-Darwin (macOS, MacOS X) platforms, the @option{-fconstant-cfstrings} option, if ++Darwin / macOS platforms, the @option{-fconstant-cfstrings} option, if + also present, overrides the @option{-fconstant-string-class} setting and cause + @code{@@"@dots{}"} literals to be laid out as constant CoreFoundation strings. + Note that @option{-fconstant-cfstrings} is an alias for the target-specific +@@ -4816,7 +4827,7 @@ runtime. This is the default for most types of systems. + @opindex fnext-runtime + @item -fnext-runtime + Generate output compatible with the NeXT runtime. This is the default +-for NeXT-based systems, including Darwin and Mac OS X@. The macro ++for NeXT-based systems, including Darwin / macOS. The macro + @code{__NEXT_RUNTIME__} is predefined if (and only if) this option is + used. + +@@ -6031,8 +6042,45 @@ Give an error whenever the @dfn{base standard} (see @option{-Wpedantic}) + requires a diagnostic, in some cases where there is undefined behavior + at compile-time and in some other cases that do not prevent compilation + of programs that are valid according to the standard. This is not +-equivalent to @option{-Werror=pedantic}, since there are errors enabled +-by this option and not enabled by the latter and vice versa. ++equivalent to @option{-Werror=pedantic}: the latter option is unlikely to be ++useful, as it only makes errors of the diagnostics that are controlled by ++@option{-Wpedantic}, whereas this option also affects required diagnostics that ++are always enabled or controlled by options other than @option{-Wpedantic}. ++ ++If you want the required diagnostics that are warnings by default to ++be errors instead, but don't also want to enable the @option{-Wpedantic} ++diagnostics, you can specify @option{-pedantic-errors -Wno-pedantic} ++(or @option{-pedantic-errors -Wno-error=pedantic} to enable them but ++only as warnings). ++ ++Some required diagnostics are errors by default, but can be reduced to ++warnings using @option{-fpermissive} or their specific warning option, ++e.g. @option{-Wno-error=narrowing}. ++ ++Some diagnostics for non-ISO practices are controlled by specific ++warning options other than @option{-Wpedantic}, but are also made ++errors by @option{-pedantic-errors}. For instance: ++ ++@gccoptlist{ ++-Wattributes @r{(for standard attributes)} ++-Wchanges-meaning @r{(C++)} ++-Wcomma-subscript @r{(C++23 or later)} ++-Wdeclaration-after-statement @r{(C90 or earlier)} ++-Welaborated-enum-base @r{(C++11 or later)} ++-Wimplicit-int @r{(C99 or later)} ++-Wimplicit-function-declaration @r{(C99 or later)} ++-Wincompatible-pointer-types ++-Wint-conversion ++-Wlong-long @r{(C90 or earlier)} ++-Wmain ++-Wnarrowing @r{(C++11 or later)} ++-Wpointer-arith ++-Wpointer-sign ++-Wincompatible-pointer-types ++-Wregister @r{(C++17 or later)} ++-Wvla @r{(C90 or earlier)} ++-Wwrite-strings @r{(C++11 or later)} ++} + + @opindex Wall + @opindex Wno-all +@@ -11285,7 +11333,7 @@ possible. + Produce debugging information in DWARF format (if that is supported). + The value of @var{version} may be either 2, 3, 4 or 5; the default + version for most targets is 5 (with the exception of VxWorks, TPF and +-Darwin/Mac OS X, which default to version 2, and AIX, which defaults ++Darwin / macOS, which default to version 2, and AIX, which defaults + to version 4). + + Note that with DWARF Version 2, some ports require and always +@@ -18167,6 +18215,17 @@ the behavior of older compilers in which temporaries' stack space is not reused, the aggressive stack reuse can lead to runtime errors. This option is used to control the temporary stack reuse optimization. @@ -4199,31 +6900,92 @@ index de40f62e219..f735557aed0 100644 @opindex ftrapv @item -ftrapv This option generates traps for signed overflow on addition, subtraction, -@@ -18218,6 +18230,19 @@ instructions. It does not allow exceptions to be thrown from - arbitrary signal handlers such as @code{SIGALRM}. This enables - @option{-fexceptions}. - -+@opindex foff-stack-trampolines -+@item -foff-stack-trampolines -+Certain platforms (such as the Apple M1) do not permit an executable -+stack. Generate calls to @code{__builtin_nested_func_ptr_created} and -+@code{__builtin_nested_func_ptr_deleted} in order to allocate and -+deallocate trampoline space on the executable heap. Please note that -+these functions are implemented in libgcc, and will not be compiled in -+unless you provide @option{--enable-off-stack-trampolines} when -+building gcc. @emph{PLEASE NOTE}: The trampolines are @emph{not} -+guaranteed to be correctly deallocated if you @code{setjmp}, -+instantiate nested functions, and then @code{longjmp} back to a state -+prior to having allocated those nested functions. -+ - @opindex fdelete-dead-exceptions - @item -fdelete-dead-exceptions - Consider that instructions that may throw exceptions but don't otherwise +@@ -18652,6 +18711,20 @@ For languages other than Ada, the @code{-ftrampolines} and + trampolines are always generated on platforms that need them + for nested functions. + ++@opindex ftrampoline-impl ++@item -ftrampoline-impl=@r{[}stack@r{|}heap@r{]} ++By default, trampolines are generated on stack. However, certain platforms ++(such as the Apple M1) do not permit an executable stack. Compiling with ++@option{-ftrampoline-impl=heap} generate calls to ++@code{__gcc_nested_func_ptr_created} and ++@code{__gcc_nested_func_ptr_deleted} in order to allocate and ++deallocate trampoline space on the executable heap. These functions are ++implemented in libgcc, and will only be provided on specific targets: ++x86_64 Darwin, x86_64 and aarch64 Linux. @emph{PLEASE NOTE}: Heap ++trampolines are @emph{not} guaranteed to be correctly deallocated if you ++@code{setjmp}, instantiate nested functions, and then @code{longjmp} back ++to a state prior to having allocated those nested functions. ++ + @opindex fvisibility + @item -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]} + Set the default ELF image symbol visibility to the specified option---all +@@ -24024,6 +24097,11 @@ without that switch. Using this switch may require recompiling all + other modules in a program, including system libraries. Use this + switch to conform to a non-default data model. + ++@opindex munreachable-traps ++@item -munreachable-traps ++Causes @code{__builtin_unreachable} to be rendered as a trap. This is the ++default for all Darwin architectures. ++ + @opindex mfix-and-continue + @opindex ffix-and-continue + @opindex findirect-data +@@ -24070,6 +24148,14 @@ an executable when linking, using the Darwin @file{libtool} command. + This causes GCC's output file to have the @samp{ALL} subtype, instead of + one controlled by the @option{-mcpu} or @option{-march} option. + ++@opindex nodefaultrpaths ++@item -nodefaultrpaths ++Do not add default run paths for the compiler library directories to ++executables, modules or dynamic libraries. On macOS 10.5 and later, ++the embedded runpath is added by default unless the user adds ++@option{-nodefaultrpaths} to the link line. Run paths are needed ++(and therefore enforced) to build on macOS version 10.11 or later. ++ + @item -allowable_client @var{client_name} + @itemx -client_name + @itemx -compatibility_version +@@ -29823,7 +29909,7 @@ the same as @option{-mbig}. + + @opindex mdynamic-no-pic + @item -mdynamic-no-pic +-On Darwin and Mac OS X systems, compile code so that it is not ++On Darwin / macOS systems, compile code so that it is not + relocatable, but that its external references are relocatable. The + resulting code is suitable for applications, but not shared + libraries. +diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi +index 26df8b4..f9a2318 100644 +--- a/gcc/doc/plugins.texi ++++ b/gcc/doc/plugins.texi +@@ -44,7 +44,7 @@ Plugins are loaded with + + Where @var{name} is the plugin name and @var{ext} is the platform-specific + dynamic library extension. It should be @code{dll} on Windows/MinGW, +-@code{dylib} on Darwin/Mac OS X, and @code{so} on all other platforms. ++@code{dylib} on Darwin/macOS, and @code{so} on all other platforms. + The plugin arguments are parsed by GCC and passed to respective + plugins as key-value pairs. Multiple plugins can be invoked by + specifying multiple @option{-fplugin} arguments. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi -index a660e33739b..4479f8cbf0e 100644 +index a660e33..1080f85 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi -@@ -4354,6 +4354,16 @@ with the specified mode and type. The default hook returns +@@ -1042,6 +1042,10 @@ also define the hook to @code{default_promote_function_mode_always_promote} + if you would like to apply the same rules given by @code{PROMOTE_MODE}. + @end deftypefn + ++@deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE_CA (cumulative_args_t, @var{function_arg_info}, @var{const_tree}, int *@var{}, @var{int}) ++Like @code{promote_function_mode}, but takes a cumulative_args pointer and a current arg to supply the input. ++@end deftypefn ++ + @defmac PARM_BOUNDARY + Normal alignment required for function parameters on the stack, in + bits. All stack parameters receive at least this much alignment +@@ -4354,6 +4358,16 @@ with the specified mode and type. The default hook returns @code{PARM_BOUNDARY} for all arguments. @end deftypefn @@ -4240,7 +7002,7 @@ index a660e33739b..4479f8cbf0e 100644 @deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode @var{mode}, const_tree @var{type}) Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}, which is the default value for this hook. You can define this hook to -@@ -4361,6 +4371,16 @@ return a different value if an argument size must be rounded to a larger +@@ -4361,6 +4375,16 @@ return a different value if an argument size must be rounded to a larger value. @end deftypefn @@ -4257,11 +7019,41 @@ index a660e33739b..4479f8cbf0e 100644 @defmac FUNCTION_ARG_REGNO_P (@var{regno}) A C expression that is nonzero if @var{regno} is the number of a hard register in which function arguments are sometimes passed. This does +@@ -5764,7 +5788,7 @@ This hook determines whether a function from a class of functions + Set this macro to 1 to use the "NeXT" Objective-C message sending conventions + by default. This calling convention involves passing the object, the selector + and the method arguments all at once to the method-lookup library function. +-This is the usual setting when targeting Darwin/Mac OS X systems, which have ++This is the usual setting when targeting Darwin / macOS systems, which have + the NeXT runtime installed. + + If the macro is set to 0, the "GNU" Objective-C message sending convention +@@ -12365,6 +12389,11 @@ This target hook can be used to generate a target-specific code + If selftests are enabled, run any selftests for this target. + @end deftypefn + ++@deftypefn {Target Hook} bool TARGET_UNREACHABLE_SHOULD_TRAP (void) ++This hook should return @code{true} if the target wants @code{__builtin_unreachable} to expand to a trap or @code{abort ()}. ++ The default value is false. ++@end deftypefn ++ + @deftypefn {Target Hook} bool TARGET_MEMTAG_CAN_TAG_ADDRESSES () + True if the backend architecture naturally supports ignoring some region + of pointers. This feature means that @option{-fsanitize=hwaddress} can diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in -index f7ab5d48a63..cf6259c6cf6 100644 +index f7ab5d4..7f82c02 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in -@@ -3341,8 +3341,12 @@ required. +@@ -938,6 +938,8 @@ applied. + + @hook TARGET_PROMOTE_FUNCTION_MODE + ++@hook TARGET_PROMOTE_FUNCTION_MODE_CA ++ + @defmac PARM_BOUNDARY + Normal alignment required for function parameters on the stack, in + bits. All stack parameters receive at least this much alignment +@@ -3341,8 +3343,12 @@ required. @hook TARGET_FUNCTION_ARG_BOUNDARY @@ -4274,10 +7066,182 @@ index f7ab5d48a63..cf6259c6cf6 100644 @defmac FUNCTION_ARG_REGNO_P (@var{regno}) A C expression that is nonzero if @var{regno} is the number of a hard register in which function arguments are sometimes passed. This does +@@ -4008,7 +4014,7 @@ macro, a reasonable default is used. + Set this macro to 1 to use the "NeXT" Objective-C message sending conventions + by default. This calling convention involves passing the object, the selector + and the method arguments all at once to the method-lookup library function. +-This is the usual setting when targeting Darwin/Mac OS X systems, which have ++This is the usual setting when targeting Darwin / macOS systems, which have + the NeXT runtime installed. + + If the macro is set to 0, the "GNU" Objective-C message sending convention +@@ -7965,6 +7971,8 @@ maintainer is familiar with. + + @hook TARGET_RUN_TARGET_SELFTESTS + ++@hook TARGET_UNREACHABLE_SHOULD_TRAP ++ + @hook TARGET_MEMTAG_CAN_TAG_ADDRESSES + + @hook TARGET_MEMTAG_TAG_SIZE +diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in +index bddf46a..a9120f3 100644 +--- a/gcc/exec-tool.in ++++ b/gcc/exec-tool.in +@@ -23,6 +23,8 @@ ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@" + ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@" + ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@" + ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@" ++ORIGINAL_LLD_FOR_TARGET="@ORIGINAL_LLD_FOR_TARGET@" ++ORIGINAL_CLASSIC_LD_FOR_TARGET="@ORIGINAL_CLASSIC_LD_FOR_TARGET@" + ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@" + ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@" + ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@" +@@ -39,24 +41,41 @@ case "$invoked" in + dir=gas + ;; + collect-ld) +- # Check -fuse-ld=bfd and -fuse-ld=gold +- case " $* " in +- *\ -fuse-ld=bfd\ *) +- original=$ORIGINAL_LD_BFD_FOR_TARGET +- ;; +- *\ -fuse-ld=gold\ *) +- original=$ORIGINAL_LD_GOLD_FOR_TARGET +- ;; +- *) +- # when using a linker plugin, gcc will always pass '-plugin' as the +- # first or second option to the linker. +- if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then +- original=$ORIGINAL_PLUGIN_LD_FOR_TARGET +- else +- original=$ORIGINAL_LD_FOR_TARGET +- fi +- ;; +- esac ++ # when using a linker plugin, gcc will always pass '-plugin' as the ++ # first or second option to the linker. ++ if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then ++ original=$ORIGINAL_PLUGIN_LD_FOR_TARGET ++ else ++ original=$ORIGINAL_LD_FOR_TARGET ++ fi ++ # Check -fuse-ld=bfd, -fuse-ld=gold and -fuse-ld=classic ++ # Remove -fuse-ld=classic from the command line ++ for arg do ++ # temporarily, remove the arg. ++ shift ++ case $arg in ++ -fuse-ld=bfd) ++ original=$ORIGINAL_LD_BFD_FOR_TARGET ++ ;; ++ -fuse-ld=gold) ++ original=$ORIGINAL_LD_GOLD_FOR_TARGET ++ ;; ++ -fuse-ld=lld) ++ original=$ORIGINAL_LLD_FOR_TARGET ++ # We want to remove this from the command line; by the slightly ++ # obtuse mechanism of not putting it back. ++ continue ++ ;; ++ -fuse-ld=classic) ++ original=$ORIGINAL_CLASSIC_LD_FOR_TARGET ++ # As for lld. ++ continue ++ ;; ++ *) ;; ++ esac ++ # if we want to keep the arg, put it back. ++ set -- "$@" "$arg" ++ done + prog=ld-new$exeext + if test "$original" = ../gold/ld-new$exeext; then + dir=gold +diff --git a/gcc/explow.cc b/gcc/explow.cc +index 6424c08..7c2973a 100644 +--- a/gcc/explow.cc ++++ b/gcc/explow.cc +@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see + #include "langhooks.h" + #include "except.h" + #include "dojump.h" ++#include "calls.h" + #include "explow.h" + #include "expr.h" + #include "stringpool.h" +@@ -817,6 +818,16 @@ promote_function_mode (const_tree type, machine_mode mode, int *punsignedp, + return mode; + } + } ++ ++machine_mode ++promote_function_mode (cumulative_args_t args_so_far, function_arg_info arg, ++ const_tree funtype, int *punsignedp , int for_return) ++{ ++ return targetm.calls.promote_function_mode_ca (args_so_far, arg, funtype, ++ punsignedp, for_return); ++// return promote_function_mode (arg.type, arg.mode, punsignedp, funtype, for_return); ++} ++ + /* Return the mode to use to store a scalar of TYPE and MODE. + PUNSIGNEDP points to the signedness of the type and may be adjusted + to show what signedness to use on extension operations. */ +diff --git a/gcc/explow.h b/gcc/explow.h +index 2db4f5c..c7d2286 100644 +--- a/gcc/explow.h ++++ b/gcc/explow.h +@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see + #ifndef GCC_EXPLOW_H + #define GCC_EXPLOW_H + ++#include "calls.h" /* for cummulative args stuff. */ ++ + /* Return a memory reference like MEMREF, but which is known to have a + valid address. */ + extern rtx validize_mem (rtx); +@@ -47,8 +49,13 @@ extern rtx force_not_mem (rtx); + + /* Return mode and signedness to use when an argument or result in the + given mode is promoted. */ +-extern machine_mode promote_function_mode (const_tree, machine_mode, int *, +- const_tree, int); ++machine_mode promote_function_mode (const_tree, machine_mode, int *, ++ const_tree, int); ++ ++/* Return mode and signedness to use when an argument or result in the ++ given mode is promoted. */ ++machine_mode promote_function_mode (cumulative_args_t, function_arg_info, ++ const_tree, int *, int); + + /* Return mode and signedness to use when an object in the given mode + is promoted. */ +diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi +index 87baf5a..908f2b7 100644 +--- a/gcc/fortran/gfortran.texi ++++ b/gcc/fortran/gfortran.texi +@@ -978,7 +978,7 @@ low level file descriptor corresponding to an open Fortran unit. Then, + using e.g. the @code{ISO_C_BINDING} feature, one can call the + underlying system call to flush dirty data to stable storage, such as + @code{fsync} on POSIX, @code{_commit} on MingW, or @code{fcntl(fd, +-F_FULLSYNC, 0)} on Mac OS X. The following example shows how to call ++F_FULLSYNC, 0)} on macOS. The following example shows how to call + fsync: + + @smallexample diff --git a/gcc/function.cc b/gcc/function.cc -index edf0b2ec6cf..a8d49aa7613 100644 +index 8d6c447..4308e24 100644 --- a/gcc/function.cc +++ b/gcc/function.cc +@@ -58,8 +58,8 @@ along with GCC; see the file COPYING3. If not see + #include "varasm.h" + #include "except.h" + #include "dojump.h" +-#include "explow.h" + #include "calls.h" ++#include "explow.h" + #include "expr.h" + #include "optabs-tree.h" + #include "output.h" @@ -2448,7 +2448,10 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, else if (DECL_CHAIN (parm)) data->arg.named = 1; /* Not the last non-variadic parm. */ @@ -4290,7 +7254,23 @@ index edf0b2ec6cf..a8d49aa7613 100644 else data->arg.named = 0; /* Treat as variadic. */ -@@ -2505,6 +2508,7 @@ assign_parms_setup_varargs (struct assign_parm_data_all *all, +@@ -2490,9 +2493,12 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, + + /* Find mode as it is passed by the ABI. */ + unsignedp = TYPE_UNSIGNED (data->arg.type); +- data->arg.mode +- = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp, +- TREE_TYPE (current_function_decl), 0); ++// data->arg.mode ++// = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp, ++// TREE_TYPE (current_function_decl), 0); ++ data->arg.mode = promote_function_mode (all->args_so_far, data->arg, ++ TREE_TYPE (current_function_decl), ++ &unsignedp, 0); + } + + /* A subroutine of assign_parms. Invoke setup_incoming_varargs. */ +@@ -2505,6 +2511,7 @@ assign_parms_setup_varargs (struct assign_parm_data_all *all, function_arg_info last_named_arg = data->arg; last_named_arg.named = true; @@ -4298,7 +7278,7 @@ index edf0b2ec6cf..a8d49aa7613 100644 targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg, &varargs_pretend_bytes, no_rtl); -@@ -2613,7 +2617,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, +@@ -2613,7 +2620,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs, all->reg_parm_stack_space, @@ -4309,7 +7289,7 @@ index edf0b2ec6cf..a8d49aa7613 100644 &all->stack_args_size, &data->locate); /* Update parm_stack_boundary if this parameter is passed in the -@@ -3944,7 +3950,8 @@ gimplify_parameters (gimple_seq *cleanup) +@@ -3945,7 +3954,8 @@ gimplify_parameters (gimple_seq *cleanup) if (data.arg.pass_by_reference) { tree type = TREE_TYPE (data.arg.type); @@ -4319,7 +7299,7 @@ index edf0b2ec6cf..a8d49aa7613 100644 if (reference_callee_copied (&all.args_so_far_v, orig_arg)) { tree local, t; -@@ -4047,6 +4054,7 @@ gimplify_parameters (gimple_seq *cleanup) +@@ -4048,6 +4058,7 @@ gimplify_parameters (gimple_seq *cleanup) void locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, int reg_parm_stack_space, int partial, @@ -4327,7 +7307,7 @@ index edf0b2ec6cf..a8d49aa7613 100644 tree fndecl ATTRIBUTE_UNUSED, struct args_size *initial_offset_ptr, struct locate_and_pad_arg_data *locate) -@@ -4084,9 +4092,23 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, +@@ -4085,9 +4096,23 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, ? arg_size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode))); where_pad = targetm.calls.function_arg_padding (passed_mode, type); @@ -4355,7 +7335,7 @@ index edf0b2ec6cf..a8d49aa7613 100644 /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */ diff --git a/gcc/function.h b/gcc/function.h -index d4ce8a7c6c6..09ab17e66c1 100644 +index d4ce8a7..09ab17e 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see @@ -4375,7 +7355,7 @@ index d4ce8a7c6c6..09ab17e66c1 100644 struct locate_and_pad_arg_data *); extern void generate_setjmp_warnings (void); diff --git a/gcc/gcc.cc b/gcc/gcc.cc -index 16bb07f2cdc..d0349741d2f 100644 +index 16bb07f..d034974 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -575,6 +575,7 @@ or with constant text in a single argument. @@ -4454,7 +7434,7 @@ index 16bb07f2cdc..d0349741d2f 100644 for_each_path (&include_prefixes, false, info.append_len, spec_path, &info); diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h -index 12ceef39180..af071079940 100644 +index 12ceef3..af07107 100644 --- a/gcc/ginclude/stddef.h +++ b/gcc/ginclude/stddef.h @@ -428,9 +428,8 @@ typedef struct { @@ -4470,10 +7450,10 @@ index 12ceef39180..af071079940 100644 #endif } max_align_t; diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in -index a65f13853ae..3fd564a5932 100644 +index 5507920..5bdba6c 100644 --- a/gcc/jit/Make-lang.in +++ b/gcc/jit/Make-lang.in -@@ -59,7 +59,7 @@ LIBGCCJIT_AGE = 1 +@@ -69,7 +69,7 @@ LIBGCCJIT_COMPAT = 0 LIBGCCJIT_BASENAME = libgccjit LIBGCCJIT_SONAME = \ @@ -4482,180 +7462,227 @@ index a65f13853ae..3fd564a5932 100644 LIBGCCJIT_FILENAME = $(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib LIBGCCJIT_LINKER_NAME = $(LIBGCCJIT_BASENAME).dylib +diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc +index e06f161..2a04573 100644 +--- a/gcc/jit/jit-playback.cc ++++ b/gcc/jit/jit-playback.cc +@@ -3024,7 +3024,7 @@ invoke_driver (const char *ctxt_progname, + ADD_ARG ("-fno-use-linker-plugin"); + + #if defined (DARWIN_X86) || defined (DARWIN_PPC) +- /* OS X's linker defaults to treating undefined symbols as errors. ++ /* macOS's linker defaults to treating undefined symbols as errors. + If the context has any imported functions or globals they will be + undefined until the .so is dynamically-linked into the process. + Ensure that the driver passes in "-undefined dynamic_lookup" to the +diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h +index 057d3e5..04545e4 100644 +--- a/gcc/jit/libgccjit.h ++++ b/gcc/jit/libgccjit.h +@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see + #define LIBGCCJIT_H + + #include ++#ifdef __APPLE__ ++# include /* For ssize_t. */ ++#endif + + #ifdef __cplusplus + extern "C" { diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in -index b34db0d9156..e6ad91ee168 100644 +index 0ae3e18..320f930 100644 --- a/gcc/m2/Make-lang.in +++ b/gcc/m2/Make-lang.in -@@ -478,6 +478,11 @@ GM2_MIN_FLAGS=$(GM2_G) $(GM2_OS) \ - -Wpedantic-cast -Wpedantic-param-names -fno-exceptions \ - -ffunction-sections -fdata-sections $(GM2_CPP) - -+# ALL_LINKERFLAGS may include -pie (when GCC is configured with -+# --enable-host-pie), so use -fPIE if needed. (It would not be -+# a good idea to override CFLAGS.) -+GM2_PICFLAGS = $(PICFLAG) -+ - O2=-O2 -g - SO_O2=-O2 -g -fPIC - SO=-O0 -g -fPIC -@@ -1354,23 +1359,23 @@ m2/boot-bin/mc$(exeext): $(BUILD-MC-BOOT-O) $(BUILD-MC-INTERFACE-O) \ - - m2/mc-boot/$(SRC_PREFIX)%.o: m2/mc-boot/$(SRC_PREFIX)%.cc m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) $(CXXFLAGS) -g -c -I. -I$(srcdir)/m2/mc-boot-ch -I$(srcdir)/m2/mc-boot -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) $< -o $@ -+ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -g -c -I. -I$(srcdir)/m2/mc-boot-ch -I$(srcdir)/m2/mc-boot -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) $< -o $@ - - m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.c m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) $(CXXFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ -+ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ - - m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.cc m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) $(CXXFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ -+ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ - - m2/mc-boot/main.o: $(M2LINK) $(srcdir)/m2/init/mcinit - -test -d $(@D) || $(mkinstalldirs) $(@D) - unset CC ; $(M2LINK) -s --langc++ --exit --name m2/mc-boot/main.cc $(srcdir)/m2/init/mcinit -- $(CXX) $(CXXFLAGS) -g -c -I. -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) m2/mc-boot/main.cc -o $@ -+ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -g -c -I. -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) m2/mc-boot/main.cc -o $@ - - mcflex.o: mcflex.c m2/gm2-libs/gm2-libs-host.h -- $(CC) $(CFLAGS) -I$(srcdir)/m2/mc -g -c $< -o $@ # remember that mcReserved.h is copied into m2/mc -+ $(CC) $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2/mc -g -c $< -o $@ # remember that mcReserved.h is copied into m2/mc - - mcflex.c: $(srcdir)/m2/mc/mc.flex - flex -t $< > $@ -@@ -1378,17 +1383,17 @@ mcflex.c: $(srcdir)/m2/mc/mc.flex - m2/gm2-libs-boot/M2RTS.o: $(srcdir)/m2/gm2-libs/M2RTS.mod $(MCDEPS) $(BUILD-BOOT-H) - -test -d $(@D) || $(mkinstalldirs) $(@D) - $(MC) --suppress-noreturn -o=m2/gm2-libs-boot/M2RTS.c $(srcdir)/m2/gm2-libs/M2RTS.mod -- $(COMPILER) -c -DIN_GCC $(CFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/M2RTS.c -o $@ -+ $(COMPILER) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/M2RTS.c -o $@ - - m2/gm2-libs-boot/%.o: $(srcdir)/m2/gm2-libs-boot/%.mod $(MCDEPS) $(BUILD-BOOT-H) - -test -d $(@D) || $(mkinstalldirs) $(@D) - $(MC) -o=m2/gm2-libs-boot/$*.c $(srcdir)/m2/gm2-libs-boot/$*.mod -- $(COMPILER) -c -DIN_GCC $(CFLAGS) $(MCINCLUDES) m2/gm2-libs-boot/$*.c -o $@ -+ $(COMPILER) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) $(MCINCLUDES) m2/gm2-libs-boot/$*.c -o $@ - - m2/gm2-libs-boot/%.o: $(srcdir)/m2/gm2-libs/%.mod $(MCDEPS) $(BUILD-BOOT-H) - -test -d $(@D) || $(mkinstalldirs) $(@D) - $(MC) -o=m2/gm2-libs-boot/$*.c $(srcdir)/m2/gm2-libs/$*.mod -- $(COMPILER) -c -DIN_GCC $(CFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/$*.c -o $@ -+ $(COMPILER) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/$*.c -o $@ - - m2/gm2-libs-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-libs/%.def $(MCDEPS) - -test -d $(@D) || $(mkinstalldirs) $(@D) -@@ -1396,49 +1401,49 @@ m2/gm2-libs-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-libs/%.def $(MCDEPS) - - m2/gm2-libs-boot/RTcodummy.o: $(srcdir)/m2/gm2-libs-ch/RTcodummy.c m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c -DIN_GCC $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/RTintdummy.o: $(srcdir)/m2/gm2-libs-ch/RTintdummy.c m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c -DIN_GCC $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/wrapc.o: $(srcdir)/m2/gm2-libs-ch/wrapc.c m2/gm2-libs-boot/$(SRC_PREFIX)wrapc.h m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c -DHAVE_CONFIG_H $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libs $(INCLUDES) $< -o $@ -+ $(CXX) -c -DHAVE_CONFIG_H $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libs $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/UnixArgs.o: $(srcdir)/m2/gm2-libs-ch/UnixArgs.cc m2/gm2-libs-boot/$(SRC_PREFIX)UnixArgs.h m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c -DIN_GCC $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/choosetemp.o: m2/gm2-libs-ch/choosetemp.c m2/gm2-libiberty/Gchoosetemp.h m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/errno.o: $(srcdir)/m2/gm2-libs-ch/errno.c m2/gm2-libs-boot/$(SRC_PREFIX)errno.h m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/dtoa.o: $(srcdir)/m2/gm2-libs-ch/dtoa.cc m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/ldtoa.o: $(srcdir)/m2/gm2-libs-ch/ldtoa.cc m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/termios.o: $(srcdir)/m2/gm2-libs-ch/termios.c $(BUILD-LIBS-BOOT-H) m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/SysExceptions.o: $(srcdir)/m2/gm2-libs-ch/SysExceptions.c \ - m2/gm2-libs-boot/$(SRC_PREFIX)SysExceptions.h m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ - - m2/gm2-libs-boot/SysStorage.o: $(srcdir)/m2/gm2-libs/SysStorage.mod $(MCDEPS) $(BUILD-BOOT-H) - -test -d $(@D) || $(mkinstalldirs) $(@D) - $(MC) -o=m2/gm2-libs-boot/SysStorage.c $(srcdir)/m2/gm2-libs/SysStorage.mod -- $(COMPILER) -DIN_GCC -c $(CFLAGS) \ -+ $(COMPILER) -DIN_GCC -c $(CFLAGS) $(GM2_PICFLAGS) \ - -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) \ - m2/gm2-libs-boot/SysStorage.c -o m2/gm2-libs-boot/SysStorage.o +@@ -501,6 +501,11 @@ GM2_MIN_FLAGS=$(GM2_G) $(GM2_OS) \ + -Wpedantic-cast -Wpedantic-param-names -fno-exceptions \ + -ffunction-sections -fdata-sections $(GM2_CPP) -@@ -1511,7 +1516,7 @@ m2/gm2-compiler/%.o: m2/gm2-compiler/%.mod ++# ALL_LINKERFLAGS may include -pie (when GCC is configured with ++# --enable-host-pie), so use -fPIE if needed. (It would not be ++# a good idea to override CFLAGS.) ++GM2_PICFLAGS = $(PICFLAG) ++ + O2=-O2 -g + SO_O2=-O2 -g -fPIC + SO=-O0 -g -fPIC +@@ -1396,7 +1401,7 @@ m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.c m2/gm2-libs/gm2-l - m2/gm2-libs-iso/%.o: $(srcdir)/m2/gm2-libs-iso/%.c m2/gm2-libs/gm2-libs-host.h + m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.cc m2/gm2-libs/gm2-libs-host.h -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -DBUILD_GM2_LIBS_TARGET -DBUILD_GM2_LIBS -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -DBUILD_GM2_LIBS_TARGET -DBUILD_GM2_LIBS -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ +- $(CXX) $(CXXFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ ++ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ - m2/gm2-libs-iso/%.o: $(srcdir)/m2/gm2-libs-iso/%.mod - -test -d $(@D) || $(mkinstalldirs) $(@D) -@@ -1613,15 +1618,15 @@ m2/gm2-libs/%.o: $(srcdir)/m2/gm2-libs/%.mod $(MCDEPS) $(BUILD-BOOT-H) + m2/mc-boot/main.o: $(M2LINK) $(srcdir)/m2/init/mcinit + -test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR) +diff --git a/gcc/objc/objc-act.cc b/gcc/objc/objc-act.cc +index fe2d2b5..8558059 100644 +--- a/gcc/objc/objc-act.cc ++++ b/gcc/objc/objc-act.cc +@@ -3317,7 +3317,7 @@ objc_build_string_object (tree string) + length = TREE_STRING_LENGTH (string) - 1; + + /* The target may have different ideas on how to construct an ObjC string +- literal. On Darwin (Mac OS X), for example, we may wish to obtain a ++ literal. On Darwin / macOS, for example, we may wish to obtain a + constant CFString reference instead. + At present, this is only supported for the NeXT runtime. */ + if (flag_next_runtime +@@ -10362,5 +10362,51 @@ objc_common_tree_size (enum tree_code code) + } + } - m2/gm2-libs/%.o: $(srcdir)/m2/gm2-libs-ch/%.c m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -DBUILD_GM2_LIBS -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -DBUILD_GM2_LIBS -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ ++/* Information for Objective-C-specific features known to __has_feature. */ ++ ++struct objc_feature_info ++{ ++ typedef bool (*predicate_t) (); ++ ++ const char *ident; ++ predicate_t predicate; ++ ++ constexpr objc_feature_info (const char *name) ++ : ident (name), predicate (nullptr) {} ++ constexpr objc_feature_info (const char *name, predicate_t p) ++ : ident (name), predicate (p) {} ++ ++ bool has_feature () const ++ { ++ return predicate ? predicate () : true; ++ } ++}; ++ ++static bool objc_nonfragile_abi_p () ++{ ++ return flag_next_runtime && flag_objc_abi >= 2; ++} ++ ++static constexpr objc_feature_info objc_features[] = ++{ ++ { "objc_default_synthesize_properties" }, ++ { "objc_instancetype" }, ++ { "objc_nonfragile_abi", objc_nonfragile_abi_p } ++}; ++ ++/* Register Objective-C-specific features for __has_feature. */ ++ ++void ++objc_common_register_features () ++{ ++ for (unsigned i = 0; i < ARRAY_SIZE (objc_features); i++) ++ { ++ const objc_feature_info *info = objc_features + i; ++ if (!info->has_feature ()) ++ continue; ++ ++ c_common_register_feature (info->ident, true); ++ } ++} - m2/gm2-libs/%.o: $(srcdir)/m2/gm2-libs-ch/%.cc m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@ + #include "gt-objc-objc-act.h" +diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h +index e21ab52..bcf0249 100644 +--- a/gcc/objc/objc-act.h ++++ b/gcc/objc/objc-act.h +@@ -29,6 +29,9 @@ int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *); + void objc_common_init_ts (void); + const char *objc_get_sarif_source_language (const char *); + ++/* Register features common to Objective-C and Objective-C++. */ ++void objc_common_register_features (); ++ + /* NB: The remaining public functions are prototyped in c-common.h, for the + benefit of stub-objc.cc and objc-act.cc. */ + +diff --git a/gcc/objc/objc-lang.cc b/gcc/objc/objc-lang.cc +index 89b3be4..7568248 100644 +--- a/gcc/objc/objc-lang.cc ++++ b/gcc/objc/objc-lang.cc +@@ -58,6 +58,16 @@ objc_get_sarif_source_language (const char *) + return "objectivec"; + } - m2/gm2-libs/choosetemp.o: m2/gm2-libs-ch/choosetemp.c m2/gm2-libiberty/Gchoosetemp.h m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) -c $(CFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@ -+ $(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@ ++/* Implement c-family hook to add language-specific features ++ for __has_{feature,extension}. */ ++ ++void ++c_family_register_lang_features () ++{ ++ objc_common_register_features (); ++ c_register_features (); ++} ++ + /* Lang hook routines common to C and ObjC appear in c-objc-common.cc; + there should be very few (if any) routines below. */ - m2/gm2-libs-boot/libgm2.a: m2/boot-bin/mc$(exeext) $(BUILD-LIBS-BOOT) - -test -d $(@D) || $(mkinstalldirs) $(@D) -@@ -1722,11 +1727,11 @@ include m2/Make-maintainer - else - m2/pge-boot/%.o: m2/pge-boot/%.c m2/gm2-libs/gm2-libs-host.h m2/gm2config.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) $(CFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@ -+ $(CXX) $(CFLAGS) $(GM2_PICFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@ +diff --git a/gcc/objcp/objcp-lang.cc b/gcc/objcp/objcp-lang.cc +index 9887209..ede59a6 100644 +--- a/gcc/objcp/objcp-lang.cc ++++ b/gcc/objcp/objcp-lang.cc +@@ -80,6 +80,16 @@ objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain, + #undef RECURSE + } - m2/pge-boot/%.o: m2/pge-boot/%.cc m2/gm2-libs/gm2-libs-host.h m2/gm2config.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) $(CXXFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@ -+ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@ ++/* Implement c-family hook to add language-specific features ++ for __has_{feature,extension}. */ ++ ++void ++c_family_register_lang_features () ++{ ++ objc_common_register_features (); ++ cp_register_features (); ++} ++ + static void + objcxx_init_ts (void) + { +diff --git a/gcc/opts.cc b/gcc/opts.cc +index e0ba89f..71371e2 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -3215,6 +3215,7 @@ common_handle_option (struct gcc_options *opts, + break; - $(PGE): $(BUILD-PGE-O) - +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(BUILD-PGE-O) -lm + case OPT_fuse_ld_bfd: ++ case OPT_fuse_ld_classic: + case OPT_fuse_ld_gold: + case OPT_fuse_ld_lld: + case OPT_fuse_ld_mold: +diff --git a/gcc/plugin.cc b/gcc/plugin.cc +index 142f3fa..c3e40b2 100644 +--- a/gcc/plugin.cc ++++ b/gcc/plugin.cc +@@ -190,10 +190,10 @@ add_new_plugin (const char* plugin_name) + #if defined(__MINGW32__) + static const char plugin_ext[] = ".dll"; + #elif defined(__APPLE__) +- /* Mac OS has two types of libraries: dynamic libraries (.dylib) and ++ /* macOS has two types of libraries: dynamic libraries (.dylib) and + plugins (.bundle). Both can be used with dlopen()/dlsym() but the + former cannot be linked at build time (i.e., with the -lfoo linker +- option). A GCC plugin is therefore probably a Mac OS plugin but their ++ option). A GCC plugin is therefore probably a macOS plugin but their + use seems to be quite rare and the .bundle extension is more of a + recommendation rather than the rule. This raises the questions of how + well they are supported by tools (e.g., libtool). So to avoid diff --git a/gcc/target.def b/gcc/target.def -index 171bbd1caf1..ba2c342d40f 100644 +index 171bbd1..75b51d2 100644 --- a/gcc/target.def +++ b/gcc/target.def -@@ -4992,6 +4992,18 @@ with the specified mode and type. The default hook returns\n\ +@@ -4574,6 +4574,13 @@ if you would like to apply the same rules given by @code{PROMOTE_MODE}.", + const_tree funtype, int for_return), + default_promote_function_mode) + ++DEFHOOK ++(promote_function_mode_ca, ++ "Like @code{promote_function_mode}, but takes a cumulative_args pointer \ ++ and a current arg to supply the input.", ++ machine_mode, (cumulative_args_t, function_arg_info, const_tree, int *, int), ++ default_promote_function_mode_ca) ++ + DEFHOOK + (promote_prototypes, + "This target hook returns @code{true} if an argument declared in a\n\ +@@ -4992,6 +4999,18 @@ with the specified mode and type. The default hook returns\n\ unsigned int, (machine_mode mode, const_tree type), default_function_arg_boundary) @@ -4674,7 +7701,7 @@ index 171bbd1caf1..ba2c342d40f 100644 DEFHOOK (function_arg_round_boundary, "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\ -@@ -5001,6 +5013,18 @@ value.", +@@ -5001,6 +5020,18 @@ value.", unsigned int, (machine_mode mode, const_tree type), default_function_arg_round_boundary) @@ -4693,8 +7720,25 @@ index 171bbd1caf1..ba2c342d40f 100644 /* Return the diagnostic message string if function without a prototype is not allowed for this 'val' argument; NULL otherwise. */ DEFHOOK +@@ -7138,6 +7169,16 @@ DEFHOOKPOD + @option{-fsanitize=shadow-call-stack}. The default value is false.", + bool, false) + ++/* This value represents whether __builtin_unreachable should be expanded ++ as a trap instruction (or an abort() if the trap is not available). */ ++DEFHOOK ++(unreachable_should_trap, ++ "This hook should return @code{true} if the target wants \ ++ @code{__builtin_unreachable} to expand to a trap or @code{abort ()}.\n\ ++ The default value is false.", ++ bool, (void), ++ hook_bool_void_false) ++ + /* Close the 'struct gcc_target' definition. */ + HOOK_VECTOR_END (C90_EMPTY_HACK) + diff --git a/gcc/target.h b/gcc/target.h -index cd448e4b7ab..064523f2a2e 100644 +index cd448e4..064523f 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -51,22 +51,8 @@ @@ -4723,10 +7767,26 @@ index cd448e4b7ab..064523f2a2e 100644 /* Types of memory operation understood by the "by_pieces" infrastructure. Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc -index 51bf3fb7a82..421aacd829d 100644 +index 51bf3fb..13a7c20 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc -@@ -856,6 +856,14 @@ default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, +@@ -159,6 +159,15 @@ default_promote_function_mode_always_promote (const_tree type, + return promote_mode (type, mode, punsignedp); + } + ++machine_mode ++default_promote_function_mode_ca (cumulative_args_t, function_arg_info arg, ++ const_tree funtype, int *punsignedp, ++ int for_return) ++{ ++ return promote_function_mode (arg.type, arg.mode, punsignedp, ++ funtype, for_return); ++} ++ + machine_mode + default_cc_modes_compatible (machine_mode m1, machine_mode m2) + { +@@ -856,6 +865,14 @@ default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, return PARM_BOUNDARY; } @@ -4741,7 +7801,7 @@ index 51bf3fb7a82..421aacd829d 100644 unsigned int default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED) -@@ -863,6 +871,14 @@ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, +@@ -863,6 +880,14 @@ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, return PARM_BOUNDARY; } @@ -4757,10 +7817,20 @@ index 51bf3fb7a82..421aacd829d 100644 hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) { diff --git a/gcc/targhooks.h b/gcc/targhooks.h -index cf3d3107a0d..cd3c6a8d18a 100644 +index cf3d310..cd4e830 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h -@@ -158,6 +158,12 @@ extern unsigned int default_function_arg_boundary (machine_mode, +@@ -34,6 +34,9 @@ extern machine_mode default_promote_function_mode (const_tree, machine_mode, + extern machine_mode default_promote_function_mode_always_promote + (const_tree, machine_mode, int *, const_tree, int); + ++extern machine_mode default_promote_function_mode_ca ++ (cumulative_args_t, function_arg_info, const_tree, int *, int); ++ + extern machine_mode default_cc_modes_compatible (machine_mode, + machine_mode); + +@@ -158,6 +161,12 @@ extern unsigned int default_function_arg_boundary (machine_mode, const_tree); extern unsigned int default_function_arg_round_boundary (machine_mode, const_tree); @@ -4773,199 +7843,8 @@ index cf3d3107a0d..cd3c6a8d18a 100644 extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); extern rtx default_function_value (const_tree, const_tree, bool); extern HARD_REG_SET default_zero_call_used_regs (HARD_REG_SET); -diff --git a/gcc/testsuite/gfortran.dg/coarray/caf.exp b/gcc/testsuite/gfortran.dg/coarray/caf.exp -index d232be2fa90..fb233e3d082 100644 ---- a/gcc/testsuite/gfortran.dg/coarray/caf.exp -+++ b/gcc/testsuite/gfortran.dg/coarray/caf.exp -@@ -28,6 +28,7 @@ - - # Load procedures from common libraries. - load_lib gfortran-dg.exp -+load_lib atomic-dg.exp - - # If a testcase doesn't have special options, use these. - global DEFAULT_FFLAGS -@@ -47,6 +48,7 @@ global gfortran_test_path - global gfortran_aux_module_flags - set gfortran_test_path $srcdir/$subdir - set gfortran_aux_module_flags $DEFAULT_FFLAGS -+ - proc dg-compile-aux-modules { args } { - global gfortran_test_path - global gfortran_aux_module_flags -@@ -71,7 +73,16 @@ proc dg-compile-aux-modules { args } { - # Add -latomic only where supported. Assume built-in support elsewhere. - set maybe_atomic_lib "" - if [check_effective_target_libatomic_available] { -- set maybe_atomic_lib "-latomic" -+ #set maybe_atomic_lib "-latomic" -+ if ![is_remote host] { -+ if [info exists TOOL_OPTIONS] { -+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]" -+ } else { -+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs]]" -+ } -+ } -+ set t [get_multilibs] -+ puts "maybe al $maybe_atomic_lib ml $t" - } - - # Main loop. -@@ -97,14 +108,14 @@ foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ]] - foreach flags $option_list { - verbose "Testing $nshort (single), $flags" 1 - set gfortran_aux_module_flags "-fcoarray=single $flags" -- dg-test $test "-fcoarray=single $flags $maybe_atomic_lib" "" -+ dg-test $test "-fcoarray=single $flags" $maybe_atomic_lib - cleanup-modules "" - } - - foreach flags $option_list { - verbose "Testing $nshort (libcaf_single), $flags" 1 - set gfortran_aux_module_flags "-fcoarray=lib $flags -lcaf_single" -- dg-test $test "-fcoarray=lib $flags -lcaf_single $maybe_atomic_lib" "" -+ dg-test $test "-fcoarray=lib $flags -lcaf_single" $maybe_atomic_lib - cleanup-modules "" - } - } -diff --git a/gcc/testsuite/gfortran.dg/dg.exp b/gcc/testsuite/gfortran.dg/dg.exp -index ee2760327dc..73541ea7301 100644 ---- a/gcc/testsuite/gfortran.dg/dg.exp -+++ b/gcc/testsuite/gfortran.dg/dg.exp -@@ -18,6 +18,7 @@ - - # Load support procs. - load_lib gfortran-dg.exp -+load_lib atomic-dg.exp - - # If a testcase doesn't have special options, use these. - global DEFAULT_FFLAGS -@@ -53,13 +54,38 @@ proc dg-compile-aux-modules { args } { - } - } - -+# coarray tests might need libatomic. Assume that it is either not needed or -+# provided by builtins if it's not available. -+set maybe_atomic_lib "" -+if [check_effective_target_libatomic_available] { -+ if ![is_remote host] { -+ if [info exists TOOL_OPTIONS] { -+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]" -+ } else { -+ set maybe_atomic_lib "[atomic_link_flags [get_multilibs]]" -+ } -+ } else { -+ set maybe_atomic_lib "" -+ } -+ set t [get_multilibs] -+ puts "dg set al $maybe_atomic_lib ml $t" -+} -+ -+set all_flags $DEFAULT_FFLAGS -+if { $maybe_atomic_lib != "" } { -+ foreach f $maybe_atomic_lib { -+ lappend all_flags $f -+ } -+} -+ -+puts "revised FFLAGS $all_flags" -+ - # Main loop. - gfortran-dg-runtest [lsort \ -- [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $DEFAULT_FFLAGS -+ [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $all_flags - - gfortran-dg-runtest [lsort \ -- [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $DEFAULT_FFLAGS -- -+ [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $all_flags - - # All done. - dg-finish -diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp -index 35e60eaaed5..157b60908d6 100644 ---- a/gcc/testsuite/lib/asan-dg.exp -+++ b/gcc/testsuite/lib/asan-dg.exp -@@ -78,7 +78,7 @@ proc asan_link_flags_1 { paths lib } { - || [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.${shlib_ext}"] } { - append flags " -B${gccpath}/libsanitizer/ " - append flags " -B${gccpath}/libsanitizer/${lib}/ " -- append flags " -L${gccpath}/libsanitizer/${lib}/.libs " -+ append flags " -B${gccpath}/libsanitizer/${lib}/.libs " - append ld_library_path ":${gccpath}/libsanitizer/${lib}/.libs" - } - } else { -diff --git a/gcc/testsuite/lib/atomic-dg.exp b/gcc/testsuite/lib/atomic-dg.exp -index 1589acd8eaf..ce1799cef2d 100644 ---- a/gcc/testsuite/lib/atomic-dg.exp -+++ b/gcc/testsuite/lib/atomic-dg.exp -@@ -33,7 +33,7 @@ proc atomic_link_flags { paths } { - if { [file exists "${gccpath}/libatomic/.libs/libatomic.a"] - || [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] } { - append flags " -B${gccpath}/libatomic/ " -- append flags " -L${gccpath}/libatomic/.libs" -+ append flags " -B${gccpath}/libatomic/.libs" - append ld_library_path ":${gccpath}/libatomic/.libs" - } - } else { -diff --git a/gcc/testsuite/lib/target-libpath.exp b/gcc/testsuite/lib/target-libpath.exp -index 6d530fb4af6..5de039b4fc2 100644 ---- a/gcc/testsuite/lib/target-libpath.exp -+++ b/gcc/testsuite/lib/target-libpath.exp -@@ -67,6 +67,7 @@ proc set_ld_library_path_env_vars { } { - global orig_dyld_library_path - global orig_path - global orig_gcc_exec_prefix -+ global ENABLE_DARWIN_AT_RPATH - global env - - # Save the original GCC_EXEC_PREFIX. -@@ -133,6 +134,7 @@ proc set_ld_library_path_env_vars { } { - # - # Doing this is somewhat of a hack as ld_library_path gets repeated in - # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables. -+ if { ![istarget *-*-darwin*] } { - if { $orig_ld_library_path_saved } { - setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" - } else { -@@ -166,11 +168,23 @@ proc set_ld_library_path_env_vars { } { - } else { - setenv LD_LIBRARY_PATH_64 "$ld_library_path" - } -- if { $orig_dyld_library_path_saved } { -- setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" -- } else { -- setenv DYLD_LIBRARY_PATH "$ld_library_path" - } -+ if { [istarget *-*-darwin*] } { -+ if { [info exists ENABLE_DARWIN_AT_RPATH] || [istarget *-*-darwin1\[5-9\]*] -+ || [istarget *-*-darwin20*] } { -+ # Either we are not using DYLD_LIBRARY_PATH or we're on a version of the -+ # OS for which it is not passed through system exes. -+ if [info exists env(DYLD_LIBRARY_PATH)] { -+ unsetenv DYLD_LIBRARY_PATH -+ } -+ } else { -+ if { $orig_dyld_library_path_saved } { -+ setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" -+ } else { -+ setenv DYLD_LIBRARY_PATH "$ld_library_path" -+ } -+ } -+ } - if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { - if { $orig_path_saved } { - setenv PATH "$ld_library_path:$orig_path" -@@ -179,6 +193,7 @@ proc set_ld_library_path_env_vars { } { - } - } - -+ verbose -log "set paths" - verbose -log "LD_LIBRARY_PATH=[getenv LD_LIBRARY_PATH]" - verbose -log "LD_RUN_PATH=[getenv LD_RUN_PATH]" - verbose -log "SHLIB_PATH=[getenv SHLIB_PATH]" diff --git a/gcc/tree-nested.cc b/gcc/tree-nested.cc -index 1418e1f7f56..060072ba76e 100644 +index 0f44b3d..8355425 100644 --- a/gcc/tree-nested.cc +++ b/gcc/tree-nested.cc @@ -611,6 +611,14 @@ get_trampoline_type (struct nesting_info *info) @@ -4974,7 +7853,7 @@ index 1418e1f7f56..060072ba76e 100644 + /* When trampolines are created off-stack then the only thing we need in the + local frame is a single pointer. */ -+ if (flag_off_stack_trampolines) ++ if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) + { + trampoline_type = build_pointer_type (void_type_node); + return trampoline_type; @@ -4983,7 +7862,7 @@ index 1418e1f7f56..060072ba76e 100644 align = TRAMPOLINE_ALIGNMENT; size = TRAMPOLINE_SIZE; -@@ -2788,17 +2796,27 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) +@@ -2793,17 +2801,27 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) /* Compute the address of the field holding the trampoline. */ x = get_frame_field (info, target_context, x, &wi->gsi); @@ -4997,7 +7876,7 @@ index 1418e1f7f56..060072ba76e 100644 + /* APB: We don't need to do the adjustment calls when using off-stack + trampolines, any such adjustment will be done when the off-stack + trampoline is created. */ -+ if (!descr && flag_off_stack_trampolines) ++ if (!descr && flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) + x = gsi_gimplify_val (info, x, &wi->gsi); else - builtin = builtin_decl_implicit (BUILT_IN_ADJUST_TRAMPOLINE); @@ -5020,7 +7899,7 @@ index 1418e1f7f56..060072ba76e 100644 /* Cast back to the proper function type. */ x = build1 (NOP_EXPR, TREE_TYPE (t), x); -@@ -3377,6 +3395,7 @@ build_init_call_stmt (struct nesting_info *info, tree decl, tree field, +@@ -3382,6 +3400,7 @@ build_init_call_stmt (struct nesting_info *info, tree decl, tree field, static void finalize_nesting_tree_1 (struct nesting_info *root) { @@ -5028,14 +7907,14 @@ index 1418e1f7f56..060072ba76e 100644 gimple_seq stmt_list = NULL; gimple *stmt; tree context = root->context; -@@ -3508,9 +3527,48 @@ finalize_nesting_tree_1 (struct nesting_info *root) +@@ -3513,9 +3532,48 @@ finalize_nesting_tree_1 (struct nesting_info *root) if (!field) continue; - x = builtin_decl_implicit (BUILT_IN_INIT_TRAMPOLINE); - stmt = build_init_call_stmt (root, i->context, field, x); - gimple_seq_add_stmt (&stmt_list, stmt); -+ if (flag_off_stack_trampolines) ++ if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) + { + /* We pass a whole bunch of arguments to the builtin function that + creates the off-stack trampoline, these are @@ -5060,13 +7939,13 @@ index 1418e1f7f56..060072ba76e 100644 + root->frame_decl, field, NULL_TREE); + arg3 = build_addr (x); + -+ x = builtin_decl_implicit (BUILT_IN_NESTED_PTR_CREATED); ++ x = builtin_decl_explicit (BUILT_IN_GCC_NESTED_PTR_CREATED); + stmt = gimple_build_call (x, 3, arg1, arg2, arg3); + gimple_seq_add_stmt (&stmt_list, stmt); + + /* This call to delete the nested function trampoline is added to + the cleanup list, and called when we exit the current scope. */ -+ x = builtin_decl_implicit (BUILT_IN_NESTED_PTR_DELETED); ++ x = builtin_decl_explicit (BUILT_IN_GCC_NESTED_PTR_DELETED); + stmt = gimple_build_call (x, 0); + gimple_seq_add_stmt (&cleanup_list, stmt); + } @@ -5080,7 +7959,7 @@ index 1418e1f7f56..060072ba76e 100644 } } -@@ -3535,11 +3593,40 @@ finalize_nesting_tree_1 (struct nesting_info *root) +@@ -3540,11 +3598,40 @@ finalize_nesting_tree_1 (struct nesting_info *root) /* If we created initialization statements, insert them. */ if (stmt_list) { @@ -5089,9 +7968,9 @@ index 1418e1f7f56..060072ba76e 100644 - bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); - gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); - gimple_bind_set_body (bind, stmt_list); -+ if (flag_off_stack_trampolines) ++ if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) + { -+ /* Handle the new, off stack trampolines. */ ++ /* Handle off-stack trampolines. */ + gbind *bind; + annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); + annotate_all_with_location (cleanup_list, DECL_SOURCE_LOCATION (context)); @@ -5102,7 +7981,7 @@ index 1418e1f7f56..060072ba76e 100644 + + if (cleanup_list != NULL) + { -+ /* We Maybe shouldn't be creating this try/finally if -fno-exceptions is ++ /* Maybe we shouldn't be creating this try/finally if -fno-exceptions is + in use. If this is the case, then maybe we should, instead, be + inserting the cleanup code onto every path out of this function? Not + yet figured out how we would do this. */ @@ -5127,49 +8006,40 @@ index 1418e1f7f56..060072ba76e 100644 /* If a chain_decl was created, then it needs to be registered with diff --git a/gcc/tree.cc b/gcc/tree.cc -index 207293c48cb..0a4770ec801 100644 +index 12dea81..8837041 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc -@@ -9852,6 +9852,23 @@ build_common_builtin_nodes (void) +@@ -9853,6 +9853,28 @@ build_common_builtin_nodes (void) "__builtin_nonlocal_goto", ECF_NORETURN | ECF_NOTHROW); + tree ptr_ptr_type_node = build_pointer_type (ptr_type_node); + -+ ftype = build_function_type_list (void_type_node, -+ ptr_type_node, // void *chain -+ ptr_type_node, // void *func -+ ptr_ptr_type_node, // void **dst -+ NULL_TREE); -+ local_define_builtin ("__builtin_nested_func_ptr_created", ftype, -+ BUILT_IN_NESTED_PTR_CREATED, -+ "__builtin_nested_func_ptr_created", ECF_NOTHROW); -+ -+ ftype = build_function_type_list (void_type_node, -+ NULL_TREE); -+ local_define_builtin ("__builtin_nested_func_ptr_deleted", ftype, -+ BUILT_IN_NESTED_PTR_DELETED, -+ "__builtin_nested_func_ptr_deleted", ECF_NOTHROW); ++ if (!builtin_decl_explicit_p (BUILT_IN_GCC_NESTED_PTR_CREATED)) ++ { ++ ftype = build_function_type_list (void_type_node, ++ ptr_type_node, // void *chain ++ ptr_type_node, // void *func ++ ptr_ptr_type_node, // void **dst ++ NULL_TREE); ++ local_define_builtin ("__builtin___gcc_nested_func_ptr_created", ftype, ++ BUILT_IN_GCC_NESTED_PTR_CREATED, ++ "__gcc_nested_func_ptr_created", ECF_NOTHROW); ++ } ++ ++ if (!builtin_decl_explicit_p (BUILT_IN_GCC_NESTED_PTR_DELETED)) ++ { ++ ftype = build_function_type_list (void_type_node, NULL_TREE); ++ local_define_builtin ("__builtin___gcc_nested_func_ptr_deleted", ftype, ++ BUILT_IN_GCC_NESTED_PTR_DELETED, ++ "__gcc_nested_func_ptr_deleted", ECF_NOTHROW); ++ } + ftype = build_function_type_list (void_type_node, ptr_type_node, ptr_type_node, NULL_TREE); local_define_builtin ("__builtin_setjmp_setup", ftype, -diff --git a/gotools/Makefile.in b/gotools/Makefile.in -index 2783b91ef4b..9739a79526b 100644 ---- a/gotools/Makefile.in -+++ b/gotools/Makefile.in -@@ -704,8 +704,8 @@ distclean-generic: - maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." --@NATIVE_FALSE@install-exec-local: - @NATIVE_FALSE@uninstall-local: -+@NATIVE_FALSE@install-exec-local: - clean: clean-am - - clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ diff --git a/intl/Makefile.in b/intl/Makefile.in -index 409d693c48e..5beebdc152c 100644 +index 409d693..5beebdc 100644 --- a/intl/Makefile.in +++ b/intl/Makefile.in @@ -54,7 +54,7 @@ CTAGS = @CTAGS@ @@ -5182,7 +8052,7 @@ index 409d693c48e..5beebdc152c 100644 HEADERS = \ gmo.h \ diff --git a/intl/configure b/intl/configure -index 03f40487a92..79bb5831a47 100755 +index 03f4048..79bb583 100755 --- a/intl/configure +++ b/intl/configure @@ -623,6 +623,8 @@ ac_header_list= @@ -5245,7 +8115,7 @@ index 03f40487a92..79bb5831a47 100755 cat >confcache <<\_ACEOF diff --git a/intl/configure.ac b/intl/configure.ac -index 16a740aa230..81aa831f59f 100644 +index 16a740a..81aa831 100644 --- a/intl/configure.ac +++ b/intl/configure.ac @@ -83,10 +83,25 @@ fi @@ -5277,7 +8147,7 @@ index 16a740aa230..81aa831f59f 100644 AC_CONFIG_FILES(Makefile config.intl) diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am -index c6c8d81c56a..d18738cd7e6 100644 +index c6c8d81..3bb32f3 100644 --- a/libatomic/Makefile.am +++ b/libatomic/Makefile.am @@ -65,8 +65,13 @@ libatomic_version_script = @@ -5291,12 +8161,12 @@ index c6c8d81c56a..d18738cd7e6 100644 -libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags) +libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \ -+ $(lt_host_flags) $(libatomic_darwin_rpath) ++ $(lt_host_flags) $(libatomic_darwin_rpath) libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \ fenv.c fence.c flag.c diff --git a/libatomic/Makefile.in b/libatomic/Makefile.in -index a0fa3dfc8cc..155c9aa9255 100644 +index a0fa3df..ef7ef45 100644 --- a/libatomic/Makefile.in +++ b/libatomic/Makefile.in @@ -417,7 +417,12 @@ noinst_LTLIBRARIES = libatomic_convenience.la @@ -5308,13 +8178,13 @@ index a0fa3dfc8cc..155c9aa9255 100644 +@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ +@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path +libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \ -+ $(lt_host_flags) $(libatomic_darwin_rpath) ++ $(lt_host_flags) $(libatomic_darwin_rpath) + libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c \ init.c fenv.c fence.c flag.c $(am__append_2) SIZEOBJS = load store cas exch fadd fsub fand fior fxor fnand tas diff --git a/libatomic/configure b/libatomic/configure -index e47d2d7fb35..7c687b932e7 100755 +index e47d2d7..7c1d46b 100755 --- a/libatomic/configure +++ b/libatomic/configure @@ -658,6 +658,8 @@ OPT_LDFLAGS @@ -5334,16 +8204,17 @@ index e47d2d7fb35..7c687b932e7 100755 enable_maintainer_mode enable_symvers enable_werror -@@ -1452,6 +1455,8 @@ Optional Features: +@@ -1452,6 +1455,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer -@@ -7608,7 +7613,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -7608,7 +7614,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -5352,7 +8223,7 @@ index e47d2d7fb35..7c687b932e7 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9581,6 +9586,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9581,6 +9587,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -5402,7 +8273,7 @@ index e47d2d7fb35..7c687b932e7 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9598,9 +9646,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9598,9 +9647,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -5418,25 +8289,25 @@ index e47d2d7fb35..7c687b932e7 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -11406,7 +11458,7 @@ else +@@ -11406,7 +11459,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11409 "configure" -+#line 11461 "configure" ++#line 11462 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11512,7 +11564,7 @@ else +@@ -11512,7 +11565,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11515 "configure" -+#line 11567 "configure" ++#line 11568 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11797,6 +11849,15 @@ fi +@@ -11797,6 +11850,15 @@ fi @@ -5452,7 +8323,7 @@ index e47d2d7fb35..7c687b932e7 100755 # For libtool versioning info, format is CURRENT:REVISION:AGE libtool_VERSION=3:0:2 -@@ -15924,6 +15985,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then +@@ -15924,6 +15986,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -5464,7 +8335,7 @@ index e47d2d7fb35..7c687b932e7 100755 if test -z "${LIBAT_BUILD_VERSIONED_SHLIB_TRUE}" && test -z "${LIBAT_BUILD_VERSIONED_SHLIB_FALSE}"; then as_fn_error $? "conditional \"LIBAT_BUILD_VERSIONED_SHLIB\" was never defined. diff --git a/libatomic/configure.ac b/libatomic/configure.ac -index 31304685dbd..20981f16f70 100644 +index 3130468..20981f1 100644 --- a/libatomic/configure.ac +++ b/libatomic/configure.ac @@ -156,6 +156,8 @@ AC_SUBST(enable_shared) @@ -5476,30 +8347,8 @@ index 31304685dbd..20981f16f70 100644 # For libtool versioning info, format is CURRENT:REVISION:AGE libtool_VERSION=3:0:2 AC_SUBST(libtool_VERSION) -diff --git a/libatomic/testsuite/lib/libatomic.exp b/libatomic/testsuite/lib/libatomic.exp -index 10f38475bc8..c6d645e9ae3 100644 ---- a/libatomic/testsuite/lib/libatomic.exp -+++ b/libatomic/testsuite/lib/libatomic.exp -@@ -148,11 +148,15 @@ proc libatomic_init { args } { - if { $blddir != "" } { - lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/" - lappend ALWAYS_CFLAGS "additional_flags=-I${blddir}" -- lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs" -+ if [istarget *-*-darwin*] { -+ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/.libs" -+ } else { -+ lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs" -+ } - } - lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.." - -- if [istarget *-*-darwin*] { -+ if [istarget *-*-darwin\[89\]*] { - lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc" - } - diff --git a/libbacktrace/configure b/libbacktrace/configure -index 6af2c04c81a..38b54957034 100755 +index 6af2c04..4a25e38 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -681,6 +681,8 @@ PIC_FLAG @@ -5519,16 +8368,17 @@ index 6af2c04c81a..38b54957034 100755 enable_largefile enable_cet enable_werror -@@ -1453,6 +1456,8 @@ Optional Features: +@@ -1453,6 +1456,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --disable-largefile omit support for large files --enable-cet enable Intel CET in target libraries [default=auto] --disable-werror disable building with -Werror -@@ -8010,7 +8015,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8010,7 +8016,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -5537,7 +8387,7 @@ index 6af2c04c81a..38b54957034 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9716,6 +9721,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9716,6 +9722,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -5587,7 +8437,7 @@ index 6af2c04c81a..38b54957034 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9733,9 +9781,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9733,9 +9782,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -5603,25 +8453,25 @@ index 6af2c04c81a..38b54957034 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -11541,7 +11593,7 @@ else +@@ -11541,7 +11594,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11544 "configure" -+#line 11596 "configure" ++#line 11597 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11647,7 +11699,7 @@ else +@@ -11647,7 +11700,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11650 "configure" -+#line 11702 "configure" ++#line 11703 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11886,6 +11938,15 @@ CC="$lt_save_CC" +@@ -11886,6 +11939,15 @@ CC="$lt_save_CC" @@ -5637,7 +8487,7 @@ index 6af2c04c81a..38b54957034 100755 # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; -@@ -14435,6 +14496,10 @@ if test -z "${HAVE_DWZ_TRUE}" && test -z "${HAVE_DWZ_FALSE}"; then +@@ -14435,6 +14497,10 @@ if test -z "${HAVE_DWZ_TRUE}" && test -z "${HAVE_DWZ_FALSE}"; then as_fn_error $? "conditional \"HAVE_DWZ\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -5649,7 +8499,7 @@ index 6af2c04c81a..38b54957034 100755 as_fn_error $? "conditional \"HAVE_ELF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac -index 39e6bf41e35..98b96fcb86f 100644 +index 39e6bf4..98b96fc 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -84,6 +84,8 @@ AM_CONDITIONAL(HAVE_DWZ, test "$DWZ" != "") @@ -5662,7 +8512,7 @@ index 39e6bf41e35..98b96fcb86f 100644 backtrace_supported=yes diff --git a/libcc1/configure b/libcc1/configure -index bae3b8712b6..9ee2b785eb1 100755 +index bae3b87..cd9acc3 100755 --- a/libcc1/configure +++ b/libcc1/configure @@ -787,6 +787,7 @@ with_pic @@ -5673,16 +8523,17 @@ index bae3b8712b6..9ee2b785eb1 100755 enable_cet with_gcc_major_version_only enable_werror_always -@@ -1439,6 +1440,8 @@ Optional Features: +@@ -1439,6 +1440,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-cet enable Intel CET in host libraries [default=auto] --enable-werror-always enable -Werror despite compiler version --enable-plugin enable plugin support -@@ -7271,7 +7274,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -7271,7 +7275,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -5691,7 +8542,7 @@ index bae3b8712b6..9ee2b785eb1 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8976,6 +8979,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8976,6 +8980,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -5741,7 +8592,7 @@ index bae3b8712b6..9ee2b785eb1 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -8993,9 +9039,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8993,9 +9040,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -5757,25 +8608,25 @@ index bae3b8712b6..9ee2b785eb1 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -10801,7 +10851,7 @@ else +@@ -10801,7 +10852,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10804 "configure" -+#line 10854 "configure" ++#line 10855 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -10907,7 +10957,7 @@ else +@@ -10907,7 +10958,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10910 "configure" -+#line 10960 "configure" ++#line 10961 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12189,6 +12239,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -12189,6 +12240,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -5825,7 +8676,7 @@ index bae3b8712b6..9ee2b785eb1 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -12206,12 +12299,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -12206,12 +12300,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -5850,7 +8701,7 @@ index bae3b8712b6..9ee2b785eb1 100755 fi diff --git a/libcody/Makefile.in b/libcody/Makefile.in -index bb87468cb9a..cb01b0092d8 100644 +index bb87468..cb01b00 100644 --- a/libcody/Makefile.in +++ b/libcody/Makefile.in @@ -31,7 +31,7 @@ endif @@ -5863,7 +8714,7 @@ index bb87468cb9a..cb01b0092d8 100644 # Per-source & per-directory compile flags (warning: recursive) diff --git a/libcody/configure b/libcody/configure -index da52a5cfca5..0e536c0ccb0 100755 +index da52a5c..0e536c0 100755 --- a/libcody/configure +++ b/libcody/configure @@ -591,7 +591,10 @@ configure_args @@ -5930,7 +8781,7 @@ index da52a5cfca5..0e536c0ccb0 100755 # Check whether --enable-exceptions was given. diff --git a/libcody/configure.ac b/libcody/configure.ac -index 960191ecb72..14e8dd4a226 100644 +index 960191e..14e8dd4 100644 --- a/libcody/configure.ac +++ b/libcody/configure.ac @@ -63,9 +63,31 @@ fi @@ -5968,7 +8819,7 @@ index 960191ecb72..14e8dd4a226 100644 NMS_ENABLE_EXCEPTIONS diff --git a/libcpp/configure b/libcpp/configure -index e9937cde330..1389ddab544 100755 +index e9937cd..1389dda 100755 --- a/libcpp/configure +++ b/libcpp/configure @@ -625,6 +625,8 @@ ac_includes_default="\ @@ -6022,7 +8873,7 @@ index e9937cde330..1389ddab544 100755 PICFLAG= fi diff --git a/libcpp/configure.ac b/libcpp/configure.ac -index 89ac99b04bd..b29b4d6acf1 100644 +index 89ac99b..b29b4d6 100644 --- a/libcpp/configure.ac +++ b/libcpp/configure.ac @@ -211,8 +211,23 @@ esac @@ -6051,8 +8902,63 @@ index 89ac99b04bd..b29b4d6acf1 100644 AC_SUBST(PICFLAG) # Enable Intel CET on Intel CET enabled host if jit is enabled. +diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h +index b8e50ae..26474a4 100644 +--- a/libcpp/include/cpplib.h ++++ b/libcpp/include/cpplib.h +@@ -756,6 +756,9 @@ struct cpp_callbacks + /* Callback to determine whether a built-in function is recognized. */ + int (*has_builtin) (cpp_reader *); + ++ /* Callback to determine whether a feature is available. */ ++ int (*has_feature) (cpp_reader *, bool); ++ + /* Callback that can change a user lazy into normal macro. */ + void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned); + +@@ -960,7 +963,9 @@ enum cpp_builtin_type + BT_HAS_STD_ATTRIBUTE, /* `__has_c_attribute(x)' */ + BT_HAS_BUILTIN, /* `__has_builtin(x)' */ + BT_HAS_INCLUDE, /* `__has_include(x)' */ +- BT_HAS_INCLUDE_NEXT /* `__has_include_next(x)' */ ++ BT_HAS_INCLUDE_NEXT, /* `__has_include_next(x)' */ ++ BT_HAS_FEATURE, /* `__has_feature(x)' */ ++ BT_HAS_EXTENSION /* `__has_extension(x)' */ + }; + + #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) +diff --git a/libcpp/init.cc b/libcpp/init.cc +index c508f06..465dafe 100644 +--- a/libcpp/init.cc ++++ b/libcpp/init.cc +@@ -433,6 +433,8 @@ static const struct builtin_macro builtin_array[] = + B("__has_builtin", BT_HAS_BUILTIN, true), + B("__has_include", BT_HAS_INCLUDE, true), + B("__has_include_next",BT_HAS_INCLUDE_NEXT, true), ++ B("__has_feature", BT_HAS_FEATURE, true), ++ B("__has_extension", BT_HAS_EXTENSION, true), + /* Keep builtins not used for -traditional-cpp at the end, and + update init_builtins() if any more are added. */ + B("_Pragma", BT_PRAGMA, true), +diff --git a/libcpp/macro.cc b/libcpp/macro.cc +index d4238d4..d2e8f9b 100644 +--- a/libcpp/macro.cc ++++ b/libcpp/macro.cc +@@ -677,6 +677,12 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, + number = builtin_has_include (pfile, node, + node->value.builtin == BT_HAS_INCLUDE_NEXT); + break; ++ ++ case BT_HAS_FEATURE: ++ case BT_HAS_EXTENSION: ++ number = pfile->cb.has_feature (pfile, ++ node->value.builtin == BT_HAS_FEATURE); ++ break; + } + + if (result == NULL) diff --git a/libdecnumber/configure b/libdecnumber/configure -index fb6db05565a..84bc4ffc767 100755 +index fb6db05..84bc4ff 100755 --- a/libdecnumber/configure +++ b/libdecnumber/configure @@ -626,6 +626,8 @@ ac_subst_vars='LTLIBOBJS @@ -6106,7 +9012,7 @@ index fb6db05565a..84bc4ffc767 100755 PICFLAG= fi diff --git a/libdecnumber/configure.ac b/libdecnumber/configure.ac -index aafd06f8a64..30a51ca410b 100644 +index aafd06f..30a51ca 100644 --- a/libdecnumber/configure.ac +++ b/libdecnumber/configure.ac @@ -100,8 +100,23 @@ AC_C_BIGENDIAN @@ -6136,7 +9042,7 @@ index aafd06f8a64..30a51ca410b 100644 # Enable Intel CET on Intel CET enabled host if jit is enabled. diff --git a/libffi/Makefile.am b/libffi/Makefile.am -index c6d6f849c53..d2ae0c04c7b 100644 +index c6d6f84..d2ae0c0 100644 --- a/libffi/Makefile.am +++ b/libffi/Makefile.am @@ -214,7 +214,12 @@ libffi.map: $(top_srcdir)/libffi.map.in @@ -6154,7 +9060,7 @@ index c6d6f849c53..d2ae0c04c7b 100644 AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src diff --git a/libffi/Makefile.in b/libffi/Makefile.in -index 5524a6a571e..34e77a45d1a 100644 +index 5524a6a..34e77a4 100644 --- a/libffi/Makefile.in +++ b/libffi/Makefile.in @@ -597,7 +597,11 @@ AM_CFLAGS = -Wall -g -fexceptions $(CET_FLAGS) $(am__append_2) @@ -6171,7 +9077,7 @@ index 5524a6a571e..34e77a45d1a 100644 AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) $(CET_FLAGS) diff --git a/libffi/configure b/libffi/configure -index 2bb9f8d83d6..069476bc2e6 100755 +index 2bb9f8d..0fae8b5 100755 --- a/libffi/configure +++ b/libffi/configure @@ -667,6 +667,8 @@ MAINT @@ -6191,16 +9097,17 @@ index 2bb9f8d83d6..069476bc2e6 100755 enable_maintainer_mode enable_pax_emutramp enable_debug -@@ -1465,6 +1468,8 @@ Optional Features: +@@ -1465,6 +1468,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer -@@ -7797,7 +7802,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -7797,7 +7803,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -6209,7 +9116,7 @@ index 2bb9f8d83d6..069476bc2e6 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9771,6 +9776,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9771,6 +9777,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -6259,7 +9166,7 @@ index 2bb9f8d83d6..069476bc2e6 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9788,9 +9836,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9788,9 +9837,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -6275,25 +9182,25 @@ index 2bb9f8d83d6..069476bc2e6 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -11596,7 +11648,7 @@ else +@@ -11596,7 +11649,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11599 "configure" -+#line 11651 "configure" ++#line 11652 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11702,7 +11754,7 @@ else +@@ -11702,7 +11755,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11705 "configure" -+#line 11757 "configure" ++#line 11758 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12578,6 +12630,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -12578,6 +12631,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -6343,7 +9250,7 @@ index 2bb9f8d83d6..069476bc2e6 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -12595,12 +12690,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -12595,12 +12691,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -6367,7 +9274,7 @@ index 2bb9f8d83d6..069476bc2e6 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -14970,6 +15073,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +@@ -14970,6 +15074,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # Only expand once: @@ -6382,7 +9289,7 @@ index 2bb9f8d83d6..069476bc2e6 100755 if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. -@@ -17115,6 +17226,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then +@@ -17115,6 +17227,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -6394,7 +9301,7 @@ index 2bb9f8d83d6..069476bc2e6 100755 as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libffi/configure.ac b/libffi/configure.ac -index 014d89d0423..716f20ae313 100644 +index 014d89d..716f20a 100644 --- a/libffi/configure.ac +++ b/libffi/configure.ac @@ -55,6 +55,7 @@ AC_SUBST(CET_FLAGS) @@ -6405,158 +9312,28 @@ index 014d89d0423..716f20ae313 100644 AC_CHECK_TOOL(READELF, readelf) -diff --git a/libffi/testsuite/lib/libffi.exp b/libffi/testsuite/lib/libffi.exp -index 15d3d5ebd73..611f5177c7a 100644 ---- a/libffi/testsuite/lib/libffi.exp -+++ b/libffi/testsuite/lib/libffi.exp -@@ -337,8 +337,13 @@ proc libffi-init { args } { - verbose "libffi_dir $libffi_dir" - if { $libffi_dir != "" } { - set libffi_dir [file dirname ${libffi_dir}] -- set libffi_link_flags "-L${libffi_dir}/.libs" -- lappend libffi_link_flags "-L${blddircxx}/src/.libs" -+ if [istarget *-*-darwin*] { -+ set libffi_link_flags "-B${libffi_dir}/.libs" -+ lappend libffi_link_flags "-B${blddircxx}/src/.libs" -+ } else { -+ set libffi_link_flags "-L${libffi_dir}/.libs" -+ lappend libffi_link_flags "-L${blddircxx}/src/.libs" -+ } - } - - set_ld_library_path_env_vars -@@ -382,7 +387,7 @@ proc libffi_target_compile { source dest type options } { - # Darwin needs a stack execution allowed flag. - - if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"] -- || [istarget "*-*-darwin2*"] } { -+ || [istarget "x86_64-*-darwin2*"] } { - lappend options "additional_flags=-Wl,-allow_stack_execute" - lappend options "additional_flags=-Wl,-search_paths_first" - } -diff --git a/libgcc/config.host b/libgcc/config.host -index 9d7212028d0..018dfe79d82 100644 ---- a/libgcc/config.host -+++ b/libgcc/config.host -@@ -82,7 +82,7 @@ m32c*-*-*) - cpu_type=m32c - tmake_file=t-fdpbit - ;; --aarch64*-*-*) -+aarch64*-*-* | arm64*-*-*) - cpu_type=aarch64 - ;; - alpha*-*-*) -@@ -251,7 +251,29 @@ case ${host} in - echo "Warning: libgcc configured to support macOS 10.5" 1>&2 - ;; - esac -- extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a" -+ # We are not using libtool to build the libs here, so we need to replicate -+ # a little of the logic around setting Darwin rpaths. Setting an explicit -+ # yes or no is honoured, otherwise we choose a suitable default. -+ # Sadly, this has to be kept in line with the rules in libtool.m4. -+ # This make fragment will override the setting in t-slibgcc-darwin so it -+ # must appear after it. -+ if test "x$enable_darwin_at_rpath" = "x"; then -+ echo "enable_darwin_at_rpath is unset" 1>&2 -+ case ${host} in -+ *-darwin[45678]*) ;; -+ *-darwin9* | *-darwin1[01234]*) ;; # We might default these on later. -+ *-darwin*) -+ echo "but is needed after macOS 10.11 (setting it on)" 1>&2 -+ enable_darwin_at_rpath=yes -+ ;; -+ esac -+ else -+ echo "enable_darwin_at_rpath is '$enable_darwin_at_rpath'" 1>&2 -+ fi -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ tmake_file="$tmake_file t-darwin-rpath " -+ fi -+ extra_parts="crt3.o crttms.o crttme.o libemutls_w.a " - ;; - *-*-dragonfly*) - tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip" -@@ -395,6 +417,17 @@ aarch64*-*-elf | aarch64*-*-rtems*) - tmake_file="${tmake_file} t-dfprules" - md_unwind_header=aarch64/aarch64-unwind.h - ;; -+aarch64*-*-darwin*) -+ extra_parts="$extra_parts crtfastmath.o" -+ tmake_file="${tmake_file} ${cpu_type}/t-aarch64" -+ tmake_file="${tmake_file} ${cpu_type}/t-lse " -+ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp " -+ tmake_file="${tmake_file} t-crtfm t-dfprules" -+ md_unwind_header=aarch64/aarch64-unwind.h -+ if test x$off_stack_trampolines = xyes; then -+ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" -+ fi -+ ;; - aarch64*-*-freebsd*) - extra_parts="$extra_parts crtfastmath.o" - tmake_file="${tmake_file} ${cpu_type}/t-aarch64" -@@ -423,6 +456,9 @@ aarch64*-*-linux*) - tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" - tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" - tmake_file="${tmake_file} t-dfprules" -+ if test x$off_stack_trampolines = xyes; then -+ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" -+ fi - ;; - aarch64*-*-vxworks7*) - extra_parts="$extra_parts crtfastmath.o" -@@ -691,12 +727,17 @@ hppa*-*-netbsd*) - i[34567]86-*-darwin*) - tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" - tm_file="$tm_file i386/darwin-lib.h" -+ extra_parts="$extra_parts libd10-uwfef.a " - extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" - ;; - x86_64-*-darwin*) - tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" - tm_file="$tm_file i386/darwin-lib.h" -+ extra_parts="$extra_parts libd10-uwfef.a " - extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -+ if test x$off_stack_trampolines = xyes; then -+ tmake_file="${tmake_file} i386/t-heap-trampoline" -+ fi - ;; - i[34567]86-*-elfiamcu) - tmake_file="$tmake_file i386/t-crtstuff t-softfp-sfdftf i386/32/t-softfp i386/32/t-iamcu i386/t-softfp t-softfp t-dfprules" -@@ -763,6 +804,9 @@ x86_64-*-linux*) - tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" - tm_file="${tm_file} i386/elf-lib.h" - md_unwind_header=i386/linux-unwind.h -+ if test x$off_stack_trampolines = xyes; then -+ tmake_file="${tmake_file} i386/t-heap-trampoline" -+ fi - ;; - x86_64-*-kfreebsd*-gnu) - extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -@@ -1171,12 +1215,14 @@ powerpc-*-darwin*) - # We build the darwin10 EH shim for Rosetta (running on x86 machines). - tm_file="$tm_file i386/darwin-lib.h" - tmake_file="$tmake_file rs6000/t-ppc64-fp rs6000/t-ibm-ldouble" -+ extra_parts="$extra_parts libd10-uwfef.a " - extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" - ;; - powerpc64-*-darwin*) - # We build the darwin10 EH shim for Rosetta (running on x86 machines). - tm_file="$tm_file i386/darwin-lib.h" - tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble" -+ extra_parts="$extra_parts libd10-uwfef.a " - extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" - ;; - powerpc*-*-freebsd*) -diff --git a/libgcc/config/aarch64/heap-trampoline.c b/libgcc/config/aarch64/heap-trampoline.c +diff --git a/libffi/doc/version.texi b/libffi/doc/version.texi +index f2b741e..6261b21 100644 +--- a/libffi/doc/version.texi ++++ b/libffi/doc/version.texi +@@ -1,4 +1,4 @@ +-@set UPDATED 27 June 2021 +-@set UPDATED-MONTH June 2021 ++@set UPDATED 31 August 2022 ++@set UPDATED-MONTH August 2022 + @set EDITION 3.4.2 + @set VERSION 3.4.2 +diff --git b/libgcc/config/aarch64/heap-trampoline.c b/libgcc/config/aarch64/heap-trampoline.c new file mode 100644 -index 00000000000..c8b83681ed7 +index 0000000..b2c69aa --- /dev/null +++ b/libgcc/config/aarch64/heap-trampoline.c -@@ -0,0 +1,172 @@ +@@ -0,0 +1,185 @@ +/* Copyright The GNU Toolchain Authors. */ + ++/* libc is required to allocate trampolines. */ ++#ifndef inhibit_libc ++ +#include +#include +#include @@ -6569,32 +9346,38 @@ index 00000000000..c8b83681ed7 +#include +#endif + ++/* HEAP_T_ATTR is provided to allow targets to build the exported functions ++ as weak definitions. */ ++#ifndef HEAP_T_ATTR ++# define HEAP_T_ATTR ++#endif ++ +void *allocate_trampoline_page (void); +int get_trampolines_per_page (void); +struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); +void *allocate_trampoline_page (void); + -+void __builtin_nested_func_ptr_created (void *chain, void *func, void **dst); -+void __builtin_nested_func_ptr_deleted (void); -+ -+#if defined(__gnu_linux__) -+static const uint32_t aarch64_trampoline_insns[] = { -+ 0xd503245f, /* hint 34 */ -+ 0x580000b1, /* ldr x17, .+20 */ -+ 0x580000d2, /* ldr x18, .+24 */ -+ 0xd61f0220, /* br x17 */ -+ 0xd5033f9f, /* dsb sy */ -+ 0xd5033fdf /* isb */ ++void __gcc_nested_func_ptr_created (void *chain, void *func, void **dst); ++void __gcc_nested_func_ptr_deleted (void); ++ ++#if defined(__linux__) ++static const unsigned char aarch64_trampoline_insns[6][4] = { ++ {0x5f, 0x24, 0x03, 0xd5}, /* hint 34 */ ++ {0xb1, 0x00, 0x00, 0x58}, /* ldr x17, .+20 */ ++ {0xd2, 0x00, 0x00, 0x58}, /* ldr x18, .+24 */ ++ {0x20, 0x02, 0x1f, 0xd6}, /* br x17 */ ++ {0x9f, 0x3f, 0x03, 0xd5}, /* dsb sy */ ++ {0xdf, 0x3f, 0x03, 0xd5} /* isb */ +}; + +#elif __APPLE__ -+static const uint32_t aarch64_trampoline_insns[] = { -+ 0xd503245f, /* hint 34 */ -+ 0x580000b1, /* ldr x17, .+20 */ -+ 0x580000d0, /* ldr x16, .+24 */ -+ 0xd61f0220, /* br x17 */ -+ 0xd5033f9f, /* dsb sy */ -+ 0xd5033fdf /* isb */ ++static const unsigned char aarch64_trampoline_insns[6][4] = { ++ {0x5f, 0x24, 0x03, 0xd5}, /* hint 34 */ ++ {0xb1, 0x00, 0x00, 0x58}, /* ldr x17, .+20 */ ++ {0xd0, 0x00, 0x00, 0x58}, /* ldr x16, .+24 */ ++ {0x20, 0x02, 0x1f, 0xd6}, /* br x17 */ ++ {0x9f, 0x3f, 0x03, 0xd5}, /* dsb sy */ ++ {0xdf, 0x3f, 0x03, 0xd5} /* isb */ +}; + +#else @@ -6602,7 +9385,7 @@ index 00000000000..c8b83681ed7 +#endif + +struct aarch64_trampoline { -+ uint32_t insns[6]; ++ unsigned char insns[6][4]; + void *func_ptr; + void *chain_ptr; +}; @@ -6630,7 +9413,7 @@ index 00000000000..c8b83681ed7 +{ + void *page; + -+#if defined(__gnu_linux__) ++#if defined(__linux__) + page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE, 0, 0); +#elif __APPLE__ @@ -6661,8 +9444,9 @@ index 00000000000..c8b83681ed7 + return p; +} + ++HEAP_T_ATTR +void -+__builtin_nested_func_ptr_created (void *chain, void *func, void **dst) ++__gcc_nested_func_ptr_created (void *chain, void *func, void **dst) +{ + if (tramp_ctrl_curr == NULL) + { @@ -6708,8 +9492,9 @@ index 00000000000..c8b83681ed7 + *dst = &trampoline->insns; +} + ++HEAP_T_ATTR +void -+__builtin_nested_func_ptr_deleted (void) ++__gcc_nested_func_ptr_deleted (void) +{ + if (tramp_ctrl_curr == NULL) + abort (); @@ -6727,8 +9512,10 @@ index 00000000000..c8b83681ed7 + tramp_ctrl_curr = prev; + } +} ++ ++#endif /* !inhibit_libc */ diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S -index dde3a28e07b..87ee33bc52a 100644 +index dde3a28..87ee33b 100644 --- a/libgcc/config/aarch64/lse.S +++ b/libgcc/config/aarch64/lse.S @@ -58,7 +58,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see @@ -6760,8 +9547,8 @@ index dde3a28e07b..87ee33bc52a 100644 + .text + .balign 16 + .private_extern _\name -+ .cfi_startproc +_\name: ++ .cfi_startproc + BTI_C +.endm + @@ -6782,7 +9569,7 @@ index dde3a28e07b..87ee33bc52a 100644 STARTFN NAME(cas) diff --git a/libgcc/config/aarch64/sfp-machine.h b/libgcc/config/aarch64/sfp-machine.h -index 97c38a34c86..b35e2c5e29a 100644 +index 97c38a3..b35e2c5 100644 --- a/libgcc/config/aarch64/sfp-machine.h +++ b/libgcc/config/aarch64/sfp-machine.h @@ -124,6 +124,27 @@ void __sfp_handle_exceptions (int); @@ -6813,9 +9600,9 @@ index 97c38a34c86..b35e2c5e29a 100644 # define _strong_alias(name, aliasname) \ extern __typeof (name) aliasname __attribute__ ((alias (#name))); +#endif -diff --git a/libgcc/config/aarch64/t-darwin b/libgcc/config/aarch64/t-darwin +diff --git b/libgcc/config/aarch64/t-darwin b/libgcc/config/aarch64/t-darwin new file mode 100644 -index 00000000000..f6ecda7b608 +index 0000000..f6ecda7 --- /dev/null +++ b/libgcc/config/aarch64/t-darwin @@ -0,0 +1,7 @@ @@ -6826,9 +9613,9 @@ index 00000000000..f6ecda7b608 +LIB2_SIDITI_CONV_FUNCS = yes + +BUILD_LIBGCCS1 = -diff --git a/libgcc/config/aarch64/t-heap-trampoline b/libgcc/config/aarch64/t-heap-trampoline +diff --git b/libgcc/config/aarch64/t-heap-trampoline b/libgcc/config/aarch64/t-heap-trampoline new file mode 100644 -index 00000000000..3f70c2cd0c0 +index 0000000..6468fb8 --- /dev/null +++ b/libgcc/config/aarch64/t-heap-trampoline @@ -0,0 +1,20 @@ @@ -6850,16 +9637,19 @@ index 00000000000..3f70c2cd0c0 +# along with GCC; see the file COPYING3. If not see +# . + -+LIB2ADD += $(srcdir)/config/aarch64/heap-trampoline.c -+HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=11.0 -diff --git a/libgcc/config/i386/heap-trampoline.c b/libgcc/config/i386/heap-trampoline.c ++LIB2ADDEH += $(srcdir)/config/aarch64/heap-trampoline.c ++LIB2ADDEHSHARED += $(srcdir)/config/aarch64/heap-trampoline.c +diff --git b/libgcc/config/i386/heap-trampoline.c b/libgcc/config/i386/heap-trampoline.c new file mode 100644 -index 00000000000..96e13bf828e +index 0000000..2e8df1c --- /dev/null +++ b/libgcc/config/i386/heap-trampoline.c -@@ -0,0 +1,172 @@ +@@ -0,0 +1,255 @@ +/* Copyright The GNU Toolchain Authors. */ + ++/* libc is required to allocate trampolines. */ ++#ifndef inhibit_libc ++ +#include +#include +#include @@ -6872,39 +9662,109 @@ index 00000000000..96e13bf828e +#include +#endif + ++/* HEAP_T_ATTR is provided to allow targets to build the exported functions ++ as weak definitions. */ ++#ifndef HEAP_T_ATTR ++# define HEAP_T_ATTR ++#endif ++ +void *allocate_trampoline_page (void); +int get_trampolines_per_page (void); +struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); +void *allocate_trampoline_page (void); + -+void __builtin_nested_func_ptr_created (void *chain, void *func, void **dst); -+void __builtin_nested_func_ptr_deleted (void); ++void __gcc_nested_func_ptr_created (void *chain, void *func, void **dst); ++void __gcc_nested_func_ptr_deleted (void); ++ ++#if __x86_64__ ++ ++#ifdef __LP64__ ++static const uint8_t trampoline_insns[] = { ++#if defined __CET__ && (__CET__ & 1) != 0 ++ /* endbr64. */ ++ 0xf3, 0x0f, 0x1e, 0xfa, ++#endif ++ ++ /* movabsq $,%r11 */ ++ 0x49, 0xbb, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* movabsq $,%r10 */ ++ 0x49, 0xba, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* rex.WB jmpq *%r11 */ ++ 0x41, 0xff, 0xe3, + ++ /* Pad to the multiple of 4 bytes. */ ++ 0x90 ++}; ++#else +static const uint8_t trampoline_insns[] = { -+ /* movabs $,%r11 */ -+ 0x49, 0xbb, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++#if defined __CET__ && (__CET__ & 1) != 0 ++ /* endbr64. */ ++ 0xf3, 0x0f, 0x1e, 0xfa, ++#endif + -+ /* movabs $,%r10 */ -+ 0x49, 0xba, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* movl $,%r11d */ ++ 0x41, 0xbb, ++ 0x00, 0x00, 0x00, 0x00, ++ ++ /* movl $,%r10d */ ++ 0x41, 0xba, ++ 0x00, 0x00, 0x00, 0x00, + + /* rex.WB jmpq *%r11 */ -+ 0x41, 0xff, 0xe3 ++ 0x41, 0xff, 0xe3, ++ ++ /* Pad to the multiple of 4 bytes. */ ++ 0x90 +}; ++#endif + +union ix86_trampoline { + uint8_t insns[sizeof(trampoline_insns)]; + + struct __attribute__((packed)) fields { ++#if defined __CET__ && (__CET__ & 1) != 0 ++ uint8_t endbr64[4]; ++#endif + uint8_t insn_0[2]; + void *func_ptr; + uint8_t insn_1[2]; + void *chain_ptr; + uint8_t insn_2[3]; ++ uint8_t pad; ++ } fields; ++}; ++ ++#elif __i386__ ++ ++static const uint8_t trampoline_insns[] = { ++ /* movl $,%ecx */ ++ 0xb9, ++ 0x00, 0x00, 0x00, 0x00, ++ ++ /* jmpl -. */ ++ 0xe9, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++union ix86_trampoline { ++ uint8_t insns[sizeof(trampoline_insns)]; ++ ++ struct __attribute__((packed)) fields { ++ uint8_t insn_0[1]; ++ void *chain_ptr; ++ uint8_t insn_1[1]; ++ uintptr_t func_offset; + } fields; +}; + ++#else ++#error unsupported architecture/ABI ++#endif ++ +struct tramp_ctrl_data +{ + struct tramp_ctrl_data *prev; @@ -6964,8 +9824,9 @@ index 00000000000..96e13bf828e + return p; +} + ++HEAP_T_ATTR +void -+__builtin_nested_func_ptr_created (void *chain, void *func, void **dst) ++__gcc_nested_func_ptr_created (void *chain, void *func, void **dst) +{ + if (tramp_ctrl_curr == NULL) + { @@ -6995,8 +9856,14 @@ index 00000000000..96e13bf828e + + memcpy (trampoline->insns, trampoline_insns, + sizeof(trampoline_insns)); -+ trampoline->fields.func_ptr = func; + trampoline->fields.chain_ptr = chain; ++#if __x86_64__ ++ trampoline->fields.func_ptr = func; ++#elif __i386__ ++ uintptr_t off_add = (uintptr_t) &trampoline->fields.func_offset; ++ off_add += 4; ++ trampoline->fields.func_offset = (uintptr_t)func - off_add; ++#endif + +#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 + /* Re-enable write protection. */ @@ -7011,8 +9878,9 @@ index 00000000000..96e13bf828e + *dst = &trampoline->insns; +} + ++HEAP_T_ATTR +void -+__builtin_nested_func_ptr_deleted (void) ++__gcc_nested_func_ptr_deleted (void) +{ + if (tramp_ctrl_curr == NULL) + abort (); @@ -7030,9 +9898,21 @@ index 00000000000..96e13bf828e + tramp_ctrl_curr = prev; + } +} -diff --git a/libgcc/config/i386/t-heap-trampoline b/libgcc/config/i386/t-heap-trampoline ++ ++#endif /* !inhibit_libc */ +diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin +index 4c18da1..84efe35 100644 +--- a/libgcc/config/i386/t-darwin ++++ b/libgcc/config/i386/t-darwin +@@ -5,5 +5,3 @@ LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf + # Extra symbols for this port. + SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-darwin.ver + +-# Build a legacy libgcc_s.1 +-BUILD_LIBGCCS1 = YES +diff --git b/libgcc/config/i386/t-heap-trampoline b/libgcc/config/i386/t-heap-trampoline new file mode 100644 -index 00000000000..76f438d9529 +index 0000000..5cd11f5 --- /dev/null +++ b/libgcc/config/i386/t-heap-trampoline @@ -0,0 +1,20 @@ @@ -7054,18 +9934,71 @@ index 00000000000..76f438d9529 +# along with GCC; see the file COPYING3. If not see +# . + -+LIB2ADD += $(srcdir)/config/i386/heap-trampoline.c -+HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=10.8 -diff --git a/libgcc/config/t-darwin-rpath b/libgcc/config/t-darwin-rpath ++LIB2ADDEH += $(srcdir)/config/i386/heap-trampoline.c ++LIB2ADDEHSHARED += $(srcdir)/config/i386/heap-trampoline.c +diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin +index 183d0df..8b513bd 100644 +--- a/libgcc/config/rs6000/t-darwin ++++ b/libgcc/config/rs6000/t-darwin +@@ -56,6 +56,3 @@ unwind-dw2_s.o: HOST_LIBGCC2_CFLAGS += -maltivec + unwind-dw2.o: HOST_LIBGCC2_CFLAGS += -maltivec + + LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c +- +-# Build a legacy libgcc_s.1 +-BUILD_LIBGCCS1 = YES +diff --git b/libgcc/config/rs6000/t-darwin-libgccs1 b/libgcc/config/rs6000/t-darwin-libgccs1 +new file mode 100644 +index 0000000..7dc252e +--- /dev/null ++++ b/libgcc/config/rs6000/t-darwin-libgccs1 +@@ -0,0 +1,3 @@ ++ ++# Build a legacy libgcc_s.1 ++BUILD_LIBGCCS1 = YES +\ No newline at end of file +diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin +index a3bb70c..0f65b54 100644 +--- a/libgcc/config/t-darwin ++++ b/libgcc/config/t-darwin +@@ -51,5 +51,18 @@ LIB2ADDEH = $(srcdir)/unwind-dw2.c \ + # Do not build a shared unwind lib by default. + LIBEHSOBJS= + ++# Make heap trampoline helpers weak definitions so that we can merge them from ++# multiple DSOs. ++heap-trampoline.o: HOST_LIBGCC2_CFLAGS += \ ++ -DHEAP_T_ATTR='__attribute__((__weak__,__visibility__("default")))' ++heap-trampoline_s.o: HOST_LIBGCC2_CFLAGS += \ ++ -DHEAP_T_ATTR='__attribute__((__weak__,__visibility__("default")))' ++ ++# Make a heap trampoline support CRT so that it can be linked optionally, use ++# the shared version so that we can link with DSOs. ++libheapt_w.a: heap-trampoline_s.o ++ $(AR_CREATE_FOR_TARGET) $@ $< ++ $(RANLIB_FOR_TARGET) $@ ++ + # Symbols for all the sub-ports. + SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/libgcc-libsystem.ver +diff --git b/libgcc/config/t-darwin-min-11 b/libgcc/config/t-darwin-min-11 +new file mode 100644 +index 0000000..4009d41 +--- /dev/null ++++ b/libgcc/config/t-darwin-min-11 +@@ -0,0 +1,3 @@ ++# Support building with -mmacosx-version-min back to macOS 11. ++DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=11 ++DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=11 +diff --git b/libgcc/config/t-darwin-rpath b/libgcc/config/t-darwin-rpath new file mode 100644 -index 00000000000..e73d7f378b0 +index 0000000..e73d7f3 --- /dev/null +++ b/libgcc/config/t-darwin-rpath @@ -0,0 +1,2 @@ +# Use @rpath and add a search path to exes and dylibs that depend on this. +SHLIB_RPATH = @rpath diff --git a/libgcc/config/t-slibgcc-darwin b/libgcc/config/t-slibgcc-darwin -index cb0cbbdb1c5..da4886848e8 100644 +index cb0cbbd..da48868 100644 --- a/libgcc/config/t-slibgcc-darwin +++ b/libgcc/config/t-slibgcc-darwin @@ -1,4 +1,4 @@ @@ -7146,183 +10079,183 @@ index cb0cbbdb1c5..da4886848e8 100644 done $(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T* rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T* -diff --git a/libgcc/configure b/libgcc/configure -index be5d45f1755..85fc0b08c82 100755 ---- a/libgcc/configure -+++ b/libgcc/configure -@@ -630,7 +630,6 @@ LIPO - AR - toolexeclibdir - toolexecdir --enable_gcov - target_subdir - host_subdir - build_subdir -@@ -654,6 +653,8 @@ build_cpu - build - with_aix_soname - enable_vtable_verify -+enable_gcov -+off_stack_trampolines - enable_shared - libgcc_topdir - target_alias -@@ -701,6 +702,8 @@ with_target_subdir - with_cross_host - with_ld - enable_shared -+enable_off_stack_trampolines -+enable_gcov - enable_vtable_verify - with_aix_soname - enable_version_specific_runtime_libs -@@ -708,7 +711,6 @@ with_toolexeclibdir - with_slibdir - enable_maintainer_mode - with_build_libsubdir --enable_gcov - enable_largefile - enable_decimal_float - with_system_libunwind -@@ -1342,12 +1344,15 @@ Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-shared don't provide a shared libgcc -+ --enable-off-stack-trampolines -+ Specify whether to support generating off-stack trampolines -+ -+ --disable-gcov don't provide libgcov and related host tools - --enable-vtable-verify Enable vtable verification feature - --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer -- --disable-gcov don't provide libgcov and related host tools - --disable-largefile omit support for large files - --enable-decimal-float={no,yes,bid,dpd} - enable decimal float extension to C. Selecting 'bid' -@@ -2252,6 +2257,48 @@ fi - - - -+# Check whether --enable-off-stack-trampolines was given. -+if test "${enable_off_stack_trampolines+set}" = set; then : -+ enableval=$enable_off_stack_trampolines; -+case "$target" in -+ x86_64-*-linux* | x86_64-*-darwin1[4-9]* | x86_64-*-darwin2*) -+ off_stack_trampolines=$enableval -+ ;; -+ aarch64*-*-linux* ) -+ off_stack_trampolines=$enableval -+ ;; -+ aarch64*-*darwin* ) -+ off_stack_trampolines=$enableval -+ ;; -+ *) -+ as_fn_error $? "Configure option --enable-off-stack-trampolines is not supported \ -+for this platform" "$LINENO" 5 -+ off_stack_trampolines=no -+ ;; -+esac -+else -+ -+case "$target" in -+ *-*-darwin2*) -+ off_stack_trampolines=yes -+ ;; -+ *) -+ off_stack_trampolines=no -+ ;; -+esac -+fi -+ -+ -+ -+# Check whether --enable-gcov was given. -+if test "${enable_gcov+set}" = set; then : -+ enableval=$enable_gcov; -+else -+ enable_gcov=yes -+fi -+ -+ -+ - # Check whether --enable-vtable-verify was given. - if test "${enable_vtable_verify+set}" = set; then : - enableval=$enable_vtable_verify; case "$enableval" in -diff --git a/libgcc/configure.ac b/libgcc/configure.ac -index 2fc9d5d7c93..7d11bf00142 100644 ---- a/libgcc/configure.ac -+++ b/libgcc/configure.ac -@@ -68,6 +68,40 @@ AC_ARG_ENABLE(shared, - ], [enable_shared=yes]) - AC_SUBST(enable_shared) - -+AC_ARG_ENABLE([off-stack-trampolines], -+ [AS_HELP_STRING([--enable-off-stack-trampolines] -+ [Specify whether to support generating off-stack trampolines])],[ -+case "$target" in -+ x86_64-*-linux* | x86_64-*-darwin1[[4-9]]* | x86_64-*-darwin2*) -+ off_stack_trampolines=$enableval -+ ;; -+ aarch64*-*-linux* ) -+ off_stack_trampolines=$enableval -+ ;; -+ aarch64*-*darwin* ) -+ off_stack_trampolines=$enableval -+ ;; -+ *) -+ AC_MSG_ERROR([Configure option --enable-off-stack-trampolines is not supported \ -+for this platform]) -+ off_stack_trampolines=no -+ ;; -+esac],[ -+case "$target" in -+ *-*-darwin2*) -+ off_stack_trampolines=yes -+ ;; -+ *) -+ off_stack_trampolines=no -+ ;; -+esac]) -+AC_SUBST(off_stack_trampolines) -+ -+AC_ARG_ENABLE(gcov, -+[ --disable-gcov don't provide libgcov and related host tools], -+[], [enable_gcov=yes]) -+AC_SUBST(enable_gcov) -+ - AC_ARG_ENABLE(vtable-verify, - [ --enable-vtable-verify Enable vtable verification feature ], - [case "$enableval" in +diff --git a/libgcc/config.host b/libgcc/config.host +index c94d69d..e96b913 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -82,7 +82,7 @@ m32c*-*-*) + cpu_type=m32c + tmake_file=t-fdpbit + ;; +-aarch64*-*-*) ++aarch64*-*-* | arm64*-*-*) + cpu_type=aarch64 + ;; + alpha*-*-*) +@@ -233,16 +233,21 @@ case ${host} in + ;; + esac + tmake_file="$tmake_file t-slibgcc-darwin" +- # newer toolsets produce warnings when building for unsupported versions. + case ${host} in +- *-*-darwin1[89]* | *-*-darwin2* ) +- tmake_file="t-darwin-min-8 $tmake_file" ++ x86_64-*-darwin2[0-3]*) ++ tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file" ++ ;; ++ *-*-darwin2*) ++ tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file" ++ ;; ++ *-*-darwin1[89]*) ++ tmake_file="t-darwin-min-8 t-darwin-libgccs1 $tmake_file" + ;; + *-*-darwin9* | *-*-darwin1[0-7]*) +- tmake_file="t-darwin-min-5 $tmake_file" ++ tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file" + ;; + *-*-darwin[4-8]*) +- tmake_file="t-darwin-min-1 $tmake_file" ++ tmake_file="t-darwin-min-1 t-darwin-libgccs1 $tmake_file" + ;; + *) + # Fall back to configuring for the oldest system known to work with +@@ -251,7 +256,29 @@ case ${host} in + echo "Warning: libgcc configured to support macOS 10.5" 1>&2 + ;; + esac +- extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a" ++ # We are not using libtool to build the libs here, so we need to replicate ++ # a little of the logic around setting Darwin rpaths. Setting an explicit ++ # yes or no is honoured, otherwise we choose a suitable default. ++ # Sadly, this has to be kept in line with the rules in libtool.m4. ++ # This make fragment will override the setting in t-slibgcc-darwin so it ++ # must appear after it. ++ if test "x$enable_darwin_at_rpath" = "x"; then ++ echo "enable_darwin_at_rpath is unset" 1>&2 ++ case ${host} in ++ *-darwin[45678]*) ;; ++ *-darwin9* | *-darwin1[01234]*) ;; # We might default these on later. ++ *-darwin*) ++ echo "but is needed after macOS 10.11 (setting it on)" 1>&2 ++ enable_darwin_at_rpath=yes ++ ;; ++ esac ++ else ++ echo "enable_darwin_at_rpath is '$enable_darwin_at_rpath'" 1>&2 ++ fi ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ tmake_file="$tmake_file t-darwin-rpath " ++ fi ++ extra_parts="crt3.o crttms.o crttme.o libemutls_w.a " + ;; + *-*-dragonfly*) + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip" +@@ -395,6 +422,15 @@ aarch64*-*-elf | aarch64*-*-rtems*) + tmake_file="${tmake_file} t-dfprules" + md_unwind_header=aarch64/aarch64-unwind.h + ;; ++aarch64*-*-darwin*) ++ extra_parts="$extra_parts crtfastmath.o libheapt_w.a" ++ tmake_file="${tmake_file} ${cpu_type}/t-aarch64" ++ tmake_file="${tmake_file} ${cpu_type}/t-lse " ++ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp " ++ tmake_file="${tmake_file} t-crtfm t-dfprules" ++ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" ++ md_unwind_header=aarch64/aarch64-unwind.h ++ ;; + aarch64*-*-freebsd*) + extra_parts="$extra_parts crtfastmath.o" + tmake_file="${tmake_file} ${cpu_type}/t-aarch64" +@@ -423,6 +459,7 @@ aarch64*-*-linux*) + tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" + tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" + tmake_file="${tmake_file} t-dfprules" ++ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" + ;; + aarch64*-*-vxworks7*) + extra_parts="$extra_parts crtfastmath.o" +@@ -691,12 +728,18 @@ hppa*-*-netbsd*) + i[34567]86-*-darwin*) + tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" + tm_file="$tm_file i386/darwin-lib.h" +- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" ++ extra_parts="$extra_parts libd10-uwfef.a " ++ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o" ++ extra_parts="$extra_parts crtfastmath.o libheapt_w.a" ++ tmake_file="${tmake_file} i386/t-heap-trampoline" + ;; + x86_64-*-darwin*) + tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" + tm_file="$tm_file i386/darwin-lib.h" +- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" ++ extra_parts="$extra_parts libd10-uwfef.a " ++ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o" ++ extra_parts="$extra_parts crtfastmath.o libheapt_w.a" ++ tmake_file="${tmake_file} i386/t-heap-trampoline" + ;; + i[34567]86-*-elfiamcu) + tmake_file="$tmake_file i386/t-crtstuff t-softfp-sfdftf i386/32/t-softfp i386/32/t-iamcu i386/t-softfp t-softfp t-dfprules" +@@ -746,6 +789,7 @@ i[34567]86-*-linux*) + tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" + tm_file="${tm_file} i386/elf-lib.h" + md_unwind_header=i386/linux-unwind.h ++ tmake_file="${tmake_file} i386/t-heap-trampoline" + ;; + i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-kopensolaris*-gnu) + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" +@@ -763,6 +807,7 @@ x86_64-*-linux*) + tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" + tm_file="${tm_file} i386/elf-lib.h" + md_unwind_header=i386/linux-unwind.h ++ tmake_file="${tmake_file} i386/t-heap-trampoline" + ;; + x86_64-*-kfreebsd*-gnu) + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" +@@ -1171,12 +1216,14 @@ powerpc-*-darwin*) + # We build the darwin10 EH shim for Rosetta (running on x86 machines). + tm_file="$tm_file i386/darwin-lib.h" + tmake_file="$tmake_file rs6000/t-ppc64-fp rs6000/t-ibm-ldouble" ++ extra_parts="$extra_parts libd10-uwfef.a " + extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" + ;; + powerpc64-*-darwin*) + # We build the darwin10 EH shim for Rosetta (running on x86 machines). + tm_file="$tm_file i386/darwin-lib.h" + tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble" ++ extra_parts="$extra_parts libd10-uwfef.a " + extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" + ;; + powerpc*-*-freebsd*) diff --git a/libgcc/libgcc-std.ver.in b/libgcc/libgcc-std.ver.in -index c4f87a50e70..a48f4899eb6 100644 +index c4f87a5..ad854bf 100644 --- a/libgcc/libgcc-std.ver.in +++ b/libgcc/libgcc-std.ver.in -@@ -1943,4 +1943,7 @@ GCC_4.8.0 { - GCC_7.0.0 { +@@ -1944,3 +1944,9 @@ GCC_7.0.0 { __PFX__divmoddi4 __PFX__divmodti4 -+ -+ __builtin_nested_func_ptr_created -+ __builtin_nested_func_ptr_deleted } ++ ++%inherit GCC_14.0.0 GCC_7.0.0 ++GCC_14.0.0 { ++ __gcc_nested_func_ptr_created ++ __gcc_nested_func_ptr_deleted ++} diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h -index 3ec9bbd8164..ac7eaab4f01 100644 +index 3ec9bbd..a7a5dff 100644 --- a/libgcc/libgcc2.h +++ b/libgcc/libgcc2.h @@ -29,6 +29,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #pragma GCC visibility push(default) #endif -+extern void __builtin_nested_func_ptr_created (void *, void *, void **); -+extern void __builtin_nested_func_ptr_deleted (void); ++extern void __gcc_nested_func_ptr_created (void *, void *, void **); ++extern void __gcc_nested_func_ptr_deleted (void); + extern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t); extern void __clear_cache (void *, void *); extern void __eprintf (const char *, const char *, unsigned int, const char *) diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am -index 454ad12e701..2bc2e57919d 100644 +index 454ad12..3d21373 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -37,6 +37,11 @@ else @@ -7331,7 +10264,7 @@ index 454ad12e701..2bc2e57919d 100644 endif +extra_darwin_ldflags_libgfortran = @extra_ldflags_libgfortran@ +if ENABLE_DARWIN_AT_RPATH -+extra_darwin_ldflags_libgfortran += -Wc,-nodefaultrpaths ++extra_darwin_ldflags_libgfortran += -Wc,-nodefaultrpaths +extra_darwin_ldflags_libgfortran += -Wl,-rpath,@loader_path +endif @@ -7347,7 +10280,7 @@ index 454ad12e701..2bc2e57919d 100644 libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in -index 23df0761096..ed0d05f502a 100644 +index 23df076..ed0d05f 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -91,8 +91,10 @@ POST_UNINSTALL = : @@ -7460,7 +10393,7 @@ index 23df0761096..ed0d05f502a 100644 $(gfor_helper_src) $(gfor_ieee_src) $(gfor_io_headers) $(gfor_specific_src) diff --git a/libgfortran/configure b/libgfortran/configure -index d7c3a5e27a0..57a2c9d4946 100755 +index d7c3a5e..feb75f6 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -654,6 +654,8 @@ extra_ldflags_libgfortran @@ -7480,16 +10413,17 @@ index d7c3a5e27a0..57a2c9d4946 100755 enable_largefile enable_libquadmath_support with_gcc_major_version_only -@@ -1478,6 +1481,8 @@ Optional Features: +@@ -1478,6 +1481,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --disable-largefile omit support for large files --disable-libquadmath-support disable libquadmath support for Fortran -@@ -9235,7 +9240,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -9235,7 +9241,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -7498,7 +10432,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10945,6 +10950,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10945,6 +10951,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -7548,7 +10482,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10962,9 +11010,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10962,9 +11011,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -7564,25 +10498,25 @@ index d7c3a5e27a0..57a2c9d4946 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12791,7 +12843,7 @@ else +@@ -12791,7 +12844,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12794 "configure" -+#line 12846 "configure" ++#line 12847 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12897,7 +12949,7 @@ else +@@ -12897,7 +12950,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12900 "configure" -+#line 12952 "configure" ++#line 12953 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13299,6 +13351,14 @@ esac +@@ -13299,6 +13352,14 @@ esac @@ -7597,7 +10531,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 #AC_MSG_NOTICE([====== Finished libtool configuration]) ; sleep 10 # We need gfortran to compile parts of the library -@@ -14942,6 +15002,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -14942,6 +15003,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -7647,7 +10581,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 archive_cmds_need_lc_FC=no hardcode_direct_FC=no hardcode_automatic_FC=yes -@@ -14959,9 +15062,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -14959,9 +15063,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -7663,7 +10597,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -16234,9 +16341,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +@@ -16234,9 +16342,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # extra LD Flags which are required for targets @@ -7676,7 +10610,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 extra_ldflags_libgfortran=-Wl,-single_module ;; esac -@@ -31597,6 +31705,10 @@ if test -z "${HAVE_HWCAP_TRUE}" && test -z "${HAVE_HWCAP_FALSE}"; then +@@ -31597,6 +31706,10 @@ if test -z "${HAVE_HWCAP_TRUE}" && test -z "${HAVE_HWCAP_FALSE}"; then as_fn_error $? "conditional \"HAVE_HWCAP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -7688,7 +10622,7 @@ index d7c3a5e27a0..57a2c9d4946 100755 as_fn_error $? "conditional \"IEEE_SUPPORT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac -index 07b9a48a19f..4ee63cf723e 100644 +index 07b9a48..4ee63cf 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -282,6 +282,7 @@ LT_LIB_M @@ -7713,7 +10647,7 @@ index 07b9a48a19f..4ee63cf723e 100644 ;; esac diff --git a/libgm2/Makefile.am b/libgm2/Makefile.am -index 95df3ed7a30..aa35e747c9a 100644 +index 95df3ed..aa35e74 100644 --- a/libgm2/Makefile.am +++ b/libgm2/Makefile.am @@ -46,6 +46,12 @@ SUBDIRS = libm2min libm2log libm2cor libm2iso libm2pim @@ -7740,9 +10674,30 @@ index 95df3ed7a30..aa35e747c9a 100644 # Subdir rules rely on $(FLAGS_TO_PASS) FLAGS_TO_PASS = $(AM_MAKEFLAGS) diff --git a/libgm2/Makefile.in b/libgm2/Makefile.in -index d9950065de1..f97f6d0812d 100644 +index 2b9592b..f97f6d0 100644 --- a/libgm2/Makefile.in +++ b/libgm2/Makefile.in +@@ -90,15 +90,15 @@ host_triplet = @host@ + target_triplet = @target@ + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../config/acx.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ +- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac ++ $(top_srcdir)/../config/override.m4 \ ++ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ ++ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ ++ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ @@ -344,6 +344,8 @@ GM2_SRC = $(GCC_DIR)/m2 SUBDIRS = libm2min libm2log libm2cor libm2iso libm2pim GM2_BUILDDIR := $(shell pwd) @@ -7762,8 +10717,32 @@ index d9950065de1..f97f6d0812d 100644 # Subdir rules rely on $(FLAGS_TO_PASS) +diff --git a/libgm2/aclocal.m4 b/libgm2/aclocal.m4 +index c352303..832065f 100644 +--- a/libgm2/aclocal.m4 ++++ b/libgm2/aclocal.m4 +@@ -1187,14 +1187,14 @@ AC_SUBST([am__tar]) + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../libtool.m4]) +-m4_include([../ltoptions.m4]) +-m4_include([../ltsugar.m4]) +-m4_include([../ltversion.m4]) +-m4_include([../lt~obsolete.m4]) + m4_include([../config/acx.m4]) + m4_include([../config/depstand.m4]) + m4_include([../config/lead-dot.m4]) + m4_include([../config/multi.m4]) + m4_include([../config/no-executables.m4]) + m4_include([../config/override.m4]) ++m4_include([../libtool.m4]) ++m4_include([../ltoptions.m4]) ++m4_include([../ltsugar.m4]) ++m4_include([../ltversion.m4]) ++m4_include([../lt~obsolete.m4]) diff --git a/libgm2/configure b/libgm2/configure -index 8eb1bc81c66..d1a056a8a3b 100755 +index bf35b40..64f4f80 100755 --- a/libgm2/configure +++ b/libgm2/configure @@ -649,6 +649,8 @@ GM2_FOR_TARGET @@ -7783,16 +10762,17 @@ index 8eb1bc81c66..d1a056a8a3b 100755 with_gcc_major_version_only ' ac_precious_vars='build_alias -@@ -1456,6 +1459,8 @@ Optional Features: +@@ -1456,6 +1459,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -6575,10 +6580,6 @@ fi +@@ -6611,10 +6617,6 @@ fi @@ -7803,7 +10783,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -@@ -9149,7 +9150,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -9185,7 +9187,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -7812,7 +10792,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9197,6 +9198,8 @@ done +@@ -9233,6 +9235,8 @@ done @@ -7821,7 +10801,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 enable_win32_dll=no -@@ -10860,6 +10863,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10896,6 +10900,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -7871,7 +10851,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10877,9 +10923,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10913,9 +10960,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -7887,25 +10867,25 @@ index 8eb1bc81c66..d1a056a8a3b 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12706,7 +12756,7 @@ else +@@ -12742,7 +12793,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF --#line 12709 "configure" -+#line 12759 "configure" +-#line 12745 "configure" ++#line 12796 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12812,7 +12862,7 @@ else +@@ -12848,7 +12899,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF --#line 12815 "configure" -+#line 12865 "configure" +-#line 12851 "configure" ++#line 12902 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13694,6 +13744,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13730,6 +13781,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -7955,7 +10935,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -13711,12 +13804,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13747,12 +13841,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -7979,7 +10959,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -16090,6 +16191,21 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +@@ -16126,6 +16228,21 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu @@ -8001,7 +10981,7 @@ index 8eb1bc81c66..d1a056a8a3b 100755 if test "${multilib}" = "yes"; then -@@ -19873,6 +19989,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then +@@ -20314,6 +20431,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -8013,10 +10993,10 @@ index 8eb1bc81c66..d1a056a8a3b 100755 as_fn_error $? "conditional \"BUILD_PIMLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libgm2/configure.ac b/libgm2/configure.ac -index 3a79d2612b6..e8c7ba711cd 100644 +index 9386bbf..305d2dc 100644 --- a/libgm2/configure.ac +++ b/libgm2/configure.ac -@@ -177,8 +177,12 @@ AC_PATH_PROG(PERL, perl, perl-not-found-in-path-error) +@@ -213,8 +213,12 @@ AC_PATH_PROG(PERL, perl, perl-not-found-in-path-error) AC_PROG_MAKE_SET AC_PROG_INSTALL @@ -8031,7 +11011,7 @@ index 3a79d2612b6..e8c7ba711cd 100644 AC_SUBST(enable_static) diff --git a/libgm2/libm2cor/Makefile.am b/libgm2/libm2cor/Makefile.am -index 48de40c22dd..e50c7a2ef55 100644 +index ae96b4b..a08e6a9 100644 --- a/libgm2/libm2cor/Makefile.am +++ b/libgm2/libm2cor/Makefile.am @@ -123,6 +123,10 @@ libm2cor_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8046,20 +11026,36 @@ index 48de40c22dd..e50c7a2ef55 100644 BUILT_SOURCES = SYSTEM.def CLEANFILES = SYSTEM.def diff --git a/libgm2/libm2cor/Makefile.in b/libgm2/libm2cor/Makefile.in -index 9d643d5f8f6..d92c956aae6 100644 +index 8daf0ea..9e14c90 100644 --- a/libgm2/libm2cor/Makefile.in +++ b/libgm2/libm2cor/Makefile.in -@@ -105,6 +105,7 @@ POST_UNINSTALL = : +@@ -105,17 +105,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +@BUILD_CORLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ subdir = libm2cor ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../config/acx.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ +- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac ++ $(top_srcdir)/../config/override.m4 \ ++ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ ++ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ ++ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am @@ -469,8 +470,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_CORLIB_TRUE@ -fm2-pathname=m2iso -I$(GM2_SRC)/gm2-libs-iso \ - @BUILD_CORLIB_TRUE@ -fm2-g -g -Wreturn-type -fcase -fm2-prefix=m2cor + @BUILD_CORLIB_TRUE@ -fm2-g -g -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2cor -@BUILD_CORLIB_TRUE@@TARGET_DARWIN_FALSE@libm2cor_la_link_flags = -@BUILD_CORLIB_TRUE@@TARGET_DARWIN_TRUE@libm2cor_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8071,10 +11067,10 @@ index 9d643d5f8f6..d92c956aae6 100644 @BUILD_CORLIB_TRUE@BUILT_SOURCES = SYSTEM.def @BUILD_CORLIB_TRUE@CLEANFILES = SYSTEM.def diff --git a/libgm2/libm2iso/Makefile.am b/libgm2/libm2iso/Makefile.am -index d48ef0692ab..b0c4a5f965e 100644 +index 90d344f..e88c4b6 100644 --- a/libgm2/libm2iso/Makefile.am +++ b/libgm2/libm2iso/Makefile.am -@@ -195,6 +195,10 @@ libm2iso_la_link_flags = -Wl,-undefined,dynamic_lookup +@@ -197,6 +197,10 @@ libm2iso_la_link_flags = -Wl,-undefined,dynamic_lookup else libm2iso_la_link_flags = endif @@ -8086,20 +11082,36 @@ index d48ef0692ab..b0c4a5f965e 100644 CLEANFILES = SYSTEM.def BUILT_SOURCES = SYSTEM.def diff --git a/libgm2/libm2iso/Makefile.in b/libgm2/libm2iso/Makefile.in -index b8936e745fe..7c7e181a01e 100644 +index 8d6443d..7be5ad1 100644 --- a/libgm2/libm2iso/Makefile.in +++ b/libgm2/libm2iso/Makefile.in -@@ -105,6 +105,7 @@ POST_UNINSTALL = : +@@ -105,17 +105,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +@BUILD_ISOLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ subdir = libm2iso ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ -@@ -568,8 +569,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) +-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../config/acx.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ +- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac ++ $(top_srcdir)/../config/override.m4 \ ++ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ ++ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ ++ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am +@@ -570,8 +571,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_ISOLIB_TRUE@ -fm2-pathname=m2pim -I$(GM2_SRC)/gm2-libs \ - @BUILD_ISOLIB_TRUE@ -fiso -fextended-opaque -fm2-g -g -Wreturn-type -fcase -fm2-prefix=m2iso + @BUILD_ISOLIB_TRUE@ -fiso -fextended-opaque -fm2-g -g -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2iso -@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_FALSE@libm2iso_la_link_flags = -@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_TRUE@libm2iso_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8111,7 +11123,7 @@ index b8936e745fe..7c7e181a01e 100644 @BUILD_ISOLIB_TRUE@CLEANFILES = SYSTEM.def @BUILD_ISOLIB_TRUE@BUILT_SOURCES = SYSTEM.def diff --git a/libgm2/libm2log/Makefile.am b/libgm2/libm2log/Makefile.am -index a15747fd245..3b7609ee5c1 100644 +index 27f3840..25f5f9b 100644 --- a/libgm2/libm2log/Makefile.am +++ b/libgm2/libm2log/Makefile.am @@ -142,6 +142,9 @@ libm2log_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8125,20 +11137,36 @@ index a15747fd245..3b7609ee5c1 100644 BUILT_SOURCES = ../libm2pim/SYSTEM.def diff --git a/libgm2/libm2log/Makefile.in b/libgm2/libm2log/Makefile.in -index fa98b1d8ff1..cf48c2bb74f 100644 +index 2188f9e..f82ddb6 100644 --- a/libgm2/libm2log/Makefile.in +++ b/libgm2/libm2log/Makefile.in -@@ -105,6 +105,7 @@ POST_UNINSTALL = : +@@ -105,17 +105,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +@BUILD_LOGLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ subdir = libm2log ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../config/acx.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ +- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac ++ $(top_srcdir)/../config/override.m4 \ ++ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ ++ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ ++ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am @@ -478,8 +479,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_LOGLIB_TRUE@ -fm2-pathname=m2iso -I$(GM2_SRC)/gm2-libs-iso \ - @BUILD_LOGLIB_TRUE@ -Wreturn-type -fcase -fm2-prefix=m2log + @BUILD_LOGLIB_TRUE@ -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2log -@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_FALSE@libm2log_la_link_flags = -@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_TRUE@libm2log_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8150,7 +11178,7 @@ index fa98b1d8ff1..cf48c2bb74f 100644 @BUILD_LOGLIB_TRUE@BUILT_SOURCES = ../libm2pim/SYSTEM.def @BUILD_LOGLIB_TRUE@M2LIBDIR = /m2/m2log/ diff --git a/libgm2/libm2min/Makefile.am b/libgm2/libm2min/Makefile.am -index 1ff160028f6..21411769505 100644 +index 1ff1600..2141176 100644 --- a/libgm2/libm2min/Makefile.am +++ b/libgm2/libm2min/Makefile.am @@ -113,6 +113,9 @@ libm2min_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8164,17 +11192,33 @@ index 1ff160028f6..21411769505 100644 BUILT_SOURCES = SYSTEM.def CLEANFILES = SYSTEM.def diff --git a/libgm2/libm2min/Makefile.in b/libgm2/libm2min/Makefile.in -index 1c0bebdc304..ed3312deb0f 100644 +index 42cba0e..ed3312d 100644 --- a/libgm2/libm2min/Makefile.in +++ b/libgm2/libm2min/Makefile.in -@@ -105,6 +105,7 @@ POST_UNINSTALL = : +@@ -105,17 +105,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ subdir = libm2min ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../config/acx.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ +- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac ++ $(top_srcdir)/../config/override.m4 \ ++ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ ++ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ ++ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am @@ -442,8 +443,10 @@ libm2min_la_M2FLAGS = \ -fm2-pathname=m2pim -I$(GM2_SRC)/gm2-libs -fno-exceptions \ -fno-m2-plugin -fno-scaffold-dynamic -fno-scaffold-main -fm2-prefix=m2min @@ -8189,7 +11233,7 @@ index 1c0bebdc304..ed3312deb0f 100644 BUILT_SOURCES = SYSTEM.def CLEANFILES = SYSTEM.def diff --git a/libgm2/libm2pim/Makefile.am b/libgm2/libm2pim/Makefile.am -index ebfeba1ac1d..e777a60c077 100644 +index ac172b9..61d6c81 100644 --- a/libgm2/libm2pim/Makefile.am +++ b/libgm2/libm2pim/Makefile.am @@ -175,6 +175,9 @@ libm2pim_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8203,20 +11247,36 @@ index ebfeba1ac1d..e777a60c077 100644 BUILT_SOURCES = SYSTEM.def CLEANFILES = SYSTEM.def diff --git a/libgm2/libm2pim/Makefile.in b/libgm2/libm2pim/Makefile.in -index e5a97976d93..5e97a02a91d 100644 +index 4c2d574..0f3a6fe 100644 --- a/libgm2/libm2pim/Makefile.in +++ b/libgm2/libm2pim/Makefile.in -@@ -105,6 +105,7 @@ POST_UNINSTALL = : +@@ -105,17 +105,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +@BUILD_PIMLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ subdir = libm2pim ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../config/acx.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ +- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac ++ $(top_srcdir)/../config/override.m4 \ ++ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ ++ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ ++ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am @@ -539,8 +540,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_PIMLIB_TRUE@ -fm2-pathname=m2iso -I$(GM2_SRC)/gm2-libs-iso \ - @BUILD_PIMLIB_TRUE@ -fm2-g -g -Wreturn-type -fcase -fm2-prefix=m2pim + @BUILD_PIMLIB_TRUE@ -fm2-g -g -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2pim -@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_FALSE@libm2pim_la_link_flags = -@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_TRUE@libm2pim_la_link_flags = -Wl,-undefined,dynamic_lookup @@ -8228,7 +11288,7 @@ index e5a97976d93..5e97a02a91d 100644 @BUILD_PIMLIB_TRUE@BUILT_SOURCES = SYSTEM.def @BUILD_PIMLIB_TRUE@CLEANFILES = SYSTEM.def diff --git a/libgo/configure b/libgo/configure -index a607dbff68e..72d46c3eec3 100755 +index a607dbf..72d46c3 100755 --- a/libgo/configure +++ b/libgo/configure @@ -708,6 +708,8 @@ glibgo_toolexecdir @@ -8285,7 +11345,7 @@ index a607dbff68e..72d46c3eec3 100755 as_fn_error $? "conditional \"USE_LIBFFI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libgo/configure.ac b/libgo/configure.ac -index a59aa091d1d..6f1ac32660b 100644 +index a59aa09..6f1ac32 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -53,6 +53,7 @@ AC_LIBTOOL_DLOPEN @@ -8297,7 +11357,7 @@ index a59aa091d1d..6f1ac32660b 100644 CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} AC_SUBST(CC_FOR_BUILD) diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am -index 428f7a9dab5..ceb8c910abd 100644 +index 428f7a9..ceb8c91 100644 --- a/libgomp/Makefile.am +++ b/libgomp/Makefile.am @@ -53,9 +53,14 @@ else @@ -8317,7 +11377,7 @@ index 428f7a9dab5..ceb8c910abd 100644 libgomp_la_DEPENDENCIES = $(libgomp_version_dep) libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in -index f1afb5ef57f..ef97186e68d 100644 +index f1afb5e..ef97186 100644 --- a/libgomp/Makefile.in +++ b/libgomp/Makefile.in @@ -535,8 +535,11 @@ nodist_toolexeclib_HEADERS = libgomp.spec @@ -8334,7 +11394,7 @@ index f1afb5ef57f..ef97186e68d 100644 libgomp_la_LIBADD = $(DL_LIBS) libgomp_la_DEPENDENCIES = $(libgomp_version_dep) diff --git a/libgomp/configure b/libgomp/configure -index ed18809ff1c..2d19357d123 100755 +index 389500d..1c219c2 100755 --- a/libgomp/configure +++ b/libgomp/configure @@ -682,6 +682,8 @@ FC @@ -8354,16 +11414,17 @@ index ed18809ff1c..2d19357d123 100755 enable_maintainer_mode enable_linux_futex enable_tls -@@ -1477,6 +1480,8 @@ Optional Features: +@@ -1477,6 +1480,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer -@@ -7621,7 +7626,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -7621,7 +7627,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -8372,7 +11433,7 @@ index ed18809ff1c..2d19357d123 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9594,6 +9599,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9594,6 +9600,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -8422,7 +11483,7 @@ index ed18809ff1c..2d19357d123 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9611,9 +9659,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9611,9 +9660,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -8438,25 +11499,25 @@ index ed18809ff1c..2d19357d123 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -11419,7 +11471,7 @@ else +@@ -11419,7 +11472,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11422 "configure" -+#line 11474 "configure" ++#line 11475 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11525,7 +11577,7 @@ else +@@ -11525,7 +11578,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11528 "configure" -+#line 11580 "configure" ++#line 11581 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11786,6 +11838,14 @@ esac +@@ -11786,6 +11839,14 @@ esac @@ -8471,7 +11532,7 @@ index ed18809ff1c..2d19357d123 100755 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -@@ -13461,6 +13521,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13461,6 +13522,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -8521,7 +11582,7 @@ index ed18809ff1c..2d19357d123 100755 archive_cmds_need_lc_FC=no hardcode_direct_FC=no hardcode_automatic_FC=yes -@@ -13478,9 +13581,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13478,9 +13582,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -8537,7 +11598,7 @@ index ed18809ff1c..2d19357d123 100755 module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -17122,6 +17229,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then +@@ -17129,6 +17237,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then as_fn_error $? "conditional \"BUILD_INFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -8549,7 +11610,7 @@ index ed18809ff1c..2d19357d123 100755 as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libgomp/configure.ac b/libgomp/configure.ac -index cc96e5b753b..cef33212028 100644 +index dd88f20..5deba11 100644 --- a/libgomp/configure.ac +++ b/libgomp/configure.ac @@ -149,6 +149,7 @@ AM_PROG_LIBTOOL @@ -8561,7 +11622,7 @@ index cc96e5b753b..cef33212028 100644 AM_MAINTAINER_MODE diff --git a/libiberty/configure b/libiberty/configure -index 860f981fa18..b8a19c42110 100755 +index 860f981..b8a19c4 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -5258,8 +5258,8 @@ case "${enable_shared}" in @@ -8576,7 +11637,7 @@ index 860f981fa18..b8a19c42110 100755 fi diff --git a/libiberty/configure.ac b/libiberty/configure.ac -index 28d996f9cf7..6747a7b5cff 100644 +index 28d996f..6747a7b 100644 --- a/libiberty/configure.ac +++ b/libiberty/configure.ac @@ -233,8 +233,8 @@ case "${enable_shared}" in @@ -8591,7 +11652,7 @@ index 28d996f9cf7..6747a7b5cff 100644 fi diff --git a/libitm/Makefile.am b/libitm/Makefile.am -index 3f31ad30556..a25317b07fe 100644 +index 3f31ad3..a25317b 100644 --- a/libitm/Makefile.am +++ b/libitm/Makefile.am @@ -54,7 +54,12 @@ libitm_version_info = -version-info $(libtool_VERSION) @@ -8609,7 +11670,7 @@ index 3f31ad30556..a25317b07fe 100644 libitm_la_SOURCES = \ aatree.cc alloc.cc alloc_c.cc alloc_cpp.cc barrier.cc beginend.cc \ diff --git a/libitm/Makefile.in b/libitm/Makefile.in -index 7f53ea9b9db..ed28db45057 100644 +index 7f53ea9..ed28db4 100644 --- a/libitm/Makefile.in +++ b/libitm/Makefile.in @@ -481,7 +481,12 @@ libitm_version_info = -version-info $(libtool_VERSION) @@ -8627,7 +11688,7 @@ index 7f53ea9b9db..ed28db45057 100644 barrier.cc beginend.cc clone.cc eh_cpp.cc local.cc query.cc \ retry.cc rwlock.cc useraction.cc util.cc sjlj.S tls.cc \ diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S -index 0342516cdc8..2c27f46dc43 100644 +index 0342516..2c27f46 100644 --- a/libitm/config/aarch64/sjlj.S +++ b/libitm/config/aarch64/sjlj.S @@ -57,10 +57,19 @@ @@ -8700,7 +11761,7 @@ index 0342516cdc8..2c27f46dc43 100644 /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */ #define FEATURE_1_AND 0xc0000000 diff --git a/libitm/configure b/libitm/configure -index 6230c04dd24..014453a3f49 100755 +index 6230c04..b941ecf 100755 --- a/libitm/configure +++ b/libitm/configure @@ -660,6 +660,8 @@ libtool_VERSION @@ -8720,16 +11781,17 @@ index 6230c04dd24..014453a3f49 100755 enable_maintainer_mode enable_linux_futex enable_tls -@@ -1462,6 +1465,8 @@ Optional Features: +@@ -1462,6 +1465,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer -@@ -8283,7 +8288,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8283,7 +8289,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -8738,7 +11800,7 @@ index 6230c04dd24..014453a3f49 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10257,6 +10262,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10257,6 +10263,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -8788,7 +11850,7 @@ index 6230c04dd24..014453a3f49 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10274,9 +10322,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10274,9 +10323,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -8804,25 +11866,25 @@ index 6230c04dd24..014453a3f49 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12082,7 +12134,7 @@ else +@@ -12082,7 +12135,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12085 "configure" -+#line 12137 "configure" ++#line 12138 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12188,7 +12240,7 @@ else +@@ -12188,7 +12241,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12191 "configure" -+#line 12243 "configure" ++#line 12244 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13064,6 +13116,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13064,6 +13117,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -8872,7 +11934,7 @@ index 6230c04dd24..014453a3f49 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -13081,12 +13176,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13081,12 +13177,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -8896,7 +11958,7 @@ index 6230c04dd24..014453a3f49 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -15458,6 +15561,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +@@ -15458,6 +15562,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu @@ -8911,7 +11973,7 @@ index 6230c04dd24..014453a3f49 100755 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -@@ -18216,6 +18327,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then +@@ -18216,6 +18328,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then as_fn_error $? "conditional \"BUILD_INFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -8923,7 +11985,7 @@ index 6230c04dd24..014453a3f49 100755 as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libitm/configure.ac b/libitm/configure.ac -index 050d6b23e18..d0d108e1737 100644 +index 050d6b2..d0d108e 100644 --- a/libitm/configure.ac +++ b/libitm/configure.ac @@ -157,6 +157,7 @@ AM_CONDITIONAL(BUILD_INFO, test $gcc_cv_prog_makeinfo_modern = "yes") @@ -8935,7 +11997,7 @@ index 050d6b23e18..d0d108e1737 100644 AM_MAINTAINER_MODE diff --git a/libitm/configure.tgt b/libitm/configure.tgt -index 0362e61570a..2818a587ebf 100644 +index 0362e61..2818a58 100644 --- a/libitm/configure.tgt +++ b/libitm/configure.tgt @@ -50,7 +50,7 @@ fi @@ -8947,44 +12009,8 @@ index 0362e61570a..2818a587ebf 100644 alpha*) ARCH=alpha ;; rs6000 | powerpc*) XCFLAGS="${XCFLAGS} -mhtm" -diff --git a/libitm/testsuite/lib/libitm.exp b/libitm/testsuite/lib/libitm.exp -index da918d1ee8d..61bbfa0c923 100644 ---- a/libitm/testsuite/lib/libitm.exp -+++ b/libitm/testsuite/lib/libitm.exp -@@ -159,6 +159,7 @@ proc libitm_init { args } { - } - - if [istarget *-*-darwin*] { -+ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/.libs" - lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc" - } - -diff --git a/libitm/testsuite/libitm.c++/c++.exp b/libitm/testsuite/libitm.c++/c++.exp -index de45e7e5480..1b0ead05fee 100644 ---- a/libitm/testsuite/libitm.c++/c++.exp -+++ b/libitm/testsuite/libitm.c++/c++.exp -@@ -56,8 +56,10 @@ if { $lang_test_file_found } { - # Gather a list of all tests. - set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]] - -+ set stdcxxadder "" - if { $blddir != "" } { - set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}" -+ set stdcxxadder "-B ${blddir}/${lang_library_path}" - } else { - set ld_library_path "$always_ld_library_path" - } -@@ -72,7 +74,7 @@ if { $lang_test_file_found } { - } - - # Main loop. -- dg-runtest $tests "" $libstdcxx_includes -+ dg-runtest $tests $stdcxxadder $libstdcxx_includes - } - - # All done. diff --git a/libobjc/configure b/libobjc/configure -index 6da20b8e4ff..7087d079450 100755 +index 6da20b8..ce18c24 100755 --- a/libobjc/configure +++ b/libobjc/configure @@ -636,6 +636,9 @@ OBJC_BOEHM_GC_LIBS @@ -9013,16 +12039,17 @@ index 6da20b8e4ff..7087d079450 100755 enable_tls enable_objc_gc with_target_bdw_gc -@@ -1392,6 +1395,8 @@ Optional Features: +@@ -1392,6 +1395,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-tls Use thread-local storage [default=yes] --enable-objc-gc enable use of Boehm's garbage collector with the GNU Objective-C runtime -@@ -3431,17 +3436,6 @@ esac +@@ -3431,17 +3437,6 @@ esac @@ -9040,7 +12067,7 @@ index 6da20b8e4ff..7087d079450 100755 # Add CET specific flags if CET is enabled -@@ -6973,7 +6967,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -6973,7 +6968,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -9049,7 +12076,7 @@ index 6da20b8e4ff..7087d079450 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8950,6 +8944,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8950,6 +8945,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -9099,7 +12126,7 @@ index 6da20b8e4ff..7087d079450 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -8967,9 +9004,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8967,9 +9005,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -9115,25 +12142,25 @@ index 6da20b8e4ff..7087d079450 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -10796,7 +10837,7 @@ else +@@ -10796,7 +10838,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10799 "configure" -+#line 10840 "configure" ++#line 10841 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -10902,7 +10943,7 @@ else +@@ -10902,7 +10944,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10905 "configure" -+#line 10946 "configure" ++#line 10947 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11174,6 +11215,38 @@ $as_echo "no" >&6; } +@@ -11174,6 +11216,38 @@ $as_echo "no" >&6; } fi @@ -9172,7 +12199,7 @@ index 6da20b8e4ff..7087d079450 100755 # ------- # Headers # ------- -@@ -11915,6 +11988,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then +@@ -11915,6 +11989,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -9184,7 +12211,7 @@ index 6da20b8e4ff..7087d079450 100755 : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/libobjc/configure.ac b/libobjc/configure.ac -index 9bd7d59d597..cb21ebbfcc7 100644 +index 9bd7d59..cb21ebb 100644 --- a/libobjc/configure.ac +++ b/libobjc/configure.ac @@ -148,17 +148,6 @@ m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) @@ -9238,7 +12265,7 @@ index 9bd7d59d597..cb21ebbfcc7 100644 # Headers # ------- diff --git a/libphobos/configure b/libphobos/configure -index 925c53c5f5e..969ae6077cc 100755 +index 925c53c..2e8c06d 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -707,6 +707,8 @@ get_gcc_base_ver @@ -9258,16 +12285,17 @@ index 925c53c5f5e..969ae6077cc 100755 with_gcc_major_version_only enable_werror with_libatomic -@@ -1490,6 +1493,8 @@ Optional Features: +@@ -1490,6 +1493,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-werror turns on -Werror [default=no] --enable-version-specific-runtime-libs Specify that runtime libraries should be installed -@@ -8244,7 +8249,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8244,7 +8250,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -9276,7 +12304,7 @@ index 925c53c5f5e..969ae6077cc 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9949,6 +9954,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9949,6 +9955,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -9326,7 +12354,7 @@ index 925c53c5f5e..969ae6077cc 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9966,9 +10014,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9966,9 +10015,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -9342,25 +12370,25 @@ index 925c53c5f5e..969ae6077cc 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -11774,7 +11826,7 @@ else +@@ -11774,7 +11827,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11777 "configure" -+#line 11829 "configure" ++#line 11830 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11880,7 +11932,7 @@ else +@@ -11880,7 +11933,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11883 "configure" -+#line 11935 "configure" ++#line 11936 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13405,6 +13457,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13405,6 +13458,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -9410,7 +12438,7 @@ index 925c53c5f5e..969ae6077cc 100755 archive_cmds_need_lc_D=no hardcode_direct_D=no hardcode_automatic_D=yes -@@ -13422,9 +13517,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13422,9 +13518,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -9426,7 +12454,7 @@ index 925c53c5f5e..969ae6077cc 100755 module_expsym_cmds_D="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -14026,6 +14125,14 @@ CFLAGS=$lt_save_CFLAGS +@@ -14026,6 +14126,14 @@ CFLAGS=$lt_save_CFLAGS @@ -9441,7 +12469,7 @@ index 925c53c5f5e..969ae6077cc 100755 # libtool variables for Phobos shared and position-independent compiles. # -@@ -15750,6 +15857,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then +@@ -15750,6 +15858,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -9453,7 +12481,7 @@ index 925c53c5f5e..969ae6077cc 100755 as_fn_error $? "conditional \"DRUNTIME_CPU_AARCH64\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libphobos/configure.ac b/libphobos/configure.ac -index 464f4105430..ba8b5ecd65b 100644 +index 464f410..ba8b5ec 100644 --- a/libphobos/configure.ac +++ b/libphobos/configure.ac @@ -93,6 +93,7 @@ AM_PROG_LIBTOOL @@ -9465,7 +12493,7 @@ index 464f4105430..ba8b5ecd65b 100644 # libtool variables for Phobos shared and position-independent compiles. # diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am -index 8225ba4a028..186948806d5 100644 +index 8225ba4..1869488 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -128,8 +128,11 @@ ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \ @@ -9482,7 +12510,7 @@ index 8225ba4a028..186948806d5 100644 libgdruntime_la_DEPENDENCIES = $(DRTSTUFF) # Also override library link commands: This is not strictly diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in -index 797d6435a7c..cd13090010f 100644 +index 797d643..cd13090 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -810,8 +810,9 @@ ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \ @@ -9497,7 +12525,7 @@ index 797d6435a7c..cd13090010f 100644 libgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE) libgdruntime_la_DEPENDENCIES = $(DRTSTUFF) diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am -index 6474fca5eb5..f6521ed5860 100644 +index 6474fca..f6521ed 100644 --- a/libphobos/src/Makefile.am +++ b/libphobos/src/Makefile.am @@ -44,8 +44,11 @@ toolexeclib_DATA = libgphobos.spec @@ -9514,7 +12542,7 @@ index 6474fca5eb5..f6521ed5860 100644 libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la else diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in -index a6229587e7b..cc3358b437e 100644 +index a622958..cc3358b 100644 --- a/libphobos/src/Makefile.in +++ b/libphobos/src/Makefile.in @@ -529,8 +529,9 @@ toolexeclib_DATA = libgphobos.spec @@ -9529,7 +12557,7 @@ index a6229587e7b..cc3358b437e 100644 @ENABLE_LIBDRUNTIME_ONLY_FALSE@libgphobos_la_LIBADD = \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ ../libdruntime/libgdruntime_convenience.la $(LIBZ) diff --git a/libquadmath/Makefile.am b/libquadmath/Makefile.am -index 35dffb46f6e..0d02c95e738 100644 +index 35dffb4..f199adf 100644 --- a/libquadmath/Makefile.am +++ b/libquadmath/Makefile.am @@ -36,8 +36,13 @@ endif @@ -9543,12 +12571,12 @@ index 35dffb46f6e..0d02c95e738 100644 +endif libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ - $(version_arg) $(lt_host_flags) -lm -+ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) ++ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h diff --git a/libquadmath/Makefile.in b/libquadmath/Makefile.in -index 8c011212258..068af559457 100644 +index 8c01121..7002575 100644 --- a/libquadmath/Makefile.in +++ b/libquadmath/Makefile.in @@ -355,6 +355,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -9567,12 +12595,12 @@ index 8c011212258..068af559457 100644 +@BUILD_LIBQUADMATH_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path @BUILD_LIBQUADMATH_TRUE@libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) -lm -+@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) ++@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) @BUILD_LIBQUADMATH_TRUE@libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) @BUILD_LIBQUADMATH_TRUE@nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h diff --git a/libquadmath/configure b/libquadmath/configure -index 958fb876c5b..9b1703d6ee5 100755 +index 958fb87..c51d4f3 100755 --- a/libquadmath/configure +++ b/libquadmath/configure @@ -644,11 +644,14 @@ LIBQUAD_USE_SYMVER_GNU_FALSE @@ -9598,16 +12626,17 @@ index 958fb876c5b..9b1703d6ee5 100755 enable_maintainer_mode with_toolexeclibdir enable_symvers -@@ -1435,6 +1439,8 @@ Optional Features: +@@ -1435,6 +1439,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer -@@ -7272,7 +7278,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -7272,7 +7279,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -9616,7 +12645,7 @@ index 958fb876c5b..9b1703d6ee5 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8984,6 +8990,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8984,6 +8991,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -9666,7 +12695,7 @@ index 958fb876c5b..9b1703d6ee5 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9001,9 +9050,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9001,9 +9051,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -9682,25 +12711,25 @@ index 958fb876c5b..9b1703d6ee5 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -10830,7 +10883,7 @@ else +@@ -10830,7 +10884,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10833 "configure" -+#line 10886 "configure" ++#line 10887 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -10936,7 +10989,7 @@ else +@@ -10936,7 +10990,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10939 "configure" -+#line 10992 "configure" ++#line 10993 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11197,6 +11250,14 @@ esac +@@ -11197,6 +11251,14 @@ esac @@ -9715,156 +12744,28 @@ index 958fb876c5b..9b1703d6ee5 100755 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -@@ -12161,6 +12222,148 @@ esac +@@ -12161,6 +12223,20 @@ esac ++# AC_CHECK_LIBM variant which avoids AC_CHECK_LIB (that doesn't work ++# on bare metal). In the past we've used -lm in Makefile.am unconditionally, ++# let's use it there unless target knows it doesn't need that. +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; -+*-ncr-sysv4.3*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5 -+$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; } -+if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_check_lib_save_LIBS=$LIBS -+LIBS="-lmw $LIBS" -+if test x$gcc_no_link = xyes; then -+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 -+fi -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char _mwvalidcheckl (); -+int -+main () -+{ -+return _mwvalidcheckl (); -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_lib_mw__mwvalidcheckl=yes -+else -+ ac_cv_lib_mw__mwvalidcheckl=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5 -+$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; } -+if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then : -+ LIBM="-lmw" -+fi -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 -+$as_echo_n "checking for cos in -lm... " >&6; } -+if ${ac_cv_lib_m_cos+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_check_lib_save_LIBS=$LIBS -+LIBS="-lm $LIBS" -+if test x$gcc_no_link = xyes; then -+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 -+fi -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char cos (); -+int -+main () -+{ -+return cos (); -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_lib_m_cos=yes -+else -+ ac_cv_lib_m_cos=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 -+$as_echo "$ac_cv_lib_m_cos" >&6; } -+if test "x$ac_cv_lib_m_cos" = xyes; then : -+ LIBM="$LIBM -lm" -+fi -+ -+ ;; +*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 -+$as_echo_n "checking for cos in -lm... " >&6; } -+if ${ac_cv_lib_m_cos+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_check_lib_save_LIBS=$LIBS -+LIBS="-lm $LIBS" -+if test x$gcc_no_link = xyes; then -+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 -+fi -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char cos (); -+int -+main () -+{ -+return cos (); -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_lib_m_cos=yes -+else -+ ac_cv_lib_m_cos=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 -+$as_echo "$ac_cv_lib_m_cos" >&6; } -+if test "x$ac_cv_lib_m_cos" = xyes; then : -+ LIBM="-lm" -+fi -+ ++ LIBM=-lm + ;; +esac + -+ + for ac_header in fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -@@ -13421,6 +13624,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then +@@ -13421,6 +13497,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then as_fn_error $? "conditional \"BUILD_INFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -9876,7 +12777,7 @@ index 958fb876c5b..9b1703d6ee5 100755 as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libquadmath/configure.ac b/libquadmath/configure.ac -index eec4084a45f..94a3f2179e9 100644 +index eec4084..349be26 100644 --- a/libquadmath/configure.ac +++ b/libquadmath/configure.ac @@ -59,6 +59,7 @@ AM_PROG_LIBTOOL @@ -9887,17 +12788,29 @@ index eec4084a45f..94a3f2179e9 100644 AM_MAINTAINER_MODE -@@ -121,6 +122,8 @@ esac +@@ -121,6 +122,20 @@ esac AC_SUBST(toolexecdir) AC_SUBST(toolexeclibdir) -+AC_CHECK_LIBM ++# AC_CHECK_LIBM variant which avoids AC_CHECK_LIB (that doesn't work ++# on bare metal). In the past we've used -lm in Makefile.am unconditionally, ++# let's use it there unless target knows it doesn't need that. ++LIBM= ++case $host in ++*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) ++ # These system don't have libm, or don't need it ++ ;; ++*) ++ LIBM=-lm ++ ;; ++esac ++AC_SUBST([LIBM]) + AC_CHECK_HEADERS(fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h) LIBQUAD_CHECK_MATH_H_SIGNGAM diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am -index 4f802f723d6..223d3e07816 100644 +index 4f802f7..223d3e0 100644 --- a/libsanitizer/asan/Makefile.am +++ b/libsanitizer/asan/Makefile.am @@ -60,7 +60,12 @@ libasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la @@ -9915,7 +12828,7 @@ index 4f802f723d6..223d3e07816 100644 libasan_preinit.o: asan_preinit.o cp $< $@ diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in -index 7833a9a4c3f..e88e5e0b0a7 100644 +index 7833a9a..e88e5e0 100644 --- a/libsanitizer/asan/Makefile.in +++ b/libsanitizer/asan/Makefile.in @@ -465,7 +465,12 @@ libasan_la_LIBADD = \ @@ -9933,7 +12846,7 @@ index 7833a9a4c3f..e88e5e0b0a7 100644 # Work around what appears to be a GNU make bug handling MAKEFLAGS # values defined in terms of make variables, as is the case for CC and diff --git a/libsanitizer/configure b/libsanitizer/configure -index e7984f96615..43b8b1b0737 100755 +index e7984f9..dac8308 100755 --- a/libsanitizer/configure +++ b/libsanitizer/configure @@ -666,6 +666,8 @@ LSAN_SUPPORTED_FALSE @@ -9953,16 +12866,17 @@ index e7984f96615..43b8b1b0737 100755 enable_werror with_gcc_major_version_only enable_cet -@@ -1471,6 +1474,8 @@ Optional Features: +@@ -1471,6 +1474,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --disable-werror disable building with -Werror --enable-cet enable Intel CET in target libraries [default=auto] -@@ -8853,7 +8858,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8853,7 +8859,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -9971,7 +12885,7 @@ index e7984f96615..43b8b1b0737 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10558,6 +10563,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10558,6 +10564,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -10021,7 +12935,7 @@ index e7984f96615..43b8b1b0737 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10575,9 +10623,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10575,9 +10624,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -10037,25 +12951,25 @@ index e7984f96615..43b8b1b0737 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12383,7 +12435,7 @@ else +@@ -12383,7 +12436,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12386 "configure" -+#line 12438 "configure" ++#line 12439 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12489,7 +12541,7 @@ else +@@ -12489,7 +12542,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12492 "configure" -+#line 12544 "configure" ++#line 12545 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13365,6 +13417,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13365,6 +13418,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -10105,7 +13019,7 @@ index e7984f96615..43b8b1b0737 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -13382,12 +13477,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13382,12 +13478,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -10129,7 +13043,7 @@ index e7984f96615..43b8b1b0737 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -15807,6 +15910,15 @@ esac +@@ -15807,6 +15911,15 @@ esac @@ -10145,7 +13059,7 @@ index e7984f96615..43b8b1b0737 100755 # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -@@ -17205,6 +17317,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then +@@ -17205,6 +17318,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -10157,7 +13071,7 @@ index e7984f96615..43b8b1b0737 100755 as_fn_error $? "conditional \"TSAN_SUPPORTED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac -index 04cd8910ed6..5906c8d4887 100644 +index 04cd891..5906c8d 100644 --- a/libsanitizer/configure.ac +++ b/libsanitizer/configure.ac @@ -85,6 +85,8 @@ esac @@ -10170,7 +13084,7 @@ index 04cd8910ed6..5906c8d4887 100644 if test "${multilib}" = "yes"; then diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am -index 5a89189f6d8..11b1a9c5c57 100644 +index 5a89189..11b1a9c 100644 --- a/libsanitizer/hwasan/Makefile.am +++ b/libsanitizer/hwasan/Makefile.am @@ -47,7 +47,11 @@ libhwasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la @@ -10187,7 +13101,7 @@ index 5a89189f6d8..11b1a9c5c57 100644 libhwasan_preinit.o: hwasan_preinit.o cp $< $@ diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in -index 4240aa90147..f9ec8f9c177 100644 +index 4240aa9..f9ec8f9 100644 --- a/libsanitizer/hwasan/Makefile.in +++ b/libsanitizer/hwasan/Makefile.in @@ -445,7 +445,10 @@ libhwasan_la_SOURCES = $(hwasan_files) @@ -10203,7 +13117,7 @@ index 4240aa90147..f9ec8f9c177 100644 # Work around what appears to be a GNU make bug handling MAKEFLAGS # values defined in terms of make variables, as is the case for CC and diff --git a/libsanitizer/lsan/Makefile.am b/libsanitizer/lsan/Makefile.am -index 6ff28ff5eea..7701b0e18cf 100644 +index 6ff28ff..7701b0e 100644 --- a/libsanitizer/lsan/Makefile.am +++ b/libsanitizer/lsan/Makefile.am @@ -41,8 +41,12 @@ if LIBBACKTRACE_SUPPORTED @@ -10222,7 +13136,7 @@ index 6ff28ff5eea..7701b0e18cf 100644 cp $< $@ diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in -index d8fd4ee9557..078edf01fda 100644 +index d8fd4ee..078edf0 100644 --- a/libsanitizer/lsan/Makefile.in +++ b/libsanitizer/lsan/Makefile.in @@ -413,7 +413,12 @@ liblsan_la_LIBADD = \ @@ -10248,7 +13162,7 @@ index d8fd4ee9557..078edf01fda 100644 cp $< $@ diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am -index da80743da9d..01290b0313d 100644 +index da80743..01290b0 100644 --- a/libsanitizer/tsan/Makefile.am +++ b/libsanitizer/tsan/Makefile.am @@ -57,7 +57,11 @@ libtsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la @@ -10265,7 +13179,7 @@ index da80743da9d..01290b0313d 100644 libtsan_preinit.o: tsan_preinit.o cp $< $@ diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in -index 36498832bb8..95011584bcb 100644 +index 3649883..9501158 100644 --- a/libsanitizer/tsan/Makefile.in +++ b/libsanitizer/tsan/Makefile.in @@ -464,7 +464,10 @@ libtsan_la_DEPENDENCIES = \ @@ -10281,7 +13195,7 @@ index 36498832bb8..95011584bcb 100644 # Work around what appears to be a GNU make bug handling MAKEFLAGS # values defined in terms of make variables, as is the case for CC and diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am -index d480f26adc0..7769b3437e4 100644 +index d480f26..7769b34 100644 --- a/libsanitizer/ubsan/Makefile.am +++ b/libsanitizer/ubsan/Makefile.am @@ -36,7 +36,12 @@ if LIBBACKTRACE_SUPPORTED @@ -10299,7 +13213,7 @@ index d480f26adc0..7769b3437e4 100644 # Use special rules for files that require RTTI support. ubsan_handlers_cxx.% ubsan_type_hash.% ubsan_type_hash_itanium.% : AM_CXXFLAGS += -frtti diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in -index 92a8e387fd7..7e51480e970 100644 +index 92a8e38..7e51480 100644 --- a/libsanitizer/ubsan/Makefile.in +++ b/libsanitizer/ubsan/Makefile.in @@ -400,7 +400,12 @@ libubsan_la_SOURCES = $(ubsan_files) @@ -10317,7 +13231,7 @@ index 92a8e387fd7..7e51480e970 100644 # Work around what appears to be a GNU make bug handling MAKEFLAGS # values defined in terms of make variables, as is the case for CC and diff --git a/libssp/Makefile.am b/libssp/Makefile.am -index 1636e43b369..f7ed2aa6043 100644 +index 1636e43..f7ed2aa 100644 --- a/libssp/Makefile.am +++ b/libssp/Makefile.am @@ -49,8 +49,12 @@ libssp_la_SOURCES = \ @@ -10335,7 +13249,7 @@ index 1636e43b369..f7ed2aa6043 100644 libssp_nonshared_la_SOURCES = \ ssp-local.c diff --git a/libssp/Makefile.in b/libssp/Makefile.in -index bc8a0dc2b28..1cf86361b96 100644 +index bc8a0dc..1cf8636 100644 --- a/libssp/Makefile.in +++ b/libssp/Makefile.in @@ -376,8 +376,11 @@ libssp_la_SOURCES = \ @@ -10352,7 +13266,7 @@ index bc8a0dc2b28..1cf86361b96 100644 libssp_nonshared_la_SOURCES = \ ssp-local.c diff --git a/libssp/configure b/libssp/configure -index 492915d2ce0..7a3c784aaf4 100755 +index 492915d..72102be 100755 --- a/libssp/configure +++ b/libssp/configure @@ -636,6 +636,8 @@ LIBOBJS @@ -10372,16 +13286,17 @@ index 492915d2ce0..7a3c784aaf4 100755 with_toolexeclibdir with_gcc_major_version_only ' -@@ -1426,6 +1429,8 @@ Optional Features: +@@ -1426,6 +1429,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -7458,7 +7463,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -7458,7 +7464,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -10390,7 +13305,7 @@ index 492915d2ce0..7a3c784aaf4 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9170,6 +9175,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9170,6 +9176,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -10440,7 +13355,7 @@ index 492915d2ce0..7a3c784aaf4 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -9187,9 +9235,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -9187,9 +9236,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -10456,25 +13371,25 @@ index 492915d2ce0..7a3c784aaf4 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -11016,7 +11068,7 @@ else +@@ -11016,7 +11069,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11019 "configure" -+#line 11071 "configure" ++#line 11072 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11122,7 +11174,7 @@ else +@@ -11122,7 +11175,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11125 "configure" -+#line 11177 "configure" ++#line 11178 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11400,6 +11452,15 @@ fi +@@ -11400,6 +11453,15 @@ fi @@ -10490,7 +13405,7 @@ index 492915d2ce0..7a3c784aaf4 100755 # Calculate toolexeclibdir # Also toolexecdir, though it's only used in toolexeclibdir case ${version_specific_libs} in -@@ -11609,6 +11670,10 @@ if test -z "${LIBSSP_USE_SYMVER_SUN_TRUE}" && test -z "${LIBSSP_USE_SYMVER_SUN_F +@@ -11609,6 +11671,10 @@ if test -z "${LIBSSP_USE_SYMVER_SUN_TRUE}" && test -z "${LIBSSP_USE_SYMVER_SUN_F as_fn_error $? "conditional \"LIBSSP_USE_SYMVER_SUN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -10502,7 +13417,7 @@ index 492915d2ce0..7a3c784aaf4 100755 : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/libssp/configure.ac b/libssp/configure.ac -index f30f81c54f6..90778e2355d 100644 +index f30f81c..90778e2 100644 --- a/libssp/configure.ac +++ b/libssp/configure.ac @@ -165,6 +165,8 @@ AC_SUBST(enable_static) @@ -10515,19 +13430,19 @@ index f30f81c54f6..90778e2355d 100644 # Also toolexecdir, though it's only used in toolexeclibdir case ${version_specific_libs} in diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure -index 9b602777545..7f1874c413a 100755 +index d35baaf..4cac54b 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure -@@ -789,6 +789,8 @@ GLIBCXX_HOSTED_TRUE - glibcxx_compiler_shared_flag - glibcxx_compiler_pic_flag +@@ -791,6 +791,8 @@ glibcxx_compiler_pic_flag glibcxx_lt_pic_flag + OS_IS_DARWIN_FALSE + OS_IS_DARWIN_TRUE +ENABLE_DARWIN_AT_RPATH_FALSE +ENABLE_DARWIN_AT_RPATH_TRUE enable_static enable_shared lt_host_flags -@@ -924,6 +926,7 @@ with_pic +@@ -926,6 +928,7 @@ with_pic enable_fast_install with_gnu_ld enable_libtool_lock @@ -10535,16 +13450,17 @@ index 9b602777545..7f1874c413a 100755 enable_hosted_libstdcxx enable_libstdcxx_hosted enable_libstdcxx_verbose -@@ -1615,6 +1618,8 @@ Optional Features: +@@ -1617,6 +1620,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --disable-hosted-libstdcxx only build freestanding C++ runtime support --disable-libstdcxx-hosted -@@ -8501,7 +8506,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8503,7 +8509,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -10553,7 +13469,7 @@ index 9b602777545..7f1874c413a 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10341,6 +10346,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10343,6 +10349,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -10603,7 +13519,7 @@ index 9b602777545..7f1874c413a 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10358,9 +10406,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10360,9 +10409,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -10619,25 +13535,25 @@ index 9b602777545..7f1874c413a 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12187,7 +12239,7 @@ else +@@ -12189,7 +12242,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF --#line 12190 "configure" -+#line 12242 "configure" +-#line 12192 "configure" ++#line 12245 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12293,7 +12345,7 @@ else +@@ -12295,7 +12348,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF --#line 12296 "configure" -+#line 12348 "configure" +-#line 12298 "configure" ++#line 12351 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13175,6 +13227,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13177,6 +13230,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -10687,7 +13603,7 @@ index 9b602777545..7f1874c413a 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -13192,12 +13287,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13194,12 +13290,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -10711,7 +13627,7 @@ index 9b602777545..7f1874c413a 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -15594,6 +15697,14 @@ esac +@@ -15596,6 +15700,14 @@ esac @@ -10724,63 +13640,63 @@ index 9b602777545..7f1874c413a 100755 +fi + - if test "$enable_vtable_verify" = yes; then - predep_objects_CXX="${predep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_start.o" -@@ -16017,7 +16128,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } + os_is_darwin=no + case ${host_os} in +@@ -16033,7 +16145,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF --#line 16020 "configure" -+#line 16131 "configure" +-#line 16036 "configure" ++#line 16148 "configure" int main() { typedef bool atomic_type; -@@ -16052,7 +16163,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } +@@ -16068,7 +16180,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF --#line 16055 "configure" -+#line 16166 "configure" +-#line 16071 "configure" ++#line 16183 "configure" int main() { typedef short atomic_type; -@@ -16087,7 +16198,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } +@@ -16103,7 +16215,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF --#line 16090 "configure" -+#line 16201 "configure" +-#line 16106 "configure" ++#line 16218 "configure" int main() { // NB: _Atomic_word not necessarily int. -@@ -16123,7 +16234,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } +@@ -16139,7 +16251,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF --#line 16126 "configure" -+#line 16237 "configure" +-#line 16142 "configure" ++#line 16254 "configure" int main() { typedef long long atomic_type; -@@ -16279,7 +16390,7 @@ $as_echo "mutex" >&6; } +@@ -16295,7 +16407,7 @@ $as_echo "mutex" >&6; } # unnecessary for this test. cat > conftest.$ac_ext << EOF --#line 16282 "configure" -+#line 16393 "configure" +-#line 16298 "configure" ++#line 16410 "configure" int main() { _Decimal32 d1; -@@ -16321,7 +16432,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +@@ -16337,7 +16449,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF --#line 16324 "configure" -+#line 16435 "configure" +-#line 16340 "configure" ++#line 16452 "configure" template struct same { typedef T2 type; }; -@@ -73038,6 +73149,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then +@@ -73309,6 +73421,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -10788,11 +13704,11 @@ index 9b602777545..7f1874c413a 100755 + as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi - if test -z "${GLIBCXX_HOSTED_TRUE}" && test -z "${GLIBCXX_HOSTED_FALSE}"; then - as_fn_error $? "conditional \"GLIBCXX_HOSTED\" was never defined. + if test -z "${OS_IS_DARWIN_TRUE}" && test -z "${OS_IS_DARWIN_FALSE}"; then + as_fn_error $? "conditional \"OS_IS_DARWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac -index 91b3c1f32f2..8832c70de3c 100644 +index 0c3c7a2..6dde72c 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -108,6 +108,7 @@ AM_PROG_LIBTOOL @@ -10801,10 +13717,10 @@ index 91b3c1f32f2..8832c70de3c 100644 AC_SUBST(enable_static) +AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - if test "$enable_vtable_verify" = yes; then - predep_objects_CXX="${predep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_start.o" + os_is_darwin=no + case ${host_os} in diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am -index 5b9af41cdb9..925137c2ccc 100644 +index 5b9af41..925137c 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -152,8 +152,13 @@ libstdc___la_DEPENDENCIES = \ @@ -10823,7 +13739,7 @@ index 5b9af41cdb9..925137c2ccc 100644 libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags) diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in -index f42d957af36..0ce75f30708 100644 +index f42d957..0ce75f3 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -560,8 +560,11 @@ libstdc___la_DEPENDENCIES = \ @@ -10840,7 +13756,7 @@ index f42d957af36..0ce75f30708 100644 libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags) @GLIBCXX_LDBL_ALT128_COMPAT_FALSE@@GLIBCXX_LDBL_COMPAT_TRUE@LTCXXCOMPILE64 = $(LTCXXCOMPILE) diff --git a/libtool.m4 b/libtool.m4 -index b92e284d9f9..f3bddafc19d 100644 +index b92e284..5361f26 100644 --- a/libtool.m4 +++ b/libtool.m4 @@ -1005,7 +1005,7 @@ _LT_EOF @@ -10865,7 +13781,7 @@ index b92e284d9f9..f3bddafc19d 100644 + # configuring can override the defaults for any system version that supports + # them - they are, however, forced off for system versions without support. + AC_ARG_ENABLE([darwin-at-rpath], -+ AS_HELP_STRING([--enable-darwin-at-path], ++ AS_HELP_STRING([--enable-darwin-at-rpath], + [install libraries with @rpath/library-name, requires rpaths to be added to executables]), + [if test "x$enable_darwin_at_rpath" = "xyes"; then + # This is not supported before macOS 10.5 / Darwin9. @@ -10923,15 +13839,7 @@ index b92e284d9f9..f3bddafc19d 100644 _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) -@@ -4227,6 +4274,7 @@ _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) - ])# _LT_COMPILER_PIC - -+_LT_TAGVAR(enable_darwin_at_rpath, $1)=no - - # _LT_LINKER_SHLIBS([TAGNAME]) - # ---------------------------- -@@ -6466,7 +6514,6 @@ fi # test "$_lt_caught_CXX_error" != yes +@@ -6466,7 +6513,6 @@ fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG @@ -10940,7 +13848,7 @@ index b92e284d9f9..f3bddafc19d 100644 # --------------------------------- # Figure out "hidden" library dependencies from verbose diff --git a/libvtv/configure b/libvtv/configure -index e7e490d8b3e..f09f4d9dbcf 100755 +index e7e490d..da4fe61 100755 --- a/libvtv/configure +++ b/libvtv/configure @@ -640,6 +640,8 @@ VTV_CYGMIN_FALSE @@ -10960,16 +13868,17 @@ index e7e490d8b3e..f09f4d9dbcf 100755 enable_cet with_gcc_major_version_only ' -@@ -1446,6 +1449,8 @@ Optional Features: +@@ -1446,6 +1449,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-cet enable Intel CET in target libraries [default=auto] Optional Packages: -@@ -8748,7 +8753,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8748,7 +8754,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -10978,7 +13887,7 @@ index e7e490d8b3e..f09f4d9dbcf 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10453,6 +10458,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10453,6 +10459,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -11028,7 +13937,7 @@ index e7e490d8b3e..f09f4d9dbcf 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10470,9 +10518,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10470,9 +10519,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -11044,25 +13953,25 @@ index e7e490d8b3e..f09f4d9dbcf 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12278,7 +12330,7 @@ else +@@ -12278,7 +12331,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12281 "configure" -+#line 12333 "configure" ++#line 12334 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12384,7 +12436,7 @@ else +@@ -12384,7 +12437,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12387 "configure" -+#line 12439 "configure" ++#line 12440 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -13260,6 +13312,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13260,6 +13313,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -11112,7 +14021,7 @@ index e7e490d8b3e..f09f4d9dbcf 100755 archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes -@@ -13277,12 +13372,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -13277,12 +13373,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -11136,7 +14045,7 @@ index e7e490d8b3e..f09f4d9dbcf 100755 archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi -@@ -15676,6 +15779,14 @@ esac +@@ -15676,6 +15780,14 @@ esac @@ -11151,7 +14060,7 @@ index e7e490d8b3e..f09f4d9dbcf 100755 # For libtool versioning info, format is CURRENT:REVISION:AGE libtool_VERSION=1:0:0 -@@ -16021,6 +16132,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then +@@ -16021,6 +16133,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -11163,7 +14072,7 @@ index e7e490d8b3e..f09f4d9dbcf 100755 as_fn_error $? "conditional \"VTV_CYGMIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libvtv/configure.ac b/libvtv/configure.ac -index f3b937e4b10..50aaadbb3a3 100644 +index f3b937e..50aaadb 100644 --- a/libvtv/configure.ac +++ b/libvtv/configure.ac @@ -153,6 +153,7 @@ AM_PROG_LIBTOOL @@ -11175,7 +14084,7 @@ index f3b937e4b10..50aaadbb3a3 100644 # For libtool versioning info, format is CURRENT:REVISION:AGE libtool_VERSION=1:0:0 diff --git a/lto-plugin/configure b/lto-plugin/configure -index d522bd24c95..23162fc0fff 100755 +index d522bd2..c3b1b5f 100755 --- a/lto-plugin/configure +++ b/lto-plugin/configure @@ -634,6 +634,8 @@ LTLIBOBJS @@ -11195,16 +14104,17 @@ index d522bd24c95..23162fc0fff 100755 ' ac_precious_vars='build_alias host_alias -@@ -1431,6 +1434,8 @@ Optional Features: +@@ -1431,6 +1434,9 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -8603,7 +8608,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -8603,7 +8609,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -11213,7 +14123,7 @@ index d522bd24c95..23162fc0fff 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10309,6 +10314,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10309,6 +10315,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -11263,7 +14173,7 @@ index d522bd24c95..23162fc0fff 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -10326,9 +10374,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -10326,9 +10375,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -11279,25 +14189,25 @@ index d522bd24c95..23162fc0fff 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -12134,7 +12186,7 @@ else +@@ -12134,7 +12187,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12137 "configure" -+#line 12189 "configure" ++#line 12190 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12240,7 +12292,7 @@ else +@@ -12240,7 +12293,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12243 "configure" -+#line 12295 "configure" ++#line 12296 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -12477,6 +12529,14 @@ CC="$lt_save_CC" +@@ -12477,6 +12530,14 @@ CC="$lt_save_CC" # Only expand once: @@ -11312,7 +14222,7 @@ index d522bd24c95..23162fc0fff 100755 -@@ -12723,6 +12783,10 @@ if test -z "${LTO_PLUGIN_USE_SYMVER_SUN_TRUE}" && test -z "${LTO_PLUGIN_USE_SYMV +@@ -12723,6 +12784,10 @@ if test -z "${LTO_PLUGIN_USE_SYMVER_SUN_TRUE}" && test -z "${LTO_PLUGIN_USE_SYMV as_fn_error $? "conditional \"LTO_PLUGIN_USE_SYMVER_SUN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -11324,7 +14234,7 @@ index d522bd24c95..23162fc0fff 100755 : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/lto-plugin/configure.ac b/lto-plugin/configure.ac -index 0a7202782ae..5812bbbfc08 100644 +index 0a72027..5812bbb 100644 --- a/lto-plugin/configure.ac +++ b/lto-plugin/configure.ac @@ -110,6 +110,7 @@ fi @@ -11336,7 +14246,7 @@ index 0a7202782ae..5812bbbfc08 100644 AC_SUBST(target_noncanonical) AC_TYPE_INT64_T diff --git a/zlib/Makefile.in b/zlib/Makefile.in -index 3f5102d1b87..80fe3b69116 100644 +index 3f5102d..80fe3b6 100644 --- a/zlib/Makefile.in +++ b/zlib/Makefile.in @@ -353,6 +353,8 @@ datadir = @datadir@ @@ -11349,7 +14259,7 @@ index 3f5102d1b87..80fe3b69116 100644 host = @host@ host_alias = @host_alias@ diff --git a/zlib/configure b/zlib/configure -index e35ac6e7e17..ccafc4f03f7 100755 +index e35ac6e..a7673a8 100755 --- a/zlib/configure +++ b/zlib/configure @@ -635,10 +635,14 @@ am__EXEEXT_TRUE @@ -11378,18 +14288,19 @@ index e35ac6e7e17..ccafc4f03f7 100755 ' ac_precious_vars='build_alias host_alias -@@ -1419,7 +1425,10 @@ Optional Features: +@@ -1419,7 +1425,11 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ --enable-darwin-at-rpath ++ install libraries with @rpath/library-name, requires + rpaths to be added to executables --enable-host-shared build host code as shared libraries + --enable-host-pie build host code as PIE Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -6934,7 +6943,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } +@@ -6934,7 +6944,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in @@ -11398,7 +14309,7 @@ index e35ac6e7e17..ccafc4f03f7 100755 ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8913,6 +8922,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8913,6 +8923,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) @@ -11448,7 +14359,7 @@ index e35ac6e7e17..ccafc4f03f7 100755 archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes -@@ -8930,9 +8982,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +@@ -8930,9 +8983,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all @@ -11464,25 +14375,25 @@ index e35ac6e7e17..ccafc4f03f7 100755 module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else -@@ -10759,7 +10815,7 @@ else +@@ -10759,7 +10816,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10762 "configure" -+#line 10818 "configure" ++#line 10819 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -10865,7 +10921,7 @@ else +@@ -10865,7 +10922,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10868 "configure" -+#line 10924 "configure" ++#line 10925 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -@@ -11102,6 +11158,14 @@ CC="$lt_save_CC" +@@ -11102,6 +11159,14 @@ CC="$lt_save_CC" # Only expand once: @@ -11497,7 +14408,7 @@ index e35ac6e7e17..ccafc4f03f7 100755 # Find CPP now so that any conditional tests below won't do it and # thereby make the resulting definitions conditional. -@@ -11548,15 +11612,31 @@ else +@@ -11548,15 +11613,31 @@ else multilib_arg= fi @@ -11531,7 +14442,7 @@ index e35ac6e7e17..ccafc4f03f7 100755 ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF -@@ -11732,6 +11812,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then +@@ -11732,6 +11813,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -11543,7 +14454,7 @@ index e35ac6e7e17..ccafc4f03f7 100755 as_fn_error $? "conditional \"TARGET_LIBRARY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/zlib/configure.ac b/zlib/configure.ac -index be1cfe29651..9501cdfea85 100644 +index be1cfe2..9501cdf 100644 --- a/zlib/configure.ac +++ b/zlib/configure.ac @@ -64,6 +64,7 @@ GCC_CET_FLAGS(CET_FLAGS) diff --git a/build/pkgs/gcc/patches/gcc-xcode15-warnings.patch b/build/pkgs/gcc/patches/gcc-xcode15-warnings.patch deleted file mode 100644 index 5d1a8ca9160..00000000000 --- a/build/pkgs/gcc/patches/gcc-xcode15-warnings.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/gcc/config/aarch64/darwin.h b/gcc/config/aarch64/darwin.h -index 5609c569dc1..9fcbfa3d777 100644 ---- a/gcc/config/aarch64/darwin.h -+++ b/gcc/config/aarch64/darwin.h -@@ -65,10 +65,6 @@ along with GCC; see the file COPYING3. If not see - #define DARWIN_NOPIE_SPEC \ - " %=1.1.0 +mpmath >=1.1.0, <1.4 diff --git a/build/pkgs/msolve/spkg-configure.m4 b/build/pkgs/msolve/spkg-configure.m4 new file mode 100644 index 00000000000..b0440b9b071 --- /dev/null +++ b/build/pkgs/msolve/spkg-configure.m4 @@ -0,0 +1,23 @@ +SAGE_SPKG_CONFIGURE([msolve], [ + PKG_CHECK_MODULES([msolve], [msolve >= 0.6.5], [], [ + AC_CACHE_CHECK([for msolve], [ac_cv_path_MSOLVE], + [AC_PATH_PROGS_FEATURE_CHECK([MSOLVE], [msolve], + [msolvin=$(mktemp) + msolvout=$(mktemp) + msolvchk=$(mktemp) + echo -e 'x,y\n0\nx-y,\nx*y-1' >$msolvin + changequote(<<, >>)dnl + echo -e '[0, [1,\n[[[-1, -1], [-1, -1]], [[1, 1], [1, 1]]]\n]]:' >$msolvchk + changequote([, ])dnl + $ac_path_MSOLVE -f $msolvin -o $msolvout + AS_IF([test x$(diff $msolvout $msolvchk) = x], + [ac_cv_path_MSOLVE=$ac_path_MSOLVE + ac_path_MSOLVE_found=:], + [sage_spkg_install_msolve=yes + AC_MSG_RESULT([could not find working msolve]) + ]) + ], [sage_spkg_install_msolve=yes + AC_MSG_RESULT([could not find working msolve]) + ])]) + ]) +]) diff --git a/build/pkgs/nauty/checksums.ini b/build/pkgs/nauty/checksums.ini index 9663569c7c4..41ff91d3186 100644 --- a/build/pkgs/nauty/checksums.ini +++ b/build/pkgs/nauty/checksums.ini @@ -1,4 +1,4 @@ tarball=nauty${VERSION}.tar.gz -sha1=672e9fc9dfd07201af37ee65807a9b493331ed92 -sha256=159d2156810a6bb240410cd61eb641add85088d9f15c888cdaa37b8681f929ce +sha1=23504eeae95a1a8a9abfd47029b4ff9da886471f +sha256=c97ab42bf48796a86a598bce3e9269047ca2b32c14fc23e07208a244fe52c4ee upstream_url=https://pallini.di.uniroma1.it/nauty${VERSION_MAJOR}_${VERSION_MINOR}_${VERSION_MICRO}.tar.gz diff --git a/build/pkgs/nauty/package-version.txt b/build/pkgs/nauty/package-version.txt index b8635c72de3..d578041c4b8 100644 --- a/build/pkgs/nauty/package-version.txt +++ b/build/pkgs/nauty/package-version.txt @@ -1 +1 @@ -2.8.8.p0 +2.8.9 diff --git a/build/pkgs/nauty/spkg-install.in b/build/pkgs/nauty/spkg-install.in index a2557c3cd8e..8f83cf3b841 100644 --- a/build/pkgs/nauty/spkg-install.in +++ b/build/pkgs/nauty/spkg-install.in @@ -8,7 +8,7 @@ fi # Nauty doesn't have an install target; passing a prefix to configure is # useless (but harmless) -sdh_configure CC="$CC -fPIC" $NAUTY_CONFIGURE +sdh_configure CC="$CC -fPIC" $NAUTY_CONFIGURE --enable-static --disable-shared sdh_make # No install target so we resort to manual copy @@ -18,7 +18,7 @@ countg countneg cubhamg deledgeg delptg dimacs2g directg dreadnaut dretodot dretog edgetransg genbg genbgL geng gengL genposetg genquarticg genrang genspecialg gentourng gentreeg genktreeg hamheuristic labelg linegraphg listg multig nbrhoodg newedgeg pickg planarg productg ranlabg ransubg shortg showg -subdivideg twohamg underlyingg vcolg watercluster2 NRswitchg" +subdivideg twohamg underlyingg uniqg vcolg watercluster2 NRswitchg" sdh_install $PROGRAMS "$SAGE_LOCAL/bin" sdh_install nauty.h "$SAGE_LOCAL/include/nauty" diff --git a/build/pkgs/nbclient/distros/fedora.txt b/build/pkgs/nbclient/distros/fedora.txt new file mode 100644 index 00000000000..17730f59437 --- /dev/null +++ b/build/pkgs/nbclient/distros/fedora.txt @@ -0,0 +1 @@ +python3-nbclient diff --git a/build/pkgs/nbconvert/distros/fedora.txt b/build/pkgs/nbconvert/distros/fedora.txt new file mode 100644 index 00000000000..e1f71656c82 --- /dev/null +++ b/build/pkgs/nbconvert/distros/fedora.txt @@ -0,0 +1 @@ +python3-nbconvert diff --git a/build/pkgs/nbformat/distros/fedora.txt b/build/pkgs/nbformat/distros/fedora.txt new file mode 100644 index 00000000000..7521f00141c --- /dev/null +++ b/build/pkgs/nbformat/distros/fedora.txt @@ -0,0 +1 @@ +python3-nbformat diff --git a/build/pkgs/nest_asyncio/distros/fedora.txt b/build/pkgs/nest_asyncio/distros/fedora.txt new file mode 100644 index 00000000000..9b465b8bab8 --- /dev/null +++ b/build/pkgs/nest_asyncio/distros/fedora.txt @@ -0,0 +1 @@ +python3-nest-asyncio diff --git a/build/pkgs/networkx/distros/fedora.txt b/build/pkgs/networkx/distros/fedora.txt index 293f943529a..67790667af2 100644 --- a/build/pkgs/networkx/distros/fedora.txt +++ b/build/pkgs/networkx/distros/fedora.txt @@ -1 +1 @@ -python-networkx +python3-networkx diff --git a/build/pkgs/nibabel/distros/fedora.txt b/build/pkgs/nibabel/distros/fedora.txt new file mode 100644 index 00000000000..19df029d93f --- /dev/null +++ b/build/pkgs/nibabel/distros/fedora.txt @@ -0,0 +1 @@ +python3-nibabel diff --git a/build/pkgs/normaliz/distros/fedora.txt b/build/pkgs/normaliz/distros/fedora.txt index b48a8dfa158..15c4e2a32b2 100644 --- a/build/pkgs/normaliz/distros/fedora.txt +++ b/build/pkgs/normaliz/distros/fedora.txt @@ -1 +1,2 @@ +libnormaliz libnormaliz-devel diff --git a/build/pkgs/notebook/distros/fedora.txt b/build/pkgs/notebook/distros/fedora.txt new file mode 100644 index 00000000000..70e09d9511a --- /dev/null +++ b/build/pkgs/notebook/distros/fedora.txt @@ -0,0 +1 @@ +python3-notebook diff --git a/build/pkgs/numpy/distros/fedora.txt b/build/pkgs/numpy/distros/fedora.txt index c8722b9f663..79d5c5a1429 100644 --- a/build/pkgs/numpy/distros/fedora.txt +++ b/build/pkgs/numpy/distros/fedora.txt @@ -1 +1 @@ -python-numpy +python3-numpy diff --git a/build/pkgs/onetbb/distros/fedora.txt b/build/pkgs/onetbb/distros/fedora.txt index 21e1846951c..118cbf13265 100644 --- a/build/pkgs/onetbb/distros/fedora.txt +++ b/build/pkgs/onetbb/distros/fedora.txt @@ -1 +1,2 @@ +tbb tbb-devel diff --git a/build/pkgs/openblas/checksums.ini b/build/pkgs/openblas/checksums.ini index e05d9117e1f..7d8c96ad5a0 100644 --- a/build/pkgs/openblas/checksums.ini +++ b/build/pkgs/openblas/checksums.ini @@ -1,4 +1,4 @@ tarball=openblas-VERSION.tar.gz -sha1=af6dce0e486e684be842053fcbd98eaf97e39749 -sha256=4e6e4f5cb14c209262e33e6816d70221a2fe49eb69eaf0a06f065598ac602c68 +sha1=f75172274a7ce69901605b8c759e2e0891c9b7f4 +sha256=f1003466ad074e9b0c8d421a204121100b0751c96fc6fcf3d1456bd12f8a00a1 upstream_url=https://github.com/xianyi/OpenBLAS/archive/vVERSION.tar.gz diff --git a/build/pkgs/openblas/package-version.txt b/build/pkgs/openblas/package-version.txt index e23fb32dfcb..9578e9400c1 100644 --- a/build/pkgs/openblas/package-version.txt +++ b/build/pkgs/openblas/package-version.txt @@ -1 +1 @@ -0.3.26 +0.3.28 diff --git a/build/pkgs/packaging/checksums.ini b/build/pkgs/packaging/checksums.ini index 4b1b2974bde..560bd2a20a4 100644 --- a/build/pkgs/packaging/checksums.ini +++ b/build/pkgs/packaging/checksums.ini @@ -1,4 +1,4 @@ tarball=packaging-VERSION-py3-none-any.whl -sha1=21573cef174a05ac2794b34f3841d6f9ea9fa507 -sha256=2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 +sha1=a050029d1e0c1b95b3ddcd566be4ad352cd42666 +sha256=5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 upstream_url=https://pypi.io/packages/py3/p/packaging/packaging-VERSION-py3-none-any.whl diff --git a/build/pkgs/packaging/distros/fedora.txt b/build/pkgs/packaging/distros/fedora.txt index 02ad855da9a..8f1c0ffc29f 100644 --- a/build/pkgs/packaging/distros/fedora.txt +++ b/build/pkgs/packaging/distros/fedora.txt @@ -1 +1 @@ -python-packaging +python3-packaging diff --git a/build/pkgs/packaging/package-version.txt b/build/pkgs/packaging/package-version.txt index d9133a54b63..0dad123924d 100644 --- a/build/pkgs/packaging/package-version.txt +++ b/build/pkgs/packaging/package-version.txt @@ -1 +1 @@ -24.0 +24.1 diff --git a/build/pkgs/palettable/SPKG.rst b/build/pkgs/palettable/SPKG.rst deleted file mode 100644 index b0557d6c128..00000000000 --- a/build/pkgs/palettable/SPKG.rst +++ /dev/null @@ -1,16 +0,0 @@ -palettable: Color palettes for Python -===================================== - -Description ------------ - -Color palettes for Python - -License -------- - -Upstream Contact ----------------- - -https://pypi.org/project/palettable/ - diff --git a/build/pkgs/palettable/checksums.ini b/build/pkgs/palettable/checksums.ini deleted file mode 100644 index 1ec683df7d8..00000000000 --- a/build/pkgs/palettable/checksums.ini +++ /dev/null @@ -1,4 +0,0 @@ -tarball=palettable-VERSION.tar.gz -sha1=4bdbbeae7f20bc71ce8246cb5269da2c3046ad62 -sha256=72feca71cf7d79830cd6d9181b02edf227b867d503bec953cf9fa91bf44896bd -upstream_url=https://pypi.io/packages/source/p/palettable/palettable-VERSION.tar.gz diff --git a/build/pkgs/palettable/dependencies b/build/pkgs/palettable/dependencies deleted file mode 100644 index 47296a7bace..00000000000 --- a/build/pkgs/palettable/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/palettable/distros/conda.txt b/build/pkgs/palettable/distros/conda.txt deleted file mode 100644 index 646dd7426bb..00000000000 --- a/build/pkgs/palettable/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -palettable diff --git a/build/pkgs/palettable/distros/fedora.txt b/build/pkgs/palettable/distros/fedora.txt new file mode 100644 index 00000000000..b40b0270c2c --- /dev/null +++ b/build/pkgs/palettable/distros/fedora.txt @@ -0,0 +1 @@ +python3-palettable diff --git a/build/pkgs/palettable/package-version.txt b/build/pkgs/palettable/package-version.txt deleted file mode 100644 index 15a27998172..00000000000 --- a/build/pkgs/palettable/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -3.3.0 diff --git a/build/pkgs/palettable/spkg-configure.m4 b/build/pkgs/palettable/spkg-configure.m4 deleted file mode 100644 index 76d3715e9fd..00000000000 --- a/build/pkgs/palettable/spkg-configure.m4 +++ /dev/null @@ -1 +0,0 @@ -SAGE_SPKG_CONFIGURE([palettable], [SAGE_PYTHON_PACKAGE_CHECK([palettable])]) diff --git a/build/pkgs/palettable/spkg-install.in b/build/pkgs/palettable/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/palettable/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/palettable/type b/build/pkgs/palettable/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/palettable/type +++ /dev/null @@ -1 +0,0 @@ -optional diff --git a/build/pkgs/palettable/version_requirements.txt b/build/pkgs/palettable/version_requirements.txt deleted file mode 100644 index 646dd7426bb..00000000000 --- a/build/pkgs/palettable/version_requirements.txt +++ /dev/null @@ -1 +0,0 @@ -palettable diff --git a/build/pkgs/pandocfilters/distros/fedora.txt b/build/pkgs/pandocfilters/distros/fedora.txt index e7a86d0373c..d0d4c24e15e 100644 --- a/build/pkgs/pandocfilters/distros/fedora.txt +++ b/build/pkgs/pandocfilters/distros/fedora.txt @@ -1 +1 @@ -python-pandocfilters +python3-pandocfilters diff --git a/build/pkgs/pari/spkg-configure.m4 b/build/pkgs/pari/spkg-configure.m4 index 5ece8b4891e..207487119a6 100644 --- a/build/pkgs/pari/spkg-configure.m4 +++ b/build/pkgs/pari/spkg-configure.m4 @@ -1,7 +1,8 @@ SAGE_SPKG_CONFIGURE([pari], [ dnl See gp_version below on how the version is computed from MAJV.MINV.PATCHV m4_pushdef([SAGE_PARI_MINVER],["134916"])dnl this version and higher allowed - m4_pushdef([SAGE_PARI_MAXVER],["999999"])dnl this version and higher not allowed + dnl Do not allow Pari 2.17 or later, see #38769: + m4_pushdef([SAGE_PARI_MAXVER],["135424"])dnl this version and higher not allowed SAGE_SPKG_DEPCHECK([gmp readline], [ AC_PATH_PROG([GP], [gp]) if test x$GP = x; then dnl GP test diff --git a/build/pkgs/pari_jupyter/distros/fedora.txt b/build/pkgs/pari_jupyter/distros/fedora.txt new file mode 100644 index 00000000000..3d44bea1b74 --- /dev/null +++ b/build/pkgs/pari_jupyter/distros/fedora.txt @@ -0,0 +1 @@ +python3-pari-jupyter diff --git a/build/pkgs/parso/distros/fedora.txt b/build/pkgs/parso/distros/fedora.txt new file mode 100644 index 00000000000..72fc6162fb9 --- /dev/null +++ b/build/pkgs/parso/distros/fedora.txt @@ -0,0 +1 @@ +python3-parso diff --git a/build/pkgs/pathspec/distros/fedora.txt b/build/pkgs/pathspec/distros/fedora.txt new file mode 100644 index 00000000000..e519f68e341 --- /dev/null +++ b/build/pkgs/pathspec/distros/fedora.txt @@ -0,0 +1 @@ +python3-pathspec diff --git a/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt b/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt index da97cd97866..ed4b3c9338a 100644 --- a/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt +++ b/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt @@ -6,3 +6,4 @@ perl-TermReadKey perl-XML-Writer perl-XML-LibXML perl-XML-LibXSLT +perl-SVG diff --git a/build/pkgs/pexpect/distros/fedora.txt b/build/pkgs/pexpect/distros/fedora.txt index 74d08141569..8d745ee4a07 100644 --- a/build/pkgs/pexpect/distros/fedora.txt +++ b/build/pkgs/pexpect/distros/fedora.txt @@ -1 +1 @@ -python-pexpect +python3-pexpect diff --git a/build/pkgs/pickleshare/distros/fedora.txt b/build/pkgs/pickleshare/distros/fedora.txt index 6d991a27d41..a00907d167b 100644 --- a/build/pkgs/pickleshare/distros/fedora.txt +++ b/build/pkgs/pickleshare/distros/fedora.txt @@ -1 +1 @@ -python-pickleshare +python3-pickleshare diff --git a/build/pkgs/pillow/distros/fedora.txt b/build/pkgs/pillow/distros/fedora.txt index 86dbb1d13b8..3319fcd7e0f 100644 --- a/build/pkgs/pillow/distros/fedora.txt +++ b/build/pkgs/pillow/distros/fedora.txt @@ -1 +1 @@ -python-pillow +python3-pillow diff --git a/build/pkgs/pint/SPKG.rst b/build/pkgs/pint/SPKG.rst deleted file mode 100644 index 05ee603025c..00000000000 --- a/build/pkgs/pint/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -pint: Physical quantities module -================================ - -Description ------------ - -Physical quantities module - -License -------- - -BSD - -Upstream Contact ----------------- - -https://pypi.org/project/Pint/ - diff --git a/build/pkgs/pint/checksums.ini b/build/pkgs/pint/checksums.ini deleted file mode 100644 index 7e883f32e55..00000000000 --- a/build/pkgs/pint/checksums.ini +++ /dev/null @@ -1,4 +0,0 @@ -tarball=Pint-VERSION.tar.gz -sha1=c14ac08ca2d5a68d79ea7cd2252dc7e2a572c56a -sha256=387cf04078dc7dfe4a708033baad54ab61d82ab06c4ee3d4922b1e45d5626067 -upstream_url=https://pypi.io/packages/source/p/pint/Pint-VERSION.tar.gz diff --git a/build/pkgs/pint/dependencies b/build/pkgs/pint/dependencies deleted file mode 100644 index 47296a7bace..00000000000 --- a/build/pkgs/pint/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/pint/distros/conda.txt b/build/pkgs/pint/distros/conda.txt deleted file mode 100644 index 45f523a5a6e..00000000000 --- a/build/pkgs/pint/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -pint diff --git a/build/pkgs/pint/distros/fedora.txt b/build/pkgs/pint/distros/fedora.txt new file mode 100644 index 00000000000..b0f2af45706 --- /dev/null +++ b/build/pkgs/pint/distros/fedora.txt @@ -0,0 +1 @@ +python3-pint diff --git a/build/pkgs/pint/package-version.txt b/build/pkgs/pint/package-version.txt deleted file mode 100644 index 847e9aef6d1..00000000000 --- a/build/pkgs/pint/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -0.20.1 diff --git a/build/pkgs/pint/spkg-configure.m4 b/build/pkgs/pint/spkg-configure.m4 deleted file mode 100644 index bfa78b5f327..00000000000 --- a/build/pkgs/pint/spkg-configure.m4 +++ /dev/null @@ -1 +0,0 @@ -SAGE_SPKG_CONFIGURE([pint], [SAGE_PYTHON_PACKAGE_CHECK([pint])]) diff --git a/build/pkgs/pint/spkg-install.in b/build/pkgs/pint/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/pint/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/pint/type b/build/pkgs/pint/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/pint/type +++ /dev/null @@ -1 +0,0 @@ -optional diff --git a/build/pkgs/pint/version_requirements.txt b/build/pkgs/pint/version_requirements.txt deleted file mode 100644 index a3031611162..00000000000 --- a/build/pkgs/pint/version_requirements.txt +++ /dev/null @@ -1 +0,0 @@ -Pint diff --git a/build/pkgs/pip/checksums.ini b/build/pkgs/pip/checksums.ini index 62ecf000278..0afec1866ed 100644 --- a/build/pkgs/pip/checksums.ini +++ b/build/pkgs/pip/checksums.ini @@ -1,4 +1,4 @@ tarball=pip-VERSION-py3-none-any.whl -sha1=e44313ae1e6af3c2bd3b60ab2fa8c34308d00555 -sha256=ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc +sha1=044a04440eef697c8ec9e03544117345c57aa683 +sha256=2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2 upstream_url=https://pypi.io/packages/py3/p/pip/pip-VERSION-py3-none-any.whl diff --git a/build/pkgs/pip/distros/fedora.txt b/build/pkgs/pip/distros/fedora.txt index 311c1b821ca..39bd9fc5097 100644 --- a/build/pkgs/pip/distros/fedora.txt +++ b/build/pkgs/pip/distros/fedora.txt @@ -1 +1 @@ -python-pip +python3-pip diff --git a/build/pkgs/pip/package-version.txt b/build/pkgs/pip/package-version.txt index d9133a54b63..9dc0ade5023 100644 --- a/build/pkgs/pip/package-version.txt +++ b/build/pkgs/pip/package-version.txt @@ -1 +1 @@ -24.0 +24.2 diff --git a/build/pkgs/pkgconfig/distros/fedora.txt b/build/pkgs/pkgconfig/distros/fedora.txt index 38a18b3565f..38e5106dd74 100644 --- a/build/pkgs/pkgconfig/distros/fedora.txt +++ b/build/pkgs/pkgconfig/distros/fedora.txt @@ -1 +1 @@ -python-pkgconfig +python3-pkgconfig diff --git a/build/pkgs/plantri/distros/fedora.txt b/build/pkgs/plantri/distros/fedora.txt new file mode 100644 index 00000000000..290ff321e46 --- /dev/null +++ b/build/pkgs/plantri/distros/fedora.txt @@ -0,0 +1 @@ +plantri diff --git a/build/pkgs/platformdirs/distros/fedora.txt b/build/pkgs/platformdirs/distros/fedora.txt new file mode 100644 index 00000000000..d65e921f05e --- /dev/null +++ b/build/pkgs/platformdirs/distros/fedora.txt @@ -0,0 +1 @@ +python3-platformdirs diff --git a/build/pkgs/pluggy/checksums.ini b/build/pkgs/pluggy/checksums.ini index 80a46179d43..3b6e7041f14 100644 --- a/build/pkgs/pluggy/checksums.ini +++ b/build/pkgs/pluggy/checksums.ini @@ -1,4 +1,4 @@ tarball=pluggy-VERSION-py3-none-any.whl -sha1=25492905db99a151fc86368f0cca518a5ee5a832 -sha256=d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7 +sha1=ccb7a74c114522f26e2c3b1884468343f54098d3 +sha256=44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 upstream_url=https://pypi.io/packages/py3/p/pluggy/pluggy-VERSION-py3-none-any.whl diff --git a/build/pkgs/pluggy/distros/fedora.txt b/build/pkgs/pluggy/distros/fedora.txt index c869e54c551..43a3acf0462 100644 --- a/build/pkgs/pluggy/distros/fedora.txt +++ b/build/pkgs/pluggy/distros/fedora.txt @@ -1 +1 @@ -python-pluggy +python3-pluggy diff --git a/build/pkgs/pluggy/package-version.txt b/build/pkgs/pluggy/package-version.txt index f0bb29e7638..bc80560fad6 100644 --- a/build/pkgs/pluggy/package-version.txt +++ b/build/pkgs/pluggy/package-version.txt @@ -1 +1 @@ -1.3.0 +1.5.0 diff --git a/build/pkgs/pluggy/version_requirements.txt b/build/pkgs/pluggy/version_requirements.txt index 11bdb5c1f5f..220b4cd0386 100644 --- a/build/pkgs/pluggy/version_requirements.txt +++ b/build/pkgs/pluggy/version_requirements.txt @@ -1 +1,2 @@ -pluggy +# warn_on_impl_args used by pytest +pluggy >=1.5 diff --git a/build/pkgs/polymake/SPKG.rst b/build/pkgs/polymake/SPKG.rst index 844b603a0e1..f1e6522d65c 100644 --- a/build/pkgs/polymake/SPKG.rst +++ b/build/pkgs/polymake/SPKG.rst @@ -50,14 +50,19 @@ you will need the ``local::lib`` Perl module installed:: cpan -i XML::Writer XML::LibXML XML::LibXSLT File::Slurp Term::ReadLine::Gnu JSON SVG MongoDB -Several Sage packages should be installed before installing the ``polymake`` -package to give a more featureful Polymake installation:: +Before installing the ``polymake`` package, refer to the SPKG pages for the following packages to ensure a more featureful Polymake installation: - sage -i 4ti2 latte_int topcom qhull +- [4ti2](https://doc.sagemath.org/html/en/reference/spkg/4ti2.html) +- [latte_int](https://doc.sagemath.org/html/en/reference/spkg/latte_int.html) +- [topcom](https://doc.sagemath.org/html/en/reference/spkg/topcom.html) +- [qhull](https://doc.sagemath.org/html/en/reference/spkg/qhull.html) -Software that would need to be installed manually (no Sage package -available) for a more featureful Polymake installation: ``azove``, ``porta``, -``vinci``, ``SplitsTree4``. +For additional software that may enhance your Polymake installation (but for which no Sage package is available), you can manually install the following: + +- ``azove`` +- ``porta`` +- ``vinci`` +- ``SplitsTree4`` Information on missing Polymake prerequisites after installing polymake:: @@ -65,10 +70,8 @@ Information on missing Polymake prerequisites after installing polymake:: (sage-sh) $ polymake polytope> show_unconfigured; -In order to use Polymake from Sage, you will also need the ``jupymake`` -package:: +In order to use Polymake from Sage, please refer to the [Jupymake SPKG page](https://doc.sagemath.org/html/en/reference/spkg/jupymake.html) for installation instructions. - sage -i jupymake Debugging polymake install problems diff --git a/build/pkgs/pplpy/distros/fedora.txt b/build/pkgs/pplpy/distros/fedora.txt index 579bdb042f6..f39eaff76ae 100644 --- a/build/pkgs/pplpy/distros/fedora.txt +++ b/build/pkgs/pplpy/distros/fedora.txt @@ -1 +1 @@ -python-pplpy +python3-pplpy diff --git a/build/pkgs/primecount/checksums.ini b/build/pkgs/primecount/checksums.ini index c3f0b9ce77d..4e9965b9965 100644 --- a/build/pkgs/primecount/checksums.ini +++ b/build/pkgs/primecount/checksums.ini @@ -1,4 +1,4 @@ tarball=primecount-VERSION.tar.gz -sha1=3854ef6c7f454086f31aa80d68f628c5b685d702 -sha256=e9a1fa2c41b9a7b84f2bead21b53cc9f7e2a5a0a34ddd818431a4e789aa44230 +sha1=dac5db8fb6aadd8b96fcb190073becd420a2cc31 +sha256=d867ac18cc52c0f7014682169988a76f39e4cd56f8ce78fb56e064499b1d66bb upstream_url=https://github.com/kimwalisch/primecount/archive/refs/tags/vVERSION.tar.gz diff --git a/build/pkgs/primecount/package-version.txt b/build/pkgs/primecount/package-version.txt index 38abeb202c0..9ad4d4f295e 100644 --- a/build/pkgs/primecount/package-version.txt +++ b/build/pkgs/primecount/package-version.txt @@ -1 +1 @@ -7.6 +7.14 diff --git a/build/pkgs/primecountpy/distros/fedora.txt b/build/pkgs/primecountpy/distros/fedora.txt new file mode 100644 index 00000000000..792a40abfc5 --- /dev/null +++ b/build/pkgs/primecountpy/distros/fedora.txt @@ -0,0 +1 @@ +python3-primecountpy diff --git a/build/pkgs/primesieve/checksums.ini b/build/pkgs/primesieve/checksums.ini index faae4fa7982..5bfc159aae0 100644 --- a/build/pkgs/primesieve/checksums.ini +++ b/build/pkgs/primesieve/checksums.ini @@ -1,4 +1,4 @@ tarball=primesieve-VERSION.tar.gz -sha1=cb0a7c49b37b51980fc610d3041b9591c67a460c -sha256=b29a7ec855764ce7474d00be03e1d83209bd097faa3778382dfb73a06866097e +sha1=19941abdd52bc44a8714ead8da4af0a7ddd92ec5 +sha256=eb7081adebe8030e93b3675c74ac603438d10a36792246b274c79f11d8a987ce upstream_url=https://github.com/kimwalisch/primesieve/archive/refs/tags/vVERSION.tar.gz diff --git a/build/pkgs/primesieve/package-version.txt b/build/pkgs/primesieve/package-version.txt index 2dbc24b32d3..800fd35ee86 100644 --- a/build/pkgs/primesieve/package-version.txt +++ b/build/pkgs/primesieve/package-version.txt @@ -1 +1 @@ -11.0 +12.4 diff --git a/build/pkgs/prometheus_client/distros/fedora.txt b/build/pkgs/prometheus_client/distros/fedora.txt new file mode 100644 index 00000000000..4d7723ec37e --- /dev/null +++ b/build/pkgs/prometheus_client/distros/fedora.txt @@ -0,0 +1 @@ +python3-prometheus_client diff --git a/build/pkgs/prompt_toolkit/distros/fedora.txt b/build/pkgs/prompt_toolkit/distros/fedora.txt index 967f8570d4f..c6d59003df0 100644 --- a/build/pkgs/prompt_toolkit/distros/fedora.txt +++ b/build/pkgs/prompt_toolkit/distros/fedora.txt @@ -1 +1 @@ -python-prompt-toolkit +python3-prompt-toolkit diff --git a/build/pkgs/ptyprocess/distros/fedora.txt b/build/pkgs/ptyprocess/distros/fedora.txt index 911a22468fc..ad4f6db1ca7 100644 --- a/build/pkgs/ptyprocess/distros/fedora.txt +++ b/build/pkgs/ptyprocess/distros/fedora.txt @@ -1 +1 @@ -python-ptyprocess +python3-ptyprocess diff --git a/build/pkgs/pure_eval/distros/fedora.txt b/build/pkgs/pure_eval/distros/fedora.txt new file mode 100644 index 00000000000..0feeff64011 --- /dev/null +++ b/build/pkgs/pure_eval/distros/fedora.txt @@ -0,0 +1 @@ +python3-pure-eval diff --git a/build/pkgs/py/distros/fedora.txt b/build/pkgs/py/distros/fedora.txt index b348d395fbd..81fefe60903 100644 --- a/build/pkgs/py/distros/fedora.txt +++ b/build/pkgs/py/distros/fedora.txt @@ -1 +1 @@ -python-py +python3-py diff --git a/build/pkgs/pybind11/distros/fedora.txt b/build/pkgs/pybind11/distros/fedora.txt new file mode 100644 index 00000000000..ac2d3cb471d --- /dev/null +++ b/build/pkgs/pybind11/distros/fedora.txt @@ -0,0 +1 @@ +python3-pybind11 diff --git a/build/pkgs/pybtex/distros/fedora.txt b/build/pkgs/pybtex/distros/fedora.txt new file mode 100644 index 00000000000..bdd39a48fde --- /dev/null +++ b/build/pkgs/pybtex/distros/fedora.txt @@ -0,0 +1 @@ +python3-pybtex diff --git a/build/pkgs/pycosat/distros/fedora.txt b/build/pkgs/pycosat/distros/fedora.txt index dab3122ef4c..c9ba620944f 100644 --- a/build/pkgs/pycosat/distros/fedora.txt +++ b/build/pkgs/pycosat/distros/fedora.txt @@ -1 +1 @@ -python-pycosat +python3-pycosat diff --git a/build/pkgs/pycparser/distros/fedora.txt b/build/pkgs/pycparser/distros/fedora.txt new file mode 100644 index 00000000000..0ba4f8b19f5 --- /dev/null +++ b/build/pkgs/pycparser/distros/fedora.txt @@ -0,0 +1 @@ +python3-pycparser diff --git a/build/pkgs/pycryptosat/distros/fedora.txt b/build/pkgs/pycryptosat/distros/fedora.txt new file mode 100644 index 00000000000..eb2adec7e72 --- /dev/null +++ b/build/pkgs/pycryptosat/distros/fedora.txt @@ -0,0 +1 @@ +python3-pycryptosat diff --git a/build/pkgs/pygments/distros/fedora.txt b/build/pkgs/pygments/distros/fedora.txt index f3e72a89c38..3ab37929b2c 100644 --- a/build/pkgs/pygments/distros/fedora.txt +++ b/build/pkgs/pygments/distros/fedora.txt @@ -1 +1 @@ -python-pygments +python3-pygments diff --git a/build/pkgs/pygraphviz/distros/fedora.txt b/build/pkgs/pygraphviz/distros/fedora.txt new file mode 100644 index 00000000000..0157eae2581 --- /dev/null +++ b/build/pkgs/pygraphviz/distros/fedora.txt @@ -0,0 +1 @@ +python3-pygraphviz diff --git a/build/pkgs/pyparsing/distros/fedora.txt b/build/pkgs/pyparsing/distros/fedora.txt new file mode 100644 index 00000000000..492a7ce0a69 --- /dev/null +++ b/build/pkgs/pyparsing/distros/fedora.txt @@ -0,0 +1 @@ +python3-pyparsing diff --git a/build/pkgs/pyproject_api/checksums.ini b/build/pkgs/pyproject_api/checksums.ini index cb551b5f7dd..dc2899fad91 100644 --- a/build/pkgs/pyproject_api/checksums.ini +++ b/build/pkgs/pyproject_api/checksums.ini @@ -1,4 +1,4 @@ tarball=pyproject_api-VERSION-py3-none-any.whl -sha1=5ea24c784a68fd0ef0228c332dc078ce64387eb8 -sha256=4c0116d60476b0786c88692cf4e325a9814965e2469c5998b830bba16b183675 +sha1=3723eb52bd6844f30f30f6f5b3723ce0f57a3cbf +sha256=2dc1654062c2b27733d8fd4cdda672b22fe8741ef1dde8e3a998a9547b071eeb upstream_url=https://pypi.io/packages/py3/p/pyproject_api/pyproject_api-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyproject_api/package-version.txt b/build/pkgs/pyproject_api/package-version.txt index 9c6d6293b1a..943f9cbc4ec 100644 --- a/build/pkgs/pyproject_api/package-version.txt +++ b/build/pkgs/pyproject_api/package-version.txt @@ -1 +1 @@ -1.6.1 +1.7.1 diff --git a/build/pkgs/pyproject_hooks/checksums.ini b/build/pkgs/pyproject_hooks/checksums.ini index 4688d10283b..fbb1f71394e 100644 --- a/build/pkgs/pyproject_hooks/checksums.ini +++ b/build/pkgs/pyproject_hooks/checksums.ini @@ -1,4 +1,4 @@ tarball=pyproject_hooks-VERSION-py3-none-any.whl -sha1=6c99163c52786fb97eac8b4e38cc13fa3af141a9 -sha256=283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 +sha1=f8c16752e1deea6a3e9a261c6725c1af408d04e7 +sha256=7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2 upstream_url=https://pypi.io/packages/py3/p/pyproject_hooks/pyproject_hooks-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyproject_hooks/package-version.txt b/build/pkgs/pyproject_hooks/package-version.txt index 3eefcb9dd5b..9084fa2f716 100644 --- a/build/pkgs/pyproject_hooks/package-version.txt +++ b/build/pkgs/pyproject_hooks/package-version.txt @@ -1 +1 @@ -1.0.0 +1.1.0 diff --git a/build/pkgs/pyproject_metadata/checksums.ini b/build/pkgs/pyproject_metadata/checksums.ini index 446d55ef265..91d3eb258c8 100644 --- a/build/pkgs/pyproject_metadata/checksums.ini +++ b/build/pkgs/pyproject_metadata/checksums.ini @@ -1,4 +1,4 @@ -tarball=pyproject-metadata-VERSION.tar.gz -sha1=41fba5c33917d77b9364fadb76e590e86789634d -sha256=0a94f18b108b9b21f3a26a3d541f056c34edcb17dc872a144a15618fed7aef67 -upstream_url=https://pypi.io/packages/source/p/pyproject_metadata/pyproject-metadata-VERSION.tar.gz +tarball=pyproject_metadata-VERSION-py3-none-any.whl +sha1=59998bbcd31cc63f3e95f3ad8120ff71326595a0 +sha256=ad858d448e1d3a1fb408ac5bac9ea7743e7a8bbb472f2693aaa334d2db42f526 +upstream_url=https://pypi.io/packages/py3/p/pyproject_metadata/pyproject_metadata-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyproject_metadata/dependencies b/build/pkgs/pyproject_metadata/dependencies index 3df264eee42..a0e3d35a70e 100644 --- a/build/pkgs/pyproject_metadata/dependencies +++ b/build/pkgs/pyproject_metadata/dependencies @@ -1,4 +1,4 @@ - packaging pyparsing | $(PYTHON_TOOLCHAIN) $(PYTHON) +packaging | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pyproject_metadata/distros/fedora.txt b/build/pkgs/pyproject_metadata/distros/fedora.txt new file mode 100644 index 00000000000..5180a07a0cc --- /dev/null +++ b/build/pkgs/pyproject_metadata/distros/fedora.txt @@ -0,0 +1 @@ +python3-pyproject-metadata diff --git a/build/pkgs/pyproject_metadata/package-version.txt b/build/pkgs/pyproject_metadata/package-version.txt index 39e898a4f95..a3df0a6959e 100644 --- a/build/pkgs/pyproject_metadata/package-version.txt +++ b/build/pkgs/pyproject_metadata/package-version.txt @@ -1 +1 @@ -0.7.1 +0.8.0 diff --git a/build/pkgs/pyproject_metadata/spkg-install.in b/build/pkgs/pyproject_metadata/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/pyproject_metadata/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/pyrsistent/distros/fedora.txt b/build/pkgs/pyrsistent/distros/fedora.txt new file mode 100644 index 00000000000..77485df49f0 --- /dev/null +++ b/build/pkgs/pyrsistent/distros/fedora.txt @@ -0,0 +1 @@ +python3-pyrsistent diff --git a/build/pkgs/pysingular/distros/fedora.txt b/build/pkgs/pysingular/distros/fedora.txt new file mode 100644 index 00000000000..6466894c1c7 --- /dev/null +++ b/build/pkgs/pysingular/distros/fedora.txt @@ -0,0 +1 @@ +python3-pysingular diff --git a/build/pkgs/pytest/SPKG.rst b/build/pkgs/pytest/SPKG.rst index 144ed70ce41..657d63a3e1f 100644 --- a/build/pkgs/pytest/SPKG.rst +++ b/build/pkgs/pytest/SPKG.rst @@ -4,7 +4,7 @@ pytest: Simple powerful testing with Python Description ----------- -pytest: simple powerful testing with Python +Simple powerful testing with Python License ------- diff --git a/build/pkgs/pytest/checksums.ini b/build/pkgs/pytest/checksums.ini new file mode 100644 index 00000000000..3b273f6dc6a --- /dev/null +++ b/build/pkgs/pytest/checksums.ini @@ -0,0 +1,4 @@ +tarball=pytest-VERSION-py3-none-any.whl +sha1=985b136db51e6729983433c6632564dc557f5fb6 +sha256=4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5 +upstream_url=https://pypi.io/packages/py3/p/pytest/pytest-VERSION-py3-none-any.whl diff --git a/build/pkgs/pytest/dependencies b/build/pkgs/pytest/dependencies index af3334a7daf..a22227f8adc 100644 --- a/build/pkgs/pytest/dependencies +++ b/build/pkgs/pytest/dependencies @@ -1,4 +1,4 @@ - pluggy packaging attrs py pyparsing importlib_metadata tomli | $(PYTHON_TOOLCHAIN) $(PYTHON) +iniconfig packaging pluggy exceptiongroup tomli colorama | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pytest/distros/fedora.txt b/build/pkgs/pytest/distros/fedora.txt new file mode 100644 index 00000000000..6665fd281bb --- /dev/null +++ b/build/pkgs/pytest/distros/fedora.txt @@ -0,0 +1 @@ +python3-pytest diff --git a/build/pkgs/pytest/package-version.txt b/build/pkgs/pytest/package-version.txt new file mode 100644 index 00000000000..9c78b761ea1 --- /dev/null +++ b/build/pkgs/pytest/package-version.txt @@ -0,0 +1 @@ +8.3.2 diff --git a/build/pkgs/pytest/type b/build/pkgs/pytest/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/pytest/type +++ b/build/pkgs/pytest/type @@ -1 +1 @@ -optional +standard diff --git a/build/pkgs/pytest/requirements.txt b/build/pkgs/pytest/version_requirements.txt similarity index 100% rename from build/pkgs/pytest/requirements.txt rename to build/pkgs/pytest/version_requirements.txt diff --git a/build/pkgs/pytest_mock/checksums.ini b/build/pkgs/pytest_mock/checksums.ini new file mode 100644 index 00000000000..181cfb34ea0 --- /dev/null +++ b/build/pkgs/pytest_mock/checksums.ini @@ -0,0 +1,4 @@ +tarball=pytest_mock-VERSION-py3-none-any.whl +sha1=7fcd316f0d08a7c961bec3ca0d756429ccb6b840 +sha256=0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f +upstream_url=https://pypi.io/packages/py3/p/pytest_mock/pytest_mock-VERSION-py3-none-any.whl diff --git a/build/pkgs/pytest_mock/dependencies b/build/pkgs/pytest_mock/dependencies index 720c11ec214..3330d413050 100644 --- a/build/pkgs/pytest_mock/dependencies +++ b/build/pkgs/pytest_mock/dependencies @@ -1,4 +1,4 @@ - pytest packaging attrs pluggy tomli py pyparsing | $(PYTHON_TOOLCHAIN) $(PYTHON) +pytest | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/valgrind/package-version.txt b/build/pkgs/pytest_mock/package-version.txt similarity index 100% rename from build/pkgs/valgrind/package-version.txt rename to build/pkgs/pytest_mock/package-version.txt diff --git a/build/pkgs/pytest_mock/type b/build/pkgs/pytest_mock/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/pytest_mock/type +++ b/build/pkgs/pytest_mock/type @@ -1 +1 @@ -optional +standard diff --git a/build/pkgs/pytest_mock/requirements.txt b/build/pkgs/pytest_mock/version_requirements.txt similarity index 100% rename from build/pkgs/pytest_mock/requirements.txt rename to build/pkgs/pytest_mock/version_requirements.txt diff --git a/build/pkgs/pytest_xdist/SPKG.rst b/build/pkgs/pytest_xdist/SPKG.rst index f962a257b37..5f6a74338cf 100644 --- a/build/pkgs/pytest_xdist/SPKG.rst +++ b/build/pkgs/pytest_xdist/SPKG.rst @@ -1,10 +1,10 @@ -pytest_xdist: pytest xdist plugin for distributed testing and loop-on-failing modes -=================================================================================== +pytest_xdist: Pytest xdist plugin for distributed testing, most importantly across multiple CPUs +================================================================================================ Description ----------- -pytest xdist plugin for distributed testing and loop-on-failing modes +Pytest xdist plugin for distributed testing, most importantly across multiple CPUs License ------- diff --git a/build/pkgs/pytest_xdist/checksums.ini b/build/pkgs/pytest_xdist/checksums.ini new file mode 100644 index 00000000000..97486be4a3a --- /dev/null +++ b/build/pkgs/pytest_xdist/checksums.ini @@ -0,0 +1,4 @@ +tarball=pytest_xdist-VERSION-py3-none-any.whl +sha1=de5b68f355cb51478ba9d5104da67a6359dee9e0 +sha256=9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7 +upstream_url=https://pypi.io/packages/py3/p/pytest_xdist/pytest_xdist-VERSION-py3-none-any.whl diff --git a/build/pkgs/pytest_xdist/dependencies b/build/pkgs/pytest_xdist/dependencies index 19d8b032667..15db1ed37bd 100644 --- a/build/pkgs/pytest_xdist/dependencies +++ b/build/pkgs/pytest_xdist/dependencies @@ -1,4 +1,4 @@ - pytest | $(PYTHON_TOOLCHAIN) $(PYTHON) +execnet pytest | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pytest_xdist/distros/fedora.txt b/build/pkgs/pytest_xdist/distros/fedora.txt new file mode 100644 index 00000000000..e6e6abd74ed --- /dev/null +++ b/build/pkgs/pytest_xdist/distros/fedora.txt @@ -0,0 +1 @@ +python3-pytest-xdist diff --git a/build/pkgs/pytest_xdist/package-version.txt b/build/pkgs/pytest_xdist/package-version.txt new file mode 100644 index 00000000000..9575d51bad2 --- /dev/null +++ b/build/pkgs/pytest_xdist/package-version.txt @@ -0,0 +1 @@ +3.6.1 diff --git a/build/pkgs/pytest_xdist/type b/build/pkgs/pytest_xdist/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/pytest_xdist/type +++ b/build/pkgs/pytest_xdist/type @@ -1 +1 @@ -optional +standard diff --git a/build/pkgs/pytest_xdist/requirements.txt b/build/pkgs/pytest_xdist/version_requirements.txt similarity index 100% rename from build/pkgs/pytest_xdist/requirements.txt rename to build/pkgs/pytest_xdist/version_requirements.txt diff --git a/build/pkgs/python3/checksums.ini b/build/pkgs/python3/checksums.ini index 73dddf24722..3bac47d26a6 100644 --- a/build/pkgs/python3/checksums.ini +++ b/build/pkgs/python3/checksums.ini @@ -1,4 +1,4 @@ tarball=Python-VERSION.tar.xz -sha1=c221421f3ba734daaf013dbdc7b48aa725cea18e -sha256=f6d419a6d8743ab26700801b4908d26d97e8b986e14f95de31b32de2b0e79554 +sha1=d9b83c17a717e1cbd3ab6bd14cfe3e508e6d87b2 +sha256=fa8a2e12c5e620b09f53e65bcd87550d2e5a1e2e04bf8ba991dcc55113876397 upstream_url=https://www.python.org/ftp/python/VERSION/Python-VERSION.tar.xz diff --git a/build/pkgs/python3/package-version.txt b/build/pkgs/python3/package-version.txt index 455808f8e19..d9506ceba51 100644 --- a/build/pkgs/python3/package-version.txt +++ b/build/pkgs/python3/package-version.txt @@ -1 +1 @@ -3.12.4 +3.12.5 diff --git a/build/pkgs/python3/spkg-install.in b/build/pkgs/python3/spkg-install.in index caf91d20c6d..2b2844ea02f 100644 --- a/build/pkgs/python3/spkg-install.in +++ b/build/pkgs/python3/spkg-install.in @@ -20,11 +20,7 @@ cd src sdh_make_install -i -j1 echo "Installing valgrind suppression file..." -if [ "$PKG_BASE" = "python2" ]; then - SUPP_FILENAME="python.supp" -else - SUPP_FILENAME="${PKG_BASE}.supp" -fi +SUPP_FILENAME="python3.supp" sdh_install -T Misc/valgrind-python.supp "$SAGE_LOCAL/lib/valgrind/$SUPP_FILENAME" if [ "$UNAME" = "Linux" ]; then @@ -42,14 +38,9 @@ else fi PYTHON_VERSION=$($PYTHON -c 'import sys; print("%d.%d" % sys.version_info[:2])') -if [ "$PKG_BASE" = "python2" ]; then - PYTHON_LDVERSION="$PYTHON_VERSION" - PYTHON_CONFIG_DIR="$SAGE_LOCAL/lib/python${PYTHON_VERSION}/config" -else - PYTHON_ABIFLAGS=$($PYTHON -c 'import sys; print(sys.abiflags)') - PYTHON_LDVERSION="$PYTHON_VERSION$PYTHON_ABIFLAGS" - PYTHON_CONFIG_DIR="$SAGE_LOCAL/lib/python${PYTHON_VERSION}/config-${PYTHON_LDVERSION}" -fi +PYTHON_ABIFLAGS=$($PYTHON -c 'import sys; print(sys.abiflags)') +PYTHON_LDVERSION="$PYTHON_VERSION$PYTHON_ABIFLAGS" +PYTHON_CONFIG_DIR="$SAGE_LOCAL/lib/python${PYTHON_VERSION}/config-${PYTHON_LDVERSION}" # On OS X with XCode 4, the presence of # $SAGE_LOCAL/lib/python3.x/config/libpython3.x.a causes problems with diff --git a/build/pkgs/python_build/distros/conda.txt b/build/pkgs/python_build/distros/conda.txt index 378eac25d31..162b1f739e8 100644 --- a/build/pkgs/python_build/distros/conda.txt +++ b/build/pkgs/python_build/distros/conda.txt @@ -1 +1 @@ -build +python-build diff --git a/build/pkgs/python_igraph/distros/fedora.txt b/build/pkgs/python_igraph/distros/fedora.txt index 03f8142066f..6b5f452ff56 100644 --- a/build/pkgs/python_igraph/distros/fedora.txt +++ b/build/pkgs/python_igraph/distros/fedora.txt @@ -1 +1,2 @@ python-igraph +python3-igraph-devel diff --git a/build/pkgs/pythran/distros/fedora.txt b/build/pkgs/pythran/distros/fedora.txt new file mode 100644 index 00000000000..86d056b339f --- /dev/null +++ b/build/pkgs/pythran/distros/fedora.txt @@ -0,0 +1 @@ +pythran diff --git a/build/pkgs/pytz/distros/fedora.txt b/build/pkgs/pytz/distros/fedora.txt index 2cccc9e61ec..1b20e1dbb77 100644 --- a/build/pkgs/pytz/distros/fedora.txt +++ b/build/pkgs/pytz/distros/fedora.txt @@ -1 +1 @@ -python-pytz +python3-pytz diff --git a/build/pkgs/pytz_deprecation_shim/distros/fedora.txt b/build/pkgs/pytz_deprecation_shim/distros/fedora.txt new file mode 100644 index 00000000000..f6cc43e10db --- /dev/null +++ b/build/pkgs/pytz_deprecation_shim/distros/fedora.txt @@ -0,0 +1 @@ +python3-pytz-deprecation-shim diff --git a/build/pkgs/pyzmq/distros/fedora.txt b/build/pkgs/pyzmq/distros/fedora.txt index 23f64d1f1a3..265a272130e 100644 --- a/build/pkgs/pyzmq/distros/fedora.txt +++ b/build/pkgs/pyzmq/distros/fedora.txt @@ -1 +1 @@ -python-pyzmq +python3-pyzmq diff --git a/build/pkgs/r/spkg-configure.m4 b/build/pkgs/r/spkg-configure.m4 deleted file mode 100644 index 0552d0c56ce..00000000000 --- a/build/pkgs/r/spkg-configure.m4 +++ /dev/null @@ -1,14 +0,0 @@ -SAGE_SPKG_CONFIGURE([r], [dnl - dnl https://rpy2.github.io/doc/v3.4.x/html/overview.html#requirements - m4_pushdef([SAGE_R_MINVER], ["3.5"]) - PKG_CHECK_MODULES([R], [libR >= SAGE_R_MINVER], [dnl - AC_PATH_PROG([R], [R]) - AS_IF([test "x$R" = x], [dnl - AC_MSG_NOTICE([R is not found]) - sage_spkg_install_r=yes - ], [dnl TODO: check that versions of R and libR match - sage_spkg_install_r=no - ]) - ], [sage_spkg_install_r=yes]) - m4_popdef([SAGE_R_MINVER]) -]) diff --git a/build/pkgs/r_jupyter/dependencies b/build/pkgs/r_jupyter/dependencies index 44078fe297e..c9895da2b6d 100644 --- a/build/pkgs/r_jupyter/dependencies +++ b/build/pkgs/r_jupyter/dependencies @@ -1 +1,5 @@ -notebook r +notebook rpy2 + +---------- +R is the real dependency. But SPKG r is a dummy package, and does not install R. +Since SPKG rpy2 checks for the system R, we put rpy2 as a dependency instead. diff --git a/build/pkgs/requests/distros/fedora.txt b/build/pkgs/requests/distros/fedora.txt index 93a7bc19b60..43147b2be74 100644 --- a/build/pkgs/requests/distros/fedora.txt +++ b/build/pkgs/requests/distros/fedora.txt @@ -1 +1 @@ -python-requests +python3-requests diff --git a/build/pkgs/rpy2/dependencies b/build/pkgs/rpy2/dependencies index b88615716d4..271ec08a7f9 100644 --- a/build/pkgs/rpy2/dependencies +++ b/build/pkgs/rpy2/dependencies @@ -1,4 +1,4 @@ - r cffi tzlocal pytz jinja2 | $(PYTHON_TOOLCHAIN) pycparser $(PYTHON) +cffi tzlocal pytz jinja2 | $(PYTHON_TOOLCHAIN) pycparser $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/rpy2/spkg-configure.m4 b/build/pkgs/rpy2/spkg-configure.m4 index 0cb3784ea9c..e19713c5775 100644 --- a/build/pkgs/rpy2/spkg-configure.m4 +++ b/build/pkgs/rpy2/spkg-configure.m4 @@ -1,14 +1,36 @@ SAGE_SPKG_CONFIGURE([rpy2], [ - SAGE_PYTHON_PACKAGE_CHECK([rpy2]) + SAGE_PYTHON_PACKAGE_CHECK([rpy2]) ], [dnl REQUIRED-CHECK - AC_REQUIRE([SAGE_SPKG_CONFIGURE_R]) - dnl rpy2 is only needed when there is a usable system R - AS_VAR_IF([sage_spkg_install_r], [yes], [dnl - AS_VAR_IF([sage_use_system_r], [installed], [dnl - dnl Legacy SPKG installation of r - AS_VAR_SET([SPKG_REQUIRE], [yes]) - ], [dnl No system package, no legacy SPKG installation - AS_VAR_SET([SPKG_REQUIRE], [no]) - ]) + dnl rpy2 is only needed when there is a usable system R + dnl Check for the R installation and version + dnl https://rpy2.github.io/doc/v3.4.x/html/overview.html#requirements + m4_pushdef([SAGE_R_MINVER], ["3.5"]) + PKG_CHECK_MODULES([R], [libR >= SAGE_R_MINVER], [dnl + AC_PATH_PROG([R_EXECUTABLE], [R]) + AS_IF([test "x$R_EXECUTABLE" = x], [dnl + AC_MSG_NOTICE([R is not found]) + dnl No R found, so do not require rpy2 package + AS_VAR_SET([SPKG_REQUIRE], [no]) + ], [dnl Extract R version + AC_MSG_CHECKING([for version of R executable]) + R_VERSION=$($R_EXECUTABLE --version | sed -n 's/^R version \([[0-9.]]*\).*/\1/p') + AC_MSG_RESULT([$R_VERSION]) + dnl Extract libR version + AC_MSG_CHECKING([for version of libR]) + LIBR_VERSION=$(pkg-config --modversion libR) + AC_MSG_RESULT([$LIBR_VERSION]) + dnl Compare R and libR versions + AS_IF([test "x$R_VERSION" = "x$LIBR_VERSION"], [dnl + AC_MSG_NOTICE([R and libR versions match ($R_VERSION)]) + dnl Good system R is found, require rpy2 package + AS_VAR_SET([SPKG_REQUIRE], [yes]) + ], [dnl R and libR versions do not match + AC_MSG_NOTICE([R version ($R_VERSION) does not match libR version ($LIBR_VERSION)]) + AS_VAR_SET([SPKG_REQUIRE], [no]) + ]) ]) + ], [dnl libR not found or outdated + AS_VAR_SET([SPKG_REQUIRE], [no]) + ]) + m4_popdef([SAGE_R_MINVER]) ]) diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 375190d9093..570eca0f747 100644 --- a/build/pkgs/sage_conf/version_requirements.txt +++ b/build/pkgs/sage_conf/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.4 +sage-conf ~= 10.5b8 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index f164da252b8..253a03aa504 100644 --- a/build/pkgs/sage_docbuild/version_requirements.txt +++ b/build/pkgs/sage_docbuild/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.4 +sage-docbuild ~= 10.5b8 diff --git a/build/pkgs/sage_setup/dependencies b/build/pkgs/sage_setup/dependencies index cae3faf9049..497a8118c28 100644 --- a/build/pkgs/sage_setup/dependencies +++ b/build/pkgs/sage_setup/dependencies @@ -1,4 +1,4 @@ - cython pkgconfig jinja2 $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/*.py $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/autogen/interpreters/specs/*.py $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/command/*.py | $(PYTHON_TOOLCHAIN) $(PYTHON) + cython pkgconfig jinja2 $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/*.py $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/autogen/interpreters/internal/specs/*.py $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/command/*.py | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index fb7d287156f..cdca5c8c377 100644 --- a/build/pkgs/sage_setup/version_requirements.txt +++ b/build/pkgs/sage_setup/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.4 +sage-setup ~= 10.5b8 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index 7abf79506b7..dd89096c7e5 100644 --- a/build/pkgs/sage_sws2rst/version_requirements.txt +++ b/build/pkgs/sage_sws2rst/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.4 +sage-sws2rst ~= 10.5b8 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index 9c4941c493e..82fcd9b2e70 100644 --- a/build/pkgs/sagelib/version_requirements.txt +++ b/build/pkgs/sagelib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.4 +sagemath-standard ~= 10.5b8 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 2565f173029..d7a5d2904e6 100644 --- a/build/pkgs/sagemath_bliss/version_requirements.txt +++ b/build/pkgs/sagemath_bliss/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.4 +sagemath-bliss ~= 10.5b8 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 6b7585e509b..efc07d283b2 100644 --- a/build/pkgs/sagemath_categories/version_requirements.txt +++ b/build/pkgs/sagemath_categories/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.4 +sagemath-categories ~= 10.5b8 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index 2b240b0cc98..cfc2259b00b 100644 --- a/build/pkgs/sagemath_coxeter3/version_requirements.txt +++ b/build/pkgs/sagemath_coxeter3/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.4 +sagemath-coxeter3 ~= 10.5b8 diff --git a/build/pkgs/sagemath_doc_html/dependencies b/build/pkgs/sagemath_doc_html/dependencies index 1d286fe50bc..40717629a77 100644 --- a/build/pkgs/sagemath_doc_html/dependencies +++ b/build/pkgs/sagemath_doc_html/dependencies @@ -1,4 +1,4 @@ -sagelib sphinx sphinx_copybutton sphinx_inline_tabs pplpy_doc | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon jmol ipywidgets jupyter_sphinx sage_docbuild elliptic_curves furo fpylll graphs +sagelib sphinx sphinx_copybutton sphinx_inline_tabs pplpy_doc | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon ipywidgets sage_docbuild elliptic_curves furo fpylll graphs # Building the documentation has many dependencies, because all # documented modules are imported and because we use matplotlib to diff --git a/build/pkgs/sagemath_doc_html/dependencies_optional b/build/pkgs/sagemath_doc_html/dependencies_optional new file mode 100644 index 00000000000..e9b59e89755 --- /dev/null +++ b/build/pkgs/sagemath_doc_html/dependencies_optional @@ -0,0 +1 @@ +jupyter_sphinx diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index acb1b9f636a..fc2b0a5c400 100644 --- a/build/pkgs/sagemath_environment/version_requirements.txt +++ b/build/pkgs/sagemath_environment/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.4 +sagemath-environment ~= 10.5b8 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index 7284fdc97cc..a37506596f3 100644 --- a/build/pkgs/sagemath_mcqd/version_requirements.txt +++ b/build/pkgs/sagemath_mcqd/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.4 +sagemath-mcqd ~= 10.5b8 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index e41cf324ac5..87631b79435 100644 --- a/build/pkgs/sagemath_meataxe/version_requirements.txt +++ b/build/pkgs/sagemath_meataxe/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.4 +sagemath-meataxe ~= 10.5b8 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index 19b35bd4a07..637d04fa986 100644 --- a/build/pkgs/sagemath_objects/version_requirements.txt +++ b/build/pkgs/sagemath_objects/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.4 +sagemath-objects ~= 10.5b8 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index b5cec69b83a..e721b5a1d1f 100644 --- a/build/pkgs/sagemath_repl/version_requirements.txt +++ b/build/pkgs/sagemath_repl/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.4 +sagemath-repl ~= 10.5b8 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 60fde833e03..3412b468da9 100644 --- a/build/pkgs/sagemath_sirocco/version_requirements.txt +++ b/build/pkgs/sagemath_sirocco/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.4 +sagemath-sirocco ~= 10.5b8 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index 6461411de40..b78e9037e85 100644 --- a/build/pkgs/sagemath_tdlib/version_requirements.txt +++ b/build/pkgs/sagemath_tdlib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.4 +sagemath-tdlib ~= 10.5b8 diff --git a/build/pkgs/sagetex/dependencies b/build/pkgs/sagetex/dependencies index af9b5f370fb..13610c4b390 100644 --- a/build/pkgs/sagetex/dependencies +++ b/build/pkgs/sagetex/dependencies @@ -1,4 +1,4 @@ - maxima scipy matplotlib pillow tachyon pyparsing | $(PYTHON) + maxima scipy matplotlib pillow tachyon pyparsing | $(PYTHON_TOOLCHAIN) $(PYTHON) To build SageTeX, you just need Python and pyparsing, but to test (SAGE_CHECK=yes) SageTeX, you actually need to run Sage, produce plots,... diff --git a/build/pkgs/sagetex/dependencies_check b/build/pkgs/sagetex/dependencies_check index d24e23242d4..ff812202db7 100644 --- a/build/pkgs/sagetex/dependencies_check +++ b/build/pkgs/sagetex/dependencies_check @@ -1,4 +1,4 @@ -$(SAGERUNTIME) sympy elliptic_curves jmol +$(SAGERUNTIME) sympy elliptic_curves To build SageTeX, you just need Python, but to test (SAGE_CHECK=yes) SageTeX, you actually need to run Sage, produce plots,... diff --git a/build/pkgs/scip/distros/fedora.txt b/build/pkgs/scip/distros/fedora.txt new file mode 100644 index 00000000000..3065c152171 --- /dev/null +++ b/build/pkgs/scip/distros/fedora.txt @@ -0,0 +1 @@ +scip diff --git a/build/pkgs/scipy/distros/fedora.txt b/build/pkgs/scipy/distros/fedora.txt index 7ff2882c1bf..12b366666d6 100644 --- a/build/pkgs/scipy/distros/fedora.txt +++ b/build/pkgs/scipy/distros/fedora.txt @@ -1 +1 @@ -python-scipy +python3-scipy diff --git a/build/pkgs/send2trash/distros/fedora.txt b/build/pkgs/send2trash/distros/fedora.txt new file mode 100644 index 00000000000..2f9abb6f584 --- /dev/null +++ b/build/pkgs/send2trash/distros/fedora.txt @@ -0,0 +1 @@ +python3-send2trash diff --git a/build/pkgs/setuptools/checksums.ini b/build/pkgs/setuptools/checksums.ini index 2436821630d..97d83ec2dd7 100644 --- a/build/pkgs/setuptools/checksums.ini +++ b/build/pkgs/setuptools/checksums.ini @@ -1,4 +1,4 @@ tarball=setuptools-VERSION-py3-none-any.whl -sha1=49841be6743b2d129d01d02d5fd339dd693c99dc -sha256=c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32 +sha1=3756539d45341ca5cec9e2dfe11539faa066f5cd +sha256=b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e upstream_url=https://pypi.io/packages/py3/s/setuptools/setuptools-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools/package-version.txt b/build/pkgs/setuptools/package-version.txt index 2a93f495d25..153e4cd6210 100644 --- a/build/pkgs/setuptools/package-version.txt +++ b/build/pkgs/setuptools/package-version.txt @@ -1 +1 @@ -69.5.1 +73.0.1 diff --git a/build/pkgs/setuptools_scm/distros/fedora.txt b/build/pkgs/setuptools_scm/distros/fedora.txt index 720fd2897be..2aa5ca12cba 100644 --- a/build/pkgs/setuptools_scm/distros/fedora.txt +++ b/build/pkgs/setuptools_scm/distros/fedora.txt @@ -1 +1 @@ -python-setuptools_scm +python3-setuptools_scm diff --git a/build/pkgs/singular_jupyter/distros/fedora.txt b/build/pkgs/singular_jupyter/distros/fedora.txt new file mode 100644 index 00000000000..b4632d4ad59 --- /dev/null +++ b/build/pkgs/singular_jupyter/distros/fedora.txt @@ -0,0 +1 @@ +python3-jupyter-kernel-singular diff --git a/build/pkgs/sirocco/distros/fedora.txt b/build/pkgs/sirocco/distros/fedora.txt index f2baa26096c..4d66f8f3619 100644 --- a/build/pkgs/sirocco/distros/fedora.txt +++ b/build/pkgs/sirocco/distros/fedora.txt @@ -1 +1,2 @@ sirocco +sirocco-devel diff --git a/build/pkgs/six/distros/fedora.txt b/build/pkgs/six/distros/fedora.txt index 787c5308ea4..68ff8595d0b 100644 --- a/build/pkgs/six/distros/fedora.txt +++ b/build/pkgs/six/distros/fedora.txt @@ -1 +1 @@ -python-six +python3-six diff --git a/build/pkgs/soplex/distros/fedora.txt b/build/pkgs/soplex/distros/fedora.txt new file mode 100644 index 00000000000..3fcd744bc92 --- /dev/null +++ b/build/pkgs/soplex/distros/fedora.txt @@ -0,0 +1 @@ +soplex diff --git a/build/pkgs/soupsieve/distros/fedora.txt b/build/pkgs/soupsieve/distros/fedora.txt new file mode 100644 index 00000000000..338c275caa9 --- /dev/null +++ b/build/pkgs/soupsieve/distros/fedora.txt @@ -0,0 +1 @@ +python3-soupsieve diff --git a/build/pkgs/sphinx/checksums.ini b/build/pkgs/sphinx/checksums.ini index 5cd194279be..463dfef26f9 100644 --- a/build/pkgs/sphinx/checksums.ini +++ b/build/pkgs/sphinx/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinx-VERSION-py3-none-any.whl -sha1=d4155cf2dbd768db9431fddcb7f53dd67caf56e1 -sha256=1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560 +sha1=f9af5608fbb188f12e38d3c09cdefeef40255365 +sha256=c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239 upstream_url=https://pypi.io/packages/py3/s/sphinx/sphinx-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinx/distros/fedora.txt b/build/pkgs/sphinx/distros/fedora.txt index db9f745da4c..7b28855c51b 100644 --- a/build/pkgs/sphinx/distros/fedora.txt +++ b/build/pkgs/sphinx/distros/fedora.txt @@ -1 +1 @@ -python-sphinx +python3-sphinx diff --git a/build/pkgs/sphinx/package-version.txt b/build/pkgs/sphinx/package-version.txt index ba6a7620d4e..25627bcf165 100644 --- a/build/pkgs/sphinx/package-version.txt +++ b/build/pkgs/sphinx/package-version.txt @@ -1 +1 @@ -7.2.6 +7.4.7 diff --git a/build/pkgs/sphinx/version_requirements.txt b/build/pkgs/sphinx/version_requirements.txt index 9003fdec2f8..d311e5262f2 100644 --- a/build/pkgs/sphinx/version_requirements.txt +++ b/build/pkgs/sphinx/version_requirements.txt @@ -1 +1 @@ -sphinx >=5.2, <8 +sphinx >=7.4.7, <9 diff --git a/build/pkgs/sphinx_basic_ng/distros/fedora.txt b/build/pkgs/sphinx_basic_ng/distros/fedora.txt index de43e3bfd58..71ac46b68ce 100644 --- a/build/pkgs/sphinx_basic_ng/distros/fedora.txt +++ b/build/pkgs/sphinx_basic_ng/distros/fedora.txt @@ -1 +1 @@ -python-sphinx-basic-ng +python3-sphinx-basic-ng diff --git a/build/pkgs/sphinx_copybutton/distros/fedora.txt b/build/pkgs/sphinx_copybutton/distros/fedora.txt index 2a99b129e49..576663b4a9d 100644 --- a/build/pkgs/sphinx_copybutton/distros/fedora.txt +++ b/build/pkgs/sphinx_copybutton/distros/fedora.txt @@ -1 +1 @@ -python-sphinx-copybutton +python3-sphinx-copybutton diff --git a/build/pkgs/sphinxcontrib_applehelp/distros/fedora.txt b/build/pkgs/sphinxcontrib_applehelp/distros/fedora.txt deleted file mode 100644 index 3754baa21f5..00000000000 --- a/build/pkgs/sphinxcontrib_applehelp/distros/fedora.txt +++ /dev/null @@ -1 +0,0 @@ -python-sphinxcontrib-applehelp diff --git a/build/pkgs/sphinxcontrib_devhelp/distros/fedora.txt b/build/pkgs/sphinxcontrib_devhelp/distros/fedora.txt index 0b1b3e44a6b..14357dcb071 100644 --- a/build/pkgs/sphinxcontrib_devhelp/distros/fedora.txt +++ b/build/pkgs/sphinxcontrib_devhelp/distros/fedora.txt @@ -1 +1 @@ -python-sphinxcontrib-devhelp +python3-sphinxcontrib-devhelp diff --git a/build/pkgs/sphinxcontrib_htmlhelp/distros/fedora.txt b/build/pkgs/sphinxcontrib_htmlhelp/distros/fedora.txt index 81390fd522f..3362a84ccc8 100644 --- a/build/pkgs/sphinxcontrib_htmlhelp/distros/fedora.txt +++ b/build/pkgs/sphinxcontrib_htmlhelp/distros/fedora.txt @@ -1 +1 @@ -python-sphinxcontrib-htmlhelp +python3-sphinxcontrib-htmlhelp diff --git a/build/pkgs/sphinxcontrib_jsmath/distros/fedora.txt b/build/pkgs/sphinxcontrib_jsmath/distros/fedora.txt deleted file mode 100644 index 2b4927832ac..00000000000 --- a/build/pkgs/sphinxcontrib_jsmath/distros/fedora.txt +++ /dev/null @@ -1 +0,0 @@ -python-sphinxcontrib-jsmath diff --git a/build/pkgs/sphinxcontrib_qthelp/distros/fedora.txt b/build/pkgs/sphinxcontrib_qthelp/distros/fedora.txt index 2c11924a5df..9e8fef277fc 100644 --- a/build/pkgs/sphinxcontrib_qthelp/distros/fedora.txt +++ b/build/pkgs/sphinxcontrib_qthelp/distros/fedora.txt @@ -1 +1 @@ -python-sphinxcontrib-qthelp +python3-sphinxcontrib-qthelp diff --git a/build/pkgs/sphinxcontrib_serializinghtml/distros/fedora.txt b/build/pkgs/sphinxcontrib_serializinghtml/distros/fedora.txt index 46d22be403f..1a8ea8424a7 100644 --- a/build/pkgs/sphinxcontrib_serializinghtml/distros/fedora.txt +++ b/build/pkgs/sphinxcontrib_serializinghtml/distros/fedora.txt @@ -1 +1 @@ -python-sphinxcontrib-serializinghtml +python3-sphinxcontrib-serializinghtml diff --git a/build/pkgs/sphinxcontrib_websupport/distros/fedora.txt b/build/pkgs/sphinxcontrib_websupport/distros/fedora.txt index a9a5a1a1727..2c8e8e8d34d 100644 --- a/build/pkgs/sphinxcontrib_websupport/distros/fedora.txt +++ b/build/pkgs/sphinxcontrib_websupport/distros/fedora.txt @@ -1 +1 @@ -python-sphinxcontrib-websupport +python3-sphinxcontrib-websupport diff --git a/build/pkgs/sqlalchemy/distros/fedora.txt b/build/pkgs/sqlalchemy/distros/fedora.txt new file mode 100644 index 00000000000..943697378a7 --- /dev/null +++ b/build/pkgs/sqlalchemy/distros/fedora.txt @@ -0,0 +1 @@ +python3-sqlalchemy diff --git a/build/pkgs/stack_data/distros/fedora.txt b/build/pkgs/stack_data/distros/fedora.txt new file mode 100644 index 00000000000..b5be058ebaa --- /dev/null +++ b/build/pkgs/stack_data/distros/fedora.txt @@ -0,0 +1 @@ +python3-stack-data diff --git a/build/pkgs/suitesparse/SPKG.rst b/build/pkgs/suitesparse/SPKG.rst index 7a9bd5d599c..ab673b390e7 100644 --- a/build/pkgs/suitesparse/SPKG.rst +++ b/build/pkgs/suitesparse/SPKG.rst @@ -2,26 +2,19 @@ suitesparse: A suite of sparse matrix software ============================================== SuiteSparse is a collection of software to deal with sparse matrix. It is -hosted at http://faculty.cse.tamu.edu/davis/suitesparse.html +hosted at https://people.engr.tamu.edu/davis/suitesparse.html with source code +now on github at https://github.com/DrTimothyAldenDavis/SuiteSparse -This spkg does a minimal install of suitesparse disabling the following +This spkg does a minimal install of suitesparse, only intalling the following -- metis -- GraphBLAS (need cmake) -- Mongoose (need cmake) +- AMD +- CAMD +- COLAMD +- CCOLAMD +- CHOLMOD +- UMFPACK -An external metis package can be used but we just disable its use. - -Patches: - -- The first patch disable the building of package using cmake. -- The second patch make sure we use sage's blas/lapack on OS X. By - default - suitesparse discard any configurations to use the accelerate framework. - -The building of metis is diabled by passing MY_METIS_LIB=none to make -(any value would have done) We also configure cholmod so it doesn't -require metis by passing CHOLMOD_CONFIG=-DNPARTITION to make. +Those are all the packages needed for cvxopt. Other configurations are self explanatory. diff --git a/build/pkgs/suitesparse/checksums.ini b/build/pkgs/suitesparse/checksums.ini index e05ee205baf..d3b1ad9641a 100644 --- a/build/pkgs/suitesparse/checksums.ini +++ b/build/pkgs/suitesparse/checksums.ini @@ -1,4 +1,4 @@ tarball=SuiteSparse-VERSION.tar.gz -sha1=83dd96b32701e12b7577acb7d9aea80138d7e46e -sha256=acb4d1045f48a237e70294b950153e48dce5b5f9ca8190e86c2b8c54ce00a7ee +sha1=aa2745d8e38d2c010e0a7256acd36eba1de19055 +sha256=8ea989f36be3646d0b0eecb06218698766ca06256c0de15a64350e993bf5c5f9 upstream_url=https://github.com/DrTimothyAldenDavis/SuiteSparse/archive/refs/tags/vVERSION.tar.gz diff --git a/build/pkgs/suitesparse/dependencies b/build/pkgs/suitesparse/dependencies index c9663df28f5..8ea6f6f523a 100644 --- a/build/pkgs/suitesparse/dependencies +++ b/build/pkgs/suitesparse/dependencies @@ -1 +1 @@ -$(BLAS) gfortran mpfr $(MP_LIBRARY) +$(BLAS) gfortran mpfr $(MP_LIBRARY) | cmake diff --git a/build/pkgs/suitesparse/package-version.txt b/build/pkgs/suitesparse/package-version.txt index 4e32c7b1caf..09a6d30847d 100644 --- a/build/pkgs/suitesparse/package-version.txt +++ b/build/pkgs/suitesparse/package-version.txt @@ -1 +1 @@ -5.10.1 +7.8.0 diff --git a/build/pkgs/suitesparse/patches/01-no_cmake_project.patch b/build/pkgs/suitesparse/patches/01-no_cmake_project.patch deleted file mode 100644 index 8b2b1a2666c..00000000000 --- a/build/pkgs/suitesparse/patches/01-no_cmake_project.patch +++ /dev/null @@ -1,90 +0,0 @@ -diff --git a/Makefile b/Makefile -index abd00d0f..10c31390 100644 ---- a/Makefile -+++ b/Makefile -@@ -16,7 +16,6 @@ include SuiteSparse_config/SuiteSparse_config.mk - # installs all libraries SuiteSparse/lib. - go: metis - ( cd SuiteSparse_config && $(MAKE) ) -- ( cd Mongoose && $(MAKE) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' ) - ( cd AMD && $(MAKE) ) - ( cd BTF && $(MAKE) ) - ( cd CAMD && $(MAKE) ) -@@ -34,7 +33,6 @@ ifneq ($(GPU_CONFIG),) - ( cd GPUQREngine && $(MAKE) ) - endif - ( cd SPQR && $(MAKE) ) -- ( cd GraphBLAS && $(MAKE) JOBS=$(JOBS) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' ) - ( cd SLIP_LU && $(MAKE) ) - # ( cd PIRO_BAND && $(MAKE) ) - # ( cd SKYLINE_SVD && $(MAKE) ) -@@ -46,7 +44,6 @@ endif - # (note that CSparse is not installed; CXSparse is installed instead) - install: metisinstall - ( cd SuiteSparse_config && $(MAKE) install ) -- ( cd Mongoose && $(MAKE) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' install ) - ( cd AMD && $(MAKE) install ) - ( cd BTF && $(MAKE) install ) - ( cd CAMD && $(MAKE) install ) -@@ -63,7 +60,6 @@ ifneq (,$(GPU_CONFIG)) - ( cd GPUQREngine && $(MAKE) install ) - endif - ( cd SPQR && $(MAKE) install ) -- ( cd GraphBLAS && $(MAKE) JOBS=$(JOBS) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' install ) - # ( cd PIRO_BAND && $(MAKE) install ) - # ( cd SKYLINE_SVD && $(MAKE) install ) - ( cd SLIP_LU && $(MAKE) install ) -@@ -126,7 +122,6 @@ endif - # the static library - library: metis - ( cd SuiteSparse_config && $(MAKE) ) -- ( cd Mongoose && $(MAKE) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' library ) - ( cd AMD && $(MAKE) library ) - ( cd BTF && $(MAKE) library ) - ( cd CAMD && $(MAKE) library ) -@@ -144,7 +139,6 @@ ifneq (,$(GPU_CONFIG)) - ( cd GPUQREngine && $(MAKE) library ) - endif - ( cd SPQR && $(MAKE) library ) -- ( cd GraphBLAS && $(MAKE) JOBS=$(JOBS) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' library ) - ( cd SLIP_LU && $(MAKE) library ) - # ( cd PIRO_BAND && $(MAKE) library ) - # ( cd SKYLINE_SVD && $(MAKE) library ) -@@ -154,7 +148,6 @@ endif - # both the dynamic and static libraries. - static: metis - ( cd SuiteSparse_config && $(MAKE) static ) -- ( cd Mongoose && $(MAKE) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' static ) - ( cd AMD && $(MAKE) static ) - ( cd BTF && $(MAKE) static ) - ( cd CAMD && $(MAKE) static ) -@@ -172,7 +165,6 @@ ifneq (,$(GPU_CONFIG)) - ( cd GPUQREngine && $(MAKE) static ) - endif - ( cd SPQR && $(MAKE) static ) -- ( cd GraphBLAS && $(MAKE) JOBS=$(JOBS) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' static ) - ( cd SLIP_LU && $(MAKE) static ) - # ( cd PIRO_BAND && $(MAKE) static ) - # ( cd SKYLINE_SVD && $(MAKE) static ) -@@ -291,21 +283,3 @@ else - @echo 'Using pre-installed METIS 5.1.0 library at ' '[$(MY_METIS_LIB)]' - endif - --# just compile GraphBLAS --gb: -- echo $(CMAKE_OPTIONS) -- ( cd GraphBLAS && $(MAKE) JOBS=$(JOBS) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' ) -- --# just install GraphBLAS --gbinstall: -- echo $(CMAKE_OPTIONS) -- ( cd GraphBLAS && $(MAKE) JOBS=$(JOBS) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' install ) -- --# just compile Mongoose --mon: -- ( cd Mongoose && $(MAKE) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' ) -- --# just install Mongoose --moninstall: -- ( cd Mongoose && $(MAKE) CMAKE_OPTIONS='$(CMAKE_OPTIONS)' install ) -- diff --git a/build/pkgs/suitesparse/patches/02-darwin_blas.patch b/build/pkgs/suitesparse/patches/02-darwin_blas.patch deleted file mode 100644 index 546bfc80642..00000000000 --- a/build/pkgs/suitesparse/patches/02-darwin_blas.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/SuiteSparse_config/SuiteSparse_config.mk b/SuiteSparse_config/SuiteSparse_config.mk -index 2fe1ab09..352ff593 100644 ---- a/SuiteSparse_config/SuiteSparse_config.mk -+++ b/SuiteSparse_config/SuiteSparse_config.mk -@@ -370,8 +370,8 @@ SUITESPARSE_VERSION = 5.10.1 - # command line in the Terminal, before doing 'make': - # xcode-select --install - CF += -fno-common -- BLAS ?= -framework Accelerate -- LAPACK ?= -framework Accelerate -+ #BLAS ?= -framework Accelerate -+ #LAPACK ?= -framework Accelerate - # OpenMP is not yet supported by default in clang - CFOPENMP = - LDLIBS += -rpath $(INSTALL_LIB) diff --git a/build/pkgs/suitesparse/patches/03-buildflags.patch b/build/pkgs/suitesparse/patches/03-buildflags.patch deleted file mode 100644 index 8a2c312be39..00000000000 --- a/build/pkgs/suitesparse/patches/03-buildflags.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/SuiteSparse_config/SuiteSparse_config.mk b/SuiteSparse_config/SuiteSparse_config.mk -index 352ff593..61f0076e 100644 ---- a/SuiteSparse_config/SuiteSparse_config.mk -+++ b/SuiteSparse_config/SuiteSparse_config.mk -@@ -72,9 +72,9 @@ SUITESPARSE_VERSION = 5.10.1 - # which puts the libraries in /yada/mylibs, include files in /yoda/myinc, - # and documentation in /solo/mydox. - INSTALL ?= $(SUITESPARSE) -- INSTALL_LIB ?= $(INSTALL)/lib -- INSTALL_INCLUDE ?= $(INSTALL)/include -- INSTALL_DOC ?= $(INSTALL)/share/doc/suitesparse-$(SUITESPARSE_VERSION) -+ INSTALL_LIB ?= $(DESTDIR)$(INSTALL)/lib -+ INSTALL_INCLUDE ?= $(DESTDIR)$(INSTALL)/include -+ INSTALL_DOC ?= $(DESTDIR)$(INSTALL)/share/doc/suitesparse-$(SUITESPARSE_VERSION) - - #--------------------------------------------------------------------------- - # parallel make -@@ -358,7 +358,7 @@ SUITESPARSE_VERSION = 5.10.1 - - ifeq ($(UNAME),Linux) - # add the realtime library, librt, and SuiteSparse/lib -- LDLIBS += -lrt -Wl,-rpath=$(INSTALL_LIB) -+ LDLIBS += -lrt - endif - - #--------------------------------------------------------------------------- -@@ -464,7 +464,7 @@ else - SO_TARGET = $(LIBRARY).$(VERSION).dylib - SO_OPTS += -dynamiclib -compatibility_version $(SO_VERSION) \ - -current_version $(VERSION) \ -- -Wl,-install_name -Wl,@rpath/$(SO_MAIN) \ -+ -Wl,-install_name -Wl,$(INSTALL)/lib/$(SO_MAIN) \ - -shared -undefined dynamic_lookup - # When a Mac *.dylib file is moved, this command is required - # to change its internal name to match its location in the filesystem: diff --git a/build/pkgs/suitesparse/patches/04-cygwin.patch b/build/pkgs/suitesparse/patches/04-cygwin.patch deleted file mode 100644 index f4118f86670..00000000000 --- a/build/pkgs/suitesparse/patches/04-cygwin.patch +++ /dev/null @@ -1,802 +0,0 @@ -diff --git a/AMD/Lib/Makefile b/AMD/Lib/Makefile -index 3b92f6a0..582bef2a 100644 ---- a/AMD/Lib/Makefile -+++ b/AMD/Lib/Makefile -@@ -2,7 +2,7 @@ - # AMD Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libamd -+LIBRARY = amd - VERSION = 2.4.6 - SO_VERSION = 2 - -@@ -81,19 +81,22 @@ libamdf77.a: $(AMDF77) - #------------------------------------------------------------------------------- - - # install AMD --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/amd.h $(INSTALL_INCLUDE) - $(CP) ../Doc/AMD_UserGuide.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/AMD_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/amd.h - chmod 644 $(INSTALL_DOC)/AMD_UserGuide.pdf - chmod 644 $(INSTALL_DOC)/AMD_README.txt -diff --git a/BTF/Lib/Makefile b/BTF/Lib/Makefile -index 85b7a264..6e4e2ec4 100644 ---- a/BTF/Lib/Makefile -+++ b/BTF/Lib/Makefile -@@ -2,7 +2,7 @@ - # BTF Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libbtf -+LIBRARY = btf - VERSION = 1.2.6 - SO_VERSION = 1 - -@@ -66,18 +66,21 @@ btf_l_strongcomp.o: ../Source/btf_strongcomp.c - #------------------------------------------------------------------------------- - - # install BTF --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/btf.h $(INSTALL_INCLUDE) - $(CP) ../README.txt $(INSTALL_DOC)/BTF_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/btf.h - chmod 644 $(INSTALL_DOC)/BTF_README.txt - -diff --git a/CAMD/Lib/Makefile b/CAMD/Lib/Makefile -index b3ae159e..27cb072a 100644 ---- a/CAMD/Lib/Makefile -+++ b/CAMD/Lib/Makefile -@@ -2,7 +2,7 @@ - # CAMD Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libcamd -+LIBRARY = camd - VERSION = 2.4.6 - SO_VERSION = 2 - -@@ -62,19 +62,22 @@ $(AR_TARGET): $(OBJ) - #------------------------------------------------------------------------------- - - # install CAMD --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/camd.h $(INSTALL_INCLUDE) - $(CP) ../Doc/CAMD_UserGuide.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/CAMD_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/camd.h - chmod 644 $(INSTALL_DOC)/CAMD_UserGuide.pdf - chmod 644 $(INSTALL_DOC)/CAMD_README.txt -diff --git a/CCOLAMD/Lib/Makefile b/CCOLAMD/Lib/Makefile -index 52c52eb9..18190be0 100644 ---- a/CCOLAMD/Lib/Makefile -+++ b/CCOLAMD/Lib/Makefile -@@ -2,7 +2,7 @@ - # CCOLAMD Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libccolamd -+LIBRARY = ccolamd - VERSION = 2.9.6 - SO_VERSION = 2 - -@@ -49,18 +49,21 @@ distclean: clean - - $(RM) -r $(PURGE) - - # install CCOLAMD --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/ccolamd.h $(INSTALL_INCLUDE) - $(CP) ../README.txt $(INSTALL_DOC)/CCOLAMD_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/ccolamd.h - chmod 644 $(INSTALL_DOC)/CCOLAMD_README.txt - -diff --git a/CHOLMOD/Lib/Makefile b/CHOLMOD/Lib/Makefile -index bc3eab69..d240b4cd 100644 ---- a/CHOLMOD/Lib/Makefile -+++ b/CHOLMOD/Lib/Makefile -@@ -2,7 +2,7 @@ - # CHOLMOD/Lib/Makefile: for compiling the CHOLMOD library - #=============================================================================== - --LIBRARY = libcholmod -+LIBRARY = cholmod - VERSION = 3.0.14 - SO_VERSION = 3 - -@@ -535,20 +535,23 @@ cholmod_l_gpu.o: ../GPU/cholmod_gpu.c - #------------------------------------------------------------------------------- - - # install CHOLMOD --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CXX) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/cholmod*.h $(INSTALL_INCLUDE) - $(RM) $(INSTALL_INCLUDE)/cholmod_internal.h - $(CP) ../Doc/CHOLMOD_UserGuide.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/CHOLMOD_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/cholmod*.h - chmod 644 $(INSTALL_DOC)/CHOLMOD_UserGuide.pdf - chmod 644 $(INSTALL_DOC)/CHOLMOD_README.txt -diff --git a/COLAMD/Lib/Makefile b/COLAMD/Lib/Makefile -index 2d0c5aa6..26720b62 100644 ---- a/COLAMD/Lib/Makefile -+++ b/COLAMD/Lib/Makefile -@@ -2,7 +2,7 @@ - # COLAMD Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libcolamd -+LIBRARY = colamd - VERSION = 2.9.6 - SO_VERSION = 2 - -@@ -49,18 +49,21 @@ distclean: clean - - $(RM) -r $(PURGE) - - # install COLAMD --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/colamd.h $(INSTALL_INCLUDE) - $(CP) ../README.txt $(INSTALL_DOC)/COLAMD_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/colamd.h - chmod 644 $(INSTALL_DOC)/COLAMD_README.txt - -diff --git a/CSparse/Lib/Makefile b/CSparse/Lib/Makefile -index e3f32cec..468f7a47 100644 ---- a/CSparse/Lib/Makefile -+++ b/CSparse/Lib/Makefile -@@ -14,7 +14,7 @@ - # install' in this Makefile only installs a static compiled library in - # CSparse/Lib. It does not install it for system-wide usage. - --LIBRARY = libcsparse -+LIBRARY = csparse - CF = $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -O - - I = -I../Include -diff --git a/CXSparse/Lib/Makefile b/CXSparse/Lib/Makefile -index a21e3607..270b8027 100644 ---- a/CXSparse/Lib/Makefile -+++ b/CXSparse/Lib/Makefile -@@ -2,7 +2,7 @@ - # CXSparse Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libcxsparse -+LIBRARY = cxsparse - VERSION = 3.2.0 - SO_VERSION = 3 - -@@ -113,18 +113,21 @@ distclean: clean - - $(RM) -r $(PURGE) - - # install CXSparse --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(CS) -+$(INSTALL_SO): $(CS) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/cs.h $(INSTALL_INCLUDE) - $(CP) ../README.txt $(INSTALL_DOC)/CXSPARSE_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/cs.h - chmod 644 $(INSTALL_DOC)/CXSPARSE_README.txt - -diff --git a/CXSparse_newfiles/Lib/Makefile b/CXSparse_newfiles/Lib/Makefile -index a21e3607..270b8027 100644 ---- a/CXSparse_newfiles/Lib/Makefile -+++ b/CXSparse_newfiles/Lib/Makefile -@@ -2,7 +2,7 @@ - # CXSparse Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libcxsparse -+LIBRARY = cxsparse - VERSION = 3.2.0 - SO_VERSION = 3 - -@@ -113,18 +113,21 @@ distclean: clean - - $(RM) -r $(PURGE) - - # install CXSparse --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(CS) -+$(INSTALL_SO): $(CS) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/cs.h $(INSTALL_INCLUDE) - $(CP) ../README.txt $(INSTALL_DOC)/CXSPARSE_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/cs.h - chmod 644 $(INSTALL_DOC)/CXSPARSE_README.txt - -diff --git a/GPUQREngine/Lib/Makefile b/GPUQREngine/Lib/Makefile -index adf46039..7bb34807 100644 ---- a/GPUQREngine/Lib/Makefile -+++ b/GPUQREngine/Lib/Makefile -@@ -2,7 +2,7 @@ - # GPUQREngine/Lib/Makefile: for compiling the GPUQREngine library - #------------------------------------------------------------------------------- - --LIBRARY = libGPUQREngine -+LIBRARY = GPUQREngine - VERSION = 1.0.5 - SO_VERSION = 1 - -@@ -129,17 +129,20 @@ $(AR_TARGET): $(OBJS) - #------------------------------------------------------------------------------- - - # install GPUQREngine. Note that the include files are not installed. --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJS) -+$(INSTALL_SO): $(OBJS) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CXX) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -- $(CP) ../README.txt $(INSTALL_DOC)/GPUQRENGINE_README.txt - chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif -+ $(CP) ../README.txt $(INSTALL_DOC)/GPUQRENGINE_README.txt - chmod 644 $(INSTALL_DOC)/GPUQRENGINE_README.txt - - # uninstall GPUQREngine -diff --git a/KLU/Lib/Makefile b/KLU/Lib/Makefile -index 2dc62cb4..35e2ed3a 100644 ---- a/KLU/Lib/Makefile -+++ b/KLU/Lib/Makefile -@@ -2,7 +2,7 @@ - # KLU Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libklu -+LIBRARY = klu - VERSION = 1.3.8 - SO_VERSION = 1 - -@@ -263,19 +263,22 @@ klu_l_memory.o: ../Source/klu_memory.c - #------------------------------------------------------------------------------- - - # install KLU --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/klu.h $(INSTALL_INCLUDE) - $(CP) ../Doc/KLU_UserGuide.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/KLU_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/klu.h - chmod 644 $(INSTALL_DOC)/KLU_UserGuide.pdf - chmod 644 $(INSTALL_DOC)/KLU_README.txt -diff --git a/LDL/Lib/Makefile b/LDL/Lib/Makefile -index 604ffa27..da5ecd53 100644 ---- a/LDL/Lib/Makefile -+++ b/LDL/Lib/Makefile -@@ -2,7 +2,7 @@ - # LDL Lib/Makefile - #------------------------------------------------------------------------------- - --LIBRARY = libldl -+LIBRARY = ldl - VERSION = 2.2.6 - SO_VERSION = 2 - -@@ -46,19 +46,22 @@ clean: - - $(RM) -r $(CLEAN) - - # install LDL --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/ldl.h $(INSTALL_INCLUDE) - $(CP) ../Doc/ldl_userguide.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/LDL_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/ldl.h - chmod 644 $(INSTALL_DOC)/ldl_userguide.pdf - chmod 644 $(INSTALL_DOC)/LDL_README.txt -diff --git a/RBio/Lib/Makefile b/RBio/Lib/Makefile -index 056715de..4ba42157 100644 ---- a/RBio/Lib/Makefile -+++ b/RBio/Lib/Makefile -@@ -2,7 +2,7 @@ - # RBio/Lib/Makefile: for compiling the RBio library - #=============================================================================== - --LIBRARY = librbio -+LIBRARY = rbio - VERSION = 2.2.6 - SO_VERSION = 2 - -@@ -60,18 +60,21 @@ RBio_i.o: ../Source/RBio.c - #------------------------------------------------------------------------------- - - # install RBio --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/RBio.h $(INSTALL_INCLUDE) - $(CP) ../README.txt $(INSTALL_DOC)/RBIO_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/RBio.h - chmod 644 $(INSTALL_DOC)/RBIO_README.txt - -diff --git a/SLIP_LU/Lib/Makefile b/SLIP_LU/Lib/Makefile -index 8b2221f1..b2153824 100644 ---- a/SLIP_LU/Lib/Makefile -+++ b/SLIP_LU/Lib/Makefile -@@ -8,7 +8,7 @@ - # To run a demo using the library - # cd ../Demo ; make - --LIBRARY = libsliplu -+LIBRARY = sliplu - VERSION = 1.0.2 - SO_VERSION = 1 - -@@ -63,19 +63,22 @@ $(AR_TARGET): $(OBJ) - #------------------------------------------------------------------------------- - - # install SLIP_LU --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/SLIP_LU.h $(INSTALL_INCLUDE) - $(CP) ../Doc/SLIP_LU_UserGuide.pdf $(INSTALL_DOC) - $(CP) ../README.md $(INSTALL_DOC)/SLIP_LU_README.md -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/SLIP_LU.h - chmod 644 $(INSTALL_DOC)/SLIP_LU_UserGuide.pdf - chmod 644 $(INSTALL_DOC)/SLIP_LU_README.md -diff --git a/SPQR/Lib/Makefile b/SPQR/Lib/Makefile -index 06c142ae..10e32007 100644 ---- a/SPQR/Lib/Makefile -+++ b/SPQR/Lib/Makefile -@@ -2,7 +2,7 @@ - # SuiteSparseQR/Lib/Makefile - #=============================================================================== - --LIBRARY = libspqr -+LIBRARY = spqr - VERSION = 2.0.9 - SO_VERSION = 2 - -@@ -242,22 +242,25 @@ spqrgpu_computeFrontStaging.o: ../SPQRGPU/spqrgpu_computeFrontStaging.cpp - #------------------------------------------------------------------------------- - - # install SPQR --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CXX) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/SuiteSparseQR.hpp $(INSTALL_INCLUDE) - $(CP) ../Include/SuiteSparseQR_C.h $(INSTALL_INCLUDE) - $(CP) ../Include/SuiteSparseQR_definitions.h $(INSTALL_INCLUDE) - $(CP) ../Include/spqr.hpp $(INSTALL_INCLUDE) - $(CP) ../Doc/spqr_user_guide.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/SPQR_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/SuiteSparseQR.hpp - chmod 644 $(INSTALL_INCLUDE)/SuiteSparseQR_C.h - chmod 644 $(INSTALL_INCLUDE)/SuiteSparseQR_definitions.h -diff --git a/SuiteSparse_GPURuntime/Lib/Makefile b/SuiteSparse_GPURuntime/Lib/Makefile -index 31f536a5..2f6c54d0 100644 ---- a/SuiteSparse_GPURuntime/Lib/Makefile -+++ b/SuiteSparse_GPURuntime/Lib/Makefile -@@ -2,7 +2,7 @@ - # SuiteSparse_GPURuntime/Lib/Makfile - #------------------------------------------------------------------------------- - --LIBRARY = libSuiteSparse_GPURuntime -+LIBRARY = SuiteSparse_GPURuntime - VERSION = 1.0.5 - SO_VERSION = 1 - -@@ -70,17 +70,20 @@ SuiteSparseGPU_Workspace_transfer.o: ../Source/SuiteSparseGPU_Workspace_transfer - #------------------------------------------------------------------------------- - - # install SuiteSparse_GPURuntime (just the library, not the include files) --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJS) -+$(INSTALL_SO): $(OBJS) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CXX) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -- $(CP) ../README.txt $(INSTALL_DOC)/GPURUNTIME_README.txt - chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif -+ $(CP) ../README.txt $(INSTALL_DOC)/GPURUNTIME_README.txt - chmod 644 $(INSTALL_DOC)/GPURUNTIME_README.txt - - # uninstall SuiteSparse_GPURuntime -diff --git a/SuiteSparse_config/Makefile b/SuiteSparse_config/Makefile -index 6a5814d4..e2acc53e 100644 ---- a/SuiteSparse_config/Makefile -+++ b/SuiteSparse_config/Makefile -@@ -6,7 +6,7 @@ SUITESPARSE ?= $(realpath $(CURDIR)/..) - export SUITESPARSE - - # version of SuiteSparse_config is also version of SuiteSparse meta-package --LIBRARY = libsuitesparseconfig -+LIBRARY = suitesparseconfig - VERSION = 5.10.1 - SO_VERSION = 5 - -@@ -44,19 +44,23 @@ clean: - - $(RM) -r $(CLEAN) - - # install SuiteSparse_config --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+# Likely redundant with the above but not on Cygwin -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -- $(CP) SuiteSparse_config.h $(INSTALL_INCLUDE) -- $(CP) README.txt $(INSTALL_DOC)/SUITESPARSECONFIG_README.txt - chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 755 $(INSTALL_LIB)/$(SO_PLAIN) -+endif -+ $(CP) SuiteSparse_config.h $(INSTALL_INCLUDE) -+ $(CP) README.txt $(INSTALL_DOC)/SUITESPARSECONFIG_README.txt - chmod 644 $(INSTALL_INCLUDE)/SuiteSparse_config.h - chmod 644 $(INSTALL_DOC)/SUITESPARSECONFIG_README.txt - -diff --git a/SuiteSparse_config/SuiteSparse_config.mk b/SuiteSparse_config/SuiteSparse_config.mk -index 61f0076e..5caa89dd 100644 ---- a/SuiteSparse_config/SuiteSparse_config.mk -+++ b/SuiteSparse_config/SuiteSparse_config.mk -@@ -16,14 +16,14 @@ SUITESPARSE_VERSION = 5.10.1 - # To disable these auto configurations, use 'make UNAME=custom' - - ifndef UNAME -- ifeq ($(OS),Windows_NT) -- # Cygwin Make on Windows has an $(OS) variable, but not uname. -- # Note that this option is untested. -- UNAME = Windows -- else -- # Linux and Darwin (Mac OSX) have been tested. -- UNAME := $(shell uname) -- endif -+ # Linux and Darwin (Mac OSX) have been tested. -+ UNAME := $(shell uname) -+ endif -+ -+ # On Cygwin we'll typically have UNAME=CYGWIN but just normalize -+ # to "CYGWIN" -+ ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) -+ UNAME := Cygwin - endif - - #=============================================================================== -@@ -170,6 +170,11 @@ SUITESPARSE_VERSION = 5.10.1 - # It places its shared *.so libraries in SuiteSparse/lib. - # Linux also requires the -lrt library (see below) - LDLIBS ?= -lm -+ # Note: Because suitesparse doesn't really do install staging properly -+ # (it just outputs final build artifacts directly to their install paths) -+ # we must add that path to our linker flags in order to link properly -+ # against built libraries; it might be better to fix the whole build -+ # system though). - LDFLAGS += -L$(INSTALL_LIB) - - # NOTE: Use of the Intel MKL BLAS is strongly recommended. The OpenBLAS can -@@ -447,21 +452,23 @@ SUITESPARSE_VERSION = 5.10.1 - - SO_OPTS = $(LDFLAGS) - --ifeq ($(UNAME),Windows) -- # Cygwin Make on Windows (untested) -- AR_TARGET = $(LIBRARY).lib -- SO_PLAIN = $(LIBRARY).dll -- SO_MAIN = $(LIBRARY).$(SO_VERSION).dll -- SO_TARGET = $(LIBRARY).$(VERSION).dll -- SO_INSTALL_NAME = echo -+ifeq ($(UNAME),Cygwin) -+ # Cygwin Make on Windows -+ AR_TARGET = lib$(LIBRARY).a -+ SO_TARGET = cyg$(LIBRARY)-$(SO_VERSION).dll -+ IMPLIB = lib$(LIBRARY).dll.a -+ SO_OPTS += -shared -Wl,--no-undefined -Wl,--out-implib -Wl,$(INSTALL_LIB)/$(IMPLIB) -+ INSTALL_DLL := $(DESTDIR)$(INSTALL)/bin -+ INSTALL_SO = $(INSTALL_DLL)/$(SO_TARGET) - else - # Mac or Linux/Unix -- AR_TARGET = $(LIBRARY).a -+ AR_TARGET = lib$(LIBRARY).a -+ INSTALL_SO = $(INSTALL_LIB)/$(SO_TARGET) - ifeq ($(UNAME),Darwin) - # Mac -- SO_PLAIN = $(LIBRARY).dylib -- SO_MAIN = $(LIBRARY).$(SO_VERSION).dylib -- SO_TARGET = $(LIBRARY).$(VERSION).dylib -+ SO_PLAIN = lib$(LIBRARY).dylib -+ SO_MAIN = lib$(LIBRARY).$(SO_VERSION).dylib -+ SO_TARGET = lib$(LIBRARY).$(VERSION).dylib - SO_OPTS += -dynamiclib -compatibility_version $(SO_VERSION) \ - -current_version $(VERSION) \ - -Wl,-install_name -Wl,$(INSTALL)/lib/$(SO_MAIN) \ -@@ -471,9 +478,9 @@ else - SO_INSTALL_NAME = install_name_tool -id - else - # Linux and other variants of Unix -- SO_PLAIN = $(LIBRARY).so -- SO_MAIN = $(LIBRARY).so.$(SO_VERSION) -- SO_TARGET = $(LIBRARY).so.$(VERSION) -+ SO_PLAIN = lib$(LIBRARY).so -+ SO_MAIN = lib$(LIBRARY).so.$(SO_VERSION) -+ SO_TARGET = lib$(LIBRARY).so.$(VERSION) - SO_OPTS += -shared -Wl,-soname -Wl,$(SO_MAIN) -Wl,--no-undefined - # Linux/Unix *.so files can be moved without modification: - SO_INSTALL_NAME = echo -diff --git a/SuiteSparse_config/xerbla/Makefile b/SuiteSparse_config/xerbla/Makefile -index db68a2ea..c59820c2 100644 ---- a/SuiteSparse_config/xerbla/Makefile -+++ b/SuiteSparse_config/xerbla/Makefile -@@ -16,9 +16,9 @@ library: - all: library - - ifeq ($(USE_FORTRAN),0) -- LIBRARY = libcerbla -+ LIBRARY = cerbla - else -- LIBRARY = libxerbla -+ LIBRARY = xerbla - endif - - include ../SuiteSparse_config.mk -@@ -44,19 +44,22 @@ $(AR_TARGET): $(DEPENDS) - - $(RM) xerbla.o - - # install libcerbla / libxerbla --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(DEPENDS) -+$(INSTALL_SO): $(DEPENDS) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(COMPILE) - $(CC) $(SO_OPTS) xerbla.o -o $@ - - $(RM) xerbla.o -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -- $(CP) xerbla.h $(INSTALL_INCLUDE) - chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif -+ $(CP) xerbla.h $(INSTALL_INCLUDE) - chmod 644 $(INSTALL_INCLUDE)/xerbla.h - - # uninstall libcerbla / libxerbla -diff --git a/UMFPACK/Lib/Makefile b/UMFPACK/Lib/Makefile -index 78436de1..0f291068 100644 ---- a/UMFPACK/Lib/Makefile -+++ b/UMFPACK/Lib/Makefile -@@ -2,7 +2,7 @@ - # UMFPACK Makefile for compiling on Unix systems - #------------------------------------------------------------------------------- - --LIBRARY = libumfpack -+LIBRARY = umfpack - VERSION = 5.7.9 - SO_VERSION = 5 - -@@ -288,20 +288,23 @@ clean: - - #------------------------------------------------------------------------------- - # install UMFPACK --install: $(AR_TARGET) $(INSTALL_LIB)/$(SO_TARGET) -+install: $(AR_TARGET) $(INSTALL_SO) - --$(INSTALL_LIB)/$(SO_TARGET): $(OBJ) -+$(INSTALL_SO): $(OBJ) - @mkdir -p $(INSTALL_LIB) -+ @mkdir -p $(dir $(INSTALL_SO)) - @mkdir -p $(INSTALL_INCLUDE) - @mkdir -p $(INSTALL_DOC) - $(CC) $(SO_OPTS) $^ -o $@ $(LDLIBS) -+ifneq ($(UNAME),Cygwin) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_PLAIN) ) - ( cd $(INSTALL_LIB) ; ln -sf $(SO_TARGET) $(SO_MAIN) ) -+ chmod 755 $(INSTALL_LIB)/$(SO_TARGET) -+endif - $(CP) ../Include/umfpack*.h $(INSTALL_INCLUDE) - $(CP) ../Doc/UMFPACK_UserGuide.pdf $(INSTALL_DOC) - $(CP) ../Doc/UMFPACK_QuickStart.pdf $(INSTALL_DOC) - $(CP) ../README.txt $(INSTALL_DOC)/UMFPACK_README.txt -- chmod 755 $(INSTALL_LIB)/$(SO_TARGET) - chmod 644 $(INSTALL_INCLUDE)/umfpack*.h - chmod 644 $(INSTALL_DOC)/UMFPACK_UserGuide.pdf - chmod 644 $(INSTALL_DOC)/UMFPACK_QuickStart.pdf diff --git a/build/pkgs/suitesparse/spkg-install.in b/build/pkgs/suitesparse/spkg-install.in index b6944a409ba..f7ef16bb48b 100644 --- a/build/pkgs/suitesparse/spkg-install.in +++ b/build/pkgs/suitesparse/spkg-install.in @@ -1,14 +1,21 @@ -# -*- shell-script -*- cd src -export CC="${CC-gcc} -std=c99" - -echo "print configuration" -$MAKE MY_METIS_LIB=none CHOLMOD_CONFIG=-DNPARTITION \ - BLAS="$(pkg-config --libs blas)" LAPACK="$(pkg-config --libs lapack)" \ - INSTALL="$SAGE_LOCAL" DESTDIR="$SAGE_DESTDIR" config -# build and install -$MAKE MY_METIS_LIB=none CHOLMOD_CONFIG=-DNPARTITION \ - BLAS="$(pkg-config --libs blas)" LAPACK="$(pkg-config --libs lapack)" \ - INSTALL="$SAGE_LOCAL" DESTDIR="$SAGE_DESTDIR" install +echo "Configuring suitesparse" +# * NSTATIC suitesparse defines some negative options like this one "NSTATIC=ON" means no static libraries. +# Hopefully these sill be normalised in the future. +# * SUITESPARSE_INCLUDEDIR_POSTFIX sets the subfolder in which to install headers. +# It default to "suitesparse" if not defined, which currently breaks dependencies. +# * SUITESPARSE_USE_FORTRAN make sure the fortran interface is off. There is trouble when +# gcc and gfortran version are not matching. +# * SUITESPARSE_ENABLE_PROJECTS semi column separated list of the desired packages. Default is +# all the packages in the suitesparse tarball. +# On macOS ARM cvxopt does not start if suitesparse uses @rpath, set explicit install name dir instead +sdh_cmake -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_INSTALL_NAME_DIR="$SAGE_LOCAL/lib" \ + -DCMAKE_MACOSX_RPATH=OFF \ + -DNSTATIC=ON \ + -DSUITESPARSE_USE_FORTRAN=OFF \ + -DSUITESPARSE_INCLUDEDIR_POSTFIX="" \ + -DSUITESPARSE_ENABLE_PROJECTS="suitesparse_config;amd;camd;ccolamd;colamd;cholmod;umfpack" +sdh_make_install diff --git a/build/pkgs/surf/distros/debian.txt b/build/pkgs/surf/distros/debian.txt new file mode 100644 index 00000000000..e33671ee0e3 --- /dev/null +++ b/build/pkgs/surf/distros/debian.txt @@ -0,0 +1 @@ +surf-alggeo diff --git a/build/pkgs/surf/distros/fedora.txt b/build/pkgs/surf/distros/fedora.txt new file mode 100644 index 00000000000..4cbab33147a --- /dev/null +++ b/build/pkgs/surf/distros/fedora.txt @@ -0,0 +1 @@ +surf-geometry diff --git a/build/pkgs/sympy/checksums.ini b/build/pkgs/sympy/checksums.ini index 30e67c20de6..17e31ea9f3d 100644 --- a/build/pkgs/sympy/checksums.ini +++ b/build/pkgs/sympy/checksums.ini @@ -1,4 +1,4 @@ tarball=sympy-VERSION-py3-none-any.whl -sha1=80fa00ab605295d61992ca3faa76771a62944527 -sha256=9b2cbc7f1a640289430e13d2a56f02f867a1da0190f2f99d8968c2f74da0e515 +sha1=e34c28a2aa2b677efe2f1b7cefe275e20d2e652c +sha256=c51d75517712f1aed280d4ce58506a4a88d635d6b5dd48b39102a7ae1f3fcfe9 upstream_url=https://pypi.io/packages/py3/s/sympy/sympy-VERSION-py3-none-any.whl diff --git a/build/pkgs/sympy/distros/fedora.txt b/build/pkgs/sympy/distros/fedora.txt index 126c88afd85..db423c87ba7 100644 --- a/build/pkgs/sympy/distros/fedora.txt +++ b/build/pkgs/sympy/distros/fedora.txt @@ -1 +1 @@ -python-sympy +python3-sympy diff --git a/build/pkgs/sympy/package-version.txt b/build/pkgs/sympy/package-version.txt index f8f4f03b3dc..61ce01b3011 100644 --- a/build/pkgs/sympy/package-version.txt +++ b/build/pkgs/sympy/package-version.txt @@ -1 +1 @@ -1.12.1 +1.13.2 diff --git a/build/pkgs/tachyon/checksums.ini b/build/pkgs/tachyon/checksums.ini index bd19e444c37..ad06308b255 100644 --- a/build/pkgs/tachyon/checksums.ini +++ b/build/pkgs/tachyon/checksums.ini @@ -1,3 +1,4 @@ -tarball=tachyon-VERSION.tar.bz2 -sha1=9866dc93e129115994708efa6e7ca16e20d58237 -sha256=e8888a410610e2726dca32f40f31ff34a83cb474b41e5a1e0ac8bbb175e1a466 +tarball=tachyon-VERSION.tar.gz +sha1=28ac9dc28ba90b47ab7e03c81bb2170ddbb1c248 +sha256=09203c102311149f5df5cc367409f96c725742666d19c24db5ba994d5a81a6f5 +upstream_url=https://users.ox.ac.uk/~coml0531/tmp/tachyon-VERSION.tar.gz diff --git a/build/pkgs/tachyon/distros/fedora.txt b/build/pkgs/tachyon/distros/fedora.txt index 035020a8d5b..9c9043ce249 100644 --- a/build/pkgs/tachyon/distros/fedora.txt +++ b/build/pkgs/tachyon/distros/fedora.txt @@ -1,2 +1,3 @@ +# deprecated in Fedora 40 tachyon tachyon-devel diff --git a/build/pkgs/tachyon/package-version.txt b/build/pkgs/tachyon/package-version.txt index ffe8ed95362..fcdf7816d66 100644 --- a/build/pkgs/tachyon/package-version.txt +++ b/build/pkgs/tachyon/package-version.txt @@ -1 +1 @@ -0.98.9.p7 +0.99.5.p0 diff --git a/build/pkgs/tachyon/patches/Make-arch.patch b/build/pkgs/tachyon/patches/Make-arch.patch index 0fcce9a58f0..81d53dda551 100644 --- a/build/pkgs/tachyon/patches/Make-arch.patch +++ b/build/pkgs/tachyon/patches/Make-arch.patch @@ -1,642 +1,19 @@ +diff --git a/unix/Make-arch b/unix/Make-arch +index 08afb85..dbeb691 100644 --- a/unix/Make-arch +++ b/unix/Make-arch -@@ -7,7 +7,8 @@ - - # Some machines don't have/need ranlib, in their case, use 'touch' - # this should be overridden by arch specific configuration lines below --RANLIB= touch -+# RANLIB=ranlib -+# Do not override Sage's RANLIB environment variable - - # MPI path setup, probably shouldn't need to be changed. - MPIINC=$(MPIDIR)/include -@@ -23,7 +24,8 @@ default: - @echo "--------------------------------------------------------------" - @echo " Parallel Versions " - @echo "" -- @echo " aix-thr - IBM AIX 5.x POSIX Threads " -+ @echo " aix-generic-thr - IBM AIX POSIX Threads. Generic compiler" -+ @echo " aix-thr - IBM AIX 5.x POSIX Threads. IBM compiler " - @echo " aix-64-thr - IBM AIX 5.x POSIX Threads, 64-bit " - @echo " aix-mpi - IBM AIX 5.x (SP) MPI " - @echo " asci-red-mpi - Intel ASCI Red MPI " -@@ -32,11 +34,12 @@ default: - @echo " cray-t3e-mpi - Cray T3E MPI " - @echo " cray-xt3-mpi - Cray XT3 MPI " - @echo " compaq-alphasc-mpi - Lemieux at PSC MPI " -+ @echo " hpux-generic-thr - HP/UX POSIX Threads. Generic compiler " - @echo " hpux-thr - HP/UX 11.x POSIX Threads " - @echo " hpux-ia64-thr - HP-UX IA-64, HP C, POSIX Threads " - @echo " irix6-thr - SGI IRIX 6.5.x POSIX Threads " - @echo " irix6-64-thr - SGI IRIX 6.5.x POSIX Threads, 64-bit " -- @echo " linux-beowulf-mpi - Scyld Linux MPI " -+ @echo " linux-beowulf-mpi - Scyld Linux MPI " - @echo " linux-alpha-ccc-qsw - Linux Alpha, Compaq C, MPI, QSWnet " - @echo " linux-lam - Linux MPI (OSC LAM) " - @echo " linux-lam-64 - Linux AMD64/EM64T, MPI, 64-bit " -@@ -48,13 +51,14 @@ default: - @echo "linux-ia64-thr-sgicc - Linux IA-64, SGI Pro64 Compilers " - @echo " macosx-thr - MacOS X PowerPC, POSIX Threads " - @echo " macosx-x86-thr - MacOS X Intel x86, POSIX Threads " -- @echo " solaris-ultra-hpc - Sun Solaris 9/10 ClusterTools 4.0 MPI " -- @echo " solaris-mpi - Sun Solaris 9/10 MPI (MPICH) " -- @echo " solaris-lam - Sun Solaris 9/10 MPI (OSC LAM) " -- @echo " solaris-thr - Sun Solaris 9/10 UI/Sun Threads " -- @echo " solaris-ultra-thr - Sun Solaris 9/10 UI/Sun Threads, US-1/2" -- @echo " solaris-ultra3-thr - Sun Solaris 9/10 UI/Sun Threads, US-III" -- @echo " solaris-64-thr - Sun Solaris 9/10 UI/Sun Threads, 64-bit" -+ @echo " solaris-ultra-hpc - Sun Solaris 9/10 ClusterTools 4.0 MPI " -+ @echo " solaris-mpi - Sun Solaris 9/10 MPI (MPICH) " -+ @echo " solaris-lam - Sun Solaris 9/10 MPI (OSC LAM) " -+ @echo " solaris-thr - Sun Solaris 9/10 UI/Sun Threads " -+ @echo "solaris-pthreads-gcc-64-bit - 64-bit (should work on SPARC or x64)" -+ @echo " solaris-ultra-thr - Sun Solaris 9/10 UI/Sun Threads, US-1/2" -+ @echo " solaris-ultra3-thr - Sun Solaris 9/10 UI/Sun Threads, US-III" -+ @echo " solaris-64-thr - Sun Solaris 9/10 UI/Sun Threads, 64-bit" - @echo "--------------------------------------------------------------" - @echo " Hybrid Parallel Versions " - @echo "" -@@ -63,9 +67,11 @@ default: - @echo "--------------------------------------------------------------" - @echo " Sequential Versions " - @echo "" -- @echo " aix - IBM AIX 5.x " -+ @echo " aix - IBM 5.x using IBM's compiler " -+ @echo " aix-generic - IBM AIX Generic compiler (gcc etc) " - @echo " bsd - OpenBSD/FreeBSD/NetBSD " -- @echo " hpux - HP/UX 11.x " -+ @echo " hpux - HP/UX 11.x HP's compiler " -+ @echo " hpux-generic - HP/UX 11.x Generic compiler (gcc etc) " - @echo " irix6 - SGI Irix 6.x " - @echo " linux - Linux " - @echo " linux-64 - Linux, AMD64/EM64T, GCC 3.x, 64-bit " -@@ -102,7 +108,7 @@ default: - @echo "Consult the README file in this directory for further info. " - - ## --## Intel ASCI Red (Janus) using MPI. -+## Intel ASCI Red (Janus) using MPI. - ## No pthreads on ASCI Red yet. I didn't bother with the cop() stuff - ## - asci-red-mpi: -@@ -118,7 +124,7 @@ asci-red-mpi: - - ## - ## IBM Blue Gene/L Parallel Supercomputer --## -+## - ## NOTE: strip breaks bluegene executables, they are dynamically re-linked - ## at runtime, so we must use /bin/true rather than strip - ## -@@ -137,7 +143,7 @@ bluegene-mpi: - ## Cray Parallel Vector Processor Machines Using Threads - ## - ## Tested on J90s, but should work on almost any of the Cray PVP systems. --## Note: This code is not currently vectorized, and you may be better -+## Note: This code is not currently vectorized, and you may be better - ## off running on a fast workstation, or even better, on a T3E!!! - ## - cray-thr: -@@ -228,7 +234,7 @@ cray-xt3-mpi: - ## - ## Architecture flags for the Intel Paragon XP/S Supercomputer using MPI - ## for message passing. NX is no longer supported by this software. --## Configurations supporting systems with MP-3 nodes are listed, -+## Configurations supporting systems with MP-3 nodes are listed, - ## Concurrent I/O is used by default. - ## - -@@ -264,8 +270,8 @@ paragon-mpi: - - - ## --## Architecture flags for the Intel iPSC/860 Multicomputer using MPI --## for message passing. NX is no longer supported by this software. -+## Architecture flags for the Intel iPSC/860 Multicomputer using MPI -+## for message passing. NX is no longer supported by this software. - ## Tested with the mpich distribution from Argonne National Labs - ## - -@@ -277,7 +283,7 @@ ipsc860-mpi: - "AR = ar860" \ - "ARFLAGS = r" \ - "STRIP = strip860" \ -- "LIBS = -L. -L$(MPILIB)/intelnx/ch_nx -ltachyon -lmpi $(MISCLIB) -lm" -+ "LIBS = -L. -L$(MPILIB)/intelnx/ch_nx -ltachyon -lmpi $(MISCLIB) -lm" - - ipsc860-mpi-debug: - $(MAKE) all \ -@@ -287,7 +293,7 @@ ipsc860-mpi-debug: - "AR = ar860" \ - "ARFLAGS = r" \ - "STRIP = touch " \ -- "LIBS = -L. -L$(MPILIB)/intelnx/ch_nx -ltachyon -lmpi $(MISCLIB) -lm" -+ "LIBS = -L. -L$(MPILIB)/intelnx/ch_nx -ltachyon -lmpi $(MISCLIB) -lm" - - - ## -@@ -296,22 +302,18 @@ ipsc860-mpi-debug: - tru64-alpha: - $(MAKE) all \ - "ARCH = tru64-alpha" \ -- "CC = cc" \ - "CFLAGS = -std1 -fast -O4 -arch host -tune host -w0 -verbose $(MISCFLAGS) -DLP64" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ - "LIBS = -non_shared -om -L. -ltachyon $(MISCLIB) -lm" - - ## --## OSF1 / Digital Unix 4.0b on Alpha processors with POSIX Threads -+## OSF1 / Digital Unix 4.0b on Alpha processors with POSIX Threads - ## - tru64-alpha-thr: - $(MAKE) all \ - "ARCH = tru64-alpha-thr" \ -- "CC = cc" \ - "CFLAGS = -speculate all -std1 -pthread -fast -O4 -arch host -tune host -verbose $(MISCFLAGS) -DTHR -DLP64" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" -@@ -319,9 +321,7 @@ tru64-alpha-thr: - tru64-alpha-thr-ogl: - $(MAKE) all \ - "ARCH = tru64-alpha-thr-ogl" \ -- "CC = cc" \ - "CFLAGS = -speculate all -std1 -pthread -fast -O4 -arch host -tune host -verbose $(MISCFLAGS) -DTHR -DUSEOPENGL -DLP64" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ - "LIBS = -L. -ltachyon $(TRU64_GLX_LIBS) $(MISCLIB) -lm" -@@ -448,7 +448,7 @@ solaris-ultra-hpc: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon -lmpi $(MISCLIB) -lm -lsocket -lnsl" -+ "LIBS = -L. -ltachyon -lmpi $(MISCLIB) -lm -lsocket -lnsl" - - solaris-mpi: - $(MAKE) all \ -@@ -458,7 +458,7 @@ solaris-mpi: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -L$(MPILIB)/solaris/ch_p4 -ltachyon -lmpi $(MISCLIB) -lm -lsocket -lnsl" -+ "LIBS = -L. -L$(MPILIB)/solaris/ch_p4 -ltachyon -lmpi $(MISCLIB) -lm -lsocket -lnsl" - - solaris-thr: - $(MAKE) all \ -@@ -473,9 +473,15 @@ solaris-thr: - solaris-pthreads-gcc: - $(MAKE) all \ - "ARCH = solaris-pthreads-gcc" \ -- "CC = gcc" \ - "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -D_REENTRANT -DSunOS $(MISCFLAGS) -DTHR -DUSEPOSIXTHREADS" \ -- "AR = ar" \ -+ "ARFLAGS = r" \ -+ "STRIP = strip" \ -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -+ -+solaris-pthreads-gcc-64-bit: -+ $(MAKE) all \ -+ "ARCH = solaris-pthreads-gcc" \ -+ "CFLAGS = -Wall -O4 -m64 -fomit-frame-pointer -ffast-math -D_REENTRANT -DSunOS $(MISCFLAGS) -DTHR -DUSEPOSIXTHREADS" \ - "ARFLAGS = r" \ - "STRIP = strip" \ +@@ -1471,6 +1471,25 @@ + "RANLIB = ranlib" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -@@ -618,7 +624,7 @@ solaris-ultra-hpc-ogl: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon -lmpi $(MISCLIB) $(SOLARIS_GLX_LIBS) $(MISCLIB) -lm -lsocket -lnsl" -+ "LIBS = -L. -ltachyon -lmpi $(MISCLIB) $(SOLARIS_GLX_LIBS) $(MISCLIB) -lm -lsocket -lnsl" - - solaris-ultra-pthreads-ogl: - $(MAKE) all \ -@@ -643,9 +649,7 @@ solaris-apcc-ultra-thr: - solaris-gcc-thr: - $(MAKE) all \ - "ARCH = solaris-gcc-thr" \ -- "CC = gcc" \ - "CFLAGS = -ansi -Wall -pedantic -O4 -mv8 -msupersparc -DSunOS $(MISCFLAGS) -DTHR -D_REENTRANT" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = touch" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lsocket -lthread" -@@ -653,9 +657,7 @@ solaris-gcc-thr: - solaris-gcc-thr-x11: - $(MAKE) all \ - "ARCH = solaris-gcc-thr-x11" \ -- "CC = gcc" \ - "CFLAGS = -ansi -Wall -pedantic -O4 -mv8 -msupersparc $(X11INC) -DSunOS $(MISCFLAGS) -DTHR -D_REENTRANT -DUSEX11" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = touch" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lsocket $(X11LIB) -lthread" -@@ -701,7 +703,7 @@ irix5-mpi: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -L$(MPILIB)/IRIX/ch_p4 -ltachyon -lmpi $(MISCLIB) -lm" -+ "LIBS = -L. -L$(MPILIB)/IRIX/ch_p4 -ltachyon -lmpi $(MISCLIB) -lm" - - irix5: - $(MAKE) all \ -@@ -710,7 +712,7 @@ irix5: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon $(MISCLIB) -lm" -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - irix6: - $(MAKE) all \ -@@ -719,7 +721,7 @@ irix6: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon $(MISCLIB) -lm" -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - irix6-purify: - $(MAKE) all \ -@@ -738,7 +740,7 @@ irix6-64-thr: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - - irix6-thr: - $(MAKE) all \ -@@ -747,7 +749,7 @@ irix6-thr: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - - irix6-thr-purify: - $(MAKE) all \ -@@ -766,7 +768,7 @@ irix6-thr-ogl: - "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "LIBS = -L. -ltachyon $(IRIX_GLX_LIBS) $(MISCLIB) -lm -lpthread" -+ "LIBS = -L. -ltachyon $(IRIX_GLX_LIBS) $(MISCLIB) -lm -lpthread" - - - ## -@@ -776,6 +778,8 @@ irix6-thr-ogl: - ## available yet, since access to a thread capable test machine is needed - ## for implementation. These configurations require xlc. - ## -+## The AIX and HP-UX target for generic compilers (e.g. gcc) have not been -+## properly tested. - - - aix: -@@ -788,6 +792,19 @@ aix: - "STRIP = strip" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - -+# The aix-generic target has not been tested. -+# It should work with gcc and perhaps other -+# compilers, as the compiler name is not -+# hard-coded. As long as CFLAGS are set properly -+# it should work both 32-bit and 64-bit. -+aix-generic: + ++# Linux Arm using gcc ++linux-arm: + $(MAKE) all \ -+ "ARCH = aix-generic" \ -+ "CFLAGS = $(CFLAGS) -DAIX $(MISCFLAGS)" \ -+ "ARFLAGS = r" \ -+ "STRIP = strip" \ -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm" -+ - aix-mpi: - $(MAKE) all \ - "ARCH = aix-mpi" \ -@@ -808,6 +825,19 @@ aix-thr: - "STRIP = strip" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - -+# The aix-generic-thr target has not been tested. -+# It should work with gcc and perhaps other -+# compilers, as the compiler name is not -+# hard-coded. As long as CFLAGS are set properly -+# it should work both 32-bit and 64-bit. -+aix-generic-thr: -+ $(MAKE) all \ -+ "ARCH = aix-generic-thr" \ -+ "CFLAGS = $(CFLAGS) -DAIX $(MISCFLAGS) -DTHR -D_REENTRANT" \ ++ "ARCH = linux-arm" \ ++ "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ + "ARFLAGS = r" \ + "STRIP = strip" \ -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -+ - aix-64-thr: - $(MAKE) all \ - "ARCH = aix-64-thr" \ -@@ -836,6 +866,32 @@ hpux: - "STRIP = strip" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - -+# The hpux-generic target has not been tested. -+# It should work with gcc and perhaps other -+# compilers, as the compiler name is not -+# hard-coded. As long as CFLAGS are set properly -+# it should work both 32-bit and 64-bit. -+hpux-generic: -+ $(MAKE) all \ -+ "ARCH = hpux-generic" \ -+ "CFLAGS = $(CFLAGS) -DHPUX $(MISCFLAGS)" \ -+ "ARFLAGS = r" \ -+ "STRIP = strip" \ -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm" -+ -+# The hpux-generic-thr target has not been tested. -+# It should work with gcc and perhaps other -+# compilers, as the compiler name is not -+# hard-coded. As long as CFLAGS are set properly -+# it should work both 32-bit and 64-bit. -+hpux-generic-thr: -+ $(MAKE) all \ -+ "ARCH = hpux-generic-thr" \ -+ "CFLAGS = $(CFLAGS) -DHPUX $(MISCFLAGS) -DTHR -D_REENTRANT" \ -+ "ARFLAGS = r" \ -+ "STRIP = strip" \ -+ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -+ - hpux-thr: - $(MAKE) all \ - "ARCH = hpux-thr" \ -@@ -867,67 +923,57 @@ hpux-ia64-thr: - next: - $(MAKE) all \ - "ARCH = next" \ -- "CC = cc" \ - "CFLAGS = -O -DNEXT $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - macosx: - $(MAKE) all \ - "ARCH = macosx" \ -- "CC = cc" \ - "CFLAGS = -Os -ffast-math -DBsd $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ -+ "LIBS = -L. -ltachyon $(MISCLIB)" -+ -+macosx-64: -+ $(MAKE) all \ -+ "ARCH = macosx" \ -+ "CFLAGS = -Os -m64 -ffast-math -DBsd $(MISCFLAGS)" \ -+ "ARFLAGS = r" \ -+ "STRIP = strip" \ - "LIBS = -L. -ltachyon $(MISCLIB)" - - macosx-thr: - $(MAKE) all \ - "ARCH = macosx-thr" \ -- "CC = cc" \ - "CFLAGS = -Os -ffast-math -DBsd -DTHR -F/System/Library/Frameworks $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lpthread -framework Carbon" - - macosx-altivec: - $(MAKE) all \ - "ARCH = macosx-altivec" \ -- "CC = cc" \ - "CFLAGS = -Os -mcpu=750 -faltivec -force_cpusubtype_ALL -fomit-frame-pointer -ffast-math -DBsd $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB)" - - macosx-x86-thr: - $(MAKE) all \ - "ARCH = macosx-x86-thr" \ -- "CC = cc" \ - "CFLAGS = -O2 -ffast-math -DBsd -DTHR -F/System/Library/Frameworks $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lpthread -framework Carbon" - - macosx-x86-thr-ogl: - $(MAKE) all \ - "ARCH = macosx-x86-thr-ogl" \ -- "CC = cc" \ - "CFLAGS = -O2 -ffast-math -DBsd -DTHR -I/usr/X11R6/include -F/System/Library/Frameworks $(MISCFLAGS) -DUSEOPENGL" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lpthread -L/usr/X11R6/lib -lGLU -lGL -lX11 -framework Carbon" - - -@@ -938,12 +984,9 @@ macosx-x86-thr-ogl: - beos: - $(MAKE) all \ - "ARCH = beos" \ -- "CC = gcc" \ - "CFLAGS = -O3 -fomit-frame-pointer -ffast-math $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB)" - - ## -@@ -954,23 +997,17 @@ beos: - bsd: - $(MAKE) all \ - "ARCH = bsd" \ -- "CC = gcc" \ - "CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DBsd $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - bsd-sparc: - $(MAKE) all \ - "ARCH = bsd-sparc" \ -- "CC = gcc" \ - "CFLAGS = -mv8 -msupersparc -O3 -fomit-frame-pointer -ffast-math -DBsd $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - ## -@@ -980,23 +1017,17 @@ bsd-sparc: - win32: - $(MAKE) all \ - "ARCH = win32" \ -- "CC = gcc" \ -- "CFLAGS = -mpentium -Wall -O3 -fomit-frame-pointer -ffast-math -DWIN32 $(MISCFLAGS)" \ -- "AR = ar" \ -+ "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DWIN32 $(MISCFLAGS)" \ - "ARFLAGS = r" \ - "STRIP = echo" \ -- "RANLIB = echo" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - win32-mpi: - $(MAKE) all \ - "ARCH = win32-mpi" \ -- "CC = gcc" \ -- "CFLAGS = -mpentium -Wall -O3 -fomit-frame-pointer -ffast-math -DWIN32 $(MISCFLAGS) -I'/Program files/MPIPro/INCLUDE' -DMPI" \ -- "AR = ar" \ -+ "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DWIN32 $(MISCFLAGS) -I'/Program files/MPIPro/INCLUDE' -DMPI" \ - "ARFLAGS = r" \ - "STRIP = echo" \ -- "RANLIB = echo" \ - "LIBS = -L. -L'/Program files/MPIPro/LIB' -ltachyon -lmpi $(MISCLIB) -lm" - - ## -@@ -1007,60 +1038,45 @@ win32-mpi: - linux: - $(MAKE) all \ - "ARCH = linux" \ -- "CC = gcc" \ - "CFLAGS = -m32 -Wall -O3 -g -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux on x86, using gcc - linux-profile: - $(MAKE) all \ - "ARCH = linux-profile" \ -- "CC = gcc" \ - "CFLAGS = -m32 -Wall -O3 -g -pg -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = touch" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux on x86, using gcc - linux-debug: - $(MAKE) all \ - "ARCH = linux-debug" \ -- "CC = gcc" \ - "CFLAGS = -m32 -Wall -g -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = touch" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux on AMD64/EM64T, using gcc - linux-64: - $(MAKE) all \ - "ARCH = linux-64" \ -- "CC = gcc" \ - "CFLAGS = -m64 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DLP64 $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux on AMD64/EM64T, using gcc - linux-64-debug: - $(MAKE) all \ - "ARCH = linux-64-debug" \ -- "CC = gcc" \ - "CFLAGS = -m64 -Wall -O -g -DLinux -DLP64 $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = touch" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - -@@ -1068,12 +1084,9 @@ linux-64-debug: - linux-64-thr: - $(MAKE) all \ - "ARCH = linux-64-thr" \ -- "CC = gcc" \ - "CFLAGS = -m64 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DLP64 -DTHR -D_REENTRANT $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - - -@@ -1081,17 +1094,14 @@ linux-64-thr: - linux-p4: - $(MAKE) all \ - "ARCH = linux-p4" \ -- "CC = gcc" \ - "CFLAGS = -mcpu=i686 -march=i686 -funroll-loops -fexpensive-optimizations -malign-double -fschedule-insns2 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux x86, on Intel P4 using Intel C 8.0 --# "CFLAGS = -axN -fast -ansi_alias -DLinux $(MISCFLAGS)" --# "CFLAGS = -restrict -O3 -tpp7 -vec_report3 -xiMKW -ip -unroll -static -DLinux $(MISCFLAGS)" -+# "CFLAGS = -axN -fast -ansi_alias -DLinux $(MISCFLAGS)" -+# "CFLAGS = -restrict -O3 -tpp7 -vec_report3 -xiMKW -ip -unroll -static -DLinux $(MISCFLAGS)" - linux-p4-icc: - $(MAKE) all \ - "ARCH = linux-p4-icc" \ -@@ -1119,23 +1129,17 @@ linux-p4-icc-thr: - linux-athlon: - $(MAKE) all \ - "ARCH = linux-athlon" \ -- "CC = gcc" \ - "CFLAGS = -mcpu=athlon -march=athlon -funroll-loops -fexpensive-optimizations -malign-double -fschedule-insns2 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - linux-athlon-thr: - $(MAKE) all \ - "ARCH = linux-athlon-thr" \ -- "CC = gcc" \ - "CFLAGS = -mcpu=athlon -march=athlon -funroll-loops -fexpensive-optimizations -malign-double -fschedule-insns2 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DTHR -D_REENTRANT $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - - -@@ -1167,21 +1171,25 @@ linux-athlon-pgcc: - linux-thr: - $(MAKE) all \ - "ARCH = linux-thr" \ -- "CC = gcc" \ - "CFLAGS = -m32 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DTHR -D_REENTRANT $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ ++ "RANLIB = ranlib" \ + "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" + +# Linux Arm using gcc, with threads @@ -646,199 +23,8 @@ + "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DTHR -D_REENTRANT $(MISCFLAGS)" \ + "ARFLAGS = r" \ + "STRIP = strip" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - ++ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" ++ # Linux x86 using gcc, threads, and OpenGL linux-thr-ogl: $(MAKE) all \ - "ARCH = linux-thr-ogl" \ -- "CC = cc" \ - "CFLAGS = -m32 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DTHR -D_REENTRANT $(MISCFLAGS) -DUSEOPENGL $(LINUX_GLX_INCS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = touch" \ - "LIBS = -L. -ltachyon $(MISCLIB) $(LINUX_GLX_LIBS) $(MISCLIB) -lm -lpthread" -@@ -1190,24 +1198,18 @@ linux-thr-ogl: - linux-beowulf-mpi-ogl: - $(MAKE) all \ - "ARCH = linux-beowulf-mpi" \ -- "CC = gcc" \ - "CFLAGS = -m32 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DMPI $(MISCFLAGS) -DUSEOPENGL $(LINUX_GLX_INCS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon -lmpi $(MISCLIB) $(LINUX_GLX_LIBS) $(MISCLIB) -lm" - - # Linux x86 using Scyld's beowulf distribution - linux-beowulf-mpi: - $(MAKE) all \ - "ARCH = linux-beowulf-mpi" \ -- "CC = gcc" \ - "CFLAGS = -m32 -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DMPI $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon -lmpi $(MISCLIB) -lm" - - # Linux x86 using LAM MPI -@@ -1239,10 +1241,8 @@ linux-mpi: - "ARCH = linux-mpi" \ - "CC = mpicc" \ - "CFLAGS = -DLinux -DMPI $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - linux-mpi-thr: -@@ -1250,10 +1250,8 @@ linux-mpi-thr: - "ARCH = linux-mpi-thr" \ - "CC = mpicc" \ - "CFLAGS = -DLinux -DMPI -DTHR $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - - linux-mpi-64: -@@ -1261,10 +1259,8 @@ linux-mpi-64: - "ARCH = linux-mpi-64" \ - "CC = mpicc" \ - "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -I$(LAMHOME)/h -DLinux -DMPI -DLP64 $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -L$(LAMHOME)/lib -ltachyon $(MISCLIB) -lm" - - -@@ -1297,48 +1293,36 @@ linux-lam-thr: - linux-ipaq: - $(MAKE) all \ - "ARCH = linux-ipaq" \ -- "CC = gcc" \ - "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - --# Linux PPC using gcc -+# Linux PPC using gcc - linux-ppc: - $(MAKE) all \ - "ARCH = linux-ppc" \ -- "CC = gcc" \ - "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - --# Linux PPC using gcc -+# Linux PPC using gcc - linux-ps2: - $(MAKE) all \ - "ARCH = linux-ps2" \ -- "CC = gcc" \ - "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - --# Linux Alpha using gcc -+# Linux Alpha using gcc - linux-alpha: - $(MAKE) all \ - "ARCH = linux-alpha" \ -- "CC = gcc" \ - "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux $(MISCFLAGS)" \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ -- "RANLIB = ranlib" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux Alpha using Compaq's compilers -@@ -1369,12 +1353,9 @@ linux-alpha-ccc-qsw: - linux-ia64: - $(MAKE) all \ - "ARCH = linux-ia64" \ -- "CC = cc" \ - "CFLAGS = -O3 -DLinux $(MISCFLAGS) -DLP64" \ -- "AR = ar" \ - "ARFLAGS = r" \ -- "STRIP = strip" \ -- "RANLIB = ranlib" \ -+ "STRIP = echo" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm" - - # Linux IA-64 using SGI compilers (Merced, Itanium, McKinley, etc) -@@ -1393,12 +1374,9 @@ linux-ia64-sgicc: - linux-ia64-thr: - $(MAKE) all \ - "ARCH = linux-ia64-thr" \ -- "CC = cc" \ - "CFLAGS = -O3 -DLinux -DTHR -D_REENTRANT $(MISCFLAGS) -DLP64" \ -- "AR = ar" \ - "ARFLAGS = r" \ -- "STRIP = strip" \ -- "RANLIB = ranlib" \ -+ "STRIP = echo" \ - "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" - - # Linux IA-64 using SGI compilers and threads (Merced, Itanium, McKinley, etc) -@@ -1421,9 +1399,7 @@ linux-ia64-thr-sgicc: - sgi-altix-mpi: - $(MAKE) all \ - "ARCH = sgi-altix-mpi" \ -- "CC = cc" \ - "CFLAGS = -Wall -O3 -DLinux -DMPI " \ -- "AR = ar" \ - "ARFLAGS = r" \ - "STRIP = strip" \ - "LIBS = -ltachyon -lmpi $(MISCLIB) -lm " -@@ -1432,7 +1408,7 @@ sgi-altix-mpi: - ## CSPI PowerPC Based Multicomputers Running VXWORKS - ## This configuration works for the machine at MPI Software Technologies - ## Uses MSTI MPI/Pro for message passing. --## -+## - cspi-ppc-mpi: - $(MAKE) all \ - "ARCH = cspi-ppc-mpi" \ -@@ -1448,7 +1424,7 @@ cspi-ppc-mpi: - ## Mercury PowerPC Based Multicomputers Running MCOS - ## This configuration works for the machine at MPI Software Technologies - ## Uses MSTI MPI/Pro for message passing. --## -+## - mercury-ppc-mpi: - $(MAKE) all \ - "ARCH = mercury-ppc-mpi" \ -@@ -1469,7 +1445,7 @@ mercury-ppc-mpi-rtvi: - "ARFLAGS = -r" \ - "STRIP = /bin/touch" \ - "LIBS = -L. -L/opt/MPIPro/lib ../compile/mercury-ppc-mpi-rtvi/libmgf.a ../compile/mercury-ppc-mpi-rtvi/libray.a $(RTVILIB) -lmpi.appc" -- @echo "Note: Remember to link ray.ppc -> ray before your first run." -+ @echo "Note: Remember to link ray.ppc -> ray before your first run." - @echo " Also, copy your machines file into your CWD." - - ## -@@ -1490,7 +1466,7 @@ mercury-i860-rtvi: - ## Mercury i860 Based Multicomputers Running MCOS - ## This configuration works for the machine at MPI Software Technologies - ## Uses MSTI MPI/Pro for message passing. --## -+## - mercury-i860-mpi: - $(MAKE) all \ - "ARCH = mercury-i860-mpi" \ diff --git a/build/pkgs/tachyon/patches/Make-config.patch b/build/pkgs/tachyon/patches/Make-config.patch deleted file mode 100644 index f52089d60f4..00000000000 --- a/build/pkgs/tachyon/patches/Make-config.patch +++ /dev/null @@ -1,111 +0,0 @@ ---- a/unix/Make-config 2011-03-13 11:01:07.000000000 +0000 -+++ b/unix/Make-config 2016-07-04 15:29:57.982923000 +0000 -@@ -9,7 +9,7 @@ - # - # Raytracer configuration variables - # Edit any of these settings as needed to configure directories --# and source areas for your system. -+# and source areas for your system. - # Important items to edit are the X11 configuration and MPI - # - -@@ -62,7 +62,7 @@ - # UMR CS Dept - #MPIDIR=/software/all/mpi - --# Default Paragon XP/S location -+# Default Paragon XP/S location - #MPIDIR=/usr - - # Cornell Theory Center SP-2 splogin.tc.cornell.edu -@@ -72,7 +72,7 @@ - ########################################################################## - # Floating point configuration: - # Leaving this blank will cause the library to use double precision floats --# Setting -DUSESINGLEFLT causes the library to use single precision floats -+# Setting -DUSESINGLEFLT causes the library to use single precision floats - ########################################################################## - # Uncomment the following line for double precision floating point math - # uses about twice as much memory per object as single precision math. -@@ -86,7 +86,7 @@ - # Object mailbox storage configuration: - # Leaving this blank will cause the library to use auxiliary mailbox data - # structures for improving the effectiveness of grid-based ray tracing. --# Setting -DDISABLEMBOX will cause the library to disable this feature. -+# Setting -DDISABLEMBOX will cause the library to disable this feature. - ########################################################################## - # Uncomment the following line for full mailbox data structure use, this - # uses a per-thread mailbox array, or either 4 or 8 bytes per scene object, -@@ -94,15 +94,15 @@ - MBOX= - # Uncomment the following line to disable the use of mailbox data structures, - # this eliminates per-thread storage normally allocated for the mailbox --# data structure, but may incur a rendering speed penalty. -+# data structure, but may incur a rendering speed penalty. - #MBOX=-DDISABLEMBOX - - - ########################################################################## - # JPEG support configuration: - # JPEGINC is the directory where your Independent JPEG Group include files --# are made available. JPEGLIB is the directory where your Independent --# JPEG Group libraries are made available. -+# are made available. JPEGLIB is the directory where your Independent -+# JPEG Group libraries are made available. - # - # IJG JPEG library version 6b can be downloaded from: - # http://www.ijg.org/files/ -@@ -122,29 +122,25 @@ - # PNG support configuration: - # PNGINC is the directory where your libpng and libz include files - # are made available. PNGLIB is the directory where your libpng --# and libz libraries are made available. -+# and libz libraries are made available. - # - # LibPNG can be downlaoded from: - # http://www.libpng.org/ - ########################################################################## - # Uncomment the following lines to disable PNG support --USEPNG= --PNGINC= --PNGLIB= -+USEPNG= -DUSEPNG -+PNGINC= -I$(SAGE_LOCAL)/include -+PNGLIB= -L$(SAGE_LOCAL)/lib -lpng -lz - --# Uncomment the following lines to enable PNG support --#USEPNG= -DUSEPNG --#PNGINC= -I/usr/local/include --#PNGLIB= -L/usr/local/lib -lpng -lz - - - ########################################################################## --# OMF (Open Media Framework) configuration -+# OMF (Open Media Framework) configuration - # Requires OMF Toolkit version 2.x - ########################################################################## - #OMFDIR = /disk5/users/johns/graphics/OMFKT202/Toolkit - #OMFINC = -I$(OMFDIR)/include -I$(OMFDIR)/kitomfi -I$(OMFDIR)/bento -I$(OMFDIR)/jpeg -I$(OMFDIR)/portinc -I$(OMFDIR)/avidjpg --#OMFLIB = -L$(OMFDIR)/DO_sun5_opt/usr/lib -lAJPG -lOMFI -lbento -ljpeg -+#OMFLIB = -L$(OMFDIR)/DO_sun5_opt/usr/lib -lAJPG -lOMFI -lbento -ljpeg - #OMFDEF = -DUSEOMF - - -@@ -159,7 +155,7 @@ - - ########################################################################## - # Spaceball I/O library configuration: --# A spaceball can used for fly-throughs of scenes when running on -+# A spaceball can used for fly-throughs of scenes when running on - # a fast multiprocessor, parallel machine, or PC cluster. - # - # Libsball can be downloaded from: -@@ -172,7 +168,7 @@ - - ########################################################################## - # MGF Materials and Geometry Format scene parser library --# If enabled, this allows Tachyon to read MGF scene files using -+# If enabled, this allows Tachyon to read MGF scene files using - # compiled-in MGF scene parser code. - ########################################################################## - #MGFDIR=../../libmgf diff --git a/build/pkgs/tachyon/patches/Makefile.patch b/build/pkgs/tachyon/patches/Makefile.patch deleted file mode 100644 index 08bb0ced8a0..00000000000 --- a/build/pkgs/tachyon/patches/Makefile.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/unix/Makefile -+++ b/unix/Makefile -@@ -121,35 +121,35 @@ ${MGFLIB} : ../libmgf/Makefile - }; - - ${ARCHDIR}/tachyon : ${RAYLIB} ${PARSELIB} ${OBJDIR}/main.o ${OBJDIR}/getargs.o ${OBJDIR}/parse.o ${OBJDIR}/nffparse.o ${OBJDIR}/glwin.o ${OBJDIR}/spaceball.o ${OBJDIR}/trackball.o ${PARSEOBJS} -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/tachyon ${OBJDIR}/main.o ${OBJDIR}/getargs.o ${OBJDIR}/parse.o ${OBJDIR}/nffparse.o ${OBJDIR}/glwin.o ${OBJDIR}/spaceball.o ${OBJDIR}/trackball.o ${PARSEOBJS} -L${RAYLIBDIR} ${PARSELIBS} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/tachyon ${LDFLAGS} ${OBJDIR}/main.o ${OBJDIR}/getargs.o ${OBJDIR}/parse.o ${OBJDIR}/nffparse.o ${OBJDIR}/glwin.o ${OBJDIR}/spaceball.o ${OBJDIR}/trackball.o ${PARSEOBJS} -L${RAYLIBDIR} ${PARSELIBS} ${LIBS} - ${STRIP} ${ARCHDIR}/tachyon - - ${ARCHDIR}/animray : ${RAYLIB} ${OBJDIR}/mainanim.o -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animray ${OBJDIR}/mainanim.o -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animray ${LDFLAGS} ${OBJDIR}/mainanim.o -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/animray - - ${ARCHDIR}/animspheres : ${RAYLIB} ${OBJDIR}/animspheres.o -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animspheres ${OBJDIR}/animspheres.o -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animspheres ${LDFLAGS} ${OBJDIR}/animspheres.o -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/animspheres - - ${ARCHDIR}/animspheres2 : ${RAYLIB} ${OBJDIR}/animspheres2.o -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animspheres2 ${OBJDIR}/animspheres2.o -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animspheres2 ${LDFLAGS} ${OBJDIR}/animspheres2.o -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/animspheres2 - - ${ARCHDIR}/hypertex : ${RAYLIB} ${OBJDIR}/hypertex.o ${DEMOSRC}/hypertex.c -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/hypertex ${OBJDIR}/hypertex.o -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/hypertex ${LDFLAGS} ${OBJDIR}/hypertex.o -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/hypertex - - ${ARCHDIR}/fire : ${RAYLIB} ${OBJDIR}/fire.o ${DEMOSRC}/fire.c -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/fire ${OBJDIR}/fire.o -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/fire ${LDFLAGS} ${OBJDIR}/fire.o -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/fire - - ${ARCHDIR}/animskull : ${RAYLIB} ${OBJDIR}/animskull.o -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animskull ${OBJDIR}/animskull.o -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/animskull ${LDFLAGS} ${OBJDIR}/animskull.o -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/animskull - - ${ARCHDIR}/tgatoyuv : ${RAYLIB} ${DEMOSRC}/tgatoyuv.c -- ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/tgatoyuv ${DEMOSRC}/tgatoyuv.c -L${RAYLIBDIR} ${LIBS} -+ ${CC} ${CFLAGS} ${DEMOINC} -o ${ARCHDIR}/tgatoyuv ${LDFLAGS} ${DEMOSRC}/tgatoyuv.c -L${RAYLIBDIR} ${LIBS} - ${STRIP} ${ARCHDIR}/tgatoyuv - - # diff --git a/build/pkgs/tachyon/patches/main.c.patch b/build/pkgs/tachyon/patches/main.c.patch deleted file mode 100644 index 0fb7d406969..00000000000 --- a/build/pkgs/tachyon/patches/main.c.patch +++ /dev/null @@ -1,201 +0,0 @@ ---- a/demosrc/main.c 2011-03-13 11:01:07.000000000 +0000 -+++ b/demosrc/main.c 2016-07-04 15:28:58.422923000 +0000 -@@ -1,4 +1,4 @@ --/* -+/* - * main.c - This file contains the main program and driver for the raytracer. - * - * $Id: main.c,v 1.76 2010/01/18 19:36:34 johns Exp $ -@@ -31,7 +31,7 @@ - float x; - float y; - float z; --} floatvec; -+} floatvec; - - - typedef struct { -@@ -88,7 +88,7 @@ - printf("Couldn't allocate image buffer for framebuffer display!!\n"); - free(dh); - return NULL; -- } -+ } - #endif - } - -@@ -119,9 +119,9 @@ - } - - --/* -+/* - * main loop for creating animations by flying using a spaceball -- * or other 3-D input mechanism. -+ * or other 3-D input mechanism. - */ - static int fly_scene(argoptions opt, SceneHandle scene, int node) { - dispHandle * dh = NULL; -@@ -178,7 +178,7 @@ - if (node == 0) { - printf("\rRendering Frame: %9d %10.4f FPS ", frameno, fps); - fflush(stdout); -- } -+ } - - #if defined(USESPACEBALL) - if (bh != NULL) -@@ -188,18 +188,18 @@ - rt_renderscene(scene); - - if (dh != NULL) -- tachyon_display_draw(dh); -+ tachyon_display_draw(dh); - - frameno++; -- } -+ } - - rt_timer_stop(animationtimer); - fps = frameno / rt_timer_time(animationtimer); - - if (node == 0) { - printf("\rCompleted animation of %d frames \n", frameno); -- printf("Animation Time: %10.4f seconds (Averaged %7.4f FPS)\n", -- rt_timer_time(animationtimer), fps); -+ printf("Animation Time: %10.4f seconds (Averaged %7.4f FPS)\n", -+ rt_timer_time(animationtimer), fps); - } - rt_timer_destroy(fpstimer); - -@@ -218,7 +218,7 @@ - - - --/* -+/* - * main loop for creating animations by playing recorded camera fly-throughs - */ - static int animate_scene(argoptions opt, SceneHandle scene, int node) { -@@ -270,7 +270,7 @@ - if (node == 0) { - printf("\rRendering Frame: %9d %10.4f FPS ", frameno, fps); - fflush(stdout); -- } -+ } - } - else { - sprintf(outfilename, opt.outfilename, frameno); -@@ -279,23 +279,23 @@ - fflush(stdout); - } - } -- -+ - rt_outputfile(scene, outfilename); - rt_camera_position(scene, cmc, cmv, cmu); - - rt_renderscene(scene); - - if (dh != NULL) -- tachyon_display_draw(dh); -+ tachyon_display_draw(dh); - - frameno++; -- } -+ } - rt_timer_stop(animationtimer); - fps = frameno / rt_timer_time(animationtimer); - if (node == 0) { - printf("\rCompleted animation of %d frames \n", frameno); -- printf("Animation Time: %10.4f seconds (Averaged %7.4f FPS)\n", -- rt_timer_time(animationtimer), fps); -+ printf("Animation Time: %10.4f seconds (Averaged %7.4f FPS)\n", -+ rt_timer_time(animationtimer), fps); - } - rt_timer_destroy(fpstimer); - fclose(camfp); -@@ -336,7 +336,8 @@ - char * filename; - int node, fileindex; - rt_timerhandle parsetimer; -- -+ size_t len; -+ - node = rt_initialize(&argc, &argv); - - rt_set_ui_message(my_ui_message); -@@ -346,7 +347,7 @@ - printf("Tachyon Parallel/Multiprocessor Ray Tracer Version %s \n", - TACHYON_VERSION_STRING); - printf("Copyright 1994-2010, John E. Stone \n"); -- printf("------------------------------------------------------------ \n"); -+ printf("------------------------------------------------------------ \n"); - } - - if ((rc = getargs(argc, argv, &opt, node)) != 0) { -@@ -358,7 +359,7 @@ - printf("Rendering %d scene files.\n", opt.numfiles); - } - -- for (fileindex=0; fileindex 4 && (!strcmp(filename+len-4, ".nff") || -+ !strcmp(filename+len-4, ".NFF"))) { - rc = ParseNFF(filename, scene); /* must be an NFF file */ - } -- else if (strstr(filename, ".ac") || strstr(filename, ".AC")) { -+ else if (len > 3 && (!strcmp(filename+len-3, ".ac") || -+ !strcmp(filename+len-3, ".AC"))) { - rc = ParseAC3D(filename, scene); /* Must be an AC3D file */ - } - #ifdef USELIBMGF -- else if (strstr(filename, ".mgf") || strstr(filename, ".MGF")) { -+ else if (len > 4 && (!strcmp(filename+len-4, ".mgf") || -+ !strcmp(filename+len-4, ".MGF"))) { - rc = ParseMGF(filename, scene, 1); /* Must be an MGF file */ - } - #endif -- else { -+ else { - rc = readmodel(filename, scene); /* Assume its a Tachyon scene file */ - } - - rt_timer_stop(parsetimer); -- if (rc == PARSENOERR && node == 0) -+ if (rc == PARSENOERR && node == 0) - printf("Scene Parsing Time: %10.4f seconds\n", rt_timer_time(parsetimer)); - rt_timer_destroy(parsetimer); -- -+ - if (rc != PARSENOERR && node == 0) { - switch(rc) { - case PARSEBADFILE: -@@ -409,7 +415,7 @@ - break; - case PARSEALLOCERR: - printf("Parser ran out of memory.\n"); -- break; -+ break; - } - if (fileindex+1 < opt.numfiles) - printf("Aborting render, continuing with next scene file...\n"); -@@ -429,7 +435,7 @@ - } - else if (strlen(opt.spaceball) > 0) { - return fly_scene(opt, scene, node); /* fly with spaceball etc */ -- } -+ } - else { - if (opt.numfiles > 1 && opt.nosave != 1) { - char multioutfilename[FILENAME_MAX]; diff --git a/build/pkgs/tachyon/spkg-install.in b/build/pkgs/tachyon/spkg-install.in index 5f0d2980dc3..6a68d95688c 100644 --- a/build/pkgs/tachyon/spkg-install.in +++ b/build/pkgs/tachyon/spkg-install.in @@ -27,7 +27,7 @@ case "$UNAME" in ppc*|powerpc*) TARGET=linux-ppc ;; - armv6l*|armv7l*) + armv6l*|armv7l*|aarch64*) TARGET=linux-arm-thr ;; esac @@ -52,7 +52,8 @@ if [ -z "$TARGET" ]; then sdh_die "Error: Sorry, your platform isn't supported by Tachyon and/or Sage. Exiting..." fi -sdh_make "$TARGET" +# The Makefile ignores LDFLAGS; we include it here so that rpath is set on Linux +sdh_make "$TARGET" USEPNG=-DUSEPNG PNGLIB="$LDFLAGS -lpng -lz" echo "Installing the Tachyon binary..." cd "$CUR" diff --git a/build/pkgs/tdlib/distros/fedora.txt b/build/pkgs/tdlib/distros/fedora.txt new file mode 100644 index 00000000000..f795385d55d --- /dev/null +++ b/build/pkgs/tdlib/distros/fedora.txt @@ -0,0 +1,2 @@ +python3-tdlib +python3-tdlib-devel diff --git a/build/pkgs/texttable/distros/fedora.txt b/build/pkgs/texttable/distros/fedora.txt index 8d1ccec8c7d..8f8e7e29d7a 100644 --- a/build/pkgs/texttable/distros/fedora.txt +++ b/build/pkgs/texttable/distros/fedora.txt @@ -1 +1 @@ -python-texttable +python3-texttable diff --git a/build/pkgs/tinycss2/distros/fedora.txt b/build/pkgs/tinycss2/distros/fedora.txt index cb5becfe9eb..a2c2cb2f4ab 100644 --- a/build/pkgs/tinycss2/distros/fedora.txt +++ b/build/pkgs/tinycss2/distros/fedora.txt @@ -1 +1 @@ -python-tinycss2 +python3-tinycss2 diff --git a/build/pkgs/tomli/distros/fedora.txt b/build/pkgs/tomli/distros/fedora.txt new file mode 100644 index 00000000000..cfd9f618b76 --- /dev/null +++ b/build/pkgs/tomli/distros/fedora.txt @@ -0,0 +1 @@ +python3-tomli diff --git a/build/pkgs/tornado/distros/fedora.txt b/build/pkgs/tornado/distros/fedora.txt new file mode 100644 index 00000000000..426685be95b --- /dev/null +++ b/build/pkgs/tornado/distros/fedora.txt @@ -0,0 +1 @@ +python3-tornado diff --git a/build/pkgs/trove_classifiers/checksums.ini b/build/pkgs/trove_classifiers/checksums.ini index 8d25c121cc2..42e0ec6eefe 100644 --- a/build/pkgs/trove_classifiers/checksums.ini +++ b/build/pkgs/trove_classifiers/checksums.ini @@ -1,4 +1,4 @@ tarball=trove_classifiers-VERSION-py3-none-any.whl -sha1=36240d053d16400380aee01f0879785693008a96 -sha256=678bd6fcc5218d72e3304e27a608acc9b91e17bd00c3f3d8c968497c843ad98b +sha1=8219f839a8223a9dd0912cde22d579cfa75a516e +sha256=ccc57a33717644df4daca018e7ec3ef57a835c48e96a1e71fc07eb7edac67af6 upstream_url=https://pypi.io/packages/py3/t/trove_classifiers/trove_classifiers-VERSION-py3-none-any.whl diff --git a/build/pkgs/trove_classifiers/distros/fedora.txt b/build/pkgs/trove_classifiers/distros/fedora.txt index faa3f51e677..01b98a590f0 100644 --- a/build/pkgs/trove_classifiers/distros/fedora.txt +++ b/build/pkgs/trove_classifiers/distros/fedora.txt @@ -1 +1 @@ -python-trove-classifiers +python3-trove-classifiers diff --git a/build/pkgs/trove_classifiers/package-version.txt b/build/pkgs/trove_classifiers/package-version.txt index c296ac66b65..981877628c9 100644 --- a/build/pkgs/trove_classifiers/package-version.txt +++ b/build/pkgs/trove_classifiers/package-version.txt @@ -1 +1 @@ -2024.4.10 +2024.7.2 diff --git a/build/pkgs/typing_extensions/checksums.ini b/build/pkgs/typing_extensions/checksums.ini index c22c17569af..5d4ca8ca5f2 100644 --- a/build/pkgs/typing_extensions/checksums.ini +++ b/build/pkgs/typing_extensions/checksums.ini @@ -1,4 +1,4 @@ tarball=typing_extensions-VERSION-py3-none-any.whl -sha1=049c6031f754e1c33932ce1c2ad78b857a70a244 -sha256=b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594 +sha1=0fb5b2732cc421561b1348cac1334eb6a4e0bb7f +sha256=04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d upstream_url=https://pypi.io/packages/py3/t/typing_extensions/typing_extensions-VERSION-py3-none-any.whl diff --git a/build/pkgs/typing_extensions/distros/fedora.txt b/build/pkgs/typing_extensions/distros/fedora.txt index 8c13a4539ac..424ebf1a645 100644 --- a/build/pkgs/typing_extensions/distros/fedora.txt +++ b/build/pkgs/typing_extensions/distros/fedora.txt @@ -1 +1 @@ -python-typing-extensions +python3-typing-extensions diff --git a/build/pkgs/typing_extensions/package-version.txt b/build/pkgs/typing_extensions/package-version.txt index 815588ef140..f1cd7de1de5 100644 --- a/build/pkgs/typing_extensions/package-version.txt +++ b/build/pkgs/typing_extensions/package-version.txt @@ -1 +1 @@ -4.12.0 +4.12.2 diff --git a/build/pkgs/tzdata/distros/fedora.txt b/build/pkgs/tzdata/distros/fedora.txt new file mode 100644 index 00000000000..0883ff0705b --- /dev/null +++ b/build/pkgs/tzdata/distros/fedora.txt @@ -0,0 +1 @@ +tzdata diff --git a/build/pkgs/tzlocal/distros/fedora.txt b/build/pkgs/tzlocal/distros/fedora.txt index 1de39af60b2..95d2d705c05 100644 --- a/build/pkgs/tzlocal/distros/fedora.txt +++ b/build/pkgs/tzlocal/distros/fedora.txt @@ -1 +1 @@ -python-tzlocal +python3-tzlocal diff --git a/build/pkgs/urllib3/distros/fedora.txt b/build/pkgs/urllib3/distros/fedora.txt index af6e58664fb..918569f9677 100644 --- a/build/pkgs/urllib3/distros/fedora.txt +++ b/build/pkgs/urllib3/distros/fedora.txt @@ -1 +1 @@ -python-urllib3 +python3-urllib3 diff --git a/build/pkgs/valgrind/SPKG.rst b/build/pkgs/valgrind/SPKG.rst index 99a7ab96ed2..251e871a1a8 100644 --- a/build/pkgs/valgrind/SPKG.rst +++ b/build/pkgs/valgrind/SPKG.rst @@ -4,9 +4,6 @@ valgrind: Memory error detector, call graph generator, runtime profiler Description ----------- -This is an optional spkg. It supports Linux on x86, x86-64, ppc, ppc64 -and ARM as well as Darwin (Mac OS X 10.5 and 10.6) on x86 and x86-64. - Valgrind is an instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in @@ -18,10 +15,7 @@ branch-prediction profiler, a call-graph generating cache and branch-prediction profiler, and a heap profiler. It also includes three experimental tools: a heap/stack/global array overrun detector, a second heap profiler that examines how heap blocks are used, and a SimPoint -basic block vector generator. It runs on the following platforms: -X86/Linux, AMD64/Linux, ARM/Linux, PPC32/Linux, PPC64/Linux, -S390X/Linux, ARM/Android (2.3.x), X86/Darwin and AMD64/Darwin (Mac OS X -10.6 and 10.7). +basic block vector generator. License ------- @@ -35,20 +29,3 @@ Upstream Contact - http://www.valgrind.org/ - valgrind-user, valgrind-devel mailing lists - -Dependencies ------------- - -- None - - -Special Build Instructions --------------------------- - -- To build on OS X, you need to use Apple's compiler. FSF GCC is - unsupported. - -Patches -~~~~~~~ - -- None. diff --git a/build/pkgs/valgrind/checksums.ini b/build/pkgs/valgrind/checksums.ini deleted file mode 100644 index 3ffe6ab866a..00000000000 --- a/build/pkgs/valgrind/checksums.ini +++ /dev/null @@ -1,3 +0,0 @@ -tarball=valgrind-VERSION.tar.bz2 -sha1=182afd405b92ddb6f52c6729e848eacf4b1daf46 -sha256=037c11bfefd477cc6e9ebe8f193bb237fe397f7ce791b4a4ce3fa1c6a520baa5 diff --git a/build/pkgs/valgrind/distros/fedora.txt b/build/pkgs/valgrind/distros/fedora.txt new file mode 100644 index 00000000000..19e18cdba88 --- /dev/null +++ b/build/pkgs/valgrind/distros/fedora.txt @@ -0,0 +1,2 @@ +valgrind +vagrind-devel diff --git a/build/pkgs/valgrind/spkg-install.in b/build/pkgs/valgrind/spkg-install.in deleted file mode 100644 index 2aa2762a7ed..00000000000 --- a/build/pkgs/valgrind/spkg-install.in +++ /dev/null @@ -1,20 +0,0 @@ -cd src - -./configure --prefix=$SAGE_LOCAL -if [ $? -ne 0 ]; then - echo >&2 "Error configuring Valgrind" - exit 1 -fi - -$MAKE -if [ $? -ne 0 ]; then - echo >&2 "Error building Valgrind" - exit 1 -fi - -$MAKE install -if [ $? -ne 0 ]; then - echo >&2 "Error installing Valgrind" - exit 1 -fi - diff --git a/build/pkgs/valgrind/type b/build/pkgs/valgrind/type index 9839eb20815..134d9bc32d5 100644 --- a/build/pkgs/valgrind/type +++ b/build/pkgs/valgrind/type @@ -1 +1 @@ -experimental +optional diff --git a/build/pkgs/virtualenv/distros/fedora.txt b/build/pkgs/virtualenv/distros/fedora.txt new file mode 100644 index 00000000000..030879e0d89 --- /dev/null +++ b/build/pkgs/virtualenv/distros/fedora.txt @@ -0,0 +1 @@ +python3-virtualenv diff --git a/build/pkgs/wcwidth/distros/fedora.txt b/build/pkgs/wcwidth/distros/fedora.txt new file mode 100644 index 00000000000..2974220c878 --- /dev/null +++ b/build/pkgs/wcwidth/distros/fedora.txt @@ -0,0 +1 @@ +python3-wcwidth diff --git a/build/pkgs/webencodings/distros/fedora.txt b/build/pkgs/webencodings/distros/fedora.txt index 12ddba901a4..ac30c2f3307 100644 --- a/build/pkgs/webencodings/distros/fedora.txt +++ b/build/pkgs/webencodings/distros/fedora.txt @@ -1 +1 @@ -python-webencodings +python3-webencodings diff --git a/build/pkgs/wheel/checksums.ini b/build/pkgs/wheel/checksums.ini index ea4d40c1f27..3157a2efcec 100644 --- a/build/pkgs/wheel/checksums.ini +++ b/build/pkgs/wheel/checksums.ini @@ -1,4 +1,4 @@ tarball=wheel-VERSION-py3-none-any.whl -sha1=71a83a2237cb57ab45bdafed364564e36ca5dc95 -sha256=55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81 +sha1=65ec55742da04152c8b06d6586fb36d779d7883e +sha256=2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f upstream_url=https://pypi.io/packages/py3/w/wheel/wheel-VERSION-py3-none-any.whl diff --git a/build/pkgs/wheel/distros/fedora.txt b/build/pkgs/wheel/distros/fedora.txt index ae4cbb9f52f..3c066725a1d 100644 --- a/build/pkgs/wheel/distros/fedora.txt +++ b/build/pkgs/wheel/distros/fedora.txt @@ -1 +1 @@ -python-wheel +python3-wheel diff --git a/build/pkgs/wheel/package-version.txt b/build/pkgs/wheel/package-version.txt index 8298bb08b2d..a8ab6c9666a 100644 --- a/build/pkgs/wheel/package-version.txt +++ b/build/pkgs/wheel/package-version.txt @@ -1 +1 @@ -0.43.0 +0.44.0 diff --git a/build/pkgs/widgetsnbextension/distros/fedora.txt b/build/pkgs/widgetsnbextension/distros/fedora.txt index 3483570a543..4faf6e10349 100644 --- a/build/pkgs/widgetsnbextension/distros/fedora.txt +++ b/build/pkgs/widgetsnbextension/distros/fedora.txt @@ -1 +1 @@ -python-widgetsnbextension +python3-widgetsnbextension diff --git a/build/pkgs/xindy/distros/fedora.txt b/build/pkgs/xindy/distros/fedora.txt new file mode 100644 index 00000000000..9b69095e628 --- /dev/null +++ b/build/pkgs/xindy/distros/fedora.txt @@ -0,0 +1 @@ +texlive-xindy diff --git a/build/pkgs/zipp/distros/fedora.txt b/build/pkgs/zipp/distros/fedora.txt new file mode 100644 index 00000000000..029ff9c75da --- /dev/null +++ b/build/pkgs/zipp/distros/fedora.txt @@ -0,0 +1 @@ +python3-zipp diff --git a/build/pkgs/zlib/spkg-configure.m4 b/build/pkgs/zlib/spkg-configure.m4 index c2e3b7059c0..adb36006813 100644 --- a/build/pkgs/zlib/spkg-configure.m4 +++ b/build/pkgs/zlib/spkg-configure.m4 @@ -1,7 +1,8 @@ SAGE_SPKG_CONFIGURE([zlib], [ + PKG_CHECK_MODULES([zlib], [zlib >= 1.2.11], [zlib_cv_pc=yes], [zlib_cv_pc=no]) AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no]) AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no]) - if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes"; then + if test "$zlib_cv_pc" = "yes" && test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes"; then PKG_CHECK_MODULES([LIBPNG], [libpng >= 1.2], [], [ dnl inflateValidate is needed for Sage's libpng, newer than 1.2; this ensures dnl we have the minimum required for building zlib version diff --git a/build/sage_bootstrap/compat/__init__.py b/build/sage_bootstrap/compat/__init__.py index 7fb303e4edc..153820ad1b6 100644 --- a/build/sage_bootstrap/compat/__init__.py +++ b/build/sage_bootstrap/compat/__init__.py @@ -28,3 +28,11 @@ from StringIO import StringIO except ImportError: from io import StringIO + + +try: + # Use this for Python 3. This function is available for Python >= 3.3 + from shlex import quote +except ImportError: + # Use this for Python 2. This function is available for Python < 3.13 + from pipes import quote diff --git a/build/sage_bootstrap/flock.py b/build/sage_bootstrap/flock.py index 483482a6edf..bc95a0ecf8f 100644 --- a/build/sage_bootstrap/flock.py +++ b/build/sage_bootstrap/flock.py @@ -12,10 +12,11 @@ import fcntl import os -import pipes import sys import argparse +from sage_bootstrap.compat import quote + class FileType(argparse.FileType): """ @@ -105,7 +106,7 @@ def run(argv=None): kind = "exclusive" sys.stderr.write("Waiting for {0} lock to run {1} ... ".format( - kind, ' '.join(pipes.quote(arg) for arg in command))) + kind, ' '.join(quote(arg) for arg in command))) fcntl.flock(lock, locktype) sys.stderr.write("ok\n") diff --git a/configure.ac b/configure.ac index 4848a8f4b21..5c12ff36ac9 100644 --- a/configure.ac +++ b/configure.ac @@ -450,7 +450,7 @@ AC_ARG_ENABLE([cvxopt], AC_ARG_ENABLE([notebook], AS_HELP_STRING([--disable-notebook], [disable build of the Jupyter notebook and related packages]), [ - for pkg in notebook nbconvert beautifulsoup4 sagenb_export nbformat nbclient terminado send2trash prometheus_client mistune pandocfilters bleach defusedxml jsonschema jupyter_jsmol argon2_cffi argon2_cffi_bindings webencodings tinycss2 ipympl soupsieve fastjsonschema anyio arrow async_lru fqdn isoduration json5 jsonpointer jsonschema_specifications jupyter_events jupyter_lsp jupyter_server jupyter_server_terminals jupyterlab jupyterlab_server jupyterlab_pygments jupyterlab_mathjax2 notebook_shim overrides python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator sniffio types_python_dateutil uri_template webcolors websocket_client; do + for pkg in notebook nbconvert beautifulsoup4 sagenb_export nbformat nbclient terminado send2trash prometheus_client mistune pandocfilters bleach defusedxml jsonschema jupyter_jsmol argon2_cffi argon2_cffi_bindings webencodings tinycss2 ipympl soupsieve fastjsonschema anyio arrow async_lru fqdn isoduration json5 jsonpointer jsonschema_specifications jupyter_events jupyter_lsp jupyter_server jupyter_server_terminals jupyterlab jupyterlab_server jupyterlab_pygments jupyterlab_mathjax2 jupyter_sphinx notebook_shim overrides python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator sniffio types_python_dateutil uri_template webcolors websocket_client httpx httpcore h11; do AS_VAR_SET([SAGE_ENABLE_$pkg], [$enableval]) done ]) @@ -463,6 +463,12 @@ AC_ARG_ENABLE([r], done ]) +AC_ARG_ENABLE([sagetex], + AS_HELP_STRING([--disable-sagetex], + [don't build SageTeX]), [ + AS_VAR_SET([SAGE_ENABLE_sagetex], [$enableval]) + ]) + AC_ARG_ENABLE([doc], AS_HELP_STRING([--disable-doc], [disable build of the Sage documentation and packages depending on it]), [ @@ -537,6 +543,19 @@ AC_CONFIG_COMMANDS(mkdirs, AC_MSG_NOTICE([[creating symbolic link lib64 -> lib]]) ln -s lib "$SAGE_LOCAL/lib64" fi + dnl Check that the file system is sufficiently functional + if test -z "$SAGE_BUILD_DIR"; then + SAGE_BUILD_DIR="$SAGE_LOCAL/var/tmp/sage/build" + fi + AC_MSG_NOTICE([creating directory $SAGE_BUILD_DIR]) + mkdir -p "$SAGE_BUILD_DIR" || AC_MSG_ERROR([error creating directory $SAGE_BUILD_DIR (SAGE_BUILD_DIR)]) + rm -f "$SAGE_BUILD_DIR"/conftest + touch "$SAGE_BUILD_DIR"/conftest || AC_MSG_ERROR([error creating a file in $SAGE_BUILD_DIR]) + chmod +x "$SAGE_BUILD_DIR"/conftest || AC_MSG_ERROR([error setting file permissions +x in $SAGE_BUILD_DIR]) + test -x "$SAGE_BUILD_DIR"/conftest || AC_MSG_ERROR([file permissions +x did not persist in $SAGE_BUILD_DIR]) + chmod -x "$SAGE_BUILD_DIR"/conftest || AC_MSG_ERROR([error setting file permissions -x in $SAGE_BUILD_DIR]) + test -x "$SAGE_BUILD_DIR"/conftest && AC_MSG_ERROR([file permissions -x did not persist in $SAGE_BUILD_DIR]) + rm -f "$SAGE_BUILD_DIR"/conftest ], [ SAGE_LOGS="$SAGE_ROOT/logs/pkgs" diff --git a/constraints_pkgs.txt b/constraints_pkgs.txt new file mode 100644 index 00000000000..9e4fe969fbc --- /dev/null +++ b/constraints_pkgs.txt @@ -0,0 +1,39 @@ +# This "constraints file" can be used for forcing pip +# (and any tools that delegate to pip, such as pypa/build) +# to install the distribution packages included in +# the SageMath monorepository only from their source trees +# in SAGE_ROOT/pkgs/ instead of from PyPI. +# +# Example: Building a sagemath-standard wheel +# +# [alice@localhost sage]$ ./bootstrap +# [alice@localhost sage]$ ./configure +# [alice@localhost sage]$ export MAKE="make -j16" SAGE_NUM_THREADS=16 +# [alice@localhost sage]$ make all-sage-local +# [alice@localhost sage]$ export PIP_CONSTRAINT="$(pwd)/constraints_pkgs.txt" +# [alice@localhost sage]$ ./sage -sh -c 'python3 -m build -v -v pkgs/sagemath-standard' +# +# Non-example: Installing the built wheel using the same +# constraints file will fail because sagemath-standard is one +# of the distribution packages listed below. It will conflict +# with the built wheel for sagemath-standard! +# Use "pkgs/sagemath-standard/constraints_pkgs.txt" instead. + +# Reference on the format: +# https://pip.pypa.io/en/stable/user_guide/#constraints-files +# +sage_conf @ file://${SAGE_ROOT}/pkgs/sage-conf +sage_docbuild @ file://${SAGE_ROOT}/pkgs/sage-docbuild +sage_setup @ file://${SAGE_ROOT}/pkgs/sage-setup +sage_sws2rst @ file://${SAGE_ROOT}/pkgs/sage-sws2rst +sagemath-bliss @ file://${SAGE_ROOT}/pkgs/sagemath-bliss +sagemath-categories @ file://${SAGE_ROOT}/pkgs/sagemath-categories +sagemath-coxeter3 @ file://${SAGE_ROOT}/pkgs/sagemath-coxeter3 +sagemath-environment @ file://${SAGE_ROOT}/pkgs/sagemath-environment +sagemath-mcqd @ file://${SAGE_ROOT}/pkgs/sagemath-mcqd +sagemath-meataxe @ file://${SAGE_ROOT}/pkgs/sagemath-meataxe +sagemath-objects @ file://${SAGE_ROOT}/pkgs/sagemath-objects +sagemath-repl @ file://${SAGE_ROOT}/pkgs/sagemath-repl +sagemath-sirocco @ file://${SAGE_ROOT}/pkgs/sagemath-sirocco +sagemath-standard @ file://${SAGE_ROOT}/pkgs/sagemath-standard +sagemath-tdlib @ file://${SAGE_ROOT}/pkgs/sagemath-tdlib diff --git a/docker/Dockerfile b/docker/Dockerfile index a74b451bc3b..a97664b2292 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -75,7 +75,7 @@ ARG MAKE_BUILD=make-build ################################################################################ # Image containing the run-time dependencies for Sage # ################################################################################ -FROM ubuntu:jammy as run-time-dependencies +FROM ubuntu:jammy AS run-time-dependencies LABEL maintainer="Erik M. Bray , Julian Rüth , Sebastian Oehms " # Set sane defaults for common environment variables. ENV LC_ALL C.UTF-8 @@ -108,7 +108,7 @@ WORKDIR $HOME # Image containing everything so that a make in a clone of the Sage repository # # completes without errors # ################################################################################ -FROM run-time-dependencies as build-time-dependencies +FROM run-time-dependencies AS build-time-dependencies # Install the build time dependencies & git & rdfind RUN sudo apt-get -qq update \ && sudo apt-get -qq install -y wget build-essential automake m4 dpkg-dev python3 libssl-dev git rdfind \ @@ -118,7 +118,7 @@ RUN sudo apt-get -qq update \ ################################################################################ # Image with an empty git repository in $SAGE_ROOT. # ################################################################################ -FROM build-time-dependencies as source-clean +FROM build-time-dependencies AS source-clean ARG SAGE_ROOT=/home/sage/sage RUN mkdir -p "$SAGE_ROOT" WORKDIR $SAGE_ROOT @@ -135,7 +135,7 @@ RUN git remote add upstream https://github.com/sagemath/sage.git # build is not going to use the build-time-dependencies target but rely on # # whatever tools are installed in ARTIFACT_BASE. # ################################################################################ -FROM $ARTIFACT_BASE as source-from-context +FROM $ARTIFACT_BASE AS source-from-context WORKDIR $HOME COPY --chown=sage:sage . sage-context # Checkout the commit that is checked out in $HOME/sage-context @@ -183,7 +183,7 @@ RUN patch -p1 < "$HOME"/sage-context.patch ################################################################################ # Image with a built sage but without sage's documentation. # ################################################################################ -FROM source-from-context as make-build +FROM source-from-context AS make-build # Make sure that the result runs on most CPUs. ENV SAGE_FAT_BINARY yes # Just to be sure Sage doesn't try to build its own GCC (even though @@ -204,7 +204,7 @@ RUN make build ################################################################################ # Image with a full build of sage and its documentation. # ################################################################################ -FROM $MAKE_BUILD as make-all +FROM $MAKE_BUILD AS make-all # The docbuild needs quite some RAM (as of May 2018). It sometimes calls # os.fork() to spawn an external program which then exceeds easily the # overcommit limit of the system (no RAM is actually used, but this limit is @@ -218,7 +218,7 @@ RUN make ################################################################################ # Image with a full build of sage, ready to release. # ################################################################################ -FROM make-all as make-release +FROM make-all AS make-release RUN make micro_release ################################################################################ @@ -226,7 +226,7 @@ RUN make micro_release # temporary build artifacts which is set up to start the command line # # interface if no parameters are passed in. # ################################################################################ -FROM run-time-dependencies as sagemath +FROM run-time-dependencies AS sagemath ARG HOME=/home/sage ARG SAGE_ROOT=/home/sage/sage COPY --chown=sage:sage --from=make-release $SAGE_ROOT/ $SAGE_ROOT/ @@ -244,7 +244,7 @@ CMD ["sage"] # Image with a full build of sage and its documentation but everything # # stripped that can be quickly rebuild by make. # ################################################################################ -FROM make-all as make-fast-rebuild-clean +FROM make-all AS make-fast-rebuild-clean # Of course, without site-packages/sage, sage does not start but copying/compiling # them from build/pkgs/sagelib/src/build is very fast. RUN make fast-rebuild-clean; \ @@ -255,7 +255,7 @@ RUN make fast-rebuild-clean; \ # identical to make-fast-rebuild-clean or contains a "patch" which can be used # # to upgrade ARTIFACT_BASE to make-fast-rebuild-clean. # ################################################################################ -FROM make-fast-rebuild-clean as sagemath-dev-patch +FROM make-fast-rebuild-clean AS sagemath-dev-patch ARG ARTIFACT_BASE=source-clean ARG SAGE_ROOT=/home/sage/sage # Build a patch containing of a tar file which contains all the modified files @@ -277,12 +277,12 @@ RUN if [ x"$ARTIFACT_BASE" != x"source-clean" ]; then \ # the build artifacts intact so developers can make changes and rebuild # # quickly # ################################################################################ -FROM $ARTIFACT_BASE as sagemath-dev +FROM $ARTIFACT_BASE AS sagemath-dev ARG SAGE_ROOT=/home/sage/sage # If docker is backed by aufs, then the following command adds the size of # ARTIFACT_BASE to the image size. As of mid 2018 this is notably the case with # the docker instances provided by setup_remote_docker on CircleCI. As a -# result, the sagemath-dev images that are "build-from-latest" are twice as big +# result, the sagemath-dev images that are "build-from-latest" are twice AS big # as the ones that are build on GitLab: # https://github.com/moby/moby/issues/6119#issuecomment-268870519 COPY --chown=sage:sage --from=sagemath-dev-patch $SAGE_ROOT $SAGE_ROOT diff --git a/docker/README.md b/docker/README.md index 190793c202d..404cf973490 100644 --- a/docker/README.md +++ b/docker/README.md @@ -49,7 +49,7 @@ Have a look at `.gitlab-ci.yml` if you want to setup GitLab CI for your own fork # Report bugs and issues -Please tell us of any bugs or omissions at our [Issue Tracker](https://trac.sagemath.org) or contact us through the [sage-support](https://groups.google.com/forum/#!forum/sage-support) or the [sage-devel](https://groups.google.com/forum/#!forum/sage-devel) mailing lists. +Please tell us of any bugs or omissions at our [Issue Tracker](https://github.com/sagemath/sage/issues) or contact us through the [sage-support](https://groups.google.com/forum/#!forum/sage-support) or the [sage-devel](https://groups.google.com/forum/#!forum/sage-devel) mailing lists. # License diff --git a/m4/pyproject_toml_metadata.m4 b/m4/pyproject_toml_metadata.m4 index 0d9824b1f2e..5f39bd00077 100644 --- a/m4/pyproject_toml_metadata.m4 +++ b/m4/pyproject_toml_metadata.m4 @@ -17,5 +17,12 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering :: Mathematics", ] -urls = {Homepage = "https://www.sagemath.org"} requires-python = ">=3.9, <3.13" + +[project.urls] +download = "https://doc.sagemath.org/html/en/installation/index.html" +"release notes" = "https://github.com/sagemath/sage/releases" +source = "https://github.com/sagemath/sage" +documentation = "https://doc.sagemath.org" +homepage = "https://www.sagemath.org" +tracker = "https://github.com/sagemath/sage/issues" diff --git a/meson.build b/meson.build new file mode 100644 index 00000000000..8bf73d23d55 --- /dev/null +++ b/meson.build @@ -0,0 +1,215 @@ +project( + 'SageMath', + ['c', 'cpp', 'cython'], + version: files('src/VERSION.txt'), + license: 'GPL v3', + default_options: ['c_std=c17', 'cpp_std=c++17'], +) + +# Python module +# https://mesonbuild.com/Python-module.html +py_module = import('python') +py = py_module.find_installation(pure: false) +py_dep = py.dependency() + +# Additional targets +py_with_pytest = py_module.find_installation( + required: false, + modules: ['pytest'], +) +if py_with_pytest.found() + test( + 'pytest', + py_with_pytest, + args: [ + '-m', + 'pytest', + '-c', + meson.current_source_dir() / 'tox.ini', + '--doctest', + meson.current_source_dir() / 'src' / 'sage' / 'categories', + ], + timeout: 0, + ) +endif + +# Workaround for missing init files (Cython doesn't handle namespace packages well) +create_files_command = [ + 'python3', + '-c', + ''' +import os +content = "# Here so that cython creates the correct module name" +file_paths = [ + 'src/sage/interfaces/__init__.py', + 'src/sage/crypto/block_cipher/__init__.py', + 'src/sage/crypto/public_key/__init__.py', + 'src/sage/logic/__init__.py', + 'src/sage/parallel/__init__.py', + 'src/sage/dynamics/cellular_automata/__init__.py', + 'src/sage/dynamics/arithmetic_dynamics/__init__.py', + 'src/sage/dynamics/__init__.py', + 'src/sage/dynamics/complex_dynamics/__init__.py', + 'src/sage/knots/__init__.py', + 'src/sage/topology/__init__.py', + 'src/sage/functions/__init__.py', + 'src/sage/manifolds/subsets/__init__.py', + 'src/sage/manifolds/__init__.py', + 'src/sage/manifolds/differentiable/examples/__init__.py', + 'src/sage/manifolds/differentiable/__init__.py', + 'src/sage/coding/source_coding/__init__.py', + 'src/sage/coding/guruswami_sudan/__init__.py', + 'src/sage/coding/__init__.py', + 'src/sage/coding/codecan/__init__.py', + 'src/sage/games/__init__.py', + 'src/sage/quivers/__init__.py', + 'src/sage/schemes/cyclic_covers/__init__.py', + 'src/sage/schemes/plane_conics/__init__.py', + 'src/sage/schemes/curves/__init__.py', + 'src/sage/schemes/plane_quartics/__init__.py', + 'src/sage/schemes/jacobians/__init__.py', + 'src/sage/schemes/toric/sheaf/__init__.py', + 'src/sage/schemes/toric/__init__.py', + 'src/sage/schemes/product_projective/__init__.py', + 'src/sage/schemes/elliptic_curves/__init__.py', + 'src/sage/schemes/riemann_surfaces/__init__.py', + 'src/sage/schemes/hyperelliptic_curves/__init__.py', + 'src/sage/schemes/berkovich/__init__.py', + 'src/sage/schemes/generic/__init__.py', + 'src/sage/schemes/projective/__init__.py', + 'src/sage/schemes/__init__.py', + 'src/sage/schemes/affine/__init__.py', + 'src/sage/modular/hecke/__init__.py', + 'src/sage/modular/pollack_stevens/__init__.py', + 'src/sage/modular/overconvergent/__init__.py', + 'src/sage/modular/modform/__init__.py', + 'src/sage/modular/quasimodform/__init__.py', + 'src/sage/modular/modsym/__init__.py', + 'src/sage/modular/local_comp/__init__.py', + 'src/sage/modular/quatalg/__init__.py', + 'src/sage/modular/ssmod/__init__.py', + 'src/sage/modular/abvar/__init__.py', + 'src/sage/modular/__init__.py', + 'src/sage/modular/btquotients/__init__.py', + 'src/sage/modular/arithgroup/__init__.py', + 'src/sage/modular/modform_hecketriangle/__init__.py', + 'src/sage/combinat/cluster_algebra_quiver/__init__.py', + 'src/sage/combinat/root_system/__init__.py', + 'src/sage/combinat/species/__init__.py', + 'src/sage/combinat/designs/__init__.py', + 'src/sage/combinat/posets/__init__.py', + 'src/sage/combinat/matrices/__init__.py', + 'src/sage/combinat/rigged_configurations/__init__.py', + 'src/sage/combinat/ncsf_qsym/__init__.py', + 'src/sage/combinat/path_tableaux/__init__.py', + 'src/sage/combinat/sf/__init__.py', + 'src/sage/combinat/__init__.py', + 'src/sage/combinat/chas/__init__.py', + 'src/sage/combinat/ncsym/__init__.py', + 'src/sage/combinat/words/__init__.py', + 'src/sage/combinat/crystals/__init__.py', + 'src/sage/tensor/modules/__init__.py', + 'src/sage/tensor/__init__.py', + 'src/sage/groups/matrix_gps/__init__.py', + 'src/sage/groups/semimonomial_transformations/__init__.py', + 'src/sage/groups/perm_gps/partn_ref2/__init__.py', + 'src/sage/groups/perm_gps/partn_ref/__init__.py', + 'src/sage/groups/perm_gps/__init__.py', + 'src/sage/groups/__init__.py', + 'src/sage/groups/affine_gps/__init__.py', + 'src/sage/groups/abelian_gps/__init__.py', + 'src/sage/groups/additive_abelian/__init__.py', + 'src/sage/groups/lie_gps/__init__.py', + 'src/sage/groups/misc_gps/__init__.py', + 'src/sage/symbolic/__init__.py', + 'src/sage/symbolic/integration/__init__.py', + 'src/sage/lfunctions/__init__.py', + 'src/sage/arith/__init__.py', + 'src/sage/ext/__init__.py', + 'src/sage/ext/interpreters/__init__.py', + 'src/sage/categories/examples/__init__.py', + 'src/sage/categories/__init__.py', + 'src/sage/modules/fg_pid/__init__.py', + 'src/sage/modules/__init__.py', + 'src/sage/modules/with_basis/__init__.py', + 'src/sage/modules/fp_graded/steenrod/__init__.py', + 'src/sage/modules/fp_graded/__init__.py', + 'src/sage/misc/__init__.py', + 'src/sage/rings/convert/__init__.py', + 'src/sage/rings/invariants/__init__.py', + 'src/sage/rings/finite_rings/__init__.py', + 'src/sage/rings/function_field/__init__.py', + 'src/sage/rings/function_field/drinfeld_modules/__init__.py', + 'src/sage/rings/semirings/__init__.py', + 'src/sage/rings/number_field/__init__.py', + 'src/sage/rings/__init__.py', + 'src/sage/rings/padics/__init__.py', + 'src/sage/rings/valuation/__init__.py', + 'src/sage/rings/asymptotic/__init__.py', + 'src/sage/rings/polynomial/weil/__init__.py', + 'src/sage/rings/polynomial/__init__.py', + 'src/sage/rings/polynomial/padics/__init__.py', + 'src/sage/monoids/__init__.py', + 'src/sage/matrix/__init__.py', + 'src/sage/matroids/__init__.py', + 'src/sage/interacts/__init__.py', + 'src/sage/__init__.py', + 'src/sage/plot/__init__.py', + 'src/sage/plot/plot3d/__init__.py', + 'src/sage/typeset/__init__.py', + 'src/sage/algebras/lie_conformal_algebras/__init__.py', + 'src/sage/algebras/fusion_rings/__init__.py', + 'src/sage/algebras/letterplace/__init__.py', + 'src/sage/algebras/quatalg/__init__.py', + 'src/sage/algebras/steenrod/__init__.py', + 'src/sage/algebras/finite_dimensional_algebras/__init__.py', + 'src/sage/algebras/__init__.py', + 'src/sage/algebras/hecke_algebras/__init__.py', + 'src/sage/algebras/lie_algebras/__init__.py', + 'src/sage/algebras/quantum_groups/__init__.py', + 'src/sage/quadratic_forms/genera/__init__.py', + 'src/sage/quadratic_forms/__init__.py', + 'src/sage/game_theory/__init__.py', + 'src/sage/sandpiles/__init__.py', + 'src/sage/sat/__init__.py', + 'src/sage/homology/__init__.py', + 'src/sage/geometry/riemannian_manifolds/__init__.py', + 'src/sage/geometry/hyperplane_arrangement/__init__.py', + 'src/sage/geometry/triangulation/__init__.py', + 'src/sage/geometry/polyhedron/modules/__init__.py', + 'src/sage/geometry/polyhedron/__init__.py', + 'src/sage/geometry/polyhedron/combinatorial_polyhedron/__init__.py', + 'src/sage/geometry/__init__.py', + 'src/sage/geometry/hyperbolic_space/__init__.py', + 'src/sage/sets/__init__.py', + 'src/sage/probability/__init__.py', + 'src/sage/numerical/backends/__init__.py', + 'src/sage/numerical/__init__.py', + 'src/sage/data_structures/__init__.py', + 'src/sage/graphs/graph_decompositions/__init__.py', + 'src/sage/graphs/generators/__init__.py', + 'src/sage/graphs/__init__.py', + 'src/sage/graphs/base/__init__.py', + 'src/sage/databases/__init__.py', + 'src/sage/stats/hmm/__init__.py', + 'src/sage/stats/__init__.py', + 'src/sage/stats/distributions/__init__.py', + 'src/sage/libs/gap/__init__.py', + 'src/sage/libs/mpfi/__init__.py', + 'src/sage/libs/__init__.py', + 'src/sage/libs/polybori/__init__.py', + 'src/sage/libs/mpfr/__init__.py', + 'src/sage/libs/mpc/__init__.py', + 'src/sage/calculus/transforms/__init__.py', + 'src/sage/calculus/__init__.py', +] +for path in file_paths: + path = "''' + meson.current_source_dir() + '''/" + path + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, 'w') as f: + f.write(content) + ''', +] +run_command(create_files_command, check: true) + +subdir('src') diff --git a/meson.format b/meson.format new file mode 100644 index 00000000000..f56718e583f --- /dev/null +++ b/meson.format @@ -0,0 +1 @@ +indent_by: ' ' diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sage-conf/_sage_conf/_conf.py.in b/pkgs/sage-conf/_sage_conf/_conf.py.in index 54a59fdbacf..e5386cf89cf 100644 --- a/pkgs/sage-conf/_sage_conf/_conf.py.in +++ b/pkgs/sage-conf/_sage_conf/_conf.py.in @@ -8,6 +8,7 @@ VERSION = "@PACKAGE_VERSION@" # to it. SAGE_LOCAL = "@prefix@" SAGE_ROOT = "@SAGE_ROOT@" +SAGE_SHARE = "@SAGE_SHARE@" # The semicolon-separated list of GAP root paths. This is the list of # locations that are searched for GAP packages. This is passed directly diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sage-setup/pyproject.toml b/pkgs/sage-setup/pyproject.toml index 96b079cec62..a8cac2c6a64 100644 --- a/pkgs/sage-setup/pyproject.toml +++ b/pkgs/sage-setup/pyproject.toml @@ -39,7 +39,8 @@ packages = [ "sage_setup", "sage_setup.autogen", "sage_setup.autogen.interpreters", - "sage_setup.autogen.interpreters.specs", + "sage_setup.autogen.interpreters.internal", + "sage_setup.autogen.interpreters.internal.specs", "sage_setup.command", ] include-package-data = false diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-categories/known-test-failures.json b/pkgs/sagemath-categories/known-test-failures.json index 80705635b7e..23e9f1adeeb 100644 --- a/pkgs/sagemath-categories/known-test-failures.json +++ b/pkgs/sagemath-categories/known-test-failures.json @@ -807,6 +807,10 @@ "failed": true, "ntests": 0 }, + "sage.doctest.check_tolerance": { + "failed": true, + "ntests": 19 + }, "sage.doctest.control": { "failed": true, "ntests": 230 @@ -821,13 +825,21 @@ "failed": true, "ntests": 413 }, + "sage.doctest.marked_output": { + "failed": true, + "ntests": 21 + }, "sage.doctest.parsing": { "failed": true, - "ntests": 313 + "ntests": 275 }, "sage.doctest.reporting": { "ntests": 115 }, + "sage.doctest.rif_tol": { + "failed": true, + "ntests": 18 + }, "sage.doctest.sources": { "failed": true, "ntests": 343 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-repl/MANIFEST.in b/pkgs/sagemath-repl/MANIFEST.in index ba331ec2931..0d9a0289491 100644 --- a/pkgs/sagemath-repl/MANIFEST.in +++ b/pkgs/sagemath-repl/MANIFEST.in @@ -7,6 +7,12 @@ include sage/misc/sagedoc.py include sage/misc/sage_input.py include sage/misc/sage_eval.py +# expect_objects from sage.interfaces.quit is needed to compute the +# CPU time used by each doctest. We include sage.interfaces.cleaner +# because it is conditionally imported by sage.interfaces.quit. +include sage/interfaces/quit.py +include sage/interfaces/cleaner.py + include VERSION.txt global-exclude all__*.py diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-repl/pyproject.toml.m4 b/pkgs/sagemath-repl/pyproject.toml.m4 index 459a599f1fb..f0ed5af473c 100644 --- a/pkgs/sagemath-repl/pyproject.toml.m4 +++ b/pkgs/sagemath-repl/pyproject.toml.m4 @@ -42,6 +42,7 @@ py-modules = [ ] packages = [ "sage.doctest", + "sage.interfaces", "sage.repl", "sage.repl.display", "sage.repl.ipython_kernel", diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pkgs/sagemath-standard/README.rst b/pkgs/sagemath-standard/README.rst index f429984aa4c..b5d44eb1f9b 100644 --- a/pkgs/sagemath-standard/README.rst +++ b/pkgs/sagemath-standard/README.rst @@ -8,24 +8,26 @@ About SageMath "Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, and MATLAB" - Copyright (C) 2005-2020 The Sage Development Team + Copyright (C) 2005-2024 The Sage Development Team https://www.sagemath.org SageMath fully supports all major Linux distributions, recent versions of macOS, and Windows (Windows Subsystem for Linux). -The traditional and recommended way to install SageMath is from source via Sage-the-distribution (https://www.sagemath.org/download-source.html). Sage-the-distribution first builds a large number of open source packages from source (unless it finds suitable versions installed in the system) and then installs the Sage Library (sagelib, implemented in Python and Cython). +See https://doc.sagemath.org/html/en/installation/index.html +for general installation instructions. -About this experimental pip-installable source distribution ------------------------------------------------------------ +About this pip-installable distribution package +----------------------------------------------- -This pip-installable source distribution `sagemath-standard` is an experimental distribution of the Sage Library. Use at your own risk. +This pip-installable source distribution `sagemath-standard` is a +distribution of the Sage Library. Building `sagemath-standard` has a large number of system packages as prerequisites. See https://doc.sagemath.org/html/en/installation/source.html#linux-recommended-installation for partial lists for various systems. -The connection to the system environment is facilitated through the https://pypi.org/project/sage-conf/ distribution package. +The connection to the system environment is facilitated through the https://pypi.org/project/sage-conf/ distribution package; for step-by-step installation instructions, see https://github.com/sagemath/sage/blob/develop/README.md#alternative-installation-using-pypi A modularization effort is in progress with the goal of making it possible to install parts of the Sage Library with fewer prerequisites. https://github.com/sagemath/sage/issues/29705 diff --git a/pkgs/sagemath-standard/constraints_pkgs.txt b/pkgs/sagemath-standard/constraints_pkgs.txt new file mode 100644 index 00000000000..139aae58f86 --- /dev/null +++ b/pkgs/sagemath-standard/constraints_pkgs.txt @@ -0,0 +1,21 @@ +# This "constraints file" can be used for forcing pip +# (and any tools that delegate to pip, such as pypa/build) +# to install the dependencies of sagemath-standard that are +# distribution packages included in the SageMath monorepository +# only from their source trees in SAGE_ROOT/pkgs/ +# instead of from PyPI. +# +# Example: +# +# [alice@localhost sage]$ ./bootstrap +# [alice@localhost sage]$ ./configure +# [alice@localhost sage]$ export MAKE="make -j16" SAGE_NUM_THREADS=16 +# [alice@localhost sage]$ make all-sage-local +# [alice@localhost sage]$ export PIP_CONSTRAINT="$(pwd)/pkgs/sagemath-standard/constraints_pkgs.txt" +# [alice@localhost sage]$ ./sage -sh -c 'python3 -m build -v -v pkgs/sagemath-standard' +# +# Reference on the format: +# https://pip.pypa.io/en/stable/user_guide/#constraints-files +# +sage_conf @ file://${SAGE_ROOT}/pkgs/sage-conf +sage_setup @ file://${SAGE_ROOT}/pkgs/sage-setup diff --git a/pkgs/sagemath-standard/tox.ini b/pkgs/sagemath-standard/tox.ini index c197f49d9be..0ac97f8a021 100644 --- a/pkgs/sagemath-standard/tox.ini +++ b/pkgs/sagemath-standard/tox.ini @@ -31,6 +31,19 @@ envlist = # # ./sage -sh -c '(cd pkgs/sagemath-standard && tox -v -v -v -e sagepython-sagewheels-nopypi)' # + # Build and test without using the concrete dependencies specified by requirements.txt, + # using the dependencies declared in pyproject.toml and setup.cfg (install-requires) only: + # Install the distribution packages included in the SageMath monorepository only from + # their source trees in SAGE_ROOT/pkgs/ (not from PyPI). + # + # ./sage -sh -c '(cd pkgs/sagemath-standard && tox -v -v -v -e sagepython-constraints_pkgs-norequirements)' + # + # Build dependencies according to requirements.txt (all versions fixed). + # Install the distribution packages included in the SageMath monorepository only from + # their source trees in SAGE_ROOT/pkgs/ (not from PyPI). + # + # ./sage -sh -c '(cd pkgs/sagemath-standard && tox -v -v -v -e sagepython-constraints_pkgs)' + # # EXPERIMENTAL ENVIRONMENTS: # # Build dependencies according to requirements.txt (all versions fixed). @@ -80,6 +93,8 @@ passenv = MAKEFLAGS # SAGE_VENV only for referring to the basepython or finding the wheels sagepython, sagewheels: SAGE_VENV + # Used as an environment variable in constraints_pkgs.txt + constraints_pkgs: SAGE_ROOT # Location of the wheels sagewheels: SAGE_SPKG_WHEELS @@ -88,6 +103,7 @@ setenv = # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} nopypi: PIP_NO_INDEX=true + constraints_pkgs: PIP_CONSTRAINT={toxinidir}/constraints_pkgs.txt # No build isolation for PEP 517 packages - use what is already in the environment # Note that this pip env "NO" variable uses inverted logic: # PIP_NO_BUILD_ISOLATION=False means don't use build isolation. @@ -153,6 +169,17 @@ setenv = {[pkgenv]setenv} basepython = {env:SAGE_VENV}/bin/python3 +[testenv:.pkg-sagepython-constraints_pkgs] +passenv = {[pkgenv]passenv} + SAGE_VENV + # Location of constraints_pkgs.txt + SAGE_ROOT + +setenv = {[pkgenv]setenv} + PIP_CONSTRAINT={env:SAGE_ROOT}/constraints_pkgs.txt + +basepython = {env:SAGE_VENV}/bin/python3 + [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 package_env = .pkg-sagepython @@ -177,6 +204,14 @@ package_env = .pkg-sagepython basepython = {env:SAGE_VENV}/bin/python3 package_env = .pkg-sagepython +[testenv:sagepython-constraints_pkgs] +basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-constraints_pkgs + +[testenv:sagepython-constraints_pkgs-norequirements] +basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-constraints_pkgs + [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000000..47c125c4e26 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,155 @@ +[build-system] +build-backend = 'mesonpy' +# Minimum requirements for the build system to execute. +requires = [ + 'meson-python', + 'cypari2 >=2.1.1', + 'cysignals >=1.11.4', + # Exclude 3.0.3 because of https://github.com/cython/cython/issues/5748 + 'cython >=3.0, != 3.0.3', + 'gmpy2 ~=2.1.b999', + 'memory_allocator', + 'numpy >=1.19', + 'jinja2' +] +[project] +name = "sagemath" +description = "Sage: Open Source Mathematics Software: Standard Python Library" +dependencies = [ + 'six >=1.15.0', + 'conway-polynomials >=0.8', + 'cypari2 >=2.1.1', + 'cysignals >=1.10.2', + 'cython >=3.0, != 3.0.3', + 'gmpy2 ~=2.1.b999', + 'lrcalc ~=2.1', + 'memory_allocator', + 'numpy >=1.19', + # Issue #30922: pplpy 0.8.4 and earlier do not declare dependencies correctly + 'pplpy >=0.8.6', + 'primecountpy', + 'requests >=2.13.0', + # According to https://github.com/python/typing_extensions/blob/main/CHANGELOG.md, + # version 4.4.0 adds another Python 3.11 typing backport + 'typing_extensions >= 4.4.0; python_version<"3.11"', + 'ipython >=7.13.0', + 'pexpect >=4.8.0', + 'sphinx >=5.2, <9', + 'networkx >=2.4', + # 1.8 is known good version. + # Per https://docs.scipy.org/doc/scipy/dev/core-dev/index.html#version-numbering + # and https://docs.scipy.org/doc/scipy/dev/core-dev/index.html#deprecations, + # deprecations cannot be introduced in micro releases. + # SciPy devs wait "at least 6 months", "in practice two (minor) releases" + # from deprecation to removal of a feature. + 'scipy >=1.5', + 'sympy >=1.6, <2.0', + # Issue #33642: Set lower bound for use of matplotlib color maps introduced in #33491, + # and to suppress deprecation warnings (https://github.com/matplotlib/matplotlib/pull/21073) + 'matplotlib >=3.5.1', + 'pillow >=7.2.0', + 'mpmath >=1.1.0', + 'ipykernel >=5.2.1', + 'jupyter-client', + 'ipywidgets >=7.5.1', + 'fpylll >=0.5.9', + 'ptyprocess > 0.5', +] +dynamic = ["version"] +license = {text = "GNU General Public License (GPL) v2 or later"} +authors = [{name = "The Sage Developers", email = "sage-support@googlegroups.com"}] +classifiers = [ + "Development Status :: 6 - Mature", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: POSIX", + "Operating System :: MacOS :: MacOS X", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Scientific/Engineering :: Mathematics", +] +urls = {Homepage = "https://www.sagemath.org"} +requires-python = ">=3.9, <3.13" + +[project.optional-dependencies] +R = [ + 'rpy2 >=3.3', +] + +[project.readme] +file = "README.md" +content-type = "text/markdown" + +[tool.conda-lock] +platforms = [ + 'osx-64', 'linux-64', 'linux-aarch64', 'osx-arm64' +] + +[external] +# External dependencies in the format proposed by https://peps.python.org/pep-0725 +build-requires = [ + "virtual:compiler/c", + "virtual:compiler/cpp", + "pkg:generic/pkg-config" +] + +host-requires = [ + "virtual:interface/blas", + "pkg:generic/boost", + "pkg:generic/brial", + "pkg:generic/cddlib", + "pkg:generic/cliquer", + "pkg:generic/ecl", + "pkg:generic/eclib", + "pkg:generic/ecm", + "pkg:generic/fflas-ffpack", + "pkg:generic/fplll", + "pkg:generic/flint", + "pkg:generic/libgd", + "pkg:generic/gap", + "pkg:generic/gfan", + "pkg:generic/giac", + "pkg:generic/givaro", + "pkg:generic/glpk", + "pkg:generic/gmp", + "pkg:generic/gsl", + "pkg:generic/iml", + "pkg:generic/lcalc", + "pkg:generic/libbraiding", + "pkg:generic/libhomfly", + "pkg:generic/linbox", + "pkg:generic/lrcalc", + "pkg:generic/m4ri", + "pkg:generic/m4rie", + "pkg:generic/maxima", + "pkg:generic/mpc", + "pkg:generic/mpfi", + "pkg:generic/mpfr", + "pkg:generic/nauty", + "pkg:generic/ntl", + "pkg:generic/palp", + "pkg:generic/pari", + "pkg:generic/pari-elldata", + "pkg:generic/pari-galdata", + "pkg:generic/pari-seadata", + "pkg:generic/planarity", + "pkg:generic/ppl", + "pkg:generic/primesieve", + "pkg:generic/primecount", + "pkg:generic/qhull", + "pkg:generic/rw", + "pkg:generic/singular", + "pkg:generic/symmetrica", + "pkg:generic/sympow", +] + +dependencies = [ + "pkg:generic/tachyon", + "pkg:generic/sagemath-polytopes-db", + "pkg:generic/sagemath-elliptic-curves", +] diff --git a/src/VERSION.txt b/src/VERSION.txt index 1be519cd2ec..8d89e93406d 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.4 +10.5.beta8 diff --git a/src/bin/sage b/src/bin/sage index df4ff198426..d102056b6c6 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -428,7 +428,7 @@ usage_advanced() { echo " --initial -- only show the first failure per block" echo " --debug -- drop into PDB after an unexpected error" echo " --failed -- only test files that failed last test" - echo " --warn-long [timeout] -- warning if doctest is slow" + echo " --warn-long [timeout] -- warn if tests take too much CPU time" echo " --only-errors -- only output failures, not successes" echo " --gc=GC -- control garbarge collection (ALWAYS:" echo " collect garbage before every test; NEVER:" diff --git a/src/bin/sage-fixdoctests b/src/bin/sage-fixdoctests index 044170fac53..9877af91cc8 100755 --- a/src/bin/sage-fixdoctests +++ b/src/bin/sage-fixdoctests @@ -38,6 +38,7 @@ import subprocess import sys from argparse import ArgumentParser +from collections import defaultdict from pathlib import Path from sage.doctest.control import DocTestDefaults, DocTestController @@ -459,6 +460,8 @@ def process_grouped_blocks(grouped_iterator, distribution=None, venv=None, envir src_in_lines = src_in.splitlines() shallow_copy_of_src_in_lines = list(src_in_lines) file_optional_tags = set(parse_file_optional_tags(enumerate(src_in_lines))) + persistent_tags_counts = defaultdict(int) + tags_counts = defaultdict(int) for block in blocks: try: @@ -474,6 +477,7 @@ def process_grouped_blocks(grouped_iterator, distribution=None, venv=None, envir # Remove duplicate optional tags and rewrite all '# optional' that should be '# needs' persistent_optional_tags = {} + persistent_optional_tags_counted = False for i, line in enumerate(src_in_lines): if m := re.match(' *sage: *(.*)#', line): tags, line_sans_tags, is_persistent = parse_optional_tags(line, return_string_sans_tags=True) @@ -481,6 +485,7 @@ def process_grouped_blocks(grouped_iterator, distribution=None, venv=None, envir persistent_optional_tags = {tag: explanation for tag, explanation in tags.items() if explanation or tag not in file_optional_tags} + persistent_optional_tags_counted = False line = update_optional_tags(line, tags=persistent_optional_tags, force_rewrite='standard') if re.fullmatch(' *sage: *', line): # persistent (block-scoped or file-scoped) tag was removed, so remove the whole line @@ -491,9 +496,19 @@ def process_grouped_blocks(grouped_iterator, distribution=None, venv=None, envir if explanation or (tag not in file_optional_tags and tag not in persistent_optional_tags)} line = update_optional_tags(line, tags=tags, force_rewrite='standard') + if not persistent_optional_tags_counted: + persistent_tags_counts[frozenset(persistent_optional_tags)] += 1 + persistent_optional_tags_counted = True + tags_counts[frozenset(tags)] += 1 src_in_lines[i] = line elif line.strip() in ['', '"""', "'''"]: # Blank line or end of docstring persistent_optional_tags = {} + persistent_optional_tags_counted = False + elif re.match(' *sage: ', line): + if not persistent_optional_tags_counted: + persistent_tags_counts[frozenset(persistent_optional_tags)] += 1 + persistent_optional_tags_counted = True + tags_counts[frozenset()] += 1 if src_in_lines != shallow_copy_of_src_in_lines: if (output := output_filename(input)) is None: @@ -523,6 +538,21 @@ def process_grouped_blocks(grouped_iterator, distribution=None, venv=None, envir unprocessed_files.discard(input) + if args.verbose: + if file_optional_tags: + print(f"File tags: ") + print(f" {' '.join(sorted(file_optional_tags))}") + if persistent_tags_counts: + print(f"Doctest blocks by persistent tags: ") + for tags, count in sorted(persistent_tags_counts.items(), + key=lambda i: i[1], reverse=True): + print(f"{count:6} {' '.join(sorted(tags)) or '(untagged)'}") + if tags_counts: + print(f"Doctest examples by tags: ") + for tags, count in sorted(tags_counts.items(), + key=lambda i: i[1], reverse=True): + print(f"{count:6} {' '.join(sorted(tags)) or '(untagged)'}") + def fix_with_distribution(file_set, distribution=None, verbose=False): if verbose: diff --git a/src/bin/sage-preparse b/src/bin/sage-preparse index 6392909ce1c..3422d236bf2 100755 --- a/src/bin/sage-preparse +++ b/src/bin/sage-preparse @@ -74,7 +74,7 @@ def do_preparse(f, files_before=[]): - ``f`` -- string: the name of a file - ``files_before`` -- list of strings of previous filenames loaded (to avoid circular loops) - OUTPUT: None (writes a file with extension .sage.py to disk). + OUTPUT: none (writes a file with extension .sage.py to disk) """ if f in files_so_far: return diff --git a/src/bin/sage-runtests b/src/bin/sage-runtests index 81efd01a4d8..8ab309685c7 100755 --- a/src/bin/sage-runtests +++ b/src/bin/sage-runtests @@ -1,206 +1,9 @@ #!/usr/bin/env sage-python -import argparse -import os import sys -# Note: the DOT_SAGE and SAGE_STARTUP_FILE environment variables have already been set by sage-env -DOT_SAGE = os.environ.get('DOT_SAGE', os.path.join(os.environ.get('HOME'), - '.sage')) - -# Override to not pick up user configuration, see Issue #20270 -os.environ['SAGE_STARTUP_FILE'] = os.path.join(DOT_SAGE, 'init-doctests.sage') - - -def _get_optional_defaults(): - """Return the default value for the --optional flag.""" - optional = ['sage', 'optional'] - - return ','.join(optional) +from sage.doctest.__main__ import main if __name__ == "__main__": - parser = argparse.ArgumentParser(usage="sage -t [options] filenames", - description="Run all tests in a file or a list of files whose extensions " - "are one of the following: " - ".py, .pyx, .pxd, .pxi, .sage, .spyx, .tex, .rst.") - parser.add_argument("-p", "--nthreads", dest="nthreads", - type=int, nargs='?', const=0, default=1, metavar="N", - help="test in parallel using N threads, with 0 interpreted as max(2, min(8, cpu_count())); " - "when run under the control of the GNU make jobserver (make -j), request as most N job slots") - parser.add_argument("-T", "--timeout", type=int, default=-1, help="timeout (in seconds) for doctesting one file, 0 for no timeout") - what = parser.add_mutually_exclusive_group() - what.add_argument("-a", "--all", action="store_true", default=False, help="test all files in the Sage library") - what.add_argument("--installed", action="store_true", default=False, help="test all installed modules of the Sage library") - parser.add_argument("--logfile", type=argparse.FileType('a'), metavar="FILE", help="log all output to FILE") - - parser.add_argument("--format", choices=["sage", "github"], default="sage", - help="set format of error messages and warnings") - parser.add_argument("-l", "--long", action="store_true", default=False, help="include lines with the phrase 'long time'") - parser.add_argument("-s", "--short", dest="target_walltime", nargs='?', - type=int, default=-1, const=300, metavar="SECONDS", - help="run as many doctests as possible in about 300 seconds (or the number of seconds given as an optional argument)") - parser.add_argument("--warn-long", dest="warn_long", nargs='?', - type=float, default=-1.0, const=1.0, metavar="SECONDS", - help="warn if tests take more time than SECONDS") - # By default, include all tests marked 'sagemath_doc_html' -- see - # https://github.com/sagemath/sage/issues/25345 and - # https://github.com/sagemath/sage/issues/26110: - parser.add_argument("--optional", metavar="FEATURES", default=_get_optional_defaults(), - help='only run tests including one of the "# optional" tags listed in FEATURES (separated by commas); ' - 'if "sage" is listed, will also run the standard doctests; ' - 'if "sagemath_doc_html" is listed, will also run the tests relying on the HTML documentation; ' - 'if "optional" is listed, will also run tests for installed optional packages or detected features; ' - 'if "external" is listed, will also run tests for available external software; ' - 'if set to "all", then all tests will be run; ' - 'use "!FEATURE" to disable tests marked "# optional - FEATURE". ' - 'Note that "!" needs to be quoted or escaped in the shell.') - parser.add_argument("--hide", metavar="FEATURES", default="", - help='run tests pretending that the software listed in FEATURES (separated by commas) is not installed; ' - 'if "all" is listed, will also hide features corresponding to all optional or experimental packages; ' - 'if "optional" is listed, will also hide features corresponding to optional packages.') - parser.add_argument("--probe", metavar="FEATURES", default="", - help='run tests that would not be run because one of the given FEATURES (separated by commas) is not installed; ' - 'report the tests that pass nevertheless') - parser.add_argument("--randorder", type=int, metavar="SEED", help="randomize order of tests") - parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests", - default=os.environ.get("SAGE_DOCTEST_RANDOM_SEED")) - parser.add_argument("--global-iterations", "--global_iterations", type=int, default=0, help="repeat the whole testing process this many times") - parser.add_argument("--file-iterations", "--file_iterations", type=int, default=0, help="repeat each file this many times, stopping on the first failure") - parser.add_argument("--environment", type=str, default="sage.repl.ipython_kernel.all_jupyter", help="name of a module that provides the global environment for tests") - - parser.add_argument("-i", "--initial", action="store_true", default=False, help="only show the first failure in each file") - parser.add_argument("--exitfirst", action="store_true", default=False, help="end the test run immediately after the first failure or unexpected exception") - parser.add_argument("--force_lib", "--force-lib", action="store_true", default=False, help="do not import anything from the tested file(s)") - parser.add_argument("--if-installed", action="store_true", default=False, help="skip Python/Cython files that are not installed as modules") - parser.add_argument("--abspath", action="store_true", default=False, help="print absolute paths rather than relative paths") - parser.add_argument("--verbose", action="store_true", default=False, help="print debugging output during the test") - parser.add_argument("-d", "--debug", action="store_true", default=False, help="drop into a python debugger when an unexpected error is raised") - parser.add_argument("--only-errors", action="store_true", default=False, help="only output failures, not test successes") - - parser.add_argument("--gdb", action="store_true", default=False, help="run doctests under the control of gdb") - parser.add_argument("--lldb", action="store_true", default=False, help="run doctests under the control of lldb") - parser.add_argument("--valgrind", "--memcheck", action="store_true", default=False, - help="run doctests using Valgrind's memcheck tool. The log " - "files are named sage-memcheck.PID and can be found in " + - os.path.join(DOT_SAGE, "valgrind")) - parser.add_argument("--massif", action="store_true", default=False, - help="run doctests using Valgrind's massif tool. The log " - "files are named sage-massif.PID and can be found in " + - os.path.join(DOT_SAGE, "valgrind")) - parser.add_argument("--cachegrind", action="store_true", default=False, - help="run doctests using Valgrind's cachegrind tool. The log " - "files are named sage-cachegrind.PID and can be found in " + - os.path.join(DOT_SAGE, "valgrind")) - parser.add_argument("--omega", action="store_true", default=False, - help="run doctests using Valgrind's omega tool. The log " - "files are named sage-omega.PID and can be found in " + - os.path.join(DOT_SAGE, "valgrind")) - - parser.add_argument("-f", "--failed", action="store_true", default=False, - help="doctest only those files that failed in the previous run") - what.add_argument("-n", "--new", action="store_true", default=False, - help="doctest only those files that have been changed in the repository and not yet been committed") - parser.add_argument("--show-skipped", "--show_skipped", action="store_true", default=False, - help="print a summary at the end of each file of optional tests that were skipped") - - parser.add_argument("--stats_path", "--stats-path", default=os.path.join(DOT_SAGE, "timings2.json"), - help="path to a json dictionary for timings and failure status for each file from previous runs; it will be updated in this run") - parser.add_argument("--baseline_stats_path", "--baseline-stats-path", default=None, - help="path to a json dictionary for timings and failure status for each file, to be used as a baseline; it will not be updated") - - class GCAction(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - gcopts = dict(DEFAULT=0, ALWAYS=1, NEVER=-1) - new_value = gcopts[values] - setattr(namespace, self.dest, new_value) - - parser.add_argument("--gc", - choices=["DEFAULT", "ALWAYS", "NEVER"], - default=0, - action=GCAction, - help="control garbarge collection " - "(ALWAYS: collect garbage before every test; NEVER: disable gc; DEFAULT: Python default)") - - # The --serial option is only really for internal use, better not - # document it. - parser.add_argument("--serial", action="store_true", default=False, help=argparse.SUPPRESS) - # Same for --die_timeout - parser.add_argument("--die_timeout", type=int, default=-1, help=argparse.SUPPRESS) - - parser.add_argument("filenames", help="file names", nargs='*') - - # custom treatment to separate properly - # one or several file names at the end - new_arguments = [] - need_filenames = True - in_filenames = False - afterlog = False - for arg in sys.argv[1:]: - if arg in ('-n', '--new', '-a', '--all', '--installed'): - need_filenames = False - elif need_filenames and not (afterlog or in_filenames) and os.path.exists(arg): - in_filenames = True - new_arguments.append('--') - new_arguments.append(arg) - afterlog = arg in ['--logfile', '--stats_path', '--stats-path', - '--baseline_stats_path', '--baseline-stats-path'] - - args = parser.parse_args(new_arguments) - - if not args.filenames and not (args.all or args.new or args.installed): - print('either use --new, --all, --installed, or some filenames') - sys.exit(2) - - # Limit the number of threads to 2 to save system resources. - # See Issue #23713, #23892, #30351 - if sys.platform == 'darwin': - os.environ["OMP_NUM_THREADS"] = "1" - else: - os.environ["OMP_NUM_THREADS"] = "2" - - os.environ["SAGE_NUM_THREADS"] = "2" - - from sage.doctest.control import DocTestController - DC = DocTestController(args, args.filenames) - err = DC.run() - - # Issue #33521: Do not run pytest if the pytest configuration is not available. - # This happens when the source tree is not available and SAGE_SRC falls back - # to SAGE_LIB. - from sage.env import SAGE_SRC - if not all(os.path.isfile(os.path.join(SAGE_SRC, f)) - for f in ["conftest.py", "tox.ini"]): - sys.exit(err) - - try: - exit_code_pytest = 0 - import pytest - pytest_options = [] - if args.verbose: - pytest_options.append("-v") - - # #35999: no filename in arguments defaults to "src" - if not args.filenames: - filenames = [SAGE_SRC] - else: - # #31924: Do not run pytest on individual Python files unless - # they match the pytest file pattern. However, pass names - # of directories. We use 'not os.path.isfile(f)' for this so that - # we do not silently hide typos. - filenames = [f for f in args.filenames - if f.endswith("_test.py") or not os.path.isfile(f)] - if filenames: - print(f"Running pytest on {filenames} with options {pytest_options}") - exit_code_pytest = pytest.main(filenames + pytest_options) - if exit_code_pytest == 5: - # Exit code 5 means there were no test files, pass in this case - exit_code_pytest = 0 - - except ModuleNotFoundError: - print("pytest is not installed in the venv, skip checking tests that rely on it") - - if err == 0: - sys.exit(exit_code_pytest) - else: - sys.exit(err) + sys.exit(main()) diff --git a/src/bin/sage-valgrind b/src/bin/sage-valgrind index ae0d5dae389..9c668c3bdd0 100755 --- a/src/bin/sage-valgrind +++ b/src/bin/sage-valgrind @@ -20,6 +20,7 @@ fi SUPP+=" --suppressions=$SAGE_EXTCODE/valgrind/pyalloc.supp" SUPP+=" --suppressions=$SAGE_EXTCODE/valgrind/sage.supp" SUPP+=" --suppressions=$SAGE_EXTCODE/valgrind/sage-additional.supp" +SUPP+=" --suppressions=$SAGE_EXTCODE/valgrind/valgrind-python.supp" MEMCHECK_FLAGS="--leak-resolution=high --leak-check=full --num-callers=25 $SUPP" diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index e306177e47a..16a381b0b24 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.4' -SAGE_RELEASE_DATE='2024-07-19' -SAGE_VERSION_BANNER='SageMath version 10.4, Release Date: 2024-07-19' +SAGE_VERSION='10.5.beta8' +SAGE_RELEASE_DATE='2024-10-26' +SAGE_VERSION_BANNER='SageMath version 10.5.beta8, Release Date: 2024-10-26' diff --git a/src/doc/Makefile b/src/doc/Makefile index 2d433b3727c..98a3d138baf 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -42,7 +42,7 @@ doc-inventory-reference: doc-src $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) doc-inventory--$(subst /,-,$(BIBLIO)) - $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(OTHER_DOCS), doc-inventory--$(subst /,-,$(doc))) + $(MAKE) $(foreach doc, $(OTHER_DOCS), doc-inventory--$(subst /,-,$(doc))) $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" doc-inventory--reference_top endif @@ -63,7 +63,7 @@ doc-html-reference: doc-html-reference-sub doc-html-other: doc-html-reference $(eval DOCS = $(shell sage --docbuild --all-documents all)) @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi - $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-html--$(subst /,-,$(doc))) + $(MAKE) $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-html--$(subst /,-,$(doc))) doc-html: doc-html-reference doc-html-other diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 32a31430554..e99ecd52c28 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -84,28 +84,15 @@ mkdir -p "$OUTPUT_DIR" if [ "${BOOTSTRAP_QUIET}" = "no" ]; then echo >&2 $0:$LINENO: installing "$OUTPUT_DIR"/"*.rst" fi -OUTPUT_INDEX="$OUTPUT_DIR"/index.rst -cat > "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" < "$OUTPUT_DIR"/index_standard.rst +(cat <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" < "$OUTPUT_DIR"/index_optional.rst for PKG_BASE in $(sage-package list --has-file SPKG.rst | grep '^sagemath_'); do echo "* :ref:\`spkg_$PKG_BASE\`" -done >> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" < "$OUTPUT_DIR"/index_sagemath.rst +(cat <> "$OUTPUT_INDEX" +done -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" - -cat >> "$OUTPUT_INDEX" < "$OUTPUT_DIR"/index_experimental.rst (cat < "$OUTPUT_INDEX" +) > "$OUTPUT_DIR"/index_alph.rst sage-package list --has-file SPKG.rst | OUTPUT_DIR=$OUTPUT_DIR OUTPUT_RST=1 xargs -P 99 -n 1 sage-spkg-info diff --git a/src/doc/ca/intro/conf.py b/src/doc/ca/intro/conf.py index e46ebfb8c8d..877eba7eeb7 100644 --- a/src/doc/ca/intro/conf.py +++ b/src/doc/ca/intro/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/ca/intro', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/ca/intro', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/ca/intro', '{filename}'), }) # General information about the project. diff --git a/src/doc/common/static/custom-tabs.css b/src/doc/common/static/custom-tabs.css new file mode 100644 index 00000000000..b38f14b1e3d --- /dev/null +++ b/src/doc/common/static/custom-tabs.css @@ -0,0 +1,13 @@ +/* Additional css for tabs */ + +.tab-set { + margin-top: 0px; +} + +.tab-set > label { + padding: 0.1em var(--tabs--pading-x); +} + +p.with-sage-tab { + margin-bottom:0.25rem +} diff --git a/src/doc/common/static/jupyter-sphinx-furo.js b/src/doc/common/static/jupyter-sphinx-furo.js index b63de354db8..ad06a84d5a2 100644 --- a/src/doc/common/static/jupyter-sphinx-furo.js +++ b/src/doc/common/static/jupyter-sphinx-furo.js @@ -109,12 +109,12 @@ function changeVersion() { if (selected_url) { if (window.location.protocol == 'file:') { let pathname = window.location.pathname; - let cutoff_point = pathname.indexOf('doc/sage'); + let cutoff_point = pathname.indexOf('/html'); if (cutoff_point !== -1) { - pathname = pathname.substring(cutoff_point + 8); + pathname = pathname.substring(cutoff_point); window.location.href = selected_url + pathname; } else { - window.location.href = selected_url + 'html/en/index.html'; + window.location.href = selected_url + '/index.html'; } } else { window.location.href = selected_url + window.location.pathname; diff --git a/src/doc/de/a_tour_of_sage/conf.py b/src/doc/de/a_tour_of_sage/conf.py index 33f9e9642b7..fb960f06ffd 100644 --- a/src/doc/de/a_tour_of_sage/conf.py +++ b/src/doc/de/a_tour_of_sage/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -22,9 +27,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/de/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/de/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/de/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/de/thematische_anleitungen/conf.py b/src/doc/de/thematische_anleitungen/conf.py index d3a843c30bd..b8ec2573f90 100644 --- a/src/doc/de/thematische_anleitungen/conf.py +++ b/src/doc/de/thematische_anleitungen/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/de/thematische_anleitungen', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/de/thematische_anleitungen', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/de/thematische_anleitungen', '{filename}'), }) # General information about the project. diff --git a/src/doc/de/tutorial/conf.py b/src/doc/de/tutorial/conf.py index fe4c5b0d3e1..da1c19e0ffc 100644 --- a/src/doc/de/tutorial/conf.py +++ b/src/doc/de/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/de/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/de/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/de/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/de/tutorial/interactive_shell.rst b/src/doc/de/tutorial/interactive_shell.rst index 6e313da4b52..8915be27d07 100644 --- a/src/doc/de/tutorial/interactive_shell.rst +++ b/src/doc/de/tutorial/interactive_shell.rst @@ -356,9 +356,9 @@ dem man nachgehen sollte. sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 - sage: gap(0) + sage: libgap(0) 0 - sage: time g = gap.eval('1938^99484;;') + sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 @@ -742,7 +742,7 @@ nicht erlaubt. :: - sage: a = gap(2) + sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): diff --git a/src/doc/el/a_tour_of_sage/conf.py b/src/doc/el/a_tour_of_sage/conf.py index f451fdf5ab8..ff4e9436313 100644 --- a/src/doc/el/a_tour_of_sage/conf.py +++ b/src/doc/el/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,6 +25,12 @@ # contains common paths. html_static_path = [] + html_common_static_path +# Add small view/edit buttons. +html_theme_options.update({ + 'source_view_link': os.path.join(source_repository, f'blob/develop/src/doc/el/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, f'edit/develop/src/doc/el/a_tour_of_sage', '{filename}'), +}) + # General information about the project. project = 'Περιήγηση στο Sage' name = 'a_tour_of_sage' diff --git a/src/doc/en/a_tour_of_sage/conf.py b/src/doc/en/a_tour_of_sage/conf.py index 38184747c9f..689eed59af3 100644 --- a/src/doc/en/a_tour_of_sage/conf.py +++ b/src/doc/en/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, f'blob/develop/src/doc/en/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, f'blob/develop/src/doc/en/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, f'edit/develop/src/doc/en/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/constructions/conf.py b/src/doc/en/constructions/conf.py index 13743e5b276..a28d011781c 100644 --- a/src/doc/en/constructions/conf.py +++ b/src/doc/en/constructions/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/constructions', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/constructions', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/constructions', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/constructions/groups.rst b/src/doc/en/constructions/groups.rst index da90efecfaa..a7ce106c831 100644 --- a/src/doc/en/constructions/groups.rst +++ b/src/doc/en/constructions/groups.rst @@ -124,31 +124,25 @@ You can compute conjugacy classes of a finite group using "natively":: You can use the Sage-GAP interface:: - sage: gap.eval("G := Group((1,2)(3,4),(1,2,3))") - 'Group([ (1,2)(3,4), (1,2,3) ])' - sage: gap.eval("CG := ConjugacyClasses(G)") - '[ ()^G, (2,3,4)^G, (2,4,3)^G, (1,2)(3,4)^G ]' - sage: gap.eval("gamma := CG[3]") - '(2,4,3)^G' - sage: gap.eval("g := Representative(gamma)") - '(2,4,3)' + sage: libgap.eval("G := Group((1,2)(3,4),(1,2,3))") + Group([ (1,2)(3,4), (1,2,3) ]) + sage: libgap.eval("CG := ConjugacyClasses(G)") + [ ()^G, (2,3,4)^G, (2,4,3)^G, (1,2)(3,4)^G ] + sage: libgap.eval("gamma := CG[3]") + (2,4,3)^G + sage: libgap.eval("g := Representative(gamma)") + (2,4,3) Or, here's another (more "pythonic") way to do this type of computation:: - sage: G = gap.Group('[(1,2,3), (1,2)(3,4), (1,7)]') + sage: G = libgap.eval("Group([(1,2,3), (1,2)(3,4), (1,7)])") sage: CG = G.ConjugacyClasses() sage: gamma = CG[2] sage: g = gamma.Representative() sage: CG; gamma; g - [ ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), () ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (4,7) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (3,4,7) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (2,3)(4,7) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (2,3,4,7) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2)(3,4,7) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2,3,4,7) ) ] - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (4,7) ) - (4,7) + [ ()^G, (4,7)^G, (3,4,7)^G, (2,3)(4,7)^G, (2,3,4,7)^G, (1,2)(3,4,7)^G, (1,2,3,4,7)^G ] + (3,4,7)^G + (3,4,7) .. index:: pair: group; normal subgroups @@ -162,29 +156,29 @@ If you want to find all the normal subgroups of a permutation group :math:`G` (up to conjugacy), you can use Sage's interface to GAP:: sage: G = AlternatingGroup( 5 ) - sage: gap(G).NormalSubgroups() - [ AlternatingGroup( [ 1 .. 5 ] ), Group( () ) ] + sage: libgap(G).NormalSubgroups() + [ Alt( [ 1 .. 5 ] ), Group(()) ] or :: - sage: G = gap("AlternatingGroup( 5 )") + sage: G = libgap.AlternatingGroup( 5 ) sage: G.NormalSubgroups() - [ AlternatingGroup( [ 1 .. 5 ] ), Group( () ) ] + [ Alt( [ 1 .. 5 ] ), Group(()) ] Here's another way, working more directly with GAP:: - sage: print(gap.eval("G := AlternatingGroup( 5 )")) + sage: libgap.eval("G := AlternatingGroup( 5 )") Alt( [ 1 .. 5 ] ) - sage: print(gap.eval("normal := NormalSubgroups( G )")) + sage: libgap.eval("normal := NormalSubgroups( G )") [ Alt( [ 1 .. 5 ] ), Group(()) ] - sage: G = gap.new("DihedralGroup( 10 )") + sage: G = libgap.eval("DihedralGroup( 10 )") sage: G.NormalSubgroups().SortedList() - [ Group( of ... ), Group( [ f2 ] ), Group( [ f1, f2 ] ) ] - sage: print(gap.eval("G := SymmetricGroup( 4 )")) + [ Group([ ]), Group([ f2 ]), ] + sage: libgap.eval("G := SymmetricGroup( 4 )") Sym( [ 1 .. 4 ] ) - sage: print(gap.eval("normal := NormalSubgroups( G );")) + sage: libgap.eval("normal := NormalSubgroups( G );") [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), ... ]), Group(()) ] @@ -201,7 +195,7 @@ How do you compute the center of a group in Sage? Although Sage calls GAP to do the computation of the group center, ``center`` is "wrapped" (i.e., Sage has a class PermutationGroup with associated class method "center"), so the user does not need to use -the ``gap`` command. Here's an example:: +the ``libgap`` command. Here's an example:: sage: G = PermutationGroup(['(1,2,3)(4,5)', '(3,4)']) sage: G.center() diff --git a/src/doc/en/constructions/interface_issues.rst b/src/doc/en/constructions/interface_issues.rst index c5df32a2a5f..f8b62866da1 100644 --- a/src/doc/en/constructions/interface_issues.rst +++ b/src/doc/en/constructions/interface_issues.rst @@ -92,7 +92,7 @@ Sage and other computer algebra systems If ``foo`` is a Pari, GAP ( without ending semicolon), Singular, Maxima command, resp., enter ``gp("foo")`` for Pari, -``gap.eval("foo")}`` ``singular.eval("foo")``, ``maxima("foo")``, resp.. +``libgap.eval("foo")}`` ``singular.eval("foo")``, ``maxima("foo")``, resp.. These programs merely send the command string to the external program, execute it, and read the result back into Sage. Therefore, these will not work if the external program is not installed and in diff --git a/src/doc/en/constructions/linear_algebra.rst b/src/doc/en/constructions/linear_algebra.rst index 4e76c65ad0a..b25cdf94634 100644 --- a/src/doc/en/constructions/linear_algebra.rst +++ b/src/doc/en/constructions/linear_algebra.rst @@ -306,11 +306,11 @@ Finally, you can use Sage's GAP interface as well to compute :: - sage: print(gap.eval("A := [[1,2,3],[4,5,6],[7,8,9]]")) + sage: A = libgap([[1,2,3],[4,5,6],[7,8,9]]); A [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] - sage: print(gap.eval("v := Eigenvectors( Rationals,A)")) + sage: libgap(QQ).Eigenvectors(A) [ [ 1, -2, 1 ] ] - sage: print(gap.eval("lambda := Eigenvalues( Rationals,A)")) + sage: libgap(QQ).Eigenvalues(A) [ 0 ] .. _section-rref: diff --git a/src/doc/en/constructions/polynomials.rst b/src/doc/en/constructions/polynomials.rst index a928c355ae2..8824bcdc99d 100644 --- a/src/doc/en/constructions/polynomials.rst +++ b/src/doc/en/constructions/polynomials.rst @@ -42,23 +42,24 @@ Another approach to this: sage: a = S.gen() sage: a^20062006 80*a - sage: print(gap.eval("R:= PolynomialRing( GF(97))")) + sage: libgap.eval("R:= PolynomialRing( GF(97))") GF(97)[x_1] - sage: print(gap.eval("i:= IndeterminatesOfPolynomialRing(R)")) + sage: libgap.eval("i:= IndeterminatesOfPolynomialRing(R)") [ x_1 ] - sage: gap.eval("x:= i[1];; f:= x;;") - '' - sage: print(gap.eval("PowerMod( R, x, 20062006, x^3+7 );")) + sage: libgap.eval("x:= i[1]"); libgap.eval("f:= x;") + x_1 + x_1 + sage: libgap.eval("PowerMod( R, x, 20062006, x^3+7 );") Z(97)^41*x_1 - sage: print(gap.eval("PowerMod( R, x, 20062006, x^3+7 );")) + sage: libgap.eval("PowerMod( R, x, 20062006, x^3+7 );") Z(97)^41*x_1 - sage: print(gap.eval("PowerMod( R, x, 2006200620062006, x^3+7 );")) + sage: libgap.eval("PowerMod( R, x, 2006200620062006, x^3+7 );") Z(97)^4*x_1^2 sage: a^2006200620062006 43*a^2 - sage: print(gap.eval("PowerMod( R, x, 2006200620062006, x^3+7 );")) + sage: libgap.eval("PowerMod( R, x, 2006200620062006, x^3+7 );") Z(97)^4*x_1^2 - sage: print(gap.eval("Int(Z(97)^4)")) + sage: libgap.eval("Int(Z(97)^4)") 43 .. index:: @@ -136,11 +137,11 @@ interface. :: - sage: R = gap.PolynomialRing(gap.GF(2)); R - PolynomialRing( GF(2), ["x_1"] ) + sage: R = libgap.PolynomialRing(GF(2)); R + GF(2)[x_1] sage: i = R.IndeterminatesOfPolynomialRing(); i [ x_1 ] - sage: x_1 = i[1] + sage: x_1 = i[0] sage: f = (x_1^3 - x_1 + 1)*(x_1 + x_1^2); f x_1^5+x_1^4+x_1^3+x_1 sage: g = (x_1^3 - x_1 + 1)*(x_1 + 1); g diff --git a/src/doc/en/constructions/rep_theory.rst b/src/doc/en/constructions/rep_theory.rst index daf02719826..c9c5233136f 100644 --- a/src/doc/en/constructions/rep_theory.rst +++ b/src/doc/en/constructions/rep_theory.rst @@ -16,7 +16,7 @@ Sage-GAP interface can be used to compute character tables. You can construct the table of character values of a permutation group :math:`G` as a Sage matrix, using the method ``character_table`` of the PermutationGroup class, or via the -pexpect interface to the GAP command ``CharacterTable``. +interface to the GAP command ``CharacterTable``. :: @@ -29,8 +29,8 @@ pexpect interface to the GAP command ``CharacterTable``. [ 1 -1 1 -1 1] [ 1 1 -1 -1 1] [ 2 0 0 0 -2] - sage: CT = gap(G).CharacterTable() - sage: print(gap.eval("Display(%s)"%CT.name())) + sage: CT = libgap(G).CharacterTable() + sage: CT.Display() CT1 2 3 2 2 2 3 @@ -55,11 +55,10 @@ Here is another example: [ 1 -zeta3 - 1 zeta3 1] [ 1 zeta3 -zeta3 - 1 1] [ 3 0 0 -1] - sage: gap.eval("G := Group((1,2)(3,4),(1,2,3))") - 'Group([ (1,2)(3,4), (1,2,3) ])' - sage: gap.eval("T := CharacterTable(G)") - 'CharacterTable( Alt( [ 1 .. 4 ] ) )' - sage: print(gap.eval("Display(T)")) + sage: G = libgap.eval("Group((1,2)(3,4),(1,2,3))"); G + Group([ (1,2)(3,4), (1,2,3) ]) + sage: T = G.CharacterTable() + sage: T.Display() CT2 2 2 . . 2 @@ -82,28 +81,30 @@ denotes a square root of :math:`-3`, say :math:`i\sqrt{3}`, and :math:`b3 = \frac{1}{2}(-1+i \sqrt{3})`. Note the added ``print`` Python command. This makes the output look much nicer. +.. link + :: - sage: print(gap.eval("irr := Irr(G)")) + sage: irr = G.Irr(); irr [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3)^2, E(3), 1 ] ), Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3), E(3)^2, 1 ] ), Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 3, 0, 0, -1 ] ) ] - sage: print(gap.eval("Display(irr)")) + sage: irr.Display() [ [ 1, 1, 1, 1 ], [ 1, E(3)^2, E(3), 1 ], [ 1, E(3), E(3)^2, 1 ], [ 3, 0, 0, -1 ] ] - sage: gap.eval("CG := ConjugacyClasses(G)") - '[ ()^G, (2,3,4)^G, (2,4,3)^G, (1,2)(3,4)^G ]' - sage: gap.eval("gamma := CG[3]") - '(2,4,3)^G' - sage: gap.eval("g := Representative(gamma)") - '(2,4,3)' - sage: gap.eval("chi := irr[2]") - 'Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3)^2, E(3), 1 ] )' - sage: gap.eval("g^chi") - 'E(3)' + sage: CG = G.ConjugacyClasses(); CG + [ ()^G, (2,3,4)^G, (2,4,3)^G, (1,2)(3,4)^G ] + sage: gamma = CG[2]; gamma + (2,4,3)^G + sage: g = gamma.Representative(); g + (2,4,3) + sage: chi = irr[1]; chi + Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3)^2, E(3), 1 ] ) + sage: g^chi + E(3) This last quantity is the value of the character ``chi`` at the group element ``g``. @@ -117,11 +118,11 @@ table prints nicely. sage: %Pprint Pretty printing has been turned OFF - sage: gap.eval("G := Group((1,2)(3,4),(1,2,3))") - 'Group([ (1,2)(3,4), (1,2,3) ])' - sage: gap.eval("T := CharacterTable(G)") - 'CharacterTable( Alt( [ 1 .. 4 ] ) )' - sage: gap.eval("Display(T)") + sage: G = libgap.eval("Group((1,2)(3,4),(1,2,3))"); G + Group([ (1,2)(3,4), (1,2,3) ]) + sage: T = G.CharacterTable(); T + CharacterTable( Alt( [ 1 .. 4 ] ) ) + sage: T.Display() CT3 2 2 2 . . @@ -138,12 +139,12 @@ table prints nicely. A = E(3)^2 = (-1-Sqrt(-3))/2 = -1-b3 - sage: gap.eval("irr := Irr(G)") + sage: irr = G.Irr(); irr [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ), Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ), Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 3, -1, 0, 0 ] ) ] - sage: gap.eval("Display(irr)") + sage: irr.Display() [ [ 1, 1, 1, 1 ], [ 1, 1, E(3)^2, E(3) ], [ 1, 1, E(3), E(3)^2 ], @@ -162,15 +163,15 @@ Brauer characters The Brauer character tables in GAP do not yet have a "native" interface. To access them you can directly interface with GAP using -pexpect and the ``gap.eval`` command. +the ``libgap.eval`` command. The example below using the GAP interface illustrates the syntax. :: - sage: print(gap.eval("G := Group((1,2)(3,4),(1,2,3))")) + sage: G = libgap.eval("Group((1,2)(3,4),(1,2,3))"); G Group([ (1,2)(3,4), (1,2,3) ]) - sage: print(gap.eval("irr := IrreducibleRepresentations(G,GF(7))")) # random arch. dependent output + sage: irr = G.IrreducibleRepresentations(GF(7)); irr # random arch. dependent output [ [ (1,2)(3,4), (1,2,3) ] -> [ [ [ Z(7)^0 ] ], [ [ Z(7)^4 ] ] ], [ (1,2)(3,4), (1,2,3) ] -> [ [ [ Z(7)^0 ] ], [ [ Z(7)^2 ] ] ], [ (1,2)(3,4), (1,2,3) ] -> [ [ [ Z(7)^0 ] ], [ [ Z(7)^0 ] ] ], @@ -179,16 +180,15 @@ The example below using the GAP interface illustrates the syntax. [ Z(7), Z(7)^5, Z(7)^2 ] ], [ [ 0*Z(7), Z(7)^0, 0*Z(7) ], [ 0*Z(7), 0*Z(7), Z(7)^0 ], [ Z(7)^0, 0*Z(7), 0*Z(7) ] ] ] ] - sage: gap.eval("brvals := List(irr,chi->List(ConjugacyClasses(G),c->BrauerCharacterValue(Image(chi,Representative(c)))))") - '' - sage: print(gap.eval("Display(brvals)")) # random architecture dependent output + sage: brvals = [[chi.Image(c.Representative()).BrauerCharacterValue() + ....: for c in G.ConjugacyClasses()] for chi in irr] + sage: brvals # random architecture dependent output [ [ 1, 1, E(3)^2, E(3) ], [ 1, 1, E(3), E(3)^2 ], [ 1, 1, 1, 1 ], [ 3, -1, 0, 0 ] ] - sage: print(gap.eval("T := CharacterTable(G)")) - CharacterTable( Alt( [ 1 .. 4 ] ) ) - sage: print(gap.eval("Display(T)")) + sage: T = G.CharacterTable() + sage: T.Display() CT3 2 2 . . 2 diff --git a/src/doc/en/constructions/rings.rst b/src/doc/en/constructions/rings.rst index 54a23a080b5..65557b229e1 100644 --- a/src/doc/en/constructions/rings.rst +++ b/src/doc/en/constructions/rings.rst @@ -72,16 +72,13 @@ Here is another approach using GAP: :: - sage: R = gap.new("PolynomialRing(GF(97), 4)"); R - PolynomialRing( GF(97), ["x_1", "x_2", "x_3", "x_4"] ) + sage: R = libgap.PolynomialRing(GF(97), 4); R + GF(97)[x_1,x_2,x_3,x_4] sage: I = R.IndeterminatesOfPolynomialRing(); I [ x_1, x_2, x_3, x_4 ] - sage: vars = (I.name(), I.name(), I.name(), I.name()) - sage: _ = gap.eval( - ....: "x_0 := %s[1];; x_1 := %s[2];; x_2 := %s[3];;x_3 := %s[4];;" - ....: % vars) - sage: f = gap.new("x_1*x_2+x_3"); f - x_2*x_3+x_4 + sage: x1, x2, x3, x4 = I + sage: f = x1*x2 + x3; f + x_1*x_2+x_3 sage: f.Value(I,[1,1,1,1]) Z(97)^34 diff --git a/src/doc/en/developer/coding_in_other.rst b/src/doc/en/developer/coding_in_other.rst index d1abfcb65cb..3410c9e6edc 100644 --- a/src/doc/en/developer/coding_in_other.rst +++ b/src/doc/en/developer/coding_in_other.rst @@ -161,10 +161,11 @@ convert output from PARI to Sage objects: GAP === -Wrapping a GAP function in Sage is a matter of writing a program in -Python that uses the pexpect interface to pipe various commands to GAP -and read back the input into Sage. This is sometimes easy, sometimes -hard. +Wrapping a GAP function in Sage can be done in two different ways. The +first one uses the ``pexpect`` interface to pipe various commands to +GAP and read back the input into Sage. The second way is to access GAP +through its library interface ``libgap``. We recommend the second one +for the sake of efficiency. For example, suppose we want to make a wrapper for the computation of the Cartan matrix of a simple Lie algebra. The Cartan matrix of `G_2` @@ -180,32 +181,30 @@ is available in GAP using the commands: In Sage, one can access these commands by typing:: - sage: L = gap.SimpleLieAlgebra('"G"', 2, 'Rationals'); L - Algebra( Rationals, [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, - v.11, v.12, v.13, v.14 ] ) + sage: L = libgap.SimpleLieAlgebra("G", 2, QQ); L + sage: R = L.RootSystem(); R sage: R.CartanMatrix() [ [ 2, -1 ], [ -3, 2 ] ] -Note the ``'"G"'`` which is evaluated in GAP as the string ``"G"``. - The purpose of this section is to use this example to show how one might write a Python/Sage program whose input is, say, ``('G',2)`` and whose output is the matrix above (but as a Sage Matrix---see the code in the directory :sage_root:`src/sage/matrix/` and the corresponding parts of the Sage reference manual). -First, the input must be converted into strings consisting of legal -GAP commands. Then the GAP output, which is also a string, must be -parsed and converted if possible to a corresponding Sage/Python -object. +First, the input must be converted into a libgap object, either by +applying ``libgap.eval`` on a string, or by using a GAP command +``CMD`` as a ``libgap.CMD`` method. Then one can work with these +object using other GAP commands as ``libgap`` methods. At the end, one +can convert back to sage using the method ``sage`` if it works. .. skip .. CODE-BLOCK:: python - def cartan_matrix(type, rank): + def cartan_matrix(typ, rank): """ Return the Cartan matrix of given Chevalley type and rank. @@ -213,7 +212,7 @@ object. - type -- a Chevalley letter name, as a string, for a family type of simple Lie algebras - - rank -- an integer (legal for that type). + - rank -- an integer (legal for that type) EXAMPLES:: @@ -227,23 +226,16 @@ object. [ 2 -1] [-3 2] """ - L = gap.SimpleLieAlgebra('"%s"' % type, rank, 'Rationals') + L = libgap.SimpleLieAlgebra(typ, rank, libgap.Rationals) R = L.RootSystem() sM = R.CartanMatrix() - ans = eval(str(sM)) + ans = sM.sage() MS = MatrixSpace(QQ, rank) return MS(ans) The output ``ans`` is a Python list. The last two lines convert that list to an instance of the Sage class ``Matrix``. -Alternatively, one could replace the first line of the above function -with this: - -.. CODE-BLOCK:: python - - L = gap.new('SimpleLieAlgebra("%s", %s, Rationals);'%(type, rank)) - Defining "easy" and "hard" is subjective, but here is one definition. Wrapping a GAP function is "easy" if there is already a corresponding class in Python or Sage for the output data type of the GAP function diff --git a/src/doc/en/developer/coding_in_python.rst b/src/doc/en/developer/coding_in_python.rst index 82dda02f209..bb08408777b 100644 --- a/src/doc/en/developer/coding_in_python.rst +++ b/src/doc/en/developer/coding_in_python.rst @@ -668,17 +668,28 @@ Deprecation =========== When making a **backward-incompatible** modification in Sage, the old code should -keep working and display a message indicating how it should be updated/written -in the future. We call this a *deprecation*. +keep working and a message indicating how the code should be updated/written +in the future should be displayed somewhere. We call this *deprecation*. We explain +how to do the deprecation, the deprecation policy, below. + +Any class, function, method, or attribute defined in a file under +:sage_root:`src/sage` is subject to the deprecation policy. If its name starts +with an underscore, then it is considered internal, and exempt from the +deprecation policy. .. NOTE:: - Deprecated code can only be removed one year after the first - stable release in which it appeared. + A deprecated class, function, method, or attribute can only be removed one + year after the first stable release in which it appeared. + +When a deprecated function, method, or attribute is used, a deprecation warning +is issued. The warning message contains the number of the GitHub PR that +implemented the deprecation. We use 12345 in the examples below. -Each deprecation warning contains the number of the GitHub PR that defines -it. We use 666 in the examples below. For each entry, consult the function's -documentation for more information on its behaviour and optional arguments. +.. NOTE:: + + For deprecation tools used in the examples, consult the tool's documentation for more + information on its behaviour and optional arguments. * **Rename a keyword:** by decorating a function/method with :class:`~sage.misc.decorators.rename_keyword`, any user calling @@ -687,7 +698,7 @@ documentation for more information on its behaviour and optional arguments. .. CODE-BLOCK:: python from sage.misc.decorators import rename_keyword - @rename_keyword(deprecation=666, my_old_keyword='my_new_keyword') + @rename_keyword(deprecation=12345, my_old_keyword='my_new_keyword') def my_function(my_new_keyword=True): return my_new_keyword @@ -701,7 +712,7 @@ documentation for more information on its behaviour and optional arguments. def my_new_function(): ... - my_old_function = deprecated_function_alias(666, my_new_function) + my_old_function = deprecated_function_alias(12345, my_new_function) * **Moving an object to a different module:** if you rename a source file or move some function (or class) to a @@ -713,7 +724,7 @@ documentation for more information on its behaviour and optional arguments. .. CODE-BLOCK:: python from sage.misc.lazy_import import lazy_import - lazy_import('sage.new.module.name', 'name_of_the_function', deprecation=666) + lazy_import('sage.new.module.name', 'name_of_the_function', deprecation=12345) You can also lazily import everything using ``*`` or a few functions using a tuple: @@ -721,8 +732,8 @@ documentation for more information on its behaviour and optional arguments. .. CODE-BLOCK:: python from sage.misc.lazy_import import lazy_import - lazy_import('sage.new.module.name', '*', deprecation=666) - lazy_import('sage.other.module', ('func1', 'func2'), deprecation=666) + lazy_import('sage.new.module.name', '*', deprecation=12345) + lazy_import('sage.other.module', ('func1', 'func2'), deprecation=12345) * **Remove a name from a global namespace:** this is when you want to remove a name from a global namespace (say, ``sage.all`` or some @@ -736,7 +747,7 @@ documentation for more information on its behaviour and optional arguments. .. CODE-BLOCK:: python from sage.misc.lazy_import import lazy_import as _lazy_import - _lazy_import('sage.some.package', 'some_function', deprecation=666) + _lazy_import('sage.some.package', 'some_function', deprecation=12345) * **Any other case:** if none of the cases above apply, call :func:`~sage.misc.superseded.deprecation` in the function that you want to @@ -746,18 +757,51 @@ documentation for more information on its behaviour and optional arguments. .. CODE-BLOCK:: python from sage.misc.superseded import deprecation - deprecation(666, "Do not use your computer to compute 1+1. Use your brain.") + deprecation(12345, "Do not use your computer to compute 1 + 1. Use your brain.") + +.. NOTE:: + + These decorators only work for Python. There is no implementation + of decorators in Cython. Hence, when in need to rename a keyword/function/method/... + in a Cython (.pyx) file and/or to deprecate something, forget about decorators and + just use :func:`~sage.misc.superseded.deprecation_cython` instead. The usage of + :func:`~sage.misc.superseded.deprecation_cython` is exactly the same as + :func:`~sage.misc.superseded.deprecation`. + +When a class is renamed or removed, it should be deprecated unless it is +internal. A class is internal if its name starts with an underscore, or experts +(authors and reviewers of a PR making changes to the class) agree that the +class is unlikely to be directly imported by user code. Otherwise, or if experts +disagree, it is public. + +As a class is imported rather than run by user code, there are some technical +difficulties in using the above deprecation tools. Instead we follow +the procedure below: + +* **Renaming a class:** rename ``OldClass`` to ``NewClass`` and add an + alias ``OldClass = NewClass``: + + .. CODE-BLOCK:: python + + class NewClass: + ... + + OldClass = NewClass # OldClass is deprecated. See Issue 12345. + +* **Removing a class:** add a comment: + + .. CODE-BLOCK:: python + + # OldClass is deprecated. See Issue 12345. + + class OldClass: -Note that these decorators only work for (pure) Python. There is no implementation -of decorators in Cython. Hence, when in need to rename a keyword/function/method/... -in a Cython (.pyx) file and/or to deprecate something, forget about decorators and -just use :func:`~sage.misc.superseded.deprecation_cython` instead. The usage of -:func:`~sage.misc.superseded.deprecation_cython` is exactly the same as -:func:`~sage.misc.superseded.deprecation`. +In both cases, make it sure to display the change in the "Deprecations" +section of the release notes of the next stable release. Experimental/unstable code --------------------------- +========================== You can mark your newly created code (classes/functions/methods) as experimental/unstable. In this case, no deprecation warning is needed @@ -778,7 +822,7 @@ reviewing process. .. CODE-BLOCK:: python from sage.misc.superseded import experimental - @experimental(66666) + @experimental(12345) def experimental_function(): # do something @@ -790,7 +834,7 @@ reviewing process. from sage.misc.superseded import experimental class experimental_class(SageObject): - @experimental(66666) + @experimental(12345) def __init__(self, some, arguments): # do something @@ -801,7 +845,7 @@ reviewing process. .. CODE-BLOCK:: python from sage.misc.superseded import experimental_warning - experimental_warning(66666, 'This code is not foolproof.') + experimental_warning(12345, 'This code is not foolproof.') Using optional packages diff --git a/src/doc/en/developer/conf.py b/src/doc/en/developer/conf.py index 58e0ca995b7..6e80447f4c7 100644 --- a/src/doc/en/developer/conf.py +++ b/src/doc/en/developer/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/developer', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/developer', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/developer', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/developer/doctesting.rst b/src/doc/en/developer/doctesting.rst index 75cc659934f..71145b8082a 100644 --- a/src/doc/en/developer/doctesting.rst +++ b/src/doc/en/developer/doctesting.rst @@ -745,10 +745,10 @@ In order to run the long tests as well, do the following:: cpu time: 25.2 seconds cumulative wall time: 34.7 seconds -To find tests that take longer than the allowed time use the -``--warn-long`` flag. Without any options it will cause tests to -print a warning if they take longer than 1.0 second. Note that this is -a warning, not an error:: +To find tests that take longer than a specified amount of CPU time, +use the ``--warn-long`` flag. Without any options, it will cause a +warning to be printed if any tests take longer than one +cpu-second. Note that this is a warning, not an error:: [roed@localhost sage]$ ./sage -t --warn-long src/sage/rings/factorint.pyx Running doctests with ID 2012-07-14-03-27-03-2c952ac1. @@ -758,22 +758,22 @@ a warning, not an error:: File "src/sage/rings/factorint.pyx", line 125, in sage.rings.factorint.base_exponent Failed example: base_exponent(-4) - Test ran for 4.09 s + Test ran for 4.09 cpu seconds ********************************************************************** File "src/sage/rings/factorint.pyx", line 153, in sage.rings.factorint.factor_aurifeuillian Failed example: fa(2^6+1) - Test ran for 2.22 s + Test ran for 2.22 cpu seconds ********************************************************************** File "src/sage/rings/factorint.pyx", line 155, in sage.rings.factorint.factor_aurifeuillian Failed example: fa(2^58+1) - Test ran for 2.22 s + Test ran for 2.22 cpu seconds ********************************************************************** File "src/sage/rings/factorint.pyx", line 163, in sage.rings.factorint.factor_aurifeuillian Failed example: fa(2^4+1) - Test ran for 2.25 s + Test ran for 2.25 cpu seconds ********************************************************************** ---------------------------------------------------------------------- All tests passed! @@ -792,12 +792,12 @@ You can also pass in an explicit amount of time:: File "tests.py", line 240, in sage.rings.tests.test_random_elements Failed example: sage.rings.tests.test_random_elements(trials=1000) # long time (5 seconds) - Test ran for 13.36 s + Test ran for 13.36 cpu seconds ********************************************************************** File "tests.py", line 283, in sage.rings.tests.test_random_arith Failed example: sage.rings.tests.test_random_arith(trials=1000) # long time (5 seconds?) - Test ran for 12.42 s + Test ran for 12.42 cpu seconds ********************************************************************** ---------------------------------------------------------------------- All tests passed! diff --git a/src/doc/en/developer/index.rst b/src/doc/en/developer/index.rst index 7dc5cefd440..bc4f982ffe0 100644 --- a/src/doc/en/developer/index.rst +++ b/src/doc/en/developer/index.rst @@ -4,14 +4,6 @@ Welcome to Sage Developer Guide =============================== -.. NOTE:: - - Sage development moved to `GitHub `_ in - February 2023, from `the Sage Trac server `_, - which had been the center of Sage development for a long time. After the - transition, this guide was updated accordingly. However, the legacy is - still with us in many aspects of the current Sage development. - Everybody who uses Sage is encouraged to contribute something back to Sage at some point. You could: diff --git a/src/doc/en/developer/portability_platform_table.rst b/src/doc/en/developer/portability_platform_table.rst index 67ebb9f7c0b..d8d56329d4d 100644 --- a/src/doc/en/developer/portability_platform_table.rst +++ b/src/doc/en/developer/portability_platform_table.rst @@ -1564,113 +1564,167 @@ .. |codespace-fedora-40-maximal| image:: https://github.com/codespaces/badge.svg :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-fedora-40-maximal%2Fdevcontainer.json -.. |image-centos-7-devtoolset-gcc_11-minimal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-system-packages +.. |image-fedora-41-minimal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-minimal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-minimal-with-system-packages -.. |image-centos-7-devtoolset-gcc_11-minimal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-configured +.. |image-fedora-41-minimal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-minimal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-minimal-configured -.. |image-centos-7-devtoolset-gcc_11-minimal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%23677895 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-targets-pre +.. |image-fedora-41-minimal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-minimal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%23677895 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-minimal-with-targets-pre -.. |image-centos-7-devtoolset-gcc_11-minimal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%236686c1 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-targets +.. |image-fedora-41-minimal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-minimal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%236686c1 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-minimal-with-targets -.. |image-centos-7-devtoolset-gcc_11-minimal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%236495ed - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-minimal-with-targets-optional +.. |image-fedora-41-minimal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-minimal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%236495ed + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-minimal-with-targets-optional -.. |codespace-centos-7-devtoolset-gcc_11-minimal| image:: https://github.com/codespaces/badge.svg - :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-7-devtoolset-gcc_11-minimal%2Fdevcontainer.json +.. |codespace-fedora-41-minimal| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-fedora-41-minimal%2Fdevcontainer.json -.. |image-centos-7-devtoolset-gcc_11-standard-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-system-packages +.. |image-fedora-41-standard-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-standard-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-standard-with-system-packages -.. |image-centos-7-devtoolset-gcc_11-standard-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-configured +.. |image-fedora-41-standard-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-standard-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-standard-configured -.. |image-centos-7-devtoolset-gcc_11-standard-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%235d8a4c - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-targets-pre +.. |image-fedora-41-standard-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-standard-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%235d8a4c + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-standard-with-targets-pre -.. |image-centos-7-devtoolset-gcc_11-standard-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%2350ab2e - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-targets +.. |image-fedora-41-standard-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-standard-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%2350ab2e + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-standard-with-targets -.. |image-centos-7-devtoolset-gcc_11-standard-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%2344cc11 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-standard-with-targets-optional +.. |image-fedora-41-standard-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-standard-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%2344cc11 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-standard-with-targets-optional -.. |codespace-centos-7-devtoolset-gcc_11-standard| image:: https://github.com/codespaces/badge.svg - :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-7-devtoolset-gcc_11-standard%2Fdevcontainer.json +.. |codespace-fedora-41-standard| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-fedora-41-standard%2Fdevcontainer.json -.. |image-centos-7-devtoolset-gcc_11-maximal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-system-packages +.. |image-fedora-41-maximal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-maximal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-maximal-with-system-packages -.. |image-centos-7-devtoolset-gcc_11-maximal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-configured +.. |image-fedora-41-maximal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-maximal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-maximal-configured -.. |image-centos-7-devtoolset-gcc_11-maximal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%238f6b8d - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-targets-pre +.. |image-fedora-41-maximal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-maximal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%238f6b8d + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-maximal-with-targets-pre -.. |image-centos-7-devtoolset-gcc_11-maximal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%23b46eb2 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-targets +.. |image-fedora-41-maximal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-maximal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%23b46eb2 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-maximal-with-targets -.. |image-centos-7-devtoolset-gcc_11-maximal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%23da70d6 - :target: https://ghcr.io/sagemath/sage/sage-centos-7-devtoolset-gcc_11-maximal-with-targets-optional +.. |image-fedora-41-maximal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-fedora-41-maximal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%23da70d6 + :target: https://ghcr.io/sagemath/sage/sage-fedora-41-maximal-with-targets-optional -.. |codespace-centos-7-devtoolset-gcc_11-maximal| image:: https://github.com/codespaces/badge.svg - :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-7-devtoolset-gcc_11-maximal%2Fdevcontainer.json +.. |codespace-fedora-41-maximal| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-fedora-41-maximal%2Fdevcontainer.json -.. |image-centos-stream-9-python3.9-minimal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-system-packages +.. |image-centos-stream-9-minimal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-minimal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-minimal-with-system-packages -.. |image-centos-stream-9-python3.9-minimal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-minimal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-minimal-configured +.. |image-centos-stream-9-minimal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-minimal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-minimal-configured -.. |image-centos-stream-9-python3.9-minimal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%23677895 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-targets-pre +.. |image-centos-stream-9-minimal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-minimal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%23677895 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-minimal-with-targets-pre -.. |image-centos-stream-9-python3.9-minimal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%236686c1 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-targets +.. |image-centos-stream-9-minimal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-minimal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%236686c1 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-minimal-with-targets -.. |image-centos-stream-9-python3.9-minimal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%236495ed - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-minimal-with-targets-optional +.. |image-centos-stream-9-minimal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-minimal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%236495ed + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-minimal-with-targets-optional -.. |codespace-centos-stream-9-python3.9-minimal| image:: https://github.com/codespaces/badge.svg - :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-python3.9-minimal%2Fdevcontainer.json +.. |codespace-centos-stream-9-minimal| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-minimal%2Fdevcontainer.json -.. |image-centos-stream-9-python3.9-standard-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-system-packages +.. |image-centos-stream-9-standard-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-standard-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-standard-with-system-packages -.. |image-centos-stream-9-python3.9-standard-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-standard-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-standard-configured +.. |image-centos-stream-9-standard-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-standard-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-standard-configured -.. |image-centos-stream-9-python3.9-standard-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%235d8a4c - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-targets-pre +.. |image-centos-stream-9-standard-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-standard-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%235d8a4c + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-standard-with-targets-pre -.. |image-centos-stream-9-python3.9-standard-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%2350ab2e - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-targets +.. |image-centos-stream-9-standard-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-standard-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%2350ab2e + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-standard-with-targets -.. |image-centos-stream-9-python3.9-standard-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%2344cc11 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-standard-with-targets-optional +.. |image-centos-stream-9-standard-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-standard-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%2344cc11 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-standard-with-targets-optional -.. |codespace-centos-stream-9-python3.9-standard| image:: https://github.com/codespaces/badge.svg - :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-python3.9-standard%2Fdevcontainer.json +.. |codespace-centos-stream-9-standard| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-standard%2Fdevcontainer.json -.. |image-centos-stream-9-python3.9-maximal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-system-packages +.. |image-centos-stream-9-maximal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-maximal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-maximal-with-system-packages -.. |image-centos-stream-9-python3.9-maximal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-maximal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-maximal-configured +.. |image-centos-stream-9-maximal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-maximal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-maximal-configured -.. |image-centos-stream-9-python3.9-maximal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%238f6b8d - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-targets-pre +.. |image-centos-stream-9-maximal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-maximal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%238f6b8d + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-maximal-with-targets-pre -.. |image-centos-stream-9-python3.9-maximal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%23b46eb2 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-targets +.. |image-centos-stream-9-maximal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-maximal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%23b46eb2 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-maximal-with-targets -.. |image-centos-stream-9-python3.9-maximal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%23da70d6 - :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.9-maximal-with-targets-optional +.. |image-centos-stream-9-maximal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-maximal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%23da70d6 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-maximal-with-targets-optional -.. |codespace-centos-stream-9-python3.9-maximal| image:: https://github.com/codespaces/badge.svg - :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-python3.9-maximal%2Fdevcontainer.json +.. |codespace-centos-stream-9-maximal| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-maximal%2Fdevcontainer.json + +.. |image-centos-stream-9-python3.12-minimal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-system-packages + +.. |image-centos-stream-9-python3.12-minimal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-minimal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-minimal-configured + +.. |image-centos-stream-9-python3.12-minimal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%23677895 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-targets-pre + +.. |image-centos-stream-9-python3.12-minimal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%236686c1 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-targets + +.. |image-centos-stream-9-python3.12-minimal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%236495ed + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-minimal-with-targets-optional + +.. |codespace-centos-stream-9-python3.12-minimal| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-python3.12-minimal%2Fdevcontainer.json + +.. |image-centos-stream-9-python3.12-standard-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-system-packages + +.. |image-centos-stream-9-python3.12-standard-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-standard-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-standard-configured + +.. |image-centos-stream-9-python3.12-standard-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%235d8a4c + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-targets-pre + +.. |image-centos-stream-9-python3.12-standard-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%2350ab2e + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-targets + +.. |image-centos-stream-9-python3.12-standard-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%2344cc11 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-standard-with-targets-optional + +.. |codespace-centos-stream-9-python3.12-standard| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-python3.12-standard%2Fdevcontainer.json + +.. |image-centos-stream-9-python3.12-maximal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-system-packages + +.. |image-centos-stream-9-python3.12-maximal-configured| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-maximal-configured/latest_tag?ignore=latest,dev,*-failed&label=configured&color=%23696969 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-maximal-configured + +.. |image-centos-stream-9-python3.12-maximal-with-targets-pre| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-targets-pre/latest_tag?ignore=latest,dev,*-failed&label=with-targets-pre&color=%238f6b8d + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-targets-pre + +.. |image-centos-stream-9-python3.12-maximal-with-targets| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-targets/latest_tag?ignore=latest,dev,*-failed&label=with-targets&color=%23b46eb2 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-targets + +.. |image-centos-stream-9-python3.12-maximal-with-targets-optional| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-targets-optional/latest_tag?ignore=latest,dev,*-failed&label=with-targets-optional&color=%23da70d6 + :target: https://ghcr.io/sagemath/sage/sage-centos-stream-9-python3.12-maximal-with-targets-optional + +.. |codespace-centos-stream-9-python3.12-maximal| image:: https://github.com/codespaces/badge.svg + :target: https://codespaces.new/sagemath/sage?devcontainer_path=.devcontainer%2Fportability-centos-stream-9-python3.12-maximal%2Fdevcontainer.json .. |image-almalinux-8-python3.9-minimal-with-system-packages| image:: https://ghcr-badge.egpl.dev/sagemath/sage/sage-almalinux-8-python3.9-minimal-with-system-packages/size?tag=dev&label=with-system-packages&color=%23696969 :target: https://ghcr.io/sagemath/sage/sage-almalinux-8-python3.9-minimal-with-system-packages @@ -2647,27 +2701,38 @@ * -    ‑*maximal* - |image-fedora-40-maximal-with-system-packages| |image-fedora-40-maximal-with-targets-pre| - - * - **centos**-7-devtoolset-gcc_11 + * - **fedora**-41 + +    ‑*minimal* + - |image-fedora-41-minimal-with-system-packages| |image-fedora-41-minimal-with-targets-pre| |image-fedora-41-minimal-with-targets| |image-fedora-41-minimal-with-targets-optional| + - |codespace-fedora-41-minimal| + * -    ‑*standard* + - |image-fedora-41-standard-with-system-packages| |image-fedora-41-standard-with-targets-pre| |image-fedora-41-standard-with-targets| |image-fedora-41-standard-with-targets-optional| + - |codespace-fedora-41-standard| + * -    ‑*maximal* + - |image-fedora-41-maximal-with-system-packages| |image-fedora-41-maximal-with-targets-pre| + - + * - **centos**-stream-9    ‑*minimal* - - |image-centos-7-devtoolset-gcc_11-minimal-with-system-packages| |image-centos-7-devtoolset-gcc_11-minimal-with-targets-pre| |image-centos-7-devtoolset-gcc_11-minimal-with-targets| |image-centos-7-devtoolset-gcc_11-minimal-with-targets-optional| - - |codespace-centos-7-devtoolset-gcc_11-minimal| + - |image-centos-stream-9-minimal-with-system-packages| |image-centos-stream-9-minimal-with-targets-pre| |image-centos-stream-9-minimal-with-targets| |image-centos-stream-9-minimal-with-targets-optional| + - |codespace-centos-stream-9-minimal| * -    ‑*standard* - - |image-centos-7-devtoolset-gcc_11-standard-with-system-packages| |image-centos-7-devtoolset-gcc_11-standard-with-targets-pre| |image-centos-7-devtoolset-gcc_11-standard-with-targets| |image-centos-7-devtoolset-gcc_11-standard-with-targets-optional| - - |codespace-centos-7-devtoolset-gcc_11-standard| + - |image-centos-stream-9-standard-with-system-packages| |image-centos-stream-9-standard-with-targets-pre| |image-centos-stream-9-standard-with-targets| |image-centos-stream-9-standard-with-targets-optional| + - |codespace-centos-stream-9-standard| * -    ‑*maximal* - - |image-centos-7-devtoolset-gcc_11-maximal-with-system-packages| |image-centos-7-devtoolset-gcc_11-maximal-with-targets-pre| + - |image-centos-stream-9-maximal-with-system-packages| |image-centos-stream-9-maximal-with-targets-pre| - - * - **centos**-stream-9-python3.9 + * - **centos**-stream-9-python3.12    ‑*minimal* - - |image-centos-stream-9-python3.9-minimal-with-system-packages| |image-centos-stream-9-python3.9-minimal-with-targets-pre| |image-centos-stream-9-python3.9-minimal-with-targets| |image-centos-stream-9-python3.9-minimal-with-targets-optional| - - |codespace-centos-stream-9-python3.9-minimal| + - |image-centos-stream-9-python3.12-minimal-with-system-packages| |image-centos-stream-9-python3.12-minimal-with-targets-pre| |image-centos-stream-9-python3.12-minimal-with-targets| |image-centos-stream-9-python3.12-minimal-with-targets-optional| + - |codespace-centos-stream-9-python3.12-minimal| * -    ‑*standard* - - |image-centos-stream-9-python3.9-standard-with-system-packages| |image-centos-stream-9-python3.9-standard-with-targets-pre| |image-centos-stream-9-python3.9-standard-with-targets| |image-centos-stream-9-python3.9-standard-with-targets-optional| - - |codespace-centos-stream-9-python3.9-standard| + - |image-centos-stream-9-python3.12-standard-with-system-packages| |image-centos-stream-9-python3.12-standard-with-targets-pre| |image-centos-stream-9-python3.12-standard-with-targets| |image-centos-stream-9-python3.12-standard-with-targets-optional| + - |codespace-centos-stream-9-python3.12-standard| * -    ‑*maximal* - - |image-centos-stream-9-python3.9-maximal-with-system-packages| |image-centos-stream-9-python3.9-maximal-with-targets-pre| + - |image-centos-stream-9-python3.12-maximal-with-system-packages| |image-centos-stream-9-python3.12-maximal-with-targets-pre| - * - **almalinux**-8-python3.9 diff --git a/src/doc/en/developer/review.rst b/src/doc/en/developer/review.rst index 0a55393955b..cdcbd42c375 100644 --- a/src/doc/en/developer/review.rst +++ b/src/doc/en/developer/review.rst @@ -76,6 +76,13 @@ The following should generally be checked while reading and testing the code: optional doctests related to the functionality. See :ref:`chapter-doctesting` for more information. +For changes that affect the **user interface**, in particular, upgrades to +IPython and Jupyter component packages, manual testing is crucial because +our automatic tests do not cover the user interface. We recommend to use +a `Jupyter notebook with comprehensive tests of graphics and typesetting +`_, +some of which is Sage-specific. + You are now ready to change the PR's status (see :ref:`section-github-pr-status`): diff --git a/src/doc/en/faq/conf.py b/src/doc/en/faq/conf.py index fab823b6592..a175e9cf0ee 100644 --- a/src/doc/en/faq/conf.py +++ b/src/doc/en/faq/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -22,9 +27,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/faq', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/faq', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/faq', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index 53f225fd729..393a9c369e5 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -324,7 +324,7 @@ ints. For example:: sage: RealNumber = float; Integer = int sage: from scipy import stats sage: stats.ttest_ind([1,2,3,4,5], [2,3,4,5,.6]) - Ttest...Result(statistic=0.0767529..., pvalue=0.940704...) + Ttest...Result(statistic=...0.0767529..., pvalue=...0.940704...) sage: stats.uniform(0,15).ppf([0.5,0.7]) array([ 7.5, 10.5]) @@ -479,35 +479,6 @@ How do I run sage in daemon mode, i.e. as a service? There are several possibilities. Use ``screen``, ``nohup`` or ``disown``. -The show command for plotting 3-D objects does not work. -"""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -The default live 3-D plotting for Sage 6.4+ uses -`Jmol/JSmol `_ -for viewing. From the command line the Jmol Java application is used, -and for in browser viewing either pure javascript or a Java applet -is used. By default in browsers pure javascript is used to avoid -the problems with some browsers that do not support java applet -plugins (namely Chrome). On each browser worksheet there is a -checkbox which must be checked before a 3-D plot is generated if -the user wants to use the Java applet (the applet is a little faster -with complex plots). - -The most likely reason for a malfunction is that you do not have -a Java Run Time Environment (JRE) installed or you have one older than -version 1.7. If things work from the command line another possibility -is that your browser does not have the proper plugin to support Java -applets (at present, 2014, plugins do not work with most versions of -Chrome). Make sure you have installed either the IcedTea browser -plugin (for linux see your package manager), see: -`IcedTea `_, -or the Oracle Java plugin see: -`Java `_. - -If you are using a Sage server over the web and even javascript rendering -does not work, you may have a problem with your browser's javascript -engine or have it turned off. - May I use Sage tools in a commercial environment? """"""""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 49495d60ebf..69369767854 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -7,7 +7,7 @@ SageMath can be installed on Linux and macOS via Conda from the `conda-forge `_ conda channel. Both the ``x86_64`` (Intel) architecture and the ``arm64``/``aarch64`` -architectures (including Apple Silicon, M1) are supported. +architectures (including Apple Silicon, M1, M2, M3, M4) are supported. You will need a working Conda installation: either Miniforge (or Mambaforge), Miniconda or Anaconda. If you don't have one yet, we recommend installing @@ -27,8 +27,8 @@ follows. In a terminal, * Change channel priority to strict: ``conda config --set channel_priority strict`` -If you installed Miniforge (or Mambaforge), we recommend to use -`mamba `_ in the following, +If you installed Miniforge (or Mambaforge), we recommend to use +`mamba `_ in the following, which uses a faster dependency solver than ``conda``. .. _sec-installation-conda-binary: @@ -70,27 +70,27 @@ Using conda to provide system packages for the Sage distribution If Conda is installed (check by typing ``conda info``), one can install SageMath from source as follows: - - Create a new conda environment including all standard packages - recognized by sage, and activate it:: +- Create a new conda environment including all standard packages + recognized by sage, and activate it:: - $ conda env create --file environment-3.11-linux.yml --name sage-build - $ conda activate sage-build + $ conda env create --file environment-3.11-linux.yml --name sage-build + $ conda activate sage-build - If you use a different architecture, replace ``linux`` by ``macos``. - Alternatively, use ``environment-optional-3.11-linux.yml`` in place of - ``environment-3.11-linux.yml`` to create an environment with all standard and optional - packages recognized by sage. + If you use a different architecture, replace ``linux`` by ``macos``. + Alternatively, use ``environment-optional-3.11-linux.yml`` in place of + ``environment-3.11-linux.yml`` to create an environment with all standard and optional + packages recognized by sage. - A different Python version can be selected by replacing ``3.11`` by ``3.9`` - or ``3.10`` in these commands. + A different Python version can be selected by replacing ``3.11`` by ``3.9`` + or ``3.10`` in these commands. - - Then the SageMath distribution will be built using the compilers provided by Conda - and using many packages installed by Conda:: +- Then the SageMath distribution will be built using the compilers provided by Conda + and using many packages installed by Conda:: - $ ./bootstrap - $ ./configure --with-python=$CONDA_PREFIX/bin/python \ - --prefix=$CONDA_PREFIX - $ make + $ ./bootstrap + $ ./configure --with-python=$CONDA_PREFIX/bin/python \ + --prefix=$CONDA_PREFIX + $ make .. _sec-installation-conda-develop: @@ -105,51 +105,51 @@ environment for Sage development. Here we assume that you are using a git checkout. - - Optionally, set the build parallelism for the Sage library. Use - whatever the meaningful value for your machine is - no more than - the number of cores:: +- Optionally, set the build parallelism for the Sage library. Use + whatever the meaningful value for your machine is - no more than + the number of cores:: - $ export SAGE_NUM_THREADS=24 + $ export SAGE_NUM_THREADS=24 - - Create and activate a new conda environment with the dependencies of Sage - and a few additional developer tools:: +- Create and activate a new conda environment with the dependencies of Sage + and a few additional developer tools: - .. tab:: mamba - - .. code-block:: shell - - $ mamba env create --file src/environment-dev-3.11-linux.yml --name sage-dev - $ conda activate sage-dev - - .. tab:: conda - - .. code-block:: shell - - $ conda env create --file src/environment-dev-3.11-linux.yml --name sage-dev - $ conda activate sage-dev + .. tab:: mamba - Alternatively, you can use ``src/environment-3.11-linux.yml`` or - ``src/environment-optional-3.11-linux.yml``, which will only install standard - (and optional) packages without any additional developer tools. + .. code-block:: shell - A different Python version can be selected by replacing ``3.11`` by ``3.9`` - or ``3.10`` in these commands. + $ mamba env create --file src/environment-dev-3.11-linux.yml --name sage-dev + $ conda activate sage-dev - - Bootstrap the source tree and install the build prerequisites and the Sage library:: + .. tab:: conda - $ ./bootstrap - $ pip install --no-build-isolation --config-settings editable_mode=compat -v -v --editable ./src + .. code-block:: shell - If you encounter any errors, try to install the ``sage-conf`` package first:: + $ conda env create --file src/environment-dev-3.11-linux.yml --name sage-dev + $ conda activate sage-dev - $ pip install --no-build-isolation -v -v --editable ./pkgs/sage-conf_conda + Alternatively, you can use ``src/environment-3.11-linux.yml`` or + ``src/environment-optional-3.11-linux.yml``, which will only install standard + (and optional) packages without any additional developer tools. - and then run the last command again. + A different Python version can be selected by replacing ``3.11`` by ``3.9`` + or ``3.10`` in these commands. - - Verify that Sage has been installed:: +- Bootstrap the source tree and install the build prerequisites and the Sage library:: - $ sage -c 'print(version())' - SageMath version 10.2.beta4, Release Date: 2023-09-24 + $ ./bootstrap + $ pip install --no-build-isolation --config-settings editable_mode=compat -v -v --editable ./src + + If you encounter any errors, try to install the ``sage-conf`` package first:: + + $ pip install --no-build-isolation -v -v --editable ./pkgs/sage-conf_conda + + and then run the last command again. + +- Verify that Sage has been installed:: + + $ sage -c 'print(version())' + SageMath version 10.2.beta4, Release Date: 2023-09-24 Note that ``make`` is not used at all. All dependencies (including all Python packages) are provided by conda. diff --git a/src/doc/en/installation/conf.py b/src/doc/en/installation/conf.py index 41f91e228d0..7e6174b0d90 100644 --- a/src/doc/en/installation/conf.py +++ b/src/doc/en/installation/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/installation', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/installation', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/installation', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/installation/index.rst b/src/doc/en/installation/index.rst index f88a92dc5c7..5e60d65ebb0 100644 --- a/src/doc/en/installation/index.rst +++ b/src/doc/en/installation/index.rst @@ -11,8 +11,7 @@ was made. More up-to-date information and details regarding supported platforms may have become available afterwards and can be found in the section "Availability and installation help" of the -`release tour `_ for each -SageMath release. +`release tour for each SageMath release `_. **Where would you like to run SageMath?** Pick one of the following sections. @@ -218,6 +217,7 @@ More information: binary conda source + meson launching troubles diff --git a/src/doc/en/installation/meson.rst b/src/doc/en/installation/meson.rst new file mode 100644 index 00000000000..b8e44bc12fc --- /dev/null +++ b/src/doc/en/installation/meson.rst @@ -0,0 +1,122 @@ +.. _build-source-meson: + +================================ +Building from source using Meson +================================ + +This is a short guide on how to build the Sage from source using Meson. + +Walkthrough +=========== + +Assume we're starting from a clean repo and a fully set up conda environment: + +.. CODE-BLOCK:: shell-session + + $ ./bootstrap-conda + $ mamba env create --file src/environment-dev-3.11.yml --name sage-dev + $ conda activate sage-dev + +Alternatively, install all build requirements as described in section +:ref:`section-prereqs`. In the likely case that you have to install some +dependencies manually, set the correct environment variables to point +to the installed libraries: + +.. CODE-BLOCK:: shell-session + + $ export C_INCLUDE_PATH=$C_INCLUDE_PATH:/your/path/to/include + $ export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/your/path/to/include + $ export LIBRARY_PATH=$LIBRARY_PATH:/your/path/to/lib + +.. NOTE:: + + If you have previously build Sage in-place, you first have to delete the + already compiled files, e.g. with ``shopt -s globstar`` followed by + ``rm src/**/*.so`` or ``for f in src/**/*.so ; do mv "$f" "$f.old"; done``. + Moreover, remove the old generated files with + ``find src/sage/ext/interpreters -type f ! -name 'meson.build' -delete``. + Also uninstall the 'old' sage packages with ``pip uninstall sage-conf sage-setup sagemath-standard``. + +To compile and install the project in editable install, just use: + +.. CODE-BLOCK:: shell-session + + $ pip install --no-build-isolation --editable . + +This will install Sage in the current Python environment. +In a Conda environment, the ``--no-build-isolation`` flag is necessary to +allow the build system to reuse the already installed build dependencies. +If you don't use Conda, you can omit this flag. + +You can then start Sage from the command line with ``./sage`` +or run the tests with ``./sage -t``. + +.. NOTE:: + + By using ``pip install --editable`` in the above steps, the Sage library + is installed in editable mode. This means that when you only edit source + files, there is no need to rebuild the library; it suffices to restart Sage. + Note that this even works when you edit Cython files, so you no longer need + to manually compile after editing Cython files. + +.. NOTE:: + + Note that ``make`` is not used at all, nor is ``configure``. + This means that any Sage-the-distribution commands such as ``sage -i`` + will not work. + +Background information +====================== + +Under the hood, pip invokes meson to configure and build the project. +We can also use meson directly as follows. + +To configure the project, we need to run the following command: + +.. CODE-BLOCK:: shell-session + + $ meson setup builddir --prefix=$PWD/build-install + +This will create a build directory ``builddir`` that will hold the build artifacts. +The ``--prefix`` option specifies the directory where the Sage will be installed. +To compile the project, run the following command: + +.. CODE-BLOCK:: shell-session + + $ meson compile -C builddir + +Installing is done with the following command: + +.. CODE-BLOCK:: shell-session + + $ meson install -C builddir + +This will then install in the directory specified by ``--prefix``, e.g. +``build-install/lib/python3.11/site-packages/sage``. +Usually, this directory is not on your Python path, so you have to use: + +.. CODE-BLOCK:: shell-session + + $ PYTHONPATH=build-install/lib/python3.11/site-packages ./sage + +Alternatively, we can still use pip to install: + +.. CODE-BLOCK:: shell-session + + $ pip install --no-build-isolation --config-settings=builddir=builddir --editable . + +.. tip:: + + Package maintainers may want to specify further build options or need + to install to a different directory than the install prefix. + Both are supported naturally by Meson: + + .. CODE-BLOCK:: shell-session + + $ meson setup builddir --prefix=/usr --libdir=... -Dcpp_args=... + $ meson compile -C builddir + $ DESTDIR=/path/to/staging/root meson install -C builddir + + See `Meson's quick guide `_ + and `Meson's install guide `_ + for more information. diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index f2e40ed3982..12b1483dfa2 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -370,6 +370,12 @@ does not raise an :class:`ImportError`, then it worked. Installation steps ------------------ +.. hint:: + + The following steps use the classical ``./configure && make`` build + process. The modern Meson build system is also supported, see + :ref:`build-source-meson`. + #. Follow the procedure in the file `README.md `_ in ``SAGE_ROOT``. diff --git a/src/doc/en/installation/troubles.rst b/src/doc/en/installation/troubles.rst index 4a7c6d5581b..22d4e4772da 100644 --- a/src/doc/en/installation/troubles.rst +++ b/src/doc/en/installation/troubles.rst @@ -8,8 +8,8 @@ the :ref:`sec-installation-from-sources` or use one of the alternatives proposed at the end of :ref:`installation-guide`. If you have any problems building or running Sage, please take a look -at the Installation FAQ in the `Sage Release Tour -`_ corresponding to the version +at the `release tour +`_ corresponding to the version that you are installing. It may offer version-specific installation help that has become available after the release was made and is therefore not covered by this manual. diff --git a/src/doc/en/prep/Calculus.rst b/src/doc/en/prep/Calculus.rst index c2f636be558..d33b3082040 100644 --- a/src/doc/en/prep/Calculus.rst +++ b/src/doc/en/prep/Calculus.rst @@ -316,8 +316,9 @@ help it look nicer in the browser? - 1/10*(sqrt(5) - 3)*log(2*x^2 + x*(sqrt(5) - 1) + 2)/(sqrt(5) - 1) + 1/5*log(x + 1) -Some integrals are a little tricky, of course. Sage tries hard to integrate using Maxima, Giac and Sympy:: +Some integrals are a little tricky, of course. Sage tries hard to integrate using Maxima, Sympy, and (optionally, if installed) Giac. The following can only be integrated by Giac:: + sage: # needs sage.libs.giac sage: integral(1/(1+x^10),x) ...1/20*(sqrt(5) + 1)*arctan((4*x + sqrt(-2*sqrt(5) + 10))/(sqrt(5) + 1)) + 1/20*(sqrt(5) + 1)*arctan((4*x - sqrt(-2*sqrt(5) + 10))/(sqrt(5) + 1)) diff --git a/src/doc/en/prep/Quickstarts/Statistics-and-Distributions.rst b/src/doc/en/prep/Quickstarts/Statistics-and-Distributions.rst index b5eb3d842a2..958a378f945 100644 --- a/src/doc/en/prep/Quickstarts/Statistics-and-Distributions.rst +++ b/src/doc/en/prep/Quickstarts/Statistics-and-Distributions.rst @@ -24,6 +24,8 @@ NumPy provides, for example, functions to compute the arithmetic mean and the standard deviation:: sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: np.mean([1, 2, 3, 5]) 2.75 diff --git a/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst b/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst index 3bc9308669b..c97efdecee4 100644 --- a/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst +++ b/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst @@ -384,11 +384,6 @@ Below, you can experiment with several of the plotting options. Basic 3D Plotting ----------------- -There are several mechanisms for viewing three\-dimensional plots in -Sage, but we will stick to the default option in the notebook interface, -which is via javascript applets from the program `Jmol/JSmol -`_ . - Plotting a 3D plot is similar to plotting a 2D plot, but we need to specify ranges for two variables instead of one. diff --git a/src/doc/en/prep/conf.py b/src/doc/en/prep/conf.py index 3dc26674397..03ff6ed7afc 100644 --- a/src/doc/en/prep/conf.py +++ b/src/doc/en/prep/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/prep', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/prep', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/prep', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/reference/algebras/lie_algebras.rst b/src/doc/en/reference/algebras/lie_algebras.rst index 03f66f4da88..4fefbe909f5 100644 --- a/src/doc/en/reference/algebras/lie_algebras.rst +++ b/src/doc/en/reference/algebras/lie_algebras.rst @@ -7,6 +7,8 @@ Lie Algebras sage/algebras/lie_algebras/abelian sage/algebras/lie_algebras/affine_lie_algebra sage/algebras/lie_algebras/bch + sage/algebras/lie_algebras/bgg_resolution + sage/algebras/lie_algebras/bgg_dual_module sage/algebras/lie_algebras/center_uea sage/algebras/lie_algebras/classical_lie_algebra sage/algebras/lie_algebras/examples diff --git a/src/doc/en/reference/conf.py b/src/doc/en/reference/conf.py index d9bb5da5acb..92b8a8d45b4 100644 --- a/src/doc/en/reference/conf.py +++ b/src/doc/en/reference/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release, latex_elements, exclude_patterns from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -25,9 +30,10 @@ ref_src = os.path.join(SAGE_DOC_SRC, 'en', 'reference') ref_out = os.path.join(SAGE_DOC, 'html', 'en', 'reference') -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/reference/index.rst'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/reference/index.rst'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/reference/index.rst'), }) # General information about the project. diff --git a/src/doc/en/reference/conf_sub.py b/src/doc/en/reference/conf_sub.py index 8346b13c9f4..c7adc1da994 100644 --- a/src/doc/en/reference/conf_sub.py +++ b/src/doc/en/reference/conf_sub.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release, exclude_patterns from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -42,9 +47,10 @@ title = name.capitalize() title = title.replace('`', '$') -# We use the directory's name to add a small edit button. +# We use the directory's name to add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, f'blob/develop/src/doc/en/reference/{name}', '{filename}'), + 'source_view_link': os.path.join(source_repository, f'blob/develop/src/doc/en/reference/{name}', '{filename}'), + 'source_edit_link': os.path.join(source_repository, f'edit/develop/src/doc/en/reference/{name}', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/reference/cryptography/index.rst b/src/doc/en/reference/cryptography/index.rst index 3c7997247be..8ab26473b5a 100644 --- a/src/doc/en/reference/cryptography/index.rst +++ b/src/doc/en/reference/cryptography/index.rst @@ -34,4 +34,8 @@ Cryptography sage/crypto/lattice sage/crypto/lwe + sage/crypto/key_exchange/catalog + sage/crypto/key_exchange/key_exchange_scheme + sage/crypto/key_exchange/diffie_hellman + .. include:: ../footer.txt diff --git a/src/doc/en/reference/graphs/index.rst b/src/doc/en/reference/graphs/index.rst index f681c083a08..34c5f134839 100644 --- a/src/doc/en/reference/graphs/index.rst +++ b/src/doc/en/reference/graphs/index.rst @@ -84,6 +84,7 @@ Libraries of algorithms sage/graphs/spanning_tree sage/graphs/pq_trees sage/graphs/trees + sage/graphs/matching sage/graphs/matchpoly sage/graphs/genus sage/graphs/lovasz_theta @@ -98,6 +99,7 @@ Libraries of algorithms sage/graphs/graph_decompositions/bandwidth sage/graphs/graph_decompositions/cutwidth sage/graphs/graph_decompositions/graph_products + sage/graphs/graph_decompositions/slice_decomposition sage/graphs/graph_decompositions/modular_decomposition sage/graphs/graph_decompositions/clique_separators sage/graphs/convexity_properties diff --git a/src/doc/en/reference/knots/index.rst b/src/doc/en/reference/knots/index.rst index ed42964e5a5..999a75a97dc 100644 --- a/src/doc/en/reference/knots/index.rst +++ b/src/doc/en/reference/knots/index.rst @@ -7,5 +7,6 @@ Knot Theory sage/knots/knot sage/knots/link sage/knots/knotinfo + sage/knots/free_knotinfo_monoid .. include:: ../footer.txt diff --git a/src/doc/en/reference/polynomial_rings/index.rst b/src/doc/en/reference/polynomial_rings/index.rst index 0035c50021f..a3b32b51ce7 100644 --- a/src/doc/en/reference/polynomial_rings/index.rst +++ b/src/doc/en/reference/polynomial_rings/index.rst @@ -62,6 +62,16 @@ Infinite Polynomial Rings sage/rings/polynomial/symmetric_ideal sage/rings/polynomial/symmetric_reduction +Tropical Polynomials +-------------------- + +.. toctree:: + :maxdepth: 1 + + sage/rings/semirings/tropical_polynomial + sage/rings/semirings/tropical_mpolynomial + sage/rings/semirings/tropical_variety + Boolean Polynomials ------------------- diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index b7725c7848b..6bc9946a442 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -857,6 +857,9 @@ REFERENCES: .. [BrHu2019] Petter Brändén, June Huh. *Lorentzian polynomials*. Ann. Math. (2) 192, No. 3, 821-891 (2020). :arxiv:`1902.03719`, :doi:`10.4007/annals.2020.192.3.4`. + +.. [Bru2014] Erwan Brugalle and Kristin Shaw. *A bit of tropical geometry*. + Amer. Math. Monthly, 121(7):563-589, 2014. .. [BHNR2004] \S. Brlek, S. Hamel, M. Nivat, C. Reutenauer, On the Palindromic Complexity of Infinite Words, @@ -1323,6 +1326,9 @@ REFERENCES: no. 1 (2003): 97-111, http://www.moi.math.bas.bg/moiuser/~iliya/pdf_site/gf5srev.pdf. +.. [BS2007] \R. Bröker and P. Stevenhagen. *Constructing elliptic curves of + prime order*. [math.NT] (2007), :arXiv:`0712.2022`. + .. [BS2010] \P. Baseilhac and K. Shigechi. *A new current algebra and the reflection equation*. Lett. Math. Phys. **92** (2010), pp. 47-65. :arxiv:`0906.1482`. @@ -1437,6 +1443,11 @@ REFERENCES: for closed Riemannian manifolds*, Ann. of Math. (2) 45 (1944), 747–752. +.. [CHNP2020] Kieran Clancy, Michael Haythorpe, Alex Newcombe and Ed Pegg Jr, + *There Are No Cubic Graphs on 26 Vertices with Crossing Number 10 + or 11*, Graphs and Combinatorics 36, pages: 1713 -- 1721, (2020), + :doi:`10.1007/s00373-020-02204-6`. + .. [CP2023] \M. Cati and D.V. Pasechnik. *Implementing Hadamard Matrices in SageMath*. Preprint, :arxiv:`2306.16812`, (2023). @@ -1658,6 +1669,11 @@ REFERENCES: .. [CIA] CIA Factbook 09 https://www.cia.gov/library/publications/the-world-factbook/ +.. [CJ2022] \M. Chang, C. Jefferson, *Disjoint direct product decomposition + of permutation groups*, Journal of Symbolic Computation (2022), + Volume 108, pages 1-16. :doi:`10.1016/j.jsc.2021.04.003`. + Preprint: :arxiv:`2004.11618v3`. + .. [CK1986] \R. Calderbank, W.M. Kantor, *The geometry of two-weight codes*, Bull. London Math. Soc. 18(1986) 97-122. @@ -1689,6 +1705,10 @@ REFERENCES: bi-matrix games*. http://vknight.org/unpeudemath/code/2015/06/25/on_testing_degeneracy_of_games/ (2015) +.. [CKWL2019] Marcelo H. de Carvalho, Nishad Kothari, Xiumei Wang and Yixun + Linc. *Birkhoff-von Neumann graphs that are PM-compact*. 2019. + :doi:`10.48550/arXiv.1807.07339`. + .. [CL1996] Chartrand, G. and Lesniak, L.: *Graphs and Digraphs*. Chapman and Hall/CRC, 1996. @@ -1705,12 +1725,20 @@ REFERENCES: Yokonuma-Hecke algebras and the HOMFLYPT polynomial*. (2015) :arxiv:`1204.1871v4`. +.. [CL2023] Xavier Caruso and Antoine Leudière. + *Algorithms for computing norms and characteristic polynomials on general Drinfeld modules*, (2023) :arxiv:`2307.02879`. + .. [Cle1872] Alfred Clebsch, *Theorie der binären algebraischen Formen*, Teubner, 1872. .. [CLG1997] Frank Celler and C. R. Leedham-Green, *Calculating the Order of an Invertible Matrix*, 1997 +.. [CLM2006] Marcelo H. de Carvalho, Cláudio L. Lucchesi and U.S.R. Murty, + *How to build a brick*, Discrete Mathematics, Volume 306, + Issues 19--20, Pages 2383--2410,ISSN 0012--365X, (2006), + :doi:`10.1016/j.disc.2005.12.032`. + .. [CLRS2001] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein, *Section 22.4: Topological sort*, Introduction to Algorithms (2nd ed.), MIT Press and @@ -1823,8 +1851,8 @@ REFERENCES: With an appendix by Ernst Kani. Canad. Math. Bull. 48 (2005), no. 1, 16--31. -.. [Colb2004] C.J. Colbourn. “Combinatorial aspects of covering arrays”. - Matematiche (Catania) 59 (2004), pp. 125–172. +.. [Colb2004] C.J. Colbourn. *Combinatorial aspects of covering arrays*. + Matematiche (Catania) 59 (2004), pp. 125-172. .. [Col2004] Pierre Colmez, Invariant `\mathcal{L}` et derivees de valeurs propres de Frobenius, preprint, 2004. @@ -1971,6 +1999,10 @@ REFERENCES: .. [CS2018] Craig Costello and Benjamin Smith: Montgomery curves and their arithmetic. J. Cryptogr. Eng. 8 (2018), 227-240. +.. [CS2022] \Logan Crew, and Sophie Spirkl. *Modular relations of the Tutte symmetric function*, + Journal of Combinatorial Theory, Series A, Volume 187, 2022, 105572, + :doi:`10.1016/j.jcta.2021.105572.` + .. [CST2010] Tullio Ceccherini-Silberstein, Fabio Scarabotti, Filippo Tolli. *Representation Theory of the Symmetric Groups: The @@ -2607,6 +2639,15 @@ REFERENCES: Wehler K3 Surfaces over finite fields*. New Zealand Journal of Mathematics 45 (2015), 19–31. +.. [FiLi2001] Ilse Fischer and Charles H.C. Little, *A Characterisation of + Pfaffian Near Bipartite Graphs*, Journal of Combinatorial Theory, + Series B, vol. 82, issue 2, (2001), pages: 175 -- 222, ISSN: + 0095 -- 8956, :doi:`10.1006/jctb.2000.2025`. + +.. [Fil2017] Ivana Filipan, *An Invitation to Combinatorial Tropical Geometry*. + Conference: 1st Croatian Combinatorial Days. 2017. + :doi:`10.5592/CO/CCD.2016.05`. + .. [FIV2012] \H. Fournier, A. Ismail, and A. Vigneron. *Computing the Gromov hyperbolicity of a discrete metric space*. 2012. :arxiv:`1210.3323`. @@ -2799,6 +2840,10 @@ REFERENCES: .. [Gek1991] \E.-U. Gekeler. On finite Drinfeld modules. Journal of algebra, 1(141):187–203, 1991. +.. [Gek2008] \E.-U. Gekeler. Frobenius Distributions of Drinfeld Modules over + Finite Fields. Transactions of the American Mathematical Society, + Volume 360 (2008), no. 4. + .. [Gek2017] \E.-U. Gekeler. On Drinfeld modular forms of higher rank. Journal de théorie des nombres de Bordeaux, Volume 29 (2017) no. 3, pp. 875-902. :doi:`10.5802/jtnb.1005` @@ -3003,7 +3048,10 @@ REFERENCES: Texts in Mathematics, Springer, 2001. .. [Gre2006] \R. M. Green, *Star reducible Coxeter groups*, Glasgow - Mathematical Journal, Volume 48, Issue 3, pp. 583-609. + Mathematical Journal, Volume 48, Issue 3, pp. 583-609. + +.. [Ger2008] Gert-Martin Greuel and Gerhard Pfister. A Singular introduction + to commutative algebra. Vol. 348. Berlin: Springer, 2008. .. [Gri2021] \O. Gritsenko, *On strongly regular graph with parameters (65; 32; 15; 16)*, :arxiv:`2102.05432`. @@ -3486,6 +3534,10 @@ REFERENCES: Trans. Am. Math. Soc. 375, No. 6, 4411-4427 (2022). :arxiv:`1906.09633`, :doi:`10.1090/tran/8606`. +.. [Humphreys08] James E. Humphreys. *Representations of Semisimple Lie + Algebras in the BGG Category* `\mathcal{O}`. + Graduate Studies in Mathematics. Amer. Math. Soc., 2008. + .. [Hutz2007] \B. Hutz. Arithmetic Dynamics on Varieties of dimension greater than one. PhD Thesis, Brown University 2007 @@ -3769,6 +3821,10 @@ REFERENCES: .. [Kas2018] András Kaszanyitzky. *The GraftalLace Cellular Automata*. Preprint, :arxiv:`1805.11532`. +.. [Kat1973] G. Katona. *Two applications (for search theory and truth + functions) of Sperner type theorems*. Periodica Math., + 3:19-26, 1973. + .. [Kat1991] Nicholas M. Katz, *Exponential sums and differential equations*, Princeton University Press, Princeton NJ, 1991. @@ -3837,6 +3893,10 @@ REFERENCES: \M. Grötschel, \L Lovász, *Handbook of combinatorics*, Vol. 1, Chapter 18, 1995 +.. [KK2003] T. Kivinen and M. Kojo. *More Modular Exponential (MODP) + Diffie-Hellman groups for Internet Key Exchange (IKE)*, in RFC 3526. + Available at https://www.rfc-editor.org/rfc/rfc3526 + .. [KKMMNN1992] S-J. Kang, M. Kashiwara, K. C. Misra, T. Miwa, T. Nakashima, and A. Nakayashiki. *Affine crystals and vertex models*. Int. J. Mod. Phys. A, **7** (suppl. 1A), (1992) pp. 449-484. @@ -3906,6 +3966,10 @@ REFERENCES: 47:95-104, 1997. :doi:`10.1023/A:1022444205860` +.. [KM2015] Nishad Kothari and U.S.R. Murty. *K4-free and C6¯-free Planar + Matching Covered Graphs.* Journal of Graph Theory. 82. (2015) + :doi:`10.1002/jgt.21882`. + .. [KMAUTOM2000] Masayuki Kanda, Shiho Moriai, Kazumaro Aoki, Hiroki Ueda, Youichi Takashima, Kazuo Ohta, and Tsutomu Matsumoto, *E2 - a new 128-bit block cipher*; in IEICE Transactions on @@ -4073,6 +4137,9 @@ REFERENCES: .. [KS] Sheldon Katz and Stein Arild Stromme, "Schubert", A Maple package for intersection theory and enumerative geometry. +.. [KS1973] D. Kleitman and J. Spencer. *Families of k-independent sets*. + Discrete Math, 6:255-262, 1973. + .. [KS1998] Maximilian Kreuzer and Harald Skarke, *Classification of Reflexive Polyhedra in Three Dimensions*, :arxiv:`hep-th/9805190` @@ -4387,6 +4454,10 @@ REFERENCES: .. [LM2018] \A. Lauve, M. Mastnak. *Bialgebra coverings and transfer of structure*. Preprint, :arxiv:`1803.02691`. +.. [LM2024] C.L. Lucchesi, U.S.R. Murty. *Perfect Matchings: A Theory of + Matching Covered Graphs*. Algorithms and Computation in Mathematics. + Springer Cham, 1st edition, 2024, :doi:`10.1007/978-3-031-47504-7`. + .. [LMR2010] \N. Linial, R. Meshulam and M. Rosenthal, "Sum complexes -- a new family of hypertrees", Discrete & Computational Geometry, 2010, Volume 44, Number 3, Pages 622-636 @@ -4440,6 +4511,11 @@ REFERENCES: IEEE Trans. Inf. Th. 25(1979), 1-7. :doi:`10.1109/TIT.1979.1055985`. +.. [Lov1983] László Lovász, + *Ear-decompositions of matching-covered graphs*, + Combinatorica 3, 105--117 (1983) + :doi:`10.1007/BF02579346`. + .. [LP2007] \G. Leander and A. Poschmann, *On the Classification of 4 Bit S-boxes*; in WAIFI, (2007), pp. 159-176. @@ -4594,6 +4670,12 @@ REFERENCES: measures*. Publications Mathématiques de l'Institut des Hautes Études Scientifiques 98(1) (2003), pp. 167-212. +.. [LZ2001] Dingjun Lou and Ning Zhong. *A highly efficient algorithm to + determine bicritical graphs.* In: Wang, J. (eds) Computing and + Combinatorics. Lecture Notes in Computer Science, vol 2108, + pages 349--356. Springer, Berlin, Heidelberg, 2001, + :doi:`10.1007/3-540-44679-6_38`. + .. [LZ2004] S. Lando and A. Zvonkine, "Graphs on surfaces and their applications", Springer-Verlag, 2004. @@ -5120,6 +5202,13 @@ REFERENCES: :doi:`10.1007/s00453-006-1225-y`, http://www.cs.uoi.gr/~stavros/C-Papers/C-2004-SODA.pdf +.. [NT2007] Serguei Norine and Robin Thomas. *Minimally Non-Pfaffian Graphs*. + Combinatorica, vol. 27, no. 5, pages: 587 -- 600, Springer. 2007. + :doi:`10.1016/j.jctb.2007.12.005`. + +.. [Nur2004] K. Nurmela. *Upper bounds for covering arrays by tabu search*. + Discrete Applied Math., 138 (2004), 143-152. + .. [NWS2002] Newman, M.E.J., Watts, D.J. and Strogatz, S.H. *Random graph models of social networks*. Proc. Nat. Acad. Sci. USA 99:1 (2002), 2566-2572. :doi:`10.1073/pnas.012582999` @@ -5343,6 +5432,11 @@ REFERENCES: Mathematical Physics, Analysis and Geometry 1, 171-191 (1998). :doi:`10.1023/A:1009724323513` +.. [PP2010] \C. Paar and J. Pelzl. + *Understanding Cryptography: A Textbook for Students and Practitioners*. + Springer Berlin, Heidelberg, 2010. + :doi:`10.1007/978-3-642-04101-3` + .. [PPW2013] \D. Perkinson, J. Perlman, and J. Wilmes. *Primer for the algebraic geometry of sandpiles*. Tropical and Non-Archimedean @@ -5623,6 +5717,11 @@ REFERENCES: .. [RS2012] G. Rudolph and M. Schmidt, "Differential Geometry and Mathematical Physics. Part I. Manifolds, Lie Groups and Hamiltonian Systems", Springer, 2012. +.. [RST2019] Neil Robertson, Paul Seymour and Robin Thomas, *Excluded minors in + cubic graphs*, Journal of Combinatorial Theory, Series B, vol. 138, + (2019), pages: 219 -- 285, ISSN: 0095 -- 8956, + :doi:`10.1016/j.jctb.2019.02.002`. + .. [RSW2011] Victor Reiner, Franco Saliola, Volkmar Welker. *Spectra of Symmetrized Shuffling Operators*. :arxiv:`1102.2460v2`. @@ -5891,8 +5990,8 @@ REFERENCES: .. [SloaHada] \N.J.A. Sloane's Library of Hadamard Matrices, at https://neilsloane.com/hadamard/ -.. [SMC2006] \G.B. Sherwood, S.S Martirosyan, and C.J. Colbourn, "Covering - arrays of higher strength from permutation vectors". J. Combin. +.. [SMC2006] \G.B. Sherwood, S.S Martirosyan, and C.J. Colbourn, *Covering + arrays of higher strength from permutation vectors*. J. Combin. Designs, 14 (2006) pp. 202-213. .. [SMMK2013] \T. Suzaki, K. Minematsu, S. Morioka, and E. Kobayashi, @@ -6056,6 +6155,11 @@ REFERENCES: of the chromatic polynomial of a graph*, Adv. Math., ***111*** no.1 (1995), 166-194. :doi:`10.1006/aima.1995.1020`. +.. [Sta1998] \R. P. Stanley, *Graph colorings and related symmetric functions: + ideas and applications A description of results, interesting applications, + & notable open problems*, Discrete Mathematics, 193, no.1-3, (1998), + 267-286. :doi:`10.1016/S0012-365X(98)00146-0`. + .. [Sta2002] Richard P. Stanley, *The rank and minimal border strip decompositions of a skew partition*, @@ -6296,6 +6400,11 @@ REFERENCES: Discrete Mathematics, Volume 63, Issues 2-3, 1987, Pages 279-295. +.. [SYKU2010] Toshiki Saitoh, Katsuhisa Yamanaka, Masashi Kiyomi, Ryuhei Uehara: + Random Generation and Enumeration of Proper Interval Graphs. + IEICE Trans. Inf. Syst. 93-D(7): 1816-1823 (2010) + :doi:`10.1587/transinf.E93.D.1816` + .. [SYYTIYTT2002] \T. Shimoyama, H. Yanami, K. Yokoyama, M. Takenaka, K. Itoh, \J. Yajima, N. Torii, and H. Tanaka, *The block cipher SC2000*; in FSE, (2001), pp. 312-327. @@ -6358,7 +6467,7 @@ REFERENCES: .. [TCHP2008] Marc Tedder, Derek Corneil, Michel Habib and Christophe Paul, *Simple, linear-time modular decomposition*, 2008. - :arxiv:`0710.3901`. + :arxiv:`0710.3901v3`. .. [Tee1997] Tee, Garry J. "Continuous branches of inverses of the 12 Jacobi elliptic functions for real @@ -6416,6 +6525,10 @@ REFERENCES: .. [TTWL2009] Trebst, Troyer, Wang and Ludwig, A short introduction to Fibonacci anyon models, :arxiv:`0902.3275`. +.. [Tut1947] W.T. Tutte. *The factorization of linear graphs.* Journal of the + London Mathematical Society, vol. s1-22, issue 2, pages 107--111, + April 1947. :doi:`10.1112/jlms/s1-22.2.107`. + .. [Tur1974] \R. J. Turyn *Hadamard matrices, Baumert-Hall units, four-symbol sequences, pulse compression, and surface wave encodings*. Journal of Combinatorial Theory, Series A 16.3 (1974), pp 313–333. @@ -6590,8 +6703,8 @@ REFERENCES: .. [Wat2010] Watkins, David S. Fundamentals of Matrix Computations, Third Edition. Wiley, Hoboken, New Jersey, 2010. -.. [WC2007] \R.A. Walker II, and C.J. Colbourn, "Perfect Hash Families: - Constructions and Existence". J. Math. Crypt. 1 (2007), +.. [WC2007] \R.A. Walker II, and C.J. Colbourn, *Perfect Hash Families: + Constructions and Existence*. J. Math. Crypt. 1 (2007), pp.125-150 .. [Web2007] James Webb. *Game theory: decisions, interaction and diff --git a/src/doc/en/reference/spkg/index.rst b/src/doc/en/reference/spkg/index.rst new file mode 100644 index 00000000000..e9ba934a540 --- /dev/null +++ b/src/doc/en/reference/spkg/index.rst @@ -0,0 +1,87 @@ +.. _spkg: + +Packages and Features +===================== + +Standard Packages +----------------- + +The Sage distribution includes most programs and libraries on which +Sage depends. It installs them automatically if it does not find +equivalent system packages. + +.. include:: index_standard.rst + + +Optional Packages +----------------- + +For additional functionality, you can install some of the following +optional packages. + +.. include:: index_optional.rst + + +Features +-------- + +.. toctree:: + :maxdepth: 1 + + sage/features + sage/features/join_feature + sage/features/all + sage/features/sagemath + sage/features/pkg_systems + sage/features/bliss + sage/features/csdp + sage/features/databases + sage/features/dvipng + sage/features/ffmpeg + sage/features/four_ti_2 + sage/features/gap + sage/features/graph_generators + sage/features/graphviz + sage/features/imagemagick + sage/features/interfaces + sage/features/internet + sage/features/kenzo + sage/features/latex + sage/features/latte + sage/features/lrs + sage/features/mcqd + sage/features/meataxe + sage/features/mip_backends + sage/features/normaliz + sage/features/pandoc + sage/features/pdf2svg + sage/features/polymake + sage/features/rubiks + sage/features/tdlib + sage/features/topcom + + +Distribution Packages of the Sage Library +----------------------------------------- + +.. include:: index_sagemath.rst + + +Experimental Packages +--------------------- + +Some packages that provide additional functionality are marked as +"experimental". Developers are needed in order to improve the +integration of these packages into the Sage distribution. + +.. include:: index_experimental.rst + + +All External Packages +--------------------- + +.. toctree:: + :maxdepth: 1 + + index_alph + diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 516ac714e13..ad5a01ea1a6 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -115,15 +115,13 @@ This base class provides a lot more methods than a general parent:: '_coerce_impl', '_default_category', '_gens', - '_ideal_monoid', '_latex_names', '_list', '_one_element', '_pseudo_fraction_field', - '_unit_ideal', '_zero_element', - '_zero_ideal', 'algebraic_closure', + 'an_embedding', 'base_extend', 'divides', 'epsilon', @@ -132,12 +130,10 @@ This base class provides a lot more methods than a general parent:: 'gen', 'gens', 'ideal', - 'ideal_monoid', 'integral_closure', 'is_commutative', 'is_field', 'is_integrally_closed', - 'is_noetherian', 'is_prime_field', 'is_subring', 'krull_dimension', @@ -146,11 +142,8 @@ This base class provides a lot more methods than a general parent:: 'one', 'order', 'prime_subfield', - 'principal_ideal', 'random_element', - 'unit_ideal', 'zero', - 'zero_ideal', 'zeta', 'zeta_order'] diff --git a/src/doc/en/thematic_tutorials/conf.py b/src/doc/en/thematic_tutorials/conf.py index 19f9a3da5af..581a8e89fc6 100644 --- a/src/doc/en/thematic_tutorials/conf.py +++ b/src/doc/en/thematic_tutorials/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -22,9 +27,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/thematic_tutorials', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/thematic_tutorials', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/thematic_tutorials', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py index b8eef385e4f..9de7aa68adb 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_orders.rst b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_orders.rst index 1c03f15d526..47b8e5f7fc6 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_orders.rst +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_orders.rst @@ -99,7 +99,6 @@ with ideals in non-maximal orders. sage: K. = NumberField(x^3 + 2) sage: R = K.order(3*a) sage: R.ideal(5) - doctest:warning ... FutureWarning: ... Ideal (5, 15*a, 45*a^2) of Order generated by 3*a in Number Field in a with defining polynomial x^3 + 2 sage: R.ideal(5).factor() Traceback (most recent call last): diff --git a/src/doc/en/thematic_tutorials/lie/lie_basics.rst b/src/doc/en/thematic_tutorials/lie/lie_basics.rst index e8be4590c3f..190ef6515c0 100644 --- a/src/doc/en/thematic_tutorials/lie/lie_basics.rst +++ b/src/doc/en/thematic_tutorials/lie/lie_basics.rst @@ -789,7 +789,7 @@ and for describing the affine Weyl group. In particular, the hyperplane for the reflection `r_0`, used in generating the affine Weyl group, is translated off the origin (so it becomes an affine hyperplane). Now the root system is not described as linear transformations -on an Euclidean space, but instead by *affine* transformations. Thus the +on a Euclidean space, but instead by *affine* transformations. Thus the dominant chamber has finite volume and tiles the Eucledian space. Moreover, each such tile corresponds to a unique element in the affine Weyl group. @@ -848,7 +848,7 @@ the twisting procedure defined in [Kac]_. It has the following properties: Further Generalizations ----------------------- -If a root system (on an Euclidean space) has only the angles +If a root system (on a Euclidean space) has only the angles `\pi/2, 2\pi/3, 3\pi/4, 5\pi/6` between its roots, then we call the root system *crystallographic* (on :wikipedia:`Root_system`, this condition is called integrality since for any two roots we have diff --git a/src/doc/en/thematic_tutorials/numerical_sage/conf.py b/src/doc/en/thematic_tutorials/numerical_sage/conf.py index 5772289f6fa..c8e220f8f99 100644 --- a/src/doc/en/thematic_tutorials/numerical_sage/conf.py +++ b/src/doc/en/thematic_tutorials/numerical_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the diff --git a/src/doc/en/thematic_tutorials/numerical_sage/numpy.rst b/src/doc/en/thematic_tutorials/numerical_sage/numpy.rst index dbc2de71d42..925e5312882 100644 --- a/src/doc/en/thematic_tutorials/numerical_sage/numpy.rst +++ b/src/doc/en/thematic_tutorials/numerical_sage/numpy.rst @@ -7,6 +7,8 @@ import it. :: sage: import numpy + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") # to ensure numpy 2.0 compatibility The basic object of computation in NumPy is an array. It is simple to create an array. diff --git a/src/doc/en/thematic_tutorials/sandpile.rst b/src/doc/en/thematic_tutorials/sandpile.rst index 22f48a2f560..417f10e4dbd 100644 --- a/src/doc/en/thematic_tutorials/sandpile.rst +++ b/src/doc/en/thematic_tutorials/sandpile.rst @@ -1024,9 +1024,7 @@ INPUT: - ``k`` -- integer -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -1046,9 +1044,7 @@ INPUT: - ``k`` -- integer -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -1068,9 +1064,7 @@ INPUT: - ``multivariable`` -- (default: ``True``) boolean -OUTPUT: - -polynomial +OUTPUT: polynomial EXAMPLES:: @@ -1108,9 +1102,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -Betti numbers for the sandpile +OUTPUT: Betti numbers for the sandpile EXAMPLES:: @@ -1229,9 +1221,7 @@ EXAMPLES:: A script for the minimal burning configuration. -OUTPUT: - -dict +OUTPUT: dict EXAMPLES:: @@ -1284,9 +1274,7 @@ EXAMPLES:: The canonical divisor. This is the divisor with `\deg(v)-2` grains of sand on each vertex (not counting loops). Only for undirected graphs. -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -1309,9 +1297,7 @@ EXAMPLES:: A dictionary of dictionaries representing a directed graph. -OUTPUT: - -dict +OUTPUT: dict EXAMPLES:: @@ -1332,9 +1318,7 @@ EXAMPLES:: The genus: (# non-loop edges) - (# vertices) + 1. Only defined for undirected graphs. -OUTPUT: - -integer +OUTPUT: integer EXAMPLES:: @@ -1352,9 +1336,7 @@ EXAMPLES:: A Groebner basis for the homogeneous toppling ideal. It is computed with respect to the standard sandpile ordering (see ``ring``). -OUTPUT: - -Groebner basis +OUTPUT: Groebner basis EXAMPLES:: @@ -1402,9 +1384,7 @@ EXAMPLES:: The size of the sandpile group. -OUTPUT: - -integer +OUTPUT: integer EXAMPLES:: @@ -1422,9 +1402,7 @@ The number of superstable configurations in each degree. Equivalently, this is the list of first differences of the Hilbert function of the (homogeneous) toppling ideal. -OUTPUT: - -list of nonnegative integers +OUTPUT: list of nonnegative integers EXAMPLES:: @@ -1447,9 +1425,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -printed string +OUTPUT: printed string EXAMPLES:: @@ -1476,9 +1452,7 @@ EXAMPLES:: The Hilbert function of the homogeneous toppling ideal. -OUTPUT: - -list of nonnegative integers +OUTPUT: list of nonnegative integers EXAMPLES:: @@ -1501,9 +1475,7 @@ INPUT: - ``gens`` -- (default: ``False``) boolean -OUTPUT: - -ideal or, optionally, the generators of an ideal +OUTPUT: ideal or, optionally, the generators of an ideal EXAMPLES:: @@ -1555,9 +1527,7 @@ INPUT: - ``v`` -- (optional) vertex name -OUTPUT: - -integer or dict +OUTPUT: integer or dict EXAMPLES:: @@ -1575,9 +1545,7 @@ EXAMPLES:: The invariant factors of the sandpile group. -OUTPUT: - -list of integers +OUTPUT: list of integers EXAMPLES:: @@ -1594,9 +1562,7 @@ EXAMPLES:: Is the underlying graph undirected? ``True`` if `(u,v)` is and edge if and only if `(v,u)` is an edge, each edge with the same weight. -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -1667,9 +1633,7 @@ group is isomorphic to the direct sum of the cyclic group of order The Laplacian matrix of the graph. Its *rows* encode the vertex firing rules. -OUTPUT: - -matrix +OUTPUT: matrix EXAMPLES:: @@ -1824,9 +1788,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -tuple of SandpileConfig +OUTPUT: tuple of SandpileConfig EXAMPLES:: @@ -1860,9 +1822,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -list of SandpileConfig +OUTPUT: list of SandpileConfig EXAMPLES:: @@ -1889,9 +1849,7 @@ EXAMPLES:: The nonsink vertices. -OUTPUT: - -list of vertices +OUTPUT: list of vertices EXAMPLES:: @@ -1951,9 +1909,7 @@ INPUT: - ``v`` - (optional) vertex name -OUTPUT: - -integer or dict +OUTPUT: integer or dict EXAMPLES:: @@ -2001,9 +1957,7 @@ EXAMPLES:: Generators for the multiplicative group of zeros of the sandpile ideal. -OUTPUT: - -list of complex numbers +OUTPUT: list of complex numbers EXAMPLES: @@ -2025,9 +1979,7 @@ single generator for the group of solutions. The postulation number of the toppling ideal. This is the largest weight of a superstable configuration of the graph. -OUTPUT: - -nonnegative integer +OUTPUT: nonnegative integer EXAMPLES:: @@ -2048,9 +2000,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -list of recurrent configurations +OUTPUT: list of recurrent configurations EXAMPLES:: @@ -2086,9 +2036,7 @@ EXAMPLES:: The reduced Laplacian matrix of the graph. -OUTPUT: - -matrix +OUTPUT: matrix EXAMPLES:: @@ -2119,9 +2067,7 @@ A copy of the sandpile with vertex names permuted. After reordering, vertex `u` comes before vertex `v` in the list of vertices if `u` is closer to the sink. -OUTPUT: - -Sandpile +OUTPUT: Sandpile EXAMPLES:: @@ -2149,9 +2095,7 @@ INPUT: - ``verbose`` -- (default: ``False``) boolean -OUTPUT: - -free resolution of the toppling ideal +OUTPUT: free resolution of the toppling ideal EXAMPLES:: @@ -2186,9 +2130,7 @@ EXAMPLES:: The ring containing the homogeneous toppling ideal. -OUTPUT: - -ring +OUTPUT: ring EXAMPLES:: @@ -2248,9 +2190,7 @@ EXAMPLES:: The sink vertex. -OUTPUT: - -sink vertex +OUTPUT: sink vertex EXAMPLES:: @@ -2274,9 +2214,7 @@ matrices `D, U, V` such that `ULV = D` where `L` is the transpose of the Laplacian, `D` is diagonal, and `U` and `V` are invertible over the integers. -OUTPUT: - -list of integer matrices +OUTPUT: list of integer matrices EXAMPLES:: @@ -2299,9 +2237,7 @@ EXAMPLES:: Approximations of the complex affine zeros of the sandpile ideal. -OUTPUT: - -list of complex numbers +OUTPUT: list of complex numbers EXAMPLES:: @@ -2346,9 +2282,7 @@ INPUT: - ``smax`` -- (optional) SandpileConfig or list representing a SandpileConfig -OUTPUT: - -generator for all stable configurations +OUTPUT: generator for all stable configurations EXAMPLES:: @@ -2370,9 +2304,7 @@ EXAMPLES:: The stationary density of the sandpile. -OUTPUT: - -rational number +OUTPUT: rational number EXAMPLES:: @@ -2407,9 +2339,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -list of SandpileConfig +OUTPUT: list of SandpileConfig EXAMPLES:: @@ -2449,9 +2379,7 @@ INPUT: - ``orbits`` - list of lists partitioning the vertices -OUTPUT: - -list of recurrent configurations +OUTPUT: list of recurrent configurations EXAMPLES:: @@ -2486,9 +2414,7 @@ EXAMPLES:: The Tutte polynomial of the underlying graph. Only defined for undirected sandpile graphs. -OUTPUT: - -polynomial +OUTPUT: polynomial EXAMPLES:: @@ -2508,9 +2434,7 @@ EXAMPLES:: The unsaturated, homogeneous toppling ideal. -OUTPUT: - -ideal +OUTPUT: ideal EXAMPLES:: @@ -2528,9 +2452,7 @@ EXAMPLES:: The version number of Sage Sandpiles. -OUTPUT: - -string +OUTPUT: string EXAMPLES:: @@ -2548,9 +2470,7 @@ EXAMPLES:: The all-zero configuration. -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -2566,9 +2486,7 @@ EXAMPLES:: The all-zero divisor. -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -2625,13 +2543,13 @@ SandpileConfig - :ref:`help ` --- List of SandpileConfig methods. -- :ref:`is_recurrent ` --- Is the configuration recurrent? +- :ref:`is_recurrent ` --- Return whether the configuration is recurrent. -- :ref:`is_stable ` --- Is the configuration stable? +- :ref:`is_stable ` --- Return whether the configuration is stable. -- :ref:`is_superstable ` --- Is the configuration superstable? +- :ref:`is_superstable ` --- Return whether the configuration is superstable. -- :ref:`is_symmetric ` --- Is the configuration symmetric? +- :ref:`is_symmetric ` --- Return whether the configuration is symmetric. - :ref:`order ` --- The order of the equivalent recurrent element. @@ -2663,9 +2581,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -2687,9 +2603,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -2717,9 +2631,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -2751,9 +2663,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -2775,9 +2685,7 @@ SandpileConfig The stabilized configuration. - OUTPUT: - - ``SandpileConfig`` + OUTPUT: ``SandpileConfig`` EXAMPLES:: @@ -2799,9 +2707,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -2833,9 +2739,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -2872,9 +2776,7 @@ SandpileConfig - ``other`` -- SandpileConfig or Integer - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -2910,9 +2812,7 @@ SandpileConfig - ``k`` -- SandpileConfig - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -2937,9 +2837,7 @@ SandpileConfig The additive inverse of the configuration. - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -2960,9 +2858,7 @@ SandpileConfig - ``other`` -- SandpileConfig - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -2986,9 +2882,7 @@ INPUT: - ``distrib`` -- (optional) list of nonnegative numbers summing to 1 (representing a prob. dist.) -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -3050,9 +2944,7 @@ INPUT: - ``v`` -- vertex -OUTPUT: - -integer +OUTPUT: integer EXAMPLES:: @@ -3081,9 +2973,7 @@ REFERENCES: The degree of the configuration. -OUTPUT: - -integer +OUTPUT: integer EXAMPLES:: @@ -3100,9 +2990,7 @@ EXAMPLES:: The difference with the maximal stable configuration. -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -3128,9 +3016,7 @@ INPUT: - ``with_firing_vector`` -- (default: ``False``) boolean -OUTPUT: - -SandpileConfig or [SandpileConfig, firing_vector] +OUTPUT: SandpileConfig or [SandpileConfig, firing_vector] EXAMPLES:: @@ -3165,9 +3051,7 @@ INPUT: - ``with_firing_vector`` -- (default: ``False``) boolean -OUTPUT: - -SandpileConfig or [SandpileConfig, firing_vector] +OUTPUT: SandpileConfig or [SandpileConfig, firing_vector] EXAMPLES:: @@ -3202,9 +3086,7 @@ INPUT: - ``sigma`` -- SandpileConfig or (list or dict representing a SandpileConfig) -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -3225,9 +3107,7 @@ EXAMPLES:: Fire all unstable vertices. -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -3248,9 +3128,7 @@ INPUT: - ``v`` -- vertex -OUTPUT: - -SandpileConfig +OUTPUT: SandpileConfig EXAMPLES:: @@ -3271,9 +3149,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -printed string +OUTPUT: printed string EXAMPLES:: @@ -3298,10 +3174,10 @@ EXAMPLES:: fire_unstable -- Fire all unstable vertices. fire_vertex -- Fire the given vertex. help -- List of SandpileConfig methods. - is_recurrent -- Is the configuration recurrent? - is_stable -- Is the configuration stable? - is_superstable -- Is the configuration superstable? - is_symmetric -- Is the configuration symmetric? + is_recurrent -- Return whether the configuration is recurrent. + is_stable -- Return whether the configuration is stable. + is_superstable -- Return whether the configuration is superstable. + is_symmetric -- Return whether the configuration is symmetric. order -- The order of the equivalent recurrent element. sandpile -- The configuration's underlying sandpile. show -- Show the configuration. @@ -3316,11 +3192,9 @@ EXAMPLES:: **is_recurrent()** -Is the configuration recurrent? - -OUTPUT: +Return whether the configuration is recurrent. -boolean +OUTPUT: boolean EXAMPLES:: @@ -3336,11 +3210,9 @@ EXAMPLES:: **is_stable()** -Is the configuration stable? +Return whether the configuration is stable. -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -3358,11 +3230,9 @@ EXAMPLES:: **is_superstable()** -Is the configuration superstable? +Return whether the configuration is superstable. -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -3376,7 +3246,7 @@ EXAMPLES:: **is_symmetric(orbits)** -Is the configuration symmetric? Return ``True`` if the values of the +Return whether the configuration is symmetric. Return ``True`` if the values of the configuration are constant over the vertices in each sublist of ``orbits``. @@ -3384,9 +3254,7 @@ INPUT: - ``orbits`` -- list of lists of vertices -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -3407,9 +3275,7 @@ EXAMPLES:: The order of the equivalent recurrent element. -OUTPUT: - -integer +OUTPUT: integer EXAMPLES:: @@ -3435,9 +3301,7 @@ EXAMPLES:: The configuration's underlying sandpile. -OUTPUT: - -Sandpile +OUTPUT: Sandpile EXAMPLES:: @@ -3489,9 +3353,7 @@ INPUT: - ``with_firing_vector`` -- (default: ``False``) boolean -OUTPUT: - -``SandpileConfig`` or ``[SandpileConfig, firing_vector]`` +OUTPUT: ``SandpileConfig`` or ``[SandpileConfig, firing_vector]`` EXAMPLES:: @@ -3538,9 +3400,7 @@ EXAMPLES:: The unstable vertices. -OUTPUT: - -list of vertices +OUTPUT: list of vertices EXAMPLES:: @@ -3558,9 +3418,7 @@ EXAMPLES:: The values of the configuration as a list. The list is sorted in the order of the vertices. -OUTPUT: - -list of integers +OUTPUT: list of integers boolean @@ -3616,13 +3474,13 @@ SandpileDivisor - :ref:`help ` --- List of SandpileDivisor methods. -- :ref:`is_alive ` --- Is the divisor stabilizable? +- :ref:`is_alive ` --- Return whether the divisor is stabilizable. -- :ref:`is_linearly_equivalent ` --- Is the given divisor linearly equivalent? +- :ref:`is_linearly_equivalent ` --- Return whether the given divisor is linearly equivalent. -- :ref:`is_q_reduced ` --- Is the divisor q-reduced? +- :ref:`is_q_reduced ` --- Return whether the divisor is q-reduced. -- :ref:`is_symmetric ` --- Is the divisor symmetric? +- :ref:`is_symmetric ` --- Return whether the divisor is symmetric. - :ref:`is_weierstrass_pt ` --- Is the given vertex a Weierstrass point? @@ -3672,9 +3530,7 @@ SandpileDivisor - ``other`` -- SandpileDivisor - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -3697,9 +3553,7 @@ SandpileDivisor - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3731,9 +3585,7 @@ SandpileDivisor - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3760,9 +3612,7 @@ SandpileDivisor - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3794,9 +3644,7 @@ SandpileDivisor - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3818,9 +3666,7 @@ SandpileDivisor The additive inverse of the divisor. - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -3841,9 +3687,7 @@ SandpileDivisor - ``other`` -- SandpileDivisor - OUTPUT: - - Difference of ``self`` and ``other`` + OUTPUT: difference of ``self`` and ``other`` EXAMPLES:: @@ -3861,9 +3705,7 @@ SandpileDivisor The support-complex. (See NOTE.) -OUTPUT: - -simplicial complex +OUTPUT: simplicial complex EXAMPLES:: @@ -3893,9 +3735,7 @@ INPUT: - ``distrib`` -- (optional) list of nonnegative numbers representing a probability distribution on the vertices -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -3918,9 +3758,7 @@ EXAMPLES:: The Betti numbers for the support-complex. (See NOTE.) -OUTPUT: - -dictionary of integers +OUTPUT: dictionary of integers EXAMPLES:: @@ -3942,9 +3780,7 @@ EXAMPLES:: The degree of the divisor. -OUTPUT: - -integer +OUTPUT: integer EXAMPLES:: @@ -3961,9 +3797,7 @@ EXAMPLES:: The difference with the maximal stable divisor. -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -4050,9 +3884,7 @@ INPUT: - ``sigma`` -- SandpileDivisor or (list or dict representing a SandpileDivisor) -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -4073,9 +3905,7 @@ EXAMPLES:: Fire all unstable vertices. -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -4096,9 +3926,7 @@ INPUT: - ``v`` -- vertex -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -4119,9 +3947,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -printed string +OUTPUT: printed string EXAMPLES:: @@ -4139,11 +3965,11 @@ EXAMPLES:: fire_unstable -- Fire all unstable vertices. fire_vertex -- Fire the given vertex. help -- List of SandpileDivisor methods. - is_alive -- Is the divisor stabilizable? - is_linearly_equivalent -- Is the given divisor linearly equivalent? - is_q_reduced -- Is the divisor q-reduced? - is_symmetric -- Is the divisor symmetric? - is_weierstrass_pt -- Is the given vertex a Weierstrass point? + is_alive -- Return whether the divisor is stabilizable. + is_linearly_equivalent -- Return whether the given divisor is linearly equivalent. + is_q_reduced -- Return whether the divisor is q-reduced. + is_symmetric -- Return whether the divisor is symmetric. + is_weierstrass_pt -- Return whether the given vertex is a Weierstrass point. polytope -- The polytope determining the complete linear system. polytope_integer_pts -- The integer points inside divisor's polytope. q_reduced -- The linearly equivalent q-reduced divisor. @@ -4166,7 +3992,7 @@ EXAMPLES:: **is_alive(cycle=False)** -Is the divisor stabilizable? In other words, will the divisor stabilize +Return whether the divisor is stabilizable. In other words, will the divisor stabilize under repeated firings of all unstable vertices? Optionally returns the resulting cycle. @@ -4174,9 +4000,7 @@ INPUT: - ``cycle`` -- (default: ``False``) boolean -OUTPUT: - -boolean or optionally, a list of SandpileDivisors +OUTPUT: boolean or optionally, a list of SandpileDivisors EXAMPLES:: @@ -4193,7 +4017,7 @@ EXAMPLES:: **is_linearly_equivalent(D, with_firing_vector=False)** -Is the given divisor linearly equivalent? Optionally, returns the +Return whether the given divisor is linearly equivalent. Optionally, returns the firing vector. (See NOTE.) INPUT: @@ -4202,9 +4026,7 @@ INPUT: - ``with_firing_vector`` -- (default: ``False``) boolean -OUTPUT: - -boolean or integer vector +OUTPUT: boolean or integer vector EXAMPLES:: @@ -4236,12 +4058,10 @@ EXAMPLES:: **is_q_reduced()** -Is the divisor `q`-reduced? This would mean that `self = c + kq` where +Return whether the divisor is `q`-reduced. This would mean that `self = c + kq` where `c` is superstable, `k` is an integer, and `q` is the sink vertex. -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -4276,7 +4096,7 @@ general directed graphs: **is_symmetric(orbits)** -Is the divisor symmetric? Return ``True`` if the values of the +Return whether the divisor is symmetric. Return ``True`` if the values of the configuration are constant over the vertices in each sublist of ``orbits``. @@ -4284,9 +4104,7 @@ INPUT: - ``orbits`` -- list of lists of vertices -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -4307,15 +4125,13 @@ EXAMPLES:: **is_weierstrass_pt(v='sink')** -Is the given vertex a Weierstrass point? +Return whether the given vertex is a Weierstrass point. INPUT: - ``v`` -- (default: ``sink``) vertex -OUTPUT: - -boolean +OUTPUT: boolean EXAMPLES:: @@ -4344,9 +4160,7 @@ EXAMPLES:: The polytope determining the complete linear system. -OUTPUT: - -polytope +OUTPUT: polytope EXAMPLES:: @@ -4381,9 +4195,7 @@ The integer points inside divisor's polytope. The polytope referred to here is the one determining the divisor's complete linear system (see the documentation for ``polytope``). -OUTPUT: - -tuple of integer vectors +OUTPUT: tuple of integer vectors EXAMPLES:: @@ -4412,9 +4224,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -SandpileDivisor or list representing SandpileDivisor +OUTPUT: SandpileDivisor or list representing SandpileDivisor EXAMPLES:: @@ -4499,9 +4309,7 @@ EXAMPLES:: The divisor's underlying sandpile. -OUTPUT: - -Sandpile +OUTPUT: Sandpile EXAMPLES:: @@ -4547,9 +4355,7 @@ INPUT: - ``distrib`` -- (optional) list of nonnegative numbers representing a probability distribution on the vertices -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -4598,9 +4404,7 @@ EXAMPLES:: List of vertices at which the divisor is nonzero. -OUTPUT: - -list representing the support of the divisor +OUTPUT: list representing the support of the divisor EXAMPLES:: @@ -4619,9 +4423,7 @@ EXAMPLES:: The unstable vertices. -OUTPUT: - -list of vertices +OUTPUT: list of vertices EXAMPLES:: @@ -4639,9 +4441,7 @@ EXAMPLES:: The values of the divisor as a list. The list is sorted in the order of the vertices. -OUTPUT: - -list of integers +OUTPUT: list of integers boolean @@ -4671,9 +4471,7 @@ INPUT: - ``verbose`` -- (default: ``True``) boolean -OUTPUT: - -SandpileDivisor +OUTPUT: SandpileDivisor EXAMPLES:: @@ -4777,9 +4575,7 @@ INPUT: - ``v`` -- (default: ``sink``) vertex -OUTPUT: - -tuple of int +OUTPUT: tuple of int EXAMPLES:: @@ -4818,9 +4614,7 @@ Other - ``S`` -- Sandpi - ``eff`` -- list of divisors - OUTPUT: - - DiGraph + OUTPUT: DiGraph EXAMPLES:: @@ -4844,9 +4638,7 @@ Other - ``S`` - Sandpi - ``eff`` - list of divisors - OUTPUT: - - DiGraph + OUTPUT: DiGraph EXAMPLES:: @@ -4939,9 +4731,7 @@ Documentation for each method is available through the Sage online help system: - ``v`` - vertex - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES: diff --git a/src/doc/en/tutorial/afterword.rst b/src/doc/en/tutorial/afterword.rst index 84dd2891b71..390e67bac07 100644 --- a/src/doc/en/tutorial/afterword.rst +++ b/src/doc/en/tutorial/afterword.rst @@ -107,10 +107,8 @@ behaves differently from Python in several ways. 10 - **Integer division:** The Python expression ``2/3`` does not - behave the way mathematicians might expect. In Python2, if ``m`` and - ``n`` are ints, then ``m/n`` is also an int, namely the quotient of ``m`` - divided by ``n``. Therefore ``2/3=0``. In Python3, ``2/3`` returns the - floating point number ``0.6666...``. In both Python2 and Python3, ``//`` + behave the way mathematicians might expect: ``2/3`` returns the + floating point number ``0.6666...``. Note that ``//`` is the Euclidean division and ``2//3`` returns ``0``. We deal with this in the Sage interpreter, by wrapping integer @@ -125,16 +123,11 @@ behaves differently from Python in several ways. Rational Field sage: 2//3 0 - sage: int(2)/int(3) # not tested, python2 - 0 - **Long integers:** Python has native support for arbitrary precision integers, in addition to C-int's. These are significantly - slower than what GMP provides, and have the property that they - print with an ``L`` at the end to distinguish them from int's (and - this won't change any time soon). Sage implements arbitrary - precision integers using the GMP C-library, and these print without - an ``L``. + slower than what GMP provides. Sage implements arbitrary + precision integers using the GMP C-library. Rather than modifying the Python interpreter (as some people have diff --git a/src/doc/en/tutorial/conf.py b/src/doc/en/tutorial/conf.py index 7b475a3bb6e..52be3420ed1 100644 --- a/src/doc/en/tutorial/conf.py +++ b/src/doc/en/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/en/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/en/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/en/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/en/tutorial/interactive_shell.rst b/src/doc/en/tutorial/interactive_shell.rst index 8a630a5d9fc..84c20840589 100644 --- a/src/doc/en/tutorial/interactive_shell.rst +++ b/src/doc/en/tutorial/interactive_shell.rst @@ -363,9 +363,9 @@ this may indicate a performance issue worth looking into. sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 - sage: gap(0) + sage: libgap(0) 0 - sage: time g = gap.eval('1938^99484;;') + sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 @@ -793,7 +793,7 @@ allowed. :: - sage: a = gap(2) + sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): diff --git a/src/doc/en/tutorial/latex.rst b/src/doc/en/tutorial/latex.rst index a173afd75c5..73ef2df3a31 100644 --- a/src/doc/en/tutorial/latex.rst +++ b/src/doc/en/tutorial/latex.rst @@ -49,7 +49,7 @@ output of the entered commands automatically. You can start this automatic rendering by executing ``%display latex`` (and stop by executing ``%display plain``). -.. ONLY:: html +.. ONLY:: html and feature_jupyter_sphinx Thus, in the Jupyter notebook, you get diff --git a/src/doc/en/website/conf.py b/src/doc/en/website/conf.py index 38f31e5d46f..b238169bb3c 100644 --- a/src/doc/en/website/conf.py +++ b/src/doc/en/website/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the diff --git a/src/doc/es/a_tour_of_sage/conf.py b/src/doc/es/a_tour_of_sage/conf.py index b6f43afd2da..801f7cadb95 100644 --- a/src/doc/es/a_tour_of_sage/conf.py +++ b/src/doc/es/a_tour_of_sage/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -22,9 +27,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/es/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/es/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/es/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/es/tutorial/conf.py b/src/doc/es/tutorial/conf.py index 913dfc06025..dcb44232ca0 100644 --- a/src/doc/es/tutorial/conf.py +++ b/src/doc/es/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/es/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/es/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/es/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/fr/a_tour_of_sage/conf.py b/src/doc/fr/a_tour_of_sage/conf.py index 19c047882bf..9cca4b7d1f8 100644 --- a/src/doc/fr/a_tour_of_sage/conf.py +++ b/src/doc/fr/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release, latex_elements from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/fr/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/fr/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/fr/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/fr/tutorial/conf.py b/src/doc/fr/tutorial/conf.py index 87c13353111..38e0160f3ba 100644 --- a/src/doc/fr/tutorial/conf.py +++ b/src/doc/fr/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release, latex_elements from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/fr/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/fr/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/fr/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/fr/tutorial/interactive_shell.rst b/src/doc/fr/tutorial/interactive_shell.rst index 5283104c277..eb8829ceec1 100644 --- a/src/doc/fr/tutorial/interactive_shell.rst +++ b/src/doc/fr/tutorial/interactive_shell.rst @@ -366,9 +366,9 @@ qui mérite d'être examiné. sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 - sage: gap(0) + sage: libgap(0) 0 - sage: time g = gap.eval('1938^99484;;') + sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 @@ -809,7 +809,7 @@ reconstruire, mais d'autres non, aussi la reconstruction d'objets GAP :: - sage: a = gap(2) + sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): diff --git a/src/doc/hu/a_tour_of_sage/conf.py b/src/doc/hu/a_tour_of_sage/conf.py index 590be9195cb..2e5215fcf5d 100644 --- a/src/doc/hu/a_tour_of_sage/conf.py +++ b/src/doc/hu/a_tour_of_sage/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -22,9 +27,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/hu/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/hu/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/hu/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/it/a_tour_of_sage/conf.py b/src/doc/it/a_tour_of_sage/conf.py index 6d217dee7ec..48a568cc4d1 100644 --- a/src/doc/it/a_tour_of_sage/conf.py +++ b/src/doc/it/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release, latex_elements from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/it/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/it/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/it/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/it/faq/conf.py b/src/doc/it/faq/conf.py index c2cd668d0f8..84a8ac93eab 100644 --- a/src/doc/it/faq/conf.py +++ b/src/doc/it/faq/conf.py @@ -15,6 +15,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -22,9 +27,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/it/faq', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/it/faq', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/it/faq', '{filename}'), }) # General information about the project. diff --git a/src/doc/it/faq/faq-contribute.rst b/src/doc/it/faq/faq-contribute.rst index 63c67a8e264..3b6c1612083 100644 --- a/src/doc/it/faq/faq-contribute.rst +++ b/src/doc/it/faq/faq-contribute.rst @@ -158,8 +158,8 @@ Consulta anche la Guida dello Sviluppo Sage, specialmente il capitolo `Convenzioni per scrivere codice sorgente in Sage `_. -Ho inviato al server trac una correzione molte settimane fa. Perché la state ignorando? -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Ho inviato al GitHub Sage repo una correzione molte settimane fa. Perché la state ignorando? +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Non stiamo cercando di ignorare la tua correzione. Le persone che lavorano su Sage lo fanno nel loro tempo libero. diff --git a/src/doc/it/faq/faq-usage.rst b/src/doc/it/faq/faq-usage.rst index 37bef7b13c1..677d1a24bc2 100644 --- a/src/doc/it/faq/faq-usage.rst +++ b/src/doc/it/faq/faq-usage.rst @@ -305,7 +305,7 @@ anziché Integer di Sage. Ad esempio:: sage: RealNumber = float; Integer = int sage: from scipy import stats sage: stats.ttest_ind([1,2,3,4,5], [2,3,4,5,.6]) - Ttest...Result(statistic=0.0767529..., pvalue=0.940704...) + Ttest...Result(statistic=...0.0767529..., pvalue=...0.940704...) sage: stats.uniform(0,15).ppf([0.5,0.7]) array([ 7.5, 10.5]) @@ -469,37 +469,6 @@ Ci sono parecchie possibilità. Puoi usare i programmi a riga di comando ``screen``, ``nohup`` o ``disown``. -Il comando show (mostra) per la visualizzazione di oggetti 3D non funziona. -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -La visualizzazione 3D in tempo reale per Sage dalla versione 6.4 in -avanti usa il pacchetto `Jmol/JSmol `_. -Dalla linea di comando viene utilizzata l'applicazione Java Jmol, -mentre per la visualizzazione dal browser viene usato puro javascript -oppure una Java applet. In genere nei browser è usato javascript puro -per evitare problemi con quei browser che non supportano i plugin per -le applet Java (ad esempio Chrome). In ogni worksheet su browser c'è -una casella da spuntare prima di generare una vista tridimensionale -qualora l'utente voglia usare l'applet Java (essa è un po' più veloce -con viste complicate). - -La ragione più probabile di un malfunzionamento è che non hai -installato l'ambiente runtime di Java (JRE) o che è più vecchio della -versione 1.7. Se le cose funzionano dalla riga di comando, -un'altra possibilità è che il tuo browser non abbia il plugin giusto -per supportare le Java applet (al momento, nel 2014, tali plugin non -lavorano con la maggior parte delle versioni di Chrome). Assicurati di -aver installato il plugin IcedTea (su Linux vedi il tuo gestore dei -pacchetti) o il plugin di Oracle Java -(vedi: `IcedTea `_ -e `Java `_). - -Se stai usando un server Sage sul web e anche la visualizzazione -tramite javascript non funziona, potresti avere un problema con la -funzionalità javascript del tuo browser, o potresti aver disabilitato -javascript. - - Posso usare gli strumenti di Sage in un ambiente commerciale? """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/doc/it/tutorial/conf.py b/src/doc/it/tutorial/conf.py index 13bfa100034..ea77f3199b0 100644 --- a/src/doc/it/tutorial/conf.py +++ b/src/doc/it/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release, latex_elements from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/it/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/it/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/it/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/ja/a_tour_of_sage/conf.py b/src/doc/ja/a_tour_of_sage/conf.py index 105cae0a93d..eef0eba83b3 100644 --- a/src/doc/ja/a_tour_of_sage/conf.py +++ b/src/doc/ja/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release, latex_elements from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/ja/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/ja/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/ja/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/ja/tutorial/conf.py b/src/doc/ja/tutorial/conf.py index ef32faab6b8..eaaa4558a34 100644 --- a/src/doc/ja/tutorial/conf.py +++ b/src/doc/ja/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release, latex_elements from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/ja/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/ja/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/ja/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/ja/tutorial/interactive_shell.rst b/src/doc/ja/tutorial/interactive_shell.rst index 6a845fb3bf6..4ef6131d1b7 100644 --- a/src/doc/ja/tutorial/interactive_shell.rst +++ b/src/doc/ja/tutorial/interactive_shell.rst @@ -333,9 +333,9 @@ GMPの方が速いが,その差はわずかだ(Sage用にビルドされたPAR sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 - sage: gap(0) + sage: libgap(0) 0 - sage: time g = gap.eval('1938^99484;;') + sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 @@ -735,7 +735,7 @@ GAPでは,相当数のオブジェクトが再構成に使える印字形式 :: - sage: a = gap(2) + sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): diff --git a/src/doc/pt/a_tour_of_sage/conf.py b/src/doc/pt/a_tour_of_sage/conf.py index 075e2d7a4f5..806bc1b77c8 100644 --- a/src/doc/pt/a_tour_of_sage/conf.py +++ b/src/doc/pt/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/pt/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/pt/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/pt/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/doc/pt/tutorial/conf.py b/src/doc/pt/tutorial/conf.py index 13582d8b896..26368567ee4 100644 --- a/src/doc/pt/tutorial/conf.py +++ b/src/doc/pt/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/pt/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/pt/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/pt/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/pt/tutorial/interactive_shell.rst b/src/doc/pt/tutorial/interactive_shell.rst index 8f39dbe25d7..67d8c9823e3 100644 --- a/src/doc/pt/tutorial/interactive_shell.rst +++ b/src/doc/pt/tutorial/interactive_shell.rst @@ -353,9 +353,9 @@ indicar algum problema de performance que vale a pena investigar. sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 - sage: gap(0) + sage: libgap(0) 0 - sage: time g = gap.eval('1938^99484;;') + sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 @@ -781,7 +781,7 @@ representações impressas não é permitido. :: - sage: a = gap(2) + sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): diff --git a/src/doc/ru/tutorial/conf.py b/src/doc/ru/tutorial/conf.py index 5ff38a94d50..f2f44113045 100644 --- a/src/doc/ru/tutorial/conf.py +++ b/src/doc/ru/tutorial/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, 'blob/develop/src/doc/ru/tutorial', '{filename}'), + 'source_view_link': os.path.join(source_repository, 'blob/develop/src/doc/ru/tutorial', '{filename}'), + 'source_edit_link': os.path.join(source_repository, 'edit/develop/src/doc/ru/tutorial', '{filename}'), }) # General information about the project. diff --git a/src/doc/ru/tutorial/interactive_shell.rst b/src/doc/ru/tutorial/interactive_shell.rst index 213b2964fb0..49d36fd3784 100644 --- a/src/doc/ru/tutorial/interactive_shell.rst +++ b/src/doc/ru/tutorial/interactive_shell.rst @@ -341,9 +341,9 @@ Wall time. Однако, если существует существенная sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 - sage: gap(0) + sage: libgap(0) 0 - sage: time g = gap.eval('1938^99484;;') + sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 @@ -720,7 +720,7 @@ Sage не может сохранять и загружать объекты, с :: - sage: a = gap(2) + sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): diff --git a/src/doc/tr/a_tour_of_sage/conf.py b/src/doc/tr/a_tour_of_sage/conf.py index c1854ee2f42..9d2a503d78d 100644 --- a/src/doc/tr/a_tour_of_sage/conf.py +++ b/src/doc/tr/a_tour_of_sage/conf.py @@ -13,6 +13,11 @@ from sage_docbuild.conf import release from sage_docbuild.conf import * # NOQA + +for tag in feature_tags(): + tags.add(tag) + + # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the @@ -20,9 +25,10 @@ # contains common paths. html_static_path = [] + html_common_static_path -# Add a small edit button. +# Add small view/edit buttons. html_theme_options.update({ - 'source_edit_link': os.path.join(source_repository, f'blob/develop/src/doc/tr/a_tour_of_sage', '{filename}'), + 'source_view_link': os.path.join(source_repository, f'blob/develop/src/doc/tr/a_tour_of_sage', '{filename}'), + 'source_edit_link': os.path.join(source_repository, f'edit/develop/src/doc/tr/a_tour_of_sage', '{filename}'), }) # General information about the project. diff --git a/src/environment-3.10-linux-aarch64.yml b/src/environment-3.10-linux-aarch64.yml index 4e20820eec1..7c6026a6b00 100644 --- a/src/environment-3.10-linux-aarch64.yml +++ b/src/environment-3.10-linux-aarch64.yml @@ -38,7 +38,6 @@ dependencies: - brotli=1.1.0=h31becfc_1 - brotli-bin=1.1.0=h31becfc_1 - brotli-python=1.1.0=py310hbb3657e_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 @@ -320,6 +319,7 @@ dependencies: - pyrsistent=0.20.0=py310h7c1f4a2_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=hbbe8eec_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.10-linux.yml b/src/environment-3.10-linux.yml index 73a318f1073..929b40139c5 100644 --- a/src/environment-3.10-linux.yml +++ b/src/environment-3.10-linux.yml @@ -39,7 +39,6 @@ dependencies: - brotli=1.1.0=hd590300_1 - brotli-bin=1.1.0=hd590300_1 - brotli-python=1.1.0=py310hc6cd4ac_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 @@ -273,6 +272,8 @@ dependencies: - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=hed6455c_2 - memory-allocator=0.1.3=py310h2372a71_0 + - meson=1.5.2=pyhd8ed1ab_0 + - meson-python=0.15.0=pyh0c530f3_0 - metis=5.1.0=h59595ed_1007 - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hfe3b2da_0 @@ -358,6 +359,7 @@ dependencies: - pyrsistent=0.20.0=py310h2372a71_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=hd12c33a_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.10-macos-x86_64.yml b/src/environment-3.10-macos-x86_64.yml index ef12b1c101c..268e619f1ff 100644 --- a/src/environment-3.10-macos-x86_64.yml +++ b/src/environment-3.10-macos-x86_64.yml @@ -32,7 +32,6 @@ dependencies: - brotli=1.1.0=h0dc2134_1 - brotli-bin=1.1.0=h0dc2134_1 - brotli-python=1.1.0=py310h9e9d8ca_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 @@ -324,6 +323,7 @@ dependencies: - pyrsistent=0.20.0=py310hb372a2b_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=h00d2728_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.10-macos.yml b/src/environment-3.10-macos.yml index 1e7bd5209bc..87692b1e2ee 100644 --- a/src/environment-3.10-macos.yml +++ b/src/environment-3.10-macos.yml @@ -32,7 +32,6 @@ dependencies: - brotli=1.1.0=hb547adb_1 - brotli-bin=1.1.0=hb547adb_1 - brotli-python=1.1.0=py310h1253130_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 @@ -245,6 +244,8 @@ dependencies: - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2bbcd85_2 - memory-allocator=0.1.3=py310h2aa6e3c_0 + - meson=1.5.2=pyhd8ed1ab_0 + - meson-python=0.15.0=pyh0c530f3_0 - metis=5.1.0=h13dd4ca_1007 - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h91ba8db_0 @@ -324,6 +325,7 @@ dependencies: - pyrsistent=0.20.0=py310hd125d64_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=h2469fbe_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.11-linux-aarch64.yml b/src/environment-3.11-linux-aarch64.yml index e03e0ed8864..87cee9aad2a 100644 --- a/src/environment-3.11-linux-aarch64.yml +++ b/src/environment-3.11-linux-aarch64.yml @@ -38,7 +38,6 @@ dependencies: - brotli=1.1.0=h31becfc_1 - brotli-bin=1.1.0=h31becfc_1 - brotli-python=1.1.0=py311h8715677_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 @@ -320,6 +319,7 @@ dependencies: - pyrsistent=0.20.0=py311hc8f2f60_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=hddfb980_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.11-linux.yml b/src/environment-3.11-linux.yml index 32d1541e494..7fee7689a28 100644 --- a/src/environment-3.11-linux.yml +++ b/src/environment-3.11-linux.yml @@ -39,7 +39,6 @@ dependencies: - brotli=1.1.0=hd590300_1 - brotli-bin=1.1.0=hd590300_1 - brotli-python=1.1.0=py311hb755f60_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 @@ -273,6 +272,8 @@ dependencies: - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=hed6455c_2 - memory-allocator=0.1.3=py311h459d7ec_0 + - meson=1.5.2=pyhd8ed1ab_0 + - meson-python=0.15.0=pyh0c530f3_0 - metis=5.1.0=h59595ed_1007 - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hfe3b2da_0 @@ -358,6 +359,7 @@ dependencies: - pyrsistent=0.20.0=py311h459d7ec_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=hb806964_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.11-macos-x86_64.yml b/src/environment-3.11-macos-x86_64.yml index 6d62ac79ca3..d0fc9f07c5c 100644 --- a/src/environment-3.11-macos-x86_64.yml +++ b/src/environment-3.11-macos-x86_64.yml @@ -32,7 +32,6 @@ dependencies: - brotli=1.1.0=h0dc2134_1 - brotli-bin=1.1.0=h0dc2134_1 - brotli-python=1.1.0=py311hdf8f085_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 @@ -324,6 +323,7 @@ dependencies: - pyrsistent=0.20.0=py311he705e18_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=h657bba9_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.11-macos.yml b/src/environment-3.11-macos.yml index a96a5142606..4111aa010f2 100644 --- a/src/environment-3.11-macos.yml +++ b/src/environment-3.11-macos.yml @@ -32,7 +32,6 @@ dependencies: - brotli=1.1.0=hb547adb_1 - brotli-bin=1.1.0=hb547adb_1 - brotli-python=1.1.0=py311ha891d26_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 @@ -245,6 +244,8 @@ dependencies: - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2bbcd85_2 - memory-allocator=0.1.3=py311heffc1b2_0 + - meson=1.5.2=pyhd8ed1ab_0 + - meson-python=0.15.0=pyh0c530f3_0 - metis=5.1.0=h13dd4ca_1007 - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h91ba8db_0 @@ -324,6 +325,7 @@ dependencies: - pyrsistent=0.20.0=py311h05b510d_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=h932a869_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.9-linux-aarch64.yml b/src/environment-3.9-linux-aarch64.yml index cd423b040c4..43382444aae 100644 --- a/src/environment-3.9-linux-aarch64.yml +++ b/src/environment-3.9-linux-aarch64.yml @@ -38,7 +38,6 @@ dependencies: - brotli=1.1.0=h31becfc_1 - brotli-bin=1.1.0=h31becfc_1 - brotli-python=1.1.0=py39h387a81e_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 @@ -320,6 +319,7 @@ dependencies: - pyrsistent=0.20.0=py39h7cc1d5f_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=h4ac3b42_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.9-linux.yml b/src/environment-3.9-linux.yml index 36d7a6fab66..83a922eb4f4 100644 --- a/src/environment-3.9-linux.yml +++ b/src/environment-3.9-linux.yml @@ -39,7 +39,6 @@ dependencies: - brotli=1.1.0=hd590300_1 - brotli-bin=1.1.0=hd590300_1 - brotli-python=1.1.0=py39h3d6467e_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 @@ -273,6 +272,8 @@ dependencies: - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=hed6455c_2 - memory-allocator=0.1.3=py39hd1e30aa_0 + - meson=1.5.2=pyhd8ed1ab_0 + - meson-python=0.15.0=pyh0c530f3_0 - metis=5.1.0=h59595ed_1007 - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hfe3b2da_0 @@ -358,6 +359,7 @@ dependencies: - pyrsistent=0.20.0=py39hd1e30aa_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=h0755675_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.9-macos-x86_64.yml b/src/environment-3.9-macos-x86_64.yml index 566775ddd11..c3026a8fbc0 100644 --- a/src/environment-3.9-macos-x86_64.yml +++ b/src/environment-3.9-macos-x86_64.yml @@ -32,7 +32,6 @@ dependencies: - brotli=1.1.0=h0dc2134_1 - brotli-bin=1.1.0=h0dc2134_1 - brotli-python=1.1.0=py39h840bb9f_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 @@ -324,6 +323,7 @@ dependencies: - pyrsistent=0.20.0=py39ha09f3b3_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=h7a9c478_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-3.9-macos.yml b/src/environment-3.9-macos.yml index 4cf9ff6e7bc..906b3b79f22 100644 --- a/src/environment-3.9-macos.yml +++ b/src/environment-3.9-macos.yml @@ -32,7 +32,6 @@ dependencies: - brotli=1.1.0=hb547adb_1 - brotli-bin=1.1.0=hb547adb_1 - brotli-python=1.1.0=py39hb198ff7_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 @@ -245,6 +244,8 @@ dependencies: - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2bbcd85_2 - memory-allocator=0.1.3=py39h0f82c59_0 + - meson=1.5.2=pyhd8ed1ab_0 + - meson-python=0.15.0=pyh0c530f3_0 - metis=5.1.0=h13dd4ca_1007 - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h91ba8db_0 @@ -324,6 +325,7 @@ dependencies: - pyrsistent=0.20.0=py39h17cfd9d_0 - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=hd7ebdb9_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.10-linux-aarch64.yml b/src/environment-dev-3.10-linux-aarch64.yml index e0a7428c353..5cc9a611a2a 100644 --- a/src/environment-dev-3.10-linux-aarch64.yml +++ b/src/environment-dev-3.10-linux-aarch64.yml @@ -42,7 +42,6 @@ dependencies: - brotli=1.1.0=h31becfc_1 - brotli-bin=1.1.0=h31becfc_1 - brotli-python=1.1.0=py310hbb3657e_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 @@ -367,6 +366,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.10.14=hbbe8eec_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.10-linux.yml b/src/environment-dev-3.10-linux.yml index 98b9bb546f9..90d8df80567 100644 --- a/src/environment-dev-3.10-linux.yml +++ b/src/environment-dev-3.10-linux.yml @@ -42,7 +42,6 @@ dependencies: - brotli=1.1.0=hd590300_1 - brotli-bin=1.1.0=hd590300_1 - brotli-python=1.1.0=py310hc6cd4ac_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 @@ -402,6 +401,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.10.14=hd12c33a_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.10-macos-x86_64.yml b/src/environment-dev-3.10-macos-x86_64.yml index 2013ecba6a1..6541d3ef7c8 100644 --- a/src/environment-dev-3.10-macos-x86_64.yml +++ b/src/environment-dev-3.10-macos-x86_64.yml @@ -35,7 +35,6 @@ dependencies: - brotli=1.1.0=h0dc2134_1 - brotli-bin=1.1.0=h0dc2134_1 - brotli-python=1.1.0=py310h9e9d8ca_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 @@ -365,6 +364,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.10.14=h00d2728_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.10-macos.yml b/src/environment-dev-3.10-macos.yml index 5e68c311f97..014df8bdc08 100644 --- a/src/environment-dev-3.10-macos.yml +++ b/src/environment-dev-3.10-macos.yml @@ -35,7 +35,6 @@ dependencies: - brotli=1.1.0=hb547adb_1 - brotli-bin=1.1.0=hb547adb_1 - brotli-python=1.1.0=py310h1253130_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 @@ -365,6 +364,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.10.14=h2469fbe_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.11-linux-aarch64.yml b/src/environment-dev-3.11-linux-aarch64.yml index b6877adff0c..9772d14d173 100644 --- a/src/environment-dev-3.11-linux-aarch64.yml +++ b/src/environment-dev-3.11-linux-aarch64.yml @@ -42,7 +42,6 @@ dependencies: - brotli=1.1.0=h31becfc_1 - brotli-bin=1.1.0=h31becfc_1 - brotli-python=1.1.0=py311h8715677_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 @@ -367,6 +366,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.11.9=hddfb980_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.11-linux.yml b/src/environment-dev-3.11-linux.yml index 61335e6a853..f59609c4b25 100644 --- a/src/environment-dev-3.11-linux.yml +++ b/src/environment-dev-3.11-linux.yml @@ -42,7 +42,6 @@ dependencies: - brotli=1.1.0=hd590300_1 - brotli-bin=1.1.0=hd590300_1 - brotli-python=1.1.0=py311hb755f60_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 @@ -402,6 +401,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.11.9=hb806964_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.11-macos-x86_64.yml b/src/environment-dev-3.11-macos-x86_64.yml index ac36b8f0f89..3368f995b8c 100644 --- a/src/environment-dev-3.11-macos-x86_64.yml +++ b/src/environment-dev-3.11-macos-x86_64.yml @@ -35,7 +35,6 @@ dependencies: - brotli=1.1.0=h0dc2134_1 - brotli-bin=1.1.0=h0dc2134_1 - brotli-python=1.1.0=py311hdf8f085_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 @@ -365,6 +364,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.11.9=h657bba9_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.11-macos.yml b/src/environment-dev-3.11-macos.yml index 584fcb8acc4..ba84799917e 100644 --- a/src/environment-dev-3.11-macos.yml +++ b/src/environment-dev-3.11-macos.yml @@ -35,7 +35,6 @@ dependencies: - brotli=1.1.0=hb547adb_1 - brotli-bin=1.1.0=hb547adb_1 - brotli-python=1.1.0=py311ha891d26_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 @@ -365,6 +364,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.11.9=h932a869_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.9-linux-aarch64.yml b/src/environment-dev-3.9-linux-aarch64.yml index d975d72ca98..39923130bc5 100644 --- a/src/environment-dev-3.9-linux-aarch64.yml +++ b/src/environment-dev-3.9-linux-aarch64.yml @@ -42,7 +42,6 @@ dependencies: - brotli=1.1.0=h31becfc_1 - brotli-bin=1.1.0=h31becfc_1 - brotli-python=1.1.0=py39h387a81e_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 @@ -367,6 +366,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.9.19=h4ac3b42_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.9-linux.yml b/src/environment-dev-3.9-linux.yml index 6aaffa90cab..451a093512e 100644 --- a/src/environment-dev-3.9-linux.yml +++ b/src/environment-dev-3.9-linux.yml @@ -42,7 +42,6 @@ dependencies: - brotli=1.1.0=hd590300_1 - brotli-bin=1.1.0=hd590300_1 - brotli-python=1.1.0=py39h3d6467e_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 @@ -402,6 +401,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.9.19=h0755675_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.9-macos-x86_64.yml b/src/environment-dev-3.9-macos-x86_64.yml index d34360440bd..92632f26f85 100644 --- a/src/environment-dev-3.9-macos-x86_64.yml +++ b/src/environment-dev-3.9-macos-x86_64.yml @@ -35,7 +35,6 @@ dependencies: - brotli=1.1.0=h0dc2134_1 - brotli-bin=1.1.0=h0dc2134_1 - brotli-python=1.1.0=py39h840bb9f_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 @@ -365,6 +364,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.9.19=h7a9c478_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/environment-dev-3.9-macos.yml b/src/environment-dev-3.9-macos.yml index 934855f53d6..bcc3c684e61 100644 --- a/src/environment-dev-3.9-macos.yml +++ b/src/environment-dev-3.9-macos.yml @@ -35,7 +35,6 @@ dependencies: - brotli=1.1.0=hb547adb_1 - brotli-bin=1.1.0=hb547adb_1 - brotli-python=1.1.0=py39hb198ff7_1 - - build=0.7.0=pyhd8ed1ab_0 - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 @@ -365,6 +364,7 @@ dependencies: - pytest=8.2.2=pyhd8ed1ab_0 - pytest-xdist=3.6.1=pyhd8ed1ab_0 - python=3.9.19=hd7ebdb9_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 - python-dateutil=2.9.0=pyhd8ed1ab_0 - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000000..12d82fa91c3 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,154 @@ +# Compilers +cc = meson.get_compiler('c') +cpp = meson.get_compiler('cpp') +cython = meson.get_compiler('cython') + +# Setup dependencies that are needed by many modules +inc_numpy = run_command( + py, + [ + '-c', + ''' +import numpy +print(numpy.get_include()) + '''.strip(), + ], + check: true, +).stdout().strip() +numpy = declare_dependency(include_directories: inc_numpy) + +inc_cysignals = run_command( + py, + [ + '-c', + ''' +import cysignals +print(cysignals.__file__.replace('__init__.py', '')) + '''.strip(), + ], + check: true, +).stdout().strip() +cysignals = declare_dependency(include_directories: inc_cysignals) + +inc_gmpy2 = run_command( + py, + [ + '-c', + ''' +import gmpy2 +print(gmpy2.__file__.replace('__init__.py', '')) + '''.strip(), + ], + check: true, +).stdout().strip() +gmpy2 = declare_dependency(include_directories: inc_gmpy2) +gmp = dependency('gmp') + +inc_cypari2 = run_command( + py, + [ + '-c', + ''' +import cypari2 +print(cypari2.__file__.replace('__init__.py', '')) + '''.strip(), + ], + check: true, +).stdout().strip() +cypari2 = declare_dependency(include_directories: inc_cypari2) +pari = cc.find_library('pari') + +mpfr = cc.find_library('mpfr') + +flint = dependency('flint', version: '>=3.0.0') +if flint.version().version_compare('<3.1') + # In older versions of flint, pkg-config file is broken, so we manually use find_library + # This has been fixed in flint v3.1: https://github.com/flintlib/flint/pull/1647 + flint = cc.find_library('flint') +endif + +blas_order = [] +if host_machine.system() == 'darwin' + blas_order += 'accelerate' +endif +if host_machine.cpu_family() == 'x86_64' + blas_order += 'mkl' +endif +# pkg-config uses a lower-case name while CMake uses a capitalized name, so try +# that too to make the fallback detection with CMake work +blas_order += ['cblas', 'openblas', 'OpenBLAS', 'flexiblas', 'blis', 'blas'] +blas = dependency(blas_order) +gsl = dependency( + 'gsl', + fallback: ['gsl', 'gsl_dep'], + version: '>=2.5', + required: true, +) +gd = cc.find_library('gd') +m = cc.find_library('m') +m4ri = cc.find_library('m4ri') +m4rie = cc.find_library('m4rie') +mtx = cc.find_library('mtx', required: false, disabler: true) +png = cc.find_library('png') +zlib = cc.find_library('z') +# Cannot be found via pkg-config +ec = cc.find_library('ec') +ecm = cc.find_library('ecm') +ppl = cc.find_library('ppl') +gmpxx = cc.find_library('gmpxx') +fflas = dependency('fflas-ffpack') +fplll = dependency('fplll') +givaro = cc.find_library('givaro') +linbox = dependency('linbox', required: false) +if not linbox.found() + linbox = cc.find_library('linbox') +endif +mpc = cc.find_library('mpc') +mpfi = cc.find_library('mpfi') +# Cannot be found via pkg-config (pkg-config file will be added in 4.13) +# Test for common.h header that was added in 4.12 as a indirect version check +gap = cc.find_library('gap', has_headers: ['gap/common.h']) +singular = dependency('Singular') +maxima = find_program('maxima', required: true) +# Cannot be found via pkg-config +ntl = cc.find_library('ntl') +# Cannot be found via pkg-config +meataxe = cc.find_library('meataxe', required: false, disabler: true) + +# Meson currently ignores include_directories for Cython modules, so we +# have to add them manually. +# https://github.com/mesonbuild/meson/issues/9562 +add_project_arguments('-I', meson.current_source_dir(), language: 'cython') +add_project_arguments('-I', meson.current_build_dir(), language: 'cython') + +# Add global compiler flags +add_project_arguments('-X auto_pickle=False', language: 'cython') +add_project_arguments('-X autotestdict=False', language: 'cython') +add_project_arguments('-X binding=False', language: 'cython') +add_project_arguments('-X c_api_binop_methods=True', language: 'cython') +add_project_arguments('-X cdivision=True', language: 'cython') +add_project_arguments('-X cpow=True', language: 'cython') +add_project_arguments('-X embedsignature=True', language: 'cython') +add_project_arguments('--embed-positions', language: 'cython') +add_project_arguments('-X fast_getattr=True', language: 'cython') +#add_project_arguments('-X language_level="3"', language : 'cython') +add_project_arguments('-X legacy_implicit_noexcept=True', language: 'cython') +add_project_arguments( + '-X preliminary_late_includes_cy28=True', + language: 'cython', +) + +inc_cpython = include_directories('sage/cpython') +inc_rings = include_directories('sage/rings') +inc_rings_finite = include_directories('sage/rings/finite_rings') +inc_flint = include_directories('sage/libs/flint') +inc_gsl = include_directories('sage/libs/gsl') +inc_ntl = include_directories('sage/libs/ntl') +inc_arb = include_directories('sage/libs/arb') +inc_data_structures = include_directories('sage/data_structures') +inc_ext = include_directories('sage/ext') +inc_partn_ref2 = include_directories('sage/groups/perm_gps/partn_ref2') +inc_src = include_directories('.') + +# Submodules +subdir('sage') diff --git a/src/pyproject.toml b/src/pyproject.toml index f70304534d9..4b70dc133d1 100644 --- a/src/pyproject.toml +++ b/src/pyproject.toml @@ -14,6 +14,7 @@ requires = [ 'memory_allocator', 'numpy >=1.19', 'pkgconfig', + 'jinja2', ] build-backend = "setuptools.build_meta" @@ -21,3 +22,68 @@ build-backend = "setuptools.build_meta" platforms = [ 'osx-64', 'linux-64', 'linux-aarch64', 'osx-arm64' ] + +[external] +# External dependencies in the format proposed by https://peps.python.org/pep-0725 +# In the future, sage-the-distribution can read this information +build-requires = [ + "virtual:compiler/c", + "virtual:compiler/cpp", + "pkg:generic/pkg-config" +] + +host-requires = [ + "virtual:interface/blas", + "pkg:generic/boost", + "pkg:generic/brial", + "pkg:generic/cddlib", + "pkg:generic/cliquer", + "pkg:generic/ecl", + "pkg:generic/eclib", + "pkg:generic/ecm", + "pkg:generic/fflas-ffpack", + "pkg:generic/fplll", + "pkg:generic/flint", + "pkg:generic/libgd", + "pkg:generic/gap", + "pkg:generic/gfan", + "pkg:generic/giac", + "pkg:generic/givaro", + "pkg:generic/glpk", + "pkg:generic/gmp", + "pkg:generic/gsl", + "pkg:generic/iml", + "pkg:generic/lcalc", + "pkg:generic/libbraiding", + "pkg:generic/libhomfly", + "pkg:generic/linbox", + "pkg:generic/lrcalc", + "pkg:generic/m4ri", + "pkg:generic/m4rie", + "pkg:generic/maxima", + "pkg:generic/mpc", + "pkg:generic/mpfi", + "pkg:generic/mpfr", + "pkg:generic/nauty", + "pkg:generic/ntl", + "pkg:generic/palp", + "pkg:generic/pari", + "pkg:generic/pari-elldata", + "pkg:generic/pari-galdata", + "pkg:generic/pari-seadata", + "pkg:generic/planarity", + "pkg:generic/ppl", + "pkg:generic/primesieve", + "pkg:generic/primecount", + "pkg:generic/qhull", + "pkg:generic/rw", + "pkg:generic/singular", + "pkg:generic/symmetrica", + "pkg:generic/sympow", +] + +dependencies = [ + "pkg:generic/tachyon", + "pkg:generic/sagemath-polytopes-db", + "pkg:generic/sagemath-elliptic-curves", +] diff --git a/src/sage/algebras/affine_nil_temperley_lieb.py b/src/sage/algebras/affine_nil_temperley_lieb.py index ae3e8e87464..958171992d4 100644 --- a/src/sage/algebras/affine_nil_temperley_lieb.py +++ b/src/sage/algebras/affine_nil_temperley_lieb.py @@ -23,7 +23,7 @@ class AffineNilTemperleyLiebTypeA(CombinatorialFreeModule): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer The affine nilTemperley Lieb algebra is generated by `a_i` for `i=0,1,\ldots,n-1` subject to the relations `a_i a_i = a_i a_{i+1} a_i = a_{i+1} a_i a_{i+1} = 0` and @@ -48,7 +48,7 @@ def __init__(self, n, R=ZZ, prefix='a'): EXAMPLES:: - sage: A = AffineNilTemperleyLiebTypeA(3, prefix="a"); A + sage: A = AffineNilTemperleyLiebTypeA(3, prefix='a'); A The affine nilTemperley Lieb algebra A3 over the ring Integer Ring sage: TestSuite(A).run() sage: A = AffineNilTemperleyLiebTypeA(3, QQ); A @@ -67,7 +67,7 @@ def __init__(self, n, R=ZZ, prefix='a'): def _element_constructor_(self, w): """ - Constructs a basis element from an element of the Weyl group. + Construct a basis element from an element of the Weyl group. If `w = w_1 ... w_k` is a reduced word for `w`, then `A(w)` returns zero if `w` contains braid relations. @@ -76,7 +76,7 @@ def _element_constructor_(self, w): EXAMPLES:: - sage: A = AffineNilTemperleyLiebTypeA(3, prefix="a") + sage: A = AffineNilTemperleyLiebTypeA(3, prefix='a') sage: W = A.weyl_group() sage: w = W.from_reduced_word([2,1,2]) sage: A(w) diff --git a/src/sage/algebras/algebra.py b/src/sage/algebras/algebra.py index a63aae4e217..8d9395a3176 100644 --- a/src/sage/algebras/algebra.py +++ b/src/sage/algebras/algebra.py @@ -23,7 +23,7 @@ def is_Algebra(x): r""" - Return True if x is an Algebra. + Return ``True`` if `x` is an Algebra. EXAMPLES:: diff --git a/src/sage/algebras/askey_wilson.py b/src/sage/algebras/askey_wilson.py index f696969763d..f8fc56f5f46 100644 --- a/src/sage/algebras/askey_wilson.py +++ b/src/sage/algebras/askey_wilson.py @@ -800,15 +800,13 @@ def __init__(self, domain, on_generators, position=0, codomain=None, INPUT: - ``domain`` -- an Askey-Wilson algebra - - ``on_generators`` -- a list of length 6 corresponding to + - ``on_generators`` -- list of length 6 corresponding to the images of the generators - ``codomain`` -- (optional) the codomain - - ``position`` -- (default: 0) integer + - ``position`` -- integer (default: 0) - ``category`` -- (optional) category - OUTPUT: - - - module morphism + OUTPUT: module morphism EXAMPLES:: @@ -847,16 +845,14 @@ def __eq__(self, other): def _on_basis(self, c): r""" - Computes the image of this morphism on the basis element + Compute the image of this morphism on the basis element indexed by ``c``. INPUT: - - ``c`` -- a tuple of length 6 - - OUTPUT: + - ``c`` -- tuple of length 6 - - element of the codomain + OUTPUT: element of the codomain EXAMPLES:: diff --git a/src/sage/algebras/associated_graded.py b/src/sage/algebras/associated_graded.py index 681bec7e060..8806a1281ff 100644 --- a/src/sage/algebras/associated_graded.py +++ b/src/sage/algebras/associated_graded.py @@ -286,7 +286,7 @@ def algebra_generators(self): Finite family {'x': bar(U['x']), 'y': bar(U['y']), 'z': bar(U['z'])} """ G = self._A.algebra_generators() - return Family(G.keys(), lambda x: self(G[x]), name="generator") + return Family(G.keys(), lambda x: self(G[x]), name='generator') def degree_on_basis(self, x): """ diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index 8b3dbd9c584..92ad6c34d64 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -991,9 +991,7 @@ def lift_module_morphism(self, m, names=None): - ``names`` -- (default: ``'e'``) the names of the generators of the Clifford algebra of the domain of (the map represented by) ``m`` - OUTPUT: - - The algebra morphism `Cl(m)` from `Cl(W, m(Q))` to ``self``. + OUTPUT: the algebra morphism `Cl(m)` from `Cl(W, m(Q))` to ``self`` EXAMPLES:: @@ -1142,9 +1140,7 @@ def lift_isometry(self, m, names=None): the Clifford algebra of the codomain of (the map represented by) ``m`` - OUTPUT: - - The algebra morphism `Cl(m)` from ``self`` to `Cl(W, m^{-1}(Q))`. + OUTPUT: the algebra morphism `Cl(m)` from ``self`` to `Cl(W, m^{-1}(Q))` EXAMPLES:: @@ -1416,7 +1412,7 @@ class ExteriorAlgebra(CliffordAlgebra): - ``R`` -- the base ring, *or* the free module whose exterior algebra is to be computed - - ``names`` -- a list of strings to name the generators of the + - ``names`` -- list of strings to name the generators of the exterior algebra; this list can either have one entry only (in which case the generators will be called ``e + '0'``, ``e + '1'``, ..., ``e + 'n-1'``, with ``e`` being said entry), or have ``n`` entries @@ -1599,9 +1595,8 @@ def lift_morphism(self, phi, names=None): the Clifford algebra of the domain of (the map represented by) ``phi`` - OUTPUT: - - The algebra morphism `\Lambda(\phi)` from ``self`` to `\Lambda(W)`. + OUTPUT: the algebra morphism `\Lambda(\phi)` from ``self`` to + `\Lambda(W)` EXAMPLES:: @@ -1707,7 +1702,7 @@ def boundary(self, s_coeff): INPUT: - - ``s_coeff`` -- a dictionary whose keys are in `I \times I`, where + - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where `I` is the index set of the underlying vector space `V`, and whose values can be coerced into 1-forms (degree 1 elements) in ``E`` (usually, these values will just be elements of `V`) @@ -1730,7 +1725,7 @@ def coboundary(self, s_coeff): INPUT: - - ``s_coeff`` -- a dictionary whose keys are in `I \times I`, where + - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where `I` is the index set of the underlying vector space `V`, and whose values can be coerced into 1-forms (degree 1 elements) in ``E`` (usually, these values will just be elements of `V`) @@ -1795,7 +1790,6 @@ def coproduct_on_basis(self, a): sage: E.coproduct_on_basis((0,1,2)) 1 # x*y*z + x # y*z - y # x*z + x*y # z + z # x*y - x*z # y + y*z # x + x*y*z # 1 - """ from sage.combinat.combinat import unshuffle_iterator one = self.base_ring().one() @@ -2139,7 +2133,7 @@ def __init__(self, E, s_coeff): We skip the pickling test as there is an infinite recursion when doing equality checks:: - sage: TestSuite(par).run(skip="_test_pickling") + sage: TestSuite(par).run(skip='_test_pickling') Check that it knows it is a finite-dimensional algebra morphism (:issue:`25339`):; @@ -2207,7 +2201,7 @@ class ExteriorAlgebraBoundary(ExteriorAlgebraDifferential): INPUT: - ``E`` -- an exterior algebra of a vector space `L` - - ``s_coeff`` -- a dictionary whose keys are in `I \times I`, where + - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where `I` is the index set of the basis of the vector space `L`, and whose values can be coerced into 1-forms (degree 1 elements) in ``E``; this dictionary will be used to define the Lie algebra structure @@ -2452,7 +2446,7 @@ class ExteriorAlgebraCoboundary(ExteriorAlgebraDifferential): INPUT: - ``E`` -- an exterior algebra of a vector space `L` - - ``s_coeff`` -- a dictionary whose keys are in `I \times I`, where + - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where `I` is the index set of the basis of the vector space `L`, and whose values can be coerced into 1-forms (degree 1 elements) in ``E``; this dictionary will be used to define the Lie algebra structure @@ -2736,7 +2730,7 @@ class ExteriorAlgebraIdeal(Ideal_nc): sage: xbar * ybar 0 """ - def __init__(self, ring, gens, coerce=True, side="twosided"): + def __init__(self, ring, gens, coerce=True, side='twosided'): """ Initialize ``self``. @@ -2747,13 +2741,13 @@ def __init__(self, ring, gens, coerce=True, side="twosided"): sage: E. = ExteriorAlgebra(QQ) sage: I = E.ideal([x*y - x, x*y - 1]) - sage: TestSuite(I).run(skip="_test_category") + sage: TestSuite(I).run(skip='_test_category') sage: I = E.ideal([x*y - 3, 0, 2*3]) - sage: TestSuite(I).run(skip="_test_category") + sage: TestSuite(I).run(skip='_test_category') sage: I = E.ideal([]) - sage: TestSuite(I).run(skip="_test_category") + sage: TestSuite(I).run(skip='_test_category') """ self._groebner_strategy = None self._reduced = False @@ -2795,7 +2789,7 @@ def _contains_(self, f): EXAMPLES:: sage: E. = ExteriorAlgebra(QQ) - sage: I = E.ideal([x, x*y*z + 2*x*z + 3*y*z], side="left") + sage: I = E.ideal([x, x*y*z + 2*x*z + 3*y*z], side='left') sage: I.groebner_basis() (x, y*z) sage: x in I @@ -2848,9 +2842,9 @@ def __richcmp__(self, other, op): sage: E. = ExteriorAlgebra(QQ) sage: p = a + b*c - sage: IT = E.ideal([p], side="twosided") - sage: IR = E.ideal([p], side="right") - sage: IL = E.ideal([p], side="left") + sage: IT = E.ideal([p], side='twosided') + sage: IR = E.ideal([p], side='right') + sage: IL = E.ideal([p], side='left') sage: IR == IL False sage: IR <= IL @@ -2920,7 +2914,7 @@ def __richcmp__(self, other, op): return contained and contains if op == op_NE: return not (contained and contains) - # remaining case < + # remaining case < return contained and not contains def __mul__(self, other): @@ -2936,7 +2930,7 @@ def __mul__(self, other): sage: E. = ExteriorAlgebra(QQ) - sage: I = E.ideal([a + 1], side="left") + sage: I = E.ideal([a + 1], side='left') sage: J = I * I; J Left Ideal (2*a + 1, a, b, c, d, a*b, a*c, a*d, 2*a*b*c + b*c, 2*a*b*d + b*d, 2*a*c*d + c*d, a*b*c, a*b*d, a*c*d, b*c*d, a*b*c*d) @@ -2955,10 +2949,10 @@ def __mul__(self, other): sage: K = J * I sage: K Left Ideal (-a*b - a*c + b + c) of The exterior algebra of rank 4 over Rational Field - sage: E.ideal([J.gen(0) * d * I.gen(0)], side="left") <= K + sage: E.ideal([J.gen(0) * d * I.gen(0)], side='left') <= K True - sage: J = E.ideal([b + c*d], side="right") + sage: J = E.ideal([b + c*d], side='right') sage: I * J Twosided Ideal (a*c*d + a*b + c*d + b) of The exterior algebra of rank 4 over Rational Field sage: X = J * I; X @@ -2971,7 +2965,7 @@ def __mul__(self, other): sage: a * p # not a left ideal a*c*d + a*b - sage: I = E.ideal([a + 1], side="right") + sage: I = E.ideal([a + 1], side='right') sage: E.ideal([1]) * I Twosided Ideal (a + 1) of The exterior algebra of rank 4 over Rational Field sage: I * E.ideal([1]) @@ -2991,9 +2985,9 @@ def __mul__(self, other): if self.side() == "left" or self.side() == "twosided": if other.side() == "right" or other.side() == "twosided": - return self.ring().ideal(gens, side="twosided") - return self.ring().ideal(gens, side="left") - return self.ring().ideal(gens, side="right") + return self.ring().ideal(gens, side='twosided') + return self.ring().ideal(gens, side='left') + return self.ring().ideal(gens, side='right') def groebner_basis(self, term_order=None, reduced=True): r""" @@ -3004,12 +2998,12 @@ def groebner_basis(self, term_order=None, reduced=True): - ``term_order`` -- the term order used to compute the Gröbner basis; must be one of the following: - * ``"neglex"`` -- (default) negative (read right-to-left) lex order - * ``"degrevlex"`` -- degree reverse lex order - * ``"deglex"`` -- degree lex order + * ``'neglex'`` -- (default) negative (read right-to-left) lex order + * ``'degrevlex'`` -- degree reverse lex order + * ``'deglex'`` -- degree lex order - - ``reduced`` -- (default: ``True``) whether or not to return the - reduced Gröbner basis + - ``reduced`` -- boolean (default: ``True``); whether or not to return + the reduced Gröbner basis EXAMPLES: @@ -3043,7 +3037,7 @@ def groebner_basis(self, term_order=None, reduced=True): -a*c*d + a*c*e - a*d*e + c*d*e) The example above was computed first using M2, which agrees with - the ``"degrevlex"`` ordering:: + the ``'degrevlex'`` ordering:: E = QQ[a..e, SkewCommutative => true] I = ideal( c*d*e - b*d*e + b*c*e - b*c*d, diff --git a/src/sage/algebras/clifford_algebra_element.pyx b/src/sage/algebras/clifford_algebra_element.pyx index 52b994f48af..47a5e8026a2 100644 --- a/src/sage/algebras/clifford_algebra_element.pyx +++ b/src/sage/algebras/clifford_algebra_element.pyx @@ -713,7 +713,7 @@ cdef class ExteriorAlgebraElement(CliffordAlgebraElement): INPUT: - - ``I`` -- a list of exterior algebra elements or an ideal + - ``I`` -- list of exterior algebra elements or an ideal - ``left`` -- boolean; if reduce as a left ideal (``True``) or right ideal (``False``), ignored if ``I`` is an ideal diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index df35e502dbd..6772673cbcb 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -242,7 +242,7 @@ sage: S.cluster_variable(3) (x2 + 1)/x3 -Walking around by mutating ``S`` updates the informations stored in ``A``:: +Walking around by mutating ``S`` updates the information stored in ``A``:: sage: len(A.g_vectors_so_far()) 10 @@ -355,6 +355,7 @@ # **************************************************************************** from copy import copy +from typing import Any from sage.arith.misc import binomial from sage.categories.homset import Hom @@ -461,7 +462,7 @@ def d_vector(self) -> tuple: sage: x.d_vector() (1, 1, 2, -2) """ - monomials = self.lift().dict() + monomials = self.lift().monomial_coefficients() minimal = map(min, zip(*monomials)) return tuple(-vector(minimal))[:self.parent().rank()] @@ -562,7 +563,7 @@ def homogeneous_components(self) -> dict: """ deg_matrix = block_matrix([[identity_matrix(self.parent().rank()), -self.parent().b_matrix()]]) - components = {} + components: dict[tuple, Any] = {} x = self.lift() monomials = x.monomials() for m in monomials: @@ -614,8 +615,9 @@ def theta_basis_decomposition(self): f_poly = components[g_vect].F_polynomial() g_vect = vector(g_vect) while f_poly != zero_U: - y_exp = min(f_poly.dict()) - coeff = f_poly.dict()[y_exp] + coeffs = f_poly.monomial_coefficients() + y_exp = min(coeffs) + coeff = coeffs[y_exp] g_theta = tuple(g_vect + B * vector(y_exp)) out[g_theta] = out.get(g_theta, zero_A) + A({zero_t + tuple(y_exp): coeff}) f_poly -= U({y_exp: coeff}) * A.theta_basis_F_polynomial(g_theta) @@ -638,7 +640,7 @@ class ClusterAlgebraSeed(SageObject): - ``G`` -- the matrix of g-vectors of ``self`` - ``parent`` -- :class:`ClusterAlgebra`; the algebra to which the seed belongs - - ``path`` -- list (default ``[]``); the mutation sequence from the + - ``path`` -- list (default: ``[]``); the mutation sequence from the initial seed of ``parent`` to ``self`` .. WARNING:: @@ -902,7 +904,7 @@ def c_vector(self, j) -> tuple: INPUT: - - ``j`` -- an integer in ``range(self.parent().rank())``; + - ``j`` -- integer in ``range(self.parent().rank())``; the index of the c-vector to return EXAMPLES:: @@ -953,7 +955,7 @@ def g_vector(self, j) -> tuple: INPUT: - - ``j`` -- an integer in ``range(self.parent().rank())``; + - ``j`` -- integer in ``range(self.parent().rank())``; the index of the g-vector to return EXAMPLES:: @@ -984,7 +986,7 @@ def F_polynomial(self, j): INPUT: - - ``j`` -- an integer in ``range(self.parent().rank())``; + - ``j`` -- integer in ``range(self.parent().rank())``; the index of the F-polynomial to return EXAMPLES:: @@ -1015,7 +1017,7 @@ def cluster_variable(self, j): INPUT: - - ``j`` -- an integer in ``range(self.parent().rank())``; + - ``j`` -- integer in ``range(self.parent().rank())``; the index of the cluster variable to return EXAMPLES:: @@ -1055,9 +1057,10 @@ def mutate(self, direction, **kwargs): * an iterable of such integers to mutate along a sequence * a string "sinks" or "sources" to mutate at all sinks or sources simultaneously - - ``inplace`` -- bool (default ``True``); whether to mutate in place or to return a new object + - ``inplace`` -- boolean (default: ``True``); whether to mutate in place + or to return a new object - - ``mutating_F`` -- bool (default ``True``); whether to compute + - ``mutating_F`` -- boolean (default: ``True``); whether to compute F-polynomials while mutating .. NOTE:: @@ -1162,10 +1165,10 @@ def _mutated_F(self, k, old_g_vector): INPUT: - - ``k`` -- an integer in ``range(self.parent().rank())``; + - ``k`` -- an integer in ``range(self.parent().rank())``; the direction in which we are mutating - - ``old_g_vector`` -- tuple; the k-th g-vector of ``self`` + - ``old_g_vector`` -- tuple; the `k`-th g-vector of ``self`` before mutating .. NOTE:: @@ -1219,22 +1222,22 @@ class ClusterAlgebra(Parent, UniqueRepresentation): - ``data`` -- some data defining a cluster algebra; it can be anything that can be parsed by :class:`ClusterQuiver` - - ``scalars`` -- a ring (default `\ZZ`); the scalars over + - ``scalars`` -- a ring (default: `\ZZ`); the scalars over which the cluster algebra is defined - - ``cluster_variable_prefix`` -- string (default ``'x'``); it needs to be + - ``cluster_variable_prefix`` -- string (default: ``'x'``); it needs to be a valid variable name - - ``cluster_variable_names`` -- a list of strings; each element needs + - ``cluster_variable_names`` -- list of strings; each element needs to be a valid variable name; supersedes ``cluster_variable_prefix`` - - ``coefficient_prefix`` -- string (default ``'y'``); it needs to be - a valid variable name. + - ``coefficient_prefix`` -- string (default: ``'y'``); it needs to be + a valid variable name - - ``coefficient_names`` -- a list of strings; each element needs + - ``coefficient_names`` -- list of strings; each element needs to be a valid variable name; supersedes ``cluster_variable_prefix`` - - ``principal_coefficients`` -- bool (default ``False``); supersedes any + - ``principal_coefficients`` -- boolean (default: ``False``); supersedes any coefficient defined by ``data`` ALGORITHM: @@ -1431,11 +1434,11 @@ def _repr_(self) -> str: and coefficients y0, y1 over Integer Ring """ var_names = self.initial_cluster_variable_names() - var_names = (" " if len(var_names) == 1 else "s ") + ", ".join(var_names) + var_names_str = (" " if len(var_names) == 1 else "s ") + ", ".join(var_names) coeff_names = self.coefficient_names() coeff_prefix = " and" + (" " if len(coeff_names) > 0 else " no ") + "coefficient" coeff = coeff_prefix + (" " if len(coeff_names) == 1 else "s ") + ", ".join(coeff_names) + (" " if len(coeff_names) > 0 else "") - return "A Cluster Algebra with cluster variable" + var_names + coeff + "over " + repr(self.scalars()) + return "A Cluster Algebra with cluster variable" + var_names_str + coeff + "over " + repr(self.scalars()) def _an_element_(self): r""" @@ -1811,7 +1814,7 @@ def g_vectors(self, mutating_F=True): INPUT: - - ``mutating_F`` -- bool (default ``True``); whether to compute + - ``mutating_F`` -- boolean (default: ``True``); whether to compute F-polynomials; disable this for speed considerations ALGORITHM: @@ -1990,12 +1993,13 @@ def F_polynomial(self, g_vector): def find_g_vector(self, g_vector, depth=infinity): r""" - Return a mutation sequence to obtain a seed containing the g-vector ``g_vector`` from the initial seed. + Return a mutation sequence to obtain a seed containing the g-vector + ``g_vector`` from the initial seed. INPUT: - - ``g_vector`` -- a tuple: the g-vector to find - - ``depth`` -- a positive integer or infinity (default ``infinity``); + - ``g_vector`` -- tuple; the g-vector to find + - ``depth`` -- positive integer or infinity (default: ``infinity``); the maximum distance from ``self.current_seed`` to reach OUTPUT: @@ -2111,7 +2115,7 @@ def coefficient(self, j): INPUT: - - ``j`` -- an integer in ``range(self.parent().rank())``; + - ``j`` -- integer in ``range(self.parent().rank())``; the index of the coefficient to return EXAMPLES:: @@ -2167,7 +2171,7 @@ def initial_cluster_variable(self, j): INPUT: - - ``j`` -- an integer in ``range(self.parent().rank())``; + - ``j`` -- integer in ``range(self.parent().rank())``; the index of the cluster variable to return EXAMPLES:: @@ -2212,19 +2216,19 @@ def seeds(self, **kwargs): INPUT: - - ``from_current_seed`` -- bool (default ``False``); whether to start + - ``from_current_seed`` -- boolean (default: ``False``); whether to start the iterator from :meth:`current_seed` or :meth:`initial_seed` - - ``mutating_F`` -- bool (default ``True``); whether to compute + - ``mutating_F`` -- boolean (default: ``True``); whether to compute F-polynomials also; disable this for speed considerations - ``allowed_directions`` -- iterable of integers - (default ``range(self.rank())``); the directions in which to mutate + (default: ``range(self.rank())``); the directions in which to mutate - - ``depth`` -- a positive integer or infinity (default ``infinity``); + - ``depth`` -- positive integer or infinity (default: ``infinity``); the maximum depth at which to stop searching - - ``catch_KeyboardInterrupt`` -- bool (default ``False``); whether to + - ``catch_KeyboardInterrupt`` -- boolean (default: ``False``); whether to catch ``KeyboardInterrupt`` and return it rather then raising an exception -- this allows the iterator returned by this method to be resumed after being interrupted @@ -2319,7 +2323,7 @@ def reset_exploring_iterator(self, mutating_F=True): INPUT: - - ``mutating_F`` -- bool (default ``True``); whether to also compute + - ``mutating_F`` -- boolean (default: ``True``); whether to also compute F-polynomials; disable this for speed considerations EXAMPLES:: @@ -2343,7 +2347,7 @@ def explore_to_depth(self, depth): INPUT: - - ``depth`` -- a positive integer or infinity; the maximum depth + - ``depth`` -- positive integer or infinity; the maximum depth at which to stop searching EXAMPLES:: @@ -2370,7 +2374,7 @@ def cluster_fan(self, depth=infinity): INPUT: - - ``depth`` -- a positive integer or infinity (default ``infinity``); + - ``depth`` -- positive integer or infinity (default: ``infinity``); the maximum depth at which to compute EXAMPLES:: @@ -2401,7 +2405,7 @@ def mutate_initial(self, direction, **kwargs): * an iterable of such integers to mutate along a sequence * a string "sinks" or "sources" to mutate at all sinks or sources simultaneously - - ``mutating_F`` -- bool (default ``True``); whether to compute + - ``mutating_F`` -- boolean (default: ``True``); whether to compute F-polynomials while mutating .. NOTE:: diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index a027d1c996a..fdcaeedaad8 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -114,11 +114,9 @@ def sorting_keys(element): INPUT: - - ``element`` -- A CohomologyClass + - ``element`` -- a CohomologyClass - OUTPUT: - - Its coordinates in the corresponding ``cohomology_raw`` quotient vector space + OUTPUT: its coordinates in the corresponding ``cohomology_raw`` quotient vector space EXAMPLES:: @@ -224,7 +222,7 @@ def image_monomial(exponent): return A.zero() for g in I.gens(): - d = g.dict() + d = g.monomial_coefficients() res = A.sum(d[ex] * image_monomial(ex) for ex in d) if not res.is_zero(): raise ValueError("the differential does not preserve the ideal") @@ -261,7 +259,7 @@ def __init__(self, A, im_gens): We skip the category test because homsets/morphisms aren't proper parents/elements yet:: - sage: TestSuite(d).run(skip="_test_category") + sage: TestSuite(d).run(skip='_test_category') An error is raised if the differential `d` does not have degree 1 or if `d \circ d` is not zero:: @@ -305,7 +303,7 @@ def _call_(self, x): if x.is_zero(): return self.codomain().zero() res = self.codomain().zero() - dic = x.dict() + dic = x.monomial_coefficients() for key in dic: keyl = list(key) coef = dic[key] @@ -394,11 +392,11 @@ def differential_matrix(self, n): A = self.domain() dom = A.basis(n) cod = A.basis(n + 1) - cokeys = [next(iter(a.lift().dict().keys())) for a in cod] + cokeys = [next(iter(a.lift().monomial_coefficients().keys())) for a in cod] m = matrix(A.base_ring(), len(dom), len(cod)) for i, domi in enumerate(dom): im = self(domi) - dic = im.lift().dict() + dic = im.lift().monomial_coefficients() for j in dic.keys(): k = cokeys.index(j) m[i, k] = dic[j] @@ -433,7 +431,6 @@ def coboundaries(self, n): Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] - """ A = self.domain() F = A.base_ring() @@ -614,7 +611,7 @@ def __init__(self, A, im_gens): We skip the category test because homsets/morphisms aren't proper parents/elements yet:: - sage: TestSuite(d).run(skip="_test_category") + sage: TestSuite(d).run(skip='_test_category') """ Differential.__init__(self, A, im_gens) @@ -643,10 +640,10 @@ def differential_matrix_multigraded(self, n, total=False): INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, - return the matrix corresponding to total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, + return the matrix corresponding to total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -673,11 +670,11 @@ def differential_matrix_multigraded(self, n, total=False): n = G(vector(n)) dom = A.basis(n) cod = A.basis(n + self._degree_of_differential) - cokeys = [next(iter(a.lift().dict().keys())) for a in cod] + cokeys = [next(iter(a.lift().monomial_coefficients().keys())) for a in cod] m = matrix(self.base_ring(), len(dom), len(cod)) for i, domi in enumerate(dom): im = self(domi) - dic = im.lift().dict() + dic = im.lift().monomial_coefficients() for j in dic.keys(): k = cokeys.index(j) m[i, k] = dic[j] @@ -686,19 +683,19 @@ def differential_matrix_multigraded(self, n, total=False): def coboundaries(self, n, total=False): """ - The ``n``-th coboundary group of the algebra. + The `n`-th coboundary group of the algebra. This is a vector space over the base field `F`, and it is returned as a subspace of the vector space `F^d`, where the - ``n``-th homogeneous component has dimension `d`. + `n`-th homogeneous component has dimension `d`. INPUT: - ``n`` -- degree - - ``total`` (default ``False``) -- if ``True``, return the - coboundaries in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + coboundaries in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -733,19 +730,19 @@ def coboundaries(self, n, total=False): def cocycles(self, n, total=False): r""" - The ``n``-th cocycle group of the algebra. + The `n`-th cocycle group of the algebra. This is a vector space over the base field `F`, and it is returned as a subspace of the vector space `F^d`, where the - ``n``-th homogeneous component has dimension `d`. + `n`-th homogeneous component has dimension `d`. INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, return the - cocycles in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + cocycles in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -778,7 +775,7 @@ def cocycles(self, n, total=False): def cohomology_raw(self, n, total=False): r""" - The ``n``-th cohomology group of the algebra. + The `n`-th cohomology group of the algebra. This is a vector space over the base ring, and it is returned as the quotient cocycles/coboundaries. @@ -786,10 +783,10 @@ def cohomology_raw(self, n, total=False): INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, return the - cohomology in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + cohomology in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. .. SEEALSO:: @@ -822,7 +819,7 @@ def cohomology_raw(self, n, total=False): def cohomology(self, n, total=False): r""" - The ``n``-th cohomology group of the algebra. + The `n`-th cohomology group of the algebra. This is a vector space over the base ring, defined as the quotient cocycles/coboundaries. The elements of the quotient @@ -832,10 +829,10 @@ def cohomology(self, n, total=False): INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, return the - cohomology in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + cohomology in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. .. SEEALSO:: @@ -889,11 +886,11 @@ class GCAlgebra(UniqueRepresentation, QuotientRing_nc): 1, and if both ``names`` and ``degrees`` are omitted, an error is raised. - - ``R`` (default: None) -- the ring over which the + - ``R`` -- (default: ``None``) the ring over which the algebra is defined: if this is specified, the algebra is defined to be ``R/I``. - - ``I`` (default: None) -- an ideal in ``R``. It is + - ``I`` -- (default: ``None``) an ideal in `R`. It is should include, among other relations, the squares of the generators of odd degree @@ -1086,7 +1083,7 @@ def _repr_(self): @cached_method def _basis_for_free_alg(self, n): r""" - Basis of the associated free commutative DGA in degree ``n``. + Basis of the associated free commutative DGA in degree `n`. That is, ignore the relations when computing the basis: compute the basis of the free commutative DGA with generators @@ -1096,9 +1093,7 @@ def _basis_for_free_alg(self, n): - ``n`` -- integer - OUTPUT: - - Tuple of basis elements in degree ``n``, as tuples of exponents. + OUTPUT: tuple of basis elements in degree `n`, as tuples of exponents EXAMPLES:: @@ -1164,7 +1159,7 @@ def _basis_for_free_alg(self, n): def basis(self, n): """ - Return a basis of the ``n``-th homogeneous component of ``self``. + Return a basis of the `n`-th homogeneous component of ``self``. EXAMPLES:: @@ -1187,7 +1182,7 @@ def basis(self, n): basis = [] for v in free_basis: el = prod([self.gen(i)**v[i] for i in range(len(v))]) - di = el.dict() + di = el.monomial_coefficients() if len(di) == 1: k, = di.keys() if tuple(k) == v: @@ -1202,7 +1197,7 @@ def quotient(self, I, check=True): - ``I`` -- a two-sided homogeneous ideal of this algebra - - ``check`` -- (default: ``True``) if ``True``, check whether + - ``check`` -- boolean (default: ``True``); if ``True``, check whether ``I`` is generated by homogeneous elements EXAMPLES:: @@ -1350,7 +1345,7 @@ def differential(self, diff): INPUT: - - ``diff`` -- a dictionary defining a differential + - ``diff`` -- dictionary defining a differential The keys of the dictionary are generators of the algebra, and the associated values are their targets under the @@ -1380,7 +1375,7 @@ def cdg_algebra(self, differential): INPUT: - - ``differential`` -- a dictionary defining a differential or + - ``differential`` -- dictionary defining a differential or a map defining a valid differential The keys of the dictionary are generators of the algebra, and @@ -1482,7 +1477,7 @@ def degree(self, total=False): """ if self.is_zero(): raise ValueError("the zero element does not have a well-defined degree") - exps = self.lift().dict().keys() + exps = self.monomial_coefficients().keys() degrees = self.parent()._degrees n = self.parent().ngens() l = [sum(e[i] * degrees[i] for i in range(n)) for e in exps] @@ -1494,7 +1489,7 @@ def is_homogeneous(self, total=False): INPUT: - - ``total`` -- boolean (default ``False``); only used in the + - ``total`` -- boolean (default: ``False``); only used in the multi-graded case, in which case if ``True``, check to see if ``self`` is homogeneous with respect to total degree @@ -1546,7 +1541,6 @@ def homogeneous_parts(self): Return the homogeneous parts of the element. The result is given as a dictionary indexed by degree. - EXAMPLES:: sage: A. = GradedCommutativeAlgebra(QQ) @@ -1554,7 +1548,7 @@ def homogeneous_parts(self): sage: a.homogeneous_parts() {1: -2*e3 + e5, 2: e1*e2, 3: e1*e3*e5 - 3*e2*e3*e5} """ - dic = self.dict() + dic = self.monomial_coefficients() terms = [self.parent()({t: dic[t]}) for t in dic.keys()] res = {} for term in terms: @@ -1565,7 +1559,7 @@ def homogeneous_parts(self): res[deg] = term return {i: res[i] for i in sorted(res.keys())} - def dict(self): + def monomial_coefficients(self): r""" A dictionary that determines the element. @@ -1575,11 +1569,18 @@ def dict(self): EXAMPLES:: sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1, 2, 2, 3)) - sage: dic = (x*y - 5*y*z + 7*x*y^2*z^3*t).dict() - sage: sorted(dic.items()) + sage: elt = x*y - 5*y*z + 7*x*y^2*z^3*t + sage: sorted(elt.monomial_coefficients().items()) + [((0, 1, 1, 0), -5), ((1, 1, 0, 0), 1), ((1, 2, 3, 1), 7)] + + ``dict`` is an alias:: + + sage: sorted(elt.dict().items()) [((0, 1, 1, 0), -5), ((1, 1, 0, 0), 1), ((1, 2, 3, 1), 7)] """ - return self.lift().dict() + return self.lift().monomial_coefficients() + + dict = monomial_coefficients def __call__(self, *values, **kwargs): r""" @@ -1593,9 +1594,7 @@ def __call__(self, *values, **kwargs): - ``values`` -- (optional) either the values in which the variables will be evaluated or a dictionary - OUTPUT: - - this element evaluated at the given values + OUTPUT: this element evaluated at the given values EXAMPLES:: @@ -1653,8 +1652,8 @@ def __call__(self, *values, **kwargs): if gstr in kwargs: images[i] = kwargs[gstr] res = 0 - for (m, c) in self.dict().items(): - term = prod((gen**y for (y, gen) in zip(m, images)), c) + for m, c in self.monomial_coefficients().items(): + term = prod((gen ** y for y, gen in zip(m, images)), c) res += term return res @@ -1663,21 +1662,19 @@ def basis_coefficients(self, total=False): Return the coefficients of this homogeneous element with respect to the basis in its degree. - For example, if this is the sum of the 0th and 2nd basis + For example, if this is the sum of the `0`-th and `2`-nd basis elements, return the list ``[1, 0, 1]``. Raise an error if the element is not homogeneous. INPUT: - - ``total`` -- boolean (default ``False``); this + - ``total`` -- boolean (default: ``False``); this is only used in the multi-graded case, in which case if ``True``, it returns the coefficients with respect to the basis for the total degree of this element - OUTPUT: - - A list of elements of the base field. + OUTPUT: list of elements of the base field EXAMPLES:: @@ -1717,7 +1714,7 @@ class GCAlgebra_multigraded(GCAlgebra): - ``base`` -- the base field - - ``degrees`` -- a tuple or list specifying the degrees of the + - ``degrees`` -- tuple or list specifying the degrees of the generators - ``names`` -- (optional) names of the generators: a list of @@ -1815,7 +1812,7 @@ def quotient(self, I, check=True): - ``I`` -- a two-sided homogeneous ideal of this algebra - - ``check`` -- (default: ``True``) if ``True``, check whether + - ``check`` -- boolean (default: ``True``); if ``True``, check whether ``I`` is generated by homogeneous elements EXAMPLES:: @@ -1870,13 +1867,13 @@ def _coerce_map_from_(self, other): def basis(self, n, total=False): """ - Basis in degree ``n``. + Basis in degree `n`. - ``n`` -- degree or integer - - ``total`` (default: ``False``) -- if True, return the - basis in total degree ``n``. + - ``total`` -- boolean (default: ``False``); if ``True``, return the + basis in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -1887,12 +1884,13 @@ def basis(self, n, total=False): sage: A.basis(2, total=True) [a^2, a*b, b^2, c] - Since 2 is a not a multi-index, we don't need to specify ``total=True``:: + Since 2 is a not a multi-index, we don't need to specify that ``total`` + is ``True``:: sage: A.basis(2) [a^2, a*b, b^2, c] - If ``total==True``, then ``n`` can still be a tuple, list, + If ``total`` is ``True``, then `n` can still be a tuple, list, etc., and its total degree is used instead:: sage: A.basis((1,1), total=True) @@ -1911,7 +1909,7 @@ def differential(self, diff): INPUT: - - ``diff`` -- a dictionary defining a differential + - ``diff`` -- dictionary defining a differential The keys of the dictionary are generators of the algebra, and the associated values are their targets under the @@ -1937,7 +1935,7 @@ def cdg_algebra(self, differential): INPUT: - - ``differential`` -- a dictionary defining a differential or + - ``differential`` -- dictionary defining a differential or a map defining a valid differential The keys of the dictionary are generators of the algebra, and @@ -2009,7 +2007,7 @@ def degree(self, total=False): raise ValueError("the zero element does not have a well-defined degree") degrees = self.parent()._degrees_multi n = self.parent().ngens() - exps = self.lift().dict().keys() + exps = self.monomial_coefficients().keys() l = [sum(exp[i] * degrees[i] for i in range(n)) for exp in exps] if len(set(l)) == 1: return l[0] @@ -2091,7 +2089,7 @@ def __classcall__(cls, A, differential): def __init__(self, A, differential): """ - Initialize ``self`` + Initialize ``self``. INPUT: @@ -2137,7 +2135,7 @@ def cdg_algebra(self, differential): INPUT: - - ``differential`` -- a dictionary defining a differential or + - ``differential`` -- dictionary defining a differential or a map defining a valid differential The keys of the dictionary are generators of the algebra, and @@ -2172,7 +2170,6 @@ def cdg_algebra(self, differential): y --> 0 z --> 0 t --> 0 - """ return self.graded_commutative_algebra().cdg_algebra(differential) @@ -2225,7 +2222,7 @@ def quotient(self, I, check=True): - ``I`` -- a two-sided homogeneous ideal of this algebra - - ``check`` -- (default: ``True``) if ``True``, check whether + - ``check`` -- boolean (default: ``True``); if ``True``, check whether ``I`` is generated by homogeneous elements EXAMPLES:: @@ -2289,11 +2286,11 @@ def differential(self, x=None): def coboundaries(self, n): """ - The ``n``-th coboundary group of the algebra. + The `n`-th coboundary group of the algebra. This is a vector space over the base field `F`, and it is returned as a subspace of the vector space `F^d`, where the - ``n``-th homogeneous component has dimension `d`. + `n`-th homogeneous component has dimension `d`. INPUT: @@ -2318,11 +2315,11 @@ def coboundaries(self, n): def cocycles(self, n): """ - The ``n``-th cocycle group of the algebra. + The `n`-th cocycle group of the algebra. This is a vector space over the base field `F`, and it is returned as a subspace of the vector space `F^d`, where the - ``n``-th homogeneous component has dimension `d`. + `n`-th homogeneous component has dimension `d`. INPUT: @@ -2343,7 +2340,7 @@ def cocycles(self, n): def cohomology_raw(self, n): """ - The ``n``-th cohomology group of ``self``. + The `n`-th cohomology group of ``self``. This is a vector space over the base ring, and it is returned as the quotient cocycles/coboundaries. @@ -2375,7 +2372,7 @@ def cohomology_raw(self, n): def cohomology(self, n): """ - The ``n``-th cohomology group of ``self``. + The `n`-th cohomology group of ``self``. This is a vector space over the base ring, defined as the quotient cocycles/coboundaries. The elements of the quotient @@ -2446,7 +2443,7 @@ def cohomology_generators(self, max_degree): ALGORITHM: - Reduce a basis of the `n`'th cohomology modulo all the degree `n` + Reduce a basis of the `n`-th cohomology modulo all the degree `n` products of the lower degree cohomologies. EXAMPLES:: @@ -2500,7 +2497,6 @@ def cohomology_generators(self, max_degree): sage: B = A.cdg_algebra(d) sage: B.cohomology_generators(3) {1: [e1 - e2, e3, e4], 2: [e1*e3, e1*e4]} - """ if not (max_degree in ZZ and max_degree > 0): raise ValueError('the given maximal degree must be a ' @@ -2539,14 +2535,14 @@ def vector_to_element(v, deg): def minimal_model(self, i=3, max_iterations=3, partial_result=False): r""" - Try to compute a map from a ``i``-minimal gcda that is a - ``i``-quasi-isomorphism to self. + Try to compute a map from a `i`-minimal gcda that is a + `i`-quasi-isomorphism to ``self``. INPUT: - ``i`` -- integer (default: `3`); degree to which the result is required to induce an isomorphism in cohomology, and the domain is - required to be minimal. + required to be minimal - ``max_iterations`` -- integer (default: `3`); the number of iterations of the method at each degree. If the algorithm does not @@ -2554,8 +2550,8 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): or the partial result computed up to that point is returned, deppending on the ``partial_result`` flag. - - ``partial_result`` -- boolean (default: ``False``); wether to return - the partial result if the ``max_iterations`` limit is reached. + - ``partial_result`` -- boolean (default: ``False``); whether to return + the partial result if the ``max_iterations`` limit is reached OUTPUT: @@ -2742,7 +2738,6 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): - [Fel2001]_ - [Man2019]_ - """ max_degree = int(i) if max_degree < 1: @@ -2886,12 +2881,12 @@ def extendy(phi, degree): def cohomology_algebra(self, max_degree=3): """ Compute a CDGA with trivial differential, that is isomorphic to the cohomology of - self up to``max_degree`` + ``self`` up to``max_degree`` INPUT: - ``max_degree`` -- integer (default: `3`); degree to which the result is required to - be isomorphic to self's cohomology. + be isomorphic to ``self``'s cohomology EXAMPLES:: @@ -3005,7 +3000,6 @@ def numerical_invariants(self, max_degree=3, max_iterations=3): REFERENCES: For a precise definition and properties, see [Man2019]_ . - """ self.minimal_model(max_degree, max_iterations) return {i: self._numerical_invariants[i] @@ -3324,19 +3318,19 @@ def _base_repr(self): def coboundaries(self, n, total=False): """ - The ``n``-th coboundary group of the algebra. + The `n`-th coboundary group of the algebra. This is a vector space over the base field `F`, and it is returned as a subspace of the vector space `F^d`, where the - ``n``-th homogeneous component has dimension `d`. + `n`-th homogeneous component has dimension `d`. INPUT: - ``n`` -- degree - - ``total`` (default ``False``) -- if ``True``, return the - coboundaries in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + coboundaries in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -3356,19 +3350,19 @@ def coboundaries(self, n, total=False): def cocycles(self, n, total=False): r""" - The ``n``-th cocycle group of the algebra. + The `n`-th cocycle group of the algebra. This is a vector space over the base field `F`, and it is returned as a subspace of the vector space `F^d`, where the - ``n``-th homogeneous component has dimension `d`. + `n`-th homogeneous component has dimension `d`. INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, return the - cocycles in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + cocycles in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -3388,7 +3382,7 @@ def cocycles(self, n, total=False): def cohomology_raw(self, n, total=False): """ - The ``n``-th cohomology group of the algebra. + The `n`-th cohomology group of the algebra. This is a vector space over the base ring, and it is returned as the quotient cocycles/coboundaries. @@ -3398,10 +3392,10 @@ def cohomology_raw(self, n, total=False): INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, return the - cohomology in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + cohomology in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -3430,7 +3424,7 @@ def cohomology_raw(self, n, total=False): def cohomology(self, n, total=False): """ - The ``n``-th cohomology group of the algebra. + The `n`-th cohomology group of the algebra. This is a vector space over the base ring, defined as the quotient cocycles/coboundaries. The elements of the quotient @@ -3442,10 +3436,10 @@ def cohomology(self, n, total=False): INPUT: - ``n`` -- degree - - ``total`` -- (default: ``False``) if ``True``, return the - cohomology in total degree ``n`` + - ``total`` -- boolean (default: ``False``); if ``True``, return the + cohomology in total degree `n` - If ``n`` is an integer rather than a multi-index, then the + If `n` is an integer rather than a multi-index, then the total degree is used in that case as well. EXAMPLES:: @@ -3506,7 +3500,7 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, - ``ring`` -- a graded commutative algebra - - ``relations`` -- a list or tuple of elements of ``ring`` + - ``relations`` -- list or tuple of elements of ``ring`` EXAMPLES: @@ -3733,7 +3727,7 @@ def __init__(self, parent, im_gens, check=True): Defn: (x, y) --> (x, x) sage: f.is_graded() False - sage: TestSuite(f).run(skip="_test_category") + sage: TestSuite(f).run(skip='_test_category') Since `x^2=0` but `y^2 \neq 0`, the following does not define a valid morphism:: @@ -3795,7 +3789,6 @@ def __init__(self, parent, im_gens, check=True): Graded Commutative Algebra endomorphism of Graded Commutative Algebra with generators ('e1',) in degrees (1,) over Rational Field Defn: (e1,) --> (2*e1,) - """ domain = parent.domain() codomain = parent.codomain() @@ -3875,7 +3868,7 @@ def _call_(self, x): """ codomain = self.codomain() result = codomain.zero() - for mono, coeff in x.dict().items(): + for mono, coeff in x.monomial_coefficients().items(): term = prod([gen**y for (y, gen) in zip(mono, self.im_gens())], codomain.one()) result += coeff * term @@ -3891,7 +3884,7 @@ def is_graded(self, total=False): INPUT: - - ``total`` (default: ``False``) -- if ``True``, use + - ``total`` -- boolean (default: ``False``); if ``True``, use the total degree to determine whether the morphism is graded (relevant only in the multigraded case) @@ -4116,7 +4109,6 @@ class CohomologyClass(SageObject, CachedRepresentation): e5 --> e1*e2 e6 --> e1*e2 + e3*e4 Defn: (x1_0, x1_1, x1_2, x1_3, y1_0, y1_1) --> (e1, e2, e3, e4, e5, -e5 + e6) - """ def __init__(self, x, cdga=None): """ @@ -4188,7 +4180,7 @@ def exterior_algebra_basis(n, degrees): - ``degrees`` -- iterable of integers Return list of lists, each list representing exponents for the - corresponding generators. (So each list consists of 0's and 1's.) + corresponding generators. (So each list consists of 0s and 1s.) EXAMPLES:: @@ -4230,7 +4222,7 @@ def total_degree(deg): INPUT: - - ``deg`` -- an element of a free abelian group. + - ``deg`` -- an element of a free abelian group In fact, ``deg`` could be an integer, a Python int, a list, a tuple, a vector, etc. This function returns the sum of the diff --git a/src/sage/algebras/down_up_algebra.py b/src/sage/algebras/down_up_algebra.py index 7b43db7b3a5..1bb35730014 100644 --- a/src/sage/algebras/down_up_algebra.py +++ b/src/sage/algebras/down_up_algebra.py @@ -100,7 +100,7 @@ class DownUpAlgebra(CombinatorialFreeModule): b*u^2*d + a*u*(d*u) + g*u We verify some examples of Proposition 3.5 in [BR1998]_, which states - that the 0-th degree part is commutative:: + that the `0`-th degree part is commutative:: sage: DU0 = [u^i * (d*u)^j * d^i for i,j in ....: cartesian_product([range(3), range(3)])] diff --git a/src/sage/algebras/exterior_algebra_groebner.pyx b/src/sage/algebras/exterior_algebra_groebner.pyx index d296bae64f3..9704bcbbfb0 100644 --- a/src/sage/algebras/exterior_algebra_groebner.pyx +++ b/src/sage/algebras/exterior_algebra_groebner.pyx @@ -57,7 +57,7 @@ cdef class GBElement: sage: from sage.algebras.exterior_algebra_groebner import GBElement sage: E. = ExteriorAlgebra(QQ) sage: X = GBElement(a, a.leading_support(), 1) - sage: TestSuite(X).run(skip="_test_pickling") + sage: TestSuite(X).run(skip='_test_pickling') """ self.elt = x self.ls = ls @@ -114,9 +114,9 @@ cdef class GroebnerStrategy: sage: from sage.algebras.exterior_algebra_groebner import GroebnerStrategy sage: E. = ExteriorAlgebra(QQ) - sage: I = E.ideal([a + 1], side="left") + sage: I = E.ideal([a + 1], side='left') sage: G = GroebnerStrategy(I) - sage: TestSuite(G).run(skip="_test_pickling") + sage: TestSuite(G).run(skip='_test_pickling') """ self.ideal = I self.groebner_basis = (None,) @@ -293,18 +293,18 @@ cdef class GroebnerStrategy: EXAMPLES:: sage: E. = ExteriorAlgebra(QQ) - sage: I = E.ideal([x*y - x, x*y - 1], side="left") + sage: I = E.ideal([x*y - x, x*y - 1], side='left') sage: I.groebner_basis() # indirect doctest (1,) - sage: J = E.ideal([x*y - x, 2*x*y - 2], side="left") + sage: J = E.ideal([x*y - x, 2*x*y - 2], side='left') sage: J.groebner_basis() # indirect doctest (1,) sage: E. = ExteriorAlgebra(QQ) - sage: I = E.ideal([a+b*c], side="left") + sage: I = E.ideal([a+b*c], side='left') sage: I.groebner_basis() # indirect doctest (b*c + a,) - sage: I = E.ideal([a+b*c], side="twosided") + sage: I = E.ideal([a+b*c], side='twosided') sage: I.groebner_basis() # indirect doctest (a*b, a*c, b*c + a, a*d) """ @@ -373,7 +373,7 @@ cdef class GroebnerStrategy: else: constructed[f0.lsi] = set([f0]) G.append(f0) - # Find the degress of the new pairs + # Find the degrees of the new pairs for j in range(n, len(G)): f1 = G[j] p1 = f1.ls diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index 4779f1ba1dd..3ba4bc658cb 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -1,7 +1,7 @@ """ Finite-Dimensional Algebras """ -#***************************************************************************** +# *************************************************************************** # Copyright (C) 2011 Johan Bosman # Copyright (C) 2011, 2013 Peter Bruin # Copyright (C) 2011 Michiel Kosters @@ -9,8 +9,8 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# http:s//www.gnu.org/licenses/ +# *************************************************************************** from .finite_dimensional_algebra_element import FiniteDimensionalAlgebraElement from .finite_dimensional_algebra_ideal import FiniteDimensionalAlgebraIdeal @@ -20,15 +20,15 @@ from sage.categories.magmatic_algebras import MagmaticAlgebras from sage.matrix.constructor import matrix from sage.structure.element import Matrix -from sage.rings.ring import Algebra from sage.structure.category_object import normalize_names +from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.misc.cachefunc import cached_method from functools import reduce -class FiniteDimensionalAlgebra(UniqueRepresentation, Algebra): +class FiniteDimensionalAlgebra(UniqueRepresentation, Parent): r""" Create a finite-dimensional `k`-algebra from a multiplication table. @@ -36,12 +36,12 @@ class FiniteDimensionalAlgebra(UniqueRepresentation, Algebra): - ``k`` -- a field - - ``table`` -- a list of matrices + - ``table`` -- list of matrices - - ``names`` -- (default: ``'e'``) string; names for the basis + - ``names`` -- string (default: ``'e'``); names for the basis elements - - ``assume_associative`` -- (default: ``False``) boolean; if + - ``assume_associative`` -- boolean (default: ``False``); if ``True``, then the category is set to ``category.Associative()`` and methods requiring associativity assume this @@ -187,7 +187,7 @@ def __init__(self, k, table, names='e', category=None): self._table = table self._assume_associative = "Associative" in category.axioms() # No further validity checks necessary! - Algebra.__init__(self, base_ring=k, names=names, category=category) + Parent.__init__(self, base=k, names=names, category=category) def _repr_(self): """ @@ -303,14 +303,14 @@ def basis(self): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) sage: A.basis() - Family (e0, e1) + Finite family {0: e0, 1: e1} """ from sage.sets.family import Family - return Family(self.gens()) + return Family({i: self.gen(i) for i in range(self.ngens())}) def __iter__(self): """ - Iterates over the elements of ``self``. + Iterate over the elements of ``self``. EXAMPLES:: @@ -439,21 +439,25 @@ def ideal(self, gens=None, given_by_matrix=False, side=None): - ``A`` -- a :class:`FiniteDimensionalAlgebra` - - ``gens`` -- (default: None); either an element of ``A`` or a - list of elements of ``A``, given as vectors, matrices, or + - ``gens`` -- (default: ``None``) either an element of `A` or a + list of elements of `A`, given as vectors, matrices, or FiniteDimensionalAlgebraElements. If ``given_by_matrix`` is ``True``, then ``gens`` should instead be a matrix whose rows - form a basis of an ideal of ``A``. + form a basis of an ideal of `A`. - ``given_by_matrix`` -- boolean (default: ``False``); if ``True``, no checking is done - ``side`` -- ignored but necessary for coercions + The algebra ``A`` has to be in the category of associative algebras. + EXAMPLES:: + sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: A.ideal(A([1,1])) Ideal (e0 + e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 @@ -748,6 +752,8 @@ def quotient_map(self, ideal): """ Return the quotient of ``self`` by ``ideal``. + ``self`` has to be in the category of associative and unital algebras. + INPUT: - ``ideal`` -- a :class:`FiniteDimensionalAlgebraIdeal` @@ -759,8 +765,10 @@ def quotient_map(self, ideal): EXAMPLES:: + sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: q0 = A.quotient_map(A.zero_ideal()); q0 Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 @@ -785,7 +793,8 @@ def quotient_map(self, ideal): v[0,p] = 1 v = self.element_class(self, v) table.append(f.solve_right(v.matrix() * f)) - B = FiniteDimensionalAlgebra(k, table) + cat = self.category() + B = FiniteDimensionalAlgebra(k, table, category=cat) return self.hom(f, codomain=B, check=False) def maximal_ideal(self): @@ -794,26 +803,31 @@ def maximal_ideal(self): .. NOTE:: - ``self`` must be unitary, commutative, associative and local - (have a unique maximal ideal). + ``self`` has to be in the category of unitary, commutative + and associative algebras as in the examples below. It must + moreover be local (have a unique maximal ideal). OUTPUT: - :class:`~sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_ideal.FiniteDimensionalAlgebraIdeal`; the unique maximal ideal of ``self``. If ``self`` is not a local - algebra, a :class:`ValueError` is raised. + algebra, a :exc:`ValueError` is raised. EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: A.maximal_ideal() # needs sage.rings.finite_rings Ideal (0, e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 + sage: cat = CommutativeAlgebras(QQ).FiniteDimensional().WithBasis() sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), - ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])], + ....: category=cat) sage: B.maximal_ideal() # needs sage.libs.pari Traceback (most recent call last): ... @@ -839,7 +853,8 @@ def primary_decomposition(self): .. NOTE:: - ``self`` must be unitary, commutative and associative. + ``self`` has to be in the category of unitary, commutative + and associative algebras as in the examples below. OUTPUT: @@ -848,8 +863,9 @@ def primary_decomposition(self): EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], category=cat) sage: A.primary_decomposition() # needs sage.rings.finite_rings [Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 @@ -857,9 +873,10 @@ def primary_decomposition(self): given by matrix [1 0] [0 1]] + sage: cat = CommutativeAlgebras(QQ).FiniteDimensional().WithBasis() sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), - ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])], category=cat) sage: B.primary_decomposition() # needs sage.libs.pari [Morphism from Finite-dimensional algebra of degree 3 over Rational Field @@ -914,14 +931,18 @@ def maximal_ideals(self): """ Return a list consisting of all maximal ideals of ``self``. + The algebra ``self`` has to be in the category of associative algebras. + EXAMPLES:: + sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], category=cat) sage: A.maximal_ideals() # needs sage.rings.finite_rings [Ideal (e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3] - sage: B = FiniteDimensionalAlgebra(QQ, []) + sage: cat = Algebras(QQ).FiniteDimensional().WithBasis() + sage: B = FiniteDimensionalAlgebra(QQ, [], category=cat) sage: B.maximal_ideals() [] """ diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index f1ad68cbe6a..cd101fb4e12 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -31,7 +31,6 @@ cpdef FiniteDimensionalAlgebraElement unpickle_FiniteDimensionalAlgebraElement(A sage: x = B([1,2,3]) sage: loads(dumps(x)) == x # indirect doctest True - """ cdef FiniteDimensionalAlgebraElement x = A.element_class.__new__(A.element_class) AlgebraElement.__init__(x, A) @@ -145,7 +144,6 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): True sage: loads(dumps(x)) is x False - """ return unpickle_FiniteDimensionalAlgebraElement, (self._parent, self._vector, self.__matrix) @@ -172,7 +170,6 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): sage: x.vector() (1, 1, 1) - """ self._parent, D = state v = D.pop('_vector') @@ -339,7 +336,7 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): def __getitem__(self, m): """ - Return the `m`-th coefficient of ``self`` + Return the `m`-th coefficient of ``self``. EXAMPLES:: diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py index 72744da3904..bba15b91366 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py @@ -1,6 +1,8 @@ # sage.doctest: needs sage.rings.finite_rings (because all doctests use GF) """ -Ideals of Finite Algebras +Ideals of Finite Dimensional Algebras + +It is necessary to use algebras in the category of associative algebras. """ # **************************************************************************** @@ -34,13 +36,15 @@ class FiniteDimensionalAlgebraIdeal(Ideal_generic): - ``A`` -- a finite-dimensional algebra - ``gens`` -- the generators of this ideal - - ``given_by_matrix`` -- (default: ``False``) whether the basis matrix is - given by ``gens`` + - ``given_by_matrix`` -- boolean (default: ``False``); whether the basis + matrix is given by ``gens`` EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: A.ideal(A([0,1])) Ideal (e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 """ @@ -48,10 +52,12 @@ def __init__(self, A, gens=None, given_by_matrix=False): """ EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.ideal(A([0,1])) - sage: TestSuite(I).run(skip="_test_category") # Currently ideals are not using the category framework + sage: TestSuite(I).run(skip='_test_category') # Currently ideals are not using the category framework """ k = A.base_ring() n = A.degree() @@ -74,12 +80,14 @@ def __init__(self, A, gens=None, given_by_matrix=False): def _richcmp_(self, other, op): r""" - Comparisons + Comparisons. TESTS:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I == J @@ -90,7 +98,8 @@ def _richcmp_(self, other, op): True sage: A2 = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: A is A2 True sage: A == A2 @@ -134,8 +143,10 @@ def __contains__(self, elt): """ EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: J = A.ideal(A([0,1])) sage: A([0,1]) in J True @@ -152,8 +163,10 @@ def basis_matrix(self): EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.ideal(A([1,1])) sage: I.basis_matrix() [1 0] @@ -168,8 +181,10 @@ def vector_space(self): EXAMPLES:: + sage: cat = CommutativeAlgebras(GF(3)).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.ideal(A([1,1])) sage: I.vector_space() Vector space of degree 2 and dimension 2 over Finite Field of size 3 diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py index 997d1376a6f..90c3ae45573 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py @@ -29,7 +29,7 @@ class FiniteDimensionalAlgebraMorphism(RingHomomorphism_im_gens): - ``f`` -- matrix of the underlying `k`-linear map - ``unitary`` -- boolean (default: ``True``); if ``True`` and ``check`` - is also ``True``, raise a :class:`ValueError` unless ``A`` and ``B`` are + is also ``True``, raise a :exc:`ValueError` unless ``A`` and ``B`` are unitary and ``f`` respects unit elements - ``check`` -- boolean (default: ``True``); check whether the given @@ -67,7 +67,7 @@ def __init__(self, parent, f, check=True, unitary=True): ....: Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = FiniteDimensionalAlgebraMorphism(H, Matrix([[1, 0]])) - sage: TestSuite(phi).run(skip="_test_category") + sage: TestSuite(phi).run(skip='_test_category') """ A = parent.domain() B = parent.codomain() @@ -84,8 +84,10 @@ def _repr_(self): r""" TESTS:: + sage: cat = CommutativeAlgebras(QQ).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.maximal_ideal() # needs sage.libs.pari sage: q = A.quotient_map(I) # needs sage.libs.pari sage: q._repr_() # needs sage.libs.pari @@ -98,8 +100,10 @@ def __call__(self, x): """ TESTS:: + sage: cat = CommutativeAlgebras(QQ).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.maximal_ideal() # needs sage.libs.pari sage: q = A.quotient_map(I) # needs sage.libs.pari sage: q(0) == 0 and q(1) == 1 # needs sage.libs.pari @@ -174,14 +178,14 @@ def inverse_image(self, I): - ``I`` -- ``FiniteDimensionalAlgebraIdeal``, an ideal of ``self.codomain()`` - OUTPUT: - - :class:`FiniteDimensionalAlgebraIdeal`, the inverse image of `I` under ``self``. + OUTPUT: :class:`FiniteDimensionalAlgebraIdeal`, the inverse image of `I` under ``self`` EXAMPLES:: + sage: cat = CommutativeAlgebras(QQ).FiniteDimensional().WithBasis() sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), - ....: Matrix([[0, 1], [0, 0]])]) + ....: Matrix([[0, 1], [0, 0]])], + ....: category=cat) sage: I = A.maximal_ideal() # needs sage.libs.pari sage: q = A.quotient_map(I) # needs sage.libs.pari sage: B = q.codomain() # needs sage.libs.pari diff --git a/src/sage/algebras/finite_dimensional_algebras/meson.build b/src/sage/algebras/finite_dimensional_algebras/meson.build new file mode 100644 index 00000000000..075f0b8cebd --- /dev/null +++ b/src/sage/algebras/finite_dimensional_algebras/meson.build @@ -0,0 +1,26 @@ +py.install_sources( + 'all.py', + 'finite_dimensional_algebra.py', + 'finite_dimensional_algebra_element.pxd', + 'finite_dimensional_algebra_ideal.py', + 'finite_dimensional_algebra_morphism.py', + subdir: 'sage/algebras/finite_dimensional_algebras', +) + +extension_data = { + 'finite_dimensional_algebra_element' : files( + 'finite_dimensional_algebra_element.pyx', + ), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras/finite_dimensional_algebras', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/algebras/finite_gca.py b/src/sage/algebras/finite_gca.py index a8702c3a47d..0caf51c8ec5 100644 --- a/src/sage/algebras/finite_gca.py +++ b/src/sage/algebras/finite_gca.py @@ -78,12 +78,12 @@ class FiniteGCAlgebra(CombinatorialFreeModule): - ``degrees`` -- (optional) a tuple or list specifying the degrees of the generators; if omitted, each generator is given degree 1, and if both ``names`` and ``degrees`` are omitted, an error is - raised. - - ``max_degree`` -- the maximal degree of the graded algebra. - - ``mul_symbol`` -- (optional) symbol used for multiplication. If omitted, - the string "*" is used. - - ``mul_latex_symbol`` -- (optional) latex symbol used for multiplication. - If omitted, the empty string is used. + raised + - ``max_degree`` -- the maximal degree of the graded algebra + - ``mul_symbol`` -- (optional) symbol used for multiplication; if omitted, + the string "*" is used + - ``mul_latex_symbol`` -- (optional) latex symbol used for multiplication; + if omitted, the empty string is used EXAMPLES:: @@ -132,7 +132,6 @@ class FiniteGCAlgebra(CombinatorialFreeModule): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6)) sage: type(A) - """ @staticmethod def __classcall_private__(cls, base, names=None, degrees=None, @@ -146,7 +145,7 @@ def __classcall_private__(cls, base, names=None, degrees=None, - ``base`` -- the base ring of the algebra - ``max_degree`` -- the maximal degree of the algebra - ``names`` -- the names of the variables; by default, set to ``x1``, - ``x2``, etc. + ``x2``, etc - ``degrees`` -- the degrees of the generators; by default, set to 1 TESTS:: @@ -155,7 +154,6 @@ def __classcall_private__(cls, base, names=None, degrees=None, sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6], max_degree=12) sage: A1 is A2 True - """ if max_degree is None: raise TypeError("max_degree must be specified") diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 00b0dfdafa7..8b73482e7bf 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -298,7 +298,6 @@ def create_key(self, base_ring, arg1=None, arg2=None, sage: FreeAlgebra.create_key(GF(5),3,'xyz', ....: implementation='letterplace', degrees=[1,2,3]) ((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5) - """ if arg1 is None and arg2 is None and names is None: # this is used for pickling @@ -411,7 +410,7 @@ class FreeAlgebra_generic(CombinatorialFreeModule): INPUT: - ``R`` -- a ring - - ``n`` -- an integer + - ``n`` -- integer - ``names`` -- the generator names - ``degrees`` -- (optional) a tuple or list specifying the degrees of all the generators, if omitted, the algebra is not @@ -652,7 +651,7 @@ def exp_to_monomial(T): return M([(i % ngens, Ti) for i, Ti in enumerate(T) if Ti]) return self.element_class(self, {exp_to_monomial(T): c - for T, c in x.letterplace_polynomial().dict().items()}) + for T, c in x.letterplace_polynomial().monomial_coefficients().items()}) # ok, not a free algebra element (or should not be viewed as one). if isinstance(x, str): from sage.misc.sage_eval import sage_eval @@ -751,6 +750,29 @@ def _coerce_map_from_(self, R): return self.base_ring().has_coerce_map_from(R) + def _is_valid_homomorphism_(self, other, im_gens, base_map=None): + """ + Check that the number of given images is correct. + + EXAMPLES:: + + sage: ring = algebras.Free(QQ, ['a', 'b']) + sage: a, b = ring.gens() + sage: A = matrix(QQ, 2, 2, [1, 5, 1, 5]) + sage: B = matrix(QQ, 2, 2, [1, 4, 9, 2]) + sage: C = matrix(QQ, 2, 2, [1, 7, 8, 9]) + sage: f = ring.hom([A, B]) + sage: f(a*b+1) + [47 14] + [46 15] + + sage: ring.hom([A, B, C]) + Traceback (most recent call last): + ... + ValueError: number of images must equal number of generators + """ + return len(im_gens) == self.__ngens + def gen(self, i): """ The ``i``-th generator of the algebra. @@ -892,7 +914,7 @@ def g_algebra(self, relations, names=None, order='degrevlex', check=True): """ The `G`-Algebra derived from this algebra by relations. - By default is assumed, that two variables commute. + By default it is assumed that any two variables commute. .. TODO:: @@ -935,6 +957,7 @@ def g_algebra(self, relations, names=None, order='degrevlex', check=True): (-t)*x*y + t*y + (t + 1) """ from sage.matrix.constructor import Matrix + commutative = not relations base_ring = self.base_ring() polynomial_ring = PolynomialRing(base_ring, self.gens()) @@ -970,7 +993,7 @@ def g_algebra(self, relations, names=None, order='degrevlex', check=True): from sage.rings.polynomial.plural import g_Algebra return g_Algebra(base_ring, cmat, dmat, names=names or self.variable_names(), - order=order, check=check) + order=order, check=check, commutative=commutative) def poincare_birkhoff_witt_basis(self): """ diff --git a/src/sage/algebras/free_algebra_element.py b/src/sage/algebras/free_algebra_element.py index 9fe2dcfb554..db8880eb262 100644 --- a/src/sage/algebras/free_algebra_element.py +++ b/src/sage/algebras/free_algebra_element.py @@ -84,7 +84,7 @@ def __init__(self, A, x): def _repr_(self): """ - Return string representation of self. + Return string representation of ``self``. EXAMPLES:: @@ -98,7 +98,6 @@ def _repr_(self): sage: with localvars(A, ['a','b','c']): ....: print(-x+3*y*z) -a + 3*b*c - """ v = sorted(self._monomial_coefficients.items()) P = self.parent() @@ -110,7 +109,7 @@ def _repr_(self): def _latex_(self): r""" - Return latex representation of self. + Return latex representation of ``self``. EXAMPLES:: @@ -280,6 +279,32 @@ def _acted_upon_(self, scalar, self_on_left=False): # _lmul_ = _acted_upon_ # _rmul_ = _acted_upon_ + def _im_gens_(self, codomain, im_gens, base_map): + """ + Apply a morphism defined by its values on the generators. + + EXAMPLES:: + + sage: ring = algebras.Free(QQ, ['a', 'b']) + sage: a, b = ring.gens() + sage: A = matrix(QQ, 2, 2, [2, 3, 4, 1]) + sage: B = matrix(QQ, 2, 2, [1, 7, 7, 1]) + sage: f = ring.hom([A, B]) + sage: f(a*b+1) + [24 17] + [11 30] + """ + n = self.parent().ngens() + if n == 0: + cf = next(iter(self._monomial_coefficients.values())) + return codomain.coerce(cf) + + if base_map is None: + base_map = codomain + + return codomain.sum(base_map(c) * m(*im_gens) + for m, c in self._monomial_coefficients.items()) + def variables(self): """ Return the variables used in ``self``. diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index df19a18e3e8..2d54b35a8e1 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -226,7 +226,7 @@ def gen(self, i): sage: H.gen(2) k - An :class:`IndexError` is raised if an invalid generator is requested:: + An :exc:`IndexError` is raised if an invalid generator is requested:: sage: H.gen(3) Traceback (most recent call last): diff --git a/src/sage/algebras/free_algebra_quotient_element.py b/src/sage/algebras/free_algebra_quotient_element.py index 0523ff4b9dc..b594cc65dec 100644 --- a/src/sage/algebras/free_algebra_quotient_element.py +++ b/src/sage/algebras/free_algebra_quotient_element.py @@ -189,7 +189,7 @@ def _richcmp_(self, right, op): def __neg__(self): """ - Return negative of self. + Return negative of ``self``. EXAMPLES:: diff --git a/src/sage/algebras/free_zinbiel_algebra.py b/src/sage/algebras/free_zinbiel_algebra.py index 720ee803d9b..875fde1fba9 100644 --- a/src/sage/algebras/free_zinbiel_algebra.py +++ b/src/sage/algebras/free_zinbiel_algebra.py @@ -535,7 +535,7 @@ def _coerce_map_from_(self, R): The things that coerce into ``self`` are - free Zinbiel algebras whose set `E` of labels is - a subset of the corresponding self of ``set`, and whose base + a subset of the corresponding ``self`` of ``set``, and whose base ring has a coercion map into ``self.base_ring()`` EXAMPLES:: diff --git a/src/sage/algebras/fusion_rings/f_matrix.py b/src/sage/algebras/fusion_rings/f_matrix.py index 5db72154d0d..b832a520fec 100644 --- a/src/sage/algebras/fusion_rings/f_matrix.py +++ b/src/sage/algebras/fusion_rings/f_matrix.py @@ -54,9 +54,9 @@ class FMatrix(SageObject): (see :meth:`FusionRing.fusion_labels`) - ``var_prefix`` -- (optional) a string indicating the desired prefix for variables denoting F-symbols to be solved - - ``inject_variables`` -- (default: ``False``) a boolean indicating - whether to inject variables (:class:`FusionRing` basis element - labels and F-symbols) into the global namespace + - ``inject_variables`` -- boolean (default: ``False``); whether to inject + variables (:class:`FusionRing` basis element labels and F-symbols) into + the global namespace The :class:`FusionRing` or Verlinde algebra is the Grothendieck ring of a modular tensor category [BaKi2001]_. @@ -189,7 +189,7 @@ class FMatrix(SageObject): sage: f.f_from(s, s, s, s), f.f_to(s, s, s, s) ([i0, p], [i0, p]) - The last two statments show that the possible values of + The last two statements show that the possible values of `X` and `Y` when `A = B = C = D = s` are `i_0` and `p`. The F-matrix is computed by solving the so-called @@ -263,14 +263,14 @@ class FMatrix(SageObject): sage: f.field() # long time Algebraic Field """ - def __init__(self, fusion_ring, fusion_label="f", var_prefix='fx', inject_variables=False): + def __init__(self, fusion_ring, fusion_label='f', var_prefix='fx', inject_variables=False): r""" Initialize ``self``. EXAMPLES:: sage: f = FusionRing("B3", 2).get_fmatrix() - sage: TestSuite(f).run(skip="_test_pickling") + sage: TestSuite(f).run(skip='_test_pickling') """ self._FR = fusion_ring if inject_variables and (self._FR._fusion_labels is None): @@ -472,7 +472,7 @@ def fmatrix(self, a, b, c, d): EXAMPLES:: - sage: fr = FusionRing("A1", 2, fusion_labels="c", inject_variables=True) + sage: fr = FusionRing("A1", 2, fusion_labels='c', inject_variables=True) sage: f = fr.get_fmatrix(new=True) sage: f.fmatrix(c1, c1, c1, c1) [fx0 fx1] @@ -606,7 +606,7 @@ def f_from(self, a, b, c, d): EXAMPLES:: - sage: fr = FusionRing("A1", 3, fusion_labels="a", inject_variables=True) + sage: fr = FusionRing("A1", 3, fusion_labels='a', inject_variables=True) sage: f = fr.get_fmatrix() sage: f.fmatrix(a1, a1, a2, a2) [fx6 fx7] @@ -739,7 +739,7 @@ def get_qqbar_embedding(self): EXAMPLES:: sage: fr = FusionRing("G2", 1) - sage: f = fr.get_fmatrix(fusion_label="g", inject_variables=True, new=True) + sage: f = fr.get_fmatrix(fusion_label='g', inject_variables=True, new=True) creating variables fx1..fx5 Defining fx0, fx1, fx2, fx3, fx4 sage: f.find_orthogonal_solution() @@ -822,7 +822,7 @@ def get_fvars_in_alg_field(self): EXAMPLES:: sage: fr = FusionRing("G2", 1) - sage: f = fr.get_fmatrix(fusion_label="g", inject_variables=True, new=True) + sage: f = fr.get_fmatrix(fusion_label='g', inject_variables=True, new=True) creating variables fx1..fx5 Defining fx0, fx1, fx2, fx3, fx4 sage: f.find_orthogonal_solution(verbose=False) @@ -919,7 +919,7 @@ def get_fvars_by_size(self, n, indices=False): INPUT: - - `n` -- a positive integer + - ``n`` -- positive integer - ``indices`` -- boolean (default: ``False``) If ``indices`` is ``False`` (default), @@ -974,7 +974,7 @@ def save_fvars(self, filename): INPUT: - - ``filename`` -- a string specifying the name of the pickle file + - ``filename`` -- string specifying the name of the pickle file to be used The current directory is used unless an absolute path to a file in @@ -1087,7 +1087,7 @@ def _checkpoint(self, do_chkpt, status, verbose=True): Checkpoint 2 reached! sage: del f sage: f = FusionRing("A1", 3).get_fmatrix(new=True) - sage: f.find_orthogonal_solution(warm_start="fmatrix_solver_checkpoint_A13.pickle") + sage: f.find_orthogonal_solution(warm_start='fmatrix_solver_checkpoint_A13.pickle') Computing F-symbols for The Fusion Ring of Type A1 and level 3 with Integer Ring coefficients with 71 variables... Set up 121 reduced pentagons... Elimination epoch completed... 18 eqns remain in ideal basis @@ -1123,7 +1123,7 @@ def _checkpoint(self, do_chkpt, status, verbose=True): Checkpoint 4 reached! sage: del f sage: f = FusionRing("A1", 2).get_fmatrix(new=True) - sage: f.find_orthogonal_solution(warm_start="fmatrix_solver_checkpoint_A12.pickle") + sage: f.find_orthogonal_solution(warm_start='fmatrix_solver_checkpoint_A12.pickle') Computing F-symbols for The Fusion Ring of Type A1 and level 2 with Integer Ring coefficients with 14 variables... Partitioned 0 equations into 0 components of size: [] @@ -1189,10 +1189,10 @@ def _restore_state(self, filename): TESTS:: sage: f = FusionRing("A1", 3).get_fmatrix(new=True) - sage: f.find_orthogonal_solution(save_results="test.pickle", verbose=False) # long time + sage: f.find_orthogonal_solution(save_results='test.pickle', verbose=False) # long time sage: del f sage: f = FusionRing("A1", 3).get_fmatrix(new=True) - sage: f.find_orthogonal_solution(warm_start="test.pickle") # long time + sage: f.find_orthogonal_solution(warm_start='test.pickle') # long time sage: f._chkpt_status == 7 # long time True sage: os.remove("test.pickle") # long time @@ -1227,14 +1227,11 @@ def start_worker_pool(self, processes=None): INPUT: - - ``processes`` -- an integer indicating the number of workers - in the pool; if left unspecified, the number of workers is + - ``processes`` -- integer indicating the number of workers + in the pool; if left unspecified, the number of workers equals the number of processors available - OUTPUT: - - This method returns a boolean indicating whether a worker pool - was successfully initialized. + OUTPUT: boolean; whether a worker pool was successfully initialized EXAMPLES:: @@ -1399,7 +1396,7 @@ def get_orthogonality_constraints(self, output=True): INPUT: - - ``output`` -- a boolean + - ``output`` -- boolean OUTPUT: @@ -1445,7 +1442,7 @@ def get_defining_equations(self, option, output=True): INPUT: - - ``option`` -- a string determining equations to be set up: + - ``option`` -- string determining equations to be set up: * ``'hexagons'`` -- get equations imposed on the F-matrix by the hexagon relations in the definition of a braided category @@ -1453,7 +1450,7 @@ def get_defining_equations(self, option, output=True): * ``'pentagons'`` -- get equations imposed on the F-matrix by the pentagon relations in the definition of a monoidal category - - ``output`` -- (default: ``True``) a boolean indicating whether + - ``output`` -- boolean (default: ``True``); whether results should be returned, where the equations will be polynomials. Otherwise, the constraints are appended to ``self.ideal_basis``. Constraints are stored in the internal tuple representation. The @@ -1621,7 +1618,7 @@ def equations_graph(self, eqns=None): INPUT: - - ``eqns`` -- a list of polynomials + - ``eqns`` -- list of polynomials Each polynomial is either an object in the ring returned by :meth:`get_poly_ring` or it is a tuple of pairs representing @@ -1727,7 +1724,7 @@ def _partition_eqns(self, eqns=None, verbose=True): print(graph.connected_components_sizes()) return partition - def _par_graph_gb(self, eqns=None, term_order="degrevlex", largest_comp=45, verbose=True): + def _par_graph_gb(self, eqns=None, term_order='degrevlex', largest_comp=45, verbose=True): r""" Compute a Groebner basis for a list of equations partitioned according to their corresponding graph. @@ -1783,8 +1780,8 @@ def _get_component_variety(self, var, eqns): INPUT: - - ``var`` -- a list of variable indices - - ``eqns`` -- a list of polynomial equations in the internal + - ``var`` -- list of variable indices + - ``eqns`` -- list of polynomial equations in the internal tuple of pairs representation EXAMPLES:: @@ -1992,14 +1989,14 @@ def _get_explicit_solution(self, eqns=None, verbose=True): if self._FR._basecoer: self._FR.r_matrix.clear_cache() - def find_orthogonal_solution(self, checkpoint=False, save_results="", warm_start="", use_mp=True, verbose=True): + def find_orthogonal_solution(self, checkpoint=False, save_results='', warm_start='', use_mp=True, verbose=True): r""" Solve the the hexagon and pentagon relations, along with orthogonality constraints, to evaluate an orthogonal F-matrix. INPUT: - - ``checkpoint`` -- (default: ``False``) a boolean indicating whether + - ``checkpoint`` -- boolean (default: ``False``); whether the computation should be checkpointed. Depending on the associated ``CartanType``, the computation may take hours to complete. For large examples, checkpoints are recommended. This method supports @@ -2029,13 +2026,13 @@ def find_orthogonal_solution(self, checkpoint=False, save_results="", warm_start If no file name is provided, the calculation begins from scratch. - - ``use_mp`` -- (default: ``True``) a boolean indicating whether to use + - ``use_mp`` -- boolean (default: ``True``); whether to use multiprocessing to speed up calculation. The default value ``True`` is highly recommended, since parallel processing yields results much more quickly. - - ``verbose`` -- (default: ``True``) a boolean indicating whether the - solver should print out intermediate progress reports. + - ``verbose`` -- boolean (default: ``True``); whether the + solver should print out intermediate progress reports OUTPUT: @@ -2045,7 +2042,7 @@ def find_orthogonal_solution(self, checkpoint=False, save_results="", warm_start EXAMPLES:: - sage: f = FusionRing("B5", 1).get_fmatrix(fusion_label="b", inject_variables=True) + sage: f = FusionRing("B5", 1).get_fmatrix(fusion_label='b', inject_variables=True) creating variables fx1..fx14 Defining fx0, fx1, fx2, fx3, fx4, fx5, fx6, fx7, fx8, fx9, fx10, fx11, fx12, fx13 sage: f.find_orthogonal_solution() @@ -2150,7 +2147,7 @@ def find_orthogonal_solution(self, checkpoint=False, save_results="", warm_start # Set up new equations graph and compute variety for each component if self._chkpt_status < 5: - self.ideal_basis = self._par_graph_gb(term_order="lex", verbose=verbose) + self.ideal_basis = self._par_graph_gb(term_order='lex', verbose=verbose) self.ideal_basis.sort(key=poly_tup_sortkey) self._triangular_elim(verbose=verbose) self._checkpoint(checkpoint, 5, verbose=verbose) @@ -2271,7 +2268,7 @@ def _update_equations(self): self.ideal_basis = {eq.subs(special_values) for eq in self.ideal_basis} self.ideal_basis.discard(0) - def find_cyclotomic_solution(self, equations=None, algorithm="", verbose=True, output=False): + def find_cyclotomic_solution(self, equations=None, algorithm='', verbose=True, output=False): r""" Solve the hexagon and pentagon relations to evaluate the F-matrix. @@ -2286,14 +2283,14 @@ def find_cyclotomic_solution(self, equations=None, algorithm="", verbose=True, o - ``equations`` -- (optional) a set of equations to be solved; defaults to the hexagon and pentagon equations - ``algorithm`` -- (optional) algorithm to compute Groebner Basis - - ``output`` -- (default: ``False``) output a dictionary of + - ``output`` -- boolean (default: ``False``); output a dictionary of F-matrix values; this may be useful to see but may be omitted since this information will be available afterwards via the :meth:`fmatrix` and :meth:`fmat` methods. EXAMPLES:: - sage: fr = FusionRing("A2", 1, fusion_labels="a", inject_variables=True) + sage: fr = FusionRing("A2", 1, fusion_labels='a', inject_variables=True) sage: f = fr.get_fmatrix(inject_variables=True) creating variables fx1..fx8 Defining fx0, fx1, fx2, fx3, fx4, fx5, fx6, fx7 @@ -2427,7 +2424,7 @@ def certify_pentagons(self, use_mp=True, verbose=False): Partitioned 6 equations into 6 components of size: [1, 1, 1, 1, 1, 1] Computing appropriate NumberField... - sage: f.certify_pentagons() is None # not tested (long time ~1.5s, cypari issue in doctesting framework) + sage: f.certify_pentagons() is None # not tested (cypari issue in doctesting framework), long time (~1.5s) True """ fvars_copy = deepcopy(self._fvars) diff --git a/src/sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx b/src/sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx index a9b7eb50fab..ba2a626c9f0 100644 --- a/src/sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +++ b/src/sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx @@ -273,7 +273,7 @@ cdef get_reduced_hexagons(factory, tuple mp_params): if i % n_proc == child_id: he = req_cy(basis, r_matrix, fvars, _Nk_ij, id_anyon, sextuple) if he: - red = reduce_poly_dict(he.dict(), _nnz, _ks, one) + red = reduce_poly_dict(he.monomial_coefficients(), _nnz, _ks, one) # Avoid pickling cyclotomic coefficients red = _flatten_coeffs(red) @@ -341,7 +341,7 @@ cdef get_reduced_pentagons(factory, tuple mp_params): if i % n_proc == child_id: pe = feq_cy(basis, fvars, _Nk_ij, id_anyon, zero, nonuple, prune=True) if pe: - red = reduce_poly_dict(pe.dict(), _nnz, _ks, one) + red = reduce_poly_dict(pe.monomial_coefficients(), _nnz, _ks, one) # Avoid pickling cyclotomic coefficients red = _flatten_coeffs(red) @@ -399,14 +399,14 @@ cdef list compute_gb(factory, tuple args): cdef MPolynomialRing_libsingular R = PolynomialRing(factory._FR.field(), len(sorted_vars), 'a', order=term_order) # Zip tuples into R and compute Groebner basis - cdef idx_map = {old : new for new, old in enumerate(sorted_vars)} + cdef idx_map = {old: new for new, old in enumerate(sorted_vars)} nvars = len(sorted_vars) F = factory.field() cdef list polys = list() for eq_tup in eqns: eq_tup = _unflatten_coeffs(F, eq_tup) polys.append(_tup_to_poly(resize(eq_tup, idx_map, nvars), parent=R)) - gb = Ideal(sorted(polys)).groebner_basis(algorithm="libsingular:slimgb") + gb = Ideal(sorted(polys)).groebner_basis(algorithm='libsingular:slimgb') # Change back to fmats poly ring and append to temp_eqns cdef dict inv_idx_map = {v: k for k, v in idx_map.items()} @@ -455,12 +455,12 @@ cpdef executor(tuple params): Execute a function defined in this module (``sage.algebras.fusion_rings.fast_parallel_fmats_methods``) in a worker process, and supply the factory parameter by constructing a reference - to the ``FMatrix`` object in the worker's memory adress space from + to the ``FMatrix`` object in the worker's memory address space from its ``id``. INPUT: - - ``params`` -- a tuple ``((fn_name, fmats_id), fn_args)`` where + - ``params`` -- tuple ``((fn_name, fmats_id), fn_args)`` where ``fn_name`` is the name of the function to be executed, ``fmats_id`` is the ``id`` of the :class:`FMatrix` object, and ``fn_args`` is a tuple containing all arguments to be passed to the function ``fn_name``. diff --git a/src/sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx b/src/sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx index ad6e8a1621e..deaa4517406 100644 --- a/src/sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +++ b/src/sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx @@ -268,7 +268,7 @@ cpdef executor(tuple params): Execute a function registered in this module's ``mappers`` in a worker process, and supply the ``FusionRing`` parameter by constructing a reference to the FMatrix object in the worker's memory - adress space from its ``id``. + address space from its ``id``. .. NOTE:: @@ -310,7 +310,7 @@ cpdef _unflatten_entries(fusion_ring, list entries): Restore cyclotomic coefficient object from its tuple of rational coefficients representation. - Used to circumvent pickling issue introduced by PARI settigs + Used to circumvent pickling issue introduced by PARI settings in :issue:`30537`. EXAMPLES:: diff --git a/src/sage/algebras/fusion_rings/fusion_double.py b/src/sage/algebras/fusion_rings/fusion_double.py index 7ce086f70d0..3b681d75d3b 100644 --- a/src/sage/algebras/fusion_rings/fusion_double.py +++ b/src/sage/algebras/fusion_rings/fusion_double.py @@ -98,7 +98,7 @@ class FusionDouble(CombinatorialFreeModule): :: sage: G1 = SymmetricGroup(3) - sage: H1 = FusionDouble(G1, prefix="u", inject_variables=True) + sage: H1 = FusionDouble(G1, prefix='u', inject_variables=True) sage: F = H1.get_fmatrix() The above commands create the F-matrix. You can compute all of the @@ -131,13 +131,12 @@ class FusionDouble(CombinatorialFreeModule): EXAMPLES:: sage: G = SmallPermutationGroup(16,9) - sage: F = FusionDouble(G, prefix="b",inject_variables=True) + sage: F = FusionDouble(G, prefix='b', inject_variables=True) sage: b13^2 # long time (4s) - b0 + b2 + b4 + b15 + b16 + b17 + b18 + b24 + b26 + b27 - + b0 + b3 + b4 """ @staticmethod - def __classcall_private__(cls, G, prefix="s", inject_variables=False): + def __classcall_private__(cls, G, prefix='s', inject_variables=False): """ Normalize input to ensure a unique representation. @@ -153,7 +152,7 @@ def __classcall_private__(cls, G, prefix="s", inject_variables=False): F.inject_variables() return F - def __init__(self, G, prefix="s"): + def __init__(self, G, prefix='s'): """ EXAMPLES:: @@ -211,7 +210,7 @@ def inject_variables(self): EXAMPLES:: - sage: F = FusionDouble(DiCyclicGroup(3), prefix="d") + sage: F = FusionDouble(DiCyclicGroup(3), prefix='d') sage: F.inject_variables() sage: d0 + d1 + d5 d0 + d1 + d5 @@ -237,22 +236,22 @@ def _char_cache(self, i, g): @cached_method def s_ij(self, i, j, unitary=False, base_coercion=True): r""" - Return the element of the S-matrix of this fusion ring + Return the element of the `S`-matrix of this fusion ring corresponding to the given elements. - Without the unitary option set true, this is the unnormalized S-matrix + Without the unitary option set true, this is the unnormalized `S`-matrix entry, denoted `\tilde{s}_{ij}`, in [BaKi2001]_ Chapter 3. The - normalized S-matrix entries are denoted `s_{ij}`. + normalized `S`-matrix entries are denoted `s_{ij}`. INPUT: - ``i``, ``j``, -- a pair of basis elements - - ``unitary`` -- (default: ``False``) set to ``True`` to obtain - the unitary S-matrix + - ``unitary`` -- boolean (default: ``False``); set to ``True`` to + obtain the unitary `S`-matrix EXAMPLES:: - sage: D = FusionDouble(SymmetricGroup(3), prefix="t", inject_variables=True) + sage: D = FusionDouble(SymmetricGroup(3), prefix='t', inject_variables=True) sage: [D.s_ij(t2, x) for x in D.basis()] [2, 2, 4, 0, 0, -2, -2, -2] sage: [D.s_ij(t2, x, unitary=True) for x in D.basis()] @@ -280,7 +279,7 @@ def s_ij(self, i, j, unitary=False, base_coercion=True): def s_ijconj(self, i, j, unitary=False, base_coercion=True): r""" - Return the conjugate of the element of the S-matrix given by + Return the conjugate of the element of the `S`-matrix given by ``self.s_ij(elt_i, elt_j, base_coercion=base_coercion)``. .. SEEALSO:: @@ -289,7 +288,7 @@ def s_ijconj(self, i, j, unitary=False, base_coercion=True): EXAMPLES:: - sage: P=FusionDouble(CyclicPermutationGroup(3),prefix="p",inject_variables=True) + sage: P=FusionDouble(CyclicPermutationGroup(3),prefix='p',inject_variables=True) sage: P.s_ij(p1,p3) zeta3 sage: P.s_ijconj(p1,p3) @@ -299,12 +298,12 @@ def s_ijconj(self, i, j, unitary=False, base_coercion=True): def s_matrix(self, unitary=False, base_coercion=True): r""" - Return the S-matrix of this fusion ring. + Return the `S`-matrix of this fusion ring. OPTIONAL: - - ``unitary`` -- (default: ``False``) set to ``True`` to obtain - the unitary S-matrix + - ``unitary`` -- boolean (default: ``False``); set to ``True`` to + obtain the unitary `S`-matrix Without the ``unitary`` parameter, this is the matrix denoted `\widetilde{s}` in [BaKi2001]_. @@ -329,7 +328,6 @@ def s_matrix(self, unitary=False, base_coercion=True): [ 1/3 1/3 -1/3 0 0 2/3 -1/3 -1/3] [ 1/3 1/3 -1/3 0 0 -1/3 -1/3 2/3] [ 1/3 1/3 -1/3 0 0 -1/3 2/3 -1/3] - """ b = self.basis() S = matrix([[self.s_ij(b[x], b[y], unitary=unitary, base_coercion=base_coercion) @@ -349,11 +347,11 @@ def N_ijk(self, i, j, k): where `s_0` is the unit element (assuming ``prefix='s'``). Method of computation is through the Verlinde formula, - deducing the values from the known values of the S-matrix. + deducing the values from the known values of the `S`-matrix. EXAMPLES:: - sage: A = FusionDouble(AlternatingGroup(4),prefix="a",inject_variables=True) + sage: A = FusionDouble(AlternatingGroup(4),prefix='a',inject_variables=True) sage: [A.N_ijk(a10,a11,x) for x in A.basis()] [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0] @@ -379,7 +377,7 @@ def Nk_ij(self, i, j, k, use_characters=False): INPUT: - ``i``, ``j``, ``k`` -- basis elements - - ``use_characters`` -- (default: ``False``) see the algorithm + - ``use_characters`` -- boolean (default: ``False``); see the algorithm description below ALGORITHM: @@ -423,7 +421,7 @@ def Nk_ij(self, i, j, k, use_characters=False): EXAMPLES:: - sage: A = FusionDouble(AlternatingGroup(4),prefix="aa",inject_variables=True) + sage: A = FusionDouble(AlternatingGroup(4),prefix='aa',inject_variables=True) sage: [A.Nk_ij(aa8,aa10,x) for x in A.basis()] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1] @@ -473,7 +471,7 @@ def Nk_ij(self, i, j, k, use_characters=False): @cached_method def field(self): """ - Returns a cyclotomic field large enough to contain the values + Return a cyclotomic field large enough to contain the values of R-matrices and twists that can arise for this fusion ring. EXAMPLES:: @@ -546,7 +544,7 @@ def r_matrix(self, i, j, k, base_coercion=True): EXAMPLES:: - sage: C = FusionDouble(SymmetricGroup(3),prefix="c",inject_variables=True) + sage: C = FusionDouble(SymmetricGroup(3),prefix='c',inject_variables=True) sage: c4*c5 c3 + c4 sage: [C.r_matrix(c4,c5,k) for k in [c3,c4]] @@ -654,7 +652,7 @@ def one_basis(self): EXAMPLES:: - sage: FusionDouble(CyclicPermutationGroup(2), prefix="h").one() + sage: FusionDouble(CyclicPermutationGroup(2), prefix='h').one() h1 """ return self._unit_index @@ -668,7 +666,7 @@ def dual(self, i): EXAMPLES:: - sage: K = FusionDouble(CyclicPermutationGroup(3),prefix="k") + sage: K = FusionDouble(CyclicPermutationGroup(3),prefix='k') sage: [(x,K.dual(x)) for x in K.basis()] [(k0, k0), (k1, k2), @@ -693,11 +691,12 @@ def product_on_basis(self, a, b): INPUT: - - ``a`, ``b`` -- keys for the dictionary ``self._names`` representing simple objects + - ``a``, ``b`` -- keys for the dictionary ``self._names`` representing + simple objects EXAMPLES:: - sage: Q=FusionDouble(SymmetricGroup(3),prefix="q",inject_variables=True) + sage: Q=FusionDouble(SymmetricGroup(3),prefix='q',inject_variables=True) sage: q3*q4 q1 + q2 + q5 + q6 + q7 sage: Q._names @@ -744,7 +743,7 @@ def is_simple_object(self): EXAMPLES:: - sage: H = FusionDouble(CyclicPermutationGroup(2), prefix="g", inject_variables=True) + sage: H = FusionDouble(CyclicPermutationGroup(2), prefix='g', inject_variables=True) sage: [x.is_simple_object() for x in [g0, g1, g0+g1]] [True, True, False] """ @@ -762,7 +761,7 @@ class representative `g` and an irreducible character `\chi` of EXAMPLES:: sage: G = QuaternionGroup() - sage: H = FusionDouble(G, prefix="e", inject_variables=True) + sage: H = FusionDouble(G, prefix='e', inject_variables=True) sage: e10.g() (1,3)(2,4)(5,7)(6,8) sage: e10.char() @@ -784,7 +783,7 @@ class representative `g` and an irreducible character `\chi` of EXAMPLES:: sage: G = DihedralGroup(5) - sage: H = FusionDouble(G, prefix="f", inject_variables=True) + sage: H = FusionDouble(G, prefix='f', inject_variables=True) sage: f10.g() (1,2,3,4,5) sage: f10.char() @@ -854,7 +853,7 @@ def dual(self): EXAMPLES:: sage: G = CyclicPermutationGroup(4) - sage: H = FusionDouble(G, prefix="j") + sage: H = FusionDouble(G, prefix='j') sage: [x for x in H.basis() if x == x.dual()] [j0, j1, j8, j9] diff --git a/src/sage/algebras/fusion_rings/fusion_ring.py b/src/sage/algebras/fusion_rings/fusion_ring.py index 72bc0f8600c..56045d2dce6 100644 --- a/src/sage/algebras/fusion_rings/fusion_ring.py +++ b/src/sage/algebras/fusion_rings/fusion_ring.py @@ -39,21 +39,21 @@ class FusionRing(WeylCharacterRing): INPUT: - ``ct`` -- the Cartan type of a simple (finite-dimensional) Lie algebra - - ``k`` -- a nonnegative integer - - ``conjugate`` -- (default ``False``) set ``True`` to obtain + - ``k`` -- nonnegative integer + - ``conjugate`` -- (default: ``False``) set ``True`` to obtain the complex conjugate ring - - ``cyclotomic_order`` -- (default computed depending on ``ct`` and ``k``) - - ``fusion_labels`` -- (default None) either a tuple of strings to use as labels of the + - ``cyclotomic_order`` -- (default: computed depending on ``ct`` and ``k``) + - ``fusion_labels`` -- (default: ``None``) either a tuple of strings to use as labels of the basis of simple objects, or a string from which the labels will be constructed - - ``inject_variables`` -- (default ``False``): use with ``fusion_labels``. + - ``inject_variables`` -- (default: ``False``) use with ``fusion_labels``. If ``inject_variables`` is ``True``, the fusion labels will be variables that can be accessed from the command line The cyclotomic order is an integer `N` such that all computations will return elements of the cyclotomic field of `N`-th roots of unity. Normally you will never need to change this but consider changing it - if :meth:`root_of_unity` raises a :class:`ValueError`. + if :meth:`root_of_unity` raises a :exc:`ValueError`. This algebra has a basis (sometimes called *primary fields* but here called *simple objects*) indexed by the weights of level `\leq k`. @@ -136,15 +136,15 @@ class FusionRing(WeylCharacterRing): as the Grothendieck ring of a *modular tensor category* (MTC). These include twist methods :meth:`Element.twist` and :meth:`Element.ribbon` for its elements related to the ribbon structure, and the - S-matrix :meth:`s_ij`. + `S`-matrix :meth:`s_ij`. - There are two natural normalizations of the S-matrix. Both + There are two natural normalizations of the `S`-matrix. Both are explained in Chapter 3 of [BaKi2001]_. The one that is computed by the method :meth:`s_matrix`, or whose individual entries are computed by :meth:`s_ij` is denoted `\tilde{s}` in [BaKi2001]_. It is not unitary. - The unitary S-matrix is `s=D^{-1/2}\tilde{s}` where + The unitary `S`-matrix is `s=D^{-1/2}\tilde{s}` where .. MATH:: @@ -154,7 +154,7 @@ class FusionRing(WeylCharacterRing): `d_i(V)` the *quantum dimension*. We will call quantity `D` the *global quantum dimension* and `\sqrt{D}` the *total quantum order*. They are computed by :meth:`global_q_dimension` - and :meth:`total_q_order`. The unitary S-matrix `s` may be obtained + and :meth:`total_q_order`. The unitary `S`-matrix `s` may be obtained using :meth:`s_matrix` with the option ``unitary=True``. Let us check the Verlinde formula, which is [DFMS1996]_ (16.3). This @@ -166,7 +166,7 @@ class FusionRing(WeylCharacterRing): where `N^k_{ij}` are the fusion coefficients, i.e. the structure constants of the fusion ring, and ``I`` is the unit object. - The S-matrix has the property that if `i*` denotes the dual + The `S`-matrix has the property that if `i*` denotes the dual object of `i`, implemented in Sage as ``i.dual()``, then .. MATH:: @@ -180,7 +180,7 @@ class FusionRing(WeylCharacterRing): N_{ijk} = \sum_l \frac{s(i, \ell)\, s(j, \ell)\, s(k, \ell)}{s(I, \ell)}, - In this formula `s` is the normalized unitary S-matrix + In this formula `s` is the normalized unitary `S`-matrix denoted `s` in [BaKi2001]_. We may define a function that corresponds to the right-hand side, except using `\tilde{s}` instead of `s`:: @@ -257,9 +257,9 @@ class FusionRing(WeylCharacterRing): T = \begin{pmatrix} 1 & 1\\ &1 \end{pmatrix} subject to the relations `(ST)^3 = S^2`, `S^2T = TS^2`, and `S^4 = I`. - Let `s` be the normalized S-matrix, and + Let `s` be the normalized `S`-matrix, and `t` the diagonal matrix whose entries are the twists of the simple - objects. Let `s` the unitary S-matrix and `t` the matrix of twists, + objects. Let `s` the unitary `S`-matrix and `t` the matrix of twists, and `C` the conjugation matrix :meth:`conj_matrix`. Let .. MATH:: @@ -299,7 +299,7 @@ class FusionRing(WeylCharacterRing): True """ @staticmethod - def __classcall__(cls, ct, k, base_ring=ZZ, prefix=None, style="coroots", conjugate=False, cyclotomic_order=None, fusion_labels=None, inject_variables=False): + def __classcall__(cls, ct, k, base_ring=ZZ, prefix=None, style='coroots', conjugate=False, cyclotomic_order=None, fusion_labels=None, inject_variables=False): """ Normalize input to ensure a unique representation. @@ -307,7 +307,7 @@ def __classcall__(cls, ct, k, base_ring=ZZ, prefix=None, style="coroots", conjug sage: F1 = FusionRing('B3', 2) sage: F2 = FusionRing(CartanType('B3'), QQ(2), ZZ) - sage: F3 = FusionRing(CartanType('B3'), int(2), style="coroots") + sage: F3 = FusionRing(CartanType('B3'), int(2), style='coroots') sage: F1 is F2 and F2 is F3 True @@ -387,7 +387,7 @@ def test_braid_representation(self, max_strands=6, anyon=None): INPUT: - - ``max_strands`` -- (default: 6): maximum number of braid group strands + - ``max_strands`` -- (default: 6) maximum number of braid group strands - ``anyon`` -- (optional) run this test on this particular simple object Create a braid group representation using :meth:`get_braid_generators` @@ -442,8 +442,8 @@ def fusion_labels(self, labels=None, inject_variables=False): INPUT: - ``labels`` -- (default: ``None``) a list of strings or string - - ``inject_variables`` -- (default: ``False``) if ``True``, then - inject the variable names into the global namespace; note that + - ``inject_variables`` -- boolean (default: ``False``); if ``True``, + then inject the variable names into the global namespace; note that this could override objects already defined If ``labels`` is a list, the length of the list must equal the @@ -509,7 +509,7 @@ def field(self): r""" Return a cyclotomic field large enough to contain the `2 \ell`-th roots of unity, as well as - all the S-matrix entries. + all the `S`-matrix entries. EXAMPLES:: @@ -554,7 +554,7 @@ def fvars_field(self): EXAMPLES:: - sage: A13 = FusionRing("A1", 3, fusion_labels="a", inject_variables=True) + sage: A13 = FusionRing("A1", 3, fusion_labels='a', inject_variables=True) sage: A13.fvars_field() Cyclotomic Field of order 40 and degree 16 sage: A13.field() @@ -634,7 +634,6 @@ def get_order(self): is *not* cached. Caching of :meth:`CombinatorialFreeModule.get_order` causes inconsistent results after calling :meth:`CombinatorialFreeModule.set_order`. - """ if self._order is None: self.set_order(self.basis().keys().list()) @@ -774,7 +773,7 @@ def N_ijk(self, elt_i, elt_j, elt_k): This is the same as `N_{ij}^{k\ast}`, where `N_{ij}^k` are the structure coefficients of the ring (see :meth:`Nk_ij`), - and `k\ast`` denotes the dual element. The coefficient `N_{ijk}` + and `k\ast` denotes the dual element. The coefficient `N_{ijk}` is unchanged under permutations of the three basis vectors. EXAMPLES:: @@ -815,11 +814,11 @@ def Nk_ij(self, elt_i, elt_j, elt_k): @cached_method def s_ij(self, elt_i, elt_j, base_coercion=True): r""" - Return the element of the S-matrix of this fusion ring corresponding to + Return the element of the `S`-matrix of this fusion ring corresponding to the given elements. - This is the unnormalized S-matrix, denoted `\tilde{s}_{ij}` - in [BaKi2001]_ . To obtain the normalized S-matrix, divide by + This is the unnormalized `S`-matrix, denoted `\tilde{s}_{ij}` + in [BaKi2001]_ . To obtain the normalized `S`-matrix, divide by :meth:`global_q_dimension()` or use :meth:`S_matrix()` with the option ``unitary=True``. @@ -854,7 +853,7 @@ def s_ij(self, elt_i, elt_j, base_coercion=True): def s_ijconj(self, elt_i, elt_j, base_coercion=True): """ - Return the conjugate of the element of the S-matrix given by + Return the conjugate of the element of the `S`-matrix given by ``self.s_ij(elt_i, elt_j, base_coercion=base_coercion)``. See :meth:`s_ij`. @@ -895,12 +894,12 @@ def s_ijconj(self, elt_i, elt_j, base_coercion=True): def s_matrix(self, unitary=False, base_coercion=True): r""" - Return the S-matrix of this fusion ring. + Return the `S`-matrix of this fusion ring. OPTIONAL: - - ``unitary`` -- (default: ``False``) set to ``True`` to obtain - the unitary S-matrix + - ``unitary`` -- boolean (default: ``False``); set to ``True`` to + obtain the unitary `S`-matrix Without the ``unitary`` parameter, this is the matrix denoted `\widetilde{s}` in [BaKi2001]_. @@ -1114,7 +1113,7 @@ def is_multiplicity_free(self): return k <= 2 ################################### - ### Braid group representations ### + # Braid group representations # ################################### def get_computational_basis(self, a, b, n_strands): @@ -1211,9 +1210,9 @@ def _emap(self, mapper, input_args, worker_pool=None): INPUT: - - ``mapper`` -- a string specifying the name of a function defined + - ``mapper`` -- string specifying the name of a function defined in the ``fast_parallel_fusion_ring_braid_repn`` module - - ``input_args`` -- a tuple of arguments to be passed to mapper + - ``input_args`` -- tuple of arguments to be passed to mapper This method applies the mapper in parallel if a ``worker_pool`` is provided. @@ -1263,8 +1262,8 @@ def get_braid_generators(self, total_charge_anyon, n_strands, checkpoint=False, - save_results="", - warm_start="", + save_results='', + warm_start='', use_mp=True, verbose=True): r""" @@ -1277,8 +1276,8 @@ def get_braid_generators(self, - ``fusing_anyon`` -- a basis element of ``self`` - ``total_charge_anyon`` -- a basis element of ``self`` - - ``n_strands`` -- a positive integer greater than 2 - - ``checkpoint`` -- (default: ``False``) a boolean indicating + - ``n_strands`` -- positive integer greater than 2 + - ``checkpoint`` -- boolean (default: ``False``); whether the F-matrix solver should pickle checkpoints - ``save_results`` -- (optional) a string indicating the name of a file in which to pickle computed F-symbols for later use @@ -1287,10 +1286,10 @@ def get_braid_generators(self, The pickle may be a checkpoint generated by the solver, or a file containing solver results. If all F-symbols are known, we don't run the solver again. - - ``use_mp`` -- (default: ``True``) a boolean indicating whether + - ``use_mp`` -- boolean (default: ``True``); whether to use multiprocessing to speed up the computation; this is highly recommended. - - ``verbose`` -- (default: ``True``) boolean indicating whether + - ``verbose`` -- boolean (default: ``True``); whether to be verbose with the computation For more information on the optional parameters, see @@ -1398,7 +1397,7 @@ def gens_satisfy_braid_gp_rels(self, sig): EXAMPLES:: - sage: F41 = FusionRing("F4", 1, fusion_labels="f", inject_variables=True) + sage: F41 = FusionRing("F4", 1, fusion_labels='f', inject_variables=True) sage: f1*f1 f0 + f1 sage: comp, sig = F41.get_braid_generators(f1, f0, 4, verbose=False) @@ -1465,7 +1464,7 @@ def twist(self, reduced=True): INPUT: - - ``reduced`` -- (default: ``True``) boolean; if ``True`` + - ``reduced`` -- boolean (default: ``True``); if ``True`` then return the twist reduced modulo 2 EXAMPLES:: diff --git a/src/sage/algebras/fusion_rings/meson.build b/src/sage/algebras/fusion_rings/meson.build new file mode 100644 index 00000000000..281460a066a --- /dev/null +++ b/src/sage/algebras/fusion_rings/meson.build @@ -0,0 +1,47 @@ +py.install_sources( + 'all.py', + 'f_matrix.py', + 'fast_parallel_fmats_methods.pxd', + 'fast_parallel_fusion_ring_braid_repn.pxd', + 'fusion_double.py', + 'fusion_ring.py', + 'poly_tup_engine.pxd', + 'shm_managers.pxd', + subdir: 'sage/algebras/fusion_rings', +) + +extension_data = { + 'fast_parallel_fusion_ring_braid_repn' : files( + 'fast_parallel_fusion_ring_braid_repn.pyx', + ), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras/fusion_rings', + install: true, + include_directories: [inc_cpython, inc_ntl, inc_numpy, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +extension_data_cpp = { + 'fast_parallel_fmats_methods': files('fast_parallel_fmats_methods.pyx'), + 'poly_tup_engine': files('poly_tup_engine.pyx'), + 'shm_managers': files('shm_managers.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras/fusion_rings', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ntl, inc_numpy, inc_rings], + dependencies: [py_dep, cysignals, gmp, singular], + ) +endforeach + diff --git a/src/sage/algebras/fusion_rings/poly_tup_engine.pyx b/src/sage/algebras/fusion_rings/poly_tup_engine.pyx index e44fb68b836..8d6869bd484 100644 --- a/src/sage/algebras/fusion_rings/poly_tup_engine.pyx +++ b/src/sage/algebras/fusion_rings/poly_tup_engine.pyx @@ -26,7 +26,7 @@ cpdef inline tuple poly_to_tup(MPolynomial_libsingular poly): sage: poly_to_tup(x**2*y**4 - 4/5*x*y**2 + 1/3 * y) (((2, 4), 1), ((1, 2), -4/5), ((0, 1), 1/3)) """ - return tuple(poly.dict().items()) + return tuple(poly.monomial_coefficients().items()) cpdef inline MPolynomial_libsingular _tup_to_poly(tuple eq_tup, MPolynomialRing_libsingular parent): r""" @@ -93,7 +93,7 @@ cpdef tuple _unflatten_coeffs(field, tuple eq_tup): Restore cyclotomic coefficient object from its tuple of rational coefficients representation. - Used to circumvent pickling issue introduced by PARI settigs + Used to circumvent pickling issue introduced by PARI settings in :issue:`30537`. EXAMPLES:: @@ -259,7 +259,7 @@ cpdef list get_variables_degrees(list eqns, int nvars): cpdef list variables(tuple eq_tup): """ - Return indices of all variables appearing in eq_tup + Return indices of all variables appearing in ``eq_tup``. EXAMPLES:: @@ -348,9 +348,9 @@ cdef dict subs_squares(dict eq_dict, KSHandler known_sq): INPUT: - - ``eq_dict`` -- a dictionary of ``(ETuple, coeff)`` pairs representing + - ``eq_dict`` -- dictionary of ``(ETuple, coeff)`` pairs representing a polynomial - - ``known_sq`` -- a dictionary of ``(int i, NumberFieldElement a)`` pairs + - ``known_sq`` -- dictionary of ``(int i, NumberFieldElement a)`` pairs such that `x_i^2 - a = 0` OUTPUT: @@ -446,8 +446,8 @@ cpdef dict compute_known_powers(max_degs, dict val_dict, one): - ``max_deg`` -- an ``ETuple`` indicating the maximal degree of each variable - - ``val_dict`` -- a dictionary of ``(var_idx, poly_tup)`` key-value pairs - - ``poly_tup`` -- a tuple of ``(ETuple, coeff)`` pairs reperesenting a + - ``val_dict`` -- dictionary of ``(var_idx, poly_tup)`` key-value pairs + - ``poly_tup`` -- tuple of ``(ETuple, coeff)`` pairs representing a multivariate polynomial EXAMPLES:: diff --git a/src/sage/algebras/fusion_rings/shm_managers.pyx b/src/sage/algebras/fusion_rings/shm_managers.pyx index 40d2eb9c805..3ce832d499f 100644 --- a/src/sage/algebras/fusion_rings/shm_managers.pyx +++ b/src/sage/algebras/fusion_rings/shm_managers.pyx @@ -54,9 +54,9 @@ cdef class KSHandler: - ``n_slots`` -- the total number of F-symbols - ``field`` -- F-matrix's base cyclotomic field - - ``use_mp`` -- a boolean indicating whether to construct a shared - memory block to back ``self``. - - ``init_data`` -- a dictionary or :class:`KSHandler` object containing + - ``use_mp`` -- boolean indicating whether to construct a shared + memory block to back ``self`` + - ``init_data`` -- dictionary or :class:`KSHandler` object containing known squares for initialization, e.g., from a solver checkpoint - ``name`` -- the name of a shared memory object (used by child processes for attaching) @@ -177,7 +177,7 @@ cdef class KSHandler: cpdef update(self, list eqns): r""" - Update ```self``'s ``shared_memory``-backed dictionary of known + Update ``self``'s ``shared_memory``-backed dictionary of known squares. Keys are variable indices and corresponding values are the squares. @@ -301,7 +301,7 @@ cdef class KSHandler: def __reduce__(self): r""" - Provide pickling / unpickling support for ``self.`` + Provide pickling / unpickling support for ``self``. TESTS:: @@ -396,11 +396,11 @@ cdef class FvarsHandler: - ``field`` -- base field for polynomial ring - ``idx_to_sextuple`` -- map relating a single integer index to a sextuple of ``FusionRing`` elements - - ``init_data`` -- a dictionary or :class:`FvarsHandler` object containing + - ``init_data`` -- dictionary or :class:`FvarsHandler` object containing known squares for initialization, e.g., from a solver checkpoint - - ``use_mp`` -- an integer indicating the number of child processes - used for multiprocessing; if running serially, use 0. - - ``pids_name`` -- the name of a ``ShareableList`` contaning the + - ``use_mp`` -- integer indicating the number of child processes + used for multiprocessing; if running serially, use 0 + - ``pids_name`` -- the name of a ``ShareableList`` containing the process ``pid``'s for every process in the pool (including the parent process) - ``name`` -- the name of a shared memory object @@ -418,7 +418,7 @@ cdef class FvarsHandler: .. NOTE:: - If you ever encounter an :class:`OverflowError` when running the + If you ever encounter an :exc:`OverflowError` when running the :meth:`FMatrix.find_orthogonal_solution` solver, consider increasing the parameter ``n_bytes``. @@ -468,7 +468,7 @@ cdef class FvarsHandler: sage: n_proc = f.pool._processes sage: pids_name = f._pid_list.shm.name sage: fvars = FvarsHandler(8, f._field, f._idx_to_sextuple, use_mp=n_proc, pids_name=pids_name) - sage: TestSuite(fvars).run(skip="_test_pickling") + sage: TestSuite(fvars).run(skip='_test_pickling') sage: fvars.shm.unlink() sage: f.shutdown_worker_pool() """ @@ -500,7 +500,7 @@ cdef class FvarsHandler: else: self.fvars = np.ndarray((self.ngens, ), dtype=self.fvars_t) self.child_id = 0 - # Populate with initialziation data + # Populate with initialization data for sextuple, fvar in init_data.items(): if isinstance(fvar, MPolynomial_libsingular): fvar = _flatten_coeffs(poly_to_tup(fvar)) @@ -710,7 +710,7 @@ cdef class FvarsHandler: def __reduce__(self): r""" - Provide pickling / unpickling support for ``self.`` + Provide pickling / unpickling support for ``self``. TESTS:: @@ -734,7 +734,7 @@ cdef class FvarsHandler: def items(self): r""" - Iterates through key-value pairs in the data structure as if it + Iterate through key-value pairs in the data structure as if it were a Python dict. As in a Python dict, the key-value pairs are yielded in no particular diff --git a/src/sage/algebras/group_algebra.py b/src/sage/algebras/group_algebra.py index 5d9f56cd6d1..8dc952f23b9 100644 --- a/src/sage/algebras/group_algebra.py +++ b/src/sage/algebras/group_algebra.py @@ -51,8 +51,8 @@ def GroupAlgebra(G, R=IntegerRing()): INPUT: - - `G` -- a group - - `R` -- (default: `\ZZ`) a ring + - ``G`` -- a group + - ``R`` -- (default: `\ZZ`) a ring EXAMPLES: @@ -222,8 +222,9 @@ def _coerce_map_from_(self, S): hom_G = G.coerce_map_from(S_G) if hom_K is not None and hom_G is not None: return SetMorphism(S.Hom(self, category=self.category() | S.category()), - lambda x: self.sum_of_terms( (hom_G(g), hom_K(c)) for g,c in x )) + lambda x: self.sum_of_terms((hom_G(g), hom_K(c)) for g, c in x)) from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.algebras.group_algebras', 'GroupAlgebra', GroupAlgebra_class) +register_unpickle_override('sage.algebras.group_algebras', 'GroupAlgebra', + GroupAlgebra_class) diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index 84bebb13e38..bac7fa4f2fa 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -349,7 +349,7 @@ def coproduct_on_basis(self, la): S = self.tensor_square() if all(x == 1 for x in la): n = len(la) - return S.sum_of_terms([( (Partition([1]*r), Partition([1]*(n-r))), self._q**(-r*(n-r)) ) + return S.sum_of_terms([((Partition([1]*r), Partition([1]*(n-r))), self._q**(-r*(n-r))) for r in range(n+1)], distinct=True) I = HallAlgebraMonomials(self.base_ring(), self._q) @@ -482,9 +482,9 @@ def scalar(self, y): (4*q^2 + 9)/(q^2 - q) """ q = self.parent()._q - f = lambda la: ~( q**(sum(la) + 2*la.weighted_size()) + f = lambda la: ~(q**(sum(la) + 2*la.weighted_size()) * prod(prod((1 - q**-i) for i in range(1,k+1)) - for k in la.to_exp()) ) + for k in la.to_exp())) y = self.parent()(y) ret = q.parent().zero() for mx, cx in self: @@ -687,7 +687,7 @@ def coproduct_on_basis(self, a): + (q^-1)*I[1, 1] # I[1] + I[2] # I[1] + I[2, 1] # I[] """ S = self.tensor_square() - return S.prod(S.sum_of_terms([( (Partition([r]), Partition([n-r]) ), self._q**(-r*(n-r)) ) + return S.prod(S.sum_of_terms([((Partition([r]), Partition([n-r])), self._q**(-r*(n-r))) for r in range(n+1)], distinct=True) for n in a) def antipode_on_basis(self, a): diff --git a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py index 3bc2e541f7e..8d674d0aaf1 100644 --- a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py +++ b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py @@ -8,7 +8,7 @@ Soon afterwards, Broué and Malle defined analogues of the Hecke algebras for all complex reflection groups -Fix non-negative integers `r` an `n`. The Ariki-Koike algebras are +Fix nonnegative integers `r` an `n`. The Ariki-Koike algebras are deformations of the group algebra of the complex reflection group `G(r, 1, n) = \ZZ / r\ZZ \wr \mathfrak{S}_n`. If `R` is a ring containing a *Hecke parameter* `q` and *cyclotomic parameters* `u_0, \ldots, u_{r-1}` then @@ -465,7 +465,6 @@ def super_categories(self): [Category of realizations of Ariki-Koike algebra of rank 5 and order 2 with q=q and u=(u0, u1, u2, u3, u4) over ..., Category of finite dimensional algebras with basis over ...] - """ return [Realizations(self.base()), self.base()._category] @@ -739,10 +738,10 @@ def algebra_generators(self): for i in range(self._n): r = list(self._zero_tuple) # Make a copy r[i] = 1 - d['L%s' % (i+1)] = self.monomial( (tuple(r), self._one_perm) ) + d['L%s' % (i+1)] = self.monomial((tuple(r), self._one_perm)) G = self._Pn.group_generators() for i in range(1, self._n): - d['T%s' % i] = self.monomial( (self._zero_tuple, G[i]) ) + d['T%s' % i] = self.monomial((self._zero_tuple, G[i])) return Family(sorted(d), lambda i: d[i]) def T(self, i=None): @@ -897,9 +896,9 @@ def product_on_basis(self, m1, m2): # combination of standard basis elements using the method and then, # recursively, multiply on the left and right by L1 and T2, # respectively. In other words, we multiply as L1*(T1*L2)*T2. - return ( self.monomial((L1, self._one_perm)) + return (self.monomial((L1, self._one_perm)) * self._product_Tw_L(T1, L2) - * self.monomial((self._zero_tuple, T2)) ) + * self.monomial((self._zero_tuple, T2))) def _product_LTwTv(self, L, w, v): r""" @@ -935,9 +934,7 @@ def _product_LTwTv(self, L, w, v): - ``w`` -- the permutation ``w`` - ``v`` -- the permutation ``v`` - OUTPUT: - - The corresponding element represented as a ``dict``. + OUTPUT: the corresponding element represented as a ``dict`` EXAMPLES:: @@ -962,8 +959,8 @@ def _product_LTwTv(self, L, w, v): c = ret[p] # We have to flip the side due to Sage's # convention for multiplying permutations - pi = p.apply_simple_reflection(i, side="left") - if p.has_descent(i, side="left"): + pi = p.apply_simple_reflection(i, side='left') + if p.has_descent(i, side='left'): iaxpy(1, {p: c * qm1, pi: c * self._q}, temp) else: iaxpy(1, {pi: c}, temp) @@ -994,7 +991,7 @@ def _product_Tw_L(self, w, L): INPUT: - ``w`` -- a permutation - - ``L`` -- a tuple `(a_1, \ldots, a_n)` + - ``L`` -- tuple `(a_1, \ldots, a_n)` EXAMPLES:: @@ -1026,7 +1023,7 @@ def _product_Tw_L(self, w, L): iaxpy(c, self._product_LTwTv(tuple(L), self._Pn.simple_reflections()[i], v), iL) # need T_i*T_v if a < b: - Ls = [ list(L) for k in range(b-a) ] # make copies of L + Ls = [list(L) for k in range(b-a)] # make copies of L for k in range(b-a): Ls[k][i-1] = a + k Ls[k][i] = b - k @@ -1034,7 +1031,7 @@ def _product_Tw_L(self, w, L): iaxpy(1, {(tuple(l), v): c for l in Ls}, iL) elif a > b: - Ls = [ list(L) for k in range(a-b) ] # make copies of L + Ls = [list(L) for k in range(a-b)] # make copies of L for k in range(a-b): Ls[k][i-1] = b + k Ls[k][i] = a - k @@ -1113,25 +1110,26 @@ def Ltuple(a, b): # return "small" powers of the generators without change if m < self._r: - return self.monomial( (Ltuple(0, m), self._one_perm) ) + return self.monomial((Ltuple(0, m), self._one_perm)) if i > 1: si = self._Pn.simple_reflections()[i-1] qsum = self.base_ring().one() - self._q**-1 # by calling _Li_power we avoid infinite recursion here - return ( self.sum_of_terms( ((Ltuple(c, m-c), si), qsum) for c in range(1, m) ) - + self._q**-1 * self.T(i-1) * self._Li_power(i-1, m) * self.T(i-1) ) + return (self.sum_of_terms(((Ltuple(c, m-c), si), qsum) for c in range(1, m)) + + self._q**-1 * self.T(i-1) * self._Li_power(i-1, m) * self.T(i-1)) # now left with the case i = 1 and m >= r if m > self._r: return self.monomial((Ltuple(0, 1), self._one_perm)) * self._Li_power(i,m-1) z = PolynomialRing(self.base_ring(), 'DUMMY').gen() - p = list(prod(z - val for val in self._u))#[:-1] - p.pop() # remove the highest power + p = list(prod(z - val for val in self._u)) # [:-1] + p.pop() # remove the highest power zero = self.base_ring().zero() return self._from_dict({(Ltuple(0, exp), self._one_perm): -coeff - for exp,coeff in enumerate(p) if coeff != zero}, + for exp, coeff in enumerate(p) + if coeff != zero}, remove_zeros=False, coerce=False) @cached_method @@ -1297,7 +1295,7 @@ def _from_LT_basis(self, m): True """ ret = self.prod(self.L(i+1)**k for i,k in enumerate(m[0])) - return ret * self.monomial( (self._zero_tuple, m[1]) ) + return ret * self.monomial((self._zero_tuple, m[1])) @cached_method def algebra_generators(self): @@ -1340,9 +1338,9 @@ def T(self, i=None): return [self.T(j) for j in range(self._n)] if i == 0: - return self.monomial( ((1,) + self._zero_tuple[1:], self._one_perm) ) + return self.monomial(((1,) + self._zero_tuple[1:], self._one_perm)) s = self._Pn.simple_reflections() - return self.monomial( (self._zero_tuple, s[i]) ) + return self.monomial((self._zero_tuple, s[i])) @cached_method def L(self, i=None): @@ -1517,7 +1515,7 @@ def product_on_basis(self, m1, m2): return L * M * R # The current product of T's and the type A Hecke algebra - tprod = [( [(k, a) for k, a in enumerate(t2) if a != 0], {s2: one} )] + tprod = [([(k, a) for k, a in enumerate(t2) if a != 0], {s2: one})] # s1 through t2 for i in reversed(s1.reduced_word()): @@ -1557,8 +1555,8 @@ def product_on_basis(self, m1, m2): c = sprod[p] # We have to flip the side due to Sage's # convention for multiplying permutations - pj = p.apply_simple_reflection(j, side="left") - if p.has_descent(j, side="left"): + pj = p.apply_simple_reflection(j, side='left') + if p.has_descent(j, side='left'): iaxpy(1, {p: c * qm1, pj: c * self._q}, temp) else: iaxpy(1, {pj: c}, temp) @@ -1602,9 +1600,7 @@ def _T0_polynomial(self): r""" Return `p` such that `T0^{r-1} - p = \prod_{i=0}^{r-1} (T_0 - u_i)`. - OUTPUT: - - A ``dict`` representing the polynomial `p`. + OUTPUT: a ``dict`` representing the polynomial `p` EXAMPLES:: diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index 4f2a604aa8b..9aa6fa63ff2 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -314,20 +314,20 @@ def matrix(self, subdivide=False, representation_type=None, original=False): INPUT: - - ``subdivide`` -- boolean (default: ``False``): this boolean is passed + - ``subdivide`` -- boolean (default: ``False``); this boolean is passed to the block_matrix function - ``representation_type`` -- instance of enum :class:`RepresentationType`; this can be obtained by the attribute :attr:`CubicHeckeAlgebra.repr_type` of ``self``; the following values are possible: - - ``RegularLeft`` -- (regular left repr. from the above URL) - - ``RegularRight`` -- (regular right repr. from the above URL) + - ``RegularLeft`` -- (regular left repr. from the above URL) + - ``RegularRight`` -- (regular right repr. from the above URL) - ``SplitIrredChevie`` -- (split irred. repr. via CHEVIE) - - ``SplitIrredMarin`` -- (split irred. repr. from the above URL) + - ``SplitIrredMarin`` -- (split irred. repr. from the above URL) - default: ``SplitIrredChevie`` taken if GAP3 and CHEVIE are installed on the system, otherwise the default will be ``SplitIrredMarin`` - - ``original`` -- boolean (default: ``False``): if set to true the base + - ``original`` -- boolean (default: ``False``); if set to ``True`` the base ring of the matrix will be the generic base_ring resp. generic extension ring (for the split versions) of the parent of ``self`` @@ -660,13 +660,13 @@ class CubicHeckeAlgebra(CombinatorialFreeModule): - ``names`` -- string containing the names of the generators as images of the braid group generators - - ``cubic_equation_parameters`` -- tuple ``(u, v, w)`` of three elements + - ``cubic_equation_parameters`` -- tuple ``(u, v, w)`` of three elements in an integral domain used as coefficients in the cubic equation. If this argument is given the base ring will be set to the common parent of ``u, v, w``. In addition a conversion map from the generic base ring is supplied. This keyword can also be used to change the variable names of the generic base ring (see example 3 below) - - ``cubic_equation_roots`` -- tuple ``(a, b, c)`` of three elements in an + - ``cubic_equation_roots`` -- tuple ``(a, b, c)`` of three elements in an integral domain which stand for the roots of the cubic equation. If this argument is given the extension ring will be set to the common parent of ``a, b, c``. In addition a conversion map from the generic extension ring @@ -1125,11 +1125,9 @@ def check_base_ring_embedding(base_ring_embedding): ############################################################################ def _repr_(self): r""" - Return a string representation + Return a string representation. - OUTPUT: - - String describing ``self`` + OUTPUT: string describing ``self`` TESTS:: @@ -1324,7 +1322,7 @@ def get_order(self): sage: len(CHA3.get_order()) 24 """ - # The reason we have overriden this is that we have to care about + # The reason we have overridden this is that we have to care about # the dynamical growth of thefinite sub basis used for the # calculation in case of more than 4 strands. @@ -1577,7 +1575,7 @@ def product_on_basis(self, g1, g2): ############################################################################ def _basis_tietze(self): r""" - Return the complete finite sub basis as list of Tietze tuples + Return the complete finite sub basis as list of Tietze tuples. EXAMPLES:: @@ -1944,7 +1942,7 @@ def _braid_image_to_filecache(self, braid_tietze, braid_image_vect): INPUT: - - ``braid_tietze`` -- braid in Tietze form + - ``braid_tietze`` -- braid in Tietze form - ``braid_image_vect`` -- image of the given braid in ``self`` in vector representation @@ -1982,9 +1980,7 @@ def _braid_image(self, braid): - ``braid`` -- :class:`~sage.groups.braid.Braid` whose image in ``self`` should be calculated - OUTPUT: - - An instance of the element class of ``self``. + OUTPUT: an instance of the element class of ``self`` EXAMPLES:: @@ -2026,9 +2022,7 @@ def _braid_image_from_reduced_powers(self, braid_tietze): repetitions occur among the entries (i.e. ``(1, 1)`` is not allowed but ``(1, -2, 1)`` is) - OUTPUT: - - The image of the braid as an element of ``self``. + OUTPUT: the image of the braid as an element of ``self`` EXAMPLES:: @@ -2216,9 +2210,7 @@ def _braid_image_by_basis_extension(self, braid_tietze): ``self`` should be computed; he generator exponents in the braid word are assumed to be ``1`` or ``-1`` - OUTPUT: - - An instance of the element class of ``self``. + OUTPUT: an instance of the element class of ``self`` EXAMPLES:: @@ -2521,9 +2513,7 @@ def _cubic_braid_append_to_basis(self, cubic_braid): - ``cubic_braid`` -- :class:`~sage.groups.cubic_braid.CubicBraid` whose image in ``self`` should be appended - OUTPUT: - - The new monomial of ``self``. + OUTPUT: the new monomial of ``self`` EXAMPLES:: @@ -2538,7 +2528,6 @@ def _cubic_braid_append_to_basis(self, cubic_braid): c3*c0 sage: CHA5._basis_extension [[4], [-4], [4, 1]] - """ cbTietze = list(cubic_braid.Tietze()) order = self.get_order() @@ -2573,9 +2562,7 @@ def _cubic_braid_basis_tuple(self, cubic_braid): - ``cubic_braid`` -- :class:`~sage.groups.cubic_braid.CubicBraid` - OUTPUT: - - A tuple from the basis representing the cubic braid. + OUTPUT: a tuple from the basis representing the cubic braid EXAMPLES:: @@ -2617,7 +2604,7 @@ def _cubic_braid_image(self, cubic_braid, check=True): INPUT: - - ``cubic_braid`` -- :class:`~sage.groups.cubic_braid.CubicBraid` + - ``cubic_braid`` -- :class:`~sage.groups.cubic_braid.CubicBraid` whose image in ``self`` should be returned - ``check`` -- boolean (default: ``True``); check if the given cubic braid is already registered in the finite sub basis; if set to @@ -2690,9 +2677,7 @@ def _markov_trace_module(self, extended=False, field_embedding=False): generic extension ring of ``self``. The keyword is meaningless if ``extended=False``. - OUTPUT: - - A :class:`~sage.combinat.free_module.CombinatorialFreeModule`. + OUTPUT: a :class:`~sage.combinat.free_module.CombinatorialFreeModule` EXAMPLES:: @@ -2984,7 +2969,7 @@ def cubic_equation(self, var='h', as_coefficients=False, generic=False): INPUT: - - ``var`` -- string (default ``h``) setting the indeterminate of the + - ``var`` -- string (default: ``'h'``); setting the indeterminate of the equation - ``as_coefficients`` -- boolean (default: ``False``); if set to ``True`` the list of coefficients is returned @@ -3033,9 +3018,7 @@ def cubic_equation_roots(self, generic=False): - ``generic`` -- boolean (default: ``False``); if set to ``True`` the roots are returned as elements of the generic extension ring - OUTPUT: - - A triple consisting of the roots. + OUTPUT: a triple consisting of the roots EXAMPLES:: @@ -3064,9 +3047,7 @@ def cubic_equation_parameters(self, generic=False): - ``generic`` -- boolean (default: ``False``); if set to ``True`` the coefficients are returned as elements of the generic base ring - OUTPUT: - - A tripple consisting of the coefficients. + OUTPUT: a triple consisting of the coefficients EXAMPLES:: @@ -3248,13 +3229,11 @@ def cubic_hecke_subalgebra(self, nstrands=None): INPUT: - - ``nstrands`` -- integer at least 1 and at most :meth:`strands` giving + - ``nstrands`` -- integer at least 1 and at most :meth:`strands` giving the number of strands for the subgroup; the default is one strand less than ``self`` has - OUTPUT: - - An instance of this class realizing the sub-algebra. + OUTPUT: an instance of this class realizing the sub-algebra EXAMPLES:: @@ -3499,7 +3478,7 @@ def characters(self, irr=None, original=True): - ``irr`` -- (optional) instance of :class:`AbsIrreducibeRep` selecting the irreducible representation corresponding to the character; if not given a list of all characters is returned - - ``original`` -- (default: ``True``) see description above + - ``original`` -- boolean (default: ``True``); see description above OUTPUT: diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py index 90d6657d309..b980e2fa80c 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py @@ -34,9 +34,9 @@ from sage.algebras.splitting_algebra import solve_with_extension, SplittingAlgebra -# --------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # local helper functions -# --------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def normalize_names_markov(names, markov_trace_version): r""" Return a tuple of strings of variable names of length 3 resp. 4 (if @@ -103,15 +103,15 @@ def register_ring_hom(ring_hom): try: codomain.register_conversion(ring_hom) except ValueError: - verbose('\nthe map:\n%s\ncannot be registerd as conversion\n' % ring_hom) + verbose('\nthe map:\n%s\ncannot be registered as conversion\n' % ring_hom) return -# ------------------------------------------------------------------------------ +# ----------------------------------------------------------------------------- # class for the Galois Group action on the generic extension ring corresponding # to the cubic equation -# ------------------------------------------------------------------------------ +# ----------------------------------------------------------------------------- class GaloisGroupAction(Action): r""" Action on a multivariate polynomial ring by permuting the generators. @@ -148,7 +148,7 @@ def _act_(self, perm, pol): if not self.is_left(): perm, pol = pol, perm pol_dict = {} - for key, value in pol.dict().items(): + for key, value in pol.monomial_coefficients().items(): newkey = [0] * len(key) for pos, k in enumerate(key): newkey[perm(pos + 1) - 1] = k @@ -156,15 +156,15 @@ def _act_(self, perm, pol): return self.domain()(pol_dict) -################################################################################ +############################################################################### # EXTENSION RING -# ------------------------------------------------------------------------------ +# ----------------------------------------------------------------------------- # Definition of the generic extension ring for the cubic Hecke algebra as # Laurent polynomial ring in 3 indeterminates over the cyclotomic field of a # third root of unity This is the most general ring over which the cubic Hecke # algebra is semi-simple. In opposite to the generic base ring class, this class # does not inherits from UniqueRepresentation since _test_pickling fails -# ------------------------------------------------------------------------------ +# ----------------------------------------------------------------------------- class CubicHeckeExtensionRing(LaurentPolynomialRing_mpair): r""" The generic splitting algebra for the irreducible representations of @@ -194,7 +194,7 @@ class CubicHeckeExtensionRing(LaurentPolynomialRing_mpair): realized as splitting ring via the ``as_splitting_algebra`` method - ``third_unity_root_name`` -- string (default: ``'e3'``); for setting the name of the third root if unity of ``self`` - - ``markov_trace_version`` -- boolean (default: ``False``) if this is + - ``markov_trace_version`` -- boolean (default: ``False``); if this is set to ``True`` then ``self`` contains one invertible indeterminate in addition which is meant to represent the writhe factor of a Markov trace on the cubic Hecke algebra and which default name is ``s`` @@ -261,7 +261,6 @@ def __init__(self, names, order='degrevlex', ring_of_definition=None, third_unit # Init of data used on demand # ---------------------------------------------------------------------- self._mirror = None - return ############################################################################ # overloaded inherited methods @@ -318,7 +317,7 @@ def _element_constructor_(self, x, mon=None): def _coerce_map_from_(self, R): r""" The rings that canonically coerce to ``self`` ar the ones from - inheritence and the base ring of definition of the cubic Hecke algebra. + inheritance and the base ring of definition of the cubic Hecke algebra. EXAMPLES:: @@ -386,7 +385,7 @@ def hom(self, im_gens, codomain=None, check=True, base_map=None): return super().hom(im_remain, codomain=codomain, check=check, base_map=hom_cycl_gen) else: if base_map is None: - raise ValueError('number of images must be four (inculding a ' + raise ValueError('number of images must be four (including a ' 'third root of unity at first position) or a ' 'base_map (on %s) must be given' % self.base_ring()) return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map) @@ -410,12 +409,12 @@ def _an_element_(self): s = self.one() if rem: s = rem[0] - return b**2/c+a*e3/s + return b**2/c + a*e3/s ############################################################################ # local methods ############################################################################ - def _is_markov_trace_version(self): + def _is_markov_trace_version(self) -> bool: r""" Return whether ``self`` is the version containing the writhe parameter ``s`` for the Markov trace. @@ -437,39 +436,31 @@ def _is_markov_trace_version(self): # -------------------------------------------------------------------------- def _convert_from_gap3_mvp(self, mvp_expression): r""" - Convert a string produced via ``GAP3`` interface and containing Jean + Convert an element of ``GAP3`` interface containing Jean Michel's ``MVP`` (multivariate polynomials) to an element of ``self``. INPUT: - - ``string`` -- string produced via GAP3 interface and containing + - ``mvp_expression`` -- element of ``GAP3`` interface containing Jean Michel's ``MVP`` (multivariate polynomials) EXAMPLES:: + sage: # optional - gap3 sage: from sage.algebras.hecke_algebras import cubic_hecke_base_ring as chbr + sage: CHA3 = algebras.CubicHecke(3) + sage: sch7 = CHA3.chevie().SchurElements()[7] sage: ER = chbr.CubicHeckeExtensionRing('a, b, c') - sage: gap3_string = '2+a^-2bc+a^-1b^-1c^2+a^-1b^2c^-1+ab^-2E3c' - sage: ER._convert_from_gap3_mvp(gap3_string) - a^-1*b^2*c^-1 + 2 + e3*a*b^-2*c + a^-2*b*c + a^-1*b^-1*c^2 + sage: ER._convert_from_gap3_mvp(sch7) + a*b*c^-2 + a^2*b^-1*c^-1 + a^-1*b^2*c^-1 + 2 + a*b^-2*c + a^-2*b*c + a^-1*b^-1*c^2 """ + from sage.misc.sage_eval import sage_eval E3 = self.cyclotomic_generator() a, b, c, *rem = self.gens() na, nb, nc = self.variable_names() - lc = {na: a, nb: b, nc: c, 'e': E3} - var_names = list(lc.keys()) - - from sage.repl.preparse import implicit_mul - # since implicit_mul does not know about the choice of variable names - # we have to insert * between them separately - string = str(mvp_expression) - string = string.replace('E3', 'e') - for i in var_names: - for j in var_names: - string = string.replace('%s%s' % (i, j), '%s*%s' % (i, j)) - sage_expression = implicit_mul(string) - from sage.misc.sage_eval import sage_eval - return sage_eval(sage_expression, locals=lc) + lc = {na: a, nb: b, nc: c, 'E3': E3} + sage_expr = str(mvp_expression.FormatMaple())[1:-1] + return sage_eval(sage_expr, locals=lc) ############################################################################ # global methods @@ -545,9 +536,7 @@ def mirror_involution(self): considered as `\ZZ`-algebra. The base ring elements are transformed by this automorphism. - OUTPUT: - - The involution as automorphism of ``self``. + OUTPUT: the involution as automorphism of ``self`` EXAMPLES:: @@ -592,7 +581,7 @@ def mirror_involution(self): def create_specialization(self, im_cubic_equation_roots, im_writhe_parameter=None, var='T', third_unity_root_name='E3'): r""" Return an appropriate ring containing the elements from the list - ``im_cubic_equation_roots`` defining a conversion map from self mapping + ``im_cubic_equation_roots`` defining a conversion map from ``self`` mapping the cubic equation roots of ``self`` to ``im_cubic_equation_roots``. INPUT: @@ -806,7 +795,7 @@ def field_embedding(self, characteristic=0): INPUT: - - ``characteristic`` -- integer (default: ``0``); the characteristic + - ``characteristic`` -- integer (default: `0`); the characteristic of the field EXAMPLES:: @@ -941,7 +930,7 @@ class CubicHeckeRingOfDefinition(Localization): - ``ring_of_definition`` -- (optional) a :class:`CubicHeckeRingOfDefinition` to specify the generic cubic Hecke base ring over which ``self`` may be realized as splitting ring via the ``as_splitting_algebra`` method - - ``markov_trace_version`` -- boolean (default: ``False``) if this is + - ``markov_trace_version`` -- boolean (default: ``False``); if this is set to ``True`` then ``self`` contains one invertible indeterminate in addition which is meant to represent the writhe factor of a Markov trace on the cubic Hecke algebra and which default name is ``s`` @@ -1062,7 +1051,7 @@ def _an_element_(self): ############################################################################ # Local Methods ############################################################################ - def _is_markov_trace_version(self): + def _is_markov_trace_version(self) -> bool: r""" Return whether ``self`` is the version containing the writhe parameter ``s`` for the Markov trace. @@ -1133,9 +1122,7 @@ def mirror_involution(self): considered as `\ZZ`-algebra. The base ring elements are transformed by this automorphism. - OUTPUT: - - The involution as automorphism of ``self``. + OUTPUT: the involution as automorphism of ``self`` EXAMPLES:: diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py b/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py index c0587117753..59b0767fb48 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py @@ -61,7 +61,7 @@ class RepresentationType(Enum): r""" Enum class to select a representation type for the cubic Hecke algebra. - - ``RegularLeft`` -- left regular representations + - ``RegularLeft`` -- left regular representations - ``RegularRight`` -- right regular representations - ``SplitIrredMarin`` -- split irreducible representations obtained from Ivan Marin's data @@ -491,7 +491,7 @@ def __getitem__(self, item): - ``item`` -- an :class:`AbsIrreducibeRep` specifying an absolute irreducible representation of the cubic Hecke algebra; alternatively, it can be specified by list index - (see :meth:`internal_index` repectively :meth:`gap_index`) + (see :meth:`internal_index` respectively :meth:`gap_index`) OUTPUT: @@ -551,7 +551,7 @@ def reduce_to_irr_block(self, irr): OUTPUT: - An instance of :class:`Matrix_generic_dense` with exactly one non zero block + An instance of :class:`Matrix_generic_dense` with exactly one nonzero block according to ``irr``. EXAMPLES:: @@ -586,7 +586,7 @@ class CubicHeckeMatrixSpace(MatrixSpace): INPUT: - - ``cubic_hecke_algebra`` -- (optional) + - ``cubic_hecke_algebra`` -- (optional) :class:`~sage.algebras.hecke_algebras.cubic_hecke_algebra.CubicHeckeAlgebra` must be given if ``element`` fails to be an instance of its element class - ``representation_type`` -- (default: ``RepresentationType.SplitIrredChevie``) @@ -594,7 +594,7 @@ class CubicHeckeMatrixSpace(MatrixSpace): - ``subdivide`` -- boolean (default: ``False``); whether or not to subdivide the resulting matrices - - ``original`` -- boolean (default: ``False``) if ``True``, the matrix + - ``original`` -- boolean (default: ``False``); if ``True``, the matrix will have coefficients in the generic base / extension ring EXAMPLES:: @@ -732,7 +732,7 @@ def _element_constructor_(self, x): :class:`~sage.algebras.hecke_algebras.cubic_hecke_algebra.CubicHeckeAlgebra` or an element whose parent is a :class:`MatrixSpace` - EXAMLPES:: + EXAMPlES:: sage: import sage.algebras.hecke_algebras.cubic_hecke_matrix_rep as chmr sage: CHA3. = algebras.CubicHecke(3) @@ -786,7 +786,7 @@ def __call__(self, entries=None, coerce=True, copy=None): This method needs to be overloaded here since :class:`MatrixSpace` has an own implementation of it. - EXAMLPES:: + EXAMPLES:: sage: import sage.algebras.hecke_algebras.cubic_hecke_matrix_rep as chmr sage: CHA2. = algebras.CubicHecke(2) @@ -816,9 +816,7 @@ def _specialize_matrix(self, mat): - ``mat`` -- matrix over the original base ring - OUTPUT: - - ``mat`` over the base ring of ``self`` + OUTPUT: matrix over the base ring of ``self`` EXAMPLES:: diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index a16ff3d5dda..01390f1a5a4 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -83,7 +83,7 @@ def normalized_laurent_polynomial(R, p): u + v^-1 + u^-1 """ try: - return R({k: R._base(c) for k, c in p.dict().items()}) + return R({k: R._base(c) for k, c in p.monomial_coefficients().items()}) except (AttributeError, TypeError): return R(p) @@ -128,11 +128,8 @@ class IwahoriHeckeAlgebra(Parent, UniqueRepresentation): - ``W`` -- a Coxeter group or Cartan type - ``q1`` -- a parameter - - OPTIONAL ARGUMENTS: - - - ``q2`` -- (default ``-1``) another parameter - - ``base_ring`` -- (default ``q1.parent()``) a ring containing ``q1`` + - ``q2`` -- (default: ``-1``) another parameter + - ``base_ring`` -- (default: ``q1.parent()``) a ring containing ``q1`` and ``q2`` The Iwahori-Hecke algebra [Iwa1964]_ is a deformation of the group algebra of @@ -720,7 +717,7 @@ def __getitem__(self, i): .. WARNING:: - If `i`` is not a reduced expression then the basis element + If ``i`` is not a reduced expression then the basis element indexed by the corresponding element of the algebra is returned rather than the corresponding product of the generators:: @@ -1240,7 +1237,7 @@ def __init__(self, algebra, prefix=None): EXAMPLES:: sage: H = IwahoriHeckeAlgebra("G2",1) - sage: t = H.T(prefix="t") + sage: t = H.T(prefix='t') sage: t[1] t[1] """ @@ -1258,7 +1255,7 @@ def __init__(self, algebra, prefix=None): # This **must** match the name of the class in order for # specialize_to() to work - _basis_name = None + _basis_name = 'B' def _repr_term(self, t): r""" @@ -1356,7 +1353,7 @@ class T(_Basis): sage: w0 = T(H.coxeter_group().long_element()) sage: w0 T[1,2,3,1,2,1] - sage: T = H.T(prefix="s") + sage: T = H.T(prefix='s') sage: T.an_element() s[1,2,3] + 2*s[1] + 3*s[2] + 1 @@ -1441,7 +1438,7 @@ def inverse_generators(self): sage: U1*T1,T1*U1 (1, 1) sage: P1. = LaurentPolynomialRing(QQ) - sage: H1 = IwahoriHeckeAlgebra("A2", q, base_ring=P1).T(prefix="V") + sage: H1 = IwahoriHeckeAlgebra("A2", q, base_ring=P1).T(prefix='V') sage: V1,V2 = H1.algebra_generators() sage: W1,W2 = H1.inverse_generators() sage: [W1,W2] @@ -1469,7 +1466,7 @@ def product_on_basis(self, w1, w2): result = self.product_by_generator(result, i) return result - def product_by_generator_on_basis(self, w, i, side="right"): + def product_by_generator_on_basis(self, w, i, side='right'): r""" Return the product `T_w T_i` (resp. `T_i T_w`) if ``side`` is ``'right'`` (resp. ``'left'``). @@ -1498,7 +1495,7 @@ def product_by_generator_on_basis(self, w, i, side="right"): sage: s1,s2 = H.coxeter_group().simple_reflections() sage: [T.product_by_generator_on_basis(w, 1) for w in [s1,s2,s1*s2]] [(q-1)*T[1] + q, T[2,1], T[1,2,1]] - sage: [T.product_by_generator_on_basis(w, 1, side="left") for w in [s1,s2,s1*s2]] + sage: [T.product_by_generator_on_basis(w, 1, side='left') for w in [s1,s2,s1*s2]] [(q-1)*T[1] + q, T[1,2], (q-1)*T[1,2] + q*T[2]] """ wi = w.apply_simple_reflection(i, side=side) @@ -1510,7 +1507,7 @@ def product_by_generator_on_basis(self, w, i, side="right"): else: return self.monomial(wi) - def product_by_generator(self, x, i, side="right"): + def product_by_generator(self, x, i, side='right'): r""" Return `T_i \cdot x`, where `T_i` is the `i`-th generator. This is coded individually for use in ``x._mul_()``. @@ -1704,11 +1701,11 @@ class Element(CombinatorialFreeModule.Element): (q-1)*T[1] + q sage: R. = QQ[] - sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix="x") + sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix='x') sage: sum(H.algebra_generators())^2 x[2,1] + x[1,2] + (q1+q2)*x[1] + (q1+q2)*x[2] + (-2*q1*q2) - sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix="t") + sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix='t') sage: t1,t2 = H.algebra_generators() sage: (t1-t2)^3 (q1^2-q1*q2+q2^2)*t[1] + (-q1^2+q1*q2-q2^2)*t[2] @@ -2514,7 +2511,7 @@ def __init__(self, IHAlgebra, prefix=None): # Define and register coercions from the A basis to the T basis and back again from_A_to_T = self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), - triangular="lower", key=sorting_key, + triangular='lower', key=sorting_key, category=self.category()) from_A_to_T.register_as_coercion() from_T_to_A = ~from_A_to_T @@ -2646,7 +2643,7 @@ def __init__(self, IHAlgebra, prefix=None): # Define and register coercions from the B basis to the T basis and back again from_B_to_T = self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), - triangular="lower", key=sorting_key, + triangular='lower', key=sorting_key, category=self.category()) from_B_to_T.register_as_coercion() from_T_to_B = ~from_B_to_T diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index adbcdd53eee..0b6fc0111bf 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -426,7 +426,7 @@ def _latex_(self): def __bool__(self) -> bool: """ - Return if ``self`` is non-zero. + Return if ``self`` is nonzero. EXAMPLES:: @@ -583,9 +583,9 @@ def monomial_coefficients(self, copy=True): INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally - represented by a dictionary ``d``, then make a copy of ``d``; - if ``False``, then this can cause undesired behavior by + - ``copy`` -- boolean (default: ``True``); if ``self`` is + internally represented by a dictionary ``d``, then make a copy of + ``d``; if ``False``, then this can cause undesired behavior by mutating ``d`` EXAMPLES:: @@ -851,7 +851,7 @@ def _latex_(self): def __bool__(self) -> bool: """ - Return if ``self`` is non-zero. + Return if ``self`` is nonzero. TESTS:: @@ -1571,7 +1571,7 @@ def _unicode_art_(self): def __bool__(self) -> bool: """ - Return if ``self`` is non-zero. + Return if ``self`` is nonzero. TESTS:: diff --git a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx index e2ce4445881..2a977b1a513 100644 --- a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx @@ -29,7 +29,8 @@ poly_reduce = singular_function("NF") # Free algebra elements cdef class FreeAlgebraElement_letterplace(AlgebraElement): """ - Weighted homogeneous elements of a free associative unital algebra (letterplace implementation) + Weighted homogeneous elements of a free associative unital algebra + (letterplace implementation). EXAMPLES:: @@ -60,17 +61,16 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): z*z*y*x sage: ((x*y)^3).degree() 9 - """ def __init__(self, A, x, check=True): """ INPUT: - - A free associative unital algebra in letterplace implementation, `A`. - - A homogeneous polynomial that can be coerced into the currently - used polynomial ring of `A`. - - ``check`` (optional bool, default ``True``): Do not attempt the - above coercion (for internal use only). + - ``A`` - a free associative unital algebra in letterplace implementation + - ``x`` -- a homogeneous polynomial that can be coerced into the currently + used polynomial ring of `A` + - ``check`` -- boolean (default: ``True``); do not attempt the + above coercion (for internal use only) TESTS:: @@ -85,7 +85,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): -x*y + y*x sage: loads(dumps(p)) == p True - """ cdef FreeAlgebra_letterplace P = A if check: @@ -131,7 +130,7 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): def __iter__(self): """ - Iterates over the pairs "tuple of exponents, coefficient". + Iterate over the pairs "tuple of exponents, coefficient". EXAMPLES:: @@ -140,8 +139,8 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: sorted(p) # indirect doctest [((0, 0, 0, 1, 0, 0, 0, 1), 2), ((0, 1, 0, 0, 0, 0, 1, 0), 1)] """ - cdef dict d = self._poly.dict() - yield from d.iteritems() + cdef dict d = self._poly.monomial_coefficients() + yield from d.items() def _repr_(self): """ @@ -401,7 +400,7 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): def lm_divides(self, FreeAlgebraElement_letterplace p): """ - Tell whether or not the leading monomial of self divides the + Tell whether or not the leading monomial of ``self`` divides the leading monomial of another element. .. NOTE:: @@ -468,7 +467,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace') sage: -(3*x*y+2*z^2) -3*x*y - 2*z*z - """ return FreeAlgebraElement_letterplace(self._parent, -self._poly, check=False) @@ -586,7 +584,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: (x*y+z)*z # indirect doctest x*y*z + z*z - """ cdef FreeAlgebraElement_letterplace left = self cdef FreeAlgebraElement_letterplace right = other @@ -644,9 +641,7 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): the commutative polynomial ring that is currently used to implement the multiplication in the free algebra. - OUTPUT: - - The twosided reduction of this element by the argument. + OUTPUT: the twosided reduction of this element by the argument .. NOTE:: @@ -713,12 +708,10 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): INPUT: - A twosided homogeneous ideal `I` of the parent `F` of - this element, `x`. - - OUTPUT: + - ``I`` -- a twosided homogeneous ideal of the parent `F` of + this element, `x` - The normal form of `x` wrt. `I`. + OUTPUT: the normal form of `x` wrt. `I` .. NOTE:: diff --git a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx index 0072fbd1a78..7a57922d24a 100644 --- a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx @@ -149,8 +149,8 @@ cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring, blocks): INPUT: - - ``base_ring``: A multivariate polynomial ring. - - ``blocks``: The number of blocks to be formed. + - ``base_ring`` -- a multivariate polynomial ring + - ``blocks`` -- the number of blocks to be formed OUTPUT: @@ -191,7 +191,7 @@ cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring, blocks): T += T0 names.extend([x + '_' + str(i) for x in names0]) return PolynomialRing(base_ring.base_ring(), names, order=T, - implementation="singular") + implementation='singular') ##################### @@ -234,9 +234,7 @@ cdef class FreeAlgebra_letterplace(Parent): A multivariate polynomial ring of type :class:`~sage.rings.polynomial.multipolynomial_libsingular.MPolynomialRing_libsingular`. - OUTPUT: - - The free associative version of the given commutative ring. + OUTPUT: the free associative version of the given commutative ring .. NOTE:: @@ -328,11 +326,9 @@ cdef class FreeAlgebra_letterplace(Parent): INPUT: - - `i` -- an integer - - OUTPUT: + - ``i`` -- integer - The generator with index `i` + OUTPUT: the generator with index `i` EXAMPLES:: @@ -654,8 +650,8 @@ cdef class FreeAlgebra_letterplace(Parent): INPUT: - - ``g`` -- a list of elements of this free algebra. - - ``d`` -- an integer. + - ``g`` -- list of elements of this free algebra + - ``d`` -- integer OUTPUT: @@ -701,14 +697,14 @@ cdef class FreeAlgebra_letterplace(Parent): # Coercion cpdef _coerce_map_from_(self, S): """ - A ring ``R`` coerces into self, if + A ring ``R`` coerces into ``self``, if: - it coerces into the current polynomial ring, or - it is a free graded algebra in letterplace implementation, the generator names of ``R`` are a proper subset of the - generator names of self, the degrees of equally named + generator names of ``self``, the degrees of equally named generators are equal, and the base ring of ``R`` coerces - into the base ring of self. + into the base ring of ``self``. TESTS: @@ -766,8 +762,8 @@ cdef class FreeAlgebra_letterplace(Parent): # # INPUT: # -# - ``degree`` -- the maximal degree of the output (default 2). -# - ``terms`` -- the maximal number of terms of the output (default 5). +# - ``degree`` -- the maximal degree of the output (default: 2) +# - ``terms`` -- the maximal number of terms of the output (default: 5) # # NOTE: # @@ -788,12 +784,12 @@ cdef class FreeAlgebra_letterplace(Parent): INPUT: - - A dictionary. Keys: tuples of exponents. Values: - The coefficients of the corresponding monomial - in the to-be-created element. - - ``check`` (optional bool, default ``True``): - This is forwarded to the initialisation of - :class:`~sage.algebras.letterplace.free_algebra_element_letterplace.FreeAlgebraElement_letterplace`. + - ``D`` -- dictionary; keys: tuples of exponents, values: + the coefficients of the corresponding monomial + in the to-be-created element + - ``check`` -- boolean (default: ``True``); + this is forwarded to the initialisation of + :class:`~sage.algebras.letterplace.free_algebra_element_letterplace.FreeAlgebraElement_letterplace` TESTS: diff --git a/src/sage/algebras/letterplace/letterplace_ideal.pyx b/src/sage/algebras/letterplace/letterplace_ideal.pyx index eeebf4422a4..77d0107ba07 100644 --- a/src/sage/algebras/letterplace/letterplace_ideal.pyx +++ b/src/sage/algebras/letterplace/letterplace_ideal.pyx @@ -157,16 +157,16 @@ class LetterplaceIdeal(Ideal_nc): sage: (z*I.0-x*y*z).normal_form(I) -y*x*z + z*z """ - def __init__(self, ring, gens, coerce=True, side="twosided"): + def __init__(self, ring, gens, coerce=True, side='twosided'): """ INPUT: - - ``ring``: A free algebra in letterplace implementation. - - ``gens``: List, tuple or sequence of generators. - - ``coerce`` (optional bool, default ``True``): - Shall ``gens`` be coerced first? - - ``side``: optional string, one of ``"twosided"`` (default), - ``"left"`` or ``"right"``. Determines whether the ideal + - ``ring`` -- a free algebra in letterplace implementation + - ``gens`` -- list, tuple or sequence of generators + - ``coerce`` -- boolean (default: ``True``); whether ``gens`` shall be + coerced first + - ``side`` -- string; one of ``'twosided'`` (default), + ``'left'`` or ``'right'``. Determines whether the ideal is a left, right or twosided ideal. Groebner bases or only supported in the twosided case. @@ -189,7 +189,6 @@ class LetterplaceIdeal(Ideal_nc): running ._test_new() . . . pass running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass - """ Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side) self.__GB = self @@ -201,7 +200,7 @@ class LetterplaceIdeal(Ideal_nc): INPUT: - - ``degbound`` (optional integer, or Infinity): If it is provided, + - ``degbound`` -- (optional) integer or Infinity; if it is provided, a Groebner basis at least out to that degree is returned. By default, the current degree bound of the underlying ring is used. @@ -358,8 +357,8 @@ class LetterplaceIdeal(Ideal_nc): INPUT: - - ``G``: A list or tuple of elements, an ideal, - the ambient algebra, or a single element. + - ``G`` -- a list or tuple of elements, an ideal, + the ambient algebra, or a single element OUTPUT: diff --git a/src/sage/algebras/letterplace/meson.build b/src/sage/algebras/letterplace/meson.build new file mode 100644 index 00000000000..1ada90927a7 --- /dev/null +++ b/src/sage/algebras/letterplace/meson.build @@ -0,0 +1,27 @@ +py.install_sources( + 'all.py', + 'free_algebra_element_letterplace.pxd', + 'free_algebra_letterplace.pxd', + subdir: 'sage/algebras/letterplace', +) + +extension_data_cpp = { + 'free_algebra_element_letterplace': files( + 'free_algebra_element_letterplace.pyx', + ), + 'free_algebra_letterplace': files('free_algebra_letterplace.pyx'), + 'letterplace_ideal': files('letterplace_ideal.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras/letterplace', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp, singular], + ) +endforeach + diff --git a/src/sage/algebras/lie_algebras/bgg_dual_module.py b/src/sage/algebras/lie_algebras/bgg_dual_module.py new file mode 100644 index 00000000000..c4e060131da --- /dev/null +++ b/src/sage/algebras/lie_algebras/bgg_dual_module.py @@ -0,0 +1,1175 @@ +r""" +BGG Category O Dual Modules + +AUTHORS: + +- Travis Scrimshaw (2024-01-07): Initial version +""" + +#***************************************************************************** +# Copyright (C) 2024 Travis Scrimshaw +# +# 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. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.cachefunc import cached_method +from sage.categories.enumerated_sets import EnumeratedSets +from sage.categories.monoids import Monoids +from sage.structure.parent import Parent +from sage.structure.indexed_generators import IndexedGenerators +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedMonoid +from sage.combinat.free_module import CombinatorialFreeModule +from sage.sets.family import Family +from sage.sets.finite_enumerated_set import FiniteEnumeratedSet +from sage.matrix.constructor import matrix +from sage.rings.integer_ring import ZZ +from sage.data_structures.blas_dict import iaxpy +from sage.algebras.lie_algebras.verma_module import ModulePrinting + + +class BGGDualModule(CombinatorialFreeModule): + r""" + The dual module `M^{\vee}` in the BGG Category `\mathcal{O}`. + + Let `\tau` be the transpose map of a semisimple (finite dimensional) + Lie algebra `\mathfrak{g}` over a field `R`. Let `M \in \mathcal{O}`. + The *BGG dual module* is the `R`-module `M^{\vee} := + \bigoplus_{\lambda} M_{\lambda}^*` which has a `U(\mathfrak{g})`-module + structure given by + + .. MATH:: + + x \cdot \phi(v) := \phi(\tau(x) \cdot v), + + which is also a weight module with the same grading as `M`. + + The basis we chose to work with here is the natural dual basis to the + distinguished basis `B` of `M`. That is, we define the dual function + to `b` as `\phi_b(c) = \delta_{bc}`. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(2*La[1]) + sage: Mc = M.dual() + sage: B = Mc.basis() + sage: it = iter(B) + sage: elts = [next(it) for _ in range(7)]; elts + [v[2*Lambda[1]]^*, + f[-alpha[1]]*v[2*Lambda[1]]^*, + f[-alpha[1]]^2*v[2*Lambda[1]]^*, + f[-alpha[1]]^3*v[2*Lambda[1]]^*, + f[-alpha[1]]^4*v[2*Lambda[1]]^*, + f[-alpha[1]]^5*v[2*Lambda[1]]^*, + f[-alpha[1]]^6*v[2*Lambda[1]]^*] + sage: e, h, f = g.pbw_basis().algebra_generators() + sage: [f * vec for vec in elts] + [2*f[-alpha[1]]*v[2*Lambda[1]]^*, + 2*f[-alpha[1]]^2*v[2*Lambda[1]]^*, + 0, + -4*f[-alpha[1]]^4*v[2*Lambda[1]]^*, + -10*f[-alpha[1]]^5*v[2*Lambda[1]]^*, + -18*f[-alpha[1]]^6*v[2*Lambda[1]]^*, + -28*f[-alpha[1]]^7*v[2*Lambda[1]]^*] + sage: [e * vec for vec in elts] + [0, + v[2*Lambda[1]]^*, + f[-alpha[1]]*v[2*Lambda[1]]^*, + f[-alpha[1]]^2*v[2*Lambda[1]]^*, + f[-alpha[1]]^3*v[2*Lambda[1]]^*, + f[-alpha[1]]^4*v[2*Lambda[1]]^*, + f[-alpha[1]]^5*v[2*Lambda[1]]^*] + sage: [h * vec for vec in elts] + [2*v[2*Lambda[1]]^*, + 0, + -2*f[-alpha[1]]^2*v[2*Lambda[1]]^*, + -4*f[-alpha[1]]^3*v[2*Lambda[1]]^*, + -6*f[-alpha[1]]^4*v[2*Lambda[1]]^*, + -8*f[-alpha[1]]^5*v[2*Lambda[1]]^*, + -10*f[-alpha[1]]^6*v[2*Lambda[1]]^*] + + REFERENCES: + + - [Humphreys08]_ + """ + def __init__(self, module): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: M = g.verma_module(2*La[1] + La[2]) + sage: Mc = M.dual() + sage: TestSuite(Mc).run() + + sage: M = g.verma_module(2/3*La[1] - 3/5*La[2]) + sage: Mc = M.dual() + sage: TestSuite(Mc).run() + """ + self._module = module + self._g = module.lie_algebra() + self._pbw = self._g.pbw_basis() + base_ring = module.base_ring() + indices = module.indices() + category = module.category() + CombinatorialFreeModule.__init__(self, base_ring, indices, category=category, + **module.print_options()) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(2*La[1]) + sage: M.dual() + BGG Dual of Verma module with highest weight 2*Lambda[1] of + Lie algebra of ['A', 1] in the Chevalley basis + """ + return "BGG Dual of " + repr(self._module) + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(2*La[1]) + sage: Mc = M.dual() + sage: latex(Mc) + { M_{2 \Lambda_{1}} }^{\vee} + """ + from sage.misc.latex import latex + return "{" + latex(self._module) + "}^{\\vee}" + + def _repr_generator(self, m): + r""" + Return a string representation of the generator indexed by ``m``. + + EXAMPLES:: + + sage: g = lie_algebras.sp(QQ, 4) + sage: La = g.cartan_type().root_system().ambient_space().fundamental_weights() + sage: Mc = g.verma_module(La[1] + 3/7*La[2]).dual() + sage: f1, f2 = g.f() + sage: x = g.pbw_basis()(g([f1, [f1, f2]])) + sage: v = x * Mc.highest_weight_vector() + sage: Mc._repr_generator(v.leading_support()) + 'f[-alpha[1]]*f[-alpha[1] - alpha[2]]*v[(10/7, 3/7)]^*' + """ + return self._module._repr_generator(m) + "^*" + + def _latex_generator(self, m): + """ + Return a latex representation of the generator indexed by ``m``. + + EXAMPLES:: + + sage: g = lie_algebras.sp(QQ, 4) + sage: La = g.cartan_type().root_system().ambient_space().fundamental_weights() + sage: Mc = g.verma_module(La[1] + 3/7*La[2]).dual() + sage: f1, f2 = g.f() + sage: x = g.pbw_basis()(g([f1, [f1, f2]])) + sage: v = x * Mc.highest_weight_vector() + sage: Mc._latex_generator(v.leading_support()) + { f_{-\alpha_{1}} f_{-\alpha_{1} - \alpha_{2}} v_{\frac{10}{7} e_{0} + \frac{3}{7} e_{1}} }^{\vee} + """ + return "{" + self._module._latex_generator(m) + "}^{\\vee}" + + _repr_term = _repr_generator + _latex_term = _latex_generator + + def degree_on_basis(self, m): + r""" + Return the degree of the basis element indexed by ``m``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['D', 5]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: M = g.verma_module(La[1] + La[4] - 1/3*La[5]) + sage: Mc = M.dual() + sage: elt = Mc.an_element(); elt + f[-alpha[5]]^2*f[-alpha[4]]^2*f[-alpha[3]]^3*v[Lambda[1] + Lambda[4] - 1/3*Lambda[5]]^* + + 2*f[-alpha[5]]*v[Lambda[1] + Lambda[4] - 1/3*Lambda[5]]^* + + 3*f[-alpha[4]]*v[Lambda[1] + Lambda[4] - 1/3*Lambda[5]]^* + + v[Lambda[1] + Lambda[4] - 1/3*Lambda[5]]^* + sage: [M.degree_on_basis(m) for m in elt.support()] + [Lambda[1] + 3*Lambda[2] - 2*Lambda[3] - 4/3*Lambda[5], + Lambda[1] + Lambda[4] - 1/3*Lambda[5], + Lambda[1] + Lambda[3] + Lambda[4] - 7/3*Lambda[5], + Lambda[1] + Lambda[3] - Lambda[4] - 1/3*Lambda[5]] + """ + return self._module.degree_on_basis(m) + + def highest_weight(self): + r""" + Return the highest weight of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 7]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: M = g.verma_module(2*La[1] + 5/3*La[4] - 3*La[6]) + sage: Mc = M.dual() + sage: Mc.highest_weight() + 2*Lambda[1] + 5/3*Lambda[4] - 3*Lambda[6] + """ + return self._module.highest_weight() + + def highest_weight_vector(self): + r""" + Return the highest weight vector of ``self`` (assuming the + defining module defines such a vector). + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(2*La[1]) + sage: Mc = M.dual() + sage: Mc.highest_weight_vector() + v[2*Lambda[1]]^* + """ + hwv = self._module.highest_weight_vector() + return self.element_class(self, hwv.monomial_coefficients(copy=False)) + + def lie_algebra(self): + r""" + Return the underlying Lie algebra of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 3]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(2*La[1] + La[3]) + sage: Mc = M.dual() + sage: Mc.lie_algebra() is g + True + """ + return self._g + + def dual(self): + r""" + Return the dual module of ``self``. + + In Category `\mathcal{O}`, we have `(M^{\vee})^{\vee} \cong M`, so + we return the defining module `M` of `M^{\vee}`. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['F', 4]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: M = g.verma_module(La[1] - 5/3*La[2] + 3*La[4]) + sage: Mc = M.dual() + sage: Mc.dual() is M + True + """ + return self._module + + @cached_method + def _lie_algebra_on_basis(self, b, m): + r""" + Return the action of the Lie algebra basis element indexed by ``b`` + on the basis element of ``self`` indexed by ``m``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: M = g.verma_module(La[1]) + sage: Mc = M.dual() + sage: it = iter(Mc.basis()) + sage: list(g.basis()) + [E[alpha[2]], E[alpha[1]], E[alpha[1] + alpha[2]], E[alpha[1] + 2*alpha[2]], + h1, h2, + E[-alpha[2]], E[-alpha[1]], E[-alpha[1] - alpha[2]], E[-alpha[1] - 2*alpha[2]]] + sage: for _ in range(3): + ....: m = next(it).leading_support() + ....: print(m, [Mc._lie_algebra_on_basis(k, m) for k in g.basis().keys()]) + 1 [0, 0, 0, 0, v[Lambda[1]]^*, 0, 0, f[-alpha[1]]*v[Lambda[1]]^*, + -2*f[-alpha[2]]*f[-alpha[1]]*v[Lambda[1]]^* + 2*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^*, + -2*f[-alpha[2]]^2*f[-alpha[1]]*v[Lambda[1]]^* + + 2*f[-alpha[2]]*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^* + + f[-alpha[1] - 2*alpha[2]]*v[Lambda[1]]^*] + f[-alpha[2]] [v[Lambda[1]]^*, 0, 0, 0, 2*f[-alpha[2]]*v[Lambda[1]]^*, + -2*f[-alpha[2]]*v[Lambda[1]]^*, -2*f[-alpha[2]]^2*v[Lambda[1]]^*, + f[-alpha[2]]*f[-alpha[1]]*v[Lambda[1]]^* + f[-alpha[1] - alpha[2]]*v[Lambda[1]]^*, + -4*f[-alpha[2]]^2*f[-alpha[1]]*v[Lambda[1]]^* - f[-alpha[1] - 2*alpha[2]]*v[Lambda[1]]^*, + -6*f[-alpha[2]]^3*f[-alpha[1]]*v[Lambda[1]]^* + 2*f[-alpha[2]]^2*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^*] + f[-alpha[1]] [0, v[Lambda[1]]^*, 0, 0, -f[-alpha[1]]*v[Lambda[1]]^*, + 2*f[-alpha[1]]*v[Lambda[1]]^*, + 2*f[-alpha[2]]*f[-alpha[1]]*v[Lambda[1]]^* - 2*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^*, + 0, 0, f[-alpha[1]]*f[-alpha[1] - 2*alpha[2]]*v[Lambda[1]]^* + 2*f[-alpha[1] - alpha[2]]^2*v[Lambda[1]]^*] + """ + al = self._g.degree_on_basis(b) + wt = self.degree_on_basis(m) + if al == 0: # b is indexing part of the Cartan subalgebra + # We are assuming b is part of the coroot lattice. + # FIXME: Add something at the category level to return this. + ac = b + return self.term(m, wt.scalar(ac)) + + # TODO: Avoid calling homogeneous_component_basis() as the result is not cached + gens = self._module.homogeneous_component_basis(wt + al) + elt = self._g.basis()[b] + # TODO: Determine if we can meaningfully store these results. + # Computing gens is ~1/3 of the computation and vecs is ~2/3. + vecs = {g.leading_support(): elt.transpose() * g for g in gens} + return self.element_class(self, {k: c for k, v in vecs.items() if (c := v[m])}) + + def _pbw_monomial_on_basis(self, p, m): + r""" + Return the action of the PBW monomial indexed by ``p`` on the basis + element of ``self`` indexed by ``m``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: PBW = g.pbw_basis() + sage: e, h, f = PBW.algebra_generators() + sage: M = g.verma_module(2*La[1]) + sage: Mc = M.dual() + sage: v = Mc.highest_weight_vector() + sage: Mc._pbw_monomial_on_basis((e*f^2).leading_support(), v.leading_support()) + 4*f[-alpha[1]]*v[2*Lambda[1]]^* + sage: B = Mc.basis() + sage: it = iter(B) + sage: elts = [next(it) for _ in range(7)]; elts + [v[2*Lambda[1]]^*, + f[-alpha[1]]*v[2*Lambda[1]]^*, + f[-alpha[1]]^2*v[2*Lambda[1]]^*, + f[-alpha[1]]^3*v[2*Lambda[1]]^*, + f[-alpha[1]]^4*v[2*Lambda[1]]^*, + f[-alpha[1]]^5*v[2*Lambda[1]]^*, + f[-alpha[1]]^6*v[2*Lambda[1]]^*] + """ + ret = self.monomial(m) + for b, exp in reversed(p._sorted_items()): + for _ in range(exp): + ret = self.linear_combination((self._lie_algebra_on_basis(b, m), mc) + for m, mc in ret._monomial_coefficients.items()) + return ret + + class Element(CombinatorialFreeModule.Element): + def _acted_upon_(self, scalar, self_on_left=False): + r""" + Return the action of ``scalar`` on ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: PBW = g.pbw_basis() + sage: e, h, f = PBW.algebra_generators() + sage: M = g.verma_module(2*La[1]) + sage: Mc = M.dual() + sage: v = Mc.highest_weight_vector() + sage: (h*e^2*f^2) * v + 8*v[2*Lambda[1]]^* + sage: g.casimir_element(UEA=PBW) * v + v[2*Lambda[1]]^* + sage: 5 * v + 5*v[2*Lambda[1]]^* + """ + P = self.parent() + # Check for scalars first + if scalar in P.base_ring(): + # Don't have this be a super call + return CombinatorialFreeModule.Element._acted_upon_(self, scalar, self_on_left) + + # Check for Lie algebra elements + try: + scalar = P._g(scalar) + except (ValueError, TypeError): + pass + if scalar.parent() is P._g: + if self_on_left: # only implemented as a left module + return None + mc = scalar.monomial_coefficients(copy=False) + return P.linear_combination((P._lie_algebra_on_basis(b, m), bc * mc) + for b, bc in mc.items() + for m, mc in self._monomial_coefficients.items()) + + # Check for PBW elements + try: + scalar = P._pbw(scalar) + except (ValueError, TypeError): + # Cannot be made into a PBW element, so propagate it up + return CombinatorialFreeModule.Element._acted_upon_(self, + scalar, self_on_left) + + # We only implement x * self, i.e., as a left module + if self_on_left: + return None + + mc = scalar.monomial_coefficients(copy=False) + return P.linear_combination((P._pbw_monomial_on_basis(p, m), pc * mc) + for p, pc in mc.items() + for m, mc in self._monomial_coefficients.items()) + + +##################################################################### +# Simple modules + + +# This is an abuse as the monoid is not free. +# TODO: Rewrite this (or the indexed monoid class) to use explicit vectors +# since we only want to consider ordered elements. +# Note, such a rewrite would force the Lie algebra to be finite dimensional. +class SimpleModuleIndices(IndexedFreeAbelianMonoid): + r""" + The indices of the basis for a simple `U(\mathfrak{g})`-module. + + .. NOTE:: + + The current implementation assumes the Lie algebra `\mathfrak{g}` + is finite dimensional. + """ + # This is only necessary because of the IndexedMonoid.__classcall__. + @staticmethod + def __classcall__(cls, simple, prefix='f', **kwds): + r""" + Normalize input to ensure a unique representation. + + TESTS:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 6]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[3]) + sage: from sage.algebras.lie_algebras.bgg_dual_module import SimpleModuleIndices + sage: SimpleModuleIndices(L) is L._indices + True + """ + return super(IndexedMonoid, cls).__classcall__(cls, simple, prefix=prefix, **kwds) + + def __init__(self, simple, prefix, category=None, **kwds): + r""" + Initialize ``self``. + + TESTS:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: I = g.simple_module(2*La[1] + La[2]).indices() + sage: TestSuite(I).run() + + sage: I = g.simple_module(2*La[1] - 1/3*La[2]).indices() + sage: TestSuite(I).run(max_runs=150) # long time + """ + self._simple = simple + self._g = simple.lie_algebra() + self._reached_max_depth = False + # Below was mostly copied from IndexedMonoid.__init__() + self._indices = FiniteEnumeratedSet(self._g._negative_half_index_set()) + category = Monoids().or_subcategory(category) + category = category & EnumeratedSets() + category = category.FinitelyGeneratedAsMagma() + if self._simple._dom_int: + category = category.Finite() + else: + category = category.Infinite() + Parent.__init__(self, category=category) + + # ignore the optional 'key' since it only affects CachedRepresentation + kwds.pop('key', None) + sorting_key = kwds.pop('sorting_key', self._simple._pbw._monoid_key) + IndexedGenerators.__init__(self, self._indices, prefix, sorting_key=sorting_key, **kwds) + + self._sorted_supp = sorted(self._g._negative_half_index_set(), key=self._simple._pbw._basis_key, + reverse=self.print_options()['sorting_reverse']) + self._basis = {self.one(): self._simple._ambient.highest_weight_vector()} + self._lead_supp_to_index = {self._simple._ambient.highest_weight_vector().leading_support(): self.one()} + # This is used for iteration and keeps track of the current depth + self._basis_by_depth = [dict(self._basis)] + # The basis is given as a list of indices corresponding to basis vectors in self._basis + self._weight_space_bases = {self._simple.highest_weight(): [self.one()]} + + def _an_element_(self): + r""" + Return an element of ``self``. + + The only element we can quickly guarantee is in ``self`` is 1, + so we return this. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 6]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: I = g.simple_module(2*La[1] + La[2]).indices() + sage: I._an_element_() + 1 + """ + return self.one() + + def _weight_max_depth(self, mu): + r""" + Return the maximum depth of the weight ``mu``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 6]) + sage: P = g.cartan_type().root_system().weight_lattice() + sage: La = P.fundamental_weights() + sage: al = P.simple_roots() + sage: wt = 2*La[1] + La[2] + sage: I = g.simple_module(wt).indices() + sage: I._weight_max_depth(wt) + 0 + sage: I._weight_max_depth(wt + al[2]) is None + True + sage: I._weight_max_depth(wt - 2*al[2] - 5*al[4] - 3*al[6]) + 10 + + sage: g = LieAlgebra(QQ, cartan_type=['F', 4]) + sage: P = g.cartan_type().root_system().weight_space() + sage: La = P.fundamental_weights() + sage: al = P.simple_roots() + sage: wt = 2*La[1] - 3/2*La[2] + sage: I = g.simple_module(wt).indices() + sage: I._weight_max_depth(wt) + 0 + sage: I._weight_max_depth(wt + al[2]) is None + True + sage: I._weight_max_depth(wt - 2*al[2] - 3*al[4]) + 5 + sage: I._weight_max_depth(wt - 2/3*al[1]) is None + True + """ + al = (self._simple.highest_weight() - mu)._to_root_vector() + if any(c not in ZZ or c < 0 for c in al): + return None + return sum(al) + + def weight_space_basis(self, mu): + r""" + Return the indices of the ``mu`` weight space basis elements. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: P = g.cartan_type().root_system().weight_lattice() + sage: La = P.fundamental_weights() + sage: al = P.simple_roots() + sage: wt = -3*La[1] + 3*La[2] + sage: I = g.simple_module(wt).indices() + sage: I.weight_space_basis(wt) + [1] + sage: I.weight_space_basis(wt - al[1]) + [f[-alpha[1]]] + sage: I.weight_space_basis(wt - al[2]) + [f[-alpha[2]]] + sage: I.weight_space_basis(wt - al[1] - al[2]) + [f[-alpha[1] - alpha[2]], f[-alpha[2]]*f[-alpha[1]]] + sage: I.weight_space_basis(wt - 4*al[1]) + [f[-alpha[1]]^4] + sage: I.weight_space_basis(wt - 4*al[2]) + [] + """ + if self._reached_max_depth: + return self._weight_space_bases.get(mu, []) + + max_depth = self._weight_max_depth(mu) + while max_depth >= len(self._basis_by_depth): + if self._reached_max_depth: # we've already reached everything + break + self._construct_next_level() + return self._weight_space_bases.get(mu, []) + + def __contains__(self, m): + r""" + Check if ``m`` is contained in ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1]) + sage: I = L.indices() + sage: I.one() in I + True + sage: it = iter(I) + sage: for _ in range(3): + ....: elt = next(it) + ....: print(elt, elt in I) + 1 True + f[-alpha[1]] True + f[-alpha[1] - alpha[2]] True + sage: gens = list(I.gens()); gens + [f[-alpha[2]], + f[-alpha[1]], + f[-alpha[1] - alpha[2]], + f[-2*alpha[1] - alpha[2]], + f[-3*alpha[1] - alpha[2]], + f[-3*alpha[1] - 2*alpha[2]]] + sage: gens[1] in I + True + sage: gens[0] * gens[1] in I + False + sage: gens[2] in I + True + sage: gens[0]^10 in I + False + sage: gens[5]^6 * gens[2]^10 in I + False + """ + if not isinstance(m, self.Element) or m.parent() is not self: + return False + depth = m.length() + while depth >= len(self._basis_by_depth): + if self._reached_max_depth: # we've already reached everything + break + self._construct_next_level() + return m in self._basis + + def __iter__(self): + r""" + Iterate over ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[2]) + sage: I = L.indices() + sage: list(I) + [1, f[-alpha[2]], f[-alpha[1] - alpha[2]], f[-alpha[1] - 2*alpha[2]]] + + sage: L = g.simple_module(La[1]-La[2]) + sage: I = L.indices() + sage: it = iter(I) + sage: [next(it) for _ in range(6)] + [1, f[-alpha[2]], f[-alpha[1]], f[-alpha[1] - alpha[2]], + f[-alpha[1] - 2*alpha[2]], f[-alpha[2]]^2] + """ + depth = 0 + while True: + while depth >= len(self._basis_by_depth): + if self._reached_max_depth: # we've already reached everything + return + self._construct_next_level() + yield from self._basis_by_depth[depth] + depth += 1 + + def _construct_next_level(self): + r""" + Construct the image for the next level of ``self``. + + ALGORITHM: + + For each image vector of `f_{\beta_1}^{b_1} \cdots f_{\beta_k}^{b_k} + v_{\lambda}` at the current depth `b_1 + \cdots b_k`, consider the + image under multiplication by every generator `f_{\alpha}` for + all `\alpha \leq \beta_1` in the fixed PBW ordering of the (dual) + Verma module. + + .. TODO:: + + Avoid unnecessary computations by using the corresponding + (combinatorial) crystal. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['C', 3]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1]) + sage: I = L.indices() + sage: len(I._basis) + 1 + sage: I._construct_next_level() + sage: len(I._basis) + 6 + sage: I._reached_max_depth + False + sage: I._construct_next_level() # long time + sage: len(I._basis) # long time + 6 + sage: I._reached_max_depth # long time + True + sage: I._construct_next_level() # long time + """ + if self._reached_max_depth: # we've already reached everything + return # so nothing more to do + + gens = self._g.basis() + next_level = {} + R = self._g.base_ring() + ambient = self._simple._ambient + pbw = ambient._pbw + for m, vec in self._basis_by_depth[-1].items(): + # find the first support index + ind = len(self._sorted_supp) + for i, ls in enumerate(self._sorted_supp): + if ls in m._monomial: + ind = i + 1 + break + + for ls in self._sorted_supp[:ind]: + mp = dict(m._monomial) # make a (shallow) copy + mp[ls] = mp.get(ls, 0) + 1 + key = self.element_class(self, mp) + new_vec = gens[ls] * vec + if not new_vec: + continue + # Echelonize the corresponding weight space + mu = ambient.degree_on_basis(key) + if mu not in self._weight_space_bases: + # the only vector in the weight space + self._weight_space_bases[mu] = [key] + next_level[key] = new_vec + self._basis[key] = next_level[key] + lead_supp = next_level[key].trailing_support(key=pbw._monomial_key) + self._lead_supp_to_index[lead_supp] = key + continue + + supp = set() + wt_basis = [self._basis[k] for k in self._weight_space_bases[mu]] + wt_basis.append(new_vec) + for b in wt_basis: + supp.update(b.support()) + supp = sorted(supp, key=pbw._monomial_key) + mat = matrix(R, [[b[s] for s in supp] for b in wt_basis]) + mat.echelonize() + for i, k in enumerate(self._weight_space_bases[mu]): + data = {supp[ind]: R(c) for ind, c in mat[i].iteritems() if c} + self._basis[k] = ambient.element_class(ambient, data) + i = mat.nrows() - 1 + data = {supp[ind]: R(c) for ind, c in mat[i].iteritems() if c} + if data: + next_level[key] = ambient.element_class(ambient, data) + self._basis[key] = next_level[key] + lead_supp = next_level[key].trailing_support(key=pbw._monomial_key) + self._lead_supp_to_index[lead_supp] = key + self._weight_space_bases[mu].append(key) + + if not next_level: + self._reached_max_depth = True + return + self._basis_by_depth.append(next_level) + + @cached_method + def cardinality(self): + r""" + Return the cardinality of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 6]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1]+La[4]) + sage: L._indices.cardinality() + 51975 + """ + if self._simple._dom_int: + weight = self._simple.highest_weight() + Phi = self._g.cartan_type().root_system() + P = Phi.weight_lattice() + coroots = Phi.root_lattice().simple_coroots() + la = P._from_dict({i: weight.scalar(ac) for i, ac in coroots.items()}) + from sage.combinat.crystals.monomial_crystals import CrystalOfNakajimaMonomials + return CrystalOfNakajimaMonomials(la).cardinality() + from sage.rings.infinity import infinity + return infinity + + +class SimpleModule(ModulePrinting, CombinatorialFreeModule): + r""" + Return the simple module `L_{\lambda}` as the image of the natural + morphism `\phi: M_{\lambda} \to M_{\lambda}^{\vee}`. + """ + @staticmethod + def __classcall_private__(cls, g, weight, *args, **kwds): + r""" + Normalize input to ensure a unique representation and return + the correct type. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 6]) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: type(g.simple_module(La[1] + La[2])) + + sage: type(g.simple_module(La[1] - La[2])) + + sage: type(g.simple_module(La[1] + 3/2*La[2])) + + """ + if weight.is_dominant_weight(): + return FiniteDimensionalSimpleModule(g, weight, *args, **kwds) + return super().__classcall__(cls, g, weight, *args, **kwds) + + def __init__(self, g, weight, prefix='f', basis_key=None, **kwds): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: TestSuite(L).run() + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] - La[2]) + sage: TestSuite(L).run() + """ + self._g = g + self._weight = weight + self._dom_int = weight.is_dominant_weight() + self._verma = g.verma_module(weight, basis_key=basis_key) + self._ambient = self._verma.dual() + self._pbw = self._verma.pbw_basis() + base_ring = self._g.base_ring() + indices = SimpleModuleIndices(self, prefix=prefix, **kwds) + category = self._ambient.category().Subobjects() + if self._dom_int: + category = category.FiniteDimensional() + ModulePrinting.__init__(self, 'u') + CombinatorialFreeModule.__init__(self, base_ring, indices, category=category, + **self._ambient.print_options()) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: g.simple_module(2*La[1]) + Simple module with highest weight 2*Lambda[1] of + Lie algebra of ['A', 1] in the Chevalley basis + """ + return "Simple module with highest weight {} of {}".format(self._weight, self._g) + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(2*La[1]) + sage: latex(L) + L_{2 \Lambda_{1}} + """ + from sage.misc.latex import latex + return "L_{{{}}}".format(latex(self._weight)) + + def ambient(self): + r""" + Return the ambient module of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(2*La[1]) + sage: L.ambient() + BGG Dual of Verma module with highest weight 2*Lambda[1] of + Lie algebra of ['G', 2] in the Chevalley basis + """ + return self._ambient + + @lazy_attribute + def lift(self): + r""" + Return the lift map of ``self`` to the ambient dual Verma module. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1]) + sage: [L.lift(b) for b in L.basis()] # long time + [v[Lambda[1]]^*, + f[-alpha[1]]*v[Lambda[1]]^*, + f[-alpha[2]]*f[-alpha[1]]*v[Lambda[1]]^* - f[-alpha[1] - alpha[2]]*v[Lambda[1]]^*, + f[-alpha[1]]*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^* + + f[-2*alpha[1] - alpha[2]]*v[Lambda[1]]^*, + f[-alpha[1]]^2*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^* + + f[-alpha[1]]*f[-2*alpha[1] - alpha[2]]*v[Lambda[1]]^* + + 1/2*f[-3*alpha[1] - alpha[2]]*v[Lambda[1]]^*, + f[-alpha[2]]*f[-alpha[1]]^2*f[-alpha[1] - alpha[2]]*v[Lambda[1]]^* + + f[-alpha[2]]*f[-alpha[1]]*f[-2*alpha[1] - alpha[2]]*v[Lambda[1]]^* + + 1/2*f[-alpha[2]]*f[-3*alpha[1] - alpha[2]]*v[Lambda[1]]^* + - f[-alpha[1] - alpha[2]]*f[-2*alpha[1] - alpha[2]]*v[Lambda[1]]^* + + 1/2*f[-3*alpha[1] - 2*alpha[2]]*v[Lambda[1]]^*, + f[-alpha[1]]*f[-alpha[1] - alpha[2]]*f[-2*alpha[1] - alpha[2]]*v[Lambda[1]]^* + - 1/2*f[-alpha[1]]*f[-3*alpha[1] - 2*alpha[2]]*v[Lambda[1]]^* + - 1/2*f[-alpha[1] - alpha[2]]*f[-3*alpha[1] - alpha[2]]*v[Lambda[1]]^* + + f[-2*alpha[1] - alpha[2]]^2*v[Lambda[1]]^*] + """ + return self.module_morphism(self._lift_on_basis, codomain=self._ambient, unitriangular="upper") + + def retract(self, x): + r""" + Return the retraction of ``x`` in ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(2*La[1]) + sage: L.retract(L.lift(sum(L.basis()))) + f[-alpha[1]]^2*u[2*Lambda[1]] + f[-alpha[1]]*f[-alpha[1] - alpha[2]]*u[2*Lambda[1]] + + f[-alpha[1] - alpha[2]]^2*u[2*Lambda[1]] + f[-alpha[1]]*u[2*Lambda[1]] + + f[-alpha[1] - alpha[2]]*u[2*Lambda[1]] + u[2*Lambda[1]] + sage: B = list(L.basis()) + sage: L.retract(3/2*L.lift(B[0]) - L.lift(B[2]) - 10/3*L.lift(B[3])) + -10/3*f[-alpha[1]]^2*u[2*Lambda[1]] + - f[-alpha[1] - alpha[2]]*u[2*Lambda[1]] + + 3/2*u[2*Lambda[1]] + """ + supp = sorted(x.support(), key=self._pbw._monomial_key) + data = x.monomial_coefficients(copy=True) # this is destructive to data + R = self.base_ring() + ret = {} + for ls in supp: + if ls not in data: + continue + if ls not in self._indices._lead_supp_to_index: + mu = self._ambient.degree_on_basis(ls) + # this will guarantee the computation is correct + self._indices.weight_space_basis(mu) + if ls not in self._indices._lead_supp_to_index: + raise ValueError(f"not an element of the simple module of weight {self._weight}") + key = self._indices._lead_supp_to_index[ls] + vec = self._indices._basis[key] + coeff = R(data[ls] / vec[ls]) + iaxpy(-coeff, vec._monomial_coefficients, data) + ret[key] = coeff + return self.element_class(self, ret) + + def _lift_on_basis(self, m): + r""" + Return the lift of the basis element indexed by ``m``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(2*La[1]) + sage: I = L.indices() + sage: gen = list(I.gens())[0] + sage: L._lift_on_basis(gen^2) + 4*f[-alpha[1]]^2*v[2*Lambda[1]]^* + sage: L._lift_on_basis(gen^3) + Traceback (most recent call last): + ... + ValueError: f[-alpha[1]]^3 does not index a basis element + """ + # This builds the result up to the necessary depth + if m not in self._indices: + raise ValueError(f"{m} does not index a basis element") + return self._indices._basis[m] + + def dual(self): + r""" + Return the dual module of ``self``, which is ``self`` since simple + modules are self-dual. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 4]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(2*La[1] + 3*La[4]) + sage: L.dual() is L + True + """ + return self + + def highest_weight(self): + r""" + Return the highest weight of ``self``. + + EXAMPLES:: + + sage: g = lie_algebras.so(QQ, 7) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: L.highest_weight() + Lambda[1] + Lambda[2] + """ + return self._weight + + @cached_method + def highest_weight_vector(self): + r""" + Return the highest weight vector of ``self``. + + EXAMPLES:: + + sage: g = lie_algebras.sp(QQ, 6) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: L.highest_weight_vector() + u[Lambda[1] + Lambda[2]] + """ + one = self.base_ring().one() + return self._from_dict({self._indices.one(): one}, + remove_zeros=False, coerce=False) + + def lie_algebra(self): + r""" + Return the underlying Lie algebra of ``self``. + + EXAMPLES:: + + sage: g = lie_algebras.so(QQ, 9) + sage: La = g.cartan_type().root_system().weight_space().fundamental_weights() + sage: L = g.simple_module(La[3] - 1/2*La[1]) + sage: L.lie_algebra() + Lie algebra of ['B', 4] in the Chevalley basis + """ + return self._g + + def pbw_basis(self): + r""" + Return the PBW basis of the underlying Lie algebra + used to define ``self``. + + EXAMPLES:: + + sage: g = lie_algebras.so(QQ, 8) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[2] - 2*La[3]) + sage: L.pbw_basis() + Universal enveloping algebra of Lie algebra of ['D', 4] in the Chevalley basis + in the Poincare-Birkhoff-Witt basis + """ + return self._pbw + + def homogeneous_component_basis(self, mu): + r""" + Return a basis for the ``mu`` weight space of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: P = g.cartan_type().root_system().weight_lattice() + sage: La = P.fundamental_weights() + sage: la = La[1] + La[2] + sage: L = g.simple_module(la) + sage: from itertools import product + sage: al = P.simple_roots() + sage: for wts in product(range(4), repeat=2): + ....: mu = la - wts[0] * al[1] - wts[1] * al[2] + ....: print(mu) + ....: print(L.homogeneous_component_basis(mu)) + Lambda[1] + Lambda[2] + Family (u[Lambda[1] + Lambda[2]],) + 2*Lambda[1] - Lambda[2] + Family (f[-alpha[2]]*u[Lambda[1] + Lambda[2]],) + 3*Lambda[1] - 3*Lambda[2] + Family () + 4*Lambda[1] - 5*Lambda[2] + Family () + -Lambda[1] + 2*Lambda[2] + Family (f[-alpha[1]]*u[Lambda[1] + Lambda[2]],) + 0 + Family (f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]], f[-alpha[2]]*f[-alpha[1]]*u[Lambda[1] + Lambda[2]]) + Lambda[1] - 2*Lambda[2] + Family (f[-alpha[2]]*f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]],) + 2*Lambda[1] - 4*Lambda[2] + Family () + -3*Lambda[1] + 3*Lambda[2] + Family () + -2*Lambda[1] + Lambda[2] + Family (f[-alpha[1]]*f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]],) + -Lambda[1] - Lambda[2] + Family (f[-alpha[1] - alpha[2]]^2*u[Lambda[1] + Lambda[2]],) + -3*Lambda[2] + Family () + -5*Lambda[1] + 4*Lambda[2] + Family () + -4*Lambda[1] + 2*Lambda[2] + Family () + -3*Lambda[1] + Family () + -2*Lambda[1] - 2*Lambda[2] + Family () + """ + return Family([self.monomial(b) for b in self._indices.weight_space_basis(mu)]) + + weight_space_basis = homogeneous_component_basis + + class Element(CombinatorialFreeModule.Element): + def _acted_upon_(self, scalar, self_on_left=True): + r""" + Return the action of ``scalar`` on ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: v = L.highest_weight_vector(); v + u[Lambda[1] + Lambda[2]] + sage: f1, f2 = g.pbw_basis().f() + sage: 5 * v + 5*u[Lambda[1] + Lambda[2]] + sage: f1 * f2 * v + f[-alpha[2]]*f[-alpha[1]]*u[Lambda[1] + Lambda[2]] + + f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]] + sage: f2 * f1 * v + -f[-alpha[2]]*f[-alpha[1]]*u[Lambda[1] + Lambda[2]] + + 2*f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]] + sage: f2 * f2 * f1 * v + -2*f[-alpha[2]]*f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]] + sage: f1 * f2 * f1 * v + f[-alpha[1]]*f[-alpha[1] - alpha[2]]*u[Lambda[1] + Lambda[2]] + sage: f2 * f1 * f2 * f1 * v + f[-alpha[1] - alpha[2]]^2*u[Lambda[1] + Lambda[2]] + sage: f1 * f2 * f2 * f1 * v + 2*f[-alpha[1] - alpha[2]]^2*u[Lambda[1] + Lambda[2]] + """ + # check for scalars first + ret = CombinatorialFreeModule.Element._acted_upon_(self, scalar, self_on_left) + if ret is not None: + return ret + + if self_on_left: # this is a left module action + return None + + P = self.parent() + return P.retract(scalar * P.lift(self)) + + _lmul_ = _acted_upon_ + _rmul_ = _acted_upon_ + + +class FiniteDimensionalSimpleModule(SimpleModule): + """ + A finite dimensional simple module. + """ + def bgg_resolution(self): + """ + Return the BGG resolution of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: L.bgg_resolution() + BGG resolution of Simple module with highest weight Lambda[1] + Lambda[2] + of Lie algebra of ['A', 2] in the Chevalley basis + """ + from sage.algebras.lie_algebras.bgg_resolution import BGGResolution + return BGGResolution(self) diff --git a/src/sage/algebras/lie_algebras/bgg_resolution.py b/src/sage/algebras/lie_algebras/bgg_resolution.py new file mode 100644 index 00000000000..906f8d43f95 --- /dev/null +++ b/src/sage/algebras/lie_algebras/bgg_resolution.py @@ -0,0 +1,230 @@ +r""" +BGG Resolutions + +AUTHORS: + +- Travis Scrimshaw (2024-01-07): Initial version +""" + +#***************************************************************************** +# Copyright (C) 2024 Travis Scrimshaw +# +# 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. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.misc.cachefunc import cached_function +from sage.structure.unique_representation import UniqueRepresentation +from sage.matrix.constructor import matrix +from sage.rings.integer_ring import ZZ +from sage.homology.chain_complex import ChainComplex_class + + +class BGGResolution(UniqueRepresentation, ChainComplex_class): + r""" + The BGG resolution of a simple module. + + We realize the BGG resolution as a chain complex, where the `(-1)`-th + factor corresponds to the finite dimensional simple module `L_{\lambda}` + and the `i`-th factor (`i \geq 0`) corresponds to + + .. MATH:: + + M_i := \bigoplus_{\substack{w \in W \\ \ell(w) = i}} M_{w\lambda}. + + Since the morphisms can be defined in terms of the image of the + highest weight vectors, we only encode this information as a + (finite) chain complex. We do not include the final natural projection + map `p: M_{\lambda} \to L_{\lambda}` since the highest weight vector of + weight `\lambda` only occurs in `M_{\lambda}` and `L_{\lambda}`. + + INPUT: + + - ``L`` -- a simple module + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + 4*La[2]) + sage: res = L.bgg_resolution() + sage: ascii_art(res) + [ 1 -1] [1] + [1 1] [-1 1] [1] + 0 <-- C_0 <------ C_1 <-------- C_2 <---- C_3 <-- 0 + + sage: g = LieAlgebra(QQ, cartan_type=['D', 4]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2] + 3*La[3]) + sage: res = L.bgg_resolution() + sage: w0 = WeylGroup(g.cartan_type(), prefix='s').long_element() + sage: all(res.differential(i) * res.differential(i+1) == 0 + ....: for i in range(w0.length())) + True + """ + def __init__(self, L): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: res = L.bgg_resolution() + sage: TestSuite(res).run() + """ + from sage.combinat.root_system.weyl_group import WeylGroup + ct = L.lie_algebra().cartan_type() + self._cartan_type = ct + self._simple = L + self._W = WeylGroup(ct, prefix='s') + # finish initialization + R = self._simple.base_ring() + differentials, mod_order = build_differentials(self._W) + differentials = {deg: mat.change_ring(R) for deg, mat in differentials.items()} + for deg in differentials: + differentials[deg].set_immutable() + self._module_order = mod_order + super().__init__(ZZ, -ZZ.one(), R, differentials) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1]) + sage: L.bgg_resolution() + BGG resolution of Simple module with highest weight Lambda[1] + of Lie algebra of ['B', 2] in the Chevalley basis + """ + return "BGG resolution of " + repr(self._simple) + + def simple_module(self): + r""" + Return the simple module `L_{\lambda}` defining ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['C', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: res = L.bgg_resolution() + sage: res.simple_module() is L + True + """ + return self._simple + + def module_order(self, i): + r""" + Return a tuple of Weyl group elements of length ``i`` + determining the ordering of the direct sum defining the + differential matrix. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: L = g.simple_module(La[1]) + sage: res = L.bgg_resolution() + sage: [res.module_order(i) for i in range(7)] + [[1], + [s2, s1], + [s2*s1, s1*s2], + [s1*s2*s1, s2*s1*s2], + [s1*s2*s1*s2, s2*s1*s2*s1], + [s1*s2*s1*s2*s1, s2*s1*s2*s1*s2], + [s2*s1*s2*s1*s2*s1]] + """ + if i not in self._module_order: + return [] + return self._module_order[i] + + +@cached_function +def build_differentials(W): + r""" + Construct the differentials for the BGG resolution corresponding + to the Weyl group `W`. + + ALGORITHM: + + We use the fact that (parabolic) Bruhat order is built locally + from squares, all values defining the differential are `+1` or `-1`, + and the product over the two different paths must sum to `0`. + This is outlined in Ch. 6 of [Humphreys08]_. + + This only depends on the Coxeter group `W`. There is no stabilizer + for any dominant integral weight `\lambda` undert the dot action + (i.e., the stabilizer of `\lambda + \rho` is empty). + + EXAMPLES:: + + sage: from sage.algebras.lie_algebras.bgg_resolution import build_differentials + sage: W = WeylGroup(['B', 2], prefix='s') + sage: D, O = build_differentials(W) + sage: D + {0: [], + 1: [-1 1], + 2: [1 1] + [1 1], + 3: [ 1 -1] + [-1 1], + 4: [1] + [1], + 5: []} + sage: O + {0: [1], + 1: [s2, s1], + 2: [s2*s1, s1*s2], + 3: [s2*s1*s2, s1*s2*s1], + 4: [s2*s1*s2*s1]} + """ + from itertools import combinations + w0 = W.long_element() + maxlen = w0.length() + module_order = {i: [] for i in range(maxlen+1)} + for w in W: + module_order[w.length()].append(w) + + one = ZZ.one() + # Set the initial step + prev = {w: (j, frozenset([0])) for j, w in enumerate(module_order[maxlen-1])} + prev_mat = matrix(ZZ, [[one]]*len(module_order[maxlen-1]), immutable=True) + differentials = {maxlen: prev_mat} + for i in range(maxlen-2, -1, -1): + mat = matrix.zero(ZZ, len(module_order[i]), len(prev)) + cur = {} + for j, w in enumerate(module_order[i]): + # build the data to find the squares + covers = frozenset([prev[v][0] for v in w.bruhat_upper_covers()]) + cur[w] = (j, covers) + # set the indices in each square + for v, vp in combinations(w.bruhat_upper_covers(), 2): + # get the (unique) value at the top of the square + dv = prev[v] + dvp = prev[vp] + vind = dv[0] + vpind = dvp[0] + for uind in dv[1] & dvp[1]: + # set the entries corresponding to the square + if not mat[j, vind]: + if not mat[j, vpind]: + mat[j, vpind] = one + mat[j, vind] = -mat[j, vpind] * prev_mat[vpind, uind] * prev_mat[vind, uind] + elif not mat[j, vpind]: + mat[j, vpind] = -mat[j, vind] * prev_mat[vpind, uind] * prev_mat[vind, uind] + else: + assert mat[j, vpind] * prev_mat[vpind, uind] + mat[j, vind] * prev_mat[vind, uind] == 0 + differentials[i+1] = mat + prev = cur + prev_mat = mat + differentials[0] = matrix.zero(ZZ, 0, 1) + differentials[maxlen+1] = matrix.zero(ZZ, 1, 0) + return differentials, module_order diff --git a/src/sage/algebras/lie_algebras/center_uea.py b/src/sage/algebras/lie_algebras/center_uea.py index 61f5c6e05d7..54057bc9735 100644 --- a/src/sage/algebras/lie_algebras/center_uea.py +++ b/src/sage/algebras/lie_algebras/center_uea.py @@ -6,22 +6,22 @@ - Travis Scrimshaw (2024-01-02): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2024 Travis Scrimshaw # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -#from sage.structure.unique_representation import UniqueRepresentation -#from sage.structure.parent import Parent +# from sage.structure.unique_representation import UniqueRepresentation +# from sage.structure.parent import Parent from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_lists.invlex import IntegerListsLex from sage.matrix.constructor import matrix -from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid #, IndexedFreeAbelianMonoidElement +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid from sage.monoids.indexed_free_monoid import IndexedMonoid from sage.combinat.root_system.coxeter_group import CoxeterGroup from sage.combinat.integer_vector_weighted import iterator_fast as intvecwt_iterator @@ -742,7 +742,7 @@ def retract(self, elt): True """ # This should work except it needs the monomials of the PBW basis to be - # compariable. However, this does not work for, e.g., Lie algebras + # comparable. However, this does not work for, e.g., Lie algebras # in the Chevalley basis as ee are unable to pass a key for the # module morphism. Additionally, the implementation below does more # operations in-place than the module morphism. diff --git a/src/sage/algebras/lie_algebras/classical_lie_algebra.py b/src/sage/algebras/lie_algebras/classical_lie_algebra.py index d1b0a97fe45..15badc6881f 100644 --- a/src/sage/algebras/lie_algebras/classical_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/classical_lie_algebra.py @@ -379,15 +379,15 @@ def build_assoc(row): continue basis_pivots.add(p) if self._sparse: - added.append(self.element_class( self, build_assoc(cur_mat[i]) )) + added.append(self.element_class(self, build_assoc(cur_mat[i]))) else: - added.append(self.element_class( self, self._assoc(cur_mat[i].list()) )) + added.append(self.element_class(self, self._assoc(cur_mat[i].list()))) cur_mat = cur_mat.submatrix(nrows=len(pivots)) if self._sparse: - basis = [self.element_class( self, build_assoc(cur_mat[i]) ) + basis = [self.element_class(self, build_assoc(cur_mat[i])) for i in range(cur_mat.rank())] else: - basis = [self.element_class( self, self._assoc(cur_mat[i].list()) ) + basis = [self.element_class(self, self._assoc(cur_mat[i].list())) for i in range(cur_mat.rank())] return Family(basis) @@ -978,7 +978,7 @@ def __init__(self, R): We skip the not implemented methods test as it takes too much time:: - sage: TestSuite(g).run(skip="_test_not_implemented_methods") # long time + sage: TestSuite(g).run(skip='_test_not_implemented_methods') # long time """ ct = CartanType(['E', 8]) g = LieAlgebraChevalleyBasis(R, ct) @@ -1077,7 +1077,7 @@ def __init__(self, R): ####################################### -## Compact real form +# Compact real form class MatrixCompactRealForm(FinitelyGeneratedLieAlgebra): r""" @@ -1558,7 +1558,7 @@ def monomial_coefficients(self, copy=False): ####################################### -## Chevalley Basis +# Chevalley Basis class LieAlgebraChevalleyBasis(LieAlgebraWithStructureCoefficients): r""" @@ -1642,7 +1642,7 @@ def __classcall_private__(cls, R, cartan_type, epsilon=None): raise ValueError("not a valid Dynkin orientation") else: from sage.graphs.graph import Graph - G = Graph(epsilon, multiedges=True, loops=True, format="list_of_edges") + G = Graph(epsilon, multiedges=True, loops=True, format='list_of_edges') if (G.has_multiple_edges() or G.has_loops() or cartan_type.dynkin_diagram().to_undirected() != G.to_simple()): raise ValueError("not a valid Dynkin orientation") @@ -2054,7 +2054,7 @@ def _weight_action(self, m, wt): # enough in the ambient space to correctly convert things to do # the scalar product. alc = wt.parent().simple_coroots() - return R(wt.scalar( alc[aci[m]] )) + return R(wt.scalar(alc[aci[m]])) def affine(self, kac_moody=True): r""" @@ -2098,8 +2098,8 @@ def lie_algebra_generators(self, str_keys=False): INPUT: - - ``str_keys`` -- (default: ``False``) set to ``True`` to have the - indices indexed by strings instead of simple (co)roots + - ``str_keys`` -- boolean (default: ``False``); set to ``True`` to have + the indices indexed by strings instead of simple (co)roots EXAMPLES:: @@ -2197,7 +2197,7 @@ def highest_root_basis_elt(self, pos=True): INPUT: - - ``pos`` -- (default: ``True``) if ``True``, then return + - ``pos`` -- boolean (default: ``True``); if ``True``, then return `e_{\theta}`, otherwise return `f_{\theta}` EXAMPLES:: diff --git a/src/sage/algebras/lie_algebras/examples.py b/src/sage/algebras/lie_algebras/examples.py index 7c3f373f7cd..f2db23d445b 100644 --- a/src/sage/algebras/lie_algebras/examples.py +++ b/src/sage/algebras/lie_algebras/examples.py @@ -211,7 +211,7 @@ def affine_transformations_line(R, names=['X', 'Y'], representation='bracket'): sage: L[X, Y] == Y True sage: TestSuite(L).run() - sage: L = lie_algebras.affine_transformations_line(QQ, representation="matrix") + sage: L = lie_algebras.affine_transformations_line(QQ, representation='matrix') sage: X, Y = L.lie_algebra_generators() sage: L[X, Y] == Y True @@ -264,7 +264,7 @@ def abelian(R, names=None, index_set=None): return AbelianLieAlgebra(R, names=names, index_set=index_set) -def Heisenberg(R, n, representation="structure"): +def Heisenberg(R, n, representation='structure'): """ Return the rank ``n`` Heisenberg algebra in the given representation. @@ -272,10 +272,11 @@ def Heisenberg(R, n, representation="structure"): - ``R`` -- the base ring - ``n`` -- the rank (a nonnegative integer or infinity) - - ``representation`` -- (default: "structure") can be one of the following: + - ``representation`` -- (default: ``'structure'``) can be one of the + following: - - ``"structure"`` -- using structure coefficients - - ``"matrix"`` -- using matrices + - ``'structure'`` -- using structure coefficients + - ``'matrix'`` -- using matrices EXAMPLES:: @@ -322,7 +323,7 @@ def pwitt(R, p): INPUT: - ``R`` -- the base ring - - ``p`` -- a positive integer that is `0` in ``R`` + - ``p`` -- positive integer that is `0` in `R` EXAMPLES:: diff --git a/src/sage/algebras/lie_algebras/free_lie_algebra.py b/src/sage/algebras/lie_algebras/free_lie_algebra.py index f0decd311c3..f5217231263 100644 --- a/src/sage/algebras/lie_algebras/free_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/free_lie_algebra.py @@ -496,9 +496,7 @@ def _generate_hall_set(self, k): """ Generate the Hall set of grade ``k``. - OUTPUT: - - A sorted tuple of :class:`GradedLieBracket` elements. + OUTPUT: a sorted tuple of :class:`GradedLieBracket` elements EXAMPLES:: diff --git a/src/sage/algebras/lie_algebras/heisenberg.py b/src/sage/algebras/lie_algebras/heisenberg.py index 5e4dd1c90ae..de4a6b27562 100644 --- a/src/sage/algebras/lie_algebras/heisenberg.py +++ b/src/sage/algebras/lie_algebras/heisenberg.py @@ -227,7 +227,7 @@ def n(self): sage: H = lie_algebras.Heisenberg(QQ, 3) sage: H.n() 3 - sage: H = lie_algebras.Heisenberg(QQ, 3, representation="matrix") + sage: H = lie_algebras.Heisenberg(QQ, 3, representation='matrix') sage: H.n() 3 """ @@ -313,7 +313,7 @@ def _coerce_map_from_(self, H): EXAMPLES:: sage: HB = lie_algebras.Heisenberg(QQ, 3) - sage: HM = lie_algebras.Heisenberg(QQ, 3, representation="matrix") + sage: HM = lie_algebras.Heisenberg(QQ, 3, representation='matrix') sage: HB.has_coerce_map_from(HM) True sage: HM.has_coerce_map_from(HB) @@ -336,7 +336,7 @@ def _coerce_map_from_(self, H): True sage: HB(HZ.p(2)) p2 - sage: HZ = lie_algebras.Heisenberg(ZZ, 2, representation="matrix") + sage: HZ = lie_algebras.Heisenberg(ZZ, 2, representation='matrix') sage: HB.has_coerce_map_from(HZ) True sage: HB(HZ.p(2)) @@ -548,7 +548,7 @@ def _coerce_map_from_(self, H): True sage: phi(HZ.p(3)).leading_coefficient().parent() Rational Field - sage: HF = lie_algebras.Heisenberg(QQ, 3, representation="matrix") + sage: HF = lie_algebras.Heisenberg(QQ, 3, representation='matrix') sage: H.has_coerce_map_from(HF) True sage: H(HF.p(2)) @@ -631,7 +631,7 @@ class HeisenbergAlgebra_matrix(HeisenbergAlgebra_fd, LieAlgebraFromAssociative): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 1, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 1, representation='matrix') sage: p = L.p(1) sage: q = L.q(1) sage: z = L.bracket(p, q); z @@ -643,7 +643,7 @@ class HeisenbergAlgebra_matrix(HeisenbergAlgebra_fd, LieAlgebraFromAssociative): sage: L.dimension() 3 - sage: L = lie_algebras.Heisenberg(QQ, 2, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 2, representation='matrix') sage: sorted(dict(L.basis()).items()) [( [0 1 0 0] @@ -676,7 +676,7 @@ class HeisenbergAlgebra_matrix(HeisenbergAlgebra_fd, LieAlgebraFromAssociative): 'z', [0 0 0 0] )] - sage: L = lie_algebras.Heisenberg(QQ, 0, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 0, representation='matrix') sage: sorted(dict(L.basis()).items()) [( [0 1] @@ -697,7 +697,7 @@ def __init__(self, R, n): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 2, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 2, representation='matrix') sage: TestSuite(L).run() """ HeisenbergAlgebra_fd.__init__(self, n) @@ -718,7 +718,7 @@ def _repr_(self): EXAMPLES:: - sage: lie_algebras.Heisenberg(QQ, 3, representation="matrix") + sage: lie_algebras.Heisenberg(QQ, 3, representation='matrix') Heisenberg algebra of rank 3 over Rational Field """ return "Heisenberg algebra of rank {} over {}".format(self._n, self.base_ring()) @@ -729,7 +729,7 @@ def p(self, i): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 1, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 1, representation='matrix') sage: L.p(1) [0 1 0] [0 0 0] @@ -743,7 +743,7 @@ def q(self, i): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 1, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 1, representation='matrix') sage: L.q(1) [0 0 0] [0 0 1] @@ -759,7 +759,7 @@ def z(self): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 1, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 1, representation='matrix') sage: L.z() [0 0 1] [0 0 0] @@ -773,7 +773,7 @@ def step(self): EXAMPLES:: - sage: h = lie_algebras.Heisenberg(ZZ, 2, representation="matrix") + sage: h = lie_algebras.Heisenberg(ZZ, 2, representation='matrix') sage: h.step() 2 """ @@ -792,7 +792,7 @@ def monomial_coefficients(self, copy=True): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 3, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 3, representation='matrix') sage: elt = L(Matrix(QQ, [[0, 1, 3, 0, 3], [0, 0, 0, 0, 0], [0, 0, 0, 0, -3], ....: [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]])) sage: elt diff --git a/src/sage/algebras/lie_algebras/lie_algebra.py b/src/sage/algebras/lie_algebras/lie_algebra.py index 885dcf44f0d..12a992bbffd 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra.py +++ b/src/sage/algebras/lie_algebras/lie_algebra.py @@ -276,7 +276,7 @@ class LieAlgebra(Parent, UniqueRepresentation): # IndexedGenerators): sage: L = LieAlgebra(QQ, 'x,y,z'); L Free Lie algebra generated by (x, y, z) over Rational Field - sage: P. = LieAlgebra(QQ, representation="polynomial"); P + sage: P. = LieAlgebra(QQ, representation='polynomial'); P Lie algebra generated by (a, b, c) in Free Algebra on 3 generators (a, b, c) over Rational Field @@ -306,7 +306,7 @@ class LieAlgebra(Parent, UniqueRepresentation): # IndexedGenerators): So the generators of the free Lie algebra are the generators of the free algebra and the Lie bracket is the commutator:: - sage: P. = LieAlgebra(QQ, representation="polynomial"); P + sage: P. = LieAlgebra(QQ, representation='polynomial'); P Lie algebra generated by (a, b, c) in Free Algebra on 3 generators (a, b, c) over Rational Field sage: P.bracket(a, b) + P.bracket(a - c, b + 3*c) @@ -540,7 +540,7 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: L. = LieAlgebra(QQ, representation="polynomial") + sage: L. = LieAlgebra(QQ, representation='polynomial') sage: elt = L([x, y]); elt x*y - y*x sage: elt.parent() is L @@ -581,7 +581,7 @@ def __getitem__(self, x): EXAMPLES:: - sage: L. = LieAlgebra(QQ, representation="polynomial") + sage: L. = LieAlgebra(QQ, representation='polynomial') sage: L[x, [y, x]] -x^2*y + 2*x*y*x - y*x^2 @@ -690,7 +690,7 @@ def zero(self): EXAMPLES:: - sage: L. = LieAlgebra(QQ, representation="polynomial") + sage: L. = LieAlgebra(QQ, representation='polynomial') sage: L.zero() 0 """ @@ -704,14 +704,14 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): INPUT: - - ``d`` -- a dictionary ``{index: coeff}`` where each ``index`` is the + - ``d`` -- dictionary ``{index: coeff}`` where each ``index`` is the index of a basis element and each ``coeff`` belongs to the coefficient ring ``self.base_ring()`` - - ``coerce`` -- a boolean (default: ``False``), whether to coerce the + - ``coerce`` -- boolean (default: ``False``); whether to coerce the ``coeff`` to the coefficient ring - - ``remove_zeros`` -- a boolean (default: ``True``), if some + - ``remove_zeros`` -- boolean (default: ``True``); if some ``coeff`` may be zero and should therefore be removed EXAMPLES:: @@ -816,7 +816,7 @@ def lie_algebra_generators(self): EXAMPLES:: - sage: L. = LieAlgebra(QQ, representation="polynomial") + sage: L. = LieAlgebra(QQ, representation='polynomial') sage: L.lie_algebra_generators() Finite family {'x': x, 'y': y} """ @@ -860,7 +860,7 @@ def indices(self): EXAMPLES:: - sage: L. = LieAlgebra(QQ, representation="polynomial") + sage: L. = LieAlgebra(QQ, representation='polynomial') sage: L.indices() {'x', 'y'} """ @@ -1399,7 +1399,7 @@ def _bracket_(self, rhs): EXAMPLES:: - sage: L. = LieAlgebra(QQ, representation="polynomial") + sage: L. = LieAlgebra(QQ, representation='polynomial') sage: L.bracket(x, y) x*y - y*x @@ -1526,9 +1526,7 @@ def matrix(self): r""" Return ``self`` as element of the underlying matrix algebra. - OUTPUT: - - An instance of the element class of MatrixSpace. + OUTPUT: an instance of the element class of MatrixSpace EXAMPLES:: diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index 92aeeaa7959..b24e931b5e8 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -35,7 +35,7 @@ cdef class LieAlgebraElement(IndexedFreeModuleElement): # Need to bypass the coercion model def __mul__(left, right): """ - If we are multiplying two non-zero elements, automatically + If we are multiplying two nonzero elements, automatically lift up to the universal enveloping algebra. EXAMPLES:: @@ -263,7 +263,7 @@ cdef class LieAlgebraElementWrapper(ElementWrapper): """ def __bool__(self): """ - Return if ``self`` is non-zero. + Return if ``self`` is nonzero. EXAMPLES:: @@ -305,7 +305,7 @@ cdef class LieAlgebraElementWrapper(ElementWrapper): # Need to bypass the coercion model def __mul__(left, right): """ - If we are multiplying two non-zero elements, automatically + If we are multiplying two nonzero elements, automatically lift up to the universal enveloping algebra. .. TODO:: @@ -475,7 +475,7 @@ cdef class LieAlgebraMatrixWrapper(LieAlgebraElementWrapper): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 1, representation="matrix") + sage: L = lie_algebras.Heisenberg(QQ, 1, representation='matrix') sage: z = L.z() sage: z.value.is_immutable() True @@ -583,7 +583,7 @@ cdef class LieSubalgebraElementWrapper(LieAlgebraElementWrapper): INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally + - ``copy`` -- boolean (default: ``True``); if ``self`` is internally represented by a dictionary ``d``, then make a copy of ``d``; if ``False``, then this can cause undesired behavior by mutating ``d`` diff --git a/src/sage/algebras/lie_algebras/meson.build b/src/sage/algebras/lie_algebras/meson.build new file mode 100644 index 00000000000..f50959cb44b --- /dev/null +++ b/src/sage/algebras/lie_algebras/meson.build @@ -0,0 +1,42 @@ +py.install_sources( + 'abelian.py', + 'affine_lie_algebra.py', + 'all.py', + 'bch.py', + 'bgg_dual_module.py', + 'bgg_resolution.py', + 'center_uea.py', + 'classical_lie_algebra.py', + 'examples.py', + 'free_lie_algebra.py', + 'heisenberg.py', + 'lie_algebra.py', + 'lie_algebra_element.pxd', + 'morphism.py', + 'nilpotent_lie_algebra.py', + 'onsager.py', + 'poincare_birkhoff_witt.py', + 'quotient.py', + 'rank_two_heisenberg_virasoro.py', + 'representation.py', + 'structure_coefficients.py', + 'subalgebra.py', + 'symplectic_derivation.py', + 'verma_module.py', + 'virasoro.py', + subdir: 'sage/algebras/lie_algebras', +) + +extension_data = {'lie_algebra_element' : files('lie_algebra_element.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras/lie_algebras', + install: true, + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/algebras/lie_algebras/morphism.py b/src/sage/algebras/lie_algebras/morphism.py index 32b36c26590..0e76f37e37f 100644 --- a/src/sage/algebras/lie_algebras/morphism.py +++ b/src/sage/algebras/lie_algebras/morphism.py @@ -385,7 +385,7 @@ class LieAlgebraMorphism_from_generators(LieAlgebraHomomorphism_im_gens): Note that if base_map is nontrivial then the result will not be a morphism in the category of Lie algebras over the base ring. - - ``check`` -- (default: ``True``) boolean; if ``False`` the + - ``check`` -- boolean (default: ``True``); if ``False`` the values on the Lie brackets implied by ``on_generators`` will not be checked for contradictory values diff --git a/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py b/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py index d68d186e0be..062afc42c20 100644 --- a/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py @@ -29,13 +29,13 @@ class NilpotentLieAlgebra_dense(LieAlgebraWithStructureCoefficients): INPUT: - ``R`` -- the base ring - - ``s_coeff`` -- a dictionary of structural coefficients - - ``names`` -- (default:``None``) list of strings to use as names of basis + - ``s_coeff`` -- dictionary of structural coefficients + - ``names`` -- (default: ``None``) list of strings to use as names of basis elements; if ``None``, the names will be inferred from the structural coefficients - - ``index_set`` -- (default:``None``) list of hashable and comparable + - ``index_set`` -- (default: ``None``) list of hashable and comparable elements to use for indexing - - ``step`` -- (optional) an integer; the nilpotency step of the + - ``step`` -- integer (optional); the nilpotency step of the Lie algebra if known; otherwise it will be computed when needed - ``category`` -- (optional) a subcategory of finite dimensional nilpotent Lie algebras with basis @@ -174,9 +174,9 @@ class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense): INPUT: - ``R`` -- the base ring - - ``r`` -- an integer; the number of generators - - ``s`` -- an integer; the nilpotency step of the algebra - - ``names`` -- (optional) a string or a list of strings used to name the + - ``r`` -- integer; the number of generators + - ``s`` -- integer; the nilpotency step of the algebra + - ``names`` -- (optional) string or list of strings used to name the basis elements; if ``names`` is a string, then names for the basis will be autogenerated as determined by the ``naming`` parameter - ``naming`` -- (optional) a string; the naming scheme to use for @@ -340,7 +340,7 @@ def __classcall_private__(cls, R, r, s, names=None, naming=None, category=None, def __init__(self, R, r, s, names, naming, category, **kwds): r""" - Initialize ``self`` + Initialize ``self``. EXAMPLES:: diff --git a/src/sage/algebras/lie_algebras/onsager.py b/src/sage/algebras/lie_algebras/onsager.py index d4d224ea847..0de70c0a630 100644 --- a/src/sage/algebras/lie_algebras/onsager.py +++ b/src/sage/algebras/lie_algebras/onsager.py @@ -318,7 +318,7 @@ def alternating_central_extension(self): Element = LieAlgebraElement ##################################################################### -## q-Onsager algebra (the quantum group) +# q-Onsager algebra (the quantum group) class QuantumOnsagerAlgebra(CombinatorialFreeModule): @@ -795,10 +795,10 @@ def a(m, p): assert m > 0 terms = q**-2 * self.monomial(B[kr] * B[kl]) terms -= self.monomial(B[1,m]) - temp = ( -sum(q**(-2*(p-1)) * self.monomial(B[1,m-2*p]) + temp = (-sum(q**(-2*(p-1)) * self.monomial(B[1,m-2*p]) for p in range(1, (m - 1) // 2 + 1)) + sum(a(m,p) * self.monomial(B[0,kr[1]-p]) * self.monomial(B[0,p+kl[1]]) - for p in range(1, m // 2 + 1)) ) + for p in range(1, m // 2 + 1))) terms += (q**-2 - 1) * temp else: r = -kr[1] - 1 @@ -812,10 +812,10 @@ def a(m, p): terms -= (q**2-q**-2) * sum(q**(2*(r-1-k)) * self.monomial(B[0,-(k+1)]) * self.monomial(B[0,-r+kl[1]+k]) for k in range(r)) m = -r + kl[1] + 1 - temp = ( -sum(q**(-2*(p-1)) * self.monomial(B[1,m-2*p]) + temp = (-sum(q**(-2*(p-1)) * self.monomial(B[1,m-2*p]) for p in range(1, (m - 1) // 2 + 1)) + sum(a(m,p) * self.monomial(B[0,m-p-1]) * self.monomial(B[0,p-1]) - for p in range(1, m // 2 + 1)) ) + for p in range(1, m // 2 + 1))) terms += (q**-2 - 1) * q**(2*r) * temp else: # [B[rd+a0], B[sd+a1]] r > s @@ -826,10 +826,10 @@ def a(m, p): terms -= (q**2-q**-2) * sum(q**(2*(kl[1]-1-k)) * self.monomial(B[0,-(r-kl[1]+k+1)]) * self.monomial(B[0,k]) for k in range(kl[1])) m = r - kl[1] + 1 - temp = ( -sum(q**(-2*(p-1)) * self.monomial(B[1,m-2*p]) + temp = (-sum(q**(-2*(p-1)) * self.monomial(B[1,m-2*p]) for p in range(1, (m - 1) // 2 + 1)) + sum(a(m,p) * self.monomial(B[0,-p]) * self.monomial(B[0,p-m]) - for p in range(1, m // 2 + 1)) ) + for p in range(1, m // 2 + 1))) terms += (q**-2 - 1) * q**(2*kl[1]) * temp terms = -q**2 * terms elif kl[0] == 1 and kr[0] == 0: @@ -877,7 +877,7 @@ def a(m, p): for h in range(1, ell)) - q**(2*(ell-1)) * self.monomial(B[0,-(p-ell+1)] * B[1,kl[1]-ell]) for ell in range(1, kl[1])) - else: #kl[0] == 0 and kr[0] == 1: + else: # kl[0] == 0 and kr[0] == 1: terms = self.monomial(B[kr] * B[kl]) if kl[1] < kr[1]: # [B[pd+a1], B[md]] with p < m @@ -923,7 +923,7 @@ def a(m, p): return self.monomial(lhs // B[kl]) * terms * self.monomial(rhs // B[kr]) ##################################################################### -## ACE of the Onsager algebra +# ACE of the Onsager algebra class OnsagerAlgebraACE(InfinitelyGeneratedLieAlgebra, IndexedGenerators): diff --git a/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py b/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py index 3b59303d0dc..41dc9cd8159 100644 --- a/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py +++ b/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py @@ -18,9 +18,11 @@ #***************************************************************************** from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.structure.element import get_coercion_model from operator import mul from sage.categories.algebras import Algebras +from sage.categories.triangular_kac_moody_algebras import TriangularKacMoodyAlgebras from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid from sage.combinat.free_module import CombinatorialFreeModule from sage.sets.family import Family @@ -61,12 +63,12 @@ class PoincareBirkhoffWittBasis(CombinatorialFreeModule): We then do some computations; in particular, we check that `[E, F] = H`:: - sage: E,F,H = PBW.algebra_generators() - sage: E*F + sage: E, F, H = PBW.algebra_generators() + sage: E * F PBW['E']*PBW['F'] - sage: F*E + sage: F * E PBW['E']*PBW['F'] - PBW['H'] - sage: E*F - F*E + sage: E * F - F * E PBW['H'] Next we construct another instance of the PBW basis, but sorted in the @@ -108,7 +110,7 @@ class PoincareBirkhoffWittBasis(CombinatorialFreeModule): """ @staticmethod def __classcall_private__(cls, g, basis_key=None, prefix='PBW', **kwds): - """ + r""" Normalize input to ensure a unique representation. TESTS:: @@ -120,25 +122,30 @@ def __classcall_private__(cls, g, basis_key=None, prefix='PBW', **kwds): sage: P1 is P2 True """ - return super().__classcall__(cls, - g, basis_key, prefix, **kwds) + if g in TriangularKacMoodyAlgebras.FiniteDimensional: + return PoincareBirkhoffWittBasisSemisimpleLieAlgebra(g, basis_key, prefix, **kwds) + return super().__classcall__(cls, g, basis_key, prefix, **kwds) def __init__(self, g, basis_key, prefix, **kwds): - """ + r""" Initialize ``self``. TESTS:: - sage: L = lie_algebras.sl(QQ, 2) - sage: PBW = L.pbw_basis() - sage: E,F,H = PBW.algebra_generators() - sage: TestSuite(PBW).run(elements=[E, F, H]) - sage: TestSuite(PBW).run(elements=[E, F, H, E*F + H]) # long time + sage: L = lie_algebras.VirasoroAlgebra(QQ) + sage: U = L.pbw_basis() + sage: d = U.algebra_generators() + sage: TestSuite(U).run() + sage: elts = [d[1], d[-1], d[2], d[-2]*d[1], d[-1]*d[1], d[3]^3*d[5], d['c']] + sage: TestSuite(U).run(elements=elts) # long time """ if basis_key is not None: self._basis_key = basis_key else: - self._basis_key_inverse = None + try: + self._basis_key = g._basis_key + except AttributeError: + self._basis_key_inverse = None R = g.base_ring() self._g = g @@ -630,3 +637,178 @@ def _act_on_(self, x, self_on_left): ret += term return ret return None + + +class PoincareBirkhoffWittBasisSemisimpleLieAlgebra(PoincareBirkhoffWittBasis): + r""" + The Poincare-Birkhoff-Witt basis of a finite dimensional triangular + Kac-Moody Lie algebra (i.e., a semisimple Lie algebra). + """ + def __init__(self, g, basis_key=None, *args, **kwds): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: U = lie_algebras.so(QQ, 5).pbw_basis() + sage: TestSuite(U).run() + + sage: L = lie_algebras.sl(QQ, 2) + sage: PBW = L.pbw_basis() + sage: E, F, H = PBW.algebra_generators() + sage: TestSuite(PBW).run(elements=[E, F, H]) + sage: TestSuite(PBW).run(elements=[E, F, H, E*F + H]) # long time + """ + super().__init__(g, basis_key, *args, **kwds) + if self._basis_key == self._g._triangular_key: + self._triangular_pbw = self + else: + self._triangular_pbw = self._g.pbw_basis(basis_key=self._g._triangular_key) + + def e(self, i=None): + r""" + Return the generators `e` of ``self``. + + INPUT: + + - ``i`` -- (optional) if specified, return just the + generator `e_i` + + EXAMPLES:: + + sage: U = lie_algebras.so(QQ, 5).pbw_basis() + sage: U.e() + Finite family {1: PBW[alpha[1]], 2: PBW[alpha[2]]} + sage: U.e(1) + PBW[alpha[1]] + """ + if i is None: + return Family({i: self.e(i) for i in self._g.cartan_type().index_set()}) + return self(self._g.e(i)) + + def f(self, i=None): + r""" + Return the generators `f` of ``self``. + + INPUT: + + - ``i`` -- (optional) if specified, return just the + generator `f_i` + + EXAMPLES:: + + sage: U = lie_algebras.so(QQ, 5).pbw_basis() + sage: U.f() + Finite family {1: PBW[-alpha[1]], 2: PBW[-alpha[2]]} + sage: U.f(1) + PBW[-alpha[1]] + """ + if i is None: + return Family({i: self.f(i) for i in self._g.cartan_type().index_set()}) + return self(self._g.f(i)) + + def contravariant_form(self, x, y): + r""" + Return the (universal) contravariant form of ``x`` and ``y``. + + Let `\varphi \colon U(\mathfrak{g}) \to U(\mathfrak{h})` denote + the projection onto the Cartan subalgebra and `\tau` be the transpose + map. The *(universal) contravariant form* is defined as + + .. MATH:: + + (x, y) = \varphi(\tau(x) y). + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: U = g.pbw_basis() + sage: f1, f2 = U.f() + sage: e1, e2 = U.e() + sage: U.contravariant_form(U.one(), U.one()) + 1 + sage: U.contravariant_form(f1, f1) + PBW[alphacheck[1]] + sage: U.contravariant_form(f2, f2) + PBW[alphacheck[2]] + sage: U.contravariant_form(f1*f2, f1*f2) + PBW[alphacheck[1]]*PBW[alphacheck[2]] + 3*PBW[alphacheck[2]] + sage: U.contravariant_form(e1*e1*e2, e2*e1*e2) + 0 + sage: cas = U.casimir_element() + sage: ccc = U.contravariant_form(cas, cas); ccc + 1/144*PBW[alphacheck[1]]^4 + 1/24*PBW[alphacheck[1]]^3*PBW[alphacheck[2]] + + 5/48*PBW[alphacheck[1]]^2*PBW[alphacheck[2]]^2 + + 1/8*PBW[alphacheck[1]]*PBW[alphacheck[2]]^3 + 1/16*PBW[alphacheck[2]]^4 + + 5/72*PBW[alphacheck[1]]^3 + 1/3*PBW[alphacheck[1]]^2*PBW[alphacheck[2]] + + 7/12*PBW[alphacheck[1]]*PBW[alphacheck[2]]^2 + 3/8*PBW[alphacheck[2]]^3 + + 25/144*PBW[alphacheck[1]]^2 + 5/8*PBW[alphacheck[1]]*PBW[alphacheck[2]] + + 9/16*PBW[alphacheck[2]]^2 + sage: ccc.parent() is U + True + """ + x = self._triangular_pbw(x) + y = self._triangular_pbw(y) + temp = (x.transpose() * y)._monomial_coefficients + part = self._g._part_on_basis + ret = {mon: temp[mon] for mon in temp if all(part(b) == 0 for b in mon.support())} + # TODO: Construct this direct in ``self`` + return self(self._triangular_pbw.element_class(self._triangular_pbw, ret)) + + @cached_method + def _transpose_on_basis(self, m): + """ + Return the transpose map applied to the basis element indexed by ``m``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['E', 6]) + sage: U = g.pbw_basis() + sage: f1, f2, f3, f4, f5, f6 = U.f() + sage: e1, e2, e3, e4, e5, e6 = U.e() + sage: elt = e1 * e4^2 * f1 * f2^3 + sage: U._transpose_on_basis(elt.support()[0]) + PBW[alpha[2]]^3*PBW[alpha[1]]*PBW[-alpha[4]]^2*PBW[-alpha[1]] + """ + I = self._indices + basis_mapping = self._g._transpose_basis_mapping + return self.prod(self.monomial(I({basis_mapping[k]: e})) + for k, e in reversed(m._sorted_items())) + + @lazy_attribute + def transpose(self): + r""" + The transpose map. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['F', 4]) + sage: U = g.pbw_basis() + sage: U.transpose + Generic endomorphism of Universal enveloping algebra of Lie algebra + of ['F', 4] in the Chevalley basis in the Poincare-Birkhoff-Witt basis + """ + return self.module_morphism(self._transpose_on_basis, codomain=self) + + class Element(PoincareBirkhoffWittBasis.Element): + def transpose(self): + r""" + Return the transpose map of ``self``. + + This is the transpose map on the Lie algebra extended + as an anti-involution of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['D', 4]) + sage: U = g.pbw_basis() + sage: e = U.e() + sage: f = U.f() + sage: elts = [e[1], e[1]*e[2], e[3]+e[4], e[1]*e[3]*e[4] + e[2], + ....: f[1], f[1]*f[2], f[3]+f[4], e[1]*e[3]*e[4] + e[2], + ....: e[1]*f[1], f[1]*e[1], (e[2]*f[2] - f[2]*e[2])^2] + sage: all((b*bp).transpose() == bp.transpose() * b.transpose() + ....: for b in elts for bp in elts) + True + """ + return self.parent().transpose(self) diff --git a/src/sage/algebras/lie_algebras/quotient.py b/src/sage/algebras/lie_algebras/quotient.py index 2bb472206c3..06f6d0eb55a 100644 --- a/src/sage/algebras/lie_algebras/quotient.py +++ b/src/sage/algebras/lie_algebras/quotient.py @@ -33,7 +33,7 @@ class LieQuotient_finite_dimensional_with_basis(LieAlgebraWithStructureCoefficie - ``I`` -- an ideal or a list of generators of the ideal - ``ambient`` -- (optional) the Lie algebra to be quotiented; will be deduced from ``I`` if not given - - ``names`` -- (optional) a string or a list of strings; + - ``names`` -- (optional) string or list of strings; names for the basis elements of the quotient. If ``names`` is a string, the basis will be named ``names_1``,...,``names_n``. diff --git a/src/sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py b/src/sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py index 4957ecf7bc9..b3fa2b0c7f4 100644 --- a/src/sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +++ b/src/sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py @@ -211,7 +211,7 @@ def K(self, i=None): """ if i is None: return Family(self._KI, self.K) - return self.monomial( ('K', i) ) + return self.monomial(('K', i)) def t(self, a, b): r""" @@ -225,7 +225,7 @@ def t(self, a, b): """ if a == b == 0: raise ValueError("no t(0, 0) element") - return self.monomial( ('t', self._v(a,b)) ) + return self.monomial(('t', self._v(a,b))) def E(self, a, b): r""" @@ -239,7 +239,7 @@ def E(self, a, b): """ if a == b == 0: raise ValueError("no E(0, 0) element") - return self.monomial( ('E', self._v(a,b)) ) + return self.monomial(('E', self._v(a,b))) def _v(self, a, b): r""" @@ -324,10 +324,10 @@ def _an_element_(self): d = self.monomial v = self._v return ( - d( ('E',v(1,-3)) ) - - self.base_ring().an_element() * d( ('t',v(-1,3)) ) - + d( ('E',v(2,2)) ) - + d( ('K',3) ) + d(('E',v(1,-3))) + - self.base_ring().an_element() * d(('t',v(-1,3))) + + d(('E',v(2,2))) + + d(('K',3)) ) def some_elements(self): @@ -345,9 +345,9 @@ def some_elements(self): """ d = self.monomial v = self._v - return [d( ('E',v(1,1)) ), d( ('E',v(-2,-2)) ), d( ('E',v(0,1)) ), - d( ('t',v(1,1)) ), d( ('t',v(4,-1)) ), d( ('t',v(2,3)) ), - d( ('K',2) ), d( ('K',4) ), self.an_element()] + return [d(('E',v(1,1))), d(('E',v(-2,-2))), d(('E',v(0,1))), + d(('t',v(1,1))), d(('t',v(4,-1))), d(('t',v(2,3))), + d(('K',2)), d(('K',4)), self.an_element()] class Element(LieAlgebraElement): pass diff --git a/src/sage/algebras/lie_algebras/representation.py b/src/sage/algebras/lie_algebras/representation.py index bedcb869867..af05b3c5ab5 100644 --- a/src/sage/algebras/lie_algebras/representation.py +++ b/src/sage/algebras/lie_algebras/representation.py @@ -60,9 +60,7 @@ def side(self): r""" Return that ``self`` is a left representation. - OUTPUT: - - - the string ``"left"`` + OUTPUT: the string ``'left'`` EXAMPLES:: @@ -102,7 +100,7 @@ def representation_matrix(self, elt): EXAMPLES:: sage: H1 = lie_algebras.Heisenberg(QQ, 1) - sage: F = H1.faithful_representation(algorithm="minimal") + sage: F = H1.faithful_representation(algorithm='minimal') sage: P1 = F.representation_matrix(H1.gen(0)); P1 [0 0 0] [0 0 0] @@ -144,10 +142,10 @@ class RepresentationByMorphism(CombinatorialFreeModule, Representation_abstract) - ``f`` -- the Lie algebra morphism defining the action of the basis elements of ``lie_algebra`` - ``index_set`` -- (optional) the index set of the module basis - - ``on_basis`` -- (default: ``False``) the function ``f`` defines a + - ``on_basis`` -- boolean (default: ``False``); the function `f` defines a map from the basis elements or from a generic element of ``lie_algebra`` - If ``f`` is encoded as a ``dict`` or ``Family``, then the keys must + If `f` is encoded as a ``dict`` or ``Family``, then the keys must be indices of the basis of ``lie_algebra`` and the values being the corresponding matrix defining the action. This sets ``on_basis=True``. @@ -476,7 +474,7 @@ def _acted_upon_(self, scalar, self_on_left=False): class FaithfulRepresentationNilpotentPBW(CombinatorialFreeModule, Representation_abstract): r""" - Return a faithful reprensetation of a nilpotent Lie algebra + Return a faithful representation of a nilpotent Lie algebra constructed using the PBW basis. Let `L` be a `k`-step nilpotent Lie algebra. Define a weight function @@ -509,7 +507,7 @@ class FaithfulRepresentationNilpotentPBW(CombinatorialFreeModule, Representation 2*F[1, 0, 0] + 8*F[1, 1, 0] + 3*F[2, 0, 0] + 4*F[0, 1, 0] + 4*F[0, 2, 0] + 4*F[0, 0, 1] - sage: MF = L.faithful_representation(algorithm="minimal") + sage: MF = L.faithful_representation(algorithm='minimal') sage: MF.dimension() 3 sage: [MF.representation_matrix(be) for be in L.basis()] @@ -527,7 +525,7 @@ class FaithfulRepresentationNilpotentPBW(CombinatorialFreeModule, Representation sage: F = L.faithful_representation(); F Faithful 11 dimensional representation of Lie algebra on 4 generators (a, b, c, d) over Rational Field - sage: MF = L.faithful_representation(algorithm="minimal"); MF + sage: MF = L.faithful_representation(algorithm='minimal'); MF Minimal faithful representation of Lie algebra on 4 generators (a, b, c, d) over Rational Field sage: MF.dimension() @@ -551,14 +549,14 @@ def __init__(self, L, minimal=False): sage: H2 = lie_algebras.Heisenberg(QQ, 2) sage: F = H2.faithful_representation() sage: TestSuite(F).run(elements=list(F.basis())) - sage: MF = H2.faithful_representation(algorithm="minimal") + sage: MF = H2.faithful_representation(algorithm='minimal') sage: TestSuite(MF).run(elements=list(MF.basis())) sage: sc = {('a','b'): {'b':-1, 'c':1}, ('a','c'): {'b':-1, 'c':1}} sage: L. = LieAlgebra(QQ, sc) sage: F = L.faithful_representation() sage: TestSuite(F).run(elements=list(F.basis())) - sage: MF = L.faithful_representation(algorithm="minimal") + sage: MF = L.faithful_representation(algorithm='minimal') sage: TestSuite(MF).run(elements=list(MF.basis())) """ LCS = L.lower_central_series() diff --git a/src/sage/algebras/lie_algebras/structure_coefficients.py b/src/sage/algebras/lie_algebras/structure_coefficients.py index 862ee657138..5c0c9c8bcbf 100644 --- a/src/sage/algebras/lie_algebras/structure_coefficients.py +++ b/src/sage/algebras/lie_algebras/structure_coefficients.py @@ -48,7 +48,7 @@ class LieAlgebraWithStructureCoefficients(FinitelyGeneratedLieAlgebra, IndexedGe - ``R`` -- a ring, to be used as the base ring - - ``s_coeff`` -- a dictionary, indexed by pairs of basis indices + - ``s_coeff`` -- dictionary, indexed by pairs of basis indices (see below), and whose values are dictionaries which are indexed by (single) basis indices and whose values are elements of `R` @@ -366,7 +366,7 @@ def _from_dict(self, d, coerce=False, remove_zeros=False): INPUT: - - ``d`` -- a dictionary ``{index: coeff}`` where each ``index`` is the + - ``d`` -- dictionary ``{index: coeff}`` where each ``index`` is the index of a basis element and each ``coeff`` belongs to the coefficient ring ``self.base_ring()`` - ``coerce`` -- ignored @@ -428,7 +428,7 @@ def _sorted_items_for_printing(self): .. WARNING:: The internal representation order is fixed, whereas this - depends on ``"sorting_key"`` print option as it is used + depends on ``'sorting_key'`` print option as it is used only for printing. EXAMPLES:: diff --git a/src/sage/algebras/lie_algebras/subalgebra.py b/src/sage/algebras/lie_algebras/subalgebra.py index a7fe9752856..1dd5444f766 100644 --- a/src/sage/algebras/lie_algebras/subalgebra.py +++ b/src/sage/algebras/lie_algebras/subalgebra.py @@ -35,8 +35,8 @@ class LieSubalgebra_finite_dimensional_with_basis(Parent, UniqueRepresentation): INPUT: - ``ambient`` -- the Lie algebra containing the subalgebra - - ``gens`` -- a list of generators of the subalgebra - - ``ideal`` -- (default: ``False``) a boolean; if ``True``, then ``gens`` + - ``gens`` -- list of generators of the subalgebra + - ``ideal`` -- boolean (default: ``False``); if ``True``, then ``gens`` is interpreted as the generating set of an ideal instead of a subalgebra - ``order`` -- (optional) the key used to sort the indices of ``ambient`` - ``category`` -- (optional) a subcategory of subobjects of finite @@ -311,7 +311,6 @@ def __contains__(self, x): sage: I = L.subalgebra(x) sage: I(x) in I True - """ if x in self._ambient: x = self._ambient(x) @@ -770,7 +769,7 @@ def leading_monomials(self): def from_vector(self, v, order=None, coerce=False): r""" - Return the element of ``self`` corresponding to the vector ``v`` + Return the element of ``self`` corresponding to the vector ``v``. INPUT: diff --git a/src/sage/algebras/lie_algebras/symplectic_derivation.py b/src/sage/algebras/lie_algebras/symplectic_derivation.py index f9a2e483330..af294c4c4b0 100644 --- a/src/sage/algebras/lie_algebras/symplectic_derivation.py +++ b/src/sage/algebras/lie_algebras/symplectic_derivation.py @@ -261,9 +261,9 @@ def _an_element_(self): """ d = self.monomial return ( - d( _Partitions([2,1]) ) - - self.base_ring().an_element() * d( _Partitions([5,2,2,1]) ) - + d( _Partitions([2*self._g-1, self._g+1, 2, 1, 1]) ) + d(_Partitions([2,1])) + - self.base_ring().an_element() * d(_Partitions([5,2,2,1])) + + d(_Partitions([2*self._g-1, self._g+1, 2, 1, 1])) ) def some_elements(self): @@ -279,8 +279,8 @@ def some_elements(self): """ d = self.monomial g = self._g - return [d( _Partitions([2,1]) ), d( _Partitions([g+3,g+1]) ), d( _Partitions([2,1,1])), - d( _Partitions([2*g-1,2*g-2]) ), d( _Partitions([2*g-2,g-1,1]) ), + return [d(_Partitions([2,1])), d(_Partitions([g+3,g+1])), d(_Partitions([2,1,1])), + d(_Partitions([2*g-1,2*g-2])), d(_Partitions([2*g-2,g-1,1])), self.an_element()] class Element(LieAlgebraElement): diff --git a/src/sage/algebras/lie_algebras/verma_module.py b/src/sage/algebras/lie_algebras/verma_module.py index 7970e30ef8d..01320616c5a 100644 --- a/src/sage/algebras/lie_algebras/verma_module.py +++ b/src/sage/algebras/lie_algebras/verma_module.py @@ -35,7 +35,80 @@ from sage.rings.rational_field import QQ -class VermaModule(CombinatorialFreeModule): +class ModulePrinting: + """ + Helper mixin class for printing the module vectors. + """ + def __init__(self, vector_name='v'): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: from sage.algebras.lie_algebras.verma_module import ModulePrinting + sage: MP = ModulePrinting() + sage: TestSuite(MP).run(skip="_test_pickling") + """ + self.__vector_name = vector_name + + def _repr_generator(self, m): + r""" + Return a string representation of the generator indexed by ``m``. + + EXAMPLES:: + + sage: L = lie_algebras.sp(QQ, 4) + sage: La = L.cartan_type().root_system().ambient_space().fundamental_weights() + sage: M = L.verma_module(-1/2*La[1] + 3/7*La[2]) + sage: f1, f2 = L.f() + sage: x = M.pbw_basis()(L([f1, [f1, f2]])) + sage: v = x * M.highest_weight_vector() + sage: M._repr_generator(v.leading_support()) + 'f[-2*alpha[1] - alpha[2]]*v[(-1/14, 3/7)]' + + sage: M.highest_weight_vector() + v[(-1/14, 3/7)] + sage: 2 * M.highest_weight_vector() + 2*v[(-1/14, 3/7)] + """ + ret = super()._repr_generator(m) + if ret == '1': + ret = '' + else: + ret += '*' + return ret + self.__vector_name + "[{}]".format(self._weight) + + def _latex_generator(self, m): + r""" + Return a latex representation of the generator indexed by ``m``. + + EXAMPLES:: + + sage: L = lie_algebras.sp(QQ, 4) + sage: La = L.cartan_type().root_system().ambient_space().fundamental_weights() + sage: M = L.verma_module(-1/2*La[1] + 3/7*La[2]) + sage: f1, f2 = L.f() + sage: x = M.pbw_basis()(L([f1, [f1, f2]])) + sage: v = x * M.highest_weight_vector() + sage: M._latex_generator(v.leading_support()) + f_{-2 \alpha_{1} - \alpha_{2}} v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} + + sage: latex(2 * M.highest_weight_vector()) + 2 v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} + sage: latex(M.highest_weight_vector()) + v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} + """ + ret = super()._latex_generator(m) + if ret == '1': + ret = '' + from sage.misc.latex import latex + return ret + " {}_{{{}}}".format(self.__vector_name, latex(self._weight)) + + _repr_term = _repr_generator + _latex_term = _latex_generator + + +class VermaModule(ModulePrinting, CombinatorialFreeModule): r""" A Verma module. @@ -50,7 +123,7 @@ class VermaModule(CombinatorialFreeModule): where `F_{\lambda}` is the `U(\mathfrak{b})` module such that `h \in U(\mathfrak{h})` acts as multiplication by - `\langle \lambda, h \rangle` and `U\mathfrak{g}^+) F_{\lambda} = 0`. + `\langle \lambda, h \rangle` and `U(\mathfrak{g}^+) F_{\lambda} = 0`. INPUT: @@ -118,9 +191,10 @@ def __init__(self, g, weight, basis_key=None, prefix='f', **kwds): prefix='', bracket=False, latex_bracket=False, sorting_key=self._monomial_key, category=Modules(R).WithBasis().Graded()) + ModulePrinting.__init__(self) def _triangular_key(self, x): - """ + r""" Return a key for sorting for the index ``x`` that respects the triangular decomposition by `U^-, U^0, U^+`. @@ -233,64 +307,8 @@ def _latex_(self): from sage.misc.latex import latex return "M_{{{}}}".format(latex(self._weight)) - def _repr_generator(self, m): - r""" - Return a string representation of the generator indexed by ``m``. - - EXAMPLES:: - - sage: L = lie_algebras.sp(QQ, 4) - sage: La = L.cartan_type().root_system().ambient_space().fundamental_weights() - sage: M = L.verma_module(-1/2*La[1] + 3/7*La[2]) - sage: f1, f2 = L.f(1), L.f(2) - sage: x = M.pbw_basis()(L([f1, [f1, f2]])) - sage: v = x * M.highest_weight_vector() - sage: M._repr_generator(v.leading_support()) - 'f[-2*alpha[1] - alpha[2]]*v[(-1/14, 3/7)]' - - sage: M.highest_weight_vector() - v[(-1/14, 3/7)] - sage: 2 * M.highest_weight_vector() - 2*v[(-1/14, 3/7)] - """ - ret = super()._repr_generator(m) - if ret == '1': - ret = '' - else: - ret += '*' - return ret + "v[{}]".format(self._weight) - - def _latex_generator(self, m): - r""" - Return a latex representation of the generator indexed by ``m``. - - EXAMPLES:: - - sage: L = lie_algebras.sp(QQ, 4) - sage: La = L.cartan_type().root_system().ambient_space().fundamental_weights() - sage: M = L.verma_module(-1/2*La[1] + 3/7*La[2]) - sage: f1, f2 = L.f(1), L.f(2) - sage: x = M.pbw_basis()(L([f1, [f1, f2]])) - sage: v = x * M.highest_weight_vector() - sage: M._latex_generator(v.leading_support()) - f_{-2 \alpha_{1} - \alpha_{2}} v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} - - sage: latex(2 * M.highest_weight_vector()) - 2 v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} - sage: latex(M.highest_weight_vector()) - v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} - """ - ret = super()._latex_generator(m) - if ret == '1': - ret = '' - from sage.misc.latex import latex - return ret + " v_{{{}}}".format(latex(self._weight)) - - _repr_term = _repr_generator - _latex_term = _latex_generator - def lie_algebra(self): - """ + r""" Return the underlying Lie algebra of ``self``. EXAMPLES:: @@ -304,7 +322,7 @@ def lie_algebra(self): return self._g def pbw_basis(self): - """ + r""" Return the PBW basis of the underlying Lie algebra used to define ``self``. @@ -366,6 +384,26 @@ def highest_weight(self): """ return self._weight + def dual(self): + r""" + Return the dual module `M(\lambda)^{\vee}` in Category `\mathcal{O}`. + + EXAMPLES:: + + sage: L = lie_algebras.sl(QQ, 2) + sage: La = L.cartan_type().root_system().weight_space().fundamental_weights() + sage: M = L.verma_module(2*La[1]) + sage: Mc = M.dual() + + sage: Mp = L.verma_module(-2*La[1]) + sage: Mp.dual() is Mp + True + """ + if self.is_simple(): + return self + from sage.algebras.lie_algebras.bgg_dual_module import BGGDualModule + return BGGDualModule(self) + def degree_on_basis(self, m): r""" Return the degree (or weight) of the basis element indexed by ``m``. @@ -398,7 +436,7 @@ def _coerce_map_from_(self, R): - there is a coercion from ``R`` into the base ring; - ``R`` is a Verma module over the same Lie algebra and - there is a non-zero Verma module morphism from ``R`` + there is a nonzero Verma module morphism from ``R`` into ``self``. EXAMPLES:: @@ -451,6 +489,47 @@ def _element_constructor_(self, x): return self.highest_weight_vector()._acted_upon_(x, False) return super()._element_constructor_(self, x) + def contravariant_form(self, x, y): + r""" + Return the contravariant form of ``x`` and ``y``. + + Let `C(x, y)` denote the (universal) contravariant form on + `U(\mathfrak{g})`. Then the contravariant form on `M(\lambda)` is + given by evaluating `C(x, y) \in U(\mathfrak{h})` at `\lambda`. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 1]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(2*La[1]) + sage: U = M.pbw_basis() + sage: v = M.highest_weight_vector() + sage: e, h, f = U.algebra_generators() + sage: elts = [f^k * v for k in range(8)]; elts + [v[2*Lambda[1]], f[-alpha[1]]*v[2*Lambda[1]], + f[-alpha[1]]^2*v[2*Lambda[1]], f[-alpha[1]]^3*v[2*Lambda[1]], + f[-alpha[1]]^4*v[2*Lambda[1]], f[-alpha[1]]^5*v[2*Lambda[1]], + f[-alpha[1]]^6*v[2*Lambda[1]], f[-alpha[1]]^7*v[2*Lambda[1]]] + sage: matrix([[M.contravariant_form(x, y) for x in elts] for y in elts]) + [1 0 0 0 0 0 0 0] + [0 2 0 0 0 0 0 0] + [0 0 4 0 0 0 0 0] + [0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0] + """ + pbw = self._pbw + I = pbw._indices + xlift = pbw.element_class(pbw, {I(m._monomial): c for m, c in x._monomial_coefficients.items()}) + ylift = pbw.element_class(pbw, {I(m._monomial): c for m, c in y._monomial_coefficients.items()}) + univ = pbw.contravariant_form(xlift, ylift) + la = self._weight + R = self.base_ring() + return R.sum(c * R.prod(la.scalar(k) ** e for k, e in m._monomial.items()) + for m, c in univ._monomial_coefficients.items()) + @lazy_attribute def _dominant_data(self): r""" @@ -505,6 +584,66 @@ def is_singular(self): """ return not self._dominant_data[0].is_dominant() + def is_simple(self): + r""" + Return if ``self`` is a simple module. + + A Verma module `M_{\lambda}` is simple if and only if `\lambda` + is *Verma antidominant* in the sense + + .. MATH:: + + \langle \lambda + \rho, \alpha^{\vee} \rangle \notin \ZZ_{>0} + + for all positive roots `\alpha`. + + EXAMPLES:: + + sage: L = lie_algebras.sl(QQ, 3) + sage: La = L.cartan_type().root_system().weight_space().fundamental_weights() + sage: L.verma_module(La[1] + La[2]).is_simple() + False + sage: L.verma_module(-La[1] - La[2]).is_simple() + True + sage: L.verma_module(3/2*La[1] + 1/2*La[2]).is_simple() + False + sage: L.verma_module(3/2*La[1] + 1/3*La[2]).is_simple() + True + sage: L.verma_module(-3*La[1] + 2/3*La[2]).is_simple() + True + """ + return self._weight.is_verma_dominant(positive=False) + + def is_projective(self): + r""" + Return if ``self`` is a projective module in Category `\mathcal{O}`. + + A Verma module `M_{\lambda}` is projective (in Category `\mathcal{O}` + if and only if `\lambda` is *Verma dominant* in the sense + + .. MATH:: + + \langle \lambda + \rho, \alpha^{\vee} \rangle \notin \ZZ_{<0} + + for all positive roots `\alpha`. + + EXAMPLES:: + + sage: L = lie_algebras.sl(QQ, 3) + sage: La = L.cartan_type().root_system().weight_space().fundamental_weights() + sage: L.verma_module(La[1] + La[2]).is_projective() + True + sage: L.verma_module(-La[1] - La[2]).is_projective() + True + sage: L.verma_module(3/2*La[1] + 1/2*La[2]).is_projective() + True + sage: L.verma_module(3/2*La[1] + 1/3*La[2]).is_projective() + True + sage: L.verma_module(-3*La[1] + 2/3*La[2]).is_projective() + False + """ + return self._weight.is_verma_dominant() + def homogeneous_component_basis(self, d): r""" Return a basis for the ``d``-th homogeneous component of ``self``. @@ -528,11 +667,13 @@ def homogeneous_component_basis(self, d): sage: M.homogeneous_component_basis(mu - La[1]) Family () """ - diff = _convert_wt_to_root(d - self._weight) + diff = (d - self._weight)._to_root_vector() if diff is None or not all(coeff <= 0 and coeff in ZZ for coeff in diff): return Family([]) return sorted(self._homogeneous_component_f(diff)) + weight_space_basis = homogeneous_component_basis + @cached_method def _homogeneous_component_f(self, d): r""" @@ -590,7 +731,7 @@ def _Hom_(self, Y, category=None, **options): The sole purpose of this method is to construct the homset as a :class:`~sage.algebras.lie_algebras.verma_module.VermaModuleHomset`. If ``category`` is specified and is not a subcategory of - ``self.category()``, a :class:`TypeError` is raised instead. + ``self.category()``, a :exc:`TypeError` is raised instead. This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. @@ -605,17 +746,22 @@ def _Hom_(self, Y, category=None, **options): sage: type(H) <...VermaModuleHomset_with_category_with_equality_by_id'> """ - if not (isinstance(Y, VermaModule) and self._g is Y._g): - raise TypeError("{} must be a Verma module of {}".format(Y, self._g)) + from sage.algebras.lie_algebras.bgg_dual_module import BGGDualModule, SimpleModule + if not ((isinstance(Y, (VermaModule, SimpleModule)) + or (isinstance(Y, BGGDualModule) and Y._module is self)) + and self._g is Y.lie_algebra()): + raise TypeError("{} must be an object in Category O of {}".format(Y, self._g)) if category is not None and not category.is_subcategory(self.category()): raise TypeError("{} is not a subcategory of {}".format(category, self.category())) return VermaModuleHomset(self, Y) class Element(CombinatorialFreeModule.Element): def _acted_upon_(self, scalar, self_on_left=False): - """ + r""" Return the action of ``scalar`` on ``self``. + EXAMPLES: + Check that other PBW algebras have an action:: sage: L = lie_algebras.sp(QQ, 6) @@ -639,6 +785,7 @@ def _acted_upon_(self, scalar, self_on_left=False): """ P = self.parent() # Check for scalars first + # TODO: Pass by these checks if a PBW basis element of the Lie algebra if scalar in P.base_ring(): # Don't have this be a super call return CombinatorialFreeModule.Element._acted_upon_(self, scalar, self_on_left) @@ -694,13 +841,14 @@ def _acted_upon_(self, scalar, self_on_left=False): _lmul_ = _acted_upon_ _rmul_ = _acted_upon_ + ##################################################################### -## Morphisms and Homset +# Morphisms and Homset class VermaModuleMorphism(Morphism): - """ - A morphism of Verma modules. + r""" + A morphism of a Verma module to another module in Category `\mathcal{O}`. """ def __init__(self, parent, scalar): """ @@ -765,7 +913,7 @@ def _repr_defn(self): v = self.domain().highest_weight_vector() if not self._scalar: return "{} |--> {}".format(v, self.codomain().zero()) - return "{} |--> {}".format(v, self._scalar * self.parent().singular_vector()) + return "{} |--> {}".format(v, self._scalar * self.parent().highest_weight_image()) def _richcmp_(self, other, op): r""" @@ -800,7 +948,7 @@ def _call_(self, x): sage: M = L.verma_module(La[1] + La[2]) sage: Mp = L.verma_module(M.highest_weight().dot_action([1,2])) sage: pbw = M.pbw_basis() - sage: f1, f2 = pbw(L.f(1)), pbw(L.f(2)) + sage: f1, f2 = pbw.f() sage: v = Mp.highest_weight_vector() sage: phi = Hom(Mp, M).natural_map() sage: phi(f1 * v) == f1 * phi(v) @@ -816,14 +964,14 @@ def _call_(self, x): sage: psi(v) 0 """ - if not self._scalar or self.parent().singular_vector() is None: + if not self._scalar or not self.parent().highest_weight_image(): return self.codomain().zero() mc = x.monomial_coefficients(copy=False) return self.codomain().linear_combination((self._on_basis(m), self._scalar * c) for m,c in mc.items()) def _on_basis(self, m): - """ + r""" Return the image of the basis element indexed by ``m``. EXAMPLES:: @@ -833,14 +981,17 @@ def _on_basis(self, m): sage: M = L.verma_module(La[1] + La[2]) sage: Mp = L.verma_module(M.highest_weight().dot_action([1,2])) sage: pbw = M.pbw_basis() - sage: f1, f2 = pbw(L.f(1)), pbw(L.f(2)) + sage: f1, f2 = pbw.f() sage: v = Mp.highest_weight_vector() sage: phi = Hom(Mp, M).natural_map() sage: phi._on_basis((f1 * v).leading_support()) == f1 * phi(v) True """ + vec = self.parent().highest_weight_image() + if not vec: + return vec pbw = self.codomain()._pbw - return pbw.monomial(pbw._indices(m.dict())) * self.parent().singular_vector() + return pbw.monomial(pbw._indices(m.dict())) * vec def _add_(self, other): """ @@ -907,7 +1058,7 @@ def _composition_(self, right, homset): INPUT: - ``self``, ``right`` -- maps - - homset -- a homset + - ``homset`` -- a homset ASSUMPTION: @@ -936,8 +1087,10 @@ def is_injective(self): r""" Return if ``self`` is injective or not. - A Verma module morphism `\phi : M \to M'` is injective if - and only if `\dim \hom(M, M') = 1` and `\phi \neq 0`. + A morphism `\phi : M \to M'` from a Verma module `M` to another + Verma module `M'` is injective if and only if `\dim \hom(M, M') = 1` + and `\phi \neq 0`. If `M'` is a dual Verma or simple module, then + the result is not injective. EXAMPLES:: @@ -955,15 +1108,20 @@ def is_injective(self): sage: psi.is_injective() False """ - return self.parent().singular_vector() is not None and bool(self._scalar) + if not isinstance(self.codomain(), VermaModule): + return False + return bool(self._scalar) def is_surjective(self): - """ + r""" Return if ``self`` is surjective or not. - A Verma module morphism is surjective if and only if the - domain is equal to the codomain and it is not the zero - morphism. + A morphism `\phi : M \to M'` from a Verma module `M` to another + Verma module `M'` is surjective if and only if the domain is + equal to the codomain and it is not the zero morphism. + + If `M'` is a simple module, then this surjective if and only if + `\dim \hom(M, M') = 1` and `\phi \neq 0`. EXAMPLES:: @@ -980,13 +1138,66 @@ def is_surjective(self): sage: psi.is_surjective() False """ - return self.domain() == self.codomain() and bool(self._scalar) + if not bool(self._scalar): + return False + + if isinstance(self.codomain(), VermaModule): + return self.domain() == self.codomain() + + from sage.algebras.lie_algebras.bgg_dual_module import SimpleModule + if isinstance(self.codomain(), SimpleModule): + return self.domain().highest_weight() == self.codomain().highest_weight() + + return False + + def image(self): + r""" + Return the image of ``self``. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(La[1] + 2*La[2]) + sage: Mp = g.verma_module(La[1] + 3*La[2]) + sage: phi = Hom(M, Mp).natural_map() + sage: phi.image() + Free module generated by {} over Rational Field + sage: Mc = M.dual() + sage: phi = Hom(M, Mc).natural_map() + sage: L = phi.image(); L + Simple module with highest weight Lambda[1] + 2*Lambda[2] of + Lie algebra of ['B', 2] in the Chevalley basis + sage: psi = Hom(M, L).natural_map() + sage: psi.image() + Simple module with highest weight Lambda[1] + 2*Lambda[2] of + Lie algebra of ['B', 2] in the Chevalley basis + """ + C = self.codomain() + if not bool(self._scalar): + return C.submodule([]) + + if isinstance(C, VermaModule): + if self.domain() == C: + return C + raise NotImplementedError("submodules of Verma modules not yet implemented") + + from sage.algebras.lie_algebras.bgg_dual_module import BGGDualModule, SimpleModule + if isinstance(C, BGGDualModule) and isinstance(C._module, VermaModule): + return SimpleModule(C.lie_algebra(), C.highest_weight(), prefix=C._indices.prefix(), + basis_key=C._module._basis_key) + + if isinstance(self.codomain(), SimpleModule): + return self.codomain() class VermaModuleHomset(Homset): r""" - The set of morphisms from one Verma module to another - considered as `U(\mathfrak{g})`-representations. + The set of morphisms from a Verma module to another module in + Category `\mathcal{O}` considered as `U(\mathfrak{g})`-representations. + + This currently assumes the codomain is a Verma module, its dual, + or a simple module. Let `M_{w \cdot \lambda}` and `M_{w' \cdot \lambda'}` be Verma modules, `\cdot` is the dot action, and `\lambda + \rho`, @@ -998,9 +1209,13 @@ class VermaModuleHomset(Homset): if and only if `\lambda = \lambda'` and `w' \leq w` in Bruhat order. Otherwise the homset is 0 dimensional. + + If the codomain is a dual Verma module `M_{\mu}^{\vee}`, then the + homset is `\delta_{\lambda\mu}` dimensional. When `\mu = \lambda`, + the image is the simple module `L_{\lambda}`. """ def __call__(self, x, **options): - """ + r""" Construct a morphism in this homset from ``x`` if possible. EXAMPLES:: @@ -1056,7 +1271,7 @@ def __call__(self, x, **options): return super().__call__(x, **options) def _an_element_(self): - """ + r""" Return an element of ``self``. EXAMPLES:: @@ -1077,6 +1292,37 @@ def _an_element_(self): """ return self.natural_map() + def highest_weight_image(self): + r""" + Return the image of the highest weight vector of the domain + in the codomain. + + EXAMPLES:: + + sage: g = LieAlgebra(QQ, cartan_type=['C', 3]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module(La[1] + 2*La[3]) + sage: Mc = M.dual() + sage: H = Hom(M, Mc) + sage: H.highest_weight_image() + v[Lambda[1] + 2*Lambda[3]]^* + sage: L = H.natural_map().image() + sage: Hp = Hom(M, L) + sage: Hp.highest_weight_image() + u[Lambda[1] + 2*Lambda[3]] + """ + C = self.codomain() + if isinstance(C, VermaModule): + # singular_vector() is cached, so we can safely call it twice + if self.singular_vector() is None: + return C.zero() + return self.singular_vector() + # Otherwise, it is a dual Verma or a simple, so the image + # must be the highest weight vector. + if self.domain().highest_weight() == C.highest_weight(): + return C.highest_weight_vector() + return C.zero() + @cached_method def singular_vector(self): r""" @@ -1087,12 +1333,16 @@ def singular_vector(self): ALGORITHM: We essentially follow the algorithm laid out in [deG2005]_. - We use the `\mathfrak{sl}_2` relation on - `M_{s_i \cdot \lambda} \to M_{\lambda}`, where - `\langle \lambda + \delta, \alpha_i^{\vee} \rangle = m > 0`, - i.e., the weight `\lambda` is `i`-dominant with respect to - the dot action. From here, we construct the singular vector - `f_i^m v_{\lambda}`. We iterate this until we reach `\mu`. + We split the main computation into two cases. If there exists + an `i` such that `\langle \lambda + \rho, \alpha_i^{\vee} + \rangle = m > 0` (i.e., the weight `\lambda` is `i`-dominant + with respect to the dot action), then we use the `\mathfrak{sl}_2` + relation on `M_{s_i \cdot \lambda} \to M_{\lambda}` to + construct the singular vector `f_i^m v_{\lambda}`. Otherwise + we find the shortest root `\alpha` such that `\langle \lambda + + \rho, \alpha^{\vee} \rangle > 0` and explicitly compute the + kernel with respect to the weight basis elements. We iterate + this until we reach `\mu`. EXAMPLES:: @@ -1103,13 +1353,15 @@ def singular_vector(self): sage: M = L.verma_module(la) sage: Mp = L.verma_module(mu) sage: H = Hom(Mp, M) - sage: H.singular_vector() + sage: v = H.singular_vector(); v f[-alpha[2]]*f[-alpha[1]]^3*v[Lambda[1] - Lambda[3]] + 3*f[-alpha[1]]^2*f[-alpha[1] - alpha[2]]*v[Lambda[1] - Lambda[3]] + sage: v.degree() == Mp.highest_weight() + True :: - sage: L = LieAlgebra(QQ, cartan_type=['F',4]) + sage: L = LieAlgebra(QQ, cartan_type=['F', 4]) sage: La = L.cartan_type().root_system().weight_space().fundamental_weights() sage: la = La[1] + La[2] - La[3] sage: mu = la.dot_action([1,2,3,2]) @@ -1119,7 +1371,9 @@ def singular_vector(self): sage: v = H.singular_vector() sage: pbw = M.pbw_basis() sage: E = [pbw(e) for e in L.e()] - sage: all(e * v == M.zero() for e in E) + sage: all(e * v == M.zero() for e in E) # long time + True + sage: v.degree() == Mp.highest_weight() True When `w \cdot \lambda \notin \lambda + Q^-`, there does not @@ -1135,6 +1389,24 @@ def singular_vector(self): sage: H.singular_vector() is None True + When we need to apply a non-simple reflection, we can compute + the singular vector (see :issue:`36793`):: + + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: La = g.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: M = g.verma_module((0*La[1]).dot_action([1])) + sage: Mp = g.verma_module((0*La[1]).dot_action([1,2])) + sage: H = Hom(Mp, M) + sage: v = H.singular_vector(); v + 1/2*f[-alpha[2]]*f[-alpha[1]]*v[-2*Lambda[1] + Lambda[2]] + + f[-alpha[1] - alpha[2]]*v[-2*Lambda[1] + Lambda[2]] + sage: pbw = M.pbw_basis() + sage: E = [pbw(e) for e in g.e()] + sage: all(e * v == M.zero() for e in E) + True + sage: v.degree() == Mp.highest_weight() + True + TESTS:: sage: L = lie_algebras.sl(QQ, 3) @@ -1154,29 +1426,100 @@ def singular_vector(self): return None from sage.combinat.root_system.coxeter_group import CoxeterGroup + from sage.matrix.constructor import matrix W = CoxeterGroup(self.domain()._g._cartan_type) - wp = W.from_reduced_word(self.domain()._dominant_data[1]) - w = W.from_reduced_word(self.codomain()._dominant_data[1]) + # We take the inverse to account for the left versus right action + wp = W.from_reduced_word(reversed(self.domain()._dominant_data[1])) + w = W.from_reduced_word(reversed(self.codomain()._dominant_data[1])) if not w.bruhat_le(wp): return None C = self.codomain() pbw = C._pbw - f = C._g.f() - F = {i: pbw(f[i]) for i in f.keys()} - red_word = (wp * ~w).reduced_word() + F = pbw.f() + E = pbw.e() + index_set = F.keys() + cur_w = w rho = C._weight.parent().rho() ac = C._weight.parent().simple_coroots() elt = pbw.one() wt = C._weight - # Construct the singular vector by iterated embeddings of Verma - # modules (without constructing the modules themselves) - for i in reversed(red_word): - exp = (wt + rho).scalar(ac[i]) - if exp not in ZZ or exp < 0: - return None - elt = F[i]**ZZ(exp) * elt - wt = wt.dot_action([i]) - return C.highest_weight_vector()._acted_upon_(elt, False) + pos_roots_by_ht = C._g._cartan_type.root_system().root_lattice().positive_roots_by_height() + assert all(sum(rt.coefficients()) == 1 for rt in pos_roots_by_ht[:len(index_set)]) + # for this, we don't need to check the simple roots + pos_roots_by_ht = pos_roots_by_ht[len(index_set):] + + while cur_w != wp: + ind = None + for i in cur_w.descents(side='right', positive=True): + exp = (wt + rho).scalar(ac[i]) + if exp not in ZZ or exp <= 0: + continue + # We need to check that the result is still smaller in Bruhat order + next_w = cur_w.apply_simple_reflection_right(i) + if not next_w.bruhat_le(wp): + continue + ind = i + # favor a path in weak order so we only do sl_2 relations + if not next_w.weak_le(wp, side="right"): + continue + break + if ind is None: # no simple root; need a more general approach + # We search for the shortest root that can be applied to minimize + # the size of the basis needed to compute the kernel. + for rt in pos_roots_by_ht: + exp = (wt + rho).scalar(rt.associated_coroot()) + # We need to check that the result is still smaller in Bruhat order + i, wd = rt.to_simple_root(reduced_word=True) + refl = wd + (i,) + tuple(reversed(wd)) + next_w = cur_w.apply_reflections(refl, side='right', word_type="simple") + if exp not in ZZ or exp <= 0: + continue + if not next_w.bruhat_le(wp): + continue + # We construct the Verma module of the appropriate weight in + # order to reduce the dimension and number of multiplications. + Mp = C._g.verma_module(wt) + basis = sorted(Mp._homogeneous_component_f(-rt.to_vector()), key=str) + for i in index_set: + image = [E[i] * b for b in basis] + supp = set() + for vec in image: + supp.update(vec._monomial_coefficients) + supp = sorted(supp, key=pbw._monomial_key) + if not supp: # everything is in the kernel + continue + M = matrix(pbw.base_ring(), [[v[s] for v in image] for s in supp]) + ker = M.right_kernel_matrix() + basis = [C.linear_combination((basis[j], c) for j, c in kv.iteritems()) + for kv in ker.rows()] + + assert len(basis) == 1 + if Mp is C: # We've constructed the element in the codomain + assert next_w == wp + assert basis[0].degree() == self.domain().highest_weight() + return basis[0] + pbw_elt = pbw.element_class(pbw, {pbw._indices(m._monomial): c + for m, c in basis[0]._monomial_coefficients.items()}) + elt = pbw_elt * elt + wt = wt.dot_action(refl) + cur_w = next_w + break + else: + #assert False, "unable to find root" + # Have a more explicit check at the beginning using the integral + # orbit action for the correct version of dominance; see, e.g., + # Humphreys "Representations of Semisimple Lie Algebras in the BGG Category O". + return None + else: + # Construct the singular vector by iterated embeddings of Verma + # modules from the sl_2 relations (without constructing + # the modules themselves) + elt = F[ind]**ZZ(exp) * elt + wt = wt.dot_action([ind]) + cur_w = cur_w.apply_simple_reflection_right(ind) + ret = C.highest_weight_vector()._acted_upon_(elt, False) + assert ret.degree() == self.domain().highest_weight() + return ret @cached_method def natural_map(self): @@ -1209,7 +1552,7 @@ def natural_map(self): of Lie algebra of ['A', 2] in the Chevalley basis Defn: v[Lambda[1] + 2*Lambda[2]] |--> 0 """ - if self.singular_vector() is None: + if not self.highest_weight_image(): return self.zero() return self.element_class(self, self.base_ring().one()) @@ -1236,7 +1579,7 @@ def zero(self): return self.element_class(self, self.base_ring().zero()) def dimension(self): - """ + r""" Return the dimension of ``self`` (as a vector space over the base ring). @@ -1255,12 +1598,12 @@ def dimension(self): sage: H.dimension() 0 """ - if self.singular_vector() is None: + if not self.highest_weight_image(): return ZZ.zero() return ZZ.one() def basis(self): - """ + r""" Return a basis of ``self``. EXAMPLES:: @@ -1278,50 +1621,8 @@ def basis(self): sage: H.basis() Family () """ - if self.singular_vector() is None: + if not self.highest_weight_image(): return Family([]) return Family([self.natural_map()]) Element = VermaModuleMorphism - - -def _convert_wt_to_root(wt): - r""" - Helper function to express ``wt`` as a linear combination - of simple roots. - - INPUT: - - - ``wt`` -- an element of a weight lattice realization - - OUTPUT: - - A vector over `\QQ` representing ``wt`` as a linear combination - of simple roots. - - EXAMPLES:: - - sage: from sage.algebras.lie_algebras.verma_module import _convert_wt_to_root - sage: P = RootSystem(['A',3]).weight_lattice() - sage: La = P.fundamental_weights() - sage: [_convert_wt_to_root(al) for al in P.simple_roots()] - [(1, 0, 0), (0, 1, 0), (0, 0, 1)] - sage: _convert_wt_to_root(La[1] + La[2]) - (5/4, 3/2, 3/4) - - sage: L = RootSystem(['A',3]).ambient_space() - sage: e = L.basis() - sage: _convert_wt_to_root(e[0] + 3*e[3]) - sage: _convert_wt_to_root(e[0] - e[1]) - (1, 0, 0) - sage: _convert_wt_to_root(e[0] + 2*e[1] - 3*e[2]) - (1, 3, 0) - """ - v = wt.to_vector().change_ring(QQ) - al = [a.to_vector() for a in wt.parent().simple_roots()] - b = v.parent().linear_dependence([v] + al) - if len(b) != 1 or b[0] == 0: - return None - b = b[0] # Get the actual vector that gives the linear dependency - # Get v as a linear combination of the simple roots - return vector(QQ, [-x / b[0] for x in b[1:]]) diff --git a/src/sage/algebras/lie_algebras/virasoro.py b/src/sage/algebras/lie_algebras/virasoro.py index f1d926b484b..961c6fb9bbd 100644 --- a/src/sage/algebras/lie_algebras/virasoro.py +++ b/src/sage/algebras/lie_algebras/virasoro.py @@ -206,7 +206,7 @@ def __init__(self, R, p): matrix over the base ring as part of the test:: sage: L = lie_algebras.pwitt(Zmod(6), 6) - sage: TestSuite(L).run(skip="_test_grading") + sage: TestSuite(L).run(skip='_test_grading') """ if R(p) != 0: raise ValueError("{} is not 0 in {}".format(p, R)) @@ -652,7 +652,7 @@ class Element(LieAlgebraElement): pass ##################################################################### -## Representations +# Representations class ChargelessRepresentation(CombinatorialFreeModule): @@ -1017,7 +1017,7 @@ def _monomial(self, index): """ if index in ZZ: if index >= 0: - raise ValueError("sequence must have non-positive entries") + raise ValueError("sequence must have nonpositive entries") index = (index,) return super()._monomial(index) diff --git a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py index b70bc9cbbaf..6027dee4a95 100644 --- a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py @@ -33,21 +33,20 @@ class AbelianLieConformalAlgebra(GradedLieConformalAlgebra): - ``R`` -- a commutative ring; the base ring of this Lie conformal algebra - - ``ngens`` -- a positive integer (default: ``1``); the number + - ``ngens`` -- positive integer (default: `1`); the number of generators of this Lie conformal algebra - - ``weights`` -- a list of positive rational numbers (default: - ``1`` for each - generator); the weights of the generators. The resulting + - ``weights`` -- list of positive rational numbers (default: + `1` for each generator); the weights of the generators. The resulting Lie conformal algebra is `H`-graded. - ``parity`` -- ``None`` or a list of ``0`` or ``1`` (default: - ``None``); The parity of the generators. If not ``None`` the + ``None``); the parity of the generators. If not ``None`` the resulting Lie Conformal algebra is a Super Lie conformal algebra - - ``names`` -- a tuple of ``str`` or ``None`` (default: ``None`` - ); the list of names of the generators of this algebra. + - ``names`` -- tuple of strings or ``None`` (default: ``None``); + the list of names of the generators of this algebra. - ``index_set`` -- an enumerated set or ``None`` (default: - ``None``); A set indexing the generators of this Lie - conformal algebra. + ``None``); a set indexing the generators of this Lie + conformal algebra OUTPUT: @@ -79,7 +78,7 @@ class AbelianLieConformalAlgebra(GradedLieConformalAlgebra): def __init__(self, R, ngens=1, weights=None, parity=None, names=None, index_set=None): """ - Initialize self. + Initialize ``self``. EXAMPLES:: diff --git a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py index 8c6671aa1a0..e9f697e8257 100644 --- a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py @@ -43,19 +43,19 @@ class AffineLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - ``R`` -- a commutative Ring; the base ring for this Lie - conformal algebra. + conformal algebra - ``ct`` -- a ``str`` or a :mod:`CartanType`; the Cartan Type for the corresponding finite dimensional Lie algebra. It must correspond to a simple finite dimensional Lie algebra. - - ``names`` -- a list of ``str`` or ``None`` (default: ``None``) - ; alternative names for the generators. If ``None`` the + - ``names`` -- list of ``str`` or ``None`` (default: ``None``); + alternative names for the generators. If ``None`` the generators are labeled by the corresponding root and coroot vectors. - ``prefix`` -- a ``str``; parameter passed to :class:`IndexedGenerators` - ``bracket`` -- a ``str``; parameter passed to - :class:`IndexedGenerators`. + :class:`IndexedGenerators` EXAMPLES:: @@ -83,7 +83,7 @@ class AffineLieConformalAlgebra(GradedLieConformalAlgebra): """ def __init__(self, R, ct, names=None, prefix=None, bracket=None): """ - Initialize self. + Initialize ``self``. TESTS:: @@ -96,7 +96,7 @@ def __init__(self, R, ct, names=None, prefix=None, bracket=None): ct = CartanType(ct) except IndexError: raise ValueError("ct must be a valid Cartan Type") - if not (ct.is_finite() and ct.is_irreducible ): + if not (ct.is_finite() and ct.is_irreducible): raise ValueError("only affine algebras of simple finite dimensional" "Lie algebras are implemented") hv = Integer(ct.dual_coxeter_number()) diff --git a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py index 5f88bcded94..2e689ee4c60 100644 --- a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py @@ -41,14 +41,14 @@ class BosonicGhostsLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - - ``R`` -- a commutative ring. + - ``R`` -- a commutative ring - ``ngens`` -- an even positive Integer (default: ``2``); the number of non-central generators of this Lie conformal algebra. - - ``names`` -- a list of ``str``; alternative names for the + - ``names`` -- list of ``str``; alternative names for the + generators + - ``index_set`` -- an enumerated set; an indexing set for the generators - - ``index_set`` -- an enumerated set; An indexing set for the - generators. OUTPUT: @@ -81,7 +81,7 @@ class BosonicGhostsLieConformalAlgebra(GradedLieConformalAlgebra): def __init__(self, R, ngens=2, names=None, index_set=None): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/examples.py b/src/sage/algebras/lie_conformal_algebras/examples.py index 3d520e449db..1db194445be 100644 --- a/src/sage/algebras/lie_conformal_algebras/examples.py +++ b/src/sage/algebras/lie_conformal_algebras/examples.py @@ -20,15 +20,15 @@ - Reimundo Heluani (2020-06-15): Initial implementation. """ -#****************************************************************************** +# ***************************************************************************** # Copyright (C) 2020 Reimundo Heluani # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from .abelian_lie_conformal_algebra import AbelianLieConformalAlgebra as Abelian from .affine_lie_conformal_algebra import AffineLieConformalAlgebra as Affine @@ -40,14 +40,3 @@ from .neveu_schwarz_lie_conformal_algebra import NeveuSchwarzLieConformalAlgebra as NeveuSchwarz from .virasoro_lie_conformal_algebra import VirasoroLieConformalAlgebra as Virasoro from .weyl_lie_conformal_algebra import WeylLieConformalAlgebra as Weyl - -assert Abelian -assert Affine -assert BosonicGhosts -assert FermionicGhosts -assert FreeBosons -assert FreeFermions -assert N2 -assert NeveuSchwarz -assert Virasoro -assert Weyl diff --git a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py index 3a029ec96a5..004718d4a5f 100644 --- a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py @@ -37,15 +37,15 @@ class FermionicGhostsLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - - ``R`` -- a commutative ring; the base ring of this Lie + - ``R`` -- a commutative ring; the base ring of this Lie conformal algebra - - ``ngens`` -- an even positive Integer (default: ``2``); The + - ``ngens`` -- an even positive Integer (default: ``2``); the number of non-central generators of this Lie conformal - algebra. - - ``names`` -- a tuple of ``str``; alternative names for the + algebra + - ``names`` -- tuple of strings; alternative names for the generators - ``index_set`` -- an enumerated set; alternative indexing - set for the generators. + set for the generators OUTPUT: @@ -74,7 +74,7 @@ class FermionicGhostsLieConformalAlgebra(GradedLieConformalAlgebra): """ def __init__(self,R,ngens=2,names=None,index_set=None): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py b/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py index d93ec041655..be9afefd29a 100644 --- a/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +++ b/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py @@ -35,7 +35,7 @@ def __init__(self, R, index_set=None, central_elements=None, category=None, element_class=None, prefix=None, names=None, latex_names=None, **kwds): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py index 677e9ea585d..e66489d49ca 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py @@ -43,16 +43,16 @@ class FreeBosonsLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - - ``R`` -- a commutative ring. - - ``ngens`` -- a positive Integer (default ``1``); the number of + - ``R`` -- a commutative ring + - ``ngens`` -- a positive Integer (default: `1`); the number of non-central generators of this Lie conformal algebra. - - ``gram_matrix``: a symmetric square matrix with coefficients + - ``gram_matrix`` -- a symmetric square matrix with coefficients in ``R`` (default: ``identity_matrix(ngens)``); the Gram matrix of the inner product - - ``names`` -- a tuple of ``str``; alternative names for the + - ``names`` -- tuple of strings; alternative names for the generators - ``index_set`` -- an enumerated set; alternative indexing set - for the generators. + for the generators OUTPUT: @@ -102,7 +102,7 @@ class FreeBosonsLieConformalAlgebra(GradedLieConformalAlgebra): def __init__(self, R, ngens=None, gram_matrix=None, names=None, index_set=None): """ - Initialize self. + Initialize ``self``. TESTS:: @@ -134,7 +134,7 @@ def __init__(self, R, ngens=None, gram_matrix=None, names=None, names,index_set = standardize_names_index_set(names=names, index_set=index_set, ngens=ngens) - bosondict = { (i,j): {1: {('K',0): gram_matrix[index_set.rank(i), + bosondict = {(i,j): {1: {('K',0): gram_matrix[index_set.rank(i), index_set.rank(j)]}} for i in index_set for j in index_set} GradedLieConformalAlgebra.__init__(self,R,bosondict,names=names, diff --git a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py index e952e1b92be..40810602ac4 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py @@ -42,10 +42,10 @@ class FreeFermionsLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - - ``R``: a commutative ring. - - ``ngens``: a positive Integer (default ``1``); the number of - non-central generators of this Lie conformal algebra. - - ``gram_matrix``: a symmetric square matrix with coefficients + - ``R`` -- a commutative ring + - ``ngens`` -- a positive Integer (default: ``1``); the number of + non-central generators of this Lie conformal algebra + - ``gram_matrix`` -- a symmetric square matrix with coefficients in ``R`` (default: ``identity_matrix(ngens)``); the Gram matrix of the inner product @@ -85,7 +85,7 @@ class FreeFermionsLieConformalAlgebra(GradedLieConformalAlgebra): def __init__(self, R, ngens=None, gram_matrix=None, names=None, index_set=None): """ - Initialize self. + Initialize ``self``. TESTS:: @@ -125,7 +125,7 @@ def __init__(self, R, ngens=None, gram_matrix=None, names=None, names,index_set = standardize_names_index_set(names=names, index_set=index_set, ngens=ngens) - fermiondict = { (i,j): {0: {('K',0): gram_matrix[index_set.rank(i), + fermiondict = {(i,j): {0: {('K', 0): gram_matrix[index_set.rank(i), index_set.rank(j)]}} for i in index_set for j in index_set} from sage.rings.rational_field import QQ diff --git a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py index 790d7d5a9cb..0b77dd91854 100644 --- a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py @@ -41,7 +41,7 @@ class FreelyGeneratedLieConformalAlgebra(LieConformalAlgebraWithBasis): def __init__(self, R, index_set=None, central_elements=None, category=None, element_class=None, prefix=None, **kwds): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py index 61e38845ca4..2004f54485c 100644 --- a/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py @@ -62,31 +62,31 @@ class GradedLieConformalAlgebra(LieConformalAlgebraWithStructureCoefficients): ring of this Lie conformal algebra. Behaviour is undefined if it is not a field of characteristic zero - - ``s_coeff`` -- a dictionary (default: ``None``); as in the + - ``s_coeff`` -- dictionary (default: ``None``); as in the input of :class:`LieConformalAlgebra` - - ``names`` -- tuple of ``str`` (default: ``None``); as in the + - ``names`` -- tuple of strings (default: ``None``); as in the input of :class:`LieConformalAlgebra` - - ``central_elements`` -- tuple of ``str`` (default: ``None``); + - ``central_elements`` -- tuple of strings (default: ``None``); as in the input of :class:`LieConformalAlgebra` - ``index_set`` -- enumerated set (default: ``None``); as in the input of :class:`LieConformalAlgebra` - - ``weights`` -- tuple of non-negative rational numbers + - ``weights`` -- tuple of nonnegative rational numbers (default: tuple of ``1``); a list of degrees for this Lie conformal algebra. This tuple needs to have the same cardinality as ``index_set`` or ``names``. Central elements are assumed to have weight ``0``. - - ``category`` The category that this Lie conformal algebra - belongs to. + - ``category`` -- the category that this Lie conformal algebra + belongs to - - ``parity`` -- tuple of ``0`` or ``1`` (Default: tuple of + - ``parity`` -- tuple of ``0`` or ``1`` (default: tuple of ``0``); a tuple specifying the parity of each non-central - generator. + generator EXAMPLES:: @@ -105,7 +105,7 @@ def __init__(self, R, s_coeff, index_set=None, central_elements=None, category=None, prefix=None, names=None, latex_names=None, parity=None, weights=None, **kwds): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py index 19ab2b41dbc..528a587d795 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py @@ -42,7 +42,7 @@ `T` is usually called the *translation operation* or the *derivative*. For an element `a \in L` we will say that `Ta` is the *derivative of* - `a`. We define the *n-th products* `a_{(n)} b` for `a,b \in L` by + `a`. We define the *`n`-th products* `a_{(n)} b` for `a,b \in L` by .. MATH:: @@ -63,8 +63,7 @@ .. NOTE:: In the literature arbitrary gradings are allowed. In this - implementation we only support non-negative rational gradings. - + implementation we only support nonnegative rational gradings. EXAMPLES: @@ -190,7 +189,7 @@ class LieConformalAlgebra(UniqueRepresentation, Parent): ring of this Lie conformal algebra. Behaviour is undefined if it is not a field of characteristic zero. - - ``arg0`` -- a dictionary (default: ``None``); + - ``arg0`` -- dictionary (default: ``None``); a dictionary containing the `\lambda` brackets of the generators of this Lie conformal algebra. The keys of this dictionary are pairs of either names or indices of the @@ -198,7 +197,7 @@ class LieConformalAlgebra(UniqueRepresentation, Parent): pair of generators ``'a'`` and ``'b'``, the value of ``arg0[('a','b')]`` is a dictionary whose keys are positive integer numbers and the corresponding value for the - key ``j`` is a dictionary itself representing the j-th product + key ``j`` is a dictionary itself representing the `j`-th product `a_{(j)}b`. Thus, for a positive integer number `j`, the value of ``arg0[('a','b')][j]`` is a dictionary whose entries are pairs ``('c',n)`` where ``'c'`` is the name of a generator @@ -216,19 +215,18 @@ class LieConformalAlgebra(UniqueRepresentation, Parent): pair (besides the ones defined by skew-symmetry) is assumed to have vanishing `\lambda`-bracket. - - ``names`` -- tuple of ``str`` (default: ``None``); the list of + - ``names`` -- tuple of strings (default: ``None``); the list of names for generators of this Lie conformal algebra. Do not include central elements in this list. - - ``central_elements`` -- tuple of ``str`` (default: ``None``); - A list of names for central elements of this Lie conformal - algebra. + - ``central_elements`` -- tuple of strings (default: ``None``); + a list of names for central elements of this Lie conformal algebra - ``index_set`` -- enumerated set (default: ``None``); an indexing set for the generators of this Lie conformal algebra. Do not include central elements in this list. - - ``weights`` -- tuple of non-negative rational numbers + - ``weights`` -- tuple of nonnegative rational numbers (default: ``None``); a list of degrees for this Lie conformal algebra. The returned Lie conformal algebra is H-Graded. This tuple @@ -244,18 +242,18 @@ class LieConformalAlgebra(UniqueRepresentation, Parent): ``LieConformalAlgebras(R).Super()``, even if all generators are even. - - ``category`` The category that this Lie conformal algebra - belongs to. + - ``category`` -- the category that this Lie conformal algebra + belongs to In addition we accept the following keywords: - - ``graded`` -- a boolean (default: ``False``); + - ``graded`` -- boolean (default: ``False``); if ``True``, the returned algebra is H-Graded. If ``weights`` is not specified, all non-central generators are assigned degree `1`. This keyword is ignored if ``weights`` is specified - - ``super`` -- a boolean (default: ``False``); + - ``super`` -- boolean (default: ``False``); if ``True``, the returned algebra is a super Lie conformal algebra even if all generators are even. If ``parity`` is not specified, all generators are @@ -310,8 +308,9 @@ class LieConformalAlgebra(UniqueRepresentation, Parent): """ @staticmethod def __classcall_private__(cls, R=None, arg0=None, index_set=None, - central_elements=None, category=None, prefix=None, - names=None, latex_names=None, parity=None, weights=None, **kwds): + central_elements=None, category=None, + prefix=None, names=None, latex_names=None, + parity=None, weights=None, **kwds): """ Lie conformal algebra factory. diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py index bf08362ae92..27796941d2b 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py @@ -29,12 +29,12 @@ class LCAWithGeneratorsElement(IndexedFreeModuleElement): """ def T(self, n=1): r""" - The n-th derivative of this element. + The `n`-th derivative of this element. INPUT: - - ``n`` -- a non-negative integer (default:``1``); how many - times to apply `T` to this element. + - ``n`` -- nonnegative integer (default: `1`); how many + times to apply `T` to this element We use the *divided powers* notation `T^{(j)} = \frac{T^j}{j!}`. @@ -97,7 +97,7 @@ def _bracket_(self, right): """ The lambda bracket of these two elements. - The result is a dictionary with non-negative integer keys. + The result is a dictionary with nonnegative integer keys. The value corresponding to the entry `j` is ``self_{(j)}right``. EXAMPLES:: diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py index d95c99978b3..254eeac64e6 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py @@ -55,7 +55,7 @@ class LieConformalAlgebraWithBasis(CombinatorialFreeModule): def __init__(self, R, basis_keys=None, element_class=None, category=None, prefix=None, **kwds): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py index 25b688b19ff..3cb8f645cd5 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py @@ -35,11 +35,11 @@ class LieConformalAlgebraWithStructureCoefficients( INPUT: - - ``R`` -- a ring (Default: ``None``); The base ring of this Lie + - ``R`` -- a ring (default: ``None``); the base ring of this Lie conformal algebra. Behaviour is undefined if it is not a field of characteristic zero. - - ``s_coeff`` -- Dictionary (Default: ``None``); + - ``s_coeff`` -- dictionary (default: ``None``); a dictionary containing the `\lambda` brackets of the generators of this Lie conformal algebra. The family encodes a dictionary whose keys @@ -48,7 +48,7 @@ class LieConformalAlgebraWithStructureCoefficients( generators `a` and `b`, the value of ``s_coeff[('a','b')]`` is a dictionary whose keys are positive integer numbers and the corresponding value for the key `j` is a dictionary itself - representing the j-th product `a_{(j)}b`. + representing the `j`-th product `a_{(j)}b`. Thus, for a positive integer number `j`, the value of ``s_coeff[('a','b')][j]`` is a dictionary whose entries are pairs ``('c',n)`` where ``'c'`` is the name of a generator @@ -66,21 +66,20 @@ class LieConformalAlgebraWithStructureCoefficients( defined by skew-symmetry) is assumed to have vanishing `\lambda`-bracket. - - ``names`` -- tuple of ``str`` (Default: ``None``); The list of + - ``names`` -- tuple of strings (default: ``None``); the list of names for generators of this Lie conformal algebra. Do not include central elements in this list. - - ``central_elements`` -- tuple of ``str`` (Default: ``None``); - A list of names for central - elements of this Lie conformal algebra. + - ``central_elements`` -- tuple of strings (default: ``None``); + a list of names for central elements of this Lie conformal algebra - - ``index_set`` -- enumerated set (Default: ``None``); + - ``index_set`` -- enumerated set (default: ``None``); an indexing set for the generators of this Lie conformal algebra. Do not include central elements in this list. - - ``parity`` -- tuple of `0` or `1` (Default: tuple of `0`); - a tuple specifying the parity of each non-central generator. + - ``parity`` -- tuple of `0` or `1` (default: tuple of `0`); + a tuple specifying the parity of each non-central generator EXAMPLES: @@ -121,14 +120,14 @@ def _standardize_s_coeff(s_coeff, index_set, ce, parity=None): INPUT: - - ``s_coeff`` -- a dictionary as in - :class:`~sage.algebras.lie_conformal_algebras.lie_conformal_algebra_with_structure_coefficients.LieConformalAlgebraWithStructureCoefficients`. + - ``s_coeff`` -- dictionary as in + :class:`~sage.algebras.lie_conformal_algebras.lie_conformal_algebra_with_structure_coefficients.LieConformalAlgebraWithStructureCoefficients` - ``index_set`` -- a finite enumerated set indexing the generators (not counting the central elements). - - ``ce`` -- a tuple of ``str``; a list of names for the central + - ``ce`` -- tuple of strings; a list of names for the central generators of this Lie conformal algebra - - ``parity`` -- a tuple of `0` or `1` (Default: tuple of `0`); - this tuple specifies the parity of each non-central generator. + - ``parity`` -- tuple of `0` or `1` (default: tuple of `0`); + this tuple specifies the parity of each non-central generator OUTPUT: @@ -206,7 +205,7 @@ def __init__(self, R, s_coeff, index_set=None, central_elements=None, category=None, element_class=None, prefix=None, names=None, latex_names=None, parity=None, **kwds): """ - Initialize self. + Initialize ``self``. TESTS:: @@ -276,7 +275,7 @@ def __init__(self, R, s_coeff, index_set=None, central_elements=None, s_coeff = dict(s_coeff) self._s_coeff = Family({k: tuple((j, sum(c*self.monomial(i) - for i,c in v )) for j,v in s_coeff[k]) for k in s_coeff}) + for i,c in v)) for j,v in s_coeff[k]) for k in s_coeff}) self._parity = dict(zip(self.gens(),parity+(0,)*len(central_elements))) def structure_coefficients(self): diff --git a/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py index baf7a896144..1abce4b5c76 100644 --- a/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py @@ -40,7 +40,7 @@ class N2LieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - ``R`` -- a commutative ring; the base ring of this super - Lie conformal algebra. + Lie conformal algebra EXAMPLES:: @@ -75,7 +75,7 @@ class N2LieConformalAlgebra(GradedLieConformalAlgebra): """ def __init__(self, R): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py index 7bf03e30dea..323c08ee958 100644 --- a/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py @@ -35,7 +35,7 @@ class NeveuSchwarzLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - ``R`` -- a commutative Ring; the base ring of this Lie - conformal algebra. + conformal algebra EXAMPLES:: @@ -52,7 +52,7 @@ class NeveuSchwarzLieConformalAlgebra(GradedLieConformalAlgebra): """ def __init__(self, R): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py index f0867dae808..edaf039be55 100644 --- a/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py @@ -36,7 +36,7 @@ class VirasoroLieConformalAlgebra(GradedLieConformalAlgebra): INPUT: - ``R`` -- a commutative ring; behaviour is undefined if `R` is - not a Field of characteristic zero. + not a Field of characteristic zero EXAMPLES:: @@ -55,7 +55,7 @@ class VirasoroLieConformalAlgebra(GradedLieConformalAlgebra): """ def __init__(self, R): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py index 3c319db7ca3..82e0c326547 100644 --- a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py @@ -47,17 +47,16 @@ class WeylLieConformalAlgebra(LieConformalAlgebraWithStructureCoefficients): INPUT: - ``R`` -- a commutative ring; the base ring of this Lie - conformal algebra. - - ``ngens``: an even positive Integer (default `2`); The number - of non-central generators of this Lie conformal algebra. - - ``gram_matrix``: a matrix (default: ``None``); A non-singular - skew-symmetric square matrix with coefficients in `R`. - - ``names`` -- a list or tuple of ``str``; alternative names + conformal algebra + - ``ngens`` -- an even positive Integer (default: `2`); the number + of non-central generators of this Lie conformal algebra + - ``gram_matrix`` -- a matrix (default: ``None``); a non-singular + skew-symmetric square matrix with coefficients in `R` + - ``names`` -- list or tuple of strings; alternative names for the generators - ``index_set`` -- an enumerated set; alternative indexing set for the generators - OUTPUT: The Weyl Lie conformal algebra with generators @@ -124,7 +123,7 @@ class WeylLieConformalAlgebra(LieConformalAlgebraWithStructureCoefficients): def __init__(self, R, ngens=None, gram_matrix=None, names=None, index_set=None): """ - Initialize self. + Initialize ``self``. TESTS:: diff --git a/src/sage/algebras/meson.build b/src/sage/algebras/meson.build new file mode 100644 index 00000000000..a7e74474c6b --- /dev/null +++ b/src/sage/algebras/meson.build @@ -0,0 +1,75 @@ +py.install_sources( + 'affine_nil_temperley_lieb.py', + 'algebra.py', + 'all.py', + 'askey_wilson.py', + 'associated_graded.py', + 'catalog.py', + 'cellular_basis.py', + 'clifford_algebra.py', + 'clifford_algebra_element.pxd', + 'cluster_algebra.py', + 'commutative_dga.py', + 'down_up_algebra.py', + 'exterior_algebra_groebner.pxd', + 'finite_gca.py', + 'free_algebra.py', + 'free_algebra_element.py', + 'free_algebra_quotient.py', + 'free_algebra_quotient_element.py', + 'free_zinbiel_algebra.py', + 'group_algebra.py', + 'hall_algebra.py', + 'iwahori_hecke_algebra.py', + 'jordan_algebra.py', + 'nil_coxeter_algebra.py', + 'octonion_algebra.pxd', + 'orlik_solomon.py', + 'orlik_terao.py', + 'q_commuting_polynomials.py', + 'q_system.py', + 'quantum_clifford.py', + 'quantum_matrix_coordinate_algebra.py', + 'quantum_oscillator.py', + 'quaternion_algebra.py', + 'quaternion_algebra_element.py', + 'rational_cherednik_algebra.py', + 'schur_algebra.py', + 'shuffle_algebra.py', + 'splitting_algebra.py', + 'tensor_algebra.py', + 'weyl_algebra.py', + 'yangian.py', + 'yokonuma_hecke_algebra.py', + subdir: 'sage/algebras', +) + +extension_data = { + 'clifford_algebra_element' : files('clifford_algebra_element.pyx'), + 'exterior_algebra_groebner' : files('exterior_algebra_groebner.pyx'), + 'octonion_algebra' : files('octonion_algebra.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +subdir('finite_dimensional_algebras') +subdir('fusion_rings') +install_subdir('hecke_algebras', install_dir: sage_install_dir / 'algebras') +subdir('letterplace') +subdir('lie_algebras') +install_subdir( + 'lie_conformal_algebras', + install_dir: sage_install_dir / 'algebras', +) +install_subdir('quantum_groups', install_dir: sage_install_dir / 'algebras') +subdir('quatalg') +install_subdir('steenrod', install_dir: sage_install_dir / 'algebras') diff --git a/src/sage/algebras/nil_coxeter_algebra.py b/src/sage/algebras/nil_coxeter_algebra.py index b470d16f971..8b47e6fd49b 100644 --- a/src/sage/algebras/nil_coxeter_algebra.py +++ b/src/sage/algebras/nil_coxeter_algebra.py @@ -28,11 +28,8 @@ class NilCoxeterAlgebra(IwahoriHeckeAlgebra.T): INPUT: - ``W`` -- a Weyl group - - OPTIONAL ARGUMENTS: - - - ``base_ring`` -- a ring (default is the rational numbers) - - ``prefix`` -- a label for the generators (default "u") + - ``base_ring`` -- a ring (default: rational numbers) + - ``prefix`` -- a label for the generators (default: ``'u'``) EXAMPLES:: @@ -80,14 +77,14 @@ def _repr_(self): def homogeneous_generator_noncommutative_variables(self, r): r""" - Give the `r^{th}` homogeneous function inside the Nil-Coxeter algebra. + Give the `r`-th homogeneous function inside the Nil-Coxeter algebra. In finite type `A` this is the sum of all decreasing elements of length `r`. In affine type `A` this is the sum of all cyclically decreasing elements of length `r`. This is only defined in finite type `A`, `B` and affine types `A^{(1)}`, `B^{(1)}`, `C^{(1)}`, `D^{(1)}`. INPUT: - - ``r`` -- a positive integer at most the rank of the Weyl group + - ``r`` -- positive integer at most the rank of the Weyl group EXAMPLES:: @@ -141,7 +138,6 @@ def homogeneous_noncommutative_variables(self, la): sage: U = NilCoxeterAlgebra(WeylGroup(['B',2,1])) sage: U.homogeneous_noncommutative_variables([]) 1 - """ return prod(self.homogeneous_generator_noncommutative_variables(p) for p in la) @@ -183,8 +179,6 @@ def k_schur_noncommutative_variables(self, la): Traceback (most recent call last): ... AssertionError: Weyl Group of type ['C', 3, 1] (as a matrix group acting on the root space) is not affine type A. - - """ assert self._cartan_type[0] == 'A' and len(self._cartan_type) == 3 and self._cartan_type[2] == 1, "%s is not affine type A." % (self._W) assert la in Partitions(), "%s is not a partition." % (la) diff --git a/src/sage/algebras/octonion_algebra.pyx b/src/sage/algebras/octonion_algebra.pyx index 3c1d28c2106..c38250b0be7 100644 --- a/src/sage/algebras/octonion_algebra.pyx +++ b/src/sage/algebras/octonion_algebra.pyx @@ -89,7 +89,7 @@ cdef class Octonion_generic(AlgebraElement): def __bool__(self): r""" - Return if ``self`` is non-zero or not. + Return if ``self`` is nonzero or not. EXAMPLES:: @@ -451,9 +451,7 @@ cdef class Octonion_generic(AlgebraElement): r""" Return the real part of ``self``. - OUTPUT: - - The real part of ``self`` as an element in the base ring. + OUTPUT: the real part of ``self`` as an element in the base ring EXAMPLES:: @@ -471,9 +469,7 @@ cdef class Octonion_generic(AlgebraElement): r""" Return the imginary part of ``self``. - OUTPUT: - - The imaginary part of ``self`` as an element in the octonion algebra. + OUTPUT: the imaginary part of ``self`` as an element in the octonion algebra EXAMPLES:: diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 12e8518a2b0..113bb29418f 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -25,7 +25,7 @@ class OrlikSolomonAlgebra(CombinatorialFreeModule): r""" An Orlik-Solomon algebra. - Let `R` be a commutative ring. Let `M` be a matroid with ground set + Let `R` be a commutative ring. Let `M` be a matroid with groundset `X`. Let `C(M)` denote the set of circuits of `M`. Let `E` denote the exterior algebra over `R` generated by `\{ e_x \mid x \in X \}`. The *Orlik-Solomon ideal* `J(M)` is the ideal of `E` generated by @@ -60,7 +60,7 @@ class OrlikSolomonAlgebra(CombinatorialFreeModule): - ``R`` -- the base ring - ``M`` -- the defining matroid - - ``ordering`` -- (optional) an ordering of the ground set + - ``ordering`` -- (optional) an ordering of the groundset EXAMPLES: @@ -202,7 +202,7 @@ def algebra_generators(self): r""" Return the algebra generators of ``self``. - These form a family indexed by the ground set `X` of `M`. For + These form a family indexed by the groundset `X` of `M`. For each `x \in X`, the `x`-th element is `e_x`. EXAMPLES:: @@ -255,7 +255,7 @@ def product_on_basis(self, a, b): TESTS: Let us check that `e_{s_1} e_{s_2} \cdots e_{s_k} = e_S` for any - subset `S = \{ s_1 < s_2 < \cdots < s_k \}` of the ground set:: + subset `S = \{ s_1 < s_2 < \cdots < s_k \}` of the groundset:: sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[3,4],[4,2]], multiedges=True) @@ -311,11 +311,11 @@ def product_on_basis(self, a, b): def subset_image(self, S): """ Return the element `e_S` of `A(M)` (``== self``) corresponding to - a subset `S` of the ground set of `M`. + a subset `S` of the groundset of `M`. INPUT: - - ``S`` -- a frozenset which is a subset of the ground set of `M` + - ``S`` -- frozenset which is a subset of the groundset of `M` EXAMPLES:: @@ -791,9 +791,9 @@ def action(g, m): # computing the invariant will be a block matrix. To avoid dealing # with huge matrices, we can split it up into graded pieces. - max_deg = max([b.degree() for b in OS.basis()]) - B = [] #initialize the basis - for d in range(max_deg+1): + max_deg = max(b.degree() for b in OS.basis()) + B = [] # initialize the basis + for d in range(max_deg + 1): OS_d = OS.homogeneous_component(d) OSG_d = OS_d.invariant_module(G, action=action, category=category) B += [OS_d.lift(OSG_d.lift(b)) for b in OSG_d.basis()] diff --git a/src/sage/algebras/orlik_terao.py b/src/sage/algebras/orlik_terao.py index 222e2152739..60c3c60e6db 100644 --- a/src/sage/algebras/orlik_terao.py +++ b/src/sage/algebras/orlik_terao.py @@ -292,7 +292,7 @@ def degree_on_basis(self, m): """ return len(m) - ## Multiplication + # Multiplication def product_on_basis(self, a, b): r""" @@ -359,7 +359,7 @@ def subset_image(self, S): INPUT: - - ``S`` -- a frozenset which is a subset of the groundset of `M` + - ``S`` -- frozenset which is a subset of the groundset of `M` EXAMPLES:: @@ -613,7 +613,6 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): Finite family {0: B[0], 1: B[1]} sage: [OTG.lift(b) for b in OTG.basis()] [OT{}, OT{0} + OT{1} + OT{2} + OT{3} + OT{4} + OT{5}] - """ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): r""" @@ -630,7 +629,6 @@ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): sage: import __main__; __main__.on_groundset = on_groundset sage: OTG = M.orlik_terao_algebra(QQ, invariant = (G,on_groundset)) sage: TestSuite(OTG).run() - """ ordering = kwargs.pop('ordering', None) OT = OrlikTeraoAlgebra(R, M, ordering) diff --git a/src/sage/algebras/q_commuting_polynomials.py b/src/sage/algebras/q_commuting_polynomials.py index 10f5f55a987..f19eaa042e4 100644 --- a/src/sage/algebras/q_commuting_polynomials.py +++ b/src/sage/algebras/q_commuting_polynomials.py @@ -173,7 +173,7 @@ def algebra_generators(self): Finite family {'x': x, 'y': y, 'z': z} """ d = {v: self.gen(i) for i, v in enumerate(self.variable_names())} - return Family(self.variable_names(), d.__getitem__, name="generator") + return Family(self.variable_names(), d.__getitem__, name='generator') def degree_on_basis(self, m): r""" diff --git a/src/sage/algebras/q_system.py b/src/sage/algebras/q_system.py index cea0332d4f4..a8342434847 100644 --- a/src/sage/algebras/q_system.py +++ b/src/sage/algebras/q_system.py @@ -446,12 +446,12 @@ def Q(self, a, m): if m == t[a] * self._level: return self.one() if m == 1: - return self.monomial( self._indices.gen((a,1)) ) + return self.monomial(self._indices.gen((a,1))) #if self._cartan_type.type() == 'A' and self._level is None: # return self._jacobi_trudy(a, m) I = self._cm.index_set() p = self._Q_poly(a, m) - return p.subs({ g: self.Q(I[i], 1) for i,g in enumerate(self._poly.gens()) }) + return p.subs({g: self.Q(I[i], 1) for i,g in enumerate(self._poly.gens())}) @cached_method def _Q_poly(self, a, m): diff --git a/src/sage/algebras/quantum_clifford.py b/src/sage/algebras/quantum_clifford.py index 89fea14c495..99c0c1e226f 100644 --- a/src/sage/algebras/quantum_clifford.py +++ b/src/sage/algebras/quantum_clifford.py @@ -489,7 +489,7 @@ def product_on_basis(self, m1, m2): if p1[i] != 0: # We make pairings 1-based because we cannot distinguish 0 and -0 pairings.append((i+1) * p1[i]) - # we know p1[i] != p2[i] if non-zero, so their sum is -1, 0, 1 + # we know p1[i] != p2[i] if nonzero, so their sum is -1, 0, 1 p[i] = p1[i] + p2[i] supported.append(self._n-1) # To get between the last support and the end @@ -533,7 +533,7 @@ def product_on_basis(self, m1, m2): poly *= self._w_poly.monomial(*v) poly = poly.reduce([vp[i]**(4*k) - (1 + q**(-2*k)) * vp[i]**(2*k) + q**(-2*k) for i in range(self._n)]) - pdict = poly.dict() + pdict = poly.monomial_coefficients() ret = {(self._psi(p), tuple(e)): pdict[e] * q**q_power * sign for e in pdict} @@ -610,7 +610,7 @@ def inverse(self): for wi in wp}) poly = poly.reduce([wi**(4*k) - (1 + q**(-2*k)) * wi**(2*k) + q**(-2*k) for wi in wp]) - pdict = poly.dict() + pdict = poly.monomial_coefficients() coeff = coeff.inverse_of_unit() ret = {(p, tuple(e)): coeff * c for e, c in pdict.items()} return Cl.element_class(Cl, ret) diff --git a/src/sage/algebras/quantum_groups/fock_space.py b/src/sage/algebras/quantum_groups/fock_space.py index aff82cd445f..d1d98d3c184 100644 --- a/src/sage/algebras/quantum_groups/fock_space.py +++ b/src/sage/algebras/quantum_groups/fock_space.py @@ -41,7 +41,7 @@ class FockSpaceOptions(GlobalOptions): r""" - Sets and displays the global options for elements of the Fock + Set and display the global options for elements of the Fock space classes. If no parameters are set, then the function returns a copy of the options dictionary. @@ -444,7 +444,7 @@ def inject_shorthands(self, verbose=True): INPUT: - - ``verbose`` -- boolean (default ``True``) if ``True``, prints + - ``verbose`` -- boolean (default: ``True``); if ``True``, prints the defined shorthands EXAMPLES:: @@ -749,7 +749,7 @@ def N_left(la, x, i): return (sum(1 for y in P._addable(la, i) if P._above(x, y)) - sum(1 for y in P._removable(la, i) if P._above(x, y))) q = P.realization_of()._q - return P.sum_of_terms(( la.remove_cell(*x), c * q**(-N_left(la, x, i)) ) + return P.sum_of_terms((la.remove_cell(*x), c * q**(-N_left(la, x, i))) for la,c in self for x in P._removable(la, i)) def e(self, *data): @@ -759,7 +759,7 @@ def e(self, *data): INPUT: - - ``*data`` -- a list of indices or pairs `(i, p)` + - ``*data`` -- list of indices or pairs `(i, p)` EXAMPLES:: @@ -845,8 +845,8 @@ def N_right(la, x, i): return (sum(1 for y in P._addable(la, i) if P._above(y, x)) - sum(1 for y in P._removable(la, i) if P._above(y, x))) q = P.realization_of()._q - return P.sum_of_terms( (la.add_cell(*x), c * q**N_right(la, x, i)) - for la,c in self for x in P._addable(la, i) ) + return P.sum_of_terms((la.add_cell(*x), c * q**N_right(la, x, i)) + for la,c in self for x in P._addable(la, i)) def f(self, *data): r""" @@ -855,7 +855,7 @@ def f(self, *data): INPUT: - - ``*data`` -- a list of indices or pairs `(i, p)` + - ``*data`` -- list of indices or pairs `(i, p)` EXAMPLES:: @@ -1384,7 +1384,7 @@ def _G_to_fock_basis(self, la): ############################################################################### -## Bases Category +# Bases Category class FockSpaceBases(Category_realization_of_parent): r""" @@ -1605,7 +1605,7 @@ def __getitem__(self, i): return self.monomial(i) ############################################################################### -## Truncated Fock space +# Truncated Fock space class FockSpaceTruncated(FockSpace): @@ -1819,7 +1819,7 @@ class A(CombinatorialFreeModule, BindableClass): INPUT: - - ``algorithm`` -- (default ``'GW'``) the algorithm to use when + - ``algorithm`` -- (default: ``'GW'``) the algorithm to use when computing this basis in the Fock space; the possible values are: * ``'GW'`` -- use the algorithm given by Goodman and Wenzl @@ -2020,7 +2020,7 @@ def _A_to_fock_basis(self, la): # For non-interior partitions # Construct the d's and the partition ``a`` - a = list(la) + [0]*(k - 1 - len(la)) # Add 0's to get the correct length + a = list(la) + [0]*(k - 1 - len(la)) # Add 0s to get the correct length a = [a[i] + (k - 1 - i) for i in range(k-1)] # Shift the diagram #shifted = list(a) # Make a copy of the shifted partition in case we need it later d = [(a[i] - a[i+1]) % n for i in range(k-2)] @@ -2178,7 +2178,7 @@ def _G_to_fock_basis(self, la, algorithm='GW'): mu = _Partitions([p - x for p in la]) def add_cols(nu): - return _Partitions([ v + x for v in list(nu) + [0]*(k - len(nu)) ]) + return _Partitions([v + x for v in list(nu) + [0]*(k - len(nu))]) return fock.sum_of_terms((add_cols(nu), c) for nu,c in self._G_to_fock_basis(mu)) # For critical partitions diff --git a/src/sage/algebras/quantum_groups/quantum_group_gap.py b/src/sage/algebras/quantum_groups/quantum_group_gap.py index 997fe0f3b04..931ee211ff1 100644 --- a/src/sage/algebras/quantum_groups/quantum_group_gap.py +++ b/src/sage/algebras/quantum_groups/quantum_group_gap.py @@ -371,7 +371,7 @@ def __init__(self, cartan_type, q): sage: TestSuite(Q).run() # long time """ self._cartan_type = cartan_type - GapPackage("QuaGroup", spkg="gap_package_quagroup").require() + GapPackage("QuaGroup", spkg='gap_package_quagroup').require() libgap.LoadPackage('QuaGroup') R = libgap.eval('RootSystem("%s",%s)' % (cartan_type.type(), cartan_type.rank())) Q = self._cartan_type.root_system().root_lattice() @@ -838,7 +838,7 @@ def counit(self, elt): constant = R(str(ext_rep.pop(2 * i))) # Pop the coefficient break # To reconstruct, we need the following - F = libgap.eval('ElementsFamily')(libgap.eval('FamilyObj')(self._libgap)) + F = self._libgap.FamilyObj().ElementsFamily() elt = F.ObjByExtRep(ext_rep) co = self._libgap.CounitMap() return R(str(co(elt))) + constant @@ -1084,7 +1084,7 @@ def __init__(self, parent, im_gens, check=True): sage: Q = QuantumGroup(['A',1]) sage: F, K, Ki, E = Q.gens() sage: phi = Q.hom([E, Ki, K, F]) - sage: TestSuite(phi).run(skip="_test_category") + sage: TestSuite(phi).run(skip='_test_category') """ self._repr_type_str = "Quantum group homomorphism" Morphism.__init__(self, parent) @@ -1699,7 +1699,7 @@ def crystal_graph(self): G = DiGraph([vertices, edges], format='vertices_and_edges') from sage.graphs.dot2tex_utils import have_dot2tex if have_dot2tex(): - G.set_latex_options(format="dot2tex", + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=self._cartan_type._index_set_coloring) return G @@ -2073,7 +2073,7 @@ def lift(self): + q^-1*(F[a1+a2]*v0F[a1]*v0) + 1*(F[a1+a2]*v0F[a1+a2]*v0) """ return self.module_morphism(self._ambient_basis_map.__getitem__, - codomain=self._ambient, unitriangular="lower") + codomain=self._ambient, unitriangular='lower') def retract(self, elt): """ @@ -2153,7 +2153,7 @@ def crystal_graph(self, use_ambient=True): G = DiGraph([vertices, edges], format='vertices_and_edges') from sage.graphs.dot2tex_utils import have_dot2tex if have_dot2tex(): - G.set_latex_options(format="dot2tex", + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=self._cartan_type._index_set_coloring) return G @@ -2330,7 +2330,7 @@ def _construct_monomial(self, k): sage: B._construct_monomial((3,0,1)) F[a1]^(3)*F[a2] """ - F = libgap.eval('ElementsFamily')(libgap.eval('FamilyObj')(self._libgap)) + F = self._libgap.FamilyObj().ElementsFamily() one = self._libgap_base.One() data = [] for i, val in enumerate(k): @@ -2364,7 +2364,7 @@ def basis(self): F[a1]*F[a2]^(4) """ I = cartesian_product([NonNegativeIntegers()]*len(self._pos_roots)) - return Family(I, self._construct_monomial, name="monomial") + return Family(I, self._construct_monomial, name='monomial') def _construct_canonical_basis_elts(self, k): r""" @@ -2684,7 +2684,7 @@ def _unpickle_generic_element(parent, data): sage: loads(dumps(x)) == x # indirect doctest True """ - F = libgap.eval('ElementsFamily')(libgap.eval('FamilyObj')(parent._libgap)) + F = parent._libgap.FamilyObj().ElementsFamily() ret = [] # We need to multiply by this to get the right type in GAP one = parent._libgap_base.One() diff --git a/src/sage/algebras/quantum_groups/representations.py b/src/sage/algebras/quantum_groups/representations.py index 7042c5aba76..7d42aa78787 100644 --- a/src/sage/algebras/quantum_groups/representations.py +++ b/src/sage/algebras/quantum_groups/representations.py @@ -124,7 +124,7 @@ def K_on_basis(self, i, b, power=1): """ WLR = self.basis().keys().weight_lattice_realization() alc = WLR.simple_coroots() - return self.term( b, self._q**(b.weight().scalar(alc[i]) * self._d[i] * power) ) + return self.term(b, self._q**(b.weight().scalar(alc[i]) * self._d[i] * power)) class CyclicRepresentation(QuantumGroupRepresentation): diff --git a/src/sage/algebras/quantum_matrix_coordinate_algebra.py b/src/sage/algebras/quantum_matrix_coordinate_algebra.py index 4b08c36f45f..9ddde4376c8 100644 --- a/src/sage/algebras/quantum_matrix_coordinate_algebra.py +++ b/src/sage/algebras/quantum_matrix_coordinate_algebra.py @@ -983,11 +983,9 @@ def _generator_key(t): INPUT: - a tuple (index, exponent) + - ``t`` -- tuple (index, exponent) - OUTPUT: - - a tuple made from the index only + OUTPUT: a tuple made from the index only EXAMPLES:: diff --git a/src/sage/algebras/quantum_oscillator.py b/src/sage/algebras/quantum_oscillator.py index a688283705f..7ac3509238f 100644 --- a/src/sage/algebras/quantum_oscillator.py +++ b/src/sage/algebras/quantum_oscillator.py @@ -122,7 +122,7 @@ class QuantumOscillatorAlgebra(CombinatorialFreeModule): - [Kuniba2022]_ Section 3.2 """ @staticmethod - def __classcall_private__(cls, q=None, R=None): + def __classcall_private__(cls, q=None, R=None): r""" Standardize input to ensure a unique representation. diff --git a/src/sage/algebras/quatalg/meson.build b/src/sage/algebras/quatalg/meson.build new file mode 100644 index 00000000000..2ec5cd31f22 --- /dev/null +++ b/src/sage/algebras/quatalg/meson.build @@ -0,0 +1,24 @@ +py.install_sources( + 'all.py', + 'quaternion_algebra.py', + 'quaternion_algebra_element.pxd', + subdir: 'sage/algebras/quatalg', +) + +extension_data_cpp = { + 'quaternion_algebra_cython': files('quaternion_algebra_cython.pyx'), + 'quaternion_algebra_element': files('quaternion_algebra_element.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/algebras/quatalg', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ext, inc_flint, inc_ntl, inc_rings], + dependencies: [py_dep, flint, gmp, m, ntl], + ) +endforeach + diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index 93e22abd6fd..f85f282c0bb 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -287,7 +287,6 @@ def create_object(self, version, key, **extra_args): sage: QuaternionAlgebra.create_object("6.0", (QQ, -1, -1, ('i', 'j', 'k'))) Quaternion Algebra (-1, -1) with base ring Rational Field - """ K, a, b, names = key return QuaternionAlgebra_ab(K, a, b, names=names) @@ -451,7 +450,6 @@ def is_matrix_ring(self) -> bool: Traceback (most recent call last): ... NotImplementedError: base field must be rational numbers - """ if not isinstance(self.base_ring(), RationalField): raise NotImplementedError("base field must be rational numbers") @@ -630,7 +628,7 @@ class QuaternionAlgebra_ab(QuaternionAlgebra_abstract): - ``base_ring`` -- a commutative ring `K` in which 2 is invertible - ``a``, ``b`` -- units of `K` - - ``names`` -- string (default: ``'i,j,k'``) names of the generators + - ``names`` -- string (default: ``'i,j,k'``); names of the generators OUTPUT: @@ -706,16 +704,14 @@ def maximal_order(self, take_shortcuts=True, order_basis=None): INPUT: - - ``take_shortcuts`` -- (default: ``True``) if the discriminant is + - ``take_shortcuts`` -- boolean (default: ``True``); if the discriminant is prime and the invariants of the algebra are of a nice form, use Proposition 5.2 of [Piz1980]_. - ``order_basis`` -- (default: ``None``) a basis of an order of this quaternion algebra - OUTPUT: - - A maximal order in this quaternion algebra. + OUTPUT: a maximal order in this quaternion algebra EXAMPLES:: @@ -865,7 +861,7 @@ def maximal_order(self, take_shortcuts=True, order_basis=None): # Since Voight's algorithm only works for a starting basis having 1 as # its first vector, we derive such a basis from the given order basis - basis = basis_for_quaternion_lattice(order_basis, reverse=True) + basis = basis_for_quaternion_lattice(order_basis) e_new_gens = [] @@ -943,7 +939,7 @@ def maximal_order(self, take_shortcuts=True, order_basis=None): h = (z*b)*e_n[1] - (y*a)*e_n[2] e_n[1:4] = [g, h, g * h] if (1 - a*y**2 - b*z**2 + a*b*w**2).valuation(2) > 2: - e_n = basis_for_quaternion_lattice(list(e) + e_n[1:], reverse=True) + e_n = basis_for_quaternion_lattice(list(e) + e_n[1:]) # e_n now contains elements that locally at p give a bigger order, # but the basis may be messed up at other primes (it might not @@ -957,7 +953,7 @@ def maximal_order(self, take_shortcuts=True, order_basis=None): e_new_gens.extend(e[1:]) - e_new = basis_for_quaternion_lattice(list(basis) + e_new_gens, reverse=True) + e_new = basis_for_quaternion_lattice(list(basis) + e_new_gens) return self.quaternion_order(e_new) def order_with_level(self, level): @@ -1050,7 +1046,7 @@ def invariants(self): def is_definite(self): """ - Checks whether the quaternion algebra ``self`` is definite, i.e. whether it ramifies at the + Check whether the quaternion algebra ``self`` is definite, i.e. whether it ramifies at the unique Archimedean place of its base field QQ. This is the case if and only if both invariants of ``self`` are negative. @@ -1073,7 +1069,7 @@ def is_definite(self): def __eq__(self, other): """ - Compare self and other. + Compare ``self`` and ``other``. EXAMPLES:: @@ -1089,7 +1085,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Compare self and other. + Compare ``self`` and ``other``. EXAMPLES:: @@ -1116,7 +1112,7 @@ def __hash__(self): def gen(self, i=0): """ - Return the `i^{th}` generator of ``self``. + Return the `i`-th generator of ``self``. INPUT: @@ -1320,7 +1316,7 @@ def quaternion_order(self, basis, check=True): INPUT: - ``basis`` -- list of 4 elements of ``self`` - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) EXAMPLES:: @@ -1348,9 +1344,9 @@ def ideal(self, gens, left_order=None, right_order=None, check=True, **kwds): INPUT: - - ``gens`` -- a list of elements of this quaternion order + - ``gens`` -- list of elements of this quaternion order - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - ``left_order`` -- a quaternion order or ``None`` @@ -1386,11 +1382,9 @@ def modp_splitting_data(self, p): INPUT: - - `p` -- unramified odd prime - - OUTPUT: + - ``p`` -- unramified odd prime - - 2-tuple of matrices over finite field + OUTPUT: 2-tuple of matrices over finite field EXAMPLES:: @@ -1489,7 +1483,7 @@ def modp_splitting_map(self, p): INPUT: - - `p` -- prime number + - ``p`` -- prime number EXAMPLES:: @@ -1517,7 +1511,7 @@ def phi(q): ############################################################ def unpickle_QuaternionAlgebra_v0(*key): """ - The 0th version of pickling for quaternion algebras. + The `0`-th version of pickling for quaternion algebras. EXAMPLES:: @@ -1626,8 +1620,8 @@ def __init__(self, A, basis, check=True): raise ValueError("lattice must contain 1") # check if multiplicatively closed - M1 = basis_for_quaternion_lattice(basis, reverse=False) - M2 = basis_for_quaternion_lattice(list(basis) + [x * y for x in basis for y in basis], reverse=False) + M1 = basis_for_quaternion_lattice(basis) + M2 = basis_for_quaternion_lattice(list(basis) + [x * y for x in basis for y in basis]) if M1 != M2: raise ValueError("given lattice must be a ring") @@ -1683,7 +1677,6 @@ def _element_constructor_(self, x): False sage: j/2 in O False - """ y = self.quaternion_algebra()(x) if y not in self.unit_ideal(): @@ -1725,11 +1718,11 @@ def ngens(self): def gen(self, n): """ - Return the n-th generator. + Return the `n`-th generator. INPUT: - - ``n`` -- an integer between 0 and 3, inclusive. + - ``n`` -- integer between 0 and 3, inclusive EXAMPLES:: @@ -1926,9 +1919,7 @@ def free_module(self): inside the vector space corresponding to the ambient quaternion algebra. - OUTPUT: - - A free `\ZZ`-module of rank 4. + OUTPUT: a free `\ZZ`-module of rank 4 EXAMPLES:: @@ -2013,19 +2004,17 @@ def _left_ideal_basis(self, gens): - ``gens`` -- list of elements of ``self`` - OUTPUT: - - A list of four elements of ``self``. + OUTPUT: list of four elements of ``self`` EXAMPLES:: sage: A. = QuaternionAlgebra(-17, -3) sage: A.maximal_order()._left_ideal_basis([i + j, i - j, 2*k, A(3)]) - [1/2 + 1/6*j + 2/3*k, 1/2*i + 1/2*k, 1/3*j + 1/3*k, k] + [1, i, 1/2 + 1/2*j, 1/2 + 1/2*i + 1/6*j + 1/6*k] sage: A.maximal_order()._left_ideal_basis([3*(i + j), 3*(i - j), 6*k, A(3)]) - [3/2 + 1/2*j + 2*k, 3/2*i + 3/2*k, j + k, 3*k] + [3, 3*i, 3/2 + 3/2*j, 3/2 + 3/2*i + 1/2*j + 1/2*k] """ - return basis_for_quaternion_lattice([b * g for b in self.basis() for g in gens], reverse=False) + return basis_for_quaternion_lattice([b * g for b in self.basis() for g in gens]) def _right_order_from_ideal_basis(self, basis): """ @@ -2041,12 +2030,12 @@ def _right_order_from_ideal_basis(self, basis): sage: A. = QuaternionAlgebra(17) sage: O = A.maximal_order() sage: basis = O._left_ideal_basis([1]); basis - [1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k] + [1, 1/2 + 1/2*i, j, 1/3*i + 1/2*j + 1/6*k] sage: O._right_order_from_ideal_basis(basis) Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k) sage: basis = O._left_ideal_basis([i*j - j]); basis - [17 + 17/3*i + 4/3*k, 34/3*i + 2/3*k, j + k, 2*k] + [34, 17 + 17*i, 2*j, 17 + 17/3*i + j + 1/3*k] sage: O._right_order_from_ideal_basis(basis) Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k) """ @@ -2080,12 +2069,12 @@ def left_ideal(self, gens, check=True, *, is_basis=False): INPUT: - - ``gens`` -- a list of elements of this quaternion order + - ``gens`` -- list of elements of this quaternion order - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - - ``is_basis`` -- bool (default: ``False``); if ``True`` then ``gens`` - must be a `\ZZ`-basis of the ideal + - ``is_basis`` -- boolean (default: ``False``); if ``True`` then + ``gens`` must be a `\ZZ`-basis of the ideal EXAMPLES:: @@ -2100,9 +2089,9 @@ def left_ideal(self, gens, check=True, *, is_basis=False): or a single generator:: sage: R.left_ideal([i+j]) - Fractional ideal (1/2 + 1/2*i + 1/2*j + 13/2*k, i + j, 6*j + 6*k, 12*k) + Fractional ideal (12, 6 + 6*i, i + j, 13/2 + 1/2*i + 1/2*j + 1/2*k) sage: R.left_ideal(i+j) - Fractional ideal (1/2 + 1/2*i + 1/2*j + 13/2*k, i + j, 6*j + 6*k, 12*k) + Fractional ideal (12, 6 + 6*i, i + j, 13/2 + 1/2*i + 1/2*j + 1/2*k) sage: R.left_ideal([2, 1+j]) == R*2 + R*(1+j) True """ @@ -2113,7 +2102,7 @@ def left_ideal(self, gens, check=True, *, is_basis=False): else: if gens in self.quaternion_algebra(): gens = [gens] - basis = tuple(basis_for_quaternion_lattice([b * g for b in self.basis() for g in gens], reverse=False)) + basis = tuple(basis_for_quaternion_lattice([b * g for b in self.basis() for g in gens])) check = False return QuaternionFractionalIdeal_rational(self.quaternion_algebra(), basis, left_order=self, check=check) @@ -2123,12 +2112,12 @@ def right_ideal(self, gens, check=True, *, is_basis=False): INPUT: - - ``gens`` -- a list of elements of this quaternion order + - ``gens`` -- list of elements of this quaternion order - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - - ``is_basis`` -- bool (default: ``False``); if ``True`` then ``gens`` - must be a `\ZZ`-basis of the ideal + - ``is_basis`` -- boolean (default: ``False``); if ``True`` then + ``gens`` must be a `\ZZ`-basis of the ideal EXAMPLES:: @@ -2143,9 +2132,9 @@ def right_ideal(self, gens, check=True, *, is_basis=False): or a single generator:: sage: R.right_ideal([i+j]) - Fractional ideal (1/2 + 1/2*i + 1/2*j + 11/2*k, i + j, 6*j + 6*k, 12*k) + Fractional ideal (12, 6 + 6*i, i + j, 11/2 + 1/2*i + 1/2*j + 1/2*k) sage: R.right_ideal(i+j) - Fractional ideal (1/2 + 1/2*i + 1/2*j + 11/2*k, i + j, 6*j + 6*k, 12*k) + Fractional ideal (12, 6 + 6*i, i + j, 11/2 + 1/2*i + 1/2*j + 1/2*k) sage: R.right_ideal([2, 1+j]) == 2*R + (1+j)*R True """ @@ -2156,7 +2145,7 @@ def right_ideal(self, gens, check=True, *, is_basis=False): else: if gens in self.quaternion_algebra(): gens = [gens] - basis = tuple(basis_for_quaternion_lattice([g * b for b in self.basis() for g in gens], reverse=False)) + basis = tuple(basis_for_quaternion_lattice([g * b for b in self.basis() for g in gens])) check = False return QuaternionFractionalIdeal_rational(self.quaternion_algebra(), basis, right_order=self, check=check) @@ -2221,7 +2210,7 @@ def __mul__(self, other): sage: Q. = QuaternionAlgebra(-1,-11) sage: O = Q.maximal_order() sage: I = O*j; I - Fractional ideal (-11/2 + 1/2*j, -11/2*i + 1/2*k, -11, -11*i) + Fractional ideal (11, 11*i, 11/2 + 1/2*j, 11/2*i + 1/2*k) """ return self.unit_ideal() * other @@ -2268,12 +2257,10 @@ def ternary_quadratic_form(self, include_basis=False): INPUT: - - ``include_basis`` -- bool (default: ``False``), if True also + - ``include_basis`` -- boolean (default: ``False``); if ``True`` also return a basis for the dimension 3 subspace `G` - OUTPUT: - - - QuadraticForm + OUTPUT: QuadraticForm - optional basis for dimension 3 subspace @@ -2337,13 +2324,13 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): INPUT: - - ``conjugator`` -- bool (default: ``False``), if True this + - ``conjugator`` -- boolean (default: ``False``); if ``True`` this method returns a single quaternion `\gamma \in O \cap O'` of minimal norm such that `O' = \gamma^{-1} O \gamma`, - rather than the ring isomorphism it defines. + rather than the ring isomorphism it defines - - ``B`` -- postive integer, bound on theta series - coefficients to rule out non isomorphic orders. + - ``B`` -- positive integer; bound on theta series + coefficients to rule out non isomorphic orders .. NOTE:: @@ -2359,11 +2346,13 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): sage: iso = O0.isomorphism_to(O1) sage: iso Ring morphism: - From: Order of Quaternion Algebra (-1, -19) with base ring Rational Field with basis (1, i, 1/2*i + 1/2*j, 1/2 + 1/2*k) - To: Order of Quaternion Algebra (-1, -19) with base ring Rational Field with basis (1, 667*i, 1/2 + 9*i + 1/2*j, 222075/1334*i + 333/667*j + 1/1334*k) + From: Order of Quaternion Algebra (-1, -19) with base ring Rational Field + with basis (1, i, 1/2*i + 1/2*j, 1/2 + 1/2*k) + To: Order of Quaternion Algebra (-1, -19) with base ring Rational Field + with basis (1, 667*i, 1/2 + 9*i + 1/2*j, 222075/1334*i + 333/667*j + 1/1334*k) Defn: i |--> 629/667*i + 36/667*j - 36/667*k - j |--> 684/667*i - 648/667*j - 19/667*k - k |--> -684/667*i - 19/667*j - 648/667*k + j |--> -684/667*i + 648/667*j + 19/667*k + k |--> 684/667*i + 19/667*j + 648/667*k sage: iso(1) 1 sage: iso(i) @@ -2376,7 +2365,7 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): :: sage: gamma = O0.isomorphism_to(O1, conjugator=True); gamma - -36*i - j + k + -36 + j + k sage: gamma in O0 True sage: gamma in O1 @@ -2423,7 +2412,7 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): sage: Oconj = j.inverse() * O * j sage: Oconj = Quat.quaternion_order(Oconj.basis()) sage: O.isomorphism_to(Oconj, conjugator=True) - -j + j Test error cases:: @@ -2575,7 +2564,7 @@ class QuaternionFractionalIdeal_rational(QuaternionFractionalIdeal): - ``basis`` -- tuple of length 4 of elements in of ambient quaternion algebra whose `\\ZZ`-span is an ideal - - ``check`` -- bool (default: ``True``); if ``False``, do no type + - ``check`` -- boolean (default: ``True``); if ``False``, do no type checking. """ def __init__(self, Q, basis, left_order=None, right_order=None, check=True): @@ -2584,7 +2573,7 @@ def __init__(self, Q, basis, left_order=None, right_order=None, check=True): sage: R = QuaternionAlgebra(-11,-1).maximal_order() sage: R.right_ideal(R.basis()) - Fractional ideal (1/2 + 1/2*i, i, 1/2*j + 1/2*k, k) + Fractional ideal (1, 1/2 + 1/2*i, j, 1/2*j + 1/2*k) sage: R.right_ideal(tuple(R.basis()), check=False, is_basis=True) Fractional ideal (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) @@ -2622,28 +2611,26 @@ def scale(self, alpha, left=False): - `\alpha` -- element of quaternion algebra - - ``left`` -- bool (default: ``False``); if true multiply + - ``left`` -- boolean (default: ``False``); if ``True`` multiply `\alpha` on the left, otherwise multiply `\alpha` on the right - OUTPUT: - - - a new fractional ideal + OUTPUT: a new fractional ideal EXAMPLES:: sage: B = BrandtModule(5,37); I = B.right_ideals()[0] sage: i,j,k = B.quaternion_algebra().gens(); I - Fractional ideal (2 + 2*j + 106*k, i + 2*j + 105*k, 4*j + 64*k, 148*k) + Fractional ideal (4, 148*i, 2 + 106*i + 2*j, 2 + 147*i + k) sage: I.scale(i) - Fractional ideal (2*i + 212*j - 2*k, -2 + 210*j - 2*k, 128*j - 4*k, 296*j) + Fractional ideal (296, 4*i, 2 + 2*i + 2*j, 212 + 2*i + 2*k) sage: I.scale(i, left=True) - Fractional ideal (2*i - 212*j + 2*k, -2 - 210*j + 2*k, -128*j + 4*k, -296*j) + Fractional ideal (296, 4*i, 294 + 2*i + 2*j, 84 + 2*i + 2*k) sage: I.scale(i, left=False) - Fractional ideal (2*i + 212*j - 2*k, -2 + 210*j - 2*k, 128*j - 4*k, 296*j) + Fractional ideal (296, 4*i, 2 + 2*i + 2*j, 212 + 2*i + 2*k) sage: i * I.gens()[0] - 2*i - 212*j + 2*k + 4*i sage: I.gens()[0] * i - 2*i + 212*j - 2*k + 4*i TESTS: @@ -2671,9 +2658,9 @@ def scale(self, alpha, left=False): Q = self.quaternion_algebra() alpha = Q(alpha) if left: - gens = [alpha * b for b in self.basis()] + gens = basis_for_quaternion_lattice([alpha * b for b in self.basis()]) else: - gens = [b * alpha for b in self.basis()] + gens = basis_for_quaternion_lattice([b * alpha for b in self.basis()]) left_order = self.__left_order if alpha in QQ or not left else None right_order = self.__right_order if alpha in QQ or left else None return Q.ideal(gens, check=False, @@ -2688,7 +2675,7 @@ def quaternion_algebra(self): EXAMPLES:: sage: I = BrandtModule(3, 5).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) + Fractional ideal (8, 40*i, 6 + 28*i + 2*j, 4 + 18*i + 2*k) sage: I.quaternion_algebra() Quaternion Algebra (-1, -3) with base ring Rational Field """ @@ -2701,11 +2688,9 @@ def _compute_order(self, side='left'): INPUT: - - ``side`` -- 'left' or 'right' + - ``side`` -- ``'left'`` or ``'right'`` - OUTPUT: - - The left order if side='left'; the right order if side='right'. + OUTPUT: the left order if ``side='left'``; the right order if ``side='right'`` EXAMPLES:: @@ -2798,7 +2783,7 @@ def right_order(self): EXAMPLES:: sage: I = BrandtModule(389).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 2*k, i + 2*j + k, 8*j, 8*k) + Fractional ideal (8, 8*i, 2 + 6*i + 2*j, 6 + 3*i + k) sage: I.right_order() Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis (1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k) @@ -2835,7 +2820,7 @@ def __repr__(self): sage: type(I) sage: I.__repr__() - 'Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 2*k, 8*j, 8*k)' + 'Fractional ideal (8, 8*i, 6 + 4*i + 2*j, 4 + 2*i + 2*k)' """ return 'Fractional ideal %s' % (self.gens(),) @@ -2939,12 +2924,12 @@ def __hash__(self): @cached_method def basis_matrix(self): r""" - Return basis matrix `M` in Hermite normal form for self as a + Return basis matrix `M` in Hermite normal form for ``self`` as a matrix with rational entries. If `Q` is the ambient quaternion algebra, then the `\ZZ`-span of the rows of `M` viewed as linear combinations of Q.basis() = - `[1,i,j,k]` is the fractional ideal self. Also, + `[1,i,j,k]` is the fractional ideal ``self``. Also, ``M * M.denominator()`` is an integer matrix in Hermite normal form. OUTPUT: matrix over `\QQ` @@ -2963,20 +2948,19 @@ def basis_matrix(self): def reduced_basis(self): r""" - Let `I` = ``self`` be a fractional ideal in a (rational) definite quaternion algebra. - This function returns an LLL reduced basis of I. + Let `I` = ``self`` be a fractional ideal in a (rational) definite + quaternion algebra. This function returns an LLL reduced basis of `I`. - OUTPUT: - - - A tuple of four elements in I forming an LLL reduced basis of I as a lattice + OUTPUT: a tuple of four elements in `I` forming an LLL reduced basis of + `I` as a lattice EXAMPLES:: sage: B = BrandtModule(2,37); I = B.right_ideals()[0] sage: I - Fractional ideal (2 + 2*i + 2*j + 2*k, 4*i + 108*k, 4*j + 44*k, 148*k) + Fractional ideal (4, 148*i, 108*i + 4*j, 2 + 2*i + 2*j + 2*k) sage: I.reduced_basis() - (2 + 2*i + 2*j + 2*k, 4, -2 - 2*i - 14*j + 14*k, -16*i + 12*k) + (4, 2 + 2*i + 2*j + 2*k, 2 - 14*i + 14*j - 2*k, 2 - 2*i - 14*j + 14*k) sage: l = I.reduced_basis() sage: assert all(l[i].reduced_norm() <= l[i+1].reduced_norm() for i in range(len(l) - 1)) @@ -2997,20 +2981,18 @@ def reduced_basis(self): def theta_series_vector(self, B): r""" Return theta series coefficients of ``self``, as a vector - of ``B`` integers. + of `B` integers. INPUT: - ``B`` -- positive integer - OUTPUT: - - Vector over `\ZZ` with ``B`` entries. + OUTPUT: vector over `\ZZ` with `B` entries EXAMPLES:: sage: I = BrandtModule(37).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 2*k, i + 2*j + k, 8*j, 8*k) + Fractional ideal (8, 8*i, 2 + 6*i + 2*j, 6 + 3*i + k) sage: I.theta_series_vector(5) (1, 0, 2, 2, 6) sage: I.theta_series_vector(10) @@ -3042,10 +3024,10 @@ def quadratic_form(self): sage: I = BrandtModule(11).right_ideals()[1] sage: Q = I.quadratic_form(); Q Quadratic form in 4 variables over Rational Field with coefficients: - [ 18 22 33 22 ] - [ * 7 22 11 ] - [ * * 22 0 ] - [ * * * 22 ] + [ 2 0 3 2 ] + [ * 2 2 1 ] + [ * * 3 2 ] + [ * * * 2 ] sage: Q.theta_series(10) 1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + 24*q^6 + 24*q^7 + 36*q^8 + 36*q^9 + O(q^10) sage: I.theta_series(10) @@ -3075,7 +3057,7 @@ def minimal_element(self): sage: O = Quat.maximal_order(); O Order of Quaternion Algebra (-3, -101) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k) sage: (O * 5).minimal_element() - 5/2 + 5/2*i + 5 sage: alpha = 1/2 + 1/6*i + j + 55/3*k sage: I = O*141 + O*alpha; I.norm() 141 @@ -3104,14 +3086,14 @@ def theta_series(self, B, var='q'): INPUT: - ``B`` -- positive integer - - ``var`` -- string (default: 'q') + - ``var`` -- string (default: ``'q'``) OUTPUT: power series EXAMPLES:: sage: I = BrandtModule(11).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 2*k, 8*j, 8*k) + Fractional ideal (8, 8*i, 6 + 4*i + 2*j, 4 + 2*i + 2*k) sage: I.norm() 32 sage: I.theta_series(5) @@ -3141,17 +3123,17 @@ def gram_matrix(self): r""" Return the Gram matrix of this fractional ideal. - OUTPUT: `4 \times 4` matrix over `\QQ`. + OUTPUT: `4 \times 4` matrix over `\QQ` EXAMPLES:: sage: I = BrandtModule(3,5).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) + Fractional ideal (8, 40*i, 6 + 28*i + 2*j, 4 + 18*i + 2*k) sage: I.gram_matrix() - [ 640 1920 2112 1920] - [ 1920 14080 13440 16320] - [ 2112 13440 13056 15360] - [ 1920 16320 15360 19200] + [ 256 0 192 128] + [ 0 6400 4480 2880] + [ 192 4480 3328 2112] + [ 128 2880 2112 1408] """ A = self.gens() two = QQ(2) @@ -3200,14 +3182,14 @@ def norm(self): def conjugate(self): """ - Return the ideal with generators the conjugates of the generators for self. + Return the ideal with generators the conjugates of the generators for ``self``. OUTPUT: a quaternionic fractional ideal EXAMPLES:: sage: I = BrandtModule(3,5).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) + Fractional ideal (8, 40*i, 6 + 28*i + 2*j, 4 + 18*i + 2*k) sage: I.conjugate() Fractional ideal (2 + 2*j + 28*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) """ @@ -3219,20 +3201,20 @@ def __mul__(self, right): """ Return the product of the fractional ideals ``self`` and ``right``. - .. note:: + .. NOTE:: We do not keep track of left or right order structure. EXAMPLES:: sage: I = BrandtModule(3,5).right_ideals()[1]; I - Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) + Fractional ideal (8, 40*i, 6 + 28*i + 2*j, 4 + 18*i + 2*k) sage: I*I - Fractional ideal (8 + 24*j + 16*k, 8*i + 16*j + 136*k, 32*j + 128*k, 160*k) + Fractional ideal (32, 160*i, 24 + 112*i + 8*j, 16 + 72*i + 8*k) sage: I*I.conjugate() - Fractional ideal (16 + 16*j + 224*k, 8*i + 16*j + 136*k, 32*j + 128*k, 320*k) + Fractional ideal (32, 320*i, 16 + 224*i + 16*j, 16 + 232*i + 8*k) sage: I.multiply_by_conjugate(I) - Fractional ideal (16 + 16*j + 224*k, 8*i + 16*j + 136*k, 32*j + 128*k, 320*k) + Fractional ideal (32, 320*i, 16 + 224*i + 16*j, 16 + 232*i + 8*k) """ if isinstance(right, QuaternionOrder): right = right.unit_ideal() @@ -3242,7 +3224,7 @@ def __mul__(self, right): # if self.__right_order == right.__left_order: # left_order = self.__left_order # right_order = right.__right_order - basis = tuple(basis_for_quaternion_lattice(gens, reverse=False)) + basis = tuple(basis_for_quaternion_lattice(gens)) A = self.quaternion_algebra() return A.ideal(basis, check=False) @@ -3253,9 +3235,9 @@ def __add__(self, other): EXAMPLES:: sage: I = BrandtModule(11,5).right_ideals()[1]; I - Fractional ideal (2 + 2*j + 20*k, 2*i + 4*j + 6*k, 8*j, 40*k) + Fractional ideal (8, 40*i, 2 + 20*i + 2*j, 4 + 14*i + 2*k) sage: J = BrandtModule(11,5).right_ideals()[2]; J - Fractional ideal (2 + 6*j + 20*k, 2*i + 4*j + 26*k, 8*j, 40*k) + Fractional ideal (8, 40*i, 6 + 20*i + 2*j, 4 + 34*i + 2*k) sage: I + J Fractional ideal (2 + 2*j, 2*i + 6*k, 4*j, 20*k) """ @@ -3290,15 +3272,13 @@ def free_module(self): r""" Return the underlying free `\ZZ`-module corresponding to this ideal. - OUTPUT: - - Free `\ZZ`-module of rank 4 embedded in an ambient `\QQ^4`. + OUTPUT: free `\ZZ`-module of rank 4 embedded in an ambient `\QQ^4` EXAMPLES:: sage: X = BrandtModule(3,5).right_ideals() sage: X[0] - Fractional ideal (2 + 2*j + 8*k, 2*i + 18*k, 4*j + 16*k, 20*k) + Fractional ideal (4, 20*i, 2 + 8*i + 2*j, 18*i + 2*k) sage: X[0].free_module() Free module of degree 4 and rank 4 over Integer Ring Echelon basis matrix: @@ -3350,14 +3330,13 @@ def free_module(self): def intersection(self, J): """ - Return the intersection of the ideals self and `J`. + Return the intersection of the ideals ``self`` and `J`. EXAMPLES:: sage: X = BrandtModule(3,5).right_ideals() sage: I = X[0].intersection(X[1]); I Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) - """ V = self.free_module().intersection(J.free_module()) H, d = V.basis_matrix()._clear_denom() @@ -3367,25 +3346,25 @@ def intersection(self, J): def multiply_by_conjugate(self, J): """ - Return product of self and the conjugate Jbar of `J`. + Return product of ``self`` and the conjugate Jbar of `J`. INPUT: - - ``J`` -- a quaternion ideal. + - ``J`` -- a quaternion ideal - OUTPUT: a quaternionic fractional ideal. + OUTPUT: a quaternionic fractional ideal EXAMPLES:: sage: R = BrandtModule(3,5).right_ideals() sage: R[0].multiply_by_conjugate(R[1]) - Fractional ideal (8 + 8*j + 112*k, 8*i + 16*j + 136*k, 32*j + 128*k, 160*k) + Fractional ideal (32, 160*i, 8 + 112*i + 8*j, 16 + 72*i + 8*k) sage: R[0]*R[1].conjugate() - Fractional ideal (8 + 8*j + 112*k, 8*i + 16*j + 136*k, 32*j + 128*k, 160*k) + Fractional ideal (32, 160*i, 8 + 112*i + 8*j, 16 + 72*i + 8*k) """ Jbar = [b.conjugate() for b in J.basis()] gens = [a * b for a in self.basis() for b in Jbar] - basis = tuple(basis_for_quaternion_lattice(gens, reverse=False)) + basis = tuple(basis_for_quaternion_lattice(gens)) R = self.quaternion_algebra() return R.ideal(basis, check=False) @@ -3400,7 +3379,7 @@ def pushforward(self, J, side=None): - ``J`` -- a fractional quaternion ideal with norm coprime to ``self`` and either the same left order or right order as ``self`` - - ``side`` -- string (default: ``None``) set to ``"left"`` or ``"right"`` to + - ``side`` -- string (default: ``None``); set to ``'left'`` or ``'right'`` to perform pushforward of left or right ideals respectively. If ``None`` the side is determined by the matching left or right orders @@ -3414,8 +3393,8 @@ def pushforward(self, J, side=None): sage: I2 = B.ideal([1/2 + 9/2*j, 1/2*i + 9/2*k, 5*j, 5*k]) sage: I1.left_order() == I2.left_order() True - sage: I1.pushforward(I2, side="left") - Fractional ideal (1/2 + 3/2*j + 5*k, 1/10*i + 2*j + 39/10*k, 3*j, 15*k) + sage: I1.pushforward(I2, side='left') + Fractional ideal (3, 15*i, 3/2 + 10*i + 1/2*j, 1 + 9/10*i + 1/10*k) TESTS:: @@ -3427,27 +3406,27 @@ def pushforward(self, J, side=None): ... ValueError: self and J have same left and right orders, side of pushforward must be specified sage: O0.unit_ideal().pushforward(O0.unit_ideal(), "left") - Fractional ideal (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) + Fractional ideal (1, i, 1/2 + 1/2*j, 1/2*i + 1/2*k) sage: I1 = B.ideal([1/2 + 3/2*j + 2*k, 1/2*i + j + 3/2*k, 3*j, 3*k]) sage: I2 = B.ideal([1/2 + 9/2*j, 1/2*i + 9/2*k, 5*j, 5*k]) sage: I1.pushforward(I2) - Fractional ideal (1/2 + 3/2*j + 5*k, 1/10*i + 2*j + 39/10*k, 3*j, 15*k) - sage: I1.pushforward(I2, side="right") + Fractional ideal (3, 15*i, 3/2 + 10*i + 1/2*j, 1 + 9/10*i + 1/10*k) + sage: I1.pushforward(I2, side='right') Traceback (most recent call last): ... ValueError: self and J must have the same right orders sage: I1.conjugate().pushforward(I2.conjugate()) Fractional ideal (1/2 + 3/2*j + 10*k, 1/10*i + 2*j + 39/10*k, 3*j, 15*k) - sage: I1.conjugate().pushforward(I2.conjugate(), side="left") + sage: I1.conjugate().pushforward(I2.conjugate(), side='left') Traceback (most recent call last): ... ValueError: self and J must have the same left orders - sage: I1.pushforward(I1, side="left") + sage: I1.pushforward(I1, side='left') Traceback (most recent call last): ... ValueError: self and J must have coprime norms sage: I3 = B.ideal([1/2 + 13/2*j + 6*k, 1/2*i + 3*j + 13/2*k, 9*j, 9*k]) - sage: I3.pushforward(I3*(1/3), side="left") + sage: I3.pushforward(I3*(1/3), side='left') Traceback (most recent call last): ... NotImplementedError: quaternion ideal pushforward not implemented for non-integral ideals @@ -3468,7 +3447,7 @@ def pushforward(self, J, side=None): if side == "right": if self.right_order() != J.right_order(): raise ValueError("self and J must have the same right orders") - return self.conjugate().pushforward(J.conjugate(), side="left").conjugate() + return self.conjugate().pushforward(J.conjugate(), side='left').conjugate() if side is None: same_left_order = bool(self.left_order() == J.left_order()) @@ -3478,8 +3457,8 @@ def pushforward(self, J, side=None): if same_left_order and same_right_order: raise ValueError("self and J have same left and right orders, side of pushforward must be specified") if same_left_order: - return self.pushforward(J, side="left") - return self.pushforward(J, side="right") + return self.pushforward(J, side='left') + return self.pushforward(J, side='right') raise ValueError('side must be "left", "right" or None') @@ -3494,7 +3473,7 @@ def pullback(self, J, side=None): - ``J`` -- a fractional quaternion ideal with norm coprime to ``self`` and either left order equal to the right order of ``self``, or vice versa - - ``side`` -- string (default: ``None``) set to ``"left"`` or ``"right"`` to + - ``side`` -- string (default: ``None``); set to ``'left'`` or ``'right'`` to perform pullback of left or right ideals respectively. If ``None`` the side is determined by the matching left and right orders @@ -3506,10 +3485,10 @@ def pullback(self, J, side=None): sage: i,j,k = B.gens() sage: I1 = B.ideal([1/2 + 3/2*j + 2*k, 1/2*i + j + 3/2*k, 3*j, 3*k]) sage: I2 = B.ideal([1/2 + 9/2*j, 1/2*i + 9/2*k, 5*j, 5*k]) - sage: I3 = I1.pushforward(I2, side="left") + sage: I3 = I1.pushforward(I2, side='left') sage: I3.left_order() == I2.right_order() True - sage: I3.pullback(I2, side="left") == I1 + sage: I3.pullback(I2, side='left') == I1 True TESTS:: @@ -3527,22 +3506,22 @@ def pullback(self, J, side=None): sage: I2 = B.ideal([1/2 + 15/2*j + 2*k, 1/6*i + 43/3*j + 5/2*k, 15*j, 5*k]) sage: I2.pullback(I1) Fractional ideal (1/2 + 5/2*j + 2*k, 1/2*i + 3*j + 5/2*k, 5*j, 5*k) - sage: I2.pullback(I1, side="right") + sage: I2.pullback(I1, side='right') Traceback (most recent call last): ... ValueError: right order of self should be left order of J - sage: I2.conjugate().pullback(I1.conjugate(), side="right") + sage: I2.conjugate().pullback(I1.conjugate(), side='right') Fractional ideal (1/2 + 5/2*j + 3*k, 1/2*i + 3*j + 5/2*k, 5*j, 5*k) - sage: I2.conjugate().pullback(I1.conjugate(), side="left") + sage: I2.conjugate().pullback(I1.conjugate(), side='left') Traceback (most recent call last): ... ValueError: left order of self should be right order of J - sage: I1.pullback(I1.conjugate(), side="left") + sage: I1.pullback(I1.conjugate(), side='left') Traceback (most recent call last): ... ValueError: self and J must have coprime norms sage: I3 = B.ideal([1/2 + 13/2*j + 6*k, 1/2*i + 3*j + 13/2*k, 9*j, 9*k]) - sage: I3.pullback(I3.conjugate()*(1/3), side="left") + sage: I3.pullback(I3.conjugate()*(1/3), side='left') Traceback (most recent call last): ... NotImplementedError: quaternion ideal pullback not implemented for non-integral ideals @@ -3563,7 +3542,7 @@ def pullback(self, J, side=None): if side == "right": if self.right_order() != J.left_order(): raise ValueError("right order of self should be left order of J") - return self.conjugate().pullback(J.conjugate(), side="left").conjugate() + return self.conjugate().pullback(J.conjugate(), side='left').conjugate() if side is None: is_side_left = bool(self.left_order() == J.right_order()) @@ -3573,14 +3552,14 @@ def pullback(self, J, side=None): if is_side_left and is_side_right: raise ValueError("self and J have same left and right orders, side of pullback must be specified") if is_side_left: - return self.pullback(J, side="left") - return self.pullback(J, side="right") + return self.pullback(J, side='left') + return self.pullback(J, side='right') raise ValueError('side must be "left", "right" or None') def is_equivalent(self, J, B=10, certificate=False, side=None): r""" - Checks whether ``self`` and ``J`` are equivalent as ideals. + Check whether ``self`` and ``J`` are equivalent as ideals. Tests equivalence as right ideals by default. Requires the underlying rational quaternion algebra to be definite. @@ -3594,10 +3573,10 @@ def is_equivalent(self, J, B=10, certificate=False, side=None): - ``certificate`` -- if ``True`` returns an element alpha such that alpha*J = I or J*alpha = I for right and left ideals respectively - - ``side`` -- If ``'left'`` performs left equivalence test. If ``'right' + - ``side`` -- if ``'left'`` performs left equivalence test. If ``'right' ``or ``None`` performs right ideal equivalence test - OUTPUT: bool, or (bool, alpha) if ``certificate`` is ``True`` + OUTPUT: boolean, or (boolean, alpha) if ``certificate`` is ``True`` EXAMPLES:: @@ -3622,7 +3601,7 @@ def is_equivalent(self, J, B=10, certificate=False, side=None): def is_left_equivalent(self, J, B=10, certificate=False): r""" - Checks whether ``self`` and ``J`` are equivalent as left ideals. + Check whether ``self`` and ``J`` are equivalent as left ideals. Requires the underlying rational quaternion algebra to be definite. INPUT: @@ -3634,7 +3613,7 @@ def is_left_equivalent(self, J, B=10, certificate=False): - ``certificate`` -- if ``True`` returns an element alpha such that J*alpha=I - OUTPUT: bool, or (bool, alpha) if ``certificate`` is ``True`` + OUTPUT: boolean, or (boolean, alpha) if ``certificate`` is ``True`` """ if certificate: is_equiv, cert = self.conjugate().is_right_equivalent(J.conjugate(), B, True) @@ -3645,7 +3624,7 @@ def is_left_equivalent(self, J, B=10, certificate=False): def is_right_equivalent(self, J, B=10, certificate=False): r""" - Checks whether ``self`` and ``J`` are equivalent as right ideals. + Check whether ``self`` and ``J`` are equivalent as right ideals. Requires the underlying rational quaternion algebra to be definite. INPUT: @@ -3657,7 +3636,7 @@ def is_right_equivalent(self, J, B=10, certificate=False): - ``certificate`` -- if ``True`` returns an element alpha such that alpha*J=I - OUTPUT: bool, or (bool, alpha) if ``certificate`` is ``True`` + OUTPUT: boolean, or (boolean, alpha) if ``certificate`` is ``True`` EXAMPLES:: @@ -3671,7 +3650,7 @@ def is_right_equivalent(self, J, B=10, certificate=False): sage: OO = R[0].left_order() sage: S = OO.right_ideal([3*a for a in R[0].basis()]) sage: R[0].is_right_equivalent(S, certificate=True) - (True, -1/3) + (True, 1/3) sage: -1/3*S == R[0] True @@ -3717,16 +3696,16 @@ def is_right_equivalent(self, J, B=10, certificate=False): def is_principal(self, certificate=False): r""" - Checks whether ``self`` is principal as a full rank quaternion ideal. + Check whether ``self`` is principal as a full rank quaternion ideal. Requires the underlying quaternion algebra to be definite. Independent of whether ``self`` is a left or a right ideal. INPUT: - - ``certificate`` -- if ``True`` returns a generator alpha s.t. I = alpha*O - where O is the right order of I. + - ``certificate`` -- if ``True`` returns a generator alpha s.t. + `I = \alpha O` where `O` is the right order of `I` - OUTPUT: bool, or (bool, alpha) if ``certificate`` is ``True`` + OUTPUT: boolean, or (boolean, alpha) if ``certificate`` is ``True`` EXAMPLES:: @@ -3756,7 +3735,7 @@ def is_principal(self, certificate=False): def __contains__(self, x): """ - Return whether x is in self. + Return whether ``x`` is in ``self``. EXAMPLES:: @@ -3793,56 +3772,54 @@ def cyclic_right_subideals(self, p, alpha=None): ideals `J`. More precisely the `J`'s are the right annihilators of `(1,0) \alpha^i` for `i=0,1,2,...,p` - OUTPUT: - - - list of right ideals + OUTPUT: list of right ideals .. NOTE:: Currently, `p` must satisfy a bunch of conditions, or a - :class:`NotImplementedError` is raised. In particular, `p` must + :exc:`NotImplementedError` is raised. In particular, `p` must be odd and unramified in the quaternion algebra, must be coprime to the index of the right order in the maximal - order, and also coprime to the normal of self. (The Brandt + order, and also coprime to the normal of ``self``. (The Brandt modules code has a more general algorithm in some cases.) EXAMPLES:: sage: B = BrandtModule(2,37); I = B.right_ideals()[0] sage: I.cyclic_right_subideals(3) - [Fractional ideal (2 + 2*i + 10*j + 90*k, 4*i + 4*j + 152*k, 12*j + 132*k, 444*k), - Fractional ideal (2 + 2*i + 2*j + 150*k, 4*i + 8*j + 196*k, 12*j + 132*k, 444*k), - Fractional ideal (2 + 2*i + 6*j + 194*k, 4*i + 8*j + 344*k, 12*j + 132*k, 444*k), - Fractional ideal (2 + 2*i + 6*j + 46*k, 4*i + 4*j + 4*k, 12*j + 132*k, 444*k)] + [Fractional ideal (12, 444*i, 8 + 404*i + 4*j, 2 + 150*i + 2*j + 2*k), + Fractional ideal (12, 444*i, 4 + 256*i + 4*j, 10 + 150*i + 2*j + 2*k), + Fractional ideal (12, 444*i, 8 + 256*i + 4*j, 6 + 298*i + 2*j + 2*k), + Fractional ideal (12, 444*i, 4 + 404*i + 4*j, 6 + 2*i + 2*j + 2*k)] sage: B = BrandtModule(5,389); I = B.right_ideals()[0] sage: C = I.cyclic_right_subideals(3); C - [Fractional ideal (2 + 10*j + 546*k, i + 6*j + 133*k, 12*j + 3456*k, 4668*k), - Fractional ideal (2 + 2*j + 2910*k, i + 6*j + 3245*k, 12*j + 3456*k, 4668*k), - Fractional ideal (2 + i + 2295*k, 3*i + 2*j + 3571*k, 4*j + 2708*k, 4668*k), - Fractional ideal (2 + 2*i + 2*j + 4388*k, 3*i + 2*j + 2015*k, 4*j + 4264*k, 4668*k)] + [Fractional ideal (12, 4668*i, 10 + 3426*i + 2*j, 6 + 379*i + k), + Fractional ideal (12, 4668*i, 2 + 3426*i + 2*j, 6 + 3491*i + k), + Fractional ideal (12, 4 + 1556*i, 6 + 942*i + 6*j, 693*i + 2*j + k), + Fractional ideal (12, 8 + 1556*i, 6 + 942*i + 6*j, 2 + 1007*i + 4*j + k)] sage: [(I.free_module()/J.free_module()).invariants() for J in C] [(3, 3), (3, 3), (3, 3), (3, 3)] sage: I.scale(3).cyclic_right_subideals(3) - [Fractional ideal (6 + 30*j + 1638*k, 3*i + 18*j + 399*k, 36*j + 10368*k, 14004*k), - Fractional ideal (6 + 6*j + 8730*k, 3*i + 18*j + 9735*k, 36*j + 10368*k, 14004*k), - Fractional ideal (6 + 3*i + 6885*k, 9*i + 6*j + 10713*k, 12*j + 8124*k, 14004*k), - Fractional ideal (6 + 6*i + 6*j + 13164*k, 9*i + 6*j + 6045*k, 12*j + 12792*k, 14004*k)] + [Fractional ideal (36, 14004*i, 30 + 10278*i + 6*j, 18 + 1137*i + 3*k), + Fractional ideal (36, 14004*i, 6 + 10278*i + 6*j, 18 + 10473*i + 3*k), + Fractional ideal (36, 12 + 4668*i, 18 + 2826*i + 18*j, 2079*i + 6*j + 3*k), + Fractional ideal (36, 24 + 4668*i, 18 + 2826*i + 18*j, 6 + 3021*i + 12*j + 3*k)] sage: C = I.scale(1/9).cyclic_right_subideals(3); C - [Fractional ideal (2/9 + 10/9*j + 182/3*k, 1/9*i + 2/3*j + 133/9*k, 4/3*j + 384*k, 1556/3*k), - Fractional ideal (2/9 + 2/9*j + 970/3*k, 1/9*i + 2/3*j + 3245/9*k, 4/3*j + 384*k, 1556/3*k), - Fractional ideal (2/9 + 1/9*i + 255*k, 1/3*i + 2/9*j + 3571/9*k, 4/9*j + 2708/9*k, 1556/3*k), - Fractional ideal (2/9 + 2/9*i + 2/9*j + 4388/9*k, 1/3*i + 2/9*j + 2015/9*k, 4/9*j + 4264/9*k, 1556/3*k)] + [Fractional ideal (4/3, 1556/3*i, 10/9 + 1142/3*i + 2/9*j, 2/3 + 379/9*i + 1/9*k), + Fractional ideal (4/3, 1556/3*i, 2/9 + 1142/3*i + 2/9*j, 2/3 + 3491/9*i + 1/9*k), + Fractional ideal (4/3, 4/9 + 1556/9*i, 2/3 + 314/3*i + 2/3*j, 77*i + 2/9*j + 1/9*k), + Fractional ideal (4/3, 8/9 + 1556/9*i, 2/3 + 314/3*i + 2/3*j, 2/9 + 1007/9*i + 4/9*j + 1/9*k)] sage: [(I.scale(1/9).free_module()/J.free_module()).invariants() for J in C] [(3, 3), (3, 3), (3, 3), (3, 3)] sage: Q. = QuaternionAlgebra(-2,-5) sage: I = Q.ideal([Q(1),i,j,k]) sage: I.cyclic_right_subideals(3) - [Fractional ideal (1 + 2*j, i + k, 3*j, 3*k), - Fractional ideal (1 + j, i + 2*k, 3*j, 3*k), - Fractional ideal (1 + 2*i, 3*i, j + 2*k, 3*k), - Fractional ideal (1 + i, 3*i, j + k, 3*k)] + [Fractional ideal (3, 3*i, 2 + j, i + k), + Fractional ideal (3, 3*i, 1 + j, 2*i + k), + Fractional ideal (3, 2 + i, 3*j, 2*j + k), + Fractional ideal (3, 1 + i, 3*j, j + k)] The general algorithm is not yet implemented here:: @@ -3854,17 +3831,18 @@ def cyclic_right_subideals(self, p, alpha=None): """ R = self.right_order() Q = self.quaternion_algebra() + basis = basis_for_quaternion_lattice(self.basis(), reverse=False) f = Q.modp_splitting_map(p) if alpha is not None: alpha = f(alpha) W = GF(p)**4 try: - A = W.span_of_basis([W(f(a).list()) for a in self.basis()]) + A = W.span_of_basis([W(f(a).list()) for a in basis]) scale = 1 - IB = self.basis_matrix() + IB = matrix(map(list, basis)) except (ValueError, ZeroDivisionError): # try rescaling the ideal. - B, d = self.basis_matrix()._clear_denom() + B, d = matrix(map(list, basis))._clear_denom() g = gcd(B.list()) IB = B / g scale = g / d @@ -3876,7 +3854,7 @@ def cyclic_right_subideals(self, p, alpha=None): # However, I haven't implemented that algorithm yet. raise NotImplementedError("general algorithm not implemented (%s)" % msg) - Ai = A.basis_matrix()**(-1) + Ai = ~A.basis_matrix() AiB = Ai.change_ring(QQ) * IB # Do not care about the denominator since we're really working in I/p*I. @@ -3939,7 +3917,6 @@ def is_integral(self) -> bool: sage: I = R.ideal([1/2 + 2*j + 140*k, 2*i + 4*j + 150*k, 8*j + 104*k, 152*k]) sage: I.is_integral() False - """ if self.__left_order is not None: return self.free_module() <= self.left_order().free_module() @@ -3968,7 +3945,7 @@ def primitive_decomposition(self): sage: Jequiv*g == J True sage: Jequiv, g - (Fractional ideal (1/2 + 1/2*i + 7/2*j + 13/2*k, i + 3*k, 5*j + 5*k, 10*k), 7) + (Fractional ideal (10, 5 + 5*i, 3 + j, 13/2 + 7/2*i + 1/2*j + 1/2*k), 7) TESTS: @@ -4020,7 +3997,6 @@ def is_primitive(self) -> bool: True sage: (2*I).is_primitive() False - """ _, g = self.primitive_decomposition() return g.is_one() @@ -4031,7 +4007,7 @@ def is_primitive(self) -> bool: ####################################################################### -def basis_for_quaternion_lattice(gens, reverse=None): +def basis_for_quaternion_lattice(gens, reverse=True): r""" Return a basis for the `\ZZ`-lattice in a quaternion algebra spanned by the given gens. @@ -4041,27 +4017,20 @@ def basis_for_quaternion_lattice(gens, reverse=None): - ``gens`` -- list of elements of a single quaternion algebra - ``reverse`` -- when computing the HNF do it on the basis - `(k,j,i,1)` instead of `(1,i,j,k)`; this ensures - that if ``gens`` are the generators for an order, - the first returned basis vector is 1 + `(k,j,i,1)` instead of `(1,i,j,k)`; this ensures that if + ``gens`` are the generators for a fractional ideal (in + particular, an order), the first returned basis vector + equals the norm of the ideal (in case of an order, `1`) EXAMPLES:: sage: from sage.algebras.quatalg.quaternion_algebra import basis_for_quaternion_lattice sage: A. = QuaternionAlgebra(-1,-7) sage: basis_for_quaternion_lattice([i+j, i-j, 2*k, A(1/3)]) - doctest:warning ... DeprecationWarning: ... - [1/3, i + j, 2*j, 2*k] - + [1/3, 2*i, i + j, 2*k] sage: basis_for_quaternion_lattice([A(1),i,j,k]) [1, i, j, k] - """ - if reverse is None: - from sage.misc.superseded import deprecation - deprecation(34880, 'The default value for the "reverse" argument to basis_for_quaternion_lattice() will' - ' change from False to True. Pass the argument explicitly to silence this warning.') - reverse = False if not gens: return [] Z, d = quaternion_algebra_cython.integral_matrix_and_denom_from_rational_quaternions(gens, reverse) @@ -4133,8 +4102,8 @@ def normalize_basis_at_p(e, p, B=QuaternionAlgebraElement_abstract.pair): INPUT: - - ``e`` -- list; basis of a `\ZZ` module. - WARNING: will be modified! + - ``e`` -- list; basis of a `\ZZ` module + (WARNING: will be modified!) - ``p`` -- prime for at which the basis should be normalized @@ -4273,9 +4242,7 @@ def maxord_solve_aux_eq(a, b, p): - ``p`` -- even prime ideal (actually only ``p=ZZ(2)`` is implemented) - OUTPUT: - - - A tuple `(y, z, w)` + OUTPUT: a tuple `(y, z, w)` EXAMPLES:: diff --git a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx index a0182d304ba..2b9b230242c 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx @@ -51,7 +51,7 @@ def integral_matrix_and_denom_from_rational_quaternions(v, reverse=False): INPUT: - - ``v`` -- a list of quaternions in a rational quaternion algebra + - ``v`` -- list of quaternions in a rational quaternion algebra - ``reverse`` -- whether order of the coordinates as well as the order of the list ``v`` should be reversed @@ -131,13 +131,11 @@ def rational_matrix_from_rational_quaternions(v, reverse=False): INPUT: - - ``v`` -- a list of quaternions in a rational quaternion algebra + - ``v`` -- list of quaternions in a rational quaternion algebra - ``reverse`` -- whether order of the coordinates as well as the order of the list ``v`` should be reversed - OUTPUT: - - - a matrix over `\QQ` + OUTPUT: a matrix over `\QQ` EXAMPLES:: diff --git a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx index d17566c8c22..c7faef1a27f 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx @@ -144,8 +144,8 @@ cdef to_quaternion(R, x): INPUT: - - R -- callable - - x -- element or 4-tuple + - ``R`` -- callable + - ``x`` -- element or 4-tuple Given a callable R and an x that defines a quaternion, which can be a 4-tuple, list of length 4, or something that coerces to R, return @@ -168,9 +168,9 @@ cdef inline print_coeff(y, i, bint atomic): INPUT: - - y -- coefficient - - i -- string (name of a generator) - - atomic -- boolean int; whether or not elements of base ring + - ``y`` -- coefficient + - ``i`` -- string (name of a generator) + - ``atomic`` -- boolean int; whether or not elements of base ring print atomically EXAMPLES:: @@ -222,11 +222,10 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): cpdef bint is_constant(self) noexcept: """ - Return True if this quaternion is constant, i.e., has no i, j, or k term. + Return ``True`` if this quaternion is constant, i.e., has no `i`, `j`, + or `k` term. - OUTPUT: - - bool + OUTPUT: boolean EXAMPLES:: @@ -541,7 +540,7 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): cpdef _div_(self, right): """ - Return quotient of self by right. + Return quotient of ``self`` by ``right``. EXAMPLES:: @@ -564,7 +563,8 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): INPUT: - - var -- string (default: 'x'); indeterminate of characteristic polynomial + - ``var`` -- string (default: ``'x'``); indeterminate of characteristic + polynomial EXAMPLES:: @@ -585,19 +585,17 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): def matrix(self, action='right'): """ - Return the matrix of right or left multiplication of self on + Return the matrix of right or left multiplication of ``self`` on the basis for the ambient quaternion algebra. - In particular, if action is 'right' (the default), returns the - matrix of the mapping sending x to x*self. + In particular, if action is ``'right'`` (the default), returns the + matrix of the mapping sending ``x`` to ``x*self``. INPUT: - - ``action`` -- (default: 'right') 'right' or 'left'. - - OUTPUT: + - ``action`` -- (default: ``'right'``) ``'right'`` or ``'left'`` - - a matrix + OUTPUT: a matrix EXAMPLES:: @@ -661,9 +659,9 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): def pair(self, right): """ - Return the result of pairing self and right, which should both + Return the result of pairing ``self`` and ``right``, which should both be elements of a quaternion algebra. The pairing is - (x,y) = (x.conjugate()*y).reduced_trace(). + ``(x,y) = (x.conjugate()*y).reduced_trace()``. INPUT: @@ -796,7 +794,7 @@ cdef class QuaternionAlgebraElement_generic(QuaternionAlgebraElement_abstract): cpdef _add_(self, _right): """ - Return the sum of self and _right. + Return the sum of ``self`` and ``_right``. EXAMPLES:: @@ -812,7 +810,7 @@ cdef class QuaternionAlgebraElement_generic(QuaternionAlgebraElement_abstract): cpdef _sub_(self, _right): """ - Return the difference of self and _right. + Return the difference of ``self`` and ``_right``. EXAMPLES:: @@ -827,7 +825,7 @@ cdef class QuaternionAlgebraElement_generic(QuaternionAlgebraElement_abstract): cpdef _mul_(self, _right): """ - Return the product of self and _right. + Return the product of ``self`` and ``_right``. EXAMPLES:: @@ -955,11 +953,10 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst cpdef bint is_constant(self) noexcept: """ - Return True if this quaternion is constant, i.e., has no i, j, or k term. + Return ``True`` if this quaternion is constant, i.e., has no `i`, `j`, + or `k` term. - OUTPUT: - - bool + OUTPUT: boolean EXAMPLES:: @@ -977,7 +974,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst def __bool__(self): """ - Return True if this quaternion is nonzero. + Return ``True`` if this quaternion is nonzero. EXAMPLES:: @@ -1145,7 +1142,6 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst sage: loads(dumps(theta)) == theta True - """ return (unpickle_QuaternionAlgebraElement_rational_field_v0, (self._parent, (self[0], self[1], self[2], self[3]))) @@ -1436,7 +1432,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst """ Return the reduced trace of ``self``. - This is `2x` if self is `x+iy+zj+wk`. + This is `2x` if ``self`` is `x+iy+zj+wk`. EXAMPLES:: @@ -1523,9 +1519,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst is equal to `(x + yi + zj + wk)/d` and x, y, z, w do not share a common factor with d. - OUTPUT: - - 5-tuple of Integers + OUTPUT: 5-tuple of Integers EXAMPLES:: @@ -1551,9 +1545,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst """ Return the integer part of this quaternion, ignoring the common denominator. - OUTPUT: - - 4-tuple of Integers + OUTPUT: 4-tuple of Integers EXAMPLES:: @@ -1606,7 +1598,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst def _multiply_by_integer(self, Integer n): """ - Return the product of self times the integer n. + Return the product of ``self`` times the integer `n`. EXAMPLES:: @@ -1643,7 +1635,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst def _divide_by_integer(self, Integer n): """ - Return the quotient of self by the integer n. + Return the quotient of ``self`` by the integer `n`. EXAMPLES:: @@ -1814,7 +1806,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra cpdef _add_(self, _right): """ - Add self and _right: + Add ``self`` and ``_right``: EXAMPLES:: @@ -1888,7 +1880,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra cpdef _sub_(self, _right): """ - Subtract _right from self. + Subtract ``_right`` from ``self``. EXAMPLES:: @@ -1939,7 +1931,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra cpdef _mul_(self, _right): """ - Multiply self and _right. + Multiply ``self`` and ``_right``. EXAMPLES:: diff --git a/src/sage/algebras/quaternion_algebra.py b/src/sage/algebras/quaternion_algebra.py index 4e92b73de69..a9fd6aff827 100644 --- a/src/sage/algebras/quaternion_algebra.py +++ b/src/sage/algebras/quaternion_algebra.py @@ -6,7 +6,7 @@ def unpickle_QuaternionAlgebra_v0(*key): """ - The 0th version of pickling for quaternion algebras. + The `0`-th version of pickling for quaternion algebras. EXAMPLES:: diff --git a/src/sage/algebras/rational_cherednik_algebra.py b/src/sage/algebras/rational_cherednik_algebra.py index 58b3ce5441d..1ded26a1112 100644 --- a/src/sage/algebras/rational_cherednik_algebra.py +++ b/src/sage/algebras/rational_cherednik_algebra.py @@ -245,19 +245,19 @@ def algebra_generators(self): def gen_map(k): if k[0] == 's': i = int(k[1:]) - return self.monomial( (self._hd.one(), + return self.monomial((self._hd.one(), self._weyl.group_generators()[i], - self._h.one()) ) + self._h.one())) if k[1] == 'c': i = int(k[2:]) - return self.monomial( (self._hd.one(), + return self.monomial((self._hd.one(), self._weyl.one(), - self._h.monoid_generators()[i]) ) + self._h.monoid_generators()[i])) i = int(k[1:]) - return self.monomial( (self._hd.monoid_generators()[i], + return self.monomial((self._hd.monoid_generators()[i], self._weyl.one(), - self._h.one()) ) + self._h.one())) return Family(keys, gen_map) @cached_method @@ -328,11 +328,11 @@ def product_on_basis(self, left, right): def commute_w_hd(w, al): # al is given as a dictionary ret = P.one() for k in al: - x = sum(c * gens_dict[i] for i,c in alpha[k].weyl_action(w)) + x = sum(c * gens_dict[i] for i, c in alpha[k].weyl_action(w)) ret *= x**al[k] - ret = ret.dict() + ret = ret.monomial_coefficients() for k in ret: - yield (self._hd({I[i]: e for i,e in enumerate(k) if e != 0}), ret[k]) + yield (self._hd({I[i]: e for i, e in enumerate(k) if e != 0}), ret[k]) # Do Lac Ra if they are both non-trivial if dl and dr: @@ -351,16 +351,16 @@ def commute_w_hd(w, al): # al is given as a dictionary del dr[ir] # We now commute right roots past the left reflections: s Ra = Ra' s - cur = self._from_dict({ (hd, s*right[1], right[2]): c * cc + cur = self._from_dict({(hd, s*right[1], right[2]): c * cc for s,c in terms - for hd, cc in commute_w_hd(s, dr) }) - cur = self.monomial( (left[0], left[1], self._h(dl)) ) * cur + for hd, cc in commute_w_hd(s, dr)}) + cur = self.monomial((left[0], left[1], self._h(dl))) * cur # Add back in the commuted h and hd elements - rem = self.monomial( (left[0], left[1], self._h(dl)) ) - rem = rem * self.monomial( (self._hd({ir:1}), self._weyl.one(), - self._h({il:1})) ) - rem = rem * self.monomial( (self._hd(dr), right[1], right[2]) ) + rem = self.monomial((left[0], left[1], self._h(dl))) + rem = rem * self.monomial((self._hd({ir:1}), self._weyl.one(), + self._h({il:1}))) + rem = rem * self.monomial((self._hd(dr), right[1], right[2])) return cur + rem @@ -374,19 +374,19 @@ def commute_w_hd(w, al): # al is given as a dictionary for i,c in alphacheck[k].weyl_action(right[1].reduced_word(), inverse=True)) ret *= x**dl[k] - ret = ret.dict() + ret = ret.monomial_coefficients() w = left[1]*right[1] - return self._from_dict({ (left[0], w, + return self._from_dict({(left[0], w, self._h({I[i]: e for i,e in enumerate(k) if e != 0}) * right[2] ): ret[k] - for k in ret }) + for k in ret}) # Otherwise dr is non-trivial and we have La Ls Ra Rs Rac, # so we must commute Ls Ra = Ra' Ls w = left[1]*right[1] - return self._from_dict({ (left[0] * hd, w, right[2]): c - for hd, c in commute_w_hd(left[1], dr) }) + return self._from_dict({(left[0] * hd, w, right[2]): c + for hd, c in commute_w_hd(left[1], dr)}) @cached_method def _product_coroot_root(self, i, j): @@ -429,12 +429,12 @@ def _product_coroot_root(self, i, j): al = Q.simple_root(j) R = self.base_ring() - terms = [( self._weyl.one(), self._t * R(ac.scalar(al)) )] + terms = [(self._weyl.one(), self._t * R(ac.scalar(al)))] for s in self._reflections: # p[0] is the root, p[1] is the coroot, p[2] the value c_s pr, pc, c = self._reflections[s] - terms.append(( s, c * R(ac.scalar(pr) * pc.scalar(al) - / pc.scalar(pr)) )) + terms.append((s, c * R(ac.scalar(pr) * pc.scalar(al) + / pc.scalar(pr)))) return tuple(terms) def degree_on_basis(self, m): diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index 6e0b6ad8583..b967064e565 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -155,9 +155,7 @@ def schur_representative_from_index(i0, i1): - A pair of tuples of length `r` with elements in `\{1,\dots,n\}` - OUTPUT: - - - The corresponding pair of tuples ordered correctly. + OUTPUT: the corresponding pair of tuples ordered correctly EXAMPLES:: @@ -182,7 +180,7 @@ class SchurAlgebra(CombinatorialFreeModule): A Schur algebra. Let `R` be a commutative ring, `n` be a positive integer, and `r` - be a non-negative integer. Define `A_R(n,r)` to be the set of + be a nonnegative integer. Define `A_R(n,r)` to be the set of homogeneous polynomials of degree `r` in `n^2` variables `x_{ij}`. Therefore we can write `R[x_{ij}] = \bigoplus_{r \geq 0} A_R(n,r)`, and `R[x_{ij}]` is known to be a bialgebra with coproduct given by @@ -225,7 +223,7 @@ def __init__(self, R, n, r): sage: SchurAlgebra(ZZ, 2, -2) Traceback (most recent call last): ... - ValueError: r (=-2) must be a non-negative integer + ValueError: r (=-2) must be a nonnegative integer sage: SchurAlgebra('niet', 2, 2) Traceback (most recent call last): ... @@ -234,7 +232,7 @@ def __init__(self, R, n, r): if n not in ZZ or n <= 0: raise ValueError("n (={}) must be a positive integer".format(n)) if r not in ZZ or r < 0: - raise ValueError("r (={}) must be a non-negative integer".format(r)) + raise ValueError("r (={}) must be a nonnegative integer".format(r)) if R not in Rings.Commutative(): raise ValueError("R (={}) must be a commutative ring".format(R)) @@ -543,13 +541,11 @@ def GL_irreducible_character(n, mu, KK): INPUT: - - ``n`` -- a positive integer - - ``mu`` -- a partition of at most ``n`` parts + - ``n`` -- positive integer + - ``mu`` -- a partition of at most `n` parts - ``KK`` -- a field - OUTPUT: - - a symmetric function which should be interpreted in ``n`` + OUTPUT: a symmetric function which should be interpreted in `n` variables to be meaningful as a character EXAMPLES: diff --git a/src/sage/algebras/shuffle_algebra.py b/src/sage/algebras/shuffle_algebra.py index 2db55513d66..adee056035c 100644 --- a/src/sage/algebras/shuffle_algebra.py +++ b/src/sage/algebras/shuffle_algebra.py @@ -171,7 +171,7 @@ def __init__(self, R, names, prefix): self.__ngens = self._alphabet.cardinality() cat = GradedHopfAlgebrasWithBasis(R).Commutative().Connected() CombinatorialFreeModule.__init__(self, R, Words(names, infinite=False), - latex_prefix="", prefix=prefix, + latex_prefix='', prefix=prefix, category=cat) def variable_names(self): @@ -241,7 +241,7 @@ def product_on_basis(self, w1, w2): INPUT: - - ``w1``, ``w2`` -- Basis elements + - ``w1``, ``w2`` -- basis elements EXAMPLES:: @@ -285,7 +285,7 @@ def gen(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 1ba73baf9cb..43d72ed7470 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -102,7 +102,7 @@ def is_unit(self): return super().is_unit() - def dict(self): + def monomial_coefficients(self): r""" Return the dictionary of ``self`` according to its lift to the cover. @@ -110,11 +110,18 @@ def dict(self): sage: from sage.algebras.splitting_algebra import SplittingAlgebra sage: CR3. = SplittingAlgebra(cyclotomic_polynomial(3)) - sage: (e3 + 42).dict() + sage: f = e3 + 42 + sage: f.monomial_coefficients() + {0: 42, 1: 1} + + ``dict`` is an alias:: + + sage: f.dict() {0: 42, 1: 1} """ - return self.lift().dict() + return self.lift().monomial_coefficients() + dict = monomial_coefficients # ------------------------------------------------------------------------------------------------------------------ # Parent class of the splitting algebra @@ -138,11 +145,11 @@ class SplittingAlgebra(PolynomialQuotientRing_domain): INPUT: - ``monic_polynomial`` -- the monic polynomial which should be split - - ``names`` -- names for the indeterminates to be adjoined to the + - ``names`` -- names for the indeterminates to be adjoined to the base ring of ``monic_polynomial`` - - ``warning`` -- (default: ``True``) can be used (by setting to ``False``) - to suppress a warning which will be thrown whenever it cannot be - checked that the Galois group of ``monic_polynomial`` is maximal + - ``warning`` -- boolean (default: ``True``); can be used (by setting to + ``False``) to suppress a warning which will be thrown whenever it cannot + be checked that the Galois group of ``monic_polynomial`` is maximal EXAMPLES:: @@ -282,7 +289,7 @@ def __init__(self, monic_polynomial, names='X', iterate=True, warning=True): root_names_reduces.remove(root_name) P = base_ring_step[root_names_reduces[0]] - p = P(monic_polynomial.dict()) + p = P(monic_polynomial.monomial_coefficients()) q, _ = p.quo_rem(P.gen() - first_root) verbose("Invoking recursion with: %s" % (q,)) @@ -349,10 +356,10 @@ def __init__(self, monic_polynomial, names='X', iterate=True, warning=True): if not check.is_zero(): continue root_inv = self.one() - for pos in range(deg_cf-1 ): - root_inv = (-1 )**(pos+1 ) * cf[deg_cf-pos-1 ] - root_inv * root + for pos in range(deg_cf-1): + root_inv = (-1)**(pos+1) * cf[deg_cf-pos-1] - root_inv * root verbose("inverse %s of root %s" % (root_inv, root)) - root_inv = (-1 )**(deg_cf) * cf0_inv * root_inv + root_inv = (-1)**(deg_cf) * cf0_inv * root_inv self._invertible_elements.update({root:root_inv}) verbose("adding inverse %s of root %s" % (root_inv, root)) invert_items = list(self._invertible_elements.items()) @@ -524,7 +531,8 @@ def hom(self, im_gens, codomain=None, check=True, base_map=None): def is_completely_split(self): r""" - Return True if the defining polynomial of ``self`` splits into linear factors over ``self``. + Return ``True`` if the defining polynomial of ``self`` splits into + linear factors over ``self``. EXAMPLES:: @@ -576,7 +584,7 @@ def splitting_roots(self): @cached_method def scalar_base_ring(self): r""" - Return the ring of scalars of ``self`` (considered as an algebra) + Return the ring of scalars of ``self`` (considered as an algebra). EXAMPLES:: @@ -637,16 +645,16 @@ def solve_with_extension(monic_polynomial, root_names=None, var='x', flatten=Fal INPUT: - ``monic_polynomial`` -- the monic polynomial whose roots should be created - - ``root_names`` -- names for the indeterminates needed to define the + - ``root_names`` -- names for the indeterminates needed to define the splitting algebra of the ``monic_polynomial`` (if necessary and possible) - - ``var`` -- (default: ``'x'``) for the indeterminate needed to define the + - ``var`` -- (default: ``'x'``) for the indeterminate needed to define the splitting field of the ``monic_polynomial`` (if necessary and possible) - - ``flatten`` -- (default: ``True``) if ``True`` the roots will not be - given as a list of pairs ``(root, multiplicity)`` but as a list of + - ``flatten`` -- boolean (default: ``True``); if ``True`` the roots will + not be given as a list of pairs ``(root, multiplicity)`` but as a list of roots repeated according to their multiplicity - - ``warning`` -- (default: ``True``) can be used (by setting to ``False``) - to suppress a warning which will be thrown whenever it cannot be checked - that the Galois group of ``monic_polynomial`` is maximal + - ``warning`` -- boolean (default: ``True``); can be used (by setting to + ``False``) to suppress a warning which will be thrown whenever it cannot + be checked that the Galois group of ``monic_polynomial`` is maximal OUTPUT: @@ -682,9 +690,10 @@ def create_roots(monic_polynomial, warning=True): - ``monic_polynomial`` -- the monic polynomial whose roots should be created - - ``warning`` -- (default: ``True``) can be used (by setting to ``False``) - to suppress a warning which will be thrown whenever it cannot be - checked that the Galois group of ``monic_polynomial`` is maximal + - ``warning`` -- boolean (default: ``True``); can be used (by setting + to ``False``) to suppress a warning which will be thrown whenever it + cannot be checked that the Galois group of ``monic_polynomial`` is + maximal """ parent = monic_polynomial.parent() base_ring = parent.base_ring() diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index f559e9380bc..7e4c3dc014f 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -23,7 +23,7 @@ `\mathbf{F}_p`-algebra; when `p=2`, it is generated by elements `\text{Sq}^i` for `i\geq 0` (the *Steenrod squares*), and when `p` is odd, it is generated by elements `\mathcal{P}^i` for `i \geq 0` (the -*Steenrod reduced pth powers*) along with an element `\beta` (the *mod +*Steenrod reduced `p`-th powers*) along with an element `\beta` (the *mod p Bockstein*). The Steenrod algebra is graded: `\text{Sq}^i` is in degree `i` for each `i`, `\beta` is in degree 1, and `\mathcal{P}^i` is in degree `2(p-1)i`. @@ -55,10 +55,10 @@ - The *Milnor basis*. When `p=2`, the Milnor basis consists of symbols of the form `\text{Sq}(m_1, m_2, ..., m_t)`, where each `m_i` is a - non-negative integer and if `t>1`, then the last entry `m_t > 0`. + nonnegative integer and if `t>1`, then the last entry `m_t > 0`. When `p` is odd, the Milnor basis consists of symbols of the form `Q_{e_1} Q_{e_2} ... \mathcal{P}(m_1, m_2, ..., m_t)`, where `0 \leq - e_1 < e_2 < ...`, each `m_i` is a non-negative integer, and if + e_1 < e_2 < ...`, each `m_i` is a nonnegative integer, and if `t>1`, then the last entry `m_t > 0`. When `p=2`, it can be convenient to use the notation @@ -78,12 +78,12 @@ exceptions are the `P^s_t`-bases and the commutator bases, which are defined at all primes. -- *Wood's Y basis*. For pairs of non-negative integers `(m,k)`, let +- *Wood's Y basis*. For pairs of nonnegative integers `(m,k)`, let `w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}`. Wood's `Y` basis consists of monomials `w(m_0,k_0) ... w(m_t, k_t)` with `(m_i,k_i) > (m_{i+1},k_{i+1})`, in left lex order. -- *Wood's Z basis*. For pairs of non-negative integers `(m,k)`, let +- *Wood's Z basis*. For pairs of nonnegative integers `(m,k)`, let `w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}`. Wood's `Z` basis consists of monomials `w(m_0,k_0) ... w(m_t, k_t)` with `(m_i+k_i,m_i) > (m_{i+1}+k_{i+1},m_{i+1})`, in left lex order. @@ -184,8 +184,8 @@ A_* /(\xi_1^{2^{e_1}}, \xi_2^{2^{e_2}}, \xi_3^{2^{e_3}}, ...). The list of exponents `(e_1, e_2, ...)` may be considered a function -`e` from the positive integers to the extended non-negative integers -(the non-negative integers and `\infty`); this is called the *profile +`e` from the positive integers to the extended nonnegative integers +(the nonnegative integers and `\infty`); this is called the *profile function* for the sub-Hopf algebra. The profile function must satisfy the condition @@ -205,7 +205,7 @@ A_* / (\xi_1^{p^{e_1}}, \xi_2^{p^{e_2}}, ...; \tau_0^{k_0}, \tau_1^{k_1}, ...). Here the profile function has two pieces, `e` as at the prime 2, and -`k`, which maps the non-negative integers to the set `\{1, 2\}`. +`k`, which maps the nonnegative integers to the set `\{1, 2\}`. These must satisfy the following conditions: - `e(r) \geq \min( e(r-i) - i, e(i))` for all `0 < i < r`. @@ -232,7 +232,7 @@ Sq(1,2) + Sq(4,1) sage: Sq(4) * Sq(1,2) Sq(1,1,1) + Sq(2,3) + Sq(5,2) - sage: z**2 # non-negative exponents work as they should + sage: z**2 # nonnegative exponents work as they should Sq(1,2,1) + Sq(4,1,1) sage: z**0 1 @@ -680,7 +680,7 @@ def _basis_key_iterator(self): def prime(self): r""" - The prime associated to self. + The prime associated to ``self``. EXAMPLES:: @@ -693,7 +693,7 @@ def prime(self): def basis_name(self): r""" - The basis name associated to self. + The basis name associated to ``self``. EXAMPLES:: @@ -708,7 +708,7 @@ def basis_name(self): def _has_nontrivial_profile(self): r""" - True if the profile function for this algebra seems to be that + Return ``True`` if the profile function for this algebra seems to be that for a proper sub-Hopf algebra of the Steenrod algebra. EXAMPLES:: @@ -818,7 +818,7 @@ def _repr_term(self, t): INPUT: - - ``t`` -- tuple, representing basis element in the current basis. + - ``t`` -- tuple, representing basis element in the current basis OUTPUT: string @@ -909,7 +909,7 @@ def _latex_term(self, t): INPUT: - - ``t`` -- tuple, representing basis element in the current basis. + - ``t`` -- tuple, representing basis element in the current basis OUTPUT: string @@ -957,8 +957,8 @@ def profile(self, i, component=0): INPUT: - - `i` -- integer - - ``component`` -- either 0 or 1, optional (default 0) + - ``i`` -- integer + - ``component`` -- either 0 or 1 (default: 0) OUTPUT: integer or `\infty` @@ -972,7 +972,7 @@ def profile(self, i, component=0): of the aforementioned documentation), corresponding, respectively to ``component=0`` and ``component=1``. So when `p` is odd and ``component`` is 0, `i` must be positive, while - when ``component`` is 1, `i` must be non-negative. + when ``component`` is 1, `i` must be nonnegative. EXAMPLES:: @@ -1034,15 +1034,13 @@ def profile(self, i, component=0): def homogeneous_component(self, n): """ - Return the nth homogeneous piece of the Steenrod algebra. + Return the `n`-th homogeneous piece of the Steenrod algebra. INPUT: - - `n` -- integer + - ``n`` -- integer - OUTPUT: - - a vector space spanned by the basis for this algebra in dimension `n` + OUTPUT: a vector space spanned by the basis for this algebra in dimension `n` EXAMPLES:: @@ -1127,7 +1125,7 @@ def one_basis(self): def product_on_basis(self, t1, t2): """ - The product of two basis elements of this algebra + The product of two basis elements of this algebra. INPUT: @@ -1230,7 +1228,7 @@ def product_on_basis(self, t1, t2): def coproduct_on_basis(self, t, algorithm=None): r""" - The coproduct of a basis element of this algebra + The coproduct of a basis element of this algebra. INPUT: @@ -1279,7 +1277,7 @@ def coproduct_on_basis(self, t, algorithm=None): """ def coprod_list(t): """ - if t = (n0, n1, ...), then return list of terms (i0, i1, + If t = (n0, n1, ...), then return list of terms (i0, i1, ...) where ik <= nk for each k. From each such term, can recover the second factor in the coproduct. """ @@ -1437,7 +1435,7 @@ def coprod(x): def antipode_on_basis(self, t): r""" - The antipode of a basis element of this algebra + The antipode of a basis element of this algebra. INPUT: @@ -1565,7 +1563,7 @@ def _milnor_on_basis(self, t): INPUT: - - ``t`` -- tuple, representing basis element in the current basis. + - ``t`` -- tuple, representing basis element in the current basis OUTPUT: element of the Steenrod algebra with the Milnor basis @@ -1718,11 +1716,11 @@ def _milnor_on_basis(self, t): @lazy_attribute def milnor(self): """ - Convert an element of this algebra to the Milnor basis + Convert an element of this algebra to the Milnor basis. INPUT: - - x -- an element of this algebra + - ``x`` -- an element of this algebra OUTPUT: x converted to the Milnor basis @@ -1744,12 +1742,12 @@ def _change_basis_on_basis(self, t, basis='milnor'): INPUT: - - ``t`` -- tuple, representing basis element in the current basis. + - ``t`` -- tuple, representing basis element in the current basis - ``basis`` -- string, the basis to which to convert, optional - (default 'milnor') + (default: ``'milnor'``) - OUTPUT: an element of the Steenrod algebra with basis ``basis``. + OUTPUT: an element of the Steenrod algebra with basis ``basis`` ALGORITHM: it's straightforward to convert to the Milnor basis (using :meth:`milnor` or :meth:`_milnor_on_basis`), so it's @@ -1822,16 +1820,16 @@ def _change_basis_on_basis(self, t, basis='milnor'): def _change_basis(self, x, basis='milnor'): """ - Convert an element of this algebra to the specified basis + Convert an element of this algebra to the specified basis. INPUT: - - ``x`` -- an element of this algebra. + - ``x`` -- an element of this algebra - ``basis`` -- string, the basis to which to convert, optional - (default 'milnor') + (default: ``'milnor'``) - OUTPUT: an element of the Steenrod algebra with basis ``basis``. + OUTPUT: an element of the Steenrod algebra with basis ``basis`` ALGORITHM: use :meth:`_change_basis_on_basis` and linearity @@ -1862,9 +1860,9 @@ def degree_on_basis(self, t): INPUT: - - ``t`` -- tuple, representing basis element in the current basis. + - ``t`` -- tuple, representing basis element in the current basis - OUTPUT: integer, the degree of the corresponding element. + OUTPUT: integer, the degree of the corresponding element The degree of `\text{Sq}(i_1,i_2,i_3,...)` is @@ -1993,11 +1991,12 @@ def q_degree(m, prime=3): def _coerce_map_from_(self, S): r""" - True if there is a coercion from ``S`` to ``self``, False otherwise. + Return ``True`` if there is a coercion from ``S`` to ``self``, ``False`` + otherwise. INPUT: - - ``S`` -- a Sage object. + - ``S`` -- a Sage object The algebras that coerce into the mod p Steenrod algebra are: @@ -2090,7 +2089,7 @@ def _element_constructor_(self, x): - ``x`` -- an element of some Steenrod algebra or an element of `\ZZ` or `\GF{p}` or a dict - OUTPUT: ``x`` as a member of ``self``. + OUTPUT: ``x`` as a member of ``self`` If ``x`` is a dict, then call :meth:`_from_dict` on it, coercing the coefficients into the base field. That is, treat @@ -2136,7 +2135,7 @@ def _element_constructor_(self, x): def __contains__(self, x): r""" - True if self contains x. + Return ``True`` if ``self`` contains `x`. EXAMPLES:: @@ -2192,7 +2191,7 @@ def basis(self, d=None): INPUT: - - `d` -- integer or ``None``, optional (default ``None``) + - ``d`` -- integer or ``None`` (default: ``None``) OUTPUT: @@ -2263,12 +2262,12 @@ def basis(self, d=None): def _check_profile_on_basis(self, t): """ - True if the element specified by the tuple ``t`` is in this + Return ``True`` if the element specified by the tuple ``t`` is in this algebra. INPUT: - - ``t`` -- tuple of ... + - ``t`` -- tuple EXAMPLES:: @@ -2310,11 +2309,11 @@ def _check_profile_on_basis(self, t): def P(self, *nums): r""" - The element `P(a, b, c, ...)` + The element `P(a, b, c, \ldots)`. INPUT: - - ``a``, ``b``, ``c``, ... -- non-negative integers + - ``a``, ``b``, ``c``, ... -- nonnegative integers OUTPUT: @@ -2335,7 +2334,7 @@ def P(self, *nums): sage: B.P(1,1,-12,1) Traceback (most recent call last): ... - TypeError: entries must be non-negative integers + TypeError: entries must be nonnegative integers sage: SteenrodAlgebra(basis='serre-cartan').P(0,1) Sq^2 Sq^1 + Sq^3 @@ -2353,7 +2352,7 @@ def P(self, *nums): try: assert Integer(i) >= 0 except (TypeError, AssertionError): - raise TypeError("entries must be non-negative integers") + raise TypeError("entries must be nonnegative integers") if not self._generic: t = nums @@ -2374,7 +2373,7 @@ def Q_exp(self, *nums): - ``e0``, ``e1``, ... -- sequence of 0s and 1s - OUTPUT: The element `Q_0^{e_0} Q_1^{e_1} ...` + OUTPUT: the element `Q_0^{e_0} Q_1^{e_1} ...` Note that at the prime 2, `Q_n` is the element `\text{Sq}(0,0,...,1)` , where the 1 is in the @@ -2401,7 +2400,7 @@ def Q_exp(self, *nums): """ if not all(x in (0, 1) for x in nums): raise ValueError("The tuple %s should consist " % (nums,) + - "only of 0's and 1's") + "only of 0s and 1s") else: if self.basis_name() != 'milnor': return self(SteenrodAlgebra(p=self.prime(), @@ -2426,9 +2425,9 @@ def Q(self, *nums): INPUT: - - ``n0``, ``n1``, ... -- non-negative integers + - ``n0``, ``n1``, ... -- nonnegative integers - OUTPUT: The element `Q_{n0} Q_{n1} ...` + OUTPUT: the element `Q_{n0} Q_{n1} ...` Note that at the prime 2, `Q_n` is the element `\text{Sq}(0,0,...,1)` , where the 1 is in the @@ -2540,11 +2539,11 @@ def pst(self,s,t): INPUT: - - ``s`` -- non-negative integer + - ``s`` -- nonnegative integer - - ``t`` -- positive integer + - ``t`` -- positive integer - - ``p`` -- positive prime number + - ``p`` -- positive prime number OUTPUT: element of the Steenrod algebra @@ -2567,7 +2566,7 @@ def pst(self,s,t): if self.basis_name() != 'milnor': return self(SteenrodAlgebra(p=self.prime(),generic=self._generic).pst(s,t)) if not isinstance(s, (Integer, int)) and s >= 0: - raise ValueError("%s is not a non-negative integer" % s) + raise ValueError("%s is not a nonnegative integer" % s) if not isinstance(t, (Integer, int)) and t > 0: raise ValueError("%s is not a positive integer" % t) nums = (0,)*(t-1) + (self.prime()**s,) @@ -2690,17 +2689,17 @@ def gens(self): def gen(self, i=0): r""" - The ith generator of this algebra. + The `i`-th generator of this algebra. INPUT: - - ``i`` -- non-negative integer + - ``i`` -- nonnegative integer - OUTPUT: the ith generator of this algebra + OUTPUT: the `i`-th generator of this algebra - For the full Steenrod algebra, the `i^{th}` generator is - `\text{Sq}(2^i)` at the prime 2; when `p` is odd, the 0th generator - is `\beta = Q(0)`, and for `i>0`, the `i^{th}` generator is + For the full Steenrod algebra, the `i`-th generator is + `\text{Sq}(2^i)` at the prime 2; when `p` is odd, the `0`-th generator + is `\beta = Q(0)`, and for `i>0`, the `i`-th generator is `P(p^{i-1})`. For sub-Hopf algebras of the Steenrod algebra, it is not @@ -2758,7 +2757,7 @@ def gen(self, i=0): from sage.rings.integer import Integer p = self.prime() if not isinstance(i, (Integer, int)) and i >= 0: - raise ValueError("%s is not a non-negative integer" % i) + raise ValueError("%s is not a nonnegative integer" % i) num = self.ngens() if num < Infinity: if i >= num: @@ -2830,7 +2829,7 @@ def gen(self, i=0): def is_commutative(self): r""" - True if ``self`` is graded commutative, as determined by the + Return ``True`` if ``self`` is graded commutative, as determined by the profile function. In particular, a sub-Hopf algebra of the mod 2 Steenrod algebra is commutative if and only if there is an integer `n>0` so that its profile function `e` satisfies @@ -2882,7 +2881,7 @@ def is_commutative(self): def is_finite(self): r""" - True if this algebra is finite-dimensional. + Return ``True`` if this algebra is finite-dimensional. Therefore true if the profile function is finite, and in particular the ``truncation_type`` must be finite. @@ -3131,7 +3130,7 @@ class Element(CombinatorialFreeModule.Element): """ def prime(self): """ - The prime associated to self. + The prime associated to ``self``. EXAMPLES:: @@ -3150,7 +3149,7 @@ def prime(self): def basis_name(self): """ - The basis name associated to self. + The basis name associated to ``self``. EXAMPLES:: @@ -3171,7 +3170,7 @@ def basis_name(self): def is_homogeneous(self): """ - Return True iff this element is homogeneous. + Return ``True`` iff this element is homogeneous. EXAMPLES:: @@ -3194,7 +3193,7 @@ def is_homogeneous(self): def degree(self): r""" - The degree of self. + The degree of ``self``. The degree of `\text{Sq}(i_1,i_2,i_3,...)` is @@ -3288,9 +3287,9 @@ def change_basis(self, basis='milnor'): INPUT: - - ``basis`` -- string, basis in which to work. + - ``basis`` -- string; basis in which to work - OUTPUT: representation of self in given basis + OUTPUT: representation of ``self`` in given basis The choices for ``basis`` are: @@ -3332,7 +3331,7 @@ def change_basis(self, basis='milnor'): def _basis_dictionary(self, basis): r""" - Convert self to ``basis``, returning a dictionary of terms of + Convert ``self`` to ``basis``, returning a dictionary of terms of the form (mono: coeff), where mono is a monomial in the given basis. @@ -3460,7 +3459,7 @@ def excess(self): r""" Excess of element. - OUTPUT: ``excess`` -- non-negative integer + OUTPUT: ``excess`` -- nonnegative integer The excess of a Milnor basis element `\text{Sq}(a,b,c,...)` is `a + b + c + \cdots`. When `p` is odd, the excess of `Q_{0}^{e_0} @@ -3517,9 +3516,9 @@ def excess_odd(mono): return min(excesses) def is_unit(self): - """ - True if element has a nonzero scalar multiple of P(0) as a summand, - False otherwise. + r""" + Return ``True`` if element has a nonzero scalar multiple of + `P(0)` as a summand, ``False`` otherwise. EXAMPLES:: @@ -3540,7 +3539,7 @@ def is_unit(self): def is_nilpotent(self): """ - True if element is not a unit, False otherwise. + Return ``True`` if element is not a unit, ``False`` otherwise. EXAMPLES:: @@ -3559,7 +3558,7 @@ def may_weight(self): r""" May's 'weight' of element. - OUTPUT: ``weight`` -- non-negative integer + OUTPUT: ``weight`` -- nonnegative integer If we let `F_* (A)` be the May filtration of the Steenrod algebra, the weight of an element `x` is the integer `k` so @@ -3635,10 +3634,10 @@ def may_weight(self): def is_decomposable(self): r""" - Return True if element is decomposable, False otherwise. + Return ``True`` if element is decomposable, ``False`` otherwise. That is, if element is in the square of the augmentation ideal, - return True; otherwise, return False. + return ``True``; otherwise, return ``False``. OUTPUT: boolean @@ -3685,12 +3684,12 @@ def wall_height(self): r""" Wall's 'height' of element. - OUTPUT: list of non-negative integers + OUTPUT: list of nonnegative integers The height of an element of the mod 2 Steenrod algebra is a - list of non-negative integers, defined as follows: if the + list of nonnegative integers, defined as follows: if the element is a monomial in the generators `\text{Sq}(2^i)`, then - the `i^{th}` entry in the list is the number of times + the `i`-th entry in the list is the number of times `\text{Sq}(2^i)` appears. For an arbitrary element, write it as a sum of such monomials; then its height is the maximum, ordered right-lexicographically, of the heights of those @@ -3702,7 +3701,7 @@ def wall_height(self): basis element `\text{Sq}(r_1, r_2, ...)` is obtained as follows: write each `r_i` in binary as `r_i = \sum_j 2^j r_{ij}`. Then each nonzero binary digit `r_{ij}` contributes 1 - to the `k^{th}` entry in the height, for `j \leq k \leq + to the `k`-th entry in the height, for `j \leq k \leq i+j-1`. EXAMPLES:: @@ -3777,7 +3776,7 @@ def Sq(self, *nums): INPUT: - - ``a``, ``b``, ``c``, ... -- non-negative integers + - ``a``, ``b``, ``c``, ... -- nonnegative integers OUTPUT: element of the Steenrod algebra @@ -3792,7 +3791,7 @@ def Sq(self, *nums): sage: A.Sq(5,0,2) Sq(5,0,2) - Entries must be non-negative integers; otherwise, an error + Entries must be nonnegative integers; otherwise, an error results. """ if self.prime() == 2: @@ -3803,7 +3802,7 @@ def Sq(self, *nums): def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): r""" - The mod `p` Steenrod algebra + The mod `p` Steenrod algebra. INPUT: @@ -3983,7 +3982,7 @@ def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): ``profile`` argument specifies the profile function for this algebra. Any sub-Hopf algebra of the Steenrod algebra is determined by its *profile function*. When `p=2`, this is a map `e` - from the positive integers to the set of non-negative integers, + from the positive integers to the set of nonnegative integers, plus `\infty`, corresponding to the sub-Hopf algebra dual to this quotient of the dual Steenrod algebra: @@ -4002,10 +4001,10 @@ def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): - a list or tuple, e.g., ``[3,2,1]``, corresponding to the function sending 1 to 3, 2 to 2, 3 to 1, and all other integers to the value of ``truncation_type``. - - a function from positive integers to non-negative integers (and + - a function from positive integers to nonnegative integers (and `\infty`), e.g., ``lambda n: n+2``. - ``None`` or ``Infinity`` -- use this for the profile function for - the whole Steenrod algebra. + the whole Steenrod algebra In the first and third cases, ``precision`` is ignored. In the second case, this function is converted to a tuple of length one @@ -4023,7 +4022,7 @@ def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): following:: sage: A2 = SteenrodAlgebra(profile=[3,2,1]) - sage: B2 = SteenrodAlgebra(profile=[3,2,1,0,0]) # trailing 0's ignored + sage: B2 = SteenrodAlgebra(profile=[3,2,1,0,0]) # trailing 0s ignored sage: A2 == B2 True sage: C2 = SteenrodAlgebra(profile=lambda n: max(4-n, 0), truncation_type=0) @@ -4078,12 +4077,12 @@ def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): the set `\{1,2\}`, e.g., ``([3,2,1,1], [1,1,2,2,1])``. - a pair of functions, one from the positive integers to - non-negative integers (and `\infty`), one from the non-negative + nonnegative integers (and `\infty`), one from the nonnegative integers to the set `\{1,2\}`, e.g., ``(lambda n: n+2, lambda n: 1 if n<3 else 2)``. - ``None`` or ``Infinity`` -- use this for the profile function for - the whole Steenrod algebra. + the whole Steenrod algebra You can also mix and match the first two, passing a pair with first entry a list and second entry a function, for instance. The @@ -4186,8 +4185,8 @@ def AA(n=None, p=2): INPUT: - - `n` -- non-negative integer, optional (default ``None``) - - `p` -- prime number, optional (default 2) + - ``n`` -- nonnegative integer (default: ``None``) + - ``p`` -- prime number (default: 2) OUTPUT: @@ -4226,12 +4225,11 @@ def Sq(*nums): INPUT: - - ``a``, ``b``, ``c``, ... -- non-negative integers + - ``a``, ``b``, ``c``, ... -- nonnegative integers OUTPUT: element of the Steenrod algebra - This returns the Milnor basis element - `\text{Sq}(a, b, c, ...)`. + This returns the Milnor basis element `\text{Sq}(a, b, c, ...)`. EXAMPLES:: @@ -4242,7 +4240,7 @@ def Sq(*nums): sage: (Sq(4,3) + Sq(7,2)).degree() 13 - Entries must be non-negative integers; otherwise, an error + Entries must be nonnegative integers; otherwise, an error results. This function is a good way to define elements of the Steenrod diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index 070043a08d8..06f9a5b87ad 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -20,29 +20,29 @@ Monks [Mon1998]_ and Wood [Woo1998]_ for more information about them. For commutator bases, see the preprint by Palmieri and Zhang [PZ2008]_. -- ``'milnor'``: Milnor basis. +- ``'milnor'`` -- Milnor basis -- ``'serre-cartan'`` or ``'adem'`` or ``'admissible'``: Serre-Cartan basis. +- ``'serre-cartan'`` or ``'adem'`` or ``'admissible'`` -- Serre-Cartan basis Most of the rest of the bases are only defined when `p=2`. The only exceptions are the `P^s_t`-bases and the commutator bases, which are defined at all primes. -- ``'wood_y'``: Wood's Y basis. +- ``'wood_y'`` -- Wood's Y basis -- ``'wood_z'``: Wood's Z basis. +- ``'wood_z'`` -- Wood's Z basis -- ``'wall'``, ``'wall_long'``: Wall's basis. +- ``'wall'``, ``'wall_long'`` -- Wall's basis -- ``'arnon_a'``, ``'arnon_a_long'``: Arnon's A basis. +- ``'arnon_a'``, ``'arnon_a_long'`` -- Arnon's A basis -- ``'arnon_c'``: Arnon's C basis. +- ``'arnon_c'`` -- Arnon's C basis -- ``'pst'``, ``'pst_rlex'``, ``'pst_llex'``, ``'pst_deg'``, ``'pst_revz'``: - various `P^s_t`-bases. +- ``'pst'``, ``'pst_rlex'``, ``'pst_llex'``, ``'pst_deg'``, ``'pst_revz'`` -- + various `P^s_t`-bases -- ``'comm'``, ``'comm_rlex'``, ``'comm_llex'``, ``'comm_deg'``, ``'comm_revz'``, - or these with ``'_long'`` appended: various commutator bases. +- ``'comm'``, ``'comm_rlex'``, ``'comm_llex'``, ``'comm_deg'``, ``'comm_revz'``, + or these with ``'_long'`` appended -- various commutator bases The main functions provided here are @@ -122,7 +122,7 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): INPUT: - - ``n`` -- non-negative integer, the dimension + - ``n`` -- nonnegative integer, the dimension - ``basis`` -- string, the basis from which to convert - ``p`` -- positive prime number (default: 2) @@ -190,7 +190,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): INPUT: - - ``n`` -- non-negative integer, the dimension + - ``n`` -- nonnegative integer, the dimension - ``basis`` -- string, the basis to which to convert @@ -200,7 +200,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): ``matrix`` -- change-of-basis matrix, a square matrix over `\GF{p}` - .. note:: + .. NOTE:: This is called internally. It is not intended for casual users, so no error checking is made on the integer `n`, the @@ -263,14 +263,14 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``basis`` -- string, which basis to use (default: ``'milnor'``) - ``p`` -- positive prime number (default: 2) - - ``profile`` -- profile function (default: ``None``). This + - ``profile`` -- profile function (default: ``None``); this is just passed on to the functions :func:`milnor_basis` and - :func:`pst_basis`. - - ``truncation_type`` -- truncation type, either 0 or Infinity - (default: Infinity if no profile function is specified, + :func:`pst_basis` + - ``truncation_type`` -- truncation type, either 0 or ``Infinity`` + (default: ``Infinity`` if no profile function is specified, 0 otherwise). This is just passed on to the function :func:`milnor_basis`. - ``generic`` -- boolean (default: ``None``) @@ -284,20 +284,20 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): documentation for :mod:`sage.algebras.steenrod.steenrod_algebra` for details on each basis: - - ``'milnor'``: Milnor basis. - - ``'serre-cartan'`` or ``'adem'`` or ``'admissible'``: Serre-Cartan basis. - - ``'pst'``, ``'pst_rlex'``, ``'pst_llex'``, ``'pst_deg'``, ``'pst_revz'``: - various `P^s_t`-bases. + - ``'milnor'`` -- Milnor basis + - ``'serre-cartan'`` or ``'adem'`` or ``'admissible'`` -- Serre-Cartan basis + - ``'pst'``, ``'pst_rlex'``, ``'pst_llex'``, ``'pst_deg'``, ``'pst_revz'`` -- + various `P^s_t`-bases - ``'comm'``, ``'comm_rlex'``, ``'comm_llex'``, ``'comm_deg'``, ``'comm_revz'``, or - any of these with ``'_long'`` appended: various commutator bases. + any of these with ``'_long'`` appended -- various commutator bases The rest of these bases are only defined when `p=2`. - - ``'wood_y'``: Wood's Y basis. - - ``'wood_z'``: Wood's Z basis. - - ``'wall'`` or ``'wall_long'``: Wall's basis. - - ``'arnon_a'`` or ``'arnon_a_long'``: Arnon's A basis. - - ``'arnon_c'``: Arnon's C basis. + - ``'wood_y'`` -- Wood's Y basis + - ``'wood_z'`` -- Wood's Z basis + - ``'wall'`` or ``'wall_long'`` -- Wall's basis + - ``'arnon_a'`` or ``'arnon_a_long'`` -- Arnon's A basis + - ``'arnon_c'`` -- Arnon's C basis EXAMPLES:: @@ -385,9 +385,9 @@ def restricted_partitions(n, l, no_repeats=False): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``l`` -- list of positive integers - - ``no_repeats`` -- boolean (default: ``False``), if ``True``, + - ``no_repeats`` -- boolean (default: ``False``); if ``True``, only return partitions with no repeated parts OUTPUT: iterator of lists @@ -462,10 +462,10 @@ def xi_degrees(n, p=2, reverse=True): INPUT: - ``n`` -- integer - - ``p`` -- prime number, optional (default: 2) - - ``reverse`` -- bool, optional (default: ``True``) + - ``p`` -- prime number (default: 2) + - ``reverse`` -- boolean (default: ``True``) - OUTPUT: ``list`` -- list of integers + OUTPUT: list of integers When `p=2`: decreasing list of the degrees of the `\xi_i`'s with degree at most `n`. @@ -513,7 +513,7 @@ def milnor_basis(n, p=2, **kwds): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``p`` -- positive prime number (default: 2) @@ -525,19 +525,19 @@ def milnor_basis(n, p=2, **kwds): :func:`SteenrodAlgebra ` for information on profile functions. - - ``truncation_type`` -- truncation type, either 0 or Infinity - (default: Infinity if no profile function is specified, + - ``truncation_type`` -- truncation type, either 0 or ``Infinity`` + (default: ``Infinity`` if no profile function is specified, 0 otherwise) OUTPUT: tuple of mod `p` Milnor basis elements in dimension `n` At the prime 2, the Milnor basis consists of symbols of the form `\text{Sq}(m_1, m_2, ..., m_t)`, where each - `m_i` is a non-negative integer and if `t>1`, then + `m_i` is a nonnegative integer and if `t>1`, then `m_t \neq 0`. At odd primes, it consists of symbols of the form `Q_{e_1} Q_{e_2} ... P(m_1, m_2, ..., m_t)`, where `0 \leq e_1 < e_2 < ...`, each `m_i` is a - non-negative integer, and if `t>1`, then + nonnegative integer, and if `t>1`, then `m_t \neq 0`. EXAMPLES:: @@ -678,7 +678,7 @@ def serre_cartan_basis(n, p=2, bound=1, **kwds): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``bound`` -- positive integer (optional) - ``prime`` -- positive prime number (default: 2) @@ -763,7 +763,7 @@ def atomic_basis(n, basis, **kwds): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``basis`` -- string, the name of the basis @@ -774,8 +774,8 @@ def atomic_basis(n, basis, **kwds): :mod:`sage.algebras.steenrod.steenrod_algebra` and :func:`SteenrodAlgebra` for information on profile functions. - - ``truncation_type`` -- truncation type, either 0 or Infinity - (default: Infinity if no profile function is specified, + - ``truncation_type`` -- truncation type, either 0 or ``Infinity`` + (default: ``Infinity`` if no profile function is specified, 0 otherwise). OUTPUT: tuple of basis elements in dimension `n` @@ -943,7 +943,7 @@ def arnonC_basis(n, bound=1): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``bound`` -- positive integer (optional) @@ -992,7 +992,7 @@ def atomic_basis_odd(n, basis, p, **kwds): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - ``basis`` -- string, the name of the basis @@ -1005,8 +1005,8 @@ def atomic_basis_odd(n, basis, p, **kwds): :mod:`sage.algebras.steenrod.steenrod_algebra` and :func:`SteenrodAlgebra` for information on profile functions. - - ``truncation_type`` -- truncation type, either 0 or Infinity - (default: Infinity if no profile function is specified, + - ``truncation_type`` -- truncation type, either 0 or ``Infinity`` + (default: ``Infinity`` if no profile function is specified, 0 otherwise). OUTPUT: tuple of basis elements in dimension `n` @@ -1107,10 +1107,10 @@ def steenrod_basis_error_check(dim, p, **kwds): INPUT: - - ``dim`` -- non-negative integer + - ``dim`` -- nonnegative integer - ``p`` -- positive prime number - OUTPUT: None + OUTPUT: none This checks to see if the different bases have the same length, and if the change-of-basis matrices are invertible. If something goes diff --git a/src/sage/algebras/steenrod/steenrod_algebra_misc.py b/src/sage/algebras/steenrod/steenrod_algebra_misc.py index a57372f52c3..1bf8e278502 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_misc.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_misc.py @@ -54,11 +54,9 @@ def get_basis_name(basis, p, generic=None): - ``p`` -- positive prime number - - ``generic`` -- boolean, optional, default to 'None' + - ``generic`` -- boolean (default: 'None') - OUTPUT: - - - ``basis_name`` -- string + OUTPUT: ``basis_name`` -- string Specify the names of the implemented bases. The input is converted to lower-case, then processed to return the canonical @@ -187,7 +185,7 @@ def get_basis_name(basis, p, generic=None): def is_valid_profile(profile, truncation_type, p=2, generic=None): r""" - True if ``profile``, together with ``truncation_type``, is a valid + Return ``True`` if ``profile``, together with ``truncation_type``, is a valid profile at the prime `p`. INPUT: @@ -197,11 +195,11 @@ def is_valid_profile(profile, truncation_type, p=2, generic=None): - ``truncation_type`` -- either 0 or `\infty` - - `p` -- prime number, optional, default 2 + - ``p`` -- prime number (default: 2) - - `generic` -- boolean, optional, default None + - ``generic`` -- boolean (default: ``None``) - OUTPUT: True if the profile function is valid, False otherwise. + OUTPUT: ``True`` if the profile function is valid, ``False`` otherwise See the documentation for :mod:`sage.algebras.steenrod.steenrod_algebra` for descriptions of profile functions and how they correspond to @@ -306,10 +304,10 @@ def normalize_profile(profile, precision=None, truncation_type='auto', p=2, gene INPUT: - ``profile`` -- a profile function in form specified below - - ``precision`` -- integer or ``None``, optional, default ``None`` - - ``truncation_type`` -- 0 or `\infty` or 'auto', optional, default 'auto' - - `p` -- prime, optional, default 2 - - `generic` -- boolean, optional, default ``None`` + - ``precision`` -- integer or ``None`` (default: ``None``) + - ``truncation_type`` -- 0 or `\infty` or 'auto' (default: 'auto') + - ``p`` -- prime (default: 2) + - ``generic`` -- boolean (default: ``None``) OUTPUT: @@ -329,7 +327,7 @@ def normalize_profile(profile, precision=None, truncation_type='auto', p=2, gene function, and it may be entered in any of the following forms: - a list or tuple, e.g., ``[3,2,1,1]`` - - a function from positive integers to non-negative integers (and + - a function from positive integers to nonnegative integers (and `\infty`), e.g., ``lambda n: n+2``. This corresponds to the list ``[3, 4, 5, ...]``. - ``None`` or ``Infinity`` -- use this for the profile function for @@ -340,7 +338,7 @@ def normalize_profile(profile, precision=None, truncation_type='auto', p=2, gene case it is clear how to do this; also in this case, ``precision`` is set to be one more than the length of this tuple. In the second case, construct a tuple of length one less than - ``precision`` (default value 100). In the last case, the empty + ``precision`` (default: 100). In the last case, the empty tuple is returned and ``precision`` is set to 1. Once a sub-Hopf algebra of the Steenrod algebra has been defined @@ -359,8 +357,8 @@ def normalize_profile(profile, precision=None, truncation_type='auto', p=2, gene the set `\{1,2\}`, e.g., ``([3,2,1,1], [1,1,2,2,1])``. - a pair of functions, one (called `e`) from positive integers to - non-negative integers (and `\infty`), one (called `k`) from - non-negative integers to the set `\{1,2\}`, e.g., + nonnegative integers (and `\infty`), one (called `k`) from + nonnegative integers to the set `\{1,2\}`, e.g., ``(lambda n: n+2, lambda n: 1)``. This corresponds to the pair ``([3, 4, 5, ...], [1, 1, 1, ...])``. @@ -576,11 +574,11 @@ def milnor_mono_to_string(mono, latex=False, generic=False): INPUT: - - ``mono`` -- if `generic=False`, tuple of non-negative integers (a,b,c,...); - if `generic=True`, pair of tuples of non-negative integers ((e0, e1, e2, + - ``mono`` -- if `generic=False`, tuple of nonnegative integers (a,b,c,...); + if `generic=True`, pair of tuples of nonnegative integers ((e0, e1, e2, ...), (r1, r2, ...)) - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string - ``generic`` -- whether to format generically, or for the prime 2 (default) @@ -654,7 +652,7 @@ def serre_cartan_mono_to_string(mono, latex=False, generic=False): or tuple (e0, n1, e1, n2, ...) when `generic=True`, where each ei is 0 or 1, and each ni is positive - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string - ``generic`` -- whether to format generically, or for the prime 2 (default) @@ -666,7 +664,6 @@ def serre_cartan_mono_to_string(mono, latex=False, generic=False): ``\beta^{e0} P^{n1} \beta^{e1} P^{n2} ...`` when `generic=True`. is odd. - EXAMPLES:: sage: from sage.algebras.steenrod.steenrod_algebra_misc import serre_cartan_mono_to_string @@ -730,9 +727,9 @@ def wood_mono_to_string(mono, latex=False): INPUT: - - ``mono`` -- tuple of pairs of non-negative integers (s,t) + - ``mono`` -- tuple of pairs of nonnegative integers (s,t) - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string OUTPUT: @@ -775,10 +772,10 @@ def wall_mono_to_string(mono, latex=False): INPUT: - - ``mono`` -- tuple of pairs of non-negative integers (m,k) with `m + - ``mono`` -- tuple of pairs of nonnegative integers (m,k) with `m >= k` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string OUTPUT: @@ -816,10 +813,10 @@ def wall_long_mono_to_string(mono, latex=False): INPUT: - - ``mono`` -- tuple of pairs of non-negative integers (m,k) with `m + - ``mono`` -- tuple of pairs of nonnegative integers (m,k) with `m >= k` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string OUTPUT: @@ -861,16 +858,14 @@ def arnonA_mono_to_string(mono, latex=False, p=2): INPUT: - - ``mono`` -- tuple of pairs of non-negative integers + - ``mono`` -- tuple of pairs of nonnegative integers (m,k) with `m >= k` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string - OUTPUT: - - ``string`` -- concatenation of strings of the form ``X^{m}_{k}`` - for each pair (m,k) + OUTPUT: concatenation of strings of the form ``X^{m}_{k}`` for each pair + (m,k) EXAMPLES:: @@ -903,10 +898,10 @@ def arnonA_long_mono_to_string(mono, latex=False, p=2): INPUT: - - ``mono`` -- tuple of pairs of non-negative integers (m,k) with `m + - ``mono`` -- tuple of pairs of nonnegative integers (m,k) with `m >= k` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string OUTPUT: @@ -951,7 +946,7 @@ def pst_mono_to_string(mono, latex=False, generic=False): - ``mono`` -- tuple of pairs of integers (s,t) with `s >= 0`, `t > 0` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string - ``generic`` -- whether to format generically, or for the prime 2 (default) @@ -1014,7 +1009,7 @@ def comm_mono_to_string(mono, latex=False, generic=False): - ``mono`` -- tuple of pairs of integers (s,t) with `s >= 0`, `t > 0` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string - ``generic`` -- whether to format generically, or for the prime 2 (default) @@ -1077,7 +1072,7 @@ def comm_long_mono_to_string(mono, p, latex=False, generic=False): - ``mono`` -- tuple of pairs of integers (s,t) with `s >= 0`, `t > 0` - - ``latex`` -- boolean (default: ``False``), if true, output + - ``latex`` -- boolean (default: ``False``); if ``True``, output LaTeX string - ``generic`` -- whether to format generically, or for the prime 2 (default) @@ -1140,12 +1135,12 @@ def comm_long_mono_to_string(mono, p, latex=False, generic=False): def convert_perm(m): """ - Convert tuple m of non-negative integers to a permutation in + Convert tuple m of nonnegative integers to a permutation in one-line form. INPUT: - - ``m`` -- tuple of non-negative integers with no repetitions + - ``m`` -- tuple of nonnegative integers with no repetitions OUTPUT: diff --git a/src/sage/algebras/steenrod/steenrod_algebra_mult.py b/src/sage/algebras/steenrod/steenrod_algebra_mult.py index 3cd534d0b4e..053290bc5ed 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_mult.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_mult.py @@ -47,17 +47,17 @@ both have a summand of 2.) Now, for each matrix with multinomial coefficient 1, let `t_n` be -the sum of the nth diagonal in the matrix; then +the sum of the `n`-th diagonal in the matrix; then .. MATH:: \text{Sq}(r_1, r_2, ...) \text{Sq}(s_1, s_2, ...) = \sum \text{Sq}(t_1, t_2, ...) The function :func:`milnor_multiplication` takes as input two tuples -of non-negative integers, `r` and `s`, which represent +of nonnegative integers, `r` and `s`, which represent `\text{Sq}(r)=\text{Sq}(r_1, r_2, ...)` and `\text{Sq}(s)=\text{Sq}(s_1, s_2, ...)`; it returns as output a -dictionary whose keys are tuples `t=(t_1, t_2, ...)` of non-negative +dictionary whose keys are tuples `t=(t_1, t_2, ...)` of nonnegative integers, and for each tuple the associated value is the coefficient of `\text{Sq}(t)` in the product formula. (Since we are working mod 2, this coefficient is 1 -- if it is zero, the element is omitted from @@ -128,10 +128,10 @@ \mathcal{P}(5) \mathcal{P}(1,1) = \mathcal{P}(6,1) + 2 \mathcal{P}(0,2). The function :func:`milnor_multiplication` takes as input two pairs of -tuples of non-negative integers, `(g,q)` and `(f,s)`, which represent +tuples of nonnegative integers, `(g,q)` and `(f,s)`, which represent `Q_{g_1} Q_{g_2} ... \mathcal{P}(q_1, q_2, ...)` and `Q_{f_1} Q_{f_2} ... \mathcal{P}(s_1, s_2, ...)`. It returns as output a -dictionary whose keys are pairs of tuples `(e,t)` of non-negative +dictionary whose keys are pairs of tuples `(e,t)` of nonnegative integers, and for each tuple the associated value is the coefficient in the product formula. @@ -158,7 +158,7 @@ process terminates in a finite number of steps, and therefore gives a procedure for multiplying elements of the Serre-Cartan basis. -At an odd prime `p`, the Steenrod algebra is generated by the pth +At an odd prime `p`, the Steenrod algebra is generated by the `p`-th power operations `\mathcal{P}^a` (the same as `\mathcal{P}(a)` in the Milnor basis) and the Bockstein operation `\beta` (= `Q_0` in the Milnor basis). The odd primary *Adem relations* are as follows: if `a @@ -190,7 +190,7 @@ The main function for this is :func:`make_mono_admissible`, which converts a product of Steenrod -squares or pth power operations and Bocksteins into a dictionary +squares or `p`-th power operations and Bocksteins into a dictionary representing a sum of admissible monomials. """ @@ -210,13 +210,13 @@ def milnor_multiplication(r,s): INPUT: - - r -- tuple of non-negative integers - - s -- tuple of non-negative integers + - ``r`` -- tuple of nonnegative integers + - ``s`` -- tuple of nonnegative integers OUTPUT: Dictionary of terms of the form (tuple: coeff), where - 'tuple' is a tuple of non-negative integers and 'coeff' is 1. + 'tuple' is a tuple of nonnegative integers and 'coeff' is 1. This computes Milnor matrices for the product of `\text{Sq}(r)` and `\text{Sq}(s)`, computes their multinomial coefficients, and @@ -312,9 +312,9 @@ def milnor_multiplication(r,s): else: sum = sum + M[i][j] * 2**j else: - sum = sum + M[i][j] * 2**j - j = j + 1 - i = i + 1 + sum = sum + M[i][j] * 2**j + j += 1 + i += 1 return result @@ -324,11 +324,9 @@ def multinomial(list): INPUT: - - list -- list of integers - - OUTPUT: + - ``list`` -- list of integers - None if the multinomial coefficient is 0, or sum of list if it is 1 + OUTPUT: none if the multinomial coefficient is 0, or sum of list if it is 1 Given the input `[n_1, n_2, n_3, ...]`, this computes the multinomial coefficient `(n_1 + n_2 + n_3 + ...)! / (n_1! n_2! @@ -380,10 +378,10 @@ def milnor_multiplication_odd(m1,m2,p): INPUT: - - m1 -- pair of tuples (e,r), where e is an increasing tuple of - non-negative integers and r is a tuple of non-negative integers - - m2 -- pair of tuples (f,s), same format as m1 - - p -- odd prime number + - ``m1`` -- pair of tuples (e,r), where e is an increasing tuple of + nonnegative integers and r is a tuple of nonnegative integers + - ``m2`` -- pair of tuples (f,s), same format as m1 + - ``p`` -- odd prime number OUTPUT: @@ -576,12 +574,10 @@ def multinomial_odd(list,p): INPUT: - - list -- list of integers - - p -- a prime number - - OUTPUT: + - ``list`` -- list of integers + - ``p`` -- a prime number - Associated multinomial coefficient, mod p + OUTPUT: associated multinomial coefficient, mod p Given the input `[n_1, n_2, n_3, ...]`, this computes the multinomial coefficient `(n_1 + n_2 + n_3 + ...)! / (n_1! n_2! @@ -647,9 +643,7 @@ def binomial_mod2(n,k): - `n`, `k` -- integers - OUTPUT: - - `n` choose `k`, mod 2 + OUTPUT: `n` choose `k`, mod 2 EXAMPLES:: @@ -678,11 +672,9 @@ def binomial_modp(n,k,p): INPUT: - `n`, `k` -- integers - - `p` -- prime number - - OUTPUT: + - ``p`` -- prime number - `n` choose `k`, mod `p` + OUTPUT: `n` choose `k`, mod `p` EXAMPLES:: @@ -700,14 +692,14 @@ def binomial_modp(n,k,p): @cached_function def adem(a, b, c=0, p=2, generic=None): r""" - The mod `p` Adem relations + The mod `p` Adem relations. INPUT: - - `a`, `b`, `c` (optional) -- nonnegative integers, corresponding + - `a`, `b`, `c` -- nonnegative integers (optional); corresponding to either `P^a P^b` or (if `c` present) to `P^a \beta^b P^c` - - `p` -- positive prime number (default: 2) - - `generic` -- whether to use the generic Steenrod algebra, (default: depends on prime) + - ``p`` -- positive prime number (default: 2) + - ``generic`` -- whether to use the generic Steenrod algebra, (default: depends on prime) OUTPUT: @@ -792,7 +784,7 @@ def adem(a, b, c=0, p=2, generic=None): return result # p odd if a == 0 and b == 0: - return {(c,): 1} + return {(c,): 1} if c == 0: bockstein = 0 A = a @@ -854,14 +846,14 @@ def make_mono_admissible(mono, p=2, generic=None): INPUT: - - ``mono`` -- a tuple of non-negative integers - - `p` -- prime number, optional (default 2) - - `generic` -- whether to use the generic Steenrod algebra, (default: depends on prime) + - ``mono`` -- tuple of nonnegative integers + - ``p`` -- prime number (default: 2) + - ``generic`` -- whether to use the generic Steenrod algebra (default: depends on prime) OUTPUT: Dictionary of terms of the form (tuple: coeff), where - 'tuple' is an admissible tuple of non-negative integers and + 'tuple' is an admissible tuple of nonnegative integers and 'coeff' is its coefficient. This corresponds to a linear combination of admissible monomials. When `p` is odd, each tuple must have an odd length: it should be of the form `(e_1, i_1, e_2, diff --git a/src/sage/algebras/tensor_algebra.py b/src/sage/algebras/tensor_algebra.py index 0d323a6ebb7..3a5f8d9c033 100644 --- a/src/sage/algebras/tensor_algebra.py +++ b/src/sage/algebras/tensor_algebra.py @@ -583,7 +583,7 @@ def coproduct_on_basis(self, m): # for w in Word(range(p)).shuffle(range(p, k)) ) ##################################################################### -## TensorAlgebra functor +# TensorAlgebra functor class TensorAlgebraFunctor(ConstructionFunctor): @@ -684,7 +684,7 @@ def _apply_functor_to_morphism(self, f): return D.module_morphism(phi, codomain=C) ##################################################################### -## Lift map from the base ring +# Lift map from the base ring class BaseRingLift(Morphism): diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 247b6107e0f..8eae4797c7d 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -43,12 +43,12 @@ def repr_from_monomials(monomials, term_repr, use_latex=False) -> str: INPUT: - - ``monomials`` -- a list of pairs ``[m, c]`` where ``m`` is the index + - ``monomials`` -- list of pairs ``[m, c]`` where ``m`` is the index and ``c`` is the coefficient - ``term_repr`` -- a function which returns a string given an index (can be ``repr`` or ``latex``, for example) - - ``use_latex`` -- (default: ``False``) if ``True`` then the output is - in latex format + - ``use_latex`` -- boolean (default: ``False``); if ``True`` then the + output is in latex format EXAMPLES:: @@ -728,7 +728,7 @@ def _repr_(self) -> str: # add options to class class options(GlobalOptions): r""" - Sets the global options for elements of the differential Weyl + Set the global options for elements of the differential Weyl algebra class. The default is to have the factored representations turned off. @@ -786,7 +786,7 @@ def _element_constructor_(self, x): return self.element_class(self, {i: R(c) for i, c in x if R(c) != zero}) x = self._poly_ring(x) return self.element_class(self, {(tuple(m), t): c - for m, c in x.dict().items()}) + for m, c in x.monomial_coefficients().items()}) def _coerce_map_from_(self, R): """ diff --git a/src/sage/algebras/yangian.py b/src/sage/algebras/yangian.py index 8e19b92ba07..748586a30b9 100644 --- a/src/sage/algebras/yangian.py +++ b/src/sage/algebras/yangian.py @@ -228,7 +228,7 @@ def __init__(self, base_ring, n, variable_name, filtration): EXAMPLES:: sage: Y = Yangian(QQ, 4, filtration='loop') - sage: TestSuite(Y).run(skip="_test_antipode") # Not implemented + sage: TestSuite(Y).run(skip='_test_antipode') # Not implemented sage: Y = Yangian(QQ, 4, filtration='natural') sage: G = Y.algebra_generators() sage: elts = [Y.one(), G[1,2,2], G[1,1,4], G[3,3,1], G[1,2,1]*G[2,1,4]] @@ -395,7 +395,7 @@ def algebra_generators(self): Lazy family (generator(i))_{i in The Cartesian product of (Positive integers, {1, 2, 3, 4}, {1, 2, 3, 4})} """ - return Family(self._indices._indices, self.gen, name="generator") + return Family(self._indices._indices, self.gen, name='generator') @cached_method def one_basis(self): @@ -575,13 +575,13 @@ def product_on_gens(self, a, b): # This is the special term of x = 1 x1 = self.zero() if b[1] == a[2]: - x1 += self.monomial( I.gen((a[0]+b[0]-1, a[1], b[2])) ) + x1 += self.monomial(I.gen((a[0]+b[0]-1, a[1], b[2]))) if a[1] == b[2]: - x1 -= self.monomial( I.gen((a[0]+b[0]-1, b[1], a[2])) ) + x1 -= self.monomial(I.gen((a[0]+b[0]-1, b[1], a[2]))) return self.monomial(I.gen(b) * I.gen(a)) + x1 + self.sum( - self.monomial( I.gen((x-1, b[1], a[2])) * I.gen((a[0]+b[0]-x, a[1], b[2])) ) - - self.product_on_gens( (a[0]+b[0]-x, b[1], a[2]), (x-1, a[1], b[2]) ) + self.monomial(I.gen((x-1, b[1], a[2])) * I.gen((a[0]+b[0]-x, a[1], b[2]))) + - self.product_on_gens((a[0]+b[0]-x, b[1], a[2]), (x-1, a[1], b[2])) for x in range(2, b[0]+1)) def coproduct_on_basis(self, m): @@ -610,9 +610,9 @@ def coproduct_on_basis(self, m): """ T = self.tensor_square() I = self._indices - return T.prod(T.monomial( (I.one(), I.gen((a[0],a[1],a[2]))) ) - + T.monomial( (I.gen((a[0],a[1],a[2])), I.one()) ) - + T.sum_of_terms([(( I.gen((s,a[1],k)), I.gen((a[0]-s,k,a[2])) ), 1) + return T.prod(T.monomial((I.one(), I.gen((a[0],a[1],a[2])))) + + T.monomial((I.gen((a[0],a[1],a[2])), I.one())) + + T.sum_of_terms([((I.gen((s,a[1],k)), I.gen((a[0]-s,k,a[2]))), 1) for k in range(1, self._n+1) for s in range(1, a[0])]) for a,exp in m._sorted_items() for p in range(exp)) @@ -657,7 +657,7 @@ def __init__(self, base_ring, n, level, variable_name, filtration): EXAMPLES:: sage: Y = Yangian(QQ, 4, 3) - sage: TestSuite(Y).run(skip="_test_antipode") + sage: TestSuite(Y).run(skip='_test_antipode') """ self._level = level self._n = n @@ -881,12 +881,12 @@ def product_on_gens(self, a, b): x1 = self.zero() if a[0]+b[0]-1 <= self._level: if b[1] == a[2]: - x1 += self.monomial( I.gen((a[0]+b[0]-1, a[1], b[2])) ) + x1 += self.monomial(I.gen((a[0]+b[0]-1, a[1], b[2]))) if a[1] == b[2]: - x1 -= self.monomial( I.gen((a[0]+b[0]-1, b[1], a[2])) ) + x1 -= self.monomial(I.gen((a[0]+b[0]-1, b[1], a[2]))) return self.monomial(I.gen(b) * I.gen(a)) + x1 + self.sum( - self.monomial( I.gen((x-1, b[1], a[2])) * I.gen((a[0]+b[0]-x, a[1], b[2])) ) + self.monomial(I.gen((x-1, b[1], a[2])) * I.gen((a[0]+b[0]-x, a[1], b[2]))) - self.product_on_gens((a[0]+b[0]-x, b[1], a[2]), (x-1, a[1], b[2])) for x in range(2, b[0]+1) if a[0]+b[0]-x <= self._level) @@ -1043,8 +1043,8 @@ def antipode_on_basis(self, m): + 10*tbar(1)[1,2]*tbar(1)[1,3]^3*tbar(3)[1,2] + 15*tbar(1)[1,2]^2*tbar(1)[1,3]^2*tbar(3)[1,3] """ - return self.prod( (-1)**exp * self.monomial(a**exp) - for a,exp in reversed(list(m)) ) + return self.prod((-1)**exp * self.monomial(a**exp) + for a,exp in reversed(list(m))) def coproduct_on_basis(self, m): """ diff --git a/src/sage/algebras/yokonuma_hecke_algebra.py b/src/sage/algebras/yokonuma_hecke_algebra.py index 67ee66a653e..7de8ff07798 100644 --- a/src/sage/algebras/yokonuma_hecke_algebra.py +++ b/src/sage/algebras/yokonuma_hecke_algebra.py @@ -245,10 +245,10 @@ def algebra_generators(self): for i in range(self._n): r = list(zero) # Make a copy r[i] = 1 - d['t%s' % (i+1)] = self.monomial( (tuple(r), one) ) + d['t%s' % (i+1)] = self.monomial((tuple(r), one)) G = self._Pn.group_generators() for i in range(1, self._n): - d['g%s' % i] = self.monomial( (tuple(zero), G[i]) ) + d['g%s' % i] = self.monomial((tuple(zero), G[i])) return Family(sorted(d), lambda i: d[i]) @cached_method @@ -416,8 +416,8 @@ def _product_by_basis_gen(self, m, i): - (q^-1-q)*t1^2*t2^3*t3^2*g[1] - (q^-1-q)*t1^3*t2^2*t3^2*g[1] """ t, w = m - wi = w.apply_simple_reflection(i, side="right") - if not w.has_descent(i, side="right"): + wi = w.apply_simple_reflection(i, side='right') + if not w.has_descent(i, side='right'): return self.monomial((t, wi)) R = self.base_ring() @@ -494,5 +494,5 @@ def __invert__(self): H = self.parent() t,w = self.support_of_term() c = ~self.coefficients()[0] - telt = H.monomial( (tuple((H._d - e) % H._d for e in t), H._Pn.one()) ) + telt = H.monomial((tuple((H._d - e) % H._d for e in t), H._Pn.one())) return c * telt * H.prod(H.inverse_g(i) for i in reversed(w.reduced_word())) diff --git a/src/sage/all.py b/src/sage/all.py index 916e80eef0d..7c505cd3242 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -28,7 +28,8 @@ sage: def is_not_allowed(frame): ....: module = inspect.getmodule(frame) ....: if module is None: return False - ....: return not any(module.__name__.startswith(name) for name in allowed) + ....: return not any(module.__name__.startswith(name) + ....: for name in allowed) sage: [inspect.getmodule(f).__name__ for f in frames if is_not_allowed(f)] [] @@ -57,97 +58,98 @@ import operator import math -################ end setup warnings ############################### +# ############### end setup warnings ############################### -from sage.all__sagemath_repl import * # includes .all__sagemath_objects, .all__sagemath_environment +from sage.all__sagemath_repl import * +# this includes .all__sagemath_objects, .all__sagemath_environment -################################################################### +# ################################################################## # This import also sets up the interrupt handler from cysignals.signals import (AlarmInterrupt, SignalError, - sig_on_reset as sig_on_count) + sig_on_reset as sig_on_count) -from time import sleep +from time import sleep from functools import reduce # in order to keep reduce in python3 import sage.misc.lazy_import -from sage.misc.all import * # takes a while -from sage.typeset.all import * +from sage.misc.all import * # takes a while +from sage.typeset.all import * from sage.misc.sh import sh -from sage.libs.all import * +from sage.libs.all import * from sage.data_structures.all import * -from sage.structure.all import * -from sage.rings.all import * -from sage.arith.all import * -from sage.matrix.all import * - -from sage.symbolic.all import * -from sage.modules.all import * -from sage.monoids.all import * -from sage.algebras.all import * -from sage.modular.all import * -from sage.sat.all import * -from sage.schemes.all import * -from sage.graphs.all import * -from sage.groups.all import * -from sage.arith.power import generic_power as power -from sage.databases.all import * +from sage.structure.all import * +from sage.rings.all import * +from sage.arith.all import * +from sage.matrix.all import * + +from sage.symbolic.all import * +from sage.modules.all import * +from sage.monoids.all import * +from sage.algebras.all import * +from sage.modular.all import * +from sage.sat.all import * +from sage.schemes.all import * +from sage.graphs.all import * +from sage.groups.all import * +from sage.arith.power import generic_power as power +from sage.databases.all import * from sage.categories.all import * -from sage.sets.all import * +from sage.sets.all import * from sage.probability.all import * from sage.interfaces.all import * -from sage.functions.all import * -from sage.calculus.all import * +from sage.functions.all import * +from sage.calculus.all import * -from sage.cpython.all import * +from sage.cpython.all import * -from sage.crypto.all import * +from sage.crypto.all import * import sage.crypto.mq as mq -from sage.plot.all import * -from sage.plot.plot3d.all import * +from sage.plot.all import * +from sage.plot.plot3d.all import * -from sage.coding.all import * -from sage.combinat.all import * +from sage.coding.all import * +from sage.combinat.all import * from sage.lfunctions.all import * -from sage.geometry.all import * -from sage.geometry.triangulation.all import * -from sage.geometry.riemannian_manifolds.all import * +from sage.geometry.all import * +from sage.geometry.triangulation.all import * +from sage.geometry.riemannian_manifolds.all import * -from sage.dynamics.all import * +from sage.dynamics.all import * -from sage.homology.all import * +from sage.homology.all import * -from sage.topology.all import * +from sage.topology.all import * from sage.quadratic_forms.all import * -from sage.games.all import * +from sage.games.all import * -from sage.logic.all import * +from sage.logic.all import * -from sage.numerical.all import * +from sage.numerical.all import * -from sage.stats.all import * +from sage.stats.all import * import sage.stats.all as stats -from sage.parallel.all import * +from sage.parallel.all import * -from sage.ext.fast_callable import fast_callable -from sage.ext.fast_eval import fast_float +from sage.ext.fast_callable import fast_callable +from sage.ext.fast_eval import fast_float from sage.sandpiles.all import * -from sage.tensor.all import * +from sage.tensor.all import * -from sage.matroids.all import * +from sage.matroids.all import * from sage.game_theory.all import * @@ -167,7 +169,7 @@ _init_qqbar() ########################################################### -#### WARNING: +# WARNING: # DO *not* import numpy / matplotlib / networkx here!! # Each takes a surprisingly long time to initialize, # and that initialization should be done more on-the-fly @@ -191,20 +193,29 @@ from sage.misc.persist import register_unpickle_override register_unpickle_override('sage.categories.category', 'Sets', Sets) -register_unpickle_override('sage.categories.category_types', 'HeckeModules', HeckeModules) -register_unpickle_override('sage.categories.category_types', 'Objects', Objects) -register_unpickle_override('sage.categories.category_types', 'Rings', Rings) -register_unpickle_override('sage.categories.category_types', 'Fields', Fields) -register_unpickle_override('sage.categories.category_types', 'VectorSpaces', VectorSpaces) -register_unpickle_override('sage.categories.category_types', 'Schemes_over_base', sage.categories.schemes.Schemes_over_base) -register_unpickle_override('sage.categories.category_types', 'ModularAbelianVarieties', ModularAbelianVarieties) +register_unpickle_override('sage.categories.category_types', 'HeckeModules', + HeckeModules) +register_unpickle_override('sage.categories.category_types', 'Objects', + Objects) +register_unpickle_override('sage.categories.category_types', 'Rings', + Rings) +register_unpickle_override('sage.categories.category_types', 'Fields', + Fields) +register_unpickle_override('sage.categories.category_types', 'VectorSpaces', + VectorSpaces) +register_unpickle_override('sage.categories.category_types', + 'Schemes_over_base', + sage.categories.schemes.Schemes_over_base) +register_unpickle_override('sage.categories.category_types', + 'ModularAbelianVarieties', + ModularAbelianVarieties) register_unpickle_override('sage.libs.pari.gen_py', 'pari', pari) # Cache the contents of star imports. sage.misc.lazy_import.save_cache_file() -### Debugging for Singular, see trac #10903 +# ##### Debugging for Singular, see issue #10903 # from sage.libs.singular.ring import poison_currRing # sys.settrace(poison_currRing) @@ -226,7 +237,7 @@ sage.misc.lazy_import.finish_startup() -### Python broke large ints; see trac #34506 +# Python broke large ints; see trac #34506 if hasattr(sys, "set_int_max_str_digits"): sys.set_int_max_str_digits(0) diff --git a/src/sage/all__sagemath_repl.py b/src/sage/all__sagemath_repl.py index e2866352cf6..c830950c26b 100644 --- a/src/sage/all__sagemath_repl.py +++ b/src/sage/all__sagemath_repl.py @@ -22,7 +22,7 @@ warnings.filterwarnings('ignore', category=DeprecationWarning, module='(IPython|ipykernel|jupyter_client|jupyter_core|nbformat|notebook|ipywidgets|storemagic|jedi)') -# scipy 1.18 introduced reprecation warnings on a number of things they are moving to +# scipy 1.18 introduced deprecation warnings on a number of things they are moving to # numpy, e.g. DeprecationWarning: scipy.array is deprecated # and will be removed in SciPy 2.0.0, use numpy.array instead # This affects networkx 2.2 up and including 2.4 (cf. :issue:29766) diff --git a/src/sage/arith/functions.pyx b/src/sage/arith/functions.pyx index 92dbc709897..c87dc1e67c7 100644 --- a/src/sage/arith/functions.pyx +++ b/src/sage/arith/functions.pyx @@ -30,7 +30,7 @@ def lcm(a, b=None): - ``a``, ``b`` -- two elements of a ring with lcm or - - ``a`` -- a list, tuple or iterable of elements of a ring with lcm + - ``a`` -- list; tuple or iterable of elements of a ring with lcm OUTPUT: diff --git a/src/sage/arith/long.pxd b/src/sage/arith/long.pxd index 44923f802da..5330776b3bf 100644 --- a/src/sage/arith/long.pxd +++ b/src/sage/arith/long.pxd @@ -31,9 +31,9 @@ cdef inline long pyobject_to_long(x) except? LONG_MIN: r""" Given a Python object ``x`` cast it quickly to a C long. - A :class:`TypeError` is raised if the input cannot be converted to + A :exc:`TypeError` is raised if the input cannot be converted to an integer or - an :class:`OverflowError` is raised if it does not fit into a C long. + an :exc:`OverflowError` is raised if it does not fit into a C long. TESTS: @@ -96,18 +96,18 @@ cdef inline bint integer_check_long(x, long* value, int* err) except -1: Possible errors when returning ``True``: - - ``0``: ``x`` was successfully converted to a C long and its value - is stored in ``*value``. + - ``0`` -- ``x`` was successfully converted to a C long and its value + is stored in ``*value`` - - ``ERR_OVERFLOW``: ``x`` is an integer type but too large to store - in a C long. + - ``ERR_OVERFLOW`` -- ``x`` is an integer type but too large to store + in a C long Possible errors when returning ``False``: - - ``ERR_TYPE``: ``x`` is not an integer type of any kind. + - ``ERR_TYPE`` -- ``x`` is not an integer type of any kind - - ``ERR_INDEX``: ``x`` implements ``__index__`` but a :class:`TypeError` - was raised calling ``__index__()``. + - ``ERR_INDEX`` -- ``x`` implements ``__index__`` but a :exc:`TypeError` + was raised calling ``__index__()`` - Other exceptions in ``__index__`` are simply propagated. This is the only way this function can raise an exception. @@ -225,7 +225,7 @@ cdef inline long dig(const digit* D, int n) noexcept: cdef inline bint integer_check_long_py(x, long* value, int* err) noexcept: """ - Return whether ``x`` is a python object of type ``int``. + Return whether ``x`` is a Python object of type ``int``. If possible, compute the value of this integer as C long and store it in ``*value``. @@ -235,15 +235,15 @@ cdef inline bint integer_check_long_py(x, long* value, int* err) noexcept: Possible errors when returning ``True``: - - ``0``: ``x`` was successfully converted to a C long and its value - is stored in ``*value``. + - ``0`` -- ``x`` was successfully converted to a C long and its value + is stored in ``*value`` - - ``ERR_OVERFLOW``: ``x`` is a python object of type ``int`` but - too large to store in a C long. + - ``ERR_OVERFLOW`` -- ``x`` is a Python object of type ``int`` but + too large to store in a C long Possible errors when returning ``False``: - - ``ERR_TYPE``: ``x`` is not a python object of type ``int``. + - ``ERR_TYPE`` -- ``x`` is not a Python object of type ``int`` EXAMPLES: diff --git a/src/sage/arith/meson.build b/src/sage/arith/meson.build new file mode 100644 index 00000000000..3c3656c5738 --- /dev/null +++ b/src/sage/arith/meson.build @@ -0,0 +1,34 @@ +py.install_sources( + 'all.py', + 'all__sagemath_objects.py', + 'constants.pxd', + 'functions.pxd', + 'long.pxd', + 'misc.py', + 'multi_modular.pxd', + 'numerical_approx.pxd', + 'power.pxd', + 'rational_reconstruction.pxd', + subdir: 'sage/arith', +) + +extension_data = { + 'functions' : files('functions.pyx'), + 'multi_modular' : files('multi_modular.pyx'), + 'numerical_approx' : files('numerical_approx.pyx'), + 'power' : files('power.pyx'), + 'rational_reconstruction' : files('rational_reconstruction.pyx'), + 'srange' : files('srange.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/arith', + install: true, + include_directories: [inc_cpython, inc_ext, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 28f81d7b798..745d5fcbbe7 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -23,6 +23,7 @@ from sage.structure.element import parent from sage.structure.coerce import py_scalar_to_element +from sage.structure.sequence import Sequence from sage.rings.integer import Integer, GCD_list from sage.rings.integer_ring import ZZ @@ -57,7 +58,7 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, is not found, then ``None`` will be returned. If ``proof=True`` then the result is returned only if it can be proved correct (i.e. the only possible minimal polynomial satisfying the height bound, or no - such polynomial exists). Otherwise a :class:`ValueError` is raised + such polynomial exists). Otherwise a :exc:`ValueError` is raised indicating that higher precision is required. ALGORITHM: Uses LLL for real/complex inputs, PARI C-library @@ -67,16 +68,14 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, INPUT: + - ``z`` -- real, complex, or `p`-adic number - - ``z`` -- real, complex, or `p`-adic number + - ``degree`` -- integer - - ``degree`` -- an integer - - - ``height_bound`` -- an integer (default: ``None``) specifying the maximum - coefficient size for the returned polynomial - - - ``proof`` -- a boolean (default: ``False``), requires height_bound to be set + - ``height_bound`` -- integer (default: ``None``); specifying the maximum + coefficient size for the returned polynomial + - ``proof`` -- boolean (default: ``False``); requires height_bound to be set EXAMPLES:: @@ -252,7 +251,7 @@ def norm(v): if max(abs(a) for a in coeffs) > height_bound: if proof: # Given an LLL reduced basis $b_1, ..., b_n$, we only - # know that $|b_1| <= 2^((n-1)/2) |x|$ for non-zero $x \in L$. + # know that $|b_1| <= 2^((n-1)/2) |x|$ for nonzero $x \in L$. if norm(LLL[0]) <= 2**((n - 1) / 2) * n.sqrt() * height_bound: raise ValueError("insufficient precision for non-existence proof") return None @@ -280,11 +279,11 @@ def norm(v): def bernoulli(n, algorithm='default', num_threads=1): r""" - Return the n-th Bernoulli number, as a rational number. + Return the `n`-th Bernoulli number, as a rational number. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``algorithm``: - ``'default'`` -- use 'flint' for n <= 20000, then 'arb' for n <= 300000 @@ -404,15 +403,15 @@ def factorial(n, algorithm='gmp'): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``algorithm`` -- string (default: 'gmp'): + - ``algorithm`` -- string (default: ``'gmp'``): - - ``'gmp'`` -- use the GMP C-library factorial function + - ``'gmp'`` -- use the GMP C-library factorial function - - ``'pari'`` -- use PARI's factorial function + - ``'pari'`` -- use PARI's factorial function - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -575,15 +574,15 @@ def is_prime(n) -> bool: def is_pseudoprime(n): r""" - Test whether ``n`` is a pseudo-prime + Test whether ``n`` is a pseudo-prime. The result is *NOT* proven correct - *this is a pseudo-primality test!*. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - .. note:: + .. NOTE:: We do not consider negatives of prime numbers as prime. @@ -610,14 +609,14 @@ def is_pseudoprime(n): def is_prime_power(n, get_data=False): r""" - Test whether ``n`` is a positive power of a prime number + Test whether ``n`` is a positive power of a prime number. This function simply calls the method :meth:`Integer.is_prime_power() ` of Integers. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``get_data`` -- if set to ``True``, return a pair ``(p,k)`` such that this integer equals ``p^k`` instead of ``True`` or ``(self,0)`` instead of @@ -688,10 +687,11 @@ def is_pseudoprime_power(n, get_data=False): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``get_data`` -- (boolean) instead of a boolean return a pair `(p,k)` so - that ``n`` equals `p^k` and `p` is a pseudoprime or `(n,0)` otherwise. + - ``get_data`` -- boolean (default: ``False``); instead of a boolean return + a pair `(p,k)` so that ``n`` equals `p^k` and `p` is a pseudoprime or + `(n,0)` otherwise EXAMPLES:: @@ -814,12 +814,12 @@ def prime_powers(start, stop=None): INPUT: - - ``start`` -- an integer. If two inputs are given, a lower bound + - ``start`` -- integer; if two inputs are given, a lower bound for the returned set of prime powers. If this is the only input, then it is an upper bound. - - ``stop`` -- an integer (default: ``None``). An upper bound for the - returned set of prime powers. + - ``stop`` -- integer (default: ``None``); an upper bound for the + returned set of prime powers OUTPUT: @@ -934,11 +934,9 @@ def primes_first_n(n, leave_pari=False): INPUT: - - `n` -- a nonnegative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - a list of the first `n` prime numbers. + OUTPUT: list of the first `n` prime numbers EXAMPLES:: @@ -970,11 +968,9 @@ def eratosthenes(n): INPUT: - - ``n`` -- a positive integer - - OUTPUT: + - ``n`` -- positive integer - - a list of primes less than or equal to n. + OUTPUT: list of primes less than or equal to `n` EXAMPLES:: @@ -1038,21 +1034,18 @@ def primes(start=2, stop=None, proof=None): INPUT: - - ``start`` -- an integer (default: 2) lower bound for the primes + - ``start`` -- integer (default: 2); lower bound for the primes - - ``stop`` -- an integer (or infinity) upper (open) bound for the + - ``stop`` -- integer (or infinity); upper (open) bound for the primes - - ``proof`` -- bool or ``None`` (default: ``None``) If ``True``, the + - ``proof`` -- boolean or ``None`` (default: ``None``); if ``True``, the function yields only proven primes. If ``False``, the function uses a pseudo-primality test, which is much faster for really big numbers but does not provide a proof of primality. If ``None``, uses the global default (see :mod:`sage.structure.proof.proof`) - OUTPUT: - - - an iterator over primes from ``start`` to ``stop-1``, inclusive - + OUTPUT: an iterator over primes from ``start`` to ``stop-1``, inclusive EXAMPLES:: @@ -1178,9 +1171,7 @@ def next_probable_prime(n): INPUT: - - - ``n`` -- an integer - + - ``n`` -- integer EXAMPLES:: @@ -1208,19 +1199,17 @@ def next_probable_prime(n): def next_prime(n, proof=None): """ - The next prime greater than the integer n. If n is prime, then this - function does not return n, but the next prime after n. If the - optional argument proof is False, this function only returns a + The next prime greater than the integer `n`. If `n` is prime, then this + function does not return `n`, but the next prime after `n`. If the + optional argument proof is ``False``, this function only returns a pseudo-prime, as defined by the PARI nextprime function. If it is - None, uses the global default (see :mod:`sage.structure.proof.proof`) + ``None``, uses the global default (see :mod:`sage.structure.proof.proof`) INPUT: + - ``n`` -- integer - - ``n`` -- integer - - - ``proof`` -- bool or None (default: None) - + - ``proof`` -- boolean or ``None`` (default: ``None``) EXAMPLES:: @@ -1260,7 +1249,7 @@ def next_prime(n, proof=None): def previous_prime(n): """ The largest prime < n. The result is provably correct. If n <= 1, - this function raises a ValueError. + this function raises a :exc:`ValueError`. EXAMPLES:: @@ -1395,14 +1384,14 @@ def random_prime(n, proof=None, lbound=2): INPUT: - - ``n`` -- an integer `\geq 2`. + - ``n`` -- integer `\geq 2` - - ``proof`` -- bool or ``None`` (default: ``None``) If ``False``, the function uses a - pseudo-primality test, which is much faster for really big numbers but - does not provide a proof of primality. If ``None``, uses the global default - (see :mod:`sage.structure.proof.proof`) + - ``proof`` -- boolean or ``None`` (default: ``None``); if ``False``, the function uses a + pseudo-primality test, which is much faster for really big numbers but + does not provide a proof of primality. If ``None``, uses the global default + (see :mod:`sage.structure.proof.proof`) - - ``lbound`` -- an integer `\geq 2`, lower bound for the chosen primes + - ``lbound`` -- integer; `\geq 2`, lower bound for the chosen primes EXAMPLES:: @@ -1507,7 +1496,7 @@ def divisors(n): INPUT: - - ``n`` -- the element + - ``n`` -- the element EXAMPLES: @@ -1590,15 +1579,13 @@ def divisors(n): class Sigma: """ - Return the sum of the k-th powers of the divisors of n. + Return the sum of the `k`-th powers of the divisors of `n`. INPUT: + - ``n`` -- integer - - ``n`` -- integer - - - ``k`` -- integer (default: 1) - + - ``k`` -- integer (default: 1) OUTPUT: integer @@ -1615,7 +1602,7 @@ class Sigma: sage: P = plot(sigma, 1, 100) # needs sage.plot - This method also works with k-th powers. + This method also works with `k`-th powers. :: @@ -1654,7 +1641,7 @@ class Sigma: def __repr__(self): """ A description of this class, which computes the sum of the - k-th powers of the divisors of n. + `k`-th powers of the divisors of `n`. EXAMPLES:: @@ -1666,7 +1653,7 @@ def __repr__(self): def __call__(self, n, k=1): """ - Computes the sum of (the k-th powers of) the divisors of n. + Compute the sum of (the `k`-th powers of) the divisors of `n`. EXAMPLES:: @@ -1693,25 +1680,23 @@ def __call__(self, n, k=1): def plot(self, xmin=1, xmax=50, k=1, pointsize=30, rgbcolor=(0,0,1), join=True, **kwds): """ - Plot the sigma (sum of k-th powers of divisors) function. + Plot the sigma (sum of `k`-th powers of divisors) function. INPUT: + - ``xmin`` -- (default: 1) - - ``xmin`` -- default: 1 - - - ``xmax`` -- default: 50 + - ``xmax`` -- (default: 50) - - ``k`` -- default: 1 + - ``k`` -- (default: 1) - - ``pointsize`` -- default: 30 + - ``pointsize`` -- (default: 30) - - ``rgbcolor`` -- default: (0,0,1) + - ``rgbcolor`` -- (default: (0,0,1)) - - ``join`` -- default: ``True``; whether to join the - points. + - ``join`` -- (default: ``True``) whether to join the points - - ``**kwds`` -- passed on + - ``**kwds`` -- passed on EXAMPLES:: @@ -1742,7 +1727,7 @@ def gcd(a, b=None, **kwargs): - ``a``, ``b`` -- two elements of a ring with gcd or - - ``a`` -- a list or tuple of elements of a ring with gcd + - ``a`` -- list or tuple of elements of a ring with gcd Additional keyword arguments are passed to the respectively called methods. @@ -1869,15 +1854,13 @@ def gcd(a, b=None, **kwargs): def __GCD_sequence(v, **kwargs): """ - Internal function returning the gcd of the elements of a sequence + Internal function returning the gcd of the elements of a sequence. INPUT: + - ``v`` -- a sequence (possibly empty) - - ``v`` -- A sequence (possibly empty) - - - OUTPUT: The gcd of the elements of the sequence as an element of + OUTPUT: the gcd of the elements of the sequence as an element of the sequence's universe, or the integer 0 if the sequence is empty. @@ -1955,27 +1938,43 @@ def xlcm(m, n): return (l, m, n) -def xgcd(a, b): +def xgcd(a, b=None): r""" - Return a triple ``(g,s,t)`` such that `g = s\cdot a+t\cdot b = \gcd(a,b)`. + Return the greatest common divisor and the Bézout coefficients of the input arguments. + + When both ``a`` and ``b`` are given, then return a triple ``(g,s,t)`` + such that `g = s\cdot a+t\cdot b = \gcd(a,b)`. + When only ``a`` is given, then return a tuple ``r`` of length ``len(a) + 1`` + such that `r_0 = \sum_{i = 0}^{len(a) - 1} r_{i + 1}a_i = gcd(a_0, \dots, a_{len(a) - 1})` .. NOTE:: - One exception is if `a` and `b` are not in a principal ideal domain (see + One exception is if the elements are not in a principal ideal domain (see :wikipedia:`Principal_ideal_domain`), e.g., they are both polynomials over the integers. Then this function can't in general return ``(g,s,t)`` - as above, since they need not exist. Instead, over the integers, we - first multiply `g` by a divisor of the resultant of `a/g` and `b/g`, up - to sign. + or ``r`` as above, since they need not exist. Instead, over the integers, + when ``a`` and ``b`` are given, we first multiply `g` by a divisor of the + resultant of `a/g` and `b/g`, up to sign. INPUT: + One of the following: + - ``a, b`` -- integers or more generally, element of a ring for which the xgcd make sense (e.g. a field or univariate polynomials). + - ``a`` -- a list or tuple of at least two integers or more generally, elements + of a ring which the xgcd make sense. + OUTPUT: - - ``g, s, t`` -- such that `g = s\cdot a + t\cdot b` + One of the following: + + - ``g, s, t`` -- when two inputs ``a, b`` are given. They satisfy `g = s\cdot a + t\cdot b`. + + - ``r`` -- a tuple, when only ``a`` is given (and ``b = None``). Its first entry ``r[0]`` is the gcd of the inputs, + and has length one longer than the length of ``a``. + Its entries satisfy `r_0 = \sum_{i = 0}^{len(a) - 1} r_{i + 1}a_i`. .. NOTE:: @@ -1988,6 +1987,16 @@ def xgcd(a, b): (4, 4, -5) sage: 4*56 + (-5)*44 4 + sage: xgcd([56, 44]) + (4, 4, -5) + sage: r = xgcd([30, 105, 70, 42]); r + (1, -255, 85, -17, -2) + sage: (-255)*30 + 85*105 + (-17)*70 + (-2)*42 + 1 + sage: xgcd([]) + (0,) + sage: xgcd([42]) + (42, 1) sage: g, a, b = xgcd(5/1, 7/1); g, a, b (1, 3, -2) @@ -1997,6 +2006,10 @@ def xgcd(a, b): sage: x = polygen(QQ) sage: xgcd(x^3 - 1, x^2 - 1) (x - 1, 1, -x) + sage: g, a, b, c = xgcd([x^4 - x, x^6 - 1, x^4 - 1]); g, a, b, c + (x - 1, x^3, -x, 1) + sage: a*(x^4 - x) + b*(x^6 - 1) + c*(x^4 - 1) == g + True sage: K. = NumberField(x^2 - 3) # needs sage.rings.number_field sage: g.xgcd(g + 2) # needs sage.rings.number_field @@ -2028,11 +2041,15 @@ def xgcd(a, b): (4, 1, 0) sage: xgcd(int8(4), int8(8)) # needs numpy (4, 1, 0) + sage: xgcd([int8(4), int8(8), int(10)]) # needs numpy + (2, -2, 0, 1) sage: from gmpy2 import mpz sage: xgcd(mpz(4), mpz(8)) (4, 1, 0) sage: xgcd(4, mpz(8)) (4, 1, 0) + sage: xgcd([4, mpz(8), mpz(10)]) + (2, -2, 0, 1) TESTS: @@ -2044,19 +2061,48 @@ def xgcd(a, b): sage: S. = R.fraction_field()[] sage: xgcd(y^2, a*h*y + b) (1, 7*a^2/b^2, (((-h)*a)/b^2)*y + 1/b) + + Tests with randomly generated integers:: + + sage: import numpy as np + sage: N, M = 1000, 10000 + sage: a = np.random.randint(M, size=N) * np.random.randint(M) + sage: r = xgcd(a) + sage: len(r) == len(a) + 1 + True + sage: r[0] == gcd(a) + True + sage: sum(c * x for c, x in zip(r[1:], a)) == gcd(a) + True """ - try: + if b is not None: + # xgcd of two elements + try: + return a.xgcd(b) + except AttributeError: + a = py_scalar_to_element(a) + b = py_scalar_to_element(b) + except TypeError: + b = py_scalar_to_element(b) return a.xgcd(b) - except AttributeError: - a = py_scalar_to_element(a) - b = py_scalar_to_element(b) - except TypeError: - b = py_scalar_to_element(b) - return a.xgcd(b) + + # xgcd for several elements (possibly more than one) + if len(a) == 0: + return (ZZ(0),) + a = Sequence(a, use_sage_types=True) + res = [a.universe().zero()] + for b in a: + g, s, t = xgcd(res[0], b) + res[0] = g + for i in range(1, len(res)): + res[i] *= s + res.append(t) + return tuple(res) XGCD = xgcd + # def XGCD_python(a, b): # """ # Return triple (g,p,q) such that g = p*a+b*q = GCD(a,b). @@ -2098,7 +2144,7 @@ def xkcd(n=""): INPUT: - - ``n`` -- an integer (optional) + - ``n`` -- integer (optional) OUTPUT: a fragment of HTML @@ -2277,7 +2323,7 @@ def power_mod(a, n, m): sage: from numpy import int32 # needs numpy sage: power_mod(int32(2), int32(390), int32(391)) # needs numpy - 285 + ...285... sage: from gmpy2 import mpz sage: power_mod(mpz(2), mpz(390), mpz(391)) mpz(285) @@ -2319,7 +2365,7 @@ def rational_reconstruction(a, m, algorithm='fast'): lowest terms such that the reduction of `x/y` modulo `m` is equal to `a` and the absolute values of `x` and `y` are both `\le \sqrt{m/2}`. If such `x/y` exists, that pair is unique and this function returns it. If no - such pair exists, this function raises ZeroDivisionError. + such pair exists, this function raises :exc:`ZeroDivisionError`. An efficient algorithm for computing rational reconstruction is very similar to the extended Euclidean algorithm. For more details, @@ -2327,14 +2373,14 @@ def rational_reconstruction(a, m, algorithm='fast'): INPUT: - - ``a`` -- an integer + - ``a`` -- integer - ``m`` -- a modulus - - ``algorithm`` -- (default: 'fast') + - ``algorithm`` -- string (default: ``'fast'``) - - ``'fast'`` -- a fast implementation using direct GMP library calls - in Cython. + - ``'fast'`` -- a fast implementation using direct GMP library calls + in Cython OUTPUT: @@ -2391,7 +2437,7 @@ def rational_reconstruction(a, m, algorithm='fast'): Traceback (most recent call last): ... ZeroDivisionError: rational reconstruction with zero modulus - sage: rational_reconstruction(0, 1, algorithm="foobar") + sage: rational_reconstruction(0, 1, algorithm='foobar') Traceback (most recent call last): ... ValueError: unknown algorithm 'foobar' @@ -2419,7 +2465,7 @@ def mqrr_rational_reconstruction(u, m, T): INPUT: - - ``u``, ``m``, ``T`` -- integers such that `m > u \ge 0`, `T > 0` + - ``u``, ``m``, ``T`` -- integers such that `m > u \ge 0`, `T > 0` OUTPUT: @@ -2472,22 +2518,19 @@ def mqrr_rational_reconstruction(u, m, T): def trial_division(n, bound=None): - """ - Return the smallest prime divisor <= bound of the positive integer - n, or n if there is no such prime. If the optional argument bound - is omitted, then bound <= n. + r""" + Return the smallest prime divisor less than or equal to ``bound`` of the + positive integer `n`, or `n` if there is no such prime. If the optional + argument bound is omitted, then bound `\leq n`. INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``bound`` -- (optional) a positive integer - - OUTPUT: - - - ``int`` -- a prime p=bound that divides n, or n if - there is no such prime. + - ``bound`` -- (optional) positive integer + OUTPUT: a prime ``p=bound`` that divides `n`, or `n` if + there is no such prime EXAMPLES:: @@ -2546,29 +2589,27 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): INPUT: - - ``n`` -- a nonzero integer + - ``n`` -- nonzero integer - - ``proof`` -- bool or ``None`` (default: ``None``) + - ``proof`` -- boolean or ``None`` (default: ``None``) - - ``int_`` -- bool (default: ``False``) whether to return - answers as Python ints + - ``int_`` -- boolean (default: ``False``); whether to return + answers as Python integers - - ``algorithm`` -- string + - ``algorithm`` -- string - - ``'pari'`` -- (default) use the PARI c library + - ``'pari'`` -- (default) use the PARI C library - ``'kash'`` -- use KASH computer algebra system (requires that kash be installed) - ``'magma'`` -- use Magma (requires magma be installed) - - ``verbose`` -- integer (default: 0); PARI's debug - variable is set to this; e.g., set to 4 or 8 to see lots of output - during factorization. - - OUTPUT: + - ``verbose`` -- integer (default: 0); PARI's debug + variable is set to this. E.g., set to 4 or 8 to see lots of output + during factorization. - - factorization of `n` + OUTPUT: factorization of `n` The qsieve and ecm commands give access to highly optimized implementations of algorithms for doing certain integer @@ -2845,17 +2886,17 @@ def odd_part(n): def prime_to_m_part(n, m): """ - Return the prime-to-``m`` part of ``n``. + Return the prime-to-`m` part of `n`. - This is the largest divisor of ``n`` that is coprime to ``m``. + This is the largest divisor of `n` that is coprime to `m`. INPUT: - - ``n`` -- Integer (nonzero) + - ``n`` -- integer (nonzero) - - ``m`` -- Integer + - ``m`` -- integer - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -2887,14 +2928,14 @@ def prime_to_m_part(n, m): def is_square(n, root=False): """ - Return whether or not ``n`` is square. + Return whether or not `n` is square. - If ``n`` is a square also return the square root. - If ``n`` is not square, also return ``None``. + If `n` is a square also return the square root. + If `n` is not square, also return ``None``. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``root`` -- whether or not to also return a square root (default: ``False``) @@ -2904,7 +2945,7 @@ def is_square(n, root=False): - ``bool`` -- whether or not a square - ``object`` -- (optional) an actual square if found, - and ``None`` otherwise. + and ``None`` otherwise EXAMPLES:: @@ -3032,16 +3073,14 @@ def is_squarefree(n): ################################################################# class Euler_Phi: r""" - Return the value of the Euler phi function on the integer n. We + Return the value of the Euler phi function on the integer `n`. We defined this to be the number of positive integers <= n that are - relatively prime to n. Thus if n<=0 then + relatively prime to `n`. Thus if `n \leq 0` then ``euler_phi(n)`` is defined and equals 0. INPUT: - - - ``n`` -- an integer - + - ``n`` -- integer EXAMPLES:: @@ -3056,10 +3095,7 @@ class Euler_Phi: sage: euler_phi(37) # needs sage.libs.pari 36 - Notice that euler_phi is defined to be 0 on negative numbers and - 0. - - :: + Notice that ``euler_phi`` is defined to be 0 on negative numbers and 0:: sage: euler_phi(-1) 0 @@ -3068,26 +3104,20 @@ class Euler_Phi: sage: type(euler_phi(0)) - We verify directly that the phi function is correct for 21. - - :: + We verify directly that the phi function is correct for 21:: sage: euler_phi(21) # needs sage.libs.pari 12 sage: [i for i in range(21) if gcd(21,i) == 1] [1, 2, 4, 5, 8, 10, 11, 13, 16, 17, 19, 20] - The length of the list of integers 'i' in range(n) such that the - gcd(i,n) == 1 equals euler_phi(n). - - :: + The length of the list of integers 'i' in ``range(n)`` such that the + ``gcd(i,n) == 1`` equals ``euler_phi(n)``:: sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) # needs sage.libs.pari True - The phi function also has a special plotting method. - - :: + The phi function also has a special plotting method:: sage: P = plot(euler_phi, -3, 71) # needs sage.libs.pari sage.plot @@ -3120,7 +3150,7 @@ def __repr__(self): def __call__(self, n): """ - Calls the euler_phi function. + Call the ``euler_phi`` function. EXAMPLES:: @@ -3144,19 +3174,17 @@ def plot(self, xmin=1, xmax=50, pointsize=30, rgbcolor=(0, 0, 1), INPUT: + - ``xmin`` -- (default: 1) - - ``xmin`` -- default: 1 + - ``xmax`` -- (default: 50) - - ``xmax`` -- default: 50 + - ``pointsize`` -- (default: 30) - - ``pointsize`` -- default: 30 + - ``rgbcolor`` -- (default: (0,0,1)) - - ``rgbcolor`` -- default: (0,0,1) + - ``join`` -- boolean (default: ``True``); whether to join the points - - ``join`` -- default: ``True``; whether to join the - points. - - - ``**kwds`` -- passed on + - ``**kwds`` -- passed on EXAMPLES:: @@ -3187,11 +3215,9 @@ def carmichael_lambda(n): INPUT: - - ``n`` -- a positive integer. - - OUTPUT: + - ``n`` -- positive integer - - The Carmichael function of ``n``. + OUTPUT: the Carmichael function of ``n`` ALGORITHM: @@ -3334,9 +3360,9 @@ def crt(a, b, m=None, n=None): - ``a``, ``b`` -- two residues (elements of some ring for which extended gcd is available), or two lists, one of residues and - one of moduli. + one of moduli - - ``m``, ``n`` -- (default: ``None``) two moduli, or ``None``. + - ``m``, ``n`` -- (default: ``None``) two moduli, or ``None`` OUTPUT: @@ -3577,7 +3603,7 @@ def CRT_basis(moduli): INPUT: - ``moduli`` -- list of pairwise coprime moduli `m` which admit an - extended Euclidean algorithm + extended Euclidean algorithm OUTPUT: @@ -3626,13 +3652,11 @@ def CRT_vectors(X, moduli): INPUT: - - ``X`` -- list or tuple, consisting of lists/tuples/vectors/etc of - integers of the same length - - ``moduli`` -- list of len(X) moduli - - OUTPUT: + - ``X`` -- list or tuple, consisting of lists/tuples/vectors/etc of + integers of the same length + - ``moduli`` -- list of len(X) moduli - - ``list`` -- application of CRT componentwise. + OUTPUT: list; application of CRT componentwise EXAMPLES:: @@ -3655,7 +3679,7 @@ def CRT_vectors(X, moduli): def binomial(x, m, **kwds): r""" - Return the binomial coefficient + Return the binomial coefficient. .. MATH:: @@ -3673,8 +3697,8 @@ def binomial(x, m, **kwds): INPUT: - - ``x``, ``m`` -- numbers or symbolic expressions. Either ``m`` - or ``x-m`` must be an integer. + - ``x``, ``m`` -- numbers or symbolic expressions; either ``m`` + or ``x-m`` must be an integer OUTPUT: number or symbolic expression (if input is symbolic) @@ -3799,7 +3823,7 @@ def binomial(x, m, **kwds): sage: binomial(n,2) # needs sage.symbolic 1/2*(n - 1)*n - Test p-adic numbers:: + Test `p`-adic numbers:: sage: binomial(Qp(3)(-1/2),4) # p-adic number with valuation >= 0 1 + 3 + 2*3^2 + 3^3 + 2*3^4 + 3^6 + 3^7 + 3^8 + 3^11 + 2*3^14 + 2*3^16 + 2*3^17 + 2*3^19 + O(3^20) @@ -3933,9 +3957,7 @@ def multinomial(*ks): - either an arbitrary number of integer arguments `k_1,\dots,k_n` - or an iterable (e.g. a list) of integers `[k_1,\dots,k_n]` - OUTPUT: - - Return the integer: + OUTPUT: the integer: .. MATH:: @@ -4002,11 +4024,9 @@ def binomial_coefficients(n): INPUT: + - ``n`` -- integer - - ``n`` -- an integer - - - OUTPUT: dict + OUTPUT: dictionary EXAMPLES:: @@ -4050,10 +4070,10 @@ def multinomial_coefficients(m, n): INPUT: - - ``m`` -- integer - - ``n`` -- integer + - ``m`` -- integer + - ``n`` -- integer - OUTPUT: dict + OUTPUT: dictionary EXAMPLES:: @@ -4161,9 +4181,7 @@ def kronecker_symbol(x,y): - ``y`` -- integer - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -4205,18 +4223,16 @@ def legendre_symbol(x, p): r""" The Legendre symbol `(x|p)`, for `p` prime. - .. note:: + .. NOTE:: The :func:`kronecker_symbol` command extends the Legendre symbol to composite moduli and `p=2`. INPUT: + - ``x`` -- integer - - ``x`` -- integer - - - ``p`` -- an odd prime number - + - ``p`` -- odd prime number EXAMPLES:: @@ -4257,12 +4273,12 @@ def legendre_symbol(x, p): def jacobi_symbol(a, b): r""" - The Jacobi symbol of integers a and b, where b is odd. + The Jacobi symbol of integers `a` and `b`, where `b` is odd. - .. note:: + .. NOTE:: The :func:`kronecker_symbol` command extends the Jacobi - symbol to all integers b. + symbol to all integers `b`. If @@ -4274,12 +4290,11 @@ def jacobi_symbol(a, b): where `(a|p_j)` are Legendre Symbols. - INPUT: - - ``a`` -- an integer + - ``a`` -- integer - - ``b`` -- an odd integer + - ``b`` -- odd integer EXAMPLES:: @@ -4311,15 +4326,15 @@ def primitive_root(n, check=True): """ Return a positive integer that generates the multiplicative group of integers modulo `n`, if one exists; otherwise, raise a - :class:`ValueError`. + :exc:`ValueError`. A primitive root exists if `n=4` or `n=p^k` or `n=2p^k`, where `p` is an odd prime and `k` is a nonnegative number. INPUT: - - ``n`` -- a non-zero integer - - ``check`` -- bool (default: ``True``); if False, then `n` is assumed + - ``n`` -- nonzero integer + - ``check`` -- boolean (default: ``True``); if ``False``, then `n` is assumed to be a positive integer possessing a primitive root, and behavior is undefined otherwise. @@ -4430,16 +4445,13 @@ def primitive_root(n, check=True): def nth_prime(n): """ - - Return the n-th prime number (1-indexed, so that 2 is the 1st prime.) + Return the `n`-th prime number (1-indexed, so that 2 is the 1st prime). INPUT: - - ``n`` -- a positive integer - - OUTPUT: + - ``n`` -- positive integer - - the n-th prime number + OUTPUT: the `n`-th prime number EXAMPLES:: @@ -4455,7 +4467,7 @@ def nth_prime(n): sage: nth_prime(0) Traceback (most recent call last): ... - ValueError: nth prime meaningless for non-positive n (=0) + ValueError: nth prime meaningless for nonpositive n (=0) TESTS:: @@ -4469,7 +4481,7 @@ def nth_prime(n): 29 """ if n <= 0: - raise ValueError("nth prime meaningless for non-positive n (=%s)" % n) + raise ValueError("nth prime meaningless for nonpositive n (=%s)" % n) from sage.libs.pari.all import pari return ZZ(pari.prime(n)) @@ -4523,9 +4535,7 @@ class Moebius: INPUT: - - - ``n`` -- anything that can be factored. - + - ``n`` -- anything that can be factored OUTPUT: 0, 1, or -1 @@ -4613,19 +4623,18 @@ def plot(self, xmin=0, xmax=50, pointsize=30, rgbcolor=(0,0,1), join=True, INPUT: + - ``xmin`` -- (default: 0) - - ``xmin`` -- default: 0 - - - ``xmax`` -- default: 50 + - ``xmax`` -- (default: 50) - - ``pointsize`` -- default: 30 + - ``pointsize`` -- (default: 30) - - ``rgbcolor`` -- default: (0,0,1) + - ``rgbcolor`` -- (default: (0,0,1)) - - ``join`` -- default: ``True``; whether to join the points - (very helpful in seeing their order). + - ``join`` -- (default: ``True``) whether to join the points + (very helpful in seeing their order) - - ``**kwds`` -- passed on + - ``**kwds`` -- passed on EXAMPLES:: @@ -4710,8 +4719,8 @@ def continuant(v, n=None): INPUT: - - ``v`` -- list or tuple of elements of a ring - - ``n`` -- optional integer + - ``v`` -- list or tuple of elements of a ring + - ``n`` -- (optional) integer OUTPUT: element of ring (integer, polynomial, etcetera). @@ -4778,16 +4787,14 @@ def continuant(v, n=None): def number_of_divisors(n): - """ - Return the number of divisors of the integer n. + r""" + Return the number of divisors of the integer `n`. INPUT: - - ``n`` -- a nonzero integer - - OUTPUT: + - ``n`` -- nonzero integer - - an integer, the number of divisors of n + OUTPUT: integer; the number of divisors of `n` EXAMPLES:: @@ -4812,7 +4819,7 @@ def number_of_divisors(n): return ZZ(pari(m).numdiv()) -def hilbert_symbol(a, b, p, algorithm="pari"): +def hilbert_symbol(a, b, p, algorithm='pari'): """ Return 1 if `ax^2 + by^2` `p`-adically represents a nonzero square, otherwise returns `-1`. If either a or b @@ -4820,22 +4827,20 @@ def hilbert_symbol(a, b, p, algorithm="pari"): INPUT: + - ``a``, ``b`` -- integers - - ``a, b`` -- integers - - - ``p`` -- integer; either prime or -1 (which - represents the archimedean place) + - ``p`` -- integer; either prime or -1 (which + represents the archimedean place) - - ``algorithm`` -- string + - ``algorithm`` -- string - - ``'pari'`` -- (default) use the PARI C library + - ``'pari'`` -- (default) use the PARI C library - - ``'direct'`` -- use a Python implementation + - ``'direct'`` -- use a Python implementation - - ``'all'`` -- use both PARI and direct and check that + - ``'all'`` -- use both PARI and direct and check that the results agree, then return the common answer - OUTPUT: integer (0, -1, or 1) EXAMPLES:: @@ -4940,9 +4945,7 @@ def hilbert_conductor(a, b): - ``a``, ``b`` -- integers - OUTPUT: - - squarefree positive integer + OUTPUT: squarefree positive integer EXAMPLES:: @@ -5087,11 +5090,11 @@ def falling_factorial(x, a): INPUT: - - ``x`` -- element of a ring + - ``x`` -- element of a ring - - ``a`` -- a non-negative integer or + - ``a`` -- nonnegative integer or - - ``x and a`` -- any numbers + - ``x``, ``a`` -- any numbers OUTPUT: the falling factorial @@ -5191,11 +5194,11 @@ def rising_factorial(x, a): INPUT: - - ``x`` -- element of a ring + - ``x`` -- element of a ring - - ``a`` -- a non-negative integer or + - ``a`` -- nonnegative integer or - - ``x and a`` -- any numbers + - ``x``, ``a`` -- any numbers OUTPUT: the rising factorial @@ -5304,10 +5307,10 @@ def integer_floor(x): INPUT: - - ``x`` -- an object that has a floor method or is - coercible to int + - ``x`` -- an object that has a floor method or is + coercible to integer - OUTPUT: an Integer + OUTPUT: integer EXAMPLES:: @@ -5346,7 +5349,7 @@ def integer_floor(x): def integer_trunc(i): """ - Truncate to the integer closer to zero + Truncate to the integer closer to zero. EXAMPLES:: @@ -5365,13 +5368,13 @@ def integer_trunc(i): def two_squares(n): """ Write the integer `n` as a sum of two integer squares if possible; - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: a tuple `(a,b)` of non-negative integers such that + OUTPUT: a tuple `(a,b)` of nonnegative integers such that `n = a^2 + b^2` with `a <= b`. EXAMPLES:: @@ -5487,13 +5490,13 @@ def two_squares(n): def three_squares(n): """ Write the integer `n` as a sum of three integer squares if possible; - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: a tuple `(a,b,c)` of non-negative integers such that + OUTPUT: a tuple `(a,b,c)` of nonnegative integers such that `n = a^2 + b^2 + c^2` with `a <= b <= c`. EXAMPLES:: @@ -5636,9 +5639,9 @@ def four_squares(n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: a tuple `(a,b,c,d)` of non-negative integers such that + OUTPUT: a tuple `(a,b,c,d)` of nonnegative integers such that `n = a^2 + b^2 + c^2 + d^2` with `a <= b <= c <= d`. EXAMPLES:: @@ -5708,15 +5711,15 @@ def four_squares(n): def sum_of_k_squares(k, n): """ Write the integer `n` as a sum of `k` integer squares if possible; - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. INPUT: - - ``k`` -- a non-negative integer + - ``k`` -- nonnegative integer - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: a tuple `(x_1, ..., x_k)` of non-negative integers such that + OUTPUT: a tuple `(x_1, ..., x_k)` of nonnegative integers such that their squares sum to `n`. EXAMPLES:: @@ -5762,7 +5765,7 @@ def sum_of_k_squares(k, n): sage: sum_of_k_squares(-1, 0) Traceback (most recent call last): ... - ValueError: k = -1 must be non-negative + ValueError: k = -1 must be nonnegative Tests with numpy and gmpy2 numbers:: @@ -5793,7 +5796,7 @@ def sum_of_k_squares(k, n): if n == 0: return tuple() raise ValueError("%s is not a sum of 0 squares" % n) - raise ValueError("k = %s must be non-negative" % k) + raise ValueError("k = %s must be nonnegative" % k) if n < 0: raise ValueError("%s is not a sum of %s squares" % (n,k)) @@ -5817,15 +5820,9 @@ def subfactorial(n): INPUT: + - ``n`` -- nonnegative integer - - ``n`` -- non negative integer - - - OUTPUT: - - - - ``integer`` -- function value - + OUTPUT: integer EXAMPLES:: @@ -5854,15 +5851,13 @@ def subfactorial(n): def is_power_of_two(n): r""" - Return whether ``n`` is a power of 2. + Return whether `n` is a power of 2. INPUT: - - ``n`` -- integer - - OUTPUT: + - ``n`` -- integer - boolean + OUTPUT: boolean EXAMPLES:: @@ -6041,11 +6036,9 @@ def fundamental_discriminant(D): INPUT: - - ``D`` -- an integer - - OUTPUT: + - ``D`` -- integer - - an integer, the fundamental discriminant + OUTPUT: integer; the fundamental discriminant EXAMPLES:: @@ -6084,8 +6077,8 @@ def squarefree_divisors(x): INPUT: - - x -- an element of any ring for which the prime_divisors - function works. + - ``x`` -- an element of any ring for which the prime_divisors + function works EXAMPLES: @@ -6155,12 +6148,12 @@ def dedekind_sum(p, q, algorithm='default'): INPUT: - - ``p``, ``q`` -- integers - - ``algorithm`` -- must be one of the following + - ``p``, ``q`` -- integers + - ``algorithm`` -- must be one of the following - - ``'default'`` -- (default) use FLINT - - ``'flint'`` -- use FLINT - - ``'pari'`` -- use PARI (gives different results if `p` and `q` + - ``'default'`` -- (default) use FLINT + - ``'flint'`` -- use FLINT + - ``'pari'`` -- use PARI (gives different results if `p` and `q` are not coprime) OUTPUT: a rational number @@ -6234,8 +6227,8 @@ def dedekind_sum(p, q, algorithm='default'): return flint_dedekind_sum(p, q) if algorithm == 'pari': - import sage.interfaces.gp - x = sage.interfaces.gp.gp('sumdedekind(%s,%s)' % (p, q)) + from sage.libs.pari import pari + x = pari.sumdedekind(p, q) return Rational(x) raise ValueError('unknown algorithm') @@ -6361,11 +6354,9 @@ def dedekind_psi(N): INPUT: - - ``N`` -- a positive integer - - OUTPUT: + - ``N`` -- positive integer - an integer + OUTPUT: integer The Dedekind psi function is the multiplicative function defined by @@ -6383,3 +6374,75 @@ def dedekind_psi(N): """ N = Integer(N) return Integer(N * prod(1 + 1 / p for p in N.prime_divisors())) + +def smooth_part(x, base): + r""" + Given an element ``x`` of a Euclidean domain and a factor base ``base``, + return a :class:`~sage.structure.factorization.Factorization` object + corresponding to the largest divisor of ``x`` that splits completely + over ``base``. + + The factor base can be specified in the following ways: + + - A sequence of elements. + + - A :class:`~sage.rings.generic.ProductTree` built from such a sequence. + (Caching the tree in the caller will speed things up if this function + is called multiple times with the same factor base.) + + EXAMPLES:: + + sage: from sage.arith.misc import smooth_part + sage: from sage.rings.generic import ProductTree + sage: smooth_part(10^77+1, primes(1000)) + 11^2 * 23 * 463 + sage: tree = ProductTree(primes(1000)) + sage: smooth_part(10^77+1, tree) + 11^2 * 23 * 463 + sage: smooth_part(10^99+1, tree) + 7 * 11^2 * 13 * 19 * 23 + """ + from sage.rings.generic import ProductTree + if isinstance(base, ProductTree): + tree = base + else: + tree = ProductTree(base) + fs = [] + rems = tree.remainders(x) + for j,(p,r) in enumerate(zip(tree, rems)): + if not r: + x //= p + v = 1 + while True: + y,r = divmod(x, p) + if r: + break + x = y + v += 1 + fs.append((p,v)) + from sage.structure.factorization import Factorization + return Factorization(fs) + +def coprime_part(x, base): + r""" + Given an element ``x`` of a Euclidean domain and a factor base ``base``, + return the largest divisor of ``x`` that is not divisible by any element + of ``base``. + + ALGORITHM: Divide `x` by the :func:`smooth_part`. + + EXAMPLES:: + + sage: from sage.arith.misc import coprime_part, smooth_part + sage: from sage.rings.generic import ProductTree + sage: coprime_part(10^77+1, primes(10000)) + 2159827213801295896328509719222460043196544298056155507343412527 + sage: tree = ProductTree(primes(10000)) + sage: coprime_part(10^55+1, tree) + 6426667196963538873896485804232411 + sage: coprime_part(10^55+1, tree).factor() + 20163494891 * 318727841165674579776721 + sage: prod(smooth_part(10^55+1, tree)) * coprime_part(10^55+1, tree) + 10000000000000000000000000000000000000000000000000000001 + """ + return x // prod(smooth_part(x, base)) diff --git a/src/sage/arith/multi_modular.pyx b/src/sage/arith/multi_modular.pyx index 583cf6cd9cc..1d5e9a46221 100644 --- a/src/sage/arith/multi_modular.pyx +++ b/src/sage/arith/multi_modular.pyx @@ -134,10 +134,8 @@ cdef class MultiModularBasis_base(): (their product will be at least 2*val) as list, tuple or generator a list of prime moduli to start with - - ``l_bound`` -- an integer: lower bound for the random primes - (default: 2^10) - - ``u_bound`` -- an integer: upper bound for the random primes - (default: 2^15) + - ``l_bound`` -- integer (default: 2^10); lower bound for the random primes + - ``u_bound`` -- integer (default: 2^15); upper bound for the random primes EXAMPLES:: @@ -186,13 +184,13 @@ cdef class MultiModularBasis_base(): cdef mod_int _new_random_prime(self, set known_primes) except 1: """ Choose a new random prime for inclusion in the list of moduli, - or raise a :class:`RuntimeError` if there are no more primes. + or raise a :exc:`RuntimeError` if there are no more primes. INPUT: - ``known_primes`` -- Python set of already known primes in the allowed interval; we will not return a prime in - known_primes. + known_primes """ cdef mod_int p while True: @@ -504,8 +502,8 @@ cdef class MultiModularBasis_base(): INPUT: - ``z`` -- the integer being reduced - - ``b`` -- array to hold the reductions mod each m_i. - It MUST be allocated and have length at least len + - ``b`` -- array to hold the reductions mod each `m_i`; + it *must* be allocated and have length at least len - ``offset`` -- first prime in list to reduce against - ``len`` -- number of primes in list to reduce against """ @@ -524,13 +522,12 @@ cdef class MultiModularBasis_base(): INPUT: - - ``z`` -- an array of integers being reduced - - ``b`` -- array to hold the reductions mod each m_i. - It MUST be fully allocated and each - have length at least len - - ``vn`` -- length of z and each b[i] + - ``z`` -- an array of integers being reduced + - ``b`` -- array to hold the reductions mod each m_i. + It *must* be fully allocated and each have length at least len. + - ``vn`` -- length of z and each b[i] - ``offset`` -- first prime in list to reduce against - - ``len`` -- number of primes in list to reduce against + - ``len`` -- number of primes in list to reduce against """ cdef int i, j cdef mod_int* m @@ -552,12 +549,12 @@ cdef class MultiModularBasis_base(): INPUT: - - ``z`` -- a placeholder for the constructed integer - z MUST be initialized IF and ONLY IF offset > 0 - - ``b`` -- array holding the reductions mod each m_i. - It MUST have length at least len + - ``z`` -- a placeholder for the constructed integer; *must* be + initialized if and only if ``offset > 0`` + - ``b`` -- array holding the reductions mod each m_i; *must* have + length at least ``len`` - ``offset`` -- first prime in list to reduce against - - ``len`` -- number of primes in list to reduce against + - ``len`` -- number of primes in list to reduce against """ cdef int i, s cdef mpz_t u @@ -568,7 +565,7 @@ cdef class MultiModularBasis_base(): s = 1 mpz_init_set_si(z, b[0]) if b[0] == 0: - while s < len and b[s] == 0: # fast forward to first non-zero + while s < len and b[s] == 0: # fast forward to first nonzero s += 1 else: s = 0 @@ -594,14 +591,14 @@ cdef class MultiModularBasis_base(): INPUT: - - ``z`` -- a placeholder for the constructed integers - z MUST be allocated and have length at least vc - z[j] MUST be initialized IF and ONLY IF offset > 0 - - ``b`` -- array holding the reductions mod each m_i. - MUST have length at least len - - ``vn`` -- length of z and each b[i] + - ``z`` -- a placeholder for the constructed integers; *must* be + allocated and have length at least ``vc``. z[j] *must* be initialized + if and only if ``offset > 0``. + - ``b`` -- array holding the reductions mod each m_i. *must* have + length at least ``len``. + - ``vn`` -- length of z and each b[i] - ``offset`` -- first prime in list to reduce against - - ``len`` -- number of primes in list to reduce against + - ``len`` -- number of primes in list to reduce against """ cdef int i, j cdef mpz_t u @@ -619,7 +616,7 @@ cdef class MultiModularBasis_base(): if offset == 0: mpz_set_si(z[j], b[0][j]) if b[0][j] == 0: - while i < len and b[i][j] == 0: # fast forward to first non-zero + while i < len and b[i][j] == 0: # fast forward to first nonzero i += 1 while i < len: mpz_set_si(u, ((b[i][j] + m[i] - mpz_fdiv_ui(z[j], m[i])) * self.C[i]) % m[i]) # u = ((b_i - z) * C_i) % m_i @@ -647,7 +644,7 @@ cdef class MultiModularBasis_base(): INPUT: - - ``b`` -- a list of length at most self.n + - ``b`` -- list of length at most self.n OUTPUT: @@ -667,7 +664,6 @@ cdef class MultiModularBasis_base(): 7 sage: res % 10039 9 - """ cdef int i, n n = len(b) @@ -723,7 +719,6 @@ cdef class MultiModularBasis_base(): Traceback (most recent call last): ... IndexError: negative index not valid - """ if n >= self.n: raise IndexError("beyond bound for multi-modular prime list") @@ -866,8 +861,8 @@ cdef class MultiModularBasis(MultiModularBasis_base): INPUT: - ``z`` -- the integer being reduced - - ``b`` -- array to hold the reductions mod each m_i. - It MUST be allocated and have length at least len + - ``b`` -- array to hold the reductions mod each `m_i`; it *must* be + allocated and have length at least len """ self.mpz_reduce_tail(z, b, 0, self.n) @@ -880,10 +875,9 @@ cdef class MultiModularBasis(MultiModularBasis_base): INPUT: - ``z`` -- an array of integers being reduced - - ``b`` -- array to hold the reductions mod each m_i. - It MUST be fully allocated and each - have length at least len - - ``vn`` -- length of z and each b[i] + - ``b`` -- array to hold the reductions mod each `m_i`; it *must* be + fully allocated and each have length at least len + - ``vn`` -- length of ``z`` and each ``b[i]`` """ self.mpz_reduce_vec_tail(z, b, vn, 0, self.n) @@ -895,10 +889,10 @@ cdef class MultiModularBasis(MultiModularBasis_base): INPUT: - - ``z`` -- a placeholder for the constructed integer - z MUST NOT be initialized - - ``b`` -- array holding the reductions mod each `m_i`. - It MUST have length at least len(self) + - ``z`` -- a placeholder for the constructed integer; *must not* be + initialized + - ``b`` -- array holding the reductions mod each `m_i`; it *must* have + length at least ``len(self)`` """ self.mpz_crt_tail(z, b, 0, self.n) @@ -910,12 +904,12 @@ cdef class MultiModularBasis(MultiModularBasis_base): INPUT: - - ``z`` -- a placeholder for the constructed integers - z MUST be allocated and have length at least vn, - but each z[j] MUST NOT be initialized - - ``b`` -- array holding the reductions mod each `m_i`. - It MUST have length at least len(self) - - ``vn`` -- length of z and each b[i] + - ``z`` -- a placeholder for the constructed integers; *must* be + allocated and have length at least vn,but each z[j] *must not* be + initialized + - ``b`` -- array holding the reductions mod each `m_i`; it *must* have + length at least ``len(self)`` + - ``vn`` -- length of ``z`` and each ``b[i]`` """ self.mpz_crt_vec_tail(z, b, vn, 0, self.n) diff --git a/src/sage/arith/rational_reconstruction.pyx b/src/sage/arith/rational_reconstruction.pyx index bd07977411a..6806cda3a00 100644 --- a/src/sage/arith/rational_reconstruction.pyx +++ b/src/sage/arith/rational_reconstruction.pyx @@ -35,7 +35,7 @@ cdef int mpq_rational_reconstruction(mpq_t answer, mpz_t a, mpz_t m) except -1: sqrt(m/2). If `m` is zero, raise :class`ZeroDivisionError`. If the rational - reconstruction does not exist, raise :class:`ValueError`. + reconstruction does not exist, raise :exc:`ValueError`. We assume that ``mpq_init`` has been called on ``answer``. diff --git a/src/sage/arith/srange.pyx b/src/sage/arith/srange.pyx index 51855f9646d..63a109c4b58 100644 --- a/src/sage/arith/srange.pyx +++ b/src/sage/arith/srange.pyx @@ -203,9 +203,9 @@ def srange(*args, **kwds): the form ``start + k*step`` for some integer `k`. ` ``endpoint_tolerance`` -- used to determine whether or not the - endpoint is hit for inexact rings (default 1e-5) + endpoint is hit for inexact rings (default: ``1e-5``) - OUTPUT: a list + OUTPUT: list .. NOTE:: diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index 57a72736ce9..7a3c50c569e 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -385,10 +385,10 @@ 2*pi Ensure that :issue:`25626` is fixed. As the form of the answer is dependent of -the giac version, we simplify it (see :issue:`34037`). :: +the giac version, we simplify it (see :issue:`34037`):: sage: t = SR.var('t') - sage: integrate(exp(t)/(t + 1)^2, t, algorithm="giac").full_simplify() + sage: integrate(exp(t)/(t + 1)^2, t, algorithm='giac').full_simplify() ((t + 1)*Ei(t + 1) - e^(t + 1))/(t*e + e) Check if maxima has redundant variables defined after initialization, @@ -407,7 +407,7 @@ 0.6321205588285577 sage: result = integral(exp(-300.0/(-0.064*x+14.0)),x,0.0,120.0) ... - sage: result + sage: result # abs tol 1e-10 4.62770039817000e-9 To check that :issue:`27092` is fixed:: @@ -468,7 +468,7 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False): - ``'sympy'`` -- use SymPy - - ``hold`` -- (default: ``False``) if ``True``, don't evaluate + - ``hold`` -- boolean (default: ``False``); if ``True``, don't evaluate EXAMPLES:: @@ -568,6 +568,7 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False): An example of this summation with Giac:: + sage: # needs giac sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac').factor() pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1)) @@ -609,7 +610,7 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False): sage: sum (n^3 * x^n, n, 0, infinity) (x^3 + 4*x^2 + x)/(x^4 - 4*x^3 + 6*x^2 - 4*x + 1) - .. note:: + .. NOTE:: Sage can currently only understand a subset of the output of Maxima, Maple and Mathematica, so even if the chosen backend can perform @@ -700,9 +701,7 @@ def nintegral(ex, x, a, b, - ``maximum_num_subintervals`` -- (default: 200) maximal number of subintervals - OUTPUT: - - - float: approximation to the integral + OUTPUT: float; approximation to the integral - float: estimated absolute error of the approximation @@ -845,13 +844,13 @@ def symbolic_product(expression, v, a, b, algorithm='maxima', hold=False): - ``'maxima'`` -- use Maxima (the default) - - ``'giac'`` -- use Giac + - ``'giac'`` -- use Giac (optional) - ``'sympy'`` -- use SymPy - ``'mathematica'`` -- (optional) use Mathematica - - ``hold`` -- (default: ``False``) if ``True``, don't evaluate + - ``hold`` -- boolean (default: ``False``); if ``True``, don't evaluate EXAMPLES:: @@ -880,7 +879,6 @@ def symbolic_product(expression, v, a, b, algorithm='maxima', hold=False): sage: symbolic_product(-x^2,x,1,n) (-1)^n*factorial(n)^2 - """ if not (isinstance(v, Expression) and v.is_symbol()): if isinstance(v, str): @@ -941,7 +939,7 @@ def minpoly(ex, var='x', algorithm=None, bits=None, degree=None, epsilon=0): INPUT: - - ``var`` -- polynomial variable name (default 'x') + - ``var`` -- polynomial variable name (default: ``'x'``) - ``algorithm`` -- ``'algebraic'`` or ``'numerical'`` (default both, but with numerical first) @@ -952,7 +950,7 @@ def minpoly(ex, var='x', algorithm=None, bits=None, degree=None, epsilon=0): - ``degree`` -- the expected algebraic degree - ``epsilon`` -- return without error as long as - f(self) epsilon, in the case that the result cannot be proven. + f(self) epsilon, in the case that the result cannot be proven All of the above parameters are optional, with epsilon=0, ``bits`` and ``degree`` tested up to 1000 and 24 by default respectively. The @@ -960,16 +958,15 @@ def minpoly(ex, var='x', algorithm=None, bits=None, degree=None, epsilon=0): explicitly. The algebraic algorithm ignores the last three parameters. - - OUTPUT: The minimal polynomial of ``self``. If the numerical algorithm + OUTPUT: the minimal polynomial of ``self``. If the numerical algorithm is used, then it is proved symbolically when ``epsilon=0`` (default). If the minimal polynomial could not be found, two distinct kinds of errors are raised. If no reasonable candidate was found with the - given ``bits``/``degree`` parameters, a :class:`ValueError` will be + given ``bits``/``degree`` parameters, a :exc:`ValueError` will be raised. If a reasonable candidate was found but (perhaps due to limits in the underlying symbolic package) was unable to be proved - correct, a :class:`NotImplementedError` will be raised. + correct, a :exc:`NotImplementedError` will be raised. ALGORITHM: Two distinct algorithms are used, depending on the algorithm parameter. By default, the numerical algorithm is @@ -988,11 +985,11 @@ def minpoly(ex, var='x', algorithm=None, bits=None, degree=None, epsilon=0): minpoly `f`. If `f(\mathtt{self})`, evaluated to a higher precision, is close enough to 0 then evaluate `f(\mathtt{self})` symbolically, attempting to prove - vanishing. If this fails, and ``epsilon`` is non-zero, + vanishing. If this fails, and ``epsilon`` is nonzero, return `f` if and only if `f(\mathtt{self}) < \mathtt{epsilon}`. - Otherwise raise a :class:`ValueError` (if no suitable - candidate was found) or a :class:`NotImplementedError` (if a + Otherwise raise a :exc:`ValueError` (if no suitable + candidate was found) or a :exc:`NotImplementedError` (if a likely candidate was found but could not be proved correct). EXAMPLES: First some simple examples:: @@ -1103,7 +1100,7 @@ def minpoly(ex, var='x', algorithm=None, bits=None, degree=None, epsilon=0): ... ValueError: Could not find minimal polynomial (1000 bits, degree 24). - .. note:: + .. NOTE:: Of course, failure to produce a minimal polynomial does not necessarily indicate that this number is transcendental. @@ -1171,18 +1168,18 @@ def limit(ex, dir=None, taylor=False, algorithm='maxima', **argv): INPUT: - - ``dir`` -- (default: ``None``); may have the value + - ``dir`` -- (default: ``None``) may have the value ``'plus'`` (or ``'+'`` or ``'right'`` or ``'above'``) for a limit from above, ``'minus'`` (or ``'-'`` or ``'left'`` or ``'below'``) for a limit from below, or may be omitted (implying a two-sided limit is to be computed). - - ``taylor`` -- (default: ``False``); if ``True``, use Taylor + - ``taylor`` -- (default: ``False``) if ``True``, use Taylor series, which allows more limits to be computed (but may also crash in some obscure cases due to bugs in Maxima). - ``**argv`` -- 1 named parameter - .. note:: + .. NOTE:: The output may also use ``und`` (undefined), ``ind`` (indefinite but bounded), and ``infinity`` (complex @@ -1300,7 +1297,7 @@ def limit(ex, dir=None, taylor=False, algorithm='maxima', **argv): With the standard package Giac:: - sage: from sage.libs.giac.giac import libgiac # random + sage: # needs sage.libs.giac sage: (exp(-x)/(2+sin(x))).limit(x=oo, algorithm='giac') 0 sage: limit(e^(-1/x), x=0, dir='right', algorithm='giac') @@ -1568,7 +1565,7 @@ def laplace(ex, t, s, algorithm='maxima'): - ``'sympy'`` -- use SymPy - - ``'giac'`` -- use Giac + - ``'giac'`` -- use Giac (optional) .. NOTE:: @@ -1642,7 +1639,7 @@ def laplace(ex, t, s, algorithm='maxima'): sage: p1 = plot(xt, 0, 1/2, rgbcolor=(1,0,0)) # needs sage.plot sage: p2 = plot(yt, 0, 1/2, rgbcolor=(0,1,0)) # needs sage.plot sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # needs sage.plot + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # needs sage.plot ....: (p1 + p2).save(f.name) Another example:: @@ -1672,7 +1669,7 @@ def laplace(ex, t, s, algorithm='maxima'): (0, True) sage: F # random - sympy <1.9 includes undefined heaviside(0) in answer 1 - sage: laplace(dirac_delta(t), t, s, algorithm='giac') + sage: laplace(dirac_delta(t), t, s, algorithm='giac') # needs giac 1 Heaviside step function can be handled with different interfaces. @@ -1681,8 +1678,9 @@ def laplace(ex, t, s, algorithm='maxima'): sage: laplace(heaviside(t-1), t, s) e^(-s)/s - Try with giac:: + Try with giac, if it is installed:: + sage: # needs giac sage: laplace(heaviside(t-1), t, s, algorithm='giac') e^(-s)/s @@ -1695,6 +1693,7 @@ def laplace(ex, t, s, algorithm='maxima'): Testing Giac:: + sage: # needs giac sage: var('t, s') (t, s) sage: laplace(5*cos(3*t-2)*heaviside(t-2), t, s, algorithm='giac') @@ -1703,13 +1702,14 @@ def laplace(ex, t, s, algorithm='maxima'): Check unevaluated expression from Giac (it is locale-dependent, see :issue:`22833`):: - sage: var('n') - n + sage: # needs giac + sage: n = SR.var('n') sage: laplace(t^n, t, s, algorithm='giac') laplace(t^n, t, s) Testing SymPy:: + sage: n = SR.var('n') sage: F, a, cond = laplace(t^n, t, s, algorithm='sympy') sage: a, cond (0, re(n) > -1) @@ -1810,7 +1810,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): - ``'sympy'`` -- use SymPy - - ``'giac'`` -- use Giac + - ``'giac'`` -- use Giac (optional) .. SEEALSO:: @@ -1847,11 +1847,13 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): The same instance with Giac:: + sage: # needs giac sage: inverse_laplace(1/s^2*exp(-s), s, t, algorithm='giac') (t - 1)*heaviside(t - 1) Transform a rational expression:: + sage: # needs giac sage: inverse_laplace((2*s^2*exp(-2*s) - exp(-s))/(s^3+1), s, t, ....: algorithm='giac') -1/3*(sqrt(3)*e^(1/2*t - 1/2)*sin(1/2*sqrt(3)*(t - 1)) @@ -1868,7 +1870,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): dirac_delta(t) sage: inverse_laplace(1, s, t, algorithm='sympy') dirac_delta(t) - sage: inverse_laplace(1, s, t, algorithm='giac') + sage: inverse_laplace(1, s, t, algorithm='giac') # needs giac dirac_delta(t) TESTS: @@ -1882,6 +1884,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): Testing Giac:: + sage: # needs giac sage: inverse_laplace(exp(-s)/s, s, t, algorithm='giac') heaviside(t - 1) @@ -1892,12 +1895,14 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): Testing unevaluated expression from Giac:: - sage: n = var('n') + sage: # needs giac + sage: n = SR.var('n') sage: inverse_laplace(1/s^n, s, t, algorithm='giac') ilt(1/(s^n), t, s) Try with Maxima:: + sage: n = SR.var('n') sage: inverse_laplace(1/s^n, s, t, algorithm='maxima') ilt(1/(s^n), s, t) @@ -1913,6 +1918,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): Testing the same with Giac:: + sage: # needs giac sage: inverse_laplace(cos(s), s, t, algorithm='giac') ilt(cos(s), t, s) """ @@ -2019,7 +2025,6 @@ def at(ex, *args, **kwds): sage: from sage.calculus.calculus import at sage: at(int(1), x=1) 1 - """ if not isinstance(ex, (Expression, Function)): ex = SR(ex) @@ -2114,7 +2119,7 @@ def dummy_inverse_laplace(*args): def dummy_pochhammer(*args): """ - This function is called to create formal wrappers of Pochhammer symbols + This function is called to create formal wrappers of Pochhammer symbols. EXAMPLES:: @@ -2148,7 +2153,6 @@ def _laplace_latex_(self, *args): '\\mathcal{L}\\left(f\\left(t\\right), t, s\\right)' sage: latex(laplace(f, t, s)) \mathcal{L}\left(f\left(t\right), t, s\right) - """ return "\\mathcal{L}\\left(%s\\right)" % (', '.join(latex(x) for x in args)) @@ -2236,13 +2240,13 @@ def symbolic_expression_from_maxima_string(x, equals_sub=False, maxima=maxima): INPUT: - - ``x`` -- a string + - ``x`` -- string - - ``equals_sub`` -- (default: ``False``) if ``True``, replace + - ``equals_sub`` -- boolean (default: ``False``); if ``True``, replace '=' by '==' in self - ``maxima`` -- (default: the calculus package's copy of - Maxima) the Maxima interpreter to use. + Maxima) the Maxima interpreter to use EXAMPLES:: @@ -2429,7 +2433,7 @@ def mapped_opts(v): - ``v`` -- an object - OUTPUT: a string. + OUTPUT: string The main use of this is to turn Python bools into lower case strings. @@ -2478,13 +2482,18 @@ def _find_var(name, interface=None): EXAMPLES:: - sage: y = var('y') + sage: y = SR.var('y') sage: sage.calculus.calculus._find_var('y') y sage: sage.calculus.calculus._find_var('I') I sage: sage.calculus.calculus._find_var(repr(maxima(y)), interface='maxima') y + + :: + + sage: # needs giac + sage: y = SR.var('y') sage: sage.calculus.calculus._find_var(repr(giac(y)), interface='giac') y """ @@ -2560,13 +2569,13 @@ def symbolic_expression_from_string(s, syms=None, accept_sequence=False, *, pars INPUT: - - ``s`` -- a string + - ``s`` -- string - ``syms`` -- (default: ``{}``) dictionary of strings to be regarded as symbols or functions; keys are pairs (string, number of arguments) - - ``accept_sequence`` -- (default: ``False``) controls whether + - ``accept_sequence`` -- boolean (default: ``False``); controls whether to allow a (possibly nested) set of lists and tuples as input @@ -2591,6 +2600,7 @@ def symbolic_expression_from_string(s, syms=None, accept_sequence=False, *, pars The Giac interface uses a different parser (:issue:`30133`):: + sage: # needs giac sage: from sage.calculus.calculus import SR_parser_giac sage: symbolic_expression_from_string(repr(giac(SR.var('e'))), parser=SR_parser_giac) e diff --git a/src/sage/calculus/desolvers.py b/src/sage/calculus/desolvers.py index 9f9d7534845..d17f5a14e90 100644 --- a/src/sage/calculus/desolvers.py +++ b/src/sage/calculus/desolvers.py @@ -14,40 +14,40 @@ Commands: -- :func:`desolve` -- Compute the "general solution" to a 1st or 2nd order - ODE via Maxima. +- :func:`desolve` -- compute the "general solution" to a 1st or 2nd order + ODE via Maxima -- :func:`desolve_laplace` -- Solve an ODE using Laplace transforms via - Maxima. Initial conditions are optional. +- :func:`desolve_laplace` -- solve an ODE using Laplace transforms via + Maxima. Initial conditions are optional -- :func:`desolve_rk4` -- Solve numerically an IVP for one first order - equation, return list of points or plot. +- :func:`desolve_rk4` -- solve numerically an IVP for one first order + equation, return list of points or plot -- :func:`desolve_system_rk4` -- Solve numerically an IVP for a system of first - order equations, return list of points. +- :func:`desolve_system_rk4` -- solve numerically an IVP for a system of first + order equations, return list of points -- :func:`desolve_odeint` -- Solve numerically a system of first-order ordinary +- :func:`desolve_odeint` -- solve numerically a system of first-order ordinary differential equations using :func:`~scipy:scipy.integrate.odeint` from the module :mod:`scipy:scipy.integrate`. -- :func:`desolve_system` -- Solve a system of 1st order ODEs of any size using - Maxima. Initial conditions are optional. +- :func:`desolve_system` -- solve a system of 1st order ODEs of any size using + Maxima. Initial conditions are optional -- :func:`eulers_method` -- Approximate solution to a 1st order DE, - presented as a table. +- :func:`eulers_method` -- approximate solution to a 1st order DE, + presented as a table -- :func:`eulers_method_2x2` -- Approximate solution to a 1st order system - of DEs, presented as a table. +- :func:`eulers_method_2x2` -- approximate solution to a 1st order system + of DEs, presented as a table -- :func:`eulers_method_2x2_plot` -- Plot the sequence of points obtained - from Euler's method. +- :func:`eulers_method_2x2_plot` -- plot the sequence of points obtained + from Euler's method The following functions require the optional package ``tides``: -- :func:`desolve_mintides` -- Numerical solution of a system of 1st order ODEs via - the Taylor series integrator method implemented in TIDES. +- :func:`desolve_mintides` -- numerical solution of a system of 1st order ODEs via + the Taylor series integrator method implemented in TIDES -- :func:`desolve_tides_mpfr` -- Arbitrary precision Taylor series integrator implemented in TIDES. +- :func:`desolve_tides_mpfr` -- arbitrary precision Taylor series integrator implemented in TIDES AUTHORS: @@ -93,10 +93,10 @@ def fricas_desolve(de, dvar, ics, ivar): sage: x = var('x') sage: y = function('y')(x) - sage: desolve(diff(y,x) + y - 1, y, algorithm="fricas") # optional - fricas + sage: desolve(diff(y,x) + y - 1, y, algorithm='fricas') # optional - fricas _C0*e^(-x) + 1 - sage: desolve(diff(y, x) + y == y^3*sin(x), y, algorithm="fricas") # optional - fricas + sage: desolve(diff(y, x) + y == y^3*sin(x), y, algorithm='fricas') # optional - fricas -1/5*(2*cos(x)*y(x)^2 + 4*sin(x)*y(x)^2 - 5)*e^(-2*x)/y(x)^2 TESTS:: @@ -133,11 +133,11 @@ def fricas_desolve_system(des, dvars, ics, ivar): sage: y = function('y')(t) sage: de1 = diff(x,t) + y - 1 == 0 sage: de2 = diff(y,t) - x + 1 == 0 - sage: desolve_system([de1, de2], [x, y], algorithm="fricas") # optional - fricas + sage: desolve_system([de1, de2], [x, y], algorithm='fricas') # optional - fricas [x(t) == _C0*cos(t) + cos(t)^2 + _C1*sin(t) + sin(t)^2, y(t) == -_C1*cos(t) + _C0*sin(t) + 1] - sage: desolve_system([de1, de2], [x,y], [0,1,2], algorithm="fricas") # optional - fricas + sage: desolve_system([de1, de2], [x,y], [0,1,2], algorithm='fricas') # optional - fricas [x(t) == cos(t)^2 + sin(t)^2 - sin(t), y(t) == cos(t) + 1] TESTS:: @@ -154,7 +154,6 @@ def fricas_desolve_system(des, dvars, ics, ivar): sage: sol = fricas_desolve_system([de1,de2], [x,y], [0,1,-1], t) # optional - fricas sage: sol # optional - fricas [x(t) == cos(t)^2 + sin(t)^2 + 2*sin(t), y(t) == -2*cos(t) + 1] - """ from sage.interfaces.fricas import fricas from sage.symbolic.ring import SR @@ -178,7 +177,7 @@ def fricas_desolve_system(des, dvars, ics, ivar): def desolve(de, dvar, ics=None, ivar=None, show_method=False, contrib_ode=False, - algorithm="maxima"): + algorithm='maxima'): r""" Solve a 1st or 2nd order linear ODE, including IVP and BVP. @@ -473,20 +472,20 @@ def desolve(de, dvar, ics=None, ivar=None, show_method=False, contrib_ode=False, order linear equations:: sage: de = x^3*diff(y, x, 3) + x^2*diff(y, x, 2) - 2*x*diff(y, x) + 2*y - 2*x^4 - sage: Y = desolve(de, y, algorithm="fricas"); Y # optional - fricas + sage: Y = desolve(de, y, algorithm='fricas'); Y # optional - fricas (2*x^3 - 3*x^2 + 1)*_C0/x + (x^3 - 1)*_C1/x + (x^3 - 3*x^2 - 1)*_C2/x + 1/15*(x^5 - 10*x^3 + 20*x^2 + 4)/x The initial conditions are then interpreted as `[x_0, y(x_0), y'(x_0), \ldots, y^(n)(x_0)]`:: - sage: Y = desolve(de, y, ics=[1,3,7], algorithm="fricas"); Y # optional - fricas + sage: Y = desolve(de, y, ics=[1,3,7], algorithm='fricas'); Y # optional - fricas 1/15*(x^5 + 15*x^3 + 50*x^2 - 21)/x FriCAS can also solve some non-linear equations:: sage: de = diff(y, x) == y / (x+y*log(y)) - sage: Y = desolve(de, y, algorithm="fricas"); Y # optional - fricas + sage: Y = desolve(de, y, algorithm='fricas'); Y # optional - fricas 1/2*(log(y(x))^2*y(x) - 2*x)/y(x) TESTS: @@ -674,12 +673,10 @@ def desolve_laplace(de, dvar, ics=None, ivar=None): `x`), which must be specified if there is more than one independent variable in the equation. - - ``ics`` -- a list of numbers representing initial conditions, (e.g. + - ``ics`` -- list of numbers representing initial conditions, (e.g. ``f(0)=1``, ``f'(0)=2`` corresponds to ``ics = [0,1,2]``) - OUTPUT: - - Solution of the ODE as symbolic expression + OUTPUT: solution of the ODE as symbolic expression EXAMPLES:: @@ -789,7 +786,7 @@ def sanitize_var(exprs): return soln -def desolve_system(des, vars, ics=None, ivar=None, algorithm="maxima"): +def desolve_system(des, vars, ics=None, ivar=None, algorithm='maxima'): r""" Solve a system of any size of 1st order ODEs. Initial conditions are optional. @@ -950,7 +947,7 @@ def desolve_system(des, vars, ics=None, ivar=None, algorithm="maxima"): return soln -def eulers_method(f, x0, y0, h, x1, algorithm="table"): +def eulers_method(f, x0, y0, h, x1, algorithm='table'): r""" This implements Euler's method for finding numerically the solution of the 1st order ODE `y' = f(x,y)`, `y(a)=c`. The ``x`` @@ -976,7 +973,7 @@ def eulers_method(f, x0, y0, h, x1, algorithm="table"): :: sage: x,y = PolynomialRing(QQ,2,"xy").gens() - sage: eulers_method(5*x+y-5,0,1,1/2,1,algorithm="none") + sage: eulers_method(5*x+y-5,0,1,1/2,1,algorithm='none') [[0, 1], [1/2, -1], [1, -11/4], [3/2, -33/8]] :: @@ -1008,12 +1005,12 @@ def eulers_method(f, x0, y0, h, x1, algorithm="table"): :: - sage: eulers_method(5*x+y-5,0,1,1/2,1,algorithm="none") + sage: eulers_method(5*x+y-5,0,1,1/2,1,algorithm='none') [[0, 1], [1/2, -1], [1, -11/4], [3/2, -33/8]] :: - sage: pts = eulers_method(5*x+y-5,0,1,1/2,1,algorithm="none") + sage: pts = eulers_method(5*x+y-5,0,1,1/2,1,algorithm='none') sage: P1 = list_plot(pts) # needs sage.plot sage: P2 = line(pts) # needs sage.plot sage: (P1 + P2).show() # needs sage.plot @@ -1038,7 +1035,7 @@ def eulers_method(f, x0, y0, h, x1, algorithm="table"): return soln -def eulers_method_2x2(f, g, t0, x0, y0, h, t1, algorithm="table"): +def eulers_method_2x2(f, g, t0, x0, y0, h, t1, algorithm='table'): r""" This implements Euler's method for finding numerically the solution of the 1st order system of two ODEs @@ -1066,7 +1063,7 @@ def eulers_method_2x2(f, g, t0, x0, y0, h, t1, algorithm="table"): sage: from sage.calculus.desolvers import eulers_method_2x2 sage: t, x, y = PolynomialRing(QQ,3,"txy").gens() sage: f = x+y+t; g = x-y - sage: eulers_method_2x2(f,g, 0, 0, 0, 1/3, 1,algorithm="none") + sage: eulers_method_2x2(f,g, 0, 0, 0, 1/3, 1,algorithm='none') [[0, 0, 0], [1/3, 0, 0], [2/3, 1/9, 0], [1, 10/27, 1/27], [4/3, 68/81, 4/27]] :: @@ -1217,7 +1214,6 @@ def desolve_rk4_determine_bounds(ics, end_points=None): sage: desolve_rk4_determine_bounds([0,2],[-2,4]) (-2, 4) - """ if end_points is None: return ics[0], ics[0] + 10 @@ -1264,7 +1260,7 @@ def desolve_rk4(de, dvar, ics=None, ivar=None, end_points=None, step=0.1, output - if end_points is [a,b] we integrate between ``min(ics[0], a)`` and ``max(ics[0], b)`` - - ``step`` -- (default:0.1) the length of the step (positive number) + - ``step`` -- (default: 0.1) the length of the step (positive number) - ``output`` -- (default: ``'list'``) one of ``'list'``, ``'plot'``, ``'slope_field'`` (graph of the solution with slope field) @@ -1305,7 +1301,7 @@ def desolve_rk4(de, dvar, ics=None, ivar=None, end_points=None, step=0.1, output ALGORITHM: - 4th order Runge-Kutta method. Wrapper for command ``rk`` in + `4`-th order Runge-Kutta method. Wrapper for command ``rk`` in Maxima's dynamics package. Perhaps could be faster by using fast_float instead. @@ -1361,14 +1357,10 @@ def desolve_rk4_inner(de, dvar): XMAX = XMIN YMAX = YMIN for s, t in sol: - if s > XMAX: - XMAX = s - if s < XMIN: - XMIN = s - if t > YMAX: - YMAX = t - if t < YMIN: - YMIN = t + XMAX = max(s, XMAX) + XMIN = min(s, XMIN) + YMAX = max(t, YMAX) + YMIN = min(t, YMIN) return plot_slope_field(de, (ivar, XMIN, XMAX), (dvar, YMIN, YMAX)) + R if not (isinstance(dvar, Expression) and dvar.is_symbol()): @@ -1390,12 +1382,12 @@ def desolve_rk4_inner(de, dvar): def desolve_system_rk4(des, vars, ics=None, ivar=None, end_points=None, step=0.1): r""" Solve numerically a system of first-order ordinary differential - equations using the 4th order Runge-Kutta method. Wrapper for + equations using the `4`-th order Runge-Kutta method. Wrapper for Maxima command ``rk``. INPUT: - input is similar to desolve_system and desolve_rk4 commands + Input is similar to ``desolve_system`` and ``desolve_rk4`` commands - ``des`` -- right hand sides of the system @@ -1416,9 +1408,7 @@ def desolve_system_rk4(des, vars, ics=None, ivar=None, end_points=None, step=0.1 - ``step`` -- (default: 0.1) the length of the step - OUTPUT: - - Return a list of points. + OUTPUT: a list of points .. SEEALSO:: @@ -1442,7 +1432,7 @@ def desolve_system_rk4(des, vars, ics=None, ivar=None, end_points=None, step=0.1 ALGORITHM: - 4th order Runge-Kutta method. Wrapper for command ``rk`` in Maxima's + `4`-th order Runge-Kutta method. Wrapper for command ``rk`` in Maxima's dynamics package. Perhaps could be faster by using ``fast_float`` instead. @@ -1503,19 +1493,20 @@ def desolve_odeint(des, ics, times, dvars, ivar=None, compute_jac=False, args=() INPUT: - - ``des`` -- right hand sides of the system + - ``des`` -- right hand sides of the system - - ``ics`` -- initial conditions + - ``ics`` -- initial conditions - ``times`` -- a sequence of time points in which the solution must be found - ``dvars`` -- dependent variables. ATTENTION: the order must be the same as in ``des``, that means: ``d(dvars[i])/dt=des[i]`` - - ``ivar`` -- independent variable, optional. + - ``ivar`` -- independent variable, optional - - ``compute_jac`` -- boolean. If True, the Jacobian of ``des`` is computed and - used during the integration of stiff systems. Default value is False. + - ``compute_jac`` -- boolean (default: ``False``); if ``True``, the + Jacobian of ``des`` is computed and used during the integration of stiff + systems Other Parameters (taken from the documentation of the :func:`~scipy:scipy.integrate.odeint` function from @@ -1564,9 +1555,7 @@ def desolve_odeint(des, ics, times, dvars, ivar=None, compute_jac=False, args=() - ``mxords`` : integer, (0: solver-determined) Maximum order to be allowed for the stiff (BDF) method. - OUTPUT: - - Return a list with the solution of the system at each time in ``times``. + OUTPUT: a list with the solution of the system at each time in ``times`` EXAMPLES: @@ -1700,26 +1689,22 @@ def desolve_mintides(f, ics, initial, final, delta, tolrel=1e-16, tolabs=1e-16): INPUT: - - ``f`` -- symbolic function. Its first argument will be the independent - variable. Its output should be de derivatives of the dependent variables. - - - ``ics`` -- a list or tuple with the initial conditions. - - - ``initial`` -- the starting value for the independent variable. + - ``f`` -- symbolic function; its first argument will be the independent + variable, . Its output should be de derivatives of the dependent variables. - - ``final`` -- the final value for the independent value. + - ``ics`` -- list or tuple with the initial conditions - - ``delta`` -- the size of the steps in the output. + - ``initial`` -- the starting value for the independent variable - - ``tolrel`` -- the relative tolerance for the method. + - ``final`` -- the final value for the independent value - - ``tolabs`` -- the absolute tolerance for the method. + - ``delta`` -- the size of the steps in the output + - ``tolrel`` -- the relative tolerance for the method - OUTPUT: - - - A list with the positions of the IVP. + - ``tolabs`` -- the absolute tolerance for the method + OUTPUT: list with the positions of the IVP EXAMPLES: @@ -1791,28 +1776,24 @@ def desolve_tides_mpfr(f, ics, initial, final, delta, tolrel=1e-16, tolabs=1e-16 INPUT: - - ``f`` -- symbolic function. Its first argument will be the independent + - ``f`` -- symbolic function; its first argument will be the independent variable. Its output should be de derivatives of the dependent variables. - - ``ics`` -- a list or tuple with the initial conditions. + - ``ics`` -- list or tuple with the initial conditions - - ``initial`` -- the starting value for the independent variable. + - ``initial`` -- the starting value for the independent variable - - ``final`` -- the final value for the independent value. + - ``final`` -- the final value for the independent value - - ``delta`` -- the size of the steps in the output. + - ``delta`` -- the size of the steps in the output - - ``tolrel`` -- the relative tolerance for the method. + - ``tolrel`` -- the relative tolerance for the method - - ``tolabs`` -- the absolute tolerance for the method. - - - ``digits`` -- the digits of precision used in the computation. - - - OUTPUT: + - ``tolabs`` -- the absolute tolerance for the method - - A list with the positions of the IVP. + - ``digits`` -- the digits of precision used in the computation + OUTPUT: list with the positions of the IVP EXAMPLES: diff --git a/src/sage/calculus/expr.py b/src/sage/calculus/expr.py index 7e56c888cac..f36d56b6c40 100644 --- a/src/sage/calculus/expr.py +++ b/src/sage/calculus/expr.py @@ -19,9 +19,7 @@ def symbolic_expression(x): - ``x`` - an object - OUTPUT: - - - a symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: diff --git a/src/sage/calculus/functional.py b/src/sage/calculus/functional.py index 6bd480c20e0..557ce362fd3 100644 --- a/src/sage/calculus/functional.py +++ b/src/sage/calculus/functional.py @@ -29,7 +29,7 @@ from sage.structure.element import Expression -def simplify(f, algorithm="maxima", **kwds): +def simplify(f, algorithm='maxima', **kwds): r""" Simplify the expression `f`. @@ -53,7 +53,7 @@ def simplify(f, algorithm="maxima", **kwds): sage: ex = 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) sage: simplify(ex) 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) - sage: simplify(ex, algorithm="giac") + sage: simplify(ex, algorithm='giac') # needs giac I*sqrt(x^2 - 1) """ try: @@ -158,7 +158,6 @@ def derivative(f, *args, **kwds): 2-form da on the 2-dimensional differentiable manifold M sage: derivative(a).display() da = 2 dx∧dy - """ try: return f.derivative(*args, **kwds) @@ -336,14 +335,14 @@ def limit(f, dir=None, taylor=False, **argv): INPUT: - - ``dir`` -- (default: None); dir may have the value - 'plus' (or 'above') for a limit from above, 'minus' (or 'below') - for a limit from below, or may be omitted (implying a two-sided - limit is to be computed). + - ``dir`` -- (default: ``None``) dir may have the value ``'plus'`` (or + ``'above'``) for a limit from above, ``'minus'`` (or ``'below'``) for a + limit from below, or may be omitted (implying a two-sided limit is to be + computed). - - ``taylor`` -- (default: ``False``); if True, use Taylor - series, which allows more limits to be computed (but may also - crash in some obscure cases due to bugs in Maxima). + - ``taylor`` -- (default: ``False``) if ``True``, use Taylor + series, which allows more limits to be computed (but may also + crash in some obscure cases due to bugs in Maxima). - ``\*\*argv`` -- 1 named parameter @@ -381,7 +380,7 @@ def limit(f, dir=None, taylor=False, **argv): def taylor(f, *args): """ - Expands self in a truncated Taylor or Laurent series in the + Expand ``self`` in a truncated Taylor or Laurent series in the variable `v` around the point `a`, containing terms through `(x - a)^n`. Functions in more variables are also supported. diff --git a/src/sage/calculus/functions.py b/src/sage/calculus/functions.py index efb8926b317..c044cc0a968 100644 --- a/src/sage/calculus/functions.py +++ b/src/sage/calculus/functions.py @@ -25,7 +25,7 @@ def wronskian(*args): function. The Wronskian of a list of functions is a determinant of derivatives. - The nth row (starting from 0) is a list of the nth derivatives of the + The `n`-th row (starting from 0) is a list of the `n`-th derivatives of the given functions. For two functions:: diff --git a/src/sage/calculus/integration.pyx b/src/sage/calculus/integration.pyx index f0cd3a9f1ca..f746f8aa04a 100644 --- a/src/sage/calculus/integration.pyx +++ b/src/sage/calculus/integration.pyx @@ -72,7 +72,7 @@ def numerical_integral(func, a, b=None, INPUT: - - ``a``, ``b`` -- The interval of integration, specified as two + - ``a``, ``b`` -- the interval of integration, specified as two numbers or as a tuple/list with the first element the lower bound and the second element the upper bound. Use ``+Infinity`` and ``-Infinity`` for plus or minus infinity. @@ -87,7 +87,7 @@ def numerical_integral(func, a, b=None, - ``eps_abs``, ``eps_rel`` -- sets the absolute and relative error tolerances which satisfies the relation ``|RESULT - I| <= max(eps_abs, eps_rel * |I|)``, where ``I = \int_a^b f(x) d x``. - - ``rule`` -- This controls the Gauss-Kronrod rule used in the adaptive integration: + - ``rule`` -- this controls the Gauss-Kronrod rule used in the adaptive integration: * rule=1 -- 15 point rule * rule=2 -- 21 point rule @@ -253,7 +253,6 @@ def numerical_integral(func, a, b=None, sage: h(x) = x sage: numerical_integral(h,0,1)[0] # abs tol 1e-8 0.5 - """ cdef double abs_err # step size cdef double result diff --git a/src/sage/calculus/interpolation.pyx b/src/sage/calculus/interpolation.pyx index c2acab64fd9..230bedda658 100644 --- a/src/sage/calculus/interpolation.pyx +++ b/src/sage/calculus/interpolation.pyx @@ -173,7 +173,6 @@ cdef class Spline: [(2, 3), (4, 5), (5, 5)] sage: S(3) 4.25 - """ del self.v[i] self.stop_interp() @@ -195,7 +194,6 @@ cdef class Spline: [(1, 1), (2, 3), (4, 5), (5, 5)] sage: S(3) 4.375 - """ self.v.append(xy) self.stop_interp() @@ -219,7 +217,6 @@ cdef class Spline: [(1, 1), (2, 3), (3, 2)] sage: S.list() [(1, 1), (2, 3), (4, 5)] - """ return self.v[:] @@ -309,9 +306,9 @@ cdef class Spline: INPUT: - - ``x`` -- value at which to evaluate the derivative. + - ``x`` -- value at which to evaluate the derivative - - ``order`` (default: 1) -- order of the derivative. Must be 1 or 2. + - ``order`` -- (default: 1) order of the derivative; must be 1 or 2 EXAMPLES: @@ -329,7 +326,6 @@ cdef class Spline: -1.125 sage: s.derivative(3, order=2) -1.125 - """ if (order!=1) and (order!=2): raise ValueError("Order of derivative must be 1 or 2.") @@ -352,9 +348,9 @@ cdef class Spline: INPUT: - - ``a`` -- Lower bound for the integral. + - ``a`` -- lower bound for the integral - - ``b`` -- Upper bound for the integral. + - ``b`` -- upper bound for the integral EXAMPLES: @@ -370,7 +366,6 @@ cdef class Spline: 3.75 sage: s.definite_integral(2, 0) -3.75 - """ # GSL chokes when the upper bound is smaller than the lower bound bounds_swapped = False diff --git a/src/sage/calculus/interpolators.pyx b/src/sage/calculus/interpolators.pyx index 221b52369e2..c13fcff8f93 100644 --- a/src/sage/calculus/interpolators.pyx +++ b/src/sage/calculus/interpolators.pyx @@ -27,20 +27,22 @@ Development supported by NSF award No. 0702939. import numpy as np cimport numpy as np +if int(np.version.short_version[0]) > 1: + np.set_printoptions(legacy="1.25") + from math import pi cdef double TWOPI = 2*pi def polygon_spline(pts): """ - Creates a polygon from a set of complex or `(x,y)` points. The polygon + Create a polygon from a set of complex or `(x,y)` points. The polygon will be a parametric curve from 0 to 2*pi. The returned values will be complex, not `(x,y)`. INPUT: - - ``pts`` -- A list or array of complex numbers of tuples of the form - `(x,y)`. + - ``pts`` -- list or array of complex numbers of tuples of the form `(x,y)` EXAMPLES: @@ -106,8 +108,8 @@ cdef class PSpline: INPUT: - - ``t`` -- double, the parameter value for the parameterized curve, - between 0 and 2*pi. + - ``t`` -- double; the parameter value for the parameterized curve, + between 0 and 2*pi OUTPUT: @@ -139,8 +141,8 @@ cdef class PSpline: INPUT: - - ``t`` -- double, the parameter value for the parameterized curve, - between 0 and 2*pi. + - ``t`` -- double; the parameter value for the parameterized curve, + between 0 and 2*pi OUTPUT: @@ -169,14 +171,13 @@ cdef class PSpline: def complex_cubic_spline(pts): """ - Creates a cubic spline interpolated figure from a set of complex or + Create a cubic spline interpolated figure from a set of complex or `(x,y)` points. The figure will be a parametric curve from 0 to 2*pi. The returned values will be complex, not `(x,y)`. INPUT: - - ``pts`` -- A list or array of complex numbers, or tuples of the form - `(x,y)`. + - ``pts`` -- list or array of complex numbers, or tuples of the form `(x,y)` EXAMPLES: @@ -264,8 +265,8 @@ cdef class CCSpline: INPUT: - - ``t`` -- double, the parameter value for the parameterized curve, - between 0 and 2*pi. + - ``t`` -- double; the parameter value for the parameterized curve, + between 0 and 2*pi OUTPUT: @@ -298,8 +299,8 @@ cdef class CCSpline: INPUT: - - ``t`` -- double, the parameter value for the parameterized curve, - between 0 and 2*pi. + - ``t`` -- double; the parameter value for the parameterized curve, + between 0 and 2*pi OUTPUT: diff --git a/src/sage/calculus/meson.build b/src/sage/calculus/meson.build new file mode 100644 index 00000000000..541d7d86d75 --- /dev/null +++ b/src/sage/calculus/meson.build @@ -0,0 +1,37 @@ +py.install_sources( + 'all.py', + 'calculus.py', + 'desolvers.py', + 'expr.py', + 'functional.py', + 'functions.py', + 'interpolation.pxd', + 'ode.pxd', + 'predefined.py', + 'test_sympy.py', + 'tests.py', + 'wester.py', + subdir: 'sage/calculus', +) + +extension_data = { + 'integration' : files('integration.pyx'), + 'interpolation' : files('interpolation.pyx'), + 'interpolators' : files('interpolators.pyx'), + 'ode' : files('ode.pyx'), + 'riemann' : files('riemann.pyx'), + 'var' : files('var.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/calculus', + install: true, + include_directories: [inc_numpy], + dependencies: [py_dep, cysignals, gmp, gsl, interpreters_dep], + ) +endforeach + +subdir('transforms') diff --git a/src/sage/calculus/ode.pyx b/src/sage/calculus/ode.pyx index 1d4aef35b7b..646b937e2e4 100644 --- a/src/sage/calculus/ode.pyx +++ b/src/sage/calculus/ode.pyx @@ -8,15 +8,15 @@ AUTHORS: - Robert Marik (2010 - fixed docstrings) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2004,2005,2006 Joshua Kantor # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.memory cimport sig_malloc, sig_free from cysignals.signals cimport sig_on, sig_off @@ -32,7 +32,7 @@ cdef class PyFunctionWrapper: cdef object the_parameters cdef int y_n - cdef set_yn(self,x): + cdef set_yn(self, x): self.y_n = x cdef class ode_system: @@ -53,31 +53,28 @@ cdef int c_f_compiled(double t, const double *y, double *dydt, void *params) noe cdef int status cdef ode_system wrapper wrapper = params - status = wrapper.c_f(t, y, dydt) # Could add parameters + status = wrapper.c_f(t, y, dydt) # Could add parameters return status cdef int c_jac(double t, const double *y, double *dfdy, double *dfdt, void *params) noexcept: cdef int i cdef int j cdef int y_n - cdef int param_n cdef PyFunctionWrapper wrapper wrapper = params y_n = wrapper.y_n - y_list = [] - for i in range(y_n): - y_list.append(y[i]) + y_list = [y[i] for i in range(y_n)] try: - if len(wrapper.the_parameters)==0: - jac_list=wrapper.the_jacobian(t,y_list) + if len(wrapper.the_parameters) == 0: + jac_list = wrapper.the_jacobian(t, y_list) else: - jac_list=wrapper.the_jacobian(t,y_list,wrapper.the_parameters) + jac_list = wrapper.the_jacobian(t, y_list, wrapper.the_parameters) for i in range(y_n): for j in range(y_n): - dfdy[i*y_n+j]=jac_list[i][j] + dfdy[i * y_n + j] = jac_list[i][j] for i in range(y_n): - dfdt[i]=jac_list[y_n][i] + dfdt[i] = jac_list[y_n][i] return GSL_SUCCESS except Exception: @@ -86,7 +83,6 @@ cdef int c_jac(double t, const double *y, double *dfdy, double *dfdt, void *para cdef int c_f(double t, const double *y, double *dydt, void *params) noexcept: cdef int i cdef int y_n - cdef int param_n cdef PyFunctionWrapper wrapper wrapper = params @@ -95,10 +91,10 @@ cdef int c_f(double t, const double *y, double *dydt, void *params) noexcept: for i in range(y_n): y_list.append(y[i]) try: - if len(wrapper.the_parameters)!=0: - dydt_list=wrapper.the_function(t,y_list,wrapper.the_parameters) + if len(wrapper.the_parameters) != 0: + dydt_list = wrapper.the_function(t, y_list, wrapper.the_parameters) else: - dydt_list=wrapper.the_function(t,y_list) + dydt_list = wrapper.the_function(t, y_list) for i in range(y_n): dydt[i] = dydt_list[i] return GSL_SUCCESS @@ -147,13 +143,13 @@ class ode_solver(): - ``'rk2'`` -- embedded Runge-Kutta (2,3) - - ``'rk4'`` -- 4th order classical Runge-Kutta + - ``'rk4'`` -- `4`-th order classical Runge-Kutta - ``'rk8pd'`` -- Runge-Kutta Prince-Dormand (8,9) - ``'rk2imp'`` -- implicit 2nd order Runge-Kutta at gaussian points - - ``'rk4imp'`` -- implicit 4th order Runge-Kutta at gaussian points + - ``'rk4imp'`` -- implicit `4`-th order Runge-Kutta at gaussian points - ``'bsimp'`` -- implicit Burlisch-Stoer (requires jacobian) @@ -246,7 +242,7 @@ class ode_solver(): sage: T.jacobian = j_1 sage: T.ode_solve(y_0=[1,0], t_span=[0,100], params=[10.0], num_points=1000) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # needs sage.plot + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # needs sage.plot ....: T.plot_solution(filename=f.name) The solver line is equivalent to:: @@ -271,7 +267,7 @@ class ode_solver(): By default ``T.plot_solution()`` plots the `y_0`; to plot general `y_i`, use:: - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # needs sage.plot + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # needs sage.plot ....: T.plot_solution(i=0, filename=f.name) ....: T.plot_solution(i=1, filename=f.name) ....: T.plot_solution(i=2, filename=f.name) @@ -296,7 +292,7 @@ class ode_solver(): ode_solver. The previous example can be rewritten as:: sage: T = ode_solver(g_1, y_0=[0,1,1], scale_abs=[1e-4,1e-4,1e-5], - ....: error_rel=1e-4, algorithm="rk8pd") + ....: error_rel=1e-4, algorithm='rk8pd') sage: T.ode_solve(t_span=[0,12], num_points=100) sage: f = T.interpolate_solution() sage: f(pi) @@ -342,11 +338,10 @@ class ode_solver(): sage: T.ode_solve(y_0=[1, 0], t_span=[0, 2000], ....: num_points=1000) sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".png") as f: + sage: with NamedTemporaryFile(suffix='.png') as f: ....: T.plot_solution(i=0, filename=f.name) - """ - def __init__(self,function=None,jacobian=None,h = 1e-2,error_abs=1e-10,error_rel=1e-10, a=False,a_dydt=False,scale_abs=False,algorithm="rkf45",y_0=None,t_span=None,params = []): + def __init__(self, function=None, jacobian=None, h=1e-2, error_abs=1e-10, error_rel=1e-10, a=False, a_dydt=False, scale_abs=False, algorithm='rkf45', y_0=None, t_span=None, params=[]): self.function = function self.jacobian = jacobian self.h = h @@ -376,9 +371,9 @@ class ode_solver(): INPUT: - - ``i`` -- (non-negative integer) composant of the projection + - ``i`` -- nonnegative integer; composant of the projection - - ``filename`` -- (string or ``None``) whether to plot the picture or + - ``filename`` -- string or ``None``; whether to plot the picture or save it in a file - ``interpolate`` -- whether to interpolate between the points of the @@ -403,23 +398,23 @@ class ode_solver(): pts = self.interpolate_solution(i) G = line2d(pts, **kwds) else: - pts = [(t,y[i]) for t,y in self.solution] + pts = [(t, y[i]) for t, y in self.solution] from sage.plot.point import point2d - G = point2d([(t,y[i]) for t,y in self.solution], **kwds) + G = point2d([(t, y[i]) for t, y in self.solution], **kwds) if filename is None: G.show() else: G.save(filename=filename) - def ode_solve(self,t_span=False,y_0=False,num_points=False,params=[]): - cdef double h # step size + def ode_solve(self, t_span=False, y_0=False, num_points=False, params=[]): + cdef double h # step size h = self.h cdef int i cdef int j cdef int type cdef int dim - cdef PyFunctionWrapper wrapper #struct to pass information into GSL C function - self.params=params + cdef PyFunctionWrapper wrapper # struct to pass information into GSL C function + self.params = params if t_span: self.t_span = t_span @@ -427,7 +422,7 @@ class ode_solver(): self.y_0 = y_0 dim = len(self.y_0) - type = isinstance(self.function,ode_system) + type = isinstance(self.function, ode_system) if type == 0: wrapper = PyFunctionWrapper() if self.function is not None: @@ -438,11 +433,11 @@ class ode_solver(): wrapper.the_jacobian = None else: wrapper.the_jacobian = self.jacobian - if self.params==[] and len(sage_getargspec(wrapper.the_function)[0])==2: - wrapper.the_parameters=[] - elif self.params==[] and len(sage_getargspec(wrapper.the_function)[0])>2: + if self.params == [] and len(sage_getargspec(wrapper.the_function)[0]) == 2: + wrapper.the_parameters = [] + elif self.params == [] and len(sage_getargspec(wrapper.the_function)[0]) > 2: raise ValueError("ODE system has a parameter but no parameters specified") - elif self.params!=[]: + elif self.params != []: wrapper.the_parameters = self.params wrapper.y_n = dim @@ -452,30 +447,30 @@ class ode_solver(): cdef double * scale_abs_array scale_abs_array=NULL - y = sig_malloc(sizeof(double)*(dim)) + y = sig_malloc(sizeof(double) * dim) if y == NULL: raise MemoryError("error allocating memory") result = [] - v = [0]*dim + v = [0] * dim cdef gsl_odeiv_step_type * T for i in range(dim): # copy initial conditions into C array y[i] = self.y_0[i] if self.algorithm == "rkf45": - T=gsl_odeiv_step_rkf45 + T = gsl_odeiv_step_rkf45 elif self.algorithm == "rk2": - T=gsl_odeiv_step_rk2 + T = gsl_odeiv_step_rk2 elif self.algorithm == "rk4": - T=gsl_odeiv_step_rk4 + T = gsl_odeiv_step_rk4 elif self.algorithm == "rkck": - T=gsl_odeiv_step_rkck + T = gsl_odeiv_step_rkck elif self.algorithm == "rk8pd": - T=gsl_odeiv_step_rk8pd + T = gsl_odeiv_step_rk8pd elif self.algorithm == "rk2imp": - T= gsl_odeiv_step_rk2imp + T = gsl_odeiv_step_rk2imp elif self.algorithm == "rk4imp": - T= gsl_odeiv_step_rk4imp + T = gsl_odeiv_step_rk4imp elif self.algorithm == "bsimp": T = gsl_odeiv_step_bsimp if not type and self.jacobian is None: @@ -488,38 +483,38 @@ class ode_solver(): raise TypeError("algorithm not valid") cdef gsl_odeiv_step * s - s = gsl_odeiv_step_alloc (T, dim) - if s==NULL: + s = gsl_odeiv_step_alloc(T, dim) + if s == NULL: sig_free(y) raise MemoryError("error setting up solver") cdef gsl_odeiv_control * c if not self.a and not self.a_dydt: - c = gsl_odeiv_control_y_new (self.error_abs, self.error_rel) + c = gsl_odeiv_control_y_new(self.error_abs, self.error_rel) elif self.a and self.a_dydt: if not self.scale_abs: - c = gsl_odeiv_control_standard_new(self.error_abs,self.error_rel,self.a,self.a_dydt) - elif hasattr(self.scale_abs,'__len__'): + c = gsl_odeiv_control_standard_new(self.error_abs, self.error_rel, self.a, self.a_dydt) + elif hasattr(self.scale_abs, '__len__'): if len(self.scale_abs) == dim: - scale_abs_array = sig_malloc(dim*sizeof(double)) + scale_abs_array = sig_malloc(dim * sizeof(double)) for i in range(dim): - scale_abs_array[i]=self.scale_abs[i] - c = gsl_odeiv_control_scaled_new(self.error_abs,self.error_rel,self.a,self.a_dydt,scale_abs_array,dim) + scale_abs_array[i] = self.scale_abs[i] + c = gsl_odeiv_control_scaled_new(self.error_abs, self.error_rel, self.a, self.a_dydt, scale_abs_array, dim) if c == NULL: - gsl_odeiv_control_free (c) - gsl_odeiv_step_free (s) + gsl_odeiv_control_free(c) + gsl_odeiv_step_free(s) sig_free(y) sig_free(scale_abs_array) raise MemoryError("error setting up solver") cdef gsl_odeiv_evolve * e - e = gsl_odeiv_evolve_alloc(dim) + e = gsl_odeiv_evolve_alloc(dim) if e == NULL: - gsl_odeiv_control_free (c) - gsl_odeiv_step_free (s) + gsl_odeiv_control_free(c) + gsl_odeiv_step_free(s) sig_free(y) sig_free(scale_abs_array) raise MemoryError("error setting up solver") @@ -540,59 +535,59 @@ class ode_solver(): import copy cdef int n - if len(self.t_span)==2 and num_points: + if len(self.t_span) == 2 and num_points: try: n = num_points except TypeError: - gsl_odeiv_evolve_free (e) - gsl_odeiv_control_free (c) - gsl_odeiv_step_free (s) + gsl_odeiv_evolve_free(e) + gsl_odeiv_control_free(c) + gsl_odeiv_step_free(s) sig_free(y) sig_free(scale_abs_array) raise TypeError("numpoints must be integer") result.append((self.t_span[0], self.y_0)) - delta = (self.t_span[1]-self.t_span[0])/(1.0*num_points) + delta = (self.t_span[1] - self.t_span[0]) / (1.0 * num_points) t = self.t_span[0] - t_end = self.t_span[0]+delta + t_end = self.t_span[0] + delta for i in range(1, n + 1): - while (t < t_end): + while t < t_end: try: sig_on() - status = gsl_odeiv_evolve_apply (e, c, s, &sys, &t, t_end, &h, y) + status = gsl_odeiv_evolve_apply(e, c, s, &sys, &t, t_end, &h, y) sig_off() - if (status != GSL_SUCCESS): + if status != GSL_SUCCESS: raise RuntimeError except RuntimeError: - gsl_odeiv_evolve_free (e) - gsl_odeiv_control_free (c) - gsl_odeiv_step_free (s) + gsl_odeiv_evolve_free(e) + gsl_odeiv_control_free(c) + gsl_odeiv_step_free(s) sig_free(y) sig_free(scale_abs_array) raise ValueError("error solving") for j in range(dim): - v[j]= y[j] - result.append( (t,copy.copy(v)) ) + v[j] = y[j] + result.append((t, copy.copy(v))) t = t_end - t_end= t+delta + t_end = t + delta else: n = len(self.t_span) result.append((self.t_span[0], self.y_0)) t = self.t_span[0] for i in range(1, n): - t_end=self.t_span[i] - while (t < t_end): + t_end = self.t_span[i] + while t < t_end: try: sig_on() - status = gsl_odeiv_evolve_apply (e, c, s, &sys, &t, t_end, &h, y) + status = gsl_odeiv_evolve_apply(e, c, s, &sys, &t, t_end, &h, y) sig_off() - if (status != GSL_SUCCESS): + if status != GSL_SUCCESS: raise RuntimeError except RuntimeError: - gsl_odeiv_evolve_free (e) - gsl_odeiv_control_free (c) - gsl_odeiv_step_free (s) + gsl_odeiv_evolve_free(e) + gsl_odeiv_control_free(c) + gsl_odeiv_step_free(s) sig_free(y) sig_free(scale_abs_array) raise ValueError("error solving") @@ -603,9 +598,9 @@ class ode_solver(): t = self.t_span[i] - gsl_odeiv_evolve_free (e) - gsl_odeiv_control_free (c) - gsl_odeiv_step_free (s) + gsl_odeiv_evolve_free(e) + gsl_odeiv_control_free(c) + gsl_odeiv_step_free(s) sig_free(y) sig_free(scale_abs_array) self.solution = result diff --git a/src/sage/calculus/riemann.pyx b/src/sage/calculus/riemann.pyx index 6ec80d89aa7..385aa7a09f8 100644 --- a/src/sage/calculus/riemann.pyx +++ b/src/sage/calculus/riemann.pyx @@ -44,6 +44,9 @@ from sage.calculus.integration import numerical_integral import numpy as np cimport numpy as np +if int(np.version.short_version[0]) > 1: + np.set_printoptions(legacy="1.25") + from math import pi from math import sin from math import cos @@ -86,43 +89,42 @@ cdef class Riemann_Map: INPUT: - - ``fs`` -- A list of the boundaries of the region, given as + - ``fs`` -- list of the boundaries of the region, given as complex-valued functions with domain `0` to `2*pi`. Note that the outer boundary must be parameterized counter clockwise (i.e. ``e^(I*t)``) while the inner boundaries must be clockwise (i.e. ``e^(-I*t)``). - - ``fprimes`` -- A list of the derivatives of the boundary functions. - Must be in the same order as ``fs``. + - ``fprimes`` -- list of the derivatives of the boundary functions + (Must be in the same order as ``fs``) - - ``a`` -- Complex, the center of the Riemann map. Will be mapped to + - ``a`` -- complex, the center of the Riemann map. Will be mapped to the origin of the unit disc. Note that ``a`` MUST be within the region in order for the results to be mathematically valid. The following inputs may be passed in as named parameters: - - ``N`` -- integer (default: ``500``), the number of collocation points + - ``N`` -- integer (default: `500`); the number of collocation points used to compute the map. More points will give more accurate results, especially near the boundaries, but will take longer to compute. - - ``exterior`` -- boolean (default: ``False``), if set to ``True``, the + - ``exterior`` -- boolean (default: ``False``); if set to ``True``, the exterior map will be computed, mapping the exterior of the region to the exterior of the unit circle. The following inputs may be passed as named parameters in unusual circumstances: - - ``ncorners`` -- integer (default: ``4``), if mapping a figure with + - ``ncorners`` -- integer (default: `4`); if mapping a figure with (equally t-spaced) corners -- corners that make a significant change in the direction of the boundary -- better results may be sometimes obtained by accurately giving this parameter. Used to add the proper constant to the theta correspondence function. - - ``opp`` -- boolean (default: ``False``), set to ``True`` in very rare + - ``opp`` -- boolean (default: ``False``); set to ``True`` in very rare cases where the theta correspondence function is off by ``pi``, that is, if red is mapped left of the origin in the color plot. - EXAMPLES: The unit circle identity map:: @@ -187,8 +189,6 @@ cdef class Riemann_Map: This class computes the Riemann Map via the Szego kernel using an adaptation of the method described by [KT1986]_. - - """ cdef int N, B, ncorners cdef f @@ -202,9 +202,8 @@ cdef class Riemann_Map: def __init__(self, fs, fprimes, COMPLEX_T a, int N=500, int ncorners=4, opp=False, exterior = False): - """ - Initializes the ``Riemann_Map`` class. See the class :class:`Riemann_Map` + Initialize the ``Riemann_Map`` class. See the class :class:`Riemann_Map` for full documentation on the input of this initialization method. TESTS:: @@ -385,12 +384,12 @@ cdef class Riemann_Map: The following inputs may be passed in as named parameters: - - ``boundary`` -- integer (default: ``-1``) if < 0, + - ``boundary`` -- integer (default: `-1`); if < 0, :meth:`get_theta_points` will return the points for all boundaries. If >= 0, :meth:`get_theta_points` will return only the points for the boundary specified. - - ``absolute_value`` -- boolean (default: ``False``) if ``True``, will + - ``absolute_value`` -- boolean (default: ``False``); if ``True``, will return the absolute value of the (complex valued) Szego kernel instead of the kernel itself. Useful for plotting. @@ -465,7 +464,7 @@ cdef class Riemann_Map: The following input must all be passed in as named parameters: - - ``boundary`` -- integer (default: ``-1``) if < 0, + - ``boundary`` -- integer (default: `-1`); if < 0, ``get_theta_points()`` will return the points for all boundaries. If >= 0, ``get_theta_points()`` will return only the points for the boundary specified. @@ -580,8 +579,8 @@ cdef class Riemann_Map: INPUT: - - ``pt`` -- A complex number representing the point to be - inverse mapped. + - ``pt`` -- a complex number representing the point to be + inverse mapped OUTPUT: @@ -667,12 +666,10 @@ cdef class Riemann_Map: INPUT: - - ``pt`` -- A complex number (usually with absolute value <= 1) - representing the point to be inverse mapped. - - OUTPUT: + - ``pt`` -- a complex number (usually with absolute value <= 1) + representing the point to be inverse mapped - The point on the region that Riemann maps to the input point. + OUTPUT: the point on the region that Riemann maps to the input point EXAMPLES: @@ -718,17 +715,17 @@ cdef class Riemann_Map: The following inputs may be passed in as named parameters: - - ``plotjoined`` -- boolean (default: ``True``) If ``False``, + - ``plotjoined`` -- boolean (default: ``True``); if ``False``, discrete points will be drawn; otherwise they will be connected by lines. In this case, if ``plotjoined=False``, the points shown will be the original collocation points used to generate the Riemann map. - ``rgbcolor`` -- float array (default: ``[0,0,0]``) the - red-green-blue color of the boundary. + red-green-blue color of the boundary - ``thickness`` -- positive float (default: ``1``) the thickness of - the lines or points in the boundary. + the lines or points in the boundary EXAMPLES: @@ -772,12 +769,12 @@ cdef class Riemann_Map: INPUT: - - ``plot_range`` -- a tuple of the form ``[xmin, xmax, ymin, ymax]``. - If the value is ``[]``, the default plotting window of the map will - be used. + - ``plot_range`` -- tuple of the form ``[xmin, xmax, ymin, ymax]``; + if the value is ``[]``, the default plotting window of the map will + be used - - ``x_points`` -- int, the size of the grid in the x direction - The number of points in the y_direction is scaled accordingly + - ``x_points`` -- integer; the size of the grid in the x direction; + the number of points in the y direction is scaled accordingly OUTPUT: @@ -853,42 +850,43 @@ cdef class Riemann_Map: The following inputs may be passed in as named parameters: - - ``spokes`` -- integer (default: ``16``) the number of equally - spaced radial lines to plot. + - ``spokes`` -- integer (default: 16); the number of equally + spaced radial lines to plot - - ``circles`` -- integer (default: ``4``) the number of equally - spaced circles about the center to plot. + - ``circles`` -- integer (default: 4); the number of equally + spaced circles about the center to plot - - ``pts`` -- integer (default: ``32``) the number of points to + - ``pts`` -- integer (default: 32); the number of points to plot. Each radial line is made by ``1*pts`` points, each circle has ``2*pts`` points. Note that high values may cause erratic behavior of the radial lines near the boundaries. - only for simply connected domains - - ``linescale`` -- float between 0 and 1. Shrinks the radial lines - away from the boundary to reduce erratic behavior. + - ``linescale`` -- float between 0 and 1; shrinks the radial lines + away from the boundary to reduce erratic behavior - only for simply connected domains - - ``rgbcolor`` -- float array (default: ``[0,0,0]``) the - red-green-blue color of the spiderweb. + - ``rgbcolor`` -- float array (default: ``[0,0,0]``); the + red-green-blue color of the spiderweb - - ``thickness`` -- positive float (default: ``1``) the thickness of - the lines or points in the spiderweb. + - ``thickness`` -- positive float (default: 1); the thickness of + the lines or points in the spiderweb - - ``plotjoined`` -- boolean (default: ``True``) If ``False``, + - ``plotjoined`` -- boolean (default: ``True``); if ``False``, discrete points will be drawn; otherwise they will be connected - by lines. + by lines - only for simply connected domains - - ``withcolor`` -- boolean (default: ``False``) If ``True``, - The spiderweb will be overlaid on the basic color plot. + - ``withcolor`` -- boolean (default: ``False``); if ``True``, + the spiderweb will be overlaid on the basic color plot - - ``plot_points`` -- integer (default: ``200``) the size of the grid in the x direction - The number of points in the y_direction is scaled accordingly. - Note that very large values can cause this function to run slowly. + - ``plot_points`` -- integer (default: 200); the size of the grid + in the x direction. The number of points in the y_direction is scaled + accordingly. Note that very large values can cause this function to + run slowly. - only for multiply connected domains - - ``min_mag`` -- float (default: ``0.001``) The magnitude cutoff + - ``min_mag`` -- float (default: 0.001); the magnitude cutoff below which spiderweb points are not drawn. This only applies to multiply connected domains and is designed to prevent "fuzz" at the edge of the domain. Some complicated multiply @@ -1018,12 +1016,11 @@ cdef class Riemann_Map: ``(xmin, xmax, ymin, ymax)``. Declare if you do not want the plot to use the default range for the figure. - - ``plot_points`` -- integer (default: ``100``), number of points to + - ``plot_points`` -- integer (default: 100); number of points to plot in the x direction. Points in the y direction are scaled accordingly. Note that very large values can cause this function to run slowly. - EXAMPLES: Given a Riemann map m, general usage:: @@ -1072,10 +1069,10 @@ cdef comp_pt(clist, loop=True): INPUT: - - ``clist`` -- a list of complex numbers. + - ``clist`` -- list of complex numbers - - ``loop`` -- boolean (default: ``True``) controls whether or not the - first point will be added as the last to plot a closed circle. + - ``loop`` -- boolean (default: ``True``); controls whether or not the + first point will be added as the last to plot a closed circle EXAMPLES: @@ -1095,7 +1092,7 @@ cdef comp_pt(clist, loop=True): cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2] z_values, FLOAT_T xstep, FLOAT_T ystep): """ - Computes the r*e^(I*theta) form of derivatives from the grid of points. The + Compute the r*e^(I*theta) form of derivatives from the grid of points. The derivatives are computed using quick-and-dirty taylor expansion and assuming analyticity. As such ``get_derivatives`` is primarily intended to be used for comparisons in ``plot_spiderweb`` and not for @@ -1103,8 +1100,8 @@ cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2] z_values, FLOAT_T xstep, INPUT: - - ``z_values`` -- The values for a complex function evaluated on a grid - in the complex plane, usually from ``compute_on_grid``. + - ``z_values`` -- the values for a complex function evaluated on a grid + in the complex plane, usually from ``compute_on_grid`` - ``xstep`` -- float, the spacing of the grid points in the real direction @@ -1151,34 +1148,34 @@ cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2] z_values, np.ndarray[FLOAT_T, ndim = 2] dr, np.ndarray[FLOAT_T, ndim = 2] dtheta, spokes, circles, rgbcolor, thickness, withcolor, min_mag): """ - Converts a grid of complex numbers into a matrix containing rgb data + Convert a grid of complex numbers into a matrix containing rgb data for the Riemann spiderweb plot. INPUT: - - ``z_values`` -- A grid of complex numbers, as a list of lists. + - ``z_values`` -- a grid of complex numbers, as a list of lists - - ``dr`` -- grid of floats, the r derivative of ``z_values``. - Used to determine precision. + - ``dr`` -- grid of floats, the r derivative of ``z_values`` + Used to determine precision - - ``dtheta`` -- grid of floats, the theta derivative of ``z_values``. - Used to determine precision. + - ``dtheta`` -- grid of floats, the theta derivative of ``z_values`` + Used to determine precision - - ``spokes`` -- integer; the number of equally spaced radial lines to plot. + - ``spokes`` -- integer; the number of equally spaced radial lines to plot - ``circles`` -- integer; the number of equally spaced circles about the - center to plot. + center to plot - ``rgbcolor`` -- float array; the red-green-blue color of the - lines of the spiderweb. + lines of the spiderweb - ``thickness`` -- positive float; the thickness of the lines or points - in the spiderweb. + in the spiderweb - - ``withcolor`` -- boolean; If ``True`` the spiderweb will be overlaid - on the basic color plot. + - ``withcolor`` -- boolean; if ``True`` the spiderweb will be overlaid + on the basic color plot - - ``min_mag`` -- float; The magnitude cutoff below which spiderweb + - ``min_mag`` -- float; the magnitude cutoff below which spiderweb points are not drawn. This only applies to multiply connected domains and is designed to prevent "fuzz" at the edge of the domain. Some complicated multiply connected domains (particularly @@ -1274,7 +1271,7 @@ cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim = 2] z_values): INPUT: - - ``z_values`` -- A Numpy array of complex numbers. + - ``z_values`` -- numpy array of complex numbers OUTPUT: @@ -1372,18 +1369,19 @@ cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim = 2] z_values): return rgb cpdef analytic_boundary(FLOAT_T t, int n, FLOAT_T epsilon): - """ - Provides an exact (for n = infinity) Riemann boundary - correspondence for the ellipse with axes 1 + epsilon and 1 - epsilon. The - boundary is therefore given by e^(I*t)+epsilon*e^(-I*t). It is primarily - useful for testing the accuracy of the numerical :class:`Riemann_Map`. + r""" + Provides an exact (for `n = \infty`) Riemann boundary + correspondence for the ellipse with axes `1 + \epsilon` and `1 - \epsilon`. + The boundary is therefore given by `\exp(I t)+\epsilon\exp(-I t)`. It is + primarily useful for testing the accuracy of the numerical + :class:`Riemann_Map`. INPUT: - - ``t`` -- The boundary parameter, from 0 to 2*pi + - ``t`` -- the boundary parameter, from `0` to `2 \pi` - - ``n`` -- integer; the number of terms to include. - 10 is fairly accurate, 20 is very accurate. + - ``n`` -- integer; the number of terms to include + (10 is fairly accurate, 20 is very accurate) - ``epsilon`` -- float; the skew of the ellipse (0 is circular) @@ -1426,16 +1424,16 @@ cpdef cauchy_kernel(t, args): INPUT: - - ``t`` -- The boundary parameter, meant to be integrated over + - ``t`` -- the boundary parameter, meant to be integrated over - - ``args`` -- a tuple containing: + - ``args`` -- tuple containing: - ``epsilon`` -- float; the skew of the ellipse (0 is circular) - - ``z`` -- complex; the point to be mapped. + - ``z`` -- complex; the point to be mapped - - ``n`` -- integer; the number of terms to include. - 10 is fairly accurate, 20 is very accurate. + - ``n`` -- integer; the number of terms to include + (10 is fairly accurate, 20 is very accurate) - ``part`` -- will return the real ('r'), imaginary ('i') or complex ('c') value of the kernel @@ -1474,10 +1472,10 @@ cpdef analytic_interior(COMPLEX_T z, int n, FLOAT_T epsilon): INPUT: - - ``z`` -- complex; the point to be mapped. + - ``z`` -- complex; the point to be mapped - - ``n`` -- integer; the number of terms to include. - 10 is fairly accurate, 20 is very accurate. + - ``n`` -- integer; the number of terms to include + (10 is fairly accurate, 20 is very accurate) TESTS: diff --git a/src/sage/calculus/transforms/dft.py b/src/sage/calculus/transforms/dft.py index cd0c76bfc07..bccfbcb8017 100644 --- a/src/sage/calculus/transforms/dft.py +++ b/src/sage/calculus/transforms/dft.py @@ -93,11 +93,11 @@ class IndexedSequence(SageObject): INPUT: - - ``L`` -- A list + - ``L`` -- list - - ``index_object`` must be a Sage object with an ``__iter__`` method + - ``index_object`` -- must be a Sage object with an ``__iter__`` method containing the same number of elements as ``self``, which is a - list of elements taken from a field. + list of elements taken from a field """ def __init__(self, L, index_object): r""" @@ -203,7 +203,7 @@ def index_object(self): def _repr_(self): """ - Implements print method. + Implement print method. EXAMPLES:: @@ -474,12 +474,10 @@ def convolution(self, other): INPUT: - - ``other`` -- a collection of elements of a ring with + - ``other`` -- a collection of elements of a ring with index set a finite abelian group (under `+`) - OUTPUT: - - The Dirichlet convolution of ``self`` and ``other``. + OUTPUT: the Dirichlet convolution of ``self`` and ``other`` EXAMPLES:: @@ -533,11 +531,9 @@ def convolution_periodic(self, other): INPUT: - - ``other`` -- a sequence of elements of `\CC`, `\RR` or `\GF{q}` - - OUTPUT: + - ``other`` -- a sequence of elements of `\CC`, `\RR` or `\GF{q}` - The Dirichlet convolution of ``self`` and ``other``. + OUTPUT: the Dirichlet convolution of ``self`` and ``other`` EXAMPLES:: @@ -578,7 +574,7 @@ def convolution_periodic(self, other): def __mul__(self, other): """ - Implements scalar multiplication (on the right). + Implement scalar multiplication (on the right). EXAMPLES:: @@ -598,7 +594,7 @@ def __mul__(self, other): def __eq__(self, other): """ - Implements boolean equals. + Implement boolean equals. EXAMPLES:: @@ -668,7 +664,7 @@ def fft(self): def ifft(self): """ - Implements the gsl ``FastFourierTransform.inverse`` in + Implement the gsl ``FastFourierTransform.inverse`` in :mod:`~sage.calculus.transforms.fft`. If the number of sample points in the input is a power of 2 @@ -703,7 +699,7 @@ def ifft(self): a.inverse_transform() return IndexedSequence([a[j][0] + I * a[j][1] for j in J], J) - def dwt(self, other="haar", wavelet_k=2): + def dwt(self, other='haar', wavelet_k=2): r""" Wraps the gsl ``WaveletTransform.forward`` in :mod:`~sage.calculus.transforms.dwt` (written by Joshua Kantor). Assumes the length of the sample is a @@ -720,9 +716,9 @@ def dwt(self, other="haar", wavelet_k=2): * ``'bspline'`` * ``'bspline_centered'`` - - ``wavelet_k`` -- For daubechies wavelets, ``wavelet_k`` specifies a - daubechie wavelet with `k/2` vanishing moments. - `k = 4,6,...,20` for `k` even are the only ones implemented. + - ``wavelet_k`` -- for daubechies wavelets, ``wavelet_k`` specifies a + daubechie wavelet with `k/2` vanishing moments; + `k = 4,6,...,20` for `k` even are the only ones implemented For Haar wavelets, ``wavelet_k`` must be 2. @@ -767,9 +763,9 @@ def dwt(self, other="haar", wavelet_k=2): a.forward_transform() return IndexedSequence([RR(a[j]) for j in J], J) - def idwt(self, other="haar", wavelet_k=2): + def idwt(self, other='haar', wavelet_k=2): r""" - Implements the gsl ``WaveletTransform.backward()`` in + Implement the gsl ``WaveletTransform.backward()`` in :mod:`~sage.calculus.transforms.dwt`. Assumes the length of the sample is a power of 2. Uses the @@ -777,18 +773,18 @@ def idwt(self, other="haar", wavelet_k=2): INPUT: - - ``other`` -- Must be one of the following: + - ``other`` -- must be one of the following: - * ``"haar"`` - * ``"daubechies"`` - * ``"daubechies_centered"`` - * ``"haar_centered"`` - * ``"bspline"`` - * ``"bspline_centered"`` + * ``'haar'`` + * ``'daubechies'`` + * ``'daubechies_centered'`` + * ``'haar_centered'`` + * ``'bspline'`` + * ``'bspline_centered'`` - - ``wavelet_k`` -- For daubechies wavelets, ``wavelet_k`` specifies a - daubechie wavelet with `k/2` vanishing moments. - `k = 4,6,...,20` for `k` even are the only ones implemented. + - ``wavelet_k`` -- for daubechies wavelets, ``wavelet_k`` specifies a + daubechie wavelet with `k/2` vanishing moments; + `k = 4,6,...,20` for `k` even are the only ones implemented For Haar wavelets, ``wavelet_k`` must be 2. diff --git a/src/sage/calculus/transforms/dwt.pyx b/src/sage/calculus/transforms/dwt.pyx index c88cd12d17f..fdb68153a8b 100644 --- a/src/sage/calculus/transforms/dwt.pyx +++ b/src/sage/calculus/transforms/dwt.pyx @@ -28,7 +28,7 @@ def WaveletTransform(n, wavelet_type, wavelet_k): INPUT: - - ``n`` -- a power of 2 + - ``n`` -- a power of 2 - ``T`` -- the data in the GSLDoubleArray must be real - ``wavelet_type`` -- the name of the type of wavelet, valid choices are: diff --git a/src/sage/calculus/transforms/fft.pyx b/src/sage/calculus/transforms/fft.pyx index ca7fd73cb64..1f190f00685 100644 --- a/src/sage/calculus/transforms/fft.pyx +++ b/src/sage/calculus/transforms/fft.pyx @@ -32,8 +32,8 @@ def FastFourierTransform(size, base_ring=None): INPUT: - - ``size`` -- The size of the array - - ``base_ring`` -- Unused (2013-03) + - ``size`` -- the size of the array + - ``base_ring`` -- unused (2013-03) EXAMPLES: @@ -72,7 +72,6 @@ def FastFourierTransform(size, base_ring=None): sage: a.plot().show(ymin=0) # needs sage.plot sage: a.forward_transform() sage: a.plot().show() # needs sage.plot - """ return FastFourierTransform_complex(int(size)) @@ -95,8 +94,8 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): INPUT: - - ``n`` -- An integer, the size of the array - - ``stride`` -- The stride to be applied when manipulating the array. + - ``n`` -- integer, the size of the array + - ``stride`` -- the stride to be applied when manipulating the array EXAMPLES:: @@ -126,14 +125,13 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): """ Return the size of the array. - OUTPUT: The size of the array. + OUTPUT: the size of the array EXAMPLES:: sage: a = FastFourierTransform(48) sage: len(a) 48 - """ return self.n @@ -146,8 +144,8 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): INPUT: - - ``i`` -- An integer, the index. - - ``xy`` -- An object to store as `i`-th element of the array ``self[i]``. + - ``i`` -- integer; the index + - ``xy`` -- an object to store as `i`-th element of the array ``self[i]`` EXAMPLES:: @@ -177,15 +175,13 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): def __getitem__(self, i): """ - Gets the `i`-th element of the array. + Get the `i`-th element of the array. INPUT: - - ``i``: An integer. - - OUTPUT: + - ``i`` -- integer - - The `i`-th element of the array ``self[i]``. + OUTPUT: the `i`-th element of the array ``self[i]`` EXAMPLES:: @@ -195,7 +191,6 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a[0] = 1 sage: a[0] == (1,0) True - """ if isinstance(i, slice): start, stop, step = i.indices(self.n) @@ -220,7 +215,6 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: for i in range(4): a[i] = i sage: a [(0.0, 0.0), (1.0, 0.0), (2.0, 0.0), (3.0, 0.0)] - """ return str(list(self)) @@ -230,13 +224,11 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): INPUT: - - ``xmin`` -- The lower bound of the slice to plot. - - ``xmax`` -- The upper bound of the slice to plot. - - ``**args`` -- passed on to the line plotting function. + - ``xmin`` -- the lower bound of the slice to plot + - ``xmax`` -- the upper bound of the slice to plot + - ``**args`` -- passed on to the line plotting function - OUTPUT: - - - A plot of the array interpreting each element as polar coordinates. + OUTPUT: a plot of the array interpreting each element as polar coordinates This method should not be called directly. See :meth:`plot` for the details. @@ -245,7 +237,6 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a = FastFourierTransform(4) sage: a._plot_polar(0,2) # needs sage.plot sage.symbolic Graphics object consisting of 2 graphics primitives - """ from sage.plot.point import point from sage.symbolic.constants import pi, I @@ -270,13 +261,11 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): INPUT: - - ``xmin`` -- The lower bound of the slice to plot. - - ``xmax`` -- The upper bound of the slice to plot. - - ``**args`` -- passed on to the line plotting function. - - OUTPUT: + - ``xmin`` -- the lower bound of the slice to plot + - ``xmax`` -- the upper bound of the slice to plot + - ``**args`` -- passed on to the line plotting function - - A plot of the array. + OUTPUT: a plot of the array This method should not be called directly. See :meth:`plot` for the details. @@ -302,20 +291,18 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): """ Plot a slice of the array. - - ``style`` -- Style of the plot, options are ``"rect"`` or ``"polar"`` + - ``style`` -- style of the plot, options are ``'rect'`` or ``'polar'`` - - ``"rect"`` -- height represents real part, color represents - imaginary part. - - ``"polar"`` -- height represents absolute value, color - represents argument. + - ``'rect'`` -- height represents real part, color represents + imaginary part + - ``'polar'`` -- height represents absolute value, color + represents argument - - ``xmin`` -- The lower bound of the slice to plot. 0 by default. - - ``xmax`` -- The upper bound of the slice to plot. ``len(self)`` by default. - - ``**args`` -- passed on to the line plotting function. + - ``xmin`` -- the lower bound of the slice to plot; 0 by default + - ``xmax`` -- the upper bound of the slice to plot; ``len(self)`` by default + - ``**args`` -- passed on to the line plotting function - OUTPUT: - - - A plot of the array. + OUTPUT: a plot of the array EXAMPLES:: @@ -336,7 +323,6 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a.inverse_transform() sage: a.plot() + b.plot() Graphics object consisting of 250 graphics primitives - """ if xmin is None: xmin = 0 @@ -358,9 +344,7 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): Compute the in-place forward Fourier transform of this data using the Cooley-Tukey algorithm. - OUTPUT: - - - None, the transformation is done in-place. + OUTPUT: none, the transformation is done in-place If the number of sample points in the input is a power of 2 then the gsl function ``gsl_fft_complex_radix2_forward`` is automatically called. @@ -373,7 +357,6 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a.forward_transform() sage: a #abs tol 1e-2 [(6.0, 0.0), (-2.0, 2.0), (-2.0, 0.0), (-2.0, -2.0)] - """ cdef gsl_fft_complex_wavetable * wt cdef gsl_fft_complex_workspace * mem @@ -393,9 +376,7 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): Compute the in-place inverse Fourier transform of this data using the Cooley-Tukey algorithm. - OUTPUT: - - - None, the transformation is done in-place. + OUTPUT: none, the transformation is done in-place If the number of sample points in the input is a power of 2 then the function ``gsl_fft_complex_radix2_inverse`` is automatically called. @@ -427,7 +408,6 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a.inverse_transform() sage: a.plot() + b.plot() # needs sage.plot Graphics object consisting of 256 graphics primitives - """ cdef gsl_fft_complex_wavetable * wt cdef gsl_fft_complex_workspace * mem @@ -447,9 +427,7 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): Compute the in-place backwards Fourier transform of this data using the Cooley-Tukey algorithm. - OUTPUT: - - - None, the transformation is done in-place. + OUTPUT: none, the transformation is done in-place This is the same as :meth:`inverse_transform` but lacks normalization so that ``f.forward_transform().backward_transform() == n*f``. Where diff --git a/src/sage/calculus/transforms/meson.build b/src/sage/calculus/transforms/meson.build new file mode 100644 index 00000000000..05d3fb59637 --- /dev/null +++ b/src/sage/calculus/transforms/meson.build @@ -0,0 +1,21 @@ +py.install_sources( + 'all.py', + 'dft.py', + 'dwt.pxd', + 'fft.pxd', + subdir: 'sage/calculus/transforms', +) + +extension_data = {'dwt' : files('dwt.pyx'), 'fft' : files('fft.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/calculus/transforms', + install: true, + include_directories: [inc_gsl], + dependencies: [py_dep, cysignals, gmp, gsl], + ) +endforeach + diff --git a/src/sage/calculus/var.pyx b/src/sage/calculus/var.pyx index 97170624389..4967bb9bd9a 100644 --- a/src/sage/calculus/var.pyx +++ b/src/sage/calculus/var.pyx @@ -13,7 +13,7 @@ def var(*args, **kwds): INPUT: - - ``args`` -- A single string ``var('x y')``, a list of strings + - ``args`` -- a single string ``var('x y')``, a list of strings ``var(['x','y'])``, or multiple strings ``var('x', 'y')``. A single string can be either a single variable name, or a space or comma separated list of variable names. In a list or tuple of @@ -22,7 +22,7 @@ def var(*args, **kwds): before or after variable names are ignored. - ``kwds`` -- keyword arguments can be given to specify domain and - custom latex_name for variables. See EXAMPLES for usage. + custom latex_name for variables; see EXAMPLES for usage .. NOTE:: @@ -36,7 +36,7 @@ def var(*args, **kwds): If a single symbolic variable was created, the variable itself. Otherwise, a tuple of symbolic variables. The variable names are checked to be valid Python identifiers and a - :class:`ValueError` is raised otherwise. + :exc:`ValueError` is raised otherwise. EXAMPLES: @@ -77,12 +77,12 @@ def var(*args, **kwds): Custom latex expression can be assigned to variable:: - sage: x = var('sui', latex_name="s_{u,i}"); x._latex_() + sage: x = var('sui', latex_name='s_{u,i}'); x._latex_() '{s_{u,i}}' In notebook, we can also colorize latex expression:: - sage: x = var('sui', latex_name="\\color{red}{s_{u,i}}"); x._latex_() + sage: x = var('sui', latex_name='\\color{red}{s_{u,i}}'); x._latex_() '{\\color{red}{s_{u,i}}}' We can substitute a new variable name for n:: @@ -139,11 +139,11 @@ def function(s, **kwds): - ``nargs=0`` -- number of arguments the function accepts, defaults to variable number of arguments, or 0 - ``latex_name`` -- name used when printing in latex mode - - ``conversions`` -- a dictionary specifying names of this function in + - ``conversions`` -- dictionary specifying names of this function in other systems, this is used by the interfaces internally during conversion - ``eval_func`` -- method used for automatic evaluation - ``evalf_func`` -- method used for numeric evaluation - - ``evalf_params_first`` -- bool to indicate if parameters should be + - ``evalf_params_first`` -- boolean to indicate if parameters should be evaluated numerically before calling the custom evalf function - ``conjugate_func`` -- method used for complex conjugation - ``real_part_func`` -- method used when taking real parts @@ -215,7 +215,7 @@ def function(s, **kwds): Custom typesetting of symbolic functions in LaTeX, either using latex_name keyword:: - sage: function('riemann', latex_name="\\mathcal{R}") + sage: function('riemann', latex_name='\\mathcal{R}') riemann sage: latex(riemann(x)) \mathcal{R}\left(x\right) diff --git a/src/sage/categories/action.pyx b/src/sage/categories/action.pyx index 0f49a368f3e..73be8d625bf 100644 --- a/src/sage/categories/action.pyx +++ b/src/sage/categories/action.pyx @@ -85,7 +85,7 @@ cdef class Action(Functor): - ``S`` -- a parent or Python type - - ``is_left`` -- (boolean, default: ``True``) whether elements of + - ``is_left`` -- boolean (default: ``True``); whether elements of ``G`` are on the left - ``op`` -- (default: ``None``) operation. This is not used by @@ -200,9 +200,9 @@ cdef class Action(Functor): INPUT: - - ``g`` -- an object with parent ``self.G``. + - ``g`` -- an object with parent ``self.G`` - - ``x`` -- an object with parent ``self.US()``. + - ``x`` -- an object with parent ``self.US()`` .. WARNING:: diff --git a/src/sage/categories/additive_magmas.py b/src/sage/categories/additive_magmas.py index 00f7f80cd9b..ccfda512014 100644 --- a/src/sage/categories/additive_magmas.py +++ b/src/sage/categories/additive_magmas.py @@ -60,7 +60,6 @@ class AdditiveMagmas(Category_singleton): sage: C = AdditiveMagmas() sage: TestSuite(C).run() - """ def super_categories(self): @@ -176,7 +175,7 @@ def summation(self, x, y): INPUT: - - ``x``, ``y`` -- elements of this additive magma + - ``x``, ``y`` -- elements of this additive magma EXAMPLES:: @@ -401,9 +400,7 @@ def _add_(self, right): - ``self``, ``right`` -- two elements with the same parent - OUTPUT: - - - an element of the same parent + OUTPUT: an element of the same parent EXAMPLES:: @@ -425,9 +422,7 @@ def _add_parent(self, other): - ``other`` -- an element of the parent of ``self`` - OUTPUT: - - - an element of the parent of ``self`` + OUTPUT: an element of the parent of ``self`` EXAMPLES:: @@ -656,7 +651,7 @@ class ParentMethods: def _test_zero(self, **options): r""" - Test that ``self.zero()`` is an element of self and + Test that ``self.zero()`` is an element of ``self`` and is neutral for the addition. INPUT: @@ -778,7 +773,7 @@ def __bool__(self): All parents in the category ``CommutativeAdditiveMonoids()`` should implement this method. - .. note:: This is currently not useful because this method is + .. NOTE:: This is currently not useful because this method is overridden by ``Element``. TESTS:: @@ -955,7 +950,7 @@ def extra_super_categories(self): class ParentMethods: def zero(self): r""" - Returns the zero of this group + Return the zero of this group. EXAMPLES:: @@ -976,8 +971,8 @@ def extra_super_categories(self): [Category of unital magmas] sage: C.super_categories() - [Category of unital algebras with basis over Rational Field, - Category of additive magma algebras over Rational Field] + [Category of additive magma algebras over Rational Field, + Category of unital algebras with basis over Rational Field] """ from sage.categories.magmas import Magmas return [Magmas().Unital()] diff --git a/src/sage/categories/additive_monoids.py b/src/sage/categories/additive_monoids.py index 3d76c87113b..70a195f582e 100644 --- a/src/sage/categories/additive_monoids.py +++ b/src/sage/categories/additive_monoids.py @@ -56,7 +56,7 @@ def sum(self, args): INPUT: - - ``args`` -- a list (or iterable) of elements of ``self`` + - ``args`` -- list (or iterable) of elements of ``self`` EXAMPLES:: diff --git a/src/sage/categories/affine_weyl_groups.py b/src/sage/categories/affine_weyl_groups.py index 9a26f8c5590..71dfcd2350a 100644 --- a/src/sage/categories/affine_weyl_groups.py +++ b/src/sage/categories/affine_weyl_groups.py @@ -17,7 +17,7 @@ class AffineWeylGroups(Category_singleton): """ - The category of affine Weyl groups + The category of affine Weyl groups. .. TODO:: add a description of this category @@ -125,9 +125,9 @@ def select_length(pair): def succ(pair): u, length = pair - for i in u.descents(positive=True, side="left"): + for i in u.descents(positive=True, side='left'): u1 = u.apply_simple_reflection(i, "left") - if (length < k and i == u1.first_descent(side="left") and + if (length < k and i == u1.first_descent(side='left') and u1.is_affine_grassmannian()): yield (u1, length + 1) return @@ -220,9 +220,7 @@ def affine_grassmannian_to_partition(self): - ``self`` is affine Grassmannian element of the affine Weyl group of type `A_k^{(1)}` (i.e. all reduced words end in 0) - OUTPUT: - - - `k`-bounded partition + OUTPUT: `k`-bounded partition .. SEEALSO:: :meth:`affine_grassmannian_to_core` diff --git a/src/sage/categories/algebra_functor.py b/src/sage/categories/algebra_functor.py index ec3c2ba8616..ae5ef793296 100644 --- a/src/sage/categories/algebra_functor.py +++ b/src/sage/categories/algebra_functor.py @@ -128,7 +128,6 @@ Category of semigroup algebras over Rational Field, ... Category of unital magma algebras over Rational Field, - ... Category of magma algebras over Rational Field, ... Category of set algebras over Rational Field, @@ -592,9 +591,7 @@ def _apply_functor(self, base_ring): - ``base_ring`` -- the base ring of the group algebra - OUTPUT: - - A group algebra. + OUTPUT: a group algebra EXAMPLES:: @@ -615,9 +612,7 @@ def _apply_functor_to_morphism(self, f): - ``f`` -- a morphism of rings - OUTPUT: - - A morphism of group algebras. + OUTPUT: a morphism of group algebras EXAMPLES:: diff --git a/src/sage/categories/algebra_ideals.py b/src/sage/categories/algebra_ideals.py index c973743adc1..22719fb9974 100644 --- a/src/sage/categories/algebra_ideals.py +++ b/src/sage/categories/algebra_ideals.py @@ -85,7 +85,6 @@ def super_categories(self): sage: C = AlgebraIdeals(FreeAlgebra(QQ, 2, 'a,b')) # needs sage.combinat sage.modules sage: C.super_categories() # needs sage.combinat sage.modules [] - """ R = self.algebra() try: diff --git a/src/sage/categories/algebra_modules.py b/src/sage/categories/algebra_modules.py index 8a84fa109d7..64a7ca3014a 100644 --- a/src/sage/categories/algebra_modules.py +++ b/src/sage/categories/algebra_modules.py @@ -32,7 +32,6 @@ class AlgebraModules(Category_module): the categories of left and right modules are isomorphic. Feedback and use cases for potential generalizations to the non commutative case are welcome. - """ def __init__(self, A): """ @@ -67,7 +66,7 @@ def __init__(self, A): @classmethod def an_instance(cls): """ - Returns an instance of this class + Return an instance of this class. EXAMPLES:: diff --git a/src/sage/categories/algebras.py b/src/sage/categories/algebras.py index 7dcf02467ff..3a2bf0f5c3e 100644 --- a/src/sage/categories/algebras.py +++ b/src/sage/categories/algebras.py @@ -62,7 +62,7 @@ class Algebras(CategoryWithAxiom_over_base_ring): # For backward compatibility? def __contains__(self, x): """ - Membership testing + Membership testing. EXAMPLES:: @@ -224,7 +224,7 @@ class ElementMethods: # TODO: move the content of AlgebraElement here or higher in the category hierarchy def _div_(self, y): """ - Division by invertible elements + Division by invertible elements. # TODO: move in Monoids @@ -273,7 +273,7 @@ def algebra_generators(self): class CartesianProducts(CartesianProductsCategory): """ - The category of algebras constructed as Cartesian products of algebras + The category of algebras constructed as Cartesian products of algebras. This construction gives the direct product of algebras. See discussion on: @@ -327,7 +327,7 @@ class DualObjects(DualObjectsCategory): def extra_super_categories(self): r""" - Return the dual category + Return the dual category. EXAMPLES: diff --git a/src/sage/categories/algebras_with_basis.py b/src/sage/categories/algebras_with_basis.py index e0ebfb46184..73383dd329b 100644 --- a/src/sage/categories/algebras_with_basis.py +++ b/src/sage/categories/algebras_with_basis.py @@ -309,7 +309,7 @@ class ParentMethods: @cached_method def one_basis(self): """ - Returns the index of the one of this tensor product of + Return the index of the one of this tensor product of algebras, as per ``AlgebrasWithBasis.ParentMethods.one_basis`` It is the tuple whose operands are the indices of the @@ -372,6 +372,6 @@ def product_on_basis(self, t1, t2): class ElementMethods: """ - Implements operations on elements of tensor products of algebras with basis + Implement operations on elements of tensor products of algebras with basis """ pass diff --git a/src/sage/categories/bialgebras.py b/src/sage/categories/bialgebras.py index eeb89f4f61b..87b5bc5afe6 100644 --- a/src/sage/categories/bialgebras.py +++ b/src/sage/categories/bialgebras.py @@ -20,7 +20,7 @@ class Bialgebras(Category_over_base_ring): """ - The category of bialgebras + The category of bialgebras. EXAMPLES:: diff --git a/src/sage/categories/bialgebras_with_basis.py b/src/sage/categories/bialgebras_with_basis.py index 8b392b05984..10e829fd7fb 100644 --- a/src/sage/categories/bialgebras_with_basis.py +++ b/src/sage/categories/bialgebras_with_basis.py @@ -156,11 +156,9 @@ def convolution_power_of_id(self, n): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - the image of ``self`` under the convolution power `\mathrm{Id}^{*n}` + OUTPUT: the image of ``self`` under the convolution power `\mathrm{Id}^{*n}` .. NOTE:: @@ -249,9 +247,7 @@ def convolution_product(self, *maps): \ldots, f_n` on ``self.parent()``; or a single ``list`` or ``tuple`` of such maps - OUTPUT: - - - the convolution product of ``maps`` applied to ``self`` + OUTPUT: the convolution product of ``maps`` applied to ``self`` AUTHORS: diff --git a/src/sage/categories/bimodules.py b/src/sage/categories/bimodules.py index 52f83bfefd4..5658cd5e514 100644 --- a/src/sage/categories/bimodules.py +++ b/src/sage/categories/bimodules.py @@ -24,7 +24,7 @@ class Bimodules(CategoryWithParameters): """ - The category of `(R,S)`-bimodules + The category of `(R,S)`-bimodules. For `R` and `S` rings, a `(R,S)`-bimodule `X` is a left `R`-module and right `S`-module such that the left and right actions commute: @@ -102,7 +102,7 @@ def _make_named_class_key(self, name): sage: Bimodules(Fields(), Rings())._make_named_class_key('element_class') (Category of fields, Category of rings) """ - return (self._left_base_ring if isinstance(self._left_base_ring, Category) else self._left_base_ring.category(), + return (self._left_base_ring if isinstance(self._left_base_ring, Category) else self._left_base_ring.category(), self._right_base_ring if isinstance(self._right_base_ring, Category) else self._right_base_ring.category()) @classmethod diff --git a/src/sage/categories/cartesian_product.py b/src/sage/categories/cartesian_product.py index 9e83183a287..2da692abc3c 100644 --- a/src/sage/categories/cartesian_product.py +++ b/src/sage/categories/cartesian_product.py @@ -105,7 +105,6 @@ class CartesianProductFunctor(CovariantFunctorialConstruction, MultivariateConst ` of ``Monoids(QQ)``. This nested class is itself a subclass of :class:`CartesianProductsCategory`. - """ _functor_name = "cartesian_product" _functor_category = "CartesianProducts" @@ -242,7 +241,6 @@ def _repr_object_names(self): sage: ModulesWithBasis(QQ).CartesianProducts() # indirect doctest Category of Cartesian products of vector spaces with basis over Rational Field - """ # This method is only required for the capital `C` return "Cartesian products of %s" % (self.base_category()._repr_object_names()) diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index 7ed37217378..b534f7be794 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -71,7 +71,7 @@ A parent ``P`` is in a category ``C`` if ``P.category()`` is a subcategory of ``C``. -.. note:: +.. NOTE:: Any object of a category should be an instance of :class:`~sage.structure.category_object.CategoryObject`. @@ -127,9 +127,9 @@ class Category(UniqueRepresentation, SageObject): r""" The base class for modeling mathematical categories, like for example: - - ``Groups()``: the category of groups - - ``EuclideanDomains()``: the category of euclidean rings - - ``VectorSpaces(QQ)``: the category of vector spaces over the field of + - ``Groups()`` -- the category of groups + - ``EuclideanDomains()`` -- the category of euclidean rings + - ``VectorSpaces(QQ)`` -- the category of vector spaces over the field of rationals See :mod:`sage.categories.primer` for an introduction to @@ -200,10 +200,10 @@ class inheritance from ``C.parent_class``. We define a hierarchy of four categories ``As()``, ``Bs()``, ``Cs()``, ``Ds()`` with a diamond inheritance. Think for example: - - ``As()``: the category of sets - - ``Bs()``: the category of additive groups - - ``Cs()``: the category of multiplicative monoids - - ``Ds()``: the category of rings + - ``As()`` -- the category of sets + - ``Bs()`` -- the category of additive groups + - ``Cs()`` -- the category of multiplicative monoids + - ``Ds()`` -- the category of rings :: @@ -491,7 +491,6 @@ def _label(self): sage: Rings()._label 'Rings' - """ t = str(self.__class__.__base__) t = t[t.rfind('.') + 1:] @@ -566,7 +565,7 @@ def an_instance(cls): def __call__(self, x, *args, **opts): """ Construct an object in this category from the data in ``x``, - or throw :class:`TypeError` or :class:`NotImplementedError`. + or throw :exc:`TypeError` or :exc:`NotImplementedError`. If ``x`` is readily in ``self`` it is returned unchanged. Categories wishing to extend this minimal behavior should @@ -584,7 +583,7 @@ def __call__(self, x, *args, **opts): def _call_(self, x): """ Construct an object in this category from the data in ``x``, - or throw :class:`NotImplementedError`. + or throw :exc:`NotImplementedError`. EXAMPLES:: @@ -608,7 +607,7 @@ def _repr_(self): def _latex_(self): r""" - Returns the latex representation of this category. + Return the latex representation of this category. EXAMPLES:: @@ -682,7 +681,7 @@ def _subcategory_hook_(self, category): def __contains__(self, x): """ - Membership testing + Membership testing. Returns whether ``x`` is an object in this category, that is if the category of ``x`` is a subcategory of ``self``. @@ -701,7 +700,7 @@ def __contains__(self, x): @staticmethod def __classcontains__(cls, x): """ - Membership testing, without arguments + Membership testing, without arguments. INPUT: @@ -785,7 +784,7 @@ def is_abelian(self): def category_graph(self): r""" - Returns the graph of all super categories of this category + Return the graph of all super categories of this category. EXAMPLES:: @@ -807,9 +806,7 @@ def super_categories(self): """ Return the *immediate* super categories of ``self``. - OUTPUT: - - - a duplicate-free list of categories. + OUTPUT: a duplicate-free list of categories Every category should implement this method. @@ -843,9 +840,9 @@ def _all_super_categories(self): .. SEEALSO:: :meth:`all_super_categories` - .. note:: this attribute is likely to eventually become a tuple. + .. NOTE:: this attribute is likely to eventually become a tuple. - .. note:: this sets :meth:`_super_categories_for_classes` as a side effect + .. NOTE:: this sets :meth:`_super_categories_for_classes` as a side effect EXAMPLES:: @@ -878,7 +875,7 @@ def _all_super_categories_proper(self): .. SEEALSO:: :meth:`all_super_categories` - .. note:: this attribute is likely to eventually become a tuple. + .. NOTE:: this attribute is likely to eventually become a tuple. EXAMPLES:: @@ -898,7 +895,7 @@ def _set_of_super_categories(self): """ The frozen set of all proper super categories of this category. - .. note:: this is used for speeding up category containment tests. + .. NOTE:: this is used for speeding up category containment tests. .. SEEALSO:: :meth:`all_super_categories` @@ -928,16 +925,16 @@ def _set_of_super_categories(self): def all_super_categories(self, proper=False): """ - Returns the list of all super categories of this category. + Return the list of all super categories of this category. INPUT: - - ``proper`` -- a boolean (default: ``False``); whether to exclude this category. + - ``proper`` -- boolean (default: ``False``); whether to exclude this category Since :issue:`11943`, the order of super categories is determined by Python's method resolution order C3 algorithm. - .. note:: + .. NOTE:: Whenever speed matters, the developers are advised to use instead the lazy attributes :meth:`_all_super_categories`, @@ -972,7 +969,6 @@ def all_super_categories(self, proper=False): True sage: Sets().all_super_categories(proper=True) is Sets()._all_super_categories_proper True - """ if proper: return self._all_super_categories_proper @@ -1374,9 +1370,9 @@ def full_super_categories(self): def _test_category_graph(self, **options): """ - Check that the category graph matches with Python's method resolution order + Check that the category graph matches with Python's method resolution order. - .. note:: + .. NOTE:: By :issue:`11943`, the list of categories returned by :meth:`all_super_categories` is supposed to match with the @@ -1393,7 +1389,6 @@ def _test_category_graph(self, **options): sage: C.element_class.mro() == [X.element_class for X in C._all_super_categories] + [object] True sage: TestSuite(C).run() # indirect doctest - """ tester = self._tester(**options) tester.assertEqual(self.parent_class.mro(), [C.parent_class for C in self._all_super_categories] + [object]) @@ -1401,7 +1396,7 @@ def _test_category_graph(self, **options): def _test_category(self, **options): r""" - Run generic tests on this category + Run generic tests on this category. .. SEEALSO:: :class:`TestSuite`. @@ -1470,15 +1465,15 @@ def _make_named_class(self, name, method_provider, cache=False, picklable=True): INPUT: - - ``name`` -- a string; the name of the class as an attribute of - ``self``. E.g. "parent_class" - - ``method_provider`` -- a string; the name of an attribute of + - ``name`` -- string; the name of the class as an attribute of + ``self`` (e.g. "parent_class") + - ``method_provider`` -- string; the name of an attribute of ``self`` that provides methods for the new class (in - addition to those coming from the super categories). - E.g. "ParentMethods" - - ``cache`` -- a boolean or ``ignore_reduction`` (default: ``False``) + addition to those coming from the super categories, + e.g. "ParentMethods") + - ``cache`` -- boolean or ``ignore_reduction`` (default: ``False``) (passed down to dynamic_class; for internal use only) - - ``picklable`` -- a boolean (default: ``True``) + - ``picklable`` -- boolean (default: ``True``) ASSUMPTION: @@ -1626,7 +1621,6 @@ def subcategory_class(self): sage: type(cls) - """ return self._make_named_class('subcategory_class', 'SubcategoryMethods', cache=False, picklable=False) @@ -1748,7 +1742,7 @@ def morphism_class(self): def required_methods(self): """ - Returns the methods that are required and optional for parents + Return the methods that are required and optional for parents in this category and their elements. EXAMPLES:: @@ -1763,7 +1757,7 @@ def required_methods(self): # Operations on the lattice of categories def is_subcategory(self, c): """ - Returns True if self is naturally embedded as a subcategory of c. + Return ``True`` if ``self`` is naturally embedded as a subcategory of `c`. EXAMPLES:: @@ -1818,11 +1812,9 @@ def or_subcategory(self, category=None, join=False): - ``category`` -- a sub category of ``self``, tuple/list thereof, or ``None`` - - ``join`` -- a boolean (default: ``False``) - - OUTPUT: + - ``join`` -- boolean (default: ``False``) - - a category + OUTPUT: a category EXAMPLES:: @@ -1884,7 +1876,7 @@ def _is_subclass(self, c): @cached_method def _meet_(self, other): """ - Returns the largest common subcategory of self and other: + Return the largest common subcategory of ``self`` and ``other``. EXAMPLES:: @@ -1917,7 +1909,7 @@ def _meet_(self, other): distributivity. For the meet computation, there may be several lowest common - sub categories of self and other, in which case, we need to + sub categories of ``self`` and ``other``, in which case, we need to take the join of them all. FIXME: @@ -1941,7 +1933,7 @@ def _meet_(self, other): @staticmethod def meet(categories): """ - Returns the meet of a list of categories + Return the meet of a list of categories. INPUT: @@ -1999,7 +1991,7 @@ def _with_axiom_as_tuple(self, axiom): INPUT: - - ``axiom`` -- a string, the name of an axiom + - ``axiom`` -- string, the name of an axiom This is a lazy version of :meth:`_with_axiom` which is used to avoid recursion loops during join calculations. @@ -2056,7 +2048,7 @@ def _with_axiom(self, axiom): INPUT: - - ``axiom`` -- a string, the name of an axiom + - ``axiom`` -- string, the name of an axiom EXAMPLES:: @@ -2087,7 +2079,7 @@ def _with_axioms(self, axioms): INPUT: - - ``axioms`` -- a list of strings, the names of the axioms + - ``axioms`` -- list of strings; the names of the axioms EXAMPLES:: @@ -2184,7 +2176,7 @@ def _without_axioms(self, named=False): INPUT: - - ``named`` -- a boolean (default: ``False``) + - ``named`` -- boolean (default: ``False``) .. TODO:: Improve this explanation. @@ -2217,11 +2209,9 @@ def _sort(categories): INPUT: - - ``categories`` -- a list (or iterable) of non-join categories + - ``categories`` -- list (or iterable) of non-join categories - OUTPUT: - - A sorted tuple of categories, possibly with repeats. + OUTPUT: a sorted tuple of categories, possibly with repeats .. NOTE:: @@ -2300,10 +2290,10 @@ def join(categories, as_list=False, ignore_axioms=(), axioms=()): INPUT: - - ``categories`` -- a list (or iterable) of categories - - ``as_list`` -- a boolean (default: ``False``); + - ``categories`` -- list (or iterable) of categories + - ``as_list`` -- boolean (default: ``False``); whether the result should be returned as a list - - ``axioms`` -- a tuple of strings; the names of some + - ``axioms`` -- tuple of strings; the names of some supplementary axioms .. SEEALSO:: :meth:`__and__` for a shortcut @@ -2510,7 +2500,7 @@ def category(self): def example(self, *args, **keywords): """ - Returns an object in this category. Most of the time, this is a parent. + Return an object in this category. Most of the time, this is a parent. This serves three purposes: @@ -2567,7 +2557,7 @@ def example(self, *args, **keywords): def is_Category(x): """ - Returns True if x is a category. + Return ``True`` if `x` is a category. EXAMPLES:: @@ -2628,7 +2618,7 @@ def category_graph(categories=None): INPUT: - - ``categories`` -- a list (or iterable) of categories + - ``categories`` -- list (or iterable) of categories If ``categories`` is specified, then the graph contains the mentioned categories together with all their super @@ -2716,13 +2706,13 @@ def _make_named_class(self, name, method_provider, cache=False, **options): INPUT: - - ``name`` -- a string; the name of the class as an attribute + - ``name`` -- string; the name of the class as an attribute of ``self`` - - ``method_provider`` -- a string; the name of an attribute of + - ``method_provider`` -- string; the name of an attribute of ``self`` that provides methods for the new class (in addition to what comes from the super categories) - ``**options`` -- other named options to pass down to - :meth:`Category._make_named_class`. + :meth:`Category._make_named_class` ASSUMPTION: @@ -2830,7 +2820,7 @@ def _make_named_class_key(self, name): INPUT: - - ``name`` -- a string; the name of the class as an attribute + - ``name`` -- string; the name of the class as an attribute of ``self`` .. SEEALSO:: @@ -2946,13 +2936,13 @@ class JoinCategory(CategoryWithParameters): def __init__(self, super_categories, **kwds): """ - Initializes this JoinCategory + Initialize this JoinCategory. INPUT: - - ``super_categories`` -- Categories to join. This category will + - ``super_categories`` -- categories to join; this category will consist of objects and morphisms that lie in all of these - categories. + categories - ``name`` -- ignored @@ -3006,7 +2996,7 @@ def _make_named_class_key(self, name): def super_categories(self): """ - Returns the immediate super categories, as per :meth:`Category.super_categories`. + Return the immediate super categories, as per :meth:`Category.super_categories`. EXAMPLES:: @@ -3032,13 +3022,13 @@ def additional_structure(self): def _subcategory_hook_(self, category): """ - Returns whether ``category`` is a subcategory of this join category + Return whether ``category`` is a subcategory of this join category. INPUT: - - ``category`` -- a category. + - ``category`` -- a category - .. note:: + .. NOTE:: ``category`` is a sub-category of this join category if and only if it is a sub-category of all super categories @@ -3143,7 +3133,7 @@ def _without_axioms(self, named=False): INPUT: - - ``named`` -- a boolean (default: ``False``) + - ``named`` -- boolean (default: ``False``) See :meth:`Category._without_axioms` for the description of the ``named`` parameter. @@ -3229,7 +3219,7 @@ def _repr_(self, as_join=False): INPUT: - - ``as_join`` -- a boolean (default: ``False``) + - ``as_join`` -- boolean (default: ``False``) EXAMPLES:: diff --git a/src/sage/categories/category_cy_helper.pyx b/src/sage/categories/category_cy_helper.pyx index 913a1c4d2b7..ca29f3f9042 100644 --- a/src/sage/categories/category_cy_helper.pyx +++ b/src/sage/categories/category_cy_helper.pyx @@ -8,15 +8,15 @@ AUTHOR: - Simon King (initial version) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2014 Simon King # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** ####################################### # Sorting @@ -47,7 +47,7 @@ cpdef tuple _sort_uniq(categories): INPUT: - - ``categories`` -- a list (or iterable) of categories + - ``categories`` -- list (or iterable) of categories OUTPUT: a sorted tuple of mutually incomparable categories @@ -79,9 +79,9 @@ cpdef tuple _flatten_categories(categories, ClasscallMetaclass JoinCategory): INPUT: - - ``categories`` -- a list (or iterable) of categories + - ``categories`` -- list (or iterable) of categories - - ``JoinCategory`` -- A type such that instances of that type will be + - ``JoinCategory`` -- a type such that instances of that type will be replaced by its super categories. Usually, this type is :class:`JoinCategory`. @@ -122,12 +122,12 @@ cpdef tuple join_as_tuple(tuple categories, tuple axioms, tuple ignore_axioms): INPUT: - - ``categories`` -- tuple of categories to be joined, + - ``categories`` -- tuple of categories to be joined - ``axioms`` -- tuple of strings; the names of some - supplementary axioms. + supplementary axioms - ``ignore_axioms`` -- tuple of pairs ``(cat, axiom)``, such that ``axiom`` will not be applied to ``cat``, should ``cat`` - occur in the algorithm. + occur in the algorithm EXAMPLES:: @@ -294,7 +294,7 @@ cpdef tuple canonicalize_axioms(AxiomContainer all_axioms, axioms): - ``all_axioms`` -- all available axioms - - ``axioms`` -- a set (or iterable) of axioms + - ``axioms`` -- set (or iterable) of axioms .. NOTE:: diff --git a/src/sage/categories/category_singleton.pyx b/src/sage/categories/category_singleton.pyx index d907eedb9e8..0423ab9d83a 100644 --- a/src/sage/categories/category_singleton.pyx +++ b/src/sage/categories/category_singleton.pyx @@ -16,6 +16,8 @@ from sage.categories.category import Category from sage.structure.category_object cimport CategoryObject from sage.structure.dynamic_class import DynamicMetaclass +# I have no idea why this is necessary, but otherwise the type import fails (maybe because its shadowed by sage's cpython module?) +from cpython.method cimport PyMethod_Check from cpython.type cimport PyType_IsSubtype # This helper class is used to implement Category_singleton.__contains__ @@ -24,7 +26,7 @@ from cpython.type cimport PyType_IsSubtype cdef class Category_contains_method_by_parent_class: """ - Returns whether ``x`` is an object in this category. + Return whether ``x`` is an object in this category. More specifically, returns ``True`` if and only if ``x`` has a category which is a subcategory of this one. @@ -62,11 +64,11 @@ cdef class Category_contains_method_by_parent_class: TESTS: - The following used to segfault in a preliminary version of the - code:: + The following used to segfault in a preliminary version of the + code:: - sage: None in Rings() - False + sage: None in Rings() + False """ if x is None: return False @@ -76,7 +78,7 @@ cdef class Category_contains_method_by_parent_class: return PyType_IsSubtype(((y._category or y.category()).parent_class), self._parent_class_of_category) except AttributeError: return False - except TypeError: # this is for objects that aren't CategoryObjects + except TypeError: # this is for objects that are not CategoryObjects try: return PyType_IsSubtype((x.category().parent_class), self._parent_class_of_category) except AttributeError: @@ -85,7 +87,7 @@ cdef class Category_contains_method_by_parent_class: class Category_singleton(Category): """ - A base class for implementing singleton category + A base class for implementing singleton category. A *singleton* category is a category whose class takes no parameters like ``Fields()`` or ``Rings()``. See also the @@ -218,9 +220,9 @@ class Category_singleton(Category): , , , + , , , - , , , , @@ -260,7 +262,6 @@ class Category_singleton(Category): False Oh well; it's not really relevant for those tests. - """ # That is just an optimized constant cached_method @@ -294,7 +295,8 @@ class Category_singleton(Category): sage: Category_singleton() Traceback (most recent call last): ... - AssertionError: is not a direct subclass of + AssertionError: is not a direct subclass of + Instantiating a subclass of a subclass of :class:`Category_singleton` also triggers an assertion error:: diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index ed4fdce2c62..de62a0109f0 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -62,7 +62,7 @@ def __init__(self, object): @classmethod def an_instance(cls): """ - Returns an instance of this class + Return an instance of this class. EXAMPLES:: @@ -147,7 +147,7 @@ def _latex_(self): ############################################################# class Category_over_base(CategoryWithParameters): r""" - A base class for categories over some base object + A base class for categories over some base object. INPUT: @@ -253,7 +253,7 @@ def _make_named_class_key(self, name): @classmethod def an_instance(cls): """ - Returns an instance of this class + Return an instance of this class. EXAMPLES:: @@ -386,7 +386,7 @@ def _subcategory_hook_(self, C): OUTPUT: A boolean if it is certain that ``C`` is (or is not) a - subcategory of self. :obj:`~sage.misc.unknown.Unknown` + subcategory of ``self``. :obj:`~sage.misc.unknown.Unknown` otherwise. EXAMPLES: @@ -514,7 +514,6 @@ def __contains__(self, x): sage: QQ['x'] in Algebras(Fields()) # todo: not implemented True - """ try: # The issubclass test handles extension types or when the @@ -616,8 +615,8 @@ def __contains__(self, x): """ if super().__contains__(x): return True - from sage.rings.ideal import is_Ideal - return is_Ideal(x) and x.ring() == self.ring() + from sage.rings.ideal import Ideal_generic + return isinstance(x, Ideal_generic) and x.ring() == self.ring() def __call__(self, v): """ diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 19e3b2a9e91..766ec9b64cb 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -1908,7 +1908,7 @@ def _base_category_class_and_axiom(cls): sage: CommutativeRings()._base_category_class_and_axiom (, 'Commutative') sage: CommutativeRings()._base_category_class_and_axiom_origin - 'deduced by base_category_class_and_axiom' + 'set by __classget__' ``Sets.Infinite`` is a nested class, so the attribute is set by :meth:`CategoryWithAxiom.__classget__` the first time @@ -2219,7 +2219,7 @@ def _repr_object_names_static(category, axioms): INPUT: - ``base_category`` -- a category - - ``axioms`` -- a list or iterable of strings + - ``axioms`` -- list or iterable of strings EXAMPLES:: diff --git a/src/sage/categories/chain_complexes.py b/src/sage/categories/chain_complexes.py index 6e6448f3d38..562d21d0c49 100644 --- a/src/sage/categories/chain_complexes.py +++ b/src/sage/categories/chain_complexes.py @@ -37,7 +37,6 @@ class ChainComplexes(Category_module): TESTS:: sage: TestSuite(ChainComplexes(RationalField())).run() - """ def super_categories(self): @@ -46,7 +45,6 @@ def super_categories(self): sage: ChainComplexes(Integers(9)).super_categories() [Category of modules over Ring of integers modulo 9] - """ from sage.categories.fields import Fields from sage.categories.modules import Modules @@ -93,7 +91,6 @@ def homology(self, n=None): Free module generated by {} over Rational Field sage: C.homology(4) Free module generated by {[x^2], [y^2]} over Rational Field - """ @abstract_method @@ -118,7 +115,6 @@ def differential(self, *args, **kwargs): Defn: x --> 0 y --> 0 z --> x*y - """ @abstract_method(optional=True) @@ -146,7 +142,6 @@ def reduce_to_homology(self, x, n=None): - ``n`` -- (default: ``None``) degree of the homology; if none is provided, the direct sum homology will be used - EXAMPLES:: sage: # needs sage.symbolic @@ -211,7 +206,6 @@ class HomologyFunctor(Functor): Generic morphism: From: Z To: Z - """ def __init__(self, domain, n=None): r""" @@ -222,7 +216,6 @@ def __init__(self, domain, n=None): sage: H = HomologyFunctor(ChainComplexes(QQ), 1); H Functor from Category of chain complexes over Rational Field to Category of commutative additive groups - """ if not isinstance(domain, ChainComplexes): raise TypeError(f'{domain} must be a category of chain complexes') @@ -240,7 +233,6 @@ def _apply_functor(self, x): sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) sage: H._apply_functor(C) # needs sage.modules Z x C3 - """ return x.homology(self._n) diff --git a/src/sage/categories/classical_crystals.py b/src/sage/categories/classical_crystals.py index 777eb16dddc..42dc02bdb2f 100644 --- a/src/sage/categories/classical_crystals.py +++ b/src/sage/categories/classical_crystals.py @@ -82,7 +82,7 @@ def super_categories(self): def example(self, n=3): """ - Returns an example of highest weight crystals, as per + Return an example of highest weight crystals, as per :meth:`Category.example`. EXAMPLES:: @@ -191,7 +191,7 @@ def demazure_character(self, w, f=None): def character(self, R=None): """ - Returns the character of this crystal. + Return the character of this crystal. INPUT: @@ -214,7 +214,7 @@ def character(self, R=None): One may specify an alternate :class:`WeylCharacterRing`:: - sage: R = WeylCharacterRing("A2", style="coroots") + sage: R = WeylCharacterRing("A2", style='coroots') sage: chiT = T.character(R); chiT A2(0,0) + 2*A2(1,1) + A2(0,3) + A2(3,0) + A2(2,2) sage: chiT in R @@ -223,12 +223,11 @@ def character(self, R=None): It should have the same Cartan type and use the same realization of the weight lattice as ``self``:: - sage: R = WeylCharacterRing("A3", style="coroots") + sage: R = WeylCharacterRing("A3", style='coroots') sage: T.character(R) Traceback (most recent call last): ... ValueError: Weyl character ring does not have the right Cartan type - """ from sage.combinat.root_system.weyl_characters import WeylCharacterRing if R is None: @@ -241,7 +240,7 @@ def character(self, R=None): def __iter__(self): r""" - Returns an iterator over the elements of this crystal. + Return an iterator over the elements of this crystal. This iterator uses little memory, storing only one element of the crystal at a time. For details on the complexity, see @@ -385,7 +384,7 @@ def __iter__(self): def _test_fast_iter(self, **options): r""" - Tests whether the elements returned by :meth:`.__iter__` + Test whether the elements returned by :meth:`.__iter__` and ``Crystal.list(self)`` are the same (the two algorithms are different). @@ -403,7 +402,7 @@ def _test_fast_iter(self, **options): def cardinality(self): r""" - Returns the number of elements of the crystal, using Weyl's + Return the number of elements of the crystal, using Weyl's dimension formula on each connected component. EXAMPLES:: diff --git a/src/sage/categories/coalgebras.py b/src/sage/categories/coalgebras.py index 7db6b72a6d4..f8dddc6e398 100644 --- a/src/sage/categories/coalgebras.py +++ b/src/sage/categories/coalgebras.py @@ -27,7 +27,7 @@ class Coalgebras(Category_over_base_ring): """ - The category of coalgebras + The category of coalgebras. EXAMPLES:: @@ -49,7 +49,7 @@ def super_categories(self): """ return [Modules(self.base_ring())] - WithBasis = LazyImport('sage.categories.coalgebras_with_basis', 'CoalgebrasWithBasis') + WithBasis = LazyImport('sage.categories.coalgebras_with_basis', 'CoalgebrasWithBasis') Graded = LazyImport('sage.categories.graded_coalgebras', 'GradedCoalgebras') class ParentMethods: diff --git a/src/sage/categories/coalgebras_with_basis.py b/src/sage/categories/coalgebras_with_basis.py index 7e111e727f6..33f532cfc95 100644 --- a/src/sage/categories/coalgebras_with_basis.py +++ b/src/sage/categories/coalgebras_with_basis.py @@ -92,7 +92,6 @@ def coproduct(self): (B[(1,2,3)], B[(1,2,3)] # B[(1,2,3)]) sage: b, A.coproduct(b) (B[(1,3)], B[(1,3)] # B[(1,3)]) - """ if self.coproduct_on_basis is not NotImplemented: # TODO: if self is a Hopf algebra, then one would want @@ -145,7 +144,6 @@ def counit(self): (B[(1,2,3)], 1) sage: b, A.counit(b) (B[(1,3)], 1) - """ if self.counit_on_basis is not NotImplemented: return self.module_morphism(self.counit_on_basis,codomain=self.base_ring()) diff --git a/src/sage/categories/coercion_methods.pyx b/src/sage/categories/coercion_methods.pyx index 0084b39d5eb..7640ea2aba5 100644 --- a/src/sage/categories/coercion_methods.pyx +++ b/src/sage/categories/coercion_methods.pyx @@ -24,9 +24,7 @@ def _mul_parent(self, other): - ``other`` -- an element of the parent of ``self`` - OUTPUT: - - - an element of the parent of ``self`` + OUTPUT: an element of the parent of ``self`` EXAMPLES:: diff --git a/src/sage/categories/commutative_rings.py b/src/sage/categories/commutative_rings.py index 0c00abea30d..6c47efacfe0 100644 --- a/src/sage/categories/commutative_rings.py +++ b/src/sage/categories/commutative_rings.py @@ -19,7 +19,7 @@ class CommutativeRings(CategoryWithAxiom): """ - The category of commutative rings + The category of commutative rings. commutative rings with unity, i.e. rings with commutative * and a multiplicative identity @@ -46,7 +46,6 @@ class CommutativeRings(CategoryWithAxiom): sage: GroupAlgebra(CyclicPermutationGroup(3), QQ) in CommutativeRings() # not implemented, needs sage.groups sage.modules True - """ class ParentMethods: def is_commutative(self) -> bool: @@ -149,14 +148,14 @@ def over(self, base=None, gen=None, gens=None, name=None, names=None): morphism - ``gen`` -- a generator of this extension (over its base) or ``None`` - (default: ``None``); + (default: ``None``) - - ``gens`` -- a list of generators of this extension (over its base) - or ``None`` (default: ``None``); + - ``gens`` -- list of generators of this extension (over its base) + or ``None`` (default: ``None``) - ``name`` -- a variable name or ``None`` (default: ``None``) - - ``names`` -- a list or a tuple of variable names or ``None`` + - ``names`` -- list or a tuple of variable names or ``None`` (default: ``None``) EXAMPLES: @@ -275,7 +274,7 @@ def frobenius_endomorphism(self, n=1): INPUT: - - ``n`` -- a nonnegative integer (default: 1) + - ``n`` -- nonnegative integer (default: 1) OUTPUT: @@ -391,7 +390,6 @@ def derivation_module(self, codomain=None, twist=None): .. SEEALSO:: :meth:`derivation` - """ from sage.rings.derivation import RingDerivationModule if codomain is None: @@ -461,7 +459,6 @@ def derivation(self, arg=None, twist=None): [x |--> x^2, y |--> y^2, z |--> z^2] - id sage: R.derivation(x, twist=theta) # needs sage.modules x*([x |--> x^2, y |--> y^2, z |--> z^2] - id) - """ if isinstance(arg, (list, tuple)): codomain = Sequence([self(0)] + list(arg)).universe() @@ -534,9 +531,7 @@ def cyclotomic_cosets(self, q, cosets=None): provided, the function only return the list of cosets that contain some element from ``cosets``. - OUTPUT: - - A list of lists. + OUTPUT: list of lists EXAMPLES:: diff --git a/src/sage/categories/complete_discrete_valuation.py b/src/sage/categories/complete_discrete_valuation.py index 7f291c43e37..40c1c51b77e 100644 --- a/src/sage/categories/complete_discrete_valuation.py +++ b/src/sage/categories/complete_discrete_valuation.py @@ -22,7 +22,7 @@ class CompleteDiscreteValuationRings(Category_singleton): """ - The category of complete discrete valuation rings + The category of complete discrete valuation rings. EXAMPLES:: @@ -138,7 +138,7 @@ def lift_to_precision(self, absprec=None): INPUT: - - ``absprec`` -- an integer or ``None`` (default: ``None``), the + - ``absprec`` -- integer or ``None`` (default: ``None``); the absolute precision of the result. If ``None``, lifts to the maximum precision allowed. @@ -168,13 +168,12 @@ def lift_to_precision(self, absprec=None): 2 + 3*5 + O(5^8) sage: c.lift_to_precision().precision_relative() == R.precision_cap() # needs sage.rings.padics True - """ class CompleteDiscreteValuationFields(Category_singleton): """ - The category of complete discrete valuation fields + The category of complete discrete valuation fields. EXAMPLES:: diff --git a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py index efa0ddbeccd..242a9144243 100644 --- a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py +++ b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py @@ -53,7 +53,7 @@ class ComplexReflectionOrGeneralizedCoxeterGroups(Category_singleton): - A collection of *reflections* which are the conjugates of all the non trivial powers of the simple reflections. - The usual notions of reduced words, length, irreducibility, etc + The usual notions of reduced words, length, irreducibility, etc., can be canonically defined from the above. The following methods must be implemented: @@ -560,7 +560,7 @@ def distinguished_reflection(self, i): INPUT: - - ``i`` -- an element of the index set of the distinguished reflections. + - ``i`` -- an element of the index set of the distinguished reflections .. SEEALSO:: @@ -650,7 +650,7 @@ def from_reduced_word(self, word, word_type='simple'): INPUT: - - ``word`` -- a list (or iterable) of elements of the + - ``word`` -- list (or iterable) of elements of the index set of ``self`` (resp. of the distinguished or of all reflections) - ``word_type`` -- (default: ``'simple'``): @@ -773,7 +773,7 @@ def irreducible_component_index_sets(self): [[i,j] for i,j in itertools.combinations(I,2) if s[i]*s[j] != s[j]*s[i] ]], - format="vertices_and_edges") + format='vertices_and_edges') return G.connected_components(sort=False) @abstract_method(optional=True) @@ -942,7 +942,7 @@ def apply_simple_reflection(self, i, side='right'): INPUT: - ``i`` -- an element of the index set - - ``side`` -- (default: ``"right"``) ``"left"`` or ``"right"`` + - ``side`` -- (default: ``'right'``) ``'left'`` or ``'right'`` This default implementation simply calls :meth:`apply_simple_reflection_left` or @@ -953,20 +953,20 @@ def apply_simple_reflection(self, i, side='right'): sage: W = CoxeterGroups().example() sage: w = W.an_element(); w (1, 2, 3, 0) - sage: w.apply_simple_reflection(0, side="left") + sage: w.apply_simple_reflection(0, side='left') (0, 2, 3, 1) - sage: w.apply_simple_reflection(1, side="left") + sage: w.apply_simple_reflection(1, side='left') (2, 1, 3, 0) - sage: w.apply_simple_reflection(2, side="left") + sage: w.apply_simple_reflection(2, side='left') (1, 3, 2, 0) - sage: w.apply_simple_reflection(0, side="right") + sage: w.apply_simple_reflection(0, side='right') (2, 1, 3, 0) - sage: w.apply_simple_reflection(1, side="right") + sage: w.apply_simple_reflection(1, side='right') (1, 3, 2, 0) - sage: w.apply_simple_reflection(2, side="right") + sage: w.apply_simple_reflection(2, side='right') (1, 2, 0, 3) - By default, ``side`` is ``"right"``:: + By default, ``side`` is ``'right'``:: sage: w.apply_simple_reflection(0) (2, 1, 3, 0) @@ -979,17 +979,17 @@ def apply_simple_reflection(self, i, side='right'): 5-colored permutations of size 3 sage: w = W.an_element(); w [[1, 0, 0], [3, 1, 2]] - sage: w.apply_simple_reflection(1, side="left") + sage: w.apply_simple_reflection(1, side='left') [[0, 1, 0], [1, 3, 2]] - sage: w.apply_simple_reflection(2, side="left") + sage: w.apply_simple_reflection(2, side='left') [[1, 0, 0], [3, 2, 1]] - sage: w.apply_simple_reflection(3, side="left") + sage: w.apply_simple_reflection(3, side='left') [[1, 0, 1], [3, 1, 2]] - sage: w.apply_simple_reflection(1, side="right") + sage: w.apply_simple_reflection(1, side='right') [[1, 0, 0], [3, 2, 1]] - sage: w.apply_simple_reflection(2, side="right") + sage: w.apply_simple_reflection(2, side='right') [[1, 0, 0], [2, 1, 3]] - sage: w.apply_simple_reflection(3, side="right") + sage: w.apply_simple_reflection(3, side='right') [[2, 0, 0], [3, 1, 2]] TESTS:: @@ -1119,7 +1119,7 @@ def apply_reflections(self, word, side='right', word_type='all'): def _mul_(self, other): r""" - Return the product of ``self`` and ``other`` + Return the product of ``self`` and ``other``. This default implementation computes a reduced word of ``other`` using :meth:`reduced_word`, and applies the diff --git a/src/sage/categories/covariant_functorial_construction.py b/src/sage/categories/covariant_functorial_construction.py index 9cfbf82ae76..aee0d22a6af 100644 --- a/src/sage/categories/covariant_functorial_construction.py +++ b/src/sage/categories/covariant_functorial_construction.py @@ -93,14 +93,14 @@ class CovariantFunctorialConstruction(UniqueRepresentation, SageObject): In practice, each subclass of this class should provide the following attributes: - - ``_functor_category`` -- a string which should match the name of - the nested category class to be used in each category to - specify information and generic operations for elements of this - category. + - ``_functor_category`` -- string which should match the name of + the nested category class to be used in each category to + specify information and generic operations for elements of this + category - - ``_functor_name`` -- a string which specifies the name of the - functor, and also (when relevant) of the method on parents and - elements used for calling the construction. + - ``_functor_name`` -- string which specifies the name of the + functor, and also (when relevant) of the method on parents and + elements used for calling the construction TODO: What syntax do we want for `F_{Cat}`? For example, for the tensor product construction, which one do we want among (see @@ -131,8 +131,8 @@ def category_from_parents(self, parents): INPUT: - - self: a functor F - - parents: a list (or iterable) of parents. + - ``self`` -- a functor `F` + - ``parents`` -- a list (or iterable) of parents EXAMPLES:: @@ -157,8 +157,8 @@ def category_from_categories(self, categories): INPUT: - - ``self``: a functor `F` - - ``categories``: a non empty tuple of categories + - ``self`` -- a functor `F` + - ``categories`` -- a non empty tuple of categories EXAMPLES:: @@ -182,8 +182,8 @@ def category_from_category(self, category): INPUT: - - ``self``: a functor `F` - - ``category``: a category + - ``self`` -- a functor `F` + - ``category`` -- a category EXAMPLES:: @@ -205,18 +205,18 @@ def _repr_(self): def __call__(self, args, **kwargs): """ - Functorial construction application + Functorial construction application. INPUT: - - ``self``: a covariant functorial construction `F` - - ``args``: a tuple (or iterable) of parents or elements + - ``self`` -- a covariant functorial construction `F` + - ``args`` -- a tuple (or iterable) of parents or elements Returns `F(args)` EXAMPLES:: - sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]); E.rename("E") # needs sage.modules + sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]); E.rename('E') # needs sage.modules sage: tensor((E, E, E)) # needs sage.modules E # E # E """ @@ -237,9 +237,7 @@ def _base_category_class(cls): """ Recover the class of the base category. - OUTPUT: - - A *tuple* whose single entry is the base category class. + OUTPUT: a *tuple* whose single entry is the base category class .. WARNING:: @@ -396,9 +394,9 @@ def category_of(cls, category, *args): INPUT: - - ``cls`` -- the category class for the functorial construction `F` - - ``category`` -- a category `Cat` - - ``*args`` -- further arguments for the functor + - ``cls`` -- the category class for the functorial construction `F` + - ``category`` -- a category `Cat` + - ``*args`` -- further arguments for the functor EXAMPLES:: @@ -527,9 +525,9 @@ def default_super_categories(cls, category, *args): INPUT: - - ``cls`` -- the category class for the functor `F` - - ``category`` -- a category `Cat` - - ``*args`` -- further arguments for the functor + - ``cls`` -- the category class for the functor `F` + - ``category`` -- a category `Cat` + - ``*args`` -- further arguments for the functor OUTPUT: a (join) category @@ -677,9 +675,7 @@ def default_super_categories(cls, category, *args): - ``category`` -- a category `Cat` - ``*args`` -- further arguments for the functor - OUTPUT: - - A join category. + OUTPUT: a join category This implements the property that an induced subcategory is a subcategory. diff --git a/src/sage/categories/coxeter_group_algebras.py b/src/sage/categories/coxeter_group_algebras.py index 03b6b39d71e..32fe0292bb5 100644 --- a/src/sage/categories/coxeter_group_algebras.py +++ b/src/sage/categories/coxeter_group_algebras.py @@ -13,7 +13,7 @@ class CoxeterGroupAlgebras(AlgebrasCategory): class ParentMethods: def demazure_lusztig_operator_on_basis(self, w, i, q1, q2, - side="right"): + side='right'): r""" Return the result of applying the `i`-th Demazure Lusztig operator on ``w``. @@ -23,7 +23,7 @@ def demazure_lusztig_operator_on_basis(self, w, i, q1, q2, - ``w`` -- an element of the Coxeter group - ``i`` -- an element of the index set - ``q1``, ``q2`` -- two elements of the ground ring - - ``bar`` -- a boolean (default ``False``) + - ``bar`` -- boolean (default: ``False``) See :meth:`demazure_lusztig_operators` for details. @@ -70,16 +70,16 @@ def demazure_lusztig_operator_on_basis(self, w, i, q1, q2, """ return (q1+q2) * self.monomial(w.apply_simple_projection(i,side=side)) - self.term(w.apply_simple_reflection(i, side=side), q2) - def demazure_lusztig_operators(self, q1, q2, side="right", affine=True): + def demazure_lusztig_operators(self, q1, q2, side='right', affine=True): r""" Return the Demazure Lusztig operators acting on ``self``. INPUT: - ``q1``, ``q2`` -- two elements of the ground ring `K` - - ``side`` -- ``"left"`` or ``"right"`` (default: ``"right"``); + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``); which side to act upon - - ``affine`` -- a boolean (default: ``True``) + - ``affine`` -- boolean (default: ``True``) The Demazure-Lusztig operator `T_i` is the linear map `R \to R` obtained by interpolating between the diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 25261db6645..fe663d6eb97 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -170,7 +170,7 @@ def coxeter_diagram(self): EXAMPLES:: sage: # needs sage.combinat sage.graphs sage.groups - sage: W = CoxeterGroup(['H', 3], implementation="reflection") + sage: W = CoxeterGroup(['H', 3], implementation='reflection') sage: G = W.coxeter_diagram(); G Graph on 3 vertices sage: G.edges(sort=True) @@ -262,7 +262,7 @@ def braid_orbit_iter(self, word): INPUT: - - ``word`` -- a list (or iterable) of indices in + - ``word`` -- list (or iterable) of indices in ``self.index_set()`` OUTPUT: @@ -309,7 +309,7 @@ def braid_orbit(self, word): INPUT: - - ``word``: a list (or iterable) of indices in + - ``word`` -- a list (or iterable) of indices in ``self.index_set()`` OUTPUT: @@ -410,9 +410,9 @@ def _element_constructor_(self, x, **args): EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W1 = WeylGroup("G2", prefix="s") + sage: W1 = WeylGroup("G2", prefix='s') sage: W2 = CoxeterGroup("G2") - sage: W3 = CoxeterGroup("G2", implementation="permutation") + sage: W3 = CoxeterGroup("G2", implementation='permutation') sage: W1(W2.an_element()) s1*s2 sage: W2(W1.an_element()) @@ -437,15 +437,15 @@ def _element_constructor_(self, x, **args): pass return self.element_class(self, x, **args) - def weak_order_ideal(self, predicate, side="right", category=None): + def weak_order_ideal(self, predicate, side='right', category=None): """ - Return a weak order ideal defined by a predicate + Return a weak order ideal defined by a predicate. INPUT: - - ``predicate``: a predicate on the elements of ``self`` defining an + - ``predicate`` -- a predicate on the elements of ``self`` defining an weak order ideal in ``self`` - - ``side``: "left" or "right" (default: "right") + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) OUTPUT: an enumerated set @@ -592,7 +592,7 @@ def standard_coxeter_elements(self): r""" Return all standard Coxeter elements in ``self``. - This is the set of all elements in self obtained from any + This is the set of all elements in ``self`` obtained from any product of the simple reflections in ``self``. .. NOTE:: @@ -636,14 +636,14 @@ class is not unique and we only obtain one such class. return {self.from_reduced_word(w) for w in Permutations(self.index_set())} - def grassmannian_elements(self, side="right"): + def grassmannian_elements(self, side='right'): """ Return the left or right Grassmannian elements of ``self`` as an enumerated set. INPUT: - - ``side`` -- (default: ``"right"``) ``"left"`` or ``"right"`` + - ``side`` -- (default: ``'right'``) ``'left'`` or ``'right'`` EXAMPLES:: @@ -741,7 +741,6 @@ def simple_projection(self, i, side='right', length_increasing=True): (1, 2, 3, 0) sage: d0(pi) (1, 2, 3, 0) - """ if not (i in self.index_set() or i == 0): raise ValueError("%s is not 0 and not in the Dynkin node set %s" % (i, self.index_set())) @@ -827,7 +826,7 @@ def kazhdan_lusztig_cells(self, side='left'): sage: len(W.kazhdan_lusztig_cells()) 10 - Computing the two sided cells in `B_3`:: + Computing the two-sided cells in `B_3`:: sage: # optional - coxeter3, needs sage.combinat sage.groups sage.libs.gap sage.modules sage.rings.number_field sage: W = CoxeterGroup('B3', implementation='coxeter3') @@ -892,9 +891,9 @@ def simple_projections(self, side='right', length_increasing=True): INPUT: - ``self`` -- a Coxeter group `W` - - ``side`` -- 'left' or 'right' (default: 'right') - - ``length_increasing`` -- a boolean (default: ``True``) specifying - whether the operator increases or decreases length + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``length_increasing`` -- boolean (default: ``True``); whether + the operator increases or decreases length This returns the simple projections of `W`, as a family. @@ -965,7 +964,7 @@ def sign_representation(self, base_ring=None): from sage.modules.with_basis.representation import SignRepresentationCoxeterGroup return SignRepresentationCoxeterGroup(self, base_ring) - def reflection_representation(self, base_ring=None, side="left"): + def reflection_representation(self, base_ring=None, side='left'): r""" Return the reflection representation of ``self``. @@ -1010,7 +1009,7 @@ def demazure_product(self, Q): INPUT: - - ``Q`` is a list of elements from the index set of ``self``. + - ``Q`` -- list of elements from the index set of ``self`` This returns the Coxeter group element that represents the composition of 0-Hecke or Demazure operators. @@ -1041,14 +1040,14 @@ def bruhat_interval(self, x, y): EXAMPLES:: - sage: W = WeylGroup("A3", prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup("A3", prefix='s') # needs sage.combinat sage.groups sage: s1, s2, s3 = W.simple_reflections() # needs sage.combinat sage.groups sage: W.bruhat_interval(s2, s1*s3*s2*s1*s3) # needs sage.combinat sage.groups [s1*s2*s3*s2*s1, s2*s3*s2*s1, s3*s1*s2*s1, s1*s2*s3*s1, s1*s2*s3*s2, s3*s2*s1, s2*s3*s1, s2*s3*s2, s1*s2*s1, s3*s1*s2, s1*s2*s3, s2*s1, s3*s2, s2*s3, s1*s2, s2] - sage: W = WeylGroup(['A', 2, 1], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 2, 1], prefix='s') # needs sage.combinat sage.groups sage: s0, s1, s2 = W.simple_reflections() # needs sage.combinat sage.groups sage: W.bruhat_interval(1, s0*s1*s2) # needs sage.combinat sage.groups [s0*s1*s2, s1*s2, s0*s2, s0*s1, s2, s1, s0, 1] @@ -1080,12 +1079,12 @@ def bruhat_interval_poset(self, x, y, facade=False): EXAMPLES:: - sage: W = WeylGroup("A3", prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup("A3", prefix='s') # needs sage.combinat sage.groups sage: s1, s2, s3 = W.simple_reflections() # needs sage.combinat sage.groups sage: W.bruhat_interval_poset(s2, s1*s3*s2*s1*s3) # needs sage.combinat sage.groups Finite poset containing 16 elements - sage: W = WeylGroup(['A', 2, 1], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 2, 1], prefix='s') # needs sage.combinat sage.groups sage: s0, s1, s2 = W.simple_reflections() # needs sage.combinat sage.groups sage: W.bruhat_interval_poset(1, s0*s1*s2) # needs sage.combinat sage.groups Finite poset containing 8 elements @@ -1159,7 +1158,7 @@ def bruhat_graph(self, x=None, y=None, edge_labels=False): sage: W.bruhat_graph(s1, s3*s2*s3) Digraph on 0 vertices - sage: W = WeylGroup("A3", prefix="s") # needs sage.combinat sage.graphs sage.groups + sage: W = WeylGroup("A3", prefix='s') # needs sage.combinat sage.graphs sage.groups sage: s1, s2, s3 = W.simple_reflections() # needs sage.combinat sage.graphs sage.groups sage: G = W.bruhat_graph(s1*s3, s1*s2*s3*s2*s1); G # needs sage.combinat sage.graphs sage.groups Digraph on 10 vertices @@ -1292,7 +1291,7 @@ def random_element_of_length(self, n): def _test_simple_projections(self, **options): """ - Runs sanity checks on :meth:`.simple_projections` + Run sanity checks on :meth:`.simple_projections` and :meth:`CoxeterGroups.ElementMethods.apply_simple_projection` EXAMPLES:: @@ -1318,7 +1317,7 @@ def _test_has_descent(self, **options): """ Run sanity checks on the method :meth:`CoxeterGroups.ElementMethods.has_descent` of the - elements of self. + elements of ``self``. EXAMPLES:: @@ -1430,7 +1429,7 @@ def _test_coxeter_relations(self, **options): class ElementMethods: def has_descent(self, i, side='right', positive=False): """ - Return whether i is a (left/right) descent of self. + Return whether `i` is a (left/right) descent of ``self``. See :meth:`.descents` for a description of the options. @@ -1462,7 +1461,7 @@ def has_descent(self, i, side='right', positive=False): # @abstract_method(optional = True) def has_right_descent(self, i): """ - Return whether ``i`` is a right descent of self. + Return whether `i` is a right descent of ``self``. EXAMPLES:: @@ -1481,7 +1480,7 @@ def has_right_descent(self, i): def has_left_descent(self, i): """ - Return whether `i` is a left descent of self. + Return whether `i` is a left descent of ``self``. This default implementation uses that a left descent of `w` is a right descent of `w^{-1}`. @@ -1543,8 +1542,8 @@ def descents(self, side='right', index_set=None, positive=False): - ``index_set`` -- a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: all of them) - - ``side`` -- 'left' or 'right' (default: 'right') - - ``positive`` -- a boolean (default: ``False``) + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``positive`` -- boolean (default: ``False``) The ``index_set`` option can be used to restrict to the parabolic subgroup indexed by ``index_set``. @@ -1578,13 +1577,13 @@ def descents(self, side='right', index_set=None, positive=False): return [i for i in index_set if self.has_descent(i, side=side, positive=positive)] - def is_grassmannian(self, side="right") -> bool: + def is_grassmannian(self, side='right') -> bool: """ Return whether ``self`` is Grassmannian. INPUT: - - ``side`` -- "left" or "right" (default: "right") + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) An element is Grassmannian if it has at most one descent on the right (resp. on the left). @@ -1605,9 +1604,9 @@ def is_grassmannian(self, side="right") -> bool: sage: (s[1]*s[2]*s[1]).is_grassmannian() False - sage: (s[0]*s[2]*s[1]).is_grassmannian(side="left") + sage: (s[0]*s[2]*s[1]).is_grassmannian(side='left') False - sage: (s[0]*s[2]*s[1]).is_grassmannian(side="right") + sage: (s[0]*s[2]*s[1]).is_grassmannian(side='right') True sage: (s[0]*s[2]*s[1]).is_grassmannian() True @@ -1810,9 +1809,7 @@ def support(self): Return the support of ``self``, that is the simple reflections that appear in the reduced expressions of ``self``. - OUTPUT: - - The support of ``self`` as a set of integers + OUTPUT: the support of ``self`` as a set of integers EXAMPLES:: @@ -1924,7 +1921,7 @@ def reduced_word_graph(self): or x[j + m:] != y[j + m:]): continue edges.append([x, y, m]) - G = Graph(edges, immutable=True, format="list_of_edges") + G = Graph(edges, immutable=True, format='list_of_edges') colors = {2: 'blue', 3: 'red', 4: 'green'} G.set_latex_options(edge_labels=True, color_by_label=lambda x: colors[x]) @@ -1990,7 +1987,6 @@ def reflection_length(self): sage: s = W.simple_reflections() # needs sage.groups sage: (s[3]*s[2]*s[3]).reflection_length() # needs sage.combinat sage.groups 1 - """ return self.absolute_length() @@ -2064,9 +2060,8 @@ def absolute_chain(self): """ reflections = self.absolute_chain_reflections() P = self.parent() - chain = [P.prod(reversed(reflections[:i])) - for i in range(len(reflections)+1)] - return chain + return [P.prod(reversed(reflections[:i])) + for i in range(len(reflections) + 1)] def absolute_chain_reflections(self): r""" @@ -2282,7 +2277,7 @@ def coset_representative(self, index_set, side='right'): INPUT: - ``index_set`` -- a subset (or iterable) of the nodes of the Dynkin diagram - - ``side`` -- 'left' or 'right' + - ``side`` -- ``'left'`` or ``'right'`` EXAMPLES:: @@ -2313,7 +2308,6 @@ def coset_representative(self, index_set, side='right'): [1] sage: w.coset_representative([1,2,3], side='left').reduced_word() [] - """ while True: i = self.first_descent(side=side, index_set=index_set) @@ -2329,9 +2323,9 @@ def apply_simple_projection(self, i, side='right', length_increasing=True): INPUT: - ``i`` -- an element of the index set of the Coxeter group - - ``side`` -- 'left' or 'right' (default: 'right') - - ``length_increasing`` -- a boolean (default: ``True``) specifying - the direction of the projection + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``length_increasing`` -- boolean (default: ``True``); + specifying the direction of the projection See :meth:`CoxeterGroups.ParentMethods.simple_projections` for the definition of the simple projections. @@ -2348,7 +2342,7 @@ def apply_simple_projection(self, i, side='right', length_increasing=True): (1, 2, 0, 3) sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['C', 4], prefix="s") + sage: W = WeylGroup(['C', 4], prefix='s') sage: v = W.from_reduced_word([1,2,3,4,3,1]) sage: v s1*s2*s3*s4*s3*s1 @@ -2358,7 +2352,6 @@ def apply_simple_projection(self, i, side='right', length_increasing=True): s1*s2*s3*s4*s3*s1 sage: v.apply_simple_projection(1, length_increasing=False) s1*s2*s3*s4*s3 - """ if self.has_descent(i, side=side, positive=length_increasing): return self.apply_simple_reflection(i, side=side) @@ -2372,10 +2365,10 @@ def binary_factorizations(self, predicate=ConstantFunction(True)): Iterating through this set is Constant Amortized Time (counting arithmetic operations in the Coxeter group as constant time) complexity, and memory linear in the length - of `self`. + of ``self``. One can pass as optional argument a predicate p such that - `p(u)` implies `p(u')` for any `u` left factor of `self` + `p(u)` implies `p(u')` for any `u` left factor of ``self`` and `u'` left factor of `u`. Then this returns only the factorizations `self = uv` such `p(u)` holds. @@ -2475,7 +2468,7 @@ def bruhat_lower_covers(self): sage: w = W.from_reduced_word([0,2]) sage: print([v.reduced_word() for v in w.bruhat_lower_covers()]) [[2], [0]] - sage: W = WeylGroup("A3", prefix="s", implementation="permutation") + sage: W = WeylGroup("A3", prefix='s', implementation='permutation') sage: s1, s2, s3 = W.simple_reflections() sage: (s1*s2*s3*s1).bruhat_lower_covers() [s2*s1*s3, s1*s2*s1, s1*s2*s3] @@ -2514,7 +2507,7 @@ def bruhat_upper_covers(self): EXAMPLES:: - sage: W = WeylGroup(['A', 3, 1], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 3, 1], prefix='s') # needs sage.combinat sage.groups sage: w = W.from_reduced_word([1,2,1]) # needs sage.combinat sage.groups sage: w.bruhat_upper_covers() # needs sage.combinat sage.groups [s1*s2*s1*s0, s1*s2*s0*s1, s0*s1*s2*s1, s3*s1*s2*s1, s2*s3*s1*s2, s1*s2*s3*s1] @@ -2553,7 +2546,7 @@ def bruhat_lower_covers_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A', 3], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 3], prefix='s') # needs sage.combinat sage.groups sage: w = W.from_reduced_word([3,1,2,1]) # needs sage.combinat sage.groups sage: w.bruhat_lower_covers_reflections() # needs sage.combinat sage.groups [(s1*s2*s1, s1*s2*s3*s2*s1), (s3*s2*s1, s2), (s3*s1*s2, s1)] @@ -2587,13 +2580,12 @@ def lower_cover_reflections(self, side='right'): EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['A', 3],prefix="s") + sage: W = WeylGroup(['A', 3],prefix='s') sage: w = W.from_reduced_word([3,1,2,1]) sage: w.lower_cover_reflections() [s1*s2*s3*s2*s1, s2, s1] sage: w.lower_cover_reflections(side='left') [s2*s3*s2, s3, s1] - """ if side == 'left': self = self.inverse() @@ -2610,7 +2602,7 @@ def bruhat_upper_covers_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A', 4], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 4], prefix='s') # needs sage.combinat sage.groups sage: w = W.from_reduced_word([3,1,2,1]) # needs sage.combinat sage.groups sage: w.bruhat_upper_covers_reflections() # needs sage.combinat sage.groups [(s1*s2*s3*s2*s1, s3), (s2*s3*s1*s2*s1, s2*s3*s2), @@ -2635,13 +2627,12 @@ def cover_reflections(self, side='right'): EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['A', 4], prefix="s") + sage: W = WeylGroup(['A', 4], prefix='s') sage: w = W.from_reduced_word([3,1,2,1]) sage: w.cover_reflections() [s3, s2*s3*s2, s4, s1*s2*s3*s4*s3*s2*s1] sage: w.cover_reflections(side='left') [s4, s2, s1*s2*s1, s3*s4*s3] - """ if side == 'left': self = self.inverse() @@ -2654,9 +2645,9 @@ def bruhat_le(self, other): INPUT: - - other -- an element of the same Coxeter group + - ``other`` -- an element of the same Coxeter group - OUTPUT: a boolean + OUTPUT: boolean EXAMPLES:: @@ -2680,7 +2671,7 @@ def bruhat_le(self, other): reduced word for ``other`` contains a reduced word for ``self`` as subword. See Stembridge, A short derivation of the Möbius function for the Bruhat order. J. Algebraic - Combin. 25 (2007), no. 2, 141--148, Proposition 1.1. + Combinatoric 25 (2007), no. 2, 141--148, Proposition 1.1. Complexity: `O(l * c)`, where `l` is the minimum of the lengths of `u` and of `v`, and `c` is the cost of the low @@ -2720,21 +2711,23 @@ def bruhat_le(self, other): return self.apply_simple_projection(desc, length_increasing=False).bruhat_le(other.apply_simple_reflection(desc)) return self == other + @cached_in_parent_method def weak_le(self, other, side='right'): - """ - Comparison in weak order. + r""" + Perform the comparison between ``self`` and ``other`` in + weak (Bruhat) order. INPUT: - - other -- an element of the same Coxeter group - - side -- 'left' or 'right' (default: 'right') + - ``other`` -- an element of the same Coxeter group + - ``side`` -- string (default: ``'right'``); ``'left'`` or ``'right'`` - OUTPUT: a boolean + OUTPUT: boolean - This returns whether ``self`` <= ``other`` in left - (resp. right) weak order, that is if 'v' can be obtained - from 'v' by length increasing multiplication by simple - reflections on the left (resp. right). + This returns whether `u \leq v`, where `u` is ``self`` and `v` + is ``other``, in left (resp. right) weak order, that is if `v` + can be obtained from `u` by length increasing multiplication by + simple reflections on the left (resp. right). EXAMPLES:: @@ -2797,11 +2790,11 @@ def weak_covers(self, side='right', index_set=None, positive=False): INPUT: - - side -- 'left' or 'right' (default: 'right') - - positive -- a boolean (default: ``False``) - - index_set -- a list of indices or None + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``positive`` -- boolean (default: ``False``) + - ``index_set`` -- list of indices or None - OUTPUT: a list + OUTPUT: list EXAMPLES:: @@ -2845,11 +2838,9 @@ def coxeter_sorting_word(self, c): INPUT: - - ``c`` -- a Coxeter element. - - OUTPUT: + - ``c`` -- a Coxeter element - the ``c``-sorting word of ``self`` as a list of integers. + OUTPUT: the ``c``-sorting word of ``self`` as a list of integers EXAMPLES:: @@ -2889,13 +2880,9 @@ def is_coxeter_sortable(self, c, sorting_word=None): INPUT: - - ``c`` -- a Coxeter element. - - ``sorting_word`` -- sorting word (default: None) used to - not recompute the ``c``-sorting word if already computed. - - OUTPUT: - - is ``self`` ``c``-sortable + - ``c`` -- a Coxeter element + - ``sorting_word`` -- sorting word (default: ``None``); used to + not recompute the `c`-sorting word if already computed EXAMPLES:: @@ -2965,18 +2952,18 @@ def apply_demazure_product(self, element, side='right', reduced word) of elements from the index set of the Coxeter group. - - ``side`` -- 'left' or 'right' (default: 'right'); the + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``); the side of ``self`` on which the element should be applied. If ``side`` is 'left' then the operation is applied on the left. - - ``length_increasing`` -- a boolean (default: ``True``) + - ``length_increasing`` -- boolean (default: ``True``) whether to act length increasingly or decreasingly EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['C', 4], prefix="s") + sage: W = WeylGroup(['C', 4], prefix='s') sage: v = W.from_reduced_word([1,2,3,4,3,1]) sage: v.apply_demazure_product([1,3,4,3,3]) s4*s1*s2*s3*s4*s3*s1 @@ -2986,7 +2973,6 @@ def apply_demazure_product(self, element, side='right', s3*s4*s1*s2*s3*s4*s2*s3*s1 sage: v.apply_demazure_product(v) s2*s3*s4*s1*s2*s3*s4*s2*s3*s2*s1 - """ # if self and element have the same parent if self.parent().is_parent_of(element): @@ -3011,16 +2997,20 @@ def apply_demazure_product(self, element, side='right', def min_demazure_product_greater(self, element): r""" - Find the unique Bruhat-minimum element ``u`` such that ``v`` `\le` ``w`` * ``u`` where ``v`` is ``self``, ``w`` is ``element`` and ``*`` is the Demazure product. + Find the unique Bruhat-minimum element ``u`` such that ``v`` `\le` + ``w`` * ``u`` where ``v`` is ``self``, ``w`` is ``element`` and + ``*`` is the Demazure product. INPUT: - - ``element`` is either an element of the same Coxeter group as ``self`` or a list (such as a reduced word) of elements from the index set of the Coxeter group. + - ``element`` -- is either an element of the same Coxeter group as + ``self`` or a list (such as a reduced word) of elements from the + index set of the Coxeter group EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['A', 4], prefix="s") + sage: W = WeylGroup(['A', 4], prefix='s') sage: v = W.from_reduced_word([2,3,4,1,2]) sage: u = W.from_reduced_word([2,3,2,1]) sage: v.min_demazure_product_greater(u) @@ -3029,7 +3019,6 @@ def min_demazure_product_greater(self, element): s4*s2 sage: v.min_demazure_product_greater((2,3,2,1)) s4*s2 - """ # if self and element have the same parent if self.parent().is_parent_of(element): @@ -3053,8 +3042,9 @@ def deodhar_factor_element(self, w, index_set): INPUT: - - ``w`` is an element of the same Coxeter group ``W`` as ``self`` - - ``index_set`` is a subset of Dynkin nodes defining a parabolic subgroup ``W'`` of ``W`` + - ``w`` -- an element of the same Coxeter group ``W`` as ``self`` + - ``index_set`` -- a subset of Dynkin nodes defining a parabolic + subgroup ``W'`` of ``W`` It is assumed that ``v = self`` and ``w`` are minimum length coset representatives for ``W/W'`` such that ``v`` `\le` ``w`` in Bruhat order. @@ -3068,7 +3058,7 @@ def deodhar_factor_element(self, w, index_set): EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['A', 5], prefix="s") + sage: W = WeylGroup(['A', 5], prefix='s') sage: v = W.from_reduced_word([5]) sage: w = W.from_reduced_word([4,5,2,3,1,2]) sage: v.deodhar_factor_element(w, [1,3,4]) @@ -3112,8 +3102,9 @@ def deodhar_lift_up(self, w, index_set): INPUT: - - ``w`` is an element of the same Coxeter group ``W`` as ``self``. - - ``index_set`` is a subset of Dynkin nodes defining a parabolic subgroup ``W'``. + - ``w`` -- an element of the same Coxeter group ``W`` as ``self`` + - ``index_set`` -- a subset of Dynkin nodes defining a parabolic + subgroup ``W'`` OUTPUT: @@ -3125,7 +3116,7 @@ def deodhar_lift_up(self, w, index_set): EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['A', 3], prefix="s") + sage: W = WeylGroup(['A', 3], prefix='s') sage: v = W.from_reduced_word([1,2,3]) sage: w = W.from_reduced_word([1,3,2]) sage: v.deodhar_lift_up(w, [3]) @@ -3147,8 +3138,8 @@ def deodhar_lift_down(self, w, index_set): INPUT: - - ``w`` is an element of the same Coxeter group ``W`` as ``self``. - - ``index_set`` is a subset of Dynkin nodes defining a parabolic subgroup ``W'``. + - ``w`` -- an element of the same Coxeter group ``W`` as ``self`` + - ``index_set`` -- a subset of Dynkin nodes defining a parabolic subgroup ``W'`` OUTPUT: @@ -3160,12 +3151,11 @@ def deodhar_lift_down(self, w, index_set): EXAMPLES:: sage: # needs sage.combinat sage.groups - sage: W = WeylGroup(['A', 3], prefix="s") + sage: W = WeylGroup(['A', 3], prefix='s') sage: v = W.from_reduced_word([1,2,3,2]) sage: w = W.from_reduced_word([3,2]) sage: v.deodhar_lift_down(w, [3]) s2*s3*s2 - """ vmin = self.coset_representative(index_set) wmin = w.coset_representative(index_set) @@ -3183,7 +3173,7 @@ def inversions_as_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A', 3], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 3], prefix='s') # needs sage.combinat sage.groups sage: w = W.from_reduced_word([3,1,2,1]) # needs sage.combinat sage.groups sage: w.inversions_as_reflections() # needs sage.combinat sage.groups [s1, s1*s2*s1, s2, s1*s2*s3*s2*s1] @@ -3200,7 +3190,7 @@ def left_inversions_as_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A', 3], prefix="s") # needs sage.combinat sage.groups + sage: W = WeylGroup(['A', 3], prefix='s') # needs sage.combinat sage.groups sage: w = W.from_reduced_word([3,1,2,1]) # needs sage.combinat sage.groups sage: w.left_inversions_as_reflections() # needs sage.combinat sage.groups [s1, s3, s1*s2*s3*s2*s1, s2*s3*s2] @@ -3214,9 +3204,9 @@ def lower_covers(self, side='right', index_set=None): INPUT: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``index_set`` -- a list of indices or ``None`` + - ``index_set`` -- list of indices or ``None`` - OUTPUT: a list + OUTPUT: list EXAMPLES:: @@ -3250,9 +3240,9 @@ def upper_covers(self, side='right', index_set=None): INPUT: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``index_set`` -- a list of indices or ``None`` + - ``index_set`` -- list of indices or ``None`` - OUTPUT: a list + OUTPUT: list EXAMPLES:: diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index d8687f7e72a..c822bbd50fc 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -116,20 +116,20 @@ def super_categories(self): """ return [EnumeratedSets()] - def example(self, choice="highwt", **kwds): + def example(self, choice='highwt', **kwds): r""" - Returns an example of a crystal, as per + Return an example of a crystal, as per :meth:`Category.example() `. INPUT: - - ``choice`` -- str [default: 'highwt']. Can be either 'highwt' - for the highest weight crystal of type A, or 'naive' for an - example of a broken crystal. + - ``choice`` -- string (default: ``'highwt'``); can be either ``'highwt'`` + for the highest weight crystal of type A, or ``'naive'`` for an + example of a broken crystal - ``**kwds`` -- keyword arguments passed onto the constructor for the - chosen crystal. + chosen crystal EXAMPLES:: @@ -237,7 +237,7 @@ class ParentMethods: def an_element(self): """ - Returns an element of ``self`` + Return an element of ``self``. sage: C = crystals.Letters(['A', 5]) sage: C.an_element() @@ -309,7 +309,7 @@ def weight_lattice_realization(self): def cartan_type(self): """ - Returns the Cartan type of the crystal + Return the Cartan type of the crystal. EXAMPLES:: @@ -322,7 +322,7 @@ def cartan_type(self): @cached_method def index_set(self): """ - Returns the index set of the Dynkin diagram underlying the crystal + Return the index set of the Dynkin diagram underlying the crystal. EXAMPLES:: @@ -334,7 +334,7 @@ def index_set(self): def Lambda(self): """ - Returns the fundamental weights in the weight lattice + Return the fundamental weights in the weight lattice realization for the root system associated with the crystal EXAMPLES:: @@ -351,10 +351,10 @@ def __iter__(self, index_set=None, max_depth=float('inf')): INPUT: - - ``index_set`` -- (Default: ``None``) the index set; if ``None`` + - ``index_set`` -- (default: ``None``) the index set; if ``None`` then use the index set of the crystal - - ``max_depth`` -- (Default: infinity) the maximum depth to build + - ``max_depth`` -- (default: infinity) the maximum depth to build The iteration order is not specified except that, if ``max_depth`` is finite, then the iteration goes depth by @@ -382,7 +382,6 @@ def __iter__(self, index_set=None, max_depth=float('inf')): [(-Lambda[0] + Lambda[2],), (Lambda[0] - Lambda[1] + delta,), (Lambda[1] - Lambda[2],)] - """ if index_set is None: index_set = self.index_set() @@ -391,8 +390,8 @@ def __iter__(self, index_set=None, max_depth=float('inf')): R = RecursivelyEnumeratedSet(self.module_generators, succ, structure=None) return R.breadth_first_search_iterator(max_depth) - def subcrystal(self, index_set=None, generators=None, max_depth=float("inf"), - direction="both", contained=None, + def subcrystal(self, index_set=None, generators=None, max_depth=float('inf'), + direction='both', contained=None, virtualization=None, scaling_factors=None, cartan_type=None, category=None): r""" @@ -580,7 +579,7 @@ def _Hom_(self, Y, category=None, **options): The sole purpose of this method is to construct the homset as a :class:`~sage.categories.crystals.CrystalHomset`. If ``category`` is specified and is not a subcategory of - :class:`Crystals`, a :class:`TypeError` is raised instead. + :class:`Crystals`, a :exc:`TypeError` is raised instead. This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. @@ -634,8 +633,8 @@ def crystal_morphism(self, on_gens, codomain=None, default are all scaling factors to be one - ``category`` -- (optional) the category for the crystal morphism; the default is the category of :class:`Crystals`. - - ``check`` -- (default: ``True``) check if the crystal morphism - is valid + - ``check`` -- boolean (default: ``True``); check if the crystal + morphism is valid .. SEEALSO:: @@ -914,7 +913,7 @@ def digraph(self, subset=None, index_set=None): G = DiGraph(d) from sage.graphs.dot2tex_utils import have_dot2tex if have_dot2tex(): - G.set_latex_options(format="dot2tex", + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=self.cartan_type()._index_set_coloring) return G @@ -955,7 +954,7 @@ def latex_file(self, filename): def _latex_(self, **options): r""" - Returns the crystal graph as a latex string. This can be exported + Return the crystal graph as a latex string. This can be exported to a file with ``self.latex_file('filename')``. EXAMPLES:: @@ -1008,14 +1007,15 @@ def metapost(self, filename, thicklines=False, labels=True, scaling_factor=1.0, - ``filename`` -- name of the output file, e.g., ``'filename.mp'`` - - ``thicklines`` -- (default: ``True``) for thicker edges + - ``thicklines`` -- boolean (default: ``True``); for thicker edges - - ``labels`` -- (default: ``False``) to suppress labeling of the vertices + - ``labels`` -- boolean (default: ``False``); whether to suppress + labeling of the vertices - - ``scaling_factor`` -- (default: ``1.0``) Increasing or decreasing the + - ``scaling_factor`` -- (default: ``1.0``) increasing or decreasing the scaling factor changes the size of the image - - ``tallness`` -- (default: ``1.0``) Increasing makes the image taller + - ``tallness`` -- (default: ``1.0``) increasing makes the image taller without increasing the width EXAMPLES:: @@ -1330,7 +1330,7 @@ def index_set(self): def cartan_type(self): """ - Returns the Cartan type associated to ``self`` + Return the Cartan type associated to ``self``. EXAMPLES:: @@ -1550,7 +1550,7 @@ def is_highest_weight(self, index_set=None): def is_lowest_weight(self, index_set=None): r""" - Returns ``True`` if ``self`` is a lowest weight. + Return ``True`` if ``self`` is a lowest weight. Specifying the option ``index_set`` to be a subset `I` of the index set of the underlying crystal, finds all lowest weight vectors for arrows in `I`. @@ -1699,7 +1699,7 @@ def all_paths_to_highest_weight(self, index_set=None): if hw: yield [] - def subcrystal(self, index_set=None, max_depth=float("inf"), direction="both", + def subcrystal(self, index_set=None, max_depth=float("inf"), direction='both', contained=None, cartan_type=None, category=None): r""" Construct the subcrystal generated by ``self`` using `e_i` and/or @@ -2046,7 +2046,8 @@ class CrystalMorphismByGenerators(CrystalMorphism): for the weight, `\varepsilon` and `\varphi` - ``gens`` -- (optional) a finite list of generators to define the morphism; the default is to use the highest weight vectors of the crystal - - ``check`` -- (default: ``True``) check if the crystal morphism is valid + - ``check`` -- boolean (default: ``True``); check if the crystal morphism + is valid .. SEEALSO:: @@ -2201,7 +2202,7 @@ def _call_(self, x): def __bool__(self) -> bool: """ - Return if ``self`` is a non-zero morphism. + Return if ``self`` is a nonzero morphism. EXAMPLES:: @@ -2222,9 +2223,7 @@ def to_module_generator(self, x): Return a generator ``mg`` and a path of `e_i` and `f_i` operations to ``mg``. - OUTPUT: - - A tuple consisting of: + OUTPUT: a tuple consisting of: - a module generator, - a list of ``'e'`` and ``'f'`` to denote which operation, and diff --git a/src/sage/categories/discrete_valuation.py b/src/sage/categories/discrete_valuation.py index 1d13c49cd83..77267664bb2 100644 --- a/src/sage/categories/discrete_valuation.py +++ b/src/sage/categories/discrete_valuation.py @@ -18,7 +18,7 @@ class DiscreteValuationRings(Category_singleton): """ - The category of discrete valuation rings + The category of discrete valuation rings. EXAMPLES:: @@ -97,10 +97,10 @@ def _matrix_charpoly(self, M, var): sage: M.charpoly() x^3 + (4 + 4*t^2 + 4*t^4 + O(t^25))*x^2 + (4*t + O(t^24))*x - Another example over the p-adics:: + Another example over the `p`-adics:: sage: # needs sage.modules sage.rings.padics - sage: R = Zp(5, print_mode="digits", prec=5) + sage: R = Zp(5, print_mode='digits', prec=5) sage: M = matrix(R, 3, 3, range(9)) sage: M [ 0 ...00001 ...00002] @@ -138,7 +138,6 @@ def euclidean_degree(self): Traceback (most recent call last): ... ValueError: Euclidean degree of the zero element not defined - """ if not self: raise ValueError("Euclidean degree of the zero element not defined") @@ -199,7 +198,7 @@ def is_unit(self): def gcd(self,other): """ - Return the greatest common divisor of self and other, + Return the greatest common divisor of ``self`` and ``other``, normalized so that it is a power of the distinguished uniformizer. """ @@ -212,7 +211,7 @@ def gcd(self,other): def lcm(self,other): """ - Return the least common multiple of self and other, + Return the least common multiple of ``self`` and ``other``, normalized so that it is a power of the distinguished uniformizer. """ @@ -226,7 +225,7 @@ def lcm(self,other): class DiscreteValuationFields(Category_singleton): """ - The category of discrete valuation fields + The category of discrete valuation fields. EXAMPLES:: @@ -295,10 +294,10 @@ def _matrix_hessenbergize(self, H): [ O(t^10) O(t^10) O(t^10) O(t^10)] [ O(t^10) O(t^10) O(t^10) O(t^10)] - Another example over the p-adics:: + Another example over the `p`-adics:: sage: # needs sage.modules sage.rings.padics - sage: K = Qp(5, print_mode="digits", prec=5) + sage: K = Qp(5, print_mode='digits', prec=5) sage: H = matrix(K, 3, 3, range(9)); H [ 0 ...00001 ...00002] [ ...00003 ...00004 ...000010] diff --git a/src/sage/categories/division_rings.py b/src/sage/categories/division_rings.py index 3e6eb7c6c1c..fd3797fccc6 100644 --- a/src/sage/categories/division_rings.py +++ b/src/sage/categories/division_rings.py @@ -16,10 +16,10 @@ class DivisionRings(CategoryWithAxiom): """ - The category of division rings + The category of division rings. A division ring (or skew field) is a not necessarily commutative - ring where all non-zero elements have multiplicative inverses + ring where all nonzero elements have multiplicative inverses EXAMPLES:: diff --git a/src/sage/categories/domains.py b/src/sage/categories/domains.py index 052cc9a795c..de1cb009a08 100644 --- a/src/sage/categories/domains.py +++ b/src/sage/categories/domains.py @@ -17,7 +17,7 @@ class Domains(CategoryWithAxiom): """ - The category of domains + The category of domains. A domain (or non-commutative integral domain), is a ring, not necessarily commutative, with no nonzero zero divisors. @@ -77,7 +77,6 @@ def _test_zero_divisors(self, **options): sage: ZZ._test_zero_divisors() sage: ZpFM(5)._test_zero_divisors() # needs sage.rings.padics - """ if not self.is_exact(): return # Can't check on inexact rings diff --git a/src/sage/categories/drinfeld_modules.py b/src/sage/categories/drinfeld_modules.py index c2ba86e9f2f..aca5675497a 100644 --- a/src/sage/categories/drinfeld_modules.py +++ b/src/sage/categories/drinfeld_modules.py @@ -205,14 +205,14 @@ class DrinfeldModules(Category_over_base_ring): def __init__(self, base_field, name='t'): r""" - Initialize `self`. + Initialize ``self``. INPUT: - ``base_field`` -- the base field, which is a ring extension over a base - - ``name`` (default: ``'t'``) -- the name of the Ore polynomial + - ``name`` -- (default: ``'t'``) the name of the Ore polynomial variable TESTS:: @@ -290,7 +290,7 @@ def _latex_(self): r""" Return a latex representation of the category. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -310,7 +310,7 @@ def _repr_(self): r""" Return a string representation of the category. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -506,7 +506,7 @@ def object(self, gen): def ore_polring(self): r""" - Return the Ore polynomial ring of the category + Return the Ore polynomial ring of the category. EXAMPLES:: @@ -527,7 +527,7 @@ def random_object(self, rank): INPUT: - - ``rank`` -- an integer, the rank of the Drinfeld module + - ``rank`` -- integer; the rank of the Drinfeld module EXAMPLES:: @@ -785,6 +785,5 @@ def ore_variable(self): Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 over its base twisted by Frob^2 sage: phi.ore_variable() t - """ return self.category().ore_polring().gen() diff --git a/src/sage/categories/enumerated_sets.py b/src/sage/categories/enumerated_sets.py index 5526bdb0235..68a830c289d 100644 --- a/src/sage/categories/enumerated_sets.py +++ b/src/sage/categories/enumerated_sets.py @@ -21,7 +21,7 @@ class EnumeratedSets(CategoryWithAxiom): """ - The category of enumerated sets + The category of enumerated sets. An *enumerated set* is a *finite* or *countable* set or multiset `S` together with a canonical enumeration of its elements; @@ -40,36 +40,36 @@ class EnumeratedSets(CategoryWithAxiom): The standard methods for an enumerated set ``S`` are: - - ``S.cardinality()``: the number of elements of the set. This + - ``S.cardinality()`` -- the number of elements of the set. This is the equivalent for ``len`` on a list except that the return value is specified to be a Sage :class:`Integer` or ``infinity``, instead of a Python ``int``. - - ``iter(S)``: an iterator for the elements of the set; + - ``iter(S)`` -- an iterator for the elements of the set; - - ``S.list()``: a fresh list of the elements of the set, when - possible; raises a :class:`NotImplementedError` if the list is + - ``S.list()`` -- a fresh list of the elements of the set, when + possible; raises a :exc:`NotImplementedError` if the list is predictably too large to be expanded in memory. - - ``S.tuple()``: a tuple of the elements of the set, when - possible; raises a :class:`NotImplementedError` if the tuple is + - ``S.tuple()`` -- a tuple of the elements of the set, when + possible; raises a :exc:`NotImplementedError` if the tuple is predictably too large to be expanded in memory. - - ``S.unrank(n)``: the ``n``-th element of the set when ``n`` is a sage + - ``S.unrank(n)`` -- the ``n``-th element of the set when ``n`` is a sage ``Integer``. This is the equivalent for ``l[n]`` on a list. - - ``S.rank(e)``: the position of the element ``e`` in the set; + - ``S.rank(e)`` -- the position of the element ``e`` in the set; This is equivalent to ``l.index(e)`` for a list except that the return value is specified to be a Sage :class:`Integer`, instead of a Python ``int``. - - ``S.first()``: the first object of the set; it is equivalent to + - ``S.first()`` -- the first object of the set; it is equivalent to ``S.unrank(0)``. - - ``S.next(e)``: the object of the set which follows ``e``; it is + - ``S.next(e)`` -- the object of the set which follows ``e``; it is equivalent to ``S.unrank(S.rank(e) + 1)``. - - ``S.random_element()``: a random generator for an element of + - ``S.random_element()`` -- a random generator for an element of the set. Unless otherwise stated, and for finite enumerated sets, the probability is uniform. @@ -78,7 +78,6 @@ class EnumeratedSets(CategoryWithAxiom): - ``FiniteEnumeratedSets().example()`` - ``InfiniteEnumeratedSets().example()`` - EXAMPLES:: sage: EnumeratedSets() @@ -184,7 +183,7 @@ def __iter__(self): the methods of the first column are defined using ``__iter__`` If none of these are provided, this raises - a :class:`NotImplementedError`. + a :exc:`NotImplementedError`. EXAMPLES: @@ -229,7 +228,6 @@ def __iter__(self): ....: return [5, 6, 7] sage: it = iter(set_list()); [next(it), next(it), next(it)] [5, 6, 7] - """ # Check if .first() and .next(x) are overridden in the subclass if ( self.first != self._first_from_iterator and @@ -710,7 +708,7 @@ def _next_from_iterator(self, obj): def _unrank_from_iterator(self, r): """ - The ``r``-th element of ``self`` + The ``r``-th element of ``self``. ``self.unrank(r)`` returns the ``r``-th element of ``self``, where ``r`` is an integer between ``0`` and ``n-1`` where ``n`` is the @@ -748,12 +746,12 @@ def _unrank_from_iterator(self, r): def _rank_from_iterator(self, x): """ - The rank of an element of ``self`` + The rank of an element of ``self``. ``self.rank(x)`` returns the rank of `x`, that is its position in the enumeration of ``self``. This is an integer between ``0`` and ``n-1`` where ``n`` is the - cardinality of ``self``, or None if `x` is not in `self`. + cardinality of ``self``, or None if `x` is not in ``self``. This is the default (brute force) implementation from the category ``EnumeratedSets()`` which can be used when the @@ -862,7 +860,7 @@ def _iterator_from_unrank(self): @cached_method def _an_element_from_iterator(self): """ - Return the first element of ``self`` returned by :meth:`__iter__` + Return the first element of ``self`` returned by :meth:`__iter__`. If ``self`` is empty, the exception :class:`~sage.categories.sets_cat.EmptySetError` is raised instead. @@ -930,7 +928,7 @@ def random_element(self): the probability is uniform. This is a generic implementation from the category - ``EnumeratedSets()``. It raises a :class:`NotImplementedError` + ``EnumeratedSets()``. It raises a :exc:`NotImplementedError` since one does not know whether the set is finite. EXAMPLES:: @@ -952,8 +950,8 @@ def map(self, f, name=None, *, is_injective=True): INPUT: - - ``is_injective`` -- boolean (default: ``True``) whether to assume - that ``f`` is injective. + - ``is_injective`` -- boolean (default: ``True``); whether to assume + that `f` is injective EXAMPLES:: @@ -1003,7 +1001,7 @@ def map(self, f, name=None, *, is_injective=True): # def _test_enumerated_set_contains(self, **options): """ - Checks that the methods :meth:`.__contains__` and :meth:`.__iter__` are consistent. + Check that the methods :meth:`.__contains__` and :meth:`.__iter__` are consistent. See also :class:`TestSuite`. @@ -1039,7 +1037,7 @@ def _test_enumerated_set_contains(self, **options): def _test_enumerated_set_iter_list(self, **options): """ - Checks that the methods :meth:`.list` and :meth:`.__iter__` are consistent. + Check that the methods :meth:`.list` and :meth:`.__iter__` are consistent. See also: :class:`TestSuite`. diff --git a/src/sage/categories/euclidean_domains.py b/src/sage/categories/euclidean_domains.py index 87e2edf5002..93a834c9cfc 100644 --- a/src/sage/categories/euclidean_domains.py +++ b/src/sage/categories/euclidean_domains.py @@ -40,7 +40,6 @@ class EuclideanDomains(Category_singleton): TESTS:: sage: TestSuite(EuclideanDomains()).run() - """ def super_categories(self): """ @@ -60,7 +59,6 @@ def is_euclidean_domain(self): sage: Parent(QQ,category=EuclideanDomains()).is_euclidean_domain() True - """ return True @@ -71,7 +69,7 @@ def gcd_free_basis(self, elts): INPUT: - - ``elts`` -- A sequence of elements of ``self``. + - ``elts`` -- a sequence of elements of ``self`` OUTPUT: @@ -132,7 +130,7 @@ def refine(a, b): def _test_euclidean_degree(self, **options): r""" - Test that the assumptions on an Euclidean degree are met. + Test that the assumptions on a Euclidean degree are met. EXAMPLES:: @@ -197,7 +195,7 @@ class ElementMethods: @abstract_method def euclidean_degree(self): r""" - Return the degree of this element as an element of an Euclidean + Return the degree of this element as an element of a Euclidean domain, i.e., for elements `a`, `b` the euclidean degree `f` satisfies the usual properties: @@ -213,7 +211,7 @@ def euclidean_degree(self): OUTPUT: - For non-zero elements, a natural number. For the zero element, this + For nonzero elements, a natural number. For the zero element, this might raise an exception or produce some other output, depending on the implementation. @@ -257,15 +255,13 @@ def gcd(self, other): def quo_rem(self, other): r""" Return the quotient and remainder of the division of this element - by the non-zero element ``other``. + by the nonzero element ``other``. INPUT: - ``other`` -- an element in the same euclidean domain - OUTPUT: - - a pair of elements + OUTPUT: a pair of elements EXAMPLES:: diff --git a/src/sage/categories/examples/algebras_with_basis.py b/src/sage/categories/examples/algebras_with_basis.py index 2521aadae04..c0da74e21dc 100644 --- a/src/sage/categories/examples/algebras_with_basis.py +++ b/src/sage/categories/examples/algebras_with_basis.py @@ -19,7 +19,7 @@ class FreeAlgebra(CombinatorialFreeModule): r""" - An example of an algebra with basis: the free algebra + An example of an algebra with basis: the free algebra. This class illustrates a minimal implementation of an algebra with basis. """ @@ -31,7 +31,6 @@ def __init__(self, R, alphabet=("a", "b", "c")): sage: A = AlgebrasWithBasis(QQ).example(); A # needs sage.modules An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field sage: TestSuite(A).run() # needs sage.modules - """ self._alphabet = alphabet CombinatorialFreeModule.__init__(self, R, @@ -50,10 +49,10 @@ def _repr_(self): @cached_method def one_basis(self): """ - Returns the empty word, which index the one of this algebra, + Return the empty word, which index the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. - EXAMPLES::r + EXAMPLES:: sage: A = AlgebrasWithBasis(QQ).example() # needs sage.modules sage: A.one_basis() # needs sage.modules diff --git a/src/sage/categories/examples/commutative_additive_monoids.py b/src/sage/categories/examples/commutative_additive_monoids.py index eb98d91237c..5a99ccffee2 100644 --- a/src/sage/categories/examples/commutative_additive_monoids.py +++ b/src/sage/categories/examples/commutative_additive_monoids.py @@ -17,7 +17,7 @@ class FreeCommutativeAdditiveMonoid(FreeCommutativeAdditiveSemigroup): r""" - An example of a commutative additive monoid: the free commutative monoid + An example of a commutative additive monoid: the free commutative monoid. This class illustrates a minimal implementation of a commutative monoid. @@ -69,11 +69,11 @@ class FreeCommutativeAdditiveMonoid(FreeCommutativeAdditiveSemigroup): def __init__(self, alphabet=('a','b','c','d')): r""" - The free commutative monoid + The free commutative monoid. INPUT: - - ``alphabet`` -- a tuple of strings: the generators of the monoid + - ``alphabet`` -- tuple of strings; the generators of the monoid EXAMPLES:: @@ -83,7 +83,6 @@ def __init__(self, alphabet=('a','b','c','d')): TESTS:: sage: TestSuite(M).run() - """ self.alphabet = alphabet Parent.__init__(self, category=CommutativeAdditiveMonoids()) @@ -95,14 +94,13 @@ def _repr_(self): sage: M = CommutativeAdditiveMonoids().example(alphabet=('a','b','c')) sage: M._repr_() "An example of a commutative monoid: the free commutative monoid generated by ('a', 'b', 'c')" - """ return "An example of a commutative monoid: the free commutative monoid generated by %s" % (self.alphabet,) @cached_method def zero(self): r""" - Returns the zero of this additive monoid, as per :meth:`CommutativeAdditiveMonoids.ParentMethods.zero`. + Return the zero of this additive monoid, as per :meth:`CommutativeAdditiveMonoids.ParentMethods.zero`. EXAMPLES:: diff --git a/src/sage/categories/examples/commutative_additive_semigroups.py b/src/sage/categories/examples/commutative_additive_semigroups.py index 34e2ebfd0d8..78701a16be3 100644 --- a/src/sage/categories/examples/commutative_additive_semigroups.py +++ b/src/sage/categories/examples/commutative_additive_semigroups.py @@ -19,7 +19,7 @@ class FreeCommutativeAdditiveSemigroup(UniqueRepresentation, Parent): r""" - An example of a commutative additive monoid: the free commutative monoid + An example of a commutative additive monoid: the free commutative monoid. This class illustrates a minimal implementation of a commutative additive monoid. @@ -69,11 +69,11 @@ class FreeCommutativeAdditiveSemigroup(UniqueRepresentation, Parent): def __init__(self, alphabet=('a','b','c','d')): r""" - The free commutative monoid + The free commutative monoid. INPUT: - - ``alphabet`` -- a tuple of strings: the generators of the semigroup + - ``alphabet`` -- tuple of strings; the generators of the semigroup EXAMPLES:: @@ -94,13 +94,12 @@ def _repr_(self): sage: M = CommutativeAdditiveSemigroups().example(alphabet=('a','b','c')) sage: M._repr_() "An example of a commutative semigroup: the free commutative semigroup generated by ('a', 'b', 'c')" - """ return "An example of a commutative semigroup: the free commutative semigroup generated by %s" % (self.alphabet,) def summation(self, x, y): r""" - Returns the product of ``x`` and ``y`` in the semigroup, as per + Return the product of ``x`` and ``y`` in the semigroup, as per :meth:`CommutativeAdditiveSemigroups.ParentMethods.summation`. EXAMPLES:: @@ -119,7 +118,7 @@ def summation(self, x, y): @cached_method def additive_semigroup_generators(self): r""" - Returns the generators of the semigroup. + Return the generators of the semigroup. EXAMPLES:: @@ -134,7 +133,7 @@ def additive_semigroup_generators(self): def an_element(self): r""" - Returns an element of the semigroup. + Return an element of the semigroup. EXAMPLES:: @@ -167,11 +166,10 @@ def __init__(self, parent, iterable): {'a': 2, 'b': 0, 'c': 1, 'd': 5} """ d = {a: 0 for a in parent.alphabet} - for a, c in iterable: - d[a] = c + d.update(iterable) ElementWrapper.__init__(self, parent, d) - def _repr_(self): + def _repr_(self) -> str: """ EXAMPLES:: @@ -183,8 +181,9 @@ def _repr_(self): 0 """ d = self.value - result = ' + '.join( ("%s*%s" % (d[a],a) if d[a] != 1 else a) for a in sorted(d.keys()) if d[a] != 0) - return '0' if result == '' else result + result = ' + '.join(("%s*%s" % (d[a], a) if d[a] != 1 else a) + for a in sorted(d.keys()) if d[a] != 0) + return '0' if not result else result def __hash__(self): """ diff --git a/src/sage/categories/examples/crystals.py b/src/sage/categories/examples/crystals.py index 4786a4ed6fd..5d3fcc5ed9f 100644 --- a/src/sage/categories/examples/crystals.py +++ b/src/sage/categories/examples/crystals.py @@ -127,7 +127,7 @@ class Element(ElementWrapper): def e(self, i): r""" - Returns the action of `e_i` on ``self``. + Return the action of `e_i` on ``self``. EXAMPLES:: @@ -143,7 +143,7 @@ def e(self, i): def f(self, i): r""" - Returns the action of `f_i` on ``self``. + Return the action of `f_i` on ``self``. EXAMPLES:: @@ -189,7 +189,8 @@ def __init__(self): self.n = 2 self._cartan_type = CartanType(['A', 2]) self.G = DiGraph(5) - self.G.add_edges([ [0,1,1], [1,2,1], [2,3,1], [3,5,1], [0,4,2], [4,5,2] ]) + self.G.add_edges([[0, 1, 1], [1, 2, 1], [2, 3, 1], + [3, 5, 1], [0, 4, 2], [4, 5, 2]]) self.module_generators = [self(0)] def __repr__(self): @@ -204,7 +205,7 @@ def __repr__(self): class Element(ElementWrapper): def e(self, i): r""" - Returns the action of `e_i` on ``self``. + Return the action of `e_i` on ``self``. EXAMPLES:: @@ -220,7 +221,7 @@ def e(self, i): def f(self, i): r""" - Returns the action of `f_i` on ``self``. + Return the action of `f_i` on ``self``. EXAMPLES:: diff --git a/src/sage/categories/examples/facade_sets.py b/src/sage/categories/examples/facade_sets.py index 3108ba967c0..a26e23834ee 100644 --- a/src/sage/categories/examples/facade_sets.py +++ b/src/sage/categories/examples/facade_sets.py @@ -81,13 +81,12 @@ def _repr_(self): EXAMPLES:: sage: S = Sets().Facade().example() # indirect doctest - """ return "An example of facade set: the monoid of positive integers" def _element_constructor_(self, object): r""" - Construction of elements + Construction of elements. Since ``self`` is a strict subset of the parent it is a facade for, it is mandatory to override this method. This method diff --git a/src/sage/categories/examples/filtered_algebras_with_basis.py b/src/sage/categories/examples/filtered_algebras_with_basis.py index 9b982e7123f..6de8f87edc0 100644 --- a/src/sage/categories/examples/filtered_algebras_with_basis.py +++ b/src/sage/categories/examples/filtered_algebras_with_basis.py @@ -34,17 +34,17 @@ class PBWBasisCrossProduct(CombinatorialFreeModule): The implementation involves the following: - - A set of algebra generators -- the set of generators `x,y,z`. + - A set of algebra generators -- the set of generators `x,y,z` - The index of the unit element -- the unit element in the monoid - of monomials. + of monomials - A product -- this is given on basis elements by using - :meth:`product_on_basis`. + :meth:`product_on_basis` - A degree function -- this is determined on the basis elements by using :meth:`degree_on_basis` which returns the sum of exponents - of the monomial. + of the monomial """ def __init__(self, base_ring): """ @@ -127,7 +127,7 @@ def degree_on_basis(self, m): - ``m`` -- an element of the free abelian monoid - OUTPUT: an integer, the degree of the corresponding basis element + OUTPUT: integer; the degree of the corresponding basis element EXAMPLES:: diff --git a/src/sage/categories/examples/filtered_modules_with_basis.py b/src/sage/categories/examples/filtered_modules_with_basis.py index d62c3d906ff..4dbe78dc5eb 100644 --- a/src/sage/categories/examples/filtered_modules_with_basis.py +++ b/src/sage/categories/examples/filtered_modules_with_basis.py @@ -108,7 +108,7 @@ def degree_on_basis(self, t): - ``t`` -- the index of an element of the basis of this module, i.e. a partition - OUTPUT: an integer, the degree of the corresponding basis element + OUTPUT: integer; the degree of the corresponding basis element EXAMPLES:: diff --git a/src/sage/categories/examples/finite_coxeter_groups.py b/src/sage/categories/examples/finite_coxeter_groups.py index 9abf9304929..b84da8d221a 100644 --- a/src/sage/categories/examples/finite_coxeter_groups.py +++ b/src/sage/categories/examples/finite_coxeter_groups.py @@ -92,7 +92,7 @@ def __init__(self, n=5): INPUT: - - `n` -- an integer with `n \geq 2` + - ``n`` -- integer with `n \geq 2` EXAMPLES:: @@ -117,7 +117,7 @@ def _repr_(self): def __contains__(self, x): r""" - Check in the element x is in the mathematical parent self. + Check if the element ``x`` is in the mathematical parent ``self``. EXAMPLES:: @@ -135,7 +135,7 @@ def __contains__(self, x): @cached_method def one(self): r""" - Implements :meth:`Monoids.ParentMethods.one`. + Implement :meth:`Monoids.ParentMethods.one`. EXAMPLES:: @@ -147,7 +147,7 @@ def one(self): def index_set(self): r""" - Implements :meth:`CoxeterGroups.ParentMethods.index_set`. + Implement :meth:`CoxeterGroups.ParentMethods.index_set`. EXAMPLES:: @@ -185,9 +185,9 @@ class Element(ElementWrapper): wrapped_class = tuple __lt__ = ElementWrapper._lt_by_value - def has_right_descent(self, i, positive=False, side="right"): + def has_right_descent(self, i, positive=False, side='right'): r""" - Implements :meth:`SemiGroups.ElementMethods.has_right_descent`. + Implement :meth:`SemiGroups.ElementMethods.has_right_descent`. EXAMPLES:: @@ -222,7 +222,7 @@ def has_right_descent(self, i, positive=False, side="right"): def apply_simple_reflection_right(self, i): r""" - Implements :meth:`CoxeterGroups.ElementMethods.apply_simple_reflection`. + Implement :meth:`CoxeterGroups.ElementMethods.apply_simple_reflection`. EXAMPLES:: diff --git a/src/sage/categories/examples/finite_enumerated_sets.py b/src/sage/categories/examples/finite_enumerated_sets.py index 264b9bc13ba..a4a1ea6fdd6 100644 --- a/src/sage/categories/examples/finite_enumerated_sets.py +++ b/src/sage/categories/examples/finite_enumerated_sets.py @@ -17,7 +17,7 @@ class Example(UniqueRepresentation, Parent): r""" - An example of a finite enumerated set: `\{1,2,3\}` + An example of a finite enumerated set: `\{1,2,3\}`. This class provides a minimal implementation of a finite enumerated set. @@ -107,7 +107,6 @@ def __iter__(self): sage: list(FiniteEnumeratedSets().example()) # indirect doctest [1, 2, 3] - """ return iter(self._set) @@ -131,7 +130,7 @@ def __init__(self, ambient=Example()): def ambient(self): """ - Returns the ambient space for ``self``, as per + Return the ambient space for ``self``, as per :meth:`Sets.Subquotients.ParentMethods.ambient() `. diff --git a/src/sage/categories/examples/finite_monoids.py b/src/sage/categories/examples/finite_monoids.py index 20119abac66..3190daba74e 100644 --- a/src/sage/categories/examples/finite_monoids.py +++ b/src/sage/categories/examples/finite_monoids.py @@ -21,7 +21,7 @@ class IntegerModMonoid(UniqueRepresentation, Parent): r""" - An example of a finite monoid: the integers mod `n` + An example of a finite monoid: the integers mod `n`. This class illustrates a minimal implementation of a finite monoid. @@ -115,7 +115,6 @@ def one(self): sage: M = FiniteMonoids().example() sage: M.one() 1 - """ return self(ZZ.one()) @@ -134,7 +133,7 @@ def product(self, x, y): def an_element(self): r""" - Returns an element of the monoid, as per :meth:`Sets.ParentMethods.an_element`. + Return an element of the monoid, as per :meth:`Sets.ParentMethods.an_element`. EXAMPLES:: diff --git a/src/sage/categories/examples/finite_semigroups.py b/src/sage/categories/examples/finite_semigroups.py index d019e6895e4..a70fe35cabb 100644 --- a/src/sage/categories/examples/finite_semigroups.py +++ b/src/sage/categories/examples/finite_semigroups.py @@ -19,7 +19,7 @@ class LeftRegularBand(UniqueRepresentation, Parent): r""" - An example of a finite semigroup + An example of a finite semigroup. This class provides a minimal implementation of a finite semigroup. @@ -71,7 +71,7 @@ class LeftRegularBand(UniqueRepresentation, Parent): Now, let us look at the structure of the semigroup:: sage: S = FiniteSemigroups().example(alphabet = ('a','b','c')) - sage: S.cayley_graph(side="left", simple=True).plot() # needs sage.graphs sage.plot + sage: S.cayley_graph(side='left', simple=True).plot() # needs sage.graphs sage.plot Graphics object consisting of 60 graphics primitives sage: S.j_transversal_of_idempotents() # random (arbitrary choice) # needs sage.graphs ['acb', 'ac', 'ab', 'bc', 'a', 'c', 'b'] @@ -134,7 +134,7 @@ def _repr_(self): def product(self, x, y): r""" - Returns the product of two elements of the semigroup. + Return the product of two elements of the semigroup. EXAMPLES:: @@ -145,7 +145,6 @@ def product(self, x, y): 'ab' sage: S('a') * S('a') 'a' - """ assert x in self assert y in self @@ -156,20 +155,19 @@ def product(self, x, y): @cached_method def semigroup_generators(self): r""" - Returns the generators of the semigroup. + Return the generators of the semigroup. EXAMPLES:: sage: S = FiniteSemigroups().example(alphabet=('x','y')) sage: S.semigroup_generators() Family ('x', 'y') - """ return Family([self(i) for i in self.alphabet]) def an_element(self): r""" - Returns an element of the semigroup. + Return an element of the semigroup. EXAMPLES:: diff --git a/src/sage/categories/examples/finite_weyl_groups.py b/src/sage/categories/examples/finite_weyl_groups.py index b3321bdb58b..91be348f3d1 100644 --- a/src/sage/categories/examples/finite_weyl_groups.py +++ b/src/sage/categories/examples/finite_weyl_groups.py @@ -61,7 +61,7 @@ class SymmetricGroup(UniqueRepresentation, Parent): 24 sage: S.long_element() (3, 2, 1, 0) - sage: S.cayley_graph(side="left").plot() # needs sage.graphs sage.plot + sage: S.cayley_graph(side='left').plot() # needs sage.graphs sage.plot Graphics object consisting of 120 graphics primitives Alternatively, one could have implemented @@ -91,14 +91,13 @@ def _repr_(self): sage: FiniteWeylGroups().example() The symmetric group on {0, ..., 3} - """ return "The symmetric group on {0, ..., %s}" % (self.n-1) @cached_method def one(self): """ - Implements :meth:`Monoids.ParentMethods.one`. + Implement :meth:`Monoids.ParentMethods.one`. EXAMPLES:: @@ -109,7 +108,7 @@ def one(self): def index_set(self): """ - Implements :meth:`CoxeterGroups.ParentMethods.index_set`. + Implement :meth:`CoxeterGroups.ParentMethods.index_set`. EXAMPLES:: @@ -147,7 +146,7 @@ def cartan_type(self): def product(self, x, y): """ - Implements :meth:`Semigroups.ParentMethods.product`. + Implement :meth:`Semigroups.ParentMethods.product`. EXAMPLES:: @@ -176,7 +175,7 @@ class Element(ElementWrapper): def has_right_descent(self, i): """ - Implements :meth:`CoxeterGroups.ElementMethods.has_right_descent`. + Implement :meth:`CoxeterGroups.ElementMethods.has_right_descent`. EXAMPLES:: diff --git a/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py b/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py index 28699e17256..ae91a374489 100644 --- a/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +++ b/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py @@ -21,7 +21,7 @@ class GradedConnectedCombinatorialHopfAlgebraWithPrimitiveGenerator(Combinatoria r""" This class illustrates an implementation of a graded Hopf algebra with basis that has one primitive generator of degree 1 and basis - elements indexed by non-negative integers. + elements indexed by nonnegative integers. This Hopf algebra example differs from what topologists refer to as a graded Hopf algebra because the twist operation in the tensor rule @@ -33,7 +33,6 @@ class GradedConnectedCombinatorialHopfAlgebraWithPrimitiveGenerator(Combinatoria (\Delta \otimes \Delta) = \Delta \circ \mu where `\tau(x\otimes y) = y\otimes x`. - """ def __init__(self, base_ring): """ @@ -41,7 +40,6 @@ def __init__(self, base_ring): sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: TestSuite(H).run() - """ CombinatorialFreeModule.__init__(self, base_ring, NonNegativeIntegers(), category=GradedHopfAlgebrasWithBasis(base_ring).Connected()) @@ -49,11 +47,9 @@ def __init__(self, base_ring): @cached_method def one_basis(self): """ - Returns 0, which index the unit of the Hopf algebra. - - OUTPUT: + Return 0, which index the unit of the Hopf algebra. - - the non-negative integer 0 + OUTPUT: the nonnegative integer 0 EXAMPLES:: @@ -62,40 +58,35 @@ def one_basis(self): 0 sage: H.one() P0 - """ return self.basis().keys()(0) def degree_on_basis(self, i): """ - The degree of a non-negative integer is itself + The degree of a nonnegative integer is itself. INPUT: - - ``i`` -- a non-negative integer - - OUTPUT: + - ``i`` -- nonnegative integer - - a non-negative integer + OUTPUT: nonnegative integer TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.degree_on_basis(45) 45 - """ return i def _repr_(self): """ - Representation of the graded connected Hopf algebra + Representation of the graded connected Hopf algebra. EXAMPLES:: sage: GradedHopfAlgebrasWithBasis(QQ).Connected().example() An example of a graded connected Hopf algebra with basis over Rational Field - """ return "An example of a graded connected Hopf algebra with basis over %s" % self.base_ring() @@ -108,7 +99,6 @@ def _repr_term(self, i): sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H._repr_term(45) 'P45' - """ return 'P' + repr(i) @@ -121,18 +111,15 @@ def product_on_basis(self, i, j): INPUT: - - ``i``, ``j`` -- non-negative integers - - OUTPUT: + - ``i``, ``j`` -- nonnegative integers - - a basis element indexed by ``i+j`` + OUTPUT: a basis element indexed by ``i+j`` TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.monomial(4) * H.monomial(5) P9 - """ return self.monomial(i+j) @@ -146,11 +133,9 @@ def coproduct_on_basis(self, i): INPUT: - - ``i`` -- a non-negative integer - - OUTPUT: + - ``i`` -- nonnegative integer - - an element of the tensor square of ``self`` + OUTPUT: an element of the tensor square of ``self`` TESTS:: diff --git a/src/sage/categories/examples/graded_modules_with_basis.py b/src/sage/categories/examples/graded_modules_with_basis.py index 348bc5b9568..7443a48a7af 100644 --- a/src/sage/categories/examples/graded_modules_with_basis.py +++ b/src/sage/categories/examples/graded_modules_with_basis.py @@ -38,7 +38,7 @@ class GradedPartitionModule(CombinatorialFreeModule): sage: A = GradedModulesWithBasis(QQ).example() # needs sage.modules - - A basis function - this module is graded by the non-negative + - A basis function - this module is graded by the nonnegative integers, so there is a function defined in this module, creatively called :func:`basis`, which takes an integer `d` as input and returns a family of partitions representing a basis @@ -122,7 +122,7 @@ def degree_on_basis(self, t): - ``t`` -- the index of an element of the basis of this module, i.e. a partition - OUTPUT: an integer, the degree of the corresponding basis element + OUTPUT: integer, the degree of the corresponding basis element EXAMPLES:: @@ -139,7 +139,7 @@ def degree_on_basis(self, t): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: diff --git a/src/sage/categories/examples/hopf_algebras_with_basis.py b/src/sage/categories/examples/hopf_algebras_with_basis.py index b9eb6ffac81..a2d8c88e074 100644 --- a/src/sage/categories/examples/hopf_algebras_with_basis.py +++ b/src/sage/categories/examples/hopf_algebras_with_basis.py @@ -19,7 +19,7 @@ class MyGroupAlgebra(CombinatorialFreeModule): r""" - An example of a Hopf algebra with basis: the group algebra of a group + An example of a Hopf algebra with basis: the group algebra of a group. This class illustrates a minimal implementation of a Hopf algebra with basis. """ @@ -50,7 +50,7 @@ def _repr_(self): @cached_method def one_basis(self): """ - Returns the one of the group, which index the one of this algebra, + Return the one of the group, which index the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. EXAMPLES:: diff --git a/src/sage/categories/examples/infinite_enumerated_sets.py b/src/sage/categories/examples/infinite_enumerated_sets.py index 8f23d276988..82f12b4691c 100644 --- a/src/sage/categories/examples/infinite_enumerated_sets.py +++ b/src/sage/categories/examples/infinite_enumerated_sets.py @@ -17,7 +17,7 @@ class NonNegativeIntegers(UniqueRepresentation, Parent): r""" - An example of infinite enumerated set: the non negative integers + An example of infinite enumerated set: the nonnegative integers. This class provides a minimal implementation of an infinite enumerated set. @@ -25,7 +25,7 @@ class NonNegativeIntegers(UniqueRepresentation, Parent): sage: NN = InfiniteEnumeratedSets().example() sage: NN - An example of an infinite enumerated set: the non negative integers + An example of an infinite enumerated set: the nonnegative integers sage: NN.cardinality() +Infinity sage: NN.list() @@ -85,7 +85,7 @@ def __init__(self): sage: NN = InfiniteEnumeratedSets().example() sage: NN - An example of an infinite enumerated set: the non negative integers + An example of an infinite enumerated set: the nonnegative integers sage: NN.category() Category of infinite enumerated sets sage: TestSuite(NN).run() @@ -97,9 +97,9 @@ def _repr_(self): TESTS:: sage: InfiniteEnumeratedSets().example() # indirect doctest - An example of an infinite enumerated set: the non negative integers + An example of an infinite enumerated set: the nonnegative integers """ - return "An example of an infinite enumerated set: the non negative integers" + return "An example of an infinite enumerated set: the nonnegative integers" def __contains__(self, elt): """ @@ -139,11 +139,11 @@ def __call__(self, elt): sage: NN(-1) Traceback (most recent call last): ... - ValueError: Value -1 is not a non negative integer. + ValueError: Value -1 is not a nonnegative integer. """ if elt in self: return self._element_constructor_(elt) - raise ValueError("Value %s is not a non negative integer." % (elt)) + raise ValueError("Value %s is not a nonnegative integer." % (elt)) def an_element(self): """ diff --git a/src/sage/categories/examples/lie_algebras.py b/src/sage/categories/examples/lie_algebras.py index b8a3f9c8e21..ac70705f41f 100644 --- a/src/sage/categories/examples/lie_algebras.py +++ b/src/sage/categories/examples/lie_algebras.py @@ -216,7 +216,7 @@ def __hash__(self): def __bool__(self) -> bool: """ - Check non-zero. + Check nonzero. EXAMPLES:: diff --git a/src/sage/categories/examples/magmas.py b/src/sage/categories/examples/magmas.py index 538929c70a0..c11248b7d80 100644 --- a/src/sage/categories/examples/magmas.py +++ b/src/sage/categories/examples/magmas.py @@ -56,7 +56,7 @@ def __init__(self, alphabet=('a', 'b', 'c', 'd')): INPUT: - - ``alphabet`` -- a tuple of strings; the generators of the magma + - ``alphabet`` -- tuple of strings; the generators of the magma EXAMPLES:: @@ -136,7 +136,7 @@ def _element_constructor_(self, x): INPUT: - - ``x`` -- a string + - ``x`` -- string EXAMPLES:: diff --git a/src/sage/categories/examples/meson.build b/src/sage/categories/examples/meson.build new file mode 100644 index 00000000000..ecb63c913ba --- /dev/null +++ b/src/sage/categories/examples/meson.build @@ -0,0 +1,49 @@ +py.install_sources( + 'algebras_with_basis.py', + 'all.py', + 'commutative_additive_monoids.py', + 'commutative_additive_semigroups.py', + 'coxeter_groups.py', + 'crystals.py', + 'cw_complexes.py', + 'facade_sets.py', + 'filtered_algebras_with_basis.py', + 'filtered_modules_with_basis.py', + 'finite_coxeter_groups.py', + 'finite_dimensional_algebras_with_basis.py', + 'finite_dimensional_lie_algebras_with_basis.py', + 'finite_enumerated_sets.py', + 'finite_monoids.py', + 'finite_semigroups.py', + 'finite_weyl_groups.py', + 'graded_connected_hopf_algebras_with_basis.py', + 'graded_modules_with_basis.py', + 'graphs.py', + 'hopf_algebras_with_basis.py', + 'infinite_enumerated_sets.py', + 'lie_algebras.py', + 'lie_algebras_with_basis.py', + 'magmas.py', + 'manifolds.py', + 'monoids.py', + 'posets.py', + 'semigroups.py', + 'sets_cat.py', + 'sets_with_grading.py', + 'with_realizations.py', + subdir: 'sage/categories/examples', +) + +extension_data = {'semigroups_cython' : files('semigroups_cython.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/categories/examples', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/categories/examples/monoids.py b/src/sage/categories/examples/monoids.py index 27da0cf418c..cbeaea058c5 100644 --- a/src/sage/categories/examples/monoids.py +++ b/src/sage/categories/examples/monoids.py @@ -19,7 +19,7 @@ class FreeMonoid(FreeSemigroup): r""" - An example of a monoid: the free monoid + An example of a monoid: the free monoid. This class illustrates a minimal implementation of a monoid. For a full featured implementation of free monoids, see :func:`FreeMonoid`. @@ -78,11 +78,11 @@ class FreeMonoid(FreeSemigroup): def __init__(self, alphabet=('a','b','c','d')): r""" - The free monoid + The free monoid. INPUT: - - ``alphabet`` -- a tuple of strings: the generators of the monoid + - ``alphabet`` -- tuple of strings; the generators of the monoid EXAMPLES:: @@ -92,7 +92,6 @@ def __init__(self, alphabet=('a','b','c','d')): TESTS:: sage: TestSuite(M).run() - """ self.alphabet = alphabet Parent.__init__(self, category=Monoids()) @@ -104,14 +103,13 @@ def _repr_(self): sage: M = Monoids().example(alphabet=('a','b','c')) sage: M._repr_() "An example of a monoid: the free monoid generated by ('a', 'b', 'c')" - """ return "An example of a monoid: the free monoid generated by %s" % (self.alphabet,) @cached_method def one(self): r""" - Returns the one of the monoid, as per :meth:`Monoids.ParentMethods.one`. + Return the one of the monoid, as per :meth:`Monoids.ParentMethods.one`. EXAMPLES:: @@ -119,7 +117,6 @@ def one(self): An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') sage: M.one() '' - """ return self("") diff --git a/src/sage/categories/examples/posets.py b/src/sage/categories/examples/posets.py index 639ec9c6bc8..9e67b294fee 100644 --- a/src/sage/categories/examples/posets.py +++ b/src/sage/categories/examples/posets.py @@ -19,7 +19,7 @@ class FiniteSetsOrderedByInclusion(UniqueRepresentation, Parent): r""" - An example of a poset: finite sets ordered by inclusion + An example of a poset: finite sets ordered by inclusion. This class provides a minimal implementation of a poset @@ -80,7 +80,7 @@ def _repr_(self): def le(self, x, y): r""" - Returns whether `x` is a subset of `y` + Return whether `x` is a subset of `y`. EXAMPLES:: @@ -96,7 +96,7 @@ def le(self, x, y): def an_element(self): r""" - Returns an element of this poset + Return an element of this poset. EXAMPLES:: @@ -113,7 +113,7 @@ class Element(ElementWrapper): class PositiveIntegersOrderedByDivisibilityFacade(UniqueRepresentation, Parent): r""" - An example of a facade poset: the positive integers ordered by divisibility + An example of a facade poset: the positive integers ordered by divisibility. This class provides a minimal implementation of a facade poset @@ -163,7 +163,7 @@ def _repr_(self): def le(self, x, y): r""" - Returns whether `x` is divisible by `y` + Return whether `x` is divisible by `y`. EXAMPLES:: diff --git a/src/sage/categories/examples/semigroups.py b/src/sage/categories/examples/semigroups.py index 6aceee5fe13..49b5bd164f6 100644 --- a/src/sage/categories/examples/semigroups.py +++ b/src/sage/categories/examples/semigroups.py @@ -70,7 +70,7 @@ class LeftZeroSemigroup(UniqueRepresentation, Parent): """ def __init__(self): r""" - The left zero semigroup + The left zero semigroup. EXAMPLES:: @@ -85,18 +85,16 @@ def __init__(self): def _repr_(self): r""" - EXAMPLES:: sage: Semigroups().example()._repr_() 'An example of a semigroup: the left zero semigroup' - """ return "An example of a semigroup: the left zero semigroup" def product(self, x, y): r""" - Returns the product of ``x`` and ``y`` in the semigroup, as per + Return the product of ``x`` and ``y`` in the semigroup, as per :meth:`Semigroups.ParentMethods.product`. EXAMPLES:: @@ -106,7 +104,6 @@ def product(self, x, y): 'hello' sage: S(3)*S(1)*S(2) 3 - """ assert x in self assert y in self @@ -114,25 +111,23 @@ def product(self, x, y): def an_element(self): r""" - Returns an element of the semigroup. + Return an element of the semigroup. EXAMPLES:: sage: Semigroups().example().an_element() 42 - """ return self(42) def some_elements(self): r""" - Returns a list of some elements of the semigroup. + Return a list of some elements of the semigroup. EXAMPLES:: sage: Semigroups().example().some_elements() [3, 42, 'a', 3.4, 'raton laveur'] - """ return [self(i) for i in [3, 42, "a", 3.4, "raton laveur"]] @@ -149,7 +144,6 @@ def is_idempotent(self): True sage: S(17).is_idempotent() True - """ return True @@ -186,7 +180,7 @@ def __init__(self, alphabet=('a','b','c','d')): INPUT: - - ``alphabet`` -- a tuple of strings: the generators of the semigroup + - ``alphabet`` -- tuple of strings; the generators of the semigroup EXAMPLES:: @@ -209,13 +203,12 @@ def _repr_(self): sage: from sage.categories.examples.semigroups import FreeSemigroup sage: FreeSemigroup(('a','b','c'))._repr_() "An example of a semigroup: the free semigroup generated by ('a', 'b', 'c')" - """ return "An example of a semigroup: the free semigroup generated by %s" % (self.alphabet,) def product(self, x, y): r""" - Returns the product of ``x`` and ``y`` in the semigroup, as per + Return the product of ``x`` and ``y`` in the semigroup, as per :meth:`Semigroups.ParentMethods.product`. EXAMPLES:: @@ -223,7 +216,6 @@ def product(self, x, y): sage: F = Semigroups().example('free') sage: F.an_element() * F('a')^5 'abcdaaaaa' - """ assert x in self assert y in self @@ -232,27 +224,25 @@ def product(self, x, y): @cached_method def semigroup_generators(self): r""" - Returns the generators of the semigroup. + Return the generators of the semigroup. EXAMPLES:: sage: F = Semigroups().example('free') sage: F.semigroup_generators() Family ('a', 'b', 'c', 'd') - """ return Family([self(i) for i in self.alphabet]) def an_element(self): r""" - Returns an element of the semigroup. + Return an element of the semigroup. EXAMPLES:: sage: F = Semigroups().example('free') sage: F.an_element() 'abcd' - """ return self(''.join(self.alphabet)) @@ -262,7 +252,7 @@ def _element_constructor_(self, x): INPUT: - - ``x`` -- a string + - ``x`` -- string EXAMPLES:: @@ -288,7 +278,6 @@ def _element_constructor_(self, x): sage: S = Semigroups().Subquotients().example() sage: type(S._element_constructor_(17)) - """ for a in x: assert a in self.alphabet @@ -303,7 +292,7 @@ class Element(ElementWrapper): class QuotientOfLeftZeroSemigroup(UniqueRepresentation, Parent): r""" - Example of a quotient semigroup + Example of a quotient semigroup. EXAMPLES:: @@ -368,7 +357,6 @@ def _element_constructor_(self, x): sage: S = Semigroups().Subquotients().example() sage: type(S._element_constructor_(17)) - """ return self.retract(self.ambient()(x)) @@ -405,20 +393,18 @@ def _repr_(self): sage: Semigroups().Subquotients().example()._repr_() 'An example of a (sub)quotient semigroup: a quotient of the left zero semigroup' - """ return "An example of a (sub)quotient semigroup: a quotient of the left zero semigroup" def ambient(self): r""" - Returns the ambient semigroup. + Return the ambient semigroup. EXAMPLES:: sage: S = Semigroups().Subquotients().example() sage: S.ambient() An example of a semigroup: the left zero semigroup - """ return Semigroups().example() @@ -428,7 +414,7 @@ def lift(self, x): INPUT: - - ``x`` -- an element of ``self``. + - ``x`` -- an element of ``self`` OUTPUT: @@ -447,14 +433,13 @@ def lift(self, x): 100 sage: S.lift(S(y)) 42 - """ assert x in self return x.value def the_answer(self): r""" - Returns the Answer to Life, the Universe, and Everything as an + Return the Answer to Life, the Universe, and Everything as an element of this semigroup. EXAMPLES:: @@ -462,48 +447,43 @@ def the_answer(self): sage: S = Semigroups().Subquotients().example() sage: S.the_answer() 42 - """ return self.retract(self.ambient()(42)) def an_element(self): r""" - Returns an element of the semigroup. + Return an element of the semigroup. EXAMPLES:: sage: S = Semigroups().Subquotients().example() sage: S.an_element() 42 - """ return self.the_answer() def some_elements(self): r""" - Returns a list of some elements of the semigroup. + Return a list of some elements of the semigroup. EXAMPLES:: sage: S = Semigroups().Subquotients().example() sage: S.some_elements() [1, 2, 3, 8, 42, 42] - """ return [self.retract(self.ambient()(i)) for i in [1, 2, 3, 8, 42, 100]] def retract(self, x): r""" - Returns the retract ``x`` onto an element of this semigroup. + Return the retract ``x`` onto an element of this semigroup. INPUT: - - ``x`` -- an element of the ambient semigroup (``self.ambient()``). - - OUTPUT: + - ``x`` -- an element of the ambient semigroup (``self.ambient()``) - - an element of ``self``. + OUTPUT: an element of ``self`` EXAMPLES:: @@ -520,7 +500,6 @@ def retract(self, x): sage: S.retract(L(171)) in S True - """ from sage.rings.integer_ring import ZZ assert x in self.ambient() and x.value in ZZ @@ -535,7 +514,7 @@ class Element(ElementWrapper): class IncompleteSubquotientSemigroup(UniqueRepresentation,Parent): def __init__(self, category=None): r""" - An incompletely implemented subquotient semigroup, for testing purposes + An incompletely implemented subquotient semigroup, for testing purposes. EXAMPLES:: @@ -587,14 +566,13 @@ def __init__(self, category=None): def ambient(self): r""" - Returns the ambient semigroup. + Return the ambient semigroup. EXAMPLES:: sage: S = Semigroups().Subquotients().example() sage: S.ambient() An example of a semigroup: the left zero semigroup - """ return Semigroups().example() diff --git a/src/sage/categories/examples/semigroups_cython.pyx b/src/sage/categories/examples/semigroups_cython.pyx index 4f7a6990586..3c7f28777f5 100644 --- a/src/sage/categories/examples/semigroups_cython.pyx +++ b/src/sage/categories/examples/semigroups_cython.pyx @@ -128,7 +128,7 @@ cdef class LeftZeroSemigroupElement(Element): class LeftZeroSemigroup(LeftZeroSemigroupPython): r""" - An example of semigroup + An example of semigroup. This class illustrates a minimal implementation of a semi-group where the element class is an extension type, and still gets code diff --git a/src/sage/categories/examples/sets_cat.py b/src/sage/categories/examples/sets_cat.py index 30d63ec9c73..003a4b04a5f 100644 --- a/src/sage/categories/examples/sets_cat.py +++ b/src/sage/categories/examples/sets_cat.py @@ -106,7 +106,7 @@ def _repr_(self): def an_element(self): """ - Implements :meth:`Sets.ParentMethods.an_element`. + Implement :meth:`Sets.ParentMethods.an_element`. TESTS:: @@ -186,7 +186,7 @@ def _repr_(self): def an_element(self): """ - Implements :meth:`Sets.ParentMethods.an_element`. + Implement :meth:`Sets.ParentMethods.an_element`. TESTS:: @@ -200,7 +200,7 @@ def an_element(self): def _element_constructor_(self, i): """ - Constructs an element of self from an integer, testing that + Construct an element of ``self`` from an integer, testing that this integer is indeed prime. EXAMPLES:: @@ -221,7 +221,7 @@ def _element_constructor_(self, i): @abstract_method def _from_integer_(self, i): """ - Fast construction of an element of self from an integer. + Fast construction of an element of ``self`` from an integer. No prime checking is performed. To be defined. diff --git a/src/sage/categories/examples/with_realizations.py b/src/sage/categories/examples/with_realizations.py index 4a4896026e7..b3b27d87d2f 100644 --- a/src/sage/categories/examples/with_realizations.py +++ b/src/sage/categories/examples/with_realizations.py @@ -25,7 +25,7 @@ class SubsetAlgebra(UniqueRepresentation, Parent): r""" - An example of parent endowed with several realizations + An example of parent endowed with several realizations. We consider an algebra `A(S)` whose bases are indexed by the subsets `s` of a given set `S`. We consider three natural basis of @@ -121,7 +121,6 @@ class SubsetAlgebra(UniqueRepresentation, Parent): sage: (1 + Out[1]) * In[2,3] Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}] - """ def __init__(self, R, S): @@ -202,7 +201,7 @@ def __init__(self, R, S): def a_realization(self): r""" - Returns the default realization of ``self`` + Return the default realization of ``self``. EXAMPLES:: @@ -257,7 +256,7 @@ def indices_key(self, x): def supsets(self, set): r""" - Returns all the subsets of `S` containing ``set`` + Return all the subsets of `S` containing ``set``. INPUT: @@ -363,7 +362,7 @@ def _repr_(self): @cached_method def one(self): r""" - Returns the unit of this algebra. + Return the unit of this algebra. This default implementation takes the unit in the fundamental basis, and coerces it in ``self``. @@ -382,7 +381,7 @@ def one(self): class Fundamental(CombinatorialFreeModule, BindableClass): r""" - The Subset algebra, in the fundamental basis + The Subset algebra, in the fundamental basis. INPUT: @@ -436,7 +435,7 @@ def product_on_basis(self, left, right): def one_basis(self): r""" - Returns the index of the basis element which is equal to '1'. + Return the index of the basis element which is equal to '1'. EXAMPLES:: @@ -458,7 +457,7 @@ def one_basis(self): class In(CombinatorialFreeModule, BindableClass): r""" - The Subset Algebra, in the ``In`` basis + The Subset Algebra, in the ``In`` basis. INPUT: @@ -501,7 +500,7 @@ def __init__(self, A): class Out(CombinatorialFreeModule, BindableClass): r""" - The Subset Algebra, in the `Out` basis + The Subset Algebra, in the `Out` basis. INPUT: diff --git a/src/sage/categories/facade_sets.py b/src/sage/categories/facade_sets.py index ecb32a25835..e832068fa97 100644 --- a/src/sage/categories/facade_sets.py +++ b/src/sage/categories/facade_sets.py @@ -17,13 +17,13 @@ class FacadeSets(CategoryWithAxiom): def example(self, choice='subset'): r""" - Returns an example of facade set, as per + Return an example of facade set, as per :meth:`Category.example() `. INPUT: - - ``choice`` -- 'union' or 'subset' (default: 'subset'). + - ``choice`` -- 'union' or 'subset' (default: ``'subset'``) EXAMPLES:: @@ -46,14 +46,14 @@ class ParentMethods: def _element_constructor_(self, element): """ - Coerce ``element`` into ``self`` + Coerce ``element`` into ``self``. INPUT: - ``element`` -- any object This default implementation returns ``element`` if - ``self`` is a facade for ``parent(element)`. Otherwise it + ``self`` is a facade for ``parent(element)``. Otherwise it attempts in turn to coerce ``element`` into each parent ``self`` is a facade for. @@ -106,12 +106,12 @@ def _element_constructor_(self, element): def facade_for(self): """ - Returns the parents this set is a facade for + Return the parents this set is a facade for. This default implementation assumes that ``self`` has an attribute ``_facade_for``, typically initialized by :meth:`Parent.__init__`. If the attribute is not present, the method - raises a NotImplementedError. + raises a :exc:`NotImplementedError`. EXAMPLES:: @@ -138,7 +138,7 @@ def facade_for(self): def is_parent_of(self, element): """ - Returns whether ``self`` is the parent of ``element`` + Return whether ``self`` is the parent of ``element``. INPUT: @@ -183,7 +183,7 @@ def is_parent_of(self, element): def __contains__(self, element): """ - Membership testing + Membership testing. Returns whether ``element`` is in one of the parents ``self`` is a facade for. @@ -212,7 +212,7 @@ def _an_element_(self): For each parent ``self`` is a facade for, this default implementation tries the method ``an_element`` until it finds an element in ``self``. If none is found, this raises a - :class:`NotImplementedError`. + :exc:`NotImplementedError`. EXAMPLES:: diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 1a069f4d5e9..dafa795f94f 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -27,7 +27,7 @@ class Fields(CategoryWithAxiom): """ The category of (commutative) fields, i.e. commutative rings where - all non-zero elements have multiplicative inverses + all nonzero elements have multiplicative inverses EXAMPLES:: @@ -125,7 +125,6 @@ def __contains__(self, x): sage: len([X for X in gc.get_objects() ....: if isinstance(X, sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic)]) - n 0 - """ from sage.rings.ring import _is_Field try: @@ -160,13 +159,12 @@ def _contains_helper(cls): True sage: F._contains_helper(Q) True - """ return Category_contains_method_by_parent_class(cls()) def _call_(self, x): """ - Construct a field from the data in ``x`` + Construct a field from the data in ``x``. EXAMPLES:: @@ -197,7 +195,7 @@ class ParentMethods: def is_field( self, proof=True ): r""" - Returns True as ``self`` is a field. + Return ``True`` as ``self`` is a field. EXAMPLES:: @@ -413,7 +411,6 @@ def is_perfect(self): True sage: FunctionField(GF(2), 'x').is_perfect() False - """ if self.characteristic() == 0: return True @@ -452,7 +449,7 @@ def _test_characteristic_fields(self, **options): def fraction_field(self): r""" - Returns the *fraction field* of ``self``, which is ``self``. + Return the *fraction field* of ``self``, which is ``self``. EXAMPLES:: @@ -470,7 +467,7 @@ def _squarefree_decomposition_univariate_polynomial(self, f): INPUT: - - ``f`` -- a univariate non-zero polynomial over this field + - ``f`` -- a univariate nonzero polynomial over this field ALGORITHM: For rings of characteristic zero, we use the algorithm described in [Yun1976]_. Other fields may provide their own @@ -520,7 +517,7 @@ def _squarefree_decomposition_univariate_polynomial(self, f): def vector_space(self, *args, **kwds): r""" - Gives an isomorphism of this field with a vector space over a subfield. + Give an isomorphism of this field with a vector space over a subfield. This method is an alias for ``free_module``, which may have more documentation. @@ -553,7 +550,7 @@ def vector_space(self, *args, **kwds): class ElementMethods: def euclidean_degree(self): r""" - Return the degree of this element as an element of an Euclidean + Return the degree of this element as an element of a Euclidean domain. In a field, this returns 0 for all but the zero element (for @@ -590,7 +587,7 @@ def quo_rem(self, other): def is_unit( self ): r""" - Returns True if ``self`` has a multiplicative inverse. + Return ``True`` if ``self`` has a multiplicative inverse. EXAMPLES:: @@ -749,7 +746,7 @@ def xgcd(self, other): sage: GF(5)(0).xgcd(GF(5)(0)) (0, 0, 0) - The xgcd of non-zero floating point numbers will be a triple of + The xgcd of nonzero floating point numbers will be a triple of floating points. But if the input are two integral floating points the result is a floating point version of the standard gcd on `\ZZ`:: @@ -814,7 +811,7 @@ def inverse_of_unit(self): 1/2 Trying to invert the zero element typically raises a - :class:`ZeroDivisionError`:: + :exc:`ZeroDivisionError`:: sage: QQ(0).inverse_of_unit() Traceback (most recent call last): diff --git a/src/sage/categories/filtered_algebras_with_basis.py b/src/sage/categories/filtered_algebras_with_basis.py index 068aa37e52e..98795bdd08a 100644 --- a/src/sage/categories/filtered_algebras_with_basis.py +++ b/src/sage/categories/filtered_algebras_with_basis.py @@ -241,9 +241,7 @@ def induced_graded_map(self, other, f): - ``f`` -- a filtration-preserving linear map from ``self`` to ``other`` (can be given as a morphism or as a function) - OUTPUT: - - The graded linear map `\operatorname{gr} f`. + OUTPUT: the graded linear map `\operatorname{gr} f` EXAMPLES: diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index cb1df2f0bba..454f31e5070 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -159,7 +159,7 @@ def basis(self, d=None): over Integer Ring(i))_{i in Partitions} Checking this method on a filtered algebra. Note that this - will typically raise a :class:`NotImplementedError` when this + will typically raise a :exc:`NotImplementedError` when this feature is not implemented. :: sage: A = AlgebrasWithBasis(ZZ).Filtered().example() @@ -481,9 +481,7 @@ def induced_graded_map(self, other, f): - ``f`` -- a filtration-preserving linear map from ``self`` to ``other`` (can be given as a morphism or as a function) - OUTPUT: - - The graded linear map `\operatorname{gr} f`. + OUTPUT: the graded linear map `\operatorname{gr} f` EXAMPLES: diff --git a/src/sage/categories/finite_complex_reflection_groups.py b/src/sage/categories/finite_complex_reflection_groups.py index 20f03360322..c834ccbef21 100644 --- a/src/sage/categories/finite_complex_reflection_groups.py +++ b/src/sage/categories/finite_complex_reflection_groups.py @@ -731,8 +731,8 @@ def reflection_length(self, in_unitary_group=False): INPUT: - - ``in_unitary_group`` -- (default: ``False``) if ``True``, - the reflection length is computed in the unitary group + - ``in_unitary_group`` -- boolean (default: ``False``); if + ``True``, the reflection length is computed in the unitary group which is the dimension of the move space of ``self`` EXAMPLES:: @@ -838,14 +838,14 @@ def absolute_order_ideal(self, gens=None, Otherwise, the standard Coxeter element is used as unique maximal element. - - ``in_unitary_group`` (default:``True``) determines the + - ``in_unitary_group`` -- (default: ``True``) determines the length function used to compute the order. For real groups, both possible orders coincide, and for complex non-real groups, the order in the unitary group is much faster to compute. - - ``return_lengths`` (default:``False``) whether or not - to also return the lengths of the elements. + - ``return_lengths`` -- (default: ``False``) whether or not + to also return the lengths of the elements EXAMPLES:: @@ -920,8 +920,8 @@ def noncrossing_partition_lattice(self, c=None, L=None, of ``self`` is given, it is used as the underlying set (only cover relations are checked). - - ``in_unitary_group`` -- (default: ``False``) if ``False``, the - relation is given by `\sigma \leq \tau` if + - ``in_unitary_group`` -- boolean (default: ``False``); if + ``False``, the relation is given by `\sigma \leq \tau` if `l_R(\sigma) + l_R(\sigma^{-1}\tau) = l_R(\tau)`; if ``True``, the relation is given by `\sigma \leq \tau` if `\dim(\mathrm{Fix}(\sigma)) + \dim(\mathrm{Fix}(\sigma^{-1}\tau)) @@ -980,7 +980,7 @@ def noncrossing_partition_lattice(self, c=None, L=None, def generalized_noncrossing_partitions(self, m, c=None, positive=False): r""" - Return the set of all chains of length ``m`` in the + Return the set of all chains of length `m` in the noncrossing partition lattice of ``self``, see :meth:`noncrossing_partition_lattice`. @@ -990,11 +990,12 @@ def generalized_noncrossing_partitions(self, m, c=None, positive=False): INPUT: - - ``c`` -- (default: ``None``) if an element ``c`` in ``self`` + - ``c`` -- (default: ``None``) if an element `c` in ``self`` is given, it is used as the maximal element in the interval - - ``positive`` -- (default: ``False``) if ``True``, only those - generalized noncrossing partitions of full support are returned + - ``positive`` -- boolean (default: ``False``); if ``True``, + only those generalized noncrossing partitions of full support + are returned EXAMPLES:: @@ -1067,8 +1068,8 @@ def absolute_poset(self, in_unitary_group=False): INPUT: - - ``in_unitary_group`` -- (default: ``False``) if ``False``, - the relation is given by ``\sigma \leq \tau`` if + - ``in_unitary_group`` -- boolean (default: ``False``); if + ``False``, the relation is given by ``\sigma \leq \tau`` if `l_R(\sigma) + l_R(\sigma^{-1}\tau) = l_R(\tau)` If ``True``, the relation is given by `\sigma \leq \tau` if `\dim(\mathrm{Fix}(\sigma)) + \dim(\mathrm{Fix}(\sigma^{-1}\tau)) @@ -1332,7 +1333,7 @@ def rational_catalan_number(self, p, polynomial=False): INPUT: - - ``polynomial`` -- optional boolean (default ``False``) + - ``polynomial`` -- boolean (default: ``False``); if ``True``, return instead the `q`-analogue as a polynomial in `q` @@ -1388,12 +1389,11 @@ def fuss_catalan_number(self, m, positive=False, INPUT: - - ``positive`` -- optional boolean (default ``False``) - if ``True``, return instead the positive Fuss-Catalan - number - - ``polynomial`` -- optional boolean (default ``False``) - if ``True``, return instead the `q`-analogue as a - polynomial in `q` + - ``positive`` -- boolean (default: ``False``); if + ``True``, return instead the positive Fuss-Catalan number + - ``polynomial`` -- boolean (default: ``False``); if + ``True``, return instead the `q`-analogue as a polynomial + in `q` See [Ar2006]_ for further information. @@ -1465,12 +1465,11 @@ def catalan_number(self, positive=False, polynomial=False): INPUT: - - ``positive`` -- optional boolean (default ``False``) - if ``True``, return instead the positive Catalan - number - - ``polynomial`` -- optional boolean (default ``False``) - if ``True``, return instead the `q`-analogue as a - polynomial in `q` + - ``positive`` -- boolean (default: ``False``); if + ``True``, return instead the positive Catalan number + - ``polynomial`` -- boolean (default: ``False``); if + ``True``, return instead the `q`-analogue as a polynomial + in `q` .. NOTE:: diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index 2095783728b..2df5d054dd0 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -113,8 +113,8 @@ def long_element(self, index_set=None, as_word=False): - ``index_set`` -- a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: all of them) - - ``as_word`` -- boolean (default ``False``). If ``True``, then - return instead a reduced decomposition of the longest element. + - ``as_word`` -- boolean (default: ``False``); if ``True``, then + return instead a reduced decomposition of the longest element Should this method be called maximal_element? longest_element? @@ -274,7 +274,7 @@ def bhz_poset(self): was defined in [BHZ2005]_. This partial order is not a lattice, as there is no unique - maximal element. It can be succintly defined as follows. + maximal element. It can be succinctly defined as follows. Let `u` and `v` be two elements of the Coxeter group `W`. Let `S(u)` be the support of `u`. Then `u \leq v` if and only @@ -394,12 +394,12 @@ def codegrees(self): return tuple(d - 2 for d in self.degrees()) @cached_method - def weak_poset(self, side="right", facade=False): + def weak_poset(self, side='right', facade=False): """ INPUT: - - ``side`` -- "left", "right", or "twosided" (default: "right") - - ``facade`` -- a boolean (default: ``False``) + - ``side`` -- "left", "right", or "twosided" (default: ``'right'``) + - ``facade`` -- boolean (default: ``False``) Returns the left (resp. right) poset for weak order. In this poset, `u` is smaller than `v` if some reduced word @@ -479,7 +479,7 @@ def weak_poset(self, side="right", facade=False): from sage.combinat.posets.posets import Poset from sage.combinat.posets.lattices import LatticePoset if side == "twosided": - covers = tuple([u, v] for u in self for v in u.upper_covers(side="left") + u.upper_covers(side="right")) + covers = tuple([u, v] for u in self for v in u.upper_covers(side='left') + u.upper_covers(side='right')) return Poset((self, covers), cover_relations=True, facade=facade) covers = tuple([u, v] for u in self for v in u.upper_covers(side=side)) @@ -499,7 +499,7 @@ def inversion_sequence(self, word): INPUT: - ``word`` -- a word in the indices of the simple - generators of ``self``. + generators of ``self`` EXAMPLES:: @@ -511,7 +511,6 @@ def inversion_sequence(self, word): sage: [t.reduced_word() for t in CoxeterGroup(["A",3]).inversion_sequence([2,1,3,2,1,3])] [[2], [1, 2, 1], [2, 3, 2], [1, 2, 3, 2, 1], [3], [1]] - """ return [self.from_reduced_word(word[:i+1]+list(reversed(word[:i]))) for i in range(len(word))] @@ -552,12 +551,12 @@ def m_cambrian_lattice(self, c, m=1, on_roots=False): INPUT: - - `c` -- a Coxeter element of ``self`` (as a tuple, or + - ``c`` -- a Coxeter element of ``self`` (as a tuple, or as an element of ``self``) - - `m` -- a positive integer (default: 1) + - ``m`` -- positive integer (default: 1) - - ``on_roots`` (default: ``False``) -- if + - ``on_roots`` -- boolean (default: ``False``); if ``on_roots`` is ``True``, the lattice is realized on roots rather than on reflections. In order for this to work, the ElementMethod ``reflection_to_root`` must be @@ -637,14 +636,14 @@ def cambrian_lattice(self, c, on_roots=False): See :arxiv:`1503.00710` and :arxiv:`math/0611106`. Delta sequences are certain 2-colored minimal factorizations - of ``c`` into reflections. + of `c` into reflections. INPUT: - ``c`` -- a standard Coxeter element in ``self`` (as a tuple, or as an element of ``self``) - - ``on_roots`` (default: ``False``) -- if + - ``on_roots`` -- boolean (default: ``False``); if ``on_roots`` is ``True``, the lattice is realized on roots rather than on reflections. In order for this to work, the ElementMethod ``reflection_to_root`` must be @@ -678,7 +677,7 @@ def is_real(self): def permutahedron(self, point=None, base_ring=None): r""" - Return the permutahedron of ``self``, + Return the permutahedron of ``self``. This is the convex hull of the point ``point`` in the weight basis under the action of ``self`` on the underlying vector @@ -690,9 +689,9 @@ def permutahedron(self, point=None, base_ring=None): INPUT: - - ``point`` -- optional, a point given by its coordinates in - the weight basis (default is `(1, 1, 1, \ldots)`) - - ``base_ring`` -- optional, the base ring of the polytope + - ``point`` -- (optional) a point given by its coordinates in + the weight basis (default: `(1, 1, 1, \ldots)`) + - ``base_ring`` -- (optional) the base ring of the polytope .. NOTE:: @@ -741,7 +740,6 @@ def permutahedron(self, point=None, base_ring=None): W = CoxeterGroup(['I',7]) p = W.permutahedron() sphinx_plot(p) - """ n = self.one().canonical_matrix().rank() weights = self.fundamental_weights() @@ -801,7 +799,7 @@ def coxeter_poset(self): 3 sage: # optional - gap3 - sage: W = CoxeterGroup(['H', 3], implementation="permutation") + sage: W = CoxeterGroup(['H', 3], implementation='permutation') sage: P = W.coxeter_poset() sage: P Finite meet-semilattice containing 363 elements @@ -874,7 +872,7 @@ def coxeter_complex(self): {0: 0, 1: 0, 2: Z} sage: # optional - gap3 - sage: W = CoxeterGroup(['H', 3], implementation="permutation") + sage: W = CoxeterGroup(['H', 3], implementation='permutation') sage: C = W.coxeter_complex() sage: C Simplicial complex with 62 vertices and 120 facets @@ -943,7 +941,7 @@ def absolute_length(self): @cached_in_parent_method def bruhat_upper_covers(self): r""" - Returns all the elements that cover ``self`` in Bruhat order. + Return all the elements that cover ``self`` in Bruhat order. EXAMPLES:: diff --git a/src/sage/categories/finite_crystals.py b/src/sage/categories/finite_crystals.py index 97fd31c1968..d1a436f4d6c 100644 --- a/src/sage/categories/finite_crystals.py +++ b/src/sage/categories/finite_crystals.py @@ -76,7 +76,7 @@ def extra_super_categories(self): def example(self, n=3): """ - Returns an example of highest weight crystals, as per + Return an example of highest weight crystals, as per :meth:`Category.example`. EXAMPLES:: diff --git a/src/sage/categories/finite_dimensional_algebras_with_basis.py b/src/sage/categories/finite_dimensional_algebras_with_basis.py index 4df8a265f06..f4a31b557f9 100644 --- a/src/sage/categories/finite_dimensional_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_algebras_with_basis.py @@ -74,9 +74,7 @@ def radical_basis(self): characteristic `p` in which we can compute `x^{1/p}` [FR1985]_, [Eb1989]_. - OUTPUT: - - - a list of elements of ``self``. + OUTPUT: list of elements of ``self`` .. SEEALSO:: :meth:`radical`, :class:`Algebras.Semisimple` @@ -147,6 +145,7 @@ def radical_basis(self): We compute the radical basis in a subalgebra using the inherited product:: + sage: # needs sage.modules sage: scoeffs = {('a','e'): {'a':1}, ('b','e'): {'a':1, 'b':1}, ....: ('c','d'): {'a':1}, ('c','e'): {'c':1}} sage: L. = LieAlgebra(QQ, scoeffs) @@ -157,14 +156,14 @@ def radical_basis(self): TESTS:: - sage: A = KleinFourGroup().algebra(GF(2)) # needs sage.groups sage.modules - sage: A.radical_basis() # needs sage.groups sage.modules + sage: # needs sage.groups sage.modules + sage: A = KleinFourGroup().algebra(GF(2)) + sage: A.radical_basis() (() + (1,2)(3,4), (3,4) + (1,2)(3,4), (1,2) + (1,2)(3,4)) - - sage: A = KleinFourGroup().algebra(QQ, category=Monoids()) # needs sage.groups sage.modules - sage: A.radical_basis.__module__ # needs sage.groups sage.modules + sage: A = KleinFourGroup().algebra(QQ, category=Monoids()) + sage: A.radical_basis.__module__ 'sage.categories.finite_dimensional_algebras_with_basis' - sage: A.radical_basis() # needs sage.groups sage.modules + sage: A.radical_basis() () """ F = self.base_ring() @@ -348,9 +347,7 @@ def center_basis(self): r""" Return a basis of the center of ``self``. - OUTPUT: - - - a list of elements of ``self``. + OUTPUT: list of elements of ``self`` .. SEEALSO:: :meth:`center` @@ -425,6 +422,7 @@ def subalgebra(self, gens, category=None, *args, **opts): EXAMPLES:: + sage: # needs sage.modules sage: scoeffs = {('a','e'): {'a':1}, ('b','e'): {'a':1, 'b':1}, ....: ('c','d'): {'a':1}, ('c','e'): {'c':1}} sage: L. = LieAlgebra(QQ, scoeffs) @@ -433,6 +431,7 @@ def subalgebra(self, gens, category=None, *args, **opts): sage: A.dimension() 7 + sage: # needs sage.modules sage: L. = LieAlgebra(GF(3), {('x','z'): {'x':1, 'y':1}, ('y','z'): {'y':1}}) sage: MS = MatrixSpace(L.base_ring(), L.dimension()) sage: gens = [b.adjoint_matrix() for b in L.basis()] @@ -477,6 +476,7 @@ def ideal_submodule(self, gens, side='left', category=None, *args, **opts): EXAMPLES:: + sage: # needs sage.modules sage: scoeffs = {('a','e'): {'a':1}, ('b','e'): {'a':1, 'b':1}, ....: ('c','d'): {'a':1}, ('c','e'): {'c':1}} sage: L. = LieAlgebra(QQ, scoeffs) @@ -656,7 +656,7 @@ def idempotent_lift(self, x): INPUT: - - `x` -- an element of `A` that projects on an idempotent + - ``x`` -- an element of `A` that projects on an idempotent `\overline x` of the semisimple quotient of `A`. Alternatively one may give as input the idempotent `\overline{x}`, in which case some lift thereof will be @@ -703,7 +703,7 @@ def cartan_invariants_matrix(self): r""" Return the Cartan invariants matrix of the algebra. - OUTPUT: a matrix of non negative integers + OUTPUT: a matrix of nonnegative integers Let `A` be this finite dimensional algebra and `(S_i)_{i\in I}` be representatives of the right simple @@ -718,7 +718,7 @@ def cartan_invariants_matrix(self): `S_i=\operatorname{top} P^R_i`. The *Cartan invariant matrix* `(C_{i,j})_{i,j\in I}` is a - matrix of non negative integers that encodes much of the + matrix of nonnegative integers that encodes much of the representation theory of `A`; namely: - `C_{i,j}` counts how many times `S_i^*\otimes S_j` @@ -851,9 +851,9 @@ def isotypic_projective_modules(self, side='left'): INPUT: - - ``side`` -- 'left' or 'right' (default: 'left') + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``) - OUTPUT: a list of subspaces of ``self``. + OUTPUT: list of subspaces of ``self`` EXAMPLES:: @@ -862,7 +862,7 @@ def isotypic_projective_modules(self, side='left'): An example of a finite dimensional algebra with basis: the path algebra of the Kronecker quiver (containing the arrows a:x->y and b:x->y) over Rational Field - sage: Q = A.isotypic_projective_modules(side="left"); Q + sage: Q = A.isotypic_projective_modules(side='left'); Q [Free module generated by {0} over Rational Field, Free module generated by {0, 1, 2} over Rational Field] sage: [[x.lift() for x in Qi.basis()] @@ -895,7 +895,7 @@ def peirce_summand(self, ei, ej): - ``ei``, ``ej`` -- two idempotents of `A` - OUTPUT: `e_i A e_j`, as a subspace of `A`. + OUTPUT: `e_i A e_j`, as a subspace of `A` .. SEEALSO:: @@ -963,13 +963,13 @@ def peirce_decomposition(self, idempotents=None, check=True): INPUT: - - ``idempotents`` -- a list of orthogonal idempotents + - ``idempotents`` -- list of orthogonal idempotents `(e_i)_{i=0,\ldots,n}` of the algebra that sum to `1` (default: the idempotents returned by :meth:`orthogonal_idempotents_central_mod_radical`) - - ``check`` -- (default: ``True``) whether to check that the - idempotents are indeed orthogonal and idempotent and + - ``check`` -- boolean (default: ``True``); whether to check that + the idempotents are indeed orthogonal and idempotent and sum to `1` OUTPUT: @@ -1039,7 +1039,7 @@ def is_identity_decomposition_into_orthogonal_idempotents(self, l): INPUT: - - ``l`` -- a list or iterable of elements of ``self`` + - ``l`` -- list or iterable of elements of ``self`` EXAMPLES:: @@ -1175,7 +1175,7 @@ def to_matrix(self, base_ring=None, action=operator.mul, side='left'): - ``base_ring`` -- the base ring for the matrix to be constructed - ``action`` -- a bivariate function (default: :func:`operator.mul`) - - ``side`` -- 'left' or 'right' (default: 'left') + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``) EXAMPLES:: @@ -1196,7 +1196,7 @@ def to_matrix(self, base_ring=None, action=operator.mul, side='left'): [0 1 0 0 0 0] [0 0 0 0 0 1] [0 0 0 0 1 0] - sage: a.to_matrix(base_ring=RDF, side="left") + sage: a.to_matrix(base_ring=RDF, side='left') [0.0 0.0 1.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0 1.0 0.0] [1.0 0.0 0.0 0.0 0.0 0.0] @@ -1541,18 +1541,21 @@ def simple_module_parameterization(self): EXAMPLES:: + sage: # needs sage.modules sage: TL = TemperleyLiebAlgebra(5, 30, QQ) # semisimple sage: len(TL.radical_basis()) 0 sage: TL.simple_module_parameterization() (1, 3, 5) + sage: # needs sage.modules sage: TL = TemperleyLiebAlgebra(5, 1, QQ) # not semisimple sage: len(TL.radical_basis()) 24 sage: TL.simple_module_parameterization() (1, 3, 5) + sage: # needs sage.modules sage: TL = TemperleyLiebAlgebra(6, 30, QQ) # semisimple sage: all(TL.cell_module(la).dimension() ....: == TL.cell_module(la).simple_module().dimension() @@ -1561,6 +1564,7 @@ def simple_module_parameterization(self): sage: TL.simple_module_parameterization() (0, 2, 4, 6) + sage: # needs sage.modules sage: TL = TemperleyLiebAlgebra(6, 0, QQ) # not semisimple sage: TL.simple_module_parameterization() (2, 4, 6) diff --git a/src/sage/categories/finite_dimensional_bialgebras_with_basis.py b/src/sage/categories/finite_dimensional_bialgebras_with_basis.py index 321d98568e3..c0e25dec7fe 100644 --- a/src/sage/categories/finite_dimensional_bialgebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_bialgebras_with_basis.py @@ -13,7 +13,7 @@ def FiniteDimensionalBialgebrasWithBasis(base_ring): """ - The category of finite dimensional bialgebras with a distinguished basis + The category of finite dimensional bialgebras with a distinguished basis. EXAMPLES:: diff --git a/src/sage/categories/finite_dimensional_coalgebras_with_basis.py b/src/sage/categories/finite_dimensional_coalgebras_with_basis.py index 520177b0e8f..489d943f75c 100644 --- a/src/sage/categories/finite_dimensional_coalgebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_coalgebras_with_basis.py @@ -13,7 +13,7 @@ def FiniteDimensionalCoalgebrasWithBasis(base_ring): """ - The category of finite dimensional coalgebras with a distinguished basis + The category of finite dimensional coalgebras with a distinguished basis. EXAMPLES:: diff --git a/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py index fa53cb36ed2..fccea88f2fb 100644 --- a/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py @@ -48,11 +48,11 @@ class FiniteDimensionalGradedLieAlgebrasWithBasis(CategoryWithAxiom_over_base_ri class ParentMethods: def _test_grading(self, **options): r""" - Tests that the Lie bracket respects the grading. + Test that the Lie bracket respects the grading. INPUT: - - ``options`` -- any keyword arguments accepted by :meth:`_tester`. + - ``options`` -- any keyword arguments accepted by :meth:`_tester` EXAMPLES:: @@ -138,7 +138,7 @@ class Stratified(CategoryWithAxiom_over_base_ring): class ParentMethods: def _test_generated_by_degree_one(self, **options): r""" - Tests that the Lie algebra is generated by the homogeneous + Test that the Lie algebra is generated by the homogeneous component of degree one. INPUT: diff --git a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py index 39363f5fb18..6f27e3fa33d 100644 --- a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py @@ -378,8 +378,8 @@ def structure_coefficients(self, include_zeros=False): INPUT: - - ``include_zeros`` -- (default: ``False``) if ``True``, then - include the `[x, y] = 0` pairs in the output + - ``include_zeros`` -- boolean (default: ``False``); if ``True``, + then include the `[x, y] = 0` pairs in the output OUTPUT: @@ -1007,7 +1007,7 @@ def subalgebra(self, *gens, **kwds): INPUT: - - ``gens`` -- a list of generators of the subalgebra + - ``gens`` -- list of generators of the subalgebra - ``category`` -- (optional) a subcategory of subobjects of finite dimensional Lie algebras with basis @@ -1048,7 +1048,7 @@ def ideal(self, *gens, **kwds): INPUT: - - ``gens`` -- a list of generators of the ideal + - ``gens`` -- list of generators of the ideal - ``category`` -- (optional) a subcategory of subobjects of finite dimensional Lie algebras with basis @@ -1131,7 +1131,7 @@ def quotient(self, I, names=None, category=None): INPUT: - ``I`` -- an ideal or a list of generators of the ideal - - ``names`` -- (optional) a string or a list of strings; + - ``names`` -- (optional) string or list of strings; names for the basis elements of the quotient. If ``names`` is a string, the basis will be named ``names_1``,...,``names_n``. @@ -1179,8 +1179,8 @@ def product_space(self, L, submodule=False): INPUT: - ``L`` -- a Lie subalgebra of ``self`` - - ``submodule`` -- (default: ``False``) if ``True``, then the - result is forced to be a submodule of ``self`` + - ``submodule`` -- boolean (default: ``False``); if ``True``, then + the result is forced to be a submodule of ``self`` EXAMPLES:: @@ -1359,8 +1359,8 @@ def lower_central_series(self, submodule=False): INPUT: - - ``submodule`` -- (default: ``False``) if ``True``, then the - result is given as submodules of ``self`` + - ``submodule`` -- boolean (default: ``False``); if ``True``, then + the result is given as submodules of ``self`` We define the lower central series of a Lie algebra `\mathfrak{g}` recursively by `\mathfrak{g}_0 := \mathfrak{g}` and @@ -1638,9 +1638,9 @@ def chevalley_eilenberg_complex(self, M=None, dual=False, sparse=True, ncpus=Non are matrices representing a Lie algebra homomorphism defining the representation - - ``dual`` -- (default: ``False``) if ``True``, causes + - ``dual`` -- boolean (default: ``False``); if ``True``, causes the dual of the complex to be computed - - ``sparse`` -- (default: ``True``) whether to use sparse + - ``sparse`` -- boolean (default: ``True``); whether to use sparse or dense matrices - ``ncpus`` -- (optional) how many cpus to use @@ -1877,7 +1877,7 @@ def homology(self, deg=None, M=None, sparse=True, ncpus=None): - ``deg`` -- the degree of the homology (optional) - ``M`` -- (default: the trivial module) a right module of ``self`` - - ``sparse`` -- (default: ``True``) whether to use sparse + - ``sparse`` -- boolean (default: ``True``); whether to use sparse matrices for the Chevalley-Eilenberg chain complex - ``ncpus`` -- (optional) how many cpus to use when computing the Chevalley-Eilenberg chain complex @@ -1945,7 +1945,7 @@ def cohomology(self, deg=None, M=None, sparse=True, ncpus=None): - ``deg`` -- the degree of the homology (optional) - ``M`` -- (default: the trivial module) a right module of ``self`` - - ``sparse`` -- (default: ``True``) whether to use sparse + - ``sparse`` -- boolean (default: ``True``); whether to use sparse matrices for the Chevalley-Eilenberg chain complex - ``ncpus`` -- (optional) how many cpus to use when computing the Chevalley-Eilenberg chain complex @@ -2041,7 +2041,7 @@ def morphism(self, on_generators, codomain=None, base_map=None, check=True): from the values of ``on_generators`` if not given - ``base_map`` -- a homomorphism from the base ring to something coercing into the codomain - - ``check`` -- (default: ``True``) boolean; if ``False`` the + - ``check`` -- boolean (default: ``True``); if ``False`` the values on the Lie brackets implied by ``on_generators`` will not be checked for contradictory values @@ -2234,11 +2234,12 @@ def casimir_element(self, order=2, UEA=None, force_generic=False, basis=False): - ``order`` -- (default: ``2``) the order of the Casimir element - ``UEA`` -- (optional) the universal enveloping algebra implementation to return the result in - - ``force_generic`` -- (default: ``False``) if ``True`` for the - quadratic order, then this uses the default algorithm; otherwise - this is ignored - - ``basis`` -- (default: ``False``) if ``True``, this returns a - basis of all Casimir elements of order ``order`` as a list + - ``force_generic`` -- boolean (default: ``False``); if ``True`` + for the quadratic order, then this uses the default algorithm + (otherwise this is ignored) + - ``basis`` -- boolean (default: ``False``); if ``True``, this + returns a basis of all Casimir elements of order ``order`` as a + list ALGORITHM: @@ -2429,7 +2430,7 @@ def faithful_representation(self, algorithm=None): General case - * ``'generic'`` -- generic algortihm (only implemented currently + * ``'generic'`` -- generic algorithm (only implemented currently for positive characteristic) Note that the algorithm for any more generic cases can be used @@ -2445,12 +2446,12 @@ def faithful_representation(self, algorithm=None): sage: F = H2.faithful_representation(); F Faithful 16 dimensional representation of Heisenberg algebra of rank 2 over Rational Field - sage: M = H2.faithful_representation(algorithm="minimal"); M + sage: M = H2.faithful_representation(algorithm='minimal'); M Minimal faithful representation of Heisenberg algebra of rank 2 over Rational Field sage: M.dimension() 4 - sage: H2.faithful_representation(algorithm="invalid") + sage: H2.faithful_representation(algorithm='invalid') Traceback (most recent call last): ... ValueError: invalid algorithm 'invalid' diff --git a/src/sage/categories/finite_dimensional_modules_with_basis.py b/src/sage/categories/finite_dimensional_modules_with_basis.py index c5566fc0f20..ee5b6490346 100644 --- a/src/sage/categories/finite_dimensional_modules_with_basis.py +++ b/src/sage/categories/finite_dimensional_modules_with_basis.py @@ -21,7 +21,7 @@ class FiniteDimensionalModulesWithBasis(CategoryWithAxiom_over_base_ring): """ - The category of finite dimensional modules with a distinguished basis + The category of finite dimensional modules with a distinguished basis. EXAMPLES:: @@ -44,9 +44,7 @@ def gens(self) -> tuple: """ Return the generators of ``self``. - OUTPUT: - - A tuple containing the basis elements of ``self``. + OUTPUT: a tuple containing the basis elements of ``self`` EXAMPLES:: @@ -66,7 +64,7 @@ def annihilator(self, S, action=operator.mul, side='right', category=None): - ``action`` -- a function (default: :obj:`operator.mul`) - - ``side`` -- 'left' or 'right' (default: 'right') + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - ``category`` -- a category @@ -121,10 +119,10 @@ def annihilator(self, S, action=operator.mul, side='right', category=None): Taking annihilator is order reversing for inclusion:: sage: # needs sage.modules - sage: A = F.annihilator([]); A .rename("A") - sage: Ax = F.annihilator([x]); Ax .rename("Ax") - sage: Ay = F.annihilator([y]); Ay .rename("Ay") - sage: Axy = F.annihilator([x,y]); Axy.rename("Axy") + sage: A = F.annihilator([]); A .rename('A') + sage: Ax = F.annihilator([x]); Ax .rename('Ax') + sage: Ay = F.annihilator([y]); Ay .rename('Ay') + sage: Axy = F.annihilator([x,y]); Axy.rename('Axy') sage: P = Poset(([A, Ax, Ay, Axy], attrcall("is_submodule"))) # needs sage.graphs sage: sorted(P.cover_relations(), key=str) # needs sage.graphs [[Ax, A], [Axy, Ax], [Axy, Ay], [Ay, A]] @@ -143,8 +141,8 @@ def annihilator_basis(self, S, action=operator.mul, side='right'): - ``action`` -- a function (default: :obj:`operator.mul`) - - ``side`` -- 'left' or 'right' (default: 'right'): - on which side of ``self`` the elements of `S` acts. + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``): + on which side of ``self`` the elements of `S` acts See :meth:`annihilator` for the assumptions and definition of the annihilator. @@ -198,15 +196,15 @@ def annihilator_basis(self, S, action=operator.mul, side='right'): roles of `x` and `y`:: sage: # needs sage.graphs sage.modules - sage: F.annihilator_basis([y], side="left") + sage: F.annihilator_basis([y], side='left') (x, a, b) - sage: F.annihilator_basis([a], side="left") + sage: F.annihilator_basis([a], side='left') (x, a, b) - sage: F.annihilator_basis([b], side="left") + sage: F.annihilator_basis([b], side='left') (x, a, b) - sage: F.annihilator_basis([x], side="left") + sage: F.annihilator_basis([x], side='left') (y,) - sage: F.annihilator_basis([a + 3*b + 2*x], side="left") + sage: F.annihilator_basis([a + 3*b + 2*x], side='left') (-1/2*a - 3/2*b + y,) By specifying an inner product, this method can be used to @@ -310,9 +308,9 @@ def echelon_form(self, elements, row_reduced=False, order=None): INPUT: - - ``elements`` -- a list or finite iterable of elements of ``self`` - - ``row_reduced`` -- (default: ``False``) whether to compute the - basis for the row reduced echelon form + - ``elements`` -- list or finite iterable of elements of ``self`` + - ``row_reduced`` -- boolean (default: ``False``); whether to + compute the basis for the row reduced echelon form - ``order`` -- (optional) either something that can be converted into a tuple or a key function @@ -325,7 +323,7 @@ def echelon_form(self, elements, row_reduced=False, order=None): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x') sage: x = X.basis() sage: V = X.echelon_form([x[0]-x[1], x[0]-x[2], x[1]-x[2]]); V [x[0] - x[2], x[1] - x[2]] @@ -394,7 +392,7 @@ def echelon_form(self, elements, row_reduced=False, order=None): return ret def invariant_module(self, S, action=operator.mul, action_on_basis=None, - side="left", **kwargs): + side='left', **kwargs): r""" Return the submodule of ``self`` invariant under the action of ``S``. @@ -415,9 +413,7 @@ def invariant_module(self, S, action=operator.mul, action_on_basis=None, - ``action_on_basis`` -- (optional) define the action of ``S`` on the basis of ``self`` - OUTPUT: - - - :class:`~sage.modules.with_basis.invariant.FiniteDimensionalInvariantModule` + OUTPUT: :class:`~sage.modules.with_basis.invariant.FiniteDimensionalInvariantModule` EXAMPLES: @@ -485,7 +481,7 @@ def twisted_invariant_module(self, G, chi, INPUT: - ``G`` -- a finitely-generated group - - ``chi`` -- a list/tuple of character values or an instance of + - ``chi`` -- list/tuple of character values or an instance of :class:`~sage.groups.class_function.ClassFunction_gap` - ``action`` -- a function (default: :obj:`operator.mul`) - ``action_on_basis`` -- (optional) define the action of ``g`` @@ -493,9 +489,7 @@ def twisted_invariant_module(self, G, chi, - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``); which side of ``self`` the elements of ``S`` acts - OUTPUT: - - - :class:`~sage.modules.with_basis.invariant.FiniteDimensionalTwistedInvariantModule` + OUTPUT: :class:`~sage.modules.with_basis.invariant.FiniteDimensionalTwistedInvariantModule` EXAMPLES:: @@ -576,7 +570,7 @@ def _vector_(self, order=None): coerce=True, copy=False) class MorphismMethods: - def matrix(self, base_ring=None, side="left"): + def matrix(self, base_ring=None, side='left'): r""" Return the matrix of this morphism in the distinguished bases of the domain and codomain. @@ -586,7 +580,7 @@ def matrix(self, base_ring=None, side="left"): - ``base_ring`` -- a ring (default: ``None``, meaning the base ring of the codomain) - - ``side`` -- "left" or "right" (default: "left") + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``) If ``side`` is "left", this morphism is considered as acting on the left; i.e. each column of the matrix @@ -609,7 +603,7 @@ def matrix(self, base_ring=None, side="left"): sage: phi.matrix() [1 2] [3 5] - sage: phi.matrix(side="right") + sage: phi.matrix(side='right') [1 3] [2 5] @@ -784,8 +778,8 @@ def __invert__(self): sage: # needs sage.modules sage: category = FiniteDimensionalModulesWithBasis(ZZ) - sage: X = CombinatorialFreeModule(ZZ, [1,2], category=category); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4], category=category); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(ZZ, [1,2], category=category); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(ZZ, [3,4], category=category); Y.rename('Y'); y = Y.basis() sage: phi = X.module_morphism(on_basis={1: y[3] + 3*y[4], 2: 2*y[3] + 5*y[4]}.__getitem__, ....: codomain=Y, category=category) sage: psi = ~phi @@ -1069,6 +1063,5 @@ def extra_super_categories(self): sage: C.FiniteDimensional() Category of tensor products of finite dimensional modules with basis over Integer Ring - """ return [self.base_category()] diff --git a/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py index ae3a38d9dda..0d6cfd0f3a8 100644 --- a/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py @@ -52,7 +52,7 @@ class ParentMethods: def _test_nilpotency(self, **options): r""" - Tests that ``self`` is nilpotent and has the correct step. + Test that ``self`` is nilpotent and has the correct step. INPUT: @@ -75,7 +75,7 @@ def _test_nilpotency(self, **options): sage: L._test_nilpotency() Traceback (most recent call last): ... - AssertionError: final term of lower central series is non-zero + AssertionError: final term of lower central series is nonzero See the documentation for :class:`TestSuite` for more information. """ @@ -83,7 +83,7 @@ def _test_nilpotency(self, **options): lcs = self.lower_central_series(submodule=True) tester.assertEqual(lcs[-1].dimension(), 0, - msg="final term of lower central series is non-zero") + msg="final term of lower central series is nonzero") step = self.step() tester.assertEqual(len(lcs) - 1, step, diff --git a/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py b/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py index 2057b5c38de..83c0d6d17d8 100644 --- a/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py @@ -18,7 +18,7 @@ class FiniteDimensionalSemisimpleAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): """ - The category of finite dimensional semisimple algebras with a distinguished basis + The category of finite dimensional semisimple algebras with a distinguished basis. EXAMPLES:: @@ -45,9 +45,9 @@ def radical_basis(self, **keywords): r""" Return a basis of the Jacobson radical of this algebra. - - ``keywords`` -- for compatibility; ignored. + - ``keywords`` -- for compatibility; ignored - OUTPUT: the empty list since this algebra is semisimple. + OUTPUT: the empty list since this algebra is semisimple EXAMPLES:: @@ -121,12 +121,10 @@ def _orthogonal_decomposition(self, generators=None): INPUT: - - ``generators`` -- a list of generators of + - ``generators`` -- list of generators of ``self`` (default: the basis of ``self``) - OUTPUT: - - A list of quasi-idempotent elements of ``self``. + OUTPUT: list of quasi-idempotent elements of ``self`` Each quasi-idempotent `e` spans a one dimensional (non unital) subalgebra of @@ -146,7 +144,7 @@ def _orthogonal_decomposition(self, generators=None): dimension 1 subalgebras. The algorithm is recursive and proceeds as follows: - 0. If `A` is of dimension 1, return a non zero + 0. If `A` is of dimension 1, return a nonzero element. 1. Otherwise: find one of the generators such @@ -217,9 +215,7 @@ def central_orthogonal_idempotents(self): of the identity into primitive orthogonal idempotents. - OUTPUT: - - A list of orthogonal idempotents of ``self``. + OUTPUT: list of orthogonal idempotents of ``self`` EXAMPLES:: diff --git a/src/sage/categories/finite_enumerated_sets.py b/src/sage/categories/finite_enumerated_sets.py index b3b9ede2deb..d3438e43d37 100644 --- a/src/sage/categories/finite_enumerated_sets.py +++ b/src/sage/categories/finite_enumerated_sets.py @@ -13,7 +13,7 @@ from sage.categories.enumerated_sets import EnumeratedSets from sage.categories.sets_cat import Sets from sage.categories.cartesian_product import CartesianProductsCategory -from sage.categories.isomorphic_objects import IsomorphicObjectsCategory +from sage.categories.isomorphic_objects import IsomorphicObjectsCategory from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import from sage.cpython.getattr import raw_getattr @@ -22,7 +22,7 @@ class FiniteEnumeratedSets(CategoryWithAxiom): """ - The category of finite enumerated sets + The category of finite enumerated sets. EXAMPLES:: @@ -116,7 +116,7 @@ def _cardinality_from_iterator(self, *ignored_args, **ignored_kwds): sage: from sage.categories.examples.finite_enumerated_sets import Example sage: class FreshExample(Example): pass - sage: C = FreshExample(); C.rename("FreshExample") + sage: C = FreshExample(); C.rename('FreshExample') sage: C.cardinality @@ -191,15 +191,15 @@ def _cardinality_from_list(self, *ignored_args, **ignored_kwds): return Integer(len(self.tuple())) def _unrank_from_list(self, r): - """ - The ``r``-th element of ``self`` + r""" + The `r`-th element of ``self``. INPUT: - - ``r`` -- an integer between ``0`` and ``n-1``, - where ``n`` is the cardinality of ``self``. + - ``r`` -- integer between `0` and `n-1`, + where `n` is the cardinality of ``self`` - OUTPUT: the ``r``-th element of ``self`` + OUTPUT: the `r`-th element of ``self`` This implementation of :meth:`unrank` uses the method :meth:`list` (which is cached). Reciprocally, calling @@ -310,7 +310,7 @@ def _list_from_iterator(self): sage: from sage.categories.examples.finite_enumerated_sets import Example sage: class FreshExample(Example): pass - sage: C = FreshExample(); C.rename("FreshExample") + sage: C = FreshExample(); C.rename('FreshExample') sage: C.list sage: C.unrank @@ -528,7 +528,7 @@ def _last_from_unrank(self): def _test_enumerated_set_iter_cardinality(self, **options): """ - Checks that the methods :meth:`.cardinality` and + Check that the methods :meth:`.cardinality` and :meth:`.__iter__` are consistent. Also checks that :meth:`.cardinality` returns an ``Integer``. @@ -609,7 +609,7 @@ class ParentMethods: def last(self): r""" - Return the last element + Return the last element. EXAMPLES:: @@ -678,12 +678,12 @@ def rank(self, x): def unrank(self, i): r""" - Return the ``i``-th element of this Cartesian product. + Return the `i`-th element of this Cartesian product. INPUT: - - ``i`` -- integer between ``0`` and ``n-1`` where - ``n`` is the cardinality of this set. + - ``i`` -- integer between `0` and `n-1` where + `n` is the cardinality of this set .. SEEALSO:: @@ -711,7 +711,7 @@ def unrank(self, i): from sage.rings.integer_ring import ZZ i = ZZ(i) if i < 0: - raise IndexError("i (={}) must be a non-negative integer") + raise IndexError("i (={}) must be a nonnegative integer") elt = [] for c in reversed(self.cartesian_factors()): card = c.cardinality() @@ -725,7 +725,7 @@ class IsomorphicObjects(IsomorphicObjectsCategory): def example(self): """ - Returns an example of isomorphic object of a finite + Return an example of isomorphic object of a finite enumerated set, as per :meth:`Category.example `. @@ -741,7 +741,7 @@ class ParentMethods: def cardinality(self): r""" - Returns the cardinality of ``self`` which is the same + Return the cardinality of ``self`` which is the same as that of the ambient set ``self`` is isomorphic to. EXAMPLES:: @@ -755,7 +755,7 @@ def cardinality(self): def __iter__(self): r""" - Returns an iterator over ``self``, using the bijection + Return an iterator over ``self``, using the bijection with the ambient space. EXAMPLES:: diff --git a/src/sage/categories/finite_groups.py b/src/sage/categories/finite_groups.py index 8ef8541bdbf..88cce2fbae0 100644 --- a/src/sage/categories/finite_groups.py +++ b/src/sage/categories/finite_groups.py @@ -81,7 +81,7 @@ def monoid_generators(self): def cardinality(self): """ - Returns the cardinality of ``self``, as per + Return the cardinality of ``self``, as per :meth:`EnumeratedSets.ParentMethods.cardinality`. This default implementation calls :meth:`.order` if @@ -152,7 +152,7 @@ def conjugacy_classes(self): This will eventually be a fall-back method for groups not defined over GAP. Right now, it just raises a - :class:`NotImplementedError`, until we include a non-GAP + :exc:`NotImplementedError`, until we include a non-GAP way of listing the conjugacy classes representatives. EXAMPLES:: diff --git a/src/sage/categories/finite_lattice_posets.py b/src/sage/categories/finite_lattice_posets.py index cb0e41a2ba8..3ad8c3e81fa 100644 --- a/src/sage/categories/finite_lattice_posets.py +++ b/src/sage/categories/finite_lattice_posets.py @@ -36,7 +36,6 @@ class FiniteLatticePosets(CategoryWithAxiom): sage: C is FiniteLatticePosets().Finite() True sage: TestSuite(C).run() - """ class ParentMethods: diff --git a/src/sage/categories/finite_monoids.py b/src/sage/categories/finite_monoids.py index f4211d81bd2..169477871bd 100644 --- a/src/sage/categories/finite_monoids.py +++ b/src/sage/categories/finite_monoids.py @@ -47,7 +47,7 @@ def nerve(self): a_1 * a_2 * \cdots * a_k - The 0th face of this is obtained by deleting `a_1`, and + The `0`-th face of this is obtained by deleting `a_1`, and the `k`-th face is obtained by deleting `a_k`. The other faces are obtained by multiplying elements: the 1st face is @@ -170,7 +170,7 @@ def rhodes_radical_congruence(self, base_ring=None): INPUT: - - ``base_ring`` (default: `\QQ`) a field + - ``base_ring`` -- (default: `\QQ`) a field OUTPUT: @@ -186,7 +186,7 @@ def rhodes_radical_congruence(self, base_ring=None): sage: # needs sage.combinat sage.groups sage.modules sage: from sage.monoids.hecke_monoid import HeckeMonoid sage: H3 = HeckeMonoid(SymmetricGroup(3)) - sage: H3.repr_element_method(style="reduced") + sage: H3.repr_element_method(style='reduced') sage: H3.rhodes_radical_congruence() [([1, 2], [2, 1]), ([1, 2], [1, 2, 1]), ([2, 1], [1, 2, 1])] diff --git a/src/sage/categories/finite_permutation_groups.py b/src/sage/categories/finite_permutation_groups.py index 476f8b4a200..28edb0a2d4d 100644 --- a/src/sage/categories/finite_permutation_groups.py +++ b/src/sage/categories/finite_permutation_groups.py @@ -78,7 +78,7 @@ class FinitePermutationGroups(CategoryWithAxiom): def example(self): """ - Returns an example of finite permutation group, as per + Return an example of finite permutation group, as per :meth:`Category.example`. EXAMPLES:: @@ -111,10 +111,10 @@ def cycle_index(self, parent=None): INPUT: - - ``self`` -- a permutation group `G` - - ``parent`` -- a free module with basis indexed by partitions, - or behave as such, with a ``term`` and ``sum`` method - (default: the symmetric functions over the rational field in the `p` basis) + - ``self`` -- a permutation group `G` + - ``parent`` -- a free module with basis indexed by partitions, + or behave as such, with a ``term`` and ``sum`` method + (default: the symmetric functions over the rational field in the `p` basis) The *cycle index* of a permutation group `G` (:wikipedia:`Cycle_index`) is a gadget counting the @@ -288,24 +288,25 @@ def profile_series(self, variable='z'): def profile(self, n, using_polya=True): r""" - Return the value in ``n`` of the profile of the group ``self``. + Return the value in `n` of the profile of the group ``self``. Optional argument ``using_polya`` allows to change the default method. INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - - ``using_polya`` (optional) -- a boolean: if ``True`` (default), the computation - uses Pólya enumeration (and all values of the profile are cached, so this - should be the method used in case several of them are needed); - if ``False``, uses the GAP interface to compute the orbit. + - ``using_polya`` -- boolean (default: ``True``); if ``True``, the + computation uses Pólya enumeration (and all values of the profile + are cached, so this should be the method used in case several of + them are needed); if ``False``, uses the GAP interface to compute + the orbit. OUTPUT: - - A nonnegative integer that is the number of orbits of ``n``-subsets + - A nonnegative integer that is the number of orbits of `n`-subsets under the action induced by ``self`` on the subsets of its domain - (i.e. the value of the profile of ``self`` in ``n``) + (i.e. the value of the profile of ``self`` in `n`) .. SEEALSO:: @@ -321,7 +322,6 @@ def profile(self, n, using_polya=True): sage: D8 = DihedralGroup(8) sage: D8.profile(4, using_polya=False) 8 - """ if using_polya: diff --git a/src/sage/categories/finite_posets.py b/src/sage/categories/finite_posets.py index c1a008d1c12..37369269cf2 100644 --- a/src/sage/categories/finite_posets.py +++ b/src/sage/categories/finite_posets.py @@ -44,7 +44,6 @@ class FinitePosets(CategoryWithAxiom): sage: C is Posets().Finite() True sage: TestSuite(C).run() - """ class ParentMethods: @@ -181,7 +180,7 @@ def is_poset_isomorphism(self, f, codomain): sage: B.is_poset_isomorphism(f, D) False - .. note:: since ``D`` and ``B`` are not facade posets, ``f`` is + .. NOTE:: since ``D`` and ``B`` are not facade posets, ``f`` is responsible for the conversions between integers and subsets to elements of ``D`` and ``B`` and back. @@ -229,7 +228,7 @@ def is_poset_morphism(self, f, codomain): sage: B.is_poset_morphism(f, D) True - .. note:: since ``D`` and ``B`` are not facade posets, ``f`` is responsible + .. NOTE:: since ``D`` and ``B`` are not facade posets, ``f`` is responsible for the conversions between integers and subsets to elements of ``D`` and ``B`` and back. @@ -265,7 +264,6 @@ def is_poset_morphism(self, f, codomain): Finite poset containing 0 elements sage: P.is_poset_morphism(f, P) True - """ for x in self: for y in self.upper_covers(x): @@ -287,9 +285,9 @@ def order_ideal_generators(self, ideal, direction='down'): of ``self``, as a list (or iterable); this should be an order ideal if ``direction`` is set to ``'down'``, and an order filter if ``direction`` is set to - ``'up'``. + ``'up'`` - ``direction`` -- ``'up'`` or ``'down'`` (default: - ``'down'``). + ``'down'``) The antichain of (minimal) generators of an order ideal `I` in a poset `P` is the set of all minimal elements of @@ -312,7 +310,7 @@ def order_ideal_generators(self, ideal, direction='down'): sage: sorted(sorted(p) for p in gen) [[1, 2], [2, 3]] - If ``direction`` is 'up', then this instead computes + If ``direction`` is ``'up'``, then this instead computes the minimal generators for an order filter:: sage: I = P.order_filter([Set([1,2]), Set([2,3]), Set([1])]) @@ -336,7 +334,7 @@ def order_ideal_generators(self, ideal, direction='down'): def order_filter_generators(self, filter): r""" - Generators for an order filter + Generators for an order filter. INPUT: @@ -386,7 +384,7 @@ def order_ideal_complement_generators(self, antichain, direction='up'): - ``antichain`` -- an antichain of ``self``, as a list (or iterable), or, more generally, generators of an order ideal (resp. order filter) - - ``direction`` -- 'up' or 'down' (default: 'up') + - ``direction`` -- ``'up'`` or ``'down'`` (default: ``'up'``) OUTPUT: @@ -406,13 +404,13 @@ def order_ideal_complement_generators(self, antichain, direction='up'): sage: P.order_ideal_complement_generators([1,2,3]) set() - sage: P.order_ideal_complement_generators([1], direction="down") + sage: P.order_ideal_complement_generators([1], direction='down') {2} - sage: P.order_ideal_complement_generators([3], direction="down") + sage: P.order_ideal_complement_generators([3], direction='down') {1, 2} - sage: P.order_ideal_complement_generators([1,2], direction="down") + sage: P.order_ideal_complement_generators([1,2], direction='down') set() - sage: P.order_ideal_complement_generators([1,2,3], direction="down") + sage: P.order_ideal_complement_generators([1,2,3], direction='down') set() .. WARNING:: @@ -452,9 +450,7 @@ def rowmotion(self, order_ideal): - ``order_ideal`` -- an order ideal of ``self``, as a set - OUTPUT: - - - the image of ``order_ideal`` under rowmotion, as a set again + OUTPUT: the image of ``order_ideal`` under rowmotion, as a set again EXAMPLES:: @@ -597,7 +593,7 @@ def birational_free_labelling(self, linear_extension=None, field of the labelling, because the latter will have indeterminates adjoined! - - ``reduced`` -- (default: ``False``) if set to + - ``reduced`` -- boolean (default: ``False``); if set to ``True``, the result will be the *reduced* birational free labelling, which differs from the regular one by having `0` and `1` both sent to `1` instead of `a` and @@ -608,7 +604,7 @@ def birational_free_labelling(self, linear_extension=None, names of extra variables to be adjoined to the ground field (these don't have an effect on the labels) - - ``labels`` -- (default: ``'x'``) Either a function + - ``labels`` -- (default: ``'x'``) either a function that takes an element of the poset and returns a name for the indeterminate corresponding to that element, or a string containing a comma-separated list of @@ -666,7 +662,7 @@ def birational_free_labelling(self, linear_extension=None, [(1, x1), (2, x3), (3, x2)] sage: l = P.birational_free_labelling(linear_extension=[1, 3, 2], - ....: prefix="wut", reduced=True, + ....: prefix='wut', reduced=True, ....: addvars="spam, eggs"); l (Fraction Field of Multivariate Polynomial Ring in wut1, wut2, wut3, spam, eggs over Rational Field, @@ -703,7 +699,7 @@ def birational_free_labelling(self, linear_extension=None, sage: P = posets.ChainPoset(2).product(posets.ChainPoset(2)) # needs sage.modules sage: l = P.birational_free_labelling(labels=x_label, - ....: min_label="lambda", max_label="mu") + ....: min_label='lambda', max_label='mu') sage: sorted(l[1].items()) [((0, 0), x_00), ((0, 1), x_01), ((1, 0), x_10), ((1, 1), x_11)] sage: l[2] @@ -747,7 +743,7 @@ def birational_free_labelling(self, linear_extension=None, sage: P = posets.SSTPoset([2,1]) sage: lext = sorted(P) sage: l = P.birational_free_labelling(linear_extension=lext, - ....: addvars="ohai"); l + ....: addvars='ohai'); l (Fraction Field of Multivariate Polynomial Ring in a, x1, x2, x3, x4, x5, x6, x7, x8, b, ohai over Rational Field, {...}, @@ -773,7 +769,7 @@ def birational_free_labelling(self, linear_extension=None, Finite lattice containing 6 elements sage: lex = [(1,0),(0,0),(1,1),(0,1),(1,2),(0,2)] sage: l = P.birational_free_labelling(linear_extension=lex, - ....: prefix="u", reduced=True) + ....: prefix='u', reduced=True) sage: l (Fraction Field of Multivariate Polynomial Ring in u1, u2, u3, u4, u5, u6 over Rational Field, {...}, @@ -790,7 +786,7 @@ def birational_free_labelling(self, linear_extension=None, For comparison, the standard linear extension:: sage: # needs sage.modules - sage: l = P.birational_free_labelling(prefix="u", reduced=True); l + sage: l = P.birational_free_labelling(prefix='u', reduced=True); l (Fraction Field of Multivariate Polynomial Ring in u1, u2, u3, u4, u5, u6 over Rational Field, {...}, 1, @@ -810,7 +806,7 @@ def birational_free_labelling(self, linear_extension=None, sage: # needs sage.modules sage: lex = [(0,0),(0,1),(1,0),(1,1),(0,2),(1,2)] sage: l = P.birational_free_labelling(linear_extension=P.linear_extension(lex), - ....: prefix="u", reduced=True) + ....: prefix='u', reduced=True) sage: l (Fraction Field of Multivariate Polynomial Ring in u1, u2, u3, u4, u5, u6 over Rational Field, {...}, @@ -829,7 +825,7 @@ def birational_free_labelling(self, linear_extension=None, sage: P = Poset({1: [3], 2: [3,4]}) sage: lex = [1, 2, 4, 3] sage: l = P.birational_free_labelling(linear_extension=lex, - ....: prefix="aaa", + ....: prefix='aaa', ....: base_field=Zmod(13)) sage: l (Fraction Field of Multivariate Polynomial Ring in a, aaa1, aaa2, aaa3, aaa4, b over Ring of integers modulo 13, @@ -857,12 +853,12 @@ def birational_free_labelling(self, linear_extension=None, {}, 1, 1) - sage: P.birational_free_labelling(prefix="zzz") + sage: P.birational_free_labelling(prefix='zzz') (Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field, {}, a, b) - sage: P.birational_free_labelling(labels="x,y,z", min_label="spam", max_label="eggs") + sage: P.birational_free_labelling(labels='x,y,z', min_label='spam', max_label='eggs') (Fraction Field of Multivariate Polynomial Ring in spam, eggs over Rational Field, {}, spam, @@ -933,7 +929,7 @@ def birational_toggle(self, v, labelling): encoded to be understood by Sage. This implementation allows `\mathbf{K}` to be a semifield, not just a field. The birational `v`-toggle is only a rational map, so an exception (most - likely, :class:`ZeroDivisionError`) will be thrown if the + likely, :exc:`ZeroDivisionError`) will be thrown if the denominator is zero. INPUT: @@ -1154,7 +1150,7 @@ def birational_toggles(self, vs, labelling): encoded to be understood by Sage. This implementation allows `\mathbf{K}` to be a semifield, not just a field. The birational `v`-toggle is only a rational map, so an exception (most - likely, :class:`ZeroDivisionError`) will be thrown if the + likely, :exc:`ZeroDivisionError`) will be thrown if the denominator is zero. INPUT: @@ -1233,7 +1229,7 @@ def birational_rowmotion(self, labelling): by Sage. This implementation allows `\mathbf{K}` to be a semifield, not just a field. Birational rowmotion is only a rational map, so an exception (most likely, - :class:`ZeroDivisionError`) will be thrown if the + :exc:`ZeroDivisionError`) will be thrown if the denominator is zero. INPUT: @@ -1364,10 +1360,10 @@ def panyushev_orbits(self, element_constructor=set): INPUT: - - ``element_constructor`` (defaults to ``set``) -- a type + - ``element_constructor`` -- (default: ``set``) a type constructor (``set``, ``tuple``, ``list``, ``frozenset``, ``iter``, etc.) which is to be applied to the antichains - before they are returned. + before they are returned OUTPUT: @@ -1426,10 +1422,10 @@ def rowmotion_orbits(self, element_constructor=set): INPUT: - - ``element_constructor`` (defaults to ``set``) -- a type + - ``element_constructor`` -- (default: ``set``) a type constructor (``set``, ``tuple``, ``list``, ``frozenset``, ``iter``, etc.) which is to be applied to the antichains - before they are returned. + before they are returned OUTPUT: @@ -1477,15 +1473,13 @@ def rowmotion_orbits_plots(self): sage: P = Poset({}) sage: P.rowmotion_orbits_plots() Graphics Array of size 1 x 1 - """ from sage.plot.plot import graphics_array plot_of_orb_plots = [] max_orbit_size = 0 for orb in self.rowmotion_orbits(): orb_plots = [] - if len(orb) > max_orbit_size: - max_orbit_size = len(orb) + max_orbit_size = max(len(orb), max_orbit_size) for oi in orb: oiplot = self.order_ideal_plot(oi) orb_plots.append(oiplot) @@ -1512,15 +1506,15 @@ def toggling_orbits(self, vs, element_constructor=set): INPUT: - - ``vs``: a list (or other iterable) of elements of ``self`` + - ``vs`` -- a list (or other iterable) of elements of ``self`` (but since the output depends on the order, sets should not be used as ``vs``). OUTPUT: - - a partition of the order ideals of ``self``, as a list of - sets ``L`` such that for each ``L`` and ``i``, cyclically: - ``self.order_ideal_toggles(L[i], vs) == L[i+1]``. + A partition of the order ideals of ``self``, as a list of + sets ``L`` such that for each ``L`` and ``i``, cyclically: + ``self.order_ideal_toggles(L[i], vs) == L[i+1]``. EXAMPLES:: @@ -1564,15 +1558,13 @@ def toggling_orbits_plots(self, vs): sage: P = Poset({}) sage: P.toggling_orbits_plots([]) Graphics Array of size 1 x 1 - """ from sage.plot.plot import graphics_array plot_of_orb_plots = [] max_orbit_size = 0 for orb in self.toggling_orbits(vs): orb_plots = [] - if len(orb) > max_orbit_size: - max_orbit_size = len(orb) + max_orbit_size = max(len(orb), max_orbit_size) for oi in orb: oiplot = self.order_ideal_plot(oi) orb_plots.append(oiplot) @@ -1592,21 +1584,19 @@ def panyushev_orbit_iter(self, antichain, element_constructor=set, INPUT: - ``antichain`` -- an antichain of ``self``, given as an - iterable. + iterable - - ``element_constructor`` (defaults to ``set``) -- a type - constructor (``set``, ``tuple``, ``list``, ``frozenset``, - ``iter``, etc.) which is to be applied to the antichains - before they are yielded. + - ``element_constructor`` -- a type constructor (default: ``set``). + Can be ``set``, ``tuple``, ``list``, ``frozenset``, ``iter``, + etc. To be applied to the antichains before they are yielded. - - ``stop`` -- a Boolean (default: ``True``) determining - whether the iterator should stop once it completes its - cycle (this happens when it is set to ``True``) or go on - forever (this happens when it is set to ``False``). + - ``stop`` -- boolean (default: ``True``); whether the iterator + should stop once it completes its cycle (this happens when it is + set to ``True``) or go on forever (this happens when it is set to + ``False``). - - ``check`` -- a Boolean (default: ``True``) determining - whether ``antichain`` should be checked for being an - antichain. + - ``check`` -- boolean (default: ``True``); whether to check + ``antichain`` for being an antichain OUTPUT: @@ -1682,21 +1672,21 @@ def rowmotion_orbit_iter(self, oideal, element_constructor=set, stop=True, check INPUT: - ``oideal`` -- an order ideal of ``self``, given as an - iterable. + iterable - - ``element_constructor`` (defaults to ``set``) -- a type + - ``element_constructor`` -- (defaults to ``set``) a type constructor (``set``, ``tuple``, ``list``, ``frozenset``, ``iter``, etc.) which is to be applied to the order - ideals before they are yielded. + ideals before they are yielded - - ``stop`` -- a Boolean (default: ``True``) determining + - ``stop`` -- boolean (default: ``True``); whether the iterator should stop once it completes its cycle (this happens when it is set to ``True``) or go on - forever (this happens when it is set to ``False``). + forever (this happens when it is set to ``False``) - - ``check`` -- a Boolean (default: ``True``) determining + - ``check`` -- boolean (default: ``True``); whether ``oideal`` should be checked for being an - order ideal. + order ideal OUTPUT: @@ -1786,24 +1776,24 @@ def toggling_orbit_iter(self, vs, oideal, element_constructor=set, stop=True, ch INPUT: - - ``vs``: a list (or other iterable) of elements of ``self`` + - ``vs`` -- list (or other iterable) of elements of ``self`` (but since the output depends on the order, sets should not be used as ``vs``). - ``oideal`` -- an order ideal of ``self``, given as an - iterable. + iterable - - ``element_constructor`` (defaults to ``set``) -- a type + - ``element_constructor`` -- (default: ``set``) a type constructor (``set``, ``tuple``, ``list``, ``frozenset``, ``iter``, etc.) which is to be applied to the order ideals before they are yielded. - - ``stop`` -- a Boolean (default: ``True``) determining + - ``stop`` -- boolean (default: ``True``); whether the iterator should stop once it completes its cycle (this happens when it is set to ``True``) or go on forever (this happens when it is set to ``False``). - - ``check`` -- a Boolean (default: ``True``) determining + - ``check`` -- boolean (default: ``True``); whether ``oideal`` should be checked for being an order ideal. @@ -1898,10 +1888,10 @@ def order_ideals_lattice(self, as_ideals=True, facade=None): INPUT: - - ``as_ideals`` -- Boolean, if ``True`` (default) returns + - ``as_ideals`` -- boolean (default: ``True``); if ``True`` returns a poset on the set of order ideals, otherwise on the set of antichains - - ``facade`` -- Boolean or ``None`` (default). Whether to + - ``facade`` -- boolean or ``None`` (default); whether to return a facade lattice or not. By default return facade lattice if the poset is a facade poset. @@ -1978,13 +1968,13 @@ def directed_subsets(self, direction): r""" Return the order filters (resp. order ideals) of ``self``, as lists. - If ``direction`` is 'up', returns the order filters (upper sets). + If ``direction`` is ``'up'``, returns the order filters (upper sets). - If ``direction`` is 'down', returns the order ideals (lower sets). + If ``direction`` is ``'down'``, returns the order ideals (lower sets). INPUT: - - ``direction`` -- 'up' or 'down' + - ``direction`` -- ``'up'`` or ``'down'`` EXAMPLES:: diff --git a/src/sage/categories/finite_semigroups.py b/src/sage/categories/finite_semigroups.py index b699e33c9ab..831da9308bc 100644 --- a/src/sage/categories/finite_semigroups.py +++ b/src/sage/categories/finite_semigroups.py @@ -63,7 +63,7 @@ class FiniteSemigroups(CategoryWithAxiom): class ParentMethods: def idempotents(self): r""" - Returns the idempotents of the semigroup + Return the idempotents of the semigroup. EXAMPLES:: @@ -76,7 +76,7 @@ def idempotents(self): @cached_method def j_classes(self): r""" - Returns the `J`-classes of the semigroup. + Return the `J`-classes of the semigroup. Two elements `u` and `v` of a monoid are in the same `J`-class if `u` divides `v` and `v` divides `u`. @@ -92,16 +92,14 @@ def j_classes(self): [['a'], ['ab', 'ba'], ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'], ['ac', 'ca'], ['b'], ['bc', 'cb'], ['c']] """ - return self.cayley_graph(side="twosided", simple=True).strongly_connected_components() + return self.cayley_graph(side='twosided', simple=True).strongly_connected_components() @cached_method def j_classes_of_idempotents(self): r""" - Returns all the idempotents of self, grouped by J-class. + Return all the idempotents of self, grouped by J-class. - OUTPUT: - - a list of lists. + OUTPUT: list of lists EXAMPLES:: @@ -115,7 +113,7 @@ def j_classes_of_idempotents(self): @cached_method def j_transversal_of_idempotents(self): r""" - Returns a list of one idempotent per regular J-class + Return a list of one idempotent per regular J-class. EXAMPLES:: diff --git a/src/sage/categories/finitely_generated_semigroups.py b/src/sage/categories/finitely_generated_semigroups.py index b3e2a46f3a4..1b3189970d8 100644 --- a/src/sage/categories/finitely_generated_semigroups.py +++ b/src/sage/categories/finitely_generated_semigroups.py @@ -58,7 +58,6 @@ def extra_super_categories(self): sage: Semigroups().FinitelyGenerated().extra_super_categories() [Category of enumerated sets] - """ return [EnumeratedSets()] @@ -93,7 +92,7 @@ def semigroup_generators(self): # TODO: update transitive ideal - def succ_generators(self, side="twosided"): + def succ_generators(self, side='twosided'): r""" Return the successor function of the ``side``-sided Cayley graph of ``self``. @@ -105,7 +104,7 @@ def succ_generators(self, side="twosided"): INPUT: - - ``side``: "left", "right", or "twosided" + - ``side`` -- ``'left'``, ``'right'``, or ``'twosided'`` (default) .. TODO:: Design choice: @@ -121,7 +120,6 @@ def succ_generators(self, side="twosided"): ('ca', 'cab', 'ca', 'cad') sage: S.succ_generators("twosided" )(S('ca')) ('ac', 'bca', 'ca', 'dca', 'ca', 'cab', 'ca', 'cad') - """ left = (side == "left" or side == "twosided") right = (side == "right" or side == "twosided") @@ -146,10 +144,10 @@ def __iter__(self): """ from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet return iter(RecursivelyEnumeratedSet(self.semigroup_generators(), - self.succ_generators(side="right"), + self.succ_generators(side='right'), enumeration='breadth')) - def ideal(self, gens, side="twosided"): + def ideal(self, gens, side='twosided'): r""" Return the ``side``-sided ideal generated by ``gens``. @@ -161,21 +159,21 @@ def ideal(self, gens, side="twosided"): INPUT: - - ``gens`` -- a list (or iterable) of elements of ``self`` + - ``gens`` -- list (or iterable) of elements of ``self`` - ``side`` -- [default: "twosided"] "left", "right" or "twosided" EXAMPLES:: sage: S = FiniteSemigroups().example() - sage: sorted(S.ideal([S('cab')], side="left")) + sage: sorted(S.ideal([S('cab')], side='left')) ['abc', 'abcd', 'abdc', 'acb', 'acbd', 'acdb', 'adbc', 'adcb', 'bac', 'bacd', 'badc', 'bca', 'bcad', 'bcda', 'bdac', 'bdca', 'cab', 'cabd', 'cadb', 'cba', 'cbad', 'cbda', 'cdab', 'cdba', 'dabc', 'dacb', 'dbac', 'dbca', 'dcab', 'dcba'] - sage: list(S.ideal([S('cab')], side="right")) + sage: list(S.ideal([S('cab')], side='right')) ['cab', 'cabd'] - sage: sorted(S.ideal([S('cab')], side="twosided")) + sage: sorted(S.ideal([S('cab')], side='twosided')) ['abc', 'abcd', 'abdc', 'acb', 'acbd', 'acdb', 'adbc', 'adcb', 'bac', 'bacd', 'badc', 'bca', 'bcad', 'bcda', 'bdac', 'bdca', 'cab', 'cabd', 'cadb', 'cba', 'cbad', @@ -199,7 +197,7 @@ def some_elements(self): r""" Return an iterable containing some elements of the semigroup. - OUTPUT: the ten first elements of the semigroup, if they exist. + OUTPUT: the ten first elements of the semigroup, if they exist EXAMPLES:: diff --git a/src/sage/categories/function_fields.py b/src/sage/categories/function_fields.py index 649b5973af5..5207a9da3ad 100644 --- a/src/sage/categories/function_fields.py +++ b/src/sage/categories/function_fields.py @@ -36,7 +36,7 @@ class FunctionFields(Category): @cached_method def super_categories(self): """ - Returns the Category of which this is a direct sub-Category + Return the Category of which this is a direct sub-Category For a list off all super categories see all_super_categories EXAMPLES:: @@ -48,8 +48,8 @@ def super_categories(self): def _call_(self, x): r""" - Constructs an object in this category from the data in ``x``, - or throws a TypeError. + Construct an object in this category from the data in ``x``, + or throw a :exc:`TypeError`. EXAMPLES:: diff --git a/src/sage/categories/functor.pyx b/src/sage/categories/functor.pyx index 2ca369c2ef5..9b491ee0b94 100644 --- a/src/sage/categories/functor.pyx +++ b/src/sage/categories/functor.pyx @@ -52,7 +52,6 @@ def _Functor_unpickle(Cl, D, domain, codomain): True sage: F.domain(), loads(dumps(F)).domain() (Category of rings, Category of rings) - """ F = Functor.__new__(Cl) Functor.__init__(F, domain, codomain) @@ -63,7 +62,7 @@ def _Functor_unpickle(Cl, D, domain, codomain): cdef class Functor(SageObject): """ - A class for functors between two categories + A class for functors between two categories. NOTE: @@ -73,17 +72,15 @@ cdef class Functor(SageObject): Instead, one should implement three methods, which are composed in the default call method: - - ``_coerce_into_domain(self, x)``: Return an object of ``self``'s - domain, corresponding to ``x``, or raise a :class:`TypeError`. - - - Default: Raise :class:`TypeError` if ``x`` is not in ``self``'s domain. + - ``_coerce_into_domain(self, x)`` -- return an object of ``self``'s + domain, corresponding to ``x``, or raise a :exc:`TypeError`. + - Default: Raise :exc:`TypeError` if ``x`` is not in ``self``'s domain. - - ``_apply_functor(self, x)``: Apply ``self`` to an object ``x`` of + - ``_apply_functor(self, x)`` -- apply ``self`` to an object ``x`` of ``self``'s domain. - - Default: Conversion into ``self``'s codomain. - - ``_apply_functor_to_morphism(self, f)``: Apply ``self`` to a morphism + - ``_apply_functor_to_morphism(self, f)`` -- apply ``self`` to a morphism ``f`` in ``self``'s domain. - Default: Return ``self(f.domain()).hom(f,self(f.codomain()))``. @@ -163,7 +160,6 @@ cdef class Functor(SageObject): sage: F(f)(p) (-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t - 4*a^2 - 8*a*b - 4*b^2 - a - b + 1 - """ def __init__(self, domain, codomain): """ @@ -177,7 +173,6 @@ cdef class Functor(SageObject): Rational Field sage: F(GF(2)) Finite Field of size 2 - """ if not isinstance(domain, category.Category): raise TypeError("domain (=%s) must be a category" % domain) @@ -234,7 +229,6 @@ cdef class Functor(SageObject): sage: F = Functor(FiniteFields(), Fields()) sage: F._apply_functor(ZZ) Rational Field - """ return self.__codomain(x) @@ -277,16 +271,16 @@ cdef class Functor(SageObject): def _coerce_into_domain(self, x): """ - Interprete the argument as an object of self's domain. + Interpret the argument as an object of ``self``'s domain. NOTE: A subclass of :class:`Functor` may overload this method. It should - return an object of self's domain, and should raise a - :class:`TypeError` if this is impossible. + return an object of ``self``'s domain, and should raise a + :exc:`TypeError` if this is impossible. By default, the argument will not be changed, but a - :class:`TypeError` will be raised if the argument does not + :exc:`TypeError` will be raised if the argument does not belong to the domain. TESTS:: @@ -383,7 +377,6 @@ cdef class Functor(SageObject): TypeError: Functor from Category of rings to Category of rings is ill-defined, since it sends x (=Rational Field) to something that is not in Category of rings. - """ from sage.categories.morphism import Morphism if isinstance(x, Morphism): @@ -395,27 +388,25 @@ cdef class Functor(SageObject): def domain(self): """ - The domain of self + The domain of ``self``. EXAMPLES:: sage: F = ForgetfulFunctor(FiniteFields(), Fields()) sage: F.domain() Category of finite enumerated fields - """ return self.__domain def codomain(self): """ - The codomain of self + The codomain of ``self``. EXAMPLES:: sage: F = ForgetfulFunctor(FiniteFields(), Fields()) sage: F.codomain() Category of fields - """ return self.__codomain @@ -445,7 +436,6 @@ def is_Functor(x): The forgetful functor from Category of fields to Category of rings sage: is_Functor(F2) True - """ from sage.misc.superseded import deprecation deprecation(38184, @@ -477,7 +467,6 @@ class ForgetfulFunctor_generic(Functor): to Category of fields sage: F(GF(3)) Finite Field of size 3 - """ def __reduce__(self): """ @@ -497,7 +486,6 @@ class ForgetfulFunctor_generic(Functor): sage: F # indirect doctest The forgetful functor from Category of finite enumerated fields to Category of fields - """ return "The forgetful functor from %s to %s" % (self.domain(), self.codomain()) @@ -508,7 +496,7 @@ class ForgetfulFunctor_generic(Functor): It is tested whether the second argument belongs to the class of forgetful functors and has the same domain and codomain as - self. If the second argument is a functor of a different class + ``self``. If the second argument is a functor of a different class but happens to be a forgetful functor, both arguments will still be considered as being *different*. @@ -552,7 +540,7 @@ class ForgetfulFunctor_generic(Functor): class IdentityFunctor_generic(ForgetfulFunctor_generic): """ - Generic identity functor on any category + Generic identity functor on any category. NOTE: @@ -591,7 +579,6 @@ class IdentityFunctor_generic(ForgetfulFunctor_generic): True sage: F The identity functor on Category of groups - """ ForgetfulFunctor_generic.__init__(self, C, C) @@ -632,7 +619,6 @@ class IdentityFunctor_generic(ForgetfulFunctor_generic): sage: F._apply_functor(ZZ) Integer Ring - """ return x @@ -643,11 +629,9 @@ def IdentityFunctor(C): INPUT: - A category, ``C``. - - OUTPUT: + - ``C`` -- a category - The identity functor in ``C``. + OUTPUT: the identity functor in ``C`` EXAMPLES:: @@ -665,7 +649,7 @@ def ForgetfulFunctor(domain, codomain): INPUT: - ``C``, ``D`` -- two categories + - ``C``, ``D`` -- two categories OUTPUT: diff --git a/src/sage/categories/g_sets.py b/src/sage/categories/g_sets.py index d49f790a9e0..f6388d8c496 100644 --- a/src/sage/categories/g_sets.py +++ b/src/sage/categories/g_sets.py @@ -65,7 +65,7 @@ def super_categories(self): @classmethod def an_instance(cls): """ - Returns an instance of this class. + Return an instance of this class. EXAMPLES:: diff --git a/src/sage/categories/graded_algebras.py b/src/sage/categories/graded_algebras.py index 082be147748..8d20019bafd 100644 --- a/src/sage/categories/graded_algebras.py +++ b/src/sage/categories/graded_algebras.py @@ -17,7 +17,7 @@ class GradedAlgebras(GradedModulesCategory): """ - The category of graded algebras + The category of graded algebras. EXAMPLES:: diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index 37c23ebfd82..793e19c848b 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -17,7 +17,7 @@ class GradedAlgebrasWithBasis(GradedModulesCategory): """ - The category of graded algebras with a distinguished basis + The category of graded algebras with a distinguished basis. EXAMPLES:: @@ -89,7 +89,7 @@ def graded_algebra(self): def free_graded_module(self, generator_degrees, names=None): """ - Create a finitely generated free graded module over ``self`` + Create a finitely generated free graded module over ``self``. INPUT: @@ -175,7 +175,7 @@ def extra_super_categories(self): class ParentMethods: """ - Implements operations on tensor products of super algebras + Implement operations on tensor products of super algebras with basis. """ @cached_method diff --git a/src/sage/categories/graded_bialgebras.py b/src/sage/categories/graded_bialgebras.py index 7af567076ac..e7079ee1e5f 100644 --- a/src/sage/categories/graded_bialgebras.py +++ b/src/sage/categories/graded_bialgebras.py @@ -13,7 +13,7 @@ def GradedBialgebras(base_ring): """ - The category of graded bialgebras + The category of graded bialgebras. EXAMPLES:: diff --git a/src/sage/categories/graded_bialgebras_with_basis.py b/src/sage/categories/graded_bialgebras_with_basis.py index e98b44ecb9d..9828a25797f 100644 --- a/src/sage/categories/graded_bialgebras_with_basis.py +++ b/src/sage/categories/graded_bialgebras_with_basis.py @@ -13,7 +13,7 @@ def GradedBialgebrasWithBasis(base_ring): """ - The category of graded bialgebras with a distinguished basis + The category of graded bialgebras with a distinguished basis. EXAMPLES:: diff --git a/src/sage/categories/graded_coalgebras.py b/src/sage/categories/graded_coalgebras.py index 9e36b48dbe5..d229e7a228a 100644 --- a/src/sage/categories/graded_coalgebras.py +++ b/src/sage/categories/graded_coalgebras.py @@ -17,7 +17,7 @@ class GradedCoalgebras(GradedModulesCategory): """ - The category of graded coalgebras + The category of graded coalgebras. EXAMPLES:: diff --git a/src/sage/categories/graded_hopf_algebras_with_basis.py b/src/sage/categories/graded_hopf_algebras_with_basis.py index 3c0458c0e03..2687cbd03be 100644 --- a/src/sage/categories/graded_hopf_algebras_with_basis.py +++ b/src/sage/categories/graded_hopf_algebras_with_basis.py @@ -72,7 +72,6 @@ def super_categories(self): TESTS:: sage: TestSuite(GradedHopfAlgebrasWithBasis(QQ).WithRealizations()).run() - """ from sage.categories.graded_hopf_algebras import GradedHopfAlgebras R = self.base_category().base_ring() @@ -102,9 +101,7 @@ def counit_on_basis(self, i): - ``i`` -- an element of the index set - OUTPUT: - - - an element of the base ring + OUTPUT: an element of the base ring .. MATH:: diff --git a/src/sage/categories/graded_lie_algebras.py b/src/sage/categories/graded_lie_algebras.py index 501d5e7feea..eb60c7e5fca 100644 --- a/src/sage/categories/graded_lie_algebras.py +++ b/src/sage/categories/graded_lie_algebras.py @@ -74,7 +74,7 @@ class FiniteDimensional(CategoryWithAxiom_over_base_ring): """ def extra_super_categories(self): """ - Implements the fact that a finite dimensional stratified Lie + Implement the fact that a finite dimensional stratified Lie algebra is nilpotent. EXAMPLES:: diff --git a/src/sage/categories/graded_modules_with_basis.py b/src/sage/categories/graded_modules_with_basis.py index 5cba7e5f016..a4d66e9c753 100644 --- a/src/sage/categories/graded_modules_with_basis.py +++ b/src/sage/categories/graded_modules_with_basis.py @@ -78,13 +78,13 @@ def submodule(self, gens, check=True, already_echelonized=False, INPUT: - - ``gens`` -- a list or family of elements of ``self`` - - ``check`` -- (default: ``True``) whether to verify that the - elements of ``gens`` are in ``self`` - - ``already_echelonized`` -- (default: ``False``) whether + - ``gens`` -- list or family of elements of ``self`` + - ``check`` -- boolean (default: ``True``); whether to verify that + the elements of ``gens`` are in ``self`` + - ``already_echelonized`` -- boolean (default: ``False``); whether the elements of ``gens`` are already in (not necessarily reduced) echelon form - - ``unitriangular`` -- (default: ``False``) whether + - ``unitriangular`` -- boolean (default: ``False``); whether the lift morphism is unitriangular - ``support_order`` -- (optional) either something that can be converted into a tuple or a key function diff --git a/src/sage/categories/group_algebras.py b/src/sage/categories/group_algebras.py index b0700b004de..e83de9263d3 100644 --- a/src/sage/categories/group_algebras.py +++ b/src/sage/categories/group_algebras.py @@ -189,9 +189,7 @@ def center_basis(self): classes of the group, and `f_\sigma` is the sum of the elements in the conjugacy class of `\sigma`. - OUTPUT: - - - ``tuple`` of elements of ``self`` + OUTPUT: tuple of elements of ``self`` .. WARNING:: @@ -209,7 +207,7 @@ def center_basis(self): - :meth:`Groups.Algebras.ElementMethods.central_form` - :meth:`Monoids.Algebras.ElementMethods.is_central` """ - return tuple([self.sum_of_monomials(conj) for conj in + return tuple([self.sum_of_monomials(conj) for conj in self.basis().keys().conjugacy_classes()]) # Hopf algebra structure diff --git a/src/sage/categories/groupoid.py b/src/sage/categories/groupoid.py index 0f67bd47608..b197c092be5 100644 --- a/src/sage/categories/groupoid.py +++ b/src/sage/categories/groupoid.py @@ -67,7 +67,6 @@ def _make_named_class_key(self, name): sage: Groupoid(DihedralGroup(3)).parent_class is Groupoid(ZZ).parent_class True - """ return None @@ -83,7 +82,7 @@ def super_categories(self): @classmethod def an_instance(cls): """ - Returns an instance of this class. + Return an instance of this class. EXAMPLES:: diff --git a/src/sage/categories/groups.py b/src/sage/categories/groups.py index ae0721c0a55..bc7bb6b7c66 100644 --- a/src/sage/categories/groups.py +++ b/src/sage/categories/groups.py @@ -60,7 +60,7 @@ def free(index_set=None, names=None, **kwds): - ``index_set`` -- (optional) an index set for the generators; if an integer, then this represents `\{0, 1, \ldots, n-1\}` - - ``names`` -- a string or list/tuple/iterable of strings + - ``names`` -- string or list/tuple/iterable of strings (default: ``'x'``); the generator names or name prefix When the index set is an integer or only variable names are given, @@ -155,7 +155,7 @@ def _test_inverse(self, **options): def semidirect_product(self, N, mapping, check=True): r""" - The semi-direct product of two groups + The semi-direct product of two groups. EXAMPLES:: @@ -171,7 +171,7 @@ def semidirect_product(self, N, mapping, check=True): def holomorph(self): r""" - The holomorph of a group + The holomorph of a group. The holomorph of a group `G` is the semidirect product `G \rtimes_{id} Aut(G)`, where `id` is the identity function @@ -195,7 +195,7 @@ def cayley_table(self, names='letters', elements=None): Return the "multiplication" table of this multiplicative group, which is also known as the "Cayley table". - .. note:: The order of the elements in the row and column + .. NOTE:: The order of the elements in the row and column headings is equal to the order given by the table's :meth:`~sage.matrix.operation_table.OperationTable.column_keys` method. The association between the actual elements and the @@ -225,7 +225,7 @@ def cayley_table(self, names='letters', elements=None): * a list - a list of strings, where the length of the list equals the number of elements. - - ``elements`` -- (default = ``None``); A list of + - ``elements`` -- (default: ``None``) a list of elements of the group, in forms that can be coerced into the structure, eg. their string representations. This may be used to impose an @@ -430,7 +430,6 @@ class provides even greater flexibility, including changing AUTHOR: - Rob Beezer (2010-03-15) - """ from sage.matrix.operation_table import OperationTable import operator @@ -510,7 +509,7 @@ def free(index_set=None, names=None, **kwds): - ``index_set`` -- (optional) an index set for the generators; if an integer, then this represents `\{0, 1, \ldots, n-1\}` - - ``names`` -- a string or list/tuple/iterable of strings + - ``names`` -- string or list/tuple/iterable of strings (default: ``'x'``); the generator names or name prefix EXAMPLES:: @@ -627,7 +626,7 @@ def lift(i, gen): gens_prod = cartesian_product([Family(G.group_generators(), lambda g: (i, g)) for i, G in enumerate(F)]) - return Family(gens_prod, lift, name="gen") + return Family(gens_prod, lift, name='gen') def order(self): r""" diff --git a/src/sage/categories/h_trivial_semigroups.py b/src/sage/categories/h_trivial_semigroups.py index 51b2502f3e4..4988bed8cbc 100644 --- a/src/sage/categories/h_trivial_semigroups.py +++ b/src/sage/categories/h_trivial_semigroups.py @@ -19,7 +19,7 @@ class HTrivialSemigroups(CategoryWithAxiom): def Finite_extra_super_categories(self): r""" - Implement the fact that a finite `H`-trivial is aperiodic + Implement the fact that a finite `H`-trivial is aperiodic. EXAMPLES:: diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index 20b9829adac..99ce981eb03 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -104,7 +104,7 @@ class ParentMethods: def _Hom_(self, Y, category): r""" - Return the homset from ``self`` to ``Y`` in the category ``category`` + Return the homset from ``self`` to ``Y`` in the category ``category``. INPUT: @@ -115,7 +115,7 @@ def _Hom_(self, Y, category): The sole purpose of this method is to construct the homset as a :class:`~sage.modular.hecke.homspace.HeckeModuleHomspace`. If ``category`` is specified and is not a subcategory of - :class:`HeckeModules`, a :class:`TypeError` is raised instead + :class:`HeckeModules`, a :exc:`TypeError` is raised instead This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. diff --git a/src/sage/categories/highest_weight_crystals.py b/src/sage/categories/highest_weight_crystals.py index f80d177d917..db7600755bb 100644 --- a/src/sage/categories/highest_weight_crystals.py +++ b/src/sage/categories/highest_weight_crystals.py @@ -80,7 +80,7 @@ def super_categories(self): def example(self): """ - Returns an example of highest weight crystals, as per + Return an example of highest weight crystals, as per :meth:`Category.example`. EXAMPLES:: @@ -114,14 +114,13 @@ class ParentMethods: @cached_method def highest_weight_vectors(self): r""" - Returns the highest weight vectors of ``self`` + Return the highest weight vectors of ``self``. This default implementation selects among the module generators those that are highest weight, and caches the result. A crystal element `b` is highest weight if `e_i(b)=0` for all `i` in the index set. - EXAMPLES:: sage: C = crystals.Letters(['A',5]) @@ -140,7 +139,7 @@ def highest_weight_vectors(self): def highest_weight_vector(self): r""" - Returns the highest weight vector if there is a single one; + Return the highest weight vector if there is a single one; otherwise, raises an error. Caveat: this assumes that :meth:`.highest_weight_vectors` @@ -191,10 +190,10 @@ def __iter__(self, index_set=None, max_depth=float("inf")): INPUT: - - ``index_set`` -- (Default: ``None``) The index set; if ``None`` + - ``index_set`` -- (default: ``None``) the index set; if ``None`` then use the index set of the crystal - - ``max_depth`` -- (Default: infinity) The maximum depth to build + - ``max_depth`` -- (default: infinity) the maximum depth to build EXAMPLES:: @@ -254,13 +253,13 @@ def q_dimension(self, q=None, prec=None, use_product=False): - ``q`` -- the (generic) parameter `q` - - ``prec`` -- (default: ``None``) The precision of the power + - ``prec`` -- (default: ``None``) the precision of the power series ring to use if the crystal is not known to be finite (i.e. the number of terms returned). If ``None``, then the result is returned as a lazy power series. - - ``use_product`` -- (default: ``False``) if we have a finite - crystal and ``True``, use the product formula + - ``use_product`` -- boolean (default: ``False``); if we have a + finite crystal and ``True``, use the product formula EXAMPLES:: @@ -412,7 +411,7 @@ def _Hom_(self, Y, category=None, **options): The sole purpose of this method is to construct the homset as a :class:`~sage.categories.highest_weight_crystals.HighestWeightCrystalHomset`. If ``category`` is specified and is not a subcategory of - :class:`HighestWeightCrystals`, a :class:`TypeError` is raised + :class:`HighestWeightCrystals`, a :exc:`TypeError` is raised instead This method is not meant to be called directly. Please use @@ -522,7 +521,7 @@ def digraph(self, subset=None, index_set=None, depth=None): G = DiGraph(d) from sage.graphs.dot2tex_utils import have_dot2tex if have_dot2tex(): - G.set_latex_options(format="dot2tex", + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=self.cartan_type()._index_set_coloring) return G @@ -670,7 +669,7 @@ def extra_super_categories(self): class ParentMethods: """ - Implements operations on tensor products of crystals. + Implement operations on tensor products of crystals. """ @cached_method def highest_weight_vectors(self): @@ -855,7 +854,8 @@ class HighestWeightCrystalMorphism(CrystalMorphismByGenerators): for the weight, `\varepsilon` and `\varphi` - ``gens`` -- (optional) a list of generators to define the morphism; the default is to use the highest weight vectors of the crystal - - ``check`` -- (default: ``True``) check if the crystal morphism is valid + - ``check`` -- boolean (default: ``True``); check if the crystal morphism + is valid """ def __init__(self, parent, on_gens, cartan_type=None, virtualization=None, scaling_factors=None, diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index c0be4dedfdc..1b05cca4a52 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -94,11 +94,11 @@ def Hom(X, Y, category=None, check=True): - ``Y`` -- an object of a category - - ``category`` -- a category in which the morphisms must be. - (default: the meet of the categories of ``X`` and ``Y``) - Both ``X`` and ``Y`` must belong to that category. + - ``category`` -- a category in which the morphisms must be + (default: the meet of the categories of ``X`` and ``Y``); + both ``X`` and ``Y`` must belong to that category - - ``check`` -- a boolean (default: ``True``): whether to check the + - ``check`` -- boolean (default: ``True``); whether to check the input, and in particular that ``X`` and ``Y`` belong to ``category``. @@ -179,7 +179,7 @@ def Hom(X, Y, category=None, check=True): A parent (or a parent class of a category) may specify how to construct certain homsets by implementing a method ``_Hom_(self, codomain, category)``. This method should either construct the - requested homset or raise a :class:`TypeError`. This hook is currently + requested homset or raise a :exc:`TypeError`. This hook is currently mostly used to create homsets in some specific subclass of :class:`Homset` (e.g. :class:`sage.rings.homset.RingHomset`):: @@ -303,7 +303,7 @@ def Hom(X, Y, category=None, check=True): category. Case of a non parent:: sage: # needs sage.graphs - sage: S = SimplicialComplex([[1,2], [1,4]]); S.rename("S") + sage: S = SimplicialComplex([[1,2], [1,4]]); S.rename('S') sage: Hom(S, S, SimplicialComplexes()) Set of Morphisms from S to S in Category of finite simplicial complexes sage: Hom(Set(), S, Sets()) @@ -323,7 +323,7 @@ def Hom(X, Y, category=None, check=True): sage: class PermissiveCategory(Category): ....: def super_categories(self): return [Objects()] ....: def __contains__(self, X): return True - sage: C = PermissiveCategory(); C.rename("Permissive category") + sage: C = PermissiveCategory(); C.rename('Permissive category') sage: S.category().is_subcategory(C) False sage: S in C @@ -500,13 +500,11 @@ def End(X, category=None): INPUT: - - ``X`` -- anything + - ``X`` -- anything - - ``category`` -- (optional) category in which to coerce ``X`` + - ``category`` -- (optional) category in which to coerce ``X`` - OUTPUT: - - A set of endomorphisms in category + OUTPUT: a set of endomorphisms in category EXAMPLES:: @@ -613,8 +611,8 @@ def __init__(self, X, Y, category=None, base=None, check=True): r""" TESTS:: - sage: X = ZZ['x']; X.rename("X") - sage: Y = ZZ['y']; Y.rename("Y") + sage: X = ZZ['x']; X.rename('X') + sage: Y = ZZ['y']; Y.rename('Y') sage: f = X.hom([0], Y) sage: class MyHomset(Homset): ....: def _an_element_(self): @@ -931,7 +929,7 @@ def _element_constructor_(self, x, check=None, **options): Set of Morphisms from Free Group on generators {x, y, z} to Free Group on generators {x, y, z} in Category of infinite groups sage: HH = Hom(H, H) - sage: HH(HH.identity(), foo="bar") + sage: HH(HH.identity(), foo='bar') Traceback (most recent call last): ... NotImplementedError: no keywords are implemented for @@ -1270,8 +1268,8 @@ def __init__(self, X, Y, category=None, check=True, base=None): r""" TESTS:: - sage: X = ZZ['x']; X.rename("X") - sage: Y = ZZ['y']; Y.rename("Y") + sage: X = ZZ['x']; X.rename('X') + sage: Y = ZZ['y']; Y.rename('Y') sage: f = X.hom([0], Y) sage: class MyHomset(HomsetWithBase): ....: def _an_element_(self): diff --git a/src/sage/categories/homsets.py b/src/sage/categories/homsets.py index 9fce08733d6..d930e5a3fd2 100644 --- a/src/sage/categories/homsets.py +++ b/src/sage/categories/homsets.py @@ -27,8 +27,8 @@ def default_super_categories(cls, category): INPUT: - - ``cls`` -- the category class for the functor `F` - - ``category`` -- a category `Cat` + - ``cls`` -- the category class for the functor `F` + - ``category`` -- a category `Cat` OUTPUT: a category @@ -122,7 +122,7 @@ def default_super_categories(cls, category): def _test_homsets_category(self, **options): r""" - Run generic tests on this homsets category + Run generic tests on this homsets category. .. SEEALSO:: :class:`TestSuite`. @@ -148,7 +148,6 @@ def base(self): sage: ModulesWithBasis(ZZ).Homsets().base() Integer Ring - """ from sage.categories.category_types import Category_over_base for C in self._all_super_categories_proper: diff --git a/src/sage/categories/hopf_algebras.py b/src/sage/categories/hopf_algebras.py index acc85774aff..d6dd6024ecb 100644 --- a/src/sage/categories/hopf_algebras.py +++ b/src/sage/categories/hopf_algebras.py @@ -46,7 +46,7 @@ def super_categories(self): def dual(self): """ - Return the dual category + Return the dual category. EXAMPLES: @@ -64,7 +64,7 @@ class ElementMethods: def antipode(self): """ - Return the antipode of self + Return the antipode of ``self``. EXAMPLES:: @@ -199,7 +199,7 @@ class ParentMethods: # HopfAlgebras.ParentMethods. def antipode_by_coercion(self, x): """ - Returns the image of ``x`` by the antipode + Return the image of ``x`` by the antipode. This default implementation coerces to the default realization, computes the antipode there, and coerces the diff --git a/src/sage/categories/hopf_algebras_with_basis.py b/src/sage/categories/hopf_algebras_with_basis.py index 60e30bde8d3..ea61bbac184 100644 --- a/src/sage/categories/hopf_algebras_with_basis.py +++ b/src/sage/categories/hopf_algebras_with_basis.py @@ -20,7 +20,7 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): """ - The category of Hopf algebras with a distinguished basis + The category of Hopf algebras with a distinguished basis. EXAMPLES:: @@ -37,7 +37,7 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): sage: A = C.example(); A # needs sage.groups An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: A.rename("A") # needs sage.groups + sage: A.rename('A') # needs sage.groups sage: A.category() # needs sage.groups Category of finite dimensional Hopf algebras with basis over Rational Field @@ -121,7 +121,7 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): def example(self, G=None): """ - Returns an example of algebra with basis:: + Return an example of algebra with basis:: sage: HopfAlgebrasWithBasis(QQ['x']).example() # needs sage.groups An example of Hopf algebra with basis: the group algebra of the @@ -169,11 +169,11 @@ class ParentMethods: @abstract_method(optional=True) def antipode_on_basis(self, x): """ - The antipode of the Hopf algebra on the basis (optional) + The antipode of the Hopf algebra on the basis (optional). INPUT: - - ``x`` -- an index of an element of the basis of ``self`` + - ``x`` -- an index of an element of the basis of ``self`` Returns the antipode of the basis element indexed by ``x``. @@ -256,7 +256,6 @@ def _test_antipode(self, **options): sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules sage: s._test_antipode() # needs lrcalc_python sage.combinat sage.modules - """ tester = self._tester(**options) diff --git a/src/sage/categories/infinite_enumerated_sets.py b/src/sage/categories/infinite_enumerated_sets.py index fbd1413cabb..8a6618a4fe6 100644 --- a/src/sage/categories/infinite_enumerated_sets.py +++ b/src/sage/categories/infinite_enumerated_sets.py @@ -19,7 +19,7 @@ class InfiniteEnumeratedSets(CategoryWithAxiom): """ - The category of infinite enumerated sets + The category of infinite enumerated sets. An infinite enumerated sets is a countable set together with a canonical enumeration of its elements. @@ -102,7 +102,7 @@ def _test_enumerated_set_iter_cardinality(self, **options): * :meth:`.cardinality` is supposed to return ``infinity`` - * :meth:`.list` is supposed to raise a :class:`NotImplementedError`. + * :meth:`.list` is supposed to raise a :exc:`NotImplementedError`. EXAMPLES:: diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index a0577a194b0..173a14cf25f 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -20,7 +20,7 @@ class IntegralDomains(CategoryWithAxiom): """ - The category of integral domains + The category of integral domains. An integral domain is commutative ring with no zero divisors, or equivalently a commutative domain. @@ -130,7 +130,6 @@ def _test_fraction_field(self, **options): EXAMPLES:: sage: ZZ._test_fraction_field() - """ tester = self._tester(**options) try: diff --git a/src/sage/categories/isomorphic_objects.py b/src/sage/categories/isomorphic_objects.py index e85f0a8d6da..98af7c4ae7a 100644 --- a/src/sage/categories/isomorphic_objects.py +++ b/src/sage/categories/isomorphic_objects.py @@ -24,7 +24,7 @@ class IsomorphicObjectsCategory(RegressiveCovariantConstructionCategory): @classmethod def default_super_categories(cls, category): """ - Returns the default super categories of ``category.IsomorphicObjects()`` + Return the default super categories of ``category.IsomorphicObjects()``. Mathematical meaning: if `A` is the image of `B` by an isomorphism in the category `C`, then `A` is both a subobject @@ -32,8 +32,8 @@ def default_super_categories(cls, category): INPUT: - - ``cls`` -- the class ``IsomorphicObjectsCategory`` - - ``category`` -- a category `Cat` + - ``cls`` -- the class ``IsomorphicObjectsCategory`` + - ``category`` -- a category `Cat` OUTPUT: a (join) category diff --git a/src/sage/categories/lambda_bracket_algebras.py b/src/sage/categories/lambda_bracket_algebras.py index 9c93d417489..b291086e25e 100644 --- a/src/sage/categories/lambda_bracket_algebras.py +++ b/src/sage/categories/lambda_bracket_algebras.py @@ -34,15 +34,14 @@ class LambdaBracketAlgebras(Category_over_base_ring): This is an abstract base category for Lie conformal algebras and super Lie conformal algebras. - """ @staticmethod def __classcall_private__(cls, R, check=True): r""" INPUT: - - `R` -- a commutative ring - - ``check`` -- a boolean (default: ``True``); whether to check + - ``R`` -- a commutative ring + - ``check`` -- boolean (default: ``True``); whether to check that `R` is a commutative ring EXAMPLES:: @@ -251,7 +250,7 @@ def T(self, n=1): INPUT: - - ``n`` -- integer (default:``1``); how many times + - ``n`` -- integer (default: `1`); how many times to apply `T` to this element OUTPUT: diff --git a/src/sage/categories/lattice_posets.py b/src/sage/categories/lattice_posets.py index 1477e0972e5..7bdc5bfc0de 100644 --- a/src/sage/categories/lattice_posets.py +++ b/src/sage/categories/lattice_posets.py @@ -38,12 +38,11 @@ class LatticePosets(Category): sage: C = LatticePosets() sage: TestSuite(C).run() - """ @cached_method def super_categories(self): r""" - Returns a list of the (immediate) super categories of + Return a list of the (immediate) super categories of ``self``, as per :meth:`Category.super_categories`. EXAMPLES:: @@ -60,11 +59,11 @@ class ParentMethods: @abstract_method def meet(self, x, y): """ - Returns the meet of `x` and `y` in this lattice + Return the meet of `x` and `y` in this lattice. INPUT: - - ``x``, ``y`` -- elements of ``self`` + - ``x``, ``y`` -- elements of ``self`` EXAMPLES:: @@ -76,11 +75,11 @@ def meet(self, x, y): @abstract_method def join(self, x, y): """ - Returns the join of `x` and `y` in this lattice + Return the join of `x` and `y` in this lattice. INPUT: - - ``x``, ``y`` -- elements of ``self`` + - ``x``, ``y`` -- elements of ``self`` EXAMPLES:: diff --git a/src/sage/categories/lie_algebras.py b/src/sage/categories/lie_algebras.py index 0f8fde4936f..f134cfded5b 100644 --- a/src/sage/categories/lie_algebras.py +++ b/src/sage/categories/lie_algebras.py @@ -178,7 +178,7 @@ class FiniteDimensional(CategoryWithAxiom_over_base_ring): def extra_super_categories(self): """ - Implements the fact that a finite dimensional Lie algebra over + Implement the fact that a finite dimensional Lie algebra over a finite ring is finite. EXAMPLES:: @@ -645,7 +645,7 @@ def bch(self, X, Y, prec=None): - ``X`` -- an element of ``self`` - ``Y`` -- an element of ``self`` - - ``prec`` -- an integer; the maximum length of Lie brackets to be + - ``prec`` -- integer; the maximum length of Lie brackets to be considered in the formula EXAMPLES: @@ -781,7 +781,7 @@ def _test_jacobi_identity(self, **options): INPUT: - - ``options`` -- any keyword arguments accepted by :meth:`_tester`. + - ``options`` -- any keyword arguments accepted by :meth:`_tester` EXAMPLES: @@ -820,7 +820,7 @@ def _test_antisymmetry(self, **options): INPUT: - - ``options`` -- any keyword arguments accepted by :meth:`_tester`. + - ``options`` -- any keyword arguments accepted by :meth:`_tester` EXAMPLES: @@ -852,7 +852,7 @@ def _test_distributivity(self, **options): INPUT: - - ``options`` -- any keyword arguments accepted by :meth:`_tester`. + - ``options`` -- any keyword arguments accepted by :meth:`_tester` TESTS:: @@ -864,7 +864,7 @@ def _test_distributivity(self, **options): By default, this method runs the tests only on the elements returned by ``self.some_elements()``:: - sage: L = LieAlgebra(QQ, 3, 'x,y,z', representation="polynomial") # needs sage.combinat sage.modules + sage: L = LieAlgebra(QQ, 3, 'x,y,z', representation='polynomial') # needs sage.combinat sage.modules sage: L.some_elements() # needs sage.combinat sage.modules [x + y + z] sage: L._test_distributivity() # needs sage.combinat sage.modules @@ -1043,7 +1043,7 @@ def __init__(self, domain, codomain): We skip the category test since this is currently not an element of a homspace:: - sage: TestSuite(f).run(skip="_test_category") # needs sage.combinat sage.libs.singular sage.modules + sage: TestSuite(f).run(skip='_test_category') # needs sage.combinat sage.libs.singular sage.modules """ Morphism.__init__(self, Hom(domain, codomain)) diff --git a/src/sage/categories/lie_algebras_with_basis.py b/src/sage/categories/lie_algebras_with_basis.py index 9518113ce23..6db83cbe61d 100644 --- a/src/sage/categories/lie_algebras_with_basis.py +++ b/src/sage/categories/lie_algebras_with_basis.py @@ -44,7 +44,7 @@ def example(self, gens=None): sage: LieAlgebras(QQ).WithBasis().example(Compositions()) # needs sage.combinat sage.modules An example of a Lie algebra: the abelian Lie algebra on the - generators indexed by Compositions of non-negative integers + generators indexed by Compositions of nonnegative integers over Rational Field """ if gens is None: diff --git a/src/sage/categories/lie_conformal_algebras.py b/src/sage/categories/lie_conformal_algebras.py index 561d9e1e693..13c4f3e7c5b 100644 --- a/src/sage/categories/lie_conformal_algebras.py +++ b/src/sage/categories/lie_conformal_algebras.py @@ -60,8 +60,7 @@ .. NOTE:: In the literature arbitrary gradings are allowed. In this - implementation we only support non-negative rational gradings. - + implementation we only support nonnegative rational gradings. EXAMPLES: diff --git a/src/sage/categories/lie_groups.py b/src/sage/categories/lie_groups.py index 1512a599e04..792b87bad39 100644 --- a/src/sage/categories/lie_groups.py +++ b/src/sage/categories/lie_groups.py @@ -30,7 +30,7 @@ class LieGroups(Category_over_base_ring): TESTS:: - sage: TestSuite(C).run(skip="_test_category_over_bases") + sage: TestSuite(C).run(skip='_test_category_over_bases') """ @cached_method def super_categories(self): diff --git a/src/sage/categories/loop_crystals.py b/src/sage/categories/loop_crystals.py index fbf4afd3f58..e6bf9126876 100644 --- a/src/sage/categories/loop_crystals.py +++ b/src/sage/categories/loop_crystals.py @@ -822,7 +822,7 @@ def one_dimensional_configuration_sum(self, q=None, group_components=True): - ``q`` -- (default: ``None``) a variable or ``None``; if ``None``, a variable `q` is set in the code - - ``group_components`` -- (default: ``True``) boolean; if + - ``group_components`` -- boolean (default: ``True``); if ``True``, then the terms are grouped by classical component The one-dimensional configuration sum is the sum of the @@ -924,7 +924,7 @@ def energy_function(self, algorithm=None): factors are perfect of the same level and otherwise this uses ``'definition'`` - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1021,7 +1021,7 @@ def affine_grading(self): :meth:`e_string_to_ground_state`) and counting the number of affine Kashiwara operators `e_0` applied on the way. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 2fa35e45b49..ea491b2caf7 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -380,7 +380,7 @@ def is_field(self, proof=True): Return ``True`` if ``self`` is a field. For a magma algebra `RS` this is always false unless - `S` is trivial and the base ring `R`` is a field. + `S` is trivial and the base ring `R` is a field. EXAMPLES:: @@ -835,9 +835,9 @@ def __init_extra__(self): def multiplication_table(self, names='letters', elements=None): r""" - Returns a table describing the multiplication operation. + Return a table describing the multiplication operation. - .. note:: The order of the elements in the row and column + .. NOTE:: The order of the elements in the row and column headings is equal to the order given by the table's :meth:`~sage.matrix.operation_table.OperationTable.list` method. The association can also be retrieved with the @@ -861,7 +861,7 @@ def multiplication_table(self, names='letters', elements=None): of the elements themselves. * a list - a list of strings, where the length of the list equals the number of elements. - - ``elements`` -- default = ``None``. A list of + - ``elements`` -- (default: ``None``) a list of elements of the magma, in forms that can be coerced into the structure, eg. their string representations. This may be used to impose an @@ -987,15 +987,13 @@ class ElementMethods: @abstract_method(optional=True) def _mul_(self, right): """ - Product of two elements + Product of two elements. INPUT: - ``self``, ``right`` -- two elements with the same parent - OUTPUT: - - - an element of the same parent + OUTPUT: an element of the same parent EXAMPLES:: @@ -1031,7 +1029,6 @@ def is_idempotent(self): 'x' sage: x.is_idempotent() True - """ return self * self == self @@ -1180,7 +1177,6 @@ def product_by_coercion(self, left, right): sage: y = Out.an_element() sage: Out.product(x, y) Out[{}] + 4*Out[{1}] + 9*Out[{2}] + Out[{1, 2}] - """ R = self.realization_of().a_realization() return self(R(left) * R(right)) diff --git a/src/sage/categories/magmatic_algebras.py b/src/sage/categories/magmatic_algebras.py index 60da61a4983..0b45887d254 100644 --- a/src/sage/categories/magmatic_algebras.py +++ b/src/sage/categories/magmatic_algebras.py @@ -65,7 +65,6 @@ def super_categories(self): sage: from sage.categories.additive_semigroups import AdditiveSemigroups sage: MA.is_subcategory((AdditiveSemigroups() & Magmas()).Distributive()) True - """ R = self.base_ring() # Note: The specifications impose `self` to be a subcategory @@ -219,7 +218,6 @@ def _product_from_product_on_basis_multiply( self, left, right ): sage: a, b, c = A.algebra_generators() # needs sage.combinat sage.modules sage: A._product_from_product_on_basis_multiply(a*b + 2*c, a - b) # needs sage.combinat sage.modules B[word: aba] - B[word: abb] + 2*B[word: ca] - 2*B[word: cb] - """ return self.linear_combination((self.product_on_basis(mon_left, mon_right), coeff_left * coeff_right ) for (mon_left, coeff_left) in left.monomial_coefficients(copy=False).items() diff --git a/src/sage/categories/manifolds.py b/src/sage/categories/manifolds.py index 22138cca200..95e4dd928d9 100644 --- a/src/sage/categories/manifolds.py +++ b/src/sage/categories/manifolds.py @@ -36,7 +36,7 @@ class Manifolds(Category_over_base_ring): TESTS:: - sage: TestSuite(C).run(skip="_test_category_over_bases") # needs sage.rings.real_mpfr + sage: TestSuite(C).run(skip='_test_category_over_bases') # needs sage.rings.real_mpfr """ def __init__(self, base, name=None): r""" @@ -46,7 +46,7 @@ def __init__(self, base, name=None): sage: from sage.categories.manifolds import Manifolds sage: C = Manifolds(RR) - sage: TestSuite(C).run(skip="_test_category_over_bases") + sage: TestSuite(C).run(skip='_test_category_over_bases') """ if base not in Fields().Topological(): raise ValueError("base must be a topological field") @@ -318,7 +318,7 @@ class FiniteDimensional(CategoryWithAxiom_over_base_ring): sage: from sage.categories.manifolds import Manifolds sage: C = Manifolds(RR).FiniteDimensional() - sage: TestSuite(C).run(skip="_test_category_over_bases") + sage: TestSuite(C).run(skip='_test_category_over_bases') """ class Connected(CategoryWithAxiom_over_base_ring): @@ -329,7 +329,7 @@ class Connected(CategoryWithAxiom_over_base_ring): sage: from sage.categories.manifolds import Manifolds sage: C = Manifolds(RR).Connected() - sage: TestSuite(C).run(skip="_test_category_over_bases") + sage: TestSuite(C).run(skip='_test_category_over_bases') """ diff --git a/src/sage/categories/map.pxd b/src/sage/categories/map.pxd index 6f3b3bb8a91..8738d4cf042 100644 --- a/src/sage/categories/map.pxd +++ b/src/sage/categories/map.pxd @@ -16,9 +16,9 @@ cdef class Map(Element): cpdef Element _call_(self, x) cpdef Element _call_with_args(self, x, args=*, kwds=*) - cdef public domain # will be either a weakref or a constant map - cdef public codomain # will be a constant map - cdef Parent _codomain # for accessing the codomain directly + cdef public domain # will be either a weakref or a constant map + cdef public codomain # will be a constant map + cdef Parent _codomain # for accessing the codomain directly cdef object _category_for # category in which this is a morphism cdef public _repr_type_str diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index b420adb4d76..43e476847d0 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -183,7 +183,7 @@ cdef class Map(Element): cdef Map out = Element.__copy__(self) # Element.__copy__ updates the __dict__, but not the slots. # Let's do this now, but with strong references. - out._parent = self.parent() # self._parent might be None + out._parent = self.parent() # self._parent might be None out._update_slots(self._extra_slots()) return out @@ -401,10 +401,10 @@ cdef class Map(Element): INPUT: - - ``slots`` -- A dictionary of slots to be updated. - The dictionary must have the keys ``'_domain'`` and + - ``slots`` -- dictionary of slots to be updated; + the dictionary must have the keys ``'_domain'`` and ``'_codomain'``, and may have the keys ``'_repr_type_str'`` - and ``'_is_coercion'``. + and ``'_is_coercion'`` TESTS: @@ -462,10 +462,10 @@ cdef class Map(Element): Return a dict with attributes to pickle and copy this map. """ return dict( - _domain=self.domain(), - _codomain=self._codomain, - _is_coercion=self._is_coercion, - _repr_type_str=self._repr_type_str) + _domain=self.domain(), + _codomain=self._codomain, + _is_coercion=self._is_coercion, + _repr_type_str=self._repr_type_str) def _extra_slots_test(self): """ @@ -509,7 +509,7 @@ cdef class Map(Element): .. NOTE:: - By default, the string ``"Generic"`` is returned. Subclasses may overload this method. + By default, the string ``'Generic'`` is returned. Subclasses may overload this method. EXAMPLES:: @@ -634,7 +634,7 @@ cdef class Map(Element): def category_for(self): """ - Returns the category self is a morphism for. + Return the category ``self`` is a morphism for. .. NOTE:: @@ -655,9 +655,11 @@ cdef class Map(Element): sage: f = R.hom([x+y, x-y], R) sage: f.category_for() Join of Category of unique factorization domains - and Category of commutative algebras - over (number fields and quotient fields and metric spaces) - and Category of infinite sets + and Category of algebras with basis over + (number fields and quotient fields and metric spaces) + and Category of commutative algebras over + (number fields and quotient fields and metric spaces) + and Category of infinite sets sage: f.category() Category of endsets of unital magmas and right modules over (number fields and quotient fields and metric spaces) @@ -801,7 +803,7 @@ cdef class Map(Element): """ P = parent(x) cdef Parent D = self.domain() - if P is D: # we certainly want to call _call_/with_args + if P is D: # we certainly want to call _call_/with_args if not args and not kwds: return self._call_(x) return self._call_with_args(x, args, kwds) @@ -857,7 +859,7 @@ cdef class Map(Element): def __mul__(self, right): r""" - The multiplication * operator is operator composition + The multiplication * operator is operator composition. IMPLEMENTATION: @@ -937,7 +939,7 @@ cdef class Map(Element): INPUT: - - ``self`` -- a Map in some ``Hom(Y, Z, category_left)`` + - ``self`` -- a Map in some ``Hom(Y, Z, category_left)`` - ``right`` -- a Map in some ``Hom(X, Y, category_right)`` OUTPUT: @@ -977,7 +979,7 @@ cdef class Map(Element): INPUT: - ``self``, ``right`` -- maps - - homset -- a homset + - ``homset`` -- a homset ASSUMPTION: @@ -1139,7 +1141,7 @@ cdef class Map(Element): OUTPUT: An element of Hom(X, Z) obtained by composing self with `\phi`. If - no canonical `\phi` exists, a :class:`TypeError` is raised. + no canonical `\phi` exists, a :exc:`TypeError` is raised. EXAMPLES:: @@ -1183,8 +1185,8 @@ cdef class Map(Element): OUTPUT: - An element of Hom(X, Z) obtained by composing self with `\phi`. If - no canonical `\phi` exists, a :class:`TypeError` is raised. + An element of Hom(X, Z) obtained by composing ``self`` with `\phi`. If + no canonical `\phi` exists, a :exc:`TypeError` is raised. EXAMPLES:: @@ -1215,7 +1217,7 @@ cdef class Map(Element): def is_surjective(self): """ - Tells whether the map is surjective (not implemented in the base class). + Tell whether the map is surjective (not implemented in the base class). TESTS:: @@ -1357,7 +1359,7 @@ cdef class Section(Map): """ INPUT: - A map. + - ``map`` -- a map TESTS:: @@ -1499,9 +1501,9 @@ cdef class FormalCompositeMap(Map): """ INPUT: - - ``parent``: a homset - - ``first``: a map or a list of maps - - ``second``: a map or None + - ``parent`` -- a homset + - ``first`` -- a map or a list of maps + - ``second`` -- a map or None .. NOTE:: @@ -1711,13 +1713,12 @@ cdef class FormalCompositeMap(Map): Traceback (most recent call last): ... IndexError: list index out of range - """ return self.__list[i] cpdef Element _call_(self, x): """ - Call with a single argument + Call with a single argument. TESTS:: @@ -1766,7 +1767,7 @@ cdef class FormalCompositeMap(Map): def _repr_type(self): """ - Return a string describing the type of ``self``, namely "Composite" + Return a string describing the type of ``self``, namely "Composite". TESTS:: @@ -1792,7 +1793,7 @@ cdef class FormalCompositeMap(Map): def _repr_defn(self): """ - Return a string describing the definition of ``self`` + Return a string describing the definition of ``self``. The return value is obtained from the string representations of the two constituents. @@ -1887,7 +1888,7 @@ cdef class FormalCompositeMap(Map): """ Tell whether ``self`` is injective. - It raises :class:`NotImplementedError` if it cannot be determined. + It raises :exc:`NotImplementedError` if it cannot be determined. EXAMPLES:: @@ -1932,7 +1933,6 @@ cdef class FormalCompositeMap(Map): sage: f = QQ.hom(QQbar) * ZZ.hom(QQ) # needs sage.rings.number_field sage: f.is_injective() # needs sage.rings.number_field True - """ try: # we try the category first @@ -1962,7 +1962,7 @@ cdef class FormalCompositeMap(Map): """ Tell whether ``self`` is surjective. - It raises :class:`NotImplementedError` if it cannot be determined. + It raises :exc:`NotImplementedError` if it cannot be determined. EXAMPLES:: diff --git a/src/sage/categories/meson.build b/src/sage/categories/meson.build new file mode 100644 index 00000000000..132037fe7fd --- /dev/null +++ b/src/sage/categories/meson.build @@ -0,0 +1,224 @@ +py.install_sources( + 'action.pxd', + 'additive_groups.py', + 'additive_magmas.py', + 'additive_monoids.py', + 'additive_semigroups.py', + 'affine_weyl_groups.py', + 'algebra_functor.py', + 'algebra_ideals.py', + 'algebra_modules.py', + 'algebras.py', + 'algebras_with_basis.py', + 'all.py', + 'all__sagemath_objects.py', + 'aperiodic_semigroups.py', + 'associative_algebras.py', + 'basic.py', + 'bialgebras.py', + 'bialgebras_with_basis.py', + 'bimodules.py', + 'cartesian_product.py', + 'category.py', + 'category_cy_helper.pxd', + 'category_singleton.pxd', + 'category_types.py', + 'category_with_axiom.py', + 'chain_complexes.py', + 'classical_crystals.py', + 'coalgebras.py', + 'coalgebras_with_basis.py', + 'commutative_additive_groups.py', + 'commutative_additive_monoids.py', + 'commutative_additive_semigroups.py', + 'commutative_algebra_ideals.py', + 'commutative_algebras.py', + 'commutative_ring_ideals.py', + 'commutative_rings.py', + 'complete_discrete_valuation.py', + 'complex_reflection_groups.py', + 'complex_reflection_or_generalized_coxeter_groups.py', + 'covariant_functorial_construction.py', + 'coxeter_group_algebras.py', + 'coxeter_groups.py', + 'crystals.py', + 'cw_complexes.py', + 'dedekind_domains.py', + 'discrete_valuation.py', + 'distributive_magmas_and_additive_magmas.py', + 'division_rings.py', + 'domains.py', + 'drinfeld_modules.py', + 'dual.py', + 'enumerated_sets.py', + 'euclidean_domains.py', + 'facade_sets.py', + 'fields.py', + 'filtered_algebras.py', + 'filtered_algebras_with_basis.py', + 'filtered_hopf_algebras_with_basis.py', + 'filtered_modules.py', + 'filtered_modules_with_basis.py', + 'finite_complex_reflection_groups.py', + 'finite_coxeter_groups.py', + 'finite_crystals.py', + 'finite_dimensional_algebras_with_basis.py', + 'finite_dimensional_bialgebras_with_basis.py', + 'finite_dimensional_coalgebras_with_basis.py', + 'finite_dimensional_graded_lie_algebras_with_basis.py', + 'finite_dimensional_hopf_algebras_with_basis.py', + 'finite_dimensional_lie_algebras_with_basis.py', + 'finite_dimensional_modules_with_basis.py', + 'finite_dimensional_nilpotent_lie_algebras_with_basis.py', + 'finite_dimensional_semisimple_algebras_with_basis.py', + 'finite_enumerated_sets.py', + 'finite_fields.py', + 'finite_groups.py', + 'finite_lattice_posets.py', + 'finite_monoids.py', + 'finite_permutation_groups.py', + 'finite_posets.py', + 'finite_semigroups.py', + 'finite_sets.py', + 'finite_weyl_groups.py', + 'finitely_generated_lambda_bracket_algebras.py', + 'finitely_generated_lie_conformal_algebras.py', + 'finitely_generated_magmas.py', + 'finitely_generated_semigroups.py', + 'function_fields.py', + 'functor.pxd', + 'g_sets.py', + 'gcd_domains.py', + 'generalized_coxeter_groups.py', + 'graded_algebras.py', + 'graded_algebras_with_basis.py', + 'graded_bialgebras.py', + 'graded_bialgebras_with_basis.py', + 'graded_coalgebras.py', + 'graded_coalgebras_with_basis.py', + 'graded_hopf_algebras.py', + 'graded_hopf_algebras_with_basis.py', + 'graded_lie_algebras.py', + 'graded_lie_algebras_with_basis.py', + 'graded_lie_conformal_algebras.py', + 'graded_modules.py', + 'graded_modules_with_basis.py', + 'graphs.py', + 'group_algebras.py', + 'groupoid.py', + 'groups.py', + 'h_trivial_semigroups.py', + 'hecke_modules.py', + 'highest_weight_crystals.py', + 'homset.py', + 'homsets.py', + 'hopf_algebras.py', + 'hopf_algebras_with_basis.py', + 'infinite_enumerated_sets.py', + 'integral_domains.py', + 'isomorphic_objects.py', + 'j_trivial_semigroups.py', + 'kac_moody_algebras.py', + 'l_trivial_semigroups.py', + 'lambda_bracket_algebras.py', + 'lambda_bracket_algebras_with_basis.py', + 'lattice_posets.py', + 'left_modules.py', + 'lie_algebras.py', + 'lie_algebras_with_basis.py', + 'lie_conformal_algebras.py', + 'lie_conformal_algebras_with_basis.py', + 'lie_groups.py', + 'loop_crystals.py', + 'magmas.py', + 'magmas_and_additive_magmas.py', + 'magmatic_algebras.py', + 'manifolds.py', + 'map.pxd', + 'matrix_algebras.py', + 'metric_spaces.py', + 'modular_abelian_varieties.py', + 'modules.py', + 'modules_with_basis.py', + 'monoid_algebras.py', + 'monoids.py', + 'morphism.pxd', + 'noetherian_rings.py', + 'number_fields.py', + 'objects.py', + 'partially_ordered_monoids.py', + 'permutation_groups.py', + 'pointed_sets.py', + 'polyhedra.py', + 'poor_man_map.py', + 'posets.py', + 'primer.py', + 'principal_ideal_domains.py', + 'pushout.py', + 'quantum_group_representations.py', + 'quotient_fields.py', + 'quotients.py', + 'r_trivial_semigroups.py', + 'realizations.py', + 'regular_crystals.py', + 'regular_supercrystals.py', + 'right_modules.py', + 'ring_ideals.py', + 'rings.py', + 'rngs.py', + 'schemes.py', + 'semigroups.py', + 'semirings.py', + 'semisimple_algebras.py', + 'sets_cat.py', + 'sets_with_grading.py', + 'sets_with_partial_maps.py', + 'shephard_groups.py', + 'signed_tensor.py', + 'simplicial_complexes.py', + 'simplicial_sets.py', + 'subobjects.py', + 'subquotients.py', + 'super_algebras.py', + 'super_algebras_with_basis.py', + 'super_hopf_algebras_with_basis.py', + 'super_lie_conformal_algebras.py', + 'super_modules.py', + 'super_modules_with_basis.py', + 'supercommutative_algebras.py', + 'supercrystals.py', + 'tensor.py', + 'topological_spaces.py', + 'triangular_kac_moody_algebras.py', + 'tutorial.py', + 'unique_factorization_domains.py', + 'unital_algebras.py', + 'vector_bundles.py', + 'vector_spaces.py', + 'weyl_groups.py', + 'with_realizations.py', + subdir: 'sage/categories', +) + +extension_data = { + 'action' : files('action.pyx'), + 'category_cy_helper' : files('category_cy_helper.pyx'), + 'category_singleton' : files('category_singleton.pyx'), + 'coercion_methods' : files('coercion_methods.pyx'), + 'functor' : files('functor.pyx'), + 'map' : files('map.pyx'), + 'morphism' : files('morphism.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/categories', + install: true, + include_directories: [inc_cpython, inc_ext], + dependencies: [py_dep, gmp], + ) +endforeach + +subdir('examples') diff --git a/src/sage/categories/metric_spaces.py b/src/sage/categories/metric_spaces.py index c8e36669601..e53ebe7bfee 100644 --- a/src/sage/categories/metric_spaces.py +++ b/src/sage/categories/metric_spaces.py @@ -227,7 +227,7 @@ def dist(self, b): class Homsets(HomsetsCategory): """ - The category of homsets of metric spaces + The category of homsets of metric spaces. It consists of the metric maps, that is, the Lipschitz functions with Lipschitz constant 1. diff --git a/src/sage/categories/modules.py b/src/sage/categories/modules.py index 990fcdfb456..f9bc036910f 100644 --- a/src/sage/categories/modules.py +++ b/src/sage/categories/modules.py @@ -45,7 +45,7 @@ class Modules(Category_module): INPUT: - ``base_ring`` -- a ring `R` or subcategory of ``Rings()`` - - ``dispatch`` -- a boolean (for internal use; default: ``True``) + - ``dispatch`` -- boolean (for internal use; default: ``True``) When the base ring is a field, the category of vector spaces is returned instead (unless ``dispatch == False``). @@ -558,7 +558,6 @@ def extra_super_categories(self): sage: Modules(QQ).FiniteDimensional().TensorProducts().FiniteDimensional() Category of tensor products of finite dimensional vector spaces over Rational Field - """ return [self.base_category()] @@ -637,7 +636,7 @@ def linear_combination(self, iter_of_elements_coeff, factor_on_left=True): @cached_method def tensor_square(self): """ - Returns the tensor square of ``self`` + Return the tensor square of ``self``. EXAMPLES:: @@ -660,7 +659,7 @@ def module_morphism(self, *, function, category=None, codomain, **keywords): INPUT: - - ``self`` -- a parent `X` in ``Modules(R)``. + - ``self`` -- a parent `X` in ``Modules(R)`` - ``function`` -- a function `f` from `X` to `Y` @@ -681,7 +680,6 @@ def module_morphism(self, *, function, category=None, codomain, **keywords): 2-dimensional vector space over the Rational Field sage: neg(e[0]) Element -e_0 of the 2-dimensional vector space over the Rational Field - """ # Make sure that we only create a module morphism, even if # domain and codomain have more structure @@ -699,7 +697,7 @@ def quotient(self, submodule, check=True, **kwds): something that can be turned into one via ``self.submodule(submodule)`` - - ``check``, other keyword arguments: passed on to + - ``check``, other keyword arguments -- passed on to :meth:`quotient_module`. This method just delegates to :meth:`quotient_module`. @@ -717,7 +715,6 @@ def quotient(self, submodule, check=True, **kwds): - """ return self.quotient_module(submodule, check=check, **kwds) @@ -837,7 +834,7 @@ def extra_super_categories(self): class CartesianProducts(CartesianProductsCategory): """ - The category of modules constructed as Cartesian products of modules + The category of modules constructed as Cartesian products of modules. This construction gives the direct product of modules. The implementation is based on the following resources: @@ -896,7 +893,7 @@ def __init_extra__(self): (Vector space of dimension 2 over Rational Field, Univariate Polynomial Ring in x over Rational Field) sage: A.category() # needs sage.modules - Category of Cartesian products of vector spaces + Category of Cartesian products of vector spaces with basis over (number fields and quotient fields and metric spaces) sage: A.base_ring() # needs sage.modules Rational Field @@ -988,9 +985,9 @@ def tensor_factors(self): sage: # needs sage.modules sage: F = CombinatorialFreeModule(ZZ, [1,2]) - sage: F.rename("F") + sage: F.rename('F') sage: G = CombinatorialFreeModule(ZZ, [3,4]) - sage: G.rename("G") + sage: G.rename('G') sage: T = tensor([F, G]); T F # G sage: T.tensor_factors() diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index ea691177704..7b51d82c7ba 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -68,8 +68,8 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring): Let `X` and `Y` be two modules with basis. We can build `Hom(X,Y)`:: - sage: X = CombinatorialFreeModule(QQ, [1,2]); X.rename("X") # needs sage.modules - sage: Y = CombinatorialFreeModule(QQ, [3,4]); Y.rename("Y") # needs sage.modules + sage: X = CombinatorialFreeModule(QQ, [1,2]); X.rename('X') # needs sage.modules + sage: Y = CombinatorialFreeModule(QQ, [3,4]); Y.rename('Y') # needs sage.modules sage: H = Hom(X, Y); H # needs sage.modules Set of Morphisms from X to Y in Category of finite dimensional vector spaces with basis over Rational Field @@ -139,7 +139,6 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring): 0 sage: TestSuite(ModulesWithBasis(ZZ)).run() - """ def _call_(self, x): @@ -241,7 +240,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, INPUT: - ``self`` -- a parent `X` in ``ModulesWithBasis(R)`` with - basis `x=(x_i)_{i\in I}`. + basis `x=(x_i)_{i\in I}` Exactly one of the four following options must be specified in order to define the morphism: @@ -249,7 +248,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, - ``on_basis`` -- a function `f` from `I` to `Y` - ``diagonal`` -- a function `d` from `I` to `R` - ``function`` -- a function `f` from `X` to `Y` - - ``matrix`` -- a matrix of size `\dim Y \times \dim X` + - ``matrix`` -- a matrix of size `\dim Y \times \dim X` (if the keyword ``side`` is set to ``'left'``) or `\dim Y \times \dim X` (if this keyword is ``'right'``) @@ -264,28 +263,28 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, can be used (with care) to define affine maps. Only meaningful with ``on_basis``. - - ``position`` -- a non-negative integer specifying which + - ``position`` -- nonnegative integer specifying which positional argument is used as the input of the function `f` (default: 0); this is currently only used with ``on_basis``. - - ``triangular`` -- (default: ``None``) ``"upper"`` or - ``"lower"`` or ``None``: + - ``triangular`` -- (default: ``None``) ``'upper'`` or + ``'lower'`` or ``None``: - * ``"upper"`` -- if the + * ``'upper'`` -- if the :meth:`~ModulesWithBasis.ElementMethods.leading_support` of the image of the basis vector `x_i` is `i`, or - * ``"lower"`` -- if the + * ``'lower'`` -- if the :meth:`~ModulesWithBasis.ElementMethods.trailing_support` of the image of the basis vector `x_i` is `i`. - - ``unitriangular`` -- (default: ``False``) a boolean. - Only meaningful for a triangular morphism. + - ``unitriangular`` -- boolean (default: ``False``); + only meaningful for a triangular morphism. As a shorthand, one may use ``unitriangular="lower"`` - for ``triangular="lower", unitriangular=True``. + for ``triangular='lower', unitriangular=True``. - - ``side`` -- "left" or "right" (default: "left") - Only meaningful for a morphism built from a matrix. + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``); + only meaningful for a morphism built from a matrix EXAMPLES: @@ -302,8 +301,8 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X') + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y') sage: def f(i): ....: return Y.monomial(i) + 2*Y.monomial(i+1) sage: phi = X.module_morphism(f, codomain=Y) @@ -437,7 +436,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, and `Y` have the same index set `I`:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(ZZ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(ZZ, [1, 2, 3]); X.rename('X') sage: from sage.arith.misc import factorial sage: phi = X.module_morphism(diagonal=factorial, codomain=X) sage: x = X.basis() @@ -451,9 +450,9 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, and `Y` is `m`:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') sage: x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y") + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y') sage: y = Y.basis() sage: m = matrix([[0,1,2], [3,5,0]]) sage: phi = X.module_morphism(matrix=m, codomain=Y) @@ -473,10 +472,10 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, sage: # needs sage.modules sage: I = list(range(1, 200)) - sage: X = CombinatorialFreeModule(QQ, I); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(QQ, I); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(QQ, I); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(QQ, I); Y.rename('Y'); y = Y.basis() sage: f = Y.sum_of_monomials * divisors - sage: phi = X.module_morphism(f, triangular="upper", codomain=Y) + sage: phi = X.module_morphism(f, triangular='upper', codomain=Y) sage: phi(x[2]) B[1] + B[2] sage: phi(x[6]) @@ -500,7 +499,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismFromFunction sage: def f(x): return x + X.term(0, sum(x.coefficients())) sage: phi = X.module_morphism(function=f, codomain=X, - ....: triangular="upper") + ....: triangular='upper') sage: phi(x[2] + 3*x[4]) 4*B[0] + B[2] + 3*B[4] sage: phi.preimage(_) @@ -526,7 +525,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, TESTS:: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules sage: phi = X.module_morphism(codomain=X) # needs sage.modules Traceback (most recent call last): ... @@ -535,7 +534,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules sage: phi = X.module_morphism(diagonal=factorial, matrix=matrix(), # needs sage.modules ....: codomain=X) Traceback (most recent call last): @@ -545,7 +544,7 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules sage: phi = X.module_morphism(matrix=factorial, codomain=X) # needs sage.modules Traceback (most recent call last): ... @@ -553,12 +552,11 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules sage: phi = X.module_morphism(diagonal=3, codomain=X) # needs sage.modules Traceback (most recent call last): ... ValueError: diagonal (=3) should be a function - """ if len([x for x in [matrix, on_basis, function, diagonal] if x is not None]) != 1: raise ValueError("module_morphism() takes exactly one option out of `matrix`, `on_basis`, `function`, `diagonal`") @@ -599,7 +597,7 @@ def _repr_(self): Free module generated by {1, 2, 3} over Rational Field sage: C._name = "foobar"; C foobar over Rational Field - sage: C.rename("barfoo"); C + sage: C.rename('barfoo'); C barfoo sage: class FooBar(Parent): @@ -682,9 +680,9 @@ def echelon_form(self, elements, row_reduced=False, order=None): INPUT: - - ``elements`` -- a list or finite iterable of elements of ``self`` - - ``row_reduced`` -- (default: ``False``) whether to compute the - basis for the row reduced echelon form + - ``elements`` -- list or finite iterable of elements of ``self`` + - ``row_reduced`` -- boolean (default: ``False``); whether to + compute the basis for the row reduced echelon form - ``order`` -- (optional) either something that can be converted into a tuple or a key function @@ -736,13 +734,13 @@ def submodule(self, gens, check=True, already_echelonized=False, INPUT: - - ``gens`` -- a list or family of elements of ``self`` - - ``check`` -- (default: ``True``) whether to verify that the - elements of ``gens`` are in ``self`` - - ``already_echelonized`` -- (default: ``False``) whether + - ``gens`` -- list or family of elements of ``self`` + - ``check`` -- boolean (default: ``True``); whether to verify that + the elements of ``gens`` are in ``self`` + - ``already_echelonized`` -- boolean (default: ``False``); whether the elements of ``gens`` are already in (not necessarily reduced) echelon form - - ``unitriangular`` -- (default: ``False``) whether + - ``unitriangular`` -- boolean (default: ``False``); whether the lift morphism is unitriangular - ``support_order`` -- (optional) either something that can be converted into a tuple or a key function @@ -779,7 +777,7 @@ def submodule(self, gens, check=True, already_echelonized=False, `y_1 - x_1 - x_2`, and its basis elements are indexed by `0` and `1`:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x') sage: x = X.basis() sage: gens = [x[0] - x[1], x[1] - x[2]]; gens [x[0] - x[1], x[1] - x[2]] @@ -802,7 +800,7 @@ def submodule(self, gens, check=True, already_echelonized=False, submodule whose index set coincides with the index set of the family:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x') sage: x = X.basis() sage: gens = Family({1: x[0] - x[1], 3: x[1] - x[2]}); gens Finite family {1: x[0] - x[1], 3: x[1] - x[2]} @@ -827,7 +825,7 @@ def submodule(self, gens, check=True, already_echelonized=False, a basis (an explicit basis will be computed):: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x') sage: x = X.basis() sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]; gens [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]] @@ -942,7 +940,7 @@ def quotient_module(self, submodule, check=True, already_echelonized=False, cate EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x') sage: x = X.basis() sage: Y = X.quotient_module([x[0] - x[1], x[1] - x[2]], ....: already_echelonized=True) @@ -983,7 +981,7 @@ def tensor(*parents, **kwargs): EXAMPLES:: sage: C = AlgebrasWithBasis(QQ) - sage: A = C.example(); A.rename("A") # needs sage.combinat sage.modules + sage: A = C.example(); A.rename('A') # needs sage.combinat sage.modules sage: A.tensor(A, A) # needs sage.combinat sage.modules A # A # A sage: A.rename(None) # needs sage.combinat sage.modules @@ -1127,7 +1125,7 @@ def sum_of_monomials(self): INPUT: - - ``indices`` -- a list (or iterable) of indices of basis + - ``indices`` -- list (or iterable) of indices of basis elements EXAMPLES:: @@ -1170,9 +1168,7 @@ def term(self, index, coeff=None): - ``index`` -- the index of a basis element - ``coeff`` -- an element of the coefficient ring (default: one) - OUTPUT: - - ``coeff * B[index]``, where ``B`` is the basis of ``self``. + OUTPUT: ``coeff * B[index]``, where ``B`` is the basis of ``self`` EXAMPLES:: @@ -1193,7 +1189,7 @@ def sum_of_terms(self, terms): INPUT: - - ``terms`` -- a list (or iterable) of pairs ``(index, coeff)`` + - ``terms`` -- list (or iterable) of pairs ``(index, coeff)`` OUTPUT: @@ -1368,7 +1364,7 @@ def random_element(self, n=2): ALGORITHM: - Return a sum of ``n`` terms, each of which is formed by + Return a sum of `n` terms, each of which is formed by multiplying a random element of the base ring by a random element of the group. @@ -1409,7 +1405,6 @@ def random_element(self, n=2): sage: F = Foo(QQ, tuple(), category=C) # needs sage.modules sage: F.random_element() == F.zero() # needs sage.modules True - """ indices = self.basis().keys() a = self.zero() @@ -1440,9 +1435,9 @@ def monomial_coefficients(self, copy=True): INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally - represented by a dictionary ``d``, then make a copy of ``d``; - if ``False``, then this can cause undesired behavior by + - ``copy`` -- boolean (default: ``True``); if ``self`` is + internally represented by a dictionary ``d``, then make a copy of + ``d``; if ``False``, then this can cause undesired behavior by mutating ``d`` EXAMPLES:: @@ -1657,7 +1652,7 @@ def support(self): """ Return an iterable of the objects indexing the basis of ``self.parent()`` whose corresponding coefficients of - ``self`` are non-zero. + ``self`` are nonzero. This method returns these objects in an arbitrary order. @@ -1698,7 +1693,7 @@ def monomials(self): The monomials of an element `a` are defined to be the basis elements whose corresponding coefficients of `a` are - non-zero. + nonzero. EXAMPLES:: @@ -1717,7 +1712,7 @@ def monomials(self): def terms(self): """ - Return a list of the (non-zero) terms of ``self`` (in an + Return a list of the (nonzero) terms of ``self`` (in an arbitrary order). .. SEEALSO:: :meth:`monomials` @@ -1739,12 +1734,12 @@ def terms(self): def coefficients(self, sort=True): """ - Return a list of the (non-zero) coefficients appearing on + Return a list of the (nonzero) coefficients appearing on the basis elements in ``self`` (in an arbitrary order). INPUT: - - ``sort`` -- (default: ``True``) to sort the coefficients + - ``sort`` -- boolean (default: ``True``); to sort the coefficients based upon the default ordering of the indexing set .. SEEALSO:: @@ -1786,7 +1781,7 @@ def support_of_term(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename('X') # needs sage.modules sage: X.monomial(2).support_of_term() # needs sage.modules 2 sage: X.term(3, 2).support_of_term() # needs sage.modules @@ -1818,7 +1813,7 @@ def leading_support(self, *args, **kwds): sage: # needs sage.modules sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]) - sage: X.rename("X"); x = X.basis() + sage: X.rename('X'); x = X.basis() sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) sage: x.leading_support() 3 @@ -1853,7 +1848,7 @@ def leading_item(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) sage: x.leading_item() (3, 4) @@ -1883,7 +1878,7 @@ def leading_monomial(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.leading_monomial() B[3] @@ -1912,7 +1907,7 @@ def leading_coefficient(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.leading_coefficient() 1 @@ -1941,7 +1936,7 @@ def leading_term(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.leading_term() B[3] @@ -1967,7 +1962,7 @@ def trailing_support(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') # needs sage.modules sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) # needs sage.modules sage: x.trailing_support() # needs sage.modules 1 @@ -1998,7 +1993,7 @@ def trailing_item(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.trailing_item() (1, 3) @@ -2028,7 +2023,7 @@ def trailing_monomial(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.trailing_monomial() B[1] @@ -2057,7 +2052,7 @@ def trailing_coefficient(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.trailing_coefficient() 3 @@ -2086,7 +2081,7 @@ def trailing_term(self, *args, **kwds): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) sage: x.trailing_term() 3*B[1] @@ -2103,7 +2098,7 @@ def trailing_term(self, *args, **kwds): def map_coefficients(self, f, new_base_ring=None): """ - Return the element obtained by applying ``f`` to the non-zero + Return the element obtained by applying ``f`` to the nonzero coefficients of ``self``. If ``f`` is a :class:`sage.categories.map.Map`, then the resulting @@ -2167,7 +2162,6 @@ def map_coefficients(self, f, new_base_ring=None): 0 sage: B['a'].map_coefficients(lambda c: GF(2)(c), QQ) B['a'] - """ R = self.parent() if isinstance(f, Map): @@ -2334,8 +2328,8 @@ def __call_on_basis__(self, **options): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X') + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y') sage: H = Hom(X, Y) sage: x = X.basis() sage: def on_basis(i): @@ -2351,9 +2345,9 @@ def __call_on_basis__(self, **options): Diagonal functions can be constructed using the ``diagonal`` option:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename('X') sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], - ....: key="Y"); Y.rename("Y") + ....: key='Y'); Y.rename('Y') sage: H = Hom(X, Y) sage: x = X.basis() sage: phi = H(diagonal=lambda x: x^2) @@ -2374,8 +2368,8 @@ def __call_on_basis__(self, **options): We check that the homset category is properly set up:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X') + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y') sage: H = Hom(X, Y) sage: H.zero().category_for() Category of finite dimensional vector spaces with basis over Rational Field @@ -2397,8 +2391,8 @@ def on_basis(self): EXAMPLES:: sage: # needs sage.modules - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X') + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y') sage: H = Hom(X, Y) sage: x = X.basis() sage: f = H(lambda x: Y.zero()).on_basis() @@ -2423,7 +2417,7 @@ def _on_basis(self, i): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") # needs sage.modules + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X') # needs sage.modules sage: phi = End(X)(lambda x: 2*x) # needs sage.modules sage: phi._on_basis(3) # needs sage.modules 2*B[3] @@ -2496,13 +2490,13 @@ def extra_super_categories(self): class ParentMethods: """ - Implements operations on tensor products of modules with basis. + Implement operations on tensor products of modules with basis. """ pass class ElementMethods: """ - Implements operations on elements of tensor products of modules + Implement operations on elements of tensor products of modules with basis. """ @@ -2533,10 +2527,10 @@ def apply_multilinear_morphism(self, f, codomain=None): examples, with two modules `A` and `B`:: sage: # needs sage.modules - sage: A = CombinatorialFreeModule(ZZ, [1,2], prefix="A") - sage: A.rename("A") - sage: B = CombinatorialFreeModule(ZZ, [3,4], prefix="B") - sage: B.rename("B") + sage: A = CombinatorialFreeModule(ZZ, [1,2], prefix='A') + sage: A.rename('A') + sage: B = CombinatorialFreeModule(ZZ, [3,4], prefix='B') + sage: B.rename('B') and `f` the bilinear morphism `(a,b) \mapsto b \otimes a` from `A \times B` to `B \otimes A`:: @@ -2586,8 +2580,8 @@ def apply_multilinear_morphism(self, f, codomain=None): module with basis with a different base ring:: sage: # needs sage.modules - sage: C = CombinatorialFreeModule(QQ, [(1,3),(2,4)], prefix="C") - sage: C.rename("C") + sage: C = CombinatorialFreeModule(QQ, [(1,3),(2,4)], prefix='C') + sage: C.rename('C') sage: def f(a, b): ....: return C.sum_of_terms([((1,3), QQ(a[1]*b[3])), ....: ((2,4), QQ(a[2]*b[4]))]) diff --git a/src/sage/categories/monoids.py b/src/sage/categories/monoids.py index 654bb195172..877e9026199 100644 --- a/src/sage/categories/monoids.py +++ b/src/sage/categories/monoids.py @@ -94,7 +94,7 @@ def free(index_set=None, names=None, **kwds): - ``index_set`` -- (optional) an index set for the generators; if an integer, then this represents `\{0, 1, \ldots, n-1\}` - - ``names`` -- a string or list/tuple/iterable of strings + - ``names`` -- string or list/tuple/iterable of strings (default: ``'x'``); the generator names or name prefix EXAMPLES:: @@ -148,7 +148,7 @@ def prod(self, args): INPUT: - - ``args`` -- a list (or iterable) of elements of ``self`` + - ``args`` -- list (or iterable) of elements of ``self`` Returns the product of the elements in ``args``, as an element of ``self``. @@ -292,11 +292,11 @@ def is_one(self): def _pow_int(self, n): r""" - Return ``self`` to the `n^{th}` power. + Return ``self`` to the `n`-th power. INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -308,11 +308,11 @@ def _pow_int(self, n): def _pow_naive(self, n): r""" - Return ``self`` to the `n^{th}` power (naive implementation). + Return ``self`` to the `n`-th power (naive implementation). INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer This naive implementation does not use binary exponentiation; there are cases where this is actually @@ -411,7 +411,7 @@ def free(index_set=None, names=None, **kwds): - ``index_set`` -- (optional) an index set for the generators; if an integer, then this represents `\{0, 1, \ldots, n-1\}` - - ``names`` -- a string or list/tuple/iterable of strings + - ``names`` -- string or list/tuple/iterable of strings (default: ``'x'``); the generator names or name prefix EXAMPLES:: @@ -472,7 +472,7 @@ class ParentMethods: def one(self): """ - Returns the multiplicative unit of this monoid, + Return the multiplicative unit of this monoid, obtained by retracting that of the ambient monoid. EXAMPLES:: @@ -677,7 +677,7 @@ def lift(i, gen): gens_prod = cartesian_product([Family(M.monoid_generators(), lambda g: (i, g)) for i, M in enumerate(F)]) - return Family(gens_prod, lift, name="gen") + return Family(gens_prod, lift, name='gen') class ElementMethods: def multiplicative_order(self): diff --git a/src/sage/categories/morphism.pyx b/src/sage/categories/morphism.pyx index 30fe12271c3..34bcd1ca5f5 100644 --- a/src/sage/categories/morphism.pyx +++ b/src/sage/categories/morphism.pyx @@ -297,13 +297,12 @@ cdef class Morphism(Map): AssertionError: coercion from Univariate Polynomial Ring in x over Integer Ring to Univariate Polynomial Ring in z over Integer Ring already registered or discovered - """ self._codomain.register_coercion(self) def register_as_conversion(self): r""" - Register this morphism as a conversion to Sage's coercion model + Register this morphism as a conversion to Sage's coercion model. (see :mod:`sage.structure.coerce`). @@ -442,7 +441,6 @@ cdef class Morphism(Map): sage: f = Hom(ZZ,Zmod(1)).an_element() sage: bool(f) # indirect doctest False - """ try: return self._is_nonzero() @@ -575,7 +573,7 @@ cdef class SetMorphism(Morphism): - ``parent`` -- a Homset - ``function`` -- a Python function that takes elements - of the domain as input and returns elements of the codomain. + of the domain as input and returns elements of the codomain EXAMPLES:: @@ -628,7 +626,6 @@ cdef class SetMorphism(Morphism): sage: f(2,'hello world',test=1) # indirect doctest foo called with ('hello world',) {'test': 1} 2 - """ try: return self._function(x, *args, **kwds) @@ -637,11 +634,11 @@ cdef class SetMorphism(Morphism): cdef dict _extra_slots(self): """ - INPUT: + Extend the dictionary with extra slots for this class. - - ``_slots`` -- a dictionary + INPUT: - Extends the dictionary with extra slots for this class. + - ``_slots`` -- dictionary EXAMPLES:: @@ -661,7 +658,7 @@ cdef class SetMorphism(Morphism): """ INPUT: - - ``_slots`` -- a dictionary + - ``_slots`` -- dictionary Updates the slots of ``self`` from the data in the dictionary @@ -688,7 +685,7 @@ cdef class SetMorphism(Morphism): cpdef bint _eq_c_impl(self, Element other) noexcept: """ - Equality test + Equality test. EXAMPLES:: @@ -704,7 +701,6 @@ cdef class SetMorphism(Morphism): False sage: f._eq_c_impl(1) False - """ return isinstance(other, SetMorphism) and self.parent() == other.parent() and self._function == (other)._function @@ -712,9 +708,9 @@ cdef class SetMorphism(Morphism): """ INPUT: - - ``self`` -- SetMorphism + - ``self`` -- SetMorphism - ``right`` -- any object - - ``op`` -- integer + - ``op`` -- integer EXAMPLES:: @@ -751,7 +747,7 @@ cdef class SetIsomorphism(SetMorphism): - ``parent`` -- a Homset - ``function`` -- a Python function that takes elements - of the domain as input and returns elements of the codomain. + of the domain as input and returns elements of the codomain EXAMPLES:: @@ -802,13 +798,13 @@ cdef class SetIsomorphism(SetMorphism): raise RuntimeError('inverse morphism has not been set') return self._inverse - cdef dict _extra_slots(self) noexcept: + cdef dict _extra_slots(self): """ Extend the dictionary with extra slots for this class. INPUT: - - ``_slots`` -- a dictionary + - ``_slots`` -- dictionary EXAMPLES:: @@ -827,13 +823,13 @@ cdef class SetIsomorphism(SetMorphism): slots['_inverse'] = self._inverse return slots - cdef _update_slots(self, dict _slots) noexcept: + cdef _update_slots(self, dict _slots): """ Update the slots of ``self`` from the data in the dictionary. INPUT: - - ``_slots`` -- a dictionary + - ``_slots`` -- dictionary EXAMPLES:: diff --git a/src/sage/categories/noetherian_rings.py b/src/sage/categories/noetherian_rings.py index 231d3e8192c..fe0e80acc06 100644 --- a/src/sage/categories/noetherian_rings.py +++ b/src/sage/categories/noetherian_rings.py @@ -30,7 +30,7 @@ class NoetherianRings(Category): """ - The category of Noetherian rings + The category of Noetherian rings. A Noetherian ring is a commutative ring in which every ideal is finitely generated. diff --git a/src/sage/categories/number_fields.py b/src/sage/categories/number_fields.py index 8c6ed11d4c3..cc5571b5c07 100644 --- a/src/sage/categories/number_fields.py +++ b/src/sage/categories/number_fields.py @@ -96,7 +96,7 @@ def __contains__(self, x): def _call_(self, x): r""" Construct an object in this category from the data in ``x``, - or raise a :class:`TypeError`. + or raise a :exc:`TypeError`. EXAMPLES:: @@ -134,21 +134,22 @@ def zeta_function(self, prec=53, INPUT: - - ``prec`` -- optional integer (default 53) bits precision + - ``prec`` -- integer (default: 53); bits of precision - - ``max_imaginary_part`` -- optional real number (default 0) + - ``max_imaginary_part`` -- real (default: 0) - - ``max_asymp_coeffs`` -- optional integer (default 40) + - ``max_asymp_coeffs`` -- integer (default: 40) - - ``algorithm`` -- optional (default "pari") either "gp" or "pari" + - ``algorithm`` -- (default: ``'pari'``) either ``'gp'`` or + ``'pari'`` - OUTPUT: The zeta function of this number field. + OUTPUT: the zeta function of this number field - If algorithm is "gp", this returns an interface to Tim - Dokchitser's gp script for computing with L-functions. + If algorithm is ``'gp'``, this returns an interface to Tim + Dokchitser's gp script for computing with `L`-functions. - If algorithm is "pari", this returns instead an interface to Pari's - own general implementation of L-functions. + If algorithm is ``'pari'``, this returns instead an interface to Pari's + own general implementation of `L`-functions. EXAMPLES:: @@ -168,13 +169,13 @@ def zeta_function(self, prec=53, Using the algorithm "pari":: sage: K. = NumberField(ZZ['x'].0^2 + ZZ['x'].0 - 1) # needs sage.rings.number_field - sage: Z = K.zeta_function(algorithm="pari") # needs sage.rings.number_field sage.symbolic + sage: Z = K.zeta_function(algorithm='pari') # needs sage.rings.number_field sage.symbolic sage: Z(-1) # needs sage.rings.number_field sage.symbolic 0.0333333333333333 sage: x = polygen(QQ, 'x') sage: L. = NumberField([x^2 - 5, x^2 + 3, x^2 + 1]) # needs sage.rings.number_field - sage: Z = L.zeta_function(algorithm="pari") # needs sage.rings.number_field sage.symbolic + sage: Z = L.zeta_function(algorithm='pari') # needs sage.rings.number_field sage.symbolic sage: Z(5) # needs sage.rings.number_field sage.symbolic 1.00199015670185 diff --git a/src/sage/categories/objects.py b/src/sage/categories/objects.py index 3668827f5bd..bad56fcb0f8 100644 --- a/src/sage/categories/objects.py +++ b/src/sage/categories/objects.py @@ -41,7 +41,7 @@ class Objects(Category_singleton): def additional_structure(self): """ - Return ``None`` + Return ``None``. Indeed, by convention, the category of objects defines no additional structure. diff --git a/src/sage/categories/poor_man_map.py b/src/sage/categories/poor_man_map.py index ccbc32ecaca..3195f14bab8 100644 --- a/src/sage/categories/poor_man_map.py +++ b/src/sage/categories/poor_man_map.py @@ -17,9 +17,9 @@ class PoorManMap(sage.structure.sage_object.SageObject): """ - A class for maps between sets which are not (yet) modeled by parents + A class for maps between sets which are not (yet) modeled by parents. - Could possibly disappear when all combinatorial classes / enumerated sets will be parents + Could possibly disappear when all combinatorial classes / enumerated sets will be parents. INPUT: @@ -56,7 +56,6 @@ class PoorManMap(sage.structure.sage_object.SageObject): sage: h = PoorManMap(sqrt, domain=(1, 4, 9), codomain=(1, 2, 3)) sage: i == g*h True - """ def __init__(self, function, domain=None, codomain=None, name=None): """ @@ -68,7 +67,6 @@ def __init__(self, function, domain=None, codomain=None, name=None): sage: TestSuite(f).run() sage: TestSuite(f*g).run() - """ from collections.abc import Iterable if not isinstance(function, Iterable): @@ -91,15 +89,14 @@ def _repr_(self): A map from (1, 2, 3) sage: PoorManMap(lambda x: x+2, codomain=(3,4,5)) A map to (3, 4, 5) - """ return ((self._name if self._name is not None else "A map") + - (" from %s" % (self._domain,) if self._domain is not None else "" ) + - (" to %s" % (self._codomain,) if self._codomain is not None else "" )) + (" from %s" % (self._domain,) if self._domain is not None else "") + + (" to %s" % (self._codomain,) if self._codomain is not None else "")) def domain(self): """ - Returns the domain of ``self`` + Return the domain of ``self``. EXAMPLES:: @@ -111,7 +108,7 @@ def domain(self): def codomain(self): """ - Returns the codomain of ``self`` + Return the codomain of ``self``. EXAMPLES:: @@ -136,7 +133,6 @@ def __eq__(self, other): sage: h4 = PoorManMap(lambda x: x, domain=(1,2,3), codomain=(1,2,6)) sage: f == g, f == h1, f == h2, f == h3, f == h4, f == 1, 1 == f (True, False, False, False, False, False, False) - """ if isinstance(other, PoorManMap): return (self._functions == other._functions @@ -161,7 +157,6 @@ def __ne__(self, other): sage: h4 = PoorManMap(lambda x: x, domain=(1,2,3), codomain=(1,2,6)) sage: f != g, f != h1, f != h2, f != h3, f != h4, f != 1, 1 != f (False, True, True, True, True, True, True) - """ return not (self == other) @@ -176,20 +171,19 @@ def __hash__(self): sage: g = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) sage: hash(f) == hash(g) True - """ return hash((self._functions, self._domain, self._codomain, self._name)) def __mul__(self, other): r""" - Composition + Composition. INPUT: - - ``self`` -- a map `f` - - ``other`` -- a map `g` + - ``self`` -- a map `f` + - ``other`` -- a map `g` - Returns the composition map `f\circ g` of `f`` and `g` + Returns the composition map `f\circ g` of `f` and `g` EXAMPLES:: @@ -256,7 +250,6 @@ def __call__(self, *args): sage: g = PoorManMap(lambda x: -x, domain=(2,3,4), codomain=(-2,-3,-4)) sage: (g*f)(2) -3 - """ for function in reversed(self._functions): args = [function(*args)] diff --git a/src/sage/categories/posets.py b/src/sage/categories/posets.py index 0d846648e6f..9b30798d0d4 100644 --- a/src/sage/categories/posets.py +++ b/src/sage/categories/posets.py @@ -88,7 +88,6 @@ class Posets(Category): sage: C = Posets() sage: TestSuite(C).run() - """ @cached_method def super_categories(self): @@ -165,7 +164,7 @@ def le(self, x, y): INPUT: - - ``x``, ``y`` -- elements of ``self``. + - ``x``, ``y`` -- elements of ``self`` EXAMPLES:: @@ -184,7 +183,7 @@ def lt(self, x, y): INPUT: - - ``x``, ``y`` -- elements of ``self``. + - ``x``, ``y`` -- elements of ``self`` This default implementation delegates the work to :meth:`le`. @@ -206,7 +205,7 @@ def ge(self, x, y): INPUT: - - ``x``, ``y`` -- elements of ``self``. + - ``x``, ``y`` -- elements of ``self`` This default implementation delegates the work to :meth:`le`. @@ -228,7 +227,7 @@ def gt(self, x, y): INPUT: - - ``x``, ``y`` -- elements of ``self``. + - ``x``, ``y`` -- elements of ``self`` This default implementation delegates the work to :meth:`lt`. @@ -310,17 +309,17 @@ def directed_subset(self, elements, direction): Return the order filter or the order ideal generated by a list of elements. - If ``direction`` is 'up', the order filter (upper set) is + If ``direction`` is ``'up'``, the order filter (upper set) is being returned. - If ``direction`` is 'down', the order ideal (lower set) is + If ``direction`` is ``'down'``, the order ideal (lower set) is being returned. INPUT: - - elements -- a list of elements. + - ``elements`` -- list of elements - - direction -- 'up' or 'down'. + - ``direction`` -- ``'up'`` or ``'down'`` EXAMPLES:: @@ -456,7 +455,7 @@ def is_order_ideal(self, o): INPUT: - - ``o`` -- a list (or set, or tuple) containing some elements of ``self`` + - ``o`` -- list (or set, or tuple) containing some elements of ``self`` EXAMPLES:: @@ -472,7 +471,6 @@ def is_order_ideal(self, o): True sage: P.is_order_ideal([1, 3, 4]) False - """ return all((u in self and all(x in o for x in self.lower_covers(u))) for u in o) @@ -483,7 +481,7 @@ def is_order_filter(self, o): INPUT: - - ``o`` -- a list (or set, or tuple) containing some elements of ``self`` + - ``o`` -- list (or set, or tuple) containing some elements of ``self`` EXAMPLES:: @@ -499,7 +497,6 @@ def is_order_filter(self, o): False sage: P.is_order_filter({3, 6, 12}) True - """ return all((u in self and all(x in o for x in self.upper_covers(u))) for u in o) @@ -515,9 +512,8 @@ def is_chain_of_poset(self, o, ordered=False): - ``o`` -- an iterable (e. g., list, set, or tuple) containing some elements of ``self`` - - ``ordered`` -- a Boolean (default: ``False``) which - decides whether the notion of a chain includes being - ordered + - ``ordered`` -- a Boolean (default: ``False``); decides + whether the notion of a chain includes being ordered OUTPUT: diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index aa8b134ac23..dbae2b41049 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -58,7 +58,7 @@ - Thousands of different kinds of objects (classes): Integers, polynomials, matrices, groups, number fields, elliptic - curves, permutations, morphisms, languages, ... and a few racoons ... + curves, permutations, morphisms, languages, ... and a few raccoons ... - Tens of thousands methods and functions: @@ -118,7 +118,7 @@ What makes binary powering work in the above examples? In both cases, we have *a set* endowed with a *multiplicative binary operation* which is *associative* and which has a unit element. Such a set is called a -*monoid*, and binary powering (to a non-negative power) works generally +*monoid*, and binary powering (to a nonnegative power) works generally for any monoid. Sage knows about monoids:: @@ -193,7 +193,7 @@ Those can be viewed graphically:: sage: g = Groups().category_graph() # needs sage.graphs - sage: g.set_latex_options(format="dot2tex") # needs sage.graphs sage.modules sage.plot + sage: g.set_latex_options(format='dot2tex') # needs sage.graphs sage.modules sage.plot sage: view(g) # not tested # needs sage.graphs sage.modules sage.plot In case ``dot2tex`` is not available, you can use instead:: @@ -203,7 +203,7 @@ Here is an overview of all categories in Sage:: sage: g = sage.categories.category.category_graph() # needs sage.graphs sage.groups sage.modules - sage: g.set_latex_options(format="dot2tex") # needs sage.graphs sage.modules sage.plot + sage: g.set_latex_options(format='dot2tex') # needs sage.graphs sage.modules sage.plot sage: view(g) # not tested # needs sage.graphs sage.modules sage.plot Wrap-up: generic algorithms in Sage are organized in a hierarchy of @@ -379,7 +379,7 @@ Category of objects] sage: g = EuclideanDomains().category_graph() # needs sage.graphs - sage: g.set_latex_options(format="dot2tex") # needs sage.graphs sage.plot + sage: g.set_latex_options(format='dot2tex') # needs sage.graphs sage.plot sage: view(g) # not tested # needs sage.graphs sage.plot A bit of help from computer science @@ -498,7 +498,7 @@ class implements: The full hierarchy is best viewed graphically:: sage: g = class_graph(m.__class__) # needs sage.combinat sage.graphs - sage: g.set_latex_options(format="dot2tex") # needs sage.combinat sage.graphs sage.plot + sage: g.set_latex_options(format='dot2tex') # needs sage.combinat sage.graphs sage.plot sage: view(g) # not tested # needs sage.combinat sage.graphs sage.plot Parallel hierarchy of classes for parents @@ -554,7 +554,7 @@ class implements: sage: # needs sage.combinat sage.graphs sage.modules sage.plot sage: g = class_graph(m.__class__) sage: g.relabel(lambda x: x.replace("_",r"\_")) - sage: g.set_latex_options(format="dot2tex") + sage: g.set_latex_options(format='dot2tex') sage: view(g) # not tested .. NOTE:: @@ -1114,8 +1114,8 @@ class SubcategoryMethods: Let for example `A` and `B` be two parents, and let us construct the Cartesian product `A \times B \times B`:: - sage: A = AlgebrasWithBasis(QQ).example(); A.rename("A") # needs sage.combinat sage.modules - sage: B = HopfAlgebrasWithBasis(QQ).example(); B.rename("B") # needs sage.groups sage.modules + sage: A = AlgebrasWithBasis(QQ).example(); A.rename('A') # needs sage.combinat sage.modules + sage: B = HopfAlgebrasWithBasis(QQ).example(); B.rename('B') # needs sage.groups sage.modules sage: C = cartesian_product([A, B, B]); C # needs sage.combinat sage.groups sage.modules A (+) B (+) B @@ -1277,7 +1277,7 @@ class naming and introspection. Sage currently works around the The meaning of each axiom is described in the documentation of the corresponding method, which can be obtained as usual by -instrospection:: +introspection:: sage: C = Groups() sage: C.Finite? # not tested @@ -1368,7 +1368,7 @@ class naming and introspection. Sage currently works around the How far should this be pushed? :class:`Fields` should definitely stay, but should :class:`FiniteGroups` or :class:`DivisionRings` be removed from the global namespace? Do we want to further - completely deprecate the notation ``FiniteGroups()` in favor of + completely deprecate the notation ``FiniteGroups()`` in favor of ``Groups().Finite()``? .. _category-primer-axioms-explosion: @@ -1405,7 +1405,7 @@ class naming and introspection. Sage currently works around the or for more advanced categories:: sage: g = HopfAlgebras(QQ).WithBasis().Graded().Connected().category_graph() # needs sage.graphs - sage: g.set_latex_options(format="dot2tex") # needs sage.graphs sage.plot + sage: g.set_latex_options(format='dot2tex') # needs sage.graphs sage.plot sage: view(g) # not tested # needs sage.graphs sage.plot Difference between axioms and regressive covariant functorial constructions diff --git a/src/sage/categories/principal_ideal_domains.py b/src/sage/categories/principal_ideal_domains.py index 89c25cc374f..c86d4f6ddf7 100644 --- a/src/sage/categories/principal_ideal_domains.py +++ b/src/sage/categories/principal_ideal_domains.py @@ -15,7 +15,7 @@ class PrincipalIdealDomains(Category_singleton): """ - The category of (constructive) principal ideal domains + The category of (constructive) principal ideal domains. By constructive, we mean that a single generator can be constructively found for any ideal given by a finite set of diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 1b98e358511..b67f37ed524 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -123,7 +123,6 @@ class ConstructionFunctor(Functor): b |--> a - b sage: F(f)(F(A)(x)*a) (a + b)*x - """ def __mul__(self, other): """ @@ -151,7 +150,6 @@ def __mul__(self, other): True sage: F*I is F True - """ if not isinstance(self, ConstructionFunctor) and not isinstance(other, ConstructionFunctor): raise CoercionException("Non-constructive product") @@ -179,7 +177,6 @@ def pushout(self, other): Poly[t](FractionField(...)) sage: P.pushout(F) Poly[t](FractionField(...)) - """ if self.rank > other.rank: return self * other @@ -253,7 +250,6 @@ def _repr_(self): sage: Q = ZZ.quo(2).construction()[0] sage: Q # indirect doctest QuotientFunctor - """ s = str(type(self)) import re @@ -278,7 +274,6 @@ def merge(self, other): sage: P.merge(F) sage: P.merge(P) Poly[t] - """ if self == other: return self @@ -307,7 +302,6 @@ def commutes(self, other): False sage: F.commutes(F) False - """ return False @@ -331,7 +325,6 @@ def expand(self): sage: FP = F*P sage: FP.expand() [FractionField, Poly[t]] - """ return [self] @@ -351,12 +344,12 @@ def common_base(self, other_functor, self_bases, other_bases): INPUT: - - ``other_functor`` -- a construction functor. + - ``other_functor`` -- a construction functor - - ``self_bases`` -- the arguments passed to this functor. + - ``self_bases`` -- the arguments passed to this functor - ``other_bases`` -- the arguments passed to the functor - ``other_functor``. + ``other_functor`` OUTPUT: @@ -389,14 +382,14 @@ def _raise_common_base_exception_(self, other_functor, INPUT: - - ``other_functor`` -- a functor. + - ``other_functor`` -- a functor - - ``self_bases`` -- the arguments passed to this functor. + - ``self_bases`` -- the arguments passed to this functor - ``other_bases`` -- the arguments passed to the functor - ``other_functor``. + ``other_functor`` - - ``reason`` -- a string or ``None`` (default). + - ``reason`` -- string or ``None`` (default) TESTS:: @@ -428,8 +421,8 @@ class CompositeConstructionFunctor(ConstructionFunctor): INPUT: - ``F1, F2,...``: A list of Construction Functors. The result is the - composition ``F1`` followed by ``F2`` followed by ... + - ``F1, F2,...`` -- a list of Construction Functors. The result is the + composition ``F1`` followed by ``F2`` followed by ... EXAMPLES:: @@ -459,7 +452,6 @@ def __init__(self, *args): Poly[y](FractionField(Poly[x](FractionField(...)))) sage: F == CompositeConstructionFunctor(*F.all) True - """ self.all = [] for c in args: @@ -491,7 +483,6 @@ def _apply_functor_to_morphism(self, f): Ring endomorphism of Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field Defn: a |--> a + b b |--> a - b - """ for c in self.all: f = c(f) @@ -508,7 +499,6 @@ def _apply_functor(self, R): sage: R. = QQ[] sage: F(R) # indirect doctest Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field - """ for c in self.all: R = c(R) @@ -545,7 +535,7 @@ def __ne__(self, other): def __mul__(self, other): """ - Compose construction functors to a composit construction functor, unless one of them is the identity. + Compose construction functors to a composite construction functor, unless one of them is the identity. .. NOTE:: @@ -559,7 +549,6 @@ def __mul__(self, other): sage: F2 = CompositeConstructionFunctor(QQ.construction()[0],ZZ['y'].construction()[0]) sage: F1*F2 Poly[x](FractionField(Poly[y](FractionField(...)))) - """ if isinstance(self, CompositeConstructionFunctor): all = [other] + self.all @@ -577,7 +566,6 @@ def _repr_(self): sage: F = CompositeConstructionFunctor(QQ.construction()[0],ZZ['x'].construction()[0],QQ.construction()[0],ZZ['y'].construction()[0]) sage: F # indirect doctest Poly[y](FractionField(Poly[x](FractionField(...)))) - """ s = "..." for c in self.all: @@ -604,7 +592,6 @@ def expand(self): Poly[y](FractionField(Poly[x](FractionField(...)))) sage: prod(F.expand()) == F True - """ return list(reversed(self.all)) @@ -621,7 +608,6 @@ class IdentityConstructionFunctor(ConstructionFunctor): True sage: I == loads(dumps(I)) True - """ rank = -100 @@ -635,7 +621,6 @@ def __init__(self): True sage: I(RR) is RR True - """ from sage.categories.sets_cat import Sets ConstructionFunctor.__init__(self, Sets(), Sets()) @@ -703,7 +688,7 @@ def __ne__(self, other): def __mul__(self, other): """ - Compose construction functors to a composit construction functor, unless one of them is the identity. + Compose construction functors to a composite construction functor, unless one of them is the identity. .. NOTE:: @@ -724,7 +709,6 @@ def __mul__(self, other): True sage: P*I is P True - """ if isinstance(self, IdentityConstructionFunctor): return other @@ -759,16 +743,14 @@ def common_base(self, other_functor, self_bases, other_bases): INPUT: - - ``other_functor`` -- a construction functor. + - ``other_functor`` -- a construction functor - - ``self_bases`` -- the arguments passed to this functor. + - ``self_bases`` -- the arguments passed to this functor - ``other_bases`` -- the arguments passed to the functor - ``other_functor``. - - OUTPUT: + ``other_functor`` - A parent. + OUTPUT: a parent If no common base is found a :class:`sage.structure.coerce_exceptions.CoercionException` is raised. @@ -840,7 +822,6 @@ class PolynomialFunctor(ConstructionFunctor): Univariate Polynomial Ring in x over Finite Field of size 5 sage: (S.0 + R.0).parent().is_sparse() False - """ rank = 9 @@ -861,7 +842,6 @@ def __init__(self, var, multi_variate=False, sparse=False, implementation=None): Univariate Polynomial Ring in x over Integer Ring sage: Q == P True - """ from .rings import Rings Functor.__init__(self, Rings(), Rings()) @@ -879,7 +859,6 @@ def _apply_functor(self, R): sage: P = ZZ['x'].construction()[0] sage: P(GF(3)) # indirect doctest Univariate Polynomial Ring in x over Finite Field of size 3 - """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing kwds = {} @@ -973,7 +952,6 @@ def merge(self, other): sage: P.merge(Q) sage: P.merge(P) is P True - """ if isinstance(other, MultiPolynomialFunctor): return other.merge(self) @@ -992,7 +970,6 @@ def _repr_(self): sage: P = ZZ['x'].construction()[0] sage: P # indirect doctest Poly[x] - """ return "Poly[%s]" % self.var @@ -1020,7 +997,6 @@ class MultiPolynomialFunctor(ConstructionFunctor): b |--> a - b sage: F(f)(F(A)(x)*a) (a + b)*x - """ rank = 9 @@ -1278,7 +1254,6 @@ class InfinitePolynomialFunctor(ConstructionFunctor): w_2 + z_3 sage: _.parent() is P True - """ # We do provide merging with polynomial rings. However, it seems that it is better @@ -1295,7 +1270,6 @@ def __init__(self, gens, order, implementation): InfPoly{[a,b,x], "degrevlex", "sparse"} sage: F == loads(dumps(F)) True - """ if not gens: raise ValueError("Infinite Polynomial Rings have at least one generator") @@ -1330,7 +1304,6 @@ def _apply_functor(self, R): InfPoly{[a,b,x], "degrevlex", "sparse"} sage: F(QQ['t']) # indirect doctest Infinite polynomial ring in a, b, x over Univariate Polynomial Ring in t over Rational Field - """ from sage.rings.polynomial.infinite_polynomial_ring import ( InfinitePolynomialRing, @@ -1343,7 +1316,6 @@ def _repr_(self): sage: F = sage.categories.pushout.InfinitePolynomialFunctor(['a','b','x'],'degrevlex','sparse'); F # indirect doctest InfPoly{[a,b,x], "degrevlex", "sparse"} - """ return 'InfPoly{[%s], "%s", "%s"}' % (','.join(self._gens), self._order, self._imple) @@ -1405,7 +1377,6 @@ def __mul__(self, other): sage: F4 = sage.categories.pushout.FractionField() sage: F2*F4 InfPoly{[x,y], "degrevlex", "dense"}(FractionField(...)) - """ if isinstance(other, IdentityConstructionFunctor): return self @@ -1449,10 +1420,10 @@ def __mul__(self, other): if x.count('_') == 1: g, n = x.split('_') if n.isdigit(): - if g.isalnum(): # we can interprete x in any InfinitePolynomialRing - if g in self._gens: # we can interprete x in self, hence, we will not use it as a variable anymore. + if g.isalnum(): # we can interpret x in any InfinitePolynomialRing + if g in self._gens: # we can interpret x in self, hence, we will not use it as a variable anymore. RemainingVars.pop(RemainingVars.index(x)) - IsOverlap = True # some variables of other can be interpreted in self. + IsOverlap = True # some variables of other can be interpreted in self. if OverlappingVars: # Is OverlappingVars in the right order? g0, n0 = OverlappingVars[-1].split('_') @@ -1510,7 +1481,6 @@ def merge(self, other): x_2 + y_3 sage: _.parent().construction() [InfPoly{[x,y], "degrevlex", "dense"}, Rational Field] - """ # Merging is only done if the ranks of self and other are the same. # It may happen that other is a substructure of self up to the monomial order @@ -1565,7 +1535,6 @@ def expand(self): InfPoly{[x], "degrevlex", "dense"}] sage: prod(F.expand())==F True - """ if len(self._gens) == 1: return [self] @@ -1603,7 +1572,6 @@ class MatrixFunctor(ConstructionFunctor): sage: F(f)(M) [ x + y x - y] [x^2 - y^2 2*x] - """ rank = 10 @@ -1652,7 +1620,6 @@ def _apply_functor(self, R): Full MatrixSpace of 2 by 3 dense matrices over Real Field with 53 bits of precision sage: F(RR) in F.codomain() # needs sage.modules True - """ from sage.matrix.matrix_space import MatrixSpace return MatrixSpace(R, self.nrows, self.ncols, sparse=self.is_sparse) @@ -1711,7 +1678,6 @@ def merge(self, other): True sage: F3.merge(F3).is_sparse True - """ if self != other: return None @@ -1746,7 +1712,6 @@ class LaurentPolynomialFunctor(ConstructionFunctor): y |--> 3*x - y sage: F(f)(x*F(P).gen()^-2 + y*F(P).gen()^3) (x + 2*y)*t^-2 + (3*x - y)*t^3 - """ rank = 9 @@ -1754,10 +1719,10 @@ def __init__(self, var, multi_variate=False): """ INPUT: - - ``var``, a string or a list of strings - - ``multi_variate``, optional bool, default ``False`` if ``var`` is a string - and ``True`` otherwise: If ``True``, application to a Laurent polynomial - ring yields a multivariate Laurent polynomial ring. + - ``var`` -- string or list of strings + - ``multi_variate`` -- boolean (default: ``False``); if ``var`` is a + string and ``True`` otherwise: If ``True``, application to a Laurent + polynomial ring yields a multivariate Laurent polynomial ring. TESTS:: @@ -1772,7 +1737,6 @@ def __init__(self, var, multi_variate=False): Multivariate Laurent Polynomial Ring in t, s over Rational Field sage: F3(QQ) # needs sage.modules Multivariate Laurent Polynomial Ring in s, t over Rational Field - """ Functor.__init__(self, Rings(), Rings()) if not isinstance(var, (str, tuple, list)): @@ -1797,7 +1761,6 @@ def _apply_functor(self, R): Multivariate Laurent Polynomial Ring in t, s over Rational Field sage: F3(QQ) # needs sage.modules Multivariate Laurent Polynomial Ring in s, t over Rational Field - """ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing from sage.rings.polynomial.laurent_polynomial_ring_base import ( @@ -1870,7 +1833,6 @@ def merge(self, other): sage: F1.merge(F1)(LaurentPolynomialRing(GF(2), 'a')) Univariate Laurent Polynomial Ring in t over Univariate Laurent Polynomial Ring in a over Finite Field of size 2 - """ if self == other or isinstance(other, PolynomialFunctor) and self.var == other.var: return LaurentPolynomialFunctor(self.var, (self.multi_variate or other.multi_variate)) @@ -1901,11 +1863,12 @@ def __init__(self, n=None, is_sparse=False, inner_product_matrix=None, *, """ INPUT: - - ``n``, the rank of the to-be-created modules (non-negative integer) - - ``is_sparse`` (optional bool, default ``False``), create sparse implementation of modules - - ``inner_product_matrix``: ``n`` by ``n`` matrix, used to compute inner products in the + - ``n`` -- the rank of the to-be-created modules (nonnegative integer) + - ``is_sparse`` -- boolean (default: ``False``); create sparse + implementation of modules + - ``inner_product_matrix`` -- ``n`` by ``n`` matrix, used to compute inner products in the to-be-created modules - - ``name_mapping``, ``latex_name_mapping``: Dictionaries from base rings to names + - ``name_mapping``, ``latex_name_mapping`` -- Dictionaries from base rings to names - other keywords: see :func:`~sage.modules.free_module.FreeModule` TESTS:: @@ -1929,7 +1892,6 @@ def __init__(self, n=None, is_sparse=False, inner_product_matrix=None, *, sage: M2 = F2(QQ); M2; M2.is_sparse() Sparse vector space of dimension 3 over Rational Field True - """ # Functor.__init__(self, Rings(), FreeModules()) # FreeModules() takes a base ring # Functor.__init__(self, Objects(), Objects()) # Object() makes no sense, since FreeModule raises an error, e.g., on Set(['a',1]). @@ -1979,18 +1941,17 @@ def _apply_functor(self, R): sage: M_QQ = pushout(M, QQ) sage: latex(M_QQ) M \otimes \Bold{Q} - """ from sage.modules.free_module import FreeModule name = self.name_mapping.get(R, None) latex_name = self.latex_name_mapping.get(R, None) if name is None: - for base_ring, name in self.name_mapping.items(): + for name in self.name_mapping.values(): name = f'{name}_base_ext' break if latex_name is None: from sage.misc.latex import latex - for base_ring, latex_name in self.latex_name_mapping.items(): + for latex_name in self.latex_name_mapping.values(): latex_name = fr'{latex_name} \otimes {latex(R)}' break if name is None and latex_name is None: @@ -2214,7 +2175,6 @@ class SubspaceFunctor(ConstructionFunctor): User basis matrix: [1 0 1] [0 1 0] - """ rank = 11 # ranking of functor, not rank of module @@ -2226,7 +2186,7 @@ def __init__(self, basis): """ INPUT: - ``basis``: a list of elements of a free module. + - ``basis`` -- list of elements of a free module TESTS:: @@ -2340,7 +2300,6 @@ def __eq__(self, other): sage: F1 == F4 == F3 # needs sage.modules True - """ if not isinstance(other, SubspaceFunctor): return False @@ -2411,7 +2370,6 @@ def merge(self, other): [1 0 0] [0 1 0] [0 0 1] - """ if isinstance(other, SubspaceFunctor): # in order to remove linear dependencies, and in @@ -2466,7 +2424,6 @@ class FractionField(ConstructionFunctor): 1/(x + 2*y) sage: F == loads(dumps(F)) True - """ rank = 5 @@ -2540,7 +2497,6 @@ class CompletionFunctor(ConstructionFunctor): (1 + O(5^20))*a + 1 + O(5^40) sage: 1/2 + a (1 + O(5^20))*a + 3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 2*5^8 + 2*5^9 + 2*5^10 + 2*5^11 + 2*5^12 + 2*5^13 + 2*5^14 + 2*5^15 + 2*5^16 + 2*5^17 + 2*5^18 + 2*5^19 + O(5^20) - """ rank = 4 _real_types = ['Interval', 'Ball', 'MPFR', 'RDF', 'RLF', 'RR'] @@ -2550,14 +2506,15 @@ def __init__(self, p, prec, extras=None): """ INPUT: - - ``p``: A prime number, the generator of a univariate polynomial ring, or ``+Infinity`` + - ``p`` -- prime number, the generator of a univariate polynomial ring, + or ``+Infinity`` - - ``prec``: an integer, yielding the precision in bits. Note that + - ``prec`` -- integer; yielding the precision in bits. Note that if ``p`` is prime then the ``prec`` is the *capped* precision, while it is the *set* precision if ``p`` is ``+Infinity``. In the ``lattice-cap`` precision case, ``prec`` will be a tuple instead. - - ``extras`` (optional dictionary): Information on how to print elements, etc. + - ``extras`` -- dictionary (optional); information on how to print elements, etc. If 'type' is given as a key, the corresponding value should be a string among the following: @@ -2629,7 +2586,6 @@ def _apply_functor(self, R): True sage: F1(QQ) 5-adic Field with capped relative precision 20 - """ try: if not self.extras: @@ -2900,15 +2856,15 @@ def __init__(self, I, names=None, as_field=False, domain=None, """ INPUT: - - ``I``, an ideal (the modulus) - - ``names`` (optional string or list of strings), the names for the + - ``I`` -- an ideal (the modulus) + - ``names`` -- string or list of strings (optional); the names for the quotient ring generators - - ``as_field`` (optional bool, default false), return the quotient - ring as field (if available). - - ``domain`` (optional category, default ``Rings()``), the domain of - this functor. - - ``codomain`` (optional category, default ``Rings()``), the codomain - of this functor. + - ``as_field`` -- boolean (default: ``False``); return the quotient + ring as field (if available) + - ``domain`` -- category (default: ``Rings()``); the domain of + this functor + - ``codomain`` -- category (default: ``Rings()``); the codomain + of this functor - Further named arguments. In particular, an implementation of the quotient can be suggested here. These named arguments are passed to the quotient construction. @@ -2937,7 +2893,6 @@ def __init__(self, I, names=None, as_field=False, domain=None, sage: F = QuotientFunctor([5] * ZZ) sage: F(ZZ) Ring of integers modulo 5 - """ if domain is None: domain = Rings() @@ -3075,7 +3030,6 @@ def merge(self, other): sage: pushout(GF(5), Integers(5)) # needs sage.libs.pari Finite Field of size 5 - """ if type(self) is not type(other): return None @@ -3101,13 +3055,11 @@ def merge(self, other): codomain = self.codomain().join([self.codomain(), other.codomain()]) # Get the optional arguments: as_field = self.as_field or other.as_field - kwds = {} - for k,v in self.kwds.items(): - kwds[k] = v - for k,v in other.kwds.items(): + kwds = dict(self.kwds) + for k, v in other.kwds.items(): if k == 'category': if kwds[k] is not None: - kwds[k] = v.join([v,kwds[k]]) + kwds[k] = v.join([v, kwds[k]]) else: kwds[k] = v continue @@ -3205,7 +3157,6 @@ class AlgebraicExtensionFunctor(ConstructionFunctor): Residue field of Integers modulo 17 sage: F(CyclotomicField(49)) Residue field in zbar of Fractional ideal (17) - """ rank = 3 @@ -3235,11 +3186,11 @@ def __init__(self, polys, names, embeddings=None, structures=None, cyclotomic field, rather than just a number field. - ``precs`` -- (optional) list of integers. If it is provided, - it is used to determine the precision of p-adic extensions. + it is used to determine the precision of `p`-adic extensions. - ``implementations`` -- (optional) list of strings. If it is provided, it is used to determine an implementation in the - p-adic case. + `p`-adic case. - ``residue`` -- (optional) prime ideal of an order in a number field, determining a residue field. If it is provided, @@ -3390,7 +3341,6 @@ def _apply_functor(self, R): sage: AEF = AlgebraicExtensionFunctor([a^2 - 3], ['a'], [None]) sage: AEF(K) 3-adic Eisenstein Extension Field in a defined by a^2 - 3 - """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -3466,7 +3416,7 @@ def merge(self, other): INPUT: - - ``other`` -- Construction Functor. + - ``other`` -- Construction Functor OUTPUT: @@ -3552,7 +3502,6 @@ def merge(self, other): CoercionException: ('Ambiguous Base Extension', Number Field in a with defining polynomial x^3 - 2 with a = -0.6299605249474365? + 1.091123635971722?*I, Number Field in b with defining polynomial x^6 - 2 with b = 1.122462048309373?) - """ if isinstance(other, AlgebraicClosureFunctor): return other @@ -3627,7 +3576,6 @@ def __mul__(self, other): sage: F, R = L.construction() sage: prod(F.expand())(R) == L #indirect doctest True - """ if isinstance(other, IdentityConstructionFunctor): return self @@ -3693,7 +3641,6 @@ class AlgebraicClosureFunctor(ConstructionFunctor): Complex Field with 53 bits of precision sage: F(F(QQ)) is F(QQ) True - """ rank = 3 @@ -3709,7 +3656,6 @@ def __init__(self): Complex Field with 53 bits of precision sage: F == loads(dumps(F)) True - """ Functor.__init__(self, Rings(), Rings()) @@ -3745,7 +3691,6 @@ def merge(self, other): True sage: CDF.construction()[0].merge(CDF.construction()[0]) # needs sage.rings.complex_double AlgebraicClosureFunctor - """ if self == other: return self @@ -4030,7 +3975,6 @@ def _apply_functor(self, R): sage: F = BlackBoxConstructionFunctor(f) sage: F(ZZ) # indirect doctest # needs sage.modules Ambient free module of rank 2 over the principal ideal domain Integer Ring - """ return self.box(R) @@ -4651,7 +4595,6 @@ def pushout_lattice(R, S): AUTHOR: - Robert Bradshaw - """ R_tower = construction_tower(R) S_tower = construction_tower(S) @@ -4804,7 +4747,7 @@ def construction_tower(R): INPUT: - An object + - ``R`` -- an object OUTPUT: @@ -4822,7 +4765,6 @@ def construction_tower(R): of Univariate Polynomial Ring in t over Rational Field), (FractionField, Univariate Polynomial Ring in t over Rational Field), (Poly[t], Rational Field), (FractionField, Integer Ring)] - """ tower = [(None, R)] c = R.construction() @@ -4844,11 +4786,10 @@ def expand_tower(tower): INPUT: - A construction tower as returned by :func:`construction_tower`. + - ``tower`` -- a construction tower as returned by + :func:`construction_tower` - OUTPUT: - - A new construction tower with all the construction functors expanded. + OUTPUT: a new construction tower with all the construction functors expanded EXAMPLES:: @@ -4884,11 +4825,9 @@ def type_to_parent(P): INPUT: - A type - - OUTPUT: + - ``P`` -- a type - A Sage parent structure corresponding to the given type + OUTPUT: a Sage parent structure corresponding to the given type TESTS:: diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index ba6476ee89c..76f0570a819 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -18,7 +18,7 @@ class QuotientFields(Category_singleton): """ - The category of quotient fields over an integral domain + The category of quotient fields over an integral domain. EXAMPLES:: @@ -57,7 +57,7 @@ def denominator(self): @coerce_binop def gcd(self, other): """ - Greatest common divisor + Greatest common divisor. .. NOTE:: @@ -141,7 +141,7 @@ def gcd(self, other): @coerce_binop def lcm(self, other): """ - Least common multiple + Least common multiple. In a field, the least common multiple is not very informative, as it is only determined up to a unit. But in the fraction field of an @@ -343,12 +343,10 @@ def factor(self, *args, **kwds): INPUT: - - ``*args`` -- Arbitrary arguments suitable over the base ring - - ``**kwds`` -- Arbitrary keyword arguments suitable over the base ring + - ``*args`` -- arbitrary arguments suitable over the base ring + - ``**kwds`` -- arbitrary keyword arguments suitable over the base ring - OUTPUT: - - - Factorization of ``self`` over the base ring + OUTPUT: factorization of ``self`` over the base ring EXAMPLES:: @@ -380,9 +378,7 @@ def partial_fraction_decomposition(self, decompose_powers=True): whether to decompose prime power denominators as opposed to having a single term for each irreducible factor of the denominator - OUTPUT: - - Partial fraction decomposition of ``self`` over the base ring. + OUTPUT: partial fraction decomposition of ``self`` over the base ring AUTHORS: @@ -632,7 +628,7 @@ def derivative(self, *args): def _derivative(self, var=None): r""" - Returns the derivative of this rational function with respect to the + Return the derivative of this rational function with respect to the variable ``var``. Over a ring with a working gcd implementation, the derivative of a @@ -642,11 +638,9 @@ def _derivative(self, var=None): INPUT: - - ``var`` -- Variable with respect to which the derivative is computed - - OUTPUT: + - ``var`` -- variable with respect to which the derivative is computed - - Derivative of ``self`` with respect to ``var`` + OUTPUT: derivative of ``self`` with respect to ``var`` .. SEEALSO:: diff --git a/src/sage/categories/quotients.py b/src/sage/categories/quotients.py index 120d00f80b0..fa5fd3513db 100644 --- a/src/sage/categories/quotients.py +++ b/src/sage/categories/quotients.py @@ -24,7 +24,7 @@ class QuotientsCategory(RegressiveCovariantConstructionCategory): @classmethod def default_super_categories(cls, category): """ - Returns the default super categories of ``category.Quotients()`` + Return the default super categories of ``category.Quotients()``. Mathematical meaning: if `A` is a quotient of `B` in the category `C`, then `A` is also a subquotient of `B` in the @@ -32,8 +32,8 @@ def default_super_categories(cls, category): INPUT: - - ``cls`` -- the class ``QuotientsCategory`` - - ``category`` -- a category `Cat` + - ``cls`` -- the class ``QuotientsCategory`` + - ``category`` -- a category `Cat` OUTPUT: a (join) category diff --git a/src/sage/categories/realizations.py b/src/sage/categories/realizations.py index 7ebeaf2ce57..26d5125f9e7 100644 --- a/src/sage/categories/realizations.py +++ b/src/sage/categories/realizations.py @@ -25,9 +25,9 @@ class RealizationsCategory(RegressiveCovariantConstructionCategory): """ - An abstract base class for all categories of realizations category + An abstract base class for all categories of realizations category. - Relization are implemented as + Realization are implemented as :class:`~sage.categories.covariant_functorial_construction.RegressiveCovariantConstructionCategory`. See there for the documentation of how the various bindings such as ``Sets().Realizations()`` and ``P.Realizations()``, where ``P`` @@ -111,7 +111,7 @@ def Realizations(self): class Category_realization_of_parent(Category_over_base, BindableClass): """ - An abstract base class for categories of all realizations of a given parent + An abstract base class for categories of all realizations of a given parent. INPUT: @@ -163,7 +163,7 @@ def __init__(self, parent_with_realization): def _get_name(self): """ - Return a human readable string specifying which kind of bases this category is for + Return a human readable string specifying which kind of bases this category is for. It is obtained by splitting and lower casing the last part of the class name. @@ -173,7 +173,7 @@ def _get_name(self): sage: from sage.categories.realizations import Category_realization_of_parent sage: class MultiplicativeBasesOnPrimitiveElements(Category_realization_of_parent): ....: def super_categories(self): return [Objects()] - sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") # needs sage.combinat sage.modules + sage: Sym = SymmetricFunctions(QQ); Sym.rename('Sym') # needs sage.combinat sage.modules sage: MultiplicativeBasesOnPrimitiveElements(Sym)._get_name() # needs sage.combinat sage.modules 'multiplicative bases on primitive elements' """ @@ -191,7 +191,7 @@ def _repr_object_names(self): sage: from sage.categories.realizations import Category_realization_of_parent sage: class MultiplicativeBasesOnPrimitiveElements(Category_realization_of_parent): ....: def super_categories(self): return [Objects()] - sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") # needs sage.combinat sage.modules + sage: Sym = SymmetricFunctions(QQ); Sym.rename('Sym') # needs sage.combinat sage.modules sage: C = MultiplicativeBasesOnPrimitiveElements(Sym); C # needs sage.combinat sage.modules Category of multiplicative bases on primitive elements of Sym sage: C._repr_object_names() # needs sage.combinat sage.modules diff --git a/src/sage/categories/regular_crystals.py b/src/sage/categories/regular_crystals.py index 8b5a56b8ce2..506be6ba4ec 100644 --- a/src/sage/categories/regular_crystals.py +++ b/src/sage/categories/regular_crystals.py @@ -98,7 +98,7 @@ def super_categories(self): def example(self, n=3): """ - Returns an example of highest weight crystals, as per + Return an example of highest weight crystals, as per :meth:`Category.example`. EXAMPLES:: @@ -170,7 +170,7 @@ class ParentMethods: # sage: m.demazure_operator([1,4,2]) def demazure_operator(self, element, reduced_word): r""" - Returns the application of Demazure operators `D_i` for `i` from + Return the application of Demazure operators `D_i` for `i` from ``reduced_word`` on ``element``. INPUT: @@ -180,9 +180,7 @@ def demazure_operator(self, element, reduced_word): - ``reduced_word`` -- a reduced word of the Weyl group of the same type as the underlying crystal - OUTPUT: - - - an element of the free module indexed by the underlying crystal + OUTPUT: an element of the free module indexed by the underlying crystal EXAMPLES:: @@ -229,12 +227,10 @@ def demazure_subcrystal(self, element, reduced_word, only_support=True): underlying crystal - ``reduced_word`` -- a reduced word of the Weyl group of the same type as the underlying crystal - - ``only_support`` -- (default: ``True``) only include arrows - corresponding to the support of ``reduced_word`` - - OUTPUT: + - ``only_support`` -- boolean (default: ``True``); only include + arrows corresponding to the support of ``reduced_word`` - - the Demazure subcrystal + OUTPUT: the Demazure subcrystal EXAMPLES:: @@ -375,7 +371,7 @@ def dual_equivalence_graph(self, X=None, index_set=None, directed=True): (default: the whole index set of ``self``); this has to be a subset of the index set of ``self`` (as a list or tuple) - - ``directed`` -- (default: ``True``) whether to have the + - ``directed`` -- boolean (default: ``True``); whether to have the dual equivalence graph be directed, where the head of an edge `b - b'` is `b` and the tail is `b' = f_{i-1} f_i e_{i-1} e_i b`) @@ -453,10 +449,10 @@ def wt_zero(x): if checker(y): edges.append([x, y, i]) from sage.graphs.digraph import DiGraph - G = DiGraph([X, edges], format="vertices_and_edges", immutable=True) + G = DiGraph([X, edges], format='vertices_and_edges', immutable=True) from sage.graphs.dot2tex_utils import have_dot2tex if have_dot2tex(): - G.set_latex_options(format="dot2tex", edge_labels=True, + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=self.cartan_type()._index_set_coloring) return G @@ -878,11 +874,11 @@ def dual_equivalence_class(self, index_set=None): if y not in visited: todo.add(y) from sage.graphs.graph import Graph - G = Graph([visited, edges], format="vertices_and_edges", + G = Graph([visited, edges], format='vertices_and_edges', immutable=True, multiedges=True) from sage.graphs.dot2tex_utils import have_dot2tex if have_dot2tex(): - G.set_latex_options(format="dot2tex", edge_labels=True, + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=self.cartan_type()._index_set_coloring) return G diff --git a/src/sage/categories/regular_supercrystals.py b/src/sage/categories/regular_supercrystals.py index f7f6f3fa80e..0e4ae6bad27 100644 --- a/src/sage/categories/regular_supercrystals.py +++ b/src/sage/categories/regular_supercrystals.py @@ -39,7 +39,7 @@ class RegularSuperCrystals(Category_singleton): - either an attribute ``_cartan_type`` or a method ``cartan_type`` - - ``module_generators``: a list (or container) of distinct elements + - ``module_generators`` -- a list (or container) of distinct elements that generate the crystal using `f_i` and `e_i` Furthermore, their elements ``x`` should implement the following diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index b1ffb1db328..781f1a1462b 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -22,7 +22,7 @@ class Rings(CategoryWithAxiom): """ - The category of rings + The category of rings. Associative rings with unit, not necessarily commutative @@ -137,7 +137,6 @@ def is_injective(self) -> bool: sage: R = ZpFM(3) # needs sage.rings.padics sage: R.fraction_field().coerce_map_from(R).is_injective() True - """ if self.domain().is_zero(): return True @@ -289,7 +288,7 @@ def Division(self): """ Return the full subcategory of the division objects of ``self``. - A ring satisfies the *division axiom* if all non-zero + A ring satisfies the *division axiom* if all nonzero elements have multiplicative inverses. EXAMPLES:: @@ -346,8 +345,8 @@ def is_integral_domain(self, proof=True) -> bool: INPUT: - - ``proof`` -- (default: ``True``) Determines what to do in unknown - cases + - ``proof`` -- boolean (default: ``True``); determine what to do + in unknown cases ALGORITHM: @@ -500,7 +499,7 @@ def _Hom_(self, Y, category): The sole purpose of this method is to construct the homset as a :class:`~sage.rings.homset.RingHomset`. If ``category`` is specified and is not a subcategory of - :class:`Rings() `, a :class:`TypeError` is raised instead + :class:`Rings() `, a :exc:`TypeError` is raised instead This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. @@ -644,13 +643,6 @@ def ideal_monoid(self): """ The monoid of the ideals of this ring. - .. NOTE:: - - The code is copied from the base class of rings. - This is since there are rings that do not inherit - from that class, such as matrix algebras. See - :issue:`7797`. - EXAMPLES:: sage: # needs sage.modules @@ -667,6 +659,28 @@ def ideal_monoid(self): sage: MS.ideal_monoid() is MS.ideal_monoid() # needs sage.modules True + + More examples:: + + sage: # needs sage.combinat sage.modules + sage: F. = FreeAlgebra(ZZ, 3) + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F + sage: Q = F.quotient(I) + sage: Q.ideal_monoid() + Monoid of ideals of Quotient of Free Algebra on 3 generators (x, y, z) + over Integer Ring by the ideal (x*y + y*z, x^2 + x*y - y*x - y^2) + sage: F. = FreeAlgebra(ZZ, implementation='letterplace') + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F + sage: Q = F.quo(I) + sage: Q.ideal_monoid() + Monoid of ideals of Quotient of Free Associative Unital Algebra + on 3 generators (x, y, z) over Integer Ring + by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) + + sage: ZZ.ideal_monoid() + Monoid of ideals of Integer Ring + sage: R. = QQ[]; R.ideal_monoid() + Monoid of ideals of Univariate Polynomial Ring in x over Rational Field """ try: from sage.rings.ideal_monoid import IdealMonoid @@ -695,6 +709,65 @@ def _ideal_class_(self, n=0): from sage.rings.noncommutative_ideals import Ideal_nc return Ideal_nc + @cached_method + def zero_ideal(self): + """ + Return the zero ideal of this ring (cached). + + EXAMPLES:: + + sage: ZZ.zero_ideal() + Principal ideal (0) of Integer Ring + sage: QQ.zero_ideal() + Principal ideal (0) of Rational Field + sage: QQ['x'].zero_ideal() + Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field + + The result is cached:: + + sage: ZZ.zero_ideal() is ZZ.zero_ideal() + True + + TESTS: + + Make sure that :issue:`13644` is fixed:: + + sage: # needs sage.rings.padics + sage: K = Qp(3) + sage: R. = K[] + sage: L. = K.extension(a^2-3) + sage: L.ideal(a) + Principal ideal (1 + O(a^40)) of 3-adic Eisenstein Extension Field in a defined by a^2 - 3 + """ + return self._ideal_class_(1)(self, [self.zero()]) + + @cached_method + def unit_ideal(self): + """ + Return the unit ideal of this ring. + + EXAMPLES:: + + sage: Zp(7).unit_ideal() # needs sage.rings.padics + Principal ideal (1 + O(7^20)) of 7-adic Ring with capped relative precision 20 + """ + return self._ideal_class_(1)(self, [self.one()]) + + def principal_ideal(self, gen, coerce=True): + """ + Return the principal ideal generated by gen. + + EXAMPLES:: + + sage: R. = ZZ[] + sage: R.principal_ideal(x+2*y) + Ideal (x + 2*y) of Multivariate Polynomial Ring in x, y over Integer Ring + """ + C = self._ideal_class_(1) + if coerce: + gen = self(gen) + return C(self, [gen]) + def characteristic(self): """ Return the characteristic of this ring. @@ -752,13 +825,13 @@ def ideal(self, *args, **kwds): INPUT: - - An element or a list/tuple/sequence of elements. - - ``coerce`` (optional bool, default ``True``): - First coerce the elements into this ring. - - ``side``, optional string, one of ``"twosided"`` - (default), ``"left"``, ``"right"``: determines + - an element or a list/tuple/sequence of elements + - ``coerce`` -- boolean (default: ``True``); + first coerce the elements into this ring + - ``side`` -- (optional) string, one of ``'twosided'`` + (default), ``'left'``, ``'right'``; determines whether the resulting ideal is twosided, a left - ideal or a right ideal. + ideal or a right ideal EXAMPLES:: @@ -857,7 +930,7 @@ def quotient(self, I, names=None, **kwds): INPUT: - - ``I`` -- A twosided ideal of this ring. + - ``I`` -- a twosided ideal of this ring - ``names`` -- (optional) names of the generators of the quotient (if there are multiple generators, you can specify a single character string and the generators are named in sequence starting with 0). @@ -997,9 +1070,7 @@ def quotient_ring(self, I, names=None, **kwds): - further named arguments that may be passed to the quotient ring constructor. - OUTPUT: - - - ``R/I`` -- the quotient ring of `R` by the ideal `I` + OUTPUT: ``R/I`` -- the quotient ring of `R` by the ideal `I` EXAMPLES:: @@ -1353,12 +1424,10 @@ def free_module(self, base=None, basis=None, map=True): - ``basis`` -- (optional) a basis for this ring over the base - - ``map`` -- boolean (default ``True``), whether to return + - ``map`` -- boolean (default: ``True``); whether to return `R`-linear maps to and from `V` - OUTPUT: - - - A finite-rank free `R`-module `V` + OUTPUT: a finite-rank free `R`-module `V` - An `R`-module isomorphism from `V` to this ring (only included if ``map`` is ``True``) @@ -1410,10 +1479,10 @@ def free_module(self, base=None, basis=None, map=True): def _random_nonzero_element(self, *args, **kwds): """ - Return a random non-zero element in this ring. + Return a random nonzero element in this ring. The default behaviour of this method is to repeatedly call the - ``random_element`` method until a non-zero element is obtained. + ``random_element`` method until a nonzero element is obtained. In this implementation, all parameters are simply pushed forward to the ``random_element`` method. @@ -1469,9 +1538,7 @@ def inverse_of_unit(self): r""" Return the inverse of this element if it is a unit. - OUTPUT: - - An element in the same ring as this element. + OUTPUT: an element in the same ring as this element EXAMPLES:: @@ -1521,7 +1588,7 @@ def inverse_of_unit(self): def _divide_if_possible(self, y): """ Divide ``self`` by ``y`` if possible and raise a - :class:`ValueError` otherwise. + :exc:`ValueError` otherwise. EXAMPLES:: diff --git a/src/sage/categories/schemes.py b/src/sage/categories/schemes.py index d0b99f271eb..68187fa2257 100644 --- a/src/sage/categories/schemes.py +++ b/src/sage/categories/schemes.py @@ -24,6 +24,11 @@ from sage.categories.fields import Fields from sage.categories.homsets import HomsetsCategory from sage.misc.abstract_method import abstract_method +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.categories.map', 'Map') +lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') +lazy_import('sage.schemes.generic.scheme', 'Scheme') class Schemes(Category): @@ -94,7 +99,7 @@ def super_categories(self): def _call_(self, x): """ - Construct a scheme from the data in ``x`` + Construct a scheme from the data in ``x``. EXAMPLES: @@ -138,17 +143,11 @@ def _call_(self, x): Defn: Natural morphism: From: Integer Ring To: Rational Field - """ - from sage.schemes.generic.scheme import Scheme - if isinstance(x, Scheme): - return x - from sage.schemes.generic.morphism import is_SchemeMorphism - if is_SchemeMorphism(x): + if isinstance(x, (SchemeMorphism, Scheme)): return x from sage.categories.commutative_rings import CommutativeRings from sage.schemes.generic.spec import Spec - from sage.categories.map import Map if x in CommutativeRings(): return Spec(x) elif isinstance(x, Map) and x.category_for().is_subcategory(Rings()): diff --git a/src/sage/categories/semigroups.py b/src/sage/categories/semigroups.py index 658b77c96b2..1635296450b 100644 --- a/src/sage/categories/semigroups.py +++ b/src/sage/categories/semigroups.py @@ -60,18 +60,18 @@ class Semigroups(CategoryWithAxiom): """ _base_category_class_and_axiom = (Magmas, "Associative") - def example(self, choice="leftzero", **kwds): + def example(self, choice='leftzero', **kwds): r""" - Returns an example of a semigroup, as per + Return an example of a semigroup, as per :meth:`Category.example() `. INPUT: - - ``choice`` -- str (default: 'leftzero'). Can be either 'leftzero' - for the left zero semigroup, or 'free' for the free semigroup. + - ``choice`` -- string (default: ``'leftzero'``); can be either 'leftzero' + for the left zero semigroup, or 'free' for the free semigroup - ``**kwds`` -- keyword arguments passed onto the constructor for the - chosen semigroup. + chosen semigroup EXAMPLES:: @@ -81,7 +81,6 @@ def example(self, choice="leftzero", **kwds): An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') sage: Semigroups().example(choice='free', alphabet=('a','b')) An example of a semigroup: the free semigroup generated by ('a', 'b') - """ import sage.categories.examples.semigroups as examples if choice == "leftzero": @@ -114,7 +113,6 @@ def _test_associativity(self, **options): sage: L._test_associativity(elements = (L(1), L(2), L(3))) See the documentation for :class:`TestSuite` for more information. - """ tester = self._tester(**options) S = tester.some_elements() @@ -173,26 +171,23 @@ def prod(self, args): assert len(args) > 0, "Cannot compute an empty product in a semigroup" return prod(args[1:], args[0]) - def cayley_graph(self, side="right", simple=False, elements=None, + def cayley_graph(self, side='right', simple=False, elements=None, generators=None, connecting_set=None): r""" Return the Cayley graph for this finite semigroup. INPUT: - - ``side`` -- "left", "right", or "twosided": - the side on which the generators act (default:"right") - - ``simple`` -- boolean (default: ``False``): - if True, returns a simple graph (no loops, no labels, - no multiple edges) - - ``generators`` -- a list, tuple, or family of elements + - ``side`` -- ``'left'``, ``'right'``, or ``'twosided'``: + the side on which the generators act (default: ``'right'``) + - ``simple`` -- boolean (default: ``False``); if ``True``, returns + a simple graph (no loops, no labels, no multiple edges) + - ``generators`` -- list; tuple, or family of elements of ``self`` (default: ``self.semigroup_generators()``) - ``connecting_set`` -- alias for ``generators``; deprecated - - ``elements`` -- a list (or iterable) of elements of ``self`` + - ``elements`` -- list (or iterable) of elements of ``self`` - OUTPUT: - - - :class:`DiGraph` + OUTPUT: :class:`DiGraph` EXAMPLES: @@ -263,7 +258,7 @@ def cayley_graph(self, side="right", simple=False, elements=None, :: - sage: g = S.cayley_graph(side="left", simple=True) # needs sage.graphs + sage: g = S.cayley_graph(side='left', simple=True) # needs sage.graphs sage: g.vertices(sort=True) # needs sage.graphs ['a', 'ab', 'b', 'ba'] sage: g.edges(sort=True) # needs sage.graphs @@ -272,7 +267,7 @@ def cayley_graph(self, side="right", simple=False, elements=None, :: - sage: g = S.cayley_graph(side="twosided", simple=True) # needs sage.graphs + sage: g = S.cayley_graph(side='twosided', simple=True) # needs sage.graphs sage: g.vertices(sort=True) # needs sage.graphs ['a', 'ab', 'b', 'ba'] sage: g.edges(sort=True) # needs sage.graphs @@ -281,7 +276,7 @@ def cayley_graph(self, side="right", simple=False, elements=None, :: - sage: g = S.cayley_graph(side="twosided") # needs sage.graphs + sage: g = S.cayley_graph(side='twosided') # needs sage.graphs sage: g.vertices(sort=True) # needs sage.graphs ['a', 'ab', 'b', 'ba'] sage: g.edges(sort=True) # needs sage.graphs @@ -295,7 +290,7 @@ def cayley_graph(self, side="right", simple=False, elements=None, TESTS:: - sage: SymmetricGroup(2).cayley_graph(side="both") # needs sage.graphs sage.groups + sage: SymmetricGroup(2).cayley_graph(side='both') # needs sage.graphs sage.groups Traceback (most recent call last): ... ValueError: option 'side' must be 'left', 'right' or 'twosided' @@ -344,7 +339,7 @@ def cayley_graph(self, side="right", simple=False, elements=None, generators = self.semigroup_generators() if isinstance(generators, (list, tuple)): generators = {self(g): self(g) for g in generators} - left = (side == "left" or side == "twosided") + left = (side == "left" or side == "twosided") right = (side == "right" or side == "twosided") def add_edge(source, target, label, side_label): @@ -379,7 +374,7 @@ def subsemigroup(self, generators, one=None, category=None): ``self``, or a list, iterable, ... that can be converted into one (see :class:`Family`). - - ``one`` -- a unit for the subsemigroup, or ``None``. + - ``one`` -- a unit for the subsemigroup, or ``None`` - ``category`` -- a category @@ -457,7 +452,7 @@ def subsemigroup(self, generators, one=None, category=None): return AutomaticSemigroup(generators, ambient=self, one=one, category=category) - def trivial_representation(self, base_ring=None, side="twosided"): + def trivial_representation(self, base_ring=None, side='twosided'): r""" Return the trivial representation of ``self`` over ``base_ring``. @@ -479,12 +474,12 @@ def trivial_representation(self, base_ring=None, side="twosided"): from sage.modules.with_basis.representation import TrivialRepresentation return TrivialRepresentation(self, base_ring) - def regular_representation(self, base_ring=None, side="left"): + def regular_representation(self, base_ring=None, side='left'): """ Return the regular representation of ``self`` over ``base_ring``. - - ``side`` -- (default: ``"left"``) whether this is the - ``"left"`` or ``"right"`` regular representation + - ``side`` -- (default: ``'left'``) whether this is the + ``'left'`` or ``'right'`` regular representation EXAMPLES:: @@ -499,7 +494,7 @@ def regular_representation(self, base_ring=None, side="left"): from sage.modules.with_basis.representation import RegularRepresentation return RegularRepresentation(self, base_ring, side) - def representation(self, module, on_basis, side="left", *args, **kwargs): + def representation(self, module, on_basis, side='left', *args, **kwargs): r""" Return a representation of ``self`` on ``module`` with the action given by ``on_basis``. @@ -511,11 +506,12 @@ def representation(self, module, on_basis, side="left", *args, **kwargs): ``g`` is an element of the semigroup and ``m`` is an element of the indexing set for the basis, and returns the result of ``g`` acting on ``m`` - - ``side`` -- (default: ``"left"``) whether this is a - ``"left"`` or ``"right"`` representation + - ``side`` -- (default: ``'left'``) whether this is a + ``'left'`` or ``'right'`` representation EXAMPLES:: + sage: # needs sage.groups sage: G = CyclicPermutationGroup(3) sage: M = algebras.Exterior(QQ, 'x', 3) sage: def on_basis(g, m): # cyclically permute generators @@ -533,11 +529,11 @@ class ElementMethods: def _pow_int(self, n): """ - Return ``self`` to the `n^{th}` power. + Return ``self`` to the `n`-th power. INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -830,7 +826,7 @@ class Subquotients(SubquotientsCategory): def example(self): """ - Returns an example of subquotient of a semigroup, as per + Return an example of subquotient of a semigroup, as per :meth:`Category.example() `. @@ -1006,7 +1002,7 @@ def product_on_basis(self, g1, g2): """ return self.monomial(g1 * g2) - def trivial_representation(self, side="twosided"): + def trivial_representation(self, side='twosided'): """ Return the trivial representation of ``self``. @@ -1026,14 +1022,14 @@ def trivial_representation(self, side="twosided"): S = self.basis().keys() return S.trivial_representation(self.base_ring()) - def regular_representation(self, side="left"): + def regular_representation(self, side='left'): """ Return the regular representation of ``self``. INPUT: - - ``side`` -- (default: ``"left"``) whether this is the - ``"left"`` or ``"right"`` regular representation + - ``side`` -- (default: ``'left'``) whether this is the + ``'left'`` or ``'right'`` regular representation EXAMPLES:: @@ -1047,7 +1043,7 @@ def regular_representation(self, side="left"): S = self.basis().keys() return S.regular_representation(self.base_ring(), side) - def representation(self, module, on_basis, side="left", *args, **kwargs): + def representation(self, module, on_basis, side='left', *args, **kwargs): r""" Return a representation of ``self`` on ``module`` with the action of the semigroup given by ``on_basis``. @@ -1059,11 +1055,12 @@ def representation(self, module, on_basis, side="left", *args, **kwargs): ``g`` is an element of the semigroup and ``m`` is an element of the indexing set for the basis, and returns the result of ``g`` acting on ``m`` - - ``side`` -- (default: ``"left"``) whether this is a - ``"left"`` or ``"right"`` representation + - ``side`` -- (default: ``'left'``) whether this is a + ``'left'`` or ``'right'`` representation EXAMPLES:: + sage: # needs sage.groups sage: G = groups.permutation.Dihedral(5) sage: CFM = CombinatorialFreeModule(GF(2), [1, 2, 3, 4, 5]) sage: A = G.algebra(GF(2)) diff --git a/src/sage/categories/semisimple_algebras.py b/src/sage/categories/semisimple_algebras.py index 5f889ea0e16..90fa3828d09 100644 --- a/src/sage/categories/semisimple_algebras.py +++ b/src/sage/categories/semisimple_algebras.py @@ -92,9 +92,9 @@ def radical_basis(self, **keywords): r""" Return a basis of the Jacobson radical of this algebra. - - ``keywords`` -- for compatibility; ignored. + - ``keywords`` -- for compatibility; ignored - OUTPUT: the empty list since this algebra is semisimple. + OUTPUT: the empty list since this algebra is semisimple EXAMPLES:: diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 51eb9b14453..9d63ac2fa30 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -71,7 +71,6 @@ def print_compare(x, y): 1 != 2 sage: print_compare(1,1) 1 == 1 - """ if x == y: return LazyFormat("%s == %s") % (x, y) @@ -136,9 +135,9 @@ class Sets(Category_singleton): + - @@ -212,7 +211,6 @@ class Sets(Category_singleton): TESTS:: sage: TestSuite(Sets()).run() - """ def super_categories(self): @@ -573,7 +571,6 @@ def Subobjects(self): sage: Semigroups().Subobjects().is_subcategory(Semigroups().Subquotients()) True sage: TestSuite(C).run() - """ return SubobjectsCategory.category_of(self) @@ -1064,7 +1061,7 @@ def an_element(self): This is used both for illustration and testing purposes. If the set ``self`` is empty, :meth:`an_element` should raise the exception - :class:`EmptySetError`. + :exc:`EmptySetError`. This default implementation calls :meth:`_an_element_` and caches the result. Any parent should implement either @@ -1207,7 +1204,6 @@ def _test_elements_eq_reflexive(self, **options): We restore ``P.element_class`` in a proper state for further tests:: sage: P.element_class.__eq__ = eq - """ tester = self._tester(**options) S = list(tester.some_elements()) + [None, 0] @@ -1246,7 +1242,6 @@ def _test_elements_eq_symmetric(self, **options): We restore ``P.element_class`` in a proper state for further tests:: sage: P.element_class.__eq__ = eq - """ tester = self._tester(**options) S = list(tester.some_elements()) + [None, 0] @@ -1278,7 +1273,6 @@ def _test_elements_eq_transitive(self, **options): ... AssertionError: non transitive equality: 3 + O(3^2) == O(3) and O(3) == 0 but 3 + O(3^2) != 0 - """ tester = self._tester(**options) S = list(tester.some_elements()) @@ -1525,7 +1519,6 @@ def _test_construction(self, **options): sage: F(R) == QQ True sage: TestSuite(QQ).run() # indirect doctest - """ tester = self._tester(**options) FO = self.construction() @@ -1541,7 +1534,7 @@ def cartesian_product(*parents, **kwargs): INPUT: - - ``parents`` -- a list (or other iterable) of parents. + - ``parents`` -- list (or other iterable) of parents - ``category`` -- (default: ``None``) the category the Cartesian product belongs to. If ``None`` is passed, @@ -1557,14 +1550,12 @@ def cartesian_product(*parents, **kwargs): for this Cartesian product (see also :class:`~sage.sets.cartesian_product.CartesianProduct`). - OUTPUT: - - The Cartesian product. + OUTPUT: the Cartesian product EXAMPLES:: sage: C = AlgebrasWithBasis(QQ) - sage: A = C.example(); A.rename("A") # needs sage.combinat sage.modules + sage: A = C.example(); A.rename('A') # needs sage.combinat sage.modules sage: A.cartesian_product(A, A) # needs sage.combinat sage.modules A (+) A (+) A sage: ZZ.cartesian_product(GF(2), FiniteEnumeratedSet([1,2,3])) @@ -1832,7 +1823,7 @@ def __invert__(self): .. NOTE:: This is an optional method. A default implementation - raising :class:`NotImplementedError` could be provided instead. + raising :exc:`NotImplementedError` could be provided instead. """ def is_injective(self): @@ -2187,7 +2178,7 @@ class CartesianProducts(CartesianProductsCategory): sage: C = Sets().CartesianProducts().example() sage: C The Cartesian product of (Set of prime numbers (basic implementation), - An example of an infinite enumerated set: the non negative integers, + An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) sage: C.category() Category of Cartesian products of sets @@ -2217,7 +2208,7 @@ def example(self): sage: Sets().CartesianProducts().example() The Cartesian product of (Set of prime numbers (basic implementation), - An example of an infinite enumerated set: the non negative integers, + An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) """ from .finite_enumerated_sets import FiniteEnumeratedSets @@ -2362,7 +2353,7 @@ def an_element(self): sage: C = Sets().CartesianProducts().example(); C The Cartesian product of (Set of prime numbers (basic implementation), - An example of an infinite enumerated set: the non negative integers, + An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) sage: C.an_element() (47, 42, 1) @@ -2415,7 +2406,7 @@ def is_finite(self): def cardinality(self): r""" - Return the cardinality of self. + Return the cardinality of ``self``. EXAMPLES:: @@ -2523,7 +2514,7 @@ def cartesian_projection(self, i): sage: C = Sets().CartesianProducts().example(); C The Cartesian product of (Set of prime numbers (basic implementation), - An example of an infinite enumerated set: the non negative integers, + An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) sage: x = C.an_element(); x (47, 42, 1) @@ -2600,8 +2591,8 @@ def cartesian_projection(self, i): EXAMPLES:: sage: # needs sage.modules - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') sage: S = cartesian_product([F, G]) sage: x = (S.monomial((0,4)) + 2 * S.monomial((0,5)) ....: + 3 * S.monomial((1,6))) @@ -2619,9 +2610,9 @@ def cartesian_factors(self): EXAMPLES:: sage: # needs sage.modules - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") - sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.rename("H") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') + sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.rename('H') sage: S = cartesian_product([F, G, H]) sage: x = (S.monomial((0,4)) + 2 * S.monomial((0,5)) ....: + 3 * S.monomial((1,6)) + 4 * S.monomial((2,4)) @@ -2657,7 +2648,6 @@ def extra_super_categories(self): Category of modules with basis over Integer Ring, ... Category of objects] - """ from sage.categories.modules_with_basis import ModulesWithBasis return [ModulesWithBasis(self.base_ring())] @@ -2696,7 +2686,7 @@ def construction(self): def _repr_(self): r""" - Return the string representation of `self`. + Return the string representation of ``self``. EXAMPLES:: @@ -2812,7 +2802,7 @@ def _register_realization(self, realization): sage: R in A.realizations() # indirect doctest True - Note: the test above uses ``QQ[x]`` to not interfer + Note: the test above uses ``QQ[x]`` to not interfere with other tests. """ assert realization.realization_of() is self @@ -2824,9 +2814,10 @@ def inject_shorthands(self, shorthands=None, verbose=True): INPUT: - - ``shorthands`` -- a list (or iterable) of strings (default: ``self._shorthands``) - or ``"all"`` (for ``self._shorthands_all``) - - ``verbose`` -- boolean (default ``True``); + - ``shorthands`` -- list (or iterable) of strings + (default: ``self._shorthands``) + or ``'all'`` (for ``self._shorthands_all``) + - ``verbose`` -- boolean (default: ``True``); whether to print the defined shorthands EXAMPLES: diff --git a/src/sage/categories/sets_with_grading.py b/src/sage/categories/sets_with_grading.py index 9f9037e94b5..9777c0fd68c 100644 --- a/src/sage/categories/sets_with_grading.py +++ b/src/sage/categories/sets_with_grading.py @@ -22,7 +22,7 @@ class SetsWithGrading(Category): A *set with a grading* is a set `S` equipped with a grading by some other set `I` (by default the set `\NN` of the - non-negative integers): + nonnegative integers): .. MATH:: @@ -54,7 +54,7 @@ class SetsWithGrading(Category): EXAMPLES: - A typical example of a set with a grading is the set of non-negative + A typical example of a set with a grading is the set of nonnegative integers graded by themselves:: sage: N = SetsWithGrading().example(); N @@ -137,7 +137,7 @@ def _test_graded_components(self, **options): def grading_set(self): """ Return the set ``self`` is graded by. By default, this is - the set of non-negative integers. + the set of nonnegative integers. EXAMPLES:: @@ -203,9 +203,7 @@ def generating_series(self): """ Default implementation for generating series. - OUTPUT: - - A series, indexed by the grading set. + OUTPUT: a series, indexed by the grading set EXAMPLES:: @@ -225,7 +223,7 @@ def generating_series(self): from sage.rings.lazy_series_ring import LazyPowerSeriesRing from sage.sets.non_negative_integers import NonNegativeIntegers if isinstance(self.grading_set(), NonNegativeIntegers): - R = LazyPowerSeriesRing(ZZ, names="z") + R = LazyPowerSeriesRing(ZZ, names='z') return R(lambda n: self.graded_component(n).cardinality()) raise NotImplementedError diff --git a/src/sage/categories/sets_with_partial_maps.py b/src/sage/categories/sets_with_partial_maps.py index 01993c2fb82..8fb38cf894b 100644 --- a/src/sage/categories/sets_with_partial_maps.py +++ b/src/sage/categories/sets_with_partial_maps.py @@ -18,7 +18,7 @@ class SetsWithPartialMaps(Category_singleton): """ The category whose objects are sets and whose morphisms are - maps that are allowed to raise a :class:`ValueError` on some inputs. + maps that are allowed to raise a :exc:`ValueError` on some inputs. This category is equivalent to the category of pointed sets, via the equivalence sending an object X to X union {error}, diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index e714a4571c4..65e526d8688 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -30,7 +30,7 @@ class SimplicialSets(Category_singleton): The category of simplicial sets. A simplicial set `X` is a collection of sets `X_i`, indexed by - the non-negative integers, together with maps + the nonnegative integers, together with maps .. math:: @@ -203,7 +203,7 @@ class Pointed(CategoryWithAxiom): class ParentMethods: def base_point(self): """ - Return this simplicial set's base point + Return this simplicial set's base point. EXAMPLES:: @@ -229,11 +229,11 @@ def base_point_map(self, domain=None): INPUT: - - ``domain`` -- optional, default ``None``. Use - this to specify a particular one-point space as - the domain. The default behavior is to use the - :func:`sage.topology.simplicial_set.Point` - function to use a standard one-point space. + - ``domain`` -- (default: ``None``) use this to specify a + particular one-point space as the domain. The default + behavior is to use the + :func:`sage.topology.simplicial_set.Point` function to use a + standard one-point space. EXAMPLES:: @@ -278,7 +278,7 @@ def fundamental_group(self, simplify=True): INPUT: - - ``simplify`` (bool, optional ``True``) -- if + - ``simplify`` -- boolean (default: ``True``); if ``False``, then return a presentation of the group in terms of generators and relations. If ``True``, the default, simplify as much as GAP is able to. @@ -407,20 +407,19 @@ def universal_cover_map(self): EXAMPLES:: sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # needs sage.graphs sage.groups - sage: phi = RP2.universal_cover_map(); phi # needs sage.graphs sage.groups + sage: phi = RP2.universal_cover_map(); phi # needs sage.graphs sage.groups gap_package_polenta Simplicial set morphism: From: Simplicial set with 6 non-degenerate simplices To: RP^2 Defn: [(1, 1), (1, e), (f, 1), (f, e), (f * f, 1), (f * f, e)] --> [1, 1, f, f, f * f, f * f] - sage: phi.domain().face_data() # needs sage.graphs sage.groups + sage: phi.domain().face_data() # needs sage.graphs sage.groups gap_package_polenta {(1, 1): None, (1, e): None, (f, 1): ((1, e), (1, 1)), (f, e): ((1, 1), (1, e)), (f * f, 1): ((f, e), s_0 (1, 1), (f, 1)), (f * f, e): ((f, 1), s_0 (1, e), (f, e))} - """ edges = self.n_cells(1) if not edges: @@ -439,8 +438,7 @@ def covering_map(self, character): INPUT: - - ``character`` -- a dictionary - + - ``character`` -- dictionary EXAMPLES:: @@ -486,7 +484,7 @@ def covering_map(self, character): char[s] = G.one() for d in range(1, self.dimension() + 1): - for s in self.n_cells(d): + for s in self.all_n_simplices(d): if s not in char.keys(): if d == 1 and s.is_degenerate(): char[s] = G.one() @@ -527,7 +525,7 @@ def cover(self, character): INPUT: - - ``character`` -- a dictionary + - ``character`` -- dictionary EXAMPLES:: @@ -566,7 +564,7 @@ def universal_cover(self): sage: RP3 = simplicial_sets.RealProjectiveSpace(3) sage: C = RP3.universal_cover(); C Simplicial set with 8 non-degenerate simplices - sage: C.face_data() + sage: C.face_data() # needs gap_package_polenta {(1, 1): None, (1, e): None, (f, 1): ((1, e), (1, 1)), @@ -577,6 +575,16 @@ def universal_cover(self): (f * f * f, e): ((f * f, 1), s_0 (f, e), s_1 (f, e), (f * f, e))} sage: C.fundamental_group() Finitely presented group < | > + + TESTS:: + + sage: RP2 = simplicial_sets.RealProjectiveSpace(2) + sage: S3 = simplicial_sets.Sphere(3) + sage: X = S3.wedge(RP2) + sage: XU = X.universal_cover() + sage: [XU.homology(i) for i in range(5)] + [0, 0, Z, Z x Z, 0] + """ return self.universal_cover_map().domain() @@ -593,16 +601,15 @@ def _canonical_twisting_operator(self): sage: X = simplicial_sets.Torus() sage: d = X._canonical_twisting_operator() sage: d - {(s_0 v_0, sigma_1): f3, (sigma_1, s_0 v_0): f2*f3^-1, (sigma_1, sigma_1): f2} + {(s_0 v_0, sigma_1): f2, (sigma_1, s_0 v_0): f1*f2^-1, (sigma_1, sigma_1): f1} sage: list(d.values())[0].parent() - Multivariate Laurent Polynomial Ring in f2, f3 over Integer Ring + Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring sage: Y = simplicial_sets.RealProjectiveSpace(2) sage: d2 = Y._canonical_twisting_operator() sage: d2 {f: F1bar} sage: list(d2.values())[0].parent() Quotient of Univariate Laurent Polynomial Ring in F1 over Integer Ring by the ideal (-1 + F1^2) - """ G, d = self._universal_cover_dict() phi = G.abelianization_map() @@ -624,7 +631,7 @@ def twisted_chain_complex(self, twisting_operator=None, dimensions=None, augment INPUT: - - ``twisting_operator`` -- a dictionary, associating the twist of each + - ``twisting_operator`` -- dictionary, associating the twist of each simplex. If it is not given, the canonical one (associated to the laurent polynomial ring abelianization of the fundamental group, ignoring torsion) is used. @@ -634,20 +641,20 @@ def twisted_chain_complex(self, twisting_operator=None, dimensions=None, augment chain complex in those dimensions, setting the chain groups in all other dimensions to zero. - - ``augmented`` (default: ``False``) -- if ``True``, + - ``augmented`` -- boolean (default: ``False``); if ``True``, return the augmented chain complex (that is, include a class in dimension `-1` corresponding to the empty cell). - - ``cochain`` (default: ``False``) -- if ``True``, + - ``cochain`` -- boolean (default: ``False``); if ``True``, return the cochain complex (that is, the dual of the chain complex). - - ``verbose`` (default: ``False``) -- ignored. + - ``verbose`` -- boolean (default: ``False``); ignored - - ``subcomplex`` (default: ``None``) -- if present, - compute the chain complex relative to this subcomplex. + - ``subcomplex`` -- (default: ``None``) if present, + compute the chain complex relative to this subcomplex - - ``check`` (default: ``False``) -- If ``True``, make + - ``check`` -- boolean (default: ``False``); if ``True``, make sure that the chain complex is actually a chain complex: the differentials are composable and their product is zero. @@ -677,10 +684,10 @@ def twisted_chain_complex(self, twisting_operator=None, dimensions=None, augment sage: X = simplicial_sets.Torus() sage: C = X.twisted_chain_complex() sage: C.differential(1) - [ f3 - 1 f2*f3^-1 - 1 f2 - 1] + [ f2 - 1 f1*f2^-1 - 1 f1 - 1] sage: C.differential(2) - [ 1 f2*f3^-1] - [ f3 1] + [ 1 f1*f2^-1] + [ f2 1] [ -1 -1] sage: C.differential(3) [] @@ -696,7 +703,6 @@ def twisted_chain_complex(self, twisting_operator=None, dimensions=None, augment [1 + F1] sage: C.differential(3) [] - """ from sage.homology.chain_complex import ChainComplex from sage.structure.element import get_coercion_model @@ -825,10 +831,10 @@ def twisted_homology(self, n, reduced=False): INPUT: - - ``n`` -- a positive integer. + - ``n`` -- positive integer - - ``reduced`` -- (default: ``False``) if set to True, the presentation matrix - will be reduced. + - ``reduced`` -- boolean (default: ``False``); if set to True, + the presentation matrix will be reduced EXAMPLES:: @@ -848,29 +854,29 @@ def twisted_homology(self, n, reduced=False): sage: # needs sage.graphs sage: Y = simplicial_sets.Torus() sage: Y.twisted_homology(1) - Quotient module by Submodule of Ambient free module of rank 5 over the integral domain Multivariate Polynomial Ring in f2, f2inv, f3, f3inv over Integer Ring + Quotient module by Submodule of Ambient free module of rank 5 over the integral domain Multivariate Polynomial Ring in f1, f1inv, f2, f2inv over Integer Ring Generated by the rows of the matrix: [ 1 0 0 0 0] [ 0 1 0 0 0] [ 0 0 1 0 0] [ 0 0 0 1 0] [ 0 0 0 0 1] + [f1*f1inv - 1 0 0 0 0] + [ 0 f1*f1inv - 1 0 0 0] + [ 0 0 f1*f1inv - 1 0 0] + [ 0 0 0 f1*f1inv - 1 0] + [ 0 0 0 0 f1*f1inv - 1] [f2*f2inv - 1 0 0 0 0] [ 0 f2*f2inv - 1 0 0 0] [ 0 0 f2*f2inv - 1 0 0] [ 0 0 0 f2*f2inv - 1 0] [ 0 0 0 0 f2*f2inv - 1] - [f3*f3inv - 1 0 0 0 0] - [ 0 f3*f3inv - 1 0 0 0] - [ 0 0 f3*f3inv - 1 0 0] - [ 0 0 0 f3*f3inv - 1 0] - [ 0 0 0 0 f3*f3inv - 1] sage: Y.twisted_homology(2) - Quotient module by Submodule of Ambient free module of rank 0 over the integral domain Multivariate Polynomial Ring in f2, f2inv, f3, f3inv over Integer Ring + Quotient module by Submodule of Ambient free module of rank 0 over the integral domain Multivariate Polynomial Ring in f1, f1inv, f2, f2inv over Integer Ring Generated by the rows of the matrix: [] sage: Y.twisted_homology(1, reduced=True) - Quotient module by Submodule of Ambient free module of rank 5 over the integral domain Multivariate Polynomial Ring in f2, f2inv, f3, f3inv over Integer Ring + Quotient module by Submodule of Ambient free module of rank 5 over the integral domain Multivariate Polynomial Ring in f1, f1inv, f2, f2inv over Integer Ring Generated by the rows of the matrix: [1 0 0 0 0] [0 1 0 0 0] @@ -893,7 +899,6 @@ def twisted_homology(self, n, reduced=False): sage: X.universal_cover().homology(2) Z^5 sage: from sage.libs.singular.function import singular_function - """ from sage.libs.singular.function import singular_function from sage.libs.singular.option import opt_verb diff --git a/src/sage/categories/subobjects.py b/src/sage/categories/subobjects.py index db64d84d9c4..47a81f1c9a9 100644 --- a/src/sage/categories/subobjects.py +++ b/src/sage/categories/subobjects.py @@ -24,7 +24,7 @@ class SubobjectsCategory(RegressiveCovariantConstructionCategory): @classmethod def default_super_categories(cls, category): """ - Returns the default super categories of ``category.Subobjects()`` + Return the default super categories of ``category.Subobjects()``. Mathematical meaning: if `A` is a subobject of `B` in the category `C`, then `A` is also a subquotient of `B` in the @@ -32,8 +32,8 @@ def default_super_categories(cls, category): INPUT: - - ``cls`` -- the class ``SubobjectsCategory`` - - ``category`` -- a category `Cat` + - ``cls`` -- the class ``SubobjectsCategory`` + - ``category`` -- a category `Cat` OUTPUT: a (join) category diff --git a/src/sage/categories/super_algebras.py b/src/sage/categories/super_algebras.py index abb2d404002..658dfebd2d8 100644 --- a/src/sage/categories/super_algebras.py +++ b/src/sage/categories/super_algebras.py @@ -78,7 +78,7 @@ def tensor(*parents, **kwargs): EXAMPLES:: sage: # needs sage.combinat sage.modules - sage: A. = ExteriorAlgebra(ZZ); A.rename("A") + sage: A. = ExteriorAlgebra(ZZ); A.rename('A') sage: T = A.tensor(A,A); T A # A # A sage: T in Algebras(ZZ).Graded().SignedTensorProducts() diff --git a/src/sage/categories/super_algebras_with_basis.py b/src/sage/categories/super_algebras_with_basis.py index 46731a1609f..aa0de0004ef 100644 --- a/src/sage/categories/super_algebras_with_basis.py +++ b/src/sage/categories/super_algebras_with_basis.py @@ -16,7 +16,7 @@ class SuperAlgebrasWithBasis(SuperModulesCategory): """ - The category of super algebras with a distinguished basis + The category of super algebras with a distinguished basis. EXAMPLES:: diff --git a/src/sage/categories/super_modules.py b/src/sage/categories/super_modules.py index fe44beff26b..4e02ccbae30 100644 --- a/src/sage/categories/super_modules.py +++ b/src/sage/categories/super_modules.py @@ -38,9 +38,7 @@ def default_super_categories(cls, category, *args): - ``category`` -- a category `Cat` - ``*args`` -- further arguments for the functor - OUTPUT: - - A join category. + OUTPUT: a join category This implements the property that subcategories constructed by the set of whitelisted axioms is a subcategory. @@ -134,7 +132,7 @@ def super_categories(self): def extra_super_categories(self): r""" - Adds :class:`VectorSpaces` to the super categories of ``self`` if + Add :class:`VectorSpaces` to the super categories of ``self`` if the base ring is a field. EXAMPLES:: diff --git a/src/sage/categories/supercrystals.py b/src/sage/categories/supercrystals.py index fdc074a37d9..09b924e0ad6 100644 --- a/src/sage/categories/supercrystals.py +++ b/src/sage/categories/supercrystals.py @@ -121,7 +121,7 @@ def edge_options(data): edge_opts['label'] = LatexExpr(str(l)) return edge_opts - G.set_latex_options(format="dot2tex", edge_labels=True, edge_options=edge_options) + G.set_latex_options(format='dot2tex', edge_labels=True, edge_options=edge_options) return G def genuine_highest_weight_vectors(self): diff --git a/src/sage/categories/tensor.py b/src/sage/categories/tensor.py index 11e470e378f..c9de28aecfd 100644 --- a/src/sage/categories/tensor.py +++ b/src/sage/categories/tensor.py @@ -55,8 +55,6 @@ class TensorProductFunctor(CovariantFunctorialConstruction): tensor = TensorProductFunctor() - - """ The tensor product functorial construction @@ -71,7 +69,7 @@ class TensorProductFunctor(CovariantFunctorialConstruction): class TensorProductsCategory(CovariantConstructionCategory): r""" - An abstract base class for all TensorProducts's categories + An abstract base class for all TensorProducts's categories. TESTS:: @@ -88,7 +86,7 @@ class TensorProductsCategory(CovariantConstructionCategory): def TensorProducts(self): """ - Returns the category of tensor products of objects of ``self`` + Return the category of tensor products of objects of ``self``. By associativity of tensor products, this is ``self`` (a tensor product of tensor products of `Cat`'s is a tensor product of `Cat`'s) diff --git a/src/sage/categories/triangular_kac_moody_algebras.py b/src/sage/categories/triangular_kac_moody_algebras.py index 0a7988282d3..d6541107a0f 100644 --- a/src/sage/categories/triangular_kac_moody_algebras.py +++ b/src/sage/categories/triangular_kac_moody_algebras.py @@ -19,12 +19,14 @@ from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.categories.category_types import Category_over_base_ring +from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring from sage.categories.kac_moody_algebras import KacMoodyAlgebras class TriangularKacMoodyAlgebras(Category_over_base_ring): - """ + r""" Category of Kac-Moody algebras with a distinguished basis that respects the triangular decomposition. @@ -40,7 +42,6 @@ def super_categories(self): sage: TriangularKacMoodyAlgebras(QQ).super_categories() [Join of Category of graded Lie algebras with basis over Rational Field and Category of kac moody algebras over Rational Field] - """ # We do not also derive from (Magmatic) algebras since we don't want * # to be our Lie bracket @@ -61,11 +62,18 @@ def _part_on_basis(self, m): EXAMPLES:: - sage: L = lie_algebras.so(QQ, 5) # needs sage.combinat sage.modules - sage: L.f() # needs sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: L = lie_algebras.so(QQ, 5) + sage: L.f() # indirect doctest Finite family {1: E[-alpha[1]], 2: E[-alpha[2]]} - sage: L.f(1) # needs sage.combinat sage.modules + sage: f1 = L.f(1); f1 # indirect doctest E[-alpha[1]] + sage: L._part_on_basis(f1.leading_support()) + -1 + sage: L._part_on_basis(L.e(1).leading_support()) + 1 + sage: all(L._part_on_basis(b) == 0 for b in L.basis() if b.degree() == 0) + True """ deg = self.degree_on_basis(m) if not deg: @@ -200,6 +208,30 @@ def _weight_action(self, m, wt): 0 """ + def _triangular_key(self, x): + r""" + Return a key for sorting for the index ``x`` that respects + the triangular decomposition by `U^-, U^0, U^+`. + + EXAMPLES:: + + sage: # needs sage.combinat sage.modules + sage: L = lie_algebras.sl(QQ, 3) + sage: La = L.cartan_type().root_system().weight_lattice().fundamental_weights() + sage: sorted(L.basis().keys(), key=L._basis_key) + [alpha[2], alpha[1], alpha[1] + alpha[2], + alphacheck[1], alphacheck[2], + -alpha[2], -alpha[1], -alpha[1] - alpha[2]] + sage: sorted(L.basis().keys(), key=L._triangular_key) + [-alpha[2], -alpha[1], -alpha[1] - alpha[2], + alphacheck[1], alphacheck[2], + alpha[2], alpha[1], alpha[1] + alpha[2]] + """ + try: + return (self._part_on_basis(x), self._basis_key(x)) + except AttributeError: + return (self._part_on_basis(x), x) + def verma_module(self, la, basis_key=None, **kwds): """ Return the Verma module with highest weight ``la`` @@ -224,6 +256,49 @@ def verma_module(self, la, basis_key=None, **kwds): from sage.algebras.lie_algebras.verma_module import VermaModule return VermaModule(self, la, basis_key=basis_key, **kwds) + def simple_module(self, la, basis_key=None, **kwds): + r""" + Return the simple module with highest weight ``la`` + over ``self``. + + INPUT: + + - ``la`` -- the weight + - ``basis_key`` -- (optional) a key function for the indexing + set of the basis elements of ``self`` + + OUTPUT: + + If ``la`` is :meth:`Verma antidominant + `, + then this returns the + :class:`~sage.algebras.lie_algebras.verma_module.VermaModule` + of highest weight ``la`` (which is simple and more efficient). + Otherwise this returns a + :class:`~sage.algebras.lie_algebras.bgg_dual_module.SimpleModule`. + + EXAMPLES:: + + sage: # needs sage.combinat sage.modules + sage: g = lie_algebras.sl(QQ, 3) + sage: P = g.cartan_type().root_system().weight_lattice() + sage: La = P.fundamental_weights() + sage: L = g.simple_module(La[1] + La[2]) + sage: L + Simple module with highest weight Lambda[1] + Lambda[2] + of Lie algebra of ['A', 2] in the Chevalley basis + sage: L = g.simple_module(-La[1] - La[2]) + sage: L + Verma module with highest weight -Lambda[1] - Lambda[2] + of Lie algebra of ['A', 2] in the Chevalley basis + """ + if la.is_verma_dominant(positive=False): + from sage.algebras.lie_algebras.verma_module import VermaModule + return VermaModule(self, la, basis_key=basis_key, **kwds) + + from sage.algebras.lie_algebras.bgg_dual_module import SimpleModule + return SimpleModule(self, la, basis_key=basis_key, **kwds) + class ElementMethods: def part(self): """ @@ -238,7 +313,7 @@ def part(self): EXAMPLES:: sage: # needs sage.combinat sage.modules - sage: L = LieAlgebra(QQ, cartan_type="F4") + sage: L = LieAlgebra(QQ, cartan_type='F4') sage: L.inject_variables() Defining e1, e2, e3, e4, f1, f2, f3, f4, h1, h2, h3, h4 sage: e1.part() @@ -263,3 +338,103 @@ def part(self): if all(k == 0 for k in S): return 0 raise ValueError("element is not in one part") + + class FiniteDimensional(CategoryWithAxiom_over_base_ring): + r""" + Category of finite dimensional Kac-Moody algebras (which correspond + to semisimple Lie algebras) with a distinguished basis that + respects the triangular decomposition. + """ + class ParentMethods: + @lazy_attribute + def _transpose_basis_mapping(self): + """ + The mapping on basis elements for the transpose map. + + EXAMPLES:: + + sage: # needs sage.combinat sage.modules + sage: g = LieAlgebra(QQ, cartan_type=['A', 2]) + sage: g._transpose_basis_mapping + {-alpha[1]: alpha[1], + -alpha[1] - alpha[2]: alpha[1] + alpha[2], + -alpha[2]: alpha[2], + alpha[1]: -alpha[1], + alpha[1] + alpha[2]: -alpha[1] - alpha[2], + alpha[2]: -alpha[2], + alphacheck[1]: alphacheck[1], + alphacheck[2]: alphacheck[2]} + """ + Q = self.cartan_type().root_system().root_lattice() + K = self.basis().keys() + deg_map = {} + ret = {} + for k in K: + deg = self.degree_on_basis(k) + if deg: + deg_map[deg] = k + else: + ret[k] = k + for al, k in deg_map.items(): + ret[k] = deg_map[-al] + return ret + + @cached_method + def _transpose_on_basis(self, m): + r""" + Return the transpose map on the basis element indexed by ``m``. + + EXAMPLES:: + + sage: # needs sage.combinat sage.modules + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: B = g.basis() + sage: [(B[k], g._transpose_on_basis(k)) for k in B.keys()] + [(E[alpha[2]], E[-alpha[2]]), + (E[alpha[1]], E[-alpha[1]]), + (E[alpha[1] + alpha[2]], E[-alpha[1] - alpha[2]]), + (E[alpha[1] + 2*alpha[2]], E[-alpha[1] - 2*alpha[2]]), + (h1, h1), + (h2, h2), + (E[-alpha[2]], E[alpha[2]]), + (E[-alpha[1]], E[alpha[1]]), + (E[-alpha[1] - alpha[2]], E[alpha[1] + alpha[2]]), + (E[-alpha[1] - 2*alpha[2]], E[alpha[1] + 2*alpha[2]])] + """ + return self.monomial(self._transpose_basis_mapping[m]) + + @lazy_attribute + def transpose(self): + r""" + The transpose map of ``self``. + + EXAMPLES:: + + sage: # needs sage.combinat sage.modules + sage: g = LieAlgebra(QQ, cartan_type=['B', 2]) + sage: g.transpose + Generic endomorphism of Lie algebra of ['B', 2] in the Chevalley basis + """ + return self.module_morphism(self._transpose_on_basis, codomain=self) + + class ElementMethods: + def transpose(self): + r""" + Return the transpose of ``self``. + + The transpose `\tau` is the map that sends the root basis + elements `e_{\alpha} \leftrightarrow e_{-\alpha}` and fixes + the Cartan subalgebra `h_{\alpha}`. It is an anti-involution + in the sense `[\tau(a), \tau(b)] = \tau([b, a])`. + + EXAMPLES:: + + sage: # needs sage.combinat sage.modules + sage: g = LieAlgebra(QQ, cartan_type=['G', 2]) + sage: for b in g.basis(): + ....: for bp in g.basis(): + ....: a = g[b.transpose(), bp.transpose()] + ....: ap = g[bp, b].transpose() + ....: assert a == ap + """ + return self.parent().transpose(self) diff --git a/src/sage/categories/unique_factorization_domains.py b/src/sage/categories/unique_factorization_domains.py index a4a66111f4b..0189898f6d0 100644 --- a/src/sage/categories/unique_factorization_domains.py +++ b/src/sage/categories/unique_factorization_domains.py @@ -34,7 +34,6 @@ class UniqueFactorizationDomains(Category_singleton): TESTS:: sage: TestSuite(UniqueFactorizationDomains()).run() - """ def super_categories(self): @@ -127,7 +126,6 @@ def is_unique_factorization_domain(self, proof=True): sage: UFD = UniqueFactorizationDomains() sage: Parent(QQ, category=UFD).is_unique_factorization_domain() True - """ return True @@ -137,7 +135,7 @@ def _gcd_univariate_polynomial(self, f, g): INPUT: - - ``f``, ``g`` -- two polynomials defined over this UFD. + - ``f``, ``g`` -- two polynomials defined over this UFD .. NOTE:: @@ -169,7 +167,6 @@ def _gcd_univariate_polynomial(self, f, g): sage: g = 4*x + 2 sage: f.gcd(g).parent() is R True - """ if f.degree() < g.degree(): A,B = g, f @@ -294,7 +291,6 @@ def squarefree_part(self): sage: squarefree_part(pol) 37*x^3 - 1369/21*x^2 + 703/21*x - 37/7 - """ decomp = self.squarefree_decomposition() return prod(fac for fac, mult in decomp if mult % 2 == 1) diff --git a/src/sage/categories/vector_bundles.py b/src/sage/categories/vector_bundles.py index bd6e569ba36..4d87464bd18 100644 --- a/src/sage/categories/vector_bundles.py +++ b/src/sage/categories/vector_bundles.py @@ -35,8 +35,7 @@ class VectorBundles(Category_over_base_ring): TESTS:: - sage: TestSuite(C).run(skip="_test_category_over_bases") - + sage: TestSuite(C).run(skip='_test_category_over_bases') """ def __init__(self, base_space, base_field, name=None): r""" @@ -47,8 +46,7 @@ def __init__(self, base_space, base_field, name=None): sage: M = Manifold(2, 'M') sage: from sage.categories.vector_bundles import VectorBundles sage: C = VectorBundles(M, RR) - sage: TestSuite(C).run(skip="_test_category_over_bases") - + sage: TestSuite(C).run(skip='_test_category_over_bases') """ if base_field not in Fields().Topological(): raise ValueError("base field must be a topological field") @@ -64,7 +62,6 @@ def super_categories(self): sage: from sage.categories.vector_bundles import VectorBundles sage: VectorBundles(M, RR).super_categories() [Category of topological spaces] - """ return [Sets().Topological()] @@ -78,7 +75,6 @@ def base_space(self): sage: from sage.categories.vector_bundles import VectorBundles sage: VectorBundles(M, RR).base_space() 2-dimensional topological manifold M - """ return self._base_space @@ -95,7 +91,6 @@ def _repr_object_names(self): sage: VectorBundles(M, RR)._repr_object_names() 'vector bundles over Real Field with 53 bits of precision with base space 2-dimensional differentiable manifold M' - """ base_space = self._base_space return Category_over_base_ring._repr_object_names(self) + \ @@ -122,7 +117,6 @@ def Differentiable(self): sage: TestSuite(VectorBundles(M, RR).Differentiable()).run() sage: VectorBundles(M, RR).Differentiable.__module__ 'sage.categories.vector_bundles' - """ return self._with_axiom('Differentiable') diff --git a/src/sage/categories/vector_spaces.py b/src/sage/categories/vector_spaces.py index 84286a83bc4..d0da56da108 100644 --- a/src/sage/categories/vector_spaces.py +++ b/src/sage/categories/vector_spaces.py @@ -27,7 +27,7 @@ class VectorSpaces(Category_module): """ - The category of (abstract) vector spaces over a given field + The category of (abstract) vector spaces over a given field. ??? with an embedding in an ambient vector space ??? @@ -43,8 +43,9 @@ def __classcall_private__(cls, K, check=True): """ INPUT: - - `K` -- a field - - ``check`` -- a boolean (default: ``True``) whether to check that `K` is a field. + - ``K`` -- a field + - ``check`` -- boolean (default: ``True``); whether to check that `K` + is a field EXAMPLES:: @@ -92,7 +93,7 @@ def __init__(self, K): def _call_(self, x): """ - Try to coerce ``x`` into an object of this category + Try to coerce ``x`` into an object of this category. EXAMPLES:: @@ -106,7 +107,6 @@ def _call_(self, x): sage: Q3 = FiniteRankFreeModule(QQ, 3) # needs sage.modules sage: Modules(QQ)(Q3) is Q3 # needs sage.modules True - """ try: V = x.vector_space(self.base_field()) @@ -118,7 +118,7 @@ def _call_(self, x): def base_field(self): """ - Returns the base field over which the vector spaces of this + Return the base field over which the vector spaces of this category are all defined. EXAMPLES:: @@ -174,7 +174,6 @@ def dimension(self): 3 sage: M.tensor_module(1, 2).dimension() # needs sage.modules 27 - """ return self.rank() @@ -239,7 +238,6 @@ def extra_super_categories(self): [Category of finite dimensional vector spaces with basis over Rational Field] sage: VectorSpaces(QQ).WithBasis().FiniteDimensional().TensorProducts().FiniteDimensional() Category of tensor products of finite dimensional vector spaces with basis over Rational Field - """ return [self.base_category()] @@ -300,7 +298,6 @@ def extra_super_categories(self): [Category of finite dimensional vector spaces over Rational Field] sage: VectorSpaces(QQ).FiniteDimensional().TensorProducts().FiniteDimensional() Category of tensor products of finite dimensional vector spaces over Rational Field - """ return [self.base_category()] @@ -308,7 +305,7 @@ class DualObjects(DualObjectsCategory): def extra_super_categories(self): r""" - Returns the dual category + Return the dual category. EXAMPLES: diff --git a/src/sage/categories/weyl_groups.py b/src/sage/categories/weyl_groups.py index aa2d4cd6f11..8472aaa455c 100644 --- a/src/sage/categories/weyl_groups.py +++ b/src/sage/categories/weyl_groups.py @@ -18,7 +18,7 @@ class WeylGroups(Category_singleton): r""" - The category of Weyl groups + The category of Weyl groups. See the :wikipedia:`Wikipedia page of Weyl Groups `. @@ -94,7 +94,7 @@ def coxeter_matrix(self): def pieri_factors(self, *args, **keywords): r""" - Returns the set of Pieri factors in this Weyl group. + Return the set of Pieri factors in this Weyl group. For any type, the set of Pieri factors forms a lower ideal in Bruhat order, generated by all the conjugates of some @@ -171,7 +171,7 @@ def bruhat_cone(self, x, y, side='upper', backend='cdd'): - ``y`` -- an element in the group `W` - - ``side`` (default: ``'upper'``) -- must be one of the following: + - ``side`` -- (default: ``'upper'``) must be one of the following: * ``'upper'`` -- return the upper Bruhat cone of the interval [``x``, ``y``] * ``'lower'`` -- return the lower Bruhat cone of the interval [``x``, ``y``] @@ -243,7 +243,7 @@ def quantum_bruhat_graph(self, index_set=()): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s") + sage: W = WeylGroup(['A',3], prefix='s') sage: g = W.quantum_bruhat_graph((1,3)) sage: g Parabolic Quantum Bruhat Graph of Weyl Group of type ['A', 3] @@ -260,7 +260,7 @@ def quantum_bruhat_graph(self, index_set=()): (s2, s1*s2, alpha[1] + alpha[2]), (s2, s3*s2, alpha[2] + alpha[3]), (1, s2, alpha[2])] - sage: W = WeylGroup(['A',3,1], prefix="s") + sage: W = WeylGroup(['A',3,1], prefix='s') sage: g = W.quantum_bruhat_graph() Traceback (most recent call last): ... @@ -317,14 +317,14 @@ def length(x): from sage.graphs.digraph import DiGraph return DiGraph(visited, name="Parabolic Quantum Bruhat Graph of %s for nodes %s" % (self, index_set), - format="dict_of_dicts", - data_structure="static_sparse") + format='dict_of_dicts', + data_structure='static_sparse') class ElementMethods: def is_pieri_factor(self): r""" - Returns whether ``self`` is a Pieri factor, as used for + Return whether ``self`` is a Pieri factor, as used for computing Stanley symmetric functions. .. SEEALSO:: @@ -357,7 +357,7 @@ def is_pieri_factor(self): def left_pieri_factorizations(self, max_length=None): r""" - Returns all factorizations of ``self`` as `uv`, where `u` + Return all factorizations of ``self`` as `uv`, where `u` is a Pieri factor and `v` is an element of the Weyl group. .. SEEALSO:: @@ -426,7 +426,7 @@ def predicate(u): @cached_in_parent_method def stanley_symmetric_function_as_polynomial(self, max_length=None): r""" - Returns a multivariate generating function for the number + Return a multivariate generating function for the number of factorizations of a Weyl group element into Pieri factors of decreasing length, weighted by a statistic on Pieri factors. @@ -440,7 +440,7 @@ def stanley_symmetric_function_as_polynomial(self, max_length=None): INPUT: - ``self`` -- an element `w` of a Weyl group `W` - - ``max_length`` -- a non negative integer or infinity (default: infinity) + - ``max_length`` -- nonnegative integer or infinity (default: infinity) Returns the generating series for the Pieri factorizations `w = u_1 \cdots u_k`, where `u_i` is a Pieri factor for @@ -585,7 +585,7 @@ def reflection_to_root(self): EXAMPLES:: - sage: W = WeylGroup(['C',2],prefix="s") + sage: W = WeylGroup(['C',2], prefix='s') sage: W.from_reduced_word([1,2,1]).reflection_to_root() 2*alpha[1] + alpha[2] sage: W.from_reduced_word([1,2]).reflection_to_root() @@ -614,7 +614,7 @@ def reflection_to_coroot(self): EXAMPLES:: - sage: W = WeylGroup(['C',2],prefix="s") + sage: W = WeylGroup(['C',2], prefix='s') sage: W.from_reduced_word([1,2,1]).reflection_to_coroot() alphacheck[1] + alphacheck[2] sage: W.from_reduced_word([1,2]).reflection_to_coroot() @@ -655,7 +655,7 @@ def inversions(self, side='right', inversion_type='reflections'): EXAMPLES:: - sage: W = WeylGroup(['C',2], prefix="s") + sage: W = WeylGroup(['C',2], prefix='s') sage: w = W.from_reduced_word([1,2]) sage: w.inversions() [s2, s2*s1*s2] @@ -743,7 +743,7 @@ def bruhat_lower_covers_coroots(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s") + sage: W = WeylGroup(['A',3], prefix='s') sage: w = W.from_reduced_word([3,1,2,1]) sage: w.bruhat_lower_covers_coroots() [(s1*s2*s1, alphacheck[1] + alphacheck[2] + alphacheck[3]), @@ -754,7 +754,7 @@ def bruhat_lower_covers_coroots(self): def bruhat_upper_covers_coroots(self): r""" - Returns all 2-tuples (``v``, `\alpha`) where ``v`` is covers ``self`` and `\alpha` + Return all 2-tuples (``v``, `\alpha`) where ``v`` is covers ``self`` and `\alpha` is the positive coroot such that ``self`` = ``v`` `s_\alpha` where `s_\alpha` is the reflection orthogonal to `\alpha`. @@ -764,7 +764,7 @@ def bruhat_upper_covers_coroots(self): EXAMPLES:: - sage: W = WeylGroup(['A',4], prefix="s") + sage: W = WeylGroup(['A',4], prefix='s') sage: w = W.from_reduced_word([3,1,2,1]) sage: w.bruhat_upper_covers_coroots() [(s1*s2*s3*s2*s1, alphacheck[3]), @@ -791,17 +791,17 @@ def quantum_bruhat_successors(self, index_set=None, roots=False, quantum_only=Fa simple reflections used to generate the parabolic subgroup; the default value indicates that the subgroup is the identity - - ``roots`` -- (default: ``False``) if ``True``, returns the - list of 2-tuples (``w``, `\alpha`) where ``w`` is a successor + - ``roots`` -- boolean (default: ``False``); if ``True``, returns + the list of 2-tuples (``w``, `\alpha`) where ``w`` is a successor and `\alpha` is the positive root associated with the successor relation - - ``quantum_only`` -- (default: ``False``) if ``True``, returns - only the quantum successors + - ``quantum_only`` -- boolean (default: ``False``); if ``True``, + returns only the quantum successors EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s") + sage: W = WeylGroup(['A',3], prefix='s') sage: w = W.from_reduced_word([3,1,2]) sage: w.quantum_bruhat_successors([1], roots = True) [(s3, alpha[2]), (s1*s2*s3*s2, alpha[3]), diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index ca46d40327b..d94eb1ca309 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -205,7 +205,7 @@ class AbstractCode(Parent): def __init__(self, length, default_encoder_name=None, default_decoder_name=None, metric='Hamming'): r""" - Initializes mandatory parameters that any code shares. + Initialize mandatory parameters that any code shares. This method only exists for inheritance purposes as it initializes parameters that need to be known by every code. The class @@ -281,19 +281,19 @@ def __init__(self, length, default_encoder_name=None, ... ValueError: length must be a Python int or a Sage Integer - If the length of the code is not a non-zero positive integer + If the length of the code is not a nonzero positive integer (See :issue:`21326`), it will raise an exception:: sage: C = MyCodeFamily(0) Traceback (most recent call last): ... - ValueError: length must be a non-zero positive integer + ValueError: length must be a nonzero positive integer """ if not isinstance(length, (int, Integer)): raise ValueError("length must be a Python int or a Sage Integer") if length <= 0: - raise ValueError("length must be a non-zero positive integer") + raise ValueError("length must be a nonzero positive integer") self._length = length self._metric = metric @@ -398,7 +398,7 @@ def ambient_space(self): def __call__(self, m): r""" - Returns either ``m`` if it is a codeword or ``self.encode(m)`` + Return either ``m`` if it is a codeword or ``self.encode(m)`` if it is an element of the message space of the encoder used by ``encode``. @@ -516,7 +516,7 @@ def list(self): def length(self): r""" - Returns the length of this code. + Return the length of this code. EXAMPLES:: @@ -542,7 +542,7 @@ def metric(self): def add_decoder(self, name, decoder): r""" - Adds an decoder to the list of registered decoders of ``self``. + Add an decoder to the list of registered decoders of ``self``. .. NOTE:: @@ -604,7 +604,7 @@ def add_decoder(self, name, decoder): def add_encoder(self, name, encoder): r""" - Adds an encoder to the list of registered encoders of ``self``. + Add an encoder to the list of registered encoders of ``self``. .. NOTE:: @@ -672,15 +672,13 @@ def decode_to_code(self, word, decoder_name=None, *args, **kwargs): - ``word`` -- an element in the ambient space as ``self`` - - ``decoder_name`` -- (default: ``None``) Name of the decoder which will be used + - ``decoder_name`` -- (default: ``None``) name of the decoder which will be used to decode ``word``. The default decoder of ``self`` will be used if default value is kept. - ``args``, ``kwargs`` -- all additional arguments are forwarded to :meth:`decoder` - OUTPUT: - - - A vector of ``self``. + OUTPUT: a vector of ``self`` EXAMPLES:: @@ -710,15 +708,13 @@ def decode_to_message(self, word, decoder_name=None, *args, **kwargs): - ``word`` -- an element in the ambient space as ``self`` - - ``decoder_name`` -- (default: ``None``) Name of the decoder which will be used + - ``decoder_name`` -- (default: ``None``) name of the decoder which will be used to decode ``word``. The default decoder of ``self`` will be used if default value is kept. - ``args``, ``kwargs`` -- all additional arguments are forwarded to :meth:`decoder` - OUTPUT: - - - A vector of the message space of ``self``. + OUTPUT: a vector of the message space of ``self`` EXAMPLES:: @@ -752,9 +748,7 @@ def decoder(self, decoder_name=None, *args, **kwargs): - ``args``, ``kwargs`` -- all additional arguments will be forwarded to the constructor of the decoder that will be returned by this method - OUTPUT: - - - a decoder object + OUTPUT: a decoder object Besides creating the decoder and returning it, this method also stores the decoder in a cache. With this behaviour, each decoder will be created @@ -810,7 +804,6 @@ def decoder(self, decoder_name=None, *args, **kwargs): It accepts unspecified arguments as well. See the documentation of sage.coding.information_set_decoder.LinearCodeInformationSetDecoder for more details. - """ if not self._default_decoder_name: raise NotImplementedError("No decoder implemented for this code.") @@ -832,15 +825,15 @@ def decoder(self, decoder_name=None, *args, **kwargs): def decoders_available(self, classes=False): r""" - Returns a list of the available decoders' names for ``self``. + Return a list of the available decoders' names for ``self``. INPUT: - - ``classes`` -- (default: ``False``) if ``classes`` is set to ``True``, - return instead a :class:`dict` mapping available decoder name to the - associated decoder class. + - ``classes`` -- boolean (default: ``False``); if ``classes`` is set to + ``True``, return instead a :class:`dict` mapping available decoder + name to the associated decoder class - OUTPUT: a list of strings, or a :class:`dict` mapping strings to classes. + OUTPUT: list of strings, or a :class:`dict` mapping strings to classes EXAMPLES:: @@ -863,26 +856,24 @@ def decoders_available(self, classes=False): def encode(self, word, encoder_name=None, *args, **kwargs): r""" - Transforms an element of a message space into a codeword. + Transform an element of a message space into a codeword. INPUT: - ``word`` -- an element of a message space of the code - - ``encoder_name`` -- (default: ``None``) Name of the encoder which will be used - to encode ``word``. The default encoder of ``self`` will be used if - default value is kept. + - ``encoder_name`` -- (default: ``None``) name of the encoder which + will be used to encode ``word``. The default encoder of ``self`` will + be used if default value is kept. - - ``args``, ``kwargs`` -- all additional arguments are forwarded to the construction of the - encoder that is used.. + - ``args``, ``kwargs`` -- all additional arguments are forwarded to the + construction of the encoder that is used One can use the following shortcut to encode a word :: C(word) - OUTPUT: - - - a vector of ``self``. + OUTPUT: a vector of ``self`` EXAMPLES:: @@ -909,7 +900,7 @@ def encode(self, word, encoder_name=None, *args, **kwargs): @cached_method def encoder(self, encoder_name=None, *args, **kwargs): r""" - Returns an encoder of ``self``. + Return an encoder of ``self``. The returned encoder provided by this method is cached. @@ -923,12 +914,10 @@ def encoder(self, encoder_name=None, *args, **kwargs): returned. The default encoder of ``self`` will be used if default value is kept. - - ``args``, ``kwargs`` -- all additional arguments are forwarded to the constructor of the encoder - this method will return. - - OUTPUT: + - ``args``, ``kwargs`` -- all additional arguments are forwarded to the + constructor of the encoder this method will return - - an Encoder object. + OUTPUT: an Encoder object .. NOTE:: @@ -1011,15 +1000,15 @@ def encoder(self, encoder_name=None, *args, **kwargs): def encoders_available(self, classes=False): r""" - Returns a list of the available encoders' names for ``self``. + Return a list of the available encoders' names for ``self``. INPUT: - - ``classes`` -- (default: ``False``) if ``classes`` is set to ``True``, - return instead a :class:`dict` mapping available encoder name to the - associated encoder class. + - ``classes`` -- boolean (default: ``False``); if ``classes`` is set to + ``True``, return instead a :class:`dict` mapping available encoder + name to the associated encoder class - OUTPUT: a list of strings, or a :class:`dict` mapping strings to classes. + OUTPUT: list of strings, or a :class:`dict` mapping strings to classes EXAMPLES:: @@ -1040,29 +1029,28 @@ def encoders_available(self, classes=False): def unencode(self, c, encoder_name=None, nocheck=False, **kwargs): r""" - Returns the message corresponding to ``c``. + Return the message corresponding to ``c``. This is the inverse of :meth:`encode`. INPUT: - - ``c`` -- a codeword of ``self``. + - ``c`` -- a codeword of ``self`` - ``encoder_name`` -- (default: ``None``) name of the decoder which will be used to decode ``word``. The default decoder of ``self`` will be used if default value is kept. - - ``nocheck`` -- (default: ``False``) checks if ``c`` is in ``self``. You might set - this to ``True`` to disable the check for saving computation. Note that if ``c`` is - not in ``self`` and ``nocheck = True``, then the output of :meth:`unencode` is - not defined (except that it will be in the message space of ``self``). + - ``nocheck`` -- boolean (default: ``False``); checks if ``c`` is in + ``self``. You might set this to ``True`` to disable the check for + saving computation. Note that if ``c`` is not in ``self`` and + ``nocheck = True``, then the output of :meth:`unencode` is not + defined (except that it will be in the message space of ``self``). - ``kwargs`` -- all additional arguments are forwarded to the construction of the - encoder that is used. + encoder that is used - OUTPUT: - - - an element of the message space of ``encoder_name`` of ``self``. + OUTPUT: an element of the message space of ``encoder_name`` of ``self`` EXAMPLES:: @@ -1078,12 +1066,10 @@ def unencode(self, c, encoder_name=None, nocheck=False, **kwargs): def random_element(self, *args, **kwds): """ - Returns a random codeword; passes other positional and keyword + Return a random codeword; passes other positional and keyword arguments to ``random_element()`` method of vector space. - OUTPUT: - - - Random element of the vector space of this code + OUTPUT: random element of the vector space of this code EXAMPLES:: diff --git a/src/sage/coding/ag_code.py b/src/sage/coding/ag_code.py index a29cbe7e7d0..5f77b346fa4 100644 --- a/src/sage/coding/ag_code.py +++ b/src/sage/coding/ag_code.py @@ -120,7 +120,7 @@ class EvaluationAGCode(AGCode): INPUT: - - ``pls`` -- a list of rational places of a function field + - ``pls`` -- list of rational places of a function field - ``G`` -- a divisor whose support is disjoint from ``pls`` @@ -331,7 +331,7 @@ def designed_distance(self): """ Return the designed distance of the AG code. - If the code is of dimension zero, then a :class:`ValueError` is raised. + If the code is of dimension zero, then a :exc:`ValueError` is raised. EXAMPLES:: @@ -355,11 +355,11 @@ def designed_distance(self): class DifferentialAGCode(AGCode): """ - Differential AG code defined by rational places ``pls`` and a divisor ``G`` + Differential AG code defined by rational places ``pls`` and a divisor ``G``. INPUT: - - ``pls`` -- a list of rational places of a function field + - ``pls`` -- list of rational places of a function field - ``G`` -- a divisor whose support is disjoint from ``pls`` @@ -575,7 +575,7 @@ def designed_distance(self): """ Return the designed distance of the differential AG code. - If the code is of dimension zero, then a :class:`ValueError` is raised. + If the code is of dimension zero, then a :exc:`ValueError` is raised. EXAMPLES:: @@ -603,7 +603,7 @@ class CartierCode(AGCode): INPUT: - - ``pls`` -- a list of rational places + - ``pls`` -- list of rational places - ``G`` -- a divisor whose support is disjoint from ``pls`` @@ -611,7 +611,7 @@ class CartierCode(AGCode): - ``name`` -- string; name of the generator of the subfield `\GF{p^r}` - OUTPUT: Cartier code over `\GF{p^r}` where `p` is the characteristic of the + OUTPUT: cartier code over `\GF{p^r}` where `p` is the characteristic of the base constant field of the function field Note that if ``r`` is 1 the default, then ``name`` can be omitted. diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index ceb3eb327fd..df59bad740d 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -76,7 +76,7 @@ from sage.rings.polynomial.polynomial_element cimport Polynomial class EvaluationAGCodeEncoder(Encoder): """ - Encoder of an evaluation AG code + Encoder of an evaluation AG code. INPUT: @@ -1464,7 +1464,7 @@ cdef class Decoder_K(): - ``detect_Q_polynomial`` -- boolean; if ``True``, a Q-polynomial is detected for fast decoding - If decoding fails for some reason, ``DecodingError`` is raised. The + If decoding fails for some reason, :exc:`DecodingError` is raised. The message contained in the exception indicates the type of the decoding failure. @@ -1811,13 +1811,13 @@ cdef class EvaluationAGCodeDecoder_K(Decoder_K): INPUT: - - ``pls`` -- a list of places of a function field + - ``pls`` -- list of places of a function field - ``G`` -- a divisor of the function field - ``Q`` -- a rational place not in ``pls`` - - ``verbose`` -- if ``True``, verbose information is printed. + - ``verbose`` -- if ``True``, verbose information is printed EXAMPLES:: @@ -2066,7 +2066,7 @@ cdef class DifferentialAGCodeDecoder_K(Decoder_K): INPUT: - - ``pls`` -- a list of places of a function field + - ``pls`` -- list of places of a function field - ``G`` -- a divisor of the function field @@ -2320,7 +2320,7 @@ cdef class Decoder_K_extension(): INPUT: - - ``pls`` -- a list of places of a function field + - ``pls`` -- list of places of a function field - ``G`` -- a divisor of the function field @@ -2538,7 +2538,7 @@ cdef class EvaluationAGCodeDecoder_K_extension(Decoder_K_extension): INPUT: - - ``pls`` -- a list of places of a function field + - ``pls`` -- list of places of a function field - ``G`` -- a divisor of the function field @@ -2592,7 +2592,7 @@ cdef class DifferentialAGCodeDecoder_K_extension(Decoder_K_extension): INPUT: - - ``pls`` -- a list of places of a function field + - ``pls`` -- list of places of a function field - ``G`` -- a divisor of the function field diff --git a/src/sage/coding/bch_code.py b/src/sage/coding/bch_code.py index 1344ba42f65..ebd9d7bc3b4 100644 --- a/src/sage/coding/bch_code.py +++ b/src/sage/coding/bch_code.py @@ -35,6 +35,7 @@ from .grs_code import GeneralizedReedSolomonCode from .decoder import Decoder + class BCHCode(CyclicCode): r""" Representation of a BCH code seen as a cyclic code. @@ -140,7 +141,7 @@ def __init__(self, base_field, length, designed_distance, def __eq__(self, other): r""" - Tests equality between BCH Code objects. + Test equality between BCH Code objects. EXAMPLES:: @@ -262,15 +263,15 @@ class BCHUnderlyingGRSDecoder(Decoder): INPUT: - - ``code`` -- The associated code of this decoder. + - ``code`` -- the associated code of this decoder - - ``grs_decoder`` -- The string name of the decoder to use over the + - ``grs_decoder`` -- the string name of the decoder to use over the underlying GRS code - - ``**kwargs`` -- All extra arguments are forwarded to the GRS decoder + - ``**kwargs`` -- all extra arguments are forwarded to the GRS decoder """ - def __init__(self, code, grs_decoder="KeyEquationSyndrome", **kwargs): + def __init__(self, code, grs_decoder='KeyEquationSyndrome', **kwargs): r""" EXAMPLES:: diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 421422c7746..3c73e0f7176 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -88,7 +88,7 @@ cdef int *hamming_weights() noexcept: def weight_dist(M): """ - Computes the weight distribution of the row space of `M`. + Compute the weight distribution of the row space of `M`. EXAMPLES:: @@ -119,7 +119,6 @@ def weight_dist(M): ....: [0,0,0,0,0,0,0,1,0,0,1,1,1,1,0,0,1]]) sage: weight_dist(M) [1, 0, 0, 0, 0, 0, 68, 0, 85, 0, 68, 0, 34, 0, 0, 0, 0, 0] - """ cdef bitset_t word cdef int i,j,k, dim=M.nrows(), deg=M.ncols() @@ -193,7 +192,6 @@ def test_word_perms(t_limit=5.0): sage: from sage.coding.binary_code import test_word_perms sage: test_word_perms() # long time (5s on sage.math, 2011) - """ cdef WordPermutation *g cdef WordPermutation *h @@ -557,7 +555,6 @@ def test_expand_to_ortho_basis(B=None): 0000100001 0000010001 0000001001 - """ cdef codeword *output cdef int k=0, i @@ -581,8 +578,8 @@ cdef codeword *expand_to_ortho_basis(BinaryCode B, int n) noexcept: r""" INPUT: - - B -- a BinaryCode in standard form - - n -- the degree + - ``B`` -- a BinaryCode in standard form + - ``n`` -- the degree OUTPUT: @@ -738,7 +735,6 @@ cdef class BinaryCode: sage: B Binary [32,1] linear code, generator matrix [11111111111111111111111111111111] - """ def __cinit__(self, arg1, arg2=None): """ @@ -848,7 +844,6 @@ cdef class BinaryCode: sage: B = BinaryCode(M) sage: loads(dumps(B)) == B True - """ return BinaryCode, (self.matrix(),) @@ -882,7 +877,6 @@ cdef class BinaryCode: sage: B.matrix() [1 1 1 1 0 0] [0 0 1 1 1 1] - """ cdef int i, j from sage.matrix.constructor import matrix @@ -1016,7 +1010,6 @@ cdef class BinaryCode: [00111100] [00001111] [10101010] - """ cdef int i, j s = 'Binary [%d,%d] linear code, generator matrix\n'%(self.ncols, self.nrows) @@ -1026,9 +1019,9 @@ cdef class BinaryCode: def _word(self, coords): """ - Considering coords as an integer in binary, think of the 0's and 1's as - coefficients of the basis given by self.matrix(). This function returns - a string representation of that word. + Considering ``coords`` as an integer in binary, think of the 0s and 1s + as coefficients of the basis given by ``self.matrix()``. This function + returns a string representation of that word. EXAMPLES:: @@ -1042,7 +1035,6 @@ cdef class BinaryCode: Note that behavior under input which does not represent a word in the code is unspecified (gives nonsense). - """ s = '' for j from 0 <= j < self.ncols: @@ -1051,7 +1043,7 @@ cdef class BinaryCode: def _is_one(self, word, col): """ - Returns the col-th letter of word, i.e. 0 or 1. Words are expressed + Return the col-th letter of word, i.e. 0 or 1. Words are expressed as integers, which represent linear combinations of the rows of the generator matrix of the code. @@ -1073,7 +1065,6 @@ cdef class BinaryCode: 1 sage: B._is_automorphism([1,0,3,2,4,5,6,7], [0, 1, 2, 3, 4, 5, 6, 7, 9, 8, 11, 10, 13, 12, 15, 14]) 1 - """ return self.is_one(word, col) != 0 @@ -1086,10 +1077,10 @@ cdef class BinaryCode: INPUT: - - col_gamma -- permutation sending i |--> col_gamma[i] acting - on the columns. - - word_gamma -- permutation sending i |--> word_gamma[i] acting - on the words. + - ``col_gamma`` -- permutation sending i |--> col_gamma[i] acting + on the columns + - ``word_gamma`` -- permutation sending i |--> word_gamma[i] acting + on the words EXAMPLES:: @@ -1105,7 +1096,6 @@ cdef class BinaryCode: [10101010] sage: B._is_automorphism([1,0,3,2,4,5,6,7], [0, 1, 2, 3, 4, 5, 6, 7, 9, 8, 11, 10, 13, 12, 15, 14]) 1 - """ cdef int i cdef int *_col_gamma @@ -1141,7 +1131,7 @@ cdef class BinaryCode: INPUT: - - labeling -- a list permutation of the columns + - ``labeling`` -- list permutation of the columns EXAMPLES:: @@ -1176,7 +1166,6 @@ cdef class BinaryCode: [001000000000001011011110] [010000000000101110001101] [100000000000010111000111] - """ # Tests for this function implicitly test _apply_permutation_to_basis # and _update_words_from_basis. These functions should not be used @@ -1273,7 +1262,6 @@ cdef class OrbitPartition: cell of the partition, and the size of the partition. See :wikipedia:`Disjoint-set_data_structure` - """ def __cinit__(self, int nrows, int ncols): """ @@ -1347,7 +1335,6 @@ cdef class OrbitPartition: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 Columns: 0,1,2,3,4,5,6,7 - """ cdef int i cdef int j @@ -1371,7 +1358,7 @@ cdef class OrbitPartition: def _wd_find(self, word): """ - Returns the root of word. + Return the root of word. EXAMPLES:: @@ -1386,7 +1373,6 @@ cdef class OrbitPartition: 0,1,2,3,4,5,6,7 sage: O._wd_find(12) 12 - """ return self.wd_find(word) @@ -1421,7 +1407,6 @@ cdef class OrbitPartition: 0,1,2,3,4,5,6,7 sage: O._wd_find(10) 1 - """ self.wd_union(x, y) @@ -1445,7 +1430,7 @@ cdef class OrbitPartition: def _col_find(self, col): """ - Returns the root of col. + Return the root of col. EXAMPLES:: @@ -1460,7 +1445,6 @@ cdef class OrbitPartition: 0,1,2,3,4,5,6,7 sage: O._col_find(6) 6 - """ return self.col_find(col) @@ -1495,7 +1479,6 @@ cdef class OrbitPartition: 0,1,2,3,1,5,6,7 sage: O._col_find(4) 1 - """ self.col_union(x, y) @@ -1519,7 +1502,7 @@ cdef class OrbitPartition: def _merge_perm(self, col_gamma, wd_gamma): """ - Merges the cells of self under the given permutation. If gamma[a] = b, + Merges the cells of ``self`` under the given permutation. If gamma[a] = b, then after merge_perm, a and b will be in the same cell. Returns 0 if nothing was done, otherwise returns 1. @@ -1542,7 +1525,6 @@ cdef class OrbitPartition: 0,1,2,3,4,5,6,7,8,8,10,10,12,12,14,14 Columns: 0,0,2,2,4,5,6,7 - """ cdef int i cdef int *_col_gamma @@ -1707,7 +1689,7 @@ cdef class PartitionStack: def print_data(self): """ - Prints all data for self. + Print all data for ``self``. EXAMPLES:: @@ -1780,7 +1762,6 @@ cdef class PartitionStack: 0 0 0 - """ cdef int i, j s = '' @@ -1829,7 +1810,7 @@ cdef class PartitionStack: def __repr__(self): """ - Return a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -1838,7 +1819,6 @@ cdef class PartitionStack: sage: P = PartitionStack(2, 6) sage: P ({0,1,2,3}) ({0,1,2,3,4,5}) - """ cdef int i, j, k s = '' @@ -1853,7 +1833,7 @@ cdef class PartitionStack: def _repr_at_k(self, k): """ - Gives a string representing the partition at level k: + Give a string representing the partition at level k. EXAMPLES:: @@ -1862,7 +1842,6 @@ cdef class PartitionStack: ({0,1,2,3}) ({0,1,2,3,4,5}) sage: P._repr_at_k(0) '({0,1,2,3}) ({0,1,2,3,4,5})\n' - """ s = '({' for j from 0 <= j < self.nwords: @@ -1884,7 +1863,7 @@ cdef class PartitionStack: def _is_discrete(self, k): """ - Returns whether the partition at level k is discrete. + Return whether the partition at level k is discrete. EXAMPLES:: @@ -1906,7 +1885,6 @@ cdef class PartitionStack: 0 sage: P._is_discrete(5) 1 - """ return self.is_discrete(k) @@ -1924,7 +1902,7 @@ cdef class PartitionStack: def _num_cells(self, k): """ - Returns the number of cells in the partition at level k. + Return the number of cells in the partition at level k. EXAMPLES:: @@ -1942,7 +1920,6 @@ cdef class PartitionStack: ({0,1,2,3}) ({0},{1},{2},{3},{4},{5}) sage: P._num_cells(3) 5 - """ return self.num_cells(k) @@ -1960,7 +1937,7 @@ cdef class PartitionStack: def _sat_225(self, k): """ - Returns whether the partition at level k satisfies the hypotheses of + Return whether the partition at level k satisfies the hypotheses of Lemma 2.25 in Brendan McKay's Practical Graph Isomorphism paper (see sage/graphs/graph_isom.pyx. @@ -1982,7 +1959,6 @@ cdef class PartitionStack: ({0,1,2,3}) ({0},{1},{2},{3,4,5}) ({0,1,2,3}) ({0},{1},{2},{3},{4,5}) ({0,1,2,3}) ({0},{1},{2},{3},{4},{5}) - """ return self.sat_225(k) @@ -2262,7 +2238,6 @@ cdef class PartitionStack: ({4,3,5},{6}) ({99},{99,99,99,99,99}) ({4,3},{5},{6}) ({99},{99,99},{99,99,99}) ({4},{3},{5},{6}) ({99},{99},{99},{99},{99,99}) - """ cdef int i for i from 0 <= i < len(col_ents): @@ -2296,7 +2271,6 @@ cdef class PartitionStack: ({0},{3},{2,1}) ({0},{5,4,3,2,1}) ({0},{3},{2},{1}) ({0},{5},{4},{3,2,1}) ({0},{3},{2},{1}) ({0},{5},{4},{3},{2},{1}) - """ self.col_percolate(start, end) @@ -2331,7 +2305,6 @@ cdef class PartitionStack: ({0},{3},{2,1}) ({0},{5,4,3,2,1}) ({0},{3},{2},{1}) ({0},{5},{4},{3,2,1}) ({0},{3},{2},{1}) ({0},{5},{4},{3},{2},{1}) - """ self.wd_percolate(start, end) @@ -2430,7 +2403,6 @@ cdef class PartitionStack: ({0,1,2,3}) ({0},{1},{2},{3,4,5}) ({0,1,2,3}) ({0},{1},{2},{3},{4,5}) ({0,1,2,3}) ({0},{1},{2},{3},{4},{5}) - """ return self.split_vertex(v, k) @@ -2471,7 +2443,7 @@ cdef class PartitionStack: def _col_degree(self, C, col, wd_ptr, k): """ - Returns the number of words in the cell specified by wd_ptr that have a + Return the number of words in the cell specified by wd_ptr that have a 1 in the col-th column. EXAMPLES:: @@ -2496,7 +2468,6 @@ cdef class PartitionStack: ({0,1,2,3}) ({0},{1},{2},{3},{4},{5}) sage: P._col_degree(B, 2, 0, 2) 2 - """ return self.col_degree(C, col, wd_ptr, k) @@ -2512,7 +2483,7 @@ cdef class PartitionStack: def _wd_degree(self, C, wd, col_ptr, k): """ - Returns the number of columns in the cell specified by col_ptr that are + Return the number of columns in the cell specified by col_ptr that are 1 in wd. EXAMPLES:: @@ -2537,7 +2508,6 @@ cdef class PartitionStack: ({0,1,2,3}) ({0},{1},{2},{3},{4},{5}) sage: P._wd_degree(B, 1, 1, 1) 3 - """ cdef int *ham_wts = hamming_weights() result = self.wd_degree(C, wd, col_ptr, k, ham_wts) @@ -2561,9 +2531,9 @@ cdef class PartitionStack: INPUT: - - start -- location of the beginning of the cell - - k -- at what level of refinement the partition of interest lies - - degrees -- the counts to sort by + - ``start`` -- location of the beginning of the cell + - ``k`` -- at what level of refinement the partition of interest lies + - ``degrees`` -- the counts to sort by EXAMPLES:: @@ -2577,7 +2547,6 @@ cdef class PartitionStack: sage: P ({0,1,2,3}) ({0,1,4,5,2,3}) ({0,1,2,3}) ({0},{1},{4,5},{2,3}) - """ cdef int i for i from 0 <= i < len(degrees): @@ -2633,9 +2602,9 @@ cdef class PartitionStack: INPUT: - - start -- location of the beginning of the cell - - k -- at what level of refinement the partition of interest lies - - degrees -- the counts to sort by + - ``start`` -- location of the beginning of the cell + - ``k`` -- at what level of refinement the partition of interest lies + - ``degrees`` -- the counts to sort by EXAMPLES:: @@ -2647,7 +2616,6 @@ cdef class PartitionStack: sage: P ({0,1,6,7,2,3,4,5}) ({0,1,2,3,4,5}) ({0,1},{6,7},{2,3,4,5}) ({0,1,2,3,4,5}) - """ cdef int i for i from 0 <= i < len(degrees): @@ -2742,7 +2710,6 @@ cdef class PartitionStack: ({0},{4},{6,2},{13,9},{11,15},{10,14},{12,8},{7,3},{1},{5}) ({0},{1},{2},{3,4,7,6,5}) ({0},{4},{6,2},{13,9},{11,15},{10,14},{12,8},{7,3},{1},{5}) ({0},{1},{2},{3},{4,7,6,5}) ({0},{4},{6},{2},{13},{9},{11},{15},{10},{14},{12},{8},{7},{3},{1},{5}) ({0},{1},{2},{3},{4},{7},{6},{5}) - """ cdef int i, alpha_length = len(alpha) cdef int *_alpha = sig_malloc( (self.nwords + self.ncols) * sizeof(int) ) @@ -2858,7 +2825,6 @@ cdef class PartitionStack: sage: P ({0,1,2,3}) ({0,1,2,3,4,5}) ({0,1,2,3}) ({0},{1,2,3,4,5}) - """ self.clear(k) @@ -2959,7 +2925,6 @@ cdef class PartitionStack: 8 0 11 - """ cdef int i, j if self.basis_locations: @@ -2993,7 +2958,6 @@ cdef class PartitionStack: 8 0 11 - """ cdef int i cdef int *ham_wts = hamming_weights() @@ -3060,7 +3024,6 @@ cdef class PartitionStack: 1 sage: P._get_permutation(Q) ([0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11], [0, 1, 2, 3, 5, 4, 7, 6]) - """ cdef int i cdef int *word_g = sig_malloc( self.nwords * sizeof(int) ) @@ -3182,17 +3145,18 @@ cdef class BinaryCodeClassifier: INPUT: - ``CC`` -- a BinaryCode object - - ``verbosity`` -- a nonnegative integer + - ``verbosity`` -- nonnegative integer OUTPUT: - a tuple, (gens, labeling, size, base) - gens -- a list of permutations (in list form) representing generators - of the permutation automorphism group of the code CC. - labeling -- a permutation representing the canonical labeling of the - code. mostly for internal use; entries describe the relabeling - on the columns. - size -- the order of the automorphism group. - base -- a set of cols whose action determines the action on all cols + + a tuple, (gens, labeling, size, base) + - gens; list of permutations (in list form) representing generators + of the permutation automorphism group of the code CC + - labeling; a permutation representing the canonical labeling of the + code. mostly for internal use; entries describe the relabeling + on the columns. + - size; the order of the automorphism group + - base; a set of cols whose action determines the action on all cols EXAMPLES:: @@ -3329,7 +3293,6 @@ cdef class BinaryCodeClassifier: sage: BC = BinaryCodeClassifier() sage: BC._aut_gp_and_can_label(B)[2] 442368 - """ cdef int i, j cdef BinaryCode C = CC @@ -3943,7 +3906,6 @@ cdef class BinaryCodeClassifier: [000000000100010011011110] [000000000010001011110101] [000000000001001101101110] - """ aut_gp_gens, labeling, size, base = self._aut_gp_and_can_label(B) B._apply_permutation_to_basis(labeling) @@ -4003,7 +3965,6 @@ cdef class BinaryCodeClassifier: n=10 : 0 1 1 1 0 0 n=11 : 0 0 1 1 0 0 n=12 : 1 2 3 4 2 0 - """ cdef BinaryCode m cdef codeword *ortho_basis diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index f197bc607d2..e297a6fe68e 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -62,7 +62,7 @@ def random_error_vector(n, F, error_positions): r""" - Return a vector of length ``n`` over ``F`` filled with random non-zero coefficients + Return a vector of length ``n`` over ``F`` filled with random nonzero coefficients at the positions given by ``error_positions``. .. NOTE:: @@ -75,11 +75,9 @@ def random_error_vector(n, F, error_positions): - ``F`` -- the field over which the vector is defined - - ``error_positions`` -- the non-zero positions of the vector + - ``error_positions`` -- the nonzero positions of the vector - OUTPUT: - - - a vector of ``F`` + OUTPUT: a vector of ``F`` AUTHORS: @@ -97,6 +95,7 @@ def random_error_vector(n, F, error_positions): vect[i] = F._random_nonzero_element() return vector(F, vect) + def format_interval(t): r""" Return a formatted string representation of ``t``. @@ -109,11 +108,9 @@ def format_interval(t): INPUT: - - ``t`` -- a list or a tuple - - OUTPUT: + - ``t`` -- list or a tuple - - a string + OUTPUT: string TESTS:: @@ -125,7 +122,6 @@ def format_interval(t): sage: t = (2, 10) sage: format_interval(t) 'between 2 and 10' - """ return str(t[0]) if t[0] == t[1] else 'between %s and %s' % (t[0], t[1]) @@ -155,7 +151,7 @@ class Channel(SageObject): def __init__(self, input_space, output_space): r""" - Initializes parameters for a Channel object. + Initialize parameters for a Channel object. This is a private method, which should be called by the constructor of every encoder, as it automatically initializes the mandatory @@ -204,9 +200,7 @@ def transmit(self, message): - ``message`` -- a vector - OUTPUT: - - - a vector of the output space of ``self`` + OUTPUT: a vector of the output space of ``self`` EXAMPLES:: @@ -255,7 +249,6 @@ def input_space(self): sage: Chan = channels.StaticErrorRateChannel(GF(59)^6, n_err) sage: Chan.input_space() Vector space of dimension 6 over Finite Field of size 59 - """ return self._input_space @@ -395,9 +388,7 @@ def transmit_unsafe(self, message): - ``message`` -- a vector - OUTPUT: - - - a vector of the output space + OUTPUT: a vector of the output space EXAMPLES:: @@ -490,8 +481,6 @@ class ErrorErasureChannel(Channel): def __init__(self, space, number_errors, number_erasures): r""" - - TESTS: If the sum of number of errors and number of erasures @@ -579,9 +568,7 @@ def transmit_unsafe(self, message): - ``message`` -- a vector - OUTPUT: - - - a couple of vectors, namely: + OUTPUT: a couple of vectors, namely: - the transmitted message, which is ``message`` with erroneous and erased positions @@ -666,10 +653,10 @@ class QarySymmetricChannel(Channel): INPUT: - - ``space`` -- the input and output space of the channel. It has to be - `\GF{q}^n` for some finite field `\GF{q}`. + - ``space`` -- the input and output space of the channel; it has to be + `\GF{q}^n` for some finite field `\GF{q}` - - ``epsilon`` -- the transmission error probability of the individual elements. + - ``epsilon`` -- the transmission error probability of the individual elements EXAMPLES: @@ -798,7 +785,7 @@ def probability_of_exactly_t_errors(self, t): INPUT: - - ``t`` -- an integer + - ``t`` -- integer EXAMPLES:: @@ -818,7 +805,7 @@ def probability_of_at_most_t_errors(self, t): INPUT: - - ``t`` -- an integer + - ``t`` -- integer EXAMPLES:: diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index fd4e36561ef..4bb33d9565f 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -50,7 +50,7 @@ where `0` is a distinguished element of `F`; in particular it is `0` of the field if `F` is a field. The minimum distance of -a linear code is the smallest non-zero weight of a codeword in `C`. The +a linear code is the smallest nonzero weight of a codeword in `C`. The relatively minimum distance is denoted @@ -108,47 +108,42 @@ This module implements: -- ``codesize_upper_bound(n,d,q)``, for the best known (as of May, - 2006) upper bound `A(n,d)` for the size of a code of length `n`, - minimum distance `d` over a field of size `q`. +- ``codesize_upper_bound(n,d,q)``, for the best known (as of May, 2006) upper + bound `A(n,d)` for the size of a code of length `n`, minimum distance `d` + over a field of size `q`. -- ``dimension_upper_bound(n,d,q)``, an upper bound - `B(n,d)=B_q(n,d)` for the dimension of a linear code of - length `n`, minimum distance `d` over a field of size `q`. +- ``dimension_upper_bound(n,d,q)``, an upper bound `B(n,d)=B_q(n,d)` for the + dimension of a linear code of length `n`, minimum distance `d` over a field + of size `q`. -- ``gilbert_lower_bound(n,q,d)``, a lower bound for number of - elements in the largest code of min distance `d` in - `\GF{q}^n`. +- ``gilbert_lower_bound(n,q,d)``, a lower bound for number of elements in the + largest code of min distance `d` in `\GF{q}^n`. -- ``gv_info_rate(n,delta,q)``, `log_q(GLB)/n`, where GLB is - the Gilbert lower bound and `\delta = d/n`. +- ``gv_info_rate(n,delta,q)``, `log_q(GLB)/n`, where GLB is the Gilbert lower + bound and `\delta = d/n`. -- ``gv_bound_asymp(delta,q)``, asymptotic analog of Gilbert lower - bound. +- ``gv_bound_asymp(delta,q)``, asymptotic analog of Gilbert lower bound. -- ``plotkin_upper_bound(n,q,d)`` +- ``plotkin_upper_bound(n,q,d)`` -- ``plotkin_bound_asymp(delta,q)``, asymptotic analog of Plotkin - bound. +- ``plotkin_bound_asymp(delta,q)``, asymptotic analog of Plotkin bound. -- ``griesmer_upper_bound(n,q,d)`` +- ``griesmer_upper_bound(n,q,d)`` -- ``elias_upper_bound(n,q,d)`` +- ``elias_upper_bound(n,q,d)`` -- ``elias_bound_asymp(delta,q)``, asymptotic analog of Elias bound. +- ``elias_bound_asymp(delta,q)``, asymptotic analog of Elias bound. -- ``hamming_upper_bound(n,q,d)`` +- ``hamming_upper_bound(n,q,d)`` -- ``hamming_bound_asymp(delta,q)``, asymptotic analog of Hamming - bound. +- ``hamming_bound_asymp(delta,q)``, asymptotic analog of Hamming bound. -- ``singleton_upper_bound(n,q,d)`` +- ``singleton_upper_bound(n,q,d)`` -- ``singleton_bound_asymp(delta,q)``, asymptotic analog of Singleton - bound. +- ``singleton_bound_asymp(delta,q)``, asymptotic analog of Singleton bound. -- ``mrrw1_bound_asymp(delta,q)``, "first" asymptotic - McEliese-Rumsey-Rodemich-Welsh bound for the information rate. +- ``mrrw1_bound_asymp(delta,q)``, "first" asymptotic + McEliese-Rumsey-Rodemich-Welsh bound for the information rate. - Delsarte (a.k.a. Linear Programming (LP)) upper bounds. @@ -195,7 +190,7 @@ def _check_n_q_d(n, q, d, field_based=True): More precisely, this checks that the parameters are positive integers, that `q` is a prime power for codes over a field, or, more generally, that `q` is of size at least 2, and that `n >= d`. - This raises a :class:`ValueError` otherwise. + This raises a :exc:`ValueError` otherwise. TESTS:: @@ -254,15 +249,15 @@ def codesize_upper_bound(n, d, q, algorithm=None): sage: codes.bounds.codesize_upper_bound(10, 3, 2) 93 - sage: codes.bounds.codesize_upper_bound(24, 8, 2, algorithm="LP") # needs sage.numerical.mip + sage: codes.bounds.codesize_upper_bound(24, 8, 2, algorithm='LP') # needs sage.numerical.mip 4096 - sage: codes.bounds.codesize_upper_bound(10, 3, 2, algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.codesize_upper_bound(10, 3, 2, algorithm='gap') # optional - gap_package_guava 85 sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm=None) # needs sage.symbolic 123361 - sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm='gap') # optional - gap_package_guava 123361 - sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm="LP") # needs sage.numerical.mip + sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm='LP') # needs sage.numerical.mip 109226 TESTS: @@ -271,7 +266,7 @@ def codesize_upper_bound(n, d, q, algorithm=None): sage: codes.bounds.codesize_upper_bound(19, 10, 2) 20 - sage: codes.bounds.codesize_upper_bound(19, 10, 2, algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.codesize_upper_bound(19, 10, 2, algorithm='gap') # optional - gap_package_guava 20 Meaningless parameters are rejected:: @@ -283,7 +278,7 @@ def codesize_upper_bound(n, d, q, algorithm=None): """ _check_n_q_d(n, q, d, field_based=False) if algorithm == "gap": - GapPackage("guava", spkg="gap_packages").require() + GapPackage("guava", spkg='gap_packages').require() libgap.load_package('guava') return int(libgap.UpperBound(n, d, q)) if algorithm == "LP": @@ -313,7 +308,7 @@ def dimension_upper_bound(n, d, q, algorithm=None): 6 sage: codes.bounds.dimension_upper_bound(30,15,4) # needs sage.libs.pari sage.symbolic 13 - sage: codes.bounds.dimension_upper_bound(30,15,4,algorithm="LP") # needs sage.libs.pari sage.numerical.mip + sage: codes.bounds.dimension_upper_bound(30,15,4,algorithm='LP') # needs sage.libs.pari sage.numerical.mip 12 TESTS: @@ -365,6 +360,7 @@ def gilbert_lower_bound(n, q, d): ans = q**n/volume_hamming(n,q,d-1) return ans + def plotkin_upper_bound(n,q,d, algorithm=None): r""" Return the Plotkin upper bound. @@ -380,12 +376,12 @@ def plotkin_upper_bound(n,q,d, algorithm=None): sage: codes.bounds.plotkin_upper_bound(10,2,3) 192 - sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm='gap') # optional - gap_package_guava 192 """ _check_n_q_d(n, q, d, field_based=False) if algorithm == "gap": - GapPackage("guava", spkg="gap_packages").require() + GapPackage("guava", spkg='gap_packages').require() libgap.load_package("guava") return QQ(libgap.UpperBoundPlotkin(n, d, q)) else: @@ -403,6 +399,7 @@ def plotkin_upper_bound(n,q,d, algorithm=None): fact = int(fact) + 1 return int(d/( d - t * fact)) * q**(n - fact) + def griesmer_upper_bound(n,q,d,algorithm=None): r""" Return the Griesmer upper bound. @@ -417,7 +414,6 @@ def griesmer_upper_bound(n,q,d,algorithm=None): `n\geq \sum_{i=0}^{k-1} \lceil d/q^i \rceil.` - EXAMPLES: The bound is reached for the ternary Golay codes:: @@ -431,7 +427,7 @@ def griesmer_upper_bound(n,q,d,algorithm=None): sage: codes.bounds.griesmer_upper_bound(10,2,3) # needs sage.libs.pari 128 - sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap") # optional - gap_package_guava, needs sage.libs.pari + sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm='gap') # optional - gap_package_guava, needs sage.libs.pari 128 TESTS:: @@ -443,7 +439,7 @@ def griesmer_upper_bound(n,q,d,algorithm=None): """ _check_n_q_d(n, q, d) if algorithm == "gap": - GapPackage("guava", spkg="gap_packages").require() + GapPackage("guava", spkg='gap_packages').require() libgap.load_package("guava") return QQ(libgap.UpperBoundGriesmer(n, d, q)) else: @@ -472,13 +468,13 @@ def elias_upper_bound(n,q,d,algorithm=None): sage: codes.bounds.elias_upper_bound(10,2,3) 232 - sage: codes.bounds.elias_upper_bound(10,2,3,algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.elias_upper_bound(10,2,3,algorithm='gap') # optional - gap_package_guava 232 """ _check_n_q_d(n, q, d, field_based=False) r = 1-1/q if algorithm == "gap": - GapPackage("guava", spkg="gap_packages").require() + GapPackage("guava", spkg='gap_packages').require() libgap.load_package("guava") return QQ(libgap.UpperBoundElias(n, d, q)) else: @@ -577,10 +573,10 @@ def entropy(x, q=2): INPUT: - - ``x`` -- real number in the interval `[0, 1]`. + - ``x`` -- real number in the interval `[0, 1]` - - ``q`` -- (default: 2) integer greater than 1. This is the base of the - logarithm. + - ``q`` -- (default: 2) integer greater than 1; this is the base of the + logarithm EXAMPLES:: @@ -622,10 +618,10 @@ def entropy_inverse(x, q=2): INPUT: - - ``x`` -- real number in the interval `[0, 1]`. + - ``x`` -- real number in the interval `[0, 1]` - - ``q`` -- (default: 2) integer greater than 1. This is the base of the - logarithm. + - ``q`` -- (default: 2) integer greater than 1; this is the base of the + logarithm OUTPUT: @@ -741,7 +737,7 @@ def elias_bound_asymp(delta, q): 0.39912396330... """ r = 1 - 1 / q - return RDF((1-entropy(r-sqrt(r*(r-delta)), q))) + return RDF(1-entropy(r-sqrt(r*(r-delta)), q)) def mrrw1_bound_asymp(delta, q): diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index a3569938e40..be1c087c280 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -178,9 +178,12 @@ def _is_a_splitting(S1, S2, n, return_automorphism=False): else: return False + def _lift2smallest_field(a): """ - INPUT: a is an element of a finite field GF(q) + INPUT: + + - ``a`` -- an element of a finite field GF(q) OUTPUT: the element b of the smallest subfield F of GF(q) for which F(b)=a. @@ -216,7 +219,7 @@ def _lift2smallest_field(a): def permutation_action(g, v): r""" - Returns permutation of rows `g * v`. + Return permutation of rows `g * v`. Works on lists, matrices, sequences and vectors (by permuting coordinates). The code requires @@ -325,9 +328,10 @@ def walsh_matrix(m0): ##################### main constructions ##################### + def DuadicCodeEvenPair(F,S1,S2): r""" - Constructs the "even pair" of duadic codes associated to the + Construct the "even pair" of duadic codes associated to the "splitting" (see the docstring for ``_is_a_splitting`` for the definition) S1, S2 of n. @@ -374,9 +378,10 @@ def DuadicCodeEvenPair(F,S1,S2): C2 = CyclicCode(length=n, generator_pol=gg2) return C1,C2 + def DuadicCodeOddPair(F,S1,S2): """ - Constructs the "odd pair" of duadic codes associated to the + Construct the "odd pair" of duadic codes associated to the "splitting" S1, S2 of n. .. warning:: @@ -429,6 +434,7 @@ def DuadicCodeOddPair(F,S1,S2): C2 = CyclicCode(length=n, generator_pol=gg2) return C1,C2 + def ExtendedQuadraticResidueCode(n,F): r""" The extended quadratic residue code (or XQR code) is obtained from @@ -438,14 +444,12 @@ def ExtendedQuadraticResidueCode(n,F): INPUT: + - ``n`` -- an odd prime - - ``n`` -- an odd prime - - - ``F`` -- a finite prime field whose order must be a - quadratic residue modulo `n`. - + - ``F`` -- a finite prime field whose order must be a + quadratic residue modulo `n` - OUTPUT: Returns an extended quadratic residue code. + OUTPUT: an extended quadratic residue code EXAMPLES:: @@ -471,6 +475,7 @@ def ExtendedQuadraticResidueCode(n,F): C = QuadraticResidueCodeOddPair(n,F)[0] return C.extended_code() + def from_parity_check_matrix(H): r""" Return the linear code that has ``H`` as a parity check matrix. @@ -494,12 +499,13 @@ def from_parity_check_matrix(H): Cd = LinearCode(H) return Cd.dual_code() + def QuadraticResidueCode(n,F): r""" A quadratic residue code (or QR code) is a cyclic code whose generator polynomial is the product of the polynomials `x-\alpha^i` (`\alpha` is a primitive - `n`'th root of unity; `i` ranges over the set of + `n`-th root of unity; `i` ranges over the set of quadratic residues modulo `n`). See :class:`QuadraticResidueCodeEvenPair` and @@ -507,14 +513,12 @@ def QuadraticResidueCode(n,F): INPUT: + - ``n`` -- an odd prime - - ``n`` -- an odd prime - - - ``F`` -- a finite prime field whose order must be a - quadratic residue modulo `n`. - + - ``F`` -- a finite prime field whose order must be a + quadratic residue modulo `n` - OUTPUT: Returns a quadratic residue code. + OUTPUT: a quadratic residue code EXAMPLES:: @@ -539,6 +543,7 @@ def QuadraticResidueCode(n,F): """ return QuadraticResidueCodeOddPair(n,F)[0] + def QuadraticResidueCodeEvenPair(n,F): r""" Quadratic residue codes of a given odd prime length and base ring @@ -548,7 +553,7 @@ def QuadraticResidueCodeEvenPair(n,F): quadratic residue mod `n`. They are constructed as "even-like" duadic codes associated the - splitting `(Q,N)` mod `n`, where `Q` is the set of non-zero quadratic + splitting `(Q,N)` mod `n`, where `Q` is the set of nonzero quadratic residues and `N` is the non-residues. EXAMPLES:: @@ -598,8 +603,8 @@ def QuadraticResidueCodeEvenPair(n,F): if n <= 2 or not n.is_prime(): raise ValueError("the argument n must be an odd prime") Q = quadratic_residues(n) - Q.remove(0) # non-zero quad residues - N = [x for x in srange(1, n) if x not in Q] # non-zero quad non-residues + Q.remove(0) # nonzero quad residues + N = [x for x in srange(1, n) if x not in Q] # nonzero quad non-residues if q not in Q: raise ValueError("the order of the finite field must be a quadratic residue modulo n") return DuadicCodeEvenPair(F,Q,N) @@ -614,7 +619,7 @@ def QuadraticResidueCodeOddPair(n,F): quadratic residue mod `n`. They are constructed as "odd-like" duadic codes associated the - splitting `(Q,N)` mod `n`, where `Q` is the set of non-zero quadratic + splitting `(Q,N)` mod `n`, where `Q` is the set of nonzero quadratic residues and `N` is the non-residues. EXAMPLES:: @@ -658,8 +663,8 @@ def QuadraticResidueCodeOddPair(n,F): if n <= 2 or not n.is_prime(): raise ValueError("the argument n must be an odd prime") Q = quadratic_residues(n) - Q.remove(0) # non-zero quad residues - N = [x for x in srange(1, n) if x not in Q] # non-zero quad non-residues + Q.remove(0) # nonzero quad residues + N = [x for x in srange(1, n) if x not in Q] # nonzero quad non-residues if q not in Q: raise ValueError("the order of the finite field must be a quadratic residue modulo n") return DuadicCodeOddPair(F,Q,N) @@ -690,6 +695,7 @@ def random_linear_code(F, length, dimension): if G.rank() == dimension: return LinearCode(G) + def ToricCode(P,F): r""" Let `P` denote a list of lattice points in @@ -714,15 +720,12 @@ def ToricCode(P,F): INPUT: + - ``P`` -- all the integer lattice points in a polytope + defining the toric variety - - ``P`` -- all the integer lattice points in a polytope - defining the toric variety. - - - ``F`` -- a finite field. - + - ``F`` -- a finite field - OUTPUT: Returns toric code with length n = , dimension k over field - F. + OUTPUT: toric code with length `n`, dimension `k` over field `F` EXAMPLES:: @@ -731,7 +734,7 @@ def ToricCode(P,F): [36, 5] linear code over GF(7) sage: C.minimum_distance() # needs sage.groups 24 - sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava + sage: C.minimum_distance(algorithm='guava') # optional - gap_package_guava ...24 sage: C = codes.ToricCode([[-2,-2],[-1,-2],[-1,-1],[-1,0], ....: [0,-1],[0,0],[0,1],[1,-1],[1,0]], GF(5)) @@ -739,7 +742,7 @@ def ToricCode(P,F): [16, 9] linear code over GF(5) sage: C.minimum_distance() # needs sage.groups 6 - sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava + sage: C.minimum_distance(algorithm='guava') # optional - gap_package_guava 6 sage: C = codes.ToricCode([[0,0],[1,1],[1,2],[1,3],[1,4],[2,1], ....: [2,2],[2,3],[3,1],[3,2],[4,1]], GF(8,"a")) diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index 7f7f8504b49..e54e64a20a9 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -81,13 +81,13 @@ columns do share the same coloring:: We can also restrict the group action to linear isometries:: - sage: P = LinearCodeAutGroupCanLabel(C, algorithm_type="linear") + sage: P = LinearCodeAutGroupCanLabel(C, algorithm_type='linear') sage: P.get_autom_order() == GL(3, GF(4, 'a')).order() True and to the action of the symmetric group only:: - sage: P = LinearCodeAutGroupCanLabel(C, algorithm_type="permutational") + sage: P = LinearCodeAutGroupCanLabel(C, algorithm_type='permutational') sage: P.get_autom_order() == C.permutation_automorphism_group().order() True """ @@ -184,18 +184,18 @@ class LinearCodeAutGroupCanLabel: True """ - def __init__(self, C, P=None, algorithm_type="semilinear"): + def __init__(self, C, P=None, algorithm_type='semilinear'): """ - see :class:`LinearCodeAutGroupCanLabel` + See :class:`LinearCodeAutGroupCanLabel`. INPUT: - ``C`` -- a linear code - - ``P`` (optional) -- a coloring of the coordinates i.e. a partition + - ``P`` -- (optional) a coloring of the coordinates i.e. a partition (list of disjoint lists) of [0 , ..., C.length()-1 ] - - ``algorithm_type`` (optional) -- which defines the acting group, either + - ``algorithm_type`` -- (optional) defines the acting group, either * ``permutational`` @@ -213,7 +213,7 @@ class LinearCodeAutGroupCanLabel: [0 1 0 1 0 1 1] [0 0 1 1 1 1 0] sage: P2 = LinearCodeAutGroupCanLabel(C, P=[[0,3,5],[1,2,4,6]], - ....: algorithm_type="permutational") + ....: algorithm_type='permutational') sage: P2.get_canonical_form().generator_matrix() [1 1 1 0 0 0 1] [0 1 0 1 1 0 1] @@ -294,7 +294,7 @@ class LinearCodeAutGroupCanLabel: # this command allows you some advanced debugging # it prints the backtrack tree -> must be activated when installing - # pr._latex_view(title="MyTitle") #this will provide you some visual representation of what is going on + # pr._latex_view(title='MyTitle') #this will provide you some visual representation of what is going on can_transp = pr.get_transporter() can_col_set = pr.get_canonical_form().columns() @@ -405,19 +405,19 @@ class LinearCodeAutGroupCanLabel: - ``normalization_inverse`` -- the inverse of ``normalization`` - - ``col2pos`` -- a list of disjoint indices in ``range(n)`` + - ``col2pos`` -- list of disjoint indices in ``range(n)`` - ``col2P`` -- an increasing list of integers, with ``len(col2P) == len(col2pos)`` with ``col2P[i] == col2P[j]`` if and only if the indices ``col2pos[i]`` and ``col2pos[j]`` are in the same partition - - ``zero_column_case`` (boolean) -- set to ``True`` iff we are dealing + - ``zero_column_case`` -- boolean; set to ``True`` iff we are dealing with the zero column OUTPUT: - - a list of generators in `S` + - list of generators in `S` - the order of this group @@ -478,7 +478,7 @@ class LinearCodeAutGroupCanLabel: INPUT: - - ``gens`` -- a list of semimonomial transformation group elements of length `m` + - ``gens`` -- list of semimonomial transformation group elements of length `m` - ``normalization`` -- a semimonomial transformation of length `n` diff --git a/src/sage/coding/codecan/codecan.pyx b/src/sage/coding/codecan/codecan.pyx index af8d82e660a..47311e16260 100644 --- a/src/sage/coding/codecan/codecan.pyx +++ b/src/sage/coding/codecan/codecan.pyx @@ -111,10 +111,10 @@ cdef class InnerGroup: Those stabilizers can be stored as triples: - - ``rank`` -- an integer in `\{0, \ldots, k\}` + - ``rank`` -- integer in `\{0, \ldots, k\}` - ``row_partition`` -- a partition of `\{0, \ldots, k-1\}` with - discrete cells for all integers `i` `\geq` ``rank``. - - ``frob_pow`` -- an integer `s` in `\{0, \ldots, r-1\}` if `q = p^r` + discrete cells for all integers `i` `\geq` ``rank`` + - ``frob_pow`` -- integer `s` in `\{0, \ldots, r-1\}` if `q = p^r` The group `G_{\Pi^{(I)}(x)}` contains all elements `(A, \varphi, \alpha) \in G`, where @@ -132,13 +132,13 @@ cdef class InnerGroup: See [Feu2009]_ for more details. """ - def __cinit__(self, k=0, algorithm="semilinear", **kwds): + def __cinit__(self, k=0, algorithm='semilinear', **kwds): r""" - See :class:`sage.coding.codecan.codecan.InnerGroup` + See :class:`sage.coding.codecan.codecan.InnerGroup`. INPUT: - - ``k`` -- an integer, gives the dimension of the matrix component + - ``k`` -- integer; gives the dimension of the matrix component - ``algorithm`` -- either * "semilinear" -- full group @@ -146,7 +146,7 @@ cdef class InnerGroup: * "permutational -- no field automorphisms and no column multiplications i.e. `G = GL(k,q)` - - ``transporter`` (optional) -- set to an element of the group + - ``transporter`` -- (optional) set to an element of the group :class:`sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup` if you would like to modify this element simultaneously @@ -186,7 +186,7 @@ cdef class InnerGroup: def __dealloc__(self): r""" - Deallocates ``self``. + Deallocate ``self``. """ OP_dealloc(self.row_partition) @@ -198,7 +198,7 @@ cdef class InnerGroup: cdef bint has_semilinear_action(self) noexcept: """ - Returns ``True`` iff the field automorphism group component of ``self`` + Return ``True`` iff the field automorphism group component of ``self`` is non-trivial. """ return (self.frob_pow > 0) @@ -505,7 +505,7 @@ cdef class PartitionRefinementLinearCode(PartitionRefinement_generic): self._nr_of_point_refine_calls = 0 self._stored_states = dict() - def __init__(self, n, generator_matrix, P=None, algorithm_type="semilinear"): + def __init__(self, n, generator_matrix, P=None, algorithm_type='semilinear'): r""" Initialization, we immediately start the algorithm (see :mod:`sage.coding.codecan.codecan`) @@ -514,13 +514,13 @@ cdef class PartitionRefinementLinearCode(PartitionRefinement_generic): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``generator_matrix`` -- a `k \times n` matrix over `\GF{q}` of full row rank, - i.e. `k last modified: 2002-03-20 - This function raises an :class:`IOError` if an error occurs downloading data or - parsing it. It raises a :class:`ValueError` if the ``q`` input is invalid. + This function raises an :exc:`IOError` if an error occurs downloading data or + parsing it. It raises a :exc:`ValueError` if the ``q`` input is invalid. AUTHORS: @@ -188,29 +182,29 @@ def best_linear_code_in_codetables_dot_de(n, k, F, verbose=False): def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, in_test=None): """ - Returns a Python iterator which generates a complete set of + Return a Python iterator which generates a complete set of representatives of all permutation equivalence classes of self-orthogonal binary linear codes of length in ``[1..n]`` and dimension in ``[1..k]``. INPUT: - - ``n`` -- Integer, maximal length + - ``n`` -- integer; maximal length - - ``k`` -- Integer, maximal dimension + - ``k`` -- integer; maximal dimension - - ``b`` -- Integer, requires that the generators all have weight divisible - by ``b`` (if ``b=2``, all self-orthogonal codes are generated, and if - ``b=4``, all doubly even codes are generated). Must be an even positive - integer. + - ``b`` -- integer; requires that the generators all have weight divisible + by ``b`` (if ``b=2``, all self-orthogonal codes are generated, and if + ``b=4``, all doubly even codes are generated). Must be an even positive + integer. - - ``parent`` -- Used in recursion (default: ``None``) + - ``parent`` -- used in recursion (default: ``None``) - - ``BC`` -- Used in recursion (default: ``None``) + - ``BC`` -- used in recursion (default: ``None``) - - ``equal`` -- If ``True``, generates only [n, k] codes (default: ``False``) + - ``equal`` -- if ``True``, generates only [n, k] codes (default: ``False``) - - ``in_test`` -- Used in recursion (default: ``None``) + - ``in_test`` -- used in recursion (default: ``None``) EXAMPLES: diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index a7a2a8629ed..05089583389 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -23,6 +23,7 @@ from sage.misc.abstract_method import abstract_method from sage.structure.sage_object import SageObject + class Decoder(SageObject): r""" Abstract top-class for :class:`Decoder` objects. @@ -52,7 +53,7 @@ class Decoder(SageObject): @classmethod def decoder_type(cls): r""" - Returns the set of types of ``self``. + Return the set of types of ``self``. This method can be called on both an uninstantiated decoder class, or on an instance of a decoder class. @@ -98,7 +99,6 @@ def decoder_type(cls): works for specific channels. ====================== ================================================ - EXAMPLES: We call it on a class:: @@ -134,7 +134,7 @@ def _instance_decoder_type(self): def __init__(self, code, input_space, connected_encoder_name): r""" - Initializes mandatory parameters for :class:`Decoder` objects. + Initialize mandatory parameters for :class:`Decoder` objects. This method only exists for inheritance purposes as it initializes parameters that need to be known by every decoder. An abstract @@ -183,7 +183,7 @@ def __init__(self, code, input_space, connected_encoder_name): def __hash__(self): r""" - Returns the hash value of ``self``. + Return the hash value of ``self``. This is a generic implementation which should be overwritten on decoders with extra arguments. @@ -202,9 +202,10 @@ def __hash__(self): def __ne__(self, other): r""" - Tests inequality of ``self`` and ``other``. + Test inequality of ``self`` and ``other``. - This is a generic implementation, which returns the inverse of ``__eq__`` for self. + This is a generic implementation, which returns the inverse of + ``__eq__`` for ``self``. EXAMPLES:: @@ -229,11 +230,9 @@ def decode_to_code(self, r): INPUT: - - ``r`` -- a element of the input space of ``self``. + - ``r`` -- a element of the input space of ``self`` - OUTPUT: - - - a vector of :meth:`code`. + OUTPUT: a vector of :meth:`code` EXAMPLES:: @@ -281,11 +280,9 @@ def decode_to_message(self, r): INPUT: - - ``r`` -- a element of the input space of ``self``. - - OUTPUT: + - ``r`` -- a element of the input space of ``self`` - - a vector of :meth:`message_space`. + OUTPUT: a vector of :meth:`message_space` EXAMPLES:: diff --git a/src/sage/coding/delsarte_bounds.py b/src/sage/coding/delsarte_bounds.py index 2b64738b76f..a7cc35e058d 100644 --- a/src/sage/coding/delsarte_bounds.py +++ b/src/sage/coding/delsarte_bounds.py @@ -50,7 +50,7 @@ def krawtchouk(n, q, l, x, check=True): - ``n``, ``q``, ``x`` -- arbitrary numbers - - ``l`` -- a nonnegative integer + - ``l`` -- nonnegative integer - ``check`` -- check the input for correctness. ``True`` by default. Otherwise, pass it as it is. Use ``check=False`` at @@ -135,7 +135,7 @@ def eberlein(n, w, k, u, check=True): - ``w``, ``k``, ``x`` -- arbitrary numbers - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``check`` -- check the input for correctness. ``True`` by default. Otherwise, pass it as it is. Use ``check=False`` at @@ -233,7 +233,7 @@ def _delsarte_LP_building(n, d, d_star, q, isinteger, solver, maxc=0): def _delsarte_cwc_LP_building(n, d, w, solver, isinteger): r""" - LP builder for Delsarte's LP for constant weight codes + LP builder for Delsarte's LP for constant weight codes. It is used in :func:`delsarte_bound_constant_weight_code`; not exported. @@ -290,7 +290,7 @@ def _q(k, i): def delsarte_bound_constant_weight_code(n, d, w, return_data=False, - solver="PPL", isinteger=False): + solver='PPL', isinteger=False): r""" Find the Delsarte bound on a constant weight code. @@ -362,9 +362,9 @@ def delsarte_bound_constant_weight_code(n, d, w, return_data=False, def delsarte_bound_hamming_space(n, d, q, return_data=False, - solver="PPL", isinteger=False): + solver='PPL', isinteger=False): r""" - Find the Delsarte bound on codes in ``H_q^n`` of minimal distance ``d`` + Find the Delsarte bound on codes in ``H_q^n`` of minimal distance ``d``. Find the Delsarte bound [De1973]_ on the size of codes in the Hamming space ``H_q^n`` of minimal distance ``d``. @@ -446,14 +446,14 @@ def delsarte_bound_hamming_space(n, d, q, return_data=False, def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_data=False, - solver="PPL", isinteger=False): + solver='PPL', isinteger=False): r""" Find a modified Delsarte bound on additive codes in Hamming space `H_q^n` of minimal distance `d`. Find the Delsarte LP bound on ``F_{q_base}``-dimension of additive codes in Hamming space `H_q^n` of minimal distance ``d`` with minimal distance of the dual code at least ``d_star``. If - ``q_base`` is set to non-zero, then ``q`` is a power of + ``q_base`` is set to nonzero, then ``q`` is a power of ``q_base``, and the code is, formally, linear over ``F_{q_base}``. Otherwise it is assumed that ``q_base==q``. @@ -466,10 +466,10 @@ def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_da - ``q`` -- the size of the alphabet - ``d_star`` -- the (lower bound on) minimal distance of the dual code; - only makes sense for additive codes. + only makes sense for additive codes - ``q_base`` -- if ``0``, the code is assumed to be linear. Otherwise, - ``q=q_base^m`` and the code is linear over ``F_{q_base}``. + ``q=q_base^m`` and the code is linear over ``F_{q_base}`` - ``return_data`` -- if ``True``, return a triple ``(W,LP,bound)``, where ``W`` is a weights vector, and ``LP`` the Delsarte bound @@ -483,7 +483,7 @@ def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_da list), you are on your own! - ``isinteger`` -- if ``True``, uses an integer programming solver (ILP), - rather that an LP solver. Can be very slow if set to ``True``. + rather that an LP solver (can be very slow if set to ``True``) EXAMPLES: @@ -640,7 +640,7 @@ def _delsarte_Q_LP_building(q, d, solver, isinteger): def delsarte_bound_Q_matrix(q, d, return_data=False, - solver="PPL", isinteger=False): + solver='PPL', isinteger=False): r""" Delsarte bound on a code with Q matrix ``q`` and lower bound on min. dist. ``d``. diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index 8b992ee9662..459d6c82ebc 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -23,6 +23,7 @@ from sage.misc.cachefunc import cached_method from sage.structure.sage_object import SageObject + class Encoder(SageObject): r""" Abstract top-class for :class:`Encoder` objects. @@ -61,7 +62,7 @@ class Encoder(SageObject): def __init__(self, code): r""" - Initializes mandatory parameters for an :class:`Encoder` object. + Initialize mandatory parameters for an :class:`Encoder` object. This method only exists for inheritance purposes as it initializes parameters that need to be known by every linear code. An abstract @@ -95,9 +96,10 @@ def __init__(self, code): def __ne__(self, other): r""" - Tests inequality of ``self`` and ``other``. + Test inequality of ``self`` and ``other``. - This is a generic implementation, which returns the inverse of ``__eq__`` for self. + This is a generic implementation, which returns the inverse of + ``__eq__`` for ``self``. EXAMPLES:: @@ -115,7 +117,7 @@ def __ne__(self, other): def encode(self, word): r""" - Transforms an element of the message space into a codeword. + Transform an element of the message space into a codeword. This is a default implementation which assumes that the message space of the encoder is `F^{k}`, where `F` is @@ -126,7 +128,7 @@ def encode(self, word): .. NOTE:: :meth:`encode` might be a partial function over ``self``'s :meth:`message_space`. - One should use the exception :class:`EncodingError` to catch attempts + One should use the exception :exc:`EncodingError` to catch attempts to encode words that are outside of the message space. One can use the following shortcut to encode a word with an encoder ``E``:: @@ -135,11 +137,9 @@ def encode(self, word): INPUT: - - ``word`` -- a vector of the message space of the ``self``. - - OUTPUT: + - ``word`` -- a vector of the message space of the ``self`` - - a vector of :meth:`code`. + OUTPUT: a vector of :meth:`code` EXAMPLES:: @@ -167,14 +167,14 @@ def encode(self, word): def __call__(self, m): r""" - Transforms an element of the message space into a codeword. + Transform an element of the message space into a codeword. This behaves the same as `self.encode`. See `sage.coding.encoder.Encoder.encode` for details. INPUT: - - ``word`` -- a vector of the message space of the ``self``. + - ``word`` -- a vector of the message space of the ``self`` EXAMPLES:: @@ -204,16 +204,15 @@ def unencode(self, c, nocheck=False): INPUT: - - ``c`` -- a codeword of :meth:`code`. - - - ``nocheck`` -- (default: ``False``) checks if ``c`` is in :meth:`code`. You might set - this to ``True`` to disable the check for saving computation. Note that if ``c`` is - not in :meth:`self` and ``nocheck = True``, then the output of :meth:`unencode` is - not defined (except that it will be in the message space of ``self``). + - ``c`` -- a codeword of :meth:`code` - OUTPUT: + - ``nocheck`` -- boolean (default: ``False``); checks if ``c`` is in + :meth:`code`. You might set this to ``True`` to disable the check for + saving computation. Note that if ``c`` is not in :meth:`self` and + ``nocheck = True``, then the output of :meth:`unencode` is not + defined (except that it will be in the message space of ``self``). - - an element of the message space of ``self`` + OUTPUT: an element of the message space of ``self`` EXAMPLES:: @@ -246,7 +245,7 @@ def unencode(self, c, nocheck=False): sage: C = LinearCode(G) Traceback (most recent call last): ... - ValueError: length must be a non-zero positive integer + ValueError: length must be a nonzero positive integer """ if not nocheck and c not in self.code(): raise EncodingError("Given word is not in the code") @@ -283,7 +282,7 @@ def _unencoder_matrix(self): def unencode_nocheck(self, c): r""" - Returns the message corresponding to ``c``. + Return the message corresponding to ``c``. When ``c`` is not a codeword, the output is unspecified. @@ -293,12 +292,9 @@ def unencode_nocheck(self, c): INPUT: + - ``c`` -- a codeword of :meth:`code` - - ``c`` -- a codeword of :meth:`code`. - - OUTPUT: - - - an element of the message space of ``self``. + OUTPUT: an element of the message space of ``self`` EXAMPLES:: @@ -332,7 +328,7 @@ def unencode_nocheck(self, c): def code(self): r""" - Returns the code for this :class:`Encoder`. + Return the code for this :class:`Encoder`. EXAMPLES:: @@ -347,7 +343,7 @@ def code(self): def message_space(self): r""" - Returns the ambient space of allowed input to :meth:`encode`. + Return the ambient space of allowed input to :meth:`encode`. Note that :meth:`encode` is possibly a partial function over the ambient space. @@ -365,7 +361,7 @@ def message_space(self): @abstract_method(optional=True) def generator_matrix(self): r""" - Returns a generator matrix of the associated code of ``self``. + Return a generator matrix of the associated code of ``self``. This is an abstract method and it should be implemented separately. Reimplementing this for each subclass of :class:`Encoder` is not mandatory @@ -385,6 +381,7 @@ def generator_matrix(self): [1 1 0 1 0 0 1] """ + class EncodingError(Exception): r""" Special exception class to indicate an error during encoding or unencoding. diff --git a/src/sage/coding/extended_code.py b/src/sage/coding/extended_code.py index a9d582b2a67..46335b19bdc 100644 --- a/src/sage/coding/extended_code.py +++ b/src/sage/coding/extended_code.py @@ -31,13 +31,14 @@ from sage.modules.free_module_element import vector from copy import copy + class ExtendedCode(AbstractLinearCode): r""" Representation of an extended code. INPUT: - - ``C`` -- A linear code + - ``C`` -- a linear code EXAMPLES:: @@ -71,7 +72,7 @@ def __init__(self, C): def __eq__(self, other): r""" - Tests equality between two extended codes. + Test equality between two extended codes. EXAMPLES:: @@ -186,7 +187,7 @@ class ExtendedCodeExtendedMatrixEncoder(Encoder): INPUT: - - ``code`` -- The associated code of ``self``. + - ``code`` -- the associated code of ``self`` """ def __init__(self, code): @@ -234,7 +235,7 @@ def _latex_(self): def __eq__(self, other): r""" - Tests equality between GRSEvaluationVectorEncoder objects. + Test equality between GRSEvaluationVectorEncoder objects. EXAMPLES:: @@ -285,7 +286,7 @@ class ExtendedCodeOriginalCodeDecoder(Decoder): INPUT: - - ``code`` -- The associated code of this decoder + - ``code`` -- the associated code of this decoder - ``original_decoder`` -- (default: ``None``) the decoder that will be used over the original code. It has to be a decoder object over the original code. @@ -444,7 +445,7 @@ def decoding_radius(self, *args, **kwargs): INPUT: - ``*args``, ``**kwargs`` -- arguments and optional arguments are - forwarded to original decoder's ``decoding_radius`` method. + forwarded to original decoder's ``decoding_radius`` method EXAMPLES:: diff --git a/src/sage/coding/gabidulin_code.py b/src/sage/coding/gabidulin_code.py index 341b9b89f5d..3db66e4af7b 100644 --- a/src/sage/coding/gabidulin_code.py +++ b/src/sage/coding/gabidulin_code.py @@ -207,7 +207,7 @@ def __init__(self, base_field, length, dimension, sub_field=None, if not len(evaluation_points) == length: raise ValueError("the number of evaluation points should be equal to the length of the code") for i in range(length): - if not evaluation_points[i] in base_field: + if evaluation_points[i] not in base_field: raise ValueError("evaluation point does not belong to the 'base field'") basis = self.matrix_form_of_vector(vector(evaluation_points)) if basis.rank() != length: @@ -257,9 +257,7 @@ def __eq__(self, other): - ``other`` -- another Gabidulin Code object - OUTPUT: - - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -399,7 +397,7 @@ def __init__(self, code): INPUT: - - ``code`` -- the associated code of this encoder. + - ``code`` -- the associated code of this encoder EXAMPLES:: @@ -467,9 +465,7 @@ def __eq__(self, other): - ``other`` -- another Gabidulin Generator Matrix Encoder - OUTPUT: - - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -625,9 +621,7 @@ def __eq__(self, other): - ``other`` -- another Gabidulin Polynomial Evaluation Encoder - OUTPUT: - - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -666,7 +660,7 @@ def message_space(self): C = self.code() return C.base_field()['x', C.twisting_homomorphism()] - def encode(self, p, form="vector"): + def encode(self, p, form='vector'): """ Transform the polynomial ``p`` into a codeword of :meth:`code`. @@ -680,11 +674,9 @@ def encode(self, p, form="vector"): - ``form`` -- type parameter taking strings "vector" or "matrix" as values and converting the output codeword into the respective form - (default: "vector") - - OUTPUT: + (default: ``'vector'``) - - a codeword corresponding to `p` in vector or matrix form + OUTPUT: a codeword corresponding to `p` in vector or matrix form EXAMPLES:: @@ -855,9 +847,7 @@ def __eq__(self, other) -> bool: - ``other`` -- another Gabidulin Gao Decoder - OUTPUT: - - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -894,9 +884,7 @@ def _partial_xgcd(self, a, b, d_stop): - ``d_stop`` -- the number of iterations for which the algorithm is to be run - OUTPUT: - - - ``r_c`` -- right linearized remainder of `a` and `b` + OUTPUT: ``r_c`` -- right linearized remainder of `a` and `b` - ``u_c`` -- right linearized quotient of `a` and `b` @@ -995,9 +983,7 @@ def decode_to_code(self, r): - ``r`` -- received codeword - OUTPUT: - - - the decoded codeword corresponding to the received codeword + OUTPUT: the decoded codeword corresponding to the received codeword EXAMPLES:: @@ -1028,9 +1014,7 @@ def decode_to_message(self, r): - ``r`` -- received codeword - OUTPUT: - - - the message corresponding to the received codeword + OUTPUT: the message corresponding to the received codeword EXAMPLES:: diff --git a/src/sage/coding/golay_code.py b/src/sage/coding/golay_code.py index 7690962b4b7..233c754df97 100644 --- a/src/sage/coding/golay_code.py +++ b/src/sage/coding/golay_code.py @@ -32,17 +32,18 @@ from .linear_code import (AbstractLinearCode, LinearCodeGeneratorMatrixEncoder) + class GolayCode(AbstractLinearCode): r""" Representation of a Golay Code. INPUT: - - ``base_field`` -- The base field over which the code is defined. - Can only be ``GF(2)`` or ``GF(3)``. + - ``base_field`` -- the base field over which the code is defined; + can only be ``GF(2)`` or ``GF(3)`` - - ``extended`` -- (default: ``True``) if set to ``True``, creates an extended Golay - code. + - ``extended`` -- boolean (default: ``True``); if set to ``True``, creates + an extended Golay code EXAMPLES:: @@ -238,7 +239,7 @@ def covering_radius(self): def weight_distribution(self): r""" - Return the list whose `i`'th entry is the number of words of weight `i` + Return the list whose `i`-th entry is the number of words of weight `i` in ``self``. The weight distribution of all Golay codes are known, and are thus returned @@ -282,7 +283,7 @@ def weight_distribution(self): def generator_matrix(self): r""" - Return a generator matrix of ``self`` + Return a generator matrix of ``self``. Generator matrices of all Golay codes are known, and are thus returned by this method without performing any computation diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index 9a87078c619..aede3782597 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -35,6 +35,7 @@ from sage.modules.free_module_element import vector from sage.coding.all import codes + def _columnize(element): """ Convert a finite field element to a column vector over the prime field. @@ -79,7 +80,7 @@ class GoppaCode(AbstractLinearCode): - ``generating_pol`` -- a monic polynomial with coefficients in a finite field `\GF{p^m}`, the code is defined over `\GF{p}`, `p` must be a prime number - - ``defining_set`` -- a set of elements of `\GF{p^m}` that are not roots + - ``defining_set`` -- set of elements of `\GF{p^m}` that are not roots of `g`, its cardinality is the length of the code EXAMPLES:: @@ -126,7 +127,7 @@ def __init__(self, generating_pol, defining_set): def _repr_(self): """ - Representation of a Goppa code + Representation of a Goppa code. EXAMPLES:: @@ -315,7 +316,7 @@ def distance_bound(self): class GoppaCodeEncoder(Encoder): r""" - Encoder for Goppa codes + Encoder for Goppa codes. Encodes words represented as vectors of length `k`, where `k` is the dimension of ``self``, with entries from `\GF{p}`, the prime field of @@ -393,7 +394,7 @@ def _latex_(self): def __eq__(self, other): """ - Test equality with ``other`` + Test equality with ``other``. EXAMPLES:: @@ -412,7 +413,7 @@ def __eq__(self, other): def generator_matrix(self): r""" - A generator matrix for ``self`` + A generator matrix for ``self``. Dimension of resulting matrix is `k \times n`, where `k` is the dimension of ``self`` and `n` is the length of ``self``. diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index 17f5e06114f..2fada75c4a9 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -11,7 +11,7 @@ \{ (f(\alpha_1), \ldots, f(\alpha_n)) \mid f \in F[x], \deg f < k \} An RS code is often called "classical" if `\alpha_i = \alpha^{i-1}` and `\alpha` -is a primitive `n`'th root of unity. +is a primitive `n`-th root of unity. More generally, given also `n` "column multipliers" `\beta_1, \dots, \beta_n`, the corresponding Generalized Reed-Solomon code (GRS code) of dimension `k` is @@ -76,18 +76,18 @@ class GeneralizedReedSolomonCode(AbstractLinearCode): INPUT: - - ``evaluation_points`` -- a list of distinct elements of some + - ``evaluation_points`` -- list of distinct elements of some finite field `F` - ``dimension`` -- the dimension of the resulting code - - ``column_multipliers`` -- (default: ``None``) list of non-zero + - ``column_multipliers`` -- (default: ``None``) list of nonzero elements of `F`; all column multipliers are set to 1 if default value is kept EXAMPLES: - Often, one constructs a Reed-Solomon code by taking all non-zero elements of + Often, one constructs a Reed-Solomon code by taking all nonzero elements of the field as evaluation points, and specifying no column multipliers (see also :func:`ReedSolomonCode` for constructing classical Reed-Solomon codes directly):: @@ -192,7 +192,7 @@ def __init__(self, evaluation_points, dimension, column_multipliers=None): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, F.list()[:n]) Traceback (most recent call last): ... - ValueError: All column multipliers must be non-zero + ValueError: All column multipliers must be nonzero And all the evaluation points must be different. Note that they should be different after converting into the same field:: @@ -240,7 +240,7 @@ def __init__(self, evaluation_points, dimension, column_multipliers=None): self._dimension = dimension if F.zero() in self._column_multipliers: - raise ValueError("All column multipliers must be non-zero") + raise ValueError("All column multipliers must be nonzero") if len(self._evaluation_points) != len(set(self._evaluation_points)): raise ValueError("All evaluation points must be different") @@ -503,7 +503,7 @@ def covering_radius(self): @cached_method def weight_distribution(self): r""" - Return the list whose `i`'th entry is the number of words of weight `i` + Return the list whose `i`-th entry is the number of words of weight `i` in ``self``. Computing the weight distribution for a GRS code is very fast. Note that @@ -550,7 +550,7 @@ def _punctured_form(self, points): INPUT: - - ``points`` -- a set of positions where to puncture ``self`` + - ``points`` -- set of positions where to puncture ``self`` EXAMPLES:: @@ -579,7 +579,7 @@ def ReedSolomonCode(base_field, length, dimension, primitive_root=None): A classical `[n,k]` Reed-Solomon code over `\GF{q}` with `1 \le k \le n` and `n | (q-1)` is a Reed-Solomon code whose evaluation points are the - consecutive powers of a primitive `n`'th root of unity `\alpha`, i.e. + consecutive powers of a primitive `n`-th root of unity `\alpha`, i.e. `\alpha_i = \alpha^{i-1}`, where `\alpha_1, \ldots, \alpha_n` are the evaluation points. A classical Reed-Solomon codes has all column multipliers equal `1`. @@ -593,17 +593,17 @@ def ReedSolomonCode(base_field, length, dimension, primitive_root=None): INPUT: - ``base_field`` -- the finite field for which to build the classical - Reed-Solomon code. + Reed-Solomon code - ``length`` -- the length of the classical Reed-Solomon code. Must divide - `q-1` where `q` is the cardinality of ``base_field``. + `q-1` where `q` is the cardinality of ``base_field`` - - ``dimension`` -- the dimension of the resulting code. + - ``dimension`` -- the dimension of the resulting code - - ``primitive_root`` -- (default: ``None``) a primitive `n`'th root of unity - to use for constructing the classical Reed-Solomon code. If not supplied, + - ``primitive_root`` -- (default: ``None``) a primitive `n`-th root of unity + to use for constructing the classical Reed-Solomon code; if not supplied, one will be computed and can be recovered as ``C.evaluation_points()[1]`` - where `C` is the code returned by this method. + where `C` is the code returned by this method EXAMPLES:: @@ -623,12 +623,12 @@ def ReedSolomonCode(base_field, length, dimension, primitive_root=None): sage: C = codes.ReedSolomonCode(GF(64,'a'), 9, 4); C [9, 4, 6] Reed-Solomon Code over GF(64) - The primitive `n`'th root of unity can be recovered as the 2nd evaluation point of the code:: + The primitive `n`-th root of unity can be recovered as the 2nd evaluation point of the code:: sage: alpha = C.evaluation_points()[1]; alpha a^5 + a^4 + a^2 + a - We can also supply a different primitive `n`'th root of unity:: + We can also supply a different primitive `n`-th root of unity:: sage: beta = alpha^2; beta a^4 + a @@ -759,7 +759,7 @@ def _latex_(self): @cached_method def generator_matrix(self): r""" - Return a generator matrix of ``self`` + Return a generator matrix of ``self``. Considering a GRS code of length `n`, dimension `k`, with evaluation points `(\alpha_1, \dots, \alpha_n)` and column multipliers @@ -872,7 +872,6 @@ def __init__(self, code, polynomial_ring=None): Traceback (most recent call last): ... ValueError: polynomial_ring's base field has to be the same as code's - """ from sage.rings.polynomial.polynomial_ring import PolynomialRing_commutative super().__init__(code) @@ -956,9 +955,7 @@ def encode(self, p): - ``p`` -- a polynomial from the message space of ``self`` of degree less than ``self.code().dimension()`` - OUTPUT: - - - a codeword in associated code of ``self`` + OUTPUT: a codeword in associated code of ``self`` EXAMPLES:: @@ -1056,7 +1053,6 @@ def unencode_nocheck(self, c): 6*x^4 + 6*x^3 + 2*x^2 sage: E.encode(p) == c False - """ C = self.code() alphas = C.evaluation_points() @@ -1070,7 +1066,7 @@ def unencode_nocheck(self, c): def message_space(self): r""" - Return the message space of ``self`` + Return the message space of ``self``. EXAMPLES:: @@ -1269,9 +1265,7 @@ def decode_to_message(self, r): - ``r`` -- a codeword of ``self`` - OUTPUT: - - - a vector of ``self`` message space + OUTPUT: a vector of ``self`` message space EXAMPLES:: @@ -1381,9 +1375,7 @@ def decoding_radius(self): r""" Return maximal number of errors that ``self`` can decode. - OUTPUT: - - - the number of errors as an integer + OUTPUT: the number of errors as an integer EXAMPLES:: @@ -1464,7 +1456,7 @@ def __eq__(self, other): def __hash__(self): """ - Return the hash of self. + Return the hash of ``self``. EXAMPLES:: @@ -1519,9 +1511,7 @@ def _polynomial_vanishing_at_alphas(self, PolRing): - ``PolRing`` -- polynomial ring of the output - OUTPUT: - - - a polynomial over ``PolRing`` + OUTPUT: a polynomial over ``PolRing`` EXAMPLES:: @@ -1541,7 +1531,7 @@ def _polynomial_vanishing_at_alphas(self, PolRing): def _partial_xgcd(self, a, b, PolRing): r""" - Performs an Euclidean algorithm on ``a`` and ``b`` until a remainder + Perform a Euclidean algorithm on ``a`` and ``b`` until a remainder has degree less than `\frac{n+k}{2}`, `n` being the dimension of the code, `k` its dimension, and returns `(r, s)` such that in the step just before termination, `r = a s + b t`. @@ -1652,9 +1642,7 @@ def decode_to_message(self, r): - ``r`` -- a codeword of ``self`` - OUTPUT: - - - a vector of ``self`` message space + OUTPUT: a vector of ``self`` message space EXAMPLES:: @@ -1764,11 +1752,9 @@ def decode_to_code(self, r): def decoding_radius(self): r""" - Return maximal number of errors that ``self`` can decode - - OUTPUT: + Return maximal number of errors that ``self`` can decode. - - the number of errors as an integer + OUTPUT: the number of errors as an integer EXAMPLES:: @@ -1898,7 +1884,7 @@ def decode_to_message(self, word_and_erasure_vector): INPUT: - - ``word_and_erasure_vector`` -- a tuple whose: + - ``word_and_erasure_vector`` -- tuple whose: * first element is an element of the ambient space of the code * second element is a vector over `\GF{2}` whose length is the @@ -1914,9 +1900,7 @@ def decode_to_message(self, word_and_erasure_vector): In either case, if ``r`` is not a codeword, the output is unspecified. - OUTPUT: - - - a vector of ``self`` message space + OUTPUT: a vector of ``self`` message space EXAMPLES:: @@ -1993,9 +1977,7 @@ def decoding_radius(self, number_erasures): - ``number_erasures`` -- the number of erasures when we try to decode - OUTPUT: - - - the number of errors as an integer + OUTPUT: the number of errors as an integer EXAMPLES:: @@ -2032,7 +2014,7 @@ class GRSKeyEquationSyndromeDecoder(Decoder): INPUT: - - ``code`` -- The associated code of this decoder. + - ``code`` -- the associated code of this decoder EXAMPLES:: @@ -2130,7 +2112,7 @@ def _latex_(self): def _partial_xgcd(self, a, b, PolRing): r""" - Performs an Euclidean algorithm on ``a`` and ``b`` until a remainder + Perform a Euclidean algorithm on ``a`` and ``b`` until a remainder has degree less than `\frac{n+k}{2}`, `n` being the dimension of the code, `k` its dimension, and returns `(r, t)` such that in the step just before termination, `r = a s + b t`. @@ -2177,9 +2159,7 @@ def _syndrome(self, r): - ``r`` -- a vector of the ambient space of ``self.code()`` - OUTPUT: - - - a list + OUTPUT: list EXAMPLES:: @@ -2214,9 +2194,7 @@ def _forney_formula(self, error_evaluator, error_locator): - ``error_evaluator``, ``error_locator`` -- two polynomials - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -2322,7 +2300,7 @@ def decode_to_code(self, r): def decode_to_message(self, r): r""" - Decode ``r`` to an element in message space of ``self`` + Decode ``r`` to an element in message space of ``self``. .. NOTE:: @@ -2334,9 +2312,7 @@ def decode_to_message(self, r): - ``r`` -- a codeword of ``self`` - OUTPUT: - - - a vector of ``self`` message space + OUTPUT: a vector of ``self`` message space EXAMPLES:: @@ -2358,11 +2334,9 @@ def decode_to_message(self, r): def decoding_radius(self): r""" - Return maximal number of errors that ``self`` can decode - - OUTPUT: + Return maximal number of errors that ``self`` can decode. - - the number of errors as an integer + OUTPUT: the number of errors as an integer EXAMPLES:: diff --git a/src/sage/coding/guava.py b/src/sage/coding/guava.py index 4dbe39e85b8..8a375af4bef 100644 --- a/src/sage/coding/guava.py +++ b/src/sage/coding/guava.py @@ -52,11 +52,9 @@ def QuasiQuadraticResidueCode(p): INPUT: - - ``p`` -- a prime `>2`. + - ``p`` -- a prime `>2` - OUTPUT: - - Returns a QQR code of length `2p`. + OUTPUT: a QQR code of length `2p` EXAMPLES:: @@ -67,8 +65,8 @@ def QuasiQuadraticResidueCode(p): AUTHOR: David Joyner (11-2005) """ - GapPackage("guava", spkg="gap_packages").require() - libgap.load_package("guava") + GapPackage('guava', spkg='gap_packages').require() + libgap.load_package('guava') C = libgap.QQRCode(p) G = C.GeneratorMat() MS = MatrixSpace(GF(2), len(G), len(G[0])) @@ -85,11 +83,9 @@ def RandomLinearCodeGuava(n, k, F): INPUT: - - ``n``, ``k`` -- integers with `n>k>1`. - - OUTPUT: + - ``n``, ``k`` -- integers with `n>k>1` - Returns a "random" linear code with length `n`, dimension `k` over field `F`. + OUTPUT: a "random" linear code with length `n`, dimension `k` over field `F` EXAMPLES:: @@ -102,8 +98,8 @@ def RandomLinearCodeGuava(n, k, F): """ current_randstate().set_seed_gap() - GapPackage("guava", spkg="gap_packages").require() - libgap.load_package("guava") + GapPackage('guava', spkg='gap_packages').require() + libgap.load_package('guava') C = libgap.RandomLinearCode(n,k,F) G = C.GeneratorMat() MS = MatrixSpace(F, len(G), len(G[0])) diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 2cd680b5da0..54a624375bd 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -36,6 +36,7 @@ from sage.functions.other import floor from sage.misc.functional import sqrt + def n_k_params(C, n_k): r""" Internal helper function for the :class:`GRSGuruswamiSudanDecoder` class for @@ -48,14 +49,14 @@ def n_k_params(C, n_k): INPUT: - - ``C`` -- A GRS code or ``None`` + - ``C`` -- a GRS code or ``None`` - - ``n_k`` -- A tuple `(n,k)` being length and dimension of a GRS code, or - ``None``. + - ``n_k`` -- tuple `(n,k)` being length and dimension of a GRS code, or + ``None`` OUTPUT: - - ``n_k`` -- A tuple `(n,k)` being length and dimension of a GRS code. + - ``n_k`` -- tuple `(n,k)` being length and dimension of a GRS code EXAMPLES:: @@ -85,6 +86,7 @@ def n_k_params(C, n_k): elif n_k is not None: return n_k + def roth_ruckenstein_root_finder(p, maxd=None, precision=None): """ Wrapper for Roth-Ruckenstein algorithm to compute the roots of a polynomial @@ -102,7 +104,8 @@ def roth_ruckenstein_root_finder(p, maxd=None, precision=None): gens = p.parent().gens() if len(gens) == 2: p = p.polynomial(gens[1]) - return p.roots(multiplicities=False, degree_bound=maxd, algorithm="Roth-Ruckenstein") + return p.roots(multiplicities=False, degree_bound=maxd, algorithm='Roth-Ruckenstein') + def alekhnovich_root_finder(p, maxd=None, precision=None): """ @@ -121,7 +124,8 @@ def alekhnovich_root_finder(p, maxd=None, precision=None): gens = p.parent().gens() if len(gens) == 2: p = p.polynomial(gens[1]) - return p.roots(multiplicities=False, degree_bound=maxd, algorithm="Alekhnovich") + return p.roots(multiplicities=False, degree_bound=maxd, algorithm='Alekhnovich') + class GRSGuruswamiSudanDecoder(Decoder): r""" @@ -152,10 +156,10 @@ class GRSGuruswamiSudanDecoder(Decoder): INPUT: - - ``code`` -- A code associated to this decoder. + - ``code`` -- a code associated to this decoder - - ``tau`` -- (default: ``None``) an integer, the number of errors one wants the - Guruswami-Sudan algorithm to correct. + - ``tau`` -- integer (default: ``None``); the number of errors one wants the + Guruswami-Sudan algorithm to correct - ``parameters`` -- (default: ``None``) a pair of integers, where: @@ -165,8 +169,8 @@ class GRSGuruswamiSudanDecoder(Decoder): - ``interpolation_alg`` -- (default: ``None``) the interpolation algorithm that will be used. The following possibilities are currently available: - * ``"LinearAlgebra"`` -- uses a linear system solver. - * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction + * ``'LinearAlgebra'`` -- uses a linear system solver. + * ``'LeeOSullivan'`` -- uses Lee O'Sullivan method based on row reduction of a matrix * ``None`` -- one of the above will be chosen based on the size of the code and the parameters. @@ -177,9 +181,9 @@ class GRSGuruswamiSudanDecoder(Decoder): - ``root_finder`` -- (default: ``None``) the rootfinding algorithm that will be used. The following possibilities are currently available: - * ``"Alekhnovich"`` -- uses Alekhnovich's algorithm. + * ``'Alekhnovich'`` -- uses Alekhnovich's algorithm. - * ``"RothRuckenstein"`` -- uses Roth-Ruckenstein algorithm. + * ``'RothRuckenstein'`` -- uses Roth-Ruckenstein algorithm. * ``None`` -- one of the above will be chosen based on the size of the code and the parameters. @@ -231,7 +235,7 @@ class GRSGuruswamiSudanDecoder(Decoder): sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2), - ....: root_finder="RothRuckenstein"); D + ....: root_finder='RothRuckenstein'); D Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) @@ -252,7 +256,7 @@ def parameters_given_tau(tau, C=None, n_k=None): INPUT: - - ``tau`` -- an integer, number of errors one wants the Guruswami-Sudan + - ``tau`` -- integer; number of errors one wants the Guruswami-Sudan algorithm to correct - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the @@ -331,8 +335,9 @@ def guruswami_sudan_decoding_radius(C=None, n_k=None, l=None, s=None): - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the length and the dimension of the :class:`GeneralizedReedSolomonCode` - - ``s`` -- (default: ``None``) an integer, the multiplicity parameter of Guruswami-Sudan algorithm - - ``l`` -- (default: ``None``) an integer, the list size parameter + - ``s`` -- integer (default: ``None``); the multiplicity parameter of + Guruswami-Sudan algorithm + - ``l`` -- integer (default: ``None``); the list size parameter .. NOTE:: @@ -427,7 +432,7 @@ def _suitable_parameters_given_tau(tau, C=None, n_k=None): INPUT: - - ``tau`` -- an integer, number of errors one wants the Guruswami-Sudan + - ``tau`` -- integer; number of errors one wants the Guruswami-Sudan algorithm to correct - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the @@ -497,10 +502,10 @@ def gs_satisfactory(tau, s, l, C=None, n_k=None): INPUT: - - ``tau`` -- an integer, number of errors one expects Guruswami-Sudan algorithm + - ``tau`` -- integer; number of errors one expects Guruswami-Sudan algorithm to correct - - ``s`` -- an integer, multiplicity parameter of Guruswami-Sudan algorithm - - ``l`` -- an integer, list size parameter + - ``s`` -- integer; multiplicity parameter of Guruswami-Sudan algorithm + - ``l`` -- integer; list size parameter - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a tuple of integers, respectively the length and the dimension of the :class:`GeneralizedReedSolomonCode` @@ -576,7 +581,7 @@ def __init__(self, code, tau=None, parameters=None, interpolation_alg=None, root Same thing for ``root_finder``:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = GSD(C, tau=97, root_finder="FortyTwo") + sage: D = GSD(C, tau=97, root_finder='FortyTwo') Traceback (most recent call last): ... ValueError: Please provide a method or one of the allowed strings for root_finder @@ -660,7 +665,7 @@ def _latex_(self): def __eq__(self, other): r""" - Tests equality between GRSGuruswamiSudanDecoder objects. + Test equality between GRSGuruswamiSudanDecoder objects. EXAMPLES:: @@ -762,7 +767,7 @@ def decode_to_message(self, r): INPUT: - ``r`` -- a received word, i.e. a vector in `F^n` where `F` and `n` are - the base field respectively length of :meth:`self.code`. + the base field respectively length of :meth:`self.code` EXAMPLES:: @@ -807,7 +812,7 @@ def decode_to_code(self, r): INPUT: - ``r`` -- a received word, i.e. a vector in `F^n` where `F` and `n` are - the base field respectively length of :meth:`self.code`. + the base field respectively length of :meth:`self.code` EXAMPLES:: diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index ec4307a500b..b1334307e79 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -25,6 +25,8 @@ from sage.misc.misc_c import prod ####################### Linear algebra system solving ############################### + + def _flatten_once(lstlst): r""" Flattens a list of list into a list, but only flattening one layer and @@ -36,7 +38,7 @@ def _flatten_once(lstlst): INPUT: - - ``lstlst`` -- a list of lists. + - ``lstlst`` -- list of lists EXAMPLES:: @@ -52,18 +54,17 @@ def _flatten_once(lstlst): # Linear algebraic Interpolation algorithm, helper functions #************************************************************* + def _monomial_list(maxdeg, l, wy): r""" - Returns a list of all non-negative integer pairs `(i,j)` such that ``i + wy + Return a list of all nonnegative integer pairs `(i,j)` such that ``i + wy * j < maxdeg`` and ``j \geq l``. INPUT: - - ``maxdeg``, ``l``, ``wy`` -- integers. + - ``maxdeg``, ``l``, ``wy`` -- integers - OUTPUT: - - - a list of pairs of integers. + OUTPUT: list of pairs of integers EXAMPLES:: @@ -90,7 +91,7 @@ def _monomial_list(maxdeg, l, wy): def _interpolation_matrix_given_monomials(points, s, monomials): r""" - Returns a matrix whose nullspace is a basis for all interpolation + Return a matrix whose nullspace is a basis for all interpolation polynomials, each polynomial having its coefficients laid out according to the given list of monomials. @@ -100,11 +101,11 @@ def _interpolation_matrix_given_monomials(points, s, monomials): INPUT: - - ``points`` -- a list of pairs of field elements, the interpolation points. + - ``points`` -- list of pairs of field elements, the interpolation points - - ``s`` -- an integer, the multiplicity parameter from Guruswami-Sudan algorithm. + - ``s`` -- integer; the multiplicity parameter from Guruswami-Sudan algorithm - - ``monomials`` -- a list of monomials, each represented by the powers as an integer pair `(i,j)`. + - ``monomials`` -- list of monomials, each represented by the powers as an integer pair `(i,j)` EXAMPLES:: @@ -158,27 +159,28 @@ def _interpolation_max_weighted_deg(n, tau, s): """ return (n-tau) * s + def _interpolation_matrix_problem(points, tau, parameters, wy): r""" - Returns the linear system of equations which ``Q`` should be a solution to. + Return the linear system of equations which ``Q`` should be a solution to. This linear system is returned as a matrix ``M`` and a list of monomials ``monomials``, where a vector in the right nullspace of ``M`` corresponds to an - interpolation polynomial `Q`, by mapping the `t`'th element of such a vector - to the coefficient to `x^iy^j`, where `(i,j)` is the `t`'th element of ``monomials``. + interpolation polynomial `Q`, by mapping the `t`-th element of such a vector + to the coefficient to `x^iy^j`, where `(i,j)` is the `t`-th element of ``monomials``. INPUT: - - ``points`` -- a list of interpolation points, as pairs of field elements. + - ``points`` -- list of interpolation points, as pairs of field elements - - ``tau`` -- an integer, the number of errors one wants to decode. + - ``tau`` -- integer; the number of errors one wants to decode - ``parameters`` -- (default: ``None``) a pair of integers, where: - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - the second integer is the list size parameter. - - ``wy`` -- an integer specifying the `y`-weighted degree that is to be + - ``wy`` -- integer; specifying the `y`-weighted degree that is to be minimised in the interpolation polynomial. In Guruswami-Sudan, this is `k-1`, where `k` is the dimension of the GRS code. @@ -235,10 +237,10 @@ def gs_interpolation_linalg(points, tau, parameters, wy): INPUT: - - ``points`` -- a list of tuples ``(xi, yi)`` such that we seek ``Q`` with - ``(xi,yi)`` being a root of ``Q`` with multiplicity ``s``. + - ``points`` -- list of tuples ``(xi, yi)`` such that we seek ``Q`` with + ``(xi,yi)`` being a root of ``Q`` with multiplicity ``s`` - - ``tau`` -- an integer, the number of errors one wants to decode. + - ``tau`` -- integer; the number of errors one wants to decode - ``parameters`` -- (default: ``None``) a pair of integers, where: @@ -246,8 +248,8 @@ def gs_interpolation_linalg(points, tau, parameters, wy): algorithm and - the second integer is the list size parameter. - - ``wy`` -- an integer, the `y`-weight, where we seek `Q` of low - ``(1, wy)``-weighted degree. + - ``wy`` -- integer; the `y`-weight, where we seek `Q` of low + ``(1, wy)``-weighted degree EXAMPLES: @@ -279,7 +281,7 @@ def gs_interpolation_linalg(points, tau, parameters, wy): """ M, monomials = _interpolation_matrix_problem(points, tau, parameters, wy) Ker = M.right_kernel() - # Pick a non-zero element from the right kernel + # Pick a nonzero element from the right kernel sol = Ker.basis()[0] # Construct the Q polynomial PF = M.base_ring()['x', 'y'] #make that ring a ring in @@ -289,6 +291,7 @@ def gs_interpolation_linalg(points, tau, parameters, wy): ####################### Lee-O'Sullivan's method ############################### + def lee_osullivan_module(points, parameters, wy): r""" Return the analytically straight-forward basis for the `\GF{q}[x]` module @@ -298,7 +301,7 @@ def lee_osullivan_module(points, parameters, wy): The module is constructed in the following way: Let `R(x)` be the Lagrange interpolation polynomial through the sought interpolation points `(x_i, y_i)`, i.e. `R(x_i) = y_i`. Let `G(x) = \prod_{i=1}^n (x-x_i)`. Then the - `i`'th row of the basis matrix of the module is the coefficient-vector of + `i`-th row of the basis matrix of the module is the coefficient-vector of the following polynomial in `\GF{q}[x][y]`: `P_i(x,y) = G(x)^{[i-s]} (y - R(x))^{i - [i-s]} y^{[i-s]}` , @@ -310,8 +313,8 @@ def lee_osullivan_module(points, parameters, wy): INPUT: - - ``points`` -- a list of tuples ``(xi, yi)`` such that we seek `Q` with - ``(xi,yi)`` being a root of `Q` with multiplicity `s`. + - ``points`` -- list of tuples ``(xi, yi)`` such that we seek `Q` with + ``(xi,yi)`` being a root of `Q` with multiplicity `s` - ``parameters`` -- (default: ``None``) a pair of integers, where: @@ -319,8 +322,8 @@ def lee_osullivan_module(points, parameters, wy): algorithm and - the second integer is the list size parameter. - - ``wy`` -- an integer, the `y`-weight, where we seek `Q` of low - ``(1,wy)`` weighted degree. + - ``wy`` -- integer; the `y`-weight, where we seek `Q` of low + ``(1,wy)`` weighted degree EXAMPLES:: @@ -353,7 +356,7 @@ def pad(lst): def gs_interpolation_lee_osullivan(points, tau, parameters, wy): r""" - Returns an interpolation polynomial Q(x,y) for the given input using the + Return an interpolation polynomial Q(x,y) for the given input using the module-based algorithm of Lee and O'Sullivan. This algorithm constructs an explicit `(\ell+1) \times (\ell+1)` polynomial @@ -364,10 +367,10 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): INPUT: - - ``points`` -- a list of tuples ``(xi, yi)`` such that we seek ``Q`` with - ``(xi,yi)`` being a root of ``Q`` with multiplicity ``s``. + - ``points`` -- list of tuples ``(xi, yi)`` such that we seek ``Q`` with + ``(xi,yi)`` being a root of ``Q`` with multiplicity ``s`` - - ``tau`` -- an integer, the number of errors one wants to decode. + - ``tau`` -- integer; the number of errors one wants to decode - ``parameters`` -- (default: ``None``) a pair of integers, where: @@ -375,8 +378,8 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): algorithm and - the second integer is the list size parameter. - - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low - ``(1,wy)`` weighted degree. + - ``wy`` -- integer; the `y`-weight, where we seek ``Q`` of low + ``(1,wy)`` weighted degree EXAMPLES:: diff --git a/src/sage/coding/guruswami_sudan/utils.py b/src/sage/coding/guruswami_sudan/utils.py index f29d4eac46f..31bfdf85e64 100644 --- a/src/sage/coding/guruswami_sudan/utils.py +++ b/src/sage/coding/guruswami_sudan/utils.py @@ -29,14 +29,14 @@ def polynomial_to_list(p, len): r""" - Returns ``p`` as a list of its coefficients of length ``len``. + Return ``p`` as a list of its coefficients of length ``len``. INPUT: - ``p`` -- a polynomial - - ``len`` -- an integer. If ``len`` is smaller than the degree of ``p``, the - returned list will be of size degree of ``p``, else it will be of size ``len``. + - ``len`` -- integer; if ``len`` is smaller than the degree of ``p``, the + returned list will be of size degree of ``p``, else it will be of size ``len`` EXAMPLES:: @@ -51,14 +51,14 @@ def polynomial_to_list(p, len): def johnson_radius(n, d): r""" - Returns the Johnson-radius for the code length `n` and the minimum distance `d`. + Return the Johnson-radius for the code length `n` and the minimum distance `d`. The Johnson radius is defined as `n - \sqrt(n(n-d))`. INPUT: - - ``n`` -- an integer, the length of the code - - ``d`` -- an integer, the minimum distance of the code + - ``n`` -- integer; the length of the code + - ``d`` -- integer; the minimum distance of the code EXAMPLES:: @@ -70,7 +70,7 @@ def johnson_radius(n, d): def ligt(x): r""" - Returns the least integer greater than ``x``. + Return the least integer greater than ``x``. EXAMPLES:: @@ -88,7 +88,7 @@ def ligt(x): def gilt(x): r""" - Returns the greatest integer smaller than ``x``. + Return the greatest integer smaller than ``x``. EXAMPLES:: @@ -109,16 +109,17 @@ def gilt(x): def solve_degree2_to_integer_range(a, b, c): r""" - Returns the greatest integer range `[i_1, i_2]` such that - `i_1 > x_1` and `i_2 < x_2` where `x_1, x_2` are the two zeroes of the equation in `x`: - `ax^2+bx+c=0`. + Return the greatest integer range `[i_1, i_2]` such that + `i_1 > x_1` and `i_2 < x_2` where `x_1, x_2` are the two zeroes of the + equation in `x`: `ax^2+bx+c=0`. - If there is no real solution to the equation, it returns an empty range with negative coefficients. + If there is no real solution to the equation, it returns an empty range + with negative coefficients. INPUT: - - ``a``, ``b`` and ``c`` -- coefficients of a second degree equation, ``a`` being the coefficient of - the higher degree term. + - ``a``, ``b`` and ``c`` -- coefficients of a second degree equation, ``a`` + being the coefficient of the higher degree term EXAMPLES:: @@ -145,11 +146,11 @@ def solve_degree2_to_integer_range(a, b, c): def _degree_of_vector(v, shifts=None): r""" - Returns the greatest degree among the entries of the polynomial vector `v`. + Return the greatest degree among the entries of the polynomial vector `v`. INPUT: - - ``v`` -- a vector of polynomials. + - ``v`` -- a vector of polynomials - ``shifts`` -- (default: ``None``) a list of integer shifts to consider ``v`` under, i.e. compute `\max(\deg v_i + s_i)`, where `s_1,\ldots, s_n` diff --git a/src/sage/coding/hamming_code.py b/src/sage/coding/hamming_code.py index 184023e3c29..431e660fae7 100644 --- a/src/sage/coding/hamming_code.py +++ b/src/sage/coding/hamming_code.py @@ -33,9 +33,9 @@ class HammingCode(AbstractLinearCode): INPUT: - - ``base_field`` -- the base field over which ``self`` is defined. + - ``base_field`` -- the base field over which ``self`` is defined - - ``order`` -- the order of ``self``. + - ``order`` -- the order of ``self`` EXAMPLES:: @@ -147,7 +147,6 @@ def parity_check_matrix(self): [1 0 1 1 0 1 0 1 1 1 0 1 1] [0 1 1 2 0 0 1 1 2 0 1 1 2] [0 0 0 0 1 1 1 1 1 2 2 2 2] - """ n = self.length() F = self.base_field() diff --git a/src/sage/coding/information_set_decoder.py b/src/sage/coding/information_set_decoder.py index 32bce3225e9..c059b185816 100644 --- a/src/sage/coding/information_set_decoder.py +++ b/src/sage/coding/information_set_decoder.py @@ -68,6 +68,7 @@ def _format_decoding_interval(decoding_interval): return "exactly {0}".format(decoding_interval[0]) return "between {0} and {1}".format(decoding_interval[0], decoding_interval[1]) + class InformationSetAlgorithm(SageObject): r""" Abstract class for algorithms for @@ -78,14 +79,14 @@ class InformationSetAlgorithm(SageObject): INPUT: - - ``code`` -- A linear code for which to decode. + - ``code`` -- a linear code for which to decode - - ``number_errors`` -- an integer, the maximal number of errors to accept as + - ``number_errors`` -- integer; the maximal number of errors to accept as correct decoding. An interval can also be specified by giving a pair of integers, where both end values are taken to be in the interval. - - ``algorithm_name`` -- A name for the specific ISD algorithm used (used for - printing). + - ``algorithm_name`` -- a name for the specific ISD algorithm used (used for + printing) - ``parameters`` -- (optional) A dictionary for setting the parameters of this ISD algorithm. Note that sanity checking this dictionary for the @@ -269,7 +270,7 @@ def parameters(self): def __eq__(self, other): r""" - Tests equality between ISD algorithm objects. + Test equality between ISD algorithm objects. EXAMPLES:: @@ -301,7 +302,7 @@ def __eq__(self, other): def __hash__(self): r""" - Returns the hash value of ``self``. + Return the hash value of ``self``. EXAMPLES:: @@ -319,7 +320,7 @@ def __hash__(self): def _repr_(self): r""" - Returns a string representation of this ISD algorithm. + Return a string representation of this ISD algorithm. EXAMPLES:: @@ -333,7 +334,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of this ISD algorithm. + Return a latex representation of this ISD algorithm. EXAMPLES:: @@ -372,10 +373,10 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): INPUT: - - ``code`` -- A linear code for which to decode. + - ``code`` -- a linear code for which to decode - ``decoding_interval`` -- a pair of integers specifying an interval of - number of errors to correct. Includes both end values. + number of errors to correct; includes both end values - ``search_size`` -- (optional) the size of subsets to use on step 3 of the algorithm as described above. Usually a small number. It has to be at most @@ -439,10 +440,10 @@ def decode(self, r): INPUT: - - `r` -- a received word, i.e. a vector in the ambient space of - :meth:`decoder.Decoder.code`. + - ``r`` -- a received word, i.e. a vector in the ambient space of + :meth:`decoder.Decoder.code` - OUTPUT: A codeword whose distance to `r` satisfies ``self.decoding_interval()``. + OUTPUT: a codeword whose distance to `r` satisfies ``self.decoding_interval()``. EXAMPLES:: @@ -518,10 +519,10 @@ def calibrate(self): computations similar to those done by the decoding algorithm. We don't explicitly estimate `\rho`. - OUTPUT: Does not output anything but sets private fields used by + OUTPUT: does not output anything but sets private fields used by :meth:`sage.coding.information_set_decoder.InformationSetAlgorithm.parameters()` and - :meth:`sage.coding.information_set_decoder.InformationSetAlgorithm.time_estimate()``. + :meth:`sage.coding.information_set_decoder.InformationSetAlgorithm.time_estimate()`. EXAMPLES:: @@ -606,10 +607,10 @@ def _calibrate_select(self, estimates): INPUT: - - `estimates` -- list of time estimates, for the search size set to the - index of the list entry. + - ``estimates`` -- list of time estimates, for the search size set to the + index of the list entry - OUTPUT: None, but sets the private fields `self._parameters` and + OUTPUT: none, but sets the private fields `self._parameters` and `self._time_estimate`. TESTS:: @@ -668,9 +669,9 @@ class LinearCodeInformationSetDecoder(Decoder): INPUT: - - ``code`` -- A linear code for which to decode. + - ``code`` -- a linear code for which to decode - - ``number_errors`` -- an integer, the maximal number of errors to accept as + - ``number_errors`` -- integer; the maximal number of errors to accept as correct decoding. An interval can also be specified by giving a pair of integers, where both end values are taken to be in the interval. @@ -697,7 +698,7 @@ class LinearCodeInformationSetDecoder(Decoder): :meth:`sage.code.linear_code.AbstractLinearCode.decoder` method:: sage: C = codes.GolayCode(GF(3)) - sage: D = C.decoder("InformationSet", 2); D + sage: D = C.decoder('InformationSet', 2); D Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors @@ -705,7 +706,7 @@ class LinearCodeInformationSetDecoder(Decoder): order to pass special parameters to it:: sage: C = codes.GolayCode(GF(3)) - sage: D2 = C.decoder("InformationSet", 2, algorithm="Lee-Brickell", search_size=2); D2 + sage: D2 = C.decoder('InformationSet', 2, algorithm='Lee-Brickell', search_size=2); D2 Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors sage: D2.algorithm() @@ -716,7 +717,7 @@ class LinearCodeInformationSetDecoder(Decoder): If you specify an algorithm which is not known, you get a friendly error message:: - sage: C.decoder("InformationSet", 2, algorithm="NoSuchThing") + sage: C.decoder('InformationSet', 2, algorithm="NoSuchThing") Traceback (most recent call last): ... ValueError: Unknown ISD algorithm 'NoSuchThing'. @@ -727,14 +728,14 @@ class LinearCodeInformationSetDecoder(Decoder): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0, 2)) - sage: D = C.decoder("InformationSet", 2, algorithm=A); D + sage: D = C.decoder('InformationSet', 2, algorithm=A); D Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors When passing an already constructed ISD algorithm, you can't also pass parameters to the ISD algorithm when constructing the decoder:: - sage: C.decoder("InformationSet", 2, algorithm=A, search_size=2) + sage: C.decoder('InformationSet', 2, algorithm=A, search_size=2) Traceback (most recent call last): ... ValueError: ISD algorithm arguments are not allowed @@ -743,7 +744,7 @@ class LinearCodeInformationSetDecoder(Decoder): We can also information-set decode non-binary codes:: sage: C = codes.GolayCode(GF(3)) - sage: D = C.decoder("InformationSet", 2); D + sage: D = C.decoder('InformationSet', 2); D Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors @@ -766,7 +767,7 @@ def __init__(self, code, number_errors, algorithm=None, **kwargs): or an Integer/int:: sage: C = codes.GolayCode(GF(2)) - sage: D = C.decoder("InformationSet", "aa") + sage: D = C.decoder('InformationSet', "aa") Traceback (most recent call last): ... ValueError: number_errors should be an integer or a pair of integers @@ -775,14 +776,14 @@ def __init__(self, code, number_errors, algorithm=None, **kwargs): two values, the first one being at most the second one:: sage: C = codes.GolayCode(GF(2)) - sage: D = C.decoder("InformationSet", (4, 2)) + sage: D = C.decoder('InformationSet', (4, 2)) Traceback (most recent call last): ... ValueError: number_errors should be a positive integer or a valid interval within the positive integers You cannot ask the decoder to correct more errors than the code length:: - sage: D = C.decoder("InformationSet", 25) + sage: D = C.decoder('InformationSet', 25) Traceback (most recent call last): ... ValueError: The provided number of errors should be at most the code's length @@ -790,7 +791,7 @@ def __init__(self, code, number_errors, algorithm=None, **kwargs): If ``algorithm`` is not set, additional parameters cannot be passed to the ISD algorithm:: - sage: D = C.decoder("InformationSet", 2, search_size=2) + sage: D = C.decoder('InformationSet', 2, search_size=2) Traceback (most recent call last): ... ValueError: Additional arguments to an information-set decoder algorithm are only allowed if a specific algorithm is selected by setting the algorithm keyword @@ -800,7 +801,7 @@ def __init__(self, code, number_errors, algorithm=None, **kwargs): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0, 2)) - sage: D = C.decoder("InformationSet", 2, A, search_size=3) + sage: D = C.decoder('InformationSet', 2, A, search_size=3) Traceback (most recent call last): ... ValueError: ISD algorithm arguments are not allowed when supplying a constructed ISD algorithm @@ -812,11 +813,11 @@ def __init__(self, code, number_errors, algorithm=None, **kwargs): sage: C = codes.GolayCode(GF(2)) sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0, 2)) - sage: D = C.decoder("InformationSet", 2, A); D + sage: D = C.decoder('InformationSet', 2, A); D Information-set decoder (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 2 errors - sage: D = C.decoder("InformationSet", (0,2), A); D + sage: D = C.decoder('InformationSet', (0,2), A); D Information-set decoder (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 2 errors - sage: D = C.decoder("InformationSet", 3, A); D + sage: D = C.decoder('InformationSet', 3, A); D Traceback (most recent call last): ... ValueError: number_errors must match that of the passed ISD algorithm @@ -878,10 +879,10 @@ def known_algorithms(dictionary=False): INPUT: - - ``dictionary`` -- optional. If set to ``True``, return a ``dict`` - mapping decoding algorithm name to its class. + - ``dictionary`` -- boolean (default: ``False``); if set to ``True``, + return a ``dict`` mapping decoding algorithm name to its class - OUTPUT: a list of strings or a ``dict`` from string to ISD algorithm class. + OUTPUT: list of strings or a ``dict`` from string to ISD algorithm class EXAMPLES:: @@ -901,7 +902,7 @@ def algorithm(self): EXAMPLES:: sage: C = codes.GolayCode(GF(2)) - sage: D = C.decoder("InformationSet", (2,4), "Lee-Brickell") + sage: D = C.decoder('InformationSet', (2,4), "Lee-Brickell") sage: D.algorithm() ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding between 2 and 4 errors @@ -921,9 +922,9 @@ def decode_to_code(self, r): INPUT: - - ``r`` -- a vector in the ambient space of :meth:`decoder.Decoder.code`. + - ``r`` -- a vector in the ambient space of :meth:`decoder.Decoder.code` - OUTPUT: a codeword of :meth:`decoder.Decoder.code`. + OUTPUT: a codeword of :meth:`decoder.Decoder.code` EXAMPLES:: @@ -976,7 +977,7 @@ def decoding_radius(self): EXAMPLES:: sage: C = codes.GolayCode(GF(2)) - sage: D = C.decoder("InformationSet", 2) + sage: D = C.decoder('InformationSet', 2) sage: D.decoding_radius() 2 """ @@ -992,7 +993,7 @@ def decoding_interval(self): EXAMPLES:: sage: C = codes.GolayCode(GF(2)) - sage: D = C.decoder("InformationSet", 2) + sage: D = C.decoder('InformationSet', 2) sage: D.decoding_interval() (0, 2) """ @@ -1000,12 +1001,12 @@ def decoding_interval(self): def _repr_(self): r""" - Returns a string representation of this decoding algorithm. + Return a string representation of this decoding algorithm. EXAMPLES:: sage: C = codes.GolayCode(GF(2)) - sage: D = C.decoder("InformationSet", 2) + sage: D = C.decoder('InformationSet', 2) sage: D Information-set decoder (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 2 errors """ @@ -1013,13 +1014,13 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of this decoding algorithm. + Return a latex representation of this decoding algorithm. EXAMPLES:: sage: C = codes.GolayCode(GF(2)) sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm - sage: D = C.decoder("InformationSet", 2) + sage: D = C.decoder('InformationSet', 2) sage: latex(D) \textnormal{Information-set decoder (Lee-Brickell) for }[24, 12, 8] \textnormal{ Extended Golay Code over } \Bold{F}_{2} \textnormal{decoding up to 2 errors} """ diff --git a/src/sage/coding/kasami_codes.pyx b/src/sage/coding/kasami_codes.pyx index ef70ec676fd..835806fd808 100644 --- a/src/sage/coding/kasami_codes.pyx +++ b/src/sage/coding/kasami_codes.pyx @@ -90,10 +90,10 @@ class KasamiCode(AbstractLinearCode): INPUT: - - ``s``, ``t`` -- (integer) the parameters of the Kasami code + - ``s``, ``t`` -- integer; the parameters of the Kasami code - - ``extended`` -- (default: ``True``) if set to ``True``, - creates an extended Kasami code. + - ``extended`` -- boolean (default: ``True``); if set to ``True``, + creates an extended Kasami code EXAMPLES:: diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 91e2855fd79..a9e3813b474 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -18,7 +18,7 @@ parity check matrix for `C`. We commonly endow `F^n` with the Hamming metric, i.e. the weight of a vector is -the number of non-zero elements in it. The central operation of a linear code +the number of nonzero elements in it. The central operation of a linear code is then "decoding": given a linear code `C \subset F^n` and a "received word" `r \in F^n` , retrieve the codeword `c \in C` such that the Hamming distance between `r` and `c` is minimal. @@ -253,9 +253,7 @@ def _dump_code_in_leon_format(C): - ``C`` -- a linear code (over GF(p), p < 11) - OUTPUT: - - - Absolute path to the file written + OUTPUT: absolute path to the file written EXAMPLES:: @@ -272,7 +270,6 @@ def _dump_code_in_leon_format(C): )); FINISH; sage: f.close() - """ from sage.misc.temporary_file import tmp_filename F = C.base_ring() @@ -346,14 +343,13 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric): A lot of methods of the abstract class rely on the knowledge of a generator matrix. It is thus strongly recommended to set an encoder with a generator matrix implemented as a default encoder. - """ _registered_encoders = {} _registered_decoders = {} def __init__(self, base_field, length, default_encoder_name, default_decoder_name): """ - Initializes mandatory parameters that any linear code shares. + Initialize mandatory parameters that any linear code shares. This method only exists for inheritance purposes as it initializes parameters that need to be known by every linear code. The class @@ -441,19 +437,19 @@ def _an_element_(self): """ return self.gens()[0] - def automorphism_group_gens(self, equivalence="semilinear"): + def automorphism_group_gens(self, equivalence='semilinear'): r""" Return generators of the automorphism group of ``self``. INPUT: - - ``equivalence`` (optional) -- which defines the acting group, either + - ``equivalence`` -- (optional) defines the acting group, either - * ``"permutational"`` + * ``'permutational'`` - * ``"linear"`` + * ``'linear'`` - * ``"semilinear"`` + * ``'semilinear'`` OUTPUT: @@ -486,7 +482,7 @@ def automorphism_group_gens(self, equivalence="semilinear"): Ring endomorphism of Finite Field in z of size 2^2 Defn: z |--> z)], 362880) - sage: C.automorphism_group_gens(equivalence="linear") + sage: C.automorphism_group_gens(equivalence='linear') ([((z, 1, z + 1, z + 1, 1, z + 1, z, 1, z + 1, z + 1, 1, z, 1, z + 1, z, 1, z, 1, z + 1, 1, 1); (1,12,11,10,6,8,9,20,13,21,5,14,3,16,17,19,7,4,2,15,18), @@ -503,7 +499,7 @@ def automorphism_group_gens(self, equivalence="semilinear"): Ring endomorphism of Finite Field in z of size 2^2 Defn: z |--> z)], 181440) - sage: C.automorphism_group_gens(equivalence="permutational") + sage: C.automorphism_group_gens(equivalence='permutational') ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), Ring endomorphism of Finite Field in z of size 2^2 @@ -579,7 +575,7 @@ def assmus_mattson_designs(self, t, mode=None): `C=C^*` in this case, so this info is extraneous). The test fails to produce 6-designs (ie, the hypotheses of the theorem fail to hold, not that the 6-designs definitely don't exist). The command - ``assmus_mattson_designs(C,5,mode="verbose")`` returns the same value + ``assmus_mattson_designs(C,5,mode='verbose')`` returns the same value but prints out more detailed information. The second example below illustrates the blocks of the 5-(24, 8, 1) @@ -636,10 +632,10 @@ def assmus_mattson_designs(self, t, mode=None): # S. Pancratz, 19 Jan 2010: In the doctests below, I removed the example # ``C.binomial_moment(3)``, which was also marked as ``#long``. This way, # we shorten the doctests time while still maintaining a zero and a - # non-zero example. + # nonzero example. def binomial_moment(self, i): r""" - Return the i-th binomial moment of the `[n,k,d]_q`-code `C`: + Return the `i`-th binomial moment of the `[n,k,d]_q`-code `C`: .. MATH:: @@ -734,7 +730,7 @@ def _canonize(self, equivalence): from sage.coding.codecan.autgroup_can_label import LinearCodeAutGroupCanLabel return LinearCodeAutGroupCanLabel(self, algorithm_type=equivalence) - def canonical_representative(self, equivalence="semilinear"): + def canonical_representative(self, equivalence='semilinear'): r""" Compute a canonical orbit representative under the action of the semimonomial transformation group. @@ -747,13 +743,13 @@ def canonical_representative(self, equivalence="semilinear"): INPUT: - - ``equivalence`` (optional) -- which defines the acting group, either + - ``equivalence`` -- (optional) defines the acting group, either - * ``"permutational"`` + * ``'permutational'`` - * ``"linear"`` + * ``'linear'`` - * ``"semilinear"`` + * ``'semilinear'`` OUTPUT: @@ -927,8 +923,8 @@ def covering_radius(self): is limited to computing with fields of size at most 256 """ from sage.libs.gap.libgap import libgap - GapPackage("guava", spkg="gap_packages").require() - libgap.LoadPackage("guava") + GapPackage('guava', spkg='gap_packages').require() + libgap.LoadPackage('guava') F = self.base_ring() if F.cardinality() > 256: raise NotImplementedError("the GAP algorithm that Sage is using " @@ -1043,7 +1039,7 @@ def direct_sum(self, other): def juxtapose(self, other): """ - Juxtaposition of ``self`` and ``other`` + Juxtaposition of ``self`` and ``other``. The two codes must have equal dimension. @@ -1114,7 +1110,6 @@ def product_code(self, other): True sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() # needs sage.libs.gap True - """ G1 = self.generator_matrix() G2 = other.generator_matrix() @@ -1286,7 +1281,7 @@ def is_permutation_equivalent(self,other,algorithm=None): [7, 4] Hamming Code over GF(2) sage: C1.is_permutation_equivalent(C2) True - sage: C1.is_permutation_equivalent(C2, algorithm="verbose") # needs sage.groups + sage: C1.is_permutation_equivalent(C2, algorithm='verbose') # needs sage.groups (True, (3,4)(5,7,6)) sage: C1 = codes.random_linear_code(GF(2), 10, 5) sage: C2 = codes.random_linear_code(GF(3), 10, 5) @@ -1318,7 +1313,7 @@ def is_permutation_equivalent(self,other,algorithm=None): def is_galois_closed(self): r""" - Checks if ``self`` is equal to its Galois closure. + Check if ``self`` is equal to its Galois closure. EXAMPLES:: @@ -1350,22 +1345,20 @@ def minimum_distance(self, algorithm=None): .. NOTE:: - When using GAP, this raises a :class:`NotImplementedError` if + When using GAP, this raises a :exc:`NotImplementedError` if the base field of the code has size greater than 256 due to limitations in GAP. INPUT: - - ``algorithm`` -- (default: ``None``) the name of the algorithm to use - to perform minimum distance computation. ``algorithm`` can be: + - ``algorithm`` -- (default: ``None``) the name of the algorithm to use + to perform minimum distance computation. ``algorithm`` can be: - - ``None``, to use GAP methods (but not Guava) + - ``None``, to use GAP methods (but not Guava) - - ``"Guava"``, to use the optional GAP package Guava + - ``'guava'``, to use the optional GAP package Guava - OUTPUT: - - - Integer, minimum distance of this code + OUTPUT: integer; minimum distance of this code EXAMPLES:: @@ -1378,10 +1371,10 @@ def minimum_distance(self, algorithm=None): If ``algorithm`` is provided, then the minimum distance will be recomputed even if there is a stored value from a previous run.:: - sage: C.minimum_distance(algorithm="gap") # needs sage.libs.gap + sage: C.minimum_distance(algorithm='gap') # needs sage.libs.gap 3 sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages # needs sage.libs.gap - sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava + sage: C.minimum_distance(algorithm='guava') # optional - gap_package_guava ...3 TESTS:: @@ -1401,13 +1394,13 @@ def minimum_distance(self, algorithm=None): NotImplementedError: the GAP algorithm that Sage is using is limited to computing with fields of size at most 256 """ - if algorithm == "guava": - GapPackage("guava", spkg="gap_packages").require() + if algorithm == 'guava': + GapPackage('guava', spkg='gap_packages').require() # If the minimum distance has already been computed or provided by # the user then simply return the stored value. # This is done only if algorithm is None. - if algorithm not in (None, "gap", "guava"): + if algorithm not in (None, 'gap', 'guava'): raise ValueError("The algorithm argument must be one of None, " "'gap' or 'guava'; got '{0}'".format(algorithm)) @@ -1419,9 +1412,9 @@ def minimum_distance(self, algorithm=None): "of size at most 256") G = self.generator_matrix() - if (q == 2 or q == 3) and algorithm == "guava": + if (q == 2 or q == 3) and algorithm == 'guava': from sage.libs.gap.libgap import libgap - libgap.LoadPackage("guava") + libgap.LoadPackage('guava') C = libgap(G).GeneratorMatCode(libgap(F)) d = C.MinimumWeight() return ZZ(d) @@ -1433,10 +1426,10 @@ def _minimum_weight_codeword(self, algorithm=None): INPUT: - - ``algorithm`` -- (default: ``None``) the name of the algorithm to use - to perform minimum weight codeword search. If set to ``None``, - a search using GAP methods will be done. ``algorithm`` can be: - - ``"Guava"``, which will use optional GAP package Guava + - ``algorithm`` -- (default: ``None``) the name of the algorithm to use + to perform minimum weight codeword search. If set to ``None``, + a search using GAP methods will be done. ``algorithm`` can be + ``'guava'``, which will use the optional GAP package Guava. REMARKS: @@ -1472,9 +1465,9 @@ def _minimum_weight_codeword(self, algorithm=None): current_randstate().set_seed_gap() - if algorithm == "guava": - GapPackage("guava", spkg="gap_packages").require() - libgap.LoadPackage("guava") + if algorithm == 'guava': + GapPackage('guava', spkg='gap_packages').require() + libgap.LoadPackage('guava') C = Gmat.GeneratorMatCode(F) cg = C.MinimumDistanceCodeword() c = [cg[j].sage(ring=F) for j in range(n)] @@ -1538,7 +1531,7 @@ def module_composition_factors(self, gp): # M_gap.MTX.CompositionFactors() yet return libgap.eval('MTX.CompositionFactors('+str(M_gap)+')') - def permutation_automorphism_group(self, algorithm="partition"): + def permutation_automorphism_group(self, algorithm='partition'): r""" If `C` is an `[n,k,d]` code over `F`, this function computes the subgroup `Aut(C) \subset S_n` of all permutation automorphisms of `C`. @@ -1552,21 +1545,19 @@ def permutation_automorphism_group(self, algorithm="partition"): INPUT: - - ``algorithm`` -- If ``"gap"`` then GAP's MatrixAutomorphism function + - ``algorithm`` -- if ``'gap'`` then GAP's MatrixAutomorphism function (written by Thomas Breuer) is used. The implementation combines an idea of mine with an improvement suggested by Cary Huffman. If - ``"gap+verbose"`` then code-theoretic data is printed out at - several stages of the computation. If ``"partition"`` then the + ``'gap+verbose'`` then code-theoretic data is printed out at + several stages of the computation. If ``'partition'`` then the (default) partition refinement algorithm of Robert Miller is used. - Finally, if ``"codecan"`` then the partition refinement algorithm + Finally, if ``'codecan'`` then the partition refinement algorithm of Thomas Feulner is used, which also computes a canonical representative of ``self`` (call :meth:`~sage.coding.linear_code.LinearCode.canonical_representative` to access it). - OUTPUT: - - - Permutation automorphism group + OUTPUT: permutation automorphism group EXAMPLES:: @@ -1615,19 +1606,19 @@ def permutation_automorphism_group(self, algorithm="partition"): 9999360 sage: C = codes.HammingCode(GF(3), 2); C [4, 2] Hamming Code over GF(3) - sage: C.permutation_automorphism_group(algorithm="partition") + sage: C.permutation_automorphism_group(algorithm='partition') Permutation Group with generators [(1,3,4)] sage: C = codes.HammingCode(GF(4,"z"), 2); C [5, 3] Hamming Code over GF(4) - sage: G = C.permutation_automorphism_group(algorithm="partition"); G + sage: G = C.permutation_automorphism_group(algorithm='partition'); G Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] - sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time + sage: GG = C.permutation_automorphism_group(algorithm='codecan') # long time sage: GG == G # long time True - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_package_guava + sage: C.permutation_automorphism_group(algorithm='gap') # optional - gap_package_guava Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] sage: C = codes.GolayCode(GF(3), True) - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_package_guava + sage: C.permutation_automorphism_group(algorithm='gap') # optional - gap_package_guava Permutation Group with generators [(5,7)(6,11)(8,9)(10,12), (4,6,11)(5,8,12)(7,10,9), (3,4)(6,8)(9,11)(10,12), (2,3)(6,11)(8,12)(9,10), (1,2)(5,10)(7,12)(8,9)] @@ -1640,7 +1631,7 @@ def permutation_automorphism_group(self, algorithm="partition"): Using the 132 codewords of weight 5 Supergroup size: 39916800 in addition to the output of - ``C.permutation_automorphism_group(algorithm="gap")``. + ``C.permutation_automorphism_group(algorithm='gap')``. """ F = self.base_ring() q = F.order() @@ -1648,7 +1639,7 @@ def permutation_automorphism_group(self, algorithm="partition"): n = len(G.columns()) if "gap" in algorithm: from sage.libs.gap.libgap import libgap - GapPackage("guava", spkg="gap_packages").require() + GapPackage('guava', spkg='gap_packages').require() libgap.LoadPackage('guava') wts = self.weight_distribution() # bottleneck 1 nonzerowts = [i for i in range(len(wts)) if wts[i] != 0] @@ -1725,11 +1716,9 @@ def punctured(self, L): INPUT: - - ``L`` -- List of positions to puncture + - ``L`` -- list of positions to puncture - OUTPUT: - - - an instance of :class:`sage.coding.punctured_code` + OUTPUT: an instance of :class:`sage.coding.punctured_code` EXAMPLES:: @@ -1742,11 +1731,11 @@ def punctured(self, L): def _punctured_form(self, points): r""" - Return a representation of self as a :class:`LinearCode` punctured in ``points``. + Return a representation of ``self`` as a :class:`LinearCode` punctured in ``points``. INPUT: - - ``points`` -- a set of positions where to puncture ``self`` + - ``points`` -- set of positions where to puncture ``self`` EXAMPLES:: @@ -1790,11 +1779,9 @@ def shortened(self, L): INPUT: - - ``L`` -- Subset of `\{1,...,n\}`, where `n` is the length of this code - - OUTPUT: + - ``L`` -- subset of `\{1,...,n\}`, where `n` is the length of this code - - Linear code, the shortened code described above + OUTPUT: linear code, the shortened code described above EXAMPLES:: @@ -1816,15 +1803,13 @@ def weight_distribution(self, algorithm=None): INPUT: - - ``algorithm`` -- (default: ``None``) If set to ``"gap"``, - call GAP. If set to ``"leon"``, call the option GAP package GUAVA and + - ``algorithm`` -- (default: ``None``) if set to ``'gap'``, + call GAP. If set to ``'leon'``, call the option GAP package GUAVA and call a function therein by Jeffrey Leon (see warning below). If set to - ``"binary"``, use an algorithm optimized for binary codes. The default - is to use ``"binary"`` for binary codes and ``"gap"`` otherwise. + ``'binary'``, use an algorithm optimized for binary codes. The default + is to use ``'binary'`` for binary codes and ``'gap'`` otherwise. - OUTPUT: - - - A list of non-negative integers: the weight distribution. + OUTPUT: list of nonnegative integers; the weight distribution .. WARNING:: @@ -1848,27 +1833,26 @@ def weight_distribution(self, algorithm=None): [1, 0, 0, 30, 15, 18] sage: C = codes.HammingCode(GF(2), 3); C [7, 4] Hamming Code over GF(2) - sage: C.weight_distribution(algorithm="leon") # optional - gap_package_guava + sage: C.weight_distribution(algorithm='leon') # optional - gap_package_guava [1, 0, 0, 7, 7, 0, 0, 1] - sage: C.weight_distribution(algorithm="gap") # needs sage.libs.gap + sage: C.weight_distribution(algorithm='gap') # needs sage.libs.gap [1, 0, 0, 7, 7, 0, 0, 1] - sage: C.weight_distribution(algorithm="binary") + sage: C.weight_distribution(algorithm='binary') [1, 0, 0, 7, 7, 0, 0, 1] sage: # optional - gap_package_guava sage: C = codes.HammingCode(GF(3), 3); C [13, 10] Hamming Code over GF(3) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") + sage: C.weight_distribution() == C.weight_distribution(algorithm='leon') True sage: C = codes.HammingCode(GF(5), 2); C [6, 4] Hamming Code over GF(5) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") + sage: C.weight_distribution() == C.weight_distribution(algorithm='leon') True sage: C = codes.HammingCode(GF(7), 2); C [8, 6] Hamming Code over GF(7) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") + sage: C.weight_distribution() == C.weight_distribution(algorithm='leon') True - """ if algorithm is None: if self.base_ring().order() == 2: @@ -1893,7 +1877,7 @@ def weight_distribution(self, algorithm=None): # The GAP command DirectoriesPackageLibrary tells the location of the latest # version of the Guava libraries, so gives us the location of the Guava binaries too. from sage.libs.gap.libgap import libgap - guava_bin_dir = libgap.DirectoriesPackagePrograms("guava")[0].Filename("").sage() + guava_bin_dir = libgap.DirectoriesPackagePrograms('guava')[0].Filename("").sage() input = _dump_code_in_leon_format(self) + "::code" lines = subprocess.check_output([os.path.join(guava_bin_dir, 'wtdist'), input]) # to use the already present output parser @@ -1916,9 +1900,7 @@ def support(self): Return the set of indices `j` where `A_j` is nonzero, where `A_j` is the number of codewords in ``self`` of Hamming weight `j`. - OUTPUT: - - - List of integers + OUTPUT: list of integers EXAMPLES:: @@ -1943,25 +1925,23 @@ def weight_enumerator(self, names=None, bivariate=True): INPUT: - - ``names`` -- (default: ``"xy"``) The names of the variables in the + - ``names`` -- (default: ``'xy'``) the names of the variables in the homogeneous polynomial. Can be given as a single string of length 2, or a single string with a comma, or as a tuple or list of two strings. - - ``bivariate`` -- (default: ``True``) Whether to return a bivariate, - homogeneous polynomial or just a univariate polynomial. If set to - ``False``, then ``names`` will be interpreted as a single variable - name and default to ``"x"``. - - OUTPUT: + - ``bivariate`` -- boolean (default: ``True``); whether to return a + bivariate, homogeneous polynomial or just a univariate polynomial. If + set to ``False``, then ``names`` will be interpreted as a single + variable name and default to ``'x'``. - - The weight enumerator polynomial over `\ZZ`. + OUTPUT: the weight enumerator polynomial over `\ZZ` EXAMPLES:: sage: C = codes.HammingCode(GF(2), 3) sage: C.weight_enumerator() x^7 + 7*x^4*y^3 + 7*x^3*y^4 + y^7 - sage: C.weight_enumerator(names="st") + sage: C.weight_enumerator(names='st') s^7 + 7*s^4*t^3 + 7*s^3*t^4 + t^7 sage: C.weight_enumerator(names="var1, var2") var1^7 + 7*var1^4*var2^3 + 7*var1^3*var2^4 + var2^7 @@ -1992,7 +1972,7 @@ def weight_enumerator(self, names=None, bivariate=True): x, = R.gens() return sum(spec[i]*x**i for i in range(n+1)) - def zeta_polynomial(self, name="T"): + def zeta_polynomial(self, name='T'): r""" Return the Duursma zeta polynomial of this code. @@ -2001,11 +1981,9 @@ def zeta_polynomial(self, name="T"): INPUT: - - ``name`` -- String, variable name (default: ``"T"``) + - ``name`` -- string (default: ``'T'``); variable name - OUTPUT: - - - Polynomial over `\QQ` + OUTPUT: polynomial over `\QQ` EXAMPLES:: @@ -2063,13 +2041,13 @@ def zeta_polynomial(self, name="T"): P = sum([P_coeffs[i]*T**i for i in range(r+1)]) return RT(P) / RT(P)(1) - def zeta_function(self, name="T"): + def zeta_function(self, name='T'): r""" Return the Duursma zeta function of the code. INPUT: - - ``name`` -- String, variable name (default: ``"T"``) + - ``name`` -- string (default: ``'T'``); variable name OUTPUT: @@ -2223,7 +2201,7 @@ class LinearCode(AbstractLinearCode): - ``generator`` -- a generator matrix over a finite field (``G`` can be defined over a finite ring but the matrices over that ring must have - certain attributes, such as ``rank``); or a code over a finite field + certain attributes, such as ``rank``) or a code over a finite field - ``d`` -- (default: ``None``) the minimum distance of the code @@ -2344,7 +2322,7 @@ def __init__(self, generator, d=None): sage: C = LinearCode(G) Traceback (most recent call last): ... - ValueError: this linear code contains no non-zero vector + ValueError: this linear code contains no nonzero vector """ base_ring = generator.base_ring() @@ -2362,7 +2340,7 @@ def __init__(self, generator, d=None): from sage.matrix.constructor import matrix generator = matrix(base_ring, basis) if generator.nrows() == 0: - raise ValueError("this linear code contains no non-zero vector") + raise ValueError("this linear code contains no nonzero vector") except AttributeError: # Assume input is an AbstractLinearCode, extract its generator matrix generator = generator.generator_matrix() @@ -2422,7 +2400,7 @@ def generator_matrix(self, encoder_name=None, **kwargs): will be returned if default value is kept. - ``kwargs`` -- all additional arguments are forwarded to the construction of the - encoder that is used. + encoder that is used EXAMPLES:: @@ -2451,7 +2429,7 @@ class LinearCodeGeneratorMatrixEncoder(Encoder): INPUT: - - ``code`` -- The associated :class:`LinearCode` of this encoder. + - ``code`` -- the associated :class:`LinearCode` of this encoder """ def __init__(self, code): @@ -2468,7 +2446,7 @@ def __init__(self, code): def __eq__(self, other): r""" - Tests equality between LinearCodeGeneratorMatrixEncoder objects. + Test equality between LinearCodeGeneratorMatrixEncoder objects. EXAMPLES:: @@ -2535,7 +2513,7 @@ def generator_matrix(self): class LinearCodeSyndromeDecoder(Decoder): r""" - Constructs a decoder for Linear Codes based on syndrome lookup table. + Construct a decoder for Linear Codes based on syndrome lookup table. The decoding algorithm works as follows: @@ -2566,7 +2544,7 @@ class LinearCodeSyndromeDecoder(Decoder): INPUT: - - ``code`` -- A code associated to this decoder + - ``code`` -- a code associated to this decoder - ``maximum_error_weight`` -- (default: ``None``) the maximum number of errors to look for when building the table. An error is raised if it is @@ -2703,7 +2681,7 @@ def __init__(self, code, maximum_error_weight=None): def __eq__(self, other): r""" - Tests equality between LinearCodeSyndromeDecoder objects. + Test equality between LinearCodeSyndromeDecoder objects. EXAMPLES:: @@ -2719,7 +2697,7 @@ def __eq__(self, other): def __hash__(self): """ - Return the hash of self. + Return the hash of ``self``. EXAMPLES:: @@ -2762,7 +2740,7 @@ def _latex_(self): @cached_method def _build_lookup_table(self): r""" - Builds lookup table for all possible error patterns of weight up to :meth:`maximum_error_weight`. + Build lookup table for all possible error patterns of weight up to :meth:`maximum_error_weight`. EXAMPLES:: @@ -2889,9 +2867,7 @@ def decode_to_code(self, r): - ``r`` -- a codeword of ``self`` - OUTPUT: - - - a vector of ``self``'s message space + OUTPUT: a vector of ``self``'s message space EXAMPLES:: @@ -2984,7 +2960,7 @@ class LinearCodeNearestNeighborDecoder(Decoder): INPUT: - - ``code`` -- A code associated to this decoder + - ``code`` -- a code associated to this decoder """ def __init__(self, code): @@ -3001,7 +2977,7 @@ def __init__(self, code): def __eq__(self, other): r""" - Tests equality between LinearCodeNearestNeighborDecoder objects. + Test equality between LinearCodeNearestNeighborDecoder objects. EXAMPLES:: @@ -3050,9 +3026,7 @@ def decode_to_code(self, r): - ``r`` -- a codeword of ``self`` - OUTPUT: - - - a vector of ``self``'s message space + OUTPUT: a vector of ``self``'s message space EXAMPLES:: diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index bd7727b7794..49c30a415c8 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -140,7 +140,7 @@ class AbstractLinearCodeNoMetric(AbstractCode, Module): def __init__(self, base_field, length, default_encoder_name, default_decoder_name, metric='Hamming'): """ - Initializes mandatory parameters that any linear code shares. + Initialize mandatory parameters that any linear code shares. This method only exists for inheritance purposes as it initializes parameters that need to be known by every linear code. The class @@ -231,7 +231,7 @@ def generator_matrix(self, encoder_name=None, **kwargs): will be used if default value is kept. - ``kwargs`` -- all additional arguments are forwarded to the construction of the - encoder that is used. + encoder that is used EXAMPLES:: @@ -246,7 +246,7 @@ def generator_matrix(self, encoder_name=None, **kwargs): def __eq__(self, other): r""" - Tests equality between two linear codes. + Test equality between two linear codes. EXAMPLES:: @@ -282,9 +282,10 @@ def __eq__(self, other): def __ne__(self, other): r""" - Tests inequality of ``self`` and ``other``. + Test inequality of ``self`` and ``other``. - This is a generic implementation, which returns the inverse of ``__eq__`` for self. + This is a generic implementation, which returns the inverse of + ``__eq__`` for ``self``. EXAMPLES:: @@ -390,9 +391,7 @@ def basis(self): r""" Return a basis of ``self``. - OUTPUT: - - - ``Sequence`` -- an immutable sequence whose universe is ambient space of ``self``. + OUTPUT: ``Sequence`` -- an immutable sequence whose universe is ambient space of ``self`` EXAMPLES:: @@ -463,9 +462,7 @@ def syndrome(self, r): - ``r`` -- a vector of the same length as ``self`` - OUTPUT: - - - a column vector + OUTPUT: a column vector EXAMPLES:: @@ -497,7 +494,8 @@ def syndrome(self, r): def __contains__(self, v): r""" - Return True if `v` can be coerced into ``self``. Otherwise, returns False. + Return ``True`` if `v` can be coerced into ``self``. + Otherwise, return ``False``. EXAMPLES:: @@ -560,14 +558,12 @@ def standard_form(self, return_permutation=True): INPUT: - - ``return_permutation`` -- (default: ``True``) if ``True``, the column - permutation which brings ``self`` into the returned code is also - returned. + - ``return_permutation`` -- boolean (default: ``True``); if ``True``, + the column permutation which brings ``self`` into the returned code + is also returned - OUTPUT: - - - A :class:`LinearCode` whose :meth:`systematic_generator_matrix` is - guaranteed to be of the form `[I \vert A]`. + OUTPUT: a :class:`LinearCode` whose :meth:`systematic_generator_matrix` + is guaranteed to be of the form `[I \vert A]`. EXAMPLES:: @@ -656,9 +652,7 @@ def information_set(self): is called an information set if the corresponding columns form a square matrix of full rank. - OUTPUT: - - - Information set of a systematic generator matrix of the code. + OUTPUT: information set of a systematic generator matrix of the code EXAMPLES:: @@ -682,10 +676,7 @@ def is_information_set(self, positions): - A list of positions, i.e. integers in the range 0 to `n-1` where `n` is the length of ``self``. - OUTPUT: - - - A boolean indicating whether the positions form an information set. - + OUTPUT: boolean indicating whether the positions form an information set EXAMPLES:: @@ -722,7 +713,6 @@ def __iter__(self): sage: L = list(C) sage: L[10].is_immutable() True - """ from sage.modules.finite_submodule_iter import \ FiniteFieldsubspace_iterator @@ -755,7 +745,7 @@ def __getitem__(self, i): ``[i*a^0 * G[0] + a^0*G[1] for i in range(p)]``, and so on. - Hence the `i`-th element can be obtained by the p-adic expansion + Hence the `i`-th element can be obtained by the `p`-adic expansion of `i` as ``[i_0, i_1, ...,i_{m-1}, i_m, i_{m+1}, ..., i_{km-1}].`` The element that is generated is: @@ -800,7 +790,6 @@ def __getitem__(self, i): sage: C[0].is_immutable() True - """ # IMPORTANT: If the __iter__() function implementation is changed # then the implementation here must also be changed so that @@ -1050,14 +1039,14 @@ class LinearCodeSystematicEncoder(Encoder): INPUT: - - ``code`` -- The associated code of this encoder. + - ``code`` -- the associated code of this encoder - ``systematic_positions`` -- (default: ``None``) the positions in codewords that should correspond to the message symbols. A list of `k` distinct integers in the range 0 to `n-1` where `n` is the length of the code and `k` its - dimension. The 0th symbol of a message will then be at position + dimension. The `0`-th symbol of a message will then be at position ``systematic_positions[0]``, the 1st index at position - ``systematic_positions[1]``, etc. A :class:`ValueError` is raised at + ``systematic_positions[1]``, etc. A :exc:`ValueError` is raised at construction time if the supplied indices do not form an information set. EXAMPLES: @@ -1153,7 +1142,7 @@ def __init__(self, code, systematic_positions=None): def __eq__(self, other): r""" - Tests equality between LinearCodeSystematicEncoder objects. + Test equality between LinearCodeSystematicEncoder objects. EXAMPLES:: @@ -1285,7 +1274,7 @@ def generator_matrix(self): def systematic_permutation(self): r""" - Return a permutation which would take the systematic positions into [0,..,k-1] + Return a permutation which would take the systematic positions into [0,..,k-1]. EXAMPLES:: diff --git a/src/sage/coding/linear_rank_metric.py b/src/sage/coding/linear_rank_metric.py index 2c7154c9e42..97a37e96c9b 100644 --- a/src/sage/coding/linear_rank_metric.py +++ b/src/sage/coding/linear_rank_metric.py @@ -142,8 +142,8 @@ def to_matrix_representation(v, sub_field=None, basis=None): - ``v`` -- a vector over some field `\GF{q^m}` - - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not - specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`; if not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}` - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let @@ -176,6 +176,7 @@ def to_matrix_representation(v, sub_field=None, basis=None): extension, to_big_field, from_big_field = base_field.vector_space(sub_field, basis, map=True) return matrix(sub_field, m, n, lambda i, j: from_big_field(v[j])[i]) + def from_matrix_representation(w, base_field=None, basis=None): r""" Return a vector representation of a matrix ``w`` over ``base_field`` in terms @@ -235,8 +236,8 @@ def rank_weight(c, sub_field=None, basis=None): - ``c`` -- a vector over some field `\GF{q^m}`; or a matrix over `\GF{q}` - - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not - specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`; if not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}` - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let @@ -255,6 +256,7 @@ def rank_weight(c, sub_field=None, basis=None): c = to_matrix_representation(c, sub_field, basis) return c.rank() + def rank_distance(a, b, sub_field=None, basis=None): r""" Return the rank of ``a`` - ``b`` as a matrix over ``sub_field``. @@ -272,8 +274,8 @@ def rank_distance(a, b, sub_field=None, basis=None): - ``b`` -- a vector over some field `\GF{q^m}` - - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not - specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`; if not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}` - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let @@ -706,7 +708,7 @@ def __init__(self, generator, sub_field=None, basis=None): from sage.matrix.constructor import matrix generator = matrix(base_field, gen_basis) if generator.nrows() == 0: - raise ValueError("this linear code contains no non-zero vector") + raise ValueError("this linear code contains no nonzero vector") except AttributeError: # Assume input is an AbstractLinearRankMetricCode, extract its generator matrix generator = generator.generator_matrix() @@ -759,7 +761,7 @@ def generator_matrix(self, encoder_name=None, **kwargs): will be returned if default value is kept. - ``kwargs`` -- all additional arguments are forwarded to the construction of the - encoder that is used. + encoder that is used EXAMPLES:: @@ -790,7 +792,7 @@ def __init__(self, code): INPUT: - - ``code`` -- A code associated to this decoder + - ``code`` -- a code associated to this decoder EXAMPLES:: @@ -854,9 +856,7 @@ def decode_to_code(self, r): - ``r`` -- a codeword of ``self`` - OUTPUT: - - - a vector of ``self``'s message space + OUTPUT: a vector of ``self``'s message space EXAMPLES:: diff --git a/src/sage/coding/meson.build b/src/sage/coding/meson.build new file mode 100644 index 00000000000..65b2e0d8eb1 --- /dev/null +++ b/src/sage/coding/meson.build @@ -0,0 +1,59 @@ +py.install_sources( + 'abstract_code.py', + 'ag_code.py', + 'all.py', + 'bch_code.py', + 'binary_code.pxd', + 'bounds_catalog.py', + 'channel.py', + 'channels_catalog.py', + 'code_bounds.py', + 'code_constructions.py', + 'codes_catalog.py', + 'cyclic_code.py', + 'databases.py', + 'decoder.py', + 'decoders_catalog.py', + 'delsarte_bounds.py', + 'encoder.py', + 'encoders_catalog.py', + 'extended_code.py', + 'gabidulin_code.py', + 'golay_code.py', + 'goppa_code.py', + 'grs_code.py', + 'guava.py', + 'hamming_code.py', + 'information_set_decoder.py', + 'linear_code.py', + 'linear_code_no_metric.py', + 'linear_rank_metric.py', + 'parity_check_code.py', + 'punctured_code.py', + 'reed_muller_code.py', + 'self_dual_codes.py', + 'subfield_subcode.py', + 'two_weight_db.py', + subdir: 'sage/coding', +) + +extension_data = { + 'ag_code_decoders' : files('ag_code_decoders.pyx'), + 'binary_code' : files('binary_code.pyx'), + 'kasami_codes' : files('kasami_codes.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/coding', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +subdir('codecan') +install_subdir('guruswami_sudan', install_dir: sage_install_dir / 'coding') +install_subdir('source_coding', install_dir: sage_install_dir / 'coding') diff --git a/src/sage/coding/parity_check_code.py b/src/sage/coding/parity_check_code.py index 73e7c9b7816..589c1c6f391 100644 --- a/src/sage/coding/parity_check_code.py +++ b/src/sage/coding/parity_check_code.py @@ -40,9 +40,9 @@ class ParityCheckCode(AbstractLinearCode): INPUT: - - ``base_field`` -- the base field over which ``self`` is defined. + - ``base_field`` -- the base field over which ``self`` is defined - - ``dimension`` -- the dimension of ``self``. + - ``dimension`` -- the dimension of ``self`` EXAMPLES:: @@ -61,9 +61,9 @@ def __init__(self, base_field=GF(2), dimension=7): INPUT: - ``base_field`` -- the base field over which ``self`` is defined - or GF(2) if no base_field. + or GF(2) if no base_field - - ``dimension`` -- the dimension of ``self`` or 7 if no dimension. + - ``dimension`` -- the dimension of ``self`` or 7 if no dimension EXAMPLES:: @@ -148,7 +148,7 @@ class ParityCheckCodeGeneratorMatrixEncoder(LinearCodeGeneratorMatrixEncoder): INPUT: - - ``code`` -- the associated code of this encoder. + - ``code`` -- the associated code of this encoder EXAMPLES:: @@ -212,7 +212,7 @@ class ParityCheckCodeStraightforwardEncoder(Encoder): INPUT: - - ``code`` -- the associated code of this encoder. + - ``code`` -- the associated code of this encoder EXAMPLES:: @@ -290,12 +290,10 @@ def encode(self, message): INPUT: - - ``message`` -- A ``self.code().dimension()``-vector from the message - space of ``self``. + - ``message`` -- a ``self.code().dimension()``-vector from the message + space of ``self`` - OUTPUT: - - - A codeword in associated code of ``self``. + OUTPUT: a codeword in associated code of ``self`` EXAMPLES:: @@ -318,13 +316,11 @@ def unencode_nocheck(self, word): INPUT: - - ``word`` -- A ``self.code().length()``-vector from the ambiant space - of ``self``. - - OUTPUT: + - ``word`` -- a ``self.code().length()``-vector from the ambiant space + of ``self`` - - A vector corresponding to the ``self.code().dimension()``-first - symbols in ``word``. + OUTPUT: a vector corresponding to the ``self.code().dimension()``-first + symbols in ``word`` EXAMPLES:: diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index e7658e18f34..c8be67993f8 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -27,6 +27,7 @@ from sage.rings.finite_rings.finite_field_constructor import GF from copy import copy + def _puncture(v, points): r""" Return v punctured as the positions listed in ``points``. @@ -35,7 +36,7 @@ def _puncture(v, points): - ``v`` -- a vector or a list of vectors - - ``points`` -- a set of integers, or an integer + - ``points`` -- set of integers, or an integer EXAMPLES:: @@ -58,6 +59,7 @@ def _puncture(v, points): new_v = [v[i] for i in range(len(v)) if i not in points] return S(new_v) + def _insert_punctured_positions(l, punctured_points, value=None): r""" Return ``l`` with ``value`` inserted in the corresponding @@ -65,9 +67,9 @@ def _insert_punctured_positions(l, punctured_points, value=None): INPUT: - - ``l`` -- a list + - ``l`` -- list - - ``punctured_points`` -- a set of integers + - ``punctured_points`` -- set of integers - ``value`` -- (default: ``None``) an element to insert in every position given in``punctured_points``. If it is let to ``None``, a random value @@ -98,11 +100,12 @@ class PuncturedCode(AbstractLinearCode): r""" Representation of a punctured code. - - ``C`` -- A linear code + - ``C`` -- a linear code - - ``positions`` -- the positions where ``C`` will be punctured. It can be either an integer - if one need to puncture only one position, a list or a set of positions to puncture. - If the same position is passed several times, it will be considered only once. + - ``positions`` -- the positions where ``C`` will be punctured. It can be + either an integer if one need to puncture only one position, a list or a + set of positions to puncture. If the same position is passed several + times, it will be considered only once. EXAMPLES:: @@ -151,7 +154,7 @@ def __init__(self, C, positions): def __eq__(self, other): r""" - Tests equality between two Punctured codes. + Test equality between two Punctured codes. EXAMPLES:: @@ -246,7 +249,7 @@ def random_element(self, *args, **kwds): INPUT: - ``agrs``, ``kwds`` -- extra positional arguments passed to - :meth:`sage.modules.free_module.random_element`. + :meth:`sage.modules.free_module.random_element` EXAMPLES:: @@ -262,23 +265,22 @@ def random_element(self, *args, **kwds): def encode(self, m, original_encode=False, encoder_name=None, **kwargs): r""" - Transforms an element of the message space into an element of the code. + Transform an element of the message space into an element of the code. INPUT: - - ``m`` -- a vector of the message space of the code. + - ``m`` -- a vector of the message space of the code - - ``original_encode`` -- (default: ``False``) if this is set to ``True``, - ``m`` will be encoded using an Encoder of ``self``'s :meth:`original_code`. - This allow to avoid the computation of a generator matrix for ``self``. + - ``original_encode`` -- boolean (default: ``False``); if this is set + to ``True``, ``m`` will be encoded using an Encoder of ``self``'s + :meth:`original_code`. This allow to avoid the computation of a + generator matrix for ``self``. - - ``encoder_name`` -- (default: ``None``) Name of the encoder which will be used + - ``encoder_name`` -- (default: ``None``) name of the encoder which will be used to encode ``word``. The default encoder of ``self`` will be used if - default value is kept + default value is kept. - OUTPUT: - - - an element of ``self`` + OUTPUT: an element of ``self`` EXAMPLES:: @@ -346,7 +348,7 @@ class PuncturedCodePuncturedMatrixEncoder(Encoder): INPUT: - - ``code`` -- The associated code of this encoder. + - ``code`` -- the associated code of this encoder EXAMPLES:: @@ -437,7 +439,7 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): INPUT: - - ``code`` -- The associated code of this encoder + - ``code`` -- the associated code of this encoder - ``strategy`` -- (default: ``None``) the strategy used to decode. The available strategies are: @@ -480,7 +482,7 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) sage: Cp = codes.PuncturedCode(C, 3) - sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy="try-all") + sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy='try-all') sage: "error-erasure" in D.decoder_type() False @@ -491,7 +493,7 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): sage: Cp = codes.PuncturedCode(C, 3) sage: Dor = C.decoder("Gao") sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, original_decoder=Dor, - ....: strategy="error-erasure") + ....: strategy='error-erasure') sage: D.original_decoder() == Dor True """ @@ -579,7 +581,6 @@ def _repr_(self): sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp) sage: D Decoder of Puncturing of [15, 7, 9] Reed-Solomon Code over GF(16) on position(s) [3] through Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16) - """ return "Decoder of %s through %s" % (self.code(), self.original_decoder()) diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 6e35d530c39..64258f48927 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -79,13 +79,13 @@ def _multivariate_polynomial_interpolation(evaluation, order, polynomial_ring): INPUT: - - ``evaluation`` -- A vector or a list of evaluation of the polynomial at all the points. + - ``evaluation`` -- a vector or a list of evaluation of the polynomial at all the points - - ``num_of_var`` -- The number of variables used in the polynomial to interpolate + - ``num_of_var`` -- the number of variables used in the polynomial to interpolate - - ``order`` -- The degree of the polynomial to interpolate + - ``order`` -- the degree of the polynomial to interpolate - - ``polynomial_ring`` -- The Polynomial Ring the polynomial in question is from + - ``polynomial_ring`` -- the Polynomial Ring the polynomial in question is from EXAMPLES:: @@ -143,12 +143,12 @@ def ReedMullerCode(base_field, order, num_of_var): INPUT: - - ``base_field`` -- The finite field `F` over which the code is built. + - ``base_field`` -- the finite field `F` over which the code is built - - ``order`` -- The order of the Reed-Muller Code, which is the maximum - degree of the polynomial to be used in the code. + - ``order`` -- the order of the Reed-Muller Code, which is the maximum + degree of the polynomial to be used in the code - - ``num_of_var`` -- The number of variables used in polynomial. + - ``num_of_var`` -- the number of variables used in polynomial .. WARNING:: @@ -205,12 +205,12 @@ class directly, as :meth:`ReedMullerCode` creates either a binary or a INPUT: - - ``base_field`` -- A finite field, which is the base field of the code. + - ``base_field`` -- a finite field, which is the base field of the code - - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree - of the polynomial to be used in the code. + - ``order`` -- the order of the Reed-Muller Code, i.e., the maximum degree + of the polynomial to be used in the code - - ``num_of_var`` -- The number of variables used in polynomial. + - ``num_of_var`` -- the number of variables used in polynomial .. WARNING:: @@ -354,7 +354,7 @@ def _latex_(self): def __eq__(self, other): r""" - Tests equality between Reed-Muller Code objects. + Test equality between Reed-Muller Code objects. EXAMPLES:: @@ -389,10 +389,10 @@ class directly, as :meth:`ReedMullerCode` creates either a binary or a INPUT: - - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree - of the polynomial to be used in the code. + - ``order`` -- the order of the Reed-Muller Code, i.e., the maximum degree + of the polynomial to be used in the code - - ``num_of_var`` -- The number of variables used in the polynomial. + - ``num_of_var`` -- the number of variables used in the polynomial EXAMPLES: @@ -508,7 +508,7 @@ def _latex_(self): def __eq__(self, other): r""" - Tests equality between Reed-Muller Code objects. + Test equality between Reed-Muller Code objects. EXAMPLES:: @@ -548,7 +548,7 @@ class ReedMullerVectorEncoder(Encoder): INPUT: - - ``code`` -- The associated code of this encoder. + - ``code`` -- the associated code of this encoder EXAMPLES:: @@ -623,7 +623,7 @@ def _latex_(self): def __eq__(self, other): r""" - Tests equality between ReedMullerVectorEncoder objects. + Test equality between ReedMullerVectorEncoder objects. EXAMPLES:: @@ -642,7 +642,7 @@ def __eq__(self, other): @cached_method def generator_matrix(self): r""" - Return a generator matrix of ``self`` + Return a generator matrix of ``self``. EXAMPLES:: @@ -717,11 +717,11 @@ class ReedMullerPolynomialEncoder(Encoder): INPUT: - - ``code`` -- The associated code of this encoder. + - ``code`` -- the associated code of this encoder - - ``polynomial_ring`` -- (default:``None``) The polynomial ring from which - the message is chosen. If this is set to ``None``, a polynomial ring in - `x` will be built from the code parameters. + - ``polynomial_ring`` -- (default: ``None``) the polynomial ring from which + the message is chosen; if this is set to ``None``, a polynomial ring in + `x` will be built from the code parameters EXAMPLES:: @@ -822,7 +822,7 @@ def _latex_(self): def __eq__(self, other): r""" - Tests equality between ReedMullerVectorEncoder objects. + Test equality between ReedMullerVectorEncoder objects. EXAMPLES:: @@ -840,16 +840,14 @@ def __eq__(self, other): def encode(self, p): r""" - Transforms the polynomial ``p`` into a codeword of :meth:`code`. + Transform the polynomial ``p`` into a codeword of :meth:`code`. INPUT: - - ``p`` -- A polynomial from the message space of ``self`` of degree - less than ``self.code().order()``. + - ``p`` -- a polynomial from the message space of ``self`` of degree + less than ``self.code().order()`` - OUTPUT: - - - A codeword in associated code of ``self`` + OUTPUT: a codeword in associated code of ``self`` EXAMPLES:: @@ -902,7 +900,7 @@ def unencode_nocheck(self, c): INPUT: - - ``c`` -- A codeword of :meth:`code`. + - ``c`` -- a codeword of :meth:`code` OUTPUT: @@ -931,7 +929,6 @@ def unencode_nocheck(self, c): -x0*x1 - x1^2 + x0 + 1 sage: E.encode(p) == c False - """ return _multivariate_polynomial_interpolation( c, @@ -940,7 +937,7 @@ def unencode_nocheck(self, c): def message_space(self): r""" - Return the message space of ``self`` + Return the message space of ``self``. EXAMPLES:: @@ -954,7 +951,7 @@ def message_space(self): def polynomial_ring(self): r""" - Return the polynomial ring associated with ``self`` + Return the polynomial ring associated with ``self``. EXAMPLES:: diff --git a/src/sage/coding/self_dual_codes.py b/src/sage/coding/self_dual_codes.py index f797a6b09d3..10565d9e1a0 100644 --- a/src/sage/coding/self_dual_codes.py +++ b/src/sage/coding/self_dual_codes.py @@ -6,18 +6,18 @@ The main function is ``self_dual_binary_codes``, which is a case-by-case list of entries, each represented by a Python dictionary. -Format of each entry: a Python dictionary with keys ``"order autgp"``, ``"spectrum"``, -``"code"``, ``"Comment"``, ``"Type"``, where +Format of each entry: a Python dictionary with keys ``'order autgp'``, ``'spectrum'``, +``'code'``, ``'Comment'``, ``'Type'``, where -- ``"code"`` -- a sd code `C` of length `n`, dim `n/2`, over `\GF{2}` +- ``'code'`` -- a sd code `C` of length `n`, dim `n/2`, over `\GF{2}` -- ``"order autgp"`` -- order of the permutation automorphism group of `C` +- ``'order autgp'`` -- order of the permutation automorphism group of `C` -- ``"Type"`` -- the type of `C` (which can be ``"I"`` or ``"II"``, in the binary case) +- ``'Type'`` -- the type of `C` (which can be ``'I'`` or ``'II'``, in the binary case) -- ``"spectrum"`` -- the spectrum `[A_0,A_1,...,A_n]` +- ``'spectrum'`` -- the spectrum `[A_0,A_1,...,A_n]` -- ``"Comment"`` -- possibly an empty string. +- ``'Comment'`` -- possibly an empty string Python dictionaries were used since they seemed to be both human-readable and allow others to update the database easiest. @@ -54,10 +54,10 @@ case: For even `m`, let `A_m` denote the `m\times m` matrix over `\GF{2}` -given by adding the all 1's matrix to the identity matrix (in +given by adding the all 1s matrix to the identity matrix (in ``MatrixSpace(GF(2),m,m)`` of course). If `M_1, ..., M_r` are square matrices, let `diag(M_1,M_2,...,M_r)` denote the "block diagonal" -matrix with the matrices `M_i` on the diagonal and 0's elsewhere. Let +matrix with the matrices `M_i` on the diagonal and 0s elsewhere. Let `C(m_1,...,m_r,s)` denote the linear code with generator matrix having block form `G = (I, A)`, where `A = diag(A_{m_1},A_{m_2},...,A_{m_r},I_s)`, for some @@ -141,6 +141,7 @@ def _matA(n): A.append(I+O) return A + def _matId(n): r""" For internal use; returns a list of identity matrices over GF(2) @@ -177,9 +178,10 @@ def _MS2(n): n2 = n.quo_rem(2)[0] return MatrixSpace(_F, n2, n2) + def _I2(n): r""" - Internal function + Internal function. EXAMPLES:: @@ -196,6 +198,7 @@ def _I2(n): """ return _MS2(n).identity_matrix() + @cached_function def _And7(): """ @@ -253,6 +256,7 @@ def _H8(): ############## main functions ############## + def self_dual_binary_codes(n): r""" Return the dictionary of inequivalent binary self dual codes of length `n`. @@ -526,7 +530,7 @@ def self_dual_binary_codes(n): # "(1,5)(2,6)(3,7)(4,8)(10,14)(11,15)(12,16)(13,17)" ] ) spectrum = [1, 0, 1, 0, 28, 0, 28, 0, 198, 0, 198, 0, 28, 0, 28, 0, 1, 0, 1] self_dual_codes_18_3 = {"order autgp":7225344,"code":LinearCode(genmat),"spectrum":spectrum, - "Type":"I","Comment": "Large aut gp. Unique codeword of smallest non-zero wt.\ + "Type":"I","Comment": "Large aut gp. Unique codeword of smallest nonzero wt.\ Same spectrum as '[18,4]' sd code."} # [18,4]: genmat = _I2(n).augment(block_diagonal_matrix([_matA(n)[8],_matId(n)[8]])) @@ -534,7 +538,7 @@ def self_dual_binary_codes(n): # "(5,6)(14,15)", "(4,5)(13,14)", "(3,4)(12,13)", "(2,3)(11,12)", "(1,2)(10,11)" ] ) spectrum = [1, 0, 1, 0, 28, 0, 28, 0, 198, 0, 198, 0, 28, 0, 28, 0, 1, 0, 1] self_dual_codes_18_4 = {"order autgp":10321920,"code":LinearCode(genmat),"spectrum":spectrum, - "Type":"I","Comment": "Huge aut gp. Unique codeword of smallest non-zero wt.\ + "Type":"I","Comment": "Huge aut gp. Unique codeword of smallest nonzero wt.\ Same spectrum as '[18,3]' sd code."} # [18,5]: C = self_dual_binary_codes(n-2)["%s" % (n-2)]["5"]["code"] @@ -558,7 +562,7 @@ def self_dual_binary_codes(n): "(1,4)(2,6)(3,7)(5,17)(8,14)(10,13)(11,15)(12,16)" ] ) spectrum = [1, 0, 1, 0, 12, 0, 76, 0, 166, 0, 166, 0, 76, 0, 12, 0, 1, 0, 1] self_dual_codes_18_6 = {"order autgp":147456,"code":LinearCode(genmat),"spectrum":spectrum, - "Type":"I","Comment": "'Exceptional'. Unique codeword of smallest non-zero wt."} + "Type":"I","Comment": "'Exceptional'. Unique codeword of smallest nonzero wt."} # [18,7] (equiv to H18 in [P]) genmat = _MS(n)([[1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0], [0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], diff --git a/src/sage/coding/source_coding/huffman.py b/src/sage/coding/source_coding/huffman.py index bb25e4cc47d..2755e033632 100644 --- a/src/sage/coding/source_coding/huffman.py +++ b/src/sage/coding/source_coding/huffman.py @@ -45,7 +45,7 @@ def frequency_table(string): INPUT: - - ``string`` -- a string of symbols over some alphabet. + - ``string`` -- string of symbols over some alphabet OUTPUT: @@ -108,7 +108,7 @@ class Huffman(SageObject): - A dictionary that associates to each symbol of an alphabet a numeric value. If we consider the frequency of each alphabetic symbol, then ``source`` is considered as the frequency table of the alphabet with - each numeric (non-negative integer) value being the number of + each numeric (nonnegative integer) value being the number of occurrences of a symbol. The numeric values can also represent weights of the symbols. In that case, the numeric values are not necessarily integers, but can be real numbers. @@ -258,7 +258,7 @@ def __init__(self, source): def _build_code_from_tree(self, tree, d, prefix): r""" - Builds the Huffman code corresponding to a given tree and prefix. + Build the Huffman code corresponding to a given tree and prefix. INPUT: @@ -266,7 +266,7 @@ def _build_code_from_tree(self, tree, d, prefix): - ``d`` -- the dictionary to fill - - ``prefix`` (string) -- binary string which is the prefix + - ``prefix`` -- string; binary string which is the prefix of any element of the tree EXAMPLES:: @@ -292,15 +292,15 @@ def _build_code_from_tree(self, tree, d, prefix): def _build_code(self, dic): r""" - Constructs a Huffman code corresponding to an alphabet with the given + Construct a Huffman code corresponding to an alphabet with the given weight table. INPUT: - - ``dic`` -- a dictionary that associates to each symbol of an alphabet + - ``dic`` -- dictionary that associates to each symbol of an alphabet a numeric value. If we consider the frequency of each alphabetic symbol, then ``dic`` is considered as the frequency table of the - alphabet with each numeric (non-negative integer) value being the + alphabet with each numeric (nonnegative integer) value being the number of occurrences of a symbol. The numeric values can also represent weights of the symbols. In that case, the numeric values are not necessarily integers, but can be real numbers. In general, @@ -377,11 +377,9 @@ def encode(self, string): INPUT: - - ``string`` -- a string of symbols over an alphabet. + - ``string`` -- string of symbols over an alphabet - OUTPUT: - - - A Huffman encoding of ``string``. + OUTPUT: a Huffman encoding of ``string`` EXAMPLES: @@ -396,7 +394,7 @@ def encode(self, string): 'Sage is my most favorite general purpose computer algebra system' """ if self._character_to_code: - return "".join((self._character_to_code[x] for x in string)) + return "".join(self._character_to_code[x] for x in string) def decode(self, string): r""" @@ -404,11 +402,9 @@ def decode(self, string): INPUT: - - ``string`` -- a string of Huffman encodings. - - OUTPUT: + - ``string`` -- string of Huffman encodings - - The Huffman decoding of ``string``. + OUTPUT: the Huffman decoding of ``string`` EXAMPLES: @@ -453,15 +449,13 @@ def decode(self, string): def encoding_table(self): r""" - Returns the current encoding table. + Return the current encoding table. INPUT: - None. - OUTPUT: - - - A dictionary associating an alphabetic symbol to a Huffman encoding. + OUTPUT: a dictionary associating an alphabetic symbol to a Huffman encoding EXAMPLES:: @@ -496,15 +490,13 @@ def encoding_table(self): def tree(self): r""" - Returns the Huffman tree corresponding to the current encoding. + Return the Huffman tree corresponding to the current encoding. INPUT: - None. - OUTPUT: - - - The binary tree representing a Huffman code. + OUTPUT: the binary tree representing a Huffman code EXAMPLES:: @@ -521,24 +513,22 @@ def tree(self): g.add_edges(self._generate_edges(self._tree)) return g - def _generate_edges(self, tree, parent="", bit=""): + def _generate_edges(self, tree, parent='', bit=''): """ Generate the edges of the given Huffman tree. INPUT: - - ``tree`` -- a Huffman binary tree. + - ``tree`` -- a Huffman binary tree - ``parent`` -- (default: empty string) a parent vertex with exactly - two children. + two children - ``bit`` -- (default: empty string) the bit signifying either the - left or right branch. The bit "0" denotes the left branch and "1" - denotes the right branch. - - OUTPUT: + left or right branch; the bit '0' denotes the left branch and '1' + denotes the right branch - - An edge list of the Huffman binary tree. + OUTPUT: an edge list of the Huffman binary tree EXAMPLES:: @@ -554,8 +544,8 @@ def _generate_edges(self, tree, parent="", bit=""): u = parent s = "".join([parent, bit]) try: - left = self._generate_edges(tree[0], parent=s, bit="0") - right = self._generate_edges(tree[1], parent=s, bit="1") + left = self._generate_edges(tree[0], parent=s, bit='0') + right = self._generate_edges(tree[1], parent=s, bit='1') L = [(u, s)] if s != "" else [] return left + right + L except TypeError: diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index eac8b3ace1f..970221ec24e 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -34,9 +34,9 @@ class SubfieldSubcode(AbstractLinearCode): INPUT: - - ``original_code`` -- the code ``self`` comes from. + - ``original_code`` -- the code ``self`` comes from - - ``subfield`` -- the base field of ``self``. + - ``subfield`` -- the base field of ``self`` - ``embedding`` -- (default: ``None``) a homomorphism from ``subfield`` to ``original_code``'s base field. If ``None`` is provided, it will default @@ -71,7 +71,6 @@ def __init__(self, original_code, subfield, embedding=None): Traceback (most recent call last): ... ValueError: subfield has to be a subfield of the base field of the original code - """ if not isinstance(original_code, AbstractLinearCode): raise ValueError("original_code must be a linear code") @@ -98,7 +97,7 @@ def __init__(self, original_code, subfield, embedding=None): def __eq__(self, other): r""" - Tests equality between Subfield Subcode objects. + Test equality between Subfield Subcode objects. EXAMPLES:: @@ -266,14 +265,14 @@ class SubfieldSubcodeOriginalCodeDecoder(Decoder): INPUT: - - ``code`` -- The associated code of this decoder + - ``code`` -- the associated code of this decoder - - ``original_decoder`` -- (default: ``None``) The decoder that will be used + - ``original_decoder`` -- (default: ``None``) the decoder that will be used over the original code. It has to be a decoder object over the original code. If it is set to ``None``, the default decoder over the original code will be used. - - ``**kwargs`` -- All extra arguments are forwarded to original code's decoder + - ``**kwargs`` -- all extra arguments are forwarded to original code's decoder EXAMPLES:: @@ -403,8 +402,8 @@ def decoding_radius(self, **kwargs): INPUT: - - ``kwargs`` -- Optional arguments are forwarded to original decoder's - :meth:`sage.coding.decoder.Decoder.decoding_radius` method. + - ``kwargs`` -- optional arguments are forwarded to original decoder's + :meth:`sage.coding.decoder.Decoder.decoding_radius` method EXAMPLES:: diff --git a/src/sage/combinat/SJT.py b/src/sage/combinat/SJT.py index 03883eeb401..893f7735183 100644 --- a/src/sage/combinat/SJT.py +++ b/src/sage/combinat/SJT.py @@ -26,6 +26,7 @@ # **************************************************************************** from sage.combinat.combinat import CombinatorialElement + class SJT(CombinatorialElement): r""" A representation of a list permuted using the Steinhaus-Johnson-Trotter diff --git a/src/sage/combinat/abstract_tree.py b/src/sage/combinat/abstract_tree.py index 126185b4eb4..8ea604428f1 100644 --- a/src/sage/combinat/abstract_tree.py +++ b/src/sage/combinat/abstract_tree.py @@ -737,8 +737,8 @@ def paths_at_depth(self, depth, path=[]): INPUT: - - depth -- an integer - - path -- optional given path (as a list) used in the recursion + - ``depth`` -- integer + - ``path`` -- (optional) list; given path used in the recursion .. WARNING:: @@ -790,7 +790,7 @@ def node_number_at_depth(self, depth): INPUT: - - depth -- an integer + - ``depth`` -- integer .. SEEALSO:: @@ -1958,7 +1958,7 @@ def __getitem__(self, idx): INPUT: - - ``idx`` -- an integer, or a valid path in ``self`` identifying a node + - ``idx`` -- integer; or a valid path in ``self`` identifying a node .. NOTE:: @@ -2192,7 +2192,7 @@ def leaf_labels(self): def __eq__(self, other): """ - Test if ``self`` is equal to ``other`` + Test if ``self`` is equal to ``other``. TESTS:: @@ -2216,7 +2216,7 @@ def __eq__(self, other): def _hash_(self): """ - Return the hash value for ``self`` + Return the hash value for ``self``. TESTS:: @@ -2304,7 +2304,7 @@ def as_digraph(self): from sage.graphs.digraph import DiGraph resu = {self.label(): [t.label() for t in self if not t.is_empty()]} - resu = DiGraph(resu, format="dict_of_lists") + resu = DiGraph(resu, format='dict_of_lists') for t in self: if not t.is_empty(): resu = resu.union(t.as_digraph()) @@ -2314,7 +2314,7 @@ def as_digraph(self): class AbstractLabelledClonableTree(AbstractLabelledTree, AbstractClonableTree): """ - Abstract Labelled Clonable Tree + Abstract Labelled Clonable Tree. This class takes care of modification for the label by the clone protocol. @@ -2327,9 +2327,11 @@ def set_root_label(self, label): """ Set the label of the root of ``self``. - INPUT: ``label`` -- any Sage object + INPUT: + + - ``label`` -- any Sage object - OUTPUT: ``None``, ``self`` is modified in place + OUTPUT: none, ``self`` is modified in place .. NOTE:: @@ -2386,11 +2388,11 @@ def set_label(self, path, label): INPUT: - ``path`` -- ``None`` (default) or a path (list or tuple of children - index in the tree) + index in the tree) - ``label`` -- any sage object - OUTPUT: Nothing, ``self`` is modified in place + OUTPUT: nothing, ``self`` is modified in place .. NOTE:: @@ -2432,7 +2434,7 @@ def set_label(self, path, label): def map_labels(self, f): """ - Apply the function `f` to the labels of ``self`` + Apply the function `f` to the labels of ``self``. This method returns a copy of ``self`` on which the function `f` has been applied on all labels (a label `x` is replaced by `f(x)`). @@ -2515,7 +2517,7 @@ def _from_hexacode_aux(ch, parent, label='@'): - ``ch`` -- a hexadecimal string - - ``parent`` -- kind of trees to be produced. + - ``parent`` -- kind of trees to be produced - ``label`` -- a label (default: ``'@'``) to be used for every vertex of the tree diff --git a/src/sage/combinat/affine_permutation.py b/src/sage/combinat/affine_permutation.py index 3a6b935d0cc..74113055d13 100644 --- a/src/sage/combinat/affine_permutation.py +++ b/src/sage/combinat/affine_permutation.py @@ -47,7 +47,7 @@ class AffinePermutation(ClonableArray): def __init__(self, parent, lst, check=True): r""" - Initialize ``self`` + Initialize ``self``. INPUT: @@ -149,7 +149,7 @@ def __mul__(self, q): INPUT: - - ``q`` -- An element of ``self.parent()`` + - ``q`` -- an element of ``self.parent()`` EXAMPLES:: @@ -159,7 +159,6 @@ def __mul__(self, q): Type A affine permutation with window [-1, 3, 0, 6, 5, 4, 10, 9] sage: p.apply_simple_reflection(1, 'right') Type A affine permutation with window [-1, 3, 0, 6, 5, 4, 10, 9] - """ return self.__rmul__(q) @@ -183,7 +182,7 @@ def apply_simple_reflection(self, i, side='right'): INPUT: - - ``i`` -- an integer + - ``i`` -- integer - ``side`` -- (default: ``'right'``) determines whether to apply the reflection on the ``'right'`` or ``'left'`` @@ -219,7 +218,7 @@ def __call__(self, i): """ return self.value(i) - def is_i_grassmannian(self, i=0, side="right") -> bool: + def is_i_grassmannian(self, i=0, side='right') -> bool: r""" Test whether ``self`` is `i`-grassmannian, i.e., either is the identity or has ``i`` as the sole descent. @@ -258,7 +257,7 @@ def index_set(self): """ return tuple(range(self.k+1)) - def lower_covers(self,side="right"): + def lower_covers(self, side='right'): r""" Return lower covers of ``self``. @@ -281,7 +280,7 @@ def lower_covers(self,side="right"): def is_one(self) -> bool: r""" - Tests whether the affine permutation is the identity. + Test whether the affine permutation is the identity. EXAMPLES:: @@ -297,7 +296,7 @@ def is_one(self) -> bool: def reduced_word(self): r""" - Returns a reduced word for the affine permutation. + Return a reduced word for the affine permutation. EXAMPLES:: @@ -500,7 +499,7 @@ def apply_simple_reflection_right(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -579,7 +578,7 @@ def has_right_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -599,7 +598,7 @@ def has_left_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -675,11 +674,11 @@ def maximal_cyclic_factor(self, typ='decreasing', side='right', verbose=False): (default: ``'decreasing'``); chooses whether to find increasing or decreasing sets - - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``) chooses + - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``); chooses whether to find maximal sets starting from the left or the right - - ``verbose`` -- True or False. If True, outputs information about how - the cyclically increasing element was found. + - ``verbose`` -- boolean; if ``True``, outputs information about how + the cyclically increasing element was found EXAMPLES:: @@ -743,8 +742,8 @@ def maximal_cyclic_decomposition(self, typ='decreasing', side='right', verbose=F - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``) chooses whether to find maximal sets starting from the left or the right - - ``verbose`` -- (default: ``False``) print extra information while - finding the decomposition + - ``verbose`` -- boolean (default: ``False``); print extra information + while finding the decomposition EXAMPLES:: @@ -906,7 +905,7 @@ def is_fully_commutative(self) -> bool: if m != -1 and c[i] - (i - m) >= c[m]: return False m = i - # now check m (the last non-zero) against first non-zero. + # now check m (the last nonzero) against first nonzero. d = self.n - (m - firstnonzero) return not c[firstnonzero] - d >= c[m] @@ -917,11 +916,11 @@ def to_bounded_partition(self, typ='decreasing', side='right'): INPUT: - - ``typ`` -- ``'increasing'`` or ``'decreasing'`` (default: ``'decreasing'``.) - Chooses whether to find increasing or decreasing sets. + - ``typ`` -- ``'increasing'`` or ``'decreasing'`` (default: ``'decreasing'``); + chooses whether to find increasing or decreasing sets - - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``.) Chooses whether to - find maximal sets starting from the left or the right. + - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``); chooses + whether to find maximal sets starting from the left or the right EXAMPLES:: @@ -936,7 +935,7 @@ def to_bounded_partition(self, typ='decreasing', side='right'): def to_core(self, typ='decreasing', side='right'): r""" - Returns the core associated to the dominant element obtained by sorting + Return the core associated to the dominant element obtained by sorting the Lehmer code. INPUT: @@ -944,7 +943,7 @@ def to_core(self, typ='decreasing', side='right'): - ``typ`` -- ``'increasing'`` or ``'decreasing'`` (default: ``'decreasing'``.) - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``.) Chooses whether to - find maximal sets starting from the left or the right. + find maximal sets starting from the left or the right EXAMPLES:: @@ -1119,7 +1118,7 @@ def value(self, i): def position(self, i): r""" - Find the position `j` such the ``self.value(j)=i`` + Find the position `j` such the ``self.value(j)=i``. EXAMPLES:: @@ -1231,7 +1230,7 @@ def has_right_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1252,7 +1251,7 @@ def has_left_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1414,7 +1413,7 @@ def has_right_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1433,7 +1432,7 @@ def has_left_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1589,7 +1588,7 @@ def has_right_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1610,7 +1609,7 @@ def has_left_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1791,7 +1790,7 @@ def has_right_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1812,7 +1811,7 @@ def has_left_descent(self, i) -> bool: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -2067,7 +2066,7 @@ def _test_enumeration(self, n=4, **options): def weyl_group(self): r""" - Returns the Weyl Group of the same type as ``self``. + Return the Weyl Group of the same type as ``self``. EXAMPLES:: @@ -2079,7 +2078,7 @@ def weyl_group(self): def classical(self): r""" - Returns the finite permutation group. + Return the finite permutation group. EXAMPLES:: @@ -2093,7 +2092,7 @@ def classical(self): def cartan_type(self): r""" - Returns the Cartan type of ``self``. + Return the Cartan type of ``self``. EXAMPLES:: @@ -2104,7 +2103,7 @@ def cartan_type(self): def cartan_matrix(self): r""" - Returns the Cartan matrix of ``self``. + Return the Cartan matrix of ``self``. EXAMPLES:: @@ -2167,7 +2166,7 @@ def random_element(self, n=None): Return a random affine permutation of length ``n``. If ``n`` is not specified, then ``n`` is chosen as a random - non-negative integer in `[0, 1000]`. + nonnegative integer in `[0, 1000]`. Starts at the identity, then chooses an upper cover at random. Not very uniform: actually constructs a uniformly random reduced word @@ -2192,7 +2191,7 @@ def random_element(self, n=None): def from_word(self, w): r""" - Builds an affine permutation from a given word. + Build an affine permutation from a given word. Note: Already in category as ``from_reduced_word``, but this is less typing! @@ -2208,7 +2207,7 @@ def from_word(self, w): @cached_method def _an_element_(self): r""" - Returns a Coxeter element. + Return a Coxeter element. EXAMPLES:: diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index c55f8e01c48..901bca30fd2 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -72,7 +72,7 @@ from sage.combinat.dlx import DLXMatrix, AllExactCovers, OneExactCover -# block designs, etc +# block designs, etc. from sage.combinat.designs.all import * # Free modules and friends diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 944091eb74e..230c9a8aae7 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -84,7 +84,7 @@ class AlternatingSignMatrix(Element, An alternating sign matrix. An alternating sign matrix is a square matrix of `0`'s, `1`'s and `-1`'s - such that the sum of each row and column is `1` and the non-zero + such that the sum of each row and column is `1` and the nonzero entries in each row and column alternate in sign. These were introduced in [MRR1983]_. @@ -519,18 +519,17 @@ def to_fully_packed_loop(self): sage: asm = AlternatingSignMatrix([[1,0,0],[0,1,0],[0,0,1]]) sage: fpl = asm.to_fully_packed_loop() sage: fpl - | | - | | - + + -- + - | | - | | - -- + + + -- - | | - | | - + -- + + - | | - | | - + │ │ + │ │ + + + ── + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + ── + + + │ │ + │ │ """ from sage.combinat.fully_packed_loop import FullyPackedLoop return FullyPackedLoop(self) @@ -695,7 +694,7 @@ def ASM_compatible_bigger(self): Given an `n \times n` alternating sign matrix `A`, there are as many ASM's of size `n+1` compatible with `A` as 2 raised to the power of - the number of 1's in `A` [EKLP1992]_. + the number of 1s in `A` [EKLP1992]_. EXAMPLES:: @@ -777,7 +776,6 @@ def ASM_compatible_smaller(self): [1 0] [0 1] ] - """ n = self.parent()._n M = AlternatingSignMatrices(n-1) @@ -1020,14 +1018,14 @@ class AlternatingSignMatrices(UniqueRepresentation, Parent): An alternating sign matrix of size `n` is an `n \times n` matrix of `0`'s, `1`'s and `-1`'s such that the sum of each row and column is `1` and the - non-zero entries in each row and column alternate in sign. + nonzero entries in each row and column alternate in sign. Alternating sign matrices of size `n` are in bijection with :class:`monotone triangles ` with `n` rows. INPUT: - - `n` -- an integer, the size of the matrices. + - ``n`` -- integer; the size of the matrices EXAMPLES: @@ -1547,7 +1545,6 @@ def cover_relations(self): [0 0 1] [0 1 0] [1 0 0], [1 0 0] ) - """ return iter(self._lattice_initializer()[1]) @@ -1562,7 +1559,6 @@ def lattice(self): sage: L = A.lattice() sage: L Finite lattice containing 7 elements - """ return LatticePoset(self._lattice_initializer(), cover_relations=True, check=False) @@ -1635,7 +1631,7 @@ class MonotoneTriangles(GelfandTsetlinPatternsTopRow): INPUT: - - ``n`` -- The number of rows in the monotone triangles + - ``n`` -- the number of rows in the monotone triangles EXAMPLES: diff --git a/src/sage/combinat/backtrack.py b/src/sage/combinat/backtrack.py index 1fd90caa9d3..223d3de1db5 100644 --- a/src/sage/combinat/backtrack.py +++ b/src/sage/combinat/backtrack.py @@ -152,7 +152,7 @@ def roots(self): def children(self, x): r""" - Return the single child ``x+1`` of the integer ``x`` + Return the single child ``x+1`` of the integer ``x``. EXAMPLES:: diff --git a/src/sage/combinat/baxter_permutations.py b/src/sage/combinat/baxter_permutations.py index 648ce9c6a26..08b67b96540 100644 --- a/src/sage/combinat/baxter_permutations.py +++ b/src/sage/combinat/baxter_permutations.py @@ -25,8 +25,8 @@ class BaxterPermutations(UniqueRepresentation, Parent): INPUT: - - ``n`` -- (default: ``None``) a nonnegative integer, the size of - the permutations. + - ``n`` -- nonnegative integer (default: ``None``); the size of + the permutations OUTPUT: @@ -85,7 +85,7 @@ def __init__(self, n): def _repr_(self): """ - Return a string representation of ``self`` + Return a string representation of ``self``. EXAMPLES:: @@ -102,7 +102,7 @@ def __contains__(self, x): INPUT: - - ``x`` -- a permutation. + - ``x`` -- a permutation EXAMPLES:: @@ -150,9 +150,7 @@ def __iter__(self): r""" Efficient generation of Baxter permutations. - OUTPUT: - - An iterator over the Baxter permutations of size ``self._n``. + OUTPUT: an iterator over the Baxter permutations of size ``self._n`` EXAMPLES:: @@ -287,7 +285,7 @@ def __contains__(self, x): INPUT: - - ``x`` -- any object. + - ``x`` -- any object EXAMPLES:: @@ -312,7 +310,7 @@ def to_pair_of_twin_binary_trees(self, p): INPUT: - - ``p`` -- a Baxter permutation. + - ``p`` -- a Baxter permutation OUTPUT: diff --git a/src/sage/combinat/bijectionist.py b/src/sage/combinat/bijectionist.py index 2bb02e31aac..ce1bf8aca13 100644 --- a/src/sage/combinat/bijectionist.py +++ b/src/sage/combinat/bijectionist.py @@ -481,7 +481,6 @@ class Bijectionist(SageObject): :meth:`set_statistics`, :meth:`set_intertwining_relations`, :meth:`set_constant_blocks`, etc., is irrelevant. Calling any of these methods a second time overrides the previous specification. - """ def __init__(self, A, B, tau=None, alpha_beta=tuple(), P=None, pi_rho=tuple(), phi_psi=tuple(), Q=None, @@ -565,7 +564,7 @@ def set_constant_blocks(self, P): INPUT: - - ``P`` -- a set partition of `A`, singletons may be omitted + - ``P`` -- set partition of `A`, singletons may be omitted EXAMPLES: @@ -605,7 +604,6 @@ def set_constant_blocks(self, P): Traceback (most recent call last): ... StopIteration - """ self._bmilp = None self._P = DisjointSet(self._A) @@ -623,10 +621,10 @@ def constant_blocks(self, singletons=False, optimal=False): INPUT: - - ``singletons`` -- (default: ``False``) whether or not to + - ``singletons`` -- boolean (default: ``False``); whether or not to include singleton blocks in the output - - ``optimal`` -- (default: ``False``) whether or not to + - ``optimal`` -- boolean (default: ``False``); whether or not to compute the coarsest possible partition .. NOTE:: @@ -645,7 +643,6 @@ def constant_blocks(self, singletons=False, optimal=False): sage: bij.constant_blocks(singletons=True) {{'a', 'b'}, {'c'}} - """ if optimal: self._forced_constant_blocks() @@ -748,7 +745,6 @@ def set_statistics(self, *alpha_beta): {[]: 2, [1]: 0, [1, 2]: 0, [2, 1]: 1} {[]: 2, [1]: 0, [1, 2]: 1, [2, 1]: 0} {[]: 2, [1]: 1, [1, 2]: 0, [2, 1]: 0} - """ self._bmilp = None self._n_statistics = len(alpha_beta) @@ -815,7 +811,6 @@ def statistics_fibers(self): (3, 2, 1) [[1, 3, 2], [2, 1, 3], [3, 2, 1]] [[1, 3, 2], [2, 1, 3], [2, 3, 1]] (3, 2, 0) [[2, 3, 1]] [[3, 1, 2]] (3, 1, 0) [[3, 1, 2]] [[1, 2, 3]] - """ return self._statistics_fibers @@ -827,7 +822,7 @@ def statistics_table(self, header=True): INPUT: - - ``header`` -- (default: ``True``) whether to include a + - ``header`` -- boolean (default: ``True``); whether to include a header with the standard Greek letters OUTPUT: @@ -940,7 +935,6 @@ def statistics_table(self, header=True): [['b', 'τ'], [[], 0], [[1], 1], [[1, 2], 2], [[2, 1], 1]] sage: bij.statistics_table(header=False)[1] [[[], 0], [[1], 1], [[1, 2], 2], [[2, 1], 1]] - """ # table for alpha n_statistics = self._n_statistics @@ -1059,7 +1053,6 @@ def set_value_restrictions(self, *value_restrictions): Traceback (most recent call last): ... AssertionError: element (1, 2) was not found in A - """ # it might be much cheaper to construct the sets as subsets # of _statistics_possible_values - however, we do not want to @@ -1078,7 +1071,7 @@ def _compute_possible_block_values(self): This has to be called whenever ``self._P`` was modified. - It raises a :class:`ValueError`, if the restrictions on a + It raises a :exc:`ValueError`, if the restrictions on a block are contradictory. TESTS:: @@ -1091,7 +1084,6 @@ def _compute_possible_block_values(self): Traceback (most recent call last): ... ValueError: no possible values found for singleton block [[1, 2]] - """ self._possible_block_values = {} # P -> Power(Z) for p, block in self._P.root_to_elements_dict().items(): @@ -1254,7 +1246,6 @@ def set_distributions(self, *elements_distributions): Note that the same error occurs when an element that is not the first element of the list is not in `A`. - """ self._bmilp = None for tA, tZ in elements_distributions: @@ -1382,7 +1373,6 @@ def set_intertwining_relations(self, *pi_rho): sage: bij.set_intertwining_relations((2, concat, lambda x, y: x + y), (2, skew_concat, lambda x, y: x + y)) sage: list(bij.solutions_iterator()) [] - """ self._bmilp = None Pi_Rho = namedtuple("Pi_Rho", "numargs pi rho domain") @@ -1420,7 +1410,6 @@ def set_quadratic_relation(self, *phi_psi): and `\psi:Z\to A`. Note that, in particular, `\phi` must be constant on blocks. - EXAMPLES:: sage: A = B = DyckWords(3) @@ -1447,7 +1436,6 @@ def set_quadratic_relation(self, *phi_psi): ( [ /\ ] ) ] ( [ / \ ] ) ] ( [ / \ ], [ /\/\/\ ] ) ] - """ self._bmilp = None self._phi_psi = phi_psi @@ -1459,7 +1447,7 @@ def set_homomesic(self, Q): INPUT: - - ``Q`` -- a set partition of ``A`` + - ``Q`` -- set partition of ``A`` EXAMPLES:: @@ -1468,7 +1456,6 @@ def set_homomesic(self, Q): sage: bij.set_homomesic([[1,2], [3]]) sage: list(bij.solutions_iterator()) [{1: 2, 2: 0, 3: 1}, {1: 0, 2: 2, 3: 1}] - """ self._bmilp = None if Q is None: @@ -1640,7 +1627,6 @@ def _forced_constant_blocks(self): {{'a', 'b'}} sage: bij.constant_blocks(optimal=True) {{'a', 'b'}, {'c', 'd'}} - """ if self._bmilp is None: self._bmilp = _BijectionistMILP(self) @@ -1709,7 +1695,7 @@ def possible_values(self, p=None, optimal=False): - ``p`` -- (optional) a block of `P`, or an element of a block of `P`, or a list of these - - ``optimal`` -- (default: ``False``) whether or not to + - ``optimal`` -- boolean (default: ``False``); whether or not to compute the minimal possible set of statistic values .. NOTE:: @@ -1748,7 +1734,7 @@ def possible_values(self, p=None, optimal=False): Test if all formats are really possible:: - sage: bij.possible_values(p="a") + sage: bij.possible_values(p='a') {'a': {1, 2}, 'b': {1, 2}} sage: bij.possible_values(p=["a", "b"]) {'a': {1, 2}, 'b': {1, 2}} @@ -1762,9 +1748,9 @@ def possible_values(self, p=None, optimal=False): sage: A = B = 'ab' sage: bij = Bijectionist(A, B, lambda x: B.index(x) % 2) sage: bij.set_constant_blocks([['a', 'b']]) - sage: bij.possible_values(p="a") + sage: bij.possible_values(p='a') {'a': {0, 1}, 'b': {0, 1}} - sage: bij.possible_values(p="a", optimal=True) + sage: bij.possible_values(p='a', optimal=True) {'a': set(), 'b': set()} """ # convert input to set of block representatives @@ -1893,7 +1879,7 @@ def minimal_subdistributions_iterator(self): # add constraint that not all of these can be 1, thus vetoing # the current solution minimal_subdistribution.add_constraint(sum(active_vars) <= len(active_vars) - 1, - name="veto") + name='veto') else: s = new_s @@ -1929,7 +1915,6 @@ def _find_counterexample(self, P, s0, d, on_blocks): sage: d = {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'e': 0} sage: bij._find_counterexample(bij._A, s0, d, False) {'a': 2, 'b': 2, 'c': 1, 'd': 3, 'e': 1} - """ bmilp = self._bmilp for z in self._Z: @@ -2065,7 +2050,6 @@ def minimal_subdistributions_blocks_iterator(self): sage: sorted(D) in [d for d, _ in bij.minimal_subdistributions_iterator()] True - """ # see # https://mathoverflow.net/questions/406751/find-a-subdistribution/406975 @@ -2110,7 +2094,7 @@ def add_counter_example_constraint(s): support = [X[p] for p in P if d[p]] # add constraint that the support is different minimal_subdistribution.add_constraint(sum(support) <= len(support) - 1, - name="veto") + name='veto') else: s = new_s add_counter_example_constraint(s) @@ -2168,7 +2152,6 @@ def _preprocess_intertwining_relations(self): sage: bij._preprocess_intertwining_relations() sage: bij._P {{[1, 2, 3]}, {[1, 3, 2]}, {[2, 1, 3]}, {[2, 3, 1]}, {[3, 1, 2]}, {[3, 2, 1]}} - """ A = self._A P = self._P @@ -2207,7 +2190,7 @@ def solutions_iterator(self): r""" An iterator over all solutions of the problem. - OUTPUT: An iterator over all possible mappings `s: A\to Z` + OUTPUT: an iterator over all possible mappings `s: A\to Z` ALGORITHM: @@ -2274,7 +2257,7 @@ def solutions_iterator(self): EXAMPLES:: sage: A = B = 'abc' - sage: bij = Bijectionist(A, B, lambda x: B.index(x) % 2, solver="GLPK") + sage: bij = Bijectionist(A, B, lambda x: B.index(x) % 2, solver='GLPK') sage: next(bij.solutions_iterator()) {'a': 0, 'b': 1, 'c': 0} @@ -2303,7 +2286,7 @@ def solutions_iterator(self): sage: P = [list(a) for n in range(N) for a in Permutations(n).conjugacy_classes()] - sage: bij = Bijectionist(A, B, tau, solver="GLPK") + sage: bij = Bijectionist(A, B, tau, solver='GLPK') sage: bij.set_statistics((len, len)) sage: bij.set_constant_blocks(P) sage: for solution in bij.solutions_iterator(): @@ -2447,7 +2430,6 @@ def solutions_iterator(self): sage: s1_3 = next(iterator1) sage: len(set([tuple(sorted(s.items())) for s in [s1_1, s1_2, s1_3]])) 3 - """ if self._bmilp is None: self._bmilp = _BijectionistMILP(self) @@ -2467,7 +2449,7 @@ def __init__(self, bijectionist: Bijectionist, solutions=None): INPUT: - - ``bijectionist`` -- an instance of :class:`Bijectionist`. + - ``bijectionist`` -- an instance of :class:`Bijectionist` - ``solutions`` -- (optional) a list of solutions of the problem, each provided as a dictionary mapping `(a, z)` to @@ -2486,7 +2468,6 @@ def __init__(self, bijectionist: Bijectionist, solutions=None): sage: from sage.combinat.bijectionist import _BijectionistMILP sage: _BijectionistMILP(bij) - """ # the attributes of the bijectionist class we actually use: # _possible_block_values @@ -2534,7 +2515,7 @@ def show(self, variables=True): EXAMPLES:: sage: A = B = ["a", "b", "c"] - sage: bij = Bijectionist(A, B, lambda x: A.index(x) % 2, solver="GLPK") + sage: bij = Bijectionist(A, B, lambda x: A.index(x) % 2, solver='GLPK') sage: bij.set_constant_blocks([["a", "b"]]) sage: next(bij.solutions_iterator()) {'a': 0, 'b': 0, 'c': 1} @@ -2550,7 +2531,6 @@ def show(self, variables=True): x_1: s(a) = s(b) = 1 x_2: s(c) = 0 x_3: s(c) = 1 - """ print("Constraints are:") b = self.milp.get_backend() @@ -2609,7 +2589,6 @@ def _prepare_solution(self, on_blocks, solution): sage: bmilp = bij._bmilp sage: bmilp._prepare_solution(True, bmilp._solution_cache[0]) {'a': 0, 'c': 0} - """ P = self._bijectionist._P tZ = self._bijectionist._possible_block_values @@ -2631,16 +2610,16 @@ def solutions_iterator(self, on_blocks, additional_constraints): INPUT: - - ``additional_constraints`` -- a list of constraints for the + - ``additional_constraints`` -- list of constraints for the underlying MILP - - ``on_blocks``, whether to return the solution on blocks or + - ``on_blocks`` -- whether to return the solution on blocks or on all elements TESTS:: sage: A = B = 'abc' - sage: bij = Bijectionist(A, B, lambda x: B.index(x) % 2, solver="GLPK") + sage: bij = Bijectionist(A, B, lambda x: B.index(x) % 2, solver='GLPK') sage: from sage.combinat.bijectionist import _BijectionistMILP sage: bmilp = _BijectionistMILP(bij) sage: it = bmilp.solutions_iterator(False, []) @@ -2653,7 +2632,6 @@ def solutions_iterator(self, on_blocks, additional_constraints): {'a': 0, 'b': 0, 'c': 1} sage: next(it) {'a': 1, 'b': 0, 'c': 0} - """ i = 0 # the first unconsidered element of _solution_cache while True: @@ -2700,7 +2678,7 @@ def _add_solution(self, solution): INPUT: - - ``solution`` -- a dictionary from the indices of the MILP to + - ``solution`` -- dictionary from the indices of the MILP to a boolean EXAMPLES:: @@ -2722,14 +2700,13 @@ def _add_solution(self, solution): x_1: s(a) = a x_2: s(b) = b x_3: s(b) = a - """ active_vars = [self._x[p, z] for p in _disjoint_set_roots(self._bijectionist._P) for z in self._bijectionist._possible_block_values[p] if solution[(p, z)]] self.milp.add_constraint(sum(active_vars) <= len(active_vars) - 1, - name="veto") + name='veto') self._solution_cache.append(solution) def _is_solution(self, constraint, values): @@ -2739,7 +2716,7 @@ def _is_solution(self, constraint, values): INPUT: - ``constraint`` -- a - :class:`sage.numerical.linear_functions.LinearConstraint`. + :class:`sage.numerical.linear_functions.LinearConstraint` - ``values`` -- a candidate for a solution of the MILP as a dictionary from pairs `(a, z)\in A\times Z` to `0` or `1`, @@ -2825,7 +2802,7 @@ def add_alpha_beta_constraints(self): for w in range(len(W)): for z in range(len(Z)): self.milp.add_constraint(AZ_matrix[z][w] == B_matrix[z][w], - name="statistics") + name='statistics') def add_distribution_constraints(self): r""" @@ -2856,7 +2833,6 @@ def add_distribution_constraints(self): [2, 3, 1]: 2, [3, 1, 2]: 2, [3, 2, 1]: 2} - """ Z = self._bijectionist._Z Z_dict = {z: i for i, z in enumerate(Z)} @@ -2998,7 +2974,6 @@ def add_quadratic_relation_constraints(self): ( [ /\ ] ) ] ( [ / \ ] ) ] ( [ / \ ], [ /\/\/\ ] ) ] - """ P = self._bijectionist._P for phi, psi in self._bijectionist._phi_psi: @@ -3060,7 +3035,7 @@ def _invert_dict(d): INPUT: - - ``d`` -- a dict + - ``d`` -- dictionary EXAMPLES:: @@ -3115,7 +3090,6 @@ def _non_copying_intersection(sets): sage: A = set([1,2]); B = set([2,3]) sage: _non_copying_intersection([A, B]) {2} - """ sets = sorted(sets, key=len) result = set.intersection(*sets) diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index f9c9cdbf2a0..df8de0ada86 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -76,25 +76,22 @@ class BinaryRecurrenceSequence(SageObject): - """ Create a linear binary recurrence sequence defined by initial conditions `u_0` and `u_1` and recurrence relation `u_{n+2} = b*u_{n+1}+c*u_n`. INPUT: - - ``b`` -- an integer (partially determining the recurrence relation) - - - ``c`` -- an integer (partially determining the recurrence relation) + - ``b`` -- integer; (partially determining the recurrence relation) - - ``u0`` -- an integer (the 0th term of the binary recurrence sequence) + - ``c`` -- integer; (partially determining the recurrence relation) - - ``u1`` -- an integer (the 1st term of the binary recurrence sequence) + - ``u0`` -- integer; (the `0`-th term of the binary recurrence sequence) + - ``u1`` -- integer; (the `1`-st term of the binary recurrence sequence) - OUTPUT: - - - An integral linear binary recurrence sequence defined by ``u0``, ``u1``, and `u_{n+2} = b*u_{n+1}+c*u_n` + OUTPUT: an integral linear binary recurrence sequence defined by `u_0`, + `u_1`, and `u_{n+2} = b u_{n+1}+c u_n` .. SEEALSO:: @@ -106,7 +103,6 @@ class BinaryRecurrenceSequence(SageObject): sage: R Binary recurrence sequence defined by: u_n = 3 * u_{n-1} + 3 * u_{n-2}; With initial conditions: u_0 = 2, and u_1 = 1 - """ def __init__(self, b, c, u0=0, u1=1): @@ -123,7 +119,6 @@ def __init__(self, b, c, u0=0, u1=1): sage: R = BinaryRecurrenceSequence(1,1) sage: loads(R.dumps()) == R True - """ self.b = b self.c = c @@ -133,7 +128,7 @@ def __init__(self, b, c, u0=0, u1=1): self._PGoodness = {} # dictionary to cache primes that are "good" by some prime power self._ell = 1 # variable that keeps track of the last prime power to be used as a goodness - def __repr__(self): + def __repr__(self) -> str: """ Give string representation of the class. @@ -143,11 +138,10 @@ def __repr__(self): sage: R Binary recurrence sequence defined by: u_n = 3 * u_{n-1} + 3 * u_{n-2}; With initial conditions: u_0 = 2, and u_1 = 1 - """ return 'Binary recurrence sequence defined by: u_n = ' + str(self.b) + ' * u_{n-1} + ' + str(self.c) + ' * u_{n-2};\nWith initial conditions: u_0 = ' + str(self.u0) + ', and u_1 = ' + str(self.u1) - def __eq__(self, other): + def __eq__(self, other) -> bool: """ Compare two binary recurrence sequences. @@ -166,17 +160,17 @@ def __eq__(self, other): def __call__(self, n, modulus=0): """ - Give the nth term of a binary recurrence sequence, possibly mod some modulus. + Give the `n`-th term of a binary recurrence sequence, possibly mod some modulus. INPUT: - - ``n`` -- an integer (the index of the term in the binary recurrence sequence) + - ``n`` -- integer; the index of the term in the binary recurrence sequence - ``modulus`` -- a natural number (optional -- default value is 0) OUTPUT: - - An integer (the nth term of the binary recurrence sequence modulo ``modulus``) + - An integer (the `n`-th term of the binary recurrence sequence modulo ``modulus``) EXAMPLES:: @@ -196,7 +190,7 @@ def __call__(self, n, modulus=0): v = vector(R, [self.u0, self.u1]) return list(F**n * v)[0] - def is_degenerate(self): + def is_degenerate(self) -> bool: """ Decide whether the binary recurrence sequence is degenerate. @@ -210,13 +204,20 @@ def is_degenerate(self): More concretely, there are 4 classes of degeneracy, that can all be formulated in terms of the matrix `F = [[0,1], [c, b]]`. - - `F` is singular -- this corresponds to ``c`` = 0, and thus `\\alpha*\\beta = 0`. This sequence is geometric after term ``u0`` and so we call it ``quasigeometric``. + - `F` is singular -- this corresponds to ``c`` = 0, and thus + `\\alpha*\\beta = 0`. This sequence is geometric after term ``u0`` + and so we call it ``quasigeometric`` - - `v = [[u_0], [u_1]]` is an eigenvector of `F` -- this corresponds to a ``geometric`` sequence with `a*b = 0`. + - `v = [[u_0], [u_1]]` is an eigenvector of `F` -- this corresponds to + a ``geometric`` sequence with `a*b = 0` - - `F` is nondiagonalizable -- this corresponds to `\\alpha = \\beta`. This sequence will be the point-wise product of an arithmetic and geometric sequence. + - `F` is nondiagonalizable -- this corresponds to `\\alpha = \\beta`. + This sequence will be the point-wise product of an arithmetic and + geometric sequence. - - `F^k` is scaler, for some `k>1` -- this corresponds to `\\alpha/\\beta` a `k` th root of unity. This sequence is a union of several geometric sequences, and so we again call it ``quasigeometric``. + - `F^k` is scalar, for some `k>1` -- this corresponds to + `\\alpha/\\beta` a `k` th root of unity. This sequence is a union of + several geometric sequences, and so we again call it ``quasigeometric``. EXAMPLES:: @@ -243,13 +244,12 @@ def is_degenerate(self): if D.is_square(): A = sqrt(D) else: - K = QuadraticField(D, 'x') - A = K.gen() + A = QuadraticField(D, 'x').gen() - aa = (self.u1 - self.u0*(self.b + A)/2)/(A) #called `a` in Docstring - bb = (self.u1 - self.u0*(self.b - A)/2)/(A) #called `b` in Docstring + aa = (self.u1 - self.u0 * (self.b + A)/2)/(A) # called `a` in Docstring + bb = (self.u1 - self.u0 * (self.b - A)/2)/(A) # called `b` in Docstring - #(b+A)/2 is called alpha in Docstring, (b-A)/2 is called beta in Docstring + # (b+A)/2 is called alpha in Docstring, (b-A)/2 is called beta in Docstring if self.b != A: if ((self.b+A)/(self.b-A))**6 == 1: @@ -261,7 +261,7 @@ def is_degenerate(self): return True - def is_geometric(self): + def is_geometric(self) -> bool: """ Decide whether the binary recurrence sequence is geometric - ie a geometric sequence. @@ -279,20 +279,20 @@ def is_geometric(self): sage: S.is_geometric() True """ - #If [u_0, u_1]^T is an eigenvector for the incrementation matrix F = [[0,1],[c,b]], then the sequence - #is geometric, ie we can write u_n = a*r^n for some a and r. + # If [u_0, u_1]^T is an eigenvector for the incrementation matrix F = [[0,1],[c,b]], then the sequence + # is geometric, ie we can write u_n = a*r^n for some a and r. - #We decide if u0, u1, u2 = b*u1+c*u0 are in geometric progression by whether u1^2 = (b*u1+c*u0)*u0 + # We decide if u0, u1, u2 = b*u1+c*u0 are in geometric progression by whether u1^2 = (b*u1+c*u0)*u0 return (self.u1)**2 == (self.b*self.u1 + self.c*self.u0)*self.u0 - def is_quasigeometric(self): + def is_quasigeometric(self) -> bool: """ Decide whether the binary recurrence sequence is degenerate and similar to a geometric sequence, i.e. the union of multiple geometric sequences, or geometric after term ``u0``. If `\\alpha/\\beta` is a `k` th root of unity, where `k>1`, then necessarily `k = 2, 3, 4, 6`. - Then `F = [[0,1],[c,b]` is diagonalizable, and `F^k = [[\\alpha^k, 0], [0,\\beta^k]]` is scaler + Then `F = [[0,1],[c,b]` is diagonalizable, and `F^k = [[\\alpha^k, 0], [0,\\beta^k]]` is a diagonal matrix. Thus for all values of `j` mod `k`, the `j` mod `k` terms of `u_n` form a geometric series. @@ -323,14 +323,13 @@ def is_quasigeometric(self): if D.is_square(): A = sqrt(D) else: - K = QuadraticField(D, 'x') - A = K.gen() + A = QuadraticField(D, 'x').gen() if ((self.b+A)/(self.b-A))**6 == 1: return True return False - def is_arithmetic(self): + def is_arithmetic(self) -> bool: """ Decide whether the sequence is degenerate and an arithmetic sequence. @@ -347,7 +346,7 @@ def is_arithmetic(self): sage: S.is_arithmetic() True """ - return (self(1) - self(0) == self(2) - self(1) == self(3) - self(2)) + return self(1) - self(0) == self(2) - self(1) == self(3) - self(2) def period(self, m): """ @@ -359,11 +358,9 @@ def period(self, m): INPUT: - - ``m`` -- an integer (modulo which the period of the recurrence relation is calculated). - - OUTPUT: + - ``m`` -- integer; modulo which the period of the recurrence relation is calculated - - The integer (the period of the sequence modulo m) + OUTPUT: integer (the period of the sequence modulo m) EXAMPLES: @@ -398,7 +395,7 @@ def period(self, m): .. NOTE:: The answer is cached. """ - #If we have already computed the period mod m, then we return the stored value. + # If we have already computed the period mod m, then we return the stored value. if m in self._period_dict: return self._period_dict[m] @@ -410,17 +407,17 @@ def period(self, m): Fac = list(m.factor()) Periods = {} - #To compute the period mod m, we compute the least integer n such that A^n*w == w. This necessarily - #divides the order of A as a matrix in GL_2(Z/mZ). + # To compute the period mod m, we compute the least integer n such that A^n*w == w. This necessarily + # divides the order of A as a matrix in GL_2(Z/mZ). - #We compute the period modulo all distinct prime powers dividing m, and combine via the lcm. - #To compute the period mod p^e, we first compute the order mod p. Then the period mod p^e - #must divide p^{4e-4}*period(p), as the subgroup of matrices mod p^e, which reduce to - #the identity mod p is of order (p^{e-1})^4. So we compute the period mod p^e by successively - #multiplying the period mod p by powers of p. + # We compute the period modulo all distinct prime powers dividing m, and combine via the lcm. + # To compute the period mod p^e, we first compute the order mod p. Then the period mod p^e + # must divide p^{4e-4}*period(p), as the subgroup of matrices mod p^e, which reduce to + # the identity mod p is of order (p^{e-1})^4. So we compute the period mod p^e by successively + # multiplying the period mod p by powers of p. for p, e in Fac: - #first compute the period mod p + # first compute the period mod p if p in self._period_dict: perp = self._period_dict[p] else: @@ -429,29 +426,29 @@ def period(self, m): FF = F**(p-1) p1fac = list((p-1).factor()) - #The order of any matrix in GL_2(F_p) either divides p(p-1) or (p-1)(p+1). - #The order divides p-1 if it is diagonalizable. In any case, det(F^(p-1))=1, - #so if tr(F^(p-1)) = 2, then it must be triangular of the form [[1,a],[0,1]]. - #The order of the subgroup of matrices of this form is p, so the order must divide - #p(p-1) -- in fact it must be a multiple of p. If this is not the case, then the - #order divides (p-1)(p+1). As the period divides the order of the matrix in GL_2(F_p), - #these conditions hold for the period as well. + # The order of any matrix in GL_2(F_p) either divides p(p-1) or (p-1)(p+1). + # The order divides p-1 if it is diagonalizable. In any case, det(F^(p-1))=1, + # so if tr(F^(p-1)) = 2, then it must be triangular of the form [[1,a],[0,1]]. + # The order of the subgroup of matrices of this form is p, so the order must divide + # p(p-1) -- in fact it must be a multiple of p. If this is not the case, then the + # order divides (p-1)(p+1). As the period divides the order of the matrix in GL_2(F_p), + # these conditions hold for the period as well. - #check if the order divides (p-1) + # check if the order divides (p-1) if FF*v == v: M = p-1 Mfac = p1fac - #check if the trace is 2, then the order is a multiple of p dividing p*(p-1) + # check if the trace is 2, then the order is a multiple of p dividing p*(p-1) elif FF.trace() == 2: M = p-1 Mfac = p1fac - F = F**p #replace F by F^p as now we only need to determine the factor dividing (p-1) + F = F**p # replace F by F^p as now we only need to determine the factor dividing (p-1) - #otherwise it will divide (p+1)(p-1) + # otherwise it will divide (p+1)(p-1) else: M = (p+1)*(p-1) - p2fac = list((p+1).factor()) #factor the (p+1) and (p-1) terms separately and then combine for speed + p2fac = list((p+1).factor()) # factor the (p+1) and (p-1) terms separately and then combine for speed Mfac_dic = {} for i0, i1 in list(p1fac + p2fac): if i0 not in Mfac_dic: @@ -460,19 +457,15 @@ def period(self, m): Mfac_dic[i0] += i1 Mfac = list(Mfac_dic.items()) - #Now use a fast order algorithm to compute the period. We know that the period divides - #M = i_1*i_2*...*i_l where the i_j denote not necessarily distinct prime factors. As - #F^M*v == v, for each i_j, if F^(M/i_j)*v == v, then the period divides (M/i_j). After - #all factors have been iterated over, the result is the period mod p. + # Now use a fast order algorithm to compute the period. We know that the period divides + # M = i_1*i_2*...*i_l where the i_j denote not necessarily distinct prime factors. As + # F^M*v == v, for each i_j, if F^(M/i_j)*v == v, then the period divides (M/i_j). After + # all factors have been iterated over, the result is the period mod p. Mfac = list(Mfac) - C = [] - #expand the list of prime factors so every factor is with multiplicity 1 - - for i0, i1 in Mfac: - for _ in range(i1): - C.append(i0) + # expand the list of prime factors so every factor is with multiplicity 1 + C = [i0 for i0, i1 in Mfac for _ in range(i1)] Mfac = C n = M @@ -482,7 +475,7 @@ def period(self, m): n = b perp = n - #Now compute the period mod p^e by stepping up by multiples of p + # Now compute the period mod p^e by stepping up by multiples of p F = A.change_ring(Integers(p**e)) v = w.change_ring(Integers(p**e)) FF = F**perp @@ -498,33 +491,32 @@ def period(self, m): break Periods[p] = perpe - #take the lcm of the periods mod all distinct primes dividing m - period = 1 - for p in Periods: - period = lcm(Periods[p], period) + # take the lcm of the periods mod all distinct primes dividing m + period = lcm(Periods.values()) - self._period_dict[m] = period #cache the period mod m + self._period_dict[m] = period # cache the period mod m return period def pthpowers(self, p, Bound): """ - Find the indices of proveably all pth powers in the recurrence sequence bounded by Bound. + Find the indices of proveably all `p`-th powers in the recurrence sequence + bounded by Bound. - Let `u_n` be a binary recurrence sequence. A ``p`` th power in `u_n` is a solution - to `u_n = y^p` for some integer `y`. There are only finitely many ``p`` th powers in - any recurrence sequence [SS1983]_. + Let `u_n` be a binary recurrence sequence. A ``p`` th power in `u_n` + is a solution to `u_n = y^p` for some integer `y`. There are only + finitely many ``p`` th powers in any recurrence sequence [SS1983]_. INPUT: - ``p`` -- a rational prime integer (the fixed p in `u_n = y^p`) - - ``Bound`` -- a natural number (the maximum index `n` in `u_n = y^p` that is checked). + - ``Bound`` -- a natural number (the maximum index `n` in `u_n = y^p` that is checked) OUTPUT: - - A list of the indices of all ``p`` th powers less bounded by - ``Bound``. If the sequence is degenerate and there are many - ``p`` th powers, raises :class:`ValueError`. + A list of the indices of all ``p`` th powers less bounded by + ``Bound``. If the sequence is degenerate and there are many + ``p`` th powers, raises :exc:`ValueError`. EXAMPLES:: @@ -541,7 +533,7 @@ def pthpowers(self, p, Bound): [1] If the sequence is degenerate, and there are no ``p`` th powers, returns `[]`. Otherwise, if - there are many ``p`` th powers, raises :class:`ValueError`. + there are many ``p`` th powers, raises :exc:`ValueError`. :: @@ -569,17 +561,17 @@ def pthpowers(self, p, Bound): This function is primarily optimized in the range where ``Bound`` is much larger than ``p``. """ - #Thanks to Jesse Silliman for helpful conversations! + # Thanks to Jesse Silliman for helpful conversations! - #Reset the dictionary of good primes, as this depends on p + # Reset the dictionary of good primes, as this depends on p self._PGoodness = {} - #Starting lower bound on good primes + # Starting lower bound on good primes self._ell = 1 - #If the sequence is geometric, then the `n`th term is `a*r^n`. Thus the - #property of being a ``p`` th power is periodic mod ``p``. So there are either - #no ``p`` th powers if there are none in the first ``p`` terms, or many if there - #is at least one in the first ``p`` terms. + # If the sequence is geometric, then the `n`th term is `a*r^n`. Thus the + # property of being a ``p`` th power is periodic mod ``p``. So there are either + # no ``p`` th powers if there are none in the first ``p`` terms, or many if there + # is at least one in the first ``p`` terms. if self.is_geometric() or self.is_quasigeometric(): no_powers = True @@ -594,50 +586,50 @@ def pthpowers(self, p, Bound): else: raise ValueError("the degenerate binary recurrence sequence is geometric or quasigeometric and has many pth powers") - #If the sequence is degenerate without being geometric or quasigeometric, there - #may be many ``p`` th powers or no ``p`` th powers. + # If the sequence is degenerate without being geometric or quasigeometric, there + # may be many ``p`` th powers or no ``p`` th powers. elif (self.b**2+4*self.c) == 0: - #This is the case if the matrix F is not diagonalizable, ie b^2 +4c = 0, and alpha/beta = 1. + # This is the case if the matrix F is not diagonalizable, ie b^2 +4c = 0, and alpha/beta = 1. alpha = self.b/2 - #In this case, u_n = u_0*alpha^n + (u_1 - u_0*alpha)*n*alpha^(n-1) = alpha^(n-1)*(u_0 +n*(u_1 - u_0*alpha)), - #that is, it is a geometric term (alpha^(n-1)) times an arithmetic term (u_0 + n*(u_1-u_0*alpha)). + # In this case, u_n = u_0*alpha^n + (u_1 - u_0*alpha)*n*alpha^(n-1) = alpha^(n-1)*(u_0 +n*(u_1 - u_0*alpha)), + # that is, it is a geometric term (alpha^(n-1)) times an arithmetic term (u_0 + n*(u_1-u_0*alpha)). - #Look at classes n = k mod p, for k = 1,...,p. + # Look at classes n = k mod p, for k = 1,...,p. for k in range(1, p + 1): - #The linear equation alpha^(k-1)*u_0 + (k+pm)*(alpha^(k-1)*u1 - u0*alpha^k) - #must thus be a pth power. This is a linear equation in m, namely, A + B*m, where + # The linear equation alpha^(k-1)*u_0 + (k+pm)*(alpha^(k-1)*u1 - u0*alpha^k) + # must thus be a pth power. This is a linear equation in m, namely, A + B*m, where A = (alpha**(k-1)*self.u0 + k*(alpha**(k-1)*self.u1 - self.u0*alpha**k)) B = p*(alpha**(k-1)*self.u1 - self.u0*alpha**k) - #This linear equation represents a pth power iff A is a pth power mod B. + # This linear equation represents a pth power iff A is a pth power mod B. if _is_p_power_mod(A, p, B): raise ValueError("the degenerate binary recurrence sequence has many pth powers") return [] - #We find ``p`` th powers using an elementary sieve. Term `u_n` is a ``p`` th - #power if and only if it is a ``p`` th power modulo every prime `\\ell`. This condition - #gives nontrivial information if ``p`` divides the order of the multiplicative group of - #`\\Bold(F)_{\\ell}`, i.e. if `\\ell` is ` 1 \mod{p}`, as then only `1/p` terms are ``p`` th - #powers modulo `\\ell``. + # We find ``p`` th powers using an elementary sieve. Term `u_n` is a ``p`` th + # power if and only if it is a ``p`` th power modulo every prime `\\ell`. This condition + # gives nontrivial information if ``p`` divides the order of the multiplicative group of + # `\\Bold(F)_{\\ell}`, i.e. if `\\ell` is ` 1 \mod{p}`, as then only `1/p` terms are ``p`` th + # powers modulo `\\ell``. - #Thus, given such an `\\ell`, we get a set of necessary congruences for the index modulo the - #the period of the sequence mod `\\ell`. Then we intersect these congruences for many primes - #to get a tight list modulo a growing modulus. In order to keep this step manageable, we - #only use primes `\\ell` that have particularly smooth periods. + # Thus, given such an `\\ell`, we get a set of necessary congruences for the index modulo the + # the period of the sequence mod `\\ell`. Then we intersect these congruences for many primes + # to get a tight list modulo a growing modulus. In order to keep this step manageable, we + # only use primes `\\ell` that have particularly smooth periods. - #Some congruences in the list will remain as the modulus grows. If a congruence remains through - #7 rounds of increasing the modulus, then we check if this corresponds to a perfect power (if - #it does, we add it to our list of indices corresponding to ``p`` th powers). The rest of the congruences - #are transient and grow with the modulus. Once the smallest of these is greater than the bound, - #the list of known indices corresponding to ``p`` th powers is complete. + # Some congruences in the list will remain as the modulus grows. If a congruence remains through + # 7 rounds of increasing the modulus, then we check if this corresponds to a perfect power (if + # it does, we add it to our list of indices corresponding to ``p`` th powers). The rest of the congruences + # are transient and grow with the modulus. Once the smallest of these is greater than the bound, + # the list of known indices corresponding to ``p`` th powers is complete. else: @@ -656,50 +648,50 @@ def pthpowers(self, p, Bound): for n in range(Bound): # n is the index of the a0 - #Check whether a0 is a perfect power mod ell + # Check whether a0 is a perfect power mod ell if _is_p_power_mod(a0, p, ell): - #if a0 is a perfect power mod ell, check if nth term is ppower + # if a0 is a perfect power mod ell, check if nth term is ppower if _is_p_power(self(n), p): powers.append(n) - a0, a1 = a1, bf*a1 + cf*a0 #step up the variables + a0, a1 = a1, bf*a1 + cf*a0 # step up the variables else: - powers = [] #documents the indices of the sequence that provably correspond to pth powers - cong = [0] #list of necessary congruences on the index for it to correspond to pth powers - Possible_count = {} #keeps track of the number of rounds a congruence lasts in cong + powers = [] # documents the indices of the sequence that provably correspond to pth powers + cong = [0] # list of necessary congruences on the index for it to correspond to pth powers + Possible_count = {} # keeps track of the number of rounds a congruence lasts in cong - #These parameters are involved in how we choose primes to increase the modulus - qqold = 1 #we believe that we know complete information coming from primes good by qqold - M1 = 1 #we have congruences modulo M1, this may not be the tightest list - M2 = p #we want to move to have congruences mod M2 - qq = 1 #the largest prime power divisor of M1 is qq + # These parameters are involved in how we choose primes to increase the modulus + qqold = 1 # we believe that we know complete information coming from primes good by qqold + M1 = 1 # we have congruences modulo M1, this may not be the tightest list + M2 = p # we want to move to have congruences mod M2 + qq = 1 # the largest prime power divisor of M1 is qq - #This loop ups the modulus. + # This loop ups the modulus. while True: - #Try to get good data mod M2 + # Try to get good data mod M2 - #patience of how long we should search for a "good prime" - patience = 0.01 * _estimated_time(lcm(M2, p*next_prime_power(qq)), M1, len(cong), p) + # patience of how long we should search for a "good prime" + patience = 0.01 * _estimated_time(lcm(M2, p * next_prime_power(qq)), + M1, len(cong), p) tries = 0 - #This loop uses primes to get a small set of congruences mod M2. + # This loop uses primes to get a small set of congruences mod M2. while True: - #only proceed if took less than patience time to find the next good prime + # only proceed if took less than patience time to find the next good prime ell = _next_good_prime(p, self, qq, patience, qqold) if ell: - #gather congruence data for the sequence mod ell, which will be mod period(ell) = modu + # gather congruence data for the sequence mod ell, which will be mod period(ell) = modu cong1, modu = _find_cong1(p, self, ell) - CongNew = [] # makes a new list from cong that is now mod M = lcm(M1, modu) instead of M1 + # makes a new list from cong that is now mod M = lcm(M1, modu) instead of M1 M = lcm(M1, modu) - for k in range(M // M1): - for i in cong: - CongNew.append(k * M1 + i) + CongNew = [k * M1 + i for k in range(M // M1) + for i in cong] cong = set(CongNew) M1 = M @@ -728,15 +720,15 @@ def pthpowers(self, p, Bound): cong = list(cong) break - #Document how long each element of cong has been there + # Document how long each element of cong has been there for i in cong: if i in Possible_count: Possible_count[i] += 1 else: Possible_count[i] = 1 - #Check how long each element has persisted, if it is for at least 7 cycles, - #then we check to see if it is actually a perfect power + # Check how long each element has persisted, if it is for at least 7 cycles, + # then we check to see if it is actually a perfect power for i in Possible_count: if Possible_count[i] == 7: n = Integer(i) @@ -744,7 +736,7 @@ def pthpowers(self, p, Bound): if _is_p_power(self(n), p): powers.append(n) - #check for a contradiction + # check for a contradiction if len(cong) > len(powers): if cong[len(powers)] > Bound: break @@ -755,19 +747,17 @@ def pthpowers(self, p, Bound): def _prime_powers(N): - """ - Find the prime powers dividing ``N``. + r""" + Find the prime powers dividing `N`. - In other words, if `N = q_1^(e_1)q_2^(e_2)...q_n^(e_n)`, it returns - `[q_1^(e_1),q_2^(e_2),...,q_n^(e_n)]`. + In other words, if `N = q_1^{e_1} q_2^{e_2} \cdots q_n^{e_n}`, it returns + `[q_1^{e_1}, q_2^{e_2}, \ldots, q_n^{e_n}]`. INPUT: - - ``N`` -- an integer + - ``N`` -- integer - OUTPUT: - - - A list of the prime powers dividing N. + OUTPUT: list of the prime powers dividing N EXAMPLES:: @@ -782,15 +772,13 @@ def _prime_powers(N): def _largest_ppower_divisor(N): """ - Find the largest prime power divisor of N. + Find the largest prime power divisor of `N`. INPUT: - - ``N`` -- an integer + - ``N`` -- integer - OUTPUT: - - The largest prime power dividing ``N``. + OUTPUT: the largest prime power dividing `N` EXAMPLES:: @@ -804,12 +792,12 @@ def _largest_ppower_divisor(N): def _goodness(n, R, p): """ - Return the goodness of ``n`` for the sequence ``R`` and the prime ``p`` -- that is the largest - non-``p`` prime power dividing ``period(n)``. + Return the goodness of `n` for the sequence `R` and the prime `p` -- that is the largest + non-`p` prime power dividing ``period(n)``. INPUT: - - ``n`` -- an integer + - ``n`` -- an integer - ``R`` -- an object in the class ``BinaryRecurrenceSequence`` @@ -837,9 +825,9 @@ def _goodness(n, R, p): def _next_good_prime(p, R, qq, patience, qqold): - """ - Find the next prime `\\ell` which is good by ``qq`` but not by ``qqold``, 1 mod ``p``, and for which - ``b^2+4*c`` is a square mod `\\ell`, for the sequence ``R`` if it is possible in runtime patience. + r""" + Find the next prime `\ell` which is good by ``qq`` but not by ``qqold``, 1 mod ``p``, and for which + ``b^2+4*c`` is a square mod `\ell`, for the sequence ``R`` if it is possible in runtime patience. INPUT: @@ -851,12 +839,11 @@ def _next_good_prime(p, R, qq, patience, qqold): - ``patience`` -- a real number - - ``qqold`` -- a perfect power less than or equal to ``qq`` - - OUTPUT: - - - A prime `\\ell` such that `\\ell` is 1 mod ``p``, ``b^2+4*c`` is a square mod `\\ell` and the period of `\\ell` has ``goodness`` by ``qq`` but not ``qqold``, if patience has not be surpased. Otherwise ``False``. + - ``qqold`` -- a perfect power less than or equal to ``qq`` + OUTPUT: a prime `\ell` such that `\ell` is 1 mod `p`, `b^2+4 c` is a + square mod `\ell` and the period of `\ell` has ``goodness`` by ``qq`` but + not ``qqold``, if patience has not be surpased; otherwise ``False`` EXAMPLES:: @@ -867,62 +854,57 @@ def _next_good_prime(p, R, qq, patience, qqold): 29 sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,2,100,2) #ran out of patience, as qqold == qq, so no primes work False - """ + # We are looking for pth powers in R. + # Our primes must be good by qq, but not qqold. + # We only allow patience number of iterations to find a good prime. - #We are looking for pth powers in R. - #Our primes must be good by qq, but not qqold. - #We only allow patience number of iterations to find a good prime. - - #The variable _ell for R keeps track of the last "good" prime returned - #that was not found from the dictionary _PGoodness + # The variable _ell for R keeps track of the last "good" prime returned + # that was not found from the dictionary _PGoodness - #First, we check to see if we have already computed the goodness of a prime that fits - #our requirement of being good by qq but not by qqold. This is stored in the _PGoodness - #dictionary. + # First, we check to see if we have already computed the goodness of a prime that fits + # our requirement of being good by qq but not by qqold. This is stored in the _PGoodness + # dictionary. - #Then if we have, we return the smallest such prime and delete it from the list. If not, we - #search through patience number of primes R._ell to find one good by qq but not qqold. If it is - #not good by either qqold or qq, then we add this prime to R._PGoodness under its goodness. + # Then if we have, we return the smallest such prime and delete it from the list. If not, we + # search through patience number of primes R._ell to find one good by qq but not qqold. If it is + # not good by either qqold or qq, then we add this prime to R._PGoodness under its goodness. - #Possible_Primes keeps track of possible primes satisfying our goodness requirements we might return - Possible_Primes = [] + # Possible_Primes keeps track of possible primes satisfying our goodness requirements we might return + # check to see if anything in R._PGoodness fits our goodness requirements + Possible_Primes = [item[0] for j, item in R._PGoodness.items() + if qqold < j <= qq and item] - #check to see if anything in R._PGoodness fits our goodness requirements - for j in R._PGoodness: - if (qqold < j <= qq) and len(R._PGoodness[j]): - Possible_Primes.append(R._PGoodness[j][0]) - - #If we found good primes, we take the smallest + # If we found good primes, we take the smallest if Possible_Primes: q = min(Possible_Primes) n = _goodness(q, R, p) - del R._PGoodness[n][0] #if we are going to use it, then we delete it from R._PGoodness + del R._PGoodness[n][0] # if we are going to use it, then we delete it from R._PGoodness return q - #If nothing is already stored in R._PGoodness, we start (from where we left off at R._ell) checking - #for good primes. We only tolerate patience number of tries before giving up. + # If nothing is already stored in R._PGoodness, we start (from where we left off at R._ell) checking + # for good primes. We only tolerate patience number of tries before giving up. else: i = 0 while i < patience: i += 1 R._ell = next_prime(R._ell) - #we require that R._ell is 1 mod p, so that p divides the order of the multiplicative - #group mod R._ell, so that not all elements of GF(R._ell) are pth powers. + # we require that R._ell is 1 mod p, so that p divides the order of the multiplicative + # group mod R._ell, so that not all elements of GF(R._ell) are pth powers. if R._ell % p == 1: - #requiring that b^2 + 4c is a square in GF(R._ell) ensures that the period mod R._ell - #divides R._ell - 1 - if legendre_symbol(R.b**2+4*R.c, R._ell) == 1: + # requiring that b^2 + 4c is a square in GF(R._ell) ensures that the period mod R._ell + # divides R._ell - 1 + if legendre_symbol(R.b**2 + 4*R.c, R._ell) == 1: N = _goodness(R._ell, R, p) - #proceed only if R._ell satisfies the goodness requirements + # proceed only if R._ell satisfies the goodness requirements if qqold < N <= qq: return R._ell - #if we do not use the prime, we store it in R._PGoodness + # if we do not use the prime, we store it in R._PGoodness else: if N in R._PGoodness: R._PGoodness[N].append(R._ell) @@ -942,15 +924,13 @@ def _is_p_power_mod(a, p, N): INPUT: - - ``a`` -- an integer + - ``a`` -- integer - ``p`` -- a rational prime number - - ``N`` -- a positive integer + - ``N`` -- positive integer - OUTPUT: - - - True if ``a`` is a ``p`` th power modulo ``N``; False otherwise. + OUTPUT: ``True`` if `a` is a `p`-th power modulo `N`; ``False`` otherwise EXAMPLES:: @@ -958,19 +938,17 @@ def _is_p_power_mod(a, p, N): False sage: sage.combinat.binary_recurrence_sequences._is_p_power_mod(2**3,3,29) True - """ - - #By the chinese remainder theorem, we can answer this question by examining whether - #a is a pth power mod q^e, for all distinct prime powers q^e dividing N. + # By the chinese remainder theorem, we can answer this question by examining whether + # a is a pth power mod q^e, for all distinct prime powers q^e dividing N. for q, e in N.factor(): - #If a = q^v*x, with + # If a = q^v*x, with v = a.valuation(q) - #then if v>=e, a is congruent to 0 mod q^e and is thus a pth power trivially. + # then if v>=e, a is congruent to 0 mod q^e and is thus a pth power trivially. if v >= e: continue @@ -979,58 +957,58 @@ def _is_p_power_mod(a, p, N): if v % p: return False - #in this cse it is a pth power if x is a pth power mod q^(e-v), so let x = aa, - #and (e-v) = ee: + # in this cse it is a pth power if x is a pth power mod q^(e-v), so let x = aa, + # and (e-v) = ee: - aa = a/q**v + aa = a / q**v ee = e - v - #The above steps are equivalent to the statement that we may assume a and qq are - #relatively prime, if we replace a with aa and e with ee. Now we must determine when - #aa is a pth power mod q^ee for (aa,q)=1. + # The above steps are equivalent to the statement that we may assume a and qq are + # relatively prime, if we replace a with aa and e with ee. Now we must determine when + # aa is a pth power mod q^ee for (aa,q)=1. - #If q != p, then by Hensel's lemma, we may lift a pth power mod q, to a pth power - #mod q^2, etc. + # If q != p, then by Hensel's lemma, we may lift a pth power mod q, to a pth power + # mod q^2, etc. if q != p: - #aa is necessarily a pth power mod q if p does not divide the order of the multiplicative - #group mod q, ie if q is not 1 mod p. + # aa is necessarily a pth power mod q if p does not divide the order of the multiplicative + # group mod q, ie if q is not 1 mod p. if q % p == 1: - #otherwise aa if a pth power mod q iff aa^(q-1)/p == 1 + # otherwise aa if a pth power mod q iff aa^(q-1)/p == 1 - if GF(q)(aa)**((q-1)/p) != 1: + if GF(q)(aa)**((q - 1) / p) != 1: return False - #If q = p and ee = 1, then everything is a pth power p by Fermat's little theorem. + # If q = p and ee = 1, then everything is a pth power p by Fermat's little theorem. elif ee > 1: - #We use the strong statement of Hensel's lemma, which implies that if p is odd - #and aa is a pth power mod p^2, then aa is a pth power mod any higher power of p + # We use the strong statement of Hensel's lemma, which implies that if p is odd + # and aa is a pth power mod p^2, then aa is a pth power mod any higher power of p if p % 2: - #ZZ/(p^2)ZZ^\times is abstractly isomorphic to ZZ/(p)ZZ cross ZZ/(p-1)ZZ. then - #aa is a pth power mod p^2 if (aa)^(p*(p-1)/p) == 1, ie if aa^(p-1) == 1. + # ZZ/(p^2)ZZ^\times is abstractly isomorphic to ZZ/(p)ZZ cross ZZ/(p-1)ZZ. then + # aa is a pth power mod p^2 if (aa)^(p*(p-1)/p) == 1, ie if aa^(p-1) == 1. - if Integers(p**2)(aa)**(p-1) != 1: + if Integers(p**2)(aa)**(p - 1) != 1: return False - #Otherwise, p=2. By the strong statement of Hensel's lemma, if aa is a pth power - #mod p^3, then it is a pth power mod higher powers of p. So we need only check if it - #is a pth power mod p^2 and p^3. + # Otherwise, p=2. By the strong statement of Hensel's lemma, if aa is a pth power + # mod p^3, then it is a pth power mod higher powers of p. So we need only check if it + # is a pth power mod p^2 and p^3. elif ee == 2: - #all odd squares a 1 mod 4 + # all odd squares a 1 mod 4 if aa % 4 != 1: return False - #all odd squares are 1 mod 8 + # all odd squares are 1 mod 8 elif aa % 8 != 1: return False @@ -1044,38 +1022,34 @@ def _estimated_time(M2, M1, length, p): INPUT: - - ``M2`` -- an integer (the new modulus) - - - ``M1`` -- an integer (the old modulus) + - ``M2`` -- integer; (the new modulus) - - ``length`` -- a list (the current length of the list of congruences mod ``M1``) + - ``M1`` -- integer; (the old modulus) - - ``p`` -- a prime + - ``length`` -- list (the current length of the list of congruences mod ``M1``) - OUTPUT: + - ``p`` -- a prime - - The estimated run time of the "CRT" step to combine consistent congruences. + OUTPUT: the estimated run time of the "CRT" step to combine consistent congruences EXAMPLES:: sage: from sage.combinat.binary_recurrence_sequences import _estimated_time sage: _estimated_time(2**4*3**2*5*7*11*13*17, 2**4*3**2*5*7*11*13, 20, 7) # needs sage.symbolic 106.211159309421 - """ + # The heuristic run time of the CRT step to go from modulus M1 to M2 - #The heuristic run time of the CRT step to go from modulus M1 to M2 + # length is the current length of cong - #length is the current length of cong + Q = p * log(M2) # Size of our primes. + NPrimes = log(M2 / M1) / log(Q) # The number of primes - Q = p * log(M2) #Size of our primes. - NPrimes = log(M2/M1) / log(Q) #The number of primes + return (length * (Q / p)**NPrimes).n() - return (length * (Q/p)**NPrimes).n() - -#Find the list of necessary congruences for the index n of binary recurrence -#sequence R using the fact that the reduction mod ell must be a pth power +# Find the list of necessary congruences for the index n of binary recurrence +# sequence R using the fact that the reduction mod ell must be a pth power def _find_cong1(p, R, ell): """ Find the list of permissible indices `n` for which `u_n = y^p` mod ``ell``. @@ -1103,54 +1077,54 @@ def _find_cong1(p, R, ell): u1 = F(R.u1) bf, cf = F(R.b), F(R.c) a0 = u0 - a1 = u1 #a0 and a1 are variables for terms in sequence + a1 = u1 # a0 and a1 are variables for terms in sequence - #The set of pth powers mod ell + # The set of pth powers mod ell PPowers = set(i**p for i in F) - #The period of R mod ell + # The period of R mod ell modu = R.period(ell) - #cong1 keeps track of congruences mod modu for the sequence mod ell + # cong1 keeps track of congruences mod modu for the sequence mod ell cong1 = [] - for n in range(modu): # n is the index of the a0 + for n in range(modu): # n is the index of the a0 - #Check whether a0 is a perfect power mod ell + # Check whether a0 is a perfect power mod ell if a0 in PPowers: - #if a0 is a perfect power mod ell, add the index - #to the list of necessary congruences + # if a0 is a perfect power mod ell, add the index + # to the list of necessary congruences cong1.append(n) - a0, a1 = a1, bf*a1 + cf*a0 #step up the variables + a0, a1 = a1, bf * a1 + cf * a0 # step up the variables cong1.sort() return cong1, modu -def _is_p_power(a, p): +def _is_p_power(a, p) -> bool: """ - Determine whether ``a`` is a perfect ``p`` th power. + Determine whether `a` is a perfect `p`-th power. INPUT: - - ``a`` -- an integer + - ``a`` -- integer - ``p`` -- a prime number - OUTPUT: - - - True if ``a`` is a ``p`` th power; else False. + OUTPUT: boolean EXAMPLES:: - sage: sage.combinat.binary_recurrence_sequences._is_p_power(2**7, 7) # needs sage.symbolic + sage: from sage.combinat.binary_recurrence_sequences import _is_p_power + sage: _is_p_power(2**7, 7) True - sage: sage.combinat.binary_recurrence_sequences._is_p_power(2**7*3**2, 7) # needs sage.symbolic + sage: _is_p_power(2**7*3**2, 7) False """ - return int(a**(1/p))**p == a - # slower tentative ? - # _, test = Integer(a).nth_root(p, truncate_mode=True) - # return test + try: + Integer(a).nth_root(p) + except ValueError: + return False + return True diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index 8373ae72ad1..0d018c18b00 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -65,8 +65,8 @@ class BinaryTree(AbstractClonableTree, ClonableArray, be shortened to ``BinaryTree([None,None])``. It is also allowed to abbreviate ``[None, None]`` by ``[]``. - - ``check`` -- (default: ``True``) whether check for binary should be - performed or not. + - ``check`` -- boolean (default: ``True``); whether check for binary should + be performed or not EXAMPLES:: @@ -707,10 +707,9 @@ def graph(self, with_leaves=True): INPUT: - - ``with_leaves`` -- (default: ``True``) a Boolean, determining - whether the resulting graph will be formed from the leaves - and the nodes of ``self`` (if ``True``), or only from the - nodes of ``self`` (if ``False``) + - ``with_leaves`` -- boolean (default: ``True``); whether the resulting + graph will be formed from the leaves and the nodes of ``self`` (if + ``True``), or only from the nodes of ``self`` (if ``False``) EXAMPLES:: @@ -870,7 +869,7 @@ def show(self, with_leaves=False): sage: t1.show() # needs sage.plot """ try: - self.graph(with_leaves=with_leaves).show(layout='tree', tree_root=0, tree_orientation="down") + self.graph(with_leaves=with_leaves).show(layout='tree', tree_root=0, tree_orientation='down') except RuntimeError: # This is for the border case BinaryTree().show(). self.graph(with_leaves=with_leaves).show() @@ -943,7 +942,7 @@ def make_leaf(self): self._require_mutable() self.__init__(self.parent(), None) - def _to_dyck_word_rec(self, usemap="1L0R"): + def _to_dyck_word_rec(self, usemap='1L0R'): r""" EXAMPLES:: @@ -1149,7 +1148,7 @@ def tamari_join(self, other): b = other.to_132_avoiding_permutation() return a.permutohedron_join(b).binary_search_tree_shape(left_to_right=False) - def tamari_meet(self, other, side="right"): + def tamari_meet(self, other, side='right'): r""" Return the meet of the binary trees ``self`` and ``other`` (of equal size) in the `n`-th Tamari poset (where `n` is @@ -1238,13 +1237,14 @@ def tamari_meet(self, other, side="right"): return from_tamari_sorting_tuple(meet) @combinatorial_map(name="to Dyck paths: up step, left tree, down step, right tree") - def to_dyck_word(self, usemap="1L0R"): + def to_dyck_word(self, usemap='1L0R'): r""" Return the Dyck word associated with ``self`` using the given map. INPUT: - - ``usemap`` -- a string, either ``1L0R``, ``1R0L``, ``L1R0``, ``R1L0`` + - ``usemap`` -- string; either ``'1L0R'``, ``'1R0L'``, ``'L1R0'``, + ``'R1L0'`` The bijection is defined recursively as follows: @@ -1294,7 +1294,7 @@ def to_dyck_word(self, usemap="1L0R"): raise ValueError("%s is not a correct map" % usemap) return DyckWord(self._to_dyck_word_rec(usemap)) - def _to_ordered_tree(self, bijection="left", root=None): + def _to_ordered_tree(self, bijection='left', root=None): r""" Internal recursive method to obtain an ordered tree from a binary tree. @@ -1304,16 +1304,16 @@ def _to_ordered_tree(self, bijection="left", root=None): sage: bt = BinaryTree([[],[]]) sage: bt._to_ordered_tree() [[], [[]]] - sage: bt._to_ordered_tree(bijection="right") + sage: bt._to_ordered_tree(bijection='right') [[[]], []] - sage: bt._to_ordered_tree(bijection="none") + sage: bt._to_ordered_tree(bijection='none') Traceback (most recent call last): ... ValueError: the bijection argument should be either left or right sage: bt = BinaryTree([[[], [[], None]], [[], []]]) sage: bt._to_ordered_tree() [[], [[], []], [[], [[]]]] - sage: bt._to_ordered_tree(bijection="right") + sage: bt._to_ordered_tree(bijection='right') [[[[]], [[]]], [[]], []] """ close_root = False @@ -1378,7 +1378,7 @@ def to_ordered_tree_right_branch(self): sage: bt.to_ordered_tree_right_branch() [[[[]], [[]]], [[]], []] """ - return self._to_ordered_tree(bijection="right") + return self._to_ordered_tree(bijection='right') def _postfix_word(self, left_first=True, start=1): r""" @@ -1426,7 +1426,7 @@ def tamari_sorting_tuple(self, reverse=False): INPUT: - - ``reverse`` -- boolean (default ``False``) if ``True``, + - ``reverse`` -- boolean (default: ``False``); if ``True``, return instead the result for the left-right symmetric of the binary tree @@ -1544,10 +1544,10 @@ def to_undirected_graph(self, with_leaves=False): INPUT: - - ``with_leaves`` -- (default: ``False``) a Boolean, determining - whether the resulting graph will be formed from the leaves - and the nodes of ``self`` (if ``True``), or only from the - nodes of ``self`` (if ``False``) + - ``with_leaves`` -- boolean (default: ``False``); whether the + resulting graph will be formed from the leaves and the nodes of + ``self`` (if ``True``), or only from the nodes of ``self`` (if + ``False``) EXAMPLES:: @@ -1592,9 +1592,7 @@ def to_tilting(self): method provides the coordinates of this depiction, with the root as the top-left vertex. - OUTPUT: - - a list of pairs of integers. + OUTPUT: list of pairs of integers Every vertex of the binary tree is mapped to a pair of integers. The conventions are the following. The root has @@ -1634,11 +1632,9 @@ def _to_tilting_rec(self, shift=0): INPUT: - - ``shift`` -- an integer (default 0) - - OUTPUT: + - ``shift`` -- integer (default: 0) - list of tilting coordinates and number of leaves + OUTPUT: list of tilting coordinates and number of leaves EXAMPLES:: @@ -1674,13 +1670,13 @@ def to_poset(self, with_leaves=False, root_to_leaf=False): INPUT: - - ``with_leaves`` -- (default: ``False``) a Boolean, determining - whether the resulting poset will be formed from the leaves - and the nodes of ``self`` (if ``True``), or only from the - nodes of ``self`` (if ``False``) - - ``root_to_leaf`` -- (default: ``False``) a Boolean, - determining whether the poset orientation should be from root - to leaves (if ``True``) or from leaves to root (if ``False``). + - ``with_leaves`` -- boolean (default: ``False``); whether the + resulting poset will be formed from the leaves and the nodes of + ``self`` (if ``True``), or only from the nodes of ``self`` (if + ``False``) + - ``root_to_leaf`` -- boolean (default: ``False``); whether the poset + orientation should be from root to leaves (if ``True``) or from + leaves to root (if ``False``) EXAMPLES:: @@ -2529,12 +2525,10 @@ def comb(self, side='left'): INPUT: - - ``side`` -- (default: 'left') set to 'left' to obtain a left - comb, and to 'right' to obtain a right comb. + - ``side`` -- (default: ``'left'``) set to ``'left'`` to obtain a left + comb, and to ``'right'`` to obtain a right comb - OUTPUT: - - A list of binary trees. + OUTPUT: list of binary trees .. SEEALSO:: @@ -2671,9 +2665,7 @@ def twisting_number(self): composing it. A left (resp. right) branch is maximal if it is not included in a strictly longer left (resp. right) branch. - OUTPUT: - - A list of two integers + OUTPUT: list of two integers EXAMPLES:: @@ -2822,7 +2814,7 @@ def q_hook_length_fraction(self, q=None, q_factor=False): set to be the indeterminate `q` in the polynomial ring `\ZZ[q]`) - - ``q_factor`` -- a Boolean (default: ``False``) which + - ``q_factor`` -- a Boolean (default: ``False``); which determines whether to compute `h_{q} (T)` or to compute `f_{q} (T)` (namely, `h_{q} (T)` is obtained when ``q_factor == False``, and `f_{q} (T)` is obtained when @@ -3674,9 +3666,7 @@ def to_full(self): `T` which does not have 2 children. The resulting tree will have `2n + 1` nodes. - OUTPUT: - - A full binary tree. See :meth:`is_full` for the definition of full. + OUTPUT: a full binary tree. See :meth:`is_full` for the definition of full .. SEEALSO:: @@ -3716,7 +3706,6 @@ def to_full(self): sage: BinaryTree(None).to_full() [., .] - """ if self.is_empty(): return BinaryTree("[.,.]") @@ -3738,9 +3727,7 @@ def prune(self): bt == bt.prune().to_full() - OUTPUT: - - A binary tree. + OUTPUT: a binary tree .. SEEALSO:: @@ -3938,8 +3925,8 @@ class BinaryTrees(UniqueRepresentation, Parent): INPUT: - - ``size`` -- (optional) an integer - - ``full`` -- (optional) a boolean + - ``size`` -- integer (optional) + - ``full`` -- boolean (optional) OUTPUT: @@ -4051,7 +4038,7 @@ def from_tamari_sorting_tuple(key): INPUT: - - ``key`` -- a tuple of integers + - ``key`` -- tuple of integers EXAMPLES:: @@ -4238,7 +4225,7 @@ def _an_element_(self): def cardinality(self): """ - The cardinality of ``self`` + The cardinality of ``self``. This is a Catalan number. @@ -4487,7 +4474,7 @@ def _an_element_(self): def cardinality(self): r""" - The cardinality of ``self`` + The cardinality of ``self``. This is a Catalan number. @@ -4641,10 +4628,10 @@ class LabelledBinaryTree(AbstractLabelledClonableTree, BinaryTree): anyway!). - ``label`` -- (default: ``None``) the label to be put on the root - of this tree. + of this tree - - ``check`` -- (default: ``True``) whether checks should be - performed or not. + - ``check`` -- boolean (default: ``True``); whether checks should be + performed or not .. TODO:: @@ -4656,7 +4643,7 @@ class LabelledBinaryTree(AbstractLabelledClonableTree, BinaryTree): sage: LabelledBinaryTree(None) . - sage: LabelledBinaryTree(None, label="ae") # not well supported + sage: LabelledBinaryTree(None, label='ae') # not well supported 'ae' sage: LabelledBinaryTree([]) None[., .] @@ -5195,7 +5182,7 @@ def _an_element_(self): t = LT([], label=3) t1 = LT([t, t], label=42) t2 = LT([[], []], label=5) - return LT([t1, t2], label="toto") + return LT([t1, t2], label='toto') def unlabelled_trees(self): """ @@ -5241,9 +5228,9 @@ def binary_search_tree_shape(w, left_to_right=True): INPUT: - - ``w`` -- a list of integers + - ``w`` -- list of integers - - ``left_to_right`` -- boolean (default ``True``) + - ``left_to_right`` -- boolean (default: ``True``) OUTPUT: a non labelled binary tree diff --git a/src/sage/combinat/cartesian_product.py b/src/sage/combinat/cartesian_product.py index ef151e55ffa..7bf3590550f 100644 --- a/src/sage/combinat/cartesian_product.py +++ b/src/sage/combinat/cartesian_product.py @@ -170,7 +170,7 @@ def __repr__(self): def cardinality(self): r""" - Returns the number of elements in the Cartesian product of + Return the number of elements in the Cartesian product of everything in \*iters. EXAMPLES:: @@ -200,7 +200,7 @@ def __len__(self): An ``int``, the number of elements in the Cartesian product. If the number of elements is infinite or does not fit into a python ``int``, a - :class:`TypeError` is raised. + :exc:`TypeError` is raised. .. SEEALSO:: @@ -225,7 +225,7 @@ def __len__(self): def list(self): """ - Returns + Return. EXAMPLES:: diff --git a/src/sage/combinat/chas/fsym.py b/src/sage/combinat/chas/fsym.py index 10210028932..b28307e1ed9 100644 --- a/src/sage/combinat/chas/fsym.py +++ b/src/sage/combinat/chas/fsym.py @@ -72,7 +72,7 @@ def __init__(self, alg, graded=True): CombinatorialFreeModule.__init__(self, alg.base_ring(), StandardTableaux(), category=FSymBases(alg), - bracket="", prefix=self._prefix) + bracket='', prefix=self._prefix) def _coerce_map_from_(self, R): r""" @@ -269,7 +269,7 @@ def basis(self, degree=None): r""" The basis elements (optionally: of the specified degree). - OUTPUT: Family + OUTPUT: family EXAMPLES:: @@ -351,7 +351,7 @@ def duality_pairing_matrix(self, basis, degree): INPUT: - ``basis`` -- a basis of the dual Hopf algebra - - ``degree`` -- a non-negative integer + - ``degree`` -- nonnegative integer OUTPUT: diff --git a/src/sage/combinat/chas/wqsym.py b/src/sage/combinat/chas/wqsym.py index 567e1f1b9f5..50811f08cb8 100644 --- a/src/sage/combinat/chas/wqsym.py +++ b/src/sage/combinat/chas/wqsym.py @@ -75,7 +75,7 @@ def sorting_key(X): OrderedSetPartitions(), category=WQSymBases(alg, graded), sorting_key=sorting_key, - bracket="", prefix=self._prefix) + bracket='', prefix=self._prefix) def _repr_term(self, osp): r""" @@ -549,12 +549,12 @@ class options(GlobalOptions): NAME = 'WordQuasiSymmetricFunctions element' module = 'sage.combinat.chas.wqsym' option_class = 'WordQuasiSymmetricFunctions' - objects = dict(default="compositions", + objects = dict(default='compositions', description='Specifies how basis elements of WordQuasiSymmetricFunctions should be indexed', values=dict(compositions="Indexing the basis by ordered set partitions", words="Indexing the basis by packed words"), case_sensitive=False) - display = dict(default="normal", + display = dict(default='normal', description='Specifies how basis elements of WordQuasiSymmetricFunctions should be printed', values=dict(normal="Using the normal representation", tight="Dropping spaces after commas", @@ -918,7 +918,7 @@ def __init__(self, alg): WQSymBasis_abstract.__init__(self, alg) X = self.realization_of().X() - phi = self.module_morphism(self._C_to_X, codomain=X, unitriangular="upper") + phi = self.module_morphism(self._C_to_X, codomain=X, unitriangular='upper') phi.register_as_coercion() inv_phi = ~phi inv_phi.register_as_coercion() @@ -1067,9 +1067,9 @@ def __init__(self, alg): WQSymBasis_abstract.__init__(self, alg) M = self.realization_of().M() - phi = self.module_morphism(self._Q_to_M, codomain=M, unitriangular="lower") + phi = self.module_morphism(self._Q_to_M, codomain=M, unitriangular='lower') phi.register_as_coercion() - phi_inv = M.module_morphism(self._M_to_Q, codomain=self, unitriangular="lower") + phi_inv = M.module_morphism(self._M_to_Q, codomain=self, unitriangular='lower') phi_inv.register_as_coercion() def some_elements(self): @@ -1449,9 +1449,9 @@ def __init__(self, alg): WQSymBasis_abstract.__init__(self, alg) M = self.realization_of().M() - phi = self.module_morphism(self._Phi_to_M, codomain=M, unitriangular="lower") + phi = self.module_morphism(self._Phi_to_M, codomain=M, unitriangular='lower') phi.register_as_coercion() - phi_inv = M.module_morphism(self._M_to_Phi, codomain=self, unitriangular="lower") + phi_inv = M.module_morphism(self._M_to_Phi, codomain=self, unitriangular='lower') phi_inv.register_as_coercion() def some_elements(self): @@ -2572,9 +2572,7 @@ def to_quasisymmetric_function(self): sizes of the blocks of `P`. This `\pi` is a ring homomorphism. - OUTPUT: - - - an element of the quasisymmetric functions in the monomial basis + OUTPUT: an element of the quasisymmetric functions in the monomial basis EXAMPLES:: diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index f26523cc60c..5ab85f84208 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -70,7 +70,7 @@ class ClusterSeed(SageObject): * :class:`QuiverMutationType` - * :class:`str` -- a string representing a :class:`QuiverMutationType` + * :class:`str` -- string representing a :class:`QuiverMutationType` or a common quiver type (see Examples) * :class:`ClusterQuiver` @@ -387,14 +387,16 @@ def __init__(self, data, frozen=None, is_principal=False, user_labels=None, user def use_c_vectors(self, use=True, bot_is_c=False, force=False): r""" - Reconstruct c-vectors from other data or initialize if no usable data exists. + Reconstruct `c`-vectors from other data or initialize if no usable data + exists. Warning: Initialization may lead to inconsistent data. INPUT: - - ``use`` -- (default: ``True``) If ``True``, will use c-vectors - - ``bot_is_c`` -- (default: ``False``) If ``True`` and + - ``use`` -- boolean (default: ``True``); if ``True``, will use + `c`-vectors + - ``bot_is_c`` -- boolean (default: ``False``); if ``True`` and :class:`ClusterSeed` ``self`` has ``self._m == self._n``, then will assume bottom half of the extended exchange matrix is the c-matrix. If ``True``, lets the :class:`ClusterSeed` know c-vectors can be @@ -470,7 +472,8 @@ def use_c_vectors(self, use=True, bot_is_c=False, force=False): def use_g_vectors(self, use=True, force=False): r""" - Reconstruct g-vectors from other data or initialize if no usable data exists. + Reconstruct g-vectors from other data or initialize if no usable data + exists. .. warning:: @@ -478,7 +481,8 @@ def use_g_vectors(self, use=True, force=False): INPUT: - - ``use`` -- (default: ``True``) If ``True``, will use g-vectors + - ``use`` -- boolean (default: ``True``); if ``True``, will use + g-vectors EXAMPLES:: @@ -554,7 +558,8 @@ def use_g_vectors(self, use=True, force=False): def use_d_vectors(self, use=True, force=False): r""" - Reconstruct d-vectors from other data or initialize if no usable data exists. + Reconstruct `d`-vectors from other data or initialize if no usable data + exists. .. warning:: @@ -562,7 +567,8 @@ def use_d_vectors(self, use=True, force=False): INPUT: - - ``use`` -- (default: ``True``) If ``True``, will use d-vectors + - ``use`` -- boolean (default: ``True``); if ``True``, will use + `d`-vectors EXAMPLES:: @@ -640,17 +646,18 @@ def use_d_vectors(self, use=True, force=False): def use_fpolys(self, use=True, user_labels=None, user_labels_prefix=None): r""" - Use F-polynomials in our Cluster Seed + Use `F`-polynomials in our Cluster Seed. Note: This will automatically try to recompute the cluster variables if possible INPUT: - - ``use`` -- (default: ``True``) If ``True``, will use F-polynomials - - ``user_labels`` -- (default: ``None``) If set, will overwrite the - default cluster variable labels - - ``user_labels_prefix`` -- (default: ``None``) If set, will overwrite + - ``use`` -- boolean (default: ``True``); if ``True``, will use + `F`-polynomials + - ``user_labels`` -- (default: ``None``) if set, will overwrite the + default cluster variable ``labels`` + - ``user_labels_prefix`` -- (default: ``None``) if set, will overwrite the default EXAMPLES:: @@ -746,7 +753,8 @@ def track_mutations(self, use=True): INPUT: - - ``use`` -- (default: ``True``) If ``True``, will begin filling the mutation path + - ``use`` -- boolean (default: ``True``); if ``True``, will begin + filling the mutation path EXAMPLES:: @@ -801,8 +809,8 @@ def _sanitize_init_vars(self, user_labels, user_labels_prefix='x'): INPUT: - - ``user_labels`` -- The labels that need sanitizing - - ``user_labels_prefix`` -- (default: ``'x'``) The prefix to use + - ``user_labels`` -- the labels that need sanitizing + - ``user_labels_prefix`` -- (default: ``'x'``) the prefix to use for labels if integers given for labels EXAMPLES:: @@ -870,9 +878,9 @@ def set_c_matrix(self, data): INPUT: - - ``data`` -- The matrix to set the c-matrix to. Also allowed + - ``data`` -- the matrix to set the c-matrix to; also allowed to be a quiver or cluster seed, in which case the b-matrix - is used. + is used EXAMPLES:: @@ -1026,18 +1034,18 @@ def plot(self, circular=False, mark=None, save_pos=False, force_c=False, with_gr INPUT: - - ``circular`` -- (default: ``False``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used - ``mark`` -- (default: ``None``) if set to i, the vertex i is - highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions - of the vertices are saved. - - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen - vertices even if they were never initialized - - ``with_greens`` -- (default: ``False``) if ``True``, will display - the green vertices in green - - ``add_labels`` -- (default: ``False``) if ``True``, will use the - initial variables as labels + highlighted + - ``save_pos`` -- boolean (default: ``False``); if ``True``, the + positions of the vertices are saved + - ``force_c`` -- boolean (default: ``False``); if ``True``, will show + the frozen vertices even if they were never initialized + - ``with_greens`` -- boolean (default: ``False``); if ``True``, will + display the green vertices in green + - ``add_labels`` -- boolean (default: ``False``); if ``True``, will use + the initial variables as labels EXAMPLES:: @@ -1071,19 +1079,19 @@ def show(self, fig_size=1, circular=False, mark=None, save_pos=False, force_c=Fa INPUT: - ``fig_size`` -- (default: 1) factor by which the size of the plot - is multiplied. - - ``circular`` -- (default: ``False``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. + is multiplied + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used - ``mark`` -- (default: ``None``) if set to i, the vertex i is - highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions - of the vertices are saved. - - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen - vertices even if they were never initialized - - ``with_greens`` -- (default: ``False``) if ``True``, will display the - green vertices in green - - ``add_labels`` -- (default: ``False``) if ``True``, will use the - initial variables as labels + highlighted + - ``save_pos`` -- boolean (default: ``False``); if ``True``, the + positions of the vertices are saved + - ``force_c`` -- boolean (default: ``False``); if ``True``, will show + the frozen vertices even if they were never initialized + - ``with_greens`` -- boolean (default: ``False``); if ``True``, will + display the green vertices in green + - ``add_labels`` -- boolean (default: ``False``); if ``True``, will use + the initial variables as labels TESTS:: @@ -1114,10 +1122,10 @@ def interact(self, fig_size=1, circular=True): INPUT: - ``fig_size`` -- (default: 1) factor by which the size of the - plot is multiplied. + plot is multiplied - - ``circular`` -- (default: ``True``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. + - ``circular`` -- boolean (default: ``True``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used TESTS:: @@ -1133,18 +1141,19 @@ def save_image(self, filename, circular=False, mark=None, save_pos=False): INPUT: - - ``filename`` -- the filename the image is saved to. - - ``circular`` -- (default: ``False``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. - - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions - of the vertices are saved. + - ``filename`` -- the filename the image is saved to + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used + - ``mark`` -- (default: ``None``) if set to i, the vertex i is + highlighted + - ``save_pos`` -- boolean (default: ``False``); if ``True``, the + positions of the vertices are saved EXAMPLES:: sage: S = ClusterSeed(['F',4,[1,2]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # needs sage.plot sage.symbolic + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # needs sage.plot sage.symbolic ....: S.save_image(f.name) """ graph_plot = self.plot(circular=circular, mark=mark, save_pos=save_pos) @@ -1212,7 +1221,7 @@ def x(self, k): sage: S.x(2) x2 - sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") + sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges') sage: S = ClusterSeed(dg, frozen=['c']) sage: S.x(0) a @@ -1251,7 +1260,7 @@ def y(self, k): sage: S.y(2) y2 - sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") + sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges') sage: S = ClusterSeed(dg, frozen=['c']) sage: S.y(0) c @@ -1358,7 +1367,7 @@ def mutations(self): def cluster_variable(self, k): r""" - Generates a cluster variable using F-polynomials + Generates a cluster variable using F-polynomials. EXAMPLES:: @@ -1708,7 +1717,6 @@ def c_vector(self, k): A seed for a cluster algebra of rank 2 with 2 frozen variables sage: S.c_vector(0) (1, -1) - """ if k not in range(self._n): raise ValueError("The cluster seed does not have a c-vector of index %s." % k) @@ -1858,7 +1866,6 @@ def _d_mutate(self, k): [ 0 0 -1] sage: S.d_vector(0) (1, 0, 0) - """ B = self.b_matrix() D = copy(self._D) @@ -1953,12 +1960,13 @@ def is_acyclic(self) -> bool: def is_bipartite(self, return_bipartition=False): r""" - Return ``True`` iff ``self`` is bipartite (i.e., if the underlying quiver is bipartite). + Return ``True`` iff ``self`` is bipartite (i.e., if the underlying + quiver is bipartite). INPUT: - - ``return_bipartition`` -- (default: ``False``) if ``True``, the - bipartition is returned in the case of ``self`` being bipartite. + - ``return_bipartition`` -- boolean (default: ``False``); if ``True``, + the bipartition is returned in the case of ``self`` being bipartite EXAMPLES:: @@ -1974,12 +1982,10 @@ def green_vertices(self): r""" Return the list of green vertices of ``self``. - A vertex is defined to be green if its c-vector has all non-positive + A vertex is defined to be green if its c-vector has all nonpositive entries. More information on green vertices can be found at [BDP2013]_ - OUTPUT: - - The green vertices as a list of integers. + OUTPUT: the green vertices as a list of integers EXAMPLES:: @@ -2000,7 +2006,7 @@ def first_green_vertex(self): r""" Return the first green vertex of ``self``. - A vertex is defined to be green if its c-vector has all non-positive entries. + A vertex is defined to be green if its c-vector has all nonpositive entries. More information on green vertices can be found at [BDP2013]_ EXAMPLES:: @@ -2025,12 +2031,10 @@ def red_vertices(self): r""" Return the list of red vertices of ``self``. - A vertex is defined to be red if its c-vector has all non-negative entries. + A vertex is defined to be red if its c-vector has all nonnegative entries. More information on red vertices can be found at [BDP2013]_. - OUTPUT: - - The red vertices as a list of integers. + OUTPUT: the red vertices as a list of integers EXAMPLES:: @@ -2044,7 +2048,6 @@ def red_vertices(self): sage: Q.mutate(1) sage: Q.red_vertices() [1] - """ # Make sure we have c vectors on if not self._use_c_vec: @@ -2056,7 +2059,7 @@ def first_red_vertex(self): r""" Return the first red vertex of ``self``. - A vertex is defined to be red if its c-vector has all non-negative entries. + A vertex is defined to be red if its c-vector has all nonnegative entries. More information on red vertices can be found at [BDP2013]_. EXAMPLES:: @@ -2069,7 +2072,6 @@ def first_red_vertex(self): sage: Q.mutate(1) sage: Q.first_red_vertex() 1 - """ # Make sure we have c vectors if not self._use_c_vec: @@ -2090,7 +2092,8 @@ def urban_renewals(self, return_first=False): INPUT: - - ``return_first`` -- (default: ``False``) if ``True``, will return the first urban renewal + - ``return_first`` -- boolean (default: ``False``); if ``True``, will + return the first urban renewal OUTPUT: @@ -2132,11 +2135,9 @@ def highest_degree_denominator(self, filter=None): INPUT: - - ``filter`` -- a list or iterable - - OUTPUT: + - ``filter`` -- list or iterable - An integer. + OUTPUT: integer EXAMPLES:: @@ -2181,7 +2182,7 @@ def smallest_c_vector(self): r""" Return the vertex with the smallest c-vector. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -2209,7 +2210,7 @@ def smallest_c_vector(self): def most_decreased_edge_after_mutation(self): r""" - Return the vertex that will produce the least degrees after mutation + Return the vertex that will produce the least degrees after mutation. EXAMPLES:: @@ -2237,7 +2238,7 @@ def most_decreased_edge_after_mutation(self): def most_decreased_denominator_after_mutation(self): r""" - Return the vertex that will produce the most decrease in denominator degrees after mutation + Return the vertex that will produce the most decrease in denominator degrees after mutation. EXAMPLES:: @@ -2273,32 +2274,32 @@ def mutate(self, sequence, inplace=True, input_type=None): ``self``, a function which takes in the :class:`ClusterSeed` and returns a vertex or an iterator of vertices, or a string representing a type of vertices to mutate - - ``inplace`` -- (default: ``True``) if ``False``, the result is - returned, otherwise ``self`` is modified + - ``inplace`` -- boolean (default: ``True``); if ``False``, the result + is returned, otherwise ``self`` is modified - ``input_type`` -- (default: ``None``) indicates the type of data contained in the sequence Possible values for vertex types in ``sequence`` are: - - ``"first_source"``: mutates at first found source vertex, - - ``"sources"``: mutates at all sources, - - ``"first_sink"``: mutates at first sink, - - ``"sinks"``: mutates at all sink vertices, - - ``"green"``: mutates at the first green vertex, - - ``"red"``: mutates at the first red vertex, - - ``"urban_renewal"`` or ``"urban"``: mutates at first urban renewal vertex, - - ``"all_urban_renewals"`` or ``"all_urban"``: mutates at all - urban renewal vertices. + - ``'first_source'`` -- mutates at first found source vertex + - ``'sources'`` -- mutates at all sources + - ``'first_sink'`` -- mutates at first sink + - ``'sinks'`` -- mutates at all sink vertices + - ``'green'`` -- mutates at the first green vertex + - ``'red'`` -- mutates at the first red vertex + - ``'urban_renewal'`` or ``'urban'`` -- mutates at first urban renewal vertex + - ``'all_urban_renewals'`` or ``'all_urban'`` -- mutates at all + urban renewal vertices For ``input_type``, if no value is given, preference will be given to vertex names, then indices, then cluster variables. If all input is not of the same type, an error is given. Possible values for ``input_type`` are: - - ``"vertices"``: interprets the input sequence as vertices - - ``"indices"``: interprets the input sequence as indices - - ``"cluster_vars"``: interprets the input sequence as cluster variables - this must be selected if inputting a sequence of cluster variables. + - ``'vertices'`` -- interprets the input sequence as vertices + - ``'indices'`` -- interprets the input sequence as indices + - ``'cluster_vars'`` -- interprets the input sequence as cluster variables. + This must be selected if inputting a sequence of cluster variables. EXAMPLES:: @@ -2431,7 +2432,7 @@ def mutate(self, sequence, inplace=True, input_type=None): Mutating at vertices by default. sage: S.cluster() [(x2 + 1)/x1, x2, c] - sage: S.mutate(1, input_type="indices") + sage: S.mutate(1, input_type='indices') sage: S.cluster() [(x2 + 1)/x1, (x2*c + x1 + c)/(x1*x2), c] @@ -2444,7 +2445,7 @@ def mutate(self, sequence, inplace=True, input_type=None): Mutating at vertices by default. sage: S.cluster() [(a*c*d + 1)/b, a, c, d] - sage: S.mutate('a', input_type="cluster_vars") + sage: S.mutate('a', input_type='cluster_vars') sage: S.cluster() [(a*c*d + 1)/b, (a*c*d + b + 1)/(a*b), c, d] sage: S.mutate(['(a*c*d + 1)/b', 'd']) @@ -2608,7 +2609,7 @@ def mutate(self, sequence, inplace=True, input_type=None): index_list = [] for cluster_var in seqq: new_index = mutation_seed.cluster_index(cluster_var) - mutation_seed.mutate(new_index, input_type="indices") + mutation_seed.mutate(new_index, input_type='indices') index_list.append(new_index) except (ValueError, TypeError): raise ValueError('input interpreted as cluster variables,' @@ -2677,9 +2678,7 @@ def cluster_index(self, cluster_str): - ``cluster_str`` -- the string to look for in the cluster - OUTPUT: - - An integer or ``None`` if the string is not a cluster variable + OUTPUT: integer or ``None`` if the string is not a cluster variable EXAMPLES:: @@ -2687,7 +2686,6 @@ def cluster_index(self, cluster_str): sage: S.cluster_index('x') sage: S.cluster_index('(y+1)/x') 0 - """ if self._use_fpolys and isinstance(cluster_str, str): c = FractionField(self._R)(cluster_str) @@ -2709,24 +2707,24 @@ def mutation_sequence(self, sequence, show_sequence=False, INPUT: - - ``sequence`` -- an iterable of vertices of self. + - ``sequence`` -- an iterable of vertices of self - - ``show_sequence`` -- (default: ``False``) if ``True``, a png - containing the associated quivers is shown. + - ``show_sequence`` -- boolean (default: ``False``); if ``True``, a png + containing the associated quivers is shown - ``fig_size`` -- (default: 1.2) factor by which the size of - the plot is multiplied. + the plot is multiplied - ``return_output`` -- (default: ``'seed'``) determines what output is to be returned: * if ``'seed'``, outputs all the cluster seeds obtained - by the ``sequence`` of mutations. + by the ``sequence`` of mutations - * if ``'matrix'``, outputs a list of exchange matrices. + * if ``'matrix'``, outputs a list of exchange matrices * if ``'var'``, outputs a list of new cluster variables obtained - at each step. + at each step EXAMPLES:: @@ -2768,34 +2766,35 @@ def mutation_sequence(self, sequence, show_sequence=False, def mutation_analysis(self, options=['all'], filter=None): r""" - Runs an analysis of all potential mutation options. Note that this might take a long time on large seeds. + Run an analysis of all potential mutation options. Note that this might + take a long time on large seeds. - .. note:: + .. NOTE:: Edges are only returned if we have a non-valued quiver. Green and red vertices are only returned if the cluster is principal. INPUT: - - ``options`` -- (default: ``['all']``) a list of mutation options. - - ``filter`` -- (default: ``None``) A vertex or interval of vertices to limit our search to + - ``options`` -- (default: ``['all']``) a list of mutation options + - ``filter`` -- (default: ``None``) a vertex or interval of vertices to limit our search to Possible options are: - - ``"all"`` -- All options below - - ``"edges"`` -- Number of edges (works with skew-symmetric quivers) - - ``"edge_diff"`` -- Edges added/deleted (works with skew-symmetric quivers) - - ``"green_vertices"`` -- List of green vertices (works with principals) - - ``"green_vertices_diff"`` -- Green vertices added/removed (works with principals) - - ``"red_vertices"`` -- List of red vertices (works with principals) - - ``"red_vertices_diff"`` -- Red vertices added/removed (works with principals) - - ``"urban_renewals"`` -- List of urban renewal vertices - - ``"urban_renewals_diff"`` -- Urban renewal vertices added/removed - - ``"sources"`` -- List of source vertices - - ``"sources_diff"`` -- Source vertices added/removed - - ``"sinks"`` -- List of sink vertices - - ``"sinks_diff"`` -- Sink vertices added/removed - - ``"denominators"`` -- List of all denominators of the cluster variables + - ``'all'`` -- all options below + - ``'edges'`` -- number of edges (works with skew-symmetric quivers) + - ``'edge_diff'`` -- edges added/deleted (works with skew-symmetric quivers) + - ``'green_vertices'`` -- list of green vertices (works with principals) + - ``'green_vertices_diff'`` -- green vertices added/removed (works with principals) + - ``'red_vertices'`` -- list of red vertices (works with principals) + - ``'red_vertices_diff'`` -- red vertices added/removed (works with principals) + - ``'urban_renewals'`` -- list of urban renewal vertices + - ``'urban_renewals_diff'`` -- urban renewal vertices added/removed + - ``'sources'`` -- list of source vertices + - ``'sources_diff'`` -- source vertices added/removed + - ``'sinks'`` -- list of sink vertices + - ``'sinks_diff'`` -- sink vertices added/removed + - ``'denominators'`` -- list of all denominators of the cluster variables OUTPUT: @@ -3022,7 +3021,6 @@ def exchangeable_part(self): sage: T.exchangeable_part().quiver().digraph().edges(sort=True) [(0, 1, (1, -1)), (2, 1, (1, -1))] - """ from sage.combinat.cluster_algebra_quiver.mutation_class import _principal_part eval_dict = {self.y(i): 1 for i in range(self._m)} @@ -3259,7 +3257,7 @@ def reorient(self, data): def set_cluster(self, cluster, force=False): r""" - Sets the cluster for ``self`` to ``cluster``. + Set the cluster for ``self`` to ``cluster``. .. warning:: @@ -3267,7 +3265,7 @@ def set_cluster(self, cluster, force=False): INPUT: - - ``cluster`` -- an iterable defining a cluster for ``self``. + - ``cluster`` -- an iterable defining a cluster for ``self`` EXAMPLES:: @@ -3420,16 +3418,17 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, INPUT: - ``depth`` -- (default: infinity) integer or infinity, only seeds with - distance at most ``depth`` from ``self`` are returned. - - ``show_depth`` -- (default: ``False``) if ``True``, the current depth - of the mutation is shown while computing. - - ``return_paths`` -- (default: ``False``) if ``True``, a shortest path - of mutations from ``self`` to the given quiver is returned as well. - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only one - seed up to simultaneous permutation of rows and columns of the - exchange matrix is recorded. - - ``sink_source`` -- (default: ``False``) if ``True``, only mutations - at sinks and sources are applied. + distance at most ``depth`` from ``self`` are returned + - ``show_depth`` -- boolean (default: ``False``); if ``True``, the + current depth of the mutation is shown while computing + - ``return_paths`` -- boolean (default: ``False``); if ``True``, a + shortest path of mutations from ``self`` to the given quiver is + returned as well + - ``up_to_equivalence`` -- boolean (default: ``True``); if ``True``, + only one seed up to simultaneous permutation of rows and columns of + the exchange matrix is recorded + - ``sink_source`` -- boolean (default: ``False``); if ``True``, only + mutations at sinks and sources are applied EXAMPLES: @@ -3577,7 +3576,7 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, # If we aren't only sinking the source if not only_sink_source or all(entry >= 0 for entry in sd[0]._M.row(i)) or all(entry <= 0 for entry in sd[0]._M.row(i)): # do an inplace mutation on our cluster (sd[0]) - sd2 = sd[0].mutate(i, inplace=False, input_type="indices") + sd2 = sd[0].mutate(i, inplace=False, input_type='indices') # set up our new cluster variables if up_to_equivalence: @@ -3624,17 +3623,17 @@ def mutation_class(self, depth=infinity, show_depth=False, return_paths=False, INPUT: - - ``depth`` -- (default: ``infinity`) integer, only seeds with + - ``depth`` -- (default: ``infinity``) integer, only seeds with distance at most depth from ``self`` are returned - - ``show_depth`` -- (default: ``False``) if ``True``, the actual depth - of the mutation is shown - - ``return_paths`` -- (default: ``False``) if ``True``, a shortest - path of mutation sequences from self to the given quiver is + - ``show_depth`` -- boolean (default: ``False``); if ``True``, the + actual depth of the mutation is shown + - ``return_paths`` -- boolean (default: ``False``); if ``True``, a + shortest path of mutation sequences from self to the given quiver is returned as well - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only - seeds up to equivalence are considered - - ``sink_source`` -- (default: ``False``) if ``True``, only mutations - at sinks and sources are applied + - ``up_to_equivalence`` -- boolean (default: ``True``); if ``True``, + only seeds up to equivalence are considered + - ``sink_source`` -- boolean (default: ``False``); if ``True``, only + mutations at sinks and sources are applied EXAMPLES: @@ -3656,11 +3655,12 @@ def cluster_class_iter(self, depth=infinity, show_depth=False, up_to_equivalence - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned - - ``show_depth`` -- (default: ``False``) if ``True``, ignored if - ``depth`` is set; returns the depth of the mutation class, i.e., the - maximal distance from ``self`` of an element in the mutation class - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only - clusters up to equivalence are considered. + - ``show_depth`` -- boolean (default: ``False``); if ``True``, ignored + if ``depth`` is set; returns the depth of the mutation class, i.e., + the maximal distance from ``self`` of an element in the mutation + class + - ``up_to_equivalence`` -- boolean (default: ``True``); if ``True``, + only clusters up to equivalence are considered EXAMPLES: @@ -3735,7 +3735,7 @@ def cluster_class_iter(self, depth=infinity, show_depth=False, up_to_equivalence For a cluster seed from an arbitrarily labelled digraph:: - sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") + sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges') sage: S = ClusterSeed(dg, frozen=['b']) sage: S.cluster_class() [[a, c], [a, (b + 1)/c], [(b + 1)/a, c], [(b + 1)/a, (b + 1)/c]] @@ -3756,11 +3756,11 @@ def cluster_class(self, depth=infinity, show_depth=False, up_to_equivalence=True - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned - - ``return_depth`` -- (default: ``False``); if ``True``, ignored if + - ``return_depth`` -- (default: ``False``) if ``True``, ignored if ``depth`` is set; returns the depth of the mutation class, i.e., the maximal distance from ``self`` of an element in the mutation class - - ``up_to_equivalence`` -- (default: ``True``); if ``True``, only - clusters up to equivalence are considered. + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only + clusters up to equivalence are considered EXAMPLES: @@ -3777,14 +3777,15 @@ def cluster_class(self, depth=infinity, show_depth=False, up_to_equivalence=True def b_matrix_class_iter(self, depth=infinity, up_to_equivalence=True): r""" - Return an iterator through all `B`-matrices in the mutation class of ``self``. + Return an iterator through all `B`-matrices in the mutation class of + ``self``. INPUT: - - ``depth`` -- (default:infinity) integer or infinity, only seeds + - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only - `B`-matrices up to equivalence are considered. + - ``up_to_equivalence`` -- boolean (default: ``True``); if ``True``, + only `B`-matrices up to equivalence are considered EXAMPLES: @@ -3868,7 +3869,7 @@ def b_matrix_class_iter(self, depth=infinity, up_to_equivalence=True): For a cluster seed from an arbitrarily labelled digraph:: - sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") + sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges') sage: S = ClusterSeed(dg, frozen=['b']) sage: S.b_matrix_class() [ @@ -3888,8 +3889,8 @@ def b_matrix_class(self, depth=infinity, up_to_equivalence=True): - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only - `B`-matrices up to equivalence are considered. + - ``up_to_equivalence`` -- boolean (default: ``True``); if ``True``, + only `B`-matrices up to equivalence are considered EXAMPLES: @@ -3907,14 +3908,15 @@ def b_matrix_class(self, depth=infinity, up_to_equivalence=True): def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): r""" - Return an iterator for all cluster variables in the mutation class of ``self``. + Return an iterator for all cluster variables in the mutation class of + ``self``. INPUT: - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned - - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, - the algorithm does not use the bipartite belt + - ``ignore_bipartite_belt`` -- boolean (default: ``False``); if + ``True``, the algorithm does not use the bipartite belt EXAMPLES: @@ -4044,8 +4046,8 @@ def variable_class(self, depth=infinity, ignore_bipartite_belt=False): - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned - - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, the - algorithm does not use the bipartite belt + - ``ignore_bipartite_belt`` -- boolean (default: ``False``); if + ``True``, the algorithm does not use the bipartite belt EXAMPLES: @@ -4089,15 +4091,15 @@ def is_finite(self) -> bool: def is_mutation_finite(self, nr_of_checks=None, return_path=False): r""" - Return True if ``self`` is of finite mutation type. + Return ``True`` if ``self`` is of finite mutation type. INPUT: - - ``nr_of_checks`` -- (default: ``None``) number of mutations applied. - Standard is 500 times the number of vertices of ``self``. - - ``return_path`` -- (default: ``False``) if ``True``, in case of - ``self`` not being mutation finite, a path from ``self`` to a quiver - with an edge label `(a,-b)` and `a*b > 4` is returned. + - ``nr_of_checks`` -- (default: ``None``) number of mutations applied; + standard is 500 times the number of vertices of ``self`` + - ``return_path`` -- boolean (default: ``False``); if ``True``, in case + of ``self`` not being mutation finite, a path from ``self`` to a + quiver with an edge label `(a,-b)` and `a*b > 4` is returned ALGORITHM: @@ -4200,7 +4202,7 @@ def mutation_type(self): def greedy(self, a1, a2, algorithm='by_recursion'): r""" - Return the greedy element `x[a_1,a_2]` assuming that self is rank two. + Return the greedy element `x[a_1,a_2]` assuming that ``self`` is rank two. The third input can be ``'by_recursion'``, ``'by_combinatorics'``, or ``'just_numbers'`` to specify if the user wants the element @@ -4373,8 +4375,8 @@ def find_upper_bound(self, verbose=False): INPUT: - - ``verbose`` -- (default: ``False``) if ``True``, prints output - during the computation. + - ``verbose`` -- boolean (default: ``False``); if ``True``, prints + output during the computation EXAMPLES: @@ -4463,19 +4465,19 @@ def find_upper_bound(self, verbose=False): def get_upper_cluster_algebra_element(self, a): r""" - Compute an element in the upper cluster algebra of `B` corresponding to the vector `a \in \ZZ^n`. + Compute an element in the upper cluster algebra of `B` corresponding to + the vector `a \in \ZZ^n`. See [LLM2014]_ for more details. INPUT: - ``B`` -- a skew-symmetric matrix. Must have the same number of columns - as the length of the vectors in `vd`. - - ``a`` -- a vector in `\ZZ^n` where `n` is the number of columns in `B`. + as the length of the vectors in `vd` + - ``a`` -- a vector in `\ZZ^n` where `n` is the number of columns in `B` - OUTPUT: - - Return an element in the upper cluster algebra. Depending on the input it may or may not be irreducible. + OUTPUT: an element in the upper cluster algebra. Depending on the input + it may or may not be irreducible EXAMPLES:: @@ -4519,13 +4521,11 @@ def LLM_gen_set(self, size_limit=-1): INPUT: - - ``B`` -- a skew-symmetric matrix. + - ``B`` -- a skew-symmetric matrix - ``size_limit`` -- a limit on how many vectors you want - the function to return. - - OUTPUT: + the function to return - An array of elements in the upper cluster algebra. + OUTPUT: an array of elements in the upper cluster algebra EXAMPLES:: @@ -4563,14 +4563,13 @@ def _compute_compatible_vectors(self, vd): INPUT: - ``B`` -- a skew-symmetric matrix. Must have the same number of columns - as the length of the vectors in ``vd``. + as the length of the vectors in ``vd`` - ``vd`` -- a collection of tuples `(v,z)` with `v \in \{0,1\}^n` and `z \in \ZZ`. `n` must be the number of columns in `B`. Taken from the output of :func:`_vector_decomposition`. - OUTPUT: - - a 2-dimensional array containing all the vectors compatible with each vector in ``vd.`` + OUTPUT: a 2-dimensional array containing all the vectors compatible + with each vector in ``vd.`` .. NOTE:: @@ -4640,7 +4639,7 @@ def _compute_compatible_vectors(self, vd): if any(am < 0 for am in a[0]): compatibleList.append([]) continue - # If the vector a in vd is non-positive, it is not compatible + # If the vector a in vd is nonpositive, it is not compatible # with any vector. 0 vector will pass this check but will be # handled later. clist = [] @@ -4660,7 +4659,8 @@ def _compute_compatible_vectors(self, vd): def _produce_upper_cluster_algebra_element(self, vd, cList): r""" - Takes the compatible vectors and uses them to produce a Laurent polynomial in the upper cluster algebra. + Take the compatible vectors and uses them to produce a Laurent + polynomial in the upper cluster algebra. EXAMPLES:: @@ -4899,7 +4899,7 @@ def get_green_vertices(C): INPUT: - - ``C`` -- The C-matrix to check + - ``C`` -- the C-matrix to check EXAMPLES:: @@ -4920,7 +4920,7 @@ def get_red_vertices(C): INPUT: - - ``C`` -- The C-matrix to check + - ``C`` -- the C-matrix to check EXAMPLES:: @@ -4938,7 +4938,7 @@ def _vector_decomposition(a, length): INPUT: - - `a` -- a vector in `\ZZ^n` + - ``a`` -- a vector in `\ZZ^n` OUTPUT: @@ -5029,7 +5029,7 @@ def _power_set(n): INPUT: - - `n` -- an integer. + - ``n`` -- integer OUTPUT: @@ -5089,12 +5089,10 @@ def _multi_concatenate(l1, l2): INPUT: - -`l1` -- a 2-dimensional array. - -`l2` -- a single array. - - OUTPUT: + - ``l1`` -- a 2-dimensional array + - ``l2`` -- a single array - A 2-dimensional array. + OUTPUT: a 2-dimensional array EXAMPLES:: diff --git a/src/sage/combinat/cluster_algebra_quiver/interact.py b/src/sage/combinat/cluster_algebra_quiver/interact.py index 695e3d1d449..834e8a38d44 100644 --- a/src/sage/combinat/cluster_algebra_quiver/interact.py +++ b/src/sage/combinat/cluster_algebra_quiver/interact.py @@ -16,12 +16,12 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'): INPUT: - ``fig_size`` -- (default: 1) factor by which the size of the - plot is multiplied. + plot is multiplied - - ``circular`` -- (default: ``True``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. + - ``circular`` -- boolean (default: ``True``); if ``True``, the circular + plot is chosen, otherwise >>spring<< is used - - ``kind`` -- either ``"seed"`` (default) or ``"quiver"`` + - ``kind`` -- either ``'seed'`` (default) or ``'quiver'`` TESTS:: diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_class.py b/src/sage/combinat/cluster_algebra_quiver/mutation_class.py index 7d7b2720695..9a85542100f 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_class.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_class.py @@ -35,9 +35,7 @@ def _principal_part(mat): - ``mat`` -- a matrix with at least as many rows as columns - OUTPUT: - - The top square part of the matrix ``mat``. + OUTPUT: the top square part of the matrix ``mat`` EXAMPLES:: @@ -70,7 +68,7 @@ def _digraph_mutate(dg, k, frozen=None): - ``dg`` -- a digraph with integral edge labels with ``n+m`` vertices - ``k`` -- the vertex at which ``dg`` is mutated - - ``frozen`` -- the list of frozen vertices (default is the empty list) + - ``frozen`` -- the list of frozen vertices (default: empty list) EXAMPLES:: @@ -199,9 +197,7 @@ def _dg_canonical_form(dg, frozen=None): - ``frozen`` -- list (default: ``[]``) of frozen vertices - OUTPUT: - - - dictionary {original label: canonical label} + OUTPUT: dictionary {original label: canonical label} - list of orbits of mutable vertices (using canonical labels) @@ -283,12 +279,17 @@ def _mutation_class_iter( dg, n, m, depth=infinity, return_dig6=False, show_dept INPUT: - - ``dg`` -- a digraph with n+m vertices - - ``depth`` -- a positive integer or infinity specifying (roughly) how many steps away from the initial seed to mutate - - ``return_dig6`` -- indicates whether to convert digraph data to dig6 string data - - ``show_depth`` -- if True, indicates that a running count of the depth is to be displayed - - ``up_to_equivalence`` -- if True, only one digraph for each graph-isomorphism class is recorded - - ``sink_source`` -- if True, only mutations at sinks or sources are applied + - ``dg`` -- a digraph with `n+m` vertices + - ``depth`` -- positive integer or infinity specifying (roughly) how many + steps away from the initial seed to mutate + - ``return_dig6`` -- indicates whether to convert digraph data to dig6 + string data + - ``show_depth`` -- if ``True``, indicates that a running count of the + depth is to be displayed + - ``up_to_equivalence`` -- if ``True``, only one digraph for each + graph-isomorphism class is recorded + - ``sink_source`` -- if ``True``, only mutations at sinks or sources are + applied EXAMPLES:: @@ -387,7 +388,8 @@ def _digraph_to_dig6(dg, hashable=False): INPUT: - ``dg`` -- a digraph - - ``hashable`` -- (Boolean; optional; default: ``False``) if ``True``, the edge labels are turned into a dict. + - ``hashable`` -- boolean (default: ``False``); if ``True``, the edge + labels are turned into a dict EXAMPLES:: @@ -467,7 +469,7 @@ def _dig6_to_matrix( dig6 ): def _dg_is_sink_source( dg, v ): """ - Return True iff the digraph dg has a sink or a source at vertex v. + Return ``True`` iff the digraph dg has a sink or a source at vertex `v`. INPUT: @@ -540,7 +542,7 @@ def _graph_without_edge_labels(dg, vertices): def _has_two_cycles( dg ): """ - Return True if the input digraph has a 2-cycle and False otherwise. + Return ``True`` if the input digraph has a 2-cycle and ``False`` otherwise. EXAMPLES:: @@ -560,11 +562,13 @@ def _has_two_cycles( dg ): def _is_valid_digraph_edge_set( edges, frozen=0 ): """ - Return True if the input data is the edge set of a digraph for a quiver (no loops, no 2-cycles, edge-labels of the specified format), and returns False otherwise. + Return ``True`` if the input data is the edge set of a digraph for a quiver + (no loops, no 2-cycles, edge-labels of the specified format), and return + ``False`` otherwise. INPUT: - - ``frozen`` -- (integer; default:0) The number of frozen vertices. + - ``frozen`` -- integer (default: 0); the number of frozen vertices EXAMPLES:: diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py index 6c5edc6aa3f..8a366c81053 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py @@ -44,7 +44,8 @@ def is_mutation_finite(M, nr_of_checks=None): INPUT: - - ``nr_of_checks`` -- (default: ``None``) number of mutations applied. Standard is 500*(number of vertices of self). + - ``nr_of_checks`` -- number of mutations applied (default: ``None``); + standard is 500*(number of vertices of self) ALGORITHM: @@ -809,9 +810,9 @@ def _connected_mutation_type_AAtildeD(dg, ret_conn_vert=False): INPUT: - - ``ret_conn_vert`` -- boolean (default: ``False``). If ``True``, + - ``ret_conn_vert`` -- boolean (default: ``False``); if ``True``, returns 'connecting vertices', technical information that is - used in the algorithm. + used in the algorithm A brief description of the algorithm:: @@ -1245,7 +1246,7 @@ def load_data(n, user=True): INPUT: - - ``user`` -- boolean (default: ``True``) whether to look at user + - ``user`` -- boolean (default: ``True``); whether to look at user data. If not, only consider the optional package. EXAMPLES:: @@ -1336,10 +1337,10 @@ def _mutation_type_from_data(n, dig6, compute_if_necessary=True): def _mutation_type_test(n): """ - Tests all quivers (of the given types) of rank n to check that + Test all quivers (of the given types) of rank n to check that mutation_type() works. - Affine type D does not return True since this test is not implemented. + Affine type D does not return ``True`` since this test is not implemented. EXAMPLES:: @@ -1418,10 +1419,10 @@ def _random_tests(mt, k, mut_class=None, nr_mut=5): INPUT: - - ``mt`` something that can be turned into a QuiverMutationType - - ``k`` (integer) the number of tests performed for each quiver of rank ``n`` - - ``mut_class`` is given, this mutation class is used - - ``nr_mut`` (integer, default:5) the number of mutations performed before + - ``mt`` something that can be turned into a ``QuiverMutationType`` + - ``k`` -- integer; the number of tests performed for each quiver of rank ``n`` + - ``mut_class`` -- if given, this mutation class is used + - ``nr_mut`` -- integer (default: 5); the number of mutations performed before testing The idea of this random test is to start with a mutation type @@ -1512,9 +1513,9 @@ def _random_multi_tests(n, k, nr_mut=5): INPUT: - - ``n`` (integer) -- the rank of the mutation types to test - - ``k`` (integer) -- the number of tests performed for each quiver of rank ``n`` - - ``nr_mut`` (integer, default:5) -- the number of mutations performed before testing + - ``n`` -- integer; the rank of the mutation types to test + - ``k`` -- integer; the number of tests performed for each quiver of rank ``n`` + - ``nr_mut`` -- integer (default: 5); the number of mutations performed before testing TESTS:: diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index b42210db18c..7e07835b935 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -69,7 +69,7 @@ class ClusterQuiver(SageObject): - ``data`` -- can be any of the following:: * :class:`QuiverMutationType` - * :class:`str` -- a string representing a :class:`QuiverMutationType` or a common quiver type (see Examples) + * :class:`str` -- string representing a :class:`QuiverMutationType` or a common quiver type (see Examples) * :class:`ClusterQuiver` * :class:`Matrix` -- a skew-symmetrizable matrix * :class:`DiGraph` -- must be the input data for a quiver @@ -78,7 +78,7 @@ class ClusterQuiver(SageObject): - ``frozen`` -- (default: ``None``) sets the list of frozen variables if the input type is a :class:`DiGraph`, it is ignored otherwise - - ``user_labels`` -- (default:``None``) sets the names of the labels for + - ``user_labels`` -- (default: ``None``) sets the names of the labels for the vertices of the quiver if the input type is not a :class:`DiGraph`; otherwise it is ignored @@ -232,7 +232,8 @@ def __init__(self, data, frozen=None, user_labels=None): values)) # constructs a quiver from a mutation type - if type( data ) in [QuiverMutationType_Irreducible,QuiverMutationType_Reducible]: + if isinstance(data, (QuiverMutationType_Irreducible, + QuiverMutationType_Reducible)): if frozen is not None: print('The input specifies a mutation type, so the' ' additional parameter frozen is ignored.' @@ -534,16 +535,16 @@ def plot(self, circular=True, center=(0, 0), directed=True, mark=None, INPUT: - - ``circular`` -- (default: ``True``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. - - ``center`` -- (default:(0,0)) sets the center of the circular plot, - otherwise it is ignored. - - ``directed`` -- (default: ``True``) if ``True``, the directed - version is shown, otherwise the undirected. + - ``circular`` -- boolean (default: ``True``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used + - ``center`` -- (default: (0,0)) sets the center of the circular plot, + otherwise it is ignored + - ``directed`` -- boolean (default: ``True``); if ``True``, the + directed version is shown, otherwise the undirected - ``mark`` -- (default: ``None``) if set to i, the vertex i is - highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions - of the vertices are saved. + highlighted + - ``save_pos`` -- boolean (default: ``False``); if ``True``, the + positions of the vertices are saved - ``greens`` -- (default: ``[]``) if set to a list, will display the green vertices as green @@ -661,16 +662,17 @@ def show(self, fig_size=1, circular=False, directed=True, mark=None, save_pos=Fa INPUT: - ``fig_size`` -- (default: 1) factor by which the size of the plot - is multiplied. - - ``circular`` -- (default: ``False``) if True, the circular plot is - chosen, otherwise >>spring<< is used. - - ``directed`` -- (default: ``True``) if True, the directed version is - shown, otherwise the undirected. - - ``mark`` -- (default: None) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default: ``False``) if True, the positions of the - vertices are saved. - - ``greens`` -- (default:[]) if set to a list, will display the green - vertices as green + is multiplied + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used + - ``directed`` -- boolean (default: ``True``); if ``True``, the directed + version is shown, otherwise the undirected + - ``mark`` -- boolean (default: ``None``); if set to i, the vertex i is + highlighted + - ``save_pos`` -- boolean (default: ``False``); if ``True``, the + positions of the vertices are saved + - ``greens`` -- (default: ``[]``) if set to a list, will display the + green vertices as green TESTS:: @@ -693,10 +695,10 @@ def interact(self, fig_size=1, circular=True): INPUT: - ``fig_size`` -- (default: 1) factor by which the size of the - plot is multiplied. + plot is multiplied - - ``circular`` -- (default: ``True``) if ``True``, the circular plot - is chosen, otherwise >>spring<< is used. + - ``circular`` -- boolean (default: ``True``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used TESTS:: @@ -704,7 +706,7 @@ def interact(self, fig_size=1, circular=True): sage: S.interact() # needs sage.plot sage.symbolic ...VBox(children=... """ - return cluster_interact(self, fig_size, circular, kind="quiver") + return cluster_interact(self, fig_size, circular, kind='quiver') def save_image(self, filename, circular=False): """ @@ -712,14 +714,15 @@ def save_image(self, filename, circular=False): INPUT: - - ``filename`` -- the filename the image is saved to. - - ``circular`` -- (default: ``False``) if True, the circular plot is chosen, otherwise >>spring<< is used. + - ``filename`` -- the filename the image is saved to + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used EXAMPLES:: sage: Q = ClusterQuiver(['F',4,[1,2]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # needs sage.plot sage.symbolic + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # needs sage.plot sage.symbolic ....: Q.save_image(f.name) """ graph_plot = self.plot(circular=circular) @@ -735,7 +738,7 @@ def qmu_save(self, filename=None): INPUT: - - ``filename`` -- the filename the image is saved to. + - ``filename`` -- the filename the image is saved to If a filename is not specified, the default name is ``from_sage.qmu`` in the current sage directory. @@ -744,7 +747,7 @@ def qmu_save(self, filename=None): sage: Q = ClusterQuiver(['F',4,[1,2]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".qmu") as f: # needs sage.plot sage.symbolic + sage: with tempfile.NamedTemporaryFile(suffix='.qmu') as f: # needs sage.plot sage.symbolic ....: Q.qmu_save(f.name) Make sure we can save quivers with `m != n` frozen variables, see :issue:`14851`:: @@ -753,7 +756,7 @@ def qmu_save(self, filename=None): sage: T1 = S.principal_extension() sage: Q = T1.quiver() sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".qmu") as f: # needs sage.plot sage.symbolic + sage: with tempfile.NamedTemporaryFile(suffix='.qmu') as f: # needs sage.plot sage.symbolic ....: Q.qmu_save(f.name) """ M = self.b_matrix() @@ -879,8 +882,9 @@ def mutation_type(self): """ Return the mutation type of ``self``. - Return the mutation_type of each connected component of self if it can be determined, - otherwise, the mutation type of this component is set to be unknown. + Return the mutation_type of each connected component of ``self`` if it + can be determined, otherwise, the mutation type of this component is + set to be unknown. The mutation types of the components are ordered by vertex labels. @@ -1119,9 +1123,9 @@ def canonical_label(self, certificate=False): INPUT: - - ``certificate`` -- boolean (default: ``False``) if True, the dictionary - from ``self.vertices()`` to the vertices of the returned quiver - is returned as well. + - ``certificate`` -- boolean (default: ``False``); if ``True``, the + dictionary from ``self.vertices()`` to the vertices of the returned + quiver is returned as well EXAMPLES:: @@ -1295,7 +1299,7 @@ def sinks(self): def first_source(self): r""" - Return the first vertex of ``self`` that is a source + Return the first vertex of ``self`` that is a source. EXAMPLES:: @@ -1334,11 +1338,13 @@ def mutate(self, data, inplace=True): INPUT: - - ``sequence`` -- a vertex of ``self``, an iterator of vertices of ``self``, - a function which takes in the ClusterQuiver and returns a vertex or an iterator of vertices, - or a string of the parameter wanting to be called on ClusterQuiver that will return a vertex or - an iterator of vertices. - - ``inplace`` -- (default: ``True``) if False, the result is returned, otherwise ``self`` is modified. + - ``sequence`` -- a vertex of ``self``, an iterator of vertices of + ``self``, a function which takes in the ClusterQuiver and returns a + vertex or an iterator of vertices, or a string of the parameter + wanting to be called on ClusterQuiver that will return a vertex or + an iterator of vertices + - ``inplace`` -- boolean (default: ``True``); if ``False``, the result + is returned, otherwise ``self`` is modified EXAMPLES:: @@ -1471,13 +1477,16 @@ def mutate(self, data, inplace=True): def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2 ): """ - Return a list containing the sequence of quivers obtained from ``self`` by a sequence of mutations on vertices. + Return a list containing the sequence of quivers obtained from ``self`` + by a sequence of mutations on vertices. INPUT: - - ``sequence`` -- a list or tuple of vertices of ``self``. - - ``show_sequence`` -- (default: ``False``) if ``True``, a png containing the mutation sequence is shown. - - ``fig_size`` -- (default: 1.2) factor by which the size of the sequence is expanded. + - ``sequence`` -- list or tuple of vertices of ``self`` + - ``show_sequence`` -- boolean (default: ``False``); if ``True``, a png + containing the mutation sequence is shown + - ``fig_size`` -- (default: 1.2) factor by which the size of the + sequence is expanded EXAMPLES:: @@ -1616,17 +1625,21 @@ def reorient(self, data): raise ValueError('not a total order on the vertices of the quiver or a list of edges to be oriented') def mutation_class_iter(self, depth=infinity, show_depth=False, - return_paths=False, data_type="quiver", + return_paths=False, data_type='quiver', up_to_equivalence=True, sink_source=False): """ Return an iterator for the mutation class of ``self`` together with certain constraints. INPUT: - - ``depth`` -- (default: infinity) integer, only quivers with distance at most depth from self are returned. - - ``show_depth`` -- (default: ``False``) if True, the actual depth of the mutation is shown. - - ``return_paths`` -- (default: ``False``) if True, a shortest path of mutation sequences from self to the given quiver is returned as well. - - ``data_type`` -- (default: "quiver") can be one of the following:: + - ``depth`` -- integer (default: infinity); only quivers with distance + at most depth from ``self`` are returned. + - ``show_depth`` -- boolean (default: ``False``); if ``True``, the + actual depth of the mutation is shown + - ``return_paths`` -- boolean (default: ``False``); if ``True``, a + shortest path of mutation sequences from ``self`` to the given quiver + is returned as well + - ``data_type`` -- (default: ``'quiver'``) can be one of the following:: * "quiver" * "matrix" @@ -1634,8 +1647,10 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, * "dig6" * "path" - - ``up_to_equivalence`` -- (default: ``True``) if True, only one quiver for each graph-isomorphism class is recorded. - - ``sink_source`` -- (default: ``False``) if True, only mutations at sinks and sources are applied. + - ``up_to_equivalence`` -- boolean (default: ``True``); if ``True``, + only one quiver for each graph-isomorphism class is recorded + - ``sink_source`` -- boolean (default: ``False``); if ``True``, only + mutations at sinks and sources are applied EXAMPLES:: @@ -1751,29 +1766,29 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, yield next_element def mutation_class(self, depth=infinity, show_depth=False, return_paths=False, - data_type="quiver", up_to_equivalence=True, sink_source=False): + data_type='quiver', up_to_equivalence=True, sink_source=False): """ Return the mutation class of ``self`` together with certain constraints. INPUT: - - ``depth`` -- (default: ``infinity`) integer, only seeds with + - ``depth`` -- (default: ``infinity``) integer, only seeds with distance at most depth from ``self`` are returned - - ``show_depth`` -- (default: ``False``) if ``True``, the actual depth - of the mutation is shown - - ``return_paths`` -- (default: ``False``) if ``True``, a shortest - path of mutation sequences from self to the given quiver is + - ``show_depth`` -- boolean (default: ``False``); if ``True``, the + actual depth of the mutation is shown + - ``return_paths`` -- boolean (default: ``False``); if ``True``, a + shortest path of mutation sequences from ``self`` to the given quiver is returned as well - - ``data_type`` -- (default: ``"quiver"``) can be one of + - ``data_type`` -- (default: ``'quiver'``) can be one of the following: - * ``"quiver"`` -- the quiver is returned - * ``"dig6"`` -- the dig6-data is returned - * ``"path"`` -- shortest paths of mutation sequences from + * ``'quiver'`` -- the quiver is returned + * ``'dig6'`` -- the dig6-data is returned + * ``'path'`` -- shortest paths of mutation sequences from ``self`` are returned - - ``sink_source`` -- (default: ``False``) if ``True``, only mutations - at sinks and sources are applied + - ``sink_source`` -- boolean (default: ``False``); if ``True``, only + mutations at sinks and sources are applied EXAMPLES:: @@ -1904,12 +1919,16 @@ def is_finite(self): def is_mutation_finite( self, nr_of_checks=None, return_path=False ): """ - Uses a non-deterministic method by random mutations in various directions. Can result in a wrong answer. + Uses a non-deterministic method by random mutations in various + directions. Can result in a wrong answer. INPUT: - - ``nr_of_checks`` -- (default: None) number of mutations applied. Standard is 500*(number of vertices of self). - - ``return_path`` -- (default: ``False``) if True, in case of self not being mutation finite, a path from self to a quiver with an edge label (a,-b) and a*b > 4 is returned. + - ``nr_of_checks`` -- (default: ``None``) number of mutations applied; + Standard is 500*(number of vertices of ``self``) + - ``return_path`` -- (default: ``False``) if ``True``, in case of + ``self`` not being mutation finite, a path from ``self`` to a quiver + with an edge label `(a,-b)` and `a*b > 4` is returned ALGORITHM: @@ -1932,10 +1951,15 @@ def is_mutation_finite( self, nr_of_checks=None, return_path=False ): path = None elif not return_path and self._mutation_type == 'undetermined infinite mutation type': is_finite = False - elif type( self._mutation_type ) in [QuiverMutationType_Irreducible, QuiverMutationType_Reducible] and self._mutation_type.is_mutation_finite(): + elif (isinstance(self._mutation_type, (QuiverMutationType_Irreducible, + QuiverMutationType_Reducible)) + and self._mutation_type.is_mutation_finite()): is_finite = True path = None - elif not return_path and type( self._mutation_type ) in [QuiverMutationType_Irreducible, QuiverMutationType_Reducible] and not self._mutation_type.is_mutation_finite(): + elif (not return_path and isinstance(self._mutation_type, + (QuiverMutationType_Irreducible, + QuiverMutationType_Reducible)) + and not self._mutation_type.is_mutation_finite()): is_finite = False else: # turning dg_component into a canonical form @@ -1951,14 +1975,12 @@ def is_mutation_finite( self, nr_of_checks=None, return_path=False ): def number_of_edges(self): r""" - Return the total number of edges on the quiver + Return the total number of edges on the quiver. Note: This only works with non-valued quivers. If used on a non-valued quiver then the positive value is taken to be the number of edges added - OUTPUT: - - An integer of the number of edges. + OUTPUT: integer of the number of edges EXAMPLES:: @@ -1978,14 +2000,15 @@ def number_of_edges(self): def relabel(self, relabelling, inplace=True): r""" - Return the quiver after doing a relabelling + Return the quiver after doing a relabelling. - Will relabel the vertices of the quiver + Will relabel the vertices of the quiver. INPUT: - - ``relabelling`` -- Dictionary of labels to move around - - ``inplace`` -- (default: ``True``) if True, will return a duplicate of the quiver + - ``relabelling`` -- dictionary of labels to move around + - ``inplace`` -- boolean (default: ``True``); if ``True``, will return + a duplicate of the quiver EXAMPLES:: diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index d4b99fc9c23..c9f06a4761f 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -67,7 +67,9 @@ def __call__(self, *args): _mutation_type_error(data) # check for reducible types - if all(type(data_component) in [list, tuple, QuiverMutationType_Irreducible] for data_component in data): + if all(isinstance(data_component, (list, tuple, + QuiverMutationType_Irreducible)) + for data_component in data): if len(data) == 1: return QuiverMutationType(data[0]) else: @@ -680,11 +682,11 @@ def plot(self, circular=False, directed=True): INPUT: - - ``circular`` -- (default: ``False``) if ``True``, the - circular plot is chosen, otherwise >>spring<< is used. + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used - - ``directed`` -- (default: ``True``) if ``True``, the - directed version is shown, otherwise the undirected. + - ``directed`` -- boolean (default: ``True``); if ``True``, the + directed version is shown, otherwise the undirected EXAMPLES:: @@ -700,15 +702,15 @@ def show(self, circular=False, directed=True): INPUT: - - ``circular`` -- (default:``False``) if ``True``, the - circular plot is chosen, otherwise >>spring<< is used. + - ``circular`` -- boolean (default: ``False``); if ``True``, the + circular plot is chosen, otherwise >>spring<< is used - - ``directed`` -- (default: ``True``) if ``True``, the - directed version is shown, otherwise the undirected. + - ``directed`` -- boolean (default: ``True``); if ``True``, the + directed version is shown, otherwise the undirected TESTS:: - sage: QMT = QuiverMutationType(['A',5]) + sage: QMT = QuiverMutationType(['A', 5]) sage: QMT.show() # long time # needs sage.plot sage.symbolic """ self.plot(circular=circular, directed=directed).show() @@ -1973,8 +1975,8 @@ def __init__(self, *args): INPUT: - - ``data`` -- a list each of whose entries is a - QuiverMutationType_Irreducible + - ``data`` -- list; each of whose entries is a + :class:`QuiverMutationType_Irreducible` EXAMPLES:: @@ -2287,7 +2289,7 @@ def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): r""" Save mutation classes of certain quivers of ranks up to and equal - to ``n`` or equal to ``n`` to + to `n` or equal to `n` to ``DOT_SAGE/cluster_algebra_quiver/mutation_classes_n.dig6``. This data will then be used to determine quiver mutation types. @@ -2295,16 +2297,16 @@ def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): INPUT: - ``n`` -- the rank (or the upper limit on the rank) of the mutation - classes that are being saved. + classes that are being saved - - ``up_to`` -- (default:``True``) if ``True``, saves data for - ranks smaller than or equal to ``n``. If ``False``, saves data - for rank exactly ``n``. + - ``up_to`` -- (default: ``True``) if ``True``, saves data for + ranks smaller than or equal to `n`; if ``False``, saves data + for rank exactly `n` - - ``types`` -- (default:'ClassicalExceptional') if all, saves data + - ``types`` -- (default: ``'ClassicalExceptional'``) if all, saves data for both exceptional mutation-finite quivers and for classical - quiver. The input 'Exceptional' or 'Classical' is also allowed - to save only part of this data. + quiver; the input 'Exceptional' or 'Classical' is also allowed + to save only part of this data TESTS:: diff --git a/src/sage/combinat/cluster_complex.py b/src/sage/combinat/cluster_complex.py index 70a88878987..c99dc0df6f3 100644 --- a/src/sage/combinat/cluster_complex.py +++ b/src/sage/combinat/cluster_complex.py @@ -74,14 +74,14 @@ def cluster(self): """ if self.parent().k() != 1: raise NotImplementedError("not working for multi-cluster complexes") - F = self.parent().greedy_facet(side="positive") + F = self.parent().greedy_facet(side='positive') R = F.extended_root_configuration() N = len(list(F)) return [-R[i] if i < N else R[i] for i in self] def upper_cluster(self): """ - Return the part of the cluster that contains positive roots + Return the part of the cluster that contains positive roots. EXAMPLES:: @@ -173,7 +173,7 @@ class ClusterComplex(SubwordComplex): """ @staticmethod - def __classcall__(cls, W, k=1, coxeter_element=None, algorithm="inductive"): + def __classcall__(cls, W, k=1, coxeter_element=None, algorithm='inductive'): r""" Standardize input to ensure a unique representation. @@ -184,7 +184,7 @@ def __classcall__(cls, W, k=1, coxeter_element=None, algorithm="inductive"): sage: S2 = ClusterComplex(W) sage: S3 = ClusterComplex(CoxeterMatrix('B2'), coxeter_element=(1,2)) sage: w = W.from_reduced_word([1,2]) - sage: S4 = ClusterComplex('B2', coxeter_element=w, algorithm="inductive") + sage: S4 = ClusterComplex('B2', coxeter_element=w, algorithm='inductive') sage: S1 is S2 and S2 is S3 and S3 is S4 True """ @@ -238,9 +238,7 @@ def __call__(self, F, facet_test=True): - ``facet_test`` -- boolean (default: ``True``); tells whether or not the facet ``F`` should be tested before creation - OUTPUT: - - The facet of ``self`` at positions given by ``F``. + OUTPUT: the facet of ``self`` at positions given by ``F`` EXAMPLES:: diff --git a/src/sage/combinat/colored_permutations.py b/src/sage/combinat/colored_permutations.py index 91075c7a423..1accb8f46ee 100644 --- a/src/sage/combinat/colored_permutations.py +++ b/src/sage/combinat/colored_permutations.py @@ -815,8 +815,8 @@ def _element_constructor_(self, x): INPUT: - Either a list of pairs ``(color, element)`` - or a pair of lists ``(colors, elements)``. + - ``x`` -- either a list of pairs ``(color, element)`` or a pair of + lists ``(colors, elements)`` TESTS:: @@ -1460,13 +1460,13 @@ def to_cycles(self, singletons=True, use_min=True, negative_cycles=True): INPUT: - - ``singletons`` -- (default: ``True``) whether to include singleton - cycles or not - - ``use_min`` -- (default: ``True``) if ``False``, the cycles are - returned in the order of increasing *largest* (not smallest) + - ``singletons`` -- boolean (default: ``True``); whether to include + singleton cycles or not + - ``use_min`` -- boolean (default: ``True``); if ``False``, the cycles + are returned in the order of increasing *largest* (not smallest) elements, and each cycle starts with its largest element - - ``negative_cycles`` -- (default: ``True``) if ``False``, for any - two cycles `C^{\pm} = \{\pm c_1, \ldots, \pm c_k\}` such that + - ``negative_cycles`` -- boolean (default: ``True``); if ``False``, for + any two cycles `C^{\pm} = \{\pm c_1, \ldots, \pm c_k\}` such that `C^+ \neq C^-`, this does not include the cycle `C^-` .. WARNING:: diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 0604d4620b9..03c1797abfb 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -164,7 +164,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from __future__ import annotations -from typing import Iterator +from collections.abc import Iterator from sage.arith.misc import bernoulli, factorial from sage.rings.integer_ring import ZZ @@ -197,17 +197,17 @@ def bell_number(n, algorithm='flint', **options) -> Integer: INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``algorithm`` -- (Default: ``'flint'``) any one of the following: + - ``algorithm`` -- (default: ``'flint'``) any one of the following: - - ``'dobinski'`` -- Use Dobinski's formula implemented in Sage + - ``'dobinski'`` -- use Dobinski's formula implemented in Sage - - ``'flint'`` -- Wrap FLINT's ``arith_bell_number`` + - ``'flint'`` -- wrap FLINT's ``arith_bell_number`` - - ``'gap'`` -- Wrap GAP's ``Bell`` + - ``'gap'`` -- wrap GAP's ``Bell`` - - ``'mpmath'`` -- Wrap mpmath's ``bell`` + - ``'mpmath'`` -- wrap mpmath's ``bell`` .. WARNING:: @@ -466,9 +466,7 @@ def catalan_number(n): - ``n`` -- integer - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -505,13 +503,11 @@ def narayana_number(n: Integer, k: Integer) -> Integer: INPUT: - - ``n`` -- an integer - - - ``k`` -- an integer between ``0`` and ``n - 1`` + - ``n`` -- integer - OUTPUT: + - ``k`` -- integer between ``0`` and ``n - 1`` - an integer + OUTPUT: integer EXAMPLES:: @@ -537,13 +533,13 @@ def euler_number(n, algorithm='flint') -> Integer: INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``algorithm`` -- (Default: ``'flint'``) any one of the following: + - ``algorithm`` -- (default: ``'flint'``) any one of the following: - - ``'maxima'`` -- Wraps Maxima's ``euler``. + - ``'maxima'`` -- wraps Maxima's ``euler`` - - ``'flint'`` -- Wrap FLINT's ``arith_euler_number`` + - ``'flint'`` -- wrap FLINT's ``arith_euler_number`` EXAMPLES:: @@ -593,11 +589,9 @@ def eulerian_number(n, k, algorithm='recursive') -> Integer: - ``k`` -- integer between ``0`` and ``n - 1`` - - ``algorithm`` -- ``"recursive"`` (default) or ``"formula"`` + - ``algorithm`` -- ``'recursive'`` (default) or ``'formula'`` - OUTPUT: - - an integer + OUTPUT: integer .. SEEALSO:: :func:`eulerian_polynomial` @@ -637,13 +631,11 @@ def eulerian_polynomial(n, algorithm='derivative'): INPUT: - - ``n`` -- an integer - - - ``algorithm`` -- ``"derivative"`` (default) or ``"coeffs"`` + - ``n`` -- integer - OUTPUT: + - ``algorithm`` -- ``'derivative'`` (default) or ``'coeffs'`` - polynomial in one variable ``t`` + OUTPUT: polynomial in one variable ``t`` .. SEEALSO:: :func:`eulerian_number` @@ -679,7 +671,7 @@ def eulerian_polynomial(n, algorithm='derivative'): return R([eulerian_number(n, k, "formula") for k in range(n)]) -def fibonacci(n, algorithm="pari") -> Integer: +def fibonacci(n, algorithm='pari') -> Integer: """ Return the `n`-th Fibonacci number. @@ -691,12 +683,12 @@ def fibonacci(n, algorithm="pari") -> Integer: INPUT: - - ``algorithm`` -- a string: + - ``algorithm`` -- string; one of - * ``"pari"`` -- (default) use the PARI C library's + * ``'pari'`` -- (default) use the PARI C library's :pari:`fibo` function - * ``"gap"`` -- use GAP's Fibonacci function + * ``'gap'`` -- use GAP's Fibonacci function .. NOTE:: @@ -750,9 +742,9 @@ def lucas_number1(n, P, Q): INPUT: - - ``n`` -- integer + - ``n`` -- integer - - ``P, Q`` -- integer or rational numbers + - ``P``, ``Q`` -- integer or rational numbers OUTPUT: integer or rational number @@ -817,11 +809,9 @@ def lucas_number2(n, P, Q): INPUT: + - ``n`` -- integer - - ``n`` -- integer - - - ``P, Q`` -- integer or rational numbers - + - ``P``, ``Q`` -- integer or rational numbers OUTPUT: integer or rational number @@ -857,7 +847,7 @@ def lucas_number2(n, P, Q): return libgap.Lucas(P, Q, n)[1].sage() -def stirling_number1(n, k, algorithm="gap") -> Integer: +def stirling_number1(n, k, algorithm='gap') -> Integer: r""" Return the `n`-th Stirling number `S_1(n,k)` of the first kind. @@ -871,8 +861,8 @@ def stirling_number1(n, k, algorithm="gap") -> Integer: - ``k`` -- nonnegative machine-size integer - ``algorithm``: - * ``"gap"`` (default) -- use GAP's ``Stirling1`` function - * ``"flint"`` -- use flint's ``arith_stirling_number_1u`` function + * ``'gap'`` -- default; use GAP's ``Stirling1`` function + * ``'flint'`` -- use flint's ``arith_stirling_number_1u`` function EXAMPLES:: @@ -893,7 +883,7 @@ def stirling_number1(n, k, algorithm="gap") -> Integer: sage: stirling_number1(10,5, algorithm='flint') # needs sage.libs.flint 269325 - sage: s_sage = stirling_number1(50,3, algorithm="mutta") + sage: s_sage = stirling_number1(50,3, algorithm='mutta') Traceback (most recent call last): ... ValueError: unknown algorithm: mutta @@ -921,14 +911,14 @@ def stirling_number2(n, k, algorithm=None) -> Integer: INPUT: - - ``n`` -- nonnegative machine-size integer - - ``k`` -- nonnegative machine-size integer + - ``n`` -- nonnegative machine-size integer + - ``k`` -- nonnegative machine-size integer - ``algorithm``: - * ``None`` (default) -- use native implementation - * ``"flint"`` -- use flint's ``arith_stirling_number_2`` function - * ``"gap"`` -- use GAP's ``Stirling2`` function - * ``"maxima"`` -- use Maxima's ``stirling2`` function + * ``None`` -- default; use native implementation + * ``'flint'`` -- use flint's ``arith_stirling_number_2`` function + * ``'gap'`` -- use GAP's ``Stirling2`` function + * ``'maxima'`` -- use Maxima's ``stirling2`` function EXAMPLES: @@ -1016,10 +1006,10 @@ def stirling_number2(n, k, algorithm=None) -> Integer: ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") - sage: stirling_number2(20, 3, algorithm="maxima") # needs sage.symbolic + sage: stirling_number2(20, 3, algorithm='maxima') # needs sage.symbolic 580606446 - sage: s_sage = stirling_number2(5, 3, algorithm="namba") + sage: s_sage = stirling_number2(5, 3, algorithm='namba') Traceback (most recent call last): ... ValueError: unknown algorithm: namba @@ -1060,7 +1050,7 @@ def polygonal_number(s, n): - ``n`` -- integer; the index of the returned `s`-gonal number - OUTPUT: an integer + OUTPUT: integer EXAMPLES: @@ -1142,12 +1132,12 @@ def __init__(self, l, copy=True): INPUT: - - ``l`` -- a list or any object that can be converted to a - list by calling ``list()``. + - ``l`` -- list or any object that can be converted to a + list by calling ``list()`` - - ``copy`` -- (boolean, default ``True``) if ``False``, then + - ``copy`` -- boolean (default: ``True``); if ``False``, then ``l`` must be a ``list``, which is assigned to ``self._list`` - without copying. + without copying EXAMPLES:: @@ -1386,7 +1376,7 @@ def __hash__(self): def __bool__(self) -> bool: """ - Return ``True`` if ``self`` is non-zero. + Return ``True`` if ``self`` is nonzero. We consider a list to be zero if it has length zero. @@ -1425,7 +1415,6 @@ def __bool__(self) -> bool: sage: b = Bar([4]) sage: not b False - """ return bool(self._list) @@ -1507,10 +1496,10 @@ class CombinatorialElement(CombinatorialObject, Element, INPUT: - - ``parent`` -- the :class:`Parent` class for this element. + - ``parent`` -- the :class:`Parent` class for this element - - ``lst`` -- a list or any object that can be converted to a - list by calling ``list()``. + - ``lst`` -- list or any object that can be converted to a + list by calling ``list()`` EXAMPLES:: @@ -1582,6 +1571,7 @@ def __init__(self, parent, *args, **kwds): ##################################################### # combinatorial sets/lists + def tuples(S, k, algorithm='itertools'): r""" Return a list of all `k`-tuples of elements of a given set ``S``. @@ -1660,7 +1650,7 @@ def _tuples_native(S, k): Return a list of all `k`-tuples of elements of a given set ``S``. This is a helper method used in :meth:`tuples`. It returns the - same as ``tuples(S, k, algorithm="native")``. + same as ``tuples(S, k, algorithm='native')``. EXAMPLES:: @@ -1711,16 +1701,16 @@ def number_of_tuples(S, k, algorithm='naive') -> Integer: sage: S = [1,2,3,4,5] sage: number_of_tuples(S,2) 25 - sage: number_of_tuples(S,2, algorithm="gap") # needs sage.libs.gap + sage: number_of_tuples(S,2, algorithm='gap') # needs sage.libs.gap 25 sage: S = [1,1,2,3,4,5] sage: number_of_tuples(S,2) 25 - sage: number_of_tuples(S,2, algorithm="gap") # needs sage.libs.gap + sage: number_of_tuples(S,2, algorithm='gap') # needs sage.libs.gap 25 sage: number_of_tuples(S,0) 1 - sage: number_of_tuples(S,0, algorithm="gap") # needs sage.libs.gap + sage: number_of_tuples(S,0, algorithm='gap') # needs sage.libs.gap 1 """ if algorithm == 'naive': @@ -1827,16 +1817,16 @@ def number_of_unordered_tuples(S, k, algorithm='naive') -> Integer: sage: S = [1,2,3,4,5] sage: number_of_unordered_tuples(S,2) 15 - sage: number_of_unordered_tuples(S,2, algorithm="gap") # needs sage.libs.gap + sage: number_of_unordered_tuples(S,2, algorithm='gap') # needs sage.libs.gap 15 sage: S = [1,1,2,3,4,5] sage: number_of_unordered_tuples(S,2) 15 - sage: number_of_unordered_tuples(S,2, algorithm="gap") # needs sage.libs.gap + sage: number_of_unordered_tuples(S,2, algorithm='gap') # needs sage.libs.gap 15 sage: number_of_unordered_tuples(S,0) 1 - sage: number_of_unordered_tuples(S,0, algorithm="gap") # needs sage.libs.gap + sage: number_of_unordered_tuples(S,0, algorithm='gap') # needs sage.libs.gap 1 """ if algorithm == 'naive': @@ -1971,7 +1961,7 @@ def bell_polynomial(n: Integer, k=None, ordinary=False): - ``k`` -- (optional) if specified, returns the partial Bell polynomial, otherwise returns the complete Bell polynomial - - ``ordinary`` -- (default: ``False``) if ``True``, returns the + - ``ordinary`` -- boolean (default: ``False``); if ``True``, returns the (partial) ordinary Bell polynomial, otherwise returns the (partial) exponential Bell polynomial @@ -2107,13 +2097,12 @@ def fibonacci_sequence(start, stop=None, algorithm=None) -> Iterator: INPUT: - - ``start`` -- starting value + - ``start`` -- starting value - - ``stop`` -- stopping value + - ``stop`` -- stopping value - - ``algorithm`` -- (default: ``None``) passed on to - fibonacci function (or not passed on if None, i.e., use the - default) + - ``algorithm`` -- (default: ``None``) passed on to fibonacci function (or + not passed on if ``None``, i.e., use the default) EXAMPLES:: @@ -2268,7 +2257,7 @@ def bernoulli_polynomial(x, n: Integer): if n < 0: raise TypeError except TypeError: - raise ValueError("the second argument must be a non-negative integer") + raise ValueError("the second argument must be a nonnegative integer") if n == 0: return x**0 # result should be in the parent of x diff --git a/src/sage/combinat/combinatorial_map.py b/src/sage/combinat/combinatorial_map.py index 84876e52f56..ded649a41da 100644 --- a/src/sage/combinat/combinatorial_map.py +++ b/src/sage/combinat/combinatorial_map.py @@ -57,7 +57,7 @@ def combinatorial_map_trivial(f=None, order=None, name=None): r""" - Combinatorial map decorator + Combinatorial map decorator. See :ref:`sage.combinat.combinatorial_map` for a description of this decorator and its purpose. This default implementation does @@ -65,14 +65,11 @@ def combinatorial_map_trivial(f=None, order=None, name=None): INPUT: - - ``f`` -- (default: ``None``, if combinatorial_map is used as a decorator) a function - ``name`` -- (default: ``None``) the name for nicer outputs on combinatorial maps - ``order`` -- (default: ``None``) the order of the combinatorial map, if it is known. Is not used, but might be helpful later - OUTPUT: - - - ``f`` unchanged + OUTPUT: ``f`` unchanged EXAMPLES:: @@ -119,9 +116,7 @@ def combinatorial_map_wrapper(f=None, order=None, name=None): - ``name`` -- (default: ``None``) the name for nicer outputs on combinatorial maps - ``order`` -- (default: ``None``) the order of the combinatorial map, if it is known. Is not used, but might be helpful later - OUTPUT: - - - A combinatorial map. This is an instance of the :class:`CombinatorialMap`. + OUTPUT: a combinatorial map; this is an instance of the :class:`CombinatorialMap` EXAMPLES: @@ -182,7 +177,6 @@ def combinatorial_map_wrapper(f=None, order=None, name=None): sage: combinatorial_map(major_index) Combinatorial map: major_index - """ if f is None: return lambda f: CombinatorialMap(f, order=order, name=name) @@ -276,7 +270,7 @@ def _sage_src_lines_(self): def __get__(self, inst, cls=None): """ - Bounds the method of self to the given instance. + Bounds the method of ``self`` to the given instance. EXAMPLES:: @@ -292,7 +286,7 @@ def __get__(self, inst, cls=None): def __call__(self, *args, **kwds): """ - Calls the combinatorial map. + Call the combinatorial map. EXAMPLES:: @@ -336,7 +330,7 @@ def unbounded_map(self): def order(self): """ - Returns the order of ``self``, or ``None`` if the order is not known. + Return the order of ``self``, or ``None`` if the order is not known. EXAMPLES:: @@ -355,7 +349,7 @@ def order(self): def name(self): """ - Returns the name of a combinatorial map. + Return the name of a combinatorial map. This is used for the string representation of ``self``. EXAMPLES:: diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index 9cdb1ebd769..173590cfd74 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -51,7 +51,7 @@ class Composition(CombinatorialElement): r""" - Integer compositions + Integer compositions. A composition of a nonnegative integer `n` is a list `(i_1, \ldots, i_k)` of positive integers with total sum `n`. @@ -155,10 +155,25 @@ def __classcall_private__(cls, co=None, descents=None, code=None, from_subset=No [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0] sage: Composition(code=_) [4, 1, 2, 3, 5] + + TESTS: + + Let us check that :issue:`14862` is solved:: + + sage: C = Compositions() + sage: C([3,-1,1]) + Traceback (most recent call last): + ... + ValueError: not a composition + sage: C("strawberry") + Traceback (most recent call last): + ... + ValueError: not a composition """ if descents is not None: if isinstance(descents, tuple): - return Compositions().from_descents(descents[0], nps=descents[1]) + return Compositions().from_descents(descents[0], + nps=descents[1]) else: return Compositions().from_descents(descents) elif code is not None: @@ -167,8 +182,22 @@ def __classcall_private__(cls, co=None, descents=None, code=None, from_subset=No return Compositions().from_subset(*from_subset) elif isinstance(co, Composition): return co - else: - return Compositions()(list(co)) + + return Compositions()(co) + + def __init__(self, parent, lst): + """ + Initialize ``self``. + + EXAMPLES:: + + sage: C = Composition([3,1,2]) + sage: TestSuite(C).run() + """ + lst = [Integer(u) for u in lst] + if not all(u >= 0 for u in lst): + raise ValueError("elements must be nonnegative integers") + CombinatorialElement.__init__(self, parent, lst) def _ascii_art_(self): """ @@ -180,7 +209,7 @@ def _ascii_art_(self): [ * ** * * ] [ * * ** *** * ** * ] [ *, * , * , * , **, ** , ***, **** ] - sage: Partitions.options(diagram_str='#', convention="French") + sage: Partitions.options(diagram_str='#', convention='French') sage: ascii_art(Compositions(4).list()) [ # ] [ # # # ## ] @@ -202,7 +231,7 @@ def _unicode_art_(self): ⎢ ├┤ ├┼┘ ┌┼┤ ┌┬┬┐ ├┤ ┌┬┐ ┌┐ ⎥ ⎢ ├┤ ├┤ ├┼┘ ├┼┴┘ ┌┼┤ ┌┼┼┘ ┌┬┼┤ ┌┬┬┬┐ ⎥ ⎣ └┘, └┘ , └┘ , └┘ , └┴┘, └┴┘ , └┴┴┘, └┴┴┴┘ ⎦ - sage: Partitions.options(diagram_str='#', convention="French") + sage: Partitions.options(diagram_str='#', convention='French') sage: unicode_art(Compositions(4).list()) ⎡ ┌┐ ⎤ ⎢ ├┤ ┌┐ ┌┐ ┌┬┐ ⎥ @@ -363,7 +392,7 @@ def sum(compositions) -> Composition: INPUT: - - ``compositions`` -- a list (or iterable) of compositions + - ``compositions`` -- list (or iterable) of compositions EXAMPLES:: @@ -444,8 +473,8 @@ def ribbon_decomposition(self, other, check=True): - ``other`` -- composition of same size as ``self`` - - ``check`` -- (default: ``True``) a Boolean determining whether - to check the input compositions for having the same size + - ``check`` -- boolean (default: ``True``); whether to check the input + compositions for having the same size OUTPUT: @@ -556,12 +585,10 @@ def join(self, other, check=True) -> Composition: - ``other`` -- composition of same size as ``self`` - - ``check`` -- (default: ``True``) a Boolean determining whether - to check the input compositions for having the same size - - OUTPUT: + - ``check`` -- boolean (default: ``True``); whether to check the input + compositions for having the same size - - the join of the compositions ``self`` and ``other`` + OUTPUT: the join of the compositions ``self`` and ``other`` EXAMPLES:: @@ -681,12 +708,10 @@ def meet(self, other, check=True) -> Composition: - ``other`` -- composition of same size as ``self`` - - ``check`` -- (default: ``True``) a Boolean determining whether - to check the input compositions for having the same size - - OUTPUT: + - ``check`` -- boolean (default: ``True``); whether to check the input + compositions for having the same size - - the meet of the compositions ``self`` and ``other`` + OUTPUT: the meet of the compositions ``self`` and ``other`` EXAMPLES:: @@ -923,7 +948,7 @@ def refinement_splitting(self, J) -> list[Composition]: INPUT: - - ``J`` -- A composition such that ``self`` is finer than ``J`` + - ``J`` -- a composition such that ``self`` is finer than ``J`` OUTPUT: @@ -1051,8 +1076,8 @@ def partial_sums(self, final=True) -> list: INPUT: - - ``final`` -- (default: ``True``) whether or not to include the final - partial sum, which is always the size of the composition. + - ``final`` -- boolean (default: ``True``); whether or not to include + the final partial sum, which is always the size of the composition .. SEEALSO:: @@ -1087,8 +1112,8 @@ def to_subset(self, final=False): INPUT: - - ``final`` -- (default: ``False``) whether or not to include the final - partial sum, which is always the size of the composition. + - ``final`` -- boolean (default: ``False``); whether or not to include + the final partial sum, which is always the size of the composition .. SEEALSO:: @@ -1140,7 +1165,7 @@ def descents(self, final_descent=False) -> list: INPUT: - - ``final_descent`` -- (Default: ``False``) a boolean integer + - ``final_descent`` -- boolean (default: ``False``) OUTPUT: @@ -1253,10 +1278,10 @@ def shuffle_product(self, other, overlap=False): INPUT: - - ``other`` -- composition + - ``other`` -- composition - - ``overlap`` -- boolean (default: ``False``); if ``True``, the - overlapping shuffle product is returned. + - ``overlap`` -- boolean (default: ``False``); if ``True``, the + overlapping shuffle product is returned OUTPUT: @@ -1481,10 +1506,10 @@ class Compositions(UniqueRepresentation, Parent): [1, 2, 1] If `n` is not specified, this returns the combinatorial class of - all (non-negative) integer compositions:: + all (nonnegative) integer compositions:: sage: Compositions() - Compositions of non-negative integers + Compositions of nonnegative integers sage: [] in Compositions() True sage: [2,3,1] in Compositions() @@ -1755,8 +1780,10 @@ def _element_constructor_(self, lst) -> Composition: sage: P(Partition([5,2,1])) [5, 2, 1] """ - if isinstance(lst, (Composition, Partition)): - lst = list(lst) + # input can be an iterator, and one has to use it twice + lst = list(lst) + if any(not isinstance(x, (int, Integer)) or x < 0 for x in lst): + raise ValueError('not a composition') elt = self.element_class(self, lst) if elt not in self: raise ValueError("%s not in %s" % (elt, self)) @@ -1795,7 +1822,7 @@ def from_descents(self, descents, nps=None) -> Composition: - ``descents`` -- an iterable - - ``nps`` -- (default: ``None``) an integer or ``None`` + - ``nps`` -- integer or ``None`` (default: ``None``) OUTPUT: @@ -1830,7 +1857,7 @@ def from_subset(self, S, n) -> Composition: - ``S`` -- an iterable, a subset of `\{1, 2, \ldots, n-1\}` - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -1860,7 +1887,8 @@ def from_subset(self, S, n) -> Composition: return self.element_class(self, [n]) if n <= d[-1]: - raise ValueError("S (=%s) is not a subset of {1, ..., %s}" % (d, n - 1)) + raise ValueError("S (=%s) is not a subset of {1, ..., %s}" + % (d, n - 1)) else: d.append(n) @@ -1944,9 +1972,9 @@ def _repr_(self) -> str: TESTS:: sage: repr(Compositions()) - 'Compositions of non-negative integers' + 'Compositions of nonnegative integers' """ - return "Compositions of non-negative integers" + return "Compositions of nonnegative integers" def subset(self, size=None): """ @@ -2129,7 +2157,7 @@ def __iter__(self): def composition_iterator_fast(n): """ - Iterator over compositions of ``n`` yielded as lists. + Iterator over compositions of `n` yielded as lists. TESTS:: diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index 8ee363fb275..1e05da84c4e 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -37,7 +37,7 @@ class CompositionTableau(CombinatorialElement, metaclass=ClasscallMetaclass): INPUT: - - ``t`` -- A list of lists + - ``t`` -- list of lists EXAMPLES:: @@ -211,10 +211,7 @@ def descent_set(self): sage: CompositionTableau([[1],[3,2],[4,4]]).descent_set() [1, 3] """ - cols = {} - for row in self: - for col, i in enumerate(row): - cols[i] = col + cols = {i: col for row in self for col, i in enumerate(row)} return sorted(i for i in cols if i + 1 in cols and cols[i + 1] >= cols[i]) def descent_composition(self): @@ -278,16 +275,12 @@ class CompositionTableaux(UniqueRepresentation, Parent): INPUT: - Keyword arguments: - - ``size`` -- the size of the composition tableaux - ``shape`` -- the shape of the composition tableaux - ``max_entry`` -- the maximum entry for the composition tableaux - Positional arguments: - - - The first argument is interpreted as ``size`` or ``shape`` depending on - whether it is an integer or a composition. + The first argument is interpreted as ``size`` or ``shape`` depending on + whether it is an integer or a composition. EXAMPLES:: @@ -403,7 +396,7 @@ def __classcall_private__(cls, *args, **kwargs): if not isinstance(size, (int, Integer)): raise ValueError("size must be an integer") elif size < 0: - raise ValueError("size must be non-negative") + raise ValueError("size must be nonnegative") if shape is not None: # use in (and not isinstance) below so that lists can be used as @@ -411,7 +404,7 @@ def __classcall_private__(cls, *args, **kwargs): if shape not in Compositions(): raise ValueError("shape must be a composition") if any(i == 0 for i in shape): - raise ValueError("shape must have non-zero parts") + raise ValueError("shape must have nonzero parts") shape = Composition(shape) if (size is not None) and (shape is not None): @@ -460,9 +453,7 @@ def _element_constructor_(self, t): - ``t`` -- data which can be interpreted as a composition tableau - OUTPUT: - - - The corresponding CompositionTableau object + OUTPUT: the corresponding CompositionTableau object TESTS:: @@ -572,17 +563,15 @@ class CompositionTableaux_size(CompositionTableaux): INPUT: - - ``n`` -- a nonnegative integer. - - ``max_entry`` -- a nonnegative integer. This keyword argument defaults to ``n``. - - OUTPUT: + - ``n`` -- nonnegative integer + - ``max_entry`` -- nonnegative integer (default: `n`) - - The class of composition tableaux of size ``n``. + OUTPUT: the class of composition tableaux of size `n` """ def __init__(self, n, max_entry=None): r""" - Initializes the class of composition tableaux of size ``n``. + Initialize the class of composition tableaux of size `n`. TESTS:: @@ -674,9 +663,8 @@ class CompositionTableaux_shape(CompositionTableaux): INPUT: - - ``comp`` -- a composition. - - ``max_entry`` -- a nonnegative integer. This keyword argument defaults - to the size of ``comp``. + - ``comp`` -- a composition + - ``max_entry`` -- nonnegative integer (default: size of ``comp``) """ def __init__(self, comp, max_entry=None): """ diff --git a/src/sage/combinat/constellation.py b/src/sage/combinat/constellation.py index b4c3bfa4333..e22c3428bb4 100644 --- a/src/sage/combinat/constellation.py +++ b/src/sage/combinat/constellation.py @@ -129,19 +129,20 @@ def Constellations(*data, **options): def Constellation(g=None, mutable=False, connected=True, check=True): r""" - Constellation + Constellation. INPUT: - - ``g`` -- a list of permutations + - ``g`` -- list of permutations - - ``mutable`` -- whether the result is mutable or not. Default is ``False``. + - ``mutable`` -- boolean (default: ``False``); whether the result is + mutable or not - - ``connected`` -- whether the result should be connected. Default is - ``True``. + - ``connected`` -- boolean (default: ``True``); whether the result should + be connected - - ``check`` -- whether or not to check. If it is ``True``, then the - list ``g`` must contains no ``None``. + - ``check`` -- boolean (default: ``True``); whether or not to check. If it + is ``True``, then the list ``g`` must contain no ``None``. EXAMPLES: @@ -181,7 +182,7 @@ def Constellation(g=None, mutable=False, connected=True, check=True): class Constellation_class(Element): r""" - Constellation + Constellation. A constellation or a tuple of permutations `(g_0,g_1,...,g_k)` such that the product `g_0 g_1 ... g_k` is the identity. @@ -360,7 +361,8 @@ def genus(self): def _check(self): r""" - Check that the constellation is valid and if not raise ValueError. + Check that the constellation is valid and if not raise + :exc:`ValueError`. TESTS:: @@ -447,9 +449,7 @@ def connected_components(self): """ Return the connected components. - OUTPUT: - - A list of connected constellations. + OUTPUT: list of connected constellations EXAMPLES:: @@ -675,7 +675,7 @@ def g(self, i=None): INPUT: - - i -- integer or ``None`` (default) + - ``i`` -- integer or ``None`` (default) If ``None`` , return instead the list of all `g_i`. @@ -932,9 +932,9 @@ def __init__(self, length, degree, sym=None, connected=True): self._length = length self._degree = degree if self._length < 0: - raise ValueError("length should be a non-negative integer") + raise ValueError("length should be a nonnegative integer") if self._degree < 0: - raise ValueError("degree should be a non-negative integer") + raise ValueError("degree should be a nonnegative integer") self._sym = sym @@ -1187,9 +1187,7 @@ def braid_group_action(self): Return a list of graphs that corresponds to the braid group action on ``self`` up to isomorphism. - OUTPUT: - - - list of graphs + OUTPUT: list of graphs EXAMPLES:: @@ -1278,10 +1276,10 @@ def __init__(self, profile, domain=None, connected=True): r""" OPTIONS: - - ``profile`` -- a list of integer partitions of the same integer + - ``profile`` -- list of integer partitions of the same integer - - ``connected`` -- a boolean (default: ``True``) that specify - if we consider only connected constellations. + - ``connected`` -- boolean (default: ``True``); whether we consider + only connected constellations TESTS:: @@ -1469,7 +1467,7 @@ def perms_sym_init(g, sym=None): - ``sym`` -- a symmetric group - - ``gg`` -- a list of permutations + - ``gg`` -- list of permutations EXAMPLES:: @@ -1520,13 +1518,13 @@ def perms_sym_init(g, sym=None): def perms_are_connected(g, n): """ - Checks that the action of the generated group is transitive + Check that the action of the generated group is transitive. INPUT: - - a list of permutations of `[0, n-1]` (in a SymmetricGroup) + - ``g`` -- list of permutations of `[0, n-1]` (in a SymmetricGroup) - - an integer `n` + - ``n`` -- integer EXAMPLES:: @@ -1547,7 +1545,7 @@ def perms_are_connected(g, n): def perms_canonical_labels_from(x, y, j0, verbose=False): r""" - Return canonical labels for ``x``, ``y`` that starts at ``j0`` + Return canonical labels for ``x``, ``y`` that starts at ``j0``. .. WARNING:: @@ -1562,9 +1560,7 @@ def perms_canonical_labels_from(x, y, j0, verbose=False): - ``j0`` -- an index in [0, ..., n] - OUTPUT: - - mapping: a permutation that specify the new labels + OUTPUT: mapping: a permutation that specify the new labels EXAMPLES:: @@ -1636,11 +1632,9 @@ def perm_invert(p): INPUT: - a permutation of {0,..,n-1} given by a list of values - - OUTPUT: + - ``p`` -- a permutation of {0,..,n-1} given by a list of values - a permutation of {0,..,n-1} given by a list of values + OUTPUT: a permutation of {0,..,n-1} given by a list of values EXAMPLES:: @@ -1656,15 +1650,13 @@ def perm_invert(p): def perm_conjugate(p, s): """ - Return the conjugate of the permutation `p` by the permutation `s`. + Return the conjugate of the permutation `p` by the permutation `s`. INPUT: - two permutations of {0,..,n-1} given by lists of values - - OUTPUT: + - ``p``, ``s`` -- two permutations of {0,..,n-1} given by lists of values - a permutation of {0,..,n-1} given by a list of values + OUTPUT: a permutation of {0,..,n-1} given by a list of values EXAMPLES:: @@ -1685,16 +1677,14 @@ def perms_canonical_labels(p, e=None): INPUT: - - ``p`` is a list of at least 2 permutations + - ``p`` -- list of at least 2 permutations - - ``e`` is None or a list of integer in the domain of the + - ``e`` -- ``None`` or a list of integer in the domain of the permutations. If provided, then the renumbering algorithm is only performed from the elements of ``e``. - OUTPUT: - - - a pair made of a list of permutations (as a list of lists) and a - list that corresponds to the conjugacy used. + OUTPUT: a pair made of a list of permutations (as a list of lists) and a + list that corresponds to the conjugacy used. EXAMPLES:: diff --git a/src/sage/combinat/core.py b/src/sage/combinat/core.py index 41265d793db..21ce49f57f1 100644 --- a/src/sage/combinat/core.py +++ b/src/sage/combinat/core.py @@ -102,7 +102,7 @@ def __init__(self, parent, core): raise ValueError("%s is not a %s-core" % (part, k)) CombinatorialElement.__init__(self, parent, core) - def __eq__(self, other): + def __eq__(self, other) -> bool: """ Test for equality. @@ -123,7 +123,7 @@ def __eq__(self, other): self.parent().k == other.parent().k) return False - def __ne__(self, other): + def __ne__(self, other) -> bool: """ Test for un-equality. @@ -169,7 +169,7 @@ def __hash__(self): self._hash = hash(tuple(self._list)) + hash(self.parent().k) return self._hash - def _latex_(self): + def _latex_(self) -> str: r""" Output the LaTeX representation of this core as a partition. @@ -346,11 +346,13 @@ def affine_symmetric_group_action(self, w, transposition=False): INPUT: - - ``w`` is a tuple of integers `[w_1,\ldots,w_m]` with `0\le w_j bool: r""" - Checks whether ``self`` contains ``other``. + Check whether ``self`` contains ``other``. INPUT: - ``other`` -- another `k`-core or a list - OUTPUT: a boolean + OUTPUT: boolean This returns ``True`` if the Ferrers diagram of ``self`` contains the Ferrers diagram of ``other``. @@ -630,7 +631,6 @@ def __init__(self, k, n): sage: C = Cores(3, 4) sage: TestSuite(C).run() - """ self.k = k self.n = n @@ -660,7 +660,7 @@ def list(self): def from_partition(self, part): r""" - Converts the partition ``part`` into a core (as the identity map). + Convert the partition ``part`` into a core (as the identity map). This is the inverse method to :meth:`~sage.combinat.core.Core.to_partition`. diff --git a/src/sage/combinat/crystals/affine.py b/src/sage/combinat/crystals/affine.py index 186d2ea373e..e8f927246bc 100644 --- a/src/sage/combinat/crystals/affine.py +++ b/src/sage/combinat/crystals/affine.py @@ -233,7 +233,7 @@ def _element_constructor_(self, *value, **options): def __contains__(self, x): r""" - Checks whether ``x`` is an element of ``self``. + Check whether `x` is an element of ``self``. EXAMPLES:: @@ -442,7 +442,7 @@ def phi0(self): def phi(self, i): r""" - Returns the maximal time the crystal operator `f_i` can be applied to self. + Return the maximal time the crystal operator `f_i` can be applied to ``self``. EXAMPLES:: @@ -537,7 +537,7 @@ class AffineCrystalFromClassicalAndPromotion(AffineCrystalFromClassical): - ``automorphism, inverse_automorphism`` -- a function on the elements of the ``classical_crystal`` - - ``dynkin_node`` -- an integer specifying the classical node in the + - ``dynkin_node`` -- integer specifying the classical node in the image of the zero node under the automorphism sigma EXAMPLES:: diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 9749e16f0ec..5bfb0988ce3 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -366,7 +366,7 @@ def to_tableau(self): def affine_factorizations(w, l, weight=None): r""" - Return all factorizations of ``w`` into ``l`` factors or of weight ``weight``. + Return all factorizations of `w` into `l` factors or of weight ``weight``. INPUT: @@ -374,7 +374,8 @@ def affine_factorizations(w, l, weight=None): - ``l`` -- nonnegative integer - - ``weight`` -- (default: None) tuple of nonnegative integers specifying the length of the factors + - ``weight`` -- (default: ``None``) tuple of nonnegative integers + specifying the length of the factors EXAMPLES:: diff --git a/src/sage/combinat/crystals/affinization.py b/src/sage/combinat/crystals/affinization.py index d849e407c3f..32f56ff545f 100644 --- a/src/sage/combinat/crystals/affinization.py +++ b/src/sage/combinat/crystals/affinization.py @@ -85,7 +85,7 @@ def __init__(self, B): We skip the Stembridge axioms test since this is an abstract crystal:: sage: A = crystals.KirillovReshetikhin(['A',2,1], 2, 2).affinization() - sage: TestSuite(A).run(skip="_test_stembridge_local_axioms") # long time + sage: TestSuite(A).run(skip='_test_stembridge_local_axioms') # long time """ if not B.cartan_type().is_affine(): raise ValueError("must be an affine crystal") diff --git a/src/sage/combinat/crystals/alcove_path.py b/src/sage/combinat/crystals/alcove_path.py index 27222de68c7..dc41f63b6b5 100644 --- a/src/sage/combinat/crystals/alcove_path.py +++ b/src/sage/combinat/crystals/alcove_path.py @@ -53,18 +53,18 @@ class CrystalOfAlcovePaths(UniqueRepresentation, Parent): INPUT: - ``cartan_type`` -- Cartan type of a finite or affine untwisted root - system. + system - - ``weight`` -- Dominant weight as a list of (integral) coefficients of - the fundamental weights. + - ``weight`` -- dominant weight as a list of (integral) coefficients of + the fundamental weights - - ``highest_weight_crystal`` -- (Default: ``True``) If ``True`` + - ``highest_weight_crystal`` -- (default: ``True``) if ``True`` returns the highest weight crystal. If ``False`` returns an object which is close to being isomorphic to the tensor product of Kirillov-Reshetikhin crystals of column shape in the following sense: We get all the vertices, but only some of the edges. We'll call the included edges pseudo-Demazure. They are - all non-zero edges and the 0-edges not at the end of a 0-string + all nonzero edges and the 0-edges not at the end of a 0-string of edges, i.e. not those with `f_{0}(b) = b'` with `\varphi_0(b) =1`. (Whereas Demazure 0-edges are those that are not at the beginning of a zero string.) In this case the @@ -250,7 +250,7 @@ def __classcall_private__(cls, starting_weight, cartan_type=None, sage: B1 is B2 True """ - if isinstance(cartan_type, bool): # new style signature, optional arguments leak over + if isinstance(cartan_type, bool): # new style signature, optional arguments leak over highest_weight_crystal = cartan_type elif isinstance(cartan_type, (list, tuple)): # old style signature # switch positional arguments @@ -270,9 +270,10 @@ def __classcall_private__(cls, starting_weight, cartan_type=None, P = R.weight_space(extended=extended) Lambda = P.basis() offset = R.index_set()[Integer(0)] - starting_weight = P.sum(starting_weight[j-offset]*Lambda[j] for j in R.index_set()) + starting_weight = P.sum(starting_weight[j - offset] * Lambda[j] + for j in R.index_set()) - #set defaults + # set defaults if highest_weight_crystal is None: highest_weight_crystal = True @@ -295,7 +296,7 @@ def __init__(self, starting_weight, highest_weight_crystal): sage: TestSuite(C).run() #long time sage: C = crystals.AlcovePaths(['A',2,1],[1,0],False) - sage: TestSuite(C).run(skip="_test_stembridge_local_axioms") #long time + sage: TestSuite(C).run(skip='_test_stembridge_local_axioms') #long time Check that :issue:`20292` is fixed:: @@ -334,9 +335,9 @@ def __init__(self, starting_weight, highest_weight_crystal): self._R = RootsWithHeight(starting_weight) self._finite_cartan_type = False - self.module_generators = ( self.element_class(self, ()), ) + self.module_generators = (self.element_class(self, ()),) - def _repr_(self): + def _repr_(self) -> str: """ Return a string representation of ``self``. @@ -367,7 +368,7 @@ def _element_constructor_(self, data): return self.element_class(self, data) elif isinstance(data, list): lambda_chain = self._R.lambda_chain() - #data starts indexing at 0 + # data starts indexing at 0 return self.element_class(self, tuple(sorted([lambda_chain[i] for i in data]))) def vertices(self): @@ -393,10 +394,10 @@ def vertices(self): EXAMPLES:: - sage: C = crystals.AlcovePaths(['C',2],[1,0]) + sage: C = crystals.AlcovePaths(['C', 2], [1, 0]) sage: C.vertices() [[], [0], [0, 1], [0, 1, 2]] - sage: C = crystals.AlcovePaths(['C',2,1],[2,1],False) + sage: C = crystals.AlcovePaths(['C', 2, 1], [2, 1], False) sage: len(C.vertices()) 80 @@ -420,12 +421,12 @@ def vertices(self): # lst contains ordered pairs (w,l) l= list of positions that get # you to the word, it needs to be refreshed - #initialization + # initialization lst = [] for i in range(len_lambda_chain): associated_reflection = lambda_chain[i].root.associated_reflection() if len(associated_reflection) == 1: - lst.append( (prod([ s[j] for j in associated_reflection ]), [i]) ) + lst.append((prod([s[j] for j in associated_reflection]), [i])) l = copy(lst) @@ -433,18 +434,18 @@ def vertices(self): lst2 = [] for x in lst: suc = getattr(x[0], successors)() - for j in range(x[1][-1]+1, len_lambda_chain): + for j in range(x[1][-1] + 1, len_lambda_chain): temp = x[0] * prod( - [ s[k] for k in lambda_chain[j].root.associated_reflection() ]) + [s[k] for k in lambda_chain[j].root.associated_reflection()]) if temp in suc: - lst2.append((temp,x[1]+[j])) - l.append((temp,x[1]+[j])) - if lst2 == []: + lst2.append((temp, x[1] + [j])) + l.append((temp, x[1] + [j])) + if not lst2: break else: lst = lst2 - return [ [] ] + [i[1] for i in l] + return [[]] + [i[1] for i in l] class CrystalOfAlcovePathsElement(ElementWrapper): @@ -453,7 +454,7 @@ class CrystalOfAlcovePathsElement(ElementWrapper): INPUT: - - ``data`` -- a list of folding positions in the lambda chain (indexing + - ``data`` -- list of folding positions in the lambda chain (indexing starts at 0) or a tuple of :class:`RootsWithHeight` giving folding positions in the lambda chain. @@ -612,8 +613,7 @@ def phi(self, i): raise NotImplementedError # I think the M below should still work in this case - M = Integer(m)/2 - Integer(1)/2 - return M + return Integer(m) / 2 - Integer(1) / 2 def epsilon(self, i): r""" @@ -627,7 +627,7 @@ def epsilon(self, i): sage: [c.epsilon(2) for c in C] [0, 0, 1, 2, 1, 1, 0, 0] """ - #crude but functional + # crude but functional j = 0 temp = self temp = temp.e(i) @@ -677,24 +677,21 @@ def weight(self): weight = -self.parent().weight for i in self.value[::-1]: root = root_space(i.root) - weight = -i.height*root + weight.reflection(root) + weight = -i.height * root + weight.reflection(root) WLR = self.parent().weight_lattice_realization() if self.cartan_type().is_affine() and self.parent()._highest_weight_crystal: # We assume that WLR is the (extended) weight lattice - wt = WLR._from_dict({i: Integer(c) for i,c in -weight}, + wt = WLR._from_dict({i: Integer(c) for i, c in -weight}, remove_zeros=False) return wt La = WLR.fundamental_weights() - wt = WLR.sum(Integer(c) * La[i] for i,c in -weight) + wt = WLR.sum(Integer(c) * La[i] for i, c in -weight) if self.cartan_type().is_affine(): assert not self.parent()._highest_weight_crystal wt -= La[0] * wt.level() return wt - #def __repr__(self): - #return str(self.integer_sequence()) - def plot(self): r""" Return a plot ``self``. @@ -716,7 +713,7 @@ def plot(self): for i in integer_sequence: foldings[i] = True affine_ambient_space = RootSystem(ct.affine()).ambient_space() - return affine_ambient_space.plot() + affine_ambient_space.plot_alcove_walk( word, foldings=foldings, labels=False) + return affine_ambient_space.plot() + affine_ambient_space.plot_alcove_walk(word, foldings=foldings, labels=False) def _richcmp_(self, other, op): r""" @@ -776,7 +773,7 @@ def _folding_data(self, i): INPUT: - - ``i`` -- element of the index_set of the underlying root_system. + - ``i`` -- element of the index_set of the underlying root_system OUTPUT: @@ -855,11 +852,11 @@ def _folding_data(self, i): for k in range(int(c1), int(c2)): - x = R( sign_Beta * Beta , k) + x = R(sign_Beta * Beta, k) if ( - ( j < len(J) - 1 and J[j] < x <= J[j+1] ) or - ( j == len(J) - 1 and J[j] < x) + (j < len(J) - 1 and J[j] < x <= J[j + 1]) or + (j == len(J) - 1 and J[j] < x) ): signs[x] = sign_Beta @@ -877,7 +874,7 @@ def e(self, i): INPUT: - - ``i`` -- element of the index set of the underlying root system. + - ``i`` -- element of the index set of the underlying root system EXAMPLES:: @@ -905,19 +902,20 @@ def e(self, i): KR_test = finite_cartan_type and i == 0 and m_index < len(gi) - 1 KR_test = KR_test and M >= 1 - ###################################################################### + ################################################################### # NOTE: # In the KR_case we want to insure that positions[m_index] is in J # If m_index > 0 then it's always true # If m_index == 0 then M >=1 guarantees this - ###################################################################### + ################################################################### - if ( (not finite_cartan_type or i != 0) and m_index < len(gi)-1 # alpha_i is a simple root - ) or KR_test: + if ((not finite_cartan_type or i != 0) and m_index < len(gi) - 1) or KR_test: + # first condition above means that alpha_i is a simple root J.remove(positions[m_index]) - if m_index+1 < len(positions): # if m_index+1 != 'infinity' - # i.e. positions[m_index+1] makes sense + if m_index + 1 < len(positions): + # if m_index+1 != 'infinity' + # i.e. positions[m_index+1] makes sense J.append(positions[m_index + 1]) return_value = Parent(tuple(sorted(J))) @@ -943,7 +941,7 @@ def _gi(self, i): INPUT: - - ``i`` -- element of the index_set of the underlying root_system. + - ``i`` -- element of the index_set of the underlying root_system OUTPUT: @@ -981,23 +979,25 @@ def _gi(self, i): if not positions: return (positions, [signs['infinity']]) - gi = [ signs[ positions[0] ] ] - for j in range(1,len(positions)): + gi = [signs[positions[0]]] + for j in range(1, len(positions)): gi.append( - gi[j-1] + - signs[positions[j-1]]*self._eps(positions[j-1]) + signs[positions[j]] ) - gi.append( gi[-1] + - signs[positions[-1]]*self._eps(positions[-1]) + signs['infinity'] ) + gi[j-1] + + signs[positions[j-1]] * self._eps(positions[j-1]) + + signs[positions[j]]) + gi.append(gi[-1] + + signs[positions[-1]] * self._eps(positions[-1]) + + signs['infinity']) return (positions, gi) def f(self, i): r""" - Returns the `i`-th crystal lowering operator on ``self``. + Return the `i`-th crystal lowering operator on ``self``. INPUT: - - ``i`` -- element of the index_set of the underlying root_system. + - ``i`` -- element of the index_set of the underlying root_system EXAMPLES:: @@ -1007,7 +1007,6 @@ def f(self, i): ((alpha[1], 0),) sage: x.f(1).f(2) ((alpha[1], 0), (alpha[1] + alpha[2], 2)) - """ Parent = self.parent() finite_cartan_type = Parent._finite_cartan_type @@ -1040,12 +1039,13 @@ def f(self, i): # # otherwise if m_index - 1 > 0 then (C2) is enough - if ( (not finite_cartan_type or i != 0) and M > 0 # alpha_i is a simple root - ) or KR_test :# KR case + if ((not finite_cartan_type or i != 0) and M > 0) or KR_test: + # first condition above means that alpha_i is a simple root - J.append(positions[m_index-1]) - if m_index < len(positions): # if m_index != 'infinity' - # thus positions[m_index] makes sense + J.append(positions[m_index - 1]) + if m_index < len(positions): + # if m_index != 'infinity' + # thus positions[m_index] makes sense J.remove(positions[m_index]) return_value = Parent(tuple(sorted(J))) @@ -1096,7 +1096,6 @@ def _eps(self, root): (alpha[1], 1) sage: x._eps(y) 1 - """ if root in self.value: return -1 @@ -1124,7 +1123,7 @@ def path(self): W = WeylGroup(self.parent()._R._cartan_type, prefix='s') s = W.simple_reflections() - #start at the identity + # start at the identity w = W.one() ret = [w] for i in self: @@ -1170,9 +1169,9 @@ def __init__(self, cartan_type): self._cartan_type = cartan_type Parent.__init__(self, category=HighestWeightCrystals().Infinite()) - self.module_generators = ( self.element_class(self, (), 0), ) + self.module_generators = (self.element_class(self, (), 0),) - def _repr_(self): + def _repr_(self) -> str: """ Return a string representation of ``self``. @@ -1231,7 +1230,7 @@ def e(self, i): A = CrystalOfAlcovePaths(self.parent()._cartan_type, [shift]*n) try: y = A(tuple([A._R(rt.root, rt.height - s(rt.root)) for rt in y.value])) - except ValueError: # Invalid height (and not admissible) + except ValueError: # Invalid height (and not admissible) break shift += 1 return type(self)(self.parent(), @@ -1271,7 +1270,7 @@ def f(self, i): shift = self._shift + 1 n = self.parent()._cartan_type.rank() A = CrystalOfAlcovePaths(self.parent()._cartan_type, [shift]*n) - y = A(tuple([A._R(rt, h + shift*s(rt)) for rt,h in self.value])).f(i) + y = A(tuple([A._R(rt, h + shift*s(rt)) for rt, h in self.value])).f(i) return type(self)(self.parent(), tuple([(rt.root, rt.height - shift*s(rt.root)) for rt in y.value]), @@ -1391,14 +1390,14 @@ def projection(self, k=None): return None s = lambda rt: int(sum(rt.associated_coroot().coefficients())) n = self.parent()._cartan_type.rank() - A = CrystalOfAlcovePaths(self.parent()._cartan_type, [k]*n) - return A(tuple([A._R(rt, h + k*s(rt)) for rt,h in self.value])) + A = CrystalOfAlcovePaths(self.parent()._cartan_type, [k] * n) + return A(tuple([A._R(rt, h + k*s(rt)) for rt, h in self.value])) class RootsWithHeight(UniqueRepresentation, Parent): r""" Data structure of the ordered pairs `(\beta,k)`, - where `\beta` is a positive root and `k` is a non-negative integer. A total + where `\beta` is a positive root and `k` is a nonnegative integer. A total order is implemented on this set, and depends on the weight. INPUT: @@ -1475,7 +1474,7 @@ def __init__(self, weight): sage: R = RootsWithHeight(['A',2],[3,2]) sage: TestSuite(R).run() """ - Parent.__init__(self, category=Sets() ) + Parent.__init__(self, category=Sets()) cartan_type = weight.parent().cartan_type() self._cartan_type = cartan_type @@ -1518,7 +1517,7 @@ def _max_height(self, root): @cached_method def word(self): r""" - Gives the initial alcove path (`\lambda`-chain) in terms of simple + Give the initial alcove path (`\lambda`-chain) in terms of simple roots. Used for plotting the path. .. NOTE:: @@ -1535,7 +1534,7 @@ def word(self): cartan_type = self._root_system.cartan_type() if not cartan_type.is_finite(): raise NotImplementedError - lambda_chain = [ x.root for x in self.lambda_chain() ] + lambda_chain = [x.root for x in self.lambda_chain()] coroot_lattice = RootSystem(cartan_type).coroot_lattice() cohighest_root = coroot_lattice.highest_root() @@ -1545,11 +1544,11 @@ def word(self): beta = lambda_chain[i] for j in reversed(range(i)): beta = beta.reflection(lambda_chain[j]) - #beta is now a simple root or the highest root + # beta is now a simple root or the highest root coroot = beta.associated_coroot() - support = coroot.support() # the path is in dual affine space - if len(support) == 1: # beta is a simple root + support = coroot.support() # the path is in dual affine space + if len(support) == 1: # beta is a simple root word.append(support[0]) elif coroot == -cohighest_root: word.append(0) @@ -1576,10 +1575,8 @@ def lambda_chain(self): if not self._root_lattice.cartan_type().is_finite(): raise ValueError("Cartan type {0} is not finite".format(self._root_lattice.cartan_type())) - l = [] - for i in self._root_lattice.positive_roots(): - for j in range(self._max_height(i)): - l.append(self(i,j)) + l = (self(i, j) for i in self._root_lattice.positive_roots() + for j in range(self._max_height(i))) return sorted(l) @@ -1611,7 +1608,7 @@ def _an_element_(self): sage: R._an_element_() (alpha[1], 0) """ - return self( self._root_lattice.from_vector(vector([1])), 0 ) + return self(self._root_lattice.from_vector(vector([1])), 0) class RootsWithHeightElement(Element): @@ -1620,8 +1617,8 @@ class RootsWithHeightElement(Element): INPUT: - - ``root`` -- A positive root `\beta` in our root system - - ``height`` -- Is an integer, such that + - ``root`` -- a positive root `\beta` in our root system + - ``height`` -- integer such that `0 \leq l \leq \langle \lambda, \beta^{\vee} \rangle` EXAMPLES:: @@ -1659,9 +1656,10 @@ def __init__(self, parent, root, height): if not 0 <= height < max_height: raise ValueError("%d out of allowed range [%d,%d)" % (height, 0, max_height)) - v = [height/max_height] - v.extend( [ x/max_height for x in root.associated_coroot().to_vector() ] ) - #v.insert(0, height/max_height) + v = [height / max_height] + v.extend(x / max_height + for x in root.associated_coroot().to_vector()) + # v.insert(0, height/max_height) # the map from (root, height) --> _cmp_v is injective @@ -1744,8 +1742,8 @@ def _richcmp_(self, other, op): # I suspect that if you redefine this method to produce a # different (valid) `\lambda`-chain the rest of the # code should still work. - #todo: check if self and other have the same parent ? - #assert self.parent() is other.parent(), "elements have different parents" + # todo: check if self and other have the same parent ? + # assert self.parent() is other.parent(), "elements have different parents" return richcmp(self._cmp_v, other._cmp_v, op) @@ -1771,24 +1769,24 @@ def _test_some_specific_examples(clss=CrystalOfAlcovePaths): True """ # This appears in Lenart. - C = clss(['G',2],[0,1]) + C = clss(['G', 2], [0, 1]) G = C.digraph() GT = DiGraph({ - () : {(0) : 2 }, - (0) : {(0,8) : 1 }, - (0,1) : {(0,1,7) : 2 }, - (0,1,2) : {(0,1,2,9) : 1 }, - (0,1,2,3) : {(0,1,2,3,4) : 2 }, - (0,1,2,6) : {(0,1,2,3) : 1 }, - (0,1,2,9) : {(0,1,2,6) : 1 }, - (0,1,7) : {(0,1,2) : 2 }, - (0,1,7,9) : {(0,1,2,9) : 2 }, - (0,5) : {(0,1) : 1, (0,5,7) : 2 }, - (0,5,7) : {(0,5,7,9) : 1 }, - (0,5,7,9) : {(0,1,7,9) : 1 }, - (0,8) : {(0,5) : 1 } - }) + (): {(0): 2}, + (0): {(0, 8): 1}, + (0, 1): {(0, 1, 7): 2}, + (0, 1, 2): {(0, 1, 2, 9): 1}, + (0, 1, 2, 3): {(0, 1, 2, 3, 4): 2}, + (0, 1, 2, 6): {(0, 1, 2, 3): 1}, + (0, 1, 2, 9): {(0, 1, 2, 6): 1}, + (0, 1, 7): {(0, 1, 2): 2}, + (0, 1, 7, 9): {(0, 1, 2, 9): 2}, + (0, 5): {(0, 1): 1, (0, 5, 7): 2}, + (0, 5, 7): {(0, 5, 7, 9): 1}, + (0, 5, 7, 9): {(0, 1, 7, 9): 1}, + (0, 8): {(0, 5): 1} + }) if not G.is_isomorphic(GT): return False @@ -1798,23 +1796,23 @@ def _test_some_specific_examples(clss=CrystalOfAlcovePaths): # Some examples from Hong--Kang: # type C, ex. 8.3.5, pg. 189 - C = clss(['C',3],[0,0,1]) + C = clss(['C', 3], [0, 0, 1]) G = C.digraph() GT = DiGraph({ - ():{ (0): 3}, - (0):{ (0, 6): 2}, - (0, 1):{ (0, 1, 3): 3, (0, 1, 7): 1}, - (0, 1, 2):{ (0, 1, 2, 3): 3}, - (0, 1, 2, 3):{ (0, 1, 2, 3, 8): 2}, - (0, 1, 2, 3, 4):{ (0, 1, 2, 3, 4, 5): 3}, - (0, 1, 2, 3, 8):{ (0, 1, 2, 3, 4): 2}, - (0, 1, 3):{ (0, 1, 3, 7): 1}, - (0, 1, 3, 7):{ (0, 1, 2, 3): 1, (0, 1, 3, 7, 8): 2}, - (0, 1, 3, 7, 8):{ (0, 1, 2, 3, 8): 1}, - (0, 1, 7):{ (0, 1, 2): 1, (0, 1, 3, 7): 3}, - (0, 6):{ (0, 1): 2, (0, 6, 7): 1}, - (0, 6, 7):{ (0, 1, 7): 2} - }) + (): {(0): 3}, + (0): {(0, 6): 2}, + (0, 1): {(0, 1, 3): 3, (0, 1, 7): 1}, + (0, 1, 2): {(0, 1, 2, 3): 3}, + (0, 1, 2, 3): {(0, 1, 2, 3, 8): 2}, + (0, 1, 2, 3, 4): {(0, 1, 2, 3, 4, 5): 3}, + (0, 1, 2, 3, 8): {(0, 1, 2, 3, 4): 2}, + (0, 1, 3): {(0, 1, 3, 7): 1}, + (0, 1, 3, 7): {(0, 1, 2, 3): 1, (0, 1, 3, 7, 8): 2}, + (0, 1, 3, 7, 8): {(0, 1, 2, 3, 8): 1}, + (0, 1, 7): {(0, 1, 2): 1, (0, 1, 3, 7): 3}, + (0, 6): {(0, 1): 2, (0, 6, 7): 1}, + (0, 6, 7): {(0, 1, 7): 2} + }) if not G.is_isomorphic(GT): return False @@ -1822,68 +1820,68 @@ def _test_some_specific_examples(clss=CrystalOfAlcovePaths): print("C3 example passed.") # type B, fig. 8.1 pg. 172 - C = clss(['B',3],[2,0,0]) + C = clss(['B', 3], [2, 0, 0]) G = C.digraph() GT = DiGraph({ - ():{ (6): 1}, - (0):{ (0, 7): 2}, - (0, 1):{ (0, 1, 11): 3}, - (0, 1, 2):{ (0, 1, 2, 9): 2}, - (0, 1, 2, 3):{ (0, 1, 2, 3, 10): 1}, - (0, 1, 2, 3, 10):{ (0, 1, 2, 3, 4): 1}, - (0, 1, 2, 9):{ (0, 1, 2, 3): 2, (0, 1, 2, 9, 10): 1}, - (0, 1, 2, 9, 10):{ (0, 1, 2, 3, 10): 2}, - (0, 1, 5):{ (0, 1, 2): 3, (0, 1, 5, 9): 2}, - (0, 1, 5, 9):{ (0, 1, 2, 9): 3, (0, 1, 5, 9, 10): 1}, - (0, 1, 5, 9, 10):{ (0, 1, 2, 9, 10): 3}, - (0, 1, 8):{ (0, 1, 5): 3}, - (0, 1, 8, 9):{ (0, 1, 5, 9): 3, (0, 1, 8, 9, 10): 1}, - (0, 1, 8, 9, 10):{ (0, 1, 5, 9, 10): 3}, - (0, 1, 11):{ (0, 1, 8): 3}, - (0, 7):{ (0, 1): 2, (0, 7, 11): 3}, - (0, 7, 8):{ (0, 7, 8, 9): 2}, - (0, 7, 8, 9):{ (0, 1, 8, 9): 2}, - (0, 7, 8, 9, 10):{ (0, 1, 8, 9, 10): 2}, - (0, 7, 11):{ (0, 1, 11): 2, (0, 7, 8): 3}, - (6):{ (0): 1, (6, 7): 2}, - (6, 7):{ (0, 7): 1, (6, 7, 11): 3}, - (6, 7, 8):{ (0, 7, 8): 1, (6, 7, 8, 9): 2}, - (6, 7, 8, 9):{ (6, 7, 8, 9, 10): 1}, - (6, 7, 8, 9, 10):{ (0, 7, 8, 9, 10): 1}, - (6, 7, 11):{ (0, 7, 11): 1, (6, 7, 8): 3} - }) + (): {(6): 1}, + (0): {(0, 7): 2}, + (0, 1): {(0, 1, 11): 3}, + (0, 1, 2): {(0, 1, 2, 9): 2}, + (0, 1, 2, 3): {(0, 1, 2, 3, 10): 1}, + (0, 1, 2, 3, 10): {(0, 1, 2, 3, 4): 1}, + (0, 1, 2, 9): {(0, 1, 2, 3): 2, (0, 1, 2, 9, 10): 1}, + (0, 1, 2, 9, 10): {(0, 1, 2, 3, 10): 2}, + (0, 1, 5): {(0, 1, 2): 3, (0, 1, 5, 9): 2}, + (0, 1, 5, 9): {(0, 1, 2, 9): 3, (0, 1, 5, 9, 10): 1}, + (0, 1, 5, 9, 10): {(0, 1, 2, 9, 10): 3}, + (0, 1, 8): {(0, 1, 5): 3}, + (0, 1, 8, 9): {(0, 1, 5, 9): 3, (0, 1, 8, 9, 10): 1}, + (0, 1, 8, 9, 10): {(0, 1, 5, 9, 10): 3}, + (0, 1, 11): {(0, 1, 8): 3}, + (0, 7): {(0, 1): 2, (0, 7, 11): 3}, + (0, 7, 8): {(0, 7, 8, 9): 2}, + (0, 7, 8, 9): {(0, 1, 8, 9): 2}, + (0, 7, 8, 9, 10): {(0, 1, 8, 9, 10): 2}, + (0, 7, 11): {(0, 1, 11): 2, (0, 7, 8): 3}, + (6): {(0): 1, (6, 7): 2}, + (6, 7): {(0, 7): 1, (6, 7, 11): 3}, + (6, 7, 8): {(0, 7, 8): 1, (6, 7, 8, 9): 2}, + (6, 7, 8, 9): {(6, 7, 8, 9, 10): 1}, + (6, 7, 8, 9, 10): {(0, 7, 8, 9, 10): 1}, + (6, 7, 11): {(0, 7, 11): 1, (6, 7, 8): 3} + }) if not G.is_isomorphic(GT): return False else: print("B3 example 1 passed.") - C = clss(['B',3],[0,1,0]) + C = clss(['B', 3], [0, 1, 0]) G = C.digraph() GT = DiGraph({ - ():{ (0): 2}, - (0):{ (0, 1): 1, (0, 7): 3}, - (0, 1):{ (0, 1, 7): 3}, - (0, 1, 2):{ (0, 1, 2, 8): 2}, - (0, 1, 2, 3):{ (0, 1, 2, 3, 5): 1, (0, 1, 2, 3, 9): 3}, - (0, 1, 2, 3, 4):{ (0, 1, 2, 3, 4, 5): 1}, - (0, 1, 2, 3, 4, 5):{ (0, 1, 2, 3, 4, 5, 6): 2}, - (0, 1, 2, 3, 5):{ (0, 1, 2, 3, 5, 9): 3}, - (0, 1, 2, 3, 5, 9):{ (0, 1, 2, 3, 4, 5): 3}, - (0, 1, 2, 3, 9):{ (0, 1, 2, 3, 4): 3, (0, 1, 2, 3, 5, 9): 1}, - (0, 1, 2, 5):{ (0, 1, 2, 3, 5): 2}, - (0, 1, 2, 8):{ (0, 1, 2, 3): 2}, - (0, 1, 2, 8, 9):{ (0, 1, 2, 3, 9): 2}, - (0, 1, 7):{ (0, 1, 2): 3, (0, 1, 7, 8): 2}, - (0, 1, 7, 8):{ (0, 1, 7, 8, 9): 3}, - (0, 1, 7, 8, 9):{ (0, 1, 2, 8, 9): 3}, - (0, 2):{ (0, 1, 2): 1, (0, 2, 5): 2}, - (0, 2, 5):{ (0, 2, 5, 8): 1}, - (0, 2, 5, 8):{ (0, 1, 2, 5): 1}, - (0, 7):{ (0, 1, 7): 1, (0, 2): 3} - }) + (): {(0): 2}, + (0): {(0, 1): 1, (0, 7): 3}, + (0, 1): {(0, 1, 7): 3}, + (0, 1, 2): {(0, 1, 2, 8): 2}, + (0, 1, 2, 3): {(0, 1, 2, 3, 5): 1, (0, 1, 2, 3, 9): 3}, + (0, 1, 2, 3, 4): {(0, 1, 2, 3, 4, 5): 1}, + (0, 1, 2, 3, 4, 5): {(0, 1, 2, 3, 4, 5, 6): 2}, + (0, 1, 2, 3, 5): {(0, 1, 2, 3, 5, 9): 3}, + (0, 1, 2, 3, 5, 9): {(0, 1, 2, 3, 4, 5): 3}, + (0, 1, 2, 3, 9): {(0, 1, 2, 3, 4): 3, (0, 1, 2, 3, 5, 9): 1}, + (0, 1, 2, 5): {(0, 1, 2, 3, 5): 2}, + (0, 1, 2, 8): {(0, 1, 2, 3): 2}, + (0, 1, 2, 8, 9): {(0, 1, 2, 3, 9): 2}, + (0, 1, 7): {(0, 1, 2): 3, (0, 1, 7, 8): 2}, + (0, 1, 7, 8): {(0, 1, 7, 8, 9): 3}, + (0, 1, 7, 8, 9): {(0, 1, 2, 8, 9): 3}, + (0, 2): {(0, 1, 2): 1, (0, 2, 5): 2}, + (0, 2, 5): {(0, 2, 5, 8): 1}, + (0, 2, 5, 8): {(0, 1, 2, 5): 1}, + (0, 7): {(0, 1, 7): 1, (0, 2): 3} + }) if not G.is_isomorphic(GT): return False @@ -1919,9 +1917,9 @@ def compare_graphs(g1, g2, node1, node2): sage: compare_graphs(G1, G2, C( () ), G2.vertices(sort=True)[0]) True """ - for out_edge in g1.outgoing_edges( node1 ): + for out_edge in g1.outgoing_edges(node1): matched = False - for o2 in g2.outgoing_edges( node2 ): + for o2 in g2.outgoing_edges(node2): if o2[2] == out_edge[2]: if matched: print("ERROR: Two edges with the same label for ", out_edge, " exist.") @@ -1965,16 +1963,17 @@ def _test_against_tableaux(R, N, k, clss=CrystalOfAlcovePaths): T = CrystalOfTableaux(R, shape=shape) ct = len(T.list()) print(" T has ", ct, " nodes.") - #T.digraph().show(edge_labels=True) + # T.digraph().show(edge_labels=True) H = T.digraph() weight = T.module_generators[0].weight() - w = [ weight.scalar(RootSystem(R).ambient_space().simple_coroot(i)) for i in range(1,N+1) ] + w = [weight.scalar(RootSystem(R).ambient_space().simple_coroot(i)) + for i in range(1, N + 1)] print(" C weight ", w) - C = clss(R , w) + C = clss(R, w) cc = len(C.list()) - #C.digraph().show(edge_labels=True) + # C.digraph().show(edge_labels=True) G = C.digraph() print(" C has ", cc, " nodes.") if cc != ct: diff --git a/src/sage/combinat/crystals/bkk_crystals.py b/src/sage/combinat/crystals/bkk_crystals.py index b3658fd28a4..785f3fc7619 100644 --- a/src/sage/combinat/crystals/bkk_crystals.py +++ b/src/sage/combinat/crystals/bkk_crystals.py @@ -3,7 +3,7 @@ Benkart-Kang-Kashiwara crystals for the general-linear Lie superalgebra """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2017 Franco Saliola # 2017 Travis Scrimshaw # 2017 Anne Schilling @@ -12,8 +12,8 @@ # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.parent import Parent from sage.categories.regular_supercrystals import RegularSuperCrystals @@ -60,7 +60,7 @@ def __classcall_private__(cls, ct, shape): """ ct = CartanType(ct) shape = _Partitions(shape) - if len(shape) > ct.m + 1 and shape[ct.m+1] > ct.n + 1: + if len(shape) > ct.m + 1 and shape[ct.m + 1] > ct.n + 1: raise ValueError("invalid hook shape") return super().__classcall__(cls, ct, shape) @@ -80,16 +80,14 @@ def __init__(self, ct, shape): C = CrystalOfBKKLetters(ct) tr = shape.conjugate() mg = [] - for i,col_len in enumerate(tr): - for j in range(col_len - m): - mg.append(C(i+1)) - for j in range(max(0, m - col_len), m): - mg.append(C(-j-1)) + for i, col_len in enumerate(tr, start=1): + mg.extend(C(i) for j in range(col_len - m)) + mg.extend(C(-j - 1) for j in range(max(0, m - col_len), m)) mg = list(reversed(mg)) Parent.__init__(self, category=RegularSuperCrystals()) self.module_generators = (self.element_class(self, mg),) - def _repr_(self): + def _repr_(self) -> str: """ Return a string representation of ``self``. diff --git a/src/sage/combinat/crystals/direct_sum.py b/src/sage/combinat/crystals/direct_sum.py index 190a3279513..cbb39c7d4f6 100644 --- a/src/sage/combinat/crystals/direct_sum.py +++ b/src/sage/combinat/crystals/direct_sum.py @@ -33,8 +33,8 @@ class DirectSumOfCrystals(DisjointUnionEnumeratedSets): INPUT: - - ``crystals`` -- a list of crystals of the same Cartan type - - ``keepkey`` -- a boolean + - ``crystals`` -- list of crystals of the same Cartan type + - ``keepkey`` -- boolean The option ``keepkey`` is by default set to ``False``, assuming that the crystals are all distinct. In this case the elements of diff --git a/src/sage/combinat/crystals/elementary_crystals.py b/src/sage/combinat/crystals/elementary_crystals.py index c89dd7504fd..7619e0e0a5e 100644 --- a/src/sage/combinat/crystals/elementary_crystals.py +++ b/src/sage/combinat/crystals/elementary_crystals.py @@ -162,7 +162,7 @@ def e(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -181,7 +181,7 @@ def f(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -216,9 +216,9 @@ class TCrystal(UniqueRepresentation, Parent): INPUT: - - ``cartan_type`` -- A Cartan type + - ``cartan_type`` -- a Cartan type - - ``weight`` -- An element of the weight lattice of type ``cartan_type`` + - ``weight`` -- an element of the weight lattice of type ``cartan_type`` EXAMPLES:: @@ -300,7 +300,7 @@ def _element_constructor_(self, weight): INPUT: - - ``weight`` -- An element of the weight lattice + - ``weight`` -- an element of the weight lattice EXAMPLES:: @@ -387,7 +387,7 @@ def epsilon(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -406,7 +406,7 @@ def phi(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -474,7 +474,7 @@ class RCrystal(UniqueRepresentation, Parent): - ``cartan_type`` -- a Cartan type - ``weight`` -- an element of the weight lattice of type ``cartan_type`` - - ``dual`` -- (default: ``False``) boolean + - ``dual`` -- boolean (default: ``False``) EXAMPLES: @@ -563,7 +563,7 @@ def _element_constructor_(self, weight): INPUT: - - ``weight`` -- An element of the weight lattice + - ``weight`` -- an element of the weight lattice EXAMPLES:: @@ -658,7 +658,7 @@ def epsilon(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -686,7 +686,7 @@ def phi(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -827,7 +827,7 @@ def _element_constructor_(self, m): INPUT: - - ``m`` -- An integer + - ``m`` -- integer EXAMPLES:: @@ -952,7 +952,7 @@ def e(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -974,7 +974,7 @@ def f(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -996,7 +996,7 @@ def epsilon(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -1019,7 +1019,7 @@ def phi(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -1208,7 +1208,7 @@ def epsilon(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -1225,7 +1225,7 @@ def phi(self, i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: diff --git a/src/sage/combinat/crystals/fast_crystals.py b/src/sage/combinat/crystals/fast_crystals.py index fe32db2a419..e427c6b48aa 100644 --- a/src/sage/combinat/crystals/fast_crystals.py +++ b/src/sage/combinat/crystals/fast_crystals.py @@ -42,10 +42,10 @@ class FastCrystal(UniqueRepresentation, Parent): - ``cartan_type`` -- the Cartan type and must be either type `A_2`, `B_2`, or `C_2` - - ``shape`` -- A shape is of the form ``[l1,l2]`` where ``l1`` and ``l2`` + - ``shape`` -- a shape is of the form ``[l1,l2]`` where ``l1`` and ``l2`` are either integers or (in type `B_2`) half integers such that ``l1 - l2`` is integral. It is assumed that ``l1 >= l2 >= 0``. If - ``l1`` and ``l2` are integers, this will produce a crystal + ``l1`` and ``l2`` are integers, this will produce a crystal isomorphic to the one obtained by ``crystals.Tableaux(type, shape=[l1,l2])``. Furthermore ``crystals.FastRankTwo(['B', 2], l1+1/2, l2+1/2)`` produces a crystal @@ -101,9 +101,9 @@ class FastCrystal(UniqueRepresentation, Parent): [2, 1, 0]] """ @staticmethod - def __classcall__(cls, cartan_type, shape, format="string"): + def __classcall__(cls, cartan_type, shape, format='string'): """ - Normalize the input arguments to ensure unique representation + Normalize the input arguments to ensure unique representation. EXAMPLES:: @@ -261,7 +261,7 @@ def __call__(self, value): def digraph(self): """ - Return the digraph associated to self. + Return the digraph associated to ``self``. EXAMPLES:: @@ -273,7 +273,7 @@ def digraph(self): def cmp_elements(self, x,y): r""" - Return True if and only if there is a path from x to y in the + Return ``True`` if and only if there is a path from `x` to `y` in the crystal graph. Because the crystal graph is classical, it is a directed acyclic @@ -318,7 +318,7 @@ def __init__(self, parent, value, format): def weight(self): """ - Return the weight of self. + Return the weight of ``self``. EXAMPLES:: @@ -403,7 +403,7 @@ def _richcmp_(self, other, op): def e(self, i): """ - Return the action of `e_i` on self. + Return the action of `e_i` on ``self``. EXAMPLES:: @@ -422,7 +422,7 @@ def e(self, i): def f(self, i): """ - Return the action of `f_i` on self. + Return the action of `f_i` on ``self``. EXAMPLES:: diff --git a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py index 5e33395086d..9ba9e3c1e0a 100644 --- a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py +++ b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py @@ -76,7 +76,7 @@ class DecreasingHeckeFactorization(Element, metaclass=InheritComparisonClasscall @staticmethod def __classcall_private__(self, t, max_value=None, parent=None): """ - Assign the correct parent for ``t`` and call ``t`` as an element of that parent + Assign the correct parent for ``t`` and call ``t`` as an element of that parent. EXAMPLES:: @@ -209,7 +209,7 @@ def __hash__(self): def __eq__(self, other): """ - Return True if ``self`` equals ``other`` and False otherwise. + Return ``True`` if ``self`` equals ``other`` and ``False`` otherwise. EXAMPLES:: @@ -224,7 +224,8 @@ def __eq__(self, other): def __lt__(self,other): """ - Return True if ``self`` comes before ``other`` and False otherwise. + Return ``True`` if ``self`` comes before ``other`` and ``False`` + otherwise. We say that `h_1` comes before `h_2` if either weight of `h_1 <` weight of `h_2` lexicographically, or if both weights of `h_1` and `h_2` are equal, @@ -446,9 +447,11 @@ class FullyCommutativeStableGrothendieckCrystal(UniqueRepresentation, Parent): - ``factors`` -- the number of factors in the factorization - - ``excess`` -- the total number of letters in the factorization minus the length of a reduced word for ``w`` + - ``excess`` -- the total number of letters in the factorization minus the + length of a reduced word for ``w`` - - ``shape`` -- (default: ``False``) indicator for input ``w``, True if ``w`` is entered as a (skew) shape and False otherwise. + - ``shape`` -- boolean (default: ``False``); indicator for input ``w``, + ``True`` if ``w`` is entered as a (skew) shape and ``False`` otherwise EXAMPLES:: @@ -847,9 +850,9 @@ def _generate_decreasing_hecke_factorizations(w, factors, ex, weight=None, paren - ``ex`` -- number of extra letters in each decreasing factorizations - - ``weight`` -- (default: None) if None, returns all possible decreasing - factorizations, otherwise return all those with the - specified weight + - ``weight`` -- (default: ``None``) if ``None``, returns all possible + decreasing factorizations, otherwise return all those with the specified + weight EXAMPLES:: @@ -962,7 +965,8 @@ def _lowest_weights(w, factors, ex, parent=None): - ``ex`` -- number of extra letters in each decreasing factorizations - - ``parent`` -- (default: None) parent of the decreasing factorizations, automatically assigned if it is None + - ``parent`` -- (default: ``None``) parent of the decreasing + factorizations, automatically assigned if it is None EXAMPLES:: @@ -1143,27 +1147,27 @@ def _apply_relations(word, position, move): sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _apply_relations sage: w = [2, 1, 3, 4] - sage: _apply_relations(w, position=1, move="pq=qp") + sage: _apply_relations(w, position=1, move='pq=qp') [2, 3, 1, 4] sage: w = [1, 3, 2, 1, 2, 4] - sage: _apply_relations(w, position=2, move="pqp=qpq") + sage: _apply_relations(w, position=2, move='pqp=qpq') [1, 3, 1, 2, 1, 4] sage: w = [2, 3, 1, 2, 2, 3] - sage: _apply_relations(w, position=3, move="pp=p") + sage: _apply_relations(w, position=3, move='pp=p') [2, 3, 1, 2, 3] sage: w = [2, 3, 1, 2, 3] - sage: _apply_relations(w, position=3, move="p=pp") + sage: _apply_relations(w, position=3, move='p=pp') [2, 3, 1, 2, 2, 3] sage: w = [2, 3, 1, 2, 2, 3] - sage: _apply_relations(w, position=2, move="pqq=ppq") + sage: _apply_relations(w, position=2, move='pqq=ppq') [2, 3, 1, 1, 2, 3] sage: w = [2, 3, 1, 1, 2, 3] - sage: _apply_relations(w, position=2, move="ppq=pqq") + sage: _apply_relations(w, position=2, move='ppq=pqq') [2, 3, 1, 2, 2, 3] """ w = list(word) diff --git a/src/sage/combinat/crystals/generalized_young_walls.py b/src/sage/combinat/crystals/generalized_young_walls.py index 12ab091f6cd..65e1af9b61b 100644 --- a/src/sage/combinat/crystals/generalized_young_walls.py +++ b/src/sage/combinat/crystals/generalized_young_walls.py @@ -20,7 +20,7 @@ - [KS2010]_ """ -#****************************************************************************** +# ***************************************************************************** # Copyright (C) 2013 # # Lucas David-Roesler (roesler at lvc dot edu) @@ -28,8 +28,8 @@ # Travis Scrimshaw (tscrim at ucdavis dot edu) # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** import re from copy import deepcopy @@ -69,7 +69,7 @@ def __init__(self, parent, data): sage: mg = Y.module_generators[0] sage: TestSuite(mg).run() """ - i = len(data)-1 + i = len(data) - 1 while i >= 0 and not data[i]: data.pop() i -= 1 @@ -118,7 +118,7 @@ def _repr_diagram(self): wall += '|' if row == []: wall += '|' - ret += wall.rjust(2*self.cols+1) + "\n" + ret += wall.rjust(2 * self.cols + 1) + "\n" return ret def _ascii_art_(self): @@ -175,9 +175,9 @@ def _unicode_art_(self): import unicodedata v = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL') vl = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL AND LEFT') - table = [[None]*(self.cols-len(row)) + row for row in reversed(self)] + table = [[None] * (self.cols - len(row)) + row for row in reversed(self)] ret = [] - for i,row in enumerate(ascii_art_table(table, use_unicode=True).splitlines()): + for i, row in enumerate(ascii_art_table(table, use_unicode=True).splitlines()): if row[-1] == " ": if i % 2 == 0: ret.append(row[:-1] + vl) @@ -228,27 +228,27 @@ def raw_signature(self, i): [['-', 3, 6], ['-', 1, 4], ['-', 6, 1]] """ sig = [] - rank = self.parent().cartan_type().rank() # n+1 + rank = self.parent().cartan_type().rank() # n+1 for row in range(self.rows): - if self.data[row] == [] and i == ( row % rank ): + if self.data[row] == [] and i == (row % rank): sig.append(['+', row, 0]) elif self.data[row] == []: continue - elif self.data[row][-1] == ( (i+1) % rank ): - sig.append(['+', row, len(self.data[row])+1]) + elif self.data[row][-1] == ((i + 1) % rank): + sig.append(['+', row, len(self.data[row]) + 1]) elif self.data[row][-1] == i: sig.append(['-', row, len(self.data[row])]) return sorted(sig, key=self._sig_sort) - def _sig_sort(self,a): + def _sig_sort(self, a): r""" Internal command used to appropriately sort the output from :meth:`raw_signature()`. INPUT: - - `a` -- list of the form ``['s',j,k]`` where `s` is a string, `j` is an integer - and `k` is an integer + - ``a`` -- list of the form ``['s',j,k]`` where `s` is a string, `j` is + an integer and `k` is an integer EXAMPLES:: @@ -256,7 +256,7 @@ def _sig_sort(self,a): sage: hw._sig_sort(['+',1,0]) (0, 1) """ - return (-a[2],a[1]) + return (-a[2], a[1]) def generate_signature(self, i): r""" @@ -273,20 +273,20 @@ def generate_signature(self, i): sig = [] rank = self.parent().cartan_type().classical().rank() for row in range(self.rows): - if self.data[row] == [] and i == ( row % (rank+1) ): + if self.data[row] == [] and i == (row % (rank + 1)): sig.append(['+', row, 0]) elif self.data[row] == []: continue - elif self.data[row][-1] == ( (i+1) % (rank+1) ): - sig.append(['+', row, len(self.data[row])+1]) + elif self.data[row][-1] == ((i + 1) % (rank + 1)): + sig.append(['+', row, len(self.data[row]) + 1]) elif self.data[row][-1] == i: sig.append(['-', row, len(self.data[row])]) sig = sorted(sig, key=self._sig_sort) - strsig = ''.join( x[0] for x in sig) + strsig = ''.join(x[0] for x in sig) reducedsig = strsig - while re.search(r"\+\s*-",reducedsig): - reducedsig = re.sub(r"\+\s*-", lambda match : ''.ljust(len(match.group(0))) , reducedsig) - return (sig,reducedsig) + while re.search(r"\+\s*-", reducedsig): + reducedsig = re.sub(r"\+\s*-", lambda match: ''.ljust(len(match.group(0))), reducedsig) + return (sig, reducedsig) def signature(self, i): r""" @@ -385,18 +385,19 @@ def number_of_parts(self): sage: y.number_of_parts() 8 """ - n = self.parent().cartan_type().rank()-1 + n = self.parent().cartan_type().rank() - 1 new = self.data[:] i = 0 while i < len(new): r = new[i] - if r == [] or r in new[i+1:]: + if not r or r in new[i + 1:]: new.pop(i) - elif r[0] == n and len(r) % (n+1) == 0: - for j in range(n+1): - temp = [k % (n+1) for k in range(j+len(r)/(n+1)-1,j-1,-1)] + elif r[0] == n and not len(r) % (n + 1): + for j in range(n + 1): + temp = [k % (n + 1) + for k in range(j + len(r) // (n + 1) - 1, j - 1, -1)] if temp not in new: - new.insert(i+1, temp) + new.insert(i + 1, temp) new.pop(i) else: i += 1 @@ -425,7 +426,7 @@ def sum_of_weighted_row_lengths(self): 15 """ n = self.parent().cartan_type().rank() - 1 - m = lambda i: len([1 for r in self.data if r and r[0] == (i-1) % (n+1)]) + m = lambda i: len([1 for r in self.data if r and r[0] == (i - 1) % (n + 1)]) for r in self.data: if r and r[0] == n: raise ValueError('Statistic only valid for generalized Young walls in Y_0') @@ -461,11 +462,11 @@ def e(self, i): newdata.append(list(self.data[r][:-1])) else: newdata.append(list(self.data[r])) - return self.__class__(self.parent(),newdata) + return self.__class__(self.parent(), newdata) else: return None - def f(self,i): + def f(self, i): r""" Return the application of the Kashiwara lowering operator `f_i` on ``self``. @@ -510,11 +511,12 @@ def latex_large(self): '\\begin{tikzpicture}[baseline=5,scale=.45] \n \\foreach \\x [count=\\s from 0] in \n{{},{1,0,3,2},{2,1},{3,2,1,0,3,2},{},{},{2}} \n{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\scriptsize] at (-\\t,\\s) {$\\y$}; \n \\draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \\draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \\draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \\draw[-,thick] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n' """ s = "" - if self.data == []: + if not self.data: s += "\\emptyset" else: s += "\\begin{tikzpicture}[baseline=5,scale=.45] \n \\foreach \\x [count=\\s from 0] in \n" - s += "{" + ','.join("{" + ','.join( str(i) for i in r ) + "}" for r in self.data ) + "} \n" + s += "{" + ','.join("{" + ','.join(str(i) for i in r) + "}" + for r in self.data) + "} \n" s += "{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\scriptsize] at (-\\t,\\s) {$\\y$}; \n \\draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \\draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \\draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \\draw[-,thick] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n" return s @@ -529,11 +531,12 @@ def _latex_(self): '\\begin{tikzpicture}[baseline=5,scale=.25] \\foreach \\x [count=\\s from 0] in \n{{},{1,0,3,2},{2,1},{3,2,1,0,3,2},{},{},{2}} \n{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\tiny] at (-\\t,\\s) {$\\y$}; \n \\draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \\draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \\draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \\draw[-] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n' """ s = "" - if self.data == []: - s += "\\emptyset" + if not self.data: + s += "\\emptyset" else: s += "\\begin{tikzpicture}[baseline=5,scale=.25] \\foreach \\x [count=\\s from 0] in \n" - s += "{" + ','.join("{" + ','.join( str(i) for i in r ) + "}" for r in self.data ) + "} \n" + s += "{" + ','.join("{" + ','.join(str(i) for i in r) + "}" + for r in self.data) + "} \n" s += "{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\tiny] at (-\\t,\\s) {$\\y$}; \n \\draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \\draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \\draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \\draw[-] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n" return s @@ -544,7 +547,7 @@ def weight(self, root_lattice=False): INPUT: - ``root_lattice`` -- boolean determining whether weight should appear - in root lattice or not in extended affine weight lattice. + in root lattice or not in extended affine weight lattice EXAMPLES:: @@ -554,16 +557,13 @@ def weight(self, root_lattice=False): sage: x.weight(root_lattice=True) -2*alpha[0] - 3*alpha[1] - 5*alpha[2] - 3*alpha[3] """ - W = [] - E = self.cartan_type().root_system().weight_lattice(extended=True) L = self.cartan_type().root_system().root_lattice() alpha = L.simple_roots() - for r in self.data: - for i in r: - W.append(-1*alpha[i]) + W = sum(-1 * alpha[i] for r in self.data for i in r) if not root_lattice: - return E(sum(W)) - return L(sum(W)) + E = self.cartan_type().root_system().weight_lattice(extended=True) + return E(W) + return L(W) def epsilon(self, i): r""" @@ -587,7 +587,7 @@ def epsilon(self, i): self = self.e(i) if self is None: break - eps = eps+1 + eps += 1 return eps def Epsilon(self): @@ -601,7 +601,7 @@ def Epsilon(self): Lambda[0] + 3*Lambda[2] """ La = self.cartan_type().root_system().weight_lattice().fundamental_weights() - return sum(self.epsilon(i)*La[i] for i in self.index_set()) + return sum(self.epsilon(i) * La[i] for i in self.index_set()) def phi(self, i): r""" @@ -635,7 +635,7 @@ def Phi(self): 2*Lambda[0] + Lambda[1] - Lambda[2] + Lambda[3] """ La = self.cartan_type().root_system().weight_lattice(extended=True).fundamental_weights() - return sum(self.phi(i)*La[i] for i in self.index_set()) + return sum(self.phi(i) * La[i] for i in self.index_set()) def column(self, k): r""" @@ -651,15 +651,10 @@ def column(self, k): sage: hw.column(1) [] """ - C = [] - for row in self.data: - if k-1 < len(row): - C.append(row[k-1]) - else: - C.append(None) - return C + return [row[k - 1] if k - 1 < len(row) else None + for row in self.data] - def a(self,i,k): + def a(self, i, k): r""" Return the number `a_i(k)` of `i`-colored boxes in the ``k``-th column of ``self``. @@ -674,13 +669,11 @@ def a(self,i,k): sage: y.a(3,2) 0 """ - A = [] - for c in range(len(self.column(k))): - if self.column(k)[c] == i: - A.append(self.column(k)[c]) + A = [1 for c in range(len(self.column(k))) + if self.column(k)[c] == i] return len(A) - def in_highest_weight_crystal(self,La): + def in_highest_weight_crystal(self, La): r""" Return a boolean indicating if the generalized Young wall element is in the highest weight crystal cut out by the given highest weight @@ -718,14 +711,14 @@ def in_highest_weight_crystal(self,La): ac = self.parent().weight_lattice_realization().simple_coroots() n = self.cartan_type().classical().rank() index_set = self.index_set() - for k in range(1,self.cols+1): + for k in range(1, self.cols + 1): for j in index_set: - if self.a(j,k) - self.a( (j-1) % (n+1) ,k) <= 0: + if self.a(j, k) - self.a((j - 1) % (n + 1), k) <= 0: continue else: p_not_found = True for p in index_set: - if (j+k) % (n+1) == (p+1) % (n+1) and self.a(j,k) - self.a( (j-1) % (n+1) ,k) <= La.scalar(ac[p]): + if (j + k - p - 1) % (n + 1) == 0 and self.a(j, k) - self.a((j - 1) % (n + 1), k) <= La.scalar(ac[p]): p_not_found = False continue else: @@ -836,7 +829,7 @@ def __classcall_private__(cls, n, category=None): sage: Yinf is Yinf2 True """ - return super().__classcall__(cls,n,category) + return super().__classcall__(cls, n, category) def __init__(self, n, category): r""" @@ -845,15 +838,15 @@ def __init__(self, n, category): sage: Yinf = crystals.infinity.GeneralizedYoungWalls(3) sage: TestSuite(Yinf).run() """ - self._cartan_type = CartanType(['A',n,1]) + self._cartan_type = CartanType(['A', n, 1]) if category is None: category = (HighestWeightCrystals(), InfiniteEnumeratedSets()) Parent.__init__(self, category=category) - self.module_generators = (self.element_class(self,[]),) + self.module_generators = (self.element_class(self, []),) Element = GeneralizedYoungWall - def _element_constructor_(self,data): + def _element_constructor_(self, data): r""" Construct an element of ``self`` from ``data``. @@ -868,7 +861,7 @@ def _element_constructor_(self,data): sage: y [[], [1, 0], [2, 1]] """ - return self.element_class(self,data) + return self.element_class(self, data) def _repr_(self): r""" @@ -882,7 +875,7 @@ def _repr_(self): ######################## -## Highest weight GYW ## +# Highest weight GYW # ######################## class CrystalOfGeneralizedYoungWallsElement(GeneralizedYoungWall): @@ -890,7 +883,7 @@ class CrystalOfGeneralizedYoungWallsElement(GeneralizedYoungWall): Element of the highest weight crystal of generalized Young walls. """ - def e(self,i): + def e(self, i): r""" Compute the action of `e_i` restricted to the highest weight crystal. @@ -907,10 +900,10 @@ def e(self,i): if ret is None: return None if ret.in_highest_weight_crystal(self.parent().hw): - return self.__class__(self.parent(),ret.data) + return self.__class__(self.parent(), ret.data) return None - def f(self,i): + def f(self, i): r""" Compute the action of `f_i` restricted to the highest weight crystal. @@ -926,7 +919,7 @@ def f(self,i): """ ret = GeneralizedYoungWall.f(self, i) if ret.in_highest_weight_crystal(self.parent().hw): - return self.__class__(self.parent(),ret.data) + return self.__class__(self.parent(), ret.data) return None def weight(self): @@ -943,7 +936,7 @@ def weight(self): """ return self.parent().weight_lattice_realization()(self.parent().hw + GeneralizedYoungWall.weight(self)) - def phi(self,i): + def phi(self, i): r""" Return the value `\varepsilon_i(Y) + \langle h_i, \mathrm{wt}(Y)\rangle`, where `h_i` is the `i`-th simple @@ -1029,7 +1022,7 @@ def __classcall_private__(cls, n, La): sage: Y is Y1 True """ - La = RootSystem(['A',n,1]).weight_lattice(extended=True)(La) + La = RootSystem(['A', n, 1]).weight_lattice(extended=True)(La) return super().__classcall__(cls, n, La) def __init__(self, n, La): @@ -1043,8 +1036,8 @@ def __init__(self, n, La): sage: TestSuite(YLa).run(skip=["_test_enumerated_set_contains","_test_stembridge_local_axioms"]) # long time """ - InfinityCrystalOfGeneralizedYoungWalls.__init__( self, n, - category=(RegularCrystals(), HighestWeightCrystals(), InfiniteEnumeratedSets()) ) + InfinityCrystalOfGeneralizedYoungWalls.__init__(self, n, + category=(RegularCrystals(), HighestWeightCrystals(), InfiniteEnumeratedSets())) self.hw = La Element = CrystalOfGeneralizedYoungWallsElement diff --git a/src/sage/combinat/crystals/highest_weight_crystals.py b/src/sage/combinat/crystals/highest_weight_crystals.py index 96d7377c029..ef731d57692 100644 --- a/src/sage/combinat/crystals/highest_weight_crystals.py +++ b/src/sage/combinat/crystals/highest_weight_crystals.py @@ -192,7 +192,6 @@ def HighestWeightCrystal(dominant_weight, model=None): ....: C1 = crystals.HighestWeight(wt.to_ambient().to_weight_space(ZZ), model=model) ....: C2 = crystals.HighestWeight(wt, model=model) ....: assert C1 == C2 - """ cartan_type = dominant_weight.parent().cartan_type() if model is None: @@ -310,8 +309,8 @@ def _repr_(self): def module_generator(self): """ - This yields the module generator (or highest weight element) of the classical - crystal of given dominant weight in self. + Yield the module generator (or highest weight element) of the classical + crystal of given dominant weight in ``self``. EXAMPLES:: diff --git a/src/sage/combinat/crystals/induced_structure.py b/src/sage/combinat/crystals/induced_structure.py index 95ed85bf5f8..094a0e7a37b 100644 --- a/src/sage/combinat/crystals/induced_structure.py +++ b/src/sage/combinat/crystals/induced_structure.py @@ -47,8 +47,8 @@ class InducedCrystal(UniqueRepresentation, Parent): - ``X`` -- the base set - ``phi`` -- the map `\Phi` - ``inverse`` -- (optional) the inverse map `\Phi^{-1}` - - ``from_crystal`` -- (default: ``False``) if the induced structure is - of the second type `\Phi : C \to X` + - ``from_crystal`` -- boolean (default: ``False``); if the induced + structure is of the second type `\Phi : C \to X` EXAMPLES: diff --git a/src/sage/combinat/crystals/infinity_crystals.py b/src/sage/combinat/crystals/infinity_crystals.py index 8b2053bec8b..a7f98a369fb 100644 --- a/src/sage/combinat/crystals/infinity_crystals.py +++ b/src/sage/combinat/crystals/infinity_crystals.py @@ -130,7 +130,7 @@ class InfinityCrystalOfTableaux(CrystalOfWords): INPUT: - - ``cartan_type`` -- One of ``['A',n]``, ``['B',n]``, ``['C',n]``, + - ``cartan_type`` -- one of ``['A',n]``, ``['B',n]``, ``['C',n]``, ``['D',n]``, or ``['G',2]``, where ``n`` is a positive integer EXAMPLES:: @@ -307,7 +307,7 @@ def phi(self,i): INPUT: - - ``i`` -- An element of the index set + - ``i`` -- an element of the index set EXAMPLES:: @@ -448,7 +448,7 @@ def reduced_form(self): def seg(self): r""" - Returns the statistic `\mathrm{seg}` of ``self.`` + Return the statistic `\mathrm{seg}` of ``self``. More precisely, following [LS2012]_, define a `k`-segment of a tableau `T` in `\mathcal{B}(\infty)` to be a maximal string diff --git a/src/sage/combinat/crystals/kirillov_reshetikhin.py b/src/sage/combinat/crystals/kirillov_reshetikhin.py index 411725aa0ea..18b1882014d 100644 --- a/src/sage/combinat/crystals/kirillov_reshetikhin.py +++ b/src/sage/combinat/crystals/kirillov_reshetikhin.py @@ -164,7 +164,7 @@ def KirillovReshetikhinCrystal(cartan_type, r, s, model='KN'): - ``r`` -- a label of finite Dynkin diagram - - ``s`` -- a positive integer + - ``s`` -- positive integer - ``model`` -- (default: ``'KN'``) can be one of the following: @@ -330,7 +330,7 @@ def KirillovReshetikhinCrystal(cartan_type, r, s, model='KN'): return KirillovReshetikhinTableaux(cartan_type, r, s) if model in ['RC', 'RiggedConfigurations']: from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations - return RiggedConfigurations(cartan_type, [[r,s]]) + return RiggedConfigurations(cartan_type, [[r, s]]) if model == 'LSPaths': return KirillovReshetikhinCrystalFromLSPaths(cartan_type, r, s) @@ -378,7 +378,7 @@ def KashiwaraNakashimaTableaux(cartan_type, r, s): elif ct.type() == 'D': if r < ct.rank()-2: return KR_type_vertical(ct, r, s) - elif r in {ct.rank()-2,ct.rank()-1}: + elif r in {ct.rank()-2, ct.rank()-1}: return KR_type_spin(ct, r, s) else: raise ValueError("wrong range of parameters") @@ -396,9 +396,9 @@ def KashiwaraNakashimaTableaux(cartan_type, r, s): return KR_type_Cn(ct, r, s) else: raise ValueError("wrong range of parameters") - elif ct == CartanType(['E',6,1]) and r in [1,6,2]: + elif ct == CartanType(['E', 6, 1]) and r in [1, 6, 2]: return KR_type_E6(ct, r, s) - elif ct == CartanType(['E',7,1]) and r in [7]: + elif ct == CartanType(['E', 7, 1]) and r in [7]: return KR_type_E7(ct, r, s) else: raise NotImplementedError @@ -434,7 +434,7 @@ class KirillovReshetikhinGenericCrystal(AffineCrystalFromClassical): def __init__(self, cartan_type, r, s, dual=None): r""" - Initializes a generic Kirillov-Reshetikhin crystal. + Initialize a generic Kirillov-Reshetikhin crystal. TESTS:: @@ -482,7 +482,7 @@ def _element_constructor_(self, *args, **options): elt = args[0] # Check to make sure it can be converted if elt.cartan_type() != self.cartan_type() \ - or elt.parent().r() != self._r or elt.parent().s() != self._s: + or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape") to_hw = elt.to_classical_highest_weight() @@ -758,9 +758,10 @@ def promotion(self): [[1, 3], [2, 4]] """ T = self.classical_crystal + ct = self._cartan_type[1] return CrystalDiagramAutomorphism(T, - lambda x: T(x.to_tableau().promotion(self._cartan_type[1])), - cache=False) + lambda x: T(x.to_tableau().promotion(ct)), + cache=False) @cached_method def promotion_inverse(self): @@ -782,9 +783,10 @@ def promotion_inverse(self): [[1, 2], [3, 3]] """ T = self.classical_crystal + ct = self._cartan_type[1] return CrystalDiagramAutomorphism(T, - lambda x: T(x.to_tableau().promotion_inverse(self._cartan_type[1])), - cache=False) + lambda x: T(x.to_tableau().promotion_inverse(ct)), + cache=False) def dynkin_diagram_automorphism(self, i): r""" @@ -930,8 +932,8 @@ def dynkin_diagram_automorphism(self, i): return aut[i] def promotion_on_highest_weight_vector(self, b): - """ - Calculates promotion on a `{2,3,...,n}` highest weight vector ``b``. + r""" + Calculate promotion on a `{2, 3, \ldots, n}` highest weight vector `b`. EXAMPLES:: @@ -973,7 +975,7 @@ def from_highest_weight_vector_to_pm_diagram(self, b): True """ n = self.cartan_type().rank() - 1 - inner = Partition([Integer(b.weight()[i]) for i in range(1,n+1)]) + inner = Partition([Integer(b.weight()[i]) for i in range(1, n+1)]) inter = Partition([len([i for i in r if i > 0]) for r in b.to_tableau()]) outer = b.to_tableau().shape() return PMDiagram([self.r(), self.s(), outer, inter, inner], from_shapes=True) @@ -1002,11 +1004,11 @@ def from_pm_diagram_to_highest_weight_vector(self, pm): ulist += list(range(1, h + 1)) for h in pm.heights_of_minus(): if ct_type == 'D': - ulist += list(range(1,rank+1)) + [rank-2-k for k in range(rank-1-h)] + ulist += list(range(1, rank+1)) + [rank-2-k for k in range(rank-1-h)] elif ct_type == 'B': - ulist += list(range(1,rank+1)) + [rank-k for k in range(rank+1-h)] + ulist += list(range(1, rank+1)) + [rank-k for k in range(rank+1-h)] else: - ulist += list(range(1,rank+1)) + [rank-1-k for k in range(rank-h)] + ulist += list(range(1, rank+1)) + [rank-1-k for k in range(rank-h)] for i in reversed(ulist): u = u.f(i) return u @@ -1079,7 +1081,7 @@ def classical_decomposition(self): (Finite dimensional highest weight crystal of type ['E', 6] and highest weight 2*Lambda[1],) """ La = self.cartan_type().classical().root_system().weight_lattice().fundamental_weights() - if self.r() in [1,6]: + if self.r() in [1, 6]: dw = [self.s() * La[self.r()]] elif self.r() == 2: dw = [k*La[2] for k in range(self.s()+1)] @@ -1103,7 +1105,7 @@ def dynkin_diagram_automorphism(self, i): sage: [K.dynkin_diagram_automorphism(i) for i in K.index_set()] [1, 6, 3, 5, 4, 2, 0] """ - aut = [1,6,3,5,4,2,0] + aut = [1, 6, 3, 5, 4, 2, 0] return aut[i] def affine_weight(self, b): @@ -1133,9 +1135,11 @@ def affine_weight(self, b): cl = self.cartan_type().classical() simple_roots = cl.root_system().ambient_space().simple_roots() index_set = cl.index_set() - weight = [Integer(b.weight().scalar( simple_roots[i] )) for i in index_set] + weight = [Integer(b.weight().scalar(simple_roots[i])) + for i in index_set] E6_coeffs = [1, 2, 2, 3, 2, 1] - return tuple([-sum(weight[i] * coeff for i,coeff in enumerate(E6_coeffs))] + weight) + return tuple([-sum(weight[i] * coeff + for i, coeff in enumerate(E6_coeffs))] + weight) @cached_method def hw_auxiliary(self): @@ -1241,11 +1245,11 @@ def promotion_on_highest_weight_vectors(self): dic = self.highest_weight_dict() dic_inv = self.highest_weight_dict_inv() dic_weight = {} - for (weight, i) in dic.values(): + for weight, i in dic.values(): dic_weight[weight] = dic_weight.get(weight, []) + [i] map_index = lambda i_list: max(i_list[1]) + min(i_list[1]) - i_list[0] - map_element = lambda x: ( self.automorphism_on_affine_weight(dic[x][0]), - map_index((dic[x][1], dic_weight[dic[x][0]])) ) + map_element = lambda x: (self.automorphism_on_affine_weight(dic[x][0]), + map_index((dic[x][1], dic_weight[dic[x][0]]))) return {x: dic_inv[map_element(x)] for x in dic} @cached_method @@ -1281,7 +1285,7 @@ def promotion(self): True """ T = self.classical_decomposition() - ind = [1,2,3,4,5] + ind = [1, 2, 3, 4, 5] return CrystalDiagramAutomorphism(T, self.promotion_on_highest_weight_vectors(), ind, automorphism=self.dynkin_diagram_automorphism) @@ -1300,7 +1304,7 @@ def promotion_inverse(self): True """ p = self.promotion() - #return lambda x : p(p(x)) + # return lambda x : p(p(x)) return p * p @@ -1353,7 +1357,7 @@ def ambient_crystal(self): sage: K.ambient_crystal() Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,3) """ - return KashiwaraNakashimaTableaux(['A',2*self.cartan_type().classical().rank()+1,2], + return KashiwaraNakashimaTableaux(['A', 2*self.cartan_type().classical().rank()+1, 2], self.r(), self.s()) @cached_method @@ -1378,13 +1382,12 @@ def ambient_dict_pm_diagrams(self): [3, 1]: [[0, 0], [1, 1], [1]], [3, 3]: [[0, 0], [0, 0], [3]]} """ - ulist = [] s = self.s() r = self.r() m = s // 2 - for i in range(m+1): - for la in IntegerVectors(m-i, min_length=r, max_length=r): - ulist.append(PMDiagram([[j,j] for j in la]+[[s-2*m+2*i]])) + ulist = (PMDiagram([[j, j] for j in la]+[[s-2*m+2*i]]) + for i in range(m + 1) + for la in IntegerVectors(m-i, min_length=r, max_length=r)) return {x.inner_shape(): x for x in ulist} @cached_method @@ -1478,7 +1481,7 @@ class KR_type_CElement(KirillovReshetikhinGenericCrystalElement): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],1,2) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 1, 2) sage: type(K.module_generators[0]) """ @@ -1490,7 +1493,7 @@ def e0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],1,2) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 1, 2) sage: b = K(rows=[]) sage: b.e(0) # indirect doctest [[-1, -1]] @@ -1508,7 +1511,7 @@ def f0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],1,2) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 1, 2) sage: b = K(rows=[]) sage: b.f(0) # indirect doctest [[1, 1]] @@ -1618,7 +1621,7 @@ def module_generator(self): s = self.s() weight = s*Lambda[r] - s*Lambda[0] if r == self.cartan_type().rank() - 1: - weight += s*Lambda[r] # Special case for r == n + weight += s*Lambda[r] # Special case for r == n return [b for b in self.module_generators if b.weight() == weight][0] def classical_decomposition(self): @@ -1641,7 +1644,7 @@ def classical_decomposition(self): The crystal of tableaux of type ['B', 2] and shape(s) [[], [2], [2, 2]] """ return CrystalOfTableaux(['B', self.cartan_type().rank()-1], - shapes=horizontal_dominoes_removed(self.r(),self.s())) + shapes=horizontal_dominoes_removed(self.r(), self.s())) def ambient_crystal(self): r""" @@ -1681,13 +1684,12 @@ def ambient_dict_pm_diagrams(self): [2]: [[0, 0], [1, 1], [0]], [2, 2]: [[0, 0], [0, 0], [2]]} """ - ulist = [] s = self.s() r = self.r() m = s // 2 - for i in range(m+1): - for la in IntegerVectors(m-i, min_length=r, max_length=r): - ulist.append(PMDiagram([[j,j] for j in la]+[[s-2*m+2*i]])) + ulist = (PMDiagram([[j, j] for j in la] + [[s-2*m+2*i]]) + for i in range(m + 1) + for la in IntegerVectors(m-i, min_length=r, max_length=r)) return {x.inner_shape(): x for x in ulist} @cached_method @@ -1885,7 +1887,7 @@ class KR_type_box(KirillovReshetikhinGenericCrystal, AffineCrystalFromClassical) def __init__(self, cartan_type, r, s): r""" - Initializes a Kirillov-Reshetikhin crystal ``self``. + Initialize a Kirillov-Reshetikhin crystal ``self``. TESTS:: @@ -1897,7 +1899,7 @@ def __init__(self, cartan_type, r, s): Kirillov-Reshetikhin crystal of type ['C', 3, 1]^* with (r,s)=(1,1) sage: TestSuite(K).run() """ - KirillovReshetikhinGenericCrystal.__init__(self, cartan_type, r ,s) + KirillovReshetikhinGenericCrystal.__init__(self, cartan_type, r, s) AffineCrystalFromClassical.__init__(self, cartan_type, self.classical_decomposition(), KirillovReshetikhinCrystals()) @@ -1921,7 +1923,7 @@ def classical_decomposition(self): The crystal of tableaux of type ['B', 3] and shape(s) [[], [1], [2], [1, 1], [3], [2, 1], [3, 1], [2, 2], [3, 2], [3, 3]] """ return CrystalOfTableaux(self.cartan_type().classical(), - shapes=partitions_in_box(self.r(),self.s())) + shapes=partitions_in_box(self.r(), self.s())) def ambient_crystal(self): r""" @@ -1938,7 +1940,7 @@ def ambient_crystal(self): """ # calling KR_type_C instead of KirillovReshetikhin(['C',n,1],r,s) has the advantage that # that this also works for r=n for A_{2n}^{(2)}. - return KR_type_C(['C', self.cartan_type().classical().rank(),1], self.r(), 2*self.s()) + return KR_type_C(['C', self.cartan_type().classical().rank(), 1], self.r(), 2*self.s()) @cached_method def highest_weight_dict(self): @@ -1982,7 +1984,7 @@ def ambient_highest_weight_dict(self): def similarity_factor(self): r""" - Sets the similarity factor used to map to the ambient crystal. + Set the similarity factor used to map to the ambient crystal. EXAMPLES:: @@ -2017,10 +2019,10 @@ def to_ambient_crystal(self): ahwd = self.ambient_highest_weight_dict() pdict = {hwd[key]: ahwd[key] for key in hwd} classical = self.cartan_type().classical() - return self.crystal_morphism( pdict, codomain=self.ambient_crystal(), - index_set=classical.index_set(), - scaling_factors=self.similarity_factor(), - cartan_type=classical, check=False ) + return self.crystal_morphism(pdict, codomain=self.ambient_crystal(), + index_set=classical.index_set(), + scaling_factors=self.similarity_factor(), + cartan_type=classical, check=False) @cached_method def from_ambient_crystal(self): @@ -2045,9 +2047,9 @@ def from_ambient_crystal(self): hwd = self.highest_weight_dict() ahwd = self.ambient_highest_weight_dict() pdict_inv = {ahwd[key]: hwd[key] for key in hwd} - return AmbientRetractMap( self, self.ambient_crystal(), pdict_inv, - index_set=self.cartan_type().classical().index_set(), - similarity_factor_domain=self.similarity_factor() ) + return AmbientRetractMap(self, self.ambient_crystal(), pdict_inv, + index_set=self.cartan_type().classical().index_set(), + similarity_factor_domain=self.similarity_factor()) class KR_type_boxElement(KirillovReshetikhinGenericCrystalElement): @@ -2173,7 +2175,7 @@ def _element_constructor_(self, *args, **options): elt = args[0] # Check to make sure it can be converted if elt.cartan_type() != self.cartan_type() \ - or elt.parent().r() != self._r or elt.parent().s() != self._s: + or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape") to_hw = elt.to_classical_highest_weight() @@ -2227,7 +2229,7 @@ def ambient_crystal(self): sage: K.ambient_crystal() Kirillov-Reshetikhin crystal of type ['B', 3, 1]^* with (r,s)=(3,2) """ - return KashiwaraNakashimaTableaux(['A', 2*self.cartan_type().classical().rank()-1,2], + return KashiwaraNakashimaTableaux(['A', 2*self.cartan_type().classical().rank()-1, 2], self.r(), self.s()) @cached_method @@ -2272,7 +2274,7 @@ def ambient_highest_weight_dict(self): def similarity_factor(self): r""" - Sets the similarity factor used to map to the ambient crystal. + Set the similarity factor used to map to the ambient crystal. EXAMPLES:: @@ -2281,14 +2283,14 @@ def similarity_factor(self): {1: 2, 2: 2, 3: 1} """ C = self.cartan_type().classical() - p = {i:2 for i in C.index_set()} + p = {i: 2 for i in C.index_set()} p[C.rank()] = 1 return p @cached_method def to_ambient_crystal(self): r""" - Return a map from self to the ambient crystal of type `A_{2n-1}^{(2)}`. + Return a map from ``self`` to the ambient crystal of type `A_{2n-1}^{(2)}`. EXAMPLES:: @@ -2301,10 +2303,10 @@ def to_ambient_crystal(self): ahwd = self.ambient_highest_weight_dict() pdict = {hwd[key]: ahwd[key] for key in hwd} classical = self.cartan_type().classical() - return self.crystal_morphism( pdict, codomain=self.ambient_crystal(), - index_set=classical.index_set(), - scaling_factors=self.similarity_factor(), - cartan_type=classical, check=False ) + return self.crystal_morphism(pdict, codomain=self.ambient_crystal(), + index_set=classical.index_set(), + scaling_factors=self.similarity_factor(), + cartan_type=classical, check=False) @cached_method def from_ambient_crystal(self): @@ -2327,9 +2329,9 @@ def from_ambient_crystal(self): hwd = self.highest_weight_dict() ahwd = self.ambient_highest_weight_dict() pdict_inv = {ahwd[key]: hwd[key] for key in hwd} - return AmbientRetractMap( self, self.ambient_crystal(), pdict_inv, - index_set=self.cartan_type().classical().index_set(), - similarity_factor_domain=self.similarity_factor() ) + return AmbientRetractMap(self, self.ambient_crystal(), pdict_inv, + index_set=self.cartan_type().classical().index_set(), + similarity_factor_domain=self.similarity_factor()) class KR_type_BnElement(KirillovReshetikhinGenericCrystalElement): @@ -2339,7 +2341,7 @@ class KR_type_BnElement(KirillovReshetikhinGenericCrystalElement): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['B',3,1],3,2) + sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 2) sage: type(K.module_generators[0]) """ @@ -2356,7 +2358,7 @@ def e0(self): sage: b.e(0) # indirect doctest [--+, []] """ - b = self.parent().to_ambient_crystal()(self).e_string([0,0]) + b = self.parent().to_ambient_crystal()(self).e_string([0, 0]) if b is None: return None return self.parent().from_ambient_crystal()(b) @@ -2368,12 +2370,11 @@ def f0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['B',3,1],3,1) + sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 1) sage: b = K.module_generators[0] sage: b.f(0) # indirect doctest - """ - b = self.parent().to_ambient_crystal()(self).f_string([0,0]) + b = self.parent().to_ambient_crystal()(self).f_string([0, 0]) if b is None: return None return self.parent().from_ambient_crystal()(b) @@ -2385,7 +2386,7 @@ def epsilon0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['B',3,1],3,1) + sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 1) sage: b = K.module_generators[0] sage: b.epsilon(0) # indirect doctest 1 @@ -2400,7 +2401,7 @@ def phi0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['B',3,1],3,1) + sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 1) sage: b = K.module_generators[0] sage: b.phi(0) # indirect doctest 0 @@ -2444,7 +2445,8 @@ def classical_decomposition(self): sage: K.classical_decomposition() The crystal of tableaux of type ['C', 3] and shape(s) [[2, 2, 2]] """ - return CrystalOfTableaux(self.cartan_type().classical(), shape=[self.s()]*self.r() ) + return CrystalOfTableaux(self.cartan_type().classical(), + shape=[self.s()] * self.r()) def from_highest_weight_vector_to_pm_diagram(self, b): r""" @@ -2469,7 +2471,7 @@ def from_highest_weight_vector_to_pm_diagram(self, b): True """ n = self.cartan_type().rank()-1 - inner = Partition([Integer(b.weight()[i]) for i in range(1,n+1)]) + inner = Partition([Integer(b.weight()[i]) for i in range(1, n+1)]) inter = Partition([len([i for i in r if i > 0]) for r in b.to_tableau()]) outer = b.to_tableau().shape() return PMDiagram([self.r(), self.s(), outer, inter, inner], from_shapes=True) @@ -2496,7 +2498,7 @@ def from_pm_diagram_to_highest_weight_vector(self, pm): for h in pm.heights_of_addable_plus(): ulist += list(range(1, h + 1)) for h in pm.heights_of_minus(): - ulist += list(range(1,rank+1))+[rank-1-k for k in range(rank-h)] + ulist += list(range(1, rank+1))+[rank-1-k for k in range(rank-h)] for i in reversed(ulist): u = u.f(i) return u @@ -2509,7 +2511,7 @@ class KR_type_CnElement(KirillovReshetikhinGenericCrystalElement): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],3,2) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 2) sage: type(K.module_generators[0]) """ @@ -2523,7 +2525,7 @@ def e0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],3,2) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 2) sage: b = K.module_generators[0] sage: b.e(0) # indirect doctest [[1, 2], [2, 3], [3, -1]] @@ -2535,12 +2537,12 @@ def e0(self): [[3, -3], [-3, -2], [-1, -1]] """ n = self.parent().cartan_type().n - [b,l] = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) + b, l = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) - [l1,l2] = pm.pm_diagram[n-1] + l1, l2 = pm.pm_diagram[n-1] if l1 == 0: return None - pm.pm_diagram[n-1] = [l1-1,l2+1] + pm.pm_diagram[n-1] = [l1-1, l2+1] pm = PMDiagram(pm.pm_diagram) b = self.parent().from_pm_diagram_to_highest_weight_vector(pm) b = b.f_string(reversed(l)) @@ -2560,12 +2562,12 @@ def f0(self): sage: b.f(0) # indirect doctest """ n = self.parent().cartan_type().n - [b,l] = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) + b, l = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) - [l1,l2] = pm.pm_diagram[n-1] + l1, l2 = pm.pm_diagram[n-1] if l2 == 0: return None - pm.pm_diagram[n-1] = [l1+1,l2-1] + pm.pm_diagram[n-1] = [l1+1, l2-1] pm = PMDiagram(pm.pm_diagram) b = self.parent().from_pm_diagram_to_highest_weight_vector(pm) b = b.f_string(reversed(l)) @@ -2577,7 +2579,7 @@ def epsilon0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],3,1) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 1) sage: b = K.module_generators[0] sage: b.epsilon(0) # indirect doctest 1 @@ -2585,7 +2587,7 @@ def epsilon0(self): n = self.parent().cartan_type().n b = self.lift().to_highest_weight(index_set=list(range(2, n + 1)))[0] pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) - [l1,l2] = pm.pm_diagram[n-1] + l1, l2 = pm.pm_diagram[n-1] return l1 def phi0(self): @@ -2594,7 +2596,7 @@ def phi0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['C',3,1],3,1) + sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 1) sage: b = K.module_generators[0] sage: b.phi(0) # indirect doctest 0 @@ -2602,7 +2604,7 @@ def phi0(self): n = self.parent().cartan_type().n b = self.lift().to_highest_weight(index_set=list(range(2, n + 1)))[0] pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) - [l1,l2] = pm.pm_diagram[n-1] + l1, l2 = pm.pm_diagram[n-1] return l2 @@ -2644,7 +2646,7 @@ def _element_constructor_(self, *args, **options): elt = args[0] # Check to make sure it can be converted if elt.cartan_type() != self.cartan_type() \ - or elt.parent().r() != self._r or elt.parent().s() != self._s: + or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have" " the same Cartan type and shape") @@ -2679,7 +2681,8 @@ def classical_decomposition(self): s = s // 2 else: s = s / 2 - return CrystalOfTableaux(self.cartan_type().classical(), shape=[s]*self.r() ) + return CrystalOfTableaux(self.cartan_type().classical(), + shape=[s]*self.r()) def from_highest_weight_vector_to_pm_diagram(self, b): r""" @@ -2732,7 +2735,6 @@ def from_highest_weight_vector_to_pm_diagram(self, b): sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ] sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw) True - """ n = self.cartan_type().rank() - 1 s = self.s() @@ -2741,9 +2743,12 @@ def from_highest_weight_vector_to_pm_diagram(self, b): b = b[1] else: t = b.parent()(rows=[]) - inner = [Integer(2*b.weight()[i]+2*t.weight()[i]) for i in range(1,n+1)] - inter1 = Partition([len([i for i in r if i > 0]) for r in b.to_tableau()]) - inter = Partition([len([i for i in r if i >= 0]) for r in b.to_tableau()]) + inner = [Integer(2*b.weight()[i]+2*t.weight()[i]) + for i in range(1, n+1)] + inter1 = Partition([len([1 for i in r if i > 0]) + for r in b.to_tableau()]) + inter = Partition([len([1 for i in r if i >= 0]) + for r in b.to_tableau()]) if inter != inter1: inner[n-1] += 2 inner = Partition(inner) @@ -2784,7 +2789,7 @@ def from_pm_diagram_to_highest_weight_vector(self, pm): minus = pm.heights_of_minus() l = len([i for i in plus if i == rank-1]) a = (len(plus) + l) // 2 - ulist += sum(([i]*a for i in range(1,rank+1)),[]) + ulist += sum(([i]*a for i in range(1, rank+1)), []) a = (len(minus)-l) // 2 ulist += (list(range(1, rank + 1)) + [rank]) * a for i in reversed(ulist): @@ -2799,7 +2804,7 @@ class KR_type_Dn_twistedElement(KirillovReshetikhinGenericCrystalElement): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['D',4,2],3,2) + sage: K = crystals.KirillovReshetikhin(['D', 4, 2], 3, 2) sage: type(K.module_generators[0]) """ @@ -2813,16 +2818,16 @@ def e0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['D',4,2],3,3) + sage: K = crystals.KirillovReshetikhin(['D', 4, 2], 3, 3) sage: b = K.module_generators[0] sage: b.e(0) # indirect doctest [+++, [[2], [3], [0]]] """ n = self.parent().cartan_type().rank()-1 s = self.parent().s() - [b,l] = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) + b, l = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) - [l1,l2] = pm.pm_diagram[n-1] + l1, l2 = pm.pm_diagram[n-1] l3 = pm.pm_diagram[n-2][0] if l1+l2+l3 == s and l1 == 0: return None @@ -2855,9 +2860,9 @@ def f0(self): """ n = self.parent().cartan_type().rank()-1 s = self.parent().s() - [b,l] = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) + b, l = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) - [l1,l2] = pm.pm_diagram[n-1] + l1, l2 = pm.pm_diagram[n-1] l3 = pm.pm_diagram[n-2][0] if l1+l2+l3 == s and l2 == 0: return None @@ -2881,7 +2886,7 @@ def epsilon0(self): EXAMPLES:: - sage: K=crystals.KirillovReshetikhin(['D',4,2],3,1) + sage: K = crystals.KirillovReshetikhin(['D', 4, 2], 3, 1) sage: b = K.module_generators[0] sage: b.epsilon(0) # indirect doctest 1 @@ -2902,7 +2907,7 @@ def epsilon0(self): True """ n = self.parent().cartan_type().rank() - 1 - [b,l] = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) + b, l = self.lift().to_highest_weight(index_set=list(range(2, n + 1))) pm = self.parent().from_highest_weight_vector_to_pm_diagram(b) l1 = pm.pm_diagram[n-1][0] l4 = pm.pm_diagram[n][0] @@ -3031,7 +3036,7 @@ def _element_constructor_(self, *args, **options): elt = args[0] # Check to make sure it can be converted if elt.cartan_type() != self.cartan_type() \ - or elt.parent().r() != self._r or elt.parent().s() != self._s: + or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape") to_hw = elt.to_classical_highest_weight() @@ -3269,7 +3274,8 @@ def from_coordinates(self, coords): [[2, 2, 3, 0, -1]] """ C = self.classical_decomposition() - if not sum(coords): # Special empty element (i.e. the unique element of B(0)) + if not sum(coords): + # Special empty element (i.e. the unique element of B(0)) return self.element_class(self, C.module_generators[0]) l = C.letters @@ -3300,7 +3306,7 @@ def _element_constructor_(self, *args, **options): elt = args[0] # Check to make sure it can be converted if elt.cartan_type() != self.cartan_type() \ - or elt.parent().r() != self._r or elt.parent().s() != self._s: + or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape") to_hw = elt.to_classical_highest_weight() @@ -3330,10 +3336,10 @@ def coordinates(self): """ letters = self.parent().classical_decomposition().letters l = list(self.value) - return ( l.count(letters(1)), l.count(letters(2)), - 2*l.count(letters(3)) + l.count(letters(0)), - 2*l.count(letters(-3)) + l.count(letters(0)), - l.count(letters(-2)), l.count(letters(-1)) ) + return (l.count(letters(1)), l.count(letters(2)), + 2*l.count(letters(3)) + l.count(letters(0)), + 2*l.count(letters(-3)) + l.count(letters(0)), + l.count(letters(-2)), l.count(letters(-1))) @lazy_attribute def _A(self): @@ -3550,11 +3556,15 @@ def A7_decomposition(self): """ from sage.geometry.polyhedron.constructor import Polyhedron # variables are m_4, m_5, m_6, m_7 - P = Polyhedron(ieqs=[[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1],[0,-1,-1,0,1]], - eqns=[[-self._s,1,1,1,1]]) + P = Polyhedron(ieqs=[[0, 1, 0, 0, 0], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 1], + [0, -1, -1, 0, 1]], + eqns=[[-self._s, 1, 1, 1, 1]]) shapes = [Partition([6]*(p[3]-p[1]-p[0])+[4]*p[1]+[2]*p[2]).conjugate() for p in P.integral_points()] - return CrystalOfTableaux(['A',7], shapes=shapes) + return CrystalOfTableaux(['A', 7], shapes=shapes) @lazy_attribute def _highest_weight_to_A7_elements(self): @@ -3583,18 +3593,18 @@ def _highest_weight_to_A7_elements(self): d = {} A7 = self.A7_decomposition() for b in self: - if not b.is_highest_weight([1,3,4,5,6,7]): + if not b.is_highest_weight([1, 3, 4, 5, 6, 7]): continue - wt = [b.phi(i) for i in [7,6,5,4,3,1]] + wt = [b.phi(i) for i in [7, 6, 5, 4, 3, 1]] la = Partition([6]*(wt[4]+wt[5])+[4]*(wt[2]+wt[3])+[2]*(wt[0]+wt[1])).conjugate() - #mu = Partition(sum(([6-i]*m for i,m in enumerate(wt)), [])).conjugate() + # mu = Partition(sum(([6-i]*m for i,m in enumerate(wt)), [])).conjugate() x = A7.module_generator(la) for i in range(wt[0]): - x = x.f_string([2,3,4,5,6,7]) + x = x.f_string([2, 3, 4, 5, 6, 7]) for i in range(wt[2]): - x = x.f_string([4,5,6,7]) + x = x.f_string([4, 5, 6, 7]) for i in range(wt[4]): - x = x.f_string([6,7]) + x = x.f_string([6, 7]) d[b] = x return d @@ -3615,8 +3625,10 @@ def to_A7_crystal(self): Defn: ... """ d = self._highest_weight_to_A7_elements - return self.crystal_morphism(d, automorphism={1:6,3:5,4:4,5:3,6:2,7:1}, - index_set=[1,3,4,5,6,7], check=False) + return self.crystal_morphism(d, automorphism={1: 6, 3: 5, 4: 4, + 5: 3, 6: 2, 7: 1}, + index_set=[1, 3, 4, 5, 6, 7], + check=False) @cached_method def from_A7_crystal(self): @@ -3637,8 +3649,10 @@ def from_A7_crystal(self): A7 = self.A7_decomposition() d = self._highest_weight_to_A7_elements d_inv = {d[b]: b for b in d} - return A7.crystal_morphism(d_inv, automorphism={6:1,5:3,4:4,3:5,2:6,1:7}, - index_set=[1,2,3,4,5,6], check=False) + return A7.crystal_morphism(d_inv, automorphism={6: 1, 5: 3, 4: 4, + 3: 5, 2: 6, 1: 7}, + index_set=[1, 2, 3, 4, 5, 6], + check=False) class Element(KirillovReshetikhinGenericCrystalElement): def e0(self): @@ -3793,12 +3807,11 @@ def _repr_diagram(self): sage: pm = PMDiagram([[0,2], [0,0], [0]]) sage: print(pm._repr_diagram()) """ - t = [] ish = self.inner_shape() + [0] * self.n msh = self.intermediate_shape() + [0] * self.n osh = self.outer_shape() + [0] * self.n - for i in range(self.n): - t.append(['.']*ish[i]+['+']*(msh[i]-ish[i])+['-']*(osh[i]-msh[i])) + t = (['.'] * ish[i] + ['+'] * (msh[i]-ish[i]) + ['-'] * (osh[i]-msh[i]) + for i in range(self.n)) t = [i for i in t if i] return Tableau(t)._repr_diagram() if t else '' @@ -3822,7 +3835,7 @@ def pp(self): def inner_shape(self): """ - Return the inner shape of the pm diagram + Return the inner shape of the pm diagram. EXAMPLES:: @@ -3837,15 +3850,13 @@ def inner_shape(self): sage: pm.inner_shape() [10, 7, 5, 3, 1] """ - t = [] ll = self._list - for i in range(self.n): - t.append(sum(ll[0:2*i+1])) + t = [sum(ll[0:2*i+1]) for i in range(self.n)] return Partition(list(reversed(t))) def outer_shape(self): r""" - Return the outer shape of the `\pm` diagram + Return the outer shape of the `\pm` diagram. EXAMPLES:: @@ -3871,7 +3882,8 @@ def outer_shape(self): def intermediate_shape(self): """ - Return the intermediate shape of the pm diagram (inner shape plus positions of plusses) + Return the intermediate shape of the pm diagram (inner shape plus + positions of plusses). EXAMPLES:: @@ -3893,9 +3905,9 @@ def intermediate_shape(self): [1] """ p = self.inner_shape() - p = p + [0 for i in range(self.n)] + p = p + [0 for _ in range(self.n)] ll = list(reversed(self._list)) - p = [ p[i]+ll[2*i+1] for i in range(self.n) ] + p = [p[i] + ll[2*i+1] for i in range(self.n)] return Partition(p) def heights_of_minus(self): @@ -3933,7 +3945,7 @@ def heights_of_addable_plus(self): [1, 2, 3, 4] """ heights = [] - for i in range(1,self.n+1): + for i in range(1, self.n+1): heights += [i]*self.sigma().pm_diagram[i][0] return heights @@ -3953,11 +3965,11 @@ def sigma(self): return PMDiagram([list(reversed(a)) for a in pm]) -##################################################################################### +####################################################################### def partitions_in_box(r, s): """ - Returns all partitions in a box of width s and height r. + Return all partitions in a box of width s and height r. EXAMPLES:: @@ -3965,12 +3977,13 @@ def partitions_in_box(r, s): [[], [1], [2], [1, 1], [2, 1], [1, 1, 1], [2, 2], [2, 1, 1], [2, 2, 1], [2, 2, 2]] """ - return [x for n in range(r*s+1) for x in Partitions(n,max_part=s,max_length=r)] + return [x for n in range(r*s+1) + for x in Partitions(n, max_part=s, max_length=r)] def vertical_dominoes_removed(r, s): """ - Returns all partitions obtained from a rectangle of width s and height r by removing + Return all partitions obtained from a rectangle of width s and height r by removing vertical dominoes. EXAMPLES:: @@ -3982,12 +3995,12 @@ def vertical_dominoes_removed(r, s): sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(4,2) [[], [1, 1], [1, 1, 1, 1], [2, 2], [2, 2, 1, 1], [2, 2, 2, 2]] """ - return [x.conjugate() for x in horizontal_dominoes_removed(s,r)] + return [x.conjugate() for x in horizontal_dominoes_removed(s, r)] def horizontal_dominoes_removed(r, s): """ - Returns all partitions obtained from a rectangle of width s and height r by removing + Return all partitions obtained from a rectangle of width s and height r by removing horizontal dominoes. EXAMPLES:: @@ -3998,11 +4011,11 @@ def horizontal_dominoes_removed(r, s): [[], [2], [2, 2], [2, 2, 2]] """ ulist = [list(x) + [0]*(r-x.length()) for x in partitions_in_box(r, s//2)] - two = lambda x : 2 * (x - s // 2) + s + two = lambda x: 2 * (x - s // 2) + s return [Partition([two(y) for y in x]) for x in ulist] ##################################################################### -## Morphisms +# Morphisms class AmbientRetractMap(Map): @@ -4030,7 +4043,7 @@ def __init__(self, base, ambient, pdict_inv, index_set, Map.__init__(self, Hom(ambient, base, SetsWithPartialMaps())) if similarity_factor_domain is None: - similarity_factor_domain = {i:1 for i in index_set} + similarity_factor_domain = {i: 1 for i in index_set} if automorphism is None: automorphism = lambda i: i @@ -4071,7 +4084,7 @@ def _call_(self, x): if c is not None: d = self(c).f(automorphism(i)) assert d is not None - #now we know that x is hw + # now we know that x is hw return d return self._pdict_inv[x] @@ -4091,7 +4104,7 @@ class CrystalDiagramAutomorphism(CrystalMorphism): weight elements - ``index_set`` -- (default: the empty set) the index set - ``automorphism`` -- (default: the identity) the twisting automorphism - - ``cache`` -- (default: ``True``) cache the result + - ``cache`` -- boolean (default: ``True``); cache the result """ def __init__(self, C, on_hw, index_set=None, automorphism=None, cache=True): @@ -4150,7 +4163,7 @@ def _call_(self, x): cur = n break - if n is None: # We're at a I-highest weight element + if n is None: # We're at a I-highest weight element break if cur in self._cache: diff --git a/src/sage/combinat/crystals/letters.pyx b/src/sage/combinat/crystals/letters.pyx index f54a4705047..93434bc1bd7 100644 --- a/src/sage/combinat/crystals/letters.pyx +++ b/src/sage/combinat/crystals/letters.pyx @@ -1360,7 +1360,7 @@ cdef class LetterTuple(Element): cpdef _richcmp_(left, right, int op): """ - Check comparison between ``left`` and ``right`` based on ``op`` + Check comparison between ``left`` and ``right`` based on ``op``. EXAMPLES:: @@ -2825,7 +2825,7 @@ cdef class LetterWrapped(Element): cpdef _richcmp_(left, right, int op): """ - Check comparison between ``left`` and ``right`` based on ``op`` + Check comparison between ``left`` and ``right`` based on ``op``. EXAMPLES:: diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 2bc8396f7a4..c9fa7cb7933 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -760,7 +760,7 @@ def one_dimensional_configuration_sum(self, q=None, group_components=True): - ``q`` -- (default: ``None``) a variable or ``None``; if ``None``, a variable ``q`` is set in the code - - ``group_components`` -- (default: ``True``) boolean; if ``True``, + - ``group_components`` -- boolean (default: ``True``); if ``True``, then the terms are grouped by classical component The one-dimensional configuration sum is the sum of the weights @@ -997,7 +997,7 @@ def weyl_group_representation(self): """ cartan = self.parent().weight.parent().cartan_type().classical() I = cartan.index_set() - W = WeylGroup(cartan, prefix='s', implementation="permutation") + W = WeylGroup(cartan, prefix='s', implementation='permutation') return [W.from_reduced_word(x.to_dominant_chamber(index_set=I, reduced_word=True)[1]) for x in self.value] @cached_in_parent_method @@ -1151,7 +1151,7 @@ def energy_function(self): ct = P.cartan_type() cartan = ct.classical() Qv = RootSystem(cartan).coroot_lattice() - W = WeylGroup(cartan, prefix='s', implementation="permutation") + W = WeylGroup(cartan, prefix='s', implementation='permutation') J = tuple(weight.weyl_stabilizer()) L = self.weyl_group_representation() if ct.is_untwisted_affine() or ct.type() == 'BC': @@ -1160,7 +1160,7 @@ def energy_function(self): else: untwisted = False cartan_dual = cartan.dual() - Wd = WeylGroup(cartan_dual, prefix='s', implementation="permutation") + Wd = WeylGroup(cartan_dual, prefix='s', implementation='permutation') G = Wd.quantum_bruhat_graph(J) Qd = RootSystem(cartan_dual).root_lattice() @@ -1305,7 +1305,7 @@ def e(self, i, power=1, length_only=False): - ``i`` -- element of the index set - ``power`` -- (default: 1) positive integer; specifies the power of the lowering operator to be applied - - ``length_only`` -- (default: ``False``) boolean; if ``True``, + - ``length_only`` -- boolean (default: ``False``); if ``True``, then return the distance to the anti-dominant end of the `i`-string of ``self`` @@ -1382,7 +1382,7 @@ def f(self, i, power=1, length_only=False): - ``i`` -- element of the index set - ``power`` -- (default: 1) positive integer; specifies the power of the lowering operator to be applied - - ``length_only`` -- (default: ``False``) boolean; if ``True``, + - ``length_only`` -- boolean (default: ``False``); if ``True``, then return the distance to the anti-dominant end of the `i`-string of ``self`` diff --git a/src/sage/combinat/crystals/meson.build b/src/sage/combinat/crystals/meson.build new file mode 100644 index 00000000000..96ff9f4e19e --- /dev/null +++ b/src/sage/combinat/crystals/meson.build @@ -0,0 +1,58 @@ +py.install_sources( + 'affine.py', + 'affine_factorization.py', + 'affinization.py', + 'alcove_path.py', + 'all.py', + 'bkk_crystals.py', + 'catalog.py', + 'catalog_elementary_crystals.py', + 'catalog_infinity_crystals.py', + 'catalog_kirillov_reshetikhin.py', + 'crystals.py', + 'direct_sum.py', + 'elementary_crystals.py', + 'fast_crystals.py', + 'fully_commutative_stable_grothendieck.py', + 'generalized_young_walls.py', + 'highest_weight_crystals.py', + 'induced_structure.py', + 'infinity_crystals.py', + 'kac_modules.py', + 'kirillov_reshetikhin.py', + 'kyoto_path_model.py', + 'letters.pxd', + 'littelmann_path.py', + 'monomial_crystals.py', + 'multisegments.py', + 'mv_polytopes.py', + 'pbw_crystal.py', + 'pbw_datum.pxd', + 'polyhedral_realization.py', + 'spins.pxd', + 'star_crystal.py', + 'subcrystal.py', + 'tensor_product.py', + 'tensor_product_element.pxd', + 'virtual_crystal.py', + subdir: 'sage/combinat/crystals', +) + +extension_data = { + 'letters' : files('letters.pyx'), + 'pbw_datum' : files('pbw_datum.pyx'), + 'spins' : files('spins.pyx'), + 'tensor_product_element' : files('tensor_product_element.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/crystals', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/combinat/crystals/monomial_crystals.py b/src/sage/combinat/crystals/monomial_crystals.py index 48804bd9c15..567f3c4aa3d 100644 --- a/src/sage/combinat/crystals/monomial_crystals.py +++ b/src/sage/combinat/crystals/monomial_crystals.py @@ -135,7 +135,7 @@ def __init__(self, parent, Y, A): r""" INPUT: - - ``d`` -- a dictionary of with pairs of the form ``{(i,k): y}`` + - ``d`` -- dictionary of with pairs of the form ``{(i,k): y}`` EXAMPLES:: @@ -700,7 +700,7 @@ class InfinityCrystalOfNakajimaMonomials(UniqueRepresentation, Parent): where `\{h_i : i \in I\}` and `\{\Lambda_i : i \in I \}` are the simple coroots and fundamental weights, respectively. With a chosen set of - non-negative integers `C = (c_{ij})_{i\neq j}` such that + nonnegative integers `C = (c_{ij})_{i\neq j}` such that `c_{ij} + c_{ji} = 1`, one defines .. MATH:: @@ -792,12 +792,12 @@ def _normalize_c(c, n): sage: C = InfinityCrystalOfNakajimaMonomials._normalize_c(c, 2) Traceback (most recent call last): ... - ValueError: the c matrix must have 0's on the diagonal + ValueError: the c matrix must have 0s on the diagonal sage: c = matrix([[0,2],[-1,0]]) sage: C = InfinityCrystalOfNakajimaMonomials._normalize_c(c, 2) Traceback (most recent call last): ... - ValueError: the c matrix must have non-negative entries + ValueError: the c matrix must have nonnegative entries sage: c = matrix([[0,1],[1,0]]) sage: C = InfinityCrystalOfNakajimaMonomials._normalize_c(c, 2) Traceback (most recent call last): @@ -811,11 +811,11 @@ def _normalize_c(c, n): c = MS(c) c.set_immutable() if any(c[i,i] != 0 for i in range(n)): - raise ValueError("the c matrix must have 0's on the diagonal") + raise ValueError("the c matrix must have 0s on the diagonal") if any(c[i,j] + c[j,i] != 1 for i in range(n) for j in range(i)): raise ValueError("transpose entries do not sum to 1") if any(c[i,j] < 0 or c[j,i] < 0 for i in range(n) for j in range(i)): - raise ValueError("the c matrix must have non-negative entries") + raise ValueError("the c matrix must have nonnegative entries") return c @staticmethod @@ -864,9 +864,9 @@ def _element_constructor_(self, Y=None, A=None): INPUT: - - ``Y`` -- a dictionary whose key is a pair and whose value + - ``Y`` -- dictionary whose key is a pair and whose value is an integer - - ``A`` -- a dictionary whose key is a pair and whose value + - ``A`` -- dictionary whose key is a pair and whose value is an integer EXAMPLES:: diff --git a/src/sage/combinat/crystals/pbw_datum.pyx b/src/sage/combinat/crystals/pbw_datum.pyx index 2adcb09d902..03a7aee51d9 100644 --- a/src/sage/combinat/crystals/pbw_datum.pyx +++ b/src/sage/combinat/crystals/pbw_datum.pyx @@ -44,7 +44,7 @@ class PBWDatum(): sage: from sage.combinat.crystals.pbw_datum import PBWData, PBWDatum sage: P = PBWData("A2") sage: L = PBWDatum(P, (1,2,1), (1,4,7)) - sage: TestSuite(L).run(skip="_test_pickling") + sage: TestSuite(L).run(skip='_test_pickling') """ self.parent = parent self.long_word = tuple(long_word) @@ -195,7 +195,7 @@ class PBWData(): # UniqueRepresentation? sage: from sage.combinat.crystals.pbw_datum import PBWData sage: P = PBWData(["A",2]) - sage: TestSuite(P).run(skip="_test_pickling") + sage: TestSuite(P).run(skip='_test_pickling') """ self.cartan_type = CartanType(cartan_type) self.root_system = RootSystem(self.cartan_type) @@ -243,7 +243,7 @@ class PBWData(): # UniqueRepresentation? INPUT: - - ``reduced_word`` -- a tuple corresponding to a reduced word + - ``reduced_word`` -- tuple corresponding to a reduced word EXAMPLES:: @@ -422,10 +422,10 @@ cpdef list enhance_braid_move_chain(braid_move_chain, cartan_type): ``(interval_of_change, cartan_sub_matrix)`` where - ``interval_of_change`` is the (half-open) interval of indices where - the braid move occurs; this is `None` for the first tuple + the braid move occurs; this is ``None`` for the first tuple - ``cartan_sub_matrix`` is the off-diagonal entries of the `2 \times 2` submatrix of the Cartan matrix corresponding to the braid move; - this is `None` for the first tuple + this is ``None`` for the first tuple For a matrix:: diff --git a/src/sage/combinat/crystals/spins.pyx b/src/sage/combinat/crystals/spins.pyx index 869447915c4..5ff109602d0 100644 --- a/src/sage/combinat/crystals/spins.pyx +++ b/src/sage/combinat/crystals/spins.pyx @@ -73,7 +73,7 @@ def CrystalOfSpins(ct): INPUT: - - ``['B', n]`` -- A Cartan type `B_n`. + - ``['B', n]`` -- a Cartan type `B_n` EXAMPLES:: @@ -113,7 +113,7 @@ def CrystalOfSpinsPlus(ct): INPUT: - - ``['D', n]`` -- A Cartan type `D_n`. + - ``['D', n]`` -- a Cartan type `D_n` EXAMPLES:: @@ -146,7 +146,7 @@ def CrystalOfSpinsMinus(ct): INPUT: - - ``['D', n]`` -- A Cartan type `D_n`. + - ``['D', n]`` -- a Cartan type `D_n` EXAMPLES:: @@ -494,7 +494,7 @@ cdef class Spin(Element): def _latex_(self): r""" - Gives the latex output of a spin column. + Give the latex output of a spin column. EXAMPLES:: diff --git a/src/sage/combinat/crystals/tensor_product.py b/src/sage/combinat/crystals/tensor_product.py index e0482ec74eb..8d35ecd8c90 100644 --- a/src/sage/combinat/crystals/tensor_product.py +++ b/src/sage/combinat/crystals/tensor_product.py @@ -196,7 +196,7 @@ class TensorProductOfCrystals(CrystalOfWords): .. RUBRIC:: Regular crystals Now if all crystals `B_k` are regular crystals, all `\varepsilon_i` and - `\varphi_i` are non-negative and we can + `\varphi_i` are nonnegative and we can define tensor product by the *signature rule*. We start by writing a word in `+` and `-` as follows: @@ -408,7 +408,7 @@ def __classcall_private__(cls, *crystals, **options): # add options to class class options(GlobalOptions): r""" - Sets the global options for tensor products of crystals. The default is to + Set the global options for tensor products of crystals. The default is to use the anti-Kashiwara convention. There are two conventions for how `e_i` and `f_i` act on tensor products, @@ -447,11 +447,11 @@ class options(GlobalOptions): """ NAME = 'TensorProductOfCrystals' module = 'sage.combinat.crystals' - convention = dict(default="antiKashiwara", + convention = dict(default='antiKashiwara', description='Sets the convention used for displaying/inputting tensor product of crystals', values=dict(antiKashiwara='use the anti-Kashiwara convention', Kashiwara='use the Kashiwara convention'), - alias=dict(anti="antiKashiwara", opposite="antiKashiwara"), + alias=dict(anti='antiKashiwara', opposite='antiKashiwara'), case_sensitive=False) def _element_constructor_(self, *crystalElements): @@ -705,13 +705,13 @@ class Element(TensorProductOfQueerSuperCrystalsElement): class CrystalOfTableaux(CrystalOfWords): r""" - A class for crystals of tableaux with integer valued shapes + A class for crystals of tableaux with integer valued shapes. INPUT: - ``cartan_type`` -- a Cartan type - ``shape`` -- a partition of length at most ``cartan_type.rank()`` - - ``shapes`` -- a list of such partitions + - ``shapes`` -- list of such partitions This constructs a classical crystal with the given Cartan type and highest weight(s) corresponding to the given shape(s). @@ -886,13 +886,12 @@ class CrystalOfTableaux(CrystalOfWords): Traceback (most recent call last): ... ValueError: entries of each shape must be weakly decreasing - """ @staticmethod def __classcall_private__(cls, cartan_type, shapes=None, shape=None): """ - Normalizes the input arguments to ensure unique representation, + Normalize the input arguments to ensure unique representation, and to delegate the construction of spin tableaux. EXAMPLES:: @@ -909,7 +908,6 @@ def __classcall_private__(cls, cartan_type, shapes=None, shape=None): sage: T2 = crystals.Tableaux(['A', [1,1]], [3,1,1,1]) sage: T1 is T2 True - """ cartan_type = CartanType(cartan_type) if cartan_type.letter == 'A' and isinstance(cartan_type, SuperCartanType_standard): @@ -979,8 +977,8 @@ def __init__(self, cartan_type, shapes): INPUT: - ``cartan_type`` -- (data coercible into) a Cartan type - - ``shapes`` -- a list (or iterable) of shapes - - ``shape`` -- a shape + - ``shapes`` -- list (or iterable) of shapes + - ``shape`` -- a shape Shapes themselves are lists (or iterable) of integers. @@ -999,7 +997,7 @@ def __init__(self, cartan_type, shapes): def cartan_type(self): """ - Returns the Cartan type of the associated crystal + Return the Cartan type of the associated crystal. EXAMPLES:: @@ -1071,7 +1069,7 @@ class CrystalOfQueerTableaux(CrystalOfWords, QueerSuperCrystalsMixin): INPUT: - ``cartan_type`` -- a Cartan type - - ``shape`` -- a shape + - ``shape`` -- a shape """ def __init__(self, cartan_type, shape): diff --git a/src/sage/combinat/crystals/tensor_product_element.pyx b/src/sage/combinat/crystals/tensor_product_element.pyx index 42a7f271092..607dcc2a8dc 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pyx +++ b/src/sage/combinat/crystals/tensor_product_element.pyx @@ -42,7 +42,7 @@ from sage.rings.integer_ring import ZZ cdef class ImmutableListWithParent(ClonableArray): r""" - A class for lists having a parent + A class for lists having a parent. Specification: any subclass ``C`` should implement ``__init__`` which accepts the following form ``C(parent, list=list)`` @@ -76,7 +76,7 @@ cdef class ImmutableListWithParent(ClonableArray): cpdef _set_index(self, k, value): r""" Return a sibling of ``self`` obtained by setting the - `k^{th}` entry of self to value. + `k`-th entry of ``self`` to value. EXAMPLES:: @@ -948,7 +948,6 @@ cdef class CrystalOfTableauxElement(TensorProductOfRegularCrystalsElement): [2, 1] sage: x.shape() [2, 1] - """ return self.to_tableau().shape() diff --git a/src/sage/combinat/crystals/virtual_crystal.py b/src/sage/combinat/crystals/virtual_crystal.py index e7286e58c01..5373e277bbd 100644 --- a/src/sage/combinat/crystals/virtual_crystal.py +++ b/src/sage/combinat/crystals/virtual_crystal.py @@ -64,9 +64,9 @@ class VirtualCrystal(Subcrystal): INPUT: - ``ambient`` -- the ambient crystal - - ``virtualization`` -- a dictionary whose key `i` corresponds + - ``virtualization`` -- dictionary whose key `i` corresponds to the set `\sigma_i` - - ``scaling_factors`` -- a dictionary whose key `i` corresponds to + - ``scaling_factors`` -- dictionary whose key `i` corresponds to the scaling factor `\gamma_i` - ``contained`` -- (optional) a set (or function) which specifies when an element is contained in the subcrystal; the default is everything diff --git a/src/sage/combinat/cyclic_sieving_phenomenon.py b/src/sage/combinat/cyclic_sieving_phenomenon.py index 8ad3bfc1f0c..ce6d6e58454 100644 --- a/src/sage/combinat/cyclic_sieving_phenomenon.py +++ b/src/sage/combinat/cyclic_sieving_phenomenon.py @@ -42,14 +42,14 @@ def CyclicSievingPolynomial(L, cyc_act=None, order=None, get_order=False): - ``L`` -- if ``cyc_act`` is ``None``: list of orbit sizes, otherwise list of objects - - ``cyc_act`` -- (default:``None``) bijective function from ``L`` to ``L`` + - ``cyc_act`` -- (default: ``None``) bijective function from ``L`` to ``L`` - - ``order`` -- (default:``None``) if set to an integer, this + - ``order`` -- (default: ``None``) if set to an integer, this cyclic order of ``cyc_act`` is used (must be an integer multiple of the order of ``cyc_act``) otherwise, the order of ``cyc_action`` is used - - ``get_order`` -- (default:``False``) if ``True``, a tuple ``[p,n]`` + - ``get_order`` -- (default: ``False``) if ``True``, a tuple ``[p,n]`` is returned where ``p`` is as above, and ``n`` is the order EXAMPLES:: @@ -132,9 +132,9 @@ def CyclicSievingCheck(L, cyc_act, f, order=None) -> bool: - ``L`` -- if ``cyc_act`` is ``None``: list of orbit sizes, otherwise list of objects - - ``cyc_act`` -- (default:``None``) bijective function from ``L`` to ``L`` + - ``cyc_act`` -- (default: ``None``) bijective function from ``L`` to ``L`` - - ``order`` -- (default:``None``) if set to an integer, this + - ``order`` -- (default: ``None``) if set to an integer, this cyclic order of ``cyc_act`` is used (must be an integer multiple of the order of ``cyc_act``) otherwise, the order of ``cyc_action`` is used @@ -173,9 +173,7 @@ def orbit_decomposition(L, cyc_act) -> list[list]: - ``cyc_act`` -- bijective function from ``L`` to ``L`` - OUTPUT: - - - a list of lists, the orbits under the cyc_act acting on ``L`` + OUTPUT: list of lists, the orbits under the cyc_act acting on ``L`` EXAMPLES:: diff --git a/src/sage/combinat/debruijn_sequence.pyx b/src/sage/combinat/debruijn_sequence.pyx index 01dbf826c90..54a58dc734b 100644 --- a/src/sage/combinat/debruijn_sequence.pyx +++ b/src/sage/combinat/debruijn_sequence.pyx @@ -74,9 +74,9 @@ def debruijn_sequence(int k, int n): INPUT: - - ``k`` -- Arity. Must be an integer. + - ``k`` -- arity; must be an integer - - ``n`` -- Substring length. Must be an integer. + - ``n`` -- substring length; must be an integer EXAMPLES:: @@ -113,14 +113,14 @@ cdef gen(int t, int p, k, n): def is_debruijn_sequence(seq, k, n): r""" - Given a sequence of integer elements in `0..k-1`, tests whether it + Given a sequence of integer elements in `0, \ldots, k-1`, tests whether it corresponds to a De Bruijn sequence of parameters `k` and `n`. INPUT: - - ``seq`` -- Sequence of elements in `0..k-1`. + - ``seq`` -- sequence of elements in `0, \ldots, k-1` - - ``n``, ``k`` -- Integers. + - ``n``, ``k`` -- integers EXAMPLES:: @@ -193,8 +193,8 @@ from sage.rings.integer_ring import ZZ class DeBruijnSequences(UniqueRepresentation, Parent): - """ - Represents the De Bruijn sequences of given parameters `k` and `n`. + r""" + Represent the De Bruijn sequences of given parameters `k` and `n`. A De Bruijn sequence of parameters `k` and `n` is defined as the shortest cyclic sequence that incorporates all substrings of length `n` a `k`-ary @@ -206,10 +206,10 @@ class DeBruijnSequences(UniqueRepresentation, Parent): INPUT: - - ``k`` -- A natural number to define arity. The letters used are the - integers `0..k-1`. + - ``k`` -- a natural number to define arity; the letters used are the + integers `0, \ldots, k-1` - - ``n`` -- A natural number that defines the length of the substring. + - ``n`` -- a natural number that defines the length of the substring EXAMPLES: @@ -263,7 +263,7 @@ class DeBruijnSequences(UniqueRepresentation, Parent): TESTS: Setting ``n`` or ``k`` to anything under 1 will return - a :class:`ValueError`:: + a :exc:`ValueError`:: sage: DeBruijnSequences(3, 0).an_element() Traceback (most recent call last): @@ -271,7 +271,7 @@ class DeBruijnSequences(UniqueRepresentation, Parent): ValueError: k and n cannot be under 1 Setting ``n`` or ``k`` to any type except an integer will return a - :class:`TypeError`:: + :exc:`TypeError`:: sage: DeBruijnSequences(2.5, 3).an_element() Traceback (most recent call last): @@ -302,7 +302,7 @@ class DeBruijnSequences(UniqueRepresentation, Parent): def an_element(self): """ - Returns the lexicographically smallest De Bruijn sequence with the given + Return the lexicographically smallest De Bruijn sequence with the given parameters. ALGORITHM: @@ -320,12 +320,12 @@ class DeBruijnSequences(UniqueRepresentation, Parent): def __contains__(self, seq): r""" - Tests whether the given sequence is a De Bruijn sequence with + Test whether the given sequence is a De Bruijn sequence with the current object's parameters. INPUT: - - ``seq`` -- A sequence of integers. + - ``seq`` -- a sequence of integers EXAMPLES:: @@ -337,7 +337,7 @@ class DeBruijnSequences(UniqueRepresentation, Parent): def cardinality(self): """ - Returns the number of distinct De Bruijn sequences for the object's + Return the number of distinct De Bruijn sequences for the object's parameters. EXAMPLES:: diff --git a/src/sage/combinat/decorated_permutation.py b/src/sage/combinat/decorated_permutation.py index 817be65223d..01b3b112caa 100644 --- a/src/sage/combinat/decorated_permutation.py +++ b/src/sage/combinat/decorated_permutation.py @@ -71,7 +71,6 @@ def __classcall_private__(cls, pi): sage: hash(elt1) # random 915443076393556996 - """ pi = list(pi) return DecoratedPermutations(len(pi))(pi) @@ -137,7 +136,7 @@ class DecoratedPermutations(UniqueRepresentation, Parent): INPUT: - - `n` -- an integer, the size of the decorated permutations. + - ``n`` -- integer; the size of the decorated permutations EXAMPLES: @@ -148,7 +147,6 @@ class DecoratedPermutations(UniqueRepresentation, Parent): Decorated permutations of size 3 sage: S.cardinality() 16 - """ def __init__(self, n): @@ -230,7 +228,6 @@ def _an_element_(self): sage: S = DecoratedPermutations(3) sage: S._an_element_() [1, 2, 3] - """ return self.element_class(self, list(range(1, self._n + 1))) diff --git a/src/sage/combinat/degree_sequences.pyx b/src/sage/combinat/degree_sequences.pyx index 6a0b070a44e..4e0d282d068 100644 --- a/src/sage/combinat/degree_sequences.pyx +++ b/src/sage/combinat/degree_sequences.pyx @@ -286,7 +286,7 @@ class DegreeSequences: def __init__(self, n): r""" - Degree Sequences + Degree Sequences. An instance of this class represents the degree sequences of graphs on a given number `n` of vertices. It can be used to list and count them, as @@ -383,7 +383,7 @@ class DegreeSequences: def __repr__(self): """ - Representing the element + Representing the element. TESTS:: @@ -416,7 +416,7 @@ class DegreeSequences: cdef init(int n): """ - Initializes the memory and starts the enumeration algorithm. + Initialize the memory and starts the enumeration algorithm. """ global seq global N diff --git a/src/sage/combinat/derangements.py b/src/sage/combinat/derangements.py index 6b2d868b90d..53398e6b727 100644 --- a/src/sage/combinat/derangements.py +++ b/src/sage/combinat/derangements.py @@ -89,7 +89,7 @@ class Derangements(UniqueRepresentation, Parent): INPUT: - - ``x`` -- Can be an integer which corresponds to derangements of + - ``x`` -- can be an integer which corresponds to derangements of `\{1, 2, 3, \ldots, x\}`, a list, or a string REFERENCES: diff --git a/src/sage/combinat/descent_algebra.py b/src/sage/combinat/descent_algebra.py index 8ab3886012f..617e0d615a2 100644 --- a/src/sage/combinat/descent_algebra.py +++ b/src/sage/combinat/descent_algebra.py @@ -66,7 +66,7 @@ class DescentAlgebra(UniqueRepresentation, Parent): - ``R`` -- the base ring - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer REFERENCES: @@ -219,7 +219,7 @@ class D(CombinatorialFreeModule, BindableClass): [D{}] """ - def __init__(self, alg, prefix="D"): + def __init__(self, alg, prefix='D'): r""" Initialize ``self``. @@ -232,7 +232,7 @@ def __init__(self, alg, prefix="D"): CombinatorialFreeModule.__init__(self, alg.base_ring(), SubsetsSorted(range(1, alg._n)), category=DescentAlgebraBases(alg), - bracket="", prefix=prefix) + bracket='', prefix=prefix) # Change of basis: B = alg.B() @@ -422,7 +422,7 @@ class B(CombinatorialFreeModule, BindableClass): The basis element `B_p` is denoted `\Xi^p` in [Sch2004]_. By using compositions of `n`, the product `B_p B_q` becomes a - sum over the non-negative-integer matrices `M` with row sum `p` + sum over the nonnegative-integer matrices `M` with row sum `p` and column sum `q`. The summand corresponding to `M` is `B_c`, where `c` is the composition obtained by reading `M` row-by-row from left-to-right and top-to-bottom and removing all zeroes. @@ -438,7 +438,7 @@ class B(CombinatorialFreeModule, BindableClass): B[2, 1, 1], B[2, 2], B[3, 1], B[4]] """ - def __init__(self, alg, prefix="B"): + def __init__(self, alg, prefix='B'): r""" Initialize ``self``. @@ -451,7 +451,7 @@ def __init__(self, alg, prefix="B"): CombinatorialFreeModule.__init__(self, alg.base_ring(), Compositions(alg._n), category=DescentAlgebraBases(alg), - bracket="", prefix=prefix) + bracket='', prefix=prefix) S = NonCommutativeSymmetricFunctions(alg.base_ring()).Complete() self.module_morphism(self.to_nsym, @@ -671,7 +671,7 @@ class I(CombinatorialFreeModule, BindableClass): [I[1, 1, 1, 1], I[1, 1, 2], I[1, 2, 1], I[1, 3], I[2, 1, 1], I[2, 2], I[3, 1], I[4]] """ - def __init__(self, alg, prefix="I"): + def __init__(self, alg, prefix='I'): r""" Initialize ``self``. @@ -684,7 +684,7 @@ def __init__(self, alg, prefix="I"): CombinatorialFreeModule.__init__(self, alg.base_ring(), Compositions(alg._n), category=DescentAlgebraBases(alg), - bracket="", prefix=prefix) + bracket='', prefix=prefix) # Change of basis: B = alg.B() @@ -743,7 +743,7 @@ def one(self): def one_basis(self): """ The element `1` is not (generally) a basis vector in the `I` - basis, thus this raises a :class:`TypeError`. + basis, thus this raises a :exc:`TypeError`. EXAMPLES:: diff --git a/src/sage/combinat/designs/MOLS_handbook_data.py b/src/sage/combinat/designs/MOLS_handbook_data.py index cc555400101..7c56f13f5d2 100644 --- a/src/sage/combinat/designs/MOLS_handbook_data.py +++ b/src/sage/combinat/designs/MOLS_handbook_data.py @@ -565,6 +565,5 @@ def lower_bound(order: int) -> int: sage: from sage.combinat.designs import MOLS_handbook_data sage: MOLS_handbook_data.lower_bound(0) 0 - """ return _LOWER_BOUNDS[order] diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 48e24b4ac75..49c930ccb38 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -71,16 +71,16 @@ def biplane(n, existence=False): INPUT: - - ``n`` -- (integer) order of the biplane + - ``n`` -- integer; order of the biplane - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - - ``True`` -- meaning that Sage knows how to build the design + - ``True`` -- meaning that Sage knows how to build the design - - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + - ``Unknown`` -- meaning that Sage does not know how to build the + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist .. SEEALSO:: @@ -127,16 +127,16 @@ def balanced_incomplete_block_design(v, k, lambd=1, existence=False, use_LJCR=Fa - ``v``, ``k``, ``lambd`` -- integers - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist - - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering + - ``use_LJCR`` -- boolean; whether to query the La Jolla Covering Repository for the design when Sage does not know how to build it (see :func:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This requires internet. @@ -362,6 +362,7 @@ def balanced_incomplete_block_design(v, k, lambd=1, existence=False, use_LJCR=Fa else: raise NotImplementedError("I don't know how to build a ({},{},{})-BIBD!".format(v, k, lambd)) + def BruckRyserChowla_check(v, k, lambd): r""" Check whether the parameters passed satisfy the Bruck-Ryser-Chowla theorem. @@ -373,9 +374,7 @@ def BruckRyserChowla_check(v, k, lambd): - ``v``, ``k``, ``lambd`` -- integers; parameters to check - OUTPUT: - - - ``True`` -- the parameters satisfy the theorem + OUTPUT: ``True`` -- the parameters satisfy the theorem - ``False`` -- the theorem fails for the given parameters @@ -418,7 +417,6 @@ def BruckRyserChowla_check(v, k, lambd): sage: from sage.combinat.designs.bibd import BruckRyserChowla_check sage: BruckRyserChowla_check(13,25,50) # needs sage.schemes True - """ from sage.rings.rational_field import QQ @@ -436,9 +434,10 @@ def BruckRyserChowla_check(v, k, lambd): return flag + def steiner_triple_system(n): r""" - Return a Steiner Triple System + Return a Steiner Triple System. A Steiner Triple System (STS) of a set `\{0,...,n-1\}` is a family `S` of 3-sets such that for any `i \not = j` @@ -455,7 +454,7 @@ def steiner_triple_system(n): INPUT: - - ``n`` return a Steiner Triple System of `\{0,...,n-1\}` + - ``n`` -- return a Steiner Triple System of `\{0,...,n-1\}` EXAMPLES: @@ -528,9 +527,9 @@ def BIBD_from_TD(v,k,existence=False): INPUT: - - ``v``, ``k`` -- (integers) computes a `(v,k,1)`-BIBD. + - ``v``, ``k`` -- integers; computes a `(v,k,1)`-BIBD - - ``existence`` -- (boolean) instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design @@ -683,12 +682,12 @@ def BIBD_from_difference_family(G, D, lambd=None, check=True): - ``G`` -- a finite additive Abelian group - - ``D`` -- a difference family on ``G`` (short blocks are allowed). + - ``D`` -- a difference family on ``G`` (short blocks are allowed) - ``lambd`` -- the `\lambda` parameter (optional, only used if ``check`` is ``True``) - - ``check`` -- whether or not we check the output (default: ``True``) + - ``check`` -- boolean (default: ``True``); whether or not we check the output EXAMPLES:: @@ -749,6 +748,7 @@ def BIBD_from_difference_family(G, D, lambd=None, check=True): # (v,4,1)-BIBD # ################ + def v_4_1_BIBD(v, check=True): r""" Return a `(v,4,1)`-BIBD. @@ -766,12 +766,11 @@ def v_4_1_BIBD(v, check=True): INPUT: - - ``v`` (integer) -- number of points. + - ``v`` -- integer; number of points - - ``check`` (boolean) -- whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -852,17 +851,16 @@ def BIBD_from_PBD(PBD, v, k, check=True, base_cases=None): INPUT: - - ``v``, ``k`` -- integers. + - ``v``, ``k`` -- integers - - ``PBD`` -- A PBD on `r=(v-1)/(k-1)` points, such that for any block of - ``PBD`` of size `s` there must exist a `((k-1)s+1,k,1)`-BIBD. + - ``PBD`` -- a PBD on `r=(v-1)/(k-1)` points, such that for any block of + ``PBD`` of size `s` there must exist a `((k-1)s+1,k,1)`-BIBD - - ``check`` (boolean) -- whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. - - ``base_cases`` -- caching system, for internal use. + - ``base_cases`` -- caching system, for internal use EXAMPLES:: @@ -895,19 +893,20 @@ def BIBD_from_PBD(PBD, v, k, check=True, base_cases=None): return bibd + def _relabel_bibd(B,n,p=None): r""" - Relabels the BIBD on `n` points and blocks of size k such that + Relabel the BIBD on `n` points and blocks of size k such that `\{0,...,k-2,n-1\},\{k-1,...,2k-3,n-1\},...,\{n-k,...,n-2,n-1\}` are blocks of the BIBD. INPUT: - - ``B`` -- a list of blocks. + - ``B`` -- list of blocks - - ``n`` (integer) -- number of points. + - ``n`` -- integer; number of points - - ``p`` (optional) -- the point that will be labeled with `n-1`. + - ``p`` -- (optional) the point that will be labeled with `n-1` EXAMPLES:: @@ -944,12 +943,11 @@ def PBD_4_5_8_9_12(v, check=True): INPUT: - - ``v`` -- an integer congruent to `0` or `1` modulo `4`. + - ``v`` -- integer congruent to `0` or `1` modulo `4` - - ``check`` (boolean) -- whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -1022,6 +1020,7 @@ def PBD_4_5_8_9_12(v, check=True): return PBD + def _PBD_4_5_8_9_12_closure(B): r""" Makes sure all blocks of `B` have size in `\{4,5,8,9,12\}`. @@ -1083,7 +1082,7 @@ def _get_t_u(v): INPUT: - - ``v`` (integer) + - ``v`` -- integer EXAMPLES:: @@ -1115,7 +1114,7 @@ def v_5_1_BIBD(v, check=True): INPUT: - - ``v`` (integer) + - ``v`` -- integer .. SEEALSO:: @@ -1181,15 +1180,16 @@ def v_5_1_BIBD(v, check=True): return bibd + def _get_r_s_t_u(v): r""" - Implements the table from [ClaytonSmith]_ + Implement the table from [ClaytonSmith]_. Return the parameters ``r,s,t,u`` associated with an integer ``v``. INPUT: - - ``v`` (integer) + - ``v`` -- integer EXAMPLES:: @@ -1233,7 +1233,7 @@ def PBD_from_TD(k,t,u): INPUT: - - ``k``, ``t``, ``u`` -- integers such that `0\leq u \leq t`. + - ``k``, ``t``, ``u`` -- integers such that `0\leq u \leq t` EXAMPLES:: @@ -1243,7 +1243,6 @@ def PBD_from_TD(k,t,u): [[0, 2, 4], [0, 3], [1, 2], [1, 3, 4], [0, 1], [2, 3]] sage: is_pairwise_balanced_design(PBD,2*2+1,[2,3]) True - """ from .orthogonal_arrays import transversal_design TD = transversal_design(k+bool(u),t, check=False) @@ -1254,6 +1253,7 @@ def PBD_from_TD(k,t,u): TD.append(list(range(k*t,k*t+u))) return TD + def BIBD_5q_5_for_q_prime_power(q): r""" Return a `(5q,5,1)`-BIBD with `q\equiv 1\pmod 4` a prime power. @@ -1262,7 +1262,7 @@ def BIBD_5q_5_for_q_prime_power(q): INPUT: - - ``q`` (integer) -- a prime power such that `q\equiv 1\pmod 4`. + - ``q`` -- integer; a prime power such that `q\equiv 1\pmod 4` EXAMPLES:: @@ -1308,9 +1308,9 @@ def BIBD_from_arc_in_desarguesian_projective_plane(n,k,existence=False): INPUT: - - ``n``, ``k`` (integers) -- must be powers of two (among other restrictions). + - ``n``, ``k`` -- integers; must be powers of two (among other restrictions) - - ``existence`` (boolean) -- whether to return the BIBD obtained through + - ``existence`` -- boolean; whether to return the BIBD obtained through this construction (default), or to merely indicate with a boolean return value whether this method *can* build the requested BIBD. @@ -1353,13 +1353,12 @@ def BIBD_from_arc_in_desarguesian_projective_plane(n,k,existence=False): Some maximal arcs in finite projective planes. Journal of Combinatorial Theory 6, no. 3 (1969): 317-319. :doi:`10.1016/S0021-9800(69)80095-5` - """ q = (n-1)//(k-1)-1 - if (k % 2 or - q % 2 or - q <= k or - n != (k-1)*(q+1)+1 or + if (k % 2 or + q % 2 or + q <= k or + n != (k-1)*(q+1)+1 or not is_prime_power(k) or not is_prime_power(q)): if existence: @@ -1392,19 +1391,18 @@ def BIBD_from_arc_in_desarguesian_projective_plane(n,k,existence=False): # [Denniston69] is the set of all elements of K of degree < log_n # (seeing elements of K as polynomials in 'a') - K_iter = list(K) # faster iterations - log_n = is_prime_power(n,get_data=True)[1] - C = [(x,y,one) - for x in K_iter - for y in K_iter - if Q(x,y).polynomial().degree() < log_n] + K_iter = list(K) # faster iterations + log_n = is_prime_power(n, get_data=True)[1] + C = [(x, y, one) for x in K_iter for y in K_iter + if Q(x, y).polynomial().degree() < log_n] from sage.combinat.designs.block_design import DesarguesianProjectivePlaneDesign return DesarguesianProjectivePlaneDesign(q).trace(C)._blocks + class PairwiseBalancedDesign(GroupDivisibleDesign): r""" - Pairwise Balanced Design (PBD) + Pairwise Balanced Design (PBD). A Pairwise Balanced Design, or `(v,K,\lambda)`-PBD, is a collection `\mathcal B` of blocks defined on a set `X` of size `v`, such that any block @@ -1414,34 +1412,32 @@ class PairwiseBalancedDesign(GroupDivisibleDesign): INPUT: - - ``points`` -- the underlying set. If ``points`` is an integer `v`, then - the set is considered to be `\{0, ..., v-1\}`. + - ``points`` -- the underlying set; if ``points`` is an integer `v`, then + the set is considered to be `\{0, ..., v-1\}` - ``blocks`` -- collection of blocks - ``K`` -- list of integers of which the sizes of the blocks must be - elements. Set to ``None`` (automatic guess) by default. + elements; set to ``None`` (automatic guess) by default - - ``lambd`` (integer) -- value of `\lambda`, set to `1` by default. + - ``lambd`` -- integer; value of `\lambda`, set to `1` by default - - ``check`` (boolean) -- whether to check that the design is a `PBD` with - the right parameters. + - ``check`` -- boolean; whether to check that the design is a `PBD` with + the right parameters - ``copy`` -- (use with caution) if set to ``False`` then ``blocks`` must be a list of lists of integers. The list will not be copied but will be modified in place (each block is sorted, and the whole list is sorted). Your ``blocks`` object will become the instance's internal data. - """ def __init__(self, points, blocks, K=None, lambd=1, check=True, copy=True,**kwds): r""" - Constructor + Constructor. EXAMPLES:: sage: designs.balanced_incomplete_block_design(13,3) # indirect doctest (13,3,1)-Balanced Incomplete Block Design - """ try: i = int(points) @@ -1462,7 +1458,7 @@ def __init__(self, points, blocks, K=None, lambd=1, check=True, copy=True,**kwds def __repr__(self): r""" - Return a string describing the PBD + Return a string describing the PBD. EXAMPLES:: @@ -1475,22 +1471,22 @@ def __repr__(self): class BalancedIncompleteBlockDesign(PairwiseBalancedDesign): r""" - Balanced Incomplete Block Design (BIBD) + Balanced Incomplete Block Design (BIBD). INPUT: - ``points`` -- the underlying set. If ``points`` is an integer `v`, then - the set is considered to be `\{0, ..., v-1\}`. + the set is considered to be `\{0, ..., v-1\}` - ``blocks`` -- collection of blocks - - ``k`` (integer) -- size of the blocks. Set to ``None`` (automatic guess) - by default. + - ``k`` -- integer; size of the blocks. Set to ``None`` (automatic guess) + by default - - ``lambd`` (integer) -- value of `\lambda`, set to `1` by default. + - ``lambd`` -- integer; value of `\lambda`, set to `1` by default - - ``check`` (boolean) -- whether to check that the design is a `PBD` with - the right parameters. + - ``check`` -- boolean; whether to check that the design is a `PBD` with + the right parameters - ``copy`` -- (use with caution) if set to ``False`` then ``blocks`` must be a list of lists of integers. The list will not be copied but will be @@ -1504,7 +1500,7 @@ class BalancedIncompleteBlockDesign(PairwiseBalancedDesign): """ def __init__(self, points, blocks, k=None, lambd=1, check=True, copy=True,**kwds): r""" - Constructor + Constructor. EXAMPLES:: @@ -1522,7 +1518,7 @@ def __init__(self, points, blocks, k=None, lambd=1, check=True, copy=True,**kwds def __repr__(self): r""" - A string to describe self + A string to describe ``self``. EXAMPLES:: @@ -1553,10 +1549,10 @@ def arc(self, s=2, solver=None, verbose=0, *, integrality_tolerance=1e-3): INPUT: - - ``s`` -- (default to ``2``) the maximum number of points from the arc + - ``s`` -- (default: `2`) the maximum number of points from the arc in each block - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1564,7 +1560,7 @@ def arc(self, s=2, solver=None, verbose=0, *, integrality_tolerance=1e-3): :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``). Sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- parameter for use with MILP solvers over diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 96a4fc6e17c..0c8b5b3fd38 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -42,7 +42,7 @@ --------------------- """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Peter Dobcsanyi # Copyright (C) 2007 David Joyner # @@ -51,7 +51,7 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.arith.misc import binomial, integer_floor, is_prime_power from sage.categories.sets_cat import EmptySetError from sage.misc.lazy_import import lazy_import @@ -69,7 +69,8 @@ BlockDesign = IncidenceStructure -### utility functions ------------------------------------------------------- +# utility functions ----------------------------------------------------- + def tdesign_params(t, v, k, L): """ @@ -91,6 +92,7 @@ def tdesign_params(t, v, k, L): r = integer_floor(L * x/y) return (t, v, b, r, k, L) + def are_hyperplanes_in_projective_geometry_parameters(v, k, lmbda, return_parameters=False): r""" Return ``True`` if the parameters ``(v,k,lmbda)`` are the one of hyperplanes in @@ -167,6 +169,7 @@ def are_hyperplanes_in_projective_geometry_parameters(v, k, lmbda, return_parame return (True, (q,d)) if return_parameters else True + def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, check=True): r""" Return a projective geometry design. @@ -196,9 +199,9 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch - ``n`` -- the projective dimension - - ``d`` -- the dimension of the subspaces which make up the blocks. + - ``d`` -- the dimension of the subspaces which make up the blocks - - ``F`` -- a finite field or a prime power. + - ``F`` -- a finite field or a prime power - ``algorithm`` -- set to ``None`` by default, which results in using Sage's own implementation. In order to use GAP's implementation instead (i.e. its @@ -210,7 +213,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch ``algorithm="gap"``. If ``True``, the ground set is indexed by coordinates in `\GF{q}^{n+1}`. Otherwise the ground set is indexed by integers. - - ``check`` -- (default: ``True``) whether to check the output. + - ``check`` -- boolean (default: ``True``); whether to check the output EXAMPLES: @@ -245,7 +248,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch Check that the constructor using gap also works:: - sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_package_design + sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm='gap') # optional - gap_package_design sage: BD.is_t_design(return_parameters=True) # optional - gap_package_design (True, (2, 7, 3, 1)) """ @@ -270,7 +273,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch m.set_immutable() b.append(points[m]) blocks.append(b) - B = BlockDesign(len(points), blocks, name="ProjectiveGeometryDesign", check=check) + B = BlockDesign(len(points), blocks, name='ProjectiveGeometryDesign', check=check) if point_coordinates: B.relabel({i:p[0] for p,i in points.items()}) @@ -282,7 +285,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch gB = [] for b in gblcks: gB.append([x - 1 for x in b]) - B = BlockDesign(v, gB, name="ProjectiveGeometryDesign", check=check) + B = BlockDesign(v, gB, name='ProjectiveGeometryDesign', check=check) if check: from sage.combinat.q_analogues import q_binomial @@ -305,15 +308,14 @@ def DesarguesianProjectivePlaneDesign(n, point_coordinates=True, check=True): INPUT: - - ``n`` -- an integer which must be a power of a prime number + - ``n`` -- integer which must be a power of a prime number - - ``point_coordinates`` -- (boolean) whether to label the points with their - homogeneous coordinates (default) or with integers. + - ``point_coordinates`` -- boolean (default: ``True``); whether to label the + points with their homogeneous coordinates (default) or with integers - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. .. SEEALSO:: @@ -333,19 +335,19 @@ def DesarguesianProjectivePlaneDesign(n, point_coordinates=True, check=True): Traceback (most recent call last): ... ValueError: the order of a finite field must be a prime power - """ K = FiniteField(n, 'a') n2 = n**2 - relabel = {x:i for i,x in enumerate(K)} - Kiter = relabel # it is much faster to iterate through a dict than through - # the finite field K + relabel = {x: i for i, x in enumerate(K)} + Kiter = relabel + # it is much faster to iterate through a dict than through + # the finite field K # we decompose the (equivalence class) of points [x:y:z] of the projective # plane into an affine plane, an affine line and a point. At the same time, # we relabel the points with the integers from 0 to n^2 + n as follows: # - the affine plane is the set of points [x:y:1] (i.e. the third coordinate - # is non-zero) and gets relabeled from 0 to n^2-1 + # is nonzero) and gets relabeled from 0 to n^2-1 affine_plane = lambda x,y: relabel[x] + n * relabel[y] # - the affine line is the set of points [x:1:0] (i.e. the third coordinate is @@ -394,6 +396,7 @@ def DesarguesianProjectivePlaneDesign(n, point_coordinates=True, check=True): return B + def q3_minus_one_matrix(K): r""" Return a companion matrix in `GL(3, K)` whose multiplicative order is `q^3 - 1`. @@ -440,6 +443,7 @@ def q3_minus_one_matrix(K): if m.multiplicative_order() == q**3 - 1: return m + def normalize_hughes_plane_point(p, q): r""" Return the normalized form of point ``p`` as a 3-tuple. @@ -483,6 +487,7 @@ def normalize_hughes_plane_point(p, q): else: return ((p[0] * k)**q,(p[1]*k)**q,(p[2]*k)**q) + def HughesPlane(q2, check=True): r""" Return the Hughes projective plane of order ``q2``. @@ -522,10 +527,9 @@ def HughesPlane(q2, check=True): - ``q2`` -- an even power of an odd prime number - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -623,6 +627,7 @@ def HughesPlane(q2, check=True): from .bibd import BalancedIncompleteBlockDesign return BalancedIncompleteBlockDesign(q2**2+q2+1, blcks, check=check) + def projective_plane_to_OA(pplane, pt=None, check=True): r""" Return the orthogonal array built from the projective plane ``pplane``. @@ -636,13 +641,12 @@ def projective_plane_to_OA(pplane, pt=None, check=True): - ``pplane`` -- a projective plane as a 2-design - - ``pt`` -- a point in the projective plane ``pplane``. If it is not provided, - then it is set to `n^2 + n`. + - ``pt`` -- a point in the projective plane ``pplane``; if it is not provided, + then it is set to `n^2 + n` - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -697,9 +701,9 @@ def projective_plane(n, check=True, existence=False): `n^2+n+1` points. For more information on finite projective planes, see the :wikipedia:`Projective_plane#Finite_projective_planes`. - If no construction is possible, then the function raises a :class:`EmptySetError`, + If no construction is possible, then the function raises a :exc:`EmptySetError`, whereas if no construction is available, the function raises a - :class:`NotImplementedError`. + :exc:`NotImplementedError`. INPUT: @@ -779,6 +783,7 @@ def projective_plane(n, check=True, existence=False): else: return DesarguesianProjectivePlaneDesign(n, point_coordinates=False, check=check) + def AffineGeometryDesign(n, d, F, point_coordinates=True, check=True): r""" Return an affine geometry design. @@ -803,18 +808,18 @@ def AffineGeometryDesign(n, d, F, point_coordinates=True, check=True): INPUT: - - ``n`` (integer) -- the Euclidean dimension. The number of points of the - design is `v=|\GF{q}^n|`. + - ``n`` -- integer; the Euclidean dimension. The number of points of the + design is `v=|\GF{q}^n|` - - ``d`` (integer) -- the dimension of the (affine) subspaces of `\GF{q}^n` - which make up the blocks. + - ``d`` -- integer; the dimension of the (affine) subspaces of `\GF{q}^n` + which make up the blocks - - ``F`` -- a finite field or a prime power. + - ``F`` -- a finite field or a prime power - - ``point_coordinates`` -- (default: ``True``) whether we use - coordinates in `\GF{q}^n` or plain integers for the points of the design. + - ``point_coordinates`` -- boolean (default: ``True``); whether we use + coordinates in `\GF{q}^n` or plain integers for the points of the design - - ``check`` -- (default: ``True``) whether to check the output. + - ``check`` -- boolean (default: ``True``); whether to check the output EXAMPLES:: @@ -875,7 +880,7 @@ def AffineGeometryDesign(n, d, F, point_coordinates=True, check=True): b.append(points[m]) blocks.append(b) - B = BlockDesign(len(points), blocks, name="AffineGeometryDesign", check=check) + B = BlockDesign(len(points), blocks, name='AffineGeometryDesign', check=check) if point_coordinates: rd = {i: p[0][1:] for p, i in points.items()} @@ -923,7 +928,7 @@ def WittDesign(n): """ INPUT: - - ``n`` is in `9,10,11,12,21,22,23,24`. + - ``n`` -- integer in `9,10,11,12,21,22,23,24` Wraps GAP Design's WittDesign. If ``n=24`` then this function returns the large Witt design `W_{24}`, the unique (up to isomorphism) `5-(24,8,1)` @@ -950,7 +955,7 @@ def WittDesign(n): B = libgap.WittDesign(n) v = B['v'].sage() gB = [[x - 1 for x in b] for b in B['blocks'].sage()] - return BlockDesign(v, gB, name="WittDesign", check=True) + return BlockDesign(v, gB, name='WittDesign', check=True) def HadamardDesign(n): @@ -992,14 +997,14 @@ def HadamardDesign(n): """ from sage.combinat.matrices.hadamard_matrix import hadamard_matrix from sage.matrix.constructor import matrix - H = hadamard_matrix(n+1) #assumed to be normalised. + H = hadamard_matrix(n + 1) # assumed to be normalised. H1 = H.matrix_from_columns(range(1,n+1)) H2 = H1.matrix_from_rows(range(1,n+1)) J = matrix(ZZ,n,n,[1]*n*n) MS = J.parent() - A = MS((H2+J)/2) # convert -1's to 0's; coerce entries to ZZ + A = MS((H2+J)/2) # convert -1's to 0's; coerce entries to ZZ # A is the incidence matrix of the block design - return IncidenceStructure(incidence_matrix=A,name="HadamardDesign") + return IncidenceStructure(incidence_matrix=A, name='HadamardDesign') def Hadamard3Design(n): @@ -1012,7 +1017,7 @@ def Hadamard3Design(n): INPUT: - - ``n`` (integer) -- a multiple of 4 such that `n>4`. + - ``n`` -- integer; a multiple of 4 such that `n>4` EXAMPLES:: @@ -1056,10 +1061,10 @@ def Hadamard3Design(n): raise ValueError("The Hadamard design with n = %s does not extend to a three design." % n) from sage.combinat.matrices.hadamard_matrix import hadamard_matrix from sage.matrix.constructor import matrix, block_matrix - H = hadamard_matrix(n) #assumed to be normalised. + H = hadamard_matrix(n) # assumed to be normalised. H1 = H.matrix_from_columns(range(1, n)) J = matrix(ZZ, n, n-1, [1]*(n-1)*n) - A1 = (H1+J)/2 - A2 = (J-H1)/2 - A = block_matrix(1, 2, [A1, A2]) #the incidence matrix of the design. - return IncidenceStructure(incidence_matrix=A, name="HadamardThreeDesign") + A1 = (H1 + J) / 2 + A2 = (J - H1) / 2 + A = block_matrix(1, 2, [A1, A2]) # the incidence matrix of the design. + return IncidenceStructure(incidence_matrix=A, name='HadamardThreeDesign') diff --git a/src/sage/combinat/designs/covering_array.py b/src/sage/combinat/designs/covering_array.py index e8df8e19314..9582a627d22 100644 --- a/src/sage/combinat/designs/covering_array.py +++ b/src/sage/combinat/designs/covering_array.py @@ -16,12 +16,17 @@ .. csv-table:: :class: contentstable - :widths: 30, 70 + :widths: 50, 50 :delim: | :meth:`~sage.combinat.designs.designs_pyx.is_covering_array` | Check that an input list of lists is a `CA(N;t,k,v)`. - :meth:`~sage.combinat.designs.covering_array.CA_relabel` | Return a relabelled version of the CA. - :meth:`~sage.combinat.designs.covering_array.CA_standard_label` | Return a version of the CA relabelled to symbols `(0,\dots,n-1)`. + :meth:`~sage.combinat.designs.covering_array.CA_relabel` | Return a relabelled version of the `CA`. + :meth:`~sage.combinat.designs.covering_array.CA_standard_label` | Return a version of the `CA` relabelled to symbols `(0,\dots,n-1)`. + :meth:`~sage.combinat.designs.covering_array.truncate_columns` | Return an array with `k` columns from a larger one. + :meth:`~sage.combinat.designs.covering_array.Kleitman_Spencer_Katona` | Return a `CA(N; 2, k, 2)` using N as input. + :meth:`~sage.combinat.designs.covering_array.column_Kleitman_Spencer_Katona` | Return a `CA(N; 2, k, 2)` using k as input. + :meth:`~sage.combinat.designs.covering_array.database_check` | Check if CA can be made from the database of combinatorial designs. + :meth:`~sage.combinat.designs.covering_array.covering_array` | Return a `CA` with given parameters. REFERENCES: @@ -49,3 +54,215 @@ from .orthogonal_arrays import OA_relabel, OA_standard_label CA_relabel = OA_relabel CA_standard_label = OA_standard_label + + +def truncate_columns(array, k): + r""" + Return a covering array with `k` columns, obtained by removing excess + columns from a larger covering array. + + INPUT: + + - ``array`` -- the array to be truncated. + + - ``k`` -- the number of columns desired. Must be less than the + number of columns in ``array``. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.covering_array import truncate_columns + sage: from sage.combinat.designs.database import ca_11_2_5_3 + sage: C = ca_11_2_5_3() + sage: D = truncate_columns(C,7) + Traceback (most recent call last): + ... + ValueError: array only has 5 columns + sage: E = truncate_columns(C,4) + sage: is_covering_array(E,parameters=True) + (True, (11, 2, 4, 3)) + + """ + oldk = len(array[0]) + + if oldk == k: + return array + + if oldk < k: + raise ValueError("array only has {} columns".format(oldk)) + + return [row[:k] for row in array] + + +def Kleitman_Spencer_Katona(N): + r""" + Return a `CA(N; 2, k, 2)` where `k = \binom {N-1}{\lceil N/2 \rceil}`. + + INPUT: + + - ``N`` -- the number of rows in the array, must be an integer greater + than 3 since any smaller would not produce enough columns for a + strength 2 array. + + This construction is referenced in [Colb2004]_ from [KS1973]_ and [Kat1973]_ + + **Construction** + + Take all distinct binary `N`-tuples of weight `N/2` that have a 0 + in the first position and place them as columns in an array. + + EXAMPLES:: + + sage: from sage.combinat.designs.covering_array import Kleitman_Spencer_Katona + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: C = Kleitman_Spencer_Katona(2) + Traceback (most recent call last): + ... + ValueError: N must be greater than 3 + sage: C = Kleitman_Spencer_Katona(5) + sage: is_covering_array(C,parameters=True) + (True, (5, 2, 4, 2)) + + """ + from itertools import combinations + from sage.arith.misc import integer_ceil + if N < 4: + raise ValueError("N must be greater than 3") + + col_list = [] + for p in combinations(range(N-1), integer_ceil(N/2)): + S = [0]*N + for i in p: + S[i] = 1 + col_list.append(S) + return [[col_list[j][i] for j in range(len(col_list))] for i in range(N)] + + +def column_Kleitman_Spencer_Katona(k): + r""" + Return a covering array with `k` columns using the Kleitman-Spencer-Katona + method. + + See :func:`~sage.combinat.designs.covering_array.Kleitman_Spencer_Katona` + + INPUT: + + - ``k`` -- the number of columns in the array, must be an integer + greater than 3 since any smaller is a trivial array for strength 2. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.covering_array import column_Kleitman_Spencer_Katona + sage: C = column_Kleitman_Spencer_Katona(20) + sage: is_covering_array(C,parameters=True) + (True, (8, 2, 20, 2)) + sage: column_Kleitman_Spencer_Katona(25000) + Traceback (most recent call last): + ... + NotImplementedError: not implemented for k > 24310 + + """ + kdict = [(3, 4), (4, 5), (10, 6), (15, 7), (35, 8), (56, 9), + (126, 10), (210, 11), (462, 12), (792, 13), (1716, 14), + (3003, 15), (6435, 16), (11440, 17), (24310, 18)] + + if k > kdict[-1][0]: + raise NotImplementedError("not implemented for k > {}".format(kdict[-1][0])) + + for (ki, N) in kdict: + if k <= ki: + return truncate_columns(Kleitman_Spencer_Katona(N), k) + + +def database_check(number_columns, strength, levels): + r""" + Check if the database can be used to build a CA with the given parameters. + If so return the CA, if not return False. + + INPUT: + + - ``strength`` (integer) -- the parameter `t` of the covering array, + such that in any selection of `t` columns of the array, every + `t`-tuple appears at least once. + + - ``levels`` (integer) -- the parameter `v` which is the number of + unique symbols that appear in the covering array. + + - ``number_columns`` (integer) -- the number of columns desired for + the covering array. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.covering_array import database_check + sage: C = database_check(6, 2, 3) + sage: is_covering_array(C, parameters=True) + (True, (12, 2, 6, 3)) + sage: database_check(6, 3, 3) + False + + """ + import sage.combinat.designs.database as DB + + if (strength, levels) in DB.CA_constructions: + for i in DB.CA_constructions[(strength, levels)]: + if number_columns <= i[1]: + CA = "ca_{}_{}_{}_{}".format(i[0], strength, i[1], levels) + f = getattr(DB, CA) + return truncate_columns(f(), number_columns) + return False + else: + return False + + +def covering_array(strength, number_columns, levels): + r""" + Build a `CA(N; t, k, v)` using direct constructions, where `N` is the + smallest size known. + + INPUT: + + - ``strength`` (integer) -- the parameter `t` of the covering array, + such that in any selection of `t` columns of the array, every + `t`-tuple appears at least once. + + - ``levels`` (integer) -- the parameter `v` which is the number of + unique symbols that appear in the covering array. + + - ``number_columns`` (integer) -- the number of columns desired for + the covering array. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.covering_array import covering_array + sage: C1 = covering_array(2, 7, 3) + sage: is_covering_array(C1,parameters=True) + (True, (12, 2, 7, 3)) + sage: C2 = covering_array(2, 11, 2) + sage: is_covering_array(C2,parameters=True) + (True, (7, 2, 11, 2)) + sage: C3 = covering_array(2, 8, 7) + sage: is_covering_array(C3,parameters=True) + (True, (49, 2, 8, 7)) + sage: C4 = covering_array(2, 50, 7) + No direct construction known and/or implemented for a CA(N; 2, 50, 7) + + """ + from sage.combinat.designs.orthogonal_arrays import orthogonal_array + + if levels == 2 and strength == 2: + return column_Kleitman_Spencer_Katona(number_columns) + + in_database = database_check(number_columns, strength, levels) + if in_database: + return in_database + + if orthogonal_array(number_columns, levels, strength, existence=True) is True: + return orthogonal_array(number_columns, levels, strength) + + else: + print("No direct construction known and/or implemented for a CA(N; {}, {}, {})".format( + strength, number_columns, levels)) + return diff --git a/src/sage/combinat/designs/covering_design.py b/src/sage/combinat/designs/covering_design.py index a855dc601dc..7977de93d9d 100644 --- a/src/sage/combinat/designs/covering_design.py +++ b/src/sage/combinat/designs/covering_design.py @@ -21,7 +21,7 @@ REFERENCES: .. [1] La Jolla Covering Repository, - https://ljcr.dmgordon.org/cover.html + https://dmgordon.org/cover .. [2] Daniel M. Gordon and Douglas R. Stinson, *Coverings*, Chapter 1 in: Charles J. Colbourn and Jeffrey H. Dinitz, @@ -63,11 +63,11 @@ def schonheim(v, k, t): INPUT: - - ``v`` -- integer, size of point set + - ``v`` -- integer; size of point set - - ``k`` -- integer, cardinality of each block + - ``k`` -- integer; cardinality of each block - - ``t`` -- integer, cardinality of sets being covered + - ``t`` -- integer; cardinality of sets being covered OUTPUT: @@ -95,11 +95,11 @@ def trivial_covering_design(v, k, t): INPUT: - - ``v`` -- integer, size of point set + - ``v`` -- integer; size of point set - - ``k`` -- integer, cardinality of each block + - ``k`` -- integer; cardinality of each block - - ``t`` -- integer, cardinality of sets being covered + - ``t`` -- integer; cardinality of sets being covered OUTPUT: @@ -141,7 +141,6 @@ def trivial_covering_design(v, k, t): `k` does not divide `v`. * anything else: Just use every `k`-subset of `[0, 1,..., v-1]`. - """ if t == 0: # single block [0, ..., k-1] blk = list(range(k)) @@ -171,13 +170,13 @@ class CoveringDesign(SageObject): - ``v``, ``k``, ``t`` -- integer parameters of the covering design - - ``size`` (integer) + - ``size`` -- integer - - ``points`` -- list of points (default points are `[0, ..., v-1]`) + - ``points`` -- list of points (default: `[0, ..., v-1]`) - ``blocks`` - - ``low_bd`` (integer) -- lower bound for such a design + - ``low_bd`` -- integer; lower bound for such a design - ``method``, ``creator``, ``timestamp`` -- database information """ @@ -335,7 +334,7 @@ def v(self): def k(self): """ - Return `k`, the size of blocks of the covering design + Return `k`, the size of blocks of the covering design. EXAMPLES:: @@ -366,7 +365,7 @@ def t(self): def size(self): """ - Return the number of blocks in the covering design + Return the number of blocks in the covering design. EXAMPLES:: @@ -418,7 +417,7 @@ def method(self): def creator(self): """ - Return the creator of the covering design + Return the creator of the covering design. This field is optional, and is used in a database to give attribution for the covering design It can refer to the person @@ -437,7 +436,7 @@ def creator(self): def timestamp(self): """ - Return the time that the covering was submitted to the database + Return the time that the covering was submitted to the database. EXAMPLES:: @@ -467,7 +466,6 @@ def incidence_structure(self): sage: D.blocks() [[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]] - """ return self.__incidence_structure @@ -481,13 +479,13 @@ def best_known_covering_design_www(v, k, t, verbose=False): INPUT: - - ``v`` -- integer, the size of the point set for the design + - ``v`` -- integer; the size of the point set for the design - - ``k`` -- integer, the number of points per block + - ``k`` -- integer; the number of points per block - - ``t`` -- integer, the size of sets covered by the blocks + - ``t`` -- integer; the size of sets covered by the blocks - - ``verbose`` -- bool (default: ``False``), print verbose message + - ``verbose`` -- boolean (default: ``False``); print verbose message OUTPUT: @@ -511,14 +509,14 @@ def best_known_covering_design_www(v, k, t, verbose=False): 2 3 6 2 4 5 - A :class:`ValueError` is raised if the ``(v, k, t)`` parameters are not + A :exc:`ValueError` is raised if the ``(v, k, t)`` parameters are not found in the database. """ v = int(v) k = int(k) t = int(t) param = "?v=%s&k=%s&t=%s" % (v, k, t) - url = "https://ljcr.dmgordon.org/cover/get_cover.php" + param + url = "https://ljcr.dmgordon.org/get_cover.php" + param if verbose: print("Looking up the bounds at %s" % url) diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 943f7c9ba22..19eb9d26165 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -12,6 +12,8 @@ This module implements: +- {LIST_OF_CA_CONSTRUCTIONS} + - {LIST_OF_OA_CONSTRUCTIONS} - {LIST_OF_MOLS_CONSTRUCTIONS} @@ -66,17 +68,18 @@ # Cyclic shift of a list cyclic_shift = lambda l,i : l[-i:]+l[:-i] + def _MOLS_from_string(s,k): r""" - Return MOLS from a string + Return MOLS from a string. INPUT: - - ``s`` (string) -- represents the MOLS with entries in a-z. To understand + - ``s`` -- string; represents the MOLS with entries in a-z; to understand how the string should be formatted, read the source code of a constructor - that uses it. + that uses it - - ``k`` (integer) -- the number of MOLS encoded by the string. + - ``k`` -- integer; the number of MOLS encoded by the string EXAMPLES:: @@ -89,9 +92,10 @@ def _MOLS_from_string(s,k): matrices[i % k].append(l) return [Matrix(_) for _ in matrices] + def MOLS_10_2(): r""" - Return a pair of MOLS of order 10 + Return a pair of MOLS of order 10. Data obtained from ``_ @@ -132,9 +136,10 @@ def MOLS_10_2(): [5,6,7,1,2,3,4,0,9,8], [7,1,2,3,4,5,6,9,8,0]])] + def MOLS_12_5(): r""" - Return 5 MOLS of order 12 + Return 5 MOLS of order 12. These MOLS have been found by Brendan McKay. @@ -163,9 +168,10 @@ def MOLS_12_5(): return _MOLS_from_string(M,5) + def MOLS_14_4(): r""" - Return four MOLS of order 14 + Return four MOLS of order 14. These MOLS were shared by Ian Wanless. The first proof of existence was given in [Todorov12]_. @@ -208,6 +214,7 @@ def MOLS_14_4(): return _MOLS_from_string(M,4) + def MOLS_15_4(): r""" Return 4 MOLS of order 15. @@ -247,6 +254,7 @@ def MOLS_15_4(): return _MOLS_from_string(M,4) + def MOLS_18_3(): r""" Return 3 MOLS of order 18. @@ -308,9 +316,10 @@ def MOLS_18_3(): LIST_OF_MOLS_CONSTRUCTIONS = ", ".join(":func:`{} MOLS of order {} `".format(k,n,n,k) for n,(k,_) in MOLS_constructions.items()) + def OA_7_18(): r""" - Return an OA(7,18) + Return an OA(7,18). Proved in [JulianAbel13]_. @@ -362,9 +371,10 @@ def OA_7_18(): M = [M[i] for i in range(len(M)) if i % 18 < 9] # only develop w.r.t the last two coordinates return M + def OA_9_40(): r""" - Return an OA(9,40) + Return an OA(9,40). As explained in the Handbook III.3.62 [DesignHandbook]_. Uses the fact that `40 = 2^3 \times 5` and that `5` is prime. @@ -402,9 +412,10 @@ def OA_9_40(): return OA_n_times_2_pow_c_from_matrix(9,3,FiniteField(5),A,Y,check=False) + def OA_7_66(): r""" - Return an OA(7,66) + Return an OA(7,66). Construction shared by Julian R. Abel. @@ -442,9 +453,10 @@ def OA_7_66(): PBD = [[rel[x] for x in B] for B in PBD] return OA_from_PBD(7,66,PBD,check=False) + def OA_7_68(): r""" - Return an OA(7,68) + Return an OA(7,68). Construction shared by Julian R. Abel. @@ -482,9 +494,10 @@ def OA_7_68(): PBD = [[rel[x] for x in B] for B in PBD] return OA_from_PBD(7,68,PBD,check=False) + def OA_8_69(): r""" - Return an OA(8,69) + Return an OA(8,69). Construction shared by Julian R. Abel. @@ -554,9 +567,10 @@ def OA_8_69(): OA = [[relabel[x] for x in B] for B in OA] return OA + def OA_7_74(): r""" - Return an OA(7,74) + Return an OA(7,74). Construction shared by Julian R. Abel. @@ -594,9 +608,10 @@ def OA_7_74(): PBD = [[rel[x] for x in B] for B in PBD] return OA_from_PBD(7,74,PBD,check=False) + def OA_8_76(): r""" - Return an OA(8,76) + Return an OA(8,76). Construction shared by Julian R. Abel. @@ -661,9 +676,10 @@ def OA_8_76(): OA = [[relabel[x] for x in B] for B in OA] return OA + def OA_11_80(): r""" - Return an OA(11,80) + Return an OA(11,80). As explained in the Handbook III.3.76 [DesignHandbook]_. Uses the fact that `80 = 2^4 \times 5` and that `5` is prime. @@ -703,9 +719,10 @@ def OA_11_80(): return OA_n_times_2_pow_c_from_matrix(11,4,FiniteField(5),A,Y,check=False) + def OA_15_112(): r""" - Returns an OA(15,112) + Return an OA(15,112). Published by Julian R. Abel in [Ab1995]_. Uses the fact that 112 = `2^4 \times 7` and that `7` is prime. @@ -749,9 +766,10 @@ def OA_15_112(): return OA_n_times_2_pow_c_from_matrix(15,4,FiniteField(7),list(zip(*A)),Y,check=False) + def OA_9_120(): r""" - Return an OA(9,120) + Return an OA(9,120). Construction shared by Julian R. Abel: @@ -795,9 +813,10 @@ def OA_9_120(): return OA + def OA_9_135(): r""" - Return an OA(9,135) + Return an OA(9,135). Construction shared by Julian R. Abel: @@ -880,9 +899,10 @@ def OA_9_135(): # And call Wilson's construction return wilson_construction(truncated_OA, 9, 16, 8, (1,)*7, check=False) + def OA_11_160(): r""" - Returns an OA(11,160) + Return an OA(11,160). Published by Julian R. Abel in [Ab1995]_. Uses the fact that `160 = 2^5 \times 5` is a product of a power of `2` and a prime number. @@ -923,9 +943,10 @@ def OA_11_160(): return OA_n_times_2_pow_c_from_matrix(11,5,FiniteField(5),list(zip(*A)),Y,check=False) + def OA_16_176(): r""" - Returns an OA(16,176) + Return an OA(16,176). Published by Julian R. Abel in [Ab1995]_. Uses the fact that `176 = 2^4 \times 11` is a product of a power of `2` and a prime number. @@ -977,9 +998,10 @@ def OA_16_176(): Y = [None, 0, 1, 2, 8, 6, 9, 4, 10, 3, 5, 11, 13, 14, 12] return OA_n_times_2_pow_c_from_matrix(16,4,FiniteField(11),list(zip(*A)),Y,check=False) + def OA_11_185(): r""" - Returns an OA(11,185) + Return an OA(11,185). The construction is given in [Greig99]_. In Julian R. Abel's words: @@ -1005,7 +1027,6 @@ def OA_11_185(): sage: designs.orthogonal_arrays.is_available(11,185) # needs sage.schemes True - """ from sage.combinat.designs.difference_family import difference_family @@ -1041,6 +1062,7 @@ def OA_11_185(): OA.extend([[special_set[x] for x in B] for B in orthogonal_array(11,17)]) return OA + def OA_10_205(): r""" Return an `OA(10,205)`. @@ -1087,7 +1109,7 @@ def OA_10_205(): baer_subplane_size = 4**2+4+1 B = [0, 1, 22, 33, 83, 122, 135, 141, 145, 159, 175, 200, 226, 229, 231, 238, 246] - pplane = [[(xx+i) % pplane_size for xx in B] for i in range(pplane_size)] + pplane = [[(xx+i) % pplane_size for xx in B] for i in range(pplane_size)] baer_subplane = set([i*pplane_size/baer_subplane_size for i in range(baer_subplane_size)]) p = list(baer_subplane)[0] @@ -1122,9 +1144,10 @@ def OA_10_205(): return OA + def OA_16_208(): r""" - Returns an OA(16,208) + Return an OA(16,208). Published by Julian R. Abel in [Ab1995]_. Uses the fact that `208 = 2^4 \times 13` is a product of `2` and a prime number. @@ -1181,9 +1204,10 @@ def OA_16_208(): return OA_n_times_2_pow_c_from_matrix(16,4,FiniteField(13),list(zip(*A)),Y,check=False) + def OA_15_224(): r""" - Returns an OA(15,224) + Return an OA(15,224). Published by Julian R. Abel in [Ab1995]_ (uses the fact that `224=2^5 \times 7` is a product of a power of `2` and a prime number). @@ -1228,9 +1252,10 @@ def OA_15_224(): return OA_n_times_2_pow_c_from_matrix(15,5,FiniteField(7),list(zip(*A)),Y,check=False) + def OA_11_254(): r""" - Return an OA(11,254) + Return an OA(11,254). This constructions appears in [Greig99]_. @@ -1259,7 +1284,7 @@ def OA_11_254(): # Base block of a PG(2,19) B = (0,1,19,28,96,118,151,153,176,202,240,254,290,296,300,307,337,361,366,369) - BIBD = [[(x+i) % 381 for x in B] for i in range(381)] + BIBD = [[(x+i) % 381 for x in B] for i in range(381)] # We only keep points congruent to 0,1 mod 3 and relabel the PBD. The result is # a (254,{11,13,16})-PBD @@ -1267,9 +1292,10 @@ def OA_11_254(): return OA_from_PBD(11,254,BIBD,check=False) + def OA_20_352(): r""" - Returns an OA(20,352) + Return an OA(20,352). Published by Julian R. Abel in [Ab1995]_ (uses the fact that `352=2^5 \times 11` is the product of a power of `2` and a prime number). @@ -1326,9 +1352,10 @@ def OA_20_352(): return OA_n_times_2_pow_c_from_matrix(20,5,FiniteField(11),list(zip(*A)),Y,check=False) + def OA_20_416(): r""" - Returns an OA(20,416) + Return an OA(20,416). Published by Julian R. Abel in [Ab1995]_ (uses the fact that `416=2^5 \times 13` is the product of a power of `2` and a prime number). @@ -1386,9 +1413,10 @@ def OA_20_416(): return OA_n_times_2_pow_c_from_matrix(20,5,FiniteField(13),list(zip(*A)),Y,check=False) + def OA_20_544(): r""" - Returns an OA(20,544) + Return an OA(20,544). Published by Julian R. Abel in [Ab1995]_ (uses the fact that `544=2^5 \times 17` is the product of a power of `2` and a prime number). @@ -1455,9 +1483,10 @@ def OA_20_544(): return OA_n_times_2_pow_c_from_matrix(20,5,FiniteField(17),list(zip(*A)),Y,check=False) + def OA_17_560(): r""" - Returns an OA(17,560) + Return an OA(17,560). This OA is built in Corollary 2.2 of [Thwarts]_. @@ -1514,9 +1543,10 @@ def OA_17_560(): return wilson_construction(OA,k,n,m,[p**beta]*3,check=False) + def OA_11_640(): r""" - Returns an OA(11,640) + Return an OA(11,640). Published by Julian R. Abel in [Ab1995]_ (uses the fact that `640=2^7 \times 5` is the product of a power of `2` and a prime number). @@ -1556,9 +1586,10 @@ def OA_11_640(): return OA_n_times_2_pow_c_from_matrix(11,7,FiniteField(5),list(zip(*A)),Y,check=False) + def OA_10_796(): r""" - Returns an OA(10,796) + Return an OA(10,796). Construction shared by Julian R. Abel, from [AC07]_: @@ -1627,9 +1658,10 @@ def OA_10_796(): return OA + def OA_10_469(): r""" - Return an OA(10,469) + Return an OA(10,469). This construction appears in [Brouwer80]_. It is based on the same technique used in @@ -1676,7 +1708,7 @@ def OA_10_469(): 731,824,837,848,932,1002,1051,1055,1089,1105,1145,1165,1196,1217,1226, 1274,1281,1309,1405) - BIBD = [[(x+i) % 1407 for x in B] for i in range(1407)] + BIBD = [[(x+i) % 1407 for x in B] for i in range(1407)] # Only keep points v congruent to 0 mod 3 and relabel PBD = [[x//3 for x in B if x % 3 == 0] for B in BIBD] @@ -1701,6 +1733,7 @@ def OA_10_469(): return OA + def OA_520_plus_x(x): r""" Return an `OA(10+x,520+x)`. @@ -1740,7 +1773,6 @@ def OA_520_plus_x(x): sage: OA = OA_520_plus_x(0) # not tested (already tested in OA_10_520) sage: is_orthogonal_array(OA,10,520,2) # not tested (already tested in OA_10_520) True - """ from .orthogonal_arrays import incomplete_orthogonal_array k = 9+x+1 @@ -1775,6 +1807,7 @@ def OA_520_plus_x(x): OA.append([relabel[new_point]]*k) return OA + def OA_10_520(): r""" Return an OA(10,520). @@ -1797,9 +1830,10 @@ def OA_10_520(): """ return OA_520_plus_x(0) + def OA_12_522(): r""" - Return an OA(12,522) + Return an OA(12,522). This design is built by the slightly more general construction :func:`OA_520_plus_x`. @@ -1819,9 +1853,10 @@ def OA_12_522(): """ return OA_520_plus_x(2) + def OA_14_524(): r""" - Return an OA(14,524) + Return an OA(14,524). This design is built by the slightly more general construction :func:`OA_520_plus_x`. @@ -1841,9 +1876,10 @@ def OA_14_524(): """ return OA_520_plus_x(4) + def OA_15_896(): r""" - Returns an OA(15,896) + Return an OA(15,896). Uses the fact that `896 = 2^7 \times 7` is the product of a power of `2` and a prime number. @@ -1888,9 +1924,10 @@ def OA_15_896(): return OA_n_times_2_pow_c_from_matrix(15,7,FiniteField(7),list(zip(*A)),Y,check=False) + def OA_9_1078(): r""" - Returns an OA(9,1078) + Return an OA(9,1078). This is obtained through the generalized Brouwer-van Rees construction. Indeed, `1078 = 89.11 + (99=9.11)` and there exists an @@ -1918,9 +1955,10 @@ def OA_9_1078(): """ return wilson_construction(None,9,11,89,[[(11,9)]]) + def OA_25_1262(): r""" - Returns an OA(25,1262) + Return an OA(25,1262). The construction is given in [Greig99]_. In Julian R. Abel's words: @@ -1955,9 +1993,10 @@ def OA_25_1262(): return OA_from_PBD(25,1262,PBD,check=False) + def OA_9_1612(): r""" - Returns an OA(9,1612) + Return an OA(9,1612). This is obtained through the generalized Brouwer-van Rees construction. Indeed, `1612 = 89.17 + (99=9.11)` and there exists an @@ -1985,9 +2024,10 @@ def OA_9_1612(): """ return wilson_construction(None,9,17,89,[[(11,9)]]) + def OA_10_1620(): r""" - Returns an OA(10,1620) + Return an OA(10,1620). This is obtained through the generalized Brouwer-van Rees construction. Indeed, `1620 = 144.11+(36=4.9)` and there exists an @@ -2061,6 +2101,7 @@ def OA_10_1620(): LIST_OF_OA_CONSTRUCTIONS = ", ".join(":func:`OA({},{}) `".format(k,n,k,n) for n,(k,_) in OA_constructions.items()) + def QDM_19_6_1_1_1(): r""" Return a `(19,6;1,1;1)`-quasi-difference matrix. @@ -2143,6 +2184,7 @@ def QDM_21_5_1_1_1(): return G, Mb + def QDM_21_6_1_1_5(): r""" Return a `(21,6;1,1;5)`-quasi-difference matrix. @@ -2183,6 +2225,7 @@ def QDM_21_6_1_1_5(): return G, Mb + def QDM_25_6_1_1_5(): r""" Return a `(25,6;1,1;5)`-quasi-difference matrix. @@ -2228,6 +2271,7 @@ def QDM_25_6_1_1_5(): return G, Mb + def QDM_33_6_1_1_1(): r""" Return a `(33,6;1,1;1)`-quasi-difference matrix. @@ -2271,6 +2315,7 @@ def QDM_33_6_1_1_1(): return G, Mb + def QDM_37_6_1_1_1(): r""" Return a `(37,6;1,1;1)`-quasi-difference matrix. @@ -2309,6 +2354,7 @@ def QDM_37_6_1_1_1(): return G, Mb + def QDM_35_7_1_1_7(): r""" Return a `(35,7;1,1;7)`-quasi-difference matrix. @@ -2346,6 +2392,7 @@ def QDM_35_7_1_1_7(): return G, Mb + def QDM_45_7_1_1_9(): r""" Return a `(45,7;1,1;9)`-quasi-difference matrix. @@ -2383,6 +2430,7 @@ def QDM_45_7_1_1_9(): return G, Mb + def QDM_54_7_1_1_8(): r""" Return a `(54,7;1,1;8)`-quasi-difference matrix. @@ -2420,6 +2468,7 @@ def QDM_54_7_1_1_8(): return G, Mb + def QDM_57_9_1_1_8(): r""" Return a `(57,9;1,1;8)`-quasi-difference matrix. @@ -2712,7 +2761,7 @@ def QDM_57_9_1_1_8(): for m in _all_m) r""" -Tests for the Vmt vectors +Test for the Vmt vectors EXAMPLES:: @@ -3094,15 +3143,58 @@ def QDM_57_9_1_1_8(): [0,2,13,18,28,30,44,48,50,51,57,61], [0,4,21,26,29,33,35,36,47,55,56,60]]}, -# a 133-cyclic set from Ken Smith database -# see https://math.ccrwest.org/diffsets/diff_sets/DS_133_33_8_133.html +# a (133,33,8)-cyclic difference set +# see https://dmgordon.org/diffset (133,33, 8): - {(133,): [[0,4,7,8,15,17,19,22,24,25,29,30,38, - 47,49,50,55,58,61,62,71,73,76,77,78, - 82,95,111,113,114,121,123,127]]}, - -# a 901-cyclic -# see https://math.ccrwest.org/diffsets/diff_sets/DS_901_225_56_901.html + {(133,): [[1,5,14,22,25,27,29,32,34,38, + 46,64,65,66,76,78,81,82,84,89, + 92,93,99,103,104,106,107,112,113,122, + 126,128,129]]}, + +# a (144,66,30) non-cyclic difference set in AbelianGroup([2,8,3,3]) +# given in unpublished paper by Kroeger, Miller, Mooney, Shepard and Smith +# see https://dmgordon.org/diffset +(144,66,30): + {(2,8,3,3): [[(0,1,0,0),(0,7,0,2),(0,5,0,1),(0,3,0,0),(0,6,0,1), + (0,1,0,2),(0,4,0,0),(0,2,0,2),(0,6,0,0),(0,1,0,1), + (0,4,0,2),(0,2,0,1),(1,2,2,0),(1,3,2,0),(1,4,2,0), + (1,5,2,0),(1,6,2,0),(1,7,2,0),(0,6,1,2),(0,1,1,0), + (0,4,1,1),(0,3,1,0),(0,1,1,2),(0,4,1,0),(0,7,1,1), + (0,2,1,2),(0,6,1,0),(0,1,1,1),(0,2,1,1),(0,5,1,2), + (1,0,0,0),(1,6,0,2),(1,1,0,0),(1,4,0,1),(1,7,0,2), + (1,2,0,0),(1,5,0,1),(1,0,0,2),(1,3,0,0),(1,1,0,2), + (1,0,0,1),(1,1,0,1),(0,0,2,0),(0,6,2,2),(0,4,2,1), + (0,0,2,2),(0,3,2,0),(0,6,2,1),(0,2,2,2),(0,5,2,0), + (0,0,2,1),(0,4,2,2),(0,7,2,0),(0,2,2,1),(1,0,1,0), + (1,1,1,0),(1,2,1,0),(1,0,1,2),(1,3,1,0),(1,6,1,1), + (1,1,1,2),(1,7,1,1),(1,0,1,1),(1,1,1,1),(1,4,1,2), + (1,5,1,2)]]}, + +# a (320,88,24) non-cyclic difference set in AbelianGroup([4,4,4,5]), +# given in Arasu and Chen, Designs, Codes and Cryptography 2001 +# see https://dmgordon.org/diffset +(320,88,24): + {(4,4,4,5): [[(3,3,3,0),(2,3,2,0),(3,1,3,0),(2,2,3,0),(1,3,3,0), + (3,2,1,0),(2,2,2,0),(2,2,1,0),(2,1,2,0),(0,3,2,0), + (2,0,3,0),(1,1,3,0),(0,2,3,0),(3,0,1,0),(1,2,1,0), + (2,0,2,0),(0,2,2,0),(2,0,1,0),(0,2,1,0),(0,1,2,0), + (0,0,3,0),(1,0,1,0),(0,0,2,0),(0,0,1,0),(3,3,3,1), + (3,3,1,1),(3,0,3,1),(0,3,3,1),(3,0,1,1),(0,3,1,1), + (1,1,2,1),(1,0,2,1),(0,1,2,1),(0,0,3,1),(1,1,0,1), + (0,0,2,1),(1,0,0,1),(0,1,0,1),(0,0,1,1),(0,0,0,1), + (1,1,3,2),(3,1,1,2),(2,3,3,2),(2,2,3,2),(0,3,2,2), + (0,3,1,2),(0,2,1,2),(3,2,2,2),(3,1,2,2),(3,0,3,2), + (2,3,0,2),(2,0,2,2),(1,2,0,2),(1,1,0,2),(1,0,1,2), + (0,0,0,2),(1,1,1,3),(1,3,3,3),(3,2,1,3),(2,2,3,3), + (3,0,0,3),(3,0,3,3),(1,3,0,3),(2,0,1,3),(3,2,2,3), + (2,3,2,3),(0,3,3,3),(1,1,2,3),(0,2,2,3),(2,1,0,3), + (0,1,1,3),(0,0,0,3),(2,0,3,4),(1,1,2,4),(0,2,1,4), + (0,1,3,4),(3,2,3,4),(3,2,2,4),(2,3,2,4),(3,1,3,4), + (3,3,0,4),(2,3,1,4),(1,0,1,4),(2,2,2,4),(1,3,1,4), + (1,0,0,4),(0,1,0,4),(0,0,0,4)]]}, + +# a (901,225,56)-cyclic difference set +# see https://dmgordon.org/diffset (901,225,56): {(901,): [[ 0, 1, 5, 9, 12, 13, 14, 16, 22, 25, 41, 43, 45, 47, 53, 59, 60, 65, 69, 70, 71, 79, 80, 81, @@ -3174,6 +3266,7 @@ def DM_12_6_1(): return G,M + def DM_21_6_1(): r""" Return a `(21,6,1)`-difference matrix. @@ -3209,6 +3302,7 @@ def DM_21_6_1(): return AdditiveCyclic(21), Mb + def DM_24_8_1(): r""" Return a `(24,8,1)`-difference matrix. @@ -3256,6 +3350,7 @@ def DM_24_8_1(): return G, Mb + def DM_28_6_1(): r""" Return a `(28,6,1)`-difference matrix. @@ -3299,6 +3394,7 @@ def DM_28_6_1(): return G, Mb + def DM_33_6_1(): r""" Return a `(33,6,1)`-difference matrix. @@ -3341,6 +3437,7 @@ def DM_33_6_1(): return G, Mb + def DM_35_6_1(): r""" Return a `(35,6,1)`-difference matrix. @@ -3373,6 +3470,7 @@ def DM_35_6_1(): return G, list(zip(*M)) + def DM_36_9_1(): r""" Return a `(36,9,1)`-difference matrix. @@ -3426,6 +3524,7 @@ def DM_36_9_1(): return G, Mb + def DM_39_6_1(): r""" Return a `(39,6,1)`-difference matrix. @@ -3470,6 +3569,7 @@ def DM_39_6_1(): return G,Mb + def DM_44_6_1(): r""" Return a `(44,6,1)`-difference matrix. @@ -3529,6 +3629,7 @@ def DM_44_6_1(): return G2211, Mb + def DM_45_7_1(): r""" Return a `(45,7,1)`-difference matrix. @@ -3585,6 +3686,7 @@ def DM_45_7_1(): return G533, Mb + def DM_48_9_1(): r""" Return a `(48,9,1)`-difference matrix. @@ -3634,6 +3736,7 @@ def DM_48_9_1(): return F3F16, Mb + def DM_51_6_1(): r""" Return a `(51,6,1)`-difference matrix. @@ -3748,6 +3851,7 @@ def t2(i,R): return G, Mb + def DM_55_7_1(): r""" Return a `(55,7,1)`-difference matrix. @@ -3787,6 +3891,7 @@ def DM_55_7_1(): return G, Mb + def DM_56_8_1(): r""" Return a `(56,8,1)`-difference matrix. @@ -3834,6 +3939,7 @@ def DM_56_8_1(): return G, Mb + def DM_57_8_1(): r""" Return a `(57,8,1)`-difference matrix. @@ -3862,6 +3968,7 @@ def DM_57_8_1(): G = AdditiveCyclic(57) return G, M + def DM_60_6_1(): r""" Return a `(60,6,1)`-difference matrix. @@ -3877,7 +3984,6 @@ def DM_60_6_1(): http://onlinelibrary.wiley.com/doi/10.1002/jcd.21384/abstract - EXAMPLES:: sage: from sage.combinat.designs.designs_pyx import is_difference_matrix @@ -3914,6 +4020,7 @@ def DM_60_6_1(): return G, M60b + def DM_75_8_1(): r""" Return a `(75,8,1)`-difference matrix. @@ -3962,6 +4069,7 @@ def DM_75_8_1(): return G, Mb + def DM_273_17_1(): r""" Return a `(273,17,1)`-difference matrix. @@ -3990,6 +4098,7 @@ def DM_273_17_1(): G = AdditiveCyclic(273) return G, M + def DM_993_32_1(): r""" Return a `(993,32,1)`-difference matrix. @@ -4053,7 +4162,7 @@ def DM_993_32_1(): def RBIBD_120_8_1(): r""" - Return a resolvable `BIBD(120,8,1)` + Return a resolvable `BIBD(120,8,1)`. This function output a list ``L`` of `17\times 15` blocks such that ``L[i*15:(i+1)*15]`` is a partition of `120`. @@ -4105,7 +4214,7 @@ def RBIBD_120_8_1(): # A (precomputed) set that every block of the BIBD intersects on 0 or 2 points hyperoval = [128, 192, 194, 4, 262, 140, 175, 48, 81, 180, 245, 271, 119, 212, 249, 189, 62, 255] - #for B in BIBD: + # for B in BIBD: # len_trace = sum(x in hyperoval for x in B) # assert len_trace == 0 or len_trace == 2 @@ -4132,6 +4241,7 @@ def RBIBD_120_8_1(): equiv = [[M.nonzero_positions_in_row(x) for x in S] for S in equiv] return [B for S in equiv for B in S] + def BIBD_45_9_8(from_code=False): r""" Return a `(45,9,1)`-BIBD. @@ -4143,8 +4253,8 @@ def BIBD_45_9_8(from_code=False): INPUT: - - ``from_code`` (boolean) -- whether to build the design from hardcoded data - (default) or from the code object (much longer). + - ``from_code`` -- boolean; whether to build the design from hardcoded data + (default) or from the code object (much longer) EXAMPLES:: @@ -4216,7 +4326,7 @@ def BIBD_66_6_1(): Return a (66,6,1)-BIBD. This BIBD was obtained from La Jolla covering repository - (https://math.ccrwest.org/cover.html) where it is attributed to Colin Barker. + (https://dmgordon.org/cover) where it is attributed to Colin Barker. EXAMPLES:: @@ -4240,7 +4350,7 @@ def BIBD_76_6_1(): Return a (76,6,1)-BIBD. This BIBD was obtained from La Jolla covering repository - (https://math.ccrwest.org/cover.html) where it is attributed to Colin Barker. + (https://dmgordon.org/cover) where it is attributed to Colin Barker. EXAMPLES:: @@ -4264,7 +4374,7 @@ def BIBD_96_6_1(): Return a (96,6,1)-BIBD. This BIBD was obtained from La Jolla covering repository - (https://math.ccrwest.org/cover.html) where it is attributed to Colin Barker. + (https://dmgordon.org/cover) where it is attributed to Colin Barker. EXAMPLES:: @@ -4305,6 +4415,7 @@ def BIBD_106_6_1(): return [[((x+i) % 53+y*53) for x,y in B] for i in range(53) for B in bibd] + def BIBD_111_6_1(): r""" Return a (111,6,1)-BIBD. @@ -4363,6 +4474,7 @@ def BIBD_126_6_1(): return [[x+y*5+z*25 for x,y,z in B] for B in bibd] + def BIBD_136_6_1(): r""" Return a (136,6,1)-BIBD. @@ -4508,13 +4620,9 @@ def HigmanSimsDesign(): from sage.combinat.designs.block_design import WittDesign from .incidence_structures import IncidenceStructure W = WittDesign(24) - a,b = 0,1 - Wa = [set(B) for B in W - if (a in B and - b not in B)] - Wb = [set(B) for B in W - if (b in B and - a not in B)] + a, b = 0, 1 + Wa = [set(B) for B in W if a in B and b not in B] + Wb = [set(B) for B in W if b in B and a not in B] H = [[i for i, A in enumerate(Wa) if len(A & B) != 2] for B in Wb] @@ -4670,6 +4778,7 @@ def BIBD_79_13_2(): libgap.unset_global("p4Act") return [[int(t)-1 for t in y] for y in blocks] + def BIBD_56_11_2(): r""" Return a symmetric `(56,11,2)`-BIBD. @@ -5033,6 +5142,462 @@ def BIBD_56_11_2(): k, ', '.join('`{}`'.format(q) for q in sorted(EDS[k]) if EDS[k][q] is not False)) for k in sorted(EDS)) + +def ca_11_2_5_3(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_11_2_5_3 + sage: C = ca_11_2_5_3() + sage: is_covering_array(C,2,3) + True + + """ + return [[0, 0, 1, 0, 1], + [0, 0, 2, 1, 0], + [0, 1, 0, 1, 2], + [0, 2, 1, 2, 2], + [1, 0, 0, 2, 1], + [1, 1, 1, 2, 0], + [1, 1, 2, 0, 2], + [1, 2, 2, 1, 1], + [2, 0, 2, 2, 2], + [2, 1, 1, 1, 1], + [2, 2, 0, 0, 0]] + + +def ca_12_2_7_3(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_12_2_7_3 + sage: C = ca_12_2_7_3() + sage: is_covering_array(C,2,3) + True + + """ + return [[0, 0, 0, 2, 2, 0, 0], + [0, 0, 2, 1, 1, 1, 1], + [0, 1, 0, 0, 0, 1, 2], + [0, 2, 1, 2, 0, 2, 1], + [1, 0, 2, 0, 0, 2, 0], + [1, 1, 1, 1, 2, 0, 1], + [1, 1, 1, 2, 1, 1, 0], + [1, 2, 0, 1, 1, 2, 2], + [2, 0, 1, 0, 1, 0, 2], + [2, 1, 2, 2, 2, 2, 2], + [2, 2, 0, 0, 2, 1, 1], + [2, 2, 2, 1, 0, 0, 0]] + + +def ca_13_2_9_3(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_13_2_9_3 + sage: C = ca_13_2_9_3() + sage: is_covering_array(C,2,3) + True + + """ + return [[0, 0, 0, 2, 0, 2, 2, 2, 0], + [0, 0, 2, 0, 1, 1, 1, 2, 1], + [0, 1, 1, 1, 2, 0, 1, 2, 0], + [0, 1, 2, 1, 0, 1, 2, 0, 2], + [0, 2, 2, 2, 2, 1, 0, 1, 0], + [1, 0, 1, 0, 2, 1, 2, 0, 0], + [1, 0, 2, 1, 2, 2, 0, 2, 2], + [1, 1, 0, 0, 0, 0, 0, 1, 1], + [1, 2, 0, 2, 1, 0, 1, 0, 2], + [2, 0, 2, 1, 1, 0, 2, 1, 0], + [2, 1, 1, 2, 1, 2, 0, 0, 1], + [2, 2, 0, 1, 2, 1, 2, 2, 1], + [2, 2, 1, 0, 0, 2, 1, 1, 2]] + + +def ca_14_2_10_3(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_14_2_10_3 + sage: C = ca_14_2_10_3() + sage: is_covering_array(C,2,3) + True + + """ + return [[0, 0, 0, 0, 2, 2, 2, 1, 1, 0], + [0, 0, 0, 2, 1, 0, 0, 2, 1, 1], + [0, 0, 1, 1, 1, 2, 1, 0, 2, 2], + [0, 1, 0, 2, 0, 1, 2, 0, 1, 2], + [0, 2, 2, 2, 1, 2, 2, 1, 0, 0], + [1, 0, 2, 1, 0, 1, 1, 1, 1, 1], + [1, 1, 1, 2, 1, 1, 1, 2, 2, 0], + [1, 1, 2, 0, 0, 2, 2, 2, 2, 1], + [1, 1, 2, 1, 0, 0, 0, 0, 0, 0], + [1, 2, 0, 1, 2, 0, 1, 2, 2, 2], + [2, 0, 0, 0, 1, 0, 1, 2, 0, 2], + [2, 1, 2, 2, 2, 2, 0, 1, 2, 2], + [2, 2, 1, 0, 2, 1, 0, 0, 0, 1], + [2, 2, 1, 1, 0, 0, 2, 1, 1, 0]] + + +def ca_15_2_20_3(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from [Nur2004]_ + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_15_2_20_3 + sage: C = ca_15_2_20_3() + sage: is_covering_array(C,2,3) + True + + """ + return [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + [0, 1, 1, 1, 1, 0, 1, 2, 2, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2], + [0, 2, 2, 2, 2, 2, 2, 0, 1, 0, 0, 0, 0, 1, 2, 2, 0, 1, 1, 1], + [1, 0, 1, 1, 1, 2, 2, 0, 1, 0, 1, 1, 2, 0, 0, 1, 1, 0, 1, 2], + [1, 1, 2, 2, 2, 1, 0, 1, 0, 2, 1, 1, 0, 0, 2, 1, 2, 2, 1, 0], + [1, 2, 0, 1, 2, 0, 2, 1, 0, 2, 0, 2, 2, 1, 0, 2, 1, 0, 2, 1], + [1, 2, 1, 0, 2, 2, 1, 2, 0, 1, 2, 1, 1, 0, 1, 2, 0, 2, 0, 1], + [1, 2, 1, 2, 0, 2, 1, 1, 2, 2, 1, 0, 1, 2, 0, 0, 2, 1, 0, 0], + [2, 0, 2, 2, 2, 0, 1, 2, 2, 1, 2, 2, 0, 2, 2, 0, 1, 0, 1, 2], + [2, 1, 0, 2, 1, 2, 0, 2, 2, 2, 1, 2, 2, 0, 1, 2, 0, 1, 2, 0], + [2, 1, 2, 0, 1, 1, 2, 0, 2, 1, 0, 1, 1, 2, 1, 0, 2, 0, 2, 1], + [2, 1, 2, 1, 0, 1, 2, 2, 1, 1, 2, 0, 2, 1, 0, 0, 1, 2, 0, 0], + [2, 2, 1, 1, 1, 1, 0, 1, 0, 0, 2, 2, 1, 2, 2, 1, 0, 1, 0, 2]] + + +def ca_19_2_6_4(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_19_2_6_4 + sage: C = ca_19_2_6_4() + sage: is_covering_array(C,2,4) + True + + """ + return [[0, 0, 0, 2, 0, 0], + [0, 0, 1, 0, 1, 1], + [0, 1, 3, 1, 2, 1], + [0, 2, 2, 3, 0, 2], + [0, 3, 3, 2, 3, 3], + [1, 0, 3, 1, 1, 2], + [1, 1, 0, 3, 1, 3], + [1, 1, 2, 0, 3, 0], + [1, 2, 1, 2, 2, 0], + [1, 3, 1, 3, 0, 1], + [2, 0, 2, 3, 2, 3], + [2, 1, 1, 2, 3, 2], + [2, 2, 0, 1, 3, 1], + [2, 2, 3, 0, 0, 3], + [2, 3, 2, 1, 1, 0], + [3, 0, 3, 3, 3, 0], + [3, 1, 1, 1, 0, 3], + [3, 2, 2, 2, 1, 1], + [3, 3, 0, 0, 2, 2]] + + +def ca_21_2_7_4(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + This CA is also uniform. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_21_2_7_4 + sage: C = ca_21_2_7_4() + sage: is_covering_array(C,2,4) + True + + """ + return [[0, 0, 1, 0, 0, 0, 0], + [0, 0, 3, 1, 1, 1, 1], + [0, 1, 1, 2, 2, 2, 2], + [0, 1, 2, 3, 0, 1, 3], + [0, 2, 0, 3, 3, 0, 2], + [0, 3, 1, 3, 3, 3, 1], + [1, 0, 0, 3, 2, 3, 3], + [1, 1, 3, 1, 3, 3, 0], + [1, 2, 1, 2, 1, 0, 3], + [1, 2, 3, 2, 0, 2, 1], + [1, 3, 2, 0, 1, 1, 2], + [2, 0, 3, 0, 3, 2, 3], + [2, 1, 2, 1, 2, 0, 1], + [2, 2, 1, 1, 0, 3, 2], + [2, 2, 2, 3, 1, 2, 0], + [2, 3, 0, 2, 3, 1, 0], + [3, 0, 2, 2, 3, 3, 2], + [3, 1, 0, 0, 1, 3, 1], + [3, 2, 1, 0, 2, 1, 0], + [3, 3, 0, 1, 0, 2, 3], + [3, 3, 3, 3, 2, 0, 2]] + + +def ca_29_2_7_5(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_29_2_7_5 + sage: C = ca_29_2_7_5() + sage: is_covering_array(C,2,5) + True + + """ + return [[0, 2, 2, 3, 0, 0, 0], + [1, 4, 3, 4, 2, 3, 0], + [2, 3, 0, 0, 4, 2, 0], + [3, 0, 1, 2, 3, 4, 0], + [4, 1, 4, 1, 1, 1, 0], + [0, 0, 2, 4, 1, 2, 1], + [1, 2, 4, 0, 2, 4, 1], + [1, 3, 1, 2, 1, 0, 1], + [2, 1, 2, 2, 4, 3, 1], + [3, 3, 3, 1, 0, 1, 1], + [4, 4, 0, 3, 3, 0, 1], + [0, 1, 3, 0, 3, 0, 2], + [1, 0, 3, 3, 4, 1, 2], + [2, 2, 1, 4, 3, 1, 2], + [2, 4, 4, 2, 0, 2, 2], + [3, 2, 0, 1, 1, 3, 2], + [4, 3, 2, 4, 2, 4, 2], + [0, 3, 4, 3, 3, 3, 3], + [1, 1, 0, 4, 0, 4, 3], + [2, 0, 4, 1, 2, 0, 3], + [3, 1, 1, 3, 2, 2, 3], + [3, 4, 2, 0, 1, 1, 3], + [4, 2, 3, 2, 4, 2, 3], + [0, 0, 0, 2, 2, 1, 4], + [0, 4, 1, 1, 4, 4, 4], + [1, 1, 2, 1, 3, 2, 4], + [2, 2, 3, 3, 1, 4, 4], + [3, 3, 4, 4, 4, 0, 4], + [4, 0, 1, 0, 0, 3, 4]] + + +def ca_37_2_4_6(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_37_2_4_6 + sage: C = ca_37_2_4_6() + sage: is_covering_array(C,2,6) + True + + """ + return [[0, 0, 1, 0], + [0, 0, 2, 1], + [0, 1, 0, 2], + [0, 2, 0, 5], + [0, 3, 3, 3], + [0, 4, 4, 4], + [0, 5, 5, 5], + [1, 0, 0, 4], + [1, 1, 1, 5], + [1, 2, 3, 1], + [1, 3, 4, 0], + [1, 4, 5, 3], + [1, 5, 2, 2], + [2, 0, 0, 3], + [2, 1, 4, 1], + [2, 2, 5, 4], + [2, 3, 1, 2], + [2, 4, 2, 5], + [2, 5, 3, 0], + [3, 0, 5, 2], + [3, 1, 3, 4], + [3, 2, 2, 0], + [3, 3, 0, 5], + [3, 4, 1, 1], + [3, 5, 4, 3], + [4, 0, 3, 5], + [4, 1, 2, 3], + [4, 2, 4, 2], + [4, 3, 5, 1], + [4, 4, 0, 0], + [4, 5, 1, 4], + [5, 0, 4, 5], + [5, 1, 5, 0], + [5, 2, 1, 3], + [5, 3, 2, 4], + [5, 4, 3, 2], + [5, 5, 0, 1]] + + +def ca_39_2_5_6(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_39_2_5_6 + sage: C = ca_39_2_5_6() + sage: is_covering_array(C,2,6) + True + + """ + return [[0, 0, 1, 1, 0], + [1, 5, 2, 2, 0], + [2, 4, 5, 4, 0], + [3, 2, 0, 3, 0], + [4, 3, 4, 5, 0], + [5, 1, 3, 0, 0], + [0, 4, 4, 3, 1], + [1, 3, 5, 0, 1], + [2, 2, 1, 2, 1], + [3, 0, 3, 5, 1], + [4, 1, 2, 1, 1], + [5, 5, 0, 4, 1], + [0, 5, 5, 5, 2], + [1, 1, 1, 3, 2], + [2, 3, 0, 1, 2], + [3, 4, 2, 0, 2], + [4, 2, 3, 4, 2], + [5, 0, 4, 2, 2], + [0, 1, 0, 4, 3], + [0, 3, 3, 2, 3], + [1, 0, 2, 4, 3], + [2, 2, 4, 0, 3], + [3, 5, 4, 1, 3], + [4, 0, 5, 3, 3], + [5, 4, 1, 5, 3], + [0, 0, 0, 0, 4], + [1, 2, 0, 5, 4], + [1, 4, 3, 1, 4], + [2, 1, 4, 4, 4], + [3, 1, 5, 2, 4], + [4, 5, 1, 0, 4], + [5, 3, 2, 3, 4], + [0, 2, 2, 0, 5], + [1, 1, 4, 5, 5], + [2, 0, 2, 5, 5], + [2, 5, 3, 3, 5], + [3, 3, 1, 4, 5], + [4, 4, 0, 2, 5], + [5, 2, 5, 1, 5]] + + +def ca_41_2_6_6(): + r""" + Return a CA with the given parameters. This CA is proven to be optimal. + This CA is also uniform. + + Data obtained from https://zenodo.org/records/1476059 + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_covering_array + sage: from sage.combinat.designs.database import ca_41_2_6_6 + sage: C = ca_41_2_6_6() + sage: is_covering_array(C,2,6) + True + + """ + return [[0, 0, 0, 0, 0, 0], + [1, 1, 4, 5, 4, 0], + [2, 3, 3, 5, 2, 0], + [3, 0, 2, 3, 3, 0], + [3, 5, 5, 2, 1, 0], + [4, 2, 1, 4, 5, 0], + [5, 4, 4, 1, 1, 0], + [0, 0, 1, 1, 1, 1], + [1, 2, 5, 1, 2, 1], + [2, 4, 4, 3, 5, 1], + [2, 5, 2, 4, 0, 1], + [3, 1, 3, 0, 4, 1], + [4, 4, 0, 5, 3, 1], + [5, 3, 1, 2, 0, 1], + [0, 1, 2, 2, 2, 2], + [1, 3, 1, 3, 4, 2], + [1, 5, 4, 0, 3, 2], + [2, 0, 5, 5, 1, 2], + [3, 3, 0, 1, 5, 2], + [4, 4, 3, 2, 0, 2], + [5, 2, 3, 4, 3, 2], + [0, 2, 3, 3, 1, 3], + [0, 5, 1, 5, 5, 3], + [1, 4, 2, 1, 0, 3], + [2, 2, 0, 2, 4, 3], + [3, 3, 5, 4, 3, 3], + [4, 0, 4, 4, 2, 3], + [5, 1, 5, 0, 5, 3], + [0, 3, 4, 2, 3, 4], + [1, 1, 0, 4, 1, 4], + [2, 2, 2, 0, 5, 4], + [3, 4, 1, 0, 2, 4], + [4, 1, 5, 3, 0, 4], + [4, 5, 3, 1, 4, 4], + [5, 0, 2, 5, 4, 4], + [0, 4, 5, 4, 4, 5], + [1, 0, 3, 2, 5, 5], + [2, 1, 1, 1, 3, 5], + [3, 2, 4, 5, 0, 5], + [4, 3, 2, 0, 1, 5], + [5, 5, 0, 3, 2, 5]] + + +# Make dictionary with keys (t, v) and values (N, k) which are the +# smallest N and largest k such that a CA(N; t, k, v) can be made using +# the database. +CA_constructions = { + (2,3): ((11,5), (12,7), (13,9), (14,10), (15,20)), + (2,4): ((19,6), (21,7)), + (2,5): ((29,7),), + (2,6): ((37,4), (39,5), (41,6)) +} + +# Add this data to the module's doc. +LIST_OF_CA_CONSTRUCTIONS = ", ".join(":func:`CA({},{},{},{}) `".format(N,t,k,v,N,t,k,v) + for (t,v) in CA_constructions for (N,k) in CA_constructions[(t,v)]) + + __doc__ = __doc__.format( LIST_OF_OA_CONSTRUCTIONS=LIST_OF_OA_CONSTRUCTIONS, LIST_OF_MOLS_CONSTRUCTIONS=LIST_OF_MOLS_CONSTRUCTIONS, @@ -5041,6 +5606,7 @@ def BIBD_56_11_2(): LIST_OF_DF=LIST_OF_DF, LIST_OF_DM=LIST_OF_DM, LIST_OF_QDM=LIST_OF_QDM, - LIST_OF_EDS=LIST_OF_EDS) -del LIST_OF_OA_CONSTRUCTIONS, LIST_OF_MOLS_CONSTRUCTIONS, LIST_OF_VMT_VECTORS,LIST_OF_DF, LIST_OF_DM, LIST_OF_QDM, LIST_OF_EDS, LIST_OF_BIBD + LIST_OF_EDS=LIST_OF_EDS, + LIST_OF_CA_CONSTRUCTIONS=LIST_OF_CA_CONSTRUCTIONS) +del LIST_OF_OA_CONSTRUCTIONS, LIST_OF_MOLS_CONSTRUCTIONS, LIST_OF_VMT_VECTORS,LIST_OF_DF, LIST_OF_DM, LIST_OF_QDM, LIST_OF_EDS, LIST_OF_BIBD, LIST_OF_CA_CONSTRUCTIONS del PolynomialRing, ZZ, a, diff --git a/src/sage/combinat/designs/design_catalog.py b/src/sage/combinat/designs/design_catalog.py index 8bf7f14fd0b..b5135151866 100644 --- a/src/sage/combinat/designs/design_catalog.py +++ b/src/sage/combinat/designs/design_catalog.py @@ -72,7 +72,7 @@ REFERENCES: .. [1] La Jolla Covering Repository, - https://math.ccrwest.org/cover.html + https://dmgordon.org/cover """ from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index 054e5782930..c862821330e 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -24,20 +24,20 @@ def is_covering_array(array, strength=None, levels=None, verbose=False, paramete INPUT: - - ``array`` -- the Covering Array to be tested. + - ``array`` -- the Covering Array to be tested - - ``strength`` (integer) -- the parameter `t` of the covering array, + - ``strength`` -- integer; the parameter `t` of the covering array, such that in any selection of `t` columns of the array, every `t` -tuple appears at least once. If set to None then all t > 0 are tested to and the maximal strength is used. - - ``levels`` -- the number of symbols that appear in ``array``. - If set to None, then each unique entry in ``array`` is counted. + - ``levels`` -- the number of symbols that appear in ``array`` + If set to None, then each unique entry in ``array`` is counted - - ``verbose`` (boolean) -- whether to display some information about - the covering array. + - ``verbose`` -- boolean; whether to display some information about + the covering array - - ``parameters`` (boolean) -- whether to return the parameters of + - ``parameters`` -- boolean; whether to return the parameters of the Covering Array. If set to ``True``, the function returns a pair ``(boolean_answer,(N,t,k,v))``. @@ -145,7 +145,6 @@ def is_covering_array(array, strength=None, levels=None, verbose=False, paramete ....: [0, 1, 1, 2, 0, 2, 2, 1]] sage: is_covering_array(C,strength=2,parameters=True) (False, (8, 0, 8, 3)) - """ from itertools import product, combinations @@ -211,7 +210,7 @@ def is_covering_array(array, strength=None, levels=None, verbose=False, paramete return result -def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="OA"): +def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology='OA'): r""" Check that the integer matrix `OA` is an `OA(k,n,t)`. @@ -222,13 +221,13 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O - ``OA`` -- the Orthogonal Array to be tested - - ``k``, ``n``, ``t`` (integers) -- only implemented for `t=2`. + - ``k``, ``n``, ``t`` -- integers; only implemented for `t=2` - - ``verbose`` (boolean) -- whether to display some information when ``OA`` - is not an orthogonal array `OA(k,n)`. + - ``verbose`` -- boolean; whether to display some information when ``OA`` + is not an orthogonal array `OA(k,n)` - - ``terminology`` (string) -- how to phrase the information when ``verbose = - True``. Possible values are `"OA"`, `"MOLS"`. + - ``terminology`` -- string; how to phrase the information when ``verbose = + True``. Possible values are `"OA"`, `"MOLS"` EXAMPLES:: @@ -245,7 +244,7 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O sage: is_orthogonal_array(OA,8,9,verbose=True) Columns 0 and 3 are not orthogonal False - sage: is_orthogonal_array(OA,8,9, verbose=True, terminology="MOLS") + sage: is_orthogonal_array(OA,8,9, verbose=True, terminology='MOLS') Squares 0 and 3 are not orthogonal False @@ -259,13 +258,13 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O sage: is_orthogonal_array([[3]*8],8,9, verbose=True) The number of rows is 1 instead of 9^2=81 False - sage: is_orthogonal_array([[3]*8],8,9, verbose=True, terminology="MOLS") + sage: is_orthogonal_array([[3]*8],8,9, verbose=True, terminology='MOLS') All squares do not have dimension n^2=9^2 False sage: is_orthogonal_array([[3]*7],8,9, verbose=True) Some row does not have length 8 False - sage: is_orthogonal_array([[3]*7],8,9, verbose=True, terminology="MOLS") + sage: is_orthogonal_array([[3]*7],8,9, verbose=True, terminology='MOLS') The number of squares is not 6 False @@ -290,14 +289,14 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O for R in OA: if len(R) != k: if verbose: - print({"OA" : "Some row does not have length "+str(k), - "MOLS" : "The number of squares is not "+str(k-2)}[terminology]) + print({"OA": "Some row does not have length "+str(k), + "MOLS": "The number of squares is not "+str(k-2)}[terminology]) return False if len(OA) != n2: if verbose: - print({"OA" : "The number of rows is {} instead of {}^2={}".format(len(OA),n,n2), - "MOLS" : "All squares do not have dimension n^2={}^2".format(n)}[terminology]) + print({"OA": "The number of rows is {} instead of {}^2={}".format(len(OA),n,n2), + "MOLS": "All squares do not have dimension n^2={}^2".format(n)}[terminology]) return False if n == 0: @@ -320,8 +319,8 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O for j,x in enumerate(R): if x < 0 or x >= n: if verbose: - print({"OA" : "{} is not in the interval [0..{}]".format(x,n-1), - "MOLS" : "Entry {} was expected to be in the interval [0..{}]".format(x,n-1)}[terminology]) + print({"OA": "{} is not in the interval [0..{}]".format(x,n-1), + "MOLS": "Entry {} was expected to be in the interval [0..{}]".format(x,n-1)}[terminology]) sig_free(OAc) return False OAc[j*n2+i] = x @@ -342,8 +341,8 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O sig_free(OAc) bitset_free(seen) if verbose: - print({"OA" : "Columns {} and {} are not orthogonal".format(i,j), - "MOLS" : "Squares {} and {} are not orthogonal".format(i,j)}[terminology]) + print({"OA": "Columns {} and {} are not orthogonal".format(i,j), + "MOLS": "Squares {} and {} are not orthogonal".format(i,j)}[terminology]) return False sig_free(OAc) @@ -353,7 +352,7 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=False): r""" - Checks that input is a Group Divisible Design on `\{0,...,v-1\}` + Check that input is a Group Divisible Design on `\{0, \ldots, v-1\}`. For more information on Group Divisible Designs, see :class:`~sage.combinat.designs.group_divisible_designs.GroupDivisibleDesign`. @@ -366,18 +365,18 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals - ``blocks`` -- collection of blocks - - ``v`` (integers) -- size of the ground set assumed to be `X=\{0,...,v-1\}`. + - ``v`` -- integers; size of the ground set assumed to be `X=\{0,...,v-1\}` - ``G`` -- list of integers of which the sizes of the groups must be - elements. Set to ``None`` (automatic guess) by default. + elements. Set to ``None`` (automatic guess) by default - ``K`` -- list of integers of which the sizes of the blocks must be - elements. Set to ``None`` (automatic guess) by default. + elements. Set to ``None`` (automatic guess) by default - - ``lambd`` -- value of `\lambda`. Set to `1` by default. + - ``lambd`` -- value of `\lambda`. Set to `1` by default - - ``verbose`` (boolean) -- whether to display some information when the - design is not a GDD. + - ``verbose`` -- boolean; whether to display some information when the + design is not a GDD EXAMPLES:: @@ -430,7 +429,7 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals if v < 0 or lambd < 0: if verbose: - print("v={} and lambda={} must be non-negative integers".format(v,l)) + print("v={} and lambda={} must be nonnegative integers".format(v,l)) return False # Block sizes are element of K @@ -537,7 +536,7 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): r""" - Checks that input is a Pairwise Balanced Design (PBD) on `\{0,...,v-1\}` + Check that input is a Pairwise Balanced Design (PBD) on `\{0, \ldots, v-1\}`. For more information on Pairwise Balanced Designs (PBD), see :class:`~sage.combinat.designs.bibd.PairwiseBalancedDesign`. @@ -546,15 +545,15 @@ def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): - ``blocks`` -- collection of blocks - - ``v`` (integers) -- size of the ground set assumed to be `X=\{0,...,v-1\}`. + - ``v`` -- integers; size of the ground set assumed to be `X=\{0,...,v-1\}` - ``K`` -- list of integers of which the sizes of the blocks must be - elements. Set to ``None`` (automatic guess) by default. + elements; set to ``None`` (automatic guess) by default - - ``lambd`` -- value of `\lambda`. Set to `1` by default. + - ``lambd`` -- value of `\lambda` (default: `1`) - - ``verbose`` (boolean) -- whether to display some information when the - design is not a PBD. + - ``verbose`` -- boolean; whether to display some information when the + design is not a PBD EXAMPLES:: @@ -593,7 +592,7 @@ def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): def is_projective_plane(blocks, verbose=False): r""" - Test whether the blocks form a projective plane on `\{0,...,v-1\}` + Test whether the blocks form a projective plane on `\{0,...,v-1\}`. A *projective plane* is an incidence structure that has the following properties: @@ -612,7 +611,6 @@ def is_projective_plane(blocks, verbose=False): - ``verbose`` -- whether to print additional information - EXAMPLES:: sage: from sage.combinat.designs.designs_pyx import is_projective_plane @@ -681,10 +679,10 @@ def is_difference_matrix(M,G,k,lmbda=1,verbose=False): - ``k`` -- integer - - ``lmbda`` (integer) -- set to `1` by default. + - ``lmbda`` -- integer (default: `1`) - - ``verbose`` (boolean) -- whether to print some information when the answer - is ``False``. + - ``verbose`` -- boolean; whether to print some information when the answer + is ``False`` EXAMPLES:: @@ -732,7 +730,7 @@ def is_difference_matrix(M,G,k,lmbda=1,verbose=False): def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False): r""" - Test if the matrix is a `(G,k;\lambda,\mu;u)`-quasi-difference matrix + Test if the matrix is a `(G,k;\lambda,\mu;u)`-quasi-difference matrix. Let `G` be an abelian group of order `n`. A `(n,k;\lambda,\mu;u)`-quasi-difference matrix (QDM) is a matrix `Q_{ij}` @@ -757,8 +755,8 @@ def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False): - ``k``, ``lmbda``, ``mu``, ``u`` -- integers - - ``verbose`` (boolean) -- whether to print some information when the answer - is ``False``. + - ``verbose`` -- boolean; whether to print some information when the answer + is ``False`` EXAMPLES: @@ -954,15 +952,15 @@ _OA_cache[0].max_true = -1 _OA_cache[1].max_true = -1 _OA_cache_size = 2 -cpdef _OA_cache_set(int k,int n,truth_value): +cpdef _OA_cache_set(int k, int n, truth_value): r""" - Sets a value in the OA cache of existence results + Set a value in the OA cache of existence results. INPUT: - - ``k``, ``n`` (integers) + - ``k``, ``n`` -- integers - - ``truth_value`` -- one of ``True,False,Unknown`` + - ``truth_value`` -- one of ``True``, ``False``, ``Unknown`` """ global _OA_cache, _OA_cache_size cdef int i @@ -991,7 +989,7 @@ cpdef _OA_cache_set(int k,int n,truth_value): cpdef _OA_cache_get(int k,int n): r""" - Gets a value from the OA cache of existence results + Get a value from the OA cache of existence results. INPUT: @@ -1010,7 +1008,7 @@ cpdef _OA_cache_get(int k,int n): cpdef _OA_cache_construction_available(int k,int n): r""" - Tests if a construction is implemented using the cache's information + Test if a construction is implemented using the cache's information. INPUT: diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index eb45720a67d..49b25c12dd0 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -85,6 +85,7 @@ def group_law(G): else: raise ValueError("%s does not seem to be a group" % G) + def block_stabilizer(G, B): r""" Compute the left stabilizer of the block ``B`` under the action of ``G``. @@ -122,8 +123,8 @@ def block_stabilizer(G, B): S = [] for b in B: # fun: if we replace +(-b) with -b it completely fails!! - bb0 = op(b,b0) # bb0 = b-B[0] - if all(op(bb0,c) in B for c in B): + bb0 = op(b, b0) # bb0 = b-B[0] + if all(op(bb0, c) in B for c in B): S.append(bb0) return S @@ -135,8 +136,8 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): INPUT: - ``G`` -- group of cardinality ``v`` - - ``D`` -- a set of ``k``-subsets of ``G`` - - ``v``, ``k`` and ``l`` -- optional parameters of the difference family + - ``D`` -- set of ``k``-subsets of ``G`` + - ``v``, ``k``, ``l`` -- (optional) parameters of the difference family - ``verbose`` -- boolean (default: ``False``); whether to print additional information @@ -278,7 +279,7 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): for c in d: if b == c: continue - gg = mul(b,inv(c)) # = b-c or bc^{-1} + gg = mul(b, inv(c)) # = b-c or bc^{-1} if gg not in tmp_counter: tmp_counter[gg] = 0 where[gg].add(i) @@ -318,7 +319,7 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): g, counter[g], sorted(where[g]))) if too_much: print("Too much:") - for g in too_much: + for g in too_much: print(" {} is obtained {} times in blocks {}".format( g, counter[g], sorted(where[g]))) if too_few or too_much: @@ -328,6 +329,7 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): print("It is a ({},{},{})-difference family".format(v, k, l)) return True + def singer_difference_set(q,d): r""" Return a difference set associated to the set of hyperplanes in a projective @@ -386,9 +388,10 @@ def singer_difference_set(q,d): # build a polynomial c over GF(q) such that GF(q)[x] / (c(x)) is a # GF(q**(d+1)) and such that x is a multiplicative generator. p,e = q.factor()[0] - c = conway_polynomial(p,e*(d+1)) - if e != 1: # i.e. q is not a prime, so we factorize c over GF(q) and pick - # one of its factor + c = conway_polynomial(p, e*(d+1)) + if e != 1: + # i.e. q is not a prime, so we factorize c over GF(q) and pick + # one of its factor K = GF(q,'z') c = c.change_ring(K).factor()[0][0] else: @@ -411,6 +414,7 @@ def singer_difference_set(q,d): return Zmod((q**(d+1)-1)//(q-1)), [powers] + def df_q_6_1(K, existence=False, check=True): r""" Return a `(q,6,1)`-difference family over the finite field `K`. @@ -451,7 +455,7 @@ def df_q_6_1(K, existence=False, check=True): xx = x**5 to_coset = {x**i * xx**j: i for i in range(5) for j in range((v-1)/5)} - for c in to_coset: # the loop runs through all nonzero elements of K + for c in to_coset: # the loop runs through all nonzero elements of K if c == one or c == r or c == r2: continue if len(set(to_coset[elt] for elt in (r-one, c*(r-one), c-one, c-r, c-r**2))) == 5: @@ -470,6 +474,7 @@ def df_q_6_1(K, existence=False, check=True): return D + def radical_difference_set(K, k, l=1, existence=False, check=True): r""" Return a difference set made of a cyclotomic coset in the finite field @@ -635,6 +640,7 @@ def radical_difference_set(K, k, l=1, existence=False, check=True): return D + def one_cyclic_tiling(A,n): r""" Given a subset ``A`` of the cyclic additive group `G = Z / nZ` return @@ -698,6 +704,7 @@ def one_cyclic_tiling(A,n): for c in M: return [i-1 for i in c] + def one_radical_difference_family(K, k): r""" Search for a radical difference family on ``K`` using dancing links @@ -710,11 +717,9 @@ def one_radical_difference_family(K, k): INPUT: - ``K`` -- a finite field of cardinality `q` - - ``k`` -- a positive integer so that `k(k-1)` divides `q-1` + - ``k`` -- positive integer so that `k(k-1)` divides `q-1` - OUTPUT: - - Either a difference family or ``None`` if it does not exist. + OUTPUT: either a difference family or ``None`` if it does not exist ALGORITHM: @@ -792,13 +797,13 @@ def one_radical_difference_family(K, k): A = [r**i - 1 for i in range(1,m+1)] else: m = k // 2 - r = x ** ((q-1) // (k-1)) # (k-1)-th root of unity + r = x ** ((q-1) // (k-1)) # (k-1)-th root of unity A = [r**i - 1 for i in range(1,m)] A.append(K.one()) # instead of the complicated multiplicative group K^*/(±C) we use the # discrete logarithm to convert everything into the additive group Z/cZ - c = m * (q-1) // e # cardinal of ±C + c = m * (q-1) // e # cardinal of ±C from sage.groups.generic import discrete_log logA = [discrete_log(a,x) % c for a in A] @@ -817,6 +822,7 @@ def one_radical_difference_family(K, k): d.insert(K.zero(),0) return D + def radical_difference_family(K, k, l=1, existence=False, check=True): r""" Return a ``(v,k,l)``-radical difference family. @@ -834,7 +840,7 @@ def radical_difference_family(K, k, l=1, existence=False, check=True): - ``K`` -- a finite field - ``k`` -- positive integer; the size of the blocks - - ``l`` -- integer (default: ``1``); the `\lambda` parameter + - ``l`` -- integer (default: `1`); the `\lambda` parameter - ``existence`` -- if ``True``, then return either ``True`` if Sage knows how to build such design, ``Unknown`` if it does not and ``False`` if it knows that the design does not exist @@ -927,6 +933,7 @@ def radical_difference_family(K, k, l=1, existence=False, check=True): return D + def twin_prime_powers_difference_set(p, check=True): r""" Return a difference set on `GF(p) \times GF(p+2)`. @@ -982,6 +989,7 @@ def twin_prime_powers_difference_set(p, check=True): return G, [d] + def are_mcfarland_1973_parameters(v, k, lmbda, return_parameters=False): r""" Test whether ``(v,k,lmbda)`` is a triple that can be obtained from the @@ -992,7 +1000,7 @@ def are_mcfarland_1973_parameters(v, k, lmbda, return_parameters=False): INPUT: - ``v``, ``k``, ``lmbda`` -- integers; parameters of the difference family - - ``return_parameters`` -- boolean (default ``False``); if ``True``, return a + - ``return_parameters`` -- boolean (default: ``False``); if ``True``, return a pair ``(True, (q, s))`` so that ``(q,s)`` can be used in the function :func:`mcfarland_1973_construction` to actually build a ``(v,k,lmbda)``-difference family. Or ``(False, None)`` if the @@ -1029,18 +1037,18 @@ def are_mcfarland_1973_parameters(v, k, lmbda, return_parameters=False): 96 20 4 4 1 """ if v <= k or k <= lmbda: - return (False,None) if return_parameters else False + return (False, None) if return_parameters else False k = ZZ(k) lmbda = ZZ(lmbda) - qs,r = (k - lmbda).sqrtrem() # sqrt(k-l) should be q^s + qs, r = (k - lmbda).sqrtrem() # sqrt(k-l) should be q^s if r or (qs*(qs-1)) % lmbda: - return (False,None) if return_parameters else False + return (False, None) if return_parameters else False q = qs*(qs-1) // lmbda + 1 if (q <= 1 or - v * (q-1) != qs*q * (qs*q+q-2) or + v * (q-1) != qs*q * (qs*q+q-2) or k * (q-1) != qs * (qs*q-1)): - return (False,None) if return_parameters else False + return (False, None) if return_parameters else False # NOTE: below we compute the value of s so that qs = q^s. If the method # is_power_of of integers would be able to return the exponent, we could use @@ -1050,10 +1058,11 @@ def are_mcfarland_1973_parameters(v, k, lmbda, return_parameters=False): p2,a2 = q.is_prime_power(get_data=True) if a1 == 0 or a2 == 0 or p1 != p2 or a1 % a2: - return (False,None) if return_parameters else False + return (False, None) if return_parameters else False return (True, (q, a1//a2)) if return_parameters else True + def mcfarland_1973_construction(q, s): r""" Return a difference set. @@ -1117,6 +1126,7 @@ def mcfarland_1973_construction(q, s): return G,[D] + def are_hadamard_difference_set_parameters(v, k, lmbda): r""" Check whether ``(v,k,lmbda)`` is of the form ``(4N^2, 2N^2 - N, N^2 - N)``. @@ -1137,13 +1147,14 @@ def are_hadamard_difference_set_parameters(v, k, lmbda): N2 = N*N return v == 4*N2 and k == 2*N2 - N and lmbda == N2 - N + @cached_function def hadamard_difference_set_product_parameters(N): r""" Check whether a product construction is available for Hadamard difference set with parameter ``N``. - This function looks for two integers `N_1` and `N_2`` greater than `1` + This function looks for two integers `N_1` and `N_2` greater than `1` and so that `N = 2 N_1 N_2` and there exists Hadamard difference set with parameters `(4 N_i^2, 2N_i^2 - N_i, N_i^2 - N_i)`. If such pair exists, the output is the pair ``(N_1, N_2)`` otherwise it is ``None``. @@ -1180,6 +1191,7 @@ def hadamard_difference_set_product_parameters(N): return None + def hadamard_difference_set_product(G1, D1, G2, D2): r""" Make a product of two Hadamard difference sets. @@ -1219,6 +1231,7 @@ def hadamard_difference_set_product(G1, D1, G2, D2): return G, [[s for s in G if s not in D]] + def turyn_1965_3x3xK(k=4): r""" Return a difference set in either `C_3 \times C_3 \times C_4` or `C_3 \times @@ -1253,10 +1266,10 @@ def turyn_1965_3x3xK(k=4): else: raise ValueError("k must be 2 or 4") - L = [[(0,1),(1,1),(2,1),(0,2),(1,2),(2,2)], # complement of y=0 - [(0,0),(1,1),(2,2)], # x-y=0 - [(0,0),(1,2),(2,1)], # x+y=0 - [(0,0),(0,1),(0,2)]] # x=0 + L = [[(0,1),(1,1),(2,1),(0,2),(1,2),(2,2)], # complement of y=0 + [(0,0),(1,1),(2,2)], # x-y=0 + [(0,0),(1,2),(2,1)], # x+y=0 + [(0,0),(0,1),(0,2)]] # x=0 return G, [[G(v + k) for l, k in zip(L, K) for v in l]] @@ -1298,6 +1311,7 @@ def _is_periodic_sequence(seq, period): return False return True + def _create_m_sequence(q, n, check=True): r""" Create an m-sequence over GF(q) with period `q^n - 1`. @@ -1329,7 +1343,6 @@ def _create_m_sequence(q, n, check=True): Traceback (most recent call last): ... ValueError: q must be a prime power - """ from sage.rings.finite_rings.finite_field_constructor import GF @@ -1361,6 +1374,7 @@ def _create_m_sequence(q, n, check=True): assert _is_periodic_sequence(seq, period) return seq[:period] + def _get_submodule_of_order(G, order): r""" Construct a submodule of the given order from group ``G``. @@ -1390,6 +1404,7 @@ def _get_submodule_of_order(G, order): return H return None + def relative_difference_set_from_m_sequence(q, N, check=True, return_group=False): r""" Construct `R((q^N-1)/(q-1), q-1, q^{N-1}, q^{N-2})` where ``q`` is a prime power and `N\ge 2`. @@ -1465,6 +1480,7 @@ def relative_difference_set_from_m_sequence(q, N, check=True, return_group=False return G, set1 return set1 + def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group=False): r""" Construct `R((q^N-1)/(q-1), n, q^{N-1}, q^{N-2}d)` where `nd = q-1`. @@ -1475,8 +1491,8 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= INPUT: - ``q`` -- a prime power - - ``N`` -- an integer greater than 1 - - ``d`` -- an integer which divides `q-1` + - ``N`` -- integer greater than 1 + - ``d`` -- integer which divides `q-1` - ``check`` -- boolean (default: ``True``); if ``True``, check that the result is a relative difference set before returning it - ``return_group`` -- boolean (default: ``False``); if ``True``, the function @@ -1561,7 +1577,7 @@ def is_relative_difference_set(R, G, H, params, verbose=False): - ``R`` -- list; the relative diffeence set of length `k` - ``G`` -- an additive abelian group of order `mn` - ``H`` -- list; a submodule of ``G`` of order `n` - - ``params`` -- a tuple in the form `(m, n, k, d)` + - ``params`` -- tuple in the form `(m, n, k, d)` - ``verbose`` -- boolean (default: ``False``); if ``True``, the function will be verbose when the sequences do not satisfy the contraints @@ -1638,7 +1654,7 @@ def is_supplementary_difference_set(Ks, v=None, lmbda=None, G=None, verbose=Fals INPUT: - - ``Ks`` -- a list of sets to be checked + - ``Ks`` -- list of sets to be checked - ``v`` -- integer; the parameter `v` of the supplementary difference sets - ``lmbda`` -- integer; the parameter `\lambda` of the supplementary difference sets - ``G`` -- a group of order `v` @@ -1733,9 +1749,9 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru INPUT: - ``q`` -- an odd prime power - - ``existence`` -- boolean (default: ``False``); If ``True``, only check + - ``existence`` -- boolean (default: ``False``); if ``True``, only check whether the supplementary difference sets can be constructed - - ``check`` -- boolean (default: ``True``); If ``True``, check that the sets + - ``check`` -- boolean (default: ``True``); if ``True``, check that the sets are supplementary difference sets before returning them OUTPUT: @@ -1820,7 +1836,7 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing P = PolynomialRing(ZZ, 'x') - #Compute psi3, psi4 + # Compute psi3, psi4 hall = 0 for d in set1: hall += P.monomial(d[0]) @@ -1989,9 +2005,9 @@ def is_fixed_relative_difference_set(R, q): INPUT: - - ``R`` -- a list containing elements of an abelian group; the relative + - ``R`` -- list containing elements of an abelian group; the relative difference set - - ``q`` -- an integer + - ``q`` -- integer EXAMPLES:: @@ -3065,8 +3081,8 @@ def are_complementary_difference_sets(G, A, B, verbose=False): INPUT: - ``G`` -- a group of odd order - - ``A`` -- a set of elements of ``G`` - - ``B`` -- a set of elements of ``G`` + - ``A`` -- set of elements of ``G`` + - ``B`` -- set of elements of ``G`` - ``verbose`` -- boolean (default: ``False``); if ``True`` the function will be verbose when the sets do not satisfy the contraints @@ -3127,7 +3143,7 @@ def complementary_difference_setsI(n, check=True): Construct complementary difference sets in a group of order `n \cong 3 \mod 4`, `n` a prime power. Let `G` be a Galois Field of order `n`, where `n` satisfies the requirements - above. Let `A` be the set of non-zero quadratic elements in `G`, and `B = A`. + above. Let `A` be the set of nonzero quadratic elements in `G`, and `B = A`. Then `A` and `B` are complementary difference sets over a group of order `n`. This construction is described in [Sze1971]_. @@ -3192,11 +3208,11 @@ def complementary_difference_setsII(n, check=True): the corresponding multiplicative group. Then, there are two different constructions, depending on whether `t` is even or odd. - If `t \cong 2 \mod 4`, let `C_0` be the set of non-zero octic residues in `G`, + If `t \cong 2 \mod 4`, let `C_0` be the set of nonzero octic residues in `G`, and let `C_i = \rho^i C_0` for `1 \le i \le 7`. Then, `A = C_0 \cup C_1 \cup C_2 \cup C_3` and `B = C_0 \cup C_1 \cup C_6 \cup C_7`. - If `t` is odd, let `C_0` be the set of non-zero fourth powers in `G`, and let + If `t` is odd, let `C_0` be the set of nonzero fourth powers in `G`, and let `C_i = \rho^i C_0` for `1 \le i \le 3`. Then, `A = C_0 \cup C_1` and `B = C_0 \cup C_3`. @@ -3277,7 +3293,7 @@ def complementary_difference_setsIII(n, check=True): Construct complementary difference sets in a group of order `n = 2m + 1`, where `4m + 3` is a prime power. Consider a finite field `G` of order `n` and let `\rho` be a primite element - of this group. Now let `Q` be the set of non zero quadratic residues in `G`, + of this group. Now let `Q` be the set of nonzero quadratic residues in `G`, and let `A = \{ a | \rho^{2a} - 1 \in Q\}`, `B' = \{ b | -(\rho^{2b} + 1) \in Q\}`. Then `A` and `B = Q \setminus B'` are complementary difference sets over the ring of integers modulo `n`. For more details, see [Sz1969]_. @@ -3457,8 +3473,8 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch See also :wikipedia:`Difference_set`. - If there is no such difference family, an ``EmptySetError`` is raised and - if there is no construction at the moment :class:`NotImplementedError` + If there is no such difference family, an :exc:`EmptySetError` is raised and + if there is no construction at the moment :exc:`NotImplementedError` is raised. INPUT: @@ -3477,7 +3493,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch OUTPUT: A pair ``(G,D)`` made of a group `G` and a difference family `D` on that - group. Or, if ``existence=True``` a troolean or if + group. Or, if ``existence=True`` a troolean or if ``explain_construction=True`` a string. EXAMPLES:: @@ -3674,7 +3690,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch 3 Turyn 1965 construction 4 McFarland 1973 construction 5 False - 6 Unknown + 6 The database contains a (144,66,30)-difference family 7 False 8 McFarland 1973 construction 9 Unknown diff --git a/src/sage/combinat/designs/difference_matrices.py b/src/sage/combinat/designs/difference_matrices.py index 9be65fb4e65..11fe16bb8d5 100644 --- a/src/sage/combinat/designs/difference_matrices.py +++ b/src/sage/combinat/designs/difference_matrices.py @@ -19,6 +19,7 @@ from .designs_pyx import is_difference_matrix from .database import DM as DM_constructions + @cached_function def find_product_decomposition(g, k, lmbda=1): r""" @@ -71,6 +72,7 @@ def find_product_decomposition(g, k, lmbda=1): return False + def difference_matrix_product(k, M1, G1, lmbda1, M2, G2, lmbda2, check=True): r""" Return the product of the ``(G1, k, lmbda1)`` and ``(G2, k, lmbda2)`` @@ -121,9 +123,10 @@ def difference_matrix_product(k, M1, G1, lmbda1, M2, G2, lmbda2, check=True): return G,M + def difference_matrix(g,k,lmbda=1,existence=False,check=True): r""" - Return a `(g,k,\lambda)`-difference matrix + Return a `(g,k,\lambda)`-difference matrix. A matrix `M` is a `(g,k,\lambda)`-difference matrix if it has size `\lambda g\times k`, its entries belong to the group `G` of cardinality `g`, and @@ -132,27 +135,26 @@ def difference_matrix(g,k,lmbda=1,existence=False,check=True): INPUT: - - ``k`` -- (integer) number of columns. If ``k=None`` it is set to the - largest value available. + - ``k`` -- integer; number of columns. If ``k`` is ``None`` it is set to the + largest value available - - ``g`` -- (integer) cardinality of the group `G` + - ``g`` -- integer; cardinality of the group `G` - - ``lmbda`` -- (integer; default: 1) -- number of times each element of `G` - appears as a difference. + - ``lmbda`` -- integer (default: 1); number of times each element of `G` + appears as a difference - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist .. NOTE:: diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index 75704f995c8..1d1a7acb8ec 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -64,14 +64,14 @@ cdef class EvenlyDistributedSetsBacktracker: - ``K`` -- a finite field of cardinality `q` - - ``k`` -- a positive integer such that `k(k-1)` divides `q-1` + - ``k`` -- positive integer such that `k(k-1)` divides `q-1` - - ``up_to_isomorphism`` -- (boolean, default ``True``) whether only consider + - ``up_to_isomorphism`` -- boolean (default: ``True``); whether only consider evenly distributed sets up to automorphisms of the field of the form `x \mapsto ax + b`. If set to ``False`` then the iteration is over all evenly distributed sets that contain ``0`` and ``1``. - - ``check`` -- boolean (default is ``False``). Whether you want to check + - ``check`` -- boolean (default: ``False``); whether you want to check intermediate steps of the iterator. This is mainly intended for debugging purpose. Setting it to ``True`` will considerably slow the iteration. @@ -218,24 +218,24 @@ cdef class EvenlyDistributedSetsBacktracker: raise ValueError(f"{K} is not a field") cdef unsigned int q = K.cardinality() cdef unsigned int e = k*(k-1)/2 - if (q-1) % (2*e) != 0: + if (q-1) % (2*e): raise ValueError("k(k-1)={} does not divide q-1={}".format(k*(k-1),q-1)) - cdef unsigned int m = (q-1)/e + cdef unsigned int m = (q - 1) // e self.q = q self.e = e self.k = k - self.m = (q-1) / e + self.m = (q - 1) // e self.K = K self.diff = check_calloc(q, sizeof(unsigned int *)) self.diff[0] = check_malloc(q*q*sizeof(unsigned int)) - for i in range(1,self.q): + for i in range(1, self.q): self.diff[i] = self.diff[i-1] + q self.ratio = check_calloc(q, sizeof(unsigned int *)) self.ratio[0] = check_malloc(q*q*sizeof(unsigned int)) - for i in range(1,self.q): + for i in range(1, self.q): self.ratio[i] = self.ratio[i-1] + q self.B = check_malloc(k*sizeof(unsigned int)) @@ -284,7 +284,7 @@ cdef class EvenlyDistributedSetsBacktracker: - ``B`` -- an evenly distributed set - - ``check`` -- (boolean, default ``True``) whether to check the result + - ``check`` -- boolean (default: ``True``); whether to check the result EXAMPLES:: @@ -410,9 +410,7 @@ cdef class EvenlyDistributedSetsBacktracker: This is an internal function and should only be call by the backtracker implemented in the method `__iter__`. - OUTPUT: - - - ``False`` if ``self.B`` is not minimal + OUTPUT: ``False`` if ``self.B`` is not minimal - the list of evenly distributed sets isomorphic to ``self.B`` given as a list of tuples if ``self.up_to_isom=0`` or list diff --git a/src/sage/combinat/designs/ext_rep.py b/src/sage/combinat/designs/ext_rep.py index a6c5a43db5f..93f55f6daed 100644 --- a/src/sage/combinat/designs/ext_rep.py +++ b/src/sage/combinat/designs/ext_rep.py @@ -466,6 +466,7 @@ """ + def dump_to_tmpfile(s): """ Utility function to dump a string to a temporary file. @@ -483,6 +484,7 @@ def dump_to_tmpfile(s): f.close() return file_loc + def check_dtrs_protocols(input_name, input_pv): """ Check that the XML data is in a valid format. We can currently @@ -506,6 +508,7 @@ def check_dtrs_protocols(input_name, input_pv): msg = ('''Incompatible dtrs_protocols: program: %s %s: %s''' % (program_pv, input_name, input_pv)) raise RuntimeError(msg) + def open_extrep_file(fname): """ Try to guess the compression type from extension @@ -534,6 +537,7 @@ def open_extrep_file(fname): f = open(fname, 'rb') return f + def open_extrep_url(url): """ Try to guess the compression type from extension @@ -569,6 +573,7 @@ def open_extrep_url(url): pattern_decimal = re.compile(r'-?\d+\.\d+$') pattern_rational = re.compile(r'-?\d+/\d+$') + def _encode_attribute(string): """ Convert numbers in attributes into binary format. @@ -600,6 +605,7 @@ def _encode_attribute(string): else: return string + class XTree: ''' A lazy class to wrap a rooted tree representing an XML document. @@ -611,7 +617,7 @@ class XTree: - ``t.attribute`` -- attribute named - ``t.child`` -- first child named - - ``t[i]`` -- i-th child + - ``t[i]`` -- `i`-th child - ``for child in t:`` -- iterate over ``t``'s children - ``len(t)`` -- number of ``t``'s children @@ -773,6 +779,7 @@ def __len__(self): return len(self.xt_children) + class XTreeProcessor: ''' An incremental event-driven parser for ext-rep documents. @@ -862,11 +869,11 @@ def _start_element(self, name, attrs): check_dtrs_protocols('source', attrs['dtrs_protocol']) if self.list_of_designs_start_proc: self.list_of_designs_start_proc(attrs) - #self.outf.write('<%s' % name) - #pp_attributes(self.outf, attrs, indent='', precision_stack=[]) - #self.outf.write('>\n') + # self.outf.write('<%s' % name) + # pp_attributes(self.outf, attrs, indent='', precision_stack=[]) + # self.outf.write('>\n') elif name == 'designs': - pass # self.outf.write(' <%s>\n' % name) + pass # self.outf.write(' <%s>\n' % name) if self.in_item: for k, v in attrs.items(): attrs[k] = _encode_attribute(v) @@ -909,7 +916,7 @@ def _end_element(self, name): if name == 'block' or name == 'permutation' \ or name == 'preimage' or name == 'ksubset' \ or name == 'cycle_type' or name == 'row': - # these enclose lists of numbers + # these enclose lists of numbers children.append(ps) else: # the rest is a single number @@ -922,19 +929,19 @@ def _end_element(self, name): if self.save_designs: init_bd = XTree(self.current_node[2][0]) self.list_of_designs.append((init_bd.v, list(init_bd.blocks))) - #print_subxt(self.current_node[2][0], level=2, outf=self.outf) + # print_subxt(self.current_node[2][0], level=2, outf=self.outf) self._init() elif name == 'info': if self.info_proc: self.info_proc(self.current_node[2][0]) - #print_subxt(self.current_node[2][0], level=1, outf=self.outf) + # print_subxt(self.current_node[2][0], level=1, outf=self.outf) self._init() else: if name == 'designs': if self.designs_end_proc: self.designs_end_proc() - #self.outf.write(' ') - #self.outf.write('\n' % name) + # self.outf.write(' ') + # self.outf.write('\n' % name) def _char_data(self, data): """ @@ -955,9 +962,8 @@ def _char_data(self, data): {'b': 26, 'id': 't2-v13-b26-r6-k3-L1-0', 'v': 13}, ['[ DESIGN-1.1, GRAPE-4.2, GAPDoc-0.9999, GAP-4.4.3]']) """ - if self.in_item: - #@ this stripping may distort char data in the subtree + # @ this stripping may distort char data in the subtree # if they are not bracketed in some way. data = data.strip() if data: @@ -1030,6 +1036,7 @@ def designs_from_XML(fname): return proc.list_of_designs + def designs_from_XML_url(url): """ Return a list of designs contained in an XML file named by a URL. diff --git a/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx b/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx index 5edc2ff8a57..f5912e83690 100644 --- a/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx +++ b/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx @@ -91,7 +91,6 @@ def generalised_quadrangle_with_spread(const int s, const int t, RuntimeError: Sage can't build a GQ of order (3, 4) with a spread sage: designs.generalised_quadrangle_with_spread(3, 4, existence=True) Unknown - """ from sage.combinat.designs.incidence_structures import IncidenceStructure from sage.misc.unknown import Unknown @@ -187,9 +186,7 @@ def dual_GQ_ovoid(GQ, O): - ``O`` -- iterable; the iterable of blocks we want to compute the dual - OUTPUT: - - A pair ``(D, S)`` where ``D`` is the dual of ``GQ`` and + OUTPUT: a pair ``(D, S)`` where ``D`` is the dual of ``GQ`` and ``S`` is the dual of ``O`` EXAMPLES:: @@ -215,7 +212,6 @@ def dual_GQ_ovoid(GQ, O): (2, 4) sage: is_GQ_with_spread(*t) True - """ from sage.combinat.designs.incidence_structures import IncidenceStructure @@ -248,7 +244,7 @@ def generalised_quadrangle_hermitian_with_ovoid(const int q): A pair ``(D, O)`` where ``D`` is an IncidenceStructure representing the generalised quadrangle and ``O`` is a list of points of ``D`` which - constitute an ovoid of ``D`` + constitute an ovoid of ``D``. EXAMPLES:: diff --git a/src/sage/combinat/designs/group_divisible_designs.py b/src/sage/combinat/designs/group_divisible_designs.py index a583dd2607e..6bff9bffe2e 100644 --- a/src/sage/combinat/designs/group_divisible_designs.py +++ b/src/sage/combinat/designs/group_divisible_designs.py @@ -57,23 +57,22 @@ def group_divisible_design(v, K, G, existence=False, check=False): INPUT: - - ``v`` (integer) + - ``v`` -- integer - - ``K``, ``G`` (sets of integers) + - ``K``, ``G`` -- sets of integers - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. .. NOTE:: @@ -139,21 +138,20 @@ def GDD_4_2(q, existence=False, check=True): INPUT: - - ``q`` (integer) + - ``q`` -- integer - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -201,7 +199,7 @@ def GDD_4_2(q, existence=False, check=True): class GroupDivisibleDesign(IncidenceStructure): r""" - Group Divisible Design (GDD) + Group Divisible Design (GDD). Let `K` and `G` be sets of positive integers and let `\lambda` be a positive integer. A Group Divisible Design of index `\lambda` and order `v` is a @@ -222,23 +220,23 @@ class GroupDivisibleDesign(IncidenceStructure): INPUT: - ``points`` -- the underlying set. If ``points`` is an integer `v`, then - the set is considered to be `\{0, ..., v-1\}`. + the set is considered to be `\{0, ..., v-1\}` - ``groups`` -- the groups of the design. Set to ``None`` for an automatic - guess (this triggers ``check=True`` and can thus cost some time). + guess (this triggers ``check=True`` and can thus cost some time) - ``blocks`` -- collection of blocks - ``G`` -- list of integers of which the sizes of the groups must be - elements. Set to ``None`` (automatic guess) by default. + elements. Set to ``None`` (automatic guess) by default - ``K`` -- list of integers of which the sizes of the blocks must be - elements. Set to ``None`` (automatic guess) by default. + elements. Set to ``None`` (automatic guess) by default - - ``lambd`` (integer) -- value of `\lambda`, set to `1` by default. + - ``lambd`` -- integer (default: `1`); value of `\lambda` - - ``check`` (boolean) -- whether to check that the design is indeed a `GDD` - with the right parameters. Set to ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that the design is indeed a `GDD` + with the right parameters - ``copy`` -- (use with caution) if set to ``False`` then ``blocks`` must be a list of lists of integers. The list will not be copied but will be @@ -264,7 +262,7 @@ class GroupDivisibleDesign(IncidenceStructure): def __init__(self, points, groups, blocks, G=None, K=None, lambd=1, check=True, copy=True, **kwds): r""" - Constructor function + Constructor function. EXAMPLES:: diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 2ae9f79a80f..e9964af900c 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -73,12 +73,12 @@ class IncidenceStructure: ['a', 'b', 'c', 'd', 'e'] - ``blocks`` -- (i.e. edges, i.e. sets) the blocks defining the incidence - structure. Can be any iterable. + structure; can be any iterable - - ``incidence_matrix`` -- a binary incidence matrix. Each column represents - a set. + - ``incidence_matrix`` -- a binary incidence matrix; each column represents + a set - - ``name`` (a string, such as "Fano plane"). + - ``name`` -- string (such as "Fano plane") - ``check`` -- whether to check the input @@ -142,7 +142,7 @@ class IncidenceStructure: True """ def __init__(self, points=None, blocks=None, incidence_matrix=None, - name=None, check=True, copy=True): + name=None, check=True, copy=True): r""" TESTS:: @@ -271,7 +271,7 @@ def __repr__(self): Incidence structure with 7 points and 7 blocks """ return 'Incidence structure with {} points and {} blocks'.format( - self.num_points(), self.num_blocks()) + self.num_points(), self.num_blocks()) __str__ = __repr__ @@ -309,7 +309,7 @@ def __eq__(self, other): return self._blocks == other._blocks if (self.num_points() != other.num_points() or - self.num_blocks() != other.num_blocks()): + self.num_blocks() != other.num_blocks()): return False p_to_i = self._point_to_index if self._point_to_index else list(range(self.num_points())) @@ -336,11 +336,11 @@ def __ne__(self, other): def __contains__(self, block): r""" - Tests if a block belongs to the incidence structure + Test if a block belongs to the incidence structure. INPUT: - - ``block`` -- a block. + - ``block`` -- a block EXAMPLES:: @@ -409,12 +409,12 @@ def canonical_label(self): from sage.graphs.graph import Graph g = Graph() n = self.num_points() - g.add_edges((i+n,x) for i,b in enumerate(self._blocks) for x in b) - canonical_label = g.canonical_label([list(range(n)),list(range(n,n+self.num_blocks()))],certificate=True)[1] + g.add_edges((i+n, x) for i, b in enumerate(self._blocks) for x in b) + canonical_label = g.canonical_label([list(range(n)), list(range(n, n+self.num_blocks()))], certificate=True)[1] canonical_label = [canonical_label[x] for x in range(n)] self._canonical_label = canonical_label - return dict(zip(self._points,self._canonical_label)) + return dict(zip(self._points, self._canonical_label)) def is_isomorphic(self, other, certificate=False): r""" @@ -422,11 +422,10 @@ def is_isomorphic(self, other, certificate=False): INPUT: - - ``other`` -- an incidence structure. + - ``other`` -- an incidence structure - - ``certificate`` (boolean) -- whether to return an - isomorphism from ``self`` to ``other`` instead of a boolean - answer. + - ``certificate`` -- boolean (default: ``False``); whether to return an + isomorphism from ``self`` to ``other`` instead of a boolean answer EXAMPLES:: @@ -473,31 +472,30 @@ def is_isomorphic(self, other, certificate=False): True sage: IS1._canonical_label is None or IS2._canonical_label is None False - """ if (self.num_points() != other.num_points() or self.num_blocks() != other.num_blocks() or - sorted(self.block_sizes()) != sorted(other.block_sizes())): + sorted(self.block_sizes()) != sorted(other.block_sizes())): return {} if certificate else False A_canon = self.canonical_label() B_canon = other.canonical_label() - A = self.relabel(A_canon,inplace=False) - B = other.relabel(B_canon,inplace=False) + A = self.relabel(A_canon, inplace=False) + B = other.relabel(B_canon, inplace=False) if A == B: if certificate: - B_canon_rev = {y:x for x,y in B_canon.items()} - return {x:B_canon_rev[xint] for x,xint in A_canon.items()} + B_canon_rev = {y: x for x, y in B_canon.items()} + return {x: B_canon_rev[xint] for x, xint in A_canon.items()} else: return True else: return {} if certificate else False - def isomorphic_substructures_iterator(self, H2,induced=False): + def isomorphic_substructures_iterator(self, H2, induced=False): r""" - Iterates over all copies of ``H2`` contained in ``self``. + Iterate over all copies of ``H2`` contained in ``self``. A hypergraph `H_1` contains an isomorphic copy of a hypergraph `H_2` if there exists an injection `f:V(H_2)\mapsto V(H_1)` such that for any set @@ -514,10 +512,10 @@ def isomorphic_substructures_iterator(self, H2,induced=False): INPUT: - - ``H2`` an :class:`IncidenceStructure` object. + - ``H2`` -- an :class:`IncidenceStructure` object - - ``induced`` (boolean) -- whether to require the copies to be - induced. Set to ``False`` by default. + - ``induced`` -- boolean (default: ``False``); whether to require the copies to be + induced EXAMPLES: @@ -562,7 +560,7 @@ def isomorphic_substructures_iterator(self, H2,induced=False): 5616 """ from sage.combinat.designs.subhypergraph_search import SubHypergraphSearch - return SubHypergraphSearch(self,H2,induced=induced) + return SubHypergraphSearch(self, H2, induced=induced) def copy(self): r""" @@ -570,7 +568,7 @@ def copy(self): EXAMPLES:: - sage: IS = IncidenceStructure([[1,2,3,"e"]],name="Test") + sage: IS = IncidenceStructure([[1,2,3,"e"]], name='Test') sage: IS Incidence structure with 4 points and 1 blocks sage: copy(IS) @@ -583,7 +581,7 @@ def copy(self): IS = IncidenceStructure(self._blocks, name=self._name, check=False) - IS.relabel(dict(zip(range(self.num_points()),self._points))) + IS.relabel(dict(zip(range(self.num_points()), self._points))) IS._canonical_label = None if self._canonical_label is None else self._canonical_label[:] return IS @@ -600,7 +598,7 @@ def induced_substructure(self, points): INPUT: - - ``points`` -- a set of points. + - ``points`` -- set of points .. NOTE:: @@ -661,13 +659,13 @@ def trace(self, points, min_size=1, multiset=True): INPUT: - - ``points`` -- a set of points. + - ``points`` -- set of points - - ``min_size`` (integer; default 1) -- minimum size of the sets to - keep. By default all empty sets are discarded, i.e. ``min_size=1``. + - ``min_size`` -- integer (default: 1); minimum size of the sets to + keep. By default all empty sets are discarded, i.e. ``min_size=1`` - - ``multiset`` (boolean; default ``True``) -- whether to keep multiple - copies of the same set. + - ``multiset`` -- boolean (default: ``True``); whether to keep multiple + copies of the same set .. NOTE:: @@ -725,7 +723,7 @@ def trace(self, points, min_size=1, multiset=True): if not multiset: blocks = set(blocks) IS = IncidenceStructure(blocks) - IS.relabel({i:self._points[i] for i in int_points}) + IS.relabel({i: self._points[i] for i in int_points}) return IS def ground_set(self): @@ -776,7 +774,6 @@ def blocks(self): sage: BD = IncidenceStructure(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) sage: BD.blocks() [[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]] - """ if self._point_to_index is None: return [b[:] for b in self._blocks] @@ -807,10 +804,10 @@ def degree(self, p=None, subset=False): INPUT: - - ``p`` -- a point (or a set of points) of the incidence structure. + - ``p`` -- a point (or a set of points) of the incidence structure - - ``subset`` (boolean) -- whether to interpret the argument as a set of - point (``subset=True``) or as a point (``subset=False``, default). + - ``subset`` -- boolean (default: ``False``); whether to interpret the + argument as a set of point or as a point (default) EXAMPLES:: @@ -833,7 +830,7 @@ def degree(self, p=None, subset=False): # degree of a point if not subset: if self._point_to_index: - p = self._point_to_index.get(p,-1) + p = self._point_to_index.get(p, -1) else: p = p if (p >= 0 and p < len(self._points)) else -1 return sum((p in b) for b in self._blocks) if p != -1 else 0 @@ -841,7 +838,7 @@ def degree(self, p=None, subset=False): # degree of a set else: if self._point_to_index: - p = set(self._point_to_index.get(x,-1) for x in p) + p = set(self._point_to_index.get(x, -1) for x in p) else: p = set(p) if all(x >= 0 and x < len(self._points) for x in p) else set([-1]) @@ -856,7 +853,7 @@ def degrees(self, size=None): INPUT: - - ``size`` (integer) -- return the degree of all subsets of points of + - ``size`` -- integer; return the degree of all subsets of points of cardinality ``size``. When ``size=None``, the function outputs the degree of all points. @@ -866,9 +863,7 @@ def degrees(self, size=None): ``size=1`` it is indexed by tuples of size 1. This is the same information, stored slightly differently. - OUTPUT: - - A dictionary whose values are degrees and keys are either: + OUTPUT: a dictionary whose values are degrees and keys are either: - the points of the incidence structure if ``size=None`` (default) @@ -893,12 +888,12 @@ def degrees(self, size=None): return {p: d[i] for i, p in enumerate(self._points)} else: from itertools import combinations - d = {t:0 for t in combinations(range(self.num_points()),size)} + d = {t: 0 for t in combinations(range(self.num_points()), size)} for b in self._blocks: - for s in combinations(b,size): + for s in combinations(b, size): d[s] += 1 if self._point_to_index: - return {tuple([self._points[x] for x in s]):v for s,v in d.items()} + return {tuple([self._points[x] for x in s]): v for s, v in d.items()} else: return d @@ -923,7 +918,7 @@ def is_regular(self, r=None) -> bool | int: INPUT: - - ``r`` (integer) + - ``r`` -- integer OUTPUT: @@ -974,7 +969,7 @@ def is_uniform(self, k=None) -> bool | int: INPUT: - - ``k`` (integer) + - ``k`` -- integer OUTPUT: @@ -1094,7 +1089,7 @@ def intersection_graph(self, sizes=None): INPUT: - - ``sizes`` -- a list/set of integers. For convenience, setting + - ``sizes`` -- list/set of integers; for convenience, setting ``sizes`` to ``5`` has the same effect as ``sizes=[5]``. When set to ``None`` (default), behaves as ``sizes=PositiveIntegers()``. @@ -1117,8 +1112,8 @@ def intersection_graph(self, sizes=None): sizes = PositiveIntegers() elif sizes in PositiveIntegers(): sizes = (sizes,) - V = [Set(v) for v in self] - return Graph([V, lambda x,y: len(x & y) in sizes], loops=False) + V = [Set(v) for v in self] + return Graph([V, lambda x, y: len(x & y) in sizes], loops=False) def incidence_matrix(self): r""" @@ -1155,19 +1150,19 @@ def incidence_matrix(self): A[i, j] = 1 return A - def incidence_graph(self,labels=False): + def incidence_graph(self, labels=False): r""" - Return the incidence graph of the incidence structure + Return the incidence graph of the incidence structure. A point and a block are adjacent in this graph whenever they are incident. INPUT: - - ``labels`` (boolean) -- whether to return a graph whose vertices are - integers, or labelled elements. + - ``labels`` -- boolean; whether to return a graph whose vertices are + integers, or labelled elements - - ``labels is False`` (default) -- in this case the first vertices + - ``labels is False`` -- default; in this case the first vertices of the graphs are the elements of :meth:`ground_set`, and appear in the same order. Similarly, the following vertices represent the elements of :meth:`blocks`, and appear in the same order. @@ -1206,7 +1201,7 @@ def incidence_graph(self,labels=False): for b in self.blocks(): b = Set(b) G.add_vertex(b) - G.add_edges((b,x) for x in b) + G.add_edges((b, x) for x in b) return G else: @@ -1248,7 +1243,7 @@ def is_berge_cyclic(self): return not self.incidence_graph().is_forest() - def complement(self,uniform=False): + def complement(self, uniform=False): r""" Return the complement of the incidence structure. @@ -1257,7 +1252,7 @@ def complement(self,uniform=False): INPUT: - - ``uniform`` (boolean) -- + - ``uniform`` -- boolean - if set to ``False`` (default), returns the incidence structure whose blocks are the complements of all blocks of the incidence structure. @@ -1308,7 +1303,7 @@ def complement(self,uniform=False): num_blocks = self.num_blocks() i = 0 from itertools import combinations - for B in combinations(range(self.num_points()),k): + for B in combinations(range(self.num_points()), k): B = list(B) while i < num_blocks and self._blocks[i] < B: i += 1 @@ -1316,17 +1311,17 @@ def complement(self,uniform=False): i += 1 continue blocks.append(B) - I = IncidenceStructure(blocks,copy=False) + I = IncidenceStructure(blocks, copy=False) else: X = set(range(self.num_points())) I = IncidenceStructure([X.difference(B) for B in self._blocks]) - I.relabel({i:self._points[i] for i in range(self.num_points())}) + I.relabel({i: self._points[i] for i in range(self.num_points())}) return I def relabel(self, perm=None, inplace=True): r""" - Relabel the ground set + Relabel the ground set. INPUT: @@ -1340,11 +1335,10 @@ def relabel(self, perm=None, inplace=True): ``l[1]``, ... - ``None`` -- the incidence structure is relabeled to be on - `\{0,1,...,n-1\}` in the ordering given by :meth:`ground_set`. - - - ``inplace`` -- If ``True`` then return a relabeled graph and does not - touch ``self`` (default is ``False``). + `\{0,1,...,n-1\}` in the ordering given by :meth:`ground_set` + - ``inplace`` -- boolean (default: ``False``); if ``True`` then return + a relabeled graph and does not touch ``self`` EXAMPLES:: @@ -1393,7 +1387,7 @@ def relabel(self, perm=None, inplace=True): self._point_to_index = None return - if isinstance(perm, (list,tuple)): + if isinstance(perm, (list, tuple)): perm = dict(zip(self._points, perm)) if not isinstance(perm, dict): @@ -1417,7 +1411,7 @@ def relabel(self, perm=None, inplace=True): def packing(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Return a maximum packing + Return a maximum packing. A maximum packing in a hypergraph is collection of disjoint sets/blocks of maximal cardinality. This problem is NP-complete in general, and in @@ -1428,7 +1422,7 @@ def packing(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): INPUT: - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`solve @@ -1436,7 +1430,7 @@ def packing(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``). Sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- parameter for use with MILP solvers over @@ -1486,12 +1480,12 @@ def is_t_design(self, t=None, v=None, k=None, l=None, return_parameters=False): INPUT: - - ``t``, ``v``, ``k``, ``l`` (integers) -- their value is set to + - ``t``, ``v``, ``k``, ``l`` -- integers; their value is set to ``None`` by default. The function tests whether the design is a `t-(v,k,l)` design using the provided values and guesses the others. Note that ``l`` cannot be specified if ``t`` is not. - - ``return_parameters`` (boolean)-- whether to return the parameters of + - ``return_parameters`` -- boolean; whether to return the parameters of the `t`-design. If set to ``True``, the function returns a pair ``(boolean_answer,(t,v,k,l))``. @@ -1614,32 +1608,32 @@ def is_t_design(self, t=None, v=None, k=None, l=None, return_parameters=False): b = self.num_blocks() # Trivial wrong answers - if (any(len(block) != k for block in self._blocks) or # non k-uniform - v != self.num_points()): - return (False, (0,0,0,0)) if return_parameters else False + if (any(len(block) != k for block in self._blocks) or # non k-uniform + v != self.num_points()): + return (False, (0, 0, 0, 0)) if return_parameters else False # Trivial case t>k if (t is not None and t > k): if (l is None or l == 0): - return (True, (t,v,k,0)) if return_parameters else True + return (True, (t, v, k, 0)) if return_parameters else True else: - return (False, (0,0,0,0)) if return_parameters else False + return (False, (0, 0, 0, 0)) if return_parameters else False # Trivial case k=0 if k == 0: if (l is None or l == 0): - return (True, (0,v,k,b)) if return_parameters else True + return (True, (0, v, k, b)) if return_parameters else True else: - return (False, (0,0,0,0)) if return_parameters else False + return (False, (0, 0, 0, 0)) if return_parameters else False # Trivial case k=v (includes v=0) if k == v: if t is None: t = v if l is None or b == l: - return (True, (t,v,k,b)) if return_parameters else True + return (True, (t, v, k, b)) if return_parameters else True else: - return (True, (0,0,0,0)) if return_parameters else False + return (True, (0, 0, 0, 0)) if return_parameters else False # Handbook of combinatorial design theorem II.4.8: # @@ -1648,30 +1642,30 @@ def is_t_design(self, t=None, v=None, k=None, l=None, return_parameters=False): # # We look for the largest t such that self is a t-design from itertools import combinations - for tt in (range(1,k+1) if t is None else [t]): + for tt in (range(1, k + 1) if t is None else [t]): # is lambda an integer? - if (b*binomial(k,tt)) % binomial(v,tt) != 0: + if (b * binomial(k, tt)) % binomial(v, tt): tt -= 1 break s = {} for block in self._blocks: - for i in combinations(block,tt): - s[i] = s.get(i,0) + 1 + for i in combinations(block, tt): + s[i] = s.get(i, 0) + 1 if len(set(s.values())) != 1: tt -= 1 break - ll = b*binomial(k,tt) // binomial(v,tt) + ll = (b * binomial(k, tt)) // binomial(v, tt) if ((t is not None and t != tt) or - (l is not None and l != ll)): - return (False, (0,0,0,0)) if return_parameters else False + (l is not None and l != ll)): + return (False, (0, 0, 0, 0)) if return_parameters else False else: if tt == 0: ll = b - return (True, (tt,v,k,ll)) if return_parameters else True + return (True, (tt, v, k, ll)) if return_parameters else True def is_generalized_quadrangle(self, verbose=False, parameters=False): r""" @@ -1703,10 +1697,10 @@ def is_generalized_quadrangle(self, verbose=False, parameters=False): INPUT: - - ``verbose`` (boolean) -- whether to print an explanation when the - instance is not a generalized quadrangle. + - ``verbose`` -- boolean; whether to print an explanation when the + instance is not a generalized quadrangle - - ``parameters`` (boolean; ``False``) -- if set to ``True``, the + - ``parameters`` -- (boolean; ``False``); if set to ``True``, the function returns a pair ``(s,t)`` instead of ``True`` answers. In this case, `s` and `t` are the integers defined above if they exist (each can be set to ``False`` otherwise). @@ -1764,9 +1758,9 @@ def is_generalized_quadrangle(self, verbose=False, parameters=False): if parameters: s = self.is_uniform() t = self.is_regular() - s = s-1 if (s is not False and s >= 2) else False - t = t-1 if (t is not False and t >= 2) else False - return (s,t) + s = s - 1 if (s is not False and s >= 2) else False + t = t - 1 if (t is not False and t >= 2) else False + return (s, t) else: return True @@ -1777,11 +1771,11 @@ def dual(self, algorithm=None): INPUT: - ``algorithm`` -- whether to use Sage's implementation - (``algorithm=None``, default) or use GAP's (``algorithm="gap"``). + (``algorithm=None``, default) or use GAP's (``algorithm='gap'``) .. NOTE:: - The ``algorithm="gap"`` option requires GAP's Design package + The ``algorithm='gap'`` option requires GAP's Design package (included in the ``gap_packages`` Sage spkg). EXAMPLES: @@ -1798,12 +1792,12 @@ def dual(self, algorithm=None): Incidence structure with 4 points and 3 blocks sage: D.dual() # needs sage.modules Incidence structure with 3 points and 4 blocks - sage: print(D.dual(algorithm="gap")) # optional - gap_package_design + sage: print(D.dual(algorithm='gap')) # optional - gap_package_design Incidence structure with 3 points and 4 blocks sage: blocks = [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]] - sage: BD = IncidenceStructure(7, blocks, name="FanoPlane"); BD + sage: BD = IncidenceStructure(7, blocks, name='FanoPlane'); BD Incidence structure with 7 points and 7 blocks - sage: print(BD.dual(algorithm="gap")) # optional - gap_package_design + sage: print(BD.dual(algorithm='gap')) # optional - gap_package_design Incidence structure with 7 points and 7 blocks sage: BD.dual() # needs sage.modules Incidence structure with 7 points and 7 blocks @@ -1818,10 +1812,10 @@ def dual(self, algorithm=None): v = DD['v'].sage() gB = [[x - 1 for x in b] for b in DD['blocks'].sage()] return IncidenceStructure(list(range(v)), gB, name=None, check=False) - else: - return IncidenceStructure( - incidence_matrix=self.incidence_matrix().transpose(), - check=False) + + return IncidenceStructure( + incidence_matrix=self.incidence_matrix().transpose(), + check=False) def automorphism_group(self): r""" @@ -1862,9 +1856,9 @@ def automorphism_group(self): from sage.groups.perm_gps.permgroup import PermutationGroup g = Graph() n = self.num_points() - g.add_edges((i+n,x) for i,b in enumerate(self._blocks) for x in b) + g.add_edges((i + n, x) for i, b in enumerate(self._blocks) for x in b) ag = g.automorphism_group(partition=[list(range(n)), - list(range(n,n+self.num_blocks()))]) + list(range(n, n + self.num_blocks()))]) if self._point_to_index: gens = [[tuple([self._points[i] for i in cycle if (not cycle or cycle[0] < n)]) @@ -1879,7 +1873,7 @@ def automorphism_group(self): def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, *, integrality_tolerance=1e-3): r""" - Test whether the hypergraph is resolvable + Test whether the hypergraph is resolvable. A hypergraph is said to be resolvable if its sets can be partitionned into classes, each of which is a partition of the ground set. @@ -1893,10 +1887,10 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, INPUT: - - ``certificate`` (boolean) -- whether to return the classes along with - the binary answer (see examples below). + - ``certificate`` -- boolean; whether to return the classes along with + the binary answer (see examples below) - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1904,17 +1898,15 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``). Sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - - ``check`` (boolean) -- whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that + output is correct before returning it. As this is expected to be + useless, you may want to disable it whenever you want speed. - ``integrality_tolerance`` -- parameter for use with MILP solvers over - an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. + an inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` EXAMPLES: @@ -1979,18 +1971,18 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, # Lists of blocks containing i for every i dual = [[] for _ in domain] - for i,B in enumerate(self._blocks): + for i, B in enumerate(self._blocks): for x in B: dual[x].append(i) # Each class is a partition for t in range(n_classes): for x in domain: - p.add_constraint(p.sum(b[t,i] for i in dual[x]) == 1) + p.add_constraint(p.sum(b[t, i] for i in dual[x]) == 1) # Each set appears exactly once for i in range(len(self._blocks)): - p.add_constraint(p.sum(b[t,i] for t in range(n_classes)) == 1) + p.add_constraint(p.sum(b[t, i] for t in range(n_classes)) == 1) try: p.solve(log=verbose) @@ -2006,8 +1998,8 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, if check and self._classes is not False: assert sorted(id(c) for cls in self._classes for c in cls) == sorted(id(b) for b in self._blocks), "some set does not appear exactly once" domain = list(range(self.num_points())) - for i,c in enumerate(self._classes): - assert sorted(sum(c,[])) == domain, "class {} is not a partition".format(i) + for i, c in enumerate(self._classes): + assert sorted(sum(c, [])) == domain, "class {} is not a partition".format(i) if self._classes is False: return (False, []) if certificate else False @@ -2026,18 +2018,18 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, def coloring(self, k=None, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Compute a (weak) `k`-coloring of the hypergraph + Compute a (weak) `k`-coloring of the hypergraph. A weak coloring of a hypergraph `\mathcal H` is an assignment of colors to its vertices such that no set is monochromatic. INPUT: - - ``k`` (integer) -- compute a coloring with `k` colors if an integer is + - ``k`` -- integer; compute a coloring with `k` colors if an integer is provided, otherwise returns an optimal coloring (i.e. with the minimum possible number of colors). - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -2045,15 +2037,14 @@ def coloring(self, k=None, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- non-negative integer (default: ``0``). Set the level + - ``verbose`` -- nonnegative integer (default: `0`); set the level of verbosity you want from the linear program solver. Since the problem is `NP`-complete, its solving may take some time depending on - the graph. A value of 0 means that there will be no message printed by + the graph. A value of `0` means that there will be no message printed by the solver. - ``integrality_tolerance`` -- parameter for use with MILP solvers over - an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. + an inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` EXAMPLES: @@ -2078,7 +2069,7 @@ def coloring(self, k=None, solver=None, verbose=0, 3 """ if k is None: - for k in range(self.num_points()+1): + for k in range(self.num_points() + 1): try: return self.coloring(k) except ValueError: @@ -2102,11 +2093,11 @@ def coloring(self, k=None, solver=None, verbose=0, b = p.new_variable(binary=True) for x in range(self.num_points()): - p.add_constraint(p.sum(b[x,i] for i in range(k)) == 1) + p.add_constraint(p.sum(b[x, i] for i in range(k)) == 1) for s in self._blocks: for i in range(k): - p.add_constraint(p.sum(b[x,i] for x in s) <= len(s)-1) + p.add_constraint(p.sum(b[x, i] for x in s) <= len(s) - 1) try: p.solve(log=verbose) @@ -2115,13 +2106,13 @@ def coloring(self, k=None, solver=None, verbose=0, col = [[] for _ in range(k)] - for (x,i),v in p.get_values(b, convert=bool, tolerance=integrality_tolerance).items(): + for (x, i), v in p.get_values(b, convert=bool, tolerance=integrality_tolerance).items(): if v: col[i].append(self._points[x]) return col - def edge_coloring(self): + def edge_coloring(self) -> list: r""" Compute a proper edge-coloring. @@ -2130,9 +2121,7 @@ def edge_coloring(self): receive different colors. The coloring returned minimizes the number of colors. - OUTPUT: - - A partition of the sets into color classes. + OUTPUT: a partition of the sets into color classes EXAMPLES:: @@ -2150,7 +2139,7 @@ def edge_coloring(self): g = Graph([list(range(self.num_blocks())), lambda x, y: len(blocks_sets[x] & blocks_sets[y])], loops=False) - return [[blocks[i] for i in C] for C in g.coloring(algorithm="MILP")] + return [[blocks[i] for i in C] for C in g.coloring(algorithm='MILP')] def _spring_layout(self): r""" @@ -2196,15 +2185,15 @@ def _spring_layout(self): for x in s: g.add_edge((0, s), (1, x)) - _ = g.plot(iterations=50000,save_pos=True) + _ = g.plot(iterations=50000, save_pos=True) # The values are rounded as TikZ does not like accuracy. return {k[1]: (round(x, 3), round(y, 3)) for k, (x, y) in g.get_pos().items()} - def _latex_(self): + def _latex_(self) -> str: r""" - Return a TikZ representation of the incidence structure + Return a TikZ representation of the incidence structure. EXAMPLES:: @@ -2236,7 +2225,6 @@ def _latex_(self): \draw node...; \draw node...; \end{tikzpicture} - """ from sage.functions.trig import arctan2 @@ -2258,11 +2246,12 @@ def _latex_(self): pos = self._spring_layout() tex = "\\begin{tikzpicture}[scale=3]\n" - colors = ["black", "red", "green", "blue", "cyan", "magenta", "yellow","pink","brown"] - colored_sets = [(s,i) for i,S in enumerate(self.edge_coloring()) for s in S] + colors = ["black", "red", "green", "blue", "cyan", + "magenta", "yellow", "pink", "brown"] + colored_sets = [(s, i) for i, S in enumerate(self.edge_coloring()) for s in S] # Prints each set with its color - for s,i in colored_sets: + for s, i in colored_sets: current_color = colors[i % len(colors)] if len(s) == 2: @@ -2295,7 +2284,7 @@ def _latex_(self): tex += "\\end{tikzpicture}" return tex - def is_spread(self, spread): + def is_spread(self, spread) -> bool: r""" Check whether the input is a spread for ``self``. @@ -2352,10 +2341,7 @@ def is_spread(self, spread): points.difference_update(sblock) - if points: - return False - - return True + return not points from sage.misc.rest_index_of_methods import gen_rest_table_index diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py index e05816e8977..c8b61827e90 100644 --- a/src/sage/combinat/designs/latin_squares.py +++ b/src/sage/combinat/designs/latin_squares.py @@ -21,7 +21,7 @@ :meth:`mutually_orthogonal_latin_squares` | Return `k` Mutually Orthogonal `n\times n` Latin Squares. :meth:`are_mutually_orthogonal_latin_squares` | Check that the list ``l`` of matrices in are MOLS. :meth:`latin_square_product` | Return the product of two (or more) latin squares. - :meth:`MOLS_table` | Prints the MOLS table. + :meth:`MOLS_table` | Print the MOLS table. **Table of MOLS** @@ -199,7 +199,7 @@ def are_mutually_orthogonal_latin_squares(l, verbose=False): return False from .designs_pyx import is_orthogonal_array - return is_orthogonal_array(list(zip(*[[x for R in M for x in R] for M in l])),k,n, verbose=verbose, terminology="MOLS") + return is_orthogonal_array(list(zip(*[[x for R in M for x in R] for M in l])),k,n, verbose=verbose, terminology='MOLS') def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): @@ -211,12 +211,12 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): INPUT: - - ``k`` (integer) -- number of MOLS. If ``k=None`` it is set to the largest - value available. + - ``k`` -- integer; number of MOLS. If ``k`` is ``None`` it is set to the largest + value available - - ``n`` (integer) -- size of the latin square. + - ``n`` -- integer; size of the latin square - - ``partitions`` (boolean) -- a Latin Square can be seen as 3 partitions of + - ``partitions`` -- boolean; a Latin Square can be seen as 3 partitions of the `n^2` cells of the array into `n` sets of size `n`, respectively: * The partition of rows @@ -231,10 +231,9 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): partitions satisfying this intersection property instead of the `k+2` MOLS (though the data is exactly the same in both cases). - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -299,7 +298,7 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): Unknown If you ask for such a MOLS then you will respectively get an informative - ``EmptySetError`` or :class:`NotImplementedError`:: + :exc:`EmptySetError` or :exc:`NotImplementedError`:: sage: designs.mutually_orthogonal_latin_squares(5, 5) Traceback (most recent call last): @@ -425,7 +424,8 @@ def latin_square_product(M, N, *others): INPUT: - An arbitrary number of latin squares (greater than 2). + - ``M``, ``N``, ``*others`` -- an arbitrary number of latin squares + (greater than or equal to 2) EXAMPLES:: @@ -456,20 +456,20 @@ def latin_square_product(M, N, *others): def MOLS_table(start,stop=None,compare=False,width=None): r""" - Prints the MOLS table that Sage can produce. + Print the MOLS table that Sage can produce. INPUT: - - ``start``, ``stop`` (integers) -- print the table of MOLS for value of + - ``start``, ``stop`` -- integers; print the table of MOLS for value of `n` such that ``start<=n= k and mu <= lmbda and (orthogonal_array(k,u,existence=True) is True) for (_,lmbda,mu,u),(kk,_) in QDM[n,1].items())): _OA_cache_set(k,n,True) - for (nn,lmbda,mu,u),(kk,f) in QDM[n,1].items(): - if (kk >= k and + for (nn, lmbda, mu, u), (kk, f) in QDM[n,1].items(): + if (kk >= k and mu <= lmbda and (orthogonal_array(k,u,existence=True) is True)): if existence: @@ -1012,15 +1005,15 @@ def orthogonal_array(k,n,t=2,resolvable=False, check=True,existence=False,explai return OA -def largest_available_k(n,t=2): +def largest_available_k(n, t=2): r""" Return the largest `k` such that Sage can build an `OA(k,n)`. INPUT: - - ``n`` (integer) + - ``n`` -- integer - - ``t`` -- (integer; default: 2) -- strength of the array + - ``t`` -- integer (default: 2); strength of the array EXAMPLES:: @@ -1079,22 +1072,22 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): INPUT: - - ``k``, ``n`` (integers) + - ``k``, ``n`` -- integers - - ``holes`` (list of integers) -- respective sizes of the holes to be found. + - ``holes`` -- list of integers respective sizes of the holes to be found - - ``resolvable`` (boolean) -- set to ``True`` if you want the design to be - resolvable. The classes of the resolvable design are obtained as the first - `n` blocks, then the next `n` blocks, etc ... Set to ``False`` by default. + - ``resolvable`` -- boolean (default: ``False``); set to ``True`` if you + want the design to be resolvable. The classes of the resolvable design + are obtained as the first `n` blocks, then the next `n` blocks, etc. - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist .. NOTE:: @@ -1243,11 +1236,11 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): raise EmptySetError("The total size of holes must be smaller or equal than the size of the ground set") if (max_hole == 1 and - resolvable and + resolvable and sum_of_holes != n): if existence: return False - raise EmptySetError("There is no resolvable incomplete OA({},{}) whose holes' sizes sum to {} equivalent to OA(k+1,n) if max_hole == 1 and resolvable: @@ -1373,11 +1366,11 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): # Equal holes [h,h,...] with h>1 through OA product construction # # (i.e. OA(k,n1)-x.OA(k,1) and OA(k,n2) ==> OA(k,n1.n2)-x.OA(k,n2) ) - elif (min_hole > 1 and - max_hole == min_hole and - n % min_hole == 0 and # h divides n + elif (min_hole > 1 and + max_hole == min_hole and + n % min_hole == 0 and # h divides n orthogonal_array(k,min_hole,existence=True) and # OA(k,h) - incomplete_orthogonal_array(k,n//min_hole,[1]*number_of_holes,existence=True)): # OA(k,n/h)-x.OA(k,1) + incomplete_orthogonal_array(k,n//min_hole,[1]*number_of_holes,existence=True)): # OA(k,n/h)-x.OA(k,1) if existence: return True h = min_hole @@ -1418,9 +1411,9 @@ def OA_find_disjoint_blocks(OA, k, n, x, - ``OA`` -- an orthogonal array - - ``k``, ``n``, ``x`` (integers) + - ``k``, ``n``, ``x`` -- integers - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1429,7 +1422,7 @@ def OA_find_disjoint_blocks(OA, k, n, x, `. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` .. SEEALSO:: @@ -1481,11 +1474,11 @@ def OA_relabel(OA, k, n, blocks=tuple(), matrix=None, symbol_list=None): INPUT: - ``OA`` -- an OA, or rather a list of blocks of length `k`, each - of which contains integers from `0` to `n-1`. + of which contains integers from `0` to `n-1` - - ``k``, ``n`` (integers) + - ``k``, ``n`` -- integers - - ``blocks`` (list of blocks) -- relabels the integers of the OA + - ``blocks`` -- list of blocks; relabels the integers of the OA from `[0..n-1]` into `[0..n-1]` in such a way that the `i` blocks from ``block`` are respectively relabeled as ``[n-i,...,n-i]``, ..., ``[n-1,...,n-1]``. Thus, the blocks from @@ -1503,7 +1496,7 @@ def OA_relabel(OA, k, n, blocks=tuple(), matrix=None, symbol_list=None): If set to ``None`` (default) no such relabelling is performed. - - ``symbol_list`` -- a list of the desired symbols for the + - ``symbol_list`` -- list of the desired symbols for the relabelled OA. If this is not ``None``, the same relabelling is done on all blocks such that the index of an element in symbol_list is its preimage in the relabelling map. @@ -1544,11 +1537,10 @@ def OA_relabel(OA, k, n, blocks=tuple(), matrix=None, symbol_list=None): Traceback (most recent call last): ... RuntimeError: Two block have the same coordinate for one of the k dimensions - """ if blocks: l = [] - for i,B in enumerate(zip(*blocks)): # the blocks are disjoint + for i, B in enumerate(zip(*blocks)): # the blocks are disjoint if len(B) != len(set(B)): raise RuntimeError("Two block have the same coordinate for one of the k dimensions") @@ -1571,8 +1563,8 @@ def OA_standard_label(OA): INPUT: - - ``OA`` -- a list of lists with symbols as entries that are not - necessarily integers. + - ``OA`` -- list of lists with symbols as entries that are not + necessarily integers EXAMPLES:: @@ -1584,7 +1576,6 @@ def OA_standard_label(OA): ....: ['b', 'b', 'b', 'b']] sage: OA_standard_label(C) [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0], [1, 1, 1, 1]] - """ symbol_list = sorted({x for l in OA for x in l}) mapping = {symbol: index for index, symbol in enumerate(symbol_list)} @@ -1631,10 +1622,9 @@ def OA_n_times_2_pow_c_from_matrix(k,c,G,A,Y,check=True): - ``Y`` -- a vector with entries in `GF(2^c)` - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. .. NOTE:: @@ -1752,7 +1742,7 @@ def OA_n_times_2_pow_c_from_matrix(k,c,G,A,Y,check=True): def OA_from_quasi_difference_matrix(M,G,add_col=True,fill_hole=True): r""" - Return an Orthogonal Array from a Quasi-Difference matrix + Return an Orthogonal Array from a Quasi-Difference matrix. **Difference Matrices** @@ -1816,10 +1806,10 @@ def OA_from_quasi_difference_matrix(M,G,add_col=True,fill_hole=True): - ``G`` -- a group - - ``add_col`` (boolean) -- whether to add a column to the final OA equal to - `(x_1,\dots,x_g,x_1,\dots,x_g,\dots)` where `G=\{x_1,\dots,x_g\}`. + - ``add_col`` -- boolean; whether to add a column to the final OA equal to + `(x_1,\dots,x_g,x_1,\dots,x_g,\dots)` where `G=\{x_1,\dots,x_g\}` - - ``fill_hole`` (boolean) -- whether to return the incomplete orthogonal + - ``fill_hole`` -- boolean; whether to return the incomplete orthogonal array, or complete it with the `OA(k,u)` (default). When ``fill_hole is None``, no block of the incomplete OA contains more than one value `\geq |G|`. @@ -1872,13 +1862,13 @@ def OA_from_quasi_difference_matrix(M,G,add_col=True,fill_hole=True): def OA_from_Vmt(m,t,V): r""" - Return an Orthogonal Array from a `V(m,t)` + Return an Orthogonal Array from a `V(m,t)`. INPUT: - - ``m``, ``t`` (integers) + - ``m``, ``t`` -- integers - - ``V`` -- the vector `V(m,t)`. + - ``V`` -- the vector `V(m,t)` .. SEEALSO:: @@ -1896,7 +1886,7 @@ def OA_from_Vmt(m,t,V): def QDM_from_Vmt(m,t,V): r""" - Return a QDM from a `V(m,t)` + Return a QDM from a `V(m,t)`. **Definition** @@ -1927,9 +1917,9 @@ def QDM_from_Vmt(m,t,V): INPUT: - - ``m``, ``t`` (integers) + - ``m``, ``t`` -- integers - - ``V`` -- the vector `V(m,t)`. + - ``V`` -- the vector `V(m,t)` .. SEEALSO:: @@ -1951,7 +1941,7 @@ def QDM_from_Vmt(m,t,V): for e in V: L.append(e*wm**i) for ii in range(m+2): - M.append(L[-ii:]+L[:-ii]) # cyclic shift + M.append(L[-ii:]+L[:-ii]) # cyclic shift M.append([0]*(m+2)) @@ -1960,7 +1950,7 @@ def QDM_from_Vmt(m,t,V): def OA_from_PBD(k,n,PBD, check=True): r""" - Return an `OA(k,n)` from a PBD + Return an `OA(k,n)` from a PBD. **Construction** @@ -1980,9 +1970,9 @@ def OA_from_PBD(k,n,PBD, check=True): INPUT: - - ``k``, ``n`` (integers) + - ``k``, ``n`` -- integers - - ``PBD`` -- a PBD on `0,...,n-1`. + - ``PBD`` -- a PBD on `0, \ldots, n-1` EXAMPLES: @@ -2049,9 +2039,9 @@ def OA_from_wider_OA(OA,k): INPUT: - - ``OA`` -- an orthogonal array. + - ``OA`` -- an orthogonal array - - ``k`` (integer) + - ``k`` -- integer EXAMPLES:: @@ -2059,12 +2049,12 @@ def OA_from_wider_OA(OA,k): sage: OA_from_wider_OA(designs.orthogonal_arrays.build(6,20,2),1)[:5] [(19,), (19,), (19,), (19,), (19,)] sage: _ = designs.orthogonal_arrays.build(5,46) # indirect doctest - """ if len(OA[0]) == k: return OA return [L[:k] for L in OA] + class OAMainFunctions: r""" Functions related to orthogonal arrays. @@ -2114,8 +2104,8 @@ class OAMainFunctions: 6 If you ask for an orthogonal array that does not exist, then you will - either obtain an ``EmptySetError`` (if it knows that such an orthogonal - array does not exist) or a :class:`NotImplementedError`:: + either obtain an :exc:`EmptySetError` (if it knows that such an orthogonal + array does not exist) or a :exc:`NotImplementedError`:: sage: designs.orthogonal_arrays.build(4,2) Traceback (most recent call last): @@ -2144,11 +2134,11 @@ def __init__(self,*args,**kwds): @staticmethod def explain_construction(k,n,t=2): r""" - Return a string describing how to builds an `OA(k,n)` + Return a string describing how to builds an `OA(k,n)`. INPUT: - - ``k``, ``n``, ``t`` (integers) -- parameters of the orthogonal array. + - ``k``, ``n``, ``t`` -- integers; parameters of the orthogonal array EXAMPLES:: @@ -2162,7 +2152,7 @@ def explain_construction(k,n,t=2): @staticmethod def build(k,n,t=2,resolvable=False): r""" - Return an `OA(k,n)` of strength `t` + Return an `OA(k,n)` of strength `t`. An orthogonal array of parameters `k,n,t` is a matrix with `k` columns filled with integers from `[n]` in such a way that for any @@ -2177,12 +2167,12 @@ def build(k,n,t=2,resolvable=False): INPUT: - - ``k``, ``n``, ``t`` (integers) -- parameters of the orthogonal array. + - ``k``, ``n``, ``t`` -- integers; parameters of the orthogonal array - - ``resolvable`` (boolean) -- set to ``True`` if you want the design to be - resolvable. The `n` classes of the resolvable design are obtained as the - first `n` blocks, then the next `n` blocks, etc ... Set to ``False`` by - default. + - ``resolvable`` -- boolean (default: ``False``); set to ``True`` if + you want the design to be resolvable. The `n` classes of the + resolvable design are obtained as the first `n` blocks, then the next + `n` blocks, etc. EXAMPLES:: @@ -2197,18 +2187,17 @@ def build(k,n,t=2,resolvable=False): [1, 0, 2], [2, 2, 0]] sage: OA_7_50 = designs.orthogonal_arrays.build(7,50) # indirect doctest - """ return orthogonal_array(k,n,t,resolvable=resolvable) @staticmethod def exists(k,n,t=2): r""" - Return the existence status of an `OA(k,n)` + Return the existence status of an `OA(k,n)`. INPUT: - - ``k``, ``n``, ``t`` (integers) -- parameters of the orthogonal array. + - ``k``, ``n``, ``t`` -- integers; parameters of the orthogonal array .. WARNING:: @@ -2237,7 +2226,7 @@ def is_available(k,n,t=2): INPUT: - - ``k``, ``n``, ``t`` (integers) -- parameters of the orthogonal array. + - ``k``, ``n``, ``t`` -- integers; parameters of the orthogonal array .. SEEALSO:: diff --git a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py index b828caaaadf..937076ebb07 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py +++ b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py @@ -23,10 +23,10 @@ :func:`~sage.combinat.designs.orthogonal_arrays_build_recursive.construction_3_6` | Return a `OA(k,nm+i)`. :func:`~sage.combinat.designs.orthogonal_arrays_build_recursive.construction_q_x` | Return an `OA(k,(q-1)*(q-x)+x+2)` using the `q-x` construction. :func:`OA_and_oval` | Return a `OA(q+1,q)` whose blocks contains `\leq 2` zeroes in the last `q` columns. - :func:`thwart_lemma_3_5` | Returns an `OA(k,nm+a+b+c+d)`. - :func:`thwart_lemma_4_1` | Returns an `OA(k,nm+4(n-2))`. - :func:`three_factor_product` | Returns an `OA(k+1,n_1n_2n_3)`. - :func:`brouwer_separable_design` | Returns a `OA(k,t(q^2+q+1)+x)` using Brouwer's result on separable designs. + :func:`thwart_lemma_3_5` | Return an `OA(k,nm+a+b+c+d)`. + :func:`thwart_lemma_4_1` | Return an `OA(k,nm+4(n-2))`. + :func:`three_factor_product` | Return an `OA(k+1,n_1n_2n_3)`. + :func:`brouwer_separable_design` | Return a `OA(k,t(q^2+q+1)+x)` using Brouwer's result on separable designs. Functions --------- @@ -49,11 +49,11 @@ def construction_3_3(k,n,m,i,explain_construction=False): INPUT: - - ``k``, ``n``, ``m``, ``i`` (integers) such that the following designs are - available: `OA(k,n)`, `OA(k,m)`, `OA(k,m+1)`, `OA(k,r)`. + - ``k``, ``n``, ``m``, ``i`` -- integers such that the following designs are + available: `OA(k,n)`, `OA(k,m)`, `OA(k,m+1)`, `OA(k,r)` - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -96,6 +96,7 @@ def construction_3_3(k,n,m,i,explain_construction=False): assert is_orthogonal_array(OA,k,n*m+i) return OA + def construction_3_4(k,n,m,r,s,explain_construction=False): r""" Return a `OA(k,nm+rs)`. @@ -123,8 +124,8 @@ def construction_3_4(k,n,m,r,s,explain_construction=False): `OA(k,m+1)`, `OA(k,m+2)`, `OA(k,s)`. Additionally, it requires either a `OA(k,m+r)` or a `OA(k,m+r+1)`. - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -178,6 +179,7 @@ def construction_3_4(k,n,m,r,s,explain_construction=False): OA = wilson_construction(OA,k,n,m,[1]*r+[s],check=False) return OA + def construction_3_5(k,n,m,r,s,t,explain_construction=False): r""" Return an `OA(k,nm+r+s+t)`. @@ -190,13 +192,13 @@ def construction_3_5(k,n,m,r,s,t,explain_construction=False): INPUT: - - ``k``, ``n``, ``m`` (integers) + - ``k``, ``n``, ``m`` -- integers - - ``r``, ``s``, ``t`` (integers) -- sizes of the three truncated groups, - such that `r\leq s` and `(q-r-1)(q-s) \geq (q-s-1)*(q-r)`. + - ``r``, ``s``, ``t`` -- integers; sizes of the three truncated groups, + such that `r\leq s` and `(q-r-1)(q-s) \geq (q-s-1)*(q-r)` - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction The following designs must be available : `OA(k,n)`, `OA(k,r)`, `OA(k,s)`, `OA(k,t)`, `OA(k,m+1)`, `OA(k,m+2)`, `OA(k,m+3)`. @@ -220,7 +222,6 @@ def construction_3_5(k,n,m,r,s,t,explain_construction=False): Concerning eight mutually orthogonal latin squares, Vol. 15, n.3, pp. 255-261, Journal of Combinatorial Designs, 2007 - """ from .orthogonal_arrays import wilson_construction, OA_relabel assert r <= s @@ -273,9 +274,10 @@ def construction_3_5(k,n,m,r,s,t,explain_construction=False): OA = wilson_construction(OA,k,q,m,[r,s,t], check=False) return OA + def construction_3_6(k,n,m,i,explain_construction=False): r""" - Return a `OA(k,nm+i)` + Return a `OA(k,nm+i)`. This is Wilson's construction with `r` columns of order `1`, in which each block intersects at most two truncated columns. Such a design exists when @@ -283,12 +285,12 @@ def construction_3_6(k,n,m,i,explain_construction=False): INPUT: - - ``k``, ``n``, ``m``, ``i`` (integers) -- `n` must be a prime power. The + - ``k``, ``n``, ``m``, ``i`` -- integers; `n` must be a prime power. The following designs must be available: `OA(k+r,q)`, `OA(k,m)`, `OA(k,m+1)`, - `OA(k,m+2)`. + `OA(k,m+2)` - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction This is construction 3.6 from [AC07]_. @@ -329,6 +331,7 @@ def construction_3_6(k,n,m,i,explain_construction=False): assert is_orthogonal_array(OA,k,n*m+i) return OA + def OA_and_oval(q, *, solver=None, integrality_tolerance=1e-3): r""" Return a `OA(q+1,q)` whose blocks contains `\leq 2` zeroes in the last `q` @@ -346,7 +349,7 @@ def OA_and_oval(q, *, solver=None, integrality_tolerance=1e-3): - ``q`` -- a prime power - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -355,7 +358,7 @@ def OA_and_oval(q, *, solver=None, integrality_tolerance=1e-3): `. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` .. NOTE:: @@ -366,7 +369,6 @@ def OA_and_oval(q, *, solver=None, integrality_tolerance=1e-3): sage: from sage.combinat.designs.orthogonal_arrays_build_recursive import OA_and_oval sage: _ = OA_and_oval - """ from sage.arith.misc import is_prime_power from sage.combinat.designs.block_design import projective_plane @@ -482,13 +484,12 @@ def construction_q_x(k, q, x, check=True, explain_construction=False): - `OA(k,q)-q.OA(k,1)` - `OA(k,x+2)` - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -536,9 +537,9 @@ def construction_q_x(k, q, x, check=True, explain_construction=False): # Add rows, extended with p1 and p2 p1 = q**2 - p2 = p1+1 - TD.extend([[ii*q+i for ii in range(q)]+[p1] for i in range(1,q)]) - TD.append( [ii*q for ii in range(q)]+[p1,p2]) + p2 = p1 + 1 + TD.extend([ii*q + i for ii in range(q)] + [p1] for i in range(1, q)) + TD.append([ii*q for ii in range(q)] + [p1, p2]) # Add Columns. We do not add some columns which would have size 1 after we # delete points. @@ -579,7 +580,7 @@ def construction_q_x(k, q, x, check=True, explain_construction=False): def thwart_lemma_3_5(k,n,m,a,b,c,d=0,complement=False,explain_construction=False): r""" - Returns an `OA(k,nm+a+b+c+d)` + Return an `OA(k,nm+a+b+c+d)`. *(When `d=0`)* @@ -637,14 +638,14 @@ def thwart_lemma_3_5(k,n,m,a,b,c,d=0,complement=False,explain_construction=False INPUT: - ``k``, ``n``, ``m``, ``a``, ``b``, ``c``, ``d`` -- integers which must - satisfy the constraints above. In particular, `a+b+c\leq n+1` must hold. + satisfy the constraints above. In particular, `a+b+c\leq n+1` must hold By default, `d=0`. - - ``complement`` (boolean) -- whether to complement the sets, i.e. follow - the `n-a,n-b,n-c` variant described above. + - ``complement`` -- boolean; whether to complement the sets, i.e. follow + the `n-a,n-b,n-c` variant described above - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -755,9 +756,10 @@ def thwart_lemma_3_5(k,n,m,a,b,c,d=0,complement=False,explain_construction=False return wilson_construction(OA,k,n,m,sizes, check=False) + def thwart_lemma_4_1(k,n,m,explain_construction=False): r""" - Returns an `OA(k,nm+4(n-2))`. + Return an `OA(k,nm+4(n-2))`. Implements Lemma 4.1 from [Thwarts]_. @@ -777,10 +779,10 @@ def thwart_lemma_4_1(k,n,m,explain_construction=False): INPUT: - - ``k``, ``n``, ``m`` (integers) + - ``k``, ``n``, ``m`` -- integers - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -883,9 +885,10 @@ def thwart_lemma_4_1(k,n,m,explain_construction=False): return wilson_construction(OA,k,n,m,[n-2,]*4,check=False) + def three_factor_product(k,n1,n2,n3,check=False,explain_construction=False): r""" - Returns an `OA(k+1,n_1n_2n_3)` + Return an `OA(k+1,n_1n_2n_3)`. The three factor product construction from [DukesLing14]_ does the following: @@ -949,14 +952,14 @@ def three_factor_product(k,n1,n2,n3,check=False,explain_construction=False): INPUT: - - ``k``, ``n1``, ``n2``, ``n3`` (integers) + - ``k``, ``n1``, ``n2``, ``n3`` -- integers - - ``check`` -- (boolean) Whether to check that everything is going smoothly + - ``check`` -- boolean; whether to check that everything is going smoothly while the design is being built. It is disabled by default, as the constructor of orthogonal arrays checks the final design anyway. - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -1020,11 +1023,11 @@ def assert_c_partition(classs,k,n,c): def product_with_parallel_classes(OA1,k,g1,g2,g1_parall,parall,check=True): r""" - Returns the product of two OA while keeping track of parallel classes + Return the product of two OA while keeping track of parallel classes. INPUT: - - ``OA1`` (an `OA(k,g_1)` + - ``OA1`` -- (an `OA(k,g_1)` - ``k``, ``g1``, ``g2`` -- integers @@ -1040,7 +1043,7 @@ def product_with_parallel_classes(OA1,k,g1,g2,g1_parall,parall,check=True): Two lists of classes ``g1_parall`` and ``parallel`` which are respectively `g_1`-parallel and parallel classes such that ``g1_parall+parallel`` is an - `OA(k,g1*g2)``. + ``OA(k,g1*g2)``. """ if check: for classs in g1_parall: @@ -1148,6 +1151,7 @@ def product_with_parallel_classes(OA1,k,g1,g2,g1_parall,parall,check=True): return OA + def _reorder_matrix(matrix): r""" Return a matrix which is obtained from ``matrix`` by permutation of each row @@ -1187,7 +1191,7 @@ def _reorder_matrix(matrix): g.add_edges((x,N+i) for i,S in enumerate(matrix) for x in S) matrix = [] for _ in range(k): - matching = g.matching(algorithm="LP") + matching = g.matching(algorithm='LP') col = [0]*N for x,i,_ in matching: if i < N: @@ -1198,9 +1202,10 @@ def _reorder_matrix(matrix): return list(zip(*matrix)) + def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construction=False): r""" - Returns a `OA(k,t(q^2+q+1)+x)` using Brouwer's result on separable designs. + Return a `OA(k,t(q^2+q+1)+x)` using Brouwer's result on separable designs. This method is an implementation of Brouwer's construction presented in [Brouwer80]_. It consists in a systematic application of the usual @@ -1323,16 +1328,16 @@ def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construct INPUT: - - ``k``, ``t``, ``q``, ``x`` (integers) + - ``k``, ``t``, ``q``, ``x`` -- integers - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. Set to ``False`` by default. + - ``check`` -- boolean (default: ``False``); whether to check that output + is correct before returning it - - ``verbose`` (boolean) -- whether to print some information on the - construction and parameters being used. + - ``verbose`` -- boolean; whether to print some information on the + construction and parameters being used - - ``explain_construction`` (boolean) -- return a string describing - the construction. + - ``explain_construction`` -- boolean; return a string describing + the construction .. SEEALSO:: @@ -1448,9 +1453,9 @@ def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construct else: partition_of_blocks_of_size_t[plane-t].append([relabel[xx] for xx in B if xx % m < t]) - ############################################################################### + ########################################################################### # Separable design built ! - #------------------------- + # ------------------------ # # At this point we have a PBD on t*(q**2+q+1) points. Its blocks are # split into: @@ -1461,7 +1466,7 @@ def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construct # - blocks_of_size_q_plus_t : contains all t*(q**2+q+1)blocks of size q+t, # covering the same number of points: it is a # symmetric design. - ############################################################################### + ########################################################################### ############################################## # Part 2: Build an OA on t(q^2+q+1)+x points # diff --git a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx index 5690b681de1..f7f3502548b 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +++ b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx @@ -55,7 +55,7 @@ from sage.arith.misc import prime_powers @cached_function def find_recursive_construction(k, n): r""" - Find a recursive construction of an `OA(k,n)` (calls all others ``find_*`` functions) + Find a recursive construction of an `OA(k,n)` (calls all others ``find_*`` functions). This determines whether an `OA(k,n)` can be built through the following constructions: @@ -145,7 +145,7 @@ cpdef find_product_decomposition(int k,int n): sage: _ = f(*args) """ cdef int n1,n2 - for n1 in range(2,n): + for n1 in range(2, n): n2 = n/n1 # n2 is decreasing along the loop if n2 < n1: break @@ -194,15 +194,13 @@ cpdef find_wilson_decomposition_with_one_truncated_group(int k,int n): if u == 0 or (u>1 and k >= u+2): continue - m = n/r + m = n // r # If there exists a TD(k,m) then k= m+2: break - if (is_available(k ,m ) and - is_available(k ,m+1) and - is_available(k+1,r ) and - is_available(k ,u )): + if (is_available(k, m) and is_available(k, m + 1) and + is_available(k + 1, r) and is_available(k, u)): from sage.combinat.designs.orthogonal_arrays import wilson_construction return wilson_construction, (None,k,r,m,(u,),False) @@ -272,7 +270,7 @@ cpdef find_wilson_decomposition_with_two_truncated_groups(int k,int n): cpdef find_construction_3_3(int k,int n): r""" - Find a decomposition for construction 3.3 from [AC07]_ + Find a decomposition for construction 3.3 from [AC07]_. INPUT: @@ -294,24 +292,22 @@ cpdef find_construction_3_3(int k,int n): sage: find_construction_3_3(12,11) """ cdef int mm,nn,i - for mm in range(k-1,n/2+1): - if (not is_available(k ,mm ) or - not is_available(k ,mm+1)): + for mm in range(k-1, n//2+1): + if not(is_available(k, mm) and is_available(k, mm + 1)): continue - for nn in range(2,n/mm+1): + for nn in range(2, n//mm+1): i = n-nn*mm - if i<=0: + if i <= 0: continue - if (is_available(k+i, nn ) and - is_available(k , mm+i)): + if is_available(k + i, nn) and is_available(k, mm + i): from sage.combinat.designs.orthogonal_arrays_build_recursive import construction_3_3 - return construction_3_3, (k,nn,mm,i) + return construction_3_3, (k, nn, mm, i) -cpdef find_construction_3_4(int k,int n): +cpdef find_construction_3_4(int k, int n): r""" - Find a decomposition for construction 3.4 from [AC07]_ + Find a decomposition for construction 3.4 from [AC07]_. INPUT: @@ -339,22 +335,22 @@ cpdef find_construction_3_4(int k,int n): not is_available(k,mm+2)): continue - for nn in range(2,n/mm+1): + for nn in range(2, n//mm+1): i = n-nn*mm if i<=0: continue for s in range(1,min(i,nn)): r = i-s - if (is_available(k+r+1,nn) and - is_available(k , s) and - (is_available(k,mm+r) or is_available(k,mm+r+1))): + if (is_available(k + r + 1, nn) and + is_available(k, s) and + (is_available(k, mm + r) or is_available(k, mm + r + 1))): from sage.combinat.designs.orthogonal_arrays_build_recursive import construction_3_4 - return construction_3_4, (k,nn,mm,r,s) + return construction_3_4, (k, nn, mm, r, s) -cpdef find_construction_3_5(int k,int n): +cpdef find_construction_3_5(int k, int n): r""" - Find a decomposition for construction 3.5 from [AC07]_ + Find a decomposition for construction 3.5 from [AC07]_. INPUT: @@ -376,14 +372,14 @@ cpdef find_construction_3_5(int k,int n): sage: find_construction_3_5(9,24) """ cdef int mm,i,nn,r,s,t - for mm in range(2,n/2+1): + for mm in range(2, n//2+1): if (mm+3 >= n or not is_available(k,mm+1) or not is_available(k,mm+2) or not is_available(k,mm+3)): continue - for nn in range(2,n/mm+1): + for nn in range(2, n//mm+1): i = n-nn*mm if i<=0: continue @@ -404,7 +400,7 @@ cpdef find_construction_3_5(int k,int n): cpdef find_construction_3_6(int k,int n): r""" - Find a decomposition for construction 3.6 from [AC07]_ + Find a decomposition for construction 3.6 from [AC07]_. INPUT: @@ -433,7 +429,7 @@ cpdef find_construction_3_6(int k,int n): not is_available(k,mm+2)): continue - for nn in range(2,n/mm+1): + for nn in range(2, n//mm+1): i = n-nn*mm if i<=0: continue @@ -668,7 +664,7 @@ cpdef find_thwart_lemma_4_1(int k,int n): cpdef find_three_factor_product(int k,int n): r""" - Find `n_1n_2n_3=n` to obtain an `OA(k,n)` by the three-factor product from [DukesLing14]_ + Find `n_1n_2n_3=n` to obtain an `OA(k,n)` by the three-factor product from [DukesLing14]_. INPUT: @@ -818,11 +814,11 @@ def int_as_sum(int value, list S, int k_max): INPUT: - - ``value`` (integer) + - ``value`` -- integer - - ``S`` -- a list of integers + - ``S`` -- list of integers - - ``k_max`` (integer) + - ``k_max`` -- integer EXAMPLES:: @@ -913,7 +909,7 @@ cpdef find_brouwer_van_rees_with_one_truncated_column(int k,int n): cdef tuple values # We write n=rm+remainder - for m in range(2,n//2): + for m in range(2, n//2): if not is_available(k,m): continue @@ -935,7 +931,7 @@ cpdef find_brouwer_van_rees_with_one_truncated_column(int k,int n): continue max_multiplier = max(available_multipliers) - for r in range(2,n//m+1): + for r in range(2, n//m+1): remainder = n-r*m if (remainder > r*max_multiplier or not is_available(k+1,r) or diff --git a/src/sage/combinat/designs/resolvable_bibd.py b/src/sage/combinat/designs/resolvable_bibd.py index 55afd031183..ccc11176d54 100644 --- a/src/sage/combinat/designs/resolvable_bibd.py +++ b/src/sage/combinat/designs/resolvable_bibd.py @@ -65,16 +65,16 @@ def resolvable_balanced_incomplete_block_design(v,k,existence=False): INPUT: - - ``v``, ``k`` (integers) + - ``v``, ``k`` -- integers - - ``existence`` (boolean) -- instead of building the design, return: + - ``existence`` -- boolean; instead of building the design, return: - ``True`` -- meaning that Sage knows how to build the design - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + design, but that the design may exist (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist .. SEEALSO:: @@ -150,10 +150,10 @@ def kirkman_triple_system(v,existence=False): INPUT: - - `n` (integer) + - ``n`` -- integer - - ``existence`` (boolean; ``False`` by default) -- whether to build the - `KTS(n)` or only answer whether it exists. + - ``existence`` -- boolean (default: ``False``); whether to build the + `KTS(n)` or only answer whether it exists .. SEEALSO:: @@ -311,14 +311,14 @@ def kirkman_triple_system(v,existence=False): b.remove(8) X = sum(X, []) + [8] gdd4.relabel({v:i for i,v in enumerate(X)}) - gdd4 = gdd4.is_resolvable(True)[1] # the relabeled classes + gdd4 = gdd4.is_resolvable(True)[1] # the relabeled classes X = [B for B in gdd7 if 14 in B] for b in X: b.remove(14) X = sum(X, []) + [14] gdd7.relabel({v:i for i,v in enumerate(X)}) - gdd7 = gdd7.is_resolvable(True)[1] # the relabeled classes + gdd7 = gdd7.is_resolvable(True)[1] # the relabeled classes # The first parallel class contains 01(n'-1), the second contains # 23(n'-1), etc.. @@ -374,10 +374,10 @@ def v_4_1_rbibd(v,existence=False): INPUT: - - `n` (integer) + - ``n`` -- integer - - ``existence`` (boolean; ``False`` by default) -- whether to build the - design or only answer whether it exists. + - ``existence`` -- boolean (default: ``False``); whether to build the + design or only answer whether it exists .. SEEALSO:: @@ -441,7 +441,7 @@ def v_4_1_rbibd(v,existence=False): def PBD_4_7(v,check=True, existence=False): r""" - Return a `(v,\{4,7\})`-PBD + Return a `(v,\{4,7\})`-PBD. For all `v` such that `n\equiv 1\pmod{3}` and `n\neq 10,19, 31` there exists a `(v,\{4,7\})`-PBD. This is proved in Proposition IX.4.5 from [BJL99]_, @@ -573,7 +573,7 @@ def PBD_4_7(v,check=True, existence=False): # On these groups a (15+7,{4,7})-PBD is pasted, in such a way that the 7 # new points are a set of the final PBD PBD22 = PBD_4_7(15+7) - S = next(SS for SS in PBD22 if len(SS) == 7) # a set of size 7 + S = next(SS for SS in PBD22 if len(SS) == 7) # a set of size 7 PBD22.relabel({v:i for i,v in enumerate([i for i in range(15+7) if i not in S] + S)}) for B in PBD22: @@ -704,12 +704,11 @@ def PBD_4_7_from_Y(gdd,check=True): INPUT: - - ``gdd`` -- a `(v,\{4,5,7\},Y)`-GDD where `Y=\NN-\{3,6,10\}`. + - ``gdd`` -- a `(v,\{4,5,7\},Y)`-GDD where `Y=\NN-\{3,6,10\}` - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES:: @@ -742,19 +741,19 @@ def PBD_4_7_from_Y(gdd,check=True): raise RuntimeError("A group has size {} but I do not know how to " "build a ({},[4,7])-PBD".format(gs,3*gs+1)) - GDD = {} # the GDD we will need + GDD = {} # the GDD we will need if 4 in block_sizes: - #GDD[4] = GDD_from_BIBD(3*4,4) + # GDD[4] = GDD_from_BIBD(3*4,4) GDD[4] = group_divisible_design(3*4,K=[4],G=[3]) if 5 in block_sizes: - #GDD[5] = GDD_from_BIBD(3*5,4) + # GDD[5] = GDD_from_BIBD(3*5,4) GDD[5] = group_divisible_design(3*5,K=[4],G=[3]) if 7 in block_sizes: # It is obtained from a PBD_4_7(22) by removing a point only contained # in sets of size 4 GDD[7] = PBD_4_7(22) x = set(range(22)).difference(*[S for S in GDD[7] if len(S) != 4]).pop() - relabel = sum((S for S in GDD[7] if x in S),[]) # the groups must be 012,345,... + relabel = sum((S for S in GDD[7] if x in S),[]) # the groups must be 012,345,... relabel = [xx for xx in relabel if xx != x]+[x] GDD[7].relabel({v:i for i,v in enumerate(relabel)}) GDD[7] = [S for S in GDD[7] if 21 not in S] diff --git a/src/sage/combinat/designs/steiner_quadruple_systems.py b/src/sage/combinat/designs/steiner_quadruple_systems.py index 7c7819c4138..9576ae5f5aa 100644 --- a/src/sage/combinat/designs/steiner_quadruple_systems.py +++ b/src/sage/combinat/designs/steiner_quadruple_systems.py @@ -64,13 +64,15 @@ from sage.combinat.designs.incidence_structures import IncidenceStructure # Construction 1 + + def two_n(B): r""" Return a Steiner Quadruple System on `2n` points. INPUT: - - ``B`` -- A Steiner Quadruple System on `n` points. + - ``B`` -- a Steiner Quadruple System on `n` points EXAMPLES:: @@ -80,7 +82,6 @@ def two_n(B): ....: sqs = designs.steiner_quadruple_system(n) ....: if not two_n(sqs).is_t_design(3,2*n,4,1): ....: print("Something is wrong !") - """ n = B.num_points() Y = [] @@ -101,13 +102,15 @@ def two_n(B): return IncidenceStructure(2*n,Y,check=False,copy=False) # Construction 2 + + def three_n_minus_two(B): """ Return a Steiner Quadruple System on `3n-2` points. INPUT: - - ``B`` -- A Steiner Quadruple System on `n` points. + - ``B`` -- a Steiner Quadruple System on `n` points EXAMPLES:: @@ -156,13 +159,15 @@ def three_n_minus_two(B): return IncidenceStructure(3*n-2,Y,check=False,copy=False) # Construction 3 + + def three_n_minus_eight(B): r""" Return a Steiner Quadruple System on `3n-8` points. INPUT: - - ``B`` -- A Steiner Quadruple System on `n` points. + - ``B`` -- a Steiner Quadruple System on `n` points EXAMPLES:: @@ -172,7 +177,6 @@ def three_n_minus_eight(B): ....: sqs = designs.steiner_quadruple_system(n) ....: if not three_n_minus_eight(sqs).is_t_design(3,3*n-8,4,1): ....: print("Something is wrong !") - """ n = B.num_points() @@ -216,14 +220,16 @@ def three_n_minus_eight(B): return IncidenceStructure(3*n-8,Y,check=False,copy=False) # Construction 4 + + def three_n_minus_four(B): r""" Return a Steiner Quadruple System on `3n-4` points. INPUT: - - ``B`` -- A Steiner Quadruple System on `n` points where `n\equiv - 10\pmod{12}`. + - ``B`` -- a Steiner Quadruple System on `n` points where `n\equiv + 10\pmod{12}` EXAMPLES:: @@ -233,7 +239,6 @@ def three_n_minus_four(B): ....: sqs = designs.steiner_quadruple_system(n) ....: if not three_n_minus_four(sqs).is_t_design(3,3*n-4,4,1): ....: print("Something is wrong !") - """ n = B.num_points() @@ -281,13 +286,15 @@ def three_n_minus_four(B): return IncidenceStructure(3*n-4,Y,check=False,copy=False) # Construction 5 + + def four_n_minus_six(B): """ Return a Steiner Quadruple System on `4n-6` points. INPUT: - - ``B`` -- A Steiner Quadruple System on `n` points. + - ``B`` -- a Steiner Quadruple System on `n` points EXAMPLES:: @@ -297,7 +304,6 @@ def four_n_minus_six(B): ....: sqs = designs.steiner_quadruple_system(n) ....: if not four_n_minus_six(sqs).is_t_design(3,4*n-6,4,1): ....: print("Something is wrong !") - """ n = B.num_points() f = n-2 @@ -353,13 +359,15 @@ def four_n_minus_six(B): return IncidenceStructure(4*n-6,Y,check=False,copy=False) # Construction 6 + + def twelve_n_minus_ten(B): """ Return a Steiner Quadruple System on `12n-6` points. INPUT: - - ``B`` -- A Steiner Quadruple System on `n` points. + - ``B`` -- a Steiner Quadruple System on `n` points EXAMPLES:: @@ -369,7 +377,6 @@ def twelve_n_minus_ten(B): ....: sqs = designs.steiner_quadruple_system(n) ....: if not twelve_n_minus_ten(sqs).is_t_design(3,12*n-10,4,1): ....: print("Something is wrong !") - """ n = B.num_points() B14 = steiner_quadruple_system(14) @@ -451,13 +458,14 @@ def twelve_n_minus_ten(B): Y.append([r(x,a), r(y,aa), r(z,aaa), r(t,aaaa)]) return IncidenceStructure(12*n-10,Y,check=False,copy=False) + def relabel_system(B): r""" - Relabels the set so that `\{n-4, n-3, n-2, n-1\}` is in `B`. + Relabel the set so that `\{n-4, n-3, n-2, n-1\}` is in `B`. INPUT: - - ``B`` -- a list of 4-uples on `0,...,n-1`. + - ``B`` -- list of 4-uples on `0,...,n-1` EXAMPLES:: @@ -487,9 +495,10 @@ def get_label(x): B = [[get_label(_) for _ in s] for s in B] return IncidenceStructure(n,B) + def P(alpha, m): r""" - Return the collection of pairs `P_{\alpha}(m)` + Return the collection of pairs `P_{\alpha}(m)`. For more information on this system, see [Han1960]_. @@ -530,6 +539,7 @@ def P(alpha, m): pairs += [(y,m+y)] return pairs + def _missing_pair(n,l): r""" Return the smallest `(x,x+1)` that is not contained in `l`. @@ -552,7 +562,7 @@ def _missing_pair(n,l): def barP(eps, m): r""" - Return the collection of pairs `\overline P_{\alpha}(m)` + Return the collection of pairs `\overline P_{\alpha}(m)`. For more information on this system, see [Han1960]_. @@ -564,10 +574,11 @@ def barP(eps, m): """ return barP_system(m)[eps] + @cached_function def barP_system(m): r""" - Return the 1-factorization of `K_{2m}` `\overline P(m)` + Return the 1-factorization of `K_{2m}` `\overline P(m)`. For more information on this system, see [Han1960]_. @@ -676,6 +687,7 @@ def barP_system(m): return pairs + @cached_function def steiner_quadruple_system(n, check=False): r""" @@ -683,10 +695,10 @@ def steiner_quadruple_system(n, check=False): INPUT: - - ``n`` -- an integer such that `n\equiv 2,4\pmod 6` + - ``n`` -- integer such that `n\equiv 2,4\pmod 6` - - ``check`` (boolean) -- whether to check that the system is a Steiner - Quadruple System before returning it (`False` by default) + - ``check`` -- boolean (default: ``False``); whether to check that the + system is a Steiner Quadruple System before returning it EXAMPLES:: @@ -743,6 +755,7 @@ def steiner_quadruple_system(n, check=False): return sqs + def _SQS14(): r""" Return a Steiner Quadruple System on 14 points. @@ -776,6 +789,7 @@ def _SQS14(): [6, 8, 10, 12], [6, 9, 11, 12], [7, 8, 10, 13], [7, 8, 11, 12], [7, 9, 10, 12], [8, 9, 10, 11]] + def _SQS38(): r""" Return a Steiner Quadruple System on 14 points. diff --git a/src/sage/combinat/designs/subhypergraph_search.pyx b/src/sage/combinat/designs/subhypergraph_search.pyx index 968159b9012..8de300efe2a 100644 --- a/src/sage/combinat/designs/subhypergraph_search.pyx +++ b/src/sage/combinat/designs/subhypergraph_search.pyx @@ -31,20 +31,20 @@ over `|V(H_1)|` points. In particular, two sets of distinct cardinalities require the same memory space. A hypergraph is a C struct with the following fields: -* ``n,m`` (``int``) -- number of points and edges. +* ``n``, ``m`` -- (``int``) number of points and edges -* ``limbs`` (``int``) -- number of 64-bits blocks per set. +* ``limbs`` -- (``int``) number of 64-bits blocks per set -* ``set_space`` (``uint64_t *``) -- address of the memory used to store the - sets. +* ``set_space`` -- (``uint64_t *``) address of the memory used to store the + sets -* ``sets`` (``uint64_t **``) -- ``sets[i]`` points toward the ``limbs`` +* ``sets`` -- (``uint64_t **``) ``sets[i]`` points toward the ``limbs`` blocks encoding set `i`. Note also that ``sets[i][limbs]`` is equal to the cardinality of ``set[i]``, so that ``sets`` has length ``m*(limbs+1)*sizeof(uint64_t)``. -* ``names`` (``int *``) -- associates an integer 'name' to each of the ``n`` - points. +* ``names`` -- (``int *``) associates an integer 'name' to each of the ``n`` + points The operations used on this data structure are: @@ -133,7 +133,7 @@ cdef inline int bs_get(uint64_t * bitset, int index) noexcept: r""" Return a bit of a bitset """ - return (bitset[index/64]>>(index%64))&1 + return (bitset[index//64]>>(index%64))&1 cdef inline void bs_set(uint64_t * bitset, int index, int bit) noexcept: r""" @@ -142,8 +142,8 @@ cdef inline void bs_set(uint64_t * bitset, int index, int bit) noexcept: "bit" *MUST* be equal to either 0 or to 1. The code does not involve any "if". """ - bitset[index/64] &= ~(( 1)< bit)< 1)< bit)< sig_malloc(sizeof(int)*n) h.sets = sig_malloc(h.m*sizeof(uint64_t *)) h.set_space = sig_calloc(h.m*(h.limbs+1),sizeof(uint64_t)) @@ -249,7 +249,7 @@ cdef induced_hypergraph(hypergraph * h, int n, hypergraph * tmp): cdef void trace_hypergraph64(hypergraph * h, int n, hypergraph * tmp) noexcept: r""" - Stores in `tmp` the trace of the sets on {0,...,n-1} in h1. + Store in `tmp` the trace of the sets on `\{0, \ldots, n-1\}` in h1. Note that the size of the sets are kept as they are, i.e. the size of a set stored in tmp is what it was in h. This is useful information we use to cut @@ -426,7 +426,7 @@ cdef class SubHypergraphSearch: def relabel_heuristic(self): r""" - Relabels `H_2` in order to make the algorithm faster. + Relabel `H_2` in order to make the algorithm faster. Objective: we try to pick an ordering `p_1,...,p_k` of the points of `H_2` that maximizes the number of sets involving the first points in @@ -474,7 +474,7 @@ cdef class SubHypergraphSearch: def __iter__(self): r""" - Iterates over all copies of h2 in h1. + Iterate over all copies of h2 in h1. EXAMPLES: diff --git a/src/sage/combinat/designs/twographs.py b/src/sage/combinat/designs/twographs.py index 2bbd4d8d308..131916b89c9 100644 --- a/src/sage/combinat/designs/twographs.py +++ b/src/sage/combinat/designs/twographs.py @@ -36,9 +36,9 @@ :widths: 30, 70 :delim: | - :meth:`~TwoGraph.is_regular_twograph` | tests if ``self`` is a regular two-graph, i.e. a 2-design - :meth:`~TwoGraph.complement` | returns the complement of ``self`` - :meth:`~TwoGraph.descendant` | returns the descendant graph at `w` + :meth:`~TwoGraph.is_regular_twograph` | Test if ``self`` is a regular two-graph, i.e. a 2-design + :meth:`~TwoGraph.complement` | Return the complement of ``self`` + :meth:`~TwoGraph.descendant` | Return the descendant graph at `w` This module's functions are the following: @@ -47,9 +47,9 @@ :widths: 30, 70 :delim: | - :func:`~taylor_twograph` | constructs Taylor's two-graph for `U_3(q)` - :func:`~is_twograph` | checks that the incidence system is a two-graph - :func:`~twograph_descendant` | returns the descendant graph w.r.t. a given vertex of the two-graph of a given graph + :func:`~taylor_twograph` | Construct Taylor's two-graph for `U_3(q)` + :func:`~is_twograph` | Check that the incidence system is a two-graph + :func:`~twograph_descendant` | Return the descendant graph w.r.t. a given vertex of the two-graph of a given graph Methods --------- @@ -68,12 +68,11 @@ class TwoGraph(IncidenceStructure): of size four contains an even number of elements of `T`. For more information, see the documentation of the :mod:`~sage.combinat.designs.twographs` module. - """ def __init__(self, points=None, blocks=None, incidence_matrix=None, - name=None, check=False, copy=True): + name=None, check=False, copy=True): r""" - Constructor of the class + Constructor of the class. TESTS:: @@ -103,8 +102,8 @@ def is_regular_twograph(self, alpha=False): INPUT: - - ``alpha`` -- (default: ``False``) return the value of - ``alpha``, if possible. + - ``alpha`` -- boolean (default: ``False``); return the value of + ``alpha``, if possible EXAMPLES:: @@ -127,7 +126,7 @@ def is_regular_twograph(self, alpha=False): def descendant(self, v): """ - The descendant :class:`graph ` at ``v`` + The descendant :class:`graph ` at ``v``. The :mod:`switching class of graphs ` corresponding to ``self`` contains a graph ``D`` with ``v`` its own connected @@ -150,7 +149,7 @@ def descendant(self, v): def complement(self): """ - The two-graph which is the complement of ``self`` + The two-graph which is the complement of ``self``. That is, the two-graph consisting exactly of triples not in ``self``. Note that this is different from :meth:`complement @@ -175,7 +174,7 @@ def complement(self): def taylor_twograph(q): r""" - constructing Taylor's two-graph for `U_3(q)`, `q` odd prime power + Constructing Taylor's two-graph for `U_3(q)`, `q` odd prime power. The Taylor's two-graph `T` has the `q^3+1` points of the projective plane over `F_{q^2}` singular w.r.t. the non-degenerate Hermitean form `S` preserved by `U_3(q)` as its ground set; @@ -258,7 +257,7 @@ def has_triple(x_y_z): def twograph_descendant(G, v, name=None): r""" - Return the descendant graph w.r.t. vertex `v` of the two-graph of `G` + Return the descendant graph w.r.t. vertex `v` of the two-graph of `G`. In the :mod:`switching class ` of `G`, construct a graph `\Delta` with `v` an isolated vertex, and return the subgraph @@ -272,7 +271,7 @@ def twograph_descendant(G, v, name=None): - ``v`` -- a vertex of ``G`` - - ``name`` -- (default: ``None``); no name, otherwise derive from the construction + - ``name`` -- (default: ``None``) no name, otherwise derive from the construction EXAMPLES: diff --git a/src/sage/combinat/diagram.py b/src/sage/combinat/diagram.py index 61a97249779..25741ac1833 100644 --- a/src/sage/combinat/diagram.py +++ b/src/sage/combinat/diagram.py @@ -336,12 +336,9 @@ def _latex_(self): lr = r'\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}' - array = [] - for i in range(self._n_rows): - row = [] - for j in range(self._n_cols): - row.append("\\phantom{x}" if (i, j) in self else None) - array.append(row) + array = [[("\\phantom{x}" if (i, j) in self else None) + for j in range(self._n_cols)] + for i in range(self._n_rows)] def end_line(r): # give the line ending to row ``r`` @@ -481,7 +478,7 @@ def check(self): sage: D = Diagram([(0,0), (0,-3), (2,2), (2,4)]) Traceback (most recent call last): ... - ValueError: diagrams must be indexed by non-negative integers + ValueError: diagrams must be indexed by nonnegative integers The next example fails because one cell is indexed by rational numbers:: @@ -489,12 +486,12 @@ def check(self): sage: D = Diagram([(0,0), (0,3), (2/3,2), (2,4)]) Traceback (most recent call last): ... - ValueError: diagrams must be indexed by non-negative integers + ValueError: diagrams must be indexed by nonnegative integers """ from sage.sets.non_negative_integers import NonNegativeIntegers NN = NonNegativeIntegers() if not all(i in NN for c in self._cells for i in c): - raise ValueError("diagrams must be indexed by non-negative integers") + raise ValueError("diagrams must be indexed by nonnegative integers") def specht_module(self, base_ring=None): r""" @@ -553,7 +550,6 @@ class Diagrams(UniqueRepresentation, Parent): sage: D = Dgms([(0,0), (0,3), (2,2), (2,4)]) sage: D.parent() Combinatorial diagrams - """ def __init__(self, category=None): @@ -891,7 +887,7 @@ def check(self): sage: NorthwestDiagram([(0,1/2)]) Traceback (most recent call last): ... - ValueError: diagrams must be indexed by non-negative integers + ValueError: diagrams must be indexed by nonnegative integers """ from itertools import combinations Diagram.check(self) @@ -1202,7 +1198,7 @@ class NorthwestDiagrams(Diagrams): Combinatorial northwest diagrams Additionally, there are natural constructions of a northwest diagram - given the data of a permutation (Rothe diagrams are the protypical example + given the data of a permutation (Rothe diagrams are the prototypical example of northwest diagrams), or the data of a partition of an integer, or a skew partition. @@ -1226,7 +1222,7 @@ class NorthwestDiagrams(Diagrams): To turn a Ferrers diagram into a northwest diagram, we may call :meth:`from_partition`. This will return a Ferrer's diagram in the set of all northwest diagrams. For many use-cases it is probably better - to get Ferrer's diagrams by the corresponding method on partitons, namely + to get Ferrer's diagrams by the corresponding method on partitions, namely :meth:`sage.combinat.partitions.Partitions.ferrers_diagram`:: sage: mu = Partition([7,3,1,1]) diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index a31b5817144..6410a4a93ea 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -116,7 +116,7 @@ def brauer_diagrams(k): INPUT: - - ``k`` -- the order of the Brauer diagrams + - ``k`` -- the order of the Brauer diagrams EXAMPLES:: @@ -449,9 +449,7 @@ def base_diagram(self): r""" Return the underlying implementation of the diagram. - OUTPUT: - - - tuple of tuples of integers + OUTPUT: tuple of tuples of integers EXAMPLES:: @@ -532,7 +530,7 @@ def count_blocks_of_size(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -936,14 +934,14 @@ class options(GlobalOptions): The compact representation ``[A/B;pi]`` of the Brauer algebra diagram (see [GL1996]_) has the following components: - - ``A`` -- is a list of pairs of positive elements (upper row) that - are connected, + - ``A`` -- list of pairs of positive elements (upper row) that + are connected - - ``B`` -- is a list of pairs of negative elements (lower row) that - are connected, and + - ``B`` -- list of pairs of negative elements (lower row) that + are connected - - ``pi`` -- is a permutation that is to be interpreted as the relative - order of the remaining elements in the top row and the bottom row. + - ``pi`` -- a permutation that is to be interpreted as the relative + order of the remaining elements in the top row and the bottom row EXAMPLES:: @@ -965,7 +963,7 @@ class options(GlobalOptions): NAME = 'Brauer diagram' module = 'sage.combinat.diagram_algebras' option_class = 'BrauerDiagram' - display = dict(default="normal", + display = dict(default='normal', description='Specifies how the Brauer diagrams should be printed', values=dict(normal="Using the normal representation", compact="Using the compact representation"), @@ -1021,9 +1019,9 @@ def involution_permutation_triple(self, curt=True): INPUT: - - ``curt`` -- (default: ``True``) if ``True``, then return bijection - on free nodes as a one-line notation (standardized to look like a - permutation), else, return the honest mapping, a list of pairs + - ``curt`` -- boolean (default: ``True``); if ``True``, then return + bijection on free nodes as a one-line notation (standardized to look + like a permutation), else, return the honest mapping, a list of pairs `(i, -j)` describing the bijection on free nodes EXAMPLES:: @@ -1147,7 +1145,7 @@ class AbstractPartitionDiagrams(Parent, UniqueRepresentation): INPUT: - ``order`` -- integer or integer `+ 1/2`; the order of the diagrams - - ``category`` -- (default: ``FiniteEnumeratedSets()``); the category + - ``category`` -- (default: ``FiniteEnumeratedSets()``) the category All concrete classes should implement attributes @@ -1501,7 +1499,6 @@ def __contains__(self, obj): sage: bd = da.BrauerDiagrams(3/2) sage: bd.an_element() in bd True - """ if self.order in ZZ: r = ZZ(self.order) @@ -1589,7 +1586,7 @@ def from_involution_permutation_triple(self, D1_D2_pi): INPUT: - - ``D1_D2_pi`` -- a list or tuple where the first entry is a list of + - ``D1_D2_pi`` -- list or tuple where the first entry is a list of arcs on the top of the diagram, the second entry is a list of arcs on the bottom of the diagram, and the third entry is a permutation on the free nodes. @@ -2286,12 +2283,10 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): - ``q`` -- the deformation parameter `q` - OPTIONAL ARGUMENTS: - - - ``base_ring`` -- (default ``None``) a ring containing ``q``; if + - ``base_ring`` -- (default: ``None``) a ring containing ``q``; if ``None``, then Sage automatically chooses the parent of ``q`` - - ``prefix`` -- (default ``"P"``) a label for the basis elements + - ``prefix`` -- (default: ``'P'``) a label for the basis elements EXAMPLES: @@ -2516,7 +2511,7 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): True """ @staticmethod - def __classcall_private__(cls, k, q, base_ring=None, prefix="P"): + def __classcall_private__(cls, k, q, base_ring=None, prefix='P'): r""" Standardize the input by getting the base ring from the parent of the parameter ``q`` if no ``base_ring`` is given. @@ -2751,7 +2746,7 @@ def a(self, i): INPUT: - - ``i`` -- an integer between 1 and `k-1` + - ``i`` -- integer between 1 and `k-1` EXAMPLES:: @@ -2792,7 +2787,7 @@ def e(self, i): INPUT: - - ``i`` -- a half integer between 1/2 and `k-1/2` + - ``i`` -- half integer between `1/2` and `k-1/2` EXAMPLES:: @@ -2851,7 +2846,7 @@ def s(self, i): INPUT: - - ``i`` -- an integer between 1 and `k-1` + - ``i`` -- integer between 1 and `k-1` EXAMPLES:: @@ -2885,7 +2880,7 @@ def sigma(self, i): INPUT: - - ``i`` -- a half integer between 1/2 and `k-1/2` + - ``i`` -- half integer between `1/2` and `k-1/2` .. NOTE:: @@ -2981,7 +2976,7 @@ def jucys_murphy_element(self, i): INPUT: - - ``i`` -- a half integer between 1/2 and `k` + - ``i`` -- half integer between `1/2` and `k` ALGORITHM: @@ -3018,7 +3013,7 @@ def jucys_murphy_element(self, i): sage: L = [P.L(i/2) for i in range(1,2*k+1)] sage: all(x.dual() == x for x in L) True - sage: all(x * y == y * x for x in L for y in L) # long time + sage: all(x * y == y * x for x, y in Subsets(L, 2)) # long time True sage: Lsum = sum(L) sage: gens = [P.s(i) for i in range(1,k)] @@ -3050,13 +3045,13 @@ def jucys_murphy_element(self, i): The same tests for a half integer partition algebra:: - sage: k = 9/2 + sage: k = 7/2 sage: R. = QQ[] sage: P = PartitionAlgebra(k, n) sage: L = [P.L(i/2) for i in range(1,2*k+1)] sage: all(x.dual() == x for x in L) True - sage: all(x * y == y * x for x in L for y in L) # long time + sage: all(x * y == y * x for x, y in Subsets(L, 2)) # long time True sage: Lsum = sum(L) sage: gens = [P.s(i) for i in range(1,k-1/2)] @@ -3119,7 +3114,7 @@ def potts_representation(self, y=None): INPUT: - - ``y`` -- (option) an integer between 1 and `d`; ignored + - ``y`` -- (optional) an integer between 1 and `d`; ignored if the order of ``self`` is an integer, otherwise the default is `1` @@ -3203,7 +3198,7 @@ class OrbitBasis(DiagramAlgebra): O_\pi = \sum_{\tau \geq \pi} \mu_{2k}(\pi, \tau) D_\tau. - If `\tau` is a partition of `\ell` blocks and the `i^{th}` block of + If `\tau` is a partition of `\ell` blocks and the `i`-th block of `\tau` is a union of `b_i` blocks of `\pi`, then .. MATH:: @@ -3715,12 +3710,10 @@ class BrauerAlgebra(SubPartitionAlgebra, UnitDiagramMixin): - ``q`` -- the deformation parameter `q` - OPTIONAL ARGUMENTS: - - - ``base_ring`` -- (default ``None``) a ring containing ``q``; if ``None`` + - ``base_ring`` -- (default: ``None``) a ring containing ``q``; if ``None`` then just takes the parent of ``q`` - - ``prefix`` -- (default ``"B"``) a label for the basis elements + - ``prefix`` -- (default: ``'B'``) a label for the basis elements EXAMPLES: @@ -3760,7 +3753,7 @@ class BrauerAlgebra(SubPartitionAlgebra, UnitDiagramMixin): """ @staticmethod - def __classcall_private__(cls, k, q, base_ring=None, prefix="B"): + def __classcall_private__(cls, k, q, base_ring=None, prefix='B'): r""" Standardize the input by getting the base ring from the parent of the parameter ``q`` if no ``base_ring`` is given. @@ -4156,12 +4149,10 @@ class TemperleyLiebAlgebra(SubPartitionAlgebra, UnitDiagramMixin): - ``q`` -- the deformation parameter `q` - OPTIONAL ARGUMENTS: - - - ``base_ring`` -- (default ``None``) a ring containing ``q``; if ``None`` + - ``base_ring`` -- (default: ``None``) a ring containing ``q``; if ``None`` then just takes the parent of ``q`` - - ``prefix`` -- (default ``"T"``) a label for the basis elements + - ``prefix`` -- (default: ``'T'``) a label for the basis elements EXAMPLES: @@ -4245,7 +4236,7 @@ class TemperleyLiebAlgebra(SubPartitionAlgebra, UnitDiagramMixin): 1 7 20 21 13 """ @staticmethod - def __classcall_private__(cls, k, q, base_ring=None, prefix="T"): + def __classcall_private__(cls, k, q, base_ring=None, prefix='T'): r""" Standardize the input by getting the base ring from the parent of the parameter ``q`` if no ``base_ring`` is given. @@ -4523,12 +4514,10 @@ class PlanarAlgebra(SubPartitionAlgebra, UnitDiagramMixin): - ``q`` -- the deformation parameter `q` - OPTIONAL ARGUMENTS: - - - ``base_ring`` -- (default ``None``) a ring containing ``q``; if ``None`` + - ``base_ring`` -- (default: ``None``) a ring containing ``q``; if ``None`` then just takes the parent of ``q`` - - ``prefix`` -- (default ``"Pl"``) a label for the basis elements + - ``prefix`` -- (default: ``'Pl'``) a label for the basis elements EXAMPLES: @@ -4564,7 +4553,7 @@ class PlanarAlgebra(SubPartitionAlgebra, UnitDiagramMixin): True """ @staticmethod - def __classcall_private__(cls, k, q, base_ring=None, prefix="Pl"): + def __classcall_private__(cls, k, q, base_ring=None, prefix='Pl'): r""" Standardize the input by getting the base ring from the parent of the parameter ``q`` if no ``base_ring`` is given. @@ -4653,7 +4642,7 @@ class PropagatingIdeal(SubPartitionAlgebra): True """ @staticmethod - def __classcall_private__(cls, k, q, base_ring=None, prefix="I"): + def __classcall_private__(cls, k, q, base_ring=None, prefix='I'): r""" Standardize the input by getting the base ring from the parent of the parameter ``q`` if no ``base_ring`` is given. @@ -4711,7 +4700,7 @@ def __pow__(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -4736,9 +4725,9 @@ def TL_diagram_ascii_art(diagram, use_unicode=False, blobs=[]): INPUT: - - ``diagram`` -- a list of pairs of matchings of the set + - ``diagram`` -- list of pairs of matchings of the set `\{-1, \ldots, -n, 1, \ldots, n\}` - - ``use_unicode`` -- (default: ``False``): whether or not + - ``use_unicode`` -- boolean (default: ``False``); whether or not to use unicode art instead of ascii art - ``blobs`` -- (optional) a list of matchings with blobs on them @@ -5786,7 +5775,7 @@ def propagating_number(sp): def to_set_partition(l, k=None): r""" - Convert input to a set partition of `\{1, \ldots, k, -1, \ldots, -k\}` + Convert input to a set partition of `\{1, \ldots, k, -1, \ldots, -k\}`. Convert a list of a list of numbers to a set partitions. Each list of numbers in the outer list specifies the numbers contained in one @@ -5798,12 +5787,10 @@ def to_set_partition(l, k=None): INPUT: - - ``l`` -- a list of lists of integers + - ``l`` -- list of lists of integers - ``k`` -- integer (default: ``None``) - OUTPUT: - - - a list of sets + OUTPUT: list of sets EXAMPLES:: @@ -5860,11 +5847,9 @@ def to_Brauer_partition(l, k=None): True """ L = to_set_partition(l, k=k) - L2 = [] paired = [] not_paired = [] - for i in L: - L2.append(list(i)) + L2 = (list(i) for i in L) for i in L2: if len(i) > 2: raise ValueError("blocks must have size at most 2, but {} has {}".format(i, len(i))) diff --git a/src/sage/combinat/dlx.py b/src/sage/combinat/dlx.py index e34cc7cd7a1..d25f7414d0d 100644 --- a/src/sage/combinat/dlx.py +++ b/src/sage/combinat/dlx.py @@ -55,7 +55,7 @@ def __init__(self, ones, initialsolution=None): described by Knuth. Consider a matrix M with entries of 0 and 1, and compute a subset - of the rows of this matrix which sum to the vector of all 1's. + of the rows of this matrix which sum to the vector of all 1s. The dancing links algorithm works particularly well for sparse matrices, so the input is a list of lists of the form: (note the @@ -119,15 +119,12 @@ def __init__(self, ones, initialsolution=None): def __eq__(self, other): r""" - Return ``True`` if every attribute of - ``other`` matches the attribute of - ``self``. + Return ``True`` if every attribute of ``other`` matches the attribute + of ``self``. INPUT: - - - ``other`` -- a DLX matrix - + - ``other`` -- a DLX matrix EXAMPLES:: @@ -192,7 +189,7 @@ def _constructmatrix(self, ones, initialsolution=None): 'initialsolution' is list of row indexes that are required to be part of the solution. They will be removed from the matrix. - .. NOTE: + .. NOTE:: Rows and cols are 1-indexed ; the zero index is reserved for the root node and column heads. @@ -487,10 +484,7 @@ def AllExactCovers(M): ones = [] r = 1 # damn 1-indexing for R in M.rows(): - row = [] - for i in range(len(R)): - if R[i]: - row.append(i + 1) # damn 1-indexing + row = [i for i, Ri in enumerate(R, start=1) if Ri] ones.append([r, row]) r += 1 for s in DLXMatrix(ones): diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index f144e9c43c6..df841984f31 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -77,7 +77,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from __future__ import annotations -from typing import Iterator +from collections.abc import Iterator from .combinat import CombinatorialElement, catalan_number from sage.combinat.combinatorial_map import combinatorial_map @@ -126,7 +126,7 @@ def replace_parens(x): - If ``x`` is a closing parenthesis, replace ``x`` with the constant ``close_symbol``. - - Raise a :class:`ValueError` if ``x`` is neither an opening nor a + - Raise a :exc:`ValueError` if ``x`` is neither an opening nor a closing parenthesis. .. SEEALSO:: :func:`replace_symbols` @@ -161,7 +161,7 @@ def replace_symbols(x): INPUT: - - ``x`` -- either ``open_symbol`` or ``close_symbol``. + - ``x`` -- either ``open_symbol`` or ``close_symbol`` OUTPUT: @@ -170,7 +170,7 @@ def replace_symbols(x): - If ``x`` is ``close_symbol``, replace ``x`` with ``')'``. - If ``x`` is neither ``open_symbol`` nor ``close_symbol``, a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. .. SEEALSO:: :func:`replace_parens` @@ -363,28 +363,28 @@ def set_latex_options(self, D): The default values are set in the ``__init__`` function. - - ``tikz_scale`` -- (default: 1) scale for use with the tikz package. + - ``tikz_scale`` -- (default: 1) scale for use with the tikz package - - ``diagonal`` -- (default: ``False``) boolean value to draw the - diagonal or not. + - ``diagonal`` -- boolean (default: ``False``); value to draw the + diagonal or not - ``line width`` -- (default: 2*``tikz_scale``) value representing the - line width. + line width - - ``color`` -- (default: black) the line color. + - ``color`` -- (default: black) the line color - - ``bounce path`` -- (default: ``False``) boolean value to indicate - if the bounce path should be drawn. + - ``bounce path`` -- boolean (default: ``False``); value to indicate + if the bounce path should be drawn - - ``peaks`` -- (default: ``False``) boolean value to indicate if the - peaks should be displayed. + - ``peaks`` -- boolean (default: ``False``); value to indicate if the + peaks should be displayed - - ``valleys`` -- (default: ``False``) boolean value to indicate if the - valleys should be displayed. + - ``valleys`` -- boolean (default: ``False``); value to indicate if the + valleys should be displayed INPUT: - - ``D`` -- a dictionary with a list of latex parameters to change + - ``D`` -- dictionary with a list of latex parameters to change EXAMPLES:: @@ -406,24 +406,24 @@ def latex_options(self): The default values are set using the options. - - ``tikz_scale`` -- (default: 1) scale for use with the tikz package. + - ``tikz_scale`` -- (default: 1) scale for use with the tikz package - - ``diagonal`` -- (default: ``False``) boolean value to draw the - diagonal or not. + - ``diagonal`` -- boolean (default: ``False``); value to draw the + diagonal or not - - ``line width`` -- (default: 2*``tikz_scale``) value representing the - line width. + - ``line width`` -- (default: ``2*tikz_scale``) value representing the + line width - - ``color`` -- (default: black) the line color. + - ``color`` -- (default: black) the line color - - ``bounce path`` -- (default: ``False``) boolean value to indicate - if the bounce path should be drawn. + - ``bounce path`` -- boolean (default: ``False``); value to indicate + if the bounce path should be drawn - - ``peaks`` -- (default: ``False``) boolean value to indicate if the - peaks should be displayed. + - ``peaks`` -- boolean (default: ``False``); value to indicate if the + peaks should be displayed - - ``valleys`` -- (default: ``False``) boolean value to indicate if the - valleys should be displayed. + - ``valleys`` -- boolean (default: ``False``); value to indicate if the + valleys should be displayed EXAMPLES:: @@ -616,7 +616,7 @@ def to_path_string(self, unicode=False) -> str: INPUT: - - ``unicode`` -- boolean (default ``False``) whether to use unicode + - ``unicode`` -- boolean (default: ``False``); whether to use unicode EXAMPLES:: @@ -674,11 +674,11 @@ def pretty_print(self, type=None, labelling=None, underpath=True): south-east steps. - ``labelling`` -- (if type is "N-E") a list of labels assigned to - the up steps in ``self``. + the up steps in ``self`` - - ``underpath`` -- (if type is "N-E", default:``True``) If ``True``, + - ``underpath`` -- (if type is "N-E", default:``True``) if ``True``, the labelling is shown under the path; otherwise, it is shown to - the right of the path. + the right of the path EXAMPLES:: @@ -1215,7 +1215,6 @@ def ascent_prime_decomposition(self) -> list[DyckWord]: sage: DyckWord([1,0,1,0]).ascent_prime_decomposition() [[], [1, 0], [], [1, 0], []] - """ n = self.length() H = self.heights() @@ -1287,9 +1286,7 @@ def number_of_initial_rises(self) -> int: r""" Return the length of the initial run of ``self``. - OUTPUT: - - - a non--negative integer indicating the length of the initial rise + OUTPUT: nonnegative integer indicating the length of the initial rise EXAMPLES:: @@ -1497,9 +1494,7 @@ def touch_points(self) -> list[int]: Note that these abscissae are precisely the entries of :meth:`returns_to_zero` divided by `2`. - OUTPUT: - - - a list of integers indicating where the path touches the diagonal + OUTPUT: list of integers indicating where the path touches the diagonal EXAMPLES:: @@ -1521,9 +1516,7 @@ def touch_composition(self): This assumes ``self`` to be a complete Dyck word. - OUTPUT: - - - a composition of length equal to the length of the Dyck word. + OUTPUT: a composition of length equal to the length of the Dyck word EXAMPLES:: @@ -1547,9 +1540,7 @@ def number_of_touch_points(self) -> int: r""" Return the number of touches of ``self`` at the main diagonal. - OUTPUT: - - - a non--negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -1673,7 +1664,7 @@ def to_tamari_sorting_tuple(self) -> list[int]: return resu @combinatorial_map(name="to binary trees: up step, left tree, down step, right tree") - def to_binary_tree(self, usemap="1L0R"): + def to_binary_tree(self, usemap='1L0R'): r""" Return a binary tree recursively constructed from the Dyck path ``self`` by the map ``usemap``. The default ``usemap`` is ``'1L0R'`` @@ -1686,7 +1677,7 @@ def to_binary_tree(self, usemap="1L0R"): INPUT: - - ``usemap`` -- a string, either ``'1L0R'``, ``'1R0L'``, ``'L1R0'``, + - ``usemap`` -- string, either ``'1L0R'``, ``'1R0L'``, ``'L1R0'``, ``'R1L0'`` Other valid ``usemap`` are ``'1R0L'``, ``'L1R0'``, and ``'R1L0'``. @@ -2057,7 +2048,7 @@ def characteristic_symmetric_function(self, q=None, - ``q`` -- (default: ``q = R('q')``) a parameter for the generating function power - - ``R`` -- (default : ``R = QQ['q','t'].fraction_field()``) the base + - ``R`` -- (default: ``R = QQ['q','t'].fraction_field()``) the base ring to do the calculations over OUTPUT: @@ -2324,13 +2315,13 @@ def to_permutation(self, map) -> Permutation: | x . . | . . . - sage: D.to_permutation(map="Bandlow-Killpatrick") + sage: D.to_permutation(map='Bandlow-Killpatrick') [3, 4, 2, 1] - sage: D.to_permutation(map="Stump") + sage: D.to_permutation(map='Stump') [4, 2, 3, 1] - sage: D.to_permutation(map="Knuth") + sage: D.to_permutation(map='Knuth') [1, 2, 4, 3] - sage: D.to_permutation(map="Krattenthaler") + sage: D.to_permutation(map='Krattenthaler') [2, 1, 3, 4] TESTS:: @@ -2737,7 +2728,7 @@ def number_of_tunnels(self, tunnel_type='centered') -> int: INPUT: - ``tunnel_type`` -- (default: ``'centered'``) can be one of the - following: ``'left'``, ``'right'``, ``'centered'``, or ``'all'``. + following: ``'left'``, ``'right'``, ``'centered'``, or ``'all'`` EXAMPLES:: @@ -3021,7 +3012,6 @@ def bounce_path(self) -> DyckWord: [] sage: DyckWord([1,0]).bounce_path() [1, 0] - """ area_seq = self.to_area_sequence() i = len(area_seq) - 1 @@ -3338,7 +3328,7 @@ class options(GlobalOptions): _| x | x . | . . - sage: DyckWords.options(diagram_style="line") + sage: DyckWords.options(diagram_style='line') sage: D /\/\ / \ @@ -3346,18 +3336,18 @@ class options(GlobalOptions): """ NAME = 'DyckWords' module = 'sage.combinat.dyck_word' - display = dict(default="list", + display = dict(default='list', description='Specifies how Dyck words should be printed', values=dict(list='displayed as a list', lattice='displayed on the lattice defined by ``diagram_style``'), case_sensitive=False) - ascii_art = dict(default="path", + ascii_art = dict(default='path', description='Specifies how the ascii art of Dyck words should be printed', values=dict(path="Using the path string", pretty_output="Using pretty printing"), - alias=dict(pretty_print="pretty_output", path_string="path"), + alias=dict(pretty_print='pretty_output', path_string='path'), case_sensitive=False) - diagram_style = dict(default="grid", + diagram_style = dict(default='grid', values=dict(grid='printing as paths on a grid using N and E steps', line='printing as paths on a line using NE and SE steps',), alias={'N-E': 'grid', 'NE-SE': 'line'}, @@ -3372,7 +3362,7 @@ class options(GlobalOptions): description='The default value for the line width as a ' 'multiple of the tikz scale when latexed', checker=lambda x: True) # More trouble than it's worth to check - latex_color = dict(default="black", + latex_color = dict(default='black', description='The default value for the color when latexed', checker=lambda x: isinstance(x, str)) latex_bounce_path = dict(default=False, @@ -3878,8 +3868,8 @@ def from_area_sequence(self, code) -> DyckWord: INPUT: - - ``code`` -- a list of integers satisfying ``code[0] == 0`` - and ``0 <= code[i+1] <= code[i]+1``. + - ``code`` -- list of integers satisfying ``code[0] == 0`` + and ``0 <= code[i+1] <= code[i]+1`` EXAMPLES:: @@ -4130,7 +4120,7 @@ def random_element(self) -> DyckWord: Return a random complete Dyck word of semilength `n`. The algorithm is based on a classical combinatorial fact. One - chooses at random a word with `n` 0's and `n+1` 1's. One then + chooses at random a word with `n` 0s and `n+1` 1s. One then considers every 1 as an ascending step and every 0 as a descending step, and one finds the lowest point of the path (with respect to a slightly tilted slope). One then cuts the diff --git a/src/sage/combinat/e_one_star.py b/src/sage/combinat/e_one_star.py index c0226123521..dd62dc79ae3 100644 --- a/src/sage/combinat/e_one_star.py +++ b/src/sage/combinat/e_one_star.py @@ -248,7 +248,7 @@ class Face(SageObject): - ``v`` -- tuple of integers - ``t`` -- integer in ``[1, ..., len(v)]``, type of the face. The face of type `i` is orthogonal to the canonical vector `e_i`. - - ``color`` -- color (default: ``None``) color of the face, + - ``color`` -- color (default: ``None``); color of the face, used for plotting only. If ``None``, its value is guessed from the face type. @@ -379,7 +379,7 @@ def __hash__(self) -> int: def __add__(self, other): r""" - Addition of self with a Face, a Patch or a finite iterable of faces. + Addition of ``self`` with a Face, a Patch or a finite iterable of faces. INPUT: @@ -450,9 +450,7 @@ def color(self, color=None): the new color to assign to the face. If ``None``, it returns the color of the face. - OUTPUT: - - color or None + OUTPUT: color or None EXAMPLES:: @@ -480,9 +478,7 @@ def _plot(self, projmat, face_contour, opacity) -> Graphics: the contour of unit faces (used only for faces in three dimensions) - ``opacity`` -- the alpha value for the color of the face - OUTPUT: - - 2D graphic object + OUTPUT: 2D graphic object EXAMPLES:: @@ -561,8 +557,8 @@ class Patch(SageObject): INPUT: - ``faces`` -- finite iterable of faces - - ``face_contour`` -- dict (default:``None``) maps the face - type to vectors describing the contour of unit faces. If None, + - ``face_contour`` -- dictionary (default: ``None``); maps the face + type to vectors describing the contour of unit faces. If ``None``, defaults contour are assumed for faces of type 1, 2, 3 or 1, 2, 3. Used in plotting methods only. @@ -701,9 +697,7 @@ def __len__(self) -> int: r""" Return the number of faces contained in the patch. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -719,9 +713,7 @@ def __iter__(self): r""" Return an iterator over the faces of the patch. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -814,7 +806,7 @@ def __repr__(self) -> str: def union(self, other) -> Patch: r""" - Return a Patch consisting of the union of self and other. + Return a Patch consisting of the union of ``self`` and ``other``. INPUT: @@ -836,7 +828,7 @@ def union(self, other) -> Patch: def difference(self, other) -> Patch: r""" - Return the difference of self and other. + Return the difference of ``self`` and ``other``. INPUT: @@ -858,9 +850,9 @@ def difference(self, other) -> Patch: def dimension(self) -> None | int: r""" - Return the dimension of the vectors of the faces of self + Return the dimension of the vectors of the faces of ``self``. - It returns ``None`` if self is the empty patch. + It returns ``None`` if ``self`` is the empty patch. The dimension of a patch is the length of the vectors of the faces in the patch, which is assumed to be the same for every face in the patch. @@ -942,7 +934,7 @@ def faces_of_color(self, color) -> list[Face]: def translate(self, v) -> Patch: r""" - Return a translated copy of self by vector ``v``. + Return a translated copy of ``self`` by vector `v`. INPUT: @@ -967,9 +959,7 @@ def occurrences_of(self, other) -> list: - ``other`` -- a Patch - OUTPUT: - - a list of vectors + OUTPUT: list of vectors EXAMPLES:: @@ -1005,23 +995,23 @@ def occurrences_of(self, other) -> list: def repaint(self, cmap='Set1') -> None: r""" - Repaint all the faces of self from the given color map. + Repaint all the faces of ``self`` from the given color map. - This only changes the colors of the faces of self. + This only changes the colors of the faces of ``self``. INPUT: - - ``cmap`` -- color map (default: ``'Set1'``). It can be one of the - following: + - ``cmap`` -- color map (default: ``'Set1'``). It can be one of the + following: - - string -- A coloring map. For available coloring map names type: + - ``string`` -- a coloring map; for available coloring map names type: ``sorted(colormaps)`` - - list -- a list of colors to assign cyclically to the faces. - A list of a single color colors all the faces with the same color. - - dict -- a dict of face types mapped to colors, to color the - faces according to their type. + - ``list`` -- list of colors to assign cyclically to the faces + A list of a single color colors all the faces with the same color + - ``dict`` -- dictionary of face types mapped to colors, to color the + faces according to their type - ``{}``, the empty dict -- shortcut for - ``{1:'red', 2:'green', 3:'blue'}``. + ``{1:'red', 2:'green', 3:'blue'}`` EXAMPLES: @@ -1089,7 +1079,7 @@ def plot(self, projmat=None, opacity=0.75) -> Graphics: INPUT: - - ``projmat`` -- matrix (default: ``None``) the projection + - ``projmat`` -- matrix (default: ``None``); the projection matrix. Its number of lines must be two. Its number of columns must equal the dimension of the ambient space of the faces. If ``None``, the isometric projection is used by default. @@ -1201,21 +1191,21 @@ def plot_tikz(self, projmat=None, print_tikz_env=True, edgecolor='black', INPUT: - - ``projmat`` -- matrix (default: ``None``) the projection + - ``projmat`` -- matrix (default: ``None``); the projection matrix. Its number of lines must be two. Its number of columns must equal the dimension of the ambient space of the faces. If ``None``, the isometric projection is used by default. - - ``print_tikz_env`` -- bool (default: ``True``) if ``True``, + - ``print_tikz_env`` -- boolean (default: ``True``); if ``True``, the tikzpicture environment are printed - - ``edgecolor`` -- string (default: ``'black'``) either + - ``edgecolor`` -- string (default: ``'black'``); either ``'black'`` or ``'facecolor'`` (color of unit face edges) - ``scale`` -- real number (default: ``0.25``) scaling constant for the whole figure - - ``drawzero`` -- bool (default: ``False``) if ``True``, + - ``drawzero`` -- boolean (default: ``False``); if ``True``, mark the origin by a black dot - - ``extra_code_before`` -- string (default: ``''``) extra code to + - ``extra_code_before`` -- string (default: ``''``); extra code to include in the tikz picture - - ``extra_code_after`` -- string (default: ``''``) extra code to + - ``extra_code_after`` -- string (default: ``''``); extra code to include in the tikz picture EXAMPLES:: @@ -1359,11 +1349,11 @@ class E1Star(SageObject): INPUT: - ``sigma`` -- unimodular ``WordMorphism``, i.e. such that its incidence - matrix has determinant `\pm 1`. + matrix has determinant `\pm 1` - - ``method`` -- 'prefix' or 'suffix' (default: 'suffix') - Enables to use an alternative definition `E_1^*(\sigma)` substitutions, - where the abelianized of the prefix` is used instead of the suffix. + - ``method`` -- 'prefix' or 'suffix' (default: ``'suffix'``); + enables to use an alternative definition `E_1^*(\sigma)` substitutions, + where the abelianized of the prefix` is used instead of the suffix .. NOTE:: @@ -1478,11 +1468,9 @@ def __call__(self, patch, iterations=1) -> Patch: INPUT: - ``patch`` -- a patch - - ``iterations`` -- integer (default: 1) number of iterations + - ``iterations`` -- integer (default: 1); number of iterations - OUTPUT: - - a patch + OUTPUT: a patch EXAMPLES:: @@ -1529,9 +1517,7 @@ def __mul__(self, other) -> E1Star: - ``other`` -- an instance of E1Star - OUTPUT: - - an instance of E1Star + OUTPUT: an instance of E1Star EXAMPLES:: @@ -1568,12 +1554,9 @@ def _call_on_face(self, face, color=None): INPUT: - ``face`` -- a face - - ``color`` -- string, RGB tuple or color, (default: None) - RGB color + - ``color`` -- string (default: ``None``); RGB tuple or color - OUTPUT: - - iterator of faces + OUTPUT: iterator of faces EXAMPLES:: @@ -1621,7 +1604,6 @@ def inverse_matrix(self): [ 0 1 0] [ 0 0 1] [ 1 -1 -1] - """ return self.matrix().inverse() diff --git a/src/sage/combinat/enumeration_mod_permgroup.pyx b/src/sage/combinat/enumeration_mod_permgroup.pyx index 70b05c6276b..b2f713228ed 100644 --- a/src/sage/combinat/enumeration_mod_permgroup.pyx +++ b/src/sage/combinat/enumeration_mod_permgroup.pyx @@ -15,12 +15,12 @@ from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement cpdef list all_children(ClonableIntArray v, int max_part): r""" - Returns all the children of an integer vector (:class:`~sage.structure.list_clone.ClonableIntArray`) + Return all the children of an integer vector (:class:`~sage.structure.list_clone.ClonableIntArray`) ``v`` in the tree of enumeration by lexicographic order. The children of an integer vector ``v`` whose entries have the sum `n` are all integer vectors of sum `n+1` which follow ``v`` in the lexicographic order. - That means this function adds `1` on the last non zero entries and the + That means this function adds `1` on the last nonzero entries and the following ones. For an integer vector `v` such that .. MATH:: @@ -92,7 +92,8 @@ cpdef int lex_cmp(ClonableIntArray v1, ClonableIntArray v2) noexcept: INPUT: - Two instances `v_1, v_2` of :class:`~sage.structure.list_clone.ClonableIntArray` + - ``v1``, ``v2`` -- two instances of + :class:`~sage.structure.list_clone.ClonableIntArray` OUTPUT: @@ -118,7 +119,6 @@ cpdef int lex_cmp(ClonableIntArray v1, ClonableIntArray v2) noexcept: -1 sage: lex_cmp(v3, v1) 1 - """ cdef int i cdef int step = min(v1._len,v2._len) @@ -139,7 +139,7 @@ cpdef int lex_cmp(ClonableIntArray v1, ClonableIntArray v2) noexcept: cpdef bint is_canonical(list sgs, ClonableIntArray v) except -1: r""" - Returns ``True`` if the integer vector `v` is maximal with respect to + Return ``True`` if the integer vector `v` is maximal with respect to the lexicographic order in its orbit under the action of the permutation group whose strong generating system is ``sgs``. Such vectors are said to be canonical. @@ -186,7 +186,7 @@ cpdef bint is_canonical(list sgs, ClonableIntArray v) except -1: cpdef ClonableIntArray canonical_representative_of_orbit_of(list sgs, ClonableIntArray v): r""" - Returns the maximal vector for the lexicographic order living in + Return the maximal vector for the lexicographic order living in the orbit of `v` under the action of the permutation group whose strong generating system is ``sgs``. The maximal vector is also called "canonical". Hence, this method returns the canonical @@ -232,7 +232,7 @@ cpdef ClonableIntArray canonical_representative_of_orbit_of(list sgs, ClonableIn cpdef list canonical_children(list sgs, ClonableIntArray v, int max_part): r""" - Returns the canonical children of the integer vector ``v``. This + Return the canonical children of the integer vector ``v``. This function computes all children of the integer vector ``v`` via the function :func:`all_children` and returns from this list only these which are canonicals identified via the function @@ -253,7 +253,7 @@ cpdef list canonical_children(list sgs, ClonableIntArray v, int max_part): cpdef set orbit(list sgs, ClonableIntArray v): r""" - Returns the orbit of the integer vector ``v`` under the action of the + Return the orbit of the integer vector ``v`` under the action of the permutation group whose strong generating system is ``sgs``. NOTE: diff --git a/src/sage/combinat/expnums.pyx b/src/sage/combinat/expnums.pyx index 897a1bd7870..d0e169189ba 100644 --- a/src/sage/combinat/expnums.pyx +++ b/src/sage/combinat/expnums.pyx @@ -7,9 +7,7 @@ AUTHORS: """ from cysignals.memory cimport check_allocarray, sig_free - from sage.libs.gmp.mpz cimport * - from sage.rings.integer cimport Integer @@ -20,13 +18,11 @@ def expnums(int n, int aa): INPUT: + - ``n`` -- C machine int - - ``n`` -- C machine int - - - ``aa`` -- C machine int - + - ``aa`` -- C machine int - OUTPUT: A list of length `n`. + OUTPUT: list of length `n` ALGORITHM: We use the same integer addition algorithm as GAP. This is an extension of Bell's triangle to the general case of diff --git a/src/sage/combinat/fast_vector_partitions.pyx b/src/sage/combinat/fast_vector_partitions.pyx index 4d00d062d96..e9a103f862b 100644 --- a/src/sage/combinat/fast_vector_partitions.pyx +++ b/src/sage/combinat/fast_vector_partitions.pyx @@ -37,7 +37,7 @@ cdef list vector_halve(list v): INPUT: - - ``v`` -- list of non-negative integers, understood as a vector + - ``v`` -- list of nonnegative integers, understood as a vector OUTPUT: @@ -82,11 +82,11 @@ def recursive_within_from_to(list m, list s, list e, bint useS, bint useE): INPUT: - - ``m`` -- list of non-negative integers, understood as a vector - - ``s`` -- list of non-negative integers, understood as a vector - - ``e`` -- list of non-negative integers, understood as a vector - - ``useS`` -- boolean - - ``useE`` -- boolean + - ``m`` -- list of nonnegative integers, understood as a vector + - ``s`` -- list of nonnegative integers, understood as a vector + - ``e`` -- list of nonnegative integers, understood as a vector + - ``useS`` -- boolean + - ``useE`` -- boolean EXAMPLES:: @@ -148,9 +148,9 @@ def within_from_to(list m, list s, list e): INPUT: - - ``m`` -- list of non-negative integers, understood as a vector - - ``s`` -- list of non-negative integers, understood as a vector - - ``e`` -- list of non-negative integers, understood as a vector + - ``m`` -- list of nonnegative integers, understood as a vector + - ``s`` -- list of nonnegative integers, understood as a vector + - ``e`` -- list of nonnegative integers, understood as a vector EXAMPLES:: @@ -253,8 +253,8 @@ def recursive_vector_partitions(list v, list vL): INPUT: - - ``v`` -- list of non-negative integers, understood as a vector - - ``vL`` -- list of non-negative integers, understood as a vector + - ``v`` -- list of nonnegative integers, understood as a vector + - ``vL`` -- list of nonnegative integers, understood as a vector EXAMPLES:: @@ -284,15 +284,13 @@ def fast_vector_partitions(v, min_vals=None): INPUT: - - ``v`` -- list of non-negative integers, understood as the vector + - ``v`` -- list of nonnegative integers, understood as the vector to be partitioned - - ``min_vals`` -- optional list of non-negative integers, of same + - ``min_vals`` -- (optional) list of nonnegative integers, of same length as ``v`` - OUTPUT: - - A list of lists, each representing a vector partition of ``v``. + OUTPUT: list of lists, each representing a vector partition of ``v`` If ``min_vals`` is given, only partitions with parts ``p >= min_vals`` in the lexicographic ordering will appear. diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 480c4b4f890..2750ea15e9c 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -61,10 +61,10 @@ :widths: 30, 70 :delim: | - :meth:`~FiniteStateMachine.empty_copy` | Returns an empty deep copy - :meth:`~FiniteStateMachine.deepcopy` | Returns a deep copy - :meth:`~FiniteStateMachine.relabeled` | Returns a relabeled deep copy - :meth:`Automaton.with_output` | Extends an automaton to a transducer + :meth:`~FiniteStateMachine.empty_copy` | Return an empty deep copy + :meth:`~FiniteStateMachine.deepcopy` | Return a deep copy + :meth:`~FiniteStateMachine.relabeled` | Return a relabeled deep copy + :meth:`Automaton.with_output` | Extend an automaton to a transducer Manipulation @@ -101,18 +101,18 @@ :widths: 30, 70 :delim: | - :meth:`~FiniteStateMachine.has_state` | Checks for a state - :meth:`~FiniteStateMachine.has_initial_state` | Checks for an initial state - :meth:`~FiniteStateMachine.has_initial_states` | Checks for initial states - :meth:`~FiniteStateMachine.has_final_state` | Checks for a final state - :meth:`~FiniteStateMachine.has_final_states` | Checks for final states - :meth:`~FiniteStateMachine.has_transition` | Checks for a transition - :meth:`~FiniteStateMachine.is_deterministic` | Checks for a deterministic machine - :meth:`~FiniteStateMachine.is_complete` | Checks for a complete machine - :meth:`~FiniteStateMachine.is_connected` | Checks for a connected machine - :meth:`Automaton.is_equivalent` | Checks for equivalent automata - :meth:`~FiniteStateMachine.is_Markov_chain` | Checks for a Markov chain - :meth:`~FiniteStateMachine.is_monochromatic` | Checks whether the colors of all states are equal + :meth:`~FiniteStateMachine.has_state` | Check for a state + :meth:`~FiniteStateMachine.has_initial_state` | Check for an initial state + :meth:`~FiniteStateMachine.has_initial_states` | Check for initial states + :meth:`~FiniteStateMachine.has_final_state` | Check for a final state + :meth:`~FiniteStateMachine.has_final_states` | Check for final states + :meth:`~FiniteStateMachine.has_transition` | Check for a transition + :meth:`~FiniteStateMachine.is_deterministic` | Check for a deterministic machine + :meth:`~FiniteStateMachine.is_complete` | Check for a complete machine + :meth:`~FiniteStateMachine.is_connected` | Check for a connected machine + :meth:`Automaton.is_equivalent` | Check for equivalent automata + :meth:`~FiniteStateMachine.is_Markov_chain` | Check for a Markov chain + :meth:`~FiniteStateMachine.is_monochromatic` | Check whether the colors of all states are equal :meth:`~FiniteStateMachine.number_of_words` | Determine the number of successful paths :meth:`~FiniteStateMachine.asymptotic_moments` | Main terms of expectation and variance of sums of labels :meth:`~FiniteStateMachine.moments_waiting_time` | Moments of the waiting time for first true output @@ -211,12 +211,12 @@ :delim: | :attr:`~FSMState.final_word_out` | Final output of a state - :attr:`~FSMState.is_final` | Describes whether a state is final or not - :attr:`~FSMState.is_initial` | Describes whether a state is initial or not + :attr:`~FSMState.is_final` | Describe whether a state is final or not + :attr:`~FSMState.is_initial` | Describe whether a state is initial or not :attr:`~FSMState.initial_probability` | Probability of starting in this state as part of a Markov chain :meth:`~FSMState.label` | Label of a state - :meth:`~FSMState.relabeled` | Returns a relabeled deep copy of a state - :meth:`~FSMState.fully_equal` | Checks whether two states are fully equal (including all attributes) + :meth:`~FSMState.relabeled` | Return a relabeled deep copy of a state + :meth:`~FSMState.fully_equal` | Check whether two states are fully equal (including all attributes) :class:`FSMTransition` @@ -231,7 +231,7 @@ :attr:`~FSMTransition.to_state` | State in which transition ends :attr:`~FSMTransition.word_in` | Input word of the transition :attr:`~FSMTransition.word_out` | Output word of the transition - :meth:`~FSMTransition.deepcopy` | Returns a deep copy of the transition + :meth:`~FSMTransition.deepcopy` | Return a deep copy of the transition :class:`FSMProcessIterator` @@ -242,9 +242,9 @@ :widths: 30, 70 :delim: | - :meth:`~FSMProcessIterator.next` | Makes one step in processing the input tape - :meth:`~FSMProcessIterator.preview_word` | Reads a word from the input tape - :meth:`~FSMProcessIterator.result` | Returns the finished branches during process + :meth:`~FSMProcessIterator.next` | Make one step in processing the input tape + :meth:`~FSMProcessIterator.preview_word` | Read a word from the input tape + :meth:`~FSMProcessIterator.result` | Return the finished branches during process Helper Functions @@ -255,14 +255,14 @@ :widths: 30, 70 :delim: | - :func:`equal` | Checks whether all elements of ``iterator`` are equal + :func:`equal` | Check whether all elements of ``iterator`` are equal :func:`full_group_by` | Group iterable by values of some key :func:`startswith` | Determine whether list starts with the given prefix - :func:`FSMLetterSymbol` | Returns a string associated to the input letter - :func:`FSMWordSymbol` | Returns a string associated to a word - :func:`is_FSMState` | Tests whether an object inherits from :class:`FSMState` - :func:`is_FSMTransition` | Tests whether an object inherits from :class:`FSMTransition` - :func:`is_FiniteStateMachine` | Tests whether an object inherits from :class:`FiniteStateMachine` + :func:`FSMLetterSymbol` | Return a string associated to the input letter + :func:`FSMWordSymbol` | Return a string associated to a word + :func:`is_FSMState` | Test whether an object inherits from :class:`FSMState` + :func:`is_FSMTransition` | Test whether an object inherits from :class:`FSMTransition` + :func:`is_FiniteStateMachine` | Test whether an object inherits from :class:`FiniteStateMachine` :func:`duplicate_transition_ignore` | Default function for handling duplicate transitions :func:`duplicate_transition_raise_error` | Raise error when inserting a duplicate transition :func:`duplicate_transition_add_input` | Add input when inserting a duplicate transition @@ -343,7 +343,7 @@ --------------------------------------- We want to build an automaton which recognizes non-adjacent forms -(NAFs), i.e., sequences which have no adjacent non-zeros. +(NAFs), i.e., sequences which have no adjacent nonzeros. We use `0`, `1`, and `-1` as digits:: sage: NAF = Automaton( @@ -591,7 +591,7 @@ ... ValueError: Invalid input sequence. -The raised :class:`ValueError` means `13` is not divisible by `3`. +The raised :exc:`ValueError` means `13` is not divisible by `3`. .. _finite_state_machine_gray_code_example: @@ -730,7 +730,7 @@ True Finally, we check that this indeed computes the Gray code of the first -10 non-negative integers. +10 nonnegative integers. :: @@ -1023,15 +1023,13 @@ def full_group_by(l, key=None): def equal(iterator): """ - Checks whether all elements of ``iterator`` are equal. + Check whether all elements of ``iterator`` are equal. INPUT: - ``iterator`` -- an iterator of the elements to check - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean This implements ``_. @@ -1073,9 +1071,7 @@ def startswith(list_, prefix): - ``list_`` -- list - ``prefix`` -- list representing the prefix - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean Similar to :meth:`str.startswith`. @@ -1112,7 +1108,7 @@ def FSMLetterSymbol(letter): INPUT: - ``letter`` -- the input letter or ``None`` (representing the - empty word). + empty word) OUTPUT: @@ -1138,11 +1134,9 @@ def FSMWordSymbol(word): INPUT: - - ``word`` -- the input word. - - OUTPUT: + - ``word`` -- the input word - A string of ``word``. + OUTPUT: string of ``word`` EXAMPLES:: @@ -1162,7 +1156,7 @@ def FSMWordSymbol(word): def is_FSMState(S): """ - Tests whether or not ``S`` inherits from :class:`FSMState`. + Test whether or not ``S`` inherits from :class:`FSMState`. TESTS:: @@ -1184,10 +1178,10 @@ class FSMState(SageObject): INPUT: - - ``label`` -- the label of the state. + - ``label`` -- the label of the state - ``word_out`` -- (default: ``None``) a word that is written when - the state is reached. + the state is reached - ``is_initial`` -- (default: ``False``) @@ -1197,10 +1191,10 @@ class FSMState(SageObject): the state is reached as the last state of some input; only for final states. - - ``initial_probability`` -- (default: ``None``) The probability of - starting in this state if it is a state of a Markov chain. + - ``initial_probability`` -- (default: ``None``) the probability of + starting in this state if it is a state of a Markov chain - - ``hook`` -- (default: ``None``) A function which is called when + - ``hook`` -- (default: ``None``) a function which is called when the state is reached during processing input. It takes two input parameters: the first is the current state (to allow using the same hook for several states), the second is the current process @@ -1212,20 +1206,18 @@ class FSMState(SageObject): processing of a finite state machine the input immediately. See also the example below. - - ``color`` -- (default: ``None``) In order to distinguish states, + - ``color`` -- (default: ``None``) in order to distinguish states, they can be given an arbitrary "color" (an arbitrary object). This is used in :meth:`FiniteStateMachine.equivalence_classes`: states of different colors are never considered to be equivalent. Note that :meth:`Automaton.determinisation` requires that ``color`` is hashable. - - ``allow_label_None`` -- (default: ``False``) If ``True`` allows also - ``None`` as label. Note that a state with label ``None`` is used in + - ``allow_label_None`` -- boolean (default: ``False``); if ``True`` allows + also ``None`` as label. Note that a state with label ``None`` is used in :class:`FSMProcessIterator`. - OUTPUT: - - A state of a finite state machine. + OUTPUT: a state of a finite state machine EXAMPLES:: @@ -1437,11 +1429,9 @@ def __lt__(self, other): INPUT: - - `other` -- a state. + - ``other`` -- a state - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -1493,15 +1483,13 @@ def final_word_out(self): @final_word_out.setter def final_word_out(self, final_word_out): """ - Sets the value of the final output word of a final state. + Set the value of the final output word of a final state. INPUT: - - ``final_word_out`` -- a list, any element or ``None``. - - OUTPUT: + - ``final_word_out`` -- list; any element or ``None`` - Nothing. + OUTPUT: nothing TESTS:: @@ -1550,7 +1538,7 @@ def final_word_out(self, final_word_out): @property def is_final(self): """ - Describes whether the state is final or not. + Describe whether the state is final or not. ``True`` if the state is final and ``False`` otherwise. @@ -1576,16 +1564,14 @@ def is_final(self): @is_final.setter def is_final(self, is_final): """ - Defines the state as a final state or a non-final state. + Define the state as a final state or a non-final state. INPUT: - ``is_final`` -- ``True`` if the state should be final and - ``False`` otherwise. - - OUTPUT: + ``False`` otherwise - Nothing. + OUTPUT: nothing TESTS:: @@ -1644,14 +1630,6 @@ def label(self): """ Return the label of the state. - INPUT: - - Nothing. - - OUTPUT: - - The label of the state. - EXAMPLES:: sage: from sage.combinat.finite_state_machine import FSMState @@ -1665,13 +1643,7 @@ def __copy__(self): """ Return a (shallow) copy of the state. - INPUT: - - Nothing. - - OUTPUT: - - A new state. + OUTPUT: a new state EXAMPLES:: @@ -1715,11 +1687,9 @@ def __deepcopy__(self, memo): INPUT: - - ``memo`` -- a dictionary storing already processed elements. + - ``memo`` -- dictionary storing already processed elements - OUTPUT: - - A new state. + OUTPUT: a new state EXAMPLES:: @@ -1748,11 +1718,9 @@ def deepcopy(self, memo=None): INPUT: - ``memo`` -- (default: ``None``) a dictionary storing already - processed elements. + processed elements - OUTPUT: - - A new state. + OUTPUT: a new state EXAMPLES:: @@ -1790,14 +1758,12 @@ def relabeled(self, label, memo=None): INPUT: - - ``label`` -- the label of new state. + - ``label`` -- the label of new state - ``memo`` -- (default: ``None``) a dictionary storing already - processed elements. - - OUTPUT: + processed elements - A new state. + OUTPUT: a new state EXAMPLES:: @@ -1815,13 +1781,7 @@ def __getstate__(self): """ Return state for pickling excluding outgoing transitions. - INPUT: - - None - - OUTPUT: - - A dictionary. + OUTPUT: a dictionary Outgoing transitions are in fact stored in states, but must be pickled by the finite state machine @@ -1862,9 +1822,7 @@ def __hash__(self): """ Return a hash value for the object. - OUTPUT: - - The hash of this state. + OUTPUT: the hash of this state TESTS:: @@ -1879,13 +1837,7 @@ def _repr_(self): """ Return the string "label". - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -1902,13 +1854,11 @@ def __eq__(self, other): INPUT: - - ``self`` -- a state. - - - ``other`` -- a state. + - ``self`` -- a state - OUTPUT: + - ``other`` -- a state - ``True`` or ``False``. + OUTPUT: boolean Note that the hooks and whether the states are initial or final are not checked. To fully compare two states (including @@ -1934,17 +1884,15 @@ def __eq__(self, other): def __ne__(self, other): """ - Tests for inequality, complement of __eq__. + Test for inequality, complement of __eq__. INPUT: - - ``self`` -- a state. - - - ``other`` -- a state. + - ``self`` -- a state - OUTPUT: + - ``other`` -- a state - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -1963,16 +1911,14 @@ def fully_equal(self, other, compare_color=True): INPUT: - - ``self`` -- a state. + - ``self`` -- a state - - ``other`` -- a state. + - ``other`` -- a state - - ``compare_color`` -- If ``True`` (default) colors are - compared as well, otherwise not. + - ``compare_color`` -- boolean (default: ``True``); if ``True`` colors + are compared as well, otherwise not - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean Note that usual comparison by ``==`` does only compare the labels. @@ -2021,11 +1967,9 @@ def _epsilon_successors_(self, fsm=None): INPUT: - ``fsm`` -- the finite state machine to which ``self`` - belongs. + belongs - OUTPUT: - - A dictionary mapping states to a list of output words. + OUTPUT: a dictionary mapping states to a list of output words The states in the output are the epsilon successors of ``self``. Each word of the list of words is an output word @@ -2087,11 +2031,9 @@ def _in_epsilon_cycle_(self, fsm=None): INPUT: - ``fsm`` -- the finite state machine to which ``self`` - belongs. - - OUTPUT: + belongs - ``True`` or ``False``. + OUTPUT: boolean TESTS:: @@ -2118,13 +2060,11 @@ def _epsilon_cycle_output_empty_(self, fsm=None): INPUT: - ``fsm`` -- the finite state machine to which ``self`` - belongs. - - OUTPUT: + belongs - ``True`` or ``False`` + OUTPUT: boolean - A :class:`ValueError` is raised when ``self`` is not in an epsilon + A :exc:`ValueError` is raised when ``self`` is not in an epsilon cycle. TESTS:: @@ -2176,7 +2116,7 @@ def _epsilon_cycle_output_empty_(self, fsm=None): def is_FSMTransition(T): """ - Tests whether or not ``T`` inherits from :class:`FSMTransition`. + Test whether or not ``T`` inherits from :class:`FSMTransition`. TESTS:: @@ -2198,9 +2138,9 @@ class FSMTransition(SageObject): INPUT: - - ``from_state`` -- state from which transition starts. + - ``from_state`` -- state from which transition starts - - ``to_state`` -- state in which transition ends. + - ``to_state`` -- state in which transition ends - ``word_in`` -- the input word of the transitions (when the finite state machine is used as automaton) @@ -2208,9 +2148,7 @@ class FSMTransition(SageObject): - ``word_out`` -- the output word of the transitions (when the finite state machine is used as transducer) - OUTPUT: - - A transition of a finite state machine. + OUTPUT: a transition of a finite state machine EXAMPLES:: @@ -2224,7 +2162,6 @@ class FSMTransition(SageObject): sage: U = FSMTransition('A', 'B', 0) sage: U == T False - """ from_state = None @@ -2282,16 +2219,14 @@ def __init__(self, from_state, to_state, def __lt__(self, other): """ - Return True if ``self`` is less than ``other`` with respect to the + Return ``True`` if ``self`` is less than ``other`` with respect to the key ``(self.from_state, self.word_in, self.to_state, self.word_out)``. INPUT: - - ``other`` -- a transition. + - ``other`` -- a transition - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -2306,9 +2241,7 @@ def __copy__(self): """ Return a (shallow) copy of the transition. - OUTPUT: - - A new transition. + OUTPUT: a new transition EXAMPLES:: @@ -2331,11 +2264,9 @@ def __deepcopy__(self, memo): INPUT: - - ``memo`` -- a dictionary storing already processed elements. + - ``memo`` -- dictionary storing already processed elements - OUTPUT: - - A new transition. + OUTPUT: a new transition EXAMPLES:: @@ -2359,11 +2290,9 @@ def deepcopy(self, memo=None): INPUT: - ``memo`` -- (default: ``None``) a dictionary storing already - processed elements. - - OUTPUT: + processed elements - A new transition. + OUTPUT: a new transition EXAMPLES:: @@ -2379,22 +2308,15 @@ def deepcopy(self, memo=None): def _repr_(self): """ - Represents a transitions as from state to state and input, output. + Represent a transitions as from state to state and input, output. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: sage: from sage.combinat.finite_state_machine import FSMTransition sage: FSMTransition('A', 'B', 0, 0)._repr_() "Transition from 'A' to 'B': 0|0" - """ return "Transition from %s to %s: %s" % (repr(self.from_state), repr(self.to_state), @@ -2404,13 +2326,7 @@ def _in_out_label_(self): """ Return the input and output of a transition as "word_in|word_out". - INPUT: - - Nothing. - - OUTPUT: - - A string of the input and output labels. + OUTPUT: string of the input and output labels EXAMPLES:: @@ -2431,13 +2347,11 @@ def __eq__(self, other): INPUT: - - ``self`` -- a transition. + - ``self`` -- a transition - - ``other`` -- a transition. - - OUTPUT: + - ``other`` -- a transition - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -2461,13 +2375,11 @@ def __ne__(self, other): INPUT: - - ``self`` -- a transition. + - ``self`` -- a transition - - ``other`` -- a transition. + - ``other`` -- a transition - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -2498,7 +2410,7 @@ def __bool__(self): def is_FiniteStateMachine(FSM): """ - Tests whether or not ``FSM`` inherits from :class:`FiniteStateMachine`. + Test whether or not ``FSM`` inherits from :class:`FiniteStateMachine`. TESTS:: @@ -2528,14 +2440,12 @@ def duplicate_transition_ignore(old_transition, new_transition): INPUT: - - ``old_transition`` -- A transition in a finite state machine. + - ``old_transition`` -- a transition in a finite state machine - - ``new_transition`` -- A transition, identical to ``old_transition``, - which is to be inserted into the finite state machine. + - ``new_transition`` -- a transition, identical to ``old_transition``, + which is to be inserted into the finite state machine - OUTPUT: - - The same transition, unchanged. + OUTPUT: the same transition, unchanged EXAMPLES:: @@ -2553,21 +2463,19 @@ def duplicate_transition_raise_error(old_transition, new_transition): Alternative function for handling duplicate transitions in finite state machines. - This implementation raises a :class:`ValueError`. + This implementation raises a :exc:`ValueError`. See the documentation of the ``on_duplicate_transition`` parameter of :class:`FiniteStateMachine`. INPUT: - - ``old_transition`` -- A transition in a finite state machine. - - - ``new_transition`` -- A transition, identical to ``old_transition``, - which is to be inserted into the finite state machine. + - ``old_transition`` -- a transition in a finite state machine - OUTPUT: + - ``new_transition`` -- a transition, identical to ``old_transition``, + which is to be inserted into the finite state machine - Nothing. A :class:`ValueError` is raised. + OUTPUT: nothing. A :exc:`ValueError` is raised EXAMPLES:: @@ -2595,10 +2503,10 @@ def duplicate_transition_add_input(old_transition, new_transition): INPUT: - - ``old_transition`` -- A transition in a finite state machine. + - ``old_transition`` -- a transition in a finite state machine - - ``new_transition`` -- A transition, identical to ``old_transition``, - which is to be inserted into the finite state machine. + - ``new_transition`` -- a transition, identical to ``old_transition``, + which is to be inserted into the finite state machine OUTPUT: @@ -2664,22 +2572,22 @@ class FiniteStateMachine(SageObject): - ``input_alphabet`` and ``output_alphabet`` -- the input and output alphabets of this machine - - ``determine_alphabets`` -- If ``True``, then the function + - ``determine_alphabets`` -- if ``True``, then the function :meth:`.determine_alphabets` is called after ``data`` was read and processed, if ``False``, then not. If it is ``None``, then it is decided during the construction of the finite state machine whether :meth:`.determine_alphabets` should be called. - - ``with_final_word_out`` -- If given (not ``None``), then the + - ``with_final_word_out`` -- if given (not ``None``), then the function :meth:`.with_final_word_out` (more precisely, its inplace pendant :meth:`.construct_final_word_out`) is called with input ``letters=with_final_word_out`` at the end of the creation process. - - ``store_states_dict`` -- If ``True``, then additionally the states - are stored in an internal dictionary for speed up. + - ``store_states_dict`` -- if ``True``, then additionally the states + are stored in an internal dictionary for speed up - - ``on_duplicate_transition`` -- A function which is called when a + - ``on_duplicate_transition`` -- a function which is called when a transition is inserted into ``self`` which already existed (same ``from_state``, same ``to_state``, same ``word_in``, same ``word_out``). @@ -2696,9 +2604,7 @@ class FiniteStateMachine(SageObject): ``duplicate_transition_raise_error`` and ``duplicate_transition_add_input``. - OUTPUT: - - A finite state machine. + OUTPUT: a finite state machine The object creation of :class:`Automaton` and :class:`Transducer` is the same as the one described here (i.e. just replace the word @@ -2828,7 +2734,7 @@ class FiniteStateMachine(SageObject): non-deterministic). If the transition does not exist, the function should raise a - :class:`LookupError` or return an empty list. + :exc:`LookupError` or return an empty list. When constructing a finite state machine in this way, some initial states and an input alphabet have to be specified. @@ -3234,9 +3140,7 @@ def __copy__(self): """ Return a (shallow) copy of the finite state machine. - OUTPUT: - - A new finite state machine. + OUTPUT: a new finite state machine TESTS:: @@ -3257,14 +3161,12 @@ def empty_copy(self, memo=None, new_class=None): INPUT: - - ``memo`` -- a dictionary storing already processed elements. + - ``memo`` -- dictionary storing already processed elements - - ``new_class`` -- a class for the copy. By default - (``None``), the class of ``self`` is used. + - ``new_class`` -- a class for the copy; by default + (``None``), the class of ``self`` is used - OUTPUT: - - A new finite state machine. + OUTPUT: a new finite state machine EXAMPLES:: @@ -3303,11 +3205,9 @@ def __deepcopy__(self, memo): INPUT: - - ``memo`` -- a dictionary storing already processed elements. - - OUTPUT: + - ``memo`` -- dictionary storing already processed elements - A new finite state machine. + OUTPUT: a new finite state machine EXAMPLES:: @@ -3326,11 +3226,9 @@ def deepcopy(self, memo=None): INPUT: - ``memo`` -- (default: ``None``) a dictionary storing already - processed elements. - - OUTPUT: + processed elements - A new finite state machine. + OUTPUT: a new finite state machine EXAMPLES:: @@ -3357,11 +3255,9 @@ def _copy_from_other_(self, other, memo=None, empty=False): INPUT: - - ``other`` -- a :class:`FiniteStateMachine`. + - ``other`` -- a :class:`FiniteStateMachine` - OUTPUT: - - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -3406,9 +3302,7 @@ def __getstate__(self): """ Return state for pickling excluding outgoing transitions. - OUTPUT: - - A dictionary. + OUTPUT: a dictionary Outgoing transitions are in fact stored in states, but must be pickled by the finite state machine @@ -3430,11 +3324,9 @@ def __setstate__(self, d): INPUT: - - `d` -- a dictionary - - OUTPUT: + - ``d`` -- dictionary - None. + OUTPUT: none As transitions are in fact stored in states but not saved by states in order to avoid deep recursion, transitions @@ -3461,15 +3353,13 @@ def relabeled(self, memo=None, labels=None): INPUT: - ``memo`` -- (default: ``None``) a dictionary storing already - processed elements. + processed elements - ``labels`` -- (default: ``None``) a dictionary or callable mapping old labels to new labels. If ``None``, then the new labels are integers starting with 0. - OUTPUT: - - A new finite state machine. + OUTPUT: a new finite state machine EXAMPLES:: @@ -3507,8 +3397,8 @@ def induced_sub_finite_state_machine(self, states): INPUT: - - ``states`` -- a list (or an iterator) of states (either labels or - instances of :class:`FSMState`) of the sub-finite-state-machine. + - ``states`` -- list (or an iterator) of states (either labels or + instances of :class:`FSMState`) of the sub-finite-state-machine OUTPUT: @@ -3562,13 +3452,7 @@ def __hash__(self): Since finite state machines are mutable, they should not be hashable, so we return a type error. - INPUT: - - Nothing. - - OUTPUT: - - The hash of this finite state machine. + OUTPUT: the hash of this finite state machine EXAMPLES:: @@ -3592,11 +3476,9 @@ def __or__(self, other): INPUT: - - ``other`` -- a finite state machine. - - OUTPUT: + - ``other`` -- a finite state machine - A new finite state machine. + OUTPUT: a new finite state machine .. SEEALSO:: @@ -3917,13 +3799,9 @@ def __call__(self, *args, **kwargs): def __bool__(self): """ - Return True if the finite state machine consists of at least + Return ``True`` if the finite state machine consists of at least one state. - OUTPUT: - - True or False. - TESTS:: sage: bool(FiniteStateMachine()) @@ -3938,13 +3816,11 @@ def __eq__(self, other): INPUT: - - ``self`` -- a finite state machine. - - - ``other`` -- a finite state machine. + - ``self`` -- a finite state machine - OUTPUT: + - ``other`` -- a finite state machine - ``True`` or ``False``. + OUTPUT: boolean Note that this function compares all attributes of a state (by using :meth:`FSMState.fully_equal`) except for colors. Colors @@ -4016,17 +3892,15 @@ def __eq__(self, other): def __ne__(self, other): """ - Tests for inequality, complement of :meth:`.__eq__`. + Test for inequality, complement of :meth:`.__eq__`. INPUT: - - ``self`` -- a finite state machine. + - ``self`` -- a finite state machine - - ``other`` -- a finite state machine. - - OUTPUT: + - ``other`` -- a finite state machine - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -4050,11 +3924,9 @@ def __contains__(self, item): INPUT: - - ``item`` -- a state or a transition. + - ``item`` -- a state or a transition - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -4075,7 +3947,7 @@ def __contains__(self, item): def is_Markov_chain(self, is_zero=None): """ - Checks whether ``self`` is a Markov chain where the transition + Check whether ``self`` is a Markov chain where the transition probabilities are modeled as input labels. INPUT: @@ -4087,9 +3959,7 @@ def is_Markov_chain(self, is_zero=None): for zero, e.g. in the case of symbolic probabilities, see the examples below. - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean :attr:`on_duplicate_transition` must be :func:`duplicate_transition_add_input`, the sum of the input weights @@ -4197,16 +4067,10 @@ def default_is_zero(expression): def _repr_(self): """ - Represents the finite state machine as "Finite state machine + Represent the finite state machine as "Finite state machine with n states" where n is the number of states. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -4226,7 +4090,6 @@ def _repr_(self): 43 sage: F Finite state machine with 2 states - """ if not self._states_: return "Empty finite state machine" @@ -4245,7 +4108,7 @@ def format_letter_negative(self, letter): INPUT: - - ``letter`` -- anything. + - ``letter`` -- anything OUTPUT: @@ -4275,7 +4138,7 @@ def format_transition_label_reversed(self, word): INPUT: - - ``word`` -- list of letters. + - ``word`` -- list of letters OUTPUT: @@ -4419,7 +4282,7 @@ def latex_options(self, INPUT: - - ``coordinates`` -- a dictionary or a function mapping labels + - ``coordinates`` -- dictionary or a function mapping labels of states to pairs interpreted as coordinates. If no coordinates are given, states a placed equidistantly on a circle of radius `3`. See also :meth:`.set_coordinates`. @@ -4440,11 +4303,11 @@ def latex_options(self, typesetting in LaTeX's mathematics mode. If not given, :meth:`.default_format_transition_label` is used. - - ``loop_where`` -- a dictionary or a function mapping labels of + - ``loop_where`` -- dictionary or a function mapping labels of initial states to one of ``'above'``, ``'left'``, ``'below'``, ``'right'``. If not given, ``'above'`` is used. - - ``initial_where`` -- a dictionary or a function mapping + - ``initial_where`` -- dictionary or a function mapping labels of initial states to one of ``'above'``, ``'left'``, ``'below'``, ``'right'``. If not given, TikZ' default (currently ``'left'``) is used. @@ -4454,13 +4317,13 @@ def latex_options(self, double'`` is used unless there are non-empty final output words. - - ``accepting_distance`` -- a string giving a LaTeX length + - ``accepting_distance`` -- string giving a LaTeX length used for the length of the arrow leading from a final state. If not given, TikZ' default (currently ``'3ex'``) is used unless there are non-empty final output words, in which case ``'7ex'`` is used. - - ``accepting_where`` -- a dictionary or a function mapping + - ``accepting_where`` -- dictionary or a function mapping labels of final states to one of ``'above'``, ``'left'``, ``'below'``, ``'right'``. If not given, TikZ' default (currently ``'right'``) is used. If the final state has a @@ -4472,9 +4335,7 @@ def latex_options(self, implicitly implies ``accepting_style='accepting by arrow'``. If not given, the default ``False`` is used. - OUTPUT: - - Nothing. + OUTPUT: nothing As TikZ (cf. the :wikipedia:`PGF/TikZ`) is used to typeset the graphics, the syntax is oriented on TikZ' syntax. @@ -4767,9 +4628,7 @@ def _latex_(self): r""" Return a LaTeX code for the graph of the finite state machine. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -4973,9 +4832,7 @@ def _latex_transition_label_(self, transition, - ``format_function`` -- a function formatting the labels - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -4993,16 +4850,14 @@ def set_coordinates(self, coordinates, default=True): INPUT: - - ``coordinates`` -- a dictionary or a function mapping labels - of states to pairs interpreted as coordinates. + - ``coordinates`` -- dictionary or a function mapping labels + of states to pairs interpreted as coordinates - - ``default`` -- If ``True``, then states not given by + - ``default`` -- if ``True``, then states not given by ``coordinates`` get a default position on a circle of radius 3. - OUTPUT: - - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -5076,18 +4931,16 @@ def adjacency_matrix(self, input=None, INPUT: - - ``input`` -- Only transitions with input label ``input`` are - respected. + - ``input`` -- only transitions with input label ``input`` are + respected - - ``entry`` -- The function ``entry`` takes a transition and the + - ``entry`` -- the function ``entry`` takes a transition and the return value is written in the matrix as the entry ``(transition.from_state, transition.to_state)``. The default value (``None``) of entry takes the variable ``x`` to the power of the sum of the output word of the transition. - OUTPUT: - - A matrix. + OUTPUT: a matrix If any label of a state is not an integer, the finite state machine is relabeled at the beginning. If there are more than @@ -5145,7 +4998,6 @@ def adjacency_matrix(self, input=None, [0 1 0] [0 0 1] [1 1 0] - """ if entry is None: @@ -5186,13 +5038,11 @@ def determine_input_alphabet(self, reset=True): INPUT: - - ``reset`` -- a boolean (default: ``True``). If ``True``, then + - ``reset`` -- boolean (default: ``True``); if ``True``, then the existing input alphabet is erased, otherwise new letters are appended to the existing alphabet. - OUTPUT: - - Nothing. + OUTPUT: nothing After this operation the input alphabet of this finite state machine is a list of letters. @@ -5235,13 +5085,11 @@ def determine_output_alphabet(self, reset=True): INPUT: - - ``reset`` -- a boolean (default: ``True``). If ``True``, then + - ``reset`` -- boolean (default: ``True``); if ``True``, then the existing output alphabet is erased, otherwise new letters are appended to the existing alphabet. - OUTPUT: - - Nothing. + OUTPUT: nothing After this operation the output alphabet of this finite state machine is a list of letters. @@ -5288,13 +5136,11 @@ def determine_alphabets(self, reset=True): INPUT: - - ``reset`` -- If reset is ``True``, then the existing input + - ``reset`` -- if reset is ``True``, then the existing input and output alphabets are erased, otherwise new letters are appended to the existing alphabets. - OUTPUT: - - Nothing. + OUTPUT: nothing After this operation the input alphabet and the output alphabet of this finite state machine are a list of letters. @@ -5332,9 +5178,7 @@ def states(self): """ Return the states of the finite state machine. - OUTPUT: - - The states of the finite state machine as list. + OUTPUT: the states of the finite state machine as list EXAMPLES:: @@ -5348,9 +5192,7 @@ def iter_states(self): """ Return an iterator of the states. - OUTPUT: - - An iterator of the states of the finite state machine. + OUTPUT: an iterator of the states of the finite state machine EXAMPLES:: @@ -5366,12 +5208,10 @@ def transitions(self, from_state=None): INPUT: - - ``from_state`` -- (default: ``None``) If ``from_state`` is - given, then a list of transitions starting there is given. + - ``from_state`` -- (default: ``None``) if ``from_state`` is + given, then a list of transitions starting there is given - OUTPUT: - - A list of all transitions. + OUTPUT: list of all transitions EXAMPLES:: @@ -5388,12 +5228,10 @@ def iter_transitions(self, from_state=None): INPUT: - - ``from_state`` -- (default: ``None``) If ``from_state`` is - given, then a list of transitions starting there is given. - - OUTPUT: + - ``from_state`` -- (default: ``None``) if ``from_state`` is + given, then a list of transitions starting there is given - An iterator of all transitions. + OUTPUT: an iterator of all transitions EXAMPLES:: @@ -5417,9 +5255,7 @@ def _iter_transitions_all_(self): """ Return an iterator over all transitions. - OUTPUT: - - An iterator over all transitions. + OUTPUT: an iterator over all transitions EXAMPLES:: @@ -5435,10 +5271,6 @@ def initial_states(self): """ Return a list of all initial states. - OUTPUT: - - A list of all initial states. - EXAMPLES:: sage: from sage.combinat.finite_state_machine import FSMState @@ -5454,9 +5286,7 @@ def iter_initial_states(self): """ Return an iterator of the initial states. - OUTPUT: - - An iterator over all initial states. + OUTPUT: an iterator over all initial states EXAMPLES:: @@ -5473,10 +5303,6 @@ def final_states(self): """ Return a list of all final states. - OUTPUT: - - A list of all final states. - EXAMPLES:: sage: from sage.combinat.finite_state_machine import FSMState @@ -5493,9 +5319,7 @@ def iter_final_states(self): """ Return an iterator of the final states. - OUTPUT: - - An iterator over all initial states. + OUTPUT: an iterator over all initial states EXAMPLES:: @@ -5515,15 +5339,13 @@ def state(self, state): INPUT: - - ``state`` -- If ``state`` is not an instance of + - ``state`` -- if ``state`` is not an instance of :class:`FSMState`, then it is assumed that it is the label of a state. - OUTPUT: - - The state of the finite state machine corresponding to ``state``. + OUTPUT: the state of the finite state machine corresponding to ``state`` - If no state is found, then a :class:`LookupError` is thrown. + If no state is found, then a :exc:`LookupError` is thrown. EXAMPLES:: @@ -5560,16 +5382,14 @@ def transition(self, transition): INPUT: - - ``transition`` -- If ``transition`` is not an instance of + - ``transition`` -- if ``transition`` is not an instance of :class:`FSMTransition`, then it is assumed that it is a - tuple ``(from_state, to_state, word_in, word_out)``. + tuple ``(from_state, to_state, word_in, word_out)`` - OUTPUT: + OUTPUT: the transition of the finite state machine corresponding + to ``transition`` - The transition of the finite state machine corresponding - to ``transition``. - - If no transition is found, then a :class:`LookupError` is thrown. + If no transition is found, then a :exc:`LookupError` is thrown. EXAMPLES:: @@ -5601,9 +5421,7 @@ def has_state(self, state): - ``state`` can be a :class:`FSMState` or a label of a state. - OUTPUT: - - True or False. + OUTPUT: boolean EXAMPLES:: @@ -5625,9 +5443,7 @@ def has_transition(self, transition): - ``transition`` has to be a :class:`FSMTransition`. - OUTPUT: - - True or False. + OUTPUT: boolean EXAMPLES:: @@ -5653,9 +5469,7 @@ def has_initial_state(self, state): - ``state`` can be a :class:`FSMState` or a label. - OUTPUT: - - True or False. + OUTPUT: boolean EXAMPLES:: @@ -5672,9 +5486,7 @@ def has_initial_states(self): """ Return whether the finite state machine has an initial state. - OUTPUT: - - True or False. + OUTPUT: boolean EXAMPLES:: @@ -5692,9 +5504,7 @@ def has_final_state(self, state): - ``state`` can be a :class:`FSMState` or a label. - OUTPUT: - - True or False. + OUTPUT: boolean EXAMPLES:: @@ -5710,9 +5520,7 @@ def has_final_states(self): """ Return whether the finite state machine has a final state. - OUTPUT: - - True or False. + OUTPUT: boolean EXAMPLES:: @@ -5729,9 +5537,7 @@ def is_deterministic(self): """ Return whether the finite finite state machine is deterministic. - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean A finite state machine is considered to be deterministic if each transition has input label of length one and for each @@ -5785,9 +5591,7 @@ def is_complete(self): """ Return whether the finite state machine is complete. - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean A finite state machine is considered to be complete if each transition has an input label of length one and for each @@ -5894,10 +5698,10 @@ def process(self, *args, **kwargs): what to do (e.g. if a non-deterministic machine returns more than one path, then the output is returned in list form). - - ``only_accepted`` -- (default: ``False``) a boolean. If set, - then the first argument in the output is guaranteed to be - ``True`` (if the output is a list, then the first argument - of each element will be ``True``). + - ``only_accepted`` -- boolean (default: ``False``); if set, then the + first argument in the output is guaranteed to be ``True`` (if the + output is a list, then the first argument of each element will be + ``True``) - ``always_include_output`` -- if set (not by default), always include the output. This is inconsequential for a @@ -5909,35 +5713,31 @@ def process(self, *args, **kwargs): output (which is in form of a list) to something more readable. By default (``None``) identity is used here. - - ``check_epsilon_transitions`` -- (default: ``True``) a - boolean. If ``False``, then epsilon transitions are not - taken into consideration during process. + - ``check_epsilon_transitions`` -- boolean (default: ``True``); if + ``False``, then epsilon transitions are not taken into consideration + during process - - ``write_final_word_out`` -- (default: ``True``) a boolean - specifying whether the final output words should be written - or not. + - ``write_final_word_out`` -- boolean (default: ``True``); whether the + final output words should be written or not - - ``use_multitape_input`` -- (default: ``False``) a - boolean. If ``True``, then the multi-tape mode of the - process iterator is activated. See also the notes below for - multi-tape machines. + - ``use_multitape_input`` -- boolean (default: ``False``); if ``True``, + then the multi-tape mode of the process iterator is activated. See + also the notes below for multi-tape machines. - - ``process_all_prefixes_of_input`` -- (default: ``False``) a - boolean. If ``True``, then each prefix of the input word is - processed (instead of processing the whole input word at - once). Consequently, there is an output generated for each - of these prefixes. + - ``process_all_prefixes_of_input`` -- boolean (default: ``False``); if + ``True``, then each prefix of the input word is processed (instead of + processing the whole input word at once). Consequently, there is an + output generated for each of these prefixes. - ``process_iterator_class`` -- (default: ``None``) a class inherited from :class:`FSMProcessIterator`. If ``None``, then :class:`FSMProcessIterator` is taken. An instance of this class is created and is used during the processing. - - ``automatic_output_type`` -- (default: ``False``) a boolean. - If set and the input has a parent, then the - output will have the same parent. If the input does not have - a parent, then the output will be of the same type as the - input. + - ``automatic_output_type`` -- boolean (default: ``False``); if set and + the input has a parent, then the output will have the same parent. If + the input does not have a parent, then the output will be of the same + type as the input. OUTPUT: @@ -6216,13 +6016,11 @@ def _process_convert_output_(self, output_data, **kwargs): INPUT: - - ``output_data`` -- a triple. - - - ``full_output`` -- a boolean. + - ``output_data`` -- a triple - OUTPUT: + - ``full_output`` -- boolean - The converted output. + OUTPUT: the converted output This function is overridden in :class:`Automaton` and :class:`Transducer`. @@ -6252,7 +6050,7 @@ def iter_process(self, input_tape=None, initial_state=None, INPUT: - - ``iterator_type`` -- If ``None`` (default), then + - ``iterator_type`` -- if ``None`` (default), then an instance of :class:`FSMProcessIterator` is returned. If this is ``'simple'`` only an iterator over one output is returned (an exception is raised if this is not the case, i.e., @@ -6260,9 +6058,7 @@ def iter_process(self, input_tape=None, initial_state=None, See :meth:`process` for a description of the other parameters. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES: @@ -6406,16 +6202,14 @@ def iter_process(self, input_tape=None, initial_state=None, def _iter_process_simple_(self, iterator): r""" - Converts a :class:`process iterator ` to a simpler + Convert a :class:`process iterator ` to a simpler iterator, which only outputs the written letters. INPUT: - - ``iterator`` -- in instance of :class:`FSMProcessIterator`. + - ``iterator`` -- in instance of :class:`FSMProcessIterator` - OUTPUT: - - A generator. + OUTPUT: a generator An exception is raised if the process branches. @@ -6498,7 +6292,7 @@ def _iter_process_simple_(self, iterator): def add_state(self, state): """ - Adds a state to the finite state machine and returns the new + Add a state to the finite state machine and returns the new state. If the state already exists, that existing state is returned. @@ -6508,9 +6302,7 @@ def add_state(self, state): :class:`FSMState` or, otherwise, a label of a state. - OUTPUT: - - The new or existing state. + OUTPUT: the new or existing state EXAMPLES:: @@ -6539,15 +6331,13 @@ def add_state(self, state): def add_states(self, states): """ - Adds several states. See add_state for more information. + Add several states. See add_state for more information. INPUT: - - ``states`` -- a list of states or iterator over states. - - OUTPUT: + - ``states`` -- list of states or iterator over states - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -6561,7 +6351,7 @@ def add_states(self, states): def add_transition(self, *args, **kwargs): """ - Adds a transition to the finite state machine and returns the + Add a transition to the finite state machine and returns the new transition. If the transition already exists, the return value of @@ -6650,15 +6440,13 @@ def add_transition(self, *args, **kwargs): def _add_fsm_transition_(self, t): """ - Adds a transition. + Add a transition. INPUT: - - ``t`` -- an instance of :class:`FSMTransition`. + - ``t`` -- an instance of :class:`FSMTransition` - OUTPUT: - - The new transition. + OUTPUT: the new transition TESTS:: @@ -6681,24 +6469,22 @@ def _add_fsm_transition_(self, t): def add_from_transition_function(self, function, initial_states=None, explore_existing_states=True): """ - Constructs a finite state machine from a transition function. + Construct a finite state machine from a transition function. INPUT: - ``function`` may return a tuple (new_state, output_word) or a - list of such tuples. + list of such tuples - - ``initial_states`` -- If no initial states are given, the - already existing initial states of self are taken. + - ``initial_states`` -- if no initial states are given, the + already existing initial states of ``self`` are taken - - If ``explore_existing_states`` is True (default), then - already existing states in self (e.g. already given final - states) will also be processed if they are reachable from - the initial states. - - OUTPUT: + - ``explore_existing_states`` -- boolean (default: ``True``); if + ``True`` (default), then already existing states in ``self`` (e.g. + already given final states) will also be processed if they are + reachable from the initial statess - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -6833,7 +6619,7 @@ def add_from_transition_function(self, function, initial_states=None, def add_transitions_from_function(self, function, labels_as_input=True): """ - Adds one or more transitions if ``function(state, state)`` + Add one or more transitions if ``function(state, state)`` says that there are some. INPUT: @@ -6851,9 +6637,7 @@ def add_transitions_from_function(self, function, labels_as_input=True): - ``label_as_input`` -- (default: ``True``) - OUTPUT: - - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -6897,7 +6681,6 @@ def add_transitions_from_function(self, function, labels_as_input=True): is expected to return a pair (word_in, word_out) or a list of such pairs. For states 0 and 0 however, it returned 1, which is not acceptable. - """ for s_from in self.iter_states(): for s_to in self.iter_states(): @@ -6933,16 +6716,14 @@ def add_transitions_from_function(self, function, labels_as_input=True): def delete_transition(self, t): """ - Deletes a transition by removing it from the list of transitions of + Delete a transition by removing it from the list of transitions of the state, where the transition starts. INPUT: - - ``t`` -- a transition. - - OUTPUT: + - ``t`` -- a transition - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -6956,15 +6737,13 @@ def delete_transition(self, t): def delete_state(self, s): """ - Deletes a state and all transitions coming or going to this state. + Delete a state and all transitions coming or going to this state. INPUT: - - ``s`` -- a label of a state or an :class:`FSMState`. + - ``s`` -- a label of a state or an :class:`FSMState` - OUTPUT: - - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -7015,11 +6794,9 @@ def epsilon_successors(self, state): INPUT: - ``state`` -- the state whose epsilon successors should be - determined. + determined - OUTPUT: - - A dictionary mapping states to a list of output words. + OUTPUT: a dictionary mapping states to a list of output words The states in the output are the epsilon successors of ``state``. Each word of the list of output words is a word @@ -7050,20 +6827,16 @@ def epsilon_successors(self, state): def accessible_components(self): """ Return a new finite state machine with the accessible states - of self and all transitions between those states. - - INPUT: - - Nothing. + of ``self`` and all transitions between those states. OUTPUT: - A finite state machine with the accessible states of self and + A finite state machine with the accessible states of ``self`` and all transitions between those states. A state is accessible if there is a directed path from an - initial state to the state. If self has no initial states then - a copy of the finite state machine self is returned. + initial state to the state. If ``self`` has no initial states then + a copy of the finite state machine ``self`` is returned. EXAMPLES:: @@ -7164,7 +6937,7 @@ def disjoint_union(self, other): INPUT: - - ``other`` -- a :class:`FiniteStateMachine`. + - ``other`` -- a :class:`FiniteStateMachine` OUTPUT: @@ -7323,7 +7096,7 @@ def concatenation(self, other): INPUT: - - ``other`` -- a :class:`FiniteStateMachine`. + - ``other`` -- a :class:`FiniteStateMachine` OUTPUT: @@ -7632,31 +7405,31 @@ def product_FiniteStateMachine(self, other, function, INPUT: - ``other`` -- a finite state machine (for `d=2`) or a list - (or iterable) of `d-1` finite state machines. + (or iterable) of `d-1` finite state machines - ``function`` has to accept `d` transitions from `A_j` to `B_j` for `j\in\{1, \ldots, d\}` and returns a pair ``(word_in, word_out)`` which is the label of the transition `A=(A_1, \ldots, A_d)` to `B=(B_1, \ldots, B_d)`. If there is no transition from `A` to `B`, - then ``function`` should raise a :class:`LookupError`. + then ``function`` should raise a :exc:`LookupError`. - - ``new_input_alphabet`` (optional) -- the new input alphabet - as a list. + - ``new_input_alphabet`` -- (optional) the new input alphabet + as a list - - ``only_accessible_components`` -- If ``True`` (default), then + - ``only_accessible_components`` -- if ``True`` (default), then the result is piped through :meth:`.accessible_components`. If no ``new_input_alphabet`` is given, it is determined by :meth:`.determine_alphabets`. - - ``final_function`` -- A function mapping `d` final states of + - ``final_function`` -- a function mapping `d` final states of the original finite state machines to the final output of the corresponding state in the new finite state machine. By default, the final output is the empty word if both final outputs of the constituent states are empty; otherwise, a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. - - ``new_class`` -- Class of the new finite state machine. By - default (``None``), the class of ``self`` is used. + - ``new_class`` -- class of the new finite state machine. By + default (``None``), the class of ``self`` is used OUTPUT: @@ -7901,7 +7674,7 @@ def composition(self, other, algorithm=None, - ``algorithm`` -- can be one of the following - - ``direct`` -- The composition is calculated directly. + - ``direct`` -- the composition is calculated directly There can be arbitrarily many initial and final states, but the input and output labels must have length `1`. @@ -7910,9 +7683,9 @@ def composition(self, other, algorithm=None, The output of ``other`` is fed into ``self``. - - ``explorative`` -- An explorative algorithm is used. + - ``explorative`` -- an explorative algorithm is used - The input alphabet of self has to be specified. + The input alphabet of ``self`` has to be specified. .. WARNING:: @@ -7923,15 +7696,12 @@ def composition(self, other, algorithm=None, there are output words of ``other`` or input words of ``self`` of length greater than `1`). - OUTPUT: - - A new transducer. + OUTPUT: a new transducer The labels of the new finite state machine are pairs of states of the original finite state machines. The color of a new state is the tuple of colors of the constituent states. - EXAMPLES:: sage: F = Transducer([('A', 'B', 1, 0), ('B', 'A', 0, 1)], @@ -8349,11 +8119,9 @@ def composition_transition(states, input): def input_projection(self): """ Return an automaton where the output of each transition of - self is deleted. + ``self`` is deleted. - OUTPUT: - - An automaton. + OUTPUT: an automaton EXAMPLES:: @@ -8372,9 +8140,7 @@ def output_projection(self): Return a automaton where the input of each transition of self is deleted and the new input is the original output. - OUTPUT: - - An automaton. + OUTPUT: an automaton EXAMPLES:: @@ -8413,11 +8179,9 @@ def projection(self, what='input'): INPUT: - - ``what`` -- (default: ``input``) either ``input`` or ``output``. - - OUTPUT: + - ``what`` -- (default: ``input``) either ``input`` or ``output`` - An automaton. + OUTPUT: an automaton EXAMPLES:: @@ -8480,12 +8244,8 @@ def transposition(self, reverse_output_labels=True): INPUT: - - ``reverse_output_labels`` -- a boolean (default: ``True``): whether to reverse - output labels. - - OUTPUT: - - A new finite state machine. + - ``reverse_output_labels`` -- boolean (default: ``True``); whether to + reverse output labels EXAMPLES:: @@ -8576,13 +8336,11 @@ def transposition(self, reverse_output_labels=True): def split_transitions(self): """ - Return a new transducer, where all transitions in self with input + Return a new transducer, where all transitions in ``self`` with input labels consisting of more than one letter are replaced by a path of the corresponding length. - OUTPUT: - - A new transducer. + OUTPUT: a new transducer EXAMPLES:: @@ -8663,8 +8421,8 @@ def completion(self, sink=None): INPUT: - ``sink`` -- either an instance of :class:`FSMState` or a label - for the sink (default: ``None``). If ``None``, the least - available non-zero integer is used. + for the sink (default: ``None``); if ``None``, the least + available nonzero integer is used OUTPUT: @@ -8817,13 +8575,7 @@ def prepone_output(self): transition to the earliest possible preceding transition of the path. - INPUT: - - Nothing. - - OUTPUT: - - Nothing. + OUTPUT: nothing Apply the following to each state `s` (except initial states) of the finite state machine as often as possible: @@ -8983,10 +8735,6 @@ def equivalence_classes(self): r""" Return a list of equivalence classes of states. - OUTPUT: - - A list of equivalence classes of states. - Two states `a` and `b` are equivalent if and only if there is a bijection `\varphi` between paths starting at `a` and paths starting at `b` with the following properties: Let `p_a` be a @@ -9087,9 +8835,7 @@ def quotient(self, classes): - ``classes`` is a list of equivalence classes of states. - OUTPUT: - - A finite state machine. + OUTPUT: a finite state machine The labels of the new states are tuples of states of the ``self``, corresponding to ``classes``. @@ -9202,10 +8948,6 @@ def merged_transitions(self): Merges transitions which have the same ``from_state``, ``to_state`` and ``word_out`` while adding their ``word_in``. - INPUT: - - Nothing. - OUTPUT: A finite state machine with merged transitions. If no mergers occur, @@ -9273,13 +9015,7 @@ def markov_chain_simplification(self): Consider ``self`` as Markov chain with probabilities as input labels and simplify it. - INPUT: - - Nothing. - - OUTPUT: - - Simplified version of ``self``. + OUTPUT: simplified version of ``self`` EXAMPLES:: @@ -9310,7 +9046,7 @@ def markov_chain_simplification(self): def with_final_word_out(self, letters, allow_non_final=True): """ - Constructs a new finite state machine with final output words + Construct a new finite state machine with final output words for all states by implicitly reading trailing letters until a final state is reached. @@ -9320,15 +9056,12 @@ def with_final_word_out(self, letters, allow_non_final=True): list of such elements. This is repeated cyclically when needed. - - ``allow_non_final`` -- a boolean (default: ``True``) which - indicates whether we allow that some states may be non-final - in the resulting finite state machine. I.e., if ``False`` then - each state has to have a path to a final state with input - label matching ``letters``. - - OUTPUT: + - ``allow_non_final`` -- boolean (default: ``True``); whether we allow + that some states may be non-final in the resulting finite state + machine. I.e., if ``False`` then each state has to have a path to a + final state with input label matching ``letters``. - A finite state machine. + OUTPUT: a finite state machine The inplace version of this function is :meth:`.construct_final_word_out`. @@ -9664,14 +9397,12 @@ def graph(self, edge_labels='words_in_out'): INPUT: - - ``edge_label``: (default: ``'words_in_out'``) can be - - ``'words_in_out'`` (labels will be strings ``'i|o'``) - - a function with which takes as input a transition - and outputs (returns) the label - - OUTPUT: + - ``edge_label`` -- (default: ``'words_in_out'``) can be + - ``'words_in_out'`` (labels will be strings ``'i|o'``) + - a function with which takes as input a transition + and outputs (returns) the label - A :class:`directed graph `. + OUTPUT: a :class:`directed graph ` EXAMPLES:: @@ -9706,9 +9437,9 @@ def graph(self, edge_labels='words_in_out'): transitions = state.transitions if not transitions: isolated_vertices.append(state.label()) - for t in transitions: - graph_data.append((t.from_state.label(), t.to_state.label(), - label_fct(t))) + graph_data.extend((t.from_state.label(), t.to_state.label(), + label_fct(t)) + for t in transitions) G = DiGraph(graph_data, multiedges=True, loops=True) G.add_vertices(isolated_vertices) @@ -9721,13 +9452,7 @@ def plot(self): Plots a graph of the finite state machine with labeled vertices and labeled edges. - INPUT: - - Nothing. - - OUTPUT: - - A plot of the graph of the finite state machine. + OUTPUT: a plot of the graph of the finite state machine TESTS:: @@ -9738,23 +9463,21 @@ def plot(self): def predecessors(self, state, valid_input=None): """ - Lists all predecessors of a state. + List all predecessors of a state. INPUT: - ``state`` -- the state from which the predecessors should be - listed. + listed - - ``valid_input`` -- If ``valid_input`` is a list, then we + - ``valid_input`` -- if ``valid_input`` is a list, then we only consider transitions whose input labels are contained in ``valid_input``. ``state`` has to be a :class:`FSMState` (not a label of a state). If input labels of length larger than `1` are used, then ``valid_input`` has to be a list of lists. - OUTPUT: - - A list of states. + OUTPUT: list of states EXAMPLES:: @@ -9801,14 +9524,12 @@ def number_of_words(self, variable=None, INPUT: - ``variable`` -- a symbol denoting the length of the words, - by default `n`. - - - ``base_ring`` -- Ring (default: ``QQbar``) in which to - compute the eigenvalues. + by default `n` - OUTPUT: + - ``base_ring`` -- ring (default: ``QQbar``) in which to + compute the eigenvalues - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -9945,11 +9666,9 @@ def asymptotic_moments(self, variable=None): INPUT: - ``variable`` -- a symbol denoting the length of the input, - by default `n`. - - OUTPUT: + (default: `n`) - A dictionary consisting of + OUTPUT: a dictionary consisting of - ``expectation`` -- `e n + \operatorname{Order}(1)`, - ``variance`` -- `v n + \operatorname{Order}(1)`, @@ -10441,7 +10160,7 @@ def moments_waiting_time(self, test=bool, is_zero=None, :meth:`is_Markov_chain`. This parameter only affects the input of the Markov chain. - - ``expectation_only`` -- (default: ``False``) if set, the + - ``expectation_only`` -- boolean (default: ``False``); if set, the variance is not computed (in order to save time). By default, the variance is computed. @@ -10790,8 +10509,8 @@ def entry(transition): else: base_ring = transition_matrix.parent().base_ring() from sage.rings.polynomial.multi_polynomial_ring \ - import is_MPolynomialRing - if is_MPolynomialRing(base_ring): + import MPolynomialRing_base + if isinstance(base_ring, MPolynomialRing_base): # if base_ring is already a multivariate polynomial # ring, extend it instead of creating a univariate # polynomial ring over a polynomial ring. This @@ -10819,9 +10538,7 @@ def is_monochromatic(self): """ Check whether the colors of all states are equal. - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: @@ -10842,7 +10559,7 @@ def language(self, max_length=None, **kwargs): INPUT: - - ``max_length`` -- an integer or ``None`` (default). Only + - ``max_length`` -- integer or ``None`` (default). Only output words which come from inputs of length at most ``max_length`` will be considered. If ``None``, then this iterates over all possible words without length restrictions. @@ -10851,9 +10568,7 @@ def language(self, max_length=None, **kwargs): iterator `. See :meth:`process` for a description. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -10935,7 +10650,7 @@ def language(self, max_length=None, **kwargs): def is_Automaton(FSM): """ - Tests whether or not ``FSM`` inherits from :class:`Automaton`. + Test whether or not ``FSM`` inherits from :class:`Automaton`. TESTS:: @@ -11014,16 +10729,10 @@ def __init__(self, *args, **kwargs): def _repr_(self): """ - Represents the finite state machine as "Automaton with n + Represent the finite state machine as "Automaton with n states" where n is the number of states. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -11044,7 +10753,6 @@ def _repr_(self): 43 sage: A Automaton with 2 states - """ if not self._states_: return "Empty automaton" @@ -11064,9 +10772,7 @@ def _latex_transition_label_(self, transition, - ``format_function`` -- a function formatting the labels - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -11098,7 +10804,7 @@ def intersection(self, other, only_accessible_components=True): - ``other`` -- an automaton - - ``only_accessible_components`` -- If ``True`` (default), then + - ``only_accessible_components`` -- if ``True`` (default), then the result is piped through :meth:`.accessible_components`. If no ``new_input_alphabet`` is given, it is determined by :meth:`.determine_alphabets`. @@ -11193,9 +10899,7 @@ def determinisation(self): Return a deterministic automaton which accepts the same input words as the original one. - OUTPUT: - - A new automaton, which is deterministic. + OUTPUT: a new automaton, which is deterministic The labels of the states of the new automaton are frozensets of states of ``self``. The color of a new state is the @@ -11373,15 +11077,13 @@ def minimization(self, algorithm=None): INPUT: - - ``algorithm`` -- Either Moore's algorithm (by + - ``algorithm`` -- either Moore's algorithm (by ``algorithm='Moore'`` or as default for deterministic automata) or Brzozowski's algorithm (when ``algorithm='Brzozowski'`` or when the automaton is not deterministic) is used. - OUTPUT: - - A new automaton. + OUTPUT: a new automaton The resulting automaton is deterministic and has a minimal number of states. @@ -11487,9 +11189,7 @@ def complement(self): r""" Return the complement of this automaton. - OUTPUT: - - An :class:`Automaton`. + OUTPUT: an :class:`Automaton` If this automaton recognizes language `\mathcal{L}` over an input alphabet `\mathcal{A}`, then the complement recognizes @@ -11540,7 +11240,7 @@ def is_equivalent(self, other): INPUT: - - ``other`` -- an :class:`Automaton`. + - ``other`` -- an :class:`Automaton` EXAMPLES:: @@ -11606,12 +11306,12 @@ def process(self, *args, **kwargs): what to do (e.g. if a non-deterministic machine returns more than one path, then the output is returned in list form). - - ``only_accepted`` -- (default: ``False``) a boolean. If set, + - ``only_accepted`` -- boolean (default: ``False``); if set, then the first argument in the output is guaranteed to be ``True`` (if the output is a list, then the first argument of each element will be ``True``). - - ``full_output`` -- (default: ``True``) a boolean. If set, + - ``full_output`` -- boolean (default: ``True``); if set, then the full output is given, otherwise only whether the sequence is accepted or not (the first entry below only). @@ -11625,24 +11325,21 @@ def process(self, *args, **kwargs): output (which is in form of a list) to something more readable. By default (``None``) identity is used here. - - ``check_epsilon_transitions`` -- (default: ``True``) a - boolean. If ``False``, then epsilon transitions are not - taken into consideration during process. + - ``check_epsilon_transitions`` -- boolean (default: ``True``); a + boolean. If ``False``, then epsilon transitions are not taken into + consideration during process. - - ``write_final_word_out`` -- (default: ``True``) a boolean - specifying whether the final output words should be written - or not. + - ``write_final_word_out`` -- boolean (default: ``True``); whether the + final output words should be written or not - - ``use_multitape_input`` -- (default: ``False``) a - boolean. If ``True``, then the multi-tape mode of the - process iterator is activated. See also the notes below for - multi-tape machines. + - ``use_multitape_input`` -- boolean (default: ``False``); if ``True``, + then the multi-tape mode of the process iterator is activated. See + also the notes below for multi-tape machines. - - ``process_all_prefixes_of_input`` -- (default: ``False``) a - boolean. If ``True``, then each prefix of the input word is - processed (instead of processing the whole input word at - once). Consequently, there is an output generated for each - of these prefixes. + - ``process_all_prefixes_of_input`` -- boolean (default: ``False``); if + ``True``, then each prefix of the input word is processed (instead of + processing the whole input word at once). Consequently, there is an + output generated for each of these prefixes. - ``process_iterator_class`` -- (default: ``None``) a class inherited from :class:`FSMProcessIterator`. If ``None``, @@ -11826,17 +11523,15 @@ def _process_convert_output_(self, output_data, **kwargs): INPUT: - - ``output_data`` -- a triple. + - ``output_data`` -- a triple - - ``full_output`` -- a boolean. + - ``full_output`` -- boolean - ``always_include_output`` -- if set (not by default), always return a triple containing the (non-existing) output. This is for compatibility with transducers. - OUTPUT: - - The converted output. + OUTPUT: the converted output TESTS:: @@ -12010,9 +11705,7 @@ def with_output(self, word_out_function=None): If this is ``None``, then the output word will be equal to the input word of each transition. - OUTPUT: - - A transducer. + OUTPUT: a transducer EXAMPLES:: @@ -12098,7 +11791,7 @@ def language(self, max_length=None, **kwargs): INPUT: - - ``max_length`` -- an integer or ``None`` (default). Only + - ``max_length`` -- integer or ``None`` (default). Only inputs of length at most ``max_length`` will be considered. If ``None``, then this iterates over all possible words without length restrictions. @@ -12107,9 +11800,7 @@ def language(self, max_length=None, **kwargs): iterator `. See :meth:`process` for a description. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -12148,7 +11839,7 @@ def language(self, max_length=None, **kwargs): def is_Transducer(FSM): """ - Tests whether or not ``FSM`` inherits from :class:`Transducer`. + Test whether or not ``FSM`` inherits from :class:`Transducer`. TESTS:: @@ -12210,16 +11901,10 @@ class Transducer(FiniteStateMachine): def _repr_(self): """ - Represents the transducer as "Transducer with n states" where + Represent the transducer as "Transducer with n states" where n is the number of states. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -12239,7 +11924,6 @@ def _repr_(self): 43 sage: T Transducer with 2 states - """ if not self._states_: return "Empty transducer" @@ -12259,9 +11943,7 @@ def _latex_transition_label_(self, transition, - ``format_function`` -- a function formatting the labels - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -12294,7 +11976,7 @@ def intersection(self, other, only_accessible_components=True): - ``other`` -- a transducer - - ``only_accessible_components`` -- If ``True`` (default), then + - ``only_accessible_components`` -- if ``True`` (default), then the result is piped through :meth:`.accessible_components`. If no ``new_input_alphabet`` is given, it is determined by :meth:`.determine_alphabets`. @@ -12417,7 +12099,7 @@ def cartesian_product(self, other, only_accessible_components=True): - ``other`` -- a finite state machine (if `d=2`) or a list (or other iterable) of `d-1` finite state machines - - ``only_accessible_components`` -- If ``True`` (default), then + - ``only_accessible_components`` -- if ``True`` (default), then the result is piped through :meth:`.accessible_components`. If no ``new_input_alphabet`` is given, it is determined by :meth:`.determine_alphabets`. @@ -12593,9 +12275,7 @@ def simplification(self): """ Return a simplified transducer. - OUTPUT: - - A new transducer. + OUTPUT: a new transducer This function simplifies a transducer by Moore's algorithm, first moving common output labels of transitions leaving a @@ -12709,15 +12389,15 @@ def process(self, *args, **kwargs): what to do (e.g. if a non-deterministic machine returns more than one path, then the output is returned in list form). - - ``only_accepted`` -- (default: ``False``) a boolean. If set, + - ``only_accepted`` -- boolean (default: ``False``); if set, then the first argument in the output is guaranteed to be ``True`` (if the output is a list, then the first argument of each element will be ``True``). - - ``full_output`` -- (default: ``True``) a boolean. If set, + - ``full_output`` -- boolean (default: ``True``); if set, then the full output is given, otherwise only the generated output (the third entry below only). If the input is not - accepted, a :class:`ValueError` is raised. + accepted, a :exc:`ValueError` is raised. - ``always_include_output`` -- if set (not by default), always include the output. This is inconsequential for a @@ -12729,35 +12409,31 @@ def process(self, *args, **kwargs): output (which is in form of a list) to something more readable. By default (``None``) identity is used here. - - ``check_epsilon_transitions`` -- (default: ``True``) a - boolean. If ``False``, then epsilon transitions are not - taken into consideration during process. + - ``check_epsilon_transitions`` -- boolean (default: ``True``); if + ``False``, then epsilon transitions are not taken into consideration + during process - - ``write_final_word_out`` -- (default: ``True``) a boolean - specifying whether the final output words should be written - or not. + - ``write_final_word_out`` -- boolean (default: ``True``); whether the + final output words should be written or not - - ``use_multitape_input`` -- (default: ``False``) a - boolean. If ``True``, then the multi-tape mode of the - process iterator is activated. See also the notes below for - multi-tape machines. + - ``use_multitape_input`` -- boolean (default: ``False``); if ``True``, + then the multi-tape mode of the process iterator is activated. See + also the notes below for multi-tape machines. - - ``process_all_prefixes_of_input`` -- (default: ``False``) a - boolean. If ``True``, then each prefix of the input word is - processed (instead of processing the whole input word at - once). Consequently, there is an output generated for each - of these prefixes. + - ``process_all_prefixes_of_input`` -- boolean (default: ``False``); if + ``True``, then each prefix of the input word is processed (instead of + processing the whole input word at once). Consequently, there is an + output generated for each of these prefixes. - ``process_iterator_class`` -- (default: ``None``) a class inherited from :class:`FSMProcessIterator`. If ``None``, then :class:`FSMProcessIterator` is taken. An instance of this class is created and is used during the processing. - - ``automatic_output_type`` -- (default: ``False``) a boolean - If set and the input has a parent, then the - output will have the same parent. If the input does not have - a parent, then the output will be of the same type as the - input. + - ``automatic_output_type`` -- boolean (default: ``False``); if set and + the input has a parent, then the output will have the same parent. If + the input does not have a parent, then the output will be of the same + type as the input. OUTPUT: @@ -13006,13 +12682,11 @@ def _process_convert_output_(self, output_data, **kwargs): INPUT: - - ``output_data`` -- a triple. + - ``output_data`` -- a triple - - ``full_output`` -- a boolean. + - ``full_output`` -- boolean - OUTPUT: - - The converted output. + OUTPUT: the converted output TESTS:: @@ -13047,29 +12721,27 @@ class _FSMTapeCache_(SageObject): INPUT: - - ``tape_cache_manager`` -- a list of the existing instances of - :class:`_FSMTapeCache_`. ``self`` will be appended to this list. + - ``tape_cache_manager`` -- list of the existing instances of + :class:`_FSMTapeCache_`. ``self`` will be appended to this list - - ``tape`` -- a tuple or list of the input tracks (iterables). + - ``tape`` -- tuple or list of the input tracks (iterables) - - ``tape_ended`` -- a list of booleans (one for each track of the + - ``tape_ended`` -- list of booleans (one for each track of the tape), which indicate whether the track iterator has already raised - a ``StopIteration`` exception. + a ``StopIteration`` exception - - ``position`` -- a tuple of pairs `(p, t)` marking the current + - ``position`` -- tuple of pairs `(p, t)` marking the current positions of each of the input tracks. There `p` is the number of letter read from track `t`. The pairs of ``position`` are sorted first by `p` (smallest first) and then by `t`, i.e., lexicographically. - - ``is_multitape`` -- If ``True`` each entry of the + - ``is_multitape`` -- if ``True`` each entry of the input-word-tuple of a transition is interpreted as word for the corresponding input track. If ``False`` input-words are interpreted as an iterable of letters. - OUTPUT: - - A tape-cache. + OUTPUT: a tape-cache TESTS:: @@ -13140,9 +12812,7 @@ def _repr_(self): """ Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string Note that this representation depends on the parameter ``is_multitape`` of ``self``. @@ -13198,11 +12868,9 @@ def deepcopy(self, memo=None): INPUT: - - ``memo`` -- a dictionary. + - ``memo`` -- dictionary - OUTPUT: - - An instance of ``_FSMCacheTape_``. + OUTPUT: an instance of ``_FSMCacheTape_`` TESTS:: @@ -13230,7 +12898,7 @@ def read(self, track_number): INPUT: - - ``track_number`` -- an integer. + - ``track_number`` -- integer OUTPUT: @@ -13286,12 +12954,10 @@ def finished(self, track_number=None): INPUT: - - ``track_number`` -- an integer or ``None``. If ``None``, - then ``True`` is returned if all tracks are finished. + - ``track_number`` -- integer or ``None`` (default); if ``None``, + then ``True`` is returned if all tracks are finished - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean TESTS:: @@ -13349,18 +13015,16 @@ def preview_word(self, track_number=None, length=1, return_word=False): INPUT: - - ``track_number`` -- an integer or ``None``. If ``None``, - then a tuple of words (one from each track) is returned. - - - ``length`` -- (default: ``1``) the length of the word(s). + - ``track_number`` -- integer (default: ``None``); if ``None``, + then a tuple of words (one from each track) is returned - - ``return_word`` -- (default: ``False``) a boolean. If set, - then a word is returned, otherwise a single letter (in which - case ``length`` has to be ``1``). + - ``length`` -- (default: ``1``) the length of the word(s) - OUTPUT: + - ``return_word`` -- boolean (default: ``False``); if set, then a word + is returned, otherwise a single letter (in which case ``length`` has + to be ``1``) - A single letter or a word. + OUTPUT: a single letter or a word A :python:`RuntimeError` is thrown if the tape (at least one track) has reached its end. @@ -13450,13 +13114,11 @@ def compare_to_tape(self, track_number, word): INPUT: - - ``track_number`` -- an integer. + - ``track_number`` -- integer - - ``word`` -- a tuple or list of letters. - - OUTPUT: + - ``word`` -- tuple or list of letters - ``True`` or ``False`` + OUTPUT: boolean TESTS:: @@ -13499,11 +13161,9 @@ def forward(self, transition): INPUT: - - ``transition`` -- a transition of a finite state machine. + - ``transition`` -- a transition of a finite state machine - OUTPUT: - - Nothing. + OUTPUT: nothing If ``self.is_multitape`` is ``False``, then this function forwards ``self`` (track `0`) by the number of entries of @@ -13573,16 +13233,14 @@ def length(word): def transition_possible(self, transition): """ - Tests whether the input word of ``transition`` can be read + Test whether the input word of ``transition`` can be read from the tape. INPUT: - - ``transition`` -- a transition of a finite state machine. + - ``transition`` -- a transition of a finite state machine - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean TESTS:: @@ -13622,11 +13280,9 @@ def _transition_possible_epsilon_(self, word_in): INPUT: - - ``word_in`` -- an input word of a transition. - - OUTPUT: + - ``word_in`` -- an input word of a transition - ``True`` or ``False``. + OUTPUT: boolean TESTS:: @@ -13654,11 +13310,9 @@ def _transition_possible_test_(self, word_in): INPUT: - - ``word_in`` -- an input word of a transition. - - OUTPUT: + - ``word_in`` -- an input word of a transition - ``True`` or ``False``. + OUTPUT: boolean This method is usually overridden in inherited classes, cf. :class:`_FSMTapeCacheDetectEpsilon_` and @@ -13750,11 +13404,9 @@ def _transition_possible_test_(self, word_in): INPUT: - - ``word_in`` -- an input word of a transition. - - OUTPUT: + - ``word_in`` -- an input word of a transition - ``True`` or ``False``. + OUTPUT: boolean TESTS:: @@ -13791,13 +13443,11 @@ def compare_to_tape(self, track_number, word): INPUT: - - ``track_number`` -- an integer. + - ``track_number`` -- integer - - ``word`` -- a tuple or list of letters. Only its length is used. + - ``word`` -- tuple or list of letters; only its length is used - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean Note that this method usually returns ``True``. ``False`` can only be returned at the end of the input tape. @@ -13843,11 +13493,9 @@ def tupleofwords_to_wordoftuples(tupleofwords): INPUT: - - ``tupleofwords`` -- a tuple of a list of letters. - - OUTPUT: + - ``tupleofwords`` -- tuple of a list of letters - A list of tuples. + OUTPUT: list of tuples Missing letters in the words are padded with the letter ``None`` (from the empty word). @@ -13869,11 +13517,9 @@ def wordoftuples_to_tupleofwords(wordoftuples): INPUT: - - ``wordoftuples`` -- a list of tuples of letters. - - OUTPUT: + - ``wordoftuples`` -- list of tuples of letters - A tuple of lists. + OUTPUT: a tuple of lists Letters ``None`` (empty word) are removed from each word in the output. @@ -13899,7 +13545,7 @@ def remove_empty_letters(word): def is_FSMProcessIterator(PI): """ - Tests whether or not ``PI`` inherits from :class:`FSMProcessIterator`. + Test whether or not ``PI`` inherits from :class:`FSMProcessIterator`. TESTS:: @@ -13927,7 +13573,7 @@ class FSMProcessIterator(SageObject, Iterator): INPUT: - ``fsm`` -- the finite state machine on which the input should be - processed. + processed - ``input_tape`` -- the input tape can be a list or an iterable with entries from the input alphabet. If we are @@ -13948,28 +13594,23 @@ class FSMProcessIterator(SageObject, Iterator): output (which is in form of a list) to something more readable. By default (``None``) identity is used here. - - ``check_epsilon_transitions`` -- (default: ``True``) a - boolean. If ``False``, then epsilon transitions are not - taken into consideration during process. + - ``check_epsilon_transitions`` -- boolean (default: ``True``); if + ``False``, then epsilon transitions are not taken into consideration + during process - - ``write_final_word_out`` -- (default: ``True``) a boolean - specifying whether the final output words should be written - or not. + - ``write_final_word_out`` -- boolean (default: ``True``); whether the + final output words should be written or not - - ``use_multitape_input`` -- (default: ``False``) a - boolean. If ``True``, then the multi-tape mode of the - process iterator is activated. See also the notes below for - multi-tape machines. + - ``use_multitape_input`` -- boolean (default: ``False``); if ``True``, + then the multi-tape mode of the process iterator is activated. See also + the notes below for multi-tape machines. - - ``process_all_prefixes_of_input`` -- (default: ``False``) a - boolean. If ``True``, then each prefix of the input word is - processed (instead of processing the whole input word at - once). Consequently, there is an output generated for each - of these prefixes. + - ``process_all_prefixes_of_input`` -- boolean (default: ``False``); if + ``True``, then each prefix of the input word is processed (instead of + processing the whole input word at once). Consequently, there is an + output generated for each of these prefixes. - OUTPUT: - - An iterator. + OUTPUT: an iterator In its simplest form, it behaves like an iterator which, in each step, goes from one state to another. To decide which way @@ -14173,9 +13814,7 @@ def __repr__(self): """ Return a nice representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -14313,17 +13952,15 @@ def _push_branch_(self, state, tape_cache, outputs): INPUT: - - ``state`` -- state which has to be processed. + - ``state`` -- state which has to be processed - ``tape_cache`` -- an instance of :class:`_FSMTapeCache_` (storing - information what to read next). + information what to read next) - - ``outputs`` -- a list of output tapes on each of which words - were written until reaching ``state``. - - OUTPUT: + - ``outputs`` -- list of output tapes on each of which words + were written until reaching ``state`` - Nothing. + OUTPUT: nothing .. NOTE:: @@ -14376,7 +14013,6 @@ def _push_branch_(self, state, tape_cache, outputs): sage: T.process([0, 0, 0], format_output=lambda o: ''.join(o)) [(True, 3, 'a:)'), (True, 3, 'd:)'), (True, 3, 'e:)'), (True, 3, 'i:)'), (True, 3, 'l:)'), (True, 3, 'n:)')] - """ import heapq @@ -14407,17 +14043,15 @@ def _push_branches_(self, state, tape_cache, outputs): INPUT: - ``state`` -- state which has to be processed (i.e., the - current state, this branch is in). + current state, this branch is in) - ``tape_cache`` -- an instance of :class:`_FSMTapeCache_` (storing - information what to read next). - - - ``outputs`` -- a list of output tapes on each of which words - were written until reaching ``state``. + information what to read next) - OUTPUT: + - ``outputs`` -- list of output tapes on each of which words + were written until reaching ``state`` - Nothing. + OUTPUT: nothing When this function is called, a branch is updated, which means, stored for further processing. If the state has epsilon @@ -14483,10 +14117,6 @@ def __next__(self): """ Makes one step in processing the input tape. - INPUT: - - Nothing. - OUTPUT: It returns the current status of the iterator (see below). A @@ -14720,18 +14350,16 @@ def preview_word(self, track_number=None, length=1, return_word=False): INPUT: - - ``track_number`` -- an integer or ``None``. If ``None``, - then a tuple of words (one from each track) is returned. - - - ``length`` -- (default: ``1``) the length of the word(s). + - ``track_number`` -- integer (default: ``None``); if ``None``, then + a tuple of words (one from each track) is returned - - ``return_word`` -- (default: ``False``) a boolean. If set, - then a word is returned, otherwise a single letter (in which - case ``length`` has to be ``1``). + - ``length`` -- (default: ``1``) the length of the word(s) - OUTPUT: + - ``return_word`` -- boolean (default: ``False``); if set, then a word + is returned, otherwise a single letter (in which case ``length`` has + to be ``1``) - A single letter or a word. + OUTPUT: a single letter or a word An exception ``StopIteration`` is thrown if the tape (at least one track) has reached its end. @@ -15101,17 +14729,15 @@ def _push_branch_(self, state, tape_cache, outputs): INPUT: - - ``state`` -- state which has to be processed. + - ``state`` -- state which has to be processed - ``tape_cache`` -- an instance of :class:`_FSMTapeCache_` (storing - information what to read next). + information what to read next) - - ``outputs`` -- a list of output tapes on each of which words - were written until reaching ``state``. - - OUTPUT: + - ``outputs`` -- list of output tapes on each of which words + were written until reaching ``state`` - Nothing. + OUTPUT: nothing TESTS:: diff --git a/src/sage/combinat/finite_state_machine_generators.py b/src/sage/combinat/finite_state_machine_generators.py index ae708a195ca..a43391ef509 100644 --- a/src/sage/combinat/finite_state_machine_generators.py +++ b/src/sage/combinat/finite_state_machine_generators.py @@ -39,19 +39,19 @@ :widths: 30, 70 :delim: | - :meth:`~TransducerGenerators.Identity` | Returns a transducer realizing the identity map. - :meth:`~TransducerGenerators.abs` | Returns a transducer realizing absolute value. - :meth:`~TransducerGenerators.map` | Returns a transducer realizing a function. - :meth:`~TransducerGenerators.operator` | Returns a transducer realizing a binary operation. - :meth:`~TransducerGenerators.all` | Returns a transducer realizing logical ``and``. - :meth:`~TransducerGenerators.any` | Returns a transducer realizing logical ``or``. - :meth:`~TransducerGenerators.add` | Returns a transducer realizing addition. - :meth:`~TransducerGenerators.sub` | Returns a transducer realizing subtraction. - :meth:`~TransducerGenerators.CountSubblockOccurrences` | Returns a transducer counting the occurrences of a subblock. - :meth:`~TransducerGenerators.Wait` | Returns a transducer writing ``False`` until first (or k-th) true input is read. - :meth:`~TransducerGenerators.weight` | Returns a transducer realizing the Hamming weight. - :meth:`~TransducerGenerators.GrayCode` | Returns a transducer realizing binary Gray code. - :meth:`~TransducerGenerators.Recursion` | Returns a transducer defined by recursions. + :meth:`~TransducerGenerators.Identity` | Return a transducer realizing the identity map. + :meth:`~TransducerGenerators.abs` | Return a transducer realizing absolute value. + :meth:`~TransducerGenerators.map` | Return a transducer realizing a function. + :meth:`~TransducerGenerators.operator` | Return a transducer realizing a binary operation. + :meth:`~TransducerGenerators.all` | Return a transducer realizing logical ``and``. + :meth:`~TransducerGenerators.any` | Return a transducer realizing logical ``or``. + :meth:`~TransducerGenerators.add` | Return a transducer realizing addition. + :meth:`~TransducerGenerators.sub` | Return a transducer realizing subtraction. + :meth:`~TransducerGenerators.CountSubblockOccurrences` | Return a transducer counting the occurrences of a subblock. + :meth:`~TransducerGenerators.Wait` | Return a transducer writing ``False`` until first (or `k`-th) true input is read. + :meth:`~TransducerGenerators.weight` | Return a transducer realizing the Hamming weight. + :meth:`~TransducerGenerators.GrayCode` | Return a transducer realizing binary Gray code. + :meth:`~TransducerGenerators.Recursion` | Return a transducer defined by recursions. AUTHORS: @@ -120,11 +120,9 @@ def AnyLetter(self, input_alphabet): INPUT: - - ``input_alphabet`` -- a list, the input alphabet + - ``input_alphabet`` -- list; the input alphabet - OUTPUT: - - An :class:`~Automaton`. + OUTPUT: an :class:`~Automaton` EXAMPLES:: @@ -155,11 +153,9 @@ def AnyWord(self, input_alphabet): INPUT: - - ``input_alphabet`` -- a list, the input alphabet - - OUTPUT: + - ``input_alphabet`` -- list; the input alphabet - An :class:`~Automaton`. + OUTPUT: an :class:`~Automaton` EXAMPLES:: @@ -197,12 +193,9 @@ def EmptyWord(self, input_alphabet=None): INPUT: - - ``input_alphabet`` -- (default: ``None``) an iterable - or ``None``. - - OUTPUT: + - ``input_alphabet`` -- iterable or ``None`` (default: ``None``) - An :class:`~Automaton`. + OUTPUT: an :class:`~Automaton` EXAMPLES:: @@ -228,14 +221,12 @@ def Word(self, word, input_alphabet=None): INPUT: - - ``word`` -- an iterable. + - ``word`` -- an iterable - - ``input_alphabet`` -- a list or ``None``. If ``None``, - then the letters occurring in the word are used. + - ``input_alphabet`` -- list or ``None``; if ``None``, + then the letters occurring in the word are used - OUTPUT: - - An :class:`~Automaton`. + OUTPUT: an :class:`~Automaton` EXAMPLES:: @@ -288,15 +279,13 @@ def ContainsWord(self, word, input_alphabet): INPUT: - - ``word`` -- a list (or other iterable) of letters, the - word we are looking for. + - ``word`` -- list (or other iterable) of letters; the + word we are looking for - - ``input_alphabet`` -- a list or other iterable, the input - alphabet. + - ``input_alphabet`` -- list or other iterable; the input + alphabet - OUTPUT: - - An :class:`~Automaton`. + OUTPUT: an :class:`~Automaton` EXAMPLES:: @@ -370,16 +359,14 @@ class TransducerGenerators: def Identity(self, input_alphabet): """ - Returns the identity transducer realizing the identity map. + Return the identity transducer realizing the identity map. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - OUTPUT: - - A transducer mapping each word over ``input_alphabet`` to - itself. + OUTPUT: a transducer mapping each word over ``input_alphabet`` to + itself EXAMPLES:: @@ -397,7 +384,6 @@ def Identity(self, input_alphabet): [0, 1] sage: T([0, 1, 0, 1, 1]) [0, 1, 0, 1, 1] - """ return Transducer( [(0, 0, d, d) for d in input_alphabet], @@ -408,14 +394,14 @@ def Identity(self, input_alphabet): def CountSubblockOccurrences(self, block, input_alphabet): r""" - Returns a transducer counting the number of (possibly + Return a transducer counting the number of (possibly overlapping) occurrences of a block in the input. INPUT: - - ``block`` -- a list (or other iterable) of letters. + - ``block`` -- list (or other iterable) of letters - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable OUTPUT: @@ -533,10 +519,10 @@ def Wait(self, input_alphabet, threshold=1): INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - - ``threshold`` -- a positive integer specifying how many - occurrences of ``True`` inputs are waited for. + - ``threshold`` -- positive integer specifying how many + occurrences of ``True`` inputs are waited for OUTPUT: @@ -576,9 +562,9 @@ def map(self, f, input_alphabet): INPUT: - - ``f`` -- function to realize. + - ``f`` -- function to realize - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable OUTPUT: @@ -616,19 +602,19 @@ def map(self, f, input_alphabet): def operator(self, operator, input_alphabet, number_of_operands=2): r""" - Returns a transducer which realizes an operation + Return a transducer which realizes an operation on tuples over the given input alphabet. INPUT: - - ``operator`` -- operator to realize. It is a function which + - ``operator`` -- operator to realize; it is a function which takes ``number_of_operands`` input arguments (each out of - ``input_alphabet``). + ``input_alphabet``) - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - ``number_of_operands`` -- (default: `2`) it specifies the number - of input arguments the operator takes. + of input arguments the operator takes OUTPUT: @@ -642,7 +628,7 @@ def operator(self, operator, input_alphabet, number_of_operands=2): EXAMPLES: The following binary transducer realizes component-wise - addition (this transducer is also available as :meth:`.add`):: + addition (this transducer is also available as :meth:`add`):: sage: import operator sage: T = transducers.operator(operator.add, [0, 1]) @@ -698,15 +684,15 @@ def transition_function(state, operands): def all(self, input_alphabet, number_of_operands=2): r""" - Returns a transducer which realizes logical ``and`` over the given + Return a transducer which realizes logical ``and`` over the given input alphabet. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - ``number_of_operands`` -- (default: `2`) specifies the number - of input arguments for the ``and`` operation. + of input arguments for the ``and`` operation OUTPUT: @@ -749,15 +735,15 @@ def all(self, input_alphabet, number_of_operands=2): def any(self, input_alphabet, number_of_operands=2): r""" - Returns a transducer which realizes logical ``or`` over the given + Return a transducer which realizes logical ``or`` over the given input alphabet. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - ``number_of_operands`` -- (default: `2`) specifies the number - of input arguments for the ``or`` operation. + of input arguments for the ``or`` operation OUTPUT: @@ -800,15 +786,15 @@ def any(self, input_alphabet, number_of_operands=2): def add(self, input_alphabet, number_of_operands=2): r""" - Returns a transducer which realizes addition on pairs over the + Return a transducer which realizes addition on pairs over the given input alphabet. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - ``number_of_operands`` -- (default: `2`) it specifies the number - of input arguments the operator takes. + of input arguments the operator takes OUTPUT: @@ -854,12 +840,12 @@ def add(self, input_alphabet, number_of_operands=2): def sub(self, input_alphabet): r""" - Returns a transducer which realizes subtraction on pairs over + Return a transducer which realizes subtraction on pairs over the given input alphabet. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable OUTPUT: @@ -893,12 +879,12 @@ def sub(self, input_alphabet): def weight(self, input_alphabet, zero=0): r""" - Returns a transducer which realizes the Hamming weight of the input + Return a transducer which realizes the Hamming weight of the input over the given input alphabet. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable - ``zero`` -- the zero symbol in the alphabet used @@ -906,7 +892,7 @@ def weight(self, input_alphabet, zero=0): A transducer mapping `i_0\ldots i_k` to `(i_0\neq 0)\ldots(i_k\neq 0)`. - The Hamming weight is defined as the number of non-zero digits in the + The Hamming weight is defined as the number of nonzero digits in the input sequence over the alphabet ``input_alphabet`` (see :wikipedia:`Hamming_weight`). The output sequence of the transducer is a unary encoding of the Hamming weight. Thus the sum of the output @@ -959,12 +945,12 @@ def weight(state, input): def abs(self, input_alphabet): r""" - Returns a transducer which realizes the letter-wise + Return a transducer which realizes the letter-wise absolute value of an input word over the given input alphabet. INPUT: - - ``input_alphabet`` -- a list or other iterable. + - ``input_alphabet`` -- list or other iterable OUTPUT: @@ -987,22 +973,15 @@ def abs(self, input_alphabet): [0] sage: T([-1, -1, 0, 1]) [1, 1, 0, 1] - """ return self.map(abs, input_alphabet) def GrayCode(self): """ - Returns a transducer converting the standard binary + Return a transducer converting the standard binary expansion to Gray code. - INPUT: - - Nothing. - - OUTPUT: - - A transducer. + OUTPUT: a transducer Cf. the :wikipedia:`Gray_code` for a description of the Gray code. @@ -1052,24 +1031,24 @@ def _parse_recursion_equation_(self, equation, base, function, var, INPUT: - - ``equation`` -- An equation of the form + - ``equation`` -- an equation of the form - ``f(base^K * n + r) == f(base^k * n + s) + t`` for some integers ``0 <= k < K``, ``r`` and some ``t``---valid for all ``n`` such that the arguments on both sides are - non-negative--- + nonnegative--- or the form - ``f(r) == t`` for some integer ``r`` and some ``t``. - - ``base`` -- see :meth:`~Recursion`. + - ``base`` -- see :meth:`~Recursion` - - ``function`` -- see :meth:`~Recursion`. + - ``function`` -- see :meth:`~Recursion` - - ``var`` -- see :meth:`~Recursion`. + - ``var`` -- see :meth:`~Recursion` - - ``output_rings`` -- see :meth:`~Recursion`. + - ``output_rings`` -- see :meth:`~Recursion` OUTPUT: @@ -1373,7 +1352,7 @@ def Recursion(self, recursions, base, function=None, var=None, - ``f(base^K * n + r) == f(base^k * n + s) + t`` for some integers ``0 <= k < K``, ``r`` and some ``t``---valid for all ``n`` such that the arguments on both sides are - non-negative--- + nonnegative--- or the form @@ -1384,12 +1363,12 @@ def Recursion(self, recursions, base, function=None, var=None, ``r``, ``k``, ``s``, ``t`` as above or a tuple ``(r, t)``. Note that ``t`` *must* be a list in this case. - - ``base`` -- base of the digit expansion. + - ``base`` -- base of the digit expansion - ``function`` -- symbolic function ``f`` occurring in the - recursions. + recursions - - ``var`` -- symbolic variable. + - ``var`` -- symbolic variable - ``input_alphabet`` -- (default: ``None``) a list of digits to be used as the input alphabet. If ``None`` and the base @@ -1405,9 +1384,9 @@ def Recursion(self, recursions, base, function=None, var=None, - ``is_zero`` -- (default: ``None``) a callable. The recursion relations are only well-posed if there is no cycle with - non-zero output and input consisting of zeros. This parameter + nonzero output and input consisting of zeros. This parameter is used to determine whether the output of such a cycle is - non-zero. By default, the output must evaluate to ``False`` as + nonzero. By default, the output must evaluate to ``False`` as a boolean. - ``output_rings`` -- (default: ``[ZZ, QQ]``) a list of @@ -1416,9 +1395,7 @@ def Recursion(self, recursions, base, function=None, var=None, contained in any ring, they remain in whatever ring they are after parsing the recursions, typically the symbolic ring. - OUTPUT: - - A transducer ``T``. + OUTPUT: a transducer ``T`` The transducer is constructed such that ``T(expansion) == f(n)`` if ``expansion`` is the digit expansion of ``n`` to the base @@ -1515,7 +1492,7 @@ def Recursion(self, recursions, base, function=None, var=None, sage: sum(T(binary_expansion)) # needs sage.symbolic 3 - Indeed, the given non-adjacent form has three non-zero + Indeed, the given non-adjacent form has three nonzero digits. - The following example computes the non-adjacent form from the @@ -1856,13 +1833,13 @@ def recursion_transition(carry, level, force_nonnegative_target): INPUT: - - ``carry`` -- integer. + - ``carry`` -- integer - - ``level`` -- integer. + - ``level`` -- integer - - ``force_nonnegative_target`` -- boolean. If ``True``, only - recursion transitions leading to a non-negative carry are - returned. + - ``force_nonnegative_target`` -- boolean; if ``True``, only + recursion transitions leading to a nonnegative carry are + returned OUTPUT: @@ -1895,13 +1872,13 @@ def recursion_transitions(carry, level, force_nonnegative_target): INPUT: - - ``carry`` -- integer. + - ``carry`` -- integer - - ``level`` -- integer. + - ``level`` -- integer - - ``force_nonnegative_target`` -- boolean. If ``True``, only - recursion transitions leading to a non-negative carry are - allowed. + - ``force_nonnegative_target`` -- boolean; if ``True``, only + recursion transitions leading to a nonnegative carry are + allowed OUTPUT: @@ -1928,7 +1905,7 @@ def transition_function(states2, input): carry += input * base**level level += 1 # We now may proceed along recursion transitions - # as long as the carries stay non-negative. + # as long as the carries stay nonnegative. ((carry, level), new_output) = recursion_transitions( carry, level, True) return ((carry, level), output + new_output) @@ -1943,7 +1920,7 @@ def edge_recursion_digraph(n): INPUT: - - ``n`` -- integer. + - ``n`` -- integer OUTPUT: diff --git a/src/sage/combinat/fqsym.py b/src/sage/combinat/fqsym.py index a3898280fc6..e92c6fba45e 100644 --- a/src/sage/combinat/fqsym.py +++ b/src/sage/combinat/fqsym.py @@ -55,7 +55,7 @@ def __init__(self, alg): CombinatorialFreeModule.__init__(self, alg.base_ring(), Permutations(), category=FQSymBases(alg), - bracket="", prefix=self._prefix) + bracket='', prefix=self._prefix) def _coerce_map_from_(self, R): r""" @@ -800,9 +800,7 @@ def _G_to_F_on_basis(self, w): - ``w`` -- a permutation - OUTPUT: - - - An element of the F basis + OUTPUT: an element of the F basis TESTS:: @@ -832,9 +830,7 @@ def _F_to_G_on_basis(self, w): - ``w`` -- a permutation - OUTPUT: - - - An element of the G basis + OUTPUT: an element of the G basis TESTS:: @@ -911,10 +907,10 @@ def __init__(self, alg): F = self.realization_of().F() phi = F.module_morphism(self._F_to_M_on_basis, codomain=self, - unitriangular="lower") + unitriangular='lower') phi.register_as_coercion() phi_i = self.module_morphism(self._M_to_F_on_basis, codomain=F, - unitriangular="lower") + unitriangular='lower') phi_i.register_as_coercion() def _element_constructor_(self, x): @@ -1018,9 +1014,7 @@ def _F_to_M_on_basis(self, w): - ``w`` -- a permutation - OUTPUT: - - - An element of the M basis + OUTPUT: an element of the M basis TESTS:: @@ -1047,9 +1041,7 @@ def _M_to_F_on_basis(self, w): - ``w`` -- a permutation - OUTPUT: - - - An element of the F basis + OUTPUT: an element of the F basis ALGORITHM: @@ -1238,7 +1230,7 @@ class FQSymBases(Category_realization_of_parent): def __init__(self, base): r""" - Initialize the bases of an `FQSym` + Initialize the bases of an `FQSym`. INPUT: diff --git a/src/sage/combinat/free_dendriform_algebra.py b/src/sage/combinat/free_dendriform_algebra.py index 900b9a7ca5d..4be2c514778 100644 --- a/src/sage/combinat/free_dendriform_algebra.py +++ b/src/sage/combinat/free_dendriform_algebra.py @@ -180,7 +180,7 @@ def __init__(self, R, names=None): cat = HopfAlgebras(R).WithBasis().Graded().Connected() CombinatorialFreeModule.__init__(self, R, Trees, - latex_prefix="", + latex_prefix='', sorting_key=key, category=cat) @@ -224,11 +224,11 @@ def _repr_(self): def gen(self, i): r""" - Return the ``i``-th generator of the algebra. + Return the `i`-th generator of the algebra. INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -939,14 +939,12 @@ def merge(self, other): return self ret = list(self.vars) cur_vars = set(ret) - for v in other.vars: - if v not in cur_vars: - ret.append(v) + ret.extend(v for v in other.vars if v not in cur_vars) return DendriformFunctor(Alphabet(ret)) - else: - return None - def _repr_(self): + return None + + def _repr_(self) -> str: """ TESTS:: diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 290bdf4a8dc..639cec54ae4 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -35,13 +35,13 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): r""" - Class for free modules with a named basis + Class for free modules with a named basis. INPUT: - ``R`` -- base ring - - ``basis_keys`` -- list, tuple, family, set, etc. defining the + - ``basis_keys`` -- list; tuple, family, set, etc. defining the indexing set for the basis of this module - ``element_class`` -- the class of which elements of this module @@ -226,8 +226,8 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): involves comparison by equality (not identity). Hence, the last line of the following example used to fail with an assertion error:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix="F") - sage: G = CombinatorialFreeModule(ZZ, [1,2,3,4], prefix="G") + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='F') + sage: G = CombinatorialFreeModule(ZZ, [1,2,3,4], prefix='G') sage: f = F.monomial(1) + 2 * F.monomial(2) sage: g = 2*G.monomial(3) + G.monomial(4) sage: tensor([f, g]) @@ -261,7 +261,7 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): We check that issue :issue:`28681` is fixed:: - sage: F = CombinatorialFreeModule(ZZ, ZZ); F.rename("F") + sage: F = CombinatorialFreeModule(ZZ, ZZ); F.rename('F') sage: FF = tensor((F,F)) sage: cartesian_product((FF,FF)) F # F (+) F # F @@ -337,7 +337,7 @@ def __classcall_private__(cls, base_ring, basis_keys=None, category=None, @lazy_attribute def element_class(self): """ - The (default) class for the elements of this parent + The (default) class for the elements of this parent. Overrides :meth:`Parent.element_class` to force the construction of Python class. This is currently needed to @@ -467,7 +467,7 @@ def __init__(self, R, basis_keys=None, element_class=None, category=None, def construction(self): """ - The construction functor and base ring for self. + The construction functor and base ring for ``self``. EXAMPLES:: @@ -694,8 +694,8 @@ def _element_constructor_(self, x): A coercion between free modules with the same indices exists whenever a coercion map is defined between their base rings:: - sage: F = CombinatorialFreeModule(ZZ, ["a", "b"]); F.rename("F") - sage: G = CombinatorialFreeModule(QQ, ["a", "b"]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, ["a", "b"]); F.rename('F') + sage: G = CombinatorialFreeModule(QQ, ["a", "b"]); G.rename('G') sage: G(F.monomial("a")) B['a'] sage: G(-3*F.monomial("a")) @@ -703,7 +703,7 @@ def _element_constructor_(self, x): Otherwise, there is no conversion between distinct free modules:: - sage: H = CombinatorialFreeModule(ZZ, ["a", "b", "c"]); H.rename("H") + sage: H = CombinatorialFreeModule(ZZ, ["a", "b", "c"]); H.rename('H') sage: H(F.monomial("a")) Traceback (most recent call last): ... @@ -720,7 +720,7 @@ def _element_constructor_(self, x): The following originally used to yield ``p[[2]] # p[[2]]``, and if there was no natural coercion between ``s`` and ``p``, this would - raise a :class:`NotImplementedError`. + raise a :exc:`NotImplementedError`. Since :issue:`15305`, this takes the coercion between ``s`` and ``p`` and lifts it to the tensor product. :: @@ -923,7 +923,7 @@ def set_order(self, order): Set the order of the elements of the basis. If :meth:`set_order` has not been called, then the ordering is - the one used in the generation of the elements of self's + the one used in the generation of the elements of ``self``'s associated enumerated set. .. WARNING:: @@ -1158,8 +1158,8 @@ def sum_of_terms(self, terms, distinct=False): INPUT: - - ``terms`` -- a list (or iterable) of pairs ``(index, coeff)`` - - ``distinct`` -- (default: ``False``) whether the indices are + - ``terms`` -- list (or iterable) of pairs ``(index, coeff)`` + - ``distinct`` -- boolean (default: ``False``); whether the indices are guaranteed to be distinct EXAMPLES:: @@ -1208,14 +1208,14 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): INPUT: - - ``d`` -- a dictionary ``{index: coeff}`` where each ``index`` is + - ``d`` -- dictionary ``{index: coeff}`` where each ``index`` is the index of a basis element and each ``coeff`` belongs to the coefficient ring ``self.base_ring()`` - - ``coerce`` -- a boolean (default: ``False``), whether to coerce + - ``coerce`` -- boolean (default: ``False``); whether to coerce the coefficients ``coeff`` to the coefficient ring - - ``remove_zeros`` -- a boolean (default: ``True``), if some + - ``remove_zeros`` -- boolean (default: ``True``); if some coefficients ``coeff`` may be zero and should therefore be removed EXAMPLES:: @@ -1264,14 +1264,14 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): """ - Tensor Product of Free Modules + Tensor Product of Free Modules. EXAMPLES: We construct two free modules, assign them short names, and construct their tensor product:: - sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename('G') sage: T = tensor([F, G]); T F # G @@ -1306,7 +1306,7 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): The tensor product is associative and flattens sub tensor products:: - sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H") + sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename('H') sage: tensor([F, tensor([G, H])]) F # G # H sage: tensor([tensor([F, G]), H]) @@ -1396,8 +1396,8 @@ def _repr_(self): sage: F = CombinatorialFreeModule(ZZ, [1,2,3]) sage: G = CombinatorialFreeModule(ZZ, [1,2,3,8]) - sage: F.rename("F") - sage: G.rename("G") + sage: F.rename('F') + sage: G.rename('G') sage: T = tensor([F, G]) sage: T # indirect doctest F # G @@ -1426,9 +1426,9 @@ def tensor_factors(self): EXAMPLES:: sage: F = CombinatorialFreeModule(ZZ, [1,2]) - sage: F.rename("F") + sage: F.rename('F') sage: G = CombinatorialFreeModule(ZZ, [3,4]) - sage: G.rename("G") + sage: G.rename('G') sage: T = tensor([F, G]); T F # G sage: T.tensor_factors() @@ -1441,7 +1441,7 @@ def _ascii_art_(self, term): TESTS:: sage: R = NonCommutativeSymmetricFunctions(QQ).R() # needs sage.combinat - sage: Partitions.options(diagram_str="#", convention="french") # needs sage.combinat + sage: Partitions.options(diagram_str='#', convention='french') # needs sage.combinat sage: s = ascii_art(tensor((R[1,2], R[3,1,2]))); s # needs sage.combinat R # R # ### @@ -1470,7 +1470,7 @@ def _unicode_art_(self, term): TESTS:: sage: R = NonCommutativeSymmetricFunctions(QQ).R() # needs sage.combinat - sage: Partitions.options(diagram_str="#", convention="french") # needs sage.combinat + sage: Partitions.options(diagram_str='#', convention='french') # needs sage.combinat sage: s = unicode_art(tensor((R[1,2], R[3,1,2]))); s # needs sage.combinat R ⊗ R ┌┐ ┌┬┬┐ @@ -1501,8 +1501,8 @@ def _latex_(self): sage: F = CombinatorialFreeModule(ZZ, [1,2,3]) sage: G = CombinatorialFreeModule(ZZ, [1,2,3,8]) - sage: F.rename("F") - sage: G.rename("G") + sage: F.rename('F') + sage: G.rename('G') sage: latex(tensor([F, F, G])) # indirect doctest \text{\texttt{F}} \otimes \text{\texttt{F}} \otimes \text{\texttt{G}} sage: F._latex_ = lambda : "F" @@ -1518,8 +1518,8 @@ def _repr_term(self, term): """ TESTS:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix="F") - sage: G = CombinatorialFreeModule(ZZ, [1,2,3,4], prefix="G") + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='F') + sage: G = CombinatorialFreeModule(ZZ, [1,2,3,4], prefix='G') sage: f = F.monomial(1) + 2 * F.monomial(2) sage: g = 2*G.monomial(3) + G.monomial(4) sage: tensor([f, g]) # indirect doctest @@ -1552,17 +1552,17 @@ def tensor_constructor(self, modules): r""" INPUT: - - ``modules`` -- a tuple `(F_1,\dots,F_n)` of - free modules whose tensor product is self + - ``modules`` -- tuple `(F_1,\dots,F_n)` of + free modules whose tensor product is self Returns the canonical multilinear morphism from `F_1 \times \dots \times F_n` to `F_1 \otimes \dots \otimes F_n` EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename("G") - sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H") + sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename('G') + sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename('H') sage: f = F.monomial(1) + 2*F.monomial(2) sage: g = 2*G.monomial(3) + G.monomial(4) @@ -1599,14 +1599,14 @@ def tensor_constructor(self, modules): def _tensor_of_elements(self, elements): """ - Returns the tensor product of the specified elements. + Return the tensor product of the specified elements. The result should be in ``self``. EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename("G") - sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H") + sage: F = CombinatorialFreeModule(ZZ, [1,2]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename('G') + sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename('H') sage: f = F.monomial(1) + 2 * F.monomial(2) sage: g = 2*G.monomial(3) + G.monomial(4) @@ -1702,17 +1702,16 @@ def __init__(self, flatten): """ INPUT: - - ``flatten`` -- a tuple of booleans + - ``flatten`` -- tuple of booleans This constructs a callable which accepts ``len(flatten)`` arguments, and builds a tuple out them. When ``flatten[i]``, - the i-th argument itself should be a tuple which is flattened + the `i`-th argument itself should be a tuple which is flattened in the result. sage: from sage.combinat.free_module import CartesianProductWithFlattening sage: CartesianProductWithFlattening([True, False, True, True]) - """ self._flatten = flatten @@ -1726,7 +1725,6 @@ def __call__(self, *indices): (1, 2, (3, 4), 5, 6, 7, 8) sage: cp((1,2,3), 4, (5,6), (7,8)) (1, 2, 3, 4, 5, 6, 7, 8) - """ return sum((i if flatten else (i,) for (i, flatten) in zip(indices, self._flatten)), ()) @@ -1738,15 +1736,15 @@ def __call__(self, *indices): class CombinatorialFreeModule_CartesianProduct(CombinatorialFreeModule): """ - An implementation of Cartesian products of modules with basis + An implementation of Cartesian products of modules with basis. EXAMPLES: We construct two free modules, assign them short names, and construct their Cartesian product:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") - sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.rename("H") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') + sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.rename('H') sage: S = cartesian_product([F, G]) sage: S F (+) G @@ -1801,7 +1799,7 @@ def __init__(self, modules, **options): def _sets_keys(self): """ - In waiting for self._sets.keys() + In waiting for ``self._sets.keys()``. TESTS:: @@ -1820,7 +1818,7 @@ def _repr_(self): sage: F = CombinatorialFreeModule(ZZ, [2,4,5]) sage: CP = cartesian_product([F, F]); CP # indirect doctest Free module generated by {2, 4, 5} over Integer Ring (+) Free module generated by {2, 4, 5} over Integer Ring - sage: F.rename("F"); CP + sage: F.rename('F'); CP F (+) F """ from sage.categories.cartesian_product import cartesian_product @@ -1836,12 +1834,12 @@ def cartesian_embedding(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') sage: S = cartesian_product([F, G]) sage: phi = S.cartesian_embedding(0) sage: phi(F.monomial(4) + 2 * F.monomial(5)) @@ -1870,12 +1868,12 @@ def cartesian_projection(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') sage: S = cartesian_product([F, G]) sage: x = S.monomial((0,4)) + 2 * S.monomial((0,5)) + 3 * S.monomial((1,6)) sage: S.cartesian_projection(0)(x) @@ -1904,8 +1902,8 @@ def _cartesian_product_of_elements(self, elements): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') sage: S = cartesian_product([F, G]) sage: f = F.monomial(4) + 2*F.monomial(5) sage: g = 2*G.monomial(4) + G.monomial(6) @@ -1943,8 +1941,8 @@ def cartesian_factors(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F') + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G') sage: S = cartesian_product([F, G]) sage: S.cartesian_factors() (F, G) diff --git a/src/sage/combinat/free_prelie_algebra.py b/src/sage/combinat/free_prelie_algebra.py index 88d54b1f443..6e7525d8b23 100644 --- a/src/sage/combinat/free_prelie_algebra.py +++ b/src/sage/combinat/free_prelie_algebra.py @@ -227,7 +227,7 @@ def __init__(self, R, names=None): cat = MagmaticAlgebras(R).WithBasis().Graded() & LieAlgebras(R).WithBasis().Graded() CombinatorialFreeModule.__init__(self, R, Trees, - latex_prefix="", + latex_prefix='', sorting_key=key, category=cat) @@ -263,7 +263,7 @@ def _repr_(self): sage: enum = EnumeratedSets().Infinite().example() sage: algebras.FreePreLie(QQ, enum) # indirect doctest Free PreLie algebra on generators indexed by An example of an - infinite enumerated set: the non negative integers + infinite enumerated set: the nonnegative integers over Rational Field """ n = self.algebra_generators().cardinality() @@ -289,7 +289,7 @@ def gen(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -337,7 +337,7 @@ def change_ring(self, R): INPUT: - - `R` -- a ring + - ``R`` -- a ring EXAMPLES:: @@ -716,7 +716,7 @@ def _coerce_map_from_(self, R): The things that coerce into ``self`` are - free pre-Lie algebras whose set `E` of labels is - a subset of the corresponding self of ``set`, and whose base + a subset of the corresponding ``self`` of ``set``, and whose base ring has a coercion map into ``self.base_ring()`` EXAMPLES:: @@ -1023,14 +1023,12 @@ def merge(self, other): return self ret = list(self.vars) cur_vars = set(ret) - for v in other.vars: - if v not in cur_vars: - ret.append(v) + ret.extend(v for v in other.vars if v not in cur_vars) return PreLieFunctor(Alphabet(ret)) - else: - return None - def _repr_(self): + return None + + def _repr_(self) -> str: """ TESTS:: @@ -1048,8 +1046,8 @@ def tree_from_sortkey(ch, labels=True): INPUT: - - ``ch`` -- a list of pairs ``(integer, label)`` - - ``labels`` -- (default ``True``) whether to use labelled trees + - ``ch`` -- list of pairs ``(integer, label)`` + - ``labels`` -- boolean (default: ``True``); whether to use labelled trees OUTPUT: @@ -1101,7 +1099,7 @@ def corolla_gen(tx, list_ty, labels=True): INPUT: - ``tx`` -- a tree - - ``list_ty`` -- a list of trees + - ``list_ty`` -- list of trees EXAMPLES:: diff --git a/src/sage/combinat/fully_commutative_elements.py b/src/sage/combinat/fully_commutative_elements.py index 19f3024cac5..4cf13510dd3 100644 --- a/src/sage/combinat/fully_commutative_elements.py +++ b/src/sage/combinat/fully_commutative_elements.py @@ -140,10 +140,10 @@ def is_fully_commutative(self): r""" Check if ``self`` is the reduced word of an FC element. - To check if `self` is FC, we use the well-known characterization that an - element `w` in a Coxeter system `(W,S)` is FC if and only if for every - pair of generators `s,t \in S` for which `m(s,t)>2`, no reduced word of - `w` contains the 'braid' word `sts...` of length `m(s,t)` as a + To check if ``self`` is FC, we use the well-known characterization that + an element `w` in a Coxeter system `(W,S)` is FC if and only if for + every pair of generators `s,t \in S` for which `m(s,t)>2`, no reduced + word of `w` contains the 'braid' word `sts...` of length `m(s,t)` as a contiguous subword. See [Ste1996]_. :func:`check` is an alias of this method, and is called automatically @@ -189,13 +189,13 @@ def heap(self, **kargs): INPUT: - - ``self`` -- list, a reduced word `w=s_0... s_{k-1}` of an FC element + - ``self`` -- list; a reduced word `w=s_0... s_{k-1}` of an FC element - - ``one_index`` -- boolean (default: ``False``). Setting the value to True + - ``one_index`` -- boolean (default: ``False``); setting the value to True will change the underlying set of the poset to `\{1, 2, \dots, n\}` - - ``display_labeling`` -- boolean (default: ``False``). Setting the value to - True will display the label `s_i` for each element `i` of the poset + - ``display_labeling`` -- boolean (default: ``False``); setting the value to + ``True`` will display the label `s_i` for each element `i` of the poset OUTPUT: @@ -387,7 +387,7 @@ def has_descent(self, s, side='left'): - ``side`` -- string (default: ``'left'``); if set to 'right', determine if ``self`` has ``s`` as a right descent - OUTPUT: a boolean value + OUTPUT: boolean EXAMPLES:: @@ -657,7 +657,7 @@ def star_operation(self, J, direction, side='left'): INPUT: - - ``J`` -- a set of two integers representing two noncommuting + - ``J`` -- set of two integers representing two noncommuting generators of the Coxeter system - ``direction`` -- string, ``'upper'`` or ``'lower'``; the function @@ -803,7 +803,7 @@ class FullyCommutativeElements(UniqueRepresentation, Parent): True Attempting to create an element from an input that is not the reduced word - of a fully commutative element throws a :class:`ValueError`:: + of a fully commutative element throws a :exc:`ValueError`:: sage: FC([1,2,1]) Traceback (most recent call last): diff --git a/src/sage/combinat/fully_packed_loop.py b/src/sage/combinat/fully_packed_loop.py index b198fed0c0d..74a14fa1ecd 100644 --- a/src/sage/combinat/fully_packed_loop.py +++ b/src/sage/combinat/fully_packed_loop.py @@ -66,6 +66,9 @@ def _make_color_list(n, colors=None, color_map=None, randomize=False): r""" TESTS:: + sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: from sage.combinat.fully_packed_loop import _make_color_list sage: _make_color_list(5) sage: _make_color_list(5, ['blue', 'red']) @@ -128,33 +131,33 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): sage: fpl.link_pattern() [(1, 4), (2, 3), (5, 6)] sage: fpl - | | - | | - + -- + + - | | - | | - -- + + + -- - | | - | | - + + -- + - | | - | | + │ │ + │ │ + + ── + + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + + ── + + │ │ + │ │ sage: B = AlternatingSignMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) sage: fplb = FullyPackedLoop(B) sage: fplb.link_pattern() [(1, 6), (2, 5), (3, 4)] sage: fplb - | | - | | - + + -- + - | | - | | - -- + + + -- - | | - | | - + -- + + - | | - | | + │ │ + │ │ + + + ── + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + ── + + + │ │ + │ │ The class also has a plot method:: @@ -188,17 +191,17 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): V V V sage: fpl = FullyPackedLoop(S) sage: fpl - | | - | | - + -- + + - | | - | | - -- + + + -- - | | - | | - + + -- + - | | - | | + │ │ + │ │ + + ── + + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + + ── + + │ │ + │ │ Once we have a fully packed loop we can obtain the corresponding alternating sign matrix:: @@ -215,20 +218,20 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): sage: fpl.link_pattern() [(1, 2), (3, 6), (4, 5), (7, 8)] sage: fpl - | | - | | - + -- + -- + + -- - | - | - -- + + -- + -- + - | | - | | - + + + -- + -- - | | | - | | | - -- + + + -- + - | | - | | + │ │ + │ │ + + ── + ── + + ── + │ + │ + ── + + ── + ── + + │ │ + │ │ + + + + ── + ── + │ │ │ + │ │ │ + ── + + + ── + + │ │ + │ │ sage: m = AlternatingSignMatrix([[0,0,1,0,0,0], ....: [1,0,-1,0,1,0], @@ -240,26 +243,26 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): sage: fpl.link_pattern() [(1, 12), (2, 7), (3, 4), (5, 6), (8, 9), (10, 11)] sage: fpl - | | | - | | | - + -- + + + -- + + -- - | | | | - | | | | - -- + -- + + + -- + -- + - | - | - + -- + + -- + -- + + -- - | | | | - | | | | - -- + + + -- + + + - | | | | | - | | | | | - + -- + + -- + + + -- - | | - | | - -- + + -- + -- + + -- + - | | | - | | | + │ │ │ + │ │ │ + + ── + + + ── + + ── + │ │ │ │ + │ │ │ │ + ── + ── + + + ── + ── + + │ + │ + + ── + + ── + ── + + ── + │ │ │ │ + │ │ │ │ + ── + + + ── + + + + │ │ │ │ │ + │ │ │ │ │ + + ── + + ── + + + ── + │ │ + │ │ + ── + + ── + ── + + ── + + │ │ │ + │ │ │ sage: m = AlternatingSignMatrix([[0,1,0,0,0,0,0], ....: [1,-1,0,0,1,0,0], @@ -272,29 +275,29 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): sage: fpl.link_pattern() [(1, 2), (3, 4), (5, 6), (7, 8), (9, 14), (10, 11), (12, 13)] sage: fpl - | | | | - | | | | - + -- + -- + + -- + + -- + - | | - | | - -- + -- + -- + + -- + -- + + -- - | | - | | - + -- + + -- + -- + + -- + - | | | | - | | | | - -- + + + -- + + + + -- - | | | | | | - | | | | | | - + -- + + -- + + + -- + - | | - | | - -- + + -- + -- + + + -- + -- - | | | | - | | | | - + -- + + -- + + + -- + - | | | | - | | | | + │ │ │ │ + │ │ │ │ + + ── + ── + + ── + + ── + + │ │ + │ │ + ── + ── + ── + + ── + ── + + ── + │ │ + │ │ + + ── + + ── + ── + + ── + + │ │ │ │ + │ │ │ │ + ── + + + ── + + + + ── + │ │ │ │ │ │ + │ │ │ │ │ │ + + ── + + ── + + + ── + + │ │ + │ │ + ── + + ── + ── + + + ── + ── + │ │ │ │ + │ │ │ │ + + ── + + ── + + + ── + + │ │ │ │ + │ │ │ │ Gyration on an alternating sign matrix/fully packed loop ``fpl`` of the link pattern corresponding to ``fpl``:: @@ -354,34 +357,34 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): sage: A = AlternatingSignMatrix([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) sage: fpl = FullyPackedLoop(A) sage: fpl - | | - | | - + -- + + - | | - | | - -- + + + -- - | | - | | - + + -- + - | | - | | + │ │ + │ │ + + ── + + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + + ── + + │ │ + │ │ sage: FullyPackedLoops(3)(A) == fpl True We can also input a matrix:: sage: FullyPackedLoop([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) - | | - | | - + -- + + - | | - | | - -- + + + -- - | | - | | - + + -- + - | | - | | + │ │ + │ │ + + ── + + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + + ── + + │ │ + │ │ sage: FullyPackedLoop([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) ==\ ....: FullyPackedLoops(3)([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) True @@ -391,17 +394,17 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): sage: S = SixVertexModel(3, boundary_conditions='ice').from_alternating_sign_matrix(A) sage: fpl = FullyPackedLoop(S) sage: fpl - | | - | | - + -- + + - | | - | | - -- + + + -- - | | - | | - + + -- + - | | - | | + │ │ + │ │ + + ── + + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + + ── + + │ │ + │ │ sage: FullyPackedLoops(3)(S) == FullyPackedLoop(S) True @@ -424,14 +427,14 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): V V sage: FullyPackedLoop([[3,1],[5,3]]) - | - | - + + -- - | | - | | - -- + + - | - | + │ + │ + + + ── + │ │ + │ │ + ── + + + │ + │ sage: FullyPackedLoops(2)([[3,1],[5,3]]) == FullyPackedLoop([[3,1],[5,3]]) True @@ -491,34 +494,34 @@ def __classcall_private__(cls, generator): sage: A = AlternatingSignMatrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]) sage: FullyPackedLoop(A) - | | - | | - + + -- + - | | - | | - -- + + + -- - | | - | | - + -- + + - | | - | | + │ │ + │ │ + + + ── + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + ── + + + │ │ + │ │ sage: SVM = SixVertexModel(4, boundary_conditions='ice')[0] sage: FullyPackedLoop(SVM) - | | - | | - + + -- + + -- - | | | - | | | - -- + + + -- + - | | - | | - + -- + + + -- - | | | - | | | - -- + + -- + + - | | - | | + │ │ + │ │ + + + ── + + ── + │ │ │ + │ │ │ + ── + + + ── + + │ │ + │ │ + + ── + + + ── + │ │ │ + │ │ │ + ── + + ── + + + │ │ + │ │ """ if isinstance(generator, AlternatingSignMatrix): SVM = generator.to_six_vertex_model() @@ -556,7 +559,6 @@ def __init__(self, parent, generator): sage: A = AlternatingSignMatrix([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) sage: fpl = FullyPackedLoop(A) sage: TestSuite(fpl).run() - """ if isinstance(generator, AlternatingSignMatrix): self._six_vertex_model = generator.to_six_vertex_model() @@ -574,61 +576,57 @@ def _repr_(self): sage: A = AlternatingSignMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) sage: fpl = FullyPackedLoop(A) sage: fpl - | | - | | - + + -- + - | | - | | - -- + + + -- - | | - | | - + -- + + - | | - | | + │ │ + │ │ + + + ── + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + ── + + + │ │ + │ │ sage: A = AlternatingSignMatrix([[0,1,0,0],[0,0,1,0],[1,-1,0,1],[0,1,0,0]]) sage: S = SixVertexModel(4, boundary_conditions='ice').from_alternating_sign_matrix(A) sage: fpl = FullyPackedLoop(S) sage: fpl - | | - | | - + -- + -- + + -- - | - | - -- + + -- + -- + - | | - | | - + + + -- + -- - | | | - | | | - -- + + + -- + - | | - | | - + │ │ + │ │ + + ── + ── + + ── + │ + │ + ── + + ── + ── + + │ │ + │ │ + + + + ── + ── + │ │ │ + │ │ │ + ── + + + ── + + │ │ + │ │ """ # List are in the order of URDL # One set of rules for how to draw around even vertex, one set of rules for odd vertex n = len(self._six_vertex_model) - 1 - ascii1 = [[r' ', ' -', r' ', '- '], # LR - [r' | ', ' ', r' ', '- '], # LU - [r' ', ' ', r' | ', '- '], # LD - [r' | ', ' ', r' | ', ' '], # UD - [r' | ', ' -', r' ', ' '], # UR - [r' ', ' -', r' | ', ' ']] # RD - - ascii2 = [[r' | ', ' ', r' | ', ' '], # LR - [r' ', ' -', r' | ', ' '], # LU - [r' | ', ' -', r' ', ' '], # LD - [r' ', ' -', r' ', '- '], # UD - [r' ', ' ', r' | ', '- '], # UR - [r' | ', ' ', r' ', '- ']] # RD + ascii1 = [[r' ', ' ─', r' ', '─ '], # LR + [r' │ ', ' ', r' ', '─ '], # LU + [r' ', ' ', r' │ ', '─ '], # LD + [r' │ ', ' ', r' │ ', ' '], # UD + [r' │ ', ' ─', r' ', ' '], # UR + [r' ', ' ─', r' │ ', ' ']] # RD + + ascii2 = [[r' │ ', ' ', r' │ ', ' '], # LR + [r' ', ' ─', r' │ ', ' '], # LU + [r' │ ', ' ─', r' ', ' '], # LD + [r' ', ' ─', r' ', '─ '], # UD + [r' ', ' ', r' │ ', '─ '], # UR + [r' │ ', ' ', r' ', '─ ']] # RD ret = ' ' # Do the top line for i, entry in enumerate(self._six_vertex_model[0]): - if i % 2 == 0: - ret += ' | ' - else: - ret += ' ' + ret += ' ' if i % 2 else ' │ ' plus_sign = '+' @@ -637,17 +635,17 @@ def _repr_(self): ret += '\n ' # Do the top row for i, entry in enumerate(row): - if (i + j) % 2 == 0: + if not (i + j) % 2: ret += ascii1[entry][0] else: ret += ascii2[entry][0] ret += '\n' # Do the left-most entry - if j % 2 == 0: + if not j % 2: ret += ' ' else: - ret += ' -' + ret += ' ─' # Do the middle row for i, entry in enumerate(row): @@ -657,15 +655,15 @@ def _repr_(self): ret += ascii2[entry][3] + plus_sign + ascii2[entry][1] # Do the right-most entry - if (j+n) % 2 == 0: + if not (j + n) % 2: ret += ' ' else: - ret += '- ' + ret += '─ ' # Do the bottom row ret += '\n ' for i, entry in enumerate(row): - if (i + j) % 2 == 0: + if not (i + j) % 2: ret += ascii1[entry][2] else: ret += ascii2[entry][2] @@ -673,10 +671,7 @@ def _repr_(self): # Do the bottom line ret += '\n ' for i, entry in enumerate(self._six_vertex_model[-1]): - if (i+n+1) % 2 == 0: - ret += ' ' - else: - ret += ' | ' + ret += ' │ ' if (i + n + 1) % 2 else ' ' return ret @@ -750,19 +745,17 @@ def plot(self, **options): INPUT: - - ``link``, ``loop`` -- (boolean, default ``True``) whether to plot the links + - ``link``, ``loop`` -- boolean (default: ``True``); whether to plot the links or the loops - - ``color``, ``link_color``, ``loop_color`` -- (optional, a string or a - RGB triple) + - ``color``, ``link_color``, ``loop_color`` -- (optional) string or RGB triple - - ``colors``, ``link_colors``, ``loop_colors`` -- (optional, list) a list of - colors + - ``colors``, ``link_colors``, ``loop_colors`` -- (optional) list of colors - ``color_map``, ``link_color_map``, ``loop_color_map`` -- (string, optional) a name of a matplotlib color map for the link or the loop - - ``link_color_randomize`` -- (boolean, default ``False``) when + - ``link_color_randomize`` -- boolean (default: ``False``); when ``link_colors`` or ``link_color_map`` is specified it randomizes its order. Setting this option to ``True`` makes it unlikely to have two neighboring links with the same color. @@ -1196,17 +1189,17 @@ def six_vertex_model(self): sage: B = AlternatingSignMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) sage: fpl = FullyPackedLoop(B) sage: fpl - | | - | | - + + -- + - | | - | | - -- + + + -- - | | - | | - + -- + + - | | - | | + │ │ + │ │ + + + ── + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + ── + + + │ │ + │ │ sage: fpl.six_vertex_model() ^ ^ ^ | | | @@ -1328,20 +1321,20 @@ def _element_constructor_(self, generator): sage: A = AlternatingSignMatrix(M) sage: elt = FullyPackedLoop(A) sage: FPL = FPLs(elt); FPL - | | - | | - + + -- + + -- - | | | - | | | - -- + + + -- + - | | - | | - + -- + + + -- - | | | - | | | - -- + + -- + + - | | - | | + │ │ + │ │ + + + ── + + ── + │ │ │ + │ │ │ + ── + + + ── + + │ │ + │ │ + + ── + + + ── + │ │ │ + │ │ │ + ── + + ── + + + │ │ + │ │ sage: FPLs(A) == FPL True @@ -1357,14 +1350,14 @@ def _element_constructor_(self, generator): sage: FPL = FullyPackedLoops(2) sage: FPL([[3,1],[5,3]]) - | - | - + + -- - | | - | | - -- + + - | - | + │ + │ + + + ── + │ │ + │ │ + ── + + + │ + │ """ if isinstance(generator, AlternatingSignMatrix): SVM = generator.to_six_vertex_model() @@ -1422,17 +1415,17 @@ def _an_element_(self): sage: FPLs = FullyPackedLoops(3) sage: FPLs.an_element() - | | - | | - + + -- + - | | - | | - -- + + + -- - | | - | | - + -- + + - | | - | | + │ │ + │ │ + + + ── + + │ │ + │ │ + ── + + + ── + │ │ + │ │ + + ── + + + │ │ + │ │ """ # ASM = AlternatingSignMatrix(matrix.identity(self._n)) # SVM = ASM.to_six_vertex_model() diff --git a/src/sage/combinat/gelfand_tsetlin_patterns.py b/src/sage/combinat/gelfand_tsetlin_patterns.py index 35b18541356..5c3c485e549 100644 --- a/src/sage/combinat/gelfand_tsetlin_patterns.py +++ b/src/sage/combinat/gelfand_tsetlin_patterns.py @@ -302,11 +302,9 @@ def boxed_entries(self) -> tuple: sage: G.boxed_entries() ((1, 0),) """ - ret = [] - for i in range(1, len(self)): - for j in range(len(self[i])): - if self[i][j] == self[i - 1][j]: - ret.append((i, j)) + ret = [(i, j) for i in range(1, len(self)) + for j, selfij in enumerate(self[i]) + if selfij == self[i - 1][j]] return tuple(ret) @cached_method @@ -324,11 +322,9 @@ def circled_entries(self) -> tuple: sage: G.circled_entries() ((1, 1), (2, 0)) """ - ret = [] - for i in range(1, len(self)): - for j in range(len(self[i])): - if self[i][j] == self[i - 1][j + 1]: - ret.append((i, j)) + ret = [(i, j) for i in range(1, len(self)) + for j, selfij in enumerate(self[i]) + if selfij == self[i - 1][j + 1]] return tuple(ret) @cached_method @@ -349,11 +345,9 @@ def special_entries(self) -> tuple: sage: G.special_entries() ((2, 0),) """ - ret = [] - for i in range(1, len(self)): - for j in range(len(self[i])): - if self[i-1][j] > self[i][j] and self[i][j] > self[i-1][j+1]: - ret.append((i, j)) + ret = [(i, j) for i in range(1, len(self)) + for j, selfij in enumerate(self[i]) + if self[i - 1][j] > selfij > self[i - 1][j + 1]] return tuple(ret) def number_of_boxes(self) -> int: @@ -479,8 +473,8 @@ def Tokuyama_coefficient(self, name='t'): INPUT: - - ``name`` -- (Default: ``'t'``) An alternative name for the - variable `t`. + - ``name`` -- (default: ``'t'``) an alternative name for the + variable `t` EXAMPLES:: @@ -579,15 +573,15 @@ class GelfandTsetlinPatterns(UniqueRepresentation, Parent): INPUT: - - ``n`` -- The width or depth of the array, also known as the rank + - ``n`` -- the width or depth of the array, also known as the rank - - ``k`` -- (Default: ``None``) If specified, this is the maximum value that + - ``k`` -- (default: ``None``) if specified, this is the maximum value that can occur in the patterns - - ``top_row`` -- (Default: ``None``) If specified, this is the fixed top + - ``top_row`` -- (default: ``None``) if specified, this is the fixed top row of all patterns - - ``strict`` -- (Default: ``False``) Set to ``True`` if all patterns are + - ``strict`` -- (default: ``False``) set to ``True`` if all patterns are strict patterns TESTS: @@ -1018,14 +1012,12 @@ def _toggle_markov_chain(self, chain_state, row, col, direction): INPUT: - - ``chain_state`` -- A GelfandTsetlin pattern represented as a list of lists - - ``row`` -- The row of the cell being modified - - ``col`` -- The column of the cell being modified - - ``direction`` -- The direction to change the cell 1 = increase, 0 = decrease - - OUTPUT: + - ``chain_state`` -- a GelfandTsetlin pattern represented as a list of lists + - ``row`` -- the row of the cell being modified + - ``col`` -- the column of the cell being modified + - ``direction`` -- the direction to change the cell 1 = increase, 0 = decrease - ``chain_state`` is possibly modified. + OUTPUT: ``chain_state`` is possibly modified TESTS: @@ -1341,8 +1333,8 @@ def Tokuyama_formula(self, name='t'): INPUT: - - ``name`` -- (Default: ``'t'``) An alternative name for the - variable `t`. + - ``name`` -- (default: ``'t'``) an alternative name for the + variable `t` EXAMPLES:: diff --git a/src/sage/combinat/graph_path.py b/src/sage/combinat/graph_path.py index 2fb255579dd..df84b1acdf7 100644 --- a/src/sage/combinat/graph_path.py +++ b/src/sage/combinat/graph_path.py @@ -236,11 +236,7 @@ def paths_from_source_to_target(self, source, target): [[2, 3, 4], [2, 4]] """ source_paths = self.outgoing_paths(source) - paths = [] - for path in source_paths: - if path[-1] == target: - paths.append(path) - return paths + return [path for path in source_paths if path[-1] == target] def paths(self): """ diff --git a/src/sage/combinat/gray_codes.py b/src/sage/combinat/gray_codes.py index e2508e0e01c..63e366c2cb5 100644 --- a/src/sage/combinat/gray_codes.py +++ b/src/sage/combinat/gray_codes.py @@ -21,7 +21,7 @@ def product(m): INPUT: - - ``m`` -- a list or tuple of positive integers that correspond to the size + - ``m`` -- list or tuple of positive integers that correspond to the size of the sets in the product EXAMPLES:: @@ -119,9 +119,9 @@ def combinations(n,t): INPUT: - - ``n`` -- (integer or ``Infinity``) -- size of the ground set + - ``n`` -- integer or ``Infinity``; size of the ground set - - ``t`` -- (integer) -- size of the subsets + - ``t`` -- integer; size of the subsets EXAMPLES:: @@ -193,7 +193,6 @@ def combinations(n,t): Traceback (most recent call last): ... AssertionError: t(=6) must be >=0 and <=n(=5) - """ from sage.rings.infinity import Infinity t = int(t) diff --git a/src/sage/combinat/grossman_larson_algebras.py b/src/sage/combinat/grossman_larson_algebras.py index db2f1de5eca..0e68753f52e 100644 --- a/src/sage/combinat/grossman_larson_algebras.py +++ b/src/sage/combinat/grossman_larson_algebras.py @@ -202,7 +202,7 @@ def __init__(self, R, names=None): cat = HopfAlgebras(R).WithBasis().Graded() CombinatorialFreeModule.__init__(self, R, Trees, - latex_prefix="", + latex_prefix='', sorting_key=key, category=cat) @@ -267,7 +267,7 @@ def single_vertex(self, i): INPUT: - - ``i`` -- a nonnegative integer + - ``i`` -- nonnegative integer EXAMPLES:: @@ -336,7 +336,7 @@ def change_ring(self, R): INPUT: - - `R` -- a ring + - ``R`` -- a ring EXAMPLES:: diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index 89657cfc2f6..958b664e7cd 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -27,7 +27,7 @@ Growth diagrams, invented by Sergey Fomin [Fom1994]_, [Fom1995]_, provide a vast generalization of the Robinson-Schensted-Knuth (RSK) -correspondence between matrices with non-negative integer entries and +correspondence between matrices with nonnegative integer entries and pairs of semistandard Young tableaux of the same shape. The main fact is that many correspondences similar to RSK can be @@ -127,7 +127,7 @@ In general, growth diagrams are defined for `0-1`-fillings of arbitrary skew shapes. In the case of the Robinson-Schensted-Knuth -correspondence, even arbitrary non-negative integers are allowed. In +correspondence, even arbitrary nonnegative integers are allowed. In other cases, entries may be either zero or an `r`-th root of unity - for example, :class:`~sage.combinat.growth.RuleDomino` insertion is defined for signed permutations, that is, `r=2`. Traditionally, words @@ -138,7 +138,7 @@ to (signed) entries, where zeros can be omitted. In this case, when the parameter ``shape`` is not explicitly specified, it is assumed to be the minimal rectangle containing the origin and all coordinates -with non-zero entries. +with nonzero entries. For example, consider the following generalized permutation:: @@ -183,8 +183,8 @@ between oscillating tableaux and (partial) perfect matchings. Perfect matchings of `\{1, \ldots, 2r\}` are in bijection with `0-1`-fillings of a triangular shape with `2r-1` rows, such that for -each `k` there is either exactly one non-zero entry in row `k` or -exactly one non-zero entry in column `2r-k`. Explicitly, if `(i,j)` +each `k` there is either exactly one nonzero entry in row `k` or +exactly one nonzero entry in column `2r-k`. Explicitly, if `(i,j)` is a pair in the perfect matching, the entry in column `i-1` and row `2r-j` equals `1`. For example:: @@ -339,7 +339,7 @@ For illustration, let us implement a growth diagram class with the backward rule only. Suppose that the vertices of the graph are the -non-negative integers, the rank is given by the integer itself, and +nonnegative integers, the rank is given by the integer itself, and the backward rule is `(y, z, x) \mapsto (\min(x,y), 0)` if `y = z` or `x = z` and `(y, z, x) \mapsto (\min(x,y), 1)` otherwise. @@ -517,7 +517,7 @@ class GrowthDiagram(SageObject): Growth diagrams were introduced by Sergey Fomin [Fom1994]_, [Fom1995]_ and provide a vast generalization of the Robinson-Schensted-Knuth (RSK) correspondence between matrices - with non-negative integer entries and pairs of semistandard Young + with nonnegative integer entries and pairs of semistandard Young tableaux of the same shape. A growth diagram is based on the notion of *dual graded graphs*, @@ -918,7 +918,6 @@ def P_chain(self): sage: BinaryWord = GrowthDiagram.rules.BinaryWord() sage: BinaryWord(filling = {}).P_chain() [word: ] - """ if not self.is_rectangular(): raise ValueError("the P symbol is only defined for rectangular shapes") @@ -948,7 +947,6 @@ def Q_chain(self): sage: BinaryWord = GrowthDiagram.rules.BinaryWord() sage: BinaryWord(filling = {}).Q_chain() [word: ] - """ if not self.is_rectangular(): raise ValueError("the Q symbol is only defined for rectangular shapes") @@ -1051,7 +1049,7 @@ def to_biword(self): w2.extend([j+1]*v) else: raise ValueError("can only convert fillings with" - " non-negative entries to words") + " nonnegative entries to words") return (w1, w2) def __iter__(self): @@ -1625,9 +1623,9 @@ class Rule(UniqueRepresentation): - ``r`` -- (default: 1) the parameter in the equation `DU - UD = rI` - - ``has_multiple_edges`` -- (default: ``False``) if the dual + - ``has_multiple_edges`` -- boolean (default: ``False``); if the dual graded graph has multiple edges and therefore edges are - triples consisting of two vertices and a label. + triples consisting of two vertices and a label - ``zero_edge`` -- (default: 0) the zero label of the edges of the graphs used for degenerate edges. It is @@ -1636,12 +1634,12 @@ class Rule(UniqueRepresentation): Subclasses may provide the following methods: - ``normalize_vertex`` -- a function that converts its input to a - vertex. + vertex - - ``vertices`` -- a function that takes a non-negative integer - as input and returns the list of vertices on this rank. + - ``vertices`` -- a function that takes a nonnegative integer + as input and returns the list of vertices on this rank - - ``rank`` -- the rank function of the dual graded graphs. + - ``rank`` -- the rank function of the dual graded graphs - ``forward_rule`` -- a function with input ``(y, t, x, content)`` or ``(y, e, t, f, x, content)`` if @@ -1752,7 +1750,7 @@ def _check_duality(self, n): INPUT: - - ``n`` -- a positive integer specifying which rank of + - ``n`` -- positive integer specifying which rank of the graph to test EXAMPLES: @@ -2038,7 +2036,6 @@ def P_symbol(self, P_chain): . . . . 2 . . 1 3 . 4 5 - """ chain = P_chain[::2] shape = chain[-1] @@ -2091,7 +2088,6 @@ def Q_symbol(self, Q_chain): . . . . 2 . . 1 4' . 3' 5' - """ chain = Q_chain shape = chain[-1] @@ -2165,7 +2161,6 @@ def forward_rule(self, y, e, t, f, x, content): sage: Shifted.forward_rule([3], 0, [2], 3, [3], 0) (3, [4], 0) - """ if e != 0: raise ValueError("the P-graph should not be colored") @@ -3212,9 +3207,7 @@ def forward_rule(self, y, t, x, content): - ``content`` -- `0` or `1`; the content of the cell - OUTPUT: - - The fourth binary tree ``z``. + OUTPUT: the fourth binary tree ``z`` EXAMPLES:: @@ -3528,9 +3521,7 @@ def forward_rule(self, y, t, x, content): - ``content`` -- `0` or `1`; the content of the cell - OUTPUT: - - The fourth Fibonacci word. + OUTPUT: the fourth Fibonacci word EXAMPLES:: @@ -3710,7 +3701,7 @@ class RuleRSK(RulePartitions): Partitions of the integer 3 The local rules implemented provide the RSK correspondence - between matrices with non-negative integer entries and pairs of + between matrices with nonnegative integer entries and pairs of semistandard tableaux, the :meth:`~sage.combinat.growth.RulePartitions.P_symbol` and the :meth:`~sage.combinat.growth.RulePartitions.Q_symbol`. For @@ -3770,7 +3761,7 @@ def forward_rule(self, y, t, x, content): t x y - - ``content`` -- a non-negative integer; the content of the cell + - ``content`` -- nonnegative integer; the content of the cell OUTPUT: @@ -3875,7 +3866,7 @@ class RuleBurge(RulePartitions): Partitions of the integer 3 The local rules implemented provide Burge's correspondence - between matrices with non-negative integer entries and pairs of + between matrices with nonnegative integer entries and pairs of semistandard tableaux, the :meth:`~sage.combinat.growth.RulePartitions.P_symbol` and the :meth:`~sage.combinat.growth.RulePartitions.Q_symbol`. For @@ -3922,11 +3913,9 @@ def forward_rule(self, y, t, x, content): t x y - - ``content`` -- a non-negative integer; the content of the cell - - OUTPUT: + - ``content`` -- nonnegative integer; the content of the cell - The fourth partition according to the Burge correspondence. + OUTPUT: the fourth partition according to the Burge correspondence EXAMPLES:: @@ -4217,9 +4206,7 @@ def forward_rule(self, y, t, x, content): - ``content`` -- `-1`, `0` or `1`; the content of the cell - OUTPUT: - - The fourth partition according to domino insertion. + OUTPUT: the fourth partition according to domino insertion EXAMPLES:: diff --git a/src/sage/combinat/hall_polynomial.py b/src/sage/combinat/hall_polynomial.py index 9d2326e60f8..96e23908d37 100644 --- a/src/sage/combinat/hall_polynomial.py +++ b/src/sage/combinat/hall_polynomial.py @@ -171,7 +171,7 @@ def hall_polynomial(nu, mu, la, q=None): for k in range(n): r.append(r[-1] + sum(exp_mu[k:]) - sum(exp_nu[k:])) # Now, r is [r_0, r_1, ..., r_n]. - exp_nu += [0]*(n - len(exp_nu)) # Pad with 0's until it has length n + exp_nu += [0]*(n - len(exp_nu)) # Pad with 0s until it has length n # Note that all -1 for exp_nu is due to indexing t = sum((r[k-2] - r[k-1])*(sum(exp_nu[k-1:]) - r[k-1]) for k in range(2,n+1)) if t < 0: diff --git a/src/sage/combinat/hillman_grassl.py b/src/sage/combinat/hillman_grassl.py index 5a85d4e48d3..c4e0f48088d 100644 --- a/src/sage/combinat/hillman_grassl.py +++ b/src/sage/combinat/hillman_grassl.py @@ -462,7 +462,7 @@ def _repr_(self): def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. TESTS:: @@ -771,9 +771,8 @@ def pak_correspondence(M, copy=True): INPUT: - - ``copy`` (default: ``True``) -- boolean; - if set to ``False``, the algorithm will mutate the - input (but be more efficient) + - ``copy`` -- boolean (default: ``True``); if set to ``False``, the + algorithm will mutate the input (but be more efficient) EXAMPLES:: diff --git a/src/sage/combinat/integer_lists/base.pyx b/src/sage/combinat/integer_lists/base.pyx index 6da2125396e..d2bd5da3b92 100644 --- a/src/sage/combinat/integer_lists/base.pyx +++ b/src/sage/combinat/integer_lists/base.pyx @@ -394,7 +394,7 @@ cdef class Envelope(): inf sage: f.min_slope 1 - sage: TestSuite(f).run(skip="_test_pickling") + sage: TestSuite(f).run(skip='_test_pickling') sage: Envelope(3, sign=1/3, max_slope=-1, min_length=4) Traceback (most recent call last): ... @@ -518,7 +518,6 @@ cdef class Envelope(): sage: Envelope(lambda x: 3, sign=-1, min_part=2).limit_start() == Infinity True - """ return self.f_limit_start @@ -526,7 +525,7 @@ cdef class Envelope(): r""" Return a bound on the limit of ``self``. - OUTPUT: a nonnegative integer or `\infty` + OUTPUT: nonnegative integer or `\infty` This returns some upper bound for the accumulation points of this upper envelope. For a lower envelope, a lower bound is @@ -605,9 +604,9 @@ cdef class Envelope(): INPUT: - - ``m`` -- a nonnegative integer (starting value) + - ``m`` -- nonnegative integer (starting value) - - ``j`` -- a nonnegative integer (position) + - ``j`` -- nonnegative integer (position) This method adapts this envelope to the additional local constraint imposed by having a part `m` at position `j`. diff --git a/src/sage/combinat/integer_lists/invlex.pyx b/src/sage/combinat/integer_lists/invlex.pyx index d8ab12b0a3d..6bef85031ce 100644 --- a/src/sage/combinat/integer_lists/invlex.pyx +++ b/src/sage/combinat/integer_lists/invlex.pyx @@ -62,64 +62,64 @@ class IntegerListsLex(IntegerLists, metaclass=ClasscallMetaclass): INPUT: - - ``min_sum`` -- a nonnegative integer (default: 0): - a lower bound on ``sum(l)``. + - ``min_sum`` -- nonnegative integer (default: 0); + a lower bound on ``sum(l)`` - - ``max_sum`` -- a nonnegative integer or `\infty` (default: `\infty`): - an upper bound on ``sum(l)``. + - ``max_sum`` -- nonnegative integer or `\infty` (default: `\infty`); + an upper bound on ``sum(l)`` - - ``n`` -- a nonnegative integer (optional): if specified, this - overrides ``min_sum`` and ``max_sum``. + - ``n`` -- nonnegative integer (optional); if specified, this + overrides ``min_sum`` and ``max_sum`` - - ``min_length`` -- a nonnegative integer (default: `0`): a lower - bound on ``len(l)``. + - ``min_length`` -- nonnegative integer (default: `0`); a lower + bound on ``len(l)`` - - ``max_length`` -- a nonnegative integer or `\infty` (default: - `\infty`): an upper bound on ``len(l)``. + - ``max_length`` -- nonnegative integer or `\infty` (default: + `\infty`); an upper bound on ``len(l)`` - - ``length`` -- an integer (optional); overrides ``min_length`` - and ``max_length`` if specified; + - ``length`` -- integer (optional); overrides ``min_length`` + and ``max_length`` if specified - - ``min_part`` -- a nonnegative integer: a lower bounds on all - parts: ``min_part <= l[i]`` for ``0 <= i < len(l)``. + - ``min_part`` -- nonnegative integer; a lower bounds on all + parts: ``min_part <= l[i]`` for ``0 <= i < len(l)`` - - ``floor`` -- a list of nonnegative integers or a function: lower - bounds on the individual parts `l[i]`. + - ``floor`` -- list of nonnegative integers or a function; lower + bounds on the individual parts `l[i]` If ``floor`` is a list of integers, then ``floor<=l[i]`` for ``0 <= i < min(len(l), len(floor)``. Similarly, if ``floor`` is a function, then ``floor(i) <= l[i]`` for ``0 <= i < len(l)``. - - ``max_part`` -- a nonnegative integer or `\infty`: an upper - bound on all parts: ``l[i] <= max_part`` for ``0 <= i < len(l)``. + - ``max_part`` -- nonnegative integer or `\infty`; an upper + bound on all parts: ``l[i] <= max_part`` for ``0 <= i < len(l)`` - ``ceiling`` -- upper bounds on the individual parts ``l[i]``; this takes the same type of input as ``floor``, except that `\infty` is allowed in addition to integers, and the default value is `\infty`. - - ``min_slope`` -- an integer or `-\infty` (default: `-\infty`): + - ``min_slope`` -- integer or `-\infty` (default: `-\infty`); a lower bound on the slope between consecutive parts: ``min_slope <= l[i+1]-l[i]`` for ``0 <= i < len(l)-1`` - - ``max_slope`` -- an integer or `+\infty` (defaults: `+\infty`) + - ``max_slope`` -- integer or `+\infty` (defaults: `+\infty`); an upper bound on the slope between consecutive parts: ``l[i+1]-l[i] <= max_slope`` for ``0 <= i < len(l)-1`` - ``category`` -- a category (default: :class:`FiniteEnumeratedSets`) - - ``check`` -- boolean (default: ``True``): whether to display the + - ``check`` -- boolean (default: ``True``); whether to display the warnings raised when functions are given as input to ``floor`` or ``ceiling`` and the errors raised when there is no proper enumeration. - - ``name`` -- a string or ``None`` (default: ``None``) if set, + - ``name`` -- string or ``None`` (default: ``None``); if set, this will be passed down to :meth:`Parent.rename` to specify the name of ``self``. It is recommended to use rename method directly because this feature may become deprecated. - ``element_constructor`` -- a function (or callable) that creates - elements of ``self`` from a list. See also :class:`Parent`. + elements of ``self`` from a list. See also :class:`Parent` - ``element_class`` -- a class for the elements of ``self`` (default: `ClonableArray`). This merely sets the attribute @@ -862,7 +862,7 @@ If you know what you are doing, you can set check=False to skip this warning.""" ``None`` if this method finds a proof that there exists an upper bound on the length. Otherwise a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. EXAMPLES:: @@ -1101,8 +1101,8 @@ class IntegerListsLexIter(builtins.object): - ``_current_sum`` -- the sum of the parts of ``_current_list``; - - ``_search_ranges`` -- a list of same length as - ``_current_list``: the range for each part. + - ``_search_ranges`` -- list of same length as + ``_current_list``: the range for each part Furthermore, we assume that there is no obvious contradiction in the constraints: @@ -1177,7 +1177,7 @@ class IntegerListsLexIter(builtins.object): The push may fail if it is discovered that ``self._current_list`` cannot be extended in a valid way. - OUTPUT: a boolean: whether the push succeeded + OUTPUT: boolean; whether the push succeeded EXAMPLES:: @@ -1388,11 +1388,11 @@ class IntegerListsLexIter(builtins.object): INPUT: - - ``i`` -- a nonnegative integer (position) + - ``i`` -- nonnegative integer (position) - - ``max_sum`` -- a nonnegative integer or ``+oo`` + - ``max_sum`` -- nonnegative integer or ``+oo`` - - ``prev`` -- a nonnegative integer or ``None`` + - ``prev`` -- nonnegative integer or ``None`` Return coarse lower and upper bounds for the value ``m`` of the part at position ``i`` so that there could exists diff --git a/src/sage/combinat/integer_lists/lists.py b/src/sage/combinat/integer_lists/lists.py index 8e121461056..6a4c3cb35a3 100644 --- a/src/sage/combinat/integer_lists/lists.py +++ b/src/sage/combinat/integer_lists/lists.py @@ -280,7 +280,7 @@ def __contains__(self, item): def _element_constructor_default(self, l): """ - Default element constructor + Default element constructor. EXAMPLES:: diff --git a/src/sage/combinat/integer_lists/meson.build b/src/sage/combinat/integer_lists/meson.build new file mode 100644 index 00000000000..ac9aab23386 --- /dev/null +++ b/src/sage/combinat/integer_lists/meson.build @@ -0,0 +1,22 @@ +py.install_sources( + '__init__.py', + 'base.pxd', + 'invlex.pxd', + 'lists.py', + 'nn.py', + subdir: 'sage/combinat/integer_lists', +) + +extension_data = {'base' : files('base.pyx'), 'invlex' : files('invlex.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/integer_lists', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/combinat/integer_matrices.py b/src/sage/combinat/integer_matrices.py index db8105dd6ba..f97691338ff 100644 --- a/src/sage/combinat/integer_matrices.py +++ b/src/sage/combinat/integer_matrices.py @@ -1,8 +1,8 @@ # sage.doctest: needs sage.combinat sage.modules r""" -Counting, generating, and manipulating non-negative integer matrices +Counting, generating, and manipulating nonnegative integer matrices -Counting, generating, and manipulating non-negative integer matrices with +Counting, generating, and manipulating nonnegative integer matrices with prescribed row sums and column sums. AUTHORS: @@ -26,7 +26,7 @@ class IntegerMatrices(UniqueRepresentation, Parent): r""" - The class of non-negative integer matrices with + The class of nonnegative integer matrices with prescribed row sums and column sums. An *integer matrix* `m` with column sums `c := (c_1,...,c_k)` and row @@ -51,7 +51,6 @@ class IntegerMatrices(UniqueRepresentation, Parent): ] sage: IM.cardinality() 6 - """ @staticmethod def __classcall__(cls, row_sums, column_sums): @@ -72,7 +71,6 @@ def __classcall__(cls, row_sums, column_sums): Non-negative integer matrices with row sums [4, 4, 5] and column sums [3, 7, 1, 2] sage: IM = IntegerMatrices(Composition([4,4,5]), Composition([3,7,1,2])); IM Non-negative integer matrices with row sums [4, 4, 5] and column sums [3, 7, 1, 2] - """ from sage.combinat.composition import Composition row_sums = Composition(row_sums) @@ -134,14 +132,13 @@ def __iter__(self): [1 0] [0 1] [0 1], [1 0] ] - """ for x in integer_matrices_generator(self._row_sums, self._col_sums): yield matrix(ZZ, x) def __contains__(self, x): r""" - Tests if ``x`` is an element of ``self``. + Test if ``x`` is an element of ``self``. INPUT: @@ -218,7 +215,6 @@ def cardinality(self): 0 sage: len(IntegerMatrices([0], [0]).list()) 1 - """ from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.partition import Partition @@ -231,9 +227,7 @@ def row_sums(self): r""" The row sums of the integer matrices in ``self``. - OUTPUT: - - - Composition + OUTPUT: Composition EXAMPLES:: @@ -248,9 +242,7 @@ def column_sums(self): r""" The column sums of the integer matrices in ``self``. - OUTPUT: - - - Composition + OUTPUT: Composition EXAMPLES:: @@ -306,9 +298,7 @@ def integer_matrices_generator(row_sums, column_sums): - ``row_sums`` -- list or tuple - ``column_sums`` -- list or tuple - OUTPUT: - - - an iterator producing a list of lists + OUTPUT: an iterator producing a list of lists EXAMPLES:: diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index 3f4b59974a4..6848609cf5d 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -49,7 +49,7 @@ def is_gale_ryser(r, s): r""" - Tests whether the given sequences satisfy the condition + Test whether the given sequences satisfy the condition of the Gale-Ryser theorem. Given a binary matrix `B` of dimension `n\times m`, the @@ -59,14 +59,14 @@ def is_gale_ryser(r, s): If, given a binary matrix, these two vectors are easy to compute, the Gale-Ryser theorem lets us decide whether, given two - non-negative vectors `r,s`, there exists a binary matrix + nonnegative vectors `r,s`, there exists a binary matrix whose row/column sums vectors are `r` and `s`. This functions answers accordingly. INPUT: - - ``r``, ``s`` -- lists of non-negative integers. + - ``r``, ``s`` -- lists of nonnegative integers ALGORITHM: @@ -103,7 +103,7 @@ def is_gale_ryser(r, s): generic-sounding) term ''realizable sequence''. """ - # The sequences only contain non-negative integers + # The sequences only contain nonnegative integers if [x for x in r if x < 0] or [x for x in s if x < 0]: return False @@ -123,10 +123,10 @@ def is_gale_ryser(r, s): return len(rstar) <= len(s2) and sum(r2) == sum(s2) and rstar.dominates(s) -def gale_ryser_theorem(p1, p2, algorithm="gale", +def gale_ryser_theorem(p1, p2, algorithm='gale', *, solver=None, integrality_tolerance=1e-3): r""" - Returns the binary matrix given by the Gale-Ryser theorem. + Return the binary matrix given by the Gale-Ryser theorem. The Gale Ryser theorem asserts that if `p_1,p_2` are two partitions of `n` of respective lengths `k_1,k_2`, then there is @@ -144,7 +144,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", - ``'ryser'`` implements the construction due to Ryser [Ryser63]_. - ``'gale'`` (default) implements the construction due to Gale [Gale57]_. - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -153,11 +153,9 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", :class:`MixedIntegerLinearProgram `. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` - OUTPUT: - - A binary matrix if it exists, ``None`` otherwise. + OUTPUT: a binary matrix if it exists, ``None`` otherwise Gale's Algorithm: @@ -179,7 +177,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", * Construct the `m \times n` matrix `B` from `r` by defining the `i`-th row of `B` to be the vector whose first `r_i` - entries are `1`, and the remainder are 0's, `1 \leq i \leq m`. + entries are `1`, and the remainder are 0s, `1 \leq i \leq m`. This maximal matrix `B` with row sum `r` and ones left justified has column sum `r^{*}`. @@ -225,27 +223,27 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", sage: from sage.combinat.integer_vector import gale_ryser_theorem sage: p1 = [3,3,1,1] sage: p2 = [3,3,1,1] - sage: gale_ryser_theorem(p1, p2, algorithm="ryser") + sage: gale_ryser_theorem(p1, p2, algorithm='ryser') [1 1 1 0] [1 1 0 1] [1 0 0 0] [0 1 0 0] sage: p1 = [4,2,2] sage: p2 = [3,3,1,1] - sage: gale_ryser_theorem(p1, p2, algorithm="ryser") + sage: gale_ryser_theorem(p1, p2, algorithm='ryser') [1 1 1 1] [1 1 0 0] [1 1 0 0] sage: p1 = [4,2,2,0] sage: p2 = [3,3,1,1,0,0] - sage: gale_ryser_theorem(p1, p2, algorithm="ryser") + sage: gale_ryser_theorem(p1, p2, algorithm='ryser') [1 1 1 1 0 0] [1 1 0 0 0 0] [1 1 0 0 0 0] [0 0 0 0 0 0] sage: p1 = [3,3,2,1] sage: p2 = [3,2,2,1,1] - sage: print(gale_ryser_theorem(p1, p2, algorithm="gale")) # not tested + sage: print(gale_ryser_theorem(p1, p2, algorithm='gale')) # not tested [1 1 1 0 0] [1 1 0 0 1] [1 0 1 0 0] @@ -254,7 +252,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", With `0` in the sequences, and with unordered inputs:: sage: from sage.combinat.integer_vector import gale_ryser_theorem - sage: gale_ryser_theorem([3,3,0,1,1,0], [3,1,3,1,0], algorithm="ryser") # needs sage.combinat sage.modules + sage: gale_ryser_theorem([3,3,0,1,1,0], [3,1,3,1,0], algorithm='ryser') # needs sage.combinat sage.modules [1 1 1 0 0] [1 0 1 1 0] [0 0 0 0 0] @@ -262,7 +260,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", [0 0 1 0 0] [0 0 0 0 0] sage: p1 = [3,1,1,1,1]; p2 = [3,2,2,0] - sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # needs sage.combinat sage.modules + sage: gale_ryser_theorem(p1, p2, algorithm='ryser') # needs sage.combinat sage.modules [1 1 1 0] [1 0 0 0] [1 0 0 0] @@ -295,11 +293,11 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", Null matrix:: - sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="gale") # needs sage.combinat sage.modules + sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm='gale') # needs sage.combinat sage.modules [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="ryser") # needs sage.combinat sage.modules + sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm='ryser') # needs sage.combinat sage.modules [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -451,7 +449,7 @@ class IntegerVector(ClonableArray): def check(self): """ Check to make sure this is a valid integer vector by making sure - all entries are non-negative. + all entries are nonnegative. EXAMPLES:: @@ -478,7 +476,7 @@ def check(self): ValueError: [2, 2] doesn't satisfy correct constraints """ if any(x < 0 for x in self): - raise ValueError("all entries must be non-negative") + raise ValueError("all entries must be nonnegative") if self not in self.parent(): raise ValueError(f"{self} doesn't satisfy correct constraints") @@ -553,7 +551,7 @@ def specht_module_dimension(self, base_ring=None): class IntegerVectors(Parent, metaclass=ClasscallMetaclass): """ - The class of (non-negative) integer vectors. + The class of (nonnegative) integer vectors. INPUT: @@ -566,7 +564,7 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): .. NOTE:: - The entries are non-negative integers. + The entries are nonnegative integers. EXAMPLES: @@ -581,7 +579,7 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): sage: [1, 0, 0] in IntegerVectors() True - Entries are non-negative:: + Entries are nonnegative:: sage: [-1, 2] in IntegerVectors() False @@ -785,9 +783,8 @@ def _unrank_helper(self, x, rtn): INPUT: - - ``x`` -- a nonnegative integer - - ``rtn`` -- a list of nonnegative integers - + - ``x`` -- nonnegative integer + - ``rtn`` -- list of nonnegative integers EXAMPLES:: @@ -943,7 +940,7 @@ def rank(self, x): INPUT: - - ``x`` -- a list with ``sum(x) == n`` + - ``x`` -- list with ``sum(x) == n`` EXAMPLES:: @@ -968,7 +965,7 @@ def unrank(self, x): INPUT: - - ``x`` -- an integer. + - ``x`` -- integer EXAMPLES:: @@ -1078,7 +1075,7 @@ def rank(self, x): INPUT: - - ``x`` -- a list with ``len(x) == k`` + - ``x`` -- list with ``len(x) == k`` EXAMPLES:: @@ -1103,7 +1100,7 @@ def unrank(self, x): INPUT: - - ``x`` -- an integer such that x < self.cardinality()`` + - ``x`` -- integer such that ``x < self.cardinality()`` EXAMPLES:: @@ -1170,26 +1167,24 @@ def _list_rec(self, n, k): INPUT: - - ``n`` -- degree (must be 0) + - ``n`` -- degree (must be 0) - - ``k`` -- length of exponent tuples (must be 0) + - ``k`` -- length of exponent tuples (must be 0) EXAMPLES:: sage: IV = IntegerVectors(2,3) - sage: IV._list_rec(2,3) + sage: list(IV._list_rec(2,3)) [(2, 0, 0), (1, 1, 0), (1, 0, 1), (0, 2, 0), (0, 1, 1), (0, 0, 2)] """ - res = [] - if k == 1: - return [(n, )] + yield (n,) + return for nbar in range(n + 1): n_diff = n - nbar for rest in self._list_rec(nbar, k - 1): - res.append((n_diff,) + rest) - return res + yield (n_diff,) + rest def __iter__(self): """ @@ -1315,7 +1310,7 @@ def rank(self, x): INPUT: - - ``x`` -- a list with ``sum(x) == n`` and ``len(x) == k`` + - ``x`` -- list with ``sum(x) == n`` and ``len(x) == k`` TESTS:: @@ -1338,7 +1333,7 @@ def unrank(self, x): INPUT: - - ``x`` -- an integer such that ``x < self.cardinality()`` + - ``x`` -- integer such that ``x < self.cardinality()`` EXAMPLES:: @@ -1376,9 +1371,9 @@ class IntegerVectors_nnondescents(UniqueRepresentation, IntegerVectors): The grading parameters on the integer vector `v` are: - - `n` -- the sum of the parts of `v`, + - ``n`` -- the sum of the parts of `v` - - `c` -- the non descents composition of `v`. + - ``c`` -- the non descents composition of `v` In other words: the length of `v` equals `c_1 + \cdots + c_k`, and `v` is decreasing in the consecutive blocs of length `c_1, \ldots, c_k`, diff --git a/src/sage/combinat/integer_vector_weighted.py b/src/sage/combinat/integer_vector_weighted.py index f3675d83e0f..ec074058b81 100644 --- a/src/sage/combinat/integer_vector_weighted.py +++ b/src/sage/combinat/integer_vector_weighted.py @@ -39,9 +39,9 @@ class WeightedIntegerVectors(Parent, UniqueRepresentation): INPUT: - - ``n`` -- a non negative integer (optional) + - ``n`` -- nonnegative integer (optional) - - ``weight`` -- a tuple (or list or iterable) of positive integers + - ``weight`` -- tuple (or list or iterable) of positive integers EXAMPLES:: @@ -134,7 +134,6 @@ def _element_constructor_(self, lst): ... ValueError: cannot convert [1, 2, 0] into Integer vectors of 3 weighted by [2, 1, 1] - """ if isinstance(lst, IntegerVector): if lst.parent() is self: @@ -350,7 +349,7 @@ def iterator_fast(n, l): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``l`` -- the weights in weakly decreasing order EXAMPLES:: diff --git a/src/sage/combinat/integer_vectors_mod_permgroup.py b/src/sage/combinat/integer_vectors_mod_permgroup.py index 5cdd65f2897..38e6f5af829 100644 --- a/src/sage/combinat/integer_vectors_mod_permgroup.py +++ b/src/sage/combinat/integer_vectors_mod_permgroup.py @@ -68,10 +68,10 @@ class IntegerVectorsModPermutationGroup(UniqueRepresentation): INPUT: - ``G`` -- a permutation group - - ``sum`` -- (default: None) - a nonnegative integer - - ``max_part`` -- (default: None) - a nonnegative integer setting the + - ``sum`` -- (default: ``None``) - a nonnegative integer + - ``max_part`` -- (default: ``None``) - a nonnegative integer setting the maximum value for every element - - ``sgs`` -- (default: None) - a strong generating system of the + - ``sgs`` -- (default: ``None``) - a strong generating system of the group `G`. If you do not provide it, it will be calculated at the creation of the parent @@ -243,7 +243,6 @@ class IntegerVectorsModPermutationGroup(UniqueRepresentation): 792 1287 2002 - """ @staticmethod def __classcall__(cls, G, sum=None, max_part=None, sgs=None): @@ -417,7 +416,7 @@ def retract(self, elt): def roots(self): r""" - Returns the root of generation of ``self``. This method is + Return the root of generation of ``self``. This method is required to build the tree structure of ``self`` which inherits from the class :class:`~sage.sets.recursively_enumerated_set.RecursivelyEnumeratedSet_forest`. @@ -431,7 +430,7 @@ def roots(self): def children(self, x): r""" - Returns the list of children of the element ``x``. This method + Return the list of children of the element ``x``. This method is required to build the tree structure of ``self`` which inherits from the class :class:`~sage.sets.recursively_enumerated_set.RecursivelyEnumeratedSet_forest`. @@ -445,7 +444,7 @@ def children(self, x): def permutation_group(self): r""" - Returns the permutation group given to define ``self``. + Return the permutation group given to define ``self``. EXAMPLES:: @@ -457,7 +456,7 @@ def permutation_group(self): def is_canonical(self, v, check=True): r""" - Returns ``True`` if the integer list ``v`` is maximal in its + Return ``True`` if the integer list ``v`` is maximal in its orbit under the action of the permutation group given to define ``self``. Such integer vectors are said to be canonical. A vector `v` is canonical if and only if @@ -508,7 +507,7 @@ def __contains__(self, v): def __call__(self, v, check=True): r""" - Returns an element of ``self`` constructed from ``v`` if + Return an element of ``self`` constructed from ``v`` if possible. TESTS:: @@ -527,7 +526,7 @@ def __call__(self, v, check=True): def orbit(self, v): r""" - Returns the orbit of the integer vector ``v`` under the action of the + Return the orbit of the integer vector ``v`` under the action of the permutation group defining ``self``. The result is a set. EXAMPLES: @@ -557,7 +556,7 @@ def orbit(self, v): def subset(self, sum=None, max_part=None): r""" - Returns the subset of ``self`` containing integer vectors + Return the subset of ``self`` containing integer vectors whose entries sum to ``sum``. EXAMPLES:: @@ -591,7 +590,7 @@ class Element(ClonableIntArray): def check(self): r""" - Checks that ``self`` verify the invariants needed for + Check that ``self`` verify the invariants needed for living in ``self.parent()``. EXAMPLES:: @@ -832,7 +831,6 @@ def __iter__(self): sage: I = IntegerVectorsModPermutationGroup(G, sum=3) sage: list(iter(I)) [] - """ # Special cases when domain is empty. if self.n == 0: @@ -945,7 +943,6 @@ def cardinality(self): 10 sage: IntegerVectorsModPermutationGroup(T10, 100).cardinality() 4263421511271 - """ G = self._permgroup k = G.degree() # Vector length @@ -1129,7 +1126,7 @@ def an_element(self): r""" Return an element of ``self``. - Raises an :class:`EmptySetError` when ``self`` is empty. + Raises an :exc:`EmptySetError` when ``self`` is empty. EXAMPLES:: @@ -1178,7 +1175,7 @@ def orbit(self, v): INPUT: - ``v`` -- an element of ``self`` or any list of length the - degree of the permutation group. + degree of the permutation group EXAMPLES: diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index 52e45090701..046d2ba3a7f 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -95,15 +95,15 @@ class TamariIntervalPoset(Element, INPUT: - - ``size`` -- an integer, the size of the interval-posets (number of + - ``size`` -- integer; the size of the interval-posets (number of vertices) - - ``relations`` -- a list (or tuple) of pairs ``(a,b)`` (themselves + - ``relations`` -- list (or tuple) of pairs ``(a,b)`` (themselves lists or tuples), each representing a relation of the form - '`a` precedes `b`' in the poset. + '`a` precedes `b`' in the poset - - ``check`` -- (default: ``True``) whether to check the interval-poset - condition or not. + - ``check`` -- boolean (default: ``True``); whether to check the + interval-poset condition or not .. WARNING:: @@ -274,7 +274,7 @@ def set_latex_options(self, D): INPUT: - - ``D`` -- a dictionary with a list of latex parameters to change + - ``D`` -- dictionary with a list of latex parameters to change EXAMPLES:: @@ -722,7 +722,7 @@ def increasing_children(self, v) -> list[int]: INPUT: - - ``v`` -- an integer representing a vertex of ``self`` + - ``v`` -- integer representing a vertex of ``self`` (between 1 and ``size``) OUTPUT: @@ -761,7 +761,7 @@ def increasing_parent(self, v) -> None | int: INPUT: - - ``v`` -- an integer representing a vertex of ``self`` + - ``v`` -- integer representing a vertex of ``self`` (between 1 and ``size``) EXAMPLES:: @@ -858,7 +858,7 @@ def decreasing_children(self, v) -> list[int]: INPUT: - - ``v`` -- an integer representing a vertex of ``self`` + - ``v`` -- integer representing a vertex of ``self`` (between 1 and ``size``) OUTPUT: @@ -897,7 +897,7 @@ def decreasing_parent(self, v) -> None | int: INPUT: - - ``v`` -- an integer representing a vertex of ``self`` (between + - ``v`` -- integer representing a vertex of ``self`` (between 1 and ``size``) EXAMPLES:: @@ -1944,8 +1944,8 @@ def subposet(self, start, end) -> TIP: INPUT: - - ``start`` -- an integer, the starting vertex (inclusive) - - ``end`` -- an integer, the ending vertex (not inclusive) + - ``start`` -- integer; the starting vertex (inclusive) + - ``end`` -- integer; the ending vertex (not inclusive) EXAMPLES:: @@ -2511,9 +2511,7 @@ def new_decomposition(self) -> list[TIP]: For the number of terms, you can use instead the method :meth:`number_of_new_components`. - OUTPUT: - - a list of new interval-posets. + OUTPUT: list of new interval-posets .. SEEALSO:: @@ -2861,7 +2859,7 @@ class TamariIntervalPosets(UniqueRepresentation, Parent): INPUT: - - ``size`` -- (optional) an integer + - ``size`` -- integer (optional) OUTPUT: @@ -2942,10 +2940,10 @@ class options(GlobalOptions): description='the default value for the line width as a' 'multiple of the tikz scale when latexed', checker=lambda x: True) # More trouble than it's worth to check - latex_color_decreasing = dict(default="red", + latex_color_decreasing = dict(default='red', description='the default color of decreasing relations when latexed', checker=lambda x: True) # More trouble than it's worth to check - latex_color_increasing = dict(default="blue", + latex_color_increasing = dict(default='blue', description='the default color of increasing relations when latexed', checker=lambda x: True) # More trouble than it's worth to check latex_hspace = dict(default=1, @@ -3409,8 +3407,8 @@ def from_minimal_schnyder_wood(graph) -> TIP: INPUT: - a minimal Schnyder wood, given as a graph with colored and - oriented edges, without the three exterior unoriented edges + - ``graph`` -- a minimal Schnyder wood, given as a graph with colored + and oriented edges, without the three exterior unoriented edges The three boundary vertices must be -1, -2 and -3. @@ -3420,9 +3418,7 @@ def from_minimal_schnyder_wood(graph) -> TIP: Beware that the embedding convention used here is the opposite of the one used by the plot method. - OUTPUT: - - a Tamari interval-poset + OUTPUT: a Tamari interval-poset EXAMPLES: @@ -3537,8 +3533,7 @@ def profil(gr, vertex): liste = clockwise_labelling(graph0, -1)[1:] relabelling = {l: i for i, l in enumerate(liste)} - for l in [-1, -2, -3]: - relabelling[l] = l + relabelling.update((i, i) for i in [-1, -2, -3]) new_graph = graph.relabel(relabelling, inplace=False) dyckword_top = [] @@ -3557,7 +3552,7 @@ def profil(gr, vertex): def __call__(self, *args, **keywords): r""" - Allows for a poset to be directly transformed into an interval-poset. + Allow for a poset to be directly transformed into an interval-poset. It is some kind of coercion but cannot be made through the coercion system because posets do not have parents. diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 0b35435c517..2c048fe38fc 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -51,7 +51,7 @@ lazy_import('sage.combinat.root_system.weyl_group', 'WeylGroup') -def WeakTableau(t, k, inner_shape=[], representation="core"): +def WeakTableau(t, k, inner_shape=[], representation='core'): r""" This is the dispatcher method for the element class of weak `k`-tableaux. @@ -85,7 +85,7 @@ def WeakTableau(t, k, inner_shape=[], representation="core"): (default: ``[]``) - ``representation`` -- 'core', 'bounded', or 'factorized_permutation' - (default: 'core') + (default: ``'core'``) EXAMPLES: @@ -111,7 +111,7 @@ def WeakTableau(t, k, inner_shape=[], representation="core"): Next we create the analogue of the first example in bounded representation:: - sage: tb = WeakTableau([[1,1,2],[2,3],[3]], 3, representation="bounded") + sage: tb = WeakTableau([[1,1,2],[2,3],[3]], 3, representation='bounded') sage: tb.shape() [3, 2, 1] sage: tb.weight() @@ -196,7 +196,7 @@ def WeakTableau(t, k, inner_shape=[], representation="core"): raise NotImplementedError("The representation option needs to be 'core', 'bounded', or 'factorized_permutation'") -def WeakTableaux(k, shape , weight, representation="core"): +def WeakTableaux(k, shape , weight, representation='core'): r""" This is the dispatcher method for the parent class of weak `k`-tableaux. @@ -360,7 +360,7 @@ def size(self): ([5, 2, 1], [1, 1]) sage: t.size() 4 - sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation="bounded") + sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation='bounded') sage: t.shape() [3, 2, 1] sage: t.size() @@ -486,7 +486,7 @@ def representation(self, representation='core'): INPUT: - - ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: 'core') + - ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: ``'core'``) EXAMPLES:: @@ -614,7 +614,7 @@ def representation(self, representation='core'): INPUT: - - ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: 'core') + - ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: ``'core'``) EXAMPLES:: @@ -670,8 +670,9 @@ class WeakTableau_core(WeakTableau_abstract): @staticmethod def __classcall_private__(cls, t, k): r""" - Implements the shortcut ``WeakTableau_core(t, k)`` to ``WeakTableaux_core(k, shape , weight)(t)`` - where ``shape`` is the shape of the tableau and ``weight`` is its weight. + Implement the shortcut ``WeakTableau_core(t, k)`` to + ``WeakTableaux_core(k, shape , weight)(t)`` where ``shape`` is the + shape of the tableau and ``weight`` is its weight. TESTS:: @@ -911,9 +912,7 @@ def residues_of_entries(self, v): - ``v`` -- a label of a cell in ``self`` - OUTPUT: - - - a list of residues + OUTPUT: list of residues EXAMPLES:: @@ -940,9 +939,7 @@ def dictionary_of_coordinates_at_residues(self, v): - ``v`` -- a label of a cell in ``self`` - OUTPUT: - - - dictionary assigning coordinates in ``self`` to residues + OUTPUT: dictionary assigning coordinates in ``self`` to residues EXAMPLES:: @@ -975,9 +972,7 @@ def list_of_standard_cells(self): - ``self`` -- a weak `k`-tableau in core representation with partition weight - OUTPUT: - - - a list of lists of coordinates + OUTPUT: list of lists of coordinates .. WARNING:: @@ -1036,18 +1031,16 @@ def list_of_standard_cells(self): out.append(standard_cells) return out - def k_charge(self, algorithm="I"): + def k_charge(self, algorithm='I'): r""" Return the `k`-charge of ``self``. INPUT: - - ``algorithm`` -- (default: "I") if "I", computes `k`-charge using the `I` + - ``algorithm`` -- (default: ``'I'``) if "I", computes `k`-charge using the `I` algorithm, otherwise uses the `J`-algorithm - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer For the definition of `k`-charge and the various algorithms to compute it see Section 3.3 of [LLMSSZ2013]_. @@ -1084,9 +1077,7 @@ def k_charge_I(self): For the definition of `k`-charge and the `I`-algorithm see Section 3.3 of [LLMSSZ2013]_. - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer .. SEEALSO:: :meth:`k_charge` and :meth:`k_charge_J` @@ -1130,9 +1121,7 @@ def k_charge_J(self): For the definition of `k`-charge and the `J`-algorithm see Section 3.3 of [LLMSSZ2013]_. - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer .. SEEALSO:: :meth:`k_charge` and :meth:`k_charge_I` @@ -1189,9 +1178,7 @@ def _height_of_restricted_subword(self, sw, r): - ``sw`` -- one of the subwords of standard cells of ``self`` - ``r`` -- nonnegative integer - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -1265,7 +1252,7 @@ def __classcall_private__(cls, k, shape, weight): def __init__(self, k, shape, weight): r""" - Initializes the parent class of (skew) weak `k`-tableaux in core representation. + Initialize the parent class of (skew) weak `k`-tableaux in core representation. INPUT: @@ -1334,9 +1321,7 @@ def diag(self, c, ha): - ``c`` -- a cell in the lattice - ``ha`` -- another cell in the lattice with bigger row and smaller column than `c` - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -1354,9 +1339,7 @@ def circular_distance(self, cr, r): - ``cr``, ``r`` -- nonnegative integers between `0` and `k` - OUTPUT: - - - a positive integer + OUTPUT: positive integer EXAMPLES:: @@ -1381,8 +1364,9 @@ class WeakTableau_bounded(WeakTableau_abstract): @staticmethod def __classcall_private__(cls, t, k): r""" - Implements the shortcut ``WeakTableau_bounded(t, k)`` to ``WeakTableaux_bounded(k, shape, weight)(t)`` - where ``shape`` is the shape of the tableau and ``weight`` is its weight. + Implement the shortcut ``WeakTableau_bounded(t, k)`` to + ``WeakTableaux_bounded(k, shape, weight)(t)`` where ``shape`` is the + shape of the tableau and ``weight`` is its weight. TESTS:: @@ -1564,7 +1548,7 @@ def check(self): def _is_k_tableau(self): r""" - Checks whether ``self`` is a valid weak `k`-tableau. + Check whether ``self`` is a valid weak `k`-tableau. EXAMPLES:: @@ -1662,12 +1646,10 @@ def k_charge(self, algorithm='I'): INPUT: - - ``algorithm`` -- (default: "I") if "I", computes `k`-charge using the `I` + - ``algorithm`` -- (default: ``'I'``) if "I", computes `k`-charge using the `I` algorithm, otherwise uses the `J`-algorithm - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer For the definition of `k`-charge and the various algorithms to compute it see Section 3.3 of [LLMSSZ2013]_. @@ -1733,7 +1715,7 @@ def __classcall_private__(cls, k, shape, weight): def __init__(self, k, shape, weight): r""" - Initializes the parent class of (skew) weak `k`-tableaux in bounded representation. + Initialize the parent class of (skew) weak `k`-tableaux in bounded representation. INPUT: @@ -1809,9 +1791,9 @@ def straighten_input(t, k): INPUT: - - ``t`` -- a list of reduced words or a list of elements in the Weyl group of type + - ``t`` -- list of reduced words or a list of elements in the Weyl group of type `A_k^{(1)}` - - ``k`` -- a positive integer + - ``k`` -- positive integer EXAMPLES:: @@ -1842,7 +1824,7 @@ def straighten_input(t, k): @staticmethod def __classcall_private__(cls, t, k, inner_shape=[]): r""" - Implements the shortcut ``WeakTableau_factorized_permutation(t, k)`` to + Implement the shortcut ``WeakTableau_factorized_permutation(t, k)`` to ``WeakTableaux_factorized_permutation(k, shape, weight)(t)`` where ``shape`` is the shape of the tableau as a `(k+1)`-core (or a tuple of `(k+1)`-cores if the tableau is skew) and ``weight`` is its weight. @@ -2003,7 +1985,7 @@ def check(self): def _is_k_tableau(self): r""" - Checks whether ``self`` is a valid weak `k`-tableau. + Check whether ``self`` is a valid weak `k`-tableau. EXAMPLES:: @@ -2094,9 +2076,7 @@ def k_charge(self, algorithm='I'): r""" Return the `k`-charge of ``self``. - OUTPUT: - - - a nonnegative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -2156,7 +2136,7 @@ def __classcall_private__(cls, k, shape, weight): def __init__(self, k, shape, weight): r""" - Initializes the parent class of weak `k`-tableaux in factorized permutation representation. + Initialize the parent class of weak `k`-tableaux in factorized permutation representation. INPUT: @@ -2490,11 +2470,9 @@ def _is_valid_marked( self ): INPUT: - - ``self`` -- a list of lists representing a potential *standard* marked tableau + - ``self`` -- list of lists representing a potential *standard* marked tableau - OUTPUT: - - - a boolean, ``True`` if the marks are properly placed in the tableau + OUTPUT: boolean; ``True`` if the marks are properly placed in the tableau EXAMPLES:: @@ -2551,9 +2529,7 @@ def _is_valid_standard( self ): less than or equal to `i` for each `i`) is a `k+1`-core and that the length of the `i+1`-restricted core is the length of the `i`-restricted core plus 1. - OUTPUT: - - - a boolean, ``True`` means the standard strong marked tableau is valid + OUTPUT: boolean; ``True`` means the standard strong marked tableau is valid EXAMPLES:: @@ -2595,9 +2571,8 @@ def is_column_strict_with_weight( self, mu ): - ``mu`` -- a vector of weights - OUTPUT: - - - a boolean, ``True`` means the underlying column strict strong marked tableau is valid + OUTPUT: boolean; ``True`` means the underlying column strict strong + marked tableau is valid EXAMPLES:: @@ -2684,18 +2659,18 @@ def _repr_(self): sage: T = StrongTableau([[-1,-2,3],[-3]],2) sage: T [[-1, -2, 3], [-3]] - sage: Tableaux.options(display="diagram") + sage: Tableaux.options(display='diagram') sage: T -1 -2 3 -3 - sage: Tableaux.options(convention="French") + sage: Tableaux.options(convention='French') sage: T -3 -1 -2 3 - sage: Tableaux.options(display="compact") + sage: Tableaux.options(display='compact') sage: T -1,-2,3/-3 - sage: Tableaux.options(display="list",convention="English") + sage: Tableaux.options(display='list',convention='English') """ return self.parent().options._dispatch(self, '_repr_', 'display') @@ -2709,11 +2684,9 @@ def cell_of_marked_head(self, v): INPUT: - - ``v`` -- an integer representing the label in the standard tableau + - ``v`` -- integer representing the label in the standard tableau - OUTPUT: - - - a pair of the coordinates of the marked cell with entry ``v`` + OUTPUT: a pair of the coordinates of the marked cell with entry ``v`` EXAMPLES:: @@ -2748,11 +2721,9 @@ def content_of_marked_head(self, v): INPUT: - - ``v`` -- an integer representing the label in the standard tableau - - OUTPUT: + - ``v`` -- integer representing the label in the standard tableau - - an integer representing the residue of the location of the mark + OUTPUT: integer representing the residue of the location of the mark EXAMPLES:: @@ -2839,12 +2810,10 @@ def cell_of_highest_head( self, v ): INPUT: - - ``v`` -- an integer indicating the label in the standard tableau + - ``v`` -- integer indicating the label in the standard tableau - OUTPUT: - - - a pair of integers indicating the coordinates of the head of the highest - ribbon with label ``v`` + OUTPUT: a pair of integers indicating the coordinates of the head of + the highest ribbon with label ``v`` EXAMPLES:: @@ -2883,12 +2852,10 @@ def content_of_highest_head( self, v ): INPUT: - - ``v`` -- an integer representing the label in the standard tableau - - OUTPUT: + - ``v`` -- integer representing the label in the standard tableau - - an integer representing the content of the head of the highest - ribbon with label ``v`` + OUTPUT: an integer representing the content of the head of the highest + ribbon with label ``v`` EXAMPLES:: @@ -2959,12 +2926,10 @@ def cells_of_heads(self, v): INPUT: - - ``v`` -- an integer label - - OUTPUT: + - ``v`` -- integer label - - a list of pairs of integers of the coordinates of the heads of the ribbons - with label ``v`` + OUTPUT: a list of pairs of integers of the coordinates of the heads of + the ribbons with label ``v`` EXAMPLES:: @@ -3003,11 +2968,10 @@ def contents_of_heads(self, v): INPUT: - - ``v`` -- an integer label + - ``v`` -- integer label - OUTPUT: - - - a list of integers of the content of the heads of the ribbons with label ``v`` + OUTPUT: list of integers of the content of the heads of the ribbons + with label ``v`` EXAMPLES:: @@ -3043,11 +3007,9 @@ def entries_by_content(self, diag): INPUT: - - ``diag`` -- an integer indicating the diagonal - - OUTPUT: + - ``diag`` -- integer indicating the diagonal - - a list (perhaps empty) of labels on the diagonal ``diag`` + OUTPUT: list (perhaps empty) of labels on the diagonal ``diag`` EXAMPLES:: @@ -3080,11 +3042,9 @@ def entries_by_content_standard(self, diag): INPUT: - - ``diag`` -- an integer indicating the diagonal + - ``diag`` -- integer indicating the diagonal - OUTPUT: - - - a list (perhaps empty) of labels on the diagonal ``diag`` + OUTPUT: list (perhaps empty) of labels on the diagonal ``diag`` EXAMPLES:: @@ -3161,10 +3121,8 @@ def height_of_ribbon(self, v): - ``v`` -- the label of the standard marked tableau - OUTPUT: - - - a non-negative integer representing the number of rows - occupied by the ribbon which is marked + OUTPUT: nonnegative integer representing the number of rows + occupied by the ribbon which is marked EXAMPLES:: @@ -3202,10 +3160,8 @@ def number_of_connected_components(self, v): - ``v`` -- the label of the standard marked tableau - OUTPUT: - - - a non-negative integer representing the number of connected - components + OUTPUT: nonnegative integer representing the number of connected + components EXAMPLES:: @@ -3248,9 +3204,7 @@ def intermediate_shapes(self): recover the strong tableau one would need the intermediate shapes and the :meth:`content_of_marked_head` for each pair of adjacent shapes in the list. - OUTPUT: - - - a list of lists of integers representing `k+1`-cores + OUTPUT: list of lists of integers representing `k+1`-cores EXAMPLES:: @@ -3292,7 +3246,7 @@ def pp( self ): 3 3 3 - sage: Tableaux.options(convention="French") + sage: Tableaux.options(convention='French') sage: T.pp() 3 3 @@ -3302,7 +3256,7 @@ def pp( self ): -1 -2 . . . . -1 -2 - sage: Tableaux.options(convention="English") + sage: Tableaux.options(convention='English') """ print(self._repr_diagram()) @@ -3371,11 +3325,11 @@ def shape( self ): INPUT: - - ``form`` -- optional argument to indicate 'inner', 'outer' or 'skew' (default : 'outer') + - ``form`` -- argument to indicate ``'inner'``, ``'outer'`` or + ``'skew'`` (default: ``'outer'``) - OUTPUT: - - - a `k+1`-core or a pair of `k+1`-cores if form is not 'inner' or 'outer' + OUTPUT: a `k+1`-core or a pair of `k+1`-cores if form is not + ``'inner'`` or ``'outer'`` EXAMPLES:: @@ -3400,12 +3354,10 @@ def weight( self ): r""" Return the weight of the tableau. - The weight is a list of non-negative integers indicating the number of 1s, + The weight is a list of nonnegative integers indicating the number of 1s, number of 2s, number of 3s, etc. - OUTPUT: - - - a list of non-negative integers + OUTPUT: list of nonnegative integers EXAMPLES:: @@ -3435,9 +3387,7 @@ def size( self ): .. SEEALSO:: :meth:`sage.combinat.core.Core.length` - OUTPUT: - - - a non-negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -3459,9 +3409,7 @@ def to_list( self ): """ Return the marked column strict (possibly skew) tableau as a list of lists. - OUTPUT: - - - a list of lists of integers or ``None`` + OUTPUT: list of lists of integers or ``None`` EXAMPLES:: @@ -3494,9 +3442,7 @@ def to_unmarked_list( self ): Return the list of lists of the rows of the tableau where the markings have been removed. - OUTPUT: - - - a list of lists of integers or ``None`` + OUTPUT: list of lists of integers or ``None`` EXAMPLES:: @@ -3525,9 +3471,7 @@ def to_standard_list(self): Internally, for a strong tableau the standard strong tableau and its weight is stored separately. This method returns the underlying standard part. - OUTPUT: - - - a list of lists of integers or ``None`` + OUTPUT: list of lists of integers or ``None`` EXAMPLES:: @@ -3553,9 +3497,7 @@ def to_standard_tableau(self): is stored separately. This method returns the underlying standard part as a ``StrongTableau``. - OUTPUT: - - - a strong tableau with standard weight + OUTPUT: a strong tableau with standard weight EXAMPLES:: @@ -3583,9 +3525,7 @@ def to_unmarked_standard_list( self ): Return the list of lists of the rows of the tableau where the markings have been removed. - OUTPUT: - - - a list of lists of integers or ``None`` + OUTPUT: list of lists of integers or ``None`` EXAMPLES:: @@ -3650,11 +3590,9 @@ def restrict( self, r ): INPUT: - - ``r`` -- an integer - - OUTPUT: + - ``r`` -- integer - - A strong tableau + OUTPUT: a strong tableau EXAMPLES:: @@ -3683,7 +3621,7 @@ def restrict( self, r ): def set_weight( self, mu ): """ - Sets a new weight ``mu`` for ``self``. + Set a new weight ``mu`` for ``self``. This method first tests if the underlying standard tableau is column-strict with respect to the weight ``mu``. If it is, then it changes the weight and returns @@ -3691,7 +3629,7 @@ def set_weight( self, mu ): INPUT: - - ``mu`` -- a list of non-negative integers representing the new weight + - ``mu`` -- list of nonnegative integers representing the new weight EXAMPLES:: @@ -3728,11 +3666,9 @@ def left_action( self, tij ): INPUT: - - ``tij`` -- a transposition represented as a pair `(i, j)`. + - ``tij`` -- a transposition represented as a pair `(i, j)` - OUTPUT: - - - ``self`` after it has been modified by the action of the transposition ``tij`` + OUTPUT: ``self`` after it has been modified by the action of the transposition ``tij`` EXAMPLES:: @@ -3769,9 +3705,7 @@ def follows_tableau( self ): Return list of all strong tableaux obtained from ``self`` by extending to a core which follows the shape of ``self`` in the strong order. - OUTPUT: - - - a list of strong tableaux which follow ``self`` in strong order + OUTPUT: list of strong tableaux which follow ``self`` in strong order EXAMPLES:: @@ -3817,9 +3751,7 @@ def spin_of_ribbon( self, v ): - ``v`` -- a label of the standard part of the tableau - OUTPUT: - - - an integer value representing the spin of the ribbon with label ``v``. + OUTPUT: integer value representing the spin of the ribbon with label ``v`` EXAMPLES:: @@ -3860,9 +3792,7 @@ def spin( self ): where the sum is over all column strict marked strong `k`-tableaux of shape `\lambda` and partition content. - OUTPUT: - - - an integer value representing the spin. + OUTPUT: integer value representing the spin EXAMPLES:: @@ -3901,9 +3831,7 @@ def to_transposition_sequence( self ): which when applied to the left of an empty tableau gives the corresponding strong standard tableau. - OUTPUT: - - - a list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}` + OUTPUT: list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}` EXAMPLES:: @@ -4014,9 +3942,7 @@ def outer_shape(self): r""" Return the outer shape of the class of strong tableaux. - OUTPUT: - - - a `k+1`-core + OUTPUT: a `k+1`-core EXAMPLES:: @@ -4033,9 +3959,7 @@ def inner_shape(self): r""" Return the inner shape of the class of strong tableaux. - OUTPUT: - - - a `k+1`-core + OUTPUT: a `k+1`-core EXAMPLES:: @@ -4055,9 +3979,7 @@ def shape(self): If the ``self`` has an inner shape return a pair consisting of an inner and an outer shape. If the inner shape is empty then return only the outer shape. - OUTPUT: - - - a `k+1`-core or a pair of `k+1`-cores + OUTPUT: a `k+1`-core or a pair of `k+1`-cores EXAMPLES:: @@ -4125,8 +4047,8 @@ def standard_unmarked_iterator( cls, k, size, outer_shape=None, inner_shape=[] ) INPUT: - ``k``, ``size`` -- positive integers - - ``outer_shape`` -- a list representing a `k+1`-core (default: ``None``) - - ``inner_shape`` -- a list representing a `k+1`-core (default: ``[]``) + - ``outer_shape`` -- list representing a `k+1`-core (default: ``None``) + - ``inner_shape`` -- list representing a `k+1`-core (default: ``[]``) OUTPUT: @@ -4174,13 +4096,11 @@ def marked_given_unmarked_and_weight_iterator(cls, unmarkedT, k, weight): INPUT: - - ``unmarkedT`` -- a list of lists representing a strong unmarked tableau - - ``k`` -- a positive integer - - ``weight`` -- a list of non-negative integers indicating the weight - - OUTPUT: + - ``unmarkedT`` -- list of lists representing a strong unmarked tableau + - ``k`` -- positive integer + - ``weight`` -- list of nonnegative integers indicating the weight - - an iterator that returns ``StrongTableau`` objects + OUTPUT: an iterator that returns ``StrongTableau`` objects EXAMPLES:: @@ -4234,14 +4154,12 @@ def add_marking( cls, unmarkedT, marking, k, weight ): INPUT: - - ``unmarkedT`` -- a list of lists which is a partially marked strong `k`-tableau - - ``marking`` -- a list of pairs of coordinates where cells are to be marked - - ``k`` -- a positive integer - - ``weight`` -- a tuple of the weight of the output tableau - - OUTPUT: + - ``unmarkedT`` -- list of lists which is a partially marked strong `k`-tableau + - ``marking`` -- list of pairs of coordinates where cells are to be marked + - ``k`` -- positive integer + - ``weight`` -- tuple of the weight of the output tableau - - a ``StrongTableau`` object + OUTPUT: a ``StrongTableau`` object EXAMPLES:: @@ -4280,11 +4198,9 @@ def _left_action_list( cls, Tlist, tij, v, k ): - ``Tlist`` -- a partial standard strong `k`-tableau as a list of lists - ``tij`` -- a pair of integers representing a transposition - ``v`` -- the label to add to the tableau - - ``k`` -- a positive integer - - OUTPUT: + - ``k`` -- positive integer - - a list of lists, in particular, it is ``Tlist`` + OUTPUT: list of lists, in particular, it is ``Tlist`` EXAMPLES:: @@ -4331,11 +4247,9 @@ def follows_tableau_unsigned_standard( cls, Tlist, k ): INPUT: - ``Tlist`` -- a filling of a `k+1`-core as a list of lists - - ``k`` -- an integer + - ``k`` -- integer - OUTPUT: - - - a list of strong tableaux which follow ``Tlist`` in strong order + OUTPUT: list of strong tableaux which follow ``Tlist`` in strong order EXAMPLES:: @@ -4378,10 +4292,10 @@ def standard_marked_iterator( cls, k, size, outer_shape=None, inner_shape=[] ): INPUT: - - ``k`` -- a positive integer - - ``size`` -- a positive integer - - ``outer_shape`` -- a list which is a `k+1`-core (default: ``None``) - - ``inner_shape`` -- a list which is a `k+1`-core (default: ``[]``) + - ``k`` -- positive integer + - ``size`` -- positive integer + - ``outer_shape`` -- list which is a `k+1`-core (default: ``None``) + - ``inner_shape`` -- list which is a `k+1`-core (default: ``[]``) OUTPUT: @@ -4483,11 +4397,9 @@ def marked_CST_to_transposition_sequence(self, T, k): INPUT: - ``T`` -- a non-empty column strict tableau as a list of lists - - ``k`` -- a positive integer - - OUTPUT: + - ``k`` -- positive integer - - a list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}` + OUTPUT: list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}` EXAMPLES:: @@ -4561,13 +4473,11 @@ def transpositions_to_standard_strong( self, transeq, k, emptyTableau=[] ): INPUT: - - ``transeq`` -- a sequence of transpositions `t_{ij}` (a list of pairs). + - ``transeq`` -- a sequence of transpositions `t_{ij}` (a list of pairs) - ``emptyTableau`` -- (default: ``[]``) an empty list or a skew strong tableau possibly consisting of ``None`` entries - OUTPUT: - - - a ``StrongTableau`` object + OUTPUT: a ``StrongTableau`` object EXAMPLES:: @@ -4607,9 +4517,7 @@ def nabs(v): - ``v`` -- either an integer or ``None`` - OUTPUT: - - - either a non-negative integer or ``None`` + OUTPUT: either a nonnegative integer or ``None`` EXAMPLES:: @@ -4633,9 +4541,7 @@ def intermediate_shapes(t): shapes, where the `i`-th shape is given by the shape of the subtableau on letters `1, 2, \ldots, i`. The output is the list of these shapes. - OUTPUT: - - - a list of lists representing partitions + OUTPUT: list of lists representing partitions EXAMPLES:: diff --git a/src/sage/combinat/kazhdan_lusztig.py b/src/sage/combinat/kazhdan_lusztig.py index eca077cd815..0014af47b73 100644 --- a/src/sage/combinat/kazhdan_lusztig.py +++ b/src/sage/combinat/kazhdan_lusztig.py @@ -46,7 +46,7 @@ class KazhdanLusztigPolynomial(UniqueRepresentation, SageObject): EXAMPLES:: - sage: W = WeylGroup("B3",prefix="s") + sage: W = WeylGroup("B3",prefix='s') sage: [s1,s2,s3] = W.simple_reflections() sage: R. = LaurentPolynomialRing(QQ) sage: KL = KazhdanLusztigPolynomial(W,q) @@ -66,7 +66,7 @@ def __init__(self, W, q, trace=False): EXAMPLES:: - sage: W = WeylGroup("B3",prefix="s") + sage: W = WeylGroup("B3",prefix='s') sage: R. = LaurentPolynomialRing(QQ) sage: KL = KazhdanLusztigPolynomial(W,q) sage: TestSuite(KL).run() @@ -95,7 +95,7 @@ def R(self, x, y): EXAMPLES:: sage: R.=QQ[] - sage: W = WeylGroup("A2", prefix="s") + sage: W = WeylGroup("A2", prefix='s') sage: [s1,s2]=W.simple_reflections() sage: KL = KazhdanLusztigPolynomial(W, q) sage: [KL.R(x,s2*s1) for x in [1,s1,s2,s1*s2]] @@ -114,7 +114,7 @@ def R(self, x, y): return self._base_ring.one() else: return self._base_ring.zero() - s = self._coxeter_group.simple_reflection(y.first_descent(side="left")) + s = self._coxeter_group.simple_reflection(y.first_descent(side='left')) if (s*x).length() < x.length(): ret = self.R(s*x,s*y) if self._trace: @@ -141,7 +141,7 @@ def R_tilde(self, x, y): EXAMPLES:: sage: R. = QQ[] - sage: W = WeylGroup("A2", prefix="s") + sage: W = WeylGroup("A2", prefix='s') sage: [s1,s2] = W.simple_reflections() sage: KL = KazhdanLusztigPolynomial(W, q) sage: [KL.R_tilde(x,s2*s1) for x in [1,s1,s2,s1*s2]] @@ -155,7 +155,7 @@ def R_tilde(self, x, y): return self._base_ring.zero() if x == y: return self._base_ring.one() - s = self._coxeter_group.simple_reflection(y.first_descent(side="right")) + s = self._coxeter_group.simple_reflection(y.first_descent(side='right')) if (x * s).length() < x.length(): ret = self.R_tilde(x * s, y * s) if self._trace: @@ -187,7 +187,7 @@ def P(self, x, y): EXAMPLES:: sage: R. = QQ[] - sage: W = WeylGroup("A3", prefix="s") + sage: W = WeylGroup("A3", prefix='s') sage: [s1,s2,s3] = W.simple_reflections() sage: KL = KazhdanLusztigPolynomial(W, q) sage: KL.P(s2,s2*s1*s3*s2) diff --git a/src/sage/combinat/key_polynomial.py b/src/sage/combinat/key_polynomial.py index 43db18cc72f..1b65f5bc063 100644 --- a/src/sage/combinat/key_polynomial.py +++ b/src/sage/combinat/key_polynomial.py @@ -649,7 +649,6 @@ def from_polynomial(self, f): sage: T = crystals.Tableaux(['A', 4], shape=[4,2,1,1]) sage: k.from_polynomial(T.demazure_character([2])) k[4, 1, 2, 1] - """ if f not in self._polynomial_ring: try: # to accept elements of SymbolicRing diff --git a/src/sage/combinat/knutson_tao_puzzles.py b/src/sage/combinat/knutson_tao_puzzles.py index b8b62c6a440..f7a7c513c52 100644 --- a/src/sage/combinat/knutson_tao_puzzles.py +++ b/src/sage/combinat/knutson_tao_puzzles.py @@ -308,9 +308,7 @@ def clockwise_rotation(self) -> NablaPiece: r""" Rotate the Nabla piece by 120 degree clockwise. - OUTPUT: - - - Nabla piece + OUTPUT: Nabla piece EXAMPLES:: @@ -327,9 +325,7 @@ def half_turn_rotation(self) -> DeltaPiece: r""" Rotate the Nabla piece by 180 degree. - OUTPUT: - - - Delta piece + OUTPUT: Delta piece EXAMPLES:: @@ -430,9 +426,7 @@ def clockwise_rotation(self) -> DeltaPiece: r""" Rotate the Delta piece by 120 degree clockwise. - OUTPUT: - - - Delta piece + OUTPUT: Delta piece EXAMPLES:: @@ -449,9 +443,7 @@ def half_turn_rotation(self) -> NablaPiece: r""" Rotate the Delta piece by 180 degree. - OUTPUT: - - - Nabla piece + OUTPUT: Nabla piece EXAMPLES:: @@ -1052,7 +1044,6 @@ def BK_pieces(max_letter): sage: BK_pieces(3) Nablas : [1\1/1, 1\2(1)/2, 1\3(1)/3, 2(1)\2/1, 2\1/2(1), 2\2/2, 2\3(2)/3, 3(1)\3/1, 3(2)\3/2, 3\1/3(1), 3\2/3(2), 3\3/3] Deltas : [1/1\1, 1/2\2(1), 1/3\3(1), 2(1)/1\2, 2/2(1)\1, 2/2\2, 2/3\3(2), 3(1)/1\3, 3(2)/2\3, 3/3(1)\1, 3/3(2)\2, 3/3\3] - """ forbidden_border_labels = ['%s(%s)' % (i, j) for i in range(1, max_letter + 1) @@ -1358,7 +1349,7 @@ def __iter__(self): for k in range(d + 1): yield self[k + 1, self._n - d + k] - def plot(self, labels=True, style="fill"): + def plot(self, labels=True, style='fill'): r""" Plot completed puzzle. @@ -1496,8 +1487,8 @@ class KnutsonTaoPuzzleSolver(UniqueRepresentation): - ``HT2step`` -- equivariant cohomology of the *2-step* Grassmannian - ``BK`` -- Belkale-Kumar puzzle pieces - - ``max_letter`` -- (default: None) None or a positive integer. This is - only required only for Belkale-Kumar puzzles. + - ``max_letter`` -- ``None`` or a positive integer(default: ``None``); this + is only required for Belkale-Kumar puzzles EXAMPLES: @@ -1570,7 +1561,7 @@ class KnutsonTaoPuzzleSolver(UniqueRepresentation): (3, 4): 1/\0 0\/1, (4, 4): 1/1\1}] - The pieces in a puzzle filling are indexed by pairs of non-negative + The pieces in a puzzle filling are indexed by pairs of nonnegative integers `(i, j)` with `1 \leq i \leq j \leq n`, where `n` is the length of the word labelling the triangle edge. The pieces indexed by `(i, i)` are the triangles along the south edge of the puzzle. :: @@ -2064,9 +2055,7 @@ def _fill_piece(self, nw_label, ne_label, pieces) -> list[PuzzlePiece]: - ``nw_label``, ``nw_label`` -- label - ``pieces`` -- puzzle pieces used for the filling - OUTPUT: - - - list of the fillings + OUTPUT: list of the fillings EXAMPLES:: @@ -2075,12 +2064,9 @@ def _fill_piece(self, nw_label, ne_label, pieces) -> list[PuzzlePiece]: sage: ps._fill_piece('0', '0', ps._bottom_deltas) [0/0\0] """ - output = [] - for piece in pieces: - if (piece['north_west'] == nw_label and - piece['north_east'] == ne_label): - output.append(piece) - return output + return [piece for piece in pieces + if (piece['north_west'] == nw_label and + piece['north_east'] == ne_label)] @cached_method def _fill_strip(self, nw_labels, ne_label, pieces, final_pieces=None): @@ -2094,9 +2080,7 @@ def _fill_strip(self, nw_labels, ne_label, pieces, final_pieces=None): - ``pieces`` -- puzzle pieces used for the filling - ``final_pieces`` -- pieces used for the last piece to be filled in - OUTPUT: - - - list of lists of the fillings + OUTPUT: list of lists of the fillings EXAMPLES:: @@ -2227,9 +2211,9 @@ def structure_constants(self, lamda, mu, nu=None): - ``pieces`` -- puzzle pieces to be used - ``lambda``, ``mu`` -- edge labels of puzzle for northwest and north east side - - ``nu`` -- (default: ``None``) If ``nu`` is not specified a dictionary is returned with + - ``nu`` -- (default: ``None``) if ``nu`` is not specified a dictionary is returned with the structure coefficients corresponding to all south labels; if ``nu`` is given, only - the coefficients with the specified label is returned. + the coefficients with the specified label is returned OUTPUT: dictionary diff --git a/src/sage/combinat/lr_tableau.py b/src/sage/combinat/lr_tableau.py index 90d60beda3b..9a5e7a0ef03 100644 --- a/src/sage/combinat/lr_tableau.py +++ b/src/sage/combinat/lr_tableau.py @@ -56,7 +56,7 @@ class LittlewoodRichardsonTableau(SemistandardTableau): @staticmethod def __classcall_private__(cls, t, weight): r""" - Implements the shortcut ``LittlewoodRichardsonTableau(t, weight)`` to + Implement the shortcut ``LittlewoodRichardsonTableau(t, weight)`` to ``LittlewoodRichardsonTableaux(shape , weight)(t)`` where ``shape`` is the shape of the tableau. @@ -179,7 +179,7 @@ def __classcall_private__(cls, shape, weight): def __init__(self, shape, weight): r""" - Initializes the parent class of Littlewood-Richardson tableaux. + Initialize the parent class of Littlewood-Richardson tableaux. INPUT: diff --git a/src/sage/combinat/matrices/dancing_links.pyx b/src/sage/combinat/matrices/dancing_links.pyx index 5035bb0480b..475b5ef3e1b 100644 --- a/src/sage/combinat/matrices/dancing_links.pyx +++ b/src/sage/combinat/matrices/dancing_links.pyx @@ -145,14 +145,13 @@ cdef class dancing_linksWrapper: sage: x = dlx_solver([]) sage: x.get_solution() [] - """ self._rows = [row for row in rows] self._initialize() def _initialize(self): r""" - Initialization of the search algorithm + Initialization of the search algorithm. This adds the rows to the instance of dancing_links. This method is used by `__init__` and `reinitialize` methods and should not be @@ -173,7 +172,6 @@ cdef class dancing_linksWrapper: sage: x.reinitialize() # indirect doctest sage: x.get_solution() if x.search() else None [0, 1] - """ cdef vector[int] v cdef vector[vector[int]] vv @@ -190,7 +188,7 @@ cdef class dancing_linksWrapper: def reinitialize(self): r""" - Reinitialization of the search algorithm + Reinitialization of the search algorithm. This recreates an empty ``dancing_links`` object and adds the rows to the instance of ``dancing_links.`` @@ -226,7 +224,6 @@ cdef class dancing_linksWrapper: sage: x.get_solution() if x.search() else None [4, 5] sage: x.get_solution() if x.search() else None - """ sig_on() self._x = dancing_links() @@ -410,11 +407,9 @@ cdef class dancing_linksWrapper: INPUT: - - ``indices`` -- list, row indices to be found in the solution + - ``indices`` -- list; row indices to be found in the solution - OUTPUT: - - dancing links solver + OUTPUT: dancing links solver EXAMPLES:: @@ -426,7 +421,7 @@ cdef class dancing_linksWrapper: sage: sorted(map(sorted, d.solutions_iterator())) [[0, 1], [2, 3], [4, 5]] - To impose that the 0th row is part of the solution, the rows of the new + To impose that the `0`-th row is part of the solution, the rows of the new problem are:: sage: d_using_0 = d.restrict([0]) @@ -443,7 +438,7 @@ cdef class dancing_linksWrapper: sage: d.restrict([2]).rows() [[0, 1, 2], [3, 4, 5], [0, 1, 6], [2, 3, 4, 5], [0], [1, 2, 3, 4, 5]] - This method allows to find solutions where the 0th row is part of a + This method allows to find solutions where the `0`-th row is part of a solution:: sage: sorted(map(sorted, d.restrict([0]).solutions_iterator())) @@ -458,7 +453,7 @@ cdef class dancing_linksWrapper: sage: sorted(map(sorted, d.restrict([3]).solutions_iterator())) [[2, 3]] - Here there are no solution using both 0th and 3rd row:: + Here there are no solutions using both 0th and 3rd row:: sage: list(d.restrict([0,3]).solutions_iterator()) [] @@ -488,12 +483,10 @@ cdef class dancing_linksWrapper: INPUT: - - ``column`` -- integer, the column used to split the problem into + - ``column`` -- integer; the column used to split the problem into independent subproblems - OUTPUT: - - dict where keys are row numbers and values are dlx solvers + OUTPUT: dict where keys are row numbers and values are dlx solvers EXAMPLES:: @@ -582,18 +575,16 @@ cdef class dancing_linksWrapper: INPUT: - - ``ncpus`` -- integer (default: ``None``), maximal number of + - ``ncpus`` -- integer (default: ``None``); maximal number of subprocesses to use at the same time. If ``None``, it detects the number of effective CPUs in the system using :func:`sage.parallel.ncpus.ncpus()`. If ``ncpus=1``, the first solution is searched serially. - - ``column`` -- integer (default: ``None``), the column used to split + - ``column`` -- integer (default: ``None``); the column used to split the problem (see :meth:`restrict`). If ``None``, a random column is chosen. This argument is ignored if ``ncpus=1``. - OUTPUT: - - list of rows or ``None`` if no solution is found + OUTPUT: list of rows or ``None`` if no solution is found .. NOTE:: @@ -685,16 +676,14 @@ cdef class dancing_linksWrapper: INPUT: - - ``ncpus`` -- integer (default: ``None``), maximal number of + - ``ncpus`` -- integer (default: ``None``); maximal number of subprocesses to use at the same time. If ``None``, it detects the number of effective CPUs in the system using :func:`sage.parallel.ncpus.ncpus()`. - - ``column`` -- integer (default: ``None``), the column used to split + - ``column`` -- integer (default: ``None``); the column used to split the problem, if ``None`` a random column is chosen - OUTPUT: - - list of solutions + OUTPUT: list of solutions EXAMPLES:: @@ -802,19 +791,17 @@ cdef class dancing_linksWrapper: INPUT: - - ``ncpus`` -- integer (default: ``None``), maximal number of + - ``ncpus`` -- integer (default: ``None``); maximal number of subprocesses to use at the same time. If ``ncpus>1`` the dancing links problem is split into independent subproblems to allow parallel computation. If ``None``, it detects the number of effective CPUs in the system using :func:`sage.parallel.ncpus.ncpus()`. - - ``column`` -- integer (default: ``None``), the column used to split + - ``column`` -- integer (default: ``None``); the column used to split the problem, if ``None`` a random column is chosen (this argument is ignored if ``ncpus`` is ``1``) - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -910,9 +897,7 @@ cdef class dancing_linksWrapper: possible values include ``'picosat'``, ``'cryptominisat'``, ``'LP'``, ``'glucose'``, ``'glucose-syrup'``. - OUTPUT: - - SAT solver instance + OUTPUT: SAT solver instance EXAMPLES:: @@ -925,7 +910,6 @@ cdef class dancing_linksWrapper: sage: x.to_sat_solver('cryptominisat') # optional - pycryptosat # needs sage.sat CryptoMiniSat solver: 4 variables, 7 clauses. - """ from sage.sat.solvers.satsolver import SAT s = SAT(solver) @@ -960,9 +944,7 @@ cdef class dancing_linksWrapper: possible values include ``'picosat'``, ``'cryptominisat'``, ``'LP'``, ``'glucose'``, ``'glucose-syrup'``. - OUTPUT: - - list of rows or ``None`` if no solution is found + OUTPUT: list of rows or ``None`` if no solution is found .. NOTE:: @@ -1010,10 +992,10 @@ cdef class dancing_linksWrapper: INPUT: - - ``solver`` -- string or ``None`` (default: ``None``), possible + - ``solver`` -- string or ``None`` (default: ``None``); possible values include ``'GLPK'``, ``'GLPK/exact'``, ``'Coin'``, ``'CPLEX'``, ``'Gurobi'``, ``'CVXOPT'``, ``'PPL'``, - ``'InteractiveLP'``. + ``'InteractiveLP'`` OUTPUT: @@ -1031,8 +1013,8 @@ cdef class dancing_linksWrapper: sage: x # needs sage.numerical.mip MIPVariable with 4 binary components - In the reduction, the boolean variable x_i is True if and only if - the i-th row is in the solution:: + In the reduction, the boolean variable `x_i` is ``True`` if and only if + the `i`-th row is in the solution:: sage: p.show() # needs sage.numerical.mip Maximization: @@ -1054,7 +1036,6 @@ cdef class dancing_linksWrapper: sage: d.to_milp('gurobi') # optional - gurobi sage_numerical_backends_gurobi, needs sage.numerical.mip (Boolean Program (no objective, 4 variables, 4 constraints), MIPVariable with 4 binary components) - """ from sage.numerical.mip import MixedIntegerLinearProgram p = MixedIntegerLinearProgram(solver=solver) @@ -1082,14 +1063,12 @@ cdef class dancing_linksWrapper: INPUT: - - ``solver`` -- string or ``None`` (default: ``None``), possible + - ``solver`` -- string or ``None`` (default: ``None``); possible values include ``'GLPK'``, ``'GLPK/exact'``, ``'Coin'``, ``'CPLEX'``, ``'Gurobi'``, ``'CVXOPT'``, ``'PPL'``, - ``'InteractiveLP'``. - - OUTPUT: + ``'InteractiveLP'`` - list of rows or ``None`` if no solution is found + OUTPUT: list of rows or ``None`` if no solution is found .. NOTE:: diff --git a/src/sage/combinat/matrices/dlxcpp.py b/src/sage/combinat/matrices/dlxcpp.py index 3cdc3774d76..15c6eddbbdc 100644 --- a/src/sage/combinat/matrices/dlxcpp.py +++ b/src/sage/combinat/matrices/dlxcpp.py @@ -24,11 +24,11 @@ def DLXCPP(rows): """ - Solves the Exact Cover problem by using the Dancing Links algorithm + Solve the Exact Cover problem by using the Dancing Links algorithm described by Knuth. Consider a matrix M with entries of 0 and 1, and compute a subset - of the rows of this matrix which sum to the vector of all 1's. + of the rows of this matrix which sum to the vector of all 1s. The dancing links algorithm works particularly well for sparse matrices, so the input is a list of lists of the form:: @@ -89,7 +89,7 @@ def DLXCPP(rows): def AllExactCovers(M): """ - Solves the exact cover problem on the matrix M (treated as a dense + Solve the exact cover problem on the matrix M (treated as a dense binary matrix). EXAMPLES: No exact covers:: @@ -117,7 +117,7 @@ def AllExactCovers(M): def OneExactCover(M): """ - Solves the exact cover problem on the matrix M (treated as a dense + Solve the exact cover problem on the matrix M (treated as a dense binary matrix). EXAMPLES:: diff --git a/src/sage/combinat/matrices/hadamard_matrix.py b/src/sage/combinat/matrices/hadamard_matrix.py index 34b12f6577e..5f9f24239d4 100644 --- a/src/sage/combinat/matrices/hadamard_matrix.py +++ b/src/sage/combinat/matrices/hadamard_matrix.py @@ -125,7 +125,7 @@ def normalise_hadamard(H, skew=False): sage: is_hadamard_matrix(H, skew=True, normalized=True) True - If ``skew`` is True but the Hadamard matrix is not skew, the matrix returned + If ``skew`` is ``True`` but the Hadamard matrix is not skew, the matrix returned will not be normalized:: sage: H = normalise_hadamard(hadamard_matrix(92), skew=True) @@ -320,6 +320,88 @@ def hadamard_matrix_paleyII(n): return normalise_hadamard(H) +def hadamard_matrix_from_symmetric_conference_matrix(n, existence=False, check=True): + r""" + Construct a Hadamard matrix of order `n` from a symmetric conference matrix + of order `n/2`. + + The construction is described in Theorem 4.3.24 of [IS2006]_. + The symmetric conference matrices are obtained from + :func:`sage.combinat.matrices.hadamard_matrix.symmetric_conference_matrix`. + + INPUT: + + - ``n`` -- integer; the order of the matrix to be constructed + - ``existence`` -- boolean (default: ``False``); if ``True``, only check if + the matrix exists + - ``check`` -- boolean (default: ``True``); if ``True``, check that the matrix + is a Hadamard before returning + + OUTPUT: + + If ``existence=False``, returns the Hadamard matrix of order `n`. It raises + an error if no data is available to construct the matrix of the given order, + or if `n` does not satisfies the constraints. + If ``existence=True``, returns a boolean representing whether the matrix + can be constructed or not. + + EXAMPLES: + + By default the function returns the Hadamard matrix :: + + sage: from sage.combinat.matrices.hadamard_matrix import hadamard_matrix_from_symmetric_conference_matrix + sage: hadamard_matrix_from_symmetric_conference_matrix(20) + 20 x 20 dense matrix over Integer Ring... + + If ``existence`` is set to True, the function returns True if the matrix exists, + False if the conference matrix does not exist, and Unknown if the conference + matrix cannot be constructed yet :: + + sage: hadamard_matrix_from_symmetric_conference_matrix(12, existence=True) + True + sage: hadamard_matrix_from_symmetric_conference_matrix(4*787, existence=True) + True + + TESTS:: + + sage: from sage.combinat.matrices.hadamard_matrix import is_hadamard_matrix + sage: is_hadamard_matrix(hadamard_matrix_from_symmetric_conference_matrix(60, check=False)) + True + sage: hadamard_matrix_from_symmetric_conference_matrix(64, existence=True) + False + sage: hadamard_matrix_from_symmetric_conference_matrix(4*787, existence=True) + True + sage: hadamard_matrix_from_symmetric_conference_matrix(64) + Traceback (most recent call last): + ... + ValueError: Cannot construct Hadamard matrix of order 64, a symmetric conference matrix of order 32 is not available in sage. + sage: hadamard_matrix_from_symmetric_conference_matrix(14) + Traceback (most recent call last): + ... + ValueError: No Hadamard matrix of order 14 exists. + """ + if n < 0 or n % 4 != 0: + raise ValueError(f'No Hadamard matrix of order {n} exists.') + + m = n//2 + exists = symmetric_conference_matrix(m, existence=True) + + if existence: + return exists + + if not exists: + raise ValueError(f'Cannot construct Hadamard matrix of order {n}, a symmetric conference matrix of order {m} is not available in sage.') + + C = symmetric_conference_matrix(m) + + H = block_matrix([[C + I(m), C - I(m)], + [C - I(m), -C - I(m)]]) + + if check: + assert is_hadamard_matrix(H) + return H + + def hadamard_matrix_miyamoto_construction(n, existence=False, check=True): r""" Construct Hadamard matrix using the Miyamoto construction. @@ -363,6 +445,10 @@ def hadamard_matrix_miyamoto_construction(n, existence=False, check=True): True sage: hadamard_matrix_miyamoto_construction(64, existence=True) False + sage: hadamard_matrix_miyamoto_construction(4*65, existence=True) + True + sage: is_hadamard_matrix(hadamard_matrix_miyamoto_construction(4*65, check=False)) + True sage: hadamard_matrix_miyamoto_construction(64) Traceback (most recent call last): ... @@ -377,14 +463,16 @@ def hadamard_matrix_miyamoto_construction(n, existence=False, check=True): q = n // 4 if existence: - return is_prime_power(q) and q % 4 == 1 and hadamard_matrix(q-1, existence=True) is True + # return is_prime_power(q) and q % 4 == 1 and hadamard_matrix(q-1, existence=True) is True + return symmetric_conference_matrix(q+1, existence=True) and hadamard_matrix(q-1, existence=True) is True - if not (is_prime_power(q) and q % 4 == 1 and hadamard_matrix(q-1, existence=True)): + # if not (is_prime_power(q) and q % 4 == 1 and hadamard_matrix(q-1, existence=True)): + if not (symmetric_conference_matrix(q+1, existence=True) and hadamard_matrix(q-1, existence=True)): raise ValueError(f'The order {n} is not covered by Miyamoto construction.') m = (q-1) // 2 - C = symmetric_conference_matrix_paley(q + 1) + C = symmetric_conference_matrix(q + 1) neg = [i for i in range(2, m+2) if C[1, i] == -1] pos = [i for i in range(m+2, 2*m+2) if C[1, i] == 1] @@ -710,8 +798,7 @@ def construction_four_symbol_delta_code_I(X, Y, Z, W): - ``Z`` -- list; the third sequence (length `n`) - ``W`` -- list; the fourth sequence (length `n`) - OUTPUT: - A tuple containing the 4-symbol `\delta` code of length `2n+1`. + OUTPUT: tuple containing the 4-symbol `\delta` code of length `2n+1` EXAMPLES:: @@ -780,8 +867,7 @@ def construction_four_symbol_delta_code_II(X, Y, Z, W): - ``Z`` -- list; the third sequence (length `n`) - ``W`` -- list; the fourth sequence (length `n`) - OUTPUT: - A tuple containing the four 4-symbol `\delta` code of length `4n+3`. + OUTPUT: tuple containing the four 4-symbol `\delta` code of length `4n+3` EXAMPLES:: @@ -802,7 +888,6 @@ def construction_four_symbol_delta_code_II(X, Y, Z, W): Traceback (most recent call last): ... AssertionError - """ n = len(Z) @@ -909,10 +994,10 @@ def _construction_goethals_seidel_matrix(A, B, C, D): INPUT: - - ``A`` -- The first matrix used in the construction - - ``B`` -- The second matrix used in the construction - - ``C`` -- The third matrix used in the construction - - ``D`` -- The fourth matrix used in the construction + - ``A`` -- the first matrix used in the construction + - ``B`` -- the second matrix used in the construction + - ``C`` -- the third matrix used in the construction + - ``D`` -- the fourth matrix used in the construction TESTS:: @@ -1030,7 +1115,7 @@ def hadamard_matrix_from_sds(n, existence=False, check=True): def hadamard_matrix_cooper_wallis_construction(x1, x2, x3, x4, A, B, C, D, check=True): r""" - Create a Hadamard matrix using the contruction detailed in [CW1972]_. + Create a Hadamard matrix using the construction detailed in [CW1972]_. Given four circulant matrices `X_1`, X_2, X_3, X_4` of order `n` with entries (0, 1, -1) such that the entrywise product of two distinct matrices is always equal to `0` and that @@ -1050,7 +1135,7 @@ def hadamard_matrix_cooper_wallis_construction(x1, x2, x3, x4, A, B, C, D, check - ``C`` -- the matrix described above - ``D`` -- the matrix described above - ``check`` -- boolean (default: ``True``); if ``True``, check that the resulting - matrix is Hadamard before returing it. + matrix is Hadamard before returning it EXAMPLES:: @@ -1127,7 +1212,7 @@ def hadamard_matrix_cooper_wallis_smallcases(n, check=True, existence=False): - ``check`` -- boolean (default: ``True``); if ``True``, check that the matrix is a Hadamard matrix before returning - ``existence`` -- boolean (default: ``False``); if ``True``, only check if - the matrix exists. + the matrix exists OUTPUT: @@ -1217,7 +1302,7 @@ def _get_baumert_hall_units(n, existence=False): - ``n`` -- integer; the size of the Baumert-Hall units - ``existence`` -- boolean (default: ``False``); if ``True``, only check whether - the units can be contructed + the units can be constructed OUTPUT: @@ -1293,10 +1378,10 @@ def hadamard_matrix_turyn_type(a, b, c, d, e1, e2, e3, e4, check=True): - ``b`` -- 1,-1 list; the 1st row of `B` - ``d`` -- 1,-1 list; the 1st row of `C` - ``c`` -- 1,-1 list; the 1st row of `D` - - ``e1`` -- Matrix; the first Baumert-Hall unit - - ``e2`` -- Matrix; the second Baumert-Hall unit - - ``e3`` -- Matrix; the third Baumert-Hall unit - - ``e4`` -- Matrix; the fourth Baumert-Hall unit + - ``e1`` -- matrix; the first Baumert-Hall unit + - ``e2`` -- matrix; the second Baumert-Hall unit + - ``e3`` -- matrix; the third Baumert-Hall unit + - ``e4`` -- matrix; the fourth Baumert-Hall unit - ``check`` -- boolean (default: ``True``); whether to check that the output is a Hadamard matrix before returning it @@ -1362,9 +1447,9 @@ def turyn_type_hadamard_matrix_smallcases(n, existence=False, check=True): INPUT: - ``n`` -- integer; the order of the matrix to be constructed - - ``existence`` -- boolean (default: ``False``): if ``True``, only check if + - ``existence`` -- boolean (default: ``False``); if ``True``, only check if the matrix exists - - ``check`` -- boolean (default: ``True``): if ``True``, check that the matrix + - ``check`` -- boolean (default: ``True``); if ``True``, check that the matrix is a Hadamard matrix before returning EXAMPLES:: @@ -1643,7 +1728,7 @@ def is_skew_hadamard_matrix(M, normalized=False, verbose=False): @matrix_method def hadamard_matrix(n, existence=False, check=True, construction_name=False): r""" - Tries to construct a Hadamard matrix using the available methods. + Try to construct a Hadamard matrix using the available methods. Currently all orders `\le 1200` for which a construction is known are implemented. For `n > 1200`, only some orders are available. @@ -1658,11 +1743,11 @@ def hadamard_matrix(n, existence=False, check=True, construction_name=False): - ``True`` -- meaning that Sage knows how to build the matrix - ``Unknown`` -- meaning that Sage does not know how to build the matrix, although the matrix may exist (see :mod:`sage.misc.unknown`). - - ``False`` -- meaning that the matrix does not exist. + - ``False`` -- meaning that the matrix does not exist - - ``check`` -- boolean (default: ``True``); whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. - ``construction_name`` -- boolean (default: ``False``); if it is ``True``, ``existence`` is ``True``, and a matrix exists, output the construction name. It has no effect if ``existence`` is set to ``False``. @@ -1821,6 +1906,11 @@ def report_name(nam): if existence: return report_name(name) M = regular_symmetric_hadamard_matrix_with_constant_diagonal(n, 1) + elif hadamard_matrix_from_symmetric_conference_matrix(n, existence=True) is True: + name = "Construction from symmetric conference matrix " + name + if existence: + return report_name(name) + M = hadamard_matrix_from_symmetric_conference_matrix(n, check=False) else: if existence: return Unknown @@ -2205,7 +2295,7 @@ def rshcd_from_close_prime_powers(n): INPUT: - - ``n`` -- an integer congruent to `0\pmod{4}` + - ``n`` -- integer congruent to `0\pmod{4}` .. SEEALSO:: @@ -2259,7 +2349,7 @@ def rshcd_from_close_prime_powers(n): def williamson_goethals_seidel_skew_hadamard_matrix(a, b, c, d, check=True): r""" - Williamson-Goethals-Seidel construction of a skew Hadamard matrix + Williamson-Goethals-Seidel construction of a skew Hadamard matrix. Given `n\times n` (anti)circulant matrices `A`, `B`, `C`, `D` with 1,-1 entries, and satisfying `A+A^\top = 2I`, `AA^\top + BB^\top + CC^\top + DD^\top = 4nI`, @@ -2271,7 +2361,7 @@ def williamson_goethals_seidel_skew_hadamard_matrix(a, b, c, d, check=True): - ``b`` -- 1,-1 list; the 1st row of `B` - ``d`` -- 1,-1 list; the 1st row of `C` - ``c`` -- 1,-1 list; the 1st row of `D` - - ``check`` -- boolean (default: ``True``); if ``True``, check that the + - ``check`` -- boolean (default: ``True``); if ``True``, check that the resulting matrix is skew Hadamard before returning it EXAMPLES:: @@ -2305,7 +2395,7 @@ def williamson_goethals_seidel_skew_hadamard_matrix(a, b, c, d, check=True): def skew_hadamard_matrix_spence_construction(n, check=True): r""" - Construct skew Hadamard matrix of order `n` using Spence constrution. + Construct skew Hadamard matrix of order `n` using Spence construction. This function will construct skew Hadamard matrix of order `n=2(q+1)` where `q` is a prime power with `q = 5` (mod 8). The construction is taken from [Spe1977]_, and the @@ -2314,7 +2404,7 @@ def skew_hadamard_matrix_spence_construction(n, check=True): INPUT: - ``n`` -- positive integer - - ``check`` -- boolean (default: ``True``); if ``True``, check that the + - ``check`` -- boolean (default: ``True``); if ``True``, check that the resulting matrix is Hadamard before returning it OUTPUT: @@ -2512,7 +2602,7 @@ def get_fixed_set(s, G, q): def GS_skew_hadamard_smallcases(n, existence=False, check=True): r""" - Data for Williamson-Goethals-Seidel construction of skew Hadamard matrices + Data for Williamson-Goethals-Seidel construction of skew Hadamard matrices. Here we keep the data for this construction. Namely, it needs 4 circulant matrices with extra properties, as described in @@ -2534,7 +2624,7 @@ def GS_skew_hadamard_smallcases(n, existence=False, check=True): - ``n`` -- integer; the order of the matrix - ``existence`` -- boolean (default: ``True``); if ``True``, only check that we can do the construction - - ``check`` -- boolean (default: ``False``): if ``True``, check the result + - ``check`` -- boolean (default: ``False``); if ``True``, check the result TESTS:: @@ -2801,7 +2891,7 @@ def skew_hadamard_matrix_whiteman_construction(n, existence=False, check=True): INPUT: - ``n`` -- positive integer; the order of the matrix to be constructed - - ``existence`` -- boolean (default: ``False``); If ``True``, only return + - ``existence`` -- boolean (default: ``False``); if ``True``, only return whether the Hadamard matrix can be constructed - ``check`` -- boolean (default: ``True``); if ``True``, check that the result is a skew Hadamard matrix before returning it @@ -2992,9 +3082,9 @@ def skew_hadamard_matrix_from_good_matrices_smallcases(n, existence=False, check INPUT: - ``n`` -- integer; the order of the skew Hadamard matrix to be constructed - - ``existence`` -- boolean (default: ``False``); If ``True``, only return + - ``existence`` -- boolean (default: ``False``); if ``True``, only return whether the Hadamard matrix can be constructed - - ``check`` -- boolean (default: ``True``): if ``True``, check that the matrix + - ``check`` -- boolean (default: ``True``); if ``True``, check that the matrix is a Hadamard matrix before returning it OUTPUT: @@ -3084,7 +3174,7 @@ def pm_to_good_matrix(s, sign=1): def skew_hadamard_matrix(n, existence=False, skew_normalize=True, check=True, construction_name=False): r""" - Tries to construct a skew Hadamard matrix. + Try to construct a skew Hadamard matrix. A Hadamard matrix `H` is called skew if `H=S-I`, for `I` the identity matrix and `-S=S^\top`. Currently all orders `\le 1200` for which a construction is @@ -3100,13 +3190,13 @@ def skew_hadamard_matrix(n, existence=False, skew_normalize=True, check=True, - ``True`` -- meaning that Sage knows how to build the matrix - ``Unknown`` -- meaning that Sage does not know how to build the matrix, but that the design may exist (see :mod:`sage.misc.unknown`). - - ``False`` -- meaning that the matrix does not exist. + - ``False`` -- meaning that the matrix does not exist - ``skew_normalize`` -- boolean (default: ``True``); whether to make the 1st row all-one, and adjust the 1st column accordingly - ``check`` -- boolean (default: ``True``); whether to check that output is - correct before returning it. As this is expected to be useless (but we are - cautious guys), you may want to disable it whenever you want speed + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. - ``construction_name`` -- boolean (default: ``False``); if it is ``True``, ``existence`` is ``True``, and a matrix exists, output the construction name. It has no effect if ``existence`` is set to ``False``. @@ -3265,9 +3355,9 @@ def true(nam): return M -def symmetric_conference_matrix(n, check=True): +def symmetric_conference_matrix(n, check=True, existence=False): r""" - Tries to construct a symmetric conference matrix + Try to construct a symmetric conference matrix. A conference matrix is an `n\times n` matrix `C` with 0s on the main diagonal and 1s and -1s elsewhere, satisfying `CC^\top=(n-1)I`. @@ -3280,8 +3370,10 @@ def symmetric_conference_matrix(n, check=True): - ``n`` -- integer; dimension of the matrix - ``check`` -- boolean (default: ``True``); whether to check that output is - correct before returning it. As this is expected to be useless (but we are - cautious guys), you may want to disable it whenever you want speed + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. + - ``existence`` -- boolean (default: ``False``); if true, only check that such + a matrix exists. EXAMPLES:: @@ -3302,9 +3394,11 @@ def symmetric_conference_matrix(n, check=True): """ from sage.graphs.strongly_regular_db import strongly_regular_graph as srg try: - m = srg(n-1, (n-2)/2, (n-6)/4, (n-2)/4) + m = srg(n-1, (n-2)/2, (n-6)/4, (n-2)/4, existence=existence) except ValueError: raise + if existence: + return m C = matrix([0]+[1]*(n-1)).stack(matrix([1]*(n-1)).stack(m.seidel_adjacency_matrix()).T) if check: assert (C == C.T and C**2 == (n-1)*I(n)) @@ -3313,7 +3407,7 @@ def symmetric_conference_matrix(n, check=True): def szekeres_difference_set_pair(m, check=True): r""" - Construct Szekeres `(2m+1,m,1)`-cyclic difference family + Construct Szekeres `(2m+1,m,1)`-cyclic difference family. Let `4m+3` be a prime power. Theorem 3 in [Sz1969]_ contains a construction of a pair of *complementary difference sets* `A`, `B` in the subgroup `G` of the quadratic @@ -3363,7 +3457,7 @@ def szekeres_difference_set_pair(m, check=True): def typeI_matrix_difference_set(G, A): r""" - (1,-1)-incidence type I matrix of a difference set `A` in `G` + (1,-1)-incidence type I matrix of a difference set `A` in `G`. Let `A` be a difference set in a group `G` of order `n`. Return `n\times n` matrix `M` with `M_{ij}=1` if `A_i A_j^{-1} \in A`, and `M_{ij}=-1` otherwise. @@ -3386,7 +3480,7 @@ def typeI_matrix_difference_set(G, A): def rshcd_from_prime_power_and_conference_matrix(n): r""" - Return a `((n-1)^2,1)`-RSHCD if `n` is prime power, and symmetric `(n-1)`-conference matrix exists + Return a `((n-1)^2,1)`-RSHCD if `n` is prime power, and symmetric `(n-1)`-conference matrix exists. The construction implemented here is Theorem 16 (and Corollary 17) from [WW1972]_. @@ -3401,7 +3495,7 @@ def rshcd_from_prime_power_and_conference_matrix(n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer .. SEEALSO:: @@ -3477,7 +3571,7 @@ def are_amicable_hadamard_matrices(M, N, verbose=False): - ``M`` -- a square matrix - ``N`` -- a square matrix - - ``verbose`` -- boolean (default ``False``); whether to be verbose when the + - ``verbose`` -- boolean (default: ``False``); whether to be verbose when the matrices are not amicable Hadamard matrices EXAMPLES:: diff --git a/src/sage/combinat/matrices/latin.py b/src/sage/combinat/matrices/latin.py index 936edcc6ea4..29fbe2f960e 100644 --- a/src/sage/combinat/matrices/latin.py +++ b/src/sage/combinat/matrices/latin.py @@ -331,7 +331,7 @@ def __copy__(self): def clear_cells(self): """ - Mark every cell in self as being empty. + Mark every cell in ``self`` as being empty. EXAMPLES:: @@ -406,7 +406,7 @@ def list(self): def nr_filled_cells(self): """ Return the number of filled cells (i.e. cells with a positive - value) in the partial latin square self. + value) in the partial latin square ``self``. EXAMPLES:: @@ -459,7 +459,7 @@ def actual_row_col_sym_sizes(self): def is_empty_column(self, c): """ - Check if column c of the partial latin square self is empty. + Check if column c of the partial latin square ``self`` is empty. EXAMPLES:: @@ -475,7 +475,7 @@ def is_empty_column(self, c): def is_empty_row(self, r): """ - Check if row r of the partial latin square self is empty. + Check if row r of the partial latin square ``self`` is empty. EXAMPLES:: @@ -492,7 +492,7 @@ def is_empty_row(self, r): def nr_distinct_symbols(self): """ Return the number of distinct symbols in the partial latin square - self. + ``self``. EXAMPLES:: @@ -513,7 +513,7 @@ def nr_distinct_symbols(self): def apply_isotopism(self, row_perm, col_perm, sym_perm): """ An isotopism is a permutation of the rows, columns, and symbols of - a partial latin square self. Use isotopism() to convert a tuple + a partial latin square ``self``. Use isotopism() to convert a tuple (indexed from 0) to a Permutation object. EXAMPLES:: @@ -554,11 +554,11 @@ def apply_isotopism(self, row_perm, col_perm, sym_perm): def filled_cells_map(self): """ - Number the filled cells of self with integers from {1, 2, 3, ...}. + Number the filled cells of ``self`` with integers from {1, 2, 3, ...}. INPUT: - - ``self`` -- partial latin square self (empty cells + - ``self`` -- partial latin square ``self`` (empty cells have negative values) OUTPUT: @@ -619,12 +619,12 @@ def filled_cells_map(self): def top_left_empty_cell(self): """ - Return the least [r, c] such that self[r, c] is an empty cell. If - all cells are filled then we return None. + Return the least ``[r, c]`` such that ``self[r, c]`` is an empty cell. + If all cells are filled then we return ``None``. INPUT: - - ``self`` -- LatinSquare + - ``self`` -- LatinSquare EXAMPLES:: @@ -643,7 +643,7 @@ def top_left_empty_cell(self): def is_partial_latin_square(self): """ - self is a partial latin square if it is an n by n matrix, and each + ``self`` is a partial latin square if it is an n by n matrix, and each symbol in [0, 1, ..., n-1] appears at most once in each row, and at most once in each column. @@ -704,7 +704,7 @@ def is_partial_latin_square(self): def is_latin_square(self): """ - self is a latin square if it is an n by n matrix, and each symbol + ``self`` is a latin square if it is an n by n matrix, and each symbol in [0, 1, ..., n-1] appears exactly once in each row, and exactly once in each column. @@ -736,16 +736,16 @@ def is_latin_square(self): def permissable_values(self, r, c): """ Find all values that do not appear in row r and column c of the - latin square self. If self[r, c] is filled then we return the empty - list. + latin square ``self``. If ``self[r, c]`` is filled then we return the + empty list. INPUT: - - ``self`` -- LatinSquare + - ``self`` -- LatinSquare - - ``r`` -- int; row of the latin square + - ``r`` -- integer; row of the latin square - - ``c`` -- int; column of the latin square + - ``c`` -- integer; column of the latin square EXAMPLES:: @@ -788,7 +788,7 @@ def random_empty_cell(self): INPUT: - - ``self`` -- LatinSquare + - ``self`` -- LatinSquare OUTPUT: @@ -822,7 +822,7 @@ def random_empty_cell(self): def is_uniquely_completable(self): """ - Return True if the partial latin square self has exactly one + Return ``True`` if the partial latin square ``self`` has exactly one completion to a latin square. This is just a wrapper for the current best-known algorithm, Dancing Links by Knuth. See dancing_links.spyx @@ -850,7 +850,7 @@ def is_uniquely_completable(self): def is_completable(self): """ - Return True if the partial latin square can be completed to a + Return ``True`` if the partial latin square can be completed to a latin square. EXAMPLES: @@ -888,7 +888,7 @@ def is_completable(self): def gcs(self): """ - A greedy critical set of a latin square self is found by + A greedy critical set of a latin square ``self`` is found by successively removing elements in a row-wise (bottom-up) manner, checking for unique completion at each step. @@ -934,7 +934,7 @@ def gcs(self): def dlxcpp_has_unique_completion(self): """ - Check if the partial latin square self of order n can be embedded + Check if the partial latin square ``self`` of order n can be embedded in precisely one latin square of order n. EXAMPLES:: @@ -953,7 +953,7 @@ def dlxcpp_has_unique_completion(self): def vals_in_row(self, r): """ - Return a dictionary with key e if and only if row r of self has + Return a dictionary with key e if and only if row r of ``self`` has the symbol e. EXAMPLES:: @@ -977,7 +977,7 @@ def vals_in_row(self, r): def vals_in_col(self, c): """ - Return a dictionary with key e if and only if column c of self has + Return a dictionary with key e if and only if column c of ``self`` has the symbol e. EXAMPLES:: @@ -1212,8 +1212,7 @@ def disjoint_mate_dlxcpp_rows_and_map(self, allow_subtrade): dlx_rows.append([c_OFFSET, r_OFFSET, xy_OFFSET]) - if max_column_nr < max(c_OFFSET, r_OFFSET, xy_OFFSET): - max_column_nr = max(c_OFFSET, r_OFFSET, xy_OFFSET) + max_column_nr = max(max_column_nr, max(c_OFFSET, r_OFFSET, xy_OFFSET)) # We will have missed some columns. We # have to add 'dummy' rows so that the C++ DLX solver will find @@ -1278,7 +1277,7 @@ def find_disjoint_mates(self, nr_to_find=None, allow_subtrade=False): def contained_in(self, Q): r""" - Return True if self is a subset of Q? + Return ``True`` if ``self`` is a subset of `Q`. EXAMPLES:: @@ -1467,20 +1466,20 @@ def isotopism(p): According to the type of input (see examples below): - - an integer `n` -- the function returns the identity on `1,...,n`. + - an integer `n` -- the function returns the identity on `1,...,n` - a string representing a permutation in disjoint cycles notation, e.g. `(0,1,2)(3,4,5)` -- the corresponding permutation is returned, - shifted by 1 to act on `1,...,n`. + shifted by 1 to act on `1,...,n` - list/tuple of tuples -- assumes disjoint cycle notation, see previous - entry. + entry - a list of integers -- the function adds `1` to each member of the - list, and returns the corresponding permutation. + list, and returns the corresponding permutation - a :class:`PermutationGroupElement` ``p`` -- returns a permutation - describing ``p`` **without** any shift. + describing ``p`` **without** any shift EXAMPLES:: @@ -1550,7 +1549,7 @@ def cells_map_as_square(cells_map, n): Return a LatinSquare with cells numbered from 1, 2, ... to given the dictionary cells_map. - .. note:: + .. NOTE:: The value n should be the maximum of the number of rows and columns of the original partial latin square @@ -1596,13 +1595,11 @@ def beta1(rce, T1, T2): INPUT: + - ``rce`` -- tuple (or list) (r, c, e) in T1 - - ``rce`` -- tuple (or list) (r, c, e) in T1 + - ``T1``, ``T2`` -- latin bitrade - - ``T1, T2`` -- latin bitrade - - - OUTPUT: (x, c, e) in T2. + OUTPUT: (x, c, e) in T2 EXAMPLES:: @@ -1637,14 +1634,11 @@ def beta2(rce, T1, T2): INPUT: - - ``rce`` -- tuple (or list) (r, c, e) in T1 - - - ``T1, T2`` -- latin bitrade + - ``rce`` -- tuple (or list) (r, c, e) in T1 + - ``T1``, ``T2`` -- latin bitrade - OUTPUT: - - - (r, x, e) in T2. + OUTPUT: (r, x, e) in T2 EXAMPLES:: @@ -1679,15 +1673,11 @@ def beta3(rce, T1, T2): INPUT: + - ``rce`` -- tuple (or list) (r, c, e) in T1 - - ``rce`` -- tuple (or list) (r, c, e) in T1 - - - ``T1, T2`` -- latin bitrade - - - OUTPUT: + - ``T1, T2`` -- latin bitrade - - (r, c, x) in T2. + OUTPUT: (r, c, x) in T2. EXAMPLES:: @@ -1728,7 +1718,7 @@ def tau1(T1, T2, cells_map): \tau_1 = \beta_2^{-1} \beta_3 where the composition is left to right and `\beta_i : T2 \rightarrow T1` - changes just the `i^{th}` coordinate of a triple. + changes just the `i`-th coordinate of a triple. EXAMPLES:: @@ -1782,7 +1772,7 @@ def tau2(T1, T2, cells_map): \tau_2 = \beta_3^{-1} \beta_1 where the composition is left to right and `\beta_i : T2 \rightarrow T1` - changes just the `i^{th}` coordinate of a triple. + changes just the `i`-th coordinate of a triple. EXAMPLES:: @@ -1836,7 +1826,7 @@ def tau3(T1, T2, cells_map): \tau_3 = \beta_1^{-1} \beta_2 where the composition is left to right and `\beta_i : T2 \rightarrow T1` - changes just the `i^{th}` coordinate of a triple. + changes just the `i`-th coordinate of a triple. EXAMPLES:: @@ -1887,7 +1877,7 @@ def back_circulant(n): INPUT: - - ``n`` -- int; order of the latin square. + - ``n`` -- integer; order of the latin square EXAMPLES:: @@ -1917,7 +1907,7 @@ def forward_circulant(n): INPUT: - - ``n`` -- int; order of the latin square. + - ``n`` -- integer; order of the latin square EXAMPLES:: @@ -1993,7 +1983,7 @@ def elementary_abelian_2group(s): INPUT: - - ``s`` -- int; order of the latin square will be 2s. + - ``s`` -- integer; order of the latin square will be 2s EXAMPLES:: @@ -2035,7 +2025,7 @@ def elementary_abelian_2group(s): def coin(): """ - Simulate a fair coin (returns True or False) using + Simulate a fair coin (returns ``True`` or ``False``) using ZZ.random_element(2). EXAMPLES:: @@ -2453,7 +2443,7 @@ def p3_group_bitrade_generators(p): EXAMPLES:: sage: from sage.combinat.matrices.latin import * - sage: p3_group_bitrade_generators(3) + sage: p3_group_bitrade_generators(3) # random output ((2,6,7)(3,8,9), (1,2,3)(4,7,8)(5,6,9), (1,9,2)(3,7,4)(5,8,6), diff --git a/src/sage/combinat/matrices/meson.build b/src/sage/combinat/matrices/meson.build new file mode 100644 index 00000000000..86021f8d376 --- /dev/null +++ b/src/sage/combinat/matrices/meson.build @@ -0,0 +1,22 @@ +py.install_sources( + 'all.py', + 'dlxcpp.py', + 'hadamard_matrix.py', + 'latin.py', + subdir: 'sage/combinat/matrices', +) + +extension_data_cpp = {'dancing_links': files('dancing_links.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/matrices', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/combinat/meson.build b/src/sage/combinat/meson.build new file mode 100644 index 00000000000..c0e9fe15d8b --- /dev/null +++ b/src/sage/combinat/meson.build @@ -0,0 +1,175 @@ +py.install_sources( + 'SJT.py', + 'abstract_tree.py', + 'affine_permutation.py', + 'algebraic_combinatorics.py', + 'all.py', + 'alternating_sign_matrix.py', + 'backtrack.py', + 'baxter_permutations.py', + 'bijectionist.py', + 'binary_recurrence_sequences.py', + 'binary_tree.py', + 'blob_algebra.py', + 'cartesian_product.py', + 'catalog_partitions.py', + 'cluster_complex.py', + 'colored_permutations.py', + 'combinat.py', + 'combinat_cython.pxd', + 'combination.py', + 'combinatorial_map.py', + 'composition.py', + 'composition_signed.py', + 'composition_tableau.py', + 'constellation.py', + 'core.py', + 'counting.py', + 'cyclic_sieving_phenomenon.py', + 'decorated_permutation.py', + 'derangements.py', + 'descent_algebra.py', + 'diagram.py', + 'diagram_algebras.py', + 'dlx.py', + 'dyck_word.py', + 'e_one_star.py', + 'enumerated_sets.py', + 'enumeration_mod_permgroup.pxd', + 'family.py', + 'finite_state_machine.py', + 'finite_state_machine_generators.py', + 'fqsym.py', + 'free_dendriform_algebra.py', + 'free_module.py', + 'free_prelie_algebra.py', + 'fully_commutative_elements.py', + 'fully_packed_loop.py', + 'gelfand_tsetlin_patterns.py', + 'graph_path.py', + 'gray_codes.py', + 'grossman_larson_algebras.py', + 'growth.py', + 'hall_polynomial.py', + 'hillman_grassl.py', + 'integer_matrices.py', + 'integer_vector.py', + 'integer_vector_weighted.py', + 'integer_vectors_mod_permgroup.py', + 'interval_posets.py', + 'k_tableau.py', + 'kazhdan_lusztig.py', + 'key_polynomial.py', + 'knutson_tao_puzzles.py', + 'lr_tableau.py', + 'misc.py', + 'multiset_partition_into_sets_ordered.py', + 'necklace.py', + 'non_decreasing_parking_function.py', + 'nu_dyck_word.py', + 'nu_tamari_lattice.py', + 'ordered_tree.py', + 'output.py', + 'parallelogram_polyomino.py', + 'parking_functions.py', + 'partition.py', + 'partition_algebra.py', + 'partition_kleshchev.py', + 'partition_shifting_algebras.py', + 'partition_tuple.py', + 'perfect_matching.py', + 'permutation.py', + 'permutation_cython.pxd', + 'plane_partition.py', + 'q_analogues.py', + 'quickref.py', + 'ranker.py', + 'recognizable_series.py', + 'regular_sequence.py', + 'restricted_growth.py', + 'ribbon.py', + 'ribbon_shaped_tableau.py', + 'ribbon_tableau.py', + 'rooted_tree.py', + 'rsk.py', + 'schubert_polynomial.py', + 'set_partition.py', + 'set_partition_ordered.py', + 'shard_order.py', + 'shifted_primed_tableau.py', + 'shuffle.py', + 'sidon_sets.py', + 'similarity_class_type.py', + 'sine_gordon.py', + 'six_vertex_model.py', + 'skew_partition.py', + 'skew_tableau.py', + 'sloane_functions.py', + 'specht_module.py', + 'subset.py', + 'subsets_hereditary.py', + 'subsets_pairwise.py', + 'subword.py', + 'subword_complex.py', + 'super_tableau.py', + 'superpartition.py', + 'symmetric_group_algebra.py', + 'symmetric_group_representations.py', + 't_sequences.py', + 'tableau.py', + 'tableau_residues.py', + 'tableau_tuple.py', + 'tamari_lattices.py', + 'tiling.py', + 'tools.py', + 'triangles_FHM.py', + 'tuple.py', + 'tutorial.py', + 'vector_partition.py', + 'yang_baxter_graph.py', + subdir: 'sage/combinat', +) + +extension_data = { + 'combinat_cython' : files('combinat_cython.pyx'), + 'debruijn_sequence' : files('debruijn_sequence.pyx'), + 'degree_sequences' : files('degree_sequences.pyx'), + 'enumeration_mod_permgroup' : files('enumeration_mod_permgroup.pyx'), + 'expnums' : files('expnums.pyx'), + 'fast_vector_partitions' : files('fast_vector_partitions.pyx'), + 'partitions' : files('partitions.pyx'), + 'permutation_cython' : files('permutation_cython.pyx'), + 'q_bernoulli' : files('q_bernoulli.pyx'), + 'set_partition_iterator' : files('set_partition_iterator.pyx'), + 'subword_complex_c' : files('subword_complex_c.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +install_subdir('chas', install_dir: sage_install_dir / 'combinat') +install_subdir( + 'cluster_algebra_quiver', + install_dir: sage_install_dir / 'combinat', +) +subdir('crystals') +subdir('designs') +subdir('integer_lists') +subdir('matrices') +install_subdir('ncsf_qsym', install_dir: sage_install_dir / 'combinat') +install_subdir('ncsym', install_dir: sage_install_dir / 'combinat') +install_subdir('path_tableaux', install_dir: sage_install_dir / 'combinat') +subdir('posets') +subdir('rigged_configurations') +subdir('root_system') +install_subdir('sf', install_dir: sage_install_dir / 'combinat') +install_subdir('species', install_dir: sage_install_dir / 'combinat') +subdir('words') diff --git a/src/sage/combinat/misc.py b/src/sage/combinat/misc.py index 2a4341e8f4c..d04b615be80 100644 --- a/src/sage/combinat/misc.py +++ b/src/sage/combinat/misc.py @@ -181,7 +181,7 @@ def prev(self, j): def _monomial_exponent_to_lower_factorial(me, x): r""" - Converts a tuple of exponents to the monomial obtained by replacing + Convert a tuple of exponents to the monomial obtained by replacing each me[i] with `x_i*(x_i - 1)*\cdots*(x_i - a_i + 1)` EXAMPLES:: @@ -202,16 +202,12 @@ def _monomial_exponent_to_lower_factorial(me, x): sage: _monomial_exponent_to_lower_factorial(([2,2,2]),a) x^2*y^2*z^2 - x^2*y^2*z - x^2*y*z^2 - x*y^2*z^2 + x^2*y*z + x*y^2*z + x*y*z^2 - x*y*z """ - terms = [] - for i in range(len(me)): - for j in range(me[i]): - terms.append( x[i]-j ) - return prod(terms) + return prod(x[i] - j for i, mei in enumerate(me) for j in range(mei)) def umbral_operation(poly): r""" - Returns the umbral operation `\downarrow` applied to poly. + Return the umbral operation `\downarrow` applied to poly. The umbral operation replaces each instance of `x_i^{a_i}` with @@ -235,7 +231,7 @@ def umbral_operation(poly): exponents = poly.exponents() coefficients = poly.coefficients() length = len(exponents) - return sum( [coefficients[i]*_monomial_exponent_to_lower_factorial(exponents[i],x) for i in range(length)] ) + return sum(coefficients[i]*_monomial_exponent_to_lower_factorial(exponents[i], x) for i in range(length)) class IterableFunctionCall: diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index f6d8c5cb4ec..aae1cd569a2 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -96,7 +96,7 @@ class OrderedMultisetPartitionIntoSets(ClonableArray, metaclass=InheritComparisonClasscallMetaclass): r""" - Ordered Multiset Partition into sets + Ordered Multiset Partition into sets. An *ordered multiset partition into sets* `c` of a multiset `X` is a list `[c_1, \ldots, c_r]` of nonempty subsets of `X` (note: not @@ -224,7 +224,7 @@ def check(self): def _repr_(self): """ - Return a string representation of ``self.`` + Return a string representation of ``self``. EXAMPLES:: @@ -432,7 +432,7 @@ def multiset(self, as_dict=False): INPUT: - - ``as_dict`` -- (default: ``False``) whether to return the multiset + - ``as_dict`` -- boolean (default: ``False``); whether to return the multiset as a tuple of a dict of multiplicities EXAMPLES:: @@ -1127,7 +1127,7 @@ class OrderedMultisetPartitionsIntoSets(UniqueRepresentation, Parent): - Two Arguments: - + `A` -- a list (representing allowable letters within blocks of `c`), + + `A` -- list (representing allowable letters within blocks of `c`), or a positive integer (representing the maximal allowable letter) + `n` -- a nonnegative integer (the total number of letters within `c`) @@ -1912,7 +1912,7 @@ def subset(self, size): INPUT: - - ``size`` -- an integer representing a slice of all ordered + - ``size`` -- integer representing a slice of all ordered multiset partitions into sets The slice alluded to above is taken with respect to length, or @@ -3089,7 +3089,7 @@ def _refine_block(S, strong=False): def _is_initial_segment(lst): r""" - Return True if ``lst`` is an interval in `\ZZ` of the form `[0, 1, \ldots, n]`. + Return ``True`` if ``lst`` is an interval in `\ZZ` of the form `[0, 1, \ldots, n]`. EXAMPLES:: @@ -3148,7 +3148,7 @@ def _to_minimaj_blocks(T): INPUT: - - ``T`` -- a sequence of row words corresponding to (skew-)tableaux. + - ``T`` -- a sequence of row words corresponding to (skew-)tableaux OUTPUT: @@ -3416,7 +3416,7 @@ class Element(ElementWrapper): Minimaj elements `b` are stored internally as pairs ``(w, breaks)``, where: - - ``w`` is a word of length ``self.parent().ell`` over the + - ``w`` -- a word of length ``self.parent().ell`` over the letters `1` up to ``self.parent().n``; - ``breaks`` is a list of de-concatenation points to turn ``w`` into a list of row words of (skew-)tableaux that represent diff --git a/src/sage/combinat/ncsf_qsym/combinatorics.py b/src/sage/combinat/ncsf_qsym/combinatorics.py index d85efe38719..ef930596ab8 100644 --- a/src/sage/combinat/ncsf_qsym/combinatorics.py +++ b/src/sage/combinat/ncsf_qsym/combinatorics.py @@ -31,7 +31,7 @@ def coeff_pi(J, I): r""" - Returns the coefficient `\pi_{J,I}` as defined in [NCSF]_. + Return the coefficient `\pi_{J,I}` as defined in [NCSF]_. INPUT: @@ -53,7 +53,7 @@ def coeff_pi(J, I): def coeff_lp(J,I): r""" - Returns the coefficient `lp_{J,I}` as defined in [NCSF]_. + Return the coefficient `lp_{J,I}` as defined in [NCSF]_. INPUT: @@ -75,7 +75,7 @@ def coeff_lp(J,I): def coeff_ell(J,I): r""" - Returns the coefficient `\ell_{J,I}` as defined in [NCSF]_. + Return the coefficient `\ell_{J,I}` as defined in [NCSF]_. INPUT: @@ -97,7 +97,7 @@ def coeff_ell(J,I): def coeff_sp(J, I): r""" - Returns the coefficient `sp_{J,I}` as defined in [NCSF]_. + Return the coefficient `sp_{J,I}` as defined in [NCSF]_. INPUT: @@ -155,12 +155,10 @@ def compositions_order(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - OUTPUT: - - - A list of the compositions of ``n`` sorted into decreasing order - by `\rhd` + OUTPUT: list of the compositions of `n` sorted into decreasing order + by `\rhd` EXAMPLES:: @@ -185,7 +183,7 @@ def m_to_s_stat(R, I, K): INPUT: - - ``R`` -- A ring, supposed to be a `\QQ`-algebra + - ``R`` -- a ring; supposed to be a `\QQ`-algebra - ``I``, ``K`` -- compositions OUTPUT: @@ -226,9 +224,7 @@ def number_of_fCT(content_comp, shape_comp): - ``content_comp``, ``shape_comp`` -- compositions - OUTPUT: - - - An integer + OUTPUT: integer EXAMPLES:: @@ -274,9 +270,7 @@ def number_of_SSRCT(content_comp, shape_comp): - ``content_comp``, ``shape_comp`` -- compositions - OUTPUT: - - - An integer + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index 4fe908d727c..7b2260f3be9 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -57,7 +57,6 @@ def _repr_object_names(self): 'bases of Non-Commutative Symmetric Functions or Quasisymmetric functions over the Rational Field' sage: C Category of bases of Non-Commutative Symmetric Functions or Quasisymmetric functions over the Rational Field - """ return "bases of Non-Commutative Symmetric Functions or Quasisymmetric functions over the %s" % self.base().base_ring() @@ -132,9 +131,7 @@ def one_basis(self): r""" Return the empty composition. - OUTPUT: - - - The empty composition. + OUTPUT: the empty composition EXAMPLES:: @@ -209,7 +206,7 @@ def alternating_sum_of_compositions(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -243,7 +240,7 @@ def alternating_sum_of_finer_compositions(self, composition, conjugate=False): INPUT: - ``composition`` -- a composition - - ``conjugate`` -- (default: ``False``) a boolean + - ``conjugate`` -- boolean (default: ``False``) OUTPUT: @@ -633,8 +630,8 @@ def duality_pairing_matrix(self, basis, degree): INPUT: - - ``basis`` -- A basis of the dual Hopf algebra - - ``degree`` -- a non-negative integer + - ``basis`` -- a basis of the dual Hopf algebra + - ``degree`` -- nonnegative integer OUTPUT: @@ -857,9 +854,7 @@ def duality_pairing(self, y): - ``y`` -- an element of the dual Hopf algebra of ``self`` - OUTPUT: - - - The result of pairing ``self`` with ``y``. + OUTPUT: the result of pairing ``self`` with ``y`` EXAMPLES:: @@ -878,7 +873,6 @@ def duality_pairing(self, y): 0 sage: L[1,1,1].duality_pairing(F[1,2]) 1 - """ return self.parent().duality_pairing(self, y) @@ -893,11 +887,9 @@ def skew_by(self, y, side='left'): INPUT: - ``y`` -- an element of the dual Hopf algebra of ``self`` - - ``side`` -- (Default='left') Either 'left' or 'right' + - ``side`` -- (default: ``'left'``) either ``'left'`` or ``'right'`` - OUTPUT: - - - The result of skewing ``self`` by ``y``, on the side ``side`` + OUTPUT: the result of skewing ``self`` by ``y``, on the side ``side`` EXAMPLES: @@ -1008,13 +1000,11 @@ def __init__(self, domain, on_generators, position=0, codomain=None, category=No - ``domain`` -- an algebra with a multiplicative basis - ``on_generators`` -- a function defined on the index set of the generators - ``codomain`` -- the codomain - - ``position`` -- integer; default is 0 - - ``category`` -- a category; defaults to None - - ``anti`` -- a boolean; defaults to False - - OUTPUT: + - ``position`` -- integer (default: 0) + - ``category`` -- a category (default: ``None``) + - ``anti`` -- boolean (default: ``False``) - - module morphism + OUTPUT: module morphism EXAMPLES: @@ -1132,16 +1122,14 @@ def __ne__(self, other): def _on_basis(self, c): r""" - Computes the image of this morphism on the basis element indexed by + Compute the image of this morphism on the basis element indexed by ``c``. INPUT: - ``c`` -- an iterable that spits out generators - OUTPUT: - - - element of the codomain + OUTPUT: element of the codomain EXAMPLES:: @@ -1152,7 +1140,6 @@ def _on_basis(self, c): sage: f = AlgebraMorphism(Psi, lambda i : Phi[i,i], codomain=Phi) sage: f._on_basis([ 3, 2 ]) Phi[3, 3, 2, 2] - """ if self._anti: c = reversed(c) @@ -1161,7 +1148,7 @@ def _on_basis(self, c): class GradedModulesWithInternalProduct(Category_over_base_ring): r""" - Constructs the class of modules with internal product. This is used to give an internal + Construct the class of modules with internal product. This is used to give an internal product structure to the non-commutative symmetric functions. EXAMPLES:: @@ -1194,7 +1181,7 @@ def internal_product_on_basis(self, I, J): INPUT: - - ``I``, ``J`` -- compositions indexing two elements of the basis of self + - ``I``, ``J`` -- compositions indexing two elements of the basis of self Returns the internal product of the corresponding basis elements. If this method is implemented, the internal product is defined from @@ -1247,7 +1234,6 @@ def internal_product(self): R[2] sage: R.internal_product(R[2,2], R[1,2]) 0 - """ if self.internal_product_on_basis is not NotImplemented: return self.module_morphism( @@ -1426,9 +1412,7 @@ def internal_product_by_coercion(self, left, right): - ``left`` -- an element of the non-commutative symmetric functions - ``right`` -- an element of the non-commutative symmetric functions - OUTPUT: - - - The internal product of ``left`` and ``right``. + OUTPUT: the internal product of ``left`` and ``right`` EXAMPLES:: diff --git a/src/sage/combinat/ncsf_qsym/ncsf.py b/src/sage/combinat/ncsf_qsym/ncsf.py index 65b03741885..c1c1ef90306 100644 --- a/src/sage/combinat/ncsf_qsym/ncsf.py +++ b/src/sage/combinat/ncsf_qsym/ncsf.py @@ -78,7 +78,7 @@ class NonCommutativeSymmetricFunctions(UniqueRepresentation, Parent): We use the Sage standard renaming idiom to get shorter outputs:: - sage: NCSF.rename("NCSF") + sage: NCSF.rename('NCSF') sage: NCSF NCSF @@ -101,9 +101,9 @@ class NonCommutativeSymmetricFunctions(UniqueRepresentation, Parent): The basis itself is accessible through:: sage: Psi.basis() - Lazy family (Term map from Compositions of non-negative integers... + Lazy family (Term map from Compositions of nonnegative integers... sage: Psi.basis().keys() - Compositions of non-negative integers + Compositions of nonnegative integers To construct an element one can therefore do:: @@ -182,8 +182,11 @@ class NonCommutativeSymmetricFunctions(UniqueRepresentation, Parent): bialgebra structure, which cooperates with the grading to form a connected graded bialgebra. Thus, as any connected graded bialgebra, ``Psi`` is a Hopf algebra. Over ``QQ`` (or any other `\QQ`-algebra), - this Hopf algebra ``Psi`` is isomorphic to the tensor algebra of - its space of primitive elements. + this Hopf algebra ``Psi`` is isomorphic to the universal enveloping + algebra of its space of primitive elements. Here, the primitives + form a countably generated free Lie algebra, so ``Psi`` is isomorphic + to the tensor algebra on a countably infinite dimensional vector + space. The antipode is an anti-algebra morphism; in the ``Psi`` basis, it sends the generators to their opposites and changes their sign if @@ -398,7 +401,6 @@ class NonCommutativeSymmetricFunctions(UniqueRepresentation, Parent): sage: TestSuite(Phi).run() sage: TestSuite(Psi).run() sage: TestSuite(complete).run() - """ def __init__(self, R): @@ -455,7 +457,7 @@ def _repr_(self): # could be taken care of by the category def a_realization(self): r""" - Gives a realization of the algebra of non-commutative symmetric functions. This + Give a realization of the algebra of non-commutative symmetric functions. This particular realization is the complete basis of non-commutative symmetric functions. OUTPUT: @@ -509,9 +511,7 @@ def super_categories(self): Return the super categories of the category of bases of the non-commutative symmetric functions. - OUTPUT: - - - list + OUTPUT: list TESTS:: @@ -519,7 +519,6 @@ def super_categories(self): sage: N.Bases().super_categories() [Category of bases of Non-Commutative Symmetric Functions or Quasisymmetric functions over the Rational Field, Category of realizations of graded modules with internal product over Rational Field] - """ R = self.base().base_ring() from .generic_basis_code import GradedModulesWithInternalProduct @@ -778,7 +777,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -1677,9 +1676,7 @@ def to_symmetric_function(self): r""" Return the commutative image of a non-commutative symmetric function. - OUTPUT: - - - The commutative image of ``self``. This will be a symmetric function. + OUTPUT: the commutative image of ``self``; this will be a symmetric function EXAMPLES:: @@ -1919,20 +1916,18 @@ def to_fsym(self): def expand(self, n, alphabet='x'): r""" Expand the noncommutative symmetric function into an - element of a free algebra in ``n`` indeterminates of + element of a free algebra in `n` indeterminates of an alphabet, which by default is ``'x'``. INPUT: - - ``n`` -- a nonnegative integer; the number of variables + - ``n`` -- nonnegative integer; the number of variables in the expansion - - ``alphabet`` -- (default: ``'x'``); the alphabet in + - ``alphabet`` -- (default: ``'x'``) the alphabet in which ``self`` is to be expanded - OUTPUT: - - - An expansion of ``self`` into the ``n`` variables - specified by ``alphabet``. + OUTPUT: an expansion of ``self`` into the `n` variables + specified by ``alphabet`` EXAMPLES:: @@ -1959,7 +1954,7 @@ def expand(self, n, alphabet='x'): One can use a different set of variables by adding an optional argument ``alphabet=...``:: - sage: L[3].expand(4, alphabet="y") + sage: L[3].expand(4, alphabet='y') y2*y1*y0 + y3*y1*y0 + y3*y2*y0 + y3*y2*y1 TESTS:: @@ -2025,16 +2020,13 @@ def super_categories(self): Return the super categories of the category of multiplicative bases of the non-commutative symmetric functions. - OUTPUT: - - - list + OUTPUT: list TESTS:: sage: N = NonCommutativeSymmetricFunctions(QQ) sage: N.MultiplicativeBases().super_categories() [Category of bases of Non-Commutative Symmetric Functions over the Rational Field] - """ return [self.base().Bases()] @@ -2046,9 +2038,7 @@ def algebra_generators(self): Return the algebra generators of a given multiplicative basis of non-commutative symmetric functions. - OUTPUT: - - - The family of generators of the multiplicative basis ``self``. + OUTPUT: the family of generators of the multiplicative basis ``self`` EXAMPLES:: @@ -2101,8 +2091,8 @@ def algebra_morphism(self, on_generators, **keywords): - ``on_generators`` -- a function defined on the index set of the generators (that is, on the positive integers) - - ``anti`` -- a boolean; defaults to ``False`` - - ``category`` -- a category; defaults to ``None`` + - ``anti`` -- boolean (default: ``False``) + - ``category`` -- a category (default: ``None``) OUTPUT: @@ -2300,9 +2290,7 @@ def super_categories(self): bases of group-like elements of the non-commutative symmetric functions. - OUTPUT: - - - list + OUTPUT: list TESTS:: @@ -2348,17 +2336,15 @@ def antipode_on_basis(self, composition): # @cached_method? def coproduct_on_generators(self, i): r""" - Return the image of the `i^{th}` generator of the algebra under + Return the image of the `i`-th generator of the algebra under the coproduct. INPUT: - - ``i`` -- a positive integer - - OUTPUT: + - ``i`` -- positive integer - - The result of applying the coproduct to the `i^{th}` - generator of ``self``. + OUTPUT: the result of applying the coproduct to the `i`-th + generator of ``self`` EXAMPLES:: @@ -2423,9 +2409,7 @@ def super_categories(self): bases of primitive elements of the non-commutative symmetric functions. - OUTPUT: - - - list + OUTPUT: list TESTS:: @@ -2445,13 +2429,13 @@ def antipode_on_generators(self, i): INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer OUTPUT: - - The image of the `i`-th generator of the multiplicative - basis ``self`` under the antipode of the algebra of - non-commutative symmetric functions. + The image of the `i`-th generator of the multiplicative basis + ``self`` under the antipode of the algebra of non-commutative + symmetric functions. EXAMPLES:: @@ -2472,17 +2456,15 @@ def antipode_on_generators(self, i): def coproduct_on_generators(self, i): r""" - Return the image of the `i^{th}` generator of the + Return the image of the `i`-th generator of the multiplicative basis ``self`` under the coproduct. INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer - OUTPUT: - - - The result of applying the coproduct to the - `i^{th}` generator of ``self``. + OUTPUT: the result of applying the coproduct to the + `i`-th generator of ``self`` EXAMPLES:: @@ -2584,9 +2566,7 @@ def dual(self): Return the dual basis to the ribbon basis of the non-commutative symmetric functions. This is the Fundamental basis of the quasi-symmetric functions. - OUTPUT: - - - The fundamental basis of the quasi-symmetric functions. + OUTPUT: the fundamental basis of the quasi-symmetric functions EXAMPLES:: @@ -2605,9 +2585,7 @@ def product_on_basis(self, I, J): - ``I``, ``J`` -- compositions - OUTPUT: - - - The product of the ribbon functions indexed by ``I`` and ``J``. + OUTPUT: the product of the ribbon functions indexed by ``I`` and ``J`` EXAMPLES:: @@ -2774,7 +2752,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -2982,9 +2960,7 @@ def dual(self): Return the dual basis to the complete basis of non-commutative symmetric functions. This is the Monomial basis of quasi-symmetric functions. - OUTPUT: - - - The Monomial basis of quasi-symmetric functions. + OUTPUT: the Monomial basis of quasi-symmetric functions EXAMPLES:: @@ -3027,7 +3003,7 @@ def internal_product_on_basis(self, I, J): def to_symmetric_function_on_basis(self, I): r""" - The commutative image of a complete element + The commutative image of a complete element. The commutative image of a basis element is obtained by sorting the indexing composition of the basis element and the output @@ -3350,7 +3326,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -3677,12 +3653,10 @@ def _from_complete_on_generators(self, n): INPUT: - - ``n`` -- a positive integer - - OUTPUT: + - ``n`` -- positive integer - - The expansion of the complete generator indexed by ``n`` into the - Psi basis. + OUTPUT: the expansion of the complete generator indexed by ``n`` + into the Psi basis TESTS:: @@ -3717,12 +3691,10 @@ def _to_complete_on_generators(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - OUTPUT: - - - The expansion of the `\Psi` function indexed by ``n`` in the - complete basis. + OUTPUT: the expansion of the `\Psi` function indexed by ``n`` in + the complete basis TESTS:: @@ -3991,7 +3963,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -4111,7 +4083,6 @@ def __init__(self, NCSF): True sage: all(Phi(S(Phi[comp])) == Phi[comp] for comp in Compositions(5)) True - """ CombinatorialFreeModule.__init__(self, NCSF.base_ring(), Compositions(), prefix='Phi', bracket=False, @@ -4124,12 +4095,10 @@ def _from_complete_on_generators(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - OUTPUT: - - - The expansion of the complete function indexed by ``n`` in the - `\Phi` basis. + OUTPUT: the expansion of the complete function indexed by ``n`` in + the `\Phi` basis TESTS:: @@ -4154,12 +4123,10 @@ def _to_complete_on_generators(self, n): INPUT: - - ``n`` -- a positive integer - - OUTPUT: + - ``n`` -- positive integer - - The expansion of the `\Phi` function indexed by ``n`` in the - complete basis. + OUTPUT: the expansion of the `\Phi` function indexed by ``n`` in + the complete basis TESTS:: @@ -4252,7 +4219,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -4510,7 +4477,6 @@ def __init__(self, NCSF): True sage: all(nM(S(nM[comp])) == nM[comp] for comp in Compositions(5)) True - """ CombinatorialFreeModule.__init__(self, NCSF.base_ring(), Compositions(), prefix='nM', bracket=False, @@ -4672,7 +4638,6 @@ def __init__(self, NCSF): True sage: all(I(S(I[comp])) == I[comp] for comp in Compositions(5)) True - """ CombinatorialFreeModule.__init__(self, NCSF.base_ring(), Compositions(), prefix='I', bracket=False, @@ -4710,7 +4675,7 @@ def _H(self, alpha): INPUT: - - ``alpha`` -- a list + - ``alpha`` -- list OUTPUT: @@ -4804,9 +4769,7 @@ def dual(self): The basis returned is the dualImmaculate basis of QSym. - OUTPUT: - - - The dualImmaculate basis of the quasi-symmetric functions. + OUTPUT: the dualImmaculate basis of the quasi-symmetric functions EXAMPLES:: @@ -4869,7 +4832,7 @@ def bernstein_creation_operator(self, n): sage: S(elt).bernstein_creation_operator(1) == S(elt.bernstein_creation_operator(1)) True - Check on non-positive values of `n`:: + Check on nonpositive values of `n`:: sage: I[2,2,2].bernstein_creation_operator(-1) I[1, 1, 1, 2] + I[1, 1, 2, 1] + I[1, 2, 1, 1] - I[1, 2, 2] @@ -4998,11 +4961,9 @@ def _to_complete_transition_matrix(self, n): INPUT: - - ``n`` -- an integer - - OUTPUT: + - ``n`` -- integer - - a pair of a square matrix and the ordered list of compositions + OUTPUT: a pair of a square matrix and the ordered list of compositions EXAMPLES:: @@ -5037,9 +4998,7 @@ def _to_complete_on_basis(self, comp): - ``comp`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the complete basis + OUTPUT: a quasi-symmetric function in the complete basis EXAMPLES:: @@ -5094,9 +5053,7 @@ def dual(self): :class:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Quasisymmetric_Schur` basis of QSym. - OUTPUT: - - - the Quasisymmetric-Schur basis of the quasi-symmetric functions + OUTPUT: the Quasisymmetric-Schur basis of the quasi-symmetric functions EXAMPLES:: @@ -5114,7 +5071,7 @@ def dual(self): def to_symmetric_function_on_basis(self, I): r""" - The commutative image of a dual quasi-symmetric Schur element + The commutative image of a dual quasi-symmetric Schur element. The commutative image of a basis element is obtained by sorting the indexing composition of the basis element. @@ -5233,9 +5190,7 @@ def _to_complete_on_basis(self, comp): - ``comp`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the complete basis + OUTPUT: a quasi-symmetric function in the complete basis EXAMPLES:: @@ -5283,9 +5238,7 @@ def dual(self): :class:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Quasisymmetric_Schur` basis of QSym. - OUTPUT: - - - the Young Quasisymmetric-Schur basis of quasi-symmetric functions + OUTPUT: the Young Quasisymmetric-Schur basis of quasi-symmetric functions EXAMPLES:: @@ -5425,7 +5378,7 @@ def _to_complete_on_generator(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -5601,7 +5554,7 @@ def _to_complete_on_generator(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: diff --git a/src/sage/combinat/ncsf_qsym/qsym.py b/src/sage/combinat/ncsf_qsym/qsym.py index 23a9003b506..af82a1569f3 100644 --- a/src/sage/combinat/ncsf_qsym/qsym.py +++ b/src/sage/combinat/ncsf_qsym/qsym.py @@ -623,9 +623,7 @@ def a_realization(self): r""" Return the realization of the Monomial basis of the ring of quasi-symmetric functions. - OUTPUT: - - - The Monomial basis of quasi-symmetric functions. + OUTPUT: the Monomial basis of quasi-symmetric functions EXAMPLES:: @@ -641,9 +639,7 @@ def dual(self): Return the dual Hopf algebra of the quasi-symmetric functions, which is the non-commutative symmetric functions. - OUTPUT: - - - The non-commutative symmetric functions. + OUTPUT: the non-commutative symmetric functions EXAMPLES:: @@ -663,12 +659,10 @@ def from_polynomial(self, f, check=True): - ``f`` -- a polynomial in finitely many variables over the same base ring as ``self``. It is assumed that this polynomial is quasi-symmetric. - - ``check`` -- boolean (default: ``True``), checks whether the - polynomial is indeed quasi-symmetric. - - OUTPUT: + - ``check`` -- boolean (default: ``True``); checks whether the + polynomial is indeed quasi-symmetric - - quasi-symmetric function in the Monomial basis + OUTPUT: quasi-symmetric function in the Monomial basis EXAMPLES:: @@ -703,7 +697,7 @@ def from_polynomial(self, f, check=True): -F[1, 1] + F[2] """ assert self.base_ring() == f.base_ring() - exponent_coefficient = f.dict() + exponent_coefficient = f.monomial_coefficients() z = {} for e, c in exponent_coefficient.items(): I = Compositions()([ei for ei in e if ei]) @@ -729,9 +723,7 @@ def super_categories(self): r""" Return the super categories of bases of the Quasi-symmetric functions. - OUTPUT: - - - a list of categories + OUTPUT: list of categories TESTS:: @@ -760,12 +752,10 @@ def from_polynomial(self, f, check=True): - ``f`` -- a polynomial in finitely many variables over the same base ring as ``self``. It is assumed that this polynomial is quasi-symmetric. - - ``check`` -- boolean (default: ``True``), checks whether the - polynomial is indeed quasi-symmetric. + - ``check`` -- boolean (default: ``True``); checks whether the + polynomial is indeed quasi-symmetric - OUTPUT: - - - quasi-symmetric function + OUTPUT: quasi-symmetric function EXAMPLES:: @@ -876,7 +866,7 @@ def internal_coproduct(self): #. If `I` is a composition, then a `(0, I)`-matrix will mean a matrix whose entries are nonnegative integers such that no row and no column of this matrix is zero, and such that if - all the non-zero entries of the matrix are read (row by row, + all the nonzero entries of the matrix are read (row by row, starting at the topmost row, reading every row from left to right), then the reading word obtained is `I`. If `A` is a `(0, I)`-matrix, then `\mathrm{row}(A)` will denote the @@ -1108,7 +1098,7 @@ def adams_operator(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -1576,15 +1566,13 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- A nonnegative integer; the number of variables + - ``n`` -- nonnegative integer; the number of variables in the expansion - - ``alphabet`` -- (default: ``'x'``); the alphabet in + - ``alphabet`` -- (default: ``'x'``) the alphabet in which ``self`` is to be expanded - OUTPUT: - - - An expansion of ``self`` into the ``n`` variables specified - by ``alphabet``. + OUTPUT: an expansion of ``self`` into the ``n`` variables + specified by ``alphabet`` EXAMPLES:: @@ -1723,9 +1711,7 @@ def dual(self): Return the dual basis to the Monomial basis. This is the complete basis of the non-commutative symmetric functions. - OUTPUT: - - - The complete basis of the non-commutative symmetric functions. + OUTPUT: the complete basis of the non-commutative symmetric functions EXAMPLES:: @@ -2011,13 +1997,11 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- an integer - - ``alphabet`` -- (default: ``'x'``) a string + - ``n`` -- integer + - ``alphabet`` -- string (default: ``'x'``) - OUTPUT: - - - The quasi-symmetric function ``self`` expressed in the ``n`` variables - described by ``alphabet``. + OUTPUT: the quasi-symmetric function ``self`` expressed in the + `n` variables described by ``alphabet`` .. TODO:: accept an *alphabet* as input @@ -2055,7 +2039,7 @@ def on_basis(comp, i): return P.zero() else: return x[i-1]**comp[-1] * on_basis(comp[:-1], i-1) + \ - on_basis(comp, i-1) + on_basis(comp, i-1) return M._apply_module_morphism(self, lambda comp: on_basis(comp,n), codomain=P) @@ -2207,7 +2191,7 @@ def __init__(self, QSym): def _from_schur_on_basis(self, la): r""" - Maps the Schur symmetric function indexed by ``la`` to the + Map the Schur symmetric function indexed by ``la`` to the Fundamental basis. EXAMPLES:: @@ -2237,9 +2221,7 @@ def dual(self): Return the dual basis to the Fundamental basis. This is the ribbon basis of the non-commutative symmetric functions. - OUTPUT: - - - The ribbon basis of the non-commutative symmetric functions. + OUTPUT: the ribbon basis of the non-commutative symmetric functions EXAMPLES:: @@ -2454,7 +2436,7 @@ def internal_coproduct(self): #. If `I` is a composition, then a `(0, I)`-matrix will mean a matrix whose entries are nonnegative integers such that no row and no column of this matrix is zero, and such that if - all the non-zero entries of the matrix are read (row by row, + all the nonzero entries of the matrix are read (row by row, starting at the topmost row, reading every row from left to right), then the reading word obtained is `I`. If `A` is a `(0, I)`-matrix, then `\mathrm{row}(A)` will denote the @@ -2886,11 +2868,9 @@ def _from_monomial_transition_matrix(self, n): INPUT: - - ``n`` -- an integer - - OUTPUT: + - ``n`` -- integer - - a pair of a square matrix and the ordered list of compositions + OUTPUT: a pair of a square matrix and the ordered list of compositions EXAMPLES:: @@ -2917,16 +2897,14 @@ def _from_monomial_transition_matrix(self, n): @cached_method def _from_monomial_on_basis(self, comp): r""" - Maps the Monomial quasi-symmetric function indexed by + Map the Monomial quasi-symmetric function indexed by ``comp`` to the Quasisymmetric Schur basis. INPUT: - ``comp`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the Quasisymmetric Schur basis + OUTPUT: a quasi-symmetric function in the Quasisymmetric Schur basis EXAMPLES:: @@ -2960,9 +2938,7 @@ def _to_monomial_on_basis(self, comp_shape): - ``comp_shape`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the Monomial basis + OUTPUT: a quasi-symmetric function in the Monomial basis EXAMPLES:: @@ -3082,9 +3058,7 @@ def _to_monomial_on_basis(self, comp): - ``comp`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the Monomial basis + OUTPUT: a quasi-symmetric function in the Monomial basis EXAMPLES:: @@ -3108,9 +3082,7 @@ def _from_monomial_on_basis(self, comp): - ``comp`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the Young Quasisymmetric Schur basis + OUTPUT: a quasi-symmetric function in the Young Quasisymmetric Schur basis EXAMPLES:: @@ -3163,9 +3135,7 @@ def _to_Monomial_on_basis(self, J): - ``J`` -- a composition - OUTPUT: - - - A quasi-symmetric function in the monomial basis. + OUTPUT: a quasi-symmetric function in the monomial basis EXAMPLES:: @@ -3231,9 +3201,7 @@ def _from_Monomial_on_basis(self, J): - ``J`` -- a composition - OUTPUT: - - - A quasi-symmetric function in the dual immaculate basis. + OUTPUT: a quasi-symmetric function in the dual immaculate basis EXAMPLES:: @@ -3718,9 +3686,7 @@ def _to_Monomial_on_basis(self, J): - ``J`` -- a composition - OUTPUT: - - - A quasi-symmetric function in the Monomial basis. + OUTPUT: a quasi-symmetric function in the Monomial basis EXAMPLES:: @@ -3742,9 +3708,7 @@ def _from_Monomial_on_basis(self, J): - ``J`` -- a composition - OUTPUT: - - - A quasi-symmetric function in the Hazewinkel lambda basis. + OUTPUT: a quasi-symmetric function in the Hazewinkel lambda basis EXAMPLES:: @@ -3907,9 +3871,7 @@ def _from_Monomial_on_basis(self, I): - ``I`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the `\psi` basis + OUTPUT: a quasi-symmetric function in the `\psi` basis TESTS:: @@ -3935,9 +3897,7 @@ def _to_Monomial_on_basis(self, I): - ``I`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the Monomial basis + OUTPUT: a quasi-symmetric function in the Monomial basis TESTS:: @@ -4050,9 +4010,7 @@ def _from_Monomial_on_basis(self, I): - ``I`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the `\psi` basis + OUTPUT: a quasi-symmetric function in the `\psi` basis TESTS:: @@ -4078,9 +4036,7 @@ def _to_Monomial_on_basis(self, I): - ``I`` -- a composition - OUTPUT: - - - a quasi-symmetric function in the Monomial basis + OUTPUT: a quasi-symmetric function in the Monomial basis TESTS:: diff --git a/src/sage/combinat/ncsym/bases.py b/src/sage/combinat/ncsym/bases.py index 466d1ad42e5..b04afcdbd47 100644 --- a/src/sage/combinat/ncsym/bases.py +++ b/src/sage/combinat/ncsym/bases.py @@ -37,7 +37,7 @@ def _element_constructor_(self, x): INPUT: - - ``x`` -- a set partition or list of lists of integers + - ``x`` -- set partition or list of lists of integers EXAMPLES:: @@ -63,9 +63,7 @@ def super_categories(self): Return the super categories of bases of (the Hopf dual of) the symmetric functions in non-commuting variables. - OUTPUT: - - - a list of categories + OUTPUT: list of categories TESTS:: @@ -124,11 +122,11 @@ def _repr_(self): def __getitem__(self, i): """ - Return the basis element indexed by ``i``. + Return the basis element indexed by `i`. INPUT: - - ``i`` -- a set partition or a list of list of integers + - ``i`` -- set partition or a list of list of integers EXAMPLES:: @@ -153,9 +151,7 @@ def one_basis(self): r""" Return the index of the basis element containing `1`. - OUTPUT: - - - The empty set partition + OUTPUT: the empty set partition EXAMPLES:: @@ -175,11 +171,9 @@ def counit_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - either the ``0`` or the ``1`` of the base ring of ``self`` + OUTPUT: either the `0` or the `1` of the base ring of ``self`` EXAMPLES:: @@ -213,9 +207,7 @@ def duality_pairing(self, x, y): - ``y`` -- an element of the dual of symmetric functions in non-commuting variables - OUTPUT: - - - an element of the base ring of ``self`` + OUTPUT: an element of the base ring of ``self`` EXAMPLES:: @@ -244,12 +236,12 @@ def duality_pairing_matrix(self, basis, degree): INPUT: - ``basis`` -- a basis of the dual Hopf algebra - - ``degree`` -- a non-negative integer + - ``degree`` -- nonnegative integer OUTPUT: - - the matrix of scalar products between the basis ``self`` and the - basis ``basis`` in the dual Hopf algebra of degree ``degree`` + The matrix of scalar products between the basis ``self`` and the + basis ``basis`` in the dual Hopf algebra of degree ``degree``. EXAMPLES: @@ -351,9 +343,7 @@ def super_categories(self): Return the super categories of bases of the Hopf dual of the symmetric functions in non-commuting variables. - OUTPUT: - - - a list of categories + OUTPUT: list of categories TESTS:: @@ -395,9 +385,7 @@ def from_symmetric_function(self, f): - ``f`` -- a symmetric function - OUTPUT: - - - an element of ``self`` + OUTPUT: an element of ``self`` EXAMPLES:: @@ -444,12 +432,10 @@ def primitive(self, A, i=1): INPUT: - - ``A`` -- a set partition - - ``i`` -- a positive integer + - ``A`` -- set partition + - ``i`` -- positive integer - OUTPUT: - - - an element of ``self`` + OUTPUT: an element of ``self`` EXAMPLES:: @@ -471,9 +457,7 @@ def internal_coproduct_on_basis(self, i): - ``i`` -- the indices of an element of the basis of ``self`` - OUTPUT: - - - an element of the tensor squared of ``self`` + OUTPUT: an element of the tensor squared of ``self`` EXAMPLES:: @@ -492,9 +476,7 @@ def internal_coproduct(self): `\otimes` ``self`` by extending it by linearity. Otherwise, this uses :meth:`internal_coproduct_by_coercion()`, if available. - OUTPUT: - - - an element of the tensor squared of ``self`` + OUTPUT: an element of the tensor squared of ``self`` EXAMPLES:: @@ -517,9 +499,7 @@ def internal_coproduct_by_coercion(self, x): - ``x`` -- an element of ``self`` - OUTPUT: - - - an element of the tensor squared of ``self`` + OUTPUT: an element of the tensor squared of ``self`` EXAMPLES:: @@ -587,9 +567,7 @@ def to_symmetric_function(self): multiplicity of `i` in `\mu`. For other bases this map is extended linearly. - OUTPUT: - - - an element of the symmetric functions in the monomial basis + OUTPUT: an element of the symmetric functions in the monomial basis EXAMPLES:: @@ -681,9 +659,7 @@ def internal_coproduct(self): and the map is extended linearly. - OUTPUT: - - - an element of the tensor square of the basis of ``self`` + OUTPUT: an element of the tensor square of the basis of ``self`` EXAMPLES:: @@ -706,9 +682,7 @@ def omega(self): and the result is extended linearly. - OUTPUT: - - - an element in the same basis as ``self`` + OUTPUT: an element in the same basis as ``self`` EXAMPLES:: @@ -753,9 +727,7 @@ def super_categories(self): Return the super categories of bases of the Hopf dual of the symmetric functions in non-commuting variables. - OUTPUT: - - - a list of categories + OUTPUT: list of categories TESTS:: @@ -795,9 +767,7 @@ def product_on_basis(self, A, B): - ``A``, ``B`` -- set partitions - OUTPUT: - - - an element in the basis ``self`` + OUTPUT: an element in the basis ``self`` EXAMPLES:: @@ -858,9 +828,7 @@ def super_categories(self): Return the super categories of bases of the Hopf dual of the symmetric functions in non-commuting variables. - OUTPUT: - - - a list of categories + OUTPUT: list of categories TESTS:: diff --git a/src/sage/combinat/ncsym/dual.py b/src/sage/combinat/ncsym/dual.py index 38ae7135882..520bf5b2d0e 100644 --- a/src/sage/combinat/ncsym/dual.py +++ b/src/sage/combinat/ncsym/dual.py @@ -13,22 +13,20 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.misc.lazy_attribute import lazy_attribute -from sage.misc.misc_c import prod -from sage.structure.parent import Parent -from sage.structure.unique_representation import UniqueRepresentation +from sage.arith.misc import factorial +from sage.categories.fields import Fields from sage.categories.graded_hopf_algebras import GradedHopfAlgebras from sage.categories.rings import Rings -from sage.categories.fields import Fields - -from sage.combinat.ncsym.bases import NCSymDualBases, NCSymBasis_abstract +from sage.combinat.free_module import CombinatorialFreeModule +from sage.combinat.ncsym.bases import NCSymBasis_abstract, NCSymDualBases from sage.combinat.partition import Partition from sage.combinat.set_partition import SetPartitions -from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.subset import Subsets -from sage.arith.misc import factorial -from sage.sets.set import Set +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.misc_c import prod +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation class SymmetricFunctionsNonCommutingVariablesDual(UniqueRepresentation, Parent): @@ -86,7 +84,7 @@ def a_realization(self): """ return self.w() - _shorthands = tuple(['w']) + _shorthands = ('w',) def dual(self): r""" @@ -166,9 +164,8 @@ def dual_basis(self): The dual basis to the `\mathbf{w}` basis is the monomial basis of the symmetric functions in non-commuting variables. - OUTPUT: - - - the monomial basis of the symmetric functions in non-commuting variables + OUTPUT: the monomial basis of the symmetric functions in + non-commuting variables EXAMPLES:: @@ -200,9 +197,7 @@ def product_on_basis(self, A, B): - ``A``, ``B`` -- set partitions - OUTPUT: - - - an element of the `\mathbf{w}` basis + OUTPUT: an element of the `\mathbf{w}` basis EXAMPLES:: @@ -228,24 +223,25 @@ def product_on_basis(self, A, B): sage: w.product_on_basis(A, SetPartition([])) w{{1}, {2, 3}} """ - if len(A) == 0: + if not A: return self.monomial(B) - if len(B) == 0: + if not B: return self.monomial(A) P = SetPartitions() n = A.size() - k = B.size() + m = n + B.size() def unions(s): a = sorted(s) - b = sorted(Set(range(1, n+k+1)).difference(s)) + b = [j for j in range(1, m + 1) if j not in s] # -1 for indexing - ret = [[a[i-1] for i in sorted(part)] for part in A] - ret += [[b[i-1] for i in sorted(part)] for part in B] + ret = [[a[i - 1] for i in sorted(part)] for part in A] + ret.extend([b[i - 1] for i in sorted(part)] for part in B) return P(ret) + return self.sum_of_terms([(unions(s), 1) - for s in Subsets(n+k, n)]) + for s in Subsets(m, n)]) def coproduct_on_basis(self, A): r""" @@ -258,7 +254,7 @@ def coproduct_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition OUTPUT: @@ -277,9 +273,9 @@ def coproduct_on_basis(self, A): """ n = A.size() return self.tensor_square().sum_of_terms([ - (( A.restriction(range(1, i+1)).standardization(), - A.restriction(range(i+1, n+1)).standardization() ), 1) - for i in range(n+1)], distinct=True) + ((A.restriction(range(1, i + 1)).standardization(), + A.restriction(range(i + 1, n + 1)).standardization()), 1) + for i in range(n + 1)], distinct=True) def antipode_on_basis(self, A): r""" @@ -287,11 +283,9 @@ def antipode_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - an element in the basis ``self`` + OUTPUT: an element in the basis ``self`` EXAMPLES:: @@ -307,8 +301,8 @@ def antipode_on_basis(self, A): if A.size() == 1: return -self(A) cpr = self.coproduct_on_basis(A) - return -sum( c*self.monomial(B1)*self.antipode_on_basis(B2) - for ((B1,B2),c) in cpr if B2 != A ) + return -sum(c * self.monomial(B1) * self.antipode_on_basis(B2) + for (B1, B2), c in cpr if B2 != A) def duality_pairing(self, x, y): r""" @@ -322,9 +316,7 @@ def duality_pairing(self, x, y): - ``y`` -- an element of the symmetric functions in non-commuting variables - OUTPUT: - - - an element of the base ring of ``self`` + OUTPUT: an element of the base ring of ``self`` EXAMPLES:: @@ -351,7 +343,7 @@ def duality_pairing(self, x, y): """ x = self(x) y = self.dual_basis()(y) - return sum(coeff * y[I] for (I, coeff) in x) + return sum(coeff * y[I] for I, coeff in x) def sum_of_partitions(self, la): r""" @@ -361,11 +353,9 @@ def sum_of_partitions(self, la): INPUT: - - ``la`` -- an integer partition - - OUTPUT: + - ``la`` -- integer partition - - an element of ``self`` + OUTPUT: an element of ``self`` EXAMPLES:: @@ -394,7 +384,7 @@ def _set_par_to_par(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition EXAMPLES:: @@ -422,7 +412,7 @@ def _set_par_to_par(self, A): cur = 1 prev_len = 0 for p in A: - if prev_len > len(p) or list(p) != list(range(cur, cur+len(p))): + if prev_len > len(p) or list(p) != list(range(cur, cur + len(p))): return None prev_len = len(p) cur += len(p) @@ -444,8 +434,8 @@ def expand(self, n, letter='x'): INPUT: - - ``n`` -- an integer - - ``letter`` -- (default: ``'x'``) a string + - ``n`` -- integer + - ``letter`` -- string (default: ``'x'``) OUTPUT: @@ -470,16 +460,21 @@ def expand(self, n, letter='x'): sage: w[[1,3],[2]].expand(3, letter='y') y02*y11*y20 """ - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.combinat.permutation import Permutations + from sage.rings.polynomial.polynomial_ring_constructor import ( + PolynomialRing, + ) m = self.parent() - names = ['{}{}{}'.format(letter, i, j) for i in range(n) for j in range(n)] - R = PolynomialRing(m.base_ring(), n*n, names) - x = [[R.gens()[i*n+j] for j in range(n)] for i in range(n)] - I = R.ideal([x[i][j]*x[i][k] for j in range(n) for k in range(n) for i in range(n)]) + names = [f'{letter}{i}{j}' for i in range(n) for j in range(n)] + R = PolynomialRing(m.base_ring(), n * n, names) + x = [[R.gens()[i * n + j] + for j in range(n)] for i in range(n)] + I = R.ideal([x[i][j] * x[i][k] + for j in range(n) for k in range(n) for i in range(n)]) Q = R.quotient(I, names) - x = [[Q.gens()[i*n+j] for j in range(n)] for i in range(n)] + x = [[Q.gens()[i * n + j] + for j in range(n)] for i in range(n)] P = SetPartitions() def on_basis(A): @@ -491,7 +486,8 @@ def on_basis(A): for p in Permutations(k): if P(p.to_cycles()) == A: # -1 for indexing - ret += R.sum(prod(x[I[i]][I[p[i]-1]] for i in range(k)) + ret += R.sum(prod(x[I[i]][I[p[i] - 1]] + for i in range(k)) for I in Subsets(range(n), k)) return ret @@ -592,5 +588,5 @@ def to_symmetric_function(self): raise ValueError("not a symmetric function") h = SymmetricFunctions(self.parent().base_ring()).homogeneous() d = {A.shape(): c for A, c in self} - return h.sum_of_terms([( AA, cc / prod([factorial(i) for i in AA.to_exp()]) ) - for AA, cc in d.items()], distinct=True) + return h.sum_of_terms([(AA, cc / prod(factorial(i) for i in AA.to_exp())) + for AA, cc in d.items()], distinct=True) diff --git a/src/sage/combinat/ncsym/ncsym.py b/src/sage/combinat/ncsym/ncsym.py index 8ebc0b899bd..1bcbb7cf1e3 100644 --- a/src/sage/combinat/ncsym/ncsym.py +++ b/src/sage/combinat/ncsym/ncsym.py @@ -322,9 +322,7 @@ def a_realization(self): r""" Return the realization of the powersum basis of ``self``. - OUTPUT: - - - The powersum basis of symmetric functions in non-commuting variables. + OUTPUT: the powersum basis of symmetric functions in non-commuting variables EXAMPLES:: @@ -386,11 +384,9 @@ def _m_to_p_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the powersum basis + OUTPUT: an element of the powersum basis TESTS:: @@ -420,11 +416,9 @@ def _m_to_cp_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the `\mathbf{cp}` basis + OUTPUT: an element of the `\mathbf{cp}` basis TESTS:: @@ -457,9 +451,7 @@ def from_symmetric_function(self, f): - ``f`` -- an element of the symmetric functions - OUTPUT: - - - An element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis EXAMPLES:: @@ -500,9 +492,7 @@ def dual_basis(self): r""" Return the dual basis to the monomial basis. - OUTPUT: - - - the `\mathbf{w}` basis of the dual Hopf algebra + OUTPUT: the `\mathbf{w}` basis of the dual Hopf algebra EXAMPLES:: @@ -524,9 +514,7 @@ def duality_pairing(self, x, y): - ``y`` -- an element of the dual of symmetric functions in non-commuting variables - OUTPUT: - - - an element of the base ring of ``self`` + OUTPUT: an element of the base ring of ``self`` EXAMPLES:: @@ -564,9 +552,7 @@ def product_on_basis(self, A, B): - ``A``, ``B`` -- set partitions - OUTPUT: - - - an element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis EXAMPLES:: @@ -621,7 +607,7 @@ def coproduct_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition OUTPUT: @@ -695,11 +681,9 @@ def internal_coproduct_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - an element of the tensor square of the `\mathbf{m}` basis + OUTPUT: an element of the tensor square of the `\mathbf{m}` basis EXAMPLES:: @@ -746,11 +730,9 @@ def sum_of_partitions(self, la): INPUT: - - ``la`` -- an integer partition - - OUTPUT: + - ``la`` -- integer partition - - an element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis EXAMPLES:: @@ -789,8 +771,8 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- an integer - - ``alphabet`` -- (default: ``'x'``) a string + - ``n`` -- integer + - ``alphabet`` -- string (default: ``'x'``) OUTPUT: @@ -845,9 +827,7 @@ def to_symmetric_function(self): taking the sizes of the parts and `n_i(\mu)` is the multiplicity of `i` in `\mu`. - OUTPUT: - - - an element of the symmetric functions in the monomial basis + OUTPUT: an element of the symmetric functions in the monomial basis EXAMPLES:: @@ -894,15 +874,15 @@ def __init__(self, NCSym): # get the coercion path m -> p -> e p = NCSym.p() self.module_morphism(self._e_to_p_on_basis, codomain=p, - triangular="upper").register_as_coercion() + triangular='upper').register_as_coercion() p.module_morphism(p._p_to_e_on_basis, codomain=self, - triangular="upper").register_as_coercion() + triangular='upper').register_as_coercion() # homogeneous h = NCSym.h() self.module_morphism(self._e_to_h_on_basis, codomain=h, - triangular="upper").register_as_coercion() + triangular='upper').register_as_coercion() h.module_morphism(h._h_to_e_on_basis, codomain=self, - triangular="upper").register_as_coercion() + triangular='upper').register_as_coercion() @cached_method def _e_to_m_on_basis(self, A): @@ -911,11 +891,9 @@ def _e_to_m_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - An element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis TESTS:: @@ -940,11 +918,9 @@ def _e_to_h_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - An element of the `\mathbf{h}` basis + OUTPUT: an element of the `\mathbf{h}` basis TESTS:: @@ -968,11 +944,9 @@ def _e_to_p_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the `\mathbf{p}` basis + OUTPUT: an element of the `\mathbf{p}` basis TESTS:: @@ -1000,9 +974,7 @@ def omega(self): The involution `\omega` on `NCSym` is defined by `\omega(\mathbf{e}_A) = \mathbf{h}_A`. - OUTPUT: - - - an element in the basis ``self`` + OUTPUT: an element in the basis ``self`` EXAMPLES:: @@ -1038,9 +1010,7 @@ def to_symmetric_function(self): where `\lambda(A)` is the partition associated with `A` by taking the sizes of the parts. - OUTPUT: - - - An element of the symmetric functions in the elementary basis + OUTPUT: an element of the symmetric functions in the elementary basis EXAMPLES:: @@ -1096,11 +1066,9 @@ def _h_to_m_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis TESTS:: @@ -1124,11 +1092,9 @@ def _h_to_e_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the `\mathbf{e}` basis + OUTPUT: an element of the `\mathbf{e}` basis TESTS:: @@ -1153,11 +1119,9 @@ def _h_to_p_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - An element of the `\mathbf{p}` basis + OUTPUT: an element of the `\mathbf{p}` basis TESTS:: @@ -1185,9 +1149,7 @@ def omega(self): The involution `\omega` on `NCSym` is defined by `\omega(\mathbf{h}_A) = \mathbf{e}_A`. - OUTPUT: - - - an element in the basis ``self`` + OUTPUT: an element in the basis ``self`` EXAMPLES:: @@ -1223,9 +1185,7 @@ def to_symmetric_function(self): where `\lambda(A)` is the partition associated with `A` by taking the sizes of the parts. - OUTPUT: - - - An element of the symmetric functions in the complete basis + OUTPUT: an element of the symmetric functions in the complete basis EXAMPLES:: @@ -1283,14 +1243,14 @@ def __init__(self, NCSym): # Register coercions m = NCSym.m() self.module_morphism(self._p_to_m_on_basis, codomain=m, - unitriangular="lower").register_as_coercion() + unitriangular='lower').register_as_coercion() m.module_morphism(m._m_to_p_on_basis, codomain=self, - unitriangular="lower").register_as_coercion() + unitriangular='lower').register_as_coercion() x = NCSym.x() self.module_morphism(self._p_to_x_on_basis, codomain=x, - unitriangular="upper").register_as_coercion() + unitriangular='upper').register_as_coercion() x.module_morphism(x._x_to_p_on_basis, codomain=self, - unitriangular="upper").register_as_coercion() + unitriangular='upper').register_as_coercion() @cached_method def _p_to_m_on_basis(self, A): @@ -1299,11 +1259,9 @@ def _p_to_m_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - An element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis TESTS:: @@ -1324,11 +1282,9 @@ def _p_to_e_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the `\mathbf{e}` basis + OUTPUT: an element of the `\mathbf{e}` basis TESTS:: @@ -1352,11 +1308,9 @@ def _p_to_h_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - An element of the `\mathbf{h}` basis + OUTPUT: an element of the `\mathbf{h}` basis TESTS:: @@ -1380,11 +1334,9 @@ def _p_to_x_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - An element of the `\mathbf{x}` basis + OUTPUT: an element of the `\mathbf{x}` basis TESTS:: @@ -1405,7 +1357,7 @@ def coproduct_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition OUTPUT: @@ -1469,11 +1421,9 @@ def internal_coproduct_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - an element of the tensor square of ``self`` + OUTPUT: an element of the tensor square of ``self`` EXAMPLES:: @@ -1507,11 +1457,9 @@ def antipode_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - an element in the basis ``self`` + OUTPUT: an element in the basis ``self`` EXAMPLES:: @@ -1571,13 +1519,11 @@ def primitive(self, A, i=1): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - ``i`` -- (default: 1) index in the base set for ``A`` specifying which set of primitives this belongs to - OUTPUT: - - - an element in the basis ``self`` + OUTPUT: an element in the basis ``self`` EXAMPLES:: @@ -1621,9 +1567,7 @@ def to_symmetric_function(self): where `\lambda(A)` is the partition associated with `A` by taking the sizes of the parts. - OUTPUT: - - - an element of symmetric functions in the power sum basis + OUTPUT: an element of symmetric functions in the power sum basis EXAMPLES:: @@ -1696,9 +1640,9 @@ def __init__(self, NCSym): # Register coercions m = NCSym.m() self.module_morphism(self._cp_to_m_on_basis, codomain=m, - unitriangular="lower").register_as_coercion() + unitriangular='lower').register_as_coercion() m.module_morphism(m._m_to_cp_on_basis, codomain=self, - unitriangular="lower").register_as_coercion() + unitriangular='lower').register_as_coercion() @cached_method def _cp_to_m_on_basis(self, A): @@ -1707,11 +1651,9 @@ def _cp_to_m_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - an element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis TESTS:: @@ -1776,11 +1718,9 @@ def _x_to_p_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - an element of the `\mathbf{p}` basis + OUTPUT: an element of the `\mathbf{p}` basis TESTS:: @@ -1904,11 +1844,9 @@ def _rho_to_m_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - an element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis TESTS:: @@ -1933,11 +1871,9 @@ def _m_to_rho_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - an element of the `\rho` basis + OUTPUT: an element of the `\rho` basis TESTS:: @@ -2050,11 +1986,9 @@ def _chi_to_m_on_basis(self, A): INPUT: - - ``A`` -- a set partition + - ``A`` -- set partition - OUTPUT: - - - an element of the `\mathbf{m}` basis + OUTPUT: an element of the `\mathbf{m}` basis TESTS:: @@ -2117,11 +2051,9 @@ def _m_to_chi_on_basis(self, A): INPUT: - - ``A`` -- a set partition - - OUTPUT: + - ``A`` -- set partition - - an element of the `\chi` basis + OUTPUT: an element of the `\chi` basis TESTS:: diff --git a/src/sage/combinat/necklace.py b/src/sage/combinat/necklace.py index 9cfbe719cdc..3ac4bccf5e2 100644 --- a/src/sage/combinat/necklace.py +++ b/src/sage/combinat/necklace.py @@ -47,7 +47,7 @@ def Necklaces(content): INPUT: - - ``content`` -- a list or tuple of non-negative integers + - ``content`` -- list or tuple of nonnegative integers EXAMPLES:: @@ -75,7 +75,7 @@ class Necklaces_evaluation(UniqueRepresentation, Parent): INPUT: - - ``content`` -- a list or tuple of non-negative integers + - ``content`` -- list or tuple of nonnegative integers """ @staticmethod def __classcall_private__(cls, content): @@ -134,7 +134,7 @@ def __contains__(self, x) -> bool: INPUT: - - ``x`` -- a list of integers + - ``x`` -- list of integers EXAMPLES:: @@ -456,12 +456,12 @@ def _sfc(content, equality=False): INPUT: - - ``content`` -- a list of non-negative integers with no leading 0s + - ``content`` -- list of nonnegative integers with no leading 0s - ``equality`` -- boolean (default: ``True``) .. WARNING:: - You will get incorrect results if there are leading 0's in ``content``. + You will get incorrect results if there are leading 0s in ``content``. See :issue:`12997` and :issue:`17436`. EXAMPLES:: diff --git a/src/sage/combinat/non_decreasing_parking_function.py b/src/sage/combinat/non_decreasing_parking_function.py index 532b4bf8762..dc6bf59e3e2 100644 --- a/src/sage/combinat/non_decreasing_parking_function.py +++ b/src/sage/combinat/non_decreasing_parking_function.py @@ -189,11 +189,11 @@ def __init__(self, lst): def __getitem__(self, n): """ - Return the `n^{th}` item in the underlying list. + Return the `n`-th item in the underlying list. - .. note:: + .. NOTE:: - Note that this is different than the image of ``n`` under + Note that this is different than the image of `n` under function. It is "off by one". EXAMPLES:: @@ -410,7 +410,7 @@ def __contains__(self, x) -> bool: def __iter__(self): """ - An iterator + An iterator. TESTS:: @@ -478,7 +478,7 @@ def __init__(self, n): """ n = Integer(n) if n < 0: - raise ValueError('%s is not a non-negative integer' % n) + raise ValueError('%s is not a nonnegative integer' % n) self.n = n Parent.__init__(self, category=Monoids().Enumerated().Finite()) diff --git a/src/sage/combinat/nu_dyck_word.py b/src/sage/combinat/nu_dyck_word.py index c52e07b8469..26f54ea8900 100644 --- a/src/sage/combinat/nu_dyck_word.py +++ b/src/sage/combinat/nu_dyck_word.py @@ -93,7 +93,7 @@ def replace_dyck_char(x): - If ``x`` is a closing character, replace ``x`` with the constant ``ndw_close_symbol``. - - Raise a :class:`ValueError` if ``x`` is neither an opening nor a + - Raise a :exc:`ValueError` if ``x`` is neither an opening nor a closing character. .. SEEALSO:: :func:`replace_dyck_symbol` @@ -128,20 +128,18 @@ def replace_dyck_symbol(x, open_char='N', close_char='E') -> str: INPUT: - - ``x`` -- either ``ndw_open_symbol`` or ``ndw_close_symbol``. + - ``x`` -- either ``ndw_open_symbol`` or ``ndw_close_symbol`` - - ``open_char`` -- str (optional) default ``'N'`` + - ``open_char`` -- string (optional) default ``'N'`` - - ``close_char`` -- str (optional) default ``'E'`` + - ``close_char`` -- string (optional) default ``'E'`` - OUTPUT: - - - If ``x`` is ``ndw_open_symbol``, replace ``x`` with ``open_char``. + OUTPUT: if ``x`` is ``ndw_open_symbol``, replace ``x`` with ``open_char`` - If ``x`` is ``ndw_close_symbol``, replace ``x`` with ``close_char``. - If ``x`` is neither ``ndw_open_symbol`` nor ``ndw_close_symbol``, a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. .. SEEALSO:: :func:`replace_dyck_char` @@ -178,9 +176,9 @@ class NuDyckWord(CombinatorialElement): INPUT: - - k1 -- A path for the `\nu`-Dyck word + - ``k1`` -- a path for the `\nu`-Dyck word - - k2 -- A path for `\nu` + - ``k2`` -- a path for `\nu` EXAMPLES:: @@ -324,7 +322,6 @@ def __le__(self, other): True sage: ND3 <= ND1 True - """ if self._nu == other._nu: return path_weakly_above_other(other._path, self._path) @@ -332,7 +329,7 @@ def __le__(self, other): def __lt__(self, other): """ - Return if one path is strictly included in another + Return if one path is strictly included in another. EXAMPLES:: @@ -354,7 +351,7 @@ def __lt__(self, other): def __ge__(self, other): """ - Return if one path is included in another + Return if one path is included in another. EXAMPLES:: @@ -378,7 +375,7 @@ def __ge__(self, other): def __gt__(self, other): """ - Return if one path is strictly included in another + Return if one path is strictly included in another. EXAMPLES:: @@ -428,32 +425,32 @@ def set_latex_options(self, D): The default values are set in the ``__init__`` function. - - ``color`` -- (default: black) the line color. + - ``color`` -- (default: black) the line color - ``line width`` -- (default: `2 \times` ``tikz_scale``) value - representing the line width. + representing the line width - ``nu_options`` -- (default: ``'rounded corners=1, color=red, line - width=1'``) str to indicate what the tikz options should be for path - of `\nu`. + width=1'``) string to indicate what the tikz options should be for + path of `\nu` - ``points_color`` -- (default: ``'black'``) str to indicate color - points should be drawn with. + points should be drawn with - - ``show_grid`` -- (default: ``True``) boolean value to indicate if - grid should be shown. + - ``show_grid`` -- boolean (default: ``True``); value to indicate if + grid should be shown - - ``show_nu`` -- (default: ``True``) boolean value to indicate if `\nu` - should be shown. + - ``show_nu`` -- boolean (default: ``True``); value to indicate if `\nu` + should be shown - - ``show_points`` -- (default: ``False``) boolean value to indicate - if points should be shown on path. + - ``show_points`` -- boolean (default: ``False``); value to indicate + if points should be shown on path - - ``tikz_scale`` -- (default: 1) scale for use with the tikz package. + - ``tikz_scale`` -- (default: 1) scale for use with the tikz package INPUT: - - ``D`` -- a dictionary with a list of latex parameters to change + - ``D`` -- dictionary with a list of latex parameters to change EXAMPLES:: @@ -475,28 +472,28 @@ def latex_options(self) -> dict: The default values are set using the options. - - ``color`` -- (default: black) the line color. + - ``color`` -- (default: black) the line color - ``line width`` -- (default: 2*``tikz_scale``) value representing the - line width. + line width - ``nu_options`` -- (default: ``'rounded corners=1, color=red, line - width=1'``) str to indicate what the tikz options should be for path - of `\nu`. + width=1'``) string to indicate what the tikz options should be for + path of `\nu` - ``points_color`` -- (default: ``'black'``) str to indicate color - points should be drawn with. + points should be drawn with - - ``show_grid`` -- (default: ``True``) boolean value to indicate if - grid should be shown. + - ``show_grid`` -- boolean (default: ``True``); value to indicate if + grid should be shown - - ``show_nu`` -- (default: ``True``) boolean value to indicate if `\nu` - should be shown. + - ``show_nu`` -- boolean (default: ``True``); value to indicate if `\nu` + should be shown - - ``show_points`` -- (default: ``False``) boolean value to indicate - if points should be shown on path. + - ``show_points`` -- boolean (default: ``False``); value to indicate + if points should be shown on path - - ``tikz_scale`` -- (default: 1) scale for use with the tikz package. + - ``tikz_scale`` -- (default: 1) scale for use with the tikz package EXAMPLES:: @@ -668,7 +665,6 @@ def _ascii_art_(self): ___| . . . . . | . . . . . . . ______| . . . . . . . - """ from sage.typeset.ascii_art import AsciiArt rep = self.parent().options.ascii_art @@ -708,10 +704,10 @@ def pretty_print(self, style=None, labelling=None): - "N-E" to show ``self`` as a path of north and east steps, or - ``labelling`` -- (if style is "N-E") a list of labels assigned to - the up steps in ``self``. + the up steps in ``self`` - - ``underpath`` -- (if style is "N-E", default: ``True``) If ``True``, - an ``x`` to show the boxes between `\nu` and the `\nu`-Dyck Path. + - ``underpath`` -- (if style is "N-E", default: ``True``) if ``True``, + an ``x`` to show the boxes between `\nu` and the `\nu`-Dyck Path EXAMPLES:: @@ -1050,9 +1046,7 @@ def can_mutate(self, i) -> bool | int: Can only mutate if an east step is followed by a north step at height `i`. - OUTPUT: - - Whether we can mutate at height of `i`. + OUTPUT: whether we can mutate at height of `i` EXAMPLES:: @@ -1142,7 +1136,7 @@ class NuDyckWords(Parent): INPUT: - - ``nu`` -- the base lattice path. + - ``nu`` -- the base lattice path EXAMPLES:: @@ -1404,9 +1398,7 @@ def to_word_path(word): - ``word`` -- word to convert to wordpath - OUTPUT: - - - A ``FiniteWordPath_north_east`` object. + OUTPUT: a ``FiniteWordPath_north_east`` object EXAMPLES:: @@ -1449,13 +1441,11 @@ def path_weakly_above_other(path, other) -> bool: INPUT: - - ``path`` -- The path to verify is weakly above the other path. + - ``path`` -- the path to verify is weakly above the other path - - ``other`` -- The other path to verify is weakly below the path. - - OUTPUT: + - ``other`` -- the other path to verify is weakly below the path - bool + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/combinat/nu_tamari_lattice.py b/src/sage/combinat/nu_tamari_lattice.py index 036de27126d..7a7a9ef3d78 100644 --- a/src/sage/combinat/nu_tamari_lattice.py +++ b/src/sage/combinat/nu_tamari_lattice.py @@ -76,11 +76,9 @@ def NuTamariLattice(nu): INPUT: - - `\nu` -- a list of 0s and 1s or a string of 0s and 1s. + - `\nu` -- list of 0s and 1s or a string of 0s and 1s - OUTPUT: - - a finite lattice + OUTPUT: a finite lattice The elements of the lattice are :func:`\nu-Dyck paths` weakly above @@ -133,13 +131,11 @@ def delta_swap(p, k, delta): - ``p`` -- a `\nu`-Dyck word - - ``k`` -- an integer between `0` and ``p.length()-1`` - - - ``delta`` -- a list of nonnegative integers of length ``p.height()`` + - ``k`` -- integer between `0` and ``p.length()-1`` - OUTPUT: + - ``delta`` -- list of nonnegative integers of length ``p.height()`` - - a `\nu`-Dyck word + OUTPUT: a `\nu`-Dyck word EXAMPLES:: @@ -209,13 +205,11 @@ def AltNuTamariLattice(nu, delta=None): INPUT: - - `\nu` -- a list of 0s and 1s or a string of 0s and 1s. - - - `\delta` -- a list of nonnegative integers. + - `\nu` -- list of 0s and 1s or a string of 0s and 1s - OUTPUT: + - `\delta` -- list of nonnegative integers - - a finite lattice + OUTPUT: a finite lattice EXAMPLES:: diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index 17e391450c2..492a0b72956 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -277,7 +277,7 @@ def is_empty(self): """ return False - def _to_binary_tree_rec(self, bijection="left"): + def _to_binary_tree_rec(self, bijection='left'): r""" Internal recursive method to obtain a binary tree from an ordered tree. @@ -290,12 +290,12 @@ def _to_binary_tree_rec(self, bijection="left"): sage: T = OrderedTree([[],[]]) sage: T._to_binary_tree_rec() [[., .], .] - sage: T._to_binary_tree_rec(bijection="right") + sage: T._to_binary_tree_rec(bijection='right') [., [., .]] sage: T = OrderedTree([[], [[], []], [[], [[]]]]) sage: T._to_binary_tree_rec() [[[., .], [[., .], .]], [[., .], [., .]]] - sage: T._to_binary_tree_rec(bijection="right") + sage: T._to_binary_tree_rec(bijection='right') [., [[., [., .]], [[., [[., .], .]], .]]] """ from sage.combinat.binary_tree import BinaryTree @@ -493,7 +493,7 @@ def to_binary_tree_right_branch(self): sage: T == T.to_binary_tree_right_branch().to_ordered_tree_right_branch() True """ - return self._to_binary_tree_rec(bijection="right") + return self._to_binary_tree_rec(bijection='right') @combinatorial_map(name="To Dyck path") def to_dyck_word(self): @@ -591,8 +591,8 @@ def to_poset(self, root_to_leaf=False): INPUT: - - ``root_to_leaf`` -- boolean, true if the poset orientation should - be from root to leaves. It is false by default. + - ``root_to_leaf`` -- boolean (default: ``False``); ``True`` if the + poset orientation should be from root to leaves EXAMPLES:: @@ -709,8 +709,7 @@ def plot(self): except AttributeError: root = 1 g = self.canonical_labelling().to_undirected_graph() - return g.plot(layout='tree', tree_root=root, - tree_orientation="down") + return g.plot(layout='tree', tree_root=root, tree_orientation='down') def sort_key(self): """ @@ -775,7 +774,7 @@ def normalize(self, inplace=False): INPUT: - - ``inplace`` -- boolean, (default ``False``) if ``True``, + - ``inplace`` -- boolean (default: ``False``); if ``True``, then ``self`` is modified and nothing returned. Otherwise the normalized tree is returned. @@ -835,11 +834,11 @@ def normalize(self, inplace=False): # Abstract class to serve as a Factory no instance are created. class OrderedTrees(UniqueRepresentation, Parent): """ - Factory for ordered trees + Factory for ordered trees. INPUT: - - ``size`` -- (optional) an integer + - ``size`` -- integer (optional) OUTPUT: @@ -881,13 +880,13 @@ def __classcall_private__(cls, n=None): return OrderedTrees_all() else: if not (isinstance(n, (Integer, int)) and n >= 0): - raise ValueError("n must be a non negative integer") + raise ValueError("n must be a nonnegative integer") return OrderedTrees_size(Integer(n)) @cached_method def leaf(self): """ - Return a leaf tree with ``self`` as parent + Return a leaf tree with ``self`` as parent. EXAMPLES:: @@ -963,7 +962,7 @@ def __contains__(self, x): def unlabelled_trees(self): """ - Return the set of unlabelled trees associated to ``self`` + Return the set of unlabelled trees associated to ``self``. EXAMPLES:: @@ -974,7 +973,7 @@ def unlabelled_trees(self): def labelled_trees(self): """ - Return the set of labelled trees associated to ``self`` + Return the set of labelled trees associated to ``self``. EXAMPLES:: @@ -1006,7 +1005,7 @@ def _element_constructor_(self, *args, **keywords): class OrderedTrees_size(OrderedTrees): """ - The enumerated sets of binary trees of a given size + The enumerated sets of binary trees of a given size. EXAMPLES:: @@ -1063,7 +1062,7 @@ def _an_element_(self): def cardinality(self): """ - The cardinality of ``self`` + The cardinality of ``self``. This is a Catalan number. @@ -1112,7 +1111,7 @@ def random_element(self): def __iter__(self): """ - A basic generator + A basic generator. .. TODO:: could be optimized. @@ -1138,7 +1137,7 @@ def __iter__(self): @lazy_attribute def _parent_for(self): """ - Return the parent of the element generated by ``self`` + Return the parent of the element generated by ``self``. TESTS:: @@ -1150,7 +1149,7 @@ def _parent_for(self): @lazy_attribute def element_class(self): """ - The class of the element of ``self`` + The class of the element of ``self``. EXAMPLES:: @@ -1192,7 +1191,7 @@ class LabelledOrderedTree(AbstractLabelledClonableTree, OrderedTree): INPUT: - - ``children`` -- a list or tuple or more generally any iterable + - ``children`` -- list or tuple or more generally any iterable of trees or object convertible to trees - ``label`` -- any Sage object (default: ``None``) @@ -1398,7 +1397,7 @@ def _an_element_(self): t = LT([], label=3) t1 = LT([t, t], label=42) t2 = LT([[]], label=5) - return LT([t, t1, t2], label="toto") + return LT([t, t1, t2], label='toto') def _element_constructor_(self, *args, **keywords): """ diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 7f223921d7e..1e2725448f9 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -24,13 +24,14 @@ def tex_from_array(array, with_lines=True): r""" - Return a latex string for a two dimensional array of partition, composition or skew composition shape + Return a latex string for a two dimensional array of partition, composition + or skew composition shape. INPUT: - - ``array`` -- a list of list - - ``with_lines`` -- a boolean (default: ``True``) - Whether to draw a line to separate the entries in the array. + - ``array`` -- list of list + - ``with_lines`` -- boolean (default: ``True``); whether to draw a line to + separate the entries in the array Empty rows are allowed; however, such rows should be given as ``[None]`` rather than ``[]``. @@ -248,9 +249,9 @@ def tex_from_array_tuple(a_tuple, with_lines=True): INPUT: - - ``a_tuple`` -- a tuple of lists of lists - - ``with_lines`` -- a boolean (default: ``True``) - Whether to draw lines to separate the entries in the components of ``a_tuple``. + - ``a_tuple`` -- tuple of lists of lists + - ``with_lines`` -- boolean (default: ``True``); whether to draw lines to + separate the entries in the components of ``a_tuple`` .. SEEALSO:: :meth:`tex_from_array` for the description of each array @@ -347,12 +348,12 @@ def tex_from_skew_array(array, with_lines=False, align='b'): INPUT: - - ``array`` -- The array + - ``array`` -- the array - - ``with_lines`` -- (Default: ``False``) If ``True`` lines are drawn, if + - ``with_lines`` -- (default: ``False``) if ``True`` lines are drawn, if ``False`` they are not - - ``align`` -- (Default: ``'b'``) Determines the alignment on the latex + - ``align`` -- (default: ``'b'``) determine the alignment on the latex array environments EXAMPLES:: @@ -412,7 +413,7 @@ def end_line(r): return tex+r'\end{array}$'+raisebox_end -def ascii_art_table(data, use_unicode=False, convention="English"): +def ascii_art_table(data, use_unicode=False, convention='English'): r""" Return an ascii art table of ``data``. @@ -772,7 +773,7 @@ def box_exists(tab, i, j): INPUT: - - ``tab`` -- a list of lists + - ``tab`` -- list of lists - ``i`` -- first coordinate - ``j`` -- second coordinate diff --git a/src/sage/combinat/parallelogram_polyomino.py b/src/sage/combinat/parallelogram_polyomino.py index 53d35bca831..ac2e7ea6e4d 100644 --- a/src/sage/combinat/parallelogram_polyomino.py +++ b/src/sage/combinat/parallelogram_polyomino.py @@ -62,7 +62,7 @@ class LocalOptions: INPUT: - - ``name`` -- The name of the LocalOptions + - ``name`` -- the name of the LocalOptions - ``=dict(...)`` -- dictionary specifying an option @@ -73,7 +73,7 @@ class LocalOptions: - ``checker`` -- a function for checking whether a particular value for the option is valid - ``default`` -- the default value of the option - - ``values`` -- a dictionary of the legal values for this option (this + - ``values`` -- dictionary of the legal values for this option (this automatically defines the corresponding ``checker``); this dictionary gives the possible options, as keys, together with a brief description of them @@ -111,7 +111,7 @@ def __init__(self, name='', **options): INPUT: - - ``name`` -- The name of the LocalOptions + - ``name`` -- the name of the LocalOptions - ``=dict(...)`` -- dictionary specifying an option @@ -122,7 +122,7 @@ def __init__(self, name='', **options): - ``checker`` -- a function for checking whether a particular value for the option is valid - ``default`` -- the default value of the option - - ``values`` -- a dictionary of the legal values for this option (this + - ``values`` -- dictionary of the legal values for this option (this automatically defines the corresponding ``checker``); this dictionary gives the possible options, as keys, together with a brief description of them. @@ -135,14 +135,14 @@ def __init__(self, name='', **options): sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -168,14 +168,14 @@ def __repr__(self) -> str: sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -205,9 +205,9 @@ def __setitem__(self, key, value): INPUT: - - ``key`` -- An option. + - ``key`` -- an option - - ``value`` -- The value. + - ``value`` -- the value EXAMPLES:: @@ -217,14 +217,14 @@ def __setitem__(self, key, value): sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -251,7 +251,6 @@ def __setitem__(self, key, value): sage: o("size") 3 sage: o["size"]=-6 - """ assert (key in self._available_options) if value == "?": @@ -274,10 +273,10 @@ def __call__(self, *get_values, **options): INPUT: - - ``get_values`` -- The options to be printed. + - ``get_values`` -- the options to be printed - ``=dict(...)`` -- dictionary specifying an option see - :class:`LocalOptions` for more details. + :class:`LocalOptions` for more details EXAMPLES:: @@ -287,14 +286,14 @@ def __call__(self, *get_values, **options): sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -303,15 +302,14 @@ def __call__(self, *get_values, **options): ....: ) sage: o("display") 'list' - sage: o(display="diagram") + sage: o(display='diagram') sage: o("display") 'diagram' - sage: o(display="?") + sage: o(display='?') Current value : diagram {'default': 'list', 'values': {'diagram': 'diagram representation', 'list': 'list representation'}} - """ for key in options: value = options[key] @@ -325,7 +323,7 @@ def __getitem__(self, key): INPUT: - - ``key`` -- An option. + - ``key`` -- an option EXAMPLES:: @@ -335,14 +333,14 @@ def __getitem__(self, key): sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -366,14 +364,14 @@ def __iter__(self): sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -397,14 +395,14 @@ def keys(self) -> list[str]: sage: o = LocalOptions( ....: "Name Example", ....: tikz_options=dict( - ....: default="toto", + ....: default='toto', ....: values=dict( - ....: toto="name", + ....: toto='name', ....: x="3" ....: ) ....: ), ....: display=dict( - ....: default="list", + ....: default='list', ....: values=dict( ....: list="list representation", ....: diagram="diagram representation" @@ -497,14 +495,14 @@ def _dispatch(self, obj, dispatch_to, option, *get_values, **set_values): ) ), display=dict( - default="list", + default='list', values=dict( list='displayed as list', drawing='as a drawing', ) ), latex=dict( - default="drawing", + default='drawing', values=dict( list='displayed as list', drawing='as a drawing', @@ -595,7 +593,6 @@ class _drawing_tool: sage: dt.draw_line([1, 1], [-1, -1]) '\n \\draw[color=black, line width=1] (-1.000000, 1.000000) -- (1.000000, -1.000000);' - """ def __init__(self, options, XY=lambda v: v): @@ -606,8 +603,8 @@ def __init__(self, options, XY=lambda v: v): - ``options`` -- drawing options - - ``XY`` -- A user function to convert vector in other vector. - (default : identity function) + - ``XY`` -- a user function to convert vector in other vector + (default: identity function) EXAMPLES:: @@ -643,11 +640,9 @@ def XY(self, v): INPUT: - - ``v`` -- The vector to transform. + - ``v`` -- the vector to transform - OUTPUT: - - A list of 2 floats encoding a vector. + OUTPUT: list of 2 floats encoding a vector EXAMPLES:: @@ -677,9 +672,9 @@ def translate(pos, v): INPUT: - - ``pos`` -- The position to translate. + - ``pos`` -- the position to translate - - ``v`` -- The translation vector. + - ``v`` -- the translation vector OUTPUT: @@ -693,9 +688,9 @@ def rotate(pos, angle): INPUT: - - ``pos`` -- The position to rotate. + - ``pos`` -- the position to rotate - - ``angle`` -- The angle of rotation. + - ``angle`` -- the angle of rotation OUTPUT: @@ -710,9 +705,9 @@ def mirror(pos, axe): INPUT: - - ``pos`` -- The position to mirror. + - ``pos`` -- the position to mirror - - ``axe`` -- The axe vector. + - ``axe`` -- the axe vector OUTPUT: @@ -747,21 +742,19 @@ def draw_line(self, v1, v2, color=None, size=None): INPUT: - - ``v1`` -- point, The first point of the line. + - ``v1`` -- point, The first point of the line - - ``v2`` -- point, The second point of the line. + - ``v2`` -- point, The second point of the line - - ``color`` -- string (default:``None``), The color of the line. + - ``color`` -- string (default: ``None``); the color of the line. If set to ``None``, the color is chosen according the drawing option given by ``_drawing_tool``. - - ``size`` -- integer (default:``None``), The size of the line. + - ``size`` -- integer (default: ``None``); the size of the line. If set to ``None``, the size is chosen according the drawing option given by ``_drawing_tool``. - OUTPUT: - - The code of a line in TIKZ. + OUTPUT: the code of a line in TIKZ EXAMPLES:: @@ -790,19 +783,17 @@ def draw_polyline(self, list_of_vertices, color=None, size=None): INPUT: - - ``list_of_vertices`` -- A list of points + - ``list_of_vertices`` -- list of points - - ``color`` -- string (default:``None``), The color of the line. + - ``color`` -- string (default: ``None``); the color of the line. If set to ``None``, the color is chosen according the drawing option given by ``_drawing_tool``. - - ``size`` -- integer (default:``None``), The size of the line. + - ``size`` -- integer (default: ``None``); the size of the line. If set to ``None``, the size is chosen according the drawing option given by ``_drawing_tool``. - OUTPUT: - - The code of a polyline in TIKZ. + OUTPUT: the code of a polyline in TIKZ EXAMPLES:: @@ -826,22 +817,19 @@ def draw_point(self, p1, color=None, size=None): r""" Return the TIKZ code for a point. - INPUT: - - ``p1`` -- A point + - ``p1`` -- a point - - ``color`` -- string (default:``None``), The color of the line. + - ``color`` -- string (default: ``None``); the color of the line. If set to ``None``, the color is chosen according the drawing option given by ``_drawing_tool``. - - ``size`` -- integer (default:``None``), The size of the line. + - ``size`` -- integer (default: ``None``); the size of the line. If set to ``None``, the size is chosen according the drawing option given by ``_drawing_tool``. - OUTPUT: - - The code of a point in TIKZ. + OUTPUT: the code of a point in TIKZ EXAMPLES:: @@ -1124,7 +1112,7 @@ def __hash__(self): def __copy__(self): r""" - Copy a parallelogram Polyomino + Copy a parallelogram Polyomino. EXAMPLES:: @@ -1250,7 +1238,6 @@ def _to_dyck_delest_viennot(self): sage: pp = ParallelogramPolyomino([[1], [1]]) sage: pp._to_dyck_delest_viennot() [] - """ from sage.combinat.dyck_word import DyckWord dyck = [] @@ -1306,14 +1293,12 @@ def to_dyck_word(self, bijection=None): INPUT: - - ``bijection`` -- string or ``None`` (default:``None``) The name of + - ``bijection`` -- string or ``None`` (default: ``None``); the name of the bijection. If it is set to ``None`` then the ``'Delest-Viennot'`` bijection is used. Expected values are ``None``, ``'Delest-Viennot'``, or ``'Delest-Viennot-beta'``. - OUTPUT: - - a Dyck word + OUTPUT: a Dyck word EXAMPLES:: @@ -1346,9 +1331,7 @@ def _from_dyck_word_delest_viennot(dyck): - ``dyck`` -- a Dyck word - OUTPUT: - - A parallelogram polyomino. + OUTPUT: a parallelogram polyomino EXAMPLES:: @@ -1384,9 +1367,7 @@ def _from_dyck_word_delest_viennot_peaks_valleys(dyck): - ``dyck`` -- a Dyck word - OUTPUT: - - A parallelogram polyomino. + OUTPUT: a parallelogram polyomino EXAMPLES:: @@ -1436,12 +1417,10 @@ def from_dyck_word(dyck, bijection=None): - ``dyck`` -- a Dyck word - - ``bijection`` -- string or ``None`` (default:``None``) the bijection - to use. See :meth:`to_dyck_word` for more details. + - ``bijection`` -- string or ``None`` (default: ``None``); the + bijection to use. See :meth:`to_dyck_word` for more details. - OUTPUT: - - A parallelogram polyomino. + OUTPUT: a parallelogram polyomino EXAMPLES:: @@ -1472,8 +1451,8 @@ def _to_binary_tree_Aval_Boussicault(self, position=None): INPUT: - - ``position`` -- the cell position. This is a recursive parameter. - It should not be used directly. + - ``position`` -- the cell position; this is a recursive parameter + It should not be used directly EXAMPLES:: @@ -1529,7 +1508,7 @@ def to_binary_tree(self, bijection=None): INPUT: - - ``bijection`` -- string or ``None`` (default:``None``) The name of + - ``bijection`` -- string or ``None`` (default: ``None``); the name of bijection to use for the conversion. The possible values are ``None`` or ``'Aval-Boussicault'``. The ``None`` value is equivalent to ``'Aval-Boussicault'``. @@ -1722,7 +1701,7 @@ def to_ordered_tree(self, bijection=None): INPUT: - - ``bijection`` -- string or ``None`` (default:``None``) The name of + - ``bijection`` -- string or ``None`` (default: ``None``); the name of bijection to use for the conversion. The possible value are ``None``, ``'Boussicault-Socci'`` or ``'via dyck and Delest-Viennot'``. The ``None`` value is equivalent to the ``'Boussicault-Socci'`` @@ -1871,13 +1850,11 @@ def _prefix_lengths(word, up): INPUT: - - ``word`` -- a word of 0 and 1. + - ``word`` -- a word of 0 and 1 - ``up`` -- 0 or 1 (a letter of the word) - OUTPUT: - - A list of integers + OUTPUT: list of integers EXAMPLES:: @@ -1904,9 +1881,7 @@ def upper_heights(self): Return the list of heights associated to each vertical step of the parallelogram polyomino's upper path. - OUTPUT: - - A list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -1924,9 +1899,7 @@ def lower_heights(self): Return the list of heights associated to each vertical step of the parallelogram polyomino's lower path. - OUTPUT: - - A list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -1944,9 +1917,7 @@ def upper_widths(self): Return the list of widths associated to each horizontal step of the parallelogram polyomino's upper path. - OUTPUT: - - A list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -1964,9 +1935,7 @@ def lower_widths(self): Return the list of widths associated to each horizontal step of the parallelogram polyomino's lower path. - OUTPUT: - - A list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -2005,12 +1974,9 @@ def widths(self) -> list: sage: pp.widths() [] """ - widths = [] uw = self.upper_widths() lw = self.lower_widths() - for i in range(len(lw)): - widths.append(uw[i] - lw[i]) - return widths + return [up - lo for up, lo in zip(uw, lw)] def degree_convexity(self) -> int: r""" @@ -2088,7 +2054,7 @@ def is_k_directed(self, k) -> bool: INPUT: - - ``k`` -- A non negative integer. + - ``k`` -- nonnegative integer EXAMPLES:: @@ -2216,9 +2182,9 @@ def cell_is_inside(self, w, h): INPUT: - - ``w`` -- The x coordinate of the box position. + - ``w`` -- the x coordinate of the box position - - ``h`` -- The y coordinate of the box position. + - ``h`` -- the y coordinate of the box position OUTPUT: @@ -2314,7 +2280,7 @@ class _polyomino_row: def __init__(self, polyomino, row): r""" - The constructor of the class + The constructor of the class. EXAMPLES:: @@ -2502,7 +2468,7 @@ def bounce_path(self, direction=1): INPUT: - ``direction`` -- the initial direction of the bounce path (see above - for the definition). + for the definition) EXAMPLES:: @@ -2589,7 +2555,7 @@ def bounce(self, direction=1): INPUT: - ``direction`` -- the initial direction of the bounce path - (see :meth:`bounce_path` for the definition). + (see :meth:`bounce_path` for the definition) EXAMPLES:: @@ -2763,7 +2729,6 @@ def _to_tikz_diagram(self): (3.000000, 2.000000); \draw[color=black, line width=1] (1.000000, 1.000000) -- (3.000000, 1.000000); - """ tikz_options = self.get_tikz_options() grid_width = self.width() + 1 @@ -2984,9 +2949,7 @@ def _get_node_position_at_row(self, row): - ``row`` -- the index of the row - OUTPUT: - - A [row,column] position of the cell. + OUTPUT: a [row,column] position of the cell EXAMPLES:: @@ -3031,9 +2994,7 @@ def _get_node_position_at_column(self, column): - ``column`` -- the index of the column - OUTPUT: - - A [row,column] position of the cell. + OUTPUT: a [row,column] position of the cell EXAMPLES:: @@ -3082,16 +3043,14 @@ def get_node_position_from_box(self, box_position, direction, nb_crossed_nodes=N INPUT: - - ``box_position`` -- the position of the statring cell. + - ``box_position`` -- the position of the starting cell - - ``direction`` -- the direction (0 or 1). + - ``direction`` -- the direction (0 or 1) - ``nb_crossed_nodes`` -- ``[0]`` (default) a list containing just one - integer. + integer - OUTPUT: - - A [row,column] position of the cell. + OUTPUT: a [row,column] position of the cell EXAMPLES:: @@ -3149,7 +3108,7 @@ def get_node_position_from_box(self, box_position, direction, nb_crossed_nodes=N def box_is_node(self, pos) -> bool: r""" - Return True if the box contains a node in the context of the + Return ``True`` if the box contains a node in the context of the Aval-Boussicault bijection between parallelogram polyomino and binary tree. @@ -3158,11 +3117,9 @@ def box_is_node(self, pos) -> bool: INPUT: - - ``pos`` -- the [x,y] coordinate of the box. + - ``pos`` -- the [x,y] coordinate of the box - OUTPUT: - - A boolean + OUTPUT: boolean EXAMPLES:: @@ -3198,7 +3155,7 @@ def box_is_root(self, box) -> bool: INPUT: - - ``box`` -- the x,y coordinate of the cell. + - ``box`` -- the x,y coordinate of the cell EXAMPLES:: @@ -3232,9 +3189,9 @@ def _get_number_of_nodes_in_the_bounding_path(self, box, direction): INPUT: - ``box`` -- the x,y coordinate of the starting point of the bounding - path. + path - ``direction`` -- the initial direction of the bounding path (1 or 0, - 1 for left and 0 for top). + 1 for left and 0 for top) EXAMPLES:: @@ -3314,11 +3271,9 @@ def _get_path_in_pair_of_tree_from_row(self, line): INPUT: - - ``line`` -- the x coordinate of the line. - - OUTPUT: + - ``line`` -- the x coordinate of the line - A list of integers + OUTPUT: list of integers EXAMPLES:: @@ -3349,7 +3304,6 @@ def _get_path_in_pair_of_tree_from_row(self, line): [0] sage: pp._get_path_in_pair_of_tree_from_row(0) [] - """ pos = self._get_node_position_at_row(line) return self._get_number_of_nodes_in_the_bounding_path(pos, 0) @@ -3375,11 +3329,9 @@ def _get_path_in_pair_of_tree_from_column(self, column): INPUT: - - ``column`` -- the y coordinate of the column. - - OUTPUT: + - ``column`` -- the y coordinate of the column - A list of integers + OUTPUT: list of integers EXAMPLES:: @@ -3432,11 +3384,10 @@ def get_BS_nodes(self): sage: pp.set_options(drawing_components=dict(tree=True)) sage: view(pp) # not tested """ - result = [] - for h in range(1, self.height()): - result.append(self._get_node_position_at_row(h)) - for w in range(1, self.width()): - result.append(self._get_node_position_at_column(w)) + result = [self._get_node_position_at_row(h) + for h in range(1, self.height())] + result.extend(self._get_node_position_at_column(w) + for w in range(1, self.width())) return result def get_right_BS_nodes(self): @@ -3496,9 +3447,7 @@ def get_left_BS_nodes(self): the Boussicault-Socci bijection between parallelogram polyominoes and pair of ordered trees. - OUTPUT: - - A list of [row,column] position of cells. + OUTPUT: list of [row,column] position of cells EXAMPLES:: @@ -3696,7 +3645,7 @@ def geometry(self) -> list: def _plot_diagram(self): r""" - Return a plot of the diagram representing ``self`` + Return a plot of the diagram representing ``self``. TESTS:: @@ -3748,7 +3697,7 @@ def _plot_bounce(self, directions=None): INPUT: - - ``directions`` -- direction(s) `0` and/or `1` of the bounce paths. + - ``directions`` -- direction(s) `0` and/or `1` of the bounce paths TESTS:: @@ -3764,7 +3713,6 @@ def _plot_bounce(self, directions=None): ....: ]) sage: pp._plot_bounce(directions=[0,1]) # needs sage.plot Graphics object consisting of 9 graphics primitives - """ if directions is None: directions = [0, 1] @@ -4009,7 +3957,7 @@ def __call__(self, size=None, policy=None): INPUT: - - ``size`` -- integer (default: ``None``), the size of the parallelogram + - ``size`` -- integer (default: ``None``); the size of the parallelogram polyominoes contained in the family. If set to ``None``, the family returned contains all the parallelogram polyominoes. diff --git a/src/sage/combinat/parking_functions.py b/src/sage/combinat/parking_functions.py index fc677e47f90..00ec41337d6 100644 --- a/src/sage/combinat/parking_functions.py +++ b/src/sage/combinat/parking_functions.py @@ -63,7 +63,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from __future__ import annotations -from typing import Iterator +from collections.abc import Iterator from sage.rings.integer import Integer from sage.rings.rational_field import QQ @@ -132,12 +132,10 @@ class ParkingFunction(ClonableArray, metaclass=InheritComparisonClasscallMetacla - ``area_sequence`` -- (default: ``None``) an area sequence of a Dyck path - - ``labelled_dyck_word`` -- (default: ``None``) a Dyck word with 1's + - ``labelled_dyck_word`` -- (default: ``None``) a Dyck word with 1s replaced by labelling - OUTPUT: - - A parking function + OUTPUT: a parking function EXAMPLES:: @@ -364,7 +362,6 @@ def cars_permutation(self) -> Permutation: means that car 2 takes spots 1, car 4 takes spot 2, ..., car 1 takes spot 6 and car 7 takes spot 7. - OUTPUT: - the permutation of cars corresponding to the parking function @@ -403,7 +400,6 @@ def jump_list(self) -> list: # cars displacements car 5 had to park one spot farther (jumped or was displaced by one spot), car 6 had to jump 3 spots, and car 7 had to jump two spots. - OUTPUT: - the displacements sequence of parked cars which corresponds @@ -462,10 +458,7 @@ def lucky_cars(self): # the set of cars that can park in their preferred spo ``lucky_cars(PF) = [1, 2, 7]`` means that cars 1, 2 and 7 parked in their preferred spots and all the other cars did not. - - OUTPUT: - - - the cars that can park in their preferred spots + OUTPUT: the cars that can park in their preferred spots EXAMPLES:: @@ -490,9 +483,7 @@ def luck(self) -> Integer: # the number of lucky cars Return the number of cars that parked in their preferred parking spots (see [Shin]_ p. 33). - OUTPUT: - - - the number of cars that parked in their preferred parking spots + OUTPUT: the number of cars that parked in their preferred parking spots EXAMPLES:: @@ -518,8 +509,8 @@ def primary_dinversion_pairs(self) -> list[tuple[int, int]]: OUTPUT: - - the pairs `(i, j)` such that `i < j`, and `i^{th}` area = `j^{th}` area, - and `i^{th}` label < `j^{th}` label + The pairs `(i, j)` such that `i < j`, and `i`-th area = `j`-th area, + and `i`-th label < `j`-th label EXAMPLES:: @@ -548,8 +539,8 @@ def secondary_dinversion_pairs(self) -> list[tuple[int, int]]: OUTPUT: - - the pairs `(i, j)` such that `i < j`, and `i^{th}` area = `j^{th}` area +1, - and `i^{th}` label > `j^{th}` label + The pairs `(i, j)` such that `i < j`, and `i`-th area = `j`-th area +1, + and `i`-th label > `j`-th label EXAMPLES:: @@ -576,9 +567,7 @@ def dinversion_pairs(self) -> list[tuple[int, int]]: Return the descent inversion pairs of a labelled Dyck path corresponding to the parking function. - OUTPUT: - - - the primary and secondary diversion pairs + OUTPUT: the primary and secondary diversion pairs EXAMPLES:: @@ -604,9 +593,7 @@ def dinv(self) -> int: Same as the cardinality of :meth:`dinversion_pairs`. - OUTPUT: - - - the number of dinversion pairs + OUTPUT: the number of dinversion pairs EXAMPLES:: @@ -795,9 +782,7 @@ def to_labelling_permutation(self) -> Permutation: r""" Return the labelling of the support Dyck path of the parking function. - OUTPUT: - - - the labelling of the Dyck path + OUTPUT: the labelling of the Dyck path EXAMPLES:: @@ -822,9 +807,7 @@ def to_area_sequence(self) -> list: Return the area sequence of the support Dyck path of the parking function. - OUTPUT: - - - the area sequence of the Dyck path + OUTPUT: the area sequence of the Dyck path EXAMPLES:: @@ -879,9 +862,7 @@ def to_dyck_word(self) -> DyckWord: r""" Return the support Dyck word of the parking function. - OUTPUT: - - - the Dyck word of the corresponding parking function + OUTPUT: the Dyck word of the corresponding parking function .. SEEALSO:: :meth:`DyckWord` @@ -972,9 +953,7 @@ def to_NonDecreasingParkingFunction(self) -> PF: Return the non-decreasing parking function which underlies the parking function. - OUTPUT: - - - a sorted parking function + OUTPUT: a sorted parking function .. SEEALSO:: :meth:`NonDecreasingParkingFunction` @@ -1016,9 +995,7 @@ def characteristic_quasisymmetric_function(self, q=None, - ``R`` -- (default: ``R = QQ['q','t'].fraction_field()``) the base ring to do the calculations over - OUTPUT: - - - an element of the quasisymmetric functions over the ring ``R`` + OUTPUT: an element of the quasisymmetric functions over the ring ``R`` EXAMPLES:: @@ -1063,7 +1040,7 @@ def pretty_print(self, underpath=True): - ``underpath`` -- if the length of the parking function is less than or equal to 9 then display the labels under the - path if ``underpath`` is True otherwise display them to the + path if ``underpath`` is ``True`` otherwise display them to the right of the path (default: ``True``) EXAMPLES:: @@ -1330,7 +1307,7 @@ def __classcall_private__(cls, n=None): return ParkingFunctions_all() if not isinstance(n, (Integer, int)) or n < 0: - raise ValueError("%s is not a non-negative integer" % n) + raise ValueError("%s is not a nonnegative integer" % n) return ParkingFunctions_n(n) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 8f3222f804b..6b6a7edfa4c 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6,8 +6,8 @@ partition) with total sum `n`. A partition can be depicted by a diagram made of rows of cells, -where the number of cells in the `i^{th}` row starting from -the top is the `i^{th}` part of the partition. +where the number of cells in the `i`-th row starting from +the top is the `i`-th part of the partition. The coordinate system related to a partition applies from the top to the bottom and from left to right. So, the corners of the @@ -330,7 +330,7 @@ class Partition(CombinatorialElement): A partition is often represented as a diagram consisting of **cells**, or **boxes**, placed in rows on top of each other such that the number of - cells in the `i^{th}` row, reading from top to bottom, is the `i^{th}` + cells in the `i`-th row, reading from top to bottom, is the `i`-th part of the partition. The rows are left-justified (and become shorter and shorter the farther down one goes). This diagram is called the **Young diagram** of the partition, or more precisely its Young diagram @@ -520,7 +520,7 @@ def __init__(self, parent, mu): Initialize ``self``. We assume that ``mu`` is a weakly decreasing list of - non-negative elements in ``ZZ``. + nonnegative elements in ``ZZ``. EXAMPLES:: @@ -851,7 +851,7 @@ def _latex_(self) -> str: \end{array}$} } - sage: Partitions.options(latex="young_diagram", convention="french") + sage: Partitions.options(latex='young_diagram', convention='french') sage: Partitions.options.latex='exp_high'; latex(mu) # indirect doctest 2,1 sage: Partitions.options.latex='exp_low'; latex(mu) # indirect doctest @@ -972,7 +972,7 @@ def ferrers_diagram(self) -> str: EXAMPLES:: sage: mu = Partition([5,5,2,1]) - sage: Partitions.options(diagram_str='*', convention="english") + sage: Partitions.options(diagram_str='*', convention='english') sage: print(mu.ferrers_diagram()) ***** ***** @@ -1463,10 +1463,10 @@ def has_rectangle(self, h, w) -> bool: INPUT: - - ``h`` -- An integer `h \geq 1`. The (*minimum*) height of the - rectangle. + - ``h`` -- integer `h \geq 1`; the (*minimum*) height of the + rectangle - - ``w`` -- An integer `w \geq 1`. The width of the rectangle. + - ``w`` -- integer `w \geq 1`; the width of the rectangle EXAMPLES:: @@ -1654,16 +1654,16 @@ def next_within_bounds(self, min=[], max=None, partition_type=None): INPUT: - - ``min`` -- (default ``[]``, the empty partition) The - 'minimum partition' that ``next_within_bounds(self)`` must contain. + - ``min`` -- (default: ``[]``, the empty partition) the + 'minimum partition' that ``next_within_bounds(self)`` must contain - - ``max`` -- (default ``None``) The 'maximum partition' that - ``next_within_bounds(self)`` must be contained in. If set to ``None``, - then there is no restriction. + - ``max`` -- (default: ``None``) the 'maximum partition' that + ``next_within_bounds(self)`` must be contained in; if set to ``None``, + then there is no restriction - - ``partition_type`` -- (default ``None``) The type of partitions - allowed. For example, 'strict' for strictly decreasing partitions, or - ``None`` to allow any valid partition. + - ``partition_type`` -- (default: ``None``) the type of partitions + allowed; for example, 'strict' for strictly decreasing partitions, or + ``None`` to allow any valid partition EXAMPLES:: @@ -1707,7 +1707,7 @@ def next_within_bounds(self, min=[], max=None, partition_type=None): # if there is no max, the next partition just tacks a '1' on to the end! if max is None: return _Partitions(p + [1]) - # extend p and min to include 0's at the end + # extend p and min to include 0s at the end p = p + [0] * (len(max) - len(p)) min = min + [0] * (len(max) - len(min)) # finally, run the algo to find next_p @@ -1850,7 +1850,7 @@ def down_list(self): return list(self.down()) @combinatorial_map(name="cell poset") - def cell_poset(self, orientation="SE"): + def cell_poset(self, orientation='SE'): """ Return the Young diagram of ``self`` as a poset. The optional keyword variable ``orientation`` determines the order relation @@ -1859,10 +1859,10 @@ def cell_poset(self, orientation="SE"): The poset always uses the set of cells of the Young diagram of ``self`` as its ground set. The order relation of the poset depends on the ``orientation`` variable (which defaults to - ``"SE"``). Concretely, ``orientation`` has to be specified to - one of the strings ``"NW"``, ``"NE"``, ``"SW"``, and ``"SE"``, + ``'SE'``). Concretely, ``orientation`` has to be specified to + one of the strings ``'NW'``, ``'NE'``, ``'SW'``, and ``'SE'``, standing for "northwest", "northeast", "southwest" and - "southeast", respectively. If ``orientation`` is ``"SE"``, then + "southeast", respectively. If ``orientation`` is ``'SE'``, then the order relation of the poset is such that a cell `u` is greater or equal to a cell `v` in the poset if and only if `u` lies weakly southeast of `v` (this means that `u` can be @@ -2062,7 +2062,6 @@ def frobenius_coordinates(self): ([2, 1, 0], [2, 1, 0]) sage: Partition([9,1,1,1,1,1,1]).frobenius_coordinates() ([8], [6]) - """ mu = self muconj = mu.conjugate() # Naive implementation @@ -2355,7 +2354,7 @@ def generalized_pochhammer_symbol(self, a, alpha): def get_part(self, i, default=Integer(0)): r""" - Return the `i^{th}` part of ``self``, or ``default`` if it does + Return the `i`-th part of ``self``, or ``default`` if it does not exist. EXAMPLES:: @@ -2599,7 +2598,7 @@ def suter_diagonal_slide(self, n, exp=1): northwestern most cell in English notation) of `\lambda` is less than `n`, including the empty partition. - The map `\sigma_n` sends a partition (with non-zero entries) + The map `\sigma_n` sends a partition (with nonzero entries) `(\lambda_1, \lambda_2, \ldots, \lambda_m) \in Y_n` to the partition `(\lambda_2 + 1, \lambda_3 + 1, \ldots, \lambda_m + 1, \underbrace{1, 1, \ldots, 1}_{n - m - \lambda_1\text{ ones}})`. @@ -2774,7 +2773,7 @@ def initial_column_tableau(self): r""" Return the initial column tableau of shape ``self``. - The initial column tableau of shape self is the standard tableau + The initial column tableau of shape ``self`` is the standard tableau that has the numbers `1` to `n`, where `n` is the :meth:`size` of ``self``, entered in order from top to bottom and then left to right down the columns of ``self``. @@ -2947,10 +2946,10 @@ def ladder_tableau(self, e, ladder_lengths=False): INPUT: - - ``e`` -- a nonnegative integer; ``0`` is considered as `\infty` + - ``e`` -- nonnegative integer; `0` is considered as `\infty` (analogous to the characteristic of a ring) - - ``ladder_sizes`` -- (default: ``False``) if ``True``, also return - the sizes of the ladders + - ``ladder_sizes`` -- boolean (default: ``False``); if ``True``, also + return the sizes of the ladders .. SEEALSO:: @@ -3009,7 +3008,7 @@ def ladders(self, e): INPUT: - - ``e`` -- a nonnegative integer; if ``0``, then we + - ``e`` -- nonnegative integer; if ``0``, then we set ``e = self.size() + 1`` EXAMPLES:: @@ -3141,9 +3140,7 @@ def degree(self, e): - ``e`` -- an integer `e > 1` - OUTPUT: - - A non-negative integer. + OUTPUT: nonnegative integer EXAMPLES:: @@ -3177,11 +3174,9 @@ def prime_degree(self, p): INPUT: - - ``p`` -- a prime integer + - ``p`` -- prime integer - OUTPUT: - - A non-negative integer + OUTPUT: nonnegative integer The degree of a partition `\lambda` is the sum of the `e`-:meth:`degree` of the standard tableaux of shape `\lambda`, for @@ -3223,9 +3218,7 @@ def arm_length(self, i, j): - ``i``, ``j`` -- two integers - OUTPUT: - - An integer or a :class:`ValueError` + OUTPUT: integer or a :exc:`ValueError` EXAMPLES:: @@ -3284,9 +3277,7 @@ def arm_cells(self, i, j): - ``i``, ``j`` -- two integers - OUTPUT: - - A list of pairs of integers + OUTPUT: list of pairs of integers EXAMPLES:: @@ -3317,9 +3308,7 @@ def leg_length(self, i, j): - ``i``, ``j`` -- two integers - OUTPUT: - - An integer or a :class:`ValueError` + OUTPUT: integer or a :exc:`ValueError` EXAMPLES:: @@ -3379,9 +3368,7 @@ def leg_cells(self, i, j): - ``i``, ``j`` -- two integers - OUTPUT: - - A list of pairs of integers + OUTPUT: list of pairs of integers EXAMPLES:: @@ -3953,7 +3940,7 @@ def block(self, e, multicharge=(0,)): - ``e`` -- the quantum characteristic - - ``multicharge`` -- the multicharge (default `(0,)`) + - ``multicharge`` -- the multicharge (default: `(0,)`) OUTPUT: @@ -4021,12 +4008,10 @@ def defect(self, e, multicharge=(0,)): - ``e`` -- the quantum characteristic - - ``multicharge`` -- the multicharge (default `(0,)`) + - ``multicharge`` -- the multicharge (default: `(0,)`) - OUTPUT: - - - a non-negative integer, which is the defect of the block - containing the partition ``self`` + OUTPUT: nonnegative integer, which is the defect of the block + containing the partition ``self`` EXAMPLES:: @@ -4118,7 +4103,7 @@ def is_regular(self, e, multicharge=(0,)) -> bool: Return ``True`` is this is an ``e``-regular partition. A partition is `e`-regular if it does not have `e` equal - non-zero parts. + nonzero parts. EXAMPLES:: @@ -4374,8 +4359,8 @@ def zero_one_sequence(self): that in English convention, a 1 corresponds to an East step, and a 0 corresponds to a North step. - Note that every full `0-1` sequence starts with infinitely many 0's and - ends with infinitely many 1's. + Note that every full `0-1` sequence starts with infinitely many 0s and + ends with infinitely many 1s. One place where these arise is in the affine symmetric group where one takes an affine permutation `w` and every `i` such that @@ -4390,7 +4375,7 @@ def zero_one_sequence(self): OUTPUT: The finite `0-1` sequence is obtained from the full `0-1` - sequence by omitting all heading 0's and trailing 1's. The + sequence by omitting all heading 0s and trailing 1s. The output sequence is finite, starts with a 1 and ends with a 0 (unless it is empty, for the empty partition). Its length is the sum of the first part of the partition with the @@ -4687,11 +4672,9 @@ def k_irreducible(self, k): INPUT: - - ``k`` -- a non-negative integer - - OUTPUT: + - ``k`` -- nonnegative integer - - a partition + OUTPUT: a partition EXAMPLES:: @@ -4768,7 +4751,7 @@ def k_skew(self, k): def to_core(self, k): r""" - Maps the `k`-bounded partition ``self`` to its corresponding `k+1`-core. + Map the `k`-bounded partition ``self`` to its corresponding `k+1`-core. See also :meth:`k_skew`. @@ -4787,7 +4770,7 @@ def to_core(self, k): def from_kbounded_to_reduced_word(self, k): r""" - Maps a `k`-bounded partition to a reduced word for an element in + Map a `k`-bounded partition to a reduced word for an element in the affine permutation group. This uses the fact that there is a bijection between `k`-bounded @@ -4823,7 +4806,7 @@ def from_kbounded_to_reduced_word(self, k): def from_kbounded_to_grassmannian(self, k): r""" - Maps a `k`-bounded partition to a Grassmannian element in + Map a `k`-bounded partition to a Grassmannian element in the affine Weyl group of type `A_k^{(1)}`. For details, see the documentation of the method @@ -5364,11 +5347,9 @@ def dimension(self, smaller=None, k=1): - ``smaller`` -- a partition (default: an empty list ``[]``) - - `k` -- a positive integer (default: 1) - - OUTPUT: + - ``k`` -- positive integer (default: 1) - The number of such paths + OUTPUT: the number of such paths EXAMPLES: @@ -5514,7 +5495,7 @@ def outline(self, variable=None): INPUT: - - variable -- a variable (default: ``'x'`` in the symbolic ring) + - ``variable`` -- a variable (default: ``'x'`` in the symbolic ring) EXAMPLES:: @@ -5575,11 +5556,10 @@ def dual_equivalence_graph(self, directed=False, coloring=None): INPUT: - - ``directed`` -- (default: ``False``) whether to have the dual - equivalence graph be directed (where we have a directed edge - `S \to T` if `i` appears to the left of `i+1` in the - reading word of `T`; otherwise we have the directed edge - `T \to S`) + - ``directed`` -- boolean (default: ``False``); whether to have the + dual equivalence graph be directed (where we have a directed edge + `S \to T` if `i` appears to the left of `i+1` in the reading word of + `T`; otherwise we have the directed edge `T \to S`) - ``coloring`` -- (optional) a function which sends each integer `i > 1` to a color (as a string, e.g., ``'red'`` or @@ -5658,7 +5638,7 @@ def coloring(i): elif isinstance(coloring, dict): d = coloring coloring = lambda x: d[x] - G.set_latex_options(format="dot2tex", + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label=coloring) return G @@ -5691,11 +5671,11 @@ def coloring(i): if directed: from sage.graphs.digraph import DiGraph - self._DDEG = DiGraph([T, edges], format="vertices_and_edges", + self._DDEG = DiGraph([T, edges], format='vertices_and_edges', immutable=True, multiedges=True) else: from sage.graphs.graph import Graph - self._DEG = Graph([T, edges], format="vertices_and_edges", + self._DEG = Graph([T, edges], format='vertices_and_edges', immutable=True, multiedges=True) return self.dual_equivalence_graph(directed, coloring) @@ -6196,7 +6176,7 @@ def __classcall_private__(cls, n=None, **kwargs): kwargs['max_slope'] = min(0, kwargs.get('max_slope', 0)) if kwargs.get('min_slope', -float('inf')) > 0: - raise ValueError("the minimum slope must be non-negative") + raise ValueError("the minimum slope must be nonnegative") if 'outer' in kwargs: kwargs['max_length'] = min(len(kwargs['outer']), @@ -6241,8 +6221,8 @@ def __init__(self, is_infinite=False): INPUT: - - ``is_infinite`` -- (Default: ``False``) If ``True``, then the number - of partitions in this set is infinite. + - ``is_infinite`` -- boolean (default: ``False``); if ``True``, then + the number of partitions in this set is infinite EXAMPLES:: @@ -6261,7 +6241,7 @@ def __init__(self, is_infinite=False): # add options to class class options(GlobalOptions): r""" - Sets and displays the global options for elements of the partition, + Set and display the global options for elements of the partition, skew partition, and partition tuple classes. If no parameters are set, then the function returns a copy of the options dictionary. @@ -6290,13 +6270,13 @@ class options(GlobalOptions): <4,2,2,1> sage: Partitions.options(latex=lambda mu: '\\Diagram{%s}' % ','.join('%s'%m for m in mu._list)); latex(P) \Diagram{4,2,2,1} - sage: Partitions.options(display="diagram", diagram_str="#") + sage: Partitions.options(display='diagram', diagram_str='#') sage: P #### ## ## # - sage: Partitions.options(diagram_str="*", convention="french") + sage: Partitions.options(diagram_str='*', convention='french') sage: print(P.ferrers_diagram()) * ** @@ -6393,7 +6373,6 @@ def _element_constructor_(self, lst): Traceback (most recent call last): ... ValueError: all parts of [3/2] should be nonnegative integers - """ if isinstance(lst, PartitionTuple): if lst.level() != 1: @@ -6448,7 +6427,6 @@ def __contains__(self, x): sage: 0 in P False - """ if isinstance(x, Partition): return True @@ -6461,7 +6439,7 @@ def subset(self, *args, **kwargs): r""" Return ``self`` if no arguments are given. - Otherwise, it raises a :class:`ValueError`. + Otherwise, it raises a :exc:`ValueError`. EXAMPLES:: @@ -6612,11 +6590,11 @@ def from_beta_numbers(self, beta): Return a partition corresponding to a sequence of beta numbers. A sequence of beta numbers is a strictly increasing sequence - `0 \leq b_1 < \cdots < b_k` of non-negative integers. The + `0 \leq b_1 < \cdots < b_k` of nonnegative integers. The corresponding partition `\mu = (\mu_k, \ldots, \mu_1)` is given by `\mu_i = [1,i) \setminus \{ b_1, \ldots, b_i \}`. This gives - a bijection from the set of partitions with at most `k` non-zero parts - to the set of strictly increasing sequences of non-negative integers + a bijection from the set of partitions with at most `k` nonzero parts + to the set of strictly increasing sequences of nonnegative integers of length `k`. EXAMPLES:: @@ -6658,8 +6636,8 @@ def from_zero_one(self, seq): that in English convention, a 1 corresponds to an East step, and a 0 corresponds to a North step. - Note that every full `0-1` sequence starts with infinitely many 0's and - ends with infinitely many 1's. + Note that every full `0-1` sequence starts with infinitely many 0s and + ends with infinitely many 1s. .. SEEALSO:: @@ -6667,8 +6645,8 @@ def from_zero_one(self, seq): INPUT: - The input should be a finite sequence of 0's and 1's. The - heading 0's and trailing 1's will be discarded. + The input should be a finite sequence of 0s and 1s. The + heading 0s and trailing 1s will be discarded. EXAMPLES:: @@ -6679,7 +6657,7 @@ def from_zero_one(self, seq): sage: Partitions().from_zero_one([1, 1, 1, 1, 0, 1, 0]) [5, 4] - Heading 0's and trailing 1's are correctly handled:: + Heading 0s and trailing 1s are correctly handled:: sage: Partitions().from_zero_one([0,0,1,1,1,1,0,1,0,1,1,1]) [5, 4] @@ -6887,12 +6865,12 @@ def cardinality(self, algorithm='flint'): INPUT: - - ``algorithm`` -- (default: ``'flint'``) + - ``algorithm`` -- (default: ``'flint'``) - ``'flint'`` -- use FLINT (currently the fastest) - ``'gap'`` -- use GAP (VERY *slow*) - ``'pari'`` -- use PARI. Speed seems the same as GAP until - `n` is in the thousands, in which case PARI is faster. + `n` is in the thousands, in which case PARI is faster It is possible to associate with every partition of the integer `n` a conjugacy class of permutations in the symmetric group on `n` points @@ -7032,15 +7010,15 @@ def random_element_uniform(self): ALGORITHM: - - It is a python Implementation of RANDPAR, see [NW1978]_. The - complexity is unknown, there may be better algorithms. + - It is a python Implementation of RANDPAR, see [NW1978]_. The + complexity is unknown, there may be better algorithms. .. TODO:: Check in Knuth AOCP4. - - There is also certainly a lot of room for optimizations, see - comments in the code. + - There is also certainly a lot of room for optimizations, see + comments in the code. AUTHOR: @@ -7193,7 +7171,6 @@ def __iter__(self): sage: all(isinstance(i, Integer) for p in Partitions(4) for i in p) True - """ for p in ZS1_iterator(self.n): yield self.element_class(self, [Integer(i) for i in p]) @@ -7333,7 +7310,6 @@ def __iter__(self): sage: partitions = Partitions(9, length=3) sage: all(isinstance(i, Integer) for p in partitions for i in p) True - """ for p in ZS1_iterator_nk(self.n - self.k, self.k): v = [Integer(i + 1) for i in p] @@ -7565,7 +7541,6 @@ def _findfirst(self, n, parts): sage: p._findfirst(0, p.parts[:]) [] sage: p._findfirst(p.n, [10]) - """ if n == 0: return [] @@ -7621,7 +7596,7 @@ def _findlast(self, n, parts): - ``n`` -- nonnegative integer - - ``parts`` -- a sorted list of positive integers. + - ``parts`` -- a sorted list of positive integers OUTPUT: @@ -7675,15 +7650,15 @@ def __iter__(self): def _fast_iterator(self, n, parts): """ - A fast iterator for the partitions of ``n`` which returns lists and + A fast iterator for the partitions of `n` which returns lists and not partition types. This function is not intended to be called directly. INPUT: - - ``n`` -- nonnegative integer. + - ``n`` -- nonnegative integer - - ``parts`` -- a list of parts to use. This list will be + - ``parts`` -- list of parts to use. This list will be destroyed, so pass things here with ``foo[:]`` (or something equivalent) if you want to preserve your list. In particular, the ``__iter__`` method needs to use ``self.parts[:]``, or else we @@ -7718,20 +7693,18 @@ def _fast_iterator(self, n, parts): def _other_iterator(self, n, parts): """ - A fast iterator for the partitions of ``n`` which returns lists and + A fast iterator for the partitions of `n` which returns lists and not partition types. This function is not intended to be called directly. INPUT: - - ``n`` -- nonnegative integer. - - - ``parts`` -- a list of parts to use. + - ``n`` -- nonnegative integer - OUTPUT: + - ``parts`` -- list of parts to use - A generator object for partitions of `n` with parts in - ``parts``. + OUTPUT: a generator object for partitions of `n` with parts in + ``parts`` EXAMPLES:: @@ -7818,7 +7791,7 @@ def _repr_(self): def __contains__(self, x): """ - Checks if ``x`` is contained in ``self``. + Check if ``x`` is contained in ``self``. EXAMPLES:: @@ -7896,7 +7869,7 @@ def __classcall_private__(cls, n, ending_partition): def __init__(self, n, ending_partition): """ - Initializes ``self``. + Initialize ``self``. EXAMPLES:: @@ -7932,7 +7905,7 @@ def _repr_(self): def __contains__(self, x): """ - Checks if ``x`` is contained in ``self``. + Check if ``x`` is contained in ``self``. EXAMPLES:: @@ -8026,7 +7999,7 @@ def _repr_(self): def __contains__(self, x): """ - Checks if ``x`` is contained in ``self``. + Check if ``x`` is contained in ``self``. EXAMPLES:: @@ -8103,7 +8076,6 @@ def cardinality(self): ....: len(PartitionsInBox(a, b).list()) ....: for a in range(6) for b in range(6)) True - """ return binomial(self.h + self.w, self.w) @@ -8257,8 +8229,7 @@ def _fast_iterator(self, n, max_part): yield [] return - if n < max_part: - max_part = n + max_part = min(n, max_part) bdry = self._ell - 1 for i in reversed(range(1, max_part + 1)): @@ -8449,8 +8420,7 @@ def _fast_iterator(self, n, max_part, depth=0): yield [n] return - if n < max_part: - max_part = n + max_part = min(n, max_part) bdry = self._ell - 1 for i in reversed(range(1, max_part + 1)): @@ -8635,7 +8605,6 @@ def cardinality(self): sage: P = Partitions(5, regular=1) sage: P.cardinality() # needs sage.libs.flint 0 - """ if self._ell > self.n: return Partitions_n.cardinality(self) @@ -8700,7 +8669,6 @@ class OrderedPartitions(Partitions): [[9, 1], [8, 2], [7, 3], [6, 4], [5, 5], [4, 6], [3, 7], [2, 8], [1, 9]] sage: OrderedPartitions(4).list() # needs sage.libs.gap [[4], [3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]] - """ @staticmethod @@ -8886,7 +8854,6 @@ def cardinality(self): ....: len(PartitionsGreatestLE(n, a).list()) ....: for n in range(20) for a in range(6)) True - """ return sum(number_of_partitions_length(self.n, i) for i in range(self.k+1)) @@ -8932,7 +8899,6 @@ class PartitionsGreatestEQ(UniqueRepresentation, IntegerListsLex): sage: PartitionsGreatestEQ(10, 2).first().parent() Partitions... - """ def __init__(self, n, k): @@ -8976,7 +8942,6 @@ def cardinality(self): ....: len(PartitionsGreatestEQ(n, a).list()) ....: for n in range(20) for a in range(6)) True - """ if not self.n: return 1 @@ -9099,8 +9064,7 @@ def _fast_iterator(self, n, max_part): yield [] return - if n < max_part: - max_part = n + max_part = min(n, max_part) for i in range(max_part, 0, -1): for p in self._fast_iterator(n-i, i): @@ -9276,15 +9240,15 @@ def number_of_partitions(n, algorithm='default'): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``algorithm`` -- (default: 'default') + - ``algorithm`` -- (default: ``'default'``) [Will be deprecated except in Partition().cardinality() ] - - ``'default'`` -- If ``k`` is not ``None``, then use Gap (very slow). - If ``k`` is ``None``, use FLINT. + - ``'default'`` -- if ``k`` is not ``None``, then use Gap (very slow); + if ``k`` is ``None``, use FLINT - - ``'flint'`` -- use FLINT + - ``'flint'`` -- use FLINT EXAMPLES:: @@ -9293,7 +9257,7 @@ def number_of_partitions(n, algorithm='default'): sage: len(v) 7 - The input must be a nonnegative integer or a :class:`ValueError` is raised. + The input must be a nonnegative integer or a :exc:`ValueError` is raised. :: @@ -9369,7 +9333,6 @@ def number_of_partitions(n, algorithm='default'): sage: n = 100000000 + randint(0,100000000) sage: number_of_partitions( n - (n % 385) + 369) % 385 == 0 # long time (4s on sage.math, 2011) True - """ n = ZZ(n) if n < 0: diff --git a/src/sage/combinat/partition_algebra.py b/src/sage/combinat/partition_algebra.py index cdc59830a28..91e79be4cbc 100644 --- a/src/sage/combinat/partition_algebra.py +++ b/src/sage/combinat/partition_algebra.py @@ -37,7 +37,7 @@ def _int_or_half_int(k): OUTPUT: - If ``k`` is not in `1/2 \ZZ`, then this raises a :class:`ValueError`. + If ``k`` is not in `1/2 \ZZ`, then this raises a :exc:`ValueError`. Otherwise, we return the pair: - boolean; ``True`` if ``k`` is an integer and ``False`` if a half integer @@ -364,9 +364,7 @@ def __iter__(self): True """ for p in Permutations(self.k): - res = [] - for i in range(self.k): - res.append(Set([i + 1, -p[i]])) + res = [Set([i, -pi]) for i, pi in enumerate(p, start=1)] yield self.element_class(self, res) @@ -433,10 +431,7 @@ def __iter__(self): {{1, -3}, {2, -2}, {4, -4}, {3, -1}}] """ for p in Permutations(self.k): - res = [] - for i in range(self.k): - res.append(Set([i + 1, -p[i]])) - + res = [Set([i, -pi]) for i, pi in enumerate(p, start=1)] res.append(Set([self.k + 1, -self.k - 1])) yield self.element_class(self, res) @@ -851,7 +846,6 @@ def SetPartitionsPk(k): {{-1}, {-2}, {2}, {3, -3}, {1}} sage: P2p5.random_element() #random {{1, 2, 3, -3}, {-1, -2}} - """ is_int, k = _int_or_half_int(k) if not is_int: @@ -1579,7 +1573,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra A_%s(%s)" % (k, n) cclass = SetPartitionsAk(k) self._element_class = PartitionAlgebraElement_ak - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="A") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='A') class PartitionAlgebraElement_bk(PartitionAlgebraElement_generic): @@ -1600,7 +1594,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra B_%s(%s)" % (k, n) cclass = SetPartitionsBk(k) self._element_class = PartitionAlgebraElement_bk - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="B") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='B') class PartitionAlgebraElement_sk(PartitionAlgebraElement_generic): @@ -1621,7 +1615,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra S_%s(%s)" % (k, n) cclass = SetPartitionsSk(k) self._element_class = PartitionAlgebraElement_sk - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="S") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='S') class PartitionAlgebraElement_pk(PartitionAlgebraElement_generic): @@ -1642,7 +1636,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra P_%s(%s)" % (k, n) cclass = SetPartitionsPk(k) self._element_class = PartitionAlgebraElement_pk - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="P") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='P') class PartitionAlgebraElement_tk(PartitionAlgebraElement_generic): @@ -1663,7 +1657,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra T_%s(%s)" % (k, n) cclass = SetPartitionsTk(k) self._element_class = PartitionAlgebraElement_tk - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="T") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='T') class PartitionAlgebraElement_rk(PartitionAlgebraElement_generic): @@ -1684,7 +1678,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra R_%s(%s)" % (k, n) cclass = SetPartitionsRk(k) self._element_class = PartitionAlgebraElement_rk - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="R") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='R') class PartitionAlgebraElement_prk(PartitionAlgebraElement_generic): @@ -1705,7 +1699,7 @@ def __init__(self, R, k, n, name=None): name = "Partition algebra PR_%s(%s)" % (k, n) cclass = SetPartitionsPRk(k) self._element_class = PartitionAlgebraElement_prk - PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix="PR") + PartitionAlgebra_generic.__init__(self, R, cclass, n, k, name=name, prefix='PR') ########################################################## @@ -1942,15 +1936,15 @@ def to_set_partition(l, k=None): to_be_added -= spart sp.append(spart) - for singleton in to_be_added: - sp.append(Set([singleton])) + sp.extend(Set([singleton]) + for singleton in to_be_added) return Set(sp) def identity(k): - """ - Return the identity set partition 1, -1, ..., k, -k + r""" + Return the identity set partition `1, -1, \ldots, k, -k`. EXAMPLES:: diff --git a/src/sage/combinat/partition_kleshchev.py b/src/sage/combinat/partition_kleshchev.py index 44204aad33b..cfa78933e37 100644 --- a/src/sage/combinat/partition_kleshchev.py +++ b/src/sage/combinat/partition_kleshchev.py @@ -131,14 +131,14 @@ def conormal_cells(self, i=None): EXAMPLES:: - sage: KP = KleshchevPartitions(3, convention="regular") + sage: KP = KleshchevPartitions(3, convention='regular') sage: KP([5,4,4,3,2]).conormal_cells() {0: [(1, 4)], 1: [(5, 0), (4, 2)]} sage: KP([5,4,4,3,2]).conormal_cells(0) [(1, 4)] sage: KP([5,4,4,3,2]).conormal_cells(1) [(5, 0), (4, 2)] - sage: KP = KleshchevPartitions(3, convention="restricted") + sage: KP = KleshchevPartitions(3, convention='restricted') sage: KP([5,4,4,3,2]).conormal_cells() {0: [(1, 4), (3, 3)], 2: [(0, 5)]} """ @@ -192,7 +192,7 @@ def cogood_cells(self, i=None): EXAMPLES:: - sage: KP = KleshchevPartitions(3, convention="regular") + sage: KP = KleshchevPartitions(3, convention='regular') sage: KP([5,4,4,3,2]).cogood_cells() {0: (1, 4), 1: (4, 2)} sage: KP([5,4,4,3,2]).cogood_cells(0) @@ -435,7 +435,7 @@ def is_regular(self): A partition tuple is `e`-regular if we can get to the empty partition tuple by successively removing a sequence of good cells in the down direction. Equivalently, all partitions are `0`-regular and if `e > 0` - then a partition is `e`-regular if no `e` non-zero parts of ``self`` + then a partition is `e`-regular if no `e` nonzero parts of ``self`` are equal. EXAMPLES:: @@ -788,7 +788,6 @@ def mullineux_conjugate(self): ([2, 2, 1, 1], [3, 2, 2, 1, 1]) sage: mc.parent() Kleshchev partitions with e=3 and multicharge=(0,2) - """ P = self.parent() if self.size() == 0: @@ -1098,7 +1097,7 @@ def f(self, i): class KleshchevPartitions(PartitionTuples): r""" - Kleshchev partitions + Kleshchev partitions. A partition (tuple) `\mu` is Kleshchev if it can be recursively obtained by adding a sequence of good nodes to the empty @@ -1279,7 +1278,6 @@ def _element_constructor_(self, mu): sage: KPls = KleshchevPartitions(2, [0,0], size=2, convention='left restricted') sage: [KPlg(mu) for mu in KPls] # indirect doc test [([1], [1]), ([2], [])] - """ if isinstance(mu, (KleshchevPartition, KleshchevPartitionTuple)): KPmu = mu.parent() @@ -1426,7 +1424,7 @@ class KleshchevPartitions_all(KleshchevPartitions): def __init__(self, e, multicharge, convention): r""" - Initializes ``self``. + Initialize ``self``. EXAMPLES:: diff --git a/src/sage/combinat/partition_shifting_algebras.py b/src/sage/combinat/partition_shifting_algebras.py index 90f1f10d59f..366200aefa3 100644 --- a/src/sage/combinat/partition_shifting_algebras.py +++ b/src/sage/combinat/partition_shifting_algebras.py @@ -92,7 +92,7 @@ def check(self, seq): r""" Verify that ``seq`` is a valid shifting sequence. - If it is not, raise a :class:`ValueError`. + If it is not, raise a :exc:`ValueError`. EXAMPLES:: @@ -164,7 +164,7 @@ class ShiftingOperatorAlgebra(CombinatorialFreeModule): - ``base_ring`` -- (default: ``QQ['t']``) the base ring - - ``prefix`` -- (default: ``"S"``) the label for the shifting operators + - ``prefix`` -- (default: ``'S'``) the label for the shifting operators EXAMPLES:: diff --git a/src/sage/combinat/partition_tuple.py b/src/sage/combinat/partition_tuple.py index bf40c650c33..0e0e8e4aae9 100644 --- a/src/sage/combinat/partition_tuple.py +++ b/src/sage/combinat/partition_tuple.py @@ -341,9 +341,9 @@ class of modules for the algebras which are generalisations of the Specht INPUT: - Anything which can reasonably be interpreted as a tuple of partitions. - That is, a list or tuple of partitions or valid input to - :class:`Partition`. + Anything which can reasonably be interpreted as a tuple of partitions. + That is, a list or tuple of partitions or valid input to + :class:`Partition`. EXAMPLES:: @@ -460,7 +460,6 @@ def __init__(self, parent, mu): Traceback (most recent call last): ... ValueError: [[], [], [2, 1, 2, 1]] is not a tuple of Partitions - """ mu = [_Partitions(nu) for nu in mu] CombinatorialElement.__init__(self, parent, mu) @@ -490,7 +489,6 @@ def __len__(self): sage: len( PartitionTuple([[2,1],[3,2],[1,1,1]]) ) 3 - """ return self.level() @@ -503,36 +501,36 @@ def _repr_(self, compact=None): sage: mu=PartitionTuple(([2,1],[3,2],[1,1,1])) # indirect doctest - sage: PartitionTuples.options(display="list"); mu + sage: PartitionTuples.options(display='list'); mu ([2, 1], [3, 2], [1, 1, 1]) - sage: PartitionTuples.options(display="diagram"); mu + sage: PartitionTuples.options(display='diagram'); mu ** *** * * ** * * - sage: PartitionTuples.options(display="compact_low"); mu + sage: PartitionTuples.options(display='compact_low'); mu 1,2|2,3|1^3 - sage: PartitionTuples.options(display="compact_high"); mu + sage: PartitionTuples.options(display='compact_high'); mu 2,1|3,2|1^3 - sage: PartitionTuples.options(display="exp_low"); mu + sage: PartitionTuples.options(display='exp_low'); mu 1, 2 | 2, 3 | 1^3 - sage: PartitionTuples.options(display="exp_high"); mu + sage: PartitionTuples.options(display='exp_high'); mu 2, 1 | 3, 2 | 1^3 sage: PartitionTuples.options._reset() - sage: Partitions.options(convention="French") - sage: PartitionTuples.options(display="diagram"); mu + sage: Partitions.options(convention='French') + sage: PartitionTuples.options(display='diagram'); mu * * ** * ** *** * - sage: PartitionTuples.options(display="list"); mu + sage: PartitionTuples.options(display='list'); mu ([2, 1], [3, 2], [1, 1, 1]) - sage: PartitionTuples.options(display="compact_low"); mu + sage: PartitionTuples.options(display='compact_low'); mu 1,2|2,3|1^3 - sage: PartitionTuples.options(display="compact_high"); mu + sage: PartitionTuples.options(display='compact_high'); mu 2,1|3,2|1^3 - sage: PartitionTuples.options(display="exp_low"); mu + sage: PartitionTuples.options(display='exp_low'); mu 1, 2 | 2, 3 | 1^3 - sage: PartitionTuples.options(display="exp_high"); mu + sage: PartitionTuples.options(display='exp_high'); mu 2, 1 | 3, 2 | 1^3 sage: PartitionTuples.options._reset() """ @@ -659,7 +657,7 @@ def _latex_(self): \end{array}$} } - sage: PartitionTuples.options(latex="young_diagram", convention="french") + sage: PartitionTuples.options(latex='young_diagram', convention='french') sage: PartitionTuples.options(latex='exp_high'); latex(mu) # indirect doctest (2,1|1^{3}) sage: PartitionTuples.options(latex='exp_low'); latex(mu) # indirect doctest @@ -785,7 +783,7 @@ def diagram(self): ** * * * * - sage: PartitionTuples.options(convention="french") + sage: PartitionTuples.options(convention='french') sage: print(PartitionTuple([[3,2],[2,1],[],[1,1,1,1]]).diagram()) * * @@ -818,7 +816,7 @@ def diagram(self): def pp(self): r""" - Pretty prints this partition tuple. See :meth:`diagram`. + Pretty print this partition tuple. See :meth:`diagram`. EXAMPLES:: @@ -899,7 +897,6 @@ def up_list(self): [([1], [3, 1], [1, 1]), ([], [4, 1], [1, 1]), ([], [3, 2], [1, 1]), ([], [3, 1, 1], [1, 1]), ([], [3, 1], [2, 1]), ([], [3, 1], [1, 1, 1])] sage: PartitionTuple([[],[],[],[]]).up_list() [([1], [], [], []), ([], [1], [], []), ([], [], [1], []), ([], [], [], [1])] - """ return list(self.up()) @@ -914,7 +911,6 @@ def down(self): [([], [2, 1], [1, 1]), ([], [3], [1, 1]), ([], [3, 1], [1])] sage: [mu for mu in PartitionTuple([[],[],[]]).down()] [] - """ for c in range(len(self)): for nu in self[c].down(): @@ -978,7 +974,6 @@ def content(self, k,r,c, multicharge): sage: multicharge = [IntegerModRing(3)(c) for c in [0,0,0]] sage: PartitionTuple([[2,1],[2],[1,1,1]]).content(0,1,0, multicharge) 2 - """ return multicharge[k]-r+c @@ -1279,13 +1274,11 @@ def arm_length(self, k,r,c): INPUT: - - ``k`` -- The component - - ``r`` -- The row - - ``c`` -- The cell + - ``k`` -- the component + - ``r`` -- the row + - ``c`` -- the cell - OUTPUT: - - - The arm length as an integer + OUTPUT: the arm length as an integer The arm of cell ``(k, r, c)`` is the number of cells in the ``k``-th component which are to the right of the cell in row ``r`` and column @@ -1311,13 +1304,11 @@ def leg_length(self, k,r,c): INPUT: - - ``k`` -- The component - - ``r`` -- The row - - ``c`` -- The cell - - OUTPUT: + - ``k`` -- the component + - ``r`` -- the row + - ``c`` -- the cell - - The leg length as an integer + OUTPUT: the leg length as an integer The leg of cell ``(k, r, c)`` is the number of cells in the ``k``-th component which are below the node in row ``r`` and column ``c``. @@ -1384,7 +1375,6 @@ def to_exp(self, k=0): ([2], [0, 1], [1, 1]) sage: PartitionTuple([[1,1],[2,2,2,2],[2,1]]).to_exp() ([2], [0, 4], [1, 1]) - """ return tuple(self[c].to_exp(k) for c in range(len(self))) @@ -1401,7 +1391,6 @@ def removable_cells(self): [(0, 1, 0), (1, 0, 1), (2, 0, 1), (2, 1, 0)] sage: PartitionTuple([[1,1],[4,3],[2,1,1]]).removable_cells() [(0, 1, 0), (1, 0, 3), (1, 1, 2), (2, 0, 1), (2, 2, 0)] - """ return [(k,r,c) for k in range(len(self)) for (r,c) in self[k].removable_cells()] @@ -1420,7 +1409,6 @@ def addable_cells(self): [(0, 0, 1), (0, 2, 0), (1, 0, 2), (1, 1, 0), (2, 0, 2), (2, 1, 1), (2, 2, 0)] sage: PartitionTuple([[1,1],[4,3],[2,1,1]]).addable_cells() [(0, 0, 1), (0, 2, 0), (1, 0, 4), (1, 1, 3), (1, 2, 0), (2, 0, 2), (2, 1, 1), (2, 3, 0)] - """ return [(k,r,c) for k in range(len(self)) for (r,c) in self[k].addable_cells()] @@ -1571,11 +1559,9 @@ def degree(self, e): INPUT: - - ``e`` -- an integer `e > 1` - - OUTPUT: + - ``e`` -- integer `e > 1` - A non-negative integer. + OUTPUT: nonnegative integer EXAMPLES:: @@ -1630,9 +1616,7 @@ def prime_degree(self, p): - ``multicharge`` -- an `l`-tuple of integers, where `l` is the :meth:`level` of ``self`` - OUTPUT: - - A non-negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -1666,7 +1650,7 @@ def block(self, e, multicharge): - ``e`` -- the quantum characteristic - - ``multicharge`` -- the multicharge (default `(0,)`) + - ``multicharge`` -- the multicharge (default: `(0,)`) OUTPUT: @@ -1738,12 +1722,10 @@ def defect(self, e, multicharge): - ``e`` -- the quantum characteristic - - ``multicharge`` -- the multicharge (default `(0,)`) + - ``multicharge`` -- the multicharge (default: `(0,)`) - OUTPUT: - - - a non-negative integer, which is the defect of the block - containing the partition tuple ``self`` + OUTPUT: a nonnegative integer, which is the defect of the block + containing the partition tuple ``self`` EXAMPLES:: @@ -1788,9 +1770,9 @@ class PartitionTuples(UniqueRepresentation, Parent): - ``level`` -- the length of the tuple - - ``size`` -- the total number of cells + - ``size`` -- the total number of cells - - ``regular`` -- a positive integer or a tuple of non-negative + - ``regular`` -- positive integer or a tuple of nonnegative integers; if an integer, the highest multiplicity an entry may have in a component plus `1` @@ -1845,7 +1827,7 @@ def __classcall_private__(klass, level=None, size=None, regular=None): raise ValueError('the level must be a positive integer') if size is not None and (not isinstance(size, (int, Integer)) or size < 0): - raise ValueError('the size must be a non-negative integer') + raise ValueError('the size must be a nonnegative integer') if isinstance(regular, (list, tuple)): if level is None: @@ -1856,7 +1838,7 @@ def __classcall_private__(klass, level=None, size=None, regular=None): level, regular)) if regular == 0: raise ValueError("regular must be a positive integer or a tuple " - "of non-negative integers") + "of nonnegative integers") if level is None: if size is None: if regular is None: @@ -1902,15 +1884,13 @@ def __classcall_private__(klass, level=None, size=None, regular=None): def _element_constructor_(self, mu): r""" - Constructs an element of :class:`PartitionTuple`. + Construct an element of :class:`PartitionTuple`. INPUT: - - ``mu`` -- a tuple of partitions - - OUTPUT: + - ``mu`` -- tuple of partitions - - The corresponding :class:`PartitionTuple` object + OUTPUT: the corresponding :class:`PartitionTuple` object TESTS:: @@ -2074,7 +2054,7 @@ class PartitionTuples_all(PartitionTuples): def __init__(self): r""" - Initializes the class. + Initialize the class. EXAMPLES:: @@ -2147,7 +2127,7 @@ class PartitionTuples_level(PartitionTuples): def __init__(self, level, category=None): r""" - Initializes this class. + Initialize this class. EXAMPLES:: @@ -2158,7 +2138,7 @@ def __init__(self, level, category=None): sage: TestSuite( PartitionTuples(level=4) ).run() # needs sage.libs.flint """ if level not in NN: - raise ValueError('level must be a non-negative integer') + raise ValueError('level must be a nonnegative integer') if category is None: category = InfiniteEnumeratedSets() super().__init__(category=category) @@ -2264,7 +2244,7 @@ def __init__(self, size): sage: TestSuite( PartitionTuples(size=6) ).run() # needs sage.libs.flint """ if size not in NN: - raise ValueError('size must be a non-negative integer') + raise ValueError('size must be a nonnegative integer') super().__init__(category=InfiniteEnumeratedSets()) self._size = size @@ -2309,7 +2289,7 @@ def __contains__(self, mu): def __iter__(self): r""" - Iterates through the infinite class of partition tuples of a fixed size. + Iterate through the infinite class of partition tuples of a fixed size. EXAMPLES:: @@ -2358,7 +2338,7 @@ class PartitionTuples_level_size(PartitionTuples): def __init__(self, level, size): r""" - Initializes this class. + Initialize this class. EXAMPLES:: @@ -2366,7 +2346,7 @@ def __init__(self, level, size): sage: TestSuite( PartitionTuples(level=4, size=5) ).run() # needs sage.libs.flint sage.libs.pari """ if not (level in NN and size in NN): - raise ValueError('n and level must be non-negative integers') + raise ValueError('n and level must be nonnegative integers') super().__init__(category=FiniteEnumeratedSets()) self._level = level self._size = size @@ -2414,7 +2394,7 @@ def __contains__(self, mu): def __iter__(self): r""" - Iterates through the finite class of partition tuples of a fixed level + Iterate through the finite class of partition tuples of a fixed level and a fixed size. EXAMPLES:: @@ -2660,8 +2640,8 @@ class RegularPartitionTuples_level(PartitionTuples_level): INPUT: - - ``level`` -- a non-negative Integer; the level - - ``regular`` -- a positive integer or a tuple of non-negative + - ``level`` -- nonnegative integer; the level + - ``regular`` -- positive integer or a tuple of nonnegative integers; if an integer, the highest multiplicity an entry may have in a component plus `1` with `0` representing `\infty`-regular (equivalently, partitions without restrictions) @@ -2720,7 +2700,7 @@ def __init__(self, level, regular): sage: TestSuite(RPT).run() # needs sage.libs.flint """ if level not in NN: - raise ValueError('level must be a non-negative integer') + raise ValueError('level must be a nonnegative integer') if not isinstance(regular, tuple): # This should not happen if called from RegularPartitionTuples regular = (regular,) * level @@ -2729,7 +2709,7 @@ def __init__(self, level, regular): else: category = FiniteEnumeratedSets() if any(r not in NN for r in regular): - raise ValueError('regular must be a tuple of non-negative integers') + raise ValueError('regular must be a tuple of nonnegative integers') if len(regular) != level: raise ValueError("regular must be a tuple with length {}".format(level)) PartitionTuples_level.__init__(self, level, category=category) @@ -2887,7 +2867,7 @@ def __init__(self, size, regular): sage: TestSuite(RPT).run() # needs sage.libs.flint """ if size not in NN: - raise ValueError('size must be a non-negative integer') + raise ValueError('size must be a nonnegative integer') RegularPartitionTuples.__init__(self, regular, category=InfiniteEnumeratedSets()) self._size = size @@ -2966,9 +2946,9 @@ class RegularPartitionTuples_level_size(PartitionTuples_level_size): INPUT: - - ``level`` -- a non-negative Integer; the level - - ``size`` -- a non-negative Integer; the size - - ``regular`` -- a positive integer or a tuple of non-negative + - ``level`` -- nonnegative integer; the level + - ``size`` -- nonnegative integer; the size + - ``regular`` -- positive integer or a tuple of nonnegative integers; if an integer, the highest multiplicity an entry may have in a component plus `1` with `0` representing `\infty`-regular (equivalently, partitions without restrictions) @@ -3017,7 +2997,7 @@ def __init__(self, level, size, regular): sage: TestSuite(RPT).run() # needs sage.libs.flint sage.libs.pari """ if size not in NN: - raise ValueError('size must be a non-negative integer') + raise ValueError('size must be a nonnegative integer') if not (level in ZZ and level > 0): raise ValueError('level must be a positive integer') if not isinstance(regular, tuple): @@ -3026,7 +3006,7 @@ def __init__(self, level, size, regular): if len(regular) != level: raise ValueError(f'regular must be a list with length {level}') if any(i not in NN for i in regular): - raise ValueError('regular must be a list of non-negative integers') + raise ValueError('regular must be a list of nonnegative integers') PartitionTuples_level_size.__init__(self, level, size) self._ell = regular diff --git a/src/sage/combinat/partitions.pyx b/src/sage/combinat/partitions.pyx index e193c7e5723..f453694a90c 100644 --- a/src/sage/combinat/partitions.pyx +++ b/src/sage/combinat/partitions.pyx @@ -100,7 +100,7 @@ cdef inline ZS1_step(list P, int n, int *m, int *h): INPUT: - - ``P`` -- a list of size `n` storing a partition of `n` + - ``P`` -- list of size `n` storing a partition of `n` - ``n`` -- integer; the sum of the elements of the partition stored in ``P`` @@ -207,7 +207,7 @@ def ZS1_next(list P): INPUT: - - ``P`` -- a list encoding a partition of an integer `n` in descending order + - ``P`` -- list encoding a partition of an integer `n` in descending order (i.e., `P_i \geq P_{i+1}`) EXAMPLES:: @@ -245,7 +245,7 @@ def ZS1_next(list P): def ZS1_iterator_nk(int n, int k): r""" - An iterator for the partitions of ``n`` of length at most ``k`` (in the + An iterator for the partitions of `n` of length at most `k` (in the decreasing lexicographic order) which returns lists and not objects of type :class:`~sage.combinat.partition.Partition`. @@ -345,7 +345,7 @@ cdef inline ZS2_step(list P, int n, int *m, int *h): INPUT: - - ``P`` -- a list of size `n` storing a partition of `n` + - ``P`` -- list of size `n` storing a partition of `n` - ``n`` -- integer; the sum of the elements of the partition stored in ``P`` @@ -447,7 +447,7 @@ def ZS2_next(list P): INPUT: - - ``P`` -- a list encoding a partition of an integer `n` in descending order + - ``P`` -- list encoding a partition of an integer `n` in descending order (i.e., `P_i \geq P_{i+1}`) EXAMPLES:: @@ -488,7 +488,7 @@ cdef inline AccelDesc_step(list P, int n, int* m, int* h): INPUT: - - ``P`` -- a list of size `n` storing a partition of `n` + - ``P`` -- list of size `n` storing a partition of `n` - ``n`` -- integer; the sum of the elements of the partition stored in ``P`` @@ -602,7 +602,7 @@ def AccelDesc_next(list P): INPUT: - - ``P`` -- a list encoding a partition of an integer `n` in descending order + - ``P`` -- list encoding a partition of an integer `n` in descending order (i.e., `P_i \geq P_{i+1}`) EXAMPLES:: @@ -702,7 +702,7 @@ def AccelAsc_next(list P): INPUT: - - ``P`` -- a list encoding a partition of an integer `n` in ascending order + - ``P`` -- list encoding a partition of an integer `n` in ascending order (i.e., `P_i \leq P_{i+1}`) EXAMPLES:: diff --git a/src/sage/combinat/path_tableaux/dyck_path.py b/src/sage/combinat/path_tableaux/dyck_path.py index c3c24929e99..232b87673d7 100644 --- a/src/sage/combinat/path_tableaux/dyck_path.py +++ b/src/sage/combinat/path_tableaux/dyck_path.py @@ -45,10 +45,10 @@ class DyckPath(PathTableau): INPUT: - * a sequence of nonnegative integers - * a two row standard skew tableau - * a Dyck word - * a noncrossing perfect matching + - a sequence of nonnegative integers + - a two row standard skew tableau + - a Dyck word + - a noncrossing perfect matching EXAMPLES:: @@ -272,7 +272,7 @@ def is_skew(self): @combinatorial_map(name='to Dyck word') def to_DyckWord(self): r""" - Converts ``self`` to a Dyck word. + Convert ``self`` to a Dyck word. EXAMPLES:: diff --git a/src/sage/combinat/path_tableaux/path_tableau.py b/src/sage/combinat/path_tableaux/path_tableau.py index 9809019208e..9d9177ee355 100644 --- a/src/sage/combinat/path_tableaux/path_tableau.py +++ b/src/sage/combinat/path_tableaux/path_tableau.py @@ -223,8 +223,8 @@ def cactus(self,i,j): INPUT: - - ``i`` -- a positive integer - - ``j`` -- a positive integer weakly greater than ``i`` + - ``i`` -- positive integer + - ``j`` -- positive integer weakly greater than `i` EXAMPLES:: @@ -508,7 +508,7 @@ def __init__(self, T): def _repr_(self): r""" - Return a string representation of ``self`` + Return a string representation of ``self``. TESTS:: @@ -576,7 +576,7 @@ def __ne__(self, other): def _latex_(self): r""" - Return a `\LaTeX` representation of ``self`` + Return a `\LaTeX` representation of ``self``. EXAMPLES:: @@ -603,7 +603,6 @@ def _latex_(self): & & & & & 0 & 1 & \frac{2}{3} & 1 & 1 & 1 & 0\\ & & & & & & 0 & 1 & 3 & 4 & 5 & 1 & 0 \end{array} - """ D = self.diagram m = len(D[-1]) @@ -626,7 +625,7 @@ def __len__(self): def _ascii_art_(self): r""" - Return an ascii art representation of ``self`` + Return an ascii art representation of ``self``. TESTS:: @@ -661,7 +660,7 @@ def _ascii_art_(self): def _unicode_art_(self): r""" - Return a unicode art representation of ``self`` + Return a unicode art representation of ``self``. TESTS:: diff --git a/src/sage/combinat/path_tableaux/semistandard.py b/src/sage/combinat/path_tableaux/semistandard.py index 040710d48f0..368caf54145 100644 --- a/src/sage/combinat/path_tableaux/semistandard.py +++ b/src/sage/combinat/path_tableaux/semistandard.py @@ -97,7 +97,7 @@ class SemistandardPathTableau(PathTableau): r""" - An instance is a sequence of lists. Usually the entries will be non-negative integers + An instance is a sequence of lists. Usually the entries will be nonnegative integers in which case this is the chain of partitions of a (skew) semistandard tableau. In general the entries are elements of an ordered abelian group; each list is weakly decreasing and successive lists are interleaved. @@ -255,7 +255,7 @@ def is_skew(self): def is_integral(self) -> bool: """ - Return ``True`` if all entries are non-negative integers. + Return ``True`` if all entries are nonnegative integers. EXAMPLES:: diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index aa11a40b7af..6f6fa67787e 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -132,7 +132,7 @@ def __classcall_private__(cls, parts): The function checks that the given list or permutation is a valid perfect matching (i.e. a list of pairs with pairwise disjoint elements or a fix point free involution) and raises - a :class:`ValueError` otherwise:: + a :exc:`ValueError` otherwise:: sage: PerfectMatching([(1, 2, 3), (4, 5)]) Traceback (most recent call last): @@ -265,7 +265,6 @@ def standardization(self): sage: n = PerfectMatching([('c','b'),('d','f'),('e','a')]) sage: n.standardization() [(1, 5), (2, 3), (4, 6)] - """ P = PerfectMatchings(2 * len(self)) return P(SetPartition.standardization(self)) @@ -297,7 +296,7 @@ def loops_iterator(self, other=None): INPUT: - - ``other`` -- a perfect matching of the same set of ``self``. + - ``other`` -- a perfect matching of the same set of ``self`` (if the second argument is empty, the method :meth:`an_element` is called on the parent of the first) @@ -346,7 +345,7 @@ def loops(self, other=None): INPUT: - - ``other`` -- a perfect matching of the same set of ``self``. + - ``other`` -- a perfect matching of the same set of ``self`` (if the second argument is empty, the method :meth:`an_element` is called on the parent of the first) @@ -395,7 +394,7 @@ def loop_type(self, other=None): INPUT: - - ``other`` -- a perfect matching of the same set of ``self``. + - ``other`` -- a perfect matching of the same set of ``self`` (if the second argument is empty, the method :meth:`an_element` is called on the parent of the first) @@ -428,7 +427,7 @@ def number_of_loops(self, other=None): INPUT: - - ``other`` -- a perfect matching of the same set of ``self``. + - ``other`` -- a perfect matching of the same set of ``self`` (if the second argument is empty, the method :meth:`an_element` is called on the parent of the first) @@ -473,9 +472,7 @@ def to_graph(self): r""" Return the graph corresponding to the perfect matching. - OUTPUT: - - The realization of ``self`` as a graph. + OUTPUT: the realization of ``self`` as a graph EXAMPLES:: @@ -497,9 +494,7 @@ def to_noncrossing_set_partition(self): corresponding to the perfect matching if the perfect matching is noncrossing, and otherwise gives an error. - OUTPUT: - - The realization of ``self`` as a noncrossing set partition. + OUTPUT: the realization of ``self`` as a noncrossing set partition EXAMPLES:: diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 1ca90eff943..53901bb3c17 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -32,110 +32,110 @@ :widths: 30, 70 :delim: | - :meth:`~sage.combinat.permutation.Permutation.left_action_product` | Returns the product of ``self`` with another permutation, in which the other permutation is applied first. - :meth:`~sage.combinat.permutation.Permutation.right_action_product` | Returns the product of ``self`` with another permutation, in which ``self`` is applied first. - :meth:`~sage.combinat.permutation.Permutation.size` | Returns the size of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.cycle_string` | Returns the disjoint-cycles representation of ``self`` as string. - :meth:`~sage.combinat.permutation.Permutation.next` | Returns the permutation that follows ``self`` in lexicographic order (in the same symmetric group as ``self``). - :meth:`~sage.combinat.permutation.Permutation.prev` | Returns the permutation that comes directly before ``self`` in lexicographic order (in the same symmetric group as ``self``). - :meth:`~sage.combinat.permutation.Permutation.to_tableau_by_shape` | Returns a tableau of shape ``shape`` with the entries in ``self``. - :meth:`~sage.combinat.permutation.Permutation.to_cycles` | Returns the permutation ``self`` as a list of disjoint cycles. + :meth:`~sage.combinat.permutation.Permutation.left_action_product` | Return the product of ``self`` with another permutation, in which the other permutation is applied first. + :meth:`~sage.combinat.permutation.Permutation.right_action_product` | Return the product of ``self`` with another permutation, in which ``self`` is applied first. + :meth:`~sage.combinat.permutation.Permutation.size` | Return the size of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.cycle_string` | Return the disjoint-cycles representation of ``self`` as string. + :meth:`~sage.combinat.permutation.Permutation.next` | Return the permutation that follows ``self`` in lexicographic order (in the same symmetric group as ``self``). + :meth:`~sage.combinat.permutation.Permutation.prev` | Return the permutation that comes directly before ``self`` in lexicographic order (in the same symmetric group as ``self``). + :meth:`~sage.combinat.permutation.Permutation.to_tableau_by_shape` | Return a tableau of shape ``shape`` with the entries in ``self``. + :meth:`~sage.combinat.permutation.Permutation.to_cycles` | Return the permutation ``self`` as a list of disjoint cycles. :meth:`~sage.combinat.permutation.Permutation.forget_cycles` | Return ``self`` under the forget cycle map. - :meth:`~sage.combinat.permutation.Permutation.to_permutation_group_element` | Returns a ``PermutationGroupElement`` equal to ``self``. - :meth:`~sage.combinat.permutation.Permutation.signature` | Returns the signature of the permutation ``sef``. - :meth:`~sage.combinat.permutation.Permutation.is_even` | Returns ``True`` if the permutation ``self`` is even, and ``False`` otherwise. - :meth:`~sage.combinat.permutation.Permutation.to_matrix` | Returns a matrix representing the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.rank` | Returns the rank of ``self`` in lexicographic ordering (on the symmetric group containing ``self``). - :meth:`~sage.combinat.permutation.Permutation.to_inversion_vector` | Returns the inversion vector of a permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.inversions` | Returns a list of the inversions of permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.stack_sort` | Returns the permutation obtained by sorting ``self`` through one stack. + :meth:`~sage.combinat.permutation.Permutation.to_permutation_group_element` | Return a ``PermutationGroupElement`` equal to ``self``. + :meth:`~sage.combinat.permutation.Permutation.signature` | Return the signature of the permutation ``sef``. + :meth:`~sage.combinat.permutation.Permutation.is_even` | Return ``True`` if the permutation ``self`` is even, and ``False`` otherwise. + :meth:`~sage.combinat.permutation.Permutation.to_matrix` | Return a matrix representing the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.rank` | Return the rank of ``self`` in lexicographic ordering (on the symmetric group containing ``self``). + :meth:`~sage.combinat.permutation.Permutation.to_inversion_vector` | Return the inversion vector of a permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.inversions` | Return a list of the inversions of permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.stack_sort` | Return the permutation obtained by sorting ``self`` through one stack. :meth:`~sage.combinat.permutation.Permutation.to_digraph` | Return a digraph representation of ``self``. - :meth:`~sage.combinat.permutation.Permutation.show` | Displays the permutation as a drawing. - :meth:`~sage.combinat.permutation.Permutation.number_of_inversions` | Returns the number of inversions in the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.noninversions` | Returns the ``k``-noninversions in the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.number_of_noninversions` | Returns the number of ``k``-noninversions in the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.length` | Returns the Coxeter length of a permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.inverse` | Returns the inverse of a permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.ishift` | Returns the ``i``-shift of ``self``. - :meth:`~sage.combinat.permutation.Permutation.iswitch` | Returns the ``i``-switch of ``self``. - :meth:`~sage.combinat.permutation.Permutation.runs` | Returns a list of the runs in the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.longest_increasing_subsequence_length` | Returns the length of the longest increasing subsequences of ``self``. - :meth:`~sage.combinat.permutation.Permutation.longest_increasing_subsequences` | Returns the list of the longest increasing subsequences of ``self``. - :meth:`~sage.combinat.permutation.Permutation.longest_increasing_subsequences_number` | Returns the number of longest increasing subsequences - :meth:`~sage.combinat.permutation.Permutation.cycle_type` | Returns the cycle type of ``self`` as a partition of ``len(self)``. - :meth:`~sage.combinat.permutation.Permutation.foata_bijection` | Returns the image of the permutation ``self`` under the Foata bijection `\phi`. - :meth:`~sage.combinat.permutation.Permutation.foata_bijection_inverse` | Returns the image of the permutation ``self`` under the inverse of the Foata bijection `\phi`. - :meth:`~sage.combinat.permutation.Permutation.fundamental_transformation` | Returns the image of the permutation ``self`` under the Renyi-Foata-Schuetzenberger fundamental transformation. - :meth:`~sage.combinat.permutation.Permutation.fundamental_transformation_inverse` | Returns the image of the permutation ``self`` under the inverse of the Renyi-Foata-Schuetzenberger fundamental transformation. + :meth:`~sage.combinat.permutation.Permutation.show` | Display the permutation as a drawing. + :meth:`~sage.combinat.permutation.Permutation.number_of_inversions` | Return the number of inversions in the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.noninversions` | Return the ``k``-noninversions in the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.number_of_noninversions` | Return the number of ``k``-noninversions in the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.length` | Return the Coxeter length of a permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.inverse` | Return the inverse of a permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.ishift` | Return the ``i``-shift of ``self``. + :meth:`~sage.combinat.permutation.Permutation.iswitch` | Return the ``i``-switch of ``self``. + :meth:`~sage.combinat.permutation.Permutation.runs` | Return a list of the runs in the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.longest_increasing_subsequence_length` | Return the length of the longest increasing subsequences of ``self``. + :meth:`~sage.combinat.permutation.Permutation.longest_increasing_subsequences` | Return the list of the longest increasing subsequences of ``self``. + :meth:`~sage.combinat.permutation.Permutation.longest_increasing_subsequences_number` | Return the number of longest increasing subsequences + :meth:`~sage.combinat.permutation.Permutation.cycle_type` | Return the cycle type of ``self`` as a partition of ``len(self)``. + :meth:`~sage.combinat.permutation.Permutation.foata_bijection` | Return the image of the permutation ``self`` under the Foata bijection `\phi`. + :meth:`~sage.combinat.permutation.Permutation.foata_bijection_inverse` | Return the image of the permutation ``self`` under the inverse of the Foata bijection `\phi`. + :meth:`~sage.combinat.permutation.Permutation.fundamental_transformation` | Return the image of the permutation ``self`` under the Renyi-Foata-Schuetzenberger fundamental transformation. + :meth:`~sage.combinat.permutation.Permutation.fundamental_transformation_inverse` | Return the image of the permutation ``self`` under the inverse of the Renyi-Foata-Schuetzenberger fundamental transformation. :meth:`~sage.combinat.permutation.Permutation.destandardize` | Return destandardization of ``self`` with respect to ``weight`` and ``ordered_alphabet``. - :meth:`~sage.combinat.permutation.Permutation.to_lehmer_code` | Returns the Lehmer code of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.to_lehmer_cocode` | Returns the Lehmer cocode of ``self``. - :meth:`~sage.combinat.permutation.Permutation.reduced_word` | Returns the reduced word of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.reduced_words` | Returns a list of the reduced words of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.to_lehmer_code` | Return the Lehmer code of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.to_lehmer_cocode` | Return the Lehmer cocode of ``self``. + :meth:`~sage.combinat.permutation.Permutation.reduced_word` | Return the reduced word of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.reduced_words` | Return a list of the reduced words of the permutation ``self``. :meth:`~sage.combinat.permutation.Permutation.reduced_words_iterator` | An iterator for the reduced words of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.reduced_word_lexmin` | Returns a lexicographically minimal reduced word of a permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.fixed_points` | Returns a list of the fixed points of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.is_derangement` | Returns ``True`` if the permutation ``self`` is a derangement, and ``False`` otherwise. - :meth:`~sage.combinat.permutation.Permutation.is_simple` | Returns ``True`` if the permutation ``self`` is simple, and ``False`` otherwise. - :meth:`~sage.combinat.permutation.Permutation.number_of_fixed_points` | Returns the number of fixed points of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.recoils` | Returns the list of the positions of the recoils of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.number_of_recoils` | Returns the number of recoils of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.recoils_composition` | Returns the composition corresponding to the recoils of ``self``. - :meth:`~sage.combinat.permutation.Permutation.descents` | Returns the list of the descents of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.idescents` | Returns a list of the idescents of ``self``. - :meth:`~sage.combinat.permutation.Permutation.idescents_signature` | Returns the list obtained by mapping each position in ``self`` to `-1` if it is an idescent and `1` if it is not an idescent. - :meth:`~sage.combinat.permutation.Permutation.number_of_descents` | Returns the number of descents of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.number_of_idescents` | Returns the number of idescents of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.descents_composition` | Returns the composition corresponding to the descents of ``self``. - :meth:`~sage.combinat.permutation.Permutation.descent_polynomial` | Returns the descent polynomial of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.major_index` | Returns the major index of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.imajor_index` | Returns the inverse major index of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.to_major_code` | Returns the major code of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.peaks` | Returns a list of the peaks of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.number_of_peaks` | Returns the number of peaks of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.saliances` | Returns a list of the saliances of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.number_of_saliances` | Returns the number of saliances of the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.bruhat_lequal` | Returns ``True`` if self is less or equal to ``p2`` in the Bruhat order. - :meth:`~sage.combinat.permutation.Permutation.weak_excedences` | Returns all the numbers ``self[i]`` such that ``self[i] >= i+1``. - :meth:`~sage.combinat.permutation.Permutation.bruhat_inversions` | Returns the list of inversions of ``self`` such that the application of this inversion to ``self`` decrements its number of inversions. - :meth:`~sage.combinat.permutation.Permutation.bruhat_inversions_iterator` | Returns an iterator over Bruhat inversions of ``self``. - :meth:`~sage.combinat.permutation.Permutation.bruhat_succ` | Returns a list of the permutations covering ``self`` in the Bruhat order. + :meth:`~sage.combinat.permutation.Permutation.reduced_word_lexmin` | Return a lexicographically minimal reduced word of a permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.fixed_points` | Return a list of the fixed points of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.is_derangement` | Return ``True`` if the permutation ``self`` is a derangement, and ``False`` otherwise. + :meth:`~sage.combinat.permutation.Permutation.is_simple` | Return ``True`` if the permutation ``self`` is simple, and ``False`` otherwise. + :meth:`~sage.combinat.permutation.Permutation.number_of_fixed_points` | Return the number of fixed points of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.recoils` | Return the list of the positions of the recoils of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.number_of_recoils` | Return the number of recoils of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.recoils_composition` | Return the composition corresponding to the recoils of ``self``. + :meth:`~sage.combinat.permutation.Permutation.descents` | Return the list of the descents of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.idescents` | Return a list of the idescents of ``self``. + :meth:`~sage.combinat.permutation.Permutation.idescents_signature` | Return the list obtained by mapping each position in ``self`` to `-1` if it is an idescent and `1` if it is not an idescent. + :meth:`~sage.combinat.permutation.Permutation.number_of_descents` | Return the number of descents of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.number_of_idescents` | Return the number of idescents of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.descents_composition` | Return the composition corresponding to the descents of ``self``. + :meth:`~sage.combinat.permutation.Permutation.descent_polynomial` | Return the descent polynomial of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.major_index` | Return the major index of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.imajor_index` | Return the inverse major index of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.to_major_code` | Return the major code of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.peaks` | Return a list of the peaks of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.number_of_peaks` | Return the number of peaks of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.saliances` | Return a list of the saliances of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.number_of_saliances` | Return the number of saliances of the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.bruhat_lequal` | Return ``True`` if ``self`` is less or equal to ``p2`` in the Bruhat order. + :meth:`~sage.combinat.permutation.Permutation.weak_excedences` | Return all the numbers ``self[i]`` such that ``self[i] >= i+1``. + :meth:`~sage.combinat.permutation.Permutation.bruhat_inversions` | Return the list of inversions of ``self`` such that the application of this inversion to ``self`` decrements its number of inversions. + :meth:`~sage.combinat.permutation.Permutation.bruhat_inversions_iterator` | Return an iterator over Bruhat inversions of ``self``. + :meth:`~sage.combinat.permutation.Permutation.bruhat_succ` | Return a list of the permutations covering ``self`` in the Bruhat order. :meth:`~sage.combinat.permutation.Permutation.bruhat_succ_iterator` | An iterator for the permutations covering ``self`` in the Bruhat order. - :meth:`~sage.combinat.permutation.Permutation.bruhat_pred` | Returns a list of the permutations covered by ``self`` in the Bruhat order. + :meth:`~sage.combinat.permutation.Permutation.bruhat_pred` | Return a list of the permutations covered by ``self`` in the Bruhat order. :meth:`~sage.combinat.permutation.Permutation.bruhat_pred_iterator` | An iterator for the permutations covered by ``self`` in the Bruhat order. - :meth:`~sage.combinat.permutation.Permutation.bruhat_smaller` | Returns the combinatorial class of permutations smaller than or equal to ``self`` in the Bruhat order. - :meth:`~sage.combinat.permutation.Permutation.bruhat_greater` | Returns the combinatorial class of permutations greater than or equal to ``self`` in the Bruhat order. - :meth:`~sage.combinat.permutation.Permutation.permutohedron_lequal` | Returns ``True`` if ``self`` is less or equal to ``p2`` in the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.permutohedron_succ` | Returns a list of the permutations covering ``self`` in the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.permutohedron_pred` | Returns a list of the permutations covered by ``self`` in the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.permutohedron_smaller` | Returns a list of permutations smaller than or equal to ``self`` in the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.permutohedron_greater` | Returns a list of permutations greater than or equal to ``self`` in the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.right_permutohedron_interval_iterator` | Returns an iterator over permutations in an interval of the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.right_permutohedron_interval` | Returns a list of permutations in an interval of the permutohedron order. - :meth:`~sage.combinat.permutation.Permutation.has_pattern` | Tests whether the permutation ``self`` matches the pattern. - :meth:`~sage.combinat.permutation.Permutation.avoids` | Tests whether the permutation ``self`` avoids the pattern. - :meth:`~sage.combinat.permutation.Permutation.pattern_positions` | Returns the list of positions where the pattern ``patt`` appears in ``self``. - :meth:`~sage.combinat.permutation.Permutation.reverse` | Returns the permutation obtained by reversing the 1-line notation of ``self``. - :meth:`~sage.combinat.permutation.Permutation.complement` | Returns the complement of the permutation which is obtained by replacing each value `x` in the 1-line notation of ``self`` with `n - x + 1`. - :meth:`~sage.combinat.permutation.Permutation.permutation_poset` | Returns the permutation poset of ``self``. - :meth:`~sage.combinat.permutation.Permutation.dict` | Returns a dictionary corresponding to the permutation ``self``. - :meth:`~sage.combinat.permutation.Permutation.action` | Returns the action of the permutation ``self`` on a list. - :meth:`~sage.combinat.permutation.Permutation.robinson_schensted` | Returns the pair of standard tableaux obtained by running the Robinson-Schensted Algorithm on ``self``. - :meth:`~sage.combinat.permutation.Permutation.left_tableau` | Returns the left standard tableau after performing the RSK algorithm. - :meth:`~sage.combinat.permutation.Permutation.right_tableau` | Returns the right standard tableau after performing the RSK algorithm. - :meth:`~sage.combinat.permutation.Permutation.increasing_tree` | Returns the increasing tree of ``self``. - :meth:`~sage.combinat.permutation.Permutation.increasing_tree_shape` | Returns the shape of the increasing tree of ``self``. - :meth:`~sage.combinat.permutation.Permutation.binary_search_tree` | Returns the binary search tree of ``self``. - :meth:`~sage.combinat.permutation.Permutation.sylvester_class` | Iterates over the equivalence class of ``self`` under sylvester congruence - :meth:`~sage.combinat.permutation.Permutation.RS_partition` | Returns the shape of the tableaux obtained by the RSK algorithm. - :meth:`~sage.combinat.permutation.Permutation.remove_extra_fixed_points` | Returns the permutation obtained by removing any fixed points at the end of ``self``. - :meth:`~sage.combinat.permutation.Permutation.retract_plain` | Returns the plain retract of ``self`` to a smaller symmetric group `S_m`. - :meth:`~sage.combinat.permutation.Permutation.retract_direct_product` | Returns the direct-product retract of ``self`` to a smaller symmetric group `S_m`. - :meth:`~sage.combinat.permutation.Permutation.retract_okounkov_vershik` | Returns the Okounkov-Vershik retract of ``self`` to a smaller symmetric group `S_m`. - :meth:`~sage.combinat.permutation.Permutation.hyperoctahedral_double_coset_type` | Returns the coset-type of ``self`` as a partition. - :meth:`~sage.combinat.permutation.Permutation.binary_search_tree_shape` | Returns the shape of the binary search tree of ``self`` (a non labelled binary tree). - :meth:`~sage.combinat.permutation.Permutation.shifted_concatenation` | Returns the right (or left) shifted concatenation of ``self`` with a permutation ``other``. - :meth:`~sage.combinat.permutation.Permutation.shifted_shuffle` | Returns the shifted shuffle of ``self`` with a permutation ``other``. + :meth:`~sage.combinat.permutation.Permutation.bruhat_smaller` | Return the combinatorial class of permutations smaller than or equal to ``self`` in the Bruhat order. + :meth:`~sage.combinat.permutation.Permutation.bruhat_greater` | Return the combinatorial class of permutations greater than or equal to ``self`` in the Bruhat order. + :meth:`~sage.combinat.permutation.Permutation.permutohedron_lequal` | Return ``True`` if ``self`` is less or equal to ``p2`` in the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.permutohedron_succ` | Return a list of the permutations covering ``self`` in the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.permutohedron_pred` | Return a list of the permutations covered by ``self`` in the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.permutohedron_smaller` | Return a list of permutations smaller than or equal to ``self`` in the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.permutohedron_greater` | Return a list of permutations greater than or equal to ``self`` in the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.right_permutohedron_interval_iterator` | Return an iterator over permutations in an interval of the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.right_permutohedron_interval` | Return a list of permutations in an interval of the permutohedron order. + :meth:`~sage.combinat.permutation.Permutation.has_pattern` | Test whether the permutation ``self`` matches the pattern. + :meth:`~sage.combinat.permutation.Permutation.avoids` | Test whether the permutation ``self`` avoids the pattern. + :meth:`~sage.combinat.permutation.Permutation.pattern_positions` | Return the list of positions where the pattern ``patt`` appears in ``self``. + :meth:`~sage.combinat.permutation.Permutation.reverse` | Return the permutation obtained by reversing the 1-line notation of ``self``. + :meth:`~sage.combinat.permutation.Permutation.complement` | Return the complement of the permutation which is obtained by replacing each value `x` in the 1-line notation of ``self`` with `n - x + 1`. + :meth:`~sage.combinat.permutation.Permutation.permutation_poset` | Return the permutation poset of ``self``. + :meth:`~sage.combinat.permutation.Permutation.dict` | Return a dictionary corresponding to the permutation ``self``. + :meth:`~sage.combinat.permutation.Permutation.action` | Return the action of the permutation ``self`` on a list. + :meth:`~sage.combinat.permutation.Permutation.robinson_schensted` | Return the pair of standard tableaux obtained by running the Robinson-Schensted Algorithm on ``self``. + :meth:`~sage.combinat.permutation.Permutation.left_tableau` | Return the left standard tableau after performing the RSK algorithm. + :meth:`~sage.combinat.permutation.Permutation.right_tableau` | Return the right standard tableau after performing the RSK algorithm. + :meth:`~sage.combinat.permutation.Permutation.increasing_tree` | Return the increasing tree of ``self``. + :meth:`~sage.combinat.permutation.Permutation.increasing_tree_shape` | Return the shape of the increasing tree of ``self``. + :meth:`~sage.combinat.permutation.Permutation.binary_search_tree` | Return the binary search tree of ``self``. + :meth:`~sage.combinat.permutation.Permutation.sylvester_class` | Iterate over the equivalence class of ``self`` under sylvester congruence + :meth:`~sage.combinat.permutation.Permutation.RS_partition` | Return the shape of the tableaux obtained by the RSK algorithm. + :meth:`~sage.combinat.permutation.Permutation.remove_extra_fixed_points` | Return the permutation obtained by removing any fixed points at the end of ``self``. + :meth:`~sage.combinat.permutation.Permutation.retract_plain` | Return the plain retract of ``self`` to a smaller symmetric group `S_m`. + :meth:`~sage.combinat.permutation.Permutation.retract_direct_product` | Return the direct-product retract of ``self`` to a smaller symmetric group `S_m`. + :meth:`~sage.combinat.permutation.Permutation.retract_okounkov_vershik` | Return the Okounkov-Vershik retract of ``self`` to a smaller symmetric group `S_m`. + :meth:`~sage.combinat.permutation.Permutation.hyperoctahedral_double_coset_type` | Return the coset-type of ``self`` as a partition. + :meth:`~sage.combinat.permutation.Permutation.binary_search_tree_shape` | Return the shape of the binary search tree of ``self`` (a non labelled binary tree). + :meth:`~sage.combinat.permutation.Permutation.shifted_concatenation` | Return the right (or left) shifted concatenation of ``self`` with a permutation ``other``. + :meth:`~sage.combinat.permutation.Permutation.shifted_shuffle` | Return the shifted shuffle of ``self`` with a permutation ``other``. **Other classes defined in this file** @@ -182,21 +182,21 @@ :widths: 30, 70 :delim: | - :meth:`from_major_code` | Returns the permutation corresponding to major code ``mc``. - :meth:`from_permutation_group_element` | Returns a Permutation give a ``PermutationGroupElement`` ``pge``. - :meth:`from_rank` | Returns the permutation with the specified lexicographic rank. - :meth:`from_inversion_vector` | Returns the permutation corresponding to inversion vector ``iv``. - :meth:`from_cycles` | Returns the permutation with given disjoint-cycle representation ``cycles``. - :meth:`from_lehmer_code` | Returns the permutation with Lehmer code ``lehmer``. - :meth:`from_reduced_word` | Returns the permutation corresponding to the reduced word ``rw``. - :meth:`bistochastic_as_sum_of_permutations` | Returns a given bistochastic matrix as a nonnegative linear combination of permutations. - :meth:`bounded_affine_permutation` | Returns a partial permutation representing the bounded affine permutation of a matrix. - :meth:`descents_composition_list` | Returns a list of all the permutations in a given descent class (i. e., having a given descents composition). - :meth:`descents_composition_first` | Returns the smallest element of a descent class. - :meth:`descents_composition_last` | Returns the largest element of a descent class. - :meth:`bruhat_lequal` | Returns ``True`` if ``p1`` is less or equal to ``p2`` in the Bruhat order. - :meth:`permutohedron_lequal` | Returns ``True`` if ``p1`` is less or equal to ``p2`` in the permutohedron order. - :meth:`to_standard` | Returns a standard permutation corresponding to the permutation ``self``. + :meth:`from_major_code` | Return the permutation corresponding to major code ``mc``. + :meth:`from_permutation_group_element` | Return a Permutation give a ``PermutationGroupElement`` ``pge``. + :meth:`from_rank` | Return the permutation with the specified lexicographic rank. + :meth:`from_inversion_vector` | Return the permutation corresponding to inversion vector ``iv``. + :meth:`from_cycles` | Return the permutation with given disjoint-cycle representation ``cycles``. + :meth:`from_lehmer_code` | Return the permutation with Lehmer code ``lehmer``. + :meth:`from_reduced_word` | Return the permutation corresponding to the reduced word ``rw``. + :meth:`bistochastic_as_sum_of_permutations` | Return a given bistochastic matrix as a nonnegative linear combination of permutations. + :meth:`bounded_affine_permutation` | Return a partial permutation representing the bounded affine permutation of a matrix. + :meth:`descents_composition_list` | Return a list of all the permutations in a given descent class (i. e., having a given descents composition). + :meth:`descents_composition_first` | Return the smallest element of a descent class. + :meth:`descents_composition_last` | Return the largest element of a descent class. + :meth:`bruhat_lequal` | Return ``True`` if ``p1`` is less or equal to ``p2`` in the Bruhat order. + :meth:`permutohedron_lequal` | Return ``True`` if ``p1`` is less or equal to ``p2`` in the permutohedron order. + :meth:`to_standard` | Return a standard permutation corresponding to the permutation ``self``. AUTHORS: @@ -290,7 +290,7 @@ class Permutation(CombinatorialElement): INPUT: - - ``l`` -- Can be any one of the following: + - ``l`` -- can be any one of the following: - an instance of :class:`Permutation`, @@ -310,15 +310,14 @@ class Permutation(CombinatorialElement): Robinson-Schensted algorithm. - ``check`` -- boolean (default: ``True``); whether to check that input is - correct. Slows the function down, but ensures that nothing bad happens. - This is set to ``True`` by default. + correct; slows the function down, but ensures that nothing bad happens - - ``algorithm`` -- string (default: ``lex``); the algorithm used to generate - the permutations. Supported algorithms are: + - ``algorithm`` -- string (default: ``'lex'``); the algorithm used to + generate the permutations. Supported algorithms are: - - ``lex``: lexicographic order generation, this is the default algorithm. + - ``'lex'``: lexicographic order generation, this is the default algorithm - - ``sjt``: Steinhaus-Johnson-Trotter algorithm to generate permutations + - ``'sjt'``: Steinhaus-Johnson-Trotter algorithm to generate permutations using only transposition of two elements in the list. It is highly recommended to set ``check=True`` (default value). @@ -511,9 +510,8 @@ def __classcall_private__(cls, l, algorithm='lex', sjt=None, check=True): return RSK_inverse(P, Q, 'permutation') # if it's a tuple or nonempty list of tuples, also assume cycle # notation - elif isinstance(l, tuple) or \ - (isinstance(l, list) and l and - all(isinstance(x, tuple) for x in l)): + elif isinstance(l, tuple) or (isinstance(l, list) and l and + all(isinstance(x, tuple) for x in l)): if l and (isinstance(l[0], (int, Integer)) or len(l[0]) > 0): if isinstance(l[0], tuple): n = max(max(x) for x in l) @@ -538,19 +536,19 @@ def __init__(self, parent, l, algorithm='lex', sjt=None, check=True): INPUT: - - ``l`` -- a list of ``int`` variables + - ``l`` -- list of ``int`` variables - ``check`` -- boolean (default: ``True``); whether to check that input is correct. Slows the function down, but ensures that nothing bad happens. - - ``algorithm`` -- string (default: ``lex``); the algorithm used to + - ``algorithm`` -- string (default: ``'lex'``); the algorithm used to generate the permutations. Supported algorithms are: - - ``lex``: lexicographic order generation, this is the default - algorithm. + - ``'lex'``: lexicographic order generation, this is the default + algorithm - - ``sjt``: Steinhaus-Johnson-Trotter algorithm to generate + - ``'sjt'``: Steinhaus-Johnson-Trotter algorithm to generate permutations using only transposition of two elements in the list. It is highly recommended to set ``check=True`` (default value). @@ -597,7 +595,7 @@ def __init__(self, parent, l, algorithm='lex', sjt=None, check=True): raise ValueError("unsupported algorithm %s; expected 'lex' or 'sjt'" % self._algorithm) - if check and len(l) > 0: + if check and l: # Make a copy to sort later lst = list(l) @@ -616,14 +614,14 @@ def __init__(self, parent, l, algorithm='lex', sjt=None, check=True): # Is the maximum element of the permutation the length of input, # or is some integer missing ? if int(lst[-1]) != len(lst): - raise ValueError("the permutation has length "+str(len(lst)) + - " but its maximal element is " + - str(int(lst[-1])) + ". Some element may be " + + raise ValueError(f"the permutation has length {len(lst)} " + + f"but its maximal element is {int(lst[-1])}" + + ". Some element may be " + "repeated, or an element is missing, but " + "there is something wrong with its length.") # Do the elements appear only once ? - previous = lst[0]-1 + previous = lst[0] - 1 for i in lst: if i == previous: @@ -1654,7 +1652,7 @@ def _to_inversion_vector_orig(self): [2, 3, 6, 4, 0, 2, 2, 1, 0] """ p = self._list - iv = [0]*len(p) + iv = [0] * len(p) for i in range(len(p)): for pj in p: if pj > i+1: @@ -1683,8 +1681,8 @@ def _to_inversion_vector_small(self): """ p = self._list l = len(p)+1 - iv = [0]*l - checked = [1]*l + iv = [0] * l + checked = [1] * l for pi in reversed(p): checked[pi] = 0 iv[pi] = sum(checked[pi:]) @@ -1739,8 +1737,8 @@ def merge_and_countv(ivA_A, ivB_B): def base_case(L): s = sorted(L) d = {j: i for i, j in enumerate(s)} - iv = [0]*len(L) - checked = [1]*len(L) + iv = [0] * len(L) + checked = [1] * len(L) for pi in reversed(L): dpi = d[pi] checked[dpi] = 0 @@ -1840,7 +1838,7 @@ def to_digraph(self) -> DiGraph: return DiGraph([self, enumerate(self, start=1)], format='vertices_and_edges', loops=True) - def show(self, representation="cycles", orientation="landscape", **args): + def show(self, representation='cycles', orientation='landscape', **args): r""" Display the permutation as a drawing. @@ -1848,33 +1846,33 @@ def show(self, representation="cycles", orientation="landscape", **args): - ``representation`` -- different kinds of drawings are available - - ``"cycles"`` (default) -- the permutation is displayed as a + - ``'cycles'`` -- default; the permutation is displayed as a collection of directed cycles - - ``"braid"`` -- the permutation is displayed as segments linking - each element `1, ..., n` to its image on a parallel line. + - ``'braid'`` -- the permutation is displayed as segments linking + each element `1, ..., n` to its image on a parallel line When using this drawing, it is also possible to display the permutation horizontally (``orientation = "landscape"``, default option) or vertically (``orientation = "portrait"``). - - ``"chord-diagram"`` -- the permutation is displayed as a directed - graph, all of its vertices being located on a circle. + - ``'chord-diagram'`` -- the permutation is displayed as a directed + graph, all of its vertices being located on a circle All additional arguments are forwarded to the ``show`` subcalls. EXAMPLES:: sage: P20 = Permutations(20) - sage: P20.random_element().show(representation="cycles") # needs sage.graphs sage.plot - sage: P20.random_element().show(representation="chord-diagram") # needs sage.graphs sage.plot - sage: P20.random_element().show(representation="braid") # needs sage.plot - sage: P20.random_element().show(representation="braid", # needs sage.plot + sage: P20.random_element().show(representation='cycles') # needs sage.graphs sage.plot + sage: P20.random_element().show(representation='chord-diagram') # needs sage.graphs sage.plot + sage: P20.random_element().show(representation='braid') # needs sage.plot + sage: P20.random_element().show(representation='braid', # needs sage.plot ....: orientation='portrait') TESTS:: - sage: P20.random_element().show(representation="modern_art") + sage: P20.random_element().show(representation='modern_art') Traceback (most recent call last): ... ValueError: The value of 'representation' must be equal to 'cycles', 'chord-diagram' or 'braid' @@ -1885,7 +1883,7 @@ def show(self, representation="cycles", orientation="landscape", **args): if representation == "cycles": d.show(**args) else: - d.show(layout="circular", **args) + d.show(layout='circular', **args) elif representation == "braid": from sage.plot.line import line @@ -1903,7 +1901,7 @@ def show(self, representation="cycles", orientation="landscape", **args): L = line([r(1, 1)]) for i in range(len(p)): - L += line([r(i, 1.0), r(p[i]-1, 0)]) + L += line([r(i, 1.0), r(p[i] - 1, 0)]) L += text(str(i), r(i, 1.05)) + text(str(i), r(p[i]-1, -.05)) return L.show(axes=False, **args) @@ -2269,12 +2267,10 @@ def runs(self, as_tuple=False): INPUT: - - ``as_tuple`` -- boolean (default: ``False``) choice of + - ``as_tuple`` -- boolean (default: ``False``); choice of output format - OUTPUT: - - a list of lists or a tuple of tuples + OUTPUT: list of lists or a tuple of tuples REFERENCES: @@ -2330,12 +2326,10 @@ def decreasing_runs(self, as_tuple=False): INPUT: - - ``as_tuple`` -- boolean (default: ``False``) choice of output + - ``as_tuple`` -- boolean (default: ``False``); choice of output format - OUTPUT: - - a list of lists or a tuple of tuples + OUTPUT: list of lists or a tuple of tuples .. SEEALSO:: @@ -2438,9 +2432,9 @@ def longest_increasing_subsequences(self): for i in columns[0]: D.add_edge(0, i) # 0 is source for i in columns[-1]: - D.add_edge(i, n+1) # n+1 is sink + D.add_edge(i, n + 1) # n+1 is sink - return sorted([p[1:-1] for p in D.all_paths(0, n+1)], reverse=True) + return sorted([p[1:-1] for p in D.all_paths(0, n + 1)], reverse=True) def longest_increasing_subsequences_number(self): r""" @@ -2664,7 +2658,7 @@ def foata_bijection(self) -> Permutation: continue a = M[-1] - M_prime = [0]*(k + 1) + M_prime = [0] * (k + 1) # Locate the positions of the vertical lines. if a > e: index_list = [-1] + [i for i, val in enumerate(M) if val > e] @@ -2716,7 +2710,7 @@ def foata_bijection_inverse(self) -> Permutation: k = len(L) if k <= 1: continue - L_prime = [0]*(k) + L_prime = [0] * (k) a = L[0] # Locate the positions of the vertical lines. if a > e: @@ -2877,15 +2871,16 @@ def fundamental_transformation_inverse(self): def destandardize(self, weight, ordered_alphabet=None): r""" - Return destandardization of ``self`` with respect to ``weight`` and ``ordered_alphabet``. + Return destandardization of ``self`` with respect to ``weight`` and + ``ordered_alphabet``. INPUT: - - ``weight`` -- list or tuple of nonnegative integers that sum to `n` if ``self`` - is a permutation in `S_n`. + - ``weight`` -- list or tuple of nonnegative integers that sum to `n` + if ``self`` is a permutation in `S_n` - - ``ordered_alphabet`` -- (default: ``None``) a list or tuple specifying the ordered alphabet the - destandardized word is over + - ``ordered_alphabet`` -- (default: ``None``) a list or tuple + specifying the ordered alphabet the destandardized word is over OUTPUT: word over the ``ordered_alphabet`` which standardizes to ``self`` @@ -2924,14 +2919,14 @@ def destandardize(self, weight, ordered_alphabet=None): if not set(ides).issubset(set(partial)): raise ValueError(f"Standardization with weight {weight} is not possible!") if ordered_alphabet is None: - ordered_alphabet = list(range(1,len(weight)+1)) + ordered_alphabet = list(range(1, len(weight)+1)) else: if len(weight) > len(ordered_alphabet): raise ValueError("Not enough letters in the alphabet are specified compared to the weight") q = self.inverse() - s = [0]*len(self) + s = [0] * len(self) for i in range(len(partial)-1): - for j in range(partial[i],partial[i+1]): + for j in range(partial[i], partial[i+1]): s[q[j]-1] = ordered_alphabet[i] from sage.combinat.words.word import Word return Word(s) @@ -2970,7 +2965,6 @@ def to_lehmer_code(self) -> list: sage: all(from_lehmer_code(p.to_lehmer_code()) == p ....: for p in sample) True - """ l = len(self._list) # choose the best implementations @@ -2998,7 +2992,7 @@ def _to_lehmer_code_small(self) -> list: p = self._list l = len(p) lehmer = [] - checked = [1]*l + checked = [1] * l for pi in p: checked[pi-1] = 0 lehmer.append(sum(checked[:pi])) @@ -3066,7 +3060,6 @@ def reduced_words_iterator(self): sage: next(Permutation([5,2,3,4,1]).reduced_words_iterator()) [1, 2, 3, 4, 3, 2, 1] - """ def aux(p): is_identity = True @@ -3384,17 +3377,17 @@ def descents(self, final_descent=False, side='right', positive=False, INPUT: - - ``final_descent`` -- boolean (default ``False``); + - ``final_descent`` -- boolean (default: ``False``); if ``True``, the last position of a non-empty permutation is also considered as a descent - ``side`` -- ``'right'`` (default) or ``'left'``; if ``'left'``, return the descents of the inverse permutation - - ``positive`` -- boolean (default ``False``); + - ``positive`` -- boolean (default: ``False``); if ``True``, return the positions that are not descents - - ``from_zero`` -- boolean (default ``False``); + - ``from_zero`` -- boolean (default: ``False``); if ``True``, return the positions starting from `0` - ``index_set`` -- list (default: ``[1, ..., n-1]`` where ``self`` @@ -3460,12 +3453,12 @@ def idescents(self, final_descent=False, from_zero=False): INPUT: - - ``final_descent`` -- boolean (default ``False``); - if ``True``, the last position of a non-empty - permutation is also considered as a descent + - ``final_descent`` -- boolean (default: ``False``); if ``True``, the + last position of a non-empty permutation is also considered as a + descent - - ``from_zero`` -- optional boolean (default ``False``); - if ``False``, return the positions starting from `1` + - ``from_zero`` -- boolean (default: ``False``); if ``False``, return + the positions starting from `1` EXAMPLES:: @@ -3583,29 +3576,19 @@ def descent_polynomial(self): EXAMPLES:: sage: Permutation([2,1,3]).descent_polynomial() - z1 + z2 sage: Permutation([4,3,2,1]).descent_polynomial() - z1*z2^2*z3^3 + z2*z3*z4 .. TODO:: - This docstring needs to be fixed. First, the definition - does not match the implementation (or the examples). - Second, this doesn't seem to be defined in [GS1984]_ + This docstring needs to be fixed. This is not defined in [GS1984]_ (the descent monomial in their (7.23) is different). """ p = self - z = [] - P = PolynomialRing(ZZ, len(p), 'z') + P = PolynomialRing(ZZ, len(p) + 1, 'z') z = P.gens() - result = 1 - pol = 1 - for i in range(len(p)-1): - pol *= z[p[i]-1] - if p[i] > p[i+1]: - result *= pol - - return result + return P.prod(z[p[i]] for i in range(len(p) - 1) if p[i] > p[i + 1]) ############## # Major Code # @@ -3735,7 +3718,7 @@ def to_major_code(self, final_descent=False): """ p = self n = len(p) - major_indices = [0]*(n+1) + major_indices = [0] * (n + 1) smaller = p[:] P = Permutations() for i in range(n): @@ -4106,7 +4089,7 @@ def bruhat_greater(self): # Permutohedron Order # ######################## - def permutohedron_lequal(self, p2, side="right") -> bool: + def permutohedron_lequal(self, p2, side='right') -> bool: r""" Return ``True`` if ``self`` is less or equal to ``p2`` in the permutohedron order. @@ -4184,7 +4167,7 @@ def permutohedron_lequal(self, p2, side="right") -> bool: sage: sorted( [len([b for b in Permutations(3) if a.permutohedron_lequal(b)]) ....: for a in Permutations(3)] ) [1, 2, 2, 3, 3, 6] - sage: sorted( [len([b for b in Permutations(3) if a.permutohedron_lequal(b, side="left")]) + sage: sorted( [len([b for b in Permutations(3) if a.permutohedron_lequal(b, side='left')]) ....: for a in Permutations(3)] ) [1, 2, 2, 3, 3, 6] @@ -4205,7 +4188,7 @@ def permutohedron_lequal(self, p2, side="right") -> bool: return prod.number_of_inversions() == l2 - l1 - def permutohedron_succ(self, side="right"): + def permutohedron_succ(self, side='right'): r""" Return a list of the permutations strictly greater than ``self`` in the permutohedron order such that there is no permutation @@ -4238,7 +4221,7 @@ def permutohedron_succ(self, side="right"): pp[i+1] = p[i] succ.append(P(pp)) else: - advance = lambda perm: [i for i in range(1,n) if perm.index(i) < perm.index(i+1)] + advance = lambda perm: [i for i in range(1, n) if perm.index(i) < perm.index(i+1)] for i in advance(p): pp = p[:] pp[p.index(i)] = i+1 @@ -4246,7 +4229,7 @@ def permutohedron_succ(self, side="right"): succ.append(P(pp)) return succ - def permutohedron_pred(self, side="right") -> list: + def permutohedron_pred(self, side='right') -> list: r""" Return a list of the permutations strictly smaller than ``self`` in the permutohedron order such that there is no permutation @@ -4278,7 +4261,7 @@ def permutohedron_pred(self, side="right") -> list: pp[d] = p[d - 1] pred.append(P(pp)) else: - recoil = lambda perm: [i for i in range(1,n) if perm.index(i) > perm.index(i+1)] + recoil = lambda perm: [i for i in range(1, n) if perm.index(i) > perm.index(i+1)] for i in recoil(p): pp = p[:] pp[p.index(i)] = i+1 @@ -4286,7 +4269,7 @@ def permutohedron_pred(self, side="right") -> list: pred.append(P(pp)) return pred - def permutohedron_smaller(self, side="right") -> list: + def permutohedron_smaller(self, side='right') -> list: r""" Return a list of permutations smaller than or equal to ``self`` in the permutohedron order. @@ -4324,7 +4307,7 @@ def permutohedron_smaller(self, side="right") -> list: """ return transitive_ideal(lambda x: x.permutohedron_pred(side), self) - def permutohedron_greater(self, side="right") -> list: + def permutohedron_greater(self, side='right') -> list: r""" Return a list of permutations greater than or equal to ``self`` in the permutohedron order. @@ -4413,7 +4396,7 @@ def right_permutohedron_interval(self, other): P = Permutations() return [P(p) for p in self.right_permutohedron_interval_iterator(other)] - def permutohedron_join(self, other, side="right") -> Permutation: + def permutohedron_join(self, other, side='right') -> Permutation: r""" Return the join of the permutations ``self`` and ``other`` in the right permutohedron order (or, if ``side`` is set to @@ -4509,10 +4492,10 @@ def permutohedron_join(self, other, side="right") -> Permutation: sage: p = Permutation([3,1,2]) sage: q = Permutation([1,3,2]) - sage: p.permutohedron_join(q, side="left") + sage: p.permutohedron_join(q, side='left') [3, 2, 1] sage: r = Permutation([2,1,3]) - sage: r.permutohedron_join(p, side="left") + sage: r.permutohedron_join(p, side='left') [3, 1, 2] """ if side == "left": @@ -4533,7 +4516,7 @@ def permutohedron_join(self, other, side="right") -> Permutation: xs.append(i) return Permutations(n)(xs) - def permutohedron_meet(self, other, side="right") -> Permutation: + def permutohedron_meet(self, other, side='right') -> Permutation: r""" Return the meet of the permutations ``self`` and ``other`` in the right permutohedron order (or, if ``side`` is set to @@ -4625,10 +4608,10 @@ def permutohedron_meet(self, other, side="right") -> Permutation: sage: p = Permutation([3,1,2]) sage: q = Permutation([1,3,2]) - sage: p.permutohedron_meet(q, side="left") + sage: p.permutohedron_meet(q, side='left') [1, 2, 3] sage: r = Permutation([2,1,3]) - sage: r.permutohedron_meet(p, side="left") + sage: r.permutohedron_meet(p, side='left') [2, 1, 3] """ return self.reverse().permutohedron_join(other.reverse(), side=side).reverse() @@ -4689,16 +4672,17 @@ def pattern_positions(self, patt) -> list: if to_standard([p[z] for z in pos]) == patt] @combinatorial_map(name='Simion-Schmidt map') - def simion_schmidt(self, avoid=[1,2,3]): + def simion_schmidt(self, avoid=[1, 2, 3]): r""" - Implements the Simion-Schmidt map which sends an arbitrary permutation + Implement the Simion-Schmidt map which sends an arbitrary permutation to a pattern avoiding permutation, where the permutation pattern is one of four length-three patterns. This method also implements the bijection between (for example) ``[1,2,3]``- and ``[1,3,2]``-avoiding permutations. INPUT: - - ``avoid`` -- one of the patterns ``[1,2,3]``, ``[1,3,2]``, ``[3,1,2]``, ``[3,2,1]``. + - ``avoid`` -- one of the patterns ``[1,2,3]``, ``[1,3,2]``, + ``[3,1,2]``, ``[3,2,1]`` EXAMPLES:: @@ -4718,7 +4702,7 @@ def simion_schmidt(self, avoid=[1,2,3]): targetPermutation = [self[0]] extreme = self[0] nonMinima = [] - if avoid == [1,2,3] or avoid == [1,3,2]: + if avoid == [1, 2, 3] or avoid == [1, 3, 2]: for i in range(1, len(list(self))): if self[i] < extreme: targetPermutation.append(self[i]) @@ -4727,9 +4711,9 @@ def simion_schmidt(self, avoid=[1,2,3]): targetPermutation.append(None) nonMinima.append(self[i]) nonMinima.sort() - if avoid == [1,3,2]: + if avoid == [1, 3, 2]: nonMinima.reverse() - if avoid == [3,2,1] or avoid == [3,1,2]: + if avoid == [3, 2, 1] or avoid == [3, 1, 2]: for i in range(1, len(list(self))): if self[i] > extreme: targetPermutation.append(self[i]) @@ -4738,7 +4722,7 @@ def simion_schmidt(self, avoid=[1,2,3]): targetPermutation.append(None) nonMinima.append(self[i]) nonMinima.sort() - if avoid == [3,2,1]: + if avoid == [3, 2, 1]: nonMinima.reverse() for i in range(1, len(list(self))): @@ -5405,14 +5389,14 @@ def hyperoctahedral_double_coset_type(self): n = len(self) if n % 2 == 1: raise ValueError("%s is a permutation of odd size and has no coset-type" % self) - S = PerfectMatchings(n)([(2*i+1,2*i+2) for i in range(n//2)]) + S = PerfectMatchings(n)([(2*i+1, 2*i+2) for i in range(n//2)]) return S.loop_type(S.apply_permutation(self)) ##################### # Binary operations # ##################### - def shifted_concatenation(self, other, side="right"): + def shifted_concatenation(self, other, side='right'): r""" Return the right (or left) shifted concatenation of ``self`` with a permutation ``other``. These operations are also known @@ -5421,18 +5405,18 @@ def shifted_concatenation(self, other, side="right"): INPUT: - ``other`` -- a permutation, a list, a tuple, or any iterable - representing a permutation. + representing a permutation - - ``side`` -- (default: ``"right"``) the string "left" or "right". + - ``side`` -- string (default: ``'right'``); ``'left'`` or ``'right'`` OUTPUT: - If ``side`` is ``"right"``, the method returns the permutation + If ``side`` is ``'right'``, the method returns the permutation obtained by concatenating ``self`` with the letters of ``other`` incremented by the size of ``self``. This is what is called ``side / other`` in [LR0102066]_, and denoted as the "over" operation. - Otherwise, i. e., when ``side`` is ``"left"``, the method + Otherwise, i. e., when ``side`` is ``'left'``, the method returns the permutation obtained by concatenating the letters of ``other`` incremented by the size of ``self`` with ``self``. This is what is called ``side \ other`` in [LR0102066]_ @@ -5464,7 +5448,7 @@ def shifted_shuffle(self, other): INPUT: - ``other`` -- a permutation, a list, a tuple, or any iterable - representing a permutation. + representing a permutation OUTPUT: @@ -5536,8 +5520,8 @@ def nth_roots(self, n): sage: list(sigma.nth_roots(2)) [] - For n >= 6, this algorithm begins to be more efficient than naive search - (look at all permutations and test their n-th power). + For `n \geq 6`, this algorithm begins to be more efficient than naive search + (look at all permutations and test their `n`-th power). .. SEEALSO:: @@ -5570,7 +5554,7 @@ def nth_roots(self, n): def merging_cycles(list_of_cycles): """ - Generate all l-cycles such that its n-th power is the product + Generate all l-cycles such that its `n`-th power is the product of cycles in 'cycles' (which contains gcd(l, n) cycles of length l/gcd(l, n)) """ lC = len(list_of_cycles) @@ -6024,13 +6008,13 @@ def __classcall_private__(cls, n=None, k=None, **kwargs): else: return StandardPermutations_n(n) else: - return Permutations_nk(n,k) + return Permutations_nk(n, k) else: # In this case, we have that n is a list # Because of UniqueRepresentation, we require the elements # to be hashable if len(set(n)) == len(n): - if list(n) == list(range(1, len(n)+1)): + if all(i == j for i, j in enumerate(n, start=1)): if k is None: return StandardPermutations_n(len(n)) else: @@ -6039,7 +6023,7 @@ def __classcall_private__(cls, n=None, k=None, **kwargs): if k is None: return Permutations_set(n) else: - return Permutations_setk(n,k) + return Permutations_setk(n, k) else: if k is None: return Permutations_mset(n) @@ -6115,7 +6099,7 @@ class options(GlobalOptions): 'description': "Specifies how the permutations should be printed", 'values': {'list': "the permutations are displayed in list notation" " (aka 1-line notation)", - 'cycle': "the permutations are displayed in cycle notation" + 'cycle': "the permutations are displayed in cycle notation" " (i. e., as products of disjoint cycles)", 'singleton': "the permutations are displayed in cycle notation" " with singleton cycles shown as well", @@ -6136,7 +6120,7 @@ class options(GlobalOptions): 'checker': lambda char: isinstance(char, str)} generator_name = {'default': "s", 'description': "the letter used in latexing the reduced word", - 'checker': lambda char: isinstance(char, str)} + 'checker': lambda char: isinstance(char, str)} mult = {'default': "l2r", 'description': "The multiplication of permutations", 'values': {'l2r': r"left to right: `(p_1 \cdot p_2)(x) = p_2(p_1(x))`", @@ -6255,7 +6239,7 @@ def random_element(self): sage: s in Permutations(3,2) True """ - return sample(range(1, self.n+1), self._k) + return sample(range(1, self.n + 1), self._k) class Permutations_mset(Permutations): @@ -6518,7 +6502,7 @@ def unrank(self, r): INPUT: - - ``r`` -- an integer between ``0`` and ``self.cardinality()-1`` + - ``r`` -- integer between ``0`` and ``self.cardinality()-1`` inclusive ALGORITHM: @@ -7396,7 +7380,7 @@ def identity(self): sage: Permutations(0).identity() [] """ - return self.element_class(self, range(1,self.n+1), check=False) + return self.element_class(self, range(1, self.n + 1), check=False) one = identity @@ -7454,7 +7438,7 @@ def random_element(self): sage: s in Permutations(4) True """ - return self.element_class(self, sample(range(1, self.n+1), self.n), + return self.element_class(self, sample(range(1, self.n + 1), self.n), check=False) def cardinality(self): @@ -7516,7 +7500,7 @@ def degrees(self): sage: Permutations(7).degrees() (2, 3, 4, 5, 6, 7) """ - return tuple(Integer(i) for i in range(2, self.n+1)) + return tuple(Integer(i) for i in range(2, self.n + 1)) def codegrees(self): """ @@ -7722,11 +7706,57 @@ def simple_reflection(self, i): sage: P.simple_reflections() Finite family {1: [2, 1, 3, 4], 2: [1, 3, 2, 4], 3: [1, 2, 4, 3]} """ - g = list(range(1, self.n+1)) - g[i-1] = i+1 + g = list(range(1, self.n + 1)) + g[i - 1] = i + 1 g[i] = i return self.element_class(self, g, check=False) + @cached_method + def reflection_index_set(self): + r""" + Return the index set of the reflections of ``self``. + + .. SEEALSO:: + + - :meth:`reflection` + - :meth:`reflections` + + EXAMPLES:: + + sage: P = Permutations(4) + sage: P.reflection_index_set() + ((1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)) + """ + return tuple([tuple(c) for c in itertools.combinations(range(1, self.n + 1), 2)]) + + def reflection(self, i): + r""" + Return the reflection indexed by ``i`` of ``self``. + + This returns the permutation with cycle `i = (a, b)`. + + .. SEEALSO:: + + - :meth:`reflections_index_set` + - :meth:`reflections` + + EXAMPLES:: + + sage: P = Permutations(4) + sage: for i in P.reflection_index_set(): + ....: print('%s %s'%(i, P.reflection(i))) + (1, 2) [2, 1, 3, 4] + (1, 3) [3, 2, 1, 4] + (1, 4) [4, 2, 3, 1] + (2, 3) [1, 3, 2, 4] + (2, 4) [1, 4, 3, 2] + (3, 4) [1, 2, 4, 3] + """ + data = list(range(1, self.n + 1)) + data[i[0]-1] = i[1] + data[i[1]-1] = i[0] + return self.element_class(self, data, check=False) + class Element(Permutation): def has_left_descent(self, i, mult=None): r""" @@ -8116,13 +8146,13 @@ def from_cycles(n, cycles, parent=None): # check that the values are valid if (k < 1) or (pk < 1): raise ValueError("all elements should be strictly positive " - f"integers, but I found {min(k, pk)}") + f"integers, but I found {min(k, pk)}") if (k > n) or (pk > n): raise ValueError("you claimed that this is a permutation on " - f"1...{n}, but it contains {max(k, pk)}") + f"1...{n}, but it contains {max(k, pk)}") if p[k - 1] is not None: raise ValueError(f"the element {k} appears more than once" - " in the input") + " in the input") p[k - 1] = pk # values that are not in any cycle are fixed points of the permutation @@ -8230,9 +8260,9 @@ def bistochastic_as_sum_of_permutations(M, check=True): INPUT: - - ``M`` -- A bistochastic matrix + - ``M`` -- a bistochastic matrix - - ``check`` (boolean) -- set to ``True`` (default) to check + - ``check`` -- boolean; set to ``True`` (default) to check that the matrix is indeed bistochastic OUTPUT: @@ -8472,7 +8502,6 @@ def cardinality(self): sage: D = [6, 8, 10, 11, 12, 13, 14, 15, 17, 19] sage: P(D, n).cardinality() 125291047596 - """ def m(l): s = 0 @@ -8489,7 +8518,7 @@ def d(l): if not self._d: return one - l_ops = [1]*(self.n-1) + l_ops = [1] * (self.n-1) for i in self._d: l_ops[i] = 0 l = [one] @@ -9073,7 +9102,7 @@ def bruhat_lequal(p1, p2): # Permutohedron # ################# -def permutohedron_lequal(p1, p2, side="right"): +def permutohedron_lequal(p1, p2, side='right'): r""" Return ``True`` if ``p1`` is less than or equal to ``p2`` in the permutohedron order. @@ -9146,7 +9175,7 @@ def to_standard(p, key=None): We check against the naive method:: sage: def std(p): - ....: s = [0]*len(p) + ....: s = [0] * len(p) ....: c = p[:] ....: biggest = max(p) + 1 ....: i = 1 @@ -9184,7 +9213,7 @@ class CyclicPermutations(Permutations_mset): INPUT: - - ``mset`` -- A multiset + - ``mset`` -- a multiset EXAMPLES:: @@ -9706,7 +9735,7 @@ def __iter__(self): sage: Permutations(3, avoiding=[2,1]).list() [[1, 2, 3]] """ - yield self.element_class(self, range(1, self.n+1), check=False) + yield self.element_class(self, range(1, self.n + 1), check=False) def cardinality(self): """ diff --git a/src/sage/combinat/permutation_cython.pyx b/src/sage/combinat/permutation_cython.pyx index d9d095cfc61..978510c4ae9 100644 --- a/src/sage/combinat/permutation_cython.pyx +++ b/src/sage/combinat/permutation_cython.pyx @@ -80,7 +80,6 @@ cdef int next_swap(int n, int *c, int *o) noexcept: Returns the index i such that the next permutation can be obtained by swapping P[i] <-> P[i+1] - """ cdef int j,s,q,offset @@ -116,7 +115,7 @@ cdef int next_swap(int n, int *c, int *o) noexcept: def permutation_iterator_transposition_list(int n): """ - Returns a list of transposition indices to enumerate the + Return a list of transposition indices to enumerate the permutations on `n` letters by adjacent transpositions. Assumes zero-based lists. We artificially limit the argument to `n < 12` to avoid overflowing 32-bit pointers. @@ -188,9 +187,7 @@ cpdef bint next_perm(array l) noexcept: This method mutates the array ``l``. - OUTPUT: - - boolean; whether another permutation was obtained + OUTPUT: boolean; whether another permutation was obtained EXAMPLES:: @@ -267,11 +264,9 @@ cpdef map_to_list(array l, tuple values, int n): - ``l`` -- array of unsigned int (i.e., type ``'I'``) - ``values`` -- tuple; the values of the permutation - - ``n`` -- int; the length of the array ``l`` - - OUTPUT: + - ``n`` -- integer; the length of the array ``l`` - A list representing the permutation. + OUTPUT: list representing the permutation EXAMPLES:: diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index f8ad4a6757b..e51fcd03186 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -25,7 +25,8 @@ # **************************************************************************** from __future__ import annotations -from typing import NewType, Iterator +from typing import NewType +from collections.abc import Iterator from sage.structure.richcmp import richcmp, richcmp_method from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets @@ -56,15 +57,13 @@ class PlanePartition(ClonableArray, INPUT: - - ``PP`` -- a list of lists which represents a tableau + - ``PP`` -- list of lists which represents a tableau - ``box_size`` -- (optional) a list ``[A, B, C]`` of 3 positive integers, where ``A``, ``B``, ``C`` are the lengths of the box in the `x`-axis, `y`-axis, `z`-axis, respectively; if this is not given, it is determined by the smallest box bounding ``PP`` - OUTPUT: - - The plane partition whose tableau representation is ``PP``. + OUTPUT: the plane partition whose tableau representation is ``PP`` EXAMPLES:: @@ -162,9 +161,7 @@ def __richcmp__(self, other, op): - ``other`` -- the element that ``self`` is compared to - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -214,7 +211,6 @@ def check(self): Traceback (most recent call last): ... ValueError: entries not all integers - """ if not all(a in ZZ for b in self for a in b): raise ValueError("entries not all integers") @@ -355,9 +351,7 @@ def _repr_diagram(self, show_box=False, use_unicode=False) -> str: also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes - ``use_unicode`` -- boolean (default: ``False``); use unicode - OUTPUT: - - A string of the 3D diagram of the plane partition. + OUTPUT: string of the 3D diagram of the plane partition EXAMPLES:: @@ -508,9 +502,7 @@ def pp(self, show_box=False): - ``show_box`` -- boolean (default: ``False``); if ``True``, also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes - OUTPUT: - - A pretty print of the plane partition. + OUTPUT: a pretty print of the plane partition EXAMPLES:: @@ -616,9 +608,7 @@ def _latex_(self, show_box=False, - ``colors`` -- (default: ``["white", "lightgray", "darkgray"]``) list ``[A, B, C]`` of 3 strings representing colors - OUTPUT: - - Latex code for drawing the plane partition. + OUTPUT: latex code for drawing the plane partition EXAMPLES:: @@ -696,15 +686,15 @@ def move(side, i, j, k): for P in side] def add_topside(i, j, k): - return polygon(move(Uside, i, j, k), edgecolor="black", + return polygon(move(Uside, i, j, k), edgecolor='black', color=colors[0]) def add_leftside(i, j, k): - return polygon(move(Lside, i, j, k), edgecolor="black", + return polygon(move(Lside, i, j, k), edgecolor='black', color=colors[1]) def add_rightside(i, j, k): - return polygon(move(Rside, i, j, k), edgecolor="black", + return polygon(move(Rside, i, j, k), edgecolor='black', color=colors[2]) TP = plot([]) for r in range(len(self.z_tableau())): @@ -1485,7 +1475,7 @@ class PlanePartitions_all(PlanePartitions, DisjointUnionEnumeratedSets): """ def __init__(self): r""" - Initializes the class of all plane partitions. + Initialize the class of all plane partitions. .. WARNING:: @@ -1544,7 +1534,7 @@ class PlanePartitions_box(PlanePartitions): """ def __init__(self, box_size): r""" - Initializes the class of plane partitions that fit in a box of a + Initialize the class of plane partitions that fit in a box of a specified size. EXAMPLES:: @@ -1638,7 +1628,7 @@ def from_antichain(self, A) -> PP: pp_matrix[x][y] = z + 1 # For each value in current antichain, fill in the rest of the matrix by - # rule M[y,z] = Max(M[y+1,z], M[y,z+1]) antichiain is now in plane partition format + # rule M[y,z] = Max(M[y+1,z], M[y,z+1]) antichain is now in plane partition format if A: for i in range(a): i = a - (i + 1) @@ -1740,7 +1730,7 @@ class PlanePartitions_n(PlanePartitions): """ def __init__(self, n): r""" - Initializes the class of plane partitions with ``n`` boxes. + Initialize the class of plane partitions with ``n`` boxes. .. WARNING:: @@ -1851,7 +1841,6 @@ def cardinality(self) -> Integer: sage: P = PlanePartitions(17) sage: P.cardinality() 18334 - """ PPn = [1] for i in range(1, 1+self._n): @@ -2172,7 +2161,7 @@ def from_antichain(self, acl) -> PP: pp_matrix[x][y] = (z+1) # For each value in current antichain, fill in the rest of the - # matrix by rule M[y,z] = Max(M[y+1,z], M[y,z+1]) antichiain is + # matrix by rule M[y,z] = Max(M[y+1,z], M[y,z+1]) antichain is # now in plane partition format. if acl != []: for i in range(b): @@ -2379,7 +2368,7 @@ def from_antichain(self, acl) -> PP: pp_matrix[y][x] = z + 1 # z,y,x # for each value in current antichain, fill in the rest of the matrix by - # rule M[y,z] = Max(M[y+1,z], M[y,z+1]) antichiain is now in plane partition format + # rule M[y,z] = Max(M[y+1,z], M[y,z+1]) antichain is now in plane partition format if acl != []: for i in range(b): i = b - (i + 1) @@ -3177,7 +3166,7 @@ def from_antichain(self, acl) -> PP: n = a N = n // 2 pp_matrix = [[0] * (c) for i in range(b)] - # creates a matrix for the plane parition populated by 0s + # creates a matrix for the plane partition populated by 0s # EX: [[0,0,0], [0,0,0], [0,0,0]] width = N - 1 height = N - 1 diff --git a/src/sage/combinat/posets/cartesian_product.py b/src/sage/combinat/posets/cartesian_product.py index 8f581b5cda2..29206b236c5 100644 --- a/src/sage/combinat/posets/cartesian_product.py +++ b/src/sage/combinat/posets/cartesian_product.py @@ -25,25 +25,24 @@ class CartesianProductPoset(CartesianProduct): INPUT: - - ``sets`` -- a tuple of parents. + - ``sets`` -- tuple of parents - - ``category`` -- a subcategory of - ``Sets().CartesianProducts() & Posets()``. + - ``category`` -- a subcategory of ``Sets().CartesianProducts() & Posets()`` - - ``order`` -- a string or function specifying an order less or equal. - It can be one of the following: + - ``order`` -- string or function specifying an order less or equal; + it can be one of the following: - ``'native'`` -- elements are ordered by their native ordering, - i.e., the order the wrapped elements (tuples) provide. + i.e., the order the wrapped elements (tuples) provide - - ``'lex'`` -- elements are ordered lexicographically. + - ``'lex'`` -- elements are ordered lexicographically - ``'product'`` -- an element is less or equal to another element, if less or equal is true for all its components - (Cartesian projections). + (Cartesian projections) - - A function which performs the comparison `\leq`. It takes two - input arguments and outputs a boolean. + - a function which performs the comparison `\leq`; it takes two + input arguments and outputs a boolean Other keyword arguments (``kwargs``) are passed to the constructor of :class:`CartesianProduct`. @@ -118,13 +117,11 @@ def le(self, left, right): INPUT: - - ``left`` -- an element. + - ``left`` -- an element - - ``right`` -- an element. + - ``right`` -- an element - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -156,13 +153,11 @@ def le_lex(self, left, right): INPUT: - - ``left`` -- an element. - - - ``right`` -- an element. + - ``left`` -- an element - OUTPUT: + - ``right`` -- an element - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -220,13 +215,11 @@ def le_product(self, left, right): INPUT: - - ``left`` -- an element. - - - ``right`` -- an element. + - ``left`` -- an element - OUTPUT: + - ``right`` -- an element - A boolean. + OUTPUT: boolean The comparison is ``True`` if the result of the comparison in each component is ``True``. @@ -269,13 +262,11 @@ def le_native(self, left, right): INPUT: - - ``left`` -- an element. + - ``left`` -- an element - - ``right`` -- an element. + - ``right`` -- an element - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -313,11 +304,9 @@ def _le_(self, other): INPUT: - - ``other`` -- an element. - - OUTPUT: + - ``other`` -- an element - A boolean. + OUTPUT: boolean .. NOTE:: @@ -348,11 +337,9 @@ def __le__(self, other): INPUT: - - ``other`` -- an element. + - ``other`` -- an element - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -411,11 +398,9 @@ def __ge__(self, other): INPUT: - - ``other`` -- an element. - - OUTPUT: + - ``other`` -- an element - A boolean. + OUTPUT: boolean .. NOTE:: @@ -446,11 +431,9 @@ def __lt__(self, other): INPUT: - - ``other`` -- an element. + - ``other`` -- an element - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -481,11 +464,9 @@ def __gt__(self, other): INPUT: - - ``other`` -- an element. - - OUTPUT: + - ``other`` -- an element - A boolean. + OUTPUT: boolean .. NOTE:: diff --git a/src/sage/combinat/posets/elements.py b/src/sage/combinat/posets/elements.py index 5d033c5c26a..7a94d76e213 100644 --- a/src/sage/combinat/posets/elements.py +++ b/src/sage/combinat/posets/elements.py @@ -162,15 +162,12 @@ def _cmp(self, other): sage: P(0)._cmp(P(0)) 0 sage: P(1)._cmp(P(2)) - """ return self.parent().compare_elements(self, other) def __lt__(self, other): """ - TESTS - - :: + TESTS:: sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]}) sage: P = Poset(dag, facade = False) @@ -185,9 +182,7 @@ def __lt__(self, other): def __le__(self, other): """ - TESTS - - :: + TESTS:: sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]}) sage: P = Poset(dag, facade = False) @@ -204,9 +199,7 @@ def __le__(self, other): def __gt__(self, other): """ - TESTS - - :: + TESTS:: sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]}) sage: P = Poset(dag) @@ -221,9 +214,7 @@ def __gt__(self, other): def __ge__(self, other): """ - TESTS - - :: + TESTS:: sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]}) sage: P = Poset(dag) diff --git a/src/sage/combinat/posets/hasse_cython.pyx b/src/sage/combinat/posets/hasse_cython.pyx index 2048febd192..fee64e5d5c4 100644 --- a/src/sage/combinat/posets/hasse_cython.pyx +++ b/src/sage/combinat/posets/hasse_cython.pyx @@ -27,15 +27,15 @@ class IncreasingChains(RecursivelyEnumeratedSet_forest): INPUT: - - ``positions`` -- a list of sets of integers describing the poset, - as given by the lazy attribute ``_leq_storage`` of Hasse diagrams. + - ``positions`` -- list of sets of integers describing the poset, + as given by the lazy attribute ``_leq_storage`` of Hasse diagrams - ``element_constructor`` -- used to determine the type of chains, for example :class:`list` or :class:`tuple` - ``exclude`` -- list of integers that should not belong to the chains - - ``conversion`` -- optional list of elements of the poset + - ``conversion`` -- (optional) list of elements of the poset If ``conversion`` is provided, it is used to convert chain elements to elements of this list. diff --git a/src/sage/combinat/posets/hasse_cython_flint.pyx b/src/sage/combinat/posets/hasse_cython_flint.pyx index 5d2c5b967ae..28f3f026430 100644 --- a/src/sage/combinat/posets/hasse_cython_flint.pyx +++ b/src/sage/combinat/posets/hasse_cython_flint.pyx @@ -20,6 +20,53 @@ from sage.libs.flint.fmpz_mat cimport * from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense from sage.matrix.matrix_space import MatrixSpace from sage.rings.integer_ring import ZZ +from sage.libs.flint.fmpz_poly_sage cimport Fmpz_poly + + +cpdef Fmpz_poly chain_poly(list positions): + r""" + Return the chain polynomial of a poset. + + INPUT: + + - ``positions`` -- a list of sets of integers describing the poset, as + given by the lazy attribute ``_leq_storage`` of Hasse diagrams + + OUTPUT: a Flint polynomial in one variable over `\ZZ`. + + EXAMPLES:: + + sage: from sage.combinat.posets.hasse_cython_flint import chain_poly + sage: D = [{0, 1}, {1}] + sage: chain_poly(D) + 3 1 2 1 + sage: P = posets.TamariLattice(5) + sage: H = P._hasse_diagram + sage: D = H._leq_storage + sage: chain_poly(D) + 12 1 42 357 1385 3133 4635 4758 3468 1778 612 127 12 + """ + cdef Py_ssize_t n = len(positions) + cdef Py_ssize_t i, j + + q = Fmpz_poly([0, 1]) + zero = Fmpz_poly(0) + one = Fmpz_poly(1) + + cdef list chain_polys = [zero] * n + + # chain_polys[i] will be the generating function for the + # chains with lowest vertex i (in the labelling of the + # Hasse diagram). + for i in range(n - 1, -1, -1): + cpi = q + for j in positions[i]: + cpi += q * chain_polys[j] + chain_polys[i] = cpi + total = one + for i in range(n): + total += chain_polys[i] + return total cpdef Matrix_integer_dense moebius_matrix_fast(list positions): @@ -28,12 +75,10 @@ cpdef Matrix_integer_dense moebius_matrix_fast(list positions): INPUT: - a list of sets of integers describing the poset, as given by the - lazy attribute ``_leq_storage`` of Hasse diagrams. + - ``positions`` -- a list of sets of integers describing the poset, as + given by the lazy attribute ``_leq_storage`` of Hasse diagrams - OUTPUT: - - a dense matrix + OUTPUT: a dense matrix EXAMPLES:: @@ -87,12 +132,10 @@ cpdef Matrix_integer_dense coxeter_matrix_fast(list positions): INPUT: - a list of sets of integers describing the poset, as given by the - lazy attribute ``_leq_storage`` of Hasse diagrams. - - OUTPUT: + - ``positions`` -- a list of sets of integers describing the poset, as + given by the lazy attribute ``_leq_storage`` of Hasse diagrams - a dense matrix + OUTPUT: a dense matrix EXAMPLES:: diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 59c3f435976..56b51e96371 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -27,7 +27,8 @@ from sage.rings.integer_ring import ZZ lazy_import('sage.combinat.posets.hasse_cython_flint', - ['moebius_matrix_fast', 'coxeter_matrix_fast']) + ['moebius_matrix_fast', 'coxeter_matrix_fast', + 'chain_poly']) lazy_import('sage.matrix.constructor', 'matrix') lazy_import('sage.rings.finite_rings.finite_field_constructor', 'GF') @@ -74,7 +75,7 @@ class HasseDiagram(DiGraph): The Hasse diagram of a poset. This is just a transitively-reduced, directed, acyclic graph without loops or multiple edges. - .. note:: + .. NOTE:: We assume that ``range(n)`` is a linear extension of the poset. That is, ``range(n)`` is the vertex set and a topological sort of @@ -103,7 +104,7 @@ def _repr_(self): def linear_extension(self): r""" - Return a linear extension + Return a linear extension. EXAMPLES:: @@ -293,7 +294,7 @@ def is_lequal(self, i, j) -> bool: Return ``True`` if i is less than or equal to j in the poset, and ``False`` otherwise. - .. note:: + .. NOTE:: If the :meth:`lequal_matrix` has been computed, then this method is redefined to use the cached data (see :meth:`_alternate_is_lequal`). @@ -611,9 +612,9 @@ def interval(self, x, y): INPUT: - - ``x`` -- any element of the poset + - ``x`` -- any element of the poset - - ``y`` -- any element of the poset + - ``y`` -- any element of the poset .. NOTE:: @@ -645,9 +646,9 @@ def interval_iterator(self, x, y): INPUT: - - ``x`` -- any element of the poset + - ``x`` -- any element of the poset - - ``y`` -- any element of the poset + - ``y`` -- any element of the poset .. SEEALSO:: :meth:`interval` @@ -1035,15 +1036,13 @@ def moebius_function_matrix(self, algorithm='cython'): INPUT: - - ``algorithm`` -- optional, ``'recursive'``, ``'matrix'`` - or ``'cython'`` (default) + - ``algorithm`` -- ``'recursive'``, ``'matrix'`` or ``'cython'`` + (default) This uses either the recursive formula, a generic matrix inversion or a specific matrix inversion coded in Cython. - OUTPUT: - - a dense matrix for the algorithm ``cython``, a sparse matrix otherwise + OUTPUT: a dense matrix for the algorithm ``cython``, a sparse matrix otherwise .. NOTE:: @@ -1150,7 +1149,7 @@ def coxeter_transformation(self, algorithm='cython'): INPUT: - - ``algorithm`` -- optional, ``'cython'`` (default) or ``'matrix'`` + - ``algorithm`` -- ``'cython'`` (default) or ``'matrix'`` This uses either a specific matrix code in Cython, or generic matrices. @@ -1167,7 +1166,7 @@ def coxeter_transformation(self, algorithm='cython'): [-1 1 1 0 -1] [-1 1 0 1 -1] sage: P.__dict__['coxeter_transformation'].clear_cache() - sage: P.coxeter_transformation(algorithm="matrix") == M + sage: P.coxeter_transformation(algorithm='matrix') == M True TESTS:: @@ -1178,7 +1177,7 @@ def coxeter_transformation(self, algorithm='cython'): sage: M**8 == 1 True sage: P.__dict__['coxeter_transformation'].clear_cache() - sage: P.coxeter_transformation(algorithm="banana") + sage: P.coxeter_transformation(algorithm='banana') Traceback (most recent call last): ... ValueError: unknown algorithm @@ -1368,7 +1367,7 @@ def lequal_matrix(self, boolean=False): INPUT: - - ``boolean`` -- optional flag (default ``False``) telling whether to + - ``boolean`` -- flag (default: ``False``); whether to return a matrix with coefficients in `\GF(2)` or in `\ZZ` .. SEEALSO:: @@ -1664,7 +1663,7 @@ def is_meet_semilattice(self) -> bool: @lazy_attribute def _join(self): r""" - Computes a matrix whose ``(x,y)``-entry is the join of ``x`` + Compute a matrix whose ``(x,y)``-entry is the join of ``x`` and ``y`` in ``self`` if the join exists; and `-1` otherwise. EXAMPLES:: @@ -1873,11 +1872,11 @@ def vertical_decomposition(self, return_list=False): INPUT: - - ``return_list``, a boolean. If ``False`` (the default), return - an element that is not the top neither the bottom element of the - lattice, but is comparable to all elements of the lattice, if - the lattice is vertically decomposable and ``None`` otherwise. - If ``True``, return list of decomposition elements. + - ``return_list`` -- boolean (default: ``False``); if ``False`` (the + default), return an element that is not the top neither the bottom + element of the lattice, but is comparable to all elements of the + lattice, if the lattice is vertically decomposable and ``None`` + otherwise. If ``True``, return list of decomposition elements. EXAMPLES:: @@ -1956,7 +1955,7 @@ def pseudocomplement(self, element): INPUT: - - ``element`` -- an element of the lattice. + - ``element`` -- an element of the lattice OUTPUT: @@ -1989,9 +1988,7 @@ def orthocomplementations_iterator(self): r""" Return an iterator over orthocomplementations of the lattice. - OUTPUT: - - An iterator that gives plain list of integers. + OUTPUT: an iterator that gives plain list of integers EXAMPLES:: @@ -2164,8 +2161,8 @@ def find_nonsemimodular_pair(self, upper): INPUT: - - ``upper``, a Boolean -- if ``True``, test whether the lattice is - upper semimodular; otherwise test whether the lattice is + - ``upper`` -- boolean; if ``True``, test whether the lattice is + upper semimodular. Otherwise test whether the lattice is lower semimodular. OUTPUT: @@ -2209,7 +2206,7 @@ def antichains_iterator(self): r""" Return an iterator over the antichains of the poset. - .. note:: + .. NOTE:: The algorithm is based on Freese-Jezek-Nation p. 226. It does a depth first search through the set of all @@ -2264,7 +2261,7 @@ def antichains_iterator(self): def are_incomparable(self, i, j): """ - Return whether ``i`` and ``j`` are incomparable in the poset + Return whether ``i`` and ``j`` are incomparable in the poset. INPUT: @@ -2290,11 +2287,11 @@ def are_incomparable(self, i, j): def are_comparable(self, i, j): """ - Return whether ``i`` and ``j`` are comparable in the poset + Return whether ``i`` and ``j`` are comparable in the poset. INPUT: - - ``i``, ``j`` -- vertices of this Hasse diagram + - ``i``, ``j`` -- vertices of this Hasse diagram EXAMPLES:: @@ -2318,11 +2315,11 @@ def are_comparable(self, i, j): def antichains(self, element_class=list): """ - Return all antichains of ``self``, organized as a prefix tree + Return all antichains of ``self``, organized as a prefix tree. INPUT: - - ``element_class`` -- (default:list) an iterable type + - ``element_class`` -- (default: ``list``) an iterable type EXAMPLES:: @@ -2365,7 +2362,7 @@ def chains(self, element_class=list, exclude=None, conversion=None): (default: ``None``) - ``conversion`` -- (default: ``None``) used to pass - the list of elements of the poset in their fixed order + the list of elements of the poset in their fixed order OUTPUT: @@ -2417,6 +2414,23 @@ def chains(self, element_class=list, exclude=None, conversion=None): """ return IncreasingChains(self._leq_storage, element_class, exclude, conversion) + def chain_polynomial(self): + """ + Return the chain polynomial of the poset. + + The coefficient of `q^k` is the number of chains of `k` + elements in the poset. List of coefficients of this polynomial + is also called a *f-vector* of the poset. + + EXAMPLES:: + + sage: P = posets.ChainPoset(3) + sage: H = P._hasse_diagram + sage: t = H.chain_polynomial(); t + q^3 + 3*q^2 + 3*q + 1 + """ + return chain_poly(self._leq_storage)._sage_('q') # noqa: F821 + def is_linear_interval(self, t_min, t_max) -> bool: """ Return whether the interval ``[t_min, t_max]`` is linear. @@ -2490,9 +2504,7 @@ def diamonds(self) -> tuple: Thus each edge represents a cover relation in the Hasse diagram. We represent his as the tuple `(w, x, y, z)`. - OUTPUT: - - A tuple with + OUTPUT: a tuple with - a list of all diamonds in the Hasse Diagram, - a boolean checking that every `w,x,y` that form a ``V``, there is a @@ -2622,9 +2634,7 @@ def sublattices_iterator(self, elms, min_e): - ``elms`` -- elements already in sublattice; use set() at start - ``min_e`` -- smallest new element to add for new sublattices - OUTPUT: - - List of sublattices as sets of integers. + OUTPUT: list of sublattices as sets of integers EXAMPLES:: @@ -3146,9 +3156,9 @@ def congruence(self, parts, start=None, stop_pairs=None): INPUT: - - ``parts`` -- a list of lists; congruences to add + - ``parts`` -- list of lists; congruences to add - ``start`` -- a disjoint set; already computed congruence (or ``None``) - - ``stop_pairs`` -- a list of pairs; list of pairs for stopping computation + - ``stop_pairs`` -- list of pairs; list of pairs for stopping computation OUTPUT: diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 9c5689bcb81..149915f8fb5 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -214,7 +214,7 @@ def MeetSemilattice(data=None, *args, **options): class FiniteMeetSemilattice(FinitePoset): """ - .. note:: + .. NOTE:: We assume that the argument passed to MeetSemilattice is the poset of a meet-semilattice (i.e. a poset with greatest lower bound for each pair of elements). @@ -266,8 +266,8 @@ def meet(self, x, y=None): INPUT: - - ``x, y`` -- two elements of the (semi)lattice OR - - ``x`` -- a list or tuple of elements + - ``x``, ``y`` -- two elements of the (semi)lattice OR + - ``x`` -- list or tuple of elements EXAMPLES:: @@ -342,7 +342,7 @@ def submeetsemilattice(self, elms): INPUT: - - ``elms`` -- a list of elements of the lattice. + - ``elms`` -- list of elements of the lattice EXAMPLES:: @@ -384,7 +384,7 @@ def subjoinsemilattice(self, elms): INPUT: - - ``elms`` -- a list of elements of the lattice. + - ``elms`` -- list of elements of the lattice EXAMPLES:: @@ -435,7 +435,7 @@ def pseudocomplement(self, element): INPUT: - - ``element`` -- an element of the lattice. + - ``element`` -- an element of the lattice OUTPUT: @@ -554,7 +554,6 @@ class FiniteJoinSemilattice(FinitePoset): sage: P = Poset([[1,2],[3],[3]]) sage: J = JoinSemilattice(P) sage: TestSuite(J).run() - """ Element = JoinSemilatticeElement _desc = 'Finite join-semilattice' @@ -592,8 +591,8 @@ def join(self, x, y=None): INPUT: - - ``x, y`` -- two elements of the (semi)lattice OR - - ``x`` -- a list or tuple of elements + - ``x``, ``y`` -- two elements of the (semi)lattice OR + - ``x`` -- list or tuple of elements EXAMPLES:: @@ -675,9 +674,7 @@ def LatticePoset(data=None, *args, **options): be passed down to :func:`Poset` to construct a poset that is also a lattice. - OUTPUT: - - An instance of :class:`FiniteLatticePoset`. + OUTPUT: an instance of :class:`FiniteLatticePoset` .. SEEALSO:: @@ -756,7 +753,6 @@ class FiniteLatticePoset(FiniteMeetSemilattice, FiniteJoinSemilattice): sage: P = Poset([[1,2],[3],[3]]) sage: L = LatticePoset(P) sage: TestSuite(L).run() - """ Element = LatticePosetElement @@ -935,7 +931,7 @@ def is_join_distributive(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1023,7 +1019,7 @@ def is_meet_distributive(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1116,7 +1112,7 @@ def is_stone(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1204,7 +1200,7 @@ def is_distributive(self, certificate=False): in lattices it follows that then also join distributes over meet. - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1326,7 +1322,7 @@ def is_meet_semidistributive(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1418,7 +1414,7 @@ def is_join_semidistributive(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1539,7 +1535,7 @@ def is_trim(self, certificate=False): INPUT: - - certificate -- boolean (default ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return instead a maximum chain of left modular elements EXAMPLES:: @@ -1588,7 +1584,7 @@ def is_complemented(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -1640,8 +1636,8 @@ def is_cosectionally_complemented(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) Whether to return - a certificate if the lattice is not cosectionally complemented. + - ``certificate`` -- boolean (default: ``False``); whether to return + a certificate if the lattice is not cosectionally complemented OUTPUT: @@ -1715,8 +1711,8 @@ def is_relatively_complemented(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) Whether to return - a certificate if the lattice is not relatively complemented. + - ``certificate`` -- boolean (default: ``False``); whether to return + a certificate if the lattice is not relatively complemented OUTPUT: @@ -1829,8 +1825,8 @@ def is_sectionally_complemented(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) Whether to return - a certificate if the lattice is not sectionally complemented. + - ``certificate`` -- boolean (default: ``False``); whether to return + a certificate if the lattice is not sectionally complemented OUTPUT: @@ -1909,7 +1905,7 @@ def breadth(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2102,7 +2098,7 @@ def is_pseudocomplemented(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2167,7 +2163,7 @@ def is_join_pseudocomplemented(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2281,7 +2277,7 @@ def is_orthocomplemented(self, unique=False): INPUT: - - ``unique``, a Boolean -- If ``True``, return ``True`` only + - ``unique`` -- boolean; if ``True``, return ``True`` only if the lattice has exactly one orthocomplementation. If ``False`` (the default), return ``True`` when the lattice has at least one orthocomplementation. @@ -2334,7 +2330,7 @@ def is_atomic(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2393,7 +2389,7 @@ def is_coatomic(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2574,7 +2570,7 @@ def is_modular(self, L=None, certificate=False): - ``L`` -- (default: ``None``) a list of elements to check being modular, if ``L`` is ``None``, then this checks the entire lattice - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2732,8 +2728,8 @@ def is_upper_semimodular(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) Whether to return - a certificate if the lattice is not upper semimodular. + - ``certificate`` -- boolean (default: ``False``); whether to return + a certificate if the lattice is not upper semimodular OUTPUT: @@ -2792,8 +2788,8 @@ def is_lower_semimodular(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) Whether to return - a certificate if the lattice is not lower semimodular. + - ``certificate`` -- boolean (default: ``False``); whether to return + a certificate if the lattice is not lower semimodular OUTPUT: @@ -2849,7 +2845,7 @@ def is_supersolvable(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -2955,7 +2951,7 @@ def vertical_composition(self, other, labels='pairs'): - ``other`` -- a lattice - - ``labels`` -- a string (default ``'pairs'``); can be one of + - ``labels`` -- string (default: ``'pairs'``); can be one of the following: * ``'pairs'`` -- each element ``v`` in this poset will be @@ -3109,7 +3105,7 @@ def is_vertically_decomposable(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -3158,7 +3154,7 @@ def sublattice(self, elms): INPUT: - - ``elms`` -- a list of elements of the lattice. + - ``elms`` -- list of elements of the lattice EXAMPLES:: @@ -3355,7 +3351,7 @@ def isomorphic_sublattices_iterator(self, other): INPUT: - - other -- a finite lattice + - ``other`` -- a finite lattice EXAMPLES: @@ -3467,9 +3463,7 @@ def moebius_algebra(self, R): """ Return the Möbius algebra of ``self`` over ``R``. - OUTPUT: - - An instance of :class:`sage.combinat.posets.moebius_algebra.MoebiusAlgebra`. + OUTPUT: an instance of :class:`sage.combinat.posets.moebius_algebra.MoebiusAlgebra` EXAMPLES:: @@ -3488,9 +3482,7 @@ def quantum_moebius_algebra(self, q=None): - ``q`` -- (optional) the deformation parameter `q` - OUTPUT: - - An instance of :class:`sage.combinat.posets.moebius_algebra.QuantumMoebiusAlgebra`. + OUTPUT: an instance of :class:`sage.combinat.posets.moebius_algebra.QuantumMoebiusAlgebra` EXAMPLES:: @@ -3704,7 +3696,7 @@ def is_dismantlable(self, certificate=False): INPUT: - - ``certificate`` (boolean) -- Whether to return a certificate. + - ``certificate`` -- boolean; whether to return a certificate * If ``certificate = False`` (default), returns ``True`` or ``False`` accordingly. @@ -3821,7 +3813,7 @@ def is_interval_dismantlable(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -4002,7 +3994,7 @@ def is_subdirectly_reducible(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -4092,9 +4084,7 @@ def canonical_meetands(self, e): - ``e`` -- an element of the lattice - OUTPUT: - - - canonical meetands as a list, if it exists; if not, ``None`` + OUTPUT: canonical meetands as a list, if it exists; if not, ``None`` EXAMPLES:: @@ -4158,9 +4148,7 @@ def canonical_joinands(self, e): - ``e`` -- an element of the lattice - OUTPUT: - - - canonical joinands as a list, if it exists; if not, ``None`` + OUTPUT: canonical joinands as a list, if it exists; if not, ``None`` EXAMPLES:: @@ -4222,7 +4210,7 @@ def is_constructible_by_doublings(self, type) -> bool: INPUT: - - ``type`` -- a string; can be one of the following: + - ``type`` -- string; can be one of the following: * ``'interval'`` -- allow only doublings of an interval * ``'lower'`` -- allow doublings of lower pseudo-interval; that is, a @@ -4365,7 +4353,7 @@ def is_isoform(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate if the lattice is not isoform OUTPUT: @@ -4440,7 +4428,7 @@ def is_uniform(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate if the lattice is not uniform OUTPUT: @@ -4520,7 +4508,7 @@ def is_regular(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate if the lattice is not regular OUTPUT: @@ -4589,7 +4577,7 @@ def is_simple(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate if the lattice is not simple OUTPUT: @@ -4733,7 +4721,7 @@ def congruence(self, S): INPUT: - - ``S`` -- a list of lists; list of element blocks that the congruence + - ``S`` -- list of lists; list of element blocks that the congruence will contain OUTPUT: @@ -4890,11 +4878,9 @@ def congruences_lattice(self, labels='congruence'): INPUT: - - ``labels`` -- a string; the type of elements in the resulting lattice - - OUTPUT: + - ``labels`` -- string; the type of elements in the resulting lattice - A distributive lattice. + OUTPUT: a distributive lattice - If ``labels='congruence'``, then elements of the result will be congruences given as @@ -4992,7 +4978,7 @@ def feichtner_yuzvinsky_ring(self, G, use_defining=False, base_ring=None): INPUT: - ``G`` -- a subset of elements of ``self`` - - ``use_defining`` -- (default: ``False``) whether or not to use + - ``use_defining`` -- boolean (default: ``False``); whether or not to use the defining presentation in `x_g` - ``base_ring`` -- (default: `\QQ`) the base ring diff --git a/src/sage/combinat/posets/linear_extension_iterator.pyx b/src/sage/combinat/posets/linear_extension_iterator.pyx index 59506021e07..906957fdbde 100644 --- a/src/sage/combinat/posets/linear_extension_iterator.pyx +++ b/src/sage/combinat/posets/linear_extension_iterator.pyx @@ -14,7 +14,7 @@ def _linear_extension_prepare(D): INPUT: - - ``D``, the Hasse diagram of a poset + - ``D`` -- the Hasse diagram of a poset OUTPUT: @@ -68,7 +68,6 @@ cdef void _linear_extension_switch(list _le, list _a, list _b, list _is_plus, Py If ``i == -1``, then the sign is changed. Otherwise, then ``_a[i]`` and ``_b[i]`` are transposed. - """ cdef Py_ssize_t a_index, b_index if i == -1: @@ -102,7 +101,6 @@ cdef bint _linear_extension_right_a(_D, list _le, list _a, list _b, Py_ssize_t i False sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested False - """ cdef Py_ssize_t yindex x = _a[i] @@ -117,7 +115,7 @@ cdef bint _linear_extension_right_a(_D, list _le, list _a, list _b, Py_ssize_t i @cython.boundscheck(False) cdef bint _linear_extension_right_b(_D, list _le, list _a, list _b, Py_ssize_t i) noexcept: """ - Return True if and only if ``_b[i]`` is incomparable with the + Return ``True`` if and only if ``_b[i]`` is incomparable with the elements to its right in ``_le``. This is the ``Right`` function described on page 8 of @@ -130,7 +128,6 @@ cdef bint _linear_extension_right_b(_D, list _le, list _a, list _b, Py_ssize_t i False sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested False - """ cdef Py_ssize_t yindex x = _b[i] @@ -155,7 +152,6 @@ def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssiz sage: le, a, b = _linear_extension_prepare(D) sage: [e for e in _linear_extension_gen(D, le, a, b, [True], len(a)-1)] # needs sage.modules [[0, 2, 1, 3, 4]] - """ cdef int mra, mrb, mla cdef Py_ssize_t index, index1 @@ -253,7 +249,7 @@ def linear_extension_iterator(D): INPUT: - - ``D``, the Hasse diagram of a poset. + - ``D`` -- the Hasse diagram of a poset .. WARNING:: diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index 2289d7c2341..cf62e234321 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -52,7 +52,7 @@ class LinearExtensionOfPoset(ClonableArray, INPUT: - - ``linear_extension`` -- a list of the elements of `P` + - ``linear_extension`` -- list of the elements of `P` - ``poset`` -- the underlying poset `P` .. SEEALSO:: :class:`~sage.combinat.posets.posets.Poset`, :class:`LinearExtensionsOfPoset` @@ -93,11 +93,12 @@ class LinearExtensionOfPoset(ClonableArray, @staticmethod def __classcall_private__(cls, linear_extension, poset): r""" - Implements the shortcut ``LinearExtensionOfPoset(linear_extension, poset)`` to ``LinearExtensionsOfPoset(poset)(linear_extension)`` + Implement the shortcut ``LinearExtensionOfPoset(linear_extension, poset)`` + to ``LinearExtensionsOfPoset(poset)(linear_extension)``. INPUT: - - ``linear_extension`` -- a list of elements of ``poset`` + - ``linear_extension`` -- list of elements of ``poset`` - ``poset`` -- a finite poset .. TODO:: check whether this method is still useful @@ -131,7 +132,7 @@ def __classcall_private__(cls, linear_extension, poset): def check(self): r""" - Checks whether ``self`` is indeed a linear extension of the underlying poset. + Check whether ``self`` is indeed a linear extension of the underlying poset. TESTS:: @@ -320,7 +321,8 @@ def tau(self, i): INPUT: - - `i` -- an integer between `1` and `n-1`, where `n` is the cardinality of the poset. + - ``i`` -- integer between `1` and `n-1`, where `n` is the + cardinality of the poset The operator `\tau_i` on a linear extension `\pi` of a poset `P` interchanges positions `i` and `i+1` if the result is @@ -472,12 +474,12 @@ def jump_count(self): class LinearExtensionsOfPoset(UniqueRepresentation, Parent): """ - The set of all linear extensions of a finite poset + The set of all linear extensions of a finite poset. INPUT: - ``poset`` -- a poset `P` of size `n` - - ``facade`` -- a boolean (default: ``False``) + - ``facade`` -- boolean (default: ``False``) .. SEEALSO:: @@ -540,7 +542,7 @@ def __init__(self, poset, facade) -> None: sage: TestSuite(L).run() # needs sage.modules sage: L = P.linear_extensions(facade=True) - sage: TestSuite(L).run(skip="_test_an_element") # needs sage.modules + sage: TestSuite(L).run(skip='_test_an_element') # needs sage.modules """ self._poset = poset self._is_facade = facade @@ -660,7 +662,7 @@ def cardinality(self): def __iter__(self): r""" - Iterates through the linear extensions of the underlying poset. + Iterate through the linear extensions of the underlying poset. EXAMPLES:: @@ -701,7 +703,6 @@ def __contains__(self, obj) -> bool: sage: [p for p in Permutations(list(P)) if list(p) in L] [[1, 2, 3, 4, 6, 12], [1, 2, 3, 6, 4, 12], [1, 2, 4, 3, 6, 12], [1, 3, 2, 4, 6, 12], [1, 3, 2, 6, 4, 12]] - """ if not self._is_facade: return super().__contains__(obj) @@ -710,12 +711,12 @@ def __contains__(self, obj) -> bool: def markov_chain_digraph(self, action='promotion', labeling='identity'): r""" - Return the digraph of the action of generalized promotion or tau on ``self`` + Return the digraph of the action of generalized promotion or tau on ``self``. INPUT: - - ``action`` -- 'promotion' or 'tau' (default: 'promotion') - - ``labeling`` -- 'identity' or 'source' (default: 'identity') + - ``action`` -- 'promotion' or 'tau' (default: ``'promotion'``) + - ``labeling`` -- 'identity' or 'source' (default: ``'identity'``) .. TODO:: @@ -801,26 +802,29 @@ def markov_chain_digraph(self, action='promotion', labeling='identity'): for i in R: child = getattr(x, action)(i + 1) d[x][child] += [i + 1] - G = DiGraph(d, format="dict_of_dicts") + G = DiGraph(d, format='dict_of_dicts') if have_dot2tex(): - G.set_latex_options(format="dot2tex", edge_labels=True, + G.set_latex_options(format='dot2tex', edge_labels=True, color_by_label={1: "blue", 2: "red", 3: "green", 4: "yellow"}) return G def markov_chain_transition_matrix(self, action='promotion', labeling='identity'): r""" - Return the transition matrix of the Markov chain for the action of generalized promotion or tau on ``self`` + Return the transition matrix of the Markov chain for the action of + generalized promotion or tau on ``self``. INPUT: - ``action`` -- ``'promotion'`` or ``'tau'`` (default: ``'promotion'``) - ``labeling`` -- ``'identity'`` or ``'source'`` (default: ``'identity'``) - This method yields the transition matrix of the Markov chain defined by the action of the generalized - promotion operator `\partial_i` (resp. `\tau_i`) on the set of linear extensions of a finite poset. - Here the transition from the linear extension `\pi` to `\pi'`, where `\pi' = \pi \partial_i` - (resp. `\pi'= \pi \tau_i`) is counted with weight `x_i` (resp. `x_{\pi_i}` if ``labeling`` is set to ``source``). + This method yields the transition matrix of the Markov chain defined by + the action of the generalized promotion operator `\partial_i` (resp. + `\tau_i`) on the set of linear extensions of a finite poset. Here the + transition from the linear extension `\pi` to `\pi'`, where + `\pi' = \pi \partial_i` (resp. `\pi'= \pi \tau_i`) is counted with + weight `x_i` (resp. `x_{\pi_i}` if ``labeling`` is set to ``source``). EXAMPLES:: @@ -855,7 +859,6 @@ def markov_chain_transition_matrix(self, action='promotion', labeling='identity' [ 0 x0 0 x2 -x1 - x3] .. SEEALSO:: :meth:`markov_chain_digraph`, :meth:`promotion`, :meth:`tau` - """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.matrix.constructor import matrix diff --git a/src/sage/combinat/posets/meson.build b/src/sage/combinat/posets/meson.build new file mode 100644 index 00000000000..07837832519 --- /dev/null +++ b/src/sage/combinat/posets/meson.build @@ -0,0 +1,34 @@ +py.install_sources( + 'all.py', + 'cartesian_product.py', + 'd_complete.py', + 'elements.py', + 'forest.py', + 'hasse_diagram.py', + 'incidence_algebras.py', + 'lattices.py', + 'linear_extensions.py', + 'mobile.py', + 'moebius_algebra.py', + 'poset_examples.py', + 'posets.py', + subdir: 'sage/combinat/posets', +) + +extension_data = { + 'hasse_cython' : files('hasse_cython.pyx'), + 'hasse_cython_flint' : files('hasse_cython_flint.pyx'), + 'linear_extension_iterator' : files('linear_extension_iterator.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/posets', + install: true, + include_directories: [inc_cpython, inc_ext, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + diff --git a/src/sage/combinat/posets/mobile.py b/src/sage/combinat/posets/mobile.py index 79d22aa1749..f529f6b664c 100644 --- a/src/sage/combinat/posets/mobile.py +++ b/src/sage/combinat/posets/mobile.py @@ -91,7 +91,7 @@ def _is_valid_ribbon(self, ribbon): INPUT: - - ``ribbon`` -- a list of elements that form a ribbon in your poset + - ``ribbon`` -- list of elements that form a ribbon in your poset TESTS:: diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index e2de5f4a751..468ad8d9a01 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -133,7 +133,7 @@ def check_int(n, minimum=0): sage: check_int(-1) Traceback (most recent call last): ... - ValueError: number of elements must be a non-negative integer, not -1 + ValueError: number of elements must be a nonnegative integer, not -1 sage: check_int(1, 3) Traceback (most recent call last): @@ -143,10 +143,10 @@ def check_int(n, minimum=0): sage: check_int('junk') Traceback (most recent call last): ... - ValueError: number of elements must be a non-negative integer, not junk + ValueError: number of elements must be a nonnegative integer, not junk """ if minimum == 0: - msg = "a non-negative integer" + msg = "a nonnegative integer" else: msg = f"an integer at least {minimum}" if n not in NonNegativeIntegers() or n < minimum: @@ -282,11 +282,11 @@ def BooleanLattice(n, facade=None, use_subsets=False): @staticmethod def ChainPoset(n, facade=None): - """ - Return a chain (a totally ordered poset) containing ``n`` elements. + r""" + Return a chain (a totally ordered poset) containing `n` elements. - - ``n`` (an integer) -- number of elements. - - ``facade`` (boolean) -- whether to make the returned poset a + - ``n`` -- integer; number of elements + - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor @@ -333,8 +333,8 @@ def AntichainPoset(n, facade=None): INPUT: - - ``n`` (an integer) -- number of elements - - ``facade`` (boolean) -- whether to make the returned poset a + - ``n`` -- integer; number of elements + - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor @@ -376,7 +376,7 @@ def PentagonPoset(facade=None): INPUT: - - ``facade`` (boolean) -- whether to make the returned poset a + - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor @@ -414,7 +414,7 @@ def DiamondPoset(n, facade=None): - ``n`` -- number of elements, an integer at least 3 - - ``facade`` (boolean) -- whether to make the returned poset a + - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor @@ -446,7 +446,7 @@ def Crown(n, facade=None): - ``n`` -- number of elements, an integer at least 2 - - ``facade`` (boolean) -- whether to make the returned poset a + - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor @@ -472,8 +472,8 @@ def DivisorLattice(n, facade=None): INPUT: - - ``n`` -- an integer - - ``facade`` (boolean) -- whether to make the returned poset a + - ``n`` -- integer + - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor @@ -578,7 +578,6 @@ def RestrictedIntegerPartitions(n): Finite poset containing 15 elements sage: len(P.cover_relations()) 17 - """ def lower_covers(partition): r""" @@ -614,7 +613,7 @@ def IntegerPartitionsDominanceOrder(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -688,8 +687,8 @@ def ProductOfChains(chain_lengths, facade=None): """ Return a product of chains. - - ``chain_lengths`` -- A list of nonnegative integers; number of - elements in each chain. + - ``chain_lengths`` -- list of nonnegative integers; number of + elements in each chain - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the @@ -741,7 +740,7 @@ def RandomPoset(n, p): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer - ``p`` -- a probability, a real number between 0 and 1 (inclusive) @@ -801,11 +800,11 @@ def RandomLattice(n, p, properties=None): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer - ``p`` -- a probability, a positive real number less than one - - ``properties`` -- a list of properties for the lattice. Currently + - ``properties`` -- list of properties for the lattice. Currently implemented: * ``None``, no restrictions for lattices to create @@ -938,7 +937,7 @@ def SetPartitions(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -1019,16 +1018,14 @@ def StandardExample(n, facade=None): INPUT: - - ``n`` -- an integer `\ge 2`, dimension of the constructed poset + - ``n`` -- integer `\ge 2`; dimension of the constructed poset - ``facade`` -- boolean; whether to make the returned poset a facade poset (see :mod:`sage.categories.facade_sets`); the default behaviour is the same as the default behaviour of the :func:`~sage.combinat.posets.posets.Poset` constructor - OUTPUT: - - The standard example of a poset of dimension `n`. + OUTPUT: the standard example of a poset of dimension `n` EXAMPLES:: @@ -1085,7 +1082,7 @@ def SymmetricGroupBruhatIntervalPoset(start, end): - ``end`` -- list permutation (same n, of course) - .. note:: + .. NOTE:: Must have ``start`` <= ``end``. @@ -1120,15 +1117,15 @@ def SymmetricGroupBruhatIntervalPoset(start, end): return Poset(nodes) @staticmethod - def SymmetricGroupWeakOrderPoset(n, labels="permutations", side="right"): + def SymmetricGroupWeakOrderPoset(n, labels='permutations', side='right'): r""" The poset of permutations of `\{ 1, 2, \ldots, n \}` with respect to the weak order (also known as the permutohedron order, cf. :meth:`~sage.combinat.permutation.Permutation.permutohedron_lequal`). - The optional variable ``labels`` (default: ``"permutations"``) + The optional variable ``labels`` (default: ``'permutations'``) determines the labelling of the elements if `n < 10`. The optional - variable ``side`` (default: ``"right"``) determines whether the + variable ``side`` (default: ``'right'``) determines whether the right or the left permutohedron order is to be used. EXAMPLES:: @@ -1183,13 +1180,13 @@ def TetrahedralPoset(n, *colors, **labels): INPUT: - - ``n`` -- Defines the number (n-1) of layers in the poset. + - ``n`` -- defines the number (n-1) of layers in the poset - - ``colors`` -- The colors that define the covering relations of the - poset. Colors used are 'green', 'red', 'yellow', 'orange', 'silver', - and 'blue'. + - ``colors`` -- the colors that define the covering relations of the + poset; colors used are 'green', 'red', 'yellow', 'orange', 'silver', + and 'blue' - - ``labels`` -- Keyword variable used to determine whether the poset + - ``labels`` -- keyword variable used to determine whether the poset is labeled with integers or tuples. To label with integers, the method should be called with ``labels='integers'``. Otherwise, the labeling will default to tuples. @@ -1312,13 +1309,13 @@ def NoncrossingPartitions(W): return W.noncrossing_partition_lattice() @staticmethod - def SymmetricGroupAbsoluteOrderPoset(n, labels="permutations"): + def SymmetricGroupAbsoluteOrderPoset(n, labels='permutations'): r""" Return the poset of permutations with respect to absolute order. INPUT: - - ``n`` -- a positive integer + - ``n`` -- a positive integer - ``label`` -- (default: ``'permutations'``) a label for the elements of the poset returned by the function; the options are @@ -1334,9 +1331,9 @@ def SymmetricGroupAbsoluteOrderPoset(n, labels="permutations"): sage: posets.SymmetricGroupAbsoluteOrderPoset(4) # needs sage.groups Finite poset containing 24 elements - sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels="cycles") # needs sage.groups + sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels='cycles') # needs sage.groups Finite poset containing 6 elements - sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels="reduced_words") # needs sage.groups + sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels='reduced_words') # needs sage.groups Finite poset containing 6 elements """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -1362,8 +1359,8 @@ def UpDownPoset(n, m=1): INPUT: - - ``n`` -- nonnegative integer, number of elements in the poset - - ``m`` -- nonnegative integer (default 1), how frequently down + - ``n`` -- nonnegative integer; number of elements in the poset + - ``m`` -- nonnegative integer (default: 1); how frequently down steps occur OUTPUT: @@ -1409,9 +1406,9 @@ def YoungDiagramPoset(lam, dual=False): INPUT: - ``lam`` -- a partition - - ``dual`` -- (default: ``False``) determines the orientation - of the poset; if ``True``, then it is a join semilattice, - otherwise it is a meet semilattice + - ``dual`` -- boolean (default: ``False``); determines the orientation + of the poset. If ``True``, then it is a join semilattice, + otherwise it is a meet semilattice. EXAMPLES:: @@ -1429,9 +1426,8 @@ def YoungDiagramPoset(lam, dual=False): if dual: def cell_geq(a, b): """ - Nested function that returns `True` if the cell `a` is - to the right or below - the cell `b` in the (English) Young diagram. + Nested function that returns ``True`` if the cell `a` is to the + right or below the cell `b` in the (English) Young diagram. """ return ((a[0] == b[0] + 1 and a[1] == b[1]) or (a[1] == b[1] + 1 and a[0] == b[0])) @@ -1439,7 +1435,7 @@ def cell_geq(a, b): else: def cell_leq(a, b): """ - Nested function that returns `True` if the cell `a` is + Nested function that returns ``True`` if the cell `a` is to the left or above the cell `b` in the (English) Young diagram. """ @@ -1457,7 +1453,7 @@ def YoungsLattice(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -1581,7 +1577,7 @@ def DoubleTailedDiamond(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -1606,7 +1602,7 @@ def PermutationPattern(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer A permutation `u = u_1 \cdots u_n` contains the pattern `v = v_1 \cdots v_m` if there is a (not necessarily consecutive) @@ -1721,7 +1717,7 @@ def PermutationPatternOccurrenceInterval(bottom, top, pos): - ``bottom``, ``top`` -- permutations where ``top`` contains ``bottom`` as a pattern - - ``pos`` -- a list of indices indicating a distinguished copy of + - ``pos`` -- list of indices indicating a distinguished copy of ``bottom`` inside ``top`` (indexed starting at 0) For further information (and picture illustrating included example), @@ -1804,7 +1800,7 @@ def MobilePoset(ribbon, hangers, anchor=None): INPUT: - ``ribbon`` -- a finite poset that is a ribbon - - ``hangers`` -- a dictionary mapping an element on the ribbon + - ``hangers`` -- dictionary mapping an element on the ribbon to a list of d-complete posets that it covers - ``anchor`` -- (optional) a ``tuple`` (``ribbon_elmt``, ``anchor_elmt``, ``anchor_poset``), where ``anchor_elmt`` covers @@ -1863,7 +1859,7 @@ def _random_lattice(n, p): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer - ``p`` -- a number at least zero and less than one; higher number means more covering relations @@ -1935,7 +1931,7 @@ def _random_dismantlable_lattice(n): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer OUTPUT: @@ -1978,7 +1974,7 @@ def _random_planar_lattice(n): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer OUTPUT: @@ -2029,7 +2025,7 @@ def _random_distributive_lattice(n): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer OUTPUT: @@ -2086,7 +2082,7 @@ def _random_stone_lattice(n): INPUT: - - ``n`` -- number of elements, a non-negative integer + - ``n`` -- number of elements, a nonnegative integer OUTPUT: diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index f462becaa17..e565eb3d2ee 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -84,7 +84,7 @@ :meth:`~FinitePoset.is_incomparable_chain_free` | Return ``True`` if the poset is (m+n)-free. :meth:`~FinitePoset.is_slender` | Return ``True`` if the poset is slender. :meth:`~FinitePoset.is_sperner` | Return ``True`` if the poset is Sperner. - :meth:`~FinitePoset.is_join_semilattice` | Return ``True`` is the poset has a join operation. + :meth:`~FinitePoset.is_join_semilattice` | Return ``True`` if the poset has a join operation. :meth:`~FinitePoset.is_meet_semilattice` | Return ``True`` if the poset has a meet operation. **Minimal and maximal elements** @@ -236,7 +236,7 @@ :widths: 30, 70 :delim: | - :meth:`~FinitePoset.lequal_matrix` | Computes the matrix whose ``(i,j)`` entry is 1 if ``self.linear_extension()[i] < self.linear_extension()[j]`` and 0 otherwise. + :meth:`~FinitePoset.lequal_matrix` | Compute the matrix whose ``(i,j)`` entry is 1 if ``self.linear_extension()[i] < self.linear_extension()[j]`` and 0 otherwise. :meth:`~FinitePoset.moebius_function` | Return the value of Möbius function of given elements in the poset. :meth:`~FinitePoset.moebius_function_matrix` | Return a matrix whose ``(i,j)`` entry is the value of the Möbius function evaluated at ``self.linear_extension()[i]`` and ``self.linear_extension()[j]``. :meth:`~FinitePoset.coxeter_transformation` | Return the matrix of the Auslander-Reiten translation acting on the Grothendieck group of the derived category of modules. @@ -256,7 +256,7 @@ :meth:`~FinitePoset.list` | List the elements of the poset. :meth:`~FinitePoset.cuts` | Return the cuts of the given poset. :meth:`~FinitePoset.dilworth_decomposition` | Return a partition of the points into the minimal number of chains. - :meth:`~FinitePoset.greene_shape` | Computes the Greene-Kleitman partition aka Greene shape of the poset ``self``. + :meth:`~FinitePoset.greene_shape` | Compute the Greene-Kleitman partition aka Greene shape of the poset ``self``. :meth:`~FinitePoset.incidence_algebra` | Return the incidence algebra of ``self``. :meth:`~FinitePoset.is_EL_labelling` | Return whether ``f`` is an EL labelling of the poset. :meth:`~FinitePoset.isomorphic_subposets_iterator` | Return an iterator over the subposets isomorphic to another poset. @@ -266,7 +266,7 @@ :meth:`~FinitePoset.random_order_ideal` | Return a random order ideal of ``self`` with uniform probability. :meth:`~FinitePoset.rank` | Return the rank of an element, or the rank of the poset. :meth:`~FinitePoset.rank_function` | Return a rank function of the poset, if it exists. - :meth:`~FinitePoset.unwrap` | Unwraps an element of this poset. + :meth:`~FinitePoset.unwrap` | Unwrap an element of this poset. :meth:`~FinitePoset.atkinson` | Return the `a`-spectrum of a poset whose undirected Hasse diagram is a forest. :meth:`~FinitePoset.spectrum` | Return the `a`-spectrum of this poset. @@ -363,21 +363,21 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio 6. A previously constructed poset (the poset itself is returned). - - ``element_labels`` -- (default: ``None``); an optional list or - dictionary of objects that label the poset elements. + - ``element_labels`` -- (default: ``None``) an optional list or + dictionary of objects that label the poset elements - - ``cover_relations`` -- a boolean (default: ``False``); whether the + - ``cover_relations`` -- boolean (default: ``False``); whether the data can be assumed to describe a directed acyclic graph whose - arrows are cover relations; otherwise, the cover relations are + arrows are cover relations. Otherwise, the cover relations are first computed. - - ``linear_extension`` -- a boolean (default: ``False``); whether to + - ``linear_extension`` -- boolean (default: ``False``); whether to use the provided list of elements as default linear extension - for the poset; otherwise a linear extension is computed. If the data + for the poset. Otherwise a linear extension is computed. If the data is given as the pair ``(E, f)``, then ``E`` is taken to be the linear extension. - - ``facade`` -- a boolean or ``None`` (default); whether the + - ``facade`` -- boolean or ``None`` (default); whether the :meth:`Poset`'s elements should be wrapped to make them aware of the Poset they belong to. @@ -713,7 +713,7 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio elif isinstance(data, DiGraph): # type 4 D = data.copy(immutable=True) elif isinstance(data, dict): # type 3: dictionary of upper covers - D = DiGraph(data, format="dict_of_lists") + D = DiGraph(data, format='dict_of_lists') elif isinstance(data, (list, tuple)): # types 1, 2, 3 (list/tuple) if len(data) == 2: # types 1 or 2 if callable(data[1]): # type 2 @@ -736,7 +736,7 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio vertices = range(len(data)) D = DiGraph({v: [u for u in cov if u != v] for v, cov in zip(vertices, data)}, - format="dict_of_lists") + format='dict_of_lists') else: raise ValueError("not valid poset data") @@ -796,9 +796,9 @@ class FinitePoset(UniqueRepresentation, Parent): then ``elements`` is considered as a specified linear extension of the poset and the `linear_extension` attribute is set. - - ``category`` -- :class:`FinitePosets`, or a subcategory thereof. + - ``category`` -- :class:`FinitePosets`, or a subcategory thereof - - ``facade`` -- a boolean or ``None`` (default); whether the + - ``facade`` -- boolean or ``None`` (default); whether the :class:`~sage.combinat.posets.posets.FinitePoset`'s elements should be wrapped to make them aware of the Poset they belong to. @@ -817,7 +817,7 @@ class FinitePoset(UniqueRepresentation, Parent): :class:`~sage.combinat.posets.posets.FinitePoset`, itself built with ``facade = False``) - - ``key`` -- any hashable value (default: ``None``). + - ``key`` -- any hashable value (default: ``None``) EXAMPLES:: @@ -956,7 +956,7 @@ class contains. For example, for this class, ``FinitePoset``, @staticmethod def __classcall__(cls, hasse_diagram, elements=None, category=None, facade=None, key=None): """ - Normalizes the arguments passed to the constructor. + Normalize the arguments passed to the constructor. INPUT: @@ -998,7 +998,7 @@ def __classcall__(cls, hasse_diagram, elements=None, category=None, facade=None, hasse_diagram = poset._hasse_diagram.relabel(relabel, inplace=False) hasse_diagram = hasse_diagram.copy(immutable=True) else: - hasse_diagram = HasseDiagram(hasse_diagram, data_structure="static_sparse") + hasse_diagram = HasseDiagram(hasse_diagram, data_structure='static_sparse') if facade is None: facade = True if elements is not None: @@ -1081,7 +1081,7 @@ def __init__(self, hasse_diagram, elements, category, facade, key) -> None: # So range(len(D)) becomes a linear extension of the poset. rdict = {element: i for i, element in enumerate(self._elements)} self._hasse_diagram = HasseDiagram(hasse_diagram.relabel(rdict, inplace=False), - data_structure="static_sparse") + data_structure='static_sparse') self._element_to_vertex_dict = rdict self._is_facade = facade @@ -1279,7 +1279,7 @@ def __contains__(self, x) -> bool: def _element_constructor_(self, element): """ - Constructs an element of ``self`` + Construct an element of ``self``. EXAMPLES:: @@ -1316,7 +1316,7 @@ def _element_constructor_(self, element): def __call__(self, element): """ - Creates elements of this poset + Create elements of this poset. This overrides the generic call method for all parents :meth:`Parent.__call__`, as a work around to allow for facade @@ -1370,7 +1370,7 @@ def hasse_diagram(self): [1, 3, 5, 15] sage: H.edges(sort=True) [(1, 3, None), (1, 5, None), (3, 15, None), (5, 15, None)] - sage: H.set_latex_options(format="dot2tex") # needs sage.plot + sage: H.set_latex_options(format='dot2tex') # needs sage.plot sage: view(H) # optional - dot2tex, not tested (opens external window) """ G = DiGraph(self._hasse_diagram).relabel(self._list, inplace=False) @@ -1427,7 +1427,7 @@ def _repr_(self): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -1472,7 +1472,7 @@ def _rich_repr_(self, display_manager, **kwds): def __iter__(self): """ - Iterates through the elements of a linear extension of the poset. + Iterate through the elements of a linear extension of the poset. EXAMPLES:: @@ -1488,12 +1488,12 @@ def sorted(self, l, allow_incomparable=True, remove_duplicates=False): INPUT: - - ``l`` -- a list of elements of the poset - - ``allow_incomparable`` -- a Boolean. If ``True`` (the default), - return incomparable elements in some order; if ``False``, raise + - ``l`` -- list of elements of the poset + - ``allow_incomparable`` -- boolean (default: ``True``); if ``True``, + return incomparable elements in some order. If ``False``, raise an error if ``l`` is not a chain of the poset. - - ``remove_duplicates`` -- a Boolean. If ``True``, remove duplicates - from the output list. + - ``remove_duplicates`` -- boolean (default: ``False``); if ``True``, + remove duplicates from the output list EXAMPLES:: @@ -1553,9 +1553,8 @@ def linear_extension(self, linear_extension=None, check=True): - ``linear_extension`` -- (default: ``None``) a list of the elements of ``self`` - - ``check`` -- a boolean (default: ``True``); - whether to check that ``linear_extension`` is indeed a - linear extension of ``self``. + - ``check`` -- boolean (default: ``True``); whether to check that + ``linear_extension`` is indeed a linear extension of ``self`` EXAMPLES:: @@ -1610,10 +1609,10 @@ def linear_extensions(self, facade=False): INPUT: - - ``facade`` -- a boolean (default: ``False``); - whether to return the linear extensions as plain lists + - ``facade`` -- boolean (default: ``False``); whether to return the + linear extensions as plain lists - .. warning:: + .. WARNING:: The ``facade`` option is not yet fully functional:: @@ -1740,7 +1739,7 @@ def atkinson(self, a): Given an element `a` in a poset `P`, the `a`-spectrum is the list of integers whose `i`-th term contains the number of linear extensions of - `P` with element `a` located in the i-th position. + `P` with element `a` located in the `i`-th position. INPUT: @@ -1748,9 +1747,7 @@ def atkinson(self, a): - ``a`` -- an element of the poset - OUTPUT: - - The `a`-spectrum of this poset, returned as a list. + OUTPUT: the `a`-spectrum of this poset, returned as a list EXAMPLES:: @@ -1830,7 +1827,7 @@ def is_linear_extension(self, l) -> bool: INPUT: - - ``l`` -- a list (or iterable) containing all of the elements of ``self`` exactly once + - ``l`` -- list (or iterable) containing all of the elements of ``self`` exactly once EXAMPLES:: @@ -1908,27 +1905,27 @@ def plot(self, label_elements=True, element_labels=None, - Options to change element look: - * ``element_colors`` -- a dictionary where keys are colors and values + * ``element_colors`` -- dictionary where keys are colors and values are lists of elements * ``element_color`` -- a color for elements not set in ``element_colors`` * ``element_shape`` -- the shape of elements, like ``'s'`` for square; see https://matplotlib.org/api/markers_api.html for the list - * ``element_size`` (default: 200) - the size of elements - * ``label_elements`` (default: ``True``) - whether to display + * ``element_size`` -- (default: 200) the size of elements + * ``label_elements`` -- boolean (default: ``True``); whether to display element labels - * ``element_labels`` (default: ``None``) - a dictionary where keys + * ``element_labels`` (default: ``None``); a dictionary where keys are elements and values are labels to show - Options to change cover relation look: - * ``cover_colors`` -- a dictionary where keys are colors and values + * ``cover_colors`` -- dictionary where keys are colors and values are lists of cover relations given as pairs of elements * ``cover_color`` -- a color for elements not set in ``cover_colors`` * ``cover_style`` -- style for cover relations: ``'solid'``, ``'dashed'``, ``'dotted'`` or ``'dashdot'`` - * ``cover_labels`` -- a dictionary, list or function representing + * ``cover_labels`` -- dictionary, list or function representing labels of the covers of the poset. When set to ``None`` (default) no label is displayed on the edges of the Hasse Diagram. * ``cover_labels_background`` -- a background color for cover @@ -1937,11 +1934,11 @@ def plot(self, label_elements=True, element_labels=None, - Options to change overall look: - * ``figsize`` (default: 8) - size of the whole plot + * ``figsize`` -- (default: 8) size of the whole plot * ``title`` -- a title for the plot * ``fontsize`` -- fontsize for the title - * ``border`` (default: ``False``) - whether to draw a border over the - plot + * ``border`` -- (default: ``False``) whether to draw a border over + the plot .. NOTE:: @@ -2111,15 +2108,14 @@ def show(self, label_elements=True, element_labels=None, INPUT: - - ``label_elements`` (default: ``True``) -- whether to display + - ``label_elements`` -- boolean (default: ``True``); whether to display element labels - - ``element_labels`` (default: ``None``) -- a dictionary of - element labels + - ``element_labels`` -- dictionary (default: ``None``) of element labels - - ``cover_labels`` -- a dictionary, list or function representing labels - of the covers of ``self``. When set to ``None`` (default) no label is - displayed on the edges of the Hasse Diagram. + - ``cover_labels`` -- dictionary, list or function representing labels + of the covers of ``self``; when set to ``None`` (default) no label is + displayed on the edges of the Hasse Diagram .. NOTE:: @@ -2202,7 +2198,7 @@ def cover_relations(self): """ return list(self.cover_relations_iterator()) - @combinatorial_map(name="cover_relations_graph") + @combinatorial_map(name='cover_relations_graph') def cover_relations_graph(self): """ Return the (undirected) graph of cover relations. @@ -2305,9 +2301,7 @@ def diamonds(self): Thus each edge represents a cover relation in the Hasse diagram. We represent this as the tuple `(w, x, y, z)`. - OUTPUT: - - A tuple with + OUTPUT: a tuple with - a list of all diamonds in the Hasse Diagram, - a boolean checking that every `w,x,y` that form a ``V``, there is a @@ -2545,9 +2539,7 @@ def intervals_poset(self): r""" Return the natural partial order on the set of intervals of the poset. - OUTPUT: - - a finite poset + OUTPUT: a finite poset The poset of intervals of a poset `P` has the set of intervals `[x,y]` in `P` as elements, endowed with the order relation defined by @@ -2599,7 +2591,7 @@ def intervals_poset(self): covers.extend([[(a, b), (aa, b)] for aa in self.upper_covers(a) if self.le(aa, b)]) - dg = DiGraph([ints, covers], format="vertices_and_edges") + dg = DiGraph([ints, covers], format='vertices_and_edges') return constructor(dg, cover_relations=True) def relations_iterator(self, strict=False): @@ -2611,9 +2603,8 @@ def relations_iterator(self, strict=False): INPUT: - - ``strict`` -- a boolean (default ``False``) if ``True``, returns - an iterator over relations `x < y`, excluding all - relations `x \leq x`. + - ``strict`` -- boolean (default: ``False``); if ``True``, return + an iterator over relations `x < y`, excluding all relations `x \leq x` OUTPUT: @@ -3153,7 +3144,7 @@ def height(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -3296,14 +3287,13 @@ def is_chain_of_poset(self, elms, ordered=False) -> bool: INPUT: - - ``elms`` -- a list or other iterable containing some elements + - ``elms`` -- list or other iterable containing some elements of the poset - - ``ordered`` -- a Boolean. If ``True``, then return ``True`` - only if elements in ``elms`` are strictly increasing in the - poset; this makes no sense if ``elms`` is a set. If ``False`` - (the default), then elements can be repeated and be in any - order. + - ``ordered`` -- boolean; if ``True``, then return ``True`` only if + elements in ``elms`` are strictly increasing in the poset. This makes + no sense if ``elms`` is a set. If ``False`` (the default), then + elements can be repeated and be in any order. EXAMPLES:: @@ -3531,11 +3521,11 @@ def dimension(self, certificate=False, *, solver=None, integrality_tolerance=1e- INPUT: - - ``certificate`` (boolean; default:``False``) -- whether to return an + - ``certificate`` -- boolean (default: ``False``); whether to return an integer (the dimension) or a certificate, i.e. a smallest set of - linear extensions. + linear extensions - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -3544,7 +3534,7 @@ def dimension(self, certificate=False, *, solver=None, integrality_tolerance=1e- :class:`MixedIntegerLinearProgram `. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` .. NOTE:: @@ -3653,7 +3643,7 @@ def dimension(self, certificate=False, *, solver=None, integrality_tolerance=1e- def init_LP(k, cycles, inc_P): r""" - Initialize a LP object with k colors and the constraints from 'cycles' + Initialize a LP object with k colors and the constraints from 'cycles'. sage: init_LP(1,2,3) # not tested """ @@ -3775,7 +3765,7 @@ def jump_number(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) Whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -3873,7 +3863,7 @@ def is_jump_critical(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -4313,9 +4303,7 @@ def coxeter_transformation(self): r""" Return the Coxeter transformation of the poset. - OUTPUT: - - a square matrix with integer coefficients + OUTPUT: a square matrix with integer coefficients The output is the matrix of the Auslander-Reiten translation acting on the Grothendieck group of the derived category of @@ -4348,9 +4336,7 @@ def coxeter_polynomial(self): """ Return the Coxeter polynomial of the poset. - OUTPUT: - - a polynomial in one variable + OUTPUT: a polynomial in one variable The output is the characteristic polynomial of the Coxeter transformation. This polynomial only depends on the derived @@ -4379,7 +4365,7 @@ def coxeter_smith_form(self, algorithm='singular'): INPUT: - - ``algorithm`` -- optional (default ``'singular'``), possible + - ``algorithm`` -- (default: ``'singular'``) possible values are ``'singular'``, ``'sage'``, ``'gap'``, ``'pari'``, ``'maple'``, ``'magma'``, ``'fricas'`` @@ -4387,9 +4373,7 @@ def coxeter_smith_form(self, algorithm='singular'): algorithm. Sage is rather slow, Singular is faster and Pari is fast at least for small sizes. - OUTPUT: - - - list of polynomials in one variable, each one dividing the next one + OUTPUT: list of polynomials in one variable, each one dividing the next one The output list is a refinement of the characteristic polynomial of the Coxeter transformation, which is its product. This list @@ -4482,7 +4466,7 @@ def is_meet_semilattice(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -4555,7 +4539,7 @@ def is_join_semilattice(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -4730,8 +4714,8 @@ def antichains(self, element_constructor=None): INPUT: - - ``element_constructor`` -- a function taking an iterable as - argument (default: ``list``) + - ``element_constructor`` -- a function taking an iterable as + argument (default: ``list``) OUTPUT: @@ -4821,7 +4805,7 @@ def width(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -5258,9 +5242,7 @@ def factor(self): Cartesian products) is unique up to reordering and isomorphism. - OUTPUT: - - a list of posets + OUTPUT: list of posets EXAMPLES:: @@ -5380,7 +5362,7 @@ def disjoint_union(self, other, labels='pairs'): INPUT: - - ``other``, a poset. + - ``other`` -- poset - ``labels`` -- (defaults to 'pairs') If set to 'pairs', each element ``v`` in this poset will be named ``(0,v)`` and each @@ -5544,7 +5526,7 @@ def ordinal_sum(self, other, labels='pairs'): INPUT: - - ``other``, a poset. + - ``other`` -- poset - ``labels`` -- (defaults to 'pairs') If set to 'pairs', each element ``v`` in this poset will be named ``(0,v)`` and each @@ -5646,9 +5628,9 @@ def star_product(self, other, labels='pairs'): INPUT: - - ``other`` -- a poset. + - ``other`` -- a poset - - ``labels`` -- (defaults to 'pairs') If set to 'pairs', each + - ``labels`` -- string (default: ``'pairs'``); if set to 'pairs', each element ``v`` in this poset will be named ``(0, v)`` and each element ``u`` in ``other`` will be named ``(1, u)`` in the result. If set to 'integers', the elements of the result @@ -5877,7 +5859,7 @@ def with_bounds(self, labels=('bottom', 'top')): INPUT: - - ``labels`` -- A pair of elements to use as a bottom and top + - ``labels`` -- a pair of elements to use as a bottom and top element of the poset. Default is strings ``'bottom'`` and ``'top'``. Either of them can be ``None``, and then a new bottom or top element will not be added. @@ -6021,7 +6003,7 @@ def without_bounds(self): This is useful as an input for the method :meth:`order_complex`. If there is either no top or no bottom element, this - raises a :class:`TypeError`. + raises a :exc:`TypeError`. EXAMPLES:: @@ -6340,7 +6322,7 @@ def with_linear_extension(self, linear_extension): category=self.category(), facade=self._is_facade) - def graphviz_string(self, graph_string="graph", edge_string="--"): + def graphviz_string(self, graph_string='graph', edge_string='--'): r""" Return a representation in the DOT language, ready to render in graphviz. @@ -7105,11 +7087,9 @@ def order_complex(self, on_ints=False): INPUT: - - ``on_ints`` -- a boolean (default: ``False``) - - OUTPUT: + - ``on_ints`` -- boolean (default: ``False``) - an order complex of type :class:`SimplicialComplex` + OUTPUT: an order complex of type :class:`SimplicialComplex` EXAMPLES:: @@ -7306,9 +7286,7 @@ def M_triangle(self): The poset is expected to be graded. - OUTPUT: - - an :class:`~sage.combinat.triangles_FHM.M_triangle` + OUTPUT: an :class:`~sage.combinat.triangles_FHM.M_triangle` The M-triangle is the generating polynomial of the Möbius numbers @@ -7353,7 +7331,7 @@ def f_polynomial(self): The coefficient of `q^i` is the number of chains of `i+1` elements containing both bounds of the poset. - .. note:: + .. NOTE:: This is slightly different from the ``fPolynomial`` method in Macaulay2. @@ -7668,7 +7646,7 @@ def chain_polynomial(self): elements in the poset. List of coefficients of this polynomial is also called a *f-vector* of the poset. - .. note:: + .. NOTE:: This is not what has been called the chain polynomial in [St1986]_. The latter is identical with the order @@ -7704,18 +7682,7 @@ def chain_polynomial(self): sage: R.chain_polynomial() q + 1 """ - hasse = self._hasse_diagram - q = polygen(ZZ, 'q') - one = q.parent().one() - hasse_size = hasse.cardinality() - chain_polys = [0] * hasse_size - # chain_polys[i] will be the generating function for the - # chains with topmost vertex i (in the labelling of the - # Hasse diagram). - for i in range(hasse_size): - chain_polys[i] = q + sum(q * chain_polys[j] - for j in hasse.principal_order_ideal(i)) - return one + sum(chain_polys) + return self._hasse_diagram.chain_polynomial() def order_polynomial(self): r""" @@ -7785,11 +7752,9 @@ def promotion(self, i=1): INPUT: - - ``i`` -- an integer between `1` and `n` (default: `1`) - - OUTPUT: + - ``i`` -- integer between `1` and `n` (default: `1`) - - an isomorphic poset, with the same default linear extension + OUTPUT: an isomorphic poset, with the same default linear extension The extended promotion is defined on a poset ``self`` of size `n` by applying the promotion operator `\tau_i \tau_{i+1} @@ -7871,9 +7836,7 @@ def evacuation(self): Compute evacuation on the linear extension associated to the poset ``self``. - OUTPUT: - - - an isomorphic poset, with the same default linear extension + OUTPUT: an isomorphic poset, with the same default linear extension Evacuation is defined on a poset ``self`` of size `n` by applying the evacuation operator @@ -7988,7 +7951,7 @@ def is_slender(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -8103,9 +8066,9 @@ def is_eulerian(self, k=None, certificate=False): INPUT: - - ``k``, an integer -- only check if the poset is `k`-eulerian. + - ``k`` -- integer; only check if the poset is `k`-eulerian. If ``None`` (the default), check if the poset is Eulerian. - - ``certificate``, a Boolean -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -8215,7 +8178,7 @@ def is_greedy(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) whether to return + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate OUTPUT: @@ -8393,7 +8356,7 @@ def frank_network(self): for i in self: pdict[(0, i)] = [(1, j) for j in self if self.ge(i, j)] pdict[(1, i)] = [(2, 0)] - G = DiGraph(pdict, format="dict_of_lists") + G = DiGraph(pdict, format='dict_of_lists') a = {e: 0 for e in G.edge_iterator(labels=False)} for i in self: a[((0, i), (1, i))] = 1 @@ -8607,7 +8570,7 @@ def cuts(self): from sage.graphs.graph import Graph from sage.graphs.independent_sets import IndependentSets auxg = Graph({(u, 0): [(v, 1) for v in self if not self.ge(u, v)] - for u in self}, format="dict_of_lists") + for u in self}, format='dict_of_lists') auxg.add_vertices([(v, 1) for v in self]) return [frozenset([xa for xa, xb in c if xb == 0]) for c in IndependentSets(auxg, maximal=True)] @@ -8621,9 +8584,7 @@ def completion_by_cuts(self): See the :wikipedia:`Dedekind-MacNeille completion`. - OUTPUT: - - - a finite lattice + OUTPUT: a finite lattice EXAMPLES:: @@ -8660,9 +8621,7 @@ def incidence_algebra(self, R, prefix='I'): r""" Return the incidence algebra of ``self`` over ``R``. - OUTPUT: - - An instance of :class:`sage.combinat.posets.incidence_algebras.IncidenceAlgebra`. + OUTPUT: an instance of :class:`sage.combinat.posets.incidence_algebras.IncidenceAlgebra` EXAMPLES:: @@ -8815,7 +8774,7 @@ def is_induced_subposet(self, other): INPUT: - - ``other``, a poset. + - ``other`` -- poset .. NOTE:: @@ -8925,11 +8884,11 @@ class FinitePosets_n(UniqueRepresentation, Parent): sage: P.cardinality() 5 sage: for p in P: print(p.cover_relations()) - [] - [[1, 2]] + [[1, 2], [0, 2]] [[0, 1], [0, 2]] + [[0, 2]] [[0, 1], [1, 2]] - [[1, 2], [0, 2]] + [] """ def __init__(self, n) -> None: @@ -8971,33 +8930,46 @@ def __contains__(self, P) -> bool: return P in FinitePosets() and P.cardinality() == self._n def __iter__(self): - """ + r""" Return an iterator of representatives of the isomorphism classes of finite posets of a given size. .. NOTE:: - This uses the DiGraph iterator as a backend to construct - transitively-reduced, acyclic digraphs. + If the size `n\leq 16`, this uses an iterator from + ``nauty`` as a backend to construct only transitively-reduced, + acyclic digraphs. Otherwise it uses a slow naive iterator, + as the ``nauty`` iterator is not available. EXAMPLES:: sage: P = Posets(2) sage: list(P) [Finite poset containing 2 elements, Finite poset containing 2 elements] + + TESTS:: + + sage: it = iter(Posets(17)) + sage: next(it) + Finite poset containing 17 elements """ - from sage.graphs.digraph_generators import DiGraphGenerators - for dig in DiGraphGenerators()(self._n, is_poset): + if self._n <= 16: + it = digraphs.nauty_posetg(f"{self._n} o") + else: + it = digraphs(self._n, is_poset) + + for dig in it: # We need to relabel the digraph since range(self._n) must be a linear # extension. Too bad we need to compute this again. TODO: Fix this. - label_dict = dict(zip(dig.topological_sort(), range(dig.order()))) - yield FinitePoset(dig.relabel(label_dict, inplace=False)) + label_dict = dict(zip(dig.topological_sort(), range(self._n))) + dig.relabel(label_dict, inplace=True) + yield FinitePoset(dig) def cardinality(self, from_iterator=False): r""" Return the cardinality of this object. - .. note:: + .. NOTE:: By default, this returns pre-computed values obtained from the On-Line Encyclopedia of Integer Sequences (:oeis:`A000112`). diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index a5e8bb2e1ce..8bde8028ae2 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -105,7 +105,7 @@ def q_factorial(n, q=None): sage: q_factorial(3, p) p^3 + 2*p^2 + 2*p + 1 - The `q`-analogue of `n!` is only defined for `n` a non-negative + The `q`-analogue of `n!` is only defined for `n` a nonnegative integer (:issue:`11411`):: sage: q_factorial(-2) @@ -289,9 +289,9 @@ def q_binomial(n, k, q=None, algorithm='auto'): Check that arbitrary polynomials work:: sage: R. = ZZ[] - sage: q_binomial(2, 1, x^2 - 1, algorithm="naive") + sage: q_binomial(2, 1, x^2 - 1, algorithm='naive') x^2 - sage: q_binomial(2, 1, x^2 - 1, algorithm="cyclotomic") + sage: q_binomial(2, 1, x^2 - 1, algorithm='cyclotomic') x^2 Check that the parent is always the parent of ``q``:: @@ -305,7 +305,7 @@ def q_binomial(n, k, q=None, algorithm='auto'): :: - sage: q_binomial(2, 1, x^2 - 1, algorithm="quantum") + sage: q_binomial(2, 1, x^2 - 1, algorithm='quantum') Traceback (most recent call last): ... ValueError: unknown algorithm 'quantum' @@ -470,9 +470,9 @@ def q_catalan_number(n, q=None, m=1): INPUT: - - ``q`` -- optional variable + - ``q`` -- (optional) variable - - ``m`` -- (optional integer) to get instead the ``m``-Fuss-Catalan numbers + - ``m`` -- (optional) integer; to get instead the ``m``-Fuss-Catalan numbers If `q` is unspecified, then it defaults to using the generator `q` for a univariate polynomial ring over the integers. @@ -646,8 +646,7 @@ def q_jordan(t, q=None): INPUT: - - ``t`` -- an integer partition, or an argument accepted by - :class:`Partition` + - ``t`` -- integer partition, or an argument accepted by :class:`Partition` - ``q`` -- (default: ``None``) the variable `q`; if ``None``, then use a default variable in `\ZZ[q]` @@ -871,9 +870,9 @@ def q_stirling_number1(n, k, q=None): INPUT: - - ``n``, ``k`` -- integers with ``1 <= k <= n`` + - ``n``, ``k`` -- integers with `1 \leq k \leq n` - - ``q`` -- optional variable (default `q`) + - ``q`` -- variable (default: `q`) OUTPUT: a polynomial in the variable `q` @@ -937,9 +936,9 @@ def q_stirling_number2(n, k, q=None): INPUT: - - ``n``, ``k`` -- integers with ``1 <= k <= n`` + - ``n``, ``k`` -- integers with `1 \leq k \leq n` - - ``q`` -- optional variable (default `q`) + - ``q`` -- variable (default: `q`) OUTPUT: a polynomial in the variable `q` @@ -1002,7 +1001,7 @@ def number_of_irreducible_polynomials(n, q=None, m=1): - ``n`` -- positive integer - ``q`` -- ``None`` (default) or a prime power - - ``m`` -- positive integer (default `1`) + - ``m`` -- positive integer (default: `1`) OUTPUT: integer or integer-valued polynomial over `\QQ` diff --git a/src/sage/combinat/q_bernoulli.pyx b/src/sage/combinat/q_bernoulli.pyx index 854a80190f3..aa1d1ef42a1 100644 --- a/src/sage/combinat/q_bernoulli.pyx +++ b/src/sage/combinat/q_bernoulli.pyx @@ -17,9 +17,9 @@ def q_bernoulli(m, p=None): INPUT: - - `m` -- a nonnegative integer + - ``m`` -- nonnegative integer - - `p` (default: ``None``) -- an optional value for `q` + - ``p`` -- (default: ``None``) an optional value for `q` OUTPUT: @@ -87,11 +87,9 @@ def q_bernoulli_polynomial(m): INPUT: - - `m` -- a nonnegative integer + - ``m`` -- nonnegative integer - OUTPUT: - - A polynomial in one variable `x`. + OUTPUT: a polynomial in one variable `x` EXAMPLES:: diff --git a/src/sage/combinat/ranker.py b/src/sage/combinat/ranker.py index be78d89de53..873424268d3 100644 --- a/src/sage/combinat/ranker.py +++ b/src/sage/combinat/ranker.py @@ -22,15 +22,13 @@ def from_list(l): """ - Returns a ranker from the list l. + Return a ranker from the list l. INPUT: - - ``l`` -- a list + - ``l`` -- list - OUTPUT: - - - ``[rank, unrank]`` -- functions + OUTPUT: ``[rank, unrank]`` -- functions EXAMPLES:: @@ -71,7 +69,7 @@ def rank_from_list(l): sage: r('c') 2 - For non elements a :class:`ValueError` is raised, as with the usual + For non elements a :exc:`ValueError` is raised, as with the usual ``index`` method of lists:: sage: r('blah') @@ -109,7 +107,7 @@ def rank_from_list(l): def unrank_from_list(l): """ - Returns an unrank function from a list. + Return an unrank function from a list. EXAMPLES:: @@ -127,7 +125,7 @@ def unrank_from_list(l): def on_fly(): """ - Returns a pair of enumeration functions rank / unrank. + Return a pair of enumeration functions rank / unrank. rank assigns on the fly an integer, starting from 0, to any object passed as argument. The object should be hashable. unrank is the @@ -182,8 +180,8 @@ def unrank(L, i): INPUT: - - ``L`` -- a list, tuple, finite enumerated set, ... - - ``i`` -- an int or :class:`Integer` + - ``L`` -- list, tuple, finite enumerated set, etc. + - ``i`` -- integer The purpose of this utility is to give a uniform idiom to recover the `i`-th element of an object ``L``, whether ``L`` is a list, diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 8194e695d13..d9e799607c9 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -100,7 +100,7 @@ def __init__(self, words): @classmethod def create_by_alphabet(cls, alphabet): r""" - A prefix-closed set + A prefix-closed set. This is a convenience method for the creation of prefix-closed sets by specifying an alphabet. @@ -121,11 +121,9 @@ def create_by_alphabet(cls, alphabet): def __repr__(self): r""" - A representation string of this prefix-closed set - - OUTPUT: + A representation string of this prefix-closed set. - A string + OUTPUT: string EXAMPLES:: @@ -144,9 +142,9 @@ def add(self, w, check=True): - ``w`` -- a word - - ``check`` -- boolean (default: ``True``). If set, then it is verified + - ``check`` -- boolean (default: ``True``); if set, then it is verified whether all proper prefixes of ``w`` are already in this - prefix-closed set. + prefix-closed set OUTPUT: @@ -179,9 +177,7 @@ def iterate_possible_additions(self): r""" Return an iterator over all elements including possible new elements. - OUTPUT: - - An iterator + OUTPUT: an iterator EXAMPLES:: @@ -261,9 +257,7 @@ def prefix_set(self): See also Proposition 2.3.1 of [BR2010a]_. - OUTPUT: - - A list + OUTPUT: list EXAMPLES:: @@ -294,9 +288,7 @@ def minimize_result(operation): - ``operation`` -- a method - OUTPUT: - - A method with the following additional argument: + OUTPUT: a method with the following additional argument: - ``minimize`` -- (default: ``None``) a boolean or ``None``. If ``True``, then :meth:`minimized` is called after the operation, @@ -566,12 +558,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. - - OUTPUT: + - ``latex`` -- boolean (default: ``False``); if set, then LaTeX-output + is returned - A string + OUTPUT: string EXAMPLES:: @@ -638,9 +628,7 @@ def _latex_(self): r""" A LaTeX-representation string for this recognizable series. - OUTPUT: - - A string + OUTPUT: string TESTS:: @@ -663,11 +651,11 @@ def coefficient_of_word(self, w, multiply_left=True, multiply_right=True): - ``w`` -- a word over the parent's :meth:`~RecognizableSeriesSpace.alphabet` - - ``multiply_left`` -- (default: ``True``) a boolean. If ``False``, - then multiplication by :meth:`left ` is skipped. + - ``multiply_left`` -- boolean (default: ``True``); if ``False``, + then multiplication by :meth:`left ` is skipped - - ``multiply_right`` -- (default: ``True``) a boolean. If ``False``, - then multiplication by :meth:`right ` is skipped. + - ``multiply_right`` -- boolean (default: ``True``); if ``False``, + then multiplication by :meth:`right ` is skipped OUTPUT: @@ -710,9 +698,7 @@ def _mu_of_empty_word_(self): r""" Return :meth:`mu ` applied on the empty word. - OUTPUT: - - A matrix + OUTPUT: a matrix TESTS:: @@ -748,9 +734,7 @@ def _mu_of_word_(self, w): - ``w`` -- a word over the parent's :meth:`~RecognizableSeriesSpace.alphabet` - OUTPUT: - - A matrix + OUTPUT: a matrix TESTS:: @@ -941,9 +925,7 @@ def __eq__(self, other): - ``other`` -- an object - OUTPUT: - - A boolean + OUTPUT: boolean .. NOTE:: @@ -995,9 +977,7 @@ def __ne__(self, other): - ``other`` -- an object - OUTPUT: - - A boolean + OUTPUT: boolean .. NOTE:: @@ -1022,9 +1002,7 @@ def transposed(self): r""" Return the transposed series. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` Each of the matrices in :meth:`mu ` is transposed. Additionally the vectors :meth:`left ` and :meth:`right ` are switched. @@ -1077,9 +1055,7 @@ def minimized(self): If this is not the case, then the coefficients are automatically coerced to their fraction field. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` ALGORITHM: @@ -1139,9 +1115,7 @@ def _minimized_right_(self): Return a recognizable series equivalent to this series, but with a right minimized linear representation. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` See :meth:`minimized` for details. @@ -1161,9 +1135,7 @@ def _minimized_left_(self): Return a recognizable series equivalent to this series, but with a left minimized linear representation. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` See :meth:`minimized` for details. @@ -1276,9 +1248,7 @@ def _add_(self, other): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RecognizableSeries`. + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: @@ -1315,9 +1285,7 @@ def _neg_(self): r""" Return the additive inverse of this recognizable series. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: @@ -1342,9 +1310,7 @@ def _rmul_(self, other): - ``other`` -- an element of the coefficient (semi-)ring - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: @@ -1406,9 +1372,7 @@ def _lmul_(self, other): - ``other`` -- an element of the coefficient (semi-)ring - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: @@ -1476,9 +1440,7 @@ def hadamard_product(self, other): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: @@ -1593,7 +1555,7 @@ class RecognizableSeriesSpace(UniqueRepresentation, Parent): - ``coefficient_ring`` -- a (semi-)ring - - ``alphabet`` -- a tuple, list or + - ``alphabet`` -- tuple, list or :class:`~sage.sets.totally_ordered_finite_set.TotallyOrderedFiniteSet`. If specified, then the ``indices`` are the finite words over this ``alphabet``. @@ -1670,7 +1632,7 @@ def __normalize__(cls, category=None, minimize_results=True): r""" - Normalizes the input in order to ensure a unique + Normalize the input in order to ensure a unique representation. For more information see :class:`RecognizableSeriesSpace`. @@ -1739,7 +1701,7 @@ def __init__(self, coefficient_ring, indices, category, minimize_results): - ``category`` -- (default: ``None``) the category of this space - - ``minimize_results`` -- (default: ``True``) a boolean. If set, then + - ``minimize_results`` -- boolean (default: ``True``); if set, then :meth:`RecognizableSeries.minimized` is automatically called after performing operations. @@ -1802,9 +1764,7 @@ def alphabet(self): r""" Return the alphabet of this recognizable series space. - OUTPUT: - - A totally ordered set + OUTPUT: a totally ordered set EXAMPLES:: @@ -1822,9 +1782,7 @@ def indices(self): r""" Return the indices of the recognizable series. - OUTPUT: - - The set of finite words over the alphabet + OUTPUT: the set of finite words over the alphabet EXAMPLES:: @@ -1871,9 +1829,7 @@ def _repr_(self): Return a representation string of this recognizable sequence space. - OUTPUT: - - A string + OUTPUT: string TESTS:: @@ -1888,9 +1844,7 @@ def _an_element_(self): r""" Return an element of this recognizable series space. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: @@ -1917,9 +1871,7 @@ def some_elements(self, **kwds): - ``kwds`` are passed on to the element constructor - OUTPUT: - - An iterator + OUTPUT: an iterator EXAMPLES:: @@ -2015,9 +1967,7 @@ def one_hadamard(self): :meth:`~RecognizableSeries.hadamard_product`, i.e. the coefficient-wise multiplication. - OUTPUT: - - A :class:`RecognizableSeries` + OUTPUT: a :class:`RecognizableSeries` EXAMPLES:: diff --git a/src/sage/combinat/regular_sequence.py b/src/sage/combinat/regular_sequence.py index 6822fc7dd3d..b57e5ccbf5b 100644 --- a/src/sage/combinat/regular_sequence.py +++ b/src/sage/combinat/regular_sequence.py @@ -98,15 +98,13 @@ def pad_right(T, length, zero=0): INPUT: - - ``T`` -- A tuple, list or other iterable + - ``T`` -- tuple, list or other iterable - - ``length`` -- a nonnegative integer + - ``length`` -- nonnegative integer - ``zero`` -- (default: ``0``) the elements to pad with - OUTPUT: - - An object of the same type as ``T`` + OUTPUT: an object of the same type as ``T`` EXAMPLES:: @@ -136,7 +134,7 @@ def value(D, k): INPUT: - - ``D`` -- a tuple or other iterable + - ``D`` -- tuple or other iterable - ``k`` -- the base @@ -201,11 +199,11 @@ def __init__(self, parent, mu, left=None, right=None): When created via the parent :class:`RegularSequenceRing`, then the following option is available. - - ``allow_degenerated_sequence`` -- (default: ``False``) a boolean. If set, then - there will be no check if the input is a degenerated sequence - (see :meth:`is_degenerated`). - Otherwise the input is checked and a :class:`DegeneratedSequenceError` - is raised if such a sequence is detected. + - ``allow_degenerated_sequence`` -- boolean (default: ``False``); if + set, then there will be no check if the input is a degenerated + sequence (see :meth:`is_degenerated`). Otherwise the input is checked + and a :exc:`DegeneratedSequenceError` is raised if such a sequence + is detected. EXAMPLES:: @@ -243,7 +241,7 @@ def _repr_(self): r""" Return a representation string of this `k`-regular sequence. - OUTPUT: a string + OUTPUT: string TESTS:: @@ -267,7 +265,7 @@ def coefficient_of_n(self, n, **kwds): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: an element of the universe of the sequence @@ -408,9 +406,7 @@ def regenerated(self): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` ALGORITHM: @@ -494,15 +490,13 @@ def transposed(self, allow_degenerated_sequence=False): INPUT: - - ``allow_degenerated_sequence`` -- (default: ``False``) a boolean. If set, then - there will be no check if the transposed sequence is a degenerated sequence - (see :meth:`is_degenerated`). - Otherwise the transposed sequence is checked and a :class:`DegeneratedSequenceError` + - ``allow_degenerated_sequence`` -- boolean (default: ``False``); if + set, then there will be no check if the transposed sequence is a + degenerated sequence (see :meth:`is_degenerated`). Otherwise the + transposed sequence is checked and a :exc:`DegeneratedSequenceError` is raised if such a sequence is detected. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` Each of the matrices in :meth:`mu ` is transposed. Additionally the vectors :meth:`left ` and :meth:`right ` are switched. @@ -551,9 +545,7 @@ def _minimized_right_(self): Return a regular sequence equivalent to this series, but with a right minimized linear representation. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` .. SEEALSO:: @@ -576,9 +568,9 @@ def subsequence(self, a, b): INPUT: - - ``a`` -- a nonnegative integer + - ``a`` -- nonnegative integer - - ``b`` -- an integer + - ``b`` -- integer Alternatively, this is allowed to be a dictionary `b_j \mapsto c_j`. If so and applied on `f(n)`, @@ -589,9 +581,7 @@ def subsequence(self, a, b): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` .. NOTE:: @@ -863,16 +853,14 @@ def shift_left(self, b=1, **kwds): INPUT: - - ``b`` -- an integer + - ``b`` -- integer - ``minimize`` -- (default: ``None``) a boolean or ``None``. If ``True``, then :meth:`~RecognizableSeries.minimized` is called after the operation, if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` .. NOTE:: @@ -909,16 +897,14 @@ def shift_right(self, b=1, **kwds): INPUT: - - ``b`` -- an integer + - ``b`` -- integer - ``minimize`` -- (default: ``None``) a boolean or ``None``. If ``True``, then :meth:`~RecognizableSeries.minimized` is called after the operation, if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` .. NOTE:: @@ -964,9 +950,7 @@ def backward_differences(self, **kwds): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` .. NOTE:: @@ -1005,9 +989,7 @@ def forward_differences(self, **kwds): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` EXAMPLES:: @@ -1047,9 +1029,7 @@ def _mul_(self, other): if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` ALGORITHM: @@ -1148,18 +1128,16 @@ def partial_sums(self, include_n=False): INPUT: - - ``include_n`` -- (default: ``False``) a boolean. If set, then + - ``include_n`` -- boolean (default: ``False``); if set, then the `n`-th entry of the result is the sum of the entries up - to index `n` (included). + to index `n` (included) - ``minimize`` -- (default: ``None``) a boolean or ``None``. If ``True``, then :meth:`~RecognizableSeries.minimized` is called after the operation, if ``False``, then not. If this argument is ``None``, then the default specified by the parent's ``minimize_results`` is used. - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` EXAMPLES:: @@ -1323,7 +1301,7 @@ class RegularSequenceRing(RecognizableSeriesSpace): INPUT: - - ``k`` -- an integer at least `2` specifying the base + - ``k`` -- integer at least `2` specifying the base - ``coefficient_ring`` -- a (semi-)ring @@ -1350,7 +1328,7 @@ def __normalize__(cls, k, category=None, **kwds): r""" - Normalizes the input in order to ensure a unique + Normalize the input in order to ensure a unique representation. For more information see :class:`RegularSequenceRing`. @@ -1378,7 +1356,7 @@ def __init__(self, k, *args, **kwds): INPUT: - - ``k`` -- an integer at least `2` specifying the base + - ``k`` -- integer at least `2` specifying the base Other input arguments are passed on to :meth:`~sage.combinat.recognizable_series.RecognizableSeriesSpace.__init__`. @@ -1422,7 +1400,7 @@ def _repr_(self): r""" Return a representation string of this `k`-regular sequence space. - OUTPUT: a string + OUTPUT: string TESTS:: @@ -1438,7 +1416,7 @@ def _n_to_index_(self, n): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: a word @@ -1499,9 +1477,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - OUTPUT: - - An iterator + OUTPUT: an iterator EXAMPLES:: @@ -1572,9 +1548,7 @@ def guess(self, f, n_verify=100, max_exponent=10, sequence=None): for bootstrapping the guessing by adding information of the linear representation of ``sequence`` to the guessed representation - OUTPUT: - - A :class:`RegularSequence` + OUTPUT: a :class:`RegularSequence` ALGORITHM: @@ -1592,7 +1566,7 @@ def guess(self, f, n_verify=100, max_exponent=10, sequence=None): Implicitly, the algorithm also maintains a `d \times n_\mathrm{verify}` matrix ``A`` (where ``d`` is the dimension of the right vector valued sequence) whose columns are the current right vector valued sequence evaluated at - the non-negative integers less than `n_\mathrm{verify}` and ensures that this + the nonnegative integers less than `n_\mathrm{verify}` and ensures that this matrix has full row rank. EXAMPLES: @@ -1901,7 +1875,7 @@ def some_inverse_U_matrix(lines): # see :issue:`35748` for details. for m_indices in cantor_product(xsrange(n_verify), repeat=d, min_slope=1): # Iterate over all increasing lists of length d consisting - # of non-negative integers less than `n_verify`. + # of nonnegative integers less than `n_verify`. U = Matrix(domain, d, d, [values(m, lines) for m in m_indices]).transpose() try: @@ -2031,7 +2005,7 @@ def from_recurrence(self, *args, **kwds): If the recurrence relations are represented by symbolic equations, then the following arguments are required: - - ``equations`` -- A list of equations where the elements have + - ``equations`` -- list of equations where the elements have either the form - `f(k^M n + r) = c_{r,l} f(k^m n + l) + c_{r,l + 1} f(k^m n @@ -2070,18 +2044,18 @@ def from_recurrence(self, *args, **kwds): see [HKL2022]_, Definition 3.1, as well as in the description of ``equations`` above - - ``coeffs`` -- a dictionary where ``coeffs[(r, j)]`` is the + - ``coeffs`` -- dictionary where ``coeffs[(r, j)]`` is the coefficient `c_{r,j}` as given in the description of ``equations`` above. If ``coeffs[(r, j)]`` is not given for some ``r`` and ``j``, then it is assumed to be zero. - - ``initial_values`` -- a dictionary mapping integers ``n`` to the + - ``initial_values`` -- dictionary mapping integers ``n`` to the ``n``-th value of the sequence Optional keyword-only argument: - - ``offset`` -- (default: ``0``) an integer. See explanation of - ``equations`` above. + - ``offset`` -- integer (default: `0`); see explanation of + ``equations`` above - ``inhomogeneities`` -- (default: ``{}``) a dictionary mapping integers ``r`` to the inhomogeneity `g_r` as given @@ -2261,7 +2235,7 @@ def from_recurrence(self, *args, **kwds): sage: (S - T).is_trivial_zero() # long time True - Zero-sequence with non-zero initial values:: + Zero-sequence with nonzero initial values:: sage: Seq2.from_recurrence([ ....: f(2*n) == 0, f(2*n + 1) == 0, @@ -2299,7 +2273,7 @@ def from_recurrence(self, *args, **kwds): True Connection between the Stern--Brocot sequence and the number - of non-zero elements in the generalized Pascal's triangle (see + of nonzero elements in the generalized Pascal's triangle (see [LRS2017]_):: sage: U = Seq2.from_recurrence(M=1, m=0, @@ -2361,9 +2335,9 @@ def __init__(self, k, coefficient_ring): INPUT: - - ``k`` -- an integer at least `2` specifying the base + - ``k`` -- integer at least `2` specifying the base - - ``coefficient_ring`` -- a ring. + - ``coefficient_ring`` -- a ring These are the same parameters used when creating a :class:`RegularSequenceRing`. @@ -3023,14 +2997,14 @@ def parse_direct_arguments(self, M, m, coeffs, initial_values): sage: RP.parse_direct_arguments(1, 1/2, {}, {}) Traceback (most recent call last): ... - ValueError: 1/2 is not a non-negative integer. + ValueError: 1/2 is not a nonnegative integer. :: sage: RP.parse_direct_arguments(1, -1, {}, {}) Traceback (most recent call last): ... - ValueError: -1 is not a non-negative integer. + ValueError: -1 is not a nonnegative integer. :: @@ -3093,7 +3067,7 @@ def parse_direct_arguments(self, M, m, coeffs, initial_values): raise ValueError("%s is not a positive integer." % (M,)) from None if m not in ZZ or m < 0: - raise ValueError("%s is not a non-negative integer." + raise ValueError("%s is not a nonnegative integer." % (m,)) from None if M <= m: raise ValueError("%s is not larger than %s." @@ -3158,16 +3132,16 @@ def parameters(self, M, m, coeffs, initial_values, offset=0, inhomogeneities={}) - ``ll``, ``uu``, ``n1``, ``dim`` -- parameters and dimension of the resulting linear representation, see [HKL2022]_, Theorem A - - ``coeffs`` -- a dictionary mapping ``(r, j)`` to the coefficients + - ``coeffs`` -- dictionary mapping ``(r, j)`` to the coefficients `c_{r, j}` as given in [HKL2022]_, Equation (3.1). If ``coeffs[(r, j)]`` is not given for some ``r`` and ``j``, then it is assumed to be zero. - - ``initial_values`` -- a dictionary mapping integers ``n`` to the + - ``initial_values`` -- dictionary mapping integers ``n`` to the ``n``-th value of the sequence - - ``inhomogeneities`` -- a dictionary mapping integers ``r`` - to the inhomogeneity `g_r` as given in [HKL2022]_, Corollary D. + - ``inhomogeneities`` -- dictionary mapping integers ``r`` + to the inhomogeneity `g_r` as given in [HKL2022]_, Corollary D EXAMPLES:: @@ -3350,19 +3324,19 @@ def values(self, *, M, m, l, u, ll, coeffs, - ``ll`` -- parameter of the resulting linear representation, see [HKL2022]_, Theorem A - - ``coeffs`` -- a dictionary where ``coeffs[(r, j)]`` is the + - ``coeffs`` -- dictionary where ``coeffs[(r, j)]`` is the coefficient `c_{r,j}` as given in :meth:`RegularSequenceRing.from_recurrence`. If ``coeffs[(r, j)]`` is not given for some ``r`` and ``j``, then it is assumed to be zero. - - ``initial_values`` -- a dictionary mapping integers ``n`` to the + - ``initial_values`` -- dictionary mapping integers ``n`` to the ``n``-th value of the sequence - ``last_value_needed`` -- last initial value which is needed to determine the linear representation - - ``inhomogeneities`` -- a dictionary mapping integers ``r`` - to the inhomogeneity `g_r` as given in [HKL2022]_, Corollary D. + - ``inhomogeneities`` -- dictionary mapping integers ``r`` + to the inhomogeneity `g_r` as given in [HKL2022]_, Corollary D OUTPUT: @@ -3552,10 +3526,10 @@ def ind(self, M, m, ll, uu): vice versa, i.e., - ``ind[i]`` -- a pair ``(j, d)`` representing the sequence `x(k^j n + d)` - in the `i`-th component (0-based) of the resulting linear representation, + in the `i`-th component (0-based) of the resulting linear representation - ``ind[(j, d)]`` -- the (0-based) row number of the sequence - `x(k^j n + d)` in the linear representation. + `x(k^j n + d)` in the linear representation EXAMPLES:: @@ -3718,7 +3692,7 @@ def v_eval_n(self, recurrence_rules, n): - ``recurrence_rules`` -- a namedtuple generated by :meth:`parameters` - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: a vector @@ -3776,9 +3750,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): - ``recurrence_rules`` -- a namedtuple generated by :meth:`parameters` - - ``rem`` -- an integer between ``0`` and ``k - 1`` + - ``rem`` -- integer between `0` and `k - 1` - - ``correct_offset`` -- (default: ``True``) a boolean. If + - ``correct_offset`` -- boolean (default: ``True``); if ``True``, then the resulting linear representation has no offset. See [HKL2022]_ for more information. diff --git a/src/sage/combinat/ribbon_shaped_tableau.py b/src/sage/combinat/ribbon_shaped_tableau.py index aa896679492..dd7218c899c 100644 --- a/src/sage/combinat/ribbon_shaped_tableau.py +++ b/src/sage/combinat/ribbon_shaped_tableau.py @@ -350,18 +350,17 @@ def from_permutation(self, p): [[1, 2], [3]], [[1], [2], [3]]] """ - if p == []: + if not p: return self.element_class(self, []) comp = p.descents() - if comp == []: + if not comp: return self.element_class(self, [p[:]]) - r = [] - r.append([p[j] for j in range(comp[0])]) - for i in range(len(comp) - 1): - r.append([p[j] for j in range(comp[i], comp[i + 1])]) + r = [[p[j] for j in range(comp[0])]] + r.extend([p[j] for j in range(comp[i], comp[i + 1])] + for i in range(len(comp) - 1)) r.append([p[j] for j in range(comp[-1], len(p))]) r.reverse() return self.element_class(self, r) @@ -459,7 +458,6 @@ def __iter__(self): [[None, 2, 3], [1, 4]], [[None, 2, 4], [1, 3]], [[None, 1, 4], [2, 3]]] - """ for p in descents_composition_list(self.shape): yield self.from_permutation(p) diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index db82cbfd660..6a1643a46c7 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -58,7 +58,7 @@ class RibbonTableau(SkewTableau): 1 0 1 In the previous example, each ribbon is uniquely determined by a - non-zero entry. The 0 entries are used to fill in the rest of the + nonzero entry. The 0 entries are used to fill in the rest of the skew shape. .. NOTE:: @@ -164,14 +164,14 @@ class RibbonTableaux(UniqueRepresentation, Parent): INPUT(Optional): - - ``shape`` -- skew shape as a list of lists or an object of type + - ``shape`` -- skew shape as a list of lists or an object of type SkewPartition - - ``length`` -- integer, ``shape`` is partitioned into ribbons of + - ``length`` -- integer; ``shape`` is partitioned into ribbons of length ``length`` - - ``weight`` -- list of integers, computed from the values of - non-zero entries labeling the ribbons + - ``weight`` -- list of integers; computed from the values of + nonzero entries labeling the ribbons EXAMPLES:: @@ -413,13 +413,13 @@ def insertion_tableau(skp, perm, evaluation, tableau, length): """ INPUT: - - ``skp`` -- skew partitions + - ``skp`` -- skew partitions - - ``perm, evaluation`` -- non-negative integers + - ``perm, evaluation`` -- nonnegative integers - - ``tableau`` -- skew tableau + - ``tableau`` -- skew tableau - - ``length`` -- integer + - ``length`` -- integer TESTS:: @@ -480,11 +480,11 @@ def count_rec(nexts, current, part, weight, length): """ INPUT: - - ``nexts, current, part`` -- skew partitions + - ``nexts, current, part`` -- skew partitions - - ``weight`` -- non-negative integer list + - ``weight`` -- nonnegative integer list - - ``length`` -- integer + - ``length`` -- integer TESTS:: @@ -516,11 +516,11 @@ def list_rec(nexts, current, part, weight, length): """ INPUT: - - ``nexts, current, part`` -- skew partitions + - ``nexts, current, part`` -- skew partitions - - ``weight`` -- non-negative integer list + - ``weight`` -- nonnegative integer list - - ``length`` -- integer + - ``length`` -- integer TESTS:: @@ -575,11 +575,11 @@ def spin_rec(t, nexts, current, part, weight, length): INPUT: - - ``weight`` -- list of non-negative integers + - ``weight`` -- list of nonnegative integers - - ``length`` -- the length of the ribbons we're tiling with + - ``length`` -- the length of the ribbons we're tiling with - - ``t`` -- the variable + - ``t`` -- the variable EXAMPLES:: @@ -620,7 +620,7 @@ def spin_rec(t, nexts, current, part, weight, length): def spin_polynomial_square(part, weight, length): r""" - Returns the spin polynomial associated with ``part``, ``weight``, and + Return the spin polynomial associated with ``part``, ``weight``, and ``length``, with the substitution `t \to t^2` made. EXAMPLES:: @@ -658,7 +658,7 @@ def spin_polynomial_square(part, weight, length): def spin_polynomial(part, weight, length): """ - Returns the spin polynomial associated to ``part``, ``weight``, and + Return the spin polynomial associated to ``part``, ``weight``, and ``length``. EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index 520ce241d57..e22c657d672 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -52,7 +52,7 @@ def __init__(self, tp_krt): INPUT: - - ``parent`` -- The parent of tensor product of KR tableaux + - ``parent`` -- the parent of tensor product of KR tableaux EXAMPLES:: @@ -99,9 +99,9 @@ def run(self, verbose=False): INPUT: - - ``tp_krt`` -- A tensor product of KR tableaux + - ``tp_krt`` -- a tensor product of KR tableaux - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection EXAMPLES:: @@ -177,7 +177,7 @@ def next_state(self, val): INPUT: - - ``val`` -- The value we are adding + - ``val`` -- the value we are adding TESTS:: @@ -210,7 +210,7 @@ def _update_vacancy_nums(self, a): INPUT: - - ``a`` -- The index of the partition to update + - ``a`` -- the index of the partition to update TESTS:: @@ -250,7 +250,7 @@ def _update_partition_values(self, a): INPUT: - - ``a`` -- The index of the partition to update + - ``a`` -- the index of the partition to update TESTS:: @@ -308,7 +308,7 @@ def __init__(self, RC_element): INPUT: - - ``RC_element`` -- The rigged configuration + - ``RC_element`` -- the rigged configuration EXAMPLES:: @@ -361,9 +361,9 @@ def run(self, verbose=False, build_graph=False): INPUT: - - ``verbose`` -- (default: ``False``) display each step in the + - ``verbose`` -- boolean (default: ``False``); display each step in the bijection - - ``build_graph`` -- (default: ``False``) build the graph of each + - ``build_graph`` -- boolean (default: ``False``); build the graph of each step of the bijection EXAMPLES:: @@ -440,9 +440,9 @@ def run(self, verbose=False, build_graph=False): self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex - self._graph = DiGraph(self._graph, format="list_of_edges") + self._graph = DiGraph(self._graph, format='list_of_edges') if have_dot2tex(): - self._graph.set_latex_options(format="dot2tex", edge_labels=True) + self._graph.set_latex_options(format='dot2tex', edge_labels=True) return self.KRT(pathlist=ret_crystal_path) @abstract_method @@ -471,7 +471,7 @@ def _update_vacancy_numbers(self, a): INPUT: - - ``a`` -- The index of the partition to update + - ``a`` -- the index of the partition to update TESTS:: @@ -513,9 +513,9 @@ def _find_singular_string(self, partition, last_size): INPUT: - - ``partition`` -- The partition to look in + - ``partition`` -- the partition to look in - - ``last_size`` -- The last size found + - ``last_size`` -- the last size found TESTS:: diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index 51fd8f198bc..d511ae76a2e 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -54,9 +54,9 @@ def run(self, verbose=False): INPUT: - - ``tp_krt`` -- A tensor product of KR tableaux + - ``tp_krt`` -- a tensor product of KR tableaux - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection EXAMPLES:: @@ -553,9 +553,9 @@ def run(self, verbose=False, build_graph=False): INPUT: - - ``verbose`` -- (default: ``False``) display each step in the + - ``verbose`` -- boolean (default: ``False``); display each step in the bijection - - ``build_graph`` -- (default: ``False``) build the graph of each + - ``build_graph`` -- boolean (default: ``False``); build the graph of each step of the bijection EXAMPLES:: @@ -739,7 +739,7 @@ def run(self, verbose=False, build_graph=False): from sage.graphs.dot2tex_utils import have_dot2tex self._graph = DiGraph(self._graph) if have_dot2tex(): - self._graph.set_latex_options(format="dot2tex", edge_labels=True) + self._graph.set_latex_options(format='dot2tex', edge_labels=True) return self.KRT(pathlist=ret_crystal_path) diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index ab9b41b89bd..a6a5c8316a7 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -56,9 +56,9 @@ def run(self, verbose=False): INPUT: - - ``tp_krt`` -- A tensor product of KR tableaux + - ``tp_krt`` -- a tensor product of KR tableaux - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection EXAMPLES:: @@ -238,8 +238,7 @@ def next_state(self, val): if tableau_height <= n - 2: max_width2 = self.ret_rig_con[n - 2].insert_cell(max_width) max_width = self.ret_rig_con[n - 1].insert_cell(max_width) - if max_width2 < max_width: - max_width = max_width2 + max_width = min(max_width2, max_width) elif pos_val <= self.cur_dims[0][0]: # Special case when the height will become n max_width = self.ret_rig_con[self.cur_dims[0][0] - 1].insert_cell(max_width) @@ -425,9 +424,9 @@ def run(self, verbose=False, build_graph=False): INPUT: - - ``verbose`` -- (default: ``False``) display each step in the + - ``verbose`` -- boolean (default: ``False``); display each step in the bijection - - ``build_graph`` -- (default: ``False``) build the graph of each + - ``build_graph`` -- boolean (default: ``False``); build the graph of each step of the bijection EXAMPLES:: @@ -546,9 +545,9 @@ def run(self, verbose=False, build_graph=False): self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex - self._graph = DiGraph(self._graph, format="list_of_edges") + self._graph = DiGraph(self._graph, format='list_of_edges') if have_dot2tex(): - self._graph.set_latex_options(format="dot2tex", edge_labels=True) + self._graph.set_latex_options(format='dot2tex', edge_labels=True) return self.KRT(pathlist=ret_crystal_path) @@ -603,8 +602,7 @@ def next_state(self, height): temp_size = self.cur_partitions[n - 2][ell[n - 2]] if ell[n - 1] is not None: last_size = self.cur_partitions[n - 1][ell[n - 1]] - if temp_size > last_size: - last_size = temp_size + last_size = max(temp_size, last_size) else: b = n else: diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index ce177ffb468..7d1edfb278a 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -59,9 +59,9 @@ def run(self, verbose=False): INPUT: - - ``tp_krt`` -- A tensor product of KR tableaux + - ``tp_krt`` -- a tensor product of KR tableaux - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection EXAMPLES:: @@ -322,9 +322,9 @@ def run(self, verbose=False, build_graph=False): INPUT: - - ``verbose`` -- (default: ``False``) display each step in the + - ``verbose`` -- boolean (default: ``False``); display each step in the bijection - - ``build_graph`` -- (default: ``False``) build the graph of each + - ``build_graph`` -- boolean (default: ``False``); build the graph of each step of the bijection EXAMPLES:: @@ -424,7 +424,7 @@ def run(self, verbose=False, build_graph=False): from sage.graphs.dot2tex_utils import have_dot2tex self._graph = DiGraph(self._graph) if have_dot2tex(): - self._graph.set_latex_options(format="dot2tex", edge_labels=True) + self._graph.set_latex_options(format='dot2tex', edge_labels=True) return self.KRT(pathlist=ret_crystal_path) diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index c3a2bbeaf0a..e82b6c28035 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -4,7 +4,7 @@ A Kleber tree is a tree of weights generated by Kleber's algorithm [Kleber1]_. The nodes correspond to the weights in the positive Weyl chamber -obtained by subtracting a (non-zero) positive root. The edges are labeled by +obtained by subtracting a (nonzero) positive root. The edges are labeled by the coefficients of the roots of the difference. AUTHORS: @@ -216,10 +216,10 @@ class KleberTreeNode(Element): INPUT: - - ``parent_obj`` -- The parent object of this element - - ``node_weight`` -- The weight of this node - - ``dominant_root`` -- The dominating root - - ``parent_node`` -- (default:None) The parent node of this node + - ``parent_obj`` -- the parent object of this element + - ``node_weight`` -- the weight of this node + - ``dominant_root`` -- the dominating root + - ``parent_node`` -- (default: ``None``) the parent node of this node """ def __init__(self, parent_obj, node_weight, dominant_root, parent_node=None): @@ -515,7 +515,7 @@ class KleberTree(UniqueRepresentation, Parent): :class:`VirtualKleberTree`. The nodes correspond to the weights in the positive Weyl chamber obtained - by subtracting a (non-zero) positive root. The edges are labeled by the + by subtracting a (nonzero) positive root. The edges are labeled by the coefficients of the roots, and `X` is a child of `Y` if `Y` is the root else if the edge label of `Y` to its parent `Z` is greater (in every component) than the label from `X` to `Y`. @@ -529,7 +529,7 @@ class KleberTree(UniqueRepresentation, Parent): - ``cartan_type`` -- an affine simply-laced Cartan type - - ``B`` -- a list of dimensions of rectangles by `[r, c]` + - ``B`` -- list of dimensions of rectangles by `[r, c]` where `r` is the number of rows and `c` is the number of columns REFERENCES: @@ -623,7 +623,7 @@ def __init__(self, cartan_type, B, classical_ct): sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 3, 1], [[1,1], [1,1]]); KT Kleber tree of Cartan type ['D', 3, 1] and B = ((1, 1), (1, 1)) - sage: TestSuite(KT).run(skip="_test_elements") + sage: TestSuite(KT).run(skip='_test_elements') """ Parent.__init__(self, category=FiniteEnumeratedSets()) @@ -650,8 +650,8 @@ def latex_options(self, **options): - ``vspace`` -- (default: ``x``) the vertical spacing of the tree nodes, here ``x`` is the minimum of `-2.5` or `-.75n` where `n` is the rank of the classical type - - ``edge_labels`` -- (default: ``True``) display edge labels - - ``use_vector_notation`` -- (default: ``False``) display edge labels + - ``edge_labels`` -- boolean (default: ``True``); display edge labels + - ``use_vector_notation`` -- boolean (default: ``False``); display edge labels using vector notation instead of a linear combination EXAMPLES:: @@ -1033,12 +1033,12 @@ def digraph(self): G = DiGraph(d) if have_dot2tex(): - G.set_latex_options(format="dot2tex", edge_labels=True) + G.set_latex_options(format='dot2tex', edge_labels=True) return G def plot(self, **options): """ - Return the plot of self as a directed graph. + Return the plot of ``self`` as a directed graph. EXAMPLES:: @@ -1115,7 +1115,7 @@ class VirtualKleberTree(KleberTree): - ``cartan_type`` -- an affine non-simply-laced Cartan type - - ``B`` -- a list of dimensions of rectangles by `[r, c]` + - ``B`` -- list of dimensions of rectangles by `[r, c]` where `r` is the number of rows and `c` is the number of columns EXAMPLES:: @@ -1168,7 +1168,7 @@ def __init__(self, cartan_type, B): sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C',4,1], [[2,2]]) - sage: TestSuite(KT).run(skip="_test_elements") + sage: TestSuite(KT).run(skip='_test_elements') """ self._folded_ct = cartan_type.as_folding() virtual_dims = [] @@ -1240,7 +1240,7 @@ def breadth_first_iter(self, all_nodes=False): INPUT: - - ``all_nodes`` -- (default: ``False``) if ``True``, output all + - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all nodes in the tree EXAMPLES:: @@ -1276,7 +1276,7 @@ def depth_first_iter(self, all_nodes=False): INPUT: - - ``all_nodes`` -- (default: ``False``) if ``True``, output all + - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all nodes in the tree EXAMPLES:: @@ -1363,7 +1363,7 @@ def __init__(self, cartan_type, B): sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]); KT Virtual Kleber tree of Cartan type ['BC', 3, 2] and B = ((2, 2),) - sage: TestSuite(KT).run(skip="_test_elements") + sage: TestSuite(KT).run(skip='_test_elements') """ self._folded_ct = cartan_type.as_folding() virtual_dims = [] @@ -1432,7 +1432,7 @@ def breadth_first_iter(self, all_nodes=False): INPUT: - - ``all_nodes`` -- (default: ``False``) if ``True``, output all + - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all nodes in the tree EXAMPLES:: @@ -1457,7 +1457,7 @@ def depth_first_iter(self, all_nodes=False): INPUT: - - ``all_nodes`` -- (default: ``False``) if ``True``, output all + - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all nodes in the tree EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/kr_tableaux.py b/src/sage/combinat/rigged_configurations/kr_tableaux.py index 8bdc1d275b9..fb6f223e62c 100644 --- a/src/sage/combinat/rigged_configurations/kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/kr_tableaux.py @@ -653,12 +653,10 @@ def _fill(self, weight): INPUT: - - ``weight`` -- The weight of the highest weight KR tableau (the + - ``weight`` -- the weight of the highest weight KR tableau (the conjugate of the shape of the KR crystal's tableau) - OUTPUT: - - - A `r \times s` tableau + OUTPUT: a `r \times s` tableau EXAMPLES:: @@ -781,11 +779,9 @@ def _fill(self, shape): INPUT: - - ``shape`` -- The shape of the KR crystal's tableau - - OUTPUT: + - ``shape`` -- the shape of the KR crystal's tableau - - A `r \times s` tableau + OUTPUT: a `r \times s` tableau EXAMPLES:: @@ -879,12 +875,10 @@ def _fill(self, weight): INPUT: - - ``weight`` -- The weight of the highest weight KR tableau (the + - ``weight`` -- the weight of the highest weight KR tableau (the conjugate of the shape of the KR crystal's tableau) - OUTPUT: - - - A `r \times s` tableau + OUTPUT: a `r \times s` tableau EXAMPLES:: @@ -1219,8 +1213,8 @@ def to_array(self, rows=True): INPUT: - - ``rows`` -- (Default: ``True``) Set to ``True`` if the resulting - array is by row, otherwise it is by column. + - ``rows`` -- boolean (default: ``True``); set to ``True`` if the + resulting array is by row, otherwise it is by column EXAMPLES:: @@ -1287,9 +1281,9 @@ def to_classical_highest_weight(self, index_set=None): INPUT: - - ``index_set`` -- (Default: ``None``) Return the highest weight - with respect to the index set. If ``None`` is passed in, then this - uses the classical index set. + - ``index_set`` -- (default: ``None``) return the highest weight + with respect to the index set; if ``None`` is passed in, then this + uses the classical index set OUTPUT: @@ -1589,8 +1583,8 @@ def to_array(self, rows=True): INPUT: - - ``rows`` -- (Default: ``True``) Set to ``True`` if the resulting - array is by row, otherwise it is by column. + - ``rows`` -- boolean (default: ``True``); set to ``True`` if the + resulting array is by row, otherwise it is by column EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/meson.build b/src/sage/combinat/rigged_configurations/meson.build new file mode 100644 index 00000000000..6b12159dfda --- /dev/null +++ b/src/sage/combinat/rigged_configurations/meson.build @@ -0,0 +1,40 @@ +py.install_sources( + 'all.py', + 'bij_abstract_class.py', + 'bij_infinity.py', + 'bij_type_A.py', + 'bij_type_A2_dual.py', + 'bij_type_A2_even.py', + 'bij_type_A2_odd.py', + 'bij_type_B.py', + 'bij_type_C.py', + 'bij_type_D.py', + 'bij_type_D_tri.py', + 'bij_type_D_twisted.py', + 'bij_type_E67.py', + 'bijection.py', + 'kleber_tree.py', + 'kr_tableaux.py', + 'rc_crystal.py', + 'rc_infinity.py', + 'rigged_configuration_element.py', + 'rigged_configurations.py', + 'rigged_partition.pxd', + 'tensor_product_kr_tableaux.py', + 'tensor_product_kr_tableaux_element.py', + subdir: 'sage/combinat/rigged_configurations', +) + +extension_data = {'rigged_partition' : files('rigged_partition.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/rigged_configurations', + install: true, + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 8e1e76ed41d..4fe967a5c6c 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -55,7 +55,7 @@ class RiggedConfigurationElement(ClonableArray): - ``parent`` -- the parent of this element - - ``rigged_partitions`` -- a list of rigged partitions + - ``rigged_partitions`` -- list of rigged partitions There are two optional arguments to explicitly construct a rigged configuration. The first is ``partition_list`` which gives a list of @@ -462,9 +462,7 @@ def nu(self): Return the list `\nu` of rigged partitions of this rigged configuration element. - OUTPUT: - - The `\nu` array as a list. + OUTPUT: the `\nu` array as a list EXAMPLES:: @@ -503,9 +501,7 @@ def e(self, a): - ``a`` -- the index of the partition to remove a box - OUTPUT: - - The resulting rigged configuration element. + OUTPUT: the resulting rigged configuration element EXAMPLES:: @@ -625,9 +621,7 @@ def _generate_partition_e(self, a, b, k): - ``k`` -- the length of the string with the smallest negative rigging of smallest length - OUTPUT: - - The constructed rigged partition. + OUTPUT: the constructed rigged partition TESTS:: @@ -677,9 +671,7 @@ def f(self, a): - ``a`` -- the index of the partition to add a box - OUTPUT: - - The resulting rigged configuration element. + OUTPUT: the resulting rigged configuration element EXAMPLES:: @@ -784,9 +776,7 @@ def _generate_partition_f(self, a, b, k): - ``k`` -- the length of the string with smallest nonpositive rigging of largest length - OUTPUT: - - The constructed rigged partition. + OUTPUT: the constructed rigged partition TESTS:: @@ -1097,9 +1087,7 @@ def f(self, a): - ``a`` -- the index of the partition to add a box - OUTPUT: - - The resulting rigged configuration element. + OUTPUT: the resulting rigged configuration element EXAMPLES:: @@ -1354,9 +1342,7 @@ def e(self, a): - ``a`` -- the index of the partition to remove a box - OUTPUT: - - The resulting rigged configuration element. + OUTPUT: the resulting rigged configuration element EXAMPLES:: @@ -1408,9 +1394,7 @@ def f(self, a): - ``a`` -- the index of the partition to add a box - OUTPUT: - - The resulting rigged configuration element. + OUTPUT: the resulting rigged configuration element EXAMPLES:: @@ -1573,10 +1557,10 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False INPUT: - - ``display_steps`` -- (default: ``False``) boolean which indicates - if we want to print each step in the algorithm - - ``build_graph`` -- (default: ``False``) boolean which indicates - if we want to construct and return a graph of the bijection whose + - ``display_steps`` -- boolean (default: ``False``); indicates whether + to print each step in the algorithm + - ``build_graph`` -- boolean (default: ``False``); indicates whether + to construct and return a graph of the bijection whose vertices are rigged configurations obtained at each step and edges are labeled by either the return value of `\delta` or the doubling/halving map @@ -1659,10 +1643,10 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False INPUT: - - ``display_steps`` -- (default: ``False``) boolean which indicates - if we want to print each step in the algorithm - - ``build_graph`` -- (default: ``False``) boolean which indicates - if we want to construct and return a graph of the bijection whose + - ``display_steps`` -- boolean (default: ``False``); indicates whether + to print each step in the algorithm + - ``build_graph`` -- boolean (default: ``False``); indicates whether + to construct and return a graph of the bijection whose vertices are rigged configurations obtained at each step and edges are labeled by either the return value of `\delta` or the doubling/halving map @@ -1802,7 +1786,7 @@ def left_box(self, return_b=False): INPUT: - - ``return_b`` -- (default: ``False``) whether to return the + - ``return_b`` -- boolean (default: ``False``); whether to return the resulting letter from `\delta` OUTPUT: @@ -1990,7 +1974,7 @@ def complement_rigging(self, reverse_factors=False): INPUT: - - ``reverse_factors`` -- (default: ``False``) if ``True``, then this + - ``reverse_factors`` -- boolean (default: ``False``); if ``True``, then this returns an element in `RC(B')` where `B'` is the tensor factors of ``self`` in reverse order diff --git a/src/sage/combinat/rigged_configurations/rigged_configurations.py b/src/sage/combinat/rigged_configurations/rigged_configurations.py index 535787875b5..0d3d9954cc1 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configurations.py +++ b/src/sage/combinat/rigged_configurations/rigged_configurations.py @@ -123,7 +123,7 @@ class RiggedConfigurations(UniqueRepresentation, Parent): :class:`~sage.combinat.rigged_configurations.tensor_product_kr_tableaux.TensorProductOfKirillovReshetikhinTableaux` of non-exceptional affine types where the list `B` corresponds to the tensor factors `B^{r,s}`. The bijection has been proven in types `A_n^{(1)}` - and `D_n^{(1)}` and when the only non-zero entries of `L_i^{(a)}` are either + and `D_n^{(1)}` and when the only nonzero entries of `L_i^{(a)}` are either only `L_1^{(a)}` or only `L_i^{(1)}` (corresponding to single columns or rows respectively) [RigConBijection]_, [BijectionLRT]_, [BijectionDn]_. @@ -146,7 +146,7 @@ class RiggedConfigurations(UniqueRepresentation, Parent): - ``cartan_type`` -- a Cartan type - - ``B`` -- a list of positive integer tuples `(r,s)` corresponding to the + - ``B`` -- list of positive integer tuples `(r,s)` corresponding to the tensor factors in the bijection with tensor product of Kirillov-Reshetikhin tableaux or equivalently the sequence of width `s` and height `r` rectangles @@ -391,7 +391,7 @@ def __init__(self, cartan_type, B): # add options to class class options(GlobalOptions): r""" - Sets and displays the options for rigged configurations. + Set and display the options for rigged configurations. If no parameters are set, then the function returns a copy of the options dictionary. @@ -414,7 +414,7 @@ class options(GlobalOptions): -1[ ]-1 - sage: RiggedConfigurations.options(display="horizontal", convention="french") + sage: RiggedConfigurations.options(display='horizontal', convention='french') sage: elt -1[ ]-1 1[ ][ ][ ]1 -1[ ]-1 -3[ ][ ][ ]-3 @@ -437,7 +437,7 @@ class options(GlobalOptions): """ NAME = 'RiggedConfigurations' module = 'sage.combinat.rigged_configurations.rigged_configurations' - display = dict(default="vertical", + display = dict(default='vertical', description='Specifies how rigged configurations should be printed', values=dict(vertical='displayed vertically', horizontal='displayed horizontally'), @@ -612,7 +612,7 @@ def _block_iterator(self, container): INPUT: - - ``container`` -- a list of widths of the rows of the container + - ``container`` -- list of widths of the rows of the container TESTS:: @@ -1806,7 +1806,7 @@ def _block_iterator_n_odd(self, container): INPUT: - - ``container`` -- a list the widths of the rows of the container + - ``container`` -- list the widths of the rows of the container TESTS:: diff --git a/src/sage/combinat/rigged_configurations/rigged_partition.pyx b/src/sage/combinat/rigged_configurations/rigged_partition.pyx index 97ff48d7918..84d98c90f3e 100644 --- a/src/sage/combinat/rigged_configurations/rigged_partition.pyx +++ b/src/sage/combinat/rigged_configurations/rigged_partition.pyx @@ -360,13 +360,11 @@ cdef class RiggedPartition(SageObject): INPUT: - - ``end_column`` -- The index of the column to end at + - ``end_column`` -- the index of the column to end at - - ``t`` -- The scaling factor + - ``t`` -- the scaling factor - OUTPUT: - - - The number of cells + OUTPUT: the number of cells EXAMPLES:: @@ -405,12 +403,10 @@ cdef class RiggedPartition(SageObject): INPUT: - - ``max_width`` -- The maximum width (i.e. row length) that we can + - ``max_width`` -- the maximum width (i.e. row length) that we can insert the cell at - OUTPUT: - - - The width of the row we inserted at. + OUTPUT: the width of the row we inserted at EXAMPLES:: @@ -562,7 +558,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): INPUT: - - ``half_width_boxes`` -- (Default: ``True``) Display the partition + - ``half_width_boxes`` -- (default: ``True``) display the partition using half width boxes EXAMPLES:: @@ -611,7 +607,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): INPUT: - - ``half_width_boxes`` -- (default: ``True``) display the partition + - ``half_width_boxes`` -- boolean (default: ``True``); display the partition using half width boxes EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py index 8db94443af2..436bbe79b61 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py @@ -118,9 +118,9 @@ def __init__(self, parent, list=[[]], **options): INPUT: - - ``parent`` -- Parent for this element + - ``parent`` -- parent for this element - - ``list`` -- The list of KR tableaux elements + - ``list`` -- the list of KR tableaux elements EXAMPLES:: @@ -324,12 +324,10 @@ def to_rigged_configuration(self, display_steps=False): INPUT: - - ``display_steps`` -- (default: ``False``) Boolean which indicates - if we want to output each step in the algorithm. + - ``display_steps`` -- boolean (default: ``False``); whether to output + each step in the algorithm - OUTPUT: - - The rigged configuration corresponding to ``self``. + OUTPUT: the rigged configuration corresponding to ``self`` EXAMPLES: diff --git a/src/sage/combinat/root_system/ambient_space.py b/src/sage/combinat/root_system/ambient_space.py index e52a8504edd..0d00c45273f 100644 --- a/src/sage/combinat/root_system/ambient_space.py +++ b/src/sage/combinat/root_system/ambient_space.py @@ -18,7 +18,7 @@ class AmbientSpace(CombinatorialFreeModule): r""" - Abstract class for ambient spaces + Abstract class for ambient spaces. All subclasses should implement a class method ``smallest_base_ring`` taking a Cartan type as input, and a method @@ -140,7 +140,6 @@ def dimension(self): Traceback (most recent call last): ... NotImplementedError - """ raise NotImplementedError @@ -169,7 +168,6 @@ def _repr_(self): Ambient lattice of the Root system of type ['A', 4] sage: RootSystem(['B',4]).ambient_space() Ambient space of the Root system of type ['B', 4] - """ return self._name_string() @@ -179,7 +177,6 @@ def _name_string(self, capitalize=True, base_ring=False, type=True): sage: RootSystem(['A',4]).ambient_lattice()._name_string() "Ambient lattice of the Root system of type ['A', 4]" - """ return self._name_string_helper("ambient", capitalize=capitalize, base_ring=base_ring, type=type) @@ -230,7 +227,7 @@ def coroot_lattice(self): def simple_coroot(self, i): r""" - Returns the i-th simple coroot, as an element of this space + Return the `i`-th simple coroot, as an element of this space. EXAMPLES:: @@ -257,7 +254,6 @@ def reflection(self, root, coroot=None): sage: s_a = e.reflection(a) sage: s_a(b) (0, -1, 0, 0) - """ # TODO: get rid of this as one can use the generic implementation # (i.e. scalar and associated coroot are implemented) @@ -266,7 +262,7 @@ def reflection(self, root, coroot=None): @cached_method def fundamental_weight(self, i): r""" - Returns the fundamental weight `\Lambda_i` in ``self`` + Return the fundamental weight `\Lambda_i` in ``self``. In several of the ambient spaces, it is more convenient to construct all fundamental weights at once. To support this, we @@ -291,13 +287,13 @@ def fundamental_weight(self, i): """ return self.fundamental_weights()[i] - def from_vector_notation(self, weight, style="lattice"): + def from_vector_notation(self, weight, style='lattice'): """ INPUT: - ``weight`` -- a vector or tuple representing a weight - Returns an element of self. If the weight lattice is not + Returns an element of ``self``. If the weight lattice is not of full rank, it coerces it into the weight lattice, or its ambient space by orthogonal projection. This arises in two cases: for SL(r+1), the weight lattice is @@ -307,7 +303,7 @@ def from_vector_notation(self, weight, style="lattice"): If style="coroots" and the data is a tuple of integers, it is assumed that the data represent a linear combination of - fundamental weights. If style="coroots", and the root lattice + fundamental weights. If style='coroots', and the root lattice is not of full rank in the ambient space, it is projected into the subspace corresponding to the semisimple derived group. This arises with Cartan type A, E6 and E7. @@ -318,7 +314,7 @@ def from_vector_notation(self, weight, style="lattice"): (1, 0, 0) sage: RootSystem("A2").ambient_space().from_vector_notation([1,0,0]) (1, 0, 0) - sage: RootSystem("A2").ambient_space().from_vector_notation((1,0),style="coroots") + sage: RootSystem("A2").ambient_space().from_vector_notation((1,0),style='coroots') (2/3, -1/3, -1/3) """ if style == "coroots" and isinstance(weight, tuple) and all(xv in ZZ for xv in weight): @@ -373,8 +369,7 @@ def _repr_(self): def inner_product(self, lambdacheck): """ - The scalar product with elements of the coroot lattice - embedded in the ambient space. + The scalar product with elements of the ambient space. EXAMPLES:: @@ -383,15 +378,32 @@ def inner_product(self, lambdacheck): (-1, 0, 0) sage: a.inner_product(a) 2 + + TESTS: + + Verify that :issue:`15325` (A) is fixed:: + + sage: rt = RootSystem(['E', 8]) + sage: lat = rt.root_lattice() + sage: spc = rt.ambient_space() + sage: spc.simple_root(1).scalar(lat.simple_coroot(2)) + 0 """ + if self.parent() is not lambdacheck.parent(): + try: + # see if lambdacheck can be converted to the ambient space + lambdacheck = self.parent()(lambdacheck) + except (TypeError, ValueError): + raise TypeError(f"unable to coerce {lambdacheck} into {self.parent()}") + + # self and lambdacheck both belong to the same ambient space, so use the inner product there self_mc = self._monomial_coefficients lambdacheck_mc = lambdacheck._monomial_coefficients result = self.parent().base_ring().zero() for t,c in lambdacheck_mc.items(): - if t not in self_mc: - continue - result += c*self_mc[t] + if t in self_mc: + result += c*self_mc[t] return result scalar = inner_product @@ -406,7 +418,6 @@ def associated_coroot(self): (1/2, -1/2, -1/2, -1/2) sage: a.associated_coroot() (1, -1, -1, -1) - """ # FIXME: make it work over ZZ! return self * self.base_ring()(2/self.inner_product(self)) @@ -508,7 +519,6 @@ def to_ambient(self): (2, 2, 3) sage: v.to_ambient() (2, 2, 3) - """ return self diff --git a/src/sage/combinat/root_system/associahedron.py b/src/sage/combinat/root_system/associahedron.py index 448b1009036..7b2752daa6d 100644 --- a/src/sage/combinat/root_system/associahedron.py +++ b/src/sage/combinat/root_system/associahedron.py @@ -337,7 +337,7 @@ class Associahedra_base: Importantly, the parent knows the dimension of the ambient space. If you try to construct an associahedron of a different - dimension, a :class:`ValueError` is raised:: + dimension, a :exc:`ValueError` is raised:: sage: parent(['A',3]) Traceback (most recent call last): @@ -387,15 +387,13 @@ def _element_constructor_(self, cartan_type, **kwds): def _coerce_map_from_(self, X): r""" - Return whether there is a coercion from ``X`` + Return whether there is a coercion from ``X``. INPUT: - - ``X`` -- anything. + - ``X`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/combinat/root_system/braid_move_calculator.py b/src/sage/combinat/root_system/braid_move_calculator.py index 38931a00229..8fcdc26f24b 100644 --- a/src/sage/combinat/root_system/braid_move_calculator.py +++ b/src/sage/combinat/root_system/braid_move_calculator.py @@ -33,7 +33,7 @@ def __init__(self, coxeter_group): sage: from sage.combinat.root_system.braid_move_calculator import BraidMoveCalculator sage: W = CoxeterGroup(['C',3]) sage: B = BraidMoveCalculator(W) - sage: TestSuite(B).run(skip="_test_pickling") + sage: TestSuite(B).run(skip='_test_pickling') """ self.coxeter_matrix = coxeter_group.coxeter_matrix() diff --git a/src/sage/combinat/root_system/branching_rules.py b/src/sage/combinat/root_system/branching_rules.py index 4877b972438..91876ee8dd3 100644 --- a/src/sage/combinat/root_system/branching_rules.py +++ b/src/sage/combinat/root_system/branching_rules.py @@ -20,7 +20,7 @@ from sage.misc.functional import is_even, is_odd -def branch_weyl_character(chi, R, S, rule="default"): +def branch_weyl_character(chi, R, S, rule='default'): r""" A branching rule describes the restriction of representations from a Lie group or algebra `G` to a subgroup `H`. See for example, R. C. @@ -46,14 +46,14 @@ def branch_weyl_character(chi, R, S, rule="default"): - ``rule`` -- an element of the ``BranchingRule`` class or one (most usually) a keyword such as: - * ``"levi"`` - * ``"automorphic"`` - * ``"symmetric"`` - * ``"extended"`` - * ``"orthogonal_sum"`` - * ``"tensor"`` - * ``"triality"`` - * ``"miscellaneous"`` + * ``'levi'`` + * ``'automorphic'`` + * ``'symmetric'`` + * ``'extended'`` + * ``'orthogonal_sum'`` + * ``'tensor'`` + * ``'triality'`` + * ``'miscellaneous'`` The :class:`BranchingRule` class is a wrapper for functions from the weight lattice of `G` to the weight lattice of `H`. @@ -79,9 +79,9 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A3=WeylCharacterRing("A3",style="coroots") - sage: A2=WeylCharacterRing("A2",style="coroots") - sage: [A3(fw).branch(A2,rule="levi") for fw in A3.fundamental_weights()] + sage: A3=WeylCharacterRing("A3",style='coroots') + sage: A2=WeylCharacterRing("A2",style='coroots') + sage: [A3(fw).branch(A2,rule='levi') for fw in A3.fundamental_weights()] [A2(0,0) + A2(1,0), A2(0,1) + A2(1,0), A2(0,0) + A2(0,1)] In this case the Levi branching rule is the default branching rule @@ -94,8 +94,8 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A4=WeylCharacterRing("A4",style="coroots") - sage: A2=WeylCharacterRing("A2",style="coroots") + sage: A4=WeylCharacterRing("A4",style='coroots') + sage: A2=WeylCharacterRing("A2",style='coroots') sage: br=branching_rule("A4","A3")*branching_rule("A3","A2") sage: A4(1,0,0,0).branch(A2,rule=br) 2*A2(0,0) + A2(1,0) @@ -129,13 +129,13 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A1 = WeylCharacterRing("A1", style="coroots") - sage: A2 = WeylCharacterRing("A2", style="coroots") - sage: D4 = WeylCharacterRing("D4", style="coroots") - sage: B3 = WeylCharacterRing("B3", style="coroots") - sage: B4 = WeylCharacterRing("B4", style="coroots") - sage: A6 = WeylCharacterRing("A6", style="coroots") - sage: A7 = WeylCharacterRing("A7", style="coroots") + sage: A1 = WeylCharacterRing("A1", style='coroots') + sage: A2 = WeylCharacterRing("A2", style='coroots') + sage: D4 = WeylCharacterRing("D4", style='coroots') + sage: B3 = WeylCharacterRing("B3", style='coroots') + sage: B4 = WeylCharacterRing("B4", style='coroots') + sage: A6 = WeylCharacterRing("A6", style='coroots') + sage: A7 = WeylCharacterRing("A7", style='coroots') sage: def try_default_rule(R,S): return [R(f).branch(S) for f in R.fundamental_weights()] sage: try_default_rule(A2,A1) [A1(0) + A1(1), A1(0) + A1(1)] @@ -214,12 +214,12 @@ def branch_weyl_character(chi, R, S, rule="default"): sage: D3 = WeylCharacterRing("D3") sage: D4 = WeylCharacterRing("D4") sage: G2 = WeylCharacterRing("G2") - sage: F4 = WeylCharacterRing("F4",style="coroots") - sage: E6=WeylCharacterRing("E6",style="coroots") - sage: E7=WeylCharacterRing("E7",style="coroots") - sage: D5=WeylCharacterRing("D5",style="coroots") - sage: D6=WeylCharacterRing("D6",style="coroots") - sage: [B3(w).branch(A2,rule="levi") for w in B3.fundamental_weights()] + sage: F4 = WeylCharacterRing("F4",style='coroots') + sage: E6=WeylCharacterRing("E6",style='coroots') + sage: E7=WeylCharacterRing("E7",style='coroots') + sage: D5=WeylCharacterRing("D5",style='coroots') + sage: D6=WeylCharacterRing("D6",style='coroots') + sage: [B3(w).branch(A2,rule='levi') for w in B3.fundamental_weights()] [A2(0,0,0) + A2(1,0,0) + A2(0,0,-1), A2(0,0,0) + A2(1,0,0) + A2(1,1,0) + A2(1,0,-1) + A2(0,-1,-1) + A2(0,0,-1), A2(-1/2,-1/2,-1/2) + A2(1/2,-1/2,-1/2) + A2(1/2,1/2,-1/2) + A2(1/2,1/2,1/2)] @@ -235,73 +235,73 @@ def branch_weyl_character(chi, R, S, rule="default"): :: - sage: [C3(w).branch(A2,rule="levi") for w in C3.fundamental_weights()] + sage: [C3(w).branch(A2,rule='levi') for w in C3.fundamental_weights()] [A2(1,0,0) + A2(0,0,-1), A2(1,1,0) + A2(1,0,-1) + A2(0,-1,-1), A2(-1,-1,-1) + A2(1,-1,-1) + A2(1,1,-1) + A2(1,1,1)] - sage: [D4(w).branch(A3,rule="levi") for w in D4.fundamental_weights()] + sage: [D4(w).branch(A3,rule='levi') for w in D4.fundamental_weights()] [A3(1,0,0,0) + A3(0,0,0,-1), A3(0,0,0,0) + A3(1,1,0,0) + A3(1,0,0,-1) + A3(0,0,-1,-1), A3(1/2,-1/2,-1/2,-1/2) + A3(1/2,1/2,1/2,-1/2), A3(-1/2,-1/2,-1/2,-1/2) + A3(1/2,1/2,-1/2,-1/2) + A3(1/2,1/2,1/2,1/2)] - sage: [B3(w).branch(B2,rule="levi") for w in B3.fundamental_weights()] + sage: [B3(w).branch(B2,rule='levi') for w in B3.fundamental_weights()] [2*B2(0,0) + B2(1,0), B2(0,0) + 2*B2(1,0) + B2(1,1), 2*B2(1/2,1/2)] sage: C3 = WeylCharacterRing(['C',3]) - sage: [C3(w).branch(C2,rule="levi") for w in C3.fundamental_weights()] + sage: [C3(w).branch(C2,rule='levi') for w in C3.fundamental_weights()] [2*C2(0,0) + C2(1,0), C2(0,0) + 2*C2(1,0) + C2(1,1), C2(1,0) + 2*C2(1,1)] - sage: [D5(w).branch(D4,rule="levi") for w in D5.fundamental_weights()] + sage: [D5(w).branch(D4,rule='levi') for w in D5.fundamental_weights()] [2*D4(0,0,0,0) + D4(1,0,0,0), D4(0,0,0,0) + 2*D4(1,0,0,0) + D4(1,1,0,0), D4(1,0,0,0) + 2*D4(1,1,0,0) + D4(1,1,1,0), D4(1/2,1/2,1/2,-1/2) + D4(1/2,1/2,1/2,1/2), D4(1/2,1/2,1/2,-1/2) + D4(1/2,1/2,1/2,1/2)] - sage: G2(1,0,-1).branch(A1,rule="levi") + sage: G2(1,0,-1).branch(A1,rule='levi') A1(1,0) + A1(1,-1) + A1(0,-1) - sage: E6=WeylCharacterRing("E6",style="coroots") - sage: D5=WeylCharacterRing("D5",style="coroots") + sage: E6=WeylCharacterRing("E6",style='coroots') + sage: D5=WeylCharacterRing("D5",style='coroots') sage: fw = E6.fundamental_weights() - sage: [E6(fw[i]).branch(D5,rule="levi") for i in [1,2,6]] + sage: [E6(fw[i]).branch(D5,rule='levi') for i in [1,2,6]] [D5(0,0,0,0,0) + D5(0,0,0,0,1) + D5(1,0,0,0,0), D5(0,0,0,0,0) + D5(0,0,0,1,0) + D5(0,0,0,0,1) + D5(0,1,0,0,0), D5(0,0,0,0,0) + D5(0,0,0,1,0) + D5(1,0,0,0,0)] - sage: E7=WeylCharacterRing("E7",style="coroots") - sage: A3xA3xA1=WeylCharacterRing("A3xA3xA1",style="coroots") - sage: E7(1,0,0,0,0,0,0).branch(A3xA3xA1,rule="extended") # long time (0.7s) + sage: E7=WeylCharacterRing("E7",style='coroots') + sage: A3xA3xA1=WeylCharacterRing("A3xA3xA1",style='coroots') + sage: E7(1,0,0,0,0,0,0).branch(A3xA3xA1,rule='extended') # long time (0.7s) A3xA3xA1(0,0,1,0,0,1,1) + A3xA3xA1(0,1,0,0,1,0,0) + A3xA3xA1(1,0,0,1,0,0,1) + A3xA3xA1(1,0,1,0,0,0,0) + A3xA3xA1(0,0,0,1,0,1,0) + A3xA3xA1(0,0,0,0,0,0,2) sage: fw = E7.fundamental_weights() - sage: [E7(fw[i]).branch(D6,rule="levi") for i in [1,2,7]] # long time (0.3s) + sage: [E7(fw[i]).branch(D6,rule='levi') for i in [1,2,7]] # long time (0.3s) [3*D6(0,0,0,0,0,0) + 2*D6(0,0,0,0,1,0) + D6(0,1,0,0,0,0), 3*D6(0,0,0,0,0,1) + 2*D6(1,0,0,0,0,0) + 2*D6(0,0,1,0,0,0) + D6(1,0,0,0,1,0), D6(0,0,0,0,0,1) + 2*D6(1,0,0,0,0,0)] - sage: D7=WeylCharacterRing("D7",style="coroots") - sage: E8=WeylCharacterRing("E8",style="coroots") - sage: D7=WeylCharacterRing("D7",style="coroots") - sage: E8(1,0,0,0,0,0,0,0).branch(D7,rule="levi") # long time (7s) + sage: D7=WeylCharacterRing("D7",style='coroots') + sage: E8=WeylCharacterRing("E8",style='coroots') + sage: D7=WeylCharacterRing("D7",style='coroots') + sage: E8(1,0,0,0,0,0,0,0).branch(D7,rule='levi') # long time (7s) 3*D7(0,0,0,0,0,0,0) + 2*D7(0,0,0,0,0,1,0) + 2*D7(0,0,0,0,0,0,1) + 2*D7(1,0,0,0,0,0,0) + D7(0,1,0,0,0,0,0) + 2*D7(0,0,1,0,0,0,0) + D7(0,0,0,1,0,0,0) + D7(1,0,0,0,0,1,0) + D7(1,0,0,0,0,0,1) + D7(2,0,0,0,0,0,0) - sage: E8(0,0,0,0,0,0,0,1).branch(D7,rule="levi") # long time (0.6s) + sage: E8(0,0,0,0,0,0,0,1).branch(D7,rule='levi') # long time (0.6s) D7(0,0,0,0,0,0,0) + D7(0,0,0,0,0,1,0) + D7(0,0,0,0,0,0,1) + 2*D7(1,0,0,0,0,0,0) + D7(0,1,0,0,0,0,0) - sage: [F4(fw).branch(B3,rule="levi") for fw in F4.fundamental_weights()] # long time (1s) + sage: [F4(fw).branch(B3,rule='levi') for fw in F4.fundamental_weights()] # long time (1s) [B3(0,0,0) + 2*B3(1/2,1/2,1/2) + 2*B3(1,0,0) + B3(1,1,0), B3(0,0,0) + 6*B3(1/2,1/2,1/2) + 5*B3(1,0,0) + 7*B3(1,1,0) + 3*B3(1,1,1) + 6*B3(3/2,1/2,1/2) + 2*B3(3/2,3/2,1/2) + B3(2,0,0) + 2*B3(2,1,0) + B3(2,1,1), 3*B3(0,0,0) + 6*B3(1/2,1/2,1/2) + 4*B3(1,0,0) + 3*B3(1,1,0) + B3(1,1,1) + 2*B3(3/2,1/2,1/2), 3*B3(0,0,0) + 2*B3(1/2,1/2,1/2) + B3(1,0,0)] - sage: [F4(fw).branch(C3,rule="levi") for fw in F4.fundamental_weights()] # long time (1s) + sage: [F4(fw).branch(C3,rule='levi') for fw in F4.fundamental_weights()] # long time (1s) [3*C3(0,0,0) + 2*C3(1,1,1) + C3(2,0,0), 3*C3(0,0,0) + 6*C3(1,1,1) + 4*C3(2,0,0) + 2*C3(2,1,0) + 3*C3(2,2,0) + C3(2,2,2) + C3(3,1,0) + 2*C3(3,1,1), 2*C3(1,0,0) + 3*C3(1,1,0) + C3(2,0,0) + 2*C3(2,1,0) + C3(2,1,1), 2*C3(1,0,0) + C3(1,1,0)] sage: A1xA1 = WeylCharacterRing("A1xA1") - sage: [A3(hwv).branch(A1xA1,rule="levi") for hwv in A3.fundamental_weights()] + sage: [A3(hwv).branch(A1xA1,rule='levi') for hwv in A3.fundamental_weights()] [A1xA1(1,0,0,0) + A1xA1(0,0,1,0), A1xA1(1,1,0,0) + A1xA1(1,0,1,0) + A1xA1(0,0,1,1), A1xA1(1,1,1,0) + A1xA1(1,0,1,1)] - sage: A1xB1=WeylCharacterRing("A1xB1",style="coroots") - sage: [B3(x).branch(A1xB1,rule="levi") for x in B3.fundamental_weights()] + sage: A1xB1=WeylCharacterRing("A1xB1",style='coroots') + sage: [B3(x).branch(A1xB1,rule='levi') for x in B3.fundamental_weights()] [2*A1xB1(1,0) + A1xB1(0,2), 3*A1xB1(0,0) + 2*A1xB1(1,2) + A1xB1(2,0) + A1xB1(0,2), A1xB1(1,1) + 2*A1xB1(0,1)] @@ -323,14 +323,14 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: [A3(chi).branch(A3,rule="automorphic") for chi in A3.fundamental_weights()] + sage: [A3(chi).branch(A3,rule='automorphic') for chi in A3.fundamental_weights()] [A3(0,0,0,-1), A3(0,0,-1,-1), A3(0,-1,-1,-1)] - sage: [D4(chi).branch(D4,rule="automorphic") for chi in D4.fundamental_weights()] + sage: [D4(chi).branch(D4,rule='automorphic') for chi in D4.fundamental_weights()] [D4(1,0,0,0), D4(1,1,0,0), D4(1/2,1/2,1/2,1/2), D4(1/2,1/2,1/2,-1/2)] Here is an example with `D_4` triality:: - sage: [D4(chi).branch(D4,rule="triality") for chi in D4.fundamental_weights()] + sage: [D4(chi).branch(D4,rule='triality') for chi in D4.fundamental_weights()] [D4(1/2,1/2,1/2,-1/2), D4(1,1,0,0), D4(1/2,1/2,1/2,1/2), D4(1,0,0,0)] .. RUBRIC:: Symmetric Type @@ -371,28 +371,28 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: [w.branch(B2,rule="symmetric") for w in [A4(1,0,0,0,0),A4(1,1,0,0,0),A4(1,1,1,0,0),A4(2,0,0,0,0)]] + sage: [w.branch(B2,rule='symmetric') for w in [A4(1,0,0,0,0),A4(1,1,0,0,0),A4(1,1,1,0,0),A4(2,0,0,0,0)]] [B2(1,0), B2(1,1), B2(1,1), B2(0,0) + B2(2,0)] - sage: [A5(w).branch(C3,rule="symmetric") for w in A5.fundamental_weights()] + sage: [A5(w).branch(C3,rule='symmetric') for w in A5.fundamental_weights()] [C3(1,0,0), C3(0,0,0) + C3(1,1,0), C3(1,0,0) + C3(1,1,1), C3(0,0,0) + C3(1,1,0), C3(1,0,0)] - sage: [A5(w).branch(D3,rule="symmetric") for w in A5.fundamental_weights()] + sage: [A5(w).branch(D3,rule='symmetric') for w in A5.fundamental_weights()] [D3(1,0,0), D3(1,1,0), D3(1,1,-1) + D3(1,1,1), D3(1,1,0), D3(1,0,0)] - sage: [D4(x).branch(B3,rule="symmetric") for x in D4.fundamental_weights()] + sage: [D4(x).branch(B3,rule='symmetric') for x in D4.fundamental_weights()] [B3(0,0,0) + B3(1,0,0), B3(1,0,0) + B3(1,1,0), B3(1/2,1/2,1/2), B3(1/2,1/2,1/2)] - sage: [D4(x).branch(G2,rule="symmetric") for x in D4.fundamental_weights()] + sage: [D4(x).branch(G2,rule='symmetric') for x in D4.fundamental_weights()] [G2(0,0,0) + G2(1,0,-1), 2*G2(1,0,-1) + G2(2,-1,-1), G2(0,0,0) + G2(1,0,-1), G2(0,0,0) + G2(1,0,-1)] - sage: [E6(fw).branch(F4,rule="symmetric") for fw in E6.fundamental_weights()] # long time (4s) + sage: [E6(fw).branch(F4,rule='symmetric') for fw in E6.fundamental_weights()] # long time (4s) [F4(0,0,0,0) + F4(0,0,0,1), F4(0,0,0,1) + F4(1,0,0,0), F4(0,0,0,1) + F4(1,0,0,0) + F4(0,0,1,0), F4(1,0,0,0) + 2*F4(0,0,1,0) + F4(1,0,0,1) + F4(0,1,0,0), F4(0,0,0,1) + F4(1,0,0,0) + F4(0,0,1,0), F4(0,0,0,0) + F4(0,0,0,1)] - sage: E6=WeylCharacterRing("E6",style="coroots") - sage: C4=WeylCharacterRing("C4",style="coroots") + sage: E6=WeylCharacterRing("E6",style='coroots') + sage: C4=WeylCharacterRing("C4",style='coroots') sage: chi = E6(1,0,0,0,0,0); chi.degree() 27 - sage: chi.branch(C4,rule="symmetric") + sage: chi.branch(C4,rule='symmetric') C4(0,1,0,0) .. RUBRIC:: Extended Type @@ -437,60 +437,60 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: [B3(x).branch(D3,rule="extended") for x in B3.fundamental_weights()] + sage: [B3(x).branch(D3,rule='extended') for x in B3.fundamental_weights()] [D3(0,0,0) + D3(1,0,0), D3(1,0,0) + D3(1,1,0), D3(1/2,1/2,-1/2) + D3(1/2,1/2,1/2)] - sage: [G2(w).branch(A2, rule="extended") for w in G2.fundamental_weights()] + sage: [G2(w).branch(A2, rule='extended') for w in G2.fundamental_weights()] [A2(0,0,0) + A2(1/3,1/3,-2/3) + A2(2/3,-1/3,-1/3), A2(1/3,1/3,-2/3) + A2(2/3,-1/3,-1/3) + A2(1,0,-1)] - sage: [F4(fw).branch(B4,rule="extended") for fw in F4.fundamental_weights()] # long time (2s) + sage: [F4(fw).branch(B4,rule='extended') for fw in F4.fundamental_weights()] # long time (2s) [B4(1/2,1/2,1/2,1/2) + B4(1,1,0,0), B4(1,1,0,0) + B4(1,1,1,0) + B4(3/2,1/2,1/2,1/2) + B4(3/2,3/2,1/2,1/2) + B4(2,1,1,0), B4(1/2,1/2,1/2,1/2) + B4(1,0,0,0) + B4(1,1,0,0) + B4(1,1,1,0) + B4(3/2,1/2,1/2,1/2), B4(0,0,0,0) + B4(1/2,1/2,1/2,1/2) + B4(1,0,0,0)] - sage: E6 = WeylCharacterRing("E6", style="coroots") - sage: A2xA2xA2 = WeylCharacterRing("A2xA2xA2",style="coroots") - sage: A5xA1 = WeylCharacterRing("A5xA1",style="coroots") - sage: G2 = WeylCharacterRing("G2", style="coroots") - sage: A1xA1 = WeylCharacterRing("A1xA1", style="coroots") - sage: F4 = WeylCharacterRing("F4",style="coroots") - sage: A3xA1 = WeylCharacterRing("A3xA1", style="coroots") - sage: A2xA2 = WeylCharacterRing("A2xA2", style="coroots") - sage: A1xC3 = WeylCharacterRing("A1xC3",style="coroots") - sage: E6(1,0,0,0,0,0).branch(A5xA1,rule="extended") # (0.7s) + sage: E6 = WeylCharacterRing("E6", style='coroots') + sage: A2xA2xA2 = WeylCharacterRing("A2xA2xA2",style='coroots') + sage: A5xA1 = WeylCharacterRing("A5xA1",style='coroots') + sage: G2 = WeylCharacterRing("G2", style='coroots') + sage: A1xA1 = WeylCharacterRing("A1xA1", style='coroots') + sage: F4 = WeylCharacterRing("F4",style='coroots') + sage: A3xA1 = WeylCharacterRing("A3xA1", style='coroots') + sage: A2xA2 = WeylCharacterRing("A2xA2", style='coroots') + sage: A1xC3 = WeylCharacterRing("A1xC3",style='coroots') + sage: E6(1,0,0,0,0,0).branch(A5xA1,rule='extended') # (0.7s) A5xA1(0,0,0,1,0,0) + A5xA1(1,0,0,0,0,1) - sage: E6(1,0,0,0,0,0).branch(A2xA2xA2, rule="extended") # (0.7s) + sage: E6(1,0,0,0,0,0).branch(A2xA2xA2, rule='extended') # (0.7s) A2xA2xA2(0,1,1,0,0,0) + A2xA2xA2(1,0,0,0,0,1) + A2xA2xA2(0,0,0,1,1,0) - sage: E7 = WeylCharacterRing("E7",style="coroots") - sage: A7 = WeylCharacterRing("A7",style="coroots") - sage: E7(1,0,0,0,0,0,0).branch(A7,rule="extended") + sage: E7 = WeylCharacterRing("E7",style='coroots') + sage: A7 = WeylCharacterRing("A7",style='coroots') + sage: E7(1,0,0,0,0,0,0).branch(A7,rule='extended') A7(0,0,0,1,0,0,0) + A7(1,0,0,0,0,0,1) - sage: D6xA1 = WeylCharacterRing("D6xA1",style="coroots") - sage: E7(1,0,0,0,0,0,0).branch(D6xA1,rule="extended") + sage: D6xA1 = WeylCharacterRing("D6xA1",style='coroots') + sage: E7(1,0,0,0,0,0,0).branch(D6xA1,rule='extended') D6xA1(0,0,0,0,1,0,1) + D6xA1(0,1,0,0,0,0,0) + D6xA1(0,0,0,0,0,0,2) - sage: A5xA2 = WeylCharacterRing("A5xA2",style="coroots") - sage: E7(1,0,0,0,0,0,0).branch(A5xA2,rule="extended") + sage: A5xA2 = WeylCharacterRing("A5xA2",style='coroots') + sage: E7(1,0,0,0,0,0,0).branch(A5xA2,rule='extended') A5xA2(0,0,0,1,0,1,0) + A5xA2(0,1,0,0,0,0,1) + A5xA2(1,0,0,0,1,0,0) + A5xA2(0,0,0,0,0,1,1) - sage: E8 = WeylCharacterRing("E8",style="coroots") - sage: D8 = WeylCharacterRing("D8",style="coroots") - sage: A8 = WeylCharacterRing("A8",style="coroots") - sage: E8(0,0,0,0,0,0,0,1).branch(D8,rule="extended") # long time (0.56s) + sage: E8 = WeylCharacterRing("E8",style='coroots') + sage: D8 = WeylCharacterRing("D8",style='coroots') + sage: A8 = WeylCharacterRing("A8",style='coroots') + sage: E8(0,0,0,0,0,0,0,1).branch(D8,rule='extended') # long time (0.56s) D8(0,0,0,0,0,0,1,0) + D8(0,1,0,0,0,0,0,0) - sage: E8(0,0,0,0,0,0,0,1).branch(A8,rule="extended") # long time (0.73s) + sage: E8(0,0,0,0,0,0,0,1).branch(A8,rule='extended') # long time (0.73s) A8(0,0,0,0,0,1,0,0) + A8(0,0,1,0,0,0,0,0) + A8(1,0,0,0,0,0,0,1) - sage: F4(1,0,0,0).branch(A1xC3,rule="extended") # (0.05s) + sage: F4(1,0,0,0).branch(A1xC3,rule='extended') # (0.05s) A1xC3(1,0,0,1) + A1xC3(2,0,0,0) + A1xC3(0,2,0,0) - sage: G2(0,1).branch(A1xA1, rule="extended") + sage: G2(0,1).branch(A1xA1, rule='extended') A1xA1(2,0) + A1xA1(3,1) + A1xA1(0,2) - sage: F4(0,0,0,1).branch(A2xA2, rule="extended") # (0.4s) + sage: F4(0,0,0,1).branch(A2xA2, rule='extended') # (0.4s) A2xA2(0,1,0,1) + A2xA2(1,0,1,0) + A2xA2(0,0,1,1) - sage: F4(0,0,0,1).branch(A3xA1,rule="extended") # (0.34s) + sage: F4(0,0,0,1).branch(A3xA1,rule='extended') # (0.34s) A3xA1(0,0,0,0) + A3xA1(0,0,1,1) + A3xA1(0,1,0,0) + A3xA1(1,0,0,1) + A3xA1(0,0,0,2) - sage: D4=WeylCharacterRing("D4",style="coroots") - sage: D2xD2=WeylCharacterRing("D2xD2",style="coroots") # We get D4 => A1xA1xA1xA1 by remembering that A1xA1 = D2. - sage: [D4(fw).branch(D2xD2, rule="extended") for fw in D4.fundamental_weights()] + sage: D4=WeylCharacterRing("D4",style='coroots') + sage: D2xD2=WeylCharacterRing("D2xD2",style='coroots') # We get D4 => A1xA1xA1xA1 by remembering that A1xA1 = D2. + sage: [D4(fw).branch(D2xD2, rule='extended') for fw in D4.fundamental_weights()] [D2xD2(1,1,0,0) + D2xD2(0,0,1,1), D2xD2(2,0,0,0) + D2xD2(0,2,0,0) + D2xD2(1,1,1,1) + D2xD2(0,0,2,0) + D2xD2(0,0,0,2), D2xD2(1,0,0,1) + D2xD2(0,1,1,0), @@ -543,31 +543,31 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A5=WeylCharacterRing("A5", style="coroots") - sage: A2xA1=WeylCharacterRing("A2xA1", style="coroots") - sage: [A5(hwv).branch(A2xA1, rule="tensor") for hwv in A5.fundamental_weights()] + sage: A5=WeylCharacterRing("A5", style='coroots') + sage: A2xA1=WeylCharacterRing("A2xA1", style='coroots') + sage: [A5(hwv).branch(A2xA1, rule='tensor') for hwv in A5.fundamental_weights()] [A2xA1(1,0,1), A2xA1(0,1,2) + A2xA1(2,0,0), A2xA1(1,1,1) + A2xA1(0,0,3), A2xA1(1,0,2) + A2xA1(0,2,0), A2xA1(0,1,1)] - sage: B4=WeylCharacterRing("B4",style="coroots") - sage: B1xB1=WeylCharacterRing("B1xB1",style="coroots") - sage: [B4(f).branch(B1xB1,rule="tensor") for f in B4.fundamental_weights()] + sage: B4=WeylCharacterRing("B4",style='coroots') + sage: B1xB1=WeylCharacterRing("B1xB1",style='coroots') + sage: [B4(f).branch(B1xB1,rule='tensor') for f in B4.fundamental_weights()] [B1xB1(2,2), B1xB1(2,0) + B1xB1(2,4) + B1xB1(4,2) + B1xB1(0,2), B1xB1(2,0) + B1xB1(2,2) + B1xB1(2,4) + B1xB1(4,2) + B1xB1(4,4) + B1xB1(6,0) + B1xB1(0,2) + B1xB1(0,6), B1xB1(1,3) + B1xB1(3,1)] - sage: D4=WeylCharacterRing("D4",style="coroots") - sage: C2xC1=WeylCharacterRing("C2xC1",style="coroots") - sage: [D4(f).branch(C2xC1,rule="tensor") for f in D4.fundamental_weights()] + sage: D4=WeylCharacterRing("D4",style='coroots') + sage: C2xC1=WeylCharacterRing("C2xC1",style='coroots') + sage: [D4(f).branch(C2xC1,rule='tensor') for f in D4.fundamental_weights()] [C2xC1(1,0,1), C2xC1(0,1,2) + C2xC1(2,0,0) + C2xC1(0,0,2), C2xC1(1,0,1), C2xC1(0,1,0) + C2xC1(0,0,2)] - sage: C3=WeylCharacterRing("C3",style="coroots") - sage: B1xC1=WeylCharacterRing("B1xC1",style="coroots") - sage: [C3(f).branch(B1xC1,rule="tensor") for f in C3.fundamental_weights()] + sage: C3=WeylCharacterRing("C3",style='coroots') + sage: B1xC1=WeylCharacterRing("B1xC1",style='coroots') + sage: [C3(f).branch(B1xC1,rule='tensor') for f in C3.fundamental_weights()] [B1xC1(2,1), B1xC1(2,2) + B1xC1(4,0), B1xC1(4,1) + B1xC1(0,3)] .. RUBRIC:: Symmetric Power @@ -595,12 +595,12 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A1=WeylCharacterRing("A1",style="coroots") - sage: B3=WeylCharacterRing("B3",style="coroots") - sage: C3=WeylCharacterRing("C3",style="coroots") - sage: [B3(fw).branch(A1,rule="symmetric_power") for fw in B3.fundamental_weights()] + sage: A1=WeylCharacterRing("A1",style='coroots') + sage: B3=WeylCharacterRing("B3",style='coroots') + sage: C3=WeylCharacterRing("C3",style='coroots') + sage: [B3(fw).branch(A1,rule='symmetric_power') for fw in B3.fundamental_weights()] [A1(6), A1(2) + A1(6) + A1(10), A1(0) + A1(6)] - sage: [C3(fw).branch(A1,rule="symmetric_power") for fw in C3.fundamental_weights()] + sage: [C3(fw).branch(A1,rule='symmetric_power') for fw in C3.fundamental_weights()] [A1(5), A1(4) + A1(8), A1(3) + A1(9)] .. RUBRIC:: Miscellaneous @@ -646,58 +646,57 @@ def branch_weyl_character(chi, R, S, rule="default"): https://doc.sagemath.org/html/en/thematic_tutorials/lie.html - EXAMPLES:: sage: G2 = WeylCharacterRing("G2") sage: [fw1, fw2, fw3] = B3.fundamental_weights() - sage: B3(fw1+fw3).branch(G2, rule="miscellaneous") + sage: B3(fw1+fw3).branch(G2, rule='miscellaneous') G2(1,0,-1) + G2(2,-1,-1) + G2(2,0,-2) - sage: E6 = WeylCharacterRing("E6",style="coroots") - sage: G2 = WeylCharacterRing("G2",style="coroots") + sage: E6 = WeylCharacterRing("E6",style='coroots') + sage: G2 = WeylCharacterRing("G2",style='coroots') sage: E6(1,0,0,0,0,0).branch(G2,"miscellaneous") G2(2,0) - sage: A2=WeylCharacterRing("A2",style="coroots") - sage: E6(1,0,0,0,0,0).branch(A2,rule="miscellaneous") + sage: A2=WeylCharacterRing("A2",style='coroots') + sage: E6(1,0,0,0,0,0).branch(A2,rule='miscellaneous') A2(2,2) - sage: E6(0,1,0,0,0,0).branch(A2,rule="miscellaneous") + sage: E6(0,1,0,0,0,0).branch(A2,rule='miscellaneous') A2(1,1) + A2(1,4) + A2(4,1) sage: E6(0,0,0,0,0,2).branch(G2,"miscellaneous") # long time (0.59s) G2(0,0) + G2(2,0) + G2(1,1) + G2(0,2) + G2(4,0) - sage: F4=WeylCharacterRing("F4",style="coroots") - sage: G2xA1=WeylCharacterRing("G2xA1",style="coroots") - sage: F4(0,0,1,0).branch(G2xA1,rule="miscellaneous") + sage: F4=WeylCharacterRing("F4",style='coroots') + sage: G2xA1=WeylCharacterRing("G2xA1",style='coroots') + sage: F4(0,0,1,0).branch(G2xA1,rule='miscellaneous') G2xA1(1,0,0) + G2xA1(1,0,2) + G2xA1(1,0,4) + G2xA1(1,0,6) + G2xA1(0,1,4) + G2xA1(2,0,2) + G2xA1(0,0,2) + G2xA1(0,0,6) - sage: E6 = WeylCharacterRing("E6",style="coroots") - sage: A2xG2 = WeylCharacterRing("A2xG2",style="coroots") - sage: E6(1,0,0,0,0,0).branch(A2xG2,rule="miscellaneous") + sage: E6 = WeylCharacterRing("E6",style='coroots') + sage: A2xG2 = WeylCharacterRing("A2xG2",style='coroots') + sage: E6(1,0,0,0,0,0).branch(A2xG2,rule='miscellaneous') A2xG2(0,1,1,0) + A2xG2(2,0,0,0) - sage: E7=WeylCharacterRing("E7",style="coroots") - sage: G2xC3=WeylCharacterRing("G2xC3",style="coroots") - sage: E7(0,1,0,0,0,0,0).branch(G2xC3,rule="miscellaneous") # long time (1.84s) + sage: E7=WeylCharacterRing("E7",style='coroots') + sage: G2xC3=WeylCharacterRing("G2xC3",style='coroots') + sage: E7(0,1,0,0,0,0,0).branch(G2xC3,rule='miscellaneous') # long time (1.84s) G2xC3(1,0,1,0,0) + G2xC3(1,0,1,1,0) + G2xC3(0,1,0,0,1) + G2xC3(2,0,1,0,0) + G2xC3(0,0,1,1,0) - sage: F4xA1=WeylCharacterRing("F4xA1",style="coroots") + sage: F4xA1=WeylCharacterRing("F4xA1",style='coroots') sage: E7(0,0,0,0,0,0,1).branch(F4xA1,"miscellaneous") F4xA1(0,0,0,1,1) + F4xA1(0,0,0,0,3) - sage: A1xA1=WeylCharacterRing("A1xA1",style="coroots") - sage: E7(0,0,0,0,0,0,1).branch(A1xA1,rule="miscellaneous") + sage: A1xA1=WeylCharacterRing("A1xA1",style='coroots') + sage: E7(0,0,0,0,0,0,1).branch(A1xA1,rule='miscellaneous') A1xA1(2,5) + A1xA1(4,1) + A1xA1(6,3) - sage: A2=WeylCharacterRing("A2",style="coroots") - sage: E7(0,0,0,0,0,0,1).branch(A2,rule="miscellaneous") + sage: A2=WeylCharacterRing("A2",style='coroots') + sage: E7(0,0,0,0,0,0,1).branch(A2,rule='miscellaneous') A2(0,6) + A2(6,0) - sage: G2xA1=WeylCharacterRing("G2xA1",style="coroots") - sage: E7(1,0,0,0,0,0,0).branch(G2xA1,rule="miscellaneous") + sage: G2xA1=WeylCharacterRing("G2xA1",style='coroots') + sage: E7(1,0,0,0,0,0,0).branch(G2xA1,rule='miscellaneous') G2xA1(1,0,4) + G2xA1(0,1,0) + G2xA1(2,0,2) + G2xA1(0,0,2) - sage: E8 = WeylCharacterRing("E8",style="coroots") - sage: G2xF4 = WeylCharacterRing("G2xF4",style="coroots") - sage: E8(0,0,0,0,0,0,0,1).branch(G2xF4,rule="miscellaneous") # long time (0.76s) + sage: E8 = WeylCharacterRing("E8",style='coroots') + sage: G2xF4 = WeylCharacterRing("G2xF4",style='coroots') + sage: E8(0,0,0,0,0,0,0,1).branch(G2xF4,rule='miscellaneous') # long time (0.76s) G2xF4(1,0,0,0,0,1) + G2xF4(0,1,0,0,0,0) + G2xF4(0,0,1,0,0,0) - sage: E8=WeylCharacterRing("E8",style="coroots") - sage: A1xA2=WeylCharacterRing("A1xA2",style="coroots") - sage: E8(0,0,0,0,0,0,0,1).branch(A1xA2,rule="miscellaneous") # long time (0.76s) + sage: E8=WeylCharacterRing("E8",style='coroots') + sage: A1xA2=WeylCharacterRing("A1xA2",style='coroots') + sage: E8(0,0,0,0,0,0,0,1).branch(A1xA2,rule='miscellaneous') # long time (0.76s) A1xA2(2,0,0) + A1xA2(2,2,2) + A1xA2(4,0,3) + A1xA2(4,3,0) + A1xA2(6,1,1) + A1xA2(0,1,1) - sage: B2=WeylCharacterRing("B2",style="coroots") - sage: E8(0,0,0,0,0,0,0,1).branch(B2,rule="miscellaneous") # long time (0.53s) + sage: B2=WeylCharacterRing("B2",style='coroots') + sage: E8(0,0,0,0,0,0,0,1).branch(B2,rule='miscellaneous') # long time (0.53s) B2(0,2) + B2(0,6) + B2(3,2) .. RUBRIC:: A1 maximal subgroups of exceptional groups @@ -713,24 +712,24 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A1=WeylCharacterRing("A1",style="coroots") - sage: G2=WeylCharacterRing("G2",style="coroots") - sage: F4=WeylCharacterRing("F4",style="coroots") - sage: E7=WeylCharacterRing("E7",style="coroots") - sage: E8=WeylCharacterRing("E8",style="coroots") - sage: [G2(f).branch(A1,rule="i") for f in G2.fundamental_weights()] + sage: A1=WeylCharacterRing("A1",style='coroots') + sage: G2=WeylCharacterRing("G2",style='coroots') + sage: F4=WeylCharacterRing("F4",style='coroots') + sage: E7=WeylCharacterRing("E7",style='coroots') + sage: E8=WeylCharacterRing("E8",style='coroots') + sage: [G2(f).branch(A1,rule='i') for f in G2.fundamental_weights()] [A1(6), A1(2) + A1(10)] - sage: F4(1,0,0,0).branch(A1,rule="ii") + sage: F4(1,0,0,0).branch(A1,rule='ii') A1(2) + A1(10) + A1(14) + A1(22) - sage: E7(0,0,0,0,0,0,1).branch(A1,rule="iii") + sage: E7(0,0,0,0,0,0,1).branch(A1,rule='iii') A1(9) + A1(17) + A1(27) - sage: E7(0,0,0,0,0,0,1).branch(A1,rule="iv") + sage: E7(0,0,0,0,0,0,1).branch(A1,rule='iv') A1(5) + A1(11) + A1(15) + A1(21) - sage: E8(0,0,0,0,0,0,0,1).branch(A1,rule="v") # long time (0.6s) + sage: E8(0,0,0,0,0,0,0,1).branch(A1,rule='v') # long time (0.6s) A1(2) + A1(14) + A1(22) + A1(26) + A1(34) + A1(38) + A1(46) + A1(58) - sage: E8(0,0,0,0,0,0,0,1).branch(A1,rule="vi") # long time (0.6s) + sage: E8(0,0,0,0,0,0,0,1).branch(A1,rule='vi') # long time (0.6s) A1(2) + A1(10) + A1(14) + A1(18) + A1(22) + A1(26) + A1(28) + A1(34) + A1(38) + A1(46) - sage: E8(0,0,0,0,0,0,0,1).branch(A1,rule="vii") # long time (0.6s) + sage: E8(0,0,0,0,0,0,0,1).branch(A1,rule='vii') # long time (0.6s) A1(2) + A1(6) + A1(10) + A1(14) + A1(16) + A1(18) + 2*A1(22) + A1(26) + A1(28) + A1(34) + A1(38) .. RUBRIC:: Branching Rules From Plethysms @@ -760,7 +759,7 @@ def branch_weyl_character(chi, R, S, rule="default"): :: - sage: A1=WeylCharacterRing("A1",style="coroots") + sage: A1=WeylCharacterRing("A1",style='coroots') sage: chi=A1([5]) sage: chi.degree() 6 @@ -774,7 +773,7 @@ def branch_weyl_character(chi, R, S, rule="default"): :: - sage: C3 = WeylCharacterRing("C3",style="coroots") + sage: C3 = WeylCharacterRing("C3",style='coroots') sage: sym5rule = branching_rule_from_plethysm(chi,"C3") sage: [C3(hwv).branch(A1,rule=sym5rule) for hwv in C3.fundamental_weights()] [A1(5), A1(4) + A1(8), A1(3) + A1(9)] @@ -785,8 +784,8 @@ def branch_weyl_character(chi, R, S, rule="default"): :: - sage: G2 = WeylCharacterRing("G2",style="coroots") - sage: D7 = WeylCharacterRing("D7",style="coroots") + sage: G2 = WeylCharacterRing("G2",style='coroots') + sage: D7 = WeylCharacterRing("D7",style='coroots') sage: ad=G2(0,1); ad.degree(); ad.frobenius_schur_indicator() 14 1 @@ -829,15 +828,15 @@ def branch_weyl_character(chi, R, S, rule="default"): sage: B2 = WeylCharacterRing("B2") sage: C2 = WeylCharacterRing("C2") - sage: [B2(x).branch(C2, rule="isomorphic") for x in B2.fundamental_weights()] + sage: [B2(x).branch(C2, rule='isomorphic') for x in B2.fundamental_weights()] [C2(1,1), C2(1,0)] - sage: [C2(x).branch(B2, rule="isomorphic") for x in C2.fundamental_weights()] + sage: [C2(x).branch(B2, rule='isomorphic') for x in C2.fundamental_weights()] [B2(1/2,1/2), B2(1,0)] sage: D3 = WeylCharacterRing("D3") sage: A3 = WeylCharacterRing("A3") - sage: [A3(x).branch(D3,rule="isomorphic") for x in A3.fundamental_weights()] + sage: [A3(x).branch(D3,rule='isomorphic') for x in A3.fundamental_weights()] [D3(1/2,1/2,1/2), D3(1,0,0), D3(1/2,1/2,-1/2)] - sage: [D3(x).branch(A3,rule="isomorphic") for x in D3.fundamental_weights()] + sage: [D3(x).branch(A3,rule='isomorphic') for x in D3.fundamental_weights()] [A3(1/2,1/2,-1/2,-1/2), A3(1/4,1/4,1/4,-3/4), A3(3/4,-1/4,-1/4,-1/4)] Here `A_3(x,y,z,w)` can be understood as a representation of `SL(4)`. @@ -853,36 +852,36 @@ def branch_weyl_character(chi, R, S, rule="default"): In cases like this you might prefer ``style="coroots"``:: - sage: A3 = WeylCharacterRing("A3",style="coroots") - sage: D3 = WeylCharacterRing("D3",style="coroots") + sage: A3 = WeylCharacterRing("A3",style='coroots') + sage: D3 = WeylCharacterRing("D3",style='coroots') sage: [D3(fw) for fw in D3.fundamental_weights()] [D3(1,0,0), D3(0,1,0), D3(0,0,1)] - sage: [D3(fw).branch(A3,rule="isomorphic") for fw in D3.fundamental_weights()] + sage: [D3(fw).branch(A3,rule='isomorphic') for fw in D3.fundamental_weights()] [A3(0,1,0), A3(0,0,1), A3(1,0,0)] - sage: D2 = WeylCharacterRing("D2", style="coroots") - sage: A1xA1 = WeylCharacterRing("A1xA1", style="coroots") - sage: [D2(fw).branch(A1xA1,rule="isomorphic") for fw in D2.fundamental_weights()] + sage: D2 = WeylCharacterRing("D2", style='coroots') + sage: A1xA1 = WeylCharacterRing("A1xA1", style='coroots') + sage: [D2(fw).branch(A1xA1,rule='isomorphic') for fw in D2.fundamental_weights()] [A1xA1(1,0), A1xA1(0,1)] .. RUBRIC:: Branching From a Reducible WeylCharacterRing If the Cartan Type of R is reducible, we may project a character onto any of the components, or any combination of components. The rule to - project on the first component is specified by the string ``"proj1"``, + project on the first component is specified by the string ``'proj1'``, the rule to project on the second component is ``"proj2". To - project on the first and third components, use ``"proj13"`` and so on. + project on the first and third components, use ``'proj13'`` and so on. EXAMPLES:: - sage: A2xG2=WeylCharacterRing("A2xG2",style="coroots") - sage: A2=WeylCharacterRing("A2",style="coroots") - sage: G2=WeylCharacterRing("G2",style="coroots") - sage: A2xG2(1,0,1,0).branch(A2,rule="proj1") + sage: A2xG2=WeylCharacterRing("A2xG2",style='coroots') + sage: A2=WeylCharacterRing("A2",style='coroots') + sage: G2=WeylCharacterRing("G2",style='coroots') + sage: A2xG2(1,0,1,0).branch(A2,rule='proj1') 7*A2(1,0) - sage: A2xG2(1,0,1,0).branch(G2,rule="proj2") + sage: A2xG2(1,0,1,0).branch(G2,rule='proj2') 3*G2(1,0) - sage: A2xA2xG2=WeylCharacterRing("A2xA2xG2",style="coroots") - sage: A2xA2xG2(0,1,1,1,0,1).branch(A2xG2,rule="proj13") + sage: A2xA2xG2=WeylCharacterRing("A2xA2xG2",style='coroots') + sage: A2xA2xG2(0,1,1,1,0,1).branch(A2xG2,rule='proj13') 8*A2xG2(0,1,0,1) A more general way of specifying a branching rule from a reducible type is @@ -895,8 +894,8 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: D4 = WeylCharacterRing("D4",style="coroots") - sage: A1xA1xA1xA1 = WeylCharacterRing("A1xA1xA1xA1",style="coroots") + sage: D4 = WeylCharacterRing("D4",style='coroots') + sage: A1xA1xA1xA1 = WeylCharacterRing("A1xA1xA1xA1",style='coroots') sage: b = branching_rule("D2","A1xA1","isomorphic") sage: br = branching_rule("D4","D2xD2","extended")*branching_rule("D2xD2","A1xA1xA1xA1",[b,b]) sage: [D4(fw).branch(A1xA1xA1xA1,rule=br) for fw in D4.fundamental_weights()] @@ -917,12 +916,12 @@ def branch_weyl_character(chi, R, S, rule="default"): EXAMPLES:: - sage: A3xA2=WeylCharacterRing("A3xA2",style="coroots") - sage: A3=WeylCharacterRing("A3",style="coroots") + sage: A3xA2=WeylCharacterRing("A3xA2",style='coroots') + sage: A3=WeylCharacterRing("A3",style='coroots') sage: chi = A3xA2(0,1,0,1,0) sage: chi.branch(A3,rule=["identity","omit"]) 3*A3(0,1,0) - sage: A2=WeylCharacterRing("A2",style="coroots") + sage: A2=WeylCharacterRing("A2",style='coroots') sage: chi.branch(A2,rule=["omit","identity"]) 6*A2(1,0) @@ -931,12 +930,12 @@ def branch_weyl_character(chi, R, S, rule="default"): branching rule is equivalent to the tensor product, as the example shows:: - sage: G2=WeylCharacterRing("G2",style="coroots") - sage: G2xG2=WeylCharacterRing("G2xG2",style="coroots") - sage: G2=WeylCharacterRing("G2",style="coroots") - sage: G2xG2(1,0,0,1).branch(G2,rule="diagonal") + sage: G2=WeylCharacterRing("G2",style='coroots') + sage: G2xG2=WeylCharacterRing("G2xG2",style='coroots') + sage: G2=WeylCharacterRing("G2",style='coroots') + sage: G2xG2(1,0,0,1).branch(G2,rule='diagonal') G2(1,0) + G2(2,0) + G2(1,1) - sage: G2xG2(1,0,0,1).branch(G2,rule="diagonal") == G2(1,0)*G2(0,1) + sage: G2xG2(1,0,0,1).branch(G2,rule='diagonal') == G2(1,0)*G2(0,1) True .. RUBRIC:: Writing Your Own (Branching) Rules @@ -976,7 +975,7 @@ def rule(x): sage: br = BranchingRule("A3", "C2", lambda x: [x[0]-x[3],x[1]-x[2]], "homemade"); br homemade branching rule A3 => C2 - sage: [A3,C2]=[WeylCharacterRing(x,style="coroots") for x in ["A3","C2"]] + sage: [A3,C2]=[WeylCharacterRing(x,style='coroots') for x in ["A3","C2"]] sage: A3(0,1,0).branch(C2,rule=br) C2(0,0) + C2(0,1) """ @@ -1011,13 +1010,13 @@ class BranchingRule(SageObject): A class for branching rules. """ - def __init__(self, R, S, f, name="default", intermediate_types=[], + def __init__(self, R, S, f, name='default', intermediate_types=[], intermediate_names=[]): """ INPUT: - ``R``, ``S`` -- CartanTypes - - ``f`` -- a function from the weight lattice of R to the weight lattice of S + - ``f`` -- a function from the weight lattice of R to the weight lattice of S """ self._R = CartanType(R) self._S = CartanType(S) @@ -1035,7 +1034,7 @@ def _repr_(self): sage: branching_rule("E6","F4","symmetric") symmetric branching rule E6 => F4 - sage: b=branching_rule("F4","B3",rule="levi")*branching_rule("B3","G2",rule="miscellaneous"); b + sage: b=branching_rule("F4","B3",rule='levi')*branching_rule("B3","G2",rule='miscellaneous'); b composite branching rule F4 => (levi) B3 => (miscellaneous) G2 """ R_repr = self._R._repr_(compact=True) @@ -1091,7 +1090,7 @@ def __eq__(self, other): sage: b2 = BranchingRule("A2","A2",lambda x: x, "identity map") sage: b1 == b2 False - sage: A2 = WeylCharacterRing("A2",style="coroots") + sage: A2 = WeylCharacterRing("A2",style='coroots') sage: [A2(f).branch(A2,rule=b1) == A2(f).branch(A2,rule=b2) for f in A2.fundamental_weights()] [True, True] """ @@ -1116,7 +1115,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Test inequality + Test inequality. EXAMPLES:: @@ -1131,9 +1130,9 @@ def __mul__(self, other): """ EXAMPLES:: - sage: E6 = WeylCharacterRing("E6",style="coroots") - sage: A5 = WeylCharacterRing("A5",style="coroots") - sage: br = branching_rule("E6","A5xA1",rule="extended")*branching_rule("A5xA1","A5",rule="proj1"); br + sage: E6 = WeylCharacterRing("E6",style='coroots') + sage: A5 = WeylCharacterRing("A5",style='coroots') + sage: br = branching_rule("E6","A5xA1",rule='extended')*branching_rule("A5xA1","A5",rule='proj1'); br composite branching rule E6 => (extended) A5xA1 => (proj1) A5 sage: E6(1,0,0,0,0,0).branch(A5,rule=br) A5(0,0,0,1,0) + 2*A5(1,0,0,0,0) @@ -1175,8 +1174,8 @@ def Stype(self): return self._S def describe(self, verbose=False, debug=False, no_r=False): - """ - Describes how extended roots restrict under self. + r""" + Describe how extended roots restrict under ``self``. EXAMPLES:: @@ -1199,9 +1198,9 @@ def describe(self, verbose=False, debug=False, no_r=False): For more detailed information use verbose=True In this example, `0` is the affine root, that is, the negative - of the highest root, for `"G2"`. If `i => j` is printed, this - means that the i-th simple (or affine) root of the ambient - group restricts to the j-th simple root of the subgroup. + of the highest root, for `"G2"`. If `i \geq j` is printed, this + means that the `i`-th simple (or affine) root of the ambient + group restricts to the `j`-th simple root of the subgroup. For reference the Dynkin diagrams are also printed. The extended Dynkin diagram of the ambient group is printed if the affine root restricts to a simple root. More information @@ -1269,24 +1268,23 @@ def branch(self, chi, style=None): """ INPUT: - - ``chi`` -- A character of the WeylCharacterRing with Cartan type self.Rtype(). + - ``chi`` -- a character of the WeylCharacterRing with Cartan type self.Rtype() Returns the branched character. EXAMPLES:: - sage: G2=WeylCharacterRing("G2",style="coroots") + sage: G2=WeylCharacterRing("G2",style='coroots') sage: chi=G2(1,1); chi.degree() 64 sage: b=G2.maximal_subgroup("A2"); b extended branching rule G2 => A2 sage: b.branch(chi) A2(0,1) + A2(1,0) + A2(0,2) + 2*A2(1,1) + A2(2,0) + A2(1,2) + A2(2,1) - sage: A2=WeylCharacterRing("A2",style="coroots"); A2 + sage: A2=WeylCharacterRing("A2",style='coroots'); A2 The Weyl Character Ring of Type A2 with Integer Ring coefficients sage: chi.branch(A2,rule=b) A2(0,1) + A2(1,0) + A2(0,2) + 2*A2(1,1) + A2(2,0) + A2(1,2) + A2(2,1) - """ from sage.combinat.root_system.weyl_characters import WeylCharacterRing if style is None: @@ -1295,9 +1293,9 @@ def branch(self, chi, style=None): return chi.branch(S, rule=self) -def branching_rule(Rtype, Stype, rule="default"): +def branching_rule(Rtype, Stype, rule='default'): """ - Creates a branching rule. + Create a branching rule. INPUT: @@ -1305,8 +1303,8 @@ def branching_rule(Rtype, Stype, rule="default"): - ``S`` -- the Weyl Character Ring of `H` - - ``rule`` -- a string describing the branching rule as a map from - the weight space of `S` to the weight space of `R`. + - ``rule`` -- string describing the branching rule as a map from + the weight space of `S` to the weight space of `R` If the rule parameter is omitted, in some cases, a default rule is supplied. See :func:`~sage.combinat.root_system.branching_rules.branch_weyl_character`. @@ -1319,10 +1317,10 @@ def branching_rule(Rtype, Stype, rule="default"): """ if rule == "plethysm": try: - S = sage.combinat.root_system.weyl_characters.WeylCharacterRing(Stype.split("(")[0], style="coroots") + S = sage.combinat.root_system.weyl_characters.WeylCharacterRing(Stype.split("(")[0], style='coroots') chi = S(eval("("+Stype.split("(")[1])) except Exception: - S = sage.combinat.root_system.weyl_characters.WeylCharacterRing(Stype.split(".")[0], style="coroots") + S = sage.combinat.root_system.weyl_characters.WeylCharacterRing(Stype.split(".")[0], style='coroots') chi = eval("S." + Stype.split(".")[1]) return branching_rule_from_plethysm(chi, Rtype) Rtype = CartanType(Rtype) @@ -1385,24 +1383,24 @@ def br(x): if not Rtype.is_compound(): if Stype.is_compound() and s == r-1: try: - return branching_rule(Rtype, Stype, rule="levi") + return branching_rule(Rtype, Stype, rule='levi') except Exception: pass if Rtype[0] == "A": if Stype[0] == "B" and r == 2*s: - return branching_rule(Rtype, Stype, rule="symmetric") + return branching_rule(Rtype, Stype, rule='symmetric') elif Stype[0] == "C" and r == 2*s-1: - return branching_rule(Rtype, Stype, rule="symmetric") + return branching_rule(Rtype, Stype, rule='symmetric') elif Stype[0] == "D" and r == 2*s-1: - return branching_rule(Rtype, Stype, rule="symmetric") + return branching_rule(Rtype, Stype, rule='symmetric') elif Rtype[0] == "B" and Stype[0] == "D" and r == s: - return branching_rule(Rtype, Stype, rule="extended") + return branching_rule(Rtype, Stype, rule='extended') elif Rtype[0] == "D" and Stype[0] == "B" and r == s+1: - return branching_rule(Rtype, Stype, rule="symmetric") + return branching_rule(Rtype, Stype, rule='symmetric') if s == r-1: try: - return branching_rule(Rtype, Stype, rule="levi") + return branching_rule(Rtype, Stype, rule='levi') except Exception: pass raise ValueError("No default rule found (you must specify the rule)") @@ -1964,7 +1962,7 @@ def branching_rule_from_plethysm(chi, cartan_type, return_matrix=False): - ``chi`` -- the character of an irreducible representation `\pi` of a group `G` - - ``cartan_type`` -- a classical Cartan type (`A`,`B`,`C` or `D`). + - ``cartan_type`` -- a classical Cartan type (`A`,`B`,`C` or `D`) It is assumed that the image of the irreducible representation pi naturally has its image in the group `G`. @@ -1980,7 +1978,7 @@ def branching_rule_from_plethysm(chi, cartan_type, return_matrix=False): of `SL(3)`:: sage: A2 = WeylCharacterRing("A2") - sage: A2 = WeylCharacterRing("A2", style="coroots") + sage: A2 = WeylCharacterRing("A2", style='coroots') sage: ad = A2.adjoint_representation(); ad A2(1,1) sage: ad.degree() @@ -2043,7 +2041,7 @@ def branching_rule_from_plethysm(chi, cartan_type, return_matrix=False): return BranchingRule(ct, chi.parent().cartan_type(), lambda x: tuple(M*vector(x)), "plethysm (along %s)" % chi) -def maximal_subgroups(ct, mode="print_rules"): +def maximal_subgroups(ct, mode='print_rules'): """ Given a classical Cartan type (of rank less than or equal to 8) this prints the Cartan types of maximal subgroups, with a method @@ -2066,7 +2064,6 @@ def maximal_subgroups(ct, mode="print_rules"): A1xA1xA1xA1:branching_rule("D4","D2xD2","orthogonal_sum")*branching_rule("D2xD2","A1xA1xA1xA1",[branching_rule("D2","A1xA1","isomorphic"),branching_rule("D2","A1xA1","isomorphic")]) .. SEEALSO:: :meth:`~sage.combinat.root_system.weyl_characters.WeylCharacterRing.ParentMethods.maximal_subgroups` - """ if CartanType(ct) == CartanType("A2"): diff --git a/src/sage/combinat/root_system/cartan_matrix.py b/src/sage/combinat/root_system/cartan_matrix.py index 25728c98345..c8e665fcaa2 100644 --- a/src/sage/combinat/root_system/cartan_matrix.py +++ b/src/sage/combinat/root_system/cartan_matrix.py @@ -353,7 +353,7 @@ def matrix_space(self, nrows=None, ncols=None, sparse=None): - ``ncols`` -- number of columns - - ``sparse`` -- (boolean) sparseness + - ``sparse`` -- boolean EXAMPLES:: @@ -455,7 +455,7 @@ def root_space(self): """ return self.root_system().root_space() - def reflection_group(self, type="matrix"): + def reflection_group(self, type='matrix'): """ Return the reflection group corresponding to ``self``. @@ -717,7 +717,7 @@ def dual(self): def is_simply_laced(self): """ - Implements :meth:`CartanType_abstract.is_simply_laced()`. + Implement :meth:`CartanType_abstract.is_simply_laced()`. A Cartan matrix is simply-laced if all non diagonal entries are `0` or `-1`. @@ -737,7 +737,7 @@ def is_simply_laced(self): def is_crystallographic(self): """ - Implements :meth:`CartanType_abstract.is_crystallographic`. + Implement :meth:`CartanType_abstract.is_crystallographic`. A Cartan matrix is crystallographic if it is symmetrizable. @@ -750,7 +750,7 @@ def is_crystallographic(self): def column_with_indices(self, j): """ - Return the `j^{th}` column `(a_{i,j})_i` of ``self`` as a container + Return the `j`-th column `(a_{i,j})_i` of ``self`` as a container (or iterator) of tuples `(i, a_{i,j})` EXAMPLES:: @@ -763,7 +763,7 @@ def column_with_indices(self, j): def row_with_indices(self, i): """ - Return the `i^{th}` row `(a_{i,j})_j` of ``self`` as a container + Return the `i`-th row `(a_{i,j})_j` of ``self`` as a container (or iterator) of tuples `(j, a_{i,j})` EXAMPLES:: @@ -963,7 +963,7 @@ def coxeter_matrix(self): sage: ct.cartan_matrix().coxeter_matrix() == ct.coxeter_matrix() True """ - scalarproducts_to_order = {0: 2, 1: 3, 2: 4, 3: 6} + scalarproducts_to_order = {0: 2, 1: 3, 2: 4, 3: 6} from sage.combinat.root_system.coxeter_matrix import CoxeterMatrix I = self.index_set() n = len(I) @@ -1017,7 +1017,6 @@ def principal_submatrices(self, proper=False): ] sage: M.principal_submatrices(proper=True) # needs sage.graphs [[], [2], [2]] - """ iset = list(range(self.ncols())) ret = [] diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index e4526d5f079..ce5762719e2 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -438,7 +438,7 @@ The data essentially consists of a description of the Dynkin/Coxeter diagram and, when relevant, of the natural embedding of the root -system in an Euclidean space. Everything else is reconstructed from +system in a Euclidean space. Everything else is reconstructed from this data. - :ref:`sage.combinat.root_system.type_A` @@ -503,7 +503,7 @@ class CartanTypeFactory(SageObject): def __call__(self, *args): """ - Constructs a Cartan type object. + Construct a Cartan type object. INPUT: @@ -511,9 +511,9 @@ def __call__(self, *args): and rank is an integer or a pair of integers - ``[letter, rank, twist]`` -- letter is one of 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'BC' - and rank and twist are integers + and rank and twist are integers - - ``str`` -- a string + - ``str`` -- string - ``object`` -- a Cartan type, or an object with a Cartan type method @@ -750,11 +750,11 @@ def samples(self, finite=None, affine=None, crystallographic=None): INPUT: - - ``finite`` -- a boolean or ``None`` (default: ``None``) + - ``finite`` -- boolean or ``None`` (default: ``None``) - - ``affine`` -- a boolean or ``None`` (default: ``None``) + - ``affine`` -- boolean or ``None`` (default: ``None``) - - ``crystallographic`` -- a boolean or ``None`` (default: ``None``) + - ``crystallographic`` -- boolean or ``None`` (default: ``None``) The sample contains all the exceptional finite and affine Cartan types, as well as typical representatives of the @@ -854,7 +854,7 @@ def _samples(self): @classmethod def color(cls, i): """ - Default color scheme for the vertices of a Dynkin diagram (and associated objects) + Default color scheme for the vertices of a Dynkin diagram (and associated objects). EXAMPLES:: @@ -884,7 +884,7 @@ def color(cls, i): # add options to class class options(GlobalOptions): r""" - Sets and displays the options for Cartan types. If no parameters + Set and display the options for Cartan types. If no parameters are set, then the function returns a copy of the options dictionary. The ``options`` to partitions can be accessed as the method @@ -938,27 +938,27 @@ class options(GlobalOptions): NAME = 'CartanType' module = 'sage.combinat.root_system.cartan_type' option_class = 'CartanTypeFactory' - notation = dict(default="Stembridge", + notation = dict(default='Stembridge', description='Specifies which notation Cartan types should use when printed', values=dict(Stembridge="use Stembridge's notation", Kac="use Kac's notation"), case_sensitive=False, - alias=dict(BC="Stembridge", tilde="Stembridge", twisted="Kac")) - dual_str = dict(default="*", + alias=dict(BC='Stembridge', tilde='Stembridge', twisted='Kac')) + dual_str = dict(default='*', description='The string used for dual Cartan types when printing', checker=lambda char: isinstance(char, str)) - dual_latex = dict(default="\\vee", + dual_latex = dict(default='\\vee', description='The latex used for dual CartanTypes when latexing', checker=lambda char: isinstance(char, str)) - mark_special_node = dict(default="none", + mark_special_node = dict(default='none', description="Make the special nodes", values=dict(none="no markup", latex="only in latex", printing="only in printing", both="both in latex and printing"), case_sensitive=False) - special_node_str = dict(default="@", + special_node_str = dict(default='@', description="The string used to indicate which node is special when printing", checker=lambda char: isinstance(char, str)) - marked_node_str = dict(default="X", + marked_node_str = dict(default='X', description="The string used to indicate a marked node when printing", checker=lambda char: isinstance(char, str)) latex_relabel = dict(default=True, @@ -1048,7 +1048,7 @@ def _ascii_art_node(self, label): """ return "O" - def _latex_draw_node(self, x, y, label, position="below=4pt", fill='white'): + def _latex_draw_node(self, x, y, label, position='below=4pt', fill='white'): r""" Draw (possibly marked [crossed out]) circular node ``i`` at the position ``(x,y)`` with node label ``label`` . @@ -1066,7 +1066,7 @@ def _latex_draw_node(self, x, y, label, position="below=4pt", fill='white'): def _latex_draw_arrow_tip(self, x, y, rot=0): r""" - Draw an arrow tip at the point ``(x, y)`` rotated by ``rot`` + Draw an arrow tip at the point ``(x, y)`` rotated by ``rot``. INPUT: @@ -1261,7 +1261,7 @@ def marked_nodes(self, marked_nodes): INPUT: - - ``marked_nodes`` -- a list of nodes to mark + - ``marked_nodes`` -- list of nodes to mark EXAMPLES:: @@ -1663,7 +1663,7 @@ def coxeter_diagram(self): def is_crystallographic(self): """ - Implements :meth:`CartanType_abstract.is_crystallographic` + Implement :meth:`CartanType_abstract.is_crystallographic` by returning ``True``. EXAMPLES:: @@ -1889,7 +1889,7 @@ def _ascii_art_node(self, label): return self.options('special_node_str') return super()._ascii_art_node(label) - def _latex_draw_node(self, x, y, label, position="below=4pt"): + def _latex_draw_node(self, x, y, label, position='below=4pt'): r""" Draw (possibly marked [crossed out]) circular node ``i`` at the position ``(x,y)`` with node label ``label`` . @@ -1930,7 +1930,7 @@ def is_affine(self): def is_untwisted_affine(self): """ - Return whether ``self`` is untwisted affine + Return whether ``self`` is untwisted affine. A Cartan type is untwisted affine if it is the canonical affine extension of some finite type. Every affine type is @@ -2046,7 +2046,6 @@ def classical(self): ....: g2.delete_vertex(ct.special_node()) ....: assert g1.vertices(sort=True) == g2.vertices(sort=True) ....: assert g1.edges(sort=True) == g2.edges(sort=True) - """ @abstract_method @@ -2092,7 +2091,7 @@ def row_annihilator(self, m=None): combination of `\alpha_0, \alpha_1, \ldots, \alpha_n` with nonnegative coefficients (or alternatively, the unique minimal non trivial annihilating linear combination of the rows of the - Cartan matrix with non-negative coefficients). + Cartan matrix with nonnegative coefficients). Throw an error if the existence of uniqueness does not hold @@ -2140,7 +2139,7 @@ def col_annihilator(self): combination of `\alpha^\vee_0, \alpha^\vee, \ldots, \alpha^\vee` with nonnegative coefficients (or alternatively, the unique minimal non trivial annihilating linear combination of the columns of the - Cartan matrix with non-negative coefficients). + Cartan matrix with nonnegative coefficients). Throw an error if the existence or uniqueness does not hold @@ -2171,7 +2170,7 @@ def col_annihilator(self): def c(self): r""" - Returns the family (c_i)_i of integer coefficients defined by + Return the family (c_i)_i of integer coefficients defined by `c_i=max(1, a_i/a^vee_i)` (see e.g. [FSS07]_ p. 3) FIXME: the current implementation assumes that the Cartan @@ -2389,7 +2388,7 @@ def translation_factors(self): def _test_dual_classical(self, **options): r""" - Tests whether the special node of the dual is still the same and whether + Test whether the special node of the dual is still the same and whether the methods dual and classical commute. TESTS:: @@ -2535,7 +2534,6 @@ def __reduce__(self): (CartanType, ('D', 4)) sage: T == loads(dumps(T)) True - """ return (CartanType, (self.letter, self.n)) @@ -2553,7 +2551,7 @@ def __hash__(self): def index_set(self): r""" - Implements :meth:`CartanType_abstract.index_set`. + Implement :meth:`CartanType_abstract.index_set`. The index set for all standard finite Cartan types is of the form `\{1, \ldots, n\}`. (See :mod:`~sage.combinat.root_system.type_I` @@ -2648,7 +2646,7 @@ def type(self): @cached_method def opposition_automorphism(self): r""" - Return the opposition automorphism + Return the opposition automorphism. The *opposition automorphism* is the automorphism `i \mapsto i^*` of the vertices Dynkin diagram such that, @@ -2708,7 +2706,6 @@ def __init__(self, letter, n, affine=1): False sage: ct1 == ct3 False - """ assert (letter in ['A', 'B', 'C', 'BC', 'D', 'E', 'F', 'G']) self.letter = letter @@ -2748,7 +2745,6 @@ def __reduce__(self): (CartanType, ('D', 4, 1)) sage: T == loads(dumps(T)) True - """ return (CartanType, (self.letter, self.n, self.affine)) @@ -2816,7 +2812,7 @@ def rank(self): def index_set(self): r""" - Implements :meth:`CartanType_abstract.index_set`. + Implement :meth:`CartanType_abstract.index_set`. The index set for all standard affine Cartan types is of the form `\{0, \ldots, n\}`. @@ -2917,7 +2913,6 @@ def is_untwisted_affine(self): sage: CartanType(['B', 3, 1]).is_untwisted_affine() True - """ return True @@ -3069,39 +3064,3 @@ def __getitem__(self, i): raise IndexError("index out of range") options = CartanType.options - -############################################################################## -# For backward compatibility - - -class CartanType_simple_finite: - def __setstate__(self, dict): - """ - Implements the unpickling of Cartan types pickled by Sage <= 4.0. - - EXAMPLES: - - This is the pickle for CartanType(["A", 4]):: - - sage: pg_CartanType_simple_finite = unpickle_global('sage.combinat.root_system.cartan_type', 'CartanType_simple_finite') - sage: si1 = unpickle_newobj(pg_CartanType_simple_finite, ()) - sage: from sage.misc.fpickle import unpickleModule - sage: pg_make_integer = unpickle_global('sage.rings.integer', 'make_integer') - sage: si2 = pg_make_integer('4') - sage: unpickle_build(si1, {'tools':unpickleModule('sage.combinat.root_system.type_A'), 't':['A', si2], 'letter':'A', 'n':si2}) - - sage: si1 - ['A', 4] - sage: si1.dynkin_diagram() # needs sage.graphs - O---O---O---O - 1 2 3 4 - A4 - - This is quite hacky; in particular unique representation is not preserved:: - - sage: si1 == CartanType(["A", 4]) # todo: not implemented - True - """ - T = CartanType([dict['letter'], dict['n']]) - self.__class__ = T.__class__ - self.__dict__ = T.__dict__ diff --git a/src/sage/combinat/root_system/coxeter_group.py b/src/sage/combinat/root_system/coxeter_group.py index 854e1625b64..656c933c3e5 100644 --- a/src/sage/combinat/root_system/coxeter_group.py +++ b/src/sage/combinat/root_system/coxeter_group.py @@ -16,7 +16,7 @@ lazy_import('sage.combinat.root_system.weyl_group', 'WeylGroup') -def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=None): +def CoxeterGroup(data, implementation='reflection', base_ring=None, index_set=None): """ Return an implementation of the Coxeter group given by ``data``. @@ -69,46 +69,46 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No We now use the ``implementation`` option:: - sage: W = CoxeterGroup(["A",2], implementation="permutation"); W # optional - gap3 + sage: W = CoxeterGroup(["A",2], implementation='permutation'); W # optional - gap3 Permutation Group with generators [(1,4)(2,3)(5,6), (1,3)(2,5)(4,6)] sage: W.category() # optional - gap3 Join of Category of finite enumerated permutation groups and Category of finite Weyl groups and Category of well generated finite irreducible complex reflection groups - sage: W = CoxeterGroup(["A",2], implementation="matrix"); W # needs sage.libs.gap + sage: W = CoxeterGroup(["A",2], implementation='matrix'); W # needs sage.libs.gap Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) - sage: W = CoxeterGroup(["H",3], implementation="matrix"); W # needs sage.libs.gap sage.rings.number_field + sage: W = CoxeterGroup(["H",3], implementation='matrix'); W # needs sage.libs.gap sage.rings.number_field Finite Coxeter group over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] - sage: W = CoxeterGroup(["H",3], implementation="reflection"); W # needs sage.libs.gap sage.rings.number_field + sage: W = CoxeterGroup(["H",3], implementation='reflection'); W # needs sage.libs.gap sage.rings.number_field Finite Coxeter group over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] - sage: W = CoxeterGroup(["A",4,1], implementation="permutation") # needs sage.libs.gap + sage: W = CoxeterGroup(["A",4,1], implementation='permutation') # needs sage.libs.gap Traceback (most recent call last): ... ValueError: the type must be finite - sage: W = CoxeterGroup(["A",4], implementation="chevie"); W # optional - gap3 + sage: W = CoxeterGroup(["A",4], implementation='chevie'); W # optional - gap3 Irreducible real reflection group of rank 4 and type A4 We use the different options for the "reflection" implementation:: - sage: W = CoxeterGroup(["H",3], implementation="reflection", base_ring=RR); W # needs sage.libs.gap + sage: W = CoxeterGroup(["H",3], implementation='reflection', base_ring=RR); W # needs sage.libs.gap Finite Coxeter group over Real Field with 53 bits of precision with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1] - sage: W = CoxeterGroup([[1,10],[10,1]], implementation="reflection", # needs sage.symbolics + sage: W = CoxeterGroup([[1,10],[10,1]], implementation='reflection', # needs sage.symbolics ....: index_set=['a','b'], base_ring=SR); W Finite Coxeter group over Symbolic Ring with Coxeter matrix: [ 1 10] @@ -144,7 +144,7 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No if not cartan_type.is_finite(): raise ValueError("the type must be finite") if cartan_type.is_crystallographic(): - return WeylGroup(cartan_type, implementation="permutation") + return WeylGroup(cartan_type, implementation='permutation') return ReflectionGroup(cartan_type, index_set=index_set) elif implementation == "matrix": if cartan_type.is_crystallographic(): @@ -157,4 +157,4 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.coxeter_group', 'CoxeterGroupAsPermutationGroup', ReflectionGroup) +register_unpickle_override('sage.combinat.root_system.coxeter_group', 'CoxeterGroupAsPermutationGroup', ReflectionGroup) diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index 88a53e4bd98..10312d7e59d 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -69,11 +69,11 @@ def samples(self, finite=None, affine=None, crystallographic=None): INPUT: - - ``finite`` -- a boolean or ``None`` (default: ``None``) + - ``finite`` -- boolean or ``None`` (default: ``None``) - - ``affine`` -- a boolean or ``None`` (default: ``None``) + - ``affine`` -- boolean or ``None`` (default: ``None``) - - ``crystallographic`` -- a boolean or ``None`` (default: ``None``) + - ``crystallographic`` -- boolean or ``None`` (default: ``None``) The sample contains all the exceptional finite and affine Coxeter types, as well as typical representatives of the diff --git a/src/sage/combinat/root_system/dynkin_diagram.py b/src/sage/combinat/root_system/dynkin_diagram.py index 0b815043999..b190601f0bf 100644 --- a/src/sage/combinat/root_system/dynkin_diagram.py +++ b/src/sage/combinat/root_system/dynkin_diagram.py @@ -160,7 +160,7 @@ def DynkinDiagram(*args, **kwds): TESTS: - Check that :issue:`15277` is fixed by not having edges from 0's:: + Check that :issue:`15277` is fixed by not having edges from 0s:: sage: CM = CartanMatrix([[2,-1,0,0],[-3,2,-2,-2],[0,-1,2,-1],[0,-1,-1,2]]) sage: CM @@ -299,7 +299,7 @@ def _repr_(self, compact=False): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. Override rich output because :meth:`_repr_` outputs ascii art. The proper fix will be in :issue:`18328`. @@ -323,7 +323,7 @@ def _rich_repr_(self, display_manager, **kwds): def _latex_(self, scale=0.5): r""" - Return a latex representation of this Dynkin diagram + Return a latex representation of this Dynkin diagram. EXAMPLES:: @@ -403,7 +403,7 @@ def __hash__(self): @staticmethod def an_instance(): """ - Returns an example of Dynkin diagram + Return an example of Dynkin diagram. EXAMPLES:: @@ -415,7 +415,6 @@ def an_instance(): [ 2 -1 -1] [-2 2 -1] [-1 -1 2] - """ # hyperbolic Dynkin diagram of Exercise 4.9 p. 57 of Kac Infinite Dimensional Lie Algebras. g = DynkinDiagram() @@ -451,7 +450,7 @@ def cartan_type(self): def rank(self): r""" - Returns the index set for this Dynkin diagram + Return the index set for this Dynkin diagram. EXAMPLES:: @@ -476,7 +475,7 @@ def dynkin_diagram(self): @cached_method def cartan_matrix(self): r""" - Returns the Cartan matrix for this Dynkin diagram + Return the Cartan matrix for this Dynkin diagram. EXAMPLES:: @@ -489,7 +488,7 @@ def cartan_matrix(self): def dual(self): r""" - Returns the dual Dynkin diagram, obtained by reversing all edges. + Return the dual Dynkin diagram, obtained by reversing all edges. EXAMPLES:: @@ -686,7 +685,7 @@ def is_irreducible(self): def is_crystallographic(self): """ - Implements :meth:`CartanType_abstract.is_crystallographic` + Implement :meth:`CartanType_abstract.is_crystallographic`. A Dynkin diagram always corresponds to a crystallographic root system. @@ -784,9 +783,9 @@ def __getitem__(self, i): def column(self, j): """ - Returns the `j^{th}` column `(a_{i,j})_i` of the + Return the `j`-th column `(a_{i,j})_i` of the Cartan matrix corresponding to this Dynkin diagram, as a container - (or iterator) of tuples `(i, a_{i,j})` + (or iterator) of tuples `(i, a_{i,j})`. EXAMPLES:: @@ -799,9 +798,9 @@ def column(self, j): def row(self, i): """ - Returns the `i^{th}` row `(a_{i,j})_j` of the + Return the `i`-th row `(a_{i,j})_j` of the Cartan matrix corresponding to this Dynkin diagram, as a container - (or iterator) of tuples `(j, a_{i,j})` + (or iterator) of tuples `(j, a_{i,j})`. EXAMPLES:: @@ -835,7 +834,7 @@ def coxeter_diagram(self): True """ from sage.rings.infinity import infinity - scalarproducts_to_order = {0: 2, 1: 3, 2: 4, 3: 6} + scalarproducts_to_order = {0: 2, 1: 3, 2: 4, 3: 6} from sage.graphs.graph import Graph coxeter_diagram = Graph(multiedges=False) I = self.index_set() diff --git a/src/sage/combinat/root_system/extended_affine_weyl_group.py b/src/sage/combinat/root_system/extended_affine_weyl_group.py index 64a08c28808..b1d35c86f7a 100644 --- a/src/sage/combinat/root_system/extended_affine_weyl_group.py +++ b/src/sage/combinat/root_system/extended_affine_weyl_group.py @@ -54,11 +54,11 @@ def ExtendedAffineWeylGroup(cartan_type, general_linear=None, **print_options): INPUT: - - ``cartan_type`` -- An affine or finite Cartan type (a finite Cartan type is an + - ``cartan_type`` -- an affine or finite Cartan type (a finite Cartan type is an abbreviation for its untwisted affinization) - - ``general_linear`` -- (default: ``None``) If ``True`` and ``cartan_type`` indicates + - ``general_linear`` -- (default: ``None``) if ``True`` and ``cartan_type`` indicates untwisted type A, returns the universal central extension - - ``print_options`` -- Special instructions for printing elements (see below) + - ``print_options`` -- special instructions for printing elements (see below) .. RUBRIC:: Mnemonics @@ -76,12 +76,12 @@ def ExtendedAffineWeylGroup(cartan_type, general_linear=None, **print_options): Recognized arguments for ``print_options`` are: - - ``print_tuple`` -- ``True`` or ``False`` (default: ``False``) - If ``True``, elements are printed `(a,b)`, otherwise as `a * b` - - ``affine`` -- Prefix for simple reflections in the affine Weyl group - - ``classical`` -- Prefix for simple reflections in the classical Weyl group - - ``translation`` -- Prefix for the translation elements - - ``fundamental`` -- Prefix for the elements of the fundamental group + - ``print_tuple`` -- boolean (default: ``False``); if ``True``, elements + are printed `(a,b)`, otherwise as `a * b` + - ``affine`` -- prefix for simple reflections in the affine Weyl group + - ``classical`` -- prefix for simple reflections in the classical Weyl group + - ``translation`` -- prefix for the translation elements + - ``fundamental`` -- prefix for the elements of the fundamental group These options are not mutable. @@ -101,20 +101,20 @@ def ExtendedAffineWeylGroup(cartan_type, general_linear=None, **print_options): .. RUBRIC:: Notation - - `R` -- An irreducible affine root system - - `I` -- Set of nodes of the Dynkin diagram of `R` - - `R_0` -- The classical subsystem of `R` - - `I_0` -- Set of nodes of the Dynkin diagram of `R_0` - - `E` -- Extended affine Weyl group of type `R` - - `W` -- Affine Weyl group of type `R` + - `R` -- an irreducible affine root system + - `I` -- set of nodes of the Dynkin diagram of `R` + - `R_0` -- the classical subsystem of `R` + - `I_0` -- set of nodes of the Dynkin diagram of `R_0` + - `E` -- extended affine Weyl group of type `R` + - `W` -- affine Weyl group of type `R` - `W_0` -- finite (classical) Weyl group (of type `R_0`) - `M` -- translation lattice for `W` - `L` -- translation lattice for `E` - - `F` -- Fundamental subgroup of `E` (the length zero elements) - - `P` -- Finite weight lattice - - `Q` -- Finite root lattice - - `P^\vee` -- Finite coweight lattice - - `Q^\vee` -- Finite coroot lattice + - `F` -- fundamental subgroup of `E` (the length zero elements) + - `P` -- finite weight lattice + - `Q` -- finite root lattice + - `P^\vee` -- finite coweight lattice + - `Q^\vee` -- finite coroot lattice .. RUBRIC:: Translation lattices @@ -345,8 +345,8 @@ def ExtendedAffineWeylGroup(cartan_type, general_linear=None, **print_options): Here is a demonstration of the printing options:: - sage: E = ExtendedAffineWeylGroup(["A",2,1], affine="sx", classical="Sx", - ....: translation="x", fundamental="pix") + sage: E = ExtendedAffineWeylGroup(["A",2,1], affine='sx', classical='Sx', + ....: translation='x', fundamental='pix') sage: PW0 = E.PW0() sage: y = PW0(E.lattice_basis()[1]); y x[Lambdacheck[1]] @@ -991,7 +991,7 @@ def group_generators(self): @cached_method def PW0_to_WF_func(self, x): r""" - Implements coercion from style "PW0" to "WF". + Implement coercion from style "PW0" to "WF". EXAMPLES:: @@ -1187,7 +1187,7 @@ def simple_reflections(self): Finite family {0: (pi[0], S0), 1: (pi[0], S1), 2: (pi[0], S2), 3: (pi[0], S3)} sage: ExtendedAffineWeylGroup(['A',3,1], - ....: fundamental="f", + ....: fundamental='f', ....: print_tuple=True).FW().simple_reflections() Finite family {0: (f[0], S0), 1: (f[0], S1), 2: (f[0], S2), 3: (f[0], S3)} @@ -1203,7 +1203,7 @@ def simple_reflection(self, i): INPUT: - ``self`` -- a realization of the extended affine Weyl group - - ``i`` -- An affine Dynkin node + - ``i`` -- an affine Dynkin node EXAMPLES:: @@ -1308,7 +1308,7 @@ def from_affine_weyl(self, w): def from_reduced_word(self, word): r""" - Converts an affine or finite reduced word into a group element. + Convert an affine or finite reduced word into a group element. EXAMPLES:: @@ -1333,7 +1333,7 @@ def has_descent(self, i, side='right', positive=False): OPTIONAL: - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) If ``side='left'``, then the reflection acts on the left. If ``positive=True``, then the inequality is reversed. @@ -1365,7 +1365,7 @@ def first_descent(self, side='right', positive=False, index_set=None): INPUT: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) - ``index_set`` -- an optional subset of Dynkin nodes If ``index_set`` is not ``None``, then the descent must be in the ``index_set``. @@ -1417,12 +1417,12 @@ def apply_simple_projection(self, i, side='right', length_increasing=True): INPUT: - ``self`` -- an element of the extended affine Weyl group - - `i` -- a Dynkin node (index of a simple reflection `s_i`) + - ``i`` -- a Dynkin node (index of a simple reflection `s_i`) - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``) according to which side of ``self`` the reflection `s_i` should be multiplied - - ``length_increasing`` -- ``True`` or ``False`` (default ``True``). - If ``False``, do the above with the word "greater" replaced by "less". + - ``length_increasing`` -- boolean (default: ``True``); + if ``False``, do the above with the word "greater" replaced by "less" EXAMPLES:: @@ -1695,7 +1695,7 @@ def bruhat_le(self, x): INPUT: - ``self`` -- an element of the extended affine Weyl group - - `x` -- another element with the same parent as ``self`` + - ``x`` -- another element with the same parent as ``self`` EXAMPLES:: @@ -1756,14 +1756,14 @@ def action(self, la): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], affine="s") + sage: E = ExtendedAffineWeylGroup(['A',2,1], affine='s') sage: x = E.FW().an_element(); x pi[2] * s0*s1*s2 sage: la = E.lattice().an_element(); la 2*Lambdacheck[1] + 2*Lambdacheck[2] sage: x.action(la) 5*Lambdacheck[1] - 3*Lambdacheck[2] - sage: E = ExtendedAffineWeylGroup(['C',2,1], affine="s") + sage: E = ExtendedAffineWeylGroup(['C',2,1], affine='s') sage: x = E.PW0().from_translation(E.lattice_basis()[1]) sage: x.action(E.lattice_basis()[2]) Lambdacheck[1] + Lambdacheck[2] @@ -1788,14 +1788,14 @@ def dual_action(self, la): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], affine="s") + sage: E = ExtendedAffineWeylGroup(['A',2,1], affine='s') sage: x = E.FW().an_element(); x pi[2] * s0*s1*s2 sage: la = E.dual_lattice().an_element(); la 2*Lambda[1] + 2*Lambda[2] sage: x.dual_action(la) 5*Lambda[1] - 3*Lambda[2] - sage: E = ExtendedAffineWeylGroup(['C',2,1], affine="s") + sage: E = ExtendedAffineWeylGroup(['C',2,1], affine='s') sage: x = E.PvW0().from_dual_translation(E.dual_lattice_basis()[1]) sage: x.dual_action(E.dual_lattice_basis()[2]) Lambda[1] + Lambda[2] @@ -1835,7 +1835,7 @@ def face_data(self, i): INPUT: - - ``self`` -- An element of the extended affine Weyl group + - ``self`` -- an element of the extended affine Weyl group - ``i`` -- an affine Dynkin node OUTPUT: @@ -1929,7 +1929,7 @@ def has_descent(self, i, side='right', positive=False): OPTIONAL: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -2013,7 +2013,7 @@ class ExtendedAffineWeylGroupPW0(GroupSemidirectProduct, BindableClass): INPUT: - - ``E`` -- A parent with realization in :class:`ExtendedAffineWeylGroup_Class` + - ``E`` -- a parent with realization in :class:`ExtendedAffineWeylGroup_Class` EXAMPLES:: @@ -2058,7 +2058,7 @@ def from_translation(self, la): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], translation="tau", + sage: E = ExtendedAffineWeylGroup(['A',2,1], translation='tau', ....: print_tuple=True) sage: la = E.lattice().an_element(); la 2*Lambdacheck[1] + 2*Lambdacheck[2] @@ -2134,12 +2134,12 @@ def has_descent(self, i, side='right', positive=False): INPUT: - - ``i`` -- an index. + - ``i`` -- an index OPTIONAL: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -2203,7 +2203,7 @@ class ExtendedAffineWeylGroupW0P(GroupSemidirectProduct, BindableClass): INPUT: - - ``E`` -- A parent with realization in :class:`ExtendedAffineWeylGroup_Class` + - ``E`` -- a parent with realization in :class:`ExtendedAffineWeylGroup_Class` EXAMPLES:: @@ -2318,7 +2318,7 @@ def has_descent(self, i, side='right', positive=False): OPTIONAL: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -2368,7 +2368,7 @@ def bruhat_le(self, x): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], affine="s", + sage: E = ExtendedAffineWeylGroup(['A',2,1], affine='s', ....: print_tuple=True); WF = E.WF() sage: r = E.affine_weyl().from_reduced_word sage: v = r([1,0]) @@ -2401,7 +2401,7 @@ class ExtendedAffineWeylGroupWF(GroupSemidirectProduct, BindableClass): INPUT: - - ``E`` -- A parent with realization in :class:`ExtendedAffineWeylGroup_Class` + - ``E`` -- a parent with realization in :class:`ExtendedAffineWeylGroup_Class` EXAMPLES:: @@ -2454,7 +2454,7 @@ def simple_reflections(self): EXAMPLES:: - sage: ExtendedAffineWeylGroup(["A",3,1], affine="r").WF().simple_reflections() + sage: ExtendedAffineWeylGroup(["A",3,1], affine='r').WF().simple_reflections() Finite family {0: r0, 1: r1, 2: r2, 3: r3} """ E = self.realization_of() @@ -2487,12 +2487,12 @@ def has_descent(self, i, side='right', positive=False): INPUT: - - `i` -- an affine Dynkin index. + - ``i`` -- an affine Dynkin index OPTIONAL: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -2542,7 +2542,7 @@ def action_on_affine_roots(self, beta): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], affine="s") + sage: E = ExtendedAffineWeylGroup(['A',2,1], affine='s') sage: x = E.FW().an_element(); x pi[2] * s0*s1*s2 sage: v = RootSystem(['A',2,1]).root_lattice().an_element(); v @@ -2561,7 +2561,7 @@ class ExtendedAffineWeylGroupFW(GroupSemidirectProduct, BindableClass): INPUT: - - ``E`` -- A parent with realization in :class:`ExtendedAffineWeylGroup_Class` + - ``E`` -- a parent with realization in :class:`ExtendedAffineWeylGroup_Class` EXAMPLES:: @@ -2652,7 +2652,7 @@ def has_descent(self, i, side='right', positive=False): OPTIONAL: - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) - - ``positive`` -- ``True`` or ``False`` (default: ``False``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -2733,7 +2733,7 @@ class ExtendedAffineWeylGroupPvW0(GroupSemidirectProduct, BindableClass): INPUT: - - ``E`` -- A parent with realization in :class:`ExtendedAffineWeylGroup_Class` + - ``E`` -- a parent with realization in :class:`ExtendedAffineWeylGroup_Class` EXAMPLES:: @@ -2776,7 +2776,7 @@ def from_dual_translation(self, la): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], translation="tau", + sage: E = ExtendedAffineWeylGroup(['A',2,1], translation='tau', ....: print_tuple=True) sage: la = E.dual_lattice().an_element(); la 2*Lambda[1] + 2*Lambda[2] @@ -2842,12 +2842,12 @@ def has_descent(self, i, side='right', positive=False): INPUT: - - `i` -- an affine Dynkin index + - ``i`` -- an affine Dynkin index OPTIONAL: - - ``side`` -- 'left' or 'right' (default: 'right') - - ``positive`` -- True or False (default: ``False``) + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -2905,7 +2905,7 @@ class ExtendedAffineWeylGroupW0Pv(GroupSemidirectProduct, BindableClass): INPUT: - - `E` -- A parent with realization in :class:`ExtendedAffineWeylGroup_Class` + - ``E`` -- a parent with realization in :class:`ExtendedAffineWeylGroup_Class` EXAMPLES:: @@ -2947,7 +2947,7 @@ def from_dual_translation(self, la): EXAMPLES:: - sage: E = ExtendedAffineWeylGroup(['A',2,1], translation="tau", + sage: E = ExtendedAffineWeylGroup(['A',2,1], translation='tau', ....: print_tuple=True) sage: la = E.dual_lattice().an_element(); la 2*Lambda[1] + 2*Lambda[2] diff --git a/src/sage/combinat/root_system/fundamental_group.py b/src/sage/combinat/root_system/fundamental_group.py index 6dc13e302ec..d59f6af5415 100644 --- a/src/sage/combinat/root_system/fundamental_group.py +++ b/src/sage/combinat/root_system/fundamental_group.py @@ -39,9 +39,9 @@ def FundamentalGroupOfExtendedAffineWeylGroup(cartan_type, prefix='pi', - ``cartan_type`` -- a Cartan type that is either affine or finite, with the latter being a shorthand for the untwisted affinization - - ``prefix`` (default: 'pi') -- string that labels the elements of the group - - ``general_linear`` -- (default: None, meaning False) In untwisted type A, if True, use the - universal central extension + - ``prefix`` -- (default: ``'pi'``) string that labels the elements of the group + - ``general_linear`` -- (default: ``None``, meaning ``False``) In untwisted + type `A`, if ``True``, use the universal central extension .. RUBRIC:: Fundamental group @@ -185,7 +185,7 @@ def FundamentalGroupOfExtendedAffineWeylGroup(cartan_type, prefix='pi', (2, 2, 3) sage: x.act_on_classical_ambient(wt) (2, 3, 2) - sage: w = WeylGroup(F.cartan_type(),prefix="s").an_element(); w + sage: w = WeylGroup(F.cartan_type(),prefix='s').an_element(); w s0*s1*s2 sage: x.act_on_affine_weyl(w) s2*s0*s1 @@ -207,12 +207,12 @@ def FundamentalGroupOfExtendedAffineWeylGroup(cartan_type, prefix='pi', class FundamentalGroupElement(MultiplicativeGroupElement): def __init__(self, parent, x): r""" - This should not be called directly + This should not be called directly. EXAMPLES:: sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup - sage: x = FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1], prefix="f").an_element() + sage: x = FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1], prefix='f').an_element() sage: TestSuite(x).run() """ if x not in parent.special_nodes(): @@ -227,7 +227,7 @@ def value(self): EXAMPLES:: sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup - sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1], prefix="f") + sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1], prefix='f') sage: F.special_nodes() (0, 1, 2, 3, 4) sage: x = F(4); x @@ -244,7 +244,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup - sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1], prefix="f") + sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1], prefix='f') sage: F(2)^3 # indirect doctest f[1] """ @@ -260,7 +260,7 @@ def __invert__(self): sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',3,1]) sage: F(1).inverse() # indirect doctest pi[3] - sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['E',6,1], prefix="f") + sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['E',6,1], prefix='f') sage: F(1).inverse() f[6] """ @@ -295,7 +295,7 @@ def act_on_affine_weyl(self, w): sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',3,1]) - sage: W = WeylGroup(F.cartan_type(),prefix="s") + sage: W = WeylGroup(F.cartan_type(),prefix='s') sage: w = W.from_reduced_word([2,3,0]) sage: F(1).act_on_affine_weyl(w).reduced_word() [3, 0, 1] @@ -397,7 +397,7 @@ def leading_support(beta): Q = RootSystem(cartan_type_classical).root_lattice() alpha = Q.simple_roots() omega = RootSystem(cartan_type_classical).weight_lattice().fundamental_weights() - W = Q.weyl_group(prefix="s") + W = Q.weyl_group(prefix='s') for i in self._special_nodes: if i == special_node: continue @@ -498,7 +498,6 @@ def special_nodes(self): (0, 3) sage: FundamentalGroupOfExtendedAffineWeylGroup(['A',2,1], general_linear=True).special_nodes() Integer Ring - """ return self._special_nodes @@ -514,7 +513,7 @@ def group_generators(self): EXAMPLES:: sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup - sage: FundamentalGroupOfExtendedAffineWeylGroup(['E',6,1],prefix="f").group_generators() + sage: FundamentalGroupOfExtendedAffineWeylGroup(['E',6,1],prefix='f').group_generators() Finite family {0: f[0], 1: f[1], 6: f[6]} """ return Family(self.special_nodes(), self) @@ -526,7 +525,7 @@ def __iter__(self): EXAMPLES:: sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup - sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['E',6,1],prefix="f") + sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['E',6,1],prefix='f') sage: [x for x in F] # indirect doctest [f[0], f[1], f[6]] """ @@ -540,7 +539,7 @@ def an_element(self): EXAMPLES:: sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup - sage: FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1],prefix="f").an_element() + sage: FundamentalGroupOfExtendedAffineWeylGroup(['A',4,1],prefix='f').an_element() f[4] """ return self.last() @@ -555,7 +554,6 @@ def index_set(self): sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup sage: FundamentalGroupOfExtendedAffineWeylGroup(['A',2,1]).index_set() (0, 1, 2) - """ return self.cartan_type().index_set() diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py index e9136f2f790..fd40907d33e 100644 --- a/src/sage/combinat/root_system/hecke_algebra_representation.py +++ b/src/sage/combinat/root_system/hecke_algebra_representation.py @@ -23,7 +23,7 @@ class HeckeAlgebraRepresentation(WithEqualityById, SageObject): r""" - A representation of an (affine) Hecke algebra given by the action of the `T` generators + A representation of an (affine) Hecke algebra given by the action of the `T` generators. Let `F_i` be a family of operators implementing an action of the operators `(T_i)_{i\in I}` of the Hecke algebra on some vector @@ -42,9 +42,9 @@ class HeckeAlgebraRepresentation(WithEqualityById, SageObject): - ``domain`` -- a vector space - ``f`` -- a function ``f(l,i)`` taking a basis element `l` of ``domain`` and an index `i`, and returning `F_i` - - ``cartan_type`` -- The Cartan type of the Hecke algebra - - ``q1``, ``q2`` -- The eigenvalues of the generators `T` of the Hecke algebra - - ``side`` -- "left" or "right" (default: "right") + - ``cartan_type`` -- the Cartan type of the Hecke algebra + - ``q1``, ``q2`` -- the eigenvalues of the generators `T` of the Hecke algebra + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) whether this is a left or right representation EXAMPLES:: @@ -75,7 +75,7 @@ class HeckeAlgebraRepresentation(WithEqualityById, SageObject): sage: from sage.combinat.root_system.hecke_algebra_representation import HeckeAlgebraRepresentation sage: W = SymmetricGroup(3) sage: domain = W.algebra(QQ) - sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side="right")) + sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side='right')) sage: r = HeckeAlgebraRepresentation(domain, action, CartanType(["A",2]), 1, -1) sage: hash(r) # random 3 @@ -85,14 +85,14 @@ class HeckeAlgebraRepresentation(WithEqualityById, SageObject): - [HST2008]_ """ - def __init__(self, domain, on_basis, cartan_type, q1, q2, q=ZZ.one(), side="right"): + def __init__(self, domain, on_basis, cartan_type, q1, q2, q=ZZ.one(), side='right'): r""" TESTS:: sage: from sage.combinat.root_system.hecke_algebra_representation import HeckeAlgebraRepresentation sage: W = SymmetricGroup(3) sage: domain = W.algebra(QQ) - sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side="right")) + sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side='right')) sage: HeckeAlgebraRepresentation(domain, action, CartanType(["A",2]), 1, -1) A representation of the (1, -1)-Hecke algebra of type ['A', 2] on Symmetric group algebra of order 3 over Rational Field """ @@ -149,7 +149,7 @@ def cartan_type(self): sage: from sage.combinat.root_system.hecke_algebra_representation import HeckeAlgebraRepresentation sage: KW = SymmetricGroup(3).algebra(QQ) - sage: action = lambda x,i: KW.monomial(x.apply_simple_reflection(i, side="right")) + sage: action = lambda x,i: KW.monomial(x.apply_simple_reflection(i, side='right')) sage: H = HeckeAlgebraRepresentation(KW, action, CartanType(["A",2]), 1, -1) sage: H.cartan_type() ['A', 2] @@ -198,7 +198,7 @@ def Ti_on_basis(self, x, i): def Ti_inverse_on_basis(self, x, i): r""" - The `T_i^{-1}` operators, on basis elements + The `T_i^{-1}` operators, on basis elements. INPUT: @@ -224,22 +224,23 @@ def Ti_inverse_on_basis(self, x, i): @cached_method def on_basis(self, x, word, signs=None, scalar=None): r""" - Action of product of `T_i` and `T_i^{-1}` on ``x``. + Action of product of `T_i` and `T_i^{-1}` on `x`. INPUT: - ``x`` -- the index of a basis element - ``word`` -- word of indices of generators - - ``signs`` -- (default: None) sequence of signs of same length as ``word``; determines - which operators are supposed to be taken as inverses. - - ``scalar`` -- (default: None) scalar to multiply the answer by + - ``signs`` -- (default: ``None``) sequence of signs of same length as + ``word``; determines which operators are supposed to be taken as + inverses. + - ``scalar`` -- (default: ``None``) scalar to multiply the answer by EXAMPLES:: sage: from sage.combinat.root_system.hecke_algebra_representation import HeckeAlgebraRepresentation sage: W = SymmetricGroup(3) sage: domain = W.algebra(QQ) - sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side="right")) + sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side='right')) sage: rho = HeckeAlgebraRepresentation(domain, action, CartanType(["A",2]), 1, -1) sage: rho.on_basis(W.one(), (1,2,1)) @@ -322,19 +323,17 @@ def Tw(self, word, signs=None, scalar=None): INPUT: - - ``word`` -- a word `i_1,\dots,i_k` for some element `w` of the Weyl group. - See :meth:`straighten_word` for how this word can be specified. + - ``word`` -- a word `i_1,\dots,i_k` for some element `w` of the Weyl group + See :meth:`straighten_word` for how this word can be specified - - ``signs`` -- a list `\epsilon_1,\dots,\epsilon_k` of the + - ``signs`` -- list `\epsilon_1,\dots,\epsilon_k` of the same length as ``word`` with `\epsilon_i =\pm 1` or ``None`` for `1,\dots,1` (default: ``None``) - ``scalar`` -- an element `c` of the base ring or ``None`` for `1` (default: ``None``) - OUTPUT: - - a module morphism implementing + OUTPUT: a module morphism implementing .. MATH:: @@ -443,7 +442,7 @@ def Tw_inverse(self, word): def _test_relations(self, **options): r""" - Test that this family of operators satisfies the Iwahori Hecke relations + Test that this family of operators satisfies the Iwahori Hecke relations. EXAMPLES:: @@ -682,7 +681,7 @@ def Y(self, base_ring=ZZ): def _test_Y(self, **options): r""" - Test the `T_w^{-1}` operators + Test the `T_w^{-1}` operators. EXAMPLES:: @@ -822,13 +821,13 @@ def __init__(self, T, T_Y=None, normalized=True): INPUT: - ``T`` -- a family `(T_i)_{i\in I}` implementing the action of - the generators of an affine Hecke algebra on ``self``. + the generators of an affine Hecke algebra on ``self`` - ``T_Y`` -- a family `(T^Y_i)_{i\in I}` implementing the action of the generators of an affine Hecke algebra on ``self``. By default, this is ``T``. - - ``normalized`` -- boolean (default: ``True``) whether the + - ``normalized`` -- boolean (default: ``True``); whether the eigenvector `E_\mu` is normalized so that `\mu` has coefficient `1`. diff --git a/src/sage/combinat/root_system/integrable_representations.py b/src/sage/combinat/root_system/integrable_representations.py index a1cb764e19a..0cda82af318 100644 --- a/src/sage/combinat/root_system/integrable_representations.py +++ b/src/sage/combinat/root_system/integrable_representations.py @@ -228,7 +228,7 @@ def __init__(self, Lam): def highest_weight(self): """ - Returns the highest weight of ``self``. + Return the highest weight of ``self``. EXAMPLES:: @@ -466,7 +466,7 @@ def to_weight(self, n): INPUT: - - ``n`` -- a tuple representing a weight + - ``n`` -- tuple representing a weight EXAMPLES:: @@ -821,7 +821,7 @@ def m(self, n): INPUT: - - ``n`` -- a tuple representing a weight `\mu`. + - ``n`` -- tuple representing a weight `\mu` EXAMPLES:: @@ -864,7 +864,7 @@ def mult(self, mu): sage: L = RootSystem("B3~").weight_lattice(extended=True) sage: Lambda = L.fundamental_weights() sage: delta = L.null_root() - sage: W = L.weyl_group(prefix="s") + sage: W = L.weyl_group(prefix='s') sage: [s0,s1,s2,s3] = W.simple_reflections() sage: V = IntegrableRepresentation(Lambda[0]) sage: V.mult(Lambda[2] - 2*delta) @@ -1031,8 +1031,8 @@ def modular_characteristic(self, mu=None): OPTIONAL: - - ``mu`` -- a weight; or alternatively: - - ``n`` -- a tuple representing a weight `\mu`. + - ``mu`` -- a weight, or alternatively, + - ``n`` -- tuple representing a weight `\mu` If no optional parameter is specified, this returns `m_\Lambda`. If ``mu`` is specified, it returns `m_{\Lambda,\mu}`. You may @@ -1046,7 +1046,7 @@ def modular_characteristic(self, mu=None): sage: [V.modular_characteristic(x) for x in V.dominant_maximal_weights()] [11/56, -1/280, 111/280] """ - if type(mu) is tuple: + if isinstance(mu, tuple): n = mu else: n = self.from_weight(mu) @@ -1082,7 +1082,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): - ``i`` -- (default: 0) an element of the index set - ``weyl_character_ring`` -- a WeylCharacterRing - - ``sequence`` -- a dictionary + - ``sequence`` -- dictionary - ``depth`` -- (default: 5) an upper bound for `k` determining how many terms to give @@ -1126,7 +1126,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): Thus we have a branching to `\mathfrak{sl}(2) \times \mathfrak{sl}(2) \times \mathfrak{sl}(2)`:: - sage: A1xA1xA1 = WeylCharacterRing("A1xA1xA1",style="coroots") # needs sage.libs.gap + sage: A1xA1xA1 = WeylCharacterRing("A1xA1xA1",style='coroots') # needs sage.libs.gap sage: V.branch(i=2,weyl_character_ring=A1xA1xA1) # needs sage.libs.gap [A1xA1xA1(1,0,0), A1xA1xA1(0,1,2), @@ -1147,7 +1147,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): O---O---O=>=O---O 0 1 2 3 4 F4~ - sage: A1xC3=WeylCharacterRing("A1xC3",style="coroots") + sage: A1xC3=WeylCharacterRing("A1xC3",style='coroots') sage: A1xC3.dynkin_diagram() O 1 @@ -1176,13 +1176,12 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): [1, 3, 4, 7, 13, 19, 29, 43, 62, 90, 126, 174, 239, 325, 435, 580] sage: oeis(r) # optional -- internet 0: A029552: Expansion of phi(x) / f(-x) in powers of x where phi(), f() are Ramanujan theta functions. - """ if i is None: i = self._cartan_type.special_node() if i == self._cartan_type.special_node() or self._cartan_type.type() == 'A': if weyl_character_ring is None: - weyl_character_ring = WeylCharacterRing(self._cartan_type.classical(), style="coroots") + weyl_character_ring = WeylCharacterRing(self._cartan_type.classical(), style='coroots') if weyl_character_ring.cartan_type() != self._cartan_type.classical(): raise ValueError("Cartan type of WeylCharacterRing must be %s" % self.cartan_type().classical()) elif weyl_character_ring is None: diff --git a/src/sage/combinat/root_system/meson.build b/src/sage/combinat/root_system/meson.build new file mode 100644 index 00000000000..a8827403c7e --- /dev/null +++ b/src/sage/combinat/root_system/meson.build @@ -0,0 +1,76 @@ +py.install_sources( + 'all.py', + 'ambient_space.py', + 'associahedron.py', + 'braid_move_calculator.py', + 'branching_rules.py', + 'cartan_matrix.py', + 'cartan_type.py', + 'coxeter_group.py', + 'coxeter_matrix.py', + 'coxeter_type.py', + 'dynkin_diagram.py', + 'extended_affine_weyl_group.py', + 'fundamental_group.py', + 'hecke_algebra_representation.py', + 'integrable_representations.py', + 'non_symmetric_macdonald_polynomials.py', + 'pieri_factors.py', + 'plot.py', + 'reflection_group_complex.py', + 'reflection_group_element.pxd', + 'reflection_group_real.py', + 'root_lattice_realization_algebras.py', + 'root_lattice_realizations.py', + 'root_space.py', + 'root_system.py', + 'type_A.py', + 'type_A_affine.py', + 'type_A_infinity.py', + 'type_B.py', + 'type_BC_affine.py', + 'type_B_affine.py', + 'type_C.py', + 'type_C_affine.py', + 'type_D.py', + 'type_D_affine.py', + 'type_E.py', + 'type_E_affine.py', + 'type_F.py', + 'type_F_affine.py', + 'type_G.py', + 'type_G_affine.py', + 'type_H.py', + 'type_I.py', + 'type_Q.py', + 'type_affine.py', + 'type_dual.py', + 'type_folded.py', + 'type_marked.py', + 'type_reducible.py', + 'type_relabel.py', + 'type_super_A.py', + 'weight_lattice_realizations.py', + 'weight_space.py', + 'weyl_characters.py', + 'weyl_group.py', + subdir: 'sage/combinat/root_system', +) + +extension_data = { + 'braid_orbit' : files('braid_orbit.pyx'), + 'reflection_group_c' : files('reflection_group_c.pyx'), + 'reflection_group_element' : files('reflection_group_element.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/root_system', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index 69ed9c8f8af..90482002c92 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -32,15 +32,16 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): r""" - Nonsymmetric Macdonald polynomials + Nonsymmetric Macdonald polynomials. INPUT: - ``KL`` -- an affine Cartan type or the group algebra of a realization of the affine weight lattice - - ``q``, ``q1``, ``q2`` -- parameters in the base ring of the group algebra (default: ``q``, ``q1``, ``q2``) - - ``normalized`` -- a boolean (default: ``True``) - whether to normalize the result to have leading coefficient 1 + - ``q``, ``q1``, ``q2`` -- parameters in the base ring of the group algebra + (default: ``q``, ``q1``, ``q2``) + - ``normalized`` -- boolean (default: ``True``); whether to normalize the + result to have leading coefficient 1 This implementation covers all reduced affine root systems. The polynomials are constructed recursively by the application @@ -943,7 +944,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): Checking T0check:: - sage: T0check_on_basis = KL.T0_check_on_basis(q1,q2, convention="dominant") + sage: T0check_on_basis = KL.T0_check_on_basis(q1,q2, convention='dominant') sage: T0check_on_basis.phi # note: this is in fact a0 phi (2, 0) sage: T0check_on_basis.v # what to match it with? @@ -1284,7 +1285,6 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: for x in [0*epsilon[0], -epsilon[0], -epsilon[1], epsilon[0], epsilon[1]]: ....: x = KL.monomial(x) ....: assert q^2 * Y0(Y1(Y1(Y2(Y2(start))))) == start - """ @staticmethod @@ -1314,14 +1314,14 @@ def __classcall__(cls, KL, q='q', q1='q1', q2='q2', normalized=True): def __init__(self, KL, q, q1, q2, normalized): r""" - Initializes the nonsymmetric Macdonald polynomial class. + Initialize the nonsymmetric Macdonald polynomial class. INPUT: - ``KL`` -- algebra over weight space - ``q``, ``q1``, ``q2`` -- parameters - - ``normalized`` -- a boolean (default: ``True``) - whether to normalize the result to have leading coefficient 1 + - ``normalized`` -- boolean (default: ``True``); whether to normalize + the result to have leading coefficient 1 EXAMPLES:: @@ -1349,8 +1349,8 @@ def __init__(self, KL, q, q1, q2, normalized): self._q1 = q1 self._q2 = q2 assert self.L_prime().classical() is self.L().classical() - T = KL.twisted_demazure_lusztig_operators(q1, q2, convention="dominant") - T_Y = KL.demazure_lusztig_operators_on_classical(q, q1, q2, convention="dominant") + T = KL.twisted_demazure_lusztig_operators(q1, q2, convention='dominant') + T_Y = KL.demazure_lusztig_operators_on_classical(q, q1, q2, convention='dominant') CherednikOperatorsEigenvectors.__init__(self, T, T_Y, normalized=normalized) def _repr_(self): @@ -1499,7 +1499,6 @@ def KL0(self): sage: NonSymmetricMacdonaldPolynomials("B2~*").KL0() Algebra of the Ambient space of the Root system of type ['C', 2] over Fraction Field of Multivariate Polynomial Ring in q, q1, q2 over Rational Field - """ return self._KL.classical() @@ -1526,7 +1525,6 @@ def Q_to_Qcheck(self): alphacheck[1] + 2*alphacheck[2] sage: _.parent() Coroot lattice of the Root system of type ['C', 2, 1] - """ #assert self.cartan_type().is_untwisted_affine() Qcheck = self._T_Y.Y().keys() @@ -1726,7 +1724,7 @@ def eigenvalue_experimental(self, mu, l): INPUT: - ``mu`` -- the index `\mu` of an eigenvector - - `l` -- an index `\lambda^\vee` of some `Y` + - ``l`` -- an index `\lambda^\vee` of some `Y` .. NOTE:: @@ -1918,7 +1916,6 @@ def symmetric_macdonald_polynomial(self, mu): sage: om = E.L0().fundamental_weights() sage: E.symmetric_macdonald_polynomial(2*om[1]) ((3*q^6*v^22+3*q^5*v^22-3*q^6*v^20+q^4*v^22-4*q^5*v^20+q^4*v^18-q^5*v^16+q^3*v^18-2*q^4*v^16+q^5*v^14-q^3*v^16+q^4*v^14-4*q^4*v^12+q^2*v^14+q^5*v^10-8*q^3*v^12+4*q^4*v^10-4*q^2*v^12+8*q^3*v^10-q*v^12-q^4*v^8+4*q^2*v^10-q^2*v^8+q^3*v^6-q*v^8+2*q^2*v^6-q^3*v^4+q*v^6-q^2*v^4+4*q*v^2-q^2+3*v^2-3*q-3)/(q^6*v^22-q^5*v^20-q^4*v^12-q^3*v^12+q^3*v^10+q^2*v^10+q*v^2-1))*B[(0, 0, 0)] + ((q*v^2+v^2-q-1)/(q*v^2-1))*B[(-2, 1, 1)] + B[(-2, 2, 0)] + B[(-2, 0, 2)] + ((-q*v^2-v^2+q+1)/(-q*v^2+1))*B[(-1, -1, 2)] + ((2*q^4*v^12+2*q^3*v^12-2*q^4*v^10-2*q^3*v^10+q^2*v^8-q^3*v^6+q*v^8-2*q^2*v^6+q^3*v^4-q*v^6+q^2*v^4-2*q*v^2-2*v^2+2*q+2)/(q^4*v^12-q^3*v^10-q*v^2+1))*B[(-1, 1, 0)] + ((-q*v^2-v^2+q+1)/(-q*v^2+1))*B[(-1, 2, -1)] + ((2*q^4*v^12+2*q^3*v^12-2*q^4*v^10-2*q^3*v^10+q^2*v^8-q^3*v^6+q*v^8-2*q^2*v^6+q^3*v^4-q*v^6+q^2*v^4-2*q*v^2-2*v^2+2*q+2)/(q^4*v^12-q^3*v^10-q*v^2+1))*B[(-1, 0, 1)] + ((-q*v^2-v^2+q+1)/(-q*v^2+1))*B[(1, -2, 1)] + ((-2*q^4*v^12-2*q^3*v^12+2*q^4*v^10+2*q^3*v^10-q^2*v^8+q^3*v^6-q*v^8+2*q^2*v^6-q^3*v^4+q*v^6-q^2*v^4+2*q*v^2+2*v^2-2*q-2)/(-q^4*v^12+q^3*v^10+q*v^2-1))*B[(1, -1, 0)] + ((-q*v^2-v^2+q+1)/(-q*v^2+1))*B[(1, 1, -2)] + ((-2*q^4*v^12-2*q^3*v^12+2*q^4*v^10+2*q^3*v^10-q^2*v^8+q^3*v^6-q*v^8+2*q^2*v^6-q^3*v^4+q*v^6-q^2*v^4+2*q*v^2+2*v^2-2*q-2)/(-q^4*v^12+q^3*v^10+q*v^2-1))*B[(1, 0, -1)] + B[(2, -2, 0)] + ((q*v^2+v^2-q-1)/(q*v^2-1))*B[(2, -1, -1)] + B[(2, 0, -2)] + B[(0, -2, 2)] + ((-2*q^4*v^12-2*q^3*v^12+2*q^4*v^10+2*q^3*v^10-q^2*v^8+q^3*v^6-q*v^8+2*q^2*v^6-q^3*v^4+q*v^6-q^2*v^4+2*q*v^2+2*v^2-2*q-2)/(-q^4*v^12+q^3*v^10+q*v^2-1))*B[(0, -1, 1)] + ((2*q^4*v^12+2*q^3*v^12-2*q^4*v^10-2*q^3*v^10+q^2*v^8-q^3*v^6+q*v^8-2*q^2*v^6+q^3*v^4-q*v^6+q^2*v^4-2*q*v^2-2*v^2+2*q+2)/(q^4*v^12-q^3*v^10-q*v^2+1))*B[(0, 1, -1)] + B[(0, 2, -2)] - """ if self.cartan_type().classical() != mu.parent().cartan_type() or not mu.is_dominant(): raise ValueError("%s must be a dominant weight for the classical subrootsystem of %s" % (mu, self.cartan_type())) diff --git a/src/sage/combinat/root_system/pieri_factors.py b/src/sage/combinat/root_system/pieri_factors.py index 28b26d8bf6f..36dc4a332f2 100644 --- a/src/sage/combinat/root_system/pieri_factors.py +++ b/src/sage/combinat/root_system/pieri_factors.py @@ -551,9 +551,9 @@ def __init__(self, W, min_length, max_length, min_support, max_support): r""" INPUT: - - ``W`` -- a Weyl group of affine type `A` - - ``min_length``, ``max_length`` -- non negative integers - - ``min_support``, ``max_support`` -- subsets of the index set of `W` + - ``W`` -- a Weyl group of affine type `A` + - ``min_length``, ``max_length`` -- nonnegative integers + - ``min_support``, ``max_support`` -- subsets of the index set of `W` EXAMPLES:: @@ -604,7 +604,7 @@ def subset(self, length): INPUT: - - ``length`` -- a non-negative integer + - ``length`` -- nonnegative integer EXAMPLES:: @@ -652,7 +652,6 @@ def _test_maximal_elements(self, **options): sage: W.pieri_factors()._test_maximal_elements(verbose = True) sage: W.pieri_factors(min_length = 1)._test_maximal_elements(verbose = True) Strict subset of the Pieri factors; skipping test - """ tester = self._tester(**options) index_set = self.W.index_set() @@ -731,7 +730,6 @@ def __getitem__(self, support): [1, 0, 5, 4, 3] sage: W.pieri_factors()[[0,1,2,3,4]].reduced_word() [4, 3, 2, 1, 0] - """ index_set = sorted(self.W.index_set()) support = sorted(support) @@ -892,7 +890,7 @@ def stanley_symm_poly_weight(self, w): # The algorithm="delete" is a workaround when the set of # vertices is empty, in which case subgraph tries another # method which turns out to currently fail with Dynkin diagrams - return DiGraph(DynkinDiagram(w.parent().cartan_type())).subgraph(set(w.reduced_word()), algorithm="delete").connected_components_number() + return DiGraph(DynkinDiagram(w.parent().cartan_type())).subgraph(set(w.reduced_word()), algorithm='delete').connected_components_number() class PieriFactors_type_B_affine(PieriFactors_affine_type): @@ -1001,7 +999,7 @@ def stanley_symm_poly_weight(self, w): support_complement = set(ct.index_set()).difference(support).difference(set([0, 1])) else: support_complement = set(ct.index_set()).difference(support).difference(set([0])) - return DiGraph(DynkinDiagram(ct)).subgraph(support_complement, algorithm="delete").connected_components_number() - 1 + return DiGraph(DynkinDiagram(ct)).subgraph(support_complement, algorithm='delete').connected_components_number() - 1 class PieriFactors_type_D_affine(PieriFactors_affine_type): diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 483c510eb61..1ffa81daf78 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -73,14 +73,14 @@ `G_2`:: sage: L = RootSystem(["G",2]).ambient_space() - sage: L.plot(reflection_hyperplanes="all") + sage: L.plot(reflection_hyperplanes='all') Graphics object consisting of 21 graphics primitives .. PLOT:: :width: 300 px L = RootSystem(["G",2]).ambient_space() - sphinx_plot(L.plot(reflection_hyperplanes="all")) + sphinx_plot(L.plot(reflection_hyperplanes='all')) The group is now the dihedral group of order 12, generated by the two reflections `s_1` and `s_2`. The picture displays the hyperplanes for @@ -108,7 +108,7 @@ its corresponding reflection hyperplane:: sage: L = RootSystem(["A",2]).weight_space() - sage: L.plot(roots="all", reflection_hyperplanes="all").show(figsize=15) + sage: L.plot(roots='all', reflection_hyperplanes='all').show(figsize=15) .. NOTE:: @@ -120,7 +120,7 @@ :width: 300 px L = RootSystem(["A",2]).weight_space() - sphinx_plot(L.plot(roots="all", reflection_hyperplanes="all")) + sphinx_plot(L.plot(roots='all', reflection_hyperplanes='all')) One can further customize which roots to display, as in the following example showing the positive roots in the @@ -150,7 +150,7 @@ sage: L = RootSystem(["E",8]).ambient_space() sage: L.dimension() 8 - sage: L.plot(roots="all", reflection_hyperplanes=False, # long time + sage: L.plot(roots='all', reflection_hyperplanes=False, # long time ....: projection=lambda v: M*vector(v), labels=False) Graphics3d Object @@ -161,7 +161,7 @@ [0.180913155536, 0., 0.160212955043, 0.160212955043, 0., 0.0990170516545, 0.766360424875, 0.0990170516545], [0.338261212718, 0, 0, -0.338261212718, 0.672816364803, 0.171502564281, 0, -0.171502564281]]) L = RootSystem(["E",8]).ambient_space() - sphinx_plot(L.plot(roots="all", reflection_hyperplanes=False, projection=lambda v: M*vector(v), labels=False)) + sphinx_plot(L.plot(roots='all', reflection_hyperplanes=False, projection=lambda v: M*vector(v), labels=False)) The projection function should be linear or affine, and return a vector with rational coordinates. The rationale for the later @@ -292,14 +292,14 @@ `u = vs_i`; the color of that wall is given by `i`:: sage: L = RootSystem(["C",2,1]).ambient_space() - sage: L.plot(coroots="simple", alcove_labels=True) # long time + sage: L.plot(coroots='simple', alcove_labels=True) # long time Graphics object consisting of 216 graphics primitives .. PLOT:: :width: 300 px L = RootSystem(["C",2,1]).ambient_space() - sphinx_plot(L.plot(coroots="simple", alcove_labels=True)) + sphinx_plot(L.plot(coroots='simple', alcove_labels=True)) Even 2D pictures of the rank `1 + 1` cases can give some food for thought. Here, we draw the root lattice, with the positive roots of @@ -507,9 +507,9 @@ sage: plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,6]]) sage: w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2] sage: p = L.plot_alcoves(plot_options=plot_options) - sage: p += L.plot_alcove_walk(w1, color="green", + sage: p += L.plot_alcove_walk(w1, color='green', ....: plot_options=plot_options) - sage: p += L.plot_alcove_walk(w2, color="orange", + sage: p += L.plot_alcove_walk(w2, color='orange', ....: plot_options=plot_options) sage: p Graphics object consisting of ... graphics primitives @@ -522,15 +522,15 @@ plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,6]]) w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2] sphinx_plot(L.plot_alcoves(plot_options=plot_options) - + L.plot_alcove_walk(w1, color="green", plot_options=plot_options) - + L.plot_alcove_walk(w2, color="orange", plot_options=plot_options)) + + L.plot_alcove_walk(w1, color='green', plot_options=plot_options) + + L.plot_alcove_walk(w2, color='orange', plot_options=plot_options)) And another with some foldings:: sage: p += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], ....: foldings=[False, False, True, False, False, ....: False, True, False, True, False], - ....: color="purple") + ....: color='purple') sage: p.axes(False) sage: p.show(figsize=20) @@ -542,11 +542,11 @@ plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,6]]) w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2] p = L.plot_alcoves(plot_options=plot_options) - p += L.plot_alcove_walk(w1, color="green", plot_options=plot_options) - p += L.plot_alcove_walk(w2, color="orange", plot_options=plot_options) + p += L.plot_alcove_walk(w1, color='green', plot_options=plot_options) + p += L.plot_alcove_walk(w2, color='orange', plot_options=plot_options) p += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], foldings=[False, False, True, False, False, False, True, False, True, False], - color="purple") + color='purple') p.axes(False) sphinx_plot(p) @@ -561,7 +561,7 @@ sage: walk = L.reduced_word_of_translation(L(t)) sage: plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,5]]) sage: p = L.plot(plot_options=plot_options) - sage: p += L.plot_alcove_walk(walk, color="green", + sage: p += L.plot_alcove_walk(walk, color='green', ....: plot_options=plot_options) sage: p += plot_options.family_of_vectors({t: L(t)}) sage: plot_options.finalize(p) @@ -579,7 +579,7 @@ walk = L.reduced_word_of_translation(L(t)) plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,5]]) p = L.plot(plot_options=plot_options) # long time - p += L.plot_alcove_walk(walk, color="green", plot_options=plot_options) + p += L.plot_alcove_walk(walk, color='green', plot_options=plot_options) p += plot_options.family_of_vectors({t: L(t)}) plot_options.finalize(p) sphinx_plot(p) @@ -649,7 +649,7 @@ sage: L = RootSystem(["C",2,1]).ambient_space() sage: p = L.plot(bounding_box=[[-8,9],[-5,7]], # long time (10 s) - ....: coroots="simple") + ....: coroots='simple') sage: p # long time Graphics object consisting of ... graphics primitives @@ -657,7 +657,7 @@ :width: 300 px L = RootSystem(["C",2,1]).ambient_space() - sphinx_plot(L.plot(bounding_box=[[-8,9],[-5,7]], coroots="simple")) + sphinx_plot(L.plot(bounding_box=[[-8,9],[-5,7]], coroots='simple')) By default Sage's plot are bitmap pictures which would come out ugly if printed on paper. Instead, we recommend saving the picture in @@ -688,7 +688,7 @@ sage: rho = L.rho() sage: plot_options = L.plot_parse_options() sage: W = L.weyl_group() - sage: g = W.cayley_graph(side="right") + sage: g = W.cayley_graph(side='right') sage: positions = {w: plot_options.projection(w.action(rho)) for w in W} sage: p = L.plot_alcoves() sage: p += g.plot(pos=positions, vertex_size=0, @@ -704,7 +704,7 @@ rho = L.rho() plot_options = L.plot_parse_options() W = L.weyl_group() - g = W.cayley_graph(side="right") + g = W.cayley_graph(side='right') positions = {w: plot_options.projection(w.action(rho)) for w in W} p = L.plot_alcoves() p += g.plot(pos = positions, vertex_size=0, color_by_label=plot_options.color) @@ -719,7 +719,7 @@ sage: rho = L.rho() sage: plot_options = L.plot_parse_options() sage: W = L.weyl_group() - sage: g = W.cayley_graph(side="right") + sage: g = W.cayley_graph(side='right') sage: positions = {w: plot_options.projection(w.action(rho)) for w in W} sage: p = L.plot_roots() sage: p += g.plot3d(pos3d=positions, color_by_label=plot_options.color) @@ -733,7 +733,7 @@ rho = L.rho() plot_options = L.plot_parse_options() W = L.weyl_group() - g = W.cayley_graph(side="right") + g = W.cayley_graph(side='right') positions = {w: plot_options.projection(w.action(rho)) for w in W} sphinx_plot(L.plot_roots() + g.plot3d(pos3d=positions, color_by_label=plot_options.color)) @@ -973,12 +973,11 @@ def in_bounding_box(self, x): def text(self, label, position, rgbcolor=(0,0,0)): r""" - Return text widget with label ``label`` at position ``position`` + Return text widget with label ``label`` at position ``position``. INPUT: - - ``label`` -- a string, or a Sage object upon which latex will - be called + - ``label`` -- string or Sage object upon which latex will be called - ``position`` -- a position @@ -1124,9 +1123,7 @@ def projection(self, v): - ``x`` -- an element of the root lattice realization - OUTPUT: - - An immutable vector with integer or rational coefficients. + OUTPUT: an immutable vector with integer or rational coefficients EXAMPLES:: @@ -1170,7 +1167,6 @@ def intersection_at_level_1(self, x): sage: options = L.plot_parse_options(affine=False) sage: options.intersection_at_level_1(L.rho()) Lambda[0] + Lambda[1] + Lambda[2] - """ if self.level is not None: return x * self.level / x.level() @@ -1334,7 +1330,7 @@ def family_of_vectors(self, vectors): G += self.text(i, 1.05*head) return self.finalize(G) - def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe=False, + def cone(self, rays=[], lines=[], color='black', thickness=1, alpha=1, wireframe=False, label=None, draw_degenerate=True, as_polyhedron=False): r""" Return the cone generated by the given rays and lines. @@ -1344,28 +1340,26 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe - ``rays``, ``lines`` -- lists of elements of the root lattice realization (default: ``[]``) - - ``color`` -- a color (default: ``"black"``) + - ``color`` -- a color (default: ``'black'``) - ``alpha`` -- a number in the interval `[0, 1]` (default: `1`) the desired transparency - - ``label`` -- an object to be used as the label for this cone. + - ``label`` -- an object to be used as the label for this cone The label itself will be constructed by calling :func:`~sage.misc.latex.latex` or :func:`repr` on the object depending on the graphics backend. - - ``draw_degenerate`` -- a boolean (default: ``True``) + - ``draw_degenerate`` -- boolean (default: ``True``) whether to draw cones with a degenerate intersection with the bounding box - - ``as_polyhedron`` -- a boolean (default: ``False``) + - ``as_polyhedron`` -- boolean (default: ``False``) whether to return the result as a polyhedron, without clipping it to the bounding box, and without making a plot out of it (for testing purposes) - OUTPUT: - - A graphic object, a polyhedron, or ``0``. + OUTPUT: a graphic object, a polyhedron, or ``0`` EXAMPLES:: @@ -1598,7 +1592,6 @@ def barycentric_projection_matrix(n, angle=0): ....: m = barycentric_projection_matrix(n) ....: assert sum(m.columns()).is_zero() ....: assert matrix(QQ, n+1,n+1, lambda i,j: 1 if i==j else -1/n) == m.transpose()*m - """ from sage.matrix.constructor import matrix from sage.misc.functional import sqrt diff --git a/src/sage/combinat/root_system/reflection_group_c.pyx b/src/sage/combinat/root_system/reflection_group_c.pyx index dbfc76282f8..2f2c1b43aaf 100644 --- a/src/sage/combinat/root_system/reflection_group_c.pyx +++ b/src/sage/combinat/root_system/reflection_group_c.pyx @@ -43,7 +43,7 @@ cdef class Iterator(): sage: from sage.combinat.root_system.reflection_group_c import Iterator sage: W = ReflectionGroup(["B", 4]) # optional - gap3 sage: I = Iterator(W, W.number_of_reflections()) # optional - gap3 - sage: TestSuite(I).run(skip="_test_pickling") # optional - gap3 + sage: TestSuite(I).run(skip='_test_pickling') # optional - gap3 """ cdef tuple S = self.S cdef int n = len(S) @@ -62,7 +62,7 @@ cdef class Iterator(): noncom.append(list(range(n))) return noncom - def __init__(self, W, int N, str algorithm="depth", bint tracking_words=True, + def __init__(self, W, int N, str algorithm='depth', bint tracking_words=True, order=None): """ Initialize ``self``. @@ -72,7 +72,7 @@ cdef class Iterator(): sage: from sage.combinat.root_system.reflection_group_c import Iterator sage: W = ReflectionGroup(["B", 4]) # optional - gap3 sage: I = Iterator(W, W.number_of_reflections()) # optional - gap3 - sage: TestSuite(I).run(skip="_test_pickling") # optional - gap3 + sage: TestSuite(I).run(skip='_test_pickling') # optional - gap3 """ self.S = tuple(W.simple_reflections()) self.n = len(W._index_set) @@ -189,7 +189,7 @@ cdef class Iterator(): EXAMPLES:: sage: from sage.combinat.root_system.reflection_group_c import Iterator - sage: W = CoxeterGroup(['B',2], implementation="permutation") + sage: W = CoxeterGroup(['B',2], implementation='permutation') sage: I = Iterator(W, W.number_of_reflections()) sage: list(I.iter_depth()) [(), @@ -225,7 +225,7 @@ cdef class Iterator(): EXAMPLES:: sage: from sage.combinat.root_system.reflection_group_c import Iterator - sage: W = CoxeterGroup(['B',2], implementation="permutation") + sage: W = CoxeterGroup(['B',2], implementation='permutation') sage: I = Iterator(W, W.number_of_reflections()) sage: for w in I.iter_words_depth(): w._reduced_word [] @@ -265,7 +265,7 @@ cdef class Iterator(): EXAMPLES:: sage: from sage.combinat.root_system.reflection_group_c import Iterator - sage: W = CoxeterGroup(['B',2], implementation="permutation") + sage: W = CoxeterGroup(['B',2], implementation='permutation') sage: I = Iterator(W, W.number_of_reflections()) sage: list(I.iter_breadth()) [(), @@ -301,7 +301,7 @@ cdef class Iterator(): EXAMPLES:: sage: from sage.combinat.root_system.reflection_group_c import Iterator - sage: W = CoxeterGroup(['B',2], implementation="permutation") + sage: W = CoxeterGroup(['B',2], implementation='permutation') sage: I = Iterator(W, W.number_of_reflections()) sage: for w in I.iter_words_breadth(): w._reduced_word [] @@ -344,7 +344,7 @@ cdef class Iterator(): EXAMPLES:: sage: from sage.combinat.root_system.reflection_group_c import Iterator - sage: W = CoxeterGroup(['B',2], implementation="permutation") + sage: W = CoxeterGroup(['B',2], implementation='permutation') sage: I = Iterator(W, W.number_of_reflections()) sage: sorted(I.iter_parabolic()) [(), @@ -468,7 +468,7 @@ cpdef PermutationGroupElement reduce_in_coset(PermutationGroupElement w, tuple S EXAMPLES:: sage: from sage.combinat.root_system.reflection_group_c import reduce_in_coset - sage: W = CoxeterGroup(['B',3], implementation="permutation") + sage: W = CoxeterGroup(['B',3], implementation='permutation') sage: N = W.number_of_reflections() sage: s = W.simple_reflections() sage: w = s[2] * s[1] * s[3] @@ -545,7 +545,7 @@ def parabolic_iteration_application(W, f): EXAMPLES:: - sage: W = CoxeterGroup(['E',6], implementation="permutation") + sage: W = CoxeterGroup(['E',6], implementation='permutation') sage: from sage.combinat.root_system.reflection_group_c import parabolic_iteration_application sage: lst = [] sage: def f(x): @@ -564,7 +564,7 @@ def parabolic_iteration_application(W, f): cpdef list reduced_word_c(W, PermutationGroupElement w): r""" - Computes a reduced word for the element ``w`` in the + Compute a reduced word for the element ``w`` in the reflection group ``W`` in the positions ``range(n)``. EXAMPLES:: diff --git a/src/sage/combinat/root_system/reflection_group_complex.py b/src/sage/combinat/root_system/reflection_group_complex.py index d4c6c5b677b..32f57d5da95 100644 --- a/src/sage/combinat/root_system/reflection_group_complex.py +++ b/src/sage/combinat/root_system/reflection_group_complex.py @@ -553,7 +553,7 @@ def reflection_hyperplanes(self, as_linear_functionals=False, with_order=False): INPUT: - - ``as_linear_functionals`` -- (default:``False``) flag whether + - ``as_linear_functionals`` -- boolean (default: ``False``); whether to return the hyperplane or its linear functional in the basis dual to the given root basis @@ -626,7 +626,7 @@ def reflection_hyperplane(self, i, as_linear_functional=False, with_order=False) INPUT: - ``i`` -- an index in the index set - - ``as_linear_functionals`` -- (default:``False``) flag whether + - ``as_linear_functionals`` -- boolean (default: ``False``); whether to return the hyperplane or its linear functional in the basis dual to the given root basis @@ -855,7 +855,7 @@ def discriminant_in_invariant_ring(self, invariants=None): @cached_method def is_crystallographic(self): r""" - Return ``True`` if self is crystallographic. + Return ``True`` if ``self`` is crystallographic. This is, if the field of definition is the rational field. @@ -971,7 +971,7 @@ def conjugacy_classes_representatives(self): """ # This can be converted to usual GAP S = str(gap3('List(ConjugacyClasses(%s),Representative)' % self._gap_group._name)) - return sage_eval(_gap_return(S), {'self': self}) + return [self(w, check=False) for w in _gap_return(S)] def conjugacy_classes(self): r""" @@ -1122,9 +1122,7 @@ def reflection_eigenvalues_family(self): Return the reflection eigenvalues of ``self`` as a finite family indexed by the class representatives of ``self``. - OUTPUT: - - - list with entries `k/n` representing the eigenvalue `\zeta_n^k`. + OUTPUT: list with entries `k/n` representing the eigenvalue `\zeta_n^k` EXAMPLES:: @@ -1173,8 +1171,8 @@ def reflection_eigenvalues(self, w, is_class_representative=False): INPUT: - - ``is_class_representative`` -- boolean (default ``True``) whether to - compute instead on the conjugacy class representative. + - ``is_class_representative`` -- boolean (default: ``True``) whether to + compute instead on the conjugacy class representative .. SEEALSO:: :meth:`reflection_eigenvalues_family` @@ -1493,7 +1491,7 @@ def primitive_vector_field(self, invs=None): def apply_vector_field(self, f, vf=None): r""" - Returns a rational function obtained by applying the vector + Return a rational function obtained by applying the vector field ``vf`` to the rational function ``f``. If ``vf`` is not given, the primitive vector field is used. @@ -1790,7 +1788,7 @@ def set_reflection_representation(self,refl_repr=None): INPUT: - - ``refl_repr`` -- a dictionary representing the matrices of the + - ``refl_repr`` -- dictionary representing the matrices of the generators of ``self`` with keys given by the index set, or ``None`` to reset to the default reflection representation @@ -2002,7 +2000,7 @@ def reflection_length(self, in_unitary_group=False): INPUT: - - ``in_unitary_group`` -- (default: ``False``) if ``True``, + - ``in_unitary_group`` -- boolean (default: ``False``); if ``True``, the reflection length is computed in the unitary group which is the dimension of the move space of ``self`` @@ -2070,11 +2068,11 @@ def is_coxeter_element(self, which_primitive=1, is_class_representative=False): INPUT: - - ``which_primitive`` -- (default:``1``) for which power of + - ``which_primitive`` -- (default: ``1``) for which power of the first primitive ``h``-th root of unity to look as a reflection eigenvalue for a regular element - - ``is_class_representative`` -- boolean (default ``True``) whether + - ``is_class_representative`` -- boolean (default: ``True``); whether to compute instead on the conjugacy class representative .. SEEALSO:: @@ -2140,7 +2138,7 @@ def is_regular(self, h, is_class_representative=False): INPUT: - ``h`` -- the order of the eigenvalue - - ``is_class_representative`` -- boolean (default ``True``) whether + - ``is_class_representative`` -- boolean (default: ``True``); whether to compute instead on the conjugacy class representative EXAMPLES:: diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 3d81a84ff4b..fedda00cddd 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -21,6 +21,7 @@ AUTHORS: # (at your option) any later version. # https://www.gnu.org/licenses/ # *************************************************************************** +import re from sage.misc.lazy_attribute import lazy_attribute from sage.misc.misc_c import prod @@ -31,6 +32,8 @@ from sage.combinat.root_system.reflection_group_c import reduced_word_c, reduce_ from sage.matrix.constructor import Matrix from sage.matrix.special import identity_matrix +TUPLE = re.compile(r'(?:\([0-9,]*\))+') + cdef class ComplexReflectionGroupElement(PermutationGroupElement): """ @@ -102,7 +105,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): @lazy_attribute def _reduced_word(self): r""" - Computes a reduced word and stores it into ``self._reduced_word``. + Compute a reduced word and stores it into ``self._reduced_word``. TESTS:: @@ -181,12 +184,12 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): return ZZ(len(self.reduced_word())) # @cached_in_parent_method - def to_matrix(self, on_space="primal"): + def to_matrix(self, on_space='primal'): r""" Return ``self`` as a matrix acting on the underlying vector space. - - ``on_space`` -- optional (default: ``"primal"``) whether + - ``on_space`` -- (default: ``'primal'``) whether to act as the reflection representation on the given basis, or to act on the dual reflection representation on the dual basis @@ -194,10 +197,10 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): EXAMPLES:: sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: data = {w: [w.to_matrix(), w.to_matrix(on_space="dual")] for w in W} # optional - gap3 + sage: data = {w: [w.to_matrix(), w.to_matrix(on_space='dual')] for w in W} # optional - gap3 sage: for w in W.iteration_tracking_words(): # optional - gap3 ....: w.reduced_word() - ....: mats = [w.to_matrix(), w.to_matrix(on_space="dual")] + ....: mats = [w.to_matrix(), w.to_matrix(on_space='dual')] ....: mats ....: assert data[w] == mats [] @@ -318,7 +321,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): EXAMPLES:: sage: # needs sage.graphs - sage: W = WeylGroup(['A',2], prefix='s', implementation="permutation") + sage: W = WeylGroup(['A',2], prefix='s', implementation='permutation') sage: for w in W: ....: w.reduced_word() ....: w.canonical_matrix() @@ -348,7 +351,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): mat.set_immutable() return mat - cpdef action(self, vec, on_space="primal"): + cpdef action(self, vec, on_space='primal'): r""" Return the image of ``vec`` under the action of ``self``. @@ -356,7 +359,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): - ``vec`` -- vector in the basis given by the simple root - - ``on_space`` -- optional (default: ``"primal"``) whether + - ``on_space`` -- (default: ``'primal'``) whether to act as the reflection representation on the given basis, or to act on the dual reflection representation on the dual basis @@ -375,7 +378,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): cpdef _act_on_(self, vec, bint self_on_left): r""" - Defines the action of ``self`` as a linear transformation + Define the action of ``self`` as a linear transformation on the vector space, in the basis given by the simple roots. @@ -444,7 +447,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): sage: W = ReflectionGroup(['A',2]) # optional - gap3 sage: for w in W: # optional - gap3 ....: print("%s %s"%(w.reduced_word(), - ....: [w.action_on_root(beta,side="left") for beta in W.positive_roots()])) + ....: [w.action_on_root(beta,side='left') for beta in W.positive_roots()])) [] [(1, 0), (0, 1), (1, 1)] [2] [(1, 1), (0, -1), (1, 0)] [1] [(-1, 0), (1, 1), (0, 1)] @@ -539,7 +542,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): INPUT: - - ``is_class_representative`` -- (default: ``False``) whether + - ``is_class_representative`` -- boolean (default: ``False``); whether to first replace ``self`` by the representative of its conjugacy class @@ -696,7 +699,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): @lazy_attribute def _reduced_word(self): r""" - Computes a reduced word and stores it into ``self._reduced_word``. + Compute a reduced word and stores it into ``self._reduced_word``. The words are in ``range(n)`` and not in the index set. TESTS:: @@ -785,18 +788,18 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): # we also check == because 0-based indexing return self.perm[W._index_set_inverse[i]] >= W.number_of_reflections() - cpdef bint has_descent(self, i, side="left", positive=False) noexcept: + cpdef bint has_descent(self, i, side='left', positive=False) noexcept: r""" - Return whether ``i`` is a descent (or ascent) of ``self``. + Return whether `i` is a descent (or ascent) of ``self``. - This is done by testing whether ``i`` is mapped by ``self`` + This is done by testing whether `i` is mapped by ``self`` to a negative root. INPUT: - ``i`` -- an index of a simple reflection - - ``side`` (default: ``'right'``) -- ``'left'`` or ``'right'`` - - ``positive`` (default: ``False``) -- a boolean + - ``side`` -- (default: ``'right'``) ``'left'`` or ``'right'`` + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -823,7 +826,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): else: raise ValueError('side must be "left" or "right"') - def coset_representative(self, index_set, side="right"): + def coset_representative(self, index_set, side='right'): """ Return the unique shortest element of the Coxeter group `W` which is in the same left (resp. right) coset as @@ -837,7 +840,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): EXAMPLES:: sage: # needs sage.graphs - sage: W = CoxeterGroup(['A',4], implementation="permutation") + sage: W = CoxeterGroup(['A',4], implementation='permutation') sage: s = W.simple_reflections() sage: w = s[2] * s[1] * s[3] sage: w.coset_representative([]).reduced_word() @@ -868,17 +871,17 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): S = tuple(self._parent.simple_reflections()) N = self._parent.number_of_reflections() I = self._parent._index_set_inverse - return reduce_in_coset(self, S, [I[i] for i in index_set], N, side=="left") + return reduce_in_coset(self, S, [I[i] for i in index_set], N, side=='left') - def to_matrix(self, side="right", on_space="primal"): + def to_matrix(self, side='right', on_space='primal'): r""" Return ``self`` as a matrix acting on the underlying vector space. - - ``side`` -- optional (default: ``"right"``) whether the - action of ``self`` is on the ``"left"`` or on the ``"right"`` + - ``side`` -- (default: ``'right'``) whether the + action of ``self`` is on the ``'left'`` or on the ``'right'`` - - ``on_space`` -- optional (default: ``"primal"``) whether + - ``on_space`` -- (default: ``'primal'``) whether to act as the reflection representation on the given basis, or to act on the dual reflection representation on the dual basis @@ -888,7 +891,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: W = ReflectionGroup(['A',2]) # optional - gap3 sage: for w in W: # optional - gap3 ....: w.reduced_word() - ....: [w.to_matrix(), w.to_matrix(on_space="dual")] + ....: [w.to_matrix(), w.to_matrix(on_space='dual')] [] [ [1 0] [1 0] @@ -923,9 +926,9 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): TESTS:: sage: W = ReflectionGroup(['F',4]) # optional - gap3 - sage: all(w.to_matrix(side="left") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="right").transpose() for w in W) # optional - gap3 + sage: all(w.to_matrix(side='left') == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side='right').transpose() for w in W) # optional - gap3 True - sage: all(w.to_matrix(side="right") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="left").transpose() for w in W) # optional - gap3 + sage: all(w.to_matrix(side='right') == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side='left').transpose() for w in W) # optional - gap3 True """ W = self._parent @@ -959,7 +962,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): matrix = to_matrix - cpdef action(self, vec, side="right", on_space="primal"): + cpdef action(self, vec, side='right', on_space='primal'): r""" Return the image of ``vec`` under the action of ``self``. @@ -967,10 +970,10 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): - ``vec`` -- vector in the basis given by the simple root - - ``side`` -- optional (default: ``"right"``) whether the - action of ``self`` is on the ``"left"`` or on the ``"right"`` + - ``side`` -- (default: ``'right'``) whether the + action of ``self`` is on the ``'left'`` or on the ``'right'`` - - ``on_space`` -- optional (default: ``"primal"``) whether + - ``on_space`` -- (default: ``'primal'``) whether to act as the reflection representation on the given basis, or to act on the dual reflection representation on the dual basis @@ -980,7 +983,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: W = ReflectionGroup(['A',2]) # optional - gap3 sage: for w in W: # optional - gap3 ....: print("%s %s"%(w.reduced_word(), - ....: [w.action(weight,side="left") for weight in W.fundamental_weights()])) + ....: [w.action(weight,side='left') for weight in W.fundamental_weights()])) [] [(2/3, 1/3), (1/3, 2/3)] [2] [(2/3, 1/3), (1/3, -1/3)] [1] [(-1/3, 1/3), (1/3, 2/3)] @@ -991,10 +994,10 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): TESTS:: sage: W = ReflectionGroup(['B',3]) # optional - gap3 - sage: all(w.action(alpha,side="right") == w.action_on_root(alpha,side="right") # optional - gap3 + sage: all(w.action(alpha,side='right') == w.action_on_root(alpha,side='right') # optional - gap3 ....: for w in W for alpha in W.simple_roots()) True - sage: all(w.action(alpha,side="left") == w.action_on_root(alpha,side="left") #optional - gap3 + sage: all(w.action(alpha,side='left') == w.action_on_root(alpha,side='left') #optional - gap3 ....: for w in W for alpha in W.simple_roots()) True """ @@ -1051,10 +1054,10 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): (1, 1) -> (0, -1) """ if self_on_left: - return self.action(vec, side="left") - return self.action(vec, side="right") + return self.action(vec, side='left') + return self.action(vec, side='right') - cpdef action_on_root_indices(self, i, side="right"): + cpdef action_on_root_indices(self, i, side='right'): """ Return the action on the set of roots. @@ -1062,7 +1065,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): - ``i`` -- index of the root to act on - - ``side`` -- optional (default: ``"right"``) whether the + - ``side`` -- (default: ``'right'``) whether the action is on the left or on the right EXAMPLES:: @@ -1071,14 +1074,14 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: W = ReflectionGroup(['A',3]) sage: w = W.w0 sage: N = len(W.roots()) - sage: [w.action_on_root_indices(i,side="left") for i in range(N)] + sage: [w.action_on_root_indices(i,side='left') for i in range(N)] [8, 7, 6, 10, 9, 11, 2, 1, 0, 4, 3, 5] sage: # optional - gap3 sage: W = ReflectionGroup(['A',2], reflection_index_set=['A','B','C']) sage: w = W.w0 sage: N = len(W.roots()) - sage: [w.action_on_root_indices(i,side="left") for i in range(N)] + sage: [w.action_on_root_indices(i,side='left') for i in range(N)] [4, 3, 5, 1, 0, 2] """ cdef RealReflectionGroupElement w @@ -1090,7 +1093,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): raise ValueError('side must be "left" or "right"') return w.perm[i] - def action_on_root(self, root, side="right"): + def action_on_root(self, root, side='right'): r""" Return the root obtained by applying ``self`` to ``root``. @@ -1098,7 +1101,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): - ``root`` -- the root to act on - - ``side`` -- optional (default: ``"right"``) whether the + - ``side`` -- (default: ``'right'``) whether the action is on the left or on the right EXAMPLES:: @@ -1106,7 +1109,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: W = ReflectionGroup(['A',2]) # optional - gap3 sage: for w in W: # optional - gap3 ....: print("%s %s"%(w.reduced_word(), - ....: [w.action_on_root(beta,side="left") for beta in W.positive_roots()])) + ....: [w.action_on_root(beta,side='left') for beta in W.positive_roots()])) [] [(1, 0), (0, 1), (1, 1)] [2] [(1, 1), (0, -1), (1, 0)] [1] [(-1, 0), (1, 1), (0, 1)] @@ -1117,7 +1120,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: W = ReflectionGroup(['A',2]) # optional - gap3 sage: for w in W: # optional - gap3 ....: print("%s %s"%(w.reduced_word(), - ....: [w.action_on_root(beta,side="right") for beta in W.positive_roots()])) + ....: [w.action_on_root(beta,side='right') for beta in W.positive_roots()])) [] [(1, 0), (0, 1), (1, 1)] [2] [(1, 1), (0, -1), (1, 0)] [1] [(-1, 0), (1, 1), (0, 1)] @@ -1128,7 +1131,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): Phi = self._parent.roots() return Phi[self.action_on_root_indices(Phi.index(root), side=side)] - def inversion_set(self, side="right"): + def inversion_set(self, side='right'): r""" Return the inversion set of ``self``. @@ -1147,7 +1150,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): [2, 1] [(0, 1), (1, 1)] [1, 2, 1] [(1, 0), (0, 1), (1, 1)] - sage: W.from_reduced_word([1,2]).inversion_set(side="left") # optional - gap3 + sage: W.from_reduced_word([1,2]).inversion_set(side='left') # optional - gap3 [(0, 1), (1, 1)] """ N = self._parent.number_of_reflections() @@ -1246,8 +1249,7 @@ def _gap_return(S, coerce_obj='self'): sage: from sage.combinat.root_system.reflection_group_complex import _gap_return sage: _gap_return("[ (), (1,4)(2,3)(5,6), (1,6,2)(3,5,4) ]") # optional - gap3 - "[self('()',check=False),self('(1,4)(2,3)(5,6)',check=False),self('(1,6,2)(3,5,4)',check=False)]" + ['()', '(1,4)(2,3)(5,6)', '(1,6,2)(3,5,4)'] """ S = S.replace(' ', '').replace('\n', '') - S = S.replace(',(', '\',check=False),%s(\'(' % coerce_obj).replace('[', '[%s(\'' % coerce_obj).replace(']', '\',check=False)]') - return S + return TUPLE.findall(S) diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index c49c3e8bc6e..c9c06a74906 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -47,13 +47,13 @@ from sage.misc.cachefunc import cached_function, cached_method, cached_in_parent_method from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract +from sage.interfaces.gap3 import gap3 from sage.rings.integer_ring import ZZ from sage.combinat.root_system.reflection_group_complex import ComplexReflectionGroup, IrreducibleComplexReflectionGroup -from sage.misc.sage_eval import sage_eval from sage.combinat.root_system.reflection_group_element import RealReflectionGroupElement -def ReflectionGroup(*args,**kwds): +def ReflectionGroup(*args, **kwds): r""" Construct a finite (complex or real) reflection group as a Sage permutation group by fetching the permutation representation of the @@ -61,7 +61,7 @@ def ReflectionGroup(*args,**kwds): INPUT: - can be one or multiple of the following: + Can be one or multiple of the following: - a triple `(r, p, n)` with `p` divides `r`, which denotes the group `G(r, p, n)` @@ -295,13 +295,13 @@ def _repr_(self): type_str = type_str[:-3] return 'Reducible real reflection group of rank %s and type %s' % (self._rank, type_str) - def iteration(self, algorithm="breadth", tracking_words=True): + def iteration(self, algorithm='breadth', tracking_words=True): r""" Return an iterator going through all elements in ``self``. INPUT: - - ``algorithm`` (default: ``'breadth'``) -- must be one of + - ``algorithm`` -- (default: ``'breadth'``) must be one of the following: * ``'breadth'`` -- iterate over in a linear extension of the @@ -309,8 +309,8 @@ def iteration(self, algorithm="breadth", tracking_words=True): * ``'depth'`` -- iterate by a depth-first-search * ``'parabolic'`` -- iterate by using parabolic subgroups - - ``tracking_words`` (default: ``True``) -- whether or not to keep - track of the reduced words and store them in ``_reduced_word`` + - ``tracking_words`` -- boolean (default: ``True``); whether or not to + keep track of the reduced words and store them in ``_reduced_word`` .. NOTE:: @@ -373,7 +373,7 @@ def __iter__(self): (1,7)(3,5)(4,8) [0, 1, 0] (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] """ - return self.iteration(algorithm="breadth", tracking_words=True) + return self.iteration(algorithm='breadth', tracking_words=True) @cached_method def bipartite_index_set(self): @@ -695,7 +695,7 @@ def right_coset_representatives(self, J): from sage.combinat.root_system.reflection_group_element import _gap_return J_inv = [self._index_set_inverse[j] + 1 for j in J] S = str(gap3('ReducedRightCosetRepresentatives(%s,ReflectionSubgroup(%s,%s))' % (self._gap_group._name, self._gap_group._name, J_inv))) - return sage_eval(_gap_return(S), locals={'self': self}) + return [self(w, check=False) for w in _gap_return(S)] def simple_root_index(self, i): r""" @@ -727,7 +727,7 @@ def bruhat_cone(self, x, y, side='upper', backend='cdd'): - ``x`` -- an element in the group `W` - ``y`` -- an element in the group `W` - - ``side`` (default: ``'upper'``) -- must be one of the following: + - ``side`` -- (default: ``'upper'``) must be one of the following: * ``'upper'`` -- return the upper Bruhat cone of the interval [``x``, ``y``] * ``'lower'`` -- return the lower Bruhat cone of the interval [``x``, ``y``] @@ -820,8 +820,7 @@ def right_coset_representatives(self): if self.fix_space().is_subspace(T[i].fix_space())] S = str(gap3('ReducedRightCosetRepresentatives(%s,ReflectionSubgroup(%s,%s))' % (W._gap_group._name, W._gap_group._name, T_fix))) from sage.combinat.root_system.reflection_group_element import _gap_return - return sage_eval(_gap_return(S, coerce_obj='W'), - locals={'self': self, 'W': W}) + return [W(w, check=False) for w in _gap_return(S)] def left_coset_representatives(self): r""" diff --git a/src/sage/combinat/root_system/root_lattice_realization_algebras.py b/src/sage/combinat/root_system/root_lattice_realization_algebras.py index 266fb89eb32..970f134ba90 100644 --- a/src/sage/combinat/root_system/root_lattice_realization_algebras.py +++ b/src/sage/combinat/root_system/root_lattice_realization_algebras.py @@ -121,7 +121,7 @@ def from_polynomial(self, p): """ L = self.basis().keys() return self.sum_of_terms((L.from_vector(vector(t)), c) - for (t,c) in p.dict().items()) + for t, c in p.monomial_coefficients().items()) @cached_method def divided_difference_on_basis(self, weight, i): @@ -295,7 +295,7 @@ def demazure_operators(self): ... ValueError: the weight does not have an integral scalar product with the coroot """ - return HeckeAlgebraRepresentation(self, self.isobaric_divided_difference_on_basis, self.cartan_type(), 0, 1, side="left") + return HeckeAlgebraRepresentation(self, self.isobaric_divided_difference_on_basis, self.cartan_type(), 0, 1, side='left') def _test_demazure_operators(self, **options): """ @@ -325,7 +325,7 @@ def _test_demazure_operators(self, **options): except ImportError: pass - def demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention="antidominant"): + def demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention='antidominant'): r""" Return the result of applying the `i`-th Demazure-Lusztig operator on ``weight``. @@ -334,7 +334,7 @@ def demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention="anti - ``weight`` -- an element `\lambda` of the weight lattice - ``i`` -- an element of the index set - ``q1``, ``q2`` -- two elements of the ground ring - - ``convention`` -- ``"antidominant"``, ``"bar"``, or ``"dominant"`` (default: ``"antidominant"``) + - ``convention`` -- ``'antidominant'``, ``'bar'``, or ``'dominant'`` (default: ``'antidominant'``) See :meth:`demazure_lusztig_operators` for the details. @@ -362,11 +362,11 @@ def demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention="anti Or `1-\pi_i` for ``bar=True``:: - sage: KL.demazure_lusztig_operator_on_basis(L((2,2)), 1, 1, 0, convention="bar") + sage: KL.demazure_lusztig_operator_on_basis(L((2,2)), 1, 1, 0, convention='bar') 0 - sage: KL.demazure_lusztig_operator_on_basis(L((3,0)), 1, 1, 0, convention="bar") + sage: KL.demazure_lusztig_operator_on_basis(L((3,0)), 1, 1, 0, convention='bar') -B[(1, 2)] - B[(2, 1)] - B[(0, 3)] - sage: KL.demazure_lusztig_operator_on_basis(L((0,3)), 1, 1, 0, convention="bar") + sage: KL.demazure_lusztig_operator_on_basis(L((0,3)), 1, 1, 0, convention='bar') B[(1, 2)] + B[(2, 1)] + B[(0, 3)] At `q_1=1` and `q_2=-1` we recover the action of the simple reflection `s_i`:: @@ -389,14 +389,14 @@ def demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention="anti else: return result - def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): + def demazure_lusztig_operators(self, q1, q2, convention='antidominant'): r""" Return the Demazure-Lusztig operators acting on ``self``. INPUT: - ``q1``, ``q2`` -- two elements of the ground ring - - ``convention`` -- "antidominant", "bar", or "dominant" (default: "antidominant") + - ``convention`` -- "antidominant", "bar", or "dominant" (default: ``'antidominant'``) If `R` is the parent weight ring, the Demazure-Lusztig operator `T_i` is the linear map `R\rightarrow R` obtained @@ -448,9 +448,9 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: q1, q2 = K.gens() sage: KL = L.algebra(K) sage: T = KL.demazure_lusztig_operators(q1, q2) - sage: Tbar = KL.demazure_lusztig_operators(q1, q2, convention="bar") + sage: Tbar = KL.demazure_lusztig_operators(q1, q2, convention='bar') sage: Tdominant = KL.demazure_lusztig_operators(q1, q2, - ....: convention="dominant") + ....: convention='dominant') sage: x = KL.monomial(L((3,0))) sage: T[1](x) (q1+q2)*B[(1, 2)] + (q1+q2)*B[(2, 1)] + (q1+q2)*B[(3, 0)] + q1*B[(0, 3)] @@ -471,9 +471,9 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: q1, q2 = K.gens() sage: KL = L.algebra(K) sage: T = KL.demazure_lusztig_operators(q1, q2) - sage: Tbar = KL.demazure_lusztig_operators(q1, q2, convention="bar") + sage: Tbar = KL.demazure_lusztig_operators(q1, q2, convention='bar') sage: Tdominant = KL.demazure_lusztig_operators(q1, q2, - ....: convention="dominant") + ....: convention='dominant') sage: e = L.basis() sage: x = KL.monomial(3*e[0]) sage: T[1](x) @@ -515,7 +515,7 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): And the `\bar{T}` are basically the inverses of the `T` s:: sage: Tinv = KL.demazure_lusztig_operators(2/q1 + 1/q2, -1/q1, - ....: convention="bar") + ....: convention='bar') sage: [Tinv[1](T[1](x)) - x for x in KL.some_elements()] # needs sage.graphs [0, 0, 0, 0, 0, 0, 0] @@ -529,7 +529,7 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: Lambda = L.fundamental_weights() # needs sage.graphs sage: alphacheck = L0.simple_coroots() sage: KL = L.algebra(K) - sage: T = KL.demazure_lusztig_operators(q1, q2, convention="dominant") + sage: T = KL.demazure_lusztig_operators(q1, q2, convention='dominant') sage: Y = T.Y() sage: alphacheck = Y.keys().alpha() # alpha of coroot lattice is alphacheck sage: alphacheck @@ -566,13 +566,13 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: K = QQ['q1,q2'] sage: q1, q2 = K.gens() - sage: for cartan_type in CartanType.samples(crystallographic=True): # long time 12s + sage: for cartan_type in CartanType.samples(crystallographic=True): # long time (12s) ....: L = RootSystem(cartan_type).root_lattice() ....: KL = L.algebra(K) ....: T = KL.demazure_lusztig_operators(q1,q2) ....: T._test_relations() - sage: for cartan_type in CartanType.samples(crystallographic=True): # long time 12s + sage: for cartan_type in CartanType.samples(crystallographic=True): # long time (12s) ....: L = RootSystem(cartan_type).weight_lattice() ....: KL = L.algebra(K) ....: T = KL.demazure_lusztig_operators(q1,q2) @@ -584,7 +584,7 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): to specify explicitly the elements on which to run the tests:: - sage: for cartan_type in CartanType.samples(crystallographic=True): # long time 12s + sage: for cartan_type in CartanType.samples(crystallographic=True): # long time (12s) ....: L = RootSystem(cartan_type).ambient_space() ....: KL = L.algebra(K) ....: weight_lattice = RootSystem(cartan_type).weight_lattice(extended=L.is_extended()) @@ -594,9 +594,9 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): """ T_on_basis = functools.partial(self.demazure_lusztig_operator_on_basis, q1=q1, q2=q2, convention=convention) - return HeckeAlgebraRepresentation(self, T_on_basis, self.cartan_type(), q1, q2, side="left") + return HeckeAlgebraRepresentation(self, T_on_basis, self.cartan_type(), q1, q2, side='left') - def demazure_lusztig_operator_on_classical_on_basis(self, weight, i, q, q1, q2, convention="antidominant"): + def demazure_lusztig_operator_on_classical_on_basis(self, weight, i, q, q1, q2, convention='antidominant'): r""" Return the result of applying the `i`-th Demazure-Lusztig operator on the classical weight ``weight`` embedded at level 0. @@ -605,7 +605,7 @@ def demazure_lusztig_operator_on_classical_on_basis(self, weight, i, q, q1, q2, - ``weight`` -- a classical weight `\lambda` - ``i`` -- an element of the index set - ``q1``, ``q2`` -- two elements of the ground ring - - ``convention`` -- ``"antidominant"``, ``"bar"``, or ``"dominant"`` (default: ``"antidominant"``) + - ``convention`` -- ``'antidominant'``, ``'bar'``, or ``'dominant'`` (default: ``'antidominant'``) See :meth:`demazure_lusztig_operators` for the details. @@ -652,14 +652,14 @@ def demazure_lusztig_operator_on_classical_on_basis(self, weight, i, q, q1, q2, weight = L.embed_at_level(weight, 0) return self.q_project(self.demazure_lusztig_operator_on_basis(weight, i, q1, q2, convention=convention), q) - def demazure_lusztig_operators_on_classical(self, q, q1, q2, convention="antidominant"): + def demazure_lusztig_operators_on_classical(self, q, q1, q2, convention='antidominant'): r""" Return the Demazure-Lusztig operators acting at level 1 on ``self.classical()``. INPUT: - ``q``, ``q1``, ``q2`` -- three elements of the ground ring - - ``convention`` -- ``"antidominant"``, ``"bar"``, or ``"dominant"`` (default: ``"antidominant"``) + - ``convention`` -- ``'antidominant'``, ``'bar'``, or ``'dominant'`` (default: ``'antidominant'``) Let `KL` be the group algebra of an affine weight lattice realization `L`. The Demazure-Lusztig operators for `KL` @@ -722,7 +722,7 @@ def demazure_lusztig_operators_on_classical(self, q, q1, q2, convention="antidom sage: # needs sage.graphs sage: T = KL.demazure_lusztig_operators_on_classical(q, u, -1/u, - ....: convention="dominant") + ....: convention='dominant') sage: Y = T.Y() sage: alphacheck = Y.keys().simple_roots() sage: Ydelta = Y[Y.keys().null_root()] @@ -747,7 +747,6 @@ def demazure_lusztig_operators_on_classical(self, q, q1, q2, convention="antidom 1/(q*u)*B[Lambda[1]] sage: T0(KL0.monomial(-2*omega[1])) ((-u^2+1)/(q*u))*B[0] + 1/(q^2*u)*B[2*Lambda[1]] - """ # In type BC dual we used q^2 and q elsewhere # Not sure this is the right thing to do or just a workaround ... @@ -760,10 +759,10 @@ def demazure_lusztig_operators_on_classical(self, q, q1, q2, convention="antidom a0check = ct.acheck()[ct.special_node()] T_on_basis = functools.partial(self.demazure_lusztig_operator_on_classical_on_basis, q1=q1, q2=q2, q=q**a0check, convention=convention) - return HeckeAlgebraRepresentation(self.classical(), T_on_basis, self.cartan_type(), q1=q1, q2=q2, q=q, side="left") + return HeckeAlgebraRepresentation(self.classical(), T_on_basis, self.cartan_type(), q1=q1, q2=q2, q=q, side='left') @cached_method - def T0_check_on_basis(self, q1, q2, convention="antidominant"): + def T0_check_on_basis(self, q1, q2, convention='antidominant'): r""" Return the `T_0^\vee` operator acting on the basis. @@ -787,7 +786,7 @@ def T0_check_on_basis(self, q1, q2, convention="antidominant"): sage: L0 = L.classical() sage: KL = L.algebra(K) sage: some_weights = L.fundamental_weights() # needs sage.graphs - sage: f = KL.T0_check_on_basis(q1,q2, convention="dominant") # needs sage.graphs + sage: f = KL.T0_check_on_basis(q1,q2, convention='dominant') # needs sage.graphs sage: f(L0.zero()) # needs sage.graphs (q1+q2)*B[(0, 0)] + q1*B[(1, -1)] @@ -795,7 +794,7 @@ def T0_check_on_basis(self, q1, q2, convention="antidominant"): sage: L0 = L.classical() sage: KL = L.algebra(K) sage: some_weights = L0.fundamental_weights() - sage: f = KL.T0_check_on_basis(q1,q2, convention="dominant") # needs sage.graphs + sage: f = KL.T0_check_on_basis(q1,q2, convention='dominant') # needs sage.graphs sage: f(L0.zero()) # not checked # needs sage.graphs (q1+q2)*B[(0, 0, 0, 0)] + q1^3/q2^2*B[(1, 0, 0, -1)] @@ -818,14 +817,14 @@ def T0_check_on_basis(self, q1, q2, convention="antidominant"): sage: q2 = -1/u sage: KL = L.algebra(K) sage: KL0 = KL.classical() - sage: f = KL.T0_check_on_basis(q1,q2, convention="dominant") # needs sage.graphs - sage: T = KL.twisted_demazure_lusztig_operators(q1,q2, convention="dominant") + sage: f = KL.T0_check_on_basis(q1,q2, convention='dominant') # needs sage.graphs + sage: T = KL.twisted_demazure_lusztig_operators(q1,q2, convention='dominant') Direct calculation:: sage: T.Tw(0)(KL0.monomial(L0([0,0]))) # needs sage.graphs ((u^2-1)/u)*B[(0, 0)] + u^3*B[(1, 1)] - sage: KL.T0_check_on_basis(q1,q2, convention="dominant")(L0([0,0])) # needs sage.graphs + sage: KL.T0_check_on_basis(q1,q2, convention='dominant')(L0([0,0])) # needs sage.graphs ((u^2-1)/u)*B[(0, 0)] + u^3*B[(1, 1)] Step by step calculation, comparing by hand with Mark Shimozono:: @@ -970,7 +969,7 @@ def q_project(self, x, q): L0 = self.classical() return L0.linear_combination( (self.q_project_on_basis(l, q), c) for l,c in x ) - def twisted_demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention="antidominant"): + def twisted_demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, convention='antidominant'): r""" Return the twisted Demazure-Lusztig operator acting on the basis. @@ -979,7 +978,7 @@ def twisted_demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, conventi - ``weight`` -- an element `\lambda` of the weight lattice - ``i`` -- an element of the index set - ``q1``, ``q2`` -- two elements of the ground ring - - ``convention`` -- ``"antidominant"``, ``"bar"``, or ``"dominant"`` (default: ``"antidominant"``) + - ``convention`` -- ``'antidominant'``, ``'bar'``, or ``'dominant'`` (default: ``'antidominant'``) .. SEEALSO:: :meth:`twisted_demazure_lusztig_operators` @@ -992,16 +991,16 @@ def twisted_demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, conventi sage: KL = L.algebra(K) sage: Lambda = L.classical().fundamental_weights() sage: KL.twisted_demazure_lusztig_operator_on_basis( - ....: Lambda[1] + 2*Lambda[2], 1, q1, q2, convention="dominant") + ....: Lambda[1] + 2*Lambda[2], 1, q1, q2, convention='dominant') (-q2)*B[(2, 3, 0, 0)] sage: KL.twisted_demazure_lusztig_operator_on_basis( - ....: Lambda[1] + 2*Lambda[2], 2, q1, q2, convention="dominant") + ....: Lambda[1] + 2*Lambda[2], 2, q1, q2, convention='dominant') (-q1-q2)*B[(3, 1, 1, 0)] + (-q2)*B[(3, 0, 2, 0)] sage: KL.twisted_demazure_lusztig_operator_on_basis( - ....: Lambda[1] + 2*Lambda[2], 3, q1, q2, convention="dominant") + ....: Lambda[1] + 2*Lambda[2], 3, q1, q2, convention='dominant') q1*B[(3, 2, 0, 0)] sage: KL.twisted_demazure_lusztig_operator_on_basis( # needs sage.graphs - ....: Lambda[1]+2*Lambda[2], 0, q1, q2, convention="dominant") + ....: Lambda[1]+2*Lambda[2], 0, q1, q2, convention='dominant') ((q1*q2+q2^2)/q1)*B[(1, 2, 1, 1)] + ((q1*q2+q2^2)/q1)*B[(1, 2, 2, 0)] + q2^2/q1*B[(1, 2, 0, 2)] + ((q1^2+2*q1*q2+q2^2)/q1)*B[(2, 1, 1, 1)] + ((q1^2+2*q1*q2+q2^2)/q1)*B[(2, 1, 2, 0)] @@ -1017,19 +1016,19 @@ def twisted_demazure_lusztig_operator_on_basis(self, weight, i, q1, q2, conventi L = self.classical() return L.demazure_lusztig_operators(q1, q2, convention=convention)[i](L.monomial(weight)) - def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): + def twisted_demazure_lusztig_operators(self, q1, q2, convention='antidominant'): r""" Return the twisted Demazure-Lusztig operators acting on ``self``. INPUT: - ``q1``, ``q2`` -- two elements of the ground ring - - ``convention`` -- ``"antidominant"``, ``"bar"``, or ``"dominant"`` (default: ``"antidominant"``) + - ``convention`` -- ``'antidominant'``, ``'bar'``, or ``'dominant'`` (default: ``'antidominant'``) .. WARNING:: - the code is currently only tested for `q_1q_2=-1` - - only the ``"dominant"`` convention is functional for `i=0` + - only the ``'dominant'`` convention is functional for `i=0` For `T_1,\ldots,T_n`, these operators are the usual Demazure-Lusztig operators. On the other hand, the @@ -1040,7 +1039,7 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: K = QQ['q1,q2'].fraction_field() sage: q1, q2 = K.gens() sage: KL = L.algebra(K) - sage: T = KL.twisted_demazure_lusztig_operators(q1, q2, convention="dominant") + sage: T = KL.twisted_demazure_lusztig_operators(q1, q2, convention='dominant') sage: T._test_relations() TESTS: @@ -1052,7 +1051,7 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: K = QQ['q1,q2'].fraction_field() sage: q1,q2 = K.gens() sage: KL = L.algebra(K) - sage: T = KL.twisted_demazure_lusztig_operators(q1, q2, convention="dominant") + sage: T = KL.twisted_demazure_lusztig_operators(q1, q2, convention='dominant') sage: T._test_relations() sage: L0 = L.classical() sage: alpha = L0.simple_roots() @@ -1074,7 +1073,7 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: K = QQ['u'].fraction_field() sage: u = K.gen() sage: KL = L.algebra(K) - sage: T = KL.twisted_demazure_lusztig_operators(u, -~u, convention="dominant") + sage: T = KL.twisted_demazure_lusztig_operators(u, -~u, convention='dominant') sage: T._test_relations() sage: L0 = L.classical() sage: KL0 = L0.algebra(K) @@ -1103,11 +1102,11 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: K = QQ['q1,q2'].fraction_field() sage: q1, q2 = K.gens() - sage: for cartan_type in CartanType.samples(affine=True, crystallographic=True): # long time 12s + sage: for cartan_type in CartanType.samples(affine=True, crystallographic=True): # long time (12s) ....: if cartan_type.rank() > 4: continue ....: if cartan_type.type() == 'BC': continue ....: KL = RootSystem(cartan_type).weight_lattice().algebra(K) - ....: T = KL.twisted_demazure_lusztig_operators(q1, q2, convention="dominant") + ....: T = KL.twisted_demazure_lusztig_operators(q1, q2, convention='dominant') ....: T._test_relations() .. TODO:: @@ -1119,7 +1118,7 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: cartan_type = CartanType(["BC",1,2]) sage: KL = RootSystem(cartan_type).weight_lattice().algebra(K) - sage: T = KL.twisted_demazure_lusztig_operators(q1,q2, convention="dominant") + sage: T = KL.twisted_demazure_lusztig_operators(q1,q2, convention='dominant') sage: T._test_relations() # needs sage.graphs Traceback (most recent call last): ... tester.assertTrue(Ti(Ti(x,i,-q2),i,-q1).is_zero()) ... @@ -1135,10 +1134,10 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): sage: q2 = -1 sage: KL = L.algebra(K) sage: L0 = L.classical() - sage: T = KL.demazure_lusztig_operators(q1,q2, convention="dominant") + sage: T = KL.demazure_lusztig_operators(q1,q2, convention='dominant') sage: def T0(*l0): return KL.q_project(T[0].on_basis()(L.embed_at_level(L0(l0), 1)), q) sage: T0_check_on_basis = KL.T0_check_on_basis(q1, q2, # needs sage.graphs - ....: convention="dominant") + ....: convention='dominant') sage: def T0c(*l0): return T0_check_on_basis(L0(l0)) sage: T0(0,0,1) # not double checked # needs sage.graphs @@ -1152,13 +1151,13 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): T_on_basis, self.cartan_type().classical().dual().affine().dual(), q1, q2, - side="left") + side='left') class ElementMethods: def acted_upon(self, w): """ - Implements the action of ``w`` on ``self``. + Implement the action of ``w`` on ``self``. INPUT: diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 7539a5a85bb..2eddb3bbb38 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -33,7 +33,7 @@ class RootLatticeRealizations(Category_over_base_ring): r""" - The category of root lattice realizations over a given base ring + The category of root lattice realizations over a given base ring. A *root lattice realization* `L` over a base ring `R` is a free module (or vector space if `R` is a field) endowed with an embedding @@ -309,7 +309,7 @@ def some_elements(self): def _test_root_lattice_realization(self, **options): """ - Run sanity checks on this root lattice realization + Run sanity checks on this root lattice realization. - embedding of the root lattice - embedding of the root space over the same base ring @@ -394,7 +394,6 @@ def highest_root(self): sage: RootSystem(['E',6]).weight_space().highest_root() # needs sage.graphs Lambda[2] - """ if not self.root_system.is_finite(): raise ValueError("The root system of %s is not of finite Cartan type" % self) @@ -477,7 +476,7 @@ def simple_roots(self): if not hasattr(self,"_simple_roots"): self._simple_roots = Family(self.index_set(), self.simple_root) # Should we use rename to set a nice name for this family? - # self._simple_roots.rename("alpha") + # self._simple_roots.rename('alpha') # This break some doctests return self._simple_roots @@ -740,7 +739,6 @@ def nonparabolic_positive_roots(self, index_set=None): sage: sorted(L.nonparabolic_positive_roots(())) # needs sage.graphs [alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3], alpha[3]] - """ if not self.cartan_type().is_finite(): raise NotImplementedError("Only implemented for " @@ -766,7 +764,6 @@ def nonparabolic_positive_root_sum(self, index_set=None): 0 sage: Q.nonparabolic_positive_root_sum(()) # needs sage.graphs 3*alpha[1] + 4*alpha[2] + 3*alpha[3] - """ return self.sum(self.nonparabolic_positive_roots(index_set)) @@ -920,7 +917,6 @@ def positive_roots_by_height(self, increasing=True): Traceback (most recent call last): ... NotImplementedError: Only implemented for finite Cartan type - """ if not self.cartan_type().is_finite(): @@ -999,7 +995,6 @@ def positive_roots_nonparabolic(self, index_set=None): .. WARNING:: This returns an error if the Cartan type is not finite. - """ if not self.cartan_type().is_finite(): raise NotImplementedError("Only implemented for finite Cartan type") @@ -1036,7 +1031,6 @@ def positive_roots_nonparabolic_sum(self, index_set=None): .. WARNING:: This returns an error if the Cartan type is not finite. - """ if not self.cartan_type().is_finite(): @@ -1049,13 +1043,16 @@ def root_poset(self, restricted=False, facade=False): r""" Return the (restricted) root poset associated to ``self``. - The elements are given by the positive roots (resp. non-simple, positive roots), and - `\alpha \leq \beta` iff `\beta - \alpha` is a non-negative linear combination of simple roots. + The elements are given by the positive roots (resp. non-simple, + positive roots), and `\alpha \leq \beta` iff `\beta - \alpha` is a + nonnegative linear combination of simple roots. INPUT: - - ``restricted`` -- (default: ``False``) if ``True``, only non-simple roots are considered. - - ``facade`` -- (default: ``False``) passes facade option to the poset generator. + - ``restricted`` -- boolean (default: ``False``); if ``True``, only + non-simple roots are considered. + - ``facade`` -- boolean (default: ``False``); passes facade option + to the poset generator EXAMPLES:: @@ -1146,7 +1143,7 @@ def generalized_nonnesting_partition_lattice(self, m, facade=False): INPUT: - - `m` -- integer + - ``m`` -- integer .. SEEALSO:: @@ -1227,7 +1224,6 @@ def negative_roots(self): [-2*Lambda[1] + Lambda[2], -Lambda[1] - Lambda[2], Lambda[1] - 2*Lambda[2]] Algorithm: negate the positive roots - """ if not self.cartan_type().is_finite(): raise ValueError("%s is not a finite Cartan type" % self.cartan_type()) @@ -1245,7 +1241,6 @@ def coroot_lattice(self): sage: RootSystem(['A',2]).root_lattice().coroot_lattice() Coroot lattice of the Root system of type ['A', 2] - """ return self.root_system.coroot_lattice() @@ -1265,13 +1260,12 @@ def coroot_space(self, base_ring=QQ): sage: RootSystem(['A',2]).root_lattice().coroot_space(QQ['q']) Coroot space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 2] - """ return self.root_system.coroot_space(base_ring=base_ring) def simple_coroot(self, i): """ - Returns the `i^{th}` simple coroot. + Return the `i`-th simple coroot. EXAMPLES:: @@ -1283,19 +1277,18 @@ def simple_coroot(self, i): @cached_method def simple_coroots(self): r""" - Returns the family `( \alpha^\vee_i)_{i\in I}` of the simple coroots. + Return the family `(\alpha^\vee_i)_{i\in I}` of the simple coroots. EXAMPLES:: sage: alphacheck = RootSystem(['A',3]).root_lattice().simple_coroots() sage: [alphacheck[i] for i in [1, 2, 3]] [alphacheck[1], alphacheck[2], alphacheck[3]] - """ if not hasattr(self,"cache_simple_coroots"): self.cache_simple_coroots = Family(self.index_set(), self.simple_coroot) # Should we use rename to set a nice name for this family? - # self.cache_simple_coroots.rename("alphacheck") + # self.cache_simple_coroots.rename('alphacheck') # break some doctests return self.cache_simple_coroots @@ -1327,7 +1320,6 @@ def alphacheck(self): sage: RootSystem(["A",3]).ambient_space().alphacheck() Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1)} - """ if self.root_system.is_finite() and self.root_system.is_irreducible(): return Family(self.index_set(), self.simple_coroot, @@ -1340,7 +1332,7 @@ def cohighest_root(self): """ Return the associated coroot of the highest root. - .. note:: this is usually not the highest coroot. + .. NOTE:: this is usually not the highest coroot. EXAMPLES:: @@ -1556,7 +1548,7 @@ def simple_reflections(self): """ res = self.alpha().zip(self.reflection, self.alphacheck()) # Should we use rename to set a nice name for this family? - res.rename("simple reflections") + res.rename('simple reflections') return res s = simple_reflections @@ -1651,7 +1643,7 @@ def simple_projections(self, to_negative=True): raise NotImplementedError("only implemented when 'to_negative' is True") res = self.alpha().zip(self.projection, self.alphacheck()) # Should this use rename to set a nice name for this family? - res.rename("pi") + res.rename('pi') return res ########################################################################## @@ -1668,7 +1660,6 @@ def weyl_group(self, prefix=None): Weyl Group of type ['F', 4] (as a matrix group acting on the ambient space) sage: RootSystem(['F',4]).root_space().weyl_group() # needs sage.libs.gap Weyl Group of type ['F', 4] (as a matrix group acting on the root space) - """ from sage.combinat.root_system.weyl_group import WeylGroup return WeylGroup(self, prefix=prefix) @@ -1963,9 +1954,9 @@ def _classical_alpha_0(self): # Root system plots def plot(self, - roots="simple", + roots='simple', coroots=False, - reflection_hyperplanes="simple", + reflection_hyperplanes='simple', fundamental_weights=None, fundamental_chamber=None, alcoves=None, @@ -1977,25 +1968,25 @@ def plot(self, INPUT: - - ``roots`` -- which roots to display, if any. + - ``roots`` -- which roots to display, if any Can be one of the following: - * ``"simple"`` -- The simple roots (the default) - * ``"classical"`` -- Not yet implemented - * ``"all"`` -- Only works in the finite case + * ``'simple'`` -- the simple roots (the default) + * ``'classical'`` -- not yet implemented + * ``'all'`` -- only works in the finite case * A list or tuple of roots * ``False`` - - ``coroots`` -- which coroots to display, if any. + - ``coroots`` -- which coroots to display, if any Can be one of the following: - * ``"simple"`` -- The simple coroots (the default) - * ``"classical"`` -- Not yet implemented - * ``"all"`` -- Only works in the finite case + * ``'simple'`` -- the simple coroots (the default) + * ``'classical'`` -- not yet implemented + * ``'all'`` -- only works in the finite case * A list or tuple of coroots * ``False`` - - ``fundamental_weights`` -- a boolean or ``None`` (default: ``None``) + - ``fundamental_weights`` -- boolean or ``None`` (default: ``None``) whether to display the fundamental weights. If ``None``, the fundamental weights are drawn if available. @@ -2003,9 +1994,9 @@ def plot(self, hyperplanes to display, if any. Can be one of the following: - * ``"simple"`` -- The simple roots - * ``"classical"`` -- Not yet implemented - * ``"all"`` -- Only works in the finite case + * ``'simple'`` -- the simple roots + * ``'classical'`` -- not yet implemented + * ``'all'`` -- only works in the finite case * A list or tuple of roots * ``False`` (the default) @@ -2014,7 +2005,7 @@ def plot(self, * A boolean -- Set to ``True`` to draw the fundamental chamber - * ``"classical"`` -- Draw the classical fundamental chamber + * ``'classical'`` -- draw the classical fundamental chamber * ``None`` -- (the default) The fundamental chamber is drawn except in the root lattice where this is not yet implemented. For affine types the classical @@ -2022,7 +2013,7 @@ def plot(self, - ``alcoves`` -- one of the following (default: ``True``): - * A boolean -- Whether to display the alcoves + * A boolean -- whether to display the alcoves * A list of alcoves -- The alcoves to be drawn. Each alcove is specified by the coordinates of its center in the root lattice (affine type only). Otherwise the alcoves that intersect the @@ -2030,10 +2021,10 @@ def plot(self, - ``alcove_labels`` -- one of the following (default: ``False``): - * A boolean -- Whether to display the elements of the Weyl group + * A boolean -- whether to display the elements of the Weyl group indexing the alcoves. This currently requires to also set the ``alcoves`` option. - * A number `l` -- The label is drawn at level `l` (affine type + * A number `l` -- the label is drawn at level `l` (affine type only), which only makes sense if ``affine`` is ``False``. - ``bounding_box`` -- a rational number or a list of pairs @@ -2056,10 +2047,10 @@ def plot(self, - ``projection`` -- one of the following (default: ``True``): - * ``True`` -- The default projection for the root + * ``True`` -- the default projection for the root lattice realization is used. - * ``False`` -- No projection is used. - * ``barycentric`` -- A barycentric projection is used. + * ``False`` -- no projection is used. + * ``barycentric`` -- a barycentric projection is used. * A function -- If a function is specified, it should implement a linear (or affine) map taking as input an element of this root lattice realization and returning its @@ -2067,15 +2058,15 @@ def plot(self, rational coordinates. - ``color`` -- a function mapping vertices of the Dynkin - diagram to colors (default: ``"black"`` for 0, - ``"blue"`` for 1, ``"red"`` for 2, ``"green"`` for 3) + diagram to colors (default: ``'black'`` for 0, + ``'blue'`` for 1, ``'red'`` for 2, ``'green'`` for 3) This is used to set the color for the simple roots, fundamental weights, reflection hyperplanes, alcove facets, etc. If the color is ``None``, the object is not drawn. - - ``labels`` -- a boolean (default: ``True``) + - ``labels`` -- boolean (default: ``True``) whether to display labels on the simple roots, fundamental weights, etc. @@ -2194,9 +2185,7 @@ def _plot_projection_barycentric_matrix(self): A rational approximation of the matrix for the barycentric projection. - OUTPUT: - - a matrix with rational coefficients whose column sum is zero + OUTPUT: a matrix with rational coefficients whose column sum is zero .. SEEALSO:: @@ -2223,7 +2212,6 @@ def _plot_projection_barycentric_matrix(self): [ 1/3 1/3 1/3 -1] sage: sum(m.columns()) (0, 0, 0) - """ from sage.symbolic.constants import pi m = matrix(QQ, barycentric_projection_matrix(self.dimension()-1, angle=2*pi/3).n(20)) @@ -2264,7 +2252,7 @@ def _plot_projection_barycentric(self, x): """ return self._plot_projection_barycentric_matrix()*vector(x) - def plot_roots(self, collection="simple", **options): + def plot_roots(self, collection='simple', **options): r""" Plot the (simple/classical) roots of this root lattice. @@ -2273,11 +2261,11 @@ def plot_roots(self, collection="simple", **options): - ``collection`` -- which roots to display can be one of the following: - * ``"simple"`` (the default) - * ``"classical"`` - * ``"all"`` + * ``'simple'`` (the default) + * ``'classical'`` + * ``'all'`` - - ``**options`` -- Plotting options + - ``**options`` -- plotting options .. SEEALSO:: @@ -2349,20 +2337,20 @@ def plot_roots(self, collection="simple", **options): roots = Family(roots, self) return plot_options.family_of_vectors(roots) - def plot_coroots(self, collection="simple", **options): + def plot_coroots(self, collection='simple', **options): r""" Plot the (simple/classical) coroots of this root lattice. INPUT: - - ``collection`` -- which coroots to display. + - ``collection`` -- which coroots to display Can be one of the following: - * ``"simple"`` (the default) - * ``"classical"`` - * ``"all"`` + * ``'simple'`` (the default) + * ``'classical'`` + * ``'all'`` - - ``**options`` -- Plotting options + - ``**options`` -- plotting options .. SEEALSO:: @@ -2412,7 +2400,7 @@ def plot_fundamental_weights(self, **options): INPUT: - - ``**options`` -- Plotting options + - ``**options`` -- plotting options .. SEEALSO:: @@ -2452,20 +2440,20 @@ def plot_fundamental_weights(self, **options): self.fundamental_weights()))) return plot_options.family_of_vectors(fundamental_weights) - def plot_reflection_hyperplanes(self, collection="simple", **options): + def plot_reflection_hyperplanes(self, collection='simple', **options): r""" Plot the simple reflection hyperplanes. INPUT: - - ``collection`` -- which reflection hyperplanes to display. + - ``collection`` -- which reflection hyperplanes to display Can be one of the following: - * ``"simple"`` (the default) - * ``"classical"`` - * ``"all"`` + * ``'simple'`` (the default) + * ``'classical'`` + * ``'all'`` - - ``**options`` -- Plotting options + - ``**options`` -- plotting options .. SEEALSO:: @@ -2601,15 +2589,15 @@ def plot_hedron(self, **options): for vertex in self.rho().orbit()] return Polyhedron(vertices=vertices).plot() - def plot_fundamental_chamber(self, style="normal", **options): + def plot_fundamental_chamber(self, style='normal', **options): r""" Plot the (classical) fundamental chamber. INPUT: - - ``style`` -- ``"normal"`` or ``"classical"`` (default: ``"normal"``) + - ``style`` -- ``'normal'`` or ``'classical'`` (default: ``'normal'``) - - ``**options`` -- Plotting options + - ``**options`` -- plotting options .. SEEALSO:: @@ -2648,7 +2636,7 @@ def plot_fundamental_chamber(self, style="normal", **options): sage: print(L.plot_fundamental_chamber().description()) # needs sage.plot Polygon defined by 3 points: [(0.5, 0.5), (1.0, 0.0), (0.0, 0.0)] - sage: print(L.plot_fundamental_chamber(style="classical").description()) # needs sage.plot + sage: print(L.plot_fundamental_chamber(style='classical').description()) # needs sage.plot Polygon defined by 3 points: [(0.0, 0.0), (3.0, 3.0), (3.0, 0.0)] """ plot_options = self.plot_parse_options(**options) @@ -2666,7 +2654,7 @@ def plot_fundamental_chamber(self, style="normal", **options): lines = [] return plot_options.cone(rays=[Lambda[i] for i in I], lines=lines, - color="lightgrey", + color='lightgrey', alpha=.3) def plot_alcoves(self, alcoves=True, alcove_labels=False, wireframe=False, **options): @@ -2675,12 +2663,12 @@ def plot_alcoves(self, alcoves=True, alcove_labels=False, wireframe=False, **opt INPUT: - - ``alcoves`` -- a list of alcoves or ``True`` (default: ``True``) + - ``alcoves`` -- list of alcoves or ``True`` (default: ``True``) - - ``alcove_labels`` -- a boolean or a number specifying at + - ``alcove_labels`` -- boolean or a number specifying at which level to put the label (default: ``False``) - - ``**options`` -- Plotting options + - ``**options`` -- plotting options .. SEEALSO:: @@ -2778,13 +2766,13 @@ def alcove_label(w): alcoves = list(alcoves) if alcoves is True or (alcoves and W.is_parent_of(alcoves[0])): if alcoves is True: - alcoves = W.weak_order_ideal(alcove_in_bounding_box, side="right") + alcoves = W.weak_order_ideal(alcove_in_bounding_box, side='right') # We assume that the fundamental alcove lies within # the bounding box, and explore the alcoves # intersecting the bounding box by going up right # order (i.e. going away from the fundamental alcove) for w in alcoves: - for i in w.descents(side="right", positive=True): + for i in w.descents(side='right', positive=True): G += alcove_facet(w, i) if alcove_labels is not False: G += alcove_label(w) @@ -2803,7 +2791,7 @@ def alcove_label(w): shift = sum(x*v for x,v in zip(alcove, translation_vectors)) shift = W.from_morphism(shift.translation) for w in W0: - for i in w.descents(side="right", positive=True): + for i in w.descents(side='right', positive=True): G += alcove_facet(shift * w, i) if alcove_labels: G += alcove_label(w) @@ -2874,7 +2862,7 @@ def plot_bounding_box(self, **options): INPUT: - - ``**options`` -- Plotting options + - ``**options`` -- plotting options This is mostly for testing purposes. @@ -2896,16 +2884,16 @@ def plot_bounding_box(self, **options): [Polygon defined by 4 points] """ plot_options = self.plot_parse_options(**options) - return plot_options.bounding_box.plot(color="gray", alpha=0.5, wireframe=False) + return plot_options.bounding_box.plot(color='gray', alpha=0.5, wireframe=False) - def plot_alcove_walk(self, word, start=None, foldings=None, color="orange", **options): + def plot_alcove_walk(self, word, start=None, foldings=None, color='orange', **options): r""" Plot an alcove walk. INPUT: - - ``word`` -- a list of elements of the index set - - ``foldings`` -- a list of booleans or ``None`` (default: ``None``) + - ``word`` -- list of elements of the index set + - ``foldings`` -- list of booleans or ``None`` (default: ``None``) - ``start`` -- an element of this space (default: ``None`` for `\rho`) - ``**options`` -- plotting options @@ -2929,7 +2917,7 @@ def plot_alcove_walk(self, word, start=None, foldings=None, color="orange", **op The same plot with another alcove walk:: sage: w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2] - sage: p += L.plot_alcove_walk(w2, color="orange") # long time, needs sage.plot sage.symbolic + sage: p += L.plot_alcove_walk(w2, color='orange') # long time, needs sage.plot sage.symbolic And another with some foldings:: @@ -2937,7 +2925,7 @@ def plot_alcove_walk(self, word, start=None, foldings=None, color="orange", **op sage: pic += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], # long time (3s), needs sage.plot sage.symbolic ....: foldings=[False, False, True, False, False, ....: False, True, False, True, False], - ....: color="green"); pic + ....: color='green'); pic Graphics object consisting of 155 graphics primitives TESTS:: @@ -2946,7 +2934,7 @@ def plot_alcove_walk(self, word, start=None, foldings=None, color="orange", **op sage: p = L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], # needs sage.plot sage.symbolic ....: foldings=[False, False, True, False, False, ....: False, True, False, True, False], - ....: color="green", + ....: color='green', ....: start=L.rho()) sage: print(p.description()) # needs sage.plot sage.symbolic Line defined by 2 points: [(-1.0, 8.0), (-1.5, 9.0)] @@ -3024,7 +3012,7 @@ def plot_ls_paths(self, paths, plot_labels=None, colored_labels=True, **options) - ``plot_labels`` -- (default: ``None``) the distance to plot the LS labels from the endpoint of the path; set to ``None`` to not display the labels - - ``colored_labels`` -- (default: ``True``) if ``True``, then + - ``colored_labels`` -- boolean (default: ``True``); if ``True``, then color the labels the same color as the LS path - ``**options`` -- plotting options @@ -3084,7 +3072,7 @@ def plot_mv_polytope(self, mv_polytope, mark_endpoints=True, INPUT: - ``mv_polytope`` -- an MV polytope - - ``mark_endpoints`` -- (default: ``True``) mark the endpoints + - ``mark_endpoints`` -- boolean (default: ``True``); mark the endpoints of the MV polytope - ``circle_size`` -- (default: 0.06) the size of the circles - ``circle_thickness`` -- (default: 1.6) the thinkness of the @@ -3157,7 +3145,7 @@ def plot_crystal(self, crystal, INPUT: - ``crystal`` -- the finite crystal to plot - - ``plot_labels`` -- (default: ``True``) can be one of the + - ``plot_labels`` -- boolean (default: ``True``); can be one of the following: * ``True`` -- use the latex labels @@ -3167,7 +3155,7 @@ def plot_crystal(self, crystal, - ``label_color`` -- (default: ``'black'``) the color of the labels - - ``edge_labels`` -- (default: ``False``) if ``True``, then draw + - ``edge_labels`` -- boolean (default: ``False``); if ``True``, then draw in the edge label - ``circle_size`` -- (default: 0.06) the size of the circles - ``circle_thickness`` -- (default: 1.6) the thinkness of the @@ -3292,7 +3280,6 @@ def dual_type_cospace(self): sage: CartanType(['F',4]).root_system().coweight_lattice().dual_type_cospace() Weight lattice of the Root system of type ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1} - """ from .root_space import RootSpace from .weight_space import WeightSpace @@ -3329,7 +3316,6 @@ def to_ambient_space_morphism(self): Generic morphism: From: Weight lattice of the Root system of type ['B', 2] To: Ambient space of the Root system of type ['B', 2] - """ ########################################################################## @@ -3478,7 +3464,7 @@ def simple_reflection(self, i): def simple_reflections(self): """ - The images of ``self`` by all the simple reflections + The images of ``self`` by all the simple reflections. EXAMPLES:: @@ -3693,7 +3679,7 @@ def has_descent(self, i, positive=False): def first_descent(self, index_set=None, positive=False): """ - Return the first descent of pt + Return the first descent of pt. One can use the ``index_set`` option to restrict to the parabolic subgroup indexed by ``index_set``. @@ -3719,7 +3705,7 @@ def first_descent(self, index_set=None, positive=False): def descents(self, index_set=None, positive=False): """ - Return the descents of pt + Return the descents of pt. EXAMPLES:: @@ -3845,7 +3831,6 @@ def reduced_word(self, index_set=None, positive=True): [2, 3, 4, 5] sage: alpha[1].reduced_word([1,2]) # needs sage.graphs [2] - """ return self.to_dominant_chamber(index_set=index_set,positive=positive,reduced_word=True)[1] @@ -3912,6 +3897,57 @@ def is_dominant_weight(self): # Or is_dominant_integral_weight? return all(self.inner_product(alphacheck[i]) in NN for i in self.parent().index_set()) + def is_verma_dominant(self, positive=True): + r""" + Return if ``self`` is Verma dominant. + + A weight `\lambda` is *Verma dominant* if + + .. MATH:: + + \langle \lambda + \rho, \alpha^{\vee} \rangle \notin \ZZ_{<0} + + for all positive roots `\alpha`. Note that begin Verma dominant does + *not* imply that `\langle \lambda+\rho, \alpha^{\vee} \rangle \geq 0` + for any positive root `\alpha`. This is used to determine if + a Verma module is simple or projective. + + INPUT: + + - ``positive`` -- boolean (default: ``True``); if ``False``, then + this checks if the weight is Verma anti-dominant, where + `\ZZ_{<0}` is replaced with `\ZZ_{>0}` in the definition. + + EXAMPLES:: + + sage: P = RootSystem(['A', 3]).weight_space() + sage: La = P.fundamental_weights() + sage: alphacheck = P.coroot_lattice().positive_roots() + sage: rho = P.rho() + sage: (La[1] + 2*La[2]).is_verma_dominant() + True + sage: la = La[1] - 3/2*La[3] - rho + sage: la.is_verma_dominant() + True + sage: la.is_verma_dominant(positive=False) + False + sage: [(la+rho).scalar(coroot) for coroot in alphacheck] + [1, 0, -3/2, 1, -3/2, -1/2] + sage: mu = 1/2*La[1] - 3/2*La[3] - rho + sage: mu.is_verma_dominant() + False + sage: mu.is_verma_dominant(positive=False) + True + sage: [(mu+rho).scalar(coroot) for coroot in alphacheck] + [1/2, 0, -3/2, 1/2, -3/2, -1] + """ + P = self.parent() + alphacheck = P.coroot_lattice().positive_roots() + wt = self + P.rho() + if positive: + return not any((c := wt.scalar(ac)) in ZZ and c < 0 for ac in alphacheck) + return not any((c := wt.scalar(ac)) in ZZ and c > 0 for ac in alphacheck) + ########################################################################## # weak order ########################################################################## @@ -4088,7 +4124,7 @@ def to_simple_root(self, reduced_word=False): INPUT: - ``self`` -- a positive root - - ``reduced_word`` -- a boolean (default: ``False``) + - ``reduced_word`` -- boolean (default: ``False``) OUTPUT: @@ -4179,7 +4215,6 @@ def associated_reflection(self): (1, 2, 3, 2, 1) sage: C3_rl.simple_root(2).associated_reflection() # needs sage.graphs (2,) - """ i, reduced_word = self.to_simple_root(reduced_word=True) return reduced_word + (i,) + tuple(reversed(reduced_word)) @@ -4190,8 +4225,8 @@ def translation(self, x): INPUT: - - ``self`` -- an element `t` at level `0` - - ``x`` -- an element of the same space + - ``self`` -- an element `t` at level `0` + - ``x`` -- an element of the same space EXAMPLES:: @@ -4239,7 +4274,7 @@ def weyl_action(self, element, inverse=False): of the same Cartan type, or a tuple or a list (such as a reduced word) of elements from the index set - - ``inverse`` -- a boolean (default: ``False``); whether to + - ``inverse`` -- boolean (default: ``False``); whether to act by the inverse element EXAMPLES:: @@ -4271,7 +4306,7 @@ def weyl_action(self, element, inverse=False): action of a corresponding reduced word):: sage: # needs sage.libs.gap - sage: W = WeylGroup(['A',3], prefix="s") + sage: W = WeylGroup(['A',3], prefix='s') sage: w = W.from_reduced_word([1, 2]) sage: wl.weyl_group() == W False @@ -4325,7 +4360,6 @@ def weyl_stabilizer(self, index_set=None): [3, 4] sage: mu.weyl_stabilizer(index_set = [1,2,3]) [3] - """ if index_set is None: index_set = self.parent().cartan_type().index_set() @@ -4351,7 +4385,7 @@ def dot_action(self, w, inverse=False): the same Cartan type, or a tuple or a list (such as a reduced word) of elements from the index set - - ``inverse`` -- a boolean (default: ``False``); whether + - ``inverse`` -- boolean (default: ``False``); whether to act by the inverse element EXAMPLES:: @@ -4387,7 +4421,7 @@ def is_parabolic_root(self, index_set): INPUT: - - ``index_set`` -- the Dynkin node set of the parabolic subsystem. + - ``index_set`` -- the Dynkin node set of the parabolic subsystem .. TODO:: This implementation is only valid in the root or weight lattice @@ -4400,7 +4434,6 @@ def is_parabolic_root(self, index_set): True sage: alpha.is_parabolic_root([2]) False - """ for i in self.support(): if i not in index_set: @@ -4481,7 +4514,6 @@ def to_dual_type_cospace(self): 2*Lambdacheck[1] + 2*Lambdacheck[2] + 3*Lambdacheck[3] sage: w.parent() Coweight lattice of the Root system of type ['B', 3] - """ return self.parent().dual_type_cospace().from_vector(self.to_vector()) @@ -4504,7 +4536,6 @@ def to_classical(self): 2*e[0] + 2*e[1] + 3*e[2] sage: v.to_classical() # needs sage.graphs (2, 2, 3, 0) - """ return self.parent().classical()(self) @@ -4532,7 +4563,6 @@ def to_ambient(self): 2*alphacheck[1] + 2*alphacheck[2] + 3*alphacheck[3] sage: alphavee.to_ambient() (2, 0, 1, -3) - """ def is_long_root(self): diff --git a/src/sage/combinat/root_system/root_space.py b/src/sage/combinat/root_system/root_space.py index f8783a78d43..14f5ed4ab23 100644 --- a/src/sage/combinat/root_system/root_space.py +++ b/src/sage/combinat/root_system/root_space.py @@ -16,12 +16,12 @@ class RootSpace(CombinatorialFreeModule): r""" - The root space of a root system over a given base ring + The root space of a root system over a given base ring. INPUT: - ``root_system`` -- a root system - - ``base_ring``: a ring `R` + - ``base_ring`` -- a ring `R` The *root space* (or lattice if ``base_ring`` is `\ZZ`) of a root system is the formal free module `\bigoplus_i R \alpha_i` @@ -47,7 +47,6 @@ class RootSpace(CombinatorialFreeModule): alpha[1] sage: latex(r.simple_root(1)) \alpha_{1} - """ def __init__(self, root_system, base_ring): @@ -56,7 +55,6 @@ def __init__(self, root_system, base_ring): sage: P = RootSystem(['A',4]).root_space() sage: s = P.simple_reflections() - """ from sage.categories.morphism import SetMorphism from sage.categories.homset import Hom @@ -87,7 +85,6 @@ def _repr_(self): Coroot lattice of the Root system of type ['A', 4] sage: RootSystem(['B',4]).coroot_space() Coroot space over the Rational Field of the Root system of type ['B', 4] - """ return self._name_string() @@ -105,7 +102,8 @@ def _name_string(self, capitalize=True, base_ring=True, type=True): @cached_method def to_coroot_space_morphism(self): """ - Returns the ``nu`` map to the coroot space over the same base ring, using the symmetrizer of the Cartan matrix + Return the ``nu`` map to the coroot space over the same base ring, + using the symmetrizer of the Cartan matrix. It does not map the root lattice to the coroot lattice, but has the property that any root is mapped to some scalar @@ -168,7 +166,7 @@ def _to_root_lattice(self, x): ... ValueError: alpha[1] + alpha[2] + 3/2*alpha[3] does not have integral coefficients - .. note:: + .. NOTE:: For internal use only; instead use a conversion:: @@ -217,7 +215,6 @@ def to_ambient_space_morphism(self): Generic morphism: From: Root lattice of the Root system of type ['A', 2] To: Ambient space of the Root system of type ['A', 2] - """ if self.root_system.dual_side: L = self.cartan_type().dual().root_system().ambient_space() @@ -263,17 +260,38 @@ def scalar(self, lambdacheck): [-1 2 -1 0] [ 0 -1 2 -1] [ 0 0 -2 2] + + TESTS: + + Verify that :issue:`15325` (A) is fixed:: + + sage: rt = RootSystem(['E', 8]) + sage: lat = rt.root_lattice() + sage: spc = rt.ambient_space() + sage: lat.simple_root(1).scalar(spc.simple_coroot(2)) + 0 + + Verify that directionality is correct for roots of different lengths:: + + sage: lat = RootSystem(['B', 3]).root_lattice() + sage: lat.simple_root(2).scalar(lat.simple_coroot(3)) + -2 """ - # Find some better test - if not (lambdacheck in self.parent().coroot_lattice() or lambdacheck in self.parent().coroot_space()): - raise TypeError("%s is not in a coroot lattice/space" % (lambdacheck)) - zero = self.parent().base_ring().zero() - cartan_matrix = self.parent().dynkin_diagram() - return sum( (sum( (lambdacheck[i]*s for i,s in cartan_matrix.column(j)), zero) * c for j,c in self), zero) + if lambdacheck in self.parent().coroot_lattice() or lambdacheck in self.parent().coroot_space(): + # This is the mathematically canonical case, where we use the Cartan matrix to find the scalar product + zero = self.parent().base_ring().zero() + cartan_matrix = self.parent().dynkin_diagram() + return sum( (sum( (lambdacheck[i]*s for i,s in cartan_matrix.column(j)), zero) * c for j,c in self), zero) + + if lambdacheck in self.parent().root_system.ambient_space(): + # lambdacheck lives in the ambient space of the root space, so we take the usual dot product in the ambient space + return self.to_ambient().dot_product(lambdacheck) + + raise TypeError(f"{lambdacheck} is not in a coroot lattice/space") def is_positive_root(self): """ - Checks whether an element in the root space lies in the + Check whether an element in the root space lies in the nonnegative cone spanned by the simple roots. EXAMPLES:: @@ -292,7 +310,7 @@ def is_positive_root(self): @cached_in_parent_method def associated_coroot(self): r""" - Returns the coroot associated to this root + Return the coroot associated to this root. OUTPUT: @@ -331,7 +349,7 @@ def quantum_root(self): INPUT: - - ``self`` -- an element of the nonnegative integer span of simple roots. + - ``self`` -- an element of the nonnegative integer span of simple roots A root `\alpha` is a quantum root if `\ell(s_\alpha) = \langle 2 \rho, \alpha^\vee \rangle - 1` where `\ell` is the length function, `s_\alpha` is the reflection across the hyperplane @@ -362,7 +380,7 @@ def max_coroot_le(self): INPUT: - - ``self`` -- an element of the nonnegative integer span of simple roots. + - ``self`` -- an element of the nonnegative integer span of simple roots Returns None for the zero element. @@ -419,7 +437,7 @@ def max_quantum_element(self): INPUT: - - ``self`` -- an element of the nonnegative integer span of simple roots. + - ``self`` -- an element of the nonnegative integer span of simple roots Really ``self`` is an element of a coroot lattice. @@ -437,7 +455,6 @@ def max_quantum_element(self): [1, 2, 1] sage: Qvee.from_vector(vector([0,2])).max_quantum_element() [2] - """ Qvee = self.parent() word = [] @@ -462,7 +479,6 @@ def to_ambient(self): 2*alphacheck[1] + 2*alphacheck[2] sage: alphavee.to_ambient() (2, 2) - """ return self.parent().to_ambient_space_morphism()(self) diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index d75aeba1505..06210a749e7 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -301,7 +301,7 @@ class RootSystem(UniqueRepresentation, SageObject): @staticmethod def __classcall__(cls, cartan_type, as_dual_of=None): """ - Straighten arguments to enable unique representation + Straighten arguments to enable unique representation. .. SEEALSO:: :class:`UniqueRepresentation` @@ -341,7 +341,7 @@ def __init__(self, cartan_type, as_dual_of=None): def _test_root_lattice_realizations(self, **options): """ - Runs tests on all the root lattice realizations of this root + Run tests on all the root lattice realizations of this root system. EXAMPLES:: @@ -483,12 +483,14 @@ def root_poset(self, restricted=False, facade=False): Return the (restricted) root poset associated to ``self``. The elements are given by the positive roots (resp. non-simple, positive roots), and - `\alpha \leq \beta` iff `\beta - \alpha` is a non-negative linear combination of simple roots. + `\alpha \leq \beta` iff `\beta - \alpha` is a nonnegative linear combination of simple roots. INPUT: - - ``restricted`` -- (default: ``False``) if True, only non-simple roots are considered. - - ``facade`` -- (default: ``False``) passes facade option to the poset generator. + - ``restricted`` -- boolean (default: ``False``); if ``True``, only + non-simple roots are considered + - ``facade`` -- boolean (default: ``False``); passes facade option to + the poset generator EXAMPLES:: @@ -558,7 +560,7 @@ def weight_lattice(self, extended=False): @cached_method def weight_space(self, base_ring=QQ, extended=False): """ - Returns the weight space associated to ``self``. + Return the weight space associated to ``self``. .. SEEALSO:: @@ -785,6 +787,55 @@ def coambient_space(self, base_ring=QQ): """ return self.dual.ambient_space(base_ring) + def coxeter_number(self): + """ + Return the Coxeter number of an irreducible finite root system. + + .. SEEALSO:: + + :meth:`~sage.combinat.root_system.cartan_type.CartanType_standard_finite.coxeter_number`. + + EXAMPLES:: + + sage: rt = RootSystem(['C', 5]) + sage: rt.coxeter_number() + 10 + """ + # Check if RootSystem is finite and irreducible + if not (self.is_finite() and self.is_irreducible()): + raise ValueError("the Coxeter number is defined only for finite and irreducible root systems") + # Hand over to CartanType method + return self._cartan_type.coxeter_number() + + def dual_coxeter_number(self): + """ + Return the dual Coxeter number of a irreducible finite root system. + + The dual Coxeter number is equal to 1 plus the sum of the coefficients + of simple roots in the highest short root of the dual root system. + + .. SEEALSO:: :meth:`~sage.combinat.root_system.cartan_type.CartanType_standard_finite.dual_coxeter_number` + + EXAMPLES:: + + sage: rt = RootSystem(['C', 5]) + sage: rt.dual_coxeter_number() + 6 + + The dual Coxeter number is not the same concept as the Coxeter number + of the dual root system:: + + sage: rt.dual + Dual of root system of type ['C', 5] + sage: rt.dual.coxeter_number() + 10 + """ + # Check if RootSystem is finite and irreducible + if not (self.is_finite() and self.is_irreducible()): + raise ValueError("the dual Coxeter number is defined only for finite and irreducible root systems") + # Hand over to CartanType method + return self._cartan_type.dual_coxeter_number() + def WeylDim(ct, coeffs): """ @@ -792,11 +843,9 @@ def WeylDim(ct, coeffs): INPUT: + - ``ct`` -- a Cartan type - - ``ct`` -- a Cartan type - - - ``coeffs`` -- a list of nonnegative integers - + - ``coeffs`` -- list of nonnegative integers The length of the list must equal the rank type[1]. A dominant weight hwv is constructed by summing the fundamental weights with diff --git a/src/sage/combinat/root_system/type_A.py b/src/sage/combinat/root_system/type_A.py index 48d1474c1f4..91907976f8c 100644 --- a/src/sage/combinat/root_system/type_A.py +++ b/src/sage/combinat/root_system/type_A.py @@ -48,7 +48,7 @@ class AmbientSpace(ambient_space.AmbientSpace): @classmethod def smallest_base_ring(cls, cartan_type=None): """ - Returns the smallest base ring the ambient space can be defined upon + Return the smallest base ring the ambient space can be defined upon. .. SEEALSO:: :meth:`~sage.combinat.root_system.ambient_space.AmbientSpace.smallest_base_ring` @@ -123,7 +123,6 @@ def positive_roots(self): (1, 0, 0, -1), (0, 1, 0, -1), (0, 0, 1, -1)] - """ res = [] for j in range(self.n): @@ -148,16 +147,15 @@ def fundamental_weight(self, i): sage: e = RootSystem(['A',3]).ambient_lattice() sage: e.fundamental_weights() Finite family {1: (1, 0, 0, 0), 2: (1, 1, 0, 0), 3: (1, 1, 1, 0)} - """ return self.sum(self.monomial(j) for j in range(i)) def det(self, k=1): """ - returns the vector (1, ... ,1) which in the ['A',r] + Return the vector (1, ... ,1) which in the ['A',r] weight lattice, interpreted as a weight of GL(r+1,CC) is the determinant. If the optional parameter k is - given, returns (k, ... ,k), the k-th power of the + given, returns (k, ... ,k), the `k`-th power of the determinant. EXAMPLES:: @@ -176,7 +174,7 @@ def det(self, k=1): class CartanType(CartanType_standard_finite, CartanType_simply_laced, CartanType_simple): """ - Cartan Type `A_n` + Cartan Type `A_n`. .. SEEALSO:: :func:`~sage.combinat.root_systems.cartan_type.CartanType` """ @@ -250,7 +248,7 @@ def dual_coxeter_number(self): def dynkin_diagram(self): """ - Returns the Dynkin diagram of type A. + Return the Dynkin diagram of type A. EXAMPLES:: @@ -338,11 +336,12 @@ def ascii_art(self, label=None, node=None): label = lambda i: i if node is None: node = self._ascii_art_node - ret = "---".join(node(label(i)) for i in range(1,n+1)) + "\n" - ret += "".join("{!s:4}".format(label(i)) for i in range(1,n+1)) + ret = "---".join(node(label(i)) for i in range(1, n + 1)) + "\n" + ret += "".join("{!s:4}".format(label(i)) for i in range(1, n + 1)) return ret # For unpickling backward compatibility (Sage <= 4.1) from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_A', 'ambient_space', AmbientSpace) +register_unpickle_override('sage.combinat.root_system.type_A', + 'ambient_space', AmbientSpace) diff --git a/src/sage/combinat/root_system/type_A_affine.py b/src/sage/combinat/root_system/type_A_affine.py index 57ed18afd01..cf642231967 100644 --- a/src/sage/combinat/root_system/type_A_affine.py +++ b/src/sage/combinat/root_system/type_A_affine.py @@ -68,7 +68,7 @@ def _latex_(self): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for affine type A. + Return the extended Dynkin diagram for affine type A. EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_A_infinity.py b/src/sage/combinat/root_system/type_A_infinity.py index 9e0f4711ccd..5c42db7e176 100644 --- a/src/sage/combinat/root_system/type_A_infinity.py +++ b/src/sage/combinat/root_system/type_A_infinity.py @@ -98,7 +98,6 @@ def ascii_art(self, label=None, node=None): sage: print(CartanType(['A', NN]).ascii_art()) O---O---O---O---O---O---O---.. 0 1 2 3 4 5 6 - """ if label is None: label = lambda i: i diff --git a/src/sage/combinat/root_system/type_B.py b/src/sage/combinat/root_system/type_B.py index 8e9cb6e75a5..9794d00794c 100644 --- a/src/sage/combinat/root_system/type_B.py +++ b/src/sage/combinat/root_system/type_B.py @@ -32,7 +32,6 @@ def root(self, i, j): sage: e = RootSystem(['B',3]).ambient_space() sage: e.root(0,1) (1, -1, 0) - """ return self.monomial(i) - self.monomial(j) @@ -98,7 +97,6 @@ def positive_roots(self): (1, 0, 0), (0, 1, 0), (0, 0, 1)] - """ res = [] for i in range(self.n-1): @@ -218,7 +216,7 @@ def dual(self): def dynkin_diagram(self): """ - Returns a Dynkin diagram for type B. + Return a Dynkin diagram for type B. EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_BC_affine.py b/src/sage/combinat/root_system/type_BC_affine.py index 740dfa2e5f3..6bf8cc43697 100644 --- a/src/sage/combinat/root_system/type_BC_affine.py +++ b/src/sage/combinat/root_system/type_BC_affine.py @@ -70,7 +70,7 @@ def __init__(self, n): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for affine type BC. + Return the extended Dynkin diagram for affine type BC. EXAMPLES:: @@ -103,7 +103,6 @@ def dynkin_diagram(self): BC1~ sage: c.edges(sort=True) # needs sage.graphs [(0, 1, 1), (1, 0, 4)] - """ from .dynkin_diagram import DynkinDiagram_class n = self.n @@ -243,7 +242,7 @@ def ascii_art(self, label=None, node=None): def classical(self): """ - Returns the classical Cartan type associated with self + Return the classical Cartan type associated with ``self``. sage: CartanType(["BC", 3, 2]).classical() ['C', 3] diff --git a/src/sage/combinat/root_system/type_B_affine.py b/src/sage/combinat/root_system/type_B_affine.py index 047144f02d6..fd074cd2e8c 100644 --- a/src/sage/combinat/root_system/type_B_affine.py +++ b/src/sage/combinat/root_system/type_B_affine.py @@ -76,7 +76,6 @@ def dynkin_diagram(self): B1~ sage: b.edges(sort=True) [(0, 1, 2), (1, 0, 2)] - """ from . import cartan_type n = self.n diff --git a/src/sage/combinat/root_system/type_C.py b/src/sage/combinat/root_system/type_C.py index 8c7ebce3359..d7c6b67194f 100644 --- a/src/sage/combinat/root_system/type_C.py +++ b/src/sage/combinat/root_system/type_C.py @@ -212,7 +212,7 @@ def dual(self): def dynkin_diagram(self): """ - Returns a Dynkin diagram for type C. + Return a Dynkin diagram for type C. EXAMPLES:: @@ -306,10 +306,11 @@ def _default_folded_cartan_type(self): """ from sage.combinat.root_system.type_folded import CartanTypeFolded n = self.n - return CartanTypeFolded(self, ['A', 2*n-1], - [[i, 2*n-i] for i in range(1, n)] + [[n]]) + return CartanTypeFolded(self, ['A', 2*n - 1], + [[i, 2*n - i] for i in range(1, n)] + [[n]]) # For unpickling backward compatibility (Sage <= 4.1) from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_C', 'ambient_space', AmbientSpace) +register_unpickle_override('sage.combinat.root_system.type_C', + 'ambient_space', AmbientSpace) diff --git a/src/sage/combinat/root_system/type_C_affine.py b/src/sage/combinat/root_system/type_C_affine.py index adaf5c77562..c26e03f1b10 100644 --- a/src/sage/combinat/root_system/type_C_affine.py +++ b/src/sage/combinat/root_system/type_C_affine.py @@ -50,7 +50,7 @@ def __init__(self, n): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for affine type C. + Return the extended Dynkin diagram for affine type C. EXAMPLES:: @@ -60,7 +60,6 @@ def dynkin_diagram(self): C3~ sage: c.edges(sort=True) # needs sage.graphs [(0, 1, 2), (1, 0, 1), (1, 2, 1), (2, 1, 1), (2, 3, 1), (3, 2, 2)] - """ n = self.n if n == 1: diff --git a/src/sage/combinat/root_system/type_D.py b/src/sage/combinat/root_system/type_D.py index 5f1469e48a8..49e9d952a2f 100644 --- a/src/sage/combinat/root_system/type_D.py +++ b/src/sage/combinat/root_system/type_D.py @@ -10,6 +10,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from . import ambient_space +from sage.misc.persist import register_unpickle_override class AmbientSpace(ambient_space.AmbientSpace): @@ -116,9 +117,6 @@ def fundamental_weight(self, i): return self.sum(self.monomial(j) for j in range(i)) -from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_A', 'ambient_space', AmbientSpace) - from sage.misc.cachefunc import cached_method from .cartan_type import CartanType_standard_finite, CartanType_simply_laced, CartanType_simple @@ -182,7 +180,7 @@ def _latex_(self): def is_atomic(self): """ - Implements :meth:`CartanType_abstract.is_atomic` + Implement :meth:`CartanType_abstract.is_atomic`. `D_2` is atomic, like all `D_n`, despite being non irreducible. @@ -220,7 +218,7 @@ def dual_coxeter_number(self): @cached_method def dynkin_diagram(self): """ - Returns a Dynkin diagram for type D. + Return a Dynkin diagram for type D. EXAMPLES:: @@ -349,10 +347,10 @@ def ascii_art(self, label=None, node=None): ret = (4*(n-3))*" "+"{} {}\n".format(node(label(n)), label(n)) ret += ((4*(n-3))*" " + "|\n")*2 ret += "---".join(node(label(i)) for i in range(1, n)) + "\n" - ret += "".join("{!s:4}".format(label(i)) for i in range(1,n)) + ret += "".join("{!s:4}".format(label(i)) for i in range(1, n)) return ret # For unpickling backward compatibility (Sage <= 4.1) -from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_D', 'ambient_space', AmbientSpace) +register_unpickle_override('sage.combinat.root_system.type_D', + 'ambient_space', AmbientSpace) diff --git a/src/sage/combinat/root_system/type_D_affine.py b/src/sage/combinat/root_system/type_D_affine.py index f77204e4a01..59748fb2ff6 100644 --- a/src/sage/combinat/root_system/type_D_affine.py +++ b/src/sage/combinat/root_system/type_D_affine.py @@ -50,7 +50,7 @@ def __init__(self, n): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for affine type D. + Return the extended Dynkin diagram for affine type D. EXAMPLES:: @@ -95,7 +95,6 @@ def dynkin_diagram(self): sage: d.edges(sort=True) # needs sage.graphs [(0, 2, 1), (0, 3, 1), (1, 2, 1), (1, 3, 1), (2, 0, 1), (2, 1, 1), (3, 0, 1), (3, 1, 1)] - """ from .dynkin_diagram import DynkinDiagram_class n = self.n diff --git a/src/sage/combinat/root_system/type_E.py b/src/sage/combinat/root_system/type_E.py index 22e81d52b34..a7fbb8aeb39 100644 --- a/src/sage/combinat/root_system/type_E.py +++ b/src/sage/combinat/root_system/type_E.py @@ -374,7 +374,6 @@ def positive_roots(self): (1/2, 1/2, 1/2, 1/2, 1/2, 1/2, -1/2, -1/2)] sage: e.rho() (0, 1, 2, 3, 4, 5, 6, 23) - """ v = ZZ(1)/ZZ(2) # Note that @@ -525,7 +524,7 @@ def dual_coxeter_number(self): def dynkin_diagram(self): """ - Returns a Dynkin diagram for type E. + Return a Dynkin diagram for type E. EXAMPLES:: @@ -562,7 +561,6 @@ def dynkin_diagram(self): [(1, 3, 1), (2, 4, 1), (3, 1, 1), (3, 4, 1), (4, 2, 1), (4, 3, 1), (4, 5, 1), (5, 4, 1), (5, 6, 1), (6, 5, 1), (6, 7, 1), (7, 6, 1), (7, 8, 1), (8, 7, 1)] - """ from .dynkin_diagram import DynkinDiagram_class g = DynkinDiagram_class(self) @@ -638,4 +636,5 @@ def ascii_art(self, label=None, node=None): # For unpickling backward compatibility (Sage <= 4.1) from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_E', 'ambient_space', AmbientSpace) +register_unpickle_override('sage.combinat.root_system.type_E', + 'ambient_space', AmbientSpace) diff --git a/src/sage/combinat/root_system/type_E_affine.py b/src/sage/combinat/root_system/type_E_affine.py index 3268d0603e5..a4800974566 100644 --- a/src/sage/combinat/root_system/type_E_affine.py +++ b/src/sage/combinat/root_system/type_E_affine.py @@ -62,7 +62,7 @@ def _latex_(self): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for affine type E. + Return the extended Dynkin diagram for affine type E. EXAMPLES:: @@ -113,7 +113,6 @@ def dynkin_diagram(self): [(0, 8, 1), (1, 3, 1), (2, 4, 1), (3, 1, 1), (3, 4, 1), (4, 2, 1), (4, 3, 1), (4, 5, 1), (5, 4, 1), (5, 6, 1), (6, 5, 1), (6, 7, 1), (7, 6, 1), (7, 8, 1), (8, 0, 1), (8, 7, 1)] - """ from .dynkin_diagram import DynkinDiagram_class n = self.n diff --git a/src/sage/combinat/root_system/type_F.py b/src/sage/combinat/root_system/type_F.py index 5d699d31c5a..9a13a2e7a23 100644 --- a/src/sage/combinat/root_system/type_F.py +++ b/src/sage/combinat/root_system/type_F.py @@ -270,7 +270,7 @@ def dual_coxeter_number(self): def dynkin_diagram(self): """ - Returns a Dynkin diagram for type F. + Return a Dynkin diagram for type F. EXAMPLES:: @@ -280,7 +280,6 @@ def dynkin_diagram(self): F4 sage: f.edges(sort=True) # needs sage.graphs [(1, 2, 1), (2, 1, 1), (2, 3, 2), (3, 2, 1), (3, 4, 1), (4, 3, 1)] - """ from .dynkin_diagram import DynkinDiagram_class g = DynkinDiagram_class(self) @@ -366,7 +365,7 @@ def dual(self): 4 3 2 1 F4 relabelled by {1: 4, 2: 3, 3: 2, 4: 1} """ - return self.relabel({1:4, 2:3, 3:2, 4:1}) + return self.relabel({1: 4, 2: 3, 3: 2, 4: 1}) def _default_folded_cartan_type(self): """ @@ -383,4 +382,5 @@ def _default_folded_cartan_type(self): # For unpickling backward compatibility (Sage <= 4.1) from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_F', 'ambient_space', AmbientSpace) +register_unpickle_override('sage.combinat.root_system.type_F', + 'ambient_space', AmbientSpace) diff --git a/src/sage/combinat/root_system/type_F_affine.py b/src/sage/combinat/root_system/type_F_affine.py index 3d2dc8350ee..66bbeb574a0 100644 --- a/src/sage/combinat/root_system/type_F_affine.py +++ b/src/sage/combinat/root_system/type_F_affine.py @@ -51,7 +51,7 @@ def __init__(self): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for affine type F. + Return the extended Dynkin diagram for affine type F. EXAMPLES:: @@ -62,7 +62,6 @@ def dynkin_diagram(self): sage: f.edges(sort=True) # needs sage.graphs [(0, 1, 1), (1, 0, 1), (1, 2, 1), (2, 1, 1), (2, 3, 2), (3, 2, 1), (3, 4, 1), (4, 3, 1)] - """ from .dynkin_diagram import DynkinDiagram_class g = DynkinDiagram_class(self) @@ -107,7 +106,7 @@ def _latex_dynkin_diagram(self, label=None, node=None, node_dist=2, dual=False): def ascii_art(self, label=None, node=None): """ - Returns a ascii art representation of the extended Dynkin diagram + Return a ascii art representation of the extended Dynkin diagram. EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_G.py b/src/sage/combinat/root_system/type_G.py index a2a1612f8df..057d8d17bd1 100644 --- a/src/sage/combinat/root_system/type_G.py +++ b/src/sage/combinat/root_system/type_G.py @@ -182,7 +182,7 @@ def dual_coxeter_number(self): def dynkin_diagram(self): """ - Returns a Dynkin diagram for type G. + Return a Dynkin diagram for type G. EXAMPLES:: @@ -271,7 +271,7 @@ def dual(self): 2 1 G2 relabelled by {1: 2, 2: 1} """ - return self.relabel({1:2, 2:1}) + return self.relabel({1: 2, 2: 1}) def _default_folded_cartan_type(self): """ @@ -288,4 +288,5 @@ def _default_folded_cartan_type(self): # For unpickling backward compatibility (Sage <= 4.1) from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.root_system.type_G', 'ambient_space', AmbientSpace) +register_unpickle_override('sage.combinat.root_system.type_G', + 'ambient_space', AmbientSpace) diff --git a/src/sage/combinat/root_system/type_G_affine.py b/src/sage/combinat/root_system/type_G_affine.py index 582f7d9ed03..0cc4f0dc4d7 100644 --- a/src/sage/combinat/root_system/type_G_affine.py +++ b/src/sage/combinat/root_system/type_G_affine.py @@ -51,7 +51,7 @@ def __init__(self): def dynkin_diagram(self): """ - Returns the extended Dynkin diagram for type G. + Return the extended Dynkin diagram for type G. EXAMPLES:: @@ -102,7 +102,7 @@ def _latex_dynkin_diagram(self, label=None, node=None, node_dist=2, dual=False): def ascii_art(self, label=None, node=None): """ - Returns an ascii art representation of the Dynkin diagram + Return an ascii art representation of the Dynkin diagram. EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_H.py b/src/sage/combinat/root_system/type_H.py index 44f4b15db55..5a7c12c1b69 100644 --- a/src/sage/combinat/root_system/type_H.py +++ b/src/sage/combinat/root_system/type_H.py @@ -55,7 +55,7 @@ def _latex_(self): def coxeter_diagram(self): """ - Returns a Coxeter diagram for type H. + Return a Coxeter diagram for type H. EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_I.py b/src/sage/combinat/root_system/type_I.py index 76a24817bf9..8f67bd07ee5 100644 --- a/src/sage/combinat/root_system/type_I.py +++ b/src/sage/combinat/root_system/type_I.py @@ -79,7 +79,7 @@ def index_set(self): def coxeter_diagram(self): """ - Returns the Coxeter matrix for this type. + Return the Coxeter matrix for this type. EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_Q.py b/src/sage/combinat/root_system/type_Q.py index b2aa3748e71..3e0e33b1399 100644 --- a/src/sage/combinat/root_system/type_Q.py +++ b/src/sage/combinat/root_system/type_Q.py @@ -16,7 +16,7 @@ class CartanType(CartanType_standard_finite): """ - Cartan Type `Q_n` + Cartan Type `Q_n`. .. SEEALSO:: :func:`~sage.combinat.root_systems.cartan_type.CartanType` """ diff --git a/src/sage/combinat/root_system/type_affine.py b/src/sage/combinat/root_system/type_affine.py index f903f40bf92..4acc93d29b3 100644 --- a/src/sage/combinat/root_system/type_affine.py +++ b/src/sage/combinat/root_system/type_affine.py @@ -158,8 +158,8 @@ def sortkey(x): return (1 if isinstance(x, str) else 0, x) CombinatorialFreeModule.__init__(self, base_ring, basis_keys, - prefix="e", - latex_prefix="e", + prefix='e', + latex_prefix='e', sorting_key=sortkey, category=WeightLatticeRealizations(base_ring)) self._weight_space = self.root_system.weight_space(base_ring=base_ring,extended=True) @@ -170,7 +170,7 @@ def sortkey(x): def _name_string(self, capitalize=True, base_ring=False, type=True): r""" - Utility to implement _repr_ + Utility to implement _repr_. EXAMPLES:: @@ -402,7 +402,7 @@ def coroot_lattice(self): def _plot_projection(self, x): r""" - Implements the default projection to be used for plots + Implement the default projection to be used for plots. For affine ambient spaces, the default implementation is to project onto the classical coordinates according to the diff --git a/src/sage/combinat/root_system/type_dual.py b/src/sage/combinat/root_system/type_dual.py index d7ec7e262a3..6f4710ae787 100644 --- a/src/sage/combinat/root_system/type_dual.py +++ b/src/sage/combinat/root_system/type_dual.py @@ -237,7 +237,7 @@ def _latex_dynkin_diagram(self, label=None, node=None, node_dist=2): def ascii_art(self, label=None, node=None): """ - Return an ascii art representation of this Cartan type + Return an ascii art representation of this Cartan type. (by hacking the ascii art representation of the dual Cartan type) @@ -528,7 +528,7 @@ class CartanType_finite(CartanType, cartan_type.CartanType_finite): class CartanType_affine(CartanType, cartan_type.CartanType_affine): def classical(self): """ - Return the classical Cartan type associated with self (which should + Return the classical Cartan type associated with ``self`` (which should be affine). EXAMPLES:: @@ -576,7 +576,7 @@ def basic_untwisted(self): def special_node(self): """ - Implement :meth:`CartanType_affine.special_node` + Implement :meth:`CartanType_affine.special_node`. The special node of the dual of an affine type `T` is the special node of `T`. diff --git a/src/sage/combinat/root_system/type_marked.py b/src/sage/combinat/root_system/type_marked.py index a9ca7d15a35..83d39c1a29f 100644 --- a/src/sage/combinat/root_system/type_marked.py +++ b/src/sage/combinat/root_system/type_marked.py @@ -23,7 +23,7 @@ class CartanType(cartan_type.CartanType_decorator): - ``ct`` -- a Cartan type - - ``marked_nodes`` -- a list of marked nodes + - ``marked_nodes`` -- list of marked nodes EXAMPLES: @@ -233,7 +233,7 @@ def _ascii_art_node(self, label): return self.options('marked_node_str') return 'O' - def _latex_draw_node(self, x, y, label, position="below=4pt", fill='white'): + def _latex_draw_node(self, x, y, label, position='below=4pt', fill='white'): r""" Draw (possibly marked [crossed out]) circular node ``i`` at the position ``(x,y)`` with node label ``label`` . @@ -357,7 +357,7 @@ def dynkin_diagram(self): def dual(self): """ - Implements + Implement :meth:`sage.combinat.root_system.cartan_type.CartanType_abstract.dual`, using that taking the dual and marking nodes are commuting operations. @@ -614,7 +614,7 @@ class CartanType_affine(CartanType, cartan_type.CartanType_affine): sage: TestSuite(L).run() """ - def _latex_draw_node(self, x, y, label, position="below=4pt"): + def _latex_draw_node(self, x, y, label, position='below=4pt'): r""" Draw the possibly marked (crossed out) circular node ``i`` at the position ``(x,y)`` with node label ``label`` . diff --git a/src/sage/combinat/root_system/type_reducible.py b/src/sage/combinat/root_system/type_reducible.py index a728535447e..53dadb9864d 100644 --- a/src/sage/combinat/root_system/type_reducible.py +++ b/src/sage/combinat/root_system/type_reducible.py @@ -33,7 +33,7 @@ class CartanType(SageObject, CartanType_abstract): INPUT: - - ``types`` -- a list of simple Cartan types + - ``types`` -- list of simple Cartan types EXAMPLES:: @@ -212,7 +212,7 @@ def component_types(self): def type(self): """ - Returns "reducible" since the type is reducible. + Return ``"reducible"`` since the type is reducible. EXAMPLES:: @@ -223,7 +223,7 @@ def type(self): def rank(self): """ - Returns the rank of self. + Return the rank of ``self``. EXAMPLES:: @@ -235,7 +235,7 @@ def rank(self): @cached_method def index_set(self): r""" - Implements :meth:`CartanType_abstract.index_set`. + Implement :meth:`CartanType_abstract.index_set`. For the moment, the index set is always of the form `\{1, \ldots, n\}`. @@ -276,7 +276,7 @@ def cartan_matrix(self, subdivide=True): def dynkin_diagram(self): """ - Returns a Dynkin diagram for type reducible. + Return a Dynkin diagram for type reducible. EXAMPLES:: @@ -298,7 +298,6 @@ def dynkin_diagram(self): O---O 5 6 F4xA2 - """ from .dynkin_diagram import DynkinDiagram_class relabelling = self._index_relabelling @@ -420,7 +419,7 @@ def dual(self): def is_affine(self): """ - Report that this reducible Cartan type is not affine + Report that this reducible Cartan type is not affine. EXAMPLES:: @@ -465,7 +464,6 @@ class AmbientSpace(ambient_space.AmbientSpace): sage: RootSystem("A2xB2").ambient_space() Ambient space of the Root system of type A2xB2 - """ def cartan_type(self): @@ -497,7 +495,7 @@ def dimension(self): def ambient_spaces(self): """ - Returns a list of the irreducible Cartan types of which the + Return a list of the irreducible Cartan types of which the given reducible Cartan type is a product. EXAMPLES:: @@ -509,14 +507,14 @@ def ambient_spaces(self): return [t.root_system().ambient_space() for t in self.component_types()] def inject_weights(self, i, v): - """ + r""" Produces the corresponding element of the lattice. INPUT: - - ``i`` -- an integer in range(self.components) + - ``i`` -- integer in ``range(self.components)`` - - ``v`` -- a vector in the i-th component weight lattice + - ``v`` -- a vector in the `i`-th component weight lattice EXAMPLES:: @@ -527,7 +525,7 @@ def inject_weights(self, i, v): [(1, 1, 0, 0, 0), (0, 0, 0, 1/2, 1/2)] """ shift = self.root_system.cartan_type()._shifts[i] - return self._from_dict( dict([(shift+k, c) for (k,c) in v ])) + return self._from_dict({shift + k: c for k, c in v}) @cached_method def simple_root(self, i): diff --git a/src/sage/combinat/root_system/type_relabel.py b/src/sage/combinat/root_system/type_relabel.py index d90e97cd375..27597563ae9 100644 --- a/src/sage/combinat/root_system/type_relabel.py +++ b/src/sage/combinat/root_system/type_relabel.py @@ -317,7 +317,7 @@ def ascii_art(self, label=None, node=None): def dynkin_diagram(self): """ - Returns the Dynkin diagram for this Cartan type. + Return the Dynkin diagram for this Cartan type. EXAMPLES:: @@ -358,7 +358,7 @@ def index_set(self): def dual(self): """ - Implements :meth:`sage.combinat.root_system.cartan_type.CartanType_abstract.dual`, + Implement :meth:`sage.combinat.root_system.cartan_type.CartanType_abstract.dual`, using that taking the dual and relabelling are commuting operations. EXAMPLES:: @@ -677,7 +677,6 @@ def classical(self): O---O---O---O 2 3 4 0 A4 relabelled by {1: 2, 2: 3, 3: 4, 4: 0} - """ return self._type.classical().relabel(self._relabelling) @@ -700,7 +699,7 @@ def basic_untwisted(self): def special_node(self): r""" - Returns a special node of the Dynkin diagram + Return a special node of the Dynkin diagram. .. SEEALSO:: :meth:`~sage.combinat.root_system.CartanType_affine.special_node` @@ -718,7 +717,7 @@ def special_node(self): def is_untwisted_affine(self): """ - Implement :meth:`CartanType_affine.is_untwisted_affine` + Implement :meth:`CartanType_affine.is_untwisted_affine`. A relabelled Cartan type is untwisted affine if the original is. @@ -726,6 +725,5 @@ def is_untwisted_affine(self): sage: CartanType(['B', 3, 1]).relabel({1:2, 2:3, 3:0, 0:1}).is_untwisted_affine() True - """ return self._type.is_untwisted_affine() diff --git a/src/sage/combinat/root_system/type_super_A.py b/src/sage/combinat/root_system/type_super_A.py index c2717a572ff..5ccb17e6a4e 100644 --- a/src/sage/combinat/root_system/type_super_A.py +++ b/src/sage/combinat/root_system/type_super_A.py @@ -43,7 +43,7 @@ def __init__(self, root_system, base_ring, index_set=None): sage: R = RootSystem(['A', [4,2]]) sage: AL = R.ambient_space(); AL Ambient space of the Root system of type ['A', [4, 2]] - sage: TestSuite(AL).run(skip="_test_norm_of_simple_roots") + sage: TestSuite(AL).run(skip='_test_norm_of_simple_roots') """ ct = root_system.cartan_type() if index_set is None: @@ -378,7 +378,7 @@ def associated_coroot(self): def has_descent(self, i, positive=False): """ Test if ``self`` has a descent at position `i`, that is - if ``self`` is on the strict negative side of the `i^{th}` + if ``self`` is on the strict negative side of the `i`-th simple reflection hyperplane. If ``positive`` is ``True``, tests if it is on the strict @@ -710,7 +710,7 @@ def relabel(self, relabelling): from . import type_relabel return type_relabel.CartanType(self, relabelling) - def _latex_draw_node(self, x, y, label, position="below=4pt"): + def _latex_draw_node(self, x, y, label, position='below=4pt'): r""" Draw (possibly marked [crossed out]) circular node ``i`` at the position ``(x,y)`` with node label ``label`` . diff --git a/src/sage/combinat/root_system/weight_lattice_realizations.py b/src/sage/combinat/root_system/weight_lattice_realizations.py index 8859b2135b5..17faf8bb914 100644 --- a/src/sage/combinat/root_system/weight_lattice_realizations.py +++ b/src/sage/combinat/root_system/weight_lattice_realizations.py @@ -25,11 +25,12 @@ from sage.categories.category_types import Category_over_base_ring from sage.sets.family import Family from .root_lattice_realizations import RootLatticeRealizations +from sage.rings.rational_field import QQ class WeightLatticeRealizations(Category_over_base_ring): r""" - The category of weight lattice realizations over a given base ring + The category of weight lattice realizations over a given base ring. A *weight lattice realization* `L` over a base ring `R` is a free module (or vector space if `R` is a field) endowed with an embedding @@ -132,14 +133,14 @@ class ParentMethods: @abstract_method def fundamental_weight(self, i): r""" - Returns the `i^{th}` fundamental weight + Return the `i`-th fundamental weight. INPUT: - ``i`` -- an element of the index set By a slight notational abuse, for an affine type this method - should also accept ``"delta"`` as input, and return the image + should also accept ``'delta'`` as input, and return the image of `\delta` of the extended weight lattice in this realization. @@ -168,7 +169,7 @@ def fundamental_weight(self, i): def is_extended(self): """ - Return whether this is a realization of the extended weight lattice + Return whether this is a realization of the extended weight lattice. .. SEEALSO:: :class:`sage.combinat.root_system.weight_space.WeightSpace` @@ -190,7 +191,7 @@ def is_extended(self): def __init_extra__(self): r""" - Registers the embedding of the weight lattice into ``self`` + Registers the embedding of the weight lattice into ``self``. Also registers the embedding of the weight space over the same base field `K` into ``self`` if `K` is not `\ZZ`. @@ -210,7 +211,7 @@ def __init_extra__(self): sage: L(Lambda[2]) (0, 1, -1, 0) - .. note:: + .. NOTE:: More examples are given in :class:`WeightLatticeRealizations`; The embeddings are systematically tested in @@ -235,7 +236,7 @@ def __init_extra__(self): def _test_weight_lattice_realization(self, **options): """ - Runs sanity checks on this weight lattice realization + Run sanity checks on this weight lattice realization. - scalar products between the fundamental weights and simple coroots - embeddings from the weight lattice and weight space @@ -306,7 +307,7 @@ def _test_weight_lattice_realization(self, **options): @cached_method def fundamental_weights(self): r""" - Returns the family `(\Lambda_i)_{i\in I}` of the fundamental weights. + Return the family `(\Lambda_i)_{i\in I}` of the fundamental weights. EXAMPLES:: @@ -322,7 +323,7 @@ def fundamental_weights(self): @cached_method def simple_root(self, i): r""" - Returns the `i`-th simple root + Return the `i`-th simple root. This default implementation takes the `i`-th simple root in the weight lattice and embeds it in ``self``. @@ -531,7 +532,7 @@ def reduced_word_of_alcove_morphism(self, f): def dynkin_diagram_automorphism_of_alcove_morphism(self, f): r""" - Return the Dynkin diagram automorphism induced by an alcove morphism + Return the Dynkin diagram automorphism induced by an alcove morphism. INPUT: @@ -662,11 +663,11 @@ def reduced_word_of_translation(self, t): def _test_reduced_word_of_translation(self, elements=None, **options): r""" - Tests the method :meth:`reduced_word_of_translation`. + Test the method :meth:`reduced_word_of_translation`. INPUT: - - ``options`` -- any keyword arguments accepted by :meth:`_tester`. + - ``options`` -- any keyword arguments accepted by :meth:`_tester` EXAMPLES:: @@ -769,7 +770,7 @@ def signs_of_alcovewalk(self, walk): simple coroot associated to `\alpha_{i_k}`. This function returns a list of the form `[+1,+1,-1,...]`, - where the `k^{th}` entry denotes whether the `k^{th}` step was + where the `k`-th entry denotes whether the `k`-th step was positive or negative. See equation 3.4, of Ram: Alcove walks ..., :arxiv:`math/0601343v1` @@ -846,7 +847,7 @@ def rho_classical(self): def embed_at_level(self, x, level=1): r""" - Embed the classical weight `x` in the level ``level`` hyperplane + Embed the classical weight `x` in the level ``level`` hyperplane. This is achieved by translating the straightforward embedding of `x` by `c\Lambda_0` for `c` some appropriate @@ -855,7 +856,7 @@ def embed_at_level(self, x, level=1): INPUT: - ``x`` -- an element of the corresponding classical weight/ambient lattice - - ``level`` -- an integer or element of the base ring (default: 1) + - ``level`` -- integer or element of the base ring (default: 1) EXAMPLES:: @@ -908,6 +909,25 @@ def weyl_dimension(self, highest_weight): d = prod((rho.scalar(x) for x in pr), Integer(1)) return Integer(n/d) + @lazy_attribute + def _inverse_cartan_matrix(self): + r""" + Return the inverse Cartan matrix defining ``self``. + + EXAMPLES:: + + sage: RootSystem(['A', 3]).ambient_lattice()._inverse_cartan_matrix + [3/4 1/2 1/4] + [1/2 1 1/2] + [1/4 1/2 3/4] + sage: RootSystem(['G', 2]).weight_lattice()._inverse_cartan_matrix + [2 3] + [1 2] + """ + ret = self.cartan_type().cartan_matrix().inverse() + ret.set_immutable() + return ret + @lazy_attribute def _symmetric_form_matrix(self): r""" @@ -953,14 +973,13 @@ def _symmetric_form_matrix(self): [ 0 2 2 1] [ 0 2 4 1] [1/2 1 1 0] - """ from sage.matrix.constructor import matrix ct = self.cartan_type() cm = ct.cartan_matrix() if cm.det() != 0: diag = matrix.diagonal(cm.symmetrizer()) - return cm.inverse().transpose() * diag + return self._inverse_cartan_matrix.transpose() * diag if not ct.is_affine(): raise ValueError("only implemented for affine types when the" @@ -1080,7 +1099,6 @@ def symmetric_form(self, la): sage: all(s1(ct) == s2(ct) # needs sage.graphs ....: for ct in CartanType.samples(finite=True, crystallographic=True)) True - """ P = self.parent() ct = P.cartan_type() @@ -1131,4 +1149,37 @@ def to_weight_space(self, base_ring=None): if base_ring is None: base_ring = L.base_ring() - return L.root_system.weight_space(base_ring).sum_of_terms([i, base_ring(self.scalar(L.simple_coroot(i)))] for i in L.cartan_type().index_set()) + wt_space = L.root_system.weight_space(base_ring) + simple_coroots = L.simple_coroots() + return wt_space.sum_of_terms(((i, base_ring(self.scalar(ac))) + for i, ac in simple_coroots.items()), + distinct=True) + + @cached_method + def _to_root_vector(self): + r""" + Helper method to express ``self`` as a linear combination + of simple roots. + + OUTPUT: + + A list with entries in `\QQ` representing ``self`` as a linear + combination of simple roots. + + EXAMPLES:: + + sage: L = RootSystem(['A', 3]).ambient_space() + sage: e = L.basis() + sage: (e[0] + 3*e[3])._to_root_vector() # not in the root space + sage: (e[0] - e[1])._to_root_vector() + (1, 0, 0) + sage: (e[0] + 2*e[1] - 3*e[2])._to_root_vector() + (1, 3, 0) + """ + v = self.to_vector().change_ring(QQ) + al = [a.to_vector() for a in self.parent().simple_roots()] + b = v.parent().linear_dependence([v] + al) + if len(b) != 1 or b[0] == 0: + return None + b = b[0] # Get the actual vector that gives the linear dependency + return b[1:].change_ring(QQ) / -b[0] diff --git a/src/sage/combinat/root_system/weight_space.py b/src/sage/combinat/root_system/weight_space.py index 3df5449c7bd..3dbaa0740e8 100644 --- a/src/sage/combinat/root_system/weight_space.py +++ b/src/sage/combinat/root_system/weight_space.py @@ -21,7 +21,7 @@ class WeightSpace(CombinatorialFreeModule): - ``root_system`` -- a root system - ``base_ring`` -- a ring `R` - - ``extended`` -- a boolean (default: ``False``) + - ``extended`` -- boolean (default: ``False``) The weight space (or lattice if ``base_ring`` is `\ZZ`) of a root system is the formal free module `\bigoplus_i R \Lambda_i` @@ -145,7 +145,7 @@ class WeightSpace(CombinatorialFreeModule): @staticmethod def __classcall_private__(cls, root_system, base_ring, extended=False): """ - Guarantees Unique representation + Guarantee Unique representation. .. SEEALSO:: :class:`UniqueRepresentation` @@ -230,7 +230,6 @@ def _repr_(self): Coweight lattice of the Root system of type ['A', 4] sage: RootSystem(['B',4]).coweight_space() Coweight space over the Rational Field of the Root system of type ['B', 4] - """ return self._name_string() @@ -248,14 +247,14 @@ def _name_string(self, capitalize=True, base_ring=True, type=True): @cached_method def fundamental_weight(self, i): r""" - Returns the `i`-th fundamental weight + Return the `i`-th fundamental weight. INPUT: - - ``i`` -- an element of the index set or ``"delta"`` + - ``i`` -- an element of the index set or ``'delta'`` By a slight notational abuse, for an affine type this method - also accepts ``"delta"`` as input, and returns the image of + also accepts ``'delta'`` as input, and returns the image of `\delta` of the extended weight lattice in this realization. .. SEEALSO:: :meth:`~sage.combinat.root_system.weight_lattice_realization.ParentMethods.fundamental_weight` @@ -287,7 +286,7 @@ def fundamental_weight(self, i): @cached_method def basis_extension(self): r""" - Return the basis elements used to extend the fundamental weights + Return the basis elements used to extend the fundamental weights. EXAMPLES:: @@ -313,7 +312,7 @@ def basis_extension(self): @cached_method def simple_root(self, j): r""" - Returns the `j^{th}` simple root + Return the `j`-th simple root. EXAMPLES:: @@ -371,7 +370,7 @@ def simple_root(self, j): def _repr_term(self, m): r""" - Customized monomial printing for extended weight lattices + Customized monomial printing for extended weight lattices. EXAMPLES:: @@ -389,7 +388,7 @@ def _repr_term(self, m): def _latex_term(self, m): r""" - Customized monomial typesetting for extended weight lattices + Customized monomial typesetting for extended weight lattices. EXAMPLES:: @@ -515,9 +514,9 @@ def scalar(self, lambdacheck): return sum( (self[i]*c for (i,c) in lambdacheck), zero) def is_dominant(self): - """ - Checks whether an element in the weight space lies in the positive cone spanned - by the basis elements (fundamental weights). + r""" + Check whether an element in the weight space lies in the positive + cone spanned by the basis elements (fundamental weights). EXAMPLES:: @@ -530,9 +529,9 @@ def is_dominant(self): sage: w.is_dominant() False - In the extended affine weight lattice, 'delta' is orthogonal to + In the extended affine weight lattice, ``'delta'`` is orthogonal to the positive coroots, so adding or subtracting it should not - affect dominance :: + affect dominance:: sage: P = RootSystem(['A',2,1]).weight_lattice(extended=true) sage: Lambda = P.fundamental_weights() @@ -540,13 +539,47 @@ def is_dominant(self): sage: w = Lambda[1] - delta # needs sage.graphs sage: w.is_dominant() # needs sage.graphs True + """ + index_set = set(self.parent().index_set()) + return all(c >= 0 for i, c in self._monomial_coefficients.items() if i in index_set) + def is_dominant_weight(self): + r""" + Check whether an element in the weight space lies in the positive + `\ZZ`-lattice cone spanned by the basis elements (fundamental weights). + + EXAMPLES:: + + sage: W = RootSystem(['A',3]).weight_space() + sage: Lambda = W.basis() + sage: w = Lambda[1] + Lambda[3] + sage: w.is_dominant_weight() + True + sage: w = Lambda[1] + 2/3*Lambda[3] + sage: w.is_dominant_weight() + False + sage: w = Lambda[1] - Lambda[2] + sage: w.is_dominant_weight() + False + + In the extended affine weight lattice, ``'delta'`` is orthogonal to + the positive coroots, so adding or subtracting it should not + affect dominance:: + + sage: P = RootSystem(['A',2,1]).weight_lattice(extended=true) + sage: Lambda = P.fundamental_weights() + sage: delta = P.null_root() # needs sage.graphs + sage: w = Lambda[1] - delta # needs sage.graphs + sage: w.is_dominant_weight() # needs sage.graphs + True """ - return all(self.coefficient(i) >= 0 for i in self.parent().index_set()) + index_set = set(self.parent().index_set()) + from sage.rings.integer_ring import ZZ + return all(c in ZZ and c >= 0 for i, c in self._monomial_coefficients.items() if i in index_set) def to_ambient(self): r""" - Maps ``self`` to the ambient space. + Map ``self`` to the ambient space. EXAMPLES:: @@ -560,7 +593,6 @@ def to_ambient(self): Only implemented in finite Cartan type. Does not work for coweight lattices because there is no implemented map from the coweight lattice to the ambient space. - """ return self.parent().to_ambient_space_morphism()(self) @@ -580,5 +612,27 @@ def to_weight_space(self): """ return self + @cached_method + def _to_root_vector(self): + r""" + Helper method to express ``self`` as a linear combination + of simple roots. + + OUTPUT: + + A vector with entries in `\QQ` representing ``self`` as a linear + combination of simple roots. + + EXAMPLES:: + + sage: P = RootSystem(['A',3]).weight_lattice() + sage: La = P.fundamental_weights() + sage: [al._to_root_vector() for al in P.simple_roots()] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] + sage: (La[1] + La[2])._to_root_vector() + (5/4, 3/2, 3/4) + """ + return self.parent()._inverse_cartan_matrix * self.to_vector() + WeightSpace.Element = WeightSpaceElement diff --git a/src/sage/combinat/root_system/weyl_characters.py b/src/sage/combinat/root_system/weyl_characters.py index a42929606b1..d7f87d6f494 100644 --- a/src/sage/combinat/root_system/weyl_characters.py +++ b/src/sage/combinat/root_system/weyl_characters.py @@ -67,7 +67,7 @@ class WeylCharacterRing(CombinatorialFreeModule): sage: L = RootSystem("A2").ambient_space() sage: [fw1,fw2] = L.fundamental_weights() - sage: R = WeylCharacterRing(['A',2], prefix="R") + sage: R = WeylCharacterRing(['A',2], prefix='R') sage: [R(1),R(fw1),R(fw2)] [R(0,0,0), R(1,0,0), R(1,1,0)] @@ -93,11 +93,11 @@ class WeylCharacterRing(CombinatorialFreeModule): https://doc.sagemath.org/html/en/thematic_tutorials/lie.html """ @staticmethod - def __classcall__(cls, ct, base_ring=ZZ, prefix=None, style="lattice", k=None, conjugate=False, cyclotomic_order=None, fusion_labels=None, inject_variables=False): + def __classcall__(cls, ct, base_ring=ZZ, prefix=None, style='lattice', k=None, conjugate=False, cyclotomic_order=None, fusion_labels=None, inject_variables=False): """ TESTS:: - sage: R = WeylCharacterRing("G2", style="coroots") + sage: R = WeylCharacterRing("G2", style='coroots') sage: R.cartan_type() is CartanType("G2") True sage: R.base_ring() is ZZ @@ -111,7 +111,7 @@ def __classcall__(cls, ct, base_ring=ZZ, prefix=None, style="lattice", k=None, c prefix = repr(ct) return super().__classcall__(cls, ct, base_ring=base_ring, prefix=prefix, style=style, k=k, conjugate=conjugate, cyclotomic_order=cyclotomic_order, fusion_labels=fusion_labels, inject_variables=inject_variables) - def __init__(self, ct, base_ring=ZZ, prefix=None, style="lattice", k=None, conjugate=False, cyclotomic_order=None, fusion_labels=None, inject_variables=False): + def __init__(self, ct, base_ring=ZZ, prefix=None, style='lattice', k=None, conjugate=False, cyclotomic_order=None, fusion_labels=None, inject_variables=False): """ EXAMPLES:: @@ -152,7 +152,7 @@ def __init__(self, ct, base_ring=ZZ, prefix=None, style="lattice", k=None, conju def next_level(wt): return [wt + la for la in fw if self.level(wt + la) <= k] B = list(RecursivelyEnumeratedSet([self._space.zero()], next_level)) - B = [self._space.from_vector_notation(wt, style="coroots") for wt in B] + B = [self._space.from_vector_notation(wt, style='coroots') for wt in B] else: B = self._space @@ -274,7 +274,7 @@ def demazure_character(self, hwv, word, debug=False): EXAMPLES:: - sage: A2 = WeylCharacterRing("A2",style="coroots") + sage: A2 = WeylCharacterRing("A2",style='coroots') sage: h = sum(A2.fundamental_weights()); h (2, 1, 0) sage: A2.demazure_character(h,word=[1,2]) @@ -284,7 +284,7 @@ def demazure_character(self, hwv, word, debug=False): """ if self._style != "coroots": raise ValueError('demazure method unavailable: use style="coroots"') - hwv = self._space.from_vector_notation(hwv, style="coroots") + hwv = self._space.from_vector_notation(hwv, style='coroots') return self.ambient()._from_dict(self._demazure_weights(hwv, word=word, debug=debug)) @lazy_attribute @@ -323,7 +323,7 @@ def lift(self): def _retract(self, chi): """ - Construct a Weyl character from an invariant element of the weight ring + Construct a Weyl character from an invariant element of the weight ring. INPUT: @@ -446,12 +446,11 @@ def __call__(self, *args): [-2*A2(0,0,0), -A2(0,0,0), 0, A2(0,0,0), 2*A2(0,0,0), -2*q*A2(0,0,0), -q*A2(0,0,0), q*A2(0,0,0), 2*q*A2(0,0,0), (-q+1)*A2(0,0,0)] sage: R. = ZZ[] - sage: A2 = WeylCharacterRing(['A',2], base_ring = R, style="coroots") + sage: A2 = WeylCharacterRing(['A',2], base_ring = R, style='coroots') sage: q*A2(1) q*A2(0,0) sage: [A2(x) for x in [-2,-1,0,1,2,-2*q,-q,q,2*q,(1-q)]] [-2*A2(0,0), -A2(0,0), 0, A2(0,0), 2*A2(0,0), -2*q*A2(0,0), -q*A2(0,0), q*A2(0,0), 2*q*A2(0,0), (-q+1)*A2(0,0)] - """ # The purpose of this __call__ method is only to handle the # syntactical shorthand; otherwise it just delegates the work @@ -520,7 +519,7 @@ def _product_helper(self, d1, b): INPUT: - - ``d1`` -- a dictionary of weight multiplicities + - ``d1`` -- dictionary of weight multiplicities - ``b`` -- a dominant weight If ``d1`` is the dictionary of weight multiplicities of a character, @@ -665,9 +664,9 @@ def _irr_weights(self, hwv): else: return irreducible_character_freudenthal(hwv) - def _demazure_weights(self, hwv, word="long", debug=False): + def _demazure_weights(self, hwv, word='long', debug=False): """ - Computes the weights of a Demazure character. + Compute the weights of a Demazure character. This method duplicates the functionality of :meth:`_irr_weights`, under the assumption that ``style = "coroots"``, but allows an optional @@ -683,7 +682,7 @@ def _demazure_weights(self, hwv, word="long", debug=False): EXAMPLES:: - sage: B2 = WeylCharacterRing("B2", style="coroots") + sage: B2 = WeylCharacterRing("B2", style='coroots') sage: [B2._demazure_weights(v, word=[1,2]) for v in B2.fundamental_weights()] [{(1, 0): 1, (0, 1): 1}, {(-1/2, 1/2): 1, (1/2, -1/2): 1, (1/2, 1/2): 1}] """ @@ -694,7 +693,7 @@ def _demazure_weights(self, hwv, word="long", debug=False): dd[h] = 1 return self._demazure_helper(dd, word=word, debug=debug) - def _demazure_helper(self, dd, word="long", debug=False): + def _demazure_helper(self, dd, word='long', debug=False): r""" Assumes ``style = "coroots"``. If the optional parameter ``word`` is specified, produces a Demazure character (defaults to the long Weyl @@ -702,13 +701,13 @@ def _demazure_helper(self, dd, word="long", debug=False): INPUT: - - ``dd`` -- a dictionary of weights + - ``dd`` -- dictionary of weights - ``word`` -- (optional) a Weyl group reduced word EXAMPLES:: - sage: A2 = WeylCharacterRing("A2",style="coroots") + sage: A2 = WeylCharacterRing("A2",style='coroots') sage: dd = {}; dd[(1,1)]=int(1) sage: A2._demazure_helper(dd,word=[1,2]) {(0, 0, 0): 1, (-1, 1, 0): 1, (1, -1, 0): 1, (1, 0, -1): 1, (0, 1, -1): 1} @@ -768,7 +767,7 @@ def _demazure_helper(self, dd, word="long", debug=False): ret = {} for v in accum: if accum[v]: - ret[self._space.from_vector_notation(v, style="coroots")] = accum[v] + ret[self._space.from_vector_notation(v, style='coroots')] = accum[v] return ret @cached_method @@ -779,7 +778,7 @@ def _weight_multiplicities(self, x): EXAMPLES:: - sage: B2 = WeylCharacterRing("B2",style="coroots") + sage: B2 = WeylCharacterRing("B2",style='coroots') sage: chi = 2*B2(1,0) sage: B2._weight_multiplicities(chi) {(0, 0): 2, (-1, 0): 2, (1, 0): 2, (0, -1): 2, (0, 1): 2} @@ -822,7 +821,7 @@ def irr_repr(self, hwv): sage: B3 = WeylCharacterRing("B3") sage: [B3.irr_repr(v) for v in B3.fundamental_weights()] ['B3(1,0,0)', 'B3(1,1,0)', 'B3(1/2,1/2,1/2)'] - sage: B3 = WeylCharacterRing("B3", style="coroots") + sage: B3 = WeylCharacterRing("B3", style='coroots') sage: [B3.irr_repr(v) for v in B3.fundamental_weights()] ['B3(1,0,0)', 'B3(0,1,0)', 'B3(0,0,1)'] """ @@ -876,7 +875,7 @@ def _wt_repr(self, wt): ((1, 0, -1), (2, -1, -1)) sage: [WeylCharacterRing("G2")._wt_repr(v) for v in [fw1,fw2]] ['(1,0,-1)', '(2,-1,-1)'] - sage: [WeylCharacterRing("G2",style="coroots")._wt_repr(v) for v in [fw1,fw2]] + sage: [WeylCharacterRing("G2",style='coroots')._wt_repr(v) for v in [fw1,fw2]] ['(1,0)', '(0,1)'] """ if self._style == "lattice": @@ -1034,7 +1033,7 @@ def char_from_weights(self, mdict): INPUT: - - ``mdict`` -- a dictionary mapping weights to coefficients, + - ``mdict`` -- dictionary mapping weights to coefficients, and representing a linear combination of weights which shall be invariant under the action of the Weyl group @@ -1063,7 +1062,7 @@ def _char_from_weights(self, mdict): INPUT: - - ``mdict`` -- a dictionary of weight multiplicities + - ``mdict`` -- dictionary of weight multiplicities The output of this method is a dictionary whose keys are dominant weights that is the same as the :meth:`monomial_coefficients` method @@ -1105,7 +1104,7 @@ def adjoint_representation(self): EXAMPLES:: - sage: G2 = WeylCharacterRing("G2",style="coroots") + sage: G2 = WeylCharacterRing("G2",style='coroots') sage: G2.adjoint_representation() G2(0,1) """ @@ -1159,7 +1158,7 @@ def maximal_subgroups(self): another different one may be obtained by composing it with the triality automorphism of `D_4`:: - sage: [D4,A1xC2]=[WeylCharacterRing(x,style="coroots") for x in ["D4","A1xC2"]] + sage: [D4,A1xC2]=[WeylCharacterRing(x,style='coroots') for x in ["D4","A1xC2"]] sage: fw = D4.fundamental_weights() sage: b = D4.maximal_subgroup("A1xC2") sage: [D4(fw).branch(A1xC2,rule=b) for fw in D4.fundamental_weights()] @@ -1182,7 +1181,7 @@ def maximal_subgroup(self, ct): INPUT: - - ``ct`` -- the Cartan type of a maximal subgroup of ``self``. + - ``ct`` -- the Cartan type of a maximal subgroup of ``self`` In rare cases where there is more than one maximal subgroup (up to outer automorphisms) @@ -1198,7 +1197,7 @@ def maximal_subgroup(self, ct): For more information, see the related method :meth:`maximal_subgroups`. """ - return sage.combinat.root_system.branching_rules.maximal_subgroups(self.cartan_type(), mode="get_rule")[ct] + return sage.combinat.root_system.branching_rules.maximal_subgroups(self.cartan_type(), mode='get_rule')[ct] class Element(CombinatorialFreeModule.Element): """ @@ -1232,7 +1231,7 @@ def degree(self): L = self.parent()._space return sum(L.weyl_dimension(k) * c for k, c in self) - def branch(self, S, rule="default"): + def branch(self, S, rule='default'): """ Return the restriction of the character to the subalgebra. @@ -1242,7 +1241,7 @@ def branch(self, S, rule="default"): - ``S`` -- a Weyl character ring for a Lie subgroup or subalgebra - - ``rule`` -- a branching rule + - ``rule`` -- a branching rule See :func:`~sage.combinat.root_system.branching_rules.branch_weyl_character` for more information about branching rules. @@ -1251,7 +1250,7 @@ def branch(self, S, rule="default"): sage: B3 = WeylCharacterRing(['B',3]) sage: A2 = WeylCharacterRing(['A',2]) - sage: [B3(w).branch(A2,rule="levi") for w in B3.fundamental_weights()] + sage: [B3(w).branch(A2,rule='levi') for w in B3.fundamental_weights()] [A2(0,0,0) + A2(1,0,0) + A2(0,0,-1), A2(0,0,0) + A2(1,0,0) + A2(1,1,0) + A2(1,0,-1) + A2(0,-1,-1) + A2(0,0,-1), A2(-1/2,-1/2,-1/2) + A2(1/2,-1/2,-1/2) + A2(1/2,1/2,-1/2) + A2(1/2,1/2,1/2)] @@ -1266,7 +1265,7 @@ def dual(self): EXAMPLES:: - sage: A3 = WeylCharacterRing("A3", style="coroots") + sage: A3 = WeylCharacterRing("A3", style='coroots') sage: A3(1,0,0)^2 A3(0,1,0) + A3(2,0,0) sage: (A3(1,0,0)^2).dual() @@ -1288,7 +1287,7 @@ def highest_weight(self): EXAMPLES:: - sage: G2 = WeylCharacterRing("G2", style="coroots") + sage: G2 = WeylCharacterRing("G2", style='coroots') sage: [x.highest_weight() for x in [G2(1,0),G2(0,1)]] [(1, 0, -1), (2, -1, -1)] """ @@ -1298,7 +1297,7 @@ def highest_weight(self): def __pow__(self, n): """ - Return the n-th power of ``self``. + Return the `n`-th power of ``self``. We override the method in :mod:`sage.monoids.monoids` since using the Brauer-Klimyk algorithm, it is more efficient to @@ -1306,7 +1305,7 @@ def __pow__(self, n): EXAMPLES:: - sage: B4 = WeylCharacterRing("B4",style="coroots") + sage: B4 = WeylCharacterRing("B4",style='coroots') sage: spin = B4(0,0,0,1) sage: [spin^k for k in [0,1,3]] [B4(0,0,0,0), B4(0,0,0,1), 5*B4(0,0,0,1) + 4*B4(1,0,0,1) + 3*B4(0,1,0,1) + 2*B4(0,0,1,1) + B4(0,0,0,3)] @@ -1352,7 +1351,7 @@ def symmetric_power(self, k): INPUT: - - `k` -- a nonnegative integer + - ``k`` -- nonnegative integer The algorithm is based on the identity `k h_k = \sum_{r=1}^k p_k h_{k-r}` relating the power-sum @@ -1364,7 +1363,7 @@ def symmetric_power(self, k): EXAMPLES:: - sage: B3 = WeylCharacterRing("B3",style="coroots") + sage: B3 = WeylCharacterRing("B3",style='coroots') sage: spin = B3(0,0,1) sage: spin.symmetric_power(6) B3(0,0,0) + B3(0,0,2) + B3(0,0,4) + B3(0,0,6) @@ -1390,7 +1389,7 @@ def exterior_power(self, k): INPUT: - - ``k`` -- a nonnegative integer + - ``k`` -- nonnegative integer The algorithm is based on the identity `k e_k = \sum_{r=1}^k (-1)^{k-1} p_k e_{k-r}` relating the @@ -1402,7 +1401,7 @@ def exterior_power(self, k): EXAMPLES:: - sage: B3 = WeylCharacterRing("B3",style="coroots") + sage: B3 = WeylCharacterRing("B3",style='coroots') sage: spin = B3(0,0,1) sage: spin.exterior_power(6) B3(1,0,0) + B3(0,1,0) @@ -1431,7 +1430,7 @@ def adams_operator(self, r): INPUT: - - ``r`` -- a positive integer + - ``r`` -- positive integer This is a virtual character, whose weights are the weights of ``self``, each multiplied by `r`. @@ -1452,7 +1451,7 @@ def _adams_operator_helper(self, r): INPUT: - - ``r`` -- a positive integer + - ``r`` -- positive integer Return the dictionary of weight multiplicities for the Adams operation, needed for internal use by symmetric and exterior powers. @@ -1472,7 +1471,7 @@ def symmetric_square(self): EXAMPLES:: - sage: A2 = WeylCharacterRing("A2",style="coroots") + sage: A2 = WeylCharacterRing("A2",style='coroots') sage: A2(1,0).symmetric_square() A2(2,0) """ @@ -1509,7 +1508,7 @@ def exterior_square(self): EXAMPLES:: - sage: A2 = WeylCharacterRing("A2",style="coroots") + sage: A2 = WeylCharacterRing("A2",style='coroots') sage: A2(1,0).exterior_square() A2(0,1) """ @@ -1559,7 +1558,7 @@ def frobenius_schur_indicator(self): EXAMPLES:: - sage: B2 = WeylCharacterRing("B2",style="coroots") + sage: B2 = WeylCharacterRing("B2",style='coroots') sage: B2(1,0).frobenius_schur_indicator() 1 sage: B2(0,1).frobenius_schur_indicator() @@ -1583,7 +1582,7 @@ def weight_multiplicities(self): EXAMPLES:: - sage: B2 = WeylCharacterRing("B2",style="coroots") + sage: B2 = WeylCharacterRing("B2",style='coroots') sage: B2(0,1).weight_multiplicities() {(-1/2, -1/2): 1, (-1/2, 1/2): 1, (1/2, -1/2): 1, (1/2, 1/2): 1} """ @@ -1624,7 +1623,7 @@ def invariant_degree(self): EXAMPLES:: - sage: A2 = WeylCharacterRing("A2",style="coroots") + sage: A2 = WeylCharacterRing("A2",style='coroots') sage: rep = A2(1,0)^2*A2(0,1)^2; rep 2*A2(0,0) + A2(0,3) + 4*A2(1,1) + A2(3,0) + A2(2,2) sage: rep.invariant_degree() @@ -1642,7 +1641,7 @@ def multiplicity(self, other): EXAMPLES:: - sage: B2 = WeylCharacterRing("B2",style="coroots") + sage: B2 = WeylCharacterRing("B2",style='coroots') sage: rep = B2(1,1)^2; rep B2(0,0) + B2(1,0) + 2*B2(0,2) + B2(2,0) + 2*B2(1,2) + B2(0,4) + B2(3,0) + B2(2,2) sage: rep.multiplicity(B2(0,2)) @@ -1669,7 +1668,7 @@ def irreducible_character_freudenthal(hwv, debug=False): INPUT: - - ``hwv`` -- a dominant weight in a weight lattice. + - ``hwv`` -- a dominant weight in a weight lattice - ``L`` -- the ambient space @@ -1755,7 +1754,7 @@ def __classcall__(cls, parent, prefix=None): """ TESTS:: - sage: A3 = WeylCharacterRing("A3", style="coroots") + sage: A3 = WeylCharacterRing("A3", style='coroots') sage: a3 = WeightRing(A3) sage: a3.cartan_type(), a3.base_ring(), a3.parent() (['A', 3], Integer Ring, The Weyl Character Ring of Type A3 with Integer Ring coefficients) @@ -1824,7 +1823,7 @@ def __call__(self, *args): you may give a tuple of integers. Normally these are the components of the vector in the standard realization of the weight lattice as a vector space. Alternatively, if - the ring is constructed with style="coroots", you may + the ring is constructed with style='coroots', you may specify the weight by giving a set of integers, one for each fundamental weight; the weight is then the linear combination of the fundamental weights with these coefficients. @@ -1853,7 +1852,7 @@ def _element_constructor_(self, weight): INPUT: - - ``weight`` -- an element of the weight space, or a tuple + - ``weight`` -- an element of the weight space, or a tuple This method is responsible for constructing an appropriate weight from the data in ``weight``, and then return the @@ -2010,7 +2009,7 @@ def wt_repr(self, wt): sage: G2 = WeylCharacterRing("G2") sage: [G2.ambient().wt_repr(x) for x in G2.fundamental_weights()] ['g2(1,0,-1)', 'g2(2,-1,-1)'] - sage: G2 = WeylCharacterRing("G2",style="coroots") + sage: G2 = WeylCharacterRing("G2",style='coroots') sage: [G2.ambient().wt_repr(x) for x in G2.fundamental_weights()] ['g2(1,0)', 'g2(0,1)'] """ @@ -2089,11 +2088,11 @@ def scale(self, k): INPUT: - - ``k`` -- a nonzero integer + - ``k`` -- nonzero integer EXAMPLES:: - sage: g2 = WeylCharacterRing("G2",style="coroots").ambient() + sage: g2 = WeylCharacterRing("G2",style='coroots').ambient() sage: g2(2,3).scale(2) g2(4,6) """ @@ -2115,7 +2114,7 @@ def shift(self, mu): EXAMPLES:: - sage: g2 = WeylCharacterRing("G2",style="coroots").ambient() + sage: g2 = WeylCharacterRing("G2",style='coroots').ambient() sage: [g2(1,2).shift(fw) for fw in g2.fundamental_weights()] [g2(2,2), g2(1,3)] """ @@ -2145,7 +2144,7 @@ def demazure(self, w, debug=False): EXAMPLES:: - sage: B2 = WeylCharacterRing("B2",style="coroots") + sage: B2 = WeylCharacterRing("B2",style='coroots') sage: b2 = WeightRing(B2) sage: b2(1,0).demazure([1]) b2(1,0) + b2(-1,2) @@ -2205,7 +2204,7 @@ def demazure_lusztig(self, i, v): EXAMPLES:: sage: P. = PolynomialRing(QQ) - sage: B2 = WeylCharacterRing("B2",style="coroots",base_ring=P); b2 = B2.ambient() + sage: B2 = WeylCharacterRing("B2",style='coroots',base_ring=P); b2 = B2.ambient() sage: def T1(f): return f.demazure_lusztig(1,v) sage: def T2(f): return f.demazure_lusztig(2,v) sage: T1(T2(T1(T2(b2(1,-1))))) @@ -2220,13 +2219,13 @@ def demazure_lusztig(self, i, v): sage: b2(1,0).demazure_lusztig([2,1],v)==T2(T1(b2(1,0))) True - sage: W = B2.space().weyl_group(prefix="s") + sage: W = B2.space().weyl_group(prefix='s') sage: [s1,s2]=W.simple_reflections() sage: b2(1,0).demazure_lusztig(s2*s1,v)==T2(T1(b2(1,0))) True """ if i in self.parent().space().index_set(): - rho = self.parent().space().from_vector_notation(self.parent().space().rho(), style="coroots") + rho = self.parent().space().from_vector_notation(self.parent().space().rho(), style='coroots') inv = self.scale(-1) return (-inv.shift(-rho).demazure([i]).shift(rho) + v * inv.demazure([i])).scale(-1) elif isinstance(i, list): diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index ab57e910d55..7751520ca79 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -79,7 +79,7 @@ def WeylGroup(x, prefix=None, implementation='matrix'): - ``implementation`` -- one of the following: * ``'matrix'`` -- as matrices acting on a root system - * ``"permutation"`` -- as a permutation group acting on the roots + * ``'permutation'`` -- as a permutation group acting on the roots EXAMPLES: @@ -122,7 +122,7 @@ def WeylGroup(x, prefix=None, implementation='matrix'): :: - sage: W=WeylGroup("C3",prefix="s") + sage: W=WeylGroup("C3",prefix='s') sage: [s1,s2,s3]=W.simple_reflections() # lets Sage parse its own output sage: s2*s1*s2*s3 s1*s2*s3*s1 @@ -346,7 +346,6 @@ def simple_reflections(self): True sage: type(w) == W.element_class True - """ return self.domain().simple_reflections().map(self.from_morphism) @@ -368,13 +367,13 @@ def reflections(self): EXAMPLES:: - sage: W = WeylGroup("B2", prefix="s") + sage: W = WeylGroup("B2", prefix='s') sage: refdict = W.reflections(); refdict Finite family {(1, -1): s1, (0, 1): s2, (1, 1): s2*s1*s2, (1, 0): s1*s2*s1} sage: [r+refdict[r].action(r) for r in refdict.keys()] [(0, 0), (0, 0), (0, 0), (0, 0)] - sage: W = WeylGroup(['A',2,1], prefix="s") + sage: W = WeylGroup(['A',2,1], prefix='s') sage: W.reflections() Lazy family (real root to reflection(i))_{i in Positive real roots of type ['A', 2, 1]} @@ -476,7 +475,7 @@ def domain(self): def simple_reflection(self, i): """ - Return the `i^{th}` simple reflection. + Return the `i`-th simple reflection. EXAMPLES:: @@ -575,7 +574,7 @@ def classical(self): class ClassicalWeylSubgroup(WeylGroup_gens): """ - A class for Classical Weyl Subgroup of an affine Weyl Group + A class for Classical Weyl Subgroup of an affine Weyl Group. EXAMPLES:: @@ -656,7 +655,7 @@ def __repr__(self): type=False) return "Parabolic Subgroup of the Weyl Group of type %s (as a matrix group acting on the %s)" % (self.domain().cartan_type(), domain) - def weyl_group(self, prefix="hereditary"): + def weyl_group(self, prefix='hereditary'): """ Return the Weyl group associated to the parabolic subgroup. @@ -675,7 +674,7 @@ def weyl_group(self, prefix="hereditary"): def _test_is_finite(self, **options): """ - Tests some internal invariants + Test some internal invariants. EXAMPLES:: @@ -736,7 +735,7 @@ def _repr_(self): """ EXAMPLES:: - sage: W = WeylGroup(['A',2,1], prefix="s") + sage: W = WeylGroup(['A',2,1], prefix='s') sage: [s0,s1,s2] = W.simple_reflections() sage: s0*s1 s0*s1 @@ -764,7 +763,7 @@ def _latex_(self): EXAMPLES:: - sage: W = WeylGroup(['A',2,1], prefix="s") + sage: W = WeylGroup(['A',2,1], prefix='s') sage: [s0,s1,s2] = W.simple_reflections() sage: latex(s0*s1) # indirect doctest s_{0}s_{1} @@ -824,7 +823,7 @@ def _richcmp_(self, other, op): def action(self, v): """ - Return the action of self on the vector v. + Return the action of ``self`` on the vector `v`. EXAMPLES:: @@ -856,12 +855,12 @@ def action(self, v): # Descents # ####################################################################### - def has_descent(self, i, positive=False, side="right") -> bool: + def has_descent(self, i, positive=False, side='right') -> bool: """ Test if ``self`` has a descent at position ``i``. An element `w` has a descent in position `i` if `w` is - on the strict negative side of the `i^{th}` simple reflection + on the strict negative side of the `i`-th simple reflection hyperplane. If ``positive`` is ``True``, tests if it is on the strict @@ -946,7 +945,7 @@ def has_left_descent(self, i): sage: [(s[3]*s[2]).has_left_descent(i) for i in W.domain().index_set()] [False, False, True] """ - return self.has_descent(i, side="left") + return self.has_descent(i, side='left') def has_right_descent(self, i): """ @@ -967,9 +966,9 @@ def has_right_descent(self, i): sage: [(s[3]*s[2]).has_right_descent(i) for i in W.domain().index_set()] [False, True, False] """ - return self.has_descent(i, side="right") + return self.has_descent(i, side='right') - def apply_simple_reflection(self, i, side="right"): + def apply_simple_reflection(self, i, side='right'): s = self.parent().simple_reflections() if side == "right": return self * s[i] @@ -1015,8 +1014,8 @@ def __classcall__(cls, cartan_type, prefix=None): EXAMPLES:: - sage: W1 = WeylGroup(['B',2], implementation="permutation") - sage: W2 = WeylGroup(CartanType(['B',2]), implementation="permutation") + sage: W1 = WeylGroup(['B',2], implementation='permutation') + sage: W2 = WeylGroup(CartanType(['B',2]), implementation='permutation') sage: W1 is W2 True """ @@ -1028,7 +1027,7 @@ def __init__(self, cartan_type, prefix): EXAMPLES:: - sage: W = WeylGroup(['F',4], implementation="permutation") + sage: W = WeylGroup(['F',4], implementation='permutation') sage: TestSuite(W).run() """ self._cartan_type = cartan_type @@ -1046,20 +1045,20 @@ def __init__(self, cartan_type, prefix): cat = (cat, PermutationGroups().Finite()) PermutationGroup_generic.__init__(self, gens=p, canonicalize=False, category=cat) - def iteration(self, algorithm="breadth", tracking_words=True): + def iteration(self, algorithm='breadth', tracking_words=True): r""" Return an iterator going through all elements in ``self``. INPUT: - - ``algorithm`` (default: ``'breadth'``) -- must be one of + - ``algorithm`` -- (default: ``'breadth'``) must be one of the following: * ``'breadth'`` -- iterate over in a linear extension of the weak order * ``'depth'`` -- iterate by a depth-first-search - - ``tracking_words`` (default: ``True``) -- whether or not to keep + - ``tracking_words`` -- boolean (default: ``True``); whether or not to keep track of the reduced words and store them in ``_reduced_word`` .. NOTE:: @@ -1069,7 +1068,7 @@ def iteration(self, algorithm="breadth", tracking_words=True): EXAMPLES:: - sage: W = WeylGroup(["B",2], implementation="permutation") + sage: W = WeylGroup(["B",2], implementation='permutation') sage: for w in W.iteration("breadth",True): ....: print("%s %s"%(w, w._reduced_word)) @@ -1091,8 +1090,18 @@ def iteration(self, algorithm="breadth", tracking_words=True): (1,7,5,3)(2,4,6,8) (2,8)(3,7)(4,6) (1,5)(2,6)(3,7)(4,8) + + TESTS:: + + sage: W = WeylGroup(["A",0], implementation='permutation') + sage: list(W) + [()] + sage: W[0] + () """ from sage.combinat.root_system.reflection_group_c import Iterator + if self.rank() == 0: + return iter([self.one()]) return iter(Iterator(self, N=self.number_of_reflections(), algorithm=algorithm, tracking_words=tracking_words)) @@ -1104,7 +1113,7 @@ def __iter__(self): EXAMPLES:: - sage: W = WeylGroup(["B",2], implementation="permutation") + sage: W = WeylGroup(["B",2], implementation='permutation') sage: for w in W: print("%s %s"%(w, w._reduced_word)) () [] (1,3)(2,6)(5,7) [1] @@ -1115,7 +1124,7 @@ def __iter__(self): (1,7)(3,5)(4,8) [0, 1, 0] (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] """ - return self.iteration(algorithm="breadth", tracking_words=True) + return self.iteration(algorithm='breadth', tracking_words=True) def _coerce_map_from_(self, P): """ @@ -1124,7 +1133,7 @@ def _coerce_map_from_(self, P): EXAMPLES:: - sage: W = WeylGroup(["B",4], implementation="permutation") + sage: W = WeylGroup(["B",4], implementation='permutation') sage: W2 = WeylGroup(["B",4]) sage: W._coerce_map_from_(W2) True @@ -1134,7 +1143,7 @@ def _coerce_map_from_(self, P): sage: W4 = CoxeterGroup(["B",4]) sage: W.has_coerce_map_from(W4) False - sage: W5 = WeylGroup(["C",4], implementation="permutation") + sage: W5 = WeylGroup(["C",4], implementation='permutation') sage: W.has_coerce_map_from(W5) False """ @@ -1147,7 +1156,7 @@ def rank(self): EXAMPLES:: - sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.rank() 4 """ @@ -1159,7 +1168,7 @@ def simple_reflection(self, i): EXAMPLES:: - sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.simple_reflection(1) (1,11)(2,5)(6,8)(9,10)(12,15)(16,18)(19,20) sage: W.simple_reflections() @@ -1177,7 +1186,7 @@ def simple_roots(self): EXAMPLES:: - sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.simple_roots() Finite family {1: (1, 0, 0, 0), 2: (0, 1, 0, 0), 3: (0, 0, 1, 0), 4: (0, 0, 0, 1)} @@ -1197,7 +1206,7 @@ def index_set(self): EXAMPLES:: - sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.index_set() (1, 2, 3, 4) """ @@ -1210,7 +1219,7 @@ def reflection_index_set(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], implementation="permutation") + sage: W = WeylGroup(['A',3], implementation='permutation') sage: W.reflection_index_set() (1, 2, 3, 4, 5, 6) """ @@ -1222,7 +1231,7 @@ def cartan_type(self): EXAMPLES:: - sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.cartan_type() ['A', 4] """ @@ -1235,7 +1244,7 @@ def roots(self): EXAMPLES:: - sage: W = WeylGroup(['G',2], implementation="permutation") + sage: W = WeylGroup(['G',2], implementation='permutation') sage: W.roots() ((1, 0), (0, 1), @@ -1263,7 +1272,7 @@ def positive_roots(self): EXAMPLES:: - sage: W = WeylGroup(['C',3], implementation="permutation") + sage: W = WeylGroup(['C',3], implementation='permutation') sage: W.positive_roots() ((1, 0, 0), (0, 1, 0), @@ -1284,7 +1293,7 @@ def number_of_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['D',4], implementation="permutation") + sage: W = WeylGroup(['D',4], implementation='permutation') sage: W.number_of_reflections() 12 """ @@ -1297,7 +1306,7 @@ def distinguished_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['B',2], implementation="permutation") + sage: W = WeylGroup(['B',2], implementation='permutation') sage: W.distinguished_reflections() Finite family {1: (1,5)(2,4)(6,8), 2: (1,3)(2,6)(5,7), 3: (2,8)(3,7)(4,6), 4: (1,7)(3,5)(4,8)} @@ -1322,7 +1331,7 @@ def simple_root_index(self, i): EXAMPLES:: - sage: W = WeylGroup(['A',3], implementation="permutation") + sage: W = WeylGroup(['A',3], implementation='permutation') sage: [W.simple_root_index(i) for i in W.index_set()] [0, 1, 2] """ @@ -1333,11 +1342,11 @@ def _repr_(self): """ EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s", implementation="permutation") + sage: W = WeylGroup(['A',3], prefix='s', implementation='permutation') sage: [s1,s2,s3] = W.simple_reflections() sage: s1*s2 s1*s2 - sage: W = WeylGroup(['A',3], implementation="permutation") + sage: W = WeylGroup(['A',3], implementation='permutation') sage: [s1,s2,s3] = W.simple_reflections() sage: s1*s2 (1,10,2)(3,5,6)(4,8,7)(9,11,12) @@ -1354,11 +1363,11 @@ def _latex_(self): """ EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s", implementation="permutation") + sage: W = WeylGroup(['A',3], prefix='s', implementation='permutation') sage: [s1,s2,s3] = W.simple_reflections() sage: s1*s2 s1*s2 - sage: W = WeylGroup(['A',3], implementation="permutation") + sage: W = WeylGroup(['A',3], implementation='permutation') sage: [s1,s2,s3] = W.simple_reflections() sage: s1*s2 (1,10,2)(3,5,6)(4,8,7)(9,11,12) diff --git a/src/sage/combinat/rooted_tree.py b/src/sage/combinat/rooted_tree.py index 74aeeff0bba..0ced874b74d 100644 --- a/src/sage/combinat/rooted_tree.py +++ b/src/sage/combinat/rooted_tree.py @@ -425,11 +425,11 @@ def single_graft(self, x, grafting_function, path_prefix=()): INPUT: - - `x` -- a rooted tree + - ``x`` -- a rooted tree - - ``grafting_function`` -- a list of paths in ``self`` + - ``grafting_function`` -- list of paths in ``self`` - - ``path_prefix`` -- optional tuple (default ``()``) + - ``path_prefix`` -- tuple (default: ``()``) The ``path_prefix`` argument is only used for internal recursion. @@ -467,7 +467,7 @@ class RootedTrees(UniqueRepresentation, Parent): INPUT: - - ``size`` -- (optional) an integer + - ``size`` -- integer (optional) OUTPUT: @@ -808,10 +808,10 @@ class LabelledRootedTree(AbstractLabelledClonableTree, RootedTree): INPUT: - - ``children`` -- a list or tuple or more generally any iterable + - ``children`` -- list or tuple or more generally any iterable of trees or objects convertible to trees - - ``label`` -- any hashable Sage object (default is ``None``) + - ``label`` -- any hashable Sage object (default: ``None``) .. NOTE:: @@ -1042,7 +1042,7 @@ def _an_element_(self): t = LT([], label=3) t1 = LT([t, t], label=42) t2 = LT([[]], label=5) - return LT([t, t1, t2], label="alpha") + return LT([t, t1, t2], label='alpha') def unlabelled_trees(self): """ diff --git a/src/sage/combinat/rsk.py b/src/sage/combinat/rsk.py index de28f0e6db8..1fa0ba62b4e 100644 --- a/src/sage/combinat/rsk.py +++ b/src/sage/combinat/rsk.py @@ -222,11 +222,10 @@ def to_pairs(self, obj1=None, obj2=None, check=True): - ``obj1``, ``obj2`` -- anything representing a biword (see the doc of :meth:`forward_rule` for the - encodings accepted). + encodings accepted) - - ``check`` -- (default: ``True``) whether to check - that ``obj1`` and ``obj2`` actually define a valid - biword. + - ``check`` -- boolean (default: ``True``); whether to check that + ``obj1`` and ``obj2`` actually define a valid biword EXAMPLES:: @@ -304,11 +303,11 @@ def forward_rule(self, obj1, obj2, check_standard=False, check=True): entries and bottom entries in the biword (in this case, ``obj2`` is ``None``) - - ``check_standard`` -- (default: ``False``) check if either of the - resulting tableaux is a standard tableau, and if so, typecast it - as such + - ``check_standard`` -- boolean (default: ``False``); check if either + of the resulting tableaux is a standard tableau, and if so, typecast + it as such - - ``check`` -- (default: ``True``) whether to check + - ``check`` -- boolean (default: ``True``); whether to check that ``obj1`` and ``obj2`` actually define a valid biword @@ -348,7 +347,7 @@ def backward_rule(self, p, q, output): INPUT: - - ``p``, ``q`` -- two tableaux of the same shape. + - ``p``, ``q`` -- two tableaux of the same shape - ``output`` -- (default: ``'array'``) if ``q`` is semi-standard: @@ -893,9 +892,9 @@ def forward_rule(self, obj1, obj2, check_standard=False): case, ``obj2`` is ``None``; the top row of the biword is understood to be `(1, 2, \ldots, n)` by default) - - ``check_standard`` -- (default: ``False``) check if either of the - resulting tableaux is a standard tableau, and if so, typecast it - as such + - ``check_standard`` -- boolean (default: ``False``); check if either + of the resulting tableaux is a standard tableau, and if so, typecast + it as such EXAMPLES:: @@ -954,7 +953,7 @@ def backward_rule(self, p, q, output): - ``p``, ``q`` -- two tableaux of the same shape - - ``output`` -- (default: ``'array'``) if ``q`` is semi-standard: + - ``output`` -- (default: ``'array'``) if ``q`` is semi-standard: - ``'array'`` -- as a two-line array (i.e. generalized permutation or biword) @@ -1330,7 +1329,7 @@ def to_pairs(self, obj1=None, obj2=None, check=True): (see the doc of :meth:`forward_rule` for the encodings accepted) - - ``check`` -- (default: ``True``) whether to check + - ``check`` -- boolean (default: ``True``); whether to check that ``obj1`` and ``obj2`` actually define a valid strict biword @@ -1713,7 +1712,7 @@ def to_pairs(self, obj1=None, obj2=None, check=True): cobiword (see the doc of :meth:`forward_rule` for the encodings accepted) - - ``check`` -- (default: ``True``) whether to check + - ``check`` -- boolean (default: ``True``); whether to check that ``obj1`` and ``obj2`` actually define a valid strict cobiword @@ -2033,7 +2032,7 @@ def to_pairs(self, obj1=None, obj2=None, check=True): (see the doc of :meth:`forward_rule` for the encodings accepted) - - ``check`` -- (default: ``True``) whether to check + - ``check`` -- boolean (default: ``True``); whether to check that ``obj1`` and ``obj2`` actually define a valid restricted super biword @@ -2178,11 +2177,11 @@ def forward_rule(self, obj1, obj2, check_standard=False, check=True): entries and bottom entries in the biword (in this case, ``obj2`` is ``None``) - - ``check_standard`` -- (default: ``False``) check if either of - the resulting tableaux is a standard super tableau, and if so, + - ``check_standard`` -- boolean (default: ``False``); check if either + of the resulting tableaux is a standard super tableau, and if so, typecast it as such - - ``check`` -- (default: ``True``) whether to check + - ``check`` -- boolean (default: ``True``); whether to check that ``obj1`` and ``obj2`` actually define a valid restricted super biword @@ -2679,10 +2678,10 @@ def forward_rule(self, obj1, obj2=None, check_braid=True): understood to be the indices of the factors for each letter in this biword. - - ``check_braid`` -- (default: ``True``) indicator to validate that - input is associated to a fully commutative word in the 0-Hecke monoid, - validation is performed if set to ``True``; otherwise, this validation - is ignored. + - ``check_braid`` -- boolean (default: ``True``); indicator to validate + that input is associated to a fully commutative word in the 0-Hecke + monoid, validation is performed if set to ``True``. Οtherwise, this + validation is ignored. EXAMPLES:: @@ -2958,12 +2957,10 @@ def _backward_format_output(self, obj1, obj2, output): if j == 0: df.append([]) if j > 0 and obj1[j] < obj1[j-1]: - for _ in range(obj1[j-1]-obj1[j]): - df.append([]) + df.extend([] for _ in range(obj1[j-1]-obj1[j])) df[-1].append(obj2[j]) if obj1: - for a in range(obj1[-1]-1): - df.append([]) + df.extend([] for a in range(obj1[-1]-1)) # If biword is empty, return a decreasing factorization with 1 factor else: df.append([]) @@ -3071,7 +3068,7 @@ def RSK(obj1=None, obj2=None, insertion=InsertionRules.RSK, check_standard=False - ``RSK.rules.EG`` (or ``'EG'``) -- Edelman-Greene insertion (only for reduced words of permutations/elements of a type `A` Coxeter group) (:class:`~sage.combinat.rsk.RuleEG`) - - ``RSK.rules.Hecke`` (or ``'hecke'``) -- Hecke insertion (only + - ``RSK.rules.Hecke`` -- (or ``'hecke'``) Hecke insertion (only guaranteed for generalized permutations whose top row is strictly increasing) (:class:`~sage.combinat.rsk.RuleHecke`) - ``RSK.rules.dualRSK`` (or ``'dualRSK'``) -- Dual RSK insertion @@ -3084,8 +3081,8 @@ def RSK(obj1=None, obj2=None, insertion=InsertionRules.RSK, check_standard=False fully commutative words in the 0-Hecke monoid) (:class:`~sage.combinat.rsk.RuleStar`) - - ``check_standard`` -- (default: ``False``) check if either of the - resulting tableaux is a standard tableau, and if so, typecast it + - ``check_standard`` -- boolean (default: ``False``); check if either of + the resulting tableaux is a standard tableau, and if so, typecast it as such For precise information about constraints on the input and output, @@ -3153,7 +3150,6 @@ def RSK(obj1=None, obj2=None, insertion=InsertionRules.RSK, check_standard=False [[], []] sage: RSK(Word([]), insertion=RSK.rules.Hecke) [[], []] - """ if isinstance(insertion, str): if insertion == 'RSK': diff --git a/src/sage/combinat/schubert_polynomial.py b/src/sage/combinat/schubert_polynomial.py index 63fd2a9065e..efd11f1e0f3 100644 --- a/src/sage/combinat/schubert_polynomial.py +++ b/src/sage/combinat/schubert_polynomial.py @@ -158,7 +158,7 @@ def expand(self): p = R(p) return p - def divided_difference(self, i, algorithm="sage"): + def divided_difference(self, i, algorithm='sage'): r""" Return the ``i``-th divided difference operator, applied to ``self``. diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 5bf9e93d1ed..092e2f9dbb7 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -487,11 +487,9 @@ def conjugate(self): INPUT: - - ``self`` -- a set partition of an ordered set + - ``self`` -- set partition of an ordered set - OUTPUT: - - a set partition + OUTPUT: a set partition EXAMPLES:: @@ -652,7 +650,7 @@ def check(self): def set_latex_options(self, **kwargs): r""" - Set the latex options for use in the ``_latex_`` function + Set the latex options for use in the ``_latex_`` function. - ``tikz_scale`` -- (default: 1) scale for use with tikz package @@ -662,14 +660,14 @@ def set_latex_options(self, **kwargs): - ``color`` -- (default: ``'black'``) the arc colors - - ``fill`` -- (default: ``False``) if ``True`` then fills ``color``, - else you can pass in a color to alter the fill color - + - ``fill`` -- boolean (default: ``False``); if ``True`` then fills + ``color``, else you can pass in a color to alter the fill color - *only works with cyclic plot* - - ``show_labels`` -- (default: ``True``) if ``True`` shows labels - - *only works with plots* + - ``show_labels`` -- boolean (default: ``True``); if ``True`` shows + labels (*only works with plots*) - - ``radius`` -- (default: ``"1cm"``) radius of circle for cyclic + - ``radius`` -- (default: ``'1cm'``) radius of circle for cyclic plot - *only works with cyclic plot* - ``angle`` -- (default: 0) angle for linear plot @@ -945,15 +943,15 @@ def to_permutation(self): """ return Permutation(tuple(map(tuple, self.standard_form()))) - def to_restricted_growth_word(self, bijection="blocks"): + def to_restricted_growth_word(self, bijection='blocks'): r""" Convert a set partition of `\{1,...,n\}` to a word of length `n` - with letters in the non-negative integers such that each + with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before. INPUT: - - ``bijection`` (default: ``blocks``) -- defines the map from + - ``bijection`` -- (default: ``blocks``) defines the map from set partitions to restricted growth functions. These are currently: @@ -961,9 +959,7 @@ def to_restricted_growth_word(self, bijection="blocks"): - ``intertwining``: :meth:`to_restricted_growth_word_intertwining`. - OUTPUT: - - A restricted growth word. + OUTPUT: a restricted growth word .. SEEALSO:: @@ -1009,16 +1005,14 @@ def to_restricted_growth_word(self, bijection="blocks"): def to_restricted_growth_word_blocks(self): r""" Convert a set partition of `\{1,...,n\}` to a word of length `n` - with letters in the non-negative integers such that each + with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before. The word is obtained by sorting the blocks by their minimal element and setting the letters at the positions of the elements in the `i`-th block to `i`. - OUTPUT: - - a restricted growth word. + OUTPUT: a restricted growth word .. SEEALSO:: @@ -1041,7 +1035,7 @@ def to_restricted_growth_word_blocks(self): def to_restricted_growth_word_intertwining(self): r""" Convert a set partition of `\{1,...,n\}` to a word of length `n` - with letters in the non-negative integers such that each + with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before. The `i`-th letter of the word is the numbers of crossings of @@ -1049,9 +1043,7 @@ def to_restricted_growth_word_intertwining(self): `i`, with arcs (or half-arcs) beginning at a smaller element and ending at a larger element. - OUTPUT: - - a restricted growth word. + OUTPUT: a restricted growth word .. SEEALSO:: @@ -1098,7 +1090,7 @@ def closers(self): """ return sorted([max(B) for B in self]) - def to_rook_placement(self, bijection="arcs"): + def to_rook_placement(self, bijection='arcs'): r""" Return a set of pairs defining a placement of non-attacking rooks on a triangular board. @@ -1108,7 +1100,7 @@ def to_rook_placement(self, bijection="arcs"): INPUT: - - ``bijection`` (default: ``arcs``) -- defines the bijection + - ``bijection`` -- (default: ``arcs``) defines the bijection from set partitions to rook placements. These are currently: @@ -1160,9 +1152,7 @@ def to_rook_placement_gamma(self): rook, which are not yet attacked by another rook, equals the index of the block to which `n+1-i` belongs. - OUTPUT: - - A list of coordinates. + OUTPUT: list of coordinates .. SEEALSO:: @@ -1236,9 +1226,7 @@ def to_rook_placement_rho(self): One can show that the precisely those rows which correspond to openers of the set partition remain empty. - OUTPUT: - - A list of coordinates. + OUTPUT: list of coordinates .. SEEALSO:: @@ -1297,9 +1285,7 @@ def to_rook_placement_psi(self): Return the rook diagram obtained by placing rooks according to Yip's bijection psi. - OUTPUT: - - A list of coordinates. + OUTPUT: list of coordinates .. SEEALSO:: @@ -2117,7 +2103,7 @@ def _element_constructor_(self, s, check=True): INPUT: - - ``s`` -- a set of sets + - ``s`` -- set of sets EXAMPLES:: @@ -2139,17 +2125,17 @@ def _element_constructor_(self, s, check=True): Element = SetPartition - def from_restricted_growth_word(self, w, bijection="blocks"): + def from_restricted_growth_word(self, w, bijection='blocks'): r""" - Convert a word of length `n` with letters in the non-negative + Convert a word of length `n` with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before to a set partition of `\{1,...,n\}`. INPUT: - - ``w`` -- a restricted growth word. + - ``w`` -- a restricted growth word - - ``bijection`` (default: ``blocks``) -- defines the map from + - ``bijection`` -- (default: ``blocks``) defines the map from restricted growth functions to set partitions. These are currently: @@ -2157,9 +2143,7 @@ def from_restricted_growth_word(self, w, bijection="blocks"): - ``intertwining``: :meth:`from_restricted_growth_word_intertwining`. - OUTPUT: - - A set partition. + OUTPUT: a set partition .. SEEALSO:: @@ -2184,7 +2168,7 @@ def from_restricted_growth_word(self, w, bijection="blocks"): def from_restricted_growth_word_blocks(self, w): r""" - Convert a word of length `n` with letters in the non-negative + Convert a word of length `n` with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before to a set partition of `\{1,...,n\}`. @@ -2193,11 +2177,9 @@ def from_restricted_growth_word_blocks(self, w): INPUT: - - ``w`` -- a restricted growth word. + - ``w`` -- a restricted growth word - OUTPUT: - - A set partition. + OUTPUT: a set partition .. SEEALSO:: @@ -2219,7 +2201,7 @@ def from_restricted_growth_word_blocks(self, w): def from_restricted_growth_word_intertwining(self, w): r""" - Convert a word of length `n` with letters in the non-negative + Convert a word of length `n` with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before to a set partition of `\{1,...,n\}`. @@ -2230,11 +2212,9 @@ def from_restricted_growth_word_intertwining(self, w): INPUT: - - ``w`` -- a restricted growth word. - - OUTPUT: + - ``w`` -- a restricted growth word - A set partition. + OUTPUT: a set partition .. SEEALSO:: @@ -2264,7 +2244,7 @@ def from_restricted_growth_word_intertwining(self, w): C = [i + 1] + C return self.element_class(self, R) - def from_rook_placement(self, rooks, bijection="arcs", n=None): + def from_rook_placement(self, rooks, bijection='arcs', n=None): r""" Convert a rook placement of the triangular grid to a set partition of `\{1,...,n\}`. @@ -2275,10 +2255,10 @@ def from_rook_placement(self, rooks, bijection="arcs", n=None): INPUT: - - ``rooks`` -- a list of pairs `(i,j)` satisfying - `0 < i < j < n+1`. + - ``rooks`` -- list of pairs `(i,j)` satisfying + `0 < i < j < n+1` - - ``bijection`` (default: ``arcs``) -- defines the map from + - ``bijection`` -- (default: ``arcs``) defines the map from rook placements to set partitions. These are currently: - ``arcs``: :meth:`from_arcs`. @@ -2286,7 +2266,7 @@ def from_rook_placement(self, rooks, bijection="arcs", n=None): - ``rho``: :meth:`from_rook_placement_rho`. - ``psi``: :meth:`from_rook_placement_psi`. - - ``n`` -- (optional) the size of the ground set. + - ``n`` -- (optional) the size of the ground set .. SEEALSO:: @@ -2342,11 +2322,11 @@ def from_arcs(self, arcs, n): INPUT: - - ``n`` -- an integer specifying the size of the set - partition to be produced. + - ``n`` -- integer specifying the size of the set + partition to be produced - - ``arcs`` -- a list of pairs specifying which elements are - in the same block. + - ``arcs`` -- list of pairs specifying which elements are + in the same block .. SEEALSO:: @@ -2377,14 +2357,12 @@ def from_rook_placement_gamma(self, rooks, n): INPUT: - - ``n`` -- an integer specifying the size of the set - partition to be produced. + - ``n`` -- integer specifying the size of the set + partition to be produced - - ``rooks`` -- a list of pairs `(i,j)` such that `0 < i < j < n+1`. + - ``rooks`` -- list of pairs `(i,j)` such that `0 < i < j < n+1` - OUTPUT: - - A set partition. + OUTPUT: a set partition .. SEEALSO:: @@ -2433,14 +2411,12 @@ def from_rook_placement_rho(self, rooks, n): INPUT: - - ``n`` -- an integer specifying the size of the set - partition to be produced. - - - ``rooks`` -- a list of pairs `(i,j)` such that `0 < i < j < n+1`. + - ``n`` -- integer specifying the size of the set + partition to be produced - OUTPUT: + - ``rooks`` -- list of pairs `(i,j)` such that `0 < i < j < n+1` - A set partition. + OUTPUT: a set partition .. SEEALSO:: @@ -2499,15 +2475,12 @@ def from_rook_placement_psi(self, rooks, n): INPUT: - - ``n`` -- an integer specifying the size of the set - partition to be produced. - - - ``rooks`` -- a list of pairs `(i,j)` such that `0 < i < j < - n+1`. + - ``n`` -- integer specifying the size of the set + partition to be produced - OUTPUT: + - ``rooks`` -- list of pairs `(i,j)` such that `0 < i < j < n+1` - A set partition. + OUTPUT: a set partition .. SEEALSO:: @@ -3297,7 +3270,7 @@ def cyclic_permutations_of_set_partition(set_part): def cyclic_permutations_of_set_partition_iterator(set_part): """ - Iterates over all combinations of cyclic permutations of each cell + Iterate over all combinations of cyclic permutations of each cell of the set partition. AUTHORS: diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 782b13df638..37faaec29be 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -330,7 +330,7 @@ def sum(osps): INPUT: - - ``osps`` -- a list (or iterable) of ordered set partitions + - ``osps`` -- list (or iterable) of ordered set partitions EXAMPLES:: @@ -938,7 +938,7 @@ def __classcall_private__(cls, s=None, c=None): return OrderedSetPartitions_all() if isinstance(s, (int, Integer)): if s < 0: - raise ValueError("s must be non-negative") + raise ValueError("s must be nonnegative") s = frozenset(range(1, s + 1)) else: s = frozenset(s) diff --git a/src/sage/combinat/sf/character.py b/src/sage/combinat/sf/character.py index 6fd2490ff11..36755b58f05 100644 --- a/src/sage/combinat/sf/character.py +++ b/src/sage/combinat/sf/character.py @@ -56,9 +56,7 @@ def _my_key(self, la): - ``la`` -- a partition - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -128,11 +126,9 @@ def _b_power_k(self, k): INPUT: - - ``k`` -- a positive integer - - OUTPUT: + - ``k`` -- positive integer - - an expression in the powersum basis of the symmetric functions + OUTPUT: an expression in the powersum basis of the symmetric functions EXAMPLES:: @@ -143,7 +139,6 @@ def _b_power_k(self, k): -1/2*p[1] + 1/2*p[2] sage: st._b_power_k(6) 1/6*p[1] - 1/6*p[2] - 1/6*p[3] + 1/6*p[6] - """ if k == 1: return self._p([1]) @@ -224,7 +219,7 @@ def __init__(self, Sym): """ SFA_generic.__init__(self, Sym, basis_name="induced trivial symmetric group character", - prefix="ht", graded=False) + prefix='ht', graded=False) self._other = Sym.complete() self._p = Sym.powersum() @@ -248,9 +243,7 @@ def _b_bar_power_k_r(self, k, r): - ``k``, ``r`` -- positive integers - OUTPUT: - - - an expression in the powersum basis of the symmetric functions + OUTPUT: an expression in the powersum basis of the symmetric functions EXAMPLES:: @@ -261,7 +254,6 @@ def _b_bar_power_k_r(self, k, r): 2*p[1] + p[1, 1] - 2*p[2] - 2*p[2, 1] + p[2, 2] sage: ht._b_bar_power_k_r(3,2) 3*p[1] + p[1, 1] - 3*p[3] - 2*p[3, 1] + p[3, 3] - """ p = self._p return k**r * p.prod( self._b_power_k(k)-j for j in range(r) ) @@ -288,9 +280,7 @@ def _b_bar_power_gamma(self, gamma): - ``gamma`` -- a partition - OUTPUT: - - - an expression in the powersum basis of the symmetric functions + OUTPUT: an expression in the powersum basis of the symmetric functions EXAMPLES:: @@ -301,7 +291,6 @@ def _b_bar_power_gamma(self, gamma): 2*p[1] - 3*p[1, 1] + p[1, 1, 1] sage: ht._b_bar_power_gamma(Partition([3,3,1])) 3*p[1, 1] + p[1, 1, 1] - 3*p[3, 1] - 2*p[3, 1, 1] + p[3, 3, 1] - """ return self._p.prod(self._b_bar_power_k_r(Integer(k), Integer(r)) for k, r in gamma.to_exp_dict().items()) @@ -326,9 +315,7 @@ def _self_to_power_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - an expression in the power sum basis + OUTPUT: an expression in the power sum basis EXAMPLES:: @@ -337,7 +324,6 @@ def _self_to_power_on_basis(self, lam): p[1] - 2*p[1, 1] + 1/2*p[1, 1, 1] + 1/2*p[2, 1] sage: ht._self_to_power_on_basis([1,1,1]) 2*p[1] - 3*p[1, 1] + p[1, 1, 1] - """ return self._p.sum( c*self._b_bar_power_gamma(ga) for (ga, c) in self._p(self._other(lam)) ) @@ -451,7 +437,7 @@ def __init__(self, Sym): """ SFA_generic.__init__(self, Sym, basis_name="irreducible symmetric group character", - prefix="st", graded=False) + prefix='st', graded=False) self._other = Sym.Schur() self._p = Sym.powersum() @@ -475,9 +461,7 @@ def _b_power_k_r(self, k, r): - ``k``, ``r`` -- positive integers - OUTPUT: - - - an expression in the powersum basis of the symmetric functions + OUTPUT: an expression in the powersum basis of the symmetric functions EXAMPLES:: @@ -488,7 +472,6 @@ def _b_power_k_r(self, k, r): p[] + 4*p[1] + p[1, 1] - 4*p[2] - 2*p[2, 1] + p[2, 2] sage: st._b_power_k_r(3,2) p[] + 5*p[1] + p[1, 1] - 5*p[3] - 2*p[3, 1] + p[3, 3] - """ p = self._p return p.sum( (-1)**(r-j) * k**j * binomial(r,j) @@ -517,9 +500,7 @@ def _b_power_gamma(self, gamma): - ``gamma`` -- a partition - OUTPUT: - - - an expression in the powersum basis of the symmetric functions + OUTPUT: an expression in the powersum basis of the symmetric functions EXAMPLES:: @@ -530,7 +511,6 @@ def _b_power_gamma(self, gamma): -p[] + 8*p[1] - 6*p[1, 1] + p[1, 1, 1] sage: st._b_power_gamma(Partition([3,1])) p[] - p[1, 1] - p[3] + p[3, 1] - """ return self._p.prod(self._b_power_k_r(Integer(k), Integer(r)) for k, r in gamma.to_exp_dict().items()) @@ -557,9 +537,7 @@ def _self_to_power_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - an expression in the power sum basis + OUTPUT: an expression in the power sum basis EXAMPLES:: @@ -568,7 +546,6 @@ def _self_to_power_on_basis(self, lam): 3*p[1] - 2*p[1, 1] + 1/3*p[1, 1, 1] - 1/3*p[3] sage: st._self_to_power_on_basis([1,1]) p[] - p[1] + 1/2*p[1, 1] - 1/2*p[2] - """ return self._p.sum( c*self._b_power_gamma(ga) for (ga, c) in self._p(self._other(lam)) ) @@ -585,9 +562,7 @@ def _self_to_other_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - an expression in the Schur basis + OUTPUT: an expression in the Schur basis EXAMPLES:: diff --git a/src/sage/combinat/sf/classical.py b/src/sage/combinat/sf/classical.py index 792272417a8..badea76a0c5 100644 --- a/src/sage/combinat/sf/classical.py +++ b/src/sage/combinat/sf/classical.py @@ -155,7 +155,7 @@ def _element_constructor_(self, x): ############## # Dual bases # ############## - elif sfa.is_SymmetricFunction(x) and hasattr(x, 'dual'): + elif isinstance(x, sfa.SymmetricFunctionAlgebra_generic.Element) and hasattr(x, 'dual'): # Check to see if it is the dual of some other basis # If it is, try to coerce its corresponding element # in the other basis diff --git a/src/sage/combinat/sf/dual.py b/src/sage/combinat/sf/dual.py index 207e411a2c6..5feb90c385b 100644 --- a/src/sage/combinat/sf/dual.py +++ b/src/sage/combinat/sf/dual.py @@ -27,7 +27,7 @@ class SymmetricFunctionAlgebra_dual(classical.SymmetricFunctionAlgebra_classical): @staticmethod - def __classcall__(cls, dual_basis, scalar, scalar_name="", basis_name=None, prefix=None): + def __classcall__(cls, dual_basis, scalar, scalar_name='', basis_name=None, prefix=None): """ Normalize the arguments. @@ -35,7 +35,7 @@ def __classcall__(cls, dual_basis, scalar, scalar_name="", basis_name=None, pref sage: w = SymmetricFunctions(QQ).w() sage: B1 = w.dual_basis() - sage: B2 = w.dual_basis(prefix="d_w") + sage: B2 = w.dual_basis(prefix='d_w') sage: B1 is B2 True """ @@ -51,7 +51,7 @@ def __init__(self, dual_basis, scalar, scalar_name, basis_name, prefix): - ``dual_basis`` -- a basis of the ring of symmetric functions - - ``scalar`` -- A function `z` on partitions which determines the + - ``scalar`` -- a function `z` on partitions which determines the scalar product on the power sum basis by `\langle p_{\mu}, p_{\mu} \rangle = z(\mu)`. (Independently on the function chosen, the power sum basis will always be orthogonal; the @@ -89,7 +89,7 @@ def __init__(self, dual_basis, scalar, scalar_name, basis_name, prefix): EXAMPLES:: sage: e = SymmetricFunctions(QQ).e() - sage: f = e.dual_basis(prefix="m", basis_name="Forgotten symmetric functions"); f + sage: f = e.dual_basis(prefix='m', basis_name="Forgotten symmetric functions"); f Symmetric Functions over Rational Field in the Forgotten symmetric functions basis sage: TestSuite(f).run(elements=[f[1,1]+2*f[2], f[1]+3*f[1,1]]) sage: TestSuite(f).run() # long time (11s on sage.math, 2011) @@ -135,7 +135,6 @@ def __init__(self, dual_basis, scalar, scalar_name, basis_name, prefix): sage: y = e[1, 1, 1, 1] - 2*e[2, 1, 1] + e[2, 2] sage: sorted(f.element_class(f, dual = y)) [([1, 1, 1, 1], 6), ([2, 1, 1], 2), ([2, 2], 1)] - """ self._dual_basis = dual_basis self._scalar = scalar @@ -193,9 +192,7 @@ def _dual_to_self(self, x): - ``x`` -- an element in the dual basis of ``self`` - OUTPUT: - - - returns ``x`` expressed in the basis ``self`` + OUTPUT: ``x`` expressed in the basis ``self`` EXAMPLES:: @@ -231,9 +228,7 @@ def _self_to_dual(self, x): - ``x`` -- an element of ``self`` - OUTPUT: - - - returns ``x`` expressed in the dual basis + OUTPUT: ``x`` expressed in the dual basis EXAMPLES:: @@ -257,7 +252,7 @@ def _self_to_dual(self, x): def _dual_basis_default(self): """ - Returns the default value for ``self.dual_basis()`` + Return the default value for ``self.dual_basis()``. This returns the basis ``self`` has been built from by duality. @@ -309,9 +304,7 @@ def _repr_(self): """ Representation of ``self``. - OUTPUT: - - - a string description of ``self`` + OUTPUT: string description of ``self`` EXAMPLES:: @@ -487,7 +480,7 @@ def _precompute(self, n): def transition_matrix(self, basis, n): r""" - Returns the transition matrix between the `n^{th}` homogeneous components + Return the transition matrix between the `n`-th homogeneous components of ``self`` and ``basis``. INPUT: @@ -547,9 +540,7 @@ def product(self, left, right): - ``left``, ``right`` -- elements of ``self`` - OUTPUT: - - - the product of ``left`` and ``right`` in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` in the basis ``self`` EXAMPLES:: @@ -580,7 +571,7 @@ class Element(classical.SymmetricFunctionAlgebra_classical.Element): - ``dictionary`` -- an internal dictionary for the monomials and coefficients of ``self`` - - ``dual`` -- self as an element of the dual basis. + - ``dual`` -- self as an element of the dual basis """ def __init__(self, A, dictionary=None, dual=None): @@ -714,9 +705,7 @@ def omega(self): :meth:`omega_involution` is a synonym for the :meth:`omega` method. - OUTPUT: - - - the result of applying omega to ``self`` + OUTPUT: the result of applying omega to ``self`` EXAMPLES:: @@ -742,9 +731,7 @@ def scalar(self, x): - ``x`` -- element of the symmetric functions - OUTPUT: - - - the scalar product between ``x`` and ``self`` + OUTPUT: the scalar product between ``x`` and ``self`` EXAMPLES:: @@ -765,9 +752,7 @@ def scalar_hl(self, x): - ``x`` -- element of the same dual basis as ``self`` - OUTPUT: - - - the Hall-Littlewood scalar product between ``x`` and ``self`` + OUTPUT: the Hall-Littlewood scalar product between ``x`` and ``self`` EXAMPLES:: @@ -788,9 +773,7 @@ def _add_(self, y): - ``y`` -- element of the same dual basis as ``self`` - OUTPUT: - - - the sum of ``self`` and ``y`` + OUTPUT: the sum of ``self`` and ``y`` EXAMPLES:: @@ -830,9 +813,7 @@ def _sub_(self, y): - ``y`` -- element of the same dual basis as ``self`` - OUTPUT: - - - the difference of ``self`` and ``y`` + OUTPUT: the difference of ``self`` and ``y`` EXAMPLES:: @@ -855,9 +836,7 @@ def _div_(self, y): - ``y`` -- element of base field - OUTPUT: - - - the element ``self`` divided by ``y`` + OUTPUT: the element ``self`` divided by ``y`` EXAMPLES:: @@ -875,9 +854,7 @@ def __invert__(self): Invert ``self`` (only possible if ``self`` is a scalar multiple of `1` and we are working over a field). - OUTPUT: - - - multiplicative inverse of ``self`` if possible + OUTPUT: multiplicative inverse of ``self`` if possible EXAMPLES:: @@ -904,7 +881,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -936,6 +913,8 @@ def expand(self, n, alphabet='x'): from sage.combinat.sf.sfa import SymmetricFunctionsFunctor + + class DualBasisFunctor(SymmetricFunctionsFunctor): """ A constructor for algebras of symmetric functions constructed by @@ -1009,4 +988,6 @@ def _repr_(self): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.dual', 'SymmetricFunctionAlgebraElement_dual', SymmetricFunctionAlgebra_dual.Element) +register_unpickle_override('sage.combinat.sf.dual', + 'SymmetricFunctionAlgebraElement_dual', + SymmetricFunctionAlgebra_dual.Element) diff --git a/src/sage/combinat/sf/elementary.py b/src/sage/combinat/sf/elementary.py index f0942314323..675c02604fd 100644 --- a/src/sage/combinat/sf/elementary.py +++ b/src/sage/combinat/sf/elementary.py @@ -54,7 +54,7 @@ def __init__(self, Sym): def _dual_basis_default(self): """ - Returns the default value for ``self.dual_basis()`` + Return the default value for ``self.dual_basis()``. This method returns the dual basis to the elementary basis with respect to the standard scalar product, that is the @@ -71,20 +71,18 @@ def _dual_basis_default(self): sage: e._dual_basis_default() is e.dual_basis() True """ - return self.dual_basis(scalar=None, prefix="f", basis_name="forgotten") + return self.dual_basis(scalar=None, prefix='f', basis_name='forgotten') def coproduct_on_generators(self, i): r""" - Returns the coproduct on ``self[i]``. + Return the coproduct on ``self[i]``. INPUT: - ``self`` -- an elementary basis of the symmetric functions - - ``i`` -- a nonnegative integer + - ``i`` -- nonnegative integer - OUTPUT: - - - returns the coproduct on the elementary generator `e(i)` + OUTPUT: the coproduct on the elementary generator `e(i)` EXAMPLES:: @@ -222,7 +220,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -277,7 +275,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -337,12 +335,12 @@ def principal_specialization(self, n=infinity, q=None): INPUT: - - ``n`` (default: ``infinity``) -- a nonnegative integer or + - ``n`` -- (default: ``infinity``) a nonnegative integer or ``infinity``, specifying whether to compute the principal specialization of order ``n`` or the stable principal specialization. - - ``q`` (default: ``None``) -- the value to use for `q`; the + - ``q`` -- (default: ``None``) the value to use for `q`; the default is to create a ring of polynomials in ``q`` (or a field of rational functions in ``q``) over the given coefficient ring. @@ -378,7 +376,6 @@ def principal_specialization(self, n=infinity, q=None): sage: e.zero().principal_specialization(3) 0 - """ from sage.combinat.q_analogues import q_binomial @@ -455,10 +452,10 @@ def exponential_specialization(self, t=None, q=1): INPUT: - - ``t`` (default: ``None``) -- the value to use for `t`; - the default is to create a ring of polynomials in ``t``. + - ``t`` -- (default: ``None``) the value to use for `t`. + The default is to create a ring of polynomials in `t`. - - ``q`` (default: `1`) -- the value to use for `q`. If + - ``q`` -- (default: `1`) the value to use for `q`. If ``q`` is ``None``, then a ring (or fraction field) of polynomials in ``q`` is created. @@ -476,7 +473,6 @@ def exponential_specialization(self, t=None, q=1): sage: e.zero().exponential_specialization() 0 - """ from sage.combinat.q_analogues import q_factorial @@ -525,4 +521,6 @@ def f(partition): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.elementary', 'SymmetricFunctionAlgebraElement_elementary', SymmetricFunctionAlgebra_elementary.Element) +register_unpickle_override('sage.combinat.sf.elementary', + 'SymmetricFunctionAlgebraElement_elementary', + SymmetricFunctionAlgebra_elementary.Element) diff --git a/src/sage/combinat/sf/hall_littlewood.py b/src/sage/combinat/sf/hall_littlewood.py index 8d656533166..c725d478749 100644 --- a/src/sage/combinat/sf/hall_littlewood.py +++ b/src/sage/combinat/sf/hall_littlewood.py @@ -64,11 +64,9 @@ class HallLittlewood(UniqueRepresentation): def __repr__(self): r""" - A string representing the family of Hall-Littlewood symmetric function bases + A string representing the family of Hall-Littlewood symmetric function bases. - OUTPUT: - - - a string representing the class + OUTPUT: string representing the class EXAMPLES:: @@ -113,17 +111,13 @@ def __init__(self, Sym, t): def symmetric_function_ring( self ): r""" - The ring of symmetric functions associated to the class of Hall-Littlewood - symmetric functions + Return the ring of symmetric functions associated to the class of + Hall-Littlewood symmetric functions. INPUT: - ``self`` -- a class of Hall-Littlewood symmetric function bases - OUTPUT: - - - returns the ring of symmetric functions - EXAMPLES:: sage: HL = SymmetricFunctions(FractionField(QQ['t'])).hall_littlewood() @@ -134,17 +128,13 @@ def symmetric_function_ring( self ): def base_ring( self ): r""" - Returns the base ring of the symmetric functions where the - Hall-Littlewood symmetric functions live + Return the base ring of the symmetric functions where the + Hall-Littlewood symmetric functions live. INPUT: - ``self`` -- a class of Hall-Littlewood symmetric function bases - OUTPUT: - - The base ring of the symmetric functions. - EXAMPLES:: sage: HL = SymmetricFunctions(QQ['t'].fraction_field()).hall_littlewood(t=1) @@ -163,9 +153,7 @@ def P(self): - ``self`` -- a class of Hall-Littlewood symmetric function bases - OUTPUT: - - The class of the Hall-Littlewood `P` basis. + OUTPUT: the class of the Hall-Littlewood `P` basis EXAMPLES:: @@ -316,7 +304,7 @@ def P(self): def Q(self): r""" - Returns the algebra of symmetric functions in Hall-Littlewood `Q` + Return the algebra of symmetric functions in Hall-Littlewood `Q` basis. This is the same as the `Q` basis in John Stembridge's SF examples file. @@ -327,9 +315,7 @@ def Q(self): - ``self`` -- a class of Hall-Littlewood symmetric function bases - OUTPUT: - - - returns the class of the Hall-Littlewood `Q` basis + OUTPUT: the class of the Hall-Littlewood `Q` basis EXAMPLES:: @@ -343,7 +329,7 @@ def Q(self): def Qp(self): r""" - Returns the algebra of symmetric functions in Hall-Littlewood `Q^\prime` (Qp) + Return the algebra of symmetric functions in Hall-Littlewood `Q^\prime` (Qp) basis. This is dual to the Hall-Littlewood `P` basis with respect to the standard scalar product. @@ -354,9 +340,7 @@ def Qp(self): - ``self`` -- a class of Hall-Littlewood symmetric function bases - OUTPUT: - - - returns the class of the Hall-Littlewood `Qp`-basis + OUTPUT: the class of the Hall-Littlewood `Qp`-basis EXAMPLES:: @@ -426,16 +410,14 @@ def construction(self): def _s_to_self(self, x): r""" - Isomorphism from the Schur basis into ``self`` + Isomorphism from the Schur basis into ``self``. INPUT: - ``self`` -- a Hall-Littlewood symmetric function basis - ``x`` -- an element of the Schur basis - OUTPUT: - - - an element of ``self`` equivalent to ``x`` + OUTPUT: an element of ``self`` equivalent to ``x`` EXAMPLES:: @@ -454,16 +436,14 @@ def _s_to_self(self, x): def _self_to_s(self, x): r""" - Isomorphism from ``self`` to the Schur basis + Isomorphism from ``self`` to the Schur basis. INPUT: - ``self`` -- a Hall-Littlewood symmetric function basis - ``x`` -- an element of the basis ``self`` - OUTPUT: - - - an element of the Schur basis equivalent to ``x`` + OUTPUT: an element of the Schur basis equivalent to ``x`` EXAMPLES:: @@ -483,14 +463,14 @@ def _self_to_s(self, x): def transition_matrix(self, basis, n): r""" - Returns the transitions matrix between ``self`` and ``basis`` for the + Return the transitions matrix between ``self`` and ``basis`` for the homogeneous component of degree ``n``. INPUT: - ``self`` -- a Hall-Littlewood symmetric function basis - ``basis`` -- another symmetric function basis - - ``n`` -- a non-negative integer representing the degree + - ``n`` -- nonnegative integer representing the degree OUTPUT: @@ -543,9 +523,7 @@ def product(self, left, right): - ``left`` -- an element of the basis ``self`` - ``right`` -- another symmetric function - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -566,15 +544,13 @@ def product(self, left, right): def hall_littlewood_family(self): r""" - The family of Hall-Littlewood bases associated to ``self`` + The family of Hall-Littlewood bases associated to ``self``. INPUT: - ``self`` -- a Hall-Littlewood symmetric function basis - OUTPUT: - - - returns the class of Hall-Littlewood bases + OUTPUT: the class of Hall-Littlewood bases EXAMPLES:: @@ -591,17 +567,15 @@ class Element(sfa.SymmetricFunctionAlgebra_generic.Element): def expand(self, n, alphabet='x'): r""" - Expands the symmetric function as a symmetric polynomial in ``n`` variables. + Expand the symmetric function as a symmetric polynomial in ``n`` variables. INPUT: - ``self`` -- an element of a Hall-Littlewood basis - - ``n`` -- a positive integer - - ``alphabet`` -- a string representing a variable name (default: 'x') - - OUTPUT: + - ``n`` -- positive integer + - ``alphabet`` -- string representing a variable name (default: ``'x'``) - - returns a symmetric polynomial of ``self`` in ``n`` variables + OUTPUT: a symmetric polynomial of ``self`` in ``n`` variables EXAMPLES:: @@ -625,7 +599,7 @@ def expand(self, n, alphabet='x'): def scalar(self, x, zee=None): r""" - Returns standard scalar product between ``self`` and ``x``. + Return standard scalar product between ``self`` and ``x``. This is the default implementation that converts both ``self`` and ``x`` into Schur functions and performs the scalar product that basis. @@ -638,9 +612,7 @@ def scalar(self, x, zee=None): - ``self`` -- an element of a Hall-Littlewood basis - ``x`` -- another symmetric element of the symmetric functions - OUTPUT: - - - returns the scalar product between ``self`` and ``x`` + OUTPUT: the scalar product between ``self`` and ``x`` EXAMPLES:: @@ -664,7 +636,7 @@ def scalar(self, x, zee=None): def scalar_hl(self, x, t=None): r""" - Returns the Hall-Littlewood (with parameter ``t``) scalar product + Return the Hall-Littlewood (with parameter ``t``) scalar product of ``self`` and ``x``. The Hall-Littlewood scalar product is defined in Macdonald's @@ -681,9 +653,7 @@ def scalar_hl(self, x, t=None): - ``t`` -- an optional parameter, if this parameter is not specified then the value of the ``t`` from the basis is used in the calculation - OUTPUT: - - - returns the Hall-Littlewood scalar product between ``self`` and ``x`` + OUTPUT: the Hall-Littlewood scalar product between ``self`` and ``x`` EXAMPLES:: @@ -724,7 +694,7 @@ class Element(HallLittlewood_generic.Element): def __init__(self, hall_littlewood): r""" - A class with methods for working with the Hall-Littlewood `P` basis + A class with methods for working with the Hall-Littlewood `P` basis. The `P` basis is calculated from the Schur basis using the functions in :meth:`sage.combinat.sf.kfpoly`. These functions calculate Kostka-Foulkes polynomials @@ -781,7 +751,7 @@ def _q_to_p_normalization(self, m): def _s_to_self_base(self, part): r""" - Returns a function which gives the coefficient of a partition + Return a function which gives the coefficient of a partition in the expansion of the Schur functions ``s(part)`` in the Hall-Littlewood `P` basis. @@ -813,7 +783,7 @@ def _s_to_self_base(self, part): def _s_cache(self, n): r""" - Computes the change of basis between the `P` polynomials and the + Compute the change of basis between the `P` polynomials and the Schur functions for partitions of size ``n``. Uses the fact that the transformation matrix is upper-triangular in @@ -895,7 +865,7 @@ def __init__(self, hall_littlewood): def _p_to_q_normalization(self, m): r""" - Returns the scalar coefficient on self(m) when converting from the + Return the scalar coefficient on self(m) when converting from the `Q` basis to the `P` basis. Note that this assumes that ``m`` is a Partition object. @@ -984,7 +954,7 @@ def __init__(self, hall_littlewood): def _to_s(self, part): r""" - Returns a function which gives the coefficient of a partition + Return a function which gives the coefficient of a partition in the Schur expansion of ``self(part)``. INPUT: @@ -1018,7 +988,7 @@ def _to_s(self, part): def _s_cache(self, n): r""" - Computes the change of basis between the `Q^\prime` polynomials and the + Compute the change of basis between the `Q^\prime` polynomials and the Schur functions for partitions of size ``n``. Uses the fact that the transformation matrix is lower-triangular in @@ -1027,7 +997,7 @@ def _s_cache(self, n): INPUT: - ``self`` -- an instance of the Hall-Littlewood `P` basis - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: diff --git a/src/sage/combinat/sf/hecke.py b/src/sage/combinat/sf/hecke.py index e0b7f965ba7..aec6860cdc5 100644 --- a/src/sage/combinat/sf/hecke.py +++ b/src/sage/combinat/sf/hecke.py @@ -176,7 +176,7 @@ def __init__(self, sym, q): self.q = q SymmetricFunctionAlgebra_multiplicative.__init__(self, sym, basis_name="Hecke character with q={}".format(self.q), - prefix="qbar") + prefix='qbar') self._p = sym.power() # temporary until Hom(GradedHopfAlgebrasWithBasis work better) @@ -206,11 +206,11 @@ def construction(self): def _p_to_qbar_on_generator(self, n): r""" - Convert `p_n` to ``self`` + Convert `p_n` to ``self``. INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -238,7 +238,7 @@ def _p_to_qbar_on_basis(self, mu): INPUT: - - ``mu`` -- a partition or a list of non-negative integers + - ``mu`` -- a partition or a list of nonnegative integers EXAMPLES:: @@ -260,7 +260,7 @@ def _qbar_to_p_on_generator(self, n): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -290,7 +290,7 @@ def _qbar_to_p_on_basis(self, mu): INPUT: - - ``mu`` -- a partition or a list of non-negative integers + - ``mu`` -- a partition or a list of nonnegative integers EXAMPLES:: diff --git a/src/sage/combinat/sf/homogeneous.py b/src/sage/combinat/sf/homogeneous.py index 29cf294ea80..e6bc361f3b0 100644 --- a/src/sage/combinat/sf/homogeneous.py +++ b/src/sage/combinat/sf/homogeneous.py @@ -61,15 +61,15 @@ def _dual_basis_default(self): INPUT: - ``self`` -- a homogeneous basis of symmetric functions - - ``scalar`` -- optional input which specifies a function ``zee`` + - ``scalar`` -- (optional) input which specifies a function ``zee`` on partitions. The function ``zee`` determines the scalar product on the power sum basis with normalization `\langle p_\mu, p_\mu \rangle = \mathrm{zee}(mu)`. (default: uses standard ``zee`` function) - ``scalar_name`` -- specifies the name of the scalar function (optional) - - ``prefix`` -- optional input, specifies the prefix to be - used to display the basis. + - ``prefix`` -- (optional) input which specifies the prefix to be + used to display the basis OUTPUT: @@ -107,11 +107,9 @@ def coproduct_on_generators(self, i): INPUT: - ``self`` -- a homogeneous basis of symmetric functions - - ``i`` -- a nonnegative integer + - ``i`` -- nonnegative integer - OUTPUT: - - - the sum `\sum_{r=0}^i h_r \otimes h_{i-r}` + OUTPUT: the sum `\sum_{r=0}^i h_r \otimes h_{i-r}` EXAMPLES:: @@ -164,9 +162,7 @@ def omega(self): :meth:`omega_involution()` is a synonym for the :meth:`omega()` method. - OUTPUT: - - - the image of ``self`` under the omega automorphism + OUTPUT: the image of ``self`` under the omega automorphism EXAMPLES:: @@ -191,7 +187,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -253,12 +249,12 @@ def principal_specialization(self, n=infinity, q=None): INPUT: - - ``n`` (default: ``infinity``) -- a nonnegative integer or + - ``n`` -- (default: ``infinity``) a nonnegative integer or ``infinity``, specifying whether to compute the principal specialization of order ``n`` or the stable principal specialization. - - ``q`` (default: ``None``) -- the value to use for `q`; the + - ``q`` -- (default: ``None``) the value to use for `q`; the default is to create a ring of polynomials in ``q`` (or a field of rational functions in ``q``) over the given coefficient ring. @@ -289,7 +285,6 @@ def principal_specialization(self, n=infinity, q=None): sage: x = h.zero() sage: s = x.principal_specialization(3); s 0 - """ from sage.combinat.q_analogues import q_binomial @@ -363,12 +358,12 @@ def exponential_specialization(self, t=None, q=1): INPUT: - - ``t`` (default: ``None``) -- the value to use for `t`; - the default is to create a ring of polynomials in ``t``. + - ``t`` -- (default: ``None``) the value to use for `t`; + the default is to create a ring of polynomials in ``t`` - - ``q`` (default: `1`) -- the value to use for `q`. If + - ``q`` -- (default: `1`) the value to use for `q`; if ``q`` is ``None``, then a ring (or fraction field) of - polynomials in ``q`` is created. + polynomials in ``q`` is created EXAMPLES:: @@ -393,7 +388,6 @@ def exponential_specialization(self, t=None, q=1): sage: x = h.zero() sage: s = x.exponential_specialization(); s 0 - """ from sage.combinat.q_analogues import q_factorial @@ -441,4 +435,6 @@ def f(partition): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.homogeneous', 'SymmetricFunctionAlgebraElement_homogeneous', SymmetricFunctionAlgebra_homogeneous.Element) +register_unpickle_override('sage.combinat.sf.homogeneous', + 'SymmetricFunctionAlgebraElement_homogeneous', + SymmetricFunctionAlgebra_homogeneous.Element) diff --git a/src/sage/combinat/sf/jack.py b/src/sage/combinat/sf/jack.py index e70959f8dfc..f104af0d9d5 100644 --- a/src/sage/combinat/sf/jack.py +++ b/src/sage/combinat/sf/jack.py @@ -77,7 +77,7 @@ def __init__(self, Sym, t): - ``self`` -- the family of Jack symmetric function bases - ``Sym`` -- a ring of symmetric functions - - ``t`` -- an optional parameter (default : 't') + - ``t`` -- an optional parameter (default: ``'t'``) EXAMPLES:: @@ -95,15 +95,13 @@ def __init__(self, Sym, t): def __repr__(self): r""" - The string representation for the family of Jack symmetric function bases + The string representation for the family of Jack symmetric function bases. INPUT: - ``self`` -- the family of Jack symmetric function bases - OUTPUT: - - - returns the name of the family of bases + OUTPUT: the name of the family of bases EXAMPLES:: @@ -114,16 +112,14 @@ def __repr__(self): def base_ring( self ): r""" - Returns the base ring of the symmetric functions in which the - Jack symmetric functions live + Return the base ring of the symmetric functions in which the + Jack symmetric functions live. INPUT: - ``self`` -- the family of Jack symmetric function bases - OUTPUT: - - - the base ring of the symmetric functions ring of ``self`` + OUTPUT: the base ring of the symmetric functions ring of ``self`` EXAMPLES:: @@ -135,16 +131,14 @@ def base_ring( self ): def symmetric_function_ring( self ): r""" - Returns the base ring of the symmetric functions of the Jack symmetric + Return the base ring of the symmetric functions of the Jack symmetric function bases INPUT: - ``self`` -- the family of Jack symmetric function bases - OUTPUT: - - - the symmetric functions ring of ``self`` + OUTPUT: the symmetric functions ring of ``self`` EXAMPLES:: @@ -156,15 +150,13 @@ def symmetric_function_ring( self ): def P(self): r""" - Returns the algebra of Jack polynomials in the `P` basis. + Return the algebra of Jack polynomials in the `P` basis. INPUT: - ``self`` -- the family of Jack symmetric function bases - OUTPUT: - - - the `P` basis of the Jack symmetric functions + OUTPUT: the `P` basis of the Jack symmetric functions EXAMPLES:: @@ -261,15 +253,13 @@ def P(self): def Q(self): r""" - Returns the algebra of Jack polynomials in the `Q` basis. + Return the algebra of Jack polynomials in the `Q` basis. INPUT: - ``self`` -- the family of Jack symmetric function bases - OUTPUT: - - - the `Q` basis of the Jack symmetric functions + OUTPUT: the `Q` basis of the Jack symmetric functions EXAMPLES:: @@ -302,7 +292,7 @@ def Q(self): def J(self): r""" - Returns the algebra of Jack polynomials in the `J` basis. + Return the algebra of Jack polynomials in the `J` basis. INPUT: @@ -365,16 +355,14 @@ def J(self): def Qp(self): r""" - Returns the algebra of Jack polynomials in the `Qp`, which is dual to + Return the algebra of Jack polynomials in the `Qp`, which is dual to the `P` basis with respect to the standard scalar product. INPUT: - ``self`` -- the family of Jack symmetric function bases - OUTPUT: - - - the `Q'` basis of the Jack symmetric functions + OUTPUT: the `Q'` basis of the Jack symmetric functions EXAMPLES:: @@ -399,7 +387,7 @@ def Qp(self): def c1(part, t): r""" - Returns the `t`-Jack scalar product between ``J(part)`` and ``P(part)``. + Return the `t`-Jack scalar product between ``J(part)`` and ``P(part)``. INPUT: @@ -425,7 +413,7 @@ def c1(part, t): def c2(part, t): r""" - Returns the t-Jack scalar product between ``J(part)`` and ``Q(part)``. + Return the t-Jack scalar product between ``J(part)`` and ``Q(part)``. INPUT: @@ -462,9 +450,7 @@ def normalize_coefficients(self, c): - ``self`` -- a Jack basis of the symmetric functions - ``c`` -- a coefficient in the base ring of ``self`` - OUTPUT: - - - divide numerator and denominator by the greatest common divisor + OUTPUT: divide numerator and denominator by the greatest common divisor EXAMPLES:: @@ -510,7 +496,7 @@ def normalize_coefficients(self, c): class JackPolynomials_generic(sfa.SymmetricFunctionAlgebra_generic): def __init__(self, jack): r""" - A class of methods which are common to all Jack bases of the symmetric functions + A class of methods which are common to all Jack bases of the symmetric functions. INPUT: @@ -571,16 +557,14 @@ def construction(self): def _m_to_self(self, x): r""" - Isomorphism from the monomial basis into ``self`` + Isomorphism from the monomial basis into ``self``. INPUT: - ``self`` -- a Jack basis of the symmetric functions - ``x`` -- element of the monomial basis - OUTPUT: - - - an element of ``self`` equivalent to ``x`` + OUTPUT: an element of ``self`` equivalent to ``x`` EXAMPLES:: @@ -600,16 +584,14 @@ def _m_to_self(self, x): def _self_to_m(self, x): r""" - Isomorphism from self to the monomial basis + Isomorphism from ``self`` to the monomial basis. INPUT: - ``self`` -- a Jack basis of the symmetric functions - ``x`` -- an element of ``self`` - OUTPUT: - - - an element of the monomial basis equivalent to ``x`` + OUTPUT: an element of the monomial basis equivalent to ``x`` EXAMPLES:: @@ -629,7 +611,7 @@ def _self_to_m(self, x): def c1(self, part): r""" - Returns the `t`-Jack scalar product between ``J(part)`` and ``P(part)``. + Return the `t`-Jack scalar product between ``J(part)`` and ``P(part)``. INPUT: @@ -653,7 +635,7 @@ def c1(self, part): def c2(self, part): r""" - Returns the `t`-Jack scalar product between ``J(part)`` and ``Q(part)``. + Return the `t`-Jack scalar product between ``J(part)`` and ``Q(part)``. INPUT: @@ -679,16 +661,14 @@ def c2(self, part): def _normalize(self, x): r""" - Normalize the coefficients of ``x`` + Normalize the coefficients of ``x``. INPUT: - ``self`` -- a Jack basis of the symmetric functions - ``x`` -- an element of ``self`` - OUTPUT: - - - returns ``x`` with _normalize_coefficient applied to each of the coefficients + OUTPUT: ``x`` with _normalize_coefficient applied to each of the coefficients EXAMPLES:: @@ -706,17 +686,13 @@ def _normalize(self, x): def _normalize_morphism(self, category): r""" - Returns the normalize morphism + Return the normalize morphism. INPUT: - ``self`` -- a Jack basis of the symmetric functions - ``category`` -- a category - OUTPUT: - - - the normalized morphism - EXAMPLES:: sage: JP = SymmetricFunctions(FractionField(QQ['t'])).jack().P() @@ -751,9 +727,7 @@ def product(self, left, right): - ``self`` -- a Jack basis of the symmetric functions - ``left``, ``right`` -- symmetric function elements - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -772,16 +746,12 @@ def product(self, left, right): def jack_family(self): r""" - Returns the family of Jack bases associated to the basis ``self`` + Return the family of Jack bases associated to the basis ``self``. INPUT: - ``self`` -- a Jack basis of the symmetric functions - OUTPUT: - - - the family of Jack symmetric functions associated to ``self`` - EXAMPLES:: sage: JackP = SymmetricFunctions(QQ).jack(t=2).P() @@ -792,7 +762,7 @@ def jack_family(self): def coproduct_by_coercion(self, elt): r""" - Returns the coproduct of the element ``elt`` by coercion to the Schur basis. + Return the coproduct of the element ``elt`` by coercion to the Schur basis. INPUT: @@ -828,12 +798,10 @@ def scalar_jack(self, x, t=None): - ``self`` -- an element of a Jack basis of the symmetric functions - ``x`` -- an element of the symmetric functions - - ``t`` -- an optional parameter (default : None uses the parameter from - the basis) - - OUTPUT: + - ``t`` -- an optional parameter (default: ``None``; uses the + parameter from the basis) - - returns the Jack scalar product between ``x`` and ``self`` + OUTPUT: the Jack scalar product between ``x`` and ``self`` EXAMPLES:: @@ -855,7 +823,7 @@ def scalar_jack(self, x, t=None): def part_scalar_jack(part1, part2, t): r""" - Returns the Jack scalar product between ``p(part1)`` and ``p(part2)`` where + Return the Jack scalar product between ``p(part1)`` and ``p(part2)`` where `p` is the power-sum basis. INPUT: @@ -863,9 +831,7 @@ def part_scalar_jack(part1, part2, t): - ``part1``, ``part2`` -- two partitions - ``t`` -- a parameter - OUTPUT: - - - returns the scalar product between the power sum indexed by ``part1`` and ``part2`` + OUTPUT: the scalar product between the power sum indexed by ``part1`` and ``part2`` EXAMPLES:: @@ -913,14 +879,14 @@ def __init__(self, jack): def _m_cache(self, n): r""" - Computes the change of basis between the Jack polynomials in the `P` + Compute the change of basis between the Jack polynomials in the `P` basis and the monomial symmetric functions. This uses Gram-Schmidt to go to the monomials, and then that matrix is simply inverted. INPUT: - ``self`` -- an instance of the Jack `P` basis of the symmetric functions - - ``n`` -- a positive integer indicating the degree + - ``n`` -- positive integer indicating the degree EXAMPLES:: @@ -997,9 +963,7 @@ def product(self, left, right): - ``self`` -- a Jack basis of the symmetric functions - ``left``, ``right`` -- symmetric function elements - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -1019,7 +983,7 @@ def product(self, left, right): def scalar_jack_basis(self, part1, part2=None): r""" - Returns the scalar product of `P(part1)` and `P(part2)`. + Return the scalar product of `P(part1)` and `P(part2)`. This is equation (10.16) of [Mc1995]_ on page 380. @@ -1027,7 +991,7 @@ def scalar_jack_basis(self, part1, part2=None): - ``self`` -- an instance of the Jack `P` basis of the symmetric functions - ``part1`` -- a partition - - ``part2`` -- an optional partition (default : None) + - ``part2`` -- an optional partition (default: ``None``) OUTPUT: @@ -1096,7 +1060,7 @@ class JackPolynomials_j(JackPolynomials_generic): def __init__(self, jack): r""" - The `J` basis is a defined as a normalized form of the `P` basis + The `J` basis is a defined as a normalized form of the `P` basis. INPUT: @@ -1132,7 +1096,7 @@ class JackPolynomials_q(JackPolynomials_generic): def __init__(self, jack): r""" - The `Q` basis is defined as a normalized form of the `P` basis + The `Q` basis is defined as a normalized form of the `P` basis. INPUT: @@ -1201,9 +1165,7 @@ def product(self, left, right): - ``self`` -- an instance of the Jack `Qp` basis of the symmetric functions - ``left``, ``right`` -- symmetric function elements - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -1224,14 +1186,14 @@ def product(self, left, right): def _h_cache(self, n): r""" - Computes the change of basis between the Jack polynomials in the `Qp` + Compute the change of basis between the Jack polynomials in the `Qp` basis and the homogeneous symmetric functions. This uses the coefficients in the change of basis between the Jack `P` basis and the monomial basis. INPUT: - ``self`` -- an instance of the Jack `Qp` basis of the symmetric functions - - ``n`` -- a positive integer indicating the degree + - ``n`` -- positive integer indicating the degree EXAMPLES:: @@ -1273,16 +1235,14 @@ def _h_cache(self, n): def _self_to_h( self, x ): r""" - Isomorphism from self to the homogeneous basis + Isomorphism from ``self`` to the homogeneous basis. INPUT: - ``self`` -- a Jack `Qp` basis of the symmetric functions - ``x`` -- an element of the Jack `Qp` basis - OUTPUT: - - - an element of the homogeneous basis equivalent to ``x`` + OUTPUT: an element of the homogeneous basis equivalent to ``x`` EXAMPLES:: @@ -1302,16 +1262,14 @@ def _self_to_h( self, x ): def _h_to_self(self, x): r""" - Isomorphism from the homogeneous basis into ``self`` + Isomorphism from the homogeneous basis into ``self``. INPUT: - ``self`` -- a Jack `Qp` basis of the symmetric functions - ``x`` -- element of the homogeneous basis - OUTPUT: - - - an element of the Jack `Qp` basis equivalent to ``x`` + OUTPUT: an element of the Jack `Qp` basis equivalent to ``x`` EXAMPLES:: @@ -1331,7 +1289,7 @@ def _h_to_self(self, x): def coproduct_by_coercion(self, elt): r""" - Returns the coproduct of the element ``elt`` by coercion to the Schur basis. + Return the coproduct of the element ``elt`` by coercion to the Schur basis. INPUT: @@ -1367,7 +1325,7 @@ class Element(JackPolynomials_generic.Element): class SymmetricFunctionAlgebra_zonal(sfa.SymmetricFunctionAlgebra_generic): def __init__(self, Sym): r""" - Returns the algebra of zonal polynomials. + Return the algebra of zonal polynomials. INPUT: @@ -1389,7 +1347,7 @@ def __init__(self, Sym): #self._m_to_self_cache = {} Now that we compute Jacks once, there is a global cache #self._self_to_m_cache = {} and we don't need to compute it separately for zonals sfa.SymmetricFunctionAlgebra_generic.__init__(self, self._sym, - prefix="Z", basis_name="zonal") + prefix='Z', basis_name='zonal') category = sage.categories.all.ModulesWithBasis(self._sym.base_ring()) self .register_coercion(SetMorphism(Hom(self._P, self, category), self.sum_of_terms)) self._P.register_coercion(SetMorphism(Hom(self, self._P, category), self._P.sum_of_terms)) @@ -1405,9 +1363,7 @@ def product(self, left, right): - ``self`` -- a zonal basis of the symmetric functions - ``left``, ``right`` -- symmetric function elements - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -1436,9 +1392,7 @@ def scalar_zonal(self, x): - ``self`` -- an element of the zonal basis - ``x`` -- an element of the symmetric function - OUTPUT: - - - the scalar product between ``self`` and ``x`` + OUTPUT: the scalar product between ``self`` and ``x`` EXAMPLES:: diff --git a/src/sage/combinat/sf/k_dual.py b/src/sage/combinat/sf/k_dual.py index 62b3a2f8e72..ad7471ec001 100644 --- a/src/sage/combinat/sf/k_dual.py +++ b/src/sage/combinat/sf/k_dual.py @@ -56,7 +56,7 @@ def __init__(self, Sym, k, t='t'): - ``Sym`` -- an element of class :class:`sage.combinat.sf.sf.SymmetricFunctions` - - ``k`` -- a positive integer + - ``k`` -- positive integer - ``R`` -- a ring @@ -121,7 +121,6 @@ def __init__(self, Sym, k, t='t'): TESTS:: sage: TestSuite(Q).run() - """ R = Sym.base_ring() self.k = k @@ -147,13 +146,12 @@ def ambient(self): sage: Q = Sym.kBoundedQuotient(3,t=1) sage: Q.ambient() Symmetric Functions over Rational Field - """ return self._sym def a_realization(self): r""" - Returns a particular realization of ``self`` (the basis of `k`-bounded monomials + Return a particular realization of ``self`` (the basis of `k`-bounded monomials if `t=1` and the basis of `k`-bounded Hall-Littlewood functions otherwise). EXAMPLES:: @@ -251,19 +249,18 @@ def affineSchur(self): @cached_method def _G_to_km_on_basis_single_level(self, w, m): r""" - Returns the `m^{th}` level of the affine Grothendieck polynomial indexed by the - affine Permutation ``w``. This code could be significantly sped up if it didn't - depend on the Iwahori Hecke algebra code. + Return the `m`-th level of the affine Grothendieck + polynomial indexed by the affine Permutation ``w``. This code could be + significantly sped up if it didn't depend on the Iwahori Hecke algebra + code. INPUT: - - ``w`` -- An affine permutation (an element of the affine type `A` Weyl group). + - ``w`` -- an affine permutation (an element of the affine type `A` Weyl group) - - ``m`` -- An integer. + - ``m`` -- integer - OUTPUT: - - - An element of the `k`-bounded quotient. + OUTPUT: an element of the `k`-bounded quotient EXAMPLES:: @@ -275,7 +272,6 @@ def _G_to_km_on_basis_single_level(self, w, m): m3[1, 1, 1, 1] sage: Q._G_to_km_on_basis_single_level(W.an_element(), 5) -4*m3[1, 1, 1, 1, 1] - """ kB = self._sym.kBoundedSubspace(self.k,t=1) g = kB.K_kschur() @@ -289,20 +285,18 @@ def _G_to_km_on_basis_single_level(self, w, m): def _AffineGrothendieck(self, w, m): r""" - Returns the affine Grothendieck polynomial indexed by the affine permutation + Return the affine Grothendieck polynomial indexed by the affine permutation ``w``. Because this belongs to the completion of the algebra, and hence is an infinite sum, it computes only up to those symmetric functions of degree at most ``m``. INPUT: - - ``w`` -- An affine permutation (an element of the affine type `A` Weyl group). + - ``w`` -- an affine permutation (an element of the affine type `A` Weyl group) - - ``m`` -- An integer. + - ``m`` -- integer - OUTPUT: - - - An element of the `k`-bounded quotient. + OUTPUT: an element of the `k`-bounded quotient EXAMPLES:: @@ -316,16 +310,16 @@ def _AffineGrothendieck(self, w, m): @cached_method def _AffineGrothendieckPolynomial(self, la, m): r""" - Returns the affine Grothendieck polynomial indexed by the partition ``la``. + Return the affine Grothendieck polynomial indexed by the partition ``la``. Because this belongs to the completion of the algebra, and hence is an infinite sum, it computes only up to those symmetric functions of degree at most ``m``. This method is here to cache the polynomials. INPUT: - - ``la`` -- A `k`-bounded partition + - ``la`` -- a `k`-bounded partition - - ``m`` -- An integer + - ``m`` -- integer EXAMPLES:: @@ -337,16 +331,16 @@ def _AffineGrothendieckPolynomial(self, la, m): def AffineGrothendieckPolynomial(self, la, m): r""" - Returns the affine Grothendieck polynomial indexed by the partition ``la``. + Return the affine Grothendieck polynomial indexed by the partition ``la``. Because this belongs to the completion of the algebra, and hence is an infinite sum, it computes only up to those symmetric functions of degree at most ``m``. See :meth:`_AffineGrothendieckPolynomial` for the code. INPUT: - - ``la`` -- A `k`-bounded partition + - ``la`` -- a `k`-bounded partition - - ``m`` -- An integer + - ``m`` -- integer EXAMPLES:: @@ -360,7 +354,7 @@ def AffineGrothendieckPolynomial(self, la, m): def an_element(self): r""" - Returns an element of the quotient ring of `k`-bounded symmetric functions. This + Return an element of the quotient ring of `k`-bounded symmetric functions. This method is here to make the TestSuite run properly. EXAMPLES:: @@ -373,7 +367,7 @@ def an_element(self): def one(self): r""" - Returns the unit of the quotient ring of `k`-bounded symmetric functions. This + Return the unit of the quotient ring of `k`-bounded symmetric functions. This method is here to make the TestSuite run properly. EXAMPLES:: @@ -386,17 +380,15 @@ def one(self): def retract(self,la): r""" - Gives the retract map from the symmetric functions to the quotient ring of + Give the retract map from the symmetric functions to the quotient ring of `k`-bounded symmetric functions. This method is here to make the TestSuite run properly. INPUT: - - ``la`` -- A partition - - OUTPUT: + - ``la`` -- a partition - - The monomial element of the `k`-bounded quotient indexed by ``la``. + OUTPUT: the monomial element of the `k`-bounded quotient indexed by ``la`` EXAMPLES:: @@ -409,12 +401,12 @@ def retract(self,la): def lift(self, la): r""" - Gives the lift map from the quotient ring of `k`-bounded symmetric functions to + Give the lift map from the quotient ring of `k`-bounded symmetric functions to the symmetric functions. This method is here to make the TestSuite run properly. INPUT: - - ``la`` -- A `k`-bounded partition + - ``la`` -- a `k`-bounded partition OUTPUT: @@ -502,17 +494,15 @@ class ParentMethods: def retract(self,la): r""" - Gives the retract map from the symmetric functions to the quotient ring of + Give the retract map from the symmetric functions to the quotient ring of `k`-bounded symmetric functions. This method is here to make the TestSuite run properly. INPUT: - - ``la`` -- A partition + - ``la`` -- a partition - OUTPUT: - - - The monomial element of the `k`-bounded quotient indexed by ``la``. + OUTPUT: the monomial element of the `k`-bounded quotient indexed by ``la`` EXAMPLES:: @@ -533,9 +523,7 @@ def _element_constructor_(self, x): - ``x`` -- a `k`-bounded partition - OUTPUT: - - - an element of the `k`-bounded basis + OUTPUT: an element of the `k`-bounded basis EXAMPLES:: @@ -565,7 +553,7 @@ def _element_constructor_(self, x): def ambient(self): r""" - Returns the symmetric functions. + Return the symmetric functions. EXAMPLES:: @@ -577,7 +565,7 @@ def ambient(self): def __getitem__(self, c): r""" - Implements shorthand for accessing basis elements. + Implement shorthand for accessing basis elements. For a basis `X` indexed by partitions, this method allows for `X[[3,2]]` and `X[3,2]` to be equivalent to `X[Partition([3,2])]`. @@ -648,7 +636,7 @@ def degree_on_basis(self, b): def indices(self): r""" - The set of `k`-bounded partitions of all non-negative integers. + The set of `k`-bounded partitions of all nonnegative integers. EXAMPLES:: @@ -660,16 +648,14 @@ def indices(self): def lift(self, la): r""" - Implements the lift map from the basis ``self`` to the monomial basis of + Implement the lift map from the basis ``self`` to the monomial basis of symmetric functions. INPUT: - - ``la`` -- A `k`-bounded partition. - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - A symmetric function in the monomial basis. + OUTPUT: a symmetric function in the monomial basis EXAMPLES:: @@ -689,15 +675,13 @@ def lift(self, la): def product(self, x, y): r""" - Returns the product of two elements ``x`` and ``y``. + Return the product of two elements ``x`` and ``y``. INPUT: - - ``x``, ``y`` -- Elements of the `k`-bounded quotient of symmetric functions. + - ``x``, ``y`` -- elements of the `k`-bounded quotient of symmetric functions - OUTPUT: - - - A `k`-bounded symmetric function in the dual `k`-Schur function basis + OUTPUT: a `k`-bounded symmetric function in the dual `k`-Schur function basis EXAMPLES:: @@ -888,12 +872,12 @@ class KBoundedQuotientBasis(CombinatorialFreeModule): def __init__(self, kBoundedRing, prefix): r""" - Initializes ``self``. + Initialize ``self``. INPUT: - ``kBoundedRing`` -- an element which is of class :class:`KBoundedQuotient` - - ``prefix`` -- a string used to distinguish this basis, and used in printing. + - ``prefix`` -- string used to distinguish this basis, and used in printing EXAMPLES:: @@ -903,7 +887,6 @@ def __init__(self, kBoundedRing, prefix): 'm4' sage: isinstance(km, sage.combinat.sf.k_dual.KBoundedQuotientBasis) True - """ CombinatorialFreeModule.__init__(self, kBoundedRing.base_ring(), kBoundedRing.indices(), @@ -931,7 +914,7 @@ class kMonomial(KBoundedQuotientBasis): def __init__(self, kBoundedRing): r""" - Initializes the ring which is the `k`-Bounded monomial quotient basis. + Initialize the ring which is the `k`-Bounded monomial quotient basis. INPUT: @@ -962,18 +945,16 @@ def _repr_(self): def retract(self, la): r""" - Implements the retract function on the monomial basis. Given a partition ``la``, + Implement the retract function on the monomial basis. Given a partition ``la``, the retract will return the corresponding `k`-bounded monomial basis element if ``la`` is `k`-bounded; zero otherwise. INPUT: - - ``la`` -- A partition - - OUTPUT: + - ``la`` -- a partition - - A `k`-bounded monomial symmetric function in the `k`-quotient of symmetric - functions. + OUTPUT: a `k`-bounded monomial symmetric function in the `k`-quotient of symmetric + functions EXAMPLES:: @@ -1015,16 +996,14 @@ def retract(self, la): def lift(self, la): r""" - Implements the lift function on the monomial basis. Given a `k`-bounded partition + Implement the lift function on the monomial basis. Given a `k`-bounded partition ``la``, the lift will return the corresponding monomial basis element. INPUT: - - ``la`` -- A `k`-bounded partition - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - A monomial symmetric function. + OUTPUT: a monomial symmetric function EXAMPLES:: @@ -1050,7 +1029,7 @@ class kbounded_HallLittlewoodP(KBoundedQuotientBasis): def __init__(self, kBoundedRing): r""" - Initializes the ring which is the `k`-Bounded Hall-Littlewood P quotient basis. + Initialize the ring which is the `k`-Bounded Hall-Littlewood P quotient basis. INPUT: @@ -1085,7 +1064,7 @@ def _repr_(self): def _m_to_kHLP_on_basis(self, la): r""" - Converts from the monomial basis to the `k`-bounded Hall-Littlewood + Convert from the monomial basis to the `k`-bounded Hall-Littlewood P basis. If ``la`` is not `k`-bounded then it returns the projection of the monomial by the ideal generated by the Hall-Littlewood P basis indexed by partitions whose first part is greater than `k`. @@ -1094,9 +1073,7 @@ def _m_to_kHLP_on_basis(self, la): - ``la`` -- a partition - OUTPUT: - - - an element of the `k`-bounded Hall-Littlewood P basis. + OUTPUT: an element of the `k`-bounded Hall-Littlewood P basis EXAMPLES:: @@ -1136,16 +1113,14 @@ def _m_to_kHLP_on_basis(self, la): def _HLP_to_mk_on_basis(self, la): r""" - Converts from the Hall-Littlewood P basis to the `k`-bounded monomial basis and + Convert from the Hall-Littlewood P basis to the `k`-bounded monomial basis and projects into the `k`-bounded quotient if ``la`` is not a bounded partition. INPUT: - ``la`` -- a partition - OUTPUT: - - - an element of the `k`-bounded monomial basis + OUTPUT: an element of the `k`-bounded monomial basis EXAMPLES:: @@ -1176,18 +1151,16 @@ def _HLP_to_mk_on_basis(self, la): def retract(self, la): r""" - Implements the retract function on the Hall-Littlewood P basis. Given a partition + Implement the retract function on the Hall-Littlewood P basis. Given a partition ``la``, the retract will return the corresponding `k`-bounded Hall-Littlewood P basis element if ``la`` is `k`-bounded; zero otherwise. INPUT: - - ``la`` -- A partition + - ``la`` -- a partition - OUTPUT: - - - A `k`-bounded Hall-Littlewood P symmetric function in the `k`-quotient of - symmetric functions. + OUTPUT: a `k`-bounded Hall-Littlewood P symmetric function in the `k`-quotient of + symmetric functions EXAMPLES:: @@ -1212,17 +1185,15 @@ def retract(self, la): def lift(self, la): r""" - Implements the lift function on the Hall-Littlewood P basis. Given a `k`-bounded + Implement the lift function on the Hall-Littlewood P basis. Given a `k`-bounded partition ``la``, the lift will return the corresponding Hall-Littlewood P basis element. INPUT: - - ``la`` -- A `k`-bounded partition + - ``la`` -- a `k`-bounded partition - OUTPUT: - - - A Hall-Littlewood symmetric function. + OUTPUT: a Hall-Littlewood symmetric function EXAMPLES:: @@ -1254,7 +1225,7 @@ class DualkSchurFunctions(KBoundedQuotientBasis): def __init__(self, kBoundedRing): r""" - Initializes the ring which is the dual `k`-Schur function basis. + Initialize the ring which is the dual `k`-Schur function basis. INPUT: @@ -1290,16 +1261,14 @@ def _repr_(self): def _dks_to_khlp_on_basis(self, la): r""" - Gives the expansion of the dual `k`-Schur basis element indexed by ``la`` into + Give the expansion of the dual `k`-Schur basis element indexed by ``la`` into the Hall-Littlewood P basis. INPUT: - - ``la`` -- A `k`-bounded partition. - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - A symmetric function in the Hall-Littlewood P basis + OUTPUT: a symmetric function in the Hall-Littlewood P basis EXAMPLES:: @@ -1322,16 +1291,14 @@ def _dks_to_khlp_on_basis(self, la): def _khlp_to_dks_on_basis(self, la): r""" - Gives the expansion of the `k`-bounded Hall-Littlewood P basis element indexed by + Give the expansion of the `k`-bounded Hall-Littlewood P basis element indexed by ``la`` into the dual `k`-Schur basis. INPUT: - - ``la`` -- A `k`-bounded partition. - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - A `k`-bounded quotient symmetric function in the dual `k`-Schur basis + OUTPUT: a `k`-bounded quotient symmetric function in the dual `k`-Schur basis EXAMPLES:: @@ -1377,7 +1344,7 @@ class AffineSchurFunctions(KBoundedQuotientBasis): def __init__(self, kBoundedRing): r""" - Initializes the ring which is the `k`-Bounded affine Schur quotient basis. + Initialize the ring which is the `k`-Bounded affine Schur quotient basis. INPUT: @@ -1413,16 +1380,14 @@ def _repr_(self): def _F_to_m_on_basis(self, la): r""" - Gives the expansion of the affine Schur basis element indexed by ``la`` into + Give the expansion of the affine Schur basis element indexed by ``la`` into the monomial basis. INPUT: - - ``la`` -- A `k`-bounded partition. + - ``la`` -- a `k`-bounded partition - OUTPUT: - - - A symmetric function in the monomial basis + OUTPUT: a symmetric function in the monomial basis EXAMPLES:: @@ -1443,16 +1408,14 @@ def _F_to_m_on_basis(self, la): def _m_to_F_on_basis(self, la): r""" - Gives the expansion of the `k`-monomial basis element indexed by ``la`` into + Give the expansion of the `k`-monomial basis element indexed by ``la`` into the affine Schur basis. INPUT: - - ``la`` -- A `k`-bounded partition. - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - A `k`-bounded quotient symmetric function in the affine Schur basis + OUTPUT: a `k`-bounded quotient symmetric function in the affine Schur basis EXAMPLES:: diff --git a/src/sage/combinat/sf/kfpoly.py b/src/sage/combinat/sf/kfpoly.py index 09283745aa5..d58fb746780 100644 --- a/src/sage/combinat/sf/kfpoly.py +++ b/src/sage/combinat/sf/kfpoly.py @@ -30,7 +30,7 @@ def KostkaFoulkesPolynomial(mu, nu, t=None): r""" - Returns the Kostka-Foulkes polynomial `K_{\mu, \nu}(t)`. + Return the Kostka-Foulkes polynomial `K_{\mu, \nu}(t)`. INPUT: @@ -211,9 +211,7 @@ def riggings(part): - ``part`` -- a partition - OUTPUT: - - - a list of riggings associated to the partition ``part`` + OUTPUT: list of riggings associated to the partition ``part`` EXAMPLES:: @@ -252,12 +250,10 @@ def compat(n, mu, nu): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``mu``, ``nu`` -- partitions - OUTPUT: - - - a list of partitions + OUTPUT: list of partitions EXAMPLES:: @@ -304,9 +300,7 @@ def dom(mup, snu): - ``mup`` -- a partition conjugate to ``mu`` - ``snu`` -- a sequence of positive integers - OUTPUT: - - - a boolean value + OUTPUT: boolean EXAMPLES:: @@ -356,9 +350,7 @@ def weight(rg, t=None): - ``rg`` -- a rigging, a list of partitions - ``t`` -- an optional parameter, (default: the generator from `\ZZ['t']`) - OUTPUT: - - - a polynomial in the parameter ``t`` + OUTPUT: a polynomial in the parameter `t` EXAMPLES:: diff --git a/src/sage/combinat/sf/llt.py b/src/sage/combinat/sf/llt.py index a6234fe961a..d0a0a040672 100644 --- a/src/sage/combinat/sf/llt.py +++ b/src/sage/combinat/sf/llt.py @@ -111,12 +111,12 @@ def __classcall__(cls, Sym, k, t='t'): def __init__(self, Sym, k, t): r""" - Class of LLT symmetric function bases + Class of LLT symmetric function bases. INPUT: - ``self`` -- a family of LLT symmetric function bases - - ``k`` -- a positive integer (the level) + - ``k`` -- positive integer (the level) - ``t`` -- a parameter (default: `t`) EXAMPLES:: @@ -155,15 +155,13 @@ def __init__(self, Sym, k, t): def __repr__(self): r""" - Representation of the LLT symmetric functions + Representation of the LLT symmetric functions. INPUT: - ``self`` -- a family of LLT symmetric function bases - OUTPUT: - - - returns a string representing the LLT symmetric functions + OUTPUT: a string representing the LLT symmetric functions EXAMPLES:: @@ -183,9 +181,7 @@ def symmetric_function_ring( self ): - ``self`` -- a family of LLT symmetric functions bases - OUTPUT: - - - returns the symmetric function ring associated to ``self``. + OUTPUT: the symmetric function ring associated to ``self`` EXAMPLES:: @@ -197,15 +193,13 @@ def symmetric_function_ring( self ): def base_ring(self): r""" - Returns the base ring of ``self``. + Return the base ring of ``self``. INPUT: - ``self`` -- a family of LLT symmetric functions bases - OUTPUT: - - - returns the base ring of the symmetric function ring associated to ``self`` + OUTPUT: the base ring of the symmetric function ring associated to ``self`` EXAMPLES:: @@ -216,15 +210,13 @@ def base_ring(self): def level(self): r""" - Returns the level of ``self``. + Return the level of ``self``. INPUT: - ``self`` -- a family of LLT symmetric functions bases - OUTPUT: - - - the level is the parameter of `k` in the basis + OUTPUT: the level is the parameter of `k` in the basis EXAMPLES:: @@ -235,9 +227,9 @@ def level(self): def _llt_generic(self, skp, stat): r""" - Takes in partition, list of partitions, or a list of skew + Take in partition, list of partitions, or a list of skew partitions as well as a function which takes in two partitions and - a level and returns a coefficient. + a level and return a coefficient. INPUT: @@ -364,16 +356,14 @@ def cospin(self, skp): def hcospin(self): r""" - Returns the HCospin basis. + Return the HCospin basis. This basis is defined [LLT1997]_ equation (27). INPUT: - ``self`` -- a family of LLT symmetric functions bases - OUTPUT: - - - returns the h-cospin basis of the LLT symmetric functions + OUTPUT: the h-cospin basis of the LLT symmetric functions EXAMPLES:: @@ -395,16 +385,15 @@ def hcospin(self): def hspin(self): r""" - Returns the HSpin basis. + Return the HSpin basis. + This basis is defined [LLT1997]_ equation (28). INPUT: - ``self`` -- a family of LLT symmetric functions bases - OUTPUT: - - - returns the h-spin basis of the LLT symmetric functions + OUTPUT: the h-spin basis of the LLT symmetric functions EXAMPLES:: @@ -488,16 +477,14 @@ def construction(self): def _m_to_self(self, x): r""" - Isomorphism from the monomial basis into ``self`` + Isomorphism from the monomial basis into ``self``. INPUT: - ``self`` -- an instance of the LLT hspin or hcospin basis - ``x`` -- an element of the monomial basis - OUTPUT: - - - returns ``x`` expanded in the basis ``self`` + OUTPUT: ``x`` expanded in the basis ``self`` EXAMPLES:: @@ -517,16 +504,14 @@ def _m_to_self(self, x): def _self_to_m(self, x): r""" - Isomorphism from self to the monomial basis + Isomorphism from ``self`` to the monomial basis. INPUT: - ``self`` -- an instance of the LLT hspin or hcospin basis - ``x`` -- an element of ``self`` - OUTPUT: - - - returns ``x`` expanded in the monomial basis. + OUTPUT: ``x`` expanded in the monomial basis EXAMPLES:: @@ -546,15 +531,13 @@ def _self_to_m(self, x): def level(self): r""" - Returns the level of ``self``. + Return the level of ``self``. INPUT: - ``self`` -- an instance of the LLT hspin or hcospin basis - OUTPUT: - - - returns the level associated to the basis ``self``. + OUTPUT: the level associated to the basis ``self`` EXAMPLES:: @@ -572,9 +555,7 @@ def llt_family( self ): - ``self`` -- an instance of the LLT hspin or hcospin basis - OUTPUT: - - - returns an instance of the family of LLT bases associated to ``self``. + OUTPUT: an instance of the family of LLT bases associated to ``self`` EXAMPLES:: @@ -594,9 +575,7 @@ def product(self, left, right): - ``self`` -- an instance of the LLT hspin or hcospin basis - ``left``, ``right`` -- elements of the symmetric functions - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -617,7 +596,7 @@ def _m_cache(self, n): INPUT: - ``self`` -- an instance of the LLT hspin or hcospin basis - - ``n`` -- a positive integer representing the degree + - ``n`` -- positive integer representing the degree EXAMPLES:: @@ -685,7 +664,7 @@ def __init__(self, llt): def _to_m(self, part): r""" - Returns a function which gives the coefficient of a partition + Return a function which gives the coefficient of a partition in the monomial expansion of self(part). INPUT: @@ -753,7 +732,7 @@ def __init__(self, llt): def _to_m(self, part): r""" - Returns a function which gives the coefficient of part2 in the + Return a function which gives the coefficient of part2 in the monomial expansion of self(part). INPUT: @@ -785,5 +764,5 @@ class Element(LLT_generic.Element): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.llt', 'LLTElement_spin', LLT_spin.Element) -register_unpickle_override('sage.combinat.sf.llt', 'LLTElement_cospin', LLT_cospin.Element) +register_unpickle_override('sage.combinat.sf.llt', 'LLTElement_spin', LLT_spin.Element) +register_unpickle_override('sage.combinat.sf.llt', 'LLTElement_cospin', LLT_cospin.Element) diff --git a/src/sage/combinat/sf/macdonald.py b/src/sage/combinat/sf/macdonald.py index 85c03daa032..395906bada4 100644 --- a/src/sage/combinat/sf/macdonald.py +++ b/src/sage/combinat/sf/macdonald.py @@ -80,15 +80,13 @@ class Macdonald(UniqueRepresentation): def __repr__(self): r""" - The family of Macdonald symmetric function bases + The family of Macdonald symmetric function bases. INPUT: - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - a string representing the Macdonald symmetric function family + OUTPUT: string representing the Macdonald symmetric function family EXAMPLES:: @@ -152,16 +150,14 @@ def __init__(self, Sym, q, t): def base_ring( self ): r""" - Returns the base ring of the symmetric functions where the - Macdonald symmetric functions live + Return the base ring of the symmetric functions where the + Macdonald symmetric functions live. INPUT: - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - the base ring associated to the corresponding symmetric function ring + OUTPUT: the base ring associated to the corresponding symmetric function ring EXAMPLES:: @@ -174,16 +170,14 @@ def base_ring( self ): def symmetric_function_ring( self ): r""" - Returns the base ring of the symmetric functions where the - Macdonald symmetric functions live + Return the base ring of the symmetric functions where the + Macdonald symmetric functions live. INPUT: - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - the symmetric function ring associated to the Macdonald bases + OUTPUT: the symmetric function ring associated to the Macdonald bases EXAMPLES:: @@ -195,16 +189,14 @@ def symmetric_function_ring( self ): def P(self): r""" - Returns Macdonald polynomials in `P` basis. + Return Macdonald polynomials in `P` basis. The `P` basis is defined here as a normalized form of the `J` basis. INPUT: - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - returns the `P` Macdonald basis of symmetric functions + OUTPUT: the `P` Macdonald basis of symmetric functions EXAMPLES:: @@ -300,7 +292,7 @@ def P(self): def Q(self): r""" - Returns the Macdonald polynomials on the `Q` basis. These are dual to + Return the Macdonald polynomials on the `Q` basis. These are dual to the Macdonald polynomials on the P basis with respect to the `qt`-Hall scalar product. The `Q` basis is defined to be a normalized form of the `J` basis. @@ -309,9 +301,7 @@ def Q(self): - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - returns the `Q` Macdonald basis of symmetric functions + OUTPUT: the `Q` Macdonald basis of symmetric functions EXAMPLES:: @@ -363,7 +353,7 @@ def Q(self): def J(self): r""" - Returns the Macdonald polynomials on the `J` basis also known as the + Return the Macdonald polynomials on the `J` basis also known as the integral form of the Macdonald polynomials. These are scalar multiples of both the `P` and `Q` bases. When expressed in the `P` or `Q` basis, the scaling coefficients are polynomials in `q` and `t` rather @@ -376,9 +366,7 @@ def J(self): - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - returns the `J` Macdonald basis of symmetric functions + OUTPUT: the `J` Macdonald basis of symmetric functions EXAMPLES:: @@ -425,7 +413,7 @@ def J(self): def H(self): r""" - Returns the Macdonald polynomials on the H basis. When the `H` basis + Return the Macdonald polynomials on the H basis. When the `H` basis is expanded on the Schur basis, the coefficients are the `qt`-Kostka numbers. @@ -433,9 +421,7 @@ def H(self): - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - returns the `H` Macdonald basis of symmetric functions + OUTPUT: the `H` Macdonald basis of symmetric functions EXAMPLES:: @@ -459,7 +445,7 @@ def H(self): def Ht(self): r""" - Returns the Macdonald polynomials on the `Ht` basis. The elements of + Return the Macdonald polynomials on the `Ht` basis. The elements of the `Ht` basis are eigenvectors of the `nabla` operator. When expanded on the Schur basis, the coefficients are the modified `qt`-Kostka numbers. @@ -468,9 +454,7 @@ def Ht(self): - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - returns the `Ht` Macdonald basis of symmetric functions + OUTPUT: the `Ht` Macdonald basis of symmetric functions EXAMPLES:: @@ -507,7 +491,7 @@ def Ht(self): def S(self): r""" - Returns the modified Schur functions defined by the plethystic + Return the modified Schur functions defined by the plethystic substitution `S_{\mu} = s_{\mu}[X(1-t)/(1-q)]`. When the Macdonald polynomials in the J basis are expressed in terms of the modified Schur functions at `q=0`, the coefficients are `qt`-Kostka numbers. @@ -516,9 +500,7 @@ def S(self): - ``self`` -- a family of Macdonald symmetric function bases - OUTPUT: - - - returns the `S` Macdonald basis of symmetric functions + OUTPUT: the `S` Macdonald basis of symmetric functions EXAMPLES:: @@ -577,9 +559,7 @@ def c1(part, q, t): - ``part`` -- a partition - ``q``, ``t`` -- parameters - OUTPUT: - - - returns a polynomial of the scalar product between the `J` and `P` bases + OUTPUT: a polynomial of the scalar product between the `J` and `P` bases EXAMPLES:: @@ -609,9 +589,7 @@ def c2(part, q, t): - ``part`` -- a partition - ``q``, ``t`` -- parameters - OUTPUT: - - - returns a polynomial of the scalar product between the `J` and `P` bases + OUTPUT: a polynomial of the scalar product between the `J` and `P` bases EXAMPLES:: @@ -637,9 +615,7 @@ def cmunu1(mu, nu): - ``mu``, ``nu`` -- partitions with ``nu`` precedes ``mu`` - OUTPUT: - - - an element of the fraction field of polynomials in `q` and `t` + OUTPUT: an element of the fraction field of polynomials in `q` and `t` EXAMPLES:: @@ -694,9 +670,7 @@ def cmunu(mu, nu): - ``mu``, ``nu`` -- partitions with ``nu`` contained in ``mu`` - OUTPUT: - - - an element of the fraction field of polynomials in `q` and `t` + OUTPUT: an element of the fraction field of polynomials in `q` and `t` EXAMPLES:: @@ -743,7 +717,7 @@ class MacdonaldPolynomials_generic(sfa.SymmetricFunctionAlgebra_generic): def __init__(self, macdonald): r""" - A class for methods for one of the Macdonald bases of the symmetric functions + A class for methods for one of the Macdonald bases of the symmetric functions. INPUT: @@ -752,7 +726,7 @@ def __init__(self, macdonald): EXAMPLES:: - sage: Sym = SymmetricFunctions(FractionField(QQ['q,t'])); Sym.rename("Sym"); Sym + sage: Sym = SymmetricFunctions(FractionField(QQ['q,t'])); Sym.rename('Sym'); Sym Sym sage: Sym.macdonald().P() Sym in the Macdonald P basis @@ -806,16 +780,14 @@ def construction(self): def _s_to_self(self, x): r""" - Isomorphism from the Schur basis into self + Isomorphism from the Schur basis into ``self``. INPUT: - ``self`` -- a Macdonald basis - ``x`` -- an element of the Schur basis - OUTPUT: - - - returns the basis element ``x`` in the basis ``self`` + OUTPUT: the basis element ``x`` in the basis ``self`` EXAMPLES:: @@ -835,16 +807,14 @@ def _s_to_self(self, x): def _self_to_s(self, x): r""" - Isomorphism from self to the Schur basis + Isomorphism from ``self`` to the Schur basis. INPUT: - ``self`` -- a Macdonald basis - ``x`` -- an element of a Macdonald basis - OUTPUT: - - - returns the basis element ``x`` in the Schur functions + OUTPUT: the basis element ``x`` in the Schur functions EXAMPLES:: @@ -864,7 +834,7 @@ def _self_to_s(self, x): def c1(self, part): r""" - Returns the qt-Hall scalar product between ``J(part)`` and ``P(part)``. + Return the `qt`-Hall scalar product between ``J(part)`` and ``P(part)``. INPUT: @@ -886,7 +856,7 @@ def c1(self, part): def c2(self, part): r""" - Returns the `qt`-Hall scalar product between ``J(part)`` and ``Q(part)``. + Return the `qt`-Hall scalar product between ``J(part)`` and ``Q(part)``. INPUT: @@ -920,9 +890,7 @@ def product(self, left, right): - ``left`` -- an element of the basis ``self`` - ``right`` -- another symmetric function - OUTPUT: - - the product of ``left`` and ``right`` expanded in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expanded in the basis ``self`` EXAMPLES:: @@ -949,15 +917,13 @@ def product(self, left, right): def macdonald_family(self): r""" - Returns the family of Macdonald bases associated to the basis ``self`` + Return the family of Macdonald bases associated to the basis ``self``. INPUT: - ``self`` -- a Macdonald basis - OUTPUT: - - - the family of Macdonald symmetric functions associated to ``self`` + OUTPUT: the family of Macdonald symmetric functions associated to ``self`` EXAMPLES:: @@ -989,12 +955,10 @@ def nabla(self, q=None, t=None, power=1): INPUT: - ``self`` -- an element of a Macdonald basis - - ``q``, ``t`` -- optional parameters to specialize - - ``power`` -- an integer (default: 1) - - OUTPUT: + - ``q``, ``t`` -- (optional) parameters to specialize + - ``power`` -- integer (default: 1) - - returns the symmetric function of `\nabla` acting on ``self`` + OUTPUT: the symmetric function of `\nabla` acting on ``self`` EXAMPLES:: @@ -1060,7 +1024,7 @@ def __init__(self, macdonald): def scalar_qt_basis(self, part1, part2=None): r""" - Returns the scalar product of `P(part1)` and `P(part2)` + Return the scalar product of `P(part1)` and `P(part2)` This scalar product formula is given in equation (4.11) p.323 and (6.19) p.339 of Macdonald's book [Mac1995]_. @@ -1089,7 +1053,6 @@ def scalar_qt_basis(self, part1, part2=None): sage: P.scalar_qt_basis(Partition([2,1]), Partition([2,1])) (-q^4*t + 2*q^3*t - q^2*t + q^2 - 2*q + 1)/(-q*t^4 + 2*q*t^3 - q*t^2 + t^2 - 2*t + 1) - """ if part2 is not None and part1 != part2: return self.base_ring().zero() @@ -1166,7 +1129,7 @@ def _s_cache(self, n): INPUT: - ``self`` -- a Macdonald `J` basis - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -1190,7 +1153,7 @@ def _s_cache(self, n): def _to_s(self, part): r""" - Returns a function which gives the coefficient of a partition in + Return a function which gives the coefficient of a partition in the Schur expansion of self(part). These computations are completed with coefficients in fraction @@ -1252,7 +1215,6 @@ def __init__(self, macdonald): sage: H = Sym.macdonald().H() sage: TestSuite(H).run(skip=["_test_associativity","_test_distributivity","_test_prod"]) sage: TestSuite(H).run(elements = [H.t*H[1,1]+H.q*H[2], H[1]+(H.q+H.t)*H[1,1]]) # long time (26s on sage.math, 2012) - """ MacdonaldPolynomials_generic.__init__(self, macdonald) self._m = self._sym.m() @@ -1278,9 +1240,7 @@ def _self_to_s(self, x): - ``x`` -- an element of ``H`` basis - OUTPUT: - - - an element of the Schur basis + OUTPUT: an element of the Schur basis EXAMPLES:: @@ -1318,9 +1278,7 @@ def _s_to_self(self, x): - ``x`` -- an element of the Schur basis - OUTPUT: - - - an element of the ``H`` basis + OUTPUT: an element of the ``H`` basis EXAMPLES:: @@ -1356,9 +1314,7 @@ def _self_to_m(self, x): - ``x`` -- an element of ``H`` basis - OUTPUT: - - - an element of the monomial basis + OUTPUT: an element of the monomial basis EXAMPLES:: @@ -1410,9 +1366,7 @@ def _m_to_self( self, f ): - ``f`` -- an element of the monomial basis - OUTPUT: - - - an element of the ``H`` basis + OUTPUT: an element of the ``H`` basis EXAMPLES:: @@ -1474,7 +1428,6 @@ def __init__(self, macdonald): sage: Ht = Sym.macdonald().Ht() sage: TestSuite(Ht).run(skip=["_test_associativity","_test_distributivity","_test_prod"]) # long time (26s on sage.math, 2012) sage: TestSuite(Ht).run(elements = [Ht.t*Ht[1,1]+Ht.q*Ht[2], Ht[1]+(Ht.q+Ht.t)*Ht[1,1]]) # long time (depends on previous) - """ MacdonaldPolynomials_generic.__init__(self, macdonald) self._self_to_m_cache = _ht_to_m_cache @@ -1487,7 +1440,7 @@ def __init__(self, macdonald): def _self_to_s(self, x): r""" - Convert an element of the ``Ht`` basis to the Schur basis + Convert an element of the ``Ht`` basis to the Schur basis. This function is here to force the coercion path to the Schur basis because these bases are computed using their monomial expansion. @@ -1496,9 +1449,7 @@ def _self_to_s(self, x): - ``x`` -- an element of ``self`` - OUTPUT: - - - an element of the Schur basis + OUTPUT: an element of the Schur basis EXAMPLES:: @@ -1511,7 +1462,7 @@ def _self_to_s(self, x): def _s_to_self( self, x ): r""" - Convert an element of either the Schur basis to the ``Ht`` basis + Convert an element of either the Schur basis to the ``Ht`` basis. This function is here to force the coercion path from the Schur basis because these bases are computed using the monomial expansion. @@ -1520,9 +1471,7 @@ def _s_to_self( self, x ): - ``x`` -- an element of ``s`` basis - OUTPUT: - - - an element of the basis ``self`` + OUTPUT: an element of the basis ``self`` EXAMPLES:: @@ -1556,9 +1505,7 @@ def _Lmunu(self, nu, mu): - ``nu``, ``mu`` -- partitions of the same size - OUTPUT: - - - a polynomial in `q` and `t` + OUTPUT: a polynomial in `q` and `t` EXAMPLES:: @@ -1571,7 +1518,6 @@ def _Lmunu(self, nu, mu): t^2 + q + t + 1 sage: Lmunu(Partition([2,2]),Partition([2,1,1])) q*t + 2*t^2 + q + t + 1 - """ if not mu: if not nu: @@ -1593,16 +1539,14 @@ def _Lmunu(self, nu, mu): def _self_to_m(self, x): r""" - Takes an element of the ``Ht`` basis and returns the expansion in the + Take an element of the ``Ht`` basis and return the expansion in the monomial basis. INPUT: - ``x`` -- an element of ``Ht`` basis - OUTPUT: - - - an element of the monomial basis + OUTPUT: an element of the monomial basis EXAMPLES:: @@ -1618,7 +1562,6 @@ def _self_to_m(self, x): sage: m = Sym.m() sage: m(Ht[2,1]) ((2*x^2+2*x+2)/x)*m[1, 1, 1] + ((x^2+x+1)/x)*m[2, 1] + m[3] - """ part_coeff = lambda x, d: sorted((mu,c) for mu,c in x if sum(mu) == d) return self._m._from_dict({ part2: @@ -1645,9 +1588,7 @@ def _m_to_self( self, f ): - ``f`` -- an element of the monomial basis - OUTPUT: - - - an element of the ``Ht`` basis + OUTPUT: an element of the ``Ht`` basis EXAMPLES:: @@ -1666,7 +1607,6 @@ def _m_to_self( self, f ): sage: m = Sym.m() sage: Ht((3*x+3)*m[1, 1, 1] + (x+2)*m[2, 1] + m[3]) McdHt[2, 1] - """ if self.t == 1: subsval = self.q @@ -1686,7 +1626,7 @@ def _m_to_self( self, f ): class Element(MacdonaldPolynomials_generic.Element): def nabla(self, q=None, t=None, power=1): r""" - Returns the value of the nabla operator applied to ``self``. The + Return the value of the nabla operator applied to ``self``. The eigenvectors of the `nabla` operator are the Macdonald polynomials in the `Ht` basis. For more information see: [BGHT1999]_. @@ -1700,12 +1640,10 @@ def nabla(self, q=None, t=None, power=1): INPUT: - ``self`` -- an element of the Macdonald `Ht` basis - - ``q``, ``t`` -- optional parameters to specialize - - ``power`` -- an integer (default: 1) - - OUTPUT: + - ``q``, ``t`` -- (optional) parameters to specialize + - ``power`` -- integer (default: 1) - - returns the symmetric function of `\nabla` acting on ``self`` + OUTPUT: the symmetric function of `\nabla` acting on ``self`` EXAMPLES:: @@ -1732,7 +1670,6 @@ def nabla(self, q=None, t=None, power=1): sage: a = sum(Ht(p) for p in Partitions(3)) sage: s(a.nabla()) (t^6+9*t^2+729)*s[1, 1, 1] + (t^5+t^4+3*t^2+9*t+324)*s[2, 1] + (t^3+3*t+27)*s[3] - """ P = self.parent() Ht = P._macdonald.Ht() @@ -1750,7 +1687,7 @@ def nabla(self, q=None, t=None, power=1): class MacdonaldPolynomials_s(MacdonaldPolynomials_generic): def __init__(self, macdonald): r""" - An implementation of the basis `s_\lambda[(1-t)X/(1-q)]` + An implementation of the basis `s_\lambda[(1-t)X/(1-q)]`. This is perhaps misnamed as a 'Macdonald' basis for the symmetric functions but is used in the calculation @@ -1769,7 +1706,6 @@ def __init__(self, macdonald): sage: S = Sym.macdonald().S() sage: TestSuite(S).run(skip=["_test_associativity","_test_distributivity","_test_prod"]) sage: TestSuite(S).run(elements = [S.t*S[1,1]+S.q*S[2], S[1]+(S.q+S.t)*S[1,1]]) - """ MacdonaldPolynomials_generic.__init__(self, macdonald) self._s = macdonald._s @@ -1786,9 +1722,7 @@ def product(self, left, right): - ``self`` -- a Macdonald `S` basis - ``left``, ``right`` -- a symmetric functions - OUTPUT: - - the product of ``left`` and ``right`` + OUTPUT: the product of ``left`` and ``right`` EXAMPLES:: @@ -1804,7 +1738,7 @@ def product(self, left, right): def _to_s(self, part): r""" - Returns a function which gives the coefficient of a partition in + Return a function which gives the coefficient of a partition in the Schur expansion of ``self(part)``. these computations are completed with coefficients in fraction field of polynomials in `q` and `t` @@ -1851,7 +1785,7 @@ def _s_cache(self, n): INPUT: - ``self`` -- a Macdonald `S` basis - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -1872,7 +1806,7 @@ class Element(MacdonaldPolynomials_generic.Element): def _creation_by_determinant_helper(self, k, part): r""" - Formula from [LLM1998]_ Corollary 4.3 p. 970 + Formula from [LLM1998]_ Corollary 4.3 p. 970. This is part of a formula for a column adding creation operator for the `J` basis and its action on the `S` basis. @@ -1880,8 +1814,7 @@ def _creation_by_determinant_helper(self, k, part): INPUT: - ``self`` -- an element of the Macdonald `S` basis - - ``k`` -- a positive integer at least as big as the - length of ``part`` + - ``k`` -- positive integer at least as big as the length of ``part`` - ``part`` -- a partition OUTPUT: @@ -1934,11 +1867,9 @@ def _creation_by_determinant(self, k): INPUT: - ``self`` -- an element of the Macdonald `S` basis - - ``k`` -- a positive integer + - ``k`` -- positive integer - OUTPUT: - - - returns the column adding operator on the `J` basis on ``self`` + OUTPUT: the column adding operator on the `J` basis on ``self`` EXAMPLES:: @@ -1964,11 +1895,9 @@ def creation(self, k): INPUT: - ``self`` -- an element of the Macdonald `S` basis - - ``k`` -- a positive integer - - OUTPUT: + - ``k`` -- positive integer - - returns the column adding operator on the `J` basis on ``self`` + OUTPUT: the column adding operator on the `J` basis on ``self`` EXAMPLES:: @@ -1984,7 +1913,7 @@ def creation(self, k): def _omega_qt_in_schurs(self): r""" - Returns the image of self under the omega_qt automorphism in the + Return the image of ``self`` under the omega_qt automorphism in the Schur basis. INPUT: @@ -2012,7 +1941,7 @@ def _omega_qt_in_schurs(self): def qt_kostka(lam, mu): r""" - Returns the `K_{\lambda\mu}(q,t)` by computing the change + Return the `K_{\lambda\mu}(q,t)` by computing the change of basis from the Macdonald H basis to the Schurs. INPUT: @@ -2069,16 +1998,16 @@ def qt_kostka(lam, mu): for p2 in parts: res = s(H(p2)) for p1 in parts: - _qt_kostka_cache[(p1,p2)] = QQqt(res.coefficient(p1).numerator()) + _qt_kostka_cache[(p1, p2)] = QQqt(res.coefficient(p1).numerator()) - return _qt_kostka_cache[(lam,mu)] + return _qt_kostka_cache[(lam, mu)] # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_h', MacdonaldPolynomials_h.Element) +register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_h', MacdonaldPolynomials_h.Element) register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_ht', MacdonaldPolynomials_ht.Element) -register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_j', MacdonaldPolynomials_j.Element) -register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_p', MacdonaldPolynomials_p.Element) -register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_q', MacdonaldPolynomials_q.Element) -register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_s', MacdonaldPolynomials_s.Element) +register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_j', MacdonaldPolynomials_j.Element) +register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_p', MacdonaldPolynomials_p.Element) +register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_q', MacdonaldPolynomials_q.Element) +register_unpickle_override('sage.combinat.sf.macdonald', 'MacdonaldPolynomial_s', MacdonaldPolynomials_s.Element) diff --git a/src/sage/combinat/sf/monomial.py b/src/sage/combinat/sf/monomial.py index 583008830af..bb7b54bae4e 100644 --- a/src/sage/combinat/sf/monomial.py +++ b/src/sage/combinat/sf/monomial.py @@ -30,7 +30,7 @@ class SymmetricFunctionAlgebra_monomial(classical.SymmetricFunctionAlgebra_classical): def __init__(self, Sym): """ - A class for methods related to monomial symmetric functions + A class for methods related to monomial symmetric functions. INPUT: @@ -49,7 +49,7 @@ def __init__(self, Sym): def _dual_basis_default(self): """ - Return the default dual basis to ``self`` when no scalar product is specified + Return the default dual basis to ``self`` when no scalar product is specified. This method returns the dual basis of the monomial basis with respect to the standard scalar product, which is the @@ -80,7 +80,7 @@ def product(self, left, right): Return the product of ``left`` and ``right``. - ``left``, ``right`` -- symmetric functions written in the - monomial basis ``self``. + monomial basis ``self`` OUTPUT: @@ -135,21 +135,25 @@ def product(self, left, right): return self._from_dict(z_elt) def from_polynomial(self, f, check=True): - """ - Return the symmetric function in the monomial basis corresponding to the polynomial ``f``. + r""" + Return the symmetric function in the monomial basis corresponding + to the polynomial ``f``. INPUT: - ``self`` -- a monomial symmetric function basis - - ``f`` -- a polynomial in finitely many variables over the same base ring as ``self``. - It is assumed that this polynomial is symmetric. - - ``check`` -- boolean (default: ``True``), checks whether the polynomial is indeed symmetric + - ``f`` -- a polynomial in finitely many variables over the + same base ring as ``self``; it is assumed that this + polynomial is symmetric + - ``check`` -- boolean (default: ``True``); checks whether + the polynomial is indeed symmetric OUTPUT: - - This function converts a symmetric polynomial `f` in a polynomial ring in finitely - many variables to a symmetric function in the monomial - basis of the ring of symmetric functions over the same base ring. + - This function converts a symmetric polynomial `f` in a + polynomial ring in finitely many variables to a symmetric + function in the monomial basis of the ring of symmetric + functions over the same base ring. EXAMPLES:: @@ -173,19 +177,20 @@ def from_polynomial(self, f, check=True): sage: f = (2*m[2,1]+m[1,1]+3*m[3]).expand(3) sage: m.from_polynomial(f) m[1, 1] + 2*m[2, 1] + 3*m[3] + """ assert self.base_ring() == f.base_ring() if check and not f.is_symmetric(): raise ValueError("%s is not a symmetric polynomial" % f) out = self._from_dict({_Partitions.element_class(_Partitions, list(e)): c - for (e,c) in f.dict().items() + for e, c in f.monomial_coefficients().items() if all(e[i+1] <= e[i] for i in range(len(e)-1))}, remove_zeros=False) return out def from_polynomial_exp(self, p): r""" - Conversion from polynomial in exponential notation + Conversion from polynomial in exponential notation. INPUT: @@ -279,7 +284,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -335,12 +340,12 @@ def principal_specialization(self, n=infinity, q=None): INPUT: - - ``n`` (default: ``infinity``) -- a nonnegative integer or + - ``n`` -- (default: ``infinity``) a nonnegative integer or ``infinity``, specifying whether to compute the principal specialization of order ``n`` or the stable principal specialization. - - ``q`` (default: ``None``) -- the value to use for `q`; the + - ``q`` -- (default: ``None``) the value to use for `q`; the default is to create a ring of polynomials in ``q`` (or a field of rational functions in ``q``) over the given coefficient ring. @@ -373,7 +378,6 @@ def principal_specialization(self, n=infinity, q=None): sage: m.zero().principal_specialization(3) 0 - """ if q == 1: if n == infinity: @@ -433,12 +437,12 @@ def exponential_specialization(self, t=None, q=1): INPUT: - - ``t`` (default: ``None``) -- the value to use for `t`; - the default is to create a ring of polynomials in ``t``. + - ``t`` -- (default: ``None``) the value to use for `t`; + the default is to create a ring of polynomials in ``t`` - - ``q`` (default: `1`) -- the value to use for `q`. If + - ``q`` -- (default: `1`) the value to use for `q`; if ``q`` is ``None``, then a ring (or fraction field) of - polynomials in ``q`` is created. + polynomials in ``q`` is created EXAMPLES:: @@ -459,7 +463,6 @@ def exponential_specialization(self, t=None, q=1): sage: m.zero().exponential_specialization() 0 - """ def get_variable(ring, name): try: diff --git a/src/sage/combinat/sf/multiplicative.py b/src/sage/combinat/sf/multiplicative.py index 7ff9797f81a..5fd06b8e373 100644 --- a/src/sage/combinat/sf/multiplicative.py +++ b/src/sage/combinat/sf/multiplicative.py @@ -46,9 +46,7 @@ def product_on_basis(self, left, right): - ``left``, ``right`` -- partitions - OUTPUT: - - - an element of ``self`` + OUTPUT: an element of ``self`` EXAMPLES:: diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index 59ce50c74e2..740489adabf 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -235,7 +235,6 @@ def K_kschur(self): .. [LamSchillingShimozono10] \T. Lam, A. Schilling, M.Shimozono, K-theory Schubert calculus of the affine Grassmannian, Compositio Math. 146 (2010), 811-852. - EXAMPLES:: sage: kB = SymmetricFunctions(QQ).kBoundedSubspace(3,1) @@ -277,12 +276,12 @@ class KBoundedSubspaceBases(Category_realization_of_parent): def __init__(self, base, t='t'): """ - Initialization of the bases of the `k`-bounded subspace + Initialization of the bases of the `k`-bounded subspace. INPUT: - ``base`` -- a basis in the `k`-bounded subspace - - ``t`` -- a parameter (default: 't') + - ``t`` -- a parameter (default: ``'t'``) TESTS:: @@ -447,12 +446,12 @@ def transition_matrix(self, other, n): INPUT: - ``other`` -- a basis in the ring of symmetric functions - - ``n`` -- a positive integer + - ``n`` -- positive integer - The entry in the `i^{th}` row and `j^{th}` column is the - coefficient obtained by writing the `i^{th}` element of the + The entry in the `i`-th row and `j`-th column is the + coefficient obtained by writing the `i`-th element of the basis of ``self`` in terms of the basis ``other``, and extracting the - `j^{th}` coefficient. + `j`-th coefficient. EXAMPLES:: @@ -672,7 +671,7 @@ def hl_creation_operator(self, nu, t=None): INPUT: - - ``nu`` -- a partition or a list of integers + - ``nu`` -- a partition or a list of integers - ``t`` -- (default: ``None``, in which case ``t`` is used) an element of the base ring @@ -820,7 +819,7 @@ def scalar(self, x, zee=None): - ``zee`` -- an optional function on partitions giving the value for the scalar product between `p_{\mu}` and `p_{\mu}` - (default is to use the standard :meth:`~sage.combinat.sf.sfa.zee` function) + (default: use the standard :meth:`~sage.combinat.sf.sfa.zee` function) .. SEEALSO:: :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.scalar` @@ -1077,7 +1076,7 @@ def _to_schur_on_basis(self, p): def _product_on_basis_via_rectangles(self, left, right): r""" - Multiply two `k`-Schur functions at `t=1` indexed by ``left`` and ``right`` + Multiply two `k`-Schur functions at `t=1` indexed by ``left`` and ``right``. This algorithm uses the property that if `R` is an `r \times (k+1-r)` rectangle, then @@ -1094,9 +1093,7 @@ def _product_on_basis_via_rectangles(self, left, right): - ``left``, ``right`` -- partitions - OUTPUT: - - - the product of the `k`-Schur functions indexed by ``left`` and ``right`` + OUTPUT: the product of the `k`-Schur functions indexed by ``left`` and ``right`` EXAMPLES:: @@ -1136,9 +1133,7 @@ def product_on_basis(self, left, right): - ``left``, ``right`` -- partitions - OUTPUT: - - - an element of the `k`-Schur functions + OUTPUT: an element of the `k`-Schur functions EXAMPLES:: @@ -1184,7 +1179,7 @@ def product_on_basis(self, left, right): class kSplit(CombinatorialFreeModule): def __init__(self, kBoundedRing): r""" - The `k`-split basis of the space of `k`-bounded-symmetric functions + The `k`-split basis of the space of `k`-bounded-symmetric functions. Fix ``k`` a positive integer and ``t`` an element of the base ring. @@ -1296,7 +1291,7 @@ def _repr_(self): @cached_method def _to_schur_on_basis(self, p): r""" - Computes the change of basis of `k`-split functions to Schur functions. + Compute the change of basis of `k`-split functions to Schur functions. When `t=1` the `k`-split basis is the product of the Schur functions indexed by the partitions in the `k`-split of the partition. @@ -1483,18 +1478,16 @@ def _repr_(self): def _homogeneous_generators_noncommutative_variables_zero_Hecke(self, r): r""" - Return the ``r^{th}`` homogeneous generator, viewed as an element inside the + Return the `r`-th homogeneous generator, viewed as an element inside the affine zero Hecke algebra. - This is the sum of all cyclically decreasing elements of order ``r``. + This is the sum of all cyclically decreasing elements of order `r`. INPUT: - - ``r`` -- A positive integer - - OUTPUT: + - ``r`` -- positive integer - - An element of the affine zero Hecke algebra. + OUTPUT: an element of the affine zero Hecke algebra EXAMPLES:: @@ -1520,11 +1513,9 @@ def _homogeneous_basis(self, la): INPUT: - - ``la`` -- A `k`-bounded partition - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - An element of the affine zero Hecke algebra. + OUTPUT: an element of the affine zero Hecke algebra EXAMPLES:: @@ -1543,11 +1534,9 @@ def homogeneous_basis_noncommutative_variables_zero_Hecke(self, la): INPUT: - - ``la`` -- A `k`-bounded partition + - ``la`` -- a `k`-bounded partition - OUTPUT: - - - An element of the affine zero Hecke algebra. + OUTPUT: an element of the affine zero Hecke algebra EXAMPLES:: @@ -1567,11 +1556,9 @@ def _DualGrothMatrix(self, m): INPUT: - - ``m`` -- An integer - - OUTPUT: + - ``m`` -- integer - - A matrix. + OUTPUT: a matrix EXAMPLES:: @@ -1609,11 +1596,9 @@ def _DualGrothendieck(self, la): INPUT: - - ``la`` -- A `k`-bounded partition. + - ``la`` -- a `k`-bounded partition - OUTPUT: - - - A symmetric function in the homogeneous basis. + OUTPUT: a symmetric function in the homogeneous basis EXAMPLES:: @@ -1654,11 +1639,9 @@ def _g_to_kh_on_basis(self, la): INPUT: - - ``la`` -- A `k`-bounded partition. - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - A symmetric function in the homogeneous basis. + OUTPUT: a symmetric function in the homogeneous basis EXAMPLES:: @@ -1682,11 +1665,9 @@ def K_k_Schur_non_commutative_variables(self, la): INPUT: - - ``la`` -- A `k`-bounded Partition + - ``la`` -- a `k`-bounded Partition - OUTPUT: - - - An element of the affine zero Hecke algebra. + OUTPUT: an element of the affine zero Hecke algebra EXAMPLES:: @@ -1712,11 +1693,9 @@ def _kh_to_g_on_basis(self, la): INPUT: - - ``la`` -- A `k`-bounded partition - - OUTPUT: + - ``la`` -- a `k`-bounded partition - - An element of the `k`-bounded subspace, written in the K-`k`-Schur basis. + OUTPUT: an element of the `k`-bounded subspace, written in the K-`k`-Schur basis EXAMPLES:: @@ -1743,11 +1722,9 @@ def product(self, x, y): INPUT: - - ``x``, ``y`` -- elements of the `k`-bounded subspace, in the K-`k`-Schur basis. - - OUTPUT: + - ``x``, ``y`` -- elements of the `k`-bounded subspace, in the K-`k`-Schur basis - - An element of the `k`-bounded subspace, in the K-`k`-Schur basis + OUTPUT: an element of the `k`-bounded subspace, in the K-`k`-Schur basis EXAMPLES:: @@ -1766,12 +1743,10 @@ def lift(self, x): INPUT: - - ``x`` -- An expression in the K-`k`-Schur basis. Equivalently, ``x`` can be a + - ``x`` -- an expression in the K-`k`-Schur basis. Equivalently, ``x`` can be a `k`-bounded partition (then ``x`` corresponds to the basis element indexed by ``x``) - OUTPUT: - - - A symmetric function. + OUTPUT: a symmetric function EXAMPLES:: @@ -1794,11 +1769,9 @@ def retract(self, x): INPUT: - - ``x`` -- A symmetric function. - - OUTPUT: + - ``x`` -- a symmetric function - - A `k`-bounded symmetric function in the K-`k`-Schur basis. + OUTPUT: a `k`-bounded symmetric function in the K-`k`-Schur basis EXAMPLES:: diff --git a/src/sage/combinat/sf/ns_macdonald.py b/src/sage/combinat/sf/ns_macdonald.py index 582e2f99568..9011cc86b62 100644 --- a/src/sage/combinat/sf/ns_macdonald.py +++ b/src/sage/combinat/sf/ns_macdonald.py @@ -36,7 +36,7 @@ def boxes(self): def __getitem__(self, i): """ - Return the `i^{th}` entry of ``self``. + Return the `i`-th entry of ``self``. Note that the indexing for lattice diagrams starts at `1`. @@ -440,7 +440,7 @@ def fn(ij): def reading_word(self): """ Return the reading word of ``self``, obtained by reading the boxes - entries of self from right to left, starting in the upper right. + entries of ``self`` from right to left, starting in the upper right. EXAMPLES:: diff --git a/src/sage/combinat/sf/orthogonal.py b/src/sage/combinat/sf/orthogonal.py index 3ab5f56debc..b55b3b54a3d 100644 --- a/src/sage/combinat/sf/orthogonal.py +++ b/src/sage/combinat/sf/orthogonal.py @@ -221,9 +221,7 @@ def _s_to_o_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - the expansion of ``s[lam]`` in the orthogonal basis ``self`` + OUTPUT: the expansion of ``s[lam]`` in the orthogonal basis ``self`` EXAMPLES:: diff --git a/src/sage/combinat/sf/orthotriang.py b/src/sage/combinat/sf/orthotriang.py index 17c636ce5ea..926213f7c0e 100644 --- a/src/sage/combinat/sf/orthotriang.py +++ b/src/sage/combinat/sf/orthotriang.py @@ -49,6 +49,7 @@ class SymmetricFunctionAlgebra_orthotriang(sfa.SymmetricFunctionAlgebra_generic) class Element(sfa.SymmetricFunctionAlgebra_generic.Element): pass + @staticmethod def __classcall__(cls, Sym, base, scalar, prefix, basis_name, leading_coeff=None): """ @@ -146,9 +147,7 @@ def _base_to_self(self, x): - ``self`` -- a basis determined by an orthotriangular definition - ``x`` -- an element of the basis `base` to which ``self`` is triangularly related - OUTPUT: - - - an element of ``self`` equivalent to ``x`` + OUTPUT: an element of ``self`` equivalent to ``x`` EXAMPLES:: @@ -169,11 +168,9 @@ def _self_to_base(self, x): INPUT: - ``self`` -- a basis determined by an orthotriangular definition - - ``x`` -- an element of ``self`` as a basis of the ring of symmetric functions. - - OUTPUT: + - ``x`` -- an element of ``self`` as a basis of the ring of symmetric functions - - the element ``x`` expressed in the basis to which ``self`` is triangularly related + OUTPUT: the element ``x`` expressed in the basis to which ``self`` is triangularly related EXAMPLES:: @@ -189,13 +186,13 @@ def _self_to_base(self, x): def _base_cache(self, n): """ - Computes the change of basis between ``self`` and base for the + Compute the change of basis between ``self`` and base for the homogeneous component of size ``n`` INPUT: - ``self`` -- a basis determined by an orthotriangular definition - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -234,7 +231,7 @@ def _to_base(self, part): - ``self`` -- a basis determined by an orthotriangular definition - ``part`` -- a partition - .. note:: + .. NOTE:: We assume that self._gram_schmidt has been called before self._to_base is called. @@ -270,9 +267,7 @@ def product(self, left, right): - ``self`` -- a basis determined by an orthotriangular definition - ``left``, ``right`` -- elements in ``self`` - OUTPUT: - - - the expansion of the product of ``left`` and ``right`` in the basis ``self``. + OUTPUT: the expansion of the product of ``left`` and ``right`` in the basis ``self`` EXAMPLES:: @@ -288,6 +283,8 @@ def product(self, left, right): from sage.combinat.sf.sfa import SymmetricFunctionsFunctor + + class OrthotriangBasisFunctor(SymmetricFunctionsFunctor): """ A constructor for algebras of symmetric functions constructed by @@ -351,4 +348,4 @@ def _apply_functor(self, R): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.orthotriang', 'SymmetricFunctionAlgebraElement_orthotriang', SymmetricFunctionAlgebra_orthotriang.Element) +register_unpickle_override('sage.combinat.sf.orthotriang', 'SymmetricFunctionAlgebraElement_orthotriang', SymmetricFunctionAlgebra_orthotriang.Element) diff --git a/src/sage/combinat/sf/powersum.py b/src/sage/combinat/sf/powersum.py index 9521eaccd32..ce64edef000 100644 --- a/src/sage/combinat/sf/powersum.py +++ b/src/sage/combinat/sf/powersum.py @@ -30,7 +30,7 @@ class SymmetricFunctionAlgebra_power(multiplicative.SymmetricFunctionAlgebra_multiplicative): def __init__(self, Sym): """ - A class for methods associated to the power sum basis of the symmetric functions + A class for methods associated to the power sum basis of the symmetric functions. INPUT: @@ -57,11 +57,9 @@ def coproduct_on_generators(self, i): INPUT: - ``self`` -- the power sum basis of the symmetric functions - - ``i`` -- a positive integer + - ``i`` -- positive integer - OUTPUT: - - - the result of the coproduct on the generator `p(i)` + OUTPUT: the result of the coproduct on the generator `p(i)` EXAMPLES:: @@ -197,12 +195,10 @@ def eval_at_permutation_roots_on_generators(self, k, rho): INPUT: - - ``k`` -- a non-negative integer - - ``rho`` -- a partition or a list of non-negative integers + - ``k`` -- nonnegative integer + - ``rho`` -- a partition or a list of nonnegative integers - OUTPUT: - - - an element of the base ring + OUTPUT: an element of the base ring EXAMPLES:: @@ -257,9 +253,7 @@ def omega(self): :meth:`omega_involution()` is a synonym for the :meth:`omega()` method. - OUTPUT: - - - the image of ``self`` under the omega automorphism + OUTPUT: the image of ``self`` under the omega automorphism EXAMPLES:: @@ -331,9 +325,9 @@ def scalar(self, x, zee=None): parent = self.parent() x = parent(x) if zee is None: - f = lambda part1, part2: sfa.zee(part1) + f = lambda part1, part2: sfa.zee(part1) else: - f = lambda part1, part2: zee(part1) + f = lambda part1, part2: zee(part1) return parent._apply_multi_module_morphism(self, x, f, orthogonal=True) def _derivative(self, part): @@ -438,7 +432,7 @@ def adams_operator(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -551,7 +545,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -617,7 +611,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -683,11 +677,9 @@ def eval_at_permutation_roots(self, rho): INPUT: - - ``rho`` -- a partition or a list of non-negative integers - - OUTPUT: + - ``rho`` -- a partition or a list of nonnegative integers - - an element of the base ring + OUTPUT: an element of the base ring EXAMPLES:: @@ -737,12 +729,12 @@ def principal_specialization(self, n=infinity, q=None): INPUT: - - ``n`` (default: ``infinity``) -- a nonnegative integer or + - ``n`` -- (default: ``infinity``) a nonnegative integer or ``infinity``, specifying whether to compute the principal specialization of order ``n`` or the stable principal specialization. - - ``q`` (default: ``None``) -- the value to use for `q`; the + - ``q`` -- (default: ``None``) the value to use for `q`; the default is to create a ring of polynomials in ``q`` (or a field of rational functions in ``q``) over the given coefficient ring. @@ -785,7 +777,6 @@ def principal_specialization(self, n=infinity, q=None): sage: p.zero().principal_specialization(3) 0 - """ def get_variable(ring, name): try: @@ -871,10 +862,10 @@ def exponential_specialization(self, t=None, q=1): INPUT: - - ``t`` (default: ``None``) -- the value to use for `t`; - the default is to create a ring of polynomials in ``t``. + - ``t`` -- (default: ``None``) the value to use for `t`; + the default is to create a ring of polynomials in ``t`` - - ``q`` (default: `1`) -- the value to use for `q`. If + - ``q`` -- (default: `1`) the value to use for `q`. If ``q`` is ``None``, then a ring (or fraction field) of polynomials in ``q`` is created. @@ -897,7 +888,6 @@ def exponential_specialization(self, t=None, q=1): sage: p.zero().exponential_specialization() 0 - """ def get_variable(ring, name): try: @@ -943,4 +933,6 @@ def f(partition): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.powersum', 'SymmetricFunctionAlgebraElement_power', SymmetricFunctionAlgebra_power.Element) +register_unpickle_override('sage.combinat.sf.powersum', + 'SymmetricFunctionAlgebraElement_power', + SymmetricFunctionAlgebra_power.Element) diff --git a/src/sage/combinat/sf/schur.py b/src/sage/combinat/sf/schur.py index 40e1de75812..6d68365f270 100644 --- a/src/sage/combinat/sf/schur.py +++ b/src/sage/combinat/sf/schur.py @@ -33,7 +33,7 @@ class SymmetricFunctionAlgebra_schur(classical.SymmetricFunctionAlgebra_classical): def __init__(self, Sym): """ - A class for methods related to the Schur symmetric function basis + A class for methods related to the Schur symmetric function basis. INPUT: @@ -52,7 +52,7 @@ def __init__(self, Sym): def _dual_basis_default(self): """ - Returns the default value for ``self.dual_basis()`` + Return the default value for ``self.dual_basis()``. This method returns the dual basis to the Schur basis with respect to the standard scalar product. Since the Schur basis is self-dual, it returns itself. @@ -86,9 +86,7 @@ def product_on_basis(self, left, right): - ``self`` -- a Schur symmetric function basis - ``left``, ``right`` -- partitions - OUTPUT: - - - an element of the Schur basis, the product of ``left`` and ``right`` + OUTPUT: an element of the Schur basis, the product of ``left`` and ``right`` TESTS:: @@ -138,7 +136,7 @@ def product_on_basis(self, left, right): def coproduct_on_basis(self, mu): r""" - Returns the coproduct of ``self(mu)``. + Return the coproduct of ``self(mu)``. Here ``self`` is the basis of Schur functions in the ring of symmetric functions. @@ -229,16 +227,14 @@ def _repeated_bernstein_creation_operator_on_basis(self, la, nu): class Element(classical.SymmetricFunctionAlgebra_classical.Element): def __pow__(self, n): """ - Returns the naive powering of an instance of ``self``. + Return the naive powering of an instance of ``self``. INPUT: - ``self`` -- an element of the Schur symmetric function basis - - ``n`` -- a nonnegative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - the ``n`-th power of an instance of ``self`` in the Schur basis + OUTPUT: the `n`-th power of an instance of ``self`` in the Schur basis See ``Monoids.Element.__pow__`` and ``Monoids.Element._pow_naive``. @@ -275,7 +271,6 @@ def __pow__(self, n): # 10 loops, best of 3: 1.73 s per loop Todo: do the same for the other non multiplicative bases? - """ return self._pow_naive(n) @@ -315,9 +310,7 @@ def omega(self): :meth:`omega_involution()` is a synonym for the :meth:`omega()` method. - OUTPUT: - - - the image of ``self`` under the omega automorphism + OUTPUT: the image of ``self`` under the omega automorphism EXAMPLES:: @@ -351,9 +344,7 @@ def scalar(self, x, zee=None): (the default value is the standard :meth:`~sage.combinat.sf.sfa.zee` function) - OUTPUT: - - - the scalar product between ``self`` and ``x`` + OUTPUT: the scalar product between ``self`` and ``x`` EXAMPLES:: @@ -466,7 +457,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -563,7 +554,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -624,12 +615,12 @@ def principal_specialization(self, n=infinity, q=None): INPUT: - - ``n`` (default: ``infinity``) -- a nonnegative integer or + - ``n`` -- (default: ``infinity``) a nonnegative integer or ``infinity``, specifying whether to compute the principal specialization of order ``n`` or the stable principal specialization. - - ``q`` (default: ``None``) -- the value to use for `q`; the + - ``q`` -- (default: ``None``) the value to use for `q`; the default is to create a ring of polynomials in ``q`` (or a field of rational functions in ``q``) over the given coefficient ring. @@ -674,7 +665,6 @@ def principal_specialization(self, n=infinity, q=None): sage: s.zero().principal_specialization(3) 0 - """ def get_variable(ring, name): try: @@ -769,10 +759,10 @@ def exponential_specialization(self, t=None, q=1): INPUT: - - ``t`` (default: ``None``) -- the value to use for `t`; - the default is to create a ring of polynomials in ``t``. + - ``t`` -- (default: ``None``) the value to use for `t`; + the default is to create a ring of polynomials in ``t`` - - ``q`` (default: `1`) -- the value to use for `q`. If + - ``q`` -- (default: `1`) the value to use for `q`. If ``q`` is ``None``, then a ring (or fraction field) of polynomials in ``q`` is created. @@ -815,7 +805,6 @@ def exponential_specialization(self, t=None, q=1): sage: s.zero().exponential_specialization() 0 - """ def get_variable(ring, name): try: @@ -854,4 +843,6 @@ def f(partition): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override -register_unpickle_override('sage.combinat.sf.schur', 'SymmetricFunctionAlgebraElement_schur', SymmetricFunctionAlgebra_schur.Element) +register_unpickle_override('sage.combinat.sf.schur', + 'SymmetricFunctionAlgebraElement_schur', + SymmetricFunctionAlgebra_schur.Element) diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index fbf1ee165f7..9f15dd18fea 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -44,7 +44,7 @@ class SymmetricFunctions(UniqueRepresentation, Parent): r""" - The abstract algebra of commutative symmetric functions + The abstract algebra of commutative symmetric functions. .. rubric:: Symmetric Functions in Sage @@ -135,7 +135,7 @@ class SymmetricFunctions(UniqueRepresentation, Parent): sage: p[[]] p[] - .. note:: When elements are constructed using the ``p[something ]`` syntax , + .. NOTE:: When elements are constructed using the ``p[something ]`` syntax , an error will be raised if the input cannot be interpreted as a partition. This is *not* the case when ``p.basis()`` is used:: @@ -522,14 +522,14 @@ class function on the symmetric group where the elements One can also use the Sage standard renaming idiom to get shorter outputs:: sage: Sym = SymmetricFunctions(QQ) - sage: Sym.rename("Sym") + sage: Sym.rename('Sym') sage: Sym Sym sage: Sym.rename() And we name it back:: - sage: Sym.rename("Symmetric Functions over Rational Field"); Sym + sage: Sym.rename('Symmetric Functions over Rational Field'); Sym Symmetric Functions over Rational Field .. rubric:: Other bases @@ -863,7 +863,6 @@ def __init__(self, R): sage: Sym1 = SymmetricFunctions(FiniteField(23)) sage: Sym2 = SymmetricFunctions(Integers(23)) sage: TestSuite(Sym).run() - """ # change the line below to assert(R in Rings()) once MRO issues from #15536, #15475 are resolved assert R in Fields() or R in Rings() # side effect of this statement assures MRO exists for R @@ -898,7 +897,7 @@ def _repr_(self): # could be taken care of by the category def schur(self): r""" - The Schur basis of the Symmetric Functions + The Schur basis of the Symmetric Functions. EXAMPLES:: @@ -911,7 +910,7 @@ def schur(self): def powersum(self): r""" - The power sum basis of the Symmetric Functions + The power sum basis of the Symmetric Functions. EXAMPLES:: @@ -924,7 +923,7 @@ def powersum(self): def complete(self): r""" - The complete basis of the Symmetric Functions + The complete basis of the Symmetric Functions. EXAMPLES:: @@ -937,7 +936,7 @@ def complete(self): def elementary(self): r""" - The elementary basis of the Symmetric Functions + The elementary basis of the Symmetric Functions. EXAMPLES:: @@ -949,7 +948,7 @@ def elementary(self): def monomial(self): r""" - The monomial basis of the Symmetric Functions + The monomial basis of the Symmetric Functions. EXAMPLES:: @@ -1220,7 +1219,7 @@ def hecke_character(self, q='q'): def macdonald(self, q='q', t='t'): r""" - Returns the entry point for the various Macdonald bases. + Return the entry point for the various Macdonald bases. INPUT: @@ -1267,7 +1266,7 @@ def macdonald(self, q='q', t='t'): def hall_littlewood(self, t='t'): """ - Returns the entry point for the various Hall-Littlewood bases. + Return the entry point for the various Hall-Littlewood bases. INPUT: @@ -1299,7 +1298,7 @@ def hall_littlewood(self, t='t'): def jack(self, t='t'): """ - Returns the entry point for the various Jack bases. + Return the entry point for the various Jack bases. INPUT: @@ -1325,7 +1324,7 @@ def jack(self, t='t'): def zonal(self): """ - The zonal basis of the Symmetric Functions + The zonal basis of the Symmetric Functions. EXAMPLES:: @@ -1340,7 +1339,7 @@ def llt(self, k, t='t'): INPUT: - - ``k`` -- a positive integer indicating the level + - ``k`` -- positive integer indicating the level - ``t`` -- a parameter (default: `t`) LLT polynomials in `hspin` and `hcospin` bases. @@ -1360,7 +1359,7 @@ def llt(self, k, t='t'): def from_polynomial(self, f): """ - Converts a symmetric polynomial ``f`` to a symmetric function. + Convert a symmetric polynomial ``f`` to a symmetric function. INPUT: @@ -1422,7 +1421,7 @@ def register_isomorphism(self, morphism, only_conversion=False): def __init_extra__(self): """ - Sets up the coercions between the different bases + Set up the coercions between the different bases. EXAMPLES:: @@ -1438,7 +1437,6 @@ def __init_extra__(self): 2*s[] + 2*s[1] - 3*s[1, 1] + 3*s[2] sage: f(p.an_element()) == p.an_element() True - """ #powersum = self.powersum () #complete = self.complete () @@ -1472,8 +1470,8 @@ def kBoundedSubspace(self, k, t='t'): INPUT: - - ``k`` -- a positive integer - - ``t`` a formal parameter; `t=1` yields a subring + - ``k`` -- positive integer + - ``t`` -- a formal parameter; `t=1` yields a subring The subspace of the ring of symmetric functions spanned by `\{ s_{\lambda}[X/(1-t)] \}_{\lambda_1\le k} = \{ s_{\lambda}^{(k)}[X,t]\}_{\lambda_1 \le k}` @@ -1503,7 +1501,7 @@ def kBoundedSubspace(self, k, t='t'): def kschur(self, k, t='t'): r""" - Returns the `k`-Schur functions. + Return the `k`-Schur functions. EXAMPLES:: @@ -1543,7 +1541,7 @@ def ksplit(self, k, t='t'): def khomogeneous(self, k): r""" - Returns the homogeneous symmetric functions in the `k`-bounded subspace. + Return the homogeneous symmetric functions in the `k`-bounded subspace. EXAMPLES:: @@ -1558,11 +1556,11 @@ def khomogeneous(self, k): def kBoundedQuotient(self, k, t='t'): r""" - Returns the `k`-bounded quotient space of the ring of symmetric functions. + Return the `k`-bounded quotient space of the ring of symmetric functions. INPUT: - - ``k`` -- a positive integer + - ``k`` -- positive integer The quotient of the ring of symmetric functions ... @@ -1593,7 +1591,7 @@ def __init__(self, t, domain, codomain): INPUT: - ``t`` -- a function taking a monomial in CombinatorialFreeModule(QQ, Partitions()), - and returning a (partition, coefficient) list. + and returning a (partition, coefficient) list - ``domain``, ``codomain`` -- parents diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 033a753f076..794f7a0cb42 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -239,7 +239,7 @@ def is_SymmetricFunctionAlgebra(x): """ - Checks whether ``x`` is a symmetric function algebra. + Check whether ``x`` is a symmetric function algebra. EXAMPLES:: @@ -277,7 +277,7 @@ def zee(part): INPUT: - - ``part`` -- an integer partition (for example, ``[2,1,1]``) + - ``part`` -- integer partition (for example, ``[2,1,1]``) OUTPUT: @@ -297,19 +297,27 @@ def zee(part): def is_SymmetricFunction(x): r""" - Checks whether ``x`` is a symmetric function. + Check whether ``x`` is a symmetric function. EXAMPLES:: sage: from sage.combinat.sf.sfa import is_SymmetricFunction sage: s = SymmetricFunctions(QQ).s() sage: is_SymmetricFunction(2) + doctest:warning... + DeprecationWarning: The function is_SymmetricFunction is deprecated; + use 'isinstance(..., SymmetricFunctionAlgebra_generic.Element)' instead. + See https://github.com/sagemath/sage/issues/38279 for details. False sage: is_SymmetricFunction(s(2)) True sage: is_SymmetricFunction(s([2,1])) True """ + from sage.misc.superseded import deprecation + deprecation(38279, + "The function is_SymmetricFunction is deprecated; " + "use 'isinstance(..., SymmetricFunctionAlgebra_generic.Element)' instead.") return isinstance(x, SymmetricFunctionAlgebra_generic.Element) ##################################################################### @@ -403,7 +411,7 @@ def is_integral_domain(self, proof=True): INPUT: - ``self`` -- a basis of the symmetric functions - - ``proof`` -- an optional argument (default value: ``True``) + - ``proof`` -- an optional argument (default: value: ``True``) EXAMPLES:: @@ -417,6 +425,22 @@ def is_integral_domain(self, proof=True): """ return self.base_ring().is_integral_domain() + @cached_method + def fraction_field(self): + r""" + Return the fraction field of ``self``. + + EXAMPLES:: + + sage: s = SymmetricFunctions(QQ).s() + sage: s.fraction_field() + Fraction Field of Symmetric Functions over Rational Field in the Schur basis + """ + if not self.is_integral_domain(): + raise TypeError("self must be an integral domain") + from sage.rings.fraction_field import FractionField_generic + return FractionField_generic(self) + def is_field(self, proof=True): """ Return whether ``self`` is a field. (It is not.) @@ -424,7 +448,7 @@ def is_field(self, proof=True): INPUT: - ``self`` -- a basis of the symmetric functions - - ``proof`` -- an optional argument (default value: ``True``) + - ``proof`` -- an optional argument (default: value: ``True``) EXAMPLES:: @@ -452,7 +476,7 @@ def is_commutative(self) -> bool: def _repr_(self): """ - Text representation of this basis of symmetric functions + Text representation of this basis of symmetric functions. INPUT: @@ -467,7 +491,7 @@ def _repr_(self): In the following examples, we rename {{{Sym}}} for brevity:: - sage: Sym.rename("Sym"); Sym + sage: Sym.rename('Sym'); Sym Sym Classical bases:: @@ -573,7 +597,7 @@ def _repr_(self): @cached_method def one_basis(self): r""" - Return the empty partition, as per ``AlgebrasWithBasis.ParentMethods.one_basis`` + Return the empty partition, as per ``AlgebrasWithBasis.ParentMethods.one_basis``. INPUT: @@ -1313,13 +1337,13 @@ def carlitz_shareshian_wachs(self, n, d, s, comparison=None): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - - ``d`` -- a nonnegative integer + - ``d`` -- nonnegative integer - - ``s`` -- a nonnegative integer + - ``s`` -- nonnegative integer - - ``comparison`` (default: ``None``) -- a variable + - ``comparison`` -- (default: ``None``) a variable which can take the forms ``None``, ``-1``, ``0`` and ``1`` @@ -1812,14 +1836,14 @@ class SymmetricFunctionAlgebra_generic(CombinatorialFreeModule): """ def __init__(self, Sym, basis_name=None, prefix=None, graded=True): r""" - Initializes the symmetric function algebra. + Initialize the symmetric function algebra. INPUT: - ``Sym`` -- the ring of symmetric functions - ``basis_name`` -- name of basis (default: ``None``) - ``prefix`` -- prefix used to display basis - - ``graded`` -- (default: ``True``) if ``True``, then the basis is + - ``graded`` -- boolean (default: ``True``); if ``True``, then the basis is considered to be graded, otherwise the basis is filtered TESTS:: @@ -1849,7 +1873,7 @@ def __init__(self, Sym, basis_name=None, prefix=None, graded=True): cat = FilteredSymmetricFunctionsBases(Sym) CombinatorialFreeModule.__init__(self, Sym.base_ring(), _Partitions, category=cat, - bracket="", prefix=prefix) + bracket='', prefix=prefix) _print_style = 'lex' @@ -1861,7 +1885,7 @@ def __getitem__(self, c): INPUT: - - ``c`` -- a list, list of lists, or partition + - ``c`` -- list, list of lists, or partition .. TODO:: @@ -1906,9 +1930,7 @@ def _change_by_proportionality(self, x, function): - ``function`` -- a function which takes in a partition and returns a scalar - OUTPUT: - - A symmetric function in ``self`` which is a scaled version of ``x``. + OUTPUT: a symmetric function in ``self`` which is a scaled version of ``x`` EXAMPLES:: @@ -1934,14 +1956,12 @@ def _change_by_plethysm(self, x, expr, deg_one): - ``x`` -- a symmetric function - ``expr`` -- an expression used in the plethysm - - ``deg_one`` -- a list (or iterable) specifying the degree one + - ``deg_one`` -- list (or iterable) specifying the degree one variables (that is, the terms to be treated as degree-one elements when encountered in ``x``; they will be taken to the appropriate powers when computing the plethysm) - OUTPUT: - - The plethysm of ``x`` by ``expr``. + OUTPUT: the plethysm of ``x`` by ``expr`` EXAMPLES:: @@ -1962,7 +1982,7 @@ def _change_by_plethysm(self, x, expr, deg_one): # Convert to the power sum p = self.realization_of().power() p_x = p(x) - expr_k = lambda k: expr.subs(**dict([(str(x),x**k) for x in deg_one])) + expr_k = lambda k: expr.subs(**{str(x): x**k for x in deg_one}) f = lambda m,c: (m, c*prod([expr_k(k) for k in m])) return self(p_x.map_item(f)) @@ -1983,7 +2003,7 @@ def _apply_multi_module_morphism(self, x, y, f, orthogonal=False): - ``f`` -- a function that takes in two partitions (basis elements) and returns an element of the target domain - ``orthogonal`` -- if orthogonal is set to ``True``, then - ``f(part1, part2)`` is assumed to be 0 if ``part1 != part2``. + ``f(part1, part2)`` is assumed to be 0 if ``part1 != part2`` EXAMPLES:: @@ -2055,31 +2075,31 @@ def _from_cache(self, element, cache_function, cache_dict, **subs_dict): INPUT: - - ``element`` -- an element of a realization `M` of the ring of - symmetric functions. Note that `M` can be a different realization - than the one in which ``self`` is written, and does not have to - be specified. It is assumed that the basis of ``self`` is indexed - by partitions, and the degree of a basis element is the size of - the partition indexing it. - - - ``cache_function`` -- a function which accepts an - integer `n` as its input and creates the cache for that homogeneous - component (saving it in ``cache_dict``). - - - ``cache_dict`` -- a dictionary storing a cache. - It should be indexed by the positive integers `n`. Its values - are dictionaries indexed by the partitions of size `n`. The values - of those latter dictionaries are, again, dictionaries indexed by - partitions of size `n`. Altogether, ``cache_dict`` should be - understood to encode a graded linear map from `M` to the - realization ``self`` of the ring of symmetric functions; the - encoding is done in such a way that, for any `n` and any partitions - ``lam`` and ``mu`` of `n`, the ``self[mu]``-coordinate of the image - of ``M[lam]`` under this linear map (in the basis ``self``) is - ``cache_dict[lam][mu]``. - - - ``subs_dict`` -- (optional) a dictionary for any substitutions - to make after the value is extracted from ``cache_dict``. + - ``element`` -- an element of a realization `M` of the ring of + symmetric functions. Note that `M` can be a different realization + than the one in which ``self`` is written, and does not have to + be specified. It is assumed that the basis of ``self`` is indexed + by partitions, and the degree of a basis element is the size of + the partition indexing it. + + - ``cache_function`` -- a function which accepts an + integer `n` as its input and creates the cache for that homogeneous + component (saving it in ``cache_dict``). + + - ``cache_dict`` -- dictionary storing a cache. + It should be indexed by the positive integers `n`. Its values + are dictionaries indexed by the partitions of size `n`. The values + of those latter dictionaries are, again, dictionaries indexed by + partitions of size `n`. Altogether, ``cache_dict`` should be + understood to encode a graded linear map from `M` to the + realization ``self`` of the ring of symmetric functions; the + encoding is done in such a way that, for any `n` and any partitions + ``lam`` and ``mu`` of `n`, the ``self[mu]``-coordinate of the image + of ``M[lam]`` under this linear map (in the basis ``self``) is + ``cache_dict[lam][mu]``. + + - ``subs_dict`` -- (optional) a dictionary for any substitutions + to make after the value is extracted from ``cache_dict`` EXAMPLES:: @@ -2136,35 +2156,35 @@ def _invert_morphism(self, n, base_ring, INPUT: - - ``n`` -- an integer, the homogeneous component of - symmetric functions for which we want to a morphism's inverse + - ``n`` -- integer, the homogeneous component of + symmetric functions for which we want to a morphism's inverse - - ``base_ring`` -- the base ring being worked over + - ``base_ring`` -- the base ring being worked over - - ``self_to_other_cache`` -- a dictionary which - stores the transition from ``self`` to ``other`` + - ``self_to_other_cache`` -- dictionary which + stores the transition from ``self`` to ``other`` - - ``other_to_self_cache`` -- a dictionary which - stores the transition from ``other`` to ``self`` + - ``other_to_self_cache`` -- dictionary which + stores the transition from ``other`` to ``self`` - - ``to_other_function`` -- a function which takes in - a partition and returns a function which gives the coefficients of - ``self(part)`` in the ``other`` basis + - ``to_other_function`` -- a function which takes in + a partition and returns a function which gives the coefficients of + ``self(part)`` in the ``other`` basis - - ``to_self_function`` -- a function which takes in a - partition and returns a function which gives the coefficients of - ``other(part)`` in ``self`` + - ``to_self_function`` -- a function which takes in a + partition and returns a function which gives the coefficients of + ``other(part)`` in ``self`` - - ``upper_triangular`` -- a boolean, if ``True``, the - inverse will be computed by back substitution + - ``upper_triangular`` -- boolean; if ``True``, the + inverse will be computed by back substitution - - ``lower_triangular`` -- a boolean, if ``True``, the - inverse will be computed by forward substitution + - ``lower_triangular`` -- boolean; if ``True``, the + inverse will be computed by forward substitution - - ``ones_on_diagonal`` -- a boolean, if ``True``, the - entries on the diagonal of the morphism (and inverse) matrix are - assumed to be ones. This is used to remove divisions from the - forward and back substitute algorithms. + - ``ones_on_diagonal`` -- boolean; if ``True``, the + entries on the diagonal of the morphism (and inverse) matrix are + assumed to be ones. This is used to remove divisions from the + forward and back substitute algorithms. OUTPUT: @@ -2387,9 +2407,7 @@ def symmetric_function_ring(self): Return the family of symmetric functions associated to the basis ``self``. - OUTPUT: - - - returns an instance of the ring of symmetric functions + OUTPUT: an instance of the ring of symmetric functions EXAMPLES:: @@ -2424,13 +2442,12 @@ def transition_matrix(self, basis, n): INPUT: - ``basis`` -- a basis of the ring of symmetric functions - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: - - a matrix of coefficients giving the expansion of the - homogeneous degree-`n` elements of ``self`` in the - degree-`n` elements of ``basis`` + A matrix of coefficients giving the expansion of the homogeneous + degree-`n` elements of ``self`` in the degree-`n` elements of ``basis``. EXAMPLES:: @@ -2639,12 +2656,12 @@ def _inner_plethysm_pk_g(self, k, g, cache): INPUT: - - ``k`` -- a positive integer + - ``k`` -- positive integer - - ``g`` -- a symmetric function in the power sum basis + - ``g`` -- a symmetric function in the power sum basis - - ``cache`` -- a dictionary whose keys are (k, g) pairs - and values are the cached output of this function + - ``cache`` -- dictionary whose keys are (k, g) pairs + and values are the cached output of this function EXAMPLES:: @@ -2707,9 +2724,7 @@ def _inner_plethysm_pnu_g(self, p_x, cache, nu): Note that the order of the arguments is somewhat strange in order to facilitate partial function application. - OUTPUT: - - - an element of the basis ``self`` + OUTPUT: an element of the basis ``self`` EXAMPLES:: @@ -2745,7 +2760,7 @@ def _inner_plethysm_pnu_g(self, p_x, cache, nu): def _dual_basis_default(self): """ - Return the default value for ``self.dual_basis()`` + Return the default value for ``self.dual_basis()``. .. SEEALSO:: :meth:`dual_basis` @@ -2776,14 +2791,14 @@ def _dual_basis_default(self): """ return self.dual_basis(scalar=zee, scalar_name="Hall scalar product") - def dual_basis(self, scalar=None, scalar_name="", basis_name=None, prefix=None): + def dual_basis(self, scalar=None, scalar_name='', basis_name=None, prefix=None): r""" Return the dual basis of ``self`` with respect to the scalar product ``scalar``. INPUT: - - ``scalar`` -- A function ``zee`` from partitions to the base ring + - ``scalar`` -- a function ``zee`` from partitions to the base ring which specifies the scalar product by `\langle p_{\lambda}, p_{\lambda} \rangle = \mathrm{zee}(\lambda)`. (Independently on the function chosen, the power sum basis will always be orthogonal; @@ -2889,7 +2904,7 @@ def set_print_style(self, ps): INPUT: - - ``ps`` -- a string specifying the printing style + - ``ps`` -- string specifying the printing style EXAMPLES:: @@ -2946,7 +2961,7 @@ def from_polynomial(self, poly, check=True): INPUT: - ``poly`` -- a symmetric polynomial - - ``check`` -- (default: ``True``) boolean, specifies whether + - ``check`` -- boolean (default: ``True``); specifies whether the computation checks that the polynomial is indeed symmetric EXAMPLES:: @@ -2974,9 +2989,7 @@ def product_by_coercion(self, left, right): - ``left``, ``right`` -- instances of this basis - OUTPUT: - - - the product of ``left`` and ``right`` expressed in the basis ``self`` + OUTPUT: the product of ``left`` and ``right`` expressed in the basis ``self`` EXAMPLES:: @@ -3085,6 +3098,40 @@ class SymmetricFunctionAlgebra_generic_Element(CombinatorialFreeModule.Element): m[1, 1, 1] + m[2, 1] + m[3] sage: m.set_print_style('lex') """ + def __truediv__(self, x): + r""" + Return the quotient of ``self`` by ``other``. + + EXAMPLES:: + + sage: s = SymmetricFunctions(QQ).s() + sage: s[1]/(1+s[1]) + s[1]/(s[] + s[1]) + + sage: s[1]/2 + 1/2*s[1] + + TESTS:: + + sage: (s[1]/2).parent() + Symmetric Functions over Rational Field in the Schur basis + """ + from sage.categories.modules import _Fields + B = self.base_ring() + try: + bx = B(x) + except TypeError: + f = self.parent().fraction_field() + return f(self, x) + F = self.parent() + D = self._monomial_coefficients + + if B not in _Fields: + return type(self)(F, {k: c._divide_if_possible(x) + for k, c in D.items()}) + + return ~bx * self + def factor(self): """ Return the factorization of this symmetric function. @@ -3128,7 +3175,6 @@ def factor(self): sage: factor(6*s[1]) 2*s[] * 3*s[] * s[1] - """ from sage.combinat.sf.multiplicative import SymmetricFunctionAlgebra_multiplicative L = self.parent() @@ -3174,7 +3220,6 @@ def _floordiv_(self, other): sage: s(6) // s(2) 3*s[] - """ from sage.combinat.sf.multiplicative import SymmetricFunctionAlgebra_multiplicative # we can assume that the parents of self and other are the same @@ -3225,7 +3270,6 @@ def gcd(self, other): sage: gcd(s(9), s(6)) 3*s[] - """ from sage.combinat.sf.multiplicative import SymmetricFunctionAlgebra_multiplicative L = self.parent() @@ -3258,12 +3302,12 @@ def plethysm(self, x, include=None, exclude=None): INPUT: - - ``x`` -- a symmetric function over the same base ring as - ``self`` - - ``include`` -- a list of variables to be treated as - degree one elements instead of the default degree one elements - - ``exclude`` -- a list of variables to be excluded - from the default degree one elements + - ``x`` -- a symmetric function over the same base ring as + ``self`` + - ``include`` -- list of variables to be treated as + degree one elements instead of the default degree one elements + - ``exclude`` -- list of variables to be excluded + from the default degree one elements OUTPUT: @@ -3429,7 +3473,7 @@ def plethysm(self, x, include=None, exclude=None): tHA = HopfAlgebrasWithBasis(R).TensorProducts() tensorflag = Px in tHA - if not is_SymmetricFunction(x): + if not isinstance(x, SymmetricFunctionAlgebra_generic.Element): if R.has_coerce_map_from(Px) or x in R: x = R(x) Px = R @@ -3598,9 +3642,7 @@ def inner_plethysm(self, x): - ``x`` -- element of the ring of symmetric functions over the same base ring as ``self`` - OUTPUT: - - - an element of symmetric functions in the parent of ``self`` + OUTPUT: an element of symmetric functions in the parent of ``self`` EXAMPLES:: @@ -4806,8 +4848,8 @@ def nabla(self, q=None, t=None, power=1): INPUT: - - ``q``, ``t`` -- optional parameters (default: ``None``, in which - case ``q`` and ``t`` are used) + - ``q``, ``t`` -- parameters (default: ``None``, in which case ``q`` + and ``t`` are used) - ``power`` -- (default: ``1``) an integer indicating how many times to apply the operator `\nabla`. Negative values of ``power`` indicate powers of `\nabla^{-1}`. @@ -4867,7 +4909,7 @@ def scalar(self, x, zee=None): - ``zee`` -- an optional function on partitions giving the value for the scalar product between `p_{\mu}` and `p_{\mu}` - (default is to use the standard :meth:`~sage.combinat.sf.sfa.zee` function) + (default: the standard :meth:`~sage.combinat.sf.sfa.zee` function) This is the default implementation that converts both ``self`` and ``x`` into either Schur functions (if ``zee`` is not specified) or @@ -5165,7 +5207,7 @@ def adams_operator(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -5330,7 +5372,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -5529,7 +5571,7 @@ def _expand(self, condition, n, alphabet='x'): selecting only certain terms (namely, only the items failing the condition are being expanded) - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -5676,9 +5718,7 @@ def restrict_degree(self, d, exact=True): exactly ``d``, otherwise returns all terms of degree less than or equal to ``d`` - OUTPUT: - - - the homogeneous component of ``self`` of degree ``d`` + OUTPUT: the homogeneous component of ``self`` of degree ``d`` EXAMPLES:: @@ -5764,7 +5804,7 @@ def expand(self, n, alphabet='x'): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer - ``alphabet`` -- (default: ``'x'``) a variable for the expansion @@ -5969,11 +6009,9 @@ def eval_at_permutation_roots(self, rho): INPUT: - - ``rho`` -- a partition or a list of non-negative integers - - OUTPUT: + - ``rho`` -- a partition or a list of nonnegative integers - - an element of the base ring + OUTPUT: an element of the base ring EXAMPLES:: @@ -6012,12 +6050,10 @@ def character_to_frobenius_image(self, n): INPUT: - - ``n`` -- a non-negative integer to interpret ``self`` as + - ``n`` -- nonnegative integer to interpret ``self`` as a character of `GL_n` - OUTPUT: - - - a symmetric function of degree ``n`` + OUTPUT: a symmetric function of degree ``n`` EXAMPLES:: @@ -6064,12 +6100,12 @@ def principal_specialization(self, n=infinity, q=None): INPUT: - - ``n`` (default: ``infinity``) -- a nonnegative integer or + - ``n`` -- (default: ``infinity``) a nonnegative integer or ``infinity``, specifying whether to compute the principal specialization of order ``n`` or the stable principal specialization. - - ``q`` (default: ``None``) -- the value to use for `q`; the + - ``q`` -- (default: ``None``) the value to use for `q`; the default is to create a ring of polynomials in ``q`` (or a field of rational functions in ``q``) over the given coefficient ring. @@ -6139,7 +6175,7 @@ def principal_specialization(self, n=infinity, q=None): 1 Check that the stable principal specialization at `q = 1` - raises a :class:`ValueError`: + raises a :exc:`ValueError`: sage: def test_error(x): ....: message = "the stable principal specialization of %s at q=1 should raise a ValueError" @@ -6263,7 +6299,6 @@ def principal_specialization(self, n=infinity, q=None): {1} sage: set(b.one().principal_specialization(q=q) for b in B) {1} - """ # heuristically, it seems fastest to fall back to the # elementary basis - using the powersum basis would @@ -6318,10 +6353,10 @@ def exponential_specialization(self, t=None, q=1): INPUT: - - ``t`` (default: ``None``) -- the value to use for `t`; - the default is to create a ring of polynomials in ``t``. + - ``t`` -- (default: ``None``) the value to use for `t`; + the default is to create a ring of polynomials in ``t`` - - ``q`` (default: `1`) -- the value to use for `q`. If + - ``q`` -- (default: `1`) the value to use for `q`. If ``q`` is ``None``, then a ring (or fraction field) of polynomials in ``q`` is created. @@ -6434,6 +6469,7 @@ def exponential_specialization(self, t=None, q=1): from sage.categories.commutative_rings import CommutativeRings from sage.categories.functor import Functor + class SymmetricFunctionsFunctor(ConstructionFunctor): """ A constructor for algebras of symmetric functions. @@ -6474,7 +6510,6 @@ def __init__(self, basis, name, *args): sage: qbar = SymmetricFunctions(R).hecke_character() sage: SymmetricFunctionsFunctor(qbar, qbar.basis_name(), q) SymmetricFunctionsFunctor[Hecke character with q=q] - """ self._basis = basis.__class__.__base__ self._name = name @@ -6500,7 +6535,6 @@ def _apply_functor(self, R): Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - """ from sage.combinat.sf.sf import SymmetricFunctions return self._basis(SymmetricFunctions(R), *self._args) @@ -6812,7 +6846,7 @@ def _to_polynomials(lf, R): INPUT: - - ``lf`` -- a list of symmetric functions + - ``lf`` -- list of symmetric functions - ``R`` -- the base ring .. SEEALSO:: @@ -6842,7 +6876,7 @@ def _to_polynomials(lf, R): def _from_polynomial(p, f): """ Return the polynomial as a symmetric function in the given - basis , where the `n`th variable corresponds to the symmetric + basis , where the `n`-th variable corresponds to the symmetric function`f[n]`. INPUT: @@ -6866,7 +6900,7 @@ def _from_polynomial(p, f): n = p.parent().ngens() if n == 1: d = {_Partitions.from_exp([e]): c - for e, c in p.dict().items()} + for e, c in p.monomial_coefficients().items()} else: d = {_Partitions.from_exp(e): c for e, c in p.iterator_exp_coeff(False)} diff --git a/src/sage/combinat/sf/symplectic.py b/src/sage/combinat/sf/symplectic.py index f6db1782489..8102121389e 100644 --- a/src/sage/combinat/sf/symplectic.py +++ b/src/sage/combinat/sf/symplectic.py @@ -229,9 +229,7 @@ def _s_to_sp_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - the expansion of ``s[lam]`` in the symplectic basis ``self`` + OUTPUT: the expansion of ``s[lam]`` in the symplectic basis ``self`` EXAMPLES:: diff --git a/src/sage/combinat/sf/witt.py b/src/sage/combinat/sf/witt.py index cf14fa826c6..5e8b115c95c 100644 --- a/src/sage/combinat/sf/witt.py +++ b/src/sage/combinat/sf/witt.py @@ -239,9 +239,7 @@ def _h_to_w_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - the expansion of ``h[lam]`` in the Witt basis ``self`` + OUTPUT: the expansion of ``h[lam]`` in the Witt basis ``self`` EXAMPLES:: @@ -318,9 +316,7 @@ def _e_to_w_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - the expansion of ``e[lam]`` in the Witt basis ``self`` + OUTPUT: the expansion of ``e[lam]`` in the Witt basis ``self`` EXAMPLES:: @@ -395,9 +391,7 @@ def _p_to_w_on_basis(self, lam): - ``lam`` -- a partition - OUTPUT: - - - the expansion of ``p[lam]`` in the Witt basis ``self`` + OUTPUT: the expansion of ``p[lam]`` in the Witt basis ``self`` EXAMPLES:: @@ -561,7 +555,7 @@ def verschiebung(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: diff --git a/src/sage/combinat/shard_order.py b/src/sage/combinat/shard_order.py index b61eb61fa48..f9081ef77dc 100644 --- a/src/sage/combinat/shard_order.py +++ b/src/sage/combinat/shard_order.py @@ -45,7 +45,7 @@ class ShardPosetElement(tuple): - ``p`` -- the permutation itself as a tuple - ``runs`` -- the decreasing runs as a tuple of tuples - - ``run_indices`` -- a list ``integer -> index of the run`` + - ``run_indices`` -- list; ``integer -> index of the run`` - ``dpg`` -- the transitive closure of the shard preorder graph - ``spg`` -- the transitive reduction of the shard preorder graph @@ -60,7 +60,7 @@ class ShardPosetElement(tuple): """ def __new__(cls, p): r""" - Initialization of the underlying tuple + Initialization of the underlying tuple. TESTS:: @@ -127,7 +127,7 @@ def __le__(self, other): sage: e1 <= e0 False """ - if type(self) is not type(other) or len(self) != len(other): + if not isinstance(other, ShardPosetElement) or len(self) != len(other): raise TypeError("these are not comparable") if self.runs == other.runs: return True @@ -172,13 +172,13 @@ def shard_preorder_graph(runs): INPUT: - - a tuple of tuples, the runs of a permutation, or + - ``runs`` -- either - - a tuple of pairs `(i,j)`, each one standing for a run from `i` to `j`. + - a tuple of tuples, the runs of a permutation, or - OUTPUT: + - a tuple of pairs `(i,j)`, each one standing for a run from `i` to `j` - a directed graph, with vertices labelled by integers + OUTPUT: a directed graph, with vertices labelled by integers EXAMPLES:: diff --git a/src/sage/combinat/shifted_primed_tableau.py b/src/sage/combinat/shifted_primed_tableau.py index 68612443e82..6d889425d28 100644 --- a/src/sage/combinat/shifted_primed_tableau.py +++ b/src/sage/combinat/shifted_primed_tableau.py @@ -284,7 +284,7 @@ def __eq__(self, other): - ``other`` -- the element that ``self`` is compared to - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -311,7 +311,7 @@ def __ne__(self, other): - ``other`` -- the element that ``self`` is compared to - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -938,9 +938,7 @@ def f(self, ind): - ``ind`` -- element in the index set of the crystal - OUTPUT: - - Primed tableau or ``None``. + OUTPUT: primed tableau or ``None`` EXAMPLES:: @@ -1133,9 +1131,7 @@ def e(self, ind): - ``ind`` -- an element in the index set of the crystal - OUTPUT: - - Primed tableau or ``None``. + OUTPUT: primed tableau or ``None`` EXAMPLES:: @@ -1363,7 +1359,7 @@ class PrimedEntry(SageObject): INPUT: - - ``entry`` -- a half integer or a string of an integer + - ``entry`` -- half integer or string of an integer possibly ending in ``p`` or ``'`` - ``double`` -- the doubled value """ @@ -1537,7 +1533,7 @@ def __ge__(self, other): def is_unprimed(self): """ - Checks if ``self`` is an unprimed element. + Check if ``self`` is an unprimed element. TESTS:: @@ -1550,7 +1546,7 @@ def is_unprimed(self): def is_primed(self): """ - Checks if ``self`` is a primed element. + Check if ``self`` is a primed element. TESTS:: @@ -1648,7 +1644,7 @@ def decrease_one(self): class ShiftedPrimedTableaux(UniqueRepresentation, Parent): r""" - Returns the combinatorial class of shifted primed tableaux subject + Return the combinatorial class of shifted primed tableaux subject to the constraints given by the arguments. A primed tableau is a tableau of shifted shape on the alphabet @@ -1873,9 +1869,7 @@ def _element_constructor_(self, T): - ``T`` -- data which can be interpreted as a primed tableau - OUTPUT: - - - the corresponding primed tableau object + OUTPUT: the corresponding primed tableau object EXAMPLES:: @@ -2722,9 +2716,11 @@ def _add_strip(sub_tab, full_tab, length): if sub_tab and len(sub_tab) < len(full_tab): plat_list.append(min(sub_tab[-1] + primed_strip[-2] - 1, full_tab[len(sub_tab)])) - for row in reversed(range(1, len(sub_tab))): - plat_list.append(min(sub_tab[row-1]+primed_strip[row-1]-1, full_tab[row]) - - sub_tab[row] - primed_strip[row]) + plat_list.extend( + min(sub_tab[row-1] + primed_strip[row-1] - 1, full_tab[row]) + - sub_tab[row] - primed_strip[row] + for row in reversed(range(1, len(sub_tab)))) + if sub_tab: plat_list.append(full_tab[0] - sub_tab[0] - primed_strip[0]) else: diff --git a/src/sage/combinat/shuffle.py b/src/sage/combinat/shuffle.py index 846a214e30d..f1797f7acab 100644 --- a/src/sage/combinat/shuffle.py +++ b/src/sage/combinat/shuffle.py @@ -81,7 +81,7 @@ def __init__(self, l1, l2, element_constructor=None): sage: from sage.combinat.shuffle import ShuffleProduct sage: SP = ShuffleProduct([1,2],[4,5,7,8,9]) - sage: TestSuite(SP).run(skip="_test_an_element") + sage: TestSuite(SP).run(skip='_test_an_element') """ self._l1 = l1 self._l2 = l2 @@ -140,7 +140,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Test for unequality + Test for unequality. EXAMPLES:: @@ -205,7 +205,7 @@ def __init__(self, l1, l2, element_constructor=None): - ``l1``, ``l2`` -- iterable: the sets to shuffle - - ``element_constructor`` -- constructor for the returned elements + - ``element_constructor`` -- constructor for the returned elements TESTS:: @@ -213,7 +213,7 @@ def __init__(self, l1, l2, element_constructor=None): sage: X = SetShuffleProduct({(1,2,3), (2,3,4)}, {(5,)}) sage: X # random Shuffle set product of: [(2, 3, 4), (1, 2, 3)] and [(5,)] - sage: TestSuite(X).run(skip="_test_an_element") + sage: TestSuite(X).run(skip='_test_an_element') sage: list(SetShuffleProduct({(1,2,3), (2,3,4)}, {(5,)})) # random [[2, 3, 4, 5], [2, 5, 3, 4], [5, 2, 3, 4], [2, 3, 5, 4], @@ -243,7 +243,6 @@ def _repr_(self): Shuffle set product of: [[1, 2], [3, 4]] and [[1, 4]] sage: SetShuffleProduct([()], [[1,4]]) Shuffle set product of: [()] and [[1, 4]] - """ return "Shuffle set product of: %s and %s" % (self._element_constructor_(self._l1), self._element_constructor_(self._l2)) @@ -259,7 +258,6 @@ def _ascii_art_(self): [ [ o, o ] ] [ [ / \ ] ] [ [ ], [ o o ] ] and [ [ 1, 4 ] ] - """ from sage.typeset.ascii_art import ascii_art return (ascii_art("Set shuffle product of:") * @@ -334,7 +332,6 @@ class ShuffleProduct(ShuffleProduct_abstract): 'abdec'] sage: list(ShuffleProduct("", "de", element_constructor="".join)) ['de'] - """ def __init__(self, l1, l2, element_constructor=None): @@ -345,7 +342,7 @@ def __init__(self, l1, l2, element_constructor=None): - ``l1``, ``l2`` -- iterable: iterables to shuffle - - ``element_constructor``: constructor for the returned elements + - ``element_constructor`` -- constructor for the returned elements TESTS:: @@ -353,7 +350,7 @@ def __init__(self, l1, l2, element_constructor=None): sage: SP = ShuffleProduct([1,2,3],[4,5]) sage: SP Shuffle product of: [1, 2, 3] and [4, 5] - sage: TestSuite(SP).run(skip="_test_an_element") + sage: TestSuite(SP).run(skip='_test_an_element') sage: list(ShuffleProduct(Word("aa"), Word("bbb"), Word)) [word: aabbb, word: baabb, word: ababb, word: bbaab, word: babab, word: abbab, @@ -567,7 +564,7 @@ def __init__(self, w1, w2, r, element_constructor=None, add=operator.add): sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]]) sage: S = ShuffleProduct_overlapping_r(w,u,1) - sage: TestSuite(S).run(skip="_test_an_element") + sage: TestSuite(S).run(skip='_test_an_element') """ self.r = r self.add = add @@ -777,7 +774,7 @@ def __init__(self, w1, w2, element_constructor=None, add=operator.add): sage: from sage.combinat.shuffle import ShuffleProduct_overlapping sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]]) sage: S = ShuffleProduct_overlapping(w,u) - sage: TestSuite(S).run(skip="_test_an_element") + sage: TestSuite(S).run(skip='_test_an_element') """ self._add = add diff --git a/src/sage/combinat/sidon_sets.py b/src/sage/combinat/sidon_sets.py index 9ba6bdb5c71..e2c85f74633 100644 --- a/src/sage/combinat/sidon_sets.py +++ b/src/sage/combinat/sidon_sets.py @@ -31,12 +31,10 @@ def sidon_sets(N, g=1): INPUT: - - `N` -- A positive integer. - - `g` -- A positive integer (default: `1`). + - ``N`` -- positive integer + - ``g`` -- positive integer (default: `1`) - OUTPUT: - - - A Sage set with categories whose element are also set of integers. + OUTPUT: a Sage set with categories whose element are also set of integers EXAMPLES:: diff --git a/src/sage/combinat/similarity_class_type.py b/src/sage/combinat/similarity_class_type.py index f6a67af12c0..caa691ac559 100644 --- a/src/sage/combinat/similarity_class_type.py +++ b/src/sage/combinat/similarity_class_type.py @@ -215,13 +215,11 @@ def fq(n, q=None): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - - ``q`` -- an integer or an indeterminate - - OUTPUT: + - ``q`` -- integer or an indeterminate - A rational function in ``q``. + OUTPUT: a rational function in ``q`` EXAMPLES:: @@ -253,15 +251,13 @@ def primitives(n, invertible=False, q=None): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``invertible`` -- boolean; if set, only number of non-zero classes is returned + - ``invertible`` -- boolean; if set, only number of nonzero classes is returned - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate - OUTPUT: - - - a rational function of the variable ``q`` + OUTPUT: a rational function of the variable ``q`` EXAMPLES:: @@ -292,9 +288,9 @@ def order_of_general_linear_group(n, q=None): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate EXAMPLES:: @@ -340,9 +336,7 @@ def centralizer_group_cardinality(la, q=None): - ``q`` -- an integer or an indeterminate - OUTPUT: - - A polynomial function of ``q``. + OUTPUT: a polynomial function of ``q`` EXAMPLES:: @@ -367,9 +361,7 @@ def invariant_subspace_generating_function(la, q=None, t=None): - ``q`` -- (optional) an integer or an inderminate - ``t`` -- (optional) an indeterminate - OUTPUT: - - A polynomial in ``t`` whose coefficients are polynomials in ``q``. + OUTPUT: a polynomial in ``t`` whose coefficients are polynomials in ``q`` EXAMPLES:: @@ -588,7 +580,7 @@ def centralizer_group_card(self, q=None): INPUT: - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate EXAMPLES:: @@ -637,7 +629,7 @@ class PrimarySimilarityClassTypes(UniqueRepresentation, Parent): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``min`` -- a primary matrix type of size ``n`` EXAMPLES: @@ -767,7 +759,7 @@ class SimilarityClassType(CombinatorialElement): INPUT: - - ``tau`` -- a list of primary similarity class types or a square matrix + - ``tau`` -- list of primary similarity class types or a square matrix over a finite field EXAMPLES:: @@ -872,7 +864,7 @@ def centralizer_group_card(self, q=None): INPUT: - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate EXAMPLES:: @@ -908,10 +900,10 @@ def number_of_classes(self, invertible=False, q=None): INPUT: - - ``invertible`` -- Boolean; return number of invertible classes if set + - ``invertible`` -- boolean; return number of invertible classes if set to ``True`` - - ``q`` -- An integer or an indeterminate + - ``q`` -- integer or an indeterminate EXAMPLES:: @@ -990,7 +982,7 @@ def class_card(self, q=None): INPUT: - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate EXAMPLES:: @@ -1011,7 +1003,7 @@ def number_of_matrices(self, invertible=False, q=None): INPUT: - - ``invertible`` -- A boolean; return the number of invertible + - ``invertible`` -- a boolean; return the number of invertible matrices if set EXAMPLES:: @@ -1031,7 +1023,7 @@ def number_of_matrices(self, invertible=False, q=None): def statistic(self, func, q=None): r""" - Return + Return. .. MATH:: @@ -1044,7 +1036,7 @@ def statistic(self, func, q=None): - ``func`` -- a function that takes a partition to a polynomial in ``q`` - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate EXAMPLES:: @@ -1100,7 +1092,7 @@ class SimilarityClassTypes(UniqueRepresentation, Parent): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - ``min`` -- a primary similarity class type EXAMPLES: @@ -1168,7 +1160,7 @@ def _element_constructor_(self, tau): INPUT: - - ``tau`` -- a list of primary similarity class types + - ``tau`` -- list of primary similarity class types EXAMPLES:: @@ -1238,7 +1230,7 @@ def size(self): """ return self._n - def sum(self, stat, sumover="matrices", invertible=False, q=None): + def sum(self, stat, sumover='matrices', invertible=False, q=None): r""" Return the sum of a local statistic over all types. @@ -1256,10 +1248,10 @@ def sum(self, stat, sumover="matrices", invertible=False, q=None): \sum n_{\tau(g)}(q) where `\tau(g)` denotes the type of a matrix `g`, and the sum is over - all `n \times n` matrices if ``sumover`` is set to ``"matrices"``, is + all `n \times n` matrices if ``sumover`` is set to ``'matrices'``, is over all `n \times n` similarity classes if ``sumover`` is set to - ``"classes"``, and over all `n \times n` types if ``sumover`` is set - to ``"types"``. If ``invertible`` is set to ``True``, then the sum is + ``'classes'``, and over all `n \times n` types if ``sumover`` is set + to ``'types'``. If ``invertible`` is set to ``True``, then the sum is only over invertible matrices or classes. INPUT: @@ -1268,15 +1260,13 @@ def sum(self, stat, sumover="matrices", invertible=False, q=None): of ``q`` - ``sumover`` -- can be one of the following: - * ``"matrices"`` - * ``"classes"`` - * ``"types"`` + * ``'matrices'`` + * ``'classes'`` + * ``'types'`` - - ``q`` -- an integer or an indeterminate + - ``q`` -- integer or an indeterminate - OUTPUT: - - A function of ``q``. + OUTPUT: a function of ``q`` EXAMPLES:: @@ -1445,8 +1435,8 @@ def ext_orbits(input_data, q=None, selftranspose=False): - ``input_data`` -- input for :func:`input_parsing()` - ``q`` -- (default: `q`) an integer or an indeterminate - - ``selftranspose`` -- (default: ``False``) boolean stating if we only want - selftranspose type + - ``selftranspose`` -- boolean (default: ``False``); stating if we only + want selftranspose type TESTS:: @@ -1522,9 +1512,9 @@ def matrix_similarity_classes_length_two(n, q=None, selftranspose=False, inverti - ``n`` -- the order - ``q`` -- (default: `q`) an integer or an indeterminate - - ``selftranspose`` -- (default: ``False``) boolean stating if we only want + - ``selftranspose`` -- boolean (default: ``False``); stating if we only want selftranspose type - - ``invertible`` -- (default: ``False``) boolean stating if we only want + - ``invertible`` -- boolean (default: ``False``); stating if we only want invertible type EXAMPLES: @@ -1575,7 +1565,7 @@ def ext_orbit_centralizers(input_data, q=None, selftranspose=False): - ``input_data`` -- input for :func:`input_parsing()` - ``q`` -- (default: `q`) an integer or an indeterminate - - ``selftranspose`` -- (default: ``False``) boolean stating if we only want + - ``selftranspose`` -- boolean (default: ``False``); stating if we only want selftranspose type TESTS:: @@ -1700,9 +1690,9 @@ def matrix_centralizer_cardinalities_length_two(n, q=None, selftranspose=False, - ``n`` -- the order - ``q`` -- (default: `q`) an integer or an indeterminate - - ``selftranspose`` -- (default: ``False``) boolean stating if we only want + - ``selftranspose`` -- boolean (default: ``False``); stating if we only want selftranspose type - - ``invertible`` -- (default: ``False``) boolean stating if we only want + - ``invertible`` -- boolean (default: ``False``); stating if we only want invertible type TESTS:: diff --git a/src/sage/combinat/sine_gordon.py b/src/sage/combinat/sine_gordon.py index 0e71beca5ef..1891f172d38 100644 --- a/src/sage/combinat/sine_gordon.py +++ b/src/sage/combinat/sine_gordon.py @@ -66,7 +66,7 @@ class SineGordonYsystem(SageObject): r""" - A class to model a (reduced) sine-Gordon Y-system + A class to model a (reduced) sine-Gordon Y-system. Note that the generations, together with all integer tuples, in this implementation are numbered from 0 while in [NS]_ they are numbered from 1 diff --git a/src/sage/combinat/six_vertex_model.py b/src/sage/combinat/six_vertex_model.py index 365cc0dd360..879418f18d9 100644 --- a/src/sage/combinat/six_vertex_model.py +++ b/src/sage/combinat/six_vertex_model.py @@ -361,13 +361,13 @@ class SixVertexModel(UniqueRepresentation, Parent): There are also the following predefined boundary conditions: - * ``'ice'`` -- The top and bottom boundary conditions are outward and the + * ``'ice'`` -- the top and bottom boundary conditions are outward and the left and right boundary conditions are inward; this gives the square ice model. Also called domain wall boundary conditions. - * ``'domain wall'`` -- Same as ``'ice'``. - * ``'alternating'`` -- The boundary conditions alternate between inward + * ``'domain wall'`` -- same as ``'ice'``. + * ``'alternating'`` -- the boundary conditions alternate between inward and outward. - * ``'free'`` -- There are no boundary conditions. + * ``'free'`` -- there are no boundary conditions. EXAMPLES: diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index b78e6b84d1f..aad38f9afbf 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -277,7 +277,6 @@ def _latex_diagram(self): sage: print(SkewPartition([[],[]])._latex_diagram()) {\emptyset} - """ if not any(self._list): return "{\\emptyset}" @@ -392,7 +391,7 @@ def ferrers_diagram(self): *** *** * - sage: SkewPartitions.options(diagram_str='#', convention="French") + sage: SkewPartitions.options(diagram_str='#', convention='French') sage: print(SkewPartition([[5,4,3,1],[3,1]]).diagram()) # ### @@ -441,7 +440,7 @@ def _ascii_art_(self): [ * * * * ] [ ** ** * * * * * * ] [ ***, * , * , **, ** , *, * , * , * ] - sage: SkewPartitions.options(diagram_str='#', convention="French") + sage: SkewPartitions.options(diagram_str='#', convention='French') sage: ascii_art(SkewPartitions(3).list()) [ # # # # ] [ # # ## ## # # # # ] @@ -816,7 +815,7 @@ def inner_corners(self): icorners += [(nn, 0)] return icorners - def cell_poset(self, orientation="SE"): + def cell_poset(self, orientation='SE'): """ Return the Young diagram of ``self`` as a poset. The optional keyword variable ``orientation`` determines the order relation @@ -825,10 +824,10 @@ def cell_poset(self, orientation="SE"): The poset always uses the set of cells of the Young diagram of ``self`` as its ground set. The order relation of the poset depends on the ``orientation`` variable (which defaults to - ``"SE"``). Concretely, ``orientation`` has to be specified to - one of the strings ``"NW"``, ``"NE"``, ``"SW"``, and ``"SE"``, + ``'SE'``). Concretely, ``orientation`` has to be specified to + one of the strings ``'NW'``, ``'NE'``, ``'SW'``, and ``'SE'``, standing for "northwest", "northeast", "southwest" and - "southeast", respectively. If ``orientation`` is ``"SE"``, then + "southeast", respectively. If ``orientation`` is ``'SE'``, then the order relation of the poset is such that a cell `u` is greater or equal to a cell `v` in the poset if and only if `u` lies weakly southeast of `v` (this means that `u` can be @@ -1033,12 +1032,9 @@ def cells(self): """ outer = self.outer() inner = self.inner()[:] - inner += [0]*(len(outer)-len(inner)) - res = [] - for i in range(len(outer)): - for j in range(inner[i], outer[i]): - res.append( (i,j) ) - return res + inner += [0] * (len(outer) - len(inner)) + return [(i, j) for i, outi in enumerate(outer) + for j in range(inner[i], outi)] def to_list(self): """ @@ -1054,7 +1050,7 @@ def to_list(self): """ return [list(r) for r in list(self)] - def to_dag(self, format="string"): + def to_dag(self, format='string'): """ Return a directed acyclic graph corresponding to the skew partition ``self``. @@ -1081,7 +1077,7 @@ def to_dag(self, format="string"): ('1,1', '1,2', None)] sage: dag.vertices(sort=True) ['0,1', '0,2', '1,1', '1,2', '2,0'] - sage: dag = SkewPartition([[3, 2, 1], [1, 1]]).to_dag(format="tuple") + sage: dag = SkewPartition([[3, 2, 1], [1, 1]]).to_dag(format='tuple') sage: dag.edges(sort=True) [((0, 1), (0, 2), None), ((0, 1), (1, 1), None)] sage: dag.vertices(sort=True) @@ -1149,15 +1145,13 @@ def rows_intersection_set(self): sage: skp.rows_intersection_set() == cells True """ - res = [] outer = self.outer() inner = self.inner() - inner += [0] * int(len(outer)-len(inner)) + inner += [0] * (len(outer) - len(inner)) - for i in range(len(outer)): - for j in range(outer[i]): - if outer[i] != inner[i]: - res.append((i,j)) + res = [(i, j) for i, outi in enumerate(outer) + for j in range(outi) + if outi != inner[i]] return Set(res) def columns_intersection_set(self): @@ -1239,7 +1233,7 @@ def jacobi_trudi(self): h = SymmetricFunctions(QQ).homogeneous() H = MatrixSpace(h, nn) - q = q + [0]*int(nn-len(q)) + q = q + [0] * (nn - len(q)) m = [] for i in range(1,nn+1): row = [] @@ -1414,7 +1408,7 @@ def __init__(self, is_infinite=False): # add options to class class options(GlobalOptions): """ - Sets and displays the options for elements of the skew partition + Set and display the options for elements of the skew partition classes. If no parameters are set, then the function returns a copy of the options dictionary. @@ -1436,7 +1430,7 @@ class options(GlobalOptions): Changing the ``convention`` for skew partitions also changes the ``convention`` option for partitions and tableaux and vice versa:: - sage: SkewPartitions.options(display="diagram", convention='French') + sage: SkewPartitions.options(display='diagram', convention='French') sage: SP * * @@ -1465,24 +1459,24 @@ class options(GlobalOptions): """ NAME = 'SkewPartitions' module = 'sage.combinat.skew_partition' - display = dict(default="quotient", + display = dict(default='quotient', description='Specifies how skew partitions should be printed', values=dict(lists='displayed as a pair of lists', quotient='displayed as a quotient of partitions', diagram='as a skew Ferrers diagram'), - alias=dict(array="diagram", ferrers_diagram="diagram", - young_diagram="diagram", pair="lists"), + alias=dict(array='diagram', ferrers_diagram='diagram', + young_diagram='diagram', pair='lists'), case_sensitive=False) - latex = dict(default="young_diagram", + latex = dict(default='young_diagram', description='Specifies how skew partitions should be latexed', values=dict(diagram='latex as a skew Ferrers diagram', young_diagram='latex as a skew Young diagram', marked='latex as a partition where the skew shape is marked'), - alias=dict(array="diagram", ferrers_diagram="diagram"), + alias=dict(array='diagram', ferrers_diagram='diagram'), case_sensitive=False) diagram_str = dict(link_to=(Partitions.options,'diagram_str')) latex_diagram_str = dict(link_to=(Partitions.options,'latex_diagram_str')) - latex_marking_str = dict(default="X", + latex_marking_str = dict(default='X', description='The character used to marked the deleted cells when latexing marked partitions', checker=lambda char: isinstance(char, str)) convention = dict(link_to=(Tableaux.options,'convention')) @@ -1571,15 +1565,15 @@ def from_row_and_column_length(self, rowL, colL): INPUT: - - ``rowL`` -- A composition or a list of positive integers + - ``rowL`` -- a composition or a list of positive integers - - ``colL`` -- A composition or a list of positive integers + - ``colL`` -- a composition or a list of positive integers OUTPUT: - If it exists the unique skew-partitions with row lengths ``rowL`` and column lengths ``colL``. - - Raise a :class:`ValueError` if ``rowL`` and ``colL`` are not compatible. + - Raise a :exc:`ValueError` if ``rowL`` and ``colL`` are not compatible. EXAMPLES:: @@ -1610,7 +1604,7 @@ def from_row_and_column_length(self, rowL, colL): If some rows and columns have length zero, there is no way to retrieve unambiguously the skew partition. We therefore raise - a :class:`ValueError`. + a :exc:`ValueError`. For examples here are two skew partitions with the same row and column lengths:: @@ -1716,9 +1710,9 @@ class SkewPartitions_n(SkewPartitions): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - - ``overlap`` -- an integer (default: `0`) + - ``overlap`` -- integer (default: `0`) Caveat: this set is stable under conjugation only for ``overlap`` equal to 0 or 1. What exactly happens for negative overlaps is not yet @@ -1768,8 +1762,8 @@ def __init__(self, n, overlap): INPUT: - - ``n`` -- a non-negative integer - - ``overlap`` -- an integer + - ``n`` -- nonnegative integer + - ``overlap`` -- integer TESTS:: diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index 99ef16b740d..44189013d5c 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -152,9 +152,7 @@ def __eq__(self, other): - ``other`` -- the element that ``self`` is compared to - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -189,9 +187,7 @@ def __ne__(self, other): - ``other`` -- the element that ``self`` is compared to - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -688,7 +684,7 @@ def is_semistandard(self): def to_tableau(self): """ - Returns a tableau with the same filling. This only works if the + Return a tableau with the same filling. This only works if the inner shape of the skew tableau has size zero. EXAMPLES:: @@ -1069,9 +1065,9 @@ def rectify(self, algorithm=None): INPUT: - - ``algorithm`` -- optional: if set to ``'jdt'``, rectifies by jeu de + - ``algorithm`` -- (optional) if set to ``'jdt'``, rectifies by jeu de taquin; if set to ``'schensted'``, rectifies by Schensted insertion - of the reading word; otherwise, guesses which will be faster. + of the reading word. Otherwise, guesses which will be faster. EXAMPLES:: @@ -1136,7 +1132,6 @@ def to_list(self): [[None, None, 3], [None, 1, 3], [2, 2]] sage: st.to_list() == stlist True - """ return [list(row) for row in self] @@ -1177,10 +1172,10 @@ def row_stabilizer(self): # tableau, by including the identity permutation on the set [1..k]. k = self.size() gens = [list(range(1, k + 1))] - for row in self: - for j in range(len(row) - 1): - if row[j] is not None: - gens.append((row[j], row[j + 1])) + gens.extend((row[j], row[j + 1]) + for row in self + for j in range(len(row) - 1) + if row[j] is not None) return PermutationGroup(gens) def column_stabilizer(self): @@ -1353,8 +1348,8 @@ def standardization(self, check=True): INPUT: - - ``check`` -- (Default: ``True``) Check to make sure ``self`` is - semistandard. Set to ``False`` to avoid this check. + - ``check`` -- (default: ``True``) check to make sure ``self`` is + semistandard; set to ``False`` to avoid this check EXAMPLES:: @@ -1420,17 +1415,17 @@ def bender_knuth_involution(self, k, rows=None, check=True): INPUT: - - ``k`` -- an integer + - ``k`` -- integer - - ``rows`` -- (Default ``None``) When set to ``None``, the method + - ``rows`` -- (default: ``None``) when set to ``None``, the method computes the `k`-th Bender--Knuth involution as defined above. When an iterable, this computes the composition of the `k`-th Bender--Knuth switches at row `i` over all `i` in ``rows``. When set to an integer `i`, the method computes the `k`-th Bender--Knuth switch at row `i`. Note the indexing of the rows starts with `1`. - - ``check`` -- (Default: ``True``) Check to make sure ``self`` is - semistandard. Set to ``False`` to avoid this check. + - ``check`` -- (default: ``True``) check to make sure ``self`` is + semistandard; set to ``False`` to avoid this check OUTPUT: @@ -1686,8 +1681,8 @@ def to_ribbon(self, check_input=True): INPUT: - - ``check_input`` -- (default: ``True``) whether or not to check - that ``self`` indeed has ribbon shape + - ``check_input`` -- boolean (default: ``True``); whether or not to + check that ``self`` indeed has ribbon shape EXAMPLES:: @@ -1782,12 +1777,10 @@ def cells(self): sage: s.cells() [(0, 1), (0, 2), (1, 0), (2, 0)] """ - res = [] - for i in range(len(self)): - for j in range(len(self[i])): - if self[i][j] is not None: - res.append((i, j)) - return res + return [(i, j) + for i, selfi in enumerate(self) + for j in range(len(selfi)) + if selfi[j] is not None] def cells_containing(self, i): r""" @@ -1833,7 +1826,7 @@ def cells_containing(self, i): def is_k_tableau(self, k): r""" - Checks whether ``self`` is a valid skew weak `k`-tableau. + Check whether ``self`` is a valid skew weak `k`-tableau. EXAMPLES:: @@ -1921,7 +1914,7 @@ def _element_constructor_(self, st): def __contains__(self, x): """ - Checks if ``x`` is a skew tableau. + Check if ``x`` is a skew tableau. EXAMPLES:: @@ -1955,12 +1948,11 @@ def from_expr(self, expr): sage: SkewTableaux().from_expr([[1,1],[[5],[3,4],[1,2]]]) [[None, 1, 2], [None, 3, 4], [5]] """ - skp = [] outer = expr[1] inner = expr[0] + [0] * (len(outer) - len(expr[0])) - for i in range(len(outer)): - skp.append([None] * (inner[i]) + outer[-(i + 1)]) + skp = [[None] * (inner[i]) + outer[-(i + 1)] + for i in range(len(outer))] return self.element_class(self, skp) @@ -2295,7 +2287,7 @@ def __iter__(self): [[None, 1, 3], [None, 2], [4]], [[None, 2, 4], [None, 3], [1]]] """ - dag = self.skp.to_dag(format="tuple") + dag = self.skp.to_dag(format='tuple') le_list = list(dag.topological_sort_generator()) empty = [[None] * row_length for row_length in self.skp.outer()] @@ -2681,9 +2673,9 @@ class SemistandardSkewTableaux_shape(SemistandardSkewTableaux): INPUT: - - ``p`` -- A skew partition + - ``p`` -- a skew partition - - ``max_entry`` -- The max entry; defaults to the size of ``p``. + - ``max_entry`` -- the max entry; defaults to the size of ``p`` .. WARNING:: diff --git a/src/sage/combinat/sloane_functions.py b/src/sage/combinat/sloane_functions.py index c1aa82e4308..08897c8b6da 100644 --- a/src/sage/combinat/sloane_functions.py +++ b/src/sage/combinat/sloane_functions.py @@ -456,7 +456,7 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -561,11 +561,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -613,11 +611,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -713,9 +709,7 @@ def __init__(self): - ``n`` -- positive integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -816,11 +810,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -873,11 +865,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -938,11 +928,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1015,11 +1003,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1061,7 +1047,7 @@ def _repr_(self): def s2(self, n, k): """ - Returns the Stirling number S2(n,k) of the 2nd kind. + Return the Stirling number S2(n,k) of the 2nd kind. EXAMPLES:: @@ -1093,11 +1079,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1160,16 +1144,14 @@ def __init__(self): to `n`. Number of totatives of `n`. Euler totient function `\phi(n)`: count numbers `n` - and prime to `n`. euler_phi is a standard Sage function - implemented in PARI + and prime to `n`. ``euler_phi`` is a standard Sage function + implemented in PARI. INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1224,11 +1206,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1275,11 +1255,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1330,11 +1308,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1386,11 +1362,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1443,9 +1417,7 @@ def __init__(self): - ``n`` -- integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1497,11 +1469,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1555,11 +1525,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1610,11 +1578,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1663,11 +1629,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1720,11 +1684,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1776,11 +1738,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1829,11 +1789,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -1880,20 +1838,18 @@ def _eval(self, n): class A000012(SloaneSequence): def __init__(self): r""" - The all 1's sequence. + The all 1s sequence. INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: sage: a = sloane.A000012; a - The all 1's sequence. + The all 1s sequence. sage: a(1) 1 sage: a(2007) @@ -1912,9 +1868,9 @@ def _repr_(self): EXAMPLES:: sage: sloane.A000012._repr_() - "The all 1's sequence." + 'The all 1s sequence.' """ - return "The all 1's sequence." + return 'The all 1s sequence.' def _eval(self, n): """ @@ -1929,20 +1885,18 @@ def _eval(self, n): class A000120(SloaneSequence): def __init__(self): r""" - 1's-counting sequence: number of 1's in binary expansion of `n`. + 1s-counting sequence: number of 1s in binary expansion of `n`. INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: sage: a = sloane.A000120;a - 1's-counting sequence: number of 1's in binary expansion of n. + 1s-counting sequence: number of 1s in binary expansion of n. sage: a(0) 0 sage: a(2) @@ -1963,9 +1917,9 @@ def _repr_(self): EXAMPLES:: sage: sloane.A000120._repr_() - "1's-counting sequence: number of 1's in binary expansion of n." + '1s-counting sequence: number of 1s in binary expansion of n.' """ - return "1's-counting sequence: number of 1's in binary expansion of n." + return '1s-counting sequence: number of 1s in binary expansion of n.' def f(self, n): """ @@ -1996,15 +1950,13 @@ def __init__(self): Let `A_k` denote the first `2^k` terms; then `A_0 = 0`, and for `k \ge 0`, `A_{k+1} = A_k B_k`, where `B_k` is obtained - from `A_k` by interchanging 0's and 1's. + from `A_k` by interchanging 0s and 1s. INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2049,20 +2001,18 @@ def _eval(self, n): class A000069(SloaneSequence): def __init__(self): r""" - Odious numbers: odd number of 1's in binary expansion. + Odious numbers: odd number of 1s in binary expansion. INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: sage: a = sloane.A000069; a - Odious numbers: odd number of 1's in binary expansion. + Odious numbers: odd number of 1s in binary expansion. sage: a(0) 1 sage: a(2) @@ -2081,9 +2031,9 @@ def _repr_(self): EXAMPLES:: sage: sloane.A000069._repr_() - "Odious numbers: odd number of 1's in binary expansion." + 'Odious numbers: odd number of 1s in binary expansion.' """ - return "Odious numbers: odd number of 1's in binary expansion." + return 'Odious numbers: odd number of 1s in binary expansion.' def _eval(self, n): """ @@ -2098,20 +2048,18 @@ def _eval(self, n): class A001969(SloaneSequence): def __init__(self): r""" - Evil numbers: even number of 1's in binary expansion. + Evil numbers: even number of 1s in binary expansion. INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: sage: a = sloane.A001969;a - Evil numbers: even number of 1's in binary expansion. + Evil numbers: even number of 1s in binary expansion. sage: a(0) 0 sage: a(1) @@ -2134,9 +2082,9 @@ def _repr_(self): EXAMPLES:: sage: sloane.A001969._repr_() - "Evil numbers: even number of 1's in binary expansion." + 'Evil numbers: even number of 1s in binary expansion.' """ - return "Evil numbers: even number of 1's in binary expansion." + return 'Evil numbers: even number of 1s in binary expansion.' def _eval(self, n): """ @@ -2155,11 +2103,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2208,11 +2154,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2262,11 +2206,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2320,15 +2262,13 @@ def _eval(self, n): class A000016(SloaneSequence): def __init__(self): r""" - Sloane's A000016 + Sloane's A000016. INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2384,11 +2324,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2450,11 +2388,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2506,11 +2442,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2600,11 +2534,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2661,11 +2593,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2717,11 +2647,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2806,11 +2734,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2864,11 +2790,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2930,11 +2854,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -2999,11 +2921,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3055,11 +2975,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3147,11 +3065,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3239,11 +3155,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3293,11 +3207,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3350,11 +3262,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3405,11 +3315,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3488,11 +3396,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3543,15 +3449,13 @@ def _eval(self, n): class A000961(SloaneSequence): def __init__(self): r""" - Prime powers + Prime powers. INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3632,15 +3536,13 @@ def list(self, n): class A005117(SloaneSequence): def __init__(self): r""" - Square-free numbers + Square-free numbers. INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3726,11 +3628,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3816,11 +3716,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3878,11 +3776,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -3934,7 +3830,7 @@ def _precompute(self, how_many=500): def fib(self): """ - Returns a generator over all Fibonacci numbers, starting with 0. + Return a generator over all Fibonacci numbers, starting with 0. EXAMPLES:: @@ -3980,11 +3876,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4034,11 +3928,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4087,11 +3979,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4140,11 +4030,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4195,11 +4083,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4250,11 +4136,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4303,11 +4187,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4354,18 +4236,16 @@ def _eval(self, n): class A000142(SloaneSequence): def __init__(self): r""" - Factorial numbers: `n! = 1 \cdot 2 \cdot 3 \cdots n` + Factorial numbers: `n! = 1 \cdot 2 \cdot 3 \cdots n`. Order of symmetric group `S_n`, number of permutations of `n` letters. INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4414,11 +4294,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4468,11 +4346,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4525,11 +4401,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4582,11 +4456,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4638,11 +4510,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4692,11 +4562,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4745,11 +4613,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4848,11 +4714,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4900,11 +4764,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -4952,11 +4814,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5004,11 +4864,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5125,11 +4983,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5178,11 +5034,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5236,11 +5090,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5298,9 +5150,7 @@ def __init__(self): - ``n`` -- positive integer >= 2 - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5356,11 +5206,9 @@ def __init__(self): INPUT: - - ``n`` -- positive integer >= 3 + - ``n`` -- positive integer `\geq 3` - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5441,11 +5289,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5505,11 +5351,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5570,11 +5414,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5643,11 +5485,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5716,11 +5556,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5789,11 +5627,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5864,11 +5700,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5925,15 +5759,13 @@ def __init__(self): permutations of `n` elements with no fixed points. With offset 1 also the permanent of a (0,1)-matrix of order - `n` with `n` 0's not on a line. + `n` with `n` 0s not on a line. INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -5991,11 +5823,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6051,11 +5881,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6104,11 +5932,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6158,11 +5984,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6221,11 +6045,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6278,11 +6100,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6332,11 +6152,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6450,11 +6268,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6513,11 +6329,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6570,7 +6384,7 @@ def g(self,k): class A001221(SloaneSequence): def __init__(self): r""" - Number of different prime divisors of `n` + Number of different prime divisors of `n`. Also called omega(n) or `\omega(n)`. Maximal number of terms in any factorization of `n`. Number of prime powers @@ -6578,11 +6392,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6640,11 +6452,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6702,9 +6512,7 @@ class A046660(SloaneSequence): - ``n`` -- positive integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6756,11 +6564,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6822,11 +6628,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6922,11 +6726,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -6992,8 +6794,7 @@ def _powerful_numbers_in_range(self, n, m): # This is naive -- too slow; too much overhead # return [i for i in range(self._n, self._n+how_many) if self.is_powerful(i)] - if n < 4: - n = 4 + n = max(n, 4) # Use PARI directly -- much faster. from sage.libs.pari.all import pari L = pari('v=listcreate(); for(i=%s,%s,if(vecmin(factor(i)[,2])>1,listput(v,i))); v' % (n, m)) @@ -7048,11 +6849,9 @@ def is_powerful(self, n) -> bool: INPUT: - - `n` -- integer - - OUTPUT: + - ``n`` -- integer - ``True`` if `n` is a powerful number, else ``False`` + OUTPUT: ``True`` if `n` is a powerful number, else ``False`` EXAMPLES:: @@ -7077,16 +6876,14 @@ def __init__(self): Numbers `n` such that `\phi(2n-1) < \phi(2n)`, where `\phi` is Euler's totient function. - Euler's totient function is also known as euler_phi, euler_phi is - a standard Sage function. + Euler's totient function is also known as ``euler_phi``; ``euler_phi`` + is a standard Sage function. INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7180,8 +6977,8 @@ def list(self, n): # a group of sequences uses this function: def recur_gen2(a0, a1, a2, a3): r""" - homogeneous general second-order linear recurrence generator with - fixed coefficients + Homogeneous general second-order linear recurrence generator with + fixed coefficients. a(0) = a0, a(1) = a1, a(n) = a2\*a(n-1) + a3\*a(n-2) @@ -7251,11 +7048,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7300,11 +7095,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7350,11 +7143,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7403,11 +7194,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7450,11 +7239,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7502,11 +7289,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7550,11 +7335,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7598,11 +7381,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7648,11 +7429,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7700,11 +7479,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7782,11 +7559,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7837,11 +7612,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7894,11 +7667,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -7945,11 +7716,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8003,11 +7772,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8051,11 +7818,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8109,7 +7874,7 @@ def _eval(self, n): # a group of sequences uses this function: def recur_gen3(a0, a1, a2, a3, a4, a5): r""" - homogeneous general third-order linear recurrence generator with + Homogeneous general third-order linear recurrence generator with fixed coefficients a(0) = a0, a(1) = a1, a(2) = a2, a(n) = a3\*a(n-1) + a4\*a(n-2) + @@ -8137,11 +7902,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8221,11 +7984,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8305,7 +8066,7 @@ def perm_mh(m, h): INPUT: - ``m`` -- positive integer - - ``h`` -- non negative integer + - ``h`` -- nonnegative integer OUTPUT: permanent of the `m \times (m+h)` matrix, etc. @@ -8333,7 +8094,7 @@ def perm_mh(m, h): class A079922(SloaneSequence): r""" - function returns solutions to the Dancing School problem with + Function returns solutions to the Dancing School problem with `n` girls and `n+3` boys. The value is `per(B)`, the permanent of the (0,1)-matrix @@ -8348,9 +8109,7 @@ class A079922(SloaneSequence): - ``n`` -- positive integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8402,7 +8161,7 @@ def _eval(self, n): class A079923(SloaneSequence): r""" - function returns solutions to the Dancing School problem with + Function returns solutions to the Dancing School problem with `n` girls and `n+4` boys. The value is `per(B)`, the permanent of the (0,1)-matrix @@ -8418,9 +8177,7 @@ class A079923(SloaneSequence): - ``n`` -- positive integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8494,11 +8251,9 @@ class A109814(SloaneSequence): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8559,8 +8314,7 @@ def _eval(self, n): continue # d is odd divisor k = min(d, 2 * n // d) - if k > m: - m = k + m = max(k, m) return ZZ(m) @@ -8579,11 +8333,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8687,11 +8439,9 @@ def is_number_of_the_third_kind(self, n) -> bool: INPUT: - - `n` -- positive integer - - OUTPUT: + - ``n`` -- positive integer - ``True`` if `n` is not prime and not a power of 2 + OUTPUT: ``True`` if `n` is not prime and not a power of 2 EXAMPLES:: @@ -8731,11 +8481,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8820,11 +8568,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: @@ -8939,11 +8685,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- `B_n` + OUTPUT: integer; `B_n` EXAMPLES:: @@ -8993,11 +8737,9 @@ def __init__(self): INPUT: - - ``n`` -- non negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - ``integer`` -- `C_n` + OUTPUT: integer; `C_n` EXAMPLES:: @@ -9038,11 +8780,9 @@ def __init__(self): r""" INPUT: - - ``n`` -- non negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``integer`` -- function value + OUTPUT: integer; function value EXAMPLES:: diff --git a/src/sage/combinat/specht_module.py b/src/sage/combinat/specht_module.py index 5b8462754ef..e48e34419fe 100644 --- a/src/sage/combinat/specht_module.py +++ b/src/sage/combinat/specht_module.py @@ -37,6 +37,7 @@ from sage.modules.free_module_element import vector from sage.categories.modules_with_basis import ModulesWithBasis + class SymmetricGroupRepresentation(Representation_abstract): """ Mixin class for symmetric group (algebra) representations. @@ -747,14 +748,15 @@ def retract(self): B = self.basis() COB = matrix([b.lift().to_vector() for b in B]).T P, L, U = COB.LU() - # Since U is upper triangular, the nonzero entriesm must be in the - # upper square portiion of the matrix + # Since U is upper triangular, the nonzero entries must be in the + # upper square portion of the matrix n = len(B) Uinv = U.matrix_from_rows(range(n)).inverse() - # This is a slight abuse as the codomain should be a module with a different - # S_n action, but we only use it internally, so there isn't any problems - PLinv = (P*L).inverse() + # This is a slight abuse as the codomain should be a module + # with a different + # S_n action, but we only use it internally, so there is no problem + PLinv = (P * L).inverse() def retraction(elt): vec = PLinv * elt.to_vector(order=self._support_order) @@ -920,9 +922,9 @@ def intrinsic_arrangement(self, base_ring=None): G = self._semigroup def t(i, j): - ret = [i for i in range(1, SGA.n+1)] - ret[i-1] = j - ret[j-1] = i + ret = list(range(1, SGA.n + 1)) + ret[i - 1] = j + ret[j - 1] = i return SGA(G(ret)) # Construct the hyperplanes @@ -1145,18 +1147,12 @@ def _to_diagram(D): if isinstance(D, Diagram): return D if D in _Partitions: - D = _Partitions(D).cells() - elif D in SkewPartitions(): - D = SkewPartitions()(D).cells() - elif D in IntegerVectors(): - cells = [] - for i, row in enumerate(D): - for j in range(row): - cells.append((i, j)) - D = cells - else: - D = [tuple(cell) for cell in D] - return D + return _Partitions(D).cells() + if D in SkewPartitions(): + return SkewPartitions()(D).cells() + if D in IntegerVectors(): + return [(i, j) for i, row in enumerate(D) for j in range(row)] + return [tuple(cell) for cell in D] def specht_module_spanning_set(D, SGA=None): @@ -1165,8 +1161,8 @@ def specht_module_spanning_set(D, SGA=None): INPUT: - - ``D`` -- a list of cells ``(r,c)`` for row ``r`` and column ``c`` - - ``SGA`` -- optional; a symmetric group algebra + - ``D`` -- list of cells ``(r,c)`` for row ``r`` and column ``c`` + - ``SGA`` -- (optional) a symmetric group algebra EXAMPLES:: diff --git a/src/sage/combinat/species/all.py b/src/sage/combinat/species/all.py index 58bfc1a756f..1c3a550d342 100644 --- a/src/sage/combinat/species/all.py +++ b/src/sage/combinat/species/all.py @@ -46,6 +46,6 @@ from sage.misc.lazy_import import lazy_import lazy_import("sage.combinat.species.recursive_species", "CombinatorialSpecies") -lazy_import("sage.combinat.species", "library", as_="species") +lazy_import("sage.combinat.species", "library", as_='species') del lazy_import del install_doc diff --git a/src/sage/combinat/species/characteristic_species.py b/src/sage/combinat/species/characteristic_species.py index 37ce75abe28..a8078bc7313 100644 --- a/src/sage/combinat/species/characteristic_species.py +++ b/src/sage/combinat/species/characteristic_species.py @@ -75,7 +75,7 @@ def transport(self, perm): def automorphism_group(self): """ - Returns the group of permutations whose action on this structure + Return the group of permutations whose action on this structure leave it fixed. For the characteristic species, there is only one structure, so every permutation is in its automorphism group. @@ -169,7 +169,7 @@ def _gs_term(self, base_ring): def _order(self): """ - Returns the order of the generating series. + Return the order of the generating series. EXAMPLES:: @@ -212,7 +212,7 @@ def _cis_term(self, base_ring): def _equation(self, var_mapping): """ - Returns the right hand side of an algebraic equation satisfied by + Return the right hand side of an algebraic equation satisfied by this species. This is a utility function called by the algebraic_equation_system method. @@ -235,7 +235,7 @@ def _equation(self, var_mapping): class EmptySetSpecies(CharacteristicSpecies): def __init__(self, min=None, max=None, weight=None): """ - Returns the empty set species. + Return the empty set species. This species has exactly one structure on the empty set. It is the same (and is implemented) as ``CharacteristicSpecies(0)``. @@ -279,7 +279,7 @@ def __init__(self, min=None, max=None, weight=None): class SingletonSpecies(CharacteristicSpecies): def __init__(self, min=None, max=None, weight=None): """ - Returns the species of singletons. + Return the species of singletons. This species has exactly one structure on a set of size `1`. It is the same (and is implemented) as ``CharacteristicSpecies(1)``. diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index ccfe0141803..17a240b72dc 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -72,11 +72,11 @@ def change_labels(self, labels): INPUT: - - ``labels``, a list of labels. + - ``labels`` -- list of labels OUTPUT: - A structure with the i-th label of self replaced with the i-th + A structure with the `i`-th label of ``self`` replaced with the `i`-th label of the list. EXAMPLES:: @@ -99,7 +99,7 @@ def change_labels(self, labels): class CompositionSpecies(GenericCombinatorialSpecies, UniqueRepresentation): def __init__(self, F, G, min=None, max=None, weight=None): """ - Returns the composition of two species. + Return the composition of two species. EXAMPLES:: @@ -255,7 +255,7 @@ def _cis(self, series_ring, base_ring): def weight_ring(self): """ - Returns the weight ring for this species. This is determined by + Return the weight ring for this species. This is determined by asking Sage's coercion model what the result is when you multiply (and add) elements of the weight rings for each of the operands. diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index c808f6a0db1..bc27b988d3c 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -44,7 +44,7 @@ def canonical_label(self): def permutation_group_element(self): """ - Returns this cycle as a permutation group element. + Return this cycle as a permutation group element. EXAMPLES:: @@ -59,7 +59,7 @@ def permutation_group_element(self): def transport(self, perm): """ - Returns the transport of this structure along the permutation + Return the transport of this structure along the permutation perm. EXAMPLES:: @@ -80,7 +80,7 @@ def transport(self, perm): def automorphism_group(self): """ - Returns the group of permutations whose action on this structure + Return the group of permutations whose action on this structure leave it fixed. EXAMPLES:: @@ -117,7 +117,7 @@ def __classcall__(cls, *args, **kwds): def __init__(self, min=None, max=None, weight=None): """ - Returns the species of cycles. + Return the species of cycles. EXAMPLES:: @@ -201,7 +201,7 @@ def _gs_callable(self, base_ring, n): def _order(self): """ - Returns the order of the generating series. + Return the order of the generating series. EXAMPLES:: diff --git a/src/sage/combinat/species/empty_species.py b/src/sage/combinat/species/empty_species.py index 5c4762cb34d..8ebad9b871d 100644 --- a/src/sage/combinat/species/empty_species.py +++ b/src/sage/combinat/species/empty_species.py @@ -21,7 +21,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): """ - Returns the empty species. This species has no structure at all. + Return the empty species. This species has no structure at all. It is the zero of the semi-ring of species. EXAMPLES:: @@ -98,7 +98,7 @@ def __init__(self, min=None, max=None, weight=None): def _gs(self, series_ring, base_ring): """ - Return the generating series for self. + Return the generating series for ``self``. EXAMPLES:: @@ -135,7 +135,7 @@ def _structures(self, structure_class, labels): def _equation(self, var_mapping): """ - Returns the right hand side of an algebraic equation satisfied by + Return the right hand side of an algebraic equation satisfied by this species. This is a utility function called by the algebraic_equation_system method. diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index b327492a54a..2fc5ede99db 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -26,7 +26,7 @@ class FunctorialCompositionStructure(GenericSpeciesStructure): class FunctorialCompositionSpecies(GenericCombinatorialSpecies): def __init__(self, F, G, min=None, max=None, weight=None): """ - Returns the functorial composition of two species. + Return the functorial composition of two species. EXAMPLES:: @@ -124,7 +124,7 @@ def _cis(self, series_ring, base_ring): def weight_ring(self): """ - Returns the weight ring for this species. This is determined by + Return the weight ring for this species. This is determined by asking Sage's coercion model what the result is when you multiply (and add) elements of the weight rings for each of the operands. diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 7622efd279b..b970bb36dbf 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -145,7 +145,7 @@ def __init__(self, base_ring): sage: OrdinaryGeneratingSeriesRing.options._reset() # reset options """ - super().__init__(base_ring, names="z") + super().__init__(base_ring, names='z') Element = OrdinaryGeneratingSeries @@ -272,7 +272,7 @@ def __init__(self, base_ring): sage: ExponentialGeneratingSeriesRing.options._reset() # reset options """ - super().__init__(base_ring, names="z") + super().__init__(base_ring, names='z') Element = ExponentialGeneratingSeries diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 0761dea576d..41a0ac49ae4 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -35,7 +35,7 @@ def canonical_label(self): def transport(self, perm): """ - Returns the transport of this structure along the permutation + Return the transport of this structure along the permutation perm. EXAMPLES:: @@ -51,7 +51,7 @@ def transport(self, perm): def automorphism_group(self): """ - Returns the group of permutations whose action on this structure + Return the group of permutations whose action on this structure leave it fixed. For the species of linear orders, there is no non-trivial automorphism. @@ -81,7 +81,7 @@ def __classcall__(cls, *args, **kwds): def __init__(self, min=None, max=None, weight=None): """ - Returns the species of linear orders. + Return the species of linear orders. EXAMPLES:: diff --git a/src/sage/combinat/species/misc.py b/src/sage/combinat/species/misc.py index 12a9b2c8f70..04211b19d0c 100644 --- a/src/sage/combinat/species/misc.py +++ b/src/sage/combinat/species/misc.py @@ -41,7 +41,10 @@ def change_support(perm, support, change_perm=None): (3,4,5) """ if change_perm is None: - change_perm = prod([PermutationGroupElement((i+1,support[i])) for i in range(len(support)) if i+1 != support[i]], PermutationGroupElement([], SymmetricGroup(support))) + change_perm = prod([PermutationGroupElement((i+1, support[i])) + for i in range(len(support)) + if i+1 != support[i]], + PermutationGroupElement([], SymmetricGroup(support))) if isinstance(perm, PermutationGroup_generic): return PermutationGroup([change_support(g, support, change_perm) for g in perm.gens()]) diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index ef9adf66974..d166a99109a 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -72,7 +72,7 @@ def canonical_label(self): def transport(self, perm): """ - Returns the transport of this set partition along the permutation + Return the transport of this set partition along the permutation perm. For set partitions, this is the direct product of the automorphism groups for each of the blocks. @@ -91,7 +91,7 @@ def transport(self, perm): def automorphism_group(self): """ - Returns the group of permutations whose action on this set + Return the group of permutations whose action on this set partition leave it fixed. EXAMPLES:: @@ -113,11 +113,11 @@ def change_labels(self, labels): INPUT: - - ``labels``, a list of labels. + - ``labels`` -- list of labels OUTPUT: - A structure with the i-th label of self replaced with the i-th + A structure with the `i`-th label of ``self`` replaced with the `i`-th label of the list. EXAMPLES:: @@ -146,7 +146,7 @@ def __classcall__(cls, *args, **kwds): def __init__(self, min=None, max=None, weight=None): """ - Returns the species of partitions. + Return the species of partitions. EXAMPLES:: @@ -220,7 +220,7 @@ def _isotypes(self, structure_class, labels): def _canonical_rep_from_partition(self, structure_class, labels, p): """ - Returns the canonical representative corresponding to the partition + Return the canonical representative corresponding to the partition p. EXAMPLES:: @@ -261,7 +261,7 @@ def _itgs_callable(self, base_ring, n): def _cis(self, series_ring, base_ring): r""" - The cycle index series for the species of partitions is given by + The cycle index series for the species of partitions is given by. .. MATH:: diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index eebcc2cddce..7494ee33c08 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -44,7 +44,7 @@ def canonical_label(self): def permutation_group_element(self): """ - Returns self as a permutation group element. + Return ``self`` as a permutation group element. EXAMPLES:: @@ -59,7 +59,7 @@ def permutation_group_element(self): def transport(self, perm): """ - Returns the transport of this structure along the permutation + Return the transport of this structure along the permutation perm. EXAMPLES:: @@ -77,7 +77,7 @@ def transport(self, perm): def automorphism_group(self): """ - Returns the group of permutations whose action on this structure + Return the group of permutations whose action on this structure leave it fixed. EXAMPLES:: @@ -119,7 +119,7 @@ def __classcall__(cls, *args, **kwds): def __init__(self, min=None, max=None, weight=None): """ - Returns the species of permutations. + Return the species of permutations. EXAMPLES:: @@ -216,7 +216,7 @@ def _itgs_callable(self, base_ring, n): def _cis(self, series_ring, base_ring): r""" - The cycle index series for the species of permutations is given by + The cycle index series for the species of permutations is given by. .. MATH:: diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index 90209e64776..4a17d3c8ed2 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -123,11 +123,11 @@ def change_labels(self, labels): INPUT: - - ``labels``, a list of labels. + - ``labels`` -- list of labels OUTPUT: - A structure with the i-th label of self replaced with the i-th + A structure with the `i`-th label of ``self`` replaced with the `i`-th label of the list. EXAMPLES:: @@ -235,7 +235,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): def left_factor(self): """ - Returns the left factor of this product. + Return the left factor of this product. EXAMPLES:: @@ -249,7 +249,7 @@ def left_factor(self): def right_factor(self): """ - Returns the right factor of this product. + Return the right factor of this product. EXAMPLES:: @@ -372,7 +372,7 @@ def _cis(self, series_ring, base_ring): def weight_ring(self): """ - Returns the weight ring for this species. This is determined by + Return the weight ring for this species. This is determined by asking Sage's coercion model what the result is when you multiply (and add) elements of the weight rings for each of the operands. @@ -403,7 +403,7 @@ def weight_ring(self): def _equation(self, var_mapping): """ - Returns the right hand side of an algebraic equation satisfied by + Return the right hand side of an algebraic equation satisfied by this species. This is a utility function called by the algebraic_equation_system method. diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 8eaabf0d2a8..c9bc12a9a4f 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -307,16 +307,13 @@ def define(self, x): """ Define ``self`` to be equal to the combinatorial species ``x``. - This is - used to define combinatorial species recursively. All of the real - work is done by calling the .set() method for each of the series - associated to self. + This is used to define combinatorial species recursively. All of the + real work is done by calling the ``.set()`` method for each of the + series associated to ``self``. - EXAMPLES: The species of linear orders L can be recursively defined + EXAMPLES: The species of linear orders `L` can be recursively defined by `L = 1 + X*L` where 1 represents the empty set species - and X represents the singleton species. - - :: + and `X` represents the singleton species:: sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() @@ -421,7 +418,7 @@ def define(self, x): def _add_to_digraph(self, d): """ - Adds this species as a vertex to the digraph d along with any + Add this species as a vertex to the digraph d along with any 'children' of this species. Note that to avoid infinite recursion, we just return if this @@ -454,7 +451,7 @@ def _add_to_digraph(self, d): def _equation(self, var_mapping): """ - Returns the right hand side of an algebraic equation satisfied by + Return the right hand side of an algebraic equation satisfied by this species. This is a utility function called by the algebraic_equation_system method. diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index 94aa893cf46..3d45fe6b81a 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -50,7 +50,7 @@ def canonical_label(self): def transport(self, perm): """ - Returns the transport of this set along the permutation perm. + Return the transport of this set along the permutation perm. EXAMPLES:: @@ -65,7 +65,7 @@ def transport(self, perm): def automorphism_group(self): """ - Returns the group of permutations whose action on this set leave it + Return the group of permutations whose action on this set leave it fixed. For the species of sets, there is only one isomorphism class, so every permutation is in its automorphism group. @@ -95,7 +95,7 @@ def __classcall__(cls, *args, **kwds): def __init__(self, min=None, max=None, weight=None): """ - Returns the species of sets. + Return the species of sets. EXAMPLES:: diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 61d70666665..a1760df462f 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -350,9 +350,9 @@ def restricted(self, min=None, max=None): INPUT: - - ``min`` -- optional integer + - ``min`` -- (optional) integer - - ``max`` -- optional integer + - ``max`` -- (optional) integer EXAMPLES:: @@ -501,17 +501,16 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): INPUT: - - ``series_ring_class`` -- A class for the series - ring such as ExponentialGeneratingSeriesRing, etc. + - ``series_ring_class`` -- a class for the series ring such as + ``ExponentialGeneratingSeriesRing``, etc. - - ``prefix`` -- The string prefix associated with the - generating series such as "cis" for the cycle index series. This - prefix appears in the methods that are implemented in the - subclass. + - ``prefix`` -- the string prefix associated with the generating series + such as "cis" for the cycle index series. This prefix appears in the + methods that are implemented in the subclass. - - ``base_ring`` -- The ring in which the coefficients - of the generating series live. If it is not specified, then it is - determined by the weight of the species. + - ``base_ring`` -- the ring in which the coefficients of the generating + series live. If it is not specified, then it is determined by the + weight of the species. EXAMPLES:: diff --git a/src/sage/combinat/species/structure.py b/src/sage/combinat/species/structure.py index c5629212f5d..d34005ca138 100644 --- a/src/sage/combinat/species/structure.py +++ b/src/sage/combinat/species/structure.py @@ -66,7 +66,7 @@ def __init__(self, parent, labels, list): def parent(self): """ - Returns the species that this structure is associated with. + Return the species that this structure is associated with. EXAMPLES:: @@ -127,9 +127,9 @@ def __ne__(self, other): def labels(self): """ - Returns the labels used for this structure. + Return the labels used for this structure. - .. note:: + .. NOTE:: This includes labels which may not "appear" in this particular structure. @@ -149,11 +149,11 @@ def change_labels(self, labels): INPUT: - - ``labels``, a list of labels. + - ``labels`` -- list of labels OUTPUT: - A structure with the i-th label of self replaced with the i-th + A structure with the `i`-th label of ``self`` replaced with the `i`-th label of the list. EXAMPLES:: @@ -264,7 +264,7 @@ def __getattr__(self, attr): def __repr__(self): """ - Returns the repr of the object which this one wraps. + Return the repr of the object which this one wraps. EXAMPLES:: @@ -304,11 +304,11 @@ def change_labels(self, labels): INPUT: - - ``labels``, a list of labels. + - ``labels`` -- list of labels OUTPUT: - A structure with the i-th label of self replaced with the i-th + A structure with the `i`-th label of ``self`` replaced with the `i`-th label of the list. EXAMPLES:: @@ -334,7 +334,7 @@ def __init__(self, species, labels, iterator, generating_series, name, structure This is a abstract base class for the set of structures of a species as well as the set of isotypes of the species. - .. note:: + .. NOTE:: One typically does not use :class:`SpeciesWrapper` directly, but instead instantiates one of its subclasses: @@ -402,7 +402,7 @@ def _repr_(self) -> str: def labels(self): """ - Returns the labels used on these structures. If `X` is the + Return the labels used on these structures. If `X` is the species, then :meth:`labels` returns the preimage of these structures under the functor `X`. @@ -443,7 +443,7 @@ def __iter__(self): def cardinality(self): """ - Returns the number of structures in this set. + Return the number of structures in this set. EXAMPLES:: diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index 2e7a6697e29..5515f1c9d96 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -215,7 +215,7 @@ def _itgs_callable(self, base_ring, n): def _cis(self, series_ring, base_ring): r""" - The cycle index series for the species of subsets satisfies + The cycle index series for the species of subsets satisfies. .. MATH:: diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index b3ff129dc55..c54e7245a55 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -27,7 +27,7 @@ class SumSpeciesStructure(SpeciesStructureWrapper): class SumSpecies(GenericCombinatorialSpecies, UniqueRepresentation): def __init__(self, F, G, min=None, max=None, weight=None): """ - Returns the sum of two species. + Return the sum of two species. EXAMPLES:: @@ -64,7 +64,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): def left_summand(self): """ - Returns the left summand of this species. + Return the left summand of this species. EXAMPLES:: @@ -77,7 +77,7 @@ def left_summand(self): def right_summand(self): """ - Returns the right summand of this species. + Return the right summand of this species. EXAMPLES:: @@ -115,10 +115,10 @@ def _structures(self, structure_class, labels): [[1, 2], [2, 1], [1, 2], [2, 1]] """ for res in self.left_summand().structures(labels): - yield structure_class(self, res, tag="left") + yield structure_class(self, res, tag='left') for res in self.right_summand().structures(labels): - yield structure_class(self, res, tag="right") + yield structure_class(self, res, tag='right') def _isotypes(self, structure_class, labels): """ @@ -130,14 +130,14 @@ def _isotypes(self, structure_class, labels): [[2, 1], [1, 2], [2, 1], [1, 2]] """ for res in self._F.isotypes(labels): - yield structure_class(self, res, tag="left") + yield structure_class(self, res, tag='left') for res in self._G.isotypes(labels): - yield structure_class(self, res, tag="right") + yield structure_class(self, res, tag='right') def _gs(self, series_ring, base_ring): """ - Returns the cycle index series of this species. + Return the cycle index series of this species. EXAMPLES:: @@ -151,7 +151,7 @@ def _gs(self, series_ring, base_ring): def _itgs(self, series_ring, base_ring): """ - Returns the isomorphism type generating series of this species. + Return the isomorphism type generating series of this species. EXAMPLES:: @@ -165,7 +165,7 @@ def _itgs(self, series_ring, base_ring): def _cis(self, series_ring, base_ring): """ - Returns the generating series of this species. + Return the generating series of this species. EXAMPLES:: @@ -183,7 +183,7 @@ def _cis(self, series_ring, base_ring): def weight_ring(self): """ - Returns the weight ring for this species. This is determined by + Return the weight ring for this species. This is determined by asking Sage's coercion model what the result is when you add elements of the weight rings for each of the operands. @@ -206,7 +206,7 @@ def weight_ring(self): def _equation(self, var_mapping): """ - Returns the right hand side of an algebraic equation satisfied by + Return the right hand side of an algebraic equation satisfied by this species. This is a utility function called by the algebraic_equation_system method. diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index 57ea1f5393d..6c8d923ce9f 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -50,7 +50,7 @@ def Subsets(s, k=None, submultiset=False): r""" Return the combinatorial class of the subsets of the finite set ``s``. The set can be given as a list, Set or any iterable - convertible to a set. Alternatively, a non-negative integer `n` + convertible to a set. Alternatively, a nonnegative integer `n` can be provided in place of ``s``; in this case, the result is the combinatorial class of the subsets of the set `\{1,2,\dots,n\}` (i.e. of the Sage ``range(1,n+1)``). @@ -153,7 +153,7 @@ def Subsets(s, k=None, submultiset=False): if isinstance(s, (int, Integer)): if s < 0: - raise ValueError("s must be non-negative") + raise ValueError("s must be nonnegative") from sage.sets.integer_range import IntegerRange s = IntegerRange(1,s+1) @@ -254,7 +254,7 @@ def underlying_set(self): def __eq__(self, other): r""" - Equality test + Equality test. TESTS:: @@ -271,7 +271,7 @@ def __eq__(self, other): def __ne__(self, other): r""" - Difference test + Difference test. TESTS:: @@ -321,8 +321,10 @@ def __contains__(self, value): True sage: 2 in S False + sage: {1, 2} in S + True """ - if value not in Sets(): + if value not in Sets() and not isinstance(value, (set, frozenset)): return False return all(v in self._s for v in value) @@ -357,7 +359,7 @@ def cardinality(self): def first(self): """ - Returns the first subset of ``s``. Since we aren't restricted to + Return the first subset of ``s``. Since we aren't restricted to subsets of a certain size, this is always the empty set. EXAMPLES:: @@ -395,7 +397,6 @@ def __iter__(self): [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}] sage: [sub for sub in Subsets([1,2,3,3])] [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}] - """ k = ZZ_0 while k <= self._s.cardinality(): @@ -474,7 +475,6 @@ def unrank(self, r): Traceback (most recent call last): ... IndexError: index out of range - """ r = Integer(r) if r >= self.cardinality() or r < 0: @@ -524,7 +524,7 @@ def _element_constructor_(self,X): def _an_element_(self): """ - Returns an example of subset. + Return an example of subset. EXAMPLES:: @@ -554,7 +554,6 @@ def lattice(self): sage: Y = Subsets(0) sage: Y.lattice() # needs sage.combinat sage.graphs Finite lattice containing 1 elements - """ S = self.underlying_set() return S.subsets_lattice() @@ -605,7 +604,7 @@ def __init__(self, s, k): Subsets_s.__init__(self, s) self._k = Integer(k) if self._k < 0: - raise ValueError("the integer k (={}) should be non-negative".format(k)) + raise ValueError("the integer k (={}) should be nonnegative".format(k)) def _repr_(self): """ @@ -632,7 +631,7 @@ def __contains__(self, value): def __eq__(self, other): r""" - Equality test + Equality test. TESTS:: @@ -647,7 +646,7 @@ def __eq__(self, other): def __ne__(self, other): r""" - Difference test + Difference test. TESTS:: @@ -760,7 +759,7 @@ def _fast_iterator(self): def __iter__(self): """ - Iterates through the subsets of s of size k. + Iterate through the subsets of s of size k. EXAMPLES:: @@ -858,7 +857,7 @@ def unrank(self, r): def an_element(self): """ - Returns an example of subset. + Return an example of subset. EXAMPLES:: @@ -895,7 +894,7 @@ def list_to_dict(l): INPUT: - a list ``l`` with possibly repeated elements + - ``l`` -- list with possibly repeated elements The keys are the elements of ``l`` (in the same order in which they appear) and values are the multiplicities of each element in ``l``. @@ -1323,7 +1322,6 @@ def __iter__(self): sage: Subsets([3,2,2], submultiset=True).list() [[], [3], [2], [3, 2], [2, 2], [3, 2, 2]] - """ from sage.combinat.integer_vector import IntegerVectors elts = self._keys @@ -1479,7 +1477,7 @@ def powerset(X): INPUT: - - ``X`` -- an iterable + - ``X`` -- an iterable OUTPUT: iterator of lists diff --git a/src/sage/combinat/subsets_hereditary.py b/src/sage/combinat/subsets_hereditary.py index 33b576e3cf1..b02cf538f42 100644 --- a/src/sage/combinat/subsets_hereditary.py +++ b/src/sage/combinat/subsets_hereditary.py @@ -26,12 +26,12 @@ def subsets_with_hereditary_property(f, X, max_obstruction_size=None, ncpus=1): INPUT: - - ``f`` -- a boolean function which takes as input a list of elements from - ``X``. + - ``f`` -- boolean function which takes as input a list of elements from + ``X`` - - ``X`` -- a list/iterable. + - ``X`` -- list/iterable - - ``max_obstruction_size`` (integer) -- if you know that there is + - ``max_obstruction_size`` -- integer; if you know that there is a `k` such that `f(S)` is true if and only if `f(S')` is true for all `S'\subseteq S` with `S'\leq k`, set ``max_obstruction_size=k``. It may dramatically decrease the diff --git a/src/sage/combinat/subsets_pairwise.py b/src/sage/combinat/subsets_pairwise.py index ed5613157f2..d8fec5c1a0c 100644 --- a/src/sage/combinat/subsets_pairwise.py +++ b/src/sage/combinat/subsets_pairwise.py @@ -21,13 +21,13 @@ class PairwiseCompatibleSubsets(RecursivelyEnumeratedSet_forest): INPUT: - - ``ambient`` -- a set (or iterable) + - ``ambient`` -- set (or iterable) - ``predicate`` -- a binary predicate Assumptions: ``predicate`` is symmetric (``predicate(x,y) == predicate(y,x)``) and reflexive (``predicate(x,x) == True``). - .. note:: in fact, ``predicate(x,x)`` is never called. + .. NOTE:: in fact, ``predicate(x,x)`` is never called. .. warning:: The current name is suboptimal and is subject to change. Suggestions for a good name, and a good user entry @@ -68,11 +68,11 @@ class PairwiseCompatibleSubsets(RecursivelyEnumeratedSet_forest): organizing them in a search tree. Each node of this tree is of the form ``(subset, rest)``, where: - - ``subset`` represents an element of ``self``, represented - by an increasing tuple - - ``rest`` is the set of all `y`'s such that `y` appears - after `x` in the ambient set and ``predicate(x,y)`` - holds, represented by a decreasing tuple + - ``subset`` represents an element of ``self``, represented + by an increasing tuple + - ``rest`` is the set of all `y`'s such that `y` appears + after `x` in the ambient set and ``predicate(x,y)`` + holds, represented by a decreasing tuple The root of this tree is ``( (), ambient )``. All the other elements are generated by recursive depth first search, which gives @@ -96,7 +96,6 @@ def __init__(self, ambient, predicate, maximal=False, element_class=Set_object_e An enumerated set with a forest structure sage: import __main__; __main__.predicate = predicate sage: TestSuite(P).run() - """ self._ambient = set(ambient) self._roots = ( ((), tuple(reversed(ambient))), ) @@ -124,7 +123,7 @@ def __eq__(self, other): def __contains__(self, subset): """ - Membership testing + Membership testing. Returns whether subset is a subset of ``self._ambient``, and ``predicate(x,y)`` holds for every ``x,y`` in ``self``. @@ -163,7 +162,7 @@ def post_process(self, subset_rest): def children(self, subset_rest): """ - Returns the children of a node in the tree. + Return the children of a node in the tree. TESTS:: @@ -173,7 +172,6 @@ def children(self, subset_rest): An enumerated set with a forest structure sage: list(P.children( ((3,5), [14,11,7]) )) [((3, 5, 7), (11,)), ((3, 5, 11), (14,)), ((3, 5, 14), ())] - """ (subset, rest) = subset_rest predicate = self._predicate diff --git a/src/sage/combinat/subword.py b/src/sage/combinat/subword.py index e5a9afcb804..ff67d63343d 100644 --- a/src/sage/combinat/subword.py +++ b/src/sage/combinat/subword.py @@ -55,7 +55,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from __future__ import annotations -from typing import Iterator +from collections.abc import Iterator import itertools from sage.structure.parent import Parent diff --git a/src/sage/combinat/subword_complex.py b/src/sage/combinat/subword_complex.py index ff77970776e..8dcbd2d64cd 100644 --- a/src/sage/combinat/subword_complex.py +++ b/src/sage/combinat/subword_complex.py @@ -158,7 +158,7 @@ class SubwordComplexFacet(Simplex, Element): def __init__(self, parent, positions, facet_test=True): r""" - Initializes a facet of the subword complex ``parent``. + Initialize a facet of the subword complex ``parent``. EXAMPLES:: @@ -400,7 +400,7 @@ def kappa_preimage(self): N = len(W.long_element(as_word=True)) root_conf = self._root_configuration_indices() return [~w for w in W - if all(w.action_on_root_indices(i, side="left") < N + if all(w.action_on_root_indices(i, side='left') < N for i in root_conf)] def is_vertex(self): @@ -525,7 +525,7 @@ def extended_weight_configuration(self, coefficients=None): INPUT: - - coefficients -- (optional) a list of coefficients used to + - ``coefficients`` -- (optional) a list of coefficients used to scale the fundamental weights .. SEEALSO:: @@ -654,7 +654,7 @@ def brick_vector(self, coefficients=None): INPUT: - - coefficients -- (optional) a list of coefficients used to + - ``coefficients`` -- (optional) a list of coefficients used to scale the fundamental weights .. SEEALSO:: @@ -695,9 +695,9 @@ def flip(self, i, return_position=False): INPUT: - - ``i`` -- position in the word `Q` (integer). - - ``return_position`` -- boolean (default: ``False``) tells - whether the new position should be returned as well. + - ``i`` -- integer; position in the word `Q` + - ``return_position`` -- boolean (default: ``False``); tells + whether the new position should be returned as well OUTPUT: @@ -751,20 +751,20 @@ def plot(self, list_colors=None, labels=[], thickness=3, fontsize=14, INPUT: - - ``list_colors`` -- list (default: ``[]``) to change the colors - of the pseudolines. - - ``labels`` -- list (default: ``[]``) to change the labels - of the pseudolines. - - ``thickness`` -- integer (default: ``3``) for the thickness - of the pseudolines. - - ``fontsize`` -- integer (default: ``14``) for the size - of the font used for labels. + - ``list_colors`` -- list (default: ``[]``); to change the colors + of the pseudolines + - ``labels`` -- list (default: ``[]``); to change the labels + of the pseudolines + - ``thickness`` -- integer (default: 3); for the thickness + of the pseudolines + - ``fontsize`` -- integer (default: 14); for the size + of the font used for labels - ``shift`` -- couple of coordinates (default: ``(0,0)``) - to change the origin. - - ``compact`` -- boolean (default: ``False``) to require - a more compact representation. - - ``roots`` -- boolean (default: ``True``) to print - the extended root configuration. + to change the origin + - ``compact`` -- boolean (default: ``False``); to require + a more compact representation + - ``roots`` -- boolean (default: ``True``); whether to print + the extended root configuration EXAMPLES:: @@ -956,11 +956,11 @@ def plot(self, list_colors=None, labels=[], thickness=3, fontsize=14, if type in ['B', 'C']: L += line(pseudolines_type_B[pseudoline], color=list_colors[pseudoline], - thickness=thickness, linestyle="--") + thickness=thickness, linestyle='--') for root_label in root_labels: L += text(root_label[0], root_label[1], rgbcolor=[0, 0, 0], - fontsize=fontsize, vertical_alignment="center", - horizontal_alignment="right") + fontsize=fontsize, vertical_alignment='center', + horizontal_alignment='right') if len(labels) < last + 1: labels = list(range(1, last + 2)) for pseudoline_label in pseudoline_labels: @@ -968,15 +968,15 @@ def plot(self, list_colors=None, labels=[], thickness=3, fontsize=14, color=list_colors[pseudoline_label[0]], fontsize=fontsize, vertical_alignment=pseudoline_label[2], - horizontal_alignment="right") + horizontal_alignment='right') if labels is not False: for pseudoline in range(last): L += text(labels[pseudoline], (shift[0] + x_max + .1, shift[1] + permutation.inverse()(pseudoline + 1) - 1), color=list_colors[pseudoline], fontsize=fontsize, - vertical_alignment="center", - horizontal_alignment="left") + vertical_alignment='center', + horizontal_alignment='left') L.axes(False) return L @@ -1063,7 +1063,7 @@ class SubwordComplex(UniqueRepresentation, SimplicialComplex): # standard functions @staticmethod - def __classcall__(cls, Q, w, algorithm="inductive"): + def __classcall__(cls, Q, w, algorithm='inductive'): r""" Making the input hashable. @@ -1085,17 +1085,17 @@ def __classcall__(cls, Q, w, algorithm="inductive"): Q = tuple(Q) return super().__classcall__(cls, Q, w, algorithm=algorithm) - def __init__(self, Q, w, algorithm="inductive"): + def __init__(self, Q, w, algorithm='inductive'): r""" Initialize the subword complex `\mathcal{SC}(Q,w)`. INPUT: - - ``Q`` -- word on the simple generators of the Coxeter group. - - ``w`` -- element of the Coxeter group. - - ``algorithm`` -- (default: ``"inductive"``) choice of the + - ``Q`` -- word on the simple generators of the Coxeter group + - ``w`` -- element of the Coxeter group + - ``algorithm`` -- (default: ``'inductive'``) choice of the algorithm to generate the subword complex. Options are - ``"inductive"`` or ``"greedy"``. The second option is + ``'inductive'`` or ``'greedy'``. The second option is recommended when `|Q|` is closed to `\ell(w) + \mathrm{rank}(W)`. EXAMPLES:: @@ -1201,13 +1201,11 @@ def __call__(self, F, facet_test=True): INPUT: - - ``F`` -- an iterable of positions. - - ``facet_test`` -- boolean (default: ``True``) tells whether or - not the facet ``F`` should be tested before creation. + - ``F`` -- an iterable of positions + - ``facet_test`` -- boolean (default: ``True``); whether or + not the facet ``F`` should be tested before creation - OUTPUT: - - the facet of ``self`` at positions given by ``F``. + OUTPUT: the facet of ``self`` at positions given by ``F`` EXAMPLES:: @@ -1229,7 +1227,7 @@ def __call__(self, F, facet_test=True): def __contains__(self, F): r""" - Tests if ``self`` contains a given iterable ``F``. + Test if ``self`` contains a given iterable ``F``. EXAMPLES:: @@ -1417,7 +1415,7 @@ def __iter__(self): """ return iter(self.facets()) - def greedy_facet(self, side="positive"): + def greedy_facet(self, side='positive'): r""" Return the negative (or positive) greedy facet of ``self``. @@ -1429,17 +1427,17 @@ def greedy_facet(self, side="positive"): sage: W = ReflectionGroup(['A',2]) sage: w = W.from_reduced_word([1,2,1]) sage: SC = SubwordComplex([1,2,1,2,1], w) - sage: SC.greedy_facet(side="positive") + sage: SC.greedy_facet(side='positive') (0, 1) - sage: SC.greedy_facet(side="negative") + sage: SC.greedy_facet(side='negative') (3, 4) sage: W = CoxeterGroup(['A',2]) sage: w = W.from_reduced_word([1,2,1]) sage: SC = SubwordComplex([1,2,1,2,1], w) - sage: SC.greedy_facet(side="positive") + sage: SC.greedy_facet(side='positive') (0, 1) - sage: SC.greedy_facet(side="negative") + sage: SC.greedy_facet(side='negative') (3, 4) """ return self.element_class(self, _greedy_facet(self.word(), @@ -1567,7 +1565,7 @@ def is_root_independent(self): True """ from sage.matrix.constructor import matrix - M = matrix(self.greedy_facet(side="negative").root_configuration()) + M = matrix(self.greedy_facet(side='negative').root_configuration()) return M.rank() == max(M.ncols(), M.nrows()) @cached_method @@ -1683,7 +1681,7 @@ def brick_vectors(self, coefficients=None): INPUT: - - coefficients -- (optional) a list of coefficients used to + - ``coefficients`` -- (optional) a list of coefficients used to scale the fundamental weights .. SEEALSO:: @@ -1715,7 +1713,7 @@ def minkowski_summand(self, i): INPUT: - `i` -- an integer defining a position in the word `Q` + - ``i`` -- an integer defining a position in the word `Q` EXAMPLES:: @@ -1748,7 +1746,7 @@ def brick_polytope(self, coefficients=None): INPUT: - - coefficients -- (optional) a list of coefficients used to + - ``coefficients`` -- (optional) a list of coefficients used to scale the fundamental weights .. SEEALSO:: @@ -1827,12 +1825,10 @@ def cover_relations(self, label=False): INPUT: - - label -- boolean (default ``False``) whether or not to label + - ``label`` -- boolean (default: ``False``); whether or not to label the cover relations by the position of flip - OUTPUT: - - a list of pairs of facets + OUTPUT: list of pairs of facets EXAMPLES:: @@ -1855,7 +1851,7 @@ def cover_relations(self, label=False): ((2, 3), (3, 4))] """ N = len(self.group().long_element(as_word=True)) - F = self.greedy_facet(side="positive") + F = self.greedy_facet(side='positive') Fs = {F} seen = {F} covers = [] @@ -1878,9 +1874,7 @@ def increasing_flip_graph(self, label=True): """ Return the increasing flip graph of the subword complex. - OUTPUT: - - a directed graph + OUTPUT: a directed graph EXAMPLES:: @@ -1905,9 +1899,7 @@ def interval(self, I, J) -> set: - I, J -- two facets - OUTPUT: - - a set of facets + OUTPUT: a set of facets EXAMPLES:: @@ -1932,9 +1924,7 @@ def increasing_flip_poset(self): """ Return the increasing flip poset of the subword complex. - OUTPUT: - - a poset + OUTPUT: a poset EXAMPLES:: @@ -1956,7 +1946,7 @@ def increasing_flip_poset(self): return Poset(((), cov), facade=True) -def _greedy_facet(Q, w, side="negative", n=None, pos=0, l=None, elems=[]): +def _greedy_facet(Q, w, side='negative', n=None, pos=0, l=None, elems=[]): r""" Return the (positive or negative) *greedy facet* of the subword complex `SC(Q, w)`. @@ -1965,15 +1955,13 @@ def _greedy_facet(Q, w, side="negative", n=None, pos=0, l=None, elems=[]): - ``Q`` -- a word - ``w`` -- an element in the Coxeter group - - ``side`` -- optional, either ``'negative'`` (default) or ``'positive'`` - - ``n`` -- an integer (default: the length of `Q`) - - ``pos`` -- an integer (default: 0) - - ``l`` -- an integer (default: the length of `w`) - - ``elems`` -- a list (optional) + - ``side`` -- string; either ``'negative'`` (default) or ``'positive'`` + - ``n`` -- integer (default: the length of `Q`) + - ``pos`` -- integer (default: 0) + - ``l`` -- integer (default: the length of `w`) + - ``elems`` -- list (optional) - OUTPUT: - - - a set + OUTPUT: a set EXAMPLES:: @@ -2038,9 +2026,7 @@ def _extended_root_configuration_indices(W, Q, F): - ``Q`` -- a word representing an element of `W` - ``F`` -- a facet of the subword complex - OUTPUT: - - a list of root indices + OUTPUT: list of root indices EXAMPLES:: @@ -2067,7 +2053,7 @@ def _extended_root_configuration_indices(W, Q, F): pi = W.one() for i, wi in enumerate(Q): V_roots.append(pi.action_on_root_indices(W.simple_root_index(wi), - side="left")) + side='left')) if i not in F: pi = pi.apply_simple_reflection_right(wi) return V_roots @@ -2080,9 +2066,7 @@ def _greedy_flip_algorithm(Q, w): - ``Q`` -- a word in a Coxeter group `W` - ``w`` -- an element of `W` - OUTPUT: - - a pair: the list of facets and the list of extended root conf. indices + OUTPUT: a pair: the list of facets and the list of extended root conf. indices EXAMPLES:: @@ -2112,7 +2096,7 @@ def _greedy_flip_algorithm(Q, w): [0, 2, 1, 0, 5]]) """ W = w.parent() - F = _greedy_facet(Q, w, side="positive") + F = _greedy_facet(Q, w, side='positive') R = _extended_root_configuration_indices(W, Q, F) facet_list = [F] extended_root_conf_indices_list = [R] @@ -2122,7 +2106,7 @@ def _greedy_flip_algorithm(Q, w): has_new_child = False for i in sorted(F): if (not has_new_child) and (i >= next_index): - j = _flip_c(W, F, R, i, side="positive") + j = _flip_c(W, F, R, i, side='positive') if j != i: flip_to_ancestors.append(j) next_index = i + 1 @@ -2132,6 +2116,6 @@ def _greedy_flip_algorithm(Q, w): if not has_new_child: i = flip_to_ancestors.pop() if i != -1: - j = _flip_c(W, F, R, i, side="negative") + j = _flip_c(W, F, R, i, side='negative') next_index = j + 1 return facet_list, extended_root_conf_indices_list diff --git a/src/sage/combinat/subword_complex_c.pyx b/src/sage/combinat/subword_complex_c.pyx index 5b155efda75..17d18c50c77 100644 --- a/src/sage/combinat/subword_complex_c.pyx +++ b/src/sage/combinat/subword_complex_c.pyx @@ -1,7 +1,7 @@ # sage.doctest: needs sage.modules cpdef int _flip_c(W, set positions, list extended_root_conf_indices, - int i, side="both") noexcept: + int i, side='both') noexcept: r""" Flip a facet. @@ -11,11 +11,9 @@ cpdef int _flip_c(W, set positions, list extended_root_conf_indices, - ``positions`` -- the positions of the elements of the facet - ``extended_root_conf_indices`` -- also attached to the facet ? - ``i`` -- the position where to flip - - ``side`` -- optional, can be ``'positive'``, ``'negative'`` or ``'both'`` (default) + - ``side`` -- string; ``'positive'``, ``'negative'``, or ``'both'`` (default) - OUTPUT: - - the new position `j` that has replaced `i` + OUTPUT: the new position `j` that has replaced `i` EXAMPLES:: @@ -59,7 +57,7 @@ cpdef int _flip_c(W, set positions, list extended_root_conf_indices, if j != i: t = R[min(r, r_minus)] for k in range(min(i, j) + 1, max(i, j) + 1): - extended_root_conf_indices[k] = t.action_on_root_indices(extended_root_conf_indices[k], side="left") + extended_root_conf_indices[k] = t.action_on_root_indices(extended_root_conf_indices[k], side='left') return j diff --git a/src/sage/combinat/super_tableau.py b/src/sage/combinat/super_tableau.py index ffcdb0fc374..280654fcc5e 100644 --- a/src/sage/combinat/super_tableau.py +++ b/src/sage/combinat/super_tableau.py @@ -184,13 +184,13 @@ def check(self): Traceback (most recent call last): ... ValueError: the entries of a semistandard super tableau must be - non-negative primed integers + nonnegative primed integers """ super().check() for row in self: if not all(isinstance(c, PrimedEntry) and c > 0 for c in row): raise ValueError("the entries of a semistandard super tableau" - " must be non-negative primed integers") + " must be nonnegative primed integers") if any(row[c] > row[c + 1] for c in range(len(row) - 1)): raise ValueError("the entries in each row of a semistandard" " super tableau must be weakly increasing") @@ -419,7 +419,7 @@ class SemistandardSuperTableaux_all(SemistandardSuperTableaux): def __init__(self): r""" - Initializes the class of all semistandard super tableaux. + Initialize the class of all semistandard super tableaux. TESTS:: @@ -455,7 +455,7 @@ class StandardSuperTableaux(SemistandardSuperTableaux, Parent): INPUT: - - ``n`` -- a non-negative integer or a partition. + - ``n`` -- a nonnegative integer or a partition EXAMPLES:: @@ -519,12 +519,12 @@ def __classcall_private__(cls, n=None): sage: StandardSuperTableaux(-1) Traceback (most recent call last): ... - ValueError: the argument must be a non-negative integer or a + ValueError: the argument must be a nonnegative integer or a partition sage: StandardSuperTableaux([[1]]) Traceback (most recent call last): ... - ValueError: the argument must be a non-negative integer or a + ValueError: the argument must be a nonnegative integer or a partition """ from sage.combinat.partition import _Partitions @@ -541,7 +541,7 @@ def __classcall_private__(cls, n=None): "partitions is not implemented yet") if not isinstance(n, (int, Integer)) or n < 0: - raise ValueError("the argument must be a non-negative integer" + raise ValueError("the argument must be a nonnegative integer" " or a partition") return StandardSuperTableaux_size(n) @@ -601,7 +601,7 @@ class StandardSuperTableaux_all(StandardSuperTableaux, def __init__(self): r""" - Initializes the class of all standard super tableaux. + Initialize the class of all standard super tableaux. TESTS:: @@ -654,7 +654,7 @@ class StandardSuperTableaux_size(StandardSuperTableaux, def __init__(self, n): r""" - Initializes the class of all standard super tableaux of size ``n``. + Initialize the class of all standard super tableaux of size ``n``. TESTS:: @@ -735,7 +735,7 @@ class StandardSuperTableaux_shape(StandardSuperTableaux): def __init__(self, p): r""" - Initializes the class of all standard super tableaux of a given shape. + Initialize the class of all standard super tableaux of a given shape. TESTS:: diff --git a/src/sage/combinat/superpartition.py b/src/sage/combinat/superpartition.py index e16e87fa9f0..b270c17d68b 100644 --- a/src/sage/combinat/superpartition.py +++ b/src/sage/combinat/superpartition.py @@ -121,7 +121,7 @@ class SuperPartition(ClonableArray, @staticmethod def __classcall_private__(cls, lst): r""" - Construct a superpartition in the correct parent + Construct a superpartition in the correct parent. EXAMPLES:: @@ -323,7 +323,7 @@ def to_composition(self) -> Composition: sage: SuperPartition([[2,1,0],[3,3]]).to_composition() [2, 1, 0, 3, 3] sage: SuperPartition([[2,1,0],[3,3]]).to_composition().parent() - Compositions of non-negative integers + Compositions of nonnegative integers """ return Composition(self[0] + self[1]) @@ -332,9 +332,7 @@ def to_partition(self) -> Partition: Concatenate and sort the antisymmetric and symmetric parts to a partition. - OUTPUT: - - - a partition + OUTPUT: a partition EXAMPLES:: @@ -351,9 +349,7 @@ def antisymmetric_part(self) -> list: r""" The antisymmetric part as a list of strictly decreasing integers. - OUTPUT: - - - a list + OUTPUT: list EXAMPLES:: @@ -370,9 +366,7 @@ def symmetric_part(self) -> list: r""" The symmetric part as a list of weakly decreasing integers. - OUTPUT: - - - a list + OUTPUT: list EXAMPLES:: @@ -392,9 +386,7 @@ def bosonic_degree(self) -> int: The *bosonic degree* is the sum of the sizes of the antisymmetric and symmetric parts. - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -413,9 +405,7 @@ def fermionic_degree(self) -> int: The *fermionic degree* is the length of the antisymmetric part. - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -433,9 +423,7 @@ def bi_degree(self) -> tuple: Return the bidegree of ``self``, which is a pair consisting of the bosonic and fermionic degree. - OUTPUT: - - - a tuple of two integers + OUTPUT: a tuple of two integers EXAMPLES:: @@ -451,9 +439,7 @@ def length(self) -> int: Return the length of ``self``, which is the sum of the lengths of the antisymmetric and symmetric part. - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -468,9 +454,7 @@ def bosonic_length(self) -> int: r""" Return the length of the partition of the symmetric part. - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -485,9 +469,7 @@ def shape_circled_diagram(self) -> Partition: r""" A concatenated partition with an extra cell for each antisymmetric part - OUTPUT: - - - a partition + OUTPUT: a partition EXAMPLES:: @@ -512,11 +494,9 @@ def from_circled_diagram(shape, corners) -> SuperPartition: INPUT: - ``shape`` -- a partition or list of integers - - ``corners`` -- a list of removable cells of ``shape`` - - OUTPUT: + - ``corners`` -- list of removable cells of ``shape`` - - a :class:`SuperPartition` + OUTPUT: a :class:`SuperPartition` EXAMPLES:: @@ -541,9 +521,7 @@ def to_circled_diagram(self) -> list: and a list of removable cells of the partition indicating the location of the circled cells - OUTPUT: - - - a list consisting of a partition and a list of pairs of integers + OUTPUT: list consisting of a partition and a list of pairs of integers EXAMPLES:: @@ -566,9 +544,7 @@ def conjugate(self) -> SuperPartition: The *conjugate* of a super partition is defined by conjugating the circled diagram. - OUTPUT: - - - a :class:`SuperPartition` + OUTPUT: a :class:`SuperPartition` EXAMPLES:: @@ -588,9 +564,7 @@ def zee(self) -> Integer: Return the centralizer size of a permutation of cycle type symmetric part of ``self``. - OUTPUT: - - - a positive integer + OUTPUT: a positive integer EXAMPLES:: @@ -608,9 +582,7 @@ def sign(self) -> int: Return the sign of a permutation of cycle type the symmetric part of ``self``. - OUTPUT: - - - either `1` or `-1` + OUTPUT: either `1` or `-1` EXAMPLES:: @@ -659,9 +631,7 @@ def add_horizontal_border_strip_star(self, h) -> list: - ``h`` -- number of cells in the horizontal strip - OUTPUT: - - - a list of super partitions + OUTPUT: list of super partitions EXAMPLES:: @@ -707,9 +677,7 @@ def add_horizontal_border_strip_star_bar(self, h) -> list: - ``h`` -- number of cells in the horizontal strip - OUTPUT: - - - a list of super partitions + OUTPUT: list of super partitions EXAMPLES:: @@ -783,7 +751,7 @@ class SuperPartitions(UniqueRepresentation, Parent): INPUT: - - ``n`` -- an integer (optional: default ``None``) + - ``n`` -- integer (default: ``None``) - ``m`` -- if ``n`` is specified, an integer (optional: default ``None``) Super partitions are the indexing set for symmetric functions @@ -901,7 +869,7 @@ class options(GlobalOptions): """, NAME = 'SuperPartition' module = 'sage.combinat.superpartition' - display = dict(default="default", + display = dict(default='default', description="Specifies how the super partitions should " "be printed", values=dict(list="the super partitions are displayed in " diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index 1706f848f10..47820fc23a5 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -247,7 +247,7 @@ def __init__(self, R, W, category): sage: S = SymmetricGroup(4) sage: SGA = S.algebra(QQ) - sage: TestSuite(SGA).run(skip="_test_cellular") + sage: TestSuite(SGA).run(skip='_test_cellular') sage: SGA._test_cellular() # long time Checking that coercion works between equivalent indexing sets:: @@ -1043,10 +1043,8 @@ def central_orthogonal_idempotents(self): - :meth:`central_orthogonal_idempotent` """ - out = [] - for key in sorted(self._blocks_dictionary, reverse=True): - out.append(self.central_orthogonal_idempotent(key)) - return out + return [self.central_orthogonal_idempotent(key) + for key in sorted(self._blocks_dictionary, reverse=True)] def central_orthogonal_idempotent(self, la, block=True): r""" @@ -1986,7 +1984,7 @@ def seminormal_basis(self, mult='l2r'): INPUT: - - ``mult`` -- string (default: ``'l2r'``). If set to ``'r2l'``, + - ``mult`` -- string (default: ``'l2r'``); if set to ``'r2l'``, this causes the method to return the list of the antipodes (:meth:`antipode`) of all `\epsilon(T, S)` instead of the `\epsilon(T, S)` themselves. @@ -2016,9 +2014,9 @@ def seminormal_basis(self, mult='l2r'): basis = [] for part in Partitions_n(self.n): stp = StandardTableaux_shape(part) - for t1 in stp: - for t2 in stp: - basis.append(self.epsilon_ik(t1, t2, mult=mult)) + basis.extend(self.epsilon_ik(t1, t2, mult=mult) + for t1 in stp + for t2 in stp) return basis def dft(self, form=None, mult='l2r'): @@ -2032,7 +2030,7 @@ def dft(self, form=None, mult='l2r'): INPUT: - - ``mult`` -- string (default: `l2r`). If set to `r2l`, + - ``mult`` -- string (default: `l2r`); if set to `r2l`, this causes the method to use the antipodes (:meth:`antipode`) of the seminormal basis instead of the seminormal basis. @@ -2076,7 +2074,7 @@ def _dft_seminormal(self, mult='l2r'): INPUT: - - ``mult`` -- string (default: `l2r`). If set to `r2l`, + - ``mult`` -- string (default: `l2r`); if set to `r2l`, this causes the method to use the antipodes (:meth:`antipode`) of the seminormal basis instead of the seminormal basis. @@ -2133,11 +2131,11 @@ def epsilon_ik(self, itab, ktab, star=0, mult='l2r'): INPUT: - - ``itab``, ``ktab`` -- two standard tableaux of size `n`. + - ``itab``, ``ktab`` -- two standard tableaux of size `n` - - ``star`` -- integer (default: `0`). + - ``star`` -- integer (default: `0`) - - ``mult`` -- string (default: `l2r`). If set to `r2l`, + - ``mult`` -- string (default: `l2r`); if set to `r2l`, this causes the method to return the antipode (:meth:`antipode`) of `\epsilon(I, K)` instead of `\epsilon(I, K)` itself. @@ -2507,9 +2505,9 @@ def epsilon_ik(itab, ktab, star=0): INPUT: - - ``itab``, ``ktab`` -- two standard tableaux of same size. + - ``itab``, ``ktab`` -- two standard tableaux of same size - - ``star`` -- integer (default: `0`). + - ``star`` -- integer (default: `0`) OUTPUT: @@ -2647,7 +2645,7 @@ def kappa(alpha): INPUT: - - ``alpha`` -- integer partition (can be encoded as a list). + - ``alpha`` -- integer partition (can be encoded as a list) OUTPUT: @@ -2684,15 +2682,15 @@ def a(tableau, star=0, base_ring=QQ): INPUT: - ``tableau`` -- Young tableau which contains every integer - from `1` to its size precisely once. + from `1` to its size precisely once - - ``star`` -- nonnegative integer (default: `0`). When this + - ``star`` -- nonnegative integer (default: `0`); when this optional variable is set, the method computes not the row projection operator of ``tableau``, but the row projection operator of the restriction of ``tableau`` to the entries ``1, 2, ..., tableau.size() - star`` instead. - - ``base_ring`` -- commutative ring (default: ``QQ``). When this + - ``base_ring`` -- commutative ring (default: ``QQ``); when this optional variable is set, the row projection operator is computed over a user-determined base ring instead of `\QQ`. (Note that symmetric group algebras currently don't preserve @@ -2757,7 +2755,7 @@ def b(tableau, star=0, base_ring=QQ): INPUT: - ``tableau`` -- Young tableau which contains every integer - from `1` to its size precisely once. + from `1` to its size precisely once - ``star`` -- nonnegative integer (default: `0`). When this optional variable is set, the method computes not the column @@ -3242,7 +3240,7 @@ def _to_sga(self, ind): from sage.combinat.rsk import RSK_inverse S = ind[1] T = ind[2] - w = RSK_inverse(T, S, output="permutation") + w = RSK_inverse(T, S, output='permutation') return self._algebra.kazhdan_lusztig_basis_element(w) @@ -3435,7 +3433,7 @@ def __init__(self, R, n, q=None): """ HeckeAlgebraSymmetricGroup_generic.__init__(self, R, n, q) self._name += " on the T basis" - self.print_options(prefix="T") + self.print_options(prefix='T') def t_action_on_basis(self, perm, i): r""" diff --git a/src/sage/combinat/symmetric_group_representations.py b/src/sage/combinat/symmetric_group_representations.py index ae74e707645..f64e68fecad 100644 --- a/src/sage/combinat/symmetric_group_representations.py +++ b/src/sage/combinat/symmetric_group_representations.py @@ -45,14 +45,14 @@ from sage.sets.finite_enumerated_set import FiniteEnumeratedSets lazy_import("sage.combinat.yang_baxter_graph", "YangBaxterGraph_partition") -lazy_import("sage.groups.perm_gps.constructor", "PermutationGroupElement", as_="PermutationConstructor") +lazy_import("sage.groups.perm_gps.constructor", "PermutationGroupElement", as_='PermutationConstructor') lazy_import("sage.symbolic.ring", "SR") # #### Constructor function ################################################ -def SymmetricGroupRepresentation(partition, implementation="specht", +def SymmetricGroupRepresentation(partition, implementation='specht', ring=None, cache_matrices=True): r""" The irreducible representation of the symmetric group corresponding to @@ -62,15 +62,15 @@ def SymmetricGroupRepresentation(partition, implementation="specht", - ``partition`` -- a partition of a positive integer - - ``implementation`` -- string (default: ``"specht"``), one of: + - ``implementation`` -- string (default: ``'specht'``); one of: - * ``"seminormal"`` -- for Young's seminormal representation - * ``"orthogonal"`` -- for Young's orthogonal representation - * ``"specht"`` -- for Specht's representation + * ``'seminormal'`` -- for Young's seminormal representation + * ``'orthogonal'`` -- for Young's orthogonal representation + * ``'specht'`` -- for Specht's representation - ``ring`` -- the ring over which the representation is defined - - ``cache_matrices`` -- boolean (default: ``True``) if ``True``, then any + - ``cache_matrices`` -- boolean (default: ``True``); if ``True``, then any representation matrices that are computed are cached EXAMPLES: @@ -179,7 +179,7 @@ def SymmetricGroupRepresentation(partition, implementation="specht", return Rep(partition) -def SymmetricGroupRepresentations(n, implementation="specht", ring=None, +def SymmetricGroupRepresentations(n, implementation='specht', ring=None, cache_matrices=True): r""" Irreducible representations of the symmetric group. @@ -188,15 +188,15 @@ def SymmetricGroupRepresentations(n, implementation="specht", ring=None, - ``n`` -- positive integer - - ``implementation`` -- string (default: ``"specht"``), one of: + - ``implementation`` -- string (default: ``'specht'``); one of: - * ``"seminormal"`` -- for Young's seminormal representation - * ``"orthogonal"`` -- for Young's orthogonal representation - * ``"specht"`` -- for Specht's representation + * ``'seminormal'`` -- for Young's seminormal representation + * ``'orthogonal'`` -- for Young's orthogonal representation + * ``'specht'`` -- for Specht's representation - ``ring`` -- the ring over which the representation is defined - - ``cache_matrices`` -- boolean (default: ``True``) if ``True``, then any + - ``cache_matrices`` -- boolean (default: ``True``); if ``True``, then any representation matrices that are computed are cached EXAMPLES: @@ -1024,6 +1024,8 @@ def partition_to_vector_of_contents(partition, reverse=False): from sage.rings.quotient_ring import QuotientRing_generic from sage.combinat.specht_module import SymmetricGroupRepresentation as SymmetricGroupRepresentation_mixin + + class GarsiaProcesiModule(UniqueRepresentation, QuotientRing_generic, SymmetricGroupRepresentation_mixin): r""" A Garsia-Procesi module. diff --git a/src/sage/combinat/t_sequences.py b/src/sage/combinat/t_sequences.py index 0376ac8f262..c78a451f67c 100644 --- a/src/sage/combinat/t_sequences.py +++ b/src/sage/combinat/t_sequences.py @@ -18,8 +18,8 @@ * the last element of `X` is -1 * the last element of `U` is 1 -The nonperiodic autocorrelation of a familiy of sequences `X=\{A_1, A_2, ..., A_n\}` is defined as -(see Definition 7.2 of [Seb2017]_): +The nonperiodic autocorrelation of a familiy of sequences +`X=\{A_1, A_2, ..., A_n\}` is defined as (see Definition 7.2 of [Seb2017]_): .. MATH:: @@ -55,10 +55,11 @@ def _nonperiodic_autocorrelation(sequences, j): INPUT: - - ``sequences`` -- either a single sequence or a list of sequences for which we want - to compute the nonperiodic autocorrelation. + - ``sequences`` -- either a single sequence or a list of sequences for + which we want to compute the nonperiodic autocorrelation - - ``j`` -- integer, the parameter `j` used when calculating the nonperiodic autocorrelation. + - ``j`` -- integer; the parameter `j` used when calculating the nonperiodic + autocorrelation """ if not isinstance(sequences[0], list): sequences = [sequences] @@ -80,10 +81,10 @@ def is_skew(seq, verbose=False): INPUT: - - ``seq`` -- the sequence that should be checked. + - ``seq`` -- the sequence that should be checked - - ``verbose`` -- a boolean (default false). If true the function will be verbose - when the sequences do not satisfy the contraints. + - ``verbose`` -- boolean (default: ``False``); if ``True`` the function + will be verbose when the sequences do not satisfy the contraints EXAMPLES:: @@ -126,10 +127,10 @@ def is_symmetric(seq, verbose=False) -> bool: INPUT: - - ``seq`` -- the sequence that should be checked. + - ``seq`` -- the sequence that should be checked - - ``verbose`` -- a boolean (default false). If true the function will be verbose - when the sequences do not satisfy the contraints. + - ``verbose`` -- boolean (default: ``False``); if ``True`` the function will be + verbose when the sequences do not satisfy the contraints EXAMPLES:: @@ -176,10 +177,10 @@ def is_T_sequences_set(sequences, verbose=False): INPUT: - - ``sequences`` -- a list of four sequences. + - ``sequences`` -- list of four sequences - - ``verbose`` -- a boolean (default false). If true the function will be verbose - when the sequences do not satisfy the contraints. + - ``verbose`` -- boolean (default: ``False``); if ``True`` the function will be + verbose when the sequences do not satisfy the contraints EXAMPLES:: @@ -189,7 +190,8 @@ def is_T_sequences_set(sequences, verbose=False): True sage: seqs = [[1, 1, 0, 1, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, -1], [0, 0, 0, 0, 0]] sage: is_T_sequences_set(seqs, verbose=True) - There should be exactly a nonzero element at every index, found 2 such elemnents at index 3 + There should be exactly a nonzero element at every index, found 2 such + elements at index 3 False @@ -226,7 +228,7 @@ def is_T_sequences_set(sequences, verbose=False): tot += abs(seq[i]) if tot != 1: if verbose: - print(f"There should be exactly a nonzero element at every index, found {tot} such elemnents at index {i}") + print(f"There should be exactly a nonzero element at every index, found {tot} such elements at index {i}") return False for j in range(1, t): @@ -247,10 +249,10 @@ def turyn_sequences_smallcases(l, existence=False): INPUT: - - ``l`` -- integer, the length of the Turyn sequences. + - ``l`` -- integer; the length of the Turyn sequences - - ``existence`` -- boolean (default: ``False``). If true, only return whether the - Turyn sequences are available for the given length. + - ``existence`` -- boolean (default: ``False``); if ``True``, only return + whether the Turyn sequences are available for the given length EXAMPLES: @@ -315,9 +317,11 @@ def T_sequences_construction_from_base_sequences(base_sequences, check=True): INPUT: - - ``base_sequences`` -- the base sequences that should be used to construct the T-sequences. + - ``base_sequences`` -- the base sequences that should be used to construct + the T-sequences - - ``check`` -- boolean, if true (default) checks that the sequences created are T-sequences before returning them. + - ``check`` -- boolean (default: ``True``); check that the sequences + created are T-sequences before returning them EXAMPLES:: @@ -394,9 +398,11 @@ def T_sequences_construction_from_turyn_sequences(turyn_sequences, check=True): INPUT: - - ``turyn_sequences`` -- the Turyn sequences that should be used to construct the T-sequences . + - ``turyn_sequences`` -- the Turyn sequences that should be used to + construct the T-sequences - - ``check`` -- boolean, if true (default) checks that the sequences created are T-sequences before returning them. + - ``check`` -- boolean (default: ``True``); check that the sequences + created are T-sequences before returning them EXAMPLES:: @@ -463,12 +469,13 @@ def T_sequences_smallcases(t, existence=False, check=True): INPUT: - - ``t`` -- integer, the length of the T-sequences to construct. + - ``t`` -- integer; the length of the T-sequences to construct - - ``existence`` -- boolean (default false). If true, this method only returns whether a T-sequences of - the given size can be constructed. + - ``existence`` -- boolean (default: ``False``); if ``True``, this method + only returns whether a T-sequences of the given size can be constructed - - ``check`` -- boolean, if true (default) check that the sequences are T-sequences before returning them. + - ``check`` -- boolean (default: ``True``); check that the sequences are + T-sequences before returning them EXAMPLES: @@ -553,10 +560,13 @@ def T_sequences_smallcases(t, existence=False, check=True): def base_sequences_construction(turyn_type_seqs, check=True): - r"""Construct base sequences of length `2n-1, 2n-1, n, n` from Turyn type sequences of length `n,n,n,n-1`. + r""" + Construct base sequences of length `2n-1, 2n-1, n, n` from Turyn type + sequences of length `n,n,n,n-1`. - Given Turyn type sequences `X, Y, Z, W` of length `n,n,n,n-1`, Theorem 1 of [KTR2005]_ shows that the - following are base sequences of length `2n-1, 2n-1, n, n`: + Given Turyn type sequences `X, Y, Z, W` of length `n,n,n,n-1`, Theorem 1 of + [KTR2005]_ shows that the following are base sequences of length + `2n-1, 2n-1, n, n`: .. MATH:: @@ -569,12 +579,13 @@ def base_sequences_construction(turyn_type_seqs, check=True): INPUT: - - ``turyn_type_seqs`` -- The list of 4 Turyn type sequences that should be used to construct the base sequences. + - ``turyn_type_seqs`` -- the list of 4 Turyn type sequences that should be + used to construct the base sequences - - ``check`` -- boolean, if True (default) check that the resulting sequences are base sequences - before returning them. + - ``check`` -- boolean (default: ``True``); check that the resulting + sequences are base sequences before returning them - OUTPUT: A list containing the four base sequences. + OUTPUT: list containing the four base sequences EXAMPLES:: @@ -618,8 +629,8 @@ def base_sequences_construction(turyn_type_seqs, check=True): def is_base_sequences_tuple(base_sequences, verbose=False): r"""Check if the given sequences are base sequences. - Four (-1, +1) sequences `A, B, C, D` of length `n+p, n+p, n, n` are called base sequences if - for all `j \ge 1`: + Four (-1, +1) sequences `A, B, C, D` of length `n+p, n+p, n, n` are called + base sequences if for all `j \ge 1`: .. MATH:: @@ -629,10 +640,10 @@ def is_base_sequences_tuple(base_sequences, verbose=False): INPUT: - - ``base_sequences`` -- The list of 4 sequences that should be checked. + - ``base_sequences`` -- the list of 4 sequences that should be checked - - ``verbose`` -- a boolean (default false). If true the function will be verbose - when the sequences do not satisfy the contraints. + - ``verbose`` -- boolean (default: ``False``); if ``True`` the function + will be verbose when the sequences do not satisfy the contraints EXAMPLES:: @@ -704,10 +715,10 @@ def turyn_type_sequences_smallcases(n, existence=False): INPUT: - - ``n`` -- integer, the length of the Turyn type sequences. + - ``n`` -- integer; the length of the Turyn type sequences - - ``existence`` -- boolean (default: ``False``). If true, only return whether the - Turyn type sequences are available for the given length. + - ``existence`` -- boolean (default: ``False``); if ``True``, only return + whether the Turyn type sequences are available for the given length EXAMPLES: @@ -734,12 +745,14 @@ def turyn_type_sequences_smallcases(n, existence=False): ALGORITHM: The Turyn type sequences are stored in hexadecimal format. - Given `n` hexadecimal digits `h_1, h_2,...,h_n`, it is possible to get the Turyn type sequences - by converting each `h_i` (`1 \le i \le n-1`) into a four digits binary number. Then, the j-th binary digit is - `0` if the i-th number in the j-th sequence is `1`, and it is `1` if the number in the sequence is -1. - - For the n-th digit, it should be converted to a 3 digits binary number, and then the same mapping - as before can be used (see also [BDKR2013]_). + Given `n` hexadecimal digits `h_1, h_2,...,h_n`, it is possible to get the + Turyn type sequences by converting each `h_i` (`1 \le i \le n-1`) into a + four digits binary number. Then, the `j`-th binary digit is `0` if the `i`-th + number in the `j`-th sequence is `1`, and it is `1` if the number in the + sequence is -1. + + For the `n`-th digit, it should be converted to a 3 digits binary number, and + then the same mapping as before can be used (see also [BDKR2013]_). """ def convertLists(hexstring): seqs = [Sequence([]), Sequence([]), Sequence([]), Sequence([])] @@ -790,30 +803,33 @@ def convertLists(hexstring): def base_sequences_smallcases(n, p, existence=False, check=True): r"""Construct base sequences of length `n+p, n+p, n, n` from available data. - The function uses the construction :func:`base_sequences_construction`, together with - Turyn type sequences from :func:`turyn_type_sequences_smallcases` to construct base sequences - with `p = n-1`. + The function uses the construction :func:`base_sequences_construction`, + together with Turyn type sequences from :func:`turyn_type_sequences_smallcases` + to construct base sequences with `p = n-1`. - Furthermore, this function uses also Turyn sequences (i.e. base sequences with `p=1`) from - :func:`turyn_sequences_smallcases`. + Furthermore, this function uses also Turyn sequences (i.e. base sequences + with `p=1`) from :func:`turyn_sequences_smallcases`. INPUT: - - ``n`` -- integer, the length of the last two base sequences. + - ``n`` -- integer; the length of the last two base sequences - - ``p`` -- integer, `n+p` will be the length of the first two base sequences. + - ``p`` -- integer; `n+p` will be the length of the first two base + sequences - - ``existence`` -- boolean (default: ``False``). If True, the function will only check whether the base - sequences can be constructed. + - ``existence`` -- boolean (default: ``False``); if ``True``, the function + will only check whether the base sequences can be constructed - - ``check`` -- boolean, if True (default) check that the resulting sequences are base sequences - before returning them. + - ``check`` -- boolean (default: ``True``); check that the resulting + sequences are base sequences before returning them OUTPUT: - If ``existence`` is ``False``, the function returns a list containing the four base sequences, or raises - an error if the base sequences cannot be constructed. If ``existence`` is ``True``, the function returns a - boolean, which is ``True`` if the base sequences can be constructed and ``False`` otherwise. + If ``existence`` is ``False``, the function returns a list containing the + four base sequences, or raises an error if the base sequences cannot be + constructed. If ``existence`` is ``True``, the function returns a boolean, + which is ``True`` if the base sequences can be constructed and ``False`` + otherwise. EXAMPLES:: diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 5540faeeb1d..80e3391b279 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -126,9 +126,7 @@ class Tableau(ClonableList, metaclass=InheritComparisonClasscallMetaclass): - ``t`` -- a Tableau, a list of iterables, or an empty list - OUTPUT: - - - A Tableau object constructed from ``t``. + OUTPUT: a Tableau object constructed from ``t`` A tableau is abstractly a mapping from the cells in a partition to arbitrary objects (called entries). It is often represented as a @@ -181,7 +179,6 @@ class Tableau(ClonableList, metaclass=InheritComparisonClasscallMetaclass): Traceback (most recent call last): ... ValueError: a tableau must be a list of iterables - """ @staticmethod def __classcall_private__(cls, t): @@ -279,9 +276,7 @@ def __richcmp__(self, other, op): - ``other`` -- the element that ``self`` is compared to - OUTPUT: - - A Boolean. + OUTPUT: boolean TESTS:: @@ -469,12 +464,12 @@ def _ascii_art_(self): [ 1 ] [ 1 3 1 2 2 ] [ 1 2 3, 2 , 3 , 3 ] - sage: Tableaux.options(ascii_art="compact") + sage: Tableaux.options(ascii_art='compact') sage: ascii_art(list(StandardTableaux(3))) [ |1| ] [ |1|3| |1|2| |2| ] [ |1|2|3|, |2| , |3| , |3| ] - sage: Tableaux.options(convention="french", ascii_art="table") + sage: Tableaux.options(convention='french', ascii_art='table') sage: ascii_art(list(StandardTableaux(3))) [ +---+ ] [ | 3 | ] @@ -483,12 +478,12 @@ def _ascii_art_(self): [ +---+---+---+ +---+---+ +---+---+ +---+ ] [ | 1 | 2 | 3 | | 1 | 3 | | 1 | 2 | | 1 | ] [ +---+---+---+, +---+---+, +---+---+, +---+ ] - sage: Tableaux.options(ascii_art="repr") + sage: Tableaux.options(ascii_art='repr') sage: ascii_art(list(StandardTableaux(3))) [ 3 ] [ 2 3 2 ] [ 1 2 3, 1 3, 1 2, 1 ] - sage: Tableaux.options(convention="russian", ascii_art="table") + sage: Tableaux.options(convention='russian', ascii_art='table') sage: ascii_art(list(StandardTableaux(3))) [ / \ / \ ] [ / 3 / \ 3 \ ] @@ -497,7 +492,7 @@ def _ascii_art_(self): [ / \ / \ / \ / \ / \ / \ / \ ] [ \ 1 / \ 1 / \ 1 / \ 1 / ] [ \ / , \ / , \ / , \ / ] - sage: Tableaux.options(ascii_art="repr") + sage: Tableaux.options(ascii_art='repr') sage: ascii_art(list(StandardTableaux(3))) [ 3 3 ] [ 2 2 3 3 2 2 ] @@ -820,9 +815,7 @@ def __call__(self, *cell): - ``cell`` -- a pair of integers, tuple, or list specifying a cell in the tableau - OUTPUT: - - - The value in the corresponding cell. + OUTPUT: the value in the corresponding cell EXAMPLES:: @@ -1155,12 +1148,10 @@ def descents(self): sage: Tableau( [[1,2,3],[4,5]] ).descents() [(1, 0), (1, 1)] """ - descents = [] - for i in range(1, len(self)): - for j in range(len(self[i])): - if self[i][j] > self[i-1][j]: - descents.append((i, j)) - return descents + return [(i, j) + for i in range(1, len(self)) + for j, selfij in enumerate(self[i]) + if selfij > self[i-1][j]] def major_index(self): """ @@ -1221,15 +1212,15 @@ def inversions(self): for j, entry in enumerate(row): # c is in position (i,j) # find the d that satisfy condition 1 - for k in range(j+1, len(row)): - if entry > row[k]: - inversions.append(((i, j), (i, k))) + inversions.extend(((i, j), (i, k)) + for k in range(j + 1, len(row)) + if entry > row[k]) # find the d that satisfy condition 2 if i == 0: continue - for k in range(j): - if entry > previous_row[k]: - inversions.append(((i, j), (i-1, k))) + inversions.extend(((i, j), (i - 1, k)) + for k in range(j) + if entry > previous_row[k]) previous_row = row return inversions @@ -1264,15 +1255,14 @@ def to_sign_matrix(self, max_entry=None): r""" Return the sign matrix of ``self``. - A sign matrix is an `m \times n` matrix of 0's, 1's and -1's such that the + A sign matrix is an `m \times n` matrix of 0s, 1s, and -1s such that the partial sums of each column is either 0 or 1 and the partial sums of - each row is non-negative. [Ava2007]_ + each row is nonnegative. [Ava2007]_ INPUT: - - ``max_entry`` -- A non-negative integer, the maximum allowable number in - the tableau. Defaults to the largest entry in the tableau if not specified. - + - ``max_entry`` -- nonnegative integer; the maximum allowable number in + the tableau (defaults to the largest entry in the tableau if not specified) EXAMPLES:: @@ -1298,14 +1288,14 @@ def to_sign_matrix(self, max_entry=None): sage: s.to_sign_matrix(6) Traceback (most recent call last): ... - ValueError: the entries must be non-negative integers + ValueError: the entries must be nonnegative integers """ from sage.rings.integer_ring import ZZ from sage.sets.positive_integers import PositiveIntegers PI = PositiveIntegers() for row in self: if any(c not in PI for c in row): - raise ValueError("the entries must be non-negative integers") + raise ValueError("the entries must be nonnegative integers") from sage.matrix.matrix_space import MatrixSpace if max_entry is None: max_entry = max([max(c) for c in self]) @@ -1335,14 +1325,12 @@ def schuetzenberger_involution(self, n=None, check=True): INPUT: - - ``n`` -- an integer specifying the maximal letter in the + - ``n`` -- integer specifying the maximal letter in the alphabet (optional) - - ``check`` -- (Default: ``True``) Check to make sure ``self`` is - semistandard. Set to ``False`` to avoid this check. (optional) + - ``check`` -- boolean (default: ``True``); check to make sure ``self`` + is semistandard - OUTPUT: - - - a tableau, the Schuetzenberger involution of ``self`` + OUTPUT: a tableau, the Schuetzenberger involution of ``self`` EXAMPLES:: @@ -1402,14 +1390,12 @@ def evacuation(self, n=None, check=True): INPUT: - - ``n`` -- an integer specifying the maximal letter in the + - ``n`` -- integer specifying the maximal letter in the alphabet (optional) - - ``check`` -- (Default: ``True``) Check to make sure ``self`` is - semistandard. Set to ``False`` to avoid this check. (optional) + - ``check`` -- boolean (default: ``True``); check to make sure ``self`` + is semistandard - OUTPUT: - - - a tableau, the evacuation of ``self`` + OUTPUT: a tableau, the evacuation of ``self`` EXAMPLES:: @@ -1436,7 +1422,7 @@ def evacuation(self, n=None, check=True): """ return self.schuetzenberger_involution(n, check) - @combinatorial_map(name="standardization") + @combinatorial_map(name='standardization') def standardization(self, check=True): r""" Return the standardization of ``self``, assuming ``self`` is a @@ -1455,8 +1441,8 @@ def standardization(self, check=True): INPUT: - - ``check`` -- (Default: ``True``) Check to make sure ``self`` is - semistandard. Set to ``False`` to avoid this check. + - ``check`` -- (default: ``True``) check to make sure ``self`` is + semistandard; set to ``False`` to avoid this check EXAMPLES:: @@ -1511,17 +1497,17 @@ def bender_knuth_involution(self, k, rows=None, check=True): INPUT: - - ``k`` -- an integer + - ``k`` -- integer - - ``rows`` -- (Default ``None``) When set to ``None``, the method + - ``rows`` -- (default: ``None``) when set to ``None``, the method computes the `k`-th Bender--Knuth involution as defined above. When an iterable, this computes the composition of the `k`-th Bender--Knuth switches at row `i` over all `i` in ``rows``. When set to an integer `i`, the method computes the `k`-th Bender--Knuth switch at row `i`. Note the indexing of the rows starts with `1`. - - ``check`` -- (Default: ``True``) Check to make sure ``self`` is - semistandard. Set to ``False`` to avoid this check. + - ``check`` -- (default: ``True``) check to make sure ``self`` is + semistandard; Set to ``False`` to avoid this check OUTPUT: @@ -2083,7 +2069,7 @@ def k_weight(self, k): def is_k_tableau(self, k): r""" - Checks whether ``self`` is a valid weak `k`-tableau. + Check whether ``self`` is a valid weak `k`-tableau. EXAMPLES:: @@ -2353,7 +2339,7 @@ def schensted_insert(self, i, left=False): INPUT: - ``i`` -- a number to insert - - ``left`` -- (default: ``False``) boolean; if set to + - ``left`` -- boolean (default: ``False``); if set to ``True``, the insertion will be done from the left. That is, if one thinks of the algorithm as appending a letter to the reading word of ``self``, we append the letter to @@ -2466,7 +2452,7 @@ def reverse_bump(self, loc): INPUT: - - ``loc`` -- Can be either of the following: + - ``loc`` -- can be either of the following: - The coordinates ``(r, c)`` of the square to reverse-bump (which must be a corner of the tableau); @@ -2476,9 +2462,7 @@ def reverse_bump(self, loc): topmost row and the leftmost column are the `0`-th row and the `0`-th column. - OUTPUT: - - An ordered pair consisting of: + OUTPUT: an ordered pair consisting of: 1. The resulting (smaller) tableau; 2. The entry bumped out at the end of the process. @@ -2530,7 +2514,6 @@ def reverse_bump(self, loc): Reverse row bumping is only implemented for tableaux with weakly increasing and strictly increasing columns (though the tableau does not need to be an instance of class :class:`SemistandardTableau`). - """ if not (self.is_semistandard()): raise ValueError("reverse bumping is only defined for semistandard tableaux") @@ -3193,7 +3176,6 @@ def add_entry(self, cell, m): Traceback (most recent call last): ... IndexError: (2, 2) is not an addable cell of the tableau - """ tab = self.to_list() (r, c) = cell @@ -3709,7 +3691,6 @@ def right_key_tableau(self): sage: Tableau([]).right_key_tableau() [] - """ if not self: return self @@ -3736,7 +3717,7 @@ def left_key_tableau(self): Return the left key tableau of ``self``. The left key tableau of a tableau `T` is the key tableau whose entries - are weakly lesser than the corresponding entries in `T`, and whose column + are weakly less than the corresponding entries in `T`, and whose column reading word is subject to certain conditions. See [LS1990]_ for the full definition. ALGORITHM: @@ -3778,7 +3759,6 @@ def left_key_tableau(self): sage: Tableau([]).left_key_tableau() [] - """ if not self: return self @@ -3945,8 +3925,8 @@ def residue(self, k, e, multicharge=(0,)): INPUT: - - ``k`` -- an integer in `\{1, 2, \ldots, n\}` - - ``e`` -- an integer in `\{0, 2, 3, 4, 5, \ldots\}` + - ``k`` -- integer in `\{1, 2, \ldots, n\}` + - ``e`` -- integer in `\{0, 2, 3, 4, 5, \ldots\}` - ``multicharge`` -- (default: ``[0]``) a list of length 1 Here `n` is its size of ``self``. @@ -3955,9 +3935,7 @@ def residue(self, k, e, multicharge=(0,)): all of the contents. It is included mainly for compatibility with :meth:`~sage.combinat.tableau_tuples.TableauTuple.residue`. - OUTPUT: - - The residue in `\ZZ / e\ZZ`. + OUTPUT: the residue in `\ZZ / e\ZZ` EXAMPLES:: @@ -3990,7 +3968,7 @@ def residue_sequence(self, e, multicharge=(0,)): INPUT: - - ``e`` -- an integer in `\{0, 2, 3, 4, 5, \ldots\}` + - ``e`` -- integer in `\{0, 2, 3, 4, 5, \ldots\}` - ``multicharge`` -- (default: ``[0]``) a sequence of integers of length 1 @@ -4037,9 +4015,7 @@ def degree(self, e, multicharge=(0,)): - ``e`` -- the *quantum characteristic* - ``multicharge`` -- (default: ``[0]``) the multicharge - OUTPUT: - - The degree of the tableau ``self``, which is an integer. + OUTPUT: the degree of the tableau ``self``, which is an integer EXAMPLES:: @@ -4082,9 +4058,7 @@ def codegree(self, e, multicharge=(0,)): - ``e`` -- the *quantum characteristic* - ``multicharge`` -- (default: ``[0]``) the multicharge - OUTPUT: - - The codegree of the tableau ``self``, which is an integer. + OUTPUT: the codegree of the tableau ``self``, which is an integer EXAMPLES:: @@ -4417,9 +4391,7 @@ class SemistandardTableau(Tableau): - ``t`` -- a tableau, a list of iterables, or an empty list - OUTPUT: - - - A SemistandardTableau object constructed from ``t``. + OUTPUT: a SemistandardTableau object constructed from ``t`` A semistandard tableau is a tableau whose entries are positive integers, which are weakly increasing in rows and strictly increasing down columns. @@ -4560,7 +4532,7 @@ def check(self): for row in self: if any(c not in PI for c in row): - raise ValueError("the entries of a semistandard tableau must be non-negative integers") + raise ValueError("the entries of a semistandard tableau must be nonnegative integers") if any(row[c] > row[c+1] for c in range(len(row)-1)): raise ValueError("the entries in each row of a semistandard tableau must be weakly increasing") @@ -4812,7 +4784,6 @@ def dominates(self, t): True sage: s.dominates([[1,2,3,4,5]]) False - """ t = StandardTableau(t) return all(self.restrict(m).shape().dominates(t.restrict(m).shape()) @@ -5076,7 +5047,7 @@ def from_chain(chain): return T.element_class(T, res) -def from_shape_and_word(shape, w, convention="French"): +def from_shape_and_word(shape, w, convention='French'): r""" Return a tableau from a shape and word. @@ -5086,15 +5057,15 @@ def from_shape_and_word(shape, w, convention="French"): - ``w`` -- a word whose length equals that of the partition - - ``convention`` -- a string which can take values ``"French"`` or - ``"English"``; the default is ``"French"`` + - ``convention`` -- string (default: ``'French'``); can take values + ``'French'`` or ``'English'`` OUTPUT: A tableau, whose shape is ``shape`` and whose reading word is ``w``. - If the ``convention`` is specified as ``"French"``, the reading word is to be read + If the ``convention`` is specified as ``'French'``, the reading word is to be read starting from the top row in French convention (= the bottom row in English - convention). If the ``convention`` is specified as ``"English"``, the reading word + convention). If the ``convention`` is specified as ``'English'``, the reading word is to be read starting with the top row in English convention. EXAMPLES:: @@ -5108,7 +5079,7 @@ def from_shape_and_word(shape, w, convention="French"): sage: from_shape_and_word(shape, word) [[1, 3], [2], [4]] sage: word = Word(flatten(t)) - sage: from_shape_and_word(shape, word, convention="English") + sage: from_shape_and_word(shape, word, convention='English') [[1, 3], [2], [4]] """ res = [] @@ -5227,7 +5198,7 @@ def check(self): sage: IncreasingTableau([[0,1]]) # indirect doctest Traceback (most recent call last): ... - ValueError: the entries of an increasing tableau must be non-negative integers + ValueError: the entries of an increasing tableau must be nonnegative integers """ if not self: # Empty tableau, so trivially an increasing tableau @@ -5244,7 +5215,7 @@ def check(self): for row in self: if any(c not in PI for c in row): raise ValueError("the entries of an increasing tableau" - " must be non-negative integers") + " must be nonnegative integers") if any(row[c] >= row[c+1] for c in range(len(row)-1)): raise ValueError("the entries in each row of an increasing" " tableau must be strictly increasing") @@ -5459,7 +5430,7 @@ class Tableaux(UniqueRepresentation, Parent): INPUT: - - ``n`` (optional) -- a non-negative integer + - ``n`` -- (optional) nonnegative integer OUTPUT: @@ -5510,7 +5481,7 @@ class Tableaux(UniqueRepresentation, Parent): sage: Tableaux(t) Traceback (most recent call last): ... - ValueError: the argument to Tableaux() must be a non-negative integer + ValueError: the argument to Tableaux() must be a nonnegative integer sage: Tableaux(3)([[1, 1]]) Traceback (most recent call last): ... @@ -5565,7 +5536,7 @@ def __classcall_private__(cls, *args, **kwargs): return Tableaux_all() else: if not isinstance(n, (int, Integer)) or n < 0: - raise ValueError("the argument to Tableaux() must be a non-negative integer") + raise ValueError("the argument to Tableaux() must be a nonnegative integer") return Tableaux_size(n) Element = Tableau @@ -5573,7 +5544,7 @@ def __classcall_private__(cls, *args, **kwargs): # add options to class class options(GlobalOptions): r""" - Sets the global options for elements of the tableau, skew_tableau, + Set the global options for elements of the tableau, skew_tableau, and tableau tuple classes. The defaults are for tableau to be displayed as a list, latexed as a Young diagram using the English convention. @@ -5640,25 +5611,25 @@ class options(GlobalOptions): """ NAME = 'Tableaux' module = 'sage.combinat.tableau' - display = dict(default="list", + display = dict(default='list', description='Controls the way in which tableaux are printed', values=dict(list='print tableaux as lists', diagram='display as Young diagram (similar to :meth:`~sage.combinat.tableau.Tableau.pp()`', compact='minimal length string representation'), - alias=dict(array="diagram", ferrers_diagram="diagram", young_diagram="diagram"), + alias=dict(array='diagram', ferrers_diagram='diagram', young_diagram='diagram'), case_sensitive=False) - ascii_art = dict(default="repr", + ascii_art = dict(default='repr', description='Controls the ascii art output for tableaux', values=dict(repr='display using the diagram string representation', table='display as a table', compact='minimal length ascii art'), case_sensitive=False) - latex = dict(default="diagram", + latex = dict(default='diagram', description='Controls the way in which tableaux are latexed', values=dict(list='as a list', diagram='as a Young diagram'), - alias=dict(array="diagram", ferrers_diagram="diagram", young_diagram="diagram"), + alias=dict(array='diagram', ferrers_diagram='diagram', young_diagram='diagram'), case_sensitive=False) - convention = dict(default="English", + convention = dict(default='English', description='Sets the convention used for displaying tableaux and partitions', values=dict( English='use the English convention', @@ -5666,21 +5637,19 @@ class options(GlobalOptions): Russian='use the Russian convention', ), case_sensitive=False) - notation = dict(alt_name="convention") + notation = dict(alt_name='convention') def _element_constructor_(self, t): r""" - Constructs an object from ``t`` as an element of ``self``, if + Construct an object from ``t`` as an element of ``self``, if possible. This is inherited by all Tableaux, SemistandardTableaux, and StandardTableaux classes. INPUT: - - ``t`` -- Data which can be interpreted as a tableau + - ``t`` -- data which can be interpreted as a tableau - OUTPUT: - - - The corresponding tableau object + OUTPUT: the corresponding tableau object TESTS:: @@ -5744,7 +5713,7 @@ class Tableaux_all(Tableaux): def __init__(self): r""" - Initializes the class of all tableaux + Initialize the class of all tableaux. TESTS:: @@ -5782,7 +5751,7 @@ class Tableaux_size(Tableaux): def __init__(self, n): r""" - Initializes the class of tableaux of size ``n``. + Initialize the class of tableaux of size `n`. TESTS:: @@ -5855,11 +5824,11 @@ class SemistandardTableaux(Tableaux): Keyword arguments: - - ``size`` -- The size of the tableaux - - ``shape`` -- The shape of the tableaux - - ``eval`` -- The weight (also called content or evaluation) of + - ``size`` -- the size of the tableaux + - ``shape`` -- the shape of the tableaux + - ``eval`` -- the weight (also called content or evaluation) of the tableaux - - ``max_entry`` -- A maximum entry for the tableaux. This can be a + - ``max_entry`` -- a maximum entry for the tableaux. This can be a positive integer or infinity (``oo``). If ``size`` or ``shape`` are specified, ``max_entry`` defaults to be ``size`` or the size of ``shape``. @@ -6065,7 +6034,7 @@ def __classcall_private__(cls, *args, **kwargs): if not isinstance(size, (int, Integer)): raise ValueError("size must be an integer") if size < 0: - raise ValueError("size must be non-negative") + raise ValueError("size must be nonnegative") if shape is not None: from sage.combinat.skew_partition import SkewPartitions @@ -6294,7 +6263,7 @@ class SemistandardTableaux_all(SemistandardTableaux, DisjointUnionEnumeratedSets def __init__(self, max_entry=None): r""" - Initializes the class of all semistandard tableaux. + Initialize the class of all semistandard tableaux. .. WARNING:: @@ -6454,7 +6423,7 @@ class SemistandardTableaux_shape_inf(SemistandardTableaux): def __init__(self, p): r""" - Initializes the class of semistandard tableaux of shape ``p`` and no + Initialize the class of semistandard tableaux of shape ``p`` and no maximum entry. .. WARNING:: @@ -6542,7 +6511,7 @@ class SemistandardTableaux_size(SemistandardTableaux): def __init__(self, n, max_entry=None): r""" - Initializes the class of semistandard tableaux of size ``n``. + Initialize the class of semistandard tableaux of size `n`. .. WARNING:: @@ -6741,12 +6710,12 @@ class SemistandardTableaux_shape(SemistandardTableaux): INPUT: - ``p`` -- a partition - - ``max_entry`` -- the max entry; defaults to the size of ``p`` + - ``max_entry`` -- the max entry; defaults to the size of `p` """ def __init__(self, p, max_entry=None): r""" - Initializes the class of semistandard tableaux of shape ``p``, with a + Initialize the class of semistandard tableaux of shape `p`, with a given ``max_entry``. .. WARNING:: @@ -6859,7 +6828,6 @@ def random_element(self): sage: S = SemistandardTableaux([2, 2, 1, 1], max_entry=7) sage: S.random_element() in S True - """ from sage.misc.prandom import randint with_sentinels = [max(i, j) for i, j in zip([0]+list(self.shape), [k+1 for k in self.shape]+[0])] @@ -6958,7 +6926,7 @@ class SemistandardTableaux_shape_weight(SemistandardTableaux_shape): def __init__(self, p, mu): r""" - Initializes the class of all semistandard tableaux of shape ``p`` and + Initialize the class of all semistandard tableaux of shape ``p`` and weight ``mu``. .. WARNING:: @@ -7075,7 +7043,7 @@ class SemistandardTableaux_size_weight(SemistandardTableaux): def __init__(self, n, mu): r""" - Initializes the class of semistandard tableaux of size ``n`` and + Initialize the class of semistandard tableaux of size ``n`` and weight ``mu``. .. WARNING:: @@ -7162,14 +7130,12 @@ class RowStandardTableaux(Tableaux): INPUT: - - either a non-negative integer (possibly specified with the keyword + - either a nonnegative integer (possibly specified with the keyword ``n``) or a partition - OUTPUT: - - - with no argument, the class of all standard tableaux + OUTPUT: with no argument, the class of all standard tableaux - - with a non-negative integer argument, ``n``, the class of all standard + - with a nonnegative integer argument, ``n``, the class of all standard tableaux of size ``n`` - with a partition argument, the class of all standard tableaux of that @@ -7254,11 +7220,11 @@ def __classcall_private__(cls, *args, **kwargs): sage: RowStandardTableaux(-1) Traceback (most recent call last): ... - ValueError: the argument must be a non-negative integer or a partition + ValueError: the argument must be a nonnegative integer or a partition sage: RowStandardTableaux([[1]]) Traceback (most recent call last): ... - ValueError: the argument must be a non-negative integer or a partition + ValueError: the argument must be a nonnegative integer or a partition """ from sage.combinat.partition import _Partitions from sage.combinat.skew_partition import SkewPartitions @@ -7282,7 +7248,7 @@ def __classcall_private__(cls, *args, **kwargs): raise NotImplementedError("row standard skew tableaux not yet implemented") if not isinstance(n, (int, Integer)) or n < 0: - raise ValueError("the argument must be a non-negative integer or a partition") + raise ValueError("the argument must be a nonnegative integer or a partition") return RowStandardTableaux_size(n) @@ -7325,7 +7291,7 @@ class RowStandardTableaux_all(RowStandardTableaux, DisjointUnionEnumeratedSets): def __init__(self): r""" - Initializes the class of all standard tableaux. + Initialize the class of all standard tableaux. .. WARNING:: @@ -7390,7 +7356,7 @@ class RowStandardTableaux_size(RowStandardTableaux, DisjointUnionEnumeratedSets) def __init__(self, n): r""" - Initializes the class of all row standard tableaux of size ``n``. + Initialize the class of all row standard tableaux of size ``n``. .. WARNING:: @@ -7460,7 +7426,7 @@ class RowStandardTableaux_shape(RowStandardTableaux): def __init__(self, p): r""" - Initializes the class of all row standard tableaux of a given shape. + Initialize the class of all row standard tableaux of a given shape. .. WARNING:: @@ -7576,14 +7542,12 @@ class StandardTableaux(SemistandardTableaux): INPUT: - - Either a non-negative integer (possibly specified with the keyword ``n``) + - Either a nonnegative integer (possibly specified with the keyword ``n``) or a partition. - OUTPUT: - - - With no argument, the class of all standard tableaux + OUTPUT: with no argument, the class of all standard tableaux - - With a non-negative integer argument, ``n``, the class of all standard + - With a nonnegative integer argument, ``n``, the class of all standard tableaux of size ``n`` - With a partition argument, the class of all standard tableaux of that @@ -7656,11 +7620,11 @@ def __classcall_private__(cls, *args, **kwargs): sage: StandardTableaux(-1) Traceback (most recent call last): ... - ValueError: the argument must be a non-negative integer or a partition + ValueError: the argument must be a nonnegative integer or a partition sage: StandardTableaux([[1]]) Traceback (most recent call last): ... - ValueError: the argument must be a non-negative integer or a partition + ValueError: the argument must be a nonnegative integer or a partition """ from sage.combinat.partition import _Partitions from sage.combinat.skew_partition import SkewPartitions @@ -7683,7 +7647,7 @@ def __classcall_private__(cls, *args, **kwargs): return StandardSkewTableaux(n) if not isinstance(n, (int, Integer)) or n < 0: - raise ValueError("the argument must be a non-negative integer or a partition") + raise ValueError("the argument must be a nonnegative integer or a partition") return StandardTableaux_size(n) @@ -7728,7 +7692,7 @@ class StandardTableaux_all(StandardTableaux, DisjointUnionEnumeratedSets): def __init__(self): r""" - Initializes the class of all standard tableaux. + Initialize the class of all standard tableaux. TESTS:: @@ -7780,7 +7744,7 @@ class StandardTableaux_size(StandardTableaux, DisjointUnionEnumeratedSets): def __init__(self, n): r""" - Initializes the class of all standard tableaux of size ``n``. + Initialize the class of all standard tableaux of size `n`. .. WARNING:: @@ -7967,7 +7931,7 @@ class StandardTableaux_shape(StandardTableaux): def __init__(self, p): r""" - Initializes the class of all semistandard tableaux of a given shape. + Initialize the class of all semistandard tableaux of a given shape. .. WARNING:: @@ -8597,7 +8561,7 @@ def __classcall_private__(cls, *args, **kwargs): # Consistency checks if size is not None: if size not in NonNegativeIntegers(): - raise ValueError("size must be a non-negative integer") + raise ValueError("size must be a nonnegative integer") size = Integer(size) if shape is not None: @@ -8631,7 +8595,7 @@ def __classcall_private__(cls, *args, **kwargs): if not is_inf and not isinstance(max_entry, (int, Integer)): raise ValueError("max_entry must be an integer or PlusInfinity") elif max_entry < 0: - raise ValueError("max_entry must be non-negative") + raise ValueError("max_entry must be nonnegative") if size is not None and shape is not None: if sum(shape) != size: @@ -8866,7 +8830,7 @@ class IncreasingTableaux_all(IncreasingTableaux, DisjointUnionEnumeratedSets): def __init__(self, max_entry=None): r""" - Initializes the class of all increasing tableaux. + Initialize the class of all increasing tableaux. .. WARNING:: @@ -8921,7 +8885,7 @@ class IncreasingTableaux_size_inf(IncreasingTableaux): def __init__(self, n): r""" - Initializes the class of increasing tableaux of size ``n`` with no + Initialize the class of increasing tableaux of size `n` with no maximum entry. .. WARNING:: @@ -9002,7 +8966,7 @@ class IncreasingTableaux_shape_inf(IncreasingTableaux): def __init__(self, p): r""" - Initializes the class of increasing tableaux of shape ``p`` and no + Initialize the class of increasing tableaux of shape `p` and no maximum entry. .. WARNING:: @@ -9084,7 +9048,7 @@ class IncreasingTableaux_size(IncreasingTableaux): def __init__(self, n, max_entry=None): r""" - Initializes the class of increasing tableaux of size ``n``. + Initialize the class of increasing tableaux of size `n`. .. WARNING:: @@ -9204,7 +9168,7 @@ class IncreasingTableaux_shape(IncreasingTableaux): def __init__(self, p, max_entry=None): r""" - Initializes the class of increasing tableaux of shape ``p``, with a + Initialize the class of increasing tableaux of shape `p`, with a given ``max_entry``. .. WARNING:: @@ -9323,7 +9287,7 @@ class IncreasingTableaux_shape_weight(IncreasingTableaux_shape): def __init__(self, p, wt): r""" - Initializes the class of all increasing tableaux of shape ``p`` and + Initialize the class of all increasing tableaux of shape ``p`` and weight ``mu``. .. WARNING:: @@ -9467,7 +9431,7 @@ class IncreasingTableaux_size_weight(IncreasingTableaux): def __init__(self, n, wt): r""" - Initializes the class of increasing tableaux of size ``n`` and + Initialize the class of increasing tableaux of size `n` and weight ``wt``. .. WARNING:: diff --git a/src/sage/combinat/tableau_residues.py b/src/sage/combinat/tableau_residues.py index db94461f6ef..ccd39961fa9 100644 --- a/src/sage/combinat/tableau_residues.py +++ b/src/sage/combinat/tableau_residues.py @@ -244,7 +244,7 @@ def __init__(self, parent, residues, check): The ``multicharge`` is the optional argument which, if omitted, defaults to ``(0,)``. On the other hand, the ``residue`` must always be specified so, below, we check to see whether or note - ``residues`` is `None` and adjust accordingly in this case. + ``residues`` is ``None`` and adjust accordingly in this case. EXAMPLES:: @@ -269,7 +269,7 @@ def __init__(self, parent, residues, check): def check(self): r""" - Raise a :class:`ValueError` if ``self`` is not a residue sequence. + Raise a :exc:`ValueError` if ``self`` is not a residue sequence. EXAMPLES:: @@ -433,11 +433,11 @@ def restrict_row(self, cell, row): def swap_residues(self, i, j): r""" Return the *new* residue sequence obtained by swapping the residues - for ``i`` and `j``. + for ``i`` and ``j``. INPUT: - - ``i`` and ``j`` -- two integers between `1` and the length of + - ``i``, ``j`` -- two integers between `1` and the length of the residue sequence If residue sequence ``self`` is of the form `(r_1, \ldots, r_n)`, and @@ -718,7 +718,7 @@ def __init__(self, e, multicharge=(0,)): sage: ResidueSequences(e=0, multicharge=(0,1,2)) == ResidueSequences(e=3, multicharge=(0,1,2)) False - The TestSuite fails ``_test_pickling` because ``__getitem__`` does + The TestSuite fails ``_test_pickling`` because ``__getitem__`` does not support slices, so we skip this:: sage: R = ResidueSequences(e=0, multicharge=(0,1,2)) @@ -792,8 +792,8 @@ def cell_residue(self, *args): INPUT: - - ``r`` and ``c`` -- the row and column indices in level one - - ``k``, ``r`` and ``c`` -- the component, row and column indices + - ``r``, ``c`` -- the row and column indices in level one + - ``k``, ``r``, ``c`` -- the component, row and column indices in higher levels EXAMPLES:: diff --git a/src/sage/combinat/tableau_tuple.py b/src/sage/combinat/tableau_tuple.py index 3bc6b03d5dd..fd847c4ad1e 100644 --- a/src/sage/combinat/tableau_tuple.py +++ b/src/sage/combinat/tableau_tuple.py @@ -251,12 +251,10 @@ class TableauTuple(CombinatorialElement): INPUT: - - ``t`` -- a list or tuple of :class:`Tableau`, a list or tuple of lists + - ``t`` -- list or tuple of :class:`Tableau`, a list or tuple of lists of lists - OUTPUT: - - - The Tableau tuple object constructed from ``t``. + OUTPUT: the Tableau tuple object constructed from ``t`` A :class:`TableauTuple` is a tuple of tableau of shape a :class:`PartitionTuple`. These combinatorial objects are useful is @@ -538,7 +536,7 @@ def _latex_(self): \lr{6}&\lr{7}\\\cline{1-2} \end{array}$} } \Bigg) - sage: TableauTuples.options(convention="french") + sage: TableauTuples.options(convention='french') sage: latex(t) # indirect doctest \Bigg( {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} \raisebox{-.6ex}{$\begin{array}[t]{*{2}c}\cline{1-1} @@ -622,9 +620,7 @@ def __call__(self, *cell): - ``cell`` -- a triple of integers, tuple, or list specifying a cell in ``self`` - OUTPUT: - - - The value in the corresponding cell. + OUTPUT: the value in the corresponding cell EXAMPLES:: @@ -733,7 +729,7 @@ def pp(self): 4 5 4 5 8 14 6 9 - sage: TableauTuples.options(convention="french") + sage: TableauTuples.options(convention='french') sage: t.pp() 9 6 @@ -1047,7 +1043,6 @@ def up(self, n=None): ([[1, 2], [4]], [[3]]), ([[1, 2]], [[3, 4]]), ([[1, 2]], [[3], [4]])] - """ if n is None: n = self.size() @@ -1089,10 +1084,8 @@ def row_stabilizer(self): # tableau, by including the identity permutation on the set [1..n]. n = max(self.entries()) gens = [list(range(1, n + 1))] - for t in self: - for i in range(len(t)): - for j in range(len(t[i]) - 1): - gens.append((t[i][j], t[i][j + 1])) + gens.extend((ti[j], ti[j + 1]) for t in self + for ti in t for j in range(len(ti) - 1)) return PermutationGroup(gens) def column_stabilizer(self): @@ -1307,7 +1300,7 @@ def content(self, k, multicharge): INPUT: - - ``k`` -- an integer in `\{1, 2, \ldots, n\}` + - ``k`` -- integer in `\{1, 2, \ldots, n\}` - ``multicharge`` -- a sequence of integers of length `l` Here `l` is the :meth:`~TableauTuple.level` and `n` is the @@ -1354,16 +1347,14 @@ def residue(self, k, e, multicharge): INPUT: - - ``k`` -- an integer in `\{1, 2, \ldots, n\}` - - ``e`` -- an integer in `\{0, 2, 3, 4, 5, \ldots\}` - - ``multicharge`` -- a list of integers of length `l` + - ``k`` -- integer in `\{1, 2, \ldots, n\}` + - ``e`` -- integer in `\{0, 2, 3, 4, 5, \ldots\}` + - ``multicharge`` -- list of integers of length `l` Here `l` is the :meth:`~TableauTuple.level` and `n` is the :meth:`~TableauTuple.size` of ``self``. - OUTPUT: - - The residue of ``k`` in a standard tableau. That is, + OUTPUT: the residue of ``k`` in a standard tableau. That is, EXAMPLES:: @@ -1412,9 +1403,7 @@ class RowStandardTableauTuple(TableauTuple, metaclass=ClasscallMetaclass): - ``t`` -- a tableau, a list of (standard) tableau or an equivalent list - OUTPUT: - - - A :class:`RowStandardTableauTuple` object constructed from ``t``. + OUTPUT: a :class:`RowStandardTableauTuple` object constructed from ``t`` .. NOTE:: @@ -1538,7 +1527,7 @@ def __classcall_private__(self, t): def __init__(self, parent, t, check=True): r""" - Initializes a row standard tableau tuple. + Initialize a row standard tableau tuple. EXAMPLES:: @@ -1668,9 +1657,7 @@ def degree(self, e, multicharge): - ``e`` -- the *quantum characteristic* ``e`` - ``multicharge`` -- (default: ``[0]``) the multicharge - OUTPUT: - - The degree of the tableau ``self``, which is an integer. + OUTPUT: the degree of the tableau ``self``, which is an integer EXAMPLES:: @@ -1723,9 +1710,7 @@ def codegree(self, e, multicharge): - ``e`` -- the *quantum characteristic* - ``multicharge`` -- the multicharge - OUTPUT: - - The codegree of the tableau ``self``, which is an integer. + OUTPUT: the codegree of the tableau ``self``, which is an integer EXAMPLES:: @@ -1747,7 +1732,6 @@ def codegree(self, e, multicharge): 2 sage: StandardTableauTuple([[],[[2]], [[1]]]).codegree(0,(0,0,0)) 3 - """ if not self: # the trivial case return 0 @@ -1793,9 +1777,7 @@ class StandardTableauTuple(RowStandardTableauTuple): - ``t`` -- a tableau, a list of (standard) tableau or an equivalent list - OUTPUT: - - - A :class:`StandardTableauTuple` object constructed from ``t``. + OUTPUT: a :class:`StandardTableauTuple` object constructed from ``t`` .. NOTE:: @@ -1924,7 +1906,7 @@ def __classcall_private__(self, t): def __init__(self, parent, t, check=True): r""" - Initializes a standard tableau tuple. + Initialize a standard tableau tuple. EXAMPLES:: @@ -2056,15 +2038,13 @@ class TableauTuples(UniqueRepresentation, Parent): - ``level`` -- the level of the tableau tuples (positive integer) - - ``size`` -- the size of the tableau tuples (non-negative integer) + - ``size`` -- the size of the tableau tuples (nonnegative integer) It is not necessary to use the keywords. If they are not specified then the first integer argument specifies the ``level`` and the second the ``size`` of the tableaux. - OUTPUT: - - - The corresponding class of tableau tuples. + OUTPUT: the corresponding class of tableau tuples The entries of a tableau can be any sage object. Because of this, no enumeration of the set of :class:`TableauTuples` is possible. @@ -2197,7 +2177,7 @@ def __classcall_private__(cls, level=None, size=None): raise ValueError('the level must be a positive integer') if not (size is None or size in NN): - raise ValueError('the size must be a non-negative integer') + raise ValueError('the size must be a nonnegative integer') # now that the inputs appear to make sense, return the appropriate class @@ -2217,18 +2197,16 @@ def __classcall_private__(cls, level=None, size=None): def _element_constructor_(self, t): r""" - Constructs an object from t as an element of ``self``, if possible. + Construct an object from t as an element of ``self``, if possible. This is inherited by all :class:`TableauTuples`, :class:`StandardTableauTuples`, and :class:`StandardTableauTuples` classes. INPUT: - - ``t`` -- Data which can be interpreted as a tableau - - OUTPUT: + - ``t`` -- data which can be interpreted as a tableau - - The corresponding tableau object + OUTPUT: the corresponding tableau object EXAMPLES:: @@ -2384,7 +2362,7 @@ class TableauTuples_all(TableauTuples): def __init__(self): r""" - Initializes the class of all tableaux. + Initialize the class of all tableaux. EXAMPLES:: @@ -2427,7 +2405,7 @@ class TableauTuples_level(TableauTuples): def __init__(self, level): r""" - Initializes the class of tableaux of level ``level``. + Initialize the class of tableaux of level ``level``. EXAMPLES:: @@ -2508,7 +2486,7 @@ class TableauTuples_size(TableauTuples): def __init__(self, size): """ - Initializes the class of tableaux of size ``size``. + Initialize the class of tableaux of size ``size``. EXAMPLES:: @@ -2589,7 +2567,7 @@ class TableauTuples_level_size(TableauTuples): def __init__(self, level, size): r""" - Initializes the class of tableaux of size ``size``. + Initialize the class of tableaux of size ``size``. EXAMPLES:: @@ -2664,11 +2642,10 @@ def an_element(self): ([[1, 2]], [], []) """ if self.size() == 0: - return self.element_class(self, [[] for _ in range(self.level())]) + return self.element_class(self, [[]] * self.level()) tab = [[list(range(1, self.size() + 1))]] - for _ in range(self.level() - 1): - tab.append([]) + tab.extend([] for _ in range(self.level() - 1)) return self.element_class(self, tab) @@ -2685,18 +2662,16 @@ class RowStandardTableauTuples(TableauTuples): - ``level`` -- the :meth:`~TableauTuples.level` of the tuples of tableaux - - ``size`` -- the :meth:`~TableauTuples.size` of the tuples of tableaux + - ``size`` -- the :meth:`~TableauTuples.size` of the tuples of tableaux - - ``shape`` -- a list or a partition tuple specifying the :meth:`shape` of + - ``shape`` -- list or a partition tuple specifying the :meth:`shape` of the row standard tableau tuples It is not necessary to use the keywords. If they are not used then the first integer argument specifies the :meth:`~TableauTuples.level` and the second the :meth:`~TableauTuples.size` of the tableau tuples. - OUTPUT: - - The appropriate subclass of :class:`RowStandardTableauTuples`. + OUTPUT: the appropriate subclass of :class:`RowStandardTableauTuples` A tuple of row standard tableau is a tableau whose entries are positive integers which increase from left to right along the rows in each component. @@ -2833,7 +2808,7 @@ def __classcall_private__(cls, *args, **kwargs): raise ValueError('the level must be a positive integer') if size is not None and (not isinstance(size, (int, Integer)) or size < 0): - raise ValueError('the size must be a non-negative integer') + raise ValueError('the size must be a nonnegative integer') if shape is not None: try: @@ -2988,7 +2963,7 @@ class RowStandardTableauTuples_all(RowStandardTableauTuples, DisjointUnionEnumer def __init__(self): r""" - Initializes the class of all row standard tableaux. + Initialize the class of all row standard tableaux. .. WARNING:: @@ -3039,7 +3014,7 @@ class RowStandardTableauTuples_level(RowStandardTableauTuples, DisjointUnionEnum def __init__(self, level): r""" - Initializes the class of row standard tableaux of level + Initialize the class of row standard tableaux of level ``level`` of arbitrary ``size``. .. WARNING:: @@ -3137,7 +3112,7 @@ class RowStandardTableauTuples_size(RowStandardTableauTuples, DisjointUnionEnume def __init__(self, size): r""" - Initializes the class of row standard tableaux of size ``size`` of + Initialize the class of row standard tableaux of size ``size`` of arbitrary level. .. WARNING:: @@ -3237,7 +3212,7 @@ class RowStandardTableauTuples_level_size(RowStandardTableauTuples, DisjointUnio def __init__(self, level, size): r""" - Initializes the class of row standard tableaux of level ``level`` + Initialize the class of row standard tableaux of level ``level`` and size ``size``. .. WARNING:: @@ -3353,7 +3328,7 @@ class RowStandardTableauTuples_shape(RowStandardTableauTuples): def __init__(self, shape): r""" - Initializes the class of row standard tableaux of shape ``p`` + Initialize the class of row standard tableaux of shape ``p`` and no maximum entry. .. WARNING:: @@ -3502,7 +3477,7 @@ def __iter__(self): # line lists back into tableaux. This is done y the following functions. def tableau_from_list(tab): """ - Converts a list tab=[t_1,...,t_n] into the mu-tableau obtained by + Convert a list tab=[t_1,...,t_n] into the mu-tableau obtained by inserting t_1,..,t_n in order into the rows of mu, from left to right in each component and then left to right along the components. """ @@ -3981,18 +3956,16 @@ class StandardTableauTuples(RowStandardTableauTuples): - ``level`` -- the :meth:`~TableauTuples.level` of the tuples of tableaux - - ``size`` -- the :meth:`~TableauTuples.size` of the tuples of tableaux + - ``size`` -- the :meth:`~TableauTuples.size` of the tuples of tableaux - - ``shape`` -- a list or a partition tuple specifying the :meth:`shape` of + - ``shape`` -- list or a partition tuple specifying the :meth:`shape` of the standard tableau tuples It is not necessary to use the keywords. If they are not used then the first integer argument specifies the :meth:`~TableauTuples.level` and the second the :meth:`~TableauTuples.size` of the tableau tuples. - OUTPUT: - - The appropriate subclass of :class:`StandardTableauTuples`. + OUTPUT: the appropriate subclass of :class:`StandardTableauTuples` A tuple of standard tableau is a tableau whose entries are positive integers which increase from left to right along the rows, and from top to @@ -4125,7 +4098,7 @@ def __classcall_private__(cls, *args, **kwargs): raise ValueError('the level must be a positive integer') if size is not None and (not isinstance(size, (int, Integer)) or size < 0): - raise ValueError('the size must be a non-negative integer') + raise ValueError('the size must be a nonnegative integer') if shape is not None: try: @@ -4279,7 +4252,7 @@ class StandardTableauTuples_all(StandardTableauTuples, DisjointUnionEnumeratedSe def __init__(self): r""" - Initializes the class of all standard tableaux. Input is not + Initialize the class of all standard tableaux. Input is not checked; please use :class:`StandardTableauTuples` to ensure the options are properly parsed. @@ -4303,7 +4276,6 @@ def _repr_(self): sage: STT = StandardTableauTuples(); STT # indirect doctest Standard tableau tuples - """ return "Standard tableau tuples" @@ -4472,7 +4444,7 @@ class StandardTableauTuples_size(StandardTableauTuples, DisjointUnionEnumeratedS def __init__(self, size): r""" - Initializes the class of semistandard tableaux of size ``size`` of + Initialize the class of semistandard tableaux of size ``size`` of arbitrary level. Input is not checked; please use :class:`StandardTableauTuples` to ensure the options are properly parsed. @@ -4599,7 +4571,7 @@ class StandardTableauTuples_level_size(StandardTableauTuples, DisjointUnionEnume def __init__(self, level, size): r""" - Initializes the class of semistandard tableaux of level ``level`` and + Initialize the class of semistandard tableaux of level ``level`` and size ``size``. Input is not checked; please use :class:`StandardTableauTuples` to ensure the options are properly parsed. @@ -4742,7 +4714,7 @@ class StandardTableauTuples_shape(StandardTableauTuples): def __init__(self, shape): r""" - Initializes the class of semistandard tableaux of shape ``p`` and no + Initialize the class of semistandard tableaux of shape ``p`` and no maximum entry. Input is not checked; please use :class:`StandardTableauTuples` to ensure the options are properly parsed. @@ -4867,7 +4839,7 @@ def __iter__(self): # now use clen and cclen to "inflate" tab into a tableau def tableau_from_list(tab): """ - Converts a list tab=[t_1,...,t_n] into the mu-tableau obtained by + Convert a list tab=[t_1,...,t_n] into the mu-tableau obtained by inserting t_1,..,t_n in order into the rows of mu, from left to right in each component and then left to right along the components. """ @@ -5340,9 +5312,7 @@ def _add_entry_fast(T, cell, m): - ``cell`` -- the cell - ``m`` -- the entry to add - OUTPUT: - - - a list of lists of lists representing the tableau tuple + OUTPUT: list of lists of lists representing the tableau tuple .. WARNING:: diff --git a/src/sage/combinat/tamari_lattices.py b/src/sage/combinat/tamari_lattices.py index f3e4de13a28..89a940182d7 100644 --- a/src/sage/combinat/tamari_lattices.py +++ b/src/sage/combinat/tamari_lattices.py @@ -49,6 +49,7 @@ from __future__ import annotations from sage.combinat.posets.lattices import LatticePoset, MeetSemilattice + def paths_in_triangle(i, j, a, b) -> list[tuple[int, ...]]: r""" Return all Dyck paths from `(0,0)` to `(i,j)` in the `(a \times @@ -61,14 +62,12 @@ def paths_in_triangle(i, j, a, b) -> list[tuple[int, ...]]: INPUT: - - `a` and `b` -- integers with `a \geq b` + - ``a``, ``b`` -- integers with `a \geq b` - - `i` and `j` -- nonnegative integers with `1 \geq \frac{j}{b} \geq + - ``i``, ``j`` -- nonnegative integers with `1 \geq \frac{j}{b} \geq \frac{i}{a} \geq 0` - OUTPUT: - - - a list of paths + OUTPUT: list of paths EXAMPLES:: @@ -110,11 +109,9 @@ def swap(p, i, m=1) -> tuple[int, ...]: - ``p`` -- a Dyck path in the `(a \times b)`-rectangle - - ``i`` -- an integer between `0` and `a+b-1` - - OUTPUT: + - ``i`` -- integer between `0` and `a+b-1` - - a Dyck path in the `(a \times b)`-rectangle + OUTPUT: a Dyck path in the `(a \times b)`-rectangle EXAMPLES:: @@ -169,9 +166,9 @@ def GeneralizedTamariLattice(a, b, m=1): INPUT: - - `a` and `b` -- integers with `a \geq b` + - ``a``, ``b`` -- integers with `a \geq b` - - `m` -- a nonnegative rational number such that `a \geq b m` + - ``m`` -- a nonnegative rational number such that `a \geq b m` OUTPUT: @@ -239,13 +236,11 @@ def TamariLattice(n, m=1): INPUT: - - `n` -- a nonnegative integer (the index) + - ``n`` -- nonnegative integer (the index) - - `m` -- an optional nonnegative integer (the slope, default to 1) + - ``m`` -- nonnegative integer (the slope, default: 1) - OUTPUT: - - a finite lattice + OUTPUT: a finite lattice In the usual case, the elements of the lattice are :func:`Dyck paths` in the `(n+1 \times @@ -284,7 +279,7 @@ def swap_dexter(p, i) -> list[tuple[int, ...]]: - ``p`` -- a Dyck path in the `(a \times b)`-rectangle - - ``i`` -- an integer between `0` and `a+b-1` + - ``i`` -- integer between `0` and `a+b-1` OUTPUT: @@ -350,11 +345,9 @@ def DexterSemilattice(n): INPUT: - - ``n`` -- a nonnegative integer (the index) - - OUTPUT: + - ``n`` -- nonnegative integer (the index) - a finite meet-semilattice + OUTPUT: a finite meet-semilattice The elements of the semilattice are :func:`Dyck paths` in the `(n+1 \times diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index 797852a2851..9aed8fd0652 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -157,7 +157,7 @@ sage: L.append(Polyomino([(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)],"pink")) By default, rotations are allowed and reflections are not. In this case, -there are no solution for tiling a `8 \times 8` rectangular box:: +there are no solutions for tiling a `8 \times 8` rectangular box:: sage: T = TilingSolver(L, box=(8,8)) sage: T.number_of_solutions() # long time (2.5s) @@ -304,12 +304,10 @@ def ncube_isometry_group(n, orientation_preserving=True): INPUT: - ``n`` -- positive integer, dimension of the space - - ``orientation_preserving`` -- bool (default: ``True``), + - ``orientation_preserving`` -- boolean (default: ``True``); whether the orientation is preserved - OUTPUT: - - list of matrices + OUTPUT: list of matrices EXAMPLES:: @@ -372,12 +370,10 @@ def ncube_isometry_group_cosets(n, orientation_preserving=True): INPUT: - ``n`` -- positive integer, dimension of the space - - ``orientation_preserving`` -- bool (default: ``True``), + - ``orientation_preserving`` -- boolean (default: ``True``); whether the orientation is preserved - OUTPUT: - - list of cosets, each coset being a sorted list of matrices + OUTPUT: list of cosets, each coset being a sorted list of matrices EXAMPLES:: @@ -485,8 +481,8 @@ class Polyomino(SageObject): INPUT: - ``coords`` -- iterable of integer coordinates in `\ZZ^d` - - ``color`` -- string (default: ``'gray'``), color for display - - ``dimension`` -- integer (default: ``None``), dimension of the space, + - ``color`` -- string (default: ``'gray'``); color for display + - ``dimension`` -- integer (default: ``None``); dimension of the space, if ``None``, it is guessed from the ``coords`` if ``coords`` is non empty @@ -518,7 +514,6 @@ def __init__(self, coords, color='gray', dimension=None): sage: Polyomino([], dimension=2) Polyomino: [], Color: gray - """ from sage.modules.free_module import FreeModule from sage.rings.integer_ring import ZZ @@ -666,9 +661,7 @@ def __eq__(self, other): - ``other`` -- a polyomino - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -691,9 +684,7 @@ def __ne__(self, other): - ``other`` -- a polyomino - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -716,9 +707,7 @@ def __le__(self, other): - ``other`` -- a polyomino - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -740,9 +729,7 @@ def __ge__(self, other): - ``other`` -- a polyomino - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -764,9 +751,7 @@ def __lt__(self, other): - ``other`` -- a polyomino - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -788,9 +773,7 @@ def __gt__(self, other): - ``other`` -- a polyomino - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -812,9 +795,7 @@ def intersection(self, other): - ``other`` -- a polyomino - OUTPUT: - - polyomino + OUTPUT: polyomino EXAMPLES:: @@ -840,9 +821,7 @@ def __sub__(self, v): - ``v`` -- tuple - OUTPUT: - - polyomino + OUTPUT: polyomino EXAMPLES:: @@ -862,9 +841,7 @@ def __add__(self, v): - ``v`` -- tuple - OUTPUT: - - polyomino + OUTPUT: polyomino EXAMPLES:: @@ -883,11 +860,9 @@ def __rmul__(self, m): INPUT: - - ``m`` -- square matrix, matching the dimension of ``self``. - - OUTPUT: + - ``m`` -- square matrix, matching the dimension of ``self`` - Polyomino + OUTPUT: polyomino EXAMPLES:: @@ -947,18 +922,16 @@ def canonical_isometric_copies(self, orientation_preserving=True, INPUT: - - ``orientation_preserving`` -- bool (default: ``True``); + - ``orientation_preserving`` -- boolean (default: ``True``); if ``True``, the group of isometries of the `n`-cube is restricted to those that preserve the orientation, i.e. of determinant 1. - - ``mod_box_isometries`` -- bool (default: ``False``), whether to + - ``mod_box_isometries`` -- boolean (default: ``False``); whether to quotient the group of isometries of the `n`-cube by the subgroup of isometries of the `a_1\times a_2\cdots \times a_n` rectangular box where are the `a_i` are assumed to be distinct. - OUTPUT: - - set of Polyomino + OUTPUT: set of Polyomino EXAMPLES:: @@ -1006,11 +979,9 @@ def translated_copies(self, box): INPUT: - - ``box`` -- Polyomino or tuple of integers (size of a box) - - OUTPUT: + - ``box`` -- polyomino or tuple of integers (size of a box) - iterator of 3d polyominoes + OUTPUT: iterator of 3d polyominoes EXAMPLES:: @@ -1111,11 +1082,9 @@ def translated_copies_intersection(self, box): INPUT: - - ``box`` -- Polyomino or tuple of integers (size of a box) + - ``box`` -- polyomino or tuple of integers (size of a box) - OUTPUT: - - set of 3d polyominoes + OUTPUT: set of 3d polyominoes EXAMPLES:: @@ -1140,7 +1109,6 @@ def translated_copies_intersection(self, box): sage: sorted(sorted(a.frozenset()) ....: for a in p.translated_copies_intersection(b)) [[(0, 0)], [(0, 0), (1, 0)], [(0, 1)], [(0, 2)], [(1, 0), (2, 0)], [(2, 0)]] - """ if not isinstance(box, Polyomino): ranges = [range(a) for a in box] @@ -1171,13 +1139,13 @@ def isometric_copies(self, box, orientation_preserving=True, INPUT: - - ``box`` -- Polyomino or tuple of integers (size of a box) + - ``box`` -- polyomino or tuple of integers (size of a box) - - ``orientation_preserving`` -- bool (default: ``True``); - If ``True``, the group of isometries of the `n`-cube is restricted + - ``orientation_preserving`` -- boolean (default: ``True``); + if ``True``, the group of isometries of the `n`-cube is restricted to those that preserve the orientation, i.e. of determinant 1. - - ``mod_box_isometries`` -- bool (default: ``False``), whether to + - ``mod_box_isometries`` -- boolean (default: ``False``); whether to quotient the group of isometries of the `n`-cube by the subgroup of isometries of the `a_1\times a_2\cdots \times a_n` rectangular box where are the `a_i` are assumed to be distinct. @@ -1239,9 +1207,9 @@ def isometric_copies_intersection(self, box, orientation_preserving=True): INPUT: - - ``box`` -- Polyomino or tuple of integers (size of a box) + - ``box`` -- polyomino or tuple of integers (size of a box) - - ``orientation_preserving`` -- bool (default: ``True``); + - ``orientation_preserving`` -- boolean (default: ``True``); if ``True``, the group of isometries of the `n`-cube is restricted to those that preserve the orientation, i.e. of determinant 1. @@ -1263,7 +1231,6 @@ def isometric_copies_intersection(self, box, orientation_preserving=True): [(1, 1)], [(1, 1), (1, 2)], [(1, 2)]] - """ all_distinct_cano = self.canonical_isometric_copies(orientation_preserving, mod_box_isometries=False) @@ -1394,7 +1361,7 @@ def show3d(self, size=1): INPUT: - ``self`` -- a polyomino of dimension 3 - - ``size`` -- number (default: ``1``), the size of each + - ``size`` -- number (default: ``1``); the size of each ``1 \times 1 \times 1`` cube. This does a homothety with respect to the center of the polyomino. @@ -1424,12 +1391,9 @@ def show2d(self, size=0.7, color='black', thickness=1): INPUT: - ``self`` -- a polyomino of dimension 2 - - ``size`` -- number (default: ``0.7``), the size of each - square. - - ``color`` -- color (default: ``'black'``), color of - the boundary line. - - ``thickness`` -- number (default: ``1``), how thick the - boundary line is. + - ``size`` -- number (default: ``0.7``); the size of each square + - ``color`` -- color (default: ``'black'``); color of the boundary line + - ``thickness`` -- number (default: ``1``); how thick the boundary line is EXAMPLES:: @@ -1466,17 +1430,15 @@ def self_surrounding(self, radius, remove_incomplete_copies=True, - ``self`` -- a polyomino of dimension 2 - ``radius`` -- integer - - ``remove_incomplete_copies`` -- bool (default: ``True``), whether + - ``remove_incomplete_copies`` -- boolean (default: ``True``); whether to keep only complete copies of ``self`` in the output - - ``ncpus`` -- integer (default: ``None``), maximal number of + - ``ncpus`` -- integer (default: ``None``); maximal number of subprocesses to use at the same time. If ``None``, it detects the number of effective CPUs in the system using :func:`sage.parallel.ncpus.ncpus()`. If ``ncpus=1``, the first solution is searched serially. - OUTPUT: - - list of polyominoes + OUTPUT: list of polyominoes EXAMPLES:: @@ -1492,7 +1454,6 @@ def self_surrounding(self, radius, remove_incomplete_copies=True, sage: solution = H.self_surrounding(8, remove_incomplete_copies=False) sage: G = sum([p.show2d() for p in solution], Graphics()) # needs sage.plot - """ # Define the box to tile minxyz, maxxyz = self.bounding_box() @@ -1545,7 +1506,7 @@ def self_surrounding(self, radius, remove_incomplete_copies=True, ####################### class TilingSolver(SageObject): r""" - Tiling solver + Tiling solver. Solve the problem of tiling a polyomino with a certain number of polyominoes. @@ -1553,14 +1514,14 @@ class TilingSolver(SageObject): INPUT: - ``pieces`` -- iterable of Polyominoes - - ``box`` -- Polyomino or tuple of integers (size of a box) - - ``rotation`` -- bool (default: ``True``), whether to allow + - ``box`` -- polyomino or tuple of integers (size of a box) + - ``rotation`` -- boolean (default: ``True``); whether to allow rotations - - ``reflection`` -- bool (default: ``False``), whether to allow + - ``reflection`` -- boolean (default: ``False``); whether to allow reflections - - ``reusable`` -- bool (default: ``False``), whether to allow + - ``reusable`` -- boolean (default: ``False``); whether to allow the pieces to be reused - - ``outside`` -- bool (default: ``False``), whether to allow + - ``outside`` -- boolean (default: ``False``); whether to allow pieces to partially go outside of the box (all non-empty intersection of the pieces with the box are considered) @@ -1645,7 +1606,7 @@ def __init__(self, pieces, box, rotation=True, def _repr_(self): r""" - String representation + String representation. EXAMPLES:: @@ -1658,7 +1619,6 @@ def _repr_(self): Rotation allowed: True Reflection allowed: False Reusing pieces allowed: False - """ s = "Tiling solver of %s pieces " % len(self._pieces) s += "into a box of size %s\n" % len(self._box) @@ -1699,9 +1659,7 @@ def pieces(self): r""" Return the list of pieces. - OUTPUT: - - list of 3d polyominoes + OUTPUT: list of 3d polyominoes EXAMPLES:: @@ -1719,7 +1677,7 @@ def pieces(self): def space(self): r""" - Return an iterator over all the non negative integer coordinates + Return an iterator over all the nonnegative integer coordinates contained in the space to tile. EXAMPLES:: @@ -1739,9 +1697,7 @@ def coord_to_int_dict(self): r""" Return a dictionary mapping coordinates to integers. - OUTPUT: - - dict + OUTPUT: dictionary EXAMPLES:: @@ -1822,9 +1778,9 @@ def rows_for_piece(self, i, mod_box_isometries=False): INPUT: - - ``i`` -- integer, the `i`-th piece + - ``i`` -- integer; the `i`-th piece - - ``mod_box_isometries`` -- bool (default: ``False``), whether to + - ``mod_box_isometries`` -- boolean (default: ``False``); whether to consider only rows for positions up to the action of the quotient the group of isometries of the `n`-cube by the subgroup of isometries of the `a_1\times a_2\cdots \times a_n` @@ -1896,7 +1852,7 @@ def rows_for_piece(self, i, mod_box_isometries=False): @cached_method def rows(self): r""" - Creation of the rows + Creation of the rows. EXAMPLES:: @@ -1941,8 +1897,8 @@ def _rows_mod_box_isometries(self, i): INPUT: - - ``i`` -- integer, the `i`-th piece to consider, that piece must not - be isometric to itself by a isometry that preserve the box. + - ``i`` -- integer; the `i`-th piece to consider, that piece must not + be isometric to itself by a isometry that preserve the box EXAMPLES:: @@ -1984,7 +1940,7 @@ def _rows_mod_box_isometries(self, i): Dancing links solver for 96 columns and 5484 rows It is possible to avoid to compute 4 times each solution up to - rotations. This is done by choosing a piece (here the 0-th) and + rotations. This is done by choosing a piece (here the 0th) and considering 4 times less positions for that piece. To be precise, 90 positions instead of 360, therefore the dancing links solver below has 270 less rows:: @@ -2008,9 +1964,7 @@ def nrows_per_piece(self): r""" Return the number of rows necessary by each piece. - OUTPUT: - - list + OUTPUT: list EXAMPLES:: @@ -2049,11 +2003,9 @@ def row_to_polyomino(self, row_number): INPUT: - - ``row_number`` -- integer, the `i`-th row - - OUTPUT: + - ``row_number`` -- integer; the `i`-th row - polyomino + OUTPUT: polyomino EXAMPLES:: @@ -2079,8 +2031,8 @@ def row_to_polyomino(self, row_number): We check that issue :issue:`32252` is fixed and that colors of polyominoes are properly recovered:: - sage: v = Polyomino([(0, 0), (0, 1)], color="blue") - sage: h = Polyomino([(0, 0), (1, 0)], color="red") + sage: v = Polyomino([(0, 0), (0, 1)], color='blue') + sage: h = Polyomino([(0, 0), (1, 0)], color='red') sage: T = TilingSolver(pieces=[v, h], box=(2, 2), ....: rotation=False, reflection=False, reusable=True) sage: for i in range(4): print(i,T.row_to_polyomino(i)) @@ -2088,7 +2040,6 @@ def row_to_polyomino(self, row_number): 1 Polyomino: [(1, 0), (1, 1)], Color: blue 2 Polyomino: [(0, 0), (1, 0)], Color: red 3 Polyomino: [(0, 1), (1, 1)], Color: red - """ rows = self.rows() row = rows[row_number] @@ -2110,9 +2061,7 @@ def dlx_solver(self): r""" Return the sage DLX solver of that tiling problem. - OUTPUT: - - DLX Solver + OUTPUT: dLX Solver EXAMPLES:: @@ -2131,9 +2080,7 @@ def _dlx_solutions_iterator(self): r""" Return an iterator over the row indices of the solutions. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -2160,9 +2107,7 @@ def _dlx_common_prefix_solutions_iterator(self): The purpose is to illustrate the backtracking and construct an animation of the evolution of solutions. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -2229,9 +2174,7 @@ def _dlx_incremental_solutions_iterator(self): The purpose is to illustrate the backtracking and construct an animation of the evolution of solutions. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -2289,7 +2232,7 @@ def solve(self, partial=None): INPUT: - - ``partial`` -- string (default: ``None``), whether to + - ``partial`` -- string (default: ``None``); whether to include partial (incomplete) solutions. It can be one of the following: @@ -2297,9 +2240,7 @@ def solve(self, partial=None): - ``'common_prefix'`` -- common prefix between two consecutive solutions - ``'incremental'`` -- one piece change at a time - OUTPUT: - - iterator of list of polyominoes + OUTPUT: iterator of list of polyominoes EXAMPLES:: @@ -2363,7 +2304,6 @@ def solve(self, partial=None): Traceback (most recent call last): ... StopIteration - """ if not self.is_suitable(): return @@ -2382,9 +2322,7 @@ def number_of_solutions(self): r""" Return the number of distinct solutions. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -2416,7 +2354,7 @@ def animate(self, partial=None, stop=None, size=0.75, axes=False): INPUT: - - ``partial`` -- string (default: ``None``), whether to + - ``partial`` -- string (default: ``None``); whether to include partial (incomplete) solutions. It can be one of the following: @@ -2424,14 +2362,14 @@ def animate(self, partial=None, stop=None, size=0.75, axes=False): - ``'common_prefix'`` -- common prefix between two consecutive solutions - ``'incremental'`` -- one piece change at a time - - ``stop`` -- integer (default:``None``), number of frames + - ``stop`` -- integer (default: ``None``); number of frames - - ``size`` -- number (default: ``0.75``), the size of each + - ``size`` -- number (default: ``0.75``); the size of each ``1 \times 1`` square. This does a homothety with respect to the center of each polyomino. - - ``axes`` -- bool (default:``False``), whether the x and - y axes are shown. + - ``axes`` -- boolean (default: ``False``); whether the x and + y axes are shown EXAMPLES:: @@ -2461,7 +2399,7 @@ def animate(self, partial=None, stop=None, size=0.75, axes=False): The ``show`` function takes arguments to specify the delay between frames (measured in hundredths of a second, default value 20) and - the number of iterations (default value 0, which means to iterate + the number of iterations (default: 0, which means to iterate forever). To iterate 4 times with half a second between each frame:: sage: a.show(delay=50, iterations=4) # long time, optional - imagemagick, needs sage.plot diff --git a/src/sage/combinat/triangles_FHM.py b/src/sage/combinat/triangles_FHM.py index 6822f342658..c8248bdc5f2 100644 --- a/src/sage/combinat/triangles_FHM.py +++ b/src/sage/combinat/triangles_FHM.py @@ -7,7 +7,7 @@ invertible rational change-of-variables involving `x` and `y`. These polynomial are called triangles because their supports, the sets -of exponents where their coefficients can be non-zero, have a triangular shape. +of exponents where their coefficients can be nonzero, have a triangular shape. The M-triangle class is motivated by the generating series of Möbius numbers for graded posets. A typical example is:: @@ -60,7 +60,7 @@ def _matrix_display(self, variables=None): INPUT: - - ``variables`` -- optional choice of 2 variables + - ``variables`` -- (optional) choice of 2 variables OUPUT: @@ -381,16 +381,14 @@ def dual(self): A = self._poly.parent() dict_dual = {(n - dy, n - dx): coeff - for (dx, dy), coeff in self._poly.dict().items()} + for (dx, dy), coeff in self._poly.monomial_coefficients().items()} return M_triangle(A(dict_dual), variables=(x, y)) def transmute(self): """ Return the image of ``self`` by an involution. - OUTPUT: - - another M-triangle + OUTPUT: another M-triangle The involution is defined by converting to an H-triangle, transposing the matrix, and then converting back to an M-triangle. @@ -466,9 +464,7 @@ def transpose(self): """ Return the transposed H-triangle. - OUTPUT: - - another H-triangle + OUTPUT: another H-triangle This operation is an involution. When seen as a matrix, it performs a symmetry with respect to the northwest-southeast @@ -488,7 +484,7 @@ def transpose(self): A = self._poly.parent() dict_dual = {(n - dy, n - dx): coeff - for (dx, dy), coeff in self._poly.dict().items()} + for (dx, dy), coeff in self._poly.monomial_coefficients().items()} return H_triangle(A(dict_dual), variables=(x, y)) def m(self): diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 0da72d30dbf..ef77bf66d4e 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -461,7 +461,7 @@ sage: fraction = - R(Px) / R(Py); fraction # needs sage.symbolic (1/2/(x - 1/4))*ybar - 1/4/(x - 1/4) -.. note:: +.. NOTE:: The following variant does not work yet:: @@ -844,15 +844,15 @@ Partial orders on a set of `8` elements, up to isomorphism:: - sage: C = Posets(8); C - Posets containing 8 elements + sage: C = Posets(7); C + Posets containing 7 elements sage: C.cardinality() - 16999 + 2045 :: sage: C.unrank(20).plot() - Graphics object consisting of 20 graphics primitives + Graphics object consisting of ... graphics primitives .. image:: ../../media/a_poset.png @@ -1540,7 +1540,7 @@ These sets share the same underlying algorithmic structure, implemented in the more general (and slightly more cumbersome) class ``IntegerListsLex``. This class models sets of vectors -`(\ell_0,\dots,\ell_k)` of non-negative integers, with +`(\ell_0,\dots,\ell_k)` of nonnegative integers, with constraints on the sum and the length, and bounds on the parts and on the consecutive differences between the parts. Here are some more examples:: diff --git a/src/sage/combinat/vector_partition.py b/src/sage/combinat/vector_partition.py index 9e5f5ac9025..1f41c08d7af 100644 --- a/src/sage/combinat/vector_partition.py +++ b/src/sage/combinat/vector_partition.py @@ -36,7 +36,7 @@ def find_min(vect): INPUT: - - ``vec`` -- A list of integers + - ``vec`` -- list of integers OUTPUT: @@ -68,8 +68,8 @@ def IntegerVectorsIterator(vect, min=None): INPUT: - - ``vect`` -- A list of non-negative integers - - ``min`` -- A list of non-negative integers dominated elementwise by ``vect`` + - ``vect`` -- list of nonnegative integers + - ``min`` -- list of nonnegative integers dominated elementwise by ``vect`` OUTPUT: @@ -169,16 +169,18 @@ class VectorPartitions(UniqueRepresentation, Parent): Class of all vector partitions of ``vec`` with all parts greater than or equal to ``min`` in lexicographic order, with parts from ``parts``. - A vector partition of ``vec`` is a list of vectors with non-negative + A vector partition of ``vec`` is a list of vectors with nonnegative integer entries whose sum is ``vec``. INPUT: - - ``vec`` -- Integer vector - - ``min`` -- Integer vector dominated elementwise by ``vec`` - - ``parts`` -- Finite list of possible parts - - ``distinct`` -- Boolean, set to ``True`` if only vector partitions with distinct parts are enumerated - - ``is_repeatable`` -- Boolean function on ``parts`` which gives ``True`` in parts that can be repeated + - ``vec`` -- integer vector + - ``min`` -- integer vector dominated elementwise by ``vec`` + - ``parts`` -- finite list of possible parts + - ``distinct`` -- boolean, set to ``True`` if only vector partitions with + distinct parts are enumerated + - ``is_repeatable`` -- boolean function on ``parts`` which gives ``True`` + in parts that can be repeated EXAMPLES: @@ -238,7 +240,6 @@ class VectorPartitions(UniqueRepresentation, Parent): sage: Vector_Partitions = VectorPartitions([2,2], parts=[[0,1],[1,0],[1,1]], is_repeatable=lambda vec: sum(vec)%2!=0) sage: list(Vector_Partitions) [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]]] - """ @staticmethod def __classcall_private__(cls, vec, min=None, parts=None, distinct=False, is_repeatable=None): diff --git a/src/sage/combinat/words/abstract_word.py b/src/sage/combinat/words/abstract_word.py index 3c76c4d6de3..21d17ab759f 100644 --- a/src/sage/combinat/words/abstract_word.py +++ b/src/sage/combinat/words/abstract_word.py @@ -44,11 +44,11 @@ class Word_class(SageObject): def parent(self): r""" - Returns the parent of self. + Return the parent of ``self``. TESTS:: - sage: Word(iter([1,2,3]), length="unknown").parent() + sage: Word(iter([1,2,3]), length='unknown').parent() Finite words over Set of Python objects of class 'object' sage: Word(range(12)).parent() Finite words over Set of Python objects of class 'object' @@ -61,13 +61,13 @@ def parent(self): def _repr_(self): r""" - Returns a string representation of self. + Return a string representation of ``self``. TESTS:: - sage: Word(iter([1,2,3]), length="unknown")._repr_() + sage: Word(iter([1,2,3]), length='unknown')._repr_() 'word: 123' - sage: Word(range(100), length="unknown")._repr_() + sage: Word(range(100), length='unknown')._repr_() 'word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...' sage: Word(lambda x:x%3)._repr_() 'word: 0120120120120120120120120120120120120120...' @@ -78,7 +78,7 @@ def _repr_(self): def string_rep(self): r""" - Returns the (truncated) raw sequence of letters as a string. + Return the (truncated) raw sequence of letters as a string. EXAMPLES:: @@ -157,21 +157,21 @@ def __iter__(self): def length(self): r""" - Returns the length of self. + Return the length of ``self``. TESTS:: sage: from sage.combinat.words.word import Word_class - sage: w = Word(iter('abba'*100), length="unknown") + sage: w = Word(iter('abba'*100), length='unknown') sage: w.length() is None True - sage: w = Word(iter('abba'), length="finite") + sage: w = Word(iter('abba'), length='finite') sage: w.length() 4 - sage: w = Word(iter([0,1,1,0,1,0,0,1]*100), length="unknown") + sage: w = Word(iter([0,1,1,0,1,0,0,1]*100), length='unknown') sage: w.length() is None True - sage: w = Word(iter([0,1,1,0,1,0,0,1]), length="finite") + sage: w = Word(iter([0,1,1,0,1,0,0,1]), length='finite') sage: w.length() 8 """ @@ -179,7 +179,7 @@ def length(self): def is_finite(self): r""" - Returns whether this word is known to be finite. + Return whether this word is known to be finite. .. WARNING:: @@ -201,22 +201,19 @@ def is_finite(self): sage: w = Word(iter('a'*100)) sage: w.is_finite() False - """ return False def __len__(self): r""" - Return the length of self (as a python integer). + Return the length of ``self`` (as a Python integer). .. NOTE:: For infinite words or words of unknown length, use `length()` method instead. - OUTPUT: - - positive integer + OUTPUT: positive integer EXAMPLES:: @@ -375,26 +372,24 @@ def __richcmp__(self, other, op): def _longest_common_prefix_iterator(self, other): r""" - Return an iterator of the longest common prefix of self and other. + Return an iterator of the longest common prefix of ``self`` and ``other``. INPUT: - - ``other`` -- word - - OUTPUT: + - ``other`` -- word - iterator + OUTPUT: iterator EXAMPLES:: sage: f = words.FibonacciWord() sage: it = f._longest_common_prefix_iterator(f) - sage: w = Word(it, length="unknown"); w + sage: w = Word(it, length='unknown'); w word: 0100101001001010010100100101001001010010... sage: w[:6] word: 010010 sage: it = w._longest_common_prefix_iterator(w[:10]) - sage: w = Word(it, length="finite"); w + sage: w = Word(it, length='finite'); w word: 0100101001 """ for (b, c) in zip(self, other): @@ -405,19 +400,19 @@ def _longest_common_prefix_iterator(self, other): def longest_common_prefix(self, other, length='unknown'): r""" - Returns the longest common prefix of self and other. + Return the longest common prefix of ``self`` and ``other``. INPUT: - - ``other`` -- word + - ``other`` -- word - - ``length`` -- string (default: ``'unknown'``) - the length type of the resulting word if known. It may be one of - the following: + - ``length`` -- string (default: ``'unknown'``) + the length type of the resulting word if known. It may be one of + the following: - - ``'unknown'`` - - ``'finite'`` - - ``'infinite'`` + - ``'unknown'`` + - ``'finite'`` + - ``'infinite'`` EXAMPLES:: @@ -501,16 +496,14 @@ def longest_common_prefix(self, other, length='unknown'): def _longest_periodic_prefix_iterator(self, period=1): r""" - Returns an iterator of the longest prefix of self having the given + Return an iterator of the longest prefix of ``self`` having the given period. INPUT: - ``period`` -- positive integer (default: 1) - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -537,15 +530,13 @@ def _longest_periodic_prefix_iterator(self, period=1): def longest_periodic_prefix(self, period=1): r""" - Returns the longest prefix of self having the given period. + Return the longest prefix of ``self`` having the given period. INPUT: - ``period`` -- positive integer (default: 1) - OUTPUT: - - word + OUTPUT: word EXAMPLES:: @@ -573,7 +564,7 @@ def longest_periodic_prefix(self, period=1): def is_empty(self): r""" - Returns True if the length of self is zero, and False otherwise. + Return ``True`` if the length of ``self`` is zero, and ``False`` otherwise. EXAMPLES:: @@ -595,15 +586,15 @@ def is_empty(self): def _to_integer_iterator(self, use_parent_alphabet=False): r""" - Returns an iterator over the letters of an integer representation of - self. + Return an iterator over the letters of an integer representation of + ``self``. INPUT: - - ``use_parent_alphabet`` -- Bool (default: ``False``). When True and if - the self parent's alphabet is finite, it uses the index of + - ``use_parent_alphabet`` -- boolean (default: ``False``); when ``True`` + and if the ``self`` parent's alphabet is finite, it uses the index of the letters in the alphabet. Otherwise, the first letter occurring in - self is mapped to zero, and every letter that hasn't yet occurred in + ``self`` is mapped to zero, and every letter that hasn't yet occurred in the word is mapped to the next available integer. EXAMPLES:: @@ -648,7 +639,7 @@ def _to_integer_iterator(self, use_parent_alphabet=False): def to_integer_word(self): r""" - Returns a word over the integers whose letters are those output by + Return a word over the integers whose letters are those output by self._to_integer_iterator() EXAMPLES:: @@ -658,11 +649,11 @@ def to_integer_word(self): word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,... sage: w.to_integer_word() word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,... - sage: w = Word(iter("abbacabba"), length="finite"); w + sage: w = Word(iter("abbacabba"), length='finite'); w word: abbacabba sage: w.to_integer_word() word: 011020110 - sage: w = Word(iter("abbacabba"), length="unknown"); w + sage: w = Word(iter("abbacabba"), length='unknown'); w word: abbacabba sage: w.to_integer_word() word: 011020110 @@ -673,7 +664,7 @@ def to_integer_word(self): def lex_less(self, other): r""" - Returns True if self is lexicographically less than other. + Return ``True`` if ``self`` is lexicographically less than ``other``. EXAMPLES:: @@ -703,7 +694,7 @@ def lex_less(self, other): def lex_greater(self, other): r""" - Returns True if self is lexicographically greater than other. + Return ``True`` if ``self`` is lexicographically greater than ``other``. EXAMPLES:: @@ -733,12 +724,12 @@ def lex_greater(self, other): def apply_morphism(self, morphism): r""" - Returns the word obtained by applying the morphism to self. + Return the word obtained by applying the morphism to ``self``. INPUT: - - ``morphism`` -- Can be an instance of WordMorphism, or - anything that can be used to construct one. + - ``morphism`` -- can be an instance of WordMorphism, or + anything that can be used to construct one EXAMPLES:: @@ -772,13 +763,11 @@ def apply_morphism(self, morphism): def _delta_iterator(self): r""" - Returns an iterator of the image of self under the delta morphism. + Return an iterator of the image of ``self`` under the delta morphism. This is the word composed of the length of consecutive runs of the same letter in a given word. - OUTPUT: - - generator object + OUTPUT: generator object EXAMPLES:: @@ -803,14 +792,12 @@ def _delta_iterator(self): def delta(self): r""" - Returns the image of self under the delta morphism. + Return the image of ``self`` under the delta morphism. This is the word composed of the length of consecutive runs of the same letter in a given word. - OUTPUT: - - Word over integers + OUTPUT: word over integers EXAMPLES: @@ -838,16 +825,14 @@ def delta(self): def _iterated_right_palindromic_closure_iterator(self, f=None): r""" - Returns an iterator over the iterated (`f`-)palindromic closure of self. + Return an iterator over the iterated (`f`-)palindromic closure of ``self``. INPUT: - - ``f`` -- involution (default: None) on the alphabet of self. It must - be callable on letters as well as words (e.g. WordMorphism). - - OUTPUT: + - ``f`` -- involution on the alphabet of ``self`` (default: ``None``); + it must be callable on letters as well as words (e.g. WordMorphism) - iterator -- the iterated (`f`-)palindromic closure of self + OUTPUT: iterator; the iterated (`f`-)palindromic closure of ``self`` EXAMPLES:: @@ -904,16 +889,14 @@ def _iterated_right_palindromic_closure_iterator(self, f=None): def _iterated_right_palindromic_closure_recursive_iterator(self, f=None): r""" - Returns an iterator over the iterated (`f`-)palindromic closure of self. + Return an iterator over the iterated (`f`-)palindromic closure of ``self``. INPUT: - - ``f`` -- involution (default: None) on the alphabet of self. It must - be callable on letters as well as words (e.g. WordMorphism). + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. WordMorphism) - OUTPUT: - - iterator -- the iterated (`f`-)palindromic closure of self + OUTPUT: iterator; the iterated (`f`-)palindromic closure of ``self`` ALGORITHM: @@ -994,26 +977,24 @@ def _iterated_right_palindromic_closure_recursive_iterator(self, f=None): def iterated_right_palindromic_closure(self, f=None, algorithm='recursive'): r""" - Returns the iterated (`f`-)palindromic closure of self. + Return the iterated (`f`-)palindromic closure of ``self``. INPUT: - - ``f`` -- involution (default: None) on the alphabet of self. It must - be callable on letters as well as words (e.g. WordMorphism). - - - ``algorithm`` -- string (default: ``'recursive'``) specifying which - algorithm to be used when computing the iterated palindromic closure. - It must be one of the two following values: + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. WordMorphism) - - ``'definition'`` -- computed using the definition - - ``'recursive'`` -- computation based on an efficient formula - that recursively computes the iterated right palindromic closure - without having to recompute the longest `f`-palindromic suffix - at each iteration [2]. + - ``algorithm`` -- string (default: ``'recursive'``); specifying which + algorithm to be used when computing the iterated palindromic closure. + It must be one of the two following values: - OUTPUT: + - ``'definition'`` -- computed using the definition + - ``'recursive'`` -- computation based on an efficient formula + that recursively computes the iterated right palindromic closure + without having to recompute the longest `f`-palindromic suffix + at each iteration [2]. - word -- the iterated (`f`-)palindromic closure of self + OUTPUT: word; the iterated (`f`-)palindromic closure of ``self`` EXAMPLES:: @@ -1111,16 +1092,14 @@ def iterated_right_palindromic_closure(self, f=None, algorithm='recursive'): def prefixes_iterator(self, max_length=None): r""" - Returns an iterator over the prefixes of self. + Return an iterator over the prefixes of ``self``. INPUT: - - ``max_length`` -- non negative integer or None (optional, - default: None) the maximum length of the prefixes + - ``max_length`` -- nonnegative integer or ``None`` (default); the + maximum length of the prefixes - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -1165,16 +1144,14 @@ def prefixes_iterator(self, max_length=None): def palindrome_prefixes_iterator(self, max_length=None): r""" - Returns an iterator over the palindrome prefixes of self. + Return an iterator over the palindrome prefixes of ``self``. INPUT: - - ``max_length`` -- non negative integer or None (optional, - default: None) the maximum length of the prefixes - - OUTPUT: + - ``max_length`` -- nonnegative integer or ``None`` (default); the + maximum length of the prefixes - iterator + OUTPUT: iterator EXAMPLES:: @@ -1206,13 +1183,13 @@ def palindrome_prefixes_iterator(self, max_length=None): def _partial_sums_iterator(self, start, mod=None): r""" - Iterator over the partial sums of the prefixes of self. + Iterator over the partial sums of the prefixes of ``self``. INPUT: - - ``self`` -- A word over the integers. - - ``start`` -- integer, the first letter of the resulting word. - - ``mod`` -- (default: None) It can be one of the following: + - ``self`` -- a word over the integers + - ``start`` -- integer; the first letter of the resulting word + - ``mod`` -- (default: ``None``) it can be one of the following: - None or 0 : result is over the integers - integer : result is over the integers modulo ``mod``. @@ -1233,7 +1210,6 @@ def _partial_sums_iterator(self, start, mod=None): sage: w = Word([1,1,1,1,1,1,1,1,1,1,1,1]) sage: list(w._partial_sums_iterator(0)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - """ if mod in (None, 0): sum = start @@ -1252,13 +1228,13 @@ def _partial_sums_iterator(self, start, mod=None): def partial_sums(self, start, mod=None): r""" - Returns the word defined by the partial sums of its prefixes. + Return the word defined by the partial sums of its prefixes. INPUT: - - ``self`` -- A word over the integers. - - ``start`` -- integer, the first letter of the resulting word. - - ``mod`` -- (default: None) It can be one of the following: + - ``self`` -- a word over the integers + - ``start`` -- integer; the first letter of the resulting word + - ``mod`` -- (default: ``None``) it can be one of the following: - None or 0 : result is over the integers - integer : result is over the integers modulo ``mod``. @@ -1317,8 +1293,8 @@ def _finite_differences_iterator(self, mod=None): INPUT: - - ``self`` -- A word over the integers. - - ``mod`` -- (default: None) It can be one of the following: + - ``self`` -- a word over the integers + - ``mod`` -- (default: ``None``) it can be one of the following: - None or 0 : result is over the integers - integer : result is over the integers modulo ``mod``. @@ -1393,8 +1369,8 @@ def finite_differences(self, mod=None): INPUT: - - ``self`` -- A word over the integers. - - ``mod`` -- (default: None) It can be one of the following: + - ``self`` -- a word over the integers + - ``mod`` -- (default: ``None``) it can be one of the following: - None or 0 : result is over the integers - integer : result is over the integers modulo ``mod``. @@ -1455,16 +1431,14 @@ def sum_digits(self, base=2, mod=None): INPUT: - - ``self`` -- word over natural numbers - - - ``base`` -- integer (default : 2), greater or equal to 2 - - - ``mod`` -- modulo (default: ``None``), can take the following - values: + - ``self`` -- word over natural numbers - - integer -- the modulo + - ``base`` -- integer (default: 2) greater or equal to 2 - - ``None`` -- the value ``base`` is considered for the modulo. + - ``mod`` -- modulo (default: ``None``); can take the following + values: + - ``integer`` -- the modulo + - ``None`` -- the value ``base`` is considered for the modulo EXAMPLES: @@ -1555,11 +1529,9 @@ def first_occurrence(self, other, start=0): INPUT: - ``other`` -- a finite word - - ``start`` -- integer (default:``0``), where the search starts + - ``start`` -- integer (default: `0`) where the search starts - OUTPUT: - - integer or ``None`` + OUTPUT: integer or ``None`` EXAMPLES:: @@ -1616,16 +1588,14 @@ def first_occurrence(self, other, start=0): def factor_occurrences_iterator(self, fact): r""" - Returns an iterator over all occurrences (including overlapping ones) - of fact in self in their order of appearance. + Return an iterator over all occurrences (including overlapping ones) + of fact in ``self`` in their order of appearance. INPUT: - ``fact`` -- a non empty finite word - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -1657,16 +1627,14 @@ def factor_occurrences_iterator(self, fact): def return_words_iterator(self, fact): r""" - Returns an iterator over all the return words of fact in self + Return an iterator over all the return words of fact in self (without unicity). INPUT: - ``fact`` -- a non empty finite word - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -1705,8 +1673,8 @@ def return_words_iterator(self, fact): def complete_return_words_iterator(self, fact): r""" - Returns an iterator over all the complete return words of fact in - self (without unicity). + Return an iterator over all the complete return words of fact in + ``self`` (without unicity). A complete return words `u` of a factor `v` is a factor starting by the given factor `v` and ending just after the next occurrence @@ -1716,9 +1684,7 @@ def complete_return_words_iterator(self, fact): - ``fact`` -- a non empty finite word - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index 19ac17054b8..4c899084eff 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -14,11 +14,11 @@ {'a', 'b'} sage: build_alphabet([0,1,2]) {0, 1, 2} - sage: build_alphabet(name="PP") + sage: build_alphabet(name='PP') Positive integers - sage: build_alphabet(name="NN") + sage: build_alphabet(name='NN') Non negative integers - sage: build_alphabet(name="lower") + sage: build_alphabet(name='lower') {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} """ # **************************************************************************** @@ -80,8 +80,8 @@ def build_alphabet(data=None, names=None, name=None): punctuation'`` represents the union of the two alphabets ``'lower'`` and ``'punctuation'``. - Alternatively, ``name`` can be set to ``"positive integers"`` (or - ``"PP"``) or ``"natural numbers"`` (or ``"NN"``). + Alternatively, ``name`` can be set to ``'positive integers'`` (or + ``'PP'``) or ``'natural numbers'`` (or ``'NN'``). ``name`` cannot be combined with ``data``. @@ -124,7 +124,7 @@ def build_alphabet(data=None, names=None, name=None): sage: build_alphabet(name="positive integers") Positive integers - sage: build_alphabet(name="PP") + sage: build_alphabet(name='PP') Positive integers sage: build_alphabet(name="natural numbers") Non negative integers @@ -136,9 +136,9 @@ def build_alphabet(data=None, names=None, name=None): 'decimal', 'hexadecimal', 'radix64' which refer to standard set of characters. Theses names may be combined by separating them by a space:: - sage: build_alphabet(name="lower") + sage: build_alphabet(name='lower') {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} - sage: build_alphabet(name="hexadecimal") + sage: build_alphabet(name='hexadecimal') {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} sage: build_alphabet(name="decimal punctuation") {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', ',', '.', ';', ':', '!', '?'} @@ -183,7 +183,7 @@ def build_alphabet(data=None, names=None, name=None): TESTS:: - sage: Alphabet(3, name="punctuation") + sage: Alphabet(3, name='punctuation') Traceback (most recent call last): ... ValueError: name cannot be specified with any other argument @@ -195,7 +195,7 @@ def build_alphabet(data=None, names=None, name=None): Traceback (most recent call last): ... ValueError: invalid value for names - sage: Alphabet(name=x, names="punctuation") # needs sage.symbolic + sage: Alphabet(name=x, names='punctuation') # needs sage.symbolic Traceback (most recent call last): ... ValueError: name cannot be specified with any other argument diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 8cc01a3c085..23e02ad61fb 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -307,7 +307,7 @@ def coerce(self, other): Otherwise it will attempt to convert ``other`` to the domain of ``self``. If that fails, it will attempt to convert ``self`` to the domain of - ``other``. If both attempts fail, it raises a :class:`TypeError` + ``other``. If both attempts fail, it raises a :exc:`TypeError` to signal failure. EXAMPLES:: @@ -436,19 +436,17 @@ def __pow__(self, exp): Return the ``exp``-th power of ``self``. If ``exp`` is `\infty`, returns the infinite periodic word of base ``self``. - Otherwise, `|w|\cdot exp` must be a non-negative integer. + Otherwise, `|w|\cdot exp` must be a nonnegative integer. INPUT: - - ``exp`` -- an integer, a rational, a float number or plus infinity + - ``exp`` -- integer; a rational, a float number or plus infinity - OUTPUT: - - word -- the ``exp``-th power of ``self`` + OUTPUT: word; the ``exp``-th power of ``self`` EXAMPLES: - You can take non-negative integer powers:: + You can take nonnegative integer powers:: sage: w = Word(range(6)); w word: 012345 @@ -464,7 +462,7 @@ def __pow__(self, exp): ValueError: Power of the word is not defined on the exponent -1: the length of the word (6) times the exponent (-1) must be a positive integer - You can take non-negative rational powers:: + You can take nonnegative rational powers:: sage: w = Word(range(6)); w word: 012345 @@ -525,7 +523,7 @@ def length(self): TESTS:: sage: from sage.combinat.words.word import Word_class - sage: w = Word(iter('abba'*40), length="finite") + sage: w = Word(iter('abba'*40), length='finite') sage: w._len is None True sage: w.length() @@ -554,10 +552,8 @@ def content(self, n=None): - ``n`` -- (optional) an integer specifying the maximal letter in the alphabet - OUTPUT: - - - a list where the `i`-th entry indicates the multiplicity - of the `i`-th letter in the alphabet in ``self`` + OUTPUT: list where the `i`-th entry indicates the multiplicity + of the `i`-th letter in the alphabet in ``self`` EXAMPLES:: @@ -643,11 +639,9 @@ def schuetzenberger_involution(self, n=None): INPUT: - ``self`` -- a word - - ``n`` -- an integer specifying the maximal letter in the alphabet (optional) + - ``n`` -- integer specifying the maximal letter in the alphabet (optional) - OUTPUT: - - a word, the Schützenberger involution of ``self`` + OUTPUT: a word, the Schützenberger involution of ``self`` EXAMPLES:: @@ -842,7 +836,7 @@ def to_integer_word(self): sage: w = Word('abbabaab') sage: w.to_integer_word() word: 01101001 - sage: w = Word(iter("cacao"), length="finite") + sage: w = Word(iter("cacao"), length='finite') sage: w.to_integer_word() word: 10102 @@ -864,7 +858,7 @@ def to_integer_list(self): sage: w = Word('abbabaab') sage: w.to_integer_list() [0, 1, 1, 0, 1, 0, 0, 1] - sage: w = Word(iter("cacao"), length="finite") + sage: w = Word(iter("cacao"), length='finite') sage: w.to_integer_list() [1, 0, 1, 0, 2] sage: w = Words([3,2,1])([2,3,3,1]) @@ -946,7 +940,7 @@ def has_suffix(self, other): """ Test whether ``self`` has ``other`` as a suffix. - .. note:: + .. NOTE:: Some word datatype classes, like :class:`WordDatatype_str`, override this method. @@ -955,9 +949,7 @@ def has_suffix(self, other): - ``other`` -- a word, or data describing a word - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -980,7 +972,6 @@ def has_suffix(self, other): False sage: u.has_suffix([0,1,0,1,0]) True - """ from sage.combinat.words.word import Word w = Word(other) @@ -1034,9 +1025,7 @@ def has_prefix(self, other): - ``other`` -- a word, or data describing a word - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -1059,8 +1048,6 @@ def has_prefix(self, other): False sage: u.has_prefix([0,1,1,0,1]) True - - """ from sage.combinat.words.word import Word w = Word(other) @@ -1123,8 +1110,7 @@ def good_suffix_table(self): res = [l - p[-1]]*(l+1) for i in range(1, l+1): j = l - p[i - 1] - if res[j] > (i - p[i-1]): - res[j] = i - p[i-1] + res[j] = min(res[j], i - p[i-1]) return res @cached_method @@ -1200,8 +1186,8 @@ def number_of_factors(self, n=None, algorithm='suffix tree'): INPUT: - - ``n`` -- an integer, or ``None``. - - ``algorithm`` -- string (default: ``'suffix tree'``), takes the + - ``n`` -- integer or ``None`` + - ``algorithm`` -- string (default: ``'suffix tree'``); takes the following values: - ``'suffix tree'`` -- construct and use the suffix tree of the word @@ -1269,7 +1255,7 @@ def factor_iterator(self, n=None): INPUT: - - ``n`` -- an integer, or ``None``. + - ``n`` -- integer or ``None`` OUTPUT: @@ -1340,7 +1326,7 @@ def factor_complexity(self, n): INPUT: - - ``n`` -- the length of the factors. + - ``n`` -- the length of the factors EXAMPLES:: @@ -1362,7 +1348,7 @@ def factor_set(self, n=None, algorithm='suffix tree'): INPUT: - - ``n`` -- an integer or ``None`` (default: ``None``). + - ``n`` -- integer or ``None`` (default: ``None``) - ``algorithm`` -- string (default: ``'suffix tree'``), takes the following values: @@ -1453,11 +1439,9 @@ def topological_entropy(self, n): INPUT: - ``self`` -- a word defined over a finite alphabet - - ``n`` -- positive integer - - OUTPUT: + - ``n`` -- positive integer - real number (a symbolic expression) + OUTPUT: real number (a symbolic expression) EXAMPLES:: @@ -1592,12 +1576,10 @@ def reduced_rauzy_graph(self, n): INPUT: - - ``n`` -- a non-negative integer. Every vertex of a reduced - Rauzy graph of order ``n`` is a factor of length ``n`` of ``self``. - - OUTPUT: + - ``n`` -- nonnegative integer; every vertex of a reduced + Rauzy graph of order ``n`` is a factor of length ``n`` of ``self`` - a looped multi-digraph + OUTPUT: a looped multi-digraph DEFINITION: @@ -1609,7 +1591,7 @@ def reduced_rauzy_graph(self, n): where `w` is the unique return word to `p`. In other cases, it is the directed graph defined as followed. Let - `G_n` be the Rauzy graph of order `n` of self. The vertices are the + `G_n` be the Rauzy graph of order `n` of ``self``. The vertices are the vertices of `G_n` that are either special or not prolongable to the right or to the left. For each couple (`u`, `v`) of such vertices and each directed path in `G_n` from `u` to `v` that contains no @@ -1686,7 +1668,6 @@ def reduced_rauzy_graph(self, n): AUTHOR: Julien Leroy (March 2010): initial version - """ from sage.graphs.digraph import DiGraph from copy import copy @@ -1719,8 +1700,8 @@ def left_special_factors_iterator(self, n=None): INPUT: - - ``n`` -- integer (default: ``None``). If ``None``, it returns - an iterator over all left special factors. + - ``n`` -- integer (default: ``None``); if ``None``, it returns + an iterator over all left special factors EXAMPLES:: @@ -1755,12 +1736,10 @@ def left_special_factors(self, n=None): INPUT: - - ``n`` -- integer (default: ``None``). If ``None``, it - returns all left special factors. + - ``n`` -- integer (default: ``None``); if ``None``, it + returns all left special factors - OUTPUT: - - a list of words + OUTPUT: list of words EXAMPLES:: @@ -1786,8 +1765,8 @@ def right_special_factors_iterator(self, n=None): INPUT: - - ``n`` -- integer (default: ``None``). If ``None``, it returns - an iterator over all right special factors. + - ``n`` -- integer (default: ``None``); if ``None``, it returns + an iterator over all right special factors EXAMPLES:: @@ -1822,12 +1801,10 @@ def right_special_factors(self, n=None): INPUT: - - ``n`` -- integer (default: ``None``). If ``None``, it returns - all right special factors. - - OUTPUT: + - ``n`` -- integer (default: ``None``); if ``None``, it returns + all right special factors - a list of words + OUTPUT: list of words EXAMPLES:: @@ -1851,8 +1828,8 @@ def bispecial_factors_iterator(self, n=None): INPUT: - - ``n`` -- integer (default: ``None``). If ``None``, it returns - an iterator over all bispecial factors. + - ``n`` -- integer (default: ``None``); if ``None``, it returns + an iterator over all bispecial factors EXAMPLES:: @@ -1914,12 +1891,10 @@ def bispecial_factors(self, n=None): INPUT: - - ``n`` -- integer (default: ``None``). If ``None``, it returns - all bispecial factors. + - ``n`` -- integer (default: ``None``); if ``None``, it returns + all bispecial factors - OUTPUT: - - a list of words + OUTPUT: list of words EXAMPLES:: @@ -1947,7 +1922,7 @@ def bispecial_factors(self, n=None): def number_of_left_special_factors(self, n): r""" - Return the number of left special factors of length ``n``. + Return the number of left special factors of length `n`. A factor `u` of a word `w` is *left special* if there are two distinct letters `a` and `b` such that `au` and `bu` @@ -1957,9 +1932,7 @@ def number_of_left_special_factors(self, n): - ``n`` -- integer - OUTPUT: - - a non-negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -1988,9 +1961,7 @@ def number_of_right_special_factors(self, n): - ``n`` -- integer - OUTPUT: - - a non-negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -2153,9 +2124,7 @@ def is_conjugate_with(self, other): - ``other`` -- a finite word - OUTPUT: - - bool + OUTPUT: boolean EXAMPLES:: @@ -2272,7 +2241,6 @@ def longest_forward_extension(self, x, y): Traceback (most recent call last): ... ValueError: x and y must be valid positions in self - """ length = self.length() if not (-length <= x < length and -length <= y < length): @@ -2522,14 +2490,12 @@ def lps(self, f=None, l=None): INPUT: - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. - It must be callable on letters as well as words (e.g. ``WordMorphism``). - - ``l`` -- integer (default: ``None``) the length of the longest - palindrome suffix of ````self[:-1]````, if known. - - OUTPUT: + It must be callable on letters as well as words (e.g. ``WordMorphism``) + - ``l`` -- integer (default: ``None``); the length of the longest + palindrome suffix of ``self[:-1]``, if known - word -- If ``f`` is ``None``, the longest palindromic suffix of ``self``; - otherwise, the longest ``f``-palindromic suffix of ``self``. + OUTPUT: word; if ``f`` is ``None``, the longest palindromic suffix of + ``self``. Otherwise, the longest ``f``-palindromic suffix of ``self``. EXAMPLES:: @@ -2706,9 +2672,7 @@ def lacunas(self, f=None): default value corresponds to usual palindromes, i.e., ``f`` equal to the identity. - OUTPUT: - - a list -- list of all the lacunas of self + OUTPUT: list of all the lacunas of self EXAMPLES:: @@ -2770,19 +2734,17 @@ def length_maximal_palindrome(self, j, m=None, f=None): INPUT: - - ``j`` -- rational, position of the symmetry axis of the palindrome. + - ``j`` -- rational; position of the symmetry axis of the palindrome. Must return an integer when doubled. It is an integer when the center of the palindrome is a letter. - - ``m`` -- integer (default: ``None``), minimal length of palindrome, if known. + - ``m`` -- integer (default: ``None``); minimal length of palindrome, if known. The parity of ``m`` can't be the same as the parity of ``2j``. - - ``f`` -- involution (default: ``None``), on the alphabet. It must be - callable on letters as well as words (e.g. ``WordMorphism``). - - OUTPUT: + - ``f`` -- involution (default: ``None``) on the alphabet; it must be + callable on letters as well as words (e.g. ``WordMorphism``) - length of the longest ``f``-palindrome centered at position ``j`` + OUTPUT: length of the longest ``f``-palindrome centered at position ``j`` EXAMPLES:: @@ -2829,7 +2791,6 @@ def length_maximal_palindrome(self, j, m=None, f=None): ... ValueError: (2*j-m-1)/2(=15/2) must be an integer, i.e., 2*j(=19) and m(=3) can't have the same parity - """ # Ensure `f` is an involutory word morphism if f is not None: @@ -2874,13 +2835,12 @@ def lengths_maximal_palindromes(self, f=None): INPUT: - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. It must - be callable on letters as well as words (e.g. ``WordMorphism``). - - OUTPUT: + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. + ``WordMorphism``) - a list -- The length of the maximal palindrome (or ``f``-palindrome) - with a given symmetry axis (letter or space between two letters). + OUTPUT: list; the length of the maximal palindrome (or ``f``-palindrome) + with a given symmetry axis (letter or space between two letters) EXAMPLES:: @@ -2938,13 +2898,12 @@ def lps_lengths(self, f=None): INPUT: - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. It must - be callable on letters as well as words (e.g. ``WordMorphism``). - - OUTPUT: + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. + It must be callable on letters as well as words (e.g. + ``WordMorphism``). - a list -- The length of the longest palindromic (or ``f``-palindromic) - suffix of each prefix of ``self``. + OUTPUT: list; the length of the longest palindromic (or + ``f``-palindromic) suffix of each prefix of ``self`` EXAMPLES:: @@ -2979,13 +2938,12 @@ def palindromes(self, f=None): INPUT: - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. It must - be callable on letters as well as words (e.g. ``WordMorphism``). - - OUTPUT: + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. ``WordMorphism``). - a set -- If ``f`` is ``None``, the set of all palindromic factors of ``self``; - otherwise, the set of all ``f``-palindromic factors of ``self``. + OUTPUT: a set -- If ``f`` is ``None``, the set of all palindromic + factors of ``self``; otherwise, the set of all ``f``-palindromic + factors of ``self`` EXAMPLES:: @@ -3012,7 +2970,7 @@ def palindromic_complexity(self, n): INPUT: - - ``n`` -- the length of the factors. + - ``n`` -- the length of the factors EXAMPLES:: @@ -3032,10 +2990,6 @@ def palindrome_prefixes(self): r""" Return a list of all palindrome prefixes of ``self``. - OUTPUT: - - a list -- A list of all palindrome prefixes of ``self``. - EXAMPLES:: sage: w = Word('abaaba') @@ -3176,8 +3130,8 @@ def is_full(self, f=None): INPUT: - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. It must - be callable on letters as well as words (e.g. ``WordMorphism``). + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. ``WordMorphism``) OUTPUT: @@ -3243,8 +3197,8 @@ def palindromic_closure(self, side='right', f=None): - ``side`` -- ``'right'`` or ``'left'`` (default: ``'right'``) the direction of the closure - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. - It must be callable on letters as well as words (e.g. ``WordMorphism``). + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. ``WordMorphism``) OUTPUT: @@ -3319,8 +3273,8 @@ def is_symmetric(self, f=None): INPUT: - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. It must - be callable on letters as well as words (e.g. ``WordMorphism``). + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. ``WordMorphism``) EXAMPLES:: @@ -3420,9 +3374,7 @@ def order(self): Let `p(w)` be the period of a word `w`. The positive rational number `|w|/p(w)` is the *order* of `w`. See Chapter 8 of [Lot2002]_. - OUTPUT: - - rational -- the order + OUTPUT: rational; the order EXAMPLES:: @@ -3502,8 +3454,7 @@ def critical_exponent(self): current_pos = k-j+l-1 pft[current_pos] = m current_exp = QQ((current_pos+1, current_pos+1-m)) - if current_exp > best_exp: - best_exp = current_exp + best_exp = max(current_exp, best_exp) for ((i, j), u) in st._transition_function[v].items(): if j is None: j = self.length() @@ -3583,9 +3534,7 @@ def exponent(self): r""" Return the exponent of ``self``. - OUTPUT: - - integer -- the exponent + OUTPUT: integer; the exponent EXAMPLES:: @@ -3602,7 +3551,7 @@ def exponent(self): def has_period(self, p): r""" - Return ``True`` if ``self`` has the period ``p``, + Return ``True`` if ``self`` has the period `p`, ``False`` otherwise. .. NOTE:: @@ -3612,8 +3561,8 @@ def has_period(self, p): INPUT: - - ``p`` -- an integer to check if it is a period - of ``self``. + - ``p`` -- integer to check if it is a period + of ``self`` EXAMPLES:: @@ -3649,13 +3598,11 @@ def periods(self, divide_length=False): INPUT: - - ``divide_length`` -- boolean (default: ``False``). - When set to ``True``, then only periods that divide - the length of ``self`` are considered. - - OUTPUT: + - ``divide_length`` -- boolean (default: ``False``); + when set to ``True``, then only periods that divide + the length of ``self`` are considered - a list of positive integers + OUTPUT: list of positive integers EXAMPLES:: @@ -3814,9 +3761,7 @@ def subword_complementaries(self, other): - ``other`` -- finite word - OUTPUT: - - - list of all the complementary subwords of ``self`` in ``other``. + OUTPUT: list of all the complementary subwords of ``self`` in ``other`` EXAMPLES:: @@ -3831,7 +3776,6 @@ def subword_complementaries(self, other): sage: Word('a').subword_complementaries(Word('a')) [word: ] - """ ls = self.length() @@ -3949,9 +3893,7 @@ def lyndon_factorization(self): i.e., `w = l_1\cdots l_n` where each `l_i` is a Lyndon word and `l_1\geq \cdots \geq l_n`. See for instance [Duv1983]_. - OUTPUT: - - the list `[l_1, \ldots, l_n]` of factors obtained + OUTPUT: the list `[l_1, \ldots, l_n]` of factors obtained EXAMPLES:: @@ -4013,7 +3955,7 @@ def lyndon_factorization(self): def inversions(self): r""" Return a list of the inversions of ``self``. An inversion is a pair - `(i,j)` of non-negative integers `i < j` such that ``self[i] > self[j]``. + `(i,j)` of nonnegative integers `i < j` such that ``self[i] > self[j]``. EXAMPLES:: @@ -4046,8 +3988,8 @@ def degree(self, weights=None): INPUT: - - ``weights`` -- a list or a tuple, or a dictionary keyed by the - letters occurring in ``self``. + - ``weights`` -- list or tuple, or dictionary keyed by the + letters occurring in ``self`` EXAMPLES:: @@ -4284,22 +4226,20 @@ def find(self, sub, start=0, end=None): r""" Return the index of the first occurrence of ``sub`` in ``self``, such that ``sub`` is contained within ``self[start:end]``. - Return ``-1`` on failure. + Return `-1` on failure. INPUT: - - ``sub`` -- string, list, tuple or word to search for. + - ``sub`` -- string, list, tuple or word to search for - - ``start`` -- non-negative integer (default: ``0``) specifying - the position from which to start the search. + - ``start`` -- nonnegative integer (default: `0`) specifying + the position from which to start the search - - ``end`` -- non-negative integer (default: ``None``) specifying + - ``end`` -- nonnegative integer (default: ``None``); specifying the position at which the search must stop. If ``None``, then the search is performed up to the end of the string. - OUTPUT: - - a non-negative integer or ``-1`` + OUTPUT: nonnegative integer or `-1` EXAMPLES:: @@ -4339,7 +4279,7 @@ def find(self, sub, start=0, end=None): Check that :issue:`12804` is fixed:: - sage: w = Word(iter("ababab"), length="finite") + sage: w = Word(iter("ababab"), length='finite') sage: w.find("ab") 0 sage: w.find("ab", start=1) @@ -4351,7 +4291,6 @@ def find(self, sub, start=0, end=None): sage: w = Words('ab')(tuple('babaabaaab')) sage: w.find('abc') -1 - """ if not isinstance(sub, FiniteWord_class): try: @@ -4369,18 +4308,16 @@ def rfind(self, sub, start=0, end=None): INPUT: - - ``sub`` -- string, list, tuple or word to search for. + - ``sub`` -- string, list, tuple or word to search for - - ``start`` -- non-negative integer (default: ``0``) specifying - the position at which the search must stop. + - ``start`` -- nonnegative integer (default: `0`); specifying + the position at which the search must stop - - ``end`` -- non-negative integer (default: ``None``) specifying + - ``end`` -- nonnegative integer (default: ``None``); specifying the position from which to start the search. If ``None``, then the search is performed up to the end of the string. - OUTPUT: - - a non-negative integer or ``-1`` + OUTPUT: nonnegative integer or `-1` EXAMPLES:: @@ -4420,7 +4357,7 @@ def rfind(self, sub, start=0, end=None): Check that :issue:`12804` is fixed:: - sage: w = Word(iter("abab"), length="finite") + sage: w = Word(iter("abab"), length='finite') sage: w.rfind("ab") 2 sage: w.rfind("ab", end=3) @@ -4719,9 +4656,7 @@ def number_of_letter_occurrences(self, letter): - ``letter`` -- a letter - OUTPUT: - - - integer + OUTPUT: integer EXAMPLES:: @@ -4754,7 +4689,6 @@ def number_of_letter_occurrences(self, letter): .. SEEALSO:: :meth:`sage.combinat.words.finite_word.FiniteWord_class.number_of_factor_occurrences` - """ return Integer(sum(1 for a in self if a == letter)) count = number_of_letter_occurrences @@ -4767,9 +4701,7 @@ def _return_words_list(self, fact): - ``fact`` -- a non-empty finite word - OUTPUT: - - a Python list of finite words + OUTPUT: a Python list of finite words TESTS:: @@ -4790,9 +4722,7 @@ def return_words(self, fact): - ``fact`` -- a non-empty finite word - OUTPUT: - - a Python set of finite words + OUTPUT: a Python set of finite words EXAMPLES:: @@ -4823,9 +4753,7 @@ def complete_return_words(self, fact): - ``fact`` -- a non-empty finite word - OUTPUT: - - a Python set of finite words + OUTPUT: a Python set of finite words EXAMPLES:: @@ -5035,19 +4963,16 @@ def overlap_partition(self, other, delay=0, p=None, involution=None): INPUT: - - ``other`` -- word on the same alphabet as ``self`` - - ``delay`` -- integer (default: ``0``) - - ``p`` -- disjoint sets data structure (default: ``None``), - a partition of the alphabet into disjoint sets to start with. - If ``None``, each letter start in distinct equivalence classes. - - ``involution`` -- callable (default: ``None``), an - involution on the alphabet. If ``involution`` is not ``None``, the relation - `R_{u,v,d} \cup R_{involution(u),involution(v),d}` is considered. - - OUTPUT: - - a disjoint set data structure + - ``other`` -- word on the same alphabet as ``self`` + - ``delay`` -- integer (default: `0`) + - ``p`` -- disjoint sets data structure (default: ``None``), + a partition of the alphabet into disjoint sets to start with. + If ``None``, each letter start in distinct equivalence classes. + - ``involution`` -- callable (default: ``None``); an + involution on the alphabet. If ``involution`` is not ``None``, the relation + `R_{u,v,d} \cup R_{involution(u),involution(v),d}` is considered. + OUTPUT: a disjoint set data structure EXAMPLES:: @@ -5515,12 +5440,10 @@ def iterated_left_palindromic_closure(self, f=None): INPUT: - - ``f`` -- involution (default: ``None``) on the alphabet of ``self``. - It must be callable on letters as well as words (e.g. ``WordMorphism``). - - OUTPUT: + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. ``WordMorphism``) - word -- the left iterated ``f``-palindromic closure of ``self``. + OUTPUT: word; the left iterated ``f``-palindromic closure of ``self`` EXAMPLES:: @@ -5564,9 +5487,7 @@ def balance(self): for all letters `x` in the alphabet of `w`. A `1`-balanced word is simply said to be balanced. See Chapter 2 of [Lot2002]_. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -5637,11 +5558,7 @@ def is_balanced(self, q=1): INPUT: - - ``q`` -- integer (default: ``1``), the balance level - - OUTPUT: - - boolean -- the result + - ``q`` -- integer (default: `1`); the balance level EXAMPLES:: @@ -5697,9 +5614,7 @@ def abelian_vectors(self, n): The vectors are defined w.r.t. the order of the alphabet of the parent. - OUTPUT: - - a set of tuples + OUTPUT: a set of tuples EXAMPLES:: @@ -5755,7 +5670,6 @@ def abelian_vectors(self, n): 1 sage: w.abelian_complexity(4) 0 - """ alphabet = self.parent().alphabet() size = alphabet.cardinality() @@ -5793,7 +5707,6 @@ def abelian_complexity(self, n): sage: w = words.ThueMorseWord()[:100] sage: [w.abelian_complexity(i) for i in range(20)] [1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2] - """ return len(self.abelian_vectors(n)) @@ -5815,9 +5728,7 @@ def sturmian_desubstitute_as_possible(self): a factor of a Sturmian word if, and only if, the result is the empty word. - OUTPUT: - - a finite word defined on a two-letter alphabet + OUTPUT: a finite word defined on a two-letter alphabet EXAMPLES:: @@ -5892,7 +5803,7 @@ def sturmian_desubstitute_as_possible(self): raise TypeError('your word must be defined on a binary alphabet or use at most two different letters') elif len(alphabet) < 2: return W() - word_from_letter = {l: W([l], datatype="list", check=False) for l in alphabet} + word_from_letter = {l: W([l], datatype='list', check=False) for l in alphabet} is_prefix = True current_run_length = 0 prefix_length = 0 @@ -5959,9 +5870,7 @@ def is_sturmian_factor(self): advantage over the ``is_balanced`` method is that this one runs in linear time whereas ``is_balanced`` runs in quadratic time. - OUTPUT: - - boolean -- the result + OUTPUT: boolean EXAMPLES:: @@ -6024,9 +5933,7 @@ def is_tangent(self): This method runs in linear time. - OUTPUT: - - boolean -- the result + OUTPUT: boolean EXAMPLES:: @@ -6167,9 +6074,7 @@ def abelian_vector(self): - ``self`` -- word having a parent on a finite alphabet - OUTPUT: - - a list + OUTPUT: list EXAMPLES:: @@ -6249,7 +6154,7 @@ def shuffle(self, other, overlap=0): ``self.length()+other.length()`` that have both ``self`` and ``other`` as subwords. - If ``overlap`` is non-zero, then the combinatorial class representing + If ``overlap`` is nonzero, then the combinatorial class representing the shuffle product with overlaps is returned. The calculation of the shift in each overlap is done relative to the order of the alphabet. For example, `a` shifted by `a` is `b` in the alphabet @@ -6257,12 +6162,10 @@ def shuffle(self, other, overlap=0): INPUT: - - ``other`` -- finite word - - ``overlap`` -- (default: ``0``) integer or ``True`` - - OUTPUT: + - ``other`` -- finite word + - ``overlap`` -- (default: ``0``) integer or ``True`` - combinatorial class of shuffle product of ``self`` and ``other`` + OUTPUT: combinatorial class of shuffle product of ``self`` and ``other`` EXAMPLES:: @@ -6310,12 +6213,10 @@ def shifted_shuffle(self, other, shift=None): INPUT: - ``other`` -- finite word over the integers - - ``shift`` -- integer or ``None`` (default: ``None``) added to each letter of + - ``shift`` -- integer or ``None`` (default: ``None``); added to each letter of ``other``. When ``shift`` is ``None``, it is replaced by ``self.length()`` - OUTPUT: - - combinatorial class of shifted shuffle products of ``self`` and ``other`` + OUTPUT: combinatorial class of shifted shuffle products of ``self`` and ``other`` EXAMPLES:: @@ -6350,8 +6251,8 @@ def shifted_shuffle(self, other, shift=None): def delta_inv(self, W=None, s=None): r""" Lift ``self`` via the delta operator to obtain a word containing the - letters in alphabet (default is ``[0, 1]``). The letters used in the - construction start with ``s`` (default is ``alphabet[0]``) and cycle + letters in alphabet (default: ``[0, 1]``). The letters used in the + construction start with ``s`` (default: ``alphabet[0]``) and cycle through alphabet. INPUT: @@ -6406,7 +6307,6 @@ def delta(self): word: sage: Word('aabbabaa').delta() word: 22112 - """ if self.is_empty(): return Words()([]) @@ -6417,8 +6317,7 @@ def delta(self): for s in self: if s == ss: c += 1 - if c > max_c: - max_c = c + max_c = max(c, max_c) else: v.append(c) ss = s @@ -6524,9 +6423,7 @@ def phi(self): the word obtained by taking the first letter of the words obtained by iterating delta on ``self``. - OUTPUT: - - a word -- the result of the phi function + OUTPUT: a word -- the result of the phi function EXAMPLES:: @@ -6566,9 +6463,7 @@ def phi_inv(self, W=None): - ``self`` -- a word over the integers - ``W`` -- a parent object of words defined over integers - OUTPUT: - - a word -- the inverse of the phi function + OUTPUT: a word -- the inverse of the phi function EXAMPLES:: @@ -6618,9 +6513,7 @@ def is_smooth_prefix(self): - ``self`` -- must be a word over the integers to get something other than ``False`` - OUTPUT: - - boolean -- whether ``self`` is a smooth prefix or not + OUTPUT: boolean; whether ``self`` is a smooth prefix or not EXAMPLES:: @@ -6681,9 +6574,7 @@ def standard_factorization(self): - ``self`` -- finite word of length greater than `1` - OUTPUT: - - `2`-tuple `(u, v)` + OUTPUT: `2`-tuple `(u, v)` EXAMPLES:: @@ -6812,11 +6703,9 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn - ``thickness`` -- (default: ``1``) thickness of the contour - ``cmap`` -- (default: ``'hsv'``) color map; for available color map names type: ``import matplotlib.cm; list(matplotlib.cm.datad)`` - - ``label`` -- string (default: ``None``) a label to add on the colored vector - - OUTPUT: + - ``label`` -- string (default: ``None``); a label to add on the colored vector - Graphics + OUTPUT: Graphics EXAMPLES:: @@ -6981,7 +6870,7 @@ def is_square_free(self): def squares(self): r""" - Returns a set of all distinct squares of ``self``. + Return a set of all distinct squares of ``self``. EXAMPLES:: @@ -7101,10 +6990,8 @@ def is_christoffel(self): - ``self`` -- word - OUTPUT: - - boolean -- ``True`` if ``self`` is a Christoffel word, - ``False`` otherwise. + OUTPUT: boolean; ``True`` if ``self`` is a Christoffel word, + ``False`` otherwise EXAMPLES:: diff --git a/src/sage/combinat/words/infinite_word.py b/src/sage/combinat/words/infinite_word.py index 8baae7c1c3c..0fab1f18891 100644 --- a/src/sage/combinat/words/infinite_word.py +++ b/src/sage/combinat/words/infinite_word.py @@ -81,13 +81,13 @@ class InfiniteWord_class(Word_class): def _repr_(self): r""" - Returns a string representation of self. + Return a string representation of ``self``. TESTS:: - sage: Word(iter([1,2,3]), length="unknown")._repr_() + sage: Word(iter([1,2,3]), length='unknown')._repr_() 'word: 123' - sage: Word(range(100), length="unknown")._repr_() + sage: Word(range(100), length='unknown')._repr_() 'word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...' sage: Word(lambda x:x%3)._repr_() 'word: 0120120120120120120120120120120120120120...' @@ -99,7 +99,7 @@ def _repr_(self): def length(self): r""" - Returns the length of self. + Return the length of ``self``. EXAMPLES:: diff --git a/src/sage/combinat/words/lyndon_word.py b/src/sage/combinat/words/lyndon_word.py index fa58a3ffa03..0f4e4111f37 100644 --- a/src/sage/combinat/words/lyndon_word.py +++ b/src/sage/combinat/words/lyndon_word.py @@ -38,16 +38,14 @@ def LyndonWords(e=None, k=None): or - - ``e`` -- integer, size of alphabet - - ``k`` -- integer, length of the words + - ``e`` -- integer; size of alphabet + - ``k`` -- integer; length of the words or - ``e`` -- a composition - OUTPUT: - - A combinatorial class of Lyndon words. + OUTPUT: a combinatorial class of Lyndon words EXAMPLES:: @@ -83,9 +81,9 @@ def LyndonWords(e=None, k=None): elif isinstance(e, (int, Integer)): if e > 0: if not isinstance(k, (int, Integer)): - raise TypeError("k must be a non-negative integer") + raise TypeError("k must be a nonnegative integer") if k < 0: - raise TypeError("k must be a non-negative integer") + raise TypeError("k must be a nonnegative integer") return LyndonWords_nk(Integer(e), Integer(k)) elif e in Compositions(): return LyndonWords_evaluation(Composition(e)) @@ -100,12 +98,10 @@ def LyndonWord(data, check=True): INPUT: - ``data`` -- list - - ``check`` -- bool (default: ``True``) if ``True``, - check that the input data represents a Lyndon word. - - OUTPUT: + - ``check`` -- boolean (default: ``True``); if ``True``, + check that the input data represents a Lyndon word - A Lyndon word. + OUTPUT: a Lyndon word EXAMPLES:: diff --git a/src/sage/combinat/words/meson.build b/src/sage/combinat/words/meson.build new file mode 100644 index 00000000000..bb12f65d28f --- /dev/null +++ b/src/sage/combinat/words/meson.build @@ -0,0 +1,37 @@ +py.install_sources( + 'abstract_word.py', + 'all.py', + 'alphabet.py', + 'finite_word.py', + 'infinite_word.py', + 'lyndon_word.py', + 'morphic.py', + 'morphism.py', + 'paths.py', + 'shuffle_product.py', + 'suffix_trees.py', + 'word.py', + 'word_datatypes.pxd', + 'word_generators.py', + 'word_infinite_datatypes.py', + 'word_options.py', + 'words.py', + subdir: 'sage/combinat/words', +) + +extension_data = { + 'word_char' : files('word_char.pyx'), + 'word_datatypes' : files('word_datatypes.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/combinat/words', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 3699f08c524..160f4e2243a 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -18,7 +18,7 @@ sage: w.length() +Infinity -Computing the n-th letter of a fixed point is fast as it is using the +Computing the `n`-th letter of a fixed point is fast as it is using the abstract numeration system associated to the morphism and the starting letter, see chapter 3 of the book [BR2010b]_:: @@ -45,7 +45,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): - ``parent`` -- a parent - ``morphism`` -- a word morphism - ``letter`` -- a starting letter - - ``coding`` -- dict (default: ``None``), if ``None`` + - ``coding`` -- dictionary (default: ``None``); if ``None`` the identity map is used for the coding - ``length`` -- integer or ``'finite'`` or ``Infinity`` or ``'unknown'`` (default: ``Infinity``) the length of the word @@ -106,7 +106,6 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): word: dddcdddcba sage: list(w[10000:10010]) == L # needs sage.modules True - """ self._parent = parent # self._func = callable @@ -153,7 +152,6 @@ def __reduce__(self): 'a', {'a': 'a', 'b': 'b'}, 2)) - """ return self.__class__, (self._parent, self._morphism, self._letter, self._coding, self._len) @@ -167,9 +165,7 @@ def representation(self, n): - ``n`` -- nonnegative integer - OUTPUT: - - list + OUTPUT: list EXAMPLES:: @@ -243,11 +239,9 @@ def _func(self, key): INPUT: - ``self`` -- a fixed point of a morphism - - ``key`` -- an integer, the position + - ``key`` -- integer; the position - OUTPUT: - - - a letter + OUTPUT: a letter EXAMPLES:: @@ -271,7 +265,6 @@ def _func(self, key): sage: w = WordDatatype_morphic(W, m, 'a') sage: w._func(5) # needs sage.modules 'a' - """ letter = self._letter for a in self.representation(key): @@ -291,13 +284,11 @@ def __iter__(self): INPUT: - ``self`` -- an endomorphism, must be prolongable on - letter + letter - ``letter`` -- a letter in the domain of ``self`` - OUTPUT: - - - iterator of the fixed point + OUTPUT: iterator of the fixed point EXAMPLES:: diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 871fa118c42..7ff3b53451c 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -112,9 +112,9 @@ def get_cycles(f, domain): INPUT: - - ``f`` -- function. + - ``f`` -- function - - ``domain`` -- iterable, a subdomain of the domain of definition of ``f``. + - ``domain`` -- iterable, a subdomain of the domain of definition of ``f`` EXAMPLES:: @@ -228,11 +228,11 @@ def get_iterator(self, i): class WordMorphism(SageObject): r""" - WordMorphism class + WordMorphism class. INPUT: - - ``data`` -- dict or str or an instance of WordMorphism, the map + - ``data`` -- dictionary or string or an instance of WordMorphism, the map giving the image of letters - ``domain`` -- (optional:``None``) set of words over a given alphabet. If ``None``, the domain alphabet is computed from ``data`` @@ -565,7 +565,6 @@ def __ne__(self, other): True sage: s != s.reversal() False - """ return not self == other @@ -628,17 +627,15 @@ def __str__(self) -> str: def __call__(self, w, order=1): r""" - Return the image of ``w`` under self to the given order. + Return the image of ``w`` under ``self`` to the given order. INPUT: - - ``w`` -- word or sequence in the domain of self - - - ``order`` -- integer or plus ``Infinity`` (default: 1) + - ``w`` -- word or sequence in the domain of self - OUTPUT: + - ``order`` -- integer or plus ``Infinity`` (default: 1) - - ``word`` -- order-th iterated image under self of ``w`` + OUTPUT: ``word`` -- ``order``-th iterated image under ``self`` of ``w`` EXAMPLES: @@ -699,16 +696,16 @@ def __call__(self, w, order=1): ... ValueError: 0 not in alphabet - The order must be a non-negative integer or plus Infinity:: + The order must be a nonnegative integer or plus Infinity:: sage: tm('a', -1) Traceback (most recent call last): ... - TypeError: order (-1) must be a non-negative integer or plus Infinity + TypeError: order (-1) must be a nonnegative integer or plus Infinity sage: tm('a', 6.7) Traceback (most recent call last): ... - TypeError: order (6.7...) must be a non-negative integer or plus Infinity + TypeError: order (6.7...) must be a nonnegative integer or plus Infinity Only the first letter is considered for infinitely iterated image of a word under a morphism:: @@ -716,7 +713,7 @@ def __call__(self, w, order=1): sage: tm('aba',oo) word: abbabaabbaababbabaababbaabbabaabbaababba... - The morphism self must be prolongable on the given letter for infinitely + The morphism ``self`` must be prolongable on the given letter for infinitely iterated image:: sage: m = WordMorphism('a->ba,b->ab') @@ -761,7 +758,7 @@ def __call__(self, w, order=1): sage: w == loads(dumps(w)) True sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".sobj") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.sobj') as f: ....: save(w, filename=f.name) """ if order == 1: @@ -813,7 +810,7 @@ def __call__(self, w, order=1): return self._domain(w) else: - raise TypeError("order (%s) must be a non-negative integer or plus Infinity" % order) + raise TypeError("order (%s) must be a nonnegative integer or plus Infinity" % order) def latex_layout(self, layout=None): r""" @@ -821,13 +818,13 @@ def latex_layout(self, layout=None): INPUT: - - ``layout`` -- string (default: ``None``), can take one of the + - ``layout`` -- string (default: ``None``); can take one of the following values: - - ``None`` -- Returns the actual latex layout. By default, the + - ``None`` -- returns the actual latex layout; by default, the layout is ``'array'`` - - ``'oneliner'`` -- Set the layout to ``'oneliner'`` - - ``'array'`` -- Set the layout to ``'array'`` + - ``'oneliner'`` -- set the layout to ``'oneliner'`` + - ``'array'`` -- set the layout to ``'array'`` EXAMPLES:: @@ -956,7 +953,7 @@ def __pow__(self, exp): INPUT: - - ``exp`` -- a positive integer + - ``exp`` -- positive integer EXAMPLES:: @@ -1018,11 +1015,9 @@ def extend_by(self, other): INPUT: - - ``other`` -- a WordMorphism. + - ``other`` -- a WordMorphism - OUTPUT: - - WordMorphism + OUTPUT: WordMorphism EXAMPLES:: @@ -1065,9 +1060,7 @@ def restrict_domain(self, alphabet): - ``alphabet`` -- an iterable - OUTPUT: - - WordMorphism + OUTPUT: WordMorphism EXAMPLES:: @@ -1241,9 +1234,7 @@ def image(self, letter): - ``letter`` -- a letter in the domain alphabet - OUTPUT: - - word + OUTPUT: word .. NOTE:: @@ -1396,11 +1387,9 @@ def partition_of_domain_alphabet(self): INPUT: - - ``self`` -- An involution. + - ``self`` -- an involution - OUTPUT: - - A tuple of three sets + OUTPUT: a tuple of three sets EXAMPLES:: @@ -1481,7 +1470,7 @@ def pisot_eigenvector_right(self): to the largest eigenvalue (in absolute value). Unicity of the result is guaranteed when the multiplicity of the - largest eigenvalue is one, for example when self is a Pisot + largest eigenvalue is one, for example when ``self`` is a Pisot irreductible substitution. A substitution is Pisot irreducible if the characteristic @@ -1490,7 +1479,7 @@ def pisot_eigenvector_right(self): INPUT: - - ``self`` -- a Pisot irreducible substitution. + - ``self`` -- a Pisot irreducible substitution EXAMPLES:: @@ -1511,7 +1500,7 @@ def pisot_eigenvector_left(self): to the largest eigenvalue (in absolute value). Unicity of the result is guaranteed when the multiplicity of the - largest eigenvalue is one, for example when self is a Pisot + largest eigenvalue is one, for example when ``self`` is a Pisot irreductible substitution. A substitution is Pisot irreducible if the characteristic @@ -1520,7 +1509,7 @@ def pisot_eigenvector_left(self): INPUT: - - ``self`` -- a Pisot irreducible substitution. + - ``self`` -- a Pisot irreducible substitution EXAMPLES:: @@ -1556,7 +1545,6 @@ def _check_primitive(self): WordMorphism: 2->456, 3->418 sage: WordMorphism({2:[4,5,6],3:[4,1,8]})._check_primitive() False - """ dom_alphabet = set(self.domain().alphabet()) @@ -1648,9 +1636,7 @@ def is_prolongable(self, letter): - ``self`` -- its codomain must be an instance of Words - ``letter`` -- a letter in the domain alphabet - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -1705,7 +1691,7 @@ def is_uniform(self, k=None): INPUT: - - ``k`` -- a positive integer or ``None``. If set to a positive integer, + - ``k`` -- positive integer or ``None``. If set to a positive integer, then the function return ``True`` if ``self`` is `k`-uniform. If set to ``None``, then the function return ``True`` if ``self`` is uniform. @@ -1747,15 +1733,13 @@ def fixed_point(self, letter): INPUT: - - ``self`` -- an endomorphism (or more generally a self-composable - morphism), must be prolongable on ``letter`` - - - ``letter`` -- in the domain of ``self``, the first letter - of the fixed point. + - ``self`` -- an endomorphism (or more generally a self-composable + morphism), must be prolongable on ``letter`` - OUTPUT: + - ``letter`` -- in the domain of ``self``, the first letter + of the fixed point - - ``word`` -- the fixed point of ``self`` beginning with ``letter``. + OUTPUT: ``word`` -- the fixed point of ``self`` beginning with ``letter`` EXAMPLES:: @@ -1887,7 +1871,6 @@ def fixed_points(self): sage: s = WordMorphism(s) sage: (s^2).fixed_points() [] - """ return [self.fixed_point(letter=letter) for letter in self.domain().alphabet() @@ -1895,7 +1878,7 @@ def fixed_points(self): def periodic_point(self, letter): r""" - Return the periodic point of self that starts with ``letter``. + Return the periodic point of ``self`` that starts with ``letter``. EXAMPLES:: @@ -2008,7 +1991,7 @@ def _language_naive(self, n, u): INPUT: - - ``n`` -- non-negative integer; length of the words in the language + - ``n`` -- nonnegative integer; length of the words in the language - ``u`` -- a word used as a seed @@ -2065,11 +2048,11 @@ def language(self, n, u=None): Given a non-erasing substitution `s` and a word `u` the DOL-language generated by `s` and `u` is the union of the factors of `s^n(u)` where - `n` is a non-negative integer. + `n` is a nonnegative integer. INPUT: - - ``n`` -- non-negative integer; length of the words in the language + - ``n`` -- nonnegative integer; length of the words in the language - ``u`` -- a word or ``None`` (default: ``None``); if set to ``None`` some letter of the alphabet is used @@ -2340,8 +2323,8 @@ def is_in_classP(self, f=None): INPUT: - - ``f`` -- involution (default: None) on the alphabet of ``self``. - It must be callable on letters as well as words (e.g. WordMorphism). + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. WordMorphism) REFERENCES: @@ -2418,8 +2401,8 @@ def has_conjugate_in_classP(self, f=None): INPUT: - - ``f`` -- involution (default: None) on the alphabet of ``self``. - It must be callable on letters as well as words (e.g. WordMorphism). + - ``f`` -- involution (default: ``None``) on the alphabet of ``self``; + it must be callable on letters as well as words (e.g. WordMorphism) REFERENCES: @@ -2448,7 +2431,7 @@ def has_conjugate_in_classP(self, f=None): def dual_map(self, k=1): r""" - Return the dual map `E_k^*` of self (see [1]). + Return the dual map `E_k^*` of ``self`` (see [1]). .. NOTE:: @@ -2460,9 +2443,7 @@ def dual_map(self, k=1): ``1, 2, \ldots, d`` - ``k`` -- integer (default: 1) - OUTPUT: - - an instance of E1Star - the dual map + OUTPUT: an instance of E1Star - the dual map EXAMPLES:: @@ -2507,9 +2488,9 @@ def rauzy_fractal_projection(self, eig=None, prec=53): but for substitutions with more than 3 letters other interesting choices are sometimes possible. - - ``prec`` -- integer (default: ``53``). - The number of bits used in the floating point representations - of the coordinates. + - ``prec`` -- integer (default: 53); + the number of bits used in the floating point representations + of the coordinates OUTPUT: @@ -2611,12 +2592,10 @@ def rauzy_fractal_points(self, n=None, exchange=False, eig=None, translate=None, INPUT: - See the method :meth:`rauzy_fractal_plot` for a description - of the options and more examples. - - OUTPUT: + See the method :meth:`rauzy_fractal_plot` for a description + of the options and more examples. - dictionary of list of points + OUTPUT: dictionary of list of points EXAMPLES: @@ -2736,9 +2715,7 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, can be found in :meth:`sage.combinat.words.paths.FiniteWordPath_all.plot_projection` or in :meth:`sage.combinat.e_one_star`. - OUTPUT: - - A Graphics object. + OUTPUT: a Graphics object INPUT: @@ -2747,18 +2724,18 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, Default values: ``1000`` for a 1D fractal, ``50000`` for a 2D fractal, ``10000`` for a 3D fractal. - - ``exchange`` -- boolean (default: ``False``). - Plot the Rauzy fractal with domain exchange. + - ``exchange`` -- boolean (default: ``False``); plot the Rauzy fractal + with domain exchange - - ``eig`` -- a real element of ``QQbar`` of degree >= 2 (default: ``None``). - The eigenvalue used to plot the fractal. + - ``eig`` -- a real element of ``QQbar`` of degree >= 2 (default: ``None``); + the eigenvalue used to plot the fractal. It must be an eigenvalue of ``self.incidence_matrix()``. The one used by default the maximal eigenvalue of ``self.incidence_matrix()`` (usually a Pisot number), but for substitutions with more than 3 letters other interesting choices are sometimes possible. - - ``translate`` -- a list of vectors of ``RR^size_alphabet``, + - ``translate`` -- list of vectors of ``RR^size_alphabet``, or a dictionary from the alphabet to lists of vectors (default: ``None``). Plot translated copies of the fractal. This option allows to plot tilings easily. @@ -2771,9 +2748,9 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, is not plotted with the ``translate`` option; the vector ``(0,0,...,0)`` has to be added manually. - - ``prec`` -- integer (default: ``53``). - The number of bits used in the floating point representations - of the points of the fractal. + - ``prec`` -- integer (default: 53); + the number of bits used in the floating point representations + of the points of the fractal - ``colormap`` -- color map or dictionary (default: ``'hsv'``). It can be one of the following: @@ -2781,19 +2758,20 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, - ``string`` -- a coloring map. For available coloring map names type: ``sorted(colormaps)`` - - ``dict`` -- a dictionary of the alphabet mapped to colors. + - ``dict`` -- dictionary of the alphabet mapped to colors - - ``opacity`` -- a dictionary from the alphabet to the real interval [0,1] (default: ``None``). - If none is specified, all letters are plotted with opacity ``1``. + - ``opacity`` -- dictionary from the alphabet to the real interval + [0,1] (default: ``None``); if none is specified, all letters are + plotted with opacity ``1`` - - ``plot_origin`` -- a couple ``(k,c)`` (default: ``None``). - If specified, mark the origin by a point of size ``k`` and color ``c``. + - ``plot_origin`` -- a couple ``(k,c)`` (default: ``None``); + if specified, mark the origin by a point of size ``k`` and color ``c`` - - ``plot_basis`` -- boolean (default: ``False``). - Plot the projection of the canonical basis with the fractal. + - ``plot_basis`` -- boolean (default: ``False``); plot the projection + of the canonical basis with the fractal - - ``point_size`` -- float (default: ``None``). - The size of the points used to plot the fractal. + - ``point_size`` -- float (default: ``None``); the size of the points + used to plot the fractal EXAMPLES: @@ -3208,10 +3186,10 @@ def letter_growth_types(self): The output is a 3-tuple of lists (mortal, polynomial, exponential) where: - - ``mortal``: list of mortal letters - - ``polynomial``: a list of lists where ``polynomial[i]`` is the - list of letters with growth `n^i`. - - ``exponential``: list of at least exponentionally growing letters + - ``mortal`` -- list of mortal letters + - ``polynomial`` -- list of lists where ``polynomial[i]`` is the + list of letters with growth `n^i` + - ``exponential`` -- list of at least exponentionally growing letters EXAMPLES:: @@ -3446,8 +3424,8 @@ def is_pushy(self, w=None): INPUT: - - ``w`` -- finite iterable (default: ``self.domain().alphabet()``). - Represents a word used to start the language. + - ``w`` -- finite iterable (default: ``self.domain().alphabet()``); + represents a word used to start the language EXAMPLES:: @@ -3473,8 +3451,8 @@ def is_unboundedly_repetitive(self, w=None): INPUT: - - ``w`` -- finite iterable (default: ``self.domain().alphabet()``). - Represents a word used to start the language. + - ``w`` -- finite iterable (default: ``self.domain().alphabet()``); + represents a word used to start the language EXAMPLES:: @@ -3503,8 +3481,8 @@ def is_repetitive(self, w=None): INPUT: - - ``w`` -- finite iterable (default: ``self.domain().alphabet()``). - Represents a word used to start the language. + - ``w`` -- finite iterable (default: ``self.domain().alphabet()``); + represents a word used to start the language EXAMPLES: @@ -3550,10 +3528,10 @@ def infinite_repetitions_primitive_roots(self, w=None, allow_growing=None): INPUT: - - ``w`` -- finite iterable (default: ``self.domain().alphabet()``). - Represents a word used to start the language. + - ``w`` -- finite iterable (default: ``self.domain().alphabet()``); + represents a word used to start the language - - ``allow_growing`` -- boolean or ``None`` (default: ``None``). If + - ``allow_growing`` -- boolean or ``None`` (default: ``None``); if ``False``, return only the primitive roots that contain no growing letters. If ``True``, return only the primitive roots that contain at least one growing letter. If ``None``, return both. @@ -3696,7 +3674,7 @@ def simplify_alphabet_size(self, Z=None): r""" If this morphism is simplifiable, return morphisms `h` and `k` such that this morphism is simplifiable with respect to `h` and `k`, otherwise - raise :class:`ValueError`. + raise :exc:`ValueError`. This method is quite fast if this morphism is non-injective, but very slow if it is injective. @@ -3715,8 +3693,8 @@ def simplify_alphabet_size(self, Z=None): INPUT: - - ``Z`` -- iterable (default: ``self.domain().alphabet()``), whose - elements are used as an alphabet for the simplification. + - ``Z`` -- iterable (default: ``self.domain().alphabet()``) whose + elements are used as an alphabet for the simplification EXAMPLES: diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index ac89659fe91..a17331b7b82 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -217,7 +217,7 @@ def WordPaths(alphabet, steps=None): - ``alphabet`` -- ordered alphabet - - ``steps`` -- (default is ``None``). It can be one of the following: + - ``steps`` -- (default: ``None``) it can be one of the following: - an iterable ordered container of as many vectors as there are letters in the alphabet. The vectors are associated to the letters @@ -229,25 +229,23 @@ def WordPaths(alphabet, steps=None): to the letters according to their order in steps (given vectors first, opposite vectors after). - - ``None``: In this case, the type of steps are guessed from the - length of alphabet. + - ``None`` -- in this case, the type of steps are guessed from the + length of alphabet - - 'square_grid' or 'square': (default when size of alphabet is 4) + - ``'square_grid'`` or ``'square'`` -- (default when size of alphabet is 4) The order is : East, North, West, South. - - 'triangle_grid' or 'triangle': + - ``'triangle_grid'`` or ``'triangle'`` - - 'hexagonal_grid' or 'hexagon': (default when size of alphabet is 6) + - ``'hexagonal_grid'`` or ``'hexagon'`` -- (default when size of alphabet is 6) - - 'cube_grid' or 'cube': + - ``'cube_grid'`` or ``'cube'`` - - 'north_east', 'ne' or 'NE': (the default when size of alphabet is 2) + - ``'north_east'``, ``'ne'`` or ``'NE'`` -- (the default when size of alphabet is 2) - - 'dyck': + - ``'dyck'`` - OUTPUT: - - The combinatorial class of all paths of the given type. + OUTPUT: the combinatorial class of all paths of the given type EXAMPLES: @@ -606,7 +604,6 @@ def vector_space(self): Ambient free module of rank 3 over the principal ideal domain Integer Ring sage: WordPaths('abcdef',steps='triangle_grid').vector_space() Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - """ return self._vector_space @@ -621,8 +618,8 @@ def __init__(self, alphabet): INPUT: - - ``alphabet`` -- ordered alphabet of length 4. The order for the steps - is : East, North, West, South. + - ``alphabet`` -- ordered alphabet of length 4; the order for the steps + is : East, North, West, South EXAMPLES:: @@ -1060,7 +1057,7 @@ def points(self, include_last=True): INPUT: - - ``include_last`` -- bool (default: ``True``) whether to include the + - ``include_last`` -- boolean (default: ``True``); whether to include the last point EXAMPLES: @@ -1092,9 +1089,7 @@ def start_point(self): r""" Return the starting point of ``self``. - OUTPUT: - - vector + OUTPUT: vector EXAMPLES:: @@ -1226,7 +1221,6 @@ def tikz_trajectory(self) -> str: sage: p = P('abcde') sage: p.tikz_trajectory() '(0.000, 0.000) -- (1.00, 0.000) -- (1.50, 0.866) -- (1.00, 1.73) -- (0.000, 1.73) -- (-0.500, 0.866)' - """ from sage.misc.functional import N as n l = (str(tuple(n(x, digits=3) for x in pt)) for pt in self.points()) @@ -1239,16 +1233,14 @@ def projected_point_iterator(self, v=None, ring=None): INPUT: - - ``v`` -- vector (default: None) If None, the directive + - ``v`` -- vector (default: ``None``); if ``None``, the directive vector (i.e. the end point minus starting point) of the path is - considered. - - - ``ring`` -- ring (default: None) where to do the - computations. If None, RealField(53) is used. + considered - OUTPUT: + - ``ring`` -- ring (default: ``None``); where to do the + computations. If ``None``, RealField(53) is used. - iterator of points + OUTPUT: iterator of points EXAMPLES: @@ -1301,28 +1293,26 @@ def plot_projection(self, v=None, letters=None, color=None, ring=None, - ``self`` -- a word path in a 3 or 4 dimension vector space - - ``v`` -- vector (default: None) If None, the directive + - ``v`` -- vector (default: ``None``); if ``None``, the directive vector (i.e. the end point minus starting point) of the path is considered. - - ``letters`` -- iterable (default: None) of the letters - to be projected. If None, then all the letters are considered. + - ``letters`` -- iterable (default: ``None``); of the letters + to be projected. If ``None``, then all the letters are considered. - - ``color`` -- dictionary (default: None) of the letters - mapped to colors. If None, automatic colors are chosen. + - ``color`` -- dictionary (default: ``None``); of the letters + mapped to colors. If ``None``, automatic colors are chosen. - - ``ring`` -- ring (default: None) where to do the - computations. If None, RealField(53) is used. + - ``ring`` -- ring (default: ``None``); where to do the + computations. If ``None``, RealField(53) is used. - - ``size`` -- number (default: ``12``) size of the points. + - ``size`` -- number (default: ``12``); size of the points - - ``kind`` -- string (default: ``'right'``) either + - ``kind`` -- string (default: ``'right'``); either ``'right'`` or ``'left'``. The color of a letter is given to the projected prefix to the right or the left of the letter. - OUTPUT: - - 2d or 3d Graphic object. + OUTPUT: 2d or 3d Graphic object EXAMPLES: @@ -1422,16 +1412,14 @@ def projected_path(self, v=None, ring=None): INPUT: - - ``v`` -- vector (default: None) If None, the directive + - ``v`` -- vector (default: ``None``); if ``None``, the directive vector (i.e. the end point minus starting point) of the path is considered. - - ``ring`` -- ring (default: None) where to do the - computations. If None, RealField(53) is used. - - OUTPUT: + - ``ring`` -- ring (default: ``None``); where to do the + computations. If ``None``, RealField(53) is used. - word path + OUTPUT: word path EXAMPLES: @@ -1502,30 +1490,29 @@ def plot(self, pathoptions={"rgbcolor": 'red', "thickness": 3}, default:dict(rgbcolor='red',thickness=3)), options for the path drawing - - ``fill`` -- (boolean, default: ``True``), if fill is True and if + - ``fill`` -- boolean (default: ``True``); if fill is ``True`` and if the path is closed, the inside is colored - ``filloptions`` -- (dict, default:dict(rgbcolor='red',alpha=0.2)), options for the inside filling - - ``startpoint`` -- (boolean, default: ``True``), draw the start point? + - ``startpoint`` -- boolean (default: ``True``); draw the start point? - ``startoptions`` -- (dict, default:dict(rgbcolor='red',pointsize=100)) options for the start point drawing - - ``endarrow`` -- (boolean, default: ``True``), draw an arrow end at the end? + - ``endarrow`` -- boolean (default: ``True``); draw an arrow end at the end? - ``arrowoptions`` -- (dict, default:dict(rgbcolor='red',arrowsize=20, width=3)) options for the end point arrow - - ``gridlines`` -- (boolean, default: ``False``), show gridlines? + - ``gridlines`` -- boolean (default: ``False``); show gridlines? - ``gridoptions`` -- (dict, default: {}), options for the gridlines - EXAMPLES: A non closed path on the square grid:: @@ -1655,7 +1642,7 @@ def animate(self): Animation with 296 frames sage: show(a*b*c*d) # long time, optional - imagemagick - .. note:: + .. NOTE:: If ImageMagick is not installed, you will get an error message like this:: @@ -1667,7 +1654,6 @@ def animate(self): ImageMagick, so please install it and try again. See www.imagemagick.org, for example. - """ from sage.plot.all import line, polygon, animate @@ -1752,7 +1738,6 @@ def area(self): sage: p = P('abcd') sage: p.area() #todo: not implemented 2 - """ if not self.is_closed(): raise TypeError("the path must be closed to compute its area") @@ -1766,9 +1751,7 @@ def height(self): between the highest and the lowest `y`-coordinate of each points traced by it. - OUTPUT: - - non negative real number + OUTPUT: nonnegative real number EXAMPLES:: @@ -1776,7 +1759,7 @@ def height(self): sage: Freeman('aababaabbbAA').height() 5 - The function is well-defined if self is not simple or close:: + The function is well-defined if ``self`` is not simple or close:: sage: Freeman('aabAAB').height() 1 @@ -1818,10 +1801,8 @@ def height_vector(self): y_min = y y_max = y else: - if y > y_max: - y_max = y - if y < y_min: - y_min = y + y_max = max(y, y_max) + y_min = min(y, y_min) h_vec.append(y_max - y_min) return h_vec @@ -1833,9 +1814,7 @@ def width(self): between the rightmost and the leftmost `x`-coordinate of each points traced by it. - OUTPUT: - - non negative real number + OUTPUT: nonnegative real number EXAMPLES:: @@ -1843,7 +1822,7 @@ def width(self): sage: Freeman('aababaabbbAA').width() 5 - The function is well-defined if self is not simple or close:: + The function is well-defined if ``self`` is not simple or close:: sage: Freeman('aabAAB').width() 2 @@ -1885,10 +1864,8 @@ def width_vector(self): x_min = x x_max = x else: - if x > x_max: - x_max = x - if x < x_min: - x_min = x + x_max = max(x, x_max) + x_min = min(x, x_min) w_vec.append(x_max - x_min) return w_vec @@ -2010,10 +1987,10 @@ def plot(self, pathoptions={"rgbcolor": 'red', "arrow_head": True, "thickness": - ``pathoptions`` -- (dict, default:dict(rgbcolor='red',arrow_head=True, thickness=3)), options for the path drawing - - ``startpoint`` -- (boolean, default: ``True``), draw the start point? + - ``startpoint`` -- boolean (default: ``True``); draw the start point? - ``startoptions`` -- (dict, default:dict(rgbcolor='red',size=10)) - options for the start point drawing + options for the start point drawing EXAMPLES:: @@ -2029,7 +2006,6 @@ def plot(self, pathoptions={"rgbcolor": 'red', "arrow_head": True, "thickness": sage: p = P('abcabcAABBC') sage: p.plot() # needs sage.plot Graphics3d Object - """ # The following line seems not to work for 3d # G = Graphics() @@ -2129,7 +2105,6 @@ def area(self): Traceback (most recent call last): ... TypeError: the path must be closed to compute its area - """ if not self.is_closed(): raise TypeError("the path must be closed to compute its area") @@ -2186,7 +2161,7 @@ def is_simple(self) -> bool: If the path is closed, the last point is not considered. - .. note:: + .. NOTE:: The linear algorithm described in the thesis of Xavier Provençal should be implemented here. diff --git a/src/sage/combinat/words/shuffle_product.py b/src/sage/combinat/words/shuffle_product.py index 719e0122e5c..5aea554b6b6 100644 --- a/src/sage/combinat/words/shuffle_product.py +++ b/src/sage/combinat/words/shuffle_product.py @@ -56,7 +56,7 @@ def __init__(self, w1, w2, check=True): INPUT: - - ``check`` -- boolean (default ``True``) whether to check that + - ``check`` -- boolean (default: ``True``); whether to check that all words in the shuffle product belong to the correct parent EXAMPLES:: @@ -243,7 +243,7 @@ def __init__(self, w1, w2, check=True): INPUT: - - ``check`` -- boolean (default ``True``) whether to check that + - ``check`` -- boolean (default: ``True``); whether to check that all words in the shuffle product belong to the correct parent EXAMPLES:: diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index e64f2fb8db6..3249ce23235 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -103,7 +103,7 @@ def _process_letter(self, letter): Process a letter. That is, modify the current suffix trie producing the suffix trie for ``self.word() + letter``. - .. note:: + .. NOTE:: ``letter`` must occur within the alphabet of the word. @@ -143,7 +143,7 @@ def process_letter(self, letter): Modify ``self`` to produce the suffix trie for ``self.word() + letter``. - .. note:: + .. NOTE:: ``letter`` must occur within the alphabet of the word. @@ -602,7 +602,7 @@ def _process_letter(self, letter): This corresponds to the algorithm "update" in [Ukko1995]_. - .. note:: + .. NOTE:: This function is a helper and does not update ``self._data`` and ``self._word``. @@ -833,9 +833,8 @@ def to_digraph(self, word_labels=False): INPUT: - - ``word_labels`` -- boolean (default: ``False``) if ``False``, labels - the edges by pairs `(i, j)`; if ``True``, labels the edges by - ``word[i:j]``. + - ``word_labels`` -- boolean (default: ``False``); if ``False``, labels + the edges by pairs `(i, j)`. If ``True``, labels the edges by ``word[i:j]`` EXAMPLES:: @@ -866,14 +865,13 @@ def plot(self, word_labels=False, layout='tree', tree_root=0, INPUT: - - ``word_labels`` -- boolean (default: ``False``) if ``False``, labels - the edges by pairs `(i, j)`; if ``True``, labels the edges by - ``word[i:j]``. - - ``layout`` -- (default: ``'tree'``) - - ``tree_root`` -- (default: 0) - - ``tree_orientation`` -- (default: ``'up'``) - - ``vertex_colors`` -- (default: ``None``) - - ``edge_labels`` -- (default: ``True``) + - ``word_labels`` -- boolean (default: ``False``); if ``False``, labels + the edges by pairs `(i, j)`; if ``True``, labels the edges by ``word[i:j]`` + - ``layout`` -- (default: ``'tree'``) + - ``tree_root`` -- (default: 0) + - ``tree_orientation`` -- (default: ``'up'``) + - ``vertex_colors`` -- (default: ``None``) + - ``edge_labels`` -- (default: ``True``) EXAMPLES:: @@ -908,9 +906,8 @@ def show(self, word_labels=None, *args, **kwds): INPUT: - - ``word_labels`` -- (default: ``None``) if ``False``, labels the - edges by pairs `(i, j)`; if ``True``, labels the edges by - ``word[i:j]``. + - ``word_labels`` -- (default: ``None``) if ``False``, labels the edges + by pairs `(i, j)`; if ``True``, labels the edges by ``word[i:j]`` EXAMPLES:: @@ -1150,13 +1147,13 @@ def number_of_factors(self, n=None): INPUT: - - ``n`` -- an integer, or ``None``. + - ``n`` -- integer or ``None`` OUTPUT: - - If ``n`` is an integer, returns the number of distinct factors - of length ``n``. If ``n`` is ``None``, returns the total number of - distinct factors. + If ``n`` is an integer, returns the number of distinct factors + of length ``n``. If ``n`` is ``None``, returns the total number of + distinct factors. EXAMPLES:: @@ -1236,13 +1233,13 @@ def factor_iterator(self, n=None): INPUT: - - ``n`` -- an integer, or ``None``. + - ``n`` -- integer or ``None`` OUTPUT: - - If ``n`` is an integer, returns an iterator over all distinct - factors of length ``n``. If ``n`` is ``None``, returns an iterator - generating all distinct factors. + If ``n`` is an integer, returns an iterator over all distinct + factors of length ``n``. If ``n`` is ``None``, returns an iterator + generating all distinct factors. EXAMPLES:: @@ -1468,7 +1465,7 @@ def leftmost_covering_set(self): def condition1_square_pairs(i): r""" - Computes the squares that have their center (the last letter of the + Compute the squares that have their center (the last letter of the first occurrence of ``w`` in ``ww``) in the `i`-th block of the LZ-decomposition and that start in the `i`-th block and end in the `(i+1)`-th. @@ -1626,7 +1623,7 @@ def __init__(self, w): We skip the ``_test_and_split`` test because it is not a test meant for the ``TestSuite``:: - sage: TestSuite(DST).run(skip="_test_and_split") + sage: TestSuite(DST).run(skip='_test_and_split') Test that we do not allow ``'$'`` to appear in the word:: @@ -1686,7 +1683,7 @@ def node_processing(node, parent, head): - ``node`` -- a node of ``self`` - ``parent`` -- the parent of a node in ``self`` - - ``head`` -- a tuple indicating the head of the list ``P(node)`` + - ``head`` -- tuple indicating the head of the list ``P(node)`` OUTPUT: ``(i, pos)``, the new head of ``P(node)`` """ @@ -1811,8 +1808,8 @@ def treat_node(current_node, i, j): INPUT: - - ``current_node`` -- The node to treat - - ``(i, j)`` -- Pair of index such that the path from 0 to + - ``current_node`` -- the node to treat + - ``(i, j)`` -- pair of index such that the path from 0 to ``current_node`` reads ``self.word()[i:j]`` """ @@ -1832,7 +1829,7 @@ def treat_node(current_node, i, j): treat_node(0, 0, 0) return labeling - def square_vocabulary(self, output="pair"): + def square_vocabulary(self, output='pair'): r""" Return the list of distinct squares of ``self.word``. @@ -1843,7 +1840,7 @@ def square_vocabulary(self, output="pair"): INPUT: - - ``output`` -- (default: ``"pair"``) either ``"pair"`` or ``"word"`` + - ``output`` -- (default: ``'pair'``) either ``'pair'`` or ``'word'`` EXAMPLES:: @@ -1852,7 +1849,7 @@ def square_vocabulary(self, output="pair"): sage: sorted(DecoratedSuffixTree(w).square_vocabulary()) [(0, 0), (0, 2), (2, 2)] sage: w = Word('00110011010') - sage: sorted(DecoratedSuffixTree(w).square_vocabulary(output="word")) + sage: sorted(DecoratedSuffixTree(w).square_vocabulary(output='word')) [word: , word: 00, word: 00110011, word: 01100110, word: 1010, word: 11] """ def treat_node(current_node, i, j): diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 1802ab23750..2470ee0c00f 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -47,31 +47,31 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK INPUT: - - ``data`` -- (default: ``None``) list, string, tuple, iterator, free - monoid element, ``None`` (shorthand for ``[]``), or a callable defined - on ``[0,1,...,length]``. + - ``data`` -- (default: ``None``) list, string, tuple, iterator, free + monoid element, ``None`` (shorthand for ``[]``), or a callable defined + on ``[0,1,...,length]`` - - ``alphabet`` -- any argument accepted by Words + - ``alphabet`` -- any argument accepted by Words - - ``length`` -- (default: ``None``) This is dependent on the type of data. - It is ignored for words defined by lists, strings, tuples, - etc., because they have a naturally defined length. - For callables, this defines the domain of definition, - which is assumed to be ``[0, 1, 2, ..., length-1]``. - For iterators: Infinity if you know the iterator will not - terminate (default); ``"unknown"`` if you do not know whether the - iterator terminates; ``"finite"`` if you know that the iterator - terminates, but do not know the length. + - ``length`` -- (default: ``None``) this is dependent on the type of data. + It is ignored for words defined by lists, strings, tuples, + etc., because they have a naturally defined length. + For callables, this defines the domain of definition, + which is assumed to be ``[0, 1, 2, ..., length-1]``. + For iterators: Infinity if you know the iterator will not + terminate (default); ``'unknown'`` if you do not know whether the + iterator terminates; ``'finite'`` if you know that the iterator + terminates, but do not know the length. - - ``datatype`` -- (default: ``None``) ``None``, ``"list"``, ``"str"``, - ``"tuple"``, ``"iter"``, ``"callable"``. If ``None``, then the function - tries to guess this from the data. + - ``datatype`` -- (default: ``None``) ``None``, ``'list'``, ``'str'``, + ``'tuple'``, ``'iter'``, ``'callable'``; if ``None``, then the function + tries to guess this from the data - - ``caching`` -- (default: ``True``) ``True`` or ``False``. Whether to - keep a cache of the letters computed by an iterator or callable. + - ``caching`` -- boolean (default: ``True``); whether to + keep a cache of the letters computed by an iterator or callable - - ``RSK_data`` -- (Optional. Default: ``None``) A semistandard and a - standard Young tableau to run the inverse RSK bijection on. + - ``RSK_data`` -- (default: ``None``) semistandard and a + standard Young tableau to run the inverse RSK bijection on .. NOTE:: @@ -94,9 +94,9 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK Word with string constructed from other types:: - sage: Word([0,1,1,0,1,0,0,1], datatype="str") + sage: Word([0,1,1,0,1,0,0,1], datatype='str') word: 01101001 - sage: Word((0,1,1,0,1,0,0,1), datatype="str") + sage: Word((0,1,1,0,1,0,0,1), datatype='str') word: 01101001 Word with list:: @@ -106,9 +106,9 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK Word with list constructed from other types:: - sage: Word("01101001", datatype="list") + sage: Word("01101001", datatype='list') word: 01101001 - sage: Word((0,1,1,0,1,0,0,1), datatype="list") + sage: Word((0,1,1,0,1,0,0,1), datatype='list') word: 01101001 Word with tuple:: @@ -118,9 +118,9 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK Word with tuple constructed from other types:: - sage: Word([0,1,1,0,1,0,0,1], datatype="tuple") + sage: Word([0,1,1,0,1,0,0,1], datatype='tuple') word: 01101001 - sage: Word("01101001", datatype="str") + sage: Word("01101001", datatype='str') word: 01101001 Word with iterator:: @@ -130,9 +130,9 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,... sage: Word(iter("abbabaab")) # iterators default to infinite words word: abbabaab - sage: Word(iter("abbabaab"), length="unknown") + sage: Word(iter("abbabaab"), length='unknown') word: abbabaab - sage: Word(iter("abbabaab"), length="finite") + sage: Word(iter("abbabaab"), length='finite') word: abbabaab Word with function (a 'callable'):: @@ -145,7 +145,7 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK Word over a string with a parent:: - sage: w = Word("abbabaab", alphabet="abc"); w + sage: w = Word("abbabaab", alphabet='abc'); w word: abbabaab sage: w.parent() Finite words over {'a', 'b', 'c'} diff --git a/src/sage/combinat/words/word_char.pyx b/src/sage/combinat/words/word_char.pyx index da5d9bb2194..18be2efde90 100644 --- a/src/sage/combinat/words/word_char.pyx +++ b/src/sage/combinat/words/word_char.pyx @@ -68,7 +68,7 @@ cdef class WordDatatype_char(WordDatatype): def __cinit__(self): r""" - Initialization of C attributes + Initialization of C attributes. TESTS:: @@ -81,7 +81,7 @@ cdef class WordDatatype_char(WordDatatype): def __init__(self, parent, data): r""" - Constructor + Constructor. TESTS:: @@ -102,7 +102,7 @@ cdef class WordDatatype_char(WordDatatype): @cython.wraparound(False) # not check not correctly handle negative indices cdef _set_data(self, data): r""" - set the attribute ._data and ._length from the sequence data + Set the attribute ._data and ._length from the sequence data (usually data is a word, a tuple or a list) """ cdef size_t i @@ -114,9 +114,9 @@ cdef class WordDatatype_char(WordDatatype): def __dealloc__(self): r""" - Deallocate memory only if self uses it own memory. + Deallocate memory only if ``self`` uses it own memory. - Note that ``sig_free`` will not deallocate memory if self is the + Note that ``sig_free`` will not deallocate memory if ``self`` is the master of another word. """ # it is strictly forbidden here to access _master here! (it will be set @@ -250,7 +250,7 @@ cdef class WordDatatype_char(WordDatatype): - ``other`` -- a word (WordDatatype_char) - - ``op`` -- int, from 0 to 5 + - ``op`` -- integer from 0 to 5 TESTS:: @@ -501,11 +501,11 @@ cdef class WordDatatype_char(WordDatatype): def __pow__(self, exp, mod): r""" - Power + Power. INPUT: - - ``exp`` -- an integer, a rational, a float number or plus infinity. + - ``exp`` -- integer, rational, float, or plus infinity TESTS:: @@ -646,7 +646,7 @@ cdef class WordDatatype_char(WordDatatype): def is_square(self): r""" - Return True if self is a square, and False otherwise. + Return ``True`` if ``self`` is a square, and ``False`` otherwise. EXAMPLES:: diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index 4e30fd81ba4..ddda24ab436 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -33,11 +33,10 @@ cdef class WordDatatype(): sage: w = Word([0,1,1,0,0,1]) sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype) True - """ def __reduce__(self): r""" - Default pickle support + Default pickle support. TESTS:: @@ -49,7 +48,7 @@ cdef class WordDatatype(): def __hash__(self): r""" - Returns the hash for this word. + Return the hash for this word. TESTS:: @@ -112,9 +111,7 @@ cdef class WordDatatype_list(WordDatatype): - ``a`` -- anything - OUTPUT: - - - boolean + OUTPUT: boolean EXAMPLES:: @@ -123,36 +120,32 @@ cdef class WordDatatype_list(WordDatatype): True sage: 3 in w False - """ return a in self._data def __iter__(self): r""" - Return an iterator that iterates through the letters of self. + Return an iterator that iterates through the letters of ``self``. EXAMPLES:: sage: w = Word([0,1,1,0]) sage: list(iter(w)) [0, 1, 1, 0] - """ return iter(self._data) def __richcmp__(self, other, int op): r""" - Equality test for self and other if other is an instance of - WordDatype_list. + Equality test for ``self`` and ``other`` if other is an instance of + ``WordDatype_list``. INPUT: - ``other`` -- a word - - ``op`` -- integer: 0, 1, 2, 3, 4 or 5 - - OUTPUT: + - ``op`` -- integer; 0, 1, 2, 3, 4 or 5 - boolean or NotImplemented + OUTPUT: boolean or NotImplemented EXAMPLES:: @@ -198,7 +191,6 @@ cdef class WordDatatype_list(WordDatatype): sage: w = Word([0,1,1,0]) sage: len(w) 4 - """ return len(self._data) @@ -211,13 +203,12 @@ cdef class WordDatatype_list(WordDatatype): sage: w = Word([0,1,1,0]) sage: w.length() 4 - """ return len(self._data) def __getitem__(self, key): r""" - Implements :meth:`__getitem__` for words stored as lists. + Implement :meth:`__getitem__` for words stored as lists. INPUT: @@ -233,7 +224,6 @@ cdef class WordDatatype_list(WordDatatype): 99 sage: w[3:10:2] word: 3579 - """ if isinstance(key, slice): return self._parent(self._data[key]) @@ -242,15 +232,13 @@ cdef class WordDatatype_list(WordDatatype): def __mul__(self, other): r""" - Return the concatenation of self and other. + Return the concatenation of ``self`` and ``other``. INPUT: - ``other`` -- word represented by a list - OUTPUT: - - word + OUTPUT: word EXAMPLES:: @@ -274,16 +262,14 @@ cdef class WordDatatype_list(WordDatatype): def number_of_letter_occurrences(self, a): r""" - Returns the number of occurrences of the letter ``a`` in the word + Return the number of occurrences of the letter ``a`` in the word ``self``. INPUT: - - ``a`` -- a letter - - OUTPUT: + - ``a`` -- a letter - - integer + OUTPUT: integer EXAMPLES:: @@ -298,7 +284,6 @@ cdef class WordDatatype_list(WordDatatype): .. SEEALSO:: :meth:`sage.combinat.words.finite_word.FiniteWord_class.number_of_factor_occurrences` - """ return self._data.count(a) @@ -323,7 +308,6 @@ cdef class WordDatatype_str(WordDatatype): sage: w = Word("abba") sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype_str) True - """ self._parent = parent if isinstance(data, str): @@ -343,23 +327,20 @@ cdef class WordDatatype_str(WordDatatype): sage: w = Word('abba') sage: list(iter(w)) ['a', 'b', 'b', 'a'] - """ return iter(self._data) def __richcmp__(self, other, int op): r""" - Equality test for self and other if other is an instance of - WordDatype_str. + Equality test for ``self`` and ``other`` if other is an instance of + ``WordDatype_str``. INPUT: - ``other`` -- a word - - ``op`` -- integer: 0, 1, 2, 3, 4 or 5 + - ``op`` -- integer; 0, 1, 2, 3, 4 or 5 - OUTPUT: - - boolean or NotImplemented + OUTPUT: boolean or NotImplemented EXAMPLES:: @@ -408,7 +389,6 @@ cdef class WordDatatype_str(WordDatatype): True sage: 'c' in w False - """ # we need to override the non standard behaviour of # the __contains__ of python str @@ -429,11 +409,10 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - - ``w`` -- a word, or something that behaves like one (list, tuple, str, ...) - - OUTPUT: + - ``w`` -- a word, or something that behaves like one (``list``, + ``tuple``, ``str``, ...) - - boolean + OUTPUT: boolean EXAMPLES:: @@ -451,22 +430,20 @@ cdef class WordDatatype_str(WordDatatype): cpdef find(self, sub, start=0, end=None): r""" - Returns the index of the first occurrence of sub in self, + Return the index of the first occurrence of sub in self, such that sub is contained within self[start:end]. Returns -1 on failure. INPUT: - - ``sub`` -- string or word to search for. - - ``start`` -- non negative integer (default: 0) specifying - the position from which to start the search. - - ``end`` -- non negative integer (default: None) specifying - the position at which the search must stop. If None, then - the search is performed up to the end of the string. - - OUTPUT: + - ``sub`` -- string or word to search for + - ``start`` -- nonnegative integer (default: 0) specifying + the position from which to start the search. + - ``end`` -- nonnegative integer (default: ``None``); specifying + the position at which the search must stop. If ``None``, then + the search is performed up to the end of the string. - non negative integer or -1 + OUTPUT: nonnegative integer or `-1` EXAMPLES:: @@ -489,22 +466,20 @@ cdef class WordDatatype_str(WordDatatype): def rfind(self, sub, start=0, end=None): r""" - Returns the index of the last occurrence of sub in self, + Return the index of the last occurrence of sub in self, such that sub is contained within self[start:end]. Returns -1 on failure. INPUT: - - ``sub`` -- string or word to search for. - - ``start`` -- non negative integer (default: 0) specifying - the position at which the search must stop. - - ``end`` -- non negative integer (default: None) specifying - the position from which to start the search. If None, then - the search is performed up to the end of the string. + - ``sub`` -- string or word to search for + - ``start`` -- nonnegative integer (default: 0) specifying + the position at which the search must stop. + - ``end`` -- nonnegative integer (default: ``None``); specifying + the position from which to start the search. If ``None``, then + the search is performed up to the end of the string. - OUTPUT: - - non negative integer or -1 + OUTPUT: nonnegative integer or `-1` EXAMPLES:: @@ -539,7 +514,6 @@ cdef class WordDatatype_str(WordDatatype): sage: w = Word("abbabaabababa") sage: len(w) 13 - """ return len(self._data) @@ -552,13 +526,12 @@ cdef class WordDatatype_str(WordDatatype): sage: w = Word("abbabaabababa") sage: w.length() 13 - """ return len(self._data) def __getitem__(self, key): r""" - Implements the :meth:`__getitem__`. + Implement the :meth:`__getitem__`. TESTS:: @@ -579,15 +552,13 @@ cdef class WordDatatype_str(WordDatatype): def __mul__(self, other): r""" - Return the concatenation of self and other. + Return the concatenation of ``self`` and ``other``. INPUT: - - ``other`` -- word represented by a str + - ``other`` -- word represented by a string - OUTPUT: - - word + OUTPUT: word EXAMPLES:: @@ -617,9 +588,7 @@ cdef class WordDatatype_str(WordDatatype): - ``letter`` -- a letter - OUTPUT: - - - integer + OUTPUT: integer EXAMPLES:: @@ -639,7 +608,6 @@ cdef class WordDatatype_str(WordDatatype): .. SEEALSO:: :meth:`sage.combinat.words.finite_word.FiniteWord_class.number_of_factor_occurrences` - """ if len(letter) == 1: return self._data.count(letter) @@ -648,7 +616,7 @@ cdef class WordDatatype_str(WordDatatype): def split(self, sep=None, maxsplit=None): r""" - Returns a list of words, using sep as a delimiter string. + Return a list of words, using sep as a delimiter string. If maxsplit is given, at most maxsplit splits are done. See also the partition method. @@ -660,13 +628,11 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - - ``sep`` -- string or word (default: None) - - - ``maxsplit`` -- positive integer (default: None) + - ``sep`` -- string or word (default: ``None``) - OUTPUT: + - ``maxsplit`` -- positive integer (default: ``None``) - - a list of words + OUTPUT: list of words EXAMPLES: @@ -696,7 +662,7 @@ cdef class WordDatatype_str(WordDatatype): sage: w.split("32") [word: , word: 30301030, word: , word: 12, word: 30, word: , word: 1] - If the separator is not a string a :class:`ValueError` is raised:: + If the separator is not a string a :exc:`ValueError` is raised:: sage: w = Word("le papa du papa du papa etait un petit pioupiou") sage: w.split(Word(['p','a','p','a'])) @@ -768,11 +734,9 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - ``other`` -- a word (an instance of :class:`Word_class`) or a - :class:`str`. + :class:`str` - OUTPUT: - - - boolean + OUTPUT: boolean EXAMPLES:: @@ -793,7 +757,6 @@ cdef class WordDatatype_str(WordDatatype): False sage: u.is_suffix(w) True - """ if isinstance(other, WordDatatype_str): return other._data.endswith(self._data) @@ -809,11 +772,9 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - ``other`` -- a word (an instance of :class:`Word_class`) or a - :class:`str`. - - OUTPUT: + :class:`str` - - boolean + OUTPUT: boolean EXAMPLES:: @@ -825,7 +786,6 @@ cdef class WordDatatype_str(WordDatatype): False sage: u.has_suffix("ababa") True - """ if isinstance(other, WordDatatype_str): return self._data.endswith(other._data) @@ -841,11 +801,9 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - ``other`` -- a word (an instance of :class:`Word_class`) or a - :class:`str`. - - OUTPUT: + :class:`str` - - boolean + OUTPUT: boolean EXAMPLES:: @@ -880,11 +838,9 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - ``other`` -- a word (an instance of :class:`Word_class`) or a - :class:`str`. + :class:`str` - OUTPUT: - - - boolean + OUTPUT: boolean EXAMPLES:: @@ -905,7 +861,6 @@ cdef class WordDatatype_str(WordDatatype): False sage: abba.has_prefix(ab) True - """ if isinstance(other, WordDatatype_str): return self._data.startswith(other._data) @@ -949,30 +904,27 @@ cdef class WordDatatype_tuple(WordDatatype): def __iter__(self): r""" - Return an iterator that iterates through the letters of self. + Return an iterator that iterates through the letters of ``self``. EXAMPLES:: sage: w = Word((0,1,1,0)) sage: list(iter(w)) [0, 1, 1, 0] - """ return iter(self._data) def __richcmp__(self, other, int op): r""" - Equality test for self and other if other is an instance of - WordDatype_tuple. + Equality test for ``self`` and ``other`` if other is an instance of + ``WordDatype_tuple``. INPUT: - ``other`` -- a word - - ``op`` -- integer: 0, 1, 2, 3, 4 or 5 - - OUTPUT: + - ``op`` -- integer; 0, 1, 2, 3, 4 or 5 - boolean or NotImplemented + OUTPUT: boolean or NotImplemented EXAMPLES:: @@ -1020,7 +972,6 @@ cdef class WordDatatype_tuple(WordDatatype): sage: w = Word((0,1,1,0)) sage: len(w) 4 - """ return len(self._data) @@ -1033,7 +984,6 @@ cdef class WordDatatype_tuple(WordDatatype): sage: w = Word((0,1,1,0)) sage: w.length() 4 - """ return len(self._data) @@ -1052,17 +1002,16 @@ cdef class WordDatatype_tuple(WordDatatype): True sage: 3 in w False - """ return a in self._data def __getitem__(self, key): r""" - Implements ``__getitem__`` for words stored as tuples. + Implement ``__getitem__`` for words stored as tuples. INPUT: - - ``key`` -- an integer + - ``key`` -- integer OUTPUT: @@ -1079,7 +1028,6 @@ cdef class WordDatatype_tuple(WordDatatype): word: 3579 sage: all(w[i] == i for i in range(100)) True - """ if isinstance(key, slice): return self._parent(self._data[key]) @@ -1087,15 +1035,13 @@ cdef class WordDatatype_tuple(WordDatatype): def __mul__(self, other): r""" - Return the concatenation of self and other. + Return the concatenation of ``self`` and ``other``. INPUT: - ``other`` -- word represented by a tuple - OUTPUT: - - word + OUTPUT: word EXAMPLES:: diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 6665658a71e..5803709ba5b 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -108,8 +108,8 @@ def _build_tab(sym, tab, W): class LowerChristoffelWord(FiniteWord_list): r""" - Returns the lower Christoffel word of slope `p/q`, where `p` and - `q` are relatively prime non-negative integers, over the given + Return the lower Christoffel word of slope `p/q`, where `p` and + `q` are relatively prime nonnegative integers, over the given two-letter alphabet. The *Christoffel word of slope `p/q`* is obtained from the @@ -144,14 +144,14 @@ def __init__(self, p, q, alphabet=(0, 1), algorithm='cf'): r""" INPUT: - - ``p`` -- integer coprime with ``q``. - - ``q`` -- integer coprime with ``p``. - - ``alphabet`` -- sequence of two elements (default: (0, 1)). - - ``algorithm`` -- construction method (default: 'cf'). + - ``p`` -- integer coprime with `q` + - ``q`` -- integer coprime with `p` + - ``alphabet`` -- sequence of two elements (default: (0, 1)) + - ``algorithm`` -- construction method (default: ``'cf'``). It can be one of the following: - - ``'linear'`` -- linear algorithm in the length of the word. - - ``'cf'`` -- fast method using continued fraction. + - ``'linear'`` -- linear algorithm in the length of the word + - ``'cf'`` -- fast method using continued fraction TESTS:: @@ -257,7 +257,7 @@ def markoff_number(self): def standard_factorization(self): r""" - Returns the standard factorization of the Christoffel word ``self``. + Return the standard factorization of the Christoffel word ``self``. The *standard factorization* of a Christoffel word `w` is the unique factorization of `w` into two Christoffel words. @@ -367,7 +367,7 @@ class WordGenerator: """ def ThueMorseWord(self, alphabet=(0, 1), base=2): r""" - Returns the (Generalized) Thue-Morse word over the given alphabet. + Return the (Generalized) Thue-Morse word over the given alphabet. There are several ways to define the Thue-Morse word `t`. We use the following definition: `t[n]` is the sum modulo `m` of @@ -377,10 +377,10 @@ def ThueMorseWord(self, alphabet=(0, 1), base=2): INPUT: - - ``alphabet`` -- (default: (0, 1) ) any container that is suitable to - build an instance of OrderedAlphabet (list, tuple, str, ...) + - ``alphabet`` -- (default: ``(0, 1)``) any container that is suitable + to build an instance of OrderedAlphabet (``list``, ``tuple``, ``str``, ...) - - ``base`` -- an integer (default : 2) greater or equal to 2 + - ``base`` -- integer (default: 2); greater than or equal to 2 EXAMPLES: @@ -435,7 +435,7 @@ def ThueMorseWord(self, alphabet=(0, 1), base=2): def _ThueMorseWord_nth_digit(self, n, alphabet=(0, 1), base=2): r""" - Returns the `n`-th letter of the (Generalized) Thue-Morse word. + Return the `n`-th letter of the (Generalized) Thue-Morse word. The `n`-th digit of the Thue-Morse word can be defined as the number of bits in the 2-complement representation of the position @@ -448,9 +448,9 @@ def _ThueMorseWord_nth_digit(self, n, alphabet=(0, 1), base=2): INPUT: - - ``n`` -- integer, the position - - ``alphabet`` -- an alphabet (default : (0, 1) ) of size at least 2 - - ``base`` -- an integer (default : 2) greater or equal to 2 + - ``n`` -- integer; the position + - ``alphabet`` -- an alphabet (default: (0, 1)) of size at least 2 + - ``base`` -- integer (default: 2) greater than or equal to 2 OUTPUT: @@ -489,17 +489,17 @@ def _ThueMorseWord_nth_digit(self, n, alphabet=(0, 1), base=2): else: return alphabet[ZZ(sum(ZZ(n).digits(base=base))).mod(m)] - def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): + def FibonacciWord(self, alphabet=(0, 1), construction_method='recursive'): r""" - Returns the Fibonacci word on the given two-letter alphabet. + Return the Fibonacci word on the given two-letter alphabet. INPUT: - - ``alphabet`` -- any container of length two that is suitable to - build an instance of OrderedAlphabet (list, tuple, str, ...) + - ``alphabet`` -- any container of length two that is suitable to + build an instance of OrderedAlphabet (``list``, ``tuple``, ``str``, ...) - - ``construction_method`` -- can be any of the following: - "recursive", "fixed point", "function" (see below for definitions). + - ``construction_method`` -- can be any of the following: + "recursive", "fixed point", "function" (see below for definitions) Recursive construction: the Fibonacci word is the limit of the following sequence of words: `S_0 = 0`, `S_1 = 01`, @@ -514,19 +514,19 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): #. if the next letter is `1`, append `1` to the word; #. move to the next letter of the word. - Function: Over the alphabet `\{1, 2\}`, the n-th letter of the + Function: Over the alphabet `\{1, 2\}`, the `n`-th letter of the Fibonacci word is `\lfloor (n+2) \varphi \rfloor - \lfloor (n+1) \varphi \rfloor` where `\varphi=(1+\sqrt{5})/2` is the golden ratio. EXAMPLES:: - sage: w = words.FibonacciWord(construction_method="recursive"); w + sage: w = words.FibonacciWord(construction_method='recursive'); w word: 0100101001001010010100100101001001010010... :: - sage: v = words.FibonacciWord(construction_method="recursive", alphabet='ab'); v + sage: v = words.FibonacciWord(construction_method='recursive', alphabet='ab'); v word: abaababaabaababaababaabaababaabaababaaba... :: @@ -591,7 +591,7 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): def _FibonacciWord_RecursiveConstructionIterator(self,alphabet=(0,1)): r""" - Iterates over the symbols of the Fibonacci word, as defined by + Iterate over the symbols of the Fibonacci word, as defined by the following recursive construction: the Fibonacci word is the limit of the sequence `S_0 = 0`, `S_1 = 01`, `S_n = S_{n-1} S_{n-2}` for `n \geq 2`. @@ -617,7 +617,7 @@ def _FibonacciWord_RecursiveConstructionIterator(self,alphabet=(0,1)): def FixedPointOfMorphism(self, morphism, first_letter): r""" - Returns the fixed point of the morphism beginning with + Return the fixed point of the morphism beginning with ``first_letter``. A *fixed point* of a morphism `\varphi` is a word `w` such that @@ -625,15 +625,13 @@ def FixedPointOfMorphism(self, morphism, first_letter): INPUT: - - ``morphism`` -- endomorphism prolongable on ``first_letter``. It - must be something that WordMorphism's constructor understands - (dict, str, ...). + - ``morphism`` -- endomorphism prolongable on ``first_letter``. It + must be something that WordMorphism's constructor understands + (dict, str, ...). - - ``first_letter`` -- the first letter of the fixed point + - ``first_letter`` -- the first letter of the fixed point - OUTPUT: - - The fixed point of the morphism beginning with ``first_letter`` + OUTPUT: the fixed point of the morphism beginning with ``first_letter`` EXAMPLES:: @@ -663,7 +661,7 @@ def FixedPointOfMorphism(self, morphism, first_letter): def CodingOfRotationWord(self, alpha, beta, x=0, alphabet=(0,1)): r""" - Returns the infinite word obtained from the coding of rotation of + Return the infinite word obtained from the coding of rotation of parameters `(\alpha,\beta, x)` over the given two-letter alphabet. The *coding of rotation* corresponding to the parameters @@ -725,7 +723,7 @@ def _CodingOfRotationWord_function(self, n, alpha, beta, x=0, alphabet=(0,1)): @rename_keyword(cf='slope') def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): r""" - Returns the characteristic Sturmian word (also called standard + Return the characteristic Sturmian word (also called standard Sturmian word) of given slope. Over a binary alphabet `\{a,b\}`, the characteristic Sturmian @@ -746,23 +744,22 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): INPUT: - - ``slope`` -- the slope of the word. It can be one of the following: - - - real number in `]0, 1[` + - ``slope`` -- the slope of the word. It can be one of the following: - - iterable over the continued fraction expansion of a real - number in `]0, 1[` + - real number in `]0, 1[` - - ``alphabet`` -- any container of length two that is suitable to - build an instance of OrderedAlphabet (list, tuple, str, ...) + - iterable over the continued fraction expansion of a real + number in `]0, 1[` - - ``bits`` -- integer (optional and considered only if ``slope`` is - a real number) the number of bits to consider when computing the - continued fraction. + - ``alphabet`` -- any container of length two that is suitable to + build an instance of OrderedAlphabet (``list``, ``tuple``, ``str``, + ...) - OUTPUT: + - ``bits`` -- integer (optional and considered only if ``slope`` is + a real number); the number of bits to consider when computing the + continued fraction - word + OUTPUT: word ALGORITHM: @@ -906,19 +903,17 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): r""" - Returns an iterator over the symbols of the characteristic + Return an iterator over the symbols of the characteristic Sturmian word of slope ``cf``. INPUT: - ``cf`` -- iterator, the continued fraction expansion of a real - number in `]0, 1[`. + number in `]0, 1[` - ``alphabet`` -- the alphabet (default: ``(0,1)``) of the output - OUTPUT: - - iterator of letters + OUTPUT: iterator of letters ALGORITHM: @@ -974,7 +969,7 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): def KolakoskiWord(self, alphabet=(1,2)): r""" - Returns the Kolakoski word over the given alphabet and + Return the Kolakoski word over the given alphabet and starting with the first letter of the alphabet. Let `A = \{a,b\}` be an alphabet, where `a` and `b` are two @@ -993,12 +988,10 @@ def KolakoskiWord(self, alphabet=(1,2)): INPUT: - - ``alphabet`` -- (default: (1,2)) an iterable of two positive - integers + - ``alphabet`` -- (default: (1,2)) an iterable of two positive + integers - OUTPUT: - - infinite word + OUTPUT: infinite word EXAMPLES: @@ -1055,7 +1048,7 @@ def KolakoskiWord(self, alphabet=(1,2)): def _KolakoskiWord_iterator(self, a=1, b=2): r""" - Returns an iterator over the Kolakoski word over ``{a,b}`` + Return an iterator over the Kolakoski word over ``{a,b}`` and starting with ``a``. Let `A = \{a,b\}` be an alphabet, where `a` and `b` are two @@ -1071,14 +1064,12 @@ def _KolakoskiWord_iterator(self, a=1, b=2): INPUT: - - ``a`` -- positive integer (default: 1), the first letter occurring - in the returned Kolakoski word. - - ``b`` -- positive integer (default: 2), the second and last letter - occurring in the returned Kolakoski word. + - ``a`` -- positive integer (default: 1); the first letter occurring + in the returned Kolakoski word + - ``b`` -- positive integer (default: 2); the second and last letter + occurring in the returned Kolakoski word - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES: @@ -1113,7 +1104,7 @@ def _KolakoskiWord_iterator(self, a=1, b=2): def LowerMechanicalWord(self, alpha, rho=0, alphabet=None): r""" - Returns the lower mechanical word with slope `\alpha` and + Return the lower mechanical word with slope `\alpha` and intercept `\rho` The lower mechanical word `s_{\alpha,\rho}` with @@ -1130,9 +1121,7 @@ def LowerMechanicalWord(self, alpha, rho=0, alphabet=None): - ``alphabet`` -- iterable of two elements or ``None`` (default: ``None``) - OUTPUT: - - infinite word + OUTPUT: infinite word EXAMPLES:: @@ -1173,7 +1162,7 @@ def LowerMechanicalWord(self, alpha, rho=0, alphabet=None): def UpperMechanicalWord(self, alpha, rho=0, alphabet=None): r""" - Returns the upper mechanical word with slope `\alpha` and + Return the upper mechanical word with slope `\alpha` and intercept `\rho` The upper mechanical word `s'_{\alpha,\rho}` with @@ -1190,9 +1179,7 @@ def UpperMechanicalWord(self, alpha, rho=0, alphabet=None): - ``alphabet`` -- iterable of two elements or ``None`` (default: ``None``) - OUTPUT: - - infinite word + OUTPUT: infinite word EXAMPLES:: @@ -1233,7 +1220,7 @@ def UpperMechanicalWord(self, alpha, rho=0, alphabet=None): def StandardEpisturmianWord(self, directive_word): r""" - Returns the standard episturmian word (or epistandard word) directed by + Return the standard episturmian word (or epistandard word) directed by directive_word. Over a 2-letter alphabet, this function gives characteristic Sturmian words. @@ -1251,8 +1238,8 @@ def StandardEpisturmianWord(self, directive_word): INPUT: - - ``directive_word`` -- an infinite word or a period of a periodic - infinite word + - ``directive_word`` -- an infinite word or a period of a periodic + infinite word EXAMPLES:: @@ -1297,9 +1284,9 @@ def _StandardEpisturmianWord_LetterIterator(self, directive_word): INPUT: - - ``directive_word`` -- an infinite word or a finite word. If - directive_word is finite, then it is repeated to give - an infinite word. + - ``directive_word`` -- an infinite word or a finite word; if + directive_word is finite, then it is repeated to give + an infinite word TESTS:: @@ -1333,9 +1320,7 @@ def MinimalSmoothPrefix(self, n): - ``n`` -- the desired length of the prefix - OUTPUT: - - word -- the prefix + OUTPUT: word; the prefix .. NOTE:: @@ -1369,11 +1354,11 @@ def RandomWord(self, n, m=2, alphabet=None): INPUT: - - ``n`` -- integer, the length of the word - - ``m`` -- integer (default 2), the size of the output alphabet - - ``alphabet`` -- (default is `\{0,1,...,m-1\}`) any container of - length m that is suitable to build an instance of - OrderedAlphabet (list, tuple, str, ...) + - ``n`` -- integer; the length of the word + - ``m`` -- integer (default: 2); the size of the output alphabet + - ``alphabet`` -- (default: `\{0,1,...,m-1\}`) any container of + length m that is suitable to build an instance of + OrderedAlphabet (``list``, ``tuple``, ``str``, ...) EXAMPLES:: @@ -1409,8 +1394,8 @@ def RandomWord(self, n, m=2, alphabet=None): def UpperChristoffelWord(self, p, q, alphabet=(0,1)): r""" - Returns the upper Christoffel word of slope `p/q`, where - `p` and `q` are relatively prime non-negative + Return the upper Christoffel word of slope `p/q`, where + `p` and `q` are relatively prime nonnegative integers, over the given alphabet. The *upper Christoffel word of slope `p/q`* is equal to the @@ -1422,9 +1407,8 @@ def UpperChristoffelWord(self, p, q, alphabet=(0,1)): INPUT: - - ``alphabet`` -- any container of length two that is - suitable to build an instance of OrderedAlphabet (list, tuple, str, - ...) + - ``alphabet`` -- any container of length two that is suitable to build + an instance of OrderedAlphabet (``list``, ``tuple``, ``str``, ...) EXAMPLES:: @@ -1459,7 +1443,7 @@ def UpperChristoffelWord(self, p, q, alphabet=(0,1)): @cached_method def _fibonacci_tile(self, n, q_0=None, q_1=3): r""" - Returns the word `q_n` defined by the recurrence below. + Return the word `q_n` defined by the recurrence below. The sequence `(q_n)_{n\in\NN}` is defined by `q_0=\varepsilon`, `q_1=3` and @@ -1475,11 +1459,11 @@ def _fibonacci_tile(self, n, q_0=None, q_1=3): INPUT: - - ``n`` -- non negative integer - - ``q_0`` -- first initial value (default: None) It can be None, 0, 1, - 2 or 3. - - ``q_1`` -- second initial value (default: 3) It can be None, 0, 1, 2 - or 3. + - ``n`` -- nonnegative integer + - ``q_0`` -- first initial value (default: ``None``); it can be + ``None``, 0, 1, 2 or 3 + - ``q_1`` -- second initial value (default: 3); it can be ``None``, 0, + 1, 2 or 3 EXAMPLES:: @@ -1519,7 +1503,7 @@ def _fibonacci_tile(self, n, q_0=None, q_1=3): def fibonacci_tile(self, n): r""" - Returns the `n`-th Fibonacci Tile [BmBGL09]_. + Return the `n`-th Fibonacci Tile [BmBGL09]_. EXAMPLES:: @@ -1537,7 +1521,7 @@ def fibonacci_tile(self, n): def dual_fibonacci_tile(self, n): r""" - Returns the `n`-th dual Fibonacci Tile [BmBGL09]_. + Return the `n`-th dual Fibonacci Tile [BmBGL09]_. EXAMPLES:: @@ -1556,7 +1540,7 @@ def dual_fibonacci_tile(self, n): def _s_adic_iterator(self, sequence, letters): r""" - Returns the iterator over the `s`-adic infinite word obtained from a + Return the iterator over the `s`-adic infinite word obtained from a sequence of morphisms applied on letters where the hypothesis of nested prefixes is used. @@ -1577,15 +1561,13 @@ def _s_adic_iterator(self, sequence, letters): INPUT: - - ``sequence`` -- An iterable sequence of morphisms. It may be finite - or infinite. - - ``letters`` -- An iterable sequence of letters. The image of the + - ``sequence`` -- an iterable sequence of morphisms. It may be finite + or infinite + - ``letters`` -- an iterable sequence of letters. The image of the (i+1)-th letter under the (i+1)-th morphism must start with the i-th - letter. + letter - OUTPUT: - - iterator of letters + OUTPUT: iterator of letters EXAMPLES: @@ -1660,7 +1642,7 @@ def _s_adic_iterator(self, sequence, letters): def s_adic(self, sequence, letters, morphisms=None): r""" - Returns the `s`-adic infinite word obtained from a sequence of + Return the `s`-adic infinite word obtained from a sequence of morphisms applied on a letter. DEFINITION (from [Fogg]_): @@ -1680,20 +1662,18 @@ def s_adic(self, sequence, letters, morphisms=None): INPUT: - - ``sequence`` -- An iterable sequence of indices or of morphisms. It + - ``sequence`` -- an iterable sequence of indices or of morphisms. It may be finite or infinite. If ``sequence`` is infinite, the image of the `(i+1)`-th letter under the `(i+1)`-th morphism must start with the `i`-th letter. - - ``letters`` -- A letter or a sequence of letters. + - ``letters`` -- a letter or a sequence of letters - ``morphisms`` -- dict, list, callable or ``None`` (default: ``None``) an object that maps indices to morphisms. If ``None``, then ``sequence`` must consist of morphisms. - OUTPUT: - - A word. + OUTPUT: a word EXAMPLES: @@ -1932,11 +1912,9 @@ def PalindromicDefectWord(self, k=1, alphabet='ab'): - ``k`` -- positive integer (default: 1) - - ``alphabet`` -- iterable (default: ``'ab'``) of size two - - OUTPUT: + - ``alphabet`` -- iterable of size two (default: ``'ab'``) - finite word + OUTPUT: finite word EXAMPLES:: @@ -1984,7 +1962,7 @@ def PalindromicDefectWord(self, k=1, alphabet='ab'): def BaumSweetWord(self): r""" - Returns the Baum-Sweet Word. + Return the Baum-Sweet Word. The Baum-Sweet Sequence is an infinite word over the alphabet `\{0,1\}` defined by the following string substitution rules: @@ -2019,7 +1997,7 @@ def BaumSweetWord(self): .. MATH:: b_n = \begin{cases} - 1, & \text{if the binary representation of} n \text{ contains no block of consecutive 0's of odd length}\\ + 1, & \text{if the binary representation of} n \text{ contains no block of consecutive 0s of odd length}\\ 0, & \text{otherwise}\\ \end{cases}\\ diff --git a/src/sage/combinat/words/word_infinite_datatypes.py b/src/sage/combinat/words/word_infinite_datatypes.py index a78d461d078..d36b3f80976 100644 --- a/src/sage/combinat/words/word_infinite_datatypes.py +++ b/src/sage/combinat/words/word_infinite_datatypes.py @@ -27,8 +27,8 @@ def __init__(self, parent, callable, length=None): INPUT: - ``parent`` -- a parent - - ``callable`` -- a callable defined on ``range(stop=length)`` - - ``length`` -- (default: ``None``) nonnegative integer or ``None`` + - ``callable`` -- a callable defined on ``range(stop=length)`` + - ``length`` -- (default: ``None``) nonnegative integer or ``None`` EXAMPLES:: @@ -323,8 +323,8 @@ def __init__(self, parent, callable, length=None): INPUT: - ``parent`` -- a parent - - ``callable`` -- a callable defined on ``range(stop=length)`` - - ``length`` -- (default: ``None``) nonnegative integer or ``None`` + - ``callable`` -- a callable defined on ``range(stop=length)`` + - ``length`` -- (default: ``None``) nonnegative integer or ``None`` EXAMPLES:: @@ -545,7 +545,6 @@ def __reduce__(self): sage: w = Word(range(5)) + Word('abcde') sage: w.__reduce__() (Finite words over Set of Python objects of class 'object', ([0, 1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e'],)) - """ from sage.misc.fpickle import pickle_function try: @@ -590,12 +589,12 @@ def __init__(self, parent, iter, length=None): INPUT: - ``parent`` -- a parent - - ``iter`` -- an iterator - - ``length`` -- (default: ``None``) the length of the word + - ``iter`` -- an iterator + - ``length`` -- (default: ``None``) the length of the word EXAMPLES:: - sage: w = Word(iter("abbabaab"), length="unknown", caching=False); w + sage: w = Word(iter("abbabaab"), length='unknown', caching=False); w word: abbabaab sage: isinstance(w, sage.combinat.words.word_infinite_datatypes.WordDatatype_iter) True @@ -604,14 +603,14 @@ def __init__(self, parent, iter, length=None): sage: w.length() 8 sage: s = "abbabaabbaababbabaababbaabbabaabbaababbaabbabaabab" - sage: w = Word(iter(s), length="unknown", caching=False); w + sage: w = Word(iter(s), length='unknown', caching=False); w word: abbabaabbaababbabaababbaabbabaabbaababba... sage: w.length() is None True :: - sage: w = Word(iter("abbabaab"), length="finite", caching=False); w + sage: w = Word(iter("abbabaab"), length='finite', caching=False); w word: abbabaab sage: isinstance(w, sage.combinat.words.word_infinite_datatypes.WordDatatype_iter) True @@ -668,7 +667,7 @@ def __getitem__(self, key): A word from an iterator without a length specified:: - sage: w = Word(iter("abbabaabbaab"), length="finite", caching=False); w + sage: w = Word(iter("abbabaabbaab"), length='finite', caching=False); w word: abbabaabbaab Test getitems with indexes:: @@ -923,19 +922,19 @@ def __init__(self, parent, iter, length=None): INPUT: - ``parent`` -- a parent - - ``iter`` -- an iterator - - ``length`` -- (default: ``None``) the length of the word + - ``iter`` -- an iterator + - ``length`` -- (default: ``None``) the length of the word EXAMPLES:: sage: import itertools sage: Word(itertools.cycle("abbabaab")) word: abbabaababbabaababbabaababbabaababbabaab... - sage: w = Word(iter("abbabaab"), length="finite"); w + sage: w = Word(iter("abbabaab"), length='finite'); w word: abbabaab sage: w.length() 8 - sage: w = Word(iter("abbabaab"), length="unknown"); w + sage: w = Word(iter("abbabaab"), length='unknown'); w word: abbabaab sage: w.length() 8 @@ -990,7 +989,7 @@ def __getitem__(self, key): A word from an iterator without a length specified:: - sage: w = Word(iter("abbabaabbaab"), length="unknown"); w + sage: w = Word(iter("abbabaabbaab"), length='unknown'); w word: abbabaabbaab Test getitems with indexes:: @@ -1015,50 +1014,50 @@ def __getitem__(self, key): Suffixes:: - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[0:] word: abbabaabbaab - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[1:] word: bbabaabbaab Prefixes:: - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[:0] word: - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[:5] word: abbab With positive steps:: - sage: w = Word(iter("abbabaabbaab"), length="unknown") + sage: w = Word(iter("abbabaabbaab"), length='unknown') sage: w[::2] word: abbaba With a negative start position, the word must be expanded! :: - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[-2:] word: ab - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[-20:] word: abbabaabbaab With a negative stop position, the word must be expanded! :: - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[:-1] word: abbabaabbaa - sage: w = Word(iter("abbabaabbaab"), length="unknown") + sage: w = Word(iter("abbabaabbaab"), length='unknown') sage: w[:-10] word: ab With a negative step, the word may or may not be expanded; it depends on the slice:: - sage: w = Word(iter("abbabaabbaab"), length="finite") + sage: w = Word(iter("abbabaabbaab"), length='finite') sage: w[::-2] word: babaab sage: w = Word(iter("abbabaabbaab")) diff --git a/src/sage/combinat/words/word_options.py b/src/sage/combinat/words/word_options.py index 28ab578b791..44bc5ea071e 100644 --- a/src/sage/combinat/words/word_options.py +++ b/src/sage/combinat/words/word_options.py @@ -24,21 +24,21 @@ def WordOptions(**kwargs): """ - Sets the global options for elements of the word class. + Set the global options for elements of the word class. The defaults are for words to be displayed in list notation. INPUT: - - ``display`` -- 'string' (default), or 'list', words are displayed in - string or list notation. - - ``truncate`` -- boolean (default: ``True``), whether to truncate the string - output of long words (see truncate_length below). - - ``truncate_length`` -- integer (default: 40), if the length of the word - is greater than this integer, then the word is truncated. - - ``letter_separator`` -- (string, default: ",") if the string - representation of letters have length greater than 1, then - the letters are separated by this string in the string - representation of the word. + - ``display`` -- 'string' (default), or 'list', words are displayed in + string or list notation + - ``truncate`` -- boolean (default: ``True``); whether to truncate the string + output of long words (see truncate_length below) + - ``truncate_length`` -- integer (default: 40); if the length of the word + is greater than this integer, then the word is truncated + - ``letter_separator`` -- string (default: ``','``); if the string + representation of letters have length greater than 1, then + the letters are separated by this string in the string + representation of the word If no parameters are set, then the function returns a copy of the options dictionary. @@ -68,7 +68,7 @@ def WordOptions(**kwargs): word_options['display'] = kwargs['display'] elif 'truncate' in kwargs: if not isinstance(kwargs['truncate'], bool): - raise ValueError("truncate must be True or False") + raise ValueError("truncate must be ``True`` or False") else: word_options['truncate'] = kwargs['truncate'] elif 'truncate_length' in kwargs: @@ -88,11 +88,11 @@ def WordOptions(**kwargs): word_options['identifier'] = kwargs['identifier'] elif 'cache' in kwargs: if not isinstance(kwargs['cache'], bool): - raise ValueError("cache must be True or False") + raise ValueError("cache must be ``True`` or False") else: word_options['cache'] = kwargs['cache'] elif 'old_repr' in kwargs: if not isinstance(kwargs['old_repr'], bool): - raise ValueError("old_repr must be True or False") + raise ValueError("old_repr must be ``True`` or False") else: word_options['old_repr'] = kwargs['old_repr'] diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 426fcc73b56..e940582f83c 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -61,7 +61,7 @@ def Words(alphabet=None, length=None, finite=True, infinite=True): """ - Returns the combinatorial class of words of length k over an alphabet. + Return the combinatorial class of words of length k over an alphabet. EXAMPLES:: @@ -114,7 +114,7 @@ def Words(alphabet=None, length=None, finite=True, infinite=True): class AbstractLanguage(Parent): r""" - Abstract base class + Abstract base class. This is *not* to be used by any means. This class gather previous features of set of words (prior to :issue:`19619`). In the future that class might @@ -192,7 +192,7 @@ def alphabet(self): def identity_morphism(self): r""" - Returns the identity morphism from self to itself. + Return the identity morphism from ``self`` to itself. EXAMPLES:: @@ -229,7 +229,7 @@ def _check(self, w, length=40): - ``w`` -- word - - ``length`` -- integer (default: ``40``) + - ``length`` -- integer (default: `40`) EXAMPLES:: @@ -293,7 +293,7 @@ def _sortkey_letters(self, letter1): rk = self.alphabet().rank return rk(letter1) - def __eq__(self, other): + def __eq__(self, other) -> bool: r""" TESTS:: @@ -309,7 +309,7 @@ def __eq__(self, other): return self is other or (type(self) is type(other) and self.alphabet() == other.alphabet()) - def __ne__(self, other): + def __ne__(self, other) -> bool: r""" TESTS:: @@ -383,10 +383,10 @@ def factors(self): @lazy_attribute def _element_classes(self): r""" - Returns a dictionary that gives the class of the element of self. + Return a dictionary that gives the class of the element of ``self``. The word may be finite, infinite or of unknown length. - Its data may be str, list, tuple, a callable or an iterable. + Its data may be string, list, tuple, a callable or an iterable. For callable and iterable, the data may be cached. EXAMPLES: @@ -445,7 +445,7 @@ def _word_from_word(self, data): INPUT: - - ``data`` -- word + - ``data`` -- word EXAMPLES:: @@ -479,7 +479,8 @@ def _word_from_word(self, data): return self._element_classes['list'](self, data) from sage.combinat.words.word_datatypes import (WordDatatype_str, - WordDatatype_list, WordDatatype_tuple) + WordDatatype_list, + WordDatatype_tuple) if isinstance(data, WordDatatype_str): return self._element_classes['str'](self, data._data) if isinstance(data, WordDatatype_tuple): @@ -487,8 +488,8 @@ def _word_from_word(self, data): if isinstance(data, WordDatatype_list): return self._element_classes['list'](self, data._data) - from sage.combinat.words.word_infinite_datatypes import (WordDatatype_callable, - WordDatatype_iter) + from sage.combinat.words.word_infinite_datatypes import \ + (WordDatatype_callable, WordDatatype_iter) if isinstance(data, WordDatatype_callable): length = data.length() data = data._func @@ -508,10 +509,10 @@ def _word_from_callable(self, data, length, caching=True): INPUT: - - ``data`` -- callable - - ``length`` -- integer or ``None`` or "infinite" or ``Infinity`` - - ``caching`` -- (default: ``True``) True or False. Whether to keep a cache - of the letters computed by the callable. + - ``data`` -- callable + - ``length`` -- integer or ``None`` or ``'infinite'`` or ``Infinity`` + - ``caching`` -- boolean (default: ``True``); whether to keep a cache + of the letters computed by the callable EXAMPLES:: @@ -533,12 +534,12 @@ def _word_from_iter(self, data, length=None, caching=True): INPUT: - - ``data`` -- iterable + - ``data`` -- iterable - - ``length`` -- (optional) integer + - ``length`` -- (optional) integer - - ``caching`` -- (default: ``True``) True or False. Whether to keep a cache - of the letters computed by the iterator. + - ``caching`` -- boolean (default: ``True``); whether to keep a cache + of the letters computed by the iterator EXAMPLES:: @@ -557,28 +558,28 @@ def _word_from_iter(self, data, length=None, caching=True): def __call__(self, data=None, length=None, datatype=None, caching=True, check=True): r""" - Construct a new word object with parent self. + Construct a new word object with parent ``self``. INPUT: - - ``data`` -- (default: None) list, string, tuple, iterator, None - (shorthand for []), or a callable defined on [0,1,...,length]. + - ``data`` -- (default: ``None``) list, string, tuple, iterator, ``None`` + (shorthand for []), or a callable defined on [0,1,...,length] - - ``length`` -- integer (default: None). Only used if the data is an iterator or - a callable. It determines the length of the word. + - ``length`` -- integer (default: ``None``); only used if the data is + an iterator or a callable. It determines the length of the word - - ``datatype`` -- (default: None) None, "char", "list", "str", - "tuple", "iter", "callable" or "pickled_function". If None, then - the function tries to guess this from the data. + - ``datatype`` -- (default: ``None``) ``None``, "char", "list", "str", + "tuple", "iter", "callable" or "pickled_function"; if ``None``, then + the function tries to guess this from the data - - ``caching`` -- (default: ``True``) True or False. Whether to keep a cache - of the letters computed by an iterator or callable. + - ``caching`` -- boolean (default: ``True``); whether to keep a cache + of the letters computed by an iterator or callable - - ``check`` -- (default: ``True``) True or False. Whether to check if - the 40 first letters are in the parent alphabet. This is a - check done to test for small programming errors. Since we also - support infinite words, we cannot really implement a more - accurate check. + - ``check`` -- boolean (default: ``True``); whether to check if + the 40 first letters are in the parent alphabet. This is a + check done to test for small programming errors. Since we also + support infinite words, we cannot really implement a more + accurate check. .. NOTE:: @@ -610,9 +611,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Word with string constructed from other types:: - sage: W([0,1,1,0,1,0,0,1], datatype="str") + sage: W([0,1,1,0,1,0,0,1], datatype='str') word: 01101001 - sage: W((0,1,1,0,1,0,0,1), datatype="str") + sage: W((0,1,1,0,1,0,0,1), datatype='str') word: 01101001 Word with list:: @@ -622,9 +623,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Word with list constructed from other types:: - sage: W("01101001", datatype="list") + sage: W("01101001", datatype='list') word: 01101001 - sage: W((0,1,1,0,1,0,0,1), datatype="list") + sage: W((0,1,1,0,1,0,0,1), datatype='list') word: 01101001 Word with tuple:: @@ -634,9 +635,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Word with tuple constructed from other types:: - sage: W([0,1,1,0,1,0,0,1], datatype="tuple") + sage: W([0,1,1,0,1,0,0,1], datatype='tuple') word: 01101001 - sage: W("01101001", datatype="str") + sage: W("01101001", datatype='str') word: 01101001 Word with iterator:: @@ -849,7 +850,7 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr self._check(w) return w - def _repr_(self): + def _repr_(self) -> str: """ EXAMPLES:: @@ -860,7 +861,7 @@ def _repr_(self): def _an_element_(self): r""" - Return an element of self. + Return an element of ``self``. EXAMPLES:: @@ -875,22 +876,22 @@ def _an_element_(self): """ try: some_letters = list(self.alphabet().some_elements()) - except Exception: + except (TypeError, ValueError, AttributeError, NotImplementedError): return self([]) if len(some_letters) == 1: return self([some_letters[0]] * 3) - else: - a, b = some_letters[:2] - return self([b, a, b]) + + a, b = some_letters[:2] + return self([b, a, b]) def iterate_by_length(self, l=1): r""" - Returns an iterator over all the words of self of length l. + Return an iterator over all the words of ``self`` of length `l`. INPUT: - - ``l`` -- integer (default: 1), the length of the desired words + - ``l`` -- integer (default: 1); the length of the desired words EXAMPLES:: @@ -912,16 +913,26 @@ def iterate_by_length(self, l=1): Traceback (most recent call last): ... TypeError: the parameter l (='a') must be an integer + + TESTS:: + + sage: W = FiniteWords(NN) + sage: list(W.iterate_by_length(1)) + Traceback (most recent call last): + ... + NotImplementedError: cannot iterate over words for infinite alphabets """ if not isinstance(l, (int, Integer)): raise TypeError("the parameter l (=%r) must be an integer" % l) cls = self._element_classes['tuple'] + if not self.alphabet().is_finite(): + raise NotImplementedError("cannot iterate over words for infinite alphabets") for w in itertools.product(self.alphabet(), repeat=l): yield cls(self, w) def __iter__(self): r""" - Returns an iterator over all the words of self. + Return an iterator over all the words of ``self``. The iterator outputs the words in shortlex order (see :wikipedia:`Shortlex_order`), i.e. first by increasing length and then @@ -961,9 +972,9 @@ def __iter__(self): for l in itertools.count(): yield from self.iterate_by_length(l) - def __contains__(self, x): + def __contains__(self, x) -> bool: """ - Tests whether ``self`` contains ``x``. + Test whether ``self`` contains ``x``. OUTPUT: @@ -992,12 +1003,12 @@ def __contains__(self, x): def random_element(self, length=None, *args, **kwds): r""" - Returns a random finite word on the given alphabet. + Return a random finite word on the given alphabet. INPUT: - - ``length`` -- (optional) the length of the word. If not set, will use - a uniformly random number between 0 and 10. + - ``length`` -- (optional) the length of the word; if not set, will use + a uniformly random number between 0 and 10 - all other argument are transmitted to the random generator of the alphabet @@ -1030,30 +1041,28 @@ def iter_morphisms(self, arg=None, codomain=None, min_length=1): INPUT: - - ``arg`` -- (default: ``None``) It can be one of the following: + - ``arg`` -- (default: ``None``) it can be one of the following: - - ``None`` -- then the method iterates through all morphisms. + - ``None`` -- then the method iterates through all morphisms - - tuple `(a, b)` of two integers -- It specifies the range + - tuple `(a, b)` of two integers -- it specifies the range ``range(a, b)`` of values to consider for the sum of the length - of the image of each letter in the alphabet. + of the image of each letter in the alphabet - - list of nonnegative integers -- The length of the list must be - equal to the size of the alphabet, and the i-th integer of - ``arg`` determines the length of the word mapped to by the i-th - letter of the (ordered) alphabet. + - list of nonnegative integers -- the length of the list must be + equal to the size of the alphabet, and the `i`-th integer of + ``arg`` determines the length of the word mapped to by the `i`-th + letter of the (ordered) alphabet - - ``codomain`` -- (default: ``None``) a combinatorial class of words. - By default, ``codomain`` is ``self``. + - ``codomain`` -- (default: ``None``) a combinatorial class of words; + by default, ``codomain`` is ``self`` - - ``min_length`` -- (default: 1) nonnegative integer. If ``arg`` is + - ``min_length`` -- nonnegative integer (default: 1); if ``arg`` is not specified, then iterate through all the morphisms where the length of the images of each letter in the alphabet is at least ``min_length``. This is ignored if ``arg`` is a list. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES: @@ -1216,11 +1225,9 @@ def iter_morphisms(self, arg=None, codomain=None, min_length=1): Traceback (most recent call last): ... TypeError: codomain (=a) must be an instance of FiniteWords - """ n = self.alphabet().cardinality() - if min_length < 0: - min_length = 0 + min_length = max(min_length, 0) # create an iterable of compositions (all "compositions" if arg is # None, or [arg] otherwise) if arg is None: @@ -1266,7 +1273,7 @@ def iter_morphisms(self, arg=None, codomain=None, min_length=1): class InfiniteWords(AbstractLanguage): def cardinality(self): r""" - Return the cardinality of this set + Return the cardinality of this set. EXAMPLES:: @@ -1319,10 +1326,10 @@ def shift(self): @lazy_attribute def _element_classes(self): r""" - Returns a dictionary that gives the class of the element of self. + Return a dictionary that gives the class of the element of ``self``. The word may be finite, infinite or of unknown length. - Its data may be str, list, tuple, a callable or an iterable. + Its data may be string, list, tuple, a callable or an iterable. For callable and iterable, the data may be cached. EXAMPLES: @@ -1384,7 +1391,7 @@ def _word_from_word(self, data): INPUT: - - ``data`` -- word + - ``data`` -- word EXAMPLES:: @@ -1430,10 +1437,10 @@ def _word_from_callable(self, data, caching=True): INPUT: - - ``data`` -- callable + - ``data`` -- callable - - ``caching`` -- (default: ``True``) True or False. Whether to keep a cache - of the letters computed by the callable. + - ``caching`` -- boolean (default: ``True``); whether to keep a cache + of the letters computed by the callable EXAMPLES:: @@ -1453,10 +1460,10 @@ def _word_from_iter(self, data, caching=True): INPUT: - - ``data`` -- iterable + - ``data`` -- iterable - - ``caching`` -- (default: ``True``) True or False. Whether to keep a cache - of the letters computed by the iterator. + - ``caching`` -- boolean (default: ``True``); whether to keep a cache + of the letters computed by the iterator EXAMPLES:: @@ -1470,24 +1477,24 @@ def _word_from_iter(self, data, caching=True): def __call__(self, data=None, datatype=None, caching=True, check=True): r""" - Construct a new word object with parent self. + Construct a new word object with parent ``self``. INPUT: - - ``data`` -- iterator or a callable + - ``data`` -- iterator or a callable - - ``datatype`` -- (default: None) None, "iter", "callable" or - "pickled_function". If None, then the function tries to guess - this from the data. + - ``datatype`` -- (default: ``None``) ``None``, "iter", "callable" or + "pickled_function"; if ``None``, then the function tries to guess + this from the data - - ``caching`` -- (default: ``True``) True or False. Whether to keep a - cache of the letters computed by an iterator or callable. + - ``caching`` -- boolean (default: ``True``); whether to keep a + cache of the letters computed by an iterator or callable - - ``check`` -- (default: ``True``) True or False. Whether to check if - the 40 first letters are in the parent alphabet. This is a - check done to test for small programming errors. Since we also - support infinite words, we cannot really implement a more - accurate check. + - ``check`` -- boolean (default: ``True``); whether to check if + the 40 first letters are in the parent alphabet. This is a + check done to test for small programming errors. Since we also + support infinite words, we cannot really implement a more + accurate check. .. NOTE:: @@ -1575,7 +1582,7 @@ def __call__(self, data=None, datatype=None, caching=True, check=True): def _repr_(self): r""" - Returns a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -1586,7 +1593,7 @@ def _repr_(self): def _an_element_(self): r""" - Return an element of self. + Return an element of ``self``. EXAMPLES:: @@ -1771,35 +1778,35 @@ def _word_from_iter(self, data, caching=True): def __call__(self, data=None, length=None, datatype=None, caching=True, check=True): r""" - Construct a new word object with parent self. + Construct a new word object with parent ``self``. INPUT: - - ``data`` -- (default: None) list, string, tuple, iterator, None - (shorthand for []), or a callable defined on [0,1,...,length]. + - ``data`` -- (default: ``None``) list, string, tuple, iterator, ``None`` + (shorthand for []), or a callable defined on [0,1,...,length] - - ``length`` -- (default: None) This is dependent on the type of data. - It is ignored for words defined by lists, strings, tuples, - etc., because they have a naturally defined length. - For callables, this defines the domain of definition, - which is assumed to be [0, 1, 2, ..., length-1]. - For iterators: Infinity if you know the iterator will not - terminate (default); "unknown" if you do not know whether the - iterator terminates; "finite" if you know that the iterator - terminates, but do not know the length. + - ``length`` -- (default: ``None``) this is dependent on the type of data. + It is ignored for words defined by lists, strings, tuples, + etc., because they have a naturally defined length. + For callables, this defines the domain of definition, + which is assumed to be [0, 1, 2, ..., length-1]. + For iterators: Infinity if you know the iterator will not + terminate (default); ``'unknown'`` if you do not know whether the + iterator terminates; ``'finite'`` if you know that the iterator + terminates, but do not know the length. - - ``datatype`` -- (default: None) None, "char", "list", "str", - "tuple", "iter", "callable" or "pickled_function". If None, then - the function tries to guess this from the data. + - ``datatype`` -- (default: ``None``) ``None``, "char", "list", "str", + "tuple", "iter", "callable" or "pickled_function"; if ``None``, then + the function tries to guess this from the data. - - ``caching`` -- (default: ``True``) True or False. Whether to keep a cache - of the letters computed by an iterator or callable. + - ``caching`` -- boolean (default: ``True``); whether to keep a cache + of the letters computed by an iterator or callable - - ``check`` -- (default: ``True``) True or False. Whether to check if - the 40 first letters are in the parent alphabet. This is a - check done to test for small programming errors. Since we also - support infinite words, we cannot really implement a more - accurate check. + - ``check`` -- boolean (default: ``True``); whether to check if + the 40 first letters are in the parent alphabet. This is a + check done to test for small programming errors. Since we also + support infinite words, we cannot really implement a more + accurate check. .. NOTE:: @@ -1829,9 +1836,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Word with string constructed from other types:: - sage: Words()([0,1,1,0,1,0,0,1], datatype="str") + sage: Words()([0,1,1,0,1,0,0,1], datatype='str') word: 01101001 - sage: Words()((0,1,1,0,1,0,0,1), datatype="str") + sage: Words()((0,1,1,0,1,0,0,1), datatype='str') word: 01101001 Word with list:: @@ -1841,9 +1848,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Word with list constructed from other types:: - sage: Words()("01101001", datatype="list") + sage: Words()("01101001", datatype='list') word: 01101001 - sage: Words()((0,1,1,0,1,0,0,1), datatype="list") + sage: Words()((0,1,1,0,1,0,0,1), datatype='list') word: 01101001 Word with tuple:: @@ -1853,9 +1860,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Word with tuple constructed from other types:: - sage: Words()([0,1,1,0,1,0,0,1], datatype="tuple") + sage: Words()([0,1,1,0,1,0,0,1], datatype='tuple') word: 01101001 - sage: Words()("01101001", datatype="str") + sage: Words()("01101001", datatype='str') word: 01101001 Word with iterator:: @@ -1865,9 +1872,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,... sage: Words()(iter("abbabaab")) # iterators default to infinite words word: abbabaab - sage: Words()(iter("abbabaab"), length="unknown") + sage: Words()(iter("abbabaab"), length='unknown') word: abbabaab - sage: Words()(iter("abbabaab"), length="finite") + sage: Words()(iter("abbabaab"), length='finite') word: abbabaab Word with function (a 'callable'):: @@ -2058,7 +2065,7 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr def _repr_(self): r""" - Returns a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -2076,20 +2083,20 @@ def __init__(self, words, n): r""" INPUT: - - ``words`` -- a set of finite words + - ``words`` -- set of finite words - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer TESTS:: sage: Words([0,1], length=-42) Traceback (most recent call last): ... - ValueError: n = -42 must be non-negative + ValueError: n = -42 must be nonnegative """ n = ZZ(n) if n < 0: - raise ValueError("n = {} must be non-negative".format(n)) + raise ValueError("n = {} must be nonnegative".format(n)) self._words = words self._n = n @@ -2152,7 +2159,7 @@ def __call__(self, data, *args, **kwds): def list(self): r""" - Returns a list of all the words contained in self. + Return a list of all the words contained in ``self``. EXAMPLES:: @@ -2171,7 +2178,7 @@ def list(self): def _an_element_(self): r""" - Return an element of self. + Return an element of ``self``. EXAMPLES:: @@ -2262,7 +2269,7 @@ def __contains__(self, x): def cardinality(self): r""" - Returns the number of words of length `n` from alphabet. + Return the number of words of length `n` from alphabet. EXAMPLES:: diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 7a79e69c3be..33552e4cc46 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -43,9 +43,7 @@ def YangBaxterGraph(partition=None, root=None, operators=None): tuples of the form `(v, l)` where `v` is a successor of `u` and `l` is the label of the edge from `u` to `v`. - OUTPUT: - - - Either: + OUTPUT: either: - :class:`YangBaxterGraph_partition` -- if partition is defined - :class:`YangBaxterGraph_generic` -- if partition is ``None`` @@ -126,8 +124,8 @@ def __init__(self, root, operators): - ``root`` -- the root vertex of the graph - - ``operators`` -- a list of callables that map vertices to (new) - vertices. + - ``operators`` -- list of callables that map vertices to (new) + vertices .. NOTE:: @@ -413,7 +411,7 @@ def vertices(self, sort=False) -> list: INPUT: - - ``sort`` -- boolean (default ``False``) whether to sort the vertices + - ``sort`` -- boolean (default: ``False``); whether to sort the vertices EXAMPLES:: @@ -456,9 +454,7 @@ def vertex_relabelling_dict(self, v, relabel_operator) -> dict: - ``relabel_operator`` -- function mapping a vertex and a label to the image of the vertex - OUTPUT: - - - dictionary pairing vertices with the corresponding image of ``v`` + OUTPUT: dictionary pairing vertices with the corresponding image of ``v`` EXAMPLES:: @@ -488,10 +484,10 @@ def relabel_vertices(self, v, relabel_operator, inplace=True): INPUT: - - ``v`` -- tuple, Permutation, ... + - ``v`` -- tuple, Permutation, etc. - ``inplace`` -- if ``True``, modifies ``self``; otherwise returns a - modified copy of ``self``. + modified copy of ``self`` EXAMPLES:: @@ -523,7 +519,7 @@ def relabel_edges(self, edge_dict, inplace=True): INPUT: - - ``edge_dict`` -- a dictionary keyed by the (unlabelled) edges. + - ``edge_dict`` -- dictionary keyed by the (unlabelled) edges EXAMPLES:: @@ -678,9 +674,9 @@ def _swap_operator(self, operator, u): INPUT: - - ``i`` -- positive integer between 1 and len(u)-1, inclusive + - ``i`` -- positive integer between ``1`` and ``len(u)-1``, inclusive - - ``u`` -- tuple, list, permutation, .... + - ``u`` -- tuple, list, permutation, etc. EXAMPLES:: @@ -709,9 +705,7 @@ def vertex_relabelling_dict(self, v) -> dict: - ``v`` -- an object - OUTPUT: - - - dictionary pairing vertices with the corresponding image of ``v`` + OUTPUT: dictionary pairing vertices with the corresponding image of ``v`` EXAMPLES:: @@ -735,10 +729,10 @@ def relabel_vertices(self, v, inplace=True): INPUT: - - ``v`` -- tuple, Permutation, ... + - ``v`` -- tuple, Permutation, etc. - ``inplace`` -- if ``True``, modifies ``self``; otherwise - returns a modified copy of ``self``. + returns a modified copy of ``self`` EXAMPLES:: @@ -877,8 +871,8 @@ def __call__(self, u): def position(self): r""" - ``self`` is the operator that swaps positions ``i`` and ``i+1``. This - method returns ``i``. + Return ``i`` where ``self`` is the operator that swaps positions ``i`` + and ``i+1``. EXAMPLES:: @@ -913,7 +907,7 @@ def __call__(self, u): - ``i`` -- positive integer between ``1`` and ``len(u)-1``, inclusive - - ``u`` -- tuple, list, permutation, .... + - ``u`` -- tuple, list, permutation, etc. EXAMPLES:: diff --git a/src/sage/cpython/_py2_random.py b/src/sage/cpython/_py2_random.py index 0da28217eec..e5f160b11cc 100644 --- a/src/sage/cpython/_py2_random.py +++ b/src/sage/cpython/_py2_random.py @@ -45,6 +45,7 @@ import _random + class Random(_random.Random): """Random number generator base class used by bound module functions. @@ -59,7 +60,6 @@ class Random(_random.Random): methods: random(), seed(), getstate(), setstate() and jumpahead(). Optionally, implement a getrandbits() method so that randrange() can cover arbitrarily large ranges. - """ VERSION = 3 # used by getstate/setstate @@ -155,7 +155,6 @@ def randrange(self, start, stop=None, step=1, _int=int, _maxwidth=1 << BPF): This fixes the problem with randint() which includes the endpoint; in Python this is usually not what you want. - """ # This code is a bit messy to make it fast for the @@ -257,7 +256,6 @@ def shuffle(self, x, random=None): Optional arg random is a 0-argument function returning a random float in [0.0, 1.0); by default, the standard random.random. - """ if random is None: @@ -347,7 +345,6 @@ def triangular(self, low=0.0, high=1.0, mode=None): and having a given mode value in-between. http://en.wikipedia.org/wiki/Triangular_distribution - """ u = self.random() try: @@ -366,7 +363,6 @@ def normalvariate(self, mu, sigma): """Normal distribution. mu is the mean, and sigma is the standard deviation. - """ # mu = mean, sigma = standard deviation @@ -393,7 +389,6 @@ def lognormvariate(self, mu, sigma): If you take the natural logarithm of this distribution, you'll get a normal distribution with mean mu and standard deviation sigma. mu can have any value, and sigma must be greater than zero. - """ return _exp(self.normalvariate(mu, sigma)) @@ -407,7 +402,6 @@ def expovariate(self, lambd): a reserved word in Python.) Returned values range from 0 to positive infinity if lambd is positive, and from negative infinity to 0 if lambd is negative. - """ # lambd: rate lambd = 1/mean # ('lambda' is a Python reserved word) @@ -425,7 +419,6 @@ def vonmisesvariate(self, mu, kappa): kappa is the concentration parameter, which must be greater than or equal to zero. If kappa is equal to zero, this distribution reduces to a uniform random angle over the range 0 to 2*pi. - """ # mu: mean angle (in radians between 0 and 2*pi) # kappa: concentration parameter kappa (>= 0) @@ -476,7 +469,6 @@ def gammavariate(self, alpha, beta): x ** (alpha - 1) * math.exp(-x / beta) pdf(x) = -------------------------------------- math.gamma(alpha) * beta ** alpha - """ # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 @@ -545,7 +537,6 @@ def gauss(self, mu, sigma): slightly faster than the normalvariate() function. Not thread-safe without a lock around calls. - """ # When x and y are two variables from [0, 1), uniformly @@ -596,7 +587,6 @@ def betavariate(self, alpha, beta): Conditions on the parameters are alpha > 0 and beta > 0. Returned values range between 0 and 1. - """ # This version due to Janne Sinkkonen, and matches all the std @@ -622,7 +612,6 @@ def weibullvariate(self, alpha, beta): """Weibull distribution. alpha is the scale parameter and beta is the shape parameter. - """ # Jain, pg. 499; bug fix courtesy Bill Arms diff --git a/src/sage/cpython/atexit.pyx b/src/sage/cpython/atexit.pyx index 8bc12e2d2d9..8f833ab1437 100644 --- a/src/sage/cpython/atexit.pyx +++ b/src/sage/cpython/atexit.pyx @@ -25,12 +25,12 @@ cdef class restore_atexit: INPUT: - - ``run`` (bool, default: ``False``) -- if True, when exiting the + - ``run`` -- boolean (default: ``False``); if ``True``, when exiting the context (but before restoring the old exit functions), run all - atexit functions which were added inside the context. + atexit functions which were added inside the context - - ``clear`` (bool, default: equal to ``run``) -- if True, clear - already registered atexit handlers upon entering the context. + - ``clear`` -- boolean (default: equal to ``run``); if ``True``, clear + already registered atexit handlers upon entering the context .. WARNING:: diff --git a/src/sage/cpython/debug.pyx b/src/sage/cpython/debug.pyx index 79aba1a7fbe..f4e0a44046f 100644 --- a/src/sage/cpython/debug.pyx +++ b/src/sage/cpython/debug.pyx @@ -73,7 +73,7 @@ def getattr_debug(obj, name, default=_no_default): - ``obj`` -- the object whose attribute is requested - - ``name`` -- (string) the name of the attribute + - ``name`` -- string; the name of the attribute - ``default`` -- default value to return if attribute was not found @@ -220,7 +220,7 @@ def getattr_debug(obj, name, default=_no_default): def type_debug(cls): """ - Print all internals of the type ``cls`` + Print all internals of the type ``cls``. EXAMPLES:: diff --git a/src/sage/cpython/dict_del_by_value.pyx b/src/sage/cpython/dict_del_by_value.pyx index 44f0700206e..eff4e944ef6 100644 --- a/src/sage/cpython/dict_del_by_value.pyx +++ b/src/sage/cpython/dict_del_by_value.pyx @@ -54,8 +54,8 @@ cdef int del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_ INPUT: - ``PyDictObject *mp`` -- pointer to a dict - - ``PyObject *value`` -- pointer to a value of the dictionary - - ``Py_hash_t hash`` -- hash of the key by which the value is stored in the dict + - ``PyObject *value`` -- pointer to a value of the dictionary + - ``Py_hash_t hash`` -- hash of the key by which the value is stored in the dict The hash bucket determined by the given hash is searched for the item containing the given value. If this item cannot be found, the function is @@ -143,9 +143,9 @@ def test_del_dictitem_by_exact_value(D, value, h): INPUT: - - ``D`` -- a Python ````. - - ``value`` -- an object that is value ``D``. - - ``h`` -- the hash of the key under which to find ``value`` in ``D``. + - ``D`` -- a Python ```` + - ``value`` -- an object that is value ``D`` + - ``h`` -- the hash of the key under which to find ``value`` in ``D`` The underlying cdef function deletes an item from ``D`` that is in the hash bucket determined by ``h`` and whose value is identic with diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx index 899fbe62ecc..bebe646037f 100644 --- a/src/sage/cpython/getattr.pyx +++ b/src/sage/cpython/getattr.pyx @@ -38,7 +38,7 @@ cdef extern from "Python.h": cdef class AttributeErrorMessage: """ - Tries to emulate the standard Python :class:`AttributeError` message. + Try to emulate the standard Python :exc:`AttributeError` message. .. NOTE:: @@ -69,7 +69,7 @@ cdef class AttributeErrorMessage: TESTS: - The error message used for the :class:`AttributeError` is a unique object + The error message used for the :exc:`AttributeError` is a unique object and is changed inplace. This is for reasons of efficiency. Hence, if one really needs the error message as a string, then one should make a copy of its string representation before it changes. :: @@ -239,12 +239,12 @@ cpdef getattr_from_other_class(self, cls, name): - ``cls`` -- a new-style class - - ``name`` -- a string + - ``name`` -- string - If self is an instance of cls, raises an :class:`AttributeError`, to + If ``self`` is an instance of cls, raises an :exc:`AttributeError`, to avoid a double lookup. This function is intended to be called from __getattr__, and so should not be called if name is an attribute - of self. + of ``self``. EXAMPLES:: @@ -301,7 +301,7 @@ cpdef getattr_from_other_class(self, cls, name): TypeError: descriptor '__weakref__' for 'A' objects doesn't apply to ...'sage.rings.integer.Integer' object - When this occurs, an :class:`AttributeError` is raised:: + When this occurs, an :exc:`AttributeError` is raised:: sage: getattr_from_other_class(1, A, "__weakref__") Traceback (most recent call last): @@ -368,7 +368,7 @@ cpdef getattr_from_other_class(self, cls, name): # Not a descriptor return attribute # Conditionally defined lazy_attributes don't work well with fake subclasses - # (a :class:`TypeError` is raised if the lazy attribute is not defined). + # (a :exc:`TypeError` is raised if the lazy attribute is not defined). # For the moment, we ignore that when this occurs. # Other descriptors (including __weakref__) also break. try: @@ -382,7 +382,7 @@ cpdef getattr_from_other_class(self, cls, name): def dir_with_other_class(self, *cls): r""" - Emulates ``dir(self)``, as if self was also an instance ``cls``, + Emulates ``dir(self)``, as if ``self`` was also an instance ``cls``, right after ``caller_class`` in the method resolution order (``self.__class__.mro()``) diff --git a/src/sage/cpython/meson.build b/src/sage/cpython/meson.build new file mode 100644 index 00000000000..fdd99770782 --- /dev/null +++ b/src/sage/cpython/meson.build @@ -0,0 +1,44 @@ +py.install_sources( + '__init__.py', + '_py2_random.py', + 'all.py', + 'cython_metaclass.h', + 'cython_metaclass.pxd', + 'dict_del_by_value.pxd', + 'dict_internal.h', + 'getattr.pxd', + 'pycore_long.h', + 'pycore_long.pxd', + 'python_debug.h', + 'python_debug.pxd', + 'pyx_visit.h', + 'string.pxd', + 'string_impl.h', + 'type.pxd', + 'wrapperdescr.pxd', + subdir: 'sage/cpython', +) + +extension_data = { + 'atexit' : files('atexit.pyx'), + 'builtin_types' : files('builtin_types.pyx'), + 'cython_metaclass' : files('cython_metaclass.pyx'), + 'debug' : files('debug.pyx'), + 'dict_del_by_value' : files('dict_del_by_value.pyx'), + 'getattr' : files('getattr.pyx'), + 'string' : files('string.pyx'), + 'type' : files('type.pyx'), + 'wrapperdescr' : files('wrapperdescr.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/cpython', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/cpython/wrapperdescr.pyx b/src/sage/cpython/wrapperdescr.pyx index 1e74353e798..b1b1e67cc79 100644 --- a/src/sage/cpython/wrapperdescr.pyx +++ b/src/sage/cpython/wrapperdescr.pyx @@ -44,13 +44,13 @@ def wrapperdescr_call(slotwrapper, self, *args, **kwds): INPUT: - - ``slotwrapper`` -- a slot wrapper (for example ``int.__add__``). + - ``slotwrapper`` -- a slot wrapper (for example ``int.__add__``) - ``self`` -- the first positional argument. Normally, this should be of the correct type (an ``int`` when calling ``int.__add__``). However, this check is skipped: you can pass an arbitrary object. - - ``*args``, ``**kwds`` -- further arguments. + - ``*args``, ``**kwds`` -- further arguments .. WARNING:: diff --git a/src/sage/crypto/all.py b/src/sage/crypto/all.py index 811ee2c6a78..cd6fd8cc95e 100644 --- a/src/sage/crypto/all.py +++ b/src/sage/crypto/all.py @@ -20,4 +20,8 @@ 'lfsr_autocorrelation', 'lfsr_connection_polynomial', ]) + + +import sage.crypto.key_exchange.catalog as key_exchange + del lazy_import diff --git a/src/sage/crypto/block_cipher/des.py b/src/sage/crypto/block_cipher/des.py index 6799dd8e4c1..182de4a14b3 100644 --- a/src/sage/crypto/block_cipher/des.py +++ b/src/sage/crypto/block_cipher/des.py @@ -346,14 +346,14 @@ def __init__(self, rounds=None, keySchedule='DES_KS', keySize=64, doFinalRound=T INPUT: - - ``rounds`` -- integer (default: ``None``); the number of rounds. If + - ``rounds`` -- integer (default: ``None``); the number of rounds. If ``None`` the number of rounds of the key schedule is used. - - ``keySchedule`` -- (default: ``'DES_KS'``); the key schedule that + - ``keySchedule`` -- (default: ``'DES_KS'``) the key schedule that will be used for encryption and decryption. If ``'DES_KS'`` the default DES key schedule is used. - - ``keySize`` -- (default: ``64``); the key length in bits. Must be + - ``keySize`` -- (default: ``64``) the key length in bits. Must be ``56`` of ``64``. In the latter case the key contains 8 parity bits. - ``doFinalRound`` -- boolean (default: ``True``); if ``False`` a swap @@ -484,7 +484,7 @@ def encrypt(self, plaintext, key): INPUT: - ``plaintext`` -- integer or bit list-like; the plaintext that will be - encrypted. + encrypted - ``key`` -- integer or bit list-like; the key @@ -794,7 +794,7 @@ def __init__(self, rounds=16, masterKey=None): INPUT: - - ``rounds`` -- integer (default: ``16``); the number of rounds + - ``rounds`` -- integer (default: `16`); the number of rounds ``self`` can create keys for - ``masterKey`` -- integer or bit list-like (default: ``None``); the @@ -915,14 +915,14 @@ def __repr__(self): def __getitem__(self, r): r""" - Computes the sub key for round ``r`` derived from initial master key. + Compute the sub key for round ``r`` derived from initial master key. The key schedule object has to have been initialised with the `masterKey` argument. INPUT: - - ``r`` integer; the round for which the sub key is computed + - ``r`` -- integer; the round for which the sub key is computed EXAMPLES:: @@ -1043,9 +1043,7 @@ def convert_to_vector(I, L): - ``L`` -- integer; the desired bit length of the ouput - OUTPUT: - - - the ``L``-bit vector representation of ``I`` + OUTPUT: the ``L``-bit vector representation of ``I`` EXAMPLES:: diff --git a/src/sage/crypto/block_cipher/miniaes.py b/src/sage/crypto/block_cipher/miniaes.py index 6eb9568b9fc..0a421c17e5e 100644 --- a/src/sage/crypto/block_cipher/miniaes.py +++ b/src/sage/crypto/block_cipher/miniaes.py @@ -35,6 +35,7 @@ from sage.rings.integer import Integer from sage.structure.sage_object import SageObject + class MiniAES(SageObject): r""" This class implements the Mini Advanced Encryption Standard (Mini-AES) @@ -91,9 +92,9 @@ class MiniAES(SageObject): 0100101101000101 sage: P = bin.encoding("Encrypt this secret message!"); P 01000101011011100110001101110010011110010111000001110100001000000111010001101000011010010111001100100000011100110110010101100011011100100110010101110100001000000110110101100101011100110111001101100001011001110110010100100001 - sage: C = maes(P, key, algorithm="encrypt"); C + sage: C = maes(P, key, algorithm='encrypt'); C 11100000101000010110001101101001110110010010111011010001100111100000101000101111100110010010100001110101011100111001000010101000001111000101010011010001100111100111001100000001101100110110101001001000011100000101010110110101 - sage: plaintxt = maes(C, key, algorithm="decrypt") + sage: plaintxt = maes(C, key, algorithm='decrypt') sage: plaintxt == P True @@ -109,9 +110,9 @@ class MiniAES(SageObject): 0000000100100011010001010110011110001001101010111100110111101111 sage: key = maes.integer_to_binary(key); key 0010001110110000 - sage: C = maes(P, key, algorithm="encrypt"); C + sage: C = maes(P, key, algorithm='encrypt'); C 0011101000101110010011000101010100011101010000111000100100011010 - sage: plaintxt = maes(C, key, algorithm="decrypt") + sage: plaintxt = maes(C, key, algorithm='decrypt') sage: plaintxt == P True @@ -258,7 +259,7 @@ def __init__(self): Integer(14): K("x^3 + x^2 + x"), Integer(15): K("x^3 + x^2 + x+ 1") } - def __call__(self, B, key, algorithm="encrypt"): + def __call__(self, B, key, algorithm='encrypt'): r""" Apply Mini-AES encryption or decryption on the binary string ``B`` using the key ``key``. The flag ``algorithm`` controls what action is @@ -273,10 +274,10 @@ def __call__(self, B, key, algorithm="encrypt"): - ``key`` -- a secret key; this must be a 16-bit binary string - - ``algorithm`` -- (default: ``"encrypt"``) a string; a flag to signify + - ``algorithm`` -- (default: ``'encrypt'``) a string; a flag to signify whether encryption or decryption is to be applied to the binary - string ``B``. The encryption flag is ``"encrypt"`` and the decryption - flag is ``"decrypt"``. + string ``B``. The encryption flag is ``'encrypt'`` and the decryption + flag is ``'decrypt'``. OUTPUT: @@ -292,9 +293,9 @@ def __call__(self, B, key, algorithm="encrypt"): 0100101101000101 sage: P = bin.encoding("Encrypt this secret message!"); P 01000101011011100110001101110010011110010111000001110100001000000111010001101000011010010111001100100000011100110110010101100011011100100110010101110100001000000110110101100101011100110111001101100001011001110110010100100001 - sage: C = maes(P, key, algorithm="encrypt"); C + sage: C = maes(P, key, algorithm='encrypt'); C 11100000101000010110001101101001110110010010111011010001100111100000101000101111100110010010100001110101011100111001000010101000001111000101010011010001100111100111001100000001101100110110101001001000011100000101010110110101 - sage: plaintxt = maes(C, key, algorithm="decrypt") + sage: plaintxt = maes(C, key, algorithm='decrypt') sage: plaintxt == P True @@ -329,20 +330,20 @@ def __call__(self, B, key, algorithm="encrypt"): ... ValueError: secret key must be a 16-bit binary string - The value for ``algorithm`` must be either ``"encrypt"`` or - ``"decrypt"``:: + The value for ``algorithm`` must be either ``'encrypt'`` or + ``'decrypt'``:: sage: B = bin.encoding("ABCD") sage: key = bin.encoding("KE") - sage: maes(B, key, algorithm="ABC") + sage: maes(B, key, algorithm='ABC') Traceback (most recent call last): ... ValueError: algorithm must be either 'encrypt' or 'decrypt' - sage: maes(B, key, algorithm="e") + sage: maes(B, key, algorithm='e') Traceback (most recent call last): ... ValueError: algorithm must be either 'encrypt' or 'decrypt' - sage: maes(B, key, algorithm="d") + sage: maes(B, key, algorithm='d') Traceback (most recent call last): ... ValueError: algorithm must be either 'encrypt' or 'decrypt' @@ -406,7 +407,7 @@ def __eq__(self, other): def __repr__(self): r""" - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -431,9 +432,7 @@ def add_key(self, block, rkey): - ``rkey`` -- a round key; a `2 \times 2` matrix with entries over `\GF{2^4}` - OUTPUT: - - - The matrix addition of ``block`` and ``rkey``. + OUTPUT: the matrix addition of ``block`` and ``rkey`` EXAMPLES: @@ -590,9 +589,7 @@ def decrypt(self, C, key): - ``key`` -- a secret key for this Mini-AES block cipher; must be a `2 \times 2` matrix over the finite field `\GF{2^4}` - OUTPUT: - - - The plaintext corresponding to ``C``. + OUTPUT: the plaintext corresponding to ``C`` EXAMPLES: @@ -723,13 +720,13 @@ def decrypt(self, C, key): # undo the result of round 2 plaintext = self.add_key(C, rkey2) plaintext = self.shift_row(plaintext) - plaintext = self.nibble_sub(plaintext, algorithm="decrypt") + plaintext = self.nibble_sub(plaintext, algorithm='decrypt') # undo the result of round 1 plaintext = self.add_key(plaintext, rkey1) plaintext = self.mix_column(plaintext) plaintext = self.shift_row(plaintext) - plaintext = self.nibble_sub(plaintext, algorithm="decrypt") + plaintext = self.nibble_sub(plaintext, algorithm='decrypt') # undo the result of round 0 plaintext = self.add_key(plaintext, rkey0) @@ -762,9 +759,7 @@ def encrypt(self, P, key): - ``key`` -- a secret key for this Mini-AES block cipher; must be a `2 \times 2` matrix over the finite field `\GF{2^4}` - OUTPUT: - - - The ciphertext corresponding to ``P``. + OUTPUT: the ciphertext corresponding to ``P`` EXAMPLES: @@ -884,13 +879,13 @@ def encrypt(self, P, key): ciphertext = self.add_key(P, rkey0) # round 1 - ciphertext = self.nibble_sub(ciphertext, algorithm="encrypt") + ciphertext = self.nibble_sub(ciphertext, algorithm='encrypt') ciphertext = self.shift_row(ciphertext) ciphertext = self.mix_column(ciphertext) ciphertext = self.add_key(ciphertext, rkey1) # round 2 - ciphertext = self.nibble_sub(ciphertext, algorithm="encrypt") + ciphertext = self.nibble_sub(ciphertext, algorithm='encrypt') ciphertext = self.shift_row(ciphertext) ciphertext = self.add_key(ciphertext, rkey2) @@ -1028,7 +1023,7 @@ def mix_column(self, block): [K("x"), K("x + 1")] ] ) return M * block - def nibble_sub(self, block, algorithm="encrypt"): + def nibble_sub(self, block, algorithm='encrypt'): r""" Substitute a nibble (or a block of 4 bits) using the following S-box: @@ -1108,15 +1103,13 @@ def nibble_sub(self, block, algorithm="encrypt"): - ``block`` -- a `2 \times 2` matrix with entries over `\GF{2^4}` - - ``algorithm`` -- (default: ``"encrypt"``) a string; a flag to signify + - ``algorithm`` -- (default: ``'encrypt'``) a string; a flag to signify whether this nibble-sub operation is used for encryption or - decryption. The encryption flag is ``"encrypt"`` and the decryption - flag is ``"decrypt"``. - - OUTPUT: + decryption. The encryption flag is ``'encrypt'`` and the decryption + flag is ``'decrypt'``. - - A `2 \times 2` matrix resulting from applying an S-box on - entries of the `2 \times 2` matrix ``block``. + OUTPUT: a `2 \times 2` matrix resulting from applying an S-box on + entries of the `2 \times 2` matrix ``block``. EXAMPLES: @@ -1127,7 +1120,7 @@ def nibble_sub(self, block, algorithm="encrypt"): sage: K = FiniteField(16, "x") sage: MS = MatrixSpace(K, 2, 2) sage: mat = MS([[K("x^3 + x^2 + x + 1"), K("0")], [K("x^2 + x + 1"), K("x^3 + x")]]) - sage: maes.nibble_sub(mat, algorithm="encrypt") + sage: maes.nibble_sub(mat, algorithm='encrypt') [ x^2 + x + 1 x^3 + x^2 + x] [ x^3 x^2 + x] @@ -1141,11 +1134,11 @@ def nibble_sub(self, block, algorithm="encrypt"): [x^2 + x x] [x^2 + x x^3 + 1] - sage: maes.nibble_sub(B, algorithm="encrypt") + sage: maes.nibble_sub(B, algorithm='encrypt') [ x^3 + x + 1 x^3 + x^2 + 1] [ x^3 + x + 1 x^3 + x] - sage: maes.nibble_sub(B, algorithm="decrypt") + sage: maes.nibble_sub(B, algorithm='decrypt') [ x^3 + x x^2] [ x^3 + x x^3 + x^2 + 1] @@ -1158,11 +1151,11 @@ def nibble_sub(self, block, algorithm="encrypt"): [ x x^2 + x] [ x^3 x^3 + x^2 + x] - sage: maes.nibble_sub(P, algorithm="encrypt") + sage: maes.nibble_sub(P, algorithm='encrypt') [x^3 + x^2 + 1 x^3 + x + 1] [ x + 1 0] - sage: maes.nibble_sub(P, algorithm="decrypt") + sage: maes.nibble_sub(P, algorithm='decrypt') [ x^2 x^3 + x] [x^2 + x + 1 0] @@ -1189,20 +1182,20 @@ def nibble_sub(self, block, algorithm="encrypt"): TypeError: input block must be a 2 x 2 matrix over GF(16) The value for the option ``algorithm`` must be either the string - ``"encrypt"`` or ``"decrypt"``:: + ``'encrypt'`` or ``'decrypt'``:: sage: K = FiniteField(16, "x") sage: MS = MatrixSpace(K, 2, 2) sage: mat = MS([[K("x^3 + x^2 + x + 1"), K("0")], [K("x^2 + x + 1"), K("x^3 + x")]]) - sage: maes.nibble_sub(mat, algorithm="abc") + sage: maes.nibble_sub(mat, algorithm='abc') Traceback (most recent call last): ... ValueError: the algorithm for nibble-sub must be either 'encrypt' or 'decrypt' - sage: maes.nibble_sub(mat, algorithm="e") + sage: maes.nibble_sub(mat, algorithm='e') Traceback (most recent call last): ... ValueError: the algorithm for nibble-sub must be either 'encrypt' or 'decrypt' - sage: maes.nibble_sub(mat, algorithm="d") + sage: maes.nibble_sub(mat, algorithm='d') Traceback (most recent call last): ... ValueError: the algorithm for nibble-sub must be either 'encrypt' or 'decrypt' @@ -1284,11 +1277,9 @@ def round_key(self, key, n): - ``key`` -- the secret key - - ``n`` -- non-negative integer; the round number + - ``n`` -- nonnegative integer; the round number - OUTPUT: - - - The `n`-th round key. + OUTPUT: the `n`-th round key EXAMPLES: @@ -1430,9 +1421,7 @@ def shift_row(self, block): - ``block`` -- a `2 \times 2` matrix with entries over `\GF{2^4}` - OUTPUT: - - - A `2 \times 2` matrix resulting from applying shift-row on ``block``. + OUTPUT: a `2 \times 2` matrix resulting from applying shift-row on ``block`` EXAMPLES: @@ -1547,9 +1536,7 @@ def GF_to_binary(self, G): - ``G`` -- an element of `\GF{2^4}`, a list of elements of `\GF{2^4}`, or a matrix over `\GF{2^4}` - OUTPUT: - - - A binary string representation of ``G``. + OUTPUT: a binary string representation of ``G`` EXAMPLES: @@ -1697,9 +1684,7 @@ def GF_to_integer(self, G): - ``G`` -- an element of `\GF{2^4}`, a list of elements belonging to `\GF{2^4}`, or a matrix over `\GF{2^4}` - OUTPUT: - - - The integer representation of ``G``. + OUTPUT: the integer representation of ``G`` EXAMPLES: @@ -1908,9 +1893,7 @@ def binary_to_integer(self, B): - ``B`` -- a binary string, where the number of bits is positive and a multiple of 4 - OUTPUT: - - - A list of integers that represent the binary string ``B``. + OUTPUT: list of integers that represent the binary string ``B`` EXAMPLES: @@ -1979,12 +1962,10 @@ def integer_to_binary(self, N): INPUT: - - ``N`` -- a non-negative integer less than or equal to 15, or a list + - ``N`` -- nonnegative integer less than or equal to 15, or a list of such integers - OUTPUT: - - - A binary string representing ``N``. + OUTPUT: a binary string representing ``N`` EXAMPLES: @@ -2090,12 +2071,10 @@ def integer_to_GF(self, N): INPUT: - - ``N`` -- a non-negative integer less than or equal to 15, or a list + - ``N`` -- nonnegative integer less than or equal to 15, or a list of such integers - OUTPUT: - - - Elements of the finite field `\GF{2^4}`. + OUTPUT: elements of the finite field `\GF{2^4}` EXAMPLES: @@ -2111,7 +2090,7 @@ def integer_to_GF(self, N): sage: maes.integer_to_GF(7) x^2 + x + 1 - Obtain the finite field elements corresponding to all non-negative + Obtain the finite field elements corresponding to all nonnegative integers less than or equal to 15:: sage: from sage.crypto.block_cipher.miniaes import MiniAES diff --git a/src/sage/crypto/block_cipher/present.py b/src/sage/crypto/block_cipher/present.py index d6f6146af3a..7b1a4a8a3d5 100644 --- a/src/sage/crypto/block_cipher/present.py +++ b/src/sage/crypto/block_cipher/present.py @@ -179,11 +179,11 @@ def __init__(self, keySchedule=80, rounds=None, doFinalRound=False): INPUT: - - ``keySchedule`` -- (default: ``80``); the key schedule that will be + - ``keySchedule`` -- (default: ``80``) the key schedule that will be used for encryption and decryption. Use ``80`` or ``128`` as a shortcut for the original key schedules from [BKLPPRSV2007]_. - - ``rounds`` -- integer (default: ``None``); the number of rounds. If + - ``rounds`` -- integer (default: ``None``); the number of rounds. If ``None`` the number of rounds of the key schedule is used. - ``doFinalRound`` -- boolean (default: ``False``); flag to @@ -355,7 +355,7 @@ def encrypt(self, plaintext, key): INPUT: - ``plaintext`` -- integer or bit list-like; the plaintext that will be - encrypted. + encrypted - ``key`` -- integer or bit list-like; the key @@ -716,10 +716,10 @@ def __init__(self, keysize=80, rounds=31, master_key=None): INPUT: - - ``keysize`` -- integer (default: ``80``); the size of the keys that + - ``keysize`` -- integer (default: 80); the size of the keys that will be used in bits. It must be either 80 or 128. - - ``rounds`` -- integer (default: ``31``); the number of rounds + - ``rounds`` -- integer (default: 31); the number of rounds ``self`` can create keys for - ``master_key`` -- integer or bit list-like (default: ``None``); the @@ -836,14 +836,14 @@ def __repr__(self): def __getitem__(self, r): r""" - Computes the sub key for round ``r`` derived from initial master key. + Compute the sub key for round ``r`` derived from initial master key. The key schedule object has to have been initialised with the ``master_key`` argument. INPUT: - - ``r`` integer; the round for which the sub key is computed + - ``r`` -- integer; the round for which the sub key is computed EXAMPLES:: @@ -887,9 +887,7 @@ def convert_to_vector(I, L): - ``L`` -- integer; the desired bit length of the ouput - OUTPUT: - - - the ``L``-bit vector representation of ``I`` + OUTPUT: the ``L``-bit vector representation of ``I`` EXAMPLES:: diff --git a/src/sage/crypto/block_cipher/sdes.py b/src/sage/crypto/block_cipher/sdes.py index 30b8cf2516c..9b29d25ac15 100644 --- a/src/sage/crypto/block_cipher/sdes.py +++ b/src/sage/crypto/block_cipher/sdes.py @@ -31,6 +31,7 @@ from sage.monoids.string_monoid import BinaryStrings from sage.structure.sage_object import SageObject + class SimplifiedDES(SageObject): r""" This class implements the Simplified Data Encryption Standard (S-DES) @@ -70,8 +71,8 @@ class SimplifiedDES(SageObject): sage: Mod(len(P), 8) == 0 True sage: K = sdes.list_to_string(sdes.random_key()) - sage: C = sdes(P, K, algorithm="encrypt") - sage: plaintxt = sdes(C, K, algorithm="decrypt") + sage: C = sdes(P, K, algorithm='encrypt') + sage: plaintxt = sdes(C, K, algorithm='decrypt') sage: plaintxt == P True """ @@ -101,7 +102,7 @@ def __init__(self): # the S-box S_1 self._sbox1 = SBox(0, 1, 2, 3, 2, 0, 1, 3, 3, 0, 1, 0, 2, 1, 0, 3) - def __call__(self, B, K, algorithm="encrypt"): + def __call__(self, B, K, algorithm='encrypt'): r""" Apply S-DES encryption or decryption on the binary string ``B`` using the key ``K``. The flag ``algorithm`` controls what action is @@ -110,14 +111,14 @@ def __call__(self, B, K, algorithm="encrypt"): INPUT: - ``B`` -- a binary string, where the number of bits is positive and - a multiple of 8. + a multiple of 8 - ``K`` -- a secret key; this must be a 10-bit binary string - - ``algorithm`` -- (default: ``"encrypt"``) a string; a flag to signify + - ``algorithm`` -- (default: ``'encrypt'``) a string; a flag to signify whether encryption or decryption is to be applied to the binary - string ``B``. The encryption flag is ``"encrypt"`` and the decryption - flag is ``"decrypt"``. + string ``B``. The encryption flag is ``'encrypt'`` and the decryption + flag is ``'decrypt'``. OUTPUT: @@ -135,8 +136,8 @@ def __call__(self, B, K, algorithm="encrypt"): sage: P = bin.encoding("Encrypt this using DES!") sage: K = sdes.random_key() sage: K = sdes.list_to_string(K) - sage: C = sdes(P, K, algorithm="encrypt") - sage: plaintxt = sdes(C, K, algorithm="decrypt") + sage: C = sdes(P, K, algorithm='encrypt') + sage: plaintxt = sdes(C, K, algorithm='decrypt') sage: plaintxt == P True @@ -171,20 +172,20 @@ def __call__(self, B, K, algorithm="encrypt"): ... ValueError: secret key must be a 10-bit binary string - The value for ``algorithm`` must be either ``"encrypt"`` or - ``"decrypt"``:: + The value for ``algorithm`` must be either ``'encrypt'`` or + ``'decrypt'``:: sage: B = bin.encoding("abc") sage: K = sdes.list_to_string(sdes.random_key()) - sage: sdes(B, K, algorithm="e") + sage: sdes(B, K, algorithm='e') Traceback (most recent call last): ... ValueError: algorithm must be either 'encrypt' or 'decrypt' - sage: sdes(B, K, algorithm="d") + sage: sdes(B, K, algorithm='d') Traceback (most recent call last): ... ValueError: algorithm must be either 'encrypt' or 'decrypt' - sage: sdes(B, K, algorithm="abc") + sage: sdes(B, K, algorithm='abc') Traceback (most recent call last): ... ValueError: algorithm must be either 'encrypt' or 'decrypt' @@ -535,9 +536,9 @@ def initial_permutation(self, B, inverse=False): - ``B`` -- list; a block of 8 bits - - ``inverse`` -- (default: ``False``) if ``True`` then use the - inverse permutation `P^{-1}`; if ``False`` then use the initial - permutation `P` + - ``inverse`` -- boolean (default: ``False``); if ``True`` then use the + inverse permutation `P^{-1}`. If ``False`` then use the initial + permutation `P`. OUTPUT: @@ -647,16 +648,14 @@ def left_shift(self, B, n=1): INPUT: - - ``B`` -- a list of 10 bits + - ``B`` -- list of 10 bits - ``n`` -- (default: 1) if ``n=1`` then perform left shift by 1 position; if ``n=2`` then perform left shift by 2 positions. The valid values for ``n`` are 1 and 2, since only up to 2 positions are defined for this circular left shift operation. - OUTPUT: - - The circular left shift of each half of ``B``. + OUTPUT: the circular left shift of each half of ``B`` EXAMPLES: @@ -763,9 +762,7 @@ def list_to_string(self, B): - ``B`` -- a non-empty list of bits - OUTPUT: - - The binary string representation of ``B``. + OUTPUT: the binary string representation of ``B`` EXAMPLES: @@ -823,9 +820,7 @@ def permutation4(self, B): - ``B`` -- a block of 4-bit string - OUTPUT: - - A permutation of ``B``. + OUTPUT: a permutation of ``B`` EXAMPLES: @@ -910,9 +905,7 @@ def permutation8(self, B): - ``B`` -- a block of 10-bit string - OUTPUT: - - Pick out 8 of the 10 bits of ``B`` and permute those 8 bits. + OUTPUT: pick out 8 of the 10 bits of ``B`` and permute those 8 bits EXAMPLES: @@ -1000,9 +993,7 @@ def permutation10(self, B): - ``B`` -- a block of 10-bit string - OUTPUT: - - A permutation of ``B``. + OUTPUT: a permutation of ``B`` EXAMPLES: @@ -1170,13 +1161,11 @@ def permute_substitute(self, B, key): INPUT: - - ``B`` -- a list of 8 bits + - ``B`` -- list of 8 bits - ``key`` -- an 8-bit subkey - OUTPUT: - - The result of applying the function `\Pi_F` to ``B``. + OUTPUT: the result of applying the function `\Pi_F` to ``B`` EXAMPLES: @@ -1314,11 +1303,9 @@ def string_to_list(self, S): INPUT: - - ``S`` -- a string of bits + - ``S`` -- string of bits - OUTPUT: - - A list representation of the string ``S``. + OUTPUT: list representation of the string ``S`` EXAMPLES: @@ -1364,7 +1351,7 @@ def string_to_list(self, S): def subkey(self, K, n=1): r""" - Return the ``n``-th subkey based on the key ``K``. + Return the `n`-th subkey based on the key ``K``. INPUT: @@ -1375,9 +1362,7 @@ def subkey(self, K, n=1): values for ``n`` are 1 and 2, since only two subkeys are defined for each secret key in Schaefer's S-DES. - OUTPUT: - - The ``n``-th subkey based on the secret key ``K``. + OUTPUT: the `n`-th subkey based on the secret key ``K`` EXAMPLES: diff --git a/src/sage/crypto/boolean_function.pyx b/src/sage/crypto/boolean_function.pyx index 8cfd08bfd58..7f8f4b4fba0 100644 --- a/src/sage/crypto/boolean_function.pyx +++ b/src/sage/crypto/boolean_function.pyx @@ -120,7 +120,6 @@ cdef reed_muller(mp_limb_t* f, int ldn): .. MATH:: f(x) = \bigoplus_{support(x)\subset I} a_I .. MATH:: a_i = \bigoplus_{I\subset support(x)} f(x) - EXAMPLES:: sage: # needs sage.rings.polynomial.pbori @@ -366,7 +365,7 @@ cdef class BooleanFunction(SageObject): def __invert__(self): """ - Return the complement Boolean function of `self`. + Return the complement Boolean function of ``self``. EXAMPLES:: @@ -543,11 +542,14 @@ cdef class BooleanFunction(SageObject): """ The truth table of the Boolean function. - INPUT: a string representing the desired format, can be either + INPUT: + + - ``format`` -- string representing the desired format; can be either - - ``'bin'`` (default): we return a tuple of Boolean values - - ``'int'``: we return a tuple of 0 or 1 values - - ``'hex'``: we return a string representing the truth table in hexadecimal + - ``'bin'`` -- (default) we return a tuple of Boolean values + - ``'int'`` -- we return a tuple of 0 or 1 values + - ``'hex'`` -- we return a string representing the truth table in + hexadecimal EXAMPLES:: @@ -637,10 +639,13 @@ cdef class BooleanFunction(SageObject): """ Return the value of the function for the given input. - INPUT: either + INPUT: + + - ``x`` -- either: + + - a list: then all elements are evaluated as booleans - - a list -- then all elements are evaluated as Booleans - - an integer -- then we consider its binary representation + - an integer: then we consider its binary representation EXAMPLES:: @@ -989,9 +994,9 @@ cdef class BooleanFunction(SageObject): INPUT: - - ``d`` -- an integer; - - ``dim`` -- a Boolean (default: ``False``), if ``True``, return also - the dimension of the annihilator vector space. + - ``d`` -- integer + - ``dim`` -- boolean (default: ``False``); if ``True``, return also + the dimension of the annihilator vector space EXAMPLES:: @@ -1272,7 +1277,7 @@ cdef class BooleanFunction(SageObject): def derivative(self, u): r""" - Return the derivative in direction of ``u`` + Return the derivative in direction of ``u``. INPUT: diff --git a/src/sage/crypto/cipher.py b/src/sage/crypto/cipher.py index 14e9df6a504..98a00db47dc 100644 --- a/src/sage/crypto/cipher.py +++ b/src/sage/crypto/cipher.py @@ -16,6 +16,7 @@ from sage.structure.element import Element + class Cipher(Element): """ Cipher class @@ -23,10 +24,6 @@ class Cipher(Element): def __init__(self, parent, key): """ Create a cipher. - - INPUT: Parent and key - - EXAMPLES: None yet """ Element.__init__(self, parent) self._key = key @@ -56,31 +53,25 @@ def domain(self): def codomain(self): return self.parent().cipher_codomain() + class SymmetricKeyCipher(Cipher): """ Symmetric key cipher class """ def __init__(self, parent, key): """ - Create a symmetric cipher - - INPUT: Parent and key - - EXAMPLES: None yet + Create a symmetric cipher. """ Cipher.__init__(self, parent, key) + class PublicKeyCipher(Cipher): """ Public key cipher class """ def __init__(self, parent, key, public=True): """ - Create a public key cipher - - INPUT: Parent and key - - EXAMPLES: None yet + Create a public key cipher. """ Cipher.__init__(self, parent, key) self._public = public diff --git a/src/sage/crypto/classical.py b/src/sage/crypto/classical.py index d6740bf396a..82811ab56a8 100644 --- a/src/sage/crypto/classical.py +++ b/src/sage/crypto/classical.py @@ -258,13 +258,11 @@ def __init__(self, A): INPUT: - - ``A`` -- a string monoid over some alphabet; this is the non-empty + - ``A`` -- string monoid over some alphabet; this is the non-empty alphabet over which the plaintext and ciphertext spaces - are defined. + are defined - OUTPUT: - - - An affine cryptosystem over the alphabet ``A``. + OUTPUT: an affine cryptosystem over the alphabet ``A`` EXAMPLES: @@ -428,11 +426,11 @@ def rank_by_chi_square(self, C, pdict): INPUT: - - ``C`` -- The ciphertext, a non-empty string. The ciphertext + - ``C`` -- the ciphertext, a non-empty string. The ciphertext must be encoded using the upper-case letters of the English alphabet. - - ``pdict`` -- A dictionary of key, possible plaintext + - ``pdict`` -- dictionary of key, possible plaintext pairs. This should be the output of :func:`brute_force` with ``ranking="none"``. @@ -637,11 +635,11 @@ def rank_by_squared_differences(self, C, pdict): INPUT: - - ``C`` -- The ciphertext, a non-empty string. The ciphertext + - ``C`` -- the ciphertext, a non-empty string. The ciphertext must be encoded using the upper-case letters of the English alphabet. - - ``pdict`` -- A dictionary of key, possible plaintext + - ``pdict`` -- dictionary of key, possible plaintext pairs. This should be the output of :func:`brute_force` with ``ranking="none"``. @@ -786,25 +784,25 @@ def rank_by_squared_differences(self, C, pdict): for val, key in Rank] return RankedList - def brute_force(self, C, ranking="none"): + def brute_force(self, C, ranking='none'): r""" Attempt a brute force cryptanalysis of the ciphertext ``C``. INPUT: - - ``C`` -- A ciphertext over one of the supported alphabets of this + - ``C`` -- a ciphertext over one of the supported alphabets of this affine cryptosystem. See the class :class:`AffineCryptosystem` for documentation on the supported alphabets. - - ``ranking`` -- (default ``"none"``) the method to use for + - ``ranking`` -- (default: ``'none'``) the method to use for ranking all possible keys. If ``ranking="none"``, then do not use any ranking function. The following ranking functions are supported: - - ``"chi_square"`` -- the chi-square ranking function - as implemented in the method :func:`rank_by_chi_square`. + - ``'chi_square'`` -- the chi-square ranking function + as implemented in the method :func:`rank_by_chi_square` - - ``"squared_differences"`` -- the squared differences ranking + - ``'squared_differences'`` -- the squared differences ranking function as implemented in the method :func:`rank_by_squared_differences`. @@ -863,7 +861,7 @@ def brute_force(self, C, ranking="none"): sage: P = A.encoding("Linear functions for encrypting and decrypting."); P LINEARFUNCTIONSFORENCRYPTINGANDDECRYPTING sage: C = A.enciphering(a, b, P) - sage: Rank = A.brute_force(C, ranking="chisquare") + sage: Rank = A.brute_force(C, ranking='chisquare') sage: Rank[:10] # display only the top 10 candidate keys [((3, 7), LINEARFUNCTIONSFORENCRYPTINGANDDECRYPTING), @@ -880,7 +878,7 @@ def brute_force(self, C, ranking="none"): Use the squared differences ranking function, i.e. ``ranking="squared_differences"``:: - sage: Rank = A.brute_force(C, ranking="squared_differences") + sage: Rank = A.brute_force(C, ranking='squared_differences') sage: Rank[:10] # display only the top 10 candidate keys [((3, 7), LINEARFUNCTIONSFORENCRYPTINGANDDECRYPTING), @@ -931,14 +929,14 @@ def brute_force(self, C, ranking="none"): Only the chi-square and squared-differences ranking functions are currently supported. The keyword ``ranking`` must take on either - of the values ``"none"``, ``"chisquare"`` or - ``"squared_differences"``:: + of the values ``'none'``, ``'chisquare'`` or + ``'squared_differences'``:: sage: A = AffineCryptosystem(AlphabeticStrings()) sage: a, b = (3, 7) sage: P = A.encoding("Linear") sage: C = A.enciphering(a, b, P) - sage: A.brute_force(C, ranking="chi") + sage: A.brute_force(C, ranking='chi') Traceback (most recent call last): ... ValueError: Keyword 'ranking' must be either 'none', 'chisquare', or 'squared_differences'. @@ -987,14 +985,12 @@ def deciphering(self, a, b, C): `\ZZ/n\ZZ \times \ZZ/n\ZZ` such that `\gcd(a,n) = 1` with `n` being the size of the ciphertext and plaintext spaces. - - ``C`` -- a string of ciphertext; possibly an empty string. + - ``C`` -- string of ciphertext; possibly an empty string. Characters in this string must be encoded using one of the supported alphabets. See the method :func:`encoding()` for more information. - OUTPUT: - - - The plaintext corresponding to the ciphertext ``C``. + OUTPUT: the plaintext corresponding to the ciphertext ``C`` EXAMPLES: @@ -1061,14 +1057,12 @@ def enciphering(self, a, b, P): `\ZZ/n\ZZ \times \ZZ/n\ZZ` such that `\gcd(a,n) = 1` with `n` being the size of the ciphertext and plaintext spaces. - - ``P`` -- a string of plaintext; possibly an empty string. + - ``P`` -- string of plaintext; possibly an empty string. Characters in this string must be encoded using one of the supported alphabets. See the method :func:`encoding()` for more information. - OUTPUT: - - - The ciphertext corresponding to the plaintext ``P``. + OUTPUT: the ciphertext corresponding to the plaintext ``P`` EXAMPLES: @@ -1129,12 +1123,10 @@ def encoding(self, S): INPUT: - - ``S`` -- a string, possibly empty. + - ``S`` -- string, possibly empty - OUTPUT: - - - The encoding of ``S`` over the string monoid of this cryptosystem. - If ``S`` is an empty string, return an empty string. + OUTPUT: the encoding of ``S`` over the string monoid of this + cryptosystem; if ``S`` is an empty string, return an empty string EXAMPLES: @@ -1295,14 +1287,12 @@ class HillCryptosystem(SymmetricKeyCryptosystem): INPUT: - - ``S`` -- a string monoid over some alphabet + - ``S`` -- string monoid over some alphabet - ``m`` -- integer `> 0`; the block length of matrices that specify block permutations - OUTPUT: - - - A Hill cryptosystem of block length ``m`` over the alphabet ``S``. + OUTPUT: a Hill cryptosystem of block length ``m`` over the alphabet ``S`` EXAMPLES:: @@ -1339,14 +1329,12 @@ def __init__(self, S, m): INPUT: - - ``S`` -- a string monoid over some alphabet + - ``S`` -- string monoid over some alphabet - ``m`` -- integer `> 0`; the block length of matrices that specify block permutations - OUTPUT: - - - A Hill cryptosystem of block length ``m`` over the alphabet ``S``. + OUTPUT: a Hill cryptosystem of block length ``m`` over the alphabet ``S`` EXAMPLES:: @@ -1399,7 +1387,7 @@ def __call__(self, A): def _repr_(self): """ - Return a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -1420,9 +1408,7 @@ def block_length(self): or decryption key are the same. This row/column dimension is referred to as the *block length*. - OUTPUT: - - - The block length of an encryption/decryption key. + OUTPUT: the block length of an encryption/decryption key EXAMPLES:: @@ -1444,9 +1430,7 @@ def random_key(self): i.e. invertible `m \times m` square matrices, is smaller than `n^{m^2}`. - OUTPUT: - - - A random key within the key space of this Hill cipher. + OUTPUT: a random key within the key space of this Hill cipher EXAMPLES:: @@ -1479,9 +1463,7 @@ def inverse_key(self, A): - ``A`` -- an invertible matrix of the key space of this Hill cipher - OUTPUT: - - - The inverse matrix of ``A``. + OUTPUT: the inverse matrix of ``A`` EXAMPLES:: @@ -1519,11 +1501,10 @@ def encoding(self, M): INPUT: - - ``M`` -- a string, possibly empty + - ``M`` -- string, possibly empty - OUTPUT: - - - The encoding of ``M`` over the string monoid of this Hill cipher. + OUTPUT: the encoding of ``M`` over the string monoid of this Hill + cipher EXAMPLES:: @@ -1549,12 +1530,10 @@ def deciphering(self, A, C): - ``A`` -- a key within the key space of this Hill cipher - - ``C`` -- a string (possibly empty) over the string monoid of this + - ``C`` -- string (possibly empty) over the string monoid of this Hill cipher - OUTPUT: - - - The plaintext corresponding to the ciphertext ``C``. + OUTPUT: the plaintext corresponding to the ciphertext ``C`` EXAMPLES:: @@ -1577,12 +1556,10 @@ def enciphering(self, A, M): - ``A`` -- a key within the key space of this Hill cipher - - ``M`` -- a string (possibly empty) over the string monoid of this - Hill cipher. - - OUTPUT: + - ``M`` -- string (possibly empty) over the string monoid of this + Hill cipher - - The ciphertext corresponding to the plaintext ``M``. + OUTPUT: the ciphertext corresponding to the plaintext ``M`` EXAMPLES:: @@ -1814,13 +1791,11 @@ def __init__(self, A): INPUT: - - ``A`` -- a string monoid over some alphabet; this is the non-empty + - ``A`` -- string monoid over some alphabet; this is the non-empty alphabet over which the plaintext and ciphertext spaces - are defined. - - OUTPUT: + are defined - - A shift cryptosystem over the alphabet ``A``. + OUTPUT: a shift cryptosystem over the alphabet ``A`` EXAMPLES:: @@ -1867,9 +1842,7 @@ def __call__(self, K): `0 \leq k < n` where `n` is the size or cardinality of the set `A`. - OUTPUT: - - - A shift cipher with secret key ``K``. + OUTPUT: a shift cipher with secret key ``K`` EXAMPLES:: @@ -2018,11 +1991,11 @@ def rank_by_chi_square(self, C, pdict): INPUT: - - ``C`` -- The ciphertext, a non-empty string. The ciphertext + - ``C`` -- the ciphertext, a non-empty string. The ciphertext must be encoded using the upper-case letters of the English alphabet. - - ``pdict`` -- A dictionary of key, possible plaintext pairs. + - ``pdict`` -- dictionary of key, possible plaintext pairs. This should be the output of :func:`brute_force` with ``ranking="none"``. @@ -2255,18 +2228,16 @@ def rank_by_squared_differences(self, C, pdict): INPUT: - - ``C`` -- The ciphertext, a non-empty string. The ciphertext + - ``C`` -- the ciphertext, a non-empty string. The ciphertext must be encoded using the upper-case letters of the English alphabet. - - ``pdict`` -- A dictionary of key, possible plaintext pairs. + - ``pdict`` -- dictionary of key, possible plaintext pairs. This should be the output of :func:`brute_force` with ``ranking="none"``. - OUTPUT: - - - A list ranking the most likely keys first. Each element of the - list is a tuple of key, possible plaintext pairs. + OUTPUT: a list ranking the most likely keys first; each element of the + list is a tuple of key, possible plaintext pairs EXAMPLES: @@ -2432,25 +2403,25 @@ def rank_by_squared_differences(self, C, pdict): [RankedList.append((key, pdict[key])) for val, key in Rank] return RankedList - def brute_force(self, C, ranking="none"): + def brute_force(self, C, ranking='none'): r""" Attempt a brute force cryptanalysis of the ciphertext ``C``. INPUT: - - ``C`` -- A ciphertext over one of the supported alphabets of this + - ``C`` -- a ciphertext over one of the supported alphabets of this shift cryptosystem. See the class :class:`ShiftCryptosystem` for documentation on the supported alphabets. - - ``ranking`` -- (default ``"none"``) the method to use for + - ``ranking`` -- (default: ``'none'``) the method to use for ranking all possible keys. If ``ranking="none"``, then do not use any ranking function. The following ranking functions are supported: - - ``"chisquare"`` -- the chi-square ranking function as - implemented in the method :func:`rank_by_chi_square`. + - ``'chisquare'`` -- the chi-square ranking function as + implemented in the method :func:`rank_by_chi_square` - - ``"squared_differences"`` -- the squared differences ranking + - ``'squared_differences'`` -- the squared differences ranking function as implemented in the method :func:`rank_by_squared_differences`. @@ -2539,7 +2510,7 @@ def brute_force(self, C, ranking="none"): Use the chi-square ranking function, i.e. ``ranking="chisquare"``:: - sage: S.brute_force(C, ranking="chisquare") + sage: S.brute_force(C, ranking='chisquare') [(8, SHIFTINGUSINGMODULARARITHMETIC), (14, MBCZNCHAOMCHAGIXOFULULCNBGYNCW), @@ -2571,7 +2542,7 @@ def brute_force(self, C, ranking="none"): Use the squared differences ranking function, i.e. ``ranking="squared_differences"``:: - sage: S.brute_force(C, ranking="squared_differences") + sage: S.brute_force(C, ranking='squared_differences') [(8, SHIFTINGUSINGMODULARARITHMETIC), (23, DSTQETYRFDTYRXZOFWLCLCTESXPETN), @@ -2669,14 +2640,12 @@ def deciphering(self, K, C): shift cipher. This key is an integer `k` satisfying the inequality `0 \leq k < n`, where `n` is the size of the cipher domain. - - ``C`` -- a string of ciphertext; possibly an empty string. + - ``C`` -- string of ciphertext; possibly an empty string Characters in this string must be encoded using one of the supported alphabets. See the method :func:`encoding()` for more information. - OUTPUT: - - - The plaintext corresponding to the ciphertext ``C``. + OUTPUT: the plaintext corresponding to the ciphertext ``C`` EXAMPLES: @@ -2728,14 +2697,12 @@ def enciphering(self, K, P): This key is an integer `k` satisfying the inequality `0 \leq k < n`, where `n` is the size of the cipher domain. - - ``P`` -- a string of plaintext; possibly an empty string. + - ``P`` -- string of plaintext; possibly an empty string. Characters in this string must be encoded using one of the supported alphabets. See the method :func:`encoding()` for more information. - OUTPUT: - - - The ciphertext corresponding to the plaintext ``P``. + OUTPUT: the ciphertext corresponding to the plaintext ``P`` EXAMPLES: @@ -2792,12 +2759,10 @@ def encoding(self, S): INPUT: - - ``S`` -- a string, possibly empty. + - ``S`` -- string, possibly empty - OUTPUT: - - - The encoding of ``S`` over the string monoid of this cryptosystem. - If ``S`` is an empty string, return an empty string. + OUTPUT: the encoding of ``S`` over the string monoid of this + cryptosystem; if ``S`` is an empty string, return an empty string EXAMPLES: @@ -2849,11 +2814,9 @@ def inverse_key(self, K): INPUT: - ``K`` -- a key for this shift cipher. This must be an integer `k` - such that `0 \leq k < n`, where `n` is the size of the cipher domain. + such that `0 \leq k < n`, where `n` is the size of the cipher domain - OUTPUT: - - - The inverse key corresponding to ``K``. + OUTPUT: the inverse key corresponding to ``K`` EXAMPLES: @@ -2881,7 +2844,7 @@ def inverse_key(self, K): Regardless of the value of a key, the addition of the key and its inverse must be equal to the alphabet size. This relationship holds - exactly when the value of the key is non-zero:: + exactly when the value of the key is nonzero:: sage: S = ShiftCryptosystem(AlphabeticStrings()) sage: K = S.random_key() @@ -2964,9 +2927,7 @@ def random_key(self): key space, which is the set `\ZZ / n\ZZ`. The key `k = 0` has no effect on either the plaintext or the ciphertext. - OUTPUT: - - - A random key within the key space of this shift cryptosystem. + OUTPUT: a random key within the key space of this shift cryptosystem EXAMPLES:: @@ -2982,7 +2943,7 @@ def random_key(self): Regardless of the value of a key, the addition of the key and its inverse must be equal to the alphabet size. This relationship holds - exactly when the value of the key is non-zero:: + exactly when the value of the key is nonzero:: sage: S = ShiftCryptosystem(AlphabeticStrings()) sage: K = S.random_key() @@ -3008,17 +2969,16 @@ def random_key(self): from sage.misc.prandom import randint return Integer(randint(0, self.alphabet_size() - 1)) + class SubstitutionCryptosystem(SymmetricKeyCryptosystem): """ Create a substitution cryptosystem. INPUT: - - ``S`` -- a string monoid over some alphabet - - OUTPUT: + - ``S`` -- string monoid over some alphabet - - A substitution cryptosystem over the alphabet ``S``. + OUTPUT: a substitution cryptosystem over the alphabet ``S`` EXAMPLES:: @@ -3087,7 +3047,7 @@ def __call__(self, K): def _repr_(self): """ - Return a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -3107,9 +3067,7 @@ def random_key(self): alphabet. Let `n` be the length of the alphabet. Then there are `n!` possible keys in the key space. - OUTPUT: - - - A random key within the key space of this cryptosystem. + OUTPUT: a random key within the key space of this cryptosystem EXAMPLES:: @@ -3138,9 +3096,7 @@ def inverse_key(self, K): - ``K`` -- a key belonging to the key space of this cryptosystem - OUTPUT: - - - The inverse key of ``K``. + OUTPUT: the inverse key of ``K`` EXAMPLES:: @@ -3169,11 +3125,10 @@ def encoding(self, M): INPUT: - - ``M`` -- a string, possibly empty + - ``M`` -- string, possibly empty - OUTPUT: - - - The encoding of ``M`` over the string monoid of this cryptosystem. + OUTPUT: the encoding of ``M`` over the string monoid of this + cryptosystem EXAMPLES:: @@ -3199,12 +3154,10 @@ def deciphering(self, K, C): - ``K`` -- a key belonging to the key space of this substitution cipher - - ``C`` -- a string (possibly empty) over the string monoid of this - cryptosystem. - - OUTPUT: + - ``C`` -- string (possibly empty) over the string monoid of this + cryptosystem - - The plaintext corresponding to the ciphertext ``C``. + OUTPUT: the plaintext corresponding to the ciphertext ``C`` EXAMPLES:: @@ -3225,12 +3178,10 @@ def enciphering(self, K, M): - ``K`` -- a key belonging to the key space of this substitution cipher - - ``M`` -- a string (possibly empty) over the string monoid of this - cryptosystem. - - OUTPUT: + - ``M`` -- string (possibly empty) over the string monoid of this + cryptosystem - - The ciphertext corresponding to the plaintext ``M``. + OUTPUT: the ciphertext corresponding to the plaintext ``M`` EXAMPLES:: @@ -3243,13 +3194,14 @@ def enciphering(self, K, M): e = self(K) return e(M) + class TranspositionCryptosystem(SymmetricKeyCryptosystem): """ Create a transposition cryptosystem of block length ``n``. INPUT: - - ``S`` -- a string monoid over some alphabet + - ``S`` -- string monoid over some alphabet - ``n`` -- integer `> 0`; a block length of a block permutation @@ -3325,7 +3277,7 @@ def __call__(self, K): def _repr_(self): """ - Return a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -3344,9 +3296,7 @@ def random_key(self): cryptosystem. Let `n > 0` be the block length of this cryptosystem. Then there are `n!` possible keys. - OUTPUT: - - - A random key within the key space of this cryptosystem. + OUTPUT: a random key within the key space of this cryptosystem EXAMPLES:: @@ -3374,12 +3324,10 @@ def inverse_key(self, K, check=True): - ``K`` -- a key belonging to the key space of this transposition cipher - - ``check`` -- bool (default: ``True``); check that ``K`` belongs to - the key space of this cryptosystem. - - OUTPUT: + - ``check`` -- boolean (default: ``True``); check that ``K`` belongs to + the key space of this cryptosystem - - The inverse key corresponding to ``K``. + OUTPUT: the inverse key corresponding to ``K`` EXAMPLES:: @@ -3410,11 +3358,10 @@ def encoding(self, M): INPUT: - - ``M`` -- a string, possibly empty + - ``M`` -- string, possibly empty - OUTPUT: - - - The encoding of ``M`` over the string monoid of this cryptosystem. + OUTPUT: the encoding of ``M`` over the string monoid of this + cryptosystem EXAMPLES:: @@ -3441,12 +3388,10 @@ def deciphering(self, K, C): - ``K`` -- a key belonging to the key space of this transposition cipher - - ``C`` -- a string (possibly empty) over the string monoid of this - cryptosystem. - - OUTPUT: + - ``C`` -- string (possibly empty) over the string monoid of this + cryptosystem - - The plaintext corresponding to the ciphertext ``C``. + OUTPUT: the plaintext corresponding to the ciphertext ``C`` EXAMPLES:: @@ -3469,12 +3414,10 @@ def enciphering(self, K, M): - ``K`` -- a key belonging to the key space of this transposition cipher - - ``M`` -- a string (possibly empty) over the string monoid of this + - ``M`` -- string (possibly empty) over the string monoid of this cryptosystem - OUTPUT: - - - The ciphertext corresponding to the plaintext ``M``. + OUTPUT: the ciphertext corresponding to the plaintext ``M`` EXAMPLES:: @@ -3495,7 +3438,7 @@ class VigenereCryptosystem(SymmetricKeyCryptosystem): INPUT: - - ``S`` -- a string monoid over some alphabet + - ``S`` -- string monoid over some alphabet - ``n`` -- integer `> 0`; block length of an encryption/decryption key @@ -3546,7 +3489,9 @@ def __call__(self, K): """ Create a Vigenere cipher. - INPUT: A key which specifies a block permutation. + INPUT: + + - ``K`` -- a key which specifies a block permutation EXAMPLES:: @@ -3576,7 +3521,7 @@ def __call__(self, K): def _repr_(self): """ - Return a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -3597,9 +3542,7 @@ def random_key(self): and let `m > 0` be the block length of this cryptosystem. Then there are `n^m` possible keys. - OUTPUT: - - - A random key within the key space of this cryptosystem. + OUTPUT: a random key within the key space of this cryptosystem EXAMPLES:: @@ -3626,9 +3569,7 @@ def inverse_key(self, K): - ``K`` -- a key within the key space of this Vigenere cryptosystem - OUTPUT: - - - The inverse key corresponding to ``K``. + OUTPUT: the inverse key corresponding to ``K`` EXAMPLES:: @@ -3656,11 +3597,10 @@ def encoding(self, M): INPUT: - - ``M`` -- a string, possibly empty - - OUTPUT: + - ``M`` -- string, possibly empty - - The encoding of ``M`` over the string monoid of this cryptosystem. + OUTPUT: the encoding of ``M`` over the string monoid of this + cryptosystem EXAMPLES:: @@ -3686,12 +3626,10 @@ def deciphering(self, K, C): - ``K`` -- a key belonging to the key space of this Vigenere cipher - - ``C`` -- a string (possibly empty) over the string monoid of this + - ``C`` -- string (possibly empty) over the string monoid of this cryptosystem - OUTPUT: - - - The plaintext corresponding to the ciphertext ``C``. + OUTPUT: the plaintext corresponding to the ciphertext ``C`` EXAMPLES:: @@ -3712,12 +3650,10 @@ def enciphering(self, K, M): - ``K`` -- a key belonging to the key space of this Vigenere cipher - - ``M`` -- a string (possibly empty) over the string monoid of this + - ``M`` -- string (possibly empty) over the string monoid of this cryptosystem - OUTPUT: - - - The ciphertext corresponding to the plaintext ``M``. + OUTPUT: the ciphertext corresponding to the plaintext ``M`` EXAMPLES:: diff --git a/src/sage/crypto/classical_cipher.py b/src/sage/crypto/classical_cipher.py index b775c426058..cb2a03ede29 100644 --- a/src/sage/crypto/classical_cipher.py +++ b/src/sage/crypto/classical_cipher.py @@ -33,9 +33,9 @@ def __init__(self, parent, key): INPUT: - - ``parent`` -- an ``AffineCryptosystem`` object. + - ``parent`` -- an ``AffineCryptosystem`` object - - ``key`` -- a secret key. Let `N` be the size of the cipher domain. + - ``key`` -- a secret key; let `N` be the size of the cipher domain. A key of this affine cipher is an ordered pair `(a, b) \in \ZZ_N \times \ZZ_N` such that `\gcd(a, N) = 1`. @@ -58,12 +58,10 @@ def __eq__(self, other): INPUT: - - ``other`` -- another object to compare with. + - ``other`` -- another object to compare with - OUTPUT: - - - ``True`` if ``self`` and ``other`` are the same ``AffineCipher`` - object; ``False`` otherwise. + OUTPUT: ``True`` if ``self`` and ``other`` are the same + ``AffineCipher`` object; ``False`` otherwise EXAMPLES:: @@ -89,15 +87,13 @@ def __call__(self, M): behaviour is that the plaintext and ciphertext alphabets are the same alphabet. - - ``algorithm`` -- (default ``"encrypt"``) whether to use the - encryption or decryption algorithm on ``M``. The flag ``"encrypt"`` - signifies using the encryption algorithm, while ``"decrypt"`` + - ``algorithm`` -- (default: ``'encrypt'``) whether to use the + encryption or decryption algorithm on ``M``. The flag ``'encrypt'`` + signifies using the encryption algorithm, while ``'decrypt'`` signifies using the decryption algorithm. The only acceptable - values for ``algorithm`` are: ``"encrypt"`` and ``"decrypt"``. - - OUTPUT: + values for ``algorithm`` are: ``'encrypt'`` and ``'decrypt'``. - - The ciphertext or plaintext corresponding to ``M``. + OUTPUT: the ciphertext or plaintext corresponding to ``M`` EXAMPLES:: @@ -165,8 +161,6 @@ def __init__(self, parent, key): """ Create a Hill cipher. - INPUT: Parent and key - EXAMPLES:: sage: # needs sage.modules @@ -238,6 +232,7 @@ def inverse(self): raise ValueError("Argument\n\n%s\n\nmust be an invertible cipher." % self) return E(B) + class ShiftCipher(SymmetricKeyCipher): r""" Shift cipher class. This is the class that does the actual work of @@ -254,9 +249,9 @@ def __init__(self, parent, key): INPUT: - - ``parent`` -- a ``ShiftCryptosystem`` object. + - ``parent`` -- a ``ShiftCryptosystem`` object - - ``key`` -- a secret key. + - ``key`` -- a secret key EXAMPLES:: @@ -283,12 +278,10 @@ def __eq__(self, other): INPUT: - - ``other`` -- another object to compare with. - - OUTPUT: + - ``other`` -- another object to compare with - - ``True`` if ``self`` and ``other`` are the same ``ShiftCipher`` - object; ``False`` otherwise. + OUTPUT: ``True`` if ``self`` and ``other`` are the same ``ShiftCipher`` + object; ``False`` otherwise. EXAMPLES:: @@ -316,9 +309,7 @@ def __call__(self, M): behaviour is that the plaintext and ciphertext alphabets are the same alphabet. - OUTPUT: - - - The ciphertext or plaintext corresponding to ``M``. + OUTPUT: the ciphertext or plaintext corresponding to ``M`` EXAMPLES: @@ -384,6 +375,7 @@ def _repr_(self): # as the alphabet used for the plaintext and ciphertext spaces. return "Shift cipher on %s" % self.parent().cipher_domain() + class SubstitutionCipher(SymmetricKeyCipher): """ Substitution cipher class @@ -392,8 +384,6 @@ def __init__(self, parent, key): """ Create a substitution cipher. - INPUT: Parent and key - EXAMPLES:: sage: S = AlphabeticStrings() @@ -459,6 +449,7 @@ def inverse(self): K = E.inverse_key(self.key()) return E(K) + class TranspositionCipher(SymmetricKeyCipher): """ Transition cipher class @@ -467,8 +458,6 @@ def __init__(self, parent, key): """ Create a transposition cipher. - INPUT: Parent and key - EXAMPLES:: sage: # needs sage.groups @@ -508,7 +497,7 @@ def __init__(self, parent, key): raise ValueError("key (= %s) must have block length %s" % (key, n)) SymmetricKeyCipher.__init__(self, parent, key) - def __call__(self, M, mode="ECB"): + def __call__(self, M, mode='ECB'): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) @@ -531,6 +520,7 @@ def inverse(self): K = E.inverse_key(self.key()) return E(K) + class VigenereCipher(SymmetricKeyCipher): """ Vigenere cipher class @@ -539,8 +529,6 @@ def __init__(self, parent, key): """ Create a Vigenere cipher. - INPUT: Parent and key - EXAMPLES:: sage: S = AlphabeticStrings() @@ -560,7 +548,7 @@ def __init__(self, parent, key): """ SymmetricKeyCipher.__init__(self, parent, key) - def __call__(self, M, mode="ECB"): + def __call__(self, M, mode='ECB'): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) diff --git a/src/sage/crypto/cryptosystem.py b/src/sage/crypto/cryptosystem.py index 488b9a014b5..82fb0e553ad 100644 --- a/src/sage/crypto/cryptosystem.py +++ b/src/sage/crypto/cryptosystem.py @@ -78,15 +78,15 @@ class Cryptosystem(Set_generic): INPUT: - - ``plaintext_space`` -- the plaintext alphabet. + - ``plaintext_space`` -- the plaintext alphabet - - ``ciphertext_space`` -- the ciphertext alphabet. + - ``ciphertext_space`` -- the ciphertext alphabet - - ``key_space`` -- the key alphabet. + - ``key_space`` -- the key alphabet - - ``block_length`` -- (default: 1) the block length. + - ``block_length`` -- (default: 1) the block length - - ``period`` -- (default: ``None``) the period. + - ``period`` -- (default: ``None``) the period EXAMPLES: @@ -111,15 +111,15 @@ def __init__(self, plaintext_space, ciphertext_space, key_space, INPUT: - - ``plaintext_space`` -- the plaintext alphabet. + - ``plaintext_space`` -- the plaintext alphabet - - ``ciphertext_space`` -- the ciphertext alphabet. + - ``ciphertext_space`` -- the ciphertext alphabet - - ``key_space`` -- the key alphabet. + - ``key_space`` -- the key alphabet - - ``block_length`` -- (default: 1) the block length. + - ``block_length`` -- (default: 1) the block length - - ``period`` -- (default: ``None``) the period. + - ``period`` -- (default: ``None``) the period EXAMPLES: @@ -158,7 +158,7 @@ def __eq__(self, right): INPUT: - - ``right`` -- a ``Cryptosystem`` object. + - ``right`` -- a ``Cryptosystem`` object EXAMPLES: diff --git a/src/sage/crypto/key_exchange/all.py b/src/sage/crypto/key_exchange/all.py new file mode 100644 index 00000000000..820638a048f --- /dev/null +++ b/src/sage/crypto/key_exchange/all.py @@ -0,0 +1,6 @@ +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.crypto.key_exchange.diffie_hellman', 'DiffieHellman') +lazy_import('sage.crypto.key_exchange.key_exchange_scheme', 'KeyExchangeScheme') + +del lazy_import diff --git a/src/sage/crypto/key_exchange/catalog.py b/src/sage/crypto/key_exchange/catalog.py new file mode 100644 index 00000000000..aa105371015 --- /dev/null +++ b/src/sage/crypto/key_exchange/catalog.py @@ -0,0 +1,23 @@ +""" +Index of key exchange schemes + +This catalogue includes implementations of key exchange schemes. + +Let ```` indicate pressing the :kbd:`Tab` key. So begin by typing +``key_exchange.`` to the see the currently implemented key exchange +schemes. + +This catalogue includes the following key exchange schemes: + +- :class:`sage.crypto.key_exchange.diffie_hellman.DiffieHellman` + +To import these names into the global namespace, use:: + + sage: from sage.crypto.key_exchange.catalog import * +""" + +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.crypto.key_exchange.diffie_hellman', 'DiffieHellman') + +del lazy_import diff --git a/src/sage/crypto/key_exchange/diffie_hellman.py b/src/sage/crypto/key_exchange/diffie_hellman.py new file mode 100644 index 00000000000..47b6bd392a8 --- /dev/null +++ b/src/sage/crypto/key_exchange/diffie_hellman.py @@ -0,0 +1,326 @@ +r""" +Diffie-Hellman Key Exchange Scheme + +This module contains a toy implementation of the Diffie-Hellman key exchange +scheme. + +AUTHORS: + +- Vincent Macri (2024-07-30): initial version +""" +# **************************************************************************** +# Copyright (C) 2024 Vincent Macri +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.misc.superseded import experimental + +from sage.crypto.key_exchange.key_exchange_scheme import KeyExchangeScheme + +from sage.arith.misc import is_prime +from sage.misc.prandom import randint +from sage.rings.integer import Integer +from sage.rings.finite_rings.finite_field_constructor import GF +from sage.rings.finite_rings.finite_field_prime_modn import \ + FiniteField_prime_modn +from sage.rings.finite_rings.integer_mod import IntegerMod_abstract +from sage.structure.proof.proof import WithProof + +from typing import Union + + +class DiffieHellman(KeyExchangeScheme): + + @experimental(37305) + def __init__(self, p: Integer, g: Union[Integer, IntegerMod_abstract], + proof: bool = True) -> None: + r""" + Create an instance of the Diffie-Hellman key exchange scheme using the + given prime ``p`` and base ``g``. + + INPUT: + + - ``p`` -- prime integer defining the field `\GF{p}` that the key + exchanges will be performed over, must be at least 5 + + - ``g`` -- base for the key exchange, (coerceable to) an element of + `\GF{p}` from `2` to `p - 2` + + - ``proof`` -- (default: ``True``) whether to require a proof that + ``p`` is prime. If ``False``, a probabilistic test can be used for + checking that ``p`` is prime. This should be set to ``False`` + when using large (cryptographic size) primes, otherwise checking + primality will take too long. + + .. WARNING:: + + This is a toy implementation for educational use only! Do not use + this implementation, or any cryptographic features of Sage, in any + setting where security is needed! + + REFERENCES: + + For more information, see Section 8.1 of [PP2010]_. + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(13, 2) + doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. + See https://github.com/sagemath/sage/issues/37305 for details. + + This is an example of a full key exchange using a cryptographically + large prime. This is the prime from the 8192-bit MODP group in RFC 3526 + (see [KK2003]_):: + + sage: p = 2^8192 - 2^8128 - 1 + 2^64 * (round(2^8062 * pi) + 4743158) + sage: DH = key_exchange.DiffieHellman(p, 2, proof=False) + sage: alice_sk = DH.generate_secret_key() + sage: alice_pk = DH.generate_public_key(alice_sk) + sage: bob_sk = DH.generate_secret_key() + sage: bob_pk = DH.generate_public_key(bob_sk) + sage: alice_shared_secret = DH.compute_shared_secret(bob_pk, alice_sk) + sage: bob_shared_secret = DH.compute_shared_secret(alice_pk, bob_sk) + sage: alice_shared_secret == bob_shared_secret + True + + TESTS:: + + sage: DH = key_exchange.DiffieHellman(3, 2) + Traceback (most recent call last): + ... + ValueError: p must be at least 5 + + sage: DH = key_exchange.DiffieHellman(5, 0) + Traceback (most recent call last): + ... + ValueError: g cannot be 0, 1, or p - 1 (mod p) + + sage: DH = key_exchange.DiffieHellman(5, 1) + Traceback (most recent call last): + ... + ValueError: g cannot be 0, 1, or p - 1 (mod p) + + sage: DH = key_exchange.DiffieHellman(5, 4) + Traceback (most recent call last): + ... + ValueError: g cannot be 0, 1, or p - 1 (mod p) + """ + + if p < 5: + raise ValueError('p must be at least 5') + + if proof: + # The modn implementation checks that ``p`` is prime + self._field = GF(p, impl='modn') + else: + with WithProof('arithmetic', False): + self._field = GF(p, impl='modn') + + self._p = p + self._g = self._field(g) + + # While these values won't cause mathematical problems, they do + # completely break the security of the Diffie-Hellman scheme. + # g = 0 makes every secret key and shared secret 0 + # g = 1 makes every secret key and shared secret 1 + # g = -1 makes every secret key and shared secret 1 or -1 + if self._g == 0 or self._g == 1 or self._g == p - 1: + raise ValueError('g cannot be 0, 1, or p - 1 (mod p)') + + def field(self) -> FiniteField_prime_modn: + """ + Return the field this ``DiffieHellman`` instance is working over. + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(5, 2) + sage: DH.field() + Finite Field of size 5 + """ + return self._field + + def prime(self) -> Integer: + """ + Return the prime ``p`` for this ``DiffieHellman`` instance. + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(7, 3) + sage: DH.prime() + 7 + """ + return self._p + + def generator(self) -> IntegerMod_abstract: + """ + Return the generator ``g`` for this ``DiffieHellman`` instance. + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(7, 3) + sage: DH.generator() + 3 + """ + return self._g + + def parameters(self) -> tuple[Integer, IntegerMod_abstract]: + """ + Get the parameters ``(p, g)`` for this ``DiffieHellman`` instance. + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(7, 3) + sage: DH.parameters() + (7, 3) + """ + return (self._p, self._g) + + def generate_secret_key(self) -> Integer: + """ + Generate a random Diffie-Hellman secret key. + + TESTS: + + sage: DH = key_exchange.DiffieHellman(7, 2) + sage: keys = [DH.generate_secret_key() for i in range(10)] + sage: all(2 <= i <= 5 for i in keys) + True + """ + return randint(2, self._p - 2) + + def generate_public_key(self, secret_key: Integer) -> IntegerMod_abstract: + """ + Generate a Diffie-Hellman public key using the given secret key. + + INPUT: + + - ``secret_key`` -- the secret key to generate the public key with + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(13, 2) + sage: DH.generate_public_key(4) + 3 + """ + return self._g**secret_key + + def compute_shared_secret(self, pk: IntegerMod_abstract, + sk: Integer) -> IntegerMod_abstract: + """ + Compute the shared secret using the given public key and secret keys. + + INPUT: + + - ``pk`` -- public key + + - ``sk`` -- secret key + + EXAMPLES:: + + sage: DH = key_exchange.DiffieHellman(17, 3) + sage: DH.compute_shared_secret(13, 11) + 4 + """ + return self._field(pk**sk) + + def subgroup_size(self) -> Integer: + """ + Calculates the size of the subgroup of `\\GF{p}` generated by + ``self.generator()``. + + EXAMPLES: + + This is an example of a ``DiffieHellman`` instance where the subgroup + size is `(p - 1) / 2`:: + + sage: DH = key_exchange.DiffieHellman(47, 2) + sage: DH.subgroup_size() + 23 + + This is an example of a ``DiffieHellman`` instance where the subgroup + size is `p - 1`:: + + sage: DH = key_exchange.DiffieHellman(47, 5) + sage: DH.subgroup_size() + 46 + """ + return self._g.multiplicative_order() + + def __len__(self) -> int: + """ + Calculates the size of the subgroup of `\\GF{p}` generated by + ``self.generator()``. This is a wrapper around `subgroup_size`. + + TESTS:: + + sage: DH = key_exchange.DiffieHellman(53, 9) + sage: len(DH) + 26 + """ + return int(self.subgroup_size()) + + def __eq__(self, other) -> bool: + """ + Check if two ``DiffieHellman`` instances have the same parameter set. + + TESTS:: + + sage: DH1 = key_exchange.DiffieHellman(5, 2) + sage: DH2 = key_exchange.DiffieHellman(5, 2) + sage: DH1 == DH2 + True + sage: DH1 == 5 + False + """ + if isinstance(other, DiffieHellman): + return self.parameters() == other.parameters() + return False + + def __hash__(self) -> int: + """ + Compute the hash value of a ``DiffieHellman`` instance. + + TESTS:: + + sage: DH1 = key_exchange.DiffieHellman(7, 3) + sage: DH2 = key_exchange.DiffieHellman(7, 3) + sage: s = set([DH1, DH2]) + sage: len(s) + 1 + """ + return hash((self._p, self._g)) + + def _repr_(self) -> str: + """ + Get the string representation of the ``DiffieHellman`` instance. + + TESTS:: + + sage: DH = key_exchange.DiffieHellman(7, 3) + sage: DH + Diffie-Hellman key exchange over Finite Field of size 7 with generator 3 + """ + return ('Diffie-Hellman key exchange over ' + f'{self._field} ' + 'with generator ' + f'{self._g}') + + def _latex_(self) -> str: + r""" + Get the LaTeX representation of the ``DiffieHellman`` instance. + + TESTS:: + + sage: DH = key_exchange.DiffieHellman(7, 3) + sage: latex(DH) + \text{Diffie-Hellman key exchange over }\Bold{F}_{7}\text{ with generator }3 + """ + return ('\\text{Diffie-Hellman key exchange over }' + f'{self._field._latex_()}' + '\\text{ with generator }' + f'{self._g}') diff --git a/src/sage/crypto/key_exchange/key_exchange_scheme.py b/src/sage/crypto/key_exchange/key_exchange_scheme.py new file mode 100644 index 00000000000..8ddf0c89de6 --- /dev/null +++ b/src/sage/crypto/key_exchange/key_exchange_scheme.py @@ -0,0 +1,106 @@ +r""" +Key Exchange Schemes + +This module contains base classes for key exchange schemes. The classes defined +in this module should not be called directly. It is the responsibility of child +classes to implement specific key exchange schemes. + + +AUTHORS: + +- Vincent Macri (2024-07-30): initial version +""" +# **************************************************************************** +# Copyright (C) 2024 Vincent Macri +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.misc.superseded import experimental +from sage.structure.sage_object import SageObject + + +class KeyExchangeScheme(SageObject): + """ + Abstract base class for key exchange schemes. + + Currently experimental and subject to change. + """ + + @experimental(37305) + def __init__(self): + """ + Create a ``KeyExchangeScheme`` instance. + + TESTS:: + + sage: from sage.crypto.key_exchange.key_exchange_scheme import KeyExchangeScheme + sage: K = KeyExchangeScheme() + doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. + See https://github.com/sagemath/sage/issues/37305 for details. + """ + pass + + def generate_secret_key(self): + """ + Generate a secret key. + + TESTS:: + + sage: from sage.crypto.key_exchange.key_exchange_scheme import KeyExchangeScheme + sage: K = KeyExchangeScheme() + sage: K.generate_secret_key() + Traceback (most recent call last): + ... + NotImplementedError + """ + raise NotImplementedError + + def generate_public_key(self, secret_key): + """ + Generate a public key using the given secret key. + + TESTS:: + + sage: from sage.crypto.key_exchange.key_exchange_scheme import KeyExchangeScheme + sage: K = KeyExchangeScheme() + sage: K.generate_public_key(None) + Traceback (most recent call last): + ... + NotImplementedError + """ + raise NotImplementedError + + def compute_shared_secret(self, alice_pk, bob_sk): + """ + Compute the shared secret using the given public key and secret keys. + + TESTS:: + + sage: from sage.crypto.key_exchange.key_exchange_scheme import KeyExchangeScheme + sage: K = KeyExchangeScheme() + sage: K.compute_shared_secret(None, None) + Traceback (most recent call last): + ... + NotImplementedError + """ + raise NotImplementedError + + def parameters(self): + """ + Get the parameters for the ``KeyExchangeScheme`` instance. + + TESTS:: + + sage: from sage.crypto.key_exchange.key_exchange_scheme import KeyExchangeScheme + sage: K = KeyExchangeScheme() + sage: K.parameters() + Traceback (most recent call last): + ... + NotImplementedError + """ + raise NotImplementedError diff --git a/src/sage/crypto/lattice.py b/src/sage/crypto/lattice.py index 513730ff89f..430ab98f3ae 100644 --- a/src/sage/crypto/lattice.py +++ b/src/sage/crypto/lattice.py @@ -22,7 +22,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + def gen_lattice(type='modular', n=4, m=8, q=11, seed=None, quotient=None, dual=False, ntl=False, lattice=False): @@ -37,43 +38,41 @@ def gen_lattice(type='modular', n=4, m=8, q=11, seed=None, - ``type`` -- one of the following strings - - ``'modular'`` (default) -- A class of lattices for which + - ``'modular'`` -- default; a class of lattices for which asymptotic worst-case to average-case connections hold. For - more refer to [Aj1996]_. - - ``'random'`` -- Special case of modular (n=1). A dense class + more refer to [Aj1996]_ + - ``'random'`` -- special case of modular (n=1); a dense class of lattice used for testing basis reduction algorithms - proposed by Goldstein and Mayer [GM2002]_. - - ``'ideal'`` -- Special case of modular. Allows for a more - compact representation proposed by [LM2006]_. - - ``'cyclotomic'`` -- Special case of ideal. Allows for - efficient processing proposed by [LM2006]_. + proposed by Goldstein and Mayer [GM2002]_ + - ``'ideal'`` -- special case of modular; allows for a more + compact representation proposed by [LM2006]_ + - ``'cyclotomic'`` -- special case of ideal; allows for + efficient processing proposed by [LM2006]_ - - ``n`` -- Determinant size, primal: `det(L) = q^n`, dual: `det(L) = q^{m-n}`. + - ``n`` -- determinant size, primal: `det(L) = q^n`, dual: `det(L) = q^{m-n}`. For ideal lattices this is also the degree of the quotient polynomial. - - ``m`` -- Lattice dimension, `L \subseteq Z^m`. + - ``m`` -- lattice dimension, `L \subseteq Z^m` - - ``q`` -- Coefficient size, `q-Z^m \subseteq L`. + - ``q`` -- coefficient size, `q-Z^m \subseteq L` - - ``seed`` -- Randomness seed. + - ``seed`` -- randomness seed - - ``quotient`` -- For the type ``'ideal'``, this determines the quotient - polynomial. Ignored for all other types. + - ``quotient`` -- for the type ``'ideal'``, this determines the quotient + polynomial. Ignored for all other types - - ``dual`` -- Set this flag if you want a basis for `q-dual(L)`, for example - for Regev's LWE bases [Reg2005]_. + - ``dual`` -- set this flag if you want a basis for `q-dual(L)`, for example + for Regev's LWE bases [Reg2005]_ - - ``ntl`` -- Set this flag if you want the lattice basis in NTL readable - format. + - ``ntl`` -- set this flag if you want the lattice basis in NTL readable + format - - ``lattice`` -- Set this flag if you want a + - ``lattice`` -- set this flag if you want a :class:`FreeModule_submodule_with_basis_integer` object instead - of an integer matrix representing the basis. - - OUTPUT: + of an integer matrix representing the basis - ``B`` a unique size-reduced triangular (primal: lower_left, - dual: lower_right) basis of row vectors for the lattice in question. + OUTPUT: ``B`` a unique size-reduced triangular (primal: lower_left, + dual: lower_right) basis of row vectors for the lattice in question EXAMPLES: @@ -254,7 +253,7 @@ def gen_lattice(type='modular', n=4, m=8, q=11, seed=None, P = quotient.parent() # P should be a univariate polynomial ring over ZZ_q - if not is_PolynomialRing(P): + if not isinstance(P, PolynomialRing_general): raise TypeError("quotient should be a univariate polynomial") assert P.base_ring() is ZZ_q diff --git a/src/sage/crypto/lfsr.py b/src/sage/crypto/lfsr.py index 87d64756b3a..7a640e91533 100644 --- a/src/sage/crypto/lfsr.py +++ b/src/sage/crypto/lfsr.py @@ -139,7 +139,7 @@ def lfsr_sequence(key, fill, n): INPUT: - - ``key`` -- a list of finite field elements, `[c_0, c_1,\dots, c_k]` + - ``key`` -- list of finite field elements, `[c_0, c_1,\dots, c_k]` - ``fill`` -- the list of the initial terms of the LFSR sequence, `[x_0,x_1,\dots,x_k]` @@ -174,7 +174,6 @@ def lfsr_sequence(key, fill, n): 1 + x + x^4 + x^5 + x^8 + x^9 + x^12 + x^13 + x^16 + x^17 + O(x^20) sage: (1+x+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^4 + x^5 + x^7 + x^8 + x^9 + x^11 + x^12 + x^13 + x^15 + x^16 + x^17 + x^19 + O(x^20) - """ if not isinstance(key, list): raise TypeError("key must be a list") @@ -202,7 +201,7 @@ def lfsr_autocorrelation(L, p, k): - ``p`` -- the period of `L` - - ``k`` -- an integer between `0` and `p` + - ``k`` -- integer between `0` and `p` OUTPUT: autocorrelation sequence of `L` @@ -236,7 +235,7 @@ def lfsr_connection_polynomial(s): OUTPUT: - - ``C(x)`` -- the connection polynomial of the minimal LFSR. + - ``C(x)`` -- the connection polynomial of the minimal LFSR This implements the algorithm in section 3 of J. L. Massey's article [Mas1969]_. diff --git a/src/sage/crypto/lwe.py b/src/sage/crypto/lwe.py index 035b05b48a2..7403260c514 100644 --- a/src/sage/crypto/lwe.py +++ b/src/sage/crypto/lwe.py @@ -257,10 +257,10 @@ def __init__(self, n, q, D, secret_dist='uniform', m=None): - ``q`` -- modulus typically > n (integer > 0) - ``D`` -- an error distribution such as an instance of :class:`DiscreteGaussianDistributionIntegerSampler` or :class:`UniformSampler` - - ``secret_dist`` -- distribution of the secret (default: 'uniform'); one of + - ``secret_dist`` -- distribution of the secret (default: ``'uniform'``); one of - - "uniform" -- secret follows the uniform distribution in `\Zmod{q}` - - "noise" -- secret follows the noise distribution + - ``'uniform'`` -- secret follows the uniform distribution in `\Zmod{q}` + - ``'noise'`` -- secret follows the noise distribution - ``(lb, ub)`` -- the secret is chosen uniformly from ``[lb,...,ub]`` including both endpoints @@ -399,6 +399,7 @@ def __init__(self, n, secret_dist='uniform', m=None): D = DiscreteGaussianDistributionIntegerSampler(s/sqrt(2*pi.n()), q) LWE.__init__(self, n=n, q=q, D=D, secret_dist=secret_dist, m=m) + class LindnerPeikert(LWE): """ LWE oracle with parameters as in [LP2011]_. @@ -464,9 +465,9 @@ def __init__(self, n, instance='key', m=None): - ``n`` -- security parameter (integer >= 89) - ``instance`` -- one of - - "key" -- the LWE-instance that hides the secret key is generated - - "encrypt" -- the LWE-instance that hides the message is generated - (default: ``key``) + - ``'key'`` -- the LWE-instance that hides the secret key is generated + - ``'encrypt'`` -- the LWE-instance that hides the message is generated + (default: ``'key'``) - ``m`` -- number of allowed samples or ``None`` in which case ``m`` is chosen as in [CGW2013]_. (default: ``None``) @@ -512,6 +513,7 @@ def __init__(self, n, instance='key', m=None): else: raise TypeError("Parameter instance=%s not understood." % (instance)) + class RingLWE(SageObject): """ Ring Learning with Errors oracle. @@ -607,6 +609,7 @@ def __call__(self): a = self.R_q.random_element() return vector(a), vector(a * (self.__s) + self.D()) + class RingLindnerPeikert(RingLWE): """ Ring-LWE oracle with parameters as in [LP2011]_. @@ -650,6 +653,7 @@ def __init__(self, N, delta=0.01, m=None): D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], n, stddev) RingLWE.__init__(self, N=N, q=q, D=D, poly=None, secret_dist='noise', m=m) + class RingLWEConverter(SageObject): """ Wrapper callable to convert Ring-LWE oracles into LWE oracles by @@ -709,10 +713,10 @@ def _repr_(self): sage: lwe = RingLWEConverter(rlwe) sage: lwe RingLWEConverter(RingLWE(20, 257, Discrete Gaussian sampler for polynomials of degree < 8 with σ=5.000000 in each component, x^8 - x^6 + x^4 - x^2 + 1, 'uniform', None)) - """ return "RingLWEConverter(%s)" % str(self.ringlwe) + def samples(m, n, lwe, seed=None, balanced=False, **kwds): """ Return ``m`` LWE samples. @@ -749,7 +753,6 @@ def samples(m, n, lwe, seed=None, balanced=False, **kwds): sage: samples(2, 20, 'LindnerPeikert') [((506, 1205, 398, 0, 337, 106, 836, 75, 1242, 642, 840, 262, 1823, 1798, 1831, 1658, 1084, 915, 1994, 163), 1447), ((463, 250, 1226, 1906, 330, 933, 1014, 1061, 1322, 2035, 1849, 285, 1993, 1975, 864, 1341, 41, 1955, 1818, 1357), 312)] - """ if seed is not None: set_random_seed(seed) @@ -803,7 +806,7 @@ def balance_sample(s, q=None): ....: assert all(-257//2 <= c <= 257//2 for bi in b for c in bi) ....: assert all(s[i][j] == b[i][j] % 257 for i in range(2) for j in range(8)) - .. note:: + .. NOTE:: This function is useful to convert between Sage's standard representation of elements in `\Zmod{q}` as integers between 0 and q-1 diff --git a/src/sage/crypto/meson.build b/src/sage/crypto/meson.build new file mode 100644 index 00000000000..633c048a59c --- /dev/null +++ b/src/sage/crypto/meson.build @@ -0,0 +1,38 @@ +py.install_sources( + '__init__.py', + 'all.py', + 'boolean_function.pxd', + 'cipher.py', + 'classical.py', + 'classical_cipher.py', + 'cryptosystem.py', + 'lattice.py', + 'lfsr.py', + 'lwe.py', + 'sboxes.py', + 'stream.py', + 'stream_cipher.py', + 'util.py', + subdir: 'sage/crypto', +) + +extension_data = { + 'boolean_function' : files('boolean_function.pyx'), + 'sbox' : files('sbox.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/crypto', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +install_subdir('block_cipher', install_dir: sage_install_dir / 'crypto') +install_subdir('key_exchange', install_dir: sage_install_dir / 'crypto') +install_subdir('mq', install_dir: sage_install_dir / 'crypto') +install_subdir('public_key', install_dir: sage_install_dir / 'crypto') diff --git a/src/sage/crypto/mq/mpolynomialsystemgenerator.py b/src/sage/crypto/mq/mpolynomialsystemgenerator.py index 4416d9ef7f6..864e9ab1ea1 100644 --- a/src/sage/crypto/mq/mpolynomialsystemgenerator.py +++ b/src/sage/crypto/mq/mpolynomialsystemgenerator.py @@ -40,7 +40,8 @@ def varformatstr(self, name): encoded. INPUT: - name -- string + + - ``name`` -- string EXAMPLES:: @@ -61,8 +62,9 @@ def varstrs(self, name, round): This function is typically used by self._vars. INPUT: - name -- string - round -- integer index + + - ``name`` -- string + - ``round`` -- integer index EXAMPLES:: @@ -81,8 +83,9 @@ def vars(self, name, round): index 'round'. INPUT: - name -- string - round -- integer index + + - ``name`` -- string + - ``round`` -- integer index EXAMPLES:: @@ -113,7 +116,7 @@ def ring(self): def block_order(self): """ Return a block term ordering for the equation systems - generated by self. + generated by ``self``. EXAMPLES:: @@ -131,8 +134,9 @@ def __call__(self, P, K): Encrypt plaintext P using the key K. INPUT: - P -- plaintext (vector, list) - K -- key (vector, list) + + - ``P`` -- plaintext (vector, list) + - ``K`` -- key (vector, list) EXAMPLES:: @@ -147,7 +151,7 @@ def __call__(self, P, K): def sbox(self): """ - Return SBox object for self. + Return SBox object for ``self``. EXAMPLES:: @@ -167,8 +171,9 @@ def polynomial_system(self, P=None, K=None): to their solutions. INPUT: - P -- plaintext (vector, list) - K -- key (vector, list) + + - ``P`` -- plaintext (vector, list) + - ``K`` -- key (vector, list) EXAMPLES:: diff --git a/src/sage/crypto/mq/rijndael_gf.py b/src/sage/crypto/mq/rijndael_gf.py index 55ae295f2cd..132e7356d24 100644 --- a/src/sage/crypto/mq/rijndael_gf.py +++ b/src/sage/crypto/mq/rijndael_gf.py @@ -442,16 +442,16 @@ def __init__(self, Nb, Nk, state_chr='a', key_chr='k'): INPUT: - - ``Nb`` -- The block length of this instantiation. Must be between 4 - and 8. + - ``Nb`` -- the block length of this instantiation. Must be between 4 + and 8 - - ``Nk`` -- The key length of this instantiation. Must be between 4 and 8. + - ``Nk`` -- the key length of this instantiation. Must be between 4 and 8 - - ``state_chr`` -- The variable name for polynomials representing - elements from state matrices. + - ``state_chr`` -- the variable name for polynomials representing + elements from state matrices - - ``key_chr`` -- The variable name for polynomials representing - elements of the key schedule. + - ``key_chr`` -- the variable name for polynomials representing + elements of the key schedule EXAMPLES:: @@ -575,19 +575,17 @@ def __call__(self, text, key, algorithm='encrypt', format='hex'): INPUT: - - ``text`` -- A plaintext to encrypt or a ciphertext to decrypt. + - ``text`` -- a plaintext to encrypt or a ciphertext to decrypt - - ``key`` -- The key to encrypt/decrypt ``text`` with. + - ``key`` -- the key to encrypt/decrypt ``text`` with - - ``algorithm`` -- Whether to encrypt or decrypt ``text``. Flag for - encryption is "encrypt", flag for decryption is "decrypt". + - ``algorithm`` -- whether to encrypt or decrypt ``text``. Flag for + encryption is "encrypt", flag for decryption is "decrypt" - - ``format`` -- The format of ``text`` and ``key``, either "hex" or + - ``format`` -- the format of ``text`` and ``key``, either "hex" or "binary" - OUTPUT: - - - The encrypted or decrypted message ``text`` with key ``key``. + OUTPUT: the encrypted or decrypted message ``text`` with key ``key`` EXAMPLES:: @@ -615,8 +613,8 @@ def __call__(self, text, key, algorithm='encrypt', format='hex'): elif algorithm == 'decrypt': return self.decrypt(text, key, format) else: - raise ValueError(("keyword 'algorithm' must be either 'encrypt' " - "or 'decrypt'")) + raise ValueError("keyword 'algorithm' must be either 'encrypt' " + "or 'decrypt'") def __repr__(self): r""" @@ -679,11 +677,11 @@ def _hex_to_GF(self, H, matrix=True): INPUT: - - ``H`` -- A hex string where every two hex characters correspond to a + - ``H`` -- a hex string where every two hex characters correspond to a single element in `\GF{2^8}` - - ``matrix`` -- (default: ``True``) Return a list if ``False``; - return a state matrix if ``True``. + - ``matrix`` -- boolean (default: ``True``); return a list if ``False``. + Return a state matrix if ``True`` OUTPUT: @@ -728,7 +726,7 @@ def _GF_to_hex(self, GF): INPUT: - - ``GF`` -- Either a state matrix over `\GF{2^8}`, a list of elements + - ``GF`` -- either a state matrix over `\GF{2^8}`, a list of elements from `\GF{2^8}`, or a single element from `\GF{2^8}` OUTPUT: @@ -795,11 +793,11 @@ def _bin_to_GF(self, B, matrix=True): INPUT: - - ``B`` -- A binary string where every eight bits correspond to a + - ``B`` -- a binary string where every eight bits correspond to a single element in `\GF{2^8}` - - ``matrix`` -- (default: ``True``) Return a list if ``False``. - Return a state matrix over `\GF{2^8}` if ``True``. + - ``matrix`` -- boolean (default: ``True``); return a list if ``False``. + Return a state matrix over `\GF{2^8}` if ``True`` OUTPUT: @@ -855,7 +853,7 @@ def _GF_to_bin(self, GF): INPUT: - - ``GF`` -- Either a state matrix over `\GF{2^8}`, a list of elements + - ``GF`` -- either a state matrix over `\GF{2^8}`, a list of elements from `\GF{2^8}`, or a single element from `\GF{2^8}` OUTPUT: @@ -920,16 +918,14 @@ def encrypt(self, plain, key, format='hex'): INPUT: - - ``plain`` -- The plaintext to be encrypted. + - ``plain`` -- the plaintext to be encrypted - - ``key`` -- The key to encrypt ``plain`` with. + - ``key`` -- the key to encrypt ``plain`` with - - ``format`` -- (default: ``hex``) The string format of ``key`` and - ``plain``, either "hex" or "binary". + - ``format`` -- (default: ``hex``) the string format of ``key`` and + ``plain``, either "hex" or "binary" - OUTPUT: - - - A string of the plaintext ``plain`` encrypted with the key ``key``. + OUTPUT: string of the plaintext ``plain`` encrypted with the key ``key`` EXAMPLES:: @@ -985,8 +981,8 @@ def encrypt(self, plain, key, format='hex'): key_state = self._bin_to_GF(key) roundKeys = self.expand_key(key_state) else: - raise ValueError(("'format' keyword must be either 'hex' or " - "'binary'")) + raise ValueError("'format' keyword must be either 'hex' or " + "'binary'") state = self.add_round_key(state, roundKeys[0]) for r in range(self._Nr-1): @@ -1009,12 +1005,12 @@ def decrypt(self, ciphertext, key, format='hex'): INPUT: - - ``ciphertext`` -- The ciphertext to be decrypted. + - ``ciphertext`` -- the ciphertext to be decrypted - - ``key`` -- The key to decrypt ``ciphertext`` with. + - ``key`` -- the key to decrypt ``ciphertext`` with - - ``format`` -- (default: ``hex``) The string format that both - ``ciphertext`` and ``key`` must be in, either "hex" or "binary". + - ``format`` -- (default: ``hex``) the string format that both + ``ciphertext`` and ``key`` must be in, either "hex" or "binary" OUTPUT: @@ -1061,8 +1057,8 @@ def decrypt(self, ciphertext, key, format='hex'): elif format == 'binary': if not isinstance(ciphertext, str) or \ any(c not in '01' for c in ciphertext): - raise TypeError(("'ciphertext' keyword must be a binary " - "string")) + raise TypeError("'ciphertext' keyword must be a binary " + "string") if len(ciphertext) != 32 * self._Nb: msg = "'ciphertext' keyword's length must be {0}, not {1}" raise ValueError(msg.format(32 * self._Nb, len(ciphertext))) @@ -1076,8 +1072,8 @@ def decrypt(self, ciphertext, key, format='hex'): key_state = self._bin_to_GF(key) roundKeys = self.expand_key(key_state) else: - raise ValueError(("'format' keyword must be either \'hex\' or " - "'binary'")) + raise ValueError("'format' keyword must be either \'hex\' or " + "'binary'") state = self.add_round_key(state, roundKeys[self._Nr]) state = self.shift_rows(state, algorithm='decrypt') @@ -1100,13 +1096,13 @@ def _check_valid_PRmatrix(self, PRm, keyword): INPUT: - - ``PRm`` -- If ``PRm`` is a `4 \times Nb` matrix with entries from + - ``PRm`` -- if ``PRm`` is a `4 \times Nb` matrix with entries from the multivariate PolynomialRing ``_all_PR``, this method does nothing `\GF{2^8}`, this method does nothing. Otherwise, this method raises an error. Note that a matrix of elements from `\GF{2^8}` is regarded as a matrix with entries from ``_all_PR`` and will pass this test. - - ``keyword`` -- The name of the keyword ``PRm`` from where this + - ``keyword`` -- the name of the keyword ``PRm`` from where this method was called, for the potential error message. For example, if called from ``sub_bytes``, ``keyword`` would be "state". @@ -1164,8 +1160,8 @@ def expand_key(self, key): INPUT: - - ``key`` -- The key to build a key schedule from. Must be a matrix - over `\GF{2^8}` of dimensions `4 \times N_k`. + - ``key`` -- the key to build a key schedule from. Must be a matrix + over `\GF{2^8}` of dimensions `4 \times N_k` OUTPUT: @@ -1232,11 +1228,11 @@ def expand_key_poly(self, row, col, round): INPUT: - - ``row`` -- The row position of the element represented by this - polynomial. + - ``row`` -- the row position of the element represented by this + polynomial - - ``col`` -- The column position of the element represented by this - polynomial. + - ``col`` -- the column position of the element represented by this + polynomial OUTPUT: @@ -1323,24 +1319,24 @@ def apply_poly(self, state, poly_constr, algorithm='encrypt', keys=None, INPUT: - - ``state`` -- The state matrix over `\GF{2^8}` to which - ``poly_method`` is applied to. + - ``state`` -- the state matrix over `\GF{2^8}` to which + ``poly_method`` is applied to - - ``poly_constr`` -- The ``Round_Component_Poly_Constr`` object to - build polynomials during evaluation. + - ``poly_constr`` -- the ``Round_Component_Poly_Constr`` object to + build polynomials during evaluation - - ``algorithm`` -- (default: "encrypt") Passed directly to - ``rcpc`` to select encryption or decryption. The - encryption flag is "encrypt" and the decrypt flag is "decrypt". + - ``algorithm`` -- (default: ``'encrypt'``) passed directly to + ``rcpc`` to select encryption or decryption; the + encryption flag is "encrypt" and the decrypt flag is "decrypt" - - ``keys`` -- (default: None) An array of `N_r` subkey matrices to + - ``keys`` -- (default: ``None``) an array of `N_r` subkey matrices to replace any key variables in any polynomials returned by ``poly_method``. Must be identical to the format returned by ``expand_key``. If any polynomials have key variables and ``keys`` is not supplied, the key variables will remain as-is. - - ``poly_constr_attr`` -- (default:None) A dictionary of keyword - attributes to pass to ``rcpc`` when it is called. + - ``poly_constr_attr`` -- (default: ``None``) a dictionary of keyword + attributes to pass to ``rcpc`` when it is called OUTPUT: @@ -1448,25 +1444,25 @@ def compose(self, f, g, algorithm='encrypt', f_attr=None, g_attr=None): INPUT: - - ``f`` -- A ``Round_Component_Poly_Constr`` object corresponding to - a round component function `f`. + - ``f`` -- a ``Round_Component_Poly_Constr`` object corresponding to + a round component function `f` - - ``g`` -- A ``Round_Component_Poly_Constr`` object corresponding to + - ``g`` -- a ``Round_Component_Poly_Constr`` object corresponding to a round component function `g` or a polynomial output of this object's ``__call__`` method. - - ``algorithm`` -- (default: "encrypt") Whether ``f`` and ``g`` + - ``algorithm`` -- (default: ``'encrypt'``) whether ``f`` and ``g`` should use their encryption transformations or their decryption transformations. Does nothing if ``g`` is a ``Round_Component_Poly_Constr`` object. The encryption flag is "encrypt" and the decryption flag is "decrypt". - - ``f_attr`` -- (default: None) A dictionary of keyword attributes to - pass to ``f`` when it is called. + - ``f_attr`` -- (default: ``None``) a dictionary of keyword attributes to + pass to ``f`` when it is called - - ``g_attr`` -- (default: None) A dictionary of keyword attributes to - pass to ``g`` when it is called. Does nothing if ``g`` is a - polynomial. + - ``g_attr`` -- (default: ``None``) a dictionary of keyword attributes to + pass to ``g`` when it is called; does nothing if ``g`` is a + polynomial OUTPUT: @@ -1646,18 +1642,18 @@ def _add_round_key_pc(self, row, col, algorithm='encrypt', round=0): INPUT: - - ``row`` -- The row number of the entry represented by this method's - output. + - ``row`` -- the row number of the entry represented by this method's + output - - ``col`` -- The column number of the entry represented by this - method's output. + - ``col`` -- the column number of the entry represented by this + method's output - - ``algorithm`` -- (default: "encrypt") Whether to return the - polynomial as an encryption or as a decryption. The encryption flag - is "encrypt" and the decryption flag is "decrypt". + - ``algorithm`` -- (default: ``'encrypt'``) whether to return the + polynomial as an encryption or as a decryption; the encryption flag + is "encrypt" and the decryption flag is "decrypt" - - ``round`` -- (default: 0) The round number of the entry represented - by this method's output. + - ``round`` -- (default: 0) the round number of the entry represented + by this method's output OUTPUT: @@ -1693,9 +1689,9 @@ def add_round_key(self, state, round_key): INPUT: - - ``state`` -- The state matrix to have ``round_key`` added to. + - ``state`` -- the state matrix to have ``round_key`` added to - - ``round_key`` -- The round key to add to ``state``. + - ``round_key`` -- the round key to add to ``state`` OUTPUT: @@ -1804,20 +1800,20 @@ def _sub_bytes_pc(self, row, col, algorithm='encrypt', no_inversion=False): INPUT: - - ``row`` -- The row number of the entry represented by this method's - output. + - ``row`` -- the row number of the entry represented by this method's + output - - ``col`` -- The column number of the entry represented by this - method's output. + - ``col`` -- the column number of the entry represented by this + method's output - - ``algorithm`` -- (default: "encrypt") Whether to return the + - ``algorithm`` -- (default: ``'encrypt'``) whether to return the polynomial as an encryption or as a decryption. The encryption flag is "encrypt" and the decryption flag is "decrypt". - - ``no_inversion`` -- (default: ``False``) Don't perform the inversion - step, only perform the affine transformation. Primarily intended - to increase performance during decryption, as is shown in the - below example. + - ``no_inversion`` -- boolean (default: ``False``); don't perform the + inversion step, only perform the affine transformation. Primarily + intended to increase performance during decryption, as is shown in + the below example. OUTPUT: @@ -1878,8 +1874,8 @@ def _sub_bytes_pc(self, row, col, algorithm='encrypt', no_inversion=False): else: return result ** 254 else: - raise ValueError(("keyword 'algorithm' must be either 'encrypt' " - "or 'decrypt'")) + raise ValueError("keyword 'algorithm' must be either 'encrypt' " + "or 'decrypt'") def _srd(self, el, algorithm='encrypt'): r""" @@ -1887,17 +1883,15 @@ def _srd(self, el, algorithm='encrypt'): INPUT: - - ``el`` -- An element of `\GF{2^8}`. + - ``el`` -- an element of `\GF{2^8}` - - ``algorithm`` -- (default: "encrypt") Whether to perform the + - ``algorithm`` -- (default: ``'encrypt'``) whether to perform the encryption transformation or the decryption transformation. The encryption flag is "encrypt" and the decryption flag is "decrypt". - OUTPUT: - - - The result of the application of the non-linear transformation - SubBytes to ``el``. + OUTPUT: the result of the application of the non-linear transformation + SubBytes to ``el``. EXAMPLES:: @@ -1916,8 +1910,8 @@ def _srd(self, el, algorithm='encrypt'): state = [el] + [self._F.zero()]*((4 * self._Nb)-1) return p(state) ** 254 else: - raise ValueError(("keyword 'algorithm' must be either 'encrypt' " - "or 'decrypt'")) + raise ValueError("keyword 'algorithm' must be either 'encrypt' " + "or 'decrypt'") def sub_bytes(self, state, algorithm='encrypt'): r""" @@ -1925,16 +1919,14 @@ def sub_bytes(self, state, algorithm='encrypt'): INPUT: - - ``state`` -- The state matrix to apply SubBytes to. + - ``state`` -- the state matrix to apply SubBytes to - - ``algorithm`` -- (default: "encrypt") Whether to apply the + - ``algorithm`` -- (default: ``'encrypt'``) whether to apply the encryption step of SubBytes or its decryption inverse. The encryption flag is "encrypt" and the decryption flag is "decrypt". - OUTPUT: - - - The state matrix over `\GF{2^8}` where SubBytes has been applied - to every entry of ``state``. + OUTPUT: the state matrix over `\GF{2^8}` where SubBytes has been + applied to every entry of ``state`` EXAMPLES:: @@ -1980,21 +1972,19 @@ def _mix_columns_pc(self, row, col, algorithm='encrypt'): INPUT: - - ``row`` -- The row number of the entry represented by this method's - output. - - - ``col`` -- The column number of the entry represented by this - method's output. + - ``row`` -- the row number of the entry represented by this method's + output - - ``algorithm`` -- (default: "encrypt") Whether to perform the - encryption transformation or the decryption transformation. The - encryption flag is "encrypt" and the decryption flag is "decrypt". + - ``col`` -- the column number of the entry represented by this + method's output - OUTPUT: + - ``algorithm`` -- (default: ``'encrypt'``) whether to perform the + encryption transformation or the decryption transformation; the + encryption flag is "encrypt" and the decryption flag is "decrypt" - - A polynomial in terms of entries of the input state matrix which - represents the ``row,col`` th entry of the output matrix after - MixColumns has been applied to it. + OUTPUT: a polynomial in terms of entries of the input state matrix + which represents the ``row,col`` th entry of the output matrix after + MixColumns has been applied to it EXAMPLES:: @@ -2020,8 +2010,8 @@ def _mix_columns_pc(self, row, col, algorithm='encrypt'): elif algorithm == 'decrypt': coeffs = self._mixcols_D else: - raise ValueError(("keyword 'algorithm' must be either 'encrypt' " - "or 'decrypt'")) + raise ValueError("keyword 'algorithm' must be either 'encrypt' " + "or 'decrypt'") return sum([coeffs[row,k] * self.state_vrs[k,col] for k in range(4)]) def mix_columns(self, state, algorithm='encrypt'): @@ -2030,16 +2020,14 @@ def mix_columns(self, state, algorithm='encrypt'): INPUT: - - ``state`` -- The state matrix to apply MixColumns to. + - ``state`` -- the state matrix to apply MixColumns to - - ``algorithm`` -- (default: "encrypt") Whether to perform the - encryption version of MixColumns, or its decryption inverse. The - encryption flag is "encrypt" and the decryption flag is "decrypt". - - OUTPUT: + - ``algorithm`` -- (default: ``'encrypt'``) whether to perform the + encryption version of MixColumns, or its decryption inverse; the + encryption flag is "encrypt" and the decryption flag is "decrypt" - - The state matrix over `\GF{2^8}` which is the result of applying - MixColumns to ``state``. + OUTPUT: the state matrix over `\GF{2^8}` which is the result of + applying MixColumns to ``state`` EXAMPLES:: @@ -2082,21 +2070,19 @@ def _shift_rows_pc(self, row, col, algorithm='encrypt'): INPUT: - - ``row`` -- The row number of the entry represented by this method's - output. + - ``row`` -- the row number of the entry represented by this method's + output - - ``col`` -- The column number of the entry represented by this - method's output. + - ``col`` -- the column number of the entry represented by this + method's output - - ``algorithm`` -- (default: "encrypt") Whether to perform ShiftRows' + - ``algorithm`` -- (default: ``'encrypt'``) whether to perform ShiftRows' encryption step or its decryption inverse. The encryption flag is "encrypt" and the decryption flag is "decrypt". - OUTPUT: - - - A polynomial in terms of entries of the input state matrix which - represents the ``row,col`` th entry of the output matrix after - ShiftRows has been applied to it. + OUTPUT: a polynomial in terms of entries of the input state matrix + which represents the ``row,col`` th entry of the output matrix after + ShiftRows has been applied to it EXAMPLES:: @@ -2123,8 +2109,8 @@ def _shift_rows_pc(self, row, col, algorithm='encrypt'): elif algorithm == 'decrypt': offs = self._shiftrows_offsets_D else: - raise ValueError(("keyword 'algorithm' must be either 'encrypt' " - "or 'decrypt'")) + raise ValueError("keyword 'algorithm' must be either 'encrypt' " + "or 'decrypt'") return self.state_vrs[row, (col + offs[4 - self._Nb][row]) % 4] def shift_rows(self, state, algorithm='encrypt'): @@ -2133,17 +2119,15 @@ def shift_rows(self, state, algorithm='encrypt'): INPUT: - - ``state`` -- A state matrix over `\GF{2^8}` to which ShiftRows is - applied to. + - ``state`` -- a state matrix over `\GF{2^8}` to which ShiftRows is + applied to - - ``algorithm`` -- (default: "encrypt") Whether to perform the - encryption version of ShiftRows or its decryption inverse. The - encryption flag is "encrypt" and the decryption flag is "decrypt". - - OUTPUT: + - ``algorithm`` -- (default: ``'encrypt'``) whether to perform the + encryption version of ShiftRows or its decryption inverse; the + encryption flag is "encrypt" and the decryption flag is "decrypt" - - A state matrix over `\GF{2^8}` which is the application of ShiftRows - to ``state``. + OUTPUT: a state matrix over `\GF{2^8}` which is the application of + ShiftRows to ``state`` EXAMPLES:: @@ -2169,7 +2153,7 @@ def __init__(self, polynomial_constr, rgf, round_component_name=None): INPUT: - - ``polynomial_constr`` -- A function which takes an index + - ``polynomial_constr`` -- a function which takes an index ``row,col`` and returns a polynomial representing the ``row,col`` th entry of a matrix after a specific round component function has been applied to it. This polynomial must be in terms of @@ -2179,12 +2163,12 @@ def __init__(self, polynomial_constr, rgf, round_component_name=None): algorithm='encrypt', **kwargs)`` and must be able to be called as ``polynomial_constr(row, col)``. - - ``rgf`` -- The RijndaelGF object whose state entries are - represented by polynomials returned from ``polynomial_constr``. + - ``rgf`` -- the RijndaelGF object whose state entries are + represented by polynomials returned from ``polynomial_constr`` - - ``round_component_name`` -- The name of the round component - function this object corresponds to as a string. Used solely - for display purposes. + - ``round_component_name`` -- the name of the round component + function this object corresponds to as a string; used solely + for display purposes EXAMPLES:: @@ -2293,16 +2277,16 @@ def __call__(self, row, col, algorithm='encrypt', **kwargs): INPUT: - - ``row`` -- The row number to pass to ``polynomial_constr``. + - ``row`` -- the row number to pass to ``polynomial_constr`` - - ``col`` -- The column number to pass to ``polynomial_constr``. + - ``col`` -- the column number to pass to ``polynomial_constr`` - - ``algorithm`` -- (default: 'encrypt') The algorithm keyword - to pass to ``polynomial_constr``. + - ``algorithm`` -- (default: ``'encrypt'``) the algorithm keyword + to pass to ``polynomial_constr`` - - ``**kwargs`` -- Keyword arguments to pass to + - ``**kwargs`` -- keyword arguments to pass to ``polynomial_constr``. Keyword arguments will vary depending - on ``polynomial_constr``. + on ``polynomial_constr`` OUTPUT: diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index 514d9df9c94..610a97b05fb 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -332,11 +332,11 @@ def SR(n=1, r=1, c=1, e=4, star=False, **kwargs): INPUT: - - ``n`` -- the number of rounds (default: 1) - - ``r`` -- the number of rows in the state array (default: 1) - - ``c`` -- the number of columns in the state array (default: 1) - - ``e`` -- the exponent of the finite extension field (default: 4) - - ``star`` -- determines if SR\* or SR should be constructed (default: ``False``) + - ``n`` -- the number of rounds (default: 1) + - ``r`` -- the number of rows in the state array (default: 1) + - ``c`` -- the number of columns in the state array (default: 1) + - ``e`` -- the exponent of the finite extension field (default: 4) + - ``star`` -- determines if SR\* or SR should be constructed (default: ``False``) - ``aes_mode`` -- as the SR key schedule specification differs slightly from the AES key schedule, this parameter controls which schedule to use (default: ``True``) @@ -344,18 +344,17 @@ def SR(n=1, r=1, c=1, e=4, star=False, **kwargs): over `\GF{2^e}` (default: ``False``) - ``polybori`` -- use the ``BooleanPolynomialRing`` as polynomial representation (default: ``True``, `\GF{2}` only) - - ``order`` -- a string to specify the term ordering of the + - ``order`` -- string to specify the term ordering of the variables (default: ``deglex``) - - ``postfix`` -- a string which is appended after the variable name - (default: '') - - ``allow_zero_inversions`` -- a boolean to control whether zero + - ``postfix`` -- string which is appended after the variable name + (default: ``''``) + - ``allow_zero_inversions`` -- boolean to control whether zero inversions raise an exception (default: ``False``) - ``correct_only`` -- only include correct inversion polynomials (default: ``False``, `\GF{2}` only) - ``biaffine_only`` -- only include bilinear and biaffine inversion polynomials (default: ``True``, `\GF{2}` only) - EXAMPLES:: sage: sr = mq.SR(1, 1, 1, 4) @@ -602,7 +601,7 @@ def _repr_(self): def base_ring(self): r""" - Return the base field of self as determined by + Return the base field of ``self`` as determined by ``self.e``. EXAMPLES:: @@ -672,7 +671,7 @@ def sub_bytes(self, d): INPUT: - - ``d`` -- state array or something coercible to a state array + - ``d`` -- state array or something coercible to a state array EXAMPLES:: @@ -697,8 +696,7 @@ def sub_byte(self, b): INPUT: - - ``b`` -- an element in ``self.base_ring()`` - + - ``b`` -- an element in ``self.base_ring()`` EXAMPLES: @@ -919,10 +917,7 @@ def mix_columns(self, d): INPUT: - - - ``d`` -- state array or something coercible to a - state array - + - ``d`` -- state array or something coercible to a state array EXAMPLES:: @@ -969,13 +964,9 @@ def add_round_key(self, d, key): INPUT: + - ``d`` -- state array or something coercible to a state array - - ``d`` -- state array or something coercible to a - state array - - - ``key`` -- state array or something coercible to a - state array - + - ``key`` -- state array or something coercible to a state array EXAMPLES:: @@ -996,9 +987,7 @@ def state_array(self, d=None): INPUT: - - - ``d`` -- a matrix, a list, or a tuple (default: ``None``) - + - ``d`` -- a matrix, a list, or a tuple (default: ``None``) EXAMPLES:: @@ -1077,30 +1066,27 @@ def random_state_array(self, *args, **kwds): def random_vector(self, *args, **kwds): r""" Return a random vector as it might appear in the algebraic - expression of self. + expression of ``self``. EXAMPLES:: sage: mq.SR(2, 2, 2, 4).random_vector().parent() Full MatrixSpace of 16 by 1 dense matrices over Finite Field in a of size 2^4 - .. note:: + .. NOTE:: `\phi` was already applied to the result. """ return self.vector(self.random_state_array(*args, **kwds)) - def random_element(self, elem_type="vector", *args, **kwds): + def random_element(self, elem_type='vector', *args, **kwds): """ - Return a random element for self. Other arguments and keywords are + Return a random element for ``self``. Other arguments and keywords are passed to random_* methods. INPUT: - - - ``elem_type`` -- either 'vector' or 'state array' - (default: ``'vector'``) - + - ``elem_type`` -- either 'vector' or 'state array' (default: ``'vector'``) EXAMPLES:: @@ -1373,18 +1359,16 @@ def __call__(self, P, K): return _type(P) - def hex_str(self, M, typ="matrix"): + def hex_str(self, M, typ='matrix'): r""" Return a hex string for the provided AES state array/matrix. INPUT: + - ``M`` -- state array - - ``M`` -- state array - - - ``typ`` -- controls what to return, either 'matrix' - or 'vector' (default: ``'matrix'``) - + - ``typ`` -- controls what to return, either 'matrix' + or 'vector' (default: ``'matrix'``) EXAMPLES:: @@ -1414,9 +1398,7 @@ def hex_str_matrix(self, M): INPUT: - - - ``M`` -- an AES state array - + - ``M`` -- an AES state array EXAMPLES:: @@ -1445,9 +1427,7 @@ def hex_str_vector(self, M): INPUT: - - - ``M`` -- an AES state array - + - ``M`` -- an AES state array EXAMPLES:: @@ -1474,15 +1454,13 @@ def _insert_matrix_into_matrix(self, dst, src, row, col): INPUT: + - ``dst`` -- a matrix - - ``dst`` -- a matrix - - - ``src`` -- a matrix + - ``src`` -- a matrix - - ``row`` -- offset row - - - ``col`` -- offset columns + - ``row`` -- offset row + - ``col`` -- offset columns EXAMPLES:: @@ -1518,11 +1496,10 @@ def varformatstr(self, name, n=None, rc=None, e=None): INPUT: - - ``name`` -- name of the variable - - ``n`` -- number of rounds (default: ``None``) - - ``rc`` -- number of rows \* number of cols (default: ``None``) - - ``e`` -- exponent of base field (default: ``None``) - + - ``name`` -- name of the variable + - ``n`` -- number of rounds (default: ``None``) + - ``rc`` -- number of rows \* number of cols (default: ``None``) + - ``e`` -- exponent of base field (default: ``None``) EXAMPLES:: @@ -1584,7 +1561,6 @@ def varstrs(self, name, nr, rc=None, e=None): sage: sr = mq.SR(10, 1, 2, 4) sage: sr.varstrs('x', 2) ('x200', 'x201', 'x202', 'x203', 'x210', 'x211', 'x212', 'x213') - """ if rc is None: rc = self.r * self.c @@ -1614,7 +1590,6 @@ def vars(self, name, nr, rc=None, e=None): sage: sr = mq.SR(10, 1, 2, 4) sage: sr.vars('x', 2) (x200, x201, x202, x203, x210, x211, x212, x213) - """ gd = self.variable_dict() return tuple([gd[s] for s in self.varstrs(name, nr, rc, e)]) @@ -1671,7 +1646,6 @@ def variable_dict(self): 'x101': x101, 'x102': x102, 'x103': x103} - """ try: R,gd = self._variable_dict @@ -1688,7 +1662,7 @@ def variable_dict(self): def block_order(self): """ - Return a block order for self where each round is a block. + Return a block order for ``self`` where each round is a block. EXAMPLES:: @@ -1821,15 +1795,11 @@ def round_polynomials(self, i, plaintext=None, ciphertext=None): INPUT: + - ``i`` -- round number - - ``i`` -- round number - - - ``plaintext`` -- optional plaintext (mandatory in - first round) - - - ``ciphertext`` -- optional ciphertext (mandatory in - last round) + - ``plaintext`` -- plaintext (optional, mandatory in first round) + - ``ciphertext`` -- ciphertext (optional, mandatory in last round) OUTPUT: tuple @@ -1891,19 +1861,19 @@ def key_schedule_polynomials(self, i): INPUT: - - ``i`` -- round (`0 \leq i \leq n`) + - ``i`` -- round (`0 \leq i \leq n`) EXAMPLES:: sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=False) - The 0-th subkey is the user provided key, so only conjugacy + The `0`-th subkey is the user provided key, so only conjugacy relations or field polynomials are added.:: sage: sr.key_schedule_polynomials(0) (k000^2 + k000, k001^2 + k001, k002^2 + k002, k003^2 + k003) - The 1-th subkey is derived from the user provided key according to + The 1st subkey is derived from the user provided key according to the key schedule which is non-linear.:: sage: sr.key_schedule_polynomials(1) @@ -2138,12 +2108,13 @@ class SR_gf2n(SR_generic): """ def vector(self, d=None): """ - Constructs a vector suitable for the algebraic representation of + Construct a vector suitable for the algebraic representation of SR, i.e. BES. INPUT: - - ``d`` -- values for vector, must be understood by ``self.phi`` (default:``None``) + - ``d`` -- values for vector, must be understood by ``self.phi`` + (default: ``None``) EXAMPLES:: @@ -2192,13 +2163,13 @@ def is_vector(self, d): def phi(self, l): r""" - The operation `\phi` from [MR2002]_ + The operation `\phi` from [MR2002]_. Projects state arrays to their algebraic representation. INPUT: - - ``l`` -- element to perform `\phi` on. + - ``l`` -- element to perform `\phi` on EXAMPLES:: @@ -2243,9 +2214,9 @@ def antiphi(self, l): True """ if isinstance(l, Matrix): - ret = [e for e in l.transpose().list()[0:-1:self.e]] + ret = l.transpose().list()[0:-1:self.e] else: - ret = [e for e in l[0:-1:self.e]] + ret = l[0:-1:self.e] if isinstance(l, list): return ret @@ -2296,8 +2267,7 @@ def lin_matrix(self, length=None): INPUT: - - ``length`` -- length of state space (default: ``None``) - + - ``length`` -- length of state space (default: ``None``) EXAMPLES:: @@ -2420,13 +2390,11 @@ def inversion_polynomials(self, xi, wi, length): INPUT: + - ``xi`` -- output variables - - ``xi`` -- output variables - - - ``wi`` -- input variables - - - ``length`` -- length of both lists + - ``wi`` -- input variables + - ``length`` -- length of both lists EXAMPLES:: @@ -2453,9 +2421,9 @@ def field_polynomials(self, name, i, l=None): INPUT: - - ``name`` -- variable name - - ``i`` -- round number - - ``l`` -- r\*c (default: ``None``) + - ``name`` -- variable name + - ``i`` -- round number + - ``l`` -- r\*c (default: ``None``) EXAMPLES:: @@ -2478,7 +2446,8 @@ def field_polynomials(self, name, i, l=None): l = r*c _vars = self.vars(name, i, l, e) - return [_vars[e*j+k]**2 - _vars[e*j+(k+1) % e] for j in range(l) for k in range(e)] + return [_vars[e*j+k]**2 - _vars[e*j+(k+1) % e] for j in range(l) for k in range(e)] + class SR_gf2(SR_generic): def __init__(self, n=1, r=1, c=1, e=4, star=False, **kwargs): @@ -2498,13 +2467,12 @@ def __init__(self, n=1, r=1, c=1, e=4, star=False, **kwargs): def vector(self, d=None): """ - Constructs a vector suitable for the algebraic representation of + Construct a vector suitable for the algebraic representation of SR. INPUT: - - ``d`` -- values for vector (default: ``None``) - + - ``d`` -- values for vector (default: ``None``) EXAMPLES:: @@ -2548,9 +2516,7 @@ def is_vector(self, d): INPUT: - - - ``d`` -- matrix - + - ``d`` -- matrix EXAMPLES:: @@ -2572,14 +2538,14 @@ def is_vector(self, d): def phi(self, l, diffusion_matrix=False): r""" - The operation `\phi` from [MR2002]_ + The operation `\phi` from [MR2002]_. Given a list/matrix of elements in `\GF{2^e}`, return a matching list/matrix of elements in `\GF{2}`. INPUT: - - ``l`` -- element to perform `\phi` on. + - ``l`` -- element to perform `\phi` on - ``diffusion_matrix`` -- if ``True``, the given matrix ``l`` is transformed to a matrix which performs the same operation over `\GF{2}` as ``l`` over `\GF{2^n}` (default: ``False``). @@ -2740,8 +2706,7 @@ def lin_matrix(self, length=None): INPUT: - - ``length`` -- length of state space (default: ``None``) - + - ``length`` -- length of state space (default: ``None``) EXAMPLES:: @@ -2788,9 +2753,7 @@ def _mul_matrix(self, x): INPUT: - - - ``x`` -- an element in self.base_ring() - + - ``x`` -- an element in self.base_ring() EXAMPLES:: @@ -3135,13 +3098,11 @@ def inversion_polynomials(self, xi, wi, length): INPUT: + - ``xi`` -- output variables - - ``xi`` -- output variables - - - ``wi`` -- input variables - - - ``length`` -- length of both lists + - ``wi`` -- input variables + - ``length`` -- length of both lists EXAMPLES:: @@ -3171,9 +3132,9 @@ def field_polynomials(self, name, i, l=None): INPUT: - - ``name`` -- variable name - - ``i`` -- round number - - ``l`` -- length of variable list (default: ``None`` = r\*c) + - ``name`` -- variable name + - ``i`` -- round number + - ``l`` -- length of variable list (default: ``None`` = r\*c) EXAMPLES:: @@ -3200,7 +3161,8 @@ def field_polynomials(self, name, i, l=None): if self._polybori: return [] _vars = self.vars(name, i, l, e) - return [_vars[e*j+k]**2 - _vars[e*j+k] for j in range(l) for k in range(e)] + return [_vars[e*j+k]**2 - _vars[e*j+k] for j in range(l) for k in range(e)] + class SR_gf2_2(SR_gf2): """ @@ -3219,7 +3181,7 @@ def inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, - ``w`` -- input variables (default: ``None``) - ``biaffine_only`` -- ignored (always ``False``) - ``correct_only`` -- ignored (always ``True``) - - ``groebner`` -- precompute the Groebner basis for this S-Box (default: ``False``). + - ``groebner`` -- precompute the Groebner basis for this S-Box (default: ``False``) EXAMPLES:: @@ -3273,7 +3235,6 @@ def inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, sage: l = sr.inversion_polynomials_single_sbox() # needs sage.libs.singular sage: l == sr.inversion_polynomials_single_sbox(biaffine_only=True, correct_only=False) # needs sage.libs.singular True - """ e = self.e if x is None and w is None: @@ -3287,6 +3248,7 @@ def inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, F = S.polynomials(w, x, degree=e-2, groebner=groebner) return F + class AllowZeroInversionsContext: """ Temporarily allow zero inversion. @@ -3335,6 +3297,7 @@ def __exit__(self, typ, value, tb): """ self.sr._allow_zero_inversions = self.allow_zero_inversions + def test_consistency(max_n=2, **kwargs): r""" Test all combinations of ``r``, ``c``, ``e`` and ``n`` in ``(1, diff --git a/src/sage/crypto/public_key/blum_goldwasser.py b/src/sage/crypto/public_key/blum_goldwasser.py index 1d090673400..cf09d4038c8 100644 --- a/src/sage/crypto/public_key/blum_goldwasser.py +++ b/src/sage/crypto/public_key/blum_goldwasser.py @@ -44,6 +44,7 @@ floor = Function_floor() IntegerModRing = IntegerModFactory("IntegerModRing") + class BlumGoldwasser(PublicKeyCryptosystem): r""" The Blum-Goldwasser probabilistic public-key encryption scheme. @@ -162,12 +163,10 @@ def __eq__(self, other): INPUT: - - ``other`` -- a ``BlumGoldwasser`` object. - - OUTPUT: + - ``other`` -- a ``BlumGoldwasser`` object - - ``True`` if both ``self`` and ``other`` are ``BlumGoldwasser`` - objects. ``False`` otherwise. + OUTPUT: ``True`` if both ``self`` and ``other`` are ``BlumGoldwasser`` + objects; ``False`` otherwise Two objects are ``BlumGoldwasser`` objects if their string representations are the same. @@ -214,7 +213,7 @@ def decrypt(self, C, K): `t+1`-th iteration of the Blum-Blum-Shub algorithm. - ``K`` -- a private key `(p, q, a, b)` where `p` and `q` are - distinct Blum primes and `\gcd(p, q) = ap + bq = 1`. + distinct Blum primes and `\gcd(p, q) = ap + bq = 1` OUTPUT: @@ -361,7 +360,7 @@ def encrypt(self, P, K, seed=None): a string of ASCII characters. Where ``P`` is an ASCII string, then ``P`` is first encoded as a binary string prior to encryption. - - ``K`` -- a public key, which is the product of two Blum primes. + - ``K`` -- a public key, which is the product of two Blum primes - ``seed`` -- (default: ``None``) if `p` and `q` are Blum primes and `n = pq` is a public key, then ``seed`` is a quadratic residue in @@ -537,14 +536,12 @@ def private_key(self, p, q): INPUT: - - ``p`` -- a Blum prime. - - - ``q`` -- a Blum prime. + - ``p`` -- a Blum prime - OUTPUT: + - ``q`` -- a Blum prime - - The Blum-Goldwasser private key `(p, q, a, b)` where - `\gcd(p, q) = ap + bq = 1`. + OUTPUT: the Blum-Goldwasser private key `(p, q, a, b)` where + `\gcd(p, q) = ap + bq = 1` Both ``p`` and ``q`` must be distinct Blum primes. Let `p` be a positive prime. Then `p` is a Blum prime if `p` is congruent to 3 @@ -613,13 +610,11 @@ def public_key(self, p, q): INPUT: - - ``p`` -- a Blum prime. + - ``p`` -- a Blum prime - - ``q`` -- a Blum prime. - - OUTPUT: + - ``q`` -- a Blum prime - - The Blum-Goldwasser public key `n = pq`. + OUTPUT: the Blum-Goldwasser public key `n = pq` Both ``p`` and ``q`` must be distinct Blum primes. Let `p` be a positive prime. Then `p` is a Blum prime if `p` is congruent to 3 diff --git a/src/sage/crypto/sbox.pyx b/src/sage/crypto/sbox.pyx index eb4388efd79..30b7a3cd8c9 100644 --- a/src/sage/crypto/sbox.pyx +++ b/src/sage/crypto/sbox.pyx @@ -129,7 +129,7 @@ cdef class SBox(SageObject): - ``S`` -- a finite iterable defining the S-box with integer or finite field elements - - ``big_endian`` -- (default: ``True``) controls whether bits + - ``big_endian`` -- boolean (default: ``True``); controls whether bits shall be ordered in big endian order EXAMPLES: @@ -275,7 +275,7 @@ cdef class SBox(SageObject): INPUT: - - ``x`` -- an integer + - ``x`` -- integer - ``n`` -- bit length (optional) @@ -417,7 +417,7 @@ cdef class SBox(SageObject): sage: all([x == id(x) for x in k]) True - Some examples for inputs that throw an :class:`TypeError`:: + Some examples for inputs that throw an :exc:`TypeError`:: sage: S([1]*10^6) Traceback (most recent call last): @@ -445,7 +445,6 @@ cdef class SBox(SageObject): return K(self._S_list[ X]) except TypeError: raise TypeError("cannot apply SBox to %s" % (X,)) - raise TypeError("the characteristic of the base field must be 2") V = None try: V = K.vector_space(map=False) @@ -563,7 +562,7 @@ cdef class SBox(SageObject): def derivative(self, u): r""" - Return the derivative in direction of ``u`` + Return the derivative in direction of ``u``. INPUT: @@ -746,7 +745,7 @@ cdef class SBox(SageObject): return self.maximal_difference_probability_absolute() / (2.0**self.output_size()) @cached_method - def linear_approximation_table(self, scale="absolute_bias"): + def linear_approximation_table(self, scale='absolute_bias'): r""" Return linear approximation table (LAT) `A` for this S-box. @@ -791,13 +790,13 @@ cdef class SBox(SageObject): [ 0 -2 -2 0 0 -2 2 0] [ 0 -2 2 0 -2 0 0 -2] - sage: lat_abs_bias/(1 << S.input_size()) == S.linear_approximation_table(scale="bias") + sage: lat_abs_bias/(1 << S.input_size()) == S.linear_approximation_table(scale='bias') True - sage: lat_abs_bias/(1 << (S.input_size()-1)) == S.linear_approximation_table(scale="correlation") + sage: lat_abs_bias/(1 << (S.input_size()-1)) == S.linear_approximation_table(scale='correlation') True - sage: lat_abs_bias*2 == S.linear_approximation_table(scale="fourier_coefficient") + sage: lat_abs_bias*2 == S.linear_approximation_table(scale='fourier_coefficient') True According to this table the first bit of the input is equal @@ -946,8 +945,8 @@ cdef class SBox(SageObject): - ``degree`` -- (default: ``2``) integer > 0 - - ``groebner`` -- (default: ``False``) calculate a reduced Groebner - basis of the spanning polynomials to obtain more polynomials + - ``groebner`` -- boolean (default: ``False``); calculate a reduced + Groebner basis of the spanning polynomials to obtain more polynomials EXAMPLES:: @@ -1063,7 +1062,7 @@ cdef class SBox(SageObject): field is of degree ``m``. If the output length does not match the input length then a - :class:`TypeError` is raised. + :exc:`TypeError` is raised. INPUT: @@ -1133,13 +1132,13 @@ cdef class SBox(SageObject): represents a variable and the sign of an integer indicates inversion - - ``symbolic`` -- a string that can be parsed by the + - ``symbolic`` -- string that can be parsed by the ``SymbolicLogic`` package - - ``dimacs`` -- a string in DIMACS format which is the gold + - ``dimacs`` -- string in DIMACS format which is the gold standard for SAT-solver input (cf. http://www.satlib.org/) - - ``dimacs_headless`` -- a string in DIMACS format, but without + - ``dimacs_headless`` -- string in DIMACS format, but without the header; this is useful for concatenation of outputs EXAMPLES: @@ -1326,6 +1325,13 @@ cdef class SBox(SageObject): sage: f5 = S.component_function([1, 0, 1]) sage: f5.algebraic_normal_form() # needs sage.rings.polynomial.pbori x0*x2 + x0 + x1*x2 + + TESTS:: + + sage: from sage.crypto.sboxes import SBox + sage: sb = SBox([0, 1, 2, 3, 0, 1, 2, 3]) + sage: sb.component_function([1, 0]) + Boolean function with 3 variables """ cdef Py_ssize_t m = self.m cdef Py_ssize_t n = self.n @@ -1334,7 +1340,7 @@ cdef class SBox(SageObject): b = list(b) if len(b) > n: raise ValueError("input (%s) is too long and would be truncated" % (b,)) - b = self.from_bits(b) + b = self.from_bits(b, n) except TypeError: try: b = ZZ(b) @@ -1583,7 +1589,7 @@ cdef class SBox(SageObject): def boomerang_uniformity(self): """ - Return the boomerang uniformity + Return the boomerang uniformity. The boomerang uniformity is defined as the highest entry in the boomerang connectivity table, ignoring the first row and column. @@ -1797,7 +1803,7 @@ cdef class SBox(SageObject): Return the inverse of this S-Box. Note that the S-Box must be invertible, otherwise it will raise - a :class:`TypeError`. + a :exc:`TypeError`. EXAMPLES:: diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index 749593c401b..ab0f2759573 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -93,7 +93,7 @@ - SERPENT_S0, ..., SERPENT_S7 ([BAK1998]_) - KLEIN ([GNL2011]_) - MIBS ([ISSK2009)] - - Midori_Sb0 (MANTIS, CRAFT), Midori_Sb1 ([BBISHAR2015]_) + - Midori_Sb0 (MANTIS, CRAFT, WARP), Midori_Sb1 ([BBISHAR2015]_) - Noekeon ([DPVAR2000]_) - Piccolo ([SIHMAS2011]_) - Panda ([YWHWXSW2014]_) @@ -203,11 +203,12 @@ def carlet_tang_tang_liao(n, c=None, bf=None): INPUT: - - ``n`` -- integer, the bit length of inputs and outputs, has to be even and >= 6 + - ``n`` -- integer; the bit length of inputs and outputs, has to be even + and `\geq 6` - ``c`` -- element of `\GF{2^{n-1}}` used in the construction - (default: random element) - - ``f`` -- Function from `\GF{2^n} \to \GF{2}` or BooleanFunction on `n-1` bits - (default: ``x -> (1/(x+1)).trace())`` + (default: random element) + - ``f`` -- function from `\GF{2^n} \to \GF{2}` or BooleanFunction on `n-1` + bits (default: ``x -> (1/(x+1)).trace())``) EXAMPLES:: @@ -270,7 +271,7 @@ def gold(n, i): INPUT: - ``n`` -- size of the S-Box - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: @@ -293,7 +294,7 @@ def kasami(n, i): INPUT: - ``n`` -- size of the S-Box - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: @@ -1574,6 +1575,7 @@ def monomial_function(n, e): MIBS = SBox([4,15,3,8,13,10,12,0,11,5,7,14,2,6,1,9]) Midori_Sb0 = SBox([0xc,0xa,0xd,0x3,0xe,0xb,0xf,0x7,0x8,0x9,0x1,0x5,0x0,0x2,0x4,0x6]) MANTIS = Midori_Sb0 +WARP = Midori_Sb0 CRAFT = Midori_Sb0 Midori_Sb1 = SBox([0x1,0x0,0x5,0x3,0xe,0x2,0xf,0x7,0xd,0xa,0x9,0xb,0xc,0x8,0x4,0x6]) Noekeon = SBox([0x7,0xA,0x2,0xC,0x4,0x8,0xF,0x0,0x5,0x9,0x1,0xE,0x3,0xD,0xB,0x6]) diff --git a/src/sage/crypto/stream.py b/src/sage/crypto/stream.py index 636f588ad97..a9e94d63b24 100644 --- a/src/sage/crypto/stream.py +++ b/src/sage/crypto/stream.py @@ -25,6 +25,7 @@ IntegerModRing = IntegerModFactory("IntegerModRing") + class LFSRCryptosystem(SymmetricKeyCryptosystem): """ Linear feedback shift register cryptosystem class @@ -33,9 +34,9 @@ def __init__(self, field=None): """ Create a linear feedback shift cryptosystem. - INPUT: A string monoid over a binary alphabet. + INPUT: - OUTPUT: + - ``field`` -- (default: ``None``) string monoid over a binary alphabet EXAMPLES:: @@ -68,7 +69,9 @@ def __call__(self, key): """ Create a LFSR cipher. - INPUT: A polynomial and initial state of the LFSR. + INPUT: + + - ``key`` -- a polynomial and initial state of the LFSR """ if not isinstance(key, (list, tuple)) and len(key) == 2: raise TypeError("Argument key (= %s) must be a list of tuple of length 2" % key) @@ -99,6 +102,7 @@ def encoding(self,M): except Exception: raise TypeError("Argument M = %s does not encode in the cipher domain" % M) + class ShrinkingGeneratorCryptosystem(SymmetricKeyCryptosystem): """ Shrinking generator cryptosystem class @@ -107,9 +111,9 @@ def __init__(self, field=None): """ Create a shrinking generator cryptosystem. - INPUT: A string monoid over a binary alphabet. + INPUT: - OUTPUT: + - ``field`` -- (default: ``None``) string monoid over a binary alphabet EXAMPLES:: @@ -129,10 +133,12 @@ def __call__(self, key): """ Create a Shrinking generator cipher. - INPUT: A list or tuple consisting of two LFSR ciphers (e1,e2). + INPUT: - OUTPUT: The shrinking generator cipher with key stream generator e1 - and decimating cipher e2. + - ``key`` -- list or tuple consisting of two LFSR ciphers (e1,e2) + + OUTPUT: the shrinking generator cipher with key stream generator e1 + and decimating cipher e2 """ if not isinstance(key, (list, tuple)) and len(key) == 2: raise TypeError("Argument key (= %s) must be a list of tuple of length 2" % key) @@ -161,6 +167,7 @@ def encoding(self,M): except Exception: raise TypeError("Argument M = %s does not encode in the cipher domain" % M) + def blum_blum_shub(length, seed=None, p=None, q=None, lbound=None, ubound=None, ntries=100): r""" @@ -172,7 +179,7 @@ def blum_blum_shub(length, seed=None, p=None, q=None, INPUT: - ``length`` -- positive integer; the number of bits in the output - pseudorandom bit sequence. + pseudorandom bit sequence - ``seed`` -- (default: ``None``) if `p` and `q` are Blum primes, then ``seed`` is a quadratic residue in the multiplicative group @@ -207,9 +214,7 @@ def blum_blum_shub(length, seed=None, p=None, q=None, perform that many attempts at generating a random Blum prime. This might or might not result in a Blum prime. - OUTPUT: - - - A pseudorandom bit sequence whose length is specified by ``length``. + OUTPUT: a pseudorandom bit sequence whose length is specified by ``length`` Here is a common use case for this function. If you want this function to use pre-computed values for `p` and `q`, you should pass diff --git a/src/sage/crypto/stream_cipher.py b/src/sage/crypto/stream_cipher.py index ab9d2dfc815..4b6d36ad925 100644 --- a/src/sage/crypto/stream_cipher.py +++ b/src/sage/crypto/stream_cipher.py @@ -14,6 +14,7 @@ from .cipher import SymmetricKeyCipher from sage.monoids.string_monoid_element import StringMonoidElement + class LFSRCipher(SymmetricKeyCipher): def __init__(self, parent, poly, IS): """ @@ -21,13 +22,11 @@ def __init__(self, parent, poly, IS): INPUT: + - ``parent`` -- parent - - ``parent`` -- parent - - - ``poly`` -- connection polynomial - - - ``IS`` -- initial state + - ``poly`` -- connection polynomial + - ``IS`` -- initial state EXAMPLES:: @@ -64,17 +63,15 @@ def __init__(self, parent, poly, IS): """ SymmetricKeyCipher.__init__(self, parent, key=(poly, IS)) - def __call__(self, M, mode="ECB"): + def __call__(self, M, mode='ECB'): r""" Generate key stream from the binary string ``M``. INPUT: + - ``M`` -- a StringMonoidElement - - ``M`` -- a StringMonoidElement - - - ``mode`` -- ignored (default: 'ECB') - + - ``mode`` -- ignored (default: ``'ECB'``) EXAMPLES:: @@ -147,6 +144,7 @@ def initial_state(self): """ return self.key()[1] + class ShrinkingGeneratorCipher(SymmetricKeyCipher): def __init__(self, parent, e1, e2): """ @@ -154,13 +152,11 @@ def __init__(self, parent, e1, e2): INPUT: + - ``parent`` -- parent - - ``parent`` -- parent - - - ``poly`` -- connection polynomial - - - ``IS`` -- initial state + - ``poly`` -- connection polynomial + - ``IS`` -- initial state EXAMPLES:: @@ -222,15 +218,13 @@ def decimating_cipher(self): """ return self.key()[1] - def __call__(self, M, mode="ECB"): + def __call__(self, M, mode='ECB'): r""" INPUT: + - ``M`` -- a StringMonoidElement - - ``M`` -- a StringMonoidElement - - - ``mode`` -- ignored (default: 'ECB') - + - ``mode`` -- ignored (default: ``'ECB'``) EXAMPLES:: diff --git a/src/sage/crypto/util.py b/src/sage/crypto/util.py index 8590c83db5c..66ffb78ef2b 100644 --- a/src/sage/crypto/util.py +++ b/src/sage/crypto/util.py @@ -38,11 +38,9 @@ def ascii_integer(B): INPUT: - ``B`` -- a non-empty binary string or a non-empty list of bits. The - number of bits in ``B`` must be 8. + number of bits in ``B`` must be 8 - OUTPUT: - - - The ASCII integer corresponding to the 8-bit block ``B``. + OUTPUT: the ASCII integer corresponding to the 8-bit block ``B`` EXAMPLES: @@ -95,17 +93,16 @@ def ascii_integer(B): return sum([L[7], L[6]*2, L[5]*4, L[4]*8, L[3]*16, L[2]*32, L[1]*64, L[0]*128]) + def ascii_to_bin(A): r""" Return the binary representation of the ASCII string ``A``. INPUT: - - ``A`` -- a string or list of ASCII characters. - - OUTPUT: + - ``A`` -- string or list of ASCII characters - - The binary representation of ``A``. + OUTPUT: the binary representation of ``A`` ALGORITHM: @@ -163,6 +160,7 @@ def ascii_to_bin(A): bin = BinaryStrings() return bin.encoding("".join(list(A))) + def bin_to_ascii(B): r""" Return the ASCII representation of the binary string ``B``. @@ -170,11 +168,9 @@ def bin_to_ascii(B): INPUT: - ``B`` -- a non-empty binary string or a non-empty list of bits. The - number of bits in ``B`` must be a multiple of 8. - - OUTPUT: + number of bits in ``B`` must be a multiple of 8 - - The ASCII string corresponding to ``B``. + OUTPUT: the ASCII string corresponding to ``B`` ALGORITHM: @@ -353,17 +349,16 @@ def has_blum_prime(lbound, ubound): return True return False + def is_blum_prime(n): r""" Determine whether or not ``n`` is a Blum prime. INPUT: - - ``n`` a positive prime. - - OUTPUT: + - ``n`` -- a positive prime - - ``True`` if ``n`` is a Blum prime; ``False`` otherwise. + OUTPUT: ``True`` if ``n`` is a Blum prime; ``False`` otherwise Let `n` be a positive prime. Then `n` is a Blum prime if `n` is congruent to 3 modulo 4, i.e. `n \equiv 3 \pmod{4}`. @@ -392,15 +387,16 @@ def is_blum_prime(n): else: return False + def least_significant_bits(n, k): r""" Return the ``k`` least significant bits of ``n``. INPUT: - - ``n`` -- an integer. + - ``n`` -- integer - - ``k`` -- a positive integer. + - ``k`` -- positive integer OUTPUT: @@ -446,6 +442,7 @@ def least_significant_bits(n, k): """ return [int(_) for _ in list(n.binary()[-k:])] + def random_blum_prime(lbound, ubound, ntries=100): r""" A random Blum prime within the specified bounds. @@ -470,9 +467,7 @@ def random_blum_prime(lbound, ubound, ntries=100): perform that many attempts at generating a random Blum prime. This might or might not result in a Blum prime. - OUTPUT: - - - A random Blum prime within the specified lower and upper bounds. + OUTPUT: a random Blum prime within the specified lower and upper bounds .. NOTE:: diff --git a/src/sage/data_structures/binary_matrix.pxd b/src/sage/data_structures/binary_matrix.pxd index 8827a6a3f66..ce69e036ad2 100644 --- a/src/sage/data_structures/binary_matrix.pxd +++ b/src/sage/data_structures/binary_matrix.pxd @@ -12,7 +12,7 @@ A ``binary_matrix_t`` structure contains: - ``mp_bitcnt_t n_rows`` -- number of rows - ``bitset_t * rows`` -- ``rows[i]`` points toward a block of type ``bitset_t`` - containing the bits of row `i`. + containing the bits of row `i` """ from sage.data_structures.bitset_base cimport * diff --git a/src/sage/data_structures/bitset.pyx b/src/sage/data_structures/bitset.pyx index 9d5e2029407..973102fc2a6 100644 --- a/src/sage/data_structures/bitset.pyx +++ b/src/sage/data_structures/bitset.pyx @@ -62,28 +62,26 @@ cdef class FrozenBitset: INPUT: - - ``iter`` -- initialization parameter (default: ``None``). Valid input + - ``iter`` -- initialization parameter (default: ``None``); valid inputs are: - :class:`Bitset` and :class:`FrozenBitset` -- If this is a - :class:`Bitset` or :class:`FrozenBitset`, then it is copied. + :class:`Bitset` or :class:`FrozenBitset`, then it is copied - - ``None`` -- If ``None``, then the bitset is set to the empty set. + - ``None`` -- if ``None``, then the bitset is set to the empty set - - string -- If a nonempty string, then the bitset is initialized by + - ``string`` -- if a nonempty string, then the bitset is initialized by including an element if the index of the string is ``1``. If the - string is empty, then raise a :class:`ValueError`. + string is empty, then raise a :exc:`ValueError`. - - iterable -- If an iterable, then it is assumed to contain a list of - nonnegative integers and those integers are placed in the set. + - ``iterable`` -- if an iterable, then it is assumed to contain a list of + nonnegative integers and those integers are placed in the set - - ``capacity`` -- (default: ``None``) The maximum capacity of the bitset. + - ``capacity`` -- (default: ``None``) the maximum capacity of the bitset. If this is not specified, then it is automatically calculated from the passed iterable. It must be at least one. - OUTPUT: - - - None. + OUTPUT: none The string representation of a :class:`FrozenBitset` ``FB`` can be understood as follows. Let `B = b_0 b_1 b_2 \cdots b_k` be the string @@ -560,13 +558,7 @@ cdef class FrozenBitset: """ Test if the bitset is empty. - INPUT: - - - None. - - OUTPUT: - - - ``True`` if the bitset is empty; ``False`` otherwise. + OUTPUT: boolean EXAMPLES:: @@ -1184,7 +1176,7 @@ cdef class FrozenBitset: cpdef complement(self): """ - Return the complement of self. + Return the complement of ``self``. EXAMPLES:: @@ -1208,7 +1200,7 @@ cdef class FrozenBitset: def __invert__(self): """ - Return the complement of self. + Return the complement of ``self``. EXAMPLES:: @@ -1799,7 +1791,7 @@ cdef class Bitset(FrozenBitset): """ Update the bitset by removing ``n``. - This raises a :class:`KeyError` if ``n`` is not contained + This raises a :exc:`KeyError` if ``n`` is not contained in the bitset. EXAMPLES:: @@ -1874,7 +1866,7 @@ cdef class Bitset(FrozenBitset): """ Remove and return an arbitrary element from the set. - This raises a :class:`KeyError` if the set is empty. + This raises a :exc:`KeyError` if the set is empty. EXAMPLES:: @@ -2121,7 +2113,6 @@ def test_bitset(py_a, py_b, long n): to size 69 111001111001111001111001111001111001111001111001111001111001111001111 to size 138 111001111001111001111001111001111001111001111001111001111001111001111000000000000000000000000000000000000000000000000000000000000000000000 to original size 111001111001111001111001111001111001111001111001111001111001111001111000000000000000000000000000000000000000000000000000000000000000000000000000000000 - """ cdef bint bit = True cdef bitset_t a, b, r @@ -2279,7 +2270,6 @@ def test_bitset_set_first_n(py_a, long n): sage: from sage.data_structures.bitset import test_bitset_set_first_n sage: test_bitset_set_first_n('00'*64, 128) a.set_first_n(n) 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 - """ cdef bint bit = True cdef bitset_t a @@ -2324,7 +2314,7 @@ def test_bitset_remove(py_a, long n): def test_bitset_pop(py_a): """ - Tests for the bitset_pop function. + Test for the bitset_pop function. TESTS:: @@ -2351,11 +2341,10 @@ def test_bitset_unpickle(data): INPUT: - - ``data`` -- A tuple of data as would be produced by the internal, Cython-only, method ``bitset_pickle``. - - OUTPUT: + - ``data`` -- tuple of data as would be produced by the internal, + Cython-only, method ``bitset_pickle`` - A list form of the bitset corresponding to the pickled data. + OUTPUT: list form of the bitset corresponding to the pickled data EXAMPLES: diff --git a/src/sage/data_structures/bitset_base.pxd b/src/sage/data_structures/bitset_base.pxd index f8949d05e78..b2fb299dd9c 100644 --- a/src/sage/data_structures/bitset_base.pxd +++ b/src/sage/data_structures/bitset_base.pxd @@ -274,7 +274,7 @@ cdef inline void bitset_fix(fused_bitset_t bits) noexcept: cdef inline void sparse_bitset_set_non_zero(sparse_bitset_t bits) noexcept nogil: """ - Set the non zero chunks of ``bits``. + Set the nonzero chunks of ``bits``. """ bits.n_non_zero_chunks = _set_non_zero(bits.bits, bits.non_zero_chunks, bits.limbs) bits.non_zero_chunks_are_initialized = True @@ -331,15 +331,15 @@ cdef inline bint mpn_equal_bits_shifted(mp_srcptr b1, mp_srcptr b2, mp_bitcnt_t cdef inline bint bitset_isempty(fused_bitset_t bits) noexcept nogil: """ - Test whether bits is empty. Return True (i.e., 1) if the set is - empty, False (i.e., 0) otherwise. + Test whether bits is empty. Return ``True`` (i.e., 1) if the set is + empty, ``False`` (i.e., 0) otherwise. """ return _bitset_isempty(bits.bits, bits.limbs) cdef inline bint bitset_is_zero(fused_bitset_t bits) noexcept: """ - Test whether bits is empty (i.e., zero). Return True (1) if - the set is empty, False (0) otherwise. + Test whether bits is empty (i.e., zero). Return ``True`` (1) if + the set is empty, ``False`` (0) otherwise. This function is the same as bitset_is_empty(bits). """ @@ -347,8 +347,8 @@ cdef inline bint bitset_is_zero(fused_bitset_t bits) noexcept: cdef inline bint bitset_eq(fused_bitset_t a, fused_bitset_t b) noexcept: """ - Compare bitset a and b. Return True (i.e., 1) if the sets are - equal, and False (i.e., 0) otherwise. + Compare bitset a and b. Return ``True`` (i.e., 1) if the sets are + equal, and ``False`` (i.e., 0) otherwise. We assume ``a.limbs >= b.limbs``. """ @@ -378,7 +378,7 @@ cdef inline int bitset_lex_cmp(fused_bitset_t a, fused_bitset_t b) noexcept: INPUT: - ``a`` -- a bitset - - ``b`` -- a bitset, assumed to have the same size as ``a``. + - ``b`` -- a bitset, assumed to have the same size as ``a`` OUTPUT: @@ -416,7 +416,7 @@ cdef inline bint bitset_issuperset(fused_bitset_t a, fused_bitset_t b) noexcept cdef inline bint bitset_are_disjoint(fused_bitset_t a, fused_bitset_t b) noexcept: """ - Tests whether ``a`` and ``b`` have an empty intersection. + Test whether ``a`` and ``b`` have an empty intersection. We assume ``a.limbs <= b.limbs``. """ @@ -432,15 +432,15 @@ cdef inline bint bitset_are_disjoint(fused_bitset_t a, fused_bitset_t b) noexcep cdef inline bint bitset_in(fused_bitset_t bits, mp_bitcnt_t n) noexcept: """ - Check if n is in bits. Return True (i.e., 1) if n is in the - set, False (i.e., 0) otherwise. + Check if n is in bits. Return ``True`` (i.e., 1) if n is in the + set, ``False`` (i.e., 0) otherwise. """ return (bits.bits[n >> index_shift] >> (n % GMP_LIMB_BITS)) & 1 cdef inline bint bitset_check(fused_bitset_t bits, mp_bitcnt_t n) noexcept: """ - Check if n is in bits. Return True (i.e., 1) if n is in the - set, False (i.e., 0) otherwise. + Check if n is in bits. Return ``True`` (i.e., 1) if n is in the + set, ``False`` (i.e., 0) otherwise. This function is the same as bitset_in(bits, n). """ @@ -448,8 +448,8 @@ cdef inline bint bitset_check(fused_bitset_t bits, mp_bitcnt_t n) noexcept: cdef inline bint bitset_not_in(fused_bitset_t bits, mp_bitcnt_t n) noexcept: """ - Check if n is not in bits. Return True (i.e., 1) if n is not in the - set, False (i.e., 0) otherwise. + Check if n is not in bits. Return ``True`` (i.e., 1) if n is not in the + set, ``False`` (i.e., 0) otherwise. """ return not bitset_in(bits, n) @@ -457,7 +457,7 @@ cdef inline bint bitset_remove(fused_bitset_t bits, mp_bitcnt_t n) except -1: """ Remove ``n`` from ``bits``. - This raises a :class:`KeyError` if ``n`` is not contained in ``bits``. + This raises a :exc:`KeyError` if ``n`` is not contained in ``bits``. """ if not bitset_in(bits, n): raise KeyError(n) @@ -562,7 +562,7 @@ cdef inline long bitset_pop(fused_bitset_t a) except -1: """ Remove and return an arbitrary element from the set. - This raises a :class:`KeyError` if the set is empty. + This raises a :exc:`KeyError` if the set is empty. """ cdef long i = bitset_first(a) if i == -1: @@ -681,7 +681,7 @@ cdef inline void sparse_bitset_intersection(sparse_bitset_t r, fused_bitset_t a, """ Set r to the intersection of a and b, overwriting r. - Also set the non zero positions of ``r``. + Also set the nonzero positions of ``r``. We assume ``a.limbs >= r.limbs == b.limbs``. """ @@ -713,7 +713,7 @@ cdef inline void sparse_bitset_union(sparse_bitset_t r, fused_bitset_t a, fused_ """ Set r to the union of a and b, overwriting r. - Also set the non zero positions of ``r``. + Also set the nonzero positions of ``r``. We assume ``r.limbs >= a.limbs >= b.limbs`` and either ``r is a`` or ``r.limbs == b.limbs``. @@ -749,7 +749,7 @@ cdef inline void sparse_bitset_difference(sparse_bitset_t r, fused_bitset_t a, f Set r to the difference of a and b (i.e., things in a that are not in b), overwriting r. - Also set the non zero positions of ``r``. + Also set the nonzero positions of ``r``. We assume ``r.limbs >= a.limbs >= b.limbs`` and either ``r is a`` or ``r.limbs == b.limbs``. @@ -772,7 +772,7 @@ cdef inline void sparse_bitset_symmetric_difference(sparse_bitset_t r, fused_bit """ Set r to the symmetric difference of a and b, overwriting r. - Also set the non zero positions of ``r``. + Also set the nonzero positions of ``r``. We assume ``r.limbs >= a.limbs >= b.limbs`` and either ``r is a`` or ``r.limbs == b.limbs``. diff --git a/src/sage/data_structures/bitset_intrinsics.h b/src/sage/data_structures/bitset_intrinsics.h index 2e4dd228952..ce9c0f9889d 100644 --- a/src/sage/data_structures/bitset_intrinsics.h +++ b/src/sage/data_structures/bitset_intrinsics.h @@ -246,7 +246,7 @@ static inline int _sparse_bitset_cmp(mp_limb_t* a, mp_bitcnt_t* a_non_zero_chunk static inline long _bitset_first_in_limb_nonzero(mp_limb_t limb){ /* - Given a non-zero limb of a bitset, return the index of the first + Given a nonzero limb of a bitset, return the index of the first nonzero bit. */ #if (__BMI__) && (GMP_LIMB_BITS == 64) && (INTPTR_MAX == INT64_MAX) diff --git a/src/sage/data_structures/blas_dict.pyx b/src/sage/data_structures/blas_dict.pyx index 359ece0690d..baa27e54c22 100644 --- a/src/sage/data_structures/blas_dict.pyx +++ b/src/sage/data_structures/blas_dict.pyx @@ -19,7 +19,7 @@ meaningful in those cases. We are also assuming that ``-1 * x = -x`` and ``bool(x) == bool(-x)`` for all ``x`` in `K`. Unless stated overwise, all values `v` in the dictionaries should be -non zero (as tested with `bool(v)`). +nonzero (as tested with `bool(v)`). This is mostly used by :class:`CombinatorialFreeModule`. """ @@ -208,7 +208,7 @@ cpdef dict negate(dict D): INPUT: - - ``X`` -- a dictionary representing a vector `X` + - ``X`` -- dictionary representing a vector `X` EXAMPLES:: @@ -226,7 +226,7 @@ cpdef dict scal(a, dict D, bint factor_on_left=True): INPUT: - ``a`` -- an element of the base ring `K` - - ``X`` -- a dictionary representing a vector `X` + - ``X`` -- dictionary representing a vector `X` EXAMPLES:: @@ -248,7 +248,7 @@ cpdef dict add(dict D, dict D2): INPUT: - ``D``, ``D2`` -- dictionaries whose values are in a common ring - and all values are non-zero + and all values are nonzero EXAMPLES:: @@ -275,7 +275,7 @@ cpdef dict sum(dict_iter): INPUT: - ``dict_iter`` -- iterator of dictionaries whose values are in - a common ring and all values are non-zero + a common ring and all values are nonzero OUTPUT: @@ -360,7 +360,7 @@ cpdef dict sum_of_monomials(monomials, scalar): INPUT: - - ``monomials`` -- a list (or iterable) of indices representing the monomials + - ``monomials`` -- list (or iterable) of indices representing the monomials - ``scalar`` -- the scalar for each monomial EXAMPLES:: @@ -388,7 +388,7 @@ cpdef dict sum_of_terms(index_coeff_pairs): INPUT: - - ``index_coeff_pairs`` -- a list (or iterable) of pairs ``(index, coeff)`` + - ``index_coeff_pairs`` -- list (or iterable) of pairs ``(index, coeff)`` EXAMPLES:: diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index c87fc914921..ed30b915d14 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -1,7 +1,7 @@ from sage.libs.gmp.types cimport * from sage.data_structures.bitset cimport * -# A biseq (bounded integer sequence) is a sequence of non-negative +# A biseq (bounded integer sequence) is a sequence of nonnegative # integers, each fitting in "itembitsize" bits. We store the sequence # in a bitset of length at least length*itembitsize. ctypedef struct biseq_s: @@ -21,7 +21,7 @@ ctypedef struct biseq_s: mp_size_t length # Bitsize (ranging from 1 to GMP_LIMB_BITS) of one item of this - # sequence. Note: Each item is a non-negative integer, and all + # sequence. Note: Each item is a nonnegative integer, and all # items of this sequence satisfy an upper bound. We do not store # the exact bound for the items of this sequence, but store the # bitsize that is sufficient to store one item. diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 283cde6b1d9..44635ad2364 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -182,7 +182,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: INPUT: - - ``data`` -- a list of integers + - ``data`` -- list of integers - ``bound`` -- a number which is the maximal value of an item """ @@ -235,7 +235,7 @@ cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: """ - Tests if bounded integer sequence ``S1`` starts with bounded integer + Test if bounded integer sequence ``S1`` starts with bounded integer sequence ``S2``. ASSUMPTION: @@ -243,7 +243,6 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: - The two sequences must have equivalent bounds, i.e., the items on the sequences must fit into the same number of bits. This condition is not tested. - """ if S2.length > S1.length: return False @@ -259,7 +258,6 @@ cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: """ Return the position in ``S`` of an item in ``S[start:]``, or -1 if ``S[start:]`` does not contain the item. - """ cdef mp_size_t index sig_on() @@ -274,7 +272,6 @@ cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: cdef inline size_t biseq_getitem(biseq_t S, mp_size_t index) noexcept: """ Get item ``S[index]``, without checking margins. - """ cdef mp_bitcnt_t limb_index, bit_index bit_index = (index) * S.itembitsize @@ -292,7 +289,6 @@ cdef biseq_getitem_py(biseq_t S, mp_size_t index): """ Get item ``S[index]`` as a Python ``int``, without checking margins. - """ cdef size_t out = biseq_getitem(S, index) return PyLong_FromSize_t(out) @@ -336,7 +332,6 @@ cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop """ Create the slice ``S[start:stop:step]`` as bounded integer sequence and write the result to ``R``, which must not be initialised. - """ cdef mp_size_t length = 0 if step > 0: @@ -369,13 +364,13 @@ cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ - Tests if the bounded integer sequence ``S1[start:]`` contains a + Test if the bounded integer sequence ``S1[start:]`` contains a sub-sequence ``S2``. INPUT: - ``S1``, ``S2`` -- two bounded integer sequences - - ``start`` -- integer, start index + - ``start`` -- integer; start index OUTPUT: @@ -387,7 +382,6 @@ cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 - The two sequences must have equivalent bounds, i.e., the items on the sequences must fit into the same number of bits. This condition is not tested. - """ if S2.length == 0: return start @@ -410,7 +404,7 @@ cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) ex INPUT: - ``S1``, ``S2`` -- two bounded integer sequences - - ``start`` -- integer, start index + - ``start`` -- integer; start index OUTPUT: @@ -422,7 +416,6 @@ cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) ex - The two sequences must have equivalent bounds, i.e., the items on the sequences must fit into the same number of bits. This condition is not tested. - """ # Increase start if S1 is too short to contain S2[start:] if S1.length < S2.length - start: @@ -447,14 +440,14 @@ from sage.rings.integer cimport smallInteger cdef class BoundedIntegerSequence: """ - A sequence of non-negative uniformly bounded integers. + A sequence of nonnegative uniformly bounded integers. INPUT: - - ``bound`` -- non-negative integer. When zero, a :class:`ValueError` + - ``bound`` -- nonnegative integer. When zero, a :exc:`ValueError` will be raised. Otherwise, the given bound is replaced by the power of two that is at least the given bound. - - ``data`` -- a list of integers. + - ``data`` -- list of integers EXAMPLES: @@ -603,16 +596,15 @@ cdef class BoundedIntegerSequence: False sage: BoundedIntegerSequence(16, [2, 7, 4])[1:1] <> - """ def __cinit__(self, *args, **kwds): """ - Allocate memory for underlying data + Allocate memory for underlying data. INPUT: - - ``bound``, non-negative integer - - ``data``, ignored + - ``bound`` -- nonnegative integer + - ``data`` -- ignored .. WARNING:: @@ -624,21 +616,19 @@ cdef class BoundedIntegerSequence: sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> - """ # In __init__, we'll raise an error if the bound is 0. self.data.data.bits = NULL def __dealloc__(self): """ - Free the memory from underlying data + Free the memory from underlying data. EXAMPLES:: sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: del S # indirect doctest - """ biseq_dealloc(self.data) @@ -646,11 +636,11 @@ cdef class BoundedIntegerSequence: """ INPUT: - - ``bound`` -- positive integer. The given bound is replaced by - the next power of two that is greater than the given bound. + - ``bound`` -- positive integer; the given bound is replaced by + the next power of two that is greater than the given bound - - ``data`` -- a list of non-negative integers, all less than - ``bound``. + - ``data`` -- list of nonnegative integers; all less than + ``bound`` EXAMPLES:: @@ -702,7 +692,6 @@ cdef class BoundedIntegerSequence: Traceback (most recent call last): ... OverflowError: ... int too large to convert... - """ if bound <= 0: raise ValueError("positive bound expected") @@ -718,13 +707,12 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: copy(S) is S True - """ return self def __reduce__(self): """ - Pickling of :class:`BoundedIntegerSequence` + Pickling of :class:`BoundedIntegerSequence`. EXAMPLES:: @@ -751,7 +739,6 @@ cdef class BoundedIntegerSequence: True sage: loads(dumps(X[1::2])) == X[1::2] True - """ return NewBISEQ, biseq_pickle(self.data) @@ -764,7 +751,6 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(57, L) # indirect doctest sage: len(S) == len(L) True - """ return self.data.length @@ -780,7 +766,6 @@ cdef class BoundedIntegerSequence: True sage: bool(S[1:1]) False - """ return self.data.length!=0 @@ -798,7 +783,6 @@ cdef class BoundedIntegerSequence: <4, 1, 6, 2, 7, 20, 9> sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0]) <0, 0, 0, 0> - """ return "<" + ", ".join(str(x) for x in self) + ">" @@ -806,7 +790,7 @@ cdef class BoundedIntegerSequence: """ Return the bound of this bounded integer sequence. - All items of this sequence are non-negative integers less than the + All items of this sequence are nonnegative integers less than the returned bound. The bound is a power of two. EXAMPLES:: @@ -818,7 +802,6 @@ cdef class BoundedIntegerSequence: 32 sage: T.bound() 64 - """ return smallInteger(1) << self.data.itembitsize @@ -847,7 +830,6 @@ cdef class BoundedIntegerSequence: [4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0] sage: list(BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])) [0, 0, 0, 0] - """ cdef mp_size_t index for index in range(self.data.length): @@ -944,7 +926,6 @@ cdef class BoundedIntegerSequence: sage: B2 = BoundedIntegerSequence(8, [2,1,4]) sage: B1[0:1]+B2 <0, 2, 1, 4> - """ cdef BoundedIntegerSequence out cdef Py_ssize_t start, stop, step, slicelength @@ -968,7 +949,7 @@ cdef class BoundedIntegerSequence: def __contains__(self, other): """ - Tells whether this bounded integer sequence contains an item or a sub-sequence + Tells whether this bounded integer sequence contains an item or a sub-sequence. EXAMPLES:: @@ -1029,7 +1010,6 @@ cdef class BoundedIntegerSequence: sage: -1 in B False - """ if not isinstance(other, BoundedIntegerSequence): try: @@ -1043,7 +1023,7 @@ cdef class BoundedIntegerSequence: cpdef list list(self): """ - Converts this bounded integer sequence to a list + Convert this bounded integer sequence to a list. NOTE: @@ -1062,7 +1042,6 @@ cdef class BoundedIntegerSequence: sage: (BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])).list() [0, 0, 0, 0] - """ cdef mp_size_t i return [biseq_getitem_py(self.data, i) for i in range(self.data.length)] @@ -1097,7 +1076,6 @@ cdef class BoundedIntegerSequence: sage: T = BoundedIntegerSequence(51, L0) sage: S.startswith(T) False - """ if self.data.itembitsize != other.data.itembitsize: return False @@ -1105,7 +1083,7 @@ cdef class BoundedIntegerSequence: def index(self, other): """ - The index of a given item or sub-sequence of ``self`` + The index of a given item or sub-sequence of ``self``. EXAMPLES:: @@ -1159,7 +1137,6 @@ cdef class BoundedIntegerSequence: Traceback (most recent call last): ... TypeError: an integer is required - """ cdef mp_size_t out if not isinstance(other, BoundedIntegerSequence): @@ -1223,13 +1200,12 @@ cdef class BoundedIntegerSequence: sage: B2 = BoundedIntegerSequence(2^30, [10^9+3, 10^9+4]) sage: B1 + B2 <1000000001, 1000000002, 1000000003, 1000000004> - """ cdef BoundedIntegerSequence myself, right, out if other is None or self is None: raise TypeError('cannot concatenate bounded integer sequence and None') myself = self # may result in a type error - right = other # --"-- + right = other # --"-- if right.data.itembitsize != myself.data.itembitsize: raise ValueError("can only concatenate bounded integer sequences of compatible bounds") out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) @@ -1258,7 +1234,6 @@ cdef class BoundedIntegerSequence: sage: B2 = BoundedIntegerSequence(4,[2,3,2,3,2,3,1]) sage: B1.maximal_overlap(B2) <2, 3, 2, 3, 2, 3> - """ cdef mp_size_t i = biseq_startswith_tail(other.data, self.data, 0) if i==-1: @@ -1267,7 +1242,7 @@ cdef class BoundedIntegerSequence: def __richcmp__(self, other, op): """ - Comparison of bounded integer sequences + Comparison of bounded integer sequences. We compare, in this order: @@ -1313,7 +1288,6 @@ cdef class BoundedIntegerSequence: False sage: list(S)> list(T) True - """ cdef BoundedIntegerSequence right cdef BoundedIntegerSequence left @@ -1348,7 +1322,6 @@ cdef class BoundedIntegerSequence: True sage: hash(S) == hash(T) True - """ cdef Py_hash_t h = biseq_hash(self.data) if h == -1: @@ -1382,7 +1355,6 @@ cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize sage: S = BoundedIntegerSequence(2*sys.maxsize, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) sage: loads(dumps(S)) <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> - """ cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence) biseq_unpickle(out.data, bitset_data, itembitsize, length) diff --git a/src/sage/data_structures/list_of_pairs.pxd b/src/sage/data_structures/list_of_pairs.pxd index 4dbb57c201c..5b7483eb9ad 100644 --- a/src/sage/data_structures/list_of_pairs.pxd +++ b/src/sage/data_structures/list_of_pairs.pxd @@ -4,6 +4,7 @@ cdef struct pair_s: size_t first size_t second + @cython.final cdef class ListOfPairs: cdef pair_s** _lists diff --git a/src/sage/data_structures/meson.build b/src/sage/data_structures/meson.build new file mode 100644 index 00000000000..8a94548917b --- /dev/null +++ b/src/sage/data_structures/meson.build @@ -0,0 +1,41 @@ +py.install_sources( + 'all.py', + 'binary_matrix.pxd', + 'binary_search.pxd', + 'bitset.pxd', + 'bitset_base.pxd', + 'bitset_intrinsics.h', + 'blas_dict.pxd', + 'bounded_integer_sequences.pxd', + 'list_of_pairs.pxd', + 'mutable_poset.py', + 'sparse_bitset.pxd', + 'stream.py', + subdir: 'sage/data_structures', +) + +extension_data = { + 'binary_search' : files('binary_search.pyx'), + 'bitset' : files('bitset.pyx'), + 'bitset_base' : files('bitset_base.pyx'), + 'blas_dict' : files('blas_dict.pyx'), + 'bounded_integer_sequences' : files('bounded_integer_sequences.pyx'), + 'list_of_pairs' : files('list_of_pairs.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/data_structures', + install: true, + include_directories: [ + inc_cpython, + inc_data_structures, + inc_flint, + inc_rings, + ], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + diff --git a/src/sage/data_structures/mutable_poset.py b/src/sage/data_structures/mutable_poset.py index 8595bdcba75..0acef5aca6e 100644 --- a/src/sage/data_structures/mutable_poset.py +++ b/src/sage/data_structures/mutable_poset.py @@ -158,14 +158,12 @@ class MutablePosetShell(SageObject): INPUT: - - ``poset`` -- the poset to which this shell belongs. + - ``poset`` -- the poset to which this shell belongs - ``element`` -- the element which should be - contained/encapsulated in this shell. + contained/encapsulated in this shell - OUTPUT: - - A shell for the given element. + OUTPUT: a shell for the given element .. NOTE:: @@ -300,12 +298,10 @@ def predecessors(self, reverse=False): INPUT: - - ``reverse`` -- (default: ``False``) if set, then return - successors instead. - - OUTPUT: + - ``reverse`` -- boolean (default: ``False``); if set, then return + successors instead - A set. + OUTPUT: set .. SEEALSO:: @@ -331,12 +327,10 @@ def successors(self, reverse=False): INPUT: - - ``reverse`` -- (default: ``False``) if set, then return - predecessors instead. + - ``reverse`` -- boolean (default: ``False``); if set, then return + predecessors instead - OUTPUT: - - A set. + OUTPUT: set .. SEEALSO:: @@ -363,13 +357,7 @@ def is_special(self): infinity-element, i.e., the element larger than any possible other element. - INPUT: - - Nothing. - - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean .. SEEALSO:: @@ -393,9 +381,7 @@ def is_null(self): Return whether this shell contains the null-element, i.e., the element smaller than any possible other element. - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean .. SEEALSO:: @@ -420,9 +406,7 @@ def is_oo(self): Return whether this shell contains the infinity-element, i.e., the element larger than any possible other element. - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean .. SEEALSO:: @@ -446,13 +430,7 @@ def _repr_(self): r""" Return the representation of this shell. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string .. NOTE:: @@ -485,13 +463,7 @@ def __hash__(self): r""" Return the hash of this shell. - INPUT: - - Nothing. - - OUTPUT: - - A hash value. + OUTPUT: a hash value This returns the hash value of the key of the element contained in this shell. @@ -512,14 +484,12 @@ def le(self, other, reverse=False): INPUT: - - ``other`` -- a shell. - - - ``reverse`` -- (default: ``False``) if set, then return - whether this shell is greater than or equal to ``other``. + - ``other`` -- a shell - OUTPUT: + - ``reverse`` -- boolean (default: ``False``); if set, then return + whether this shell is greater than or equal to ``other`` - ``True`` or ``False``. + OUTPUT: boolean .. NOTE:: @@ -609,11 +579,9 @@ def eq(self, other): INPUT: - - ``other`` -- a shell. - - OUTPUT: + - ``other`` -- a shell - ``True`` or ``False``. + OUTPUT: boolean .. NOTE:: @@ -675,19 +643,17 @@ def _copy_all_linked_(self, memo, poset, mapping): INPUT: - - ``memo`` -- a dictionary which assigns to the id of the - calling shell to a copy of it. + - ``memo`` -- dictionary which assigns to the id of the + calling shell to a copy of it - ``poset`` -- the poset to which the newly created shells belongs. Note that the elements are not inserted into ``poset``; this is done in the calling method :meth:`MutablePoset._copy_shells_`. - - ``mapping`` -- a function which is applied on each of the elements. + - ``mapping`` -- a function which is applied on each of the elements - OUTPUT: - - A new shell. + OUTPUT: a new shell .. SEEALSO:: @@ -741,18 +707,16 @@ def lower_covers(self, shell, reverse=False): INPUT: - - ``shell`` -- the shell for which to find the covering shells. - There is no restriction of ``shell`` being contained in the poset. + - ``shell`` -- the shell for which to find the covering shells + There is no restriction of ``shell`` being contained in the poset If ``shell`` is contained in the poset, then use the more efficient methods :meth:`predecessors` and :meth:`successors`. - - ``reverse`` -- (default: ``False``) if set, then find + - ``reverse`` -- boolean (default: ``False``); if set, then find the upper covers (see also :meth:`upper_covers`) - instead of the lower covers. - - OUTPUT: + instead of the lower covers - A set of :class:`shells `. + OUTPUT: a set of :class:`shells ` .. NOTE:: @@ -821,18 +785,16 @@ def upper_covers(self, shell, reverse=False): INPUT: - - ``shell`` -- the shell for which to find the covering shells. - There is no restriction of ``shell`` being contained in the poset. + - ``shell`` -- the shell for which to find the covering shells + There is no restriction of ``shell`` being contained in the poset If ``shell`` is contained in the poset, then use the more efficient methods :meth:`predecessors` and :meth:`successors`. - - ``reverse`` -- (default: ``False``) if set, then find + - ``reverse`` -- boolean (default: ``False``); if set, then find the lower covers (see also :meth:`lower_covers`) instead of the upper covers. - OUTPUT: - - A set of :class:`shells `. + OUTPUT: a set of :class:`shells ` .. NOTE:: @@ -894,11 +856,11 @@ def _iter_depth_first_visit_(self, marked, INPUT: - - ``marked`` -- a set in which marked shells are stored. + - ``marked`` -- set in which marked shells are stored - - ``reverse`` -- (default: ``False``) if set, reverses the + - ``reverse`` -- boolean (default: ``False``); if set, reverses the order, i.e., ``False`` searches towards ``'oo'`` and - ``True`` searches towards ``'null'``. + ``True`` searches towards ``'null'`` - ``key`` -- (default: ``None``) a function used for sorting the direct successors of a shell (used in case of a @@ -910,10 +872,6 @@ def _iter_depth_first_visit_(self, marked, always ``True``. Note that the iteration does not go beyond a not included shell. - OUTPUT: - - An iterator. - .. NOTE:: The depth first search starts at this (``self``) shell. Thus @@ -956,9 +914,9 @@ def iter_depth_first(self, reverse=False, key=None, condition=None): INPUT: - - ``reverse`` -- (default: ``False``) if set, reverses the + - ``reverse`` -- boolean (default: ``False``); if set, reverses the order, i.e., ``False`` searches towards ``'oo'`` and - ``True`` searches towards ``'null'``. + ``True`` searches towards ``'null'`` - ``key`` -- (default: ``None``) a function used for sorting the direct successors of a shell (used in case of a @@ -970,10 +928,6 @@ def iter_depth_first(self, reverse=False, key=None, condition=None): always ``True``. Note that the iteration does not go beyond a not included shell. - OUTPUT: - - An iterator. - .. NOTE:: The depth first search starts at this (``self``) shell. Thus @@ -1018,11 +972,11 @@ def _iter_topological_visit_(self, marked, INPUT: - - ``marked`` -- a set in which marked shells are stored. + - ``marked`` -- set in which marked shells are stored - - ``reverse`` -- (default: ``False``) if set, reverses the + - ``reverse`` -- boolean (default: ``False``); if set, reverses the order, i.e., ``False`` searches towards ``'oo'`` and - ``True`` searches towards ``'null'``. + ``True`` searches towards ``'null'`` - ``key`` -- (default: ``None``) a function used for sorting the direct predecessors of a shell (used in case of a @@ -1034,9 +988,7 @@ def _iter_topological_visit_(self, marked, always ``True``. Note that the iteration does not go beyond a not included shell. - OUTPUT: - - An iterator. + OUTPUT: an iterator .. NOTE:: @@ -1081,9 +1033,9 @@ def iter_topological(self, reverse=False, key=None, condition=None): INPUT: - - ``reverse`` -- (default: ``False``) if set, reverses the + - ``reverse`` -- boolean (default: ``False``); if set, reverses the order, i.e., ``False`` searches towards ``'oo'`` and - ``True`` searches towards ``'null'``. + ``True`` searches towards ``'null'`` - ``key`` -- (default: ``None``) a function used for sorting the direct predecessors of a shell (used in case of a @@ -1095,9 +1047,7 @@ def iter_topological(self, reverse=False, key=None, condition=None): always ``True``. Note that the iteration does not go beyond a not included shell. - OUTPUT: - - An iterator. + OUTPUT: an iterator .. NOTE:: @@ -1192,19 +1142,17 @@ def merge(self, element, check=True, delete=True): INPUT: - - ``element`` -- an element (of the poset). + - ``element`` -- an element (of the poset) - - ``check`` -- (default: ``True``) if set, then the + - ``check`` -- boolean (default: ``True``); if set, then the ``can_merge``-function of :class:`MutablePoset` determines whether the merge is possible. ``can_merge`` is ``None`` means that this check is always passed. - - ``delete`` -- (default: ``True``) if set, then ``element`` - is removed from the poset after the merge. - - OUTPUT: + - ``delete`` -- boolean (default: ``True``); if set, then ``element`` + is removed from the poset after the merge - Nothing. + OUTPUT: nothing .. NOTE:: @@ -1336,7 +1284,7 @@ class MutablePoset(SageObject): position of the element in the poset. - ``can_merge`` -- a function which checks whether its second argument - can be merged to its first. + can be merged to its first This hook is called by :meth:`merge`. Moreover it is used during :meth:`add` when an element (more precisely its key) is already @@ -1345,9 +1293,7 @@ class MutablePoset(SageObject): ``can_merge`` is ``None`` (default) is equivalent to ``can_merge`` returning ``True`` in all cases. - OUTPUT: - - A mutable poset. + OUTPUT: a mutable poset You can find a short introduction and examples :mod:`here `. @@ -1441,13 +1387,7 @@ def clear(self): r""" Remove all elements from this poset. - INPUT: - - Nothing. - - OUTPUT: - - Nothing. + OUTPUT: nothing .. SEEALSO:: @@ -1481,13 +1421,7 @@ def __len__(self): r""" Return the number of elements contained in this poset. - INPUT: - - Nothing. - - OUTPUT: - - An integer. + OUTPUT: integer .. NOTE:: @@ -1561,11 +1495,9 @@ def shell(self, key): INPUT: - - ``key`` -- the key of an object. - - OUTPUT: + - ``key`` -- the key of an object - An instance of :class:`MutablePosetShell`. + OUTPUT: an instance of :class:`MutablePosetShell` .. NOTE:: @@ -1595,11 +1527,9 @@ def element(self, key): INPUT: - - ``key`` -- the key of an object. + - ``key`` -- the key of an object - OUTPUT: - - An object. + OUTPUT: an object EXAMPLES:: @@ -1624,11 +1554,9 @@ def get_key(self, element): INPUT: - - ``element`` -- an object. - - OUTPUT: + - ``element`` -- an object - An object (the key of ``element``). + OUTPUT: an object (the key of ``element``) .. SEEALSO:: @@ -1658,13 +1586,11 @@ def _copy_shells_(self, other, mapping): INPUT: - ``other`` -- the mutable poset from which the shells - should be copied to this poset. - - - ``mapping`` -- a function that is applied to each element. + should be copied to this poset - OUTPUT: + - ``mapping`` -- a function that is applied to each element - Nothing. + OUTPUT: nothing .. SEEALSO:: @@ -1700,11 +1626,9 @@ def copy(self, mapping=None): INPUT: - - ``mapping`` -- a function which is applied on each of the elements. + - ``mapping`` -- a function which is applied on each of the elements - OUTPUT: - - A poset with the same content as ``self``. + OUTPUT: a poset with the same content as ``self`` .. SEEALSO:: @@ -1739,13 +1663,11 @@ def shells(self, include_special=False): INPUT: - - ``include_special`` -- (default: ``False``) if set, then + - ``include_special`` -- boolean (default: ``False``); if set, then including shells containing a smallest element (`\emptyset`) - and a largest element (`\infty`). - - OUTPUT: + and a largest element (`\infty`) - An iterator. + OUTPUT: an iterator .. NOTE:: @@ -1784,11 +1706,11 @@ def shells_topological(self, include_special=False, INPUT: - - ``include_special`` -- (default: ``False``) if set, then + - ``include_special`` -- boolean (default: ``False``); if set, then including shells containing a smallest element (`\emptyset`) and a largest element (`\infty`). - - ``reverse`` -- (default: ``False``) -- if set, reverses the + - ``reverse`` -- boolean (default: ``False``); if set, reverses the order, i.e., ``False`` gives smallest elements first, ``True`` gives largest first. @@ -1796,9 +1718,7 @@ def shells_topological(self, include_special=False, the direct successors of a shell (used in case of a tie). If this is ``None``, no sorting occurs. - OUTPUT: - - An iterator. + OUTPUT: an iterator .. NOTE:: @@ -1843,11 +1763,7 @@ def elements(self, **kwargs): INPUT: - - ``kwargs`` -- arguments are passed to :meth:`shells`. - - OUTPUT: - - An iterator. + - ``kwargs`` -- arguments are passed to :meth:`shells` EXAMPLES:: @@ -1889,11 +1805,7 @@ def elements_topological(self, **kwargs): INPUT: - - ``kwargs`` -- arguments are passed to :meth:`shells_topological`. - - OUTPUT: - - An iterator. + - ``kwargs`` -- arguments are passed to :meth:`shells_topological` EXAMPLES:: @@ -1930,11 +1842,7 @@ def keys(self, **kwargs): INPUT: - - ``kwargs`` -- arguments are passed to :meth:`shells`. - - OUTPUT: - - An iterator. + - ``kwargs`` -- arguments are passed to :meth:`shells` EXAMPLES:: @@ -1976,11 +1884,7 @@ def keys_topological(self, **kwargs): INPUT: - - ``kwargs`` -- arguments are passed to :meth:`shells_topological`. - - OUTPUT: - - An iterator. + - ``kwargs`` -- arguments are passed to :meth:`shells_topological` EXAMPLES:: @@ -2019,16 +1923,13 @@ def repr(self, include_special=False, reverse=False): INPUT: - - ``include_special`` -- (default: ``False``) a boolean - indicating whether to include the special elements - ``'null'`` and ``'oo'`` or not. + - ``include_special`` -- boolean (default: ``False``); whether to + include the special elements ``'null'`` and ``'oo'`` or not - - ``reverse`` -- (default: ``False``) a boolean. If set, then - largest elements are displayed first. + - ``reverse`` -- boolean (default: ``False``); if set, then + largest elements are displayed first - OUTPUT: - - A string. + OUTPUT: string .. SEEALSO:: @@ -2053,12 +1954,10 @@ def repr_full(self, reverse=False): INPUT: - - ``reverse`` -- (default: ``False``) a boolean. If set, then - largest elements are displayed first. - - OUTPUT: + - ``reverse`` -- boolean (default: ``False``); if set, then + largest elements are displayed first - A string. + OUTPUT: string .. SEEALSO:: @@ -2102,11 +2001,9 @@ def contains(self, key): INPUT: - - ``key`` -- an object. - - OUTPUT: + - ``key`` -- an object - ``True`` or ``False``. + OUTPUT: boolean .. SEEALSO:: @@ -2138,11 +2035,9 @@ def add(self, element): INPUT: - ``element`` -- an object (hashable and supporting comparison - with the operator ``<=``). + with the operator ``<=``) - OUTPUT: - - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -2303,24 +2198,22 @@ def remove(self, key, raise_key_error=True): INPUT: - - ``key`` -- the key of an object. - - - ``raise_key_error`` -- (default: ``True``) switch raising - :class:`KeyError` on and off. + - ``key`` -- the key of an object - OUTPUT: + - ``raise_key_error`` -- boolean (default: ``True``); switch raising + :exc:`KeyError` on and off - Nothing. + OUTPUT: nothing If the element is not a member and ``raise_key_error`` is set - (default), raise a :class:`KeyError`. + (default), raise a :exc:`KeyError`. .. NOTE:: As with Python's ``set``, the methods :meth:`remove` and :meth:`discard` only differ in their behavior when an element is not contained in the poset: :meth:`remove` - raises a :class:`KeyError` whereas :meth:`discard` does not + raises a :exc:`KeyError` whereas :meth:`discard` does not raise any exception. This default behavior can be overridden with the @@ -2483,24 +2376,22 @@ def discard(self, key, raise_key_error=False): INPUT: - - ``key`` -- the key of an object. - - - ``raise_key_error`` -- (default: ``False``) switch raising - :class:`KeyError` on and off. + - ``key`` -- the key of an object - OUTPUT: + - ``raise_key_error`` -- boolean (default: ``False``); switch raising + :exc:`KeyError` on and off - Nothing. + OUTPUT: nothing If the element is not a member and ``raise_key_error`` is set - (not default), raise a :class:`KeyError`. + (not default), raise a :exc:`KeyError`. .. NOTE:: As with Python's ``set``, the methods :meth:`remove` and :meth:`discard` only differ in their behavior when an element is not contained in the poset: :meth:`remove` - raises a :class:`KeyError` whereas :meth:`discard` does not + raises a :exc:`KeyError` whereas :meth:`discard` does not raise any exception. This default behavior can be overridden with the @@ -2536,11 +2427,9 @@ def pop(self, **kwargs): INPUT: - - ``kwargs`` -- arguments are passed to :meth:`shells_topological`. + - ``kwargs`` -- arguments are passed to :meth:`shells_topological` - OUTPUT: - - An object. + OUTPUT: an object .. NOTE:: @@ -2580,7 +2469,7 @@ def pop(self, **kwargs): def union(self, *other): r""" - Return the union of the given posets as a new poset + Return the union of the given posets as a new poset. INPUT: @@ -2589,10 +2478,6 @@ def union(self, *other): It is possible to specify more than one ``other`` as variadic arguments (arbitrary argument lists). - OUTPUT: - - A poset. - .. NOTE:: The key of an element is used for comparison. Thus elements with @@ -2647,9 +2532,7 @@ def union_update(self, *other): It is possible to specify more than one ``other`` as variadic arguments (arbitrary argument lists). - OUTPUT: - - Nothing. + OUTPUT: nothing .. NOTE:: @@ -2716,10 +2599,6 @@ def difference(self, *other): It is possible to specify more than one ``other`` as variadic arguments (arbitrary argument lists). - OUTPUT: - - A poset. - .. NOTE:: The key of an element is used for comparison. Thus elements with @@ -2769,9 +2648,7 @@ def difference_update(self, *other): It is possible to specify more than one ``other`` as variadic arguments (arbitrary argument lists). - OUTPUT: - - Nothing. + OUTPUT: nothing .. NOTE:: @@ -2809,7 +2686,7 @@ def difference_update(self, *other): def intersection(self, *other): r""" - Return the intersection of the given posets as a new poset + Return the intersection of the given posets as a new poset. INPUT: @@ -2818,10 +2695,6 @@ def intersection(self, *other): It is possible to specify more than one ``other`` as variadic arguments (arbitrary argument lists). - OUTPUT: - - A poset. - .. NOTE:: The key of an element is used for comparison. Thus elements with @@ -2867,9 +2740,7 @@ def intersection_update(self, *other): It is possible to specify more than one ``other`` as variadic arguments (arbitrary argument lists). - OUTPUT: - - Nothing. + OUTPUT: nothing .. NOTE:: @@ -2910,11 +2781,7 @@ def symmetric_difference(self, other): INPUT: - - ``other`` -- a poset. - - OUTPUT: - - A poset. + - ``other`` -- a poset .. NOTE:: @@ -2952,11 +2819,9 @@ def symmetric_difference_update(self, other): INPUT: - - ``other`` -- a poset. + - ``other`` -- a poset - OUTPUT: - - Nothing. + OUTPUT: nothing .. NOTE:: @@ -2997,12 +2862,10 @@ def is_disjoint(self, other): INPUT: - - ``other`` -- a poset or an iterable. In the latter case the - iterated objects are seen as elements of a poset. - - OUTPUT: + - ``other`` -- a poset or an iterable; in the latter case the + iterated objects are seen as elements of a poset - Nothing. + OUTPUT: nothing .. NOTE:: @@ -3045,12 +2908,10 @@ def is_subset(self, other): INPUT: - - ``other`` -- a poset or an iterable. In the latter case the - iterated objects are seen as elements of a poset. - - OUTPUT: + - ``other`` -- a poset or an iterable; in the latter case the + iterated objects are seen as elements of a poset - Nothing. + OUTPUT: nothing .. NOTE:: @@ -3097,12 +2958,10 @@ def is_superset(self, other): INPUT: - - ``other`` -- a poset or an iterable. In the latter case the - iterated objects are seen as elements of a poset. - - OUTPUT: + - ``other`` -- a poset or an iterable; in the latter case the + iterated objects are seen as elements of a poset - Nothing. + OUTPUT: nothing .. NOTE:: @@ -3154,18 +3013,16 @@ def merge(self, key=None, reverse=False): - ``key`` -- the key specifying an element or ``None`` (default), in which case this method is called on each - element in this poset. + element in this poset - - ``reverse`` -- (default: ``False``) specifies which + - ``reverse`` -- boolean (default: ``False``); specifies which direction to go first: ``False`` searches towards ``'oo'`` and ``True`` searches towards ``'null'``. When ``key=None``, then this also specifies which elements are merged first. - OUTPUT: - - Nothing. + OUTPUT: nothing This method tests all (not necessarily direct) successors and predecessors of the given element whether they can be merged with @@ -3302,13 +3159,7 @@ def maximal_elements(self): r""" Return an iterator over the maximal elements of this poset. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -3333,13 +3184,7 @@ def minimal_elements(self): r""" Return an iterator over the minimal elements of this poset. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -3367,16 +3212,14 @@ def map(self, function, topological=False, reverse=False): INPUT: - ``function`` -- a function mapping an existing element to - a new element. - - - ``topological`` -- (default: ``False``) if set, then the - mapping is done in topological order, otherwise unordered. + a new element - - ``reverse`` -- is passed on to topological ordering. + - ``topological`` -- boolean (default: ``False``); if set, then the + mapping is done in topological order, otherwise unordered - OUTPUT: + - ``reverse`` -- is passed on to topological ordering - Nothing. + OUTPUT: nothing .. NOTE:: @@ -3431,16 +3274,14 @@ def mapped(self, function): INPUT: - ``function`` -- a function mapping an existing element to - a new element. - - - ``topological`` -- (default: ``False``) if set, then the - mapping is done in topological order, otherwise unordered. + a new element - - ``reverse`` -- is passed on to topological ordering. + - ``topological`` -- boolean (default: ``False``); if set, then the + mapping is done in topological order, otherwise unordered - OUTPUT: + - ``reverse`` -- is passed on to topological ordering - A :class:`MutablePoset`. + OUTPUT: a :class:`MutablePoset` .. NOTE:: diff --git a/src/sage/data_structures/sparse_bitset.pxd b/src/sage/data_structures/sparse_bitset.pxd index 9b95c55675b..e30de80073f 100644 --- a/src/sage/data_structures/sparse_bitset.pxd +++ b/src/sage/data_structures/sparse_bitset.pxd @@ -46,13 +46,13 @@ cdef struct sparse_bitset_s: # Pointer to the memory of ``bits``. void* mem - # Storing the non zero positions can safe time, when performing + # Storing the nonzero positions can safe time, when performing # multiple comparisons. # E.g. one can set them while computing the intersection # and then use those to ``bitset_issubset`` many times in a row. # Any modification, will invalidate the already computed positions. - # It is stored, whether the non zero chunks are correctly initialized + # It is stored, whether the nonzero chunks are correctly initialized # or not. Computations will work correctly either way. bint non_zero_chunks_are_initialized mp_bitcnt_t* non_zero_chunks diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 251deff8b96..ddca8fb26b2 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -107,7 +107,7 @@ lazy_import('sage.combinat.sf.sfa', ['_variables_recursive', '_raise_variables']) -class Stream(): +class Stream: """ Abstract base class for all streams. @@ -133,7 +133,6 @@ class Stream(): However, keep in mind that (trivially) this initialization code is not executed if ``_approximate_order`` is set to a value before it is accessed. - """ def __init__(self, true_order): """ @@ -185,7 +184,7 @@ def __ne__(self, other): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. The default implementation is ``False``. @@ -226,7 +225,7 @@ class Stream_inexact(Stream): - ``is_sparse`` -- boolean; whether the implementation of the stream is sparse - ``true_order`` -- boolean; if the approximate order is the actual order - If the cache is dense, it begins with the first non-zero term. + If the cache is dense, it begins with the first nonzero term. """ def __init__(self, is_sparse, true_order): """ @@ -251,7 +250,7 @@ def __init__(self, is_sparse, true_order): def is_nonzero(self): r""" - Return ``True`` if and only if the cache contains a non-zero element. + Return ``True`` if and only if the cache contains a nonzero element. EXAMPLES:: @@ -319,7 +318,7 @@ def __setstate__(self, d): INPUT: - - ``d`` -- a dictionary that needs to be unpickled + - ``d`` -- dictionary that needs to be unpickled EXAMPLES:: @@ -441,7 +440,7 @@ def iterate_coefficients(self): def order(self): r""" Return the order of ``self``, which is the minimum index ``n`` such - that ``self[n]`` is non-zero. + that ``self[n]`` is nonzero. EXAMPLES:: @@ -545,7 +544,6 @@ def __ne__(self, other): True sage: g != f True - """ # TODO: more cases, in particular mixed implementations, # could be detected @@ -582,7 +580,7 @@ class Stream_exact(Stream): INPUT: - - ``initial_values`` -- a list of initial values + - ``initial_values`` -- list of initial values - ``is_sparse`` -- boolean; specifies whether the stream is sparse - ``order`` -- integer (default: 0); determining the degree of the first element of ``initial_values`` @@ -607,7 +605,7 @@ def __init__(self, initial_coefficients, constant=None, degree=None, order=None) sage: Stream_exact([]) Traceback (most recent call last): ... - AssertionError: Stream_exact should only be used for non-zero streams + AssertionError: Stream_exact should only be used for nonzero streams sage: s = Stream_exact([0, 0, 1, 0, 0]) sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order @@ -669,7 +667,7 @@ def __init__(self, initial_coefficients, constant=None, degree=None, order=None) # complicated otherwise for i, v in enumerate(initial_coefficients): if v: - # We have found the first non-zero coefficient + # We have found the first nonzero coefficient order += i initial_coefficients = initial_coefficients[i:] if order + len(initial_coefficients) == self._degree: @@ -690,7 +688,7 @@ def __init__(self, initial_coefficients, constant=None, degree=None, order=None) order = self._degree self._initial_coefficients = tuple() - assert self._initial_coefficients or self._constant, "Stream_exact should only be used for non-zero streams" + assert self._initial_coefficients or self._constant, "Stream_exact should only be used for nonzero streams" super().__init__(True) self._approximate_order = order @@ -748,7 +746,7 @@ def __getitem__(self, n): def order(self): r""" Return the order of ``self``, which is the minimum index - ``n`` such that ``self[n]`` is non-zero. + ``n`` such that ``self[n]`` is nonzero. EXAMPLES:: @@ -808,7 +806,6 @@ def __eq__(self, other): sage: t = Stream_exact([2], order=-1, degree=5, constant=1) sage: s == t False - """ return (isinstance(other, type(self)) and self._degree == other._degree @@ -821,7 +818,7 @@ def __ne__(self, other): Return whether ``self`` and ``other`` are known to be different. The argument ``other`` may be exact or inexact, but is - assumed to be non-zero. + assumed to be nonzero. INPUT: @@ -882,9 +879,9 @@ def __ne__(self, other): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. - An assumption of this class is that it is non-zero. + An assumption of this class is that it is nonzero. EXAMPLES:: @@ -943,7 +940,7 @@ def __init__(self, iter, approximate_order, true_order=False): sage: from sage.data_structures.stream import Stream_iterator sage: f = Stream_iterator(iter(NonNegativeIntegers()), 0) - sage: TestSuite(f).run(skip="_test_pickling") + sage: TestSuite(f).run(skip='_test_pickling') """ self.iterate_coefficients = lambda: iter super().__init__(False, true_order) @@ -993,7 +990,7 @@ def __init__(self, function, is_sparse, approximate_order, true_order=False): sage: from sage.data_structures.stream import Stream_function sage: f = Stream_function(lambda n: 1, False, 1) - sage: TestSuite(f).run(skip="_test_pickling") + sage: TestSuite(f).run(skip='_test_pickling') """ self.get_coefficient = function super().__init__(is_sparse, true_order) @@ -1076,7 +1073,7 @@ def __init__(self, function, is_sparse): sage: from sage.data_structures.stream import Stream_taylor sage: f = Stream_taylor(polygen(QQ, 'x')^3, False) - sage: TestSuite(f).run(skip="_test_pickling") + sage: TestSuite(f).run(skip='_test_pickling') """ from sage.symbolic.ring import SR from sage.structure.element import parent @@ -1241,7 +1238,7 @@ def __init__(self, approximate_order, true_order=False): sage: from sage.data_structures.stream import Stream_uninitialized sage: C = Stream_uninitialized(0) - sage: TestSuite(C).run(skip="_test_pickling") + sage: TestSuite(C).run(skip='_test_pickling') """ self._target = None if approximate_order is None: @@ -1310,7 +1307,7 @@ class Stream_unary(Stream_inexact): - ``series`` -- :class:`Stream` the operator acts on - ``is_sparse`` -- boolean - - ``true_order`` -- boolean (default: ``False``) if the approximate order + - ``true_order`` -- boolean (default: ``False``); if the approximate order is the actual order EXAMPLES:: @@ -1871,7 +1868,7 @@ def get_coefficient(self, n): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. EXAMPLES:: @@ -1945,7 +1942,7 @@ def _approximate_order(self): or self._right._approximate_order <= 0): raise ValueError("Dirichlet convolution is only defined for " "coefficient streams with minimal index of " - "non-zero coefficient at least 1") + "nonzero coefficient at least 1") return self._left._approximate_order * self._right._approximate_order def get_coefficient(self, n): @@ -2100,13 +2097,13 @@ class Stream_plethysm(Stream_binary): - ``f`` -- a :class:`Stream` - ``g`` -- a :class:`Stream` with positive order, unless ``f`` is - of :class:`Stream_exact`. + of :class:`Stream_exact` - ``p`` -- the ring of powersum symmetric functions containing ``g`` - - ``ring`` (default: ``None``) -- the ring the result + - ``ring`` -- (default: ``None``) the ring the result should be in, by default ``p`` - - ``include`` -- a list of variables to be treated as degree one + - ``include`` -- list of variables to be treated as degree one elements instead of the default degree one elements - - ``exclude`` -- a list of variables to be excluded from the + - ``exclude`` -- list of variables to be excluded from the default degree one elements EXAMPLES:: @@ -2180,7 +2177,6 @@ class Stream_plethysm(Stream_binary): sage: r2 = Stream_plethysm(f, g, True, p, include=[]) # needs sage.modules sage: r_s - sum(r2[n] for n in range(2*(r_s.degree()+1))) # needs sage.modules (a2*b1^2-a2*b1)*p[2] + (a2*b111^2-a2*b111)*p[2, 2, 2] + (a2*b21^2-a2*b21)*p[4, 2] - """ def __init__(self, f, g, is_sparse, p, ring=None, include=None, exclude=None): r""" @@ -2396,7 +2392,6 @@ def stretched_power_restrict_degree(self, i, m, d): ....: if sum(mu.size() for mu in m) == 12}) sage: A == B # long time True - """ # TODO: we should do lazy binary powering here while len(self._powers) < m: @@ -2409,13 +2404,13 @@ def stretched_power_restrict_degree(self, i, m, d): # integer and not a symmetric function if power_d: # _raise_variables(c, i, self._degree_one) cannot vanish - # because i is positive and c is non-zero + # because i is positive and c is nonzero if self._tensor_power is None: terms = {mon.stretch(i): _raise_variables(c, i, self._degree_one) for mon, c in power_d} else: - terms = {tuple((mu.stretch(i) for mu in mon)): + terms = {tuple(mu.stretch(i) for mu in mon): _raise_variables(c, i, self._degree_one) for mon, c in power_d} return self._basis(self._p.element_class(self._p, terms)) @@ -2434,7 +2429,7 @@ class Stream_scalar(Stream_unary): INPUT: - ``series`` -- a :class:`Stream` - - ``scalar`` -- a non-zero, non-one scalar + - ``scalar`` -- a nonzero, non-one scalar - ``is_sparse`` -- boolean """ def __init__(self, series, scalar, is_sparse): @@ -2515,7 +2510,7 @@ def __eq__(self, other): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. EXAMPLES:: @@ -2542,7 +2537,7 @@ class Stream_rmul(Stream_scalar): INPUT: - ``series`` -- a :class:`Stream` - - ``scalar`` -- a non-zero, non-one scalar + - ``scalar`` -- a nonzero, non-one scalar EXAMPLES:: @@ -2584,7 +2579,7 @@ class Stream_lmul(Stream_scalar): INPUT: - ``series`` -- a :class:`Stream` - - ``scalar`` -- a non-zero, non-one scalar + - ``scalar`` -- a nonzero, non-one scalar EXAMPLES:: @@ -2691,7 +2686,7 @@ def get_coefficient(self, n): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. EXAMPLES:: @@ -2730,7 +2725,6 @@ class Stream_cauchy_invert(Stream_unary): sage: g = Stream_cauchy_invert(f) sage: [g[i] for i in range(10)] [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0] - """ def __init__(self, series, approximate_order=None): """ @@ -2830,9 +2824,9 @@ def iterate_coefficients(self): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. - An assumption of this class is that it is non-zero. + An assumption of this class is that it is nonzero. EXAMPLES:: @@ -2875,7 +2869,7 @@ def __init__(self, series, is_sparse): sage: g[1] Traceback (most recent call last): ... - ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero + ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is nonzero """ super().__init__(series, is_sparse) self._zero = ZZ.zero() @@ -2898,7 +2892,7 @@ def _approximate_order(self): # this is the true order, but we want to check first if self._series._approximate_order > 1: raise ZeroDivisionError("the Dirichlet inverse only exists if the " - "coefficient with index 1 is non-zero") + "coefficient with index 1 is nonzero") self._true_order = True return 1 @@ -2954,7 +2948,7 @@ def get_coefficient(self, n): class Stream_map_coefficients(Stream_unary): r""" - The stream with ``function`` applied to each non-zero coefficient + The stream with ``function`` applied to each nonzero coefficient of ``series``. INPUT: @@ -2974,7 +2968,6 @@ class Stream_map_coefficients(Stream_unary): sage: g = Stream_map_coefficients(f, lambda n: -n, True) sage: [g[i] for i in range(10)] [0, -1, -1, -1, -1, -1, -1, -1, -1, -1] - """ def __init__(self, series, function, is_sparse, approximate_order=None, true_order=False): """ @@ -2985,7 +2978,7 @@ def __init__(self, series, function, is_sparse, approximate_order=None, true_ord sage: from sage.data_structures.stream import (Stream_map_coefficients, Stream_function) sage: f = Stream_function(lambda n: -1, True, 0) sage: g = Stream_map_coefficients(f, lambda n: n + 1, True) - sage: TestSuite(g).run(skip="_test_pickling") + sage: TestSuite(g).run(skip='_test_pickling') """ self._function = function super().__init__(series, is_sparse, true_order) @@ -3079,14 +3072,14 @@ def __eq__(self, other): class Stream_shift(Stream): """ - Operator for shifting a non-zero, non-exact stream. + Operator for shifting a nonzero, non-exact stream. Instances of this class share the cache with its input stream. INPUT: - ``series`` -- a :class:`Stream` - - ``shift`` -- an integer + - ``shift`` -- integer """ def __init__(self, series, shift): """ @@ -3098,7 +3091,7 @@ def __init__(self, series, shift): sage: from sage.data_structures.stream import Stream_function sage: h = Stream_function(lambda n: n, True, -5) sage: M = Stream_shift(h, 2) - sage: TestSuite(M).run(skip="_test_pickling") + sage: TestSuite(M).run(skip='_test_pickling') """ self._series = series self._shift = shift @@ -3125,7 +3118,7 @@ def _approximate_order(self): def order(self): r""" Return the order of ``self``, which is the minimum index - ``n`` such that ``self[n]`` is non-zero. + ``n`` such that ``self[n]`` is nonzero. EXAMPLES:: @@ -3195,9 +3188,9 @@ def __eq__(self, other): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. - An assumption of this class is that it is non-zero. + An assumption of this class is that it is nonzero. EXAMPLES:: @@ -3226,7 +3219,7 @@ def is_uninitialized(self): class Stream_truncated(Stream_unary): """ - Operator for shifting a non-zero, non-exact stream that has + Operator for shifting a nonzero, non-exact stream that has been shifted below its minimal valuation. Instances of this class share the cache with its input stream. @@ -3234,8 +3227,8 @@ class Stream_truncated(Stream_unary): INPUT: - ``series`` -- a :class:`Stream_inexact` - - ``shift`` -- an integer - - ``minimal_valuation`` -- an integer; this is also the approximate order + - ``shift`` -- integer + - ``minimal_valuation`` -- integer; this is also the approximate order """ def __init__(self, series, shift, minimal_valuation): """ @@ -3246,9 +3239,9 @@ def __init__(self, series, shift, minimal_valuation): sage: from sage.data_structures.stream import Stream_function, Stream_truncated sage: def fun(n): return 1 if ZZ(n).is_power_of(2) else 0 sage: s = Stream_truncated(Stream_function(fun, True, 0), -5, 0) - sage: TestSuite(s).run(skip="_test_pickling") + sage: TestSuite(s).run(skip='_test_pickling') sage: s = Stream_truncated(Stream_function(fun, False, 0), -5, 0) - sage: TestSuite(s).run(skip="_test_pickling") + sage: TestSuite(s).run(skip='_test_pickling') Verify that we have used the cache to see if we can get the true order at initialization:: @@ -3386,7 +3379,7 @@ def __eq__(self, other): def order(self): """ Return the order of ``self``, which is the minimum index ``n`` such - that ``self[n]`` is non-zero. + that ``self[n]`` is nonzero. EXAMPLES:: @@ -3432,7 +3425,7 @@ def order(self): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. EXAMPLES:: @@ -3479,7 +3472,7 @@ class Stream_derivative(Stream_unary): INPUT: - ``series`` -- a :class:`Stream` - - ``shift`` -- a positive integer + - ``shift`` -- positive integer - ``is_sparse`` -- boolean """ def __init__(self, series, shift, is_sparse): @@ -3586,7 +3579,7 @@ def __eq__(self, other): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. EXAMPLES:: @@ -3607,7 +3600,7 @@ class Stream_integral(Stream_unary): INPUT: - ``series`` -- a :class:`Stream` - - ``integration_constants`` -- a list of integration constants + - ``integration_constants`` -- list of integration constants - ``is_sparse`` -- boolean """ def __init__(self, series, integration_constants, is_sparse): @@ -3714,7 +3707,7 @@ def __eq__(self, other): def is_nonzero(self): r""" Return ``True`` if and only if this stream is known - to be non-zero. + to be nonzero. EXAMPLES:: diff --git a/src/sage/databases/conway.py b/src/sage/databases/conway.py index 7c7c3af42ac..e782676fde9 100644 --- a/src/sage/databases/conway.py +++ b/src/sage/databases/conway.py @@ -15,6 +15,7 @@ # **************************************************************************** from collections.abc import Mapping + class DictInMapping(Mapping): def __init__(self, dict): """ @@ -173,7 +174,7 @@ def __iter__(self): def polynomial(self, p, n): """ Return the Conway polynomial of degree ``n`` over ``GF(p)``, - or raise a :class:`RuntimeError` if this polynomial is not in the + or raise a :exc:`RuntimeError` if this polynomial is not in the database. .. NOTE:: @@ -209,7 +210,7 @@ def polynomial(self, p, n): def has_polynomial(self, p, n): """ - Return True if the database of Conway polynomials contains the + Return ``True`` if the database of Conway polynomials contains the polynomial of degree ``n`` over ``GF(p)``. INPUT: diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index c556a64bdff..44c8fbcdc7f 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -103,7 +103,7 @@ def build(name, data_tgz, largest_conductor=0, mini=False, decompress=True): Build the CremonaDatabase with given name from scratch using the data_tgz tarball. - .. note:: + .. NOTE:: For data up to level 350000, this function takes about 3m40s. The resulting database occupies 426MB disk space. @@ -144,23 +144,23 @@ def build(name, data_tgz, largest_conductor=0, mini=False, decompress=True): def is_optimal_id(id): """ - Return True if the Cremona id refers to an optimal curve, and - false otherwise. + Return ``True`` if the Cremona id refers to an optimal curve, and + ``False`` otherwise. The curve is optimal if the id, which is of the form [letter code][number] has number 1. - .. note:: + .. NOTE:: 990h3 is the optimal curve in that class, so doesn't obey this rule. INPUT: - - ``id`` -- str of form letter code followed by an - integer, e.g., a3, bb5, etc. + - ``id`` -- string of form letter code followed by an + integer, e.g., a3, bb5, etc. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -183,7 +183,7 @@ def cremona_letter_code(n): For example, 0 - a 25 - z 26 - ba 51 - bz 52 - ca 53 - cb etc. - .. note:: + .. NOTE:: This is just the base 26 representation of n, where a=0, b=1, ..., z=25. This extends the old Cremona notation (counting from @@ -192,9 +192,9 @@ def cremona_letter_code(n): INPUT: - - ``n`` (int) -- a non-negative integer + - ``n`` -- nonnegative integer - OUTPUT: str + OUTPUT: string EXAMPLES:: @@ -217,19 +217,19 @@ def cremona_letter_code(n): sage: cremona_letter_code(QQ) Traceback (most recent call last): ... - ValueError: Cremona letter codes are only defined for non-negative integers + ValueError: Cremona letter codes are only defined for nonnegative integers sage: cremona_letter_code(x) # needs sage.symbolic Traceback (most recent call last): ... - ValueError: Cremona letter codes are only defined for non-negative integers + ValueError: Cremona letter codes are only defined for nonnegative integers sage: cremona_letter_code(-1) Traceback (most recent call last): ... - ValueError: Cremona letter codes are only defined for non-negative integers + ValueError: Cremona letter codes are only defined for nonnegative integers sage: cremona_letter_code(3.14159) Traceback (most recent call last): ... - ValueError: Cremona letter codes are only defined for non-negative integers + ValueError: Cremona letter codes are only defined for nonnegative integers """ try: m = int(n) @@ -241,7 +241,7 @@ def cremona_letter_code(n): n = -1 if n < 0: - raise ValueError("Cremona letter codes are only defined for non-negative integers") + raise ValueError("Cremona letter codes are only defined for nonnegative integers") if n == 0: return "a" @@ -267,9 +267,9 @@ def old_cremona_letter_code(n): INPUT: - - ``n`` -- int + - ``n`` -- integer - OUTPUT: str + OUTPUT: string EXAMPLES:: @@ -314,17 +314,17 @@ def parse_cremona_label(label, numerical_class_code=False): INPUT: - - ``label`` (string) -- a valid Cremona elliptic curve label + - ``label`` -- string; a valid Cremona elliptic curve label - - ``numerical_class_code`` (boolean, default: ``False``) -- if ``True``, - convert the isogeny class label from a letter code in base 26 - to an integer; this is useful for sorting + - ``numerical_class_code`` -- boolean (default: ``False``); if ``True``, + convert the isogeny class label from a letter code in base 26 + to an integer. This is useful for sorting. OUTPUT: - - ``int`` -- the conductor - - ``str`` or ``int`` -- the isogeny class label - - ``int`` -- the number + - integer; the conductor + - string or integer; the isogeny class label + - integer; the number EXAMPLES:: @@ -364,7 +364,6 @@ def parse_cremona_label(label, numerical_class_code=False): Traceback (most recent call last): ... ValueError: x11 is not a valid Cremona label - """ m = cremona_label_regex.match(str(label)) if m is None: @@ -399,11 +398,11 @@ def parse_lmfdb_label(label, numerical_class_code=False): or 37.b3, parse the label and return the conductor, isogeny class label, and number. - The LMFDB label (named after the L-functions and modular forms + The LMFDB label (named after the `L`-functions and modular forms database), is determined by the following two orders: - Isogeny classes with the same conductor are ordered - lexicographically by the coefficients in the q-expansion of the + lexicographically by the coefficients in the `q`-expansion of the associated modular form. - Curves within the same isogeny class are ordered @@ -420,17 +419,17 @@ def parse_lmfdb_label(label, numerical_class_code=False): INPUT: - - ``label`` -- str + - ``label`` -- str - - ``numerical_class_code`` (boolean, default: ``False``) -- if ``True``, - convert the isogeny class label from a letter code in base 26 - to an integer; this is useful for sorting + - ``numerical_class_code`` -- boolean (default: ``False``); if ``True``, + convert the isogeny class label from a letter code in base 26 + to an integer. This is useful for sorting. OUTPUT: - - ``int`` -- the conductor - - ``str`` or ``int`` -- the isogeny class label - - ``int`` -- the number + - ``int`` -- the conductor + - ``str`` or ``int`` -- the isogeny class label + - ``int`` -- the number EXAMPLES:: @@ -515,7 +514,7 @@ def sort_key(key1): """ Comparison key for curve id strings. - .. note:: + .. NOTE:: Not the same as standard lexicographic order! @@ -538,15 +537,12 @@ def cremona_to_lmfdb(cremona_label, CDB=None): INPUT: - - ``cremona_label`` -- a string, the Cremona label of a curve. - This can be the label of a curve (e.g. '990j1') or of an isogeny - class (e.g. '990j') + - ``cremona_label`` -- string, the Cremona label of a curve; this can be + the label of a curve (e.g. '990j1') or of an isogeny class (e.g. '990j') - ``CDB`` -- the Cremona database in which to look up the isogeny - classes of the same conductor. - - OUTPUT: + classes of the same conductor - - ``lmfdb_label`` -- a string, the corresponding LMFDB label. + OUTPUT: ``lmfdb_label``; string, the corresponding LMFDB label EXAMPLES:: @@ -571,8 +567,8 @@ class (e.g. '990j') if CDB is None: CDB = CremonaDatabase() classes = CDB.isogeny_classes(N) - ft = int(53) - tff = int(255) # This should be enough to distinguish between curves (using heuristics from Sato-Tate for example) + ft = 53 + tff = 255 # This should be enough to distinguish between curves (using heuristics from Sato-Tate for example) isos = [] for i, iso in enumerate(classes): alist = iso[0][0] @@ -598,15 +594,12 @@ def lmfdb_to_cremona(lmfdb_label, CDB=None): INPUT: - - ``lmfdb_label`` -- a string, the LMFDB label of a curve. - This can be the label of a curve (e.g. '990.j1') or of an isogeny - class (e.g. '990.j') + - ``lmfdb_label`` -- string, the LMFDB label of a curve; this can be the + label of a curve (e.g. '990.j1') or of an isogeny class (e.g. '990.j') - ``CDB`` -- the Cremona database in which to look up the isogeny - classes of the same conductor. - - OUTPUT: + classes of the same conductor - - ``cremona_label`` -- a string, the corresponding Cremona label. + OUTPUT: ``cremona_label``; a string, the corresponding Cremona label EXAMPLES:: @@ -624,8 +617,8 @@ class (e.g. '990.j') if CDB is None: CDB = CremonaDatabase() classes = CDB.isogeny_classes(N) - ft = int(53) - tff = int(255) # This should be enough to distinguish between curves (using heuristics from Sato-Tate for example) + ft = 53 + tff = 255 # This should be enough to distinguish between curves (using heuristics from Sato-Tate for example) isos = [] for i, iso in enumerate(classes): alist = iso[0][0] @@ -708,15 +701,16 @@ def __iter__(self): def __getitem__(self, N): """ - If N is an integer, return all data about level N in the database. - If N is a string it must be a Cremona label, in which case return + If `N` is an integer, return all data about level `N` in the database. + If `N` is a string it must be a Cremona label, in which case return the corresponding elliptic curve, if it is in the database. INPUT: - - ``N`` -- int or str + - ``N`` -- integer or string - OUTPUT: dict (if N is an int) or EllipticCurve (if N is a str) + OUTPUT: dictionary (if `N` is an integer) or EllipticCurve (if `N` is + a string) TESTS:: @@ -765,11 +759,9 @@ def allcurves(self, N): INPUT: - - ``N`` -- int, the conductor - - OUTPUT: + - ``N`` -- integer; the conductor - - ``dict`` -- id:[ainvs, rank, tor], ... + OUTPUT: dictionary; id:[ainvs, rank, tor], ... EXAMPLES:: @@ -795,11 +787,9 @@ def curves(self, N): INPUT: - - ``N`` -- int, the conductor + - ``N`` -- integer; the conductor - OUTPUT: - - - ``dict`` -- id:[ainvs, rank, tor], ... + OUTPUT: dictionary; id:[ainvs, rank, tor], ... EXAMPLES: @@ -828,7 +818,7 @@ def curves(self, N): ret[iso+str(num)] = [eval(c[1]),c[2],c[3]] if N == 990: del ret['h1'] - ret['h3'] = [[1,-1,1,-1568,-4669],int(1),int(6)] + ret['h3'] = [[1,-1,1,-1568,-4669],1,6] return ret def coefficients_and_data(self, label): @@ -956,12 +946,12 @@ def elliptic_curve_from_ainvs(self, ainvs): Return the elliptic curve in the database of with minimal ``ainvs`` if it exists. - This raises a :class:`RuntimeError` exception otherwise. + This raises a :exc:`RuntimeError` exception otherwise. INPUT: - - ``ainvs`` -- list (5-tuple of int's); the minimal - Weierstrass model for an elliptic curve + - ``ainvs`` -- list (5-tuple of int's); the minimal + Weierstrass model for an elliptic curve OUTPUT: EllipticCurve @@ -995,13 +985,11 @@ def elliptic_curve(self, label): INPUT: - - ``label`` -- str (Cremona or LMFDB label) - - OUTPUT: + - ``label`` -- string (Cremona or LMFDB label) - - an :class:`sage.schemes.elliptic_curves.ell_rational_field.EllipticCurve_rational_field` + OUTPUT: an :class:`sage.schemes.elliptic_curves.ell_rational_field.EllipticCurve_rational_field` - .. note:: + .. NOTE:: For more details on LMFDB labels see :func:`parse_lmfdb_label`. @@ -1032,9 +1020,9 @@ def iter(self, conductors): INPUT: - - ``conductors`` -- list or generator of ints + - ``conductors`` -- list or generator of ints - OUTPUT: generator that iterates over EllipticCurve objects. + OUTPUT: generator that iterates over EllipticCurve objects EXAMPLES:: @@ -1088,11 +1076,9 @@ def isogeny_class(self, label): INPUT: - - ``label`` -- string + - ``label`` -- string - OUTPUT: - - - ``list`` -- list of EllipticCurve objects. + OUTPUT: list of EllipticCurve objects EXAMPLES:: @@ -1118,9 +1104,7 @@ def iter_optimal(self, conductors): - ``conductors`` -- list or generator of ints - OUTPUT: - - generator that iterates over EllipticCurve objects. + OUTPUT: generator that iterates over EllipticCurve objects EXAMPLES: @@ -1138,10 +1122,10 @@ def iter_optimal(self, conductors): if N == 990: for c in self.__connection__.cursor().execute('SELECT class ' + 'FROM t_class WHERE conductor=990'): - if c[0][-1] == u'h': - yield self.elliptic_curve(c[0]+u'3') + if c[0][-1] == 'h': + yield self.elliptic_curve(c[0]+'3') else: - yield self.elliptic_curve(c[0]+u'1') + yield self.elliptic_curve(c[0]+'1') continue for c in self.__connection__.cursor().execute('SELECT curve ' + 'FROM t_curve,t_class USING(class) WHERE curve=class||1 ' @@ -1156,9 +1140,7 @@ def list(self, conductors): - ``conductors`` -- list or generator of ints - OUTPUT: - - - list of EllipticCurve objects. + OUTPUT: list of EllipticCurve objects EXAMPLES:: @@ -1176,12 +1158,10 @@ def list_optimal(self, conductors): INPUT: - - ``conductors`` -- list or generator of ints - list of EllipticCurve objects. - - OUTPUT: + - ``conductors`` -- list or generator of ints list of EllipticCurve + objects - list of EllipticCurve objects. + OUTPUT: list of EllipticCurve objects EXAMPLES:: @@ -1195,9 +1175,7 @@ def largest_conductor(self): """ The largest conductor for which the database is complete. - OUTPUT: - - - ``int`` -- largest conductor + OUTPUT: integer; largest conductor EXAMPLES:: @@ -1216,11 +1194,9 @@ def smallest_conductor(self): """ The smallest conductor for which the database is complete: always 1. - OUTPUT: + OUTPUT: integer; smallest conductor - - ``int`` -- smallest conductor - - .. note:: + .. NOTE:: This always returns the integer 1, since that is the smallest conductor for which the database is complete, @@ -1252,18 +1228,18 @@ def conductor_range(self): def number_of_curves(self, N=0, i=0): """ Return the number of curves stored in the database with conductor - N. If N = 0, returns the total number of curves in the database. + `N`. If `N = 0`, returns the total number of curves in the database. - If i is nonzero, returns the number of curves in the i-th isogeny - class. If i is a Cremona letter code, e.g., 'a' or 'bc', it is + If `i` is nonzero, returns the number of curves in the `i`-th isogeny + class. If `i` is a Cremona letter code, e.g., 'a' or 'bc', it is converted to the corresponding number. INPUT: - - ``N`` -- int - - ``i`` -- int or str + - ``N`` -- integer + - ``i`` -- integer or string - OUTPUT: int + OUTPUT: integer EXAMPLES:: @@ -1302,9 +1278,9 @@ def number_of_isogeny_classes(self, N=0): INPUT: - - ``N`` -- int + - ``N`` -- integer - OUTPUT: int + OUTPUT: integer EXAMPLES:: @@ -1368,7 +1344,6 @@ def _init_from_ftpdata(self, ftpdata, largest_conductor=0): sage: d = sage.databases.cremona.MiniCremonaDatabase(name='cremona', read_only=False, rebuild=True) # not tested sage: d._init_from_ftpdata('/home/jec/ecdata') # not tested - """ if self.__read_only__: raise RuntimeError("The database must not be read_only.") @@ -1408,15 +1383,15 @@ def _init_allcurves(self, ftpdata, largest_conductor=0): INPUT: - - `ftpdata` (string) -- the name of the directory in which the data is + - ``ftpdata`` -- string; the name of the directory in which the data is - - ``largest_conductor`` -- int (default: 0), if 0, - then only include data up to that conductor. + - ``largest_conductor`` -- integer (default: 0); if 0, + then only include data up to that conductor OUTPUT: - - ``int`` -- number_of_curves - - ``int`` -- number_of_isogeny_classes + - integer; number_of_curves + - integer; number_of_isogeny_classes EXAMPLES:: @@ -1485,9 +1460,9 @@ def allbsd(self, N): INPUT: - - ``N`` -- int, the conductor + - ``N`` -- integer; the conductor - OUTPUT: dict containing the allbsd table for each isogeny class + OUTPUT: dictionary containing the allbsd table for each isogeny class in conductor N EXAMPLES:: @@ -1514,11 +1489,9 @@ def allgens(self, N): INPUT: - - ``N`` -- int, the conductor - - OUTPUT: + - ``N`` -- integer; the conductor - - ``dict`` -- id:[points, ...], ... + OUTPUT: dictionary; id:[points, ...], ... EXAMPLES:: @@ -1543,11 +1516,9 @@ def degphi(self, N): INPUT: - - ``N`` -- int, the conductor + - ``N`` -- integer; the conductor - OUTPUT: - - - ``dict`` -- id:degphi, ... + OUTPUT: dictionary; id:degphi, ... EXAMPLES:: @@ -1672,6 +1643,7 @@ def _init_allgens(self, ftpdata, largest_conductor=0): con.executemany("UPDATE t_curve SET gens=? WHERE curve=?", curve_data) print("Committing...") + self.commit() if largest_conductor and int(v[0]) > largest_conductor: break @@ -1681,7 +1653,7 @@ def _init_allgens(self, ftpdata, largest_conductor=0): def CremonaDatabase(name=None,mini=None,set_global=None): """ - Initializes the Cremona database with name ``name``. If ``name`` is + Initialize the Cremona database with name ``name``. If ``name`` is ``None`` it instead initializes large Cremona database (named 'cremona'), if available or default mini Cremona database (named 'cremona mini'). diff --git a/src/sage/databases/cubic_hecke_db.py b/src/sage/databases/cubic_hecke_db.py index 782d3c2f771..668af9abacc 100644 --- a/src/sage/databases/cubic_hecke_db.py +++ b/src/sage/databases/cubic_hecke_db.py @@ -117,7 +117,9 @@ def simplify(mat): d = mat.dict() if isinstance(B, CubicHeckeExtensionRing): # Laurent polynomial cannot be reconstructed from string - res = {k: {tuple(j): u.dict() for j, u in v.dict().items()} for k, v in d.items()} + res = {k: {tuple(j): u.monomial_coefficients() + for j, u in v.monomial_coefficients().items()} + for k, v in d.items()} else: res = {k: str(v) for k, v in d.items()} return res @@ -129,9 +131,9 @@ class CubicHeckeDataSection(Enum): The following choices are possible: - - ``basis`` -- list of basis elements - - ``reg_left_reprs`` -- data for the left regular representation - - ``reg_right_reprs`` -- data for the right regular representation + - ``basis`` -- list of basis elements + - ``reg_left_reprs`` -- data for the left regular representation + - ``reg_right_reprs`` -- data for the right regular representation - ``irr_reprs`` -- data for the split irreducible representations - ``markov_tr_cfs`` -- data for the coefficients of the formal Markov traces @@ -239,9 +241,7 @@ def read(self, section, variables=None, nstrands=4): - ``section`` -- instance of enum :class:`CubicHeckeDataSection` to select the data to be read in - OUTPUT: - - A dictionary containing the data corresponding to the section. + OUTPUT: a dictionary containing the data corresponding to the section EXAMPLES:: @@ -310,8 +310,6 @@ def read_matrix_representation(self, representation_type, gen_ind, nstrands, rin :class:`~sage.algebras.hecke_algebras.cubic_hecke_matrix_rep.RepresentationType` specifying the type of the representation - OUTPUT: - EXAMPLES:: sage: from sage.databases.cubic_hecke_db import CubicHeckeDataBase @@ -418,9 +416,7 @@ def braid_tietze(self, strands_embed=None): - ``strands_embed`` -- (optional) the number of strands of the braid if strands should be added - OUTPUT: - - A tuple representing the braid in Tietze form. + OUTPUT: a tuple representing the braid in Tietze form EXAMPLES:: @@ -660,14 +656,14 @@ class section(Enum): Enum for the different sections of file cache. The following choices are possible: - - ``matrix_representations`` -- file cache for representation matrices + - ``matrix_representations`` -- file cache for representation matrices of basis elements - - ``braid_images`` -- file cache for images of braids + - ``braid_images`` -- file cache for images of braids - ``basis_extensions`` -- file cache for a dynamical growing basis used in the case of cubic Hecke algebras on more than 4 strands - ``markov_trace`` -- file cache for intermediate results of long calculations in order to recover the results already obtained by - preboius attemps of calculation until the corresponding intermediate + previous attemps of calculation until the corresponding intermediate step EXAMPLES:: @@ -1291,6 +1287,7 @@ def read_basis(num_strands=3): -1], [2, -1, 2], [1, 2, -1, 2], [-1, 2, -1, 2]] return data[num_strands] + def read_irr(variables, num_strands=3): r""" Return precomputed data of Ivan Marin. @@ -1334,6 +1331,7 @@ def read_irr(variables, num_strands=3): 1/b, (1, 1): 1/b, (1, 2): a/b + b/c, (2, 2): 1/c}]]) return data[num_strands] + def read_regl(variables, num_strands=3): r""" Return precomputed data of Ivan Marin. @@ -1407,6 +1405,7 @@ def read_regl(variables, num_strands=3): (22, 6): 1/w, (22, 13): u/w, (22, 22): v/w, (23, 13): 1}]]) return data[num_strands] + def read_regr(variables, num_strands=3): r""" Return precomputed data of Ivan Marin. @@ -1497,7 +1496,6 @@ def read_markov(bas_ele, variables, num_strands=4): the coefficients - ``num_strands`` -- integer (default: 4); the number of strands - OUTPUT: A list of the coefficients. The i'th member corresponds to the i'th diff --git a/src/sage/databases/db_class_polynomials.py b/src/sage/databases/db_class_polynomials.py index dd436fe5db7..57acde7c05a 100644 --- a/src/sage/databases/db_class_polynomials.py +++ b/src/sage/databases/db_class_polynomials.py @@ -106,6 +106,7 @@ def __repr__(self): # None of the following are implemented yet. ###################################################### + class AtkinClassPolynomialDatabase(ClassPolynomialDatabase): """ The database of Atkin class polynomials. diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index cba955c68b3..811a190db8f 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -307,6 +307,8 @@ def mapping(sigma): FINDSTAT_FORM_FOOTER = '' ###################################################################### + + class FindStat(UniqueRepresentation, SageObject): r""" The Combinatorial Statistic Finder. @@ -354,16 +356,16 @@ def set_user(self, name=None, email=None): INPUT: - - ``name`` -- the name of the user. + - ``name`` -- the name of the user - - ``email`` -- an email address of the user. + - ``email`` -- an email address of the user This information is used when submitting a statistic with :meth:`FindStatStatistic.submit`. EXAMPLES:: - sage: findstat().set_user(name="Anonymous", email="invalid@org") + sage: findstat().set_user(name='Anonymous', email='invalid@org') .. NOTE:: @@ -383,7 +385,7 @@ def user_name(self): EXAMPLES:: - sage: findstat().set_user(name="Anonymous", email="invalid@org") + sage: findstat().set_user(name='Anonymous', email='invalid@org') sage: findstat().user_name() 'Anonymous' """ @@ -395,7 +397,7 @@ def user_email(self): EXAMPLES:: - sage: findstat().set_user(name="Anonymous", email="invalid@org") + sage: findstat().set_user(name='Anonymous', email='invalid@org') sage: findstat().user_email() 'invalid@org' """ @@ -438,6 +440,7 @@ def _get_json(url, **kwargs): return result raise ConnectionError(response.text) + def _post_json(url, data, **kwargs): """ Return the json response or raise an error. @@ -487,7 +490,6 @@ def _submit(args, url): ....: "CurrentAuthor": "", ....: "CurrentEmail": ""} sage: _submit(args, url) # optional -- webbrowser - """ f = tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False) verbose("Created temporary file %s" % f.name, caller_name='FindStat') @@ -514,11 +516,11 @@ def _data_to_str(data, domain, codomain=None): INPUT: - - ``data``, a list of lists of objects + - ``data`` -- list of lists of objects - - ``domain``, a :class:`FindStatCollection` + - ``domain`` -- :class:`FindStatCollection` - - ``codomain`` -- (optional), a :class:`FindStatCollection` or ``None`` + - ``codomain`` -- (optional) :class:`FindStatCollection` or ``None`` If ``codomain`` is ``None``, the values are treated as integers. @@ -567,13 +569,13 @@ def _data_from_iterable(iterable, mapping=False, domain=None, same size, or a single element and a single value. Every object must be a :class:`SageObject`. - - mapping -- (default: ``False``), ``False``, if the codomain is - ``Integer`` and ``True`` if it is a FindStat collection + - ``mapping`` -- boolean (default: ``False``); ``False``, if the codomain + is ``Integer`` and ``True`` if it is a FindStat collection - - domain -- (optional), a :class:`FindStatCollection`, if + - ``domain`` -- (default: ``None``) a :class:`FindStatCollection`, if ``None`` it is guessed from the iterable - - codomain -- (optional), a :class:`FindStatCollection`, if + - ``codomain`` -- (default: ``None``) a :class:`FindStatCollection`, if ``None`` it is guessed from the iterable TESTS:: @@ -682,8 +684,8 @@ def _data_from_function(function, domain): INPUT: - - ``function``, a callable - - ``domain``, a :class:`FindStatCollection` + - ``function`` -- a callable + - ``domain`` -- a :class:`FindStatCollection` If ``function`` returns the value ``None``, the pair is omitted. @@ -707,9 +709,9 @@ def _data_from_data(data, max_values): INPUT: - - ``data``, an iterable over pairs of lists of the same size + - ``data`` -- an iterable over pairs of lists of the same size - - ``max_values``, the maximal number of objects (and values) to + - ``max_values`` -- the maximal number of objects (and values) to return We assume that the number of elements in each pair weakly @@ -750,11 +752,11 @@ def _distribution_from_data(data, domain, max_values, generating_functions=False INPUT: - - ``data``, an iterable over pairs of lists of the same size + - ``data`` -- an iterable over pairs of lists of the same size - - ``domain``, a :class:`FindStatCollection` + - ``domain`` -- a :class:`FindStatCollection` - - ``max_values``, the maximal number of objects (and values) to + - ``max_values`` -- the maximal number of objects (and values) to return TESTS:: @@ -807,11 +809,11 @@ def _generating_functions_from_dict(gfs, style): INPUT: - - ``gfs``, a dictionary whose keys are the levels and whose values + - ``gfs`` -- dictionary whose keys are the levels and whose values are dictionaries from values to multiplicities - - ``style``, one of ``"dictionary"``, ``"list"`` or - ``"polynomial"`` + - ``style`` -- one of ``'dictionary'``, ``'list'`` or + ``'polynomial'`` .. SEEALSO:: @@ -922,9 +924,7 @@ def findstat(query=None, values=None, distribution=None, domain=None, collection, such as ``Permutations(3)``. The keyword arguments ``depth`` and ``max_values`` are passed to the finder. - OUTPUT: - - An instance of a :class:`FindStatStatistic`, represented by + OUTPUT: an instance of a :class:`FindStatStatistic`, represented by - the FindStat identifier together with its name, or @@ -1007,20 +1007,20 @@ def findstat(query=None, values=None, distribution=None, domain=None, sage: findstat("Cc0024") # optional -- internet Set of combinatorial statistics with domain Cc0024: Binary words in FindStat - sage: findstat(domain="Cores") # optional -- internet + sage: findstat(domain='Cores') # optional -- internet Set of combinatorial statistics with domain Cc0013: Cores in FindStat TESTS:: - sage: findstat("Permutations", lambda x: 1, depth="x") # optional -- internet + sage: findstat("Permutations", lambda x: 1, depth='x') # optional -- internet Traceback (most recent call last): ... - ValueError: E021: Depth should be a non-negative integer at most 9, but is x. + ValueError: E021: Depth should be a nonnegative integer at most 9, but is x. sage: findstat("Permutations", lambda x: 1, depth=100) # optional -- internet Traceback (most recent call last): ... - ValueError: E021: Depth should be a non-negative integer at most 9, but is 100. + ValueError: E021: Depth should be a nonnegative integer at most 9, but is 100. sage: S = Permutation sage: findstat([(S([1,2]), 1), ([S([1,3,2]), S([1,2])], [2,3])]) # optional -- internet @@ -1042,7 +1042,7 @@ def findstat(query=None, values=None, distribution=None, domain=None, max_values = int(max_values) assert 0 <= max_values <= FINDSTAT_MAX_VALUES except (ValueError, AssertionError): - raise ValueError("the maximal number of values for a FindStat query must be a non-negative integer less than or equal to %i" % FINDSTAT_MAX_VALUES) + raise ValueError("the maximal number of values for a FindStat query must be a nonnegative integer less than or equal to %i" % FINDSTAT_MAX_VALUES) check_collection = True @@ -1135,18 +1135,17 @@ def findmap(*args, **kwargs): ``distribution``, ``depth`` and ``max_values``. They have the following meanings: - - ``depth`` -- (default ``FINDSTAT_DEFAULT_DEPTH``), a - non-negative integer, specifying how many maps to apply to - generate the given map. + - ``depth`` -- nonnegative integer (default: ``FINDSTAT_DEFAULT_DEPTH``); + specifying how many maps to apply to generate the given map - - ``max_values`` -- (default ``FINDSTAT_MAX_VALUES``), an integer - specifying how many values are sent to the finder. + - ``max_values`` -- integer (default: ``FINDSTAT_MAX_VALUES``); specifying + how many values are sent to the finder - - ``domain``, ``codomain``, an integer or string of the form + - ``domain``, ``codomain`` -- integer or string of the form ``Cc1234``, designates the domain and codomain of the sought - for maps. + for maps - - ``values``, ``distribution``, data specifying the values or + - ``values``, ``distribution`` -- data specifying the values or distribution of values of the sought for maps. The keyword arguments ``depth`` and ``max_values`` are passed to the finder. The data may be specified in one of the following @@ -1242,7 +1241,7 @@ def findmap(*args, **kwargs): sage: findmap("Cc0024") # optional -- internet Set of combinatorial maps with domain Cc0024: Binary words used by FindStat - sage: findmap(codomain="Cores") # optional -- internet + sage: findmap(codomain='Cores') # optional -- internet Set of combinatorial maps with codomain Cc0013: Cores used by FindStat """ if len(args) > 3: @@ -1265,7 +1264,7 @@ def findmap(*args, **kwargs): max_values = int(max_values) assert 0 <= max_values <= FINDSTAT_MAX_VALUES except (ValueError, AssertionError): - raise ValueError("the maximal number of values for a FindStat query must be a non-negative integer less than or equal to %i" % FINDSTAT_MAX_VALUES) + raise ValueError("the maximal number of values for a FindStat query must be a nonnegative integer less than or equal to %i" % FINDSTAT_MAX_VALUES) check_collection = True @@ -1399,13 +1398,13 @@ def __init__(self, id, data=None, function=None): INPUT: - - ``id``, a padded identifier, with number 0 reserved for new + - ``id`` -- a padded identifier, with number 0 reserved for new statistics or maps. - - ``data``, a dictionary with "Description", "Code", etc. + - ``data`` -- dictionary with "Description", "Code", etc. - - ``function`` -- (optional), a callable implementing the - statistic or map, or ``None``. + - ``function`` -- (optional) a callable implementing the + statistic or map, or ``None`` ``data`` should be provided if and only if ``id`` refers to a new statistic or map (with identifier 0). @@ -1569,9 +1568,7 @@ def id(self): r""" Return the FindStat identifier of the statistic or map. - OUTPUT: - - The FindStat identifier of the statistic or map, as an integer. + OUTPUT: the FindStat identifier of the statistic or map, as an integer EXAMPLES:: @@ -1584,9 +1581,7 @@ def id_str(self): r""" Return the FindStat identifier of the statistic or map. - OUTPUT: - - The FindStat identifier of the statistic or map, as a string. + OUTPUT: the FindStat identifier of the statistic or map, as a string EXAMPLES:: @@ -1618,9 +1613,7 @@ def description(self): r""" Return the description of the statistic or map. - OUTPUT: - - A string. For statistics, the first line is used as name. + OUTPUT: string; for statistics, the first line is used as name EXAMPLES:: @@ -1635,8 +1628,8 @@ def set_description(self, value): INPUT: - - a string -- for statistics, this is the name of the - statistic followed by its description on a separate line. + - ``value`` -- string; for statistics, this is the name of the + statistic followed by its description on a separate line This information is used when submitting the statistic or map with :meth:`submit`. @@ -1729,8 +1722,8 @@ def set_references_raw(self, value): INPUT: - - a string -- each reference should be on a single line, and - consist of one or more links to the same item. + - ``value`` -- string; each reference should be on a single line, and + consist of one or more links to the same item FindStat will automatically resolve the links, if possible. A complete list of supported services can be found at @@ -1755,9 +1748,7 @@ def sage_code(self): r""" Return the Sage code associated with the statistic or map. - OUTPUT: - - An empty string or a string of the form:: + OUTPUT: an empty string or a string of the form:: def statistic(x): ... @@ -1781,7 +1772,8 @@ def set_sage_code(self, value): INPUT: - - a string -- SageMath code producing the values of the statistic or map. + - ``value`` -- string; SageMath code producing the values of the + statistic or map Contributors are encouraged to submit code for statistics using :meth:`FindStatStatistic.set_code`. Modifying the @@ -1804,6 +1796,8 @@ def statistic(x): ###################################################################### # statistics ###################################################################### + + class FindStatCombinatorialStatistic(SageObject): """ A class providing methods to retrieve the first terms of a statistic. @@ -1856,12 +1850,10 @@ def _first_terms_raw(self, max_values): INPUT: - - ``max_values``, an integer determining how many terms to + - ``max_values`` -- integer determining how many terms to return at most - OUTPUT: - - A list of ``(string, value)`` pairs. + OUTPUT: list of ``(string, value)`` pairs This method is overridden in :class:`FindStatStatisticQuery`. @@ -1967,7 +1959,7 @@ def _generating_functions_dict(self, del gfs[lvl] return gfs - def generating_functions(self, style="polynomial", + def generating_functions(self, style='polynomial', max_values=FINDSTAT_MAX_SUBMISSION_VALUES): r""" Return the generating functions of the statistic as a dictionary. @@ -1980,19 +1972,19 @@ def generating_functions(self, style="polynomial", INPUT: - - a string -- (default:"polynomial") can be - "polynomial", "dictionary", or "list". + - ``style`` -- string (default: ``'polynomial'``); can be + ``'polynomial'``, ``'dictionary'``, or ``'list'`` OUTPUT: - - if ``style`` is ``"polynomial"``, the generating function is - returned as a polynomial. + - if ``style`` is ``'polynomial'``, the generating function is + returned as a polynomial - - if ``style`` is ``"dictionary"``, the generating function is + - if ``style`` is ``'dictionary'``, the generating function is returned as a dictionary representing the monomials of the - generating function. + generating function - - if ``style`` is ``"list"``, the generating function is + - if ``style`` is ``'list'``, the generating function is returned as a list of coefficients of the generating function. In this case, leading and trailing zeros are omitted. @@ -2006,13 +1998,13 @@ def generating_functions(self, style="polynomial", 6: q^3 + 3*q^2 + 6*q + 5, 8: q^6 + 4*q^5 + 10*q^4 + 20*q^3 + 28*q^2 + 28*q + 14} - sage: st.generating_functions(style="dictionary") # optional -- internet + sage: st.generating_functions(style='dictionary') # optional -- internet {2: {0: 1}, 4: {0: 2, 1: 1}, 6: {0: 5, 1: 6, 2: 3, 3: 1}, 8: {0: 14, 1: 28, 2: 28, 3: 20, 4: 10, 5: 4, 6: 1}} - sage: st.generating_functions(style="list") # optional -- internet + sage: st.generating_functions(style='list') # optional -- internet {2: [1], 4: [2, 1], 6: [5, 6, 3, 1], 8: [14, 28, 28, 20, 10, 4, 1]} TESTS:: @@ -2045,18 +2037,16 @@ def oeis_search(self, search_size=32, verbose=True): INPUT: - - ``search_size`` (default:32) the number of integers in the + - ``search_size`` -- (default: 32) the number of integers in the sequence. If this is chosen too big, the OEIS result may be corrupted. - - ``verbose`` (default: ``True``) if true, some information about - the search are printed. - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``); if ``True``, some + information about the search are printed - - a tuple of OEIS sequences, see - :meth:`sage.databases.oeis.OEIS.find_by_description` for more - information. + OUTPUT: a tuple of OEIS sequences, see + :meth:`sage.databases.oeis.OEIS.find_by_description` for more + information EXAMPLES:: @@ -2067,7 +2057,7 @@ def oeis_search(self, search_size=32, verbose=True): 0: A067311: Triangle read by rows: T(n,k) gives number of ways of arranging n chords on a circle with k simple intersections ... """ from sage.databases.oeis import oeis - gen_funcs = self.generating_functions(style="list") + gen_funcs = self.generating_functions(style='list') OEIS_string = "" keys = sorted(gen_funcs.keys()) @@ -2139,7 +2129,7 @@ def __init__(self, parent, id): - ``parent`` -- :class:`FindStatStatistics` - - ``id`` -- the (padded) FindStat identifier of the statistic. + - ``id`` -- the (padded) FindStat identifier of the statistic EXAMPLES:: @@ -2221,7 +2211,7 @@ def _fetch_data(self): included = _get_json(url)["included"] # slightly simplify the representation - data = {key: val for key, val in included["Statistics"][self.id_str()].items()} + data = dict(included["Statistics"][self.id_str()].items()) # we replace the list of identifiers in Bibliography with the dictionary data["Bibliography"] = included["References"] return data @@ -2250,9 +2240,9 @@ def set_first_terms(self, values): INPUT: - - a list of pairs of the form ``(object, value)`` where + - ``values`` -- list of pairs of the form ``(object, value)`` where ``object`` is a Sage object representing an element of the - appropriate collection and ``value`` is an integer. + appropriate collection and ``value`` is an integer This information is used when submitting the statistic with :meth:`submit`. @@ -2286,9 +2276,9 @@ def code(self): r""" Return the code associated with the statistic or map. - OUTPUT: + OUTPUT: string - A string. Contributors are encouraged to submit Sage code in the form:: + Contributors are encouraged to submit Sage code in the form:: def statistic(x): ... @@ -2315,7 +2305,7 @@ def set_code(self, value): INPUT: - - a string -- code producing the values of the statistic. + - ``value`` -- string; code producing the values of the statistic Contributors are encouraged to submit SageMath code in the form:: @@ -2408,6 +2398,8 @@ def info(self): _all_statistics = {} + + class FindStatStatistics(UniqueRepresentation, Parent): r""" The class of FindStat statistics. @@ -2448,7 +2440,7 @@ def _element_constructor_(self, id): INPUT: - - ``id`` -- a string containing the FindStat identifier of + - ``id`` -- string containing the FindStat identifier of the statistic, or the corresponding integer EXAMPLES:: @@ -2520,7 +2512,7 @@ def _an_element_(self): EXAMPLES:: - sage: findstat(domain="Permutations").an_element() # optional -- internet + sage: findstat(domain='Permutations').an_element() # optional -- internet St000001: The number of reduced words for a permutation. """ try: @@ -2731,7 +2723,7 @@ def __repr__(self): def __getitem__(self, i): """ - Return the t-th result in the query. + Return the `t`-th result in the query. EXAMPLES:: @@ -2755,6 +2747,7 @@ def __len__(self): """ return len(self._result) + class FindStatCompoundStatistic(Element, FindStatCombinatorialStatistic): def __init__(self, id, domain=None, check=True): """ @@ -2933,13 +2926,13 @@ def __init__(self, matching_statistic, offset, quality, domain=None): INPUT: - - ``matching_statistic``, a compound statistic identifier + - ``matching_statistic`` -- a compound statistic identifier - - ``offset``, the offset of the values, as provided by FindStat + - ``offset`` -- the offset of the values, as provided by FindStat - - ``quality``, the quality of the match, as provided by FindStat + - ``quality`` -- the quality of the match, as provided by FindStat - - ``domain`` -- (optional), the domain of the compound statistic + - ``domain`` -- (optional) the domain of the compound statistic EXAMPLES:: @@ -2997,7 +2990,6 @@ def quality(self): sage: r = FindStatMatchingStatistic("St000042oMp00116", 1, [17, 83]) # optional -- internet sage: r.quality() # optional -- internet [17, 83] - """ return self._quality[:] @@ -3052,6 +3044,8 @@ def info(self): ###################################################################### # maps ###################################################################### + + class FindStatCombinatorialMap(SageObject): """ A class serving as common ancestor of :class:`FindStatStatistic` @@ -3059,6 +3053,7 @@ class FindStatCombinatorialMap(SageObject): """ pass + class FindStatMap(Element, FindStatFunction, FindStatCombinatorialMap, @@ -3238,9 +3233,7 @@ def codomain(self): r""" Return the FindStat collection which is the codomain of the map. - OUTPUT: - - The codomain of the map as a :class:`FindStatCollection`. + OUTPUT: the codomain of the map as a :class:`FindStatCollection` EXAMPLES:: @@ -3254,9 +3247,7 @@ def properties_raw(self): r""" Return the properties of the map. - OUTPUT: - - The properties as a string. + OUTPUT: the properties as a string EXAMPLES:: @@ -3293,7 +3284,7 @@ def set_name(self, value): INPUT: - - a string -- the new name of the map. + - ``value`` -- string; the new name of the map This information is used when submitting the map with :meth:`submit`. @@ -3325,6 +3316,8 @@ def info(self): _all_maps = {} + + class FindStatMaps(UniqueRepresentation, Parent): r""" The class of FindStat maps. @@ -3340,7 +3333,7 @@ class FindStatMaps(UniqueRepresentation, Parent): sage: ccs = sorted(FindStatCollections())[:3] # optional -- internet sage: for cc_dom in ccs: # optional -- internet ....: for cc_codom in ccs: - ....: print(cc_dom.name(style="plural") + " -> " + cc_codom.name(style="plural")) + ....: print(cc_dom.name(style='plural') + " -> " + cc_codom.name(style='plural')) ....: try: ....: print(" " + next(iter(FindStatMaps(cc_dom, cc_codom))).name()) ....: except StopIteration: @@ -3388,7 +3381,7 @@ def _element_constructor_(self, id): INPUT: - - ``id`` -- a string containing the FindStat identifier of + - ``id`` -- string containing the FindStat identifier of the map, or an integer giving its id EXAMPLES:: @@ -3468,7 +3461,7 @@ def _an_element_(self): EXAMPLES:: - sage: findmap(domain="Dyck paths", codomain="Posets").an_element() # optional -- internet + sage: findmap(domain="Dyck paths", codomain='Posets').an_element() # optional -- internet Mp00232: parallelogram poset """ try: @@ -3489,7 +3482,7 @@ def __init__(self, data=None, values_of=None, distribution_of=None, depth=FINDSTAT_DEFAULT_DEPTH, debug=False): """ - Initialize a query for FindStat (compound) maps + Initialize a query for FindStat (compound) maps. INPUT: @@ -3619,7 +3612,7 @@ def __repr__(self): def __getitem__(self, i): """ - Return the i-th result in the query. + Return the `i`-th result in the query. EXAMPLES:: @@ -3643,6 +3636,7 @@ def __len__(self): """ return len(self._result) + class FindStatCompoundMap(Element, FindStatCombinatorialMap): def __init__(self, id, domain=None, codomain=None, check=True): """ @@ -3747,7 +3741,7 @@ def __call__(self, elt): def __getitem__(self, i): """ - Return the i-th map in the compound map. + Return the `i`-th map in the compound map. EXAMPLES:: @@ -3835,11 +3829,11 @@ def __init__(self, matching_map, quality, domain=None, codomain=None): INPUT: - - ``matching_map``, a compound map identifier + - ``matching_map`` -- a compound map identifier - - ``quality``, the quality of the match, as provided by FindStat + - ``quality`` -- the quality of the match, as provided by FindStat - - ``domain`` -- (optional), the domain of the compound map + - ``domain`` -- (optional) the domain of the compound map - ``codomain`` -- (optional), the codomain of the compound map @@ -3904,15 +3898,13 @@ def info(self): # helper for generation of CartanTypes def _finite_irreducible_cartan_types_by_rank(n): """ - Return the Cartan types of rank n. + Return the Cartan types of rank `n`. INPUT: - - n -- an integer. - - OUTPUT: + - ``n`` -- integer - The list of Cartan types of rank n. + OUTPUT: the list of Cartan types of rank `n` TESTS:: @@ -3936,24 +3928,23 @@ def _finite_irreducible_cartan_types_by_rank(n): return cartan_types # helper for generation of PlanePartitions + + def _plane_partitions_by_size_aux(n, outer=None): """ Iterate over the plane partitions with `n` boxes, as lists. INPUT: - - n -- an integer. - - OUTPUT: + - ``n`` -- integer - The plane partitions with `n` boxes as lists. + OUTPUT: the plane partitions with `n` boxes as lists TESTS:: sage: from sage.databases.findstat import _plane_partitions_by_size_aux sage: list(_plane_partitions_by_size_aux(3)) [[[1], [1], [1]], [[2], [1]], [[1, 1], [1]], [[3]], [[2, 1]], [[1, 1, 1]]] - """ if n == 0: yield [] @@ -3966,6 +3957,7 @@ def _plane_partitions_by_size_aux(n, outer=None): pp = [la] + pp yield pp + def _plane_partitions_by_size(n): """ Iterate over the plane partitions with `n` boxes. @@ -3976,11 +3968,9 @@ def _plane_partitions_by_size(n): INPUT: - - n -- an integer. - - OUTPUT: + - ``n`` -- integer - The plane partitions with `n` boxes. + OUTPUT: the plane partitions with `n` boxes TESTS:: @@ -3992,38 +3982,37 @@ def _plane_partitions_by_size(n): Plane partition [[3]], Plane partition [[2, 1]], Plane partition [[1, 1, 1]]] - """ for pp in _plane_partitions_by_size_aux(n): yield PlanePartition(pp) # helper for generation of Lattices + + def _finite_lattices(n): """ Iterate over the lattices with `n` elements. INPUT: - - n -- an integer. - - OUTPUT: + - ``n`` -- integer - The lattices with `n` elements. + OUTPUT: the lattices with `n` elements TESTS:: sage: from sage.databases.findstat import _finite_lattices - sage: [L.cover_relations() for L in _finite_lattices(4)] - [[['bottom', 0], ['bottom', 1], [0, 'top'], [1, 'top']], - [['bottom', 0], [0, 1], [1, 'top']]] - + sage: sorted((L.cover_relations() for L in _finite_lattices(4)), + ....: key=len) + [[['bottom', 0], [0, 1], [1, 'top']], + [['bottom', 0], ['bottom', 1], [0, 'top'], [1, 'top']]] """ if n <= 2: for P in Posets(n): if P.is_lattice(): yield LatticePoset(P) else: - for P in Posets(n-2): + for P in Posets(n - 2): Q = P.with_bounds() if Q.is_lattice(): yield LatticePoset(Q) @@ -4102,11 +4091,11 @@ def __init__(self, parent, id, data, sageconstructor_overridden): INPUT: - - ``parent`` -- :class:`FindStatCollections`. + - ``parent`` -- :class:`FindStatCollections` - - ``id`` -- the (padded) FindStat identifier of the collection. + - ``id`` -- the (padded) FindStat identifier of the collection - - ``data`` -- a dictionary containing the properties of the + - ``data`` -- dictionary containing the properties of the collection, such as its name, the corresponding class in sage, and so on. @@ -4267,12 +4256,10 @@ def in_range(self, element): INPUT: - - ``element`` -- a Sage object that belongs to the collection. - - OUTPUT: + - ``element`` -- a Sage object that belongs to the collection - ``True``, if ``element`` is used by the FindStat search - engine, and ``False`` if it is ignored. + OUTPUT: ``True``, if ``element`` is used by the FindStat search + engine, and ``False`` if it is ignored EXAMPLES:: @@ -4365,15 +4352,13 @@ def first_terms(self, function, level=None): g = (x for x in self._sageconstructor_overridden if self.element_level(x) == level) - return lazy_list(((x, function(x)) for x in g)) + return lazy_list((x, function(x)) for x in g) def id(self): r""" Return the FindStat identifier of the collection. - OUTPUT: - - The FindStat identifier of the collection as an integer. + OUTPUT: the FindStat identifier of the collection as an integer EXAMPLES:: @@ -4388,9 +4373,7 @@ def id_str(self): r""" Return the FindStat identifier of the collection. - OUTPUT: - - The FindStat identifier of the collection as a string. + OUTPUT: the FindStat identifier of the collection as a string EXAMPLES:: @@ -4465,9 +4448,7 @@ def _repr_(self): r""" Return the representation of the FindStat collection. - OUTPUT: - - The representation, including the identifier and the name. + OUTPUT: the representation, including the identifier and the name EXAMPLES:: @@ -4479,18 +4460,16 @@ def _repr_(self): return "a subset of %s: %s" % (self.id_str(), self._data["NamePlural"]) return "%s: %s" % (self.id_str(), self._data["NamePlural"]) - def name(self, style="singular"): + def name(self, style='singular'): r""" Return the name of the FindStat collection. INPUT: - - a string -- (default:"singular") can be - "singular", or "plural". - - OUTPUT: + - ``style`` -- string (default: ``'singular'``); can be + ``'singular'``, or ``'plural'`` - The name of the FindStat collection, in singular or in plural. + OUTPUT: the name of the FindStat collection, in singular or in plural EXAMPLES:: @@ -4498,7 +4477,7 @@ def name(self, style="singular"): sage: FindStatCollection("Binary trees").name() # optional -- internet 'Binary tree' - sage: FindStatCollection("Binary trees").name(style="plural") # optional -- internet + sage: FindStatCollection("Binary trees").name(style='plural') # optional -- internet 'Binary trees' """ if style == "singular": @@ -4757,7 +4736,7 @@ def _element_constructor_(self, entry): INPUT: - see :class:`FindStatCollection`. + See :class:`FindStatCollection`. TESTS: diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py index 23a7cbd545f..38e8ce47b54 100644 --- a/src/sage/databases/jones.py +++ b/src/sage/databases/jones.py @@ -129,12 +129,10 @@ def _init(self, path): INPUT: - - - ``path`` -- (default works on William Stein install.) - path must be the path to Jones's Number_Fields directory - http://hobbes.la.asu.edu/Number_Fields These files should have - been downloaded using wget. - + - ``path`` -- (default: works on William Stein install) + path must be the path to Jones's Number_Fields directory + (http://hobbes.la.asu.edu/Number_Fields); these files should have + been downloaded using wget EXAMPLES: This is how to create the database from scratch, assuming that the number fields are in the default directory above: From a @@ -171,12 +169,12 @@ def unramified_outside(self, S, d=None, var='a'): INPUT: - - ``S`` -- list or set of primes, or a single prime + - ``S`` -- list or set of primes, or a single prime - - ``d`` -- None (default, in which case all fields of degree <= 6 are returned) - or a positive integer giving the degree of the number fields returned. + - ``d`` -- ``None`` (default, in which case all fields of degree <= 6 are returned) + or a positive integer giving the degree of the number fields returned - - ``var`` -- the name used for the generator of the number fields (default 'a'). + - ``var`` -- the name used for the generator of the number fields (default: ``'a'``) EXAMPLES:: @@ -211,9 +209,9 @@ def get(self, S, var='a'): INPUT: - - ``S`` -- list or set of primes, or a single prime + - ``S`` -- list or set of primes, or a single prime - - ``var`` -- the name used for the generator of the number fields (default 'a'). + - ``var`` -- the name used for the generator of the number fields (default: ``'a'``) EXAMPLES:: @@ -248,12 +246,12 @@ def ramified_at(self, S, d=None, var='a'): INPUT: - - ``S`` -- list or set of primes + - ``S`` -- list or set of primes - - ``d`` -- None (default, in which case all fields of degree <= 6 are returned) - or a positive integer giving the degree of the number fields returned. + - ``d`` -- ``None`` (default, in which case all fields of degree <= 6 are returned) + or a positive integer giving the degree of the number fields returned - - ``var`` -- the name used for the generator of the number fields (default 'a'). + - ``var`` -- the name used for the generator of the number fields (default: ``'a'``) EXAMPLES:: diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index dc21575d779..89fd66c6078 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -44,6 +44,7 @@ columns_white_list = ['knot_atlas_anon', 'knotilus_page_anon'] columns_black_list = ['homfly_polynomial_old'] + class KnotInfoColumnTypes(Enum): r""" Enum class to specify if a column from the table of knots and links provided @@ -334,7 +335,7 @@ def diagram_url(self, fname, single=False): #---------------------------------------------------------------------------------------------------------------------------- class KnotInfoDataBase(SageObject, UniqueRepresentation): r""" - Database interface to KnotInfo + Database interface to KnotInfo. The original data are obtained from KnotInfo web-page (URL see the example below). In order to have these data installed during the build process as @@ -385,8 +386,8 @@ def create_filecache(self, force=False): INPUT: - - ``force`` -- optional boolean. If set to ``True`` the existing - file-cache is overwritten + - ``force`` -- boolean (default: ``False``); if set to ``True`` the + existing file-cache is overwritten EXAMPLES:: @@ -658,11 +659,9 @@ def columns(self): @cached_method def read_column_dict(self): r""" - Read the dictionary for the column names from the according sobj-file - - OUTPUT: + Read the dictionary for the column names from the according sobj-file. - A python dictionary containing the column names and types + OUTPUT: a Python dictionary containing the column names and types EXAMPLES:: @@ -711,12 +710,10 @@ def read_row_dict(self): @cached_method def row_names(self): r""" - Return a dictionary to obtain the original name to a row_dict key + Return a dictionary to obtain the original name to a row_dict key. - OUTPUT: - - A python dictionary containing the names of the knots and links - together with their original names from the database, + OUTPUT: a Python dictionary containing the names of the knots and links + together with their original names from the database EXAMPLES:: @@ -737,9 +734,7 @@ def read_num_knots(self): Read the number of knots contained in the database (without proper links) from the according sobj-file. - OUTPUT: - - Integer + OUTPUT: integer EXAMPLES:: @@ -758,16 +753,14 @@ def read_num_knots(self): @cached_method def read(self, column): r""" - Access a column of KnotInfo / LinkInfo + Access a column of KnotInfo / LinkInfo. INPUT: - ``column`` -- instance of enum :class:`KnotInfoColumns` to select the data to be read in - OUTPUT: - - A python list containing the data corresponding to the column. + OUTPUT: a Python list containing the data corresponding to the column EXAMPLES:: @@ -800,7 +793,7 @@ def _test_database(self, **options): sage: from sage.databases.knotinfo_db import KnotInfoDataBase sage: ki_db = KnotInfoDataBase() - sage: TestSuite(ki_db).run() # long time indirect doctest + sage: TestSuite(ki_db).run() # optional - database_knotinfo, long time, indirect doctest """ from sage.knots.knotinfo import KnotInfo from sage.misc.misc import some_tuples @@ -845,6 +838,8 @@ def _test_database(self, **options): 'fibered': ['Fibered', KnotInfoColumnTypes.OnlyKnots], 'unoriented': ['Unoriented', KnotInfoColumnTypes.OnlyLinks], 'symmetry_type': ['Symmetry Type', KnotInfoColumnTypes.OnlyKnots], + 'geometric_type': ['Geometric Type', KnotInfoColumnTypes.OnlyKnots], + 'cosmetic_crossing': ['Cosmetic Crossing', KnotInfoColumnTypes.OnlyKnots], 'width': ['Width', KnotInfoColumnTypes.OnlyKnots], 'arc_notation': ['Arc Notation', KnotInfoColumnTypes.OnlyLinks], 'dt_code': ['DT code', KnotInfoColumnTypes.OnlyLinks] @@ -1026,6 +1021,18 @@ def _test_database(self, **options): 'reversible', 'reversible' ], + dc.geometric_type: [ + '', + 'torus knot T(2,3)', + 'hyperbolic', + 'torus knot T(2,5)', + 'hyperbolic', + 'hyperbolic', + 'hyperbolic', + 'hyperbolic', + 'torus knot T(2,7)', + 'hyperbolic'], + dc.cosmetic_crossing: ['', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'], dc.homfly_polynomial: [ '', '(2*v^2-v^4)+v^2*z^2', diff --git a/src/sage/databases/odlyzko.py b/src/sage/databases/odlyzko.py index 510edb4a8f6..1e19fda8619 100644 --- a/src/sage/databases/odlyzko.py +++ b/src/sage/databases/odlyzko.py @@ -31,6 +31,7 @@ from sage.misc.persist import load from sage.env import SAGE_SHARE + def zeta_zeros(): r""" List of the imaginary parts of the first 2,001,052 zeros of the diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 03caa9cc36c..dec5cabd8a4 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -167,11 +167,9 @@ def _fetch(url): INPUT: - - ``url`` -- a string corresponding to the URL to be fetched. + - ``url`` -- string corresponding to the URL to be fetched - OUTPUT: - - - a string representing the fetched web page. + OUTPUT: string representing the fetched web page TESTS:: @@ -198,11 +196,9 @@ def _urls(html_string): INPUT: - - ``html_string`` -- a string representing some HTML code. - - OUTPUT: + - ``html_string`` -- string representing some HTML code - - a list of (string) URLs contained in ``html_string``. + OUTPUT: list of (string) URLs contained in ``html_string`` EXAMPLES:: @@ -398,18 +394,15 @@ def __repr__(self) -> str: def find_by_id(self, ident, fetch=False): r""" - INPUT: - - ``ident`` -- a string representing the A-number of the sequence - or an integer representing its number. + - ``ident`` -- string representing the A-number of the sequence + or an integer representing its number - - ``fetch`` -- (bool, default: ``False``) whether to force fetching the - content of the sequence on the internet. + - ``fetch`` -- boolean (default: ``False``); whether to force fetching the + content of the sequence on the internet - OUTPUT: - - - The OEIS sequence whose A-number or number corresponds to ``ident``. + OUTPUT: the OEIS sequence whose A-number or number corresponds to ``ident`` EXAMPLES:: @@ -426,15 +419,12 @@ def find_by_id(self, ident, fetch=False): def find_by_entry(self, entry): r""" - INPUT: - - ``entry`` -- a string corresponding to an entry in the internal format - of the OEIS. + - ``entry`` -- string corresponding to an entry in the internal format + of the OEIS - OUTPUT: - - - The corresponding OEIS sequence. + OUTPUT: the corresponding OEIS sequence EXAMPLES:: @@ -454,7 +444,7 @@ def find_by_description(self, description, max_results=3, first_result=0): INPUT: - - ``description`` -- (string) the description the searched sequences. + - ``description`` -- string; the description the searched sequences - ``max_results`` -- (integer, default: 3) the maximum number of results we want. In any case, the on-line encyclopedia will not return more @@ -507,20 +497,20 @@ def find_by_subsequence(self, subsequence, max_results=3, first_result=0): INPUT: - - ``subsequence`` -- a list or tuple of integers. + - ``subsequence`` -- list or tuple of integers - - ``max_results`` -- (integer, default: 3), the maximum of results requested. + - ``max_results`` -- integer (default: 3); the maximum of results requested - - ``first_result`` -- (integer, default: 0) allow to skip the + - ``first_result`` -- integer (default: 0); allow to skip the ``first_result`` first results in the search, to go further. This is useful if you are looking for a sequence that may appear after the 100 first found sequences. OUTPUT: - - a tuple (with fancy formatting) of at most ``max_results`` OEIS - sequences. Those sequences can be used without the need to fetch the - database again. + A tuple (with fancy formatting) of at most ``max_results`` OEIS + sequences. Those sequences can be used without the need to fetch the + database again. EXAMPLES:: @@ -552,14 +542,12 @@ def _imaginary_entry(self, ident='A999999', keywords=''): INPUT: - - ``ident`` -- a string representing the A-number of the sequence. + - ``ident`` -- string representing the A-number of the sequence - - ``keywords`` -- a string corresponding to the keyword field of the - sequence. + - ``keywords`` -- string corresponding to the keyword field of the + sequence - OUTPUT: - - - a string representing the entry of the sequence. + OUTPUT: string representing the entry of the sequence TESTS:: @@ -570,7 +558,6 @@ def _imaginary_entry(self, ident='A999999', keywords=''): sage: s = oeis.find_by_entry(entry=oeis._imaginary_entry(ident='A999998', keywords=keywords)) sage: ','.join(s.keywords()) == keywords True - """ return ('%I ' + ident + ' M9999 N9999\n' '%S ' + ident + ' 1,1,1,1,2,1,1,1,\n' @@ -612,14 +599,12 @@ def _imaginary_sequence(self, ident='A999999', keywords='sign,easy'): INPUT: - - ``ident`` -- a string representing the A-number of the sequence. + - ``ident`` -- string representing the A-number of the sequence - - ``keywords`` -- string (default: 'sign,easy'), a list of words - separated by commas. + - ``keywords`` -- string (default: ``'sign,easy'``); a list of words + separated by commas - OUTPUT: - - - OEIS sequence. + OUTPUT: OEIS sequence TESTS:: @@ -689,8 +674,8 @@ def __init__(self, ident): INPUT: - - ``ident`` -- a string representing the A-number of the sequence or an - integer representing its number. + - ``ident`` -- string representing the A-number of the sequence or an + integer representing its number TESTS:: @@ -754,7 +739,7 @@ def id(self, format='A'): INPUT: - - ``format`` -- (string, default: 'A'). + - ``format`` -- string (default: ``'A'``) OUTPUT: @@ -791,9 +776,7 @@ def __hash__(self): This method allows unique representation of OEIS sequences. - OUTPUT: - - - Python `int`. + OUTPUT: Python integer EXAMPLES:: @@ -825,9 +808,7 @@ def raw_entry(self): The raw entry is fetched online if needed. - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -856,9 +837,7 @@ def name(self) -> str: r""" Return the name of the sequence ``self``. - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -920,9 +899,7 @@ def offsets(self): from 1) whose absolute value is greater than 1. This is set to 1 if all the terms are 0 or +-1. - OUTPUT: - - - tuple of two elements. + OUTPUT: tuple of two elements EXAMPLES:: @@ -947,9 +924,7 @@ def author(self): r""" Return the author of the sequence in the encyclopedia. - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -971,9 +946,7 @@ def keywords(self, warn=True): r""" Return the keywords associated to the sequence ``self``. - OUTPUT: - - - tuple of strings. + OUTPUT: tuple of strings EXAMPLES:: @@ -1179,7 +1152,6 @@ def is_finite(self): sage: s = oeis._imaginary_sequence(ident='A999993', keywords='nonn,finit') sage: s.is_finite() True - """ if 'finit' in self.keywords() or 'full' in self.keywords(): return True @@ -1237,13 +1209,11 @@ def first_terms(self, number=None): INPUT: - - ``number`` -- (integer or ``None``, default: ``None``) the number of + - ``number`` -- integer or ``None`` (default); the number of terms returned (if less than the number of available terms). When set - to None, returns all the known terms. - - OUTPUT: + to ``None``, returns all the known terms. - - tuple of integers. + OUTPUT: tuple of integers EXAMPLES:: @@ -1273,9 +1243,7 @@ def _repr_(self): r""" Print the sequence number and a short summary of this sequence. - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -1297,11 +1265,9 @@ def __call__(self, k): INPUT: - - ``k`` -- integer. + - ``k`` -- integer - OUTPUT: - - - integer. + OUTPUT: integer .. NOTE:: @@ -1354,18 +1320,16 @@ def __call__(self, k): def __getitem__(self, i): r""" - Return the ``i``th element of sequence ``self``, viewed as a tuple. + Return the `i`-th element of sequence ``self``, viewed as a tuple. The first element appearing in the sequence ``self``corresponds to ``self[0]``. Do not confuse with calling ``self(k)``. INPUT: - - ``i`` -- integer. + - ``i`` -- integer - OUTPUT: - - - integer. + OUTPUT: integer EXAMPLES:: @@ -1395,9 +1359,7 @@ def __iter__(self): those first terms are exhausted and the real associated sequence still have terms to produce. - OUTPUT: - - - integer. + OUTPUT: integer EXAMPLES:: @@ -1498,12 +1460,12 @@ def links(self, browse=None, format='guess'): INPUT: - - ``browse`` -- an integer, a list of integers, or the word 'all' - (default: ``None``): which links to open in a web browser. + - ``browse`` -- integer; a list of integers, or the word 'all' + (default: ``None``) which links to open in a web browser - - ``format`` -- string (default: 'guess'): how to display the links. + - ``format`` -- string (default: ``'guess'``); how to display the links - OUTPUT: Tuple of strings (with fancy formatting): + OUTPUT: tuple of strings (with fancy formatting): - if ``format`` is ``url``, returns a tuple of absolute links without description. - if ``format`` is ``html``, returns nothing but prints a tuple of clickable absolute links in their context. @@ -1534,7 +1496,7 @@ def links(self, browse=None, format='guess'): sage: s.links(format='url')[3] 'https://oeis.org/A000024' - sage: HTML = s.links(format="html"); HTML + sage: HTML = s.links(format='html'); HTML 0: Wikipedia, 42 (number) 1: See. also github issue #42 ... @@ -1597,7 +1559,7 @@ def cross_references(self, fetch=False): INPUT: - - ``fetch`` -- boolean (default: ``False``). + - ``fetch`` -- boolean (default: ``False``) OUTPUT: @@ -1725,9 +1687,7 @@ def url(self): r""" Return the URL of the page associated to the sequence ``self``. - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -1828,15 +1788,15 @@ def programs(self, language='all', preparsing=True, keep_comments=False): INPUT: - - ``language`` -- string (default: 'all'), the chosen language. + - ``language`` -- string (default: ``'all'``); the chosen language. Possible values are 'all' for the full list, or any language name, for example 'sage', 'maple', 'mathematica', etc. Some further optional input is specific to sage code treatment: - - ``preparsing`` -- boolean (default: ``True``) whether to preparse + - ``preparsing`` -- boolean (default: ``True``); whether to preparse sage code - - ``keep_comments`` -- boolean (default: ``False``) whether to keep + - ``keep_comments`` -- boolean (default: ``False``); whether to keep comments in sage code OUTPUT: @@ -2070,7 +2030,7 @@ def __getslice__(self, i, j): def __getitem__(self, x): r""" If ``x`` is a slice return the corresponding sub FancyTuple, - else return the `̀`x``-th item of ``self``. + else return the ``x``-th item of ``self``. TESTS:: diff --git a/src/sage/databases/sloane.py b/src/sage/databases/sloane.py index 048aa221e6c..78fc268b486 100644 --- a/src/sage/databases/sloane.py +++ b/src/sage/databases/sloane.py @@ -109,7 +109,9 @@ def __init__(self): def __repr__(self): """ - String representation of this database. OUTPUT: str + String representation of this database. + + OUTPUT: string """ return "Local copy of Sloane Online Encyclopedia of Integer Sequences" @@ -124,11 +126,11 @@ def __iter__(self): def __getitem__(self, N): """ Return sequence N in the encyclopedia. If sequence N does not - exist, return []. + exist, return ``[]``. INPUT: - - ``N`` -- int + - ``N`` -- integer OUTPUT: list """ @@ -155,9 +157,9 @@ def find(self, seq, maxresults=30): INPUT: - - ``seq`` -- list + - ``seq`` -- list - - ``maxresults`` -- int + - ``maxresults`` -- integer OUTPUT: list of 2-tuples (i, v), where v is a sequence with seq as a subsequence. @@ -175,24 +177,24 @@ def find(self, seq, maxresults=30): return answer - def install(self, oeis_url="https://oeis.org/stripped.gz", - names_url="https://oeis.org/names.gz", overwrite=False): + def install(self, oeis_url='https://oeis.org/stripped.gz', + names_url='https://oeis.org/names.gz', overwrite=False): """ Download and install the online encyclopedia, raising an IOError if either step fails. INPUT: - - ``oeis_url`` -- string (default: "https://oeis.org...") - The URL of the stripped.gz encyclopedia file. + - ``oeis_url`` -- string (default: ``'https://oeis.org...'``) + The URL of the stripped.gz encyclopedia file - - ``names_url`` -- string (default: "https://oeis.org...") + - ``names_url`` -- string (default: ``'https://oeis.org...'``) The URL of the names.gz encyclopedia file. If you do not want to download this file, set names_url=None. - - ``overwrite`` -- boolean (default: ``False``) If the encyclopedia is + - ``overwrite`` -- boolean (default: ``False``); if the encyclopedia is already installed and overwrite=True, download and install the latest - version over the installed one. + version over the installed one """ # See if the encyclopedia already exists if not overwrite and os.path.exists(self.__file__): @@ -226,14 +228,14 @@ def install_from_gz(self, stripped_file, names_file, overwrite=False): INPUT: - - ``stripped_file`` -- string. The name of the stripped.gz OEIS file. + - ``stripped_file`` -- string; the name of the stripped.gz OEIS file - - ``names_file`` -- string. The name of the names.gz OEIS file, or - None if the user does not want it installed. + - ``names_file`` -- string; the name of the names.gz OEIS file, or + None if the user does not want it installed - - ``overwrite`` -- boolean (default: ``False``) If the encyclopedia is - already installed and overwrite=True, install 'filename' over the - old encyclopedia. + - ``overwrite`` -- boolean (default: ``False``); if the encyclopedia is + already installed and ``overwrite=True``, install 'filename' over the + old encyclopedia """ if not overwrite and os.path.exists(self.__file__): raise OSError("Sloane encyclopedia is already installed") @@ -307,11 +309,11 @@ def sequence_name(self, N): Return the name of sequence ``N`` in the encyclopedia. If sequence ``N`` does not exist, return ``''``. If the names - database is not installed, raise an :class:`IOError`. + database is not installed, raise an :exc:`IOError`. INPUT: - - ``N`` -- int + - ``N`` -- integer OUTPUT: string @@ -352,9 +354,9 @@ def copy_gz_file(gz_source, bz_destination): INPUT: - - ``gz_source`` -- string. The name of the gzipped file. + - ``gz_source`` -- string; the name of the gzipped file - - ``bz_destination`` -- string. The name of the newly compressed file. + - ``bz_destination`` -- string; the name of the newly compressed file """ import gzip diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py index bdb407b5361..fad05a0add9 100644 --- a/src/sage/databases/sql_db.py +++ b/src/sage/databases/sql_db.py @@ -98,6 +98,7 @@ 'UNIQUE','UPDATE','USING','VACUUM','VALUES','VIEW','VIRTUAL','WHEN', 'WHERE'] + def regexp(expr, item): """ Function to define regular expressions in pysqlite. @@ -141,7 +142,6 @@ def verify_type(type): Traceback (most recent call last): ... TypeError: float is not a legal type. - """ types = ['INTEGER','INT','BOOLEAN','REAL','TEXT','BOOL','BLOB','NOTYPE'] if type.upper() not in types: @@ -180,6 +180,7 @@ def verify_column(col_dict): d['sql'] = col_dict['sql'] return d + def verify_operator(operator): """ Check that ``operator`` is one of the allowed strings. @@ -253,7 +254,7 @@ def construct_skeleton(database): exe1 = cur.execute("PRAGMA table_info(%s)" % table[0]) for col in exe1.fetchall(): if not col[2]: - typ = u'NOTYPE' + typ = 'NOTYPE' else: typ = col[2] skeleton[table[0]][col[1]] = {'sql':typ, @@ -275,6 +276,8 @@ def construct_skeleton(database): p = 0 + + def _create_print_table(cur, col_titles, **kwds): r""" Create a nice printable table from the cursor given with the given @@ -283,19 +286,19 @@ def _create_print_table(cur, col_titles, **kwds): KEYWORDS: - ``max_field_size`` -- how wide each field can be - - ``format_cols`` -- a dictionary that allows the user to specify the + - ``format_cols`` -- dictionary that allows the user to specify the format of a column's output by supplying a function. The format of the dictionary is:: {'column_name':(lambda x: format_function(x))} - - ``plot_cols`` -- a dictionary that allows the user to specify that a + - ``plot_cols`` -- dictionary that allows the user to specify that a plot should be drawn by the object generated by a data slice. Note that plot kwds are permitted. The dictionary format is:: {'column_name':((lambda x: plot_function(x)),**kwds)} - - ``relabel_cols`` -- a dictionary to specify a relabeling of column + - ``relabel_cols`` -- dictionary to specify a relabeling of column headers. The dictionary format is:: {'table_name':{'old_col_name':'new_col_name'}} @@ -303,8 +306,8 @@ def _create_print_table(cur, col_titles, **kwds): - ``id_col`` -- reference to a column that can be used as an object identifier for each row - - ``html_table`` -- boolean that if True creates an html table instead of - a print table. Always set to True in the notebook. + - ``html_table`` -- boolean that if ``True`` creates an html table instead of + a print table. Always set to ``True`` in the notebook EXAMPLES:: @@ -398,6 +401,7 @@ def row_str(row, html): ret += '\n'.join([row_str(row, False) for row in cur]) return ret + class SQLQuery(SageObject): def __init__(self, database, *args, **kwds): """ @@ -406,7 +410,7 @@ def __init__(self, database, *args, **kwds): INPUT: - ``database`` -- a SQLDatabase object - - ``query_dict`` -- a dictionary specifying the query itself. The + - ``query_dict`` -- dictionary specifying the query itself. The format is:: {'table_name':'tblname', 'display_cols':['col1', 'col2','col3'], 'expression': [col, operator, value]} @@ -447,7 +451,6 @@ def __init__(self, database, *args, **kwds): Traceback (most recent call last): ... ValueError: Table has no column c1 - """ if not isinstance(database, SQLDatabase): raise TypeError('%s is not a valid SQLDatabase' % database) @@ -479,7 +482,7 @@ def __init__(self, database, *args, **kwds): else: self.__query_string__ = kwds['query_string'] if 'param_tuple' in kwds: - self.__param_tuple__ = tuple((str(x) for x in kwds['param_tuple'])) + self.__param_tuple__ = tuple(str(x) for x in kwds['param_tuple']) else: self.__param_tuple__ = tuple() return @@ -616,19 +619,19 @@ def show(self, **kwds): KEYWORDS: - ``max_field_size`` -- how wide each field can be - - ``format_cols`` -- a dictionary that allows the user to specify the + - ``format_cols`` -- dictionary that allows the user to specify the format of a column's output by supplying a function. The format of the dictionary is:: {'column_name':(lambda x: format_function(x))} - - ``plot_cols`` -- a dictionary that allows the user to specify that a + - ``plot_cols`` -- dictionary that allows the user to specify that a plot should be drawn by the object generated by a data slice. Note that plot kwds are permitted. The dictionary format is:: {'column_name':((lambda x: plot_function(x)),**kwds)} - - ``relabel_cols`` -- a dictionary to specify a relabeling of column + - ``relabel_cols`` -- dictionary to specify a relabeling of column headers. The dictionary format is:: {'table_name':{'old_col_name':'new_col_name'}} @@ -706,14 +709,14 @@ def intersect(self, other, join_table=None, join_dict=None, Return a new ``SQLQuery`` that is the intersection of ``self`` and ``other``. ``join_table`` and ``join_dict`` can be ``None`` iff the two queries only search one table in the database. All display columns - will be concatenated in order: self display cols + other display cols. + will be concatenated in order: ``self`` display cols + other display cols. INPUT: - ``other`` -- the ``SQLQuery`` to intersect with - ``join_table`` -- base table to join on (This table should have at least one column in each table to join on). - - ``join_dict`` -- a dictionary that represents the join structure for + - ``join_dict`` -- dictionary that represents the join structure for the new query. (Must include a mapping for all tables, including those previously joined in either query). Structure is given by:: @@ -837,23 +840,23 @@ def _merge_queries(self, other, ret, join_table, join_dict, operator): def union(self, other, join_table=None, join_dict=None, in_place=False): """ - Return a new ``SQLQuery`` that is the union of self and other. + Return a new ``SQLQuery`` that is the union of ``self`` and ``other``. ``join_table`` and ``join_dict`` can be ``None`` iff the two queries only search one table in the database. All display columns will be - concatenated in order: self display cols + other display cols. + concatenated in order: ``self`` display cols + other display cols. INPUT: - ``other`` -- the ``SQLQuery`` to union with - ``join_table`` -- base table to join on (This table should have at least one column in each table to join on). - - ``join_dict`` -- a dictionary that represents the join structure for + - ``join_dict`` -- dictionary that represents the join structure for the new query. (Must include a mapping for all tables, including those previously joined in either query). Structure is given by:: {'join_table1':('corr_base_col1', 'col1'), 'join_table2':('corr_base_col2', 'col2')} - where ``join_table1` is to be joined with ``join_table`` on + where ``join_table1`` is to be joined with ``join_table`` on ``join_table.corr_base_col1=join_table1.col1`` EXAMPLES:: @@ -899,7 +902,7 @@ def __init__(self, filename=None, read_only=None, skeleton=None): INPUT: - - ``filename`` -- a string + - ``filename`` -- string - ``skeleton`` -- a triple-indexed dictionary:: | - outer key -- table name @@ -1065,7 +1068,6 @@ def __init__(self, filename=None, read_only=None, skeleton=None): Call ``cleanup()`` on the temporary directory to, well, clean it up:: sage: d.cleanup() - """ if filename is None: if read_only is None: @@ -1243,8 +1245,8 @@ def get_skeleton(self, check=False): INPUT: - - ``check`` -- if True, checks to make sure the database's actual - structure matches the skeleton on record. + - ``check`` -- if ``True``, checks to make sure the database's actual + structure matches the skeleton on record EXAMPLES:: @@ -1403,7 +1405,7 @@ def create_table(self, table_name, table_skeleton): INPUT: - - ``table_name`` -- a string + - ``table_name`` -- string - ``table_skeleton`` -- a double-indexed dictionary - outer key -- column name @@ -1486,7 +1488,7 @@ def add_column(self, table_name, col_name, col_dict, default='NULL'): INPUT: - - ``col_dict`` -- a dictionary: + - ``col_dict`` -- dictionary: - key -- column name @@ -1734,7 +1736,6 @@ def rename_table(self, table_name, new_name): sage: D.show('lucy') col1 -------------------- - """ if self.__read_only__: raise RuntimeError('Cannot rename tables in a read only database.') @@ -1756,7 +1757,7 @@ def drop_table(self, table_name): INPUT: - - ``table_name`` -- a string + - ``table_name`` -- string EXAMPLES:: @@ -1811,8 +1812,8 @@ def make_index(self, col_name, table_name, unique=False): INPUT: - - ``col_name`` -- a string - - ``table_name`` -- a string + - ``col_name`` -- string + - ``table_name`` -- string - ``unique`` -- requires that there are no multiple entries in the column, makes searching faster @@ -1912,7 +1913,6 @@ def make_unique(self, table_name, col_name): 'primary_key': False, 'sql': 'INTEGER', 'unique': True}}} - """ if self.__read_only__: raise RuntimeError('Cannot modify a read only database') @@ -2094,7 +2094,7 @@ def delete_rows(self, query): INPUT: - ``query`` -- a ``SQLQuery`` (Delete the rows returned when query is - run). + run) EXAMPLES:: @@ -2146,9 +2146,9 @@ def add_rows(self, table_name, rows, entry_order=None): """ INPUT: - - ``rows`` -- a list of tuples that represent one row of data to add + - ``rows`` -- list of tuples that represent one row of data to add (types should match col types in order) - - ``entry_order`` -- an ordered list or tuple overrides normal order + - ``entry_order`` -- an ordered list or tuple overrides normal order with user defined order EXAMPLES:: @@ -2164,7 +2164,7 @@ def add_rows(self, table_name, rows, entry_order=None): if self.__read_only__: raise RuntimeError('Cannot add rows to read only database.') quest = '(' + ', '.join('?' for i in rows[0]) + ')' - strows = [tuple((str(entry) for entry in row)) for row in rows] + strows = [tuple(str(entry) for entry in row) for row in rows] if entry_order is not None: self.__connection__.executemany('INSERT INTO ' + table_name diff --git a/src/sage/databases/stein_watkins.py b/src/sage/databases/stein_watkins.py index 5c9c63a2669..45c0a6e7e9c 100644 --- a/src/sage/databases/stein_watkins.py +++ b/src/sage/databases/stein_watkins.py @@ -26,11 +26,10 @@ 999, inclusive. - The command ``SteinWatkinsPrimeData(n)`` returns an iterator over the curves - in the `n^{th}` Stein-Watkins prime table, which contains prime conductor + in the `n`-th Stein-Watkins prime table, which contains prime conductor elliptic curves of conductor between `n10^8` and `(n+1)10^8`. Here `n` varies between 0 and 99, inclusive. - EXAMPLES: We obtain the first table of elliptic curves. :: @@ -213,7 +212,7 @@ def __iter__(self): Stein-Watkins isogeny class of conductor 20 """ try: - file = bz2.open(self._file, 'rt', encoding="utf-8") + file = bz2.open(self._file, 'rt', encoding='utf-8') except OSError: raise OSError("The Stein-Watkins data file %s must be installed." % self._file) C = None @@ -348,7 +347,7 @@ def ecdb_num_curves(max_level=200000): """ i = 0 d = SteinWatkinsAllData(i) - v = [int(0) for _ in range(max_level + 1)] + v = [0 for _ in range(max_level + 1)] while True: try: C = next(d) diff --git a/src/sage/databases/symbolic_data.py b/src/sage/databases/symbolic_data.py index 0c6c4fbfc0a..f3f33192290 100644 --- a/src/sage/databases/symbolic_data.py +++ b/src/sage/databases/symbolic_data.py @@ -96,7 +96,7 @@ def __init__(self): self.__intpath = path + "/Data/XMLResources/INTPS/" self.__genpath = path + "/Data/XMLResources/GenPS/" - def get_ideal(self, name, base_ring=QQ, term_order="degrevlex"): + def get_ideal(self, name, base_ring=QQ, term_order='degrevlex'): """ Return the ideal given by 'name' over the base ring given by 'base_ring' in a polynomial ring with the term order given by @@ -130,8 +130,6 @@ def _getTextFromNode(node): return t def _dom2ideal(node): - """ - """ l = [] if str(node.nodeName) in ['vars', 'poly']: diff --git a/src/sage/doctest/__main__.py b/src/sage/doctest/__main__.py new file mode 100644 index 00000000000..1af1b22ce1d --- /dev/null +++ b/src/sage/doctest/__main__.py @@ -0,0 +1,235 @@ +import argparse +import os +import sys + +# Note: the DOT_SAGE and SAGE_STARTUP_FILE environment variables have already been set by sage-env +DOT_SAGE = os.environ.get('DOT_SAGE', os.path.join(os.environ.get('HOME'), + '.sage')) + +# Override to not pick up user configuration, see Issue #20270 +os.environ['SAGE_STARTUP_FILE'] = os.path.join(DOT_SAGE, 'init-doctests.sage') + + +def _get_optional_defaults(): + """Return the default value for the --optional flag.""" + optional = ['sage', 'optional'] + + return ','.join(optional) + + +def _make_parser(): + r""" + Return the :class:`argparse.ArgumentParser`. + + TESTS: + + Test that the defaults are the consistent:: + + sage: from sage.doctest.control import DocTestDefaults + sage: from sage.doctest.__main__ import _make_parser + sage: os.environ.pop('SAGE_DOCTEST_RANDOM_SEED', None) + ... + sage: parser = _make_parser() + sage: args = parser.parse_args([]) + sage: DD = DocTestDefaults(runtest_default=True); DD + DocTestDefaults(abspath=False, file_iterations=0, global_iterations=0, + optional='sage,optional', random_seed=None, + stats_path='.../timings2.json') + sage: D = copy(args.__dict__) + sage: del D['filenames'] + sage: DA = DocTestDefaults(runtest_default=True, **D); DA + DocTestDefaults(abspath=False, file_iterations=0, global_iterations=0, + optional='sage,optional', random_seed=None, + stats_path='.../timings2.json') + """ + parser = argparse.ArgumentParser(usage="sage -t [options] filenames", + description="Run all tests in a file or a list of files whose extensions " + "are one of the following: " + ".py, .pyx, .pxd, .pxi, .sage, .spyx, .tex, .rst.") + parser.add_argument("-p", "--nthreads", dest="nthreads", + type=int, nargs='?', const=0, default=1, metavar="N", + help="test in parallel using N threads, with 0 interpreted as max(2, min(8, cpu_count())); " + "when run under the control of the GNU make jobserver (make -j), request as most N job slots") + parser.add_argument("-T", "--timeout", type=int, default=-1, help="timeout (in seconds) for doctesting one file, 0 for no timeout") + what = parser.add_mutually_exclusive_group() + what.add_argument("-a", "--all", action="store_true", default=False, help="test all files in the Sage library") + what.add_argument("--installed", action="store_true", default=False, help="test all installed modules of the Sage library") + parser.add_argument("--logfile", type=argparse.FileType('a'), metavar="FILE", help="log all output to FILE") + + parser.add_argument("--format", choices=["sage", "github"], default="sage", + help="set format of error messages and warnings") + parser.add_argument("-l", "--long", action="store_true", default=False, help="include lines with the phrase 'long time'") + parser.add_argument("-s", "--short", dest="target_walltime", nargs='?', + type=int, default=-1, const=300, metavar="SECONDS", + help="run as many doctests as possible in about 300 seconds (or the number of seconds given as an optional argument)") + parser.add_argument("--warn-long", dest="warn_long", nargs='?', + type=float, default=-1.0, const=1.0, metavar="SECONDS", + help="warn if tests take more CPU time than SECONDS") + # By default, include all tests marked 'sagemath_doc_html' -- see + # https://github.com/sagemath/sage/issues/25345 and + # https://github.com/sagemath/sage/issues/26110: + parser.add_argument("--optional", metavar="FEATURES", default=_get_optional_defaults(), + help='only run tests including one of the "# optional" tags listed in FEATURES (separated by commas); ' + 'if "sage" is listed, will also run the standard doctests; ' + 'if "sagemath_doc_html" is listed, will also run the tests relying on the HTML documentation; ' + 'if "optional" is listed, will also run tests for installed optional packages or detected features; ' + 'if "external" is listed, will also run tests for available external software; ' + 'if set to "all", then all tests will be run; ' + 'use "!FEATURE" to disable tests marked "# optional - FEATURE". ' + 'Note that "!" needs to be quoted or escaped in the shell.') + parser.add_argument("--hide", metavar="FEATURES", default="", + help='run tests pretending that the software listed in FEATURES (separated by commas) is not installed; ' + 'if "all" is listed, will also hide features corresponding to all optional or experimental packages; ' + 'if "optional" is listed, will also hide features corresponding to optional packages.') + parser.add_argument("--probe", metavar="FEATURES", default="", + help='run tests that would not be run because one of the given FEATURES (separated by commas) is not installed; ' + 'report the tests that pass nevertheless') + parser.add_argument("--randorder", type=int, metavar="SEED", help="randomize order of tests") + parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests", + default=os.environ.get("SAGE_DOCTEST_RANDOM_SEED")) + parser.add_argument("--global-iterations", "--global_iterations", type=int, default=0, help="repeat the whole testing process this many times") + parser.add_argument("--file-iterations", "--file_iterations", type=int, default=0, help="repeat each file this many times, stopping on the first failure") + parser.add_argument("--environment", type=str, default="sage.repl.ipython_kernel.all_jupyter", help="name of a module that provides the global environment for tests") + + parser.add_argument("-i", "--initial", action="store_true", default=False, help="only show the first failure in each file") + parser.add_argument("--exitfirst", action="store_true", default=False, help="end the test run immediately after the first failure or unexpected exception") + parser.add_argument("--force_lib", "--force-lib", action="store_true", default=False, help="do not import anything from the tested file(s)") + parser.add_argument("--if-installed", action="store_true", default=False, help="skip Python/Cython files that are not installed as modules") + parser.add_argument("--abspath", action="store_true", default=False, help="print absolute paths rather than relative paths") + parser.add_argument("--verbose", action="store_true", default=False, help="print debugging output during the test") + parser.add_argument("-d", "--debug", action="store_true", default=False, help="drop into a python debugger when an unexpected error is raised") + parser.add_argument("--only-errors", action="store_true", default=False, help="only output failures, not test successes") + + parser.add_argument("--gdb", action="store_true", default=False, help="run doctests under the control of gdb") + parser.add_argument("--lldb", action="store_true", default=False, help="run doctests under the control of lldb") + parser.add_argument("--valgrind", "--memcheck", action="store_true", default=False, + help="run doctests using Valgrind's memcheck tool. The log " + "files are named sage-memcheck.PID and can be found in " + + os.path.join(DOT_SAGE, "valgrind")) + parser.add_argument("--massif", action="store_true", default=False, + help="run doctests using Valgrind's massif tool. The log " + "files are named sage-massif.PID and can be found in " + + os.path.join(DOT_SAGE, "valgrind")) + parser.add_argument("--cachegrind", action="store_true", default=False, + help="run doctests using Valgrind's cachegrind tool. The log " + "files are named sage-cachegrind.PID and can be found in " + + os.path.join(DOT_SAGE, "valgrind")) + parser.add_argument("--omega", action="store_true", default=False, + help="run doctests using Valgrind's omega tool. The log " + "files are named sage-omega.PID and can be found in " + + os.path.join(DOT_SAGE, "valgrind")) + + parser.add_argument("-f", "--failed", action="store_true", default=False, + help="doctest only those files that failed in the previous run") + what.add_argument("-n", "--new", action="store_true", default=False, + help="doctest only those files that have been changed in the repository and not yet been committed") + parser.add_argument("--show-skipped", "--show_skipped", action="store_true", default=False, + help="print a summary at the end of each file of optional tests that were skipped") + + parser.add_argument("--stats_path", "--stats-path", default=os.path.join(DOT_SAGE, "timings2.json"), + help="path to a json dictionary for timings and failure status for each file from previous runs; it will be updated in this run") + parser.add_argument("--baseline_stats_path", "--baseline-stats-path", default=None, + help="path to a json dictionary for timings and failure status for each file, to be used as a baseline; it will not be updated") + + class GCAction(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + gcopts = dict(DEFAULT=0, ALWAYS=1, NEVER=-1) + new_value = gcopts[values] + setattr(namespace, self.dest, new_value) + + parser.add_argument("--gc", + choices=["DEFAULT", "ALWAYS", "NEVER"], + default=0, + action=GCAction, + help="control garbarge collection " + "(ALWAYS: collect garbage before every test; NEVER: disable gc; DEFAULT: Python default)") + + # The --serial option is only really for internal use, better not + # document it. + parser.add_argument("--serial", action="store_true", default=False, help=argparse.SUPPRESS) + # Same for --die_timeout + parser.add_argument("--die_timeout", type=int, default=-1, help=argparse.SUPPRESS) + + parser.add_argument("filenames", help="file names", nargs='*') + return parser + + +def main(): + parser = _make_parser() + # custom treatment to separate properly + # one or several file names at the end + new_arguments = [] + need_filenames = True + in_filenames = False + afterlog = False + for arg in sys.argv[1:]: + if arg in ('-n', '--new', '-a', '--all', '--installed'): + need_filenames = False + elif need_filenames and not (afterlog or in_filenames) and os.path.exists(arg): + in_filenames = True + new_arguments.append('--') + new_arguments.append(arg) + afterlog = arg in ['--logfile', '--stats_path', '--stats-path', + '--baseline_stats_path', '--baseline-stats-path'] + + args = parser.parse_args(new_arguments) + + if not args.filenames and not (args.all or args.new or args.installed): + print('either use --new, --all, --installed, or some filenames') + return 2 + + # Limit the number of threads to 2 to save system resources. + # See Issue #23713, #23892, #30351 + if sys.platform == 'darwin': + os.environ["OMP_NUM_THREADS"] = "1" + else: + os.environ["OMP_NUM_THREADS"] = "2" + + os.environ["SAGE_NUM_THREADS"] = "2" + + from sage.doctest.control import DocTestController + DC = DocTestController(args, args.filenames) + err = DC.run() + + # Issue #33521: Do not run pytest if the pytest configuration is not available. + # This happens when the source tree is not available and SAGE_SRC falls back + # to SAGE_LIB. + from sage.env import SAGE_SRC + if not all(os.path.isfile(os.path.join(SAGE_SRC, f)) + for f in ["conftest.py", "tox.ini"]): + return err + + try: + exit_code_pytest = 0 + import pytest + pytest_options = [] + if args.verbose: + pytest_options.append("-v") + + # #35999: no filename in arguments defaults to "src" + if not args.filenames: + filenames = [SAGE_SRC] + else: + # #31924: Do not run pytest on individual Python files unless + # they match the pytest file pattern. However, pass names + # of directories. We use 'not os.path.isfile(f)' for this so that + # we do not silently hide typos. + filenames = [f for f in args.filenames + if f.endswith("_test.py") or not os.path.isfile(f)] + if filenames: + print(f"Running pytest on {filenames} with options {pytest_options}") + exit_code_pytest = pytest.main(filenames + pytest_options) + if exit_code_pytest == 5: + # Exit code 5 means there were no test files, pass in this case + exit_code_pytest = 0 + + except ModuleNotFoundError: + print("pytest is not installed in the venv, skip checking tests that rely on it") + + if err == 0: + return exit_code_pytest + return err + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/sage/doctest/check_tolerance.py b/src/sage/doctest/check_tolerance.py new file mode 100644 index 00000000000..356369151aa --- /dev/null +++ b/src/sage/doctest/check_tolerance.py @@ -0,0 +1,259 @@ +# sage_setup: distribution = sagemath-repl +""" +Check tolerance when parsing docstrings +""" + +# **************************************************************************** +# Copyright (C) 2012-2018 David Roe +# 2012 Robert Bradshaw +# 2012 William Stein +# 2013 R. Andrew Ohana +# 2013 Volker Braun +# 2013-2018 Jeroen Demeyer +# 2016-2021 Frédéric Chapoton +# 2017-2018 Erik M. Bray +# 2020 Marc Mezzarobba +# 2020-2023 Matthias Koeppe +# 2022 John H. Palmieri +# 2022 Sébastien Labbé +# 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +import re +from sage.doctest.rif_tol import RIFtol, add_tolerance +from sage.doctest.marked_output import MarkedOutput + + +# Regex pattern for float without the (optional) leading sign +float_without_sign = r'((\d*\.?\d+)|(\d+\.?))([eE][+-]?\d+)?' + + +# Regular expression for floats +float_regex = re.compile(r'\s*([+-]?\s*' + float_without_sign + r')') + + +class ToleranceExceededError(BaseException): + pass + + +def check_tolerance_real_domain(want: MarkedOutput, got: str) -> tuple[str, str]: + """ + Compare want and got over real domain with tolerance + + INPUT: + + - ``want`` -- a string, what you want + - ``got`` -- a string, what you got + + OUTPUT: + + The strings to compare, but with matching float numbers replaced by asterisk. + + EXAMPLES:: + + sage: from sage.doctest.check_tolerance import check_tolerance_real_domain + sage: from sage.doctest.marked_output import MarkedOutput + sage: check_tolerance_real_domain( + ....: MarkedOutput('foo:0.2').update(abs_tol=0.3), + ....: 'bar:0.4') + ['foo:*', 'bar:*'] + sage: check_tolerance_real_domain( + ....: MarkedOutput('foo:0.2').update(abs_tol=0.3), + ....: 'bar:0.6') + Traceback (most recent call last): + ... + sage.doctest.check_tolerance.ToleranceExceededError + """ + # First check that the number of occurrences of floats appearing match + want_str = [g[0] for g in float_regex.findall(want)] + got_str = [g[0] for g in float_regex.findall(got)] + if len(want_str) != len(got_str): + raise ToleranceExceededError() + + # Then check the numbers + want_values = [RIFtol(g) for g in want_str] + want_intervals = [add_tolerance(v, want) for v in want_values] + got_values = [RIFtol(g) for g in got_str] + # The doctest is not successful if one of the "want" and "got" + # intervals have an empty intersection + if not all(a.overlaps(b) for a, b in zip(want_intervals, got_values)): + raise ToleranceExceededError() + + # Then check the part of the doctests without the numbers + # Continue the check process with floats replaced by stars + want = float_regex.sub('*', want) + got = float_regex.sub('*', got) + return [want, got] + + +# match 1.0 or 1.0 + I or 1.0 + 2.0*I +real_plus_optional_imag = ''.join([ + r'\s*(?P[+-]?\s*', + float_without_sign, + r')(\s*(?P[+-]\s*', + float_without_sign, + r')\*I|\s*(?P[+-])\s*I)?', +]) + + +# match - 2.0*I +only_imag = ''.join([ + r'\s*(?P[+-]?\s*', + float_without_sign, + r')\*I', +]) + + +# match I or -I (no digits), require a non-word part before and after for specificity +imaginary_unit = r'(?P^|\W)(?P[+-]?)I(?P$|\W)' + + +complex_regex = re.compile(''.join([ + '(', + only_imag, + '|', + imaginary_unit, + '|', + real_plus_optional_imag, + ')', +])) + + +def complex_match_to_real_and_imag(m: re.Match) -> tuple[str, str]: + """ + Extract real and imaginary part from match + + INPUT: + + - ``m`` -- match from ``complex_regex`` + + OUTPUT: + + Pair of real and complex parts (as string) + + EXAMPLES:: + + sage: from sage.doctest.check_tolerance import complex_match_to_real_and_imag, complex_regex + sage: complex_match_to_real_and_imag(complex_regex.match('1.0')) + ('1.0', '0') + sage: complex_match_to_real_and_imag(complex_regex.match('-1.0 - I')) + ('-1.0', '-1') + sage: complex_match_to_real_and_imag(complex_regex.match('1.0 - 3.0*I')) + ('1.0', '- 3.0') + sage: complex_match_to_real_and_imag(complex_regex.match('1.0*I')) + ('0', '1.0') + sage: complex_match_to_real_and_imag(complex_regex.match('- 2.0*I')) + ('0', '- 2.0') + sage: complex_match_to_real_and_imag(complex_regex.match('-I')) + ('0', '-1') + sage: for match in complex_regex.finditer('[1, -1, I, -1, -I]'): + ....: print(complex_match_to_real_and_imag(match)) + ('1', '0') + ('-1', '0') + ('0', '1') + ('-1', '0') + ('0', '-1') + sage: for match in complex_regex.finditer('[1, -1.3, -1.5 + 0.1*I, 0.5 - 0.1*I, -1.5*I]'): + ....: print(complex_match_to_real_and_imag(match)) + ('1', '0') + ('-1.3', '0') + ('-1.5', '+ 0.1') + ('0.5', '- 0.1') + ('0', '-1.5') + """ + real = m.group('real') + if real is not None: + real_imag_coeff = m.group('real_imag_coeff') + real_imag_unit = m.group('real_imag_unit') + if real_imag_coeff is not None: + return (real, real_imag_coeff) + elif real_imag_unit is not None: + return (real, real_imag_unit + '1') + else: + return (real, '0') + only_imag = m.group('only_imag') + if only_imag is not None: + return ('0', only_imag) + unit_imag = m.group('unit_imag') + if unit_imag is not None: + return ('0', unit_imag + '1') + assert False, 'unreachable' + + +def complex_star_repl(m: re.Match): + """ + Replace the complex number in the match with '*' + """ + if m.group('unit_imag') is not None: + # preserve the matched non-word part + return ''.join([ + (m.group('unit_imag_pre') or '').strip(), + '*', + (m.group('unit_imag_post') or '').strip(), + ]) + else: + return '*' + + +def check_tolerance_complex_domain(want: MarkedOutput, got: str) -> tuple[str, str]: + """ + Compare want and got over complex domain with tolerance + + INPUT: + + - ``want`` -- a string, what you want + - ``got`` -- a string, what you got + + OUTPUT: + + The strings to compare, but with matching complex numbers replaced by asterisk. + + EXAMPLES:: + + sage: from sage.doctest.check_tolerance import check_tolerance_complex_domain + sage: from sage.doctest.marked_output import MarkedOutput + sage: check_tolerance_complex_domain( + ....: MarkedOutput('foo:[0.2 + 0.1*I]').update(abs_tol=0.3), + ....: 'bar:[0.4]') + ['foo:[*]', 'bar:[*]'] + sage: check_tolerance_complex_domain( + ....: MarkedOutput('foo:-0.5 - 0.1*I').update(abs_tol=2), + ....: 'bar:1') + ['foo:*', 'bar:*'] + sage: check_tolerance_complex_domain( + ....: MarkedOutput('foo:[1.0*I]').update(abs_tol=0.3), + ....: 'bar:[I]') + ['foo:[*]', 'bar:[*]'] + sage: check_tolerance_complex_domain(MarkedOutput('foo:0.2 + 0.1*I').update(abs_tol=0.3), 'bar:0.6') + Traceback (most recent call last): + ... + sage.doctest.check_tolerance.ToleranceExceededError + """ + want_str = [] + for match in complex_regex.finditer(want): + want_str.extend(complex_match_to_real_and_imag(match)) + got_str = [] + for match in complex_regex.finditer(got): + got_str.extend(complex_match_to_real_and_imag(match)) + if len(want_str) != len(got_str): + raise ToleranceExceededError() + + # Then check the numbers + want_values = [RIFtol(g) for g in want_str] + want_intervals = [add_tolerance(v, want) for v in want_values] + got_values = [RIFtol(g) for g in got_str] + # The doctest is not successful if one of the "want" and "got" + # intervals have an empty intersection + if not all(a.overlaps(b) for a, b in zip(want_intervals, got_values)): + raise ToleranceExceededError() + + # Then check the part of the doctests without the numbers + # Continue the check process with floats replaced by stars + want = complex_regex.sub(complex_star_repl, want) + got = complex_regex.sub(complex_star_repl, got) + return [want, got] diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index cf9c32edd63..f34d3ef5caa 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -63,28 +63,39 @@ class DocTestDefaults(SageObject): """ This class is used for doctesting the Sage doctest module. - It fills in attributes to be the same as the defaults defined in - ``sage-runtests``, expect for a few places, - which is mostly to make doctesting more predictable. + INPUT: + + - ``runtest_default`` -- (boolean, default ``False``); if ``True``, + fills in attribute to be the same as the defaults defined in + ``sage-runtests``. If ``False``, change defaults in a few places + for use in doctests of the doctester, which is mostly to make + doctesting more predictable. + + - ``**kwds`` -- attributes to override defaults EXAMPLES:: sage: from sage.doctest.control import DocTestDefaults - sage: D = DocTestDefaults() - sage: D + sage: D = DocTestDefaults(); D DocTestDefaults() sage: D.timeout -1 Keyword arguments become attributes:: - sage: D = DocTestDefaults(timeout=100) - sage: D + sage: D = DocTestDefaults(timeout=100); D DocTestDefaults(timeout=100) sage: D.timeout 100 + + The defaults for ``sage-runtests``:: + + sage: D = DocTestDefaults(runtest_default=True); D + DocTestDefaults(abspath=False, file_iterations=0, global_iterations=0, + optional='sage,optional', random_seed=None, + stats_path='.../timings2.json') """ - def __init__(self, **kwds): + def __init__(self, runtest_default=False, **kwds): """ Edit these parameters after creating an instance. @@ -109,15 +120,15 @@ def __init__(self, **kwds): self.long = False self.warn_long = -1.0 self.randorder = None - self.random_seed = 0 - self.global_iterations = 1 # sage-runtests default is 0 - self.file_iterations = 1 # sage-runtests default is 0 + self.random_seed = None if runtest_default else 0 + self.global_iterations = 0 if runtest_default else 1 + self.file_iterations = 0 if runtest_default else 1 self.environment = "sage.repl.ipython_kernel.all_jupyter" self.initial = False self.exitfirst = False self.force_lib = False self.if_installed = False - self.abspath = True # sage-runtests default is False + self.abspath = not runtest_default self.verbose = False self.debug = False self.only_errors = False @@ -139,7 +150,10 @@ def __init__(self, **kwds): # automatically anyway. However, this default is still used for # displaying user-defined optional tags and we don't want to see # the auto_optional_tags there. - self.optional = {'sage'} | auto_optional_tags + if runtest_default: + self.optional = ','.join(['sage', 'optional']) + else: + self.optional = {'sage'} | auto_optional_tags self.hide = '' self.probe = '' @@ -149,7 +163,8 @@ def __init__(self, **kwds): # We don't want to use the real stats file by default so that # we don't overwrite timings for the actual running doctests. - self.stats_path = os.path.join(DOT_SAGE, "timings_dt_test.json") + self.stats_path = os.path.join( + DOT_SAGE, "timings2.json" if runtest_default else "timings_dt_test.json") self.__dict__.update(kwds) def _repr_(self): @@ -159,7 +174,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.doctest.control import DocTestDefaults - sage: DocTestDefaults(timeout=100, foobar="hello") + sage: DocTestDefaults(timeout=100, foobar='hello') DocTestDefaults(foobar='hello', timeout=100) """ s = "DocTestDefaults(" @@ -203,7 +218,7 @@ def __ne__(self, other): def skipdir(dirname): """ - Return True if and only if the directory ``dirname`` should not be + Return ``True`` if and only if the directory ``dirname`` should not be doctested. EXAMPLES:: @@ -228,10 +243,10 @@ def skipfile(filename, tested_optional_tags=False, *, - ``filename`` -- name of a file - - ``tested_optional_tags`` -- a list or tuple or set of optional tags to test, + - ``tested_optional_tags`` -- list or tuple or set of optional tags to test, or ``False`` (no optional test) or ``True`` (all optional tests) - - ``if_installed`` -- (boolean, default ``False``) whether to skip Python/Cython files + - ``if_installed`` -- boolean (default: ``False``); whether to skip Python/Cython files that are not installed as modules - ``log`` -- function to call with log messages, or ``None`` @@ -246,7 +261,7 @@ def skipfile(filename, tested_optional_tags=False, *, sage: from sage.doctest.control import skipfile sage: skipfile("skipme.c") True - sage: filename = tmp_filename(ext=".pyx") + sage: filename = tmp_filename(ext='.pyx') sage: skipfile(filename) False sage: with open(filename, "w") as f: @@ -269,8 +284,11 @@ def skipfile(filename, tested_optional_tags=False, *, """ if filename.endswith('.rst.txt'): ext = '.rst.txt' - else: - base, ext = os.path.splitext(filename) + if filename.endswith('__main__.py'): + if log: + log(f"Skipping '{filename}' because it is a __main__.py file") + return True + _ , ext = os.path.splitext(filename) # .rst.txt appear in the installed documentation in subdirectories named "_sources" if ext not in ('.py', '.pyx', '.pxd', '.pxi', '.sage', '.spyx', '.rst', '.tex', '.rst.txt'): if log: @@ -323,7 +341,7 @@ def skipfile(filename, tested_optional_tags=False, *, return False -class Logger(): +class Logger: r""" File-like object which implements writing to multiple files at once. @@ -388,9 +406,9 @@ def __init__(self, options, args): INPUT: - - options -- either options generated from the command line by sage-runtests - or a DocTestDefaults object (possibly with some entries modified) - - args -- a list of filenames to doctest + - ``options`` -- either options generated from the command line by sage-runtests + or a DocTestDefaults object (possibly with some entries modified) + - ``args`` -- list of filenames to doctest EXAMPLES:: @@ -573,36 +591,38 @@ def __del__(self): def _init_warn_long(self): """ - Pick a suitable default for the ``--warn-long`` option if not specified. + Pick a suitable default for the ``--warn-long`` option if not + specified. It is desirable to have all tests (even ``# long`` ones) finish in less than about 5 seconds. Longer tests typically don't add coverage, they just make testing slow. - The default used here is 60 seconds on a modern computer. It - should eventually be lowered to 5 seconds, but its best to - boil the frog slowly. + The default used here is 5 seconds, unless `--long` was used, + in which case it is 30 seconds. - The stored timings are used to adjust this limit according to - the machine running the tests. + TESTS: - EXAMPLES:: + Ensure that the user's command-line options are not changed:: - sage: from sage.doctest.control import DocTestDefaults, DocTestController + sage: from sage.doctest.control import (DocTestDefaults, + ....: DocTestController) sage: DC = DocTestController(DocTestDefaults(), []) sage: DC.options.warn_long = 5.0 sage: DC._init_warn_long() - sage: DC.options.warn_long # existing command-line options are not changed + sage: DC.options.warn_long 5.00000000000000 """ # default is -1.0 if self.options.warn_long >= 0: # Specified on the command line return - try: - self.options.warn_long = 60.0 * self.second_on_modern_computer() - except RuntimeError as err: - if not sage.doctest.DOCTEST_MODE: - print(err) # No usable timing information + + # The developer's guide says that even a "long time" test + # should ideally complete in under five seconds, so we're + # being rather generous here. + self.options.warn_long = 5.0 + if self.options.long: + self.options.warn_long = 30.0 def second_on_modern_computer(self): """ @@ -613,7 +633,7 @@ def second_on_modern_computer(self): Float. The wall time on your computer that would be equivalent to one second on a modern computer. Unless you have kick-ass hardware this should always be >= 1.0. This raises a - :class:`RuntimeError` if there are no stored timings to use as + :exc:`RuntimeError` if there are no stored timings to use as benchmark. EXAMPLES:: @@ -622,6 +642,9 @@ def second_on_modern_computer(self): sage: DC = DocTestController(DocTestDefaults(), []) sage: DC.second_on_modern_computer() # not tested """ + from sage.misc.superseded import deprecation + deprecation(32981, "this method is no longer used by the sage library and will eventually be removed") + if len(self.stats) == 0: raise RuntimeError('no stored timings available') success = [] @@ -772,7 +795,7 @@ def save_stats(self, filename): with atomic_write(filename) as stats_file: json.dump(self.stats, stats_file, sort_keys=True, indent=4) - def log(self, s, end="\n"): + def log(self, s, end='\n'): """ Log the string ``s + end`` (where ``end`` is a newline by default) to the logfile and print it to the standard output. @@ -819,14 +842,13 @@ def log(self, s, end="\n"): sage: with open(DD.logfile) as f: ....: print(f.read()) hello world - """ self.logger.write(s + end) self.logger.flush() def create_run_id(self): """ - Creates the run id. + Create the run id. EXAMPLES:: @@ -840,7 +862,7 @@ def create_run_id(self): def add_files(self): r""" - Checks for the flags '--all' and '--new'. + Check for the flags '--all' and '--new'. For each one present, this function adds the appropriate directories and files to the todo list. @@ -956,7 +978,7 @@ def all_doc_sources(): def expand_files_into_sources(self): r""" - Expands ``self.files``, which may include directories, into a + Expand ``self.files``, which may include directories, into a list of :class:`sage.doctest.FileDocTestSource` This function also handles the optional command line option. @@ -971,7 +993,7 @@ def expand_files_into_sources(self): sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: len(DC.sources) - 12 + 15 sage: DC.sources[0].options.optional True @@ -1072,13 +1094,16 @@ def sort_sources(self): sage.doctest.util sage.doctest.test sage.doctest.sources + sage.doctest.rif_tol sage.doctest.reporting sage.doctest.parsing_test sage.doctest.parsing + sage.doctest.marked_output sage.doctest.forker sage.doctest.fixtures sage.doctest.external sage.doctest.control + sage.doctest.check_tolerance sage.doctest.all sage.doctest """ @@ -1099,9 +1124,7 @@ def source_baseline(self, source): - ``source`` -- a :class:`DocTestSource` instance - OUTPUT: - - A dictionary. + OUTPUT: a dictionary EXAMPLES:: @@ -1120,7 +1143,7 @@ def source_baseline(self, source): def run_doctests(self): """ - Actually runs the doctests. + Actually run the doctests. This function is called by :meth:`run`. @@ -1136,7 +1159,7 @@ def run_doctests(self): sage: DC.run_doctests() Doctesting 1 file. sage -t .../sage/rings/homset.py - [... tests, ... s] + [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1185,7 +1208,7 @@ def run_doctests(self): def cleanup(self, final=True): """ - Runs cleanup activities after actually running doctests. + Run cleanup activities after actually running doctests. In particular, saves the stats to disk and closes the logfile. @@ -1213,7 +1236,7 @@ def cleanup(self, final=True): Running doctests with ID ... Doctesting 1 file. sage -t .../rings/all.py - [... tests, ... s] + [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1235,7 +1258,7 @@ def _optional_tags_string(self): """ Return a string describing the optional tags used. - OUTPUT: a string with comma-separated tags (without spaces, so + OUTPUT: string with comma-separated tags (without spaces, so it can be used to build a command-line) EXAMPLES:: @@ -1244,10 +1267,10 @@ def _optional_tags_string(self): sage: DC = DocTestController(DocTestDefaults(), []) sage: DC._optional_tags_string() 'sage' - sage: DC = DocTestController(DocTestDefaults(optional="all,and,some,more"), []) + sage: DC = DocTestController(DocTestDefaults(optional='all,and,some,more'), []) sage: DC._optional_tags_string() 'all' - sage: DC = DocTestController(DocTestDefaults(optional="sage,openssl"), []) + sage: DC = DocTestController(DocTestDefaults(optional='sage,openssl'), []) sage: DC._optional_tags_string() 'openssl,sage' """ @@ -1259,25 +1282,33 @@ def _optional_tags_string(self): def _assemble_cmd(self): """ - Assembles a shell command used in running tests under gdb, lldb, or valgrind. + Assemble a shell command used in running tests under gdb, lldb, or valgrind. EXAMPLES:: sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(timeout=123), ["hello_world.py"]) sage: print(DC._assemble_cmd()) - sage-runtests --serial --timeout=123 hello_world.py + ...python... -m sage.doctest --serial... --timeout=123... hello_world.py """ - cmd = "sage-runtests --serial " - opt = dict_difference(self.options.__dict__, DocTestDefaults().__dict__) - if "all" in opt: - raise ValueError("You cannot run gdb/lldb/valgrind on the whole sage library") - for o in ("all", "long", "force_lib", "verbose", "failed", "new"): + cmd = f"{shlex.quote(sys.executable)} -m sage.doctest --serial " + opt = dict_difference(self.options.__dict__, DocTestDefaults(runtest_default=True).__dict__) + # Options with no argument + for o in ("all", "installed", "long", "initial", "exitfirst", + "force_lib", "if_installed", "abspath", "verbose", + "debug", "only_errors", "failed", "new", + "show_skipped"): if o in opt: - cmd += "--%s " % o - for o in ("timeout", "randorder", "stats_path"): + cmd += "--%s " % o.replace('_', '-') + # Options with one argument + for o in ("timeout", "die_timeout", "logfile", "warn_long", "randorder", + "random_seed", "global_iterations", "file_iterations", + "environment", "baseline_stats_path", "stats_path"): if o in opt: - cmd += "--%s=%s " % (o, opt[o]) + cmd += "--%s=%s " % (o.replace('_', '-'), opt[o]) + # One with a different dest + if "target_walltime" in opt: + cmd += "--%s=%s " % ("short", opt[o]) if "optional" in opt: cmd += "--optional={} ".format(self._optional_tags_string()) return cmd + " ".join(self.files) @@ -1288,8 +1319,8 @@ def run_val_gdb(self, testing=False): INPUT: - - ``testing`` -- boolean; if True then the command to be run - will be printed rather than a subprocess started. + - ``testing`` -- boolean (default: ``False``); if ``True`` then the + command to be run will be printed rather than a subprocess started EXAMPLES: @@ -1301,14 +1332,14 @@ def run_val_gdb(self, testing=False): sage: DD = DocTestDefaults(gdb=True) sage: DC = DocTestController(DD, ["hello_world.py"]) sage: DC.run_val_gdb(testing=True) - exec gdb --eval-command="run" --args ...python... sage-runtests --serial --timeout=0 hello_world.py + exec gdb --eval-command="run" --args ...python... -m sage.doctest --serial... --timeout=0... hello_world.py :: - sage: DD = DocTestDefaults(valgrind=True, optional="all", timeout=172800) + sage: DD = DocTestDefaults(valgrind=True, optional='all', timeout=172800) sage: DC = DocTestController(DD, ["hello_world.py"]) sage: DC.run_val_gdb(testing=True) - exec valgrind --tool=memcheck --leak-resolution=high --leak-check=full --num-callers=25 --suppressions="...valgrind/pyalloc.supp" --suppressions="...valgrind/sage.supp" --suppressions="...valgrind/sage-additional.supp" --log-file=.../valgrind/sage-memcheck.%p... sage-runtests --serial --timeout=172800 --optional=all hello_world.py + exec valgrind --tool=memcheck --leak-resolution=high --leak-check=full --num-callers=25 --suppressions=.../valgrind/pyalloc.supp --suppressions=.../valgrind/sage.supp --suppressions=.../valgrind/sage-additional.supp --suppressions=.../valgrind/valgrind-python.supp --log-file=.../valgrind/sage-memcheck.%p ...python... -m sage.doctest --serial... --timeout=172800... --optional=all hello_world.py """ try: sage_cmd = self._assemble_cmd() @@ -1318,13 +1349,12 @@ def run_val_gdb(self, testing=False): opt = self.options if opt.gdb: - cmd = f'''exec gdb --eval-command="run" --args {shlex.quote(sys.executable)} ''' + cmd = f'''exec gdb --eval-command="run" --args ''' flags = "" if opt.logfile: sage_cmd += f" --logfile {shlex.quote(opt.logfile)}" elif opt.lldb: - sage_cmd = sage_cmd.replace('sage-runtests', '$(command -v sage-runtests)') - cmd = f'''exec lldb --one-line "process launch" --one-line "cont" -- {sys.executable} ''' + cmd = f'''exec lldb --one-line "process launch" --one-line "cont" -- ''' flags = "" else: if opt.logfile is None: @@ -1343,9 +1373,9 @@ def run_val_gdb(self, testing=False): flags = os.getenv("SAGE_MEMCHECK_FLAGS") if flags is None: flags = "--leak-resolution=high --leak-check=full --num-callers=25 " - flags += '''--suppressions="%s" ''' % (os.path.join(SAGE_EXTCODE, "valgrind", "pyalloc.supp")) - flags += '''--suppressions="%s" ''' % (os.path.join(SAGE_EXTCODE, "valgrind", "sage.supp")) - flags += '''--suppressions="%s" ''' % (os.path.join(SAGE_EXTCODE, "valgrind", "sage-additional.supp")) + for supp in ["pyalloc.supp", "sage.supp", "sage-additional.supp", "valgrind-python.supp"]: + fname = os.path.join(SAGE_EXTCODE, "valgrind", supp) + flags += f"--suppressions={shlex.quote(fname)} " elif opt.massif: toolname = "massif" flags = os.getenv("SAGE_MASSIF_FLAGS", "--depth=6 ") @@ -1410,7 +1440,7 @@ def run(self): Running doctests with ID ... Doctesting 1 file. sage -t .../sage/sets/non_negative_integers.py - [... tests, ... s] + [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1434,7 +1464,7 @@ def run(self): Features to be detected: ... Doctesting 1 file. sage -t ....py - [0 tests, ... s] + [0 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1460,7 +1490,7 @@ def run(self): Features to be detected: ... Doctesting 1 file. sage -t ....py - [4 tests, ... s] + [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1478,7 +1508,7 @@ def run(self): Features to be detected: ... Doctesting 1 file. sage -t ....py - [4 tests, ... s] + [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1496,7 +1526,7 @@ def run(self): Features to be detected: ... Doctesting 1 file. sage -t ....py - [4 tests, ... s] + [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1590,13 +1620,13 @@ def run(self): def run_doctests(module, options=None): """ - Runs the doctests in a given file. + Run the doctests in a given file. INPUT: - - ``module`` -- a Sage module, a string, or a list of such. + - ``module`` -- a Sage module, a string, or a list of such - - ``options`` -- a DocTestDefaults object or None. + - ``options`` -- a DocTestDefaults object or ``None`` EXAMPLES:: @@ -1604,7 +1634,7 @@ def run_doctests(module, options=None): Running doctests with ID ... Doctesting 1 file. sage -t .../sage/rings/all.py - [... tests, ... s] + [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 480918b38fe..56727bd79f6 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -356,7 +356,9 @@ def external_features(): import sage.features.ffmpeg yield from sage.features.ffmpeg.all_features() import sage.features.interfaces - yield from sage.features.interfaces.all_features() + for feature in sage.features.interfaces.all_features(): + if feature.name != 'mathics': + yield feature from sage.features.mip_backends import CPLEX, Gurobi yield CPLEX() yield Gurobi() @@ -377,7 +379,7 @@ def external_software() -> list[str]: external_software = external_software() -class AvailableSoftware(): +class AvailableSoftware: """ This class keeps the set of available software whose availability is detected lazily from the list of external software. diff --git a/src/sage/doctest/fixtures.py b/src/sage/doctest/fixtures.py index 01f931727df..ee812a8ecc9 100644 --- a/src/sage/doctest/fixtures.py +++ b/src/sage/doctest/fixtures.py @@ -112,7 +112,7 @@ def sorted_pairs(iterable, pairs=False): return repr(val) -class AttributeAccessTracerHelper(): +class AttributeAccessTracerHelper: def __init__(self, delegate, prefix=" ", reads=True): r""" @@ -125,13 +125,11 @@ def __init__(self, delegate, prefix=" ", reads=True): INPUT: - - ``delegate`` -- the actual object to be proxied. + - ``delegate`` -- the actual object to be proxied - - ``prefix`` -- (default: ``" "``) - string to prepend to each printed output. + - ``prefix`` -- (default: ``" "``) string to prepend to each printed output - - ``reads`` -- (default: ``True``) - whether to trace read access as well. + - ``reads`` -- (default: ``True``) whether to trace read access as well EXAMPLES:: @@ -225,7 +223,7 @@ def set(self, name, val): setattr(self.delegate, name, val) -class AttributeAccessTracerProxy(): +class AttributeAccessTracerProxy: def __init__(self, delegate, **kwds): r""" @@ -238,13 +236,13 @@ def __init__(self, delegate, **kwds): INPUT: - - ``delegate`` -- the actual object to be proxied. + - ``delegate`` -- the actual object to be proxied - ``prefix`` -- (default: ``" "``) - string to prepend to each printed output. + string to prepend to each printed output - ``reads`` -- (default: ``True``) - whether to trace read access as well. + whether to trace read access as well EXAMPLES:: @@ -332,15 +330,15 @@ def trace_method(obj, meth, **kwds): INPUT: - - ``obj`` -- the object containing the method. + - ``obj`` -- the object containing the method - - ``meth`` -- the name of the method to be traced. + - ``meth`` -- the name of the method to be traced - ``prefix`` -- (default: ``" "``) - string to prepend to each printed output. + string to prepend to each printed output - ``reads`` -- (default: ``True``) - whether to trace read access as well. + whether to trace read access as well EXAMPLES:: diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 7e9eab2ff2e..b69c842836c 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -150,14 +150,13 @@ def init_sage(controller=None): sage: from sympy.printing.pretty.pretty import PrettyPrinter sage: s = sympify('+x^'.join(str(i) for i in range(30))) sage: print(PrettyPrinter(settings={'wrap_line': True}).doprint(s)) - 29 28 27 26 25 24 23 22 21 20 19 18 17 - x + x + x + x + x + x + x + x + x + x + x + x + x + + 29 28 27 26 25 24 23 22 21 20 19 18 17... + x + x + x + x + x + x + x + x + x + x + x + x + x... - 16 15 14 13 12 11 10 9 8 7 6 5 4 3 - x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + ... 16 15 14 13 12 11 10 9 8 7 6 5 4 3... + ...x + x + x + x + x + x + x + x + x + x + x + x + x + x... - 2 - + x + ... The displayhook sorts dictionary keys to simplify doctesting of dictionary output:: @@ -253,7 +252,7 @@ def showwarning_with_traceback(message, category, filename, lineno, file=None, l INPUT: see :func:`warnings.showwarning`. - OUTPUT: None + OUTPUT: none EXAMPLES:: @@ -307,10 +306,10 @@ class SageSpoofInOut(SageObject): INPUT: - ``outfile`` -- (default: ``tempfile.TemporaryFile()``) a seekable open file - object to which stdout and stderr should be redirected. + object to which stdout and stderr should be redirected - ``infile`` -- (default: ``open(os.devnull)``) an open file object - from which stdin should be redirected. + from which stdin should be redirected EXAMPLES:: @@ -470,7 +469,7 @@ def stop_spoofing(self): def getvalue(self): r""" - Gets the value that has been printed to ``outfile`` since the + Get the value that has been printed to ``outfile`` since the last time this function was called. EXAMPLES:: @@ -521,10 +520,10 @@ def __init__(self, *args, **kwds): :class:`doctest.OutputChecker` - ``verbose`` -- boolean, determines whether verbose printing - is enabled. + is enabled - - ``optionflags`` -- Controls the comparison with the expected - output. See :mod:`testmod` for more information. + - ``optionflags`` -- controls the comparison with the expected + output. See :mod:`testmod` for more information - ``baseline`` -- dictionary, the ``baseline_stats`` value @@ -710,27 +709,19 @@ def compiler(example): elif self.options.gc < 0: gc.disable() + from cysignals.signals import SignalError try: # Don't blink! This is where the user's code gets run. self.compile_and_execute(example, compiler, test.globs) - except SystemExit: + except (SignalError, SystemExit): + # Tests can be killed by signals in unexpected places. raise except BaseException: exception = sys.exc_info() - # On Python 2, the exception lives in sys.exc_info() as - # long we are in the same stack frame. To ensure that - # sig_occurred() works correctly, we need to clear the - # exception. This is not an issue on Python 3, where the - # exception is cleared as soon as we are outside of the - # "except" clause. - try: - sys.exc_clear() - except AttributeError: - pass # Python 3 finally: if self.debugger is not None: self.debugger.set_continue() # ==== Example Finished ==== - check_starttime = walltime() + check_timer = Timer().start() got = self._fakeout.getvalue() outcome = FAILURE # guilty until proved innocent or insane @@ -804,22 +795,22 @@ def compiler(example): f"and it succeeded (raised an exception as expected).") outcome = SUCCESS - check_duration = walltime(check_starttime) - self.total_walltime += example.walltime + check_duration + check_timer.stop() + self.total_walltime += example.walltime + check_timer.walltime # Report the outcome. if example.warnings: for warning in example.warnings: out(self._failure_header(test, example, f'Warning: {warning}')) if outcome is SUCCESS: - if self.options.warn_long > 0 and example.walltime + check_duration > self.options.warn_long: + if self.options.warn_long > 0 and example.cputime + check_timer.cputime > self.options.warn_long: self.report_overtime(out, test, example, got, - check_duration=check_duration) + check_timer=check_timer) elif example.warnings: pass elif not quiet: self.report_success(out, test, example, got, - check_duration=check_duration) + check_timer=check_timer) elif probed_tags: pass elif outcome is FAILURE: @@ -845,7 +836,7 @@ def compiler(example): def run(self, test, compileflags=0, out=None, clear_globs=True): """ - Runs the examples in a given doctest. + Run the examples in a given doctest. This function replaces :class:`doctest.DocTestRunner.run` since it needs to handle spoofing. It also leaves the display @@ -855,14 +846,14 @@ def run(self, test, compileflags=0, out=None, clear_globs=True): - ``test`` -- an instance of :class:`doctest.DocTest` - - ``compileflags`` -- int (default: 0) the set of compiler flags used to - execute examples (passed in to the :func:`compile`). + - ``compileflags`` -- integer (default: 0) the set of compiler flags + used to execute examples (passed in to the :func:`compile`) - ``out`` -- a function for writing the output (defaults to - :func:`sys.stdout.write`). + :func:`sys.stdout.write`) - - ``clear_globs`` -- boolean (default: ``True``): whether to clear - the namespace after running this doctest. + - ``clear_globs`` -- boolean (default: ``True``); whether to clear + the namespace after running this doctest OUTPUT: @@ -1044,7 +1035,7 @@ def update_digests(self, example): def compile_and_execute(self, example, compiler, globs): """ - Runs the given example, recording dependencies. + Run the given example, recording dependencies. Rather than using a basic dictionary, Sage's doctest runner uses a :class:`sage.doctest.util.RecordingDict`, which records @@ -1063,16 +1054,14 @@ def compile_and_execute(self, example, compiler, globs): INPUT: - - ``example`` -- a :class:`doctest.Example` instance. + - ``example`` -- a :class:`doctest.Example` instance - ``compiler`` -- a callable that, applied to example, produces a code object - - ``globs`` -- a dictionary in which to execute the code. + - ``globs`` -- dictionary in which to execute the code - OUTPUT: - - - the output of the compiled code snippet. + OUTPUT: the output of the compiled code snippet EXAMPLES:: @@ -1188,11 +1177,9 @@ def _failure_header(self, test, example, message='Failed example:'): - ``test`` -- a :class:`doctest.DocTest` instance - - ``example`` -- a :class:`doctest.Example` instance in ``test``. - - OUTPUT: + - ``example`` -- a :class:`doctest.Example` instance in ``test`` - - a string used for reporting that the given example failed. + OUTPUT: string used for reporting that the given example failed EXAMPLES:: @@ -1301,9 +1288,7 @@ def report_start(self, out, test, example): - ``example`` -- a :class:`doctest.Example` instance in ``test`` - OUTPUT: - - - prints a report to ``out`` + OUTPUT: prints a report to ``out`` EXAMPLES:: @@ -1333,7 +1318,7 @@ def report_start(self, out, test, example): start_txt += 'Expecting nothing\n' out(start_txt) - def report_success(self, out, test, example, got, *, check_duration=0): + def report_success(self, out, test, example, got, *, check_timer=None): """ Called when an example succeeds. @@ -1345,17 +1330,14 @@ def report_success(self, out, test, example, got, *, check_duration=0): - ``example`` -- a :class:`doctest.Example` instance in ``test`` - - ``got`` -- a string, the result of running ``example`` - - - ``check_duration`` -- number (default: ``0``) time spent for checking - the test output - - OUTPUT: + - ``got`` -- string; the result of running ``example`` - - prints a report to ``out`` + - ``check_timer`` -- a :class:`sage.doctest.util.Timer` (default: + ``None``) that measures the time spent checking whether or not + the output was correct - - if in debugging mode, starts an IPython prompt at the point - of the failure + OUTPUT: prints a report to ``out``; if in debugging mode, starts an + IPython prompt at the point of the failure EXAMPLES:: @@ -1363,20 +1345,27 @@ def report_success(self, out, test, example, got, *, check_duration=0): sage: from sage.doctest.forker import SageDocTestRunner sage: from sage.doctest.sources import FileDocTestSource sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() - sage: from sage.misc.timing import walltime + sage: from sage.doctest.util import Timer sage: import doctest, sys, os sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = sage.doctest.forker.__file__ sage: FDS = FileDocTestSource(filename, DD) sage: doctests, extras = FDS.create_doctests(globals()) sage: ex = doctests[0].examples[0] - sage: ex.walltime = 0.0r - sage: DTR.report_success(sys.stdout.write, doctests[0], ex, '1764') - ok [0.00 s] + sage: ex.cputime = 1.01 + sage: ex.walltime = 1.12 + sage: check = Timer() + sage: check.cputime = 2.14 + sage: check.walltime = 2.71 + sage: DTR.report_success(sys.stdout.write, doctests[0], ex, '1764', + ....: check_timer=check) + ok [3.83s wall] """ - # We completely replace doctest.DocTestRunner.report_success so that we can include time taken for the test + # We completely replace doctest.DocTestRunner.report_success + # so that we can include time taken for the test if self._verbose: - out("ok [%.2f s]\n" % (example.walltime + check_duration)) + out("ok [%.2fs wall]\n" % + (example.walltime + check_timer.walltime)) def report_failure(self, out, test, example, got, globs): r""" @@ -1390,13 +1379,11 @@ def report_failure(self, out, test, example, got, globs): - ``example`` -- a :class:`doctest.Example` instance in ``test`` - - ``got`` -- a string, the result of running ``example`` - - - ``globs`` -- a dictionary of globals, used if in debugging mode + - ``got`` -- string, the result of running ``example`` - OUTPUT: + - ``globs`` -- dictionary of globals, used if in debugging mode - - prints a report to ``out`` + OUTPUT: prints a report to ``out`` EXAMPLES:: @@ -1508,7 +1495,7 @@ def report_failure(self, out, test, example, got, globs): self._fakeout.start_spoofing() return returnval - def report_overtime(self, out, test, example, got, *, check_duration=0): + def report_overtime(self, out, test, example, got, *, check_timer=None): r""" Called when the ``warn_long`` option flag is set and a doctest runs longer than the specified time. @@ -1521,14 +1508,13 @@ def report_overtime(self, out, test, example, got, *, check_duration=0): - ``example`` -- a :class:`doctest.Example` instance in ``test`` - - ``got`` -- a string, the result of running ``example`` + - ``got`` -- string; the result of running ``example`` - - ``check_duration`` -- number (default: ``0``) time spent for checking - the test output + - ``check_timer`` -- a :class:`sage.doctest.util.Timer` (default: + ``None``) that measures the time spent checking whether or not + the output was correct - OUTPUT: - - - prints a report to ``out`` + OUTPUT: prints a report to ``out`` EXAMPLES:: @@ -1536,24 +1522,32 @@ def report_overtime(self, out, test, example, got, *, check_duration=0): sage: from sage.doctest.forker import SageDocTestRunner sage: from sage.doctest.sources import FileDocTestSource sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() - sage: from sage.misc.timing import walltime + sage: from sage.doctest.util import Timer sage: import doctest, sys, os sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = sage.doctest.forker.__file__ sage: FDS = FileDocTestSource(filename, DD) sage: doctests, extras = FDS.create_doctests(globals()) sage: ex = doctests[0].examples[0] - sage: ex.walltime = 1.23r - sage: DTR.report_overtime(sys.stdout.write, doctests[0], ex, 'BAD ANSWER\n', check_duration=2.34r) + sage: ex.cputime = 1.23 + sage: ex.walltime = 2.50 + sage: check = Timer() + sage: check.cputime = 2.34 + sage: check.walltime = 3.12 + sage: DTR.report_overtime(sys.stdout.write, doctests[0], ex, 'BAD ANSWER\n', check_timer=check) ********************************************************************** File ".../sage/doctest/forker.py", line 12, in sage.doctest.forker - Warning, slow doctest: + Warning: slow doctest: doctest_var = 42; doctest_var^2 - Test ran for 1.23 s, check ran for 2.34 s + Test ran for 1.23s cpu, 2.50s wall + Check ran for 2.34s cpu, 3.12s wall """ - out(self._failure_header(test, example, 'Warning, slow doctest:') + - ('Test ran for %.2f s, check ran for %.2f s\n' - % (example.walltime, check_duration))) + out(self._failure_header(test, example, 'Warning: slow doctest:') + + ('Test ran for %.2fs cpu, %.2fs wall\nCheck ran for %.2fs cpu, %.2fs wall\n' + % (example.cputime, + example.walltime, + check_timer.cputime, + check_timer.walltime))) def report_unexpected_exception(self, out, test, example, exc_info): r""" @@ -1571,9 +1565,7 @@ def report_unexpected_exception(self, out, test, example, exc_info): - ``exc_info`` -- the result of ``sys.exc_info()`` - OUTPUT: - - - prints a report to ``out`` + OUTPUT: prints a report to ``out`` - if in debugging mode, starts PDB with the given traceback @@ -1653,11 +1645,10 @@ def update_results(self, D): INPUT: - - ``D`` -- a dictionary to update with cputime and walltime - - OUTPUT: + - ``D`` -- dictionary to update with cputime and walltime - - the number of failures (or False if there is no failure attribute) + OUTPUT: the number of failures (or ``False`` if there is no failure + attribute) EXAMPLES:: @@ -1715,7 +1706,7 @@ def dummy_handler(sig, frame): class DocTestDispatcher(SageObject): """ - Creates parallel :class:`DocTestWorker` processes and dispatches + Create parallel :class:`DocTestWorker` processes and dispatches doctesting tasks. """ def __init__(self, controller): @@ -1759,9 +1750,9 @@ def serial_dispatch(self): sage: DC.timer = Timer().start() sage: DD.serial_dispatch() sage -t .../rings/homset.py - [... tests, ... s] + [... tests, ...s wall] sage -t .../rings/ideal.py - [... tests, ... s] + [... tests, ...s wall] """ for source in self.controller.sources: heading = self.controller.reporter.report_head(source) @@ -1805,17 +1796,17 @@ def parallel_dispatch(self): sage: DC.timer = Timer().start() sage: DD.parallel_dispatch() sage -t .../databases/cremona.py - [... tests, ... s] + [... tests, ...s wall] sage -t .../rings/big_oh.py - [... tests, ... s] + [... tests, ...s wall] If the ``exitfirst=True`` option is given, the results for a failing module will be immediately printed and any other ongoing tests canceled:: sage: from tempfile import NamedTemporaryFile as NTF - sage: with NTF(suffix=".py", mode="w+t") as f1, \ - ....: NTF(suffix=".py", mode="w+t") as f2: + sage: with NTF(suffix='.py', mode='w+t') as f1, \ + ....: NTF(suffix='.py', mode='w+t') as f2: ....: _ = f1.write("'''\nsage: import time; time.sleep(60)\n'''") ....: f1.flush() ....: _ = f2.write("'''\nsage: True\nFalse\n'''") @@ -1842,9 +1833,8 @@ def parallel_dispatch(self): ********************************************************************** 1 item had failures: 1 of 1 in ... - [1 test, 1 failure, ... s] + [1 test, 1 failure, ...s wall] Killing test ... - """ opt = self.controller.options @@ -1961,8 +1951,7 @@ def sel_exit(): # has the messages pipe open). # Adjust deadline to read all messages: newdeadline = now + die_timeout - if w.deadline > newdeadline: - w.deadline = newdeadline + w.deadline = min(w.deadline, newdeadline) new_workers.append(w) else: # Save the result and output of the worker @@ -2059,8 +2048,7 @@ def sel_exit(): # The master pselect() call rlist = [w.rmessages for w in workers if w.rmessages is not None] tmout = min(w.deadline for w in workers) - now - if tmout > 5: # Wait at most 5 seconds - tmout = 5 + tmout = min(tmout, 5) rlist, _, _, _ = sel.pselect(rlist, timeout=tmout) # Read messages @@ -2139,9 +2127,9 @@ def dispatch(self): sage: DC.timer = Timer().start() sage: DD.dispatch() sage -t .../sage/modules/free_module_homspace.py - [... tests, ... s] + [... tests, ...s wall] sage -t .../sage/rings/big_oh.py - [... tests, ... s] + [... tests, ...s wall] """ if self.controller.options.serial: self.serial_dispatch() @@ -2168,10 +2156,10 @@ class should be accessed by the child process. - ``source`` -- a :class:`DocTestSource` instance - - ``options`` -- an object representing doctest options. + - ``options`` -- an object representing doctest options - - ``funclist`` -- a list of callables to be called at the start of - the child process. + - ``funclist`` -- list of callables to be called at the start of + the child process - ``baseline`` -- dictionary, the ``baseline_stats`` value @@ -2191,7 +2179,7 @@ class should be accessed by the child process. sage: W.join() # Wait for worker to finish sage: result = W.result_queue.get() sage: reporter.report(FDS, False, W.exitcode, result, "") - [... tests, ... s] + [... tests, ...s wall] """ def __init__(self, source, options, funclist=[], baseline=None): """ @@ -2203,7 +2191,7 @@ def __init__(self, source, options, funclist=[], baseline=None): Running doctests with ID ... Doctesting 1 file. sage -t .../sage/rings/big_oh.py - [... tests, ... s] + [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -2242,7 +2230,7 @@ def __init__(self, source, options, funclist=[], baseline=None): def run(self): """ - Runs the :class:`DocTestTask` under its own PGID. + Run the :class:`DocTestTask` under its own PGID. TESTS:: @@ -2250,7 +2238,7 @@ def run(self): Running doctests with ID ... Doctesting 1 file. sage -t .../sage/symbolic/units.py - [... tests, ... s] + [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -2488,7 +2476,7 @@ def kill(self): return True -class DocTestTask(): +class DocTestTask: """ This class encapsulates the tests from a single source. @@ -2498,9 +2486,9 @@ class DocTestTask(): INPUT: - - ``source`` -- a :class:`sage.doctest.sources.DocTestSource` instance. + - ``source`` -- a :class:`sage.doctest.sources.DocTestSource` instance - - ``verbose`` -- boolean, controls reporting of progress by :class:`doctest.DocTestRunner`. + - ``verbose`` -- boolean, controls reporting of progress by :class:`doctest.DocTestRunner` EXAMPLES:: @@ -2544,18 +2532,18 @@ def __call__(self, options, outtmpfile=None, msgfile=None, result_queue=None, *, INPUT: - - ``options`` -- an object representing doctest options. + - ``options`` -- an object representing doctest options - ``outtmpfile`` -- a seekable file that's used by the doctest - runner to redirect stdout and stderr of the doctests. + runner to redirect stdout and stderr of the doctests - ``msgfile`` -- a file or pipe to send doctest messages about - doctest failures (or all tests in verbose mode). + doctest failures (or all tests in verbose mode) - ``result_queue`` -- an instance of :class:`multiprocessing.Queue` - to store the doctest result. For testing, this can also be None. + to store the doctest result. For testing, this can also be ``None`` - - ``baseline`` -- a dictionary, the ``baseline_stats`` value. + - ``baseline`` -- dictionary, the ``baseline_stats`` value OUTPUT: diff --git a/src/sage/doctest/marked_output.py b/src/sage/doctest/marked_output.py new file mode 100644 index 00000000000..e2f08443ea7 --- /dev/null +++ b/src/sage/doctest/marked_output.py @@ -0,0 +1,102 @@ +# sage_setup: distribution = sagemath-repl +""" +Helper for attaching tolerance information to strings +""" + +# **************************************************************************** +# Copyright (C) 2012-2018 David Roe +# 2012 Robert Bradshaw +# 2012 William Stein +# 2013 R. Andrew Ohana +# 2013 Volker Braun +# 2013-2018 Jeroen Demeyer +# 2016-2021 Frédéric Chapoton +# 2017-2018 Erik M. Bray +# 2020 Marc Mezzarobba +# 2020-2023 Matthias Koeppe +# 2022 John H. Palmieri +# 2022 Sébastien Labbé +# 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + + +class MarkedOutput(str): + """ + A subclass of string with context for whether another string + matches it. + + EXAMPLES:: + + sage: from sage.doctest.marked_output import MarkedOutput + sage: s = MarkedOutput("abc") + sage: s.rel_tol + 0 + sage: s.update(rel_tol = .05) + 'abc' + sage: s.rel_tol + 0.0500000000000000 + + sage: MarkedOutput("56 µs") + '56 \xb5s' + """ + random = False + rel_tol = 0 + abs_tol = 0 + tol = 0 + + def update(self, **kwds): + """ + EXAMPLES:: + + sage: from sage.doctest.marked_output import MarkedOutput + sage: s = MarkedOutput("0.0007401") + sage: s.update(abs_tol = .0000001) + '0.0007401' + sage: s.rel_tol + 0 + sage: s.abs_tol + 1.00000000000000e-7 + """ + self.__dict__.update(kwds) + return self + + def __reduce__(self): + """ + Pickling. + + EXAMPLES:: + + sage: from sage.doctest.marked_output import MarkedOutput + sage: s = MarkedOutput("0.0007401") + sage: s.update(abs_tol = .0000001) + '0.0007401' + sage: t = loads(dumps(s)) # indirect doctest + sage: t == s + True + sage: t.abs_tol + 1.00000000000000e-7 + """ + return make_marked_output, (str(self), self.__dict__) + + +def make_marked_output(s, D): + """ + Auxiliary function for pickling. + + EXAMPLES:: + + sage: from sage.doctest.marked_output import make_marked_output + sage: s = make_marked_output("0.0007401", {'abs_tol':.0000001}) + sage: s + '0.0007401' + sage: s.abs_tol + 1.00000000000000e-7 + """ + ans = MarkedOutput(s) + ans.__dict__.update(D) + return ans diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 2e4823c7370..0bc4965cd09 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -43,53 +43,14 @@ from sage.misc.cachefunc import cached_function from sage.repl.preparse import preparse, strip_string_literals +from sage.doctest.rif_tol import RIFtol, add_tolerance +from sage.doctest.marked_output import MarkedOutput +from sage.doctest.check_tolerance import ( + ToleranceExceededError, check_tolerance_real_domain, + check_tolerance_complex_domain, float_regex) from .external import available_software, external_software -_RIFtol = None - - -def RIFtol(*args): - """ - Create an element of the real interval field used for doctest tolerances. - - It allows large numbers like 1e1000, it parses strings with spaces - like ``RIF(" - 1 ")`` out of the box and it carries a lot of - precision. The latter is useful for testing libraries using - arbitrary precision but not guaranteed rounding such as PARI. We use - 1044 bits of precision, which should be good to deal with tolerances - on numbers computed with 1024 bits of precision. - - The interval approach also means that we do not need to worry about - rounding errors and it is also very natural to see a number with - tolerance as an interval. - - EXAMPLES:: - - sage: from sage.doctest.parsing import RIFtol - sage: RIFtol(-1, 1) - 0.? - sage: RIFtol(" - 1 ") - -1 - sage: RIFtol("1e1000") - 1.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000?e1000 - """ - global _RIFtol - if _RIFtol is None: - try: - # We need to import from sage.all to avoid circular imports. - from sage.rings.real_mpfi import RealIntervalField - except ImportError: - from warnings import warn - warn("RealIntervalField not available, ignoring all tolerance specifications in doctests") - - def fake_RIFtol(*args): - return 0 - _RIFtol = fake_RIFtol - else: - _RIFtol = RealIntervalField(1044) - return _RIFtol(*args) - # This is the correct pattern to match ISO/IEC 6429 ANSI escape sequences: ansi_escape_sequence = re.compile(r"(\x1b[@-Z\\-~]|\x1b\[.*?[@-~]|\x9b.*?[@-~])") @@ -144,9 +105,9 @@ def parse_optional_tags( INPUT: - - ``string`` -- a string + - ``string`` -- string - - ``return_string_sans_tags`` -- (boolean, default ``False``); whether to + - ``return_string_sans_tags`` -- boolean (default: ``False``); whether to additionally return ``string`` with the optional tags removed but other comments kept and a boolean ``is_persistent`` @@ -205,7 +166,6 @@ def parse_optional_tags( sage: parse_optional_tags("sage: #this is not #needs scipy\n....: import scipy", ....: return_string_sans_tags=True) ({'scipy': None}, 'sage: #this is not \n....: import scipy', False) - """ safe, literals, state = strip_string_literals(string) split = safe.split('\n', 1) @@ -277,16 +237,15 @@ def parse_file_optional_tags(lines): INPUT: - - ``lines`` -- iterable of pairs ``(lineno, line)``. + - ``lines`` -- iterable of pairs ``(lineno, line)`` - OUTPUT: - - a dictionary whose keys are strings (tags); see :func:`parse_optional_tags` + OUTPUT: dictionary whose keys are strings (tags); + see :func:`parse_optional_tags` EXAMPLES:: sage: from sage.doctest.parsing import parse_file_optional_tags - sage: filename = tmp_filename(ext=".pyx") + sage: filename = tmp_filename(ext='.pyx') sage: with open(filename, "r") as f: ....: parse_file_optional_tags(enumerate(f)) {} @@ -338,9 +297,7 @@ def _tag_group(tag): - ``tag`` -- string - OUTPUT: - - a string; one of ``'special'``, ``'optional'``, ``'standard'``, ``'sage'`` + OUTPUT: string; one of ``'special'``, ``'optional'``, ``'standard'``, ``'sage'`` EXAMPLES:: @@ -370,7 +327,8 @@ def unparse_optional_tags(tags, prefix='# '): INPUT: - - ``tags`` -- dict or iterable of tags, as output by :func:`parse_optional_tags` + - ``tags`` -- dictionary or iterable of tags, as output by + :func:`parse_optional_tags` - ``prefix`` -- to be put before a nonempty string @@ -585,13 +543,11 @@ def parse_tolerance(source, want): INPUT: - - ``source`` -- a string, the source of a doctest - - ``want`` -- a string, the desired output of the doctest + - ``source`` -- string, the source of a doctest + - ``want`` -- string, the desired output of the doctest - OUTPUT: - - ``want`` if there are no tolerance tags specified; a - :class:`MarkedOutput` version otherwise. + OUTPUT: ``want`` if there are no tolerance tags specified; a + :class:`MarkedOutput` version otherwise EXAMPLES:: @@ -696,84 +652,7 @@ def reduce_hex(fingerprints): return "%032x" % res -class MarkedOutput(str): - """ - A subclass of string with context for whether another string - matches it. - - EXAMPLES:: - - sage: from sage.doctest.parsing import MarkedOutput - sage: s = MarkedOutput("abc") - sage: s.rel_tol - 0 - sage: s.update(rel_tol = .05) - 'abc' - sage: s.rel_tol - 0.0500000000000000 - - sage: MarkedOutput("56 µs") - '56 \xb5s' - """ - random = False - rel_tol = 0 - abs_tol = 0 - tol = 0 - - def update(self, **kwds): - """ - EXAMPLES:: - - sage: from sage.doctest.parsing import MarkedOutput - sage: s = MarkedOutput("0.0007401") - sage: s.update(abs_tol = .0000001) - '0.0007401' - sage: s.rel_tol - 0 - sage: s.abs_tol - 1.00000000000000e-7 - """ - self.__dict__.update(kwds) - return self - - def __reduce__(self): - """ - Pickling. - - EXAMPLES:: - - sage: from sage.doctest.parsing import MarkedOutput - sage: s = MarkedOutput("0.0007401") - sage: s.update(abs_tol = .0000001) - '0.0007401' - sage: t = loads(dumps(s)) # indirect doctest - sage: t == s - True - sage: t.abs_tol - 1.00000000000000e-7 - """ - return make_marked_output, (str(self), self.__dict__) - - -def make_marked_output(s, D): - """ - Auxiliary function for pickling. - - EXAMPLES:: - - sage: from sage.doctest.parsing import make_marked_output - sage: s = make_marked_output("0.0007401", {'abs_tol':.0000001}) - sage: s - '0.0007401' - sage: s.abs_tol - 1.00000000000000e-7 - """ - ans = MarkedOutput(s) - ans.__dict__.update(D) - return ans - - -class OriginalSource(): +class OriginalSource: r""" Context swapping out the pre-parsed source with the original for better reporting. @@ -873,11 +752,11 @@ def __init__(self, optional_tags=(), long=False, *, probed_tags=(), file_optiona r""" INPUT: - - ``optional_tags`` -- a list or tuple of strings. + - ``optional_tags`` -- list or tuple of strings - ``long`` -- boolean, whether to run doctests marked as taking a - long time. - - ``probed_tags`` -- a list or tuple of strings. - - ``file_optional_tags`` -- an iterable of strings. + long time + - ``probed_tags`` -- list or tuple of strings + - ``file_optional_tags`` -- an iterable of strings EXAMPLES:: @@ -948,9 +827,9 @@ def parse(self, string, *args): INPUT: - - ``string`` -- the string to parse. - - ``name`` -- optional string giving the name identifying string, - to be used in error messages. + - ``string`` -- the string to parse + - ``name`` -- (optional) string giving the name identifying string, + to be used in error messages OUTPUT: @@ -990,7 +869,7 @@ def parse(self, string, *args): sage: ex.want '0.893515349287690\n' sage: type(ex.want) - + sage: ex.want.tol 2.000000000000000000...?e-11 @@ -1328,7 +1207,7 @@ class SageOutputChecker(doctest.OutputChecker): sage: ex.want '0.893515349287690\n' sage: type(ex.want) - + sage: ex.want.tol 2.000000000000000000...?e-11 sage: OC.check_output(ex.want, '0.893515349287690', optflag) @@ -1368,73 +1247,20 @@ def human_readable(match): return '' return ansi_escape_sequence.subn(human_readable, string)[0] - def add_tolerance(self, wantval, want): - """ - Enlarge the real interval element ``wantval`` according to - the tolerance options in ``want``. - - INPUT: - - - ``wantval`` -- a real interval element - - ``want`` -- a :class:`MarkedOutput` describing the tolerance - - OUTPUT: - - - an interval element containing ``wantval`` - - EXAMPLES:: - - sage: from sage.doctest.parsing import MarkedOutput, SageOutputChecker - sage: OC = SageOutputChecker() - sage: want_tol = MarkedOutput().update(tol=0.0001) - sage: want_abs = MarkedOutput().update(abs_tol=0.0001) - sage: want_rel = MarkedOutput().update(rel_tol=0.0001) - sage: OC.add_tolerance(RIF(pi.n(64)), want_tol).endpoints() # needs sage.symbolic - (3.14127849432443, 3.14190681285516) - sage: OC.add_tolerance(RIF(pi.n(64)), want_abs).endpoints() # needs sage.symbolic - (3.14149265358979, 3.14169265358980) - sage: OC.add_tolerance(RIF(pi.n(64)), want_rel).endpoints() # needs sage.symbolic - (3.14127849432443, 3.14190681285516) - sage: OC.add_tolerance(RIF(1e1000), want_tol) - 1.000?e1000 - sage: OC.add_tolerance(RIF(1e1000), want_abs) - 1.000000000000000?e1000 - sage: OC.add_tolerance(RIF(1e1000), want_rel) - 1.000?e1000 - sage: OC.add_tolerance(0, want_tol) - 0.000? - sage: OC.add_tolerance(0, want_abs) - 0.000? - sage: OC.add_tolerance(0, want_rel) - 0 - """ - if want.tol: - if wantval == 0: - return RIFtol(want.tol) * RIFtol(-1, 1) - else: - return wantval * (1 + RIFtol(want.tol) * RIFtol(-1, 1)) - elif want.abs_tol: - return wantval + RIFtol(want.abs_tol) * RIFtol(-1, 1) - elif want.rel_tol: - return wantval * (1 + RIFtol(want.rel_tol) * RIFtol(-1, 1)) - else: - return wantval - def check_output(self, want, got, optionflags): r""" - Checks to see if the output matches the desired output. + Check to see if the output matches the desired output. If ``want`` is a :class:`MarkedOutput` instance, takes into account the desired tolerance. INPUT: - - ``want`` -- a string or :class:`MarkedOutput` - - ``got`` -- a string - - ``optionflags`` -- an integer, passed down to :class:`doctest.OutputChecker` + - ``want`` -- string or :class:`MarkedOutput` + - ``got`` -- string + - ``optionflags`` -- integer; passed down to :class:`doctest.OutputChecker` - OUTPUT: - - - boolean, whether ``got`` matches ``want`` up to the specified tolerance. + OUTPUT: boolean; whether ``got`` matches ``want`` up to the specified + tolerance EXAMPLES:: @@ -1517,6 +1343,11 @@ def check_output(self, want, got, optionflags): sage: 0 # rel tol 1 1 + Abs tol checks over the complex domain:: + + sage: [1, -1.3, -1.5 + 0.1*I, 0.5 - 0.1*I, -1.5*I] # abs tol 1.0 + [1, -1, -1, 1, -I] + Spaces before numbers or between the sign and number are ignored:: sage: print("[ - 1, 2]") # abs tol 1e-10 @@ -1547,34 +1378,17 @@ def check_output(self, want, got, optionflags): sage: OC.check_output(ex.want, 'Long-step dual simplex will be used\n1.3090169943749475', optflag) True """ - # Regular expression for floats - float_regex = re.compile(r'\s*([+-]?\s*((\d*\.?\d+)|(\d+\.?))([eE][+-]?\d+)?)') - got = self.human_readable_escape_sequences(got) - - if isinstance(want, MarkedOutput): - if want.random: - return True - elif want.tol or want.rel_tol or want.abs_tol: - # First check that the number of occurrences of floats appearing match - want_str = [g[0] for g in float_regex.findall(want)] - got_str = [g[0] for g in float_regex.findall(got)] - if len(want_str) != len(got_str): - return False - - # Then check the numbers - want_values = [RIFtol(g) for g in want_str] - want_intervals = [self.add_tolerance(v, want) for v in want_values] - got_values = [RIFtol(g) for g in got_str] - # The doctest is not successful if one of the "want" and "got" - # intervals have an empty intersection - if not all(a.overlaps(b) for a, b in zip(want_intervals, got_values)): - return False - - # Then check the part of the doctests without the numbers - # Continue the check process with floats replaced by stars - want = float_regex.sub('*', want) - got = float_regex.sub('*', got) + try: + if isinstance(want, MarkedOutput): + if want.random: + return True + elif want.tol or want.rel_tol: + want, got = check_tolerance_real_domain(want, got) + elif want.abs_tol: + want, got = check_tolerance_complex_domain(want, got) + except ToleranceExceededError: + return False if doctest.OutputChecker.check_output(self, want, got, optionflags): return True @@ -1588,20 +1402,18 @@ def check_output(self, want, got, optionflags): def do_fixup(self, want, got): r""" - Performs few changes to the strings ``want`` and ``got``. + Perform few changes to the strings ``want`` and ``got``. For example, remove warnings to be ignored. INPUT: - - ``want`` -- a string or :class:`MarkedOutput` - - ``got`` -- a string - - OUTPUT: + - ``want`` -- string or :class:`MarkedOutput` + - ``got`` -- string - A tuple: + OUTPUT: a tuple: - - bool, ``True`` when some fixup were performed and ``False`` otherwise + - boolean, ``True`` when some fixup were performed and ``False`` otherwise - string, edited wanted string - string, edited got string @@ -1641,7 +1453,6 @@ def do_fixup(self, want, got): (False, '1.3090169943749475\n', 'ANYTHING1.3090169943749475') sage: OC.do_fixup(ex.want,'Long-step dual simplex will be used\n1.3090169943749475') (True, '1.3090169943749475\n', '\n1.3090169943749475') - """ did_fixup = False @@ -1717,12 +1528,10 @@ def output_difference(self, example, got, optionflags): INPUT: - ``example`` -- a :class:`doctest.Example` instance - - ``got`` -- a string - - ``optionflags`` -- an integer, passed down to :class:`doctest.OutputChecker` - - OUTPUT: + - ``got`` -- string + - ``optionflags`` -- integer; passed down to :class:`doctest.OutputChecker` - - a string, describing how ``got`` fails to match ``example.want`` + OUTPUT: string, describing how ``got`` fails to match ``example.want`` EXAMPLES:: @@ -1836,9 +1645,6 @@ def output_difference(self, example, got, optionflags): Tolerance exceeded: 0.0 vs 10.05, tolerance +infinity > 1e-1 """ - # Regular expression for floats - float_regex = re.compile(r'\s*([+-]?\s*((\d*\.?\d+)|(\d+\.?))([eE][+-]?\d+)?)') - got = self.human_readable_escape_sequences(got) want = example.want diff = doctest.OutputChecker.output_difference(self, example, got, optionflags) @@ -1860,7 +1666,7 @@ def fail(x, y, actual, desired): for wstr, gstr in zip(want_str, got_str): w = RIFtol(wstr) g = RIFtol(gstr) - if not g.overlaps(self.add_tolerance(w, want)): + if not g.overlaps(add_tolerance(w, want)): if want.tol: if not w: fail(wstr, gstr, abs(g), want.tol) diff --git a/src/sage/doctest/reporting.py b/src/sage/doctest/reporting.py index e4f5c305b45..e6bfd52bf33 100644 --- a/src/sage/doctest/reporting.py +++ b/src/sage/doctest/reporting.py @@ -10,7 +10,7 @@ - 1: Doctest failure - 2: Bad command line syntax or invalid options - 4: Test timed out -- 8: Test exited with non-zero status +- 8: Test exited with nonzero status - 16: Test crashed with a signal (e.g. segmentation fault) - 32: TAB character found - 64: Internal error in the doctesting framework @@ -102,9 +102,9 @@ def __init__(self, controller): INPUT: - ``controller`` -- a - :class:`sage.doctest.control.DocTestController` instance. + :class:`sage.doctest.control.DocTestController` instance; Note that some methods assume that appropriate tests have - been run by the controller. + been run by the controller EXAMPLES:: @@ -152,7 +152,6 @@ def were_doctests_with_optional_tag_run(self, tag): sage: DTR = DocTestReporter(DC) sage: DTR.were_doctests_with_optional_tag_run('latex') # optional - latex True - """ if self.controller.options.optional is True or tag in self.controller.options.optional: return True @@ -227,11 +226,11 @@ def _log_failure(self, source, fail_msg, event, output=None): - ``source`` -- a source from :mod:`sage.doctest.sources` - - ``fail_msg`` -- a string + - ``fail_msg`` -- string - - ``event`` -- a string + - ``event`` -- string - - ``output`` -- optional string + - ``output`` -- (optional) string EXAMPLES:: @@ -293,25 +292,22 @@ def report(self, source, timeout, return_code, results, output, pid=None): - ``source`` -- a source from :mod:`sage.doctest.sources` - - ``timeout`` -- a boolean, whether doctests timed out + - ``timeout`` -- boolean; whether doctests timed out - - ``return_code`` -- an int, the return code of the process - running doctests on that file. + - ``return_code`` -- integer; the return code of the process + running doctests on that file - - ``results`` -- (irrelevant if ``timeout`` or - ``return_code``), a tuple + - ``results`` -- (irrelevant if ``timeout`` or ``return_code``) a tuple - ``ntests`` -- the number of doctests - ``timings`` -- a :class:`sage.doctest.sources.DictAsObject` instance - storing timing data. + storing timing data - - ``output`` -- a string, printed if there was some kind of - failure + - ``output`` -- string; printed if there was some kind of failure - - ``pid`` -- optional integer (default: ``None``). The pid of - the worker process. + - ``pid`` -- integer (default: ``None``); the pid of the worker process EXAMPLES:: @@ -407,7 +403,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): 0 sage: DTR.report(FDS, False, 0, (sum([len(t.examples) for t in doctests]), D), ....: "Good tests") - [... tests, ... s] + [... tests, ...s wall] sage: DTR.stats {'sage.doctest.reporting': {'ntests': ..., 'walltime': ...}} @@ -418,7 +414,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): 1 sage: DTR.report(FDS, False, 0, (sum([len(t.examples) for t in doctests]), D), ....: "Doctest output including the failure...") - [... tests, 1 failure, ... s] + [... tests, 1 failure, ...s wall] If the user has requested that we report on skipped doctests, we do so:: @@ -437,7 +433,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): 5 magma tests not run 2 not tested tests not run 0 tests not run because we ran out of time - [... tests, ... s] + [... tests, ...s wall] Test an internal error in the reporter:: @@ -470,7 +466,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): 1 sage: DTR.report(FDS, False, 0, (sum([len(t.examples) for t in doctests]), D), ....: "Failed test") - [... tests, 1 failure, ... s] + [... tests, 1 failure, ...s wall] """ log = self.controller.log process_name = 'process (pid={0})'.format(pid) if pid else 'process' @@ -629,7 +625,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): else: total = count_noun(ntests, "test") if not (self.controller.options.only_errors and not f): - log(" [%s, %s%.2f s]" % (total, "%s, " % (count_noun(f, "failure")) if f else "", wall)) + log(" [%s, %s%.2fs wall]" % (total, "%s, " % (count_noun(f, "failure")) if f else "", wall)) self.sources_completed += 1 @@ -684,13 +680,13 @@ def finalize(self): 0 sage: DTR.report(FDS, False, 0, (sum([len(t.examples) for t in doctests]), D), ....: "Good tests") - [... tests, ... s] + [... tests, ...s wall] sage: runner.failures = 1 sage: runner.update_results(D) 1 sage: DTR.report(FDS, False, 0, (sum([len(t.examples) for t in doctests]), D), ....: "Doctest output including the failure...") - [... tests, 1 failure, ... s] + [... tests, 1 failure, ...s wall] Now we can show the output of finalize:: diff --git a/src/sage/doctest/rif_tol.py b/src/sage/doctest/rif_tol.py new file mode 100644 index 00000000000..619b2e500cd --- /dev/null +++ b/src/sage/doctest/rif_tol.py @@ -0,0 +1,123 @@ +# sage_setup: distribution = sagemath-repl +""" +Helpers for tolerance checking in doctests +""" + +# **************************************************************************** +# Copyright (C) 2012-2018 David Roe +# 2012 Robert Bradshaw +# 2012 William Stein +# 2013 R. Andrew Ohana +# 2013 Volker Braun +# 2013-2018 Jeroen Demeyer +# 2016-2021 Frédéric Chapoton +# 2017-2018 Erik M. Bray +# 2020 Marc Mezzarobba +# 2020-2023 Matthias Koeppe +# 2022 John H. Palmieri +# 2022 Sébastien Labbé +# 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.doctest.marked_output import MarkedOutput + + +_RIFtol = None + + +def RIFtol(*args): + """ + Create an element of the real interval field used for doctest tolerances. + + It allows large numbers like 1e1000, it parses strings with spaces + like ``RIF(" - 1 ")`` out of the box and it carries a lot of + precision. The latter is useful for testing libraries using + arbitrary precision but not guaranteed rounding such as PARI. We use + 1044 bits of precision, which should be good to deal with tolerances + on numbers computed with 1024 bits of precision. + + The interval approach also means that we do not need to worry about + rounding errors and it is also very natural to see a number with + tolerance as an interval. + + EXAMPLES:: + + sage: from sage.doctest.parsing import RIFtol + sage: RIFtol(-1, 1) + 0.? + sage: RIFtol(" - 1 ") + -1 + sage: RIFtol("1e1000") + 1.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000?e1000 + """ + global _RIFtol + if _RIFtol is None: + try: + # We need to import from sage.all to avoid circular imports. + from sage.rings.real_mpfi import RealIntervalField + except ImportError: + from warnings import warn + warn("RealIntervalField not available, ignoring all tolerance specifications in doctests") + + def fake_RIFtol(*args): + return 0 + _RIFtol = fake_RIFtol + else: + _RIFtol = RealIntervalField(1044) + return _RIFtol(*args) + + +def add_tolerance(wantval, want: MarkedOutput): + """ + Enlarge the real interval element ``wantval`` according to + the tolerance options in ``want``. + + INPUT: + + - ``wantval`` -- a real interval element + - ``want`` -- a :class:`MarkedOutput` describing the tolerance + + OUTPUT: an interval element containing ``wantval`` + + EXAMPLES:: + + sage: from sage.doctest.parsing import MarkedOutput, SageOutputChecker + sage: from sage.doctest.rif_tol import add_tolerance + sage: want_tol = MarkedOutput().update(tol=0.0001) + sage: want_abs = MarkedOutput().update(abs_tol=0.0001) + sage: want_rel = MarkedOutput().update(rel_tol=0.0001) + sage: add_tolerance(RIF(pi.n(64)), want_tol).endpoints() # needs sage.symbolic + (3.14127849432443, 3.14190681285516) + sage: add_tolerance(RIF(pi.n(64)), want_abs).endpoints() # needs sage.symbolic + (3.14149265358979, 3.14169265358980) + sage: add_tolerance(RIF(pi.n(64)), want_rel).endpoints() # needs sage.symbolic + (3.14127849432443, 3.14190681285516) + sage: add_tolerance(RIF(1e1000), want_tol) + 1.000?e1000 + sage: add_tolerance(RIF(1e1000), want_abs) + 1.000000000000000?e1000 + sage: add_tolerance(RIF(1e1000), want_rel) + 1.000?e1000 + sage: add_tolerance(0, want_tol) + 0.000? + sage: add_tolerance(0, want_abs) + 0.000? + sage: add_tolerance(0, want_rel) + 0 + """ + if want.tol: + if wantval == 0: + return RIFtol(want.tol) * RIFtol(-1, 1) + else: + return wantval * (1 + RIFtol(want.tol) * RIFtol(-1, 1)) + elif want.abs_tol: + return wantval + RIFtol(want.abs_tol) * RIFtol(-1, 1) + elif want.rel_tol: + return wantval * (1 + RIFtol(want.rel_tol) * RIFtol(-1, 1)) + else: + return wantval diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index c1539088015..78c45195970 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -78,7 +78,8 @@ def get_basename(path): """ - This function returns the basename of the given path, e.g. sage.doctest.sources or doc.ru.tutorial.tour_advanced + This function returns the basename of the given path, e.g. + ``sage.doctest.sources`` or ``doc.ru.tutorial.tour_advanced``. EXAMPLES:: @@ -123,14 +124,14 @@ def get_basename(path): return basename -class DocTestSource(): +class DocTestSource: """ This class provides a common base class for different sources of doctests. INPUT: - ``options`` -- a :class:`sage.doctest.control.DocTestDefaults` - instance or equivalent. + instance or equivalent """ def __init__(self, options): """ @@ -194,17 +195,17 @@ def _process_doc(self, doctests, doc, namespace, start): INPUT: - ``doctests`` -- a running list of doctests to which the new - test(s) will be appended. + test(s) will be appended - - ``doc`` -- a list of lines of a docstring, each including - the trailing newline. + - ``doc`` -- list of lines of a docstring, each including + the trailing newline - - ``namespace`` -- a dictionary or + - ``namespace`` -- dictionary or :class:`sage.doctest.util.RecordingDict`, used in the - creation of new :class:`doctest.DocTest` s. + creation of new :class:`doctest.DocTest` s - - ``start`` -- an integer, giving the line number of the start - of this docstring in the larger file. + - ``start`` -- integer giving the line number of the start + of this docstring in the larger file EXAMPLES:: @@ -257,7 +258,7 @@ def file_optional_tags(self): def _create_doctests(self, namespace, tab_okay=None): """ - Creates a list of doctests defined in this source. + Create a list of doctests defined in this source. This function collects functionality common to file and string sources, and is called by @@ -265,18 +266,18 @@ def _create_doctests(self, namespace, tab_okay=None): INPUT: - - ``namespace`` -- a dictionary or + - ``namespace`` -- dictionary or :class:`sage.doctest.util.RecordingDict`, used in the creation of new :class:`doctest.DocTest` s. - - ``tab_okay`` -- whether tabs are allowed in this source. + - ``tab_okay`` -- whether tabs are allowed in this source OUTPUT: - - ``doctests`` -- a list of doctests defined by this source + - ``doctests`` -- list of doctests defined by this source - - ``extras`` -- a dictionary with ``extras['tab']`` either - False or a list of linenumbers on which tabs appear. + - ``extras`` -- dictionary with ``extras['tab']`` either + ``False`` or a list of linenumbers on which tabs appear EXAMPLES:: @@ -385,19 +386,19 @@ class StringDocTestSource(DocTestSource): INPUT: - ``basename`` -- string such as 'sage.doctests.sources', going - into the names of created doctests and examples. + into the names of created doctests and examples - - ``source`` -- a string, giving the source code to be parsed for - doctests. + - ``source`` -- string, giving the source code to be parsed for + doctests - ``options`` -- a :class:`sage.doctest.control.DocTestDefaults` - or equivalent. + or equivalent - - ``printpath`` -- a string, to be used in place of a filename - when doctest failures are displayed. + - ``printpath`` -- string, to be used in place of a filename + when doctest failures are displayed - - ``lineno_shift`` -- an integer (default: 0) by which to shift - the line numbers of all doctests defined in this string. + - ``lineno_shift`` -- integer (default: 0) by which to shift + the line numbers of all doctests defined in this string EXAMPLES:: @@ -429,7 +430,7 @@ class StringDocTestSource(DocTestSource): """ def __init__(self, basename, source, options, printpath, lineno_shift=0): r""" - Initialization + Initialization. TESTS:: @@ -471,18 +472,18 @@ def __iter__(self): def create_doctests(self, namespace): r""" - Creates doctests from this string. + Create doctests from this string. INPUT: - - ``namespace`` -- a dictionary or :class:`sage.doctest.util.RecordingDict`. + - ``namespace`` -- dictionary or :class:`sage.doctest.util.RecordingDict` OUTPUT: - - ``doctests`` -- a list of doctests defined by this string + - ``doctests`` -- list of doctests defined by this string - - ``tab_locations`` -- either False or a list of linenumbers - on which tabs appear. + - ``tab_locations`` -- either ``False`` or a list of linenumbers + on which tabs appear EXAMPLES:: @@ -506,10 +507,10 @@ class FileDocTestSource(DocTestSource): INPUT: - - ``path`` -- string, the filename + - ``path`` -- string; the filename - ``options`` -- a :class:`sage.doctest.control.DocTestDefaults` - instance or equivalent. + instance or equivalent EXAMPLES:: @@ -528,13 +529,12 @@ class FileDocTestSource(DocTestSource): sage: from sage.doctest.control import DocTestDefaults sage: from sage.doctest.sources import FileDocTestSource - sage: filename = tmp_filename(ext=".txtt") + sage: filename = tmp_filename(ext='.txtt') sage: FDS = FileDocTestSource(filename, DocTestDefaults()) Traceback (most recent call last): ... ValueError: unknown extension for the file to test (=...txtt), valid extensions are: .py, .pyx, .pxd, .pxi, .sage, .spyx, .tex, .rst, .rst.txt - """ def __init__(self, path, options): """ @@ -578,7 +578,7 @@ def __iter__(self): sage: from sage.doctest.control import DocTestDefaults sage: from sage.doctest.sources import FileDocTestSource - sage: filename = tmp_filename(ext=".py") + sage: filename = tmp_filename(ext='.py') sage: s = "'''\n sage: 2 + 2\n 4\n'''" sage: with open(filename, 'w') as f: ....: _ = f.write(s) @@ -660,7 +660,7 @@ def printpath(self): @lazy_attribute def basename(self): """ - The basename of this file source, e.g. sage.doctest.sources + The basename of this file source, e.g. ``sage.doctest.sources``. EXAMPLES:: @@ -732,13 +732,13 @@ def create_doctests(self, namespace): INPUT: - - ``namespace`` -- a dictionary or :class:`sage.doctest.util.RecordingDict`. + - ``namespace`` -- dictionary or :class:`sage.doctest.util.RecordingDict` OUTPUT: - - ``doctests`` -- a list of doctests defined in this file. + - ``doctests`` -- list of doctests defined in this file - - ``extras`` -- a dictionary + - ``extras`` -- dictionary EXAMPLES:: @@ -805,11 +805,11 @@ def _test_enough_doctests(self, check_extras=True, verbose=True): INPUT: - - ``check_extras`` -- bool (default ``True``), whether to check if + - ``check_extras`` -- boolean (default: ``True``); whether to check if doctests are created that do not correspond to either a ``sage:`` or a ``>>>`` prompt - - ``verbose`` -- bool (default ``True``), whether to print + - ``verbose`` -- boolean (default: ``True``); whether to print offending line numbers when there are missing or extra tests TESTS:: @@ -911,11 +911,11 @@ def parse_docstring(self, docstring, namespace, start): INPUT: - - ``docstring`` -- a string containing documentation and tests. + - ``docstring`` -- string containing documentation and tests - - ``namespace`` -- a dictionary or :class:`sage.doctest.util.RecordingDict`. + - ``namespace`` -- dictionary or :class:`sage.doctest.util.RecordingDict` - - ``start`` -- an integer, one less than the starting line number + - ``start`` -- integer; one less than the starting line number EXAMPLES:: @@ -975,7 +975,7 @@ def _init(self): def _update_quotetype(self, line): r""" - Updates the track of what kind of quoted string we're in. + Update the track of what kind of quoted string we are in. We need to track whether we're inside a triple quoted string, since a triple quoted string that starts a line @@ -1078,11 +1078,9 @@ def starting_docstring(self, line): INPUT: - - ``line`` -- a string, one line of an input file - - OUTPUT: + - ``line`` -- string; one line of an input file - - either None or a Match object. + OUTPUT: either ``None`` or a Match object EXAMPLES:: @@ -1151,13 +1149,11 @@ def ending_docstring(self, line): INPUT: - - ``line`` -- a string, one line of an input file. - - OUTPUT: + - ``line`` -- string, one line of an input file - - an object that, when evaluated in a boolean context, gives - ``True`` or ``False`` depending on whether the input line marks the - end of a docstring. + OUTPUT: an object that, when evaluated in a boolean context, gives + ``True`` or ``False`` depending on whether the input line marks the + end of a docstring EXAMPLES:: @@ -1189,8 +1185,8 @@ def _neutralize_doctests(self, reindent): INPUT: - - ``reindent`` -- an integer, the number of spaces to indent - the result. + - ``reindent`` -- integer; the number of spaces to indent + the result EXAMPLES:: @@ -1270,12 +1266,10 @@ def starting_docstring(self, line): INPUT: - - ``line`` -- a string, one line of an input file + - ``line`` -- string, one line of an input file - OUTPUT: - - - a boolean giving whether the input line marks the - start of a docstring (verbatim block). + OUTPUT: boolean; whether the input line marks the start of a docstring + (verbatim block) EXAMPLES:: @@ -1347,14 +1341,13 @@ def ending_docstring(self, line, check_skip=True): INPUT: - - ``line`` -- a string, one line of an input file - - - ``check_skip`` -- boolean (default: ``True``), used internally in starting_docstring. + - ``line`` -- string, one line of an input file - OUTPUT: + - ``check_skip`` -- boolean (default: ``True``); used internally in + ``starting_docstring`` - - a boolean giving whether the input line marks the - end of a docstring (verbatim block). + OUTPUT: boolean; whether the input line marks the end of a docstring + (verbatim block) EXAMPLES:: @@ -1449,11 +1442,9 @@ def starting_docstring(self, line): INPUT: - - ``line`` -- a string, one line of an input file + - ``line`` -- string; one line of an input file - OUTPUT: - - - either None or a Match object. + OUTPUT: either ``None`` or a Match object EXAMPLES:: @@ -1507,11 +1498,9 @@ def ending_docstring(self, line): INPUT: - - ``line`` -- a string, one line of an input file - - OUTPUT: + - ``line`` -- string; one line of an input file - - a boolean, whether the verbatim block is ending. + OUTPUT: boolean; whether the verbatim block is ending EXAMPLES:: @@ -1618,7 +1607,7 @@ def __init__(self, attrs): INPUT: - - ``attrs`` -- a dictionary. + - ``attrs`` -- dictionary EXAMPLES:: diff --git a/src/sage/doctest/test.py b/src/sage/doctest/test.py index 4907d30d58d..a6aa893bb22 100644 --- a/src/sage/doctest/test.py +++ b/src/sage/doctest/test.py @@ -29,7 +29,7 @@ Running doctests... Doctesting 1 file. sage -t --warn-long 0.0 --random-seed=0 longtime.rst - [0 tests, ...s] + [0 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -40,7 +40,7 @@ Running doctests... Doctesting 1 file. sage -t --long --warn-long 0.0 --random-seed=0 longtime.rst - [1 test, ...s] + [1 test, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -266,7 +266,7 @@ If the child process is dead and removed, the last output should be as above. However, the child process interrupted its parent process (see -``"interrupt_diehard.rst"``), and became an orphan process. Depending on the +``'interrupt_diehard.rst'``), and became an orphan process. Depending on the system, an orphan process may eventually become a zombie process instead of being removed, and then the last output would just be a blank. Hence the ``# random`` tag. @@ -442,7 +442,7 @@ Running doctests... Doctesting 1 file... sage -t... 1second.rst... - [2 tests, ... s] + [2 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -471,7 +471,7 @@ 1 long test not run 1 not tested test not run 0 tests not run because we ran out of time - [2 tests, ... s] + [2 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -488,7 +488,7 @@ 2 tests not run due to known bugs 1 not tested test not run 0 tests not run because we ran out of time - [4 tests, ... s] + [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -504,7 +504,7 @@ 1 not tested test not run 2 sage tests not run 0 tests not run because we ran out of time - [2 tests, ... s] + [2 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -533,7 +533,7 @@ Running doctests... Doctesting 1 file. sage -t --warn-long 0.0 --random-seed=0 atexit.rst - [3 tests, ... s] + [3 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -564,7 +564,7 @@ ********************************************************************** 1 item had failures: 1 of 2 in sage.doctest.tests.random_seed - [1 test, 1 failure, ...s] + [1 test, 1 failure, ...s wall] ---------------------------------------------------------------------- sage -t --warn-long 0.0 --random-seed=0 random_seed.rst # 1 doctest failed ---------------------------------------------------------------------- @@ -575,7 +575,7 @@ Running doctests... Doctesting 1 file. sage -t --warn-long 0.0 --random-seed=1 random_seed.rst - [1 test, ...s] + [1 test, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- diff --git a/src/sage/doctest/tests/fail_and_die.rst b/src/sage/doctest/tests/fail_and_die.rst index 90d7d3428e6..65e652f4f5e 100644 --- a/src/sage/doctest/tests/fail_and_die.rst +++ b/src/sage/doctest/tests/fail_and_die.rst @@ -1,4 +1,4 @@ -The ``NameError`` raised on the second line should be displayed, even +The :exc:`NameError` raised on the second line should be displayed, even if we crash immediately afterwards:: sage: import time, signal diff --git a/src/sage/doctest/tests/initial.rst b/src/sage/doctest/tests/initial.rst index 595cf2b54fa..f6eec87bec5 100644 --- a/src/sage/doctest/tests/initial.rst +++ b/src/sage/doctest/tests/initial.rst @@ -1,4 +1,4 @@ -One initial typo causes a ``NameError`` in the first test and many +One initial typo causes a :exc:`NameError` in the first test and many following failures:: sage: a = binomiak(10,5) # random to test that we still get the exception diff --git a/src/sage/doctest/util.py b/src/sage/doctest/util.py index 3fe9d3408bd..ed831598e65 100644 --- a/src/sage/doctest/util.py +++ b/src/sage/doctest/util.py @@ -23,8 +23,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.misc.timing import walltime, cputime - +from time import time as walltime +from os import sysconf, times def count_noun(number, noun, plural=None, pad_number=False, pad_noun=False): """ @@ -41,7 +41,7 @@ def count_noun(number, noun, plural=None, pad_number=False, pad_noun=False): '2 oranges' sage: count_noun(3, "peach", "peaches") '3 peaches' - sage: count_noun(1, "peach", plural="peaches", pad_noun=True) + sage: count_noun(1, "peach", plural='peaches', pad_noun=True) '1 peach ' """ if plural is None: @@ -78,7 +78,7 @@ def dict_difference(self, other): sage: from sage.doctest.control import DocTestDefaults sage: D1 = DocTestDefaults() - sage: D2 = DocTestDefaults(foobar="hello", timeout=100) + sage: D2 = DocTestDefaults(foobar='hello', timeout=100) sage: dict_difference(D2.__dict__, D1.__dict__) {'foobar': 'hello', 'timeout': 100} """ @@ -104,6 +104,219 @@ class Timer: {} sage: TestSuite(Timer()).run() """ + + def _proc_stat_cpu_seconds(self, path): + r""" + Parse a "stat" file from the ``/proc`` filesystem to get + the cputime of a process. + + This also includes the times for child processes, but only + those that have already terminated and for which ``wait()`` + was called. It is important to note that pexpect processes DO + NOT fall into that category. + + The document ``Documentation/filesystems/proc.rst`` within the + Linux kernel source tree defines a "stat" file. + + INPUT: + + - ``path`` -- string; the path to a "stat" file on the ``/proc`` + filesystem, typically "/proc//stat", from which we will + read cputime information + + OUTPUT: + + A nonnegative float representing the number of cpu-seconds + used by the process associated with ``path``. An ``OSError`` is + raised if anything goes wrong, which typically happens on + platforms that don't store this information under ``/proc``. + + TESTS: + + About all we can say for certain is that this will return a + nonnegative float or raise an ``OSError``:: + + sage: from sage.doctest.util import Timer + sage: cputime = float(0.0) + sage: path = "/proc/1/stat" + sage: try: + ....: cputime = Timer()._proc_stat_cpu_seconds(path) + ....: except OSError: + ....: pass + sage: cputime >= 0.0 + True + sage: isinstance(cputime, float) + True + + We can force an ``OSError`` with an invalid PID:: + + sage: from sage.doctest.util import Timer + sage: path = "/proc/-1/stat" + sage: cputime = Timer()._proc_stat_cpu_seconds(path) + Traceback (most recent call last): + ... + OSError: unable to access /proc/-1/stat + + Or with an unparseable file (wrong number of fields, non-float + fields, et cetera):: + + sage: from tempfile import NamedTemporaryFile + sage: from os import unlink + sage: from sage.doctest.util import Timer + sage: with NamedTemporaryFile(delete=False, mode="w") as f: + ....: _ = f.write("1 2 3 4 5") + sage: cputime = Timer()._proc_stat_cpu_seconds(f.name) + Traceback (most recent call last): + ... + OSError: unable to parse ... + sage: os.unlink(f.name) + sage: with NamedTemporaryFile(delete=False, mode="w") as f: + ....: _ = f.write("1 2 3 4 5 6 7 8 9 10 11 12 w x y z 17") + sage: cputime = Timer()._proc_stat_cpu_seconds(f.name) + Traceback (most recent call last): + ... + OSError: unable to parse ... + sage: os.unlink(f.name) + + """ + try: + with open(path, "r") as statfile: + stats = statfile.read().split() + except (FileNotFoundError, PermissionError) as e: + # FileNotFoundError: bad PID, or no /proc support + # PermissionError: can't read the stat file + raise OSError(f"unable to access {path}") from e + + if len(stats) < 17: + raise OSError(f"unable to parse {path}") + + try: + # These fields used to be documented in the proc(5) man + # page, but are now most easily found in the Linux kernel + # documentation (Documentation/filesystems/proc.rst). The + # intent is to sum the user- and kernel-mode "jiffies" for + # both the given process and its children. + cputicks = sum( float(s) for s in stats[13:17] ) + except (ArithmeticError, TypeError, ValueError) as e: + # ArithmeticError: unexpected (non-numeric?) values in fields + # TypeError/ValueError: fields can't be converted to float + raise OSError(f"unable to parse {path}") from e + + try: + hertz = sysconf("SC_CLK_TCK") + except (ValueError) as e: + # ValueError: SC_CLK_TCK doesn't exist + raise OSError("SC_CLK_TCK sysconf not found") from e + + if hertz <= 0: + # The python documentation for os.sysconf() says, "If the + # configuration value specified by name isn’t defined, -1 + # is returned." Having tried this with a junk value, I + # don't believe it: I got a ValueError that was handled + # above. Nevertheless, we play it safe here and turn a -1 + # into an OSError. We check for zero, too, because we're + # about to divide by it. + raise OSError("SC_CLK_TCK sysconf is nonpositive") + + return (cputicks / hertz) + + def _quick_cputime(self, expect_objects): + r""" + A fast replacement for ``sage.misc.timing.cputime``. + + This is a "reliable" replacement (on Linux/BSD) that takes + subprocesses (particularly pexpect interfaces) into + account. The ``cputime()`` function from the ``misc`` module + can be passed ``subprocesses=True``, but this has a few + faults; mainly that it relies on each pexpect interface to + implement its own ``cputime()`` function. And most of our + pexpect interfaces either don't implement one, or implement + one in a way that requires the subprocess (being pexpected) to + be in perfect working condition -- that will often not be the + case at the end of a doctest line. + + INPUT: + + - ``expect_objects`` -- list; a list of + :class:`sage.interfaces.expect.Expect` instances whose CPU + times will be included in the total + + OUTPUT: + + A float measuring the cputime in seconds of the sage process + and all its subprocesses. + + TESTS: + + About all we can say for certain is that this will return a + nonnegative float:: + + sage: from sage.doctest.util import Timer + sage: from sage.interfaces.quit import expect_objects + sage: cputime = Timer()._quick_cputime(expect_objects) + sage: cputime >= 0.0 + True + sage: isinstance(cputime, float) + True + + If an error occurs in :meth:`_proc_stat_cpu_seconds`, this + function should still return a valid answer, albeit one that + is missing timing information for the PID that failed:: + + sage: class FakeExpect: + ....: def __call__(self): + ....: return self + ....: def is_running(self): + ....: return True + ....: def pid(self): + ....: return -1 + sage: e = FakeExpect() + sage: from sage.doctest.util import Timer + sage: cputime = Timer()._quick_cputime([e]) + sage: cputime >= 0.0 + True + sage: isinstance(cputime, float) + True + """ + # Start by using os.times() to get the cputime for sage itself + # and any subprocesses that have been wait()ed for and that + # have terminated. + cputime = sum( times()[:4] ) + + # Now try to get the times for any pexpect interfaces, since + # they do not fall into the category above. + for s in expect_objects: + S = s() + if S and S.is_running(): + try: + # This will fail anywhere but linux/BSD, but + # there's no good cross-platform way to get the + # cputimes from pexpect interfaces without totally + # mucking up the doctests. + path = f"/proc/{S.pid()}/stat" + cputime += self._proc_stat_cpu_seconds(path) + except OSError: + # If we're on macOS, we can fall back to using + # psutil, but only if it's installed. It's usually + # installed as a transitive dependency (ipython + # needs it), but it isn't explicitly listed as + # a dependency of sagelib. + try: + from psutil import (NoSuchProcess, + Process, + ZombieProcess) + try: + cputime += sum(Process(S.pid()).cpu_times()[0:2]) + except (ValueError, NoSuchProcess, ZombieProcess): + # ValueError: invalid (e.g. negative) PID + # NoSuchProcess: it's gone + # ZombieProcess: PID refers to a zombie + pass + except ImportError: + pass + + return cputime + def start(self): """ Start the timer. @@ -116,7 +329,8 @@ def start(self): sage: Timer().start() {'cputime': ..., 'walltime': ...} """ - self.cputime = cputime() + from sage.interfaces.quit import expect_objects + self.cputime = self._quick_cputime(expect_objects) self.walltime = walltime() return self @@ -134,8 +348,9 @@ def stop(self): sage: timer.stop() {'cputime': ..., 'walltime': ...} """ - self.cputime = cputime(self.cputime) - self.walltime = walltime(self.walltime) + from sage.interfaces.quit import expect_objects + self.cputime = self._quick_cputime(expect_objects) - self.cputime + self.walltime = walltime() - self.walltime return self def annotate(self, object): @@ -198,7 +413,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Test for non-equality + Test for non-equality. EXAMPLES:: @@ -423,7 +638,7 @@ def __init__(self, base): """ INPUT: - - base -- a string: the name of the module. + - ``base`` -- string; the name of the module EXAMPLES:: @@ -436,12 +651,14 @@ def __init__(self, base): def __setitem__(self, index, value): """ - Sets the value at a given indentation level. + Set the value at a given indentation level. INPUT: - - index -- a positive integer, the indentation level (often a multiple of 4, but not necessarily) - - value -- a string, the name of the class or function at that indentation level. + - ``index`` -- positive integer; the indentation level (often a + multiple of 4, but not necessarily) + - ``value`` -- string; the name of the class or function at that + indentation level EXAMPLES:: diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index 2b9dd28b13b..c2ad0f04cea 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -46,7 +46,7 @@ class initialization directly. from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.fraction_field import FractionField from sage.rings.fraction_field import FractionField_generic -from sage.rings.quotient_ring import is_QuotientRing +from sage.rings.quotient_ring import QuotientRing_nc from sage.schemes.affine.affine_morphism import SchemeMorphism_polynomial_affine_space from sage.schemes.affine.affine_morphism import SchemeMorphism_polynomial_affine_space_field from sage.schemes.affine.affine_morphism import SchemeMorphism_polynomial_affine_space_finite_field @@ -78,7 +78,7 @@ class DynamicalSystem_affine(SchemeMorphism_polynomial_affine_space, rational function, or a list or tuple of polynomials or rational functions - - ``domain`` -- optional affine space or subscheme of such; + - ``domain`` -- (optional) affine space or subscheme of such; the following combinations of ``morphism_or_polys`` and ``domain`` are meaningful: @@ -268,7 +268,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None): PR = PR.ring().change_ring(K).fraction_field() polys = [PR(poly) for poly in polys] else: - quotient_ring = any(is_QuotientRing(poly.parent()) for poly in polys) + quotient_ring = any(isinstance(poly.parent(), QuotientRing_nc) for poly in polys) # If any of the list entries lies in a quotient ring, we try # to lift all entries to a common polynomial ring. if quotient_ring: @@ -353,7 +353,7 @@ def homogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, + - ``n`` -- tuple of nonnegative integers; if `n` is an integer, then the two values of the tuple are assumed to be the same OUTPUT: :class:`DynamicalSystem_projective` @@ -434,7 +434,7 @@ def dynatomic_polynomial(self, period): INPUT: - - ``period`` -- a positive integer or a list/tuple `[m,n]`, + - ``period`` -- positive integer or a list/tuple `[m,n]`, where `m` is the preperiod and `n` is the period OUTPUT: @@ -547,7 +547,7 @@ def dynatomic_polynomial(self, period): def nth_iterate_map(self, n): r""" - Return the ``n``-th iterate of ``self``. + Return the `n`-th iterate of ``self``. ALGORITHM: @@ -559,7 +559,7 @@ def nth_iterate_map(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: a dynamical system of affine space @@ -618,13 +618,13 @@ def nth_iterate_map(self, n): def nth_iterate(self, P, n): r""" - Return the ``n``-th iterate of the point ``P`` by this dynamical system. + Return the `n`-th iterate of the point `P` by this dynamical system. INPUT: - ``P`` -- a point in the map's domain - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: a point in the map's codomain @@ -672,7 +672,7 @@ def nth_iterate(self, P, n): def orbit(self, P, n): r""" - Return the orbit of ``P`` by the dynamical system. + Return the orbit of `P` by the dynamical system. Let `F` be this dynamical system. If `n` is an integer return `[P, F(P), \ldots, F^n(P)]`. If `n` is a list or @@ -682,10 +682,10 @@ def orbit(self, P, n): - ``P`` -- a point in the map's domain - - ``n`` -- a non-negative integer or list or tuple of - two non-negative integers + - ``n`` -- nonnegative integer or list or tuple of + two nonnegative integers - OUTPUT: a list of points in the map's codomain + OUTPUT: list of points in the map's codomain EXAMPLES:: @@ -735,22 +735,20 @@ def orbit(self, P, n): def multiplier(self, P, n, check=True): r""" - Return the multiplier of the point ``P`` of period ``n`` by this + Return the multiplier of the point `P` of period `n` by this dynamical system. INPUT: - ``P`` -- a point on domain of the map - - ``n`` -- a positive integer, the period of ``P`` + - ``n`` -- positive integer, the period of `P` - - ``check`` -- (default: ``True``) boolean, verify that ``P`` - has period ``n`` + - ``check`` -- boolean (default: ``True``); verify that `P` + has period `n` - OUTPUT: - - A square matrix of size ``self.codomain().dimension_relative()`` in - the ``base_ring`` of the map. + OUTPUT: a square matrix of size ``self.codomain().dimension_relative()`` + in the ``base_ring`` of the map EXAMPLES:: @@ -819,9 +817,7 @@ def conjugate(self, M): - ``M`` -- a square invertible matrix - OUTPUT: - - An affine dynamical system + OUTPUT: an affine dynamical system EXAMPLES:: @@ -853,7 +849,6 @@ def conjugate(self, M): Dynamical System of Affine Space of dimension 1 over Integer Ring Defn: Defined on coordinates by sending (x) to (x^3 + x^2 - x - 5) - """ d = self.codomain().ngens() f = self.homogenize(d).conjugate(M) @@ -951,7 +946,7 @@ def reduce_base_field(self): the base ring is a number field, ``QQbar``, a finite field, or algebraic closure of a finite field. - OUTPUT: A dynamical system + OUTPUT: a dynamical system EXAMPLES:: @@ -998,13 +993,13 @@ def orbit_structure(self, P): Every point is preperiodic over a finite field. This function returns the pair `[m,n]` where `m` is the - preperiod and `n` is the period of the point ``P`` by this map. + preperiod and `n` is the period of the point `P` by this map. INPUT: - ``P`` -- a point in the map's domain - OUTPUT: a list `[m, n]` of integers + OUTPUT: list `[m, n]` of integers EXAMPLES:: diff --git a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py index be1ef46b251..0c27d8e2bde 100644 --- a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py @@ -55,9 +55,9 @@ class DynamicalSystem_Berkovich(Element, metaclass=InheritComparisonClasscallMet INPUT: - - ``dynamical_system`` -- A :class:`DynamicalSystem` + - ``dynamical_system`` -- a :class:`DynamicalSystem` over affine or projective space. If this input is not defined - over a p-adic field, then ``domain`` MUST be specified. + over a `p`-adic field, then ``domain`` MUST be specified. - ``domain`` -- (optional) affine or projective Berkovich space over `\CC_p`. ``domain`` must be specified if ``dynamical_system`` @@ -345,7 +345,7 @@ def domain(self): """ Return the domain of this dynamical system. - OUTPUT: A Berkovich space over ``Cp``. + OUTPUT: a Berkovich space over ``Cp`` EXAMPLES:: @@ -361,7 +361,7 @@ def as_scheme_dynamical_system(self): r""" Return this dynamical system as :class:`DynamicalSystem`. - OUTPUT: An affine or projective :class:`DynamicalSystem`. + OUTPUT: an affine or projective :class:`DynamicalSystem` EXAMPLES:: @@ -376,13 +376,13 @@ def as_scheme_dynamical_system(self): def __getitem__(self, i): """ - Return the ith polynomial. + Return the `i`-th polynomial. INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - OUTPUT: An element of polynomial ring or a + OUTPUT: an element of polynomial ring or a fraction field of a polynomial ring EXAMPLES:: @@ -399,7 +399,7 @@ def defining_polynomials(self): """ Return the defining polynomials. - OUTPUT: A tuple of polynomials that defines the + OUTPUT: a tuple of polynomials that defines the dynamical system. EXAMPLES:: @@ -417,7 +417,7 @@ def base_ring(self): """ The base ring of this dynamical system, that is, the field of definition of the coefficients. - OUTPUT: A field. + OUTPUT: a field EXAMPLES:: @@ -442,7 +442,7 @@ def _repr_(self): r""" Return a string representation of this dynamical system. - OUTPUT: a string. + OUTPUT: string EXAMPLES:: @@ -471,11 +471,11 @@ class DynamicalSystem_Berkovich_projective(DynamicalSystem_Berkovich): - ``dynamical_system`` -- a :class:`DynamicalSystem_Projective` of relative dimension 1. If this input is not defined - over a p-adic field, then ``domain`` MUST be specified. + over a `p`-adic field, then ``domain`` MUST be specified. - ``domain`` -- (optional) projective Berkovich space over `\CC_p`. If the input to ``dynamical_system`` is - not defined over a p-adic field, ``domain`` + not defined over a `p`-adic field, ``domain`` must be specified. EXAMPLES: @@ -566,13 +566,13 @@ def __init__(self, dynamical_system, domain=None): def scale_by(self, t): """ - Scales each coordinate of this dynamical system by a factor of ``t``. + Scale each coordinate of this dynamical system by a factor of `t`. INPUT: - - ``t`` -- a ring element. + - ``t`` -- a ring element - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -602,9 +602,9 @@ def scale_by(self, t): def normalize_coordinates(self): r""" - Normalizes the coordinates of the inducing map. + Normalize the coordinates of the inducing map. - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -616,7 +616,7 @@ def normalize_coordinates(self): Defn: Defined on coordinates by sending (x : y) to (x^2 : y^2) - Normalize_coordinates may sometimes fail over p-adic fields:: + Normalize_coordinates may sometimes fail over `p`-adic fields:: sage: g = DynamicalSystem_Berkovich([2*x^2, x*y]) sage: g.normalize_coordinates() # not tested @@ -646,9 +646,9 @@ def conjugate(self, M, adjugate=False, new_ideal=None): INPUT: - - ``M`` -- a square invertible matrix. + - ``M`` -- a square invertible matrix - - ``adjugate`` -- (default: ``False``) boolean, also classically + - ``adjugate`` -- boolean (default: ``False``); also classically called adjoint, takes a square matrix ``M`` and finds the transpose of its cofactor matrix. Used for conjugation in place of inverse when specified ``'True'``. Functionality is the same in projective space. @@ -657,7 +657,7 @@ def conjugate(self, M, adjugate=False, new_ideal=None): Used to specify an extension in the case where ``M`` is not defined over the same number field as this dynamical system. - OUTPUT: a dynamical system. + OUTPUT: a dynamical system EXAMPLES:: @@ -711,7 +711,7 @@ def conjugate(self, M, adjugate=False, new_ideal=None): def resultant(self, normalize=False): r""" - Computes the resultant of the defining polynomials of + Compute the resultant of the defining polynomials of this dynamical system. If ``normalize`` is ``True``, then first normalize the coordinate @@ -719,9 +719,9 @@ def resultant(self, normalize=False): INPUT: - - ``normalize`` -- (default: ``False``) boolean. + - ``normalize`` -- boolean (default: ``False``) - OUTPUT: an element of the base ring of this map. + OUTPUT: an element of the base ring of this map EXAMPLES:: @@ -751,10 +751,10 @@ def dehomogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers; if ``n`` is an integer, - then the two values of the tuple are assumed to be the same. + - ``n`` -- tuple of nonnegative integers; if `n` is an integer, + then the two values of the tuple are assumed to be the same - OUTPUT: A dynamical system on affine Berkovich space. + OUTPUT: a dynamical system on affine Berkovich space EXAMPLES:: @@ -779,15 +779,15 @@ def __call__(self, x, type_3_pole_check=True): INPUT: - - ``x`` -- a point of projective Berkovich space over ``Cp``. + - ``x`` -- a point of projective Berkovich space over ``Cp`` - - ``type_3_pole_check`` -- (default ``True``) A bool. WARNING: + - ``type_3_pole_check`` -- boolean (default: ``True``); WARNING: changing the value of ``type_3_pole_check`` can lead to mathematically incorrect answers. Only set to ``False`` if there are NO poles of the dynamical system in the disk corresponding to the type III point ``x``. See Examples. - OUTPUT: A point of projective Berkovich space over ``Cp``. + OUTPUT: a point of projective Berkovich space over ``Cp`` EXAMPLES:: @@ -869,7 +869,7 @@ def __call__(self, x, type_3_pole_check=True): else: new_poly.append(ring_of_integers(i).mod(ideal)) new_poly = R(new_poly) - fraction.append((new_poly)) + fraction.append(new_poly) gcd = fraction[0].gcd(fraction[1]) num = fraction[0].quo_rem(gcd)[0] dem = fraction[1].quo_rem(gcd)[0] @@ -966,8 +966,8 @@ class DynamicalSystem_Berkovich_affine(DynamicalSystem_Berkovich): INPUT: - - ``dynamical_system`` -- A :class:`DynamicalSystem_affine` - of relative dimension 1. + - ``dynamical_system`` -- a :class:`DynamicalSystem_affine` + of relative dimension 1 - ``domain`` -- (optional) affine or projective Berkovich space over `\CC_p`. If the input to ``dynamical_system`` is @@ -1054,7 +1054,7 @@ def homogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, + - ``n`` -- tuple of nonnegative integers. If `n` is an integer, then the two values of the tuple are assumed to be the same OUTPUT: a dynamical system on projective Berkovich space diff --git a/src/sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py b/src/sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py index 93c402d4695..43ca8843fe8 100644 --- a/src/sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +++ b/src/sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py @@ -386,9 +386,10 @@ def __call__(self, input): INPUT: - ``input`` -- one value that can be evaluated - with the generators of this dynamical semigroup. + with the generators of this dynamical semigroup - OUTPUT: A set of the resulting values after applying all of this dynamical semigroup's generators to ``input``. + OUTPUT: a set of the resulting values after applying all of this + dynamical semigroup's generators to ``input`` EXAMPLES:: @@ -423,7 +424,7 @@ def base_ring(self): The base ring of this dynamical semigroup. This is identical to the base ring of all of its defining dynamical system. - OUTPUT: A ring. + OUTPUT: a ring EXAMPLES:: @@ -441,7 +442,7 @@ def change_ring(self, new_ring): INPUT: - - ``new_ring`` -- a ring. + - ``new_ring`` -- a ring OUTPUT: @@ -471,7 +472,7 @@ def domain(self): r""" Return the domain of the generators of this dynamical semigroup. - OUTPUT: A subscheme of a projective space or affine space. + OUTPUT: a subscheme of a projective space or affine space EXAMPLES:: @@ -486,7 +487,7 @@ def codomain(self): r""" Return the codomain of the generators of this dynamical semigroup. - OUTPUT: A subscheme of a projective space or affine space. + OUTPUT: a subscheme of a projective space or affine space EXAMPLES:: @@ -501,7 +502,7 @@ def defining_polynomials(self): r""" Return the set of polynomials that define the generators of this dynamical semigroup. - OUTPUT: A set of polynomials. + OUTPUT: a set of polynomials EXAMPLES:: @@ -519,7 +520,7 @@ def defining_systems(self): r""" Return the generators of this dynamical semigroup. - OUTPUT: A tuple of dynamical systems. + OUTPUT: a tuple of dynamical systems EXAMPLES:: @@ -541,7 +542,7 @@ def nth_iterate(self, p, n): INPUT: - ``p`` -- a value on which dynamical systems can evaluate - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: a set of values @@ -619,7 +620,6 @@ def nth_iterate(self, p, n): sage: one = QQ(1) sage: f.nth_iterate(2, one) {(3 : 1), (4 : 1)} - """ n = ZZ(n) if n < 0: @@ -639,11 +639,11 @@ def orbit(self, p, n): INPUT: - - `p` -- value on which this dynamical semigroup can be evaluated - - `n` -- a nonnegative integer or a list or tuple of length 2 describing an + - ``p`` -- value on which this dynamical semigroup can be evaluated + - ``n`` -- nonnegative integer or a list or tuple of length 2 describing an interval of the number line containing entirely nonnegative integers - OUTPUT: a tuple of sets of values on the domain of this dynamical semigroup. + OUTPUT: a tuple of sets of values on the domain of this dynamical semigroup EXAMPLES:: @@ -753,13 +753,15 @@ def orbit(self, p, n): def specialization(self, assignments): r""" - Returns the specialization of the generators of this dynamical semigroup. + Return the specialization of the generators of this dynamical semigroup. INPUT: - - `assignments` -- argument for specialization of the generators of this dynamical semigroup. + - ``assignments`` -- argument for specialization of the generators of + this dynamical semigroup - OUTPUT: a dynamical semigroup with the specialization of the generators of this dynamical semigroup. + OUTPUT: a dynamical semigroup with the specialization of the generators + of this dynamical semigroup EXAMPLES:: @@ -846,7 +848,6 @@ def __mul__(self, other_dynamical_semigroup): OUTPUT: :class:`DynamicalSemigroup` - EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) @@ -986,7 +987,7 @@ def __pow__(self, n): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: :class:`DynamicalSemigroup` @@ -1123,7 +1124,7 @@ def _repr_(self): r""" Return the :class:`String` representation of this dynamical semigroup. - OUTPUT: A :class:`String` displaying information about this dynamical semigroup. + OUTPUT: a :class:`String` displaying information about this dynamical semigroup EXAMPLES:: @@ -1154,7 +1155,7 @@ def __eq__(self, other): OUTPUT: - A boolean that is True if and only if the generators of the two + A boolean that is ``True`` if and only if the generators of the two dynamical semigroups are equal as sets and no generator is of degree 1. EXAMPLES:: @@ -1221,8 +1222,8 @@ class DynamicalSemigroup_projective(DynamicalSemigroup): INPUT: - - ``ds_data`` -- list or tuple of dynamical systems or objects that define dynamical systems - over projective space. + - ``ds_data`` -- list or tuple of dynamical systems or objects that define + dynamical systems over projective space OUTPUT: :class:`DynamicalSemigroup_projective` @@ -1277,7 +1278,7 @@ def dehomogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, + - ``n`` -- tuple of nonnegative integers; if `n` is an integer, then the two values of the tuple are assumed to be the same OUTPUT: :class:`DynamicalSemigroup_affine` @@ -1349,7 +1350,7 @@ class DynamicalSemigroup_affine(DynamicalSemigroup): INPUT: - ``ds_data`` -- list or tuple of dynamical systems or objects that define dynamical systems - over affine space. + over affine space OUTPUT: :class:`DynamicalSemigroup_affine` @@ -1403,7 +1404,7 @@ def homogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, + - ``n`` -- tuple of nonnegative integers; if `n` is an integer, then the two values of the tuple are assumed to be the same OUTPUT: :class:`DynamicalSemigroup_projective` diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index d0d662dcc57..76ba5864fe6 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -45,7 +45,8 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, iso_type=False): r""" - Compute the automorphism group for ``rational_function`` via the method of fixed points + Compute the automorphism group for ``rational_function`` via the method of + fixed points. ALGORITHM: @@ -55,13 +56,14 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, - ``rational_function`` -- Rational Function defined over `\ZZ` or `\QQ` - - ``return_functions`` -- Boolean value; ``True`` will return elements in the automorphism group - as linear fractional transformations. ``False`` will return elements as `PGL_2` matrices + - ``return_functions`` -- boolean value; ``True`` will return elements in + the automorphism group as linear fractional transformations. ``False`` + will return elements as `PGL_2` matrices. - - ``iso_type`` -- Boolean; ``True`` will cause the classification of the finite automorphism - group to also be returned + - ``iso_type`` -- boolean; ``True`` will cause the classification of the + finite automorphism group to also be returned - OUTPUT: a list of automorphisms that make up the automorphism group + OUTPUT: list of automorphisms that make up the automorphism group of ``rational_function`` EXAMPLES:: @@ -410,11 +412,11 @@ def CRT_helper(automorphisms, moduli): INPUT: - - ``automorphisms`` -- a list of lists of automorphisms over various `Zmod(p^k)` + - ``automorphisms`` -- list of lists of automorphisms over various `Zmod(p^k)` - ``moduli`` -- list of the various `p^k` - OUTPUT: a list of automorphisms over `Zmod(M)` + OUTPUT: list of automorphisms over `Zmod(M)` EXAMPLES:: @@ -459,15 +461,16 @@ def CRT_automorphisms(automorphisms, order_elts, degree, moduli): INPUT: - - ``automorphisms`` -- a list of lists of automorphisms over various `Zmod(p^k)` + - ``automorphisms`` -- list of lists of automorphisms over various `Zmod(p^k)` - - ``order_elts`` -- a list of lists of the orders of the elements of ``automorphisms`` + - ``order_elts`` -- list of lists of the orders of the elements of ``automorphisms`` - - ``degree`` -- a positive integer + - ``degree`` -- positive integer - ``moduli`` -- list of prime powers, i.e., `p^k` - OUTPUT: a list containing a list of automorphisms over `Zmod(M)` and the product of the moduli + OUTPUT: list containing a list of automorphisms over `Zmod(M)` and the + product of the moduli EXAMPLES:: @@ -503,17 +506,17 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, INPUT: - - ``automorphisms`` -- a list of lists of automorphisms over various `Zmod(p^k)` + - ``automorphisms`` -- list of lists of automorphisms over various `Zmod(p^k)` - - ``rational_function`` -- A one variable rational function + - ``rational_function`` -- a one variable rational function - - ``ht_bound`` -- a positive integer + - ``ht_bound`` -- positive integer - - ``M`` -- a positive integer, a product of prime powers + - ``M`` -- positive integer, a product of prime powers - - ``return_functions`` -- (default: ``False``) boolean + - ``return_functions`` -- boolean (default: ``False``) - OUTPUT: a list of automorphisms over `\ZZ` + OUTPUT: list of automorphisms over `\ZZ` EXAMPLES:: @@ -558,15 +561,15 @@ def remove_redundant_automorphisms(automorphisms, order_elts, moduli, integral_a INPUT: - - ``automorphisms`` -- a list of lists of automorphisms + - ``automorphisms`` -- list of lists of automorphisms - - ``order_elts`` -- a list of lists of the orders of the elements of ``automorphisms`` + - ``order_elts`` -- list of lists of the orders of the elements of ``automorphisms`` - - ``moduli`` -- a list of prime powers + - ``moduli`` -- list of prime powers - ``integral_autos`` -- list of known automorphisms - OUTPUT: a list of automorphisms + OUTPUT: list of automorphisms EXAMPLES:: @@ -631,10 +634,11 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound=4, return_fun - ``prime_lower_bound`` -- (default: 4) a positive integer; a lower bound for the primes to use for the Chinese Remainder Theorem step - - ``return_functions`` -- (default: ``True``) boolean; ``True`` returns linear fractional transformations - False returns elements of `PGL(2,\QQ)` + - ``return_functions`` -- boolean (default: ``True``); ``True`` returns + linear fractional transformations ``False`` returns elements of `PGL(2,\QQ)` - - ``iso_type`` -- (default: ``False``) boolean; ``True`` returns the isomorphism type of the automorphism group + - ``iso_type`` -- boolean (default: ``False``); ``True`` returns the + isomorphism type of the automorphism group OUTPUT: a complete list of automorphisms of ``rational_function`` @@ -840,14 +844,16 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret - ``rational_function`` -- a rational function defined over the fraction field of a polynomial ring in one variable with finite field coefficients - - ``absolute`` -- (default: ``False``) boolean; ``True`` returns the absolute automorphism group and a field of definition + - ``absolute`` -- boolean (default: ``False``); ``True`` returns the + absolute automorphism group and a field of definition - - ``iso_type`` -- (default: ``False``) boolean; ``True`` returns the isomorphism type of the automorphism group + - ``iso_type`` -- boolean (default: ``False``); ``True`` returns the + isomorphism type of the automorphism group - - ``return_functions`` -- (default: ``False``) boolean; ``True`` returns linear fractional transformations - False returns elements of `PGL(2)` + - ``return_functions`` -- boolean (default: ``False``); ``True`` returns + linear fractional transformations ``False`` returns elements of `PGL(2)` - OUTPUT: a list of automorphisms of ``rational_function`` + OUTPUT: list of automorphisms of ``rational_function`` EXAMPLES:: @@ -1088,7 +1094,7 @@ def three_stable_points(rational_function, invariant_list): - ``rational_function`` -- rational function `\phi` defined over finite field `E` - - ``invariant_list`` -- a list of at least `3` points of `\mathbb{P}^1(E)` that + - ``invariant_list`` -- list of at least `3` points of `\mathbb{P}^1(E)` that is stable under `Aut_{\phi}(E)` OUTPUT: list of automorphisms @@ -1381,7 +1387,7 @@ def order_p_automorphisms(rational_function, pre_image): if case == 'fix': T = [x[0] for x in pre_image] elif case == 'F-pre_images': - T = [x for x in pre_image[0][1]] + T = list(pre_image[0][1]) else: T = [] @@ -1390,10 +1396,10 @@ def order_p_automorphisms(rational_function, pre_image): pt = guy[0] # treat case of multiple F-rational fixed points or # 1 F-rational fixed point with F-rational pre-images - if T != []: + if T: M = [t for t in T if t != pt] m = len(M) - if pt == [F(1),F(0)]: + if pt == [F(1), F(0)]: for i in range(1, m): s = z + M[i][0] - M[0][0] if s(phi(z)) == phi(s(z)): @@ -1401,8 +1407,8 @@ def order_p_automorphisms(rational_function, pre_image): else: u = F(1) / (z - pt[0]) u_inv = pt[0] + F(1)/z - for i in range(1,m): - if M[0] == [F(1),F(0)]: + for i in range(1, m): + if M[0] == [F(1), F(0)]: uy1 = 0 else: uy1 = u(M[0][0]) @@ -1460,7 +1466,7 @@ def automorphisms_fixing_pair(rational_function, pair, quad): - ``pair`` -- a pair of points of `\mathbb{P}^1(E)` - - ``quad`` -- Boolean: an indicator if this is a quadratic pair of points + - ``quad`` -- boolean; an indicator if this is a quadratic pair of points OUTPUT: set of automorphisms with order prime to characteristic defined over `E` that fix the pair, excluding the identity @@ -1704,7 +1710,7 @@ def which_group(list_of_elements): - ``list_of_elements`` -- a finite list of elements of `PGL(2,K)` that we know a priori form a group - OUTPUT: a string -- the isomorphism type of the group + OUTPUT: string; the isomorphism type of the group EXAMPLES:: @@ -1835,7 +1841,7 @@ def conjugating_set_initializer(f, g): of which no `n+1` are linearly dependent. Used to specify a possible conjugation from `f` to `g`. - - ``possible_targets`` -- a list of tuples of the form (``points``, ``repeated``). ``points`` + - ``possible_targets`` -- list of tuples of the form (``points``, ``repeated``). ``points`` is a list of ``points`` which are possible targets for point(s) in ``source``. ``repeated`` specifies how many points in ``source`` have points in ``points`` as their possible target. @@ -2060,12 +2066,12 @@ def greedy_independence_check(P, repeated_mult, point_to_mult): - ``P`` -- a projective space - - ``repeated_mult`` -- a dictionary of integers to lists of points of + - ``repeated_mult`` -- dictionary of integers to lists of points of the projective space ``P``. The list of points should be conjugation invariant. The keys are considered as weights, and this function attempts to minimize the total weight - - ``point_to_mult`` -- a dictionary of points of ``P`` to tuples of the form + - ``point_to_mult`` -- dictionary of points of ``P`` to tuples of the form (multiplier, level), where multiplier is the characteristic polynomial of the multiplier of the point, and level is the number of preimages taken to find the point @@ -2078,9 +2084,9 @@ def greedy_independence_check(P, repeated_mult, point_to_mult): Otherwise, a tuple of the form (``source``, ``corresponding``) is returned. - ``source`` -- the set `U` of the conjugation invariant pair. A set of `n+2` points - of the domain of `f`, of which no `n+1` are linearly dependent. + of the domain of `f`, of which no `n+1` are linearly dependent - - ``corresponding`` -- a list of tuples of the form ((multiplier, level), repeat) where the + - ``corresponding`` -- list of tuples of the form ((multiplier, level), repeat) where the (multiplier, level) pair is the multiplier of a point in ``source`` and repeat specifies how many points in source have that (multiplier, level) pair. This information specifies the set `V` of the invariant pair. @@ -2138,14 +2144,14 @@ def conjugating_set_helper(f, g, num_cpus, source, possible_targets): - ``num_cpus`` -- the number of threads to run in parallel - - ``source`` -- a list of `n+2` conjugation invariant points, of which - no `n+1` are linearly dependent. + - ``source`` -- list of `n+2` conjugation invariant points, of which + no `n+1` are linearly dependent - - ``possible_targets`` -- a list of tuples of the form (``points``, ``repeated``). ``points`` + - ``possible_targets`` -- list of tuples of the form (``points``, ``repeated``). ``points`` is a list of ``points`` which are possible targets for point(s) in ``source``. ``repeated`` specifies how many points in ``source`` have points in ``points`` as their possible target. - OUTPUT: a list of elements of PGL which conjugate ``f`` to ``g``. + OUTPUT: list of elements of PGL which conjugate ``f`` to ``g`` EXAMPLES:: @@ -2282,14 +2288,14 @@ def is_conjugate_helper(f, g, num_cpus, source, possible_targets): - ``num_cpus`` -- the number of threads to run in parallel - - ``source`` -- a list of `n+2` conjugation invariant points, of which - no `n+1` are linearly dependent. + - ``source`` -- list of `n+2` conjugation invariant points, of which + no `n+1` are linearly dependent - - ``possible_targets`` -- a list of tuples of the form (``points``, ``repeated``). ``points`` + - ``possible_targets`` -- list of tuples of the form (``points``, ``repeated``). ``points`` is a list of ``points`` which are possible targets for point(s) in ``source``. ``repeated`` specifies how many points in ``source`` have points in ``points`` as their possible target. - OUTPUT: ``True`` if ``f`` is conjugate to ``g``, ``False`` otherwise. + OUTPUT: ``True`` if ``f`` is conjugate to ``g``, ``False`` otherwise EXAMPLES:: diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py index 393e568118e..c8528c4821f 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py @@ -48,16 +48,16 @@ def bCheck(c, v, p, b): INPUT: - - ``c`` -- a list of polynomials in `b`. See v for their use + - ``c`` -- list of polynomials in `b`. See v for their use - - ``v`` -- a list of rational numbers, where we are considering the inequalities + - ``v`` -- list of rational numbers, where we are considering the inequalities `ord_p(c[i]) > v[i]` - ``p`` -- a prime - ``b`` -- local variable - OUTPUT: ``bval`` -- Integer, lower bound in Theorem 3.3.5 + OUTPUT: ``bval`` -- integer; lower bound in Theorem 3.3.5 EXAMPLES:: @@ -88,9 +88,9 @@ def scale(c, v, p): INPUT: - - ``c`` -- an integer polynomial + - ``c`` -- integer polynomial - - ``v`` -- an integer; the bound on the exponent from :func:`blift` + - ``v`` -- integer; the bound on the exponent from :func:`blift` - ``p`` -- a prime @@ -129,9 +129,9 @@ def blift(LF, Li, p, k, S=None, all_orbits=False): INPUT: - - ``LF`` -- a list of integer polynomials in one variable (the normalized coefficients) + - ``LF`` -- list of integer polynomials in one variable (the normalized coefficients) - - ``Li`` -- an integer, the bound on coefficients + - ``Li`` -- integer; the bound on coefficients - ``p`` -- a prime @@ -220,20 +220,18 @@ def affine_minimal(vp, return_transformation=False, D=None, quick=False): - ``vp`` -- dynamical system on the projective line - - ``D`` -- a list of primes, in case one only wants to check minimality + - ``D`` -- list of primes, in case one only wants to check minimality at those specific primes - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the `PGL_2` transformation to conjugate this map to the calculated models - - ``quick`` -- a boolean value. If true the algorithm terminates once + - ``quick`` -- boolean value. If true the algorithm terminates once algorithm determines F/G is not minimal, otherwise algorithm only terminates once a minimal model has been found - OUTPUT: - - - ``newvp`` -- dynamical system on the projective line + OUTPUT: ``newvp`` -- dynamical system on the projective line - ``conj`` -- linear fractional transformation which conjugates ``vp`` to ``newvp`` @@ -341,7 +339,7 @@ def Min(Fun, p, ubRes, conj, all_orbits=False): - ``p`` -- a prime - - ``ubRes`` -- integer, the upper bound needed for Th. 3.3.3 in [Molnar]_ + - ``ubRes`` -- integer; the upper bound needed for Th. 3.3.3 in [Molnar]_ - ``conj`` -- a 2x2 matrix keeping track of the conjugation @@ -491,11 +489,11 @@ def BM_all_minimal(vp, return_transformation=False, D=None): - ``vp`` -- a minimal model of a dynamical system on the projective line - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the ``PGL_2`` transformation to conjugate ``vp`` to the calculated minimal model - - ``D`` -- a list of primes, in case one only wants to check minimality + - ``D`` -- list of primes, in case one only wants to check minimality at those specific primes OUTPUT: @@ -592,7 +590,7 @@ def BM_all_minimal(vp, return_transformation=False, D=None): for M in all_M: new_map = mp.conjugate(M) new_map.normalize_coordinates() - if not [new_map, M] in all_maps: + if [new_map, M] not in all_maps: all_maps.append([new_map, M]) #Split into conjugacy classes @@ -637,11 +635,11 @@ def HS_minimal(f, return_transformation=False, D=None): - ``f`` -- dynamical system on the projective line with minimal resultant - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the `PGL_2` transformation to conjugate this map to the calculated models - - ``D`` -- a list of primes, in case one only wants to check minimality + - ``D`` -- list of primes, in case one only wants to check minimality at those specific primes OUTPUT: @@ -733,7 +731,7 @@ def HS_all_minimal_p(p, f, m=None, return_transformation=False): - ``m`` -- (optional) `2 \times 2` matrix associated with ``f`` - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the ``PGL_2`` transformation to conjugate ``vp`` to the calculated minimal model @@ -828,11 +826,11 @@ def HS_all_minimal(f, return_transformation=False, D=None): - ``f`` -- dynamical system on the projective line with minimal resultant - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the ``PGL_2`` transformation to conjugate ``vp`` to the calculated minimal model - - ``D`` -- a list of primes, in case one only wants to check minimality + - ``D`` -- list of primes, in case one only wants to check minimality at those specific primes OUTPUT: @@ -914,7 +912,7 @@ def get_bound_dynamical(F, f, m=1, dynatomic=True, prec=53, emb=None): This defines the maximum possible distance from `j` to the `z_0` covariant of the associated binary form `F` in the hyperbolic 3-space - for which the map `f`` could have smaller coefficients. + for which the map `f` could have smaller coefficients. INPUT: @@ -984,7 +982,7 @@ def coshdelta(z): def smallest_dynamical(f, dynatomic=True, start_n=1, prec=53, emb=None, algorithm='HS', check_minimal=True): r""" - Determine the poly with smallest coefficients in `SL(2,\ZZ)` orbit of ``F`` + Determine the poly with smallest coefficients in `SL(2,\ZZ)` orbit of ``F``. Smallest is in the sense of global height. The method is the algorithm in Hutz-Stoll [HS2018]_. @@ -1097,9 +1095,7 @@ def coshdelta(z): red_g = f.conjugate(M*MG) if G != pts_poly: R2 = get_bound_dynamical(G, red_g, m=n, dynatomic=dynatomic, prec=prec, emb=emb) - if R2 < R: - # use the better bound - R = R2 + R = min(R2, R) red_g.normalize_coordinates() if red_g.global_height(prec=prec) == 0: return [red_g, M*MG] @@ -1136,8 +1132,7 @@ def coshdelta(z): if new_size == 1: # early exit return [current_min[1], current_min[4]] new_R = get_bound_dynamical(G, g, m=n, dynatomic=dynatomic, prec=prec, emb=emb) - if new_R < R: - R = new_R + R = min(new_R, R) # add new points to check if label != 1 and min((rep+1).norm(), (rep-1).norm()) >= 1: # don't undo S diff --git a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py index be678cca40a..f16d99cbb11 100644 --- a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py @@ -50,12 +50,12 @@ class DynamicalSystem(SchemeMorphism_polynomial, INPUT: - - ``polys_or_rat_fncts`` -- a list of polynomials or rational functions, + - ``polys_or_rat_fncts`` -- list of polynomials or rational functions, all of which should have the same parent - ``domain`` -- an affine or projective scheme, or product of - projective schemes, on which ``polys`` defines an endomorphism. - Subschemes are also ok + projective schemes, on which ``polys`` defines an endomorphism + (Subschemes are also ok) - ``names`` -- (default: ``('X', 'Y')``) tuple of strings to be used as coordinate names for a projective space that is constructed @@ -338,20 +338,20 @@ def specialization(self, D=None, phi=None, homset=None): def field_of_definition_critical(self, return_embedding=False, simplify_all=False, names='a'): r""" - Return smallest extension of the base field which contains the critical points + Return smallest extension of the base field which contains the critical points. Ambient space of dynamical system must be either the affine line or projective line over a number field or finite field. INPUT: - - ``return_embedding`` -- (default: ``False``) boolean; If ``True``, return an + - ``return_embedding`` -- boolean (default: ``False``); if ``True``, return an embedding of base field of dynamical system into the returned number field or finite field. Note that computing this embedding might be expensive. - - ``simplify_all`` -- (default: ``False``) boolean; If ``True``, simplify + - ``simplify_all`` -- boolean (default: ``False``); if ``True``, simplify intermediate fields and also the resulting number field. Note that this - is not implemented for finite fields and has no effect + is not implemented for finite fields and has no effect. - ``names`` -- (optional) string to be used as generator for returned number field or finite field @@ -448,21 +448,21 @@ def field_of_definition_periodic(self, n, formal=False, return_embedding=False, INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``formal`` -- (default: ``False``) boolean; ``True`` signals to return number + - ``formal`` -- boolean (default: ``False``); ``True`` signals to return number field or finite field over which the formal periodic points are defined, where a formal periodic point is a root of the ``n``-th dynatomic polynomial. ``False`` specifies to find number field or finite field over which all periodic - points of the ``n``-th iterate are defined + points of the ``n``-th iterate are defined. - - ``return_embedding`` -- (default: ``False``) boolean; If ``True``, return + - ``return_embedding`` -- boolean (default: ``False``); if ``True``, return an embedding of base field of dynamical system into the returned number field or finite field. Note that computing this embedding might be expensive. - - ``simplify_all`` -- (default: ``False``) boolean; If ``True``, simplify + - ``simplify_all`` -- boolean (default: ``False``); if ``True``, simplify intermediate fields and also the resulting number field. Note that this - is not implemented for finite fields and has no effect + is not implemented for finite fields and has no effect. - ``names`` -- (optional) string to be used as generator for returned number field or finite field @@ -574,15 +574,15 @@ def field_of_definition_preimage(self, point, n, return_embedding=False, simplif - ``point`` -- a point in this map's domain - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``return_embedding`` -- (default: ``False``) boolean; If ``True``, return + - ``return_embedding`` -- boolean (default: ``False``); if ``True``, return an embedding of base field of dynamical system into the returned number field or finite field. Note that computing this embedding might be expensive. - - ``simplify_all`` -- (default: ``False``) boolean; If ``True``, simplify + - ``simplify_all`` -- boolean (default: ``False``); if ``True``, simplify intermediate fields and also the resulting number field. Note that this - is not implemented for finite fields and has no effect + is not implemented for finite fields and has no effect. - ``names`` -- (optional) string to be used as generator for returned number field or finite field diff --git a/src/sage/dynamics/arithmetic_dynamics/meson.build b/src/sage/dynamics/arithmetic_dynamics/meson.build new file mode 100644 index 00000000000..9e26a72c874 --- /dev/null +++ b/src/sage/dynamics/arithmetic_dynamics/meson.build @@ -0,0 +1,27 @@ +py.install_sources( + 'affine_ds.py', + 'all.py', + 'berkovich_ds.py', + 'dynamical_semigroup.py', + 'endPN_automorphism_group.py', + 'endPN_minimal_model.py', + 'generic_ds.py', + 'product_projective_ds.py', + 'projective_ds.py', + 'wehlerK3.py', + subdir: 'sage/dynamics/arithmetic_dynamics', +) + +extension_data = {'projective_ds_helper' : files('projective_ds_helper.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/dynamics/arithmetic_dynamics', + install: true, + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py index 706bb28cbef..3cf6ae27350 100644 --- a/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py @@ -47,7 +47,7 @@ class DynamicalSystem_product_projective(DynamicalSystem, INPUT: - - ``polys`` -- a list of `n_1 + \cdots + n_r` multi-homogeneous polynomials, all + - ``polys`` -- list of `n_1 + \cdots + n_r` multi-homogeneous polynomials, all of which should have the same parent - ``domain`` -- a projective scheme embedded in @@ -85,10 +85,10 @@ def _call_with_args(self, P, check=True): - ``P`` -- a point in the domain - - ``check`` -- Boolean; whether or not to perform the input checks - on the image point (Default: ``True``) + - ``check`` -- boolean (default: ``True``); whether or not to perform + the input checks on the image point - OUTPUT: The image point in the codomain + OUTPUT: the image point in the codomain EXAMPLES:: @@ -125,11 +125,11 @@ def nth_iterate(self, P, n, normalize=False): - ``P`` -- a point in ``self.domain()`` - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``normalize`` -- (default: ``False``) boolean + - ``normalize`` -- boolean (default: ``False``) - OUTPUT: A point in ``self.codomain()`` + OUTPUT: a point in ``self.codomain()`` EXAMPLES:: @@ -180,16 +180,15 @@ def orbit(self, P, N, **kwds): - ``P`` -- a point in ``self.domain()`` - - ``N`` -- a non-negative integer or list or tuple of two non-negative integers + - ``N`` -- nonnegative integer or list or tuple of two nonnegative integers kwds: - - ``check`` -- (default: ``True``) boolean + - ``check`` -- boolean (default: ``True``) - - ``normalize`` -- (default: ``False``) boolean + - ``normalize`` -- boolean (default: ``False``) - - OUTPUT: a list of points in ``self.codomain()`` + OUTPUT: list of points in ``self.codomain()`` EXAMPLES:: @@ -220,7 +219,7 @@ def orbit(self, P, N, **kwds): except TypeError: raise TypeError("orbit bounds must be integers") if N[0] < 0 or N[1] < 0: - raise TypeError("orbit bounds must be non-negative") + raise TypeError("orbit bounds must be nonnegative") if N[0] > N[1]: return [] @@ -255,9 +254,9 @@ def nth_iterate_map(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - OUTPUT: A dynamical system of products of projective spaces + OUTPUT: a dynamical system of products of projective spaces EXAMPLES:: diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index a04cf57a28d..a74efd9129a 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -89,14 +89,13 @@ class initialization directly. from sage.rings.finite_rings.integer_mod_ring import Zmod from sage.rings.fraction_field import FractionField, FractionField_generic, FractionField_1poly_field from sage.rings.fraction_field_element import FractionFieldElement -from sage.rings.function_field.function_field import is_FunctionField from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.flatten import FlatteningMorphism, UnflatteningMorphism from sage.rings.morphism import RingHomomorphism_im_gens -from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing +from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.quotient_ring import QuotientRing_generic from sage.rings.rational_field import QQ from sage.rings.real_mpfr import RealField @@ -109,6 +108,8 @@ class initialization directly. from sage.schemes.projective.projective_space import ProjectiveSpace, ProjectiveSpace_ring from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective from sage.structure.element import get_coercion_model +from sage.rings.qqbar import QQbar, number_field_elements_from_algebraics +from sage.schemes.elliptic_curves.constructor import EllipticCurve lazy_import('sage.rings.algebraic_closure_finite_field', 'AlgebraicClosureFiniteField_generic') lazy_import('sage.rings.number_field.number_field_ideal', 'NumberFieldFractionalIdeal') @@ -135,12 +136,12 @@ class DynamicalSystem_projective(SchemeMorphism_polynomial_projective_space, INPUT: - ``morphism_or_polys`` -- a SchemeMorphism, a polynomial, a - rational function, or a list or tuple of homogeneous polynomials. + rational function, or a list or tuple of homogeneous polynomials - - ``domain`` -- optional projective space or projective subscheme. + - ``domain`` -- (optional) projective space or projective subscheme - - ``names`` -- optional tuple of strings to be used as coordinate - names for a projective space that is constructed; defaults to ``'X','Y'``. + - ``names`` -- tuple of strings (default: ``'X','Y'``) to be used as coordinate + names for a projective space that is constructed The following combinations of ``morphism_or_polys`` and ``domain`` are meaningful: @@ -161,7 +162,7 @@ class DynamicalSystem_projective(SchemeMorphism_polynomial_projective_space, 1-dimensional projective space over the base ring of ``morphism_or_polys`` with coordinate names given by ``names``. - OUTPUT: :class:`DynamicalSystem_projective`. + OUTPUT: :class:`DynamicalSystem_projective` EXAMPLES:: @@ -384,7 +385,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): polys = list(morphism_or_polys) if len(polys) == 1: raise ValueError("list/tuple must have at least 2 polynomials") - test = lambda x: is_PolynomialRing(x) or is_MPolynomialRing(x) + test = lambda x: isinstance(x, PolynomialRing_general) or isinstance(x, MPolynomialRing_base) if not all(test(poly.parent()) for poly in polys): try: polys = [poly.lift() for poly in polys] @@ -394,8 +395,8 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): # homogenize! f = morphism_or_polys aff_CR = f.parent() - if (not is_PolynomialRing(aff_CR) and not isinstance(aff_CR, FractionField_generic) - and not (is_MPolynomialRing(aff_CR) and aff_CR.ngens() == 1)): + if (not isinstance(aff_CR, PolynomialRing_general) and not isinstance(aff_CR, FractionField_generic) + and not (isinstance(aff_CR, MPolynomialRing_base) and aff_CR.ngens() == 1)): msg = '{} is not a single variable polynomial or rational function' raise ValueError(msg.format(f)) if isinstance(aff_CR, FractionField_generic): @@ -498,7 +499,7 @@ def _number_field_from_algebraics(self): r""" Return a dynamical system defined over the number field of its coefficients. - OUTPUT: dynamical system. + OUTPUT: dynamical system EXAMPLES:: @@ -522,7 +523,7 @@ def dehomogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers; if ``n`` is an integer, + - ``n`` -- tuple of nonnegative integers; if ``n`` is an integer, then the two values of the tuple are assumed to be the same OUTPUT: @@ -594,7 +595,7 @@ def dynatomic_polynomial(self, period): INPUT: - - ``period`` -- a positive integer or a list/tuple `[m,n]` where + - ``period`` -- positive integer or a list/tuple `[m,n]` where `m` is the preperiod and `n` is the period OUTPUT: @@ -1005,11 +1006,11 @@ def nth_iterate(self, P, n, **kwds): - ``P`` -- a point in this map's domain - - ``n`` -- a positive integer + - ``n`` -- positive integer kwds: - - ``normalize`` -- (default: ``False``) boolean + - ``normalize`` -- boolean (default: ``False``) OUTPUT: a point in this map's codomain @@ -1138,13 +1139,13 @@ def arakelov_zhang_pairing(self, g, **kwds): INPUT: - - ``g`` -- a rational map of `\mathbb{P}^1` given as a projective morphism. - ``g`` and ``self`` should have the same field of definition. + - ``g`` -- a rational map of `\mathbb{P}^1` given as a projective morphism + ``g`` and ``self`` should have the same field of definition kwds: - - ``n`` -- (default: 5) a positive integer - Order of periodic points to use or preimages to take if starting points are specified. + - ``n`` -- positive integer (default: 5); order of periodic points to + use or preimages to take if starting points are specified - ``f_starting_point`` -- (default: ``None``) value in the base number field or None. If ``f_starting_point`` is None, we solve for points of period ``n`` for ``self``. @@ -1156,11 +1157,11 @@ def arakelov_zhang_pairing(self, g, **kwds): Otherwise, we take ``n``-th preimages of the point given by ``g_starting_point`` under ``g`` on the affine line. - - ``check_primes_of_bad_reduction`` -- (default: ``False``) boolean. - Passed to the ``primes_of_bad_reduction`` function for ``self`` and ``g``. + - ``check_primes_of_bad_reduction`` -- boolean (default: ``False``); + passed to the ``primes_of_bad_reduction`` function for ``self`` and ``g`` - - ``prec`` -- (default: ``RealField`` default) - default precision for RealField values which are returned. + - ``prec`` -- (default: ``RealField`` default); + default precision for RealField values which are returned - ``noise_multiplier`` -- (default: 2) a real number. Discriminant terms involved in the computation at the archimedean places @@ -1174,9 +1175,7 @@ def arakelov_zhang_pairing(self, g, **kwds): the accuracy of the estimate of the pairing. If desired, ``noise_multiplier`` can be set to 0, and no terms will be ignored. - OUTPUT: - - - a real number estimating the Arakelov-Zhang pairing of the two rational maps. + OUTPUT: a real number estimating the Arakelov-Zhang pairing of the two rational maps EXAMPLES:: @@ -1416,7 +1415,9 @@ def degree_sequence(self, iterates=2): Return sequence of degrees of normalized iterates starting with the degree of this dynamical system. - INPUT: ``iterates`` -- (default: 2) positive integer + INPUT: + + - ``iterates`` -- (default: 2) positive integer OUTPUT: list of integers @@ -1519,16 +1520,16 @@ def orbit(self, P, N, **kwds): - ``P`` -- a point in this dynamical system's domain - - ``n`` -- a non-negative integer or list or tuple of two - non-negative integers + - ``n`` -- nonnegative integer or list or tuple of two + nonnegative integers kwds: - - ``check`` -- (default: ``True``) boolean + - ``check`` -- boolean (default: ``True``) - - ``normalize`` -- (default: ``False``) boolean + - ``normalize`` -- boolean (default: ``False``) - OUTPUT: a list of points in this dynamical system's codomain + OUTPUT: list of points in this dynamical system's codomain EXAMPLES:: @@ -1581,7 +1582,7 @@ def orbit(self, P, N, **kwds): sage: f.orbit(P(2, 1),[-1, 4]) Traceback (most recent call last): ... - TypeError: orbit bounds must be non-negative + TypeError: orbit bounds must be nonnegative sage: f.orbit(P(2, 1), 0.1) Traceback (most recent call last): ... @@ -1633,7 +1634,7 @@ def orbit(self, P, N, **kwds): N[0] = Integer(N[0]) N[1] = Integer(N[1]) if N[0] < 0 or N[1] < 0: - raise TypeError("orbit bounds must be non-negative") + raise TypeError("orbit bounds must be nonnegative") if N[0] > N[1]: return [] @@ -1668,7 +1669,7 @@ def resultant(self, normalize=False): INPUT: - - ``normalize`` -- (default: ``False``) boolean + - ``normalize`` -- boolean (default: ``False``) OUTPUT: an element of the base ring of this map @@ -1751,20 +1752,20 @@ def primes_of_bad_reduction(self, check=True): ALGORITHM: `p` is a prime of bad reduction if and only if the defining - polynomials of self have a common zero. Or stated another way, + polynomials of ``self`` have a common zero. Or stated another way, `p` is a prime of bad reduction if and only if the radical of - the ideal defined by the defining polynomials of self is not + the ideal defined by the defining polynomials of ``self`` is not `(x_0,x_1,\ldots,x_N)`. This happens if and only if some power of each `x_i` is not in the ideal defined by the - defining polynomials of self. This last condition is what is + defining polynomials of ``self``. This last condition is what is checked. The lcm of the coefficients of the monomials `x_i` in a Groebner basis is computed. This may return extra primes. INPUT: - - ``check`` -- (default: ``True``) boolean + - ``check`` -- boolean (default: ``True``) - OUTPUT: a list of primes + OUTPUT: list of primes EXAMPLES:: @@ -1873,13 +1874,13 @@ def conjugate(self, M, adjugate=False, normalize=False): - ``M`` -- a square invertible matrix - - ``adjugate`` -- (default: ``False``) boolean, also classically called + - ``adjugate`` -- boolean (default: ``False``); also classically called adjoint, takes a square matrix ``M`` and finds the transpose of its cofactor matrix. Used for conjugation in place of inverse when specified ``True``. Functionality is the same in projective space. - - ``normalize`` -- (default: ``False``) boolean, if ``normalize`` is - ``True``, then the method ``normalize_coordinates`` is called. + - ``normalize`` -- boolean (default: ``False``); if ``normalize`` is + ``True``, then the method ``normalize_coordinates`` is called OUTPUT: a dynamical system @@ -1999,12 +2000,12 @@ def green_function(self, P, v, **kwds): - ``P`` -- a projective point - - ``v`` -- non-negative integer. a place, use ``0`` for the + - ``v`` -- nonnegative integer; a place, use ``0`` for the archimedean place kwds: - - ``N`` -- (default: 10) positive integer. number of + - ``N`` -- (default: 10) positive integer; number of terms of the series to use - ``prec`` -- (default: 100) positive integer, float point or @@ -2119,8 +2120,7 @@ def green_function(self, P, v, **kwds): h = max([(Res*c).local_height_arch(vindex, prec=prec) for c in poly.coefficients()]) else: #non-archimedean h = max([c.local_height(v, prec=prec) for c in poly.coefficients()]) - if h > maxh: - maxh = h + maxh = max(h, maxh) if maxh == 0: maxh = 1 #avoid division by 0 if isinstance(v, RingHomomorphism_im_gens): #archimedean @@ -2196,7 +2196,7 @@ def canonical_height(self, P, **kwds): - ``badprimes`` -- (optional) a list of primes of bad reduction - - ``N`` -- (default: 10) positive integer. number of + - ``N`` -- (default: 10) positive integer; number of terms of the series to use in the local green functions - ``prec`` -- (default: 100) positive integer, float point or @@ -2333,8 +2333,7 @@ def canonical_height(self, P, **kwds): if err is not None: err = err / 2 N = ceil((R(Res).log().log() - R(d-1).log() - R(err).log())/(R(d).log())) - if N < 1: - N = 1 + N = max(N, 1) kwds.update({'error_bound': err}) kwds.update({'N': N}) for n in range(N): @@ -2498,9 +2497,9 @@ def multiplier(self, P, n, check=True): - ``P`` -- a point on domain of this map - - ``n`` -- a positive integer, the period of ``P`` + - ``n`` -- positive integer, the period of ``P`` - - ``check`` -- (default: ``True``) boolean; verify that ``P`` + - ``check`` -- boolean (default: ``True``); verify that ``P`` has period ``n`` OUTPUT: @@ -2599,11 +2598,11 @@ def _multipliermod(self, P, n, p, k): - ``P`` -- a point on domain of this map - - ``n`` -- a positive integer, the period of ``P`` + - ``n`` -- positive integer, the period of ``P`` - - ``p`` -- a positive integer + - ``p`` -- positive integer - - ``k`` -- a positive integer + - ``k`` -- positive integer OUTPUT: @@ -2728,37 +2727,37 @@ def nth_preimage_tree(self, Q, n, **kwds): - ``Q`` -- a point in the domain of this map - - ``n`` -- a positive integer, the depth of the pre-image tree + - ``n`` -- positive integer, the depth of the pre-image tree kwds: - - ``return_points`` -- (default: ``False``) boolean; if ``True``, + - ``return_points`` -- boolean (default: ``False``); if ``True``, return a list of lists where the index `i` is the level of the tree and the elements of the list at that index are the `i`-th preimage points as an algebraic element of the splitting field of the - polynomial `f^n - Q = 0` + polynomial `f^n - Q = 0`. - - ``numerical`` -- (default: ``False``) boolean; calculate pre-images + - ``numerical`` -- boolean (default: ``False``); calculate pre-images numerically. Note if this is set to ``True``, preimage points are - displayed as complex numbers + displayed as complex numbers. - ``prec`` -- (default: 100) positive integer; the precision of the ``ComplexField`` if we compute the preimage points numerically - - ``display_labels`` -- (default: ``True``) boolean; whether to display + - ``display_labels`` -- boolean (default: ``True``); whether to display vertex labels. Since labels can be very cluttered, can set ``display_labels`` to ``False`` and use ``return_points`` to get a - hold of the points themselves, either as algebraic or complex numbers + hold of the points themselves, either as algebraic or complex numbers. - - ``display_complex`` -- (default: ``False``) boolean; display vertex + - ``display_complex`` -- boolean (default: ``False``); display vertex labels as complex numbers. Note if this option is chosen that we must choose an embedding from the splitting field ``field_def`` of the `n`-th-preimage equation into `\CC`. We make the choice of the first - embedding returned by ``field_def.embeddings(ComplexField())`` + embedding returned by ``field_def.embeddings(ComplexField())``. - - ``digits`` -- a positive integer, the number of decimal digits to + - ``digits`` -- positive integer; the number of decimal digits to display for complex numbers. This only applies if ``display_complex`` - is set to ``True`` + is set to ``True``. OUTPUT: @@ -2864,19 +2863,17 @@ def possible_periods(self, **kwds): Calls ``self.possible_periods()`` modulo all primes of good reduction in range ``prime_bound``. Return the intersection of those lists. - INPUT: + INPUT: keyword arguments: - kwds: - - - ``prime_bound`` -- (default: ``[1, 20]``) a list or tuple of - two positive integers or an integer for the upper bound + - ``prime_bound`` -- (default: ``[1, 20]``) a list or tuple of + two positive integers or an integer for the upper bound - ``bad_primes`` -- (optional) a list or tuple of integer primes, the primes of bad reduction - ``ncpus`` -- (default: all cpus) number of cpus to use in parallel - OUTPUT: a list of positive integers + OUTPUT: list of positive integers EXAMPLES:: @@ -2938,7 +2935,7 @@ def parallel_function(morphism): # Calling possible_periods for each prime in parallel parallel_data = [] for q in primes(primebound[0], primebound[1] + 1): - if not (q in badprimes): + if q not in badprimes: F = self.change_ring(GF(q)) parallel_data.append(((F,), {})) @@ -2969,7 +2966,7 @@ def _preperiodic_points_to_cyclegraph(self, preper): INPUT: - - ``preper`` -- a list or tuple of projective points; the complete + - ``preper`` -- list or tuple of projective points; the complete set of rational periodic or preperiodic points OUTPUT: @@ -3075,7 +3072,7 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= INPUT: - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the `PGL_2` transformation to conjugate this map to the calculated minimal model @@ -3084,7 +3081,7 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= - ``algorithm`` -- (optional) string; can be one of the following: - - ``check_primes`` -- (optional) boolean: this signals whether to + - ``check_primes`` -- (optional) boolean; this signals whether to check whether each element in ``prime_list`` is a prime * ``'BM'`` -- the Bruin-Molnar algorithm [BM2012]_ @@ -3259,7 +3256,7 @@ def all_minimal_models(self, return_transformation=False, prime_list=None, INPUT: - - ``return_transformation`` -- (default: ``False``) boolean; this + - ``return_transformation`` -- boolean (default: ``False``); this signals a return of the `PGL_2` transformation to conjugate this map to the calculated models @@ -3383,19 +3380,19 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): If the base ring of this dynamical system is finite, there may not be a model with affine preperiodic points, in which case a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. INPUT: - - ``m`` -- the preperiod of the preperiodic points to make affine. + - ``m`` -- the preperiod of the preperiodic points to make affine - - ``n`` -- the period of the preperiodic points to make affine. + - ``n`` -- the period of the preperiodic points to make affine - - ``return_conjugation`` -- (default: ``False``) If ``True``, return a tuple - ``(g, phi)`` where ``g`` is a model with affine (n, m) preperiodic points - and ``phi`` is the matrix that moves ``f`` to ``g``. + - ``return_conjugation`` -- boolean (default: ``False``); if ``True``, return a tuple + ``(g, phi)`` where ``g`` is a model with affine (n, m) preperiodic points + and ``phi`` is the matrix that moves ``f`` to ``g``. - OUTPUT: a dynamical system conjugate to this one. + OUTPUT: a dynamical system conjugate to this one EXAMPLES:: @@ -3485,7 +3482,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): raise ValueError('period must be positive') m = ZZ(m) if m < 0: - raise ValueError('preperiod must be non-negative') + raise ValueError('preperiod must be nonnegative') f = self CR = f.coordinate_ring() dom = f.domain() @@ -3533,7 +3530,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): if hyperplane_found: break else: - if is_PolynomialRing(R) or is_MPolynomialRing(R) or isinstance(R, FractionField_generic): + if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base) or isinstance(R, FractionField_generic): # for polynomial rings, we can get an infinite family of hyperplanes # by increasing the degree var = R.gen() @@ -3568,7 +3565,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): def automorphism_group(self, **kwds): r""" - Calculates the subgroup of `PGL2` that is the automorphism group + Calculate the subgroup of `PGL2` that is the automorphism group of this dynamical system. The automorphism group is the set of `PGL(2)` elements that fixes @@ -3579,7 +3576,7 @@ def automorphism_group(self, **kwds): The following keywords are used in most cases: - ``num_cpus`` -- (default: 2) the number of threads to use. Setting to a - larger number can greatly speed up this function. + larger number can greatly speed up this function The following keywords are used only when the dimension of the domain is 1 and the base ring is the rationals, but ignored in all other cases: @@ -3591,14 +3588,14 @@ def automorphism_group(self, **kwds): * ``'CRT'`` -- Chinese Remainder Theorem * ``'fixed_points'`` -- fixed points algorithm - - ``return_functions`` -- (default: ``False``) boolean; ``True`` + - ``return_functions`` -- boolean (default: ``False``); ``True`` returns elements as linear fractional transformations and ``False`` returns elements as `PGL2` matrices - - ``iso_type`` -- (default: ``False``) boolean; ``True`` returns the + - ``iso_type`` -- boolean (default: ``False``); ``True`` returns the isomorphism type of the automorphism group - OUTPUT: a list of elements in the automorphism group + OUTPUT: list of elements in the automorphism group AUTHORS: @@ -3780,7 +3777,7 @@ def critical_subscheme(self): def critical_points(self, R=None): r""" Return the critical points of this dynamical system defined over - the ring ``R`` or the base ring of this map. + the ring `R` or the base ring of this map. Must be dimension 1. @@ -3788,7 +3785,7 @@ def critical_points(self, R=None): - ``R`` -- (optional) a ring - OUTPUT: a list of projective space points defined over ``R`` + OUTPUT: list of projective space points defined over `R` EXAMPLES:: @@ -3875,7 +3872,6 @@ def ramification_type(self, R=None, stable=True): [[2], [2], [3]] sage: F.ramification_type(R=F.base_ring()) # needs sage.rings.function_field [[2], [3]] - """ # Change base ring if specified. if R is None: @@ -3914,7 +3910,7 @@ def is_postcritically_finite(self, err=0.01, use_algebraic_closure=True): - ``err`` -- (default: 0.01) positive real number - - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True``, uses the + - ``use_algebraic_closure`` -- boolean (default: ``True``); if ``True``, uses the algebraic closure. If ``False``, uses the smallest extension of the base field containing all the critical points. @@ -4109,7 +4105,7 @@ def critical_point_portrait(self, check=True, use_algebraic_closure=True): - ``check`` -- boolean (default: ``True``) - - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True``, uses the + - ``use_algebraic_closure`` -- boolean (default: ``True``); if ``True``, uses the algebraic closure. If ``False``, uses the smallest extension of the base field containing all the critical points. @@ -4175,7 +4171,6 @@ def critical_point_portrait(self, check=True, use_algebraic_closure=True): Looped digraph on 6 vertices sage: f.critical_point_portrait() #long time Looped digraph on 6 vertices - """ #input checking done in is_postcritically_finite if check: @@ -4221,9 +4216,7 @@ def critical_height(self, **kwds): base field or over the minimal extension of the base field that contains the critical points. - INPUT: - - kwds: + INPUT: keyword arguments: - ``badprimes`` -- (optional) a list of primes of bad reduction @@ -4235,9 +4228,10 @@ def critical_height(self, **kwds): - ``error_bound`` -- (optional) a positive real number - - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True``, uses the - algebraic closure. If ``False``, uses the smallest extension of the base field - containing all the critical points. + - ``use_algebraic_closure`` -- boolean (default: ``True``); if + ``True``, uses the algebraic closure. If ``False``, uses the + smallest extension of the base field containing all the critical + points. OUTPUT: real number @@ -4304,7 +4298,7 @@ def critical_height(self, **kwds): def preperiodic_points(self, m, n, **kwds): r""" - Computes the preperiodic points of period ``m, n`` of this dynamical system + Compute the preperiodic points of period ``m, n`` of this dynamical system defined over the ring ``R`` or the base ring of the map. This is done by finding the rational points on the variety @@ -4316,25 +4310,25 @@ def preperiodic_points(self, m, n, **kwds): INPUT: - - ``n`` -- a positive integer, the period + - ``n`` -- positive integer; the period - - ``m`` -- a non negative integer, the preperiod + - ``m`` -- nonnegative integer; the preperiod kwds: - - ``minimal`` -- (default: ``True``) boolean; ``True`` specifies to + - ``minimal`` -- boolean (default: ``True``); ``True`` specifies to find only the preperiodic points of minimal period ``m``,``n`` and ``False`` specifies to find all preperiodic points of period ``m``, ``n`` - - ``formal`` -- (default: ``False``) boolean; ``True`` specifies to + - ``formal`` -- boolean (default: ``False``); ``True`` specifies to find the formal periodic points only. The formal periodic points are the points in the support of the dynatomic cycle. - ``R`` -- (default: the base ring of the dynamical system) a commutative ring over which to find the preperiodic points - - ``return_scheme`` -- (default: ``False``) boolean; return a + - ``return_scheme`` -- boolean (default: ``False``); return a subscheme of the ambient space that defines the ``m``,``n`` th preperiodic points @@ -4531,7 +4525,7 @@ def preperiodic_points(self, m, n, **kwds): if n <= 0: raise ValueError("a positive integer period must be specified") if m < 0: - raise ValueError("a non negative preperiod must be specified") + raise ValueError("a nonnegative preperiod must be specified") R = kwds.pop('R', None) if R is None: f_sub = self @@ -4539,7 +4533,7 @@ def preperiodic_points(self, m, n, **kwds): else: f_sub = self.change_ring(R) R = f_sub.base_ring() #in the case when R is an embedding - if isinstance(R, FractionField_1poly_field) or is_FunctionField(R): + if isinstance(R, FractionField_1poly_field) or R in FunctionFields(): raise NotImplementedError('Periodic points not implemented for function fields; ' 'clear denominators and use the polynomial ring instead') CR = f_sub.coordinate_ring() @@ -4598,7 +4592,7 @@ def preperiodic_points(self, m, n, **kwds): for k in ZZ(n).divisors(): if ZZ(n/k).is_prime(): Sn.append(k) - if (is_PolynomialRing(R) or is_MPolynomialRing(R)): + if (isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base)): phi = FlatteningMorphism(CR) flatCR = phi.codomain() Ik = flatCR.ideal(1) @@ -4641,7 +4635,7 @@ def preperiodic_points(self, m, n, **kwds): def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='variety', return_scheme=False): r""" - Computes the periodic points of period ``n`` of this dynamical system + Compute the periodic points of period ``n`` of this dynamical system defined over the ring ``R`` or the base ring of the map. This can be done either by finding the rational points on the variety @@ -4659,18 +4653,18 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``minimal`` -- (default: ``True``) boolean; ``True`` specifies to + - ``minimal`` -- boolean (default: ``True``); ``True`` specifies to find only the periodic points of minimal period ``n`` and ``False`` specifies to find all periodic points of period ``n`` - - ``formal`` -- (default: ``False``) boolean; ``True`` specifies to + - ``formal`` -- boolean (default: ``False``); ``True`` specifies to find the formal periodic points only. The formal periodic points are the points in the support of the dynatomic cycle. - ``R`` -- (optional) a commutative ring. Defaults to the base ring of - this map. + this map - ``algorithm`` -- (default: ``'variety'``) must be one of the following: @@ -4877,11 +4871,11 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari else: f_sub = self.change_ring(R) R = f_sub.base_ring() #in the case when R is an embedding - if isinstance(R, FractionField_1poly_field) or is_FunctionField(R): + if isinstance(R, FractionField_1poly_field) or R in FunctionFields(): raise NotImplementedError('periodic points not implemented for fraction function fields; ' 'clear denominators and use the polynomial ring instead') if isinstance(R, FractionField_generic): - if is_MPolynomialRing(R.ring()): + if isinstance(R.ring(), MPolynomialRing_base): raise NotImplementedError('periodic points not implemented for fraction function fields; ' 'clear denominators and use the polynomial ring instead') CR = f_sub.coordinate_ring() @@ -4954,7 +4948,7 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari for k in ZZ(n).divisors(): if ZZ(n/k).is_prime(): Sn.append(k) - if (is_PolynomialRing(R) or is_MPolynomialRing(R)): + if (isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base)): phi = FlatteningMorphism(CR) flatCR = phi.codomain() Ik = flatCR.ideal(1) @@ -4994,7 +4988,7 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closure=True, check=True): r""" - Computes the ``n`` multiplier spectra of this dynamical system. + Compute the ``n`` multiplier spectra of this dynamical system. This is the set of multipliers of all peroidic points of period ``n`` included with the appropriate multiplicity. @@ -5011,9 +5005,9 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur INPUT: - - ``n`` -- a positive integer, the period + - ``n`` -- positive integer, the period - - ``formal`` -- (default: ``False``) boolean; ``True`` specifies + - ``formal`` -- boolean (default: ``False``); ``True`` specifies to find the formal ``n`` multiplier spectra of this map and ``False`` specifies to find the ``n`` multiplier spectra @@ -5021,7 +5015,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur or ``'cycle'`` depending on whether you compute one multiplier per point or one per cycle - - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True`` uses the + - ``use_algebraic_closure`` -- boolean (default: ``True``); if ``True`` uses the algebraic closure. Using the algebraic closure can sometimes lead to numerical instability and extraneous errors. For most accurate results in dimension 1, set to ``False``. If ``False``, and the map is defined over projective space of @@ -5029,7 +5023,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur containing all the periodic points. If the map is defined over projective space of dimension greater than 1, then the base ring of the map is used. - - ``check`` -- (defualt: ``True``) whether to check if the + - ``check`` -- boolean (default: ``True``); whether to check if the full multiplier spectra was computed. If ``False``, can lead to mathematically incorrect answers in dimension greater than 1. Ignored if ``use_algebraic_closure`` is ``True`` or if this dynamical system is defined @@ -5398,7 +5392,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur def sigma_invariants(self, n, formal=False, embedding=None, type='point', return_polynomial=False, chow=False, deform=False, check=True): r""" - Computes the values of the elementary symmetric polynomials evaluated + Compute the values of the elementary symmetric polynomials evaluated on the ``n`` multiplier spectra of this dynamical system. The sigma invariants are the symmetric polynomials evaluated on the @@ -5452,30 +5446,31 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', are 4 cases: - multipliers and ``n`` periodic points all distinct -- in this case, - we can use Proposition 4.1 of [Hutz2019]_ to compute the sigma invariants. + we can use Proposition 4.1 of [Hutz2019]_ to compute the sigma invariants - - ``n`` periodic points are all distinct, multipliers are repeated -- here we + - ``n`` -- periodic points are all distinct, multipliers are repeated; here we can use Proposition 4.2 of [Hutz2019]_ to compute the sigma invariants. This corresponds to ``chow=True``. - - ``n`` periodic points are repeated, multipliers are all distinct -- to deal + - ``n`` -- periodic points are repeated, multipliers are all distinct; to deal with this case, we deform the map by a formal parameter `k`. The deformation separates the ``n`` periodic points, making them distinct, and we can recover the ``n`` periodic points of the original map by specializing `k` to 0. This corresponds to ``deform=True``. - - ``n`` periodic points are repeated, multipliers are repeated -- here we + - ``n`` -- periodic points are repeated, multipliers are repeated; here we can use both cases 2 and 3 together. This corresponds to ``deform=True`` and ``chow=True``. As we do not want to check which case we are in beforehand, we throw a - ValueError if the computed polynomial does not have the correct degree. + :exc:`ValueError` if the computed polynomial does not have the correct + degree. INPUT: - - ``n`` -- a positive integer, the period + - ``n`` -- positive integer, the period - - ``formal`` -- (default: ``False``) boolean; ``True`` specifies + - ``formal`` -- boolean (default: ``False``); ``True`` specifies to find the values of the elementary symmetric polynomials corresponding to the formal ``n`` multiplier spectra and ``False`` specifies to instead find the values corresponding to the ``n`` @@ -5483,33 +5478,33 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', periodic points of period ``n`` - ``embedding`` -- (default: ``None``) must be ``None``, passing an embedding - is no longer supported, see :issue: `32205`. + is no longer supported, see :issue:`32205` - ``type`` -- (default: ``'point'``) string; either ``'point'`` or ``'cycle'`` depending on whether you compute with one multiplier per point or one per cycle. Not implemented for dimension greater than 1. - - ``return polynomial`` -- (default: ``False``) boolean; + - ``return polynomial`` -- boolean (default: ``False``); ``True`` specifies returning the polynomial which generates the sigma invariants, see [Hutz2019]_ for the full definition. The polynomial is always a multivariate polynomial with variables ``w`` and ``t``. - - ``chow`` -- (default: ``False``) boolean; ``True`` specifies + - ``chow`` -- boolean (default: ``False``); ``True`` specifies using the Chow algorithm from [Hutz2019]_ to compute the sigma invariants. While slower, the Chow algorithm does not lose information about multiplicities of the multipliers. In order to accurately compute the sigma polynomial when there is a repeated multiplier, ``chow`` must be ``True``. - - ``deform`` -- (default: ``False``) boolean; ``True`` specifies + - ``deform`` -- boolean (default: ``False``); ``True`` specifies first deforming the map so that all periodic points are distinct and then calculating the sigma invariants. In order to accurately calculate the sigma polynomial when there is a periodic point with multiplicity, ``deform`` must be ``True``. - - ``check`` -- (default: ``True``) boolean; when ``True`` the degree of + - ``check`` -- boolean (default: ``True``); when ``True`` the degree of the sigma polynomial is checked against the expected degree. This is done as the sigma polynomial may drop degree if multiplicities of periodic points or multipliers are not correctly accounted for using ``chow`` or @@ -5520,13 +5515,13 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', Setting ``check`` to ``False`` can lead to mathematically incorrect answers. - OUTPUT: a list of elements in the base ring, unless ``return_polynomial`` - is ``True``, in which case a polynomial in ``w`` and ``t`` is returned. - The variable ``t`` is the variable of the characteristic - polynomials of the multipliers. + OUTPUT: list of elements in the base ring, unless ``return_polynomial`` + is ``True``, in which case a polynomial in ``w`` and ``t`` is returned. + The variable ``t`` is the variable of the characteristic + polynomials of the multipliers. - If this map is defined over `\mathbb{P}^N`, where `N > 1`, then - the list is the coefficients of `w` and `t`, in lexographical order with `w > t`. + If this map is defined over `\mathbb{P}^N`, where `N > 1`, then + the list is the coefficients of `w` and `t`, in lexographical order with `w > t`. EXAMPLES:: @@ -5785,7 +5780,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', else: F = base_ring if isinstance(base_ring, FractionField_generic): - if is_MPolynomialRing(base_ring.ring()) or is_PolynomialRing(base_ring.ring()): + if isinstance(base_ring.ring(), MPolynomialRing_base) or isinstance(base_ring.ring(), PolynomialRing_general): f.normalize_coordinates() f_ring = f.change_ring(base_ring.ring()) X = f_ring.periodic_points(n, minimal=False, formal=formal, return_scheme=True) @@ -5888,7 +5883,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', base_ring = dom.base_ring() if isinstance(base_ring, FractionField_generic): base_ring = base_ring.ring() - if (is_PolynomialRing(base_ring) or is_MPolynomialRing(base_ring)): + if (isinstance(base_ring, PolynomialRing_general) or isinstance(base_ring, MPolynomialRing_base)): base_ring = base_ring.base_ring() elif base_ring in FunctionFields(): base_ring = base_ring.constant_base_field() @@ -6004,24 +5999,22 @@ def reduced_form(self, **kwds): Implemented by Rebecca Lauren Miller as part of GSOC 2016. Minimal height added by Ben Hutz July 2018. - INPUT: - - keywords: + INPUT: keyword arguments: - - ``prec`` -- (default: 300) integer, desired precision + - ``prec`` -- integer (default: 300); desired precision - - ``return_conjuagtion`` -- (default: ``True``) boolean; return + - ``return_conjuagtion`` -- boolean (default: ``True``); return an element of `SL(2, \ZZ)` - ``error_limit`` -- (default: 0.000001) a real number, sets the error tolerance - - ``smallest_coeffs`` -- (default: ``True``), boolean, whether to find the + - ``smallest_coeffs`` -- boolean (default: ``True``); whether to find the model with smallest coefficients - - ``dynatomic`` -- (default: ``True``) boolean, to use formal periodic points + - ``dynatomic`` -- boolean (default: ``True``); to use formal periodic points - - ``start_n`` -- (default: 1), positive integer, firs period to rry to find + - ``start_n`` -- positive integer (default: 1); first period to try to find appropriate binary form - ``emb`` -- (optional) embedding of based field into CC @@ -6032,10 +6025,10 @@ def reduced_form(self, **kwds): * ``'BM'`` -- Bruin-Molnar algorithm [BM2012]_ * ``'HS'`` -- Hutz-Stoll algorithm [HS2018]_ - - ``check_minimal`` -- (default: ``True``), boolean, whether to check + - ``check_minimal`` -- boolean (default: ``True``); whether to check if this map is a minimal model - - ``smallest_coeffs`` -- (default: ``True``), boolean, whether to find the + - ``smallest_coeffs`` -- boolean (default: ``True``); whether to find the model with smallest coefficients OUTPUT: @@ -6103,7 +6096,7 @@ def reduced_form(self, **kwds): sage: f.reduced_form(prec=30, smallest_coeffs=False) Traceback (most recent call last): ... - ValueError: accuracy of Newton's root not within tolerance(0.00009... > 1e-06), increase precision + ValueError: accuracy of Newton's root not within tolerance(0.00008... > 1e-06), increase precision sage: f.reduced_form(smallest_coeffs=False) ( Dynamical System of Projective Space of dimension 1 over Rational Field @@ -6332,7 +6325,7 @@ def _is_preperiodic(self, P, err=0.1, return_period=False): sets the error_bound used in the canonical height computation and ``return_period`` a boolean which - - ``return_period`` -- (default: ``False``) boolean; controls if + - ``return_period`` -- boolean (default: ``False``); controls if the period is returned if the point is preperiodic OUTPUT: @@ -6465,10 +6458,10 @@ def postcritical_set(self, check=True): INPUT: - - ``check`` -- (default: ``True``) boolean; whether to check - if this dynamical system is postcritically finite or not. + - ``check`` -- boolean (default: ``True``); whether to check + if this dynamical system is postcritically finite or not - OUTPUT: The set of postcritical points. + OUTPUT: the set of postcritical points EXAMPLES:: @@ -6535,7 +6528,7 @@ def is_chebyshev(self): r""" Check if ``self`` is a Chebyshev polynomial. - OUTPUT: True if ``self`` is Chebyshev, False otherwise. + OUTPUT: ``True`` if ``self`` is Chebyshev, ``False`` otherwise EXAMPLES:: @@ -6682,7 +6675,7 @@ def is_chebyshev(self): def is_Lattes(self): r""" - Check if ``self`` is a Lattes map + Check if ``self`` is a Lattes map. OUTPUT: ``True`` if ``self`` is Lattes, ``False`` otherwise @@ -6746,8 +6739,9 @@ def is_Lattes(self): """ # We need `f` to be defined over a number field for # the function `is_postcrtically_finite` to work - if self.base_ring() not in NumberFields(): - raise NotImplementedError("Base ring must be a number field") + if self.base_ring() is not QQbar: + if self.base_ring() not in NumberFields(): + raise NotImplementedError("Base ring must be a number field") if self.domain().dimension() != 1: return False @@ -6774,7 +6768,7 @@ def is_Lattes(self): (crit_set, post_crit_set) = crit, list(post_crit) # All Lattes maps have 3 or 4 post critical values - if not len(post_crit_set) in [3, 4]: + if len(post_crit_set) not in [3, 4]: return False f = F_crit.dehomogenize(1)[0] @@ -6836,6 +6830,201 @@ def is_Lattes(self): r_vals = sorted([val for val in r.values() if val != 1]) return r_vals in r_lattes_cases + def Lattes_to_curve(self, return_conjugation=False, check_lattes=False): + r""" + Finds a Short Weierstrass Model Elliptic curve of self + self assumed to be Lattes map and not in charateristic 2 or 3 + + INPUT: + + `return_conjugation`` -- (default: ``False``) if ``True``, then + return the conjugation that moves self to a map that comes from a + Short Weierstrass Model Elliptic curve + `check_lattes``.-.(default:.``False``) if ``True``, then will ValueError if not Lattes + + OUTPUT: a Short Weierstrass Model Elliptic curve which is isogenous to + the Elliptic curve of 'self', + If ``return_conjugation`` is ``True`` + then also returns conjugation of 'self' to short form as a matrix + + EXAMPLES:: + + sage: P. = ProjectiveSpace(QQ, 1) + sage: f = P.Lattes_map(EllipticCurve([0, 0, 0, 10, 2]), 2) + sage: f.Lattes_to_curve() + Elliptic Curve defined by y^2 = x^3 + 10*x + 2 over Rational Field + + :: + + sage: P. = ProjectiveSpace(QQ, 1) + sage: M = matrix(QQ,2,2,[[1,2],[-1,2]]) + sage: f = P.Lattes_map(EllipticCurve([1, 1, 1, 1, 2]), 2) + sage: f = f.conjugate(M) + sage: f.Lattes_to_curve(return_conjugation = True) + ( + [ -7/36*a^2 + 7/12*a + 7/3 -17/18*a^2 + 17/6*a + 34/3] + [ -1/8*a^2 + 1/4*a + 3/2 1/4*a^2 - 1/2*a - 3], + Elliptic Curve defined by y^2 = x^3 + (-94/27*a^2+94/9*a+376/9)*x + + 12232/243 over Number Field in a with defining polynomial y^3 - 18*y - 30 + ) + + :: + + sage: P. = ProjectiveSpace(QQ,1) + sage: f = P.Lattes_map(EllipticCurve([1, 1, 1, 2, 2]), 2) + sage: L. = CyclotomicField(4) + sage: M = Matrix([[1+i,2*i], [0, -i]]) + sage: f = f.conjugate(M) + sage: f.Lattes_to_curve(return_conjugation = True) + ( + [ 1 19/24*a + 19/24] + [ 0 1], + Elliptic Curve defined by y^2 = x^3 + 95/96*a*x + (-1169/3456*a+1169/3456) + over Number Field in a with defining polynomial y^2 + 1 + ) + + :: + + sage: P. = ProjectiveSpace(QQ, 1) + sage: M = matrix(QQ,2,2,[[1,3],[2,1]]) + sage: E = EllipticCurve([1, 1, 1, 2, 3]) + sage: f = P.Lattes_map(E, 2) + sage: f = f.conjugate(M) + sage: f.Lattes_to_curve(return_conjugation = True) + ( + [11/1602*a^2 41/3204*a^2] + [ -2/5*a -1/5*a], + Elliptic Curve defined by y^2 = x^3 + 2375/3421872*a^2*x + (-254125/61593696) + over Number Field in a with defining polynomial y^3 - 267 + ) + + :: + + sage: P. = ProjectiveSpace(QQ , 1) + sage: M = matrix(QQ,2,2,[[1 , 3],[2 , 1]]) + sage: E = EllipticCurve([1, 1, 1, 2, 3]) + sage: f = P.Lattes_map(E , 2) + sage: f = f.conjugate(M) + sage: m,H = f.Lattes_to_curve(true) + sage: J. = ProjectiveSpace(H.base_ring(), 1) + sage: K = J.Lattes_map(H,2) + sage: K = K.conjugate(m) + sage: K.scale_by(f[0].lc()/K[0].lc()) + sage: K == f.change_ring(K.base_ring()) + True + + :: + + sage: P. = ProjectiveSpace(RR, 1) + sage: F = DynamicalSystem_projective([x^4, y^4]) + sage: F.Lattes_to_curve(check_lattes=True) + Traceback (most recent call last): + ... + NotImplementedError: Base ring must be a number field + + :: + + sage: P. = ProjectiveSpace(QQ, 1) + sage: F = DynamicalSystem_projective([x^4, y^4]) + sage: F.Lattes_to_curve(check_lattes=True) + Traceback (most recent call last): + ... + ValueError: Map is not Lattes + + :: + + sage: P. = ProjectiveSpace(QQ, 1) + sage: F = DynamicalSystem_projective([x^4, y^4]) + sage: F.Lattes_to_curve() + Traceback (most recent call last): + ... + ValueError: No Solutions found. Check if map is Lattes + + :: + + sage: P. = ProjectiveSpace(QQ, 1) + sage: F = DynamicalSystem_projective([x^3, y^3]) + sage: F.Lattes_to_curve(check_lattes=True) + Traceback (most recent call last): + ... + NotImplementedError: Map is not Lattes or is Complex Lattes + + :: + + sage: K.=QuadraticField(2) + sage: P.=ProjectiveSpace(K, 1) + sage: E=EllipticCurve([1, x]) + sage: f=P.Lattes_map(E, 2) + sage: f.Lattes_to_curve() + Elliptic Curve defined by y^2 = x^3 + x + a + over Number Field in a with defining polynomial y^2 - 2 + + :: + + sage: P.=ProjectiveSpace(QQbar, 1) + sage: E=EllipticCurve([1, 2]) + sage: f=P.Lattes_map(E, 2) + sage: f.Lattes_to_curve(check_lattes=true) + Elliptic Curve defined by y^2 = x^3 + x + 2 over Rational Field + + """ + if self.base_ring() is not QQbar: + if self.base_ring() not in NumberFields(): + raise NotImplementedError("Base ring must be a number field") + #The Complex case is hard to implement and needs to be done later + if sqrt(self.degree()) != int(sqrt(self.degree())): + raise NotImplementedError("Map is not Lattes or is Complex Lattes") + if check_lattes: + V = self.is_Lattes() + if not V: + raise ValueError("Map is not Lattes") + n = int(sqrt(self.degree())) + #Creating a Symbolic Lattes map f_sym from a short Elliptic curve + R = PolynomialRing(self.base_ring(), 6, "avar, bvar, uvar, vvar, wvar, tvar") + a, b, u, v, w, t = R.gens() + P = ProjectiveSpace(R, 1, self.domain().gens()) + E_sym = EllipticCurve([a, b]) + f_sym = P.Lattes_map(E_sym, n) + # Conjugating f_sym map to have the right form so we can solve for the conjugating matrix later + m = matrix(R, 2, [u, v, t, w]) + f_sym = f_sym.conjugate(m) + f_sym.scale_by(u*w - v*t) + F_sym = f_sym.dehomogenize(1) + #extracting the base variables to do term by term matching + self.scale_by(1/self[0].lc()) + F = self.dehomogenize(1) + #Creating a set of equations, eq, from term by term matching + eq = [u*w - v*t-1] + for j in range(2): + if j == 0: + g = F[0].numerator() + g_sym = F_sym[0].numerator() + else: + g = F[0].denominator() + g_sym = F_sym[0].denominator() + eq += (g - g_sym).coefficients() + #Solving the equations + phi = QQbar.coerce_map_from(R.base_ring()) + if phi is None: + phi = R.base_ring().embeddings(QQbar)[0] + eq = [poly.numerator().change_ring(phi) for poly in eq] + I = eq[0].parent().ideal(eq) + pts = I.variety() + if len(pts) == 0: + raise ValueError("No Solutions found. Check if map is Lattes") + a = pts[0]['avar'] + b = pts[0]['bvar'] + u = pts[0]['uvar'] + v = pts[0]['vvar'] + t = pts[0]['tvar'] + w = pts[0]['wvar'] + K, [a, b, u, v, t, w], phi = number_field_elements_from_algebraics([a, b, u, v, t, w]) + #creating our end products + E = EllipticCurve([a, b]) + if return_conjugation: + M = matrix(K, 2, 2, [u, v, t, w]) + return (M, E) + return E class DynamicalSystem_projective_field(DynamicalSystem_projective, SchemeMorphism_polynomial_projective_space_field): @@ -6860,13 +7049,13 @@ def lift_to_rational_periodic(self, points_modp, B=None): INPUT: - - ``points_modp`` -- a list or tuple of pairs containing a point + - ``points_modp`` -- list or tuple of pairs containing a point in projective space over `\GF{p}` and the possible period - ``B`` -- (optional) a positive integer; the height bound for a rational preperiodic point - OUTPUT: a list of projective points + OUTPUT: list of projective points EXAMPLES:: @@ -6927,7 +7116,7 @@ def lift_to_rational_periodic(self, points_modp, B=None): while points: q = points.pop() qindex = N - #Find the last non-zero coordinate to use for normalizations + #Find the last nonzero coordinate to use for normalizations while q[0][qindex] % p == 0: qindex -= 1 T = q[0] @@ -7039,7 +7228,7 @@ def lift_to_rational_periodic(self, points_modp, B=None): while not done and k <= n: newP = self(newP) if newP == P: - if not ([P, k] in good_points): + if [P, k] not in good_points: good_points.append([newP, k]) done = True k += 1 @@ -7076,9 +7265,7 @@ def all_periodic_points(self, **kwds): See [Hutz2015]_. - INPUT: - - kwds: + INPUT: keyword arguments: - ``R`` -- (default: domain of dynamical system) the base ring over which the periodic points of the dynamical system are found @@ -7105,7 +7292,7 @@ def all_periodic_points(self, **kwds): - ``ncpus`` -- (default: all cpus) number of cpus to use in parallel - OUTPUT: a list of rational points in projective space + OUTPUT: list of rational points in projective space EXAMPLES:: @@ -7171,7 +7358,7 @@ def all_periodic_points(self, **kwds): sage: P. = ProjectiveSpace(QQ, 3) sage: f = DynamicalSystem_projective([x^2 - (3/4)*w^2, y^2 - 3/4*w^2, ....: z^2 - 3/4*w^2, w^2]) - sage: sorted(f.all_periodic_points(algorithm="dynatomic")) # needs sage.rings.function_field + sage: sorted(f.all_periodic_points(algorithm='dynatomic')) # needs sage.rings.function_field [(-1/2 : -1/2 : -1/2 : 1), (-1/2 : -1/2 : 3/2 : 1), (-1/2 : 3/2 : -1/2 : 1), @@ -7199,7 +7386,7 @@ def all_periodic_points(self, **kwds): sage: P. = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem([x^2 + y^2, x*y]) - sage: f.all_periodic_points(algorithm="banana") + sage: f.all_periodic_points(algorithm='banana') Traceback (most recent call last): ... ValueError: algorithm must be 'dynatomic' or 'lifting' @@ -7312,7 +7499,7 @@ def all_periodic_points(self, **kwds): pos_points = [] # check period, remove duplicates for i in range(len(all_points)): - if all_points[i][1] in periods and not (all_points[i] in pos_points): + if all_points[i][1] in periods and all_points[i] not in pos_points: pos_points.append(all_points[i]) periodic_points = DS.lift_to_rational_periodic(pos_points,B) for p,n in periodic_points: @@ -7337,9 +7524,9 @@ def all_rational_preimages(self, points): INPUT: - - ``points`` -- a list of rational points in the domain of this map + - ``points`` -- list of rational points in the domain of this map - OUTPUT: a list of rational points in the domain of this map + OUTPUT: list of rational points in the domain of this map EXAMPLES:: @@ -7407,7 +7594,7 @@ def all_rational_preimages(self, points): P = points.pop() preimages = self.rational_preimages(P) for i in range(len(preimages)): - if not preimages[i] in preperiodic: + if preimages[i] not in preperiodic: points.append(preimages[i]) preperiodic.add(preimages[i]) return list(preperiodic) @@ -7437,9 +7624,7 @@ def all_preperiodic_points(self, **kwds): - Determines the rational preperiodic points from the rational periodic points by determining rational preimages. - INPUT: - - kwds: + INPUT: keyword arguments: - ``R`` -- (default: domain of dynamical system) the base ring over which the periodic points of the dynamical system are found @@ -7467,7 +7652,7 @@ def all_preperiodic_points(self, **kwds): current options are `dynatomic` and `lifting`; defaults to solving the dynatomic for low periods and degrees and lifts for everything else - OUTPUT: a list of rational points in projective space + OUTPUT: list of rational points in projective space EXAMPLES:: @@ -7607,9 +7792,7 @@ def rational_preperiodic_graph(self, **kwds): - Determines the rational preperiodic points from the rational periodic points by determining rational preimages. - INPUT: - - kwds: + INPUT: keyword arguments: - ``prime_bound`` -- (default: ``[1, 20]``) a pair (list or tuple) of positive integers that represent the limits of primes to use @@ -7670,7 +7853,7 @@ def rational_preperiodic_graph(self, **kwds): def connected_rational_component(self, P, n=0): r""" - Computes the connected component of a rational preperiodic + Compute the connected component of a rational preperiodic point ``P`` by this dynamical system. Will work for non-preperiodic points if ``n`` is positive. @@ -7683,9 +7866,7 @@ def connected_rational_component(self, P, n=0): - ``n`` -- (default: 0) integer; maximum distance from ``P`` to branch out; a value of 0 indicates no bound - OUTPUT: - - A list of points connected to ``P`` up to the specified distance. + OUTPUT: list of points connected to ``P`` up to the specified distance EXAMPLES:: @@ -7729,7 +7910,6 @@ def connected_rational_component(self, P, n=0): (-1/2 : 1/2 : 1), (1/2 : -1/2 : 1), (1/2 : 1/2 : 1)] - """ points = [[],[]] # list of points and a list of their corresponding levels points[0].append(P) @@ -7802,12 +7982,10 @@ def conjugating_set(self, other, R=None, num_cpus=2): - ``R`` -- a field or embedding - - ``num_cpus`` -- (default: 2) the number of threads to run in parallel. - Increasing ``num_cpus`` can potentially greatly speed up this function. + - ``num_cpus`` -- (default: 2) the number of threads to run in parallel; + increasing ``num_cpus`` can potentially greatly speed up this function - OUTPUT: - - Set of conjugating `n+1` by `n+1` matrices. + OUTPUT: set of conjugating `n+1` by `n+1` matrices AUTHORS: @@ -8057,8 +8235,8 @@ def is_conjugate(self, other, R=None, num_cpus=2): - ``R`` -- a field or embedding - - ``num_cpus`` -- (default: 2) the number of threads to run in parallel. - Increasing ``num_cpus`` can potentially greatly speed up this function. + - ``num_cpus`` -- (default: 2) the number of threads to run in parallel; + increasing ``num_cpus`` can potentially greatly speed up this function OUTPUT: boolean @@ -8372,7 +8550,7 @@ def normal_form(self, return_conjugation=False): INPUT: - - ``return_conjugation`` -- (default: ``False``) boolean; if ``True``, + - ``return_conjugation`` -- boolean (default: ``False``); if ``True``, then return the conjugation element of PGL along with the embedding into the new field @@ -8437,6 +8615,14 @@ def normal_form(self, return_conjugation=False): To: Finite Field in z2 of size 3^2 Defn: 1 |--> 1 + Fixes :issue:`38012` by not forcing univariate polynomial to be univariate:: + + sage: R. = PolynomialRing(QQ) + sage: f = DynamicalSystem_affine(z^2 + z + 1).homogenize(1) + sage: f.normal_form() + Dynamical System of Projective Space of dimension 1 over Rational Field + Defn: Defined on coordinates by sending (x0 : x1) to + (x0^2 + 5/4*x1^2 : x1^2) """ # defines the field of fixed points if self.codomain().dimension_relative() != 1: @@ -8465,7 +8651,8 @@ def normal_form(self, return_conjugation=False): #we find one and not go all the way to the splitting field i = 0 if G.degree() != 0: - G = G.polynomial(G.variable(0)) + if isinstance(G.parent(), MPolynomialRing_base): + G = G.polynomial(G.variable(0)) else: #no other fixed points raise NotImplementedError("map is not a polynomial") @@ -8580,12 +8767,10 @@ def potential_good_reduction(self, prime, return_conjugation=False): points of the map, or a prime number in `\QQ` if the field of definition of the fixed points is `\QQ`. - - ``return_conjugation`` -- (default: ``False``) if set to ``True``, + - ``return_conjugation`` -- boolean (default: ``False``); if set to ``True``, the `PGL_2` map used to achieve good reduction will be returned - OUTPUT: - - A tuple: + OUTPUT: a tuple: - The first element is: - ``False`` if this dynamical system does not have potential good reduction. @@ -8685,7 +8870,6 @@ def potential_good_reduction(self, prime, return_conjugation=False): sage: prime = system.field_of_definition_periodic(1).prime_above(3) # needs sage.rings.number_field sage: system.potential_good_reduction(prime) # needs sage.rings.number_field (False, None) - """ if self.domain().base_ring() not in NumberFields(): raise ValueError('dynamical system must be defined over number field') @@ -8773,7 +8957,7 @@ def reduce_base_field(self): the base ring is a number field, QQbar, a finite field, or algebraic closure of a finite field. - OUTPUT: A dynamical system + OUTPUT: a dynamical system EXAMPLES:: @@ -8835,13 +9019,13 @@ def is_newton(self, return_conjugation=False): INPUT: - - ``return_conjugation`` -- (default: ``False``) if the map is Newton + - ``return_conjugation`` -- boolean (default: ``False``); if the map is Newton and ``True``, then return the conjugation that moves this map to the above form OUTPUT: - A Boolean. If ``return_conjugation`` is ``True``, then this also + A boolean. If ``return_conjugation`` is ``True``, then this also returns the conjugation as a matrix if ``self`` is Newton or ``None`` otherwise. @@ -8889,7 +9073,7 @@ def is_newton(self, return_conjugation=False): """ if self.degree() == 1: raise NotImplementedError("degree one Newton maps are trivial") - if not self.base_ring() in NumberFields(): + if self.base_ring() not in NumberFields(): raise NotImplementedError("only implemented over number fields") # check if Newton map sigma_1 = self.sigma_invariants(1) @@ -8970,7 +9154,7 @@ def _is_preperiodic(self, P, **kwds): keywords: - - ``return_period`` -- (default: ``False``) boolean; controls if + - ``return_period`` -- boolean (default: ``False``); controls if the period is returned OUTPUT: the boolean ``True`` or a tuple ``(m,n)`` of integers @@ -9141,7 +9325,7 @@ def possible_periods(self, return_points=False): INPUT: - - ``return_points`` -- (default: ``False``) boolean; if ``True``, + - ``return_points`` -- boolean (default: ``False``); if ``True``, then return the points as well as the possible periods OUTPUT: @@ -9196,22 +9380,22 @@ def automorphism_group(self, **kwds): The following keywords are used when the dimension of the domain is greater than 1: - - ``num_cpus`` -- (default: 2) the number of threads to use. Setting to a - larger number can greatly speed up this function. + - ``num_cpus`` -- (default: 2) the number of threads to use; setting to a + larger number can greatly speed up this function The following keywords are used when the dimension of the domain is 1: - - ``absolute`` -- (default: ``False``) boolean; if ``True``, then + - ``absolute`` -- boolean (default: ``False``); if ``True``, then return the absolute automorphism group and a field of definition - - ``iso_type`` -- (default: ``False``) boolean; if ``True``, then + - ``iso_type`` -- boolean (default: ``False``); if ``True``, then return the isomorphism type of the automorphism group - - ``return_functions`` -- (default: ``False``) boolean; ``True`` + - ``return_functions`` -- boolean (default: ``False``); ``True`` returns elements as linear fractional transformations and ``False`` returns elements as `PGL2` matrices - OUTPUT: a list of elements of the automorphism group + OUTPUT: list of elements of the automorphism group AUTHORS: @@ -9314,14 +9498,12 @@ def all_periodic_points(self, **kwds): r""" Return a list of all periodic points over a finite field. - INPUT: - - keywords: + INPUT: keyword arguments: - ``R`` -- (default: base ring of dynamical system) the base ring over which the periodic points of the dynamical system are found - OUTPUT: a list of elements which are periodic + OUTPUT: list of elements which are periodic EXAMPLES:: diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx index ea48d20c9b6..1da1efc2bd7 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx @@ -34,7 +34,7 @@ cpdef _fast_possible_periods(self, return_points=False): INPUT: - - ``return_points`` -- (default: ``False``) boolean; if ``True``, then + - ``return_points`` -- boolean (default: ``False``); if ``True``, then return the points as well as the possible periods OUTPUT: @@ -132,7 +132,7 @@ cpdef _fast_possible_periods(self, return_points=False): for r in rvalues: periods.add(period*r) points_periods.append([P_proj, period*r]) - if p == 2 or p == 3: #need e=1 for N=1, QQ + if p == 2 or p == 3: # need e=1 for N=1, QQ periods.add(period*r*p) points_periods.append([P_proj, period*r*p]) else: @@ -141,7 +141,7 @@ cpdef _fast_possible_periods(self, return_points=False): periods.add(period*r*p) points_periods.append([P_proj, period*r]) points_periods.append([P_proj, period*r*p]) - if p == 2: #need e=3 for N>1, QQ + if p == 2: # need e=3 for N>1, QQ periods.add(period*r*4) points_periods.append([P_proj, period*r*4]) periods.add(period*r*8) @@ -187,7 +187,6 @@ cpdef int _hash(list Point, int prime) noexcept: sage: from sage.dynamics.arithmetic_dynamics.projective_ds_helper import _hash sage: _hash([1, 2, 1], 3) 16 - """ cdef int hash_q cdef int coefficient diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index 21d107dee4c..3ef9877e782 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -56,10 +56,12 @@ def WehlerK3Surface(polys): r""" - Defines a K3 Surface over `\mathbb{P}^2 \times \mathbb{P}^2` defined as + Define a K3 Surface over `\mathbb{P}^2 \times \mathbb{P}^2` defined as the intersection of a bilinear and biquadratic form. [Weh1998]_ - INPUT: Bilinear and biquadratic polynomials as a tuple or list + INPUT: + + - ``polys`` -- bilinear and biquadratic polynomials as a tuple or list OUTPUT: :class:`WehlerK3Surface_ring` @@ -92,7 +94,9 @@ def random_WehlerK3Surface(PP): Produces a random K3 surface in `\mathbb{P}^2 \times \mathbb{P}^2` defined as the intersection of a bilinear and biquadratic form. [Weh1998]_ - INPUT: Projective space cartesian product + INPUT: + + - ``PP`` -- projective space cartesian product OUTPUT: :class:`WehlerK3Surface_ring` @@ -163,7 +167,9 @@ def change_ring(self, R): r""" Changes the base ring on which the Wehler K3 Surface is defined. - INPUT: ``R`` -- ring + INPUT: + + - ``R`` -- ring OUTPUT: K3 Surface defined over input ring @@ -188,9 +194,12 @@ def _check_satisfies_equations(self, P): r""" Function checks to see if point ``P`` lies on the K3 Surface. - INPUT: ``P`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2` + INPUT: + + - ``P`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2` - OUTPUT: AttributeError True if the point is not on the surface + OUTPUT: ``True`` if the point is not on the surface; :exc:`AttributeError` + otherwise EXAMPLES:: @@ -242,9 +251,9 @@ def _Lcoeff(self, component, i): INPUT: - - ``component`` -- Integer: 0 or 1 + - ``component`` -- integer; 0 or 1 - - ``i`` -- Integer: 0, 1 or 2 + - ``i`` -- integer; 0, 1 or 2 OUTPUT: polynomial in terms of either y (Component = 0) or x (Component = 1) @@ -290,11 +299,11 @@ def _Qcoeff(self, component, i, j): INPUT: - - ``component`` -- Integer: 0 or 1 + - ``component`` -- integer; 0 or 1 - - ``i`` -- Integer: 0, 1 or 2 + - ``i`` -- integer; 0, 1 or 2 - - ``j`` -- Integer: 0, 1 or 2 + - ``j`` -- integer; 0, 1 or 2 OUTPUT: polynomial in terms of either y (Component = 0) or x (Component = 1) @@ -340,9 +349,9 @@ def Gpoly(self, component, k): INPUT: - - ``component`` -- Integer: 0 or 1 + - ``component`` -- integer; 0 or 1 - - ``k`` -- Integer: 0, 1 or 2 + - ``k`` -- integer; 0, 1 or 2 OUTPUT: polynomial in terms of either `y` (``component=0``) or `x` (``component=1``) @@ -384,11 +393,11 @@ def Hpoly(self, component, i, j): INPUT: - - ``component`` -- Integer: 0 or 1 + - ``component`` -- integer; 0 or 1 - - ``i`` -- Integer: 0, 1 or 2 + - ``i`` -- integer; 0, 1 or 2 - - ``j`` -- Integer: 0, 1 or 2 + - ``j`` -- integer; 0, 1 or 2 OUTPUT: polynomial in terms of either y (``component=0``) or x (``component=1``) @@ -432,9 +441,9 @@ def Lxa(self, a): INPUT: - - ``a`` -- Point in `\mathbb{P}^2` + - ``a`` -- point in `\mathbb{P}^2` - OUTPUT: A polynomial representing the fiber + OUTPUT: a polynomial representing the fiber EXAMPLES:: @@ -470,9 +479,11 @@ def Qxa(self, a): Notation and definition from: [CS1996]_ - INPUT: ``a`` -- Point in `\mathbb{P}^2` + INPUT: + + - ``a`` -- point in `\mathbb{P}^2` - OUTPUT: A polynomial representing the fiber + OUTPUT: a polynomial representing the fiber EXAMPLES:: @@ -509,9 +520,9 @@ def Sxa(self, a): INPUT: - - ``a`` -- Point in `\mathbb{P}^2` + - ``a`` -- point in `\mathbb{P}^2` - OUTPUT: A subscheme representing the fiber + OUTPUT: a subscheme representing the fiber EXAMPLES:: @@ -545,9 +556,11 @@ def Lyb(self, b): Notation and definition from: [CS1996]_ - INPUT: ``b`` -- Point in projective space + INPUT: + + - ``b`` -- point in projective space - OUTPUT: A polynomial representing the fiber + OUTPUT: a polynomial representing the fiber EXAMPLES:: @@ -586,9 +599,9 @@ def Qyb(self, b): INPUT: - - ``b`` -- Point in projective space + - ``b`` -- point in projective space - OUTPUT: A polynomial representing the fiber + OUTPUT: a polynomial representing the fiber EXAMPLES:: @@ -624,9 +637,9 @@ def Syb(self, b): INPUT: - - ``b`` -- Point in `\mathbb{P}^2` + - ``b`` -- point in `\mathbb{P}^2` - OUTPUT: A subscheme representing the fiber + OUTPUT: a subscheme representing the fiber EXAMPLES:: @@ -642,7 +655,6 @@ def Syb(self, b): Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x0, x0^2 + 3*x0*x1 + x1^2 - """ if b not in self.ambient_space()[1]: raise TypeError("point must be in projective space of dimension 2") @@ -661,9 +673,11 @@ def Ramification_poly(self, i): The roots of this polynomial will either be degenerate fibers or fixed points of the involutions `\sigma_x` or `\sigma_y` for more information, see [CS1996]_. - INPUT: ``i`` -- Integer, either 0 (polynomial in y) or 1 (polynomial in x) + INPUT: + + - ``i`` -- integer; either 0 (polynomial in y) or 1 (polynomial in x) - OUTPUT: Polynomial in the coordinate ring of the ambient space + OUTPUT: polynomial in the coordinate ring of the ambient space EXAMPLES:: @@ -697,8 +711,8 @@ def Ramification_poly(self, i): @cached_method def is_degenerate(self): r""" - Function will return True if there is a fiber (over the algebraic closure of the - base ring) of dimension greater than 0 and False otherwise. + Function will return ``True`` if there is a fiber (over the algebraic closure of the + base ring) of dimension greater than 0 and ``False`` otherwise. OUTPUT: boolean @@ -776,7 +790,7 @@ def degenerate_fibers(self): This function finds the common solution through elimination via Groebner bases by using the .variety() function on the three affine charts in each component. - OUTPUT: The output is a list of lists where the elements of lists are + OUTPUT: the output is a list of lists where the elements of lists are points in the appropriate projective space. The first list is the points whose pullback by the projection to the first component (projective space) is dimension greater than 0. @@ -884,13 +898,15 @@ def degenerate_fibers(self): @cached_method def degenerate_primes(self, check=True): r""" - Determine which primes `p` self has degenerate fibers over `\GF{p}`. + Determine which primes `p` ``self`` has degenerate fibers over `\GF{p}`. If ``check`` is ``False``, then may return primes that do not have degenerate fibers. Raises an error if the surface is degenerate. Works only for ``ZZ`` or ``QQ``. - INPUT: ``check`` -- (default: ``True``) boolean, whether the primes are verified + INPUT: + + - ``check`` -- boolean (default: ``True``); whether the primes are verified ALGORITHM: @@ -905,7 +921,7 @@ def degenerate_primes(self, check=True): is what is checked. The lcm of the coefficients of the monomials `x_i` in a Groebner basis is computed. This may return extra primes. - OUTPUT: List of primes. + OUTPUT: list of primes EXAMPLES:: @@ -996,7 +1012,7 @@ def is_smooth(self): Checks to confirm that all of the 2x2 minors of the Jacobian generated from the biquadratic and bilinear forms have no common vanishing points. - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -1057,11 +1073,11 @@ def sigmaX(self, P, **kwds): kwds: - - ``check`` -- (default: ``True``) boolean checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``True``) boolean normalizes the point + - ``normalize`` -- boolean (default: ``True``); normalizes the point - OUTPUT: A point on the K3 surface + OUTPUT: a point on the K3 surface EXAMPLES:: @@ -1174,7 +1190,7 @@ def sigmaX(self, P, **kwds): -phi(self.Hpoly(1, 1, 2))] maxexp = [] - #Find highest exponent that we can divide out by to get a non zero answer + #Find highest exponent that we can divide out by to get a nonzero answer for i in range(2,len(T)): e = 0 while (T[i]/t**e).subs({w1:t1}) == 0: @@ -1304,11 +1320,11 @@ def sigmaY(self,P, **kwds): kwds: - - ``check`` -- (default: ``True``) boolean checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``True``) boolean normalizes the point + - ``normalize`` -- boolean (default: ``True``); normalizes the point - OUTPUT: A point on the K3 surface + OUTPUT: a point on the K3 surface EXAMPLES:: @@ -1419,7 +1435,7 @@ def sigmaY(self,P, **kwds): -phi(self.Hpoly(0, 1, 2))] maxexp = [] - #Find highest exponent that we can divide out by to get a non zero answer + #Find highest exponent that we can divide out by to get a nonzero answer for i in range(2, len(T)): e = 0 while (T[i]/t**e).subs({w1:t1}) == 0: @@ -1536,15 +1552,15 @@ def phi(self, a, **kwds): INPUT: - - ``a`` -- Point in `\mathbb{P}^2 \times \mathbb{P}^2` + - ``a`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2` kwds: - - ``check`` -- (default: ``True``) boolean checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``True``) boolean normalizes the point + - ``normalize`` -- boolean (default: ``True``); normalizes the point - OUTPUT: A point on this surface + OUTPUT: a point on this surface EXAMPLES:: @@ -1576,15 +1592,15 @@ def psi(self,a, **kwds): INPUT: - - ``a`` -- Point in `\mathbb{P}^2 \times \mathbb{P}^2` + - ``a`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2` kwds: - - ``check`` -- (default: ``True``) boolean checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``True``) boolean normalizes the point + - ``normalize`` -- boolean (default: ``True``); normalizes the point - OUTPUT: A point on this surface + OUTPUT: a point on this surface EXAMPLES:: @@ -1619,16 +1635,17 @@ def lambda_plus(self, P, v, N, m, n, prec=100): - ``P`` -- a surface point - - ``N`` -- positive integer. number of terms of the series to use + - ``N`` -- positive integer; number of terms of the series to use - - ``v`` -- non-negative integer. a place, use v = 0 for the Archimedean place + - ``v`` -- nonnegative integer; a place, use v = 0 for the Archimedean place - - ``m``, ``n`` -- positive integers; we compute the local height for the divisor `E_{mn}^{+}`. - These must be indices of non-zero coordinates of the point ``P``. + - ``m``, ``n`` -- positive integers; we compute the local height for + the divisor `E_{mn}^{+}`. These must be indices of nonzero + coordinates of the point ``P`` - - ``prec`` -- (default: 100) float point or p-adic precision + - ``prec`` -- (default: 100) float point or `p`-adic precision - OUTPUT: A real number + OUTPUT: a real number EXAMPLES:: @@ -1720,15 +1737,15 @@ def lambda_minus(self, P, v, N, m, n, prec=100): - ``N`` -- positive integer. number of terms of the series to use - - ``v`` -- non-negative integer. a place, use v = 0 for the Archimedean place + - ``v`` -- nonnegative integer. a place, use v = 0 for the Archimedean place - ``m``, ``n`` -- positive integers; we compute the local height for - the divisor `E_{mn}^{+}`. These must be indices of non-zero + the divisor `E_{mn}^{+}`. These must be indices of nonzero coordinates of the point ``P``. - - ``prec`` -- (default: 100) float point or p-adic precision + - ``prec`` -- (default: 100) float point or `p`-adic precision - OUTPUT: A real number + OUTPUT: a real number EXAMPLES:: @@ -1817,9 +1834,9 @@ def canonical_height_plus(self, P, N, badprimes=None, prec=100): - ``badprimes`` -- (optional) list of integer primes (where the surface is degenerate) - - ``prec`` -- (default: 100) float point or p-adic precision + - ``prec`` -- (default: 100) float point or `p`-adic precision - OUTPUT: A real number + OUTPUT: a real number EXAMPLES:: @@ -1881,9 +1898,9 @@ def canonical_height_minus(self, P, N, badprimes=None, prec=100): - ``badprimes`` -- (optional) list of integer primes (where the surface is degenerate) - - ``prec`` -- (default: 100) float point or p-adic precision + - ``prec`` -- (default: 100) float point or `p`-adic precision - OUTPUT: A real number + OUTPUT: a real number EXAMPLES:: @@ -1943,9 +1960,9 @@ def canonical_height(self, P, N, badprimes=None, prec=100): - ``badprimes`` -- (optional) list of integer primes (where the surface is degenerate) - - ``prec`` -- (default: 100) float point or p-adic precision + - ``prec`` -- (default: 100) float point or `p`-adic precision - OUTPUT: A real number + OUTPUT: a real number EXAMPLES:: @@ -1991,7 +2008,7 @@ def fiber(self, p, component): - ``p`` -- a point in `\mathbb{P}^2` - OUTPUT: The corresponding fiber (as a list) + OUTPUT: the corresponding fiber (as a list) EXAMPLES:: @@ -2159,22 +2176,23 @@ def fiber(self, p, component): def nth_iterate_phi(self, P, n, **kwds): r""" - Computes the ``n``-th iterate for the phi function. + Compute the `n`-th iterate for the phi function. INPUT: - ``P`` -- a point in `\mathbb{P}^2 \times \mathbb{P}^2` - - ``n`` -- an integer + - ``n`` -- integer kwds: - - ``check`` -- (default: ``True``) boolean checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is + on the surface - - ``normalize`` -- (default: ``False``) boolean normalizes the point + - ``normalize`` -- boolean (default: ``False``); normalizes the point - OUTPUT: The nth iterate of the point given the phi function (if ``n`` is positive), or the - psi function (if ``n`` is negative) + OUTPUT: the `n`-th iterate of the point given the phi function (if `n` + is positive), or the psi function (if `n` is negative) EXAMPLES:: @@ -2224,22 +2242,22 @@ def nth_iterate_phi(self, P, n, **kwds): def nth_iterate_psi(self, P, n, **kwds): r""" - Computes the ``n``-th iterate for the psi function. + Compute the `n`-th iterate for the psi function. INPUT: - ``P`` -- a point in `\mathbb{P}^2 \times \mathbb{P}^2` - - ``n`` -- an integer + - ``n`` -- integer kwds: - - ``check`` -- (default: ``True``) boolean, checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``False``) boolean, normalizes the point + - ``normalize`` -- boolean (default: ``False``); normalizes the point - OUTPUT: The nth iterate of the point given the psi function (if ``n`` is positive), - or the phi function (if ``n`` is negative) + OUTPUT: the `n`-th iterate of the point given the psi function (if `n` is positive), + or the phi function (if `n` is negative) EXAMPLES:: @@ -2285,17 +2303,17 @@ def orbit_phi(self, P, N, **kwds): INPUT: - - ``P`` -- Point on the K3 surface + - ``P`` -- point on the K3 surface - - ``N`` -- a non-negative integer or list or tuple of two non-negative integers + - ``N`` -- nonnegative integer or list or tuple of two nonnegative integers kwds: - - ``check`` -- (default: ``True``) boolean, checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``False``) boolean, normalizes the point + - ``normalize`` -- boolean (default: ``False``); normalizes the point - OUTPUT: List of points in the orbit + OUTPUT: list of points in the orbit EXAMPLES:: @@ -2323,7 +2341,7 @@ def orbit_phi(self, P, N, **kwds): except TypeError: raise TypeError("orbit bounds must be integers") if N[0] < 0 or N[1] < 0: - raise TypeError("orbit bounds must be non-negative") + raise TypeError("orbit bounds must be nonnegative") if N[0] > N[1]: return [] Q = self(copy(P)) @@ -2346,15 +2364,15 @@ def orbit_psi(self, P, N, **kwds): - ``P`` -- a point on the K3 surface - - ``N`` -- a non-negative integer or list or tuple of two non-negative integers + - ``N`` -- nonnegative integer or list or tuple of two nonnegative integers kwds: - - ``check`` -- (default: ``True``) boolean, checks to see if point is on the surface + - ``check`` -- boolean (default: ``True``); checks to see if point is on the surface - - ``normalize`` -- (default: ``False``) boolean, normalizes the point + - ``normalize`` -- boolean (default: ``False``); normalizes the point - OUTPUT: a list of points in the orbit + OUTPUT: list of points in the orbit EXAMPLES:: @@ -2380,7 +2398,7 @@ def orbit_psi(self, P, N, **kwds): except TypeError: raise TypeError("orbit bounds must be integers") if N[0] < 0 or N[1] < 0: - raise TypeError("orbit bounds must be non-negative") + raise TypeError("orbit bounds must be nonnegative") if N[0] > N[1]: return [] Q = self(copy(P)) @@ -2400,7 +2418,7 @@ def is_isomorphic(self, right): - ``right`` -- the K3 surface to compare to the original - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -2439,7 +2457,7 @@ def is_symmetric_orbit(self,orbit): - ``orbit`` -- a periodic cycle of either psi or phi - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -2493,7 +2511,7 @@ def cardinality( self): Enumerate points over `\mathbb{P}^2`, and then count the points on the fiber of each of those points. - OUTPUT: Integer -- total number of points on the surface + OUTPUT: integer; total number of points on the surface EXAMPLES:: diff --git a/src/sage/dynamics/cellular_automata/elementary.py b/src/sage/dynamics/cellular_automata/elementary.py index 77d5b705fcb..51f959ed237 100644 --- a/src/sage/dynamics/cellular_automata/elementary.py +++ b/src/sage/dynamics/cellular_automata/elementary.py @@ -51,7 +51,7 @@ class ElementaryCellularAutomata(SageObject): INPUT: - - ``rule`` -- an integer between 0 and 255 + - ``rule`` -- integer between 0 and 255 - ``width`` -- (optional) the width of the ECA - ``initial_state`` -- (optional) the initial state given as a list of ``0`` and ``1`` diff --git a/src/sage/dynamics/cellular_automata/glca.py b/src/sage/dynamics/cellular_automata/glca.py index 8c896a981e9..ea84884755b 100644 --- a/src/sage/dynamics/cellular_automata/glca.py +++ b/src/sage/dynamics/cellular_automata/glca.py @@ -34,7 +34,7 @@ class GraftalLaceCellularAutomata(SageObject): INPUT: - - ``rule`` -- a list of length 8 with integer entries `0 \leq x < 8` + - ``rule`` -- list of length 8 with integer entries `0 \leq x < 8` EXAMPLES:: @@ -105,7 +105,6 @@ def __init__(self, rule): Traceback (most recent call last): ... ValueError: invalid rule - """ if len(rule) != 8 or any(x not in range(8) for x in rule): raise ValueError("invalid rule") @@ -364,24 +363,24 @@ def _unicode_art_(self, number=None): number = len(self._states) space = len(self._states[:number]) * 2 - 1 - ret = UnicodeArt([u' '*space + u'◾']) + ret = UnicodeArt([' '*space + '◾']) space += 1 for i,state in enumerate(self._states[:number]): - temp = u' '*(space-2) - last = u' ' + temp = ' '*(space-2) + last = ' ' for x in state: if x & 0x4: - if last == u'╱': - temp += u'╳' + if last == '╱': + temp += '╳' else: - temp += u'╲' + temp += '╲' else: temp += last - temp += u'│' if x & 0x2 else ' ' - last = u'╱' if x & 0x1 else ' ' + temp += '│' if x & 0x2 else ' ' + last = '╱' if x & 0x1 else ' ' ret *= UnicodeArt([temp + last]) space -= 1 - ret *= UnicodeArt([u' '*space + u' '.join(u'◾' for dummy in range(2*i+1))]) + ret *= UnicodeArt([' '*space + ' '.join('◾' for dummy in range(2*i+1))]) space -= 1 return ret diff --git a/src/sage/dynamics/cellular_automata/solitons.py b/src/sage/dynamics/cellular_automata/solitons.py index 72ec9ed0104..8f5c3110533 100644 --- a/src/sage/dynamics/cellular_automata/solitons.py +++ b/src/sage/dynamics/cellular_automata/solitons.py @@ -755,7 +755,7 @@ def print_state(self, num=None, vacuum_letter='.', remove_trailing_vacuums=False - ``num`` -- (default: the current state) the state to print - ``vacuum_letter`` -- (default: ``'.'``) the letter to print for the vacuum - - ``remove_trailing_vacuums`` -- (default: ``False``) if ``True`` + - ``remove_trailing_vacuums`` -- boolean (default: ``False``); if ``True`` then this does not print the vacuum letters at the right end of the state @@ -964,9 +964,9 @@ def latex_states(self, num=None, as_array=True, box_width='5pt'): INPUT: - ``num`` -- the number of states - - ``as_array`` (default: ``True``) if ``True``, then the states are - placed inside of an array; if ``False``, then the states are - given as a word + - ``as_array`` -- boolean (default: ``True``); if ``True``, then the + states are placed inside of an array; if ``False``, then the states + are given as a word - ``box_width`` -- (default: ``'5pt'``) the width of the ``.`` used to represent the vacuum state when ``as_array`` is ``True`` diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index 8ceb38d0cec..f21ffca80e4 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -71,42 +71,40 @@ def mandelbrot_plot(f=None, **kwds): INPUT: - - ``f`` -- map (default: ``z^2 + c``), polynomial family used to - plot the Mandelbrot set. + - ``f`` -- map (default: ``z^2 + c``); polynomial family used to + plot the Mandelbrot set - - ``parameter`` -- variable (default: ``c``), parameter variable - used to plot the Mandelbrot set. + - ``parameter`` -- variable (default: ``c``); parameter variable + used to plot the Mandelbrot set - - ``x_center`` -- double (default: ``-1.0``), Real part of center - point. + - ``x_center`` -- double (default: ``-1.0``); Real part of center + point - - ``y_center`` -- double (default: ``0.0``), Imaginary part of - center point. + - ``y_center`` -- double (default: ``0.0``); Imaginary part of + center point - - ``image_width`` -- double (default: ``4.0``), width of image - in the complex plane. + - ``image_width`` -- double (default: ``4.0``); width of image + in the complex plane - - ``max_iteration`` -- long (default: ``500``), maximum number of - iterations the map ``f_c(z)``. + - ``max_iteration`` -- long (default: ``500``); maximum number of + iterations the map ``f_c(z)`` - - ``pixel_count`` -- long (default: ``500``), side length of - image in number of pixels. + - ``pixel_count`` -- long (default: ``500``); side length of + image in number of pixels - - ``base_color`` -- RGB color (default: ``[40, 40, 40]``) color - used to determine the coloring of set. + - ``base_color`` -- RGB color (default: ``[40, 40, 40]``); color + used to determine the coloring of set - - ``level_sep`` -- long (default: 1) number of iterations - between each color level. + - ``level_sep`` -- long (default: 1); number of iterations + between each color level - - ``number_of_colors`` -- long (default: 30) number of colors - used to plot image. + - ``number_of_colors`` -- long (default: 30); number of colors + used to plot image - - ``interact`` -- boolean (default: ``False``), controls whether - plot will have interactive functionality. + - ``interact`` -- boolean (default: ``False``); controls whether + plot will have interactive functionality - OUTPUT: - - 24-bit RGB image of the Mandelbrot set in the complex plane. + OUTPUT: 24-bit RGB image of the Mandelbrot set in the complex plane EXAMPLES: @@ -211,11 +209,11 @@ def mandelbrot_plot(f=None, **kwds): y_center=FloatSlider(min=-1.0, max=1.0, step=EPS, value=y_center, description="Imag center"), image_width=FloatSlider(min=EPS, max=4.0, step=EPS, - value=image_width, description="Width"), + value=image_width, description='Width'), max_iteration=IntSlider(min=0, max=1000, - value=max_iteration, description="Iterations"), + value=max_iteration, description='Iterations'), pixel_count=IntSlider(min=10, max=1000, - value=pixel_count, description="Pixels"), + value=pixel_count, description='Pixels'), level_sep=IntSlider(min=1, max=20, value=level_sep, description="Color sep"), color_num=IntSlider(min=1, max=100, @@ -301,36 +299,34 @@ def external_ray(theta, **kwds): INPUT: - - ``theta`` -- double or list of doubles, angles between 0 and 1 inclusive. + - ``theta`` -- double or list of doubles, angles between 0 and 1 inclusive kwds: - - ``image`` -- 24-bit RGB image (default: None) user specified - image of Mandelbrot set. + - ``image`` -- 24-bit RGB image (default: ``None``); user specified + image of Mandelbrot set - - ``D`` -- long (default: ``25``) depth of the approximation. + - ``D`` -- long (default: ``25``); depth of the approximation. As ``D`` increases, the external ray gets closer to the boundary of the Mandelbrot set. If the ray doesn't reach the boundary of the Mandelbrot set, increase ``D``. - - ``S`` -- long (default: ``10``) sharpness of the approximation. + - ``S`` -- long (default: ``10``); sharpness of the approximation. Adjusts the number of points used to approximate the external ray (number of points is equal to ``S*D``). If ray looks jagged, increase ``S``. - - ``R`` -- long (default: ``100``) radial parameter. If ``R`` is + - ``R`` -- long (default: ``100``); radial parameter. If ``R`` is large, the external ray reaches sufficiently close to infinity. If ``R`` is too small, Newton's method may not converge to the correct ray. - - ``prec`` -- long (default: ``300``) specifies the bits of + - ``prec`` -- long (default: ``300``); specifies the bits of precision used by the Complex Field when using Newton's method to compute - points on the external ray. + points on the external ray - ``ray_color`` -- RGB color (default: ``[255, 255, 255]``) color - of the external ray(s). - - OUTPUT: + of the external ray(s) - 24-bit RGB image of external ray(s) on the Mandelbrot set. + OUTPUT: 24-bit RGB image of external ray(s) on the Mandelbrot set EXAMPLES:: @@ -434,6 +430,7 @@ def external_ray(theta, **kwds): pixel[int(k[0]), int(k[1])] = tuple(ray_color) return M + def kneading_sequence(theta): r""" Determines the kneading sequence for an angle theta in RR/ZZ which @@ -444,9 +441,7 @@ def kneading_sequence(theta): - ``theta`` -- a rational number with odd denominator - OUTPUT: - - a string representing the kneading sequence of theta in RR/ZZ + OUTPUT: string representing the kneading sequence of theta in RR/ZZ REFERENCES: @@ -529,48 +524,46 @@ def julia_plot(f=None, **kwds): INPUT: - - ``f`` -- input polynomial (default: ``z^2 - 1``). + - ``f`` -- input polynomial (default: ``z^2 - 1``) - - ``period`` -- list (default: ``None``), returns the Julia set - for a random `c` value with the given (formal) cycle structure. + - ``period`` -- list (default: ``None``); returns the Julia set + for a random `c` value with the given (formal) cycle structure - - ``mandelbrot`` -- boolean (default: ``True``), when set to + - ``mandelbrot`` -- boolean (default: ``True``); when set to ``True``, an image of the Mandelbrot set is appended to the right of the - Julia set. - - - ``point_color`` -- RGB color (default: ``'tomato'``), - color of the point `c` in the Mandelbrot set (any valid input for Color). + Julia set - - ``x_center`` -- double (default: ``-1.0``), Real part - of center point. + - ``point_color`` -- RGB color (default: ``'tomato'``); + color of the point `c` in the Mandelbrot set (any valid input for Color) - - ``y_center`` -- double (default: ``0.0``), Imaginary part - of center point. + - ``x_center`` -- double (default: ``-1.0``); real part + of center point - - ``image_width`` -- double (default: ``4.0``), width of image - in the complex plane. + - ``y_center`` -- double (default: ``0.0``); imaginary part + of center point - - ``max_iteration`` -- long (default: ``500``), maximum number - of iterations the map `f(z)`. + - ``image_width`` -- double (default: ``4.0``); width of image + in the complex plane - - ``pixel_count`` -- long (default: ``500``), side length of - image in number of pixels. + - ``max_iteration`` -- long (default: ``500``); maximum number + of iterations the map `f(z)` - - ``base_color`` -- hex color (default: ``'steelblue'``), color - used to determine the coloring of set (any valid input for Color). + - ``pixel_count`` -- long (default: ``500``); side length of + image in number of pixels - - ``level_sep`` -- long (default: 1), number of iterations - between each color level. + - ``base_color`` -- hex color (default: ``'steelblue'``); color + used to determine the coloring of set (any valid input for Color) - - ``number_of_colors`` -- long (default: 30), number of colors - used to plot image. + - ``level_sep`` -- long (default: 1); number of iterations + between each color level - - ``interact`` -- boolean (default: ``False``), controls whether - plot will have interactive functionality. + - ``number_of_colors`` -- long (default: 30); number of colors + used to plot image - OUTPUT: + - ``interact`` -- boolean (default: ``False``); controls whether + plot will have interactive functionality - 24-bit RGB image of the Julia set in the complex plane. + OUTPUT: 24-bit RGB image of the Julia set in the complex plane .. TODO:: @@ -738,11 +731,11 @@ def julia_plot(f=None, **kwds): y_center=FloatSlider(min=-1.0, max=1.0, step=EPS, value=y_center, description="Imag center"), image_width=FloatSlider(min=EPS, max=4.0, step=EPS, - value=image_width, description="Width"), + value=image_width, description='Width'), max_iteration=IntSlider(min=0, max=1000, - value=max_iteration, description="Iterations"), + value=max_iteration, description='Iterations'), pixel_count=IntSlider(min=10, max=1000, - value=pixel_count, description="Pixels"), + value=pixel_count, description='Pixels'), level_sep=IntSlider(min=1, max=20, value=level_sep, description="Color sep"), color_num=IntSlider(min=1, max=100, diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx b/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx index 479589dc0e3..2fd00e9b07a 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +++ b/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx @@ -78,27 +78,25 @@ cpdef fast_mandelbrot_plot(double x_center, double y_center, INPUT: - - ``x_center`` -- double, real part of the center point in the complex plane. + - ``x_center`` -- double; real part of the center point in the complex plane - - ``y_center`` -- double, imaginary part of the center point in the complex - plane. - - - ``image_width`` -- double, width of the image in the complex plane. + - ``y_center`` -- double; imaginary part of the center point in the complex + plane - - ``max_iteration`` -- long, maximum number of iterations the map `Q_c(z)` - considered. + - ``image_width`` -- double; width of the image in the complex plane - - ``pixel_count`` -- long, side length of image in number of pixels. + - ``max_iteration`` -- long; maximum number of iterations the map `Q_c(z)` + considered - - ``level_sep`` -- long, number of iterations between each color level. + - ``pixel_count`` -- long; side length of image in number of pixels - - ``color_num`` -- long, number of colors used to plot image. + - ``level_sep`` -- long; number of iterations between each color level - - ``base_color`` -- list, RGB color used to determine the coloring of set. + - ``color_num`` -- long; number of colors used to plot image - OUTPUT: + - ``base_color`` -- list; RGB color used to determine the coloring of set - 24-bit RGB image of the Mandelbrot set in the complex plane. + OUTPUT: 24-bit RGB image of the Mandelbrot set in the complex plane EXAMPLES: @@ -185,32 +183,30 @@ cpdef fast_external_ray(double theta, long D=30, long S=10, long R=100, INPUT: - - ``theta`` -- double, angle between 0 and 1 inclusive. + - ``theta`` -- double; angle between 0 and 1 inclusive - - ``D`` -- long (default: ``25``) depth of the approximation. + - ``D`` -- long (default: ``25``); depth of the approximation. As ``D`` increases, the external ray gets closer to the boundary of the Mandelbrot set. - - ``S`` -- long (default: ``10``) sharpness of the approximation. + - ``S`` -- long (default: ``10``); sharpness of the approximation. Adjusts the number of points used to approximate the external ray (number of points is equal to ``S*D``). - - ``R`` -- long (default: ``100``) radial parameter. If ``R`` is + - ``R`` -- long (default: ``100``); radial parameter. If ``R`` is sufficiently large, the external ray reaches enough close to infinity. - - ``pixel_count`` -- long (default: ``500``) side length of image - in number of pixels. + - ``pixel_count`` -- long (default: ``500``); side length of image + in number of pixels - - ``image_width`` -- double (default: ``4``) width of the image - in the complex plane. + - ``image_width`` -- double (default: ``4``); width of the image + in the complex plane - - ``prec`` -- long (default: ``300``) specifies the bits of + - ``prec`` -- long (default: ``300``); specifies the bits of precision used by the Complex Field when using Newton's method to compute - points on the external ray. + points on the external ray - OUTPUT: - - List of tuples of Real Interval Field Elements. + OUTPUT: list of tuples of Real Interval Field Elements EXAMPLES:: @@ -292,23 +288,21 @@ cpdef fast_external_ray(double theta, long D=30, long S=10, long R=100, cpdef convert_to_pixels(point_list, double x_0, double y_0, double width, long number_of_pixels): r""" - Converts cartesian coordinates to pixels within a specified window. + Convert cartesian coordinates to pixels within a specified window. INPUT: - - ``point_list`` -- list of tuples, points in cartesian coordinates. - - - ``x_0`` -- double, x-coordinate of the center of the image. + - ``point_list`` -- list of tuples; points in cartesian coordinates - - ``y_0`` -- double, y-coordinate of the center of the image. + - ``x_0`` -- double; x-coordinate of the center of the image - - ``width`` -- double, width of visible window in cartesian coordinates. + - ``y_0`` -- double; y-coordinate of the center of the image - - ``number_of_pixels`` -- long, width of image in pixels. + - ``width`` -- double; width of visible window in cartesian coordinates - OUTPUT: + - ``number_of_pixels`` -- long; width of image in pixels - List of tuples of integers representing pixels. + OUTPUT: list of tuples of integers representing pixels EXAMPLES:: @@ -345,13 +339,11 @@ cpdef get_line(start, end): INPUT: - - ``start`` -- tuple, starting point of line. + - ``start`` -- tuple; starting point of line - - ``end`` -- tuple, ending point of line. + - ``end`` -- tuple; ending point of line - OUTPUT: - - List of tuples of integers approximating the line between two pixels. + OUTPUT: list of tuples of integers approximating the line between two pixels EXAMPLES:: @@ -427,38 +419,36 @@ cpdef fast_julia_plot(double c_real, double c_imag, INPUT: - - ``c_real`` -- double, Real part of `c` value that determines Julia set. - - - ``c_imag`` -- double, Imaginary part of `c` value that determines Julia - set. + - ``c_real`` -- double; Real part of `c` value that determines Julia set - - ``x_center`` -- double (default: ``0.0``), Real part of center - point. + - ``c_imag`` -- double; Imaginary part of `c` value that determines Julia + set - - ``y_center`` -- double (default: ``0.0``), Imaginary part of - center point. + - ``x_center`` -- double (default: ``0.0``); real part of center + point - - ``image_width`` -- double (default: ``4.0``), width of image - in the complex plane. + - ``y_center`` -- double (default: ``0.0``); imaginary part of + center point - - ``max_iteration`` -- long (default: ``500``), maximum number of - iterations the map ``Q_c(z)``. + - ``image_width`` -- double (default: ``4.0``); width of image + in the complex plane - - ``pixel_count`` -- long (default: ``500``), side length of - image in number of pixels. + - ``max_iteration`` -- long (default: ``500``); maximum number of + iterations the map ``Q_c(z)`` - - ``level_sep`` -- long (default: ``2``), number of iterations - between each color level. + - ``pixel_count`` -- long (default: ``500``); side length of + image in number of pixels - - ``color_num`` -- long (default: ``40``), number of colors used - to plot image. + - ``level_sep`` -- long (default: ``2``); number of iterations + between each color level - - ``base_color`` -- RGB color (default: ``[50, 50, 50]``), color - used to determine the coloring of set. + - ``color_num`` -- long (default: ``40``); number of colors used + to plot image - OUTPUT: + - ``base_color`` -- RGB color (default: ``[50, 50, 50]``); color + used to determine the coloring of set - 24-bit RGB image of the Julia set in the complex plane. + OUTPUT: 24-bit RGB image of the Julia set in the complex plane EXAMPLES: @@ -548,41 +538,39 @@ cpdef julia_helper(double c_real, double c_imag, double x_center=0, INPUT: - - ``c_real`` -- double, Real part of `c` value that determines Julia set. + - ``c_real`` -- double; Real part of `c` value that determines Julia set - - ``c_imag`` -- double, Imaginary part of `c` value that determines Julia - set. + - ``c_imag`` -- double; Imaginary part of `c` value that determines Julia + set - - ``x_center`` -- double (default: ``0.0``), Real part of center - point. + - ``x_center`` -- double (default: ``0.0``); Real part of center + point - - ``y_center`` -- double (default: ``0.0``), Imaginary part of - center point. + - ``y_center`` -- double (default: ``0.0``); Imaginary part of + center point - - ``image_width`` -- double (default: ``4.0``), width of image in - the complex plane. + - ``image_width`` -- double (default: ``4.0``); width of image in + the complex plane - - ``max_iteration`` -- long (default: ``500``), maximum number of - iterations the map ``Q_c(z)``. + - ``max_iteration`` -- long (default: ``500``); maximum number of + iterations the map ``Q_c(z)`` - - ``pixel_count`` -- long (default: ``500``), side length of - image in number of pixels. + - ``pixel_count`` -- long (default: ``500``); side length of + image in number of pixels - - ``level_sep`` -- long (default: ``2``), number of iterations - between each color level. + - ``level_sep`` -- long (default: ``2``); number of iterations + between each color level - - ``color_num`` -- long (default: ``40``), number of colors used - to plot image. + - ``color_num`` -- long (default: ``40``); number of colors used + to plot image - - ``base_color`` -- RGB color (default: ``[50, 50, 50]``), color - used to determine the coloring of set. + - ``base_color`` -- RGB color (default: ``[50, 50, 50]``); color + used to determine the coloring of set - - ``point_color`` -- RGB color (default: ``[255, 0, 0]``), color - of the point `c` in the Mandelbrot set. + - ``point_color`` -- RGB color (default: ``[255, 0, 0]``); color + of the point `c` in the Mandelbrot set - OUTPUT: - - 24-bit RGB image of the Julia and Mandelbrot sets in the complex plane. + OUTPUT: 24-bit RGB image of the Julia and Mandelbrot sets in the complex plane EXAMPLES: @@ -637,33 +625,31 @@ cpdef polynomial_mandelbrot(f, parameter=None, double x_center=0, INPUT: - - ``f`` -- a one parameter family of polynomial maps defined over the multivariate polynomial ring in - z, c over the Complex field. + - ``f`` -- a one parameter family of polynomial maps defined over the + multivariate polynomial ring in z, c over the Complex field - - ``parameter`` -- designates which variable is used as the parameter. - If no parameter is provided, ``c`` will be used as the parameter. + - ``parameter`` -- designates which variable is used as the parameter + If no parameter is provided, ``c`` will be used as the parameter - - ``x_center`` -- double, real part of the center point in the complex plane. + - ``x_center`` -- double, real part of the center point in the complex plane - ``y_center`` -- double, imaginary part of the center point in the complex - plane. + plane - - ``image_width`` -- double, width of the image in the complex plane. + - ``image_width`` -- double, width of the image in the complex plane - ``max_iteration`` -- long, maximum number of iterations the map `f(z)` - considered. - - - ``pixel_count`` -- long, side length of image in number of pixels. + considered - - ``level_sep`` -- long, number of iterations between each color level. + - ``pixel_count`` -- long, side length of image in number of pixels - - ``color_num`` -- long, number of colors used to plot image. + - ``level_sep`` -- long, number of iterations between each color level - - ``base_color`` -- list, RGB color used to determine the coloring of set. + - ``color_num`` -- long, number of colors used to plot image - OUTPUT: + - ``base_color`` -- list; RGB color used to determine the coloring of set - 24-bit RGB image of a Mandelbrot set in the complex plane. + OUTPUT: 24-bit RGB image of a Mandelbrot set in the complex plane EXAMPLES:: diff --git a/src/sage/dynamics/complex_dynamics/meson.build b/src/sage/dynamics/complex_dynamics/meson.build new file mode 100644 index 00000000000..d3961275d3e --- /dev/null +++ b/src/sage/dynamics/complex_dynamics/meson.build @@ -0,0 +1,19 @@ +py.install_sources( + 'all.py', + 'mandel_julia.py', + subdir: 'sage/dynamics/complex_dynamics', +) + +extension_data = {'mandel_julia_helper' : files('mandel_julia_helper.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/dynamics/complex_dynamics', + install: true, + include_directories: [], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/dynamics/finite_dynamical_system.py b/src/sage/dynamics/finite_dynamical_system.py index 9cf9fc6a51e..d6cfc29feb7 100644 --- a/src/sage/dynamics/finite_dynamical_system.py +++ b/src/sage/dynamics/finite_dynamical_system.py @@ -139,7 +139,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass): (and thus subject to mutation or exhaustion). - ``phi`` -- function, or callable that acts like a - function; the evolution of the DDS. + function; the evolution of the DDS - ``cache_orbits`` -- boolean (default: ``False``); whether or not the orbits should be cached once they @@ -366,15 +366,15 @@ def __init__(self, X, phi, cache_orbits=False, create_tuple=False): EXAMPLES:: sage: D = DiscreteDynamicalSystem([1, 3, 4], lambda x: (3 if x == 4 else 1), create_tuple=True) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem([1, 3, 4], lambda x: (3 if x == 4 else 1), create_tuple=True, is_finite=False) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem(NN, lambda x: (3 if x == 4 else 1)) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem(None, lambda x: (3 if x == 4 else 1)) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem([1, 3, 4], lambda x: x, create_tuple=True) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest """ if create_tuple: X = tuple(X) @@ -705,7 +705,7 @@ class InvertibleDiscreteDynamicalSystem(DiscreteDynamicalSystem): ``X``, as otherwise the input would be exposed. - ``phi`` -- function, or callable that acts like a - function; the evolution of the DDS. + function; the evolution of the DDS - ``inverse`` -- function, or callable that acts like a function; the inverse evolution of the DDS. (A @@ -756,13 +756,13 @@ def __init__(self, X, phi, inverse=None, cache_orbits=False, create_tuple=False) EXAMPLES:: sage: D = DiscreteDynamicalSystem([1, 3, 4], lambda x: x, create_tuple=True, inverse=True) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem([1, 3, 4], lambda x: x, create_tuple=True, is_finite=False, inverse=True) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem(NN, lambda x: x, inverse=True) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest sage: D = DiscreteDynamicalSystem(None, lambda x: x, inverse=True) - sage: TestSuite(D).run(skip ="_test_pickling") # indirect doctest + sage: TestSuite(D).run(skip ='_test_pickling') # indirect doctest """ if create_tuple: X = tuple(X) diff --git a/src/sage/dynamics/meson.build b/src/sage/dynamics/meson.build new file mode 100644 index 00000000000..134cfd1a296 --- /dev/null +++ b/src/sage/dynamics/meson.build @@ -0,0 +1,11 @@ +py.install_sources( + 'all.py', + 'finite_dynamical_system.py', + 'finite_dynamical_system_catalog.py', + 'surface_dynamics_deprecation.py', + subdir: 'sage/dynamics', +) + +subdir('arithmetic_dynamics') +install_subdir('cellular_automata', install_dir: sage_install_dir / 'dynamics') +subdir('complex_dynamics') diff --git a/src/sage/env.py b/src/sage/env.py index 722649ab3da..c6fb123cc72 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -8,10 +8,14 @@ sage: env = {k:v for (k,v) in os.environ.items() if not k.startswith("SAGE_")} sage: from subprocess import check_output - sage: environment = "sage.all" - sage: cmd = f"from {environment} import SAGE_ROOT, SAGE_LOCAL; print((SAGE_ROOT, SAGE_LOCAL))" + sage: module_name = "sage.all" # hide .all import from the linter + sage: cmd = f"from {module_name} import SAGE_ROOT, SAGE_LOCAL;" + sage: cmd += "from os.path import samefile;" + sage: cmd += f"s1 = samefile(SAGE_ROOT, '{SAGE_ROOT}');" + sage: cmd += f"s2 = samefile(SAGE_LOCAL, '{SAGE_LOCAL}');" + sage: cmd += "print(s1 and s2);" sage: out = check_output([sys.executable, "-c", cmd], env=env).decode().strip() # long time - sage: out == repr((SAGE_ROOT, SAGE_LOCAL)) # long time + sage: out == "True" # long time True AUTHORS: @@ -30,7 +34,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from typing import List, Optional +from typing import Optional import sage import os import socket @@ -74,17 +78,15 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st INPUT: - - ``key`` -- string. + - ``key`` -- string - - ``fallbacks`` -- tuple containing ``str`` or ``None`` values. + - ``fallbacks`` -- tuple containing ``str`` or ``None`` values - - ``force`` -- boolean (default: ``False``). If + - ``force`` -- boolean (default: ``False``); if ``True``, skip the environment variable and only use the - fallbacks. + fallbacks - OUTPUT: - - The value of the environment variable or its fallbacks. + OUTPUT: the value of the environment variable or its fallbacks EXAMPLES:: @@ -146,7 +148,12 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st import sage_conf value = getattr(sage_conf, key, None) except ImportError: - pass + try: + import sage.config + value = getattr(sage.config, key, None) + except ImportError: + pass + # Try all fallbacks in order as long as we don't have a value for f in fallbacks: if value is not None: @@ -281,7 +288,7 @@ def sage_include_directories(use_sources=False): INPUT: - - ``use_sources`` -- (default: ``False``) a boolean + - ``use_sources`` -- boolean (default: ``False``) OUTPUT: @@ -296,7 +303,7 @@ def sage_include_directories(use_sources=False): sage: import sage.env sage: sage.env.sage_include_directories() ['...', - '.../numpy/core/include', + '.../numpy/...core/include', '.../include/python...'] To check that C/C++ files are correctly found, we verify that we can @@ -334,7 +341,7 @@ def get_cblas_pc_module_name() -> str: """ import pkgconfig cblas_pc_modules = CBLAS_PC_MODULES.split(':') - return next((blas_lib for blas_lib in cblas_pc_modules if pkgconfig.exists(blas_lib))) + return next(blas_lib for blas_lib in cblas_pc_modules if pkgconfig.exists(blas_lib)) default_required_modules = ('fflas-ffpack', 'givaro', 'gsl', 'linbox', 'Singular', @@ -344,8 +351,7 @@ def get_cblas_pc_module_name() -> str: default_optional_modules = ('lapack',) -def cython_aliases(required_modules=None, - optional_modules=None): +def cython_aliases(required_modules=None, optional_modules=None): """ Return the aliases for compiling Cython code. These aliases are macros which can occur in ``# distutils`` headers. @@ -353,10 +359,10 @@ def cython_aliases(required_modules=None, INPUT: - ``required_modules`` -- (default: taken from ``default_required_modules``) - iterable of ``str`` values. + iterable of string values - ``optional_modules`` -- (default: taken from ``default_optional_modules``) - iterable of ``str`` values. + iterable of string values EXAMPLES:: @@ -432,9 +438,9 @@ def cython_aliases(required_modules=None, else: continue aliases["ECL_CFLAGS"] = list(filter(lambda s: not s.startswith('-I'), ecl_cflags)) - aliases["ECL_INCDIR"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-I'), ecl_cflags))) - aliases["ECL_LIBDIR"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-L'), ecl_libs))) - aliases["ECL_LIBRARIES"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-l'), ecl_libs))) + aliases["ECL_INCDIR"] = [s[2:] for s in filter(lambda s: s.startswith('-I'), ecl_cflags)] + aliases["ECL_LIBDIR"] = [s[2:] for s in filter(lambda s: s.startswith('-L'), ecl_libs)] + aliases["ECL_LIBRARIES"] = [s[2:] for s in filter(lambda s: s.startswith('-l'), ecl_libs)] aliases["ECL_LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l', '-L')), ecl_libs)) continue else: diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 9d2db75be3d..89c34b1f0fc 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -475,9 +475,9 @@ def fast_callable(x, domain=None, vars=None, x = x.function(*vars) if vars is None: - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing - if is_PolynomialRing(x.parent()) or is_MPolynomialRing(x.parent()): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base + if isinstance(x.parent(), PolynomialRing_general) or isinstance(x.parent(), MPolynomialRing_base): vars = x.parent().variable_names() else: # constant @@ -506,16 +506,16 @@ def _builder_and_stream(vars, domain): - ``domain`` -- a Sage parent or Python type or ``None``; if non-``None``, all arithmetic is done in that domain - OUTPUT: A :class:`Wrapper`, an class:`InstructionStream` + OUTPUT: a :class:`Wrapper`, an class:`InstructionStream` EXAMPLES:: sage: from sage.ext.fast_callable import _builder_and_stream sage: _builder_and_stream(["x", "y"], ZZ) - (, + (, ) sage: _builder_and_stream(["x", "y"], RR) # needs sage.rings.real_mpfr - (, + (, ) Modularized test with sagemath-categories after :issue:`35095`, which has @@ -526,7 +526,7 @@ def _builder_and_stream(vars, domain): sage: domain = RDF sage: from sage.structure.element import Element as domain sage: _builder_and_stream(["x", "y"], domain) - (, + (, ) """ if isinstance(domain, sage.rings.abc.RealField): @@ -1607,7 +1607,6 @@ cpdef _expression_binop_helper(s, o, op): add(v_0, v_1) sage: _expression_binop_helper(y, x, operator.add) # needs sage.symbolic add(v_1, v_0) - """ # The Cython way of handling operator overloading on cdef classes # (which is inherited from Python) is quite annoying. Inside the @@ -1805,7 +1804,7 @@ cpdef generate_code(Expression expr, InstructionStream stream): sage: instr_stream.instr('return') sage: v = Wrapper_py(instr_stream.get_current()) sage: type(v) - + sage: v(7) 8*pi + 56 @@ -2068,12 +2067,12 @@ cdef class InstructionStream: INPUT: - - ``metadata`` -- The ``metadata_by_opname`` from a wrapper module + - ``metadata`` -- the ``metadata_by_opname`` from a wrapper module - - ``n_args`` -- The number of arguments accessible by the generated code + - ``n_args`` -- the number of arguments accessible by the generated code (this is just passed to the wrapper class) - - ``domain`` -- The domain of interpretation (this is just passed to the + - ``domain`` -- the domain of interpretation (this is just passed to the wrapper class) EXAMPLES:: @@ -2394,14 +2393,14 @@ class CompilerInstrSpec(): The parameter list is a list of strings. Each string is one of the following: - - ``'args'`` -- The instruction argument refers to an input argument of the - wrapper class; it is just appended to the code. + - ``'args'`` -- the instruction argument refers to an input argument of the + wrapper class; it is just appended to the code - - ``'constants'``, ``'py_constants'`` -- The instruction argument is a value; the + - ``'constants'``, ``'py_constants'`` -- the instruction argument is a value; the value is added to the corresponding list (if it's not already there) and the index is appended to the code. - - ``'n_inputs'``, ``'n_outputs'`` -- The instruction actually takes a variable + - ``'n_inputs'``, ``'n_outputs'`` -- the instruction actually takes a variable number of inputs or outputs (the ``n_inputs`` and ``n_outputs`` attributes of this instruction are ignored). The instruction argument specifies the number of inputs or outputs (respectively); it is just appended to the @@ -2655,7 +2654,6 @@ class FastCallableFloatWrapper: ... ValueError: complex fast-callable function result 1.0*I for arguments (-1,) - """ def __init__(self, ff, imag_tol): r""" @@ -2668,13 +2666,13 @@ class FastCallableFloatWrapper: with :func:`fast_callable`. - ``imag_tol`` -- float; how big of an imaginary part we're willing - to ignore before raising an error. + to ignore before raising an error OUTPUT: An instance of :class:`FastCallableFloatWrapper` that can be called just like ``ff``, but that always returns a :class:`float` - if no error is raised. A :class:`ValueError` is raised if the + if no error is raised. A :exc:`ValueError` is raised if the imaginary part of the result exceeds ``imag_tol``. EXAMPLES: @@ -2695,7 +2693,6 @@ class FastCallableFloatWrapper: ... ValueError: complex fast-callable function result 1e-09*I for arguments (1.00000000000000e-9*I,) - """ self._ff = ff self._imag_tol = imag_tol @@ -2706,7 +2703,7 @@ class FastCallableFloatWrapper: TESTS: - Evaluation either returns a :class:`float`, or raises a :class:`ValueError`:: + Evaluation either returns a :class:`float`, or raises a :exc:`ValueError`:: sage: # needs sage.symbolic sage: from sage.ext.fast_callable import FastCallableFloatWrapper @@ -2719,7 +2716,6 @@ class FastCallableFloatWrapper: ....: result = float(0) sage: type(result) is float True - """ z = self._ff(*args) diff --git a/src/sage/ext/fast_eval.pyx b/src/sage/ext/fast_eval.pyx index 3db7d6fa1dc..cd14c0b0893 100644 --- a/src/sage/ext/fast_eval.pyx +++ b/src/sage/ext/fast_eval.pyx @@ -43,7 +43,7 @@ def fast_float(f, *vars, expect_one_var=False): INPUT: - - ``f`` -- an expression + - ``f`` -- an expression - ``vars`` -- the names of the arguments - ``expect_one_var`` -- don't give deprecation warning if ``vars`` is omitted, as long as expression has only one var diff --git a/src/sage/ext/interpreters/meson.build b/src/sage/ext/interpreters/meson.build new file mode 100644 index 00000000000..f965ce83da0 --- /dev/null +++ b/src/sage/ext/interpreters/meson.build @@ -0,0 +1,72 @@ + +interpreters = custom_target( + 'sage.ext.interpreters', + output: [ + 'all.py', + 'wrapper_cc.pxd', + 'wrapper_cdf.pxd', + 'wrapper_el.pxd', + 'wrapper_py.pxd', + 'wrapper_rdf.pxd', + 'wrapper_rr.pxd', + 'wrapper_cc.pyx', + 'interp_cc.c', + 'wrapper_cdf.pyx', + 'interp_cdf.c', + 'wrapper_el.pyx', + 'interp_el.c', + 'wrapper_py.pyx', + 'interp_py.c', + 'wrapper_rdf.pyx', + 'interp_rdf.c', + 'wrapper_rr.pyx', + 'interp_rr.c', + '__init__.py', + ], + input: '../../../sage_setup/autogen/interpreters/internal/__init__.py', + command: ['../../../sage_setup/autogen/interpreters/__main__.py', '@OUTDIR@'], + # Manually install the generated files instead of using install_sources + # this is a workaround for https://github.com/mesonbuild/meson/issues/7372 + install: true, + install_dir: py.get_install_dir() / 'sage/ext/interpreters', + install_tag: 'python-runtime', +) + +# Use this once https://github.com/mesonbuild/meson/issues/7372 is fixed +#foreach file : interpreters.to_list() +# py.install_sources( +# file.full_path(), +# subdir : 'sage/ext/interpreters' +# ) +#endforeach + +extension_data = { + 'wrapper_cc' : interpreters[7], + 'wrapper_cdf' : interpreters[9], + 'wrapper_el' : interpreters[11], + 'wrapper_py' : interpreters[13], + 'wrapper_rdf' : interpreters[15], + 'wrapper_rr' : interpreters[17], +} + +interpreters_dep = declare_dependency( + include_directories: include_directories('.'), + sources: [ + interpreters[1], + interpreters[2], + interpreters[3], + interpreters[4], + interpreters[5], + ], +) + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/ext/interpreters', + install: true, + include_directories: [inc_cpython, inc_ext, inc_rings, inc_src], + dependencies: [py_dep, cypari2, cysignals, gmp, gsl, mpc, mpfr, pari], + ) +endforeach diff --git a/src/sage/ext/memory.pyx b/src/sage/ext/memory.pyx index b5d9e422410..76f51623d96 100644 --- a/src/sage/ext/memory.pyx +++ b/src/sage/ext/memory.pyx @@ -44,7 +44,7 @@ cdef extern from "Python.h": cdef void alloc_error(size_t size) noexcept nogil: """ - Jump back to ``sig_on()``, raising a :class:`MemoryError`. + Jump back to ``sig_on()``, raising a :exc:`MemoryError`. """ with gil: PyErr_Format(MemoryError, "failed to allocate %zu bytes", size) diff --git a/src/sage/ext/meson.build b/src/sage/ext/meson.build new file mode 100644 index 00000000000..73d0e85101d --- /dev/null +++ b/src/sage/ext/meson.build @@ -0,0 +1,30 @@ +py.install_sources( + 'all__sagemath_objects.py', + 'ccobject.h', + 'cplusplus.pxd', + 'fast_callable.pxd', + 'fast_eval.pxd', + 'mod_int.h', + 'mod_int.pxd', + 'stdsage.pxd', + subdir: 'sage/ext', +) + +extension_data = { + 'fast_callable' : files('fast_callable.pyx'), + 'fast_eval' : files('fast_eval.pyx'), + 'memory' : files('memory.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/ext', + install: true, + include_directories: [inc_cpython, inc_ext], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +subdir('interpreters') diff --git a/src/sage/ext_data/nbconvert/postprocess.py b/src/sage/ext_data/nbconvert/postprocess.py index f3b208971c9..1774b9e1ca5 100755 --- a/src/sage/ext_data/nbconvert/postprocess.py +++ b/src/sage/ext_data/nbconvert/postprocess.py @@ -19,7 +19,7 @@ file_name = sys.argv[1] - with open(file_name, 'r') as f: + with open(file_name) as f: lines = f.readlines() # states of the parser diff --git a/src/sage/ext_data/pari/simon/ell.gp b/src/sage/ext_data/pari/simon/ell.gp index 663df10a7c3..c330ef59f55 100644 --- a/src/sage/ext_data/pari/simon/ell.gp +++ b/src/sage/ext_data/pari/simon/ell.gp @@ -878,7 +878,7 @@ if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble")); p4 = Delta Note that the case of 4 real roots can only occur if both s and t - are non-zero, otherwise the Sturm sequence is shorter than this one. + are nonzero, otherwise the Sturm sequence is shorter than this one. By Sturm's theorem, the number of roots equals (sign changes in [1, -4, -2*s, t, Delta]) - diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index df76ec9da99..e02015a5710 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -22,26 +22,26 @@ feature:: sage: from sage.features import Executable - sage: Executable(name="sh", executable="sh").is_present() + sage: Executable(name='sh', executable='sh').is_present() FeatureTestResult('sh', True) Here we test whether the grape GAP package is available:: sage: from sage.features.gap import GapPackage - sage: GapPackage("grape", spkg="gap_packages").is_present() # optional - gap_package_grape + sage: GapPackage("grape", spkg='gap_packages').is_present() # optional - gap_package_grape FeatureTestResult('gap_package_grape', True) Note that a :class:`FeatureTestResult` acts like a bool in most contexts:: - sage: if Executable(name="sh", executable="sh").is_present(): "present." + sage: if Executable(name='sh', executable='sh').is_present(): "present." 'present.' When one wants to raise an error if the feature is not available, one can use the ``require`` method:: - sage: Executable(name="sh", executable="sh").require() + sage: Executable(name='sh', executable='sh').require() - sage: Executable(name="random", executable="randomOochoz6x", spkg="random", url="http://rand.om").require() # optional - sage_spkg + sage: Executable(name='random', executable='randomOochoz6x', spkg='random', url='http://rand.om').require() # optional - sage_spkg Traceback (most recent call last): ... FeatureNotPresentError: random is not available. @@ -110,28 +110,28 @@ def __classcall__(cls, *args, **options): class Feature(TrivialUniqueRepresentation): r""" - A feature of the runtime environment + A feature of the runtime environment. INPUT: - - ``name`` -- (string) name of the feature; this should be suitable as an optional tag + - ``name`` -- string; name of the feature. This should be suitable as an optional tag for the Sage doctester, i.e., lowercase alphanumeric with underscores (``_``) allowed; features that correspond to Python modules/packages may use periods (``.``) - - ``spkg`` -- (string) name of the SPKG providing the feature + - ``spkg`` -- string; name of the SPKG providing the feature - - ``description`` -- (string) optional; plain English description of the feature + - ``description`` -- string (optional); plain English description of the feature - ``url`` -- a URL for the upstream package providing the feature - - ``type`` -- (string) one of ``'standard'``, ``'optional'`` (default), ``'experimental'`` + - ``type`` -- string; one of ``'standard'``, ``'optional'`` (default), ``'experimental'`` Overwrite :meth:`_is_present` to add feature checks. EXAMPLES:: sage: from sage.features.gap import GapPackage - sage: GapPackage("grape", spkg="gap_packages") # indirect doctest + sage: GapPackage("grape", spkg='gap_packages') # indirect doctest Feature('gap_package_grape') For efficiency, features are unique:: @@ -145,7 +145,7 @@ def __init__(self, name, spkg=None, url=None, description=None, type='optional') sage: from sage.features import Feature sage: from sage.features.gap import GapPackage - sage: isinstance(GapPackage("grape", spkg="gap_packages"), Feature) # indirect doctest + sage: isinstance(GapPackage("grape", spkg='gap_packages'), Feature) # indirect doctest True """ self.name = name @@ -182,9 +182,9 @@ def is_present(self): EXAMPLES:: sage: from sage.features.gap import GapPackage - sage: GapPackage("grape", spkg="gap_packages").is_present() # optional - gap_package_grape + sage: GapPackage("grape", spkg='gap_packages').is_present() # optional - gap_package_grape FeatureTestResult('gap_package_grape', True) - sage: GapPackage("NOT_A_PACKAGE", spkg="gap_packages").is_present() + sage: GapPackage("NOT_A_PACKAGE", spkg='gap_packages').is_present() FeatureTestResult('gap_package_NOT_A_PACKAGE', False) The result is cached:: @@ -229,7 +229,7 @@ def _is_present(self): def require(self): r""" - Raise a :class:`FeatureNotPresentError` if the feature is not present. + Raise a :exc:`FeatureNotPresentError` if the feature is not present. EXAMPLES:: @@ -253,7 +253,6 @@ def __repr__(self): sage: from sage.features.gap import GapPackage sage: GapPackage("grape") # indirect doctest Feature('gap_package_grape') - """ description = f'{self.name!r}: {self.description}' if self.description else f'{self.name!r}' return f'Feature({description})' @@ -282,14 +281,12 @@ def resolution(self): Return a suggestion on how to make :meth:`is_present` pass if it did not pass. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: sage: from sage.features import Executable - sage: Executable(name="CSDP", spkg="csdp", executable="theta", url="https://github.com/dimpase/csdp").resolution() # optional - sage_spkg + sage: Executable(name='CSDP', spkg='csdp', executable='theta', url='https://github.com/dimpase/csdp').resolution() # optional - sage_spkg '...To install CSDP...you can try to run...sage -i csdp...Further installation instructions might be available at https://github.com/dimpase/csdp.' """ if self._hidden: @@ -432,7 +429,7 @@ class FeatureNotPresentError(RuntimeError): ....: def _is_present(self): ....: return False - sage: Missing(name="missing").require() + sage: Missing(name='missing').require() Traceback (most recent call last): ... FeatureNotPresentError: missing is not available. @@ -470,7 +467,7 @@ def __str__(self): return "\n".join(lines) -class FeatureTestResult(): +class FeatureTestResult: r""" The result of a :meth:`Feature.is_present` call. @@ -498,12 +495,12 @@ class FeatureTestResult(): default you need explicitly set ``resolution`` to a string:: sage: from sage.features import FeatureTestResult - sage: package = GapPackage("NOT_A_PACKAGE", spkg="no_package") + sage: package = GapPackage("NOT_A_PACKAGE", spkg='no_package') sage: str(FeatureTestResult(package, True).resolution) # optional - sage_spkg '...To install gap_package_NOT_A_PACKAGE...you can try to run...sage -i no_package...' sage: str(FeatureTestResult(package, False).resolution) # optional - sage_spkg '...To install gap_package_NOT_A_PACKAGE...you can try to run...sage -i no_package...' - sage: FeatureTestResult(package, False, resolution="rtm").resolution + sage: FeatureTestResult(package, False, resolution='rtm').resolution 'rtm' """ def __init__(self, feature, is_present, reason=None, resolution=None): @@ -511,7 +508,7 @@ def __init__(self, feature, is_present, reason=None, resolution=None): TESTS:: sage: from sage.features import Executable, FeatureTestResult - sage: isinstance(Executable(name="sh", executable="sh").is_present(), FeatureTestResult) + sage: isinstance(Executable(name='sh', executable='sh').is_present(), FeatureTestResult) True """ self.feature = feature @@ -604,9 +601,9 @@ class FileFeature(Feature): True To work with the file described by the feature, use the method :meth:`absolute_filename`. - A :class:`FeatureNotPresentError` is raised if the file cannot be found:: + A :exc:`FeatureNotPresentError` is raised if the file cannot be found:: - sage: Executable(name="does-not-exist", executable="does-not-exist-xxxxyxyyxyy").absolute_filename() + sage: Executable(name='does-not-exist', executable='does-not-exist-xxxxyxyyxyy').absolute_filename() Traceback (most recent call last): ... sage.features.FeatureNotPresentError: does-not-exist is not available. @@ -616,7 +613,7 @@ class FileFeature(Feature): the presence of the file at run time. This is inherited from the base class :class:`Feature`:: - sage: Executable(name="sh", executable="sh").is_present() + sage: Executable(name='sh', executable='sh').is_present() FeatureTestResult('sh', True) """ def _is_present(self): @@ -626,7 +623,7 @@ def _is_present(self): EXAMPLES:: sage: from sage.features import StaticFile - sage: StaticFile(name="no_such_file", filename="KaT1aihu", spkg="some_spkg", url="http://rand.om").is_present() + sage: StaticFile(name='no_such_file', filename='KaT1aihu', spkg='some_spkg', url='http://rand.om').is_present() FeatureTestResult('no_such_file', False) """ try: @@ -644,7 +641,7 @@ def absolute_filename(self) -> str: TESTS:: sage: from sage.features import FileFeature - sage: FileFeature(name="abstract_file").absolute_filename() + sage: FileFeature(name='abstract_file').absolute_filename() Traceback (most recent call last): ... NotImplementedError @@ -675,9 +672,9 @@ class Executable(FileFeature): EXAMPLES:: sage: from sage.features import Executable - sage: Executable(name="sh", executable="sh").is_present() + sage: Executable(name='sh', executable='sh').is_present() FeatureTestResult('sh', True) - sage: Executable(name="does-not-exist", executable="does-not-exist-xxxxyxyyxyy").is_present() + sage: Executable(name='does-not-exist', executable='does-not-exist-xxxxyxyyxyy').is_present() FeatureTestResult('does-not-exist', False) """ def __init__(self, name, executable, **kwds): @@ -685,7 +682,7 @@ def __init__(self, name, executable, **kwds): TESTS:: sage: from sage.features import Executable - sage: isinstance(Executable(name="sh", executable="sh"), Executable) + sage: isinstance(Executable(name='sh', executable='sh'), Executable) True """ Feature.__init__(self, name, **kwds) @@ -700,7 +697,7 @@ def _is_present(self): EXAMPLES:: sage: from sage.features import Executable - sage: Executable(name="sh", executable="sh").is_present() + sage: Executable(name='sh', executable='sh').is_present() FeatureTestResult('sh', True) """ result = FileFeature._is_present(self) @@ -721,7 +718,7 @@ def is_functional(self): The function returns ``True`` unless explicitly overwritten:: sage: from sage.features import Executable - sage: Executable(name="sh", executable="sh").is_functional() + sage: Executable(name='sh', executable='sh').is_functional() FeatureTestResult('sh', True) """ return FeatureTestResult(self, True) @@ -733,12 +730,12 @@ def absolute_filename(self) -> str: EXAMPLES:: sage: from sage.features import Executable - sage: Executable(name="sh", executable="sh").absolute_filename() + sage: Executable(name='sh', executable='sh').absolute_filename() '/...bin/sh' - A :class:`FeatureNotPresentError` is raised if the file cannot be found:: + A :exc:`FeatureNotPresentError` is raised if the file cannot be found:: - sage: Executable(name="does-not-exist", executable="does-not-exist-xxxxyxyyxyy").absolute_filename() + sage: Executable(name='does-not-exist', executable='does-not-exist-xxxxyxyyxyy').absolute_filename() Traceback (most recent call last): ... sage.features.FeatureNotPresentError: does-not-exist is not available. @@ -770,9 +767,9 @@ class StaticFile(FileFeature): EXAMPLES:: sage: from sage.features import StaticFile - sage: StaticFile(name="no_such_file", filename="KaT1aihu", # optional - sage_spkg - ....: search_path="/", spkg="some_spkg", - ....: url="http://rand.om").require() + sage: StaticFile(name='no_such_file', filename='KaT1aihu', # optional - sage_spkg + ....: search_path='/', spkg='some_spkg', + ....: url='http://rand.om').require() Traceback (most recent call last): ... FeatureNotPresentError: no_such_file is not available. @@ -785,15 +782,14 @@ def __init__(self, name, filename, *, search_path=None, type='optional', **kwds) TESTS:: sage: from sage.features import StaticFile - sage: StaticFile(name="null", filename="null", search_path="/dev") + sage: StaticFile(name='null', filename='null', search_path='/dev') Feature('null') - sage: sh = StaticFile(name="shell", filename="sh", + sage: sh = StaticFile(name='shell', filename='sh', ....: search_path=("/dev", "/bin", "/usr")) sage: sh Feature('shell') sage: sh.absolute_filename() '/bin/sh' - """ Feature.__init__(self, name, type=type, **kwds) self.filename = filename @@ -816,16 +812,16 @@ def absolute_filename(self) -> str: sage: file_path = os.path.join(dir_with_file, "file.txt") sage: open(file_path, 'a').close() # make sure the file exists sage: search_path = ( '/foo/bar', dir_with_file ) # file is somewhere in the search path - sage: feature = StaticFile(name="file", filename="file.txt", search_path=search_path) + sage: feature = StaticFile(name='file', filename='file.txt', search_path=search_path) sage: feature.absolute_filename() == file_path True - A :class:`FeatureNotPresentError` is raised if the file cannot be found:: + A :exc:`FeatureNotPresentError` is raised if the file cannot be found:: sage: from sage.features import StaticFile - sage: StaticFile(name="no_such_file", filename="KaT1aihu",\ - search_path=(), spkg="some_spkg",\ - url="http://rand.om").absolute_filename() # optional - sage_spkg + sage: StaticFile(name='no_such_file', filename='KaT1aihu',\ + search_path=(), spkg='some_spkg',\ + url='http://rand.om').absolute_filename() # optional - sage_spkg Traceback (most recent call last): ... FeatureNotPresentError: no_such_file is not available. @@ -859,8 +855,8 @@ class CythonFeature(Feature): ....: assert fabs(-1) == 1 ....: ''' sage: fabs = CythonFeature("fabs", test_code=fabs_test_code, # needs sage.misc.cython - ....: spkg="gcc", url="https://gnu.org", - ....: type="standard") + ....: spkg='gcc', url='https://gnu.org', + ....: type='standard') sage: fabs.is_present() # needs sage.misc.cython FeatureTestResult('fabs', True) @@ -924,7 +920,7 @@ def _is_present(self): from distutils.errors import CCompilerError except ImportError: CCompilerError = () - with open(tmp_filename(ext=".pyx"), 'w') as pyx: + with open(tmp_filename(ext='.pyx'), 'w') as pyx: pyx.write(self.test_code) try: from sage.misc.cython import cython_import diff --git a/src/sage/features/all.py b/src/sage/features/all.py index a53d095c596..14d2480d520 100644 --- a/src/sage/features/all.py +++ b/src/sage/features/all.py @@ -50,7 +50,7 @@ def module_feature(module_name): - ``module_name`` -- string - OUTPUT: a :class:`Feature` or ``None``. + OUTPUT: a :class:`Feature` or ``None`` EXAMPLES:: @@ -93,7 +93,7 @@ def name_feature(name, toplevel=None): - ``toplevel`` -- a module or other namespace - OUTPUT: a :class:`Feature` or ``None``. + OUTPUT: a :class:`Feature` or ``None`` EXAMPLES:: diff --git a/src/sage/features/bliss.py b/src/sage/features/bliss.py index 0bc812a76bc..d905ff13d5f 100644 --- a/src/sage/features/bliss.py +++ b/src/sage/features/bliss.py @@ -54,8 +54,8 @@ def __init__(self): Feature('libbliss') """ CythonFeature.__init__(self, "libbliss", test_code=TEST_CODE, - spkg="bliss", - url="http://www.tcs.hut.fi/Software/bliss/") + spkg='bliss', + url='http://www.tcs.hut.fi/Software/bliss/') class Bliss(JoinFeature): @@ -77,8 +77,8 @@ def __init__(self): Feature('bliss') """ JoinFeature.__init__(self, "bliss", - [PythonModule("sage.graphs.bliss", spkg="sagemath_bliss", - url="http://www.tcs.hut.fi/Software/bliss/")]) + [PythonModule("sage.graphs.bliss", spkg='sagemath_bliss', + url='http://www.tcs.hut.fi/Software/bliss/')]) def all_features(): diff --git a/src/sage/features/cddlib.py b/src/sage/features/cddlib.py index 24b67ef9f8e..8e657ca0020 100644 --- a/src/sage/features/cddlib.py +++ b/src/sage/features/cddlib.py @@ -34,5 +34,5 @@ def __init__(self, name='cddexec_gmp'): sage: isinstance(CddExecutable(), CddExecutable) True """ - Executable.__init__(self, name=name, executable=name, spkg="cddlib", - url="https://github.com/cddlib/cddlib", type="standard") + Executable.__init__(self, name=name, executable=name, spkg='cddlib', + url='https://github.com/cddlib/cddlib', type='standard') diff --git a/src/sage/features/coxeter3.py b/src/sage/features/coxeter3.py index 97e153b18a3..bf7b476d50c 100644 --- a/src/sage/features/coxeter3.py +++ b/src/sage/features/coxeter3.py @@ -38,7 +38,7 @@ def __init__(self): """ JoinFeature.__init__(self, "coxeter3", [PythonModule("sage.libs.coxeter3.coxeter", - spkg="sagemath_coxeter3")]) + spkg='sagemath_coxeter3')]) def all_features(): diff --git a/src/sage/features/csdp.py b/src/sage/features/csdp.py index 866ca1c21d1..733e8b6ffdf 100644 --- a/src/sage/features/csdp.py +++ b/src/sage/features/csdp.py @@ -41,8 +41,8 @@ def __init__(self): sage: isinstance(CSDP(), CSDP) True """ - Executable.__init__(self, name="csdp", spkg="csdp", executable="theta", - url="https://github.com/dimpase/csdp") + Executable.__init__(self, name='csdp', spkg='csdp', executable='theta', + url='https://github.com/dimpase/csdp') def is_functional(self): r""" diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index 7a05270532c..9d070d932ed 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -48,7 +48,7 @@ class DatabaseCremona(StaticFile): INPUT: - ``name`` -- either ``'cremona'`` (the default) for the full large - database or ``'cremona_mini'`` for the small database. + database or ``'cremona_mini'`` for the small database EXAMPLES:: @@ -58,7 +58,7 @@ class DatabaseCremona(StaticFile): sage: DatabaseCremona().is_present() # optional - database_cremona_ellcurve FeatureTestResult('database_cremona_ellcurve', True) """ - def __init__(self, name="cremona", spkg="database_cremona_ellcurve", type='optional'): + def __init__(self, name='cremona', spkg='database_cremona_ellcurve', type='optional'): r""" TESTS:: @@ -82,7 +82,7 @@ def __init__(self, name="cremona", spkg="database_cremona_ellcurve", type='optio search_path=search_path, spkg=spkg, type=spkg_type, - url="https://github.com/JohnCremona/ecdata", + url='https://github.com/JohnCremona/ecdata', description="Cremona's database of elliptic curves") @@ -111,8 +111,8 @@ def __init__(self): StaticFile.__init__(self, "database_ellcurves", filename='rank0', search_path=search_path, - spkg="elliptic_curves", - type="standard", + spkg='elliptic_curves', + type='standard', description="William Stein's database of interesting curve") @@ -141,8 +141,8 @@ def __init__(self): StaticFile.__init__(self, "database_graphs", filename='graphs.db', search_path=search_path, - spkg="graphs", - type="standard", + spkg='graphs', + type='standard', description="A database of graphs") @@ -168,7 +168,7 @@ def __init__(self): StaticFile.__init__(self, "database_jones_numfield", filename='jones.sobj', search_path=sage_data_path("jones"), - spkg="database_jones_numfield", + spkg='database_jones_numfield', description="John Jones's tables of number fields") @@ -221,7 +221,7 @@ def __init__(self): sage: isinstance(DatabaseMatroids(), DatabaseMatroids) True """ - PythonModule.__init__(self, "matroid_database", spkg="matroid_database") + PythonModule.__init__(self, 'matroid_database', spkg='matroid_database') class DatabaseCubicHecke(PythonModule): diff --git a/src/sage/features/dvipng.py b/src/sage/features/dvipng.py index 66fbee39561..68bcdcb5a04 100644 --- a/src/sage/features/dvipng.py +++ b/src/sage/features/dvipng.py @@ -16,7 +16,7 @@ class dvipng(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``dvipng`` + A :class:`~sage.features.Feature` describing the presence of ``dvipng``. EXAMPLES:: @@ -32,8 +32,8 @@ def __init__(self): sage: isinstance(dvipng(), dvipng) True """ - Executable.__init__(self, "dvipng", executable="dvipng", - url="https://savannah.nongnu.org/projects/dvipng/") + Executable.__init__(self, 'dvipng', executable='dvipng', + url='https://savannah.nongnu.org/projects/dvipng/') def all_features(): diff --git a/src/sage/features/ecm.py b/src/sage/features/ecm.py index 06f4ac10dbd..3bf3e67fc14 100644 --- a/src/sage/features/ecm.py +++ b/src/sage/features/ecm.py @@ -34,8 +34,8 @@ def __init__(self): sage: isinstance(Ecm(), Ecm) True """ - Executable.__init__(self, name="ecm", executable=SAGE_ECMBIN, - spkg="ecm", type="standard") + Executable.__init__(self, name='ecm', executable=SAGE_ECMBIN, + spkg='ecm', type='standard') def all_features(): diff --git a/src/sage/features/ffmpeg.py b/src/sage/features/ffmpeg.py index 366249875d7..0d3ff8e4232 100644 --- a/src/sage/features/ffmpeg.py +++ b/src/sage/features/ffmpeg.py @@ -32,9 +32,9 @@ def __init__(self): sage: isinstance(FFmpeg(), FFmpeg) True """ - Executable.__init__(self, "ffmpeg", executable="ffmpeg", - spkg="ffmpeg", - url="https://www.ffmpeg.org/") + Executable.__init__(self, 'ffmpeg', executable='ffmpeg', + spkg='ffmpeg', + url='https://www.ffmpeg.org/') def is_functional(self): r""" @@ -45,7 +45,6 @@ def is_functional(self): sage: from sage.features.ffmpeg import FFmpeg sage: FFmpeg().is_functional() # optional - ffmpeg FeatureTestResult('ffmpeg', True) - """ # Create the content of 1-pixel png file content = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDATx\x9cc`\x00\x00\x00\x02\x00\x01H\xaf\xa4q\x00\x00\x00\x00IEND\xaeB`\x82' @@ -103,7 +102,7 @@ def is_functional(self): # If an error occurred, return False if result.returncode: return FeatureTestResult(self, False, reason='Running command "{}" ' - 'returned non-zero exit status "{}" with stderr ' + 'returned nonzero exit status "{}" with stderr ' '"{}" and stdout "{}".'.format(result.args, result.returncode, result.stderr.strip(), diff --git a/src/sage/features/four_ti_2.py b/src/sage/features/four_ti_2.py index 655674cbde1..8ae7822bfc3 100644 --- a/src/sage/features/four_ti_2.py +++ b/src/sage/features/four_ti_2.py @@ -23,7 +23,7 @@ def __init__(self, name): Executable.__init__(self, name="4ti2-" + name, executable=SAGE_ENV.get("FOURTITWO_" + name.upper(), None) or name, - spkg="4ti2") + spkg='4ti2') class FourTi2(JoinFeature): diff --git a/src/sage/features/fricas.py b/src/sage/features/fricas.py index d5b7d469207..539b3b027dd 100644 --- a/src/sage/features/fricas.py +++ b/src/sage/features/fricas.py @@ -34,9 +34,9 @@ def __init__(self): sage: isinstance(FriCAS(), FriCAS) True """ - Executable.__init__(self, name="fricas", spkg="fricas", - executable="fricas", - url="https://fricas.github.io") + Executable.__init__(self, name='fricas', spkg='fricas', + executable='fricas', + url='https://fricas.github.io') def is_functional(self): r""" diff --git a/src/sage/features/gap.py b/src/sage/features/gap.py index fdcbceee102..609cb37c263 100644 --- a/src/sage/features/gap.py +++ b/src/sage/features/gap.py @@ -30,7 +30,7 @@ class GapPackage(Feature): EXAMPLES:: sage: from sage.features.gap import GapPackage - sage: GapPackage("grape", spkg="gap_packages") + sage: GapPackage("grape", spkg='gap_packages') Feature('gap_package_grape') """ def __init__(self, package, **kwds): @@ -38,7 +38,7 @@ def __init__(self, package, **kwds): TESTS:: sage: from sage.features.gap import GapPackage - sage: isinstance(GapPackage("grape", spkg="gap_packages"), GapPackage) + sage: isinstance(GapPackage("grape", spkg='gap_packages'), GapPackage) True """ Feature.__init__(self, f"gap_package_{package}", **kwds) @@ -54,7 +54,7 @@ def _is_present(self): EXAMPLES:: sage: from sage.features.gap import GapPackage - sage: GapPackage("grape", spkg="gap_packages")._is_present() # optional - gap_package_grape + sage: GapPackage("grape", spkg='gap_packages')._is_present() # optional - gap_package_grape FeatureTestResult('gap_package_grape', True) """ try: @@ -76,11 +76,12 @@ def _is_present(self): def all_features(): - return [GapPackage("atlasrep", spkg="gap_packages"), - GapPackage("design", spkg="gap_packages"), - GapPackage("grape", spkg="gap_packages"), - GapPackage("guava", spkg="gap_packages"), - GapPackage("hap", spkg="gap_packages"), - GapPackage("polycyclic", spkg="gap_packages"), - GapPackage("qpa", spkg="gap_packages"), - GapPackage("quagroup", spkg="gap_packages")] + return [GapPackage("atlasrep", spkg='gap_packages'), + GapPackage("design", spkg='gap_packages'), + GapPackage("grape", spkg='gap_packages'), + GapPackage("guava", spkg='gap_packages'), + GapPackage("hap", spkg='gap_packages'), + GapPackage("polenta", spkg='gap_packages'), + GapPackage("polycyclic", spkg='gap_packages'), + GapPackage("qpa", spkg='gap_packages'), + GapPackage("quagroup", spkg='gap_packages')] diff --git a/src/sage/features/gfan.py b/src/sage/features/gfan.py index e3545392934..dfc6875c53b 100644 --- a/src/sage/features/gfan.py +++ b/src/sage/features/gfan.py @@ -31,7 +31,7 @@ def __init__(self, cmd=None): name = "gfan" else: name = f"gfan_{cmd}" - Executable.__init__(self, name, executable=name, spkg="gfan", type='standard') + Executable.__init__(self, name, executable=name, spkg='gfan', type='standard') def all_features(): diff --git a/src/sage/features/giac.py b/src/sage/features/giac.py new file mode 100644 index 00000000000..6f9fe2ccfba --- /dev/null +++ b/src/sage/features/giac.py @@ -0,0 +1,30 @@ +# sage_setup: distribution = sagemath-environment +r""" +Feature for testing the presence of ``giac`` +""" + +from . import Executable, FeatureTestResult + +class Giac(Executable): + r""" + A :class:`~sage.features.Feature` describing the presence of :ref:`giac `. + + EXAMPLES:: + + sage: from sage.features.giac import Giac + sage: Giac().is_present() # needs giac + FeatureTestResult('giac', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.giac import Giac + sage: isinstance(Giac(), Giac) + True + """ + Executable.__init__(self, 'giac', executable='giac', + spkg='giac', type='standard') + +def all_features(): + return [Giac()] diff --git a/src/sage/features/graph_generators.py b/src/sage/features/graph_generators.py index 8f384af9ed3..603b2bab7b8 100644 --- a/src/sage/features/graph_generators.py +++ b/src/sage/features/graph_generators.py @@ -40,9 +40,9 @@ def __init__(self): sage: isinstance(Plantri(), Plantri) True """ - Executable.__init__(self, name="plantri", spkg="plantri", - executable="plantri", - url="http://users.cecs.anu.edu.au/~bdm/plantri/") + Executable.__init__(self, name='plantri', spkg='plantri', + executable='plantri', + url='http://users.cecs.anu.edu.au/~bdm/plantri/') def is_functional(self): r""" @@ -87,9 +87,9 @@ def __init__(self): sage: isinstance(Buckygen(), Buckygen) True """ - Executable.__init__(self, name="buckygen", spkg="buckygen", - executable="buckygen", - url="http://caagt.ugent.be/buckygen/") + Executable.__init__(self, name='buckygen', spkg='buckygen', + executable='buckygen', + url='http://caagt.ugent.be/buckygen/') def is_functional(self): r""" @@ -135,9 +135,9 @@ def __init__(self): sage: isinstance(Benzene(), Benzene) True """ - Executable.__init__(self, name="benzene", spkg="benzene", - executable="benzene", - url="http://www.grinvin.org/") + Executable.__init__(self, name='benzene', spkg='benzene', + executable='benzene', + url='http://www.grinvin.org/') def is_functional(self): r""" diff --git a/src/sage/features/graphviz.py b/src/sage/features/graphviz.py index 4e6ae9a6c4a..f8c633eafbf 100644 --- a/src/sage/features/graphviz.py +++ b/src/sage/features/graphviz.py @@ -36,9 +36,9 @@ def __init__(self): sage: isinstance(dot(), dot) True """ - Executable.__init__(self, "dot", executable="dot", - spkg="graphviz", - url="https://www.graphviz.org/") + Executable.__init__(self, 'dot', executable='dot', + spkg='graphviz', + url='https://www.graphviz.org/') class neato(Executable): @@ -59,9 +59,9 @@ def __init__(self): sage: isinstance(neato(), neato) True """ - Executable.__init__(self, "neato", executable="neato", - spkg="graphviz", - url="https://www.graphviz.org/") + Executable.__init__(self, 'neato', executable='neato', + spkg='graphviz', + url='https://www.graphviz.org/') class twopi(Executable): @@ -82,9 +82,9 @@ def __init__(self): sage: isinstance(twopi(), twopi) True """ - Executable.__init__(self, "twopi", executable="twopi", - spkg="graphviz", - url="https://www.graphviz.org/") + Executable.__init__(self, 'twopi', executable='twopi', + spkg='graphviz', + url='https://www.graphviz.org/') class Graphviz(JoinFeature): @@ -107,10 +107,10 @@ def __init__(self): sage: isinstance(Graphviz(), Graphviz) True """ - JoinFeature.__init__(self, "graphviz", + JoinFeature.__init__(self, 'graphviz', [dot(), neato(), twopi()], - spkg="graphviz", - url="https://www.graphviz.org/") + spkg='graphviz', + url='https://www.graphviz.org/') def all_features(): diff --git a/src/sage/features/igraph.py b/src/sage/features/igraph.py index 00d260f2ac7..9bb61c28454 100644 --- a/src/sage/features/igraph.py +++ b/src/sage/features/igraph.py @@ -37,8 +37,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'python_igraph', - [PythonModule('igraph', spkg="python_igraph", - url="http://igraph.org")]) + [PythonModule('igraph', spkg='python_igraph', + url='http://igraph.org')]) def all_features(): return [python_igraph()] diff --git a/src/sage/features/imagemagick.py b/src/sage/features/imagemagick.py index fb273371326..866d0aed95e 100644 --- a/src/sage/features/imagemagick.py +++ b/src/sage/features/imagemagick.py @@ -39,11 +39,11 @@ def __init__(self): sage: isinstance(Magick(), Magick) True """ - Executable.__init__(self, "magick", executable="magick") + Executable.__init__(self, 'magick', executable='magick') try: _ = self.absolute_filename() except RuntimeError: - Executable.__init__(self, "magick", executable="convert") + Executable.__init__(self, 'magick', executable='convert') def is_functional(self): r""" @@ -54,7 +54,6 @@ def is_functional(self): sage: from sage.features.imagemagick import Magick sage: Magick().is_functional() # optional - imagemagick FeatureTestResult('magick', True) - """ # Create the content of 1-pixel png file content = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDATx\x9cc`\x00\x00\x00\x02\x00\x01H\xaf\xa4q\x00\x00\x00\x00IEND\xaeB`\x82' @@ -96,7 +95,7 @@ def is_functional(self): # If an error occurred, return False if result.returncode: return FeatureTestResult(self, False, reason='Running command "{}" ' - 'returned non-zero exit status "{}" with stderr ' + 'returned nonzero exit status "{}" with stderr ' '"{}" and stdout "{}".'.format(result.args, result.returncode, result.stderr.strip(), @@ -130,10 +129,10 @@ def __init__(self): sage: isinstance(ImageMagick(), ImageMagick) True """ - JoinFeature.__init__(self, "imagemagick", + JoinFeature.__init__(self, 'imagemagick', [Magick()], - spkg="imagemagick", - url="https://www.imagemagick.org/") + spkg='imagemagick', + url='https://www.imagemagick.org/') def all_features(): return [ImageMagick()] diff --git a/src/sage/features/interfaces.py b/src/sage/features/interfaces.py index 6d5249ab443..7bb061270fc 100644 --- a/src/sage/features/interfaces.py +++ b/src/sage/features/interfaces.py @@ -91,6 +91,23 @@ def _is_present(self): reason=f"Interface {interface} is not functional: {exception}") +class Mathics(InterfaceFeature): + r""" + A :class:`~sage.features.Feature` describing whether :class:`sage.interfaces.mathics.Mathics` + is present and functional. + + EXAMPLES:: + + sage: from sage.features.interfaces import Mathics + sage: Mathics().is_present() # not tested + FeatureTestResult('mathics', False) + """ + + @staticmethod + def __classcall__(cls): + return InterfaceFeature.__classcall__(cls, 'mathics', 'sage.interfaces.mathics') + + # The following are provided by external software only (no SPKG) class Magma(InterfaceFeature): @@ -223,6 +240,7 @@ def all_features(): [Feature('magma'), Feature('matlab'), Feature('mathematica'), + Feature('mathics'), Feature('maple'), Feature('macaulay2'), Feature('octave'), @@ -231,6 +249,7 @@ def all_features(): return [Magma(), Matlab(), Mathematica(), + Mathics(), Maple(), Macaulay2(), Octave(), diff --git a/src/sage/features/jmol.py b/src/sage/features/jmol.py index feb293bd8db..cf5780094bd 100644 --- a/src/sage/features/jmol.py +++ b/src/sage/features/jmol.py @@ -32,11 +32,11 @@ def __init__(self): ) StaticFile.__init__( - self, name="jmol", - filename="JmolData.jar", + self, name='jmol', + filename='JmolData.jar', search_path=jmol_search_path, - spkg="jmol", - type="standard", + spkg='jmol', + type='optional', description="Java viewer for chemical structures in 3D") diff --git a/src/sage/features/kenzo.py b/src/sage/features/kenzo.py index 39b8dd9a936..b5d83b06972 100644 --- a/src/sage/features/kenzo.py +++ b/src/sage/features/kenzo.py @@ -36,8 +36,8 @@ def __init__(self): sage: isinstance(Kenzo(), Kenzo) True """ - Feature.__init__(self, name="kenzo", spkg="kenzo", - url="https://github.com/miguelmarco/kenzo/") + Feature.__init__(self, name='kenzo', spkg='kenzo', + url='https://github.com/miguelmarco/kenzo/') def _is_present(self): r""" diff --git a/src/sage/features/latex.py b/src/sage/features/latex.py index 6f366ff86f6..271800beece 100644 --- a/src/sage/features/latex.py +++ b/src/sage/features/latex.py @@ -24,7 +24,7 @@ class LaTeX(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``latex`` + A :class:`~sage.features.Feature` describing the presence of ``latex``. EXAMPLES:: @@ -59,7 +59,7 @@ def is_functional(self): sage: print(result.reason) # not tested Running latex on a sample file (with command='latex -interaction=nonstopmode tmp_wmpos8ak.tex') - returned non-zero exit status='1' with stderr='' + returned nonzero exit status='1' with stderr='' and stdout='This is pdfTeX, ... Runaway argument? @@ -95,7 +95,7 @@ def is_functional(self): return FeatureTestResult(self, True) else: return FeatureTestResult(self, False, reason="Running latex on " - "a sample file (with command='{}') returned non-zero " + "a sample file (with command='{}') returned nonzero " "exit status='{}' with stderr='{}' " "and stdout='{}'".format(result.args, result.returncode, @@ -105,7 +105,7 @@ def is_functional(self): class latex(LaTeX): r""" - A :class:`~sage.features.Feature` describing the presence of ``latex`` + A :class:`~sage.features.Feature` describing the presence of ``latex``. EXAMPLES:: @@ -126,7 +126,7 @@ def __init__(self): class pdflatex(LaTeX): r""" - A :class:`~sage.features.Feature` describing the presence of ``pdflatex`` + A :class:`~sage.features.Feature` describing the presence of ``pdflatex``. EXAMPLES:: @@ -147,7 +147,7 @@ def __init__(self): class xelatex(LaTeX): r""" - A :class:`~sage.features.Feature` describing the presence of ``xelatex`` + A :class:`~sage.features.Feature` describing the presence of ``xelatex``. EXAMPLES:: @@ -168,7 +168,7 @@ def __init__(self): class lualatex(LaTeX): r""" - A :class:`~sage.features.Feature` describing the presence of ``lualatex`` + A :class:`~sage.features.Feature` describing the presence of ``lualatex``. EXAMPLES:: @@ -189,7 +189,7 @@ def __init__(self): class dvips(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``dvips`` + A :class:`~sage.features.Feature` describing the presence of ``dvips``. EXAMPLES:: @@ -205,12 +205,12 @@ def __init__(self): sage: isinstance(dvips(), dvips) True """ - Executable.__init__(self, "dvips", executable="dvips", - url="https://tug.org/texinfohtml/dvips.html") + Executable.__init__(self, 'dvips', executable='dvips', + url='https://tug.org/texinfohtml/dvips.html') class TeXFile(StaticFile): r""" - A :class:`sage.features.Feature` describing the presence of a TeX file + A :class:`sage.features.Feature` describing the presence of a TeX file. EXAMPLES:: diff --git a/src/sage/features/latte.py b/src/sage/features/latte.py index 7e973978c24..9370d5e1ecc 100644 --- a/src/sage/features/latte.py +++ b/src/sage/features/latte.py @@ -35,8 +35,8 @@ def __init__(self): sage: isinstance(Latte_count(), Latte_count) True """ - Executable.__init__(self, "count", executable="count", - spkg="latte_int", + Executable.__init__(self, 'count', executable='count', + spkg='latte_int', url=LATTE_URL) @@ -52,8 +52,8 @@ def __init__(self): sage: isinstance(Latte_integrate(), Latte_integrate) True """ - Executable.__init__(self, "integrate", executable="integrate", - spkg="latte_int", + Executable.__init__(self, 'integrate', executable='integrate', + spkg='latte_int', url=LATTE_URL) @@ -76,9 +76,9 @@ def __init__(self): sage: isinstance(Latte(), Latte) True """ - JoinFeature.__init__(self, "latte_int", + JoinFeature.__init__(self, 'latte_int', (Latte_count(), Latte_integrate()), - description="LattE") + description='LattE') def all_features(): diff --git a/src/sage/features/lrs.py b/src/sage/features/lrs.py index 52506e496e5..b0f61b62bc9 100644 --- a/src/sage/features/lrs.py +++ b/src/sage/features/lrs.py @@ -41,8 +41,8 @@ def __init__(self): sage: isinstance(Lrs(), Lrs) True """ - Executable.__init__(self, "lrs", executable="lrs", spkg="lrslib", - url="http://cgm.cs.mcgill.ca/~avis/C/lrs.html") + Executable.__init__(self, "lrs", executable='lrs', spkg='lrslib', + url='http://cgm.cs.mcgill.ca/~avis/C/lrs.html') def is_functional(self): r""" @@ -100,8 +100,8 @@ def __init__(self): sage: isinstance(LrsNash(), LrsNash) True """ - Executable.__init__(self, "lrsnash", executable="lrsnash", spkg="lrslib", - url="http://cgm.cs.mcgill.ca/~avis/C/lrs.html") + Executable.__init__(self, "lrsnash", executable='lrsnash', spkg='lrslib', + url='http://cgm.cs.mcgill.ca/~avis/C/lrs.html') def is_functional(self): r""" @@ -128,7 +128,7 @@ def is_functional(self): 'raised an OSError "{}" '.format(' '.join(command), e)) if result.returncode: return FeatureTestResult(self, False, reason='Running command "{}" ' - 'returned non-zero exit status "{}" with stderr ' + 'returned nonzero exit status "{}" with stderr ' '"{}" and stdout "{}".'.format(' '.join(result.args), result.returncode, result.stderr.strip(), diff --git a/src/sage/features/msolve.py b/src/sage/features/msolve.py index 4328af54876..bc66da45044 100644 --- a/src/sage/features/msolve.py +++ b/src/sage/features/msolve.py @@ -40,8 +40,8 @@ def __init__(self): sage: isinstance(msolve(), msolve) True """ - Executable.__init__(self, "msolve", executable="msolve", - url="https://msolve.lip6.fr/") + Executable.__init__(self, "msolve", executable='msolve', + url='https://msolve.lip6.fr/') def is_functional(self): r""" @@ -57,7 +57,7 @@ def is_functional(self): # if msolve_out.returncode != 0: # return FeatureTestResult(self, False, reason="msolve -h returned " -# f"non-zero exit status {msolve_out.returncode}") +# f"nonzero exit status {msolve_out.returncode}") if (msolve_out.stdout[:46] != b'\nmsolve library for polynomial system solving\n'): return FeatureTestResult(self, False, diff --git a/src/sage/features/nauty.py b/src/sage/features/nauty.py index 79542de74fc..f0f47bcda28 100644 --- a/src/sage/features/nauty.py +++ b/src/sage/features/nauty.py @@ -38,8 +38,8 @@ def __init__(self, name): """ Executable.__init__(self, name=f"nauty_{name}", executable=f"{SAGE_NAUTY_BINS_PREFIX}{name}", - spkg="nauty", - type="standard") + spkg='nauty', + type='standard') class Nauty(JoinFeature): diff --git a/src/sage/features/normaliz.py b/src/sage/features/normaliz.py index 6d1de88bf58..5b872739bc0 100644 --- a/src/sage/features/normaliz.py +++ b/src/sage/features/normaliz.py @@ -36,7 +36,7 @@ def __init__(self): True """ JoinFeature.__init__(self, 'pynormaliz', - [PythonModule('PyNormaliz', spkg="pynormaliz")]) + [PythonModule('PyNormaliz', spkg='pynormaliz')]) def all_features(): diff --git a/src/sage/features/palp.py b/src/sage/features/palp.py index b35634ac800..9e3324c495b 100644 --- a/src/sage/features/palp.py +++ b/src/sage/features/palp.py @@ -22,9 +22,9 @@ class PalpExecutable(Executable): INPUT: - - ``palpprog`` -- string, one of ``"poly"``, ``"class"``, ``"nef"``, ``"cws"``. + - ``palpprog`` -- string, one of ``'poly'``, ``'class'``, ``'nef'``, ``'cws'`` - - ``suff`` -- string or ``None``. + - ``suff`` -- string or ``None`` """ def __init__(self, palpprog, suff=None): r""" @@ -37,11 +37,11 @@ def __init__(self, palpprog, suff=None): if suff: Executable.__init__(self, f"palp_{palpprog}_{suff}d", executable=f"{palpprog}-{suff}d.x", - spkg="palp", type="standard") + spkg='palp', type='standard') else: Executable.__init__(self, f"palp_{palpprog}", executable=f"{palpprog}.x", - spkg="palp", type="standard") + spkg='palp', type='standard') class Palp(JoinFeature): r""" @@ -59,7 +59,7 @@ def __init__(self): [PalpExecutable(palpprog, suff) for palpprog in ("poly", "class", "nef", "cws") for suff in (None, 4, 5, 6, 11)], - description="PALP") + description='PALP') def all_features(): return [Palp()] diff --git a/src/sage/features/pandoc.py b/src/sage/features/pandoc.py index 1c4450b9b0c..3c43c7fcf47 100644 --- a/src/sage/features/pandoc.py +++ b/src/sage/features/pandoc.py @@ -34,8 +34,8 @@ def __init__(self): sage: isinstance(Pandoc(), Pandoc) True """ - Executable.__init__(self, "pandoc", executable="pandoc", - url="https://pandoc.org/") + Executable.__init__(self, "pandoc", executable='pandoc', + url='https://pandoc.org/') def all_features(): diff --git a/src/sage/features/pdf2svg.py b/src/sage/features/pdf2svg.py index af20d011ac3..41014eb8e5c 100644 --- a/src/sage/features/pdf2svg.py +++ b/src/sage/features/pdf2svg.py @@ -32,9 +32,9 @@ def __init__(self): sage: isinstance(pdf2svg(), pdf2svg) True """ - Executable.__init__(self, "pdf2svg", executable="pdf2svg", + Executable.__init__(self, "pdf2svg", executable='pdf2svg', spkg='pdf2svg', - url="http://www.cityinthesky.co.uk/opensource/pdf2svg/") + url='http://www.cityinthesky.co.uk/opensource/pdf2svg/') def all_features(): diff --git a/src/sage/features/polymake.py b/src/sage/features/polymake.py index 10dfab73346..6428d68a29d 100644 --- a/src/sage/features/polymake.py +++ b/src/sage/features/polymake.py @@ -36,7 +36,7 @@ def __init__(self): True """ JoinFeature.__init__(self, "jupymake", - [PythonModule("JuPyMake", spkg="jupymake")]) + [PythonModule("JuPyMake", spkg='jupymake')]) def all_features(): diff --git a/src/sage/features/poppler.py b/src/sage/features/poppler.py index d3c0ad18541..a6da8343f53 100644 --- a/src/sage/features/poppler.py +++ b/src/sage/features/poppler.py @@ -51,8 +51,8 @@ def __init__(self): sage: isinstance(pdftocairo(), pdftocairo) True """ - Executable.__init__(self, "pdftocairo", executable="pdftocairo", - url="https://poppler.freedesktop.org/") + Executable.__init__(self, "pdftocairo", executable='pdftocairo', + url='https://poppler.freedesktop.org/') def all_features(): return [pdftocairo()] diff --git a/src/sage/features/rubiks.py b/src/sage/features/rubiks.py index 2429645d2ff..cc8d5dc10ab 100644 --- a/src/sage/features/rubiks.py +++ b/src/sage/features/rubiks.py @@ -38,7 +38,7 @@ def __init__(self): True """ Executable.__init__(self, "cu2", executable=RUBIKS_BINS_PREFIX + "cu2", - spkg="rubiks") + spkg='rubiks') class size222(Executable): @@ -60,7 +60,7 @@ def __init__(self): True """ Executable.__init__(self, "size222", executable=RUBIKS_BINS_PREFIX + "size222", - spkg="rubiks") + spkg='rubiks') class optimal(Executable): @@ -82,7 +82,7 @@ def __init__(self): True """ Executable.__init__(self, "optimal", executable=RUBIKS_BINS_PREFIX + "optimal", - spkg="rubiks") + spkg='rubiks') class mcube(Executable): @@ -104,7 +104,7 @@ def __init__(self): True """ Executable.__init__(self, "mcube", executable=RUBIKS_BINS_PREFIX + "mcube", - spkg="rubiks") + spkg='rubiks') class dikcube(Executable): @@ -126,7 +126,7 @@ def __init__(self): True """ Executable.__init__(self, "dikcube", executable=RUBIKS_BINS_PREFIX + "dikcube", - spkg="rubiks") + spkg='rubiks') class cubex(Executable): @@ -148,7 +148,7 @@ def __init__(self): True """ Executable.__init__(self, "cubex", executable=RUBIKS_BINS_PREFIX + "cubex", - spkg="rubiks") + spkg='rubiks') class Rubiks(JoinFeature): @@ -173,7 +173,7 @@ def __init__(self): """ JoinFeature.__init__(self, "rubiks", [cu2(), size222(), optimal(), mcube(), dikcube(), cubex()], - spkg="rubiks") + spkg='rubiks') def all_features(): diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index fc54853bc9b..f536665d8cc 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -48,7 +48,6 @@ class SAGE_SRC(StaticFile): r""" A :class:`~sage.features.Feature` which describes the presence of the monolithic source tree of the Sage library. - """ def __init__(self): r""" @@ -175,7 +174,7 @@ def __init__(self): [PythonModule('sage.combinat'), # namespace package PythonModule('sage.combinat.tableau'), # representative ], - spkg='sagemath_combinat', type="standard") + spkg='sagemath_combinat', type='standard') class sage__geometry__polyhedron(JoinFeature): @@ -219,7 +218,7 @@ def __init__(self): PythonModule('sage.schemes.toric'), # namespace package PythonModule('sage.schemes.toric.variety'), # representative ], - spkg='sagemath_polyhedra', type="standard") + spkg='sagemath_polyhedra', type='standard') class sage__graphs(JoinFeature): @@ -301,7 +300,7 @@ def __init__(self): PythonModule('sage.topology'), # namespace package PythonModule('sage.topology.simplicial_complex'), # representative ], - spkg='sagemath_graphs', type="standard") + spkg='sagemath_graphs', type='standard') class sage__groups(JoinFeature): @@ -538,6 +537,58 @@ def __init__(self): spkg='sagemath_ntl', type='standard') +class sage__libs__giac(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.giac`. + + In addition to the modularization purposes that this tag serves, + it also provides attribution to the upstream project. + + TESTS:: + + sage: from sage.features.sagemath import sage__libs__giac + sage: sage__libs__giac().is_present() # needs sage.libs.giac + FeatureTestResult('sage.libs.giac', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__giac + sage: isinstance(sage__libs__giac(), sage__libs__giac) + True + """ + JoinFeature.__init__(self, 'sage.libs.giac', + [PythonModule('sage.libs.giac.giac')], + spkg='sagemath_giac', type='standard') + + +class sage__libs__homfly(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.homfly`. + + In addition to the modularization purposes that this tag serves, + it also provides attribution to the upstream project. + + TESTS:: + + sage: from sage.features.sagemath import sage__libs__homfly + sage: sage__libs__homfly().is_present() # needs sage.libs.homfly + FeatureTestResult('sage.libs.homfly', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__homfly + sage: isinstance(sage__libs__homfly(), sage__libs__homfly) + True + """ + JoinFeature.__init__(self, 'sage.libs.homfly', + [PythonModule('sage.libs.homfly')], + spkg='sagemath_homfly', type='standard') + + class sage__libs__pari(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.libs.pari`. @@ -1037,7 +1088,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.schemes', [PythonModule('sage.schemes.elliptic_curves.ell_generic')], - spkg="sagemath_schemes", type='standard') + spkg='sagemath_schemes', type='standard') class sage__symbolic(JoinFeature): @@ -1130,6 +1181,8 @@ def all_features(): sage__libs__ecl(), sage__libs__flint(), sage__libs__gap(), + sage__libs__giac(), + sage__libs__homfly(), sage__libs__linbox(), sage__libs__m4ri(), sage__libs__ntl(), diff --git a/src/sage/features/sat.py b/src/sage/features/sat.py new file mode 100644 index 00000000000..6a05491ddb7 --- /dev/null +++ b/src/sage/features/sat.py @@ -0,0 +1,103 @@ +# sage_setup: distribution = sagemath-environment +r""" +Feature for testing the presence of SAT solvers +""" + +from . import Executable, PythonModule + + +class Glucose(Executable): + r""" + A :class:`~sage.features.Feature` describing the presence of an + executable from the :ref:`Glucose SAT solver `. + + EXAMPLES:: + + sage: from sage.features.sat import Glucose + sage: GlucoseExecutable().is_present() # optional - glucose + FeatureTestResult('glucose', True) + """ + def __init__(self, executable="glucose"): + r""" + TESTS:: + + sage: from sage.features.sat import Glucose + sage: isinstance(Glucose(), Glucose) + True + """ + Executable.__init__(self, name=executable, executable=executable, + spkg="glucose", type="optional") + + +class Kissat(Executable): + r""" + A :class:`~sage.features.Feature` describing the presence of the + :ref:`Kissat SAT solver `. + + EXAMPLES:: + + sage: from sage.features.sat import Kissat + sage: Kissat().is_present() # optional - kissat + FeatureTestResult('kissat', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sat import Kissat + sage: isinstance(Kissat(), Kissat) + True + """ + Executable.__init__(self, name="kissat", executable="kissat", + spkg="kissat", type="optional") + + +class Pycosat(PythonModule): + r""" + A :class:`~sage.features.Feature` describing the presence of :ref:`spkg_pycosat`. + + EXAMPLES:: + + sage: from sage.features.sat import Pycosat + sage: PycosatExecutable().is_present() # optional - pycosat + FeatureTestResult('pycosat', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sat import Pycosat + sage: isinstance(Pycosat(), Pycosat) + True + """ + PythonModule.__init__(self, "pycosat", + spkg="pycosat", type="optional") + + +class Pycryptosat(PythonModule): + r""" + A :class:`~sage.features.Feature` describing the presence of :ref:`spkg_pycryptosat`. + + EXAMPLES:: + + sage: from sage.features.sat import Pycryptosat + sage: PycryptosatExecutable().is_present() # optional - pycryptosat + FeatureTestResult('pycryptosat', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sat import Pycryptosat + sage: isinstance(Pycryptosat(), Pycryptosat) + True + """ + PythonModule.__init__(self, "pycryptosat", + spkg="pycryptosat", type="optional") + + +def all_features(): + return [Glucose(), + Kissat(), + Pycosat(), + Pycryptosat()] diff --git a/src/sage/features/sirocco.py b/src/sage/features/sirocco.py index 676f187299f..2f392855a5e 100644 --- a/src/sage/features/sirocco.py +++ b/src/sage/features/sirocco.py @@ -38,7 +38,7 @@ def __init__(self): """ JoinFeature.__init__(self, "sirocco", [PythonModule("sage.libs.sirocco", - spkg="sagemath_sirocco")]) + spkg='sagemath_sirocco')]) def all_features(): diff --git a/src/sage/features/sphinx.py b/src/sage/features/sphinx.py index ec7c8be17b6..672b826f59d 100644 --- a/src/sage/features/sphinx.py +++ b/src/sage/features/sphinx.py @@ -39,5 +39,33 @@ def __init__(self): PythonModule.__init__(self, 'sphinx', spkg='sphinx', type='standard') +class JupyterSphinx(PythonModule): + r""" + A :class:`sage.features.Feature` describing the presence of + :ref:`jupyter_sphinx `. + + It is provided by a standard package in the Sage distribution, + but it can be disabled by ``configure --disable-doc`` and + ``configure --disable-notebook``. + + EXAMPLES:: + + sage: from sage.features.sphinx import JupyterSphinx + sage: JupyterSphinx().is_present() # optional - jupyter_sphinx + FeatureTestResult('jupyter_sphinx', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sphinx import JupyterSphinx + sage: isinstance(JupyterSphinx(), JupyterSphinx) + True + """ + PythonModule.__init__(self, 'jupyter_sphinx', + spkg='jupyter_sphinx', type='standard') + + def all_features(): - return [Sphinx()] + return [Sphinx(), + JupyterSphinx()] diff --git a/src/sage/features/symengine_py.py b/src/sage/features/symengine_py.py index 0e602e0b84d..96a64ca60b3 100644 --- a/src/sage/features/symengine_py.py +++ b/src/sage/features/symengine_py.py @@ -37,8 +37,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'symengine_py', - [PythonModule('symengine', spkg="symengine_py", - url="https://pypi.org/project/symengine")]) + [PythonModule('symengine', spkg='symengine_py', + url='https://pypi.org/project/symengine')]) def all_features(): return [symengine_py()] diff --git a/src/sage/features/threejs.py b/src/sage/features/threejs.py index 39136c87ecd..8698b84e0e5 100644 --- a/src/sage/features/threejs.py +++ b/src/sage/features/threejs.py @@ -1,5 +1,5 @@ # sage_setup: distribution = sagemath-environment -import os +from pathlib import Path from . import StaticFile @@ -26,24 +26,25 @@ def __init__(self): """ from sage.env import SAGE_SHARE, THREEJS_DIR + share_dir = Path(SAGE_SHARE) threejs_search_path = THREEJS_DIR or ( - os.path.join(SAGE_SHARE, "jupyter", "nbextensions", "threejs-sage"), - os.path.join(SAGE_SHARE, "sagemath", "threejs-sage"), - os.path.join(SAGE_SHARE, "sage", "threejs"), - os.path.join(SAGE_SHARE, "threejs-sage") + (share_dir / "jupyter" / "nbextensions" / "threejs-sage"), + (share_dir / "sagemath" / "threejs-sage"), + (share_dir / "sage" / "threejs"), + (share_dir / "threejs-sage") ) try: version = self.required_version() - filename = os.path.join(version, "three.min.js") + filename = Path(version) / "three.min.js" except FileNotFoundError: filename = 'unknown' StaticFile.__init__( - self, name="threejs", + self, name='threejs', filename=filename, - spkg="threejs", - type="standard", + spkg='threejs', + type='standard', search_path=threejs_search_path, description="JavaScript library to display 3D graphics") @@ -54,7 +55,7 @@ def required_version(self): Defining what version is required is delegated to the distribution package that provides the file ``threejs-version.txt`` in :mod:`sage.ext_data.threejs`. - If the file is not provided, :class:`FileNotFoundError` is raised. + If the file is not provided, :exc:`FileNotFoundError` is raised. EXAMPLES:: @@ -64,7 +65,7 @@ def required_version(self): """ from sage.env import SAGE_EXTCODE - filename = os.path.join(SAGE_EXTCODE, 'threejs', 'threejs-version.txt') + filename = Path(SAGE_EXTCODE) / 'threejs' / 'threejs-version.txt' with open(filename) as f: return f.read().strip() diff --git a/src/sage/features/topcom.py b/src/sage/features/topcom.py new file mode 100644 index 00000000000..5256519ce3d --- /dev/null +++ b/src/sage/features/topcom.py @@ -0,0 +1,67 @@ +# sage_setup: distribution = sagemath-environment +r""" +Features for testing the presence of topcom executables +""" + +# ***************************************************************************** +# Copyright (C) 2022-2024 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + +from . import Executable +from .join_feature import JoinFeature + + +class TOPCOMExecutable(Executable): + r""" + A :class:`~sage.features.Feature` which checks for executables from the :ref:`TOPCOM ` package. + + EXAMPLES:: + + sage: from sage.features.topcom import TOPCOMExecutable + sage: TOPCOMExecutable('points2allfinetriangs').is_present() # optional - topcom + FeatureTestResult('topcom_points2allfinetriangs', True) + """ + def __init__(self, name): + r""" + TESTS:: + + sage: from sage.features.topcom import TOPCOMExecutable + sage: isinstance(TOPCOMExecutable('points2finetriangs'), TOPCOMExecutable) + True + """ + Executable.__init__(self, name=f"topcom_{name}", + executable=name, + spkg="topcom") + + +class TOPCOM(JoinFeature): + r""" + A :class:`~sage.features.Feature` describing the presence of the executables + which comes as a part of :ref:`TOPCOM `. + + EXAMPLES:: + + sage: from sage.features.topcom import TOPCOM + sage: TOPCOM().is_present() # optional - topcom + FeatureTestResult('topcom', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.topcom import TOPCOM + sage: isinstance(TOPCOM(), TOPCOM) + True + """ + JoinFeature.__init__(self, "topcom", + [TOPCOMExecutable(name) + for name in ('points2allfinetriangs',)]) + + +def all_features(): + return [TOPCOM()] diff --git a/src/sage/functions/airy.py b/src/sage/functions/airy.py index 11f4c56be8c..d8f1a79fa8b 100644 --- a/src/sage/functions/airy.py +++ b/src/sage/functions/airy.py @@ -62,11 +62,11 @@ class FunctionAiryAiGeneral(BuiltinFunction): def __init__(self): r""" - The generalized derivative of the Airy Ai function + The generalized derivative of the Airy Ai function. INPUT: - - ``alpha`` -- Return the `\alpha`-th order fractional derivative with + - ``alpha`` -- return the `\alpha`-th order fractional derivative with respect to `z`. For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Ai}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots` @@ -78,7 +78,7 @@ def __init__(self): f_n(z) = \int_0^z f_{n-1}(t) dt - - ``x`` -- The argument of the function + - ``x`` -- the argument of the function EXAMPLES:: @@ -365,7 +365,7 @@ def _evalf_(self, x, **kwargs): def airy_ai(alpha, x=None, hold_derivative=True, **kwds): r""" - The Airy Ai function + The Airy Ai function. The Airy Ai function `\operatorname{Ai}(x)` is (along with `\operatorname{Bi}(x)`) one of the two linearly independent standard @@ -387,7 +387,7 @@ def airy_ai(alpha, x=None, hold_derivative=True, **kwds): INPUT: - - ``alpha`` -- Return the `\alpha`-th order fractional derivative with + - ``alpha`` -- return the `\alpha`-th order fractional derivative with respect to `z`. For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Ai}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots` @@ -399,9 +399,9 @@ def airy_ai(alpha, x=None, hold_derivative=True, **kwds): f_n(z) = \int_0^z f_{n-1}(t) dt - - ``x`` -- The argument of the function + - ``x`` -- the argument of the function - - ``hold_derivative`` -- Whether or not to stop from returning higher + - ``hold_derivative`` -- whether or not to stop from returning higher derivatives in terms of `\operatorname{Ai}(x)` and `\operatorname{Ai}'(x)` @@ -504,7 +504,7 @@ def __init__(self): INPUT: - - ``alpha`` -- Return the `\alpha`-th order fractional derivative with + - ``alpha`` -- return the `\alpha`-th order fractional derivative with respect to `z`. For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots` @@ -516,7 +516,7 @@ def __init__(self): f_n(z) = \int_0^z f_{n-1}(t) dt - - ``x`` -- The argument of the function + - ``x`` -- the argument of the function EXAMPLES:: @@ -581,7 +581,6 @@ def _evalf_(self, alpha, x, **kwargs): sage: from sage.functions.airy import airy_bi_general sage: airy_bi_general(-2, 1.0) # needs mpmath 0.388621540699059 - """ parent = kwargs.get('parent') import mpmath @@ -807,7 +806,7 @@ def _evalf_(self, x, **kwargs): def airy_bi(alpha, x=None, hold_derivative=True, **kwds): r""" - The Airy Bi function + The Airy Bi function. The Airy Bi function `\operatorname{Bi}(x)` is (along with `\operatorname{Ai}(x)`) one of the two linearly independent standard @@ -830,7 +829,7 @@ def airy_bi(alpha, x=None, hold_derivative=True, **kwds): INPUT: - - ``alpha`` -- Return the `\alpha`-th order fractional derivative with + - ``alpha`` -- return the `\alpha`-th order fractional derivative with respect to `z`. For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots` @@ -842,11 +841,11 @@ def airy_bi(alpha, x=None, hold_derivative=True, **kwds): f_n(z) = \int_0^z f_{n-1}(t) dt - - ``x`` -- The argument of the function + - ``x`` -- the argument of the function - - ``hold_derivative`` -- Whether or not to stop from returning higher - derivatives in terms of `\operatorname{Bi}(x)` and - `\operatorname{Bi}'(x)` + - ``hold_derivative`` -- boolean (default: ``True``); whether or not to + stop from returning higher derivatives in terms of `\operatorname{Bi}(x)` + and `\operatorname{Bi}'(x)` .. SEEALSO:: :func:`airy_ai` diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index cedbe56c00e..1cd132b3a45 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -7,20 +7,20 @@ The main objects which are exported from this module are: - * :meth:`bessel_J(n, x) ` -- The Bessel J function - * :meth:`bessel_Y(n, x) ` -- The Bessel Y function - * :meth:`bessel_I(n, x) ` -- The Bessel I function - * :meth:`bessel_K(n, x) ` -- The Bessel K function - * :meth:`Bessel(...) ` -- A factory function for producing Bessel functions of + * :meth:`bessel_J(n, x) ` -- the Bessel J function + * :meth:`bessel_Y(n, x) ` -- the Bessel Y function + * :meth:`bessel_I(n, x) ` -- the Bessel I function + * :meth:`bessel_K(n, x) ` -- the Bessel K function + * :meth:`Bessel(...) ` -- a factory function for producing Bessel functions of various kinds and orders - * :meth:`hankel1(nu, z) ` -- The Hankel function of the first kind - * :meth:`hankel2(nu, z) ` -- The Hankel function of the second kind - * :meth:`struve_H(nu, z) ` -- The Struve function - * :meth:`struve_L(nu, z) ` -- The modified Struve function - * :meth:`spherical_bessel_J(n, z) ` -- The Spherical Bessel J function - * :meth:`spherical_bessel_Y(n, z) ` -- The Spherical Bessel J function - * :meth:`spherical_hankel1(n, z) ` -- The Spherical Hankel function of the first kind - * :meth:`spherical_hankel2(n, z) ` -- The Spherical Hankel function of the second kind + * :meth:`hankel1(nu, z) ` -- the Hankel function of the first kind + * :meth:`hankel2(nu, z) ` -- the Hankel function of the second kind + * :meth:`struve_H(nu, z) ` -- the Struve function + * :meth:`struve_L(nu, z) ` -- the modified Struve function + * :meth:`spherical_bessel_J(n, z) ` -- the Spherical Bessel J function + * :meth:`spherical_bessel_Y(n, z) ` -- the Spherical Bessel J function + * :meth:`spherical_hankel1(n, z) ` -- the Spherical Hankel function of the first kind + * :meth:`spherical_hankel2(n, z) ` -- the Spherical Hankel function of the second kind - Bessel functions, first defined by the Swiss mathematician Daniel Bernoulli and named after Friedrich Bessel, are canonical @@ -435,7 +435,6 @@ def _derivative_(self, n, x, diff_param): Traceback (most recent call last): ... NotImplementedError: derivative with respect to order - """ if diff_param == 1: return (bessel_J(n - 1, x) - bessel_J(n + 1, x)) / Integer(2) @@ -1203,7 +1202,6 @@ def Bessel(*args, **kwds): sage: G += plot(Bessel(1, 'J'), 0, 15, color='black', linestyle='dotted') sage: G += plot(Bessel(1, 'Y'), 0, 15, color='black', linestyle='dotted') sage: show(G, ymin=-1, ymax=1) - """ # Determine the order and type of function from the arguments and keywords. # These are recorded in local variables: _type, _order, _system, _nargs. @@ -1230,7 +1228,7 @@ def Bessel(*args, **kwds): _type = kwds['typ'] else: _type = 'J' - if not (_type in ['I', 'J', 'K', 'Y']): + if _type not in ['I', 'J', 'K', 'Y']: raise ValueError("type must be one of I, J, K, Y") # return the function @@ -1476,7 +1474,7 @@ def _print_latex_(self, a, z): class Function_Hankel1(BuiltinFunction): r""" - The Hankel function of the first kind + The Hankel function of the first kind. DEFINITION: @@ -1563,7 +1561,7 @@ def _derivative_(self, nu, z, diff_param): class Function_Hankel2(BuiltinFunction): r""" - The Hankel function of the second kind + The Hankel function of the second kind. DEFINITION: @@ -1650,7 +1648,7 @@ def _derivative_(self, nu, z, diff_param): class SphericalBesselJ(BuiltinFunction): r""" - The spherical Bessel function of the first kind + The spherical Bessel function of the first kind. DEFINITION: @@ -1752,7 +1750,7 @@ def _derivative_(self, n, z, diff_param): class SphericalBesselY(BuiltinFunction): r""" - The spherical Bessel function of the second kind + The spherical Bessel function of the second kind. DEFINITION: @@ -1853,7 +1851,7 @@ def _derivative_(self, n, z, diff_param): class SphericalHankel1(BuiltinFunction): r""" - The spherical Hankel function of the first kind + The spherical Hankel function of the first kind. DEFINITION: @@ -1951,7 +1949,7 @@ def _derivative_(self, n, z, diff_param): class SphericalHankel2(BuiltinFunction): r""" - The spherical Hankel function of the second kind + The spherical Hankel function of the second kind. DEFINITION: diff --git a/src/sage/functions/error.py b/src/sage/functions/error.py index db6312af807..78eb4992aa6 100644 --- a/src/sage/functions/error.py +++ b/src/sage/functions/error.py @@ -7,12 +7,12 @@ The main objects which are exported from this module are: - * :meth:`erf ` -- The error function - * :meth:`erfc ` -- The complementary error function - * :meth:`erfi ` -- The imaginary error function - * :meth:`erfinv ` -- The inverse error function - * :meth:`fresnel_sin ` -- The Fresnel integral `S(x)` - * :meth:`fresnel_cos ` -- The Fresnel integral `C(x)` + * :meth:`erf ` -- the error function + * :meth:`erfc ` -- the complementary error function + * :meth:`erfi ` -- the imaginary error function + * :meth:`erfinv ` -- the inverse error function + * :meth:`fresnel_sin ` -- the Fresnel integral `S(x)` + * :meth:`fresnel_cos ` -- the Fresnel integral `C(x)` AUTHORS: @@ -383,7 +383,6 @@ def _derivative_(self, x, diff_param=None): sage: erfi(x).diff(x) # needs sage.symbolic 2*e^(x^2)/sqrt(pi) - """ return 2*exp(x**2)/sqrt(pi) @@ -421,7 +420,6 @@ class Function_erfc(BuiltinFunction): sage: erfc(x)._fricas_() # optional - fricas, needs sage.symbolic - erf(x) + 1 - """ def __init__(self): r""" diff --git a/src/sage/functions/exp_integral.py b/src/sage/functions/exp_integral.py index a277afd04b5..e074c430808 100644 --- a/src/sage/functions/exp_integral.py +++ b/src/sage/functions/exp_integral.py @@ -148,7 +148,6 @@ class Function_exp_integral_e(BuiltinFunction): Numerical evaluation is handled using mpmath, but symbolics are handled by Sage and Maxima. - """ def __init__(self): """ @@ -160,7 +159,6 @@ def __init__(self): exp_integral_e(1, 0) sage: exp_integral_e(1, x)._sympy_() # needs sage.symbolic expint(1, x) - """ BuiltinFunction.__init__(self, "exp_integral_e", nargs=2, conversions=dict(maxima='expintegral_e', @@ -308,7 +306,6 @@ class Function_exp_integral_e1(BuiltinFunction): Numerical evaluation is handled using mpmath, but symbolics are handled by Sage and Maxima. - """ def __init__(self): """ @@ -320,7 +317,6 @@ def __init__(self): exp_integral_e1(1) sage: exp_integral_e1(x)._sympy_() # needs sympy sage.symbolic expint(1, x) - """ BuiltinFunction.__init__(self, "exp_integral_e1", nargs=1, conversions=dict(maxima='expintegral_e1', @@ -334,7 +330,6 @@ def _evalf_(self, z, parent=None, algorithm=None): 0.000281624451981418 - 0.179324535039359*I sage: exp_integral_e1(RealField(200)(0.5)) # needs sage.rings.real_mpfr 0.55977359477616081174679593931508523522684689031635351524829 - """ return _mpmath_utils_call(_mpmath_e1, z, parent=parent) @@ -365,7 +360,6 @@ def _derivative_(self, z, diff_param=None): sage: f = exp_integral_e1(x^2) sage: f.diff(x) -2*e^(-x^2)/x - """ return -exp(-z)/z @@ -424,8 +418,6 @@ class Function_log_integral(BuiltinFunction): - mpmath documentation: `logarithmic-integral`_ .. _`logarithmic-integral`: http://mpmath.org/doc/current/functions/expintegrals.html#logarithmic-integral - - """ def __init__(self): r""" @@ -464,7 +456,6 @@ def _eval_(self, z): 2.16358859466719 sage: log_integral(0) # needs mpmath 0 - """ # Special case z = 0 if isinstance(z, Expression): @@ -481,7 +472,6 @@ def _evalf_(self, z, parent=None, algorithm=None): 78627.5491594622 sage: log_integral(RealField(200)(1e6)) # needs sage.rings.real_mpfr 78627.549159462181919862910747947261161321874382421767074759 - """ return _mpmath_utils_call(_mpmath_li, z, parent=parent) @@ -499,7 +489,6 @@ def _derivative_(self, z, diff_param=None): sage: f = log_integral(x^2) sage: f.diff(x) 2*x/log(x^2) - """ return 1/log(z) @@ -642,7 +631,6 @@ def __init__(self): sage: latex(log_integral_offset) \operatorname{log\_integral\_offset} - """ BuiltinFunction.__init__(self, "log_integral_offset", nargs=1, latex_name=r'\operatorname{log\_integral\_offset}', @@ -659,7 +647,6 @@ def _eval_(self, z): 1.11842481454970 sage: log_integral_offset(2) # needs mpmath 0 - """ if z == 2: return SR(0) @@ -677,7 +664,6 @@ def _evalf_(self, z, parent=None, algorithm=None): 78626.503995682064427078066159058066548185351766843615873183 sage: li(4.5) - li(2.0) - Li(4.5) # needs mpmath 0.000000000000000 - """ return _mpmath_utils_call(_mpmath_li, z, offset=True, parent=parent) @@ -800,7 +786,6 @@ class Function_sin_integral(BuiltinFunction): - mpmath documentation: `si`_ .. _`si`: http://mpmath.org/doc/current/functions/expintegrals.html#si - """ def __init__(self): """ @@ -815,7 +800,7 @@ def __init__(self): Si(x) sage: sin_integral(x)._fricas_init_() 'Si(x)' - sage: sin_integral(x)._giac_() # needs sage.libs.giac + sage: sin_integral(x)._giac_() # needs giac Si(sageVARx) """ BuiltinFunction.__init__(self, "sin_integral", nargs=1, @@ -835,7 +820,6 @@ def _eval_(self, z): 1.84865252799947 sage: sin_integral(0) # needs mpmath 0 - """ if isinstance(z, Expression): if z.is_trivial_zero(): @@ -888,7 +872,6 @@ def _derivative_(self, z, diff_param=None): sage: f = sin_integral(x^2) sage: f.diff(x) 2*sin(x^2)/x - """ return sin(z)/z @@ -978,7 +961,6 @@ class Function_cos_integral(BuiltinFunction): - mpmath documentation: `ci`_ .. _`ci`: http://mpmath.org/doc/current/functions/expintegrals.html#ci - """ def __init__(self): """ @@ -993,7 +975,7 @@ def __init__(self): Ci(x) sage: cos_integral(x)._fricas_init_() 'Ci(x)' - sage: cos_integral(x)._giac_() # needs sage.libs.giac + sage: cos_integral(x)._giac_() # needs giac Ci(sageVARx) """ BuiltinFunction.__init__(self, "cos_integral", nargs=1, @@ -1012,7 +994,6 @@ def _evalf_(self, z, parent=None, algorithm=None): -22.4486352650389239795759024568 sage: cos_integral(ComplexField(100)(I)) # needs sage.symbolic 0.83786694098020824089467857943 + 1.5707963267948966192313216916*I - """ return _mpmath_utils_call(_mpmath_ci, z, parent=parent) @@ -1030,7 +1011,6 @@ def _derivative_(self, z, diff_param=None): sage: f = cos_integral(x^2) sage: f.diff(x) 2*cos(x^2)/x - """ return cos(z)/z @@ -1116,7 +1096,6 @@ class Function_sinh_integral(BuiltinFunction): - mpmath documentation: `shi`_ .. _`shi`: http://mpmath.org/doc/current/functions/expintegrals.html#shi - """ def __init__(self): """ @@ -1128,7 +1107,6 @@ def __init__(self): sinh_integral(1) sage: sinh_integral(x)._sympy_() # needs sympy sage.symbolic Shi(x) - """ BuiltinFunction.__init__(self, "sinh_integral", nargs=1, latex_name=r'\operatorname{Shi}', @@ -1147,7 +1125,6 @@ def _eval_(self, z): 4.97344047585981 sage: sinh_integral(0) # needs mpmath 0 - """ # special case: z = 0 if isinstance(z, Expression): @@ -1164,7 +1141,6 @@ def _evalf_(self, z, parent=None, algorithm=None): 1.00000000000000000000055555556e-10 sage: sinh_integral(ComplexField(100)(I)) # needs sage.symbolic 0.94608307036718301494135331382*I - """ return _mpmath_utils_call(_mpmath_shi, z, parent=parent) @@ -1182,7 +1158,6 @@ def _derivative_(self, z, diff_param=None): sage: f = sinh_integral(ln(x)) sage: f.diff(x) 1/2*(x^2 - 1)/(x^2*log(x)) - """ return sinh(z)/z @@ -1264,7 +1239,6 @@ class Function_cosh_integral(BuiltinFunction): - mpmath documentation: `chi`_ .. _`chi`: http://mpmath.org/doc/current/functions/expintegrals.html#chi - """ def __init__(self): """ @@ -1276,7 +1250,6 @@ def __init__(self): cosh_integral(1) sage: cosh_integral(x)._sympy_() # needs sage.symbolic Chi(x) - """ BuiltinFunction.__init__(self, "cosh_integral", nargs=1, latex_name=r'\operatorname{Chi}', @@ -1292,7 +1265,6 @@ def _evalf_(self, z, parent=None, algorithm=None): -22.4486352650389239795709024568 sage: cosh_integral(ComplexField(100)(I)) # needs sage.symbolic 0.33740392290096813466264620389 + 1.5707963267948966192313216916*I - """ return _mpmath_utils_call(_mpmath_chi, z, parent=parent) @@ -1310,7 +1282,6 @@ def _derivative_(self, z, diff_param=None): sage: f = cosh_integral(ln(x)) sage: f.diff(x) 1/2*(x^2 + 1)/(x^2*log(x)) - """ return cosh(z)/z @@ -1440,7 +1411,7 @@ def _derivative_(self, x, diff_param=None): # moved here from sage/functions/transcendental.py def exponential_integral_1(x, n=0): r""" - Returns the exponential integral `E_1(x)`. If the optional + Return the exponential integral `E_1(x)`. If the optional argument `n` is given, computes list of the first `n` values of the exponential integral `E_1(x m)`. @@ -1458,8 +1429,7 @@ def exponential_integral_1(x, n=0): - ``n`` -- (default: 0) a nonnegative integer; if nonzero, then return a list of values ``E_1(x*m)`` for m = 1,2,3,...,n. This is useful, e.g., when computing derivatives of - L-functions. - + `L`-functions. OUTPUT: diff --git a/src/sage/functions/gamma.py b/src/sage/functions/gamma.py index be2d60d0861..c5b730eb65b 100644 --- a/src/sage/functions/gamma.py +++ b/src/sage/functions/gamma.py @@ -359,7 +359,7 @@ def __init__(self): sage: var('t') # needs sage.symbolic t - sage: integrate(-exp(-x)*x^(t-1), x, algorithm="fricas") # optional - fricas, needs sage.symbolic + sage: integrate(-exp(-x)*x^(t-1), x, algorithm='fricas') # optional - fricas, needs sage.symbolic gamma(t, x) .. SEEALSO:: @@ -816,7 +816,7 @@ def __init__(self): class Function_psi2(GinacFunction): def __init__(self): r""" - Derivatives of the digamma function `\psi(x)`. T + Derivatives of the digamma function `\psi(x)`. EXAMPLES:: @@ -979,7 +979,7 @@ def __init__(self): GiNaC is used to compute `\operatorname{B}(p,q)`. However, complex inputs are not yet handled in general. When GiNaC raises an error on - such inputs, we raise a NotImplementedError. + such inputs, we raise a :exc:`NotImplementedError`. If either input is 1, GiNaC returns the reciprocal of the other. In other cases, GiNaC uses one of the following @@ -1005,10 +1005,9 @@ def __init__(self): INPUT: - - ``p`` -- number or symbolic expression - - - ``q`` -- number or symbolic expression + - ``p`` -- number or symbolic expression + - ``q`` -- number or symbolic expression OUTPUT: number or symbolic expression (if input is symbolic) diff --git a/src/sage/functions/generalized.py b/src/sage/functions/generalized.py index 1305cd1dd25..f43849d2043 100644 --- a/src/sage/functions/generalized.py +++ b/src/sage/functions/generalized.py @@ -11,7 +11,6 @@ - Golam Mortuza Hossain (2009-06-26): initial version - EXAMPLES: Dirac delta function:: @@ -64,7 +63,7 @@ class FunctionDiracDelta(BuiltinFunction): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression DEFINITION: @@ -93,7 +92,6 @@ class FunctionDiracDelta(BuiltinFunction): REFERENCES: - :wikipedia:`Dirac_delta_function` - """ def __init__(self): r""" @@ -101,7 +99,7 @@ def __init__(self): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression EXAMPLES:: @@ -130,7 +128,7 @@ def _eval_(self, x): """ INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression EXAMPLES:: @@ -181,7 +179,7 @@ class FunctionHeaviside(GinacFunction): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression DEFINITION: @@ -231,7 +229,6 @@ class FunctionHeaviside(GinacFunction): REFERENCES: - :wikipedia:`Heaviside_function` - """ def __init__(self): r""" @@ -239,7 +236,7 @@ def __init__(self): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression EXAMPLES:: @@ -256,13 +253,13 @@ def __init__(self): H\left(x\right) sage: heaviside(x)._sympy_() # needs sympy Heaviside(x) - sage: heaviside(x)._giac_() # needs sage.libs.giac + sage: heaviside(x)._giac_() # needs giac Heaviside(sageVARx) sage: h(x) = heaviside(x) sage: h(pi).numerical_approx() 1.00000000000000 """ - GinacFunction.__init__(self, "heaviside", latex_name="H", + GinacFunction.__init__(self, "heaviside", latex_name='H', conversions=dict(maxima='hstep', mathematica='HeavisideTheta', sympy='Heaviside', @@ -270,7 +267,7 @@ def __init__(self): def _derivative_(self, x, diff_param=None): """ - Derivative of Heaviside step function + Derivative of Heaviside step function. EXAMPLES:: @@ -289,7 +286,7 @@ class FunctionUnitStep(GinacFunction): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression DEFINITION: @@ -330,7 +327,7 @@ def __init__(self): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression EXAMPLES:: @@ -358,7 +355,7 @@ def __init__(self): def _derivative_(self, x, diff_param=None): """ - Derivative of unit step function + Derivative of unit step function. EXAMPLES:: @@ -377,7 +374,7 @@ class FunctionSignum(BuiltinFunction): INPUT: - - ``x`` -- a real number or a symbolic expression + - ``x`` -- a real number or a symbolic expression DEFINITION: @@ -416,7 +413,7 @@ class FunctionSignum(BuiltinFunction): sign(x) sage: sgn(x)._fricas_init_() # needs sage.symbolic '(x+->abs(x)/x)(x)' - sage: sgn(x)._giac_() # needs sage.libs.giac sage.symbolic + sage: sgn(x)._giac_() # needs giac sage.symbolic sign(sageVARx) Test for :issue:`31085`:: @@ -427,7 +424,6 @@ class FunctionSignum(BuiltinFunction): REFERENCES: - :wikipedia:`Sign_function` - """ def __init__(self): r""" @@ -450,7 +446,7 @@ def __init__(self): conversions=dict(maxima='signum', mathematica='Sign', sympy='sign', giac='sign', fricas='(x+->abs(x)/x)'), - alt_name="sign") + alt_name='sign') def _eval_(self, x): """ @@ -517,7 +513,7 @@ def _evalf_(self, x, **kwds): if bool(approx_x.imag() == 0): # x is real if bool(approx_x.real() == 0): # x is zero return ZZ(0) - # Now we have a non-zero real + # Now we have a nonzero real if bool((approx_x**(0.5)).imag() == 0): # Check: x > 0 return ZZ(1) else: @@ -526,7 +522,7 @@ def _evalf_(self, x, **kwds): def _derivative_(self, x, diff_param=None): """ - Derivative of sgn function + Derivative of sgn function. EXAMPLES:: @@ -547,8 +543,8 @@ class FunctionKroneckerDelta(BuiltinFunction): INPUT: - - ``m`` -- a number or a symbolic expression - - ``n`` -- a number or a symbolic expression + - ``m`` -- a number or a symbolic expression + - ``n`` -- a number or a symbolic expression DEFINITION: @@ -570,7 +566,6 @@ class FunctionKroneckerDelta(BuiltinFunction): REFERENCES: - :wikipedia:`Kronecker_delta` - """ def __init__(self): r""" @@ -646,14 +641,14 @@ def _evalf_(self, m, n, **kwds): def _derivative_(self, *args, **kwds): """ - Derivative of Kronecker delta + Derivative of Kronecker delta. EXAMPLES:: sage: kronecker_delta(x, 1).diff(x) # needs sage.symbolic 0 """ - # Kronecker delta is non-zero (but finite) only in the set of + # Kronecker delta is nonzero (but finite) only in the set of # zero-measure unlike Dirac delta. Consequently, it is null # for the purpose of integration/differentiation. For *discrete sum* # Kronecker delta is however non-trivial. @@ -661,7 +656,7 @@ def _derivative_(self, *args, **kwds): def _print_latex_(self, m, n, **kwds): r""" - Return latex expression + Return latex expression. EXAMPLES:: diff --git a/src/sage/functions/hypergeometric.py b/src/sage/functions/hypergeometric.py index 010c61febe0..5431d15ce18 100644 --- a/src/sage/functions/hypergeometric.py +++ b/src/sage/functions/hypergeometric.py @@ -123,8 +123,8 @@ sage: maxima(hypergeometric([1, 1, 1], [3, 3, 3], x)) # needs sage.symbolic hypergeometric([1,1,1],[3,3,3],_SAGE_VAR_x) - sage: hypergeometric((5, 4), (4, 4), 3)._sympy_() # needs sympy sage.symbolic - hyper((5, 4), (4, 4), 3) + sage: hypergeometric((5,), (4,), 3)._sympy_() # needs sympy sage.symbolic + hyper((5,), (4,), 3) sage: hypergeometric((5, 4), (4, 4), 3)._mathematica_init_() # needs sage.symbolic 'HypergeometricPFQ[{5,4},{4,4},3]' @@ -274,9 +274,9 @@ def __call__(self, a, b, z, **kwargs): INPUT: - - ``a`` -- a list or tuple of parameters - - ``b`` -- a list or tuple of parameters - - ``z`` -- a number or symbolic expression + - ``a`` -- list or tuple of parameters + - ``b`` -- list or tuple of parameters + - ``z`` -- number or symbolic expression EXAMPLES:: @@ -295,6 +295,11 @@ def __call__(self, a, b, z, **kwargs): The only simplification that is done automatically is returning 1 if ``z`` is 0. For other simplifications use the ``simplify_hypergeometric`` method. + + TESTS:: + + sage: hypergeometric([2, 3, 4], [4, 1], 1) + hypergeometric((2, 3, 4), (4, 1), 1) """ return BuiltinFunction.__call__(self, SR._force_pyobject(a), @@ -307,7 +312,6 @@ def _print_latex_(self, a, b, z): sage: latex(hypergeometric([1, 1], [2], -1)) # needs sage.symbolic \,_2F_1\left(\begin{matrix} 1,1 \\ 2 \end{matrix} ; -1 \right) - """ aa = ",".join(latex(c) for c in a) bb = ",".join(latex(c) for c in b) @@ -370,7 +374,6 @@ def _evalf_(self, a, b, z, parent, algorithm=None): 0.693147180559945 sage: hypergeometric([], [], RealField(100)(1)) # needs sage.rings.real_mpfr sage.symbolic 2.7182818284590452353602874714 - """ if not isinstance(a, tuple) or not isinstance(b, tuple): raise TypeError("The first two parameters must be of type list") @@ -403,7 +406,7 @@ def _tderivative_(self, a, b, z, *args, **kwargs): return (t * derivative(z, diff_param) * hypergeometric([c + 1 for c in a], [c + 1 for c in b], z)) - class EvaluationMethods(): + class EvaluationMethods: def _fast_callable_(self, a, b, z, etb): """ @@ -460,23 +463,21 @@ def eliminate_parameters(self, a, b, z): """ aa = list(a) # tuples are immutable bb = list(b) - p = pp = len(aa) q = qq = len(bb) i = 0 while i < qq and aa: - bbb = bb[i] - if bbb in aa: - aa.remove(bbb) - bb.remove(bbb) - pp -= 1 + bbi = bb[i] + if bbi in aa: + aa.remove(bbi) + bb.remove(bbi) qq -= 1 else: i += 1 - if (pp, qq) != (p, q): + if qq != q: return hypergeometric(aa, bb, z) return self - def is_termwise_finite(self, a, b, z): + def is_termwise_finite(self, a, b, z) -> bool: """ Determine whether all terms of ``self`` are finite. @@ -518,8 +519,6 @@ def is_termwise_finite(self, a, b, z): return 0 not in b if abs(z) == Infinity: return False - if abs(z) == Infinity: - return False for bb in b: if bb in ZZ and bb <= 0: if any((aa in ZZ) and (bb < aa <= 0) for aa in a): @@ -1027,7 +1026,7 @@ def _derivative_(self, a, b, z, diff_param): raise NotImplementedError('derivative of hypergeometric function ' 'with respect to parameters') - class EvaluationMethods(): + class EvaluationMethods: def generalized(self, a, b, z): """ Return as a generalized hypergeometric function. @@ -1038,7 +1037,6 @@ def generalized(self, a, b, z): (a, b, z) sage: hypergeometric_M(a, b, z).generalized() # needs sage.symbolic hypergeometric((a,), (b,), z) - """ return hypergeometric([a], [b], z) @@ -1134,7 +1132,7 @@ def _derivative_(self, a, b, z, diff_param): raise NotImplementedError('derivative of hypergeometric function ' 'with respect to parameters') - class EvaluationMethods(): + class EvaluationMethods: def generalized(self, a, b, z): """ Return in terms of the generalized hypergeometric function. @@ -1150,7 +1148,6 @@ def generalized(self, a, b, z): 2*hypergeometric((1, -1), (), -2) sage: hypergeometric_U(3, I, 2).generalized() 1/8*hypergeometric((3, -I + 4), (), -1/2) - """ return z ** (-a) * hypergeometric([a, a - b + 1], [], -z ** (-1)) diff --git a/src/sage/functions/jacobi.py b/src/sage/functions/jacobi.py index 063dc8c7b78..9e5e6ae3849 100644 --- a/src/sage/functions/jacobi.py +++ b/src/sage/functions/jacobi.py @@ -935,7 +935,7 @@ def jacobi(kind, z, m, **kwargs): INPUT: - - ``kind`` -- a string of the form ``'pq'``, where ``p``, ``q`` are in + - ``kind`` -- string of the form ``'pq'``, where ``p``, ``q`` are in ``c``, ``d``, ``n``, ``s`` - ``z`` -- a complex number - ``m`` -- a complex number; note that `m = k^2`, where `k` is @@ -998,7 +998,7 @@ def inverse_jacobi(kind, x, m, **kwargs): INPUT: - - ``kind`` -- a string of the form ``'pq'``, where ``p``, ``q`` are in + - ``kind`` -- string of the form ``'pq'``, where ``p``, ``q`` are in ``c``, ``d``, ``n``, ``s`` - ``x`` -- a real number - ``m`` -- a real number; note that `m = k^2`, where `k` is the elliptic diff --git a/src/sage/functions/log.py b/src/sage/functions/log.py index 5940fe0281f..de1db4dcb92 100644 --- a/src/sage/functions/log.py +++ b/src/sage/functions/log.py @@ -573,7 +573,7 @@ class Function_lambert_w(BuiltinFunction): INPUT: - - ``n`` -- an integer. `n=0` corresponds to the principal branch. + - ``n`` -- integer; `n=0` corresponds to the principal branch - ``z`` -- a complex number @@ -920,7 +920,7 @@ def __init__(self): INPUT: - - ``z`` -- a complex number `z = a + ib`. + - ``z`` -- a complex number `z = a + ib` OUTPUT: @@ -989,7 +989,6 @@ def _evalf_(self, z, parent=None, algorithm=None): Traceback (most recent call last): ... ValueError: invalid attempt to numerically evaluate exp_polar() - """ if (not isinstance(z, Expression) and bool(-const_pi < imag(z) <= const_pi)): diff --git a/src/sage/functions/meson.build b/src/sage/functions/meson.build new file mode 100644 index 00000000000..c2a77f0e238 --- /dev/null +++ b/src/sage/functions/meson.build @@ -0,0 +1,37 @@ +py.install_sources( + 'airy.py', + 'all.py', + 'bessel.py', + 'error.py', + 'exp_integral.py', + 'gamma.py', + 'generalized.py', + 'hyperbolic.py', + 'hypergeometric.py', + 'jacobi.py', + 'log.py', + 'min_max.py', + 'orthogonal_polys.py', + 'other.py', + 'piecewise.py', + 'special.py', + 'spike_function.py', + 'transcendental.py', + 'trig.py', + 'wigner.py', + subdir: 'sage/functions', +) + +extension_data = {'prime_pi' : files('prime_pi.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/functions', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 70514cc3f44..4bf17b6c049 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -811,7 +811,7 @@ def eval_formula(self, n, x): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``x`` -- a value to evaluate the polynomial at (this can be any ring element) @@ -852,7 +852,7 @@ def eval_algebraic(self, n, x): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``x`` -- a value to evaluate the polynomial at (this can be any ring element) @@ -1035,7 +1035,7 @@ def eval_formula(self, n, x): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``x`` -- a value to evaluate the polynomial at (this can be any ring element) @@ -1072,7 +1072,7 @@ def eval_algebraic(self, n, x): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - ``x`` -- a value to evaluate the polynomial at (this can be any ring element) @@ -1612,7 +1612,7 @@ class Func_assoc_legendre_P(BuiltinFunction): EXAMPLES: - We give the first Ferrers functions for non-negative integers + We give the first Ferrers functions for nonnegative integers `n` and `m` in the interval `-1-x on (-2, 0), x|-->x on [0, 4]; x)' """ s = 'piecewise(' - args = [] - for domain, func in parameters: - args.append('{0}|-->{1} on {2}'.format(str(variable), str(func), str(domain))) - s += ', '.join(args) + '; {0})'.format(str(variable)) + # NOTE : could use ⟼ instead of |--> + args = (f'{variable}|-->{func} on {domain}' + for domain, func in parameters) + s += ', '.join(args) + f'; {variable})' return s def _subs_(self, subs_map, options, parameters, x): """ - Callback from Pynac `subs()` + Callback from Pynac ``subs()``. EXAMPLES: @@ -211,39 +209,43 @@ def _subs_(self, subs_map, options, parameters, x): piecewise(x|-->-x^y on (-2, 0), x|-->x - y on [0, 2]; x) sage: p.subs(y=sin(y)) piecewise(x|-->-x^sin(y) on (-2, 0), x|-->x - sin(y) on [0, 2]; x) + + One can change the variable as follows:: + + sage: p = piecewise([((-2, 0), -x), ([0, 4], x)], var=x) + sage: y = SR.var('y') + sage: p(y) + piecewise(y|-->-y on (-2, 0), y|-->y on [0, 4]; y) """ point = subs_map.apply_to(x, 0) - if ((point.is_numeric() or point.is_constant()) and (point.is_real())): + + if point.is_symbol(): # avoid to compare with x (see #37925) + new_params = [(domain, subs_map.apply_to(func, 0)) + for domain, func in parameters] + return piecewise(new_params, var=point) + + if (point.is_numeric() or point.is_constant()) and point.is_real(): if hasattr(point, 'pyobject'): # unwrap any numeric values point = point.pyobject() - elif point == x: # this comparison may be very slow (see #37925) - # substitution only in auxiliary variables - new_params = [] for domain, func in parameters: - new_params.append((domain, subs_map.apply_to(func, 0))) - return piecewise(new_params, var=x) - else: - raise ValueError('substituting the piecewise variable must result in real number') + if domain.contains(point): + return subs_map.apply_to(func, 0) + raise ValueError(f'point {point} is not in the domain') - for domain, func in parameters: - if domain.contains(point): - return subs_map.apply_to(func, 0) - raise ValueError('point {} is not in the domain'.format(point)) + raise ValueError('substitution not allowed') @staticmethod def in_operands(ex): """ Return whether a symbolic expression contains a piecewise - function as operand + function as operand. INPUT: - - ``ex`` -- a symbolic expression. + - ``ex`` -- a symbolic expression - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -257,20 +259,22 @@ def in_operands(ex): False """ def is_piecewise(ex): - result = ex.operator() is piecewise + if ex.operator() is piecewise: + return True for op in ex.operands(): - result = result or is_piecewise(op) - return result + if is_piecewise(op): + return True + return False return is_piecewise(ex) @staticmethod def simplify(ex): """ - Combine piecewise operands into single piecewise function + Combine piecewise operands into single piecewise function. OUTPUT: - A piecewise function whose operands are not piecewiese if + A piecewise function whose operands are not piecewise if possible, that is, as long as the piecewise variable is the same. EXAMPLES:: @@ -315,7 +319,7 @@ def _tderivative_(self, parameters, variable, *args, **kwds): for domain, func in parameters], var=variable) - class EvaluationMethods(): + class EvaluationMethods: def __pow__(self, parameters, variable, n): """ @@ -340,11 +344,11 @@ def __pow__(self, parameters, variable, n): def expression_at(self, parameters, variable, point): """ Return the expression defining the piecewise function at - ``value`` + ``value``. INPUT: - - ``point`` -- a real number. + - ``point`` -- a real number OUTPUT: @@ -373,7 +377,7 @@ def expression_at(self, parameters, variable, point): def domains(self, parameters, variable): """ - Return the individual domains + Return the individual domains. See also :meth:`~expressions`. @@ -393,7 +397,7 @@ def domains(self, parameters, variable): def domain(self, parameters, variable): """ - Return the domain + Return the domain. OUTPUT: @@ -414,11 +418,9 @@ def domain(self, parameters, variable): def __len__(self, parameters, variable): """ - Return the number of "pieces" - - OUTPUT: + Return the number of "pieces". - Integer. + OUTPUT: integer EXAMPLES:: @@ -431,13 +433,11 @@ def __len__(self, parameters, variable): def expressions(self, parameters, variable): """ - Return the individual domains + Return the individual domains. See also :meth:`~domains`. - OUTPUT: - - The collection of expressions of the component functions. + OUTPUT: the collection of expressions of the component functions EXAMPLES:: @@ -450,7 +450,7 @@ def expressions(self, parameters, variable): def items(self, parameters, variable): """ - Iterate over the pieces of the piecewise function + Iterate over the pieces of the piecewise function. .. NOTE:: @@ -476,7 +476,7 @@ def items(self, parameters, variable): def __call__(self, parameters, variable, value=None, **kwds): """ - Call the piecewise function + Call the piecewise function. EXAMPLES:: @@ -501,7 +501,7 @@ def __call__(self, parameters, variable, value=None, **kwds): def _fast_callable_(self, parameters, variable, etb): """ - Override the ``fast_callable`` + Override the ``fast_callable``. OUTPUT: @@ -522,7 +522,7 @@ def _fast_callable_(self, parameters, variable, etb): def restriction(self, parameters, variable, restricted_domain): """ - Restrict the domain + Restrict the domain. INPUT: @@ -530,9 +530,7 @@ def restriction(self, parameters, variable, restricted_domain): :class:`~sage.sets.real_set.RealSet` or something that defines one. - OUTPUT: - - A new piecewise function obtained by restricting the domain. + OUTPUT: a new piecewise function obtained by restricting the domain EXAMPLES:: @@ -550,7 +548,7 @@ def restriction(self, parameters, variable, restricted_domain): def extension(self, parameters, variable, extension, extension_domain=None): """ - Extend the function + Extend the function. INPUT: @@ -602,8 +600,10 @@ def unextend_zero(self, parameters, variable): sage: bool(h == f) True """ - result = [(domain, func) for domain,func in parameters + result = [(domain, func) for domain, func in parameters if func != 0] + if len(result) == len(self): + return self return piecewise(result, var=variable) def pieces(self, parameters, variable): @@ -622,12 +622,10 @@ def pieces(self, parameters, variable): (piecewise(x|-->-x on (-1, 0); x), piecewise(x|-->x on [0, 1]; x)) """ - result = [] - for domain, func in parameters: - result.append(piecewise([(domain, func)], var=variable)) - return tuple(result) + return tuple(piecewise([(domain, func)], var=variable) + for domain, func in parameters) - def end_points(self, parameters, variable): + def end_points(self, parameters, variable) -> list: """ Return a list of all interval endpoints for this function. @@ -683,14 +681,14 @@ def piecewise_add(self, parameters, variable, other): other.domain().contains(points[i+1])) if contains_lower: if contains_upper: - rs = RealSet.closed(points[i],points[i+1]) + rs = RealSet.closed(points[i], points[i+1]) else: - rs = RealSet.closed_open(points[i],points[i+1]) + rs = RealSet.closed_open(points[i], points[i+1]) else: if contains_upper: - rs = RealSet.open_closed(points[i],points[i+1]) + rs = RealSet.open_closed(points[i], points[i+1]) else: - rs = RealSet.open(points[i],points[i+1]) + rs = RealSet.open(points[i], points[i+1]) point = (points[i+1] + points[i])/2 except ValueError: if points[i] == minus_infinity and points[i+1] == infinity: @@ -838,9 +836,9 @@ def integral(self, parameters, variable, x=None, a=None, b=None, definite=False, Check that the algorithm keyword can be used:: sage: ex = piecewise([([0, 1], 1), ((1, oo), 1/x**2)]) - sage: integral(ex, x, 0, 100, algorithm='giac') + sage: integral(ex, x, 0, 100, algorithm='sympy') 199/100 - sage: integral(ex, x, algorithm='giac') + sage: integral(ex, x, algorithm='sympy') piecewise(x|-->x on [0, 1], x|-->-1/x + 2 on (1, +oo); x) """ if a is not None and b is not None: @@ -880,7 +878,7 @@ def integral(self, parameters, variable, x=None, a=None, b=None, definite=False, else: try: assume(start < x) - except ValueError: # Assumption is redundant + except ValueError: # Assumption is redundant pass fun_integrated = fun.integral(x, start, x, **kwds) + area forget(start < x) @@ -984,6 +982,17 @@ def convolution(self, parameters, variable, other): x|-->-x + 6 on (3, 4], x|-->-2*x + 10 on (4, 5]; x) + Some unbounded but convergent cases now work:: + + sage: p = piecewise([[(2,oo),exp(-x)]]) + sage: q = piecewise([[[2,3],x]]) + sage: p.convolution(q) + piecewise(x|-->(x - 3)*e^(-2) - e^(-x + 2) on (4, 5]; x) + sage: q.convolution(p) + piecewise(x|-->(x - 3)*e^(-2) - e^(-x + 2) on (4, 5]; x) + + TESTS: + Check that the bugs raised in :issue:`12123` are fixed:: sage: f = piecewise([[(-2, 2), 2]]) @@ -1002,44 +1011,61 @@ def convolution(self, parameters, variable, other): from sage.symbolic.integration.integral import definite_integral f = self g = other - if len(f.end_points())*len(g.end_points()) == 0: + if not f.end_points() or not g.end_points(): raise ValueError('one of the piecewise functions is nowhere defined') fd, f0 = parameters[0] gd, g0 = next(other.items()) - if len(f) == 1 and len(g) == 1: - f = f.unextend_zero() - g = g.unextend_zero() + if len(f) == 1 == len(g): a1 = fd[0].lower() a2 = fd[0].upper() b1 = gd[0].lower() b2 = gd[0].upper() - with SR.temp_var() as tt: - with SR.temp_var() as uu: - i1 = f0.subs({variable: uu}) - i2 = g0.subs({variable: tt-uu}) - fg1 = definite_integral(i1*i2, uu, a1, tt-b1).subs({tt:variable}) - fg2 = definite_integral(i1*i2, uu, tt-b2, tt-b1).subs({tt:variable}) - fg3 = definite_integral(i1*i2, uu, tt-b2, a2).subs({tt:variable}) - fg4 = definite_integral(i1*i2, uu, a1, a2).subs({tt:variable}) - if a1-b1 < a2-b2: - if a2+b1 != a1+b2: - h = piecewise([[(a1+b1,a1+b2),fg1],[(a1+b2,a2+b1),fg2],[(a2+b1,a2+b2),fg3]]) - else: - h = piecewise([[(a1+b1,a1+b2),fg1],[(a1+b2,a2+b2),fg3]]) + a1b1 = a1 + b1 + a2b2 = a2 + b2 + delta_a = a2 - a1 + delta_b = b2 - b1 + + # this fails in some unbounded cases: + a1b2 = a1 + b2 + a2b1 = a2 + b1 + + todo = [] + if delta_a > delta_b: + if a1b2 is not minus_infinity: + todo.append((a1b1, a1b2, a1, variable - b1)) + todo.append((a1b2, a2b1, variable - b2, variable - b1)) + if a2b1 is not infinity: + todo.append((a2b1, a2b2, variable - b2, a2)) + elif delta_a < delta_b: + if a2b1 is not minus_infinity: + todo.append((a1b1, a2b1, a1, variable - b1)) + todo.append((a2b1, a1b2, a1, a2)) + if a1b2 is not infinity: + todo.append((a1b2, a2b2, variable - b2, a2)) else: - if a1+b2 != a2+b1: - h = piecewise([[(a1+b1,a2+b1),fg1],[(a2+b1,a1+b2),fg4],[(a1+b2,a2+b2),fg3]]) - else: - h = piecewise([[(a1+b1,a2+b1),fg1],[(a2+b1,a2+b2),fg3]]) - return (piecewise([[(minus_infinity,infinity),0]]).piecewise_add(h)).unextend_zero() - - if len(f) > 1 or len(g) > 1: - z = piecewise([[(0,0),0]]) - for fpiece in f.pieces(): - for gpiece in g.pieces(): - h = gpiece.convolution(fpiece) - z = z.piecewise_add(h) - return z.unextend_zero() + if a2b1 is not minus_infinity: + todo.append((a1b1, a2b1, a1, variable - b1)) + todo.append((a2b1, a2b2, variable - b2, a2)) + + if not todo: + raise ValueError("no domain of integration") + + with SR.temp_var() as uu: + i1 = f0.subs({variable: uu}) + i2 = g0.subs({variable: variable - uu}) + expr = i1 * i2 + h = piecewise([[(start, stop), + definite_integral(expr, uu, mini, maxi)] + for start, stop, mini, maxi in todo]) + flat_zero = piecewise([[(minus_infinity, infinity), 0]]) + return (flat_zero.piecewise_add(h)).unextend_zero() # why ? + + z = piecewise([[(0, 0), 0]]) + for fpiece in f.pieces(): + for gpiece in g.pieces(): + h = gpiece.convolution(fpiece) + z = z.piecewise_add(h) + return z.unextend_zero() def trapezoid(self, parameters, variable, N): """ @@ -1079,8 +1105,8 @@ def trapezoid(self, parameters, variable, N): """ def func(x0, x1): f0, f1 = self(x0), self(x1) - return [[(x0,x1), f0 + (f1-f0) * (x1-x0)**(-1) - * (self.default_variable()-x0)]] + return [[(x0, x1), f0 + (f1-f0) * (x1-x0)**(-1) + * (self.default_variable()-x0)]] rsum = [] for domain, f in parameters: for interval in domain: @@ -1100,9 +1126,9 @@ def laplace(self, parameters, variable, x='x', s='t'): INPUT: - - ``x`` -- variable of ``self`` + - ``x`` -- variable of ``self`` - - ``s`` -- variable of Laplace transform. + - ``s`` -- variable of Laplace transform We assume that a piecewise function is 0 outside of its domain and that the left-most endpoint of the domain is 0. @@ -1144,7 +1170,7 @@ def laplace(self, parameters, variable, x='x', s='t'): for interval in domain: a = interval.lower() b = interval.upper() - result += (SR(f)*exp(-s*x)).integral(x,a,b) + result += (SR(f)*exp(-s*x)).integral(x, a, b) forget(s > 0) return result @@ -1171,15 +1197,13 @@ def fourier_series_cosine_coefficient(self, parameters, INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - ``L`` -- (default: ``None``) the half-period of `f`; if none is provided, `L` is assumed to be the half-width of the domain of ``self`` - OUTPUT: - - - the Fourier coefficient `a_n`, as defined above + OUTPUT: the Fourier coefficient `a_n`, as defined above EXAMPLES: @@ -1224,7 +1248,6 @@ def fourier_series_cosine_coefficient(self, parameters, sage: f = piecewise([[(-pi, pi/2), f1], [(pi/2, pi), f2]]) sage: f.fourier_series_cosine_coefficient(5, pi) -3/5/pi - """ from sage.functions.trig import cos from sage.symbolic.constants import pi @@ -1243,7 +1266,7 @@ def fourier_series_cosine_coefficient(self, parameters, a = interval.lower() b = interval.upper() result += (f*cos(pi*variable*n/L)).integrate(variable, a, b) - return SR(result/L0).simplify_trig() + return SR(result / L0).simplify_trig() def fourier_series_sine_coefficient(self, parameters, variable, n, L=None): @@ -1266,15 +1289,13 @@ def fourier_series_sine_coefficient(self, parameters, variable, INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - ``L`` -- (default: ``None``) the half-period of `f`; if none is provided, `L` is assumed to be the half-width of the domain of ``self`` - OUTPUT: - - - the Fourier coefficient `b_n`, as defined above + OUTPUT: the Fourier coefficient `b_n`, as defined above EXAMPLES: @@ -1315,7 +1336,6 @@ def fourier_series_sine_coefficient(self, parameters, variable, 4/pi sage: f2.fourier_series_sine_coefficient(6) 4/3/pi - """ from sage.functions.trig import sin from sage.symbolic.constants import pi @@ -1339,7 +1359,7 @@ def fourier_series_sine_coefficient(self, parameters, variable, def fourier_series_partial_sum(self, parameters, variable, N, L=None): r""" - Returns the partial sum up to a given order of the Fourier series + Return the partial sum up to a given order of the Fourier series of the periodic function `f` extending the piecewise-defined function ``self``. @@ -1359,7 +1379,7 @@ def fourier_series_partial_sum(self, parameters, variable, N, INPUT: - - ``N`` -- a positive integer; the order of the partial sum + - ``N`` -- positive integer; the order of the partial sum - ``L`` -- (default: ``None``) the half-period of `f`; if none is provided, `L` is assumed to be the half-width of the domain @@ -1404,7 +1424,6 @@ def fourier_series_partial_sum(self, parameters, variable, N, sage: f.fourier_series_partial_sum(5) -2*cos(2*pi*x)/pi^2 + 4/25*sin(5*pi*x)/pi^2 - 4/9*sin(3*pi*x)/pi^2 + 4*sin(pi*x)/pi^2 + 1/4 - """ from sage.symbolic.constants import pi from sage.functions.trig import cos, sin @@ -1451,16 +1470,18 @@ def _giac_init_(self, parameters, variable): EXAMPLES:: + sage: # needs giac sage: ex = piecewise([((0, 1), pi), ([1, 2], x)]) - sage: f = ex._giac_(); f # needs sage.libs.giac + sage: f = ex._giac_(); f piecewise(((sageVARx>0) and (1>sageVARx)),pi,((sageVARx>=1) and (2>=sageVARx)),sageVARx) - sage: f.diff(x) # needs sage.libs.giac + sage: f.diff(x) piecewise(((sageVARx>0) and (1>sageVARx)),0,((sageVARx>=1) and (2>=sageVARx)),1) - sage: ex = piecewise([((-100, -2), 1/x), ((1, +oo), cos(x))]) # needs sage.libs.giac - sage: g = ex._giac_(); g # needs sage.libs.giac + sage: # needs giac + sage: ex = piecewise([((-100, -2), 1/x), ((1, +oo), cos(x))]) + sage: g = ex._giac_(); g piecewise(((sageVARx>-100) and ((-2)>sageVARx)),1/sageVARx,sageVARx>1,cos(sageVARx)) - sage: g.diff(x) # needs sage.libs.giac + sage: g.diff(x) piecewise(((sageVARx>-100) and ((-2)>sageVARx)),-1/sageVARx^2,sageVARx>1,-sin(sageVARx)) TESTS:: diff --git a/src/sage/functions/prime_pi.pyx b/src/sage/functions/prime_pi.pyx index 2e4400af06e..216e2fb2321 100644 --- a/src/sage/functions/prime_pi.pyx +++ b/src/sage/functions/prime_pi.pyx @@ -49,14 +49,12 @@ cdef class PrimePi(BuiltinFunction): INPUT: - ``x`` -- a real number - - ``prime_bound`` -- (default 0) a real number < 2^32; :func:`prime_pi` will - make sure to use all the primes up to ``prime_bound`` (although, + - ``prime_bound`` -- (default: 0) a real number `< 2^32`; :func:`prime_pi` + will make sure to use all the primes up to ``prime_bound`` (although, possibly more) in computing ``prime_pi``, this can potentially speedup the time of computation, at a cost to memory usage. - OUTPUT: - - integer -- the number of primes :math:`\leq` ``x`` + OUTPUT: integer; the number of primes :math:`\leq` ``x`` EXAMPLES: @@ -84,7 +82,6 @@ cdef class PrimePi(BuiltinFunction): plots quickly and perfectly as a step function:: sage: P = plot(prime_pi, 50, 100) # needs sage.plot sage.symbolic - """ super(PrimePi, self).__init__('prime_pi', latex_name=r"\pi", conversions={'mathematica': 'PrimePi', @@ -220,12 +217,10 @@ cpdef Integer legendre_phi(x, a): - ``x`` -- a real number - - ``a`` -- a non-negative integer + - ``a`` -- nonnegative integer - OUTPUT: - - integer -- the number of positive integers :math:`\leq` ``x`` that are not - divisible by the first ``a`` primes + OUTPUT: integer; the number of positive integers :math:`\leq` ``x`` that + are not divisible by the first ``a`` primes EXAMPLES:: @@ -237,12 +232,11 @@ cpdef Integer legendre_phi(x, a): 2893 sage: legendre_phi(4215701455, 6450023226) 1 - """ if not isinstance(a, Integer): a = Integer(a) if a < Integer(0): - raise ValueError("a (=%s) must be non-negative" % a) + raise ValueError("a (=%s) must be nonnegative" % a) y = Integer(x) # legendre_phi(x, a) = 0 when x <= 0 diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index e100ba3ee23..308171af3cd 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -166,7 +166,7 @@ class SphericalHarmonic(BuiltinFunction): r""" - Returns the spherical harmonic function `Y_n^m(\theta, \varphi)`. + Return the spherical harmonic function `Y_n^m(\theta, \varphi)`. For integers `n > -1`, `|m| \leq n`, simplification is done automatically. Numeric evaluation is supported for complex `n` and `m`. @@ -217,6 +217,9 @@ class SphericalHarmonic(BuiltinFunction): sage: spherical_harmonic(1, 1, pi/2, pi).n() # abs tol 1e-14 # needs sage.symbolic 0.345494149471335 sage: from scipy.special import sph_harm # NB: arguments x and y are swapped # needs scipy + sage: import numpy as np # needs scipy + sage: if int(np.version.short_version[0]) > 1: # needs scipy + ....: np.set_printoptions(legacy="1.25") # needs scipy sage: sph_harm(1, 1, pi.n(), (pi/2).n()) # abs tol 1e-14 # needs scipy sage.symbolic (0.3454941494713355-4.231083042742082e-17j) @@ -233,7 +236,6 @@ class SphericalHarmonic(BuiltinFunction): REFERENCES: - :wikipedia:`Spherical_harmonics` - """ def __init__(self): r""" @@ -295,7 +297,6 @@ def _eval_(self, n, m, theta, phi, **kwargs): -1/4*sqrt(6)*sqrt(5)*cos(x)*e^(I*y)*sin(x)/sqrt(pi) sage: spherical_harmonic(5, -3, x, y) # needs sage.symbolic -1/32*(9*sqrt(385)*sin(x)^4 - 8*sqrt(385)*sin(x)^2)*e^(-3*I*y)*sin(x)/sqrt(pi) - """ if n in ZZ and m in ZZ and n > -1: if abs(m) > n: @@ -327,7 +328,6 @@ def _evalf_(self, n, m, theta, phi, parent, **kwds): sage: ab = [(0, 0), (1, -1), (1, 0), (1, 1), (3, 2), (3, 3)] sage: all(d(a, b) < 1e-14 for a, b in ab) # needs sage.symbolic True - """ return _mpmath_utils_call(_mpmath_spherharm, n, m, theta, phi, parent=parent) @@ -357,7 +357,6 @@ def _derivative_(self, n, m, theta, phi, diff_param): True sage: bool(DY_theta.subs({n: 1, m: -1}) == Ynm.subs({n: 1, m: -1}).diff(theta)) True - """ if diff_param == 2: return (m * cot(theta) * spherical_harmonic(n, m, theta, phi) + @@ -397,17 +396,15 @@ def _print_latex_(self, n, m, theta, phi): def elliptic_j(z, prec=53): r""" - Returns the elliptic modular `j`-function evaluated at `z`. + Return the elliptic modular `j`-function evaluated at `z`. INPUT: - - ``z`` (complex) -- a complex number with positive imaginary part. + - ``z`` -- complex; a complex number with positive imaginary part - - ``prec`` (default: 53) -- precision in bits for the complex field. + - ``prec`` -- (default: 53) precision in bits for the complex field - OUTPUT: - - (complex) The value of `j(z)`. + OUTPUT: (complex) the value of `j(z)` ALGORITHM: @@ -535,7 +532,6 @@ def __init__(self): 0.000000000000000, 0.000000000000000, 0.000000000000000] - """ BuiltinFunction.__init__(self, 'elliptic_e', nargs=2, # Maple conversion left out since it uses @@ -901,7 +897,6 @@ def __init__(self): 0.000000000000000, 0.000000000000000, 0.000000000000000] - """ BuiltinFunction.__init__(self, 'elliptic_f', nargs=2, conversions=dict(mathematica='EllipticF', diff --git a/src/sage/functions/spike_function.py b/src/sage/functions/spike_function.py index c2fb6113e39..6fa011434d8 100644 --- a/src/sage/functions/spike_function.py +++ b/src/sage/functions/spike_function.py @@ -32,13 +32,11 @@ class SpikeFunction: INPUT: - - ``v`` -- list of pairs (x, height) + - ``v`` -- list of pairs (x, height) - - ``eps`` -- parameter that determines approximation to a true spike + - ``eps`` -- parameter that determines approximation to a true spike - OUTPUT: - - a function with spikes at each point ``x`` in ``v`` with the given height. + OUTPUT: a function with spikes at each point ``x`` in ``v`` with the given height EXAMPLES:: @@ -149,7 +147,7 @@ def __call__(self, x): """ return self._eval(x)[0] - def plot_fft_abs(self, samples=2**12, xmin=None, xmax=None, **kwds): + def plot_fft_abs(self, samples=2**12, xmin=None, xmax=None, **kwds): """ Plot of (absolute values of) Fast Fourier Transform of the spike function with given number of samples. @@ -168,7 +166,7 @@ def plot_fft_abs(self, samples=2**12, xmin=None, xmax=None, **kwds): k = vector(RDF, [abs(z[i]) for i in range(len(z)//2)]) return k.plot(xmin=0, xmax=1, **kwds) - def plot_fft_arg(self, samples=2**12, xmin=None, xmax=None, **kwds): + def plot_fft_arg(self, samples=2**12, xmin=None, xmax=None, **kwds): """ Plot of (absolute values of) Fast Fourier Transform of the spike function with given number of samples. diff --git a/src/sage/functions/transcendental.py b/src/sage/functions/transcendental.py index 3dcb446e706..7cfa2640473 100644 --- a/src/sage/functions/transcendental.py +++ b/src/sage/functions/transcendental.py @@ -44,7 +44,7 @@ def __init__(self): INPUT: - - ``s`` -- real or complex number + - ``s`` -- real or complex number If s is a real number, the computation is done using the MPFR library. When the input is not real, the computation is done using @@ -173,7 +173,7 @@ def __init__(self): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -305,7 +305,7 @@ def hurwitz_zeta(s, x, **kwargs): When `x = 1`, this coincides with Riemann's zeta function. - The Dirichlet L-functions may be expressed as linear combinations + The Dirichlet `L`-functions may be expressed as linear combinations of Hurwitz zeta functions. EXAMPLES: @@ -378,7 +378,7 @@ def __init__(self): zetaderiv([1.500000000 +/- 1.01e-10], 1) """ GinacFunction.__init__(self, "zetaderiv", nargs=2, - conversions=dict(maple="Zeta")) + conversions=dict(maple='Zeta')) def _evalf_(self, n, x, parent=None, algorithm=None): r""" @@ -412,9 +412,7 @@ def zeta_symmetric(s): INPUT: - - - ``s`` -- real or complex number - + - ``s`` -- real or complex number If s is a real number the computation is done using the MPFR library. When the input is not real, the computation is done using @@ -426,7 +424,6 @@ def zeta_symmetric(s): xi(s) = \gamma(s/2 + 1) * (s-1) * \pi^{-s/2} * \zeta(s). - EXAMPLES:: sage: # needs sage.rings.real_mpfr @@ -518,7 +515,7 @@ class DickmanRho(BuiltinFunction): """ def __init__(self): """ - Constructs an object to represent Dickman's rho function. + Construct an object to represent Dickman's rho function. TESTS:: @@ -574,11 +571,11 @@ def power_series(self, n, abs_prec): INPUT: - - ``n`` -- the lower endpoint of the interval for which - this power series holds + - ``n`` -- the lower endpoint of the interval for which + this power series holds - - ``abs_prec`` -- the absolute precision of the - resulting power series + - ``abs_prec`` -- the absolute precision of the + resulting power series EXAMPLES:: @@ -602,14 +599,14 @@ def _compute_power_series(self, n, abs_prec, cache_ring=None): INPUT: - - ``n`` -- the lower endpoint of the interval for which - this power series holds + - ``n`` -- the lower endpoint of the interval for which + this power series holds - - ``abs_prec`` -- the absolute precision of the - resulting power series + - ``abs_prec`` -- the absolute precision of the + resulting power series - - ``cache_ring`` -- for internal use, caches the power - series at this precision. + - ``cache_ring`` -- for internal use, caches the power + series at this precision EXAMPLES:: @@ -653,7 +650,7 @@ def _compute_power_series(self, n, abs_prec, cache_ring=None): def approximate(self, x, parent=None): r""" - Approximate using de Bruijn's formula + Approximate using de Bruijn's formula. .. MATH:: diff --git a/src/sage/functions/trig.py b/src/sage/functions/trig.py index b767fbbd5d4..f912dd79e8f 100644 --- a/src/sage/functions/trig.py +++ b/src/sage/functions/trig.py @@ -572,7 +572,7 @@ def __init__(self): GinacFunction.__init__(self, 'arcsin', latex_name=r"\arcsin", conversions=dict(maxima='asin', sympy='asin', mathematica='ArcSin', - fricas="asin", giac="asin")) + fricas='asin', giac='asin')) arcsin = asin = Function_arcsin() @@ -762,7 +762,6 @@ def __init__(self): (0.5535743588970452-0.4023594781085251j) sage: arccot(1.+I) # needs sage.symbolic 0.553574358897045 - 0.402359478108525*I - """ GinacFunction.__init__(self, 'arccot', latex_name=r"\operatorname{arccot}", conversions=dict(maxima='acot', sympy='acot', @@ -927,7 +926,6 @@ def __init__(self): Note that the `y`-coordinate is by convention the first input. - EXAMPLES: Note the difference between the two functions:: diff --git a/src/sage/functions/wigner.py b/src/sage/functions/wigner.py index 5a19010f073..e177fc1287b 100644 --- a/src/sage/functions/wigner.py +++ b/src/sage/functions/wigner.py @@ -44,11 +44,9 @@ def _calc_factlist(nn): INPUT: - - ``nn`` -- integer, highest factorial to be computed + - ``nn`` -- integer; highest factorial to be computed - OUTPUT: - - list of integers -- the list of precomputed factorials + OUTPUT: list of integers -- the list of precomputed factorials EXAMPLES: @@ -70,10 +68,10 @@ def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3, prec=None): INPUT: - - ``j_1``, ``j_2``, ``j_3``, ``m_1``, ``m_2``, ``m_3`` -- integer or half integer + - ``j_1``, ``j_2``, ``j_3``, ``m_1``, ``m_2``, ``m_3`` -- integer or half integer - - ``prec`` -- precision, default: ``None``. Providing a precision can - drastically speed up the calculation. + - ``prec`` -- precision (default: ``None``); providing a precision can + drastically speed up the calculation OUTPUT: @@ -215,10 +213,10 @@ def clebsch_gordan(j_1, j_2, j_3, m_1, m_2, m_3, prec=None): INPUT: - - ``j_1``, ``j_2``, ``j_3``, ``m_1``, ``m_2``, ``m_3`` -- integer or half integer + - ``j_1``, ``j_2``, ``j_3``, ``m_1``, ``m_2``, ``m_3`` -- integer or half integer - - ``prec`` -- precision, default: ``None``. Providing a precision can - drastically speed up the calculation. + - ``prec`` -- precision (default: ``None``); providing a precision can + drastically speed up the calculation OUTPUT: @@ -264,17 +262,15 @@ def _big_delta_coeff(aa, bb, cc, prec=None): INPUT: - - ``aa`` -- first angular momentum, integer or half integer + - ``aa`` -- first angular momentum, integer or half integer - - ``bb`` -- second angular momentum, integer or half integer + - ``bb`` -- second angular momentum, integer or half integer - - ``cc`` -- third angular momentum, integer or half integer + - ``cc`` -- third angular momentum, integer or half integer - - ``prec`` -- precision of the ``sqrt()`` calculation - - OUTPUT: + - ``prec`` -- precision of the ``sqrt()`` calculation - double - Value of the Delta coefficient + OUTPUT: double - Value of the Delta coefficient EXAMPLES:: @@ -317,10 +313,10 @@ def racah(aa, bb, cc, dd, ee, ff, prec=None): INPUT: - - ``aa``, ..., ``ff`` -- integer or half integer + - ``aa``, ..., ``ff`` -- integer or half integer - - ``prec`` -- precision, default: ``None``. Providing a precision can - drastically speed up the calculation. + - ``prec`` -- precision (default: ``None``); providing a precision can + drastically speed up the calculation OUTPUT: @@ -390,10 +386,10 @@ def wigner_6j(j_1, j_2, j_3, j_4, j_5, j_6, prec=None): INPUT: - - ``j_1``, ..., ``j_6`` -- integer or half integer + - ``j_1``, ..., ``j_6`` -- integer or half integer - - ``prec`` -- precision, default: ``None``. Providing a precision can - drastically speed up the calculation. + - ``prec`` -- precision (default: ``None``); providing a precision can + drastically speed up the calculation OUTPUT: @@ -465,7 +461,7 @@ def wigner_6j(j_1, j_2, j_3, j_4, j_5, j_6, prec=None): - additional 6 symmetries [Reg1959]_ giving rise to 144 symmetries in total - - only non-zero if any triple of `j`'s fulfill a triangle relation + - only nonzero if any triple of `j`'s fulfill a triangle relation ALGORITHM: @@ -487,10 +483,10 @@ def wigner_9j(j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9, prec=None): INPUT: - - ``j_1``, ..., ``j_9`` -- integer or half integer + - ``j_1``, ..., ``j_9`` -- integer or half integer - - ``prec`` -- precision, default: ``None``. Providing a precision can - drastically speed up the calculation. + - ``prec`` -- precision (default: ``None``); providing a precision can + drastically speed up the calculation OUTPUT: @@ -578,10 +574,10 @@ def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None): INPUT: - - ``l_1``, ``l_2``, ``l_3``, ``m_1``, ``m_2``, ``m_3`` -- integer + - ``l_1``, ``l_2``, ``l_3``, ``m_1``, ``m_2``, ``m_3`` -- integer - - ``prec`` -- precision, default: ``None``. Providing a precision can - drastically speed up the calculation. + - ``prec`` -- precision (default: ``None``); providing a precision can + drastically speed up the calculation OUTPUT: @@ -660,7 +656,7 @@ def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None): - zero for violating any one of the conditions: `l_1 \ge |m_1|`, `l_2 \ge |m_2|`, `l_3 \ge |m_3|` - - non-zero only for an even sum of the `l_i`, i.e. + - nonzero only for an even sum of the `l_i`, i.e. `J=l_1+l_2+l_3=2n` for `n` in `\Bold{N}` ALGORITHM: diff --git a/src/sage/game_theory/catalog_normal_form_games.py b/src/sage/game_theory/catalog_normal_form_games.py index ab7b48a4dc0..705957f079e 100644 --- a/src/sage/game_theory/catalog_normal_form_games.py +++ b/src/sage/game_theory/catalog_normal_form_games.py @@ -128,7 +128,6 @@ def PrisonersDilemma(R=-2, P=-4, S=-5, T=0): ... TypeError: the input values for a Prisoners Dilemma must be of the form T > R > P > S - """ if not (T > R > P > S): raise TypeError("the input values for a Prisoners Dilemma must be of the form T > R > P > S") @@ -319,7 +318,6 @@ def StagHunt(): True sage: g.obtain_nash() [[(0, 1), (0, 1)], [(2/3, 1/3), (2/3, 1/3)], [(1, 0), (1, 0)]] - """ g = CoordinationGame(A=5, a=5, B=4, b=0, C=0, c=4, D=2, d=2) g.rename('Stag hunt - ' + repr(g)) @@ -550,7 +548,6 @@ def Pigs(): True sage: g.obtain_nash() [[(1, 0), (0, 1)]] - """ from sage.matrix.constructor import matrix A = matrix([[3, 1], [6, 0]]) @@ -915,7 +912,6 @@ def TravellersDilemma(max_value=10): True sage: g.obtain_nash() [[(0, 0, 0, 1), (0, 0, 0, 1)]] - """ from sage.matrix.constructor import matrix from sage.functions.generalized import sign diff --git a/src/sage/game_theory/cooperative_game.py b/src/sage/game_theory/cooperative_game.py index b95ba0f655a..c9253d2bbb0 100644 --- a/src/sage/game_theory/cooperative_game.py +++ b/src/sage/game_theory/cooperative_game.py @@ -33,7 +33,7 @@ class CooperativeGame(SageObject): INPUT: - - ``characteristic_function`` -- a dictionary containing all possible + - ``characteristic_function`` -- dictionary containing all possible sets of players: * key - each set must be entered as a tuple. @@ -254,7 +254,7 @@ class CooperativeGame(SageObject): """ def __init__(self, characteristic_function): r""" - Initializes a co-operative game and checks the inputs. + Initialize a co-operative game and checks the inputs. TESTS: @@ -616,7 +616,7 @@ def is_efficient(self, payoff_vector): INPUT: - - ``payoff_vector`` -- a dictionary where the key is the player + - ``payoff_vector`` -- dictionary where the key is the player and the value is their payoff EXAMPLES: @@ -684,7 +684,7 @@ def nullplayer(self, payoff_vector): INPUT: - - ``payoff_vector`` -- a dictionary where the key is the player + - ``payoff_vector`` -- dictionary where the key is the player and the value is their payoff EXAMPLES: @@ -775,7 +775,7 @@ def is_symmetric(self, payoff_vector): INPUT: - - ``payoff_vector`` -- a dictionary where the key is the player + - ``payoff_vector`` -- dictionary where the key is the player and the value is their payoff EXAMPLES: diff --git a/src/sage/game_theory/matching_game.py b/src/sage/game_theory/matching_game.py index 8efa2c2acfa..7a51988baec 100644 --- a/src/sage/game_theory/matching_game.py +++ b/src/sage/game_theory/matching_game.py @@ -73,7 +73,7 @@ class MatchingGame(SageObject): Two potential inputs are accepted (see below to see the effect of each): - - ``reviewer/suitors_preferences`` -- a dictionary containing the + - ``reviewer/suitors_preferences`` -- dictionary containing the preferences of all players: * key - each reviewer/suitors @@ -81,8 +81,8 @@ class MatchingGame(SageObject): OR: - - ``integer`` -- an integer simply representing the number of reviewers - and suitors. + - ``integer`` -- integer simply representing the number of reviewers + and suitors To implement the above game in Sage:: @@ -939,7 +939,7 @@ def solve(self, invert=False): return {key: self._sol_dict[key][0] for key in self._suitors} -class Player(): +class Player: r""" A class to act as a data holder for the players used of the matching games. @@ -1025,7 +1025,7 @@ def __eq__(self, other): def __lt__(self, other): """ - Tests less than inequality of two players. Allows for players to be + Test less than inequality of two players. Allows for players to be sorted on their names. TESTS:: @@ -1051,7 +1051,7 @@ def __lt__(self, other): def __gt__(self, other): """ - Tests greater than inequality of two players. Allows for players to be + Test greater than inequality of two players. Allows for players to be sorted on their names. TESTS:: @@ -1077,7 +1077,7 @@ def __gt__(self, other): def __ge__(self, other): """ - Tests greater than or equal inequality of two players. Allows for + Test greater than or equal inequality of two players. Allows for players to be sorted on their names. TESTS:: @@ -1113,7 +1113,7 @@ def __ge__(self, other): def __le__(self, other): """ - Tests less than or equal inequality of two players. Allows for + Test less than or equal inequality of two players. Allows for players to be sorted on their names. TESTS:: @@ -1149,7 +1149,7 @@ def __le__(self, other): def __ne__(self, other): """ - Tests inequality of two players. Allows for + Test inequality of two players. Allows for players to be sorted on their names. TESTS:: diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index 2b1e592c4e8..e46e96c2b32 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -665,12 +665,11 @@ class NormalFormGame(SageObject, MutableMapping): - ``generator`` -- can be a list of 2 matrices, a single matrix or left blank - """ def __init__(self, generator=None): r""" - Initializes a Normal Form game and checks the inputs. + Initialize a Normal Form game and checks the inputs. EXAMPLES: @@ -763,7 +762,6 @@ def __init__(self, generator=None): sage: game = NormalFormGame() sage: game Normal Form Game with the following utilities: {} - """ self.players = [] self.utilities = {} @@ -971,7 +969,7 @@ def _two_matrix_game(self, matrices): def _gambit_game(self, game): r""" - Creates a ``NormalFormGame`` object from a Gambit game. + Create a ``NormalFormGame`` object from a Gambit game. TESTS:: @@ -1004,7 +1002,7 @@ def _gambit_game(self, game): def _gambit_(self, as_integer=False, maximization=True): r""" - Creates a Gambit game from a ``NormalFormGame`` object + Create a Gambit game from a ``NormalFormGame`` object. INPUT: @@ -1165,7 +1163,7 @@ def _gambit_(self, as_integer=False, maximization=True): def is_constant_sum(self): r""" - Checks if the game is constant sum. + Check if the game is constant sum. EXAMPLES:: @@ -1294,7 +1292,7 @@ def _generate_utilities(self, replacement): INPUT: - - ``replacement`` -- Boolean value of whether previously created + - ``replacement`` -- boolean value of whether previously created profiles should be replaced or not TESTS:: @@ -1367,7 +1365,6 @@ def add_strategy(self, player): (1, 1): [3, 0], (2, 0): [False, False], (2, 1): [False, False]} - """ self.players[player].add_strategy() self._generate_utilities(False) @@ -1404,17 +1401,17 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): - ``algorithm`` -- the following algorithms should be available through this function: - * ``'lrs'`` -- This algorithm is only suited for 2 player games. + * ``'lrs'`` -- this algorithm is only suited for 2 player games. See the lrs web site (http://cgm.cs.mcgill.ca/~avis/C/lrs.html). - * ``'LCP'`` -- This algorithm is only suited for 2 player games. + * ``'LCP'`` -- this algorithm is only suited for 2 player games. See the gambit web site (http://gambit.sourceforge.net/). - * ``'lp'`` -- This algorithm is only suited for 2 player + * ``'lp'`` -- this algorithm is only suited for 2 player constant sum games. Uses MILP solver determined by the ``solver`` argument. - * ``'enumeration'`` -- This is a very inefficient + * ``'enumeration'`` -- this is a very inefficient algorithm (in essence a brute force approach). 1. For each k in 1...min(size of strategy sets) @@ -1453,7 +1450,7 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): \sum_{j\in S(\rho_1)}{\rho_2}_j = 1 - - ``maximization`` -- (default: ``True``) whether a player is + - ``maximization`` -- boolean (default: ``True``); whether a player is trying to maximize their utility or minimize it: * When set to ``True`` it is assumed that players aim to @@ -1589,7 +1586,7 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): [[(0, 0, 1, 0), (0, 0, 1)]] Running the constant-sum solver on a game which is not a constant sum - game generates a :class:`ValueError`:: + game generates a :exc:`ValueError`:: sage: cg = NormalFormGame([A, A]) sage: cg.obtain_nash(algorithm='lp', solver='glpk') @@ -1665,11 +1662,11 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): sage: A = matrix.identity(2) sage: g = NormalFormGame([A]) - sage: g.obtain_nash(algorithm="invalid") + sage: g.obtain_nash(algorithm='invalid') Traceback (most recent call last): ... ValueError: 'algorithm' should be set to 'enumeration', 'LCP', 'lp' or 'lrs' - sage: g.obtain_nash(algorithm="lp", solver="invalid") + sage: g.obtain_nash(algorithm='lp', solver='invalid') Traceback (most recent call last): ... ValueError: 'solver' should be set to 'GLPK', ..., None @@ -1823,7 +1820,7 @@ def _solve_gambit_LP(self, maximization=True): def _solve_LP(self, solver='glpk', maximization=True): r""" - Solves a constant sum :class:`NormalFormGame` using + Solve a constant sum :class:`NormalFormGame` using the specified LP solver. INPUT: @@ -2284,7 +2281,6 @@ def _Hrepresentation(self, m1, m2): -1 1 1 0 end - """ from sage.misc.superseded import deprecation deprecation(27745, @@ -2605,7 +2601,7 @@ def best_responses(self, strategy, player): - ``strategy`` -- a probability distribution vector - ``player`` -- the index of the opponent, ``0`` for the row player, - ``1`` for the column player. + ``1`` for the column player EXAMPLES:: @@ -2726,7 +2722,7 @@ def best_responses(self, strategy, player): def _is_degenerate_pure(self, certificate=False): """ - Checks whether a game is degenerate in pure strategies. + Check whether a game is degenerate in pure strategies. TESTS:: @@ -2787,7 +2783,7 @@ def _is_degenerate_pure(self, certificate=False): return False -class _Player(): +class _Player: def __init__(self, num_strategies): r""" TESTS:: diff --git a/src/sage/game_theory/parser.py b/src/sage/game_theory/parser.py index d528116f244..6ab62d5b7ff 100644 --- a/src/sage/game_theory/parser.py +++ b/src/sage/game_theory/parser.py @@ -13,7 +13,7 @@ # **************************************************************************** -class Parser(): +class Parser: r""" A class for parsing the outputs of different algorithms called in other software packages. @@ -296,7 +296,7 @@ def format_gambit(self, gambit_game): nice_stuff = [] for gambitstrategy in self.raw_string: gambitstrategy = list(gambitstrategy) - profile = [tuple(gambitstrategy[:len(gambit_game.players[int(0)].strategies)])] + profile = [tuple(gambitstrategy[:len(gambit_game.players[0].strategies)])] for player in list(gambit_game.players)[1:]: previousplayerstrategylength = len(profile[-1]) profile.append(tuple(gambitstrategy[previousplayerstrategylength: previousplayerstrategylength + len(player.strategies)])) diff --git a/src/sage/games/hexad.py b/src/sage/games/hexad.py index ddc08530b08..6a8b5e178e5 100644 --- a/src/sage/games/hexad.py +++ b/src/sage/games/hexad.py @@ -87,7 +87,7 @@ def view_list(L): EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: view_list(M.line[1]) [0 0 0] @@ -114,7 +114,7 @@ def picture_set(A, L) -> set: EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: picture_set(M.picture00, M.cross[2]) {5, 7, 8, 9, 10} sage: picture_set(M.picture02, M.square[7]) @@ -131,7 +131,7 @@ class Minimog: EXAMPLES:: sage: from sage.games.hexad import * - sage: Minimog(type="shuffle") + sage: Minimog(type='shuffle') Minimog of type shuffle sage: M = Minimog(type = "modulo11") sage: M.minimog @@ -139,7 +139,7 @@ class Minimog: [ 5 9 8 10] [ 4 1 6 7] """ - def __init__(self, type="shuffle"): + def __init__(self, type='shuffle'): self.type = type MS34 = MatrixSpace(SR, 3, 4) minimog_modulo11 = MS34([[0, 3, infinity, 2], [5, 9, 8, 10], [4, 1, 6, 7]]) @@ -225,7 +225,7 @@ def __repr__(self) -> str: EXAMPLES:: - sage: M = Minimog(type="modulo11") + sage: M = Minimog(type='modulo11') sage: M Minimog of type modulo11 """ @@ -235,23 +235,22 @@ def __str__(self) -> str: """ EXAMPLES:: - sage: M = Minimog(type="modulo11") + sage: M = Minimog(type='modulo11') sage: print(M) Minimog of type modulo11 associated to [ 0 3 +Infinity 2] [ 5 9 8 10] [ 4 1 6 7] - """ return f"Minimog of type {self.type} associated to\n {self.minimog}" def _latex_(self): r""" - Prints latex code. + Print latex code. EXAMPLES:: - sage: M = Minimog(type="modulo11") + sage: M = Minimog(type='modulo11') sage: latex(M) Minimog of type modulo11 associated to $\left(\begin{array}{rrrr} @@ -293,7 +292,6 @@ def print_kitten(self): 2 10 8 2 10 0 1 - """ MINIMOG = self.minimog kitten = f' {MINIMOG[0][2]}' @@ -313,7 +311,7 @@ def find_hexad0(self, pts): INPUT: - - ``pts`` -- a set of 2 distinct elements of MINIMOG, but not + - ``pts`` -- set of 2 distinct elements of MINIMOG, but not including the "points at infinity" OUTPUT: @@ -329,10 +327,9 @@ def find_hexad0(self, pts): EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: M.find_hexad0(set([2, 4])) ([0, 1, 2, 4, 6, 8], ['line 1', 'picture 1']) - """ MINIMOG = self.minimog L = set(pts) @@ -358,7 +355,7 @@ def find_hexad1(self, pts): INPUT: - - ``pts`` -- a set of 5 distinct elements of MINIMOG + - ``pts`` -- set of 5 distinct elements of MINIMOG OUTPUT: @@ -373,7 +370,7 @@ def find_hexad1(self, pts): EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: M.find_hexad1(set([2, 3, 4, 5, 8])) ([2, 3, 4, 5, 8, 11], ['lines (1, 2)', 'picture 1']) """ @@ -404,18 +401,16 @@ def find_hexad2(self, pts, x0): INPUT: - - ``pts`` -- a list S of 4 elements of MINIMOG, not including + - ``pts`` -- list S of 4 elements of MINIMOG, not including any "points at infinity" - ``x0`` -- in ``{MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}`` - OUTPUT: - - hexad containing `S \cup \{x0\}` of type 2 + OUTPUT: hexad containing `S \cup \{x0\}` of type 2 EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: M.find_hexad2([2, 3, 4, 5], 1) ([], []) @@ -450,9 +445,9 @@ def find_hexad3(self, pts, x0, x1): INPUT: - - ``pts`` -- a list of 3 elements of MINIMOG, not including any + - ``pts`` -- list of 3 elements of MINIMOG, not including any "points at infinity" - - ``x0``, ``x1`` -- in ``{MINIMOG[0][2], MINIMOG[2][1], + - ``x0``, ``x1`` -- in ``{MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}`` OUTPUT: @@ -463,24 +458,23 @@ def find_hexad3(self, pts, x0, x1): EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: M.find_hexad3([2, 3, 4], 0, 1) ([0, 1, 2, 3, 4, 11], ['square 2', 'picture 6']) - """ MINIMOG = self.minimog L = set(pts) H = {x0, x1} for i in range(18): - if (not (MINIMOG[0][2] in H) and L <= picture_set(self.picture21, self.square[i])): + if (MINIMOG[0][2] not in H and L <= picture_set(self.picture21, self.square[i])): WHAT = ["square " + str(i), "picture " + str(MINIMOG[0][2])] H = H | picture_set(self.picture21, self.square[i]) return list(H), WHAT - if (not (MINIMOG[2][1] in H) and L <= picture_set(self.picture02, self.square[i])): + if (MINIMOG[2][1] not in H and L <= picture_set(self.picture02, self.square[i])): WHAT = ["square " + str(i), "picture " + str(MINIMOG[2][1])] H = H | picture_set(self.picture02, self.square[i]) return list(H), WHAT - if (not (MINIMOG[0][0] in H) and L <= picture_set(self.picture00, self.square[i])): + if (MINIMOG[0][0] not in H and L <= picture_set(self.picture00, self.square[i])): WHAT = ["square " + str(i), "picture " + str(MINIMOG[0][0])] H = H | picture_set(self.picture00, self.square[i]) return list(H), WHAT @@ -492,11 +486,9 @@ def find_hexad(self, pts): INPUT: - - ``pts`` -- a list S of 5 elements of MINIMOG - - OUTPUT: + - ``pts`` -- list S of 5 elements of MINIMOG - hexad containing `S \cup \{x0\}` of some type + OUTPUT: hexad containing `S \cup \{x0\}` of some type .. NOTE:: @@ -521,7 +513,7 @@ def find_hexad(self, pts): EXAMPLES:: sage: from sage.games.hexad import * - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: M.find_hexad([0, 1, 2, 3, 4]) ([0, 1, 2, 3, 4, 11], ['square 2', 'picture 6']) sage: M.find_hexad([1, 2, 3, 4, 5]) @@ -530,7 +522,7 @@ def find_hexad(self, pts): ([2, 3, 4, 5, 8, 11], ['lines (1, 2)', 'picture 1']) sage: M.find_hexad([0, 1, 2, 4, 6]) ([0, 1, 2, 4, 6, 8], ['line 1', 'picture 1']) - sage: M = Minimog(type="modulo11") + sage: M = Minimog(type='modulo11') sage: M.find_hexad([1, 2, 3, 4, SR(infinity)]) # random (machine dependent?) order ([+Infinity, 2, 3, 4, 1, 10], ['square 8', 'picture 0']) @@ -624,7 +616,7 @@ def blackjack_move(self, L0): INPUT: - - ``L0`` -- a list of cards of length 6, taken + - ``L0`` -- list of cards of length 6, taken from `\{0, 1, ..., 11\}` .. RUBRIC:: MATHEMATICAL BLACKJACK @@ -659,10 +651,10 @@ def blackjack_move(self, L0): EXAMPLES:: - sage: M = Minimog(type="modulo11") + sage: M = Minimog(type='modulo11') sage: M.blackjack_move([0, 2, 3, 6, 1, 10]) '6 --> 5. The total went from 22 to 21.' - sage: M = Minimog(type="shuffle") + sage: M = Minimog(type='shuffle') sage: M.blackjack_move([0, 2, 4, 6, 7, 11]) '4 --> 3. The total went from 30 to 29.' diff --git a/src/sage/games/meson.build b/src/sage/games/meson.build new file mode 100644 index 00000000000..d0776c0c71a --- /dev/null +++ b/src/sage/games/meson.build @@ -0,0 +1,21 @@ +py.install_sources( + 'all.py', + 'hexad.py', + 'quantumino.py', + 'sudoku.py', + subdir: 'sage/games', +) + +extension_data = {'sudoku_backtrack' : files('sudoku_backtrack.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/games', + install: true, + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/games/quantumino.py b/src/sage/games/quantumino.py index fa0a013ff6a..e40dc47f407 100644 --- a/src/sage/games/quantumino.py +++ b/src/sage/games/quantumino.py @@ -215,9 +215,7 @@ def show_pentaminos(box=(5,8,2)): - ``box`` -- tuple of size three (default: ``(5,8,2)``), size of the box - OUTPUT: - - 3D Graphic object + OUTPUT: 3D Graphic object EXAMPLES:: @@ -348,9 +346,7 @@ def show3d(self, size=0.85): r""" Return the solution as a 3D Graphic object. - OUTPUT: - - 3D Graphic Object + OUTPUT: 3D Graphic Object EXAMPLES:: @@ -429,7 +425,7 @@ def __init__(self, aside, box=(5, 8, 2)): def __repr__(self): r""" - String representation + String representation. EXAMPLES:: @@ -484,9 +480,7 @@ def solve(self, partial=None): - ``'common'`` -- common part between two consecutive solutions - ``'incremental'`` -- one piece change at a time - OUTPUT: - - iterator of QuantuminoState + OUTPUT: iterator of :class:`QuantuminoState` EXAMPLES: @@ -574,9 +568,7 @@ def number_of_solutions(self): r""" Return the number of solutions. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/games/sudoku.py b/src/sage/games/sudoku.py index d8cfb504e14..a500fef808e 100644 --- a/src/sage/games/sudoku.py +++ b/src/sage/games/sudoku.py @@ -26,7 +26,7 @@ def sudoku(m): r""" - Solves Sudoku puzzles described by matrices. + Solve Sudoku puzzles described by matrices. INPUT: @@ -91,13 +91,14 @@ class Sudoku(SageObject): INPUT: - - puzzle -- the first argument can take one of three forms + - ``puzzle`` -- the first argument can take one of three forms * list - a Python list with elements of the puzzle in row-major order, where a blank entry is a zero * matrix - a square Sage matrix over `\ZZ` * string - a string where each character is an entry of the puzzle. For two-digit entries, a = 10, b = 11, etc. - - verify_input -- default = ``True``, use ``False`` if you know the input is valid + - ``verify_input`` -- boolean (default: ``True``); use ``False`` if you know + the input is valid EXAMPLES:: @@ -203,7 +204,7 @@ def __init__(self, puzzle, verify_input=True): def __eq__(self, other): r""" - Compares two Sudoku puzzles, based on the underlying + Compare two Sudoku puzzles, based on the underlying representation of the puzzles as tuples. EXAMPLES:: @@ -269,7 +270,6 @@ def _repr_(self): sage: s = Sudoku('.4..32....14..3.') sage: s._repr_() '+---+---+\n| 4| |\n|3 2| |\n+---+---+\n| |1 4|\n| |3 |\n+---+---+' - """ return self.to_ascii() @@ -468,9 +468,9 @@ def to_latex(self): for row in range(nsquare): for col in range(nsquare): entry = next(gen) - array.append((str(entry) if entry else ' ')) - array.append(('' if col == nsquare - 1 else '&')) - array.append(('\\\\\n' if (row+1) % n else '\\\\\\hline\n')) + array.append(str(entry) if entry else ' ') + array.append('' if col == nsquare - 1 else '&') + array.append('\\\\\n' if (row+1) % n else '\\\\\\hline\n') array.append('\\end{array}') return ''.join(array) @@ -480,8 +480,9 @@ def solve(self, algorithm='dlx'): INPUT: - - algorithm -- default = ``'dlx'``, specify choice of solution algorithm. The - two possible algorithms are ``'dlx'`` and ``'backtrack'``. + - ``algorithm`` -- string (default: ``'dlx'``); specify choice of + solution algorithm. The two possible algorithms are ``'dlx'`` and + ``'backtrack'`` OUTPUT: @@ -727,14 +728,12 @@ def dlx(self, count_only=False): INPUT: - - count_only -- boolean, default = False. - If set to ``True`` the generator returned as output will + - ``count_only`` -- boolean (default: ``False``); + if set to ``True`` the generator returned as output will simply generate ``None`` for each solution, so the - calling routine can count these. - - OUTPUT: + calling routine can count these - A generator that iterates over all the solutions. + OUTPUT: a generator that iterates over all the solutions This function is intended to be called from the :func:`~sage.games.sudoku.Sudoku.solve` method @@ -840,7 +839,7 @@ def dlx(self, count_only=False): def make_row(row, col, entry): r""" - Constructs a row of the `0-1` matrix describing + Construct a row of the `0-1` matrix describing the exact cover constraints for a Sudoku puzzle. If a (zero-based) ``entry`` is placed in location diff --git a/src/sage/games/sudoku_backtrack.pyx b/src/sage/games/sudoku_backtrack.pyx index ddf020d498d..b9630566cf5 100644 --- a/src/sage/games/sudoku_backtrack.pyx +++ b/src/sage/games/sudoku_backtrack.pyx @@ -13,7 +13,7 @@ def backtrack_all(n, puzzle): - ``n`` -- the size of the puzzle, where the array is an `n^2\times n^2` grid - - ``puzzle`` -- a list of the entries of the puzzle (1-based), in row-major order + - ``puzzle`` -- list of the entries of the puzzle (1-based), in row-major order OUTPUT: @@ -103,7 +103,7 @@ def backtrack_all(n, puzzle): for j in range(nsquare): available[level][j] = 0 - # For non-zero entries of input puzzle + # For nonzero entries of input puzzle # (1) Convert to zero-based indexing # (2) Make a set of size 1 available initially for level in range(nboxes): diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 1b25726832c..c4b308adbfa 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -236,9 +236,9 @@ from sage.features import PythonModule lazy_import('ppl', ['C_Polyhedron', 'Generator_System', 'Constraint_System', 'Linear_Expression', 'Poly_Con_Relation'], - feature=PythonModule("ppl", spkg="pplpy", type="standard")) + feature=PythonModule("ppl", spkg='pplpy', type='standard')) lazy_import('ppl', ['ray', 'point'], as_=['PPL_ray', 'PPL_point'], - feature=PythonModule("ppl", spkg="pplpy", type="standard")) + feature=PythonModule("ppl", spkg='pplpy', type='standard')) def is_Cone(x): @@ -247,11 +247,9 @@ def is_Cone(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - - ``True`` if ``x`` is a cone and ``False`` otherwise. + OUTPUT: ``True`` if ``x`` is a cone and ``False`` otherwise EXAMPLES:: @@ -278,7 +276,7 @@ def Cone(rays, lattice=None, check=True, normalize=True): INPUT: - - ``rays`` -- a list of rays. Each ray should be given as a list + - ``rays`` -- list of rays; each ray should be given as a list or a vector convertible to the rational extension of the given ``lattice``. May also be specified by a :class:`~sage.geometry.polyhedron.base.Polyhedron_base` object; @@ -301,9 +299,7 @@ def Cone(rays, lattice=None, check=True, normalize=True): this option, it is designed for code optimization and does not give as drastic improvement in speed as the previous one. - OUTPUT: - - - convex rational polyhedral cone determined by ``rays``. + OUTPUT: convex rational polyhedral cone determined by ``rays`` EXAMPLES: @@ -496,7 +492,7 @@ def _Cone_from_PPL(cone, lattice, original_rays=None): INPUT: - ``cone`` -- a :class:`~ppl.polyhedron.Polyhedron` having the - origin as its single point. + origin as its single point - ``lattice`` -- :class:`ToricLattice `, `\ZZ^n`, or any @@ -507,9 +503,7 @@ def _Cone_from_PPL(cone, lattice, original_rays=None): and ``original_rays`` were given, they will be used as internal rays of the constructed cone, in the given order. - OUTPUT: - - A :class:`ConvexRationalPolyhedralCone`. + OUTPUT: a :class:`ConvexRationalPolyhedralCone` TESTS:: @@ -556,7 +550,7 @@ def _ambient_space_point(body, data): An integral, rational, real algebraic, or numeric point of the ambient space of ``body`` is returned if ``data`` were - successfully interpreted in such a way. A :class:`TypeError` is raised + successfully interpreted in such a way. A :exc:`TypeError` is raised otherwise. TESTS:: @@ -600,7 +594,6 @@ def _ambient_space_point(body, data): (1.00000000000000, 3.14159265358979) sage: _ambient_space_point(c, vector(SR,[1, pi])) # needs sage.rings.number_field sage.symbolic (1.00000000000000, 3.14159265358979) - """ L = body.lattice() @@ -660,7 +653,7 @@ def integral_length(v): OUTPUT: - Rational number `r`` such that ``v = r * u``, where ``u`` is the + Rational number ``r`` such that ``v = r * u``, where ``u`` is the primitive integral vector in the direction of ``v``. EXAMPLES:: @@ -835,11 +828,9 @@ def __richcmp__(self, right, op): INPUT: - - ``right`` -- anything. + - ``right`` -- anything - OUTPUT: - - boolean + OUTPUT: boolean There is equality if ``right`` is of the same type as ``self``, they have the same ambient lattices, and their @@ -872,9 +863,7 @@ def __hash__(self): r""" Return the hash of ``self`` computed from rays. - OUTPUT: - - - integer. + OUTPUT: integer TESTS:: @@ -890,9 +879,7 @@ def __iter__(self): r""" Return an iterator over rays of ``self``. - OUTPUT: - - - iterator. + OUTPUT: iterator TESTS:: @@ -915,9 +902,7 @@ def cartesian_product(self, other, lattice=None): default, the direct sum of the ambient lattices of ``self`` and ``other`` is constructed. - OUTPUT: - - - an :class:`IntegralRayCollection`. + OUTPUT: an :class:`IntegralRayCollection` By the Cartesian product of ray collections `(r_0, \dots, r_{n-1})` and `(s_0, \dots, s_{m-1})` we understand the ray collection of the form @@ -970,9 +955,7 @@ def dim(self): r""" Return the dimension of the subspace spanned by rays of ``self``. - OUTPUT: - - - integer. + OUTPUT: integer EXAMPLES:: @@ -990,9 +973,7 @@ def lattice(self): r""" Return the ambient lattice of ``self``. - OUTPUT: - - - lattice. + OUTPUT: lattice EXAMPLES:: @@ -1013,7 +994,7 @@ def ambient_vector_space(self, base_field=None): INPUT: - - ``base_field`` -- (default: the rationals) a field. + - ``base_field`` -- (default: the rationals) a field EXAMPLES:: @@ -1065,9 +1046,7 @@ def lattice_dim(self): An alias is :meth:`ambient_dim`. - OUTPUT: - - - integer. + OUTPUT: integer EXAMPLES:: @@ -1085,9 +1064,7 @@ def nrays(self): r""" Return the number of rays of ``self``. - OUTPUT: - - - integer. + OUTPUT: integer EXAMPLES:: @@ -1106,9 +1083,7 @@ def plot(self, **options): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -1125,12 +1100,10 @@ def ray(self, n): INPUT: - - ``n`` -- integer, an index of a ray of ``self``. Enumeration of rays - starts with zero. - - OUTPUT: + - ``n`` -- integer; an index of a ray of ``self``. Enumeration of rays + starts with zero - - ray, an element of the lattice of ``self``. + OUTPUT: ray; an element of the lattice of ``self`` EXAMPLES:: @@ -1146,13 +1119,11 @@ def rays(self, *args): INPUT: - - ``ray_list`` -- a list of integers, the indices of the requested - rays. If not specified, all rays of ``self`` will be returned. + - ``ray_list`` -- list of integers, the indices of the requested + rays. If not specified, all rays of ``self`` will be returned - OUTPUT: - - - a :class:`~sage.geometry.point_collection.PointCollection` - of primitive integral ray generators. + OUTPUT: a :class:`~sage.geometry.point_collection.PointCollection` + of primitive integral ray generators EXAMPLES:: @@ -1185,9 +1156,7 @@ def codim(self): difference between the dimension of the ambient space and the dimension of the subspace spanned by those rays (of the cone/fan). - OUTPUT: - - A nonnegative integer representing the codimension of ``self``. + OUTPUT: nonnegative integer representing the codimension of ``self`` .. SEEALSO:: @@ -1278,11 +1247,9 @@ def span(self, base_ring=None): INPUT: - ``base_ring`` -- (default: from lattice) the base ring to use - for the generated module. - - OUTPUT: + for the generated module - A module spanned by the generators of ``self``. + OUTPUT: a module spanned by the generators of ``self`` EXAMPLES: @@ -1338,11 +1305,11 @@ def classify_cone_2d(ray0, ray1, check=True): INPUT: - - ``ray0``, ``ray1`` -- two primitive integer vectors. The - generators of the two rays generating the two-dimensional cone. + - ``ray0``, ``ray1`` -- two primitive integer vectors; the + generators of the two rays generating the two-dimensional cone - - ``check`` -- boolean (default: ``True``). Whether to check the - input rays for consistency. + - ``check`` -- boolean (default: ``True``); whether to check the + input rays for consistency OUTPUT: @@ -1465,7 +1432,7 @@ class ConvexRationalPolyhedralCone(IntegralRayCollection, Container, ConvexSet_c of* ``ambient``; - ``ambient_ray_indices`` -- increasing list or tuple of integers, indices - of rays of ``ambient`` generating this cone. + of rays of ``ambient`` generating this cone In both cases, the following keyword parameter may be specified in addition: @@ -1475,9 +1442,7 @@ class ConvexRationalPolyhedralCone(IntegralRayCollection, Container, ConvexSet_c already. The constructor does not make a copy so the ``PPL`` object should not be modified afterwards. - OUTPUT: - - - convex rational polyhedral cone. + OUTPUT: convex rational polyhedral cone .. NOTE:: @@ -1550,11 +1515,9 @@ def _sage_input_(self, sib, coerced): def _PPL_cone(self): r""" - Returns the Parma Polyhedra Library (PPL) representation of the cone. - - OUTPUT: + Return the Parma Polyhedra Library (PPL) representation of the cone. - A :class:`~ppl.polyhedron.C_Polyhedron` representing the cone. + OUTPUT: a :class:`~ppl.polyhedron.C_Polyhedron` representing the cone EXAMPLES:: @@ -1609,9 +1572,7 @@ def __getstate__(self): r""" Return the dictionary that should be pickled. - OUTPUT: - - - :class:`dict`. + OUTPUT: :class:`dict` TESTS:: @@ -1665,10 +1626,10 @@ def _contains(self, point, region='whole cone'): INPUT: - ``point`` -- anything; an attempt will be made to convert it - into an element compatible with the ambient space of ``self``. + into an element compatible with the ambient space of ``self`` - - ``region`` -- a string (default: 'whole cone'); can be - either 'whole cone', 'interior', or 'relative interior'. + - ``region`` -- string (default: 'whole cone'); can be + either 'whole cone', 'interior', or 'relative interior' OUTPUT: @@ -1677,7 +1638,7 @@ def _contains(self, point, region='whole cone'): otherwise, in particular when ``point`` is incompatible with the ambient space. - A :class:`ValueError` is raised if ``region`` is not one of the + A :exc:`ValueError` is raised if ``region`` is not one of the three allowed values. TESTS:: @@ -1799,7 +1760,6 @@ def interior(self): 2-d cone in 2-d lattice N sage: K2.interior() is K2 True - """ if self.is_solid(): return self.relative_interior() @@ -1888,15 +1848,13 @@ def cartesian_product(self, other, lattice=None): INPUT: - - ``other`` -- a :class:`cone `; + - ``other`` -- a :class:`cone ` - ``lattice`` -- (optional) the ambient lattice for the - Cartesian product cone. By default, the direct sum of the - ambient lattices of ``self`` and ``other`` is constructed. + Cartesian product cone; by default, the direct sum of the + ambient lattices of ``self`` and ``other`` is constructed - OUTPUT: - - - a :class:`cone `. + OUTPUT: a :class:`cone ` EXAMPLES:: @@ -1916,9 +1874,7 @@ def __neg__(self): """ Return the cone with opposite rays. - OUTPUT: - - - a :class:`cone `. + OUTPUT: a :class:`cone ` EXAMPLES:: @@ -1942,11 +1898,9 @@ def __richcmp__(self, right, op): INPUT: - - ``right`` -- anything. + - ``right`` -- anything - OUTPUT: - - boolean + OUTPUT: boolean There is equality if ``self`` and ``right`` are cones of any kind in the same lattice with the same rays listed in the @@ -1977,9 +1931,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1999,9 +1951,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -2036,7 +1986,7 @@ def _some_elements_(self): """ V = self.ambient_vector_space() r_iter = iter(self._rays) - p = V(0) + p = V.zero() yield p for i in range(5): try: @@ -2045,7 +1995,7 @@ def _some_elements_(self): return yield p - def _sort_faces(self, faces): + def _sort_faces(self, faces): r""" Return sorted (if necessary) ``faces`` as a tuple. @@ -2056,11 +2006,9 @@ def _sort_faces(self, faces): INPUT: - ``faces`` -- iterable of :class:`cones - `. + ` - OUTPUT: - - - :class:`tuple` of :class:`cones `. + OUTPUT: :class:`tuple` of :class:`cones ` TESTS:: @@ -2104,9 +2052,7 @@ def adjacent(self): * `F_1` and `F_2` are facets of some face of dimension `d+1`, unless `d` is the dimension of the ambient structure. - OUTPUT: - - - :class:`tuple` of :class:`cones `. + OUTPUT: :class:`tuple` of :class:`cones ` EXAMPLES:: @@ -2163,7 +2109,7 @@ def adjacent(self): if superfaces: for superface in superfaces: for facet in facets: - adjacent.update(L.open_interval(facet, superface)) + adjacent.update(L.open_interval(facet, superface)) if adjacent: adjacent.remove(L(self)) return self._sort_faces(adjacent) @@ -2181,9 +2127,7 @@ def ambient(self): r""" Return the ambient structure of ``self``. - OUTPUT: - - - cone or fan containing ``self`` as a face. + OUTPUT: cone or fan containing ``self`` as a face EXAMPLES:: @@ -2208,9 +2152,7 @@ def ambient_ray_indices(self): r""" Return indices of rays of the ambient structure generating ``self``. - OUTPUT: - - - increasing :class:`tuple` of integers. + OUTPUT: increasing :class:`tuple` of integers EXAMPLES:: @@ -2270,9 +2212,7 @@ def dual(self): r""" Return the dual cone of ``self``. - OUTPUT: - - - :class:`cone `. + OUTPUT: :class:`cone ` EXAMPLES:: @@ -2353,7 +2293,7 @@ def embed(self, cone): or :meth:`~sage.geometry.cone.ConvexRationalPolyhedralCone.facet_of`. The cone returned by this method will have ``self`` as ambient. If ``cone`` - does not represent a valid cone of ``self``, :class:`ValueError` + does not represent a valid cone of ``self``, :exc:`ValueError` exception is raised. .. NOTE:: @@ -2366,7 +2306,7 @@ def embed(self, cone): INPUT: - ``cone`` -- a :class:`cone - `. + ` OUTPUT: @@ -2663,7 +2603,7 @@ def ConeFace(atoms, facets): faces.append(self) for face in dfaces: L.add_edge(face_to_index[face], next_index) - D = {i:f for i,f in enumerate(faces)} + D = dict(enumerate(faces)) L.relabel(D) self._face_lattice = FinitePoset(L, faces, key=id(self)) return self._face_lattice @@ -2677,9 +2617,9 @@ def faces(self, dim=None, codim=None): INPUT: - - ``dim`` -- integer, dimension of the requested faces; + - ``dim`` -- integer; dimension of the requested faces - - ``codim`` -- integer, codimension of the requested faces. + - ``codim`` -- integer; codimension of the requested faces .. NOTE:: @@ -2734,7 +2674,7 @@ def faces(self, dim=None, codim=None): () In the case of non-strictly convex cones even faces of small - non-negative dimension may be missing:: + nonnegative dimension may be missing:: sage: # needs sage.graphs sage: halfplane = Cone([(1,0), (0,1), (-1,0)]) @@ -2815,9 +2755,7 @@ def facet_normals(self): #. The order of normals is random, but consistent with :meth:`facets`. - OUTPUT: - - - a :class:`~sage.geometry.point_collection.PointCollection`. + OUTPUT: a :class:`~sage.geometry.point_collection.PointCollection` If the ambient :meth:`~IntegralRayCollection.lattice` of ``self`` is a :class:`toric lattice @@ -2918,9 +2856,7 @@ def facet_of(self): r""" Return *cones* of the ambient face lattice having ``self`` as a facet. - OUTPUT: - - - :class:`tuple` of :class:`cones `. + OUTPUT: :class:`tuple` of :class:`cones ` EXAMPLES:: @@ -2956,9 +2892,7 @@ def facets(self): r""" Return facets (faces of codimension 1) of ``self``. - OUTPUT: - - - :class:`tuple` of :class:`cones `. + OUTPUT: :class:`tuple` of :class:`cones ` EXAMPLES:: @@ -3025,13 +2959,11 @@ def intersection(self, other): INPUT: - - ``other`` -- :class:`cone `. + - ``other`` -- :class:`cone ` - OUTPUT: + OUTPUT: :class:`cone ` - - :class:`cone `. - - This raises :class:`ValueError` if the ambient space dimensions + This raises :exc:`ValueError` if the ambient space dimensions are not compatible. EXAMPLES:: @@ -3110,7 +3042,7 @@ def is_equivalent(self, other): INPUT: - - ``other`` -- cone. + - ``other`` -- cone OUTPUT: @@ -3152,7 +3084,6 @@ def is_equivalent(self, other): sage: K = random_cone(max_ambient_dim=8, max_rays=10) sage: K.is_equivalent(K) True - """ if self is other: return True @@ -3169,11 +3100,9 @@ def is_face_of(self, cone): INPUT: - - ``cone`` -- cone. - - OUTPUT: + - ``cone`` -- cone - - ``True`` if ``self`` is a face of ``cone``, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is a face of ``cone``, ``False`` otherwise EXAMPLES:: @@ -3202,7 +3131,6 @@ def is_face_of(self, cone): sage: K = random_cone(max_ambient_dim=8, max_rays=10) sage: K.is_face_of(K) True - """ if self.lattice() != cone.lattice(): return False @@ -3240,12 +3168,10 @@ def is_isomorphic(self, other): INPUT: - - ``other`` -- cone. - - OUTPUT: + - ``other`` -- cone - - ``True`` if ``self`` and ``other`` are in the same - `GL(n, \ZZ)`-orbit, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` and ``other`` are in the same + `GL(n, \ZZ)`-orbit, ``False`` otherwise There are three different equivalences between cones `C_1` and `C_2` in the same lattice: @@ -3314,9 +3240,7 @@ def is_simplicial(self): generating rays form a part of a *rational* basis of the ambient space. - OUTPUT: - - - ``True`` if ``self`` is simplicial, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is simplicial, ``False`` otherwise EXAMPLES:: @@ -3339,9 +3263,7 @@ def is_smooth(self): ambient space. Equivalently, they generate the whole lattice on the linear subspace spanned by the rays. - OUTPUT: - - - ``True`` if ``self`` is smooth, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is smooth, ``False`` otherwise EXAMPLES:: @@ -3377,17 +3299,14 @@ def is_empty(self): sage: trivial_cone = cones.trivial(3) sage: trivial_cone.is_empty() False - """ return False def is_trivial(self): """ - Checks if the cone has no rays. - - OUTPUT: + Check if the cone has no rays. - - ``True`` if the cone has no rays, ``False`` otherwise. + OUTPUT: ``True`` if the cone has no rays, ``False`` otherwise EXAMPLES:: @@ -3407,9 +3326,7 @@ def is_strictly_convex(self): A cone is called **strictly convex** if it does not contain any lines. - OUTPUT: - - - ``True`` if ``self`` is strictly convex, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is strictly convex, ``False`` otherwise EXAMPLES:: @@ -3434,9 +3351,7 @@ def linear_subspace(self): r""" Return the largest linear subspace contained inside of ``self``. - OUTPUT: - - - subspace of the ambient space of ``self``. + OUTPUT: subspace of the ambient space of ``self`` EXAMPLES:: @@ -3501,11 +3416,9 @@ def plot(self, **options): INPUT: - any options for toric plots (see :func:`toric_plotter.options - `), none are mandatory. - - OUTPUT: + `), none are mandatory - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -3548,9 +3461,7 @@ def polyhedron(self, **kwds): Mathematically this polyhedron is the same as ``self``. - OUTPUT: - - - :class:`~sage.geometry.polyhedron.base.Polyhedron_base`. + OUTPUT: :class:`~sage.geometry.polyhedron.base.Polyhedron_base` EXAMPLES:: @@ -3599,9 +3510,7 @@ def strict_quotient(self): cone in the quotient of the ambient space by the linear subspace of the cone, i.e. it is the "complementary part" to the linear subspace. - OUTPUT: - - - cone. + OUTPUT: cone EXAMPLES:: @@ -3795,7 +3704,7 @@ def solid_restriction(self): L._dual_name, L._latex_name, L._latex_dual_name) # We don't need to check if these rays are zero: they will all - # have at least one non-zero coordinate; otherwise they would + # have at least one nonzero coordinate; otherwise they would # lie outside of the span of our cone. And they don't, because # they generate the cone. rays = ( S(subL.coordinates(ray)) for ray in self ) @@ -4295,7 +4204,7 @@ def semigroup_generators(self): of lattice points generating the semigroup of lattice points contained in ``self``. - .. note:: + .. NOTE:: No attempt is made to return a minimal set of generators, see :meth:`Hilbert_basis` for that. @@ -4574,7 +4483,7 @@ def Hilbert_coefficients(self, point, solver=None, verbose=0, in the cone, or something that can be converted to a point. For example, a list or tuple of integers. - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -4582,18 +4491,18 @@ def Hilbert_coefficients(self, point, solver=None, verbose=0, of the class :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``). Sets the level of verbosity + - ``verbose`` -- integer (default: 0); sets the level of verbosity of the LP solver. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` OUTPUT: A `\ZZ`-vector of length ``len(self.Hilbert_basis())`` with nonnegative components. - .. note:: + .. NOTE:: Since the Hilbert basis elements are not necessarily linearly independent, the expansion coefficients are not unique. However, @@ -4660,9 +4569,7 @@ def is_solid(self): An alias is :meth:`is_full_dimensional`. - OUTPUT: - - ``True`` if this cone is solid, and ``False`` otherwise. + OUTPUT: ``True`` if this cone is solid, and ``False`` otherwise .. SEEALSO:: @@ -4709,9 +4616,7 @@ def is_proper(self): convex; therefore it is proper if it is solid and contains no lines. - OUTPUT: - - ``True`` if this cone is proper, and ``False`` otherwise. + OUTPUT: ``True`` if this cone is proper, and ``False`` otherwise .. SEEALSO:: @@ -4742,7 +4647,6 @@ def is_proper(self): sage: halfspace = Cone([(1,0), (0,1), (-1,0)]) sage: halfspace.is_proper() False - """ return (self.is_strictly_convex() and self.is_solid()) @@ -4785,7 +4689,6 @@ def is_full_space(self): sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) sage: K.is_full_space() True - """ return self.linear_subspace() == self.lattice().vector_space() @@ -4865,9 +4768,7 @@ def is_relatively_open(self): r""" Return whether ``self`` is relatively open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -5131,9 +5032,7 @@ def lyapunov_rank(self): the dimension of the Lie algebra of the automorphism group of the cone. - OUTPUT: - - A nonnegative integer representing the Lyapunov rank of this cone. + OUTPUT: nonnegative integer representing the Lyapunov rank of this cone If the ambient space is trivial, then the Lyapunov rank will be zero. On the other hand, if the dimension of the ambient vector @@ -5357,14 +5256,14 @@ def random_element(self, ring=ZZ): INPUT: - ``ring`` -- (default: ``ZZ``) the ring from which the random - generator weights are chosen; either ``ZZ`` or ``QQ``. + generator weights are chosen; either ``ZZ`` or ``QQ`` OUTPUT: Either a lattice element or vector contained in both this cone and its ambient vector space. If ``ring`` is ``ZZ``, a lattice element is returned; otherwise a vector is returned. If ``ring`` - is neither ``ZZ`` nor ``QQ``, then a :class:`NotImplementedError` is + is neither ``ZZ`` nor ``QQ``, then a :exc:`NotImplementedError` is raised. EXAMPLES: @@ -5497,7 +5396,7 @@ def positive_operators_gens(self, K2=None): INPUT: - ``K2`` -- (default: ``self``) the codomain cone; the image of - this cone under the returned generators is a subset of ``K2``. + this cone under the returned generators is a subset of ``K2`` OUTPUT: @@ -6222,14 +6121,14 @@ def max_angle(self, other=None, exact=True, epsilon=0): be made using inexact arithmetic. (This sometimes avoids the problem noted in [Or2024]_). If the computation fails when the cones are not strictly convex or when ``exact`` is ``False``, - a :class:`ValueError` is raised. + a :exc:`ValueError` is raised. INPUT: - ``other`` -- (default: ``None``) a rational, polyhedral convex cone - - ``exact`` -- (default: ``True``) whether or not to use exact + - ``exact`` -- boolean (default: ``True``); whether or not to use exact rational arithmetic instead of floating point computations; beware that ``True`` is not guaranteed to avoid floating point computations if the algorithm runs into trouble in @@ -6272,7 +6171,7 @@ def max_angle(self, other=None, exact=True, epsilon=0): vectors will be over :class:`sage.rings.real_double.RDF`. - If ``exact`` is ``False`` or if either cone is not strictly - convex, then a :class:`ValueError` is raised to indicate + convex, then a :exc:`ValueError` is raised to indicate that we have failed; i.e. we cannot say with certainty what the maximal angle is. @@ -6447,37 +6346,35 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, INPUT: - * ``lattice`` (default: random) -- A ``ToricLattice`` object in + - ``lattice`` -- (default: random) a ``ToricLattice`` object in which the returned cone will live. By default a new lattice will be constructed with a randomly-chosen rank (subject to ``min_ambient_dim`` and ``max_ambient_dim``). - * ``min_ambient_dim`` (default: zero) -- A nonnegative integer - representing the minimum dimension of the ambient lattice. + - ``min_ambient_dim`` -- (default: zero) a nonnegative integer + representing the minimum dimension of the ambient lattice - * ``max_ambient_dim`` (default: random) -- A nonnegative integer - representing the maximum dimension of the ambient lattice. + - ``max_ambient_dim`` -- (default: random) a nonnegative integer + representing the maximum dimension of the ambient lattice - * ``min_rays`` (default: zero) -- A nonnegative integer representing - the minimum number of generating rays of the cone. + - ``min_rays`` -- (default: zero) a nonnegative integer representing + the minimum number of generating rays of the cone - * ``max_rays`` (default: random) -- A nonnegative integer representing - the maximum number of generating rays of the cone. + - ``max_rays`` -- (default: random) a nonnegative integer representing + the maximum number of generating rays of the cone - * ``strictly_convex`` (default: random) -- Whether or not to make the + - ``strictly_convex`` -- (default: random) whether or not to make the returned cone strictly convex. Specify ``True`` for a strictly convex cone, ``False`` for a non-strictly-convex cone, or ``None`` if you don't care. - * ``solid`` (default: random) -- Whether or not to make the returned + - ``solid`` -- (default: random) whether or not to make the returned cone solid. Specify ``True`` for a solid cone, ``False`` for a non-solid cone, or ``None`` if you don't care. - OUTPUT: - - A new, randomly generated cone. + OUTPUT: a new, randomly generated cone - A :class:`ValueError` will be thrown under the following conditions: + A :exc:`ValueError` will be thrown under the following conditions: * Any of ``min_ambient_dim``, ``max_ambient_dim``, ``min_rays``, or ``max_rays`` are negative. @@ -6634,7 +6531,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, provided. If the user requests too many rays in zero, one, or two dimensions, - a :class:`ValueError` is thrown:: + a :exc:`ValueError` is thrown:: sage: random_cone(max_ambient_dim=0, min_rays=1) Traceback (most recent call last): @@ -6722,7 +6619,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, sage: random_cone(lattice=L, strictly_convex=True) 0-d cone in 0-d lattice L - A :class:`ValueError` is thrown if a non-solid cone is requested in a + A :exc:`ValueError` is thrown if a non-solid cone is requested in a zero-dimensional lattice:: sage: L = ToricLattice(0) @@ -6736,7 +6633,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ... ValueError: all cones are solid when max_ambient_dim is zero. - A :class:`ValueError` is thrown if a solid cone is requested but the + A :exc:`ValueError` is thrown if a solid cone is requested but the maximum number of rays is too few:: sage: random_cone(min_ambient_dim=4, max_rays=3, solid=True) @@ -6751,7 +6648,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ValueError: max_rays must be at least 5 for a solid cone in this lattice. - A :class:`ValueError` is thrown if a non-solid cone is requested but + A :exc:`ValueError` is thrown if a non-solid cone is requested but ``min_rays`` guarantees a solid cone:: sage: random_cone(max_ambient_dim=4, min_rays=10, solid=False) @@ -6765,7 +6662,6 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ... ValueError: every cone is solid when min_rays > 2*(d - 1) where d is the dimension of the given lattice. - """ # Catch obvious mistakes so that we can generate clear error diff --git a/src/sage/geometry/cone_catalog.py b/src/sage/geometry/cone_catalog.py index a56de80b412..d58302d5915 100644 --- a/src/sage/geometry/cone_catalog.py +++ b/src/sage/geometry/cone_catalog.py @@ -72,6 +72,7 @@ # the top-level non-underscore functions defined in this module. # + def _preprocess_args(ambient_dim, lattice): r""" Preprocess arguments for cone-constructing functions. @@ -98,7 +99,7 @@ def _preprocess_args(ambient_dim, lattice): INPUT: - - ``ambient_dim`` -- a nonnegative integer; the dimension of the + - ``ambient_dim`` -- nonnegative integer; the dimension of the ambient space in which the cone will live - ``lattice`` -- a toric lattice; the lattice in which the cone @@ -176,7 +177,7 @@ def downward_monotone(ambient_dim=None, lattice=None): INPUT: - - ``ambient_dim`` -- a nonnegative integer (default: ``None``); the + - ``ambient_dim`` -- nonnegative integer (default: ``None``); the dimension of the ambient space - ``lattice`` -- a toric lattice (default: ``None``); the lattice in @@ -186,8 +187,8 @@ def downward_monotone(ambient_dim=None, lattice=None): rank of ``lattice``. If the ``lattice`` is omitted, then the default lattice of rank ``ambient_dim`` will be used. - A :class:`ValueError` is raised if neither ``ambient_dim`` nor - ``lattice`` are specified. It is also a :class:`ValueError` to + A :exc:`ValueError` is raised if neither ``ambient_dim`` nor + ``lattice`` are specified. It is also a :exc:`ValueError` to specify both ``ambient_dim`` and ``lattice`` unless the rank of ``lattice`` is equal to ``ambient_dim``. @@ -198,7 +199,7 @@ def downward_monotone(ambient_dim=None, lattice=None): nonincreasing order. Each generating ray has the integer ring as its base ring. - A :class:`ValueError` can be raised if the inputs are incompatible + A :exc:`ValueError` can be raised if the inputs are incompatible or insufficient. See the INPUT documentation for details. .. SEEALSO:: @@ -307,7 +308,7 @@ def nonnegative_orthant(ambient_dim=None, lattice=None): INPUT: - - ``ambient_dim`` -- a nonnegative integer (default: ``None``); the + - ``ambient_dim`` -- nonnegative integer (default: ``None``); the dimension of the ambient space - ``lattice`` -- a toric lattice (default: ``None``); the lattice in @@ -317,8 +318,8 @@ def nonnegative_orthant(ambient_dim=None, lattice=None): rank of ``lattice``. If the ``lattice`` is omitted, then the default lattice of rank ``ambient_dim`` will be used. - A :class:`ValueError` is raised if neither ``ambient_dim`` nor - ``lattice`` are specified. It is also a :class:`ValueError` to + A :exc:`ValueError` is raised if neither ``ambient_dim`` nor + ``lattice`` are specified. It is also a :exc:`ValueError` to specify both ``ambient_dim`` and ``lattice`` unless the rank of ``lattice`` is equal to ``ambient_dim``. @@ -329,7 +330,7 @@ def nonnegative_orthant(ambient_dim=None, lattice=None): as its generators. Each generating ray has the integer ring as its base ring. - A :class:`ValueError` can be raised if the inputs are incompatible + A :exc:`ValueError` can be raised if the inputs are incompatible or insufficient. See the INPUT documentation for details. REFERENCES: @@ -412,10 +413,10 @@ def rearrangement(p, ambient_dim=None, lattice=None): INPUT: - - ``p`` -- a nonnegative integer; the number of components to + - ``p`` -- nonnegative integer; the number of components to "rearrange", between ``1`` and ``ambient_dim`` inclusive - - ``ambient_dim`` -- a nonnegative integer (default: ``None``); the + - ``ambient_dim`` -- nonnegative integer (default: ``None``); the dimension of the ambient space - ``lattice`` -- a toric lattice (default: ``None``); the lattice in @@ -425,12 +426,12 @@ def rearrangement(p, ambient_dim=None, lattice=None): rank of ``lattice``. If the ``lattice`` is omitted, then the default lattice of rank ``ambient_dim`` will be used. - A :class:`ValueError` is raised if neither ``ambient_dim`` nor - ``lattice`` are specified. It is also a :class:`ValueError` to + A :exc:`ValueError` is raised if neither ``ambient_dim`` nor + ``lattice`` are specified. It is also a :exc:`ValueError` to specify both ``ambient_dim`` and ``lattice`` unless the rank of ``lattice`` is equal to ``ambient_dim``. - It is also a :class:`ValueError` to specify a non-integer ``p``. + It is also a :exc:`ValueError` to specify a non-integer ``p``. OUTPUT: @@ -439,7 +440,7 @@ def rearrangement(p, ambient_dim=None, lattice=None): ``lattice``, with ambient dimension ``ambient_dim``. Each generating ray has the integer ring as its base ring. - A :class:`ValueError` can be raised if the inputs are incompatible + A :exc:`ValueError` can be raised if the inputs are incompatible or insufficient. See the INPUT documentation for details. ALGORITHM: @@ -636,7 +637,7 @@ def schur(ambient_dim=None, lattice=None): INPUT: - - ``ambient_dim`` -- a nonnegative integer (default: ``None``); the + - ``ambient_dim`` -- nonnegative integer (default: ``None``); the dimension of the ambient space - ``lattice`` -- a toric lattice (default: ``None``); the lattice in @@ -646,8 +647,8 @@ def schur(ambient_dim=None, lattice=None): rank of ``lattice``. If the ``lattice`` is omitted, then the default lattice of rank ``ambient_dim`` will be used. - A :class:`ValueError` is raised if neither ``ambient_dim`` nor - ``lattice`` are specified. It is also a :class:`ValueError` to + A :exc:`ValueError` is raised if neither ``ambient_dim`` nor + ``lattice`` are specified. It is also a :exc:`ValueError` to specify both ``ambient_dim`` and ``lattice`` unless the rank of ``lattice`` is equal to ``ambient_dim``. @@ -658,7 +659,7 @@ def schur(ambient_dim=None, lattice=None): dimension ``ambient_dim``. Each generating ray has the integer ring as its base ring. - A :class:`ValueError` can be raised if the inputs are incompatible + A :exc:`ValueError` can be raised if the inputs are incompatible or insufficient. See the INPUT documentation for details. .. SEEALSO:: @@ -775,7 +776,7 @@ def trivial(ambient_dim=None, lattice=None): INPUT: - - ``ambient_dim`` -- a nonnegative integer (default: ``None``); the + - ``ambient_dim`` -- nonnegative integer (default: ``None``); the dimension of the ambient space - ``lattice`` -- a toric lattice (default: ``None``); the lattice in @@ -785,8 +786,8 @@ def trivial(ambient_dim=None, lattice=None): rank of ``lattice``. If the ``lattice`` is omitted, then the default lattice of rank ``ambient_dim`` will be used. - A :class:`ValueError` is raised if neither ``ambient_dim`` nor - ``lattice`` are specified. It is also a :class:`ValueError` to + A :exc:`ValueError` is raised if neither ``ambient_dim`` nor + ``lattice`` are specified. It is also a :exc:`ValueError` to specify both ``ambient_dim`` and ``lattice`` unless the rank of ``lattice`` is equal to ``ambient_dim``. @@ -796,7 +797,7 @@ def trivial(ambient_dim=None, lattice=None): representing the trivial cone with no nonzero generators living in ``lattice``, with ambient dimension ``ambient_dim``. - A :class:`ValueError` can be raised if the inputs are incompatible + A :exc:`ValueError` can be raised if the inputs are incompatible or insufficient. See the INPUT documentation for details. EXAMPLES: diff --git a/src/sage/geometry/cone_critical_angles.py b/src/sage/geometry/cone_critical_angles.py index 3e39102426a..9e5252a4bf9 100644 --- a/src/sage/geometry/cone_critical_angles.py +++ b/src/sage/geometry/cone_critical_angles.py @@ -40,6 +40,7 @@ from sage.rings.real_double import RDF from sage.symbolic.constants import pi + def _normalize_gevp_solution(gevp_solution): r""" Normalize the results of :func:`solve_gevp_nonzero` and @@ -128,7 +129,7 @@ def _random_admissible_cone(ambient_dim): INPUT: - - ``ambient_dim`` -- a positive integer representing the dimension + - ``ambient_dim`` -- positive integer representing the dimension of the ambient lattice in which the returned cone lives OUTPUT: @@ -136,7 +137,7 @@ def _random_admissible_cone(ambient_dim): A "random" nontrivial closed convex cone in a lattice of dimension ``ambient_dim``. - A :class:`ValueError` is raised if ``ambient_dim`` is not + A :exc:`ValueError` is raised if ``ambient_dim`` is not positive. EXAMPLES: @@ -458,7 +459,7 @@ def solve_gevp_nonzero(GG, HH, M, I, J): ALGORITHM: According to Proposition 5 [Or2020]_, the solutions corresponding - to non-zero eigenvalues can be found by solving a smaller + to nonzero eigenvalues can be found by solving a smaller eigenvalue problem in only the variable `\xi`. So, we do that, and then solve for `\eta` in terms of `\xi` as described in the proposition. @@ -626,9 +627,7 @@ def compute_gevp_M(gs, hs): - ``hs`` -- a linearly independent list of unit-norm generators for the cone `Q` - OUTPUT: - - A tuple containing four elements, in order: + OUTPUT: a tuple containing four elements, in order: - The matrix `M` described in Proposition 6 diff --git a/src/sage/geometry/convex_set.py b/src/sage/geometry/convex_set.py index dd7237f0e30..2117eccfcc6 100644 --- a/src/sage/geometry/convex_set.py +++ b/src/sage/geometry/convex_set.py @@ -45,9 +45,7 @@ def is_empty(self): r""" Test whether ``self`` is the empty set. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -62,9 +60,7 @@ def is_finite(self): r""" Test whether ``self`` is a finite set. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -87,9 +83,7 @@ def cardinality(self): """ Return the cardinality of this set. - OUTPUT: - - Either an integer or ``Infinity``. + OUTPUT: either an integer or ``Infinity`` EXAMPLES:: @@ -116,9 +110,7 @@ def is_universe(self): r""" Test whether ``self`` is the whole ambient space. - OUTPUT: - - Boolean. + OUTPUT: boolean TESTS:: @@ -260,7 +252,7 @@ def an_affine_basis(self): def _test_an_affine_basis(self, tester=None, **options): r""" - Run tests on the method :meth:`.an_affine_basis` + Run tests on the method :meth:`.an_affine_basis`. TESTS:: @@ -457,10 +449,8 @@ def is_full_dimensional(self): r""" Return whether ``self`` is full dimensional. - OUTPUT: - - Boolean. Whether the polyhedron is not contained in any strict - affine subspace. + OUTPUT: boolean; whether the polyhedron is not contained in any strict + affine subspace EXAMPLES:: @@ -482,9 +472,7 @@ def is_open(self): The default implementation of this method only knows that the empty set and the ambient space are open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -509,9 +497,7 @@ def is_relatively_open(self): sets are also relatively open, and in addition singletons are relatively open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -535,9 +521,7 @@ def is_closed(self): The default implementation of this method only knows that the empty set, a singleton set, and the ambient space are closed. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -560,9 +544,7 @@ def is_compact(self): non-closed set cannot be compact, and that the empty set and a singleton set are compact. - OUTPUT: - - Boolean. + OUTPUT: boolean sage: from sage.geometry.convex_set import ConvexSet_base sage: class ExampleSet(ConvexSet_base): @@ -627,9 +609,7 @@ def representative_point(self): """ Return a "generic" point of ``self``. - OUTPUT: - - A point in the relative interior of ``self`` as a coordinate vector. + OUTPUT: a point in the relative interior of ``self`` as a coordinate vector EXAMPLES:: @@ -676,7 +656,6 @@ def _test_convex_set(self, tester=None, **options): Failure in _test_convex_set: ... The following tests failed: _test_convex_set - """ if tester is None: tester = self._tester(**options) @@ -721,7 +700,7 @@ def an_element(self): r""" Return a point of ``self``. - If ``self`` is empty, an :class:`EmptySetError` will be raised. + If ``self`` is empty, an :exc:`EmptySetError` will be raised. The default implementation delegates to :meth:`_some_elements_`. @@ -790,9 +769,7 @@ def cartesian_product(self, other): - ``other`` -- another convex set - OUTPUT: - - The Cartesian product of ``self`` and ``other``. + OUTPUT: the Cartesian product of ``self`` and ``other`` TESTS:: @@ -908,9 +885,7 @@ def intersection(self, other): - ``other`` -- another convex set - OUTPUT: - - The intersection. + OUTPUT: the intersection TESTS:: @@ -928,7 +903,7 @@ def dilation(self, scalar): INPUT: - - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring` + - ``scalar`` -- a scalar, not necessarily in :meth:`base_ring` EXAMPLES:: @@ -998,9 +973,7 @@ def is_closed(self): r""" Return whether ``self`` is closed. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1014,9 +987,7 @@ def is_open(self): r""" Return whether ``self`` is open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1038,11 +1009,9 @@ class ConvexSet_compact(ConvexSet_closed): def is_universe(self): r""" - Return whether ``self`` is the whole ambient space - - OUTPUT: + Return whether ``self`` is the whole ambient space. - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1060,9 +1029,7 @@ def is_compact(self): r""" Return whether ``self`` is compact. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1084,9 +1051,7 @@ def is_relatively_open(self): r""" Return whether ``self`` is relatively open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1101,9 +1066,7 @@ def is_open(self): r""" Return whether ``self`` is open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1124,9 +1087,7 @@ def is_open(self): r""" Return whether ``self`` is open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1141,9 +1102,7 @@ def is_closed(self): r""" Return whether ``self`` is closed. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 864a9237ee7..86cd4c83c65 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -269,11 +269,9 @@ def is_Fan(x) -> bool: INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - ``True`` if ``x`` is a fan and ``False`` otherwise + OUTPUT: ``True`` if ``x`` is a fan and ``False`` otherwise EXAMPLES:: @@ -376,9 +374,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, union of the cones in the polyhedral fan equals to the union of the given cones, and each given cone is the union of some cones in the polyhedral fan. - OUTPUT: - - a :class:`fan ` + OUTPUT: a :class:`fan ` .. SEEALSO:: @@ -694,9 +690,7 @@ def FaceFan(polytope, lattice=None): other object that behaves like these. If not specified, an attempt will be made to determine an appropriate toric lattice automatically. - OUTPUT: - - :class:`rational polyhedral fan ` + OUTPUT: :class:`rational polyhedral fan ` See also :func:`NormalFan`. @@ -802,9 +796,7 @@ def NormalFan(polytope, lattice=None): other object that behaves like these. If not specified, an attempt will be made to determine an appropriate toric lattice automatically. - OUTPUT: - - :class:`rational polyhedral fan ` + OUTPUT: :class:`rational polyhedral fan ` See also :func:`FaceFan`. @@ -943,7 +935,7 @@ def Fan2d(rays, lattice=None): sage: Fan2d([(0,1), (1,0), (0,0)]) Traceback (most recent call last): ... - ValueError: only non-zero vectors define rays + ValueError: only nonzero vectors define rays sage: Fan2d([(0, -2), (2, -10), (1, -3), (2, -9), (2, -12), (1, 1), ....: (2, 1), (1, -5), (0, -6), (1, -7), (0, 1), (2, -4), @@ -994,7 +986,7 @@ def Fan2d(rays, lattice=None): r0 = sorted_rays[i-1][1] r1 = sorted_rays[i][1] if r1.is_zero(): - raise ValueError('only non-zero vectors define rays') + raise ValueError('only nonzero vectors define rays') assert r0 != r1 cross_prod = r0[0] * r1[1] - r0[1] * r1[0] if cross_prod < 0: @@ -1021,14 +1013,12 @@ class Cone_of_fan(ConvexRationalPolyhedralCone): INPUT: - - ``ambient`` -- fan whose cone is constructed; + - ``ambient`` -- fan whose cone is constructed - ``ambient_ray_indices`` -- increasing list or tuple of integers, indices - of rays of ``ambient`` generating this cone. - - OUTPUT: + of rays of ``ambient`` generating this cone - cone of ``ambient`` + OUTPUT: cone of ``ambient`` EXAMPLES: @@ -1067,9 +1057,7 @@ def _repr_(self) -> str: r""" Return a string representation of ``self``. - OUTPUT: - - string + OUTPUT: string TESTS:: @@ -1089,9 +1077,7 @@ def star_generator_indices(self): Return indices of generating cones of the "ambient fan" containing ``self``. - OUTPUT: - - increasing :class:`tuple` of integers + OUTPUT: increasing :class:`tuple` of integers EXAMPLES:: @@ -1141,9 +1127,7 @@ def star_generators(self): Return indices of generating cones of the "ambient fan" containing ``self``. - OUTPUT: - - increasing :class:`tuple` of integers + OUTPUT: increasing :class:`tuple` of integers EXAMPLES:: @@ -1261,9 +1245,9 @@ def __call__(self, dim=None, codim=None): INPUT: - - ``dim`` -- dimension of the requested cones; + - ``dim`` -- dimension of the requested cones - - ``codim`` -- codimension of the requested cones. + - ``codim`` -- codimension of the requested cones OUTPUT: @@ -1307,11 +1291,9 @@ def __richcmp__(self, right, op): INPUT: - - ``right`` -- anything. - - OUTPUT: + - ``right`` -- anything - boolean + OUTPUT: boolean There is equality if ``right`` is also a fan, their rays are the same and stored in the same order, and their generating @@ -1372,9 +1354,7 @@ def __iter__(self): r""" Return an iterator over generating cones of ``self``. - OUTPUT: - - iterator + OUTPUT: iterator TESTS:: @@ -1523,9 +1503,7 @@ def FanFace(rays, cones): head.extend(rays_to_index[(n,)] for n in range(self.nrays())) new_order = head + [n for n in new_order if n not in head] # "Invert" this list to a dictionary - labels = {} - for new, old in enumerate(new_order): - labels[old] = new + labels = {old: new for new, old in enumerate(new_order)} L.relabel(labels) elements = [None] * next_index @@ -1536,7 +1514,7 @@ def FanFace(rays, cones): # ray incidence information to the total list, it would be # confused with the generating cone in the case of a single cone. elements[labels[0]] = FanFace(tuple(range(self.nrays())), ()) - D = {i: f for i, f in enumerate(elements)} + D = dict(enumerate(elements)) L.relabel(D) self._cone_lattice = FinitePoset(L, elements, key=id(self)) @@ -1549,7 +1527,7 @@ def _contains(self, cone) -> bool: INPUT: - - ``cone`` -- anything. + - ``cone`` -- anything OUTPUT: @@ -1735,9 +1713,7 @@ def common_refinement(self, other): - ``other`` -- a :class:`fan ` in the same :meth:`lattice` and with the same support as this fan - OUTPUT: - - a :class:`fan ` + OUTPUT: a :class:`fan ` EXAMPLES: @@ -1791,9 +1767,7 @@ def _latex_(self) -> str: r""" Return a LaTeX representation of ``self``. - OUTPUT: - - string + OUTPUT: string TESTS:: @@ -1811,7 +1785,7 @@ def _ray_to_cones(self, i=None): INPUT: - - ``i`` -- integer, index of a ray of ``self``. + - ``i`` -- integer; index of a ray of ``self`` OUTPUT: @@ -1848,9 +1822,7 @@ def _repr_(self) -> str: r""" Return a string representation of ``self``. - OUTPUT: - - string + OUTPUT: string TESTS:: @@ -1880,13 +1852,11 @@ def _subdivide_stellar(self, new_rays, verbose): INPUT: - ``new_rays`` -- immutable primitive vectors in the lattice of - ``self``; - - - ``verbose`` -- if ``True``, some timing information will be printed. + ``self`` - OUTPUT: + - ``verbose`` -- if ``True``, some timing information will be printed - rational polyhedral fan + OUTPUT: rational polyhedral fan TESTS:: @@ -1963,7 +1933,7 @@ def cone_containing(self, *points): We think of the origin as of the smallest cone containing no rays at all. If there is no ray in ``self`` that contains all ``rays``, - a :class:`ValueError` exception will be raised. + a :exc:`ValueError` exception will be raised. EXAMPLES:: @@ -2180,9 +2150,7 @@ def __getstate__(self): r""" Return the dictionary that should be pickled. - OUTPUT: - - :class:`dict` + OUTPUT: :class:`dict` TESTS:: @@ -2206,9 +2174,9 @@ def cones(self, dim=None, codim=None): INPUT: - - ``dim`` -- dimension of the requested cones; + - ``dim`` -- dimension of the requested cones - - ``codim`` -- codimension of the requested cones. + - ``codim`` -- codimension of the requested cones .. NOTE:: @@ -2290,7 +2258,7 @@ def contains(self, cone) -> bool: INPUT: - - ``cone`` -- anything. + - ``cone`` -- anything OUTPUT: @@ -2359,7 +2327,7 @@ def embed(self, cone): or :meth:`~sage.geometry.cone.ConvexRationalPolyhedralCone.facet_of`. The cone returned by this method will have ``self`` as ambient. If ``cone`` - does not represent a valid cone of ``self``, :class:`ValueError` + does not represent a valid cone of ``self``, :exc:`ValueError` exception is raised. .. NOTE:: @@ -2372,7 +2340,7 @@ def embed(self, cone): INPUT: - ``cone`` -- a :class:`cone - `. + ` OUTPUT: @@ -2456,9 +2424,7 @@ def Gale_transform(self): r""" Return the Gale transform of ``self``. - OUTPUT: - - A matrix over `ZZ` + OUTPUT: a matrix over `ZZ` EXAMPLES:: @@ -2479,11 +2445,9 @@ def generating_cone(self, n): INPUT: - - ``n`` -- integer, the index of a generating cone. - - OUTPUT: + - ``n`` -- integer; the index of a generating cone - :class:`cone of fan` + OUTPUT: :class:`cone of fan` EXAMPLES:: @@ -2497,9 +2461,7 @@ def generating_cones(self): r""" Return generating cones of ``self``. - OUTPUT: - - :class:`tuple` of :class:`cones of fan` + OUTPUT: :class:`tuple` of :class:`cones of fan` EXAMPLES:: @@ -2572,9 +2534,7 @@ def is_complete(self) -> bool: A rational polyhedral fan is *complete* if its cones fill the whole space. - OUTPUT: - - ``True`` if ``self`` is complete and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is complete and ``False`` otherwise EXAMPLES:: @@ -2612,7 +2572,7 @@ def is_equivalent(self, other) -> bool: INPUT: - - ``other`` -- fan. + - ``other`` -- fan OUTPUT: @@ -2688,7 +2648,7 @@ def is_isomorphic(self, other) -> bool: INPUT: - - ``other`` -- a :class:`fan `. + - ``other`` -- a :class:`fan ` OUTPUT: @@ -2755,9 +2715,7 @@ def _2d_echelon_forms(self): """ Return all echelon forms of the cyclically ordered rays of a 2-d fan. - OUTPUT: - - A set of integer matrices + OUTPUT: a set of integer matrices EXAMPLES:: @@ -2777,9 +2735,7 @@ def _2d_echelon_form(self): """ Return the echelon form of one particular cyclic order of rays of a 2-d fan. - OUTPUT: - - An integer matrix whose columns are the rays in the echelon form + OUTPUT: integer matrix whose columns are the rays in the echelon form EXAMPLES:: @@ -2797,7 +2753,7 @@ def isomorphism(self, other): INPUT: - - ``other`` -- fan. + - ``other`` -- fan OUTPUT: @@ -2843,9 +2799,7 @@ def is_simplicial(self) -> bool: i.e. primitive vectors along generating rays of every cone form a part of a *rational* basis of the ambient space. - OUTPUT: - - ``True`` if ``self`` is simplicial and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is simplicial and ``False`` otherwise EXAMPLES:: @@ -2890,7 +2844,7 @@ def is_smooth(self, codim=None) -> bool: INPUT: - ``codim`` -- codimension in which smoothness has to be checked, by - default complete smoothness will be checked. + default complete smoothness will be checked OUTPUT: @@ -2962,9 +2916,7 @@ def ngenerating_cones(self): r""" Return the number of generating cones of ``self``. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -2988,9 +2940,7 @@ def plot(self, **options): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: - - a plot + OUTPUT: a plot EXAMPLES:: @@ -3005,7 +2955,7 @@ def plot(self, **options): return result def subdivide(self, new_rays=None, make_simplicial=False, - algorithm="default", verbose=False): + algorithm='default', verbose=False): r""" Construct a new fan subdividing ``self``. @@ -3022,7 +2972,7 @@ def subdivide(self, new_rays=None, make_simplicial=False, "default"; - ``verbose`` -- if ``True``, some timing information may be printed - during the process of subdivision. + during the process of subdivision OUTPUT: @@ -3102,7 +3052,7 @@ def virtual_rays(self, *args): INPUT: - - ``ray_list`` -- a list of integers, the indices of the + - ``ray_list`` -- list of integers; the indices of the requested virtual rays. If not specified, all virtual rays of ``self`` will be returned. @@ -3256,9 +3206,7 @@ def Stanley_Reisner_ideal(self, ring): - A polynomial ring in ``self.nrays()`` variables. - OUTPUT: - - The Stanley-Reisner ideal in the given polynomial ring + OUTPUT: the Stanley-Reisner ideal in the given polynomial ring EXAMPLES:: @@ -3307,7 +3255,7 @@ def oriented_boundary(self, cone): INPUT: - - ``cone`` -- a cone of the fan or the whole fan. + - ``cone`` -- a cone of the fan or the whole fan OUTPUT: @@ -3433,11 +3381,9 @@ def toric_variety(self, *args, **kwds): INPUT: - same arguments as :func:`~sage.schemes.toric.variety.ToricVariety` - - OUTPUT: + Same arguments as :func:`~sage.schemes.toric.variety.ToricVariety`. - a toric variety + OUTPUT: a toric variety This is equivalent to the command ``ToricVariety(self)`` and is provided only as a convenient alternative method to go from the @@ -3467,7 +3413,7 @@ def complex(self, base_ring=ZZ, extended=False): \ZZ^{\Sigma(0)} \longrightarrow 0 - where the leftmost non-zero entry is in degree `0` and the + where the leftmost nonzero entry is in degree `0` and the rightmost entry in degree `d`. See [Kly1990]_, eq. (3.2). This complex computes the homology of `|\Sigma|\subset N_\RR` with arbitrary support, @@ -3478,7 +3424,7 @@ def complex(self, base_ring=ZZ, extended=False): For a complete fan, this is just the non-compactly supported homology of `\RR^d`. In this case, `H_0(K)=\ZZ` and `0` in all - non-zero degrees. + nonzero degrees. For a complete fan, there is an extended chain complex @@ -3501,18 +3447,18 @@ def complex(self, base_ring=ZZ, extended=False): INPUT: - - ``extended`` -- Boolean (default: ``False``). Whether to + - ``extended`` -- boolean (default: ``False``); whether to construct the extended complex, that is, including the - `\ZZ`-term at degree -1 or not. + `\ZZ`-term at degree -1 or not - - ``base_ring`` -- A ring (default: ``ZZ``). The ring to use - instead of `\ZZ`. + - ``base_ring`` -- a ring (default: ``ZZ``); the ring to use + instead of `\ZZ` OUTPUT: The complex associated to the fan as a :class:`ChainComplex `. This raises a - :class:`ValueError` if the extended complex is requested for a + :exc:`ValueError` if the extended complex is requested for a non-complete fan. EXAMPLES:: @@ -3606,8 +3552,8 @@ def discard_faces(cones): INPUT: - - ``cones`` -- a list of - :class:`cones `. + - ``cones`` -- list of + :class:`cones ` OUTPUT: @@ -3651,11 +3597,9 @@ def _refine_arrangement_to_fan(cones): INPUT: - - ``cones`` -- a list of rational cones that are possibly overlapping. - - OUTPUT: + - ``cones`` -- list of rational cones that are possibly overlapping - a list of refined cones + OUTPUT: list of refined cones EXAMPLES:: diff --git a/src/sage/geometry/fan_isomorphism.py b/src/sage/geometry/fan_isomorphism.py index d06fb1f6688..bae1501e897 100644 --- a/src/sage/geometry/fan_isomorphism.py +++ b/src/sage/geometry/fan_isomorphism.py @@ -29,11 +29,9 @@ def fan_isomorphic_necessary_conditions(fan1, fan2): INPUT: - - ``fan1``, ``fan2`` -- two fans. + - ``fan1``, ``fan2`` -- two fans - OUTPUT: - - Boolean. ``False`` if the two fans cannot be isomorphic. ``True`` + OUTPUT: boolean; ``False`` if the two fans cannot be isomorphic. ``True`` if the two fans may be isomorphic. EXAMPLES:: @@ -69,7 +67,7 @@ def fan_isomorphism_generator(fan1, fan2): INPUT: - - ``fan1``, ``fan2`` -- two fans. + - ``fan1``, ``fan2`` -- two fans OUTPUT: @@ -193,16 +191,16 @@ def find_isomorphism(fan1, fan2, check=False): INPUT: - - ``fan1``, ``fan2`` -- two fans. + - ``fan1``, ``fan2`` -- two fans - - ``check`` -- boolean (default: ``False``). Passed to the fan + - ``check`` -- boolean (default: ``False``); passed to the fan morphism constructor, see - :func:`~sage.geometry.fan_morphism.FanMorphism`. + :func:`~sage.geometry.fan_morphism.FanMorphism` OUTPUT: A fan isomorphism. If the fans are not isomorphic, a - :class:`FanNotIsomorphicError` is raised. + :exc:`FanNotIsomorphicError` is raised. EXAMPLES:: @@ -251,7 +249,7 @@ def fan_2d_cyclically_ordered_rays(fan): INPUT: - - ``fan`` -- a 2-dimensional fan. + - ``fan`` -- a 2-dimensional fan OUTPUT: @@ -302,7 +300,7 @@ def fan_2d_echelon_forms(fan): INPUT: - - ``fan`` -- a fan. + - ``fan`` -- a fan OUTPUT: @@ -373,7 +371,7 @@ def fan_2d_echelon_form(fan): INPUT: - - ``fan`` -- a fan. + - ``fan`` -- a fan OUTPUT: diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index 7ef46b80d17..ddefd299133 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -89,7 +89,7 @@ from sage.modules.free_module_morphism import FreeModuleMorphism from sage.rings.infinity import Infinity from sage.rings.integer_ring import ZZ -from sage.rings.infinity import is_Infinite +from sage.rings.infinity import InfinityElement from functools import reduce @@ -122,29 +122,27 @@ class FanMorphism(FreeModuleMorphism): integral matrix defining such a morphism; - ``domain_fan`` -- a :class:`fan - ` in the domain; + ` in the domain - ``codomain`` -- (default: ``None``) either a codomain lattice or a fan in the codomain. If the codomain fan is not given, the image fan (fan generated by images of generating cones) of ``domain_fan`` will be used, - if possible; + if possible. - - ``subdivide`` -- (default: ``False``) if ``True`` and ``domain_fan`` is + - ``subdivide`` -- boolean (default: ``False``); if ``True`` and ``domain_fan`` is not compatible with the codomain fan because it is too coarse, it will be automatically refined to become compatible (the minimal refinement is - canonical, so there are no choices involved); + canonical, so there are no choices involved) - - ``check`` -- (default: ``True``) if ``False``, given fans and morphism + - ``check`` -- boolean (default: ``True``); if ``False``, given fans and morphism will be assumed to be compatible. Be careful when using this option, since wrong assumptions can lead to wrong and hard-to-detect errors. On - the other hand, this option may save you some time; + the other hand, this option may save you some time. - - ``verbose`` -- (default: ``False``) if ``True``, some information may be - printed during construction of the fan morphism. + - ``verbose`` -- boolean (default: ``False``); if ``True``, some information may be + printed during construction of the fan morphism - OUTPUT: - - - a fan morphism. + OUTPUT: a fan morphism EXAMPLES: @@ -266,7 +264,7 @@ def __init__(self, morphism, domain_fan, [0 1] Domain fan: Rational polyhedral fan in 2-d lattice N Codomain fan: Rational polyhedral fan in 2-d lattice N - sage: TestSuite(fm).run(skip="_test_category") + sage: TestSuite(fm).run(skip='_test_category') """ assert isinstance(domain_fan, RationalPolyhedralFan) if isinstance(codomain, RationalPolyhedralFan): @@ -307,11 +305,9 @@ def __mul__(self, right): INPUT: - ``right`` -- a :class:`FanMorphism` whose :meth:`codomain_fan` can be - mapped to :meth:`domain_fan` of ``self`` via identity map of lattices. - - OUTPUT: + mapped to :meth:`domain_fan` of ``self`` via identity map of lattices - - a :class:`FanMorphism`. + OUTPUT: a :class:`FanMorphism` EXAMPLES:: @@ -392,7 +388,7 @@ def _chambers(self): - ``chambers`` is a :class:`list` of :class:`cones ` in the domain of - ``self``; + ``self`` - ``cone_to_chamber`` is a :class:`list` of integers, if its `i`-th element is `j`, then the `j`-th element of ``chambers`` is the @@ -444,11 +440,9 @@ def _construct_codomain_fan(self, check): INPUT: - - ``check`` -- passed on to the fan constructor. - - OUTPUT: + - ``check`` -- passed on to the fan constructor - - none, but the codomain fan of ``self`` is set to the constructed fan. + OUTPUT: none, but the codomain fan of ``self`` is set to the constructed fan TESTS:: @@ -481,9 +475,7 @@ def _latex_(self): r""" Return the `\LaTeX` representation of ``self``. - OUTPUT: - - - a :class:`string`. + OUTPUT: a :class:`string` EXAMPLES:: @@ -518,7 +510,7 @@ def _ray_index_map(self): domain fan is mapped to the origin. If it is `j`, then the `i`-th ray of the domain fan is mapped onto the `j`-th ray of the codomain fan. If there is a ray in the domain fan which is mapped into the relative - interior of a higher dimensional cone, a :class:`ValueError` + interior of a higher dimensional cone, a :exc:`ValueError` exception is raised. .. NOTE:: @@ -554,9 +546,7 @@ def _repr_(self): r""" Return the string representation of ``self``. - OUTPUT: - - - a :class:`string`. + OUTPUT: a :class:`string` EXAMPLES:: @@ -587,19 +577,19 @@ def _subdivide_domain_fan(self, check, verbose): INPUT: - - ``check`` -- (default: ``True``) if ``False``, some of the + - ``check`` -- boolean (default: ``True``); if ``False``, some of the consistency checks will be omitted, which saves time but can potentially lead to wrong results. Currently, with ``check=False`` option there will be no check that ``domain_fan`` - maps to ``codomain_fan``; + maps to ``codomain_fan`` - - ``verbose`` -- (default: ``False``) if ``True``, some timing - information will be printed in the process. + - ``verbose`` -- boolean (default: ``False``); if ``True``, some timing + information will be printed in the process OUTPUT: - - none, but the domain fan of self is replaced with its minimal - refinement, if possible. Otherwise a :class:`ValueError` + - none, but the domain fan of ``self`` is replaced with its minimal + refinement, if possible. Otherwise a :exc:`ValueError` exception is raised. TESTS:: @@ -761,11 +751,9 @@ def _subdivide_domain_fan(self, check, verbose): def _support_error(self): r""" - Raise a :class:`ValueError` exception due to support incompatibility. + Raise a :exc:`ValueError` exception due to support incompatibility. - OUTPUT: - - - none, a :class:`ValueError` exception is raised. + OUTPUT: none, a :exc:`ValueError` exception is raised TESTS: @@ -804,7 +792,7 @@ def _validate(self): OUTPUT: - - none, but a :class:`ValueError` exception is raised if there is + - none, but a :exc:`ValueError` exception is raised if there is a cone of the domain fan of ``self`` which is not completely contained in a single cone of the codomain fan of ``self``, or if one of these fans does not sit in the appropriate lattice. @@ -894,9 +882,9 @@ def codomain_fan(self, dim=None, codim=None): INPUT: - - ``dim`` -- dimension of the requested cones; + - ``dim`` -- dimension of the requested cones - - ``codim`` -- codimension of the requested cones. + - ``codim`` -- codimension of the requested cones OUTPUT: @@ -924,9 +912,9 @@ def domain_fan(self, dim=None, codim=None): INPUT: - - ``dim`` -- dimension of the requested cones; + - ``dim`` -- dimension of the requested cones - - ``codim`` -- codimension of the requested cones. + - ``codim`` -- codimension of the requested cones OUTPUT: @@ -1020,9 +1008,7 @@ def index(self, cone=None): ` of the :meth:`codomain_fan` of ``self``. - OUTPUT: - - - an integer, infinity, or ``None``. + OUTPUT: integer, infinity, or ``None`` If no cone was specified, this function computes the index of the image of ``self`` in the codomain. If a cone `\sigma` was given, the @@ -1122,9 +1108,7 @@ def is_birational(self): r""" Check if ``self`` is birational. - OUTPUT: - - - ``True`` if ``self`` is birational, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is birational, ``False`` otherwise For fan morphisms this check is equivalent to ``self.index() == 1`` and means that the corresponding map between toric varieties is birational. @@ -1149,9 +1133,7 @@ def is_bundle(self): r""" Check if ``self`` is a bundle. - OUTPUT: - - - ``True`` if ``self`` is a bundle, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is a bundle, ``False`` otherwise Let `\phi: \Sigma \to \Sigma'` be a fan morphism such that the underlying lattice morphism `\phi: N \to N'` is surjective. Let @@ -1246,9 +1228,7 @@ def is_fibration(self): r""" Check if ``self`` is a fibration. - OUTPUT: - - - ``True`` if ``self`` is a fibration, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is a fibration, ``False`` otherwise A fan morphism `\phi: \Sigma \to \Sigma'` is a **fibration** if for any cone `\sigma' \in \Sigma'` and any primitive @@ -1334,9 +1314,7 @@ def is_injective(self): r""" Check if ``self`` is injective. - OUTPUT: - - - ``True`` if ``self`` is injective, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is injective, ``False`` otherwise Let `\phi: \Sigma \to \Sigma'` be a fan morphism such that the underlying lattice morphism `\phi: N \to N'` bijectively maps `N` to a @@ -1407,9 +1385,7 @@ def is_surjective(self): r""" Check if ``self`` is surjective. - OUTPUT: - - - ``True`` if ``self`` is surjective, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is surjective, ``False`` otherwise A fan morphism `\phi: \Sigma \to \Sigma'` is **surjective** if the corresponding map between cones is surjective, i.e. for each cone @@ -1458,7 +1434,7 @@ def is_surjective(self): sage: phi.is_surjective() False """ - if is_Infinite(self.index()): + if isinstance(self.index(), InfinityElement): return False # Not surjective between vector spaces. for dcones in self.codomain_fan().cones(): for sigma_p in dcones: @@ -1484,9 +1460,7 @@ def is_dominant(self): of toric varieties is dominant in the algebraic-geometric sense (that is, surjective onto a dense subset). - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1505,9 +1479,7 @@ def kernel_fan(self): r""" Return the subfan of the domain fan mapped into the origin. - OUTPUT: - - - a :class:`fan `. + OUTPUT: a :class:`fan ` .. NOTE:: @@ -1607,11 +1579,9 @@ def preimage_fan(self, cone): - ``cone`` -- a :class:`cone ` equivalent to a - cone of the :meth:`codomain_fan` of ``self``. - - OUTPUT: + cone of the :meth:`codomain_fan` of ``self`` - - a :class:`fan `. + OUTPUT: a :class:`fan ` .. NOTE:: @@ -1663,11 +1633,9 @@ def primitive_preimage_cones(self, cone): - ``cone`` -- a :class:`cone ` equivalent to a - cone of the :meth:`codomain_fan` of ``self``. - - OUTPUT: + cone of the :meth:`codomain_fan` of ``self`` - - a :class:`cone `. + OUTPUT: a :class:`cone ` Let `\phi: \Sigma \to \Sigma'` be a fan morphism, let `\sigma \in \Sigma`, and let `\sigma' = \phi(\sigma)`. Then `\sigma` is a @@ -1759,7 +1727,7 @@ def factor(self): \hookrightarrow \Sigma. - .. note:: + .. NOTE:: * `\Sigma_s` is the finest fan with the smallest support that is compatible with ``self``: any fan morphism from `\Sigma` given by @@ -1890,7 +1858,7 @@ def relative_star_generators(self, domain_cone): INPUT: - - ``domain_cone`` -- a cone of the :meth:`domain_fan` of ``self``. + - ``domain_cone`` -- a cone of the :meth:`domain_fan` of ``self`` OUTPUT: diff --git a/src/sage/geometry/hasse_diagram.py b/src/sage/geometry/hasse_diagram.py index d30f08ac8d5..74a30abed6d 100644 --- a/src/sage/geometry/hasse_diagram.py +++ b/src/sage/geometry/hasse_diagram.py @@ -30,11 +30,11 @@ def lattice_from_incidences(atom_to_coatoms, coatom_to_atoms, INPUT: - - ``atom_to_coatoms`` -- list, ``atom_to_coatom[i]`` should list all - coatoms over the ``i``-th atom; + - ``atom_to_coatoms`` -- list; ``atom_to_coatom[i]`` should list all + coatoms over the ``i``-th atom - - ``coatom_to_atoms`` -- list, ``coatom_to_atom[i]`` should list all - atoms under the ``i``-th coatom; + - ``coatom_to_atoms`` -- list; ``coatom_to_atom[i]`` should list all + atoms under the ``i``-th coatom - ``face_constructor`` -- function or class taking as the first two arguments sorted :class:`tuple` of integers and any keyword arguments. @@ -42,15 +42,15 @@ def lattice_from_incidences(atom_to_coatoms, coatom_to_atoms, argument and under coatoms passed as the second argument. Default implementation will just return these two tuples as a tuple; - - ``required_atoms`` -- list of atoms (default:None). Each + - ``required_atoms`` -- list of atoms (default: ``None``); each non-empty "face" requires at least one of the specified atoms present. Used to ensure that each face has a vertex. - - ``key`` -- any hashable value (default: None). It is passed down - to :class:`~sage.combinat.posets.posets.FinitePoset`. + - ``key`` -- any hashable value (default: ``None``); it is passed down + to :class:`~sage.combinat.posets.posets.FinitePoset` - all other keyword arguments will be passed to ``face_constructor`` on - each call. + each call OUTPUT: @@ -188,9 +188,7 @@ def default_face_constructor(atoms, coatoms, **kwds): if required_atoms is None or atom in required_atoms) new_order = head + [n for n in new_order if n not in head] # "Invert" this list to a dictionary - labels = {} - for new, old in enumerate(new_order): - labels[old] = new + labels = {old: new for new, old in enumerate(new_order)} L.relabel(labels) # Construct the actual poset elements elements = [None] * next_index @@ -198,6 +196,6 @@ def default_face_constructor(atoms, coatoms, **kwds): atoms, coatoms = face elements[labels[index]] = face_constructor( tuple(sorted(atoms)), tuple(sorted(coatoms)), **kwds) - D = {i: f for i, f in enumerate(elements)} + D = dict(enumerate(elements)) L.relabel(D) return FiniteLatticePoset(L, elements, key=key) diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py b/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py index ff509d0d97f..1e2c7270b39 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py @@ -29,6 +29,7 @@ from sage.misc.lazy_import import lazy_import lazy_import('sage.misc.call', 'attrcall') + class HyperbolicModelCoercion(Morphism): """ Abstract base class for morphisms between the hyperbolic models. @@ -148,6 +149,7 @@ def __invert__(self): # From UHP # ############ + class CoercionUHPtoPD(HyperbolicModelCoercion): """ Coercion from the UHP to PD model. @@ -188,6 +190,7 @@ def image_isometry_matrix(self, x): return matrix([[1,-I],[-I,1]]) * x * matrix([[1,I],[I,1]]).conjugate()/Integer(2) return matrix([[1,-I],[-I,1]]) * x * matrix([[1,I],[I,1]])/Integer(2) + class CoercionUHPtoKM(HyperbolicModelCoercion): """ Coercion from the UHP to KM model. @@ -227,6 +230,7 @@ def image_isometry_matrix(self, x): """ return SL2R_to_SO21(x) + class CoercionUHPtoHM(HyperbolicModelCoercion): """ Coercion from the UHP to HM model. @@ -269,6 +273,7 @@ def image_isometry_matrix(self, x): # From PD # ########### + class CoercionPDtoUHP(HyperbolicModelCoercion): """ Coercion from the PD to UHP model. @@ -318,6 +323,7 @@ def image_isometry_matrix(self, x): return matrix([[1,I],[I,1]]) * x * matrix([[1,-I],[-I,1]]).conjugate() / Integer(2) return matrix([[1,I],[I,1]]) * x * matrix([[1,-I],[-I,1]]) / Integer(2) + class CoercionPDtoKM(HyperbolicModelCoercion): """ Coercion from the PD to KM model. @@ -444,6 +450,7 @@ def image_isometry_matrix(self, x): """ return SO21_to_SL2R(x) + class CoercionKMtoPD(HyperbolicModelCoercion): """ Coercion from the KM to PD model. @@ -482,6 +489,7 @@ def image_isometry_matrix(self, x): return (matrix(2,[1,-I,-I,1]) * SO21_to_SL2R(x) * matrix(2,[1,I,I,1])/Integer(2)) + class CoercionKMtoHM(HyperbolicModelCoercion): """ Coercion from the KM to HM model. @@ -524,6 +532,7 @@ def image_isometry_matrix(self, x): # From HM # ########### + class CoercionHMtoUHP(HyperbolicModelCoercion): """ Coercion from the HM to UHP model. @@ -560,6 +569,7 @@ def image_isometry_matrix(self, x): """ return SO21_to_SL2R(x) + class CoercionHMtoPD(HyperbolicModelCoercion): """ Coercion from the HM to PD model. @@ -596,6 +606,7 @@ def image_isometry_matrix(self, x): return (matrix(2,[1,-I,-I,1]) * SO21_to_SL2R(x) * matrix(2,[1,I,I,1])/Integer(2)) + class CoercionHMtoKM(HyperbolicModelCoercion): """ Coercion from the HM to KM model. @@ -635,6 +646,7 @@ def image_isometry_matrix(self, x): ##################################################################### ## Helper functions + def SL2R_to_SO21(A): r""" Given a matrix in `SL(2, \RR)` return its irreducible representation in @@ -649,7 +661,7 @@ def SL2R_to_SO21(A): sage: from sage.geometry.hyperbolic_space.hyperbolic_coercion import SL2R_to_SO21 sage: A = SL2R_to_SO21(identity_matrix(2)) sage: J = matrix([[1,0,0],[0,1,0],[0,0,-1]]) #Lorentzian Gram matrix - sage: norm(A.transpose()*J*A - J) < 10**-4 + sage: norm(A.transpose()*J*A - J) < 10**-4 # needs scipy True """ a, b, c, d = (A/A.det().sqrt()).list() @@ -689,7 +701,7 @@ def SO21_to_SL2R(M): EXAMPLES:: sage: from sage.geometry.hyperbolic_space.hyperbolic_coercion import SO21_to_SL2R - sage: (SO21_to_SL2R(identity_matrix(3)) - identity_matrix(2)).norm() < 10**-4 + sage: (SO21_to_SL2R(identity_matrix(3)) - identity_matrix(2)).norm() < 10**-4 # needs scipy True """ #################################################################### diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py index ae51d2431d2..b9488e77b16 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py @@ -131,7 +131,6 @@ class HyperbolicGeodesic(SageObject): Geodesic in KM from (0, 1/2) to (1/2, 0) sage: HyperbolicPlane().HM().get_geodesic((0,0,1), (0,1, sqrt(2))) Geodesic in HM from (0, 0, 1) to (0, 1, sqrt(2)) - """ ##################### @@ -162,7 +161,6 @@ def _cached_geodesic(self): sage: A = HyperbolicPlane().PD().get_geodesic(0, 1/2) sage: A._cached_geodesic Geodesic in UHP from I to 3/5*I + 4/5 - """ M = self._model.realization_of().a_realization() @@ -187,7 +185,6 @@ def _complete(self): False sage: g.complete()._complete True - """ if self._model.is_bounded(): @@ -215,7 +212,6 @@ def _repr_(self): sage: HM = HyperbolicPlane().HM() sage: HM.get_geodesic((0,0,1), (0, 1, sqrt(Integer(2)))) Geodesic in HM from (0, 0, 1) to (0, 1, sqrt(2)) - """ msg = "Geodesic in {0} from {1} to {2}" @@ -244,7 +240,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Test unequality of self and other. + Test unequality of ``self`` and ``other``. EXAMPLES:: @@ -270,7 +266,6 @@ def start(self): sage: g = HyperbolicPlane().UHP().get_geodesic(I, 3*I) sage: g.start() Point in UHP I - """ return self._start @@ -283,7 +278,6 @@ def end(self): sage: g = HyperbolicPlane().UHP().get_geodesic(I, 3*I) sage: g.end() Point in UHP 3*I - """ return self._end @@ -297,7 +291,6 @@ def endpoints(self): sage: g = HyperbolicPlane().UHP().get_geodesic(I, 3*I) sage: g.endpoints() [Point in UHP I, Point in UHP 3*I] - """ return [self._start, self._end] @@ -342,7 +335,6 @@ def to_model(self, model): Geodesic in PD from 0 to 1/3*I sage: UHP.get_geodesic(I, 2*I).to_model('PD') Geodesic in PD from 0 to 1/3*I - """ if isinstance(model, str): @@ -360,12 +352,10 @@ def graphics_options(self): EXAMPLES:: - sage: g = HyperbolicPlane().UHP().get_geodesic(I, 2*I, color="red") + sage: g = HyperbolicPlane().UHP().get_geodesic(I, 2*I, color='red') sage: g.graphics_options() {'color': 'red'} - """ - return self._graphics_options def update_graphics(self, update=False, **options): @@ -391,7 +381,6 @@ def update_graphics(self, update=False, **options): sage: g.update_graphics(True, size = 20); g.graphics_options() {'color': 'blue', 'size': 20} - """ if not update: @@ -447,7 +436,6 @@ def is_complete(self): True sage: UHP.get_geodesic(2,5).is_complete() True - """ return self._complete @@ -493,7 +481,6 @@ def is_asymptotically_parallel(self, other): sage: g = HyperbolicPlane().UHP().get_geodesic(-2,5) sage: g.is_asymptotically_parallel(g) False - """ p1, p2 = self.complete().endpoints() @@ -543,7 +530,6 @@ def is_ultra_parallel(self, other): sage: g = HyperbolicPlane().UHP().get_geodesic(-2,5) sage: g.is_ultra_parallel(g) False - """ A = self.reflection_involution() @@ -610,7 +596,6 @@ def is_parallel(self, other): sage: g = HyperbolicPlane().UHP().get_geodesic(-2,5) sage: g.is_parallel(g) False - """ A = self.reflection_involution() @@ -620,7 +605,7 @@ def is_parallel(self, other): def ideal_endpoints(self): r""" Return the ideal endpoints in bounded models. Raise a - :class:`NotImplementedError` in models that are not bounded. + :exc:`NotImplementedError` in models that are not bounded. EXAMPLES:: @@ -643,7 +628,6 @@ def ideal_endpoints(self): ... NotImplementedError: boundary points are not implemented in the HM model - """ if not self._model.is_bounded(): @@ -658,7 +642,7 @@ def ideal_endpoints(self): def complete(self): r""" Return the geodesic with ideal endpoints in bounded models. Raise a - :class:`NotImplementedError` in models that are not bounded. + :exc:`NotImplementedError` in models that are not bounded. In the following examples we represent complete geodesics by a dashed line. @@ -744,7 +728,6 @@ def complete(self): sage: gc = g.complete() sage: parent(gc.start().coordinates()) Real Field with 53 bits of precision - """ if self._model.is_bounded(): @@ -794,7 +777,7 @@ def reflection_involution(self): sage: g = HM.get_geodesic((0,0,1), (1,0, n(sqrt(2)))) sage: A = g.reflection_involution() sage: B = diagonal_matrix([1, -1, 1]) - sage: bool((B - A.matrix()).norm() < 10**-9) + sage: bool((B - A.matrix()).norm() < 10**-9) # needs scipy True The above tests go through the Upper Half Plane. It remains to @@ -805,7 +788,6 @@ def reflection_involution(self): sage: R = H.PD().get_geodesic(-1,1).reflection_involution() sage: bool(moebius_transform(R.matrix(), 0) == 0) True - """ ri = self._cached_geodesic.reflection_involution() @@ -815,15 +797,13 @@ def common_perpendicula(self, other): r""" Return the unique hyperbolic geodesic perpendicular to two given geodesics, if such a geodesic exists. If none exists, raise a - :class:`ValueError`. + :exc:`ValueError`. INPUT: - ``other`` -- a hyperbolic geodesic in the same model as ``self`` - OUTPUT: - - - a hyperbolic geodesic + OUTPUT: a hyperbolic geodesic EXAMPLES:: @@ -851,7 +831,6 @@ def common_perpendicula(self, other): Traceback (most recent call last): ... ValueError: geodesics intersect; no common perpendicular exists - """ if not self.is_parallel(other): @@ -869,14 +848,11 @@ def intersection(self, other): - ``other`` -- a hyperbolic geodesic in the same model as ``self`` - OUTPUT: - - - a hyperbolic point or geodesic + OUTPUT: a hyperbolic point or geodesic EXAMPLES:: sage: PD = HyperbolicPlane().PD() - """ if self == other: @@ -951,7 +927,6 @@ def midpoint(self): Traceback (most recent call last): ... ValueError: the length must be finite - """ UHP = self._model.realization_of().a_realization() @@ -968,9 +943,7 @@ def dist(self, other): - ``other`` -- a hyperbolic geodesic or hyperbolic point in the same model - OUTPUT: - - - the hyperbolic distance + OUTPUT: the hyperbolic distance EXAMPLES:: @@ -1000,7 +973,6 @@ def dist(self, other): 1.45057451382258 sage: parent(_) Real Field with 53 bits of precision - """ return self._model.dist(self, other) @@ -1014,9 +986,7 @@ def angle(self, other): - ``other`` -- a hyperbolic geodesic in the same model as ``self`` - OUTPUT: - - - the angle in radians between the two given geodesics + OUTPUT: the angle in radians between the two given geodesics EXAMPLES:: @@ -1032,7 +1002,6 @@ def angle(self, other): g = PD.get_geodesic(3.0/5.0*I + 4.0/5.0, 15.0/17.0*I + 8.0/17.0) h = PD.get_geodesic(4.0/5.0*I + 3.0/5.0, I) sphinx_plot(g.plot()+h.plot(color='orange')) - """ return self._cached_geodesic.angle(other) @@ -1046,7 +1015,6 @@ def length(self): sage: g = HyperbolicPlane().UHP().get_geodesic(2 + I, 3 + I/2) sage: g.length() arccosh(9/4) - """ return self._model._dist_points(self._start.coordinates(), @@ -1086,7 +1054,6 @@ class HyperbolicGeodesicUHP(HyperbolicGeodesic): g = UHP.get_geodesic(I, 2 + I) h = UHP.get_geodesic(-1, -1+2*I) sphinx_plot(g.plot()+h.plot()) - """ def reflection_involution(self): @@ -1105,7 +1072,6 @@ def reflection_involution(self): Isometry in UHP [ 1 0] [ 0 -1] - """ x, y = (real(k.coordinates()) for k in self.ideal_endpoints()) @@ -1135,13 +1101,13 @@ def plot(self, boundary=True, **options): :: - sage: UHP.get_geodesic(I, 3+4*I).plot(linestyle="dashed", color="brown") # needs sage.plot + sage: UHP.get_geodesic(I, 3+4*I).plot(linestyle='dashed', color='brown') # needs sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: UHP = HyperbolicPlane().UHP() - g = UHP.get_geodesic(I, 3+4*I).plot(linestyle="dashed", color="brown") + g = UHP.get_geodesic(I, 3+4*I).plot(linestyle='dashed', color='brown') sphinx_plot(g) :: @@ -1180,7 +1146,6 @@ def plot(self, boundary=True, **options): sage: g = HyperbolicPlane().UHP().get_geodesic(3, 4) sage: g.plot(boundary=False) # needs sage.plot Graphics object consisting of 1 graphics primitive - """ opts = {'axes': False, 'aspect_ratio': 1} @@ -1236,9 +1201,7 @@ def ideal_endpoints(self): Determine the ideal (boundary) endpoints of the complete hyperbolic geodesic corresponding to ``self``. - OUTPUT: - - - a list of 2 boundary points + OUTPUT: list of 2 boundary points EXAMPLES:: @@ -1249,7 +1212,6 @@ def ideal_endpoints(self): sage: UHP.get_geodesic(1 + I, 2 + 4*I).ideal_endpoints() [Boundary point in UHP -sqrt(65) + 9, Boundary point in UHP sqrt(65) + 9] - """ start = self._start.coordinates() @@ -1276,15 +1238,13 @@ def common_perpendicular(self, other): r""" Return the unique hyperbolic geodesic perpendicular to ``self`` and ``other``, if such a geodesic exists; otherwise raise a - :class:`ValueError`. + :exc:`ValueError`. INPUT: - ``other`` -- a hyperbolic geodesic in current model - OUTPUT: - - - a hyperbolic geodesic + OUTPUT: a hyperbolic geodesic EXAMPLES:: @@ -1311,7 +1271,6 @@ def common_perpendicular(self, other): Traceback (most recent call last): ... ValueError: geodesics intersect; no common perpendicular exists - """ # Make sure both are in the same model @@ -1335,9 +1294,7 @@ def intersection(self, other): - ``other`` -- a hyperbolic geodesic in the current model - OUTPUT: - - - a list of hyperbolic points or a hyperbolic geodesic + OUTPUT: list of hyperbolic points or a hyperbolic geodesic EXAMPLES:: @@ -1353,7 +1310,7 @@ def intersection(self, other): g = UHP.get_geodesic(3, 5) h = UHP.get_geodesic(4, 7) P = g.intersection(h) - pict = g.plot(color="red")+h.plot(color="red") + pict = g.plot(color='red')+h.plot(color='red') sphinx_plot(pict) If the given geodesics do not intersect, the function returns an @@ -1467,7 +1424,6 @@ def intersection(self, other): sage: g2=UHP.get_geodesic(3*I,infinity) sage: g1.intersection(g2) Geodesic in UHP from 3.00000000000000*I to +infinity - """ UHP = self.model() @@ -1602,7 +1558,7 @@ def perpendicular_bisector(self): # UHP ....: return bool(x.dist(m) < 1e-9) sage: c, d, e = CC(1, 1), CC(2, 1), CC(2, 0.5) sage: pairs = [(c, d), (d, c), (c, e), (e, c), (d, e), (e, d)] - sage: all(bisector_gets_midpoint(a, b) for a, b in pairs) + sage: all(bisector_gets_midpoint(a, b) for a, b in pairs) # needs scipy True """ if self.length() == infinity: @@ -1717,9 +1673,7 @@ def angle(self, other): # UHP - ``other`` -- a hyperbolic geodesic in the UHP model - OUTPUT: - - - the angle in radians between the two given geodesics + OUTPUT: the angle in radians between the two given geodesics EXAMPLES:: @@ -1917,7 +1871,6 @@ def angle(self, other): # UHP arccos(1/3) sage: h2.angle(g) arccos(1/3) - """ if self.is_parallel(other): @@ -1955,7 +1908,7 @@ def angle(self, other): # UHP # is ``infinity``. if infinity in [q1, q2]: p1, p2, q1, q2 = q1, q2, p1, p2 - # Then, if ``p1`` is infinity, swap ``p1` and ``p2`. This + # Then, if ``p1`` is infinity, swap ``p1`` and ``p2``. This # ensures that if any element of ``{p1, p2}`` is ``infinity``, # then that element is now ``p2``. if p1 == infinity: @@ -1994,7 +1947,7 @@ def _get_B(a): INPUT: - - ``a`` -- an element to identify the class of the resulting matrix. + - ``a`` -- an element to identify the class of the resulting matrix EXAMPLES:: @@ -2092,7 +2045,6 @@ def _to_std_geod(self, p): sage: parent(gc._to_std_geod(g.start().coordinates())) Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of precision - """ [s, e] = [k.coordinates() for k in self.complete().endpoints()] @@ -2115,13 +2067,11 @@ def _crossratio_matrix(p0, p1, p2): # UHP INPUT: - - a list of three distinct elements + - ``p0``, ``p1``, ``p2`` -- a list of three distinct elements of `\mathbb{CP}^1` in affine coordinates; that is, each element must be a complex number, `\infty`, or symbolic. - OUTPUT: - - - an element of `\GL(2,\CC)` + OUTPUT: an element of `\GL(2,\CC)` EXAMPLES:: @@ -2143,7 +2093,6 @@ def _crossratio_matrix(p0, p1, p2): # UHP sage: HyperbolicGeodesicUHP._crossratio_matrix(x,y,z) [ y - z -x*(y - z)] [ -x + y (x - y)*z] - """ if p0 == infinity: @@ -2222,10 +2171,10 @@ def plot(self, boundary=True, **options): sage: PD.get_geodesic(-0.5, 0.3+0.4*I).plot() # needs sage.plot Graphics object consisting of 2 graphics primitives sage: g = PD.get_geodesic(-1, exp(3*I*pi/7)) - sage: G = g.plot(linestyle="dashed",color="red"); G # needs sage.plot + sage: G = g.plot(linestyle='dashed',color='red'); G # needs sage.plot Graphics object consisting of 2 graphics primitives sage: h = PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)) - sage: H = h.plot(thickness=6, color="orange"); H # needs sage.plot + sage: H = h.plot(thickness=6, color='orange'); H # needs sage.plot Graphics object consisting of 2 graphics primitives sage: show(G+H) # needs sage.plot @@ -2234,11 +2183,10 @@ def plot(self, boundary=True, **options): PD = HyperbolicPlane().PD() PD.get_geodesic(-0.5, 0.3+0.4*I).plot() g = PD.get_geodesic(-1, exp(3*I*pi/7)) - G = g.plot(linestyle="dashed",color="red") + G = g.plot(linestyle='dashed',color='red') h = PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)) - H = h.plot(thickness=6, color="orange") + H = h.plot(thickness=6, color='orange') sphinx_plot(G+H) - """ opts = {'axes': False, 'aspect_ratio': 1} @@ -2302,7 +2250,6 @@ class HyperbolicGeodesicKM(HyperbolicGeodesic): h = KM.get_geodesic(CC(-0.707106781,-0.707106781), CC(0.707106781,-0.707106781)) sphinx_plot(g.plot(color='orange')+h.plot()) - """ def plot(self, boundary=True, **options): @@ -2318,7 +2265,6 @@ def plot(self, boundary=True, **options): KM = HyperbolicPlane().KM() sphinx_plot(KM.get_geodesic(CC(0,0), CC(1,0)).plot()) - """ opts = {'axes': False, 'aspect_ratio': 1} opts.update(self.graphics_options()) @@ -2365,7 +2311,6 @@ class HyperbolicGeodesicHM(HyperbolicGeodesic): p2 = HM.get_point((-3,-3,sqrt(19))) g = HM.get_geodesic(p1, p2) sphinx_plot(g.plot(color='blue')) - """ def _plot_vertices(self, points=75): r""" @@ -2379,7 +2324,7 @@ def _plot_vertices(self, points=75): sage: p1 = HM.get_point((4, -4, sqrt(33))) sage: p2 = HM.get_point((-3,-3,sqrt(19))) sage: g = HM.get_geodesic(p1, p2) - sage: g._plot_vertices(5) + sage: g._plot_vertices(5) # needs sage.plot [(4.0, -4.0, 5.744562...), (1.363213..., -1.637073..., 2.353372...), (0.138568..., -0.969980..., 1.400022...), @@ -2428,7 +2373,6 @@ def plot(self, show_hyperboloid=True, **graphics_options): .. PLOT:: sphinx_plot(HyperbolicPlane().HM().random_geodesic().plot()) - """ x = SR.var('x') diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py b/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py index 89e73b83a07..2dd20676215 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py @@ -1,3 +1,4 @@ +# sage.doctest: needs scipy r""" Hyperbolic Isometries @@ -88,7 +89,7 @@ def __init__(self, model, A, check=True): EXAMPLES:: sage: A = HyperbolicPlane().UHP().get_isometry(matrix(2, [0,1,-1,0])) - sage: TestSuite(A).run(skip="_test_category") + sage: TestSuite(A).run(skip='_test_category') """ if check: model.isometry_test(A) @@ -119,9 +120,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string EXAMPLES:: @@ -488,7 +487,7 @@ def classification(self): def translation_length(self): r""" For hyperbolic elements, return the translation length; - otherwise, raise a :class:`ValueError`. + otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -511,7 +510,7 @@ def translation_length(self): def axis(self): r""" For a hyperbolic isometry, return the axis of the - transformation; otherwise raise a :class:`ValueError`. + transformation; otherwise raise a :exc:`ValueError`. EXAMPLES:: @@ -539,9 +538,7 @@ def fixed_point_set(self): Return a list containing the fixed point set of orientation-preserving isometries. - OUTPUT: - - list of hyperbolic points or a hyperbolic geodesic + OUTPUT: list of hyperbolic points or a hyperbolic geodesic EXAMPLES:: @@ -592,11 +589,9 @@ def fixed_geodesic(self): def repelling_fixed_point(self): r""" For a hyperbolic isometry, return the attracting fixed point; - otherwise raise a :class:`ValueError`. - - OUTPUT: + otherwise raise a :exc:`ValueError`. - - a hyperbolic point + OUTPUT: a hyperbolic point EXAMPLES:: @@ -611,11 +606,9 @@ def repelling_fixed_point(self): def attracting_fixed_point(self): r""" For a hyperbolic isometry, return the attracting fixed point; - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. - OUTPUT: - - - a hyperbolic point + OUTPUT: a hyperbolic point EXAMPLES:: @@ -627,6 +620,7 @@ def attracting_fixed_point(self): fp = self._cached_isometry.attracting_fixed_point() return self.domain().get_point(fp) + class HyperbolicIsometryUHP(HyperbolicIsometry): r""" Create a hyperbolic isometry in the UHP model. @@ -734,7 +728,7 @@ def classification(self): #UHP def translation_length(self): #UHP r""" For hyperbolic elements, return the translation length; - otherwise, raise a :class:`ValueError`. + otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -761,9 +755,7 @@ def fixed_point_set(self): # UHP Return a list or geodesic containing the fixed point set of orientation-preserving isometries. - OUTPUT: - - list of hyperbolic points or a hyperbolic geodesic + OUTPUT: list of hyperbolic points or a hyperbolic geodesic EXAMPLES:: @@ -846,11 +838,9 @@ def repelling_fixed_point(self): # UHP r""" Return the repelling fixed point. - Otherwise, this raises a :class:`ValueError`. + Otherwise, this raises a :exc:`ValueError`. - OUTPUT: - - - a hyperbolic point + OUTPUT: a hyperbolic point EXAMPLES:: @@ -872,11 +862,9 @@ def attracting_fixed_point(self): # UHP r""" Return the attracting fixed point. - Otherwise, this raises a :class:`ValueError`. - - OUTPUT: + Otherwise, this raises a :exc:`ValueError`. - - a hyperbolic point + OUTPUT: a hyperbolic point EXAMPLES:: @@ -894,6 +882,7 @@ def attracting_fixed_point(self): # UHP return self.domain().get_point(infinity) return self.domain().get_point(v[0] / v[1]) + class HyperbolicIsometryPD(HyperbolicIsometry): r""" Create a hyperbolic isometry in the PD model. @@ -956,7 +945,6 @@ def __pow__(self, n): #PD Isometry in PD [ 5/8 3/8*I] [-3/8*I 5/8] - """ return (self._cached_isometry**n).to_model('PD') @@ -996,6 +984,7 @@ def _orientation_preserving(A): #PD return bool(A[1][0] == A[0][1].conjugate() and A[1][1] == A[0][0].conjugate() and abs(A[0][0]) - abs(A[0][1]) != 0) + class HyperbolicIsometryKM(HyperbolicIsometry): r""" Create a hyperbolic isometry in the KM model. @@ -1043,9 +1032,7 @@ def moebius_transform(A, z): - ``A`` -- a `2 \times 2` invertible matrix over the complex numbers - ``z`` -- a complex number or infinity - OUTPUT: - - - a complex number or infinity + OUTPUT: a complex number or infinity EXAMPLES:: diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py index 33e5f0008fe..d9def677e6d 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py @@ -243,9 +243,7 @@ def point_in_model(self, p): - any object that can converted into a complex number - OUTPUT: - - - boolean + OUTPUT: boolean EXAMPLES:: @@ -259,7 +257,7 @@ def point_in_model(self, p): def point_test(self, p): # Abstract r""" Test whether a point is in the model. If the point is in the - model, do nothing. Otherwise, raise a :class:`ValueError`. + model, do nothing. Otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -283,9 +281,7 @@ def boundary_point_in_model(self, p): # Abstract - any object that can converted into a complex number - OUTPUT: - - - boolean + OUTPUT: boolean EXAMPLES:: @@ -297,7 +293,7 @@ def boundary_point_in_model(self, p): # Abstract def bdry_point_test(self, p): # Abstract r""" Test whether a point is in the model. If the point is in the - model, do nothing; otherwise raise a :class:`ValueError`. + model, do nothing; otherwise raise a :exc:`ValueError`. EXAMPLES:: @@ -318,11 +314,9 @@ def isometry_in_model(self, A): # Abstract INPUT: - - a matrix that represents an isometry in the appropriate model - - OUTPUT: + - ``A`` -- a matrix that represents an isometry in the appropriate model - - boolean + OUTPUT: boolean EXAMPLES:: @@ -339,7 +333,7 @@ def isometry_test(self, A): # Abstract Test whether an isometry ``A`` is in the model. If the isometry is in the model, do nothing. Otherwise, raise - a :class:`ValueError`. + a :exc:`ValueError`. EXAMPLES:: @@ -369,9 +363,7 @@ def get_point(self, coordinates, is_boundary=None, **graphics_options): - a point in hyperbolic space or on the ideal boundary - OUTPUT: - - - a :class:`~sage.geometry.hyperbolic_space.hyperbolic_point.HyperbolicPoint` + OUTPUT: a :class:`~sage.geometry.hyperbolic_space.hyperbolic_point.HyperbolicPoint` EXAMPLES: @@ -406,7 +398,7 @@ def get_point(self, coordinates, is_boundary=None, **graphics_options): sage: HyperbolicPlane().HM().get_point((0,0,1)) Point in HM (0, 0, 1) - sage: p = HyperbolicPlane().UHP().get_point(I, color="red") + sage: p = HyperbolicPlane().UHP().get_point(I, color='red') sage: p.graphics_options() {'color': 'red'} @@ -488,13 +480,13 @@ def get_isometry(self, A): [1 0] [0 1] - sage: HyperbolicPlane().KM().get_isometry(identity_matrix(3)) + sage: HyperbolicPlane().KM().get_isometry(identity_matrix(3)) # needs scipy Isometry in KM [1 0 0] [0 1 0] [0 0 1] - sage: HyperbolicPlane().HM().get_isometry(identity_matrix(3)) + sage: HyperbolicPlane().HM().get_isometry(identity_matrix(3)) # needs scipy Isometry in HM [1 0 0] [0 1 0] @@ -565,7 +557,6 @@ def random_geodesic(self, **kwargs): sage: h = HyperbolicPlane().PD().random_geodesic() sage: all( e.coordinates().abs() <= 1 for e in h.endpoints() ) True - """ R = self.realization_of().a_realization() g_ends = [R.random_point(**kwargs) for k in range(2)] @@ -580,12 +571,11 @@ def random_isometry(self, preserve_orientation=True, **kwargs): - ``preserve_orientation`` -- if ``True`` return an orientation-preserving isometry - OUTPUT: - - - a hyperbolic isometry + OUTPUT: a hyperbolic isometry EXAMPLES:: + sage: # needs scipy sage: A = HyperbolicPlane().PD().random_isometry() sage: A.preserves_orientation() True @@ -609,9 +599,7 @@ def dist(self, a, b): - ``a``, ``b`` -- a point or geodesic - OUTPUT: - - - the hyperbolic distance + OUTPUT: the hyperbolic distance EXAMPLES:: @@ -716,9 +704,7 @@ def _dist_geod_point(self, start, end, p): - ``end`` -- the end ideal point coordinates of the geodesic - ``p`` -- the coordinates of the point - OUTPUT: - - - the hyperbolic distance + OUTPUT: the hyperbolic distance EXAMPLES:: @@ -795,7 +781,7 @@ def __init__(self, space): sage: TestSuite(UHP).run() """ HyperbolicModel.__init__(self, space, - name="Upper Half Plane Model", short_name="UHP", + name="Upper Half Plane Model", short_name='UHP', bounded=True, conformal=True, dimension=2, isometry_group="PSL(2, \\RR)", isometry_group_is_projective=True) @@ -934,7 +920,7 @@ def get_background_graphic(self, **bdry_options): EXAMPLES:: - sage: hp = HyperbolicPlane().UHP().get_background_graphic() + sage: hp = HyperbolicPlane().UHP().get_background_graphic() # needs sage.plot """ from sage.plot.line import line bd_min = bdry_options.get('bd_min', -5) @@ -976,9 +962,7 @@ def _dist_geod_point(self, start, end, p): - ``end`` -- the end ideal point coordinates of the geodesic - ``p`` -- the coordinates of the point - OUTPUT: - - - the hyperbolic distance + OUTPUT: the hyperbolic distance EXAMPLES:: @@ -1098,15 +1082,13 @@ def random_isometry(self, preserve_orientation=True, **kwargs): - ``preserve_orientation`` -- if ``True`` return an orientation-preserving isometry - OUTPUT: - - - a hyperbolic isometry + OUTPUT: a hyperbolic isometry EXAMPLES:: - sage: A = HyperbolicPlane().UHP().random_isometry() - sage: B = HyperbolicPlane().UHP().random_isometry(preserve_orientation=False) - sage: B.preserves_orientation() + sage: A = HyperbolicPlane().UHP().random_isometry() # needs scipy + sage: B = HyperbolicPlane().UHP().random_isometry(preserve_orientation=False) # needs scipy + sage: B.preserves_orientation() # needs scipy False """ [a, b, c, d] = [RR.random_element() for k in range(4)] @@ -1172,7 +1154,7 @@ def __init__(self, space): # name should really be 'Poincaré Disk Model', but utf8 is not # accepted by repr HyperbolicModel.__init__(self, space, - name='Poincare Disk Model', short_name="PD", + name='Poincare Disk Model', short_name='PD', bounded=True, conformal=True, dimension=2, isometry_group="PU(1, 1)", isometry_group_is_projective=True) @@ -1272,7 +1254,7 @@ def get_background_graphic(self, **bdry_options): EXAMPLES:: - sage: circ = HyperbolicPlane().PD().get_background_graphic() + sage: circ = HyperbolicPlane().PD().get_background_graphic() # needs sage.plot """ from sage.plot.circle import circle return circle((0, 0), 1, axes=False, color='black') @@ -1298,7 +1280,7 @@ def __init__(self, space): sage: TestSuite(KM).run() """ HyperbolicModel.__init__(self, space, - name="Klein Disk Model", short_name="KM", + name="Klein Disk Model", short_name='KM', bounded=True, conformal=False, dimension=2, isometry_group="PSO(2, 1)", isometry_group_is_projective=True) @@ -1380,7 +1362,7 @@ def isometry_in_model(self, A): EXAMPLES:: sage: A = matrix(3, [[1, 0, 0], [0, 17/8, 15/8], [0, 15/8, 17/8]]) - sage: HyperbolicPlane().KM().isometry_in_model(A) + sage: HyperbolicPlane().KM().isometry_in_model(A) # needs scipy True """ if isinstance(A, HyperbolicIsometry): @@ -1396,7 +1378,7 @@ def get_background_graphic(self, **bdry_options): EXAMPLES:: - sage: circ = HyperbolicPlane().KM().get_background_graphic() + sage: circ = HyperbolicPlane().KM().get_background_graphic() # needs sage.plot """ from sage.plot.circle import circle return circle((0, 0), 1, axes=False, color='black') @@ -1421,7 +1403,7 @@ def __init__(self, space): sage: TestSuite(HM).run() """ HyperbolicModel.__init__(self, space, - name="Hyperboloid Model", short_name="HM", + name="Hyperboloid Model", short_name='HM', bounded=False, conformal=True, dimension=2, isometry_group="SO(2, 1)", isometry_group_is_projective=False) @@ -1490,7 +1472,7 @@ def isometry_in_model(self, A): EXAMPLES:: sage: A = diagonal_matrix([1,1,-1]) - sage: HyperbolicPlane().HM().isometry_in_model(A) + sage: HyperbolicPlane().HM().isometry_in_model(A) # needs scipy True """ if isinstance(A, HyperbolicIsometry): @@ -1505,7 +1487,7 @@ def get_background_graphic(self, **bdry_options): EXAMPLES:: - sage: H = HyperbolicPlane().HM().get_background_graphic() + sage: H = HyperbolicPlane().HM().get_background_graphic() # needs sage.plot """ from sage.plot.plot3d.all import plot3d from sage.symbolic.ring import SR diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_point.py b/src/sage/geometry/hyperbolic_space/hyperbolic_point.py index 62127ffe425..16e96692a92 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_point.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_point.py @@ -74,6 +74,7 @@ from sage.geometry.hyperbolic_space.hyperbolic_isometry import HyperbolicIsometry + class HyperbolicPoint(Element): r""" Abstract base class for hyperbolic points. This class should never @@ -85,7 +86,7 @@ class HyperbolicPoint(Element): - ``coordinates`` -- the coordinates of a hyperbolic point in the appropriate model - ``is_boundary`` -- whether the point is a boundary point - - ``check`` -- (default: ``True``) if ``True``, then check to make sure + - ``check`` -- boolean (default: ``True``); if ``True``, then check to make sure the coordinates give a valid point in the model EXAMPLES: @@ -270,7 +271,7 @@ def _latex_(self): def _richcmp_(self, other, op): r""" - Comparison of self and other. + Comparison of ``self`` and ``other``. EXAMPLES:: @@ -318,7 +319,7 @@ def __rmul__(self, other): We also lift matrices into isometries:: sage: B = diagonal_matrix([-1, -1, 1]) - sage: B = HyperbolicPlane().HM().get_isometry(B) + sage: B = HyperbolicPlane().HM().get_isometry(B) # needs scipy sage: B * HyperbolicPlane().HM().get_point((0, 1, sqrt(2))) Point in HM (0, -1, sqrt(2)) """ @@ -443,7 +444,7 @@ def graphics_options(self): EXAMPLES:: - sage: p = HyperbolicPlane().UHP().get_point(2 + I, color="red") + sage: p = HyperbolicPlane().UHP().get_point(2 + I, color='red') sage: p.graphics_options() {'color': 'red'} """ @@ -491,7 +492,7 @@ def symmetry_involution(self): sage: A.preserves_orientation() True - sage: A*A == HyperbolicPlane().UHP().get_isometry(identity_matrix(2)) + sage: A*A == HyperbolicPlane().UHP().get_isometry(identity_matrix(2)) # needs scipy True """ R = self.parent().realization_of().a_realization() @@ -508,11 +509,11 @@ def show(self, boundary=True, **options): EXAMPLES:: - sage: HyperbolicPlane().PD().get_point(0).show() + sage: HyperbolicPlane().PD().get_point(0).show() # needs sage.plot Graphics object consisting of 2 graphics primitives - sage: HyperbolicPlane().KM().get_point((0,0)).show() + sage: HyperbolicPlane().KM().get_point((0,0)).show() # needs sage.plot Graphics object consisting of 2 graphics primitives - sage: HyperbolicPlane().HM().get_point((0,0,1)).show() + sage: HyperbolicPlane().HM().get_point((0,0,1)).show() # needs sage.plot Graphics3d Object """ p = self.coordinates() @@ -587,7 +588,7 @@ def show(self, boundary=True, **options): sage: HyperbolicPlane().UHP().get_point(I).show() Graphics object consisting of 2 graphics primitives - sage: HyperbolicPlane().UHP().get_point(0).show() + sage: HyperbolicPlane().UHP().get_point(0).show() # needs sage.plot Graphics object consisting of 2 graphics primitives sage: HyperbolicPlane().UHP().get_point(infinity).show() Traceback (most recent call last): diff --git a/src/sage/geometry/hyperplane_arrangement/affine_subspace.py b/src/sage/geometry/hyperplane_arrangement/affine_subspace.py index 7c1065553c4..94d004f987f 100644 --- a/src/sage/geometry/hyperplane_arrangement/affine_subspace.py +++ b/src/sage/geometry/hyperplane_arrangement/affine_subspace.py @@ -82,9 +82,7 @@ class AffineSubspace(SageObject): - ``V`` -- vector subspace - OUTPUT: - - Affine subspace parallel to ``V`` and passing through ``p``. + OUTPUT: affine subspace parallel to ``V`` and passing through ``p`` EXAMPLES:: @@ -136,9 +134,7 @@ def _repr_(self): r""" String representation for an :class:`AffineSubspace`. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -159,9 +155,7 @@ def __eq__(self, other): - ``other`` -- an :class:`AffineSubspace` - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -186,9 +180,7 @@ def __ne__(self, other): - ``other`` -- an :class:`AffineSubspace` - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -212,9 +204,7 @@ def __le__(self, other): - ``other`` -- an :class:`AffineSubspace` - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -243,9 +233,7 @@ def __lt__(self, other): - ``other`` -- an :class:`AffineSubspace` - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -274,9 +262,7 @@ def __contains__(self, q): - ``q`` -- point as a list/tuple/iterable - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -294,9 +280,7 @@ def linear_part(self): r""" Return the linear part of the affine space. - OUTPUT: - - A vector subspace of the ambient space. + OUTPUT: a vector subspace of the ambient space EXAMPLES:: @@ -316,9 +300,7 @@ def point(self): r""" Return a point ``p`` in the affine space. - OUTPUT: - - A point of the affine space as a vector in the ambient space. + OUTPUT: a point of the affine space as a vector in the ambient space EXAMPLES:: @@ -333,9 +315,7 @@ def dimension(self): r""" Return the dimension of the affine space. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/geometry/hyperplane_arrangement/arrangement.py b/src/sage/geometry/hyperplane_arrangement/arrangement.py index 533f7ac1151..8517bb36671 100644 --- a/src/sage/geometry/hyperplane_arrangement/arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/arrangement.py @@ -382,7 +382,7 @@ def __init__(self, parent, hyperplanes, check=True, backend=None): - ``parent`` -- the parent :class:`HyperplaneArrangements` - - ``hyperplanes`` -- a tuple of hyperplanes + - ``hyperplanes`` -- tuple of hyperplanes - ``check`` -- boolean (default: ``True``); whether to check input @@ -423,9 +423,7 @@ def _first_ngens(self, n): """ Workaround to support the construction with names. - INPUT/OUTPUT: - - See :meth:`HyperplaneArrangements._first_ngens`. + INPUT/OUTPUT: see :meth:`HyperplaneArrangements._first_ngens` EXAMPLES:: @@ -443,9 +441,7 @@ def __getitem__(self, i): - ``i`` -- integer - OUTPUT: - - The `i`-th hyperplane. + OUTPUT: the `i`-th hyperplane EXAMPLES:: @@ -474,9 +470,7 @@ def n_hyperplanes(self): r""" Return the number of hyperplanes in the arrangement. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -495,9 +489,7 @@ def hyperplanes(self): r""" Return the hyperplanes in the arrangement as a tuple. - OUTPUT: - - A tuple + OUTPUT: a tuple EXAMPLES:: @@ -517,9 +509,7 @@ def _repr_(self): r""" String representation for a hyperplane arrangement. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -543,9 +533,7 @@ def dimension(self): """ Return the ambient space dimension of the arrangement. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -597,11 +585,9 @@ def rank(self): def backend(self): """ - Return the backend used for polyhedral objects - - OUTPUT: + Return the backend used for polyhedral objects. - A string giving the backend or ``None`` if none is specified. + OUTPUT: string giving the backend or ``None`` if none is specified EXAMPLES: @@ -648,9 +634,7 @@ def union(self, other): - ``other`` -- a hyperplane arrangement or something that can be converted into a hyperplane arrangement - OUTPUT: - - A new hyperplane arrangement. + OUTPUT: a new hyperplane arrangement EXAMPLES:: @@ -689,9 +673,7 @@ def plot(self, **kwds): """ Plot the hyperplane arrangement. - OUTPUT: - - A graphics object. + OUTPUT: a graphics object EXAMPLES:: @@ -763,18 +745,18 @@ def cone(self, variable='t'): return H(*hyperplanes, backend=self._backend) @cached_method - def intersection_poset(self, element_label="int"): + def intersection_poset(self, element_label='int'): r""" Return the intersection poset of the hyperplane arrangement. INPUT: - - ``element_label`` -- (default: ``"int"``) specify how an + - ``element_label`` -- (default: ``'int'``) specify how an intersection should be represented; must be one of the following: - * ``"subspace"`` -- as a subspace - * ``"subset"`` -- as a subset of the defining hyperplanes - * ``"int"`` -- as an integer + * ``'subspace'`` -- as a subspace + * ``'subset'`` -- as a subset of the defining hyperplanes + * ``'int'`` -- as an integer OUTPUT: @@ -810,7 +792,7 @@ def intersection_poset(self, element_label="int"): [[0], [1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]] By passing the argument ``element_label="subset"``, each element of the - intesection poset is labelled by the set of indices of the hyperplanes + intersection poset is labelled by the set of indices of the hyperplanes whose intersection is said element. The index of a hyperplane is its index in ``self.hyperplanes()``. :: @@ -930,9 +912,7 @@ def characteristic_polynomial(self): r""" Return the characteristic polynomial of the hyperplane arrangement. - OUTPUT: - - The characteristic polynomial in `\QQ[x]`. + OUTPUT: the characteristic polynomial in `\QQ[x]` EXAMPLES:: @@ -978,9 +958,7 @@ def poincare_polynomial(self): r""" Return the Poincaré polynomial of the hyperplane arrangement. - OUTPUT: - - The Poincaré polynomial in `\QQ[x]`. + OUTPUT: the Poincaré polynomial in `\QQ[x]` EXAMPLES:: @@ -1010,9 +988,7 @@ def cocharacteristic_polynomial(self): element of `L` (here, the `0` dimensional subspace), and `\mu` is the Möbius function of `L`. - OUTPUT: - - The cocharacteristic polynomial in `\ZZ[z]`. + OUTPUT: the cocharacteristic polynomial in `\ZZ[z]` EXAMPLES:: @@ -1039,7 +1015,7 @@ def cocharacteristic_polynomial(self): from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing R = PolynomialRing(ZZ, 'z') z = R.gen() - L = self.intersection_poset(element_label="subspace").dual() + L = self.intersection_poset(element_label='subspace').dual() B = L.minimal_elements()[0] return R.sum(abs(L.moebius_function(B, X)) * z**X.dimension() for X in L) @@ -1060,9 +1036,7 @@ def primitive_eulerian_polynomial(self): element of `L` (here, the `0` dimensional subspace), and `\mu` is the Möbius function of `L`. - OUTPUT: - - The primitive Eulerian polynomial in `\ZZ[z]`. + OUTPUT: the primitive Eulerian polynomial in `\ZZ[z]` EXAMPLES:: @@ -1106,7 +1080,7 @@ def primitive_eulerian_polynomial(self): We compute types `H_3` and `F_4` in Table 1 of [BHS2023]_:: sage: # needs sage.libs.gap - sage: W = CoxeterGroup(['H',3], implementation="matrix") + sage: W = CoxeterGroup(['H',3], implementation='matrix') sage: A = HyperplaneArrangements(W.base_ring(), tuple(f'x{s}' for s in range(W.rank()))) sage: H = A([[0] + list(r) for r in W.positive_roots()]) sage: H.is_simplicial() # needs sage.graphs @@ -1114,7 +1088,7 @@ def primitive_eulerian_polynomial(self): sage: H.primitive_eulerian_polynomial() z^3 + 28*z^2 + 16*z - sage: W = CoxeterGroup(['F',4], implementation="permutation") + sage: W = CoxeterGroup(['F',4], implementation='permutation') sage: A = HyperplaneArrangements(QQ, tuple(f'x{s}' for s in range(W.rank()))) sage: H = A([[0] + list(r) for r in W.positive_roots()]) sage: H.primitive_eulerian_polynomial() # long time # needs sage.graphs @@ -1163,7 +1137,7 @@ def primitive_eulerian_polynomial(self): from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing R = PolynomialRing(ZZ, 'z') z = R.gen() - L = self.intersection_poset(element_label="subspace").dual() + L = self.intersection_poset(element_label='subspace').dual() B = L.minimal_elements()[0] n = self.dimension() return R.sum(abs(L.moebius_function(B, X)) * (z - 1)**(n-X.dimension()) @@ -1365,9 +1339,7 @@ def n_regions(self): r""" The number of regions of the hyperplane arrangement. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -1399,7 +1371,7 @@ def n_regions(self): ....: vector(AA, [-1/2, AA(-1/2*v2^3 + v2), 0])) sage: H = HyperplaneArrangements(AA, names='xyz') sage: x,y,z = H.gens() - sage: A = H(backend="normaliz") # optional - pynormaliz + sage: A = H(backend='normaliz') # optional - pynormaliz sage: for v in my_vectors: # optional - pynormaliz ....: a, b, c = v ....: A = A.add_hyperplane(a*x + b*y + c*z) @@ -1456,9 +1428,7 @@ def has_good_reduction(self, p): - ``p`` -- prime number - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1488,9 +1458,7 @@ def is_linear(self): r""" Test whether all hyperplanes pass through the origin. - OUTPUT: - - A boolean. Whether all the hyperplanes pass through the origin. + OUTPUT: boolean EXAMPLES:: @@ -1521,9 +1489,7 @@ def is_essential(self): :meth:`essentialization` - OUTPUT: - - A boolean indicating whether the hyperplane arrangement is essential. + OUTPUT: boolean EXAMPLES:: @@ -1549,9 +1515,7 @@ def is_central(self, certificate=False): to return the center as a polyhedron (possibly empty) as part of the output - OUTPUT: - - If ``certificate`` is ``True``, returns a tuple containing: + OUTPUT: if ``certificate`` is ``True``, returns a tuple containing: 1. A boolean 2. The polyhedron defined to be the intersection of all the hyperplanes @@ -1620,9 +1584,7 @@ def center(self): ambient space of the arrangement that lie on all of the hyperplanes. - OUTPUT: - - A polyhedron. + OUTPUT: a polyhedron EXAMPLES: @@ -1658,9 +1620,7 @@ def is_simplicial(self): are linearly independent. A hyperplane arrangement is said to be simplicial if every region is simplicial. - OUTPUT: - - A boolean whether the hyperplane arrangement is simplicial. + OUTPUT: boolean; whether the hyperplane arrangement is simplicial EXAMPLES:: @@ -1763,7 +1723,7 @@ def echelon_col_iter(row_iter): v[pivot] = 1 complement_basis.append(vector(R, v)) # reduce the hyperplane equations - echelon_pivots = [] # the column indices where N has 1's from the echelonization + echelon_pivots = [] # the column indices where N has 1s from the echelonization for pivot, row in echelon_col_iter(complement_basis): assert row[pivot] == 1 echelon_pivots.append(pivot) @@ -1828,9 +1788,7 @@ def face_vector(self): r""" Return the face vector. - OUTPUT: - - A vector of integers. + OUTPUT: a vector of integers The `d`-th entry is the number of faces of dimension `d`. A *face* is the intersection of a region with a hyperplane of @@ -1850,7 +1808,7 @@ def face_vector(self): return v @cached_method - def _parallel_hyperplanes(self): + def _parallel_hyperplanes(self) -> tuple: """ Return the hyperplanes grouped into parallel sets. @@ -1887,7 +1845,7 @@ def _parallel_hyperplanes(self): (Hyperplane t0 + 0*t1 - t2 + 0, (1, 0, -1), 0))) """ V = self.parent().ambient_space() - parallels = dict() + parallels = {} for hyperplane in self: through_origin = V([list(hyperplane.A()), 0]).primitive(signed=False) parallel_planes = parallels.get(through_origin, []) @@ -1895,10 +1853,9 @@ def _parallel_hyperplanes(self): b = hyperplane.b() * (A / hyperplane.A()) parallel_planes.append([b, (hyperplane, A, b)]) parallels[through_origin] = parallel_planes - parallels = [tuple(tuple(hyperplane[1] - for hyperplane in sorted(parallels[key]))) - for key in parallels.keys()] - return tuple(sorted(parallels)) + parallels = sorted(tuple(hyperplane[1] for hyperplane in sorted(value)) + for key, value in parallels.items()) + return tuple(parallels) def vertices(self, exclude_sandwiched=False): """ @@ -1981,7 +1938,7 @@ def _make_region(self, hyperplanes): INPUT: - - ``hyperplanes`` -- a list/tuple/iterable of hyperplanes + - ``hyperplanes`` -- list/tuple/iterable of hyperplanes OUTPUT: @@ -2016,9 +1973,7 @@ def regions(self): The base field must have characteristic zero. - OUTPUT: - - A tuple containing the regions as polyhedra. + OUTPUT: a tuple containing the regions as polyhedra The regions are the connected components of the complement of the union of the hyperplanes as a subset of `\RR^n`. @@ -2191,15 +2146,13 @@ def poset_of_regions(self, B=None, numbered_labels=True): INPUT: - ``B`` -- a region (optional); if ``None``, then - an arbitrary region is chosen as the base region. + an arbitrary region is chosen as the base region - - ``numbered_labels`` -- bool (default: ``True``); if ``True``, + - ``numbered_labels`` -- boolean (default: ``True``); if ``True``, then the elements of the poset are numbered. Else they are labelled with the regions themselves. - OUTPUT: - - A Poset object containing the poset of regions. + OUTPUT: a Poset object containing the poset of regions EXAMPLES:: @@ -2552,7 +2505,7 @@ def face_product(self, F, G, normalize=True): - ``F``, ``G`` -- two faces of ``self`` (as polyhedra) - - ``normalize`` -- Boolean (default: ``True``); if ``True``, then + - ``normalize`` -- boolean (default: ``True``); if ``True``, then this method returns the precise instance of `FG` in the list returned by ``self.closed_faces()``, rather than creating a new instance @@ -2755,7 +2708,7 @@ def region_containing_point(self, p): OUTPUT: - A polyhedron. A :class:`ValueError` is raised if the point is not + A polyhedron. A :exc:`ValueError` is raised if the point is not interior to a region, that is, sits on a hyperplane. EXAMPLES:: @@ -3075,10 +3028,8 @@ def is_separating_hyperplane(self, region1, region2, hyperplane): - ``hyperplane`` -- a hyperplane - OUTPUT: - - A boolean. Whether the hyperplane ``hyperplane`` separate the given - regions. + OUTPUT: boolean; whether the hyperplane ``hyperplane`` separate the + given regions EXAMPLES:: @@ -3119,9 +3070,7 @@ def distance_between_regions(self, region1, region2): - ``region1``, ``region2`` -- regions of the arrangement or representative points of regions - OUTPUT: - - An integer. The number of hyperplanes separating the two regions. + OUTPUT: integer; the number of hyperplanes separating the two regions EXAMPLES:: @@ -3180,11 +3129,9 @@ def varchenko_matrix(self, names='h'): INPUT: - ``names`` -- string or list/tuple/iterable of strings. The - variable names for the polynomial ring `S`. - - OUTPUT: + variable names for the polynomial ring `S` - The Varchenko matrix. + OUTPUT: the Varchenko matrix EXAMPLES:: @@ -3463,7 +3410,7 @@ def derivation_module_free_chain(self): return construct_free_chain(self) @cached_method(key=lambda self, a: None) - def is_free(self, algorithm="singular"): + def is_free(self, algorithm='singular'): r""" Return if ``self`` is free. @@ -3473,11 +3420,11 @@ def is_free(self, algorithm="singular"): INPUT: - - ``algorithm`` -- (default: ``"singular"``) can be one of + - ``algorithm`` -- (default: ``'singular'``) can be one of the following: - * ``"singular"`` -- use Singular's minimal free resolution - * ``"BC"`` -- use the algorithm given by Barakat and Cuntz + * ``'singular'`` -- use Singular's minimal free resolution + * ``'BC'`` -- use the algorithm given by Barakat and Cuntz in [BC2012]_ (much slower than using Singular) ALGORITHM: @@ -3517,8 +3464,8 @@ def is_free(self, algorithm="singular"): sage: W = WeylGroup(['B', 3], prefix='s') # needs sage.combinat sage.groups sage: for x in W: # long time # needs sage.combinat sage.groups ....: A = x.inversion_arrangement() - ....: assert (A.is_free(algorithm="BC") - ....: == A.is_free(algorithm="singular")) + ....: assert (A.is_free(algorithm='BC') + ....: == A.is_free(algorithm='singular')) """ if not self.is_central(): raise NotImplementedError("only implemented for central arrangements") @@ -3531,7 +3478,7 @@ def is_free(self, algorithm="singular"): else: raise ValueError("invalid algorithm") - def derivation_module_basis(self, algorithm="singular"): + def derivation_module_basis(self, algorithm='singular'): """ Return a basis for the derivation module of ``self`` if one exists, otherwise return ``None``. @@ -3542,11 +3489,11 @@ def derivation_module_basis(self, algorithm="singular"): INPUT: - - ``algorithm`` -- (default: ``"singular"``) can be one of + - ``algorithm`` -- (default: ``'singular'``) can be one of the following: - * ``"singular"`` -- use Singular's minimal free resolution - * ``"BC"`` -- use the algorithm given by Barakat and Cuntz + * ``'singular'`` -- use Singular's minimal free resolution + * ``'BC'`` -- use the algorithm given by Barakat and Cuntz in [BC2012]_ (much slower than using Singular) OUTPUT: @@ -3589,8 +3536,8 @@ def derivation_module_basis(self, algorithm="singular"): ....: return sorted([max(x.degree() for x in b) for b in B]) sage: for x in W: # long time # needs sage.combinat sage.groups ....: A = x.inversion_arrangement() - ....: B = A.derivation_module_basis(algorithm="singular") - ....: Bp = A.derivation_module_basis(algorithm="BC") + ....: B = A.derivation_module_basis(algorithm='singular') + ....: Bp = A.derivation_module_basis(algorithm='BC') ....: if B is None: ....: assert Bp is None ....: else: @@ -3691,9 +3638,7 @@ def base_ring(self): """ Return the base ring. - OUTPUT: - - The base ring of the hyperplane arrangement. + OUTPUT: the base ring of the hyperplane arrangement EXAMPLES:: @@ -3709,7 +3654,7 @@ def change_ring(self, base_ring): INPUT: - - ``base_ring`` -- a ring; the new base ring. + - ``base_ring`` -- a ring; the new base ring OUTPUT: @@ -3754,9 +3699,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3784,7 +3727,7 @@ def _element_constructor_(self, *args, **kwds): whether or not there is a warning shown - ``check`` -- boolean (default: ``True``); whether to - perform argument checking. + perform argument checking EXAMPLES:: @@ -3872,9 +3815,7 @@ def ngens(self): """ Return the number of linear variables. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -3891,9 +3832,7 @@ def gens(self) -> tuple: """ Return the coordinate hyperplanes. - OUTPUT: - - A tuple of linear expressions, one for each linear variable. + OUTPUT: a tuple of linear expressions, one for each linear variable EXAMPLES:: @@ -3913,9 +3852,7 @@ def gen(self, i): - ``i`` -- integer - OUTPUT: - - A linear expression. + OUTPUT: a linear expression EXAMPLES:: diff --git a/src/sage/geometry/hyperplane_arrangement/check_freeness.py b/src/sage/geometry/hyperplane_arrangement/check_freeness.py index f1691634f69..42943d72669 100644 --- a/src/sage/geometry/hyperplane_arrangement/check_freeness.py +++ b/src/sage/geometry/hyperplane_arrangement/check_freeness.py @@ -26,6 +26,7 @@ from sage.matrix.constructor import matrix import sage.libs.singular.function_factory as fun_fact + def less_generators(X): """ Reduce the generator matrix of the module defined by ``X``. @@ -63,6 +64,7 @@ def less_generators(X): Kd = set(range(X.nrows())).difference(K) X = X.matrix_from_rows(sorted(Kd)) + def construct_free_chain(A): """ Construct the free chain for the hyperplanes ``A``. diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index b7f493d9acb..04de307442d 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -166,9 +166,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -182,9 +180,7 @@ def _latex_(self): r""" Return a LaTeX representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -208,9 +204,7 @@ def normal(self): """ Return the normal vector. - OUTPUT: - - A vector over the base ring. + OUTPUT: a vector over the base ring EXAMPLES:: @@ -228,9 +222,7 @@ def _normal_pivot(self): """ Return the index of the largest entry of the normal vector. - OUTPUT: - - An integer. The index of the largest entry. + OUTPUT: integer; the index of the largest entry EXAMPLES:: @@ -265,9 +257,7 @@ def __contains__(self, q): - ``q`` -- point (as a vector, list, or tuple) - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -287,9 +277,7 @@ def polyhedron(self, **kwds): """ Return the hyperplane as a polyhedron. - OUTPUT: - - A :func:`~sage.geometry.polyhedron.constructor.Polyhedron` instance. + OUTPUT: a :func:`~sage.geometry.polyhedron.constructor.Polyhedron` instance EXAMPLES:: @@ -426,9 +414,7 @@ def dimension(self): r""" The dimension of the hyperplane. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -448,9 +434,7 @@ def intersection(self, other): - ``other`` -- a hyperplane, a polyhedron, or something that defines a polyhedron - OUTPUT: - - A polyhedron. + OUTPUT: a polyhedron EXAMPLES:: @@ -484,7 +468,7 @@ def orthogonal_projection(self, point): A vector in the ambient vector space that lies on the hyperplane. - In finite characteristic, a :class:`ValueError` is raised if the + In finite characteristic, a :exc:`ValueError` is raised if the the norm of the hyperplane normal is zero. EXAMPLES:: @@ -634,9 +618,7 @@ def plot(self, **kwds): """ Plot the hyperplane. - OUTPUT: - - A graphics object. + OUTPUT: a graphics object EXAMPLES:: @@ -716,9 +698,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -736,9 +716,7 @@ def dimension(self): """ Return the ambient space dimension. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -760,9 +738,7 @@ def change_ring(self, base_ring): - ``base_ring`` -- a ring; the new base ring - OUTPUT: - - A new :class:`AmbientVectorSpace`. + OUTPUT: a new :class:`AmbientVectorSpace` EXAMPLES:: diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index 085cdd32e21..9e2ca3336f6 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -241,7 +241,7 @@ def Coxeter(self, data, K=QQ, names=None): - ``data`` -- either an integer or a Cartan type (or coercible into; see "CartanType") - - ``K`` -- field (default:``QQ``) + - ``K`` -- field (default: ``QQ``) - ``names`` -- tuple of strings or ``None`` (default); the variable names for the ambient space @@ -367,9 +367,7 @@ def G_Shi(self, G, K=QQ, names=None): - ``names`` -- tuple of strings or ``None`` (default); the variable names for the ambient space - OUTPUT: - - The Shi hyperplane arrangement of the given graph ``G``. + OUTPUT: the Shi hyperplane arrangement of the given graph ``G`` EXAMPLES:: @@ -456,7 +454,7 @@ def Ish(self, n, K=QQ, names=None): - ``n`` -- integer - - ``K`` -- field (default:``QQ``) + - ``K`` -- field (default: ``QQ``) - ``names`` -- tuple of strings or ``None`` (default); the variable names for the ambient space @@ -515,13 +513,11 @@ def IshB(self, n, K=QQ, names=None): INPUT: - ``n`` -- integer - - ``K`` -- field (default:``QQ``) + - ``K`` -- field (default: ``QQ``) - ``names`` -- tuple of strings or ``None`` (default); the variable names for the ambient space - OUTPUT: - - The type `B` Ish arrangement, which is the set of `2n^2` hyperplanes + OUTPUT: the type `B` Ish arrangement, which is the set of `2n^2` hyperplanes .. MATH:: @@ -691,7 +687,7 @@ def Shi(self, data, K=QQ, names=None, m=1): - ``data`` -- either an integer or a Cartan type (or coercible into; see "CartanType") - - ``K`` -- field (default:``QQ``) + - ``K`` -- field (default: ``QQ``) - ``names`` -- tuple of strings or ``None`` (default); the variable names for the ambient space diff --git a/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py b/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py index bb16768e13b..c0024f4c982 100644 --- a/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py @@ -115,9 +115,9 @@ def __init__(self, parent, hyperplanes, check=True, backend=None): - ``parent`` -- the parent :class:`OrderedHyperplaneArrangements` - - ``hyperplanes`` -- a tuple of hyperplanes + - ``hyperplanes`` -- tuple of hyperplanes - - ``check`` -- boolean (default ``True``); whether + - ``check`` -- boolean (default: ``True``); whether to check input - ``backend`` -- string (default: ``None``); the backend to @@ -142,7 +142,7 @@ def hyperplane_section(self, proj=True): INPUT: - - ``proj`` -- (default: ``True``); if the + - ``proj`` -- (default: ``True``) if the ambient space is affine or projective OUTPUT: @@ -224,7 +224,7 @@ def hyperplane_section(self, proj=True): mat_rows = mat.rows()[:-1] H1b = A1(mat_rows) return H1b - P = self.intersection_poset(element_label="subspace") + P = self.intersection_poset(element_label='subspace') center = P.maximal_elements()[0].linear_part() n1 = center.dimension() U = [] @@ -250,9 +250,7 @@ def affine_fundamental_group(self): hyperplane arrangement in `\CC^n` whose equations have coefficients in a subfield of `\QQbar`. - OUTPUT: - - A finitely presented fundamental group. + OUTPUT: a finitely presented fundamental group .. NOTE:: @@ -340,9 +338,7 @@ def affine_meridians(self): r""" Return the meridians of each hyperplane (including the one at infinity). - OUTPUT: - - A dictionary + OUTPUT: a dictionary .. NOTE:: @@ -479,9 +475,7 @@ def projective_meridians(self): r""" Return the meridian of each hyperplane. - OUTPUT: - - A dictionary + OUTPUT: a dictionary .. NOTE:: @@ -558,7 +552,7 @@ def _element_constructor_(self, *args, **kwds): preserve signs of hyperplane equations - ``check`` -- boolean (default: ``True``); whether to - perform argument checking. + perform argument checking EXAMPLES:: @@ -637,9 +631,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: diff --git a/src/sage/geometry/hyperplane_arrangement/plot.py b/src/sage/geometry/hyperplane_arrangement/plot.py index c7b413114e6..7e550bfd472 100644 --- a/src/sage/geometry/hyperplane_arrangement/plot.py +++ b/src/sage/geometry/hyperplane_arrangement/plot.py @@ -6,21 +6,21 @@ Beside the usual plot options (enter ``plot?``), the plot command for hyperplane arrangements includes the following: -- ``hyperplane_colors`` -- Color or list of colors, one for each - hyperplane (default: equally spread range of hues). +- ``hyperplane_colors`` -- color or list of colors, one for each + hyperplane (default: equally spread range of hues) -- ``hyperplane_labels`` -- Boolean, ``'short'``, ``'long'`` (default: +- ``hyperplane_labels`` -- boolean, ``'short'``, ``'long'`` (default: ``False``). If ``False``, no labels are shown; if 'short' or 'long', the hyperplanes are given short or long labels, respectively. If ``True``, the hyperplanes are given long labels. -- ``label_colors`` -- Color or list of colors, one for each hyperplane - (default: black). +- ``label_colors`` -- color or list of colors, one for each hyperplane + (default: black) -- ``label_fontsize`` -- Size for hyperplane_label font (default: - ``14``). This does not work for 3d plots. +- ``label_fontsize`` -- size for hyperplane_label font (default: + ``14``); this does not work for 3d plots -- ``label_offsets`` -- Amount be which labels are offset from +- ``label_offsets`` -- amount be which labels are offset from h.point() for each hyperplane h. The format is different for each dimension: if the hyperplanes have dimension 0, the offset can be a single number or a list of numbers, one for each hyperplane; if the @@ -30,20 +30,20 @@ 3-tuples, one for each hyperplane. (Defaults: 0-dim: ``0.1``, 1-dim: ``(0,1)``, 2-dim: ``(0,0,0.2)``). -- ``hyperplane_legend`` -- Boolean, ``'short'``, ``'long'`` (default: +- ``hyperplane_legend`` -- boolean, ``'short'``, ``'long'`` (default: ``'long'``; in 3-d: ``False``). If ``False``, no legend is shown; if ``True``, ``'short'``, or ``'long'``, the legend is shown with the default, long, or short labeling, respectively. (For arrangements of lines or planes, only.) -- ``hyperplane_opacities`` -- A number or list of numbers, one for each - hyperplane, between 0 and 1. Only applies to 3d plots. +- ``hyperplane_opacities`` -- a number or list of numbers, one for each + hyperplane, between 0 and 1; only applies to 3d plots -- ``point_sizes`` -- Number or list of numbers, one for each hyperplane +- ``point_sizes`` -- number or list of numbers, one for each hyperplane giving the sizes of points in a zero-dimensional arrangement - (default: ``50``). + (default: ``50``) -- ``ranges`` -- Range for the parameters or a list of ranges of +- ``ranges`` -- range for the parameters or a list of ranges of parameters, one for each hyperplane, for the parametric plots of the hyperplanes. If a single positive number `r` is given for ``ranges``, then all parameters run from -r to r. Otherwise, for a @@ -136,11 +136,9 @@ def plot(hyperplane_arrangement, **kwds): - ``hyperplane_arrangement`` -- the hyperplane arrangement to plot - ``**kwds`` -- plot options: see - :mod:`sage.geometry.hyperplane_arrangement.plot`. + :mod:`sage.geometry.hyperplane_arrangement.plot` - OUTPUT: - - A graphics object of the plot. + OUTPUT: a graphics object of the plot EXAMPLES:: @@ -214,14 +212,14 @@ def plot(hyperplane_arrangement, **kwds): if 'ranges' in kwds: ranges_set = True ranges = kwds.pop('ranges') - if not type(ranges) in [list,tuple]: # ranges is a single number + if type(ranges) not in [list,tuple]: # ranges is a single number ranges = [ranges] * N # So ranges is some type of list. elif dim == 2: # arrangement of lines in the plane - if not type(ranges[0]) in [list,tuple]: # a single interval + if type(ranges[0]) not in [list,tuple]: # a single interval ranges = [ranges] * N elif dim == 3: # arrangement of planes in 3-space - if not type(ranges[0][0]) in [list,tuple]: + if type(ranges[0][0]) not in [list,tuple]: ranges = [ranges] * N elif dim not in [2,3]: # ranges is not an option unless dim is 2 or 3 ranges_set = False @@ -292,33 +290,31 @@ def plot_hyperplane(hyperplane, **kwds): - ``**kwds`` -- plot options: see below - OUTPUT: - - A graphics object of the plot. + OUTPUT: a graphics object of the plot .. RUBRIC:: Plot Options Beside the usual plot options (enter ``plot?``), the plot command for hyperplanes includes the following: - - ``hyperplane_label`` -- Boolean value or string (default: ``True``). - If ``True``, the hyperplane is labeled with its equation, if a + - ``hyperplane_label`` -- boolean value or string (default: ``True``); + if ``True``, the hyperplane is labeled with its equation, if a string, it is labeled by that string, otherwise it is not - labeled. + labeled - - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label. + - ``label_color`` -- (default: ``'black'``) color for hyperplane_label - - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14) - (does not work in 3d, yet). + - ``label_fontsize`` -- size for ``hyperplane_label`` font (default: 14) + (does not work in 3d, yet) - - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1), - 2-dim: (0,0,0.2)) Amount by which label is offset from - ``hyperplane.point()``. + - ``label_offset`` -- (default: 0-dim: 0.1, 1-dim: (0,1), + 2-dim: (0,0,0.2)); amount by which label is offset from + ``hyperplane.point()`` - - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional - arrangement or of an arrangement over a finite field. + - ``point_size`` -- (default: 50) size of points in a zero-dimensional + arrangement or of an arrangement over a finite field - - ``ranges`` -- Range for the parameters for the parametric plot of the + - ``ranges`` -- range for the parameters for the parametric plot of the hyperplane. If a single positive number ``r`` is given for the value of ``ranges``, then the ranges for all parameters are set to `[-r, r]`. Otherwise, for a line in the plane, ``ranges`` has the @@ -482,9 +478,7 @@ def legend_3d(hyperplane_arrangement, hyperplane_colors, length): - ``length`` -- either ``'short'`` or ``'long'`` - OUTPUT: - - - A graphics object. + OUTPUT: a graphics object EXAMPLES:: diff --git a/src/sage/geometry/integral_points.pxi b/src/sage/geometry/integral_points.pxi index 327855b6a57..a67535b450b 100644 --- a/src/sage/geometry/integral_points.pxi +++ b/src/sage/geometry/integral_points.pxi @@ -119,7 +119,7 @@ cpdef tuple parallelotope_points(spanning_points, lattice): sage: parallelotope_points(c.rays(), c.lattice()) (N(0, 0), N(1, 1)) - A :class:`ValueError` is raised if the ``spanning_points`` are not + A :exc:`ValueError` is raised if the ``spanning_points`` are not linearly independent:: sage: rays = list(map(ToricLattice(2), [(1,1)]*2)) @@ -151,11 +151,9 @@ cpdef tuple ray_matrix_normal_form(R): INPUT: - ``R`` -- `\ZZ`-matrix whose columns are the rays spanning the - parallelotope. + parallelotope - OUTPUT: - - A tuple containing ``e``, ``d``, and ``VDinv``. + OUTPUT: a tuple containing ``e``, ``d``, and ``VDinv`` EXAMPLES:: @@ -186,7 +184,7 @@ cpdef tuple loop_over_parallelotope_points(e, d, MatrixClass VDinv, See :meth:`parallelotope_points` for ``e``, ``d``, ``VDinv``, ``R``, ``lattice``. - - ``A``, ``b``: Either both ``None`` or a vector and number. If + - ``A``, ``b`` -- either both ``None`` or a vector and number. If present, only the parallelotope points satisfying `A x \leq b` are returned. @@ -352,23 +350,23 @@ cpdef rectangular_box_points(list box_min, list box_max, INPUT: - - ``box_min`` -- A list of integers. The minimal value for each - coordinate of the rectangular bounding box. + - ``box_min`` -- list of integers; the minimal value for each + coordinate of the rectangular bounding box - - ``box_max`` -- A list of integers. The maximal value for each - coordinate of the rectangular bounding box. + - ``box_max`` -- list of integers; the maximal value for each + coordinate of the rectangular bounding box - - ``polyhedron`` -- A + - ``polyhedron`` -- a :class:`~sage.geometry.polyhedron.base.Polyhedron_base`, a PPL - :class:`~ppl.polyhedron.C_Polyhedron`, or ``None`` (default). + :class:`~ppl.polyhedron.C_Polyhedron`, or ``None`` (default) - - ``count_only`` -- Boolean (default: ``False``). Whether to + - ``count_only`` -- boolean (default: ``False``); whether to return only the total number of vertices, and not their coordinates. Enabling this option speeds up the enumeration. Cannot be combined with the ``return_saturated`` option. - - ``return_saturated`` -- Boolean (default: ``False``. Whether to + - ``return_saturated`` -- boolean (default: ``False``); whether to also return which inequalities are saturated for each point of the polyhedron. Enabling this slows down the enumeration. Cannot be combined with the ``count_only`` option. @@ -595,20 +593,18 @@ cdef loop_over_rectangular_box_points(list box_min, list box_max, INPUT: - - ``box_min``, ``box_max`` -- the bounding box. + - ``box_min``, ``box_max`` -- the bounding box - ``inequalities`` -- a :class:`InequalityCollection` containing - the inequalities defining the polyhedron. + the inequalities defining the polyhedron - - ``d`` -- the ambient space dimension. + - ``d`` -- the ambient space dimension - ``count_only`` -- whether to only return the total number of - lattice points. + lattice points - OUTPUT: - - The integral points in the bounding box satisfying all - inequalities. + OUTPUT: the integral points in the bounding box satisfying all + inequalities """ cdef int inc cdef Integer i_min, i_max @@ -729,9 +725,7 @@ cdef class Inequality_generic: - ``b`` -- element - OUTPUT: - - Inequality `A x + b \geq 0`. + OUTPUT: inequality `A x + b \geq 0` EXAMPLES:: @@ -749,7 +743,7 @@ cdef class Inequality_generic: def __cinit__(self, list A, b, int index=-1): """ - The Cython constructor + The Cython constructor. INPUT: @@ -771,9 +765,7 @@ cdef class Inequality_generic: """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -811,9 +803,7 @@ cdef class Inequality_generic: r""" Test the inequality, using the cached value from :meth:`prepare_inner_loop` - OUTPUT: - - Boolean. Whether the inequality is not satisfied. + OUTPUT: boolean; whether the inequality is not satisfied """ return inner_loop_variable * self.coeff + self.cache < 0 @@ -823,7 +813,7 @@ cdef class Inequality_generic: OUTPUT: - Boolean. Given the inequality `Ax + b \geq 0`, this method + boolean. Given the inequality `Ax + b \geq 0`, this method returns whether the equality `Ax + b = 0` is satisfied. """ return inner_loop_variable * self.coeff + self.cache == 0 @@ -849,9 +839,9 @@ cdef class Inequality_int: OUTPUT: - Inequality `A x + b \geq 0`. A :class:`OverflowError` is raised if a + Inequality `A x + b \geq 0`. A :exc:`OverflowError` is raised if a machine integer is not long enough to hold the results. A - :class:`ValueError` is raised if some of the input is not integral. + :exc:`ValueError` is raised if some of the input is not integral. EXAMPLES:: @@ -887,7 +877,6 @@ cdef class Inequality_int: Traceback (most recent call last): ... OverflowError: ... - """ cdef int A[INEQ_INT_MAX_DIM] cdef int b @@ -908,7 +897,7 @@ cdef class Inequality_int: def __cinit__(self, list A, b, list max_abs_coordinates, int index=-1): """ - The Cython constructor + The Cython constructor. See :class:`Inequality_int` for input. @@ -937,9 +926,7 @@ cdef class Inequality_int: """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -988,13 +975,13 @@ cdef class InequalityCollection: INPUT: - - ``polyhedron`` -- a polyhedron defining the inequalities. + - ``polyhedron`` -- a polyhedron defining the inequalities - - ``permutation`` -- list; a 0-based permutation of the coordinates. - Will be used to permute the coordinates of the inequality. + - ``permutation`` -- list; a 0-based permutation of the coordinates + Will be used to permute the coordinates of the inequality - ``box_min``, ``box_max`` -- the (not permuted) minimal and maximal - coordinates of the bounding box. Used for bounds checking. + coordinates of the bounding box; used for bounds checking EXAMPLES:: @@ -1031,9 +1018,7 @@ cdef class InequalityCollection: r""" Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1087,7 +1072,7 @@ cdef class InequalityCollection: def __cinit__(self, polyhedron, list permutation, box_min, box_max): """ - The Cython constructor + The Cython constructor. See the class documentation for the description of the arguments. @@ -1121,7 +1106,7 @@ cdef class InequalityCollection: cdef _cinit_from_PPL(self, list max_abs_coordinates, list permutation, polyhedron): """ - Initialize the inequalities from a PPL C_Polyhedron + Initialize the inequalities from a PPL C_Polyhedron. See __cinit__ for a description of the arguments. @@ -1170,7 +1155,7 @@ cdef class InequalityCollection: cdef _cinit_from_Polyhedron(self, list max_abs_coordinates, list permutation, polyhedron): """ - Initialize the inequalities from a Sage Polyhedron + Initialize the inequalities from a Sage Polyhedron. See __cinit__ for a description of the arguments. @@ -1238,7 +1223,7 @@ cdef class InequalityCollection: INPUT: - ``p`` -- the point coordinates. Only ``p[2:]`` coordinates - are potentially used by this method. + are potentially used by this method EXAMPLES:: @@ -1277,7 +1262,7 @@ cdef class InequalityCollection: INPUT: - ``p`` -- the coordinates of the point to loop over. Only the - ``p[1:]`` entries are used. + ``p[1:]`` entries are used EXAMPLES:: @@ -1303,8 +1288,8 @@ cdef class InequalityCollection: INPUT: - - ``i`` -- Integer. The :class:`Inequality_int` to swap to the - beginning of the list of integral inequalities. + - ``i`` -- integer; the :class:`Inequality_int` to swap to the + beginning of the list of integral inequalities EXAMPLES:: @@ -1340,12 +1325,10 @@ cdef class InequalityCollection: INPUT: - - ``inner_loop_variable`` -- Integer. the 0-th coordinate of - the lattice point. - - OUTPUT: + - ``inner_loop_variable`` -- integer; the 0th coordinate of + the lattice point - Boolean. Whether the lattice point is in the polyhedron. + OUTPUT: boolean; whether the lattice point is in the polyhedron EXAMPLES:: @@ -1379,8 +1362,8 @@ cdef class InequalityCollection: INPUT: - - ``inner_loop_variable`` -- Integer. the 0-th coordinate of - the lattice point. + - ``inner_loop_variable`` -- integer; the 0th coordinate of + the lattice point OUTPUT: diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 0f83da4c96b..857eadba882 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -29,7 +29,7 @@ included standard with Sage. PALP is described in the paper :arxiv:`math.SC/0204356`. Its distribution -also contains the application nef.x, which was created by Erwin +also contains the application ``nef.x``, which was created by Erwin Riegler and computes nef-partitions and Hodge data for toric complete intersections. @@ -41,15 +41,15 @@ Robert Bradshaw helped Andrey Novoseltsev to realize plot3d function. -.. note:: +.. NOTE:: IMPORTANT: PALP requires some parameters to be determined during compilation time, i.e., the maximum dimension of polytopes, the maximum number of points, etc. These limitations may lead to errors during calls to different functions of these module. Currently, a - ValueError exception will be raised if the output of poly.x or - nef.x is empty or contains the exclamation mark. The error message - will contain the exact command that caused an error, the + :exc:`ValueError` exception will be raised if the output of ``poly.x`` + or ``nef.x`` is empty or contains the exclamation mark. The error + message will contain the exact command that caused an error, the description and vertices of the polytope, and the obtained output. Data obtained from PALP and some other data is cached and most @@ -135,9 +135,9 @@ from sage.features import PythonModule from sage.features.palp import PalpExecutable lazy_import('ppl', ['C_Polyhedron', 'Generator_System', 'Linear_Expression'], - feature=PythonModule("ppl", spkg="pplpy", type="standard")) + feature=PythonModule("ppl", spkg='pplpy', type='standard')) lazy_import('ppl', 'point', as_='PPL_point', - feature=PythonModule("ppl", spkg="pplpy", type="standard")) + feature=PythonModule("ppl", spkg='pplpy', type='standard')) from sage.matrix.constructor import matrix from sage.structure.element import Matrix @@ -220,23 +220,20 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None): :func:`~sage.geometry.point_collection.read_palp_point_collection` for the file format; - - ``compute_vertices`` -- boolean (default: ``True``). If ``True``, the - convex hull of the given points will be computed for - determining vertices. Otherwise, the given points must be - vertices; + - ``compute_vertices`` -- boolean (default: ``True``); if ``True``, the + convex hull of the given points will be computed for determining + vertices. Otherwise, the given points must be vertices. - - ``n`` -- an integer (default: 0) if ``data`` is a name of a file, - that contains data blocks for several polytopes, the ``n``-th block - will be used; + - ``n`` -- integer (default: 0); if ``data`` is a name of a file, + that contains data blocks for several polytopes, the ``n``-th block + will be used - ``lattice`` -- the ambient lattice of the polytope. If not given, a suitable lattice will be determined automatically, most likely the :class:`toric lattice ` `M` of the appropriate dimension. - OUTPUT: - - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` EXAMPLES:: @@ -418,6 +415,7 @@ def ReflexivePolytope(dim, n): # Sequences of reflexive polytopes _rp = [None] * 4 + def ReflexivePolytopes(dim): r""" Return the sequence of all 2- or 3-dimensional reflexive polytopes. @@ -428,9 +426,11 @@ def ReflexivePolytopes(dim): future use, so repetitive calls will return the same object in memory. - :param dim: dimension of required reflexive polytopes - :type dim: 2 or 3 - :rtype: list of lattice polytopes + INPUT: + + - ``dim`` -- integer (2 or 3); dimension of required reflexive polytopes + + OUTPUT: list of lattice polytopes EXAMPLES: @@ -470,7 +470,7 @@ def is_LatticePolytope(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: @@ -495,6 +495,7 @@ def is_LatticePolytope(x): deprecation(34307, "is_LatticePolytope is deprecated, use isinstance instead") return isinstance(x, LatticePolytopeClass) + @richcmp_method class LatticePolytopeClass(ConvexSet_compact, Hashable, sage.geometry.abc.LatticePolytope): r""" @@ -512,24 +513,22 @@ class LatticePolytopeClass(ConvexSet_compact, Hashable, sage.geometry.abc.Lattic The input can be either: - - ``points`` -- :class:`~sage.geometry.point_collection.PointCollection`; + - ``points`` -- :class:`~sage.geometry.point_collection.PointCollection` - - ``compute_vertices`` -- boolean. + - ``compute_vertices`` -- boolean or (these parameters must be given as keywords): - ``ambient`` -- ambient structure, this polytope *must be a face of* - ``ambient``; + ``ambient`` - ``ambient_vertex_indices`` -- increasing list or tuple of integers, - indices of vertices of ``ambient`` generating this polytope; + indices of vertices of ``ambient`` generating this polytope - ``ambient_facet_indices`` -- increasing list or tuple of integers, - indices of facets of ``ambient`` generating this polytope. - - OUTPUT: + indices of facets of ``ambient`` generating this polytope - - lattice polytope. + OUTPUT: lattice polytope .. NOTE:: @@ -550,7 +549,6 @@ def __init__(self, points=None, compute_vertices=None, sage: LatticePolytope([(1,2,3), (4,5,6)]) # indirect test 1-d lattice polytope in 3-d lattice M sage: TestSuite(_).run() - """ if ambient is None: self._ambient = self @@ -621,7 +619,7 @@ def __richcmp__(self, other, op): INPUT: - - ``other`` -- anything. + - ``other`` -- anything .. NOTE:: @@ -685,9 +683,7 @@ def __hash__(self): r""" Return the hash of ``self``. - OUTPUT: - - - an integer. + OUTPUT: integer TESTS:: @@ -722,7 +718,7 @@ def __reduce__(self): def __setstate__(self, state): r""" - Restores the state of pickled polytope. + Restore the state of pickled polytope. TESTS:: @@ -950,11 +946,9 @@ def _embed(self, data): def _latex_(self): r""" - Return the latex representation of self. - - OUTPUT: + Return the latex representation of ``self``. - - string + OUTPUT: string EXAMPLES: @@ -981,7 +975,7 @@ def _palp(self, command, reduce_dimension=False): Returns the output of ``command`` as a string. - .. note:: + .. NOTE:: PALP cannot be called for polytopes that do not span the ambient space. If you specify ``reduce_dimension=True`` argument, PALP will be @@ -1040,9 +1034,7 @@ def _PPL(self): r""" Return the Parma Polyhedra Library (PPL) representation of ``self``. - OUTPUT: - - - :class:`~ppl.polyhedron.C_Polyhedron` + OUTPUT: :class:`~ppl.polyhedron.C_Polyhedron` EXAMPLES:: @@ -1228,11 +1220,9 @@ def _read_nef_partitions(self, data): INPUT: - - ``data`` -- a string or a file. + - ``data`` -- string or file - OUTPUT: - - - none. + OUTPUT: none TESTS:: @@ -1313,9 +1303,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - a string. + OUTPUT: string TESTS:: @@ -1341,7 +1329,7 @@ def _repr_(self): parts.extend(["face of", str(self.ambient())]) return " ".join(parts) - def _sort_faces(self, faces): + def _sort_faces(self, faces): r""" Return sorted (if necessary) ``faces`` as a tuple. @@ -1352,11 +1340,9 @@ def _sort_faces(self, faces): INPUT: - ``faces`` -- iterable of :class:`lattice polytopes - `. - - OUTPUT: + ` - - :class:`tuple` of :class:`lattice polytopes `. + OUTPUT: :class:`tuple` of :class:`lattice polytopes ` TESTS:: @@ -1400,9 +1386,7 @@ def adjacent(self): * `F_1` and `F_2` are facets of some face of dimension `d+1`, unless `d` is the dimension of the ambient structure. - OUTPUT: - - - :class:`tuple` of :class:`lattice polytopes `. + OUTPUT: :class:`tuple` of :class:`lattice polytopes ` EXAMPLES:: @@ -1420,7 +1404,7 @@ def adjacent(self): adjacent = set() for superface in self.facet_of(): for facet in self.facets(): - adjacent.update(L.open_interval(facet, superface)) + adjacent.update(L.open_interval(facet, superface)) adjacent.discard(self) return self._sort_faces(adjacent) @@ -1428,7 +1412,7 @@ def affine_transform(self, a=1, b=0): r""" Return a*P+b, where P is this lattice polytope. - .. note:: + .. NOTE:: #. While ``a`` and ``b`` may be rational, the final result must be a lattice polytope, i.e. all vertices must be integral. @@ -1521,9 +1505,7 @@ def ambient(self): r""" Return the ambient structure of ``self``. - OUTPUT: - - - lattice polytope containing ``self`` as a face. + OUTPUT: lattice polytope containing ``self`` as a face EXAMPLES:: @@ -1548,9 +1530,7 @@ def ambient_facet_indices(self): r""" Return indices of facets of the ambient polytope containing ``self``. - OUTPUT: - - - increasing :class:`tuple` of integers. + OUTPUT: increasing :class:`tuple` of integers EXAMPLES: @@ -1642,9 +1622,7 @@ def ambient_vertex_indices(self): r""" Return indices of vertices of the ambient structure generating ``self``. - OUTPUT: - - - increasing :class:`tuple` of integers. + OUTPUT: increasing :class:`tuple` of integers EXAMPLES:: @@ -1662,9 +1640,7 @@ def boundary_point_indices(self): r""" Return indices of (relative) boundary lattice points of this polytope. - OUTPUT: - - - increasing :class:`tuple` of integers. + OUTPUT: increasing :class:`tuple` of integers EXAMPLES: @@ -1704,9 +1680,7 @@ def boundary_points(self): r""" Return (relative) boundary lattice points of this polytope. - OUTPUT: - - - a :class:`point collection `. + OUTPUT: a :class:`point collection ` EXAMPLES: @@ -1795,9 +1769,9 @@ def distances(self, point=None): Return the matrix of distances for this polytope or distances for the given point. - The matrix of distances m gives distances m[i,j] between the i-th - facet (which is also the i-th vertex of the polar polytope in the - reflexive case) and j-th point of this polytope. + The matrix of distances m gives distances m[i,j] between the `i`-th + facet (which is also the `i`-th vertex of the polar polytope in the + reflexive case) and `j`-th point of this polytope. If point is specified, integral distances from the point to all facets of this polytope will be computed. @@ -1865,9 +1839,7 @@ def dual(self): This duality extends the correspondence between vertices and facets. - OUTPUT: - - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` EXAMPLES:: @@ -1917,9 +1889,7 @@ def edges(self): r""" Return edges (faces of dimension 1) of ``self``. - OUTPUT: - - - :class:`tuple` of :class:`lattice polytopes `. + OUTPUT: :class:`tuple` of :class:`lattice polytopes ` EXAMPLES:: @@ -2096,7 +2066,7 @@ def LPFace(vertices, facets): faces.append(self) for face in dfaces: L.add_edge(face_to_index[face], next_index) - D = {i:f for i,f in enumerate(faces)} + D = dict(enumerate(faces)) L.relabel(D) return FinitePoset(L, faces, key=id(self)) @@ -2106,9 +2076,9 @@ def faces(self, dim=None, codim=None): INPUT: - - ``dim`` -- integer, dimension of the requested faces; + - ``dim`` -- integer; dimension of the requested faces - - ``codim`` -- integer, codimension of the requested faces. + - ``codim`` -- integer; codimension of the requested faces .. NOTE:: @@ -2191,7 +2161,7 @@ def faces(self, dim=None, codim=None): def facet_constant(self, i): r""" - Return the constant in the ``i``-th facet inequality of this polytope. + Return the constant in the `i`-th facet inequality of this polytope. This is equivalent to ``facet_constants()[i]``. @@ -2199,9 +2169,7 @@ def facet_constant(self, i): - ``i`` -- integer; the index of the facet - OUTPUT: - - - integer -- the constant in the ``i``-th facet inequality. + OUTPUT: integer; the constant in the `i`-th facet inequality .. SEEALSO:: @@ -2227,9 +2195,7 @@ def facet_constants(self): Facet inequalities have form `n \cdot x + c \geq 0` where `n` is the inner normal and `c` is a constant. - OUTPUT: - - - an integer vector + OUTPUT: integer vector .. SEEALSO:: @@ -2284,9 +2250,7 @@ def facet_normal(self, i): - ``i`` -- integer; the index of the facet - OUTPUT: - - - a vector + OUTPUT: a vector .. SEEALSO:: @@ -2391,9 +2355,7 @@ def facet_of(self): r""" Return elements of the ambient face lattice having ``self`` as a facet. - OUTPUT: - - - :class:`tuple` of :class:`lattice polytopes `. + OUTPUT: :class:`tuple` of :class:`lattice polytopes ` EXAMPLES:: @@ -2415,9 +2377,7 @@ def facets(self): r""" Return facets (faces of codimension 1) of ``self``. - OUTPUT: - - - :class:`tuple` of :class:`lattice polytopes `. + OUTPUT: :class:`tuple` of :class:`lattice polytopes ` EXAMPLES:: @@ -2493,7 +2453,7 @@ def index(self): 3-dimensional reflexive polytopes. Databases are stored in the directory of the package. - .. note:: + .. NOTE:: The first call to this function for each dimension can take a few seconds while the dictionary of all polytopes is @@ -2557,9 +2517,7 @@ def interior_point_indices(self): r""" Return indices of (relative) interior lattice points of this polytope. - OUTPUT: - - - increasing :class:`tuple` of integers. + OUTPUT: increasing :class:`tuple` of integers EXAMPLES: @@ -2599,9 +2557,7 @@ def interior_points(self): r""" Return (relative) boundary lattice points of this polytope. - OUTPUT: - - - a :class:`point collection `. + OUTPUT: a :class:`point collection ` EXAMPLES: @@ -2624,7 +2580,7 @@ def interior_points(self): @cached_method def is_reflexive(self): r""" - Return True if this polytope is reflexive. + Return ``True`` if this polytope is reflexive. EXAMPLES: The 3-dimensional octahedron is reflexive (and 4319 other 3-polytopes):: @@ -2653,9 +2609,7 @@ def lattice(self): r""" Return the ambient lattice of ``self``. - OUTPUT: - - - a lattice. + OUTPUT: a lattice EXAMPLES:: @@ -2670,9 +2624,7 @@ def lattice_dim(self): An alias is :meth:`ambient_dim`. - OUTPUT: - - - integer. + OUTPUT: integer EXAMPLES:: @@ -2694,7 +2646,7 @@ def ambient_vector_space(self, base_field=None): INPUT: - - ``base_field`` -- (default: the rationals) a field. + - ``base_field`` -- (default: the rationals) a field EXAMPLES:: @@ -2710,9 +2662,7 @@ def linearly_independent_vertices(self): r""" Return a maximal set of linearly independent vertices. - OUTPUT: - - A tuple of vertex indices. + OUTPUT: a tuple of vertex indices EXAMPLES:: @@ -2735,25 +2685,23 @@ def nef_partitions(self, keep_symmetric=False, keep_products=True, INPUT: - - ``keep_symmetric`` -- (default: ``False``) if ``True``, "-s" option + - ``keep_symmetric`` -- boolean (default: ``False``); if ``True``, "-s" option will be passed to ``nef.x`` in order to keep symmetric partitions, - i.e. partitions related by lattice automorphisms preserving ``self``; + i.e. partitions related by lattice automorphisms preserving ``self`` - - ``keep_products`` -- (default: ``True``) if ``True``, "-D" option + - ``keep_products`` -- boolean (default: ``True``); if ``True``, "-D" option will be passed to ``nef.x`` in order to keep product partitions, - with corresponding complete intersections being direct products; + with corresponding complete intersections being direct products - - ``keep_projections`` -- (default: ``True``) if ``True``, "-P" option + - ``keep_projections`` -- boolean (default: ``True``); if ``True``, "-P" option will be passed to ``nef.x`` in order to keep projection partitions, - i.e. partitions with one of the parts consisting of a single vertex; + i.e. partitions with one of the parts consisting of a single vertex - - ``hodge_numbers`` -- (default: ``False``) if ``False``, "-p" option + - ``hodge_numbers`` -- boolean (default: ``False``); if ``False``, "-p" option will be passed to ``nef.x`` in order to skip Hodge numbers - computation, which takes a lot of time. + computation, which takes a lot of time - OUTPUT: - - - a sequence of :class:`nef-partitions `. + OUTPUT: a sequence of :class:`nef-partitions ` Type ``NefPartition?`` for definitions and notation. @@ -2883,17 +2831,15 @@ def nef_partitions(self, keep_symmetric=False, keep_products=True, def nef_x(self, keys): r""" - Run nef.x with given ``keys`` on vertices of this + Run ``nef.x`` with given ``keys`` on vertices of this polytope. INPUT: + - ``keys`` -- string of options passed to ``nef.x``; the + key "-f" is added automatically - - ``keys`` -- a string of options passed to nef.x. The - key "-f" is added automatically. - - - OUTPUT: the output of nef.x as a string. + OUTPUT: the output of ``nef.x`` as a string EXAMPLES: This call is used internally for computing nef-partitions:: @@ -2937,7 +2883,7 @@ def nfacets(self): return len(self.facet_normals()) if self.dim() > 0 else 0 @cached_method - def normal_form(self, algorithm="palp_native", permutation=False): + def normal_form(self, algorithm='palp_native', permutation=False): r""" Return the normal form of vertices of ``self``. @@ -2948,21 +2894,21 @@ def normal_form(self, algorithm="palp_native", permutation=False): The original algorithm was presented in [KS1998]_ and implemented in PALP. A modified version of the PALP algorithm is discussed in - [GK2013]_ and available here as ``"palp_modified"``. + [GK2013]_ and available here as ``'palp_modified'``. INPUT: - - ``algorithm`` -- (default: ``"palp_native"``) The algorithm which is used + - ``algorithm`` -- (default: ``'palp_native'``) the algorithm which is used to compute the normal form. Options are: - * ``"palp"`` -- Run external PALP code, usually the fastest option + * ``'palp'`` -- run external PALP code, usually the fastest option when it works; but reproducible crashes have been observed in dimension 5 and higher. - * ``"palp_native"`` -- The original PALP algorithm implemented + * ``'palp_native'`` -- the original PALP algorithm implemented in sage. Currently competitive with PALP in many cases. - * ``"palp_modified"`` -- A modified version of the PALP + * ``'palp_modified'`` -- a modified version of the PALP algorithm which determines the maximal vertex-facet pairing matrix first and then computes its automorphisms, while the PALP algorithm does both things @@ -3025,7 +2971,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): We can perform the same examples using other algorithms:: sage: o = lattice_polytope.cross_polytope(2) - sage: o.normal_form(algorithm="palp_native") # needs sage.groups + sage: o.normal_form(algorithm='palp_native') # needs sage.groups M( 1, 0), M( 0, 1), M( 0, -1), @@ -3033,7 +2979,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): in 2-d lattice M sage: o = lattice_polytope.cross_polytope(2) - sage: o.normal_form(algorithm="palp_modified") # needs sage.groups + sage: o.normal_form(algorithm='palp_modified') # needs sage.groups M( 1, 0), M( 0, 1), M( 0, -1), @@ -3041,10 +2987,10 @@ def normal_form(self, algorithm="palp_native", permutation=False): in 2-d lattice M The following examples demonstrate the speed of the available algorithms. - In low dimensions, the default algorithm, ``"palp_native"``, is the fastest. - As the dimension increases, ``"palp"`` is relatively faster than ``"palp_native"``. - ``"palp_native"`` is usually much faster than ``"palp_modified"``. - In some cases when the polytope has high symmetry, however, ``"palp_native"`` is slower:: + In low dimensions, the default algorithm, ``'palp_native'``, is the fastest. + As the dimension increases, ``'palp'`` is relatively faster than ``'palp_native'``. + ``'palp_native'`` is usually much faster than ``'palp_modified'``. + In some cases when the polytope has high symmetry, however, ``'palp_native'`` is slower:: sage: # not tested sage: o = lattice_polytope.cross_polytope(2) @@ -3076,11 +3022,11 @@ def normal_form(self, algorithm="palp_native", permutation=False): sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") 10 loops, best of 3: 0.858 s per loop - Note that the algorithm ``"palp"`` may crash for higher dimensions because of + Note that the algorithm ``'palp'`` may crash for higher dimensions because of the overflow errors as mentioned in :issue:`13525#comment:9`. - Then use ``"palp_native"`` instead, which is usually faster than ``"palp_modified"``. - Below is an example where ``"palp"`` fails and - ``"palp_native"`` is much faster than ``"palp_modified"``:: + Then use ``'palp_native'`` instead, which is usually faster than ``'palp_modified'``. + Below is an example where ``'palp'`` fails and + ``'palp_native'`` is much faster than ``'palp_modified'``:: sage: P = LatticePolytope([[-3, -3, -6, -6, -1], [3, 3, 6, 6, 1], [-3, -3, -6, -6, 1], ....: [-3, -3, -3, -6, 0], [-3, -3, -3, 0, 0], [-3, -3, 0, 0, 0], @@ -3095,13 +3041,13 @@ def normal_form(self, algorithm="palp_native", permutation=False): ....: [0, 0, 3, 6, 1], [0, 0, 6, 6, 0], [0, 3, 0, 0, -1], ....: [3, 0, 3, 0, 0], [0, 3, 0, 0, 1], [0, 3, 3, 0, 0], ....: [0, 3, 3, 6, 0], [0, 3, 6, 6, 0], [3, 0,0, 0, -1], [3, 0, 0, 0, 1]]) - sage: P.normal_form(algorithm="palp") # not tested + sage: P.normal_form(algorithm='palp') # not tested Traceback (most recent call last): ... RuntimeError: Error executing ... for a polytope sequence! Output: b'*** stack smashing detected ***: terminated\nAborted\n' - sage: P.normal_form(algorithm="palp_native") # needs sage.groups + sage: P.normal_form(algorithm='palp_native') # needs sage.groups M( 6, 0, 0, 0, 0), M( -6, 0, 0, 0, 0), M( 0, 1, 0, 0, 0), @@ -3143,7 +3089,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): M( 12, -1, -9, -6, 6), M( 12, -1, -6, -3, 3) in 5-d lattice M - sage: P.normal_form(algorithm="palp_modified") # not tested (22s; MemoryError on 32 bit), needs sage.groups + sage: P.normal_form(algorithm='palp_modified') # not tested (22s; MemoryError on 32 bit), needs sage.groups M( 6, 0, 0, 0, 0), M( -6, 0, 0, 0, 0), M( 0, 1, 0, 0, 0), @@ -3231,12 +3177,11 @@ def _palp_modified_normal_form(self, permutation=False): INPUT: - - ``permutation`` -- boolean (default: ``False``); whether to return the permutation of - the order of the vertices that was applied to obtain this matrix. - - OUTPUT: + - ``permutation`` -- boolean (default: ``False``); whether to return + the permutation of the order of the vertices that was applied to + obtain this matrix - A matrix or a tuple of a matrix and a permutation. + OUTPUT: a matrix or a tuple of a matrix and a permutation EXAMPLES:: @@ -3286,10 +3231,7 @@ def _palp_native_normal_form(self, permutation=False): of the order of the vertices that was applied to obtain this matrix. - OUTPUT: - - A matrix or a tuple of a matrix and a permutation. - + OUTPUT: a matrix or a tuple of a matrix and a permutation EXAMPLES:: @@ -3336,9 +3278,9 @@ def _palp_PM_max(self, check=False): INPUT: - - ``check`` -- Boolean (default: ``False``), whether to return + - ``check`` -- boolean (default: ``False``); whether to return the permutations leaving the maximal vertex-facet pairing - matrix invariant. + matrix invariant OUTPUT: @@ -3434,11 +3376,9 @@ def nvertices(self): @cached_method def origin(self): r""" - Return the index of the origin in the list of points of self. + Return the index of the origin in the list of points of ``self``. - OUTPUT: - - - integer if the origin belongs to this polytope, ``None`` otherwise. + OUTPUT: integer if the origin belongs to this polytope, ``None`` otherwise EXAMPLES:: @@ -3505,55 +3445,54 @@ def plot3d(self, Most of the parameters are self-explanatory: - - ``show_facets`` -- (default: ``True``) - - - ``facet_opacity`` -- (default:0.5) + - ``show_facets`` -- (default: ``True``) - - ``facet_color`` -- (default:(0,1,0)) + - ``facet_opacity`` -- (default:0.5) - - ``facet_colors`` -- (default:None) if specified, must be a list of - colors for each facet separately, used instead of ``facet_color`` + - ``facet_color`` -- (default:(0,1,0)) - - ``show_edges`` -- (default: ``True``) whether to draw - edges as lines + - ``facet_colors`` -- (default:None) if specified, must be a list of + colors for each facet separately, used instead of ``facet_color`` - - ``edge_thickness`` -- (default:3) + - ``show_edges`` -- boolean (default: ``True``); whether to draw + edges as lines - - ``edge_color`` -- (default:(0.5,0.5,0.5)) + - ``edge_thickness`` -- (default:3) - - ``show_vertices`` -- (default: ``True``) whether to draw - vertices as balls + - ``edge_color`` -- (default:(0.5,0.5,0.5)) - - ``vertex_size`` -- (default:10) + - ``show_vertices`` -- boolean (default: ``True``); whether to draw + vertices as balls - - ``vertex_color`` -- (default:(1,0,0)) + - ``vertex_size`` -- (default:10) - - ``show_points`` -- (default: ``True``) whether to draw - other points as balls + - ``vertex_color`` -- (default:(1,0,0)) - - ``point_size`` -- (default:10) + - ``show_points`` -- boolean (default: ``True``); whether to draw + other points as balls - - ``point_color`` -- (default:(0,0,1)) + - ``point_size`` -- (default:10) - - ``show_vindices`` -- (default: same as - ``show_vertices``) whether to show indices of vertices + - ``point_color`` -- (default:(0,0,1)) - - ``vindex_color`` -- (default:(0,0,0)) color for - vertex labels + - ``show_vindices`` -- (default: same as + ``show_vertices``) whether to show indices of vertices - - ``vlabels`` -- (default:None) if specified, must be a list of labels - for each vertex, default labels are vertex indices + - ``vindex_color`` -- (default:(0,0,0)) color for + vertex labels - - ``show_pindices`` -- (default: same as ``show_points``) - whether to show indices of other points + - ``vlabels`` -- (default:None) if specified, must be a list of labels + for each vertex, default labels are vertex indices - - ``pindex_color`` -- (default:(0,0,0)) color for - point labels + - ``show_pindices`` -- (default: same as ``show_points``) + whether to show indices of other points - - ``index_shift`` -- (default:1.1)) if 1, labels are - placed exactly at the corresponding points. Otherwise the label - position is computed as a multiple of the point position vector. + - ``pindex_color`` -- (default:(0,0,0)) color for + point labels + - ``index_shift`` -- (default:1.1)) if 1, labels are + placed exactly at the corresponding points. Otherwise the label + position is computed as a multiple of the point position vector. EXAMPLES: The default plot of a cube:: @@ -3678,8 +3617,8 @@ def show3d(self): def point(self, i): r""" - Return the i-th point of this polytope, i.e. the i-th column of the - matrix returned by points(). + Return the `i`-th point of this polytope, i.e. the `i`-th column of the + matrix returned by ``points()``. EXAMPLES: First few points are actually vertices:: @@ -3719,9 +3658,7 @@ def points(self, *args, **kwds): - any arguments given will be passed on to the returned object. - OUTPUT: - - - a :class:`point collection `. + OUTPUT: a :class:`point collection ` EXAMPLES: @@ -3894,19 +3831,19 @@ def polar(self): def poly_x(self, keys, reduce_dimension=False): r""" - Run poly.x with given ``keys`` on vertices of this + Run ``poly.x`` with given ``keys`` on vertices of this polytope. INPUT: - - ``keys`` -- a string of options passed to poly.x. The - key "f" is added automatically. + - ``keys`` -- string of options passed to ``poly.x``. The + key "f" is added automatically - - ``reduce_dimension`` -- (default: ``False``) if ``True`` and this - polytope is not full-dimensional, poly.x will be called for the - vertices of this polytope in some basis of the spanned affine space. + - ``reduce_dimension`` -- boolean (default: ``False``); if ``True`` and this + polytope is not full-dimensional, ``poly.x`` will be called for the + vertices of this polytope in some basis of the spanned affine space - OUTPUT: the output of poly.x as a string. + OUTPUT: the output of ``poly.x`` as a string EXAMPLES: This call is used for determining if a polytope is reflexive or not:: @@ -3937,7 +3874,7 @@ def poly_x(self, keys, reduce_dimension=False): Output: Please increase POLY_Dmax to at least 7 - You cannot call poly.x for polytopes that don't span the space (if you + You cannot call ``poly.x`` for polytopes that don't span the space (if you could, it would crush anyway):: sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)]) @@ -4035,12 +3972,9 @@ def skeleton_show(self, normal=None): INPUT: - - - ``normal`` -- a 3-dimensional vector (can be given as - a list), which should be perpendicular to the screen. If not given, - will be selected randomly (new each time and it may be far from - "nice"). - + - ``normal`` -- a 3-dimensional vector (can be given as a list), which + should be perpendicular to the screen. If not given, will be selected + randomly (new each time and it may be far from "nice"). EXAMPLES: Show a pretty picture of the octahedron:: @@ -4092,8 +4026,8 @@ def traverse_boundary(self): def vertex(self, i): r""" - Return the i-th vertex of this polytope, i.e. the i-th column of - the matrix returned by vertices(). + Return the `i`-th vertex of this polytope, i.e. the `i`-th column of + the matrix returned by ``vertices()``. EXAMPLES: Note that numeration starts with zero:: @@ -4148,9 +4082,7 @@ def vertices(self, *args, **kwds): - any arguments given will be passed on to the returned object. - OUTPUT: - - - a :class:`point collection `. + OUTPUT: a :class:`point collection ` EXAMPLES: @@ -4189,7 +4121,7 @@ def is_NefPartition(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: @@ -4220,7 +4152,7 @@ class NefPartition(SageObject, Hashable): INPUT: - - ``data`` -- a list of integers, the `i`-th element of this list must be + - ``data`` -- list of integers, the `i`-th element of this list must be the part of the `i`-th vertex of ``Delta_polar`` in this nef-partition; - ``Delta_polar`` -- a :class:`lattice polytope @@ -4231,9 +4163,7 @@ class NefPartition(SageObject, Hashable): input is correct, you can speed up construction via ``check=False`` option. - OUTPUT: - - - a nef-partition of ``Delta_polar``. + OUTPUT: a nef-partition of ``Delta_polar`` Let `M` and `N` be dual lattices. Let `\Delta \subset M_\RR` be a reflexive polytope with polar `\Delta^\circ \subset N_\RR`. Let `X_\Delta` be the @@ -4297,10 +4227,10 @@ class NefPartition(SageObject, Hashable): It is very easy to create a nef-partition for the octahedron, since for this polytope any decomposition of vertices is a nef-partition. We create a - 3-part nef-partition with the 0-th and 1-st vertices belonging to the 0-th - part (recall that numeration in Sage starts with 0), the 2-nd and 5-th - vertices belonging to the 1-st part, and 3-rd and 4-th vertices belonging - to the 2-nd part:: + 3-part nef-partition with the 0th and 1st vertices belonging to the 0th + part (recall that numeration in Sage starts with 0), the 2nd and 5th + vertices belonging to the 1st part, and 3rd and 4th vertices belonging + to the 2nd part:: sage: o = lattice_polytope.cross_polytope(3) sage: np = NefPartition([0,0,1,2,2,1], o) @@ -4381,7 +4311,7 @@ def __eq__(self, other): INPUT: - - ``other`` -- anything. + - ``other`` -- anything OUTPUT: @@ -4419,9 +4349,7 @@ def __hash__(self): r""" Return the hash of ``self``. - OUTPUT: - - - an integer. + OUTPUT: integer TESTS:: @@ -4442,7 +4370,7 @@ def __ne__(self, other): INPUT: - - ``other`` -- anything. + - ``other`` -- anything OUTPUT: @@ -4478,9 +4406,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - a string. + OUTPUT: string TESTS:: @@ -4508,9 +4434,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - a string. + OUTPUT: string TESTS:: @@ -4565,11 +4489,9 @@ def Delta(self, i=None): INPUT: - - ``i`` -- an integer. If not given, `\Delta` will be returned. + - ``i`` -- integer; if not given, `\Delta` will be returned - OUTPUT: - - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` See :class:`nef-partition ` class documentation for definitions and notation. @@ -4607,9 +4529,7 @@ def Delta_polar(self): r""" Return the polytope `\Delta^\circ` corresponding to ``self``. - OUTPUT: - - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` See :class:`nef-partition ` class documentation for definitions and notation. @@ -4628,9 +4548,7 @@ def Deltas(self): r""" Return the polytopes `\Delta_i` corresponding to ``self``. - OUTPUT: - - - a tuple of :class:`lattice polytopes `. + OUTPUT: a tuple of :class:`lattice polytopes ` See :class:`nef-partition ` class documentation for definitions and notation. @@ -4679,9 +4597,7 @@ def dual(self): r""" Return the dual nef-partition. - OUTPUT: - - - a :class:`nef-partition `. + OUTPUT: a :class:`nef-partition ` See the class documentation for the definition. @@ -4733,9 +4649,7 @@ def hodge_numbers(self): r""" Return Hodge numbers corresponding to ``self``. - OUTPUT: - - - a tuple of integers (produced by ``nef.x`` program from PALP). + OUTPUT: a tuple of integers (produced by ``nef.x`` program from PALP) EXAMPLES: @@ -4765,11 +4679,9 @@ def nabla(self, i=None): INPUT: - - ``i`` -- an integer. If not given, `\nabla` will be returned. + - ``i`` -- integer; if not given, `\nabla` will be returned - OUTPUT: - - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` See :class:`nef-partition ` class documentation for definitions and notation. @@ -4812,9 +4724,7 @@ def nabla_polar(self): r""" Return the polytope `\nabla^\circ` corresponding to ``self``. - OUTPUT: - - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` See :class:`nef-partition ` class documentation for definitions and notation. @@ -4843,9 +4753,7 @@ def nablas(self): r""" Return the polytopes `\nabla_i` corresponding to ``self``. - OUTPUT: - - - a tuple of :class:`lattice polytopes `. + OUTPUT: a tuple of :class:`lattice polytopes ` See :class:`nef-partition ` class documentation for definitions and notation. @@ -4888,9 +4796,7 @@ def nparts(self): r""" Return the number of parts in ``self``. - OUTPUT: - - - an integer. + OUTPUT: integer EXAMPLES:: @@ -4908,9 +4814,9 @@ def part(self, i, all_points=False): INPUT: - - ``i`` -- an integer + - ``i`` -- integer - - ``all_points`` -- (default: ``False``) whether to list all lattice points + - ``all_points`` -- boolean (default: ``False``); whether to list all lattice points or just vertices OUTPUT: @@ -4944,7 +4850,7 @@ def parts(self, all_points=False): INPUT: - - ``all_points`` -- (default: ``False``) whether to list all lattice points + - ``all_points`` -- boolean (default: ``False``); whether to list all lattice points or just vertices OUTPUT: @@ -4985,7 +4891,7 @@ def part_of(self, i): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer OUTPUT: @@ -5014,7 +4920,7 @@ def part_of_point(self, i): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer OUTPUT: @@ -5026,7 +4932,7 @@ def part_of_point(self, i): Since a nef-partition induces a partition on the set of boundary lattice points of `\Delta^\circ`, the value of `j` is well-defined for all `i` but the one that corresponds to the origin, in which - case this method will raise a :class:`ValueError` exception. + case this method will raise a :exc:`ValueError` exception. (The origin always belongs to all `\nabla_j`.) See :class:`nef-partition ` class documentation for @@ -5078,6 +4984,7 @@ def part_of_point(self, i): _palp_dimension = None + def _palp(command, polytopes, reduce_dimension=False): r""" Run ``command`` on vertices of given @@ -5086,7 +4993,7 @@ def _palp(command, polytopes, reduce_dimension=False): Returns the name of the file containing the output of ``command``. You should delete it after using. - .. note:: + .. NOTE:: PALP cannot be called for polytopes that do not span the ambient space. If you specify ``reduce_dimension=True`` argument, PALP will be @@ -5173,12 +5080,12 @@ def _palp_canonical_order(V, PM_max, permutations): INPUT: - - ``V`` -- :class:`point collection `. The vertices. + - ``V`` -- :class:`point collection `. The vertices - ``PM_max`` -- the maximal vertex-facet pairing matrix - ``permutations`` -- the permutations of the vertices yielding - ``PM_max``. + ``PM_max`` OUTPUT: @@ -5219,11 +5126,9 @@ def _palp_convert_permutation(permutation): INPUT: - - ``permutation`` -- A string specifying a PALP style permutation. + - ``permutation`` -- string specifying a PALP style permutation - OUTPUT: - - A :class:`permutation group element `. + OUTPUT: a :class:`permutation group element ` EXAMPLES:: @@ -5260,13 +5165,15 @@ def _read_nef_x_partitions(data): Read all nef-partitions for one polytope from a string or an open file. - ``data`` should be an output of nef.x. + INPUT: + + - ``data`` -- should be an output of ``nef.x`` Returns the sequence of nef-partitions. Each nef-partition is given as a sequence of integers. If there are no nef-partitions, returns the empty sequence. If the - string is empty or EOF is reached, raises ValueError. + string is empty or EOF is reached, raises :exc:`ValueError`. TESTS:: @@ -5319,17 +5226,15 @@ def _read_poly_x_incidences(data, dim): INPUT: - - ``data`` -- an opened file with incidence - information. The first line will be skipped, each consecutive line - contains incidence information for all faces of one dimension, the - first word of each line is a comment and is dropped. - - - ``dim`` -- dimension of the polytope. + - ``data`` -- an opened file with incidence + information. The first line will be skipped, each consecutive line + contains incidence information for all faces of one dimension, the + first word of each line is a comment and is dropped. - OUTPUT: + - ``dim`` -- dimension of the polytope - a sequence F, such that F[d][i] is a sequence of vertices - or facets corresponding to the i-th d-dimensional face. + OUTPUT: a sequence F, such that F[d][i] is a sequence of vertices + or facets corresponding to the `i`-th d-dimensional face TESTS:: @@ -5381,7 +5286,9 @@ def all_cached_data(polytopes): polytopes in the given sequence should be constructed as the polar polytope to another one. - INPUT: a sequence of lattice polytopes. + INPUT: + + - ``polytopes`` -- a sequence of lattice polytopes EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short @@ -5412,7 +5319,9 @@ def all_nef_partitions(polytopes, keep_symmetric=False): ``all_polars`` on the sequence of ``polytopes`` before using this function. - INPUT: a sequence of lattice polytopes. + INPUT: + + - ``polytopes`` -- a sequence of lattice polytopes EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short @@ -5461,7 +5370,9 @@ def all_points(polytopes): ``LatticePolytope`` during the first run. So it is recommended to use this functions if you work with big sets of data. - INPUT: a sequence of lattice polytopes. + INPUT: + + - ``polytopes`` -- a sequence of lattice polytopes EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short @@ -5514,7 +5425,9 @@ def all_polars(polytopes): ``LatticePolytope`` during the first run. So it is recommended to use this functions if you work with big sets of data. - INPUT: a sequence of lattice polytopes. + INPUT: + + - ``polytopes`` -- a sequence of lattice polytopes EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short @@ -5541,20 +5454,17 @@ def convex_hull(points): r""" Compute the convex hull of the given points. - .. note:: + .. NOTE:: ``points`` might not span the space. Also, it fails for large numbers of vertices in dimensions 4 or greater INPUT: - - ``points`` -- a list that can be converted into - vectors of the same dimension over ZZ. + - ``points`` -- list that can be converted into + vectors of the same dimension over `\ZZ` - OUTPUT: - - list of vertices of the convex hull of the given points (as - vectors). + OUTPUT: list of vertices of the convex hull of the given points (as vectors) EXAMPLES: Let's compute the convex hull of several points on a line in the plane:: @@ -5591,11 +5501,9 @@ def cross_polytope(dim): INPUT: - - ``dim`` -- an integer. - - OUTPUT: + - ``dim`` -- integer - - a :class:`lattice polytope `. + OUTPUT: a :class:`lattice polytope ` EXAMPLES:: @@ -5621,17 +5529,17 @@ def minkowski_sum(points1, points2): r""" Compute the Minkowski sum of two convex polytopes. - .. note:: + .. NOTE:: Polytopes might not be of maximal dimension. INPUT: - - ``points1, points2`` -- lists of objects that can be - converted into vectors of the same dimension, treated as vertices - of two polytopes. + - ``points1``, ``points2`` -- lists of objects that can be + converted into vectors of the same dimension, treated as vertices + of two polytopes. - OUTPUT: list of vertices of the Minkowski sum, given as vectors. + OUTPUT: list of vertices of the Minkowski sum, given as vectors EXAMPLES: Let's compute the Minkowski sum of two line segments:: @@ -5653,12 +5561,9 @@ def positive_integer_relations(points): INPUT: - - ``points`` -- lattice points given as columns of a - matrix + - ``points`` -- lattice points given as columns of a matrix - OUTPUT: - - matrix of relations between given points with non-negative + OUTPUT: matrix of relations between given points with nonnegative integer coefficients EXAMPLES: This is a 3-dimensional reflexive polytope:: @@ -5684,7 +5589,7 @@ def positive_integer_relations(points): However, the above relations may contain negative and rational numbers. This function transforms them in such a way, that all - coefficients are non-negative integers:: + coefficients are nonnegative integers:: sage: points = p.points().column_matrix() sage: lattice_polytope.positive_integer_relations(points) # needs palp @@ -5708,8 +5613,8 @@ def positive_integer_relations(points): a = nonpivot_relations.stack(a).transpose() new_relations = [] for i in range(n_nonpivots): - # Find a non-negative linear combination of relations, - # such that all components are non-negative and the i-th one is 1 + # Find a nonnegative linear combination of relations, + # such that all components are nonnegative and the `i`-th one is 1 MIP = MixedIntegerLinearProgram(maximization=False, base_ring=QQ) w = MIP.new_variable(integer=False, nonnegative=True) b = vector([0] * i + [1] + [0] * (n_nonpivots - i - 1)) @@ -5742,16 +5647,14 @@ def read_all_polytopes(file_name): INPUT: - - ``file_name`` -- a string with the name of a file with VERTICES of - polytopes. - - OUTPUT: + - ``file_name`` -- string with the name of a file with VERTICES of + polytopes - - a sequence of polytopes. + OUTPUT: a sequence of polytopes EXAMPLES: - We use poly.x to compute two polar polytopes and read them:: + We use ``poly.x`` to compute two polar polytopes and read them:: sage: # needs palp sage: d = lattice_polytope.cross_polytope(2) @@ -5801,16 +5704,14 @@ def read_palp_matrix(data, permutation=False): INPUT: - - ``data`` -- Either a string containing the filename or the file itself - containing the output by PALP. + - ``data`` -- either a string containing the filename or the file itself + containing the output by PALP - - ``permutation`` -- (default: ``False``) If ``True``, try to retrieve + - ``permutation`` -- boolean (default: ``False``); if ``True``, try to retrieve the permutation output by PALP. This parameter makes sense only when PALP computed the normal form of a lattice polytope. - OUTPUT: - - A matrix or a tuple of a matrix and a permutation. + OUTPUT: a matrix or a tuple of a matrix and a permutation EXAMPLES:: @@ -5857,11 +5758,9 @@ def set_palp_dimension(d): INPUT: - - ``d`` -- an integer from the list [4,5,6,11] or ``None``. - - OUTPUT: + - ``d`` -- integer from the list ``[4,5,6,11]`` or ``None`` - - none. + OUTPUT: none PALP has many hard-coded limits, which must be specified before compilation, one of them is dimension. Sage includes several versions with @@ -5903,16 +5802,14 @@ def skip_palp_matrix(data, n=1): INPUT: + - ``data`` -- opened file with blocks of matrix data in + the following format: A block consisting of m+1 lines has the + number m as the first element of its first line. - - ``data`` -- opened file with blocks of matrix data in - the following format: A block consisting of m+1 lines has the - number m as the first element of its first line. - - - ``n`` -- (default: 1) integer, specifies how many - blocks should be skipped + - ``n`` -- (default: 1) integer, specifies how many + blocks should be skipped - - If EOF is reached during the process, raises ValueError exception. + If EOF is reached during the process, raises :exc:`ValueError` exception. EXAMPLES: We create a file with vertices of the square and the cube, but read only the second set:: @@ -5955,25 +5852,22 @@ def skip_palp_matrix(data, n=1): raise ValueError("There are not enough data to skip!") -def write_palp_matrix(m, ofile=None, comment="", format=None): +def write_palp_matrix(m, ofile=None, comment='', format=None): r""" Write ``m`` into ``ofile`` in PALP format. INPUT: - ``m`` -- a matrix over integers or a - :class:`point collection `. - - - ``ofile`` -- a file opened for writing (default: stdout) + :class:`point collection ` - - ``comment`` -- a string (default: empty) see output description + - ``ofile`` -- a file opened for writing (default: ``stdout``) - - ``format`` -- a format string used to print matrix entries. + - ``comment`` -- string (default: empty); see output description + - ``format`` -- a format string used to print matrix entries - OUTPUT: - - - nothing is returned, output written to ``ofile`` has the format + OUTPUT: nothing is returned, output written to ``ofile`` has the format * First line: number_of_rows number_of_columns comment * Next number_of_rows lines: rows of the matrix. @@ -5986,7 +5880,7 @@ def write_palp_matrix(m, ofile=None, comment="", format=None): 1 0 0 -1 0 0 0 1 0 0 -1 0 0 0 1 0 0 -1 - sage: lattice_polytope.write_palp_matrix(o.vertices(), format="%4d") + sage: lattice_polytope.write_palp_matrix(o.vertices(), format='%4d') 3 6 1 0 0 -1 0 0 0 1 0 0 -1 0 diff --git a/src/sage/geometry/linear_expression.py b/src/sage/geometry/linear_expression.py index 8cee8aa7c12..28388cd4232 100644 --- a/src/sage/geometry/linear_expression.py +++ b/src/sage/geometry/linear_expression.py @@ -103,9 +103,7 @@ def A(self): """ Return the coefficient vector. - OUTPUT: - - The coefficient vector of the linear expression. + OUTPUT: the coefficient vector of the linear expression EXAMPLES:: @@ -124,9 +122,7 @@ def b(self): """ Return the constant term. - OUTPUT: - - The constant term of the linear expression. + OUTPUT: the constant term of the linear expression EXAMPLES:: @@ -225,12 +221,10 @@ def _repr_linear(self, include_zero=True, include_constant=True, multiplication= - ``include_constant`` -- whether to include the constant term - - ``multiplication`` -- string (default: ``*``); the + - ``multiplication`` -- string (default: ``'*'``); the multiplication symbol to use - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -359,9 +353,7 @@ def change_ring(self, base_ring): - ``base_ring`` -- a ring; the new base ring - OUTPUT: - - A new linear expression over the new base ring. + OUTPUT: a new linear expression over the new base ring EXAMPLES:: @@ -427,9 +419,7 @@ def evaluate(self, point): - ``point`` -- list/tuple/iterable of coordinates; the coordinates of a point - OUTPUT: - - The linear expression `Ax + b` evaluated at the point `x`. + OUTPUT: the linear expression `Ax + b` evaluated at the point `x` EXAMPLES:: @@ -510,7 +500,7 @@ def basis(self): """ from sage.sets.family import Family gens = self.gens() - d = {i: g for i, g in enumerate(gens)} + d = dict(enumerate(gens)) d['b'] = self.element_class(self, self.ambient_module().zero(), self.base_ring().one()) return Family(list(range(len(gens))) + ['b'], lambda i: d[i]) @@ -520,9 +510,7 @@ def ngens(self): """ Return the number of linear variables. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -538,9 +526,7 @@ def gens(self) -> tuple: """ Return the generators of ``self``. - OUTPUT: - - A tuple of linear expressions, one for each linear variable. + OUTPUT: a tuple of linear expressions, one for each linear variable EXAMPLES:: @@ -561,9 +547,7 @@ def gen(self, i): - ``i`` -- integer - OUTPUT: - - A linear expression. + OUTPUT: a linear expression EXAMPLES:: @@ -752,9 +736,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -773,9 +755,7 @@ def change_ring(self, base_ring): - ``base_ring`` -- a ring; the new base ring - OUTPUT: - - A new linear expression over the new base ring. + OUTPUT: a new linear expression over the new base ring EXAMPLES:: diff --git a/src/sage/geometry/meson.build b/src/sage/geometry/meson.build new file mode 100644 index 00000000000..826ca9ef1db --- /dev/null +++ b/src/sage/geometry/meson.build @@ -0,0 +1,55 @@ +py.install_sources( + 'all.py', + 'cone.py', + 'cone_catalog.py', + 'cone_critical_angles.py', + 'convex_set.py', + 'fan.py', + 'fan_isomorphism.py', + 'fan_morphism.py', + 'hasse_diagram.py', + 'integral_points.py', + 'lattice_polytope.py', + 'linear_expression.py', + 'newton_polygon.py', + 'polyhedral_complex.py', + 'pseudolines.py', + 'relative_interior.py', + 'ribbon_graph.py', + 'toric_lattice.py', + 'toric_plotter.py', + 'voronoi_diagram.py', + subdir: 'sage/geometry', +) + +extension_data = { + 'abc' : files('abc.pyx'), + 'integral_points_generic_dense' : files('integral_points_generic_dense.pyx'), + 'integral_points_integer_dense' : files('integral_points_integer_dense.pyx'), + 'palp_normal_form' : files('palp_normal_form.pyx'), + 'point_collection' : files('point_collection.pyx'), + 'toric_lattice_element' : files('toric_lattice_element.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/geometry', + install: true, + include_directories: [inc_cpython, inc_ext, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + +install_subdir('hyperbolic_space', install_dir: sage_install_dir / 'geometry') +install_subdir( + 'hyperplane_arrangement', + install_dir: sage_install_dir / 'geometry', +) +subdir('polyhedron') +install_subdir( + 'riemannian_manifolds', + install_dir: sage_install_dir / 'geometry', +) +subdir('triangulation') diff --git a/src/sage/geometry/newton_polygon.py b/src/sage/geometry/newton_polygon.py index c8e185d01e6..05cfbcbf621 100644 --- a/src/sage/geometry/newton_polygon.py +++ b/src/sage/geometry/newton_polygon.py @@ -36,7 +36,7 @@ def __init__(self, polyhedron, parent): INPUT: - - polyhedron -- a polyhedron defining the Newton polygon + - ``polyhedron`` -- a polyhedron defining the Newton polygon TESTS: @@ -87,15 +87,13 @@ def _repr_(self): def vertices(self, copy=True): """ - Returns the list of vertices of this Newton polygon + Return the list of vertices of this Newton polygon. INPUT: - - ``copy`` -- a boolean (default: ``True``) + - ``copy`` -- boolean (default: ``True``) - OUTPUT: - - The list of vertices of this Newton polygon (or a copy of it + OUTPUT: the list of vertices of this Newton polygon (or a copy of it if ``copy`` is set to True) EXAMPLES:: @@ -126,7 +124,7 @@ def vertices(self, copy=True): @cached_method def last_slope(self): """ - Returns the last (infinite) slope of this Newton polygon + Return the last (infinite) slope of this Newton polygon if it is infinite and ``+Infinity`` otherwise. EXAMPLES:: @@ -156,11 +154,11 @@ def last_slope(self): def slopes(self, repetition=True): """ - Returns the slopes of this Newton polygon + Return the slopes of this Newton polygon. INPUT: - - ``repetition`` -- a boolean (default: ``True``) + - ``repetition`` -- boolean (default: ``True``) OUTPUT: @@ -196,15 +194,13 @@ def slopes(self, repetition=True): def _add_(self, other): """ - Returns the convex hull of ``self`` and ``other`` + Return the convex hull of ``self`` and ``other``. INPUT: - ``other`` -- a Newton polygon - OUTPUT: - - The Newton polygon, which is the convex hull of this Newton polygon and ``other`` + OUTPUT: the Newton polygon, which is the convex hull of this Newton polygon and ``other`` EXAMPLES:: @@ -222,15 +218,13 @@ def _add_(self, other): def _mul_(self, other): """ - Returns the Minkowski sum of ``self`` and ``other`` + Return the Minkowski sum of ``self`` and ``other``. INPUT: - ``other`` -- a Newton polygon - OUTPUT: - - The Newton polygon, which is the Minkowski sum of this Newton polygon and ``other``. + OUTPUT: the Newton polygon, which is the Minkowski sum of this Newton polygon and ``other`` .. NOTE:: @@ -263,15 +257,13 @@ def _mul_(self, other): def __pow__(self, exp, ignored=None): """ - Returns ``self`` dilated by ``exp`` + Return ``self`` dilated by ``exp``. INPUT: - - ``exp`` -- a positive integer - - OUTPUT: + - ``exp`` -- positive integer - This Newton polygon scaled by a factor ``exp``. + OUTPUT: this Newton polygon scaled by a factor ``exp`` .. NOTE:: @@ -292,15 +284,13 @@ def __pow__(self, exp, ignored=None): def __lshift__(self, i): """ - Returns ``self`` shifted by `(0,i)` + Return ``self`` shifted by `(0,i)`. INPUT: - ``i`` -- a rational number - OUTPUT: - - This Newton polygon shifted by the vector `(0,i)` + OUTPUT: this Newton polygon shifted by the vector `(0,i)` EXAMPLES:: @@ -316,15 +306,13 @@ def __lshift__(self, i): def __rshift__(self, i): """ - Returns ``self`` shifted by `(0,-i)` + Return ``self`` shifted by `(0,-i)`. INPUT: - ``i`` -- a rational number - OUTPUT: - - This Newton polygon shifted by the vector `(0,-i)` + OUTPUT: this Newton polygon shifted by the vector `(0,-i)` EXAMPLES:: @@ -340,15 +328,13 @@ def __rshift__(self, i): def __call__(self, x): """ - Returns `self(x)` + Return `self(x)`. INPUT: - ``x`` -- a real number - OUTPUT: - - The value of this Newton polygon at abscissa `x` + OUTPUT: the value of this Newton polygon at abscissa `x` EXAMPLES:: @@ -476,27 +462,27 @@ def plot(self, **kwargs): (xstart,ystart) = vertices[0] (xend,yend) = vertices[-1] if self.last_slope() is Infinity: - return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle="--", **kwargs) \ + return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle='--', **kwargs) \ + line([(xstart, ystart+0.5)] + vertices + [(xend, yend+0.5)], **kwargs) \ - + line([(xend, yend+0.5), (xend, yend+1)], linestyle="--", **kwargs) + + line([(xend, yend+0.5), (xend, yend+1)], linestyle='--', **kwargs) else: - return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle="--", **kwargs) \ + return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle='--', **kwargs) \ + line([(xstart, ystart+0.5)] + vertices + [(xend+0.5, yend + 0.5*self.last_slope())], **kwargs) \ - + line([(xend+0.5, yend + 0.5*self.last_slope()), (xend+1, yend+self.last_slope())], linestyle="--", **kwargs) + + line([(xend+0.5, yend + 0.5*self.last_slope()), (xend+1, yend+self.last_slope())], linestyle='--', **kwargs) def reverse(self, degree=None): r""" - Returns the symmetric of ``self`` + Return the symmetric of ``self``. INPUT: - - ``degree`` -- an integer (default: the top right abscissa of + - ``degree`` -- integer (default: the top right abscissa of this Newton polygon) OUTPUT: The image this Newton polygon under the symmetry - '(x,y) \mapsto (degree-x, y)` + '(x,y) \mapsto (degree-x, y)`. EXAMPLES:: @@ -530,20 +516,18 @@ class ParentNewtonPolygon(Parent, UniqueRepresentation): INPUT: - - ``arg`` -- a list/tuple/iterable of vertices or of - slopes. Currently, slopes must be rational numbers. + - ``arg`` -- list/tuple/iterable of vertices or of + slopes. Currently, slopes must be rational numbers - - ``sort_slopes`` -- boolean (default: ``True``). Specifying - whether slopes must be first sorted + - ``sort_slopes`` -- boolean (default: ``True``); whether slopes must be + first sorted - ``last_slope`` -- rational or infinity (default: - ``Infinity``). The last slope of the Newton polygon - - OUTPUT: + ``Infinity``); the last slope of the Newton polygon - The corresponding Newton polygon. + OUTPUT: the corresponding Newton polygon - .. note:: + .. NOTE:: By convention, a Newton polygon always contains the point at infinity `(0, \infty)`. These polygons are attached to @@ -652,8 +636,8 @@ def __init__(self): def _repr_(self): """ - Returns the string representation of this parent, - which is ``Parent for Newton polygons`` + Return the string representation of this parent, + which is ``Parent for Newton polygons``. TESTS: @@ -668,7 +652,7 @@ def _repr_(self): def _an_element_(self): """ - Returns a Newton polygon (which is the empty one) + Return a Newton polygon (which is the empty one). TESTS: @@ -684,8 +668,8 @@ def _element_constructor_(self, arg, sort_slopes=True, last_slope=Infinity): - ``arg`` -- an argument describing the Newton polygon - - ``sort_slopes`` -- boolean (default: ``True``). Specifying - whether slopes must be first sorted + - ``sort_slopes`` -- boolean (default: ``True``); whether + slopes must be first sorted - ``last_slope`` -- rational or infinity (default: ``Infinity``). The last slope of the Newton polygon @@ -703,9 +687,7 @@ def _element_constructor_(self, arg, sort_slopes=True, last_slope=Infinity): - a list/tuple/iterable of slopes - OUTPUT: - - The corresponding Newton polygon. + OUTPUT: the corresponding Newton polygon For more informations, see :class:`ParentNewtonPolygon`. diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index fa756fe65b0..82e26830234 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -42,9 +42,9 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): INPUT: - - ``check`` -- Boolean (default: ``False``), whether to return + - ``check`` -- boolean (default: ``False``); whether to return the permutations leaving the maximal vertex-facet pairing - matrix invariant. + matrix invariant OUTPUT: @@ -350,15 +350,13 @@ def _palp_canonical_order(vertices, PM_max, permutations): INPUT: - - ``vertices`` -- iterable of iterables. The vertices. + - ``vertices`` -- iterable of iterables; the vertices - ``PM_max`` -- the maximal vertex-facet pairing matrix - - ``permutation`` -- the permutations of the vertices yielding ``PM_max``. + - ``permutation`` -- the permutations of the vertices yielding ``PM_max`` - OUTPUT: - - The PALP normal form as an iterable of integer vectors. + OUTPUT: the PALP normal form as an iterable of integer vectors TESTS:: diff --git a/src/sage/geometry/point_collection.pyx b/src/sage/geometry/point_collection.pyx index ae4c92ffd75..f310dc7cb14 100644 --- a/src/sage/geometry/point_collection.pyx +++ b/src/sage/geometry/point_collection.pyx @@ -90,11 +90,9 @@ def is_PointCollection(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - - ``True`` if ``x`` is a point collection and ``False`` otherwise. + OUTPUT: ``True`` if ``x`` is a point collection and ``False`` otherwise EXAMPLES:: @@ -205,11 +203,9 @@ cdef class PointCollection(SageObject): - ``left`` -- a :class:`PointCollection`; - - ``right`` -- a :class:`PointCollection`. - - OUTPUT: + - ``right`` -- a :class:`PointCollection` - - a :class:`PointCollection`. + OUTPUT: a :class:`PointCollection` TESTS:: @@ -243,9 +239,7 @@ cdef class PointCollection(SageObject): - a list of integers (as a single or many arguments). - OUTPUT: - - - a :class:`point collection `. + OUTPUT: a :class:`point collection ` TESTS:: @@ -279,9 +273,7 @@ cdef class PointCollection(SageObject): - ``right`` -- another PointCollection - OUTPUT: - - boolean + OUTPUT: boolean First compare according to the underlying :meth:`module` and then according to the list of points. @@ -314,11 +306,9 @@ cdef class PointCollection(SageObject): INPUT: - - ``n`` -- an integer. + - ``n`` -- integer - OUTPUT: - - - a point, an element of the ambient :meth:`module` of ``self``. + OUTPUT: a point, an element of the ambient :meth:`module` of ``self`` EXAMPLES:: @@ -332,9 +322,7 @@ cdef class PointCollection(SageObject): r""" Return the hash of ``self``. - OUTPUT: - - - an integer. + OUTPUT: integer TESTS:: @@ -348,9 +336,7 @@ cdef class PointCollection(SageObject): r""" Return an iterator over points of ``self``. - OUTPUT: - - - an iterator. + OUTPUT: an iterator TESTS:: @@ -367,9 +353,7 @@ cdef class PointCollection(SageObject): r""" Return the number of points in ``self``. - OUTPUT: - - - an integer. + OUTPUT: integer EXAMPLES:: @@ -383,9 +367,7 @@ cdef class PointCollection(SageObject): r""" Return a list of points of ``self``. - OUTPUT: - - - a list. + OUTPUT: list TESTS:: @@ -481,9 +463,7 @@ cdef class PointCollection(SageObject): r""" Return the tuple of points of ``self``. - OUTPUT: - - - a tuple. + OUTPUT: a tuple TESTS:: @@ -497,9 +477,7 @@ cdef class PointCollection(SageObject): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - a string. + OUTPUT: string TESTS:: @@ -527,11 +505,9 @@ cdef class PointCollection(SageObject): INPUT: - ``ring`` -- a base ring for the returned matrix (default: base ring of - :meth:`module` of ``self``). - - OUTPUT: + :meth:`module` of ``self``) - - a :class:`matrix `. + OUTPUT: a :class:`matrix ` EXAMPLES:: @@ -551,9 +527,7 @@ cdef class PointCollection(SageObject): r""" Return a string representation of ``self``. - OUTPUT: - - - a string. + OUTPUT: string TESTS:: @@ -631,9 +605,7 @@ cdef class PointCollection(SageObject): r""" Return the number of points in ``self``. - OUTPUT: - - - an integer. + OUTPUT: integer EXAMPLES:: @@ -655,9 +627,7 @@ cdef class PointCollection(SageObject): default, the direct sum of the ambient modules of ``self`` and ``other`` is constructed. - OUTPUT: - - - a :class:`point collection `. + OUTPUT: a :class:`point collection ` EXAMPLES:: @@ -683,9 +653,7 @@ cdef class PointCollection(SageObject): r""" Return a matrix whose columns are points of ``self``. - OUTPUT: - - - a :class:`matrix `. + OUTPUT: a :class:`matrix ` EXAMPLES:: @@ -703,9 +671,7 @@ cdef class PointCollection(SageObject): .. NOTE:: You can use either :meth:`dim` or :meth:`dimension`. - OUTPUT: - - - an integer. + OUTPUT: integer EXAMPLES:: @@ -749,18 +715,16 @@ cdef class PointCollection(SageObject): INPUT: - - ``point`` -- a point of ``self``; + - ``point`` -- a point of ``self`` - ``start`` -- (optional) an integer, if given, the search will start - at this position; + at this position - ``stop`` -- (optional) an integer, if given, the search will stop - at this position. + at this position - OUTPUT: - - - an integer if ``point`` is in ``self[start:stop]``, otherwise a - :class:`ValueError` exception is raised. + OUTPUT: an integer if ``point`` is in ``self[start:stop]``, otherwise a + :exc:`ValueError` exception is raised EXAMPLES:: @@ -786,9 +750,7 @@ cdef class PointCollection(SageObject): r""" Return a matrix whose rows are points of ``self``. - OUTPUT: - - - a :class:`matrix `. + OUTPUT: a :class:`matrix ` EXAMPLES:: @@ -810,9 +772,7 @@ cdef class PointCollection(SageObject): r""" Return the ambient module of ``self``. - OUTPUT: - - - a :class:`module `. + OUTPUT: a :class:`module ` EXAMPLES:: @@ -912,9 +872,7 @@ cdef class PointCollection(SageObject): r""" Return points of ``self`` as a :class:`frozenset`. - OUTPUT: - - - a :class:`frozenset`. + OUTPUT: a :class:`frozenset` EXAMPLES:: @@ -932,7 +890,7 @@ cdef class PointCollection(SageObject): INPUT: - - ``f`` -- a file opened for writing. + - ``f`` -- a file opened for writing EXAMPLES:: @@ -974,13 +932,13 @@ def read_palp_point_collection(f, lattice=None, permutation=False): INPUT: - - ``f`` -- an opened file with PALP output. + - ``f`` -- an opened file with PALP output - ``lattice`` -- the lattice for points. If not given, the :class:`toric lattice ` `M` of dimension `n` will be used. - - ``permutation`` -- (default: ``False``) if ``True``, try to retrieve + - ``permutation`` -- boolean (default: ``False``); if ``True``, try to retrieve the permutation. This parameter makes sense only when PALP computed the normal form of a lattice polytope. diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index 56a84be0300..539e2021f88 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -150,7 +150,7 @@ class PolyhedralComplex(GenericCellComplex): INPUT: - - ``maximal_cells`` -- a list, a tuple, or a dictionary (indexed by + - ``maximal_cells`` -- list, tuple, or dictionary (indexed by dimension) of cells of the Complex. Each cell is of class :class:`Polyhedron` of the same ambient dimension. To set up a :class:PolyhedralComplex, it is sufficient to provide the maximal @@ -165,7 +165,7 @@ class PolyhedralComplex(GenericCellComplex): - ``face_to_face_check`` -- boolean (default: ``False``); if ``True``, then the constructor checks whether the cells - are face-to-face, and it raises a :class:`ValueError` if they are not + are face-to-face, and it raises a :exc:`ValueError` if they are not - ``is_mutable`` and ``is_immutable`` -- boolean (default: ``True`` and ``False`` respectively); set ``is_mutable=False`` or ``is_immutable=True`` @@ -394,7 +394,7 @@ def cell_iterator(self, increasing=True): INPUT: - - ``increasing`` -- (default ``True``) if ``True``, return + - ``increasing`` -- boolean (default: ``True``); if ``True``, return cells in increasing order of dimension, thus starting with the zero-dimensional cells; otherwise it returns cells in decreasing order of dimension @@ -425,7 +425,7 @@ def _n_cells_sorted(self, n, subcomplex=None): INPUT: - - ``n`` -- non-negative integer; the dimension + - ``n`` -- nonnegative integer; the dimension - ``subcomplex`` -- (optional) if a subcomplex is given then return the cells which are **not** in this subcomplex @@ -509,7 +509,7 @@ def maximal_cell_iterator(self, increasing=False): INPUT: - - ``increasing`` -- (default: ``False``) if ``True``, return + - ``increasing`` -- boolean (default: ``False``); if ``True``, return maximal cells in increasing order of dimension. Otherwise it returns cells in decreasing order of dimension. @@ -552,7 +552,7 @@ def n_maximal_cells(self, n): INPUT: - - ``n`` -- non-negative integer; the dimension + - ``n`` -- nonnegative integer; the dimension .. NOTE:: @@ -594,7 +594,7 @@ def _n_maximal_cells_sorted(self, n): INPUT: - - ``n`` -- (non-negative integer) the dimension + - ``n`` -- nonnegative integer; the dimension .. WARNING:: @@ -730,15 +730,15 @@ def plot(self, **kwds): can be passed to :func:`exploded_plot`: - ``center`` -- (default: ``None``, denoting the origin) the center of explosion - - ``sticky_vertices`` -- (default: ``False``) boolean or dict. - Whether to draw line segments between shared vertices of the given polyhedra. + - ``sticky_vertices`` -- (default: ``False``) boolean or dict; + whether to draw line segments between shared vertices of the given polyhedra. A dict gives options for :func:`sage.plot.line`. - ``sticky_center`` -- (default: ``True``) boolean or dict. When ``center`` is a vertex of some of the polyhedra, whether to draw line segments connecting the ``center`` to the shifted copies of these vertices. A dict gives options for :func:`sage.plot.line`. - - ``color`` -- (default: ``None``) if ``"rainbow"``, assign a different color + - ``color`` -- (default: ``None``) if ``'rainbow'``, assign a different color to every maximal cell; otherwise, passed on to :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot`. @@ -775,7 +775,6 @@ def plot(self, **kwds): ....: Polyhedron(rays=[[-1,0,0], [0,1,0], [0,0,1]])]) sage: g5 = pc5.plot(explosion_factor=0.3, color='rainbow', alpha=0.8, # needs sage.plot ....: point={'size': 20}, axes=False, online=True) - """ if self.dimension() > 3: raise ValueError("cannot plot in high dimension") @@ -946,7 +945,7 @@ def _an_element_(self): def __contains__(self, x): """ - True if ``x`` is a polyhedron which is contained in this complex. + Return ``True`` if ``x`` is a polyhedron which is contained in this complex. EXAMPLES:: @@ -972,7 +971,7 @@ def __contains__(self, x): def __call__(self, x): """ If ``x`` is a polyhedron in this complex, return it. - Otherwise, raise a :class:`ValueError`. + Otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -1062,7 +1061,7 @@ def is_subcomplex(self, other): def is_compact(self): """ - Test for boundedness of the polyhedral complex + Test for boundedness of the polyhedral complex. EXAMPLES:: @@ -1080,7 +1079,7 @@ def graph(self): Return the 1-skeleton of this polyhedral complex, as a graph. The vertices of the graph are of type ``vector``. This raises - a :class:`NotImplementedError` if the polyhedral complex is unbounded. + a :exc:`NotImplementedError` if the polyhedral complex is unbounded. .. WARNING:: @@ -1319,7 +1318,7 @@ def n_skeleton(self, n): INPUT: - - ``n`` -- non-negative integer; the dimension + - ``n`` -- nonnegative integer; the dimension .. SEEALSO:: @@ -1676,9 +1675,7 @@ def product(self, right): - ``right`` -- the other polyhedral complex (the right-hand factor) - OUTPUT: - - - the product ``self x right`` + OUTPUT: the product ``self x right`` EXAMPLES:: @@ -2077,8 +2074,7 @@ def add_cell(self, cell): raise ValueError("the cell is not face-to-face with complex") # update dim and maximal cells d = cell.dimension() - if d > self._dim: - self._dim = d + self._dim = max(d, self._dim) maximal_cells = poset.maximal_elements() # a list self._maximal_cells = cells_list_to_cells_dict(maximal_cells) # update convexity if self was known to be convex, reset otherwise. @@ -2139,7 +2135,7 @@ def remove_cell(self, cell, check=False): TESTS: - Check that ValueError and empty complex are treated properly:: + Check that :exc:`ValueError` and empty complex are treated properly:: sage: p = Polyhedron(vertices=[[1]]) sage: pc = PolyhedralComplex([p]) @@ -2462,7 +2458,7 @@ def subdivide(self, make_simplicial=False, return PolyhedralComplex(cones, maximality_check=False, backend=self._backend) else: - # TODO: `self`` is unbounded, make it projectively simplicial. + # TODO: ``self`` is unbounded, make it projectively simplicial. # (1) homogenize self of dim d to fan in space of dim d+1; # (2) call fan.subdivide(make_simplicial=True); # (3) take section back to the space of dim d. @@ -2506,28 +2502,35 @@ def exploded_plot(polyhedra, *, center=None, explosion_factor=1, sticky_vertices=False, sticky_center=True, point=None, **kwds): r""" - Return a plot of several ``polyhedra`` in one figure with extra space between them. + Return a plot of several ``polyhedra`` in one figure with extra space + between them. INPUT: - - ``polyhedra`` -- an iterable of :class:`~sage.geometry.polyhedron.base.Polyhedron_base` objects + - ``polyhedra`` -- an iterable of + :class:`~sage.geometry.polyhedron.base.Polyhedron_base` objects - - ``center`` -- (default: ``None``, denoting the origin) the center of explosion + - ``center`` -- (default: ``None``, denoting the origin) the center of + explosion - - ``explosion_factor`` -- (default: 1) a nonnegative number; translate polyhedra by this - factor of the distance from ``center`` to their center + - ``explosion_factor`` -- (default: 1) a nonnegative number; translate + polyhedra by this factor of the distance from ``center`` to their center - - ``sticky_vertices`` -- (default: ``False``) boolean or dict. Whether to draw line segments between shared - vertices of the given polyhedra. A dict gives options for :func:`sage.plot.line`. + - ``sticky_vertices`` -- (default: ``False``) boolean or dict; whether to + draw line segments between shared vertices of the given polyhedra. A dict + gives options for :func:`sage.plot.line`. - - ``sticky_center`` -- (default: ``True``) boolean or dict. When ``center`` is a vertex of some - of the polyhedra, whether to draw line segments connecting the ``center`` to the shifted copies - of these vertices. A dict gives options for :func:`sage.plot.line`. + - ``sticky_center`` -- (default: ``True``) boolean or dict. When ``center`` + is a vertex of some of the polyhedra, whether to draw line segments + connecting the ``center`` to the shifted copies of these vertices. A dict + gives options for :func:`sage.plot.line`. - - ``color`` -- (default: ``None``) if ``"rainbow"``, assign a different color to every maximal cell and - every vertex; otherwise, passed on to :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot`. + - ``color`` -- (default: ``None``) if ``'rainbow'``, assign a different + color to every maximal cell and every vertex; otherwise, passed on to + :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot` - - other keyword arguments are passed on to :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot`. + - other keyword arguments are passed on to + :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/backend_cdd.py b/src/sage/geometry/polyhedron/backend_cdd.py index a333defe55c..07abff41d80 100644 --- a/src/sage/geometry/polyhedron/backend_cdd.py +++ b/src/sage/geometry/polyhedron/backend_cdd.py @@ -34,8 +34,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, verbose=False): INPUT: - ``vertices`` -- list of point. Each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - ``rays`` -- list of rays. Each ray can be specified as any iterable container of @@ -45,8 +45,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, verbose=False): any iterable container of :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes EXAMPLES:: @@ -97,8 +97,8 @@ def _init_from_Hrepresentation(self, ieqs, eqns, verbose=False): as any iterable container of :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes EXAMPLES:: @@ -193,7 +193,6 @@ def _parse_block(cls, cddout, header, parser): sage: Polyhedron_cdd._parse_block(cddout, 'HEADER', parser) INTRO: [['intro', '0', '1', '2']] DATA: [['data', '0', '1', '2'], ['data', '3', '4', '5']] - """ try: block = cddout[cddout.index(header)+1:] @@ -407,16 +406,16 @@ def parse_incidence_matrix(intro, data): class Polyhedron_QQ_cdd(Polyhedron_cdd, Polyhedron_QQ): """ - Polyhedra over QQ with cdd + Polyhedra over QQ with cdd. INPUT: - ``parent`` -- the parent, an instance of - :class:`~sage.geometry.polyhedron.parent.Polyhedra`. + :class:`~sage.geometry.polyhedron.parent.Polyhedra` - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/backend_cdd_rdf.py b/src/sage/geometry/polyhedron/backend_cdd_rdf.py index 72def8849ad..985cad14419 100644 --- a/src/sage/geometry/polyhedron/backend_cdd_rdf.py +++ b/src/sage/geometry/polyhedron/backend_cdd_rdf.py @@ -22,15 +22,15 @@ class Polyhedron_RDF_cdd(Polyhedron_cdd, Polyhedron_RDF): """ - Polyhedra over RDF with cdd + Polyhedra over RDF with cdd. INPUT: - - ``ambient_dim`` -- integer. The dimension of the ambient space. + - ``ambient_dim`` -- integer; the dimension of the ambient space - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/backend_field.py b/src/sage/geometry/polyhedron/backend_field.py index 7026cca98b8..ebed490d7af 100644 --- a/src/sage/geometry/polyhedron/backend_field.py +++ b/src/sage/geometry/polyhedron/backend_field.py @@ -37,13 +37,13 @@ class Polyhedron_field(Polyhedron_base): """ - Polyhedra over all fields supported by Sage + Polyhedra over all fields supported by Sage. INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: @@ -79,11 +79,9 @@ def _is_zero(self, x): INPUT: - - ``x`` -- a number in the base ring. + - ``x`` -- a number in the base ring - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -101,11 +99,9 @@ def _is_nonneg(self, x): INPUT: - - ``x`` -- a number in the base ring. - - OUTPUT: + - ``x`` -- a number in the base ring - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -123,11 +119,9 @@ def _is_positive(self, x): INPUT: - - ``x`` -- a number in the base ring. - - OUTPUT: + - ``x`` -- a number in the base ring - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -173,21 +167,21 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, INPUT: - - ``vertices`` -- list of points. Each point can be specified - as any iterable container of ``internal_base_ring`` elements. + - ``vertices`` -- list of points; each point can be specified + as any iterable container of ``internal_base_ring`` elements - - ``rays`` -- list of rays. Each ray can be specified as any - iterable container of ``internal_base_ring`` elements. + - ``rays`` -- list of rays; each ray can be specified as any + iterable container of ``internal_base_ring`` elements - - ``lines`` -- list of lines. Each line can be specified asinternal_base_ring - any iterable container of ``internal_base_ring`` elements. + - ``lines`` -- list of lines; each line can be specified asinternal_base_ring + any iterable container of ``internal_base_ring`` elements - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes - - ``internal_base_ring`` -- the base ring of the generators' components. - Default is ``None``, in which case, it is set to - :meth:`~sage.geometry.polyhedron.base.base_ring`. + - ``internal_base_ring`` -- the base ring of the generators' components; + default is ``None``, in which case, it is set to + :meth:`~sage.geometry.polyhedron.base.base_ring` EXAMPLES:: @@ -212,18 +206,18 @@ def _init_from_Hrepresentation(self, ieqs, eqns, INPUT: - - ``ieqs`` -- list of inequalities. Each line can be specified - as any iterable container of ``internal_base_ring`` elements. + - ``ieqs`` -- list of inequalities; each line can be specified + as any iterable container of ``internal_base_ring`` elements - - ``eqns`` -- list of equalities. Each line can be specified - as any iterable container of ``internal_base_ring`` elements. + - ``eqns`` -- list of equalities; each line can be specified + as any iterable container of ``internal_base_ring`` elements - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes - - ``internal_base_ring`` -- the base ring of the generators' components. - Default is ``None``, in which case, it is set to - :meth:`~sage.geometry.polyhedron.base.base_ring`. + - ``internal_base_ring`` -- the base ring of the generators' components; + default is ``None``, in which case, it is set to + :meth:`~sage.geometry.polyhedron.base.base_ring` TESTS:: @@ -335,7 +329,7 @@ def _init_Hrepresentation_backend(self, Hrep): def _init_empty_polyhedron(self): """ - Initializes an empty polyhedron. + Initialize an empty polyhedron. TESTS:: diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index 29b914531c4..f93f9d84d81 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -68,18 +68,18 @@ def _format_function_call(fn_name, *v, **k): ######################################################################### class Polyhedron_normaliz(Polyhedron_base_number_field): """ - Polyhedra with normaliz + Polyhedra with normaliz. INPUT: - ``parent`` -- :class:`~sage.geometry.polyhedron.parent.Polyhedra` the parent - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``; the + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None``; the V-representation of the polyhedron; if ``None``, the polyhedron is determined by the H-representation - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``; the + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None``; the H-representation of the polyhedron; if ``None``, the polyhedron is determined by the V-representation @@ -200,7 +200,6 @@ class Polyhedron_normaliz(Polyhedron_base_number_field): the convex hull of 2 vertices sage: P.vertices() # needs sage.rings.number_field sage.symbolic (A vertex at (2^(1/3)), A vertex at (sqrt(2))) - """ def __init__(self, parent, Vrep, Hrep, normaliz_cone=None, normaliz_data=None, internal_base_ring=None, **kwds): """ @@ -428,9 +427,7 @@ def _is_zero(self, x) -> bool: - ``x`` -- a number in the base ring - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -450,9 +447,7 @@ def _is_nonneg(self, x) -> bool: - ``x`` -- a number in the base ring - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -472,9 +467,7 @@ def _is_positive(self, x) -> bool: - ``x`` -- a number in the base ring - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -814,7 +807,7 @@ def rays_subspace_lattice_ieqs_QQ(vertices, rays, lines, ieqs): from sage.matrix.constructor import Matrix lattice = Matrix(ZZ, nmz_vertices + nmz_rays + nmz_lines).saturation() - nmz_lattice = [[x for x in y] for y in lattice] + nmz_lattice = [list(y) for y in lattice] if Matrix(ZZ, nmz_vertices + nmz_rays).rank() == Matrix(ZZ, nmz_rays).rank() + 1: # The recession cone is full-dimensional. @@ -1038,9 +1031,9 @@ def _make_normaliz_cone(data, verbose=False): INPUT: - - ``data`` -- a dictionary + - ``data`` -- dictionary - - ``verbose`` -- a boolean (default: ``False``) + - ``verbose`` -- boolean (default: ``False``) TESTS:: @@ -1061,9 +1054,7 @@ def _get_nmzcone_data(self) -> dict: r""" Get the data necessary to reproduce the normaliz cone. - OUTPUT: - - - ``data`` -- a dictionary. + OUTPUT: ``data`` -- dictionary TESTS: @@ -1105,9 +1096,9 @@ def _normaliz_format(self, data, file_output=None): INPUT: - - ``data`` -- a dictionary of PyNormaliz cone input properties + - ``data`` -- dictionary of PyNormaliz cone input properties - - ``file_output`` (string; optional) -- a filename to which the + - ``file_output`` -- string (optional); a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. @@ -1353,7 +1344,7 @@ def _h_star_vector_normaliz(self) -> list: INPUT: - - ``self`` -- A lattice polytope with backend ``'normaliz'``. + - ``self`` -- a lattice polytope with backend ``'normaliz'`` OUTPUT: @@ -1623,8 +1614,8 @@ class Polyhedron_QQ_normaliz(Polyhedron_normaliz, Polyhedron_QQ): INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None`` + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: @@ -1647,9 +1638,7 @@ def ehrhart_series(self, variable='t'): - ``variable`` -- string (default: ``'t'``) - OUTPUT: - - A rational function. + OUTPUT: a rational function EXAMPLES:: @@ -1737,9 +1726,7 @@ def _ehrhart_quasipolynomial_normaliz(self, variable='t'): - ``variable`` -- string (default: ``'t'``) - OUTPUT: - - A polynomial or tuple of polynomials. + OUTPUT: a polynomial or tuple of polynomials EXAMPLES:: @@ -1810,9 +1797,7 @@ def hilbert_series(self, grading, variable='t'): - ``variable`` -- string (default: ``'t'``) - OUTPUT: - - A rational function. + OUTPUT: a rational function EXAMPLES:: @@ -1905,7 +1890,7 @@ def integral_points(self, threshold=10000) -> tuple: OUTPUT: The list of integral points in the polyhedron. If the - polyhedron is not compact, a :class:`ValueError` is raised. + polyhedron is not compact, a :exc:`ValueError` is raised. EXAMPLES:: @@ -2121,7 +2106,7 @@ def integral_points_generators(self): Return the integral points generators of the polyhedron. Every integral point in the polyhedron can be written as a (unique) - non-negative linear combination of integral points contained in the three + nonnegative linear combination of integral points contained in the three defining parts of the polyhedron: the integral points (the compact part), the recession cone, and the lineality space. @@ -2216,7 +2201,6 @@ class functions. There are several output options to see the intermediary outputs of the function. - EXAMPLES: The `H^*`-polynomial of the standard `d-1` dimensional simplex @@ -2316,7 +2300,7 @@ class functions. # A check on whether the character table has permuted columns tbl = G_perm_gap.CharacterTable() perm = tbl.IdentificationOfConjugacyClasses() - ident_perm = [i for i in range(1, 1 + n_classes)] + ident_perm = list(range(1, 1 + n_classes)) assert perm == ident_perm, "The conjugacy classes don't match with the character table" # Create fixed subpolytopes and their Ehrhart series @@ -2374,7 +2358,7 @@ def _Hstar_as_rat_fct(self, initial_Hstar): INPUT: - - ``initial_Hstar`` -- a vector of rational functions in `t`. + - ``initial_Hstar`` -- a vector of rational functions in `t` OUTPUT: @@ -2441,21 +2425,19 @@ def _is_effective_normaliz(self, Hstar, Hstar_as_lin_comb): coefficient of each `t^i` is an effective character in the ring of class functions of the acting group. A character `\rho` is effective if the coefficients of the irreducible representations in the expression - of `\rho` are non-negative integers. + of `\rho` are nonnegative integers. INPUT: - ``Hstar`` -- a rational function in `t` with coefficients in the ring - of class functions. + of class functions - ``Hstar_as_lin_comb`` -- vector. The coefficients of the irreducible representations of the acting group in the expression of ``Hstar`` as a linear combination of irreducible representations with coefficients in the field of rational functions in `t`. - OUTPUT: - - Boolean. Whether the ``Hstar`` series is effective. + OUTPUT: boolean; whether the ``Hstar`` series is effective EXAMPLES: @@ -2507,8 +2489,8 @@ class Polyhedron_ZZ_normaliz(Polyhedron_QQ_normaliz, Polyhedron_ZZ): INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None`` + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/backend_number_field.py b/src/sage/geometry/polyhedron/backend_number_field.py index e79688bea5f..5a8b8d285a0 100644 --- a/src/sage/geometry/polyhedron/backend_number_field.py +++ b/src/sage/geometry/polyhedron/backend_number_field.py @@ -26,16 +26,16 @@ class Polyhedron_number_field(Polyhedron_field, Polyhedron_base_number_field): r""" - Polyhedra whose data can be converted to number field elements + Polyhedra whose data can be converted to number field elements. All computations are done internally using a fixed real embedded number field, which is determined automatically. INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: @@ -97,8 +97,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, INPUT: - ``vertices`` -- list of points. Each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - ``rays`` -- list of rays. Each ray can be specified as any iterable container of @@ -108,8 +108,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, any iterable container of :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes EXAMPLES:: @@ -150,8 +150,8 @@ def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True, verbose=False): as any iterable container of :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes TESTS:: diff --git a/src/sage/geometry/polyhedron/backend_polymake.py b/src/sage/geometry/polyhedron/backend_polymake.py index 0c19d8b5c91..84fdd48177b 100644 --- a/src/sage/geometry/polyhedron/backend_polymake.py +++ b/src/sage/geometry/polyhedron/backend_polymake.py @@ -33,20 +33,20 @@ ######################################################################### class Polyhedron_polymake(Polyhedron_base): """ - Polyhedra with polymake + Polyhedra with polymake. INPUT: - ``parent`` -- :class:`~sage.geometry.polyhedron.parent.Polyhedra` the parent - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``; the - V-representation of the polyhedron; if ``None``, the polyhedron - is determined by the H-representation + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None``; the + V-representation of the polyhedron. If ``None``, the polyhedron + is determined by the H-representation. - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``; the - H-representation of the polyhedron; if ``None``, the polyhedron - is determined by the V-representation + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None``; the + H-representation of the polyhedron. If ``None``, the polyhedron + is determined by the V-representation. - ``polymake_polytope`` -- a polymake polytope object @@ -133,7 +133,6 @@ class Polyhedron_polymake(Polyhedron_base): ....: backend='polymake') sage: p.n_lines() # optional - jupymake 1 - """ def _is_zero(self, x): @@ -142,11 +141,9 @@ def _is_zero(self, x): INPUT: - - ``x`` -- a number in the base ring. - - OUTPUT: + - ``x`` -- a number in the base ring - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -164,11 +161,9 @@ def _is_nonneg(self, x): INPUT: - - ``x`` -- a number in the base ring. - - OUTPUT: + - ``x`` -- a number in the base ring - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -186,11 +181,9 @@ def _is_positive(self, x): INPUT: - - ``x`` -- a number in the base ring. + - ``x`` -- a number in the base ring - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -204,7 +197,7 @@ def _is_positive(self, x): def __init__(self, parent, Vrep, Hrep, polymake_polytope=None, **kwds): """ - Initializes the polyhedron. + Initialize the polyhedron. See :class:`Polyhedron_polymake` for a description of the input data. @@ -266,8 +259,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbo INPUT: - ``vertices`` -- list of points; each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements - ``rays`` -- list of rays; each ray can be specified as any iterable container of @@ -299,8 +292,8 @@ def _polymake_Vrepresentation_data(self, vertices, rays, lines, minimal=False): INPUT: - ``vertices`` -- list of points; each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements - ``rays`` -- list of rays; each ray can be specified as any iterable container of @@ -492,7 +485,6 @@ def _init_Vrepresentation_from_polymake(self): An inequality (-5, 12) x + 10 >= 0} sage: set(p.Vrepresentation()) # optional - jupymake {A vertex at (0, 1/2), A vertex at (2, 0), A vertex at (4, 5/6)} - """ self._Vrepresentation = [] parent = self.parent() @@ -527,7 +519,6 @@ def _init_Hrepresentation_from_polymake(self): An inequality (-5, 12) x + 10 >= 0} sage: set(p.Vrepresentation()) # optional - jupymake {A vertex at (0, 1/2), A vertex at (2, 0), A vertex at (4, 5/6)} - """ p = self._polymake_polytope if not p.FEASIBLE: @@ -548,7 +539,7 @@ def _init_Hrepresentation_from_polymake(self): @classmethod def _from_polymake_polytope(cls, parent, polymake_polytope): r""" - Initializes a polyhedron from a polymake Polytope object. + Initialize a polyhedron from a polymake Polytope object. TESTS:: @@ -726,21 +717,23 @@ def _test_polymake_pickling(self, tester=None, other=None, **options): P = self._polymake_polytope P1 = other._polymake_polytope - tester.assertEqual(P.F_VECTOR, P1.F_VECTOR) - tester.assertEqual(P.VERTICES, P1.VERTICES) + tester.assertEqual(P.F_VECTOR, P1.F_VECTOR) + tester.assertEqual(P.VERTICES, P1.VERTICES) tester.assertEqual(P.LINEALITY_SPACE, P1.LINEALITY_SPACE) - tester.assertEqual(P.FACETS, P1.FACETS) - tester.assertEqual(P.AFFINE_HULL, P1.AFFINE_HULL) + tester.assertEqual(P.FACETS, P1.FACETS) + tester.assertEqual(P.AFFINE_HULL, P1.AFFINE_HULL) ######################################################################### + + class Polyhedron_QQ_polymake(Polyhedron_polymake, Polyhedron_QQ): r""" Polyhedra over `\QQ` with polymake. INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None`` + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: @@ -759,8 +752,8 @@ class Polyhedron_ZZ_polymake(Polyhedron_polymake, Polyhedron_ZZ): INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None`` + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/backend_ppl.py b/src/sage/geometry/polyhedron/backend_ppl.py index bb1a77e9f5d..c930039886b 100644 --- a/src/sage/geometry/polyhedron/backend_ppl.py +++ b/src/sage/geometry/polyhedron/backend_ppl.py @@ -16,19 +16,19 @@ from sage.features import PythonModule lazy_import('ppl', ['C_Polyhedron', 'Generator_System', 'Constraint_System', 'Linear_Expression', 'line', 'ray', 'point'], - feature=PythonModule("ppl", spkg="pplpy", type="standard")) + feature=PythonModule("ppl", spkg='pplpy', type='standard')) ######################################################################### class Polyhedron_ppl(Polyhedron_mutable): """ - Polyhedra with ppl + Polyhedra with ppl. INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: @@ -41,7 +41,7 @@ class Polyhedron_ppl(Polyhedron_mutable): def __init__(self, parent, Vrep, Hrep, ppl_polyhedron=None, mutable=False, **kwds): """ - Initializes the polyhedron. + Initialize the polyhedron. See :class:`Polyhedron_ppl` for a description of the input data. @@ -76,8 +76,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbo INPUT: - ``vertices`` -- list of point. Each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - ``rays`` -- list of rays. Each ray can be specified as any iterable container of @@ -87,8 +87,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbo any iterable container of :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes EXAMPLES:: @@ -117,8 +117,8 @@ def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True, verbose=False): as any iterable container of :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - ``verbose`` -- boolean (default: ``False``). Whether to print - verbose output for debugging purposes. + - ``verbose`` -- boolean (default: ``False``); whether to print + verbose output for debugging purposes EXAMPLES:: @@ -391,7 +391,7 @@ def Hrepresentation(self, index=None): def _init_empty_polyhedron(self): """ - Initializes an empty polyhedron. + Initialize an empty polyhedron. TESTS:: @@ -415,9 +415,10 @@ def _convert_generator_to_ppl(v, typ): INPUT: - - ``v`` -- a vertex, ray, or line. + - ``v`` -- a vertex, ray, or line - - ``typ`` -- integer according to `:sage:`~sage.geometry.polyhedron.representation.LINE` etc. + - ``typ`` -- integer according to + `:sage:`~sage.geometry.polyhedron.representation.LINE` etc. EXAMPLES:: @@ -488,9 +489,10 @@ def _convert_constraint_to_ppl(c, typ): INPUT: - - ``c`` -- an inequality or equation. + - ``c`` -- an inequality or equation - - ``typ`` -- integer according to `:sage:`~sage.geometry.polyhedron.representation.INEQUALITY` etc. + - ``typ`` -- integer according to + `:sage:`~sage.geometry.polyhedron.representation.INEQUALITY` etc. EXAMPLES:: @@ -542,13 +544,13 @@ def _convert_constraints_to_ppl(ieqs, eqns): ######################################################################### class Polyhedron_QQ_ppl(Polyhedron_ppl, Polyhedron_QQ): r""" - Polyhedra over `\QQ` with ppl + Polyhedra over `\QQ` with ppl. INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: @@ -562,13 +564,13 @@ class Polyhedron_QQ_ppl(Polyhedron_ppl, Polyhedron_QQ): ######################################################################### class Polyhedron_ZZ_ppl(Polyhedron_ppl, Polyhedron_ZZ): r""" - Polyhedra over `\ZZ` with ppl + Polyhedra over `\ZZ` with ppl. INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 67ac7d9ec9e..7110f74a202 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -64,11 +64,9 @@ def is_Polyhedron(X): INPUT: - - ``X`` -- anything. + - ``X`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -90,24 +88,24 @@ def is_Polyhedron(X): ######################################################################### class Polyhedron_base(Polyhedron_base7): """ - Base class for Polyhedron objects + Base class for Polyhedron objects. INPUT: - ``parent`` -- the parent, an instance of - :class:`~sage.geometry.polyhedron.parent.Polyhedra`. + :class:`~sage.geometry.polyhedron.parent.Polyhedra` - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. The - V-representation of the polyhedron. If ``None``, the polyhedron - is determined by the H-representation. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None``. The + V-representation of the polyhedron; if ``None``, the polyhedron + is determined by the H-representation - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. The - H-representation of the polyhedron. If ``None``, the polyhedron - is determined by the V-representation. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None``. The + H-representation of the polyhedron; if ``None``, the polyhedron + is determined by the V-representation - - ``Vrep_minimal`` (optional) -- see below + - ``Vrep_minimal`` -- (optional) see below - - ``Hrep_minimal`` (optional) -- see below + - ``Hrep_minimal`` -- (optional) see below - ``pref_rep`` -- string (default: ``None``); one of ``Vrep`` or ``Hrep`` to pick this in case the backend @@ -199,7 +197,7 @@ def to_linear_program(self, solver=None, return_variable=False, base_ring=None): - ``solver`` -- select a solver (MIP backend). See the documentation of for :class:`MixedIntegerLinearProgram`. Set to ``None`` by default. - - ``return_variable`` -- (default: ``False``) If ``True``, return a tuple + - ``return_variable`` -- boolean (default: ``False``); if ``True``, return a tuple ``(p, x)``, where ``p`` is the :class:`MixedIntegerLinearProgram` object and ``x`` is the vector-valued MIP variable in this problem, indexed from 0. If ``False``, only return ``p``. @@ -382,7 +380,7 @@ def center(self): OUTPUT: The center of the polyhedron. All rays and lines are - ignored. Raises a ``ZeroDivisionError`` for the empty + ignored. Raises a :exc:`ZeroDivisionError` for the empty polytope. EXAMPLES:: @@ -459,12 +457,10 @@ def is_inscribed(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) boolean; specifies whether to - return the circumcenter, if found. - - OUTPUT: + - ``certificate`` -- boolean (default: ``False``); specifies whether to + return the circumcenter, if found - If ``certificate`` is true, returns a tuple containing: + OUTPUT: if ``certificate`` is true, returns a tuple containing: 1. Boolean. 2. The circumcenter of the polytope or None. @@ -588,7 +584,7 @@ def is_inscribed(self, certificate=False): for vertex in affine_basis: vertex_vector = vertex.vector() raw_data += [[sum(i**2 for i in vertex_vector)] + - [i for i in vertex_vector] + [1]] + list(vertex_vector) + [1]] matrix_data = matrix(raw_data) # The determinant "a" should not be zero because @@ -798,10 +794,8 @@ def is_minkowski_summand(self, Y): See :meth:`~sage.geometry.polyhedron.base5.Polyhedron_base5.minkowski_sum`. - OUTPUT: - - Boolean. Whether there exists another polyhedron `Z` such that - ``self`` can be written as `Y\oplus Z`. + OUTPUT: boolean; whether there exists another polyhedron `Z` such that + ``self`` can be written as `Y\oplus Z` EXAMPLES:: @@ -849,9 +843,7 @@ def barycentric_subdivision(self, subdivision_frac=None): the value should be smaller than `\frac{1}{2}`. The subdivision is computed on the polar polyhedron. - OUTPUT: - - A Polyhedron object, subdivided as described above. + OUTPUT: a Polyhedron object, subdivided as described above EXAMPLES:: @@ -958,13 +950,13 @@ def permutations_to_matrices(self, conj_class_reps, acting_group=None, additiona INPUT: - - ``conj_class_reps`` -- list. A list of representatives of the - conjugacy classes of the ``acting_group``. + - ``conj_class_reps`` -- list; a list of representatives of the + conjugacy classes of the ``acting_group`` - ``acting_group`` -- a subgroup of polytope's - :meth:`~sage.geometry.polyhedron.base4.Polyhedron_base4.restricted_automorphism_group`. + :meth:`~sage.geometry.polyhedron.base4.Polyhedron_base4.restricted_automorphism_group` - - ``additional_elts`` -- list (default=None). A subset of the + - ``additional_elts`` -- list (default: ``None``); a subset of the :meth:`~sage.geometry.polyhedron.base4.Polyhedron_base4.restricted_automorphism_group` of the polytope expressed as permutations. @@ -1052,12 +1044,12 @@ def bounding_box(self, integral=False, integral_hull=False): INPUT: - - ``integral`` -- Boolean (default: ``False``). Whether to - only allow integral coordinates in the bounding box. + - ``integral`` -- boolean (default: ``False``); whether to + only allow integral coordinates in the bounding box - - ``integral_hull`` -- Boolean (default: ``False``). If ``True``, return a + - ``integral_hull`` -- boolean (default: ``False``); if ``True``, return a box containing the integral points of the polytope, or ``None, None`` if it - is known that the polytope has no integral points. + is known that the polytope has no integral points OUTPUT: @@ -1192,7 +1184,6 @@ def _polymake_init_(self): Polytope[...] sage: sorted(PP.VERTICES[:], key=repr)[0] 1 -0.472135955 0 -1.236067978 - """ from sage.interfaces.polymake import polymake polymake_field = polymake(self.base_ring().fraction_field()) diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py index b2e2ece5467..c710c5dfa62 100644 --- a/src/sage/geometry/polyhedron/base0.py +++ b/src/sage/geometry/polyhedron/base0.py @@ -35,6 +35,7 @@ from sage.structure.element import Element import sage.geometry.abc + class Polyhedron_base0(Element, sage.geometry.abc.Polyhedron): """ Initialization and basic access for polyhedra. @@ -72,7 +73,7 @@ class Polyhedron_base0(Element, sage.geometry.abc.Polyhedron): """ def __init__(self, parent, Vrep, Hrep, Vrep_minimal=None, Hrep_minimal=None, pref_rep=None, mutable=False, **kwds): """ - Initializes the polyhedron. + Initialize the polyhedron. See :class:`sage.geometry.polyhedron.base.Polyhedron_base` for a description of the input data. @@ -188,8 +189,8 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds): INPUT: - ``vertices`` -- list of point. Each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - ``rays`` -- list of rays. Each ray can be specified as any iterable container of @@ -236,7 +237,7 @@ def _init_from_Hrepresentation(self, ieqs, eqns, **kwds): def _init_empty_polyhedron(self): """ - Initializes an empty polyhedron. + Initialize an empty polyhedron. TESTS:: @@ -339,14 +340,12 @@ def base_extend(self, base_ring, backend=None): - ``base_ring`` -- the new base ring - ``backend`` -- the new backend, see - :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. + :func:`~sage.geometry.polyhedron.constructor.Polyhedron` If ``None`` (the default), attempt to keep the same backend. Otherwise, use the same defaulting behavior as described there. - OUTPUT: - - The same polyhedron, but over a larger base ring and possibly with a changed backend. + OUTPUT: the same polyhedron, but over a larger base ring and possibly with a changed backend EXAMPLES:: @@ -364,7 +363,6 @@ def base_extend(self, base_ring, backend=None): sage: Q = P.base_extend(ZZ, backend='field') sage: Q.backend() 'field' - """ new_parent = self.parent().base_extend(base_ring, backend) return new_parent(self, copy=True) @@ -450,7 +448,7 @@ def change_ring(self, base_ring, backend=None): def is_mutable(self): r""" - Return True if the polyhedron is mutable, i.e. it can be modified in place. + Return ``True`` if the polyhedron is mutable, i.e. it can be modified in place. EXAMPLES:: @@ -462,7 +460,7 @@ def is_mutable(self): def is_immutable(self): r""" - Return True if the polyhedron is immutable, i.e. it cannot be modified in place. + Return ``True`` if the polyhedron is immutable, i.e. it cannot be modified in place. EXAMPLES:: @@ -623,14 +621,14 @@ def Hrepresentation_str(self, separator='\n', latex=False, style='>=', align=Non INPUT: - - ``separator`` -- a string. Default is ``"\n"``. + - ``separator`` -- string (default: ``'\n'``) - - ``latex`` -- a boolean. Default is ``False``. + - ``latex`` -- boolean (default: ``False``) - - ``style`` -- either ``"positive"`` (making all coefficients positive) - or ``"<="``, or ``">="``. Default is ``">="``. + - ``style`` -- either ``'positive'`` (making all coefficients positive) + or ``'<='``, or ``'>='``; default is ``'>='`` - - ``align`` -- a boolean or ``None''. Default is ``None`` in which case + - ``align`` -- boolean or ``None''; default is ``None`` in which case ``align`` is ``True`` if ``separator`` is the newline character. If set, then the lines of the output string are aligned by the comparison symbol by padding blanks. @@ -639,13 +637,11 @@ def Hrepresentation_str(self, separator='\n', latex=False, style='>=', align=Non :meth:`~sage.geometry.polyhedron.representation.Hrepresentation.repr_pretty` are passed on: - - ``prefix`` -- a string + - ``prefix`` -- string - - ``indices`` -- a tuple or other iterable + - ``indices`` -- tuple or other iterable - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -761,9 +757,7 @@ def n_Hrepresentation(self): Return the number of objects that make up the H-representation of the polyhedron. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -814,9 +808,7 @@ def n_Vrepresentation(self): Return the number of objects that make up the V-representation of the polyhedron. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -849,9 +841,7 @@ def inequality_generator(self): Return a generator for the defining inequalities of the polyhedron. - OUTPUT: - - A generator of the inequality Hrepresentation objects. + OUTPUT: a generator of the inequality Hrepresentation objects EXAMPLES:: @@ -876,9 +866,7 @@ def inequalities(self): """ Return all inequalities. - OUTPUT: - - A tuple of inequalities. + OUTPUT: a tuple of inequalities EXAMPLES:: @@ -947,9 +935,7 @@ def equations(self): """ Return all linear constraints of the polyhedron. - OUTPUT: - - A tuple of equations. + OUTPUT: a tuple of equations EXAMPLES:: @@ -1065,9 +1051,7 @@ def vertices(self): """ Return all vertices of the polyhedron. - OUTPUT: - - A tuple of vertices. + OUTPUT: a tuple of vertices .. WARNING:: @@ -1102,14 +1086,14 @@ def vertices_matrix(self, base_ring=None): INPUT: - - ``base_ring`` -- A ring or ``None`` (default). The base ring + - ``base_ring`` -- a ring or ``None`` (default); the base ring of the returned matrix. If not specified, the base ring of the polyhedron is used. OUTPUT: A matrix over ``base_ring`` whose columns are the coordinates - of the vertices. A ``TypeError`` is raised if the coordinates + of the vertices. A :exc:`TypeError` is raised if the coordinates cannot be converted to ``base_ring``. .. WARNING:: @@ -1178,9 +1162,7 @@ def rays(self): """ Return a list of rays of the polyhedron. - OUTPUT: - - A tuple of rays. + OUTPUT: a tuple of rays EXAMPLES:: @@ -1202,9 +1184,7 @@ def rays_list(self): :meth:`ray_generator` instead to iterate over the list of :class:`~sage.geometry.polyhedron.representation.Ray` objects. - OUTPUT: - - A list of rays as lists of coordinates. + OUTPUT: list of rays as lists of coordinates EXAMPLES:: @@ -1235,9 +1215,7 @@ def lines(self): """ Return all lines of the polyhedron. - OUTPUT: - - A tuple of lines. + OUTPUT: a tuple of lines EXAMPLES:: @@ -1336,7 +1314,7 @@ def cdd_Hrepresentation(self): :meth:`write_cdd_Hrepresentation` -- export the polyhedron as a H-representation to a file. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -1382,7 +1360,7 @@ def write_cdd_Hrepresentation(self, filename): INPUT: - - ``filename`` -- the output file. + - ``filename`` -- the output file .. SEEALSO:: @@ -1408,7 +1386,7 @@ def cdd_Vrepresentation(self): :meth:`write_cdd_Vrepresentation` -- export the polyhedron as a V-representation to a file. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -1446,7 +1424,7 @@ def write_cdd_Vrepresentation(self, filename): INPUT: - - ``filename`` -- the output file. + - ``filename`` -- the output file .. SEEALSO:: diff --git a/src/sage/geometry/polyhedron/base1.py b/src/sage/geometry/polyhedron/base1.py index 507316f26a3..40a94c1b2d7 100644 --- a/src/sage/geometry/polyhedron/base1.py +++ b/src/sage/geometry/polyhedron/base1.py @@ -243,9 +243,7 @@ def _is_subpolyhedron(self, other): - ``other`` -- a :class:`Polyhedron` - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -262,11 +260,9 @@ def _is_subpolyhedron(self, other): def is_empty(self): """ - Test whether the polyhedron is the empty polyhedron - - OUTPUT: + Test whether the polyhedron is the empty polyhedron. - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -289,11 +285,9 @@ def is_empty(self): def is_universe(self): """ - Test whether the polyhedron is the whole ambient space - - OUTPUT: + Test whether the polyhedron is the whole ambient space. - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -318,9 +312,7 @@ def dim(self): """ Return the dimension of the polyhedron. - OUTPUT: - - -1 if the polyhedron is empty, otherwise a non-negative integer. + OUTPUT: -1 if the polyhedron is empty, otherwise a nonnegative integer EXAMPLES:: @@ -351,9 +343,7 @@ def Vrepresentation_space(self): r""" Return the ambient free module. - OUTPUT: - - A free module over the base ring of dimension :meth:`ambient_dim`. + OUTPUT: a free module over the base ring of dimension :meth:`ambient_dim` EXAMPLES:: @@ -369,9 +359,7 @@ def Hrepresentation_space(self): r""" Return the linear space containing the H-representation vectors. - OUTPUT: - - A free module over the base ring of dimension :meth:`ambient_dim` + 1. + OUTPUT: a free module over the base ring of dimension :meth:`ambient_dim` + 1 EXAMPLES:: @@ -392,7 +380,7 @@ def ambient_vector_space(self, base_field=None): INPUT: - - ``base_field`` -- (default: the fraction field of the base ring) a field. + - ``base_field`` -- a field (default: the fraction field of the base ring) EXAMPLES:: @@ -599,9 +587,7 @@ def contains(self, point): - ``point`` -- coordinates of a point (an iterable) - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -731,9 +717,7 @@ def interior_contains(self, point): - ``point`` -- coordinates of a point - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -783,9 +767,7 @@ def is_relatively_open(self): r""" Return whether ``self`` is relatively open. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -808,7 +790,6 @@ def is_relatively_open(self): A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line sage: Line.is_relatively_open() True - """ return not self.inequalities() @@ -857,9 +838,7 @@ def relative_interior_contains(self, point): - ``point`` -- coordinates of a point - OUTPUT: - - ``True`` or ``False`` + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/base2.py b/src/sage/geometry/polyhedron/base2.py index 3b72b5088c7..f2626b6efa3 100644 --- a/src/sage/geometry/polyhedron/base2.py +++ b/src/sage/geometry/polyhedron/base2.py @@ -37,6 +37,7 @@ from sage.modules.free_module_element import vector from .base1 import Polyhedron_base1 + class Polyhedron_base2(Polyhedron_base1): """ Methods related to lattice points. @@ -111,10 +112,10 @@ def lattice_polytope(self, envelope=False): INPUT: - - ``envelope`` -- boolean (default: ``False``). If the + - ``envelope`` -- boolean (default: ``False``); if the polyhedron has non-integral vertices, this option decides whether to return a strictly larger lattice polytope or - raise a ``ValueError``. This option has no effect if the + raise a :exc:`ValueError`. This option has no effect if the polyhedron has already integral vertices. OUTPUT: @@ -126,11 +127,11 @@ def lattice_polytope(self, envelope=False): but has at least one non-integral vertex, a strictly larger lattice polytope is returned. - If the polyhedron is not compact, a ``NotImplementedError`` is + If the polyhedron is not compact, a :exc:`NotImplementedError` is raised. If the polyhedron is not integral and ``envelope=False``, a - ``ValueError`` is raised. + :exc:`ValueError` is raised. ALGORITHM: @@ -204,7 +205,7 @@ def _integral_points_PALP(self): OUTPUT: The list of integral points in the polyhedron. If the - polyhedron is not compact, a ``ValueError`` is raised. + polyhedron is not compact, a :exc:`ValueError` is raised. EXAMPLES:: @@ -245,13 +246,13 @@ def h_star_vector(self): INPUT: - - ``self`` -- A lattice polytope. + - ``self`` -- a lattice polytope OUTPUT: A list whose entries give the `h^*`-vector. - .. NOTE: + .. NOTE:: The backend of ``self`` should be ``'normaliz'``. This function depends on Normaliz (i.e. the ``'pynormaliz'`` optional @@ -321,15 +322,15 @@ def _h_star_vector_normaliz(self): INPUT: - - ``self`` -- A lattice polytope. + - ``self`` -- a lattice polytope OUTPUT: The `h^*`-vector as a list. - .. NOTE: + .. NOTE:: - The backend of ``self`` should be ``'normaliz'``. + The backend of ``self`` should be ``'normaliz'``. TESTS:: @@ -379,7 +380,6 @@ def integral_points_count(self, **kwds): Traceback (most recent call last): ... NotImplementedError: ... - """ return len(self.integral_points()) @@ -392,13 +392,13 @@ def integral_points(self, threshold=100000): INPUT: - - ``threshold`` -- integer (default: 100000). Use the naive - algorithm as long as the bounding box is smaller than this. + - ``threshold`` -- integer (default: 100000); use the naive + algorithm as long as the bounding box is smaller than this OUTPUT: The list of integral points in the polyhedron. If the - polyhedron is not compact, a ``ValueError`` is raised. + polyhedron is not compact, a :exc:`ValueError` is raised. EXAMPLES:: @@ -532,21 +532,21 @@ def get_integral_point(self, index, **kwds): However, so long as :meth:`integral_points_count` does not need to enumerate all integral points, neither does this method. Hence it can be significantly faster. If the polyhedron is not compact, a - ``ValueError`` is raised. + :exc:`ValueError` is raised. INPUT: - - ``index`` -- integer. The index of the integral point to be found. If - this is not in [0, ``self.integral_point_count()``), an ``IndexError`` + - ``index`` -- integer; the index of the integral point to be found. If + this is not in [0, ``self.integral_point_count()``), an :exc:`IndexError` is raised. - ``**kwds`` -- optional keyword parameters that are passed to - :meth:`integral_points_count`. + :meth:`integral_points_count` ALGORITHM: The function computes each of the components of the requested point in - turn. To compute x_i, the ith component, it bisects the upper and lower + turn. To compute x_i, the `i`-th component, it bisects the upper and lower bounds on x_i given by the bounding box. At each bisection, it uses :meth:`integral_points_count` to determine on which side of the bisecting hyperplane the requested point lies. @@ -627,12 +627,12 @@ def random_integral_point(self, **kwds): INPUT: - ``**kwds`` -- optional keyword parameters that are passed to - :meth:`get_integral_point`. + :meth:`get_integral_point` OUTPUT: The integral point in the polyhedron chosen uniformly at random. If the - polyhedron is not compact, a ``ValueError`` is raised. If the + polyhedron is not compact, a :exc:`ValueError` is raised. If the polyhedron does not contain any integral points, an :class:`~sage.categories.sets_cat.EmptySetError` is raised. @@ -701,7 +701,7 @@ def generating_function_of_integral_points(self, **kwds): The following keyword arguments are passed to :func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`: - - ``split`` -- (default: ``False``) a boolean or list + - ``split`` -- boolean (default: ``False``) or list - ``split=False`` computes the generating function directly, without any splitting. @@ -732,7 +732,7 @@ def generating_function_of_integral_points(self, **kwds): The variable names of the Laurent polynomial ring of the output are this string followed by an integer. - - ``names`` -- a list or tuple of names (strings), or a comma separated string + - ``names`` -- list or tuple of names (strings), or a comma separated string ``name`` is extracted from ``names``, therefore ``names`` has to contain exactly one variable name, and ``name`` and``names`` cannot be specified @@ -745,12 +745,12 @@ def generating_function_of_integral_points(self, **kwds): :class:`sage.structure.factorization.Factorization` when creating the result. - - ``sort_factors`` -- (default: ``False``) a boolean + - ``sort_factors`` -- boolean (default: ``False``) - If set, then - the factors of the output are sorted such that the numerator is - first and only then all factors of the denominator. It is ensured - that the sorting is always the same; use this for doctesting. + If set, then the factors of the output are sorted such that the + numerator is first and only then all factors of the denominator. It + is ensured that the sorting is always the same; use this for + doctesting. OUTPUT: diff --git a/src/sage/geometry/polyhedron/base3.py b/src/sage/geometry/polyhedron/base3.py index 3b57c4f2055..b0a4284a743 100644 --- a/src/sage/geometry/polyhedron/base3.py +++ b/src/sage/geometry/polyhedron/base3.py @@ -38,6 +38,7 @@ from sage.rings.rational_field import QQ from .base2 import Polyhedron_base2 + class Polyhedron_base3(Polyhedron_base2): """ Methods related to the combinatorics of a polyhedron. @@ -73,7 +74,7 @@ class Polyhedron_base3(Polyhedron_base2): def _init_empty_polyhedron(self): """ - Initializes an empty polyhedron. + Initialize an empty polyhedron. TESTS:: @@ -380,7 +381,7 @@ def face_generator(self, face_dimension=None, algorithm=None): INPUT: - - ``face_dimension`` -- integer (default ``None``), + - ``face_dimension`` -- integer (default: ``None``); yield only faces of this dimension if specified - ``algorithm`` -- string (optional); @@ -610,12 +611,12 @@ def face_generator(self, face_dimension=None, algorithm=None): def faces(self, face_dimension): """ - Return the faces of given dimension + Return the faces of given dimension. INPUT: - - ``face_dimension`` -- integer. The dimension of the faces - whose representation will be returned. + - ``face_dimension`` -- integer; the dimension of the faces + whose representation will be returned OUTPUT: @@ -838,9 +839,7 @@ def bounded_edges(self): """ Return the bounded edges (excluding rays and lines). - OUTPUT: - - A generator for pairs of vertices, one pair per edge. + OUTPUT: a generator for pairs of vertices, one pair per edge EXAMPLES:: @@ -1206,7 +1205,7 @@ def simpliciality(self): def is_simplicial(self): """ - Tests if the polytope is simplicial + Test if the polytope is simplicial. A polytope is simplicial if every facet is a simplex. @@ -1253,9 +1252,7 @@ def is_pyramid(self, certificate=False): to return a vertex of the polytope which is the apex of a pyramid, if found - OUTPUT: - - If ``certificate`` is ``True``, returns a tuple containing: + OUTPUT: if ``certificate`` is ``True``, returns a tuple containing: 1. Boolean. 2. The apex of the pyramid or ``None``. @@ -1303,9 +1300,7 @@ def is_bipyramid(self, certificate=False): to return two vertices of the polytope which are the apices of a bipyramid, if found - OUTPUT: - - If ``certificate`` is ``True``, returns a tuple containing: + OUTPUT: if ``certificate`` is ``True``, returns a tuple containing: 1. Boolean. 2. ``None`` or a tuple containing: @@ -1360,9 +1355,7 @@ def is_prism(self, certificate=False): to return two facets of the polytope which are the bases of a prism, if found - OUTPUT: - - If ``certificate`` is ``True``, returns a tuple containing: + OUTPUT: if ``certificate`` is ``True``, returns a tuple containing: 1. Boolean. 2. ``None`` or a tuple containing: @@ -1500,7 +1493,6 @@ def neighborliness(self): 3 sage: [polytopes.cyclic_polytope(5,n).neighborliness() for n in range(6,10)] [6, 2, 2, 2] - """ return self.combinatorial_polyhedron().neighborliness() @@ -1550,7 +1542,6 @@ def is_neighborly(self, k=None): sage: testpolys = [polytopes.cube(), polytopes.cyclic_polytope(6, 9), polytopes.simplex(6)] sage: [(P.neighborliness() >= P.dim() // 2) == P.is_neighborly() for P in testpolys] [True, True, True] - """ return self.combinatorial_polyhedron().is_neighborly() diff --git a/src/sage/geometry/polyhedron/base4.py b/src/sage/geometry/polyhedron/base4.py index 3f8fe215749..ea0423c60fe 100644 --- a/src/sage/geometry/polyhedron/base4.py +++ b/src/sage/geometry/polyhedron/base4.py @@ -36,6 +36,7 @@ from sage.misc.cachefunc import cached_method from .base3 import Polyhedron_base3 + class Polyhedron_base4(Polyhedron_base3): """ Methods relying on :mod:`sage.graphs`. @@ -218,8 +219,8 @@ def vertex_digraph(self, f, increasing=True): - a vector ; in this case the linear form is obtained by duality using the dot product: ``f(v) = v.dot_product(f)``. - - ``increasing`` -- boolean (default ``True``) whether to orient - edges in the increasing or decreasing direction. + - ``increasing`` -- boolean (default: ``True``); whether to orient + edges in the increasing or decreasing direction By default, an edge is oriented from `v` to `w` if `f(v) \leq f(w)`. @@ -383,7 +384,6 @@ def face_lattice(self): [[()], [(0, 1)]] sage: [[ls.ambient_V_indices() for ls in lss] for lss in Polyhedron(lines=[(1,0)], vertices=[(0,0)]).face_lattice().level_sets()] [[()], [(0, 1)]] - """ from sage.combinat.posets.lattices import FiniteLatticePoset return FiniteLatticePoset(self.hasse_diagram()) @@ -471,12 +471,10 @@ def flag_f_vector(self, *args): INPUT: - - ``args`` -- integers (optional); specify an entry of the + - ``args`` -- integer (optional); specify an entry of the flag-f-vector; must be an increasing sequence of integers - OUTPUT: - - - a dictionary, if no arguments were given + OUTPUT: a dictionary, if no arguments were given - an Integer, if arguments were given @@ -603,7 +601,7 @@ def _flag_f_vector(self): @cached_method def combinatorial_automorphism_group(self, vertex_graph_only=False): """ - Computes the combinatorial automorphism group. + Compute the combinatorial automorphism group. If ``vertex_graph_only`` is ``True``, the automorphism group of the vertex-edge graph of the polyhedron is returned. Otherwise @@ -688,7 +686,6 @@ def combinatorial_automorphism_group(self, vertex_graph_only=False): sage: QG = Q.hasse_diagram().automorphism_group() sage: Q.combinatorial_automorphism_group().is_isomorphic(QG) True - """ if vertex_graph_only: G = self.graph() @@ -697,7 +694,7 @@ def combinatorial_automorphism_group(self, vertex_graph_only=False): return G.automorphism_group(edge_labels=True) @cached_method - def restricted_automorphism_group(self, output="abstract"): + def restricted_automorphism_group(self, output='abstract'): r""" Return the restricted automorphism group. @@ -764,22 +761,22 @@ def restricted_automorphism_group(self, output="abstract"): - ``output`` -- how the group should be represented: - - ``"abstract"`` (default) -- return an abstract permutation - group without further meaning. + - ``'abstract'`` -- default; return an abstract permutation + group without further meaning - - ``"permutation"`` -- return a permutation group on the + - ``'permutation'`` -- return a permutation group on the indices of the polyhedron generators. For example, the permutation ``(0,1)`` would correspond to swapping ``self.Vrepresentation(0)`` and ``self.Vrepresentation(1)``. - - ``"matrix"`` -- return a matrix group representing affine + - ``'matrix'`` -- return a matrix group representing affine transformations. When acting on affine vectors, you should append a `1` to every vector. If the polyhedron is not full dimensional, the returned matrices act as the identity on the orthogonal complement of the affine space spanned by the polyhedron. - - ``"matrixlist"`` -- like ``matrix``, but return the list of + - ``'matrixlist'`` -- like ``matrix``, but return the list of elements of the matrix group. Useful for fields without a good implementation of matrix groups or to avoid the overhead of creating the group. @@ -805,14 +802,14 @@ def restricted_automorphism_group(self, output="abstract"): sage: P = polytopes.cross_polytope(3) sage: P.restricted_automorphism_group() == PermutationGroup([[(3,4)], [(2,3),(4,5)],[(2,5)],[(1,2),(5,6)],[(1,6)]]) True - sage: P.restricted_automorphism_group(output="permutation") == PermutationGroup([[(2,3)],[(1,2),(3,4)],[(1,4)],[(0,1),(4,5)],[(0,5)]]) + sage: P.restricted_automorphism_group(output='permutation') == PermutationGroup([[(2,3)],[(1,2),(3,4)],[(1,4)],[(0,1),(4,5)],[(0,5)]]) True sage: mgens = [[[1,0,0,0],[0,1,0,0],[0,0,-1,0],[0,0,0,1]], [[1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0],[0,0,0,1]]] We test groups for equality in a fool-proof way; they can have different generators, etc:: sage: # needs sage.groups - sage: poly_g = P.restricted_automorphism_group(output="matrix") + sage: poly_g = P.restricted_automorphism_group(output='matrix') sage: matrix_g = MatrixGroup([matrix(QQ,t) for t in mgens]) sage: all(t.matrix() in poly_g for t in matrix_g.gens()) True @@ -838,7 +835,7 @@ def restricted_automorphism_group(self, output="abstract"): sage: P = Polyhedron(rays=[(1,0),(0,1)]) sage: P.Vrepresentation() (A vertex at (0, 0), A ray in the direction (0, 1), A ray in the direction (1, 0)) - sage: P.restricted_automorphism_group(output="permutation") + sage: P.restricted_automorphism_group(output='permutation') Permutation Group with generators [(1,2)] Also, the polyhedron need not be full-dimensional:: @@ -847,7 +844,7 @@ def restricted_automorphism_group(self, output="abstract"): sage: P = Polyhedron(vertices=[(1,2,3,4,5),(7,8,9,10,11)]) sage: P.restricted_automorphism_group() Permutation Group with generators [(1,2)] - sage: G = P.restricted_automorphism_group(output="matrixlist"); G + sage: G = P.restricted_automorphism_group(output='matrixlist'); G ( [1 0 0 0 0 0] [ -87/55 -82/55 -2/5 38/55 98/55 12/11] [0 1 0 0 0 0] [-142/55 -27/55 -2/5 38/55 98/55 12/11] @@ -901,7 +898,7 @@ def restricted_automorphism_group(self, output="abstract"): A 3-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^3 defined as the convex hull of 20 vertices - sage: G = P.restricted_automorphism_group(output="matrixlist") + sage: G = P.restricted_automorphism_group(output='matrixlist') sage: len(G) 120 @@ -912,21 +909,21 @@ def restricted_automorphism_group(self, output="abstract"): ....: base_ring=RDF) sage: P.restricted_automorphism_group() # needs sage.groups Permutation Group with generators [(2,3), (1,2)] - sage: len(P.restricted_automorphism_group(output="matrixlist")) + sage: len(P.restricted_automorphism_group(output='matrixlist')) 6 TESTS:: sage: P = Polyhedron(vertices=[(1,0), (1,1)], rays=[(1,0)]) - sage: P.restricted_automorphism_group(output="permutation") # needs sage.groups + sage: P.restricted_automorphism_group(output='permutation') # needs sage.groups Permutation Group with generators [(1,2)] - sage: P.restricted_automorphism_group(output="matrix") + sage: P.restricted_automorphism_group(output='matrix') Matrix group over Rational Field with 1 generators ( [ 1 0 0] [ 0 -1 1] [ 0 0 1] ) - sage: P.restricted_automorphism_group(output="foobar") + sage: P.restricted_automorphism_group(output='foobar') Traceback (most recent call last): ... ValueError: unknown output 'foobar', valid values are @@ -934,7 +931,7 @@ def restricted_automorphism_group(self, output="abstract"): Check that :issue:`28828` is fixed:: - sage: P.restricted_automorphism_group(output="matrixlist")[0].is_immutable() + sage: P.restricted_automorphism_group(output='matrixlist')[0].is_immutable() True """ # The algorithm works as follows: @@ -1072,8 +1069,8 @@ def is_combinatorially_isomorphic(self, other, algorithm='bipartite_graph'): INPUT: - ``other`` -- a polyhedron object - - ``algorithm`` (default = ``'bipartite_graph'``) -- the algorithm to use. - The other possible value is ``'face_lattice'``. + - ``algorithm`` -- (default: ``'bipartite_graph'``) the algorithm to + use; the other possible value is ``'face_lattice'`` OUTPUT: @@ -1173,7 +1170,6 @@ def is_combinatorially_isomorphic(self, other, algorithm='bipartite_graph'): Traceback (most recent call last): ... AssertionError: polyhedron `other` must be bounded - """ assert isinstance(other, Polyhedron_base4), "input `other` must be a polyhedron" assert self.is_compact(), "polyhedron `self` must be bounded" @@ -1250,7 +1246,6 @@ def is_self_dual(self): Traceback (most recent call last): ... ValueError: polyhedron has to be compact - """ if not self.is_compact(): raise ValueError("polyhedron has to be compact") diff --git a/src/sage/geometry/polyhedron/base5.py b/src/sage/geometry/polyhedron/base5.py index 2ac8b75cdd8..c94efd9428c 100644 --- a/src/sage/geometry/polyhedron/base5.py +++ b/src/sage/geometry/polyhedron/base5.py @@ -42,6 +42,7 @@ from .base4 import Polyhedron_base4 + class Polyhedron_base5(Polyhedron_base4): """ Methods constructing new polyhedra @@ -579,12 +580,10 @@ def truncation(self, cut_frac=None): INPUT: - - ``cut_frac`` -- integer, how deeply to cut into the edge. - Default is `\frac{1}{3}`. + - ``cut_frac`` -- integer; how deeply to cut into the edge + Default is `\frac{1}{3}` - OUTPUT: - - A Polyhedron object, truncated as described above. + OUTPUT: a Polyhedron object, truncated as described above EXAMPLES:: @@ -684,9 +683,7 @@ def minkowski_sum(self, other): - ``other`` -- a :class:`~sage.geometry.polyhedron.base.Polyhedron_base` - OUTPUT: - - The Minkowski sum of ``self`` and ``other`` + OUTPUT: the Minkowski sum of ``self`` and ``other`` EXAMPLES:: @@ -846,7 +843,7 @@ def minkowski_difference(self, other): def __sub__(self, other): r""" - Implement minus binary operation + Implement minus binary operation. Polyhedra are not a ring with respect to dilatation and Minkowski sum, for example `X\oplus(-1)*Y \not= X\ominus Y`. @@ -991,9 +988,9 @@ def _test_product(self, tester=None, **options): if self.n_vertices() + self.n_rays() < 40 and self.n_facets() < 40: # Check that the product preserves the backend, where possible. - P = polytopes.simplex(backend="cdd") + P = polytopes.simplex(backend='cdd') tester.assertEqual((self*P).backend(), self.backend()) - Q = polytopes.simplex(backend="ppl") + Q = polytopes.simplex(backend='ppl') tester.assertEqual((self*Q).backend(), self.backend()) # And that it changes the backend correctly where necessary. @@ -1292,9 +1289,7 @@ def convex_hull(self, other): - ``other`` -- a :class:`Polyhedron` - OUTPUT: - - The convex hull. + OUTPUT: the convex hull EXAMPLES:: @@ -1320,9 +1315,7 @@ def intersection(self, other): - ``other`` -- a :class:`Polyhedron` - OUTPUT: - - The intersection. + OUTPUT: the intersection Note that the intersection of two `\ZZ`-polyhedra might not be a `\ZZ`-polyhedron. In this case, a `\QQ`-polyhedron is @@ -1460,9 +1453,7 @@ def translation(self, displacement): - ``displacement`` -- a displacement vector or a list/tuple of coordinates that determines a displacement vector - OUTPUT: - - The translated polyhedron. + OUTPUT: the translated polyhedron EXAMPLES:: @@ -1503,7 +1494,7 @@ def _translation_double_description(self, displacement): - ``displacement`` -- a displacement vector or a list/tuple of coordinates that determines a displacement vector - OUTPUT: Tuple of consisting of new Vrepresentation, Hrepresentation and parent. + OUTPUT: tuple of consisting of new Vrepresentation, Hrepresentation and parent .. SEEALSO:: @@ -1542,7 +1533,7 @@ def dilation(self, scalar): INPUT: - - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring` + - ``scalar`` -- a scalar, not necessarily in :meth:`base_ring` OUTPUT: @@ -1933,9 +1924,7 @@ def face_truncation(self, face, linear_coefficients=None, cut_frac=None): vertex (according to the normal vector of the cutting hyperplane). Default is `\frac{1}{3}`. - OUTPUT: - - A Polyhedron object, truncated as described above. + OUTPUT: a Polyhedron object, truncated as described above EXAMPLES:: @@ -2089,9 +2078,7 @@ def stack(self, face, position=None): new vertex close to the face and a large value further away. Default is `1`. If the given value is too large, an error is returned. - OUTPUT: - - A Polyhedron object + OUTPUT: a Polyhedron object EXAMPLES:: @@ -2421,7 +2408,8 @@ def lawrence_extension(self, v): if `v` is a vertex. INPUT: - - ``v`` -- a vertex of ``self`` or a point outside it + + - ``v`` -- a vertex of ``self`` or a point outside it EXAMPLES:: @@ -2465,7 +2453,7 @@ def _test_lawrence(self, tester=None, **options): if tester is None: tester = self._tester(**options) - if self.backend() == 'normaliz' and not self.base_ring() in (ZZ, QQ): + if self.backend() == 'normaliz' and self.base_ring() not in (ZZ, QQ): # Speeds up the doctest for significantly. self = self.change_ring(self._internal_base_ring) diff --git a/src/sage/geometry/polyhedron/base6.py b/src/sage/geometry/polyhedron/base6.py index cb1577c10b1..bccb57a09f4 100644 --- a/src/sage/geometry/polyhedron/base6.py +++ b/src/sage/geometry/polyhedron/base6.py @@ -37,6 +37,7 @@ from sage.geometry.convex_set import AffineHullProjectionData from .base5 import Polyhedron_base5 + class Polyhedron_base6(Polyhedron_base5): r""" Methods related to plotting including affine hull projection. @@ -151,7 +152,7 @@ def plot(self, INPUT: - - ``point``, ``line``, ``polygon`` -- Parameters to pass to + - ``point``, ``line``, ``polygon`` -- parameters to pass to point (0d), line (1d), and polygon (2d) plot commands. Allowed values are: @@ -164,7 +165,7 @@ def plot(self, * ``False``: Switches off the drawing of the corresponding graphics object - - ``wireframe``, ``fill`` -- Similar to ``point``, ``line``, + - ``wireframe``, ``fill`` -- similar to ``point``, ``line``, and ``polygon``, but ``fill`` is used for the graphics objects in the dimension of the polytope (or of dimension 2 for higher dimensional polytopes) and ``wireframe`` is used @@ -172,13 +173,13 @@ def plot(self, (default: 'green' for ``fill`` and 'blue' for ``wireframe``) - ``position`` -- positive number; the position to take the projection - point in Schlegel diagrams. + point in Schlegel diagrams - - ``orthonormal`` -- Boolean (default: ``True``); whether to use - orthonormal projections. + - ``orthonormal`` -- boolean (default: ``True``); whether to use + orthonormal projections - ``**kwds`` -- optional keyword parameters that are passed to - all graphics objects. + all graphics objects OUTPUT: @@ -324,15 +325,15 @@ def plot(self, Draw in red without wireframe:: - sage: for p in square.plot(wireframe=False, fill="red"): # needs sage.plot + sage: for p in square.plot(wireframe=False, fill='red'): # needs sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Polygon defined by 4 points - sage: for p in line.plot(wireframe=False, fill="red"): # needs sage.plot + sage: for p in line.plot(wireframe=False, fill='red'): # needs sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Line defined by 2 points - sage: for p in point.plot(wireframe=False, fill="red"): # needs sage.plot + sage: for p in point.plot(wireframe=False, fill='red'): # needs sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Point set defined by 1 point(s) @@ -457,7 +458,7 @@ def project(polyhedron, ortho): def show(self, **kwds): r""" - Display graphics immediately + Display graphics immediately. This method attempts to display the graphics immediately, without waiting for the currently running code (if any) to @@ -467,8 +468,8 @@ def show(self, **kwds): INPUT: - - ``kwds`` -- optional keyword arguments. See :meth:`plot` for - the description of available options. + - ``kwds`` -- optional keyword arguments; see :meth:`plot` for + the description of available options OUTPUT: @@ -495,28 +496,26 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, INPUT: - - ``view`` -- list (default: [0,0,1]) representing the rotation axis (see note below). - - ``angle`` -- integer (default: 0) angle of rotation in degree from 0 to 360 (see note - below). - - ``scale`` -- integer (default: 1) specifying the scaling of the tikz picture. - - ``edge_color`` -- string (default: 'blue!95!black') representing colors which tikz - recognize. - - ``facet_color`` -- string (default: 'blue!95!black') representing colors which tikz - recognize. - - ``vertex_color`` -- string (default: 'green') representing colors which tikz - recognize. + - ``view`` -- list (default: [0,0,1]) representing the rotation axis (see note below) + - ``angle`` -- integer (default: 0); angle of rotation in degree from 0 to 360 (see note + below) + - ``scale`` -- integer (default: 1); the scaling of the tikz picture + - ``edge_color`` -- string (default: ``'blue!95!black'``); representing colors which tikz + recognizes + - ``facet_color`` -- string (default: ``'blue!95!black'``); representing colors which tikz + recognizes + - ``vertex_color`` -- string (default: ``'green'``); representing colors which tikz + recognizes - ``opacity`` -- real number (default: 0.8) between 0 and 1 giving the opacity of - the front facets. - - ``axis`` -- Boolean (default: ``False``) draw the axes at the origin or not. - - ``output_type`` -- string (default: ``None``), valid values + the front facets + - ``axis`` -- boolean (default: ``False``); draw the axes at the origin or not + - ``output_type`` -- string (default: ``None``); valid values are ``None`` (deprecated), ``'LatexExpr'`` and ``'TikzPicture'``, whether to return a LatexExpr object (which inherits from Python str) or a ``TikzPicture`` object from module :mod:`sage.misc.latex_standalone` - OUTPUT: - - - LatexExpr object or TikzPicture object + OUTPUT: LatexExpr object or TikzPicture object .. NOTE:: @@ -550,7 +549,6 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, Jmol performs a rotation of ``angle`` degrees along the vector [x,y,z] and show the result from the z-axis. - EXAMPLES:: sage: # needs sage.plot @@ -611,7 +609,6 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, \end{tikzpicture} \end{document} sage: path_to_file = t.pdf() # not tested - """ return self.projection().tikz(view, angle, scale, edge_color, facet_color, @@ -620,7 +617,7 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, def _rich_repr_(self, display_manager, **kwds): r""" - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -835,17 +832,15 @@ def schlegel_projection(self, facet=None, position=None): INPUT: - - ``facet`` -- a :class:`~sage.geometry.polyhedron.face.PolyhedronFace`. - The facet into which the Schlegel diagram is created. The default is the first facet. + - ``facet`` -- a :class:`~sage.geometry.polyhedron.face.PolyhedronFace` + The facet into which the Schlegel diagram is created. The default is the first facet - ``position`` -- a positive number. Determines a relative distance from the barycenter of ``facet``. A value close to 0 will place the projection point close to the facet and a large value further away. Default is `1`. If the given value is too large, an error is returned. - OUTPUT: - - A :class:`~sage.geometry.polyhedron.plot.Projection` object. + OUTPUT: a :class:`~sage.geometry.polyhedron.plot.Projection` object EXAMPLES:: @@ -1099,10 +1094,10 @@ def affine_hull_projection(self, INPUT: - - ``as_polyhedron`` (or ``as_convex_set``) -- (boolean or the default - ``None``) and + - ``as_polyhedron``, ``as_convex_set`` -- boolean or the default + ``None``; one of the two to be set - - ``as_affine_map`` -- (boolean, default ``False``) control the output + - ``as_affine_map`` -- boolean (default: ``False``); control the output The default ``as_polyhedron=None`` translates to ``as_polyhedron=not as_affine_map``, @@ -1120,7 +1115,7 @@ def affine_hull_projection(self, both are returned, encapsulated in an instance of :class:`~sage.geometry.convex_set.AffineHullProjectionData`. - - ``return_all_data`` -- (boolean, default ``False``) + - ``return_all_data`` -- boolean (default: ``False``) If set, then ``as_polyhedron`` and ``as_affine_map`` will set (possibly overridden) and additional (internal) data concerning @@ -1130,7 +1125,7 @@ def affine_hull_projection(self, this case. - ``orthogonal`` -- boolean (default: ``False``); if ``True``, - provide an orthogonal transformation. + provide an orthogonal transformation - ``orthonormal`` -- boolean (default: ``False``); if ``True``, provide an orthonormal transformation. If the base ring does not @@ -1603,11 +1598,11 @@ def affine_hull_manifold(self, name=None, latex_name=None, start_index=0, ambien of the ambient dimension (default: the manifold of ``ambient_chart``, if provided; otherwise, a new instance of ``EuclideanSpace``). - - ``ambient_chart`` -- a chart on ``ambient_space``. + - ``ambient_chart`` -- a chart on ``ambient_space`` - - ``names`` -- names for the coordinates on the affine hull. + - ``names`` -- names for the coordinates on the affine hull - - optional arguments accepted by :meth:`affine_hull_projection`. + - optional arguments accepted by :meth:`affine_hull_projection` The default chart is determined by the optional arguments of :meth:`affine_hull_projection`. @@ -1669,7 +1664,6 @@ def affine_hull_manifold(self, name=None, latex_name=None, start_index=0, ambien A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices sage: cube.affine_hull_manifold() # needs sage.symbolic Euclidean space E^3 - """ if ambient_space is None: if ambient_chart is not None: @@ -1690,7 +1684,7 @@ def affine_hull_manifold(self, name=None, latex_name=None, start_index=0, ambien from sage.manifolds.manifold import Manifold if name is None: name, latex_name = self._affine_hull_name_latex_name() - H = Manifold(self.dim(), name, ambient=ambient_space, structure="Riemannian", + H = Manifold(self.dim(), name, ambient=ambient_space, structure='Riemannian', latex_name=latex_name, start_index=start_index) if names is None: names = tuple(f'x{i}' for i in range(self.dim())) diff --git a/src/sage/geometry/polyhedron/base7.py b/src/sage/geometry/polyhedron/base7.py index aca38a58404..1b232a00fa2 100644 --- a/src/sage/geometry/polyhedron/base7.py +++ b/src/sage/geometry/polyhedron/base7.py @@ -37,6 +37,7 @@ from sage.rings.rational_field import QQ from .base6 import Polyhedron_base6 + class Polyhedron_base7(Polyhedron_base6): r""" Methods related to triangulation and volume. @@ -64,7 +65,7 @@ def centroid(self, engine='auto', **kwds): The mass is taken with respect to the induced Lebesgue measure, see :meth:`volume`. - If the polyhedron is not compact, a ``NotImplementedError`` is + If the polyhedron is not compact, a :exc:`NotImplementedError` is raised. INPUT: @@ -76,9 +77,9 @@ def centroid(self, engine='auto', **kwds): TOPCOM is used if it is available and internal routines otherwise. - ``**kwds`` -- keyword arguments that are passed to the - triangulation engine (see :meth:`triangulate`). + triangulation engine (see :meth:`triangulate`) - OUTPUT: The centroid as vector. + OUTPUT: the centroid as vector ALGORITHM: @@ -150,7 +151,7 @@ def centroid(self, engine='auto', **kwds): def _triangulate_normaliz(self): r""" - Gives a triangulation of the polyhedron using normaliz + Give a triangulation of the polyhedron using normaliz. OUTPUT: @@ -188,17 +189,17 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration` constructor: - - ``connected`` -- boolean (default: ``True``). Whether the + - ``connected`` -- boolean (default: ``True``); whether the triangulations should be connected to the regular triangulations via bistellar flips. These are much easier to compute than all triangulations. - - ``fine`` -- boolean (default: ``False``). Whether the + - ``fine`` -- boolean (default: ``False``); whether the triangulations must be fine, that is, make use of all points - of the configuration. + of the configuration - ``regular`` -- boolean or ``None`` (default: - ``None``). Whether the triangulations must be regular. A + ``None``); whether the triangulations must be regular. A regular triangulation is one that is induced by a piecewise-linear convex support function. In other words, the shadows of the faces of a polyhedron in one higher @@ -312,11 +313,9 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s def _volume_lrs(self, verbose=False): """ - Computes the volume of a polytope using lrs. - - OUTPUT: + Compute the volume of a polytope using lrs. - The exact volume as a rational number. + OUTPUT: the exact volume as a rational number EXAMPLES:: @@ -365,24 +364,25 @@ def _volume_lrs(self, verbose=False): def _volume_latte(self, verbose=False, algorithm='triangulate', **kwargs): """ - Computes the volume of a polytope using LattE integrale. + Compute the volume of a polytope using LattE integrale. INPUT: - ``arg`` -- a cdd or LattE description string - - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for - polytope triangulation or 'cone-decompose' for tangent cone decomposition method. + - ``algorithm`` -- (default: ``'triangulate'``) the integration method; + use 'triangulate' for polytope triangulation or 'cone-decompose' for + tangent cone decomposition method - - ``raw_output`` -- if ``True`` then return directly the output string from LattE. + - ``raw_output`` -- if ``True`` then return directly the output string + from LattE - - ``verbose`` -- if ``True`` then return directly verbose output from LattE. + - ``verbose`` -- if ``True`` then return directly verbose output from + LattE - For all other options, consult the LattE manual. - OUTPUT: - - A rational value, or a string if ``raw_output`` if set to ``True``. + OUTPUT: a rational value, or a string if ``raw_output`` if set to ``True`` .. NOTE:: @@ -436,13 +436,13 @@ def _volume_latte(self, verbose=False, algorithm='triangulate', **kwargs): def _volume_normaliz(self, measure='induced'): r""" - Computes the volume of a polytope using normaliz. + Compute the volume of a polytope using normaliz. INPUT: - - ``measure`` -- (default: 'induced') the measure to take. 'induced' - correspond to ``EuclideanVolume`` in normaliz and 'induced_lattice' - correspond to ``Volume`` in normaliz + - ``measure`` -- (default: ``'induced'``) the measure to take; + 'induced' correspond to ``EuclideanVolume`` in normaliz and + 'induced_lattice' correspond to ``Volume`` in normaliz OUTPUT: @@ -492,9 +492,7 @@ def volume(self, measure='ambient', engine='auto', **kwds): - ``**kwds`` -- keyword arguments that are passed to the triangulation engine - OUTPUT: - - The volume of the polytope + OUTPUT: the volume of the polytope EXAMPLES:: @@ -788,9 +786,7 @@ def integrate(self, function, measure='ambient', **kwds): - ``**kwds`` -- additional keyword arguments that are passed to the engine - OUTPUT: - - The integral of the polynomial over the polytope + OUTPUT: the integral of the polynomial over the polytope .. NOTE:: @@ -961,9 +957,7 @@ def _integrate_latte_(self, polynomial, **kwds): - ``**kwds`` -- additional keyword arguments that are passed to the engine - OUTPUT: - - The integral of the polynomial over the polytope. + OUTPUT: the integral of the polynomial over the polytope .. NOTE:: diff --git a/src/sage/geometry/polyhedron/base_QQ.py b/src/sage/geometry/polyhedron/base_QQ.py index a6d1aa719f3..e17f043adb5 100644 --- a/src/sage/geometry/polyhedron/base_QQ.py +++ b/src/sage/geometry/polyhedron/base_QQ.py @@ -10,7 +10,7 @@ class Polyhedron_QQ(Polyhedron_base): r""" - Base class for Polyhedra over `\QQ` + Base class for Polyhedra over `\QQ`. TESTS:: @@ -24,11 +24,9 @@ def _is_zero(self, x): INPUT: - - ``x`` -- a number in the base ring. + - ``x`` -- a number in the base ring - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -46,11 +44,9 @@ def _is_nonneg(self, x): INPUT: - - ``x`` -- a number in the base ring. + - ``x`` -- a number in the base ring - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -68,11 +64,9 @@ def _is_positive(self, x): INPUT: - - ``x`` -- a number in the base ring. + - ``x`` -- a number in the base ring - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -97,13 +91,13 @@ def integral_points_count(self, verbose=False, use_Hrepresentation=False, INPUT: - - ``verbose`` -- (boolean; ``False`` by default) whether to display - verbose output. + - ``verbose`` -- boolean (default: ``False``); whether to display + verbose output - - ``use_Hrepresentation`` -- (boolean; ``False`` by default) -- whether + - ``use_Hrepresentation`` -- boolean (default: ``False``); whether to send the H or V representation to LattE - - ``preprocess`` -- (boolean; ``True`` by default) whether, if the integral hull + - ``preprocess`` -- boolean (default: ``True``); whether, if the integral hull is known to lie in a coordinate hyperplane, to tighten bounds to reduce dimension .. SEEALSO:: @@ -237,7 +231,7 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, INPUT: - - ``engine`` -- string; The backend to use. Allowed values are: + - ``engine`` -- string; the backend to use. Allowed values are: * ``None`` (default); When no input is given the Ehrhart polynomial is computed using LattE Integrale (optional) @@ -245,13 +239,13 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, * ``'normaliz'``; use Normaliz program (optional package pynormaliz). The backend of ``self`` must be set to ``'normaliz'``. - - ``variable`` -- string (default: ``'t'``); The variable in which the - Ehrhart polynomial should be expressed. + - ``variable`` -- string (default: ``'t'``); the variable in which the + Ehrhart polynomial should be expressed - When the ``engine`` is ``'latte'``, the additional input values are: - * ``verbose`` -- boolean (default: ``False``); If ``True``, print the - whole output of the LattE command. + * ``verbose`` -- boolean (default: ``False``); if ``True``, print the + whole output of the LattE command The following options are passed to the LattE command, for details consult `the LattE documentation @@ -274,9 +268,7 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, * ``triangulation_max_height`` -- integer; use a uniform distribution of height from 1 to this number - OUTPUT: - - A univariate polynomial in ``variable`` over a rational field. + OUTPUT: a univariate polynomial in ``variable`` over a rational field .. SEEALSO:: @@ -410,10 +402,10 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, INPUT: - - ``variable`` -- string (default: ``'t'``); The variable in which the - Ehrhart polynomial should be expressed. + - ``variable`` -- string (default: ``'t'``); the variable in which the + Ehrhart polynomial should be expressed - - ``engine`` -- string; The backend to use. Allowed values are: + - ``engine`` -- string; the backend to use. Allowed values are: * ``None`` (default); When no input is given the Ehrhart polynomial is computed using Normaliz (optional) @@ -424,8 +416,8 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, - When the ``engine`` is 'latte', the additional input values are: - * ``verbose`` -- boolean (default: ``False``); If ``True``, print the - whole output of the LattE command. + * ``verbose`` -- boolean (default: ``False``); if ``True``, print the + whole output of the LattE command The following options are passed to the LattE command, for details consult `the LattE documentation @@ -593,8 +585,8 @@ def _ehrhart_quasipolynomial_normaliz(self, variable='t'): INPUT: - - ``variable`` -- string (default: ``'t'``); The variable in which the - Ehrhart polynomial is expressed. + - ``variable`` -- string (default: ``'t'``); the variable in which the + Ehrhart polynomial is expressed OUTPUT: @@ -657,7 +649,7 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, INPUT: - ``verbose`` -- boolean (default: ``False``); if ``True``, print the - whole output of the LattE command. + whole output of the LattE command The following options are passed to the LattE command, for details you should consult `the LattE documentation @@ -667,15 +659,15 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, space - ``irrational_primal`` -- boolean; triangulate in the dual space, - signed-decompose in the primal space using irrationalization. + signed-decompose in the primal space using irrationalization - ``irrational_all_primal`` -- boolean; triangulate and signed-decompose - in the primal space using irrationalization. + in the primal space using irrationalization - ``maxdet`` -- integer; decompose down to an index (determinant) of - ``maxdet`` instead of index 1 (unimodular cones). + ``maxdet`` instead of index 1 (unimodular cones) - - ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones. + - ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones - ``compute_vertex_cones`` -- string; either ``'cdd'`` or ``'lrs'`` or ``'4ti2'`` @@ -693,9 +685,7 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, Any additional argument is forwarded to LattE's executable ``count``. All occurrences of '_' will be replaced with a '-'. - OUTPUT: - - A univariate polynomial over a rational field. + OUTPUT: a univariate polynomial over a rational field ALGORITHM: @@ -814,11 +804,9 @@ def fixed_subpolytope(self, vertex_permutation): INPUT: - ``vertex_permutation`` -- permutation; a permutation of the vertices - of ``self``. - - OUTPUT: + of ``self`` - A subpolytope of ``self``. + OUTPUT: a subpolytope of ``self`` .. NOTE:: @@ -927,7 +915,7 @@ def fixed_subpolytopes(self, conj_class_reps): INPUT: - - ``conj_class_reps`` -- a list of representatives of the conjugacy + - ``conj_class_reps`` -- list of representatives of the conjugacy classes of the subgroup of the :meth:`restricted_automorphism_group` of the polytope. Each element is written as a permutation of the vertices of the polytope. @@ -1021,7 +1009,6 @@ class functions. There are several output options to see the intermediary outputs of the function. - EXAMPLES: The `H^*`-polynomial of the standard (`d-1`)-dimensional simplex @@ -1101,8 +1088,7 @@ class functions. def _Hstar_function_normaliz(self, acting_group=None, output=None): r""" Return `H^*` as a rational function in `t` with coefficients in - the ring of class functions of the ``acting_group`' - of ``self``. + the ring of class functions of the ``acting_group`` of ``self``. INPUT: @@ -1155,21 +1141,19 @@ def is_effective(self, Hstar, Hstar_as_lin_comb): coefficient of each `t^i` is an effective character in the ring of class functions of the acting group. A character `\rho` is effective if the coefficients of the irreducible representations in the expression - of `\rho` are non-negative integers. + of `\rho` are nonnegative integers. INPUT: - ``Hstar`` -- a rational function in `t` with coefficients in the ring - of class functions. + of class functions - ``Hstar_as_lin_comb`` -- vector. The coefficients of the irreducible representations of the acting group in the expression of ``Hstar`` as a linear combination of irreducible representations with coefficients in the field of rational functions in `t`. - OUTPUT: - - Boolean. Whether the ``Hstar`` series is effective. + OUTPUT: boolean; whether the ``Hstar`` series is effective .. SEEALSO:: @@ -1232,21 +1216,19 @@ def _is_effective_normaliz(self, Hstar, Hstar_as_lin_comb): coefficient of each `t^i` is an effective character in the ring of class functions of the acting group. A character `\rho` is effective if the coefficients of the irreducible representations in the expression - of `\rho` are non-negative integers. + of `\rho` are nonnegative integers. INPUT: - ``Hstar`` -- a rational function in `t` with coefficients in the ring - of class functions. + of class functions - ``Hstar_as_lin_comb`` -- vector. The coefficients of the irreducible representations of the acting group in the expression of ``Hstar`` as a linear combination of irreducible representations with coefficients in the field of rational functions in `t`. - OUTPUT: - - Boolean. Whether the ``Hstar`` series is effective. + OUTPUT: boolean; whether the ``Hstar`` series is effective TESTS:: diff --git a/src/sage/geometry/polyhedron/base_RDF.py b/src/sage/geometry/polyhedron/base_RDF.py index 93914ded471..505355ac42c 100644 --- a/src/sage/geometry/polyhedron/base_RDF.py +++ b/src/sage/geometry/polyhedron/base_RDF.py @@ -25,11 +25,9 @@ def _is_zero(self, x): INPUT: - - ``x`` -- a number in the base ring. + - ``x`` -- a number in the base ring - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -52,11 +50,9 @@ def _is_nonneg(self, x): INPUT: - - ``x`` -- a number in the base ring. - - OUTPUT: + - ``x`` -- a number in the base ring - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -79,11 +75,9 @@ def _is_positive(self, x): INPUT: - - ``x`` -- a number in the base ring. - - OUTPUT: + - ``x`` -- a number in the base ring - Boolean. + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index dd3d32d9e51..d17b40a1b3d 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -30,7 +30,7 @@ ######################################################################### class Polyhedron_ZZ(Polyhedron_QQ): r""" - Base class for Polyhedra over `\ZZ` + Base class for Polyhedra over `\ZZ`. TESTS:: @@ -116,7 +116,7 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, INPUT: - ``verbose`` -- boolean (default: ``False``); if ``True``, print the - whole output of the LattE command. + whole output of the LattE command The following options are passed to the LattE command, for details you should consult `the LattE documentation @@ -126,15 +126,15 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, space - ``irrational_primal`` -- boolean; triangulate in the dual space, - signed-decompose in the primal space using irrationalization. + signed-decompose in the primal space using irrationalization - ``irrational_all_primal`` -- boolean; triangulate and signed-decompose - in the primal space using irrationalization. + in the primal space using irrationalization - ``maxdet`` -- integer; decompose down to an index (determinant) of - ``maxdet`` instead of index 1 (unimodular cones). + ``maxdet`` instead of index 1 (unimodular cones) - - ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones. + - ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones - ``compute_vertex_cones`` -- string; either 'cdd' or 'lrs' or '4ti2' @@ -266,12 +266,10 @@ def _ehrhart_polynomial_normaliz(self, variable='t'): INPUT: - - ``variable`` -- (string, default='t'); the variable in which the - Ehrhart polynomial is expressed. + - ``variable`` -- string (default: ``'t'``); the variable in which the + Ehrhart polynomial is expressed - OUTPUT: - - A univariate polynomial over a rational field. + OUTPUT: a univariate polynomial over a rational field EXAMPLES:: @@ -316,7 +314,7 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, dual=None INPUT: - - ``engine`` -- string; The backend to use. Allowed values are: + - ``engine`` -- string; the backend to use. Allowed values are: * ``None`` (default); When no input is given the Ehrhart polynomial is computed using LattE Integrale (optional) @@ -324,8 +322,8 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, dual=None * ``'normaliz'``; use Normaliz program (optional). The backend of ``self`` must be set to 'normaliz'. - - ``variable`` -- string (default: 't'); The variable in which the - Ehrhart polynomial should be expressed. + - ``variable`` -- string (default: ``'t'``); the variable in which the + Ehrhart polynomial should be expressed - When the ``engine`` is 'latte' or None, the additional input values are: @@ -340,7 +338,7 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, dual=None space * ``irrational_primal`` -- boolean; triangulate in the dual space, signed-decompose in the primal space using irrationalization. - * ``irrational_all_primal`` -- boolean; Triangulate and signed-decompose + * ``irrational_all_primal`` -- boolean; triangulate and signed-decompose in the primal space using irrationalization. * ``maxdet`` -- integer; decompose down to an index (determinant) of ``maxdet`` instead of index 1 (unimodular cones). @@ -627,8 +625,8 @@ def fibration_generator(self, dim): INPUT: - - ``dim`` -- integer. The dimension of the lattice polytope - fiber. + - ``dim`` -- integer; the dimension of the lattice polytope + fiber OUTPUT: @@ -669,12 +667,12 @@ def find_translation(self, translated_polyhedron): INPUT: - - ``translated_polyhedron`` -- a polyhedron. + - ``translated_polyhedron`` -- a polyhedron OUTPUT: A `\ZZ`-vector that translates ``self`` to - ``translated_polyhedron``. A ``ValueError`` is raised if + ``translated_polyhedron``. A :exc:`ValueError` is raised if ``translated_polyhedron`` is not a translation of ``self``, this can be used to check that two polyhedra are not translates of each other. @@ -842,16 +840,16 @@ def is_known_summand(poly): summands += [X, Y] return tuple(decompositions) - def normal_form(self, algorithm="palp_native", permutation=False): + def normal_form(self, algorithm='palp_native', permutation=False): r""" Return the normal form of vertices of the lattice polytope ``self``. INPUT: - - ``algorithm`` -- must be ``"palp_native"``, the default. + - ``algorithm`` -- must be ``'palp_native'``, the default - ``permutation`` -- boolean (default: ``False``); if ``True``, the permutation - applied to vertices to obtain the normal form is returned as well. + applied to vertices to obtain the normal form is returned as well For more more detail, see :meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form`. @@ -903,7 +901,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): TESTS:: - sage: d.normal_form(algorithm="palp_fiction") + sage: d.normal_form(algorithm='palp_fiction') Traceback (most recent call last): ... ValueError: algorithm must be 'palp_native' diff --git a/src/sage/geometry/polyhedron/base_mutable.py b/src/sage/geometry/polyhedron/base_mutable.py index 42e77a8fcf0..1a3622a9e5b 100644 --- a/src/sage/geometry/polyhedron/base_mutable.py +++ b/src/sage/geometry/polyhedron/base_mutable.py @@ -136,7 +136,7 @@ def _add_dependent_object(self, ob): def is_mutable(self): r""" - Return True if the polyhedron is mutable, i.e. it can be modified in place. + Return ``True`` if the polyhedron is mutable, i.e. it can be modified in place. EXAMPLES:: @@ -151,7 +151,7 @@ def is_mutable(self): def is_immutable(self): r""" - Return True if the polyhedron is immutable, i.e. it cannot be modified in place. + Return ``True`` if the polyhedron is immutable, i.e. it cannot be modified in place. EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/cdd_file_format.py b/src/sage/geometry/polyhedron/cdd_file_format.py index 728f20bb9b5..edc04b4cb8f 100644 --- a/src/sage/geometry/polyhedron/cdd_file_format.py +++ b/src/sage/geometry/polyhedron/cdd_file_format.py @@ -14,13 +14,15 @@ from .misc import _set_to_None_if_empty, _common_length_of, _to_space_separated_string ######################################################################### + + def cdd_Vrepresentation(cdd_type, vertices, rays, lines, file_output=None): r""" Return a string containing the V-representation in cddlib's ext format. INPUT: - - ``file_output`` (string; optional) -- a filename to which the + - ``file_output`` -- string (optional); a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. @@ -92,13 +94,15 @@ def cdd_Vrepresentation(cdd_type, vertices, rays, lines, file_output=None): return s ######################################################################### + + def cdd_Hrepresentation(cdd_type, ieqs, eqns, file_output=None): r""" Return a string containing the H-representation in cddlib's ine format. INPUT: - - ``file_output`` (string; optional) -- a filename to which the + - ``file_output`` -- string (optional); a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index d21b824da0c..4db4eb54171 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -11,11 +11,11 @@ the ridges and the face lattice. Terminology used in this module: -- Vrep -- ``[vertices, rays, lines]`` of the polyhedron. -- Hrep -- inequalities and equations of the polyhedron. -- Facets -- facets of the polyhedron. -- Vrepresentation -- represents a face by the list of Vrep it contains. -- Hrepresentation -- represents a face by a list of Hrep it is contained in. +- Vrep -- ``[vertices, rays, lines]`` of the polyhedron +- Hrep -- inequalities and equations of the polyhedron +- Facets -- facets of the polyhedron +- Vrepresentation -- represents a face by the list of Vrep it contains +- Hrepresentation -- represents a face by a list of Hrep it is contained in - bit representation -- represents incidences as bitset, where each bit represents one incidence. There might be trailing zeros, to fit alignment requirements. In most instances, faces are represented by the bit @@ -543,7 +543,7 @@ cdef class CombinatorialPolyhedron(SageObject): cdef _init_from_ListOfFaces(self, ListOfFaces facets, ListOfFaces Vrep): """ - Initialize self from two ``ListOfFaces``. + Initialize ``self`` from two ``ListOfFaces``. """ self._bitrep_facets = facets self._bitrep_Vrep = Vrep @@ -1300,7 +1300,7 @@ cdef class CombinatorialPolyhedron(SageObject): edges = tuple(edge for edge in self.edges(names=names, algorithm=algorithm) if edge[0] in vertices and edge[1] in vertices) - return Graph([vertices, edges], format="vertices_and_edges") + return Graph([vertices, edges], format='vertices_and_edges') graph = vertex_graph @@ -1376,7 +1376,7 @@ cdef class CombinatorialPolyhedron(SageObject): - ``add_equations`` -- if ``True``, then equations of the polyhedron will be added (only applicable when ``names`` is ``True``) - - ``names`` -- boolean (default: `True`); + - ``names`` -- boolean (default: ``True``); if ``False``, then the facets are given by their indices - ``algorithm`` -- string (optional); @@ -1583,7 +1583,7 @@ cdef class CombinatorialPolyhedron(SageObject): # If names is false, the ridges are given as tuple of indices, # i.e. (1,2) instead of (('f1',), ('f2',)). V = list(v[0] for v in V) - return Graph([V, E], format="vertices_and_edges") + return Graph([V, E], format='vertices_and_edges') @cached_method def vertex_facet_graph(self, names=True): @@ -1781,14 +1781,14 @@ cdef class CombinatorialPolyhedron(SageObject): INPUT: - - ``args`` -- integers (optional); specify an entry of the - flag-f-vector; must be an increasing sequence of integers + - ``args`` -- integer (optional); specify an entry of the + flag-f-vector (must be an increasing sequence of integers) OUTPUT: - a dictionary, if no arguments were given - - an Integer, if arguments were given + - an integer, if arguments were given EXAMPLES: @@ -2674,9 +2674,7 @@ cdef class CombinatorialPolyhedron(SageObject): * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically - OUTPUT: - - - :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.face_iterator.FaceIterator` + OUTPUT: :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.face_iterator.FaceIterator` .. NOTE:: @@ -2787,9 +2785,7 @@ cdef class CombinatorialPolyhedron(SageObject): r""" Generate the face-lattice. - OUTPUT: - - - :class:`~sage.combinat.posets.lattices.FiniteLatticePoset` + OUTPUT: :class:`~sage.combinat.posets.lattices.FiniteLatticePoset` .. NOTE:: @@ -3172,7 +3168,7 @@ cdef class CombinatorialPolyhedron(SageObject): def _test_a_maximal_chain(self, tester=None, **options): """ - Run tests on the method :meth:`.a_maximal_chain` + Run tests on the method :meth:`.a_maximal_chain`. TESTS:: @@ -3252,7 +3248,7 @@ cdef class CombinatorialPolyhedron(SageObject): def is_compact(self): r""" - Return whether the polyhedron is compact + Return whether the polyhedron is compact. EXAMPLES:: @@ -3314,7 +3310,7 @@ cdef class CombinatorialPolyhedron(SageObject): cpdef CombinatorialPolyhedron dual(self): r""" - Return the dual/polar of self. + Return the dual/polar of ``self``. Only defined for bounded polyhedra. @@ -3458,7 +3454,7 @@ cdef class CombinatorialPolyhedron(SageObject): num_threads = 1 if parallelization_depth > dim - 1: - # Is a very bad choice anyway, but prevent segmenation faults. + # Is a very bad choice anyway, but prevent segmentation faults. parallelization_depth = dim - 1 if dual == -1: @@ -3594,9 +3590,7 @@ cdef class CombinatorialPolyhedron(SageObject): * ``'edges'`` * ``'ridges'`` - OUTPUT: - - Either ``'primal'`` or ``'dual'``. + OUTPUT: either ``'primal'`` or ``'dual'`` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx index 951dd9e5420..a1ce8b14cb1 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx @@ -107,9 +107,7 @@ cdef int Vrep_list_to_bit_rep(tuple Vrep_list, face_t output) except -1: - ``vertex_list`` -- tuple of pairwise distinct positive integers that fit into ``output`` - ``output`` -- an already initialized face - OUTPUT: - - - ``output`` is filled + OUTPUT: ``output`` is filled EXAMPLES:: @@ -158,16 +156,14 @@ cdef int incidences_to_bit_rep(tuple incidences, face_t output) except -1: Convert a tuple of incidences into Bit-representation. Store it in ``output``. Each entry in ``incidences`` represents a bit in - ``output``. It is set to ``1``, iff the entry in ``incidences`` is non-zero. + ``output``. It is set to ``1``, iff the entry in ``incidences`` is nonzero. INPUT: - ``incidences`` -- tuple of integers representing incidences that fit into ``output`` - ``output`` -- an already initialized face - OUTPUT: - - - ``output`` is filled + OUTPUT: ``output`` is filled EXAMPLES:: @@ -200,9 +196,7 @@ def incidence_matrix_to_bit_rep_of_facets(Matrix_dense matrix): with columns corresponding to equations deleted of type :class:`sage.matrix.matrix_dense.Matrix_dense` - OUTPUT: - - - :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` + OUTPUT: :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` EXAMPLES:: @@ -268,9 +262,7 @@ def incidence_matrix_to_bit_rep_of_Vrep(Matrix_dense matrix): with columns corresponding to equations deleted of type :class:`sage.matrix.matrix_dense.Matrix_dense` - OUTPUT: - - - :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` + OUTPUT: :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` EXAMPLES:: @@ -315,7 +307,7 @@ def incidence_matrix_to_bit_rep_of_Vrep(Matrix_dense matrix): def facets_tuple_to_bit_rep_of_facets(tuple facets_input, size_t n_Vrep): r""" - Initializes facets in Bit-representation as :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces`. + Initialize facets in Bit-representation as :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces`. INPUT: @@ -323,9 +315,7 @@ def facets_tuple_to_bit_rep_of_facets(tuple facets_input, size_t n_Vrep): Vrep must be exactly ``range(n_Vrep)`` - ``n_Vrep`` - OUTPUT: - - - :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` + OUTPUT: :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` EXAMPLES:: @@ -368,10 +358,7 @@ def facets_tuple_to_bit_rep_of_Vrep(tuple facets_input, size_t n_Vrep): Vrep must be exactly ``range(n_Vrep)`` - ``n_Vrep`` - OUTPUT: - - - :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` - + OUTPUT: :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` EXAMPLES:: @@ -423,9 +410,9 @@ def _bit_rep_to_Vrep_list_wrapper(ListOfFaces faces, index=0): INPUT: - ``faces`` -- a :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces` - - ``index`` -- (default: ``0``); the face to obtain + - ``index`` -- (default: ``0``) the face to obtain - OUTPUT: The face as tuple of integers. + OUTPUT: the face as tuple of integers EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd index 3ed71a664e1..87766041ffb 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd @@ -182,7 +182,7 @@ cdef inline void face_intersection_fused(face_t dest, face_t A, face_t B, algori Set ``dest`` to the intersection of ``A`` and ``B``. """ if algorithm_variant is standard: - # Also setting the non zero positions. + # Also setting the nonzero positions. sparse_bitset_intersection(dest.atoms, A.atoms, B.atoms) else: bitset_intersection(dest.atoms, A.atoms, B.atoms) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd index 3c015973dd1..41f97c309ef 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd @@ -15,8 +15,8 @@ cdef struct iter_s: bint dual # if 1, then iterate over dual Polyhedron face_t face # the current face of the iterator FaceStatus face_status - size_t *atom_rep # a place where atom-representaion of face will be stored - size_t *coatom_rep # a place where coatom-representaion of face will be stored + size_t *atom_rep # a place where atom-representation of face will be stored + size_t *coatom_rep # a place where coatom-representation of face will be stored int current_dimension # dimension of current face, dual dimension if ``dual`` int dimension # dimension of the polyhedron int output_dimension # only faces of this (dual?) dimension are considered @@ -25,7 +25,7 @@ cdef struct iter_s: size_t _index # this counts the number of seen faces, useful for hasing the faces # ``visited_all`` points to faces, of which we have visited all faces already. - # The number of faces in ``visited_all` might depend on the current dimension: + # The number of faces in ``visited_all`` might depend on the current dimension: # Consider we visit the facets A,B of some face F. # We will first visit all faces of A and then add A to visited_all. # Then we visit all faces of B and add B to visited_all. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index 99cfef13db2..d1daed6ad8b 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -2140,7 +2140,7 @@ cdef inline int prepare_face_iterator_for_partial_job( The first digit determines which facet to visit. The next digit determines which facet of the facet should be visited. - OUTPUT: ``1`` if the job exists and ``0`` otherwise. + OUTPUT: ``1`` if the job exists and ``0`` otherwise In addition, the first job treating a face will "visit" this face and increase the corresponding entry of the f-vector. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd index 50bbd7c4026..2156d4a8bf7 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd @@ -36,7 +36,7 @@ ctypedef face_list_s face_list_t[1] cdef inline int face_list_init(face_list_t faces, size_t n_faces, size_t n_atoms, size_t n_coatoms) except -1: """ - Sets the initial values for a list of faces with given number of faces + Set the initial values for a list of faces with given number of faces and number of atoms. """ face_list_shallow_init(faces, n_faces, n_atoms, n_coatoms) @@ -147,7 +147,7 @@ cdef inline void face_list_delete_faces_by_array(face_list_t faces, bint *delete cdef inline void face_list_delete_faces_by_face(face_list_t faces, face_t face) noexcept: r""" Remove all faces such that the ``i``-th bit in ``face`` is not set - descreasing ``faces.n_faces``. + decreasing ``faces.n_faces``. .. WARNING:: @@ -279,9 +279,7 @@ cdef inline size_t get_next_level_fused( - ``new_faces`` -- needs to be of same size as ``faces`` - ``visited_all`` -- the faces which have been visited before - OUTPUT: - - - set ``new_faces`` to point to the new faces + OUTPUT: set ``new_faces`` to point to the new faces ALGORITHM: diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx index 468347f5256..0e8a53e97dc 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx @@ -180,7 +180,7 @@ cdef class ListOfFaces: cpdef ListOfFaces __copy__(self): r""" - Return a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -423,7 +423,7 @@ cdef class ListOfFaces: cdef void delete_faces_unsafe(self, bint *delete, face_t face) noexcept: r""" - Deletes face ``i`` if and only if ``delete[i]``. + Delete face ``i`` if and only if ``delete[i]``. Alternatively, deletes all faces such that the ``i``-th bit in ``face`` is not set. @@ -478,7 +478,7 @@ cdef class ListOfFaces: def matrix(self): r""" - Obtain the matrix of self. + Obtain the matrix of ``self``. Each row represents a face and each column an atom. @@ -529,7 +529,7 @@ cdef tuple face_as_combinatorial_polyhedron(ListOfFaces facets, ListOfFaces Vrep - ``face`` -- face in Vrepresentation or ``NULL`` - ``dual`` -- boolean - OUTPUT: A tuple of new facets and new Vrepresentation as :class:`ListOfFaces`. + OUTPUT: a tuple of new facets and new Vrepresentation as :class:`ListOfFaces`. """ cdef ListOfFaces new_facets, new_Vrep cdef bint* delete diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/meson.build b/src/sage/geometry/polyhedron/combinatorial_polyhedron/meson.build new file mode 100644 index 00000000000..4b4ea8df4e7 --- /dev/null +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/meson.build @@ -0,0 +1,34 @@ +py.install_sources( + 'all.py', + 'base.pxd', + 'combinatorial_face.pxd', + 'conversions.pxd', + 'face_data_structure.pxd', + 'face_iterator.pxd', + 'face_list_data_structure.pxd', + 'list_of_faces.pxd', + 'polyhedron_face_lattice.pxd', + subdir: 'sage/geometry/polyhedron/combinatorial_polyhedron', +) + +extension_data = { + 'base' : files('base.pyx'), + 'combinatorial_face' : files('combinatorial_face.pyx'), + 'conversions' : files('conversions.pyx'), + 'face_iterator' : files('face_iterator.pyx'), + 'face_list_data_structure' : files('face_list_data_structure.pyx'), + 'list_of_faces' : files('list_of_faces.pyx'), + 'polyhedron_face_lattice' : files('polyhedron_face_lattice.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/geometry/polyhedron/combinatorial_polyhedron', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx index d0064795fa5..475b3e63e6c 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx @@ -8,11 +8,11 @@ the face lattice of a polyhedron. Terminology in this module: -- Vrep -- ``[vertices, rays, lines]`` of the polyhedron. +- Vrep -- ``[vertices, rays, lines]`` of the polyhedron -- Hrep -- inequalities and equations of the polyhedron. +- Hrep -- inequalities and equations of the polyhedron -- Facets -- facets of the polyhedron. +- Facets -- facets of the polyhedron - Coatoms -- the faces from which all others are constructed in the face iterator. This will be facets or Vrep. In non-dual mode, faces are @@ -23,9 +23,9 @@ Terminology in this module: - Atoms -- facets or Vrep depending on application of algorithm. Atoms are repsented as incidences of coatoms they are contained in. -- Vrepresentation -- represents a face by a list of Vrep it contains. +- Vrepresentation -- represents a face by a list of Vrep it contains -- Hrepresentation -- represents a face by a list of Hrep it is contained in. +- Hrepresentation -- represents a face by a list of Hrep it is contained in - bit representation -- represents incidences as ``uint64_t``-array, where each bit represents one incidence. There might be trailing zeros, to fit alignment diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index 5a5db0b43ae..0d8a4bfa6e6 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -34,15 +34,15 @@ points are equal if and only if the vector is the same. * **rays** `r_1,\dots,r_m` are a finite number of directions - (directions of infinity). Each ray is specified by a non-zero + (directions of infinity). Each ray is specified by a nonzero vector, and two rays are equal if and only if the vectors are the same up to rescaling with a positive constant. * **lines** `\ell_1,\dots,\ell_n` are a finite number of unoriented directions. In other words, a line is equivalent to the set `\{r, -r\}` for a ray `r`. Each line is specified by a - non-zero vector, and two lines are equivalent if and only if the - vectors are the same up to rescaling with a non-zero (possibly + nonzero vector, and two lines are equivalent if and only if the + vectors are the same up to rescaling with a nonzero (possibly negative) constant. When specifying a polyhedron, you can input a non-minimal set of @@ -326,21 +326,21 @@ def Polyhedron(vertices=None, rays=None, lines=None, or :meth:`polyhedron` method. In this case, the following 5 arguments cannot be provided. - - ``rays`` -- list of rays. Each ray can be specified as any - iterable container of ``base_ring`` elements. + - ``rays`` -- list of rays; each ray can be specified as any + iterable container of ``base_ring`` elements - - ``lines`` -- list of lines. Each line can be specified as any - iterable container of ``base_ring`` elements. + - ``lines`` -- list of lines; each line can be specified as any + iterable container of ``base_ring`` elements - - ``ieqs`` -- list of inequalities. Each line can be specified as any + - ``ieqs`` -- list of inequalities; each line can be specified as any iterable container of ``base_ring`` elements. An entry equal to ``[-1,7,3,4]`` represents the inequality `7x_1+3x_2+4x_3\geq 1`. - - ``eqns`` -- list of equalities. Each line can be specified as + - ``eqns`` -- list of equalities; each line can be specified as any iterable container of ``base_ring`` elements. An entry equal to ``[-1,7,3,4]`` represents the equality `7x_1+3x_2+4x_3= 1`. - - ``ambient_dim`` -- integer. The ambient space dimension. Usually + - ``ambient_dim`` -- integer; the ambient space dimension. Usually can be figured out automatically from the H/Vrepresentation dimensions. @@ -385,9 +385,7 @@ def Polyhedron(vertices=None, rays=None, lines=None, - ``mutable`` -- boolean (default: ``False``); whether the polyhedron is mutable - OUTPUT: - - The polyhedron defined by the input data. + OUTPUT: the polyhedron defined by the input data EXAMPLES: @@ -599,11 +597,11 @@ def Polyhedron(vertices=None, rays=None, lines=None, sage: Polyhedron(ambient_dim=2, ieqs=[], eqns=[], base_ring=QQ, backend='field') A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 lines - sage: Polyhedron(ambient_dim=0, ieqs=[], eqns=[[1]], base_ring=QQ, backend="cdd") + sage: Polyhedron(ambient_dim=0, ieqs=[], eqns=[[1]], base_ring=QQ, backend='cdd') The empty polyhedron in QQ^0 - sage: Polyhedron(ambient_dim=0, ieqs=[], eqns=[[1]], base_ring=QQ, backend="ppl") + sage: Polyhedron(ambient_dim=0, ieqs=[], eqns=[[1]], base_ring=QQ, backend='ppl') The empty polyhedron in QQ^0 - sage: Polyhedron(ambient_dim=0, ieqs=[], eqns=[[1]], base_ring=QQ, backend="field") + sage: Polyhedron(ambient_dim=0, ieqs=[], eqns=[[1]], base_ring=QQ, backend='field') The empty polyhedron in QQ^0 sage: Polyhedron(ambient_dim=2, vertices=[], rays=[], lines=[], base_ring=QQ) diff --git a/src/sage/geometry/polyhedron/double_description.py b/src/sage/geometry/polyhedron/double_description.py index 089580e3146..82bb0685d61 100644 --- a/src/sage/geometry/polyhedron/double_description.py +++ b/src/sage/geometry/polyhedron/double_description.py @@ -85,13 +85,11 @@ def random_inequalities(d, n): INPUT: - - ``d`` -- integer. The dimension. + - ``d`` -- integer; the dimension - - ``n`` -- integer. The number of random inequalities to generate. + - ``n`` -- integer; the number of random inequalities to generate - OUTPUT: - - A random set of inequalities as a :class:`StandardAlgorithm` instance. + OUTPUT: a random set of inequalities as a :class:`StandardAlgorithm` instance EXAMPLES:: @@ -111,7 +109,7 @@ class DoubleDescriptionPair: def __init__(self, problem, A_rows, R_cols): r""" - Base class for a double description pair `(A, R)` + Base class for a double description pair `(A, R)`. .. warning:: @@ -122,13 +120,13 @@ def __init__(self, problem, A_rows, R_cols): INPUT: - - ``problem`` -- instance of :class:`Problem`. + - ``problem`` -- instance of :class:`Problem` - - ``A_rows`` -- list of row vectors of the matrix `A`. These - encode the inequalities. + - ``A_rows`` -- list of row vectors of the matrix `A`; these + encode the inequalities - ``R_cols`` -- list of column vectors of the matrix - `R`. These encode the rays. + `R`; these encode the rays TESTS:: @@ -159,11 +157,11 @@ def _make_new(self, A_rows, R_cols): INPUT: - - ``A_rows`` -- list of row vectors of the matrix `A`. These - encode the inequalities. + - ``A_rows`` -- list of row vectors of the matrix `A`; these + encode the inequalities - ``R_cols`` -- list of column vectors of the matrix - `R`. These encode the rays. + `R`; these encode the rays OUTPUT: @@ -192,9 +190,7 @@ def __repr__(self): r""" Return string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -316,7 +312,7 @@ def R_by_sign(self, a): INPUT: - - ``a`` -- vector. Coefficient vector of a homogeneous inequality. + - ``a`` -- vector; coefficient vector of a homogeneous inequality OUTPUT: @@ -352,11 +348,9 @@ def zero_set(self, ray): INPUT: - - ``ray`` -- a ray vector. - - OUTPUT: + - ``ray`` -- a ray vector - A set containing the inequality vectors that are zero on ``ray``. + OUTPUT: a set containing the inequality vectors that are zero on ``ray`` EXAMPLES:: @@ -427,11 +421,9 @@ def are_adjacent(self, r1, r2): INPUT: - - ``r1``, ``r2`` -- two rays. + - ``r1``, ``r2`` -- two rays - OUTPUT: - - Boolean. Whether the two rays are adjacent. + OUTPUT: boolean; whether the two rays are adjacent EXAMPLES:: @@ -523,14 +515,14 @@ class Problem: def __init__(self, A): r""" - Base class for implementations of the double description algorithm + Base class for implementations of the double description algorithm. It does not make sense to instantiate the base class directly, it just provides helpers for implementations. INPUT: - - ``A`` -- a matrix. The rows of the matrix are interpreted as + - ``A`` -- a matrix; the rows of the matrix are interpreted as homogeneous inequalities `A x \geq 0`. Must have maximal rank. TESTS:: @@ -554,9 +546,7 @@ def A(self): """ Return the rows of the defining matrix `A`. - OUTPUT: - - The matrix `A` whose rows are the inequalities. + OUTPUT: the matrix `A` whose rows are the inequalities EXAMPLES:: @@ -574,9 +564,7 @@ def A_matrix(self): """ Return the defining matrix `A`. - OUTPUT: - - Matrix whose rows are the inequalities. + OUTPUT: matrix whose rows are the inequalities EXAMPLES:: @@ -592,9 +580,7 @@ def base_ring(self): """ Return the base field. - OUTPUT: - - A field. + OUTPUT: a field EXAMPLES:: @@ -610,9 +596,7 @@ def dim(self): """ Return the ambient space dimension. - OUTPUT: - - Integer. The ambient space dimension of the cone. + OUTPUT: integer; the ambient space dimension of the cone EXAMPLES:: @@ -627,9 +611,7 @@ def __repr__(self): r""" Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -650,7 +632,7 @@ def initial_pair(self): INPUT: - ``pair_class`` -- subclass of - :class:`DoubleDescriptionPair`. + :class:`DoubleDescriptionPair` OUTPUT: @@ -694,7 +676,7 @@ def add_inequality(self, a): INPUT: - - ``a`` -- vector. An inequality. + - ``a`` -- vector; an inequality EXAMPLES:: @@ -722,9 +704,10 @@ def add_inequality(self, a): self.R = R_pos + R_nul + R_new self.A.append(a) + class StandardAlgorithm(Problem): """ - Standard implementation of the double description algorithm + Standard implementation of the double description algorithm. See [FP1996]_ for the definition of the "Standard Algorithm". diff --git a/src/sage/geometry/polyhedron/double_description_inhomogeneous.py b/src/sage/geometry/polyhedron/double_description_inhomogeneous.py index 9b7882a5bcd..873b3b431ea 100644 --- a/src/sage/geometry/polyhedron/double_description_inhomogeneous.py +++ b/src/sage/geometry/polyhedron/double_description_inhomogeneous.py @@ -16,7 +16,7 @@ implementation is general and works with any field in Sage that allows you to define polyhedra. -.. note:: +.. NOTE:: If you just want polyhedra over arbitrary fields then you should just use the @@ -66,13 +66,13 @@ class PivotedInequalities(SageObject): def __init__(self, base_ring, dim): """ - Base class for inequalities that may contain linear subspaces + Base class for inequalities that may contain linear subspaces. INPUT: - - ``base_ring`` -- a field. + - ``base_ring`` -- a field - - ``dim`` -- integer. The ambient space dimension. + - ``dim`` -- integer; the ambient space dimension EXAMPLES:: @@ -98,11 +98,9 @@ def _pivot_inequalities(self, A): INPUT: - - ``A`` -- matrix. The inequalities. + - ``A`` -- matrix; the inequalities - OUTPUT: - - The matrix of pivot columns. + OUTPUT: the matrix of pivot columns EXAMPLES:: @@ -125,11 +123,9 @@ def _unpivot_ray(self, ray): INPUT: - - ``ray`` -- ray in the pivoted coordinates. - - OUTPUT: + - ``ray`` -- ray in the pivoted coordinates - Ray in the original coordinates. + OUTPUT: ray in the original coordinates EXAMPLES:: @@ -156,15 +152,15 @@ def __init__(self, base_ring, dim, inequalities, equations): INPUT: - - ``base_ring`` -- a field. + - ``base_ring`` -- a field - - ``dim`` -- integer. The ambient space dimension. + - ``dim`` -- integer; the ambient space dimension - - ``inequalities`` -- list of inequalities. Each inequality - is given as constant term, ``dim`` coefficients. + - ``inequalities`` -- list of inequalities; each inequality + is given as constant term, ``dim`` coefficients - - ``equations`` -- list of equations. Same notation as for - inequalities. + - ``equations`` -- list of equations; same notation as for + inequalities EXAMPLES:: @@ -213,15 +209,13 @@ def __init__(self, base_ring, dim, inequalities, equations): def _init_Vrep(self, inequalities, equations): """ - Split off the linear subspace from the inequalities and select pivots + Split off the linear subspace from the inequalities and select pivots. INPUT: - - ``inequalities``, ``equations`` -- see :class:`Vrep2Hrep`. + - ``inequalities``, ``equations`` -- see :class:`Vrep2Hrep` - OUTPUT: - - The pivoted inequalities. + OUTPUT: the pivoted inequalities TESTS:: @@ -285,7 +279,7 @@ def _extract_Vrep(self, DD): INPUT: - ``DD`` -- a - :class:`~sage.geometry.polyhedron.double_description.DoubleDescriptionPair`. + :class:`~sage.geometry.polyhedron.double_description.DoubleDescriptionPair` TESTS:: @@ -355,7 +349,7 @@ def verify(self, inequalities, equations): INPUT: - - ``inequalities``, ``equations`` -- see :class:`Hrep2Vrep`. + - ``inequalities``, ``equations`` -- see :class:`Hrep2Vrep` EXAMPLES:: @@ -388,18 +382,18 @@ def __init__(self, base_ring, dim, vertices, rays, lines): INPUT: - - ``base_ring`` -- a field. + - ``base_ring`` -- a field - - ``dim`` -- integer. The ambient space dimension. + - ``dim`` -- integer; the ambient space dimension - - ``vertices`` -- list of vertices. Each vertex is given as - list of ``dim`` coordinates. + - ``vertices`` -- list of vertices; each vertex is given as + list of ``dim`` coordinates - - ``rays`` -- list of rays. Each ray is given as - list of ``dim`` coordinates, not all zero. + - ``rays`` -- list of rays; each ray is given as + list of ``dim`` coordinates, not all zero - - ``lines`` -- list of line generators. Each line is given as - list of ``dim`` coordinates, not all zero. + - ``lines`` -- list of line generators; each line is given as + list of ``dim`` coordinates, not all zero EXAMPLES:: @@ -465,11 +459,9 @@ def _init_Vrep(self, vertices, rays, lines): INPUT: - - ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep`. - - OUTPUT: + - ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep` - Matrix of pivoted inequalities for the dual homogenized cone. + OUTPUT: matrix of pivoted inequalities for the dual homogenized cone TESTS:: @@ -497,7 +489,7 @@ def _extract_Hrep(self, DD): INPUT: - ``DD`` -- a - :class:`~sage.geometry.polyhedron.double_description.DoubleDescriptionPair`. + :class:`~sage.geometry.polyhedron.double_description.DoubleDescriptionPair` EXAMPLES:: @@ -520,9 +512,7 @@ def _repr_(self): r""" Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -548,7 +538,7 @@ def verify(self, vertices, rays, lines): INPUT: - - ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep`. + - ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/face.py b/src/sage/geometry/polyhedron/face.py index 97319ed1740..1f1969353a2 100644 --- a/src/sage/geometry/polyhedron/face.py +++ b/src/sage/geometry/polyhedron/face.py @@ -96,9 +96,7 @@ class PolyhedronFace(ConvexSet_closed): manually create :class:`PolyhedronFace` objects unless you know what you are doing. - OUTPUT: - - A :class:`PolyhedronFace`. + OUTPUT: a :class:`PolyhedronFace` EXAMPLES:: @@ -134,16 +132,16 @@ def __init__(self, polyhedron, V_indices, H_indices): INPUT: - - ``polyhedron`` -- a :class:`Polyhedron`. The ambient - polyhedron. + - ``polyhedron`` -- a :class:`Polyhedron`; the ambient + polyhedron - - ``V_indices`` -- list of sorted integers. The indices of the + - ``V_indices`` -- list of sorted integers; the indices of the face-spanning V-representation objects in the ambient - polyhedron. + polyhedron - - ``H_indices`` -- list of sorted integers. The indices of the + - ``H_indices`` -- list of sorted integers; the indices of the H-representation objects of the ambient polyhedron that are - saturated on the face. + saturated on the face TESTS:: @@ -200,9 +198,7 @@ def vertices(self): """ Return all vertices of the face. - OUTPUT: - - A tuple of vertices. + OUTPUT: a tuple of vertices EXAMPLES:: @@ -222,9 +218,7 @@ def n_vertices(self): """ Return the number of vertices of the face. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -263,9 +257,7 @@ def rays(self): """ Return the rays of the face. - OUTPUT: - - A tuple of rays. + OUTPUT: a tuple of rays EXAMPLES:: @@ -281,9 +273,7 @@ def n_rays(self): """ Return the number of rays of the face. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -318,9 +308,7 @@ def lines(self): """ Return all lines of the face. - OUTPUT: - - A tuple of lines. + OUTPUT: a tuple of lines EXAMPLES:: @@ -335,9 +323,7 @@ def n_lines(self): """ Return the number of lines of the face. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -353,7 +339,7 @@ def __richcmp__(self, other, op): INPUT: - - ``other`` -- anything. + - ``other`` -- anything OUTPUT: @@ -389,8 +375,7 @@ def ambient_Hrepresentation(self, index=None): INPUT: - - ``index`` -- optional. Either an integer or ``None`` - (default). + - ``index`` -- integer or ``None`` (default) OUTPUT: @@ -430,8 +415,7 @@ def ambient_Vrepresentation(self, index=None): INPUT: - - ``index`` -- optional. Either an integer or ``None`` - (default). + - ``index`` -- integer or ``None`` (default) OUTPUT: @@ -471,9 +455,7 @@ def n_ambient_Hrepresentation(self): See also :meth:`ambient_Hrepresentation`. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -497,9 +479,7 @@ def n_ambient_Vrepresentation(self): See also :meth:`ambient_Vrepresentation`. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -520,9 +500,7 @@ def ambient_H_indices(self): See also :meth:`ambient_Hrepresentation`. - OUTPUT: - - Tuple of indices + OUTPUT: tuple of indices EXAMPLES:: @@ -551,9 +529,7 @@ def ambient_V_indices(self): See also :meth:`ambient_Vrepresentation`. - OUTPUT: - - Tuple of indices + OUTPUT: tuple of indices EXAMPLES:: @@ -587,9 +563,7 @@ def dim(self): """ Return the dimension of the face. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -621,9 +595,7 @@ def _repr_(self): r""" Return a string representation. - OUTPUT: - - A string listing the V-representation indices of the face. + OUTPUT: a string listing the V-representation indices of the face EXAMPLES:: @@ -695,7 +667,7 @@ def ambient_vector_space(self, base_field=None): INPUT: - - ``base_field`` -- (default: the fraction field of the base ring) a field. + - ``base_field`` -- a field (default: the fraction field of the base ring) EXAMPLES:: @@ -714,7 +686,7 @@ def is_relatively_open(self): r""" Return whether ``self`` is relatively open. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -731,7 +703,7 @@ def is_compact(self): r""" Return whether ``self`` is compact. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -750,9 +722,7 @@ def as_polyhedron(self, **kwds): """ Return the face as an independent polyhedron. - OUTPUT: - - A polyhedron. + OUTPUT: a polyhedron EXAMPLES:: @@ -851,13 +821,11 @@ def normal_cone(self, direction='outer'): INPUT: - - ``direction`` -- string (default: ``'outer'``), the direction in + - ``direction`` -- string (default: ``'outer'``); the direction in which to consider the normals. The other allowed option is ``'inner'``. - OUTPUT: - - A polyhedron. + OUTPUT: a polyhedron EXAMPLES:: @@ -933,9 +901,7 @@ def affine_tangent_cone(self): It is equal to the sum of ``self`` and the cone of feasible directions at any point of the relative interior of ``self``. - OUTPUT: - - A polyhedron. + OUTPUT: a polyhedron EXAMPLES:: @@ -983,9 +949,7 @@ def stacking_locus(self): Return the polyhedron containing the points that sees every facet containing ``self``. - OUTPUT: - - A polyhedron. + OUTPUT: a polyhedron EXAMPLES:: @@ -1027,6 +991,7 @@ def stacking_locus(self): return parent.element_class(parent, None, [locus_ieqs, locus_eqns]) + def combinatorial_face_to_polyhedral_face(polyhedron, combinatorial_face): r""" Convert a combinatorial face to a face of a polyhedron. @@ -1036,7 +1001,7 @@ def combinatorial_face_to_polyhedral_face(polyhedron, combinatorial_face): - ``polyhedron`` -- a polyhedron containing ``combinatorial_face`` - ``combinatorial_face`` -- a :class:`CombinatorialFace` - OUTPUT: a :class:`PolyhedronFace`. + OUTPUT: a :class:`PolyhedronFace` EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/generating_function.py b/src/sage/geometry/polyhedron/generating_function.py index 89d86058c2d..c4bece2af55 100644 --- a/src/sage/geometry/polyhedron/generating_function.py +++ b/src/sage/geometry/polyhedron/generating_function.py @@ -91,7 +91,7 @@ def generating_function_of_integral_points(polyhedron, split=False, The variable names of the Laurent polynomial ring of the output are this string followed by an integer. - - ``names`` -- a list or tuple of names (strings), or a comma separated string + - ``names`` -- list or tuple of names (strings), or a comma separated string ``name`` is extracted from ``names``, therefore ``names`` has to contain exactly one variable name, and ``name`` and``names`` cannot be specified @@ -535,7 +535,7 @@ def ieqs_repr_lhs(pi): ieqs, repr_rhss = zip(*[(ieq(a, b), ieq_repr_rhs(a, b)) for a, b in zip(pi[:-1], pi[1:])]) - return Polyhedron(ieqs=ieqs), ieqs_repr_lhs(pi) + ''.join(repr_rhss) + return Polyhedron(ieqs=ieqs), ieqs_repr_lhs(pi) + ''.join(repr_rhss) split = (polyhedron_from_permutation(pi) for pi in Permutations(d)) parts = ZZ(d).factorial() @@ -680,7 +680,7 @@ def __generating_function_of_integral_points__( if sort_factors: def key(t): - D = t.dict().popitem()[0] + D = t.monomial_coefficients().popitem()[0] return (-sum(abs(d) for d in D), D) terms = sorted(terms, key=key, reverse=True) return Factorization([(numerator, 1)] + @@ -697,19 +697,17 @@ def _generating_function_via_Omega_(inequalities, B, skip_indices=()): INPUT: - - ``inequalities`` -- a list or other iterable of tuples - of numbers. + - ``inequalities`` -- list or other iterable of tuples + of numbers - ``B`` -- a Laurent polynomial ring - - ``skip_indices`` -- a list or tuple of indices + - ``skip_indices`` -- list or tuple of indices The variables corresponding to ``skip_indices`` are not handled (e.g. because they are determined by an equation). - OUTPUT: - - A pair of + OUTPUT: a pair of - a Laurent polynomial specifying the numerator and @@ -750,7 +748,7 @@ def _generating_function_via_Omega_(inequalities, B, skip_indices=()): logger.debug('terms denominator %s', terms) def decode_factor(factor): - D = factor.dict() + D = factor.monomial_coefficients() assert len(D) == 1 exponent, coefficient = next(iter(D.items())) return coefficient, exponent @@ -766,7 +764,7 @@ def decode_factor(factor): lambda factor: factor[1] == 0) other_factors = tuple(factor[0] for factor in other_factors) numerator, factors_denominator = \ - _Omega_(numerator.dict(), tuple(decoded_factors)) + _Omega_(numerator.monomial_coefficients(), tuple(decoded_factors)) terms = other_factors + factors_denominator return _simplify_(numerator, terms) @@ -780,9 +778,9 @@ class _TransformHrepresentation: INPUT: - - ``inequalities`` -- a list of tuples of numbers + - ``inequalities`` -- list of tuples of numbers - - ``equations`` -- a list of tuples of numbers + - ``equations`` -- list of tuples of numbers - ``B`` -- a Laurent polynomial ring @@ -798,7 +796,7 @@ class _TransformHrepresentation: The numerator of the generating function has to be multiplied with ``factor`` *after* substituting ``rules``. - - ``rules`` -- a dictionary mapping Laurent polynomial variables to + - ``rules`` -- dictionary mapping Laurent polynomial variables to Laurent polynomials Substitute ``rules`` into the generating function. @@ -854,7 +852,7 @@ def apply_rules(self, numerator, terms): - ``numerator`` -- a Laurent polynomial - - ``terms`` -- a tuple or other iterable of Laurent polynomials + - ``terms`` -- tuple or other iterable of Laurent polynomials The denominator is the product of factors `1 - t` for each `t` in ``terms``. @@ -887,9 +885,9 @@ class _SplitOffSimpleInequalities(_TransformHrepresentation): INPUT: - - ``inequalities`` -- a list of tuples of numbers + - ``inequalities`` -- list of tuples of numbers - - ``equations`` -- a list of tuples of numbers + - ``equations`` -- list of tuples of numbers - ``B`` -- a Laurent polynomial ring @@ -905,7 +903,7 @@ class _SplitOffSimpleInequalities(_TransformHrepresentation): The numerator of the generating function has to be multiplied with ``factor`` *after* substituting ``rules``. - - ``rules`` -- a dictionary mapping Laurent polynomial variables to + - ``rules`` -- dictionary mapping Laurent polynomial variables to Laurent polynomials Substitute ``rules`` into the generating function. @@ -1197,9 +1195,9 @@ class _EliminateByEquations(_TransformHrepresentation): INPUT: - - ``inequalities`` -- a list of tuples of numbers + - ``inequalities`` -- list of tuples of numbers - - ``equations`` -- a list of tuples of numbers + - ``equations`` -- list of tuples of numbers - ``B`` -- a Laurent polynomial ring @@ -1215,7 +1213,7 @@ class _EliminateByEquations(_TransformHrepresentation): The numerator of the generating function has to be multiplied with ``factor`` *after* substituting ``rules``. - - ``rules`` -- a dictionary mapping Laurent polynomial variables to + - ``rules`` -- dictionary mapping Laurent polynomial variables to Laurent polynomials Substitute ``rules`` into the generating function. @@ -1325,7 +1323,7 @@ def prepare_equations_transformation(E): - ``indicesn`` -- a sorted tuple of integers representing column indices ``indicesn`` contains ``0`` and all indices of the columns of ``E`` - which are non-zero. + which are nonzero. TESTS:: @@ -1365,13 +1363,13 @@ class _TransformMod(_TransformHrepresentation): INPUT: - - ``inequalities`` -- a list of tuples of numbers + - ``inequalities`` -- list of tuples of numbers - - ``equations`` -- a list of tuples of numbers + - ``equations`` -- list of tuples of numbers - ``B`` -- a Laurent polynomial ring - - ``mod`` -- a dictionary mapping an index ``i`` to ``(m, r)`` + - ``mod`` -- dictionary mapping an index ``i`` to ``(m, r)`` This is one entry of the output tuple of :meth:`generate_mods`. @@ -1387,7 +1385,7 @@ class _TransformMod(_TransformHrepresentation): The numerator of the generating function has to be multiplied with ``factor`` *after* substituting ``rules``. - - ``rules`` -- a dictionary mapping Laurent polynomial variables to + - ``rules`` -- dictionary mapping Laurent polynomial variables to Laurent polynomials Substitute ``rules`` into the generating function. @@ -1478,7 +1476,7 @@ def generate_mods(equations): INPUT: - - ``equations`` -- a list of tuples + - ``equations`` -- list of tuples OUTPUT: @@ -1531,7 +1529,7 @@ def _compositions_mod(u, m, r=0, multidimensional=False): - ``m`` -- the modulus as a positive integer - - ``multidimensional`` -- (default: ``False``) a boolean + - ``multidimensional`` -- boolean (default: ``False``) If ``multidimensional=False``: diff --git a/src/sage/geometry/polyhedron/lattice_euclidean_group_element.py b/src/sage/geometry/polyhedron/lattice_euclidean_group_element.py index 79331133960..6d26a0ff267 100644 --- a/src/sage/geometry/polyhedron/lattice_euclidean_group_element.py +++ b/src/sage/geometry/polyhedron/lattice_euclidean_group_element.py @@ -85,11 +85,11 @@ def __init__(self, A, b): def __call__(self, x): """ - Return the image of ``x`` + Return the image of ``x``. INPUT: - - ``x`` -- a vector or lattice polytope. + - ``x`` -- a vector or lattice polytope EXAMPLES:: @@ -115,7 +115,7 @@ def __call__(self, x): def _repr_(self): r""" - Return a string representation + Return a string representation. EXAMPLES:: @@ -130,7 +130,7 @@ def _repr_(self): def domain_dim(self): """ - Return the dimension of the domain lattice + Return the dimension of the domain lattice. EXAMPLES:: @@ -150,7 +150,7 @@ def domain_dim(self): def codomain_dim(self): """ - Return the dimension of the codomain lattice + Return the dimension of the codomain lattice. EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 6ea6e5c32be..5c58abb9564 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -91,6 +91,7 @@ lazy_import('sage.graphs.graph', 'Graph') lazy_import('sage.combinat.root_system.associahedron', 'Associahedron') + def zero_sum_projection(d, base_ring=None): r""" Return a matrix corresponding to the projection on the orthogonal of @@ -119,7 +120,6 @@ def zero_sum_projection(d, base_ring=None): sage: zero_sum_projection(3, base_ring=AA) # needs sage.rings.number_field [ 0.7071067811865475? -0.7071067811865475? 0] [ 0.4082482904638630? 0.4082482904638630? -0.8164965809277260?] - """ from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector @@ -135,10 +135,10 @@ def project_points(*points, **kwds): INPUT: - - ``points``... -- the points to project. + - ``points``... -- the points to project - ``base_ring`` -- (defaults to ``RDF`` if keyword is ``None`` or not - provided in ``kwds``) the base ring to use. + provided in ``kwds``) the base ring to use The projection is isometric to the orthogonal projection on the hyperplane made of zero sum vector. Hence, if the set of points have all equal sums, @@ -183,7 +183,6 @@ def project_points(*points, **kwds): sage: for i in range(len(V)): # needs sage.combinat sage.rings.number_field ....: for j in range(len(V)): ....: assert (V[i]-V[j]).norm() == (P[i]-P[j]).norm() - """ if not points: return [] @@ -208,10 +207,10 @@ def gale_transform_to_polytope(vectors, base_ring=None, backend=None): - ``vectors`` -- the vectors of the Gale transform - - ``base_ring`` -- string (default: `None`); + - ``base_ring`` -- string (default: ``None``); the base ring to be used for the construction - - ``backend`` -- string (default: `None`); + - ``backend`` -- string (default: ``None``); the backend to use to create the polytope .. NOTE:: @@ -321,6 +320,7 @@ def gale_transform_to_polytope(vectors, base_ring=None, backend=None): return P + def gale_transform_to_primal(vectors, base_ring=None, backend=None): r""" Return a point configuration dual to a totally cyclic vector configuration. @@ -333,15 +333,15 @@ def gale_transform_to_primal(vectors, base_ring=None, backend=None): - ``vectors`` -- the ordered vectors of the Gale transform - - ``base_ring`` -- string (default: `None`); + - ``base_ring`` -- string (default: ``None``); the base ring to be used for the construction - - ``backend`` -- string (default: `None`); + - ``backend`` -- string (default: ``None``); the backend to be use to construct a polyhedral, used internally in case the center is not the origin, see :func:`~sage.geometry.polyhedron.constructor.Polyhedron` - OUTPUT: An ordered point configuration as list of vectors. + OUTPUT: an ordered point configuration as list of vectors .. NOTE:: @@ -500,17 +500,17 @@ def regular_polygon(self, n, exact=True, base_ring=None, backend=None): INPUT: - - ``n`` -- a positive integer, the number of vertices. + - ``n`` -- positive integer; the number of vertices - - ``exact`` -- (boolean, default ``True``) if ``False`` floating point - numbers are used for coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` floating point + numbers are used for coordinates - ``base_ring`` -- a ring in which the coordinates will lie. It is ``None`` by default. If it is not provided and ``exact`` is ``True`` then it will be the field of real algebraic number, if ``exact`` is ``False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -579,9 +579,9 @@ def Birkhoff_polytope(self, n, backend=None): INPUT: - - ``n`` -- a positive integer giving the size of the permutation matrices. + - ``n`` -- positive integer giving the size of the permutation matrices - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope .. SEEALSO:: @@ -632,21 +632,21 @@ def simplex(self, dim=3, project=False, base_ring=None, backend=None): INPUT: - - ``dim`` -- The dimension of the simplex, a positive - integer. + - ``dim`` -- the dimension of the simplex, a positive + integer - - ``project`` -- (boolean, default ``False``) if ``True``, the polytope + - ``project`` -- boolean (default: ``False``); if ``True``, the polytope is (isometrically) projected to a vector space of dimension ``dim-1``. This corresponds to the projection given by the matrix from :func:`zero_sum_projection`. By default, this operation turns the coordinates into floating point approximations (see ``base_ring``). - - ``base_ring`` -- the base ring to use to create the polytope. - If ``project`` is ``False``, this defaults to `\ZZ`. + - ``base_ring`` -- the base ring to use to create the polytope; + if ``project`` is ``False``, this defaults to `\ZZ`. Otherwise, it defaults to ``RDF``. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope .. SEEALSO:: @@ -705,8 +705,8 @@ def icosahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- (optional) the ring in which the coordinates will belong to. Note that this ring must contain `\sqrt(5)`. If it is not @@ -714,7 +714,7 @@ def icosahedron(self, exact=True, base_ring=None, backend=None): `\QQ[\sqrt(5)]` and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -759,8 +759,7 @@ def icosahedron(self, exact=True, base_ring=None, backend=None): sage: TestSuite(ico).run() sage: ico = polytopes.icosahedron(exact=False) # needs sage.groups - sage: TestSuite(ico).run(skip="_test_lawrence") # needs sage.groups - + sage: TestSuite(ico).run(skip='_test_lawrence') # needs sage.groups """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -788,8 +787,8 @@ def dodecahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- (optional) the ring in which the coordinates will belong to. Note that this ring must contain `\sqrt(5)`. If it is not @@ -797,7 +796,7 @@ def dodecahedron(self, exact=True, base_ring=None, backend=None): `\QQ[\sqrt(5)]` and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -839,15 +838,15 @@ def small_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -911,15 +910,15 @@ def great_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -969,7 +968,7 @@ def rhombic_dodecahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope .. SEEALSO:: @@ -1017,7 +1016,7 @@ def cuboctahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope .. SEEALSO:: @@ -1065,15 +1064,15 @@ def truncated_cube(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\sqrt{2}]` and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1099,7 +1098,6 @@ def truncated_cube(self, exact=True, base_ring=None, backend=None): sage: co.f_vector() # optional - pynormaliz # needs sage.rings.number_field (1, 24, 36, 14, 1) sage: TestSuite(co).run() # optional - pynormaliz # needs sage.rings.number_field - """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -1129,7 +1127,7 @@ def tetrahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope .. SEEALSO:: @@ -1173,7 +1171,7 @@ def truncated_tetrahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1219,7 +1217,7 @@ def truncated_octahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1263,7 +1261,7 @@ def octahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1306,15 +1304,15 @@ def snub_cube(self, exact=False, base_ring=None, backend=None, verbose=False): INPUT: - - ``exact`` -- (boolean, default ``False``) if ``True`` use exact + - ``exact`` -- boolean (default: ``False``); if ``True`` use exact coordinates instead of floating point approximations - - ``base_ring`` -- the field to use. If ``None`` (the default), + - ``base_ring`` -- the field to use; if ``None`` (the default), construct the exact number field needed (if ``exact`` is ``True``) or - default to ``RDF`` (if ``exact`` is ``True``). + default to ``RDF`` (if ``exact`` is ``True``) - - ``backend`` -- the backend to use to create the polytope. If - ``None`` (the default), the backend will be selected automatically. + - ``backend`` -- the backend to use to create the polytope; if + ``None`` (the default), the backend will be selected automatically EXAMPLES:: @@ -1361,7 +1359,6 @@ def snub_cube(self, exact=False, base_ring=None, backend=None, verbose=False): sage: sc = polytopes.snub_cube(exact=True, backend='normaliz') # optional - pynormaliz, needs sage.groups sage.rings.number_field sage: sc.f_vector() # optional - pynormaliz, needs sage.groups sage.rings.number_field (1, 24, 60, 38, 1) - """ def construct_z(field): # z here is the reciprocal of the tribonacci constant, that is, the @@ -1412,15 +1409,15 @@ def buckyball(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1455,7 +1452,6 @@ def buckyball(self, exact=True, base_ring=None, backend=None): sage: bb.base_ring() Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - """ return self.icosahedron(exact=exact, base_ring=base_ring, backend=backend).truncation() @@ -1469,10 +1465,10 @@ def icosidodecahedron(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1530,19 +1526,19 @@ def icosidodecahedron_V2(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - - ``base_ring`` -- the ring in which the coordinates will belong to. + - ``base_ring`` -- the ring in which the coordinates will belong to If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: - sage: id = polytopes.icosidodecahedron_V2() # long time - 6secs + sage: id = polytopes.icosidodecahedron_V2() # long time (6s) sage: id.f_vector() # long time (1, 30, 60, 32, 1) sage: id.base_ring() # long time @@ -1604,15 +1600,15 @@ def truncated_dodecahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1657,7 +1653,6 @@ def truncated_dodecahedron(self, exact=True, base_ring=None, backend=None): sage: td.base_ring() Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -1693,19 +1688,19 @@ def pentakis_dodecahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: - sage: pd = polytopes.pentakis_dodecahedron() # long time - ~10 sec + sage: pd = polytopes.pentakis_dodecahedron() # long time (10s) sage: pd.n_vertices() # long time 32 sage: pd.n_inequalities() # long time @@ -1736,7 +1731,7 @@ def Kirkman_icosahedron(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1775,15 +1770,15 @@ def rhombicosidodecahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1820,7 +1815,6 @@ def rhombicosidodecahedron(self, exact=True, base_ring=None, backend=None): sage: rid.base_ring() Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -1855,15 +1849,15 @@ def truncated_icosidodecahedron(self, exact=True, base_ring=None, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) If ``False`` use an - approximate ring for the coordinates. + - ``exact`` -- boolean (default: ``True``); if ``False`` use an + approximate ring for the coordinates - ``base_ring`` -- the ring in which the coordinates will belong to. If it is not provided and ``exact=True`` it will be a the number field `\QQ[\phi]` where `\phi` is the golden ratio and if ``exact=False`` it will be the real double field. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -1898,7 +1892,6 @@ def truncated_icosidodecahedron(self, exact=True, base_ring=None, backend=None): (1, 120, 180, 62, 1) sage: ti.base_ring() # optional - pynormaliz Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -1937,10 +1930,10 @@ def snub_dodecahedron(self, base_ring=None, backend=None, verbose=False): INPUT: - - ``base_ring`` -- the ring in which the coordinates will belong to. If - it is not provided it will be the real double field. + - ``base_ring`` -- the ring in which the coordinates will belong to; if + it is not provided it will be the real double field - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES: @@ -1973,7 +1966,6 @@ def snub_dodecahedron(self, base_ring=None, backend=None, verbose=False): (1, 60, 150, 92, 1) sage: sd.base_ring() # not tested Real Double Field - """ if base_ring is None: from sage.rings.real_double import RDF as base_ring @@ -2012,7 +2004,7 @@ def twenty_four_cell(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2061,10 +2053,10 @@ def runcitruncated_six_hundred_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2090,10 +2082,10 @@ def cantitruncated_six_hundred_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2119,10 +2111,10 @@ def bitruncated_six_hundred_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2148,10 +2140,10 @@ def cantellated_six_hundred_cell(self, exact=False, backend=None): INPUT: - - ``exact`` -- (boolean, default ``False``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``False``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2188,10 +2180,10 @@ def truncated_six_hundred_cell(self, exact=False, backend=None): INPUT: - - ``exact`` -- (boolean, default ``False``) if ``True`` use exact + - ``exact`` -- boolean (default: ``False``); if ``True`` use exact coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2201,7 +2193,7 @@ def truncated_six_hundred_cell(self, exact=False, backend=None): It is possible to use the backend ``'normaliz'`` to get an exact representation:: - sage: polytopes.truncated_six_hundred_cell(exact=True,backend='normaliz') # not tested - long time ~16sec + sage: polytopes.truncated_six_hundred_cell(exact=True,backend='normaliz') # not tested, long time (16s) A 4-dimensional polyhedron in AA^4 defined as the convex hull of 1440 vertices """ return self.generalized_permutahedron(['H', 4], point=[1, 1, 0, 0], exact=exact, backend=backend, regular=True) @@ -2222,14 +2214,14 @@ def rectified_six_hundred_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: - sage: polytopes.rectified_six_hundred_cell(backend='normaliz') # not tested - long time ~14sec + sage: polytopes.rectified_six_hundred_cell(backend='normaliz') # not tested, long time (14s) A 4-dimensional polyhedron in AA^4 defined as the convex hull of 720 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 1, 0, 0], exact=exact, backend=backend, regular=True) @@ -2248,10 +2240,10 @@ def six_hundred_cell(self, exact=False, backend=None): INPUT: - - ``exact`` -- (boolean, default ``False``) if ``True`` use exact + - ``exact`` -- boolean (default: ``False``); if ``True`` use exact coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2312,10 +2304,10 @@ def grand_antiprism(self, exact=True, backend=None, verbose=False): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``False`` use floating + - ``exact`` -- boolean (default: ``True``); if ``False`` use floating point approximations instead of exact coordinates - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2398,7 +2390,7 @@ def Gosset_3_21(self, backend=None): INPUT: - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2433,13 +2425,13 @@ def cyclic_polytope(self, dim, n, base_ring=QQ, backend=None): INPUT: - - ``dim`` -- positive integer. the dimension of the polytope. + - ``dim`` -- positive integer; the dimension of the polytope - - ``n`` -- positive integer. the number of vertices. + - ``n`` -- positive integer; the number of vertices - - ``base_ring`` -- either ``QQ`` (default) or ``RDF``. + - ``base_ring`` -- either ``QQ`` (default) or ``RDF`` - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2474,13 +2466,13 @@ def hypersimplex(self, dim, k, project=False, backend=None): - ``n`` -- the numbers ``(1,...,n)`` are permuted - - ``project`` -- (boolean, default ``False``) if ``True``, the polytope + - ``project`` -- boolean (default: ``False``); if ``True``, the polytope is (isometrically) projected to a vector space of dimension ``dim-1``. This operation turns the coordinates into floating point approximations and corresponds to the projection given by the matrix from :func:`zero_sum_projection`. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2525,13 +2517,13 @@ def permutahedron(self, n, project=False, backend=None): - ``n`` -- integer - - ``project`` -- (boolean, default ``False``) if ``True``, the polytope + - ``project`` -- boolean (default: ``False``); if ``True``, the polytope is (isometrically) projected to a vector space of dimension ``dim-1``. This operation turns the coordinates into floating point approximations and corresponds to the projection given by the matrix from :func:`zero_sum_projection`. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2595,7 +2587,7 @@ def tri(m): eqns = ((-tri(n),) + tuple(1 for _ in range(n)),) return parent([verts, [], []], [ieqs, eqns], - Vrep_minimal=True, Hrep_minimal=True, pref_rep="Hrep") + Vrep_minimal=True, Hrep_minimal=True, pref_rep='Hrep') def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regular=False, backend=None): r""" @@ -2609,17 +2601,17 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula INPUT: - ``coxeter_type`` -- a Coxeter type; given as a pair [type,rank], - where type is a letter and rank is the number of generators. + where type is a letter and rank is the number of generators - - ``point`` -- a list (default: ``None``); a point given by its + - ``point`` -- list (default: ``None``); a point given by its coordinates in the weight basis. If ``None`` is given, the point `(1, 1, 1, \ldots)` is used. - - ``exact`` -- (boolean, default ``True``) if ``False`` use floating + - ``exact`` -- boolean (default: ``True``); if ``False`` use floating point approximations instead of exact coordinates - ``regular`` -- boolean (default: ``False``); whether to apply a - linear transformation making the vertex figures isometric. + linear transformation making the vertex figures isometric - ``backend`` -- backend to use to create the polytope; (default: ``None``) @@ -2855,10 +2847,10 @@ def omnitruncated_one_hundred_twenty_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2888,10 +2880,10 @@ def runcitruncated_one_hundred_twenty_cell(self, exact=False, backend=None): INPUT: - - ``exact`` -- (boolean, default ``False``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``False``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2928,10 +2920,10 @@ def cantitruncated_one_hundred_twenty_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2956,10 +2948,10 @@ def runcinated_one_hundred_twenty_cell(self, exact=False, backend=None): INPUT: - - ``exact`` -- (boolean, default ``False``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``False``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -2995,10 +2987,10 @@ def cantellated_one_hundred_twenty_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -3023,10 +3015,10 @@ def truncated_one_hundred_twenty_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -3051,10 +3043,10 @@ def rectified_one_hundred_twenty_cell(self, exact=True, backend=None): INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -3079,19 +3071,19 @@ def one_hundred_twenty_cell(self, exact=True, backend=None, construction='coxete INPUT: - - ``exact`` -- (boolean, default ``True``) if ``True`` use exact - coordinates instead of floating point approximations. + - ``exact`` -- boolean (default: ``True``); if ``True`` use exact + coordinates instead of floating point approximations - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope - - ``construction`` -- the construction to use (string, default 'coxeter'); - the other possibility is 'as_permutahedron'. + - ``construction`` -- string (default: ``'coxeter'``); the construction to use. + The other possibility is 'as_permutahedron'. EXAMPLES: The classical construction given by Coxeter in [Cox1969]_ is given by:: - sage: polytopes.one_hundred_twenty_cell() # not tested - long time ~15 sec. + sage: polytopes.one_hundred_twenty_cell() # not tested, long time (~15s) A 4-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^4 defined as the convex hull of 600 vertices @@ -3168,21 +3160,21 @@ def hypercube(self, dim, intervals=None, backend=None): INPUT: - - ``dim`` -- integer. The dimension of the hypercube. + - ``dim`` -- integer; the dimension of the hypercube - - ``intervals`` -- (default = None). It takes the following + - ``intervals`` -- (default: ``None``) it takes the following possible inputs: - If ``None`` (the default), it returns the `\pm 1`-cube of dimension ``dim``. - - ``'zero_one'`` -- (string). Return the `0/1`-cube. + - ``'zero_one'`` -- string; return the `0/1`-cube - a list of length ``dim``. Its elements are pairs of numbers `(a,b)` with `a < b`. The cube will be the product of these intervals. - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES: @@ -3356,16 +3348,14 @@ def cube(self, intervals=None, backend=None): - If the input is ``None`` (the default), returns the convex hull of the eight `\pm 1` vectors of length three. - - ``'zero_one'`` -- (string). Return the `0/1`-cube. + - ``'zero_one'`` -- string; return the `0/1`-cube - a list of 3 lists of length 2. The cube will be a product of these three intervals. - - ``backend`` -- the backend to use to create the polytope. - - OUTPUT: + - ``backend`` -- the backend to use to create the polytope - A cube as a polyhedron object. + OUTPUT: a cube as a polyhedron object EXAMPLES: @@ -3407,9 +3397,9 @@ def cross_polytope(self, dim, backend=None): INPUT: - - ``dim`` -- integer. The dimension of the cross-polytope. + - ``dim`` -- integer; the dimension of the cross-polytope - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: @@ -3451,9 +3441,9 @@ def parallelotope(self, generators, backend=None): INPUT: - - ``generators`` -- a list of vectors of same dimension + - ``generators`` -- list of vectors of same dimension - - ``backend`` -- the backend to use to create the polytope. + - ``backend`` -- the backend to use to create the polytope EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/meson.build b/src/sage/geometry/polyhedron/meson.build new file mode 100644 index 00000000000..3b07bbdd9a5 --- /dev/null +++ b/src/sage/geometry/polyhedron/meson.build @@ -0,0 +1,43 @@ +py.install_sources( + 'all.py', + 'backend_cdd.py', + 'backend_cdd_rdf.py', + 'backend_field.py', + 'backend_normaliz.py', + 'backend_number_field.py', + 'backend_polymake.py', + 'backend_ppl.py', + 'base.py', + 'base0.py', + 'base1.py', + 'base2.py', + 'base3.py', + 'base4.py', + 'base5.py', + 'base6.py', + 'base7.py', + 'base_QQ.py', + 'base_RDF.py', + 'base_ZZ.py', + 'base_mutable.py', + 'base_number_field.py', + 'cdd_file_format.py', + 'constructor.py', + 'double_description.py', + 'double_description_inhomogeneous.py', + 'face.py', + 'generating_function.py', + 'lattice_euclidean_group_element.py', + 'library.py', + 'misc.py', + 'palp_database.py', + 'parent.py', + 'plot.py', + 'ppl_lattice_polygon.py', + 'ppl_lattice_polytope.py', + 'representation.py', + subdir: 'sage/geometry/polyhedron', +) + +subdir('combinatorial_polyhedron') +install_subdir('modules', install_dir: sage_install_dir / 'geometry/polyhedron') diff --git a/src/sage/geometry/polyhedron/misc.py b/src/sage/geometry/polyhedron/misc.py index b47e51f79b8..e61090e83c8 100644 --- a/src/sage/geometry/polyhedron/misc.py +++ b/src/sage/geometry/polyhedron/misc.py @@ -17,13 +17,11 @@ def _to_space_separated_string(l, base_ring=None): INPUT: - - ``l`` -- anything iterable. + - ``l`` -- anything iterable - ``base_ring`` -- ring (default: ``None``); convert this ring, if given - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -66,11 +64,9 @@ def _make_listlist(x): INPUT: - - ``x`` -- ``None`` or an iterable of iterables. - - OUTPUT: + - ``x`` -- ``None`` or an iterable of iterables - A list of lists. + OUTPUT: list of lists EXAMPLES:: @@ -91,7 +87,7 @@ def _common_length_of(l1, l2=None, l3=None): """ The arguments are containers or ``None``. The function applies ``len()`` to each element, and returns the common length. If the - length differs, ``ValueError`` is raised. Used to check arguments. + length differs, :exc:`ValueError` is raised. Used to check arguments. OUTPUT: diff --git a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py index 6255650b84f..b17c2a1ce71 100644 --- a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py +++ b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py @@ -30,9 +30,9 @@ class FormalPolyhedraModule(CombinatorialFreeModule): A three-dimensional vector space of polyhedra:: - sage: I01 = closed_interval(0, 1); I01.rename("conv([0], [1])") - sage: I11 = closed_interval(1, 1); I11.rename("{[1]}") - sage: I12 = closed_interval(1, 2); I12.rename("conv([1], [2])") + sage: I01 = closed_interval(0, 1); I01.rename('conv([0], [1])') + sage: I11 = closed_interval(1, 1); I11.rename('{[1]}') + sage: I12 = closed_interval(1, 2); I12.rename('conv([1], [2])') sage: basis = [I01, I11, I12] sage: M = FormalPolyhedraModule(QQ, 1, basis=basis); M Free module generated by {conv([0], [1]), {[1]}, conv([1], [2])} over Rational Field @@ -67,7 +67,6 @@ class FormalPolyhedraModule(CombinatorialFreeModule): Q[conv([0], [1])] + Q[conv([1], [2])] sage: M_mod_lower.retract(M(I01) - 2*M(I11) + M(I12)) == M_mod_lower.retract(M(I01) + M(I12)) True - """ @staticmethod @@ -106,14 +105,14 @@ def __init__(self, base_ring, dimension, basis, category): sage: from sage.geometry.polyhedron.modules.formal_polyhedra_module import FormalPolyhedraModule sage: def closed_interval(a,b): return Polyhedron(vertices=[[a], [b]]) - sage: I01 = closed_interval(0, 1); I01.rename("conv([0], [1])") - sage: I11 = closed_interval(1, 1); I11.rename("{[1]}") - sage: I12 = closed_interval(1, 2); I12.rename("conv([1], [2])") - sage: I02 = closed_interval(0, 2); I02.rename("conv([0], [2])") + sage: I01 = closed_interval(0, 1); I01.rename('conv([0], [1])') + sage: I11 = closed_interval(1, 1); I11.rename('{[1]}') + sage: I12 = closed_interval(1, 2); I12.rename('conv([1], [2])') + sage: I02 = closed_interval(0, 2); I02.rename('conv([0], [2])') sage: M = FormalPolyhedraModule(QQ, 1, basis=[I01, I11, I12, I02]) sage: TestSuite(M).run() """ - super().__init__(base_ring, basis, prefix="", category=category) + super().__init__(base_ring, basis, prefix='', category=category) def degree_on_basis(self, m): r""" @@ -127,10 +126,10 @@ def degree_on_basis(self, m): sage: from sage.geometry.polyhedron.modules.formal_polyhedra_module import FormalPolyhedraModule sage: def closed_interval(a,b): return Polyhedron(vertices=[[a], [b]]) - sage: I01 = closed_interval(0, 1); I01.rename("conv([0], [1])") - sage: I11 = closed_interval(1, 1); I11.rename("{[1]}") - sage: I12 = closed_interval(1, 2); I12.rename("conv([1], [2])") - sage: I02 = closed_interval(0, 2); I02.rename("conv([0], [2])") + sage: I01 = closed_interval(0, 1); I01.rename('conv([0], [1])') + sage: I11 = closed_interval(1, 1); I11.rename('{[1]}') + sage: I12 = closed_interval(1, 2); I12.rename('conv([1], [2])') + sage: I02 = closed_interval(0, 2); I02.rename('conv([0], [2])') sage: M = FormalPolyhedraModule(QQ, 1, basis=[I01, I11, I12, I02]) We can extract homogeneous components:: diff --git a/src/sage/geometry/polyhedron/palp_database.py b/src/sage/geometry/polyhedron/palp_database.py index 60846d8df23..6432d62080f 100644 --- a/src/sage/geometry/polyhedron/palp_database.py +++ b/src/sage/geometry/polyhedron/palp_database.py @@ -48,10 +48,9 @@ class PALPreader(SageObject): """ Read PALP database of polytopes. - INPUT: - - ``dim`` -- integer. The dimension of the polyhedra + - ``dim`` -- integer; the dimension of the polyhedra - ``data_basename`` -- string or ``None`` (default). The directory and database base filename (PALP usually uses ``'zzdb'``) name @@ -96,7 +95,7 @@ class PALPreader(SageObject): def __init__(self, dim, data_basename=None, output='Polyhedron'): """ - The Python constructor + The Python constructor. See :class:`PALPreader` for documentation. @@ -125,9 +124,7 @@ def _palp_Popen(self): """ Open PALP. - OUTPUT: - - A PALP subprocess. + OUTPUT: a PALP subprocess EXAMPLES:: @@ -144,9 +141,7 @@ def _read_vertices(self, stdout, rows, cols): r""" Read vertex data from the PALP output pipe. - OUTPUT: - - A list of lists. + OUTPUT: list of lists EXAMPLES:: @@ -168,9 +163,7 @@ def _read_vertices_transposed(self, stdout, rows, cols): r""" Read vertex data from the PALP output pipe. - OUTPUT: - - A list of lists. + OUTPUT: list of lists EXAMPLES:: @@ -194,11 +187,9 @@ def _iterate_list(self, start, stop, step): INPUT: - ``start``, ``stop``, ``step`` -- integers specifying the - range to iterate over. - - OUTPUT: + range to iterate over - A generator for vertex data as a list of lists. + OUTPUT: a generator for vertex data as a list of lists EXAMPLES:: @@ -246,11 +237,9 @@ def _iterate_Polyhedron(self, start, stop, step): INPUT: - ``start``, ``stop``, ``step`` -- integers specifying the - range to iterate over. + range to iterate over - OUTPUT: - - A generator for lattice polyhedra. + OUTPUT: a generator for lattice polyhedra EXAMPLES:: @@ -272,11 +261,9 @@ def _iterate_PPL(self, start, stop, step): INPUT: - ``start``, ``stop``, ``step`` -- integers specifying the - range to iterate over. - - OUTPUT: + range to iterate over - A generator for PPL-based lattice polyhedra. + OUTPUT: a generator for PPL-based lattice polyhedra EXAMPLES:: @@ -296,11 +283,9 @@ def _iterate_PointCollection(self, start, stop, step): INPUT: - ``start``, ``stop``, ``step`` -- integers specifying the - range to iterate over. - - OUTPUT: + range to iterate over - A generator for PPL-based lattice polyhedra. + OUTPUT: a generator for PPL-based lattice polyhedra EXAMPLES:: @@ -326,11 +311,9 @@ def _iterate(self, output=None): INPUT: - - ``output`` -- as in the :class:`PALPreader` constructor. + - ``output`` -- as in the :class:`PALPreader` constructor - OUTPUT: - - A function generating lattice polytopes in the specified output format. + OUTPUT: a function generating lattice polytopes in the specified output format EXAMPLES:: @@ -360,9 +343,7 @@ def __iter__(self): """ Iterate over all polytopes. - OUTPUT: - - An iterator for all polytopes. + OUTPUT: an iterator for all polytopes TESTS:: @@ -405,8 +386,8 @@ class Reflexive4dHodge(PALPreader): INPUT: - - ``h11``, ``h21`` -- Integers. The Hodge numbers of the reflexive - polytopes to list. + - ``h11``, ``h21`` -- integer; the Hodge numbers of the reflexive + polytopes to list Any additional keyword arguments are passed to :class:`PALPreader`. @@ -449,9 +430,7 @@ def _palp_Popen(self): """ Open PALP. - OUTPUT: - - A PALP subprocess. + OUTPUT: a PALP subprocess EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/parent.py b/src/sage/geometry/polyhedron/parent.py index 79a77e51556..e26948de9fd 100644 --- a/src/sage/geometry/polyhedron/parent.py +++ b/src/sage/geometry/polyhedron/parent.py @@ -30,36 +30,36 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, *, ambient_space=None, base_ring=None): r""" - Construct a suitable parent class for polyhedra + Construct a suitable parent class for polyhedra. INPUT: - - ``base_ring`` -- A ring. Currently there are backends for `\ZZ`, - `\QQ`, and `\RDF`. + - ``base_ring`` -- a ring; currently there are backends for `\ZZ`, + `\QQ`, and `\RDF` - - ``ambient_dim`` -- integer. The ambient space dimension. + - ``ambient_dim`` -- integer; the ambient space dimension - - ``ambient_space`` -- A free module. + - ``ambient_space`` -- a free module - ``backend`` -- string. The name of the backend for computations. There are - several backends implemented: + several backends implemented: - * ``backend="ppl"`` uses the Parma Polyhedra Library + * ``backend="ppl"`` uses the Parma Polyhedra Library - * ``backend="cdd"`` uses CDD + * ``backend="cdd"`` uses CDD - * ``backend="normaliz"`` uses normaliz + * ``backend="normaliz"`` uses normaliz - * ``backend="polymake"`` uses polymake + * ``backend="polymake"`` uses polymake - * ``backend="field"`` a generic Sage implementation + * ``backend="field"`` a generic Sage implementation OUTPUT: A parent class for polyhedra over the given base ring if the backend supports it. If not, the parent base ring can be larger (for example, `\QQ` instead of `\ZZ`). If there is no - implementation at all, a ``ValueError`` is raised. + implementation at all, a :exc:`ValueError` is raised. EXAMPLES:: @@ -125,7 +125,6 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * sage: Polyhedra(SCR, 2, backend='number_field') # needs sage.symbolic Polyhedra in (Symbolic Constants Subring)^2 - """ if ambient_space_or_base_ring is not None: if ambient_space_or_base_ring in Rings(): @@ -202,13 +201,13 @@ class Polyhedra_base(UniqueRepresentation, Parent): INPUT: - - ``base_ring`` -- either ``ZZ``, ``QQ``, or ``RDF``. The base - ring of the ambient module/vector space. + - ``base_ring`` -- either ``ZZ``, ``QQ``, or ``RDF``; the base + ring of the ambient module/vector space - - ``ambient_dim`` -- integer. The ambient space dimension. + - ``ambient_dim`` -- integer; the ambient space dimension - - ``backend`` -- string. The name of the backend for computations. There are - several backends implemented: + - ``backend`` -- string; the name of the backend for computations. There are + several backends implemented: * ``backend="ppl"`` uses the Parma Polyhedra Library @@ -263,7 +262,7 @@ def __init__(self, base_ring, ambient_dim, backend): def list(self): """ - Return the two polyhedra in ambient dimension 0, raise an error otherwise + Return the two polyhedra in ambient dimension 0, raise an error otherwise. EXAMPLES:: @@ -297,8 +296,7 @@ def recycle(self, polyhedron): INPUT: - - ``polyhedron`` -- a polyhedron whose parent is ``self``. - + - ``polyhedron`` -- a polyhedron whose parent is ``self`` EXAMPLES:: @@ -465,9 +463,7 @@ def Vrepresentation_space(self): This is the vector space or module containing the Vrepresentation vectors. - OUTPUT: - - A free module over the base ring of dimension :meth:`ambient_dim`. + OUTPUT: a free module over the base ring of dimension :meth:`ambient_dim` EXAMPLES:: @@ -490,9 +486,7 @@ def Hrepresentation_space(self): r""" Return the linear space containing the H-representation vectors. - OUTPUT: - - A free module over the base ring of dimension :meth:`ambient_dim` + 1. + OUTPUT: a free module over the base ring of dimension :meth:`ambient_dim` + 1 EXAMPLES:: @@ -540,9 +534,7 @@ def _repr_ambient_module(self) -> str: Return an abbreviated string representation of the ambient space. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -562,9 +554,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -582,16 +572,15 @@ def _element_constructor_(self, *args, **kwds): INPUT: - - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``. + - ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None`` - - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``. + - ``Hrep`` -- list ``[ieqs, eqns]`` or ``None`` - - ``convert`` -- boolean keyword argument (default: - ``True``). Whether to convert the coordinates into the base - ring. + - ``convert`` -- boolean (default: ``True``); whether to convert the + coordinates into the base ring - - ``**kwds`` -- optional remaining keywords that are passed to the - polyhedron constructor. + - ``**kwds`` -- (optional) remaining keywords that are passed to the + polyhedron constructor EXAMPLES:: @@ -747,9 +736,9 @@ def base_extend(self, base_ring, backend=None, ambient_dim=None): INPUT: - ``base_ring``, ``backend`` -- see - :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. + :func:`~sage.geometry.polyhedron.constructor.Polyhedron` - ``ambient_dim`` -- if not ``None`` change ambient dimension - accordingly. + accordingly EXAMPLES:: @@ -783,9 +772,9 @@ def change_ring(self, base_ring, backend=None, ambient_dim=None): INPUT: - ``base_ring``, ``backend`` -- see - :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. + :func:`~sage.geometry.polyhedron.constructor.Polyhedron` - ``ambient_dim`` -- if not ``None`` change ambient dimension - accordingly. + accordingly EXAMPLES:: @@ -835,7 +824,7 @@ def _coerce_base_ring(self, other): OUTPUT: - Either `\ZZ`, `\QQ`, or `RDF`. Raises :class:`TypeError` if + Either `\ZZ`, `\QQ`, or `RDF`. Raises :exc:`TypeError` if ``other`` is not a suitable input. .. NOTE:: @@ -918,11 +907,9 @@ def _coerce_map_from_(self, X): INPUT: - - ``X`` -- anything. - - OUTPUT: + - ``X`` -- anything - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -949,16 +936,14 @@ def _get_action_(self, other, op, self_is_left): INPUT: - - ``other`` -- a scalar or a vector. + - ``other`` -- a scalar or a vector - - ``op`` -- the operator. + - ``op`` -- the operator - - ``self_is_left`` -- boolean. Whether ``self`` is on the left - of the operator. + - ``self_is_left`` -- boolean; whether ``self`` is on the left + of the operator - OUTPUT: - - An action that is used by the coercion model. + OUTPUT: an action that is used by the coercion model EXAMPLES:: @@ -1003,7 +988,6 @@ def _get_action_(self, other, op, self_is_left): Identity endomorphism of Polyhedra in ZZ^2 with precomposition on right by Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring - """ import operator from sage.structure.coerce_actions import ActedUponAction @@ -1046,13 +1030,11 @@ def _make_Inequality(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. + - ``polyhedron`` -- the new polyhedron - - ``data`` -- the H-representation data. + - ``data`` -- the H-representation data - OUTPUT: - - A new :class:`~sage.geometry.polyhedron.representation.Inequality` object. + OUTPUT: a new :class:`~sage.geometry.polyhedron.representation.Inequality` object EXAMPLES:: @@ -1073,13 +1055,11 @@ def _make_Equation(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. - - - ``data`` -- the H-representation data. + - ``polyhedron`` -- the new polyhedron - OUTPUT: + - ``data`` -- the H-representation data - A new :class:`~sage.geometry.polyhedron.representation.Equation` object. + OUTPUT: a new :class:`~sage.geometry.polyhedron.representation.Equation` object EXAMPLES:: @@ -1100,13 +1080,11 @@ def _make_Vertex(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. + - ``polyhedron`` -- the new polyhedron - - ``data`` -- the V-representation data. + - ``data`` -- the V-representation data - OUTPUT: - - A new :class:`~sage.geometry.polyhedron.representation.Vertex` object. + OUTPUT: a new :class:`~sage.geometry.polyhedron.representation.Vertex` object EXAMPLES:: @@ -1127,13 +1105,11 @@ def _make_Ray(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. - - - ``data`` -- the V-representation data. + - ``polyhedron`` -- the new polyhedron - OUTPUT: + - ``data`` -- the V-representation data - A new :class:`~sage.geometry.polyhedron.representation.Ray` object. + OUTPUT: a new :class:`~sage.geometry.polyhedron.representation.Ray` object EXAMPLES:: @@ -1154,13 +1130,11 @@ def _make_Line(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. - - - ``data`` -- the V-representation data. + - ``polyhedron`` -- the new polyhedron - OUTPUT: + - ``data`` -- the V-representation data - A new :class:`~sage.geometry.polyhedron.representation.Line` object. + OUTPUT: a new :class:`~sage.geometry.polyhedron.representation.Line` object EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index 9c8a93624ec..7a0ad2a2153 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -164,8 +164,8 @@ def __init__(self, projection_point): INPUT: - - ``projection_point`` -- a list of coordinates in the - appropriate dimension, which is the point projected from. + - ``projection_point`` -- list of coordinates in the + appropriate dimension, which is the point projected from EXAMPLES:: @@ -185,7 +185,7 @@ def __init__(self, projection_point): pproj = vector(RDF, self.projection_point) self.psize = norm(pproj) if (self.psize).is_zero(): - raise ValueError("projection direction must be a non-zero vector.") + raise ValueError("projection direction must be a nonzero vector.") v = vector(RDF, [0.0] * (self.dim - 1) + [-self.psize]) - pproj polediff = matrix(RDF, v).transpose() denom = RDF((polediff.transpose() * polediff)[0][0]) @@ -203,7 +203,7 @@ def __call__(self, x): INPUT: - - ``x`` -- a vector or anything convertible to a vector. + - ``x`` -- a vector or anything convertible to a vector OUTPUT: @@ -253,7 +253,7 @@ class ProjectionFuncSchlegel: """ def __init__(self, facet, projection_point): """ - Initializes the projection. + Initialize the projection. EXAMPLES:: @@ -297,7 +297,7 @@ def __call__(self, x): """ Apply the projection to a vector. - - ``x`` -- a vector or anything convertible to a vector. + - ``x`` -- a vector or anything convertible to a vector EXAMPLES:: @@ -453,8 +453,8 @@ def stereographic(self, projection_point=None): INPUT: - - ``projection_point`` -- The projection point. This must be - distinct from the polyhedron's vertices. Default is `(1,0,\dots,0)` + - ``projection_point`` -- the projection point. This must be + distinct from the polyhedron's vertices. Default is `(1,0,\dots,0)`. EXAMPLES:: @@ -481,7 +481,7 @@ def schlegel(self, facet=None, position=None): INPUT: - - ``facet`` -- a PolyhedronFace. The facet into which the Schlegel + - ``facet`` -- a PolyhedronFace; the facet into which the Schlegel diagram is created. The default is the first facet. - ``position`` -- a positive number. Determines a relative distance @@ -769,7 +769,7 @@ def _init_area_2d(self, polyhedron): [[3, 0, 1, 2]] """ assert polyhedron.ambient_dim() == 2, "Requires polyhedron in 2d" - vertices = [v for v in polyhedron.Vrep_generator()] + vertices = list(polyhedron.Vrep_generator()) vertices = cyclic_sort_vertices_2d(vertices) coords = [] @@ -802,7 +802,7 @@ def adjacent_vertices(i): coords[i] + shift, coords[i - 1] + shift]) if polyhedron.n_lines() == 2: - [line1, line2] = [l for l in polyhedron.lines()] + line1, line2 = polyhedron.lines() assert len(coords) == 1, "Can have only a single vertex!" v = coords[0] l1 = line1() @@ -848,7 +848,7 @@ def defining_equation(): # corresponding to a polygon faces = [] face_inequalities = [] for facet_equation in defining_equation(): - vertices = [v for v in facet_equation.incident()] + vertices = list(facet_equation.incident()) face_inequalities.append(facet_equation) vertices = cyclic_sort_vertices_2d(vertices) if len(vertices) >= 3: @@ -894,7 +894,7 @@ def adjacent_vertices(i): coords[1] + shift, coords[0] + shift]) if polyhedron.n_lines() == 2: - [line1, line2] = [l for l in polyhedron.line_generator()] + line1, line2 = polyhedron.line_generator() l1 = line1() l2 = line2() for v in polyhedron.vertex_generator(): @@ -909,11 +909,9 @@ def render_points_1d(self, **kwds): INPUT: - ``**kwds`` -- options passed through to - :func:`~sage.plot.point.point2d`. + :func:`~sage.plot.point.point2d` - OUTPUT: - - A 2-d graphics object. + OUTPUT: a 2-d graphics object EXAMPLES:: @@ -932,11 +930,9 @@ def render_line_1d(self, **kwds): INPUT: - ``**kwds`` -- options passed through to - :func:`~sage.plot.line.line2d`. - - OUTPUT: + :func:`~sage.plot.line.line2d` - A 2-d graphics object. + OUTPUT: a 2-d graphics object EXAMPLES:: @@ -1071,9 +1067,7 @@ def render_0d(self, point_opts=None, line_opts=None, polygon_opts=None): See :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot`. - OUTPUT: - - A 2-d graphics object. + OUTPUT: a 2-d graphics object EXAMPLES:: @@ -1103,9 +1097,7 @@ def render_1d(self, point_opts=None, line_opts=None, polygon_opts=None): See :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.plot`. - OUTPUT: - - A 2-d graphics object. + OUTPUT: a 2-d graphics object EXAMPLES:: @@ -1251,28 +1243,26 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, INPUT: - - ``view`` -- list (default: [0,0,1]) representing the rotation axis (see note below). - - ``angle`` -- integer (default: 0) angle of rotation in degree from 0 to 360 (see note - below). - - ``scale`` -- integer (default: 1) specifying the scaling of the tikz picture. - - ``edge_color`` -- string (default: 'blue!95!black') representing colors which tikz - recognize. - - ``facet_color`` -- string (default: 'blue!95!black') representing colors which tikz - recognize. - - ``vertex_color`` -- string (default: 'green') representing colors which tikz - recognize. + - ``view`` -- list (default: [0,0,1]) representing the rotation axis (see note below) + - ``angle`` -- integer (default: 0); angle of rotation in degree from 0 to 360 (see note + below) + - ``scale`` -- integer (default: 1); the scaling of the tikz picture + - ``edge_color`` -- string (default: ``'blue!95!black'``); representing colors which tikz + recognizes + - ``facet_color`` -- string (default: ``'blue!95!black'``); representing colors which tikz + recognizes + - ``vertex_color`` -- string (default: ``'green'``); representing colors which tikz + recognizes - ``opacity`` -- real number (default: 0.8) between 0 and 1 giving the opacity of - the front facets. - - ``axis`` -- Boolean (default: ``False``) draw the axes at the origin or not. - - ``output_type`` -- string (default: ``None``), valid values + the front facets + - ``axis`` -- boolean (default: ``False``); draw the axes at the origin or not + - ``output_type`` -- string (default: ``None``); valid values are ``None`` (deprecated), ``'LatexExpr'`` and ``'TikzPicture'``, whether to return a :class:`LatexExpr` object (which inherits from Python :class:`str`) or a :class:`TikzPicture` object from module :mod:`sage.misc.latex_standalone` - OUTPUT: - - :class:`LatexExpr` object or :class:`TikzPicture` object + OUTPUT: :class:`LatexExpr` object or :class:`TikzPicture` object .. NOTE:: @@ -1476,16 +1466,16 @@ def _tikz_2d(self, scale, edge_color, facet_color, opacity, vertex_color, axis): INPUT: - - ``scale`` -- integer specifying the scaling of the tikz picture. + - ``scale`` -- integer specifying the scaling of the tikz picture - ``edge_color`` -- string representing colors which tikz - recognize. + recognizes - ``facet_color`` -- string representing colors which tikz - recognize. + recognizes - ``vertex_color`` -- string representing colors which tikz - recognize. + recognizes - ``opacity`` -- real number between 0 and 1 giving the opacity of - the front facets. - - ``axis`` -- Boolean (default: ``False``) draw the axes at the origin or not. + the front facets + - ``axis`` -- boolean (default: ``False``); draw the axes at the origin or not OUTPUT: @@ -1606,22 +1596,20 @@ def _tikz_2d_in_3d(self, view, angle, scale, edge_color, facet_color, INPUT: - - ``view`` -- list (default: [0,0,1]) representing the rotation axis. - - ``angle`` -- integer angle of rotation in degree from 0 to 360. - - ``scale`` -- integer specifying the scaling of the tikz picture. + - ``view`` -- list (default: [0,0,1]) representing the rotation axis + - ``angle`` -- integer angle of rotation in degree from 0 to 360 + - ``scale`` -- integer specifying the scaling of the tikz picture - ``edge_color`` -- string representing colors which tikz - recognize. + recognizes - ``facet_color`` -- string representing colors which tikz - recognize. + recognizes - ``vertex_color`` -- string representing colors which tikz - recognize. + recognizes - ``opacity`` -- real number between 0 and 1 giving the opacity of - the front facets. - - ``axis`` -- Boolean draw the axes at the origin or not. - - OUTPUT: + the front facets + - ``axis`` -- boolean draw the axes at the origin or not - :class:`LatexExpr` -- containing the TikZ picture. + OUTPUT: :class:`LatexExpr` -- containing the TikZ picture EXAMPLES:: @@ -1760,22 +1748,20 @@ def _tikz_3d_in_3d(self, view, angle, scale, edge_color, INPUT: - - ``view`` -- list (default: [0,0,1]) representing the rotation axis. - - ``angle`` -- integer angle of rotation in degree from 0 to 360. - - ``scale`` -- integer specifying the scaling of the tikz picture. + - ``view`` -- list (default: [0,0,1]) representing the rotation axis + - ``angle`` -- integer angle of rotation in degree from 0 to 360 + - ``scale`` -- integer specifying the scaling of the tikz picture - ``edge_color`` -- string representing colors which tikz - recognize. + recognizes - ``facet_color`` -- string representing colors which tikz - recognize. + recognizes - ``vertex_color`` -- string representing colors which tikz - recognize. + recognizes - ``opacity`` -- real number between 0 and 1 giving the opacity of - the front facets. - - ``axis`` -- Boolean draw the axes at the origin or not. - - OUTPUT: + the front facets + - ``axis`` -- boolean draw the axes at the origin or not - :class:`LatexExpr` -- containing the TikZ picture. + OUTPUT: :class:`LatexExpr` -- containing the TikZ picture. EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/ppl_lattice_polygon.py b/src/sage/geometry/polyhedron/ppl_lattice_polygon.py index a3ddeda66a2..dc100230745 100644 --- a/src/sage/geometry/polyhedron/ppl_lattice_polygon.py +++ b/src/sage/geometry/polyhedron/ppl_lattice_polygon.py @@ -32,7 +32,7 @@ ######################################################################## class LatticePolygon_PPL_class(LatticePolytope_PPL_class): """ - A lattice polygon + A lattice polygon. This includes 2-dimensional polytopes as well as degenerate (0 and 1-dimensional) lattice polygons. Any polytope in 2d is a polygon. @@ -80,12 +80,12 @@ def ordered_vertices(self): def _find_isomorphism_degenerate(self, polytope): """ - Helper to pick an isomorphism of degenerate polygons + Helper to pick an isomorphism of degenerate polygons. INPUT: - - ``polytope`` -- a :class:`LatticePolytope_PPL_class`. The - polytope to compare with. + - ``polytope`` -- a :class:`LatticePolytope_PPL_class`; the + polytope to compare with EXAMPLES:: @@ -177,19 +177,19 @@ def _find_cyclic_isomorphism_matching_edge(self, polytope, polytope_origin, p_ray_left, p_ray_right): r""" - Helper to find an isomorphism of polygons + Helper to find an isomorphism of polygons. INPUT: - - ``polytope`` -- the lattice polytope to compare to. + - ``polytope`` -- the lattice polytope to compare to - - ``polytope_origin`` -- `\ZZ`-vector. a vertex of ``polytope`` + - ``polytope_origin`` -- `\ZZ`-vector; a vertex of ``polytope`` - - ``p_ray_left`` -- vector. the vector from ``polytope_origin`` - to one of its neighboring vertices. + - ``p_ray_left`` -- vector; the vector from ``polytope_origin`` + to one of its neighboring vertices - - ``p_ray_right`` -- vector. the vector from - ``polytope_origin`` to the other neighboring vertices. + - ``p_ray_right`` -- vector; the vector from + ``polytope_origin`` to the other neighboring vertices OUTPUT: @@ -247,7 +247,7 @@ def find_isomorphism(self, polytope): INPUT: - - ``polytope`` -- a polytope, potentially higher-dimensional. + - ``polytope`` -- a polytope, potentially higher-dimensional OUTPUT: @@ -337,11 +337,9 @@ def is_isomorphic(self, polytope): INPUT: - - ``polytope`` -- a lattice polytope. + - ``polytope`` -- a lattice polytope - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -399,9 +397,7 @@ def plot(self): """ Plot the lattice polygon. - OUTPUT: - - A graphics object. + OUTPUT: a graphics object EXAMPLES:: @@ -437,7 +433,7 @@ def plot(self): @cached_function def polar_P2_polytope(): """ - The polar of the `P^2` polytope + The polar of the `P^2` polytope. EXAMPLES:: @@ -453,7 +449,7 @@ def polar_P2_polytope(): @cached_function def polar_P1xP1_polytope(): r""" - The polar of the `P^1 \times P^1` polytope + The polar of the `P^1 \times P^1` polytope. EXAMPLES:: @@ -469,7 +465,7 @@ def polar_P1xP1_polytope(): @cached_function def polar_P2_112_polytope(): """ - The polar of the `P^2[1,1,2]` polytope + The polar of the `P^2[1,1,2]` polytope. EXAMPLES:: @@ -485,11 +481,9 @@ def polar_P2_112_polytope(): @cached_function def subpolygons_of_polar_P2(): """ - The lattice sub-polygons of the polar `P^2` polytope - - OUTPUT: + The lattice sub-polygons of the polar `P^2` polytope. - A tuple of lattice polytopes. + OUTPUT: a tuple of lattice polytopes EXAMPLES:: @@ -503,11 +497,9 @@ def subpolygons_of_polar_P2(): @cached_function def subpolygons_of_polar_P2_112(): """ - The lattice sub-polygons of the polar `P^2[1,1,2]` polytope - - OUTPUT: + The lattice sub-polygons of the polar `P^2[1,1,2]` polytope. - A tuple of lattice polytopes. + OUTPUT: a tuple of lattice polytopes EXAMPLES:: @@ -521,11 +513,9 @@ def subpolygons_of_polar_P2_112(): @cached_function def subpolygons_of_polar_P1xP1(): r""" - The lattice sub-polygons of the polar `P^1 \times P^1` polytope - - OUTPUT: + The lattice sub-polygons of the polar `P^1 \times P^1` polytope. - A tuple of lattice polytopes. + OUTPUT: a tuple of lattice polytopes EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/ppl_lattice_polytope.py b/src/sage/geometry/polyhedron/ppl_lattice_polytope.py index 3cde1c6af81..27874340a51 100644 --- a/src/sage/geometry/polyhedron/ppl_lattice_polytope.py +++ b/src/sage/geometry/polyhedron/ppl_lattice_polytope.py @@ -87,11 +87,9 @@ def _class_for_LatticePolytope(dim): INPUT: - - ``dim`` -- integer. The ambient space dimension. + - ``dim`` -- integer; the ambient space dimension - OUTPUT: - - The appropriate class for the lattice polytope. + OUTPUT: the appropriate class for the lattice polytope EXAMPLES:: @@ -129,7 +127,7 @@ def LatticePolytope_PPL(*args): sage: LatticePolytope_PPL(P) # needs pplpy A 0-dimensional lattice polytope in ZZ^2 with 1 vertex - A ``TypeError`` is raised if the arguments do not specify a lattice polytope:: + A :exc:`TypeError` is raised if the arguments do not specify a lattice polytope:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL sage: LatticePolytope_PPL((0,0), (1/2,1)) # needs pplpy @@ -195,11 +193,9 @@ class LatticePolytope_PPL_class(C_Polyhedron): def __repr__(self): """ - Return the string representation - - OUTPUT: + Return the string representation. - A string. + OUTPUT: string EXAMPLES:: @@ -233,9 +229,7 @@ def is_bounded(self): """ Return whether the lattice polytope is compact. - OUTPUT: - - Always ``True``, since polytopes are by definition compact. + OUTPUT: always ``True``, since polytopes are by definition compact EXAMPLES:: @@ -250,9 +244,7 @@ def n_vertices(self): """ Return the number of vertices. - OUTPUT: - - An integer, the number of vertices. + OUTPUT: integer; the number of vertices EXAMPLES:: @@ -344,7 +336,7 @@ def integral_points(self): OUTPUT: The list of integral points in the polyhedron. If the - polyhedron is not compact, a ``ValueError`` is raised. + polyhedron is not compact, a :exc:`ValueError` is raised. EXAMPLES:: @@ -508,7 +500,7 @@ def vertices_saturating(self, constraint): INPUT: - ``constraint`` -- a constraint (inequality or equation) of - the polytope. + the polytope OUTPUT: @@ -537,10 +529,8 @@ def is_full_dimensional(self): """ Return whether the lattice polytope is full dimensional. - OUTPUT: - - Boolean. Whether the :meth:`affine_dimension` equals the - ambient space dimension. + OUTPUT: boolean; whether the :meth:`affine_dimension` equals the + ambient space dimension EXAMPLES:: @@ -566,8 +556,8 @@ def fibration_generator(self, dim): INPUT: - - ``dim`` -- integer. The dimension of the lattice polytope - fiber. + - ``dim`` -- integer; the dimension of the lattice polytope + fiber OUTPUT: @@ -635,8 +625,8 @@ def pointsets_mod_automorphism(self, pointsets): INPUT: - - ``polytopes`` -- a tuple/list/iterable of subsets of the - integral points of ``self``. + - ``polytopes`` -- tuple/list/iterable of subsets of the + integral points of ``self`` OUTPUT: @@ -713,10 +703,10 @@ def contains(self, point_coordinates): INPUT: - - ``point_coordinates`` -- a list/tuple/iterable of rational - numbers. The coordinates of the point. + - ``point_coordinates`` -- list/tuple/iterable of rational + numbers; the coordinates of the point - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -737,9 +727,9 @@ def contains(self, point_coordinates): @cached_method def contains_origin(self): """ - Test whether the polytope contains the origin + Test whether the polytope contains the origin. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -877,13 +867,11 @@ def base_rays(self, fiber, points): INPUT: - ``fiber`` -- a sub-lattice polytope defining the - :meth:`base_projection`. + :meth:`base_projection` - - ``points`` -- the points to project to the base. - - OUTPUT: + - ``points`` -- the points to project to the base - A tuple of primitive `\ZZ`-vectors. + OUTPUT: a tuple of primitive `\ZZ`-vectors EXAMPLES:: @@ -922,7 +910,7 @@ def has_IP_property(self): That is, the polytope is full-dimensional and the origin is a interior point not on the boundary. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -957,7 +945,7 @@ def restricted_automorphism_group(self, vertex_labels=None): INPUT: - - ``vertex_labels`` -- a tuple or ``None`` (default). The + - ``vertex_labels`` -- tuple or ``None`` (default). The labels of the vertices that will be used in the output permutation group. By default, the vertices are used themselves. @@ -1029,12 +1017,12 @@ def lattice_automorphism_group(self, points=None, point_labels=None): INPUT: - - ``points`` -- A tuple of coordinate vectors or ``None`` + - ``points`` -- tuple of coordinate vectors or ``None`` (default). If specified, the points must form complete orbits under the lattice automorphism group. If ``None`` all vertices are used. - - ``point_labels`` -- A tuple of labels for the ``points`` or + - ``point_labels`` -- tuple of labels for the ``points`` or ``None`` (default). These will be used as labels for the do permutation group. If ``None``, the ``points`` will be used themselves. diff --git a/src/sage/geometry/polyhedron/representation.py b/src/sage/geometry/polyhedron/representation.py index 49993d6ada1..78e0cbf08d3 100644 --- a/src/sage/geometry/polyhedron/representation.py +++ b/src/sage/geometry/polyhedron/representation.py @@ -46,7 +46,7 @@ class PolyhedronRepresentation(SageObject): The internal base class for all representation objects of ``Polyhedron`` (vertices/rays/lines and inequalities/equations) - .. note:: + .. NOTE:: You should not (and cannot) instantiate it yourself. You can only obtain them from a Polyhedron() class. @@ -108,7 +108,7 @@ def __hash__(self): def __richcmp__(self, other, op): """ - Compare two representation objects + Compare two representation objects. This method defines a linear order on the H/V-representation objects. The order is first determined by the types of the objects, @@ -122,11 +122,9 @@ def __richcmp__(self, other, op): INPUT: - - ``other`` -- anything. + - ``other`` -- anything - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -218,7 +216,7 @@ def vector(self, base_ring=None): INPUT: - - ``base_ring`` -- the base ring of the vector. + - ``base_ring`` -- the base ring of the vector OUTPUT: @@ -321,11 +319,9 @@ def __add__(self, coordinate_list): INPUT: - - ``coordinate_list`` -- a list. + - ``coordinate_list`` -- list - OUTPUT: - - The coordinates of ``self`` concatenated with ``coordinate_list``. + OUTPUT: the coordinates of ``self`` concatenated with ``coordinate_list`` EXAMPLES:: @@ -345,11 +341,9 @@ def __radd__(self, coordinate_list): INPUT: - - ``coordinate_list`` -- a list. - - OUTPUT: + - ``coordinate_list`` -- list - ``coordinate_list`` concatenated with the coordinates of ``self``. + OUTPUT: ``coordinate_list`` concatenated with the coordinates of ``self`` EXAMPLES:: @@ -369,11 +363,9 @@ def count(self, i): INPUT: - - ``i`` -- Anything. - - OUTPUT: + - ``i`` -- anything - Integer. The number of occurrences of ``i`` in the coordinates. + OUTPUT: integer; the number of occurrences of ``i`` in the coordinates EXAMPLES:: @@ -394,7 +386,7 @@ class Hrepresentation(PolyhedronRepresentation): def __init__(self, polyhedron_parent): """ - Initializes the PolyhedronRepresentation object. + Initialize the PolyhedronRepresentation object. TESTS:: @@ -422,9 +414,9 @@ def _set_data(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. + - ``polyhedron`` -- the new polyhedron - - ``data`` -- the H-representation data. + - ``data`` -- the H-representation data TESTS:: @@ -448,7 +440,7 @@ def _set_data(self, polyhedron, data): def is_H(self): """ - Return True if the object is part of a H-representation + Return ``True`` if the object is part of a H-representation (inequality or equation). EXAMPLES:: @@ -462,7 +454,7 @@ def is_H(self): def is_inequality(self): """ - Return True if the object is an inequality of the H-representation. + Return ``True`` if the object is an inequality of the H-representation. EXAMPLES:: @@ -475,7 +467,7 @@ def is_inequality(self): def is_equation(self): """ - Return True if the object is an equation of the H-representation. + Return ``True`` if the object is an equation of the H-representation. EXAMPLES:: @@ -586,7 +578,7 @@ def adjacent(self): def is_incident(self, Vobj): """ - Return whether the incidence matrix element (Vobj,self) == 1 + Return whether the incidence matrix element (Vobj,self) == 1. EXAMPLES:: @@ -602,7 +594,7 @@ def is_incident(self, Vobj): def __mul__(self, Vobj): """ - Shorthand for ``self.eval(x)`` + Shorthand for ``self.eval(x)``. EXAMPLES:: @@ -619,7 +611,7 @@ def eval(self, Vobj): Evaluate the left hand side `A\vec{x}+b` on the given vertex/ray/line. - .. NOTE: + .. NOTE:: * Evaluating on a vertex returns `A\vec{x}+b` @@ -682,15 +674,13 @@ def repr_pretty(self, **kwds): INPUT: - - ``prefix`` -- a string - - - ``indices`` -- a tuple or other iterable + - ``prefix`` -- string - - ``latex`` -- a boolean + - ``indices`` -- tuple or other iterable - OUTPUT: + - ``latex`` -- boolean - A string + OUTPUT: string EXAMPLES:: @@ -708,9 +698,7 @@ def _latex_(self): r""" Return a LaTeX-representation of this equality/inequality. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -762,7 +750,7 @@ def type(self): def is_inequality(self): """ - Return True since this is, by construction, an inequality. + Return ``True`` since this is, by construction, an inequality. EXAMPLES:: @@ -877,7 +865,7 @@ def is_facet_defining_inequality(self, other): # See if ``self`` has the same incidences as an inequality of ``other``. # If this is the case, then the above check suffices to guarantee that all - # entries of ``cross_slack_matrix`` are non-negative. + # entries of ``cross_slack_matrix`` are nonnegative. return incidences.row(0) in other.incidence_matrix().columns() def _repr_(self): @@ -924,7 +912,7 @@ def _repr_(self): def contains(self, Vobj): """ - Tests whether the halfspace (including its boundary) defined + Test whether the halfspace (including its boundary) defined by the inequality contains the given vertex/ray/line. EXAMPLES:: @@ -950,7 +938,7 @@ def contains(self, Vobj): def interior_contains(self, Vobj): """ - Tests whether the interior of the halfspace (excluding its + Test whether the interior of the halfspace (excluding its boundary) defined by the inequality contains the given vertex/ray/line. @@ -988,9 +976,7 @@ def outer_normal(self): r""" Return the outer normal vector of ``self``. - OUTPUT: - - The normal vector directed away from the interior of the polyhedron. + OUTPUT: the normal vector directed away from the interior of the polyhedron EXAMPLES:: @@ -1040,7 +1026,7 @@ def type(self): def is_equation(self): """ - Tests if this object is an equation. By construction, it must be. + Test if this object is an equation. By construction, it must be. TESTS:: @@ -1080,7 +1066,7 @@ def _repr_(self): def contains(self, Vobj): """ - Tests whether the hyperplane defined by the equation contains + Test whether the hyperplane defined by the equation contains the given vertex/ray/line. EXAMPLES:: @@ -1099,7 +1085,7 @@ def contains(self, Vobj): def interior_contains(self, Vobj): """ - Tests whether the interior of the halfspace (excluding its + Test whether the interior of the halfspace (excluding its boundary) defined by the inequality contains the given vertex/ray/line. @@ -1130,7 +1116,7 @@ class Vrepresentation(PolyhedronRepresentation): def __init__(self, polyhedron_parent): """ - Initializes the PolyhedronRepresentation object. + Initialize the PolyhedronRepresentation object. TESTS:: @@ -1156,9 +1142,9 @@ def _set_data(self, polyhedron, data): INPUT: - - ``polyhedron`` -- the new polyhedron. + - ``polyhedron`` -- the new polyhedron - - ``data`` -- the V-representation data. + - ``data`` -- the V-representation data TESTS:: @@ -1181,7 +1167,7 @@ def _set_data(self, polyhedron, data): def is_V(self): """ - Return True if the object is part of a V-representation + Return ``True`` if the object is part of a V-representation (a vertex, ray, or line). EXAMPLES:: @@ -1195,7 +1181,7 @@ def is_V(self): def is_vertex(self): """ - Return True if the object is a vertex of the V-representation. + Return ``True`` if the object is a vertex of the V-representation. This method is over-ridden by the corresponding method in the derived class Vertex. @@ -1214,7 +1200,7 @@ def is_vertex(self): def is_ray(self): """ - Return True if the object is a ray of the V-representation. + Return ``True`` if the object is a ray of the V-representation. This method is over-ridden by the corresponding method in the derived class Ray. @@ -1234,7 +1220,7 @@ def is_ray(self): def is_line(self): """ - Return True if the object is a line of the V-representation. + Return ``True`` if the object is a line of the V-representation. This method is over-ridden by the corresponding method in the derived class Line. @@ -1283,7 +1269,7 @@ def adjacent(self): def is_incident(self, Hobj): """ - Return whether the incidence matrix element (self,Hobj) == 1 + Return whether the incidence matrix element (self,Hobj) == 1. EXAMPLES:: @@ -1301,7 +1287,7 @@ def is_incident(self, Hobj): def __mul__(self, Hobj): """ - Shorthand for self.evaluated_on(Hobj) + Shorthand for self.evaluated_on(Hobj). TESTS:: @@ -1377,7 +1363,7 @@ def type(self): def is_vertex(self): """ - Tests if this object is a vertex. By construction it always is. + Test if this object is a vertex. By construction it always is. EXAMPLES:: @@ -1392,9 +1378,7 @@ def _repr_(self): """ Return a string representation of the vertex. - OUTPUT: - - String. + OUTPUT: string TESTS:: @@ -1414,7 +1398,7 @@ def homogeneous_vector(self, base_ring=None): INPUT: - - ``base_ring`` -- the base ring of the vector. + - ``base_ring`` -- the base ring of the vector EXAMPLES:: @@ -1429,7 +1413,7 @@ def homogeneous_vector(self, base_ring=None): def evaluated_on(self, Hobj): r""" - Return `A\vec{x}+b` + Return `A\vec{x}+b`. EXAMPLES:: @@ -1449,9 +1433,7 @@ def is_integral(self): r""" Return whether the coordinates of the vertex are all integral. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1498,7 +1480,7 @@ def type(self): def is_ray(self): """ - Tests if this object is a ray. Always True by construction. + Test if this object is a ray. Always ``True`` by construction. EXAMPLES:: @@ -1531,7 +1513,7 @@ def homogeneous_vector(self, base_ring=None): INPUT: - - ``base_ring`` -- the base ring of the vector. + - ``base_ring`` -- the base ring of the vector EXAMPLES:: @@ -1546,7 +1528,7 @@ def homogeneous_vector(self, base_ring=None): def evaluated_on(self, Hobj): r""" - Return `A\vec{r}` + Return `A\vec{r}`. EXAMPLES:: @@ -1596,7 +1578,7 @@ def type(self): def is_line(self): """ - Tests if the object is a line. By construction it must be. + Test if the object is a line. By construction it must be. TESTS:: @@ -1629,7 +1611,7 @@ def homogeneous_vector(self, base_ring=None): INPUT: - - ``base_ring`` -- the base ring of the vector. + - ``base_ring`` -- the base ring of the vector EXAMPLES:: @@ -1644,7 +1626,7 @@ def homogeneous_vector(self, base_ring=None): def evaluated_on(self, Hobj): r""" - Return `A\vec{\ell}` + Return `A\vec{\ell}`. EXAMPLES:: @@ -1665,27 +1647,25 @@ def repr_pretty(coefficients, type, prefix='x', indices=None, INPUT: - - ``coefficients`` -- a tuple or other iterable + - ``coefficients`` -- tuple or other iterable - ``type`` -- either ``0`` (``PolyhedronRepresentation.INEQUALITY``) or ``1`` (``PolyhedronRepresentation.EQUATION``) - - ``prefix`` -- a string (default: ``x``) - - - ``indices`` -- a tuple or other iterable + - ``prefix`` -- string (default: ``'x'``) - - ``latex`` -- a boolean + - ``indices`` -- tuple or other iterable - - ``split`` -- a boolean; (Default: ``False``). If set to ``True``, - the output is split into a 3-tuple containing the left-hand side, - the relation, and the right-hand side of the object. + - ``latex`` -- boolean - - ``style`` -- either ``"positive"`` (making all coefficients positive), or - ``"<="`` or ``">="``. + - ``split`` -- boolean (default: ``False``); if set to ``True``, + the output is split into a 3-tuple containing the left-hand side, + the relation, and the right-hand side of the object - OUTPUT: + - ``style`` -- either ``'positive'`` (making all coefficients positive), or + ``'<='`` or ``'>='`` - A string or 3-tuple of strings (depending on ``split``). + OUTPUT: a string or 3-tuple of strings (depending on ``split``) EXAMPLES:: diff --git a/src/sage/geometry/pseudolines.py b/src/sage/geometry/pseudolines.py index 38283fae8f8..cb9f68a8ba5 100644 --- a/src/sage/geometry/pseudolines.py +++ b/src/sage/geometry/pseudolines.py @@ -170,20 +170,20 @@ class PseudolineArrangement: - def __init__(self, seq, encoding="auto"): + def __init__(self, seq, encoding='auto'): r""" - Creates an arrangement of pseudolines. + Create an arrangement of pseudolines. INPUT: - - ``seq`` (a sequence describing the line arrangement). It can be: + - ``seq`` -- a sequence describing the line arrangement. It can be: - A list of `n` permutations of size `n-1`. - A list of `\binom n 2` transpositions - A Felsner matrix, given as a sequence of `n` binary vectors of length `n-1`. - - ``encoding`` (information on how the data should be interpreted), and + - ``encoding`` -- information on how the data should be interpreted, and can assume any value among 'transpositions', 'permutations', 'Felsner' or 'auto'. In the latter case, the type will be guessed (default behaviour). @@ -462,8 +462,8 @@ def show(self, **args): l.append((x+2, l[-1][1])) L += line(l) - L += text(str(i), (0, l[0][1]+.3), horizontal_alignment="right") - L += text(str(i), (x+2, l[-1][1]+.3), horizontal_alignment="left") + L += text(str(i), (0, l[0][1]+.3), horizontal_alignment='right') + L += text(str(i), (x+2, l[-1][1]+.3), horizontal_alignment='left') return L.show(axes=False, **args) diff --git a/src/sage/geometry/relative_interior.py b/src/sage/geometry/relative_interior.py index e62a9182211..3d7aa5d1c36 100644 --- a/src/sage/geometry/relative_interior.py +++ b/src/sage/geometry/relative_interior.py @@ -17,7 +17,7 @@ class RelativeInterior(ConvexSet_relatively_open): r""" - The relative interior of a polyhedron or cone + The relative interior of a polyhedron or cone. This class should not be used directly. Use methods :meth:`~sage.geometry.polyhedron.Polyhedron_base.relative_interior`, @@ -43,7 +43,7 @@ def __init__(self, polyhedron): INPUT: - ``polyhedron`` -- an instance of :class:`Polyhedron_base` or - :class:`ConvexRationalPolyhedralCone`. + :class:`ConvexRationalPolyhedralCone` TESTS:: @@ -216,11 +216,9 @@ def closure(self): def is_universe(self): r""" - Return whether ``self`` is the whole ambient space + Return whether ``self`` is the whole ambient space. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -240,9 +238,7 @@ def is_closed(self): r""" Return whether ``self`` is closed. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -370,7 +366,7 @@ def dilation(self, scalar): INPUT: - - ``scalar`` -- A scalar + - ``scalar`` -- a scalar EXAMPLES:: @@ -406,7 +402,7 @@ def linear_transformation(self, linear_transf, **kwds): - ``linear_transf`` -- a matrix - ``**kwds`` -- passed to the :meth:`linear_transformation` method of - the closure of ``self``. + the closure of ``self`` EXAMPLES:: diff --git a/src/sage/geometry/ribbon_graph.py b/src/sage/geometry/ribbon_graph.py index 12918ae29b5..5c2950519ad 100644 --- a/src/sage/geometry/ribbon_graph.py +++ b/src/sage/geometry/ribbon_graph.py @@ -32,6 +32,7 @@ #Auxiliary functions that will be used in the classes. + def _find(l, k): r""" Return the two coordinates of the element ``k`` in the list of @@ -39,13 +40,13 @@ def _find(l, k): INPUT: - - ``l`` -- a list of lists + - ``l`` -- list of lists - ``k`` -- a candidate to be in a list in ``l`` OUTPUT: A list with two integers describing the position of the first - instance of `k`` in ``l``. + instance of ``k`` in ``l``. TESTS:: @@ -74,11 +75,9 @@ def _clean(l): INPUT: - - ``l`` -- a list of lists - - OUTPUT: + - ``l`` -- list of lists - - a list which is a copy of ``l`` with all empty sublists removed + OUTPUT: list which is a copy of ``l`` with all empty sublists removed EXAMPLES:: @@ -409,12 +408,10 @@ def contract_edge(self, k): INPUT: - - ``k`` -- non-negative integer; the position in `\rho` of the + - ``k`` -- nonnegative integer; the position in `\rho` of the transposition that is going to be contracted - OUTPUT: - - - a ribbon graph resulting from the contraction of that edge + OUTPUT: a ribbon graph resulting from the contraction of that edge EXAMPLES: @@ -609,7 +606,7 @@ def genus(self): OUTPUT: - - ``g`` -- non-negative integer representing the genus of the + - ``g`` -- nonnegative integer representing the genus of the thickening of the ribbon graph EXAMPLES:: @@ -1048,7 +1045,6 @@ def normalize(self): Ribbon graph of genus 1 and 1 boundary components (1,2,3)(4,5,6) (1,4)(2,5)(3,6) - """ #First we compute the vertices of valency 1 and store them in val_one. aux_sigma = [list(x) for x in self._sigma.cycle_tuples()] @@ -1083,6 +1079,7 @@ def normalize(self): PermutationConstructor([tuple(x) for x in aux_rho]) ) + def make_ribbon(g, r): r""" Return a ribbon graph whose thickening has genus ``g`` and ``r`` @@ -1090,7 +1087,7 @@ def make_ribbon(g, r): INPUT: - - ``g`` -- non-negative integer representing the genus of the + - ``g`` -- nonnegative integer representing the genus of the thickening - ``r`` -- positive integer representing the number of boundary @@ -1132,7 +1129,6 @@ def make_ribbon(g, r): (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,33,31)(16,32,34,17,18,19,20,21,22,23,24,25,26,27,28,29,30) sage: R.rho() (1,16)(2,17)(3,18)(4,19)(5,20)(6,21)(7,22)(8,23)(9,24)(10,25)(11,26)(12,27)(13,28)(14,29)(15,30)(31,32)(33,34) - """ #Initialize the two vertices of sigma and the edge joining them repr_sigma = [[1],[2*g+2]] @@ -1157,6 +1153,7 @@ def make_ribbon(g, r): return RibbonGraph(PermutationConstructor([tuple(x) for x in repr_sigma]), PermutationConstructor([tuple(x) for x in repr_rho])) + def bipartite_ribbon_graph(p, q): r""" Return the bipartite graph modeling the corresponding @@ -1176,8 +1173,8 @@ def bipartite_ribbon_graph(p, q): INPUT: - - ``p`` -- a positive integer - - ``q`` -- a positive integer + - ``p`` -- positive integer + - ``q`` -- positive integer EXAMPLES:: @@ -1205,15 +1202,14 @@ def bipartite_ribbon_graph(p, q): Ribbon graph of genus 9 and 1 boundary components (1,2,3,4,5,6,7)(8,9,10,11,12,13,14)(15,16,17,18,19,20,21)(22,23,24,25,26,27,28)(29,30,31,32)(33,34,35,36)(37,38,39,40)(41,42,43,44)(45,46,47,48)(49,50,51,52)(53,54,55,56) (1,32)(2,36)(3,40)(4,44)(5,48)(6,52)(7,56)(8,31)(9,35)(10,39)(11,43)(12,47)(13,51)(14,55)(15,30)(16,34)(17,38)(18,42)(19,46)(20,50)(21,54)(22,29)(23,33)(24,37)(25,41)(26,45)(27,49)(28,53) - """ sigma = [] rho = [] for i in range(p): - aux_tuple = [i*q + j + 1 for j in range(q)] + aux_tuple = [i*q + j + 1 for j in range(q)] sigma += [aux_tuple] for i in range(q): - aux_tuple = [p*q + i*p + j + 1 for j in range(p)] + aux_tuple = [p*q + i*p + j + 1 for j in range(p)] sigma += [aux_tuple] for i in range(p*q): if (i+1) % q == 0: diff --git a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py index 43fecdc0609..27940e9a723 100644 --- a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py +++ b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py @@ -33,14 +33,13 @@ def _simplify_full_rad(f): INPUT: - - ``f`` -- a symbolic expression. + - ``f`` -- a symbolic expression EXAMPLES:: sage: from sage.geometry.riemannian_manifolds.parametrized_surface3d import _simplify_full_rad sage: _simplify_full_rad(sqrt(x^2)/x) 1 - """ return f.simplify_full().canonicalize_radical() @@ -56,19 +55,18 @@ class ParametrizedSurface3D(SageObject): INPUT: - - ``surface_equation`` -- a 3-tuple of functions specifying a parametric - representation of the surface. + - ``surface_equation`` -- a 3-tuple of functions specifying a parametric + representation of the surface - - ``variables`` -- a 2-tuple of intrinsic coordinates `(u, v)` on the - surface, with `u` and `v` symbolic variables, or a 2-tuple of triples - `(u, u_{min}, u_{max})`, - `(v, v_{min}, v_{max})` when the parameter range - for the coordinates is known. + - ``variables`` -- a 2-tuple of intrinsic coordinates `(u, v)` on the + surface, with `u` and `v` symbolic variables, or a 2-tuple of triples + `(u, u_{min}, u_{max})`, `(v, v_{min}, v_{max})` when the parameter range + for the coordinates is known - - ``name`` -- name of the surface (optional). + - ``name`` -- name of the surface (optional) - .. note:: + .. NOTE:: Throughout the documentation, we use the Einstein summation convention: whenever an index appears twice, once as a @@ -76,7 +74,6 @@ class ParametrizedSurface3D(SageObject): is implied. For instance, `g_{ij} g^{jk}` stands for `\sum_j g_{ij}g^{jk}`. - EXAMPLES: We give several examples of standard surfaces in differential @@ -343,21 +340,19 @@ class ParametrizedSurface3D(SageObject): ....: (0,2*pi,100))] sage: (S.plot(opacity=0.3) + line3d(g1, color='red') # needs sage.plot ....: + line3d(g2, color='red') + line3d(g3, color='red')).show() - """ def __init__(self, equation, variables, name=None): r""" See ``ParametrizedSurface3D`` for full documentation. - .. note:: + .. NOTE:: The orientation of the surface is determined by the parametrization, that is, the natural frame with positive orientation is given by `\partial_1 \vec r`, `\partial_2 \vec r`. - EXAMPLES:: sage: u, v = var('u,v', domain='real') @@ -365,7 +360,6 @@ def __init__(self, equation, variables, name=None): sage: enneper = ParametrizedSurface3D(eq, (u, v),'Enneper Surface'); enneper Parametrized surface ('Enneper Surface') with equation (-u^3 + 3*u*v^2 + 3*u, 3*u^2*v - v^3 + 3*v, 3*u^2 - 3*v^2) - """ self.equation = tuple(equation) @@ -391,14 +385,13 @@ def _latex_(self): \left(\cos\left(u\right) \cos\left(v\right), \cos\left(v\right) \sin\left(u\right), \sin\left(v\right)\right) sage: sphere._latex_() \left(\cos\left(u\right) \cos\left(v\right), \cos\left(v\right) \sin\left(u\right), \sin\left(v\right)\right) - """ from sage.misc.latex import latex return latex(self.equation) def _repr_(self): r""" - Returns the string representation of this parametrized surface. + Return the string representation of this parametrized surface. EXAMPLES:: @@ -409,7 +402,6 @@ def _repr_(self): Parametrized surface ('enneper_surface') with equation (-u^3 + 3*u*v^2 + 3*u, 3*u^2*v - v^3 + 3*v, 3*u^2 - 3*v^2) sage: enneper._repr_() "Parametrized surface ('enneper_surface') with equation (-u^3 + 3*u*v^2 + 3*u, 3*u^2*v - v^3 + 3*v, 3*u^2 - 3*v^2)" - """ name = 'Parametrized surface' if self.name is not None: @@ -420,15 +412,13 @@ def _repr_(self): def point(self, coords): r""" - Returns a point on the surface given its intrinsic coordinates. + Return a point on the surface given its intrinsic coordinates. INPUT: - - ``coords`` -- 2-tuple specifying the intrinsic coordinates ``(u, v)`` of the point. + - ``coords`` -- 2-tuple specifying the intrinsic coordinates ``(u, v)`` of the point - OUTPUT: - - - 3-vector specifying the coordinates in `\RR^3` of the point. + OUTPUT: 3-vector specifying the coordinates in `\RR^3` of the point EXAMPLES:: @@ -442,7 +432,6 @@ def point(self, coords): (-2, 0, 1) sage: torus.point((pi, pi/2)) (0, 1, 0) - """ d = dict(zip(self.variables_list, coords)) @@ -450,19 +439,18 @@ def point(self, coords): def tangent_vector(self, coords, components): r""" - Returns the components of a tangent vector given the intrinsic + Return the components of a tangent vector given the intrinsic coordinates of the base point and the components of the vector in the intrinsic frame. INPUT: - - ``coords`` -- 2-tuple specifying the intrinsic coordinates ``(u, v)`` of the point. + - ``coords`` -- 2-tuple specifying the intrinsic coordinates ``(u, v)`` of the point - - ``components`` -- 2-tuple specifying the components of the tangent vector in the intrinsic coordinate frame. + - ``components`` -- 2-tuple specifying the components of the tangent + vector in the intrinsic coordinate frame - OUTPUT: - - - 3-vector specifying the components in `\RR^3` of the vector. + OUTPUT: 3-vector specifying the components in `\RR^3` of the vector EXAMPLES: @@ -485,7 +473,6 @@ def tangent_vector(self, coords, components): (-108, 216, -216) sage: n == w1.cross_product(w2) True - """ components = vector(components) @@ -506,8 +493,8 @@ def plot(self, urange=None, vrange=None, **kwds): INPUT: - - ``urange`` -- 2-tuple specifying the parameter range for `u`. - - ``vrange`` -- 2-tuple specifying the parameter range for `v`. + - ``urange`` -- 2-tuple specifying the parameter range for `u` + - ``vrange`` -- 2-tuple specifying the parameter range for `v` EXAMPLES:: @@ -516,7 +503,6 @@ def plot(self, urange=None, vrange=None, **kwds): sage: enneper = ParametrizedSurface3D(eq, (u, v), 'Enneper Surface') sage: enneper.plot((-5, 5), (-5, 5)) # needs sage.plot Graphics3d Object - """ from sage.plot.plot3d.parametric_plot3d import parametric_plot3d @@ -541,13 +527,11 @@ def plot(self, urange=None, vrange=None, **kwds): @cached_method def natural_frame(self): """ - Returns the natural tangent frame on the parametrized surface. + Return the natural tangent frame on the parametrized surface. The vectors of this frame are tangent to the coordinate lines on the surface. - OUTPUT: - - - The natural frame as a dictionary. + OUTPUT: the natural frame as a dictionary EXAMPLES:: @@ -570,15 +554,14 @@ def natural_frame(self): @cached_method def normal_vector(self, normalized=False): """ - Returns the normal vector field of the parametrized surface. + Return the normal vector field of the parametrized surface. INPUT: - - ``normalized`` -- (default ``False``); specifies whether the normal vector should be normalized. - - OUTPUT: + - ``normalized`` -- boolean (default: ``False``); specifies whether + the normal vector should be normalized - - Normal vector field. + OUTPUT: normal vector field EXAMPLES:: @@ -591,7 +574,6 @@ def normal_vector(self, normalized=False): (-2*u/sqrt(4*u^2 + 4*v^2 + 1), -2*v/sqrt(4*u^2 + 4*v^2 + 1), 1/sqrt(4*u^2 + 4*v^2 + 1)) - """ dr = self.natural_frame() @@ -616,7 +598,6 @@ def _compute_first_fundamental_form_coefficient(self, index): sage: eparaboloid = ParametrizedSurface3D((u, v, u^2+v^2), (u, v)) sage: eparaboloid._compute_first_fundamental_form_coefficient((1,2)) 4*u*v - """ dr = self.natural_frame() return _simplify_full_rad(dr[index[0]]*dr[index[1]]) @@ -630,11 +611,9 @@ def first_fundamental_form_coefficient(self, index): INPUT: - - ``index`` -- tuple ``(i, j)`` specifying the index of the component `g_{ij}`. + - ``index`` -- tuple ``(i, j)`` specifying the index of the component `g_{ij}` - OUTPUT: - - - Component `g_{ij}` of the first fundamental form + OUTPUT: component `g_{ij}` of the first fundamental form EXAMPLES:: @@ -651,7 +630,6 @@ def first_fundamental_form_coefficient(self, index): Traceback (most recent call last): ... ValueError: Index (1, 5) out of bounds. - """ index = tuple(sorted(index)) if len(index) == 2 and all(i == 1 or i == 2 for i in index): @@ -661,13 +639,11 @@ def first_fundamental_form_coefficient(self, index): def first_fundamental_form_coefficients(self): r""" - Returns the coefficients of the first fundamental form as a dictionary. + Return the coefficients of the first fundamental form as a dictionary. The keys are tuples `(i, j)`, where `i` and `j` range over `1, 2`, while the values are the corresponding coefficients `g_{ij}`. - OUTPUT: - - - Dictionary of first fundamental form coefficients. + OUTPUT: dictionary of first fundamental form coefficients EXAMPLES:: @@ -675,7 +651,6 @@ def first_fundamental_form_coefficients(self): sage: sphere = ParametrizedSurface3D((cos(u)*cos(v), sin(u)*cos(v), sin(v)), (u, v), 'sphere') sage: sphere.first_fundamental_form_coefficients() {(1, 1): cos(v)^2, (1, 2): 0, (2, 1): 0, (2, 2): 1} - """ coefficients = {} for index in product((1, 2), repeat=2): @@ -693,11 +668,9 @@ def first_fundamental_form(self, vector1, vector2): INPUT: - - ``vector1``, ``vector2`` -- vectors on the surface. - - OUTPUT: + - ``vector1``, ``vector2`` -- vectors on the surface - - First fundamental form evaluated on the input vectors. + OUTPUT: first fundamental form evaluated on the input vectors EXAMPLES:: @@ -720,16 +693,14 @@ def first_fundamental_form(self, vector1, vector2): def area_form_squared(self): """ - Returns the square of the coefficient of the area form on the surface. + Return the square of the coefficient of the area form on the surface. In terms of the coefficients `g_{ij}` (where `i, j = 1, 2`) of the first fundamental form, this invariant is given by `A^2 = g_{11}g_{22} - g_{12}^2`. See also :meth:`.area_form`. - OUTPUT: - - - Square of the area form + OUTPUT: square of the area form EXAMPLES:: @@ -737,7 +708,6 @@ def area_form_squared(self): sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere') sage: sphere.area_form_squared() cos(v)^2 - """ gamma = self.first_fundamental_form_coefficients() sq = gamma[(1,1)] * gamma[(2,2)] - gamma[(1,2)]**2 @@ -745,16 +715,14 @@ def area_form_squared(self): def area_form(self): r""" - Returns the coefficient of the area form on the surface. In terms of + Return the coefficient of the area form on the surface. In terms of the coefficients `g_{ij}` (where `i, j = 1, 2`) of the first fundamental form, the coefficient of the area form is given by `A = \sqrt{g_{11}g_{22} - g_{12}^2}`. See also :meth:`.area_form_squared`. - OUTPUT: - - - Coefficient of the area form + OUTPUT: coefficient of the area form EXAMPLES:: @@ -762,21 +730,18 @@ def area_form(self): sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere') sage: sphere.area_form() cos(v) - """ f = abs(sqrt(self.area_form_squared())) return _simplify_full_rad(f) def first_fundamental_form_inverse_coefficients(self): r""" - Returns the coefficients `g^{ij}` of the inverse of the fundamental + Return the coefficients `g^{ij}` of the inverse of the fundamental form, as a dictionary. The inverse coefficients are defined by `g^{ij} g_{jk} = \delta^i_k` with `\delta^i_k` the Kronecker delta. - OUTPUT: - - - Dictionary of the inverse coefficients. + OUTPUT: dictionary of the inverse coefficients EXAMPLES:: @@ -784,7 +749,6 @@ def first_fundamental_form_inverse_coefficients(self): sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere') sage: sphere.first_fundamental_form_inverse_coefficients() {(1, 1): cos(v)^(-2), (1, 2): 0, (2, 1): 0, (2, 2): 1} - """ g = self.first_fundamental_form_coefficients() @@ -799,16 +763,14 @@ def first_fundamental_form_inverse_coefficients(self): def first_fundamental_form_inverse_coefficient(self, index): r""" - Returns a specific component `g^{ij}` of the inverse of the fundamental + Return a specific component `g^{ij}` of the inverse of the fundamental form. INPUT: - - ``index`` -- tuple ``(i, j)`` specifying the index of the component `g^{ij}`. + - ``index`` -- tuple ``(i, j)`` specifying the index of the component `g^{ij}` - OUTPUT: - - - Component of the inverse of the fundamental form. + OUTPUT: component of the inverse of the fundamental form EXAMPLES:: @@ -818,7 +780,6 @@ def first_fundamental_form_inverse_coefficient(self, index): 0 sage: sphere.first_fundamental_form_inverse_coefficient((1, 1)) cos(v)^(-2) - """ index = tuple(sorted(index)) @@ -830,16 +791,14 @@ def first_fundamental_form_inverse_coefficient(self, index): @cached_method def rotation(self,theta): r""" - Gives the matrix of the rotation operator over a given angle `\theta` + Give the matrix of the rotation operator over a given angle `\theta` with respect to the natural frame. INPUT: - - ``theta`` -- rotation angle + - ``theta`` -- rotation angle - OUTPUT: - - - Rotation matrix with respect to the natural frame. + OUTPUT: rotation matrix with respect to the natural frame ALGORITHM: @@ -864,7 +823,6 @@ def rotation(self,theta): sage: rotation^3 [-1 0] [ 0 -1] - """ from sage.functions.trig import sin, cos @@ -880,18 +838,16 @@ def rotation(self,theta): @cached_method def orthonormal_frame(self, coordinates='ext'): r""" - Returns the orthonormal frame field on the surface, expressed either + Return the orthonormal frame field on the surface, expressed either in exterior coordinates (i.e. expressed as vector fields in the ambient space `\mathbb{R}^3`, the default) or interior coordinates (with respect to the natural frame) INPUT: - - ``coordinates`` -- either ``ext`` (default) or ``int``. - - OUTPUT: + - ``coordinates`` -- either ``ext`` (default) or ``int`` - - Orthogonal frame field as a dictionary. + OUTPUT: orthogonal frame field as a dictionary ALGORITHM: @@ -945,18 +901,16 @@ def orthonormal_frame(self, coordinates='ext'): def orthonormal_frame_vector(self, index, coordinates='ext'): r""" - Returns a specific basis vector field of the orthonormal frame field on + Return a specific basis vector field of the orthonormal frame field on the surface, expressed in exterior or interior coordinates. See :meth:`orthogonal_frame` for more details. INPUT: - - ``index`` -- index of the basis vector; - - ``coordinates`` -- either ``ext`` (default) or ``int``. + - ``index`` -- index of the basis vector + - ``coordinates`` -- either ``ext`` (default) or ``int`` - OUTPUT: - - - Orthonormal frame vector field. + OUTPUT: orthonormal frame vector field EXAMPLES:: @@ -981,19 +935,16 @@ def orthonormal_frame_vector(self, index, coordinates='ext'): def lie_bracket(self, v, w): r""" - Returns the Lie bracket of two vector fields that are tangent + Return the Lie bracket of two vector fields that are tangent to the surface. The vector fields should be given in intrinsic coordinates, i.e. with respect to the natural frame. INPUT: - - ``v`` and ``w`` -- vector fields on the surface, expressed - as pairs of functions or as vectors of length 2. - - OUTPUT: - - - The Lie bracket `[v, w]`. + - ``v``, ``w`` -- vector fields on the surface, expressed + as pairs of functions or as vectors of length 2 + OUTPUT: the Lie bracket `[v, w]` EXAMPLES:: @@ -1019,22 +970,21 @@ def lie_bracket(self, v, w): def frame_structure_functions(self, e1, e2): r""" - Returns the structure functions `c^k_{ij}` for a frame field + Return the structure functions `c^k_{ij}` for a frame field `e_1, e_2`, i.e. a pair of vector fields on the surface which are linearly independent at each point. The structure functions are defined using the Lie bracket by `[e_i,e_j] = c^k_{ij}e_k`. INPUT: - - ``e1``, ``e2`` -- vector fields in intrinsic coordinates on - the surface, expressed as pairs of functions, or as vectors of - length 2. + - ``e1``, ``e2`` -- vector fields in intrinsic coordinates on + the surface, expressed as pairs of functions, or as vectors of + length 2 OUTPUT: - - Dictionary of structure functions, where the key ``(i, j, k)`` refers to - the structure function `c_{i,j}^k`. - + Dictionary of structure functions, where the key ``(i, j, k)`` refers to + the structure function `c_{i,j}^k`. EXAMPLES:: @@ -1095,7 +1045,6 @@ def _compute_second_order_frame_element(self, index): (0, 0, 0) sage: paraboloid._compute_second_order_frame_element((2, 2)) (0, 0, 2) - """ variables = [self.variables[i] for i in index] ddr_element = vector([_simplify_full_rad(diff(f, variables)) @@ -1105,7 +1054,7 @@ def _compute_second_order_frame_element(self, index): def second_order_natural_frame(self): r""" - Returns the second-order frame of the surface, i.e. computes the + Return the second-order frame of the surface, i.e. computes the second-order derivatives (with respect to the parameters on the surface) of the parametric expression `\vec r = \vec r(u^1,u^2)` of the surface. @@ -1125,7 +1074,6 @@ def second_order_natural_frame(self): (1, 2): (sin(u)*sin(v), -cos(u)*sin(v), 0), (2, 1): (sin(u)*sin(v), -cos(u)*sin(v), 0), (2, 2): (-cos(u)*cos(v), -cos(v)*sin(u), -sin(v))} - """ vectors = {} @@ -1137,18 +1085,16 @@ def second_order_natural_frame(self): def second_order_natural_frame_element(self, index): r""" - Returns a vector in the second-order frame of the surface, i.e. + Return a vector in the second-order frame of the surface, i.e. computes the second-order derivatives of the parametric expression `\vec{r}` of the surface with respect to the parameters listed in the argument. INPUT: - - ``index`` -- a 2-tuple ``(i, j)`` specifying the element of the second-order frame. - - OUTPUT: + - ``index`` -- a 2-tuple ``(i, j)`` specifying the element of the second-order frame - - The second-order derivative `r_{ij}`. + OUTPUT: the second-order derivative `r_{ij}` EXAMPLES:: @@ -1156,7 +1102,6 @@ def second_order_natural_frame_element(self, index): sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere') sage: sphere.second_order_natural_frame_element((1, 2)) (sin(u)*sin(v), -cos(u)*sin(v), 0) - """ index = tuple(sorted(index)) @@ -1180,7 +1125,6 @@ def _compute_second_fundamental_form_coefficient(self, index): sage: paraboloid = ParametrizedSurface3D([u, v, u^2+v^2], [u, v], 'paraboloid') sage: paraboloid._compute_second_fundamental_form_coefficient((1,1)) 2/sqrt(4*u^2 + 4*v^2 + 1) - """ N = self.normal_vector(normalized=True) v = self.second_order_natural_frame_element(index) @@ -1188,18 +1132,16 @@ def _compute_second_fundamental_form_coefficient(self, index): def second_fundamental_form_coefficient(self, index): r""" - Returns the coefficient `h_{ij}` of the second fundamental form + Return the coefficient `h_{ij}` of the second fundamental form corresponding to the index `(i, j)`. If the equation of the surface is `\vec{r}(u^1, u^2)`, then `h_{ij} = \vec{r}_{u^i u^j} \cdot \vec{n}`, where `\vec{n}` is the unit normal. INPUT: - - ``index`` -- a 2-tuple ``(i, j)`` + - ``index`` -- a 2-tuple ``(i, j)`` - OUTPUT: - - - Component `h_{ij}` of the second fundamental form. + OUTPUT: component `h_{ij}` of the second fundamental form EXAMPLES:: @@ -1210,7 +1152,6 @@ def second_fundamental_form_coefficient(self, index): -cos(v)^2 sage: sphere.second_fundamental_form_coefficient((2, 1)) 0 - """ index = tuple(index) if len(index) == 2 and all(i == 1 or i == 2 for i in index): @@ -1220,16 +1161,14 @@ def second_fundamental_form_coefficient(self, index): def second_fundamental_form_coefficients(self): """ - Returns the coefficients `h_{ij}` of the second fundamental form as + Return the coefficients `h_{ij}` of the second fundamental form as a dictionary, where the keys are the indices `(i, j)` and the values are the corresponding components `h_{ij}`. When only one component is needed, consider instead the function :meth:`second_fundamental_form_coefficient`. - OUTPUT: - - Dictionary of second fundamental form coefficients. + OUTPUT: dictionary of second fundamental form coefficients EXAMPLES:: @@ -1238,7 +1177,6 @@ def second_fundamental_form_coefficients(self): sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere') sage: sphere.second_fundamental_form_coefficients() {(1, 1): -cos(v)^2, (1, 2): 0, (2, 1): 0, (2, 2): -1} - """ coefficients = {} @@ -1255,11 +1193,9 @@ def second_fundamental_form(self,vector1,vector2): INPUT: - - ``vector1``, ``vector2`` -- 2-tuples representing the input vectors. - - OUTPUT: + - ``vector1``, ``vector2`` -- 2-tuples representing the input vectors - - Value of the second fundamental form evaluated on the given vectors. + OUTPUT: value of the second fundamental form evaluated on the given vectors EXAMPLES: @@ -1280,7 +1216,6 @@ def second_fundamental_form(self,vector1,vector2): -cos(v)^2 - 4 sage: sphere.second_fundamental_form([1,1], [2,1]) -2*cos(v)^2 - 1 - """ hh = self.second_fundamental_form_coefficients() return sum(hh[(i, j)] * vector1[i - 1] * vector2[j - 1] @@ -1293,9 +1228,7 @@ def gauss_curvature(self): where `g_{ij}` and `h_{ij}` are the coefficients of the first and second fundamental form, respectively. - OUTPUT: - - - Gaussian curvature of the surface. + OUTPUT: Gaussian curvature of the surface. EXAMPLES:: @@ -1306,7 +1239,6 @@ def gauss_curvature(self): sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere') sage: sphere.gauss_curvature() R^(-2) - """ hh = self.second_fundamental_form_coefficients() return _simplify_full_rad( @@ -1319,9 +1251,7 @@ def mean_curvature(self): where `g_{ij}` and `h_{ij}` are the components of the first and second fundamental forms, respectively. - OUTPUT: - - - Mean curvature of the surface + OUTPUT: mean curvature of the surface EXAMPLES:: @@ -1332,7 +1262,6 @@ def mean_curvature(self): sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere') sage: sphere.mean_curvature() -1/R - """ gg = self.first_fundamental_form_coefficients() hh = self.second_fundamental_form_coefficients() @@ -1344,13 +1273,13 @@ def mean_curvature(self): @cached_method def shape_operator_coefficients(self): r""" - Returns the components of the shape operator of the surface as a + Return the components of the shape operator of the surface as a dictionary. See ``shape_operator`` for more information. OUTPUT: - - Dictionary where the keys are two-tuples ``(i, j)``, with values the - corresponding component of the shape operator. + Dictionary where the keys are two-tuples ``(i, j)``, with values the + corresponding component of the shape operator. EXAMPLES:: @@ -1360,7 +1289,6 @@ def shape_operator_coefficients(self): sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere') sage: sphere.shape_operator_coefficients() {(1, 1): -1/R, (1, 2): 0, (2, 1): 0, (2, 2): -1/R} - """ gi = self.first_fundamental_form_inverse_coefficients() @@ -1375,14 +1303,12 @@ def shape_operator_coefficients(self): def shape_operator(self): r""" - Returns the shape operator of the surface as a matrix. The shape + Return the shape operator of the surface as a matrix. The shape operator is defined as the derivative of the Gauss map, and is computed here in terms of the first and second fundamental form by means of the Weingarten equations. - OUTPUT: - - - Matrix of the shape operator + OUTPUT: matrix of the shape operator EXAMPLES:: @@ -1405,7 +1331,6 @@ def shape_operator(self): [ -8*u*v/(4*u^2 + 4*v^2 + 1)^(3/2) 2*(4*u^2 + 1)/(4*u^2 + 4*v^2 + 1)^(3/2)] sage: S.eigenvalues() [2*sqrt(4*u^2 + 4*v^2 + 1)/(16*u^4 + 16*v^4 + 8*(4*u^2 + 1)*v^2 + 8*u^2 + 1), 2/sqrt(4*u^2 + 4*v^2 + 1)] - """ shop = self.shape_operator_coefficients() @@ -1415,7 +1340,7 @@ def shape_operator(self): def principal_directions(self): r""" - Finds the principal curvatures and principal directions of the surface + Finds the principal curvatures and principal directions of the surface. OUTPUT: @@ -1447,7 +1372,7 @@ def principal_directions(self): @cached_method def connection_coefficients(self): r""" - Computes the connection coefficients or Christoffel symbols + Compute the connection coefficients or Christoffel symbols `\Gamma^k_{ij}` of the surface. If the coefficients of the first fundamental form are given by `g_{ij}` (where `i, j = 1, 2`), then `\Gamma^k_{ij} = \frac{1}{2} g^{kl} \left( \frac{\partial g_{li}}{\partial x^j} @@ -1478,7 +1403,6 @@ def connection_coefficients(self): (2, 1, 2): 0, (2, 2, 1): 0, (2, 2, 2): 0} - """ x = self.variables gg = self.first_fundamental_form_coefficients() @@ -1509,7 +1433,6 @@ def _create_geodesic_ode_system(self): sage: ode = sphere._create_geodesic_ode_system() sage: ode.function(0.0, (1.0, 0.0, 1.0, 1.0)) [1.00000000000000, 1.00000000000000, -0.4546487134128409, 3.114815449309804] - """ from sage.ext.fast_eval import fast_float from sage.calculus.ode import ode_solver @@ -1551,23 +1474,25 @@ def geodesics_numerical(self, p0, v0, tinterval): INPUT: - - ``p0`` -- 2-tuple with coordinates of the initial point. + - ``p0`` -- 2-tuple with coordinates of the initial point - - ``v0`` -- 2-tuple with components of the initial tangent vector to the geodesic. + - ``v0`` -- 2-tuple with components of the initial tangent vector to the geodesic - - ``tinterval`` -- List ``[a, b, M]``, where ``(a,b)`` is the domain of the geodesic and ``M`` is the number of subdivision points used when returning the solution. + - ``tinterval`` -- list ``[a, b, M]``, where ``(a,b)`` is the domain + of the geodesic and ``M`` is the number of subdivision points used + when returning the solution OUTPUT: List of lists ``[t, [u1(t), u2(t)], [v1(t), v2(t)], [x1(t), x2(t), x3(t)]]``, where - - ``t`` is a subdivision point; + - ``t`` -- a subdivision point; - - ``[u1(t), u2(t)]`` are the intrinsic coordinates of the geodesic point; + - ``[u1(t), u2(t)]`` are the intrinsic coordinates of the geodesic point; - - ``[v1(t), v2(t)]`` are the intrinsic coordinates of the tangent vector to the geodesic; + - ``[v1(t), v2(t)]`` are the intrinsic coordinates of the tangent vector to the geodesic; - - ``[x1(t), x2(t), x3(t)]`` are the coordinates of the geodesic point in the three-dimensional space. + - ``[x1(t), x2(t), x3(t)]`` are the coordinates of the geodesic point in the three-dimensional space. EXAMPLES:: @@ -1605,8 +1530,8 @@ def _create_pt_ode_system(self, curve, t): INPUT: - - ``curve`` -- curve in intrinsic coordinates along which to do parallel transport. - - ``t`` -- curve parameter + - ``curve`` -- curve in intrinsic coordinates along which to do parallel transport + - ``t`` -- curve parameter EXAMPLES:: @@ -1616,7 +1541,6 @@ def _create_pt_ode_system(self, curve, t): sage: ode = sphere._create_pt_ode_system((s, s), s) sage: ode.function(0.0, (1.0, 1.0)) [-0.0, 0.0] - """ from sage.ext.fast_eval import fast_float @@ -1647,7 +1571,7 @@ def _create_pt_ode_system(self, curve, t): def parallel_translation_numerical(self,curve,t,v0,tinterval): r""" - Numerically solves the equations for parallel translation of a vector + Numerically solve the equations for parallel translation of a vector along a curve on the surface. Explicitly, the equations for parallel translation are given by `\frac{d u^i}{dt} + u^j \frac{d c^k}{dt} \Gamma^i_{jk} = 0`, @@ -1663,24 +1587,24 @@ def parallel_translation_numerical(self,curve,t,v0,tinterval): INPUT: - - ``curve`` -- 2-tuple of functions which determine the curve with respect to - the local coordinate system; + - ``curve`` -- 2-tuple of functions which determine the curve with respect to + the local coordinate system - - ``t`` -- symbolic variable denoting the curve parameter; + - ``t`` -- symbolic variable denoting the curve parameter - - ``v0`` -- 2-tuple representing the initial vector; + - ``v0`` -- 2-tuple representing the initial vector - - ``tinterval`` -- list ``[a, b, N]``, where ``(a, b)`` is the domain of the curve - and ``N`` is the number of subdivision points. + - ``tinterval`` -- list ``[a, b, N]``, where ``(a, b)`` is the domain of the curve + and ``N`` is the number of subdivision points OUTPUT: The list consisting of lists ``[t, [v1(t), v2(t)]]``, where - - ``t`` is a subdivision point; + - ``t`` -- a subdivision point; - - ``[v1(t), v2(t)]`` is the list of coordinates of the vector parallel translated - along the curve. + - ``[v1(t), v2(t)]`` is the list of coordinates of the vector parallel translated + along the curve. EXAMPLES:: @@ -1697,7 +1621,6 @@ def parallel_translation_numerical(self,curve,t,v0,tinterval): [0.0000, 0.1571, 0.3142, 0.4712, 0.6283, 0.7854] sage: [round4(v) for v in components] [[1.000, 1.000], [0.9876, 1.025], [0.9499, 1.102], [0.8853, 1.238], [0.7920, 1.448], [0.6687, 1.762]] - """ solver = self._create_pt_ode_system(tuple(curve), t) diff --git a/src/sage/geometry/riemannian_manifolds/surface3d_generators.py b/src/sage/geometry/riemannian_manifolds/surface3d_generators.py index 859951befd2..76177dc279b 100644 --- a/src/sage/geometry/riemannian_manifolds/surface3d_generators.py +++ b/src/sage/geometry/riemannian_manifolds/surface3d_generators.py @@ -28,9 +28,9 @@ class SurfaceGenerators: in 3D. """ @staticmethod - def Catenoid(c=1, name="Catenoid"): + def Catenoid(c=1, name='Catenoid'): r""" - Return a catenoid surface, with parametric representation + Return a catenoid surface, with parametric representation. .. MATH:: @@ -42,9 +42,9 @@ def Catenoid(c=1, name="Catenoid"): INPUT: - - ``c`` -- surface parameter. + - ``c`` -- surface parameter - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Catenoid`. @@ -61,9 +61,9 @@ def Catenoid(c=1, name="Catenoid"): return ParametrizedSurface3D(catenoid_eq, coords, name) @staticmethod - def Crosscap(r=1, name="Crosscap"): + def Crosscap(r=1, name='Crosscap'): r""" - Return a crosscap surface, with parametrization + Return a crosscap surface, with parametrization. .. MATH:: @@ -75,9 +75,9 @@ def Crosscap(r=1, name="Crosscap"): INPUT: - - ``r`` -- surface parameter. + - ``r`` -- surface parameter - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Cross-cap`. @@ -97,7 +97,7 @@ def Crosscap(r=1, name="Crosscap"): @staticmethod def Dini(a=1, b=1, name="Dini's surface"): r""" - Return Dini's surface, with parametrization + Return Dini's surface, with parametrization. .. MATH:: @@ -109,9 +109,9 @@ def Dini(a=1, b=1, name="Dini's surface"): INPUT: - - ``a``, ``b`` -- surface parameters. + - ``a``, ``b`` -- surface parameters - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Dini%27s_surface`. @@ -129,7 +129,7 @@ def Dini(a=1, b=1, name="Dini's surface"): return ParametrizedSurface3D(dini_eq, coords, name) @staticmethod - def Ellipsoid(center=(0, 0, 0), axes=(1, 1, 1), name="Ellipsoid"): + def Ellipsoid(center=(0, 0, 0), axes=(1, 1, 1), name='Ellipsoid'): r""" Return an ellipsoid centered at ``center`` whose semi-principal axes have lengths given by the components of ``axes``. The @@ -145,11 +145,11 @@ def Ellipsoid(center=(0, 0, 0), axes=(1, 1, 1), name="Ellipsoid"): INPUT: - - ``center`` -- 3-tuple. Coordinates of the center of the ellipsoid. + - ``center`` -- 3-tuple; coordinates of the center of the ellipsoid - - ``axes`` -- 3-tuple. Lengths of the semi-principal axes. + - ``axes`` -- 3-tuple; lengths of the semi-principal axes - - ``name`` -- string. Name of the ellipsoid. + - ``name`` -- string; name of the ellipsoid For more information, see :wikipedia:`Ellipsoid`. @@ -172,7 +172,7 @@ def Ellipsoid(center=(0, 0, 0), axes=(1, 1, 1), name="Ellipsoid"): @staticmethod def Enneper(name="Enneper's surface"): r""" - Return Enneper's surface, with parametrization + Return Enneper's surface, with parametrization. .. MATH:: @@ -184,7 +184,7 @@ def Enneper(name="Enneper's surface"): INPUT: - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Enneper_surface`. @@ -201,9 +201,9 @@ def Enneper(name="Enneper's surface"): return ParametrizedSurface3D(enneper_eq, coords, name) @staticmethod - def Helicoid(h=1, name="Helicoid"): + def Helicoid(h=1, name='Helicoid'): r""" - Return a helicoid surface, with parametrization + Return a helicoid surface, with parametrization. .. MATH:: @@ -216,9 +216,9 @@ def Helicoid(h=1, name="Helicoid"): INPUT: - ``h`` -- distance along the z-axis between two - successive turns of the helicoid. + successive turns of the helicoid - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Helicoid`. @@ -249,9 +249,9 @@ def Klein(r=1, name="Klein bottle"): INPUT: - - ``r`` -- radius of the "figure-8" circle. + - ``r`` -- radius of the "figure-8" circle - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Klein_bottle`. @@ -282,7 +282,7 @@ def MonkeySaddle(name="Monkey saddle"): INPUT: - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Monkey_saddle`. @@ -302,7 +302,7 @@ def MonkeySaddle(name="Monkey saddle"): @staticmethod def Paraboloid(a=1, b=1, c=1, elliptic=True, name=None): r""" - Return a paraboloid with equation + Return a paraboloid with equation. .. MATH:: @@ -313,12 +313,12 @@ def Paraboloid(a=1, b=1, c=1, elliptic=True, name=None): INPUT: - - ``a``, ``b``, ``c`` -- Surface parameters. + - ``a``, ``b``, ``c`` -- surface parameters - - ``elliptic`` (default: ``True``) -- whether to create an elliptic or - hyperbolic paraboloid. + - ``elliptic`` -- boolean (default: ``True``); whether to create an + elliptic or hyperbolic paraboloid - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Paraboloid`. @@ -353,17 +353,17 @@ def Paraboloid(a=1, b=1, c=1, elliptic=True, name=None): return ParametrizedSurface3D(paraboloid_eq, coords, name) @staticmethod - def Sphere(center=(0, 0, 0), R=1, name="Sphere"): + def Sphere(center=(0, 0, 0), R=1, name='Sphere'): r""" Return a sphere of radius ``R`` centered at ``center``. INPUT: - - ``center`` -- 3-tuple, center of the sphere. + - ``center`` -- 3-tuple; center of the sphere - - ``R`` -- Radius of the sphere. + - ``R`` -- radius of the sphere - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Sphere`. @@ -394,7 +394,7 @@ def Sphere(center=(0, 0, 0), R=1, name="Sphere"): return SurfaceGenerators.Ellipsoid(center, (R, R, R), name) @staticmethod - def Torus(r=2, R=3, name="Torus"): + def Torus(r=2, R=3, name='Torus'): r""" Return a torus obtained by revolving a circle of radius ``r`` around a coplanar axis ``R`` units away from the center of the circle. The @@ -410,9 +410,9 @@ def Torus(r=2, R=3, name="Torus"): INPUT: - - ``r``, ``R`` -- Minor and major radius of the torus. + - ``r``, ``R`` -- minor and major radius of the torus - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Torus`. @@ -439,7 +439,7 @@ def WhitneyUmbrella(name="Whitney's umbrella"): INPUT: - - ``name`` -- string. Name of the surface. + - ``name`` -- string; name of the surface For more information, see :wikipedia:`Whitney_umbrella`. diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index d37888416b5..a79bac65c6e 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -169,11 +169,9 @@ def is_ToricLattice(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - - ``True`` if ``x`` is a toric lattice and ``False`` otherwise. + OUTPUT: ``True`` if ``x`` is a toric lattice and ``False`` otherwise EXAMPLES:: @@ -204,11 +202,9 @@ def is_ToricLatticeQuotient(x): INPUT: - - ``x`` -- anything. - - OUTPUT: + - ``x`` -- anything - - ``True`` if ``x`` is a toric lattice quotient and ``False`` otherwise. + OUTPUT: ``True`` if ``x`` is a toric lattice quotient and ``False`` otherwise EXAMPLES:: @@ -245,19 +241,17 @@ class ToricLatticeFactory(UniqueFactory): INPUT: - - ``rank`` -- nonnegative integer, the only mandatory parameter; + - ``rank`` -- nonnegative integer; the only mandatory parameter - - ``name`` -- string; + - ``name`` -- string - - ``dual_name`` -- string; + - ``dual_name`` -- string - - ``latex_name`` -- string; + - ``latex_name`` -- string - - ``latex_dual_name`` -- string. + - ``latex_dual_name`` -- string - OUTPUT: - - - lattice. + OUTPUT: lattice A toric lattice is uniquely determined by its rank and associated names. There are four such "associated names" whose meaning should be clear from @@ -413,9 +407,7 @@ def __call__(self, *args, **kwds): - anything that can be interpreted as coordinates, except for elements of other lattices. - OUTPUT: - - - :class:`~sage.geometry.toric_lattice_element.ToricLatticeElement`. + OUTPUT: :class:`~sage.geometry.toric_lattice_element.ToricLatticeElement` TESTS:: @@ -485,7 +477,6 @@ def _coerce_map_from_(self, other): Traceback (most recent call last): ... TypeError: N(1, 2, 3) cannot be converted to 3-d lattice M! - """ if (isinstance(other, ToricLattice_generic) and other.ambient_module() is not self.ambient_module()): @@ -498,12 +489,10 @@ def __contains__(self, point): INPUT: - - ``point`` -- anything. - - OUTPUT: + - ``point`` -- anything - - ``True`` if ``point`` is an element of ``self``, ``False`` - otherwise. + OUTPUT: ``True`` if ``point`` is an element of ``self``, ``False`` + otherwise TESTS:: @@ -541,9 +530,9 @@ def construction(self): OUTPUT: - - ``None``, we do not think of toric lattices as constructed from - simpler objects since we do not want to perform arithmetic involving - different lattices. + ``None``, we do not think of toric lattices as constructed from + simpler objects since we do not want to perform arithmetic involving + different lattices. TESTS:: @@ -558,7 +547,7 @@ def direct_sum(self, other): INPUT: - - ``other`` -- a toric lattice or more general module. + - ``other`` -- a toric lattice or more general module OUTPUT: @@ -658,10 +647,10 @@ def quotient(self, sub, check=True, INPUT: - - ``sub`` -- sublattice of self; + - ``sub`` -- sublattice of self - - ``check`` -- (default: ``True``) whether or not to check that ``sub`` is - a valid sublattice. + - ``check`` -- boolean (default: ``True``); whether or not to check that ``sub`` is + a valid sublattice If the quotient is one-dimensional and torsion free, the following two mutually exclusive keyword arguments are also @@ -693,7 +682,7 @@ def quotient(self, sub, check=True, by Sublattice Attempting to quotient one lattice by a sublattice of another - will result in a :class:`ValueError`:: + will result in a :exc:`ValueError`:: sage: N = ToricLattice(3) sage: M = ToricLattice(3, name='M') @@ -755,9 +744,7 @@ def saturation(self): r""" Return the saturation of ``self``. - OUTPUT: - - - a :class:`toric lattice `. + OUTPUT: a :class:`toric lattice ` EXAMPLES:: @@ -781,13 +768,11 @@ def span(self, gens, base_ring=ZZ, *args, **kwds): INPUT: - ``gens`` -- list of elements of the ambient vector space of - ``self``. + ``self`` - - ``base_ring`` -- (default: `\ZZ`) base ring for the generated module. - - OUTPUT: + - ``base_ring`` -- (default: `\ZZ`) base ring for the generated module - - submodule spanned by ``gens``. + OUTPUT: submodule spanned by ``gens`` .. NOTE:: @@ -827,13 +812,11 @@ def span_of_basis(self, basis, base_ring=ZZ, *args, **kwds): INPUT: - ``basis`` -- list of elements of the ambient vector space of - ``self``. + ``self`` - - ``base_ring`` -- (default: `\ZZ`) base ring for the generated module. + - ``base_ring`` -- (default: `\ZZ`) base ring for the generated module - OUTPUT: - - - submodule spanned by ``basis``. + OUTPUT: submodule spanned by ``basis`` .. NOTE:: @@ -943,11 +926,9 @@ def __richcmp__(self, right, op): INPUT: - - ``right`` -- anything. + - ``right`` -- anything - OUTPUT: - - boolean + OUTPUT: boolean There is equality if ``right`` is a toric lattice of the same dimension as ``self`` and their associated names are the @@ -984,9 +965,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1000,9 +979,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1016,9 +993,7 @@ def ambient_module(self): r""" Return the ambient module of ``self``. - OUTPUT: - - - :class:`toric lattice `. + OUTPUT: :class:`toric lattice ` .. NOTE:: @@ -1039,9 +1014,7 @@ def dual(self): r""" Return the lattice dual to ``self``. - OUTPUT: - - - :class:`toric lattice `. + OUTPUT: :class:`toric lattice ` EXAMPLES:: @@ -1077,9 +1050,7 @@ def plot(self, **options): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -1105,17 +1076,15 @@ class ToricLattice_sublattice_with_basis(ToricLattice_generic, :class:`~sage.modules.free_module.FreeModule_submodule_with_basis_pid`): - ``ambient`` -- ambient :class:`toric lattice ` for - this sublattice; + this sublattice - ``basis`` -- list of linearly independent elements of ``ambient``, these elements will be used as the default basis of the constructed - sublattice; + sublattice - - see the base class for other available options. + - see the base class for other available options - OUTPUT: - - - sublattice of a toric lattice with a user-specified basis. + OUTPUT: sublattice of a toric lattice with a user-specified basis See also :class:`ToricLattice_sublattice` if you do not want to specify an explicit basis. @@ -1149,9 +1118,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1171,9 +1138,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1194,9 +1159,7 @@ def dual(self): r""" Return the lattice dual to ``self``. - OUTPUT: - - - a :class:`toric lattice quotient `. + OUTPUT: a :class:`toric lattice quotient ` EXAMPLES:: @@ -1223,9 +1186,7 @@ def plot(self, **options): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -1236,7 +1197,7 @@ def plot(self, **options): Now we plot both the ambient lattice and its sublattice:: - sage: N.plot() + sublattice.plot(point_color="red") # needs sage.plot + sage: N.plot() + sublattice.plot(point_color='red') # needs sage.plot Graphics3d Object """ if "show_lattice" not in options: @@ -1262,16 +1223,14 @@ class ToricLattice_sublattice(ToricLattice_sublattice_with_basis, :class:`~sage.modules.free_module.FreeModule_submodule_pid`): - ``ambient`` -- ambient :class:`toric lattice ` for - this sublattice; + this sublattice - ``gens`` -- list of elements of ``ambient`` generating the constructed - sublattice; + sublattice - - see the base class for other available options. + - see the base class for other available options - OUTPUT: - - - sublattice of a toric lattice with an automatically chosen basis. + OUTPUT: sublattice of a toric lattice with an automatically chosen basis See also :class:`ToricLattice_sublattice_with_basis` if you want to specify an explicit basis. @@ -1315,9 +1274,7 @@ class ToricLattice_quotient_element(FGP_Element): - same as for :class:`~sage.modules.fg_pid.fgp_element.FGP_Element`. - OUTPUT: - - - element of a toric lattice quotient. + OUTPUT: element of a toric lattice quotient TESTS:: @@ -1342,9 +1299,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1360,9 +1315,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1378,11 +1331,9 @@ def set_immutable(self): r""" Make ``self`` immutable. - OUTPUT: - - - none. + OUTPUT: none - .. note:: Elements of toric lattice quotients are always immutable, so + .. NOTE:: Elements of toric lattice quotients are always immutable, so this method does nothing, it is introduced for compatibility purposes only. @@ -1402,12 +1353,12 @@ class ToricLattice_quotient(FGP_Module_class): INPUT: - - ``V`` -- ambient toric lattice; + - ``V`` -- ambient toric lattice - - ``W`` -- sublattice of ``V``; + - ``W`` -- sublattice of ``V`` - - ``check`` -- (default: ``True``) whether to check correctness of input - or not. + - ``check`` -- boolean (default: ``True``); whether to check correctness of input + or not If the quotient is one-dimensional and torsion free, the following two mutually exclusive keyword arguments are also allowed. They @@ -1428,9 +1379,7 @@ class ToricLattice_quotient(FGP_Module_class): Further given named arguments are passed to the constructor of an FGP module. - OUTPUT: - - - quotient of ``V`` by ``W``. + OUTPUT: quotient of ``V`` by ``W`` EXAMPLES: @@ -1472,7 +1421,7 @@ class ToricLattice_quotient(FGP_Module_class): def __init__(self, V, W, check=True, positive_point=None, positive_dual_point=None, **kwds): r""" - The constructor + The constructor. See :class:`ToricLattice_quotient` for an explanation of the arguments. @@ -1483,7 +1432,7 @@ def __init__(self, V, W, check=True, positive_point=None, positive_dual_point=No sage: ToricLattice_quotient(N, N.span([N(1,2,3)])) 2-d lattice, quotient of 3-d lattice N by Sublattice - An :class:`ArithmeticError` will be raised if ``W`` is not a + An :exc:`ArithmeticError` will be raised if ``W`` is not a sublattice of ``V``:: sage: N = ToricLattice(3) @@ -1607,9 +1556,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1629,9 +1576,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -1659,12 +1604,12 @@ def _module_constructor(self, V, W, check=True): INPUT: - - ``V`` -- ambient toric lattice; + - ``V`` -- ambient toric lattice - - ``W`` -- sublattice of ``V``; + - ``W`` -- sublattice of ``V`` - - ``check`` -- (default: ``True``) whether to check - correctness of input or not. + - ``check`` -- boolean (default: ``True``); whether to check + correctness of input or not TESTS:: @@ -1683,12 +1628,10 @@ def base_extend(self, R): INPUT: - - ``R`` -- either `\ZZ` or `\QQ`. + - ``R`` -- either `\ZZ` or `\QQ` - OUTPUT: - - - ``self`` if `R=\ZZ`, quotient of the base extension of the ambient - lattice by the base extension of the sublattice if `R=\QQ`. + OUTPUT: ``self`` if `R=\ZZ`, quotient of the base extension of the ambient + lattice by the base extension of the sublattice if `R=\QQ` EXAMPLES:: @@ -1716,9 +1659,7 @@ def is_torsion_free(self): r""" Check if ``self`` is torsion-free. - OUTPUT: - - - ``True`` is ``self`` has no torsion and ``False`` otherwise. + OUTPUT: ``True`` if ``self`` has no torsion and ``False`` otherwise EXAMPLES:: @@ -1738,9 +1679,7 @@ def dual(self): r""" Return the lattice dual to ``self``. - OUTPUT: - - - a :class:`toric lattice quotient `. + OUTPUT: a :class:`toric lattice quotient ` EXAMPLES:: @@ -1760,9 +1699,7 @@ def rank(self): r""" Return the rank of ``self``. - OUTPUT: - - Integer. The dimension of the free part of the quotient. + OUTPUT: integer; the dimension of the free part of the quotient EXAMPLES:: @@ -1793,12 +1730,10 @@ def coordinate_vector(self, x, reduce=False): - ``x`` -- element of ``self`` or convertible to ``self`` - - ``reduce`` -- (default: ``False``); if ``True``, reduce coefficients + - ``reduce`` -- (default: ``False``) if ``True``, reduce coefficients modulo invariants - OUTPUT: - - The coordinates as a vector. + OUTPUT: the coordinates as a vector EXAMPLES:: diff --git a/src/sage/geometry/toric_lattice_element.pyx b/src/sage/geometry/toric_lattice_element.pyx index 5fb647a60ba..1b8178077eb 100644 --- a/src/sage/geometry/toric_lattice_element.pyx +++ b/src/sage/geometry/toric_lattice_element.pyx @@ -109,11 +109,9 @@ def is_ToricLatticeElement(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - - ``True`` if ``x`` is an element of a toric lattice, ``False`` otherwise. + OUTPUT: ``True`` if ``x`` is an element of a toric lattice, ``False`` otherwise EXAMPLES:: @@ -154,9 +152,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): - same as for :class:`~sage.modules.vector_integer_dense.Vector_integer_dense`. - OUTPUT: - - - element of a toric lattice. + OUTPUT: element of a toric lattice TESTS:: @@ -176,9 +172,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): - ``right`` -- another ToricLatticeElement - OUTPUT: - - boolean + OUTPUT: boolean First compare the ambient toric lattice, then compare the vectors. @@ -212,9 +206,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): r""" Return the hash of ``self``. - OUTPUT: - - - integer. + OUTPUT: integer TESTS:: @@ -236,7 +228,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): INPUT: - - ``other`` -- :class:`ToricLatticeElement`. + - ``other`` -- :class:`ToricLatticeElement` OUTPUT: @@ -307,18 +299,16 @@ cdef class ToricLatticeElement(Vector_integer_dense): # is wrong from our point of view. cpdef _dot_product_(self, Vector right): """ - Raise a :class:`TypeError` exception. + Raise a :exc:`TypeError` exception. Dot product is not defined on toric lattices (there are actions of dual lattices on each other instead). INPUT: - - ``right`` -- vector. - - OUTPUT: + - ``right`` -- vector - - :class:`TypeError` exception is raised. + OUTPUT: :exc:`TypeError` exception is raised TESTS:: @@ -339,9 +329,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -357,9 +345,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -393,9 +379,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -412,21 +396,19 @@ cdef class ToricLatticeElement(Vector_integer_dense): def unpickle_v1(parent, entries, degree, is_mutable): """ - Unpickle a :class:`ToricLatticeElement` + Unpickle a :class:`ToricLatticeElement`. INPUT: - - ``parent`` -- The parent toric lattice. - - - ``entries`` -- a list. The coordinates of the lattice point. + - ``parent`` -- the parent toric lattice - - ``degree`` -- integer. the dimension of the toric lattice. + - ``entries`` -- list; the coordinates of the lattice point - - ``is_mutable`` -- boolean. Whether the lattice element is mutable. + - ``degree`` -- integer; the dimension of the toric lattice - OUTPUT: + - ``is_mutable`` -- boolean; whether the lattice element is mutable - The :class:`ToricLatticeElement` determined by the input data. + OUTPUT: the :class:`ToricLatticeElement` determined by the input data EXAMPLES:: diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py index e6dfb454027..398903fc76a 100644 --- a/src/sage/geometry/toric_plotter.py +++ b/src/sage/geometry/toric_plotter.py @@ -116,17 +116,15 @@ class ToricPlotter(SageObject): - ``all_options`` -- a :class:`dictionary `, containing any of the options related to toric objects (see :func:`options`) and any other - options that will be passed to lower level plotting functions; + options that will be passed to lower level plotting functions - - ``dimension`` -- an integer (1, 2, or 3), dimension of toric objects to - be plotted; + - ``dimension`` -- integer (1, 2, or 3); dimension of toric objects to + be plotted - - ``generators`` -- (optional) a list of ray generators, see examples for - a detailed explanation of this argument. + - ``generators`` -- (optional) a list of ray generators; see examples for + a detailed explanation of this argument - OUTPUT: - - - a toric plotter. + OUTPUT: a toric plotter EXAMPLES: @@ -248,11 +246,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- anything. - - OUTPUT: + - ``other`` -- anything - - ``True`` if ``self`` is equal to ``other``, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is equal to ``other``, ``False`` otherwise TESTS:: @@ -273,9 +269,7 @@ def adjust_options(self): that were not specified by the user, based on the other options. See :class:`ToricPlotter` for a detailed example. - OUTPUT: - - - none. + OUTPUT: none TESTS:: @@ -307,14 +301,12 @@ def adjust_options(self): for key in ["xmin", "ymin", "zmin"]: if round or sd[key] is None: sd[key] = - r - if sd[key] > - 0.5: - sd[key] = - 0.5 + sd[key] = min(sd[key], - 0.5) sd[key] = RDF(sd[key]) for key in ["xmax", "ymax", "zmax"]: if round or sd[key] is None: sd[key] = r - if sd[key] < 0.5: - sd[key] = 0.5 + sd[key] = max(sd[key], 0.5) sd[key] = RDF(sd[key]) if self.show_lattice is None: self.show_lattice = (r <= 5) if d <= 2 else r <= 3 @@ -325,15 +317,13 @@ def include_points(self, points, force=False): INPUT: - - ``points`` -- a list of points; + - ``points`` -- list of points - - ``force`` -- boolean (default: ``False``). by default, only bounds + - ``force`` -- boolean (default: ``False``); by default, only bounds that were not set before will be chosen to include ``points``. Use ``force=True`` if you don't mind increasing existing bounding box. - OUTPUT: - - - none. + OUTPUT: none EXAMPLES:: @@ -382,9 +372,7 @@ def plot_generators(self): Ray generators must be specified during construction or using :meth:`set_rays` before calling this method. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -429,13 +417,11 @@ def plot_labels(self, labels, positions): INPUT: - - ``labels`` -- a string or a list of strings; + - ``labels`` -- string or list of strings - - ``positions`` -- a list of points. + - ``positions`` -- list of points - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -466,9 +452,7 @@ def plot_lattice(self): r""" Plot the lattice (i.e. its points in the cut-off bounds of ``self``). - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -508,11 +492,9 @@ def plot_points(self, points): INPUT: - - ``points`` -- a list of points. - - OUTPUT: + - ``points`` -- list of points - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -535,9 +517,7 @@ def plot_ray_labels(self): Ray generators must be specified during construction or using :meth:`set_rays` before calling this method. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -556,9 +536,7 @@ def plot_rays(self): Ray generators must be specified during construction or using :meth:`set_rays` before calling this method. - OUTPUT: - - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -595,11 +573,9 @@ def plot_walls(self, walls): INPUT: - - ``walls`` -- a list of 2-d cones. - - OUTPUT: + - ``walls`` -- list of 2-d cones - - a plot. + OUTPUT: a plot EXAMPLES:: @@ -692,11 +668,9 @@ def set_rays(self, generators): INPUT: - - ``generators`` -- a list of primitive non-zero ray generators. + - ``generators`` -- list of primitive nonzero ray generators - OUTPUT: - - - none. + OUTPUT: none EXAMPLES:: @@ -742,11 +716,9 @@ def _unrecognized_option(option): INPUT: - - ``option`` -- a string. - - OUTPUT: + - ``option`` -- string - - none, a :class:`KeyError` exception is raised. + OUTPUT: none, a :exc:`KeyError` exception is raised TESTS:: @@ -770,11 +742,9 @@ def color_list(color, n): - ``color`` -- anything specifying a :class:`Color`, a list of such specifications, or the string "rainbow"; - - ``n`` -- an integer. + - ``n`` -- integer - OUTPUT: - - - a list of ``n`` colors. + OUTPUT: list of ``n`` colors If ``color`` specified a single color, it is repeated ``n`` times. If it was a list of ``n`` colors, it is returned without changes. If it was @@ -822,19 +792,17 @@ def label_list(label, n, math_mode, index_set=None): INPUT: - - ``label`` -- ``None``, a string, or a list of string; + - ``label`` -- ``None``, a string, or a list of string - - ``n`` -- an integer; + - ``n`` -- integer - - ``math_mode`` -- boolean, if ``True``, will produce LaTeX expressions - for labels; + - ``math_mode`` -- boolean; if ``True``, will produce LaTeX expressions + for labels - - ``index_set`` -- a list of integers (default: ``range(n)``) that will be - used as subscripts for labels. + - ``index_set`` -- list of integers (default: ``range(n)``) that will be + used as subscripts for labels - OUTPUT: - - - a list of ``n`` labels. + OUTPUT: list of ``n`` labels If ``label`` was a list of ``n`` entries, it is returned without changes. If ``label`` is ``None``, a list of ``n`` ``None``'s is returned. If @@ -886,7 +854,7 @@ def options(option=None, **kwds): OR: - - ``option`` -- a string, name of the option whose value you wish to get; + - ``option`` -- string, name of the option whose value you wish to get; OR: @@ -973,31 +941,31 @@ def options(option=None, **kwds): - ``wall_alpha`` -- a number between 0 and 1, the alpha-value for walls (determining their transparency); - - ``point_size`` -- an integer, the size of lattice points; + - ``point_size`` -- integer; the size of lattice points - - ``ray_thickness`` -- an integer, the thickness of rays; + - ``ray_thickness`` -- integer; the thickness of rays - - ``generator_thickness`` -- an integer, the thickness of generators; + - ``generator_thickness`` -- integer; the thickness of generators - - ``font_size`` -- an integer, the size of font used for labels; + - ``font_size`` -- integer; the size of font used for labels - - ``ray_label`` -- a string or a list of strings used for ray labels; use - ``None`` to hide labels; + - ``ray_label`` -- string or list of strings used for ray labels; use + ``None`` to hide labels - - ``wall_label`` -- a string or a list of strings used for wall labels; use - ``None`` to hide labels; + - ``wall_label`` -- string or list of strings used for wall labels; use + ``None`` to hide labels - ``radius`` -- a positive number, the radius of the cut-off region for - "round" mode; + "round" mode - ``xmin``, ``xmax``, ``ymin``, ``ymax``, ``zmin``, ``zmax`` -- numbers determining the cut-off region for "box" mode. Note that you cannot exclude the origin - if you try to do so, bounds will be automatically - expanded to include it; + expanded to include it. - ``lattice_filter`` -- a callable, taking as an argument a lattice point and returning ``True`` if this point should be included on the plot - (useful, e.g. for plotting sublattices); + (useful, e.g. for plotting sublattices) - ``wall_zorder``, ``ray_zorder``, ``generator_zorder``, ``point_zorder``, ``label_zorder`` -- integers, z-orders for different classes of objects. @@ -1022,12 +990,12 @@ def options(option=None, **kwds): The following line will make all subsequent toric plotting commands to draw "rainbows" from walls:: - sage: toric_plotter.options(wall_color="rainbow") + sage: toric_plotter.options(wall_color='rainbow') If you prefer a less colorful output (e.g. if you need black-and-white illustrations for a paper), you can use something like this:: - sage: toric_plotter.options(wall_color="grey") + sage: toric_plotter.options(wall_color='grey') """ global _options if option is None and not kwds: @@ -1052,9 +1020,7 @@ def reset_options(): r""" Reset options for plots of toric geometry objects. - OUTPUT: - - - none. + OUTPUT: none EXAMPLES:: @@ -1096,14 +1062,12 @@ def sector(ray1, ray2, **extra_options): INPUT: - ``ray1``, ``ray2`` -- rays in 2- or 3-dimensional space of the same - length; + length - - ``extra_options`` -- a dictionary of options that should be passed to - lower level plotting functions. - - OUTPUT: + - ``extra_options`` -- dictionary of options that should be passed to + lower level plotting functions - - a plot. + OUTPUT: a plot EXAMPLES:: diff --git a/src/sage/geometry/triangulation/base.pyx b/src/sage/geometry/triangulation/base.pyx index cb9cb948256..55144d1623c 100644 --- a/src/sage/geometry/triangulation/base.pyx +++ b/src/sage/geometry/triangulation/base.pyx @@ -50,18 +50,18 @@ cdef class Point(SageObject): INPUT: - - ``point_configuration`` -- :class:`PointConfiguration_base`. The - point configuration to which the point belongs. + - ``point_configuration`` -- :class:`PointConfiguration_base`; the + point configuration to which the point belongs - - ``i`` -- integer. The index of the point in the point - configuration. + - ``i`` -- integer; the index of the point in the point + configuration - - ``projective`` -- the projective coordinates of the point. + - ``projective`` -- the projective coordinates of the point - - ``affine`` -- the affine coordinates of the point. + - ``affine`` -- the affine coordinates of the point - ``reduced`` -- the reduced (with linearities removed) - coordinates of the point. + coordinates of the point EXAMPLES:: @@ -99,7 +99,7 @@ cdef class Point(SageObject): def __hash__(self): r""" - Hash value for a point in a point configuration + Hash value for a point in a point configuration. EXAMPLES:: @@ -113,9 +113,7 @@ cdef class Point(SageObject): r""" Return the point configuration to which the point belongs. - OUTPUT: - - A :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`. + OUTPUT: a :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration` EXAMPLES:: @@ -176,9 +174,7 @@ cdef class Point(SageObject): r""" Return the projective coordinates of the point in the ambient space. - OUTPUT: - - A tuple containing the coordinates. + OUTPUT: a tuple containing the coordinates EXAMPLES:: @@ -202,9 +198,7 @@ cdef class Point(SageObject): r""" Return the affine coordinates of the point in the ambient space. - OUTPUT: - - A tuple containing the coordinates. + OUTPUT: a tuple containing the coordinates EXAMPLES:: @@ -229,9 +223,7 @@ cdef class Point(SageObject): Return the affine coordinates of the point on the hyperplane spanned by the point configuration. - OUTPUT: - - A tuple containing the coordinates. + OUTPUT: a tuple containing the coordinates EXAMPLES:: @@ -256,9 +248,7 @@ cdef class Point(SageObject): Return the projective coordinates of the point on the hyperplane spanned by the point configuration. - OUTPUT: - - A tuple containing the coordinates. + OUTPUT: a tuple containing the coordinates EXAMPLES:: @@ -283,9 +273,7 @@ cdef class Point(SageObject): Return the affine coordinates of the point on the hyperplane spanned by the point configuration. - OUTPUT: - - A tuple containing the coordinates. + OUTPUT: a tuple containing the coordinates EXAMPLES:: @@ -310,9 +298,7 @@ cdef class Point(SageObject): Return the affine coordinates of the point on the hyperplane spanned by the point configuration. - OUTPUT: - - A tuple containing the coordinates. + OUTPUT: a tuple containing the coordinates EXAMPLES:: @@ -338,9 +324,7 @@ cdef class Point(SageObject): """ Return a string representation of the point. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -372,12 +356,12 @@ cdef class PointConfiguration_base(Parent): INPUT: - - ``points`` -- a tuple of tuples of projective coordinates - with ``1`` as the final coordinate. + - ``points`` -- tuple of tuples of projective coordinates + with ``1`` as the final coordinate - - ``defined_affine`` -- Boolean. Whether the point + - ``defined_affine`` -- boolean; whether the point configuration is defined as a configuration of affine (as - opposed to projective) points. + opposed to projective) points TESTS:: @@ -470,9 +454,7 @@ cdef class PointConfiguration_base(Parent): """ Return the vector space that contains the affine points. - OUTPUT: - - A vector space over the fraction field of :meth:`base_ring`. + OUTPUT: a vector space over the fraction field of :meth:`base_ring` EXAMPLES:: @@ -491,9 +473,7 @@ cdef class PointConfiguration_base(Parent): Return the vector space that is spanned by the homogeneous coordinates. - OUTPUT: - - A vector space over the fraction field of :meth:`base_ring`. + OUTPUT: a vector space over the fraction field of :meth:`base_ring` EXAMPLES:: @@ -545,9 +525,7 @@ cdef class PointConfiguration_base(Parent): Return the base ring, that is, the ring containing the coordinates of the points. - OUTPUT: - - A ring. + OUTPUT: a ring EXAMPLES:: @@ -569,10 +547,8 @@ cdef class PointConfiguration_base(Parent): """ Return whether the configuration is defined by affine points. - OUTPUT: - - Boolean. If true, the homogeneous coordinates all have `1` as - their last entry. + OUTPUT: boolean; if true, the homogeneous coordinates all have `1` as + their last entry EXAMPLES:: @@ -588,7 +564,7 @@ cdef class PointConfiguration_base(Parent): def _assert_is_affine(self): """ - Raise a :class:`ValueError` if the point configuration is not + Raise a :exc:`ValueError` if the point configuration is not defined by affine points. EXAMPLES:: @@ -612,11 +588,9 @@ cdef class PointConfiguration_base(Parent): INPUT: - - ``i`` -- integer. - - OUTPUT: + - ``i`` -- integer - The ``i``-th point of the point configuration. + OUTPUT: the ``i``-th point of the point configuration EXAMPLES:: @@ -680,17 +654,15 @@ cdef class PointConfiguration_base(Parent): def point(self, i): """ - Return the i-th point of the configuration. + Return the `i`-th point of the configuration. Same as :meth:`__getitem__` INPUT: - - ``i`` -- integer. + - ``i`` -- integer - OUTPUT: - - A point of the point configuration. + OUTPUT: a point of the point configuration EXAMPLES:: @@ -742,11 +714,9 @@ cdef class PointConfiguration_base(Parent): INPUT: - ``simplex`` -- iterable, for example a list. The elements - are the vertex indices of the simplex. - - OUTPUT: + are the vertex indices of the simplex - An integer that uniquely specifies the simplex. + OUTPUT: integer that uniquely specifies the simplex EXAMPLES:: @@ -785,7 +755,7 @@ cdef class PointConfiguration_base(Parent): INPUT: - - ``s`` -- int. An integer that uniquely specifies a simplex. + - ``s`` -- integer that uniquely specifies a simplex OUTPUT: @@ -830,12 +800,12 @@ cdef class PointConfiguration_base(Parent): ######################################################################## cdef class ConnectedTriangulationsIterator(SageObject): r""" - A Python shim for the C++-class 'triangulations' + A Python shim for the C++-class 'triangulations'. INPUT: - ``point_configuration`` -- a - :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`. + :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration` - ``seed`` -- a regular triangulation or ``None`` (default). In the latter case, a suitable triangulation is generated @@ -856,7 +826,7 @@ cdef class ConnectedTriangulationsIterator(SageObject): integer is passed, all returned triangulations will be star with respect to the - - ``fine`` -- boolean (default: ``False``). Whether to return only + - ``fine`` -- boolean (default: ``False``); whether to return only fine triangulations, that is, simplicial decompositions that make use of all the points of the configuration. diff --git a/src/sage/geometry/triangulation/element.py b/src/sage/geometry/triangulation/element.py index 3e6e0ed152d..2baf66a578e 100644 --- a/src/sage/geometry/triangulation/element.py +++ b/src/sage/geometry/triangulation/element.py @@ -55,13 +55,11 @@ def triangulation_render_2d(triangulation, **kwds): INPUT: - - ``triangulation`` -- a :class:`Triangulation`. + - ``triangulation`` -- a :class:`Triangulation` - - ``**kwds`` -- keywords that are passed on to the graphics primitives. + - ``**kwds`` -- keywords that are passed on to the graphics primitives - OUTPUT: - - A 2-d graphics object. + OUTPUT: a 2-d graphics object EXAMPLES:: @@ -116,13 +114,11 @@ def triangulation_render_3d(triangulation, **kwds): INPUT: - - ``triangulation`` -- a :class:`Triangulation`. - - - ``**kwds`` -- keywords that are passed on to the graphics primitives. + - ``triangulation`` -- a :class:`Triangulation` - OUTPUT: + - ``**kwds`` -- keywords that are passed on to the graphics primitives - A 3-d graphics object. + OUTPUT: a 3-d graphics object EXAMPLES:: @@ -236,9 +232,9 @@ def __init__(self, triangulation, parent, check=True): by the correspondence :meth:`PointConfiguration.simplex_to_int`. In the second case, a simplex is specified by listing the indices of the included points. - - ``check`` -- boolean. Whether to perform checks that the + - ``check`` -- boolean; whether to perform checks that the triangulation is, indeed, a triangulation of the point - configuration. + configuration NOTE: @@ -270,7 +266,7 @@ def __init__(self, triangulation, parent, check=True): def point_configuration(self): """ - Returns the point configuration underlying the triangulation. + Return the point configuration underlying the triangulation. EXAMPLES:: @@ -339,15 +335,15 @@ def __iter__(self): def __getitem__(self, i): """ - Access the point indices of the i-th simplex of the triangulation. + Access the point indices of the `i`-th simplex of the triangulation. INPUT: - - ``i`` -- integer. The index of a simplex. + - ``i`` -- integer; the index of a simplex OUTPUT: - A tuple of integers. The vertex indices of the i-th simplex. + A tuple of integers. The vertex indices of the `i`-th simplex. EXAMPLES:: @@ -433,9 +429,7 @@ def gkz_phi(self): that is, the total volume of all simplices containing `p_i`. See also [GKZ1994]_ page 220 equation 1.4. - OUTPUT: - - The phi vector of self. + OUTPUT: the phi vector of self EXAMPLES:: @@ -456,9 +450,7 @@ def enumerate_simplices(self): r""" Return the enumerated simplices. - OUTPUT: - - A tuple of integers that uniquely specifies the triangulation. + OUTPUT: a tuple of integers that uniquely specifies the triangulation EXAMPLES:: @@ -513,7 +505,7 @@ def fan(self, origin=None): coordinates of the points are shifted so that the apex of the fan is the origin of the coordinate system. - .. note:: If the set of cones over the simplices is not a fan, a + .. NOTE:: If the set of cones over the simplices is not a fan, a suitable exception is raised. EXAMPLES:: @@ -558,9 +550,7 @@ def simplicial_complex(self): r""" Return ``self`` as an (abstract) simplicial complex. - OUTPUT: - - A :class:`~sage.topology.simplicial_complex.SimplicialComplex`. + OUTPUT: a :class:`~sage.topology.simplicial_complex.SimplicialComplex` EXAMPLES:: @@ -660,9 +650,7 @@ def boundary_simplicial_complex(self): r""" Return the boundary of ``self`` as an (abstract) simplicial complex. - OUTPUT: - - A :class:`~sage.topology.simplicial_complex.SimplicialComplex`. + OUTPUT: a :class:`~sage.topology.simplicial_complex.SimplicialComplex` EXAMPLES:: @@ -918,7 +906,6 @@ def adjacency_graph(self): sage: t = p.triangulate() sage: t.adjacency_graph() # needs sage.graphs Graph on 8 vertices - """ vertices = [Set(_) for _ in list(self)] from sage.graphs.graph import Graph diff --git a/src/sage/geometry/triangulation/meson.build b/src/sage/geometry/triangulation/meson.build new file mode 100644 index 00000000000..dec407d83d5 --- /dev/null +++ b/src/sage/geometry/triangulation/meson.build @@ -0,0 +1,26 @@ +py.install_sources( + 'all.py', + 'data.pxd', + 'element.py', + 'functions.pxd', + 'point_configuration.py', + 'triangulations.pxd', + subdir: 'sage/geometry/triangulation', +) + +extension_data_cpp = { + 'base': files('base.pyx', 'data.cc', 'functions.cc', 'triangulations.cc'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/geometry/triangulation', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index b71ae4cb348..88aa25f6c46 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -18,13 +18,9 @@ Finding a single triangulation and listing all connected triangulations is implemented natively in this package. However, for -more advanced options [TOPCOM]_ needs to be installed. It is available -as an optional package for Sage, and you can install it with the -shell command :: +more advanced options [TOPCOM]_ needs to be installed; see :ref:`spkg_topcom`. - sage -i topcom - -.. note:: +.. NOTE:: TOPCOM and the internal algorithms tend to enumerate triangulations in a different order. This is why we always @@ -184,6 +180,8 @@ import itertools +from sage.features import FeatureNotPresentError +from sage.features.topcom import TOPCOMExecutable from sage.structure.unique_representation import UniqueRepresentation from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import @@ -217,25 +215,25 @@ class PointConfiguration(UniqueRepresentation, PointConfiguration_base): The constructor accepts the following arguments: - - ``points`` -- the points. Technically, any iterable of iterables + - ``points`` -- the points; technically, any iterable of iterables will do. In particular, a :class:`PointConfiguration` can be passed. - - ``projective`` -- boolean (default: ``False``). Whether the + - ``projective`` -- boolean (default: ``False``); whether the point coordinates should be interpreted as projective (``True``) or affine (``False``) coordinates. If necessary, points are projectivized by setting the last homogeneous coordinate to one and/or affine patches are chosen internally. - - ``connected`` -- boolean (default: ``True``). Whether the + - ``connected`` -- boolean (default: ``True``); whether the triangulations should be connected to the regular triangulations via bistellar flips. These are much easier to compute than all triangulations. - - ``fine`` -- boolean (default: ``False``). Whether the + - ``fine`` -- boolean (default: ``False``); whether the triangulations must be fine, that is, make use of all points of - the configuration. + the configuration - - ``regular`` -- boolean or ``None`` (default: ``None``). Whether + - ``regular`` -- boolean or ``None`` (default: ``None``); whether the triangulations must be regular. A regular triangulation is one that is induced by a piecewise-linear convex support function. In other words, the shadows of the faces of a @@ -247,7 +245,7 @@ class PointConfiguration(UniqueRepresentation, PointConfiguration_base): * ``None`` (default): Both kinds of triangulation. - - ``star`` -- either ``None`` or a point. Whether the + - ``star`` -- either ``None`` or a point; whether the triangulations must be star. A triangulation is star if all maximal simplices contain a common point. The central point can be specified by its index (an integer) in the given points or by @@ -291,7 +289,7 @@ def _have_TOPCOM(cls): PointConfiguration._have_TOPCOM_cached = True assert out == '{{0,1}}',\ 'TOPCOM ran but did not produce the correct output!' - except pexpect.ExceptionPexpect: + except (FeatureNotPresentError, pexpect.ExceptionPexpect): PointConfiguration._have_TOPCOM_cached = False PointConfiguration.set_engine('auto') @@ -404,7 +402,7 @@ def star_center(self): A :class:`~sage.geometry.triangulation.base.Point` if a distinguished star central point has been fixed. - :class:`ValueError` exception is raised otherwise. + :exc:`ValueError` exception is raised otherwise. EXAMPLES:: @@ -589,13 +587,13 @@ def _TOPCOM_exec(cls, executable, input_string, verbose=True): INPUT: - - ``executable`` -- string. The name of the executable. + - ``executable`` -- string; the name of the executable - - ``input_string`` -- string. Will be piped into the running - executable's stdin. + - ``input_string`` -- string; will be piped into the running + executable's stdin - - ``verbose`` -- boolean. Whether to print out the TOPCOM - interaction. + - ``verbose`` -- boolean; whether to print out the TOPCOM + interaction TESTS:: @@ -613,7 +611,9 @@ def _TOPCOM_exec(cls, executable, input_string, verbose=True): ['{{0,1,2,4},{1,2,3,4}}'] """ timeout = 600 - proc = pexpect.spawn(executable, timeout=timeout) + executable_name, *args = executable.split() + executable_absname = TOPCOMExecutable(executable_name).absolute_filename() + proc = pexpect.spawn(executable_absname, args, timeout=timeout) proc.expect(r'Evaluating Commandline Options \.\.\.') proc.expect(r'\.\.\. done\.') proc.setecho(0) @@ -691,7 +691,7 @@ def _TOPCOM_communicate(self, executable, verbose=True): def _TOPCOM_triangulations(self, verbose=True): r""" - Returns all triangulations satisfying the restrictions imposed. + Return all triangulations satisfying the restrictions imposed. EXAMPLES:: @@ -729,13 +729,13 @@ def _TOPCOM_triangulate(self, verbose=True): INPUT: - - ``verbose`` -- boolean. Whether to print out the TOPCOM - interaction. + - ``verbose`` -- boolean; whether to print out the TOPCOM + interaction OUTPUT: A :class:`~sage.geometry.triangulation.element.Triangulation` - satisfying all restrictions imposed. This raises a :class:`ValueError` + satisfying all restrictions imposed. This raises a :exc:`ValueError` if no such triangulation exists. EXAMPLES:: @@ -771,9 +771,9 @@ def restrict_to_regular_triangulations(self, regular=True): INPUT: - - ``regular`` -- ``True``, ``False``, or ``None``. Whether to + - ``regular`` -- ``True``, ``False``, or ``None``; whether to restrict to regular triangulations, irregular - triangulations, or lift any restrictions on regularity. + triangulations, or lift any restrictions on regularity OUTPUT: @@ -815,9 +815,9 @@ def restrict_to_connected_triangulations(self, connected=True): INPUT: - - ``connected`` -- boolean. Whether to restrict to + - ``connected`` -- boolean; whether to restrict to triangulations that are connected by bistellar flips to the - regular triangulations. + regular triangulations OUTPUT: @@ -854,7 +854,7 @@ def restrict_to_fine_triangulations(self, fine=True): INPUT: - - ``fine`` -- boolean. Whether to restrict to fine triangulations. + - ``fine`` -- boolean; whether to restrict to fine triangulations OUTPUT: @@ -927,10 +927,10 @@ def restrict_to_star_triangulations(self, star): def triangulations(self, verbose=False): r""" - Returns all triangulations. + Return all triangulations. - - ``verbose`` -- boolean (default: ``False``). Whether to - print out the TOPCOM interaction, if any. + - ``verbose`` -- boolean (default: ``False``); whether to + print out the TOPCOM interaction, if any OUTPUT: @@ -1004,8 +1004,8 @@ def triangulations_list(self, verbose=False): INPUT: - - ``verbose`` -- boolean. Whether to print out the TOPCOM - interaction, if any. + - ``verbose`` -- boolean; whether to print out the TOPCOM + interaction, if any OUTPUT: @@ -1033,13 +1033,13 @@ def triangulate(self, verbose=False): INPUT: - - ``verbose`` -- boolean. Whether to print out the TOPCOM - interaction, if any. + - ``verbose`` -- boolean; whether to print out the TOPCOM + interaction, if any OUTPUT: A :class:`~sage.geometry.triangulation.element.Triangulation` - satisfying all restrictions imposed. This raises a :class:`ValueError` + satisfying all restrictions imposed. This raises a :exc:`ValueError` if no such triangulation exists. EXAMPLES:: @@ -1237,8 +1237,8 @@ def exclude_points(self, point_idx_list): INPUT: - - ``point_idx_list`` -- a list of integers. The indices of - points to exclude. + - ``point_idx_list`` -- list of integers; the indices of + points to exclude OUTPUT: @@ -1271,8 +1271,8 @@ def volume(self, simplex=None): INPUT: - - ``simplex`` (optional argument) -- a simplex from a - triangulation T specified as a list of point indices. + - ``simplex`` -- (optional argument) a simplex from a + triangulation T specified as a list of point indices OUTPUT: @@ -1297,7 +1297,7 @@ def volume(self, simplex=None): sage: p.volume() 2 - .. note:: + .. NOTE:: We return `n!` * (metric volume of the simplex) to ensure that the volume is an integer. Essentially, this normalizes @@ -1485,18 +1485,16 @@ def circuits(self): def positive_circuits(self, *negative): r""" - Returns the positive part of circuits with fixed negative part. + Return the positive part of circuits with fixed negative part. A circuit is a pair `(C_+, C_-)`, each consisting of a subset (actually, an ordered tuple) of point indices. INPUT: - - ``*negative`` -- integer. The indices of points. - - OUTPUT: + - ``*negative`` -- integer; the indices of points - A tuple of all circuits with `C_-` = ``negative``. + OUTPUT: a tuple of all circuits with `C_-` = ``negative`` EXAMPLES:: @@ -1656,7 +1654,7 @@ def make_cotriang(basepts): @cached_method def distance_affine(self, x, y): r""" - Returns the distance between two points. + Return the distance between two points. The distance function used in this method is `d_{aff}(x,y)^2`, the square of the usual affine distance function @@ -1667,7 +1665,7 @@ def distance_affine(self, x, y): INPUT: - - ``x``, ``y`` -- two points of the point configuration. + - ``x``, ``y`` -- two points of the point configuration OUTPUT: @@ -1691,7 +1689,7 @@ def distance_affine(self, x, y): @cached_method def distance_FS(self, x, y): r""" - Returns the distance between two points. + Return the distance between two points. The distance function used in this method is `1-\cos d_{FS}(x,y)^2`, where `d_{FS}` is the Fubini-Study distance of @@ -1703,7 +1701,7 @@ def distance_FS(self, x, y): INPUT: - - ``x``, ``y`` -- two points of the point configuration. + - ``x``, ``y`` -- two points of the point configuration OUTPUT: @@ -1728,11 +1726,11 @@ def distance_FS(self, x, y): @cached_method def distance(self, x, y): """ - Returns the distance between two points. + Return the distance between two points. INPUT: - - ``x``, ``y`` -- two points of the point configuration. + - ``x``, ``y`` -- two points of the point configuration OUTPUT: @@ -1764,9 +1762,9 @@ def farthest_point(self, points, among=None): INPUT: - - ``points`` -- a list of points. + - ``points`` -- list of points - - ``among`` -- a list of points or ``None`` (default). The set + - ``among`` -- list of points or ``None`` (default); the set of points from which to pick the farthest one. By default, all points of the configuration are considered. @@ -1804,17 +1802,17 @@ def contained_simplex(self, large=True, initial_point=None, point_order=None): INPUT: - - ``large`` -- boolean. Whether to attempt to return a large - simplex. + - ``large`` -- boolean; whether to attempt to return a large + simplex - ``initial_point`` -- a :class:`~sage.geometry.triangulation.base.Point` or ``None`` (default). A specific point to start with when picking the simplex vertices. - - ``point_order`` -- a list or tuple of (some or all) + - ``point_order`` -- list or tuple of (some or all) :class:`~sage.geometry.triangulation.base.Point` s or ``None`` - (default). + (default) OUTPUT: @@ -1911,9 +1909,7 @@ def placing_triangulation(self, point_order=None): will be placed in some arbitrary order that attempts to produce a small number of simplices. - OUTPUT: - - A :class:`~sage.geometry.triangulation.triangulation.Triangulation`. + OUTPUT: a :class:`~sage.geometry.triangulation.triangulation.Triangulation` EXAMPLES:: @@ -2049,13 +2045,11 @@ def Gale_transform(self, points=None): INPUT: - - ``points`` -- a tuple of points or point indices or ``None`` + - ``points`` -- tuple of points or point indices or ``None`` (default). A subset of points for which to compute the Gale transform. By default, all points are used. - OUTPUT: - - A matrix over :meth:`base_ring`. + OUTPUT: a matrix over :meth:`base_ring` EXAMPLES:: diff --git a/src/sage/geometry/voronoi_diagram.py b/src/sage/geometry/voronoi_diagram.py index a4c110ff647..1402e0b1e77 100644 --- a/src/sage/geometry/voronoi_diagram.py +++ b/src/sage/geometry/voronoi_diagram.py @@ -29,12 +29,10 @@ class VoronoiDiagram(SageObject): INPUT: - - ``points`` -- a list of points. Any valid input for the - :class:`PointConfiguration` will do. + - ``points`` -- list of points; any valid input for the + :class:`PointConfiguration` will do - OUTPUT: - - An instance of the VoronoiDiagram class. + OUTPUT: an instance of the VoronoiDiagram class EXAMPLES: @@ -251,11 +249,9 @@ def plot(self, cell_colors=None, **kwds): - ``cell_colors`` -- (default: ``None``) provide the colors for the cells, either as dictionary. Randomly colored cells are provided with ``None``. - ``**kwds`` -- optional keyword parameters, passed on as arguments for - plot(). - - OUTPUT: + plot() - A graphics object. + OUTPUT: a graphics object EXAMPLES:: diff --git a/src/sage/graphs/asteroidal_triples.pyx b/src/sage/graphs/asteroidal_triples.pyx index 19201431856..7c904f777f3 100644 --- a/src/sage/graphs/asteroidal_triples.pyx +++ b/src/sage/graphs/asteroidal_triples.pyx @@ -70,7 +70,7 @@ from sage.graphs.base.static_sparse_graph cimport short_digraph, init_short_digr def is_asteroidal_triple_free(G, certificate=False): """ - Test if the input graph is asteroidal triple-free + Test if the input graph is asteroidal triple-free. An independent set of three vertices such that each pair is joined by a path that avoids the neighborhood of the third one is called an *asteroidal @@ -78,7 +78,7 @@ def is_asteroidal_triple_free(G, certificate=False): asteroidal triples. See the :mod:`module's documentation ` for more details. - This method returns ``True`` is the graph is AT-free and ``False`` otherwise. + This method returns ``True`` if the graph is AT-free and ``False`` otherwise. INPUT: @@ -147,8 +147,7 @@ def is_asteroidal_triple_free(G, certificate=False): # module sage.graphs.base.static_sparse_graph cdef list int_to_vertex = list(G) cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef bitset_t seen bitset_init(seen, n) diff --git a/src/sage/graphs/base/boost_graph.pyx b/src/sage/graphs/base/boost_graph.pyx index b38d8277037..31f3c6d0267 100644 --- a/src/sage/graphs/base/boost_graph.pyx +++ b/src/sage/graphs/base/boost_graph.pyx @@ -66,7 +66,7 @@ cdef boost_graph_from_sage_graph(BoostGenGraph *g, g_sage, vertex_to_int, revers - ``g_sage`` -- a Sage graph - - ``vertex_to_int`` -- a dictionary; it is a mapping from the vertex set of + - ``vertex_to_int`` -- dictionary; it is a mapping from the vertex set of ``g_sage`` to `(0, \ldots, n-1)` - ``reverse`` -- boolean (default: ``False``); when set to ``True``, the @@ -109,7 +109,7 @@ cdef boost_weighted_graph_from_sage_graph(BoostWeightedGraph *g, - ``g_sage`` -- a Sage graph - - ``vertex_to_int`` -- a dictionary; it is a mapping from the vertex set of + - ``vertex_to_int`` -- dictionary; it is a mapping from the vertex set of ``g_sage`` to `(0, \ldots, n-1)` - ``weight_function`` -- function (default: ``None``); a function which @@ -317,7 +317,7 @@ cpdef clustering_coeff(g, vertices=None): With labels:: sage: g.relabel(list("abcdefghiklm")) - sage: clustering_coeff(g, vertices="abde") + sage: clustering_coeff(g, vertices='abde') (0.5, {'a': 0.5, 'b': 0.5, 'd': 0.5, 'e': 0.5}) """ from sage.graphs.graph import Graph @@ -505,7 +505,7 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee'): Use Boost heuristics to approximate the bandwidth of the input graph. The bandwidth `bw(M)` of a matrix `M` is the smallest integer `k` such that - all non-zero entries of `M` are at distance `k` from the diagonal. The + all nonzero entries of `M` are at distance `k` from the diagonal. The bandwidth `bw(g)` of an undirected graph `g` is the minimum bandwidth of the adjacency matrix of `g`, over all possible relabellings of its vertices (for more information, see the @@ -578,7 +578,6 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee'): (0, []) sage: bandwidth_heuristics(graphs.RandomGNM(10,0)) # needs networkx (0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) - """ from sage.graphs.graph import Graph @@ -1049,8 +1048,8 @@ cdef get_predecessors(BoostWeightedGraph g, result, int_to_v, directed, weight_t - ``result`` -- the matrix of shortest distances - - ``int_to_v`` -- a list; it is a mapping from `(0, \ldots, n-1)` - to the vertex set of the original sage graph. + - ``int_to_v`` -- list; it is a mapping from `(0, \ldots, n-1)` + to the vertex set of the original sage graph - ``directed`` -- boolean; whether the input graph is directed @@ -1426,9 +1425,7 @@ cpdef johnson_closeness_centrality(g, weight_function=None): ``g`` are used, if ``g.weighted()==True``, otherwise all edges have weight 1. - OUTPUT: - - A dictionary associating each vertex ``v`` to its closeness centrality. + OUTPUT: a dictionary associating each vertex ``v`` to its closeness centrality EXAMPLES: @@ -1648,7 +1645,7 @@ cpdef eccentricity_DHV(g, vertex_list=None, weight_function=None, check_weight=T INPUT: - - ``g`` -- the input Sage graph. + - ``g`` -- the input Sage graph - ``vertex_list`` -- list (default: ``None``); a list of `n` vertices specifying a mapping from `(0, \ldots, n-1)` to vertex labels in `g`. When @@ -1838,7 +1835,7 @@ cpdef radius_DHV(g, weight_function=None, check_weight=True): weight 1. - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check - that the ``weight_function`` outputs a number for each edge. + that the ``weight_function`` outputs a number for each edge EXAMPLES:: @@ -1869,7 +1866,6 @@ cpdef radius_DHV(g, weight_function=None, check_weight=True): Traceback (most recent call last): ... TypeError: this method works for undirected graphs only - """ if g.is_directed(): raise TypeError("this method works for undirected graphs only") @@ -2160,11 +2156,11 @@ cdef tuple diameter_lower_bound_2Dsweep(BoostVecWeightedDiGraphU g_boost, INPUT: - - ``g_boost`` -- a boost weighted digraph. + - ``g_boost`` -- a boost weighted digraph - - ``rev_g_boost`` -- a copy of ``g_boost`` with edges reversed. + - ``rev_g_boost`` -- a copy of ``g_boost`` with edges reversed - - ``source`` -- starting node for forward and backward distance computation. + - ``source`` -- starting node for forward and backward distance computation - ``algorithm`` -- string; algorithm for computing single source shortest distances. If ``g_boost`` contains negative edge weights then it will be @@ -2322,11 +2318,11 @@ cdef double diameter_DiFUB(BoostVecWeightedDiGraphU g_boost, INPUT: - - ``g_boost`` -- a boost weighted digraph. + - ``g_boost`` -- a boost weighted digraph - - ``rev_g_boost`` -- a copy of ``g_boost`` with edges reversed. + - ``rev_g_boost`` -- a copy of ``g_boost`` with edges reversed - - ``source`` -- starting node for forward and backward distance computation. + - ``source`` -- starting node for forward and backward distance computation - ``algorithm`` -- string; algorithm for computing single source shortest distances. If ``g_boost`` contains negative edge weights then it will be @@ -2500,16 +2496,16 @@ cpdef diameter(G, algorithm=None, source=None, INPUT: - - ``G`` -- the input sage digraph. + - ``G`` -- the input sage digraph - ``algorithm`` -- string (default: ``None``); specifies the algorithm to use among: - - ``'2Dsweep'`` -- Computes lower bound on the diameter of a weighted + - ``'2Dsweep'`` -- computes lower bound on the diameter of a weighted directed graph using the weighted version of the algorithm proposed in [Broder2000]_. See the code's documentation for more details. - - ``'DiFUB'`` -- Computes the diameter of a weighted directed graph + - ``'DiFUB'`` -- computes the diameter of a weighted directed graph using the weighted version of the algorithm proposed in [CGLM2012]_. See the code's documentation for more details. @@ -2523,7 +2519,7 @@ cpdef diameter(G, algorithm=None, source=None, weight 1. - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check - that the ``weight_function`` outputs a number for each edge. + that the ``weight_function`` outputs a number for each edge EXAMPLES:: @@ -2900,7 +2896,7 @@ cpdef wiener_index(g, algorithm=None, weight_function=None, check_weight=True): weight 1. - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check - that the ``weight_function`` outputs a number for each edge. + that the ``weight_function`` outputs a number for each edge EXAMPLES: @@ -2934,12 +2930,12 @@ cpdef wiener_index(g, algorithm=None, weight_function=None, check_weight=True): TESTS: - Using ``"Dijkstra"`` on a graph with negative weights:: + Using ``'Dijkstra'`` on a graph with negative weights:: sage: g = Graph([(0, 1, -1), (1, 2, 1)]) sage: def weight_of(e): ....: return e[2] - sage: wiener_index(g, algorithm="Dijkstra", weight_function=weight_of) + sage: wiener_index(g, algorithm='Dijkstra', weight_function=weight_of) Traceback (most recent call last): ... RuntimeError: Dijkstra algorithm does not work with negative weights, use Bellman-Ford instead @@ -2949,7 +2945,7 @@ cpdef wiener_index(g, algorithm=None, weight_function=None, check_weight=True): sage: g = DiGraph([(0, 1, -1), (1, 2, -1), (2, 0, -1)]) sage: def weight_of(e): ....: return e[2] - sage: wiener_index(g, algorithm="Bellman-Ford", weight_function=weight_of) + sage: wiener_index(g, algorithm='Bellman-Ford', weight_function=weight_of) Traceback (most recent call last): ... ValueError: the graph contains a negative cycle diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 1f8e5a59c73..1aa7b32d691 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -69,20 +69,18 @@ cdef class CGraph: cpdef bint has_vertex(self, int n) except -1: """ - Determine whether the vertex ``n`` is in ``self``. + Determine whether the vertex `n` is in ``self``. This method is different from :meth:`check_vertex`. The current method - returns a boolean to signify whether or not ``n`` is a vertex of this + returns a boolean to signify whether or not `n` is a vertex of this graph. On the other hand, :meth:`check_vertex` raises an error if - ``n`` is not a vertex of this graph. + `n` is not a vertex of this graph. INPUT: - - ``n`` -- a nonnegative integer representing a vertex + - ``n`` -- nonnegative integer representing a vertex - OUTPUT: - - - ``True`` if ``n`` is a vertex of this graph; ``False`` otherwise. + OUTPUT: ``True`` if `n` is a vertex of this graph; ``False`` otherwise .. SEEALSO:: @@ -128,20 +126,18 @@ cdef class CGraph: cpdef check_vertex(self, int n): """ - Check that ``n`` is a vertex of ``self``. + Check that `n` is a vertex of ``self``. This method is different from :meth:`has_vertex`. The current method - raises an error if ``n`` is not a vertex of this graph. On the other + raises an error if `n` is not a vertex of this graph. On the other hand, :meth:`has_vertex` returns a boolean to signify whether or not - ``n`` is a vertex of this graph. + `n` is a vertex of this graph. INPUT: - - ``n`` -- a nonnegative integer representing a vertex - - OUTPUT: + - ``n`` -- nonnegative integer representing a vertex - - Raise an error if ``n`` is not a vertex of this graph + OUTPUT: raise an error if `n` is not a vertex of this graph .. SEEALSO:: @@ -189,7 +185,7 @@ cdef class CGraph: cdef int add_vertex_unsafe(self, int k) except -1: """ - Add the vertex ``k`` to the graph. + Add the vertex `k` to the graph. INPUT: @@ -204,7 +200,7 @@ cdef class CGraph: allocation is already full or the vertex is out of range - nonnegative integer -- this vertex is now guaranteed to be in the - graph. + graph .. WARNING:: @@ -223,7 +219,7 @@ cdef class CGraph: def add_vertex(self, int k=-1): """ - Adds vertex ``k`` to the graph. + Add vertex ``k`` to the graph. INPUT: @@ -235,15 +231,15 @@ cdef class CGraph: OUTPUT: - ``-1`` -- indicates that no vertex was added because the current - allocation is already full or the vertex is out of range. + allocation is already full or the vertex is out of range - nonnegative integer -- this vertex is now guaranteed to be in the - graph. + graph .. SEEALSO:: - ``add_vertex_unsafe`` -- add a vertex to a graph. This method is - potentially unsafe. You should instead use :meth:`add_vertex`. + potentially unsafe. You should instead use :meth:`add_vertex` - ``add_vertices`` -- add a bunch of vertices to a graph @@ -435,18 +431,18 @@ cdef class CGraph: cpdef del_vertex(self, int v): """ - Delete the vertex ``v``, along with all edges incident to it. + Delete the vertex `v`, along with all edges incident to it. - If ``v`` is not in ``self``, fails silently. + If `v` is not in ``self``, fails silently. INPUT: - - ``v`` -- a nonnegative integer representing a vertex + - ``v`` -- nonnegative integer representing a vertex .. SEEALSO:: - ``del_vertex_unsafe`` -- delete a vertex from a graph. This method - is potentially unsafe. Use :meth:`del_vertex` instead. + is potentially unsafe. Use :meth:`del_vertex` instead EXAMPLES: @@ -585,10 +581,6 @@ cdef class CGraph: """ Return a list of the vertices in ``self``. - OUTPUT: - - - A list of all vertices in this graph - EXAMPLES:: sage: from sage.graphs.base.sparse_graph import SparseGraph @@ -624,7 +616,7 @@ cdef class CGraph: OUTPUT: - - Raise a :class:`NotImplementedError`. This method is not implemented + - Raise a :exc:`NotImplementedError`. This method is not implemented in this base class. A child class should provide a suitable implementation. @@ -731,7 +723,7 @@ cdef class CGraph: INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self + - ``u``, ``v`` -- nonnegative integers; must be in self EXAMPLES: @@ -829,9 +821,9 @@ cdef class CGraph: INPUT: - - ``u`` -- integer; the tail of an arc. + - ``u`` -- integer; the tail of an arc - - ``v`` -- integer; the head of an arc. + - ``v`` -- integer; the head of an arc EXAMPLES: @@ -897,13 +889,13 @@ cdef class CGraph: INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self + - ``u``, ``v`` -- nonnegative integers; must be in self OUTPUT: one of - - positive integer -- indicates that there is a label on ``(u, v)``. + - positive integer -- indicates that there is a label on ``(u, v)`` - - ``0`` -- either the arc ``(u, v)`` is unlabeled, or there is no arc at all. + - ``0`` -- either the arc ``(u, v)`` is unlabeled, or there is no arc at all EXAMPLES:: @@ -927,7 +919,6 @@ cdef class CGraph: sage: G.add_arc_label(1,2,2) sage: G.arc_label(1,2) 2 - """ self.check_vertex(u) self.check_vertex(v) @@ -935,7 +926,7 @@ cdef class CGraph: cpdef list all_arcs(self, int u, int v): """ - Gives the labels of all arcs ``(u, v)``. An unlabeled arc is interpreted as + Give the labels of all arcs ``(u, v)``. An unlabeled arc is interpreted as having label 0. EXAMPLES:: @@ -951,7 +942,6 @@ cdef class CGraph: sage: G.add_arc_label(1,2,4) sage: G.all_arcs(1,2) [4, 3, 3, 2, 2, 2, 1] - """ cdef int size, num_arcs, i cdef int *arc_labels @@ -979,9 +969,9 @@ cdef class CGraph: INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self + - ``u``, ``v`` -- nonnegative integers; must be in self - - ``l`` -- a positive integer label, or zero for no label + - ``l`` -- positive integer label, or zero for no label EXAMPLES:: @@ -998,7 +988,6 @@ cdef class CGraph: sage: G.del_arc_label(0,1,0) sage: G.all_arcs(0,1) [3, 2, 1] - """ self.check_vertex(u) self.check_vertex(v) @@ -1012,9 +1001,9 @@ cdef class CGraph: INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self + - ``u``, ``v`` -- nonnegative integers; must be in self - - ``l`` -- a positive integer label, or zero for no label + - ``l`` -- positive integer label, or zero for no label EXAMPLES:: @@ -1030,7 +1019,6 @@ cdef class CGraph: True sage: G.has_arc_label(0,1,3) False - """ self.check_vertex(u) self.check_vertex(v) @@ -1054,7 +1042,7 @@ cdef class CGraph: INPUT: - - ``u`` -- non-negative integer; must be in self + - ``u`` -- nonnegative integer; must be in self - ``neighbors`` -- pointer to an (allocated) integer array @@ -1066,7 +1054,6 @@ cdef class CGraph: - ``-1`` -- indicates that the array has been filled with neighbors, but there were more - """ cdef int num_nbrs = 0 cdef int l @@ -1092,7 +1079,7 @@ cdef class CGraph: INPUT: - - ``v`` -- non-negative integer; must be in self + - ``v`` -- nonnegative integer; must be in self - ``neighbors`` -- pointer to an (allocated) integer array @@ -1104,7 +1091,6 @@ cdef class CGraph: - ``-1`` -- indicates that the array has been filled with neighbors, but there were more - """ cdef int num_nbrs = 0 cdef int l @@ -1155,10 +1141,9 @@ cdef class CGraph: .. SEEALSO:: - - :meth:`adjacency_sequence_in` -- Similar method for + - :meth:`adjacency_sequence_in` -- similar method for ``(vertices[i],v)`` instead of ``(v,vertices[i])`` (the difference only matters for digraphs) - """ cdef int i for i in range(n): @@ -1195,7 +1180,7 @@ cdef class CGraph: .. SEEALSO:: - - :meth:`adjacency_sequence_out` -- Similar method for ``(v, + - :meth:`adjacency_sequence_out` -- similar method for ``(v, vertices[i])`` instead of ``(vertices[i], v)`` (the difference only matters for digraphs) """ @@ -1267,7 +1252,7 @@ cdef class CGraph: OUTPUT: - - Raise :class:`NotImplementedError`. This method is not implemented at + - Raise :exc:`NotImplementedError`. This method is not implemented at the :class:`CGraph` level. A child class should provide a suitable implementation. @@ -1383,7 +1368,7 @@ cdef class CGraphBackend(GenericGraphBackend): def c_graph(self): r""" - Return the ``._cg`` and ``._cg_rev`` attributes + Return the ``._cg`` and ``._cg_rev`` attributes. .. NOTE:: @@ -1536,9 +1521,7 @@ cdef class CGraphBackend(GenericGraphBackend): """ Return the number of vertices in ``self``. - OUTPUT: - - - The order of this graph. + OUTPUT: the order of this graph .. SEEALSO:: @@ -1678,9 +1661,7 @@ cdef class CGraphBackend(GenericGraphBackend): - ``v`` -- any object - OUTPUT: - - - ``True`` if ``v`` is a vertex of this graph; ``False`` otherwise + OUTPUT: ``True`` if ``v`` is a vertex of this graph; ``False`` otherwise EXAMPLES:: @@ -1701,7 +1682,7 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - ``name`` -- the vertex to be added (must be hashable). If ``None``, - a new name is created. + a new name is created OUTPUT: @@ -1848,9 +1829,7 @@ cdef class CGraphBackend(GenericGraphBackend): - ``vertices`` -- iterator of vertex labels - OUTPUT: - - - Same as for :meth:`del_vertex`. + OUTPUT: same as for :meth:`del_vertex` .. SEEALSO:: @@ -1998,9 +1977,7 @@ cdef class CGraphBackend(GenericGraphBackend): - ``directed`` -- boolean; whether to take into account the orientation of this graph in counting the degree of ``v`` - OUTPUT: - - - The degree of vertex ``v`` + OUTPUT: the degree of vertex ``v`` EXAMPLES:: @@ -2131,11 +2108,11 @@ cdef class CGraphBackend(GenericGraphBackend): def out_degree(self, v): r""" - Return the out-degree of ``v`` + Return the out-degree of ``v``. INPUT: - - ``v`` -- a vertex of the graph. + - ``v`` -- a vertex of the graph EXAMPLES:: @@ -2158,7 +2135,7 @@ cdef class CGraphBackend(GenericGraphBackend): def in_degree(self, v): r""" - Return the in-degree of ``v`` + Return the in-degree of ``v``. INPUT: @@ -2186,9 +2163,7 @@ cdef class CGraphBackend(GenericGraphBackend): - ``v`` -- a vertex of this graph - OUTPUT: - - - An iterator over the neighbors the vertex ``v`` + OUTPUT: an iterator over the neighbors the vertex ``v`` .. SEEALSO:: @@ -2238,9 +2213,7 @@ cdef class CGraphBackend(GenericGraphBackend): - ``v`` -- a vertex of this graph - OUTPUT: - - - An iterator over the in-neighbors of the vertex ``v`` + OUTPUT: an iterator over the in-neighbors of the vertex ``v`` .. SEEALSO:: @@ -2281,9 +2254,7 @@ cdef class CGraphBackend(GenericGraphBackend): - ``v`` -- a vertex of this graph - OUTPUT: - - - An iterator over the out-neighbors of the vertex ``v`` + OUTPUT: an iterator over the out-neighbors of the vertex ``v`` .. SEEALSO:: @@ -2344,7 +2315,6 @@ cdef class CGraphBackend(GenericGraphBackend): (2, 3, None), (4, 5, None), (5, 6, None)] - """ cdef object u, v, l, e for e in edges: @@ -2359,15 +2329,15 @@ cdef class CGraphBackend(GenericGraphBackend): cpdef add_edge(self, object u, object v, object l, bint directed): """ - Add the edge ``(u,v)`` to self. + Add the edge ``(u,v)`` to ``self``. INPUT: - - ``u``, ``v`` -- the vertices of the edge + - ``u``, ``v`` -- the vertices of the edge - - ``l`` -- the edge label + - ``l`` -- the edge label - - ``directed`` -- if False, also add ``(v,u)`` + - ``directed`` -- if ``False``, also add ``(v,u)`` .. NOTE:: @@ -2478,7 +2448,6 @@ cdef class CGraphBackend(GenericGraphBackend): sage: D.del_edges([(0,1), (2,3), (4,5), (5,6)], False) sage: list(D.iterator_edges(range(9), True)) [] - """ cdef object u, v, l, e for e in edges: @@ -2609,7 +2578,7 @@ cdef class CGraphBackend(GenericGraphBackend): cdef list _all_edge_labels(self, int u, int v, uint32_t* edge=NULL): """ - Gives the labels of all arcs from ``u`` to ``v``. + Give the labels of all arcs from ``u`` to ``v``. ``u`` and ``v`` are the integers corresponding to vertices. @@ -2634,7 +2603,7 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean, whether to return labels as well @@ -2671,7 +2640,7 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean, whether to return labels as well @@ -2699,9 +2668,9 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - - ``labels`` -- boolean, whether to return labels as well + - ``labels`` -- boolean, whether to return labels as well EXAMPLES:: @@ -2722,7 +2691,7 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean, whether to return labels as well @@ -2745,7 +2714,7 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean, whether to return labels as well @@ -2960,9 +2929,9 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - ``other`` -- a (mutable) subclass of :class:`CGraphBackend` - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - .. NOTE: + .. NOTE:: ``other`` is assumed to be the empty graph. @@ -3164,10 +3133,10 @@ cdef class CGraphBackend(GenericGraphBackend): INPUT: - ``other`` -- a (mutable) subclass of :class:`CGraphBackend` - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``modus`` -- integer representing the modus: - ``0`` -- initialize ``other`` to be the subgraph induced by the vertices; - see :meth:`subgraph_given_vertices`` + see :meth:`subgraph_given_vertices` - ``1`` -- test whether subgraph of ``self`` induced by the vertices is a subgraph of ``other`` - ``2`` -- as ``1`` but ignore the labels """ @@ -3367,7 +3336,6 @@ cdef class CGraphBackend(GenericGraphBackend): [] sage: G._backend.shortest_path_special(1, 4, exclude_vertices=[2], exclude_edges=[(2, 3)]) [1, 5, 6, 7, 4] - """ cdef bint exclude_v = exclude_vertices cdef bint exclude_e = exclude_edges @@ -3544,7 +3512,6 @@ cdef class CGraphBackend(GenericGraphBackend): [0, 1] sage: G.shortest_path_length(0, 1) 1 - """ if x == y: if distance_flag: @@ -3702,7 +3669,7 @@ cdef class CGraphBackend(GenericGraphBackend): instead of the path. - ``reduced_weight`` -- dictionary (default: ``None``); a dictionary - that takes as input an edge ``(u, v)`` and outputs its reduced weight. + that takes as input an edge ``(u, v)`` and outputs its reduced weight OUTPUT: @@ -3723,7 +3690,6 @@ cdef class CGraphBackend(GenericGraphBackend): [1, 2, 3, 4] sage: G._backend.bidirectional_dijkstra_special(1, 4, weight_function=lambda e:e[2], include_vertices=[1, 5, 6, 4]) [1, 5, 6, 4] - """ cdef bint exclude_v = exclude_vertices cdef bint exclude_e = exclude_edges @@ -4705,7 +4671,7 @@ cdef class Search_iterator: search. The class does not build all at once in memory the whole list of visited vertices. The class maintains the following variables: - - ``graph`` -- a graph whose vertices are to be iterated over. + - ``graph`` -- a graph whose vertices are to be iterated over - ``direction`` -- integer; this determines the position at which vertices to be visited are removed from the list. For breadth-first search (BFS), @@ -4716,11 +4682,11 @@ cdef class Search_iterator: value ``direction=-1``. In this case, we use a stack to maintain the list of vertices to visit. - - ``stack`` -- a list of vertices to visit, used only when ``direction=-1`` + - ``stack`` -- list of vertices to visit, used only when ``direction=-1`` - ``queue`` -- a queue of vertices to visit, used only when ``direction=0`` - - ``seen`` -- a list of vertices that are already visited + - ``seen`` -- list of vertices that are already visited - ``test_out`` -- boolean; whether we want to consider the out-neighbors of the graph to be traversed. For undirected graphs, we consider both @@ -4764,7 +4730,7 @@ cdef class Search_iterator: - ``v`` -- a vertex in ``graph`` from which to start the traversal - - ``direction`` -- integer (default: ``0``); this determines the + - ``direction`` -- integer (default: `0`); this determines the position at which vertices to be visited are removed from the list. For breadth-first search (BFS), element removal follow a first-in first-out (FIFO) protocol, as signified by the value @@ -4822,7 +4788,6 @@ cdef class Search_iterator: sage: DiGraph([(1, 2)], immutable=True).connected_components(sort=True) [[1, 2]] - """ self.graph = graph self.direction = direction @@ -5025,7 +4990,7 @@ cdef inline bint _reorganize_edge(object v, object u, const int modus) noexcept: - ``2`` -- unsorted edges of an undirected graph - ``3`` -- sorted edges of an undirected graph - OUTPUT: Boolean according the modus: + OUTPUT: boolean according the modus: - ``modus == 0`` -- ``False`` - ``modus == 1`` -- ``True`` diff --git a/src/sage/graphs/base/dense_graph.pyx b/src/sage/graphs/base/dense_graph.pyx index abcd0809af1..45d09ced3d3 100644 --- a/src/sage/graphs/base/dense_graph.pyx +++ b/src/sage/graphs/base/dense_graph.pyx @@ -144,8 +144,8 @@ cdef class DenseGraph(CGraph): INPUT: - - ``nverts`` -- non-negative integer; the number of vertices - - ``extra_vertices`` -- non-negative integer (default: 10); how many extra + - ``nverts`` -- nonnegative integer; the number of vertices + - ``extra_vertices`` -- nonnegative integer (default: 10); how many extra vertices to allocate - ``verts`` -- list (default: ``None``); optional list of vertices to add - ``arcs`` -- list (default: ``None``); optional list of arcs to add @@ -155,7 +155,6 @@ cdef class DenseGraph(CGraph): ``extra_vertices`` can be freely added without reallocation. See top level documentation for more details. The input ``verts`` and ``arcs`` are mainly for use in pickling. - """ def __cinit__(self, int nverts, int extra_vertices=10, verts=None, arcs=None, directed=True): """ @@ -300,8 +299,7 @@ cdef class DenseGraph(CGraph): INPUT: - - ``u``, ``v`` -- non-negative integers - + - ``u``, ``v`` -- nonnegative integers """ if unlikely(l): raise ValueError("cannot add a labeled arc to an unlabeled graph") @@ -316,14 +314,14 @@ cdef class DenseGraph(CGraph): INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self + - ``u``, ``v`` -- nonnegative integers, must be in self - - ``l`` -- a positive integer label, or zero for no label, or ``-1`` for any label + - ``l`` -- positive integer label, or zero for no label, or ``-1`` for any label OUTPUT: - 0 -- False - 1 -- True + - 0 -- False + - 1 -- True """ if unlikely(l > 0): raise ValueError("cannot locate labeled arc in unlabeled graph") @@ -349,8 +347,7 @@ cdef class DenseGraph(CGraph): INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self - + - ``u``, ``v`` -- nonnegative integers, must be in self """ self._del_arc_unsafe(u, v) if u != v and not self._directed: @@ -366,7 +363,7 @@ cdef class DenseGraph(CGraph): cdef int all_arcs_unsafe(self, int u, int v, int* labels, int size) except -1: """ - Gives the labels of all arcs (u, v). + Give the labels of all arcs (u, v). INPUT: @@ -375,12 +372,9 @@ cdef class DenseGraph(CGraph): - ``labels`` -- must be a pointer to an (allocated) integer array - ``size`` -- the length of the array - OUTPUT: - - - integer -- the number of arcs ``(u, v)`` - ``-1`` -- indicates that the array has been filled with labels, but - there were more - + OUTPUT: integer; the number of arcs ``(u, v)``. + ``-1`` -- indicates that the array has been filled with labels, but + there were more. """ if self.has_arc_unsafe(u, v): if size > 0: @@ -392,7 +386,7 @@ cdef class DenseGraph(CGraph): def complement(self): r""" - Replace the graph with its complement + Replace the graph with its complement. .. NOTE:: @@ -571,7 +565,6 @@ cdef class DenseGraphBackend(CGraphBackend): Traceback (most recent call last): ... TypeError: an integer is required - """ def __init__(self, n, directed=True): @@ -584,7 +577,6 @@ cdef class DenseGraphBackend(CGraphBackend): sage: D.add_edge(0, 1, None, False) sage: list(D.iterator_edges(range(9), True)) [(0, 1, None)] - """ self._cg = DenseGraph(n, directed=directed) self._directed = directed @@ -622,7 +614,7 @@ cdef class DenseGraphBackend(CGraphBackend): INPUT: - ``edges`` -- an iterable of edges to be added; each edge can either be - of the form ``(u, v)`` or ``(u, v, l)`` + of the form ``(u, v)`` or ``(u, v, l)`` - ``directed`` -- if ``False``, adds ``(v, u)`` as well as ``(u, v)`` @@ -637,7 +629,6 @@ cdef class DenseGraphBackend(CGraphBackend): (2, 3, None), (4, 5, None), (5, 6, None)] - """ for e in edges: u, v = e[:2] @@ -678,7 +669,6 @@ cdef class DenseGraphBackend(CGraphBackend): Traceback (most recent call last): ... LookupError: (2, 4) is not an edge of the graph - """ if not self.has_edge(u, v, None): raise LookupError("({0}, {1}) is not an edge of the graph".format(repr(u), repr(v))) @@ -704,7 +694,6 @@ cdef class DenseGraphBackend(CGraphBackend): sage: D.add_edges([(0, 1), (2, 3), (4, 5), (5, 6)], False) sage: D.has_edge(0, 1, None) True - """ cdef int u_int = self.get_vertex_checked(u) cdef int v_int = self.get_vertex_checked(v) @@ -737,7 +726,6 @@ cdef class DenseGraphBackend(CGraphBackend): NotImplementedError: dense graphs do not support multiple edges sage: G.multiple_edges(None) False - """ if new is None: return False diff --git a/src/sage/graphs/base/graph_backends.pyx b/src/sage/graphs/base/graph_backends.pyx index a779c3f4f22..4363a812995 100644 --- a/src/sage/graphs/base/graph_backends.pyx +++ b/src/sage/graphs/base/graph_backends.pyx @@ -5,7 +5,7 @@ This module implements :class:`GenericGraphBackend` (the base class for backends). Any graph backend must redefine the following methods (for which -:class:`GenericGraphBackend` raises a :class:`NotImplementedError`) +:class:`GenericGraphBackend` raises a :exc:`NotImplementedError`) .. csv-table:: :class: contentstable @@ -69,7 +69,6 @@ cdef class GenericGraphBackend(SageObject): TESTS:: sage: import sage.graphs.base.graph_backends - """ _loops = False _multiple_edges = False @@ -128,9 +127,7 @@ cdef class GenericGraphBackend(SageObject): - ``name`` -- vertex label - OUTPUT: - - If ``name=None``, the new vertex name is returned, ``None`` otherwise. + OUTPUT: if ``name=None``, the new vertex name is returned, ``None`` otherwise TESTS:: @@ -176,9 +173,7 @@ cdef class GenericGraphBackend(SageObject): - ``v`` -- a vertex label - ``directed`` -- boolean - OUTPUT: - - degree of `v` + OUTPUT: degree of `v` TESTS:: @@ -192,7 +187,7 @@ cdef class GenericGraphBackend(SageObject): def in_degree(self, v): r""" - Return the in-degree of `v` + Return the in-degree of `v`. INPUT: @@ -210,7 +205,7 @@ cdef class GenericGraphBackend(SageObject): def out_degree(self, v): r""" - Return the out-degree of `v` + Return the out-degree of `v`. INPUT: @@ -313,9 +308,7 @@ cdef class GenericGraphBackend(SageObject): - ``u``, ``v`` -- vertex labels - ``l`` -- label - OUTPUT: - - boolean + OUTPUT: boolean TESTS:: @@ -335,8 +328,7 @@ cdef class GenericGraphBackend(SageObject): - ``v`` -- vertex label - OUTPUT: - boolean + OUTPUT: boolean TESTS:: @@ -359,7 +351,7 @@ cdef class GenericGraphBackend(SageObject): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean OUTPUT: @@ -386,12 +378,11 @@ cdef class GenericGraphBackend(SageObject): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean - OUTPUT: - a generator which yields edges, with or without labels - depending on the labels parameter. + OUTPUT: a generator which yields edges, with or without labels + depending on the labels parameter TESTS:: @@ -412,7 +403,7 @@ cdef class GenericGraphBackend(SageObject): INPUT: - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``labels`` -- boolean OUTPUT: @@ -442,9 +433,7 @@ cdef class GenericGraphBackend(SageObject): - ``v`` -- vertex label - OUTPUT: - - a generator which yields vertex labels + OUTPUT: a generator which yields vertex labels TESTS:: @@ -467,9 +456,7 @@ cdef class GenericGraphBackend(SageObject): - ``v`` -- vertex label - OUTPUT: - - a generator which yields vertex labels + OUTPUT: a generator which yields vertex labels TESTS:: @@ -492,9 +479,7 @@ cdef class GenericGraphBackend(SageObject): - ``v`` -- vertex label - OUTPUT: - - a generator which yields vertex labels + OUTPUT: a generator which yields vertex labels TESTS:: @@ -514,9 +499,7 @@ cdef class GenericGraphBackend(SageObject): - ``verts`` -- vertex labels - OUTPUT: - - a generator which yields vertices + OUTPUT: a generator which yields vertices TESTS:: @@ -530,7 +513,7 @@ cdef class GenericGraphBackend(SageObject): def loops(self, new=None): """ - Get/set whether or not self allows loops. + Get/set whether or not ``self`` allows loops. INPUT: @@ -554,7 +537,7 @@ cdef class GenericGraphBackend(SageObject): def multiple_edges(self, new=None): """ - Get/set whether or not self allows multiple edges. + Get/set whether or not ``self`` allows multiple edges. INPUT: @@ -578,7 +561,7 @@ cdef class GenericGraphBackend(SageObject): def name(self, new=None): """ - Get/set name of self. + Get/set name of ``self``. INPUT: @@ -602,7 +585,7 @@ cdef class GenericGraphBackend(SageObject): def num_edges(self, directed): """ - Return the number of edges in ``self`` + Return the number of edges in ``self``. INPUT: @@ -624,7 +607,7 @@ cdef class GenericGraphBackend(SageObject): def num_verts(self): """ - Return the number of vertices in ``self`` + Return the number of vertices in ``self``. TESTS:: @@ -757,7 +740,7 @@ cdef class GenericGraphBackend(SageObject): def unpickle_graph_backend(directed, vertices, edges, kwds): r""" - Return a backend from its pickled data + Return a backend from its pickled data. This methods is defined because Python's pickling mechanism can only build objects from a pair ``(f,args)`` by running ``f(*args)``. In particular, diff --git a/src/sage/graphs/base/meson.build b/src/sage/graphs/base/meson.build new file mode 100644 index 00000000000..92e205ceb81 --- /dev/null +++ b/src/sage/graphs/base/meson.build @@ -0,0 +1,51 @@ +py.install_sources( + 'all.py', + 'boost_graph.pxd', + 'c_graph.pxd', + 'dense_graph.pxd', + 'graph_backends.pxd', + 'overview.py', + 'sparse_graph.pxd', + 'static_dense_graph.pxd', + 'static_sparse_backend.pxd', + 'static_sparse_graph.pxd', + subdir: 'sage/graphs/base', +) + +extension_data = { + 'dense_graph' : files('dense_graph.pyx'), + 'graph_backends' : files('graph_backends.pyx'), + 'sparse_graph' : files('sparse_graph.pyx'), + 'static_dense_graph' : files('static_dense_graph.pyx'), + 'static_sparse_backend' : files('static_sparse_backend.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/graphs/base', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +extension_data_cpp = { + 'boost_graph': files('boost_graph.pyx'), + 'c_graph': files('c_graph.pyx'), + 'static_sparse_graph': files('static_sparse_graph.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/graphs/base', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/graphs/base/sparse_graph.pyx b/src/sage/graphs/base/sparse_graph.pyx index 3e736bc6461..a02541436ac 100644 --- a/src/sage/graphs/base/sparse_graph.pyx +++ b/src/sage/graphs/base/sparse_graph.pyx @@ -235,23 +235,22 @@ cdef class SparseGraph(CGraph): INPUT: - - ``nverts`` -- non-negative integer, the number of vertices. + - ``nverts`` -- nonnegative integer, the number of vertices - - ``expected_degree`` -- non-negative integer (default: 16), expected upper - bound on degree of vertices. + - ``expected_degree`` -- nonnegative integer (default: 16); expected upper + bound on degree of vertices - - ``extra_vertices`` -- non-negative integer (default: 0), how many extra - vertices to allocate. + - ``extra_vertices`` -- nonnegative integer (default: 0); how many extra + vertices to allocate - - ``verts`` -- optional list of vertices to add + - ``verts`` -- (optional) list of vertices to add - - ``arcs`` -- optional list of arcs to add + - ``arcs`` -- (optional) list of arcs to add The first ``nverts`` are created as vertices of the graph, and the next ``extra_vertices`` can be freely added without reallocation. See top level documentation for more details. The input ``verts`` and ``arcs`` are mainly for use in pickling. - """ def __cinit__(self, int nverts, int expected_degree=16, int extra_vertices=10, @@ -379,7 +378,7 @@ cdef class SparseGraph(CGraph): INPUT: - - ``total`` -- integer, the total size to make the array + - ``total`` -- integer; the total size to make the array Returns -1 and fails if reallocation would destroy any active vertices. @@ -414,7 +413,6 @@ cdef class SparseGraph(CGraph): sage: S.realloc(30) sage: S.current_allocation() 30 - """ if not total: raise RuntimeError('Sparse graphs must allocate space for vertices!') @@ -582,16 +580,16 @@ cdef class SparseGraph(CGraph): cdef int del_arc_unsafe(self, int u, int v) except -1: """ - Deletes *all* arcs from u to v. + Delete *all* arcs from u to v. INPUT: - - ``u``, ``v`` -- non-negative integers + - ``u``, ``v`` -- nonnegative integers OUTPUT: - 0 -- No error. - 1 -- No arc to delete. + - 0 -- no error + - 1 -- no arc to delete """ cdef int n_arcs = self._del_arc_unsafe(u, v, self.vertices) if u != v or self.is_directed(): @@ -722,11 +720,11 @@ cdef class SparseGraph(CGraph): cpdef int out_degree(self, int u) noexcept: """ - Returns the out-degree of ``v`` + Return the out-degree of ``v`` INPUT: - - ``u`` -- integer + - ``u`` -- integer EXAMPLES:: @@ -792,11 +790,11 @@ cdef class SparseGraph(CGraph): cpdef int in_degree(self, int v) noexcept: """ - Returns the in-degree of ``v`` + Return the in-degree of ``v`` INPUT: - - ``v`` -- integer + - ``v`` -- integer EXAMPLES:: @@ -864,12 +862,11 @@ cdef class SparseGraph(CGraph): INPUT: - - ``u``, ``v`` -- non-negative integers + - ``u``, ``v`` -- nonnegative integers - - ``l`` -- a positive integer label, or zero for no label - - OUTPUT: ``0`` -- No error. + - ``l`` -- positive integer label, or zero for no label + OUTPUT: ``0`` -- no error """ self._add_arc_label_unsafe(u, v, l, self.vertices) if u != v or self.is_directed(): @@ -891,9 +888,9 @@ cdef class SparseGraph(CGraph): INPUT: - - ``u``, ``v`` -- non-negative integers, must be in self + - ``u``, ``v`` -- nonnegative integers, must be in ``self`` - - ``l`` -- a positive integer label, or zero for no label + - ``l`` -- positive integer label, or zero for no label EXAMPLES:: @@ -930,10 +927,9 @@ cdef class SparseGraph(CGraph): OUTPUT: one of - - positive integer -- indicates that there is a label on ``(u, v)``. + - positive integer -- indicates that there is a label on ``(u, v)`` - ``0`` -- either the arc ``(u, v)`` is unlabeled, or there is no arc at all. - """ cdef int i = (u * self.hash_length) + (v & self.hash_mask) cdef int compared @@ -952,7 +948,7 @@ cdef class SparseGraph(CGraph): cdef int all_arcs_unsafe(self, int u, int v, int *arc_labels, int size) except -1: """ - Gives the labels of all arcs (u, v). + Give the labels of all arcs (u, v). INPUT: @@ -961,12 +957,9 @@ cdef class SparseGraph(CGraph): - ``arc_labels`` -- must be a pointer to an (allocated) integer array - ``size`` -- the length of the array - OUTPUT: - - - integer -- the number of arcs ``(u, v)`` - ``-1`` -- indicates that the array has been filled with labels, but - there were more - + OUTPUT: integer; the number of arcs ``(u, v)``. + ``-1`` -- indicates that the array has been filled with labels, but + there were more. """ cdef int i = (u * self.hash_length) + (v & self.hash_mask), j cdef int compared, num_arcs @@ -1035,8 +1028,9 @@ cdef class SparseGraph(CGraph): Delete an arc (u, v) with label l. OUTPUT: - 0 -- No error. - 1 -- No arc with label l. + + - 0 -- no error + - 1 -- no arc with label l """ cdef int i = (u * self.hash_length) + (v & self.hash_mask) cdef SparseGraphBTNode **old_parent = parent @@ -1090,13 +1084,13 @@ cdef class SparseGraph(CGraph): - ``u``, ``v`` -- integers from `0`, ..., `n-1`, where `n` is the number of vertices - - ``l`` -- a positive integer label, or zero for no label + - ``l`` -- positive integer label, or zero for no label OUTPUT: one of - - ``0`` -- No error + - ``0`` -- no error - - ``1`` -- No arc with label ``l`` + - ``1`` -- no arc with label ``l`` """ if self._del_arc_label_unsafe(u, v, l, self.vertices): return 1 # indicate an error @@ -1123,13 +1117,13 @@ cdef class SparseGraph(CGraph): - ``u``, ``v`` -- integers from `0`, ..., `n-1`, where `n` is the number of vertices - - ``l`` -- a positive integer label, or zero for no label, or ``-1`` for any label + - ``l`` -- positive integer label, or zero for no label, or ``-1`` for any label OUTPUT: one of - - ``0`` -- False + - ``0`` -- false - - ``1`` -- True + - ``1`` -- true """ cdef int i = (u * self.hash_length) + (v & self.hash_mask) cdef int compared @@ -1249,7 +1243,6 @@ cdef class SparseGraphBackend(CGraphBackend): Traceback (most recent call last): ... TypeError: an integer is required - """ def __init__(self, int n, directed=True): @@ -1262,7 +1255,6 @@ cdef class SparseGraphBackend(CGraphBackend): sage: D.add_edge(0,1,None,False) sage: list(D.iterator_edges(range(9), True)) [(0, 1, None)] - """ self._cg = SparseGraph(n, directed=directed) self._directed = directed @@ -1305,7 +1297,7 @@ cdef class SparseGraphBackend(CGraphBackend): INPUT: - - ``u``, ``v`` -- the vertices of the edge + - ``u``, ``v`` -- the vertices of the edge EXAMPLES:: @@ -1333,15 +1325,15 @@ cdef class SparseGraphBackend(CGraphBackend): def has_edge(self, object u, object v, object l): """ - Returns whether this graph has edge ``(u,v)`` with label ``l``. If ``l`` + Return whether this graph has edge ``(u,v)`` with label ``l``. If ``l`` is ``None``, return whether this graph has an edge ``(u,v)`` with any label. INPUT: - - ``u``, ``v`` -- the vertices of the edge + - ``u``, ``v`` -- the vertices of the edge - - ``l`` -- the edge label, or ``None`` + - ``l`` -- the edge label, or ``None`` EXAMPLES:: @@ -1349,7 +1341,6 @@ cdef class SparseGraphBackend(CGraphBackend): sage: D.add_edges([(0,1), (2,3), (4,5), (5,6)], False) sage: D.has_edge(0,1,None) True - """ cdef int u_int = self.get_vertex_checked(u) cdef int v_int = self.get_vertex_checked(v) @@ -1378,7 +1369,7 @@ cdef class SparseGraphBackend(CGraphBackend): INPUT: - - ``new`` -- boolean (to set) or ``None`` (to get) + - ``new`` -- boolean (to set) or ``None`` (to get) EXAMPLES:: @@ -1393,7 +1384,6 @@ cdef class SparseGraphBackend(CGraphBackend): sage: G.add_edge(0,1,0,True) sage: list(G.iterator_out_edges(range(9), True)) [(0, 1, 0)] - """ if new is None: return self._multiple_edges @@ -1405,11 +1395,11 @@ cdef class SparseGraphBackend(CGraphBackend): INPUT: - - ``u``, ``v`` -- the vertices of the edge + - ``u``, ``v`` -- the vertices of the edge - - ``l`` -- the edge label + - ``l`` -- the edge label - - ``directed`` -- if ``False``, also set ``(v,u)`` with label ``l`` + - ``directed`` -- if ``False``, also set ``(v,u)`` with label ``l`` EXAMPLES:: @@ -1424,7 +1414,6 @@ cdef class SparseGraphBackend(CGraphBackend): sage: G.set_edge_label(2,1,'b',True) sage: list(G.iterator_out_edges(range(9), True)) [(1, 2, 'a')] - """ if not self.has_edge(u, v, None): return diff --git a/src/sage/graphs/base/static_dense_graph.pyx b/src/sage/graphs/base/static_dense_graph.pyx index b23eab66a3b..6a07565ecca 100644 --- a/src/sage/graphs/base/static_dense_graph.pyx +++ b/src/sage/graphs/base/static_dense_graph.pyx @@ -64,7 +64,7 @@ cdef dict dense_graph_init(binary_matrix_t m, g, translation=None, force_undirec - ``g`` -- a graph or digraph - - ``translation`` -- (default: `None``); several options for this parameter + - ``translation`` -- (default: ``None``) several options for this parameter used to specify the mapping from vertices to integers: - ``True``, ``False``, ``None`` -- the `i`-th vertex in the binary matrix @@ -393,7 +393,7 @@ def _format_result(G, edges, edges_only, labels): - ``edges_only`` -- boolean; whether to return DiGraph or list of vertices - - ``labels`` -- boolean; whether to return labelled edges or not. This + - ``labels`` -- boolean; whether to return labeled edges or not. This parameter is used only when ``edges_only`` is ``True``. EXAMPLES: @@ -426,7 +426,7 @@ def _yield_results_for_digraph(G, edges, edges_only, labels, min_edges, max_edge - ``edges_only`` -- boolean; whether to return DiGraph or list of vertices - - ``labels`` -- boolean; whether to return labelled edges or not. This + - ``labels`` -- boolean; whether to return labeled edges or not. This parameter is used only when ``edges_only`` is ``True``. - ``min_edges`` -- integer; minimum number of edges of reported subgraphs @@ -490,7 +490,7 @@ def connected_full_subgraphs(G, edges_only=False, labels=False, - ``edges_only`` -- boolean (default: ``False``); whether to return (Di)Graph or list of vertices - - ``labels`` -- boolean (default: ``False``); whether to return labelled + - ``labels`` -- boolean (default: ``False``); whether to return labeled edges or not. This parameter is used only when ``edges_only`` is ``True``. - ``min_edges`` -- integer (default: ``None``); minimum number of edges of @@ -711,7 +711,7 @@ def connected_full_subgraphs(G, edges_only=False, labels=False, elif bitset_len(boundaries.rows[i]): # We prepare the boundary for the selection of the next vertex. - # This is equivalant to consider an empty neighborhood. + # This is equivalent to consider an empty neighborhood. bitset_copy(boundaries.rows[i + 1], boundaries.rows[i]) bitset_clear(boundaries.rows[i]) # to prevent doing twice this operation E.append([]) @@ -776,7 +776,7 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False, return (Di)Graph or list of edges. When ``vertices_only`` is ``True``, this parameter is ignored. - - ``labels`` -- boolean (default: ``False``); whether to return labelled + - ``labels`` -- boolean (default: ``False``); whether to return labeled edges or not. This parameter is used only when ``vertices_only`` is ``False`` and ``edges_only`` is ``True``. diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index ea65e2117d9..e51fc238ac5 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -60,13 +60,13 @@ cdef class StaticSparseCGraph(CGraph): def __cinit__(self, G, vertex_list=None): r""" - Cython constructor + Cython constructor. INPUT: - ``G`` -- a :class:`Graph` object - - ``vertex_list`` -- optional list of all vertices of ``G`` + - ``vertex_list`` -- (optional) list of all vertices of ``G`` The optional argument ``vertex_list`` is assumed to be a list of all vertices of the graph ``G`` in some order. @@ -143,7 +143,7 @@ cdef class StaticSparseCGraph(CGraph): def __dealloc__(self): r""" - Freeing the memory + Free the memory. TESTS:: @@ -162,7 +162,7 @@ cdef class StaticSparseCGraph(CGraph): INPUT: - - ``n`` -- an integer + - ``n`` -- integer TESTS:: @@ -213,7 +213,7 @@ cdef class StaticSparseCGraph(CGraph): cpdef list verts(self): r""" - Returns the list of vertices + Return the list of vertices. TESTS:: @@ -320,7 +320,7 @@ cdef class StaticSparseCGraph(CGraph): cpdef list out_neighbors(self, int u): r""" - List the out-neighbors of a vertex + List the out-neighbors of a vertex. INPUT: @@ -345,7 +345,7 @@ cdef class StaticSparseCGraph(CGraph): cpdef list in_neighbors(self, int u): r""" - Return the in-neighbors of a vertex + Return the in-neighbors of a vertex. INPUT: @@ -425,7 +425,7 @@ cdef class StaticSparseCGraph(CGraph): cdef class StaticSparseBackend(CGraphBackend): - def __init__(self, G, loops=False, multiedges=False): + def __init__(self, G, loops=False, multiedges=False, sort=True): """ A graph :mod:`backend ` for static sparse graphs. @@ -447,8 +447,8 @@ cdef class StaticSparseBackend(CGraphBackend): :: sage: # needs sage.combinat - sage: g = DiGraph(digraphs.DeBruijn(4, 3), data_structure="static_sparse") - sage: gi = DiGraph(g, data_structure="static_sparse") + sage: g = DiGraph(digraphs.DeBruijn(4, 3), data_structure='static_sparse') + sage: gi = DiGraph(g, data_structure='static_sparse') sage: gi.edges(sort=True)[0] ('000', '000', '0') sage: sorted(gi.edges_incident('111')) @@ -463,7 +463,7 @@ cdef class StaticSparseBackend(CGraphBackend): :: sage: g = graphs.PetersenGraph() - sage: gi = Graph(g, data_structure="static_sparse") + sage: gi = Graph(g, data_structure='static_sparse') sage: g == gi True sage: set(g.edges(sort=False)) == set(gi.edges(sort=False)) @@ -471,7 +471,7 @@ cdef class StaticSparseBackend(CGraphBackend): :: - sage: gi = Graph({ 0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, data_structure="static_sparse") + sage: gi = Graph({ 0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, data_structure='static_sparse') sage: (0, 4, 2) in gi.edges(sort=False) True sage: gi.has_edge(0, 4) @@ -480,7 +480,7 @@ cdef class StaticSparseBackend(CGraphBackend): :: sage: G = Graph({1:{2:28, 6:10}, 2:{3:16, 7:14}, 3:{4:12}, 4:{5:22, 7:18}, 5:{6:25, 7:24}}) - sage: GI = Graph({1:{2:28, 6:10}, 2:{3:16, 7:14}, 3:{4:12}, 4:{5:22, 7:18}, 5:{6:25, 7:24}}, data_structure="static_sparse") + sage: GI = Graph({1:{2:28, 6:10}, 2:{3:16, 7:14}, 3:{4:12}, 4:{5:22, 7:18}, 5:{6:25, 7:24}}, data_structure='static_sparse') sage: G == GI True @@ -489,13 +489,13 @@ cdef class StaticSparseBackend(CGraphBackend): sage: G = graphs.OddGraph(4) sage: d = G.diameter() sage: H = G.distance_graph(list(range(d + 1))) - sage: HI = Graph(H, data_structure="static_sparse") + sage: HI = Graph(H, data_structure='static_sparse') sage: HI.size() == len(HI.edges(sort=False)) True :: - sage: g = Graph({1: {1: [1, 2, 3]}}, data_structure="static_sparse") + sage: g = Graph({1: {1: [1, 2, 3]}}, data_structure='static_sparse') sage: g.size() 3 sage: g.order() @@ -511,10 +511,11 @@ cdef class StaticSparseBackend(CGraphBackend): True """ vertices = list(G) - try: - vertices.sort() - except TypeError: - pass + if sort: + try: + vertices.sort() + except TypeError: + pass cdef StaticSparseCGraph cg = StaticSparseCGraph(G, vertices) self._cg = cg @@ -539,7 +540,7 @@ cdef class StaticSparseBackend(CGraphBackend): def has_vertex(self, v): r""" - Test if the vertex belongs to the graph + Test if the vertex belongs to the graph. INPUT: @@ -700,7 +701,7 @@ cdef class StaticSparseBackend(CGraphBackend): cdef inline list _all_edge_labels(self, int u, int v, uint32_t* edge=NULL): """ - Gives the labels of all arcs from ``u`` to ``v``. + Give the labels of all arcs from ``u`` to ``v``. ``u`` and ``v`` are the integers corresponding to vertices. @@ -781,7 +782,7 @@ cdef class StaticSparseBackend(CGraphBackend): INPUT: - - ``vertices`` -- a list of vertices + - ``vertices`` -- list of vertices - ``labels`` -- whether to return labels too @@ -829,7 +830,7 @@ cdef class StaticSparseBackend(CGraphBackend): INPUT: - - ``vertices`` -- a list of vertices + - ``vertices`` -- list of vertices - ``labels`` -- whether to return labels too @@ -841,7 +842,6 @@ cdef class StaticSparseBackend(CGraphBackend): [(0, 1), (0, 4), (0, 5)] sage: list(g.iterator_out_edges([0], True)) [(0, 1, None), (0, 4, None), (0, 5, None)] - """ try: vertices = [self._vertex_to_int[x] for x in vertices] @@ -862,11 +862,11 @@ cdef class StaticSparseBackend(CGraphBackend): def iterator_verts(self, vertices): r""" - Iterate over the vertices + Iterate over the vertices. INPUT: - - ``vertices`` -- a list of objects; the method will only return the + - ``vertices`` -- list of objects; the method will only return the elements of the graph which are contained in ``vertices``. It's not very efficient. If ``vertices`` is equal to ``None``, all the vertices are returned. @@ -893,7 +893,7 @@ cdef class StaticSparseBackend(CGraphBackend): def num_verts(self): r""" - Return the number of vertices + Return the number of vertices. TESTS:: @@ -906,7 +906,7 @@ cdef class StaticSparseBackend(CGraphBackend): def allows_loops(self, value=None): r""" - Return whether the graph allows loops + Return whether the graph allows loops. INPUT: @@ -931,7 +931,7 @@ cdef class StaticSparseBackend(CGraphBackend): def multiple_edges(self, value=None): r""" - Return whether the graph allows multiple edges + Return whether the graph allows multiple edges. INPUT: @@ -956,12 +956,12 @@ cdef class StaticSparseBackend(CGraphBackend): def num_edges(self, directed): r""" - Return the number of edges + Return the number of edges. INPUT: - ``directed`` -- boolean; whether to consider the graph as directed or - not. + not TESTS:: @@ -981,7 +981,7 @@ cdef class StaticSparseBackend(CGraphBackend): :issue:`15491`:: sage: g = digraphs.RandomDirectedGNP(10, .3) - sage: gi = DiGraph(g, data_structure="static_sparse") + sage: gi = DiGraph(g, data_structure='static_sparse') sage: gi.size() == len(gi.edges(sort=False)) True """ @@ -1069,10 +1069,10 @@ cdef class StaticSparseBackend(CGraphBackend): INPUT: - ``other`` -- a (mutable) subclass of :class:`CGraphBackend` - - ``vertices`` -- a list of vertex labels + - ``vertices`` -- list of vertex labels - ``modus`` -- integer representing the modus: - ``0`` -- initialize ``other`` to be the subgraph induced by the vertices; - see :meth:`subgraph_given_vertices`` + see :meth:`subgraph_given_vertices` - ``1`` -- test whether subgraph of ``self`` induced by the vertices is a subgraph of ``other`` - ``2`` -- as ``1`` but ignore the labels """ @@ -1200,7 +1200,7 @@ cdef class StaticSparseBackend(CGraphBackend): def degree(self, v, directed): r""" - Return the degree of a vertex + Return the degree of a vertex. INPUT: @@ -1211,7 +1211,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = Graph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = Graph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.degree(0) 3 @@ -1245,7 +1245,7 @@ cdef class StaticSparseBackend(CGraphBackend): def in_degree(self, v): r""" - Return the in-degree of a vertex + Return the in-degree of a vertex. INPUT: @@ -1253,7 +1253,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = DiGraph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = DiGraph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.in_degree(0) 3 """ @@ -1271,7 +1271,7 @@ cdef class StaticSparseBackend(CGraphBackend): def out_degree(self, v): r""" - Return the out-degree of a vertex + Return the out-degree of a vertex. INPUT: @@ -1279,7 +1279,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = DiGraph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = DiGraph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.out_degree(0) 3 """ @@ -1294,7 +1294,7 @@ cdef class StaticSparseBackend(CGraphBackend): def iterator_nbrs(self, v): r""" - Iterate over the neighbors of a vertex + Iterate over the neighbors of a vertex. INPUT: @@ -1302,7 +1302,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = Graph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = Graph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.neighbors(0) [1, 4, 5] @@ -1351,7 +1351,7 @@ cdef class StaticSparseBackend(CGraphBackend): def iterator_out_nbrs(self, v): r""" - Iterate over the out-neighbors of a vertex + Iterate over the out-neighbors of a vertex. INPUT: @@ -1359,7 +1359,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = DiGraph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = DiGraph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.neighbors_out(0) [1, 4, 5] """ @@ -1380,7 +1380,7 @@ cdef class StaticSparseBackend(CGraphBackend): def iterator_in_nbrs(self, v): r""" - Iterate over the in-neighbors of a vertex + Iterate over the in-neighbors of a vertex. INPUT: @@ -1388,7 +1388,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = DiGraph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = DiGraph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.neighbors_in(0) [1, 4, 5] @@ -1426,7 +1426,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = DiGraph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = DiGraph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.add_vertex(1) Traceback (most recent call last): ... @@ -1444,7 +1444,7 @@ cdef class StaticSparseBackend(CGraphBackend): EXAMPLES:: - sage: g = DiGraph(graphs.PetersenGraph(), data_structure="static_sparse") + sage: g = DiGraph(graphs.PetersenGraph(), data_structure='static_sparse') sage: g.delete_vertex(1) Traceback (most recent call last): ... @@ -1484,7 +1484,7 @@ def _run_it_on_static_instead(f): """ def same_function_on_static_version(*kwd, **kwds): if not isinstance(kwd[0]._backend, StaticSparseBackend): - gcopy = kwd[0].copy(data_structure="static_sparse") + gcopy = kwd[0].copy(data_structure='static_sparse') return getattr(gcopy, f.__name__)(*kwd[1:], **kwds) else: return f(*kwd, **kwds) diff --git a/src/sage/graphs/base/static_sparse_graph.pxd b/src/sage/graphs/base/static_sparse_graph.pxd index 03adfe11322..6cb9e53f17d 100644 --- a/src/sage/graphs/base/static_sparse_graph.pxd +++ b/src/sage/graphs/base/static_sparse_graph.pxd @@ -7,27 +7,19 @@ ctypedef unsigned int uint cdef extern from "stdlib.h": ctypedef void const_void "const void" - void qsort(void *base, int nmemb, int size, - int(*compar)(const_void *, const_void *)) nogil - void *bsearch(const_void *key, const_void *base, size_t nmemb, size_t size, int(*compar)(const_void *, const_void *)) nogil -cdef extern from "search.h": - void *lfind(const_void *key, const_void *base, size_t *nmemb, - size_t size, int(*compar)(const_void *, const_void *)) nogil - ctypedef struct short_digraph_s: uint32_t * edges uint32_t ** neighbors PyObject * edge_labels int m int n - bint sorted_neighbors ctypedef short_digraph_s short_digraph[1] -cdef int init_short_digraph(short_digraph g, G, edge_labelled=?, vertex_list=?, sort_neighbors=?) except -1 +cdef int init_short_digraph(short_digraph g, G, edge_labelled=?, vertex_list=?) except -1 cdef void free_short_digraph(short_digraph g) noexcept cdef int init_reverse(short_digraph dst, short_digraph src) except -1 cdef int out_degree(short_digraph g, int u) noexcept diff --git a/src/sage/graphs/base/static_sparse_graph.pyx b/src/sage/graphs/base/static_sparse_graph.pyx index 898b69568d0..c27f0d9a8cc 100644 --- a/src/sage/graphs/base/static_sparse_graph.pyx +++ b/src/sage/graphs/base/static_sparse_graph.pyx @@ -33,22 +33,25 @@ Data structure The data structure is actually pretty simple and compact. ``short_digraph`` has five fields -- ``n`` (``int``); the number of vertices in the graph +- ``n`` -- integer; the number of vertices in the graph -- ``m`` (``int``); the number of edges in the graph +- ``m`` -- integer; the number of edges in the graph -- ``edges`` (``uint32_t *``); array whose length is the number of edges of the +- ``edges`` -- ``uint32_t *``; array whose length is the number of edges of the graph -- ``neighbors`` (``uint32_t **``); this array has size `n+1`, and describes how +- ``neighbors`` -- ``uint32_t **``; this array has size `n+1`, and describes how the data of ``edges`` should be read : the neighbors of vertex `i` are the elements of ``edges`` addressed by ``neighbors[i]...neighbors[i+1]-1``. The element ``neighbors[n]``, which corresponds to no vertex (they are numbered from `0` to `n-1`) is present so that it remains easy to enumerate the neighbors of vertex `n-1` : the last of them is the element addressed by ``neighbors[n]-1``. + The arrays ``neighbors[i]`` are guaranteed to be sorted so the time + complexity for deciding if ``g`` has edge `(u, v)` is `O(\log{m})` using + binary search. -- ``edge_labels`` (``list``); this cython list associates a label to each edge +- ``edge_labels`` -- list; this cython list associates a label to each edge of the graph. If a given edge is represented by ``edges[i]``, this its associated label can be found at ``edge_labels[i]``. This object is usually NULL, unless the call to ``init_short_digraph`` explicitly requires the labels @@ -116,7 +119,7 @@ Cython functions :widths: 30, 70 :delim: | - ``init_short_digraph(short_digraph g, G, edge_labelled, vertex_list, sort_neighbors)`` | Initialize ``short_digraph g`` from a Sage (Di)Graph. + ``init_short_digraph(short_digraph g, G, edge_labelled, vertex_list)`` | Initialize ``short_digraph g`` from a Sage (Di)Graph. ``int n_edges(short_digraph g)`` | Return the number of edges in ``g`` ``int out_degree(short_digraph g, int i)`` | Return the out-degree of vertex `i` in ``g`` ``has_edge(short_digraph g, int u, int v)`` | Test the existence of an edge. @@ -187,10 +190,10 @@ from libc.math cimport sqrt from libcpp.vector cimport vector from cysignals.memory cimport check_allocarray, check_calloc, sig_free from cysignals.signals cimport sig_on, sig_off +from cython.operator cimport postincrement from memory_allocator cimport MemoryAllocator from sage.data_structures.bitset_base cimport * -from sage.graphs.base.c_graph cimport CGraph from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend @@ -205,7 +208,7 @@ cdef extern from "fenv.h": cdef int init_short_digraph(short_digraph g, G, edge_labelled=False, - vertex_list=None, sort_neighbors=True) except -1: + vertex_list=None) except -1: r""" Initialize ``short_digraph g`` from a Sage (Di)Graph. @@ -223,63 +226,78 @@ cdef int init_short_digraph(short_digraph g, G, edge_labelled=False, - ``vertex_list`` -- list (default: ``None``); list of all vertices of ``G`` in some order. When given, it is used to map the vertices of the graph to consecutive integers. Otherwise, the result of ``list(G)`` is used - instead. - - - ``sort_neighbors`` -- boolean (default: ``True``); whether to ensure that - the vertices in the list of neighbors of a vertex are sorted by increasing - vertex labels. This choice may have a non-negligeable impact on the time - complexity of some methods. More precisely: - - - When set to ``True``, the time complexity for initializing ``g`` is in - `O(n + m\log{m})` for ``SparseGraph`` and `O(n^2\log{m})` for - ``DenseGraph``, and deciding if ``g`` has edge `(u, v)` can be done in - time `O(\log{m})` using binary search. - - - When set to ``False``, the time complexity for initializing ``g`` is - reduced to `O(n + m)` for ``SparseGraph`` and `O(n^2)` for - ``DenseGraph``, but the time complexity for deciding if ``g`` has - edge `(u, v)` increases to `O(m)`. - """ - g.edge_labels = NULL + instead. Beware that if ``vertex_list`` is not ``None``, it is not checked + and this function assumes that it contains a permutation of the vertices + of the graph ``G``. - if G.order() >= INT_MAX: - raise ValueError("this structure can handle at most " + str(INT_MAX) + " vertices") - else: - g.n = G.order() + COMPLEXITY: - cdef int isdigraph + The time complexity for initializing ``g`` is `O(n + m)` for ``SparseGraph`` + and `O(n^2)` for ``DenseGraph``. + TESTS: + + Indirect doctests for sorted output:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: G = graphs.CompleteGraph(5).relabel(list('abcde'), inplace=False) + sage: B = StaticSparseBackend(G, sort=False) + sage: list(B.iterator_nbrs('a')) + ['b', 'c', 'd', 'e'] + sage: G = graphs.CompleteGraph(5).relabel(list('badec'), inplace=False) + sage: B = StaticSparseBackend(G, sort=False) + sage: list(B.iterator_nbrs('a')) + ['b', 'd', 'e', 'c'] + + Same with labels:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: G = graphs.CompleteGraph(5).relabel(list('abcde'), inplace=False) + sage: for i, (u, v, _) in enumerate(G.edges()): + ....: G.set_edge_label(u, v, f'{u}{v}') + sage: B = StaticSparseBackend(G, sort=False) + sage: list(B.iterator_edges('a', True)) + [('a', 'b', 'ab'), ('a', 'c', 'ac'), ('a', 'd', 'ad'), ('a', 'e', 'ae')] + sage: G = graphs.CompleteGraph(5).relabel(list('badec'), inplace=False) + sage: for i, (u, v, _) in enumerate(G.edges()): + ....: G.set_edge_label(u, v, f'{u}{v}') + sage: B = StaticSparseBackend(G, sort=False) + sage: list(B.iterator_edges('a', True)) + [('a', 'b', 'ab'), ('a', 'd', 'ad'), ('a', 'e', 'ae'), ('a', 'c', 'ac')] + """ from sage.graphs.graph import Graph from sage.graphs.digraph import DiGraph - if isinstance(G, DiGraph): - isdigraph = 1 - elif isinstance(G, Graph): - isdigraph = 0 - else: - raise ValueError("The source graph must be either a DiGraph or a Graph object !") + if not isinstance(G, (Graph, DiGraph)): + raise ValueError("The source graph must be either a DiGraph or a Graph" + "object !") - cdef int i, j, v_id + if G.order() >= INT_MAX: + raise ValueError(f"short_digraph can handle at most {INT_MAX} vertices") + + g.edge_labels = NULL + g.n = G.order() + g.m = G.size() + + cdef int isdigraph = G.is_directed() + cdef uint32_t i, v_id, j cdef list vertices = vertex_list if vertex_list is not None else list(G) cdef dict v_to_id = {v: i for i, v in enumerate(vertices)} cdef list neighbor_label cdef list edge_labels - - g.m = G.size() - cdef int n_edges = g.m if isdigraph else 2*g.m + # Loops are not stored twice for undirected graphs + cdef int n_edges = g.m if isdigraph else 2*g.m - G.number_of_loops() g.edges = check_allocarray(n_edges, sizeof(uint32_t)) g.neighbors = check_allocarray(1 + g.n, sizeof(uint32_t *)) # Initializing the value of neighbors g.neighbors[0] = g.edges - cdef CGraph cg = G._backend - g.sorted_neighbors = sort_neighbors if not G.has_loops(): # Normal case - for i in range(1, (g.n) + 1): - g.neighbors[i] = g.neighbors[i - 1] + (cg.out_degree(vertices[i - 1]) if isdigraph else G.degree(vertices[i - 1])) + for i, v in enumerate(vertices): + g.neighbors[i+1] = g.neighbors[i] + (G.out_degree(v) if isdigraph else G.degree(v)) else: # In the presence of loops. For a funny reason, if a vertex v has a loop # attached to it and no other incident edge, Sage declares that it has @@ -287,55 +305,40 @@ cdef int init_short_digraph(short_digraph g, G, edge_labelled=False, # the number of edges, but then the degree of a vertex is not the number # of its neighbors anymore. One should never try to think. It never ends # well. - for i in range(1, (g.n) + 1): - g.neighbors[i] = g.neighbors[i - 1] + len(G.edges_incident(vertices[i - 1])) - - if not edge_labelled: - for u, v in G.edge_iterator(labels=False, sort_vertices=False): - i = v_to_id[u] - j = v_to_id[v] - - g.neighbors[i][0] = j - g.neighbors[i] += 1 + for i, v in enumerate(vertices): + g.neighbors[i+1] = g.neighbors[i] + len(G.edges_incident(v)) - if not isdigraph and i != j: - g.neighbors[j][0] = i - g.neighbors[j] += 1 - - # Reinitializing the value of neighbors - for i in range(g.n - 1, 0, -1): - g.neighbors[i] = g.neighbors[i - 1] - - g.neighbors[0] = g.edges - - if sort_neighbors: - # Sorting the neighbors - for i in range(g.n): - qsort(g.neighbors[i], g.neighbors[i + 1] - g.neighbors[i], sizeof(int), compare_uint32_p) - - else: - from operator import itemgetter + if edge_labelled: edge_labels = [None] * n_edges - if sort_neighbors: - for v in G: - neighbor_label = [(v_to_id[uu], l) if uu != v else (v_to_id[u], l) - for u, uu, l in G.edges_incident(v)] - neighbor_label.sort(key=itemgetter(0)) - v_id = v_to_id[v] - - for i, (j, label) in enumerate(neighbor_label): - g.neighbors[v_id][i] = j - edge_labels[(g.neighbors[v_id] + i) - g.edges] = label + + # Note that neighbors[i] will be naturally sorted by increasing id, + # because the arrays will be built by appending vertices in the same + # order as they appear in ``vertices`` + for i, v in enumerate(vertices): + if isdigraph: + edge_iterator = G.incoming_edge_iterator(v, + labels=edge_labelled) else: - for v in G: - v_id = v_to_id[v] - for i, (u, uu, label) in enumerate(G.edges_incident(v)): - if v == uu: - g.neighbors[v_id][i] = v_to_id[u] - else: - g.neighbors[v_id][i] = v_to_id[uu] - edge_labels[(g.neighbors[v_id] + i) - g.edges] = label + edge_iterator = G.edge_iterator(v, labels=edge_labelled, + sort_vertices=False) + for e in edge_iterator: + u = e[0] if v == e[1] else e[1] + j = v_to_id[u] + # Handle the edge u -> v of G (= the edge j -> i of g) + g.neighbors[j][0] = i + # Note: cannot use the dereference Cython operator here, do not + # known why but the following line does not compile + #dereference(g.neighbors[j]) = i + if edge_labelled: + edge_labels[g.neighbors[j] - g.edges] = e[2] + postincrement(g.neighbors[j]) # increment pointer to next item + + # Reinitializing the value of neighbors + for i in range(g.n-1, 0, -1): + g.neighbors[i] = g.neighbors[i-1] + g.neighbors[0] = g.edges + if edge_labelled: g.edge_labels = edge_labels cpython.Py_XINCREF(g.edge_labels) @@ -365,7 +368,6 @@ cdef int init_empty_copy(short_digraph dst, short_digraph src) except -1: """ dst.n = src.n dst.m = src.m - dst.sorted_neighbors = src.sorted_neighbors dst.edge_labels = NULL cdef list edge_labels @@ -382,6 +384,24 @@ cdef int init_reverse(short_digraph dst, short_digraph src) except -1: """ Initialize ``dst`` to a copy of ``src`` with all edges in the opposite direction. + + TESTS: + + Indirect doctests for sorted output:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: D = digraphs.Complete(5).relabel(list('abcde'), inplace=False) + sage: for i, (u, v, _) in enumerate(D.edges()): + ....: D.set_edge_label(u, v, f'{u}{v}') + sage: B = StaticSparseBackend(D, sort=False) + sage: list(B.iterator_in_edges('a', True)) + [('b', 'a', 'ba'), ('c', 'a', 'ca'), ('d', 'a', 'da'), ('e', 'a', 'ea')] + sage: D = digraphs.Complete(5).relabel(list('badec'), inplace=False) + sage: for i, (u, v, _) in enumerate(D.edges()): + ....: D.set_edge_label(u, v, f'{u}{v}') + sage: B = StaticSparseBackend(D, sort=False) + sage: list(B.iterator_in_edges('a', True)) + [('b', 'a', 'ba'), ('d', 'a', 'da'), ('e', 'a', 'ea'), ('c', 'a', 'ca')] """ cdef int i, j, v # Allocates memory for dst @@ -391,7 +411,7 @@ cdef int init_reverse(short_digraph dst, short_digraph src) except -1: if not dst.n: return 0 - # 1/4 + # 1/3 # # In a first pass, we count the in-degrees of each vertex and store it in a # vector. With this information, we can initialize dst.neighbors to its @@ -407,11 +427,14 @@ cdef int init_reverse(short_digraph dst, short_digraph src) except -1: dst.neighbors[i] = dst.neighbors[i - 1] + in_degree[i - 1] sig_free(in_degree) - # 2/4 + # 2/3 # # Second pass : we list the edges again, and add them in dst.edges. Doing # so, we will change the value of dst.neighbors, but that is not so bad as # we can fix it afterwards. + # Note that neighbors[i] will be naturally sorted by increasing id, + # because the arrays will be built by appending vertices in the same + # order as they appear in ``vertices`` for i in range(0, src.n): for j in range(out_degree(src, i)): v = src.neighbors[i][j] @@ -422,7 +445,7 @@ cdef int init_reverse(short_digraph dst, short_digraph src) except -1: dst.neighbors[v] += 1 - # 3/4 + # 3/3 # # Third step : set the correct values of dst.neighbors again. It is easy, as # the correct value of dst.neighbors[i] is actually dst.neighbors[i-1] @@ -430,20 +453,12 @@ cdef int init_reverse(short_digraph dst, short_digraph src) except -1: dst.neighbors[i] = dst.neighbors[i - 1] dst.neighbors[0] = dst.edges - # 4/4 - # - # Final step : if the neighbors of src are assumed to be sorted by - # increasing labels, we do the same for dst. - if src.sorted_neighbors: - for i in range(dst.n): - qsort(dst.neighbors[i], dst.neighbors[i + 1] - dst.neighbors[i], sizeof(int), compare_uint32_p) - return 0 cdef int compare_uint32_p(const_void *a, const_void *b) noexcept: """ - Comparison function needed for ``bsearch`` and ``lfind``. + Comparison function needed for ``bsearch``. """ return ( a)[0] - ( b)[0] @@ -454,17 +469,16 @@ cdef inline uint32_t * has_edge(short_digraph g, int u, int v) noexcept: Return a pointer to ``v`` in the list of neighbors of ``u`` if found and ``NULL`` otherwise. - """ - if g.sorted_neighbors: - # The neighbors of u are sorted by increasing label. We can use binary - # search to decide if g has edge (u, v) - return bsearch(&v, g.neighbors[u], g.neighbors[u + 1] - g.neighbors[u], - sizeof(uint32_t), compare_uint32_p) - # Otherwise, we use the linear time lfind method - cdef size_t nelem = g.neighbors[u + 1] - g.neighbors[u] - return lfind(&v, g.neighbors[u], &nelem, - sizeof(uint32_t), compare_uint32_p) + .. NOTE:: + + Use the fact that the array ``g.neighbors[u]`` is guaranteed to be sorted. + """ + # The neighbors of u are sorted by increasing label. We can use binary + # search to decide if g has edge (u, v) + return bsearch(&v, g.neighbors[u], + g.neighbors[u+1] - g.neighbors[u], + sizeof(uint32_t), compare_uint32_p) cdef inline object edge_label(short_digraph g, uint32_t * edge): @@ -514,7 +528,6 @@ cdef uint32_t simple_BFS(short_digraph g, - ``seen`` -- bitset of size ``n`` that must be initialized before calling this method (i.e., bitset_init(seen, n)). However, there is no need to clear it. - """ cdef uint32_t v, u cdef uint32_t waiting_beginning = 0 @@ -798,7 +811,7 @@ def tarjan_strongly_connected_components(G): cdef MemoryAllocator mem = MemoryAllocator() cdef list int_to_vertex = list(G) cdef short_digraph g - init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex, sort_neighbors=False) + init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex) cdef int * scc = mem.malloc(g.n * sizeof(int)) sig_on() cdef int nscc = tarjan_strongly_connected_components_C(g, scc) @@ -915,7 +928,7 @@ def strongly_connected_components_digraph(G): cdef MemoryAllocator mem = MemoryAllocator() cdef list int_to_vertex = list(G) cdef short_digraph g, scc_g - init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex, sort_neighbors=False) + init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex) cdef int * scc = mem.malloc(g.n * sizeof(int)) cdef int i, j, nscc cdef list edges = [] @@ -964,7 +977,7 @@ def triangles_count(G): INPUT: - - `G` -- a graph + - ``G`` -- a graph EXAMPLES:: @@ -980,7 +993,7 @@ def triangles_count(G): # g is a copy of G. If G is internally a static sparse graph, we use it. cdef list int_to_vertex = list(G) cdef short_digraph g - init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex, sort_neighbors=True) + init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex) cdef uint64_t * count = check_calloc(G.order(), sizeof(uint64_t)) @@ -1028,11 +1041,11 @@ def spectral_radius(G, prec=1e-10): INPUT: - - ``prec`` -- (default ``1e-10``) an upper bound for the relative precision + - ``prec`` -- (default: ``1e-10``) an upper bound for the relative precision of the interval - The algorithm is iterative and uses an inequality valid for non-negative - matrices. Namely, if `A` is a non-negative square matrix with + The algorithm is iterative and uses an inequality valid for nonnegative + matrices. Namely, if `A` is a nonnegative square matrix with Perron-Frobenius eigenvalue `\lambda` then the following inequality is valid for any vector `x` diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 8ce6c3f4463..45e4c67747d 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -81,7 +81,7 @@ class BipartiteGraph(Graph): #. From a NetworkX bipartite graph. - - ``partition`` -- (default: ``None``); a tuple defining vertices of the left + - ``partition`` -- (default: ``None``) a tuple defining vertices of the left and right partition of the graph. Partitions will be determined automatically if ``partition`` is ``None``. @@ -256,7 +256,7 @@ class BipartiteGraph(Graph): #. From an alist file:: sage: import tempfile - sage: with tempfile.NamedTemporaryFile(mode="w+t") as f: + sage: with tempfile.NamedTemporaryFile(mode='w+t') as f: ....: _ = f.write("7 4 \n 3 4 \n 3 3 1 3 1 1 1 \n\ ....: 3 3 3 4 \n 1 2 4 \n 1 3 4 \n 1 0 0 \n\ ....: 2 3 4 \n 2 0 0 \n 3 0 0 \n 4 0 0 \n\ @@ -354,7 +354,6 @@ class BipartiteGraph(Graph): Traceback (most recent call last): ... ValueError: cannot add edge from 0 to 0 in graph without loops - """ def __init__(self, data=None, partition=None, check=True, hash_labels=None, *args, **kwds): @@ -639,7 +638,7 @@ def _upgrade_from_graph(self): def __repr__(self): r""" - Return a short string representation of self. + Return a short string representation of ``self``. EXAMPLES:: @@ -659,16 +658,16 @@ def add_vertex(self, name=None, left=False, right=False): INPUT: - - ``name`` -- (default: ``None``); name of the new vertex. If no name is + - ``name`` -- (default: ``None``) name of the new vertex. If no name is specified, then the vertex will be represented by the least - non-negative integer not already representing a vertex. Name must be + nonnegative integer not already representing a vertex. Name must be an immutable object and cannot be ``None``. - ``left`` -- boolean (default: ``False``); if ``True``, puts the new - vertex in the left partition. + vertex in the left partition - ``right`` -- boolean (default: ``False``); if ``True``, puts the new - vertex in the right partition. + vertex in the right partition Obviously, ``left`` and ``right`` are mutually exclusive. @@ -756,13 +755,13 @@ def add_vertices(self, vertices, left=False, right=False): INPUT: - - ``vertices`` -- sequence of vertices to add. + - ``vertices`` -- sequence of vertices to add - - ``left`` -- (default: ``False``); either ``True`` or sequence of same - length as ``vertices`` with ``True``/``False`` elements. + - ``left`` -- (default: ``False``) either ``True`` or sequence of same + length as ``vertices`` with boolean elements - - ``right`` -- (default: ``False``); either ``True`` or sequence of the - same length as ``vertices`` with ``True``/``False`` elements. + - ``right`` -- (default: ``False``) either ``True`` or sequence of the + same length as ``vertices`` with boolean elements Only one of ``left`` and ``right`` keywords should be provided. See the examples below. @@ -846,11 +845,11 @@ def delete_vertex(self, vertex, in_order=False): INPUT: - - ``vertex`` -- a vertex to delete. + - ``vertex`` -- a vertex to delete - - ``in_order`` -- boolean (default ``False``); if ``True``, deletes the + - ``in_order`` -- boolean (default: ``False``); if ``True``, deletes the `i`-th vertex in the sorted list of vertices, - i.e. ``G.vertices(sort=True)[i]``. + i.e. ``G.vertices(sort=True)[i]`` EXAMPLES:: @@ -987,12 +986,12 @@ def add_edge(self, u, v=None, label=None): INPUT: - - ``u`` -- the tail of an edge. + - ``u`` -- the tail of an edge - - ``v`` -- (default: ``None``); the head of an edge. If ``v=None``, then - attempt to understand ``u`` as a edge tuple. + - ``v`` -- (default: ``None``) the head of an edge. If ``v=None``, then + attempt to understand ``u`` as a edge tuple - - ``label`` -- (default: ``None``); the label of the edge ``(u, v)``. + - ``label`` -- (default: ``None``) the label of the edge ``(u, v)`` The following forms are all accepted: @@ -1080,7 +1079,7 @@ def add_edges(self, edges, loops=True): INPUT: - ``edges`` -- an iterable of edges, given either as ``(u, v)`` - or ``(u, v, label)``. + or ``(u, v, label)`` - ``loops`` -- ignored @@ -1190,7 +1189,7 @@ def _check_bipartition_for_add_edges(self, edges): INPUT: - ``edges`` -- an iterable of edges, given either as ``(u, v)`` - or ``(u, v, label)``. + or ``(u, v, label)`` TESTS:: @@ -1254,7 +1253,7 @@ def _check_bipartition_for_add_edges(self, edges): def allow_loops(self, new, check=True): """ - Change whether loops are permitted in the (di)graph + Change whether loops are permitted in the (di)graph. .. NOTE:: @@ -1485,7 +1484,7 @@ def plot(self, *args, **kwds): kwds["pos"] = pos return Graph.plot(self, *args, **kwds) - def matching_polynomial(self, algorithm="Godsil", name=None): + def matching_polynomial(self, algorithm='Godsil', name=None): r""" Compute the matching polynomial. @@ -1498,7 +1497,7 @@ def matching_polynomial(self, algorithm="Godsil", name=None): INPUT: - - ``algorithm`` -- string (default: ``"Godsil"``); either "Godsil" or + - ``algorithm`` -- string (default: ``'Godsil'``); either "Godsil" or "rook"; "rook" is usually faster for larger graphs - ``name`` -- string (default: ``None``); name of the variable in the @@ -1539,7 +1538,7 @@ def matching_polynomial(self, algorithm="Godsil", name=None): sage: g = BipartiteGraph(matrix.ones(4, 3)) sage: g.matching_polynomial() # needs sage.libs.flint x^7 - 12*x^5 + 36*x^3 - 24*x - sage: g.matching_polynomial(algorithm="rook") + sage: g.matching_polynomial(algorithm='rook') x^7 - 12*x^5 + 36*x^3 - 24*x """ if algorithm == "Godsil": @@ -1724,7 +1723,7 @@ def load_afile(self, fname): EXAMPLES:: sage: import tempfile - sage: with tempfile.NamedTemporaryFile(mode="w+t") as f: + sage: with tempfile.NamedTemporaryFile(mode='w+t') as f: ....: _ = f.write("7 4 \n 3 4 \n 3 3 1 3 1 1 1 \n\ ....: 3 3 3 4 \n 1 2 4 \n 1 3 4 \n\ ....: 1 0 0 \n 2 3 4 \n 2 0 0 \n 3 0 0 \n\ @@ -1754,7 +1753,7 @@ def load_afile(self, fname): """ # open the file try: - fi = open(fname, "r") + fi = open(fname) except OSError: print("unable to open file <<" + fname + ">>") return None @@ -1784,7 +1783,7 @@ def load_afile(self, fname): # read adjacency information for cidx in range(num_cols): for ridx in map(int, fi.readline().split()): - # A-list uses 1-based indices with 0's as place-holders + # A-list uses 1-based indices with 0s as place-holders if ridx > 0: self.add_edge(cidx, num_cols + ridx - 1) @@ -2061,29 +2060,29 @@ def matching(self, value_only=False, algorithm=None, - ``value_only`` -- boolean (default: ``False``); when set to ``True``, only the cardinal (or the weight) of the matching is returned - - ``algorithm`` -- string (default: ``"Hopcroft-Karp"`` if - ``use_edge_labels==False``, otherwise ``"Edmonds"``); algorithm to use + - ``algorithm`` -- string (default: ``'Hopcroft-Karp'`` if + ``use_edge_labels==False``, otherwise ``'Edmonds'``); algorithm to use among: - - ``"Hopcroft-Karp"`` selects the default bipartite graph algorithm as + - ``'Hopcroft-Karp'`` selects the default bipartite graph algorithm as implemented in NetworkX - - ``"Eppstein"`` selects Eppstein's algorithm as implemented in + - ``'Eppstein'`` selects Eppstein's algorithm as implemented in NetworkX - - ``"Edmonds"`` selects Edmonds' algorithm as implemented in NetworkX + - ``'Edmonds'`` selects Edmonds' algorithm as implemented in NetworkX - - ``"LP"`` uses a Linear Program formulation of the matching problem + - ``'LP'`` uses a Linear Program formulation of the matching problem - ``use_edge_labels`` -- boolean (default: ``False``) - when set to ``True``, computes a weighted matching where each edge is weighted by its label (if an edge has no label, `1` is assumed); - only if ``algorithm`` is ``"Edmonds"``, ``"LP"`` + only if ``algorithm`` is ``'Edmonds'``, ``'LP'`` - when set to ``False``, each edge has weight `1` - - ``solver`` -- string (default: ``None``); specify a Mixed + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the @@ -2092,7 +2091,7 @@ def matching(self, value_only=False, algorithm=None, class :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with @@ -2116,7 +2115,7 @@ class :class:`MixedIntegerLinearProgram Eppstein:: sage: G = BipartiteGraph(graphs.CompleteBipartiteGraph(4,5)) - sage: G.matching(algorithm="Eppstein", value_only=True) # needs networkx + sage: G.matching(algorithm='Eppstein', value_only=True) # needs networkx 4 TESTS: @@ -2125,7 +2124,7 @@ class :class:`MixedIntegerLinearProgram exception is raised:: sage: G = BipartiteGraph(graphs.CompleteBipartiteGraph(4,5)) - sage: G.matching(algorithm="somethingdifferent") + sage: G.matching(algorithm='somethingdifferent') Traceback (most recent call last): ... ValueError: algorithm must be "Hopcroft-Karp", "Eppstein", "Edmonds" or "LP" @@ -2225,11 +2224,11 @@ class :class:`MixedIntegerLinearProgram raise ValueError('algorithm must be "Hopcroft-Karp", ' '"Eppstein", "Edmonds" or "LP"') - def vertex_cover(self, algorithm="Konig", value_only=False, + def vertex_cover(self, algorithm='Konig', value_only=False, reduction_rules=True, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Return a minimum vertex cover of self represented by a set of vertices. + Return a minimum vertex cover of ``self`` represented by a set of vertices. A minimum vertex cover of a graph is a set `S` of vertices such that each edge is incident to at least one element of `S`, and such that `S` @@ -2249,19 +2248,19 @@ def vertex_cover(self, algorithm="Konig", value_only=False, INPUT: - - ``algorithm`` -- string (default: ``"Konig"``); algorithm to use + - ``algorithm`` -- string (default: ``'Konig'``); algorithm to use among: - - ``"Konig"`` will compute a minimum vertex cover using Konig's + - ``'Konig'`` will compute a minimum vertex cover using Konig's algorithm (:wikipedia:`Kőnig%27s_theorem_(graph_theory)`) - - ``"Cliquer"`` will compute a minimum vertex cover + - ``'Cliquer'`` will compute a minimum vertex cover using the Cliquer package - - ``"MILP"`` will compute a minimum vertex cover through a mixed + - ``'MILP'`` will compute a minimum vertex cover through a mixed integer linear program - - ``"mcqd"`` will use the MCQD solver + - ``'mcqd'`` will use the MCQD solver (``_), and the MCQD package must be installed @@ -2269,13 +2268,13 @@ def vertex_cover(self, algorithm="Konig", value_only=False, only the size of a minimum vertex cover is returned. Otherwise, a minimum vertex cover is returned as a list of vertices. - - ``reduction_rules`` -- (default: ``True``); specify if the reductions + - ``reduction_rules`` -- (default: ``True``) specify if the reductions rules from kernelization must be applied as pre-processing or not. See [ACFLSS04]_ for more details. Note that depending on the instance, it might be faster to disable reduction rules. This parameter is currently ignored when ``algorithm == "Konig"``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -2283,7 +2282,7 @@ def vertex_cover(self, algorithm="Konig", value_only=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -2304,8 +2303,8 @@ def vertex_cover(self, algorithm="Konig", value_only=False, sage: # needs networkx numpy sage: g = BipartiteGraph(graphs.RandomBipartite(10, 10, .5)) - sage: vc1 = g.vertex_cover(algorithm="Konig") - sage: vc2 = g.vertex_cover(algorithm="Cliquer") + sage: vc1 = g.vertex_cover(algorithm='Konig') + sage: vc2 = g.vertex_cover(algorithm='Cliquer') sage: len(vc1) == len(vc2) True @@ -2345,7 +2344,7 @@ def vertex_cover(self, algorithm="Konig", value_only=False, VC = [] for b in self.connected_components_subgraphs(): if b.size(): - VC.extend(b.vertex_cover(algorithm="Konig")) + VC.extend(b.vertex_cover(algorithm='Konig')) if value_only: return sum(VC) return VC @@ -2397,14 +2396,14 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm - ``vertices`` -- list (default: ``None``); list of vertices - - ``edges`` -- (default: ``None``); either a single edge or an iterable + - ``edges`` -- (default: ``None``) either a single edge or an iterable container of edges (e.g., a list, set, file, numeric array, etc.). If no edges are specified, then all edges are assumed and the returned graph is an induced subgraph. In the case of multiple edges, specifying an edge as `(u, v)` means to keep all edges `(u, v)`, regardless of the label. - - ``edge_property`` -- (default: ``None``); if specified, this is + - ``edge_property`` -- (default: ``None``) if specified, this is expected to be a function on edges, which is intersected with the edges specified, if any are @@ -2478,7 +2477,7 @@ def _subgraph_by_deleting(self, vertices=None, edges=None, inplace=False, - ``vertices`` -- list (default: ``None``); list of vertices - - ``edges`` -- (default: ``None``); either a single edge or an iterable + - ``edges`` -- (default: ``None``) either a single edge or an iterable container of edges (e.g., a list, set, file, numeric array, etc.). If no edges are specified, then all edges are assumed and the returned graph is an induced subgraph. In the case of multiple edges, @@ -2489,7 +2488,7 @@ def _subgraph_by_deleting(self, vertices=None, edges=None, inplace=False, current graph is modified in place by deleting the extra vertices and edges. Otherwise a modified copy of the graph is returned - - ``edge_property`` -- (default: ``None``); if specified, this is + - ``edge_property`` -- (default: ``None``) if specified, this is expected to be a function on edges, which is intersected with the edges specified, if any are @@ -2567,15 +2566,15 @@ class by some canonization function `c`. If `G` and `H` are graphs, to this set partition will be computed. The default is the unit set partition. - - ``certificate`` -- boolean (default: ``False``). When set to + - ``certificate`` -- boolean (default: ``False``); when set to ``True``, a dictionary mapping from the vertices of the (di)graph - to its canonical label will also be returned. + to its canonical label will also be returned - - ``edge_labels`` -- boolean (default: ``False``). When set to - ``True``, allows only permutations respecting edge labels. + - ``edge_labels`` -- boolean (default: ``False``); when set to + ``True``, allows only permutations respecting edge labels - - ``algorithm`` -- a string (default: ``None``). The algorithm to use; - currently available: + - ``algorithm`` -- string (default: ``None``); the algorithm to use. + Currently available: * ``'bliss'``: use the optional package bliss (http://www.tcs.tkk.fi/Software/bliss/index.html); @@ -2587,9 +2586,9 @@ class by some canonization function `c`. If `G` and `H` are graphs, Make sure you always compare canonical forms obtained by the same algorithm. - - ``return_graph`` -- boolean (default: ``True``). When set to + - ``return_graph`` -- boolean (default: ``True``); when set to ``False``, returns the list of edges of the canonical graph - instead of the canonical graph; only available when ``'bliss'`` + instead of the canonical graph. Only available when ``'bliss'`` is explicitly set as algorithm. EXAMPLES:: @@ -2637,7 +2636,6 @@ class by some canonization function `c`. If `G` and `H` are graphs, .. SEEALSO:: :meth:`~sage.graphs.generic_graph.GenericGraph.canonical_label()` - """ if certificate: diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index f8491088abc..f9fc09db0ee 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -93,7 +93,7 @@ cdef void add_gen(void *user_param, unsigned int n, const unsigned int *aut) noe a Python object which is a pair ``(list_of_current_generators, vert_to_integer_labelling)``. - - ``n`` -- ``int``; number of points in the graph + - ``n`` -- integer; number of points in the graph - ``aut`` -- ``int *``; an automorphism of the graph """ @@ -157,17 +157,17 @@ cdef Graph *bliss_graph_from_labelled_edges(int Vnr, int Lnr, Vout, Vin, labels, INPUT: - - ``Vnr`` -- ``int``; number of vertices, such that the vertices are `0, + - ``Vnr`` -- integer; number of vertices, such that the vertices are `0, \ldots, Vnr-1` - - ``Lnr`` -- ``int``; number of labels, such that the labels are `0, \ldots, + - ``Lnr`` -- integer; number of labels, such that the labels are `0, \ldots, Lnr-1` - - ``Vout`` -- ``list``; the list of vertices of outgoing edges + - ``Vout`` -- list; the list of vertices of outgoing edges - - ``Vin`` -- ``list``; the list of vertices of ingoing edges + - ``Vin`` -- list; the list of vertices of ingoing edges - - ``labels`` -- ``list``; the list of edge labels + - ``labels`` -- list; the list of edge labels - ``partition`` -- an ordered partition of the vertex set """ @@ -234,17 +234,17 @@ cdef Digraph *bliss_digraph_from_labelled_edges(int Vnr, int Lnr, Vout, Vin, lab INPUT: - - ``Vnr`` -- ``int``; number of vertices, such that the vertices are `0, + - ``Vnr`` -- integer; number of vertices, such that the vertices are `0, \ldots, Vnr-1` - - ``Lnr`` -- ``int``; number of labels, such that the labels are `0, \ldots, + - ``Lnr`` -- integer; number of labels, such that the labels are `0, \ldots, Lnr-1` - - ``Vout`` -- ``list``; the list of vertices of outgoing edges + - ``Vout`` -- list; the list of vertices of outgoing edges - - ``Vin`` -- ``list``; the list of vertices of ingoing edges + - ``Vin`` -- list; the list of vertices of ingoing edges - - ``labels`` -- ``list``; the list of edge labels + - ``labels`` -- list; the list of edge labels - ``partition`` -- a partition of the vertex set """ @@ -306,19 +306,19 @@ cdef canonical_form_from_edge_list(int Vnr, list Vout, list Vin, int Lnr=1, list INPUT: - - ``Vnr`` -- ``int``; number of vertices, such that the vertices are `0, + - ``Vnr`` -- integer; number of vertices, such that the vertices are `0, \ldots, Vnr-1` - - ``Vout`` -- ``list``; the list of vertices of outgoing edges + - ``Vout`` -- list; the list of vertices of outgoing edges - - ``Vin`` -- ``list``; the list of vertices of ingoing edges + - ``Vin`` -- list; the list of vertices of ingoing edges - - ``Lnr`` -- ``int`` (default: 1); number of labels, such that the labels + - ``Lnr`` -- integer (default: 1); number of labels, such that the labels are `0, \ldots, Lnr-1` - - ``labels`` -- ``list`` (default: ``[]``); the list of edge labels + - ``labels`` -- list (default: ``[]``); the list of edge labels - - ``partition`` -- ``list`` (default: ``None``); a partition of the vertex + - ``partition`` -- list (default: ``None``); a partition of the vertex set - ``directed`` -- boolean (default: ``False``); whether the edges are @@ -389,7 +389,7 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True - ``G`` -- a Sage (Di)Graph - - ``partition`` -- ``list`` (default: ``None``); a partition of the vertices + - ``partition`` -- list (default: ``None``); a partition of the vertices of ``G`` into color classes - ``return_graph`` -- boolean (default: ``False``); whether to return the @@ -397,7 +397,7 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True - ``use_edge_labels`` -- boolean (default: ``True``); whether to consider edge labels. The edge labels are assumed to be hashable and - sortable. If this is not the case (ie a :class:`TypeError` is + sortable. If this is not the case (ie a :exc:`TypeError` is raised), the algorithm will consider the string representations of the labels instead of the labels. @@ -487,19 +487,19 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True Check that :issue:`32395` is fixed:: sage: g = Graph([[0, 2]]) # 1 is not a vertex! - sage: g.canonical_label(partition=[[0], [1], [2]], algorithm="bliss") # optional - bliss + sage: g.canonical_label(partition=[[0], [1], [2]], algorithm='bliss') # optional - bliss Traceback (most recent call last): ... ValueError: vertex 1 of the partition is not a vertex of the graph - sage: g.canonical_label(partition=[[0], [0, 2]], algorithm="bliss") # optional - bliss + sage: g.canonical_label(partition=[[0], [0, 2]], algorithm='bliss') # optional - bliss Traceback (most recent call last): ... ValueError: vertex 0 can appear only once in the partition - sage: g.canonical_label(partition=[[0, 0], [2]], algorithm="bliss") # optional - bliss + sage: g.canonical_label(partition=[[0, 0], [2]], algorithm='bliss') # optional - bliss Traceback (most recent call last): ... ValueError: vertex 0 can appear only once in the partition - sage: g.canonical_label(partition=[[0]], algorithm="bliss") # optional - bliss + sage: g.canonical_label(partition=[[0]], algorithm='bliss') # optional - bliss Traceback (most recent call last): ... ValueError: some vertices of the graph are not in the partition @@ -604,21 +604,21 @@ cdef automorphism_group_gens_from_edge_list(int Vnr, Vout, Vin, int Lnr=1, label INPUT: - - ``Vnr`` -- ``int``; number of vertices, such that the vertices are `0, + - ``Vnr`` -- integer; number of vertices, such that the vertices are `0, \ldots, Vnr-1` - - ``Vout`` -- ``list``; the list of vertices of outgoing edges + - ``Vout`` -- list; the list of vertices of outgoing edges - - ``Vin`` -- ``list``; the list of vertices of ingoing edges + - ``Vin`` -- list; the list of vertices of ingoing edges - - ``Lnr`` -- ``int`` (default: 1); number of labels, such that the labels + - ``Lnr`` -- integer (default: 1); number of labels, such that the labels are `0, \ldots, Lnr-1` - - ``labels`` -- ``list`` (default: ``[]``); the list of edge labels + - ``labels`` -- list (default: ``[]``); the list of edge labels - - ``int2vert`` -- ``list`` (default: ``[]``); ordering of the vertices + - ``int2vert`` -- list (default: ``[]``); ordering of the vertices - - ``partition`` -- ``list`` (default: ``None``); a partition of the vertex + - ``partition`` -- list (default: ``None``); a partition of the vertex set - ``directed`` -- boolean (default: ``False``); whether the edges are @@ -664,7 +664,7 @@ cpdef automorphism_group(G, partition=None, use_edge_labels=True) noexcept: - ``G`` -- a Sage graph - - ``partition`` -- ``list`` (default: ``None``); a partition of the vertices + - ``partition`` -- list (default: ``None``); a partition of the vertices of ``G`` into color classes. Defaults to ``None``, which is equivalent to a partition of size 1. @@ -855,9 +855,9 @@ cdef Graph *bliss_graph(G, partition, vert2int, int2vert) noexcept: - ``G`` -- a Sage Graph - - ``partition`` -- ``list``; a partition of the vertex set + - ``partition`` -- list; a partition of the vertex set - - ``vert2int, int2vert`` -- a empty ``dict`` and a empty ``list``; the + - ``vert2int, int2vert`` -- a empty ``dict`` and a empty list; the entries of the dictionary are later set to record the labeling of our graph. They are taken as arguments to avoid technicalities of returning Python objects in Cython functions. @@ -889,9 +889,9 @@ cdef Digraph *bliss_digraph(G, partition, vert2int, int2vert) noexcept: - ``G`` -- a Sage DiGraph - - ``partition`` -- ``list``; a partition of the vertex set + - ``partition`` -- list; a partition of the vertex set - - ``vert2int, int2vert`` -- a empty ``dict`` and a empty ``list``; the + - ``vert2int, int2vert`` -- a empty ``dict`` and a empty list; the entries of the dictionary are later set to record the labeling of our graph. They are taken as arguments to avoid technicalities of returning Python objects in Cython functions. diff --git a/src/sage/graphs/centrality.pyx b/src/sage/graphs/centrality.pyx index 1285dda406d..e249046ae70 100755 --- a/src/sage/graphs/centrality.pyx +++ b/src/sage/graphs/centrality.pyx @@ -38,7 +38,7 @@ cimport cython def centrality_betweenness(G, bint exact=False, bint normalize=True): r""" - Return the centrality betweenness of `G` + Return the centrality betweenness of `G`. The centrality betweenness of a vertex `v\in G` is defined by: @@ -54,7 +54,7 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True): - ``G`` -- a (di)graph - ``exact`` -- boolean (default: ``False``); whether to compute over - rationals or on ``double`` C variables. + rationals or on ``double`` C variables - ``normalize`` -- boolean (default: ``True``); whether to renormalize the values by dividing them by `\binom {n-1} 2` (for graphs) or `2\binom {n-1} @@ -115,7 +115,6 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True): {0: 0.0, 1: 0.0} sage: centrality_betweenness(Graph(2), exact=1) {0: 0, 1: 0} - """ if exact: return centrality_betweenness_C(G, 0, normalize=normalize) @@ -125,7 +124,7 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True): @cython.cdivision(True) cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): r""" - Return the centrality betweenness of G (C implementation) + Return the centrality betweenness of G (C implementation). INPUT: @@ -179,7 +178,7 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): mpq_init(mpq_tmp) try: - init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex, sort_neighbors=False) + init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex) init_reverse(bfs_dag, g) queue = check_allocarray(n, sizeof(uint32_t)) @@ -690,7 +689,7 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph cdef list V = list(G) - init_short_digraph(sd, G, edge_labelled=False, vertex_list=V, sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=V) cdef int n = sd.n cdef int* reachL = mem.malloc(n * sizeof(int)) cdef int* reachU @@ -852,9 +851,7 @@ def centrality_closeness_random_k(G, int k=1): - ``k`` -- integer (default: 1); number of random nodes to choose - OUTPUT: - - A dictionary associating to each vertex its estimated closeness centrality. + OUTPUT: a dictionary associating to each vertex its estimated closeness centrality EXAMPLES: @@ -887,7 +884,6 @@ def centrality_closeness_random_k(G, int k=1): Traceback (most recent call last): ... ValueError: G must be an undirected Graph - """ G._scream_if_not_simple() if G.is_directed(): @@ -943,7 +939,7 @@ def centrality_closeness_random_k(G, int k=1): # Copying the whole graph as a static_sparse_graph for fast shortest # paths computation in unweighted graph. This data structure is well # documented in module sage.graphs.base.static_sparse_graph - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) distance = mem.malloc(n * sizeof(uint32_t)) waiting_list = mem.malloc(n * sizeof(uint32_t)) bitset_init(seen, n) diff --git a/src/sage/graphs/chrompoly.pyx b/src/sage/graphs/chrompoly.pyx index 920a2b0eee0..17a9837041b 100644 --- a/src/sage/graphs/chrompoly.pyx +++ b/src/sage/graphs/chrompoly.pyx @@ -55,16 +55,16 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): - ``return_tree_basis`` -- boolean (default: ``False``); not used yet - - ``algorithm`` -- string (default: ``"C"``); the algorithm to use among + - ``algorithm`` -- string (default: ``'C'``); the algorithm to use among - - ``"C"``, an implementation in C by Robert Miller and Gordon Royle. + - ``'C'``, an implementation in C by Robert Miller and Gordon Royle. - - ``"Python"``, an implementation in Python using caching to avoid + - ``'Python'``, an implementation in Python using caching to avoid recomputing the chromatic polynomial of a graph that has already been seen. This seems faster on some dense graphs. - ``cache`` -- dictionary (default: ``None``); this parameter is used only - for algorithm ``"Python"``. It is a dictionary keyed by canonical + for algorithm ``'Python'``. It is a dictionary keyed by canonical labelings of graphs and used to cache the chromatic polynomials of the graphs generated by the algorithm. In other words, it avoids computing twice the chromatic polynomial of isometric graphs. One will be created @@ -114,7 +114,7 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): sage: min(i for i in range(11) if P(i) > 0) == G.chromatic_number() True - Check that algorithms ``"C"`` and ``"Python"`` return the same results:: + Check that algorithms ``'C'`` and ``'Python'`` return the same results:: sage: G = graphs.RandomGNP(8, randint(1, 9)*0.1) sage: c = G.chromatic_polynomial(algorithm='C') @@ -136,7 +136,7 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): Giving a wrong algorithm:: - sage: Graph().chromatic_polynomial(algorithm="foo") + sage: Graph().chromatic_polynomial(algorithm='foo') Traceback (most recent call last): ... ValueError: algorithm must be "C" or "Python" diff --git a/src/sage/graphs/cographs.py b/src/sage/graphs/cographs.py index b921375f643..a78e8a24376 100644 --- a/src/sage/graphs/cographs.py +++ b/src/sage/graphs/cographs.py @@ -7,7 +7,7 @@ more details on this graph class, and :oeis:`A000084` to know the number of cographs of order `n \geq 1`. -This module implements the folowing methods concerning cographs: +This module implements the following methods concerning cographs: .. csv-table:: :class: contentstable @@ -295,7 +295,7 @@ def cographs(n, as_graph=True, immutable=False): INPUT: - - ``n`` -- an integer larger or equal to 1 + - ``n`` -- integer larger or equal to 1 - ``as_graph`` -- boolean (default: ``True``); whether to return graphs or the tree data structure encoding the graph diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index b10ce489268..05d5d3b5185 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -15,12 +15,12 @@ The following methods are implemented in this module :widths: 30, 70 :delim: | - :meth:`~is_comparability_MILP` | Tests whether the graph is a comparability graph (MILP) - :meth:`~greedy_is_comparability` | Tests whether the graph is a comparability graph (greedy algorithm) - :meth:`~greedy_is_comparability_with_certificate` | Tests whether the graph is a comparability graph and returns certificates (greedy algorithm) - :meth:`~is_comparability` | Tests whether the graph is a comparability graph - :meth:`~is_permutation` | Tests whether the graph is a permutation graph. - :meth:`~is_transitive` | Tests whether the digraph is transitive. + :meth:`~is_comparability_MILP` | Test whether the graph is a comparability graph (MILP) + :meth:`~greedy_is_comparability` | Test whether the graph is a comparability graph (greedy algorithm) + :meth:`~greedy_is_comparability_with_certificate` | Test whether the graph is a comparability graph and returns certificates (greedy algorithm) + :meth:`~is_comparability` | Test whether the graph is a comparability graph + :meth:`~is_permutation` | Test whether the graph is a permutation graph. + :meth:`~is_transitive` | Test whether the digraph is transitive. Author: @@ -90,7 +90,7 @@ built is the following (see [ST1994]_): - `G` is a comparability graph - `\forall uv\in G, vu\not\in C^G_{uv}` - - The edges of `G` can be partitionned into `B_1,...,B_k` where `B_i` is the + - The edges of `G` can be partitioned into `B_1,...,B_k` where `B_i` is the equivalence class of some oriented edge in `G-B_1-\dots-B_{i-1}` Hence, ensuring that a graph is a comparability graph can be done by checking @@ -210,7 +210,7 @@ from copy import copy def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): r""" - Tests whether the graph is a comparability graph (greedy algorithm) + Test whether the graph is a comparability graph (greedy algorithm). This method only returns no-certificates. @@ -224,7 +224,7 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): each of which implies the next. It is set to ``False`` by default. - ``equivalence_class`` -- whether to return an equivalence class - if the graph is a comparability graph. + if the graph is a comparability graph OUTPUT: @@ -317,7 +317,7 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): def greedy_is_comparability_with_certificate(g, certificate=False): r""" - Tests whether the graph is a comparability graph and returns + Test whether the graph is a comparability graph and returns certificates(greedy algorithm). This method can return certificates of both *yes* and *no* answers. @@ -327,7 +327,7 @@ def greedy_is_comparability_with_certificate(g, certificate=False): INPUT: - - ``certificate`` (boolean) -- whether to return a + - ``certificate`` -- boolean; whether to return a certificate. *Yes*-answers the certificate is a transitive orientation of `G`, and a *no* certificates is an odd cycle of sequentially forcing edges. @@ -393,20 +393,20 @@ def greedy_is_comparability_with_certificate(g, certificate=False): def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): r""" - Tests whether the graph is a comparability graph (MILP) + Test whether the graph is a comparability graph (MILP). INPUT: - - ``certificate`` (boolean) -- whether to return a certificate for + - ``certificate`` -- boolean; whether to return a certificate for yes instances. This method cannot return negative certificates. - - ``solver`` -- (default: ``None``); Specify a Linear Program (LP) solver to + - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. EXAMPLES: @@ -491,39 +491,39 @@ def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): # Empty shell # ############### -def is_comparability(g, algorithm="greedy", certificate=False, check=True, +def is_comparability(g, algorithm='greedy', certificate=False, check=True, solver=None, verbose=0): r""" - Tests whether the graph is a comparability graph + Test whether the graph is a comparability graph. INPUT: - - ``algorithm`` -- choose the implementation used to do the test. + - ``algorithm`` -- choose the implementation used to do the test - - ``"greedy"`` -- a greedy algorithm (see the documentation of the - :mod:`comparability module `). + - ``'greedy'`` -- a greedy algorithm (see the documentation of the + :mod:`comparability module `) - - ``"MILP"`` -- a Mixed Integer Linear Program formulation of the + - ``'MILP'`` -- a Mixed Integer Linear Program formulation of the problem. Beware, for this implementation is unable to return negative certificates ! When ``certificate = True``, negative certificates are - always equal to ``None``. True certificates are valid, though. + always equal to ``None``. ``True`` certificates are valid, though. - - ``certificate`` (boolean) -- whether to return a + - ``certificate`` -- boolean; whether to return a certificate. *Yes*-answers the certificate is a transitive orientation of `G`, and a *no* certificates is an odd cycle of sequentially forcing edges. - - ``check`` (boolean) -- whether to check that the + - ``check`` -- boolean; whether to check that the yes-certificates are indeed transitive. As it is very quick compared to the rest of the operation, it is enabled by default. - - ``solver`` -- (default: ``None``); Specify a Linear Program (LP) solver to + - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. EXAMPLES:: @@ -575,10 +575,10 @@ def is_comparability(g, algorithm="greedy", certificate=False, check=True, return isit, certif -def is_permutation(g, algorithm="greedy", certificate=False, check=True, +def is_permutation(g, algorithm='greedy', certificate=False, check=True, solver=None, verbose=0): r""" - Tests whether the graph is a permutation graph. + Test whether the graph is a permutation graph. For more information on permutation graphs, refer to the documentation of the :mod:`comparability module `. @@ -586,32 +586,32 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, INPUT: - ``algorithm`` -- choose the implementation used for the subcalls to - :meth:`is_comparability`. + :meth:`is_comparability` - - ``"greedy"`` -- a greedy algorithm (see the documentation of the - :mod:`comparability module `). + - ``'greedy'`` -- a greedy algorithm (see the documentation of the + :mod:`comparability module `) - - ``"MILP"`` -- a Mixed Integer Linear Program formulation of the + - ``'MILP'`` -- a Mixed Integer Linear Program formulation of the problem. Beware, for this implementation is unable to return negative certificates ! When ``certificate = True``, negative certificates are - always equal to ``None``. True certificates are valid, though. + always equal to ``None``. ``True`` certificates are valid, though. - - ``certificate`` (boolean) -- whether to return a certificate for the + - ``certificate`` -- boolean; whether to return a certificate for the answer given. For ``True`` answers the certificate is a permutation, for ``False`` answers it is a no-certificate for the test of comparability or co-comparability. - - ``check`` (boolean) -- whether to check that the permutations returned + - ``check`` -- boolean; whether to check that the permutations returned indeed create the expected Permutation graph. Pretty cheap compared to the rest, hence a good investment. It is enabled by default. - - ``solver`` -- (default: ``None``); Specify a Linear Program (LP) solver to + - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. .. NOTE:: @@ -638,7 +638,7 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, sage: p1 = Permutation([nn+1 for nn in perm[0]]) sage: p2 = Permutation([nn+1 for nn in perm[1]]) sage: p = p2 * p1.inverse() - sage: p.show(representation="braid") # needs sage.plot + sage: p.show(representation='braid') # needs sage.plot TESTS: @@ -663,7 +663,7 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, sage: for i in range(20): # needs sage.numerical.mip ....: p = Permutations(10).random_element() ....: g1 = graphs.PermutationGraph(p) - ....: isit, certif = is_permutation(g1, algorithm="MILP", certificate=True) + ....: isit, certif = is_permutation(g1, algorithm='MILP', certificate=True) ....: if not isit: ....: print("Something is wrong here !!") ....: break @@ -671,7 +671,6 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, ....: if not g1.is_isomorphic(g2): ....: print("Something is wrong here !!") ....: break - """ if not certificate: # No certificate... A piece of cake @@ -714,14 +713,14 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, def is_transitive(g, certificate=False): r""" - Tests whether the digraph is transitive. + Test whether the digraph is transitive. A digraph is transitive if for any pair of vertices `u,v\in G` linked by a `uv`-path the edge `uv` belongs to `G`. INPUT: - - ``certificate`` -- whether to return a certificate for negative answers. + - ``certificate`` -- whether to return a certificate for negative answers - If ``certificate = False`` (default), this method returns ``True`` or ``False`` according to the graph. diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index ee387ab352b..05138c68f49 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -23,8 +23,10 @@ Here is what the module can do: :meth:`connected_components_sizes` | Return the sizes of the connected components as a list. :meth:`blocks_and_cut_vertices` | Return the blocks and cut vertices of the graph. :meth:`blocks_and_cuts_tree` | Return the blocks-and-cuts tree of the graph. - :meth:`is_cut_edge` | Return True if the input edge is a cut-edge or a bridge. + :meth:`is_cut_edge` | Check whether the input edge is a cut-edge or a bridge. + :meth:`is_edge_cut` | Check whether the input edges form an edge cut. :meth:`is_cut_vertex` | Check whether the input vertex is a cut-vertex. + :meth:`is_vertex_cut` | Check whether the input vertices form a vertex cut. :meth:`edge_connectivity` | Return the edge connectivity of the graph. :meth:`vertex_connectivity` | Return the vertex connectivity of the graph. @@ -48,7 +50,7 @@ Here is what the module can do: :widths: 30, 70 :delim: | - :meth:`bridges` | Returns an iterator over the bridges (or cut edges) of given undirected graph. + :meth:`bridges` | Return an iterator over the bridges (or cut edges) of given undirected graph. :meth:`cleave` | Return the connected subgraphs separated by the input vertex cut. :meth:`is_triconnected` | Check whether the graph is triconnected. :meth:`spqr_tree` | Return a SPQR-tree representing the triconnected components of the graph. @@ -70,6 +72,7 @@ Methods # **************************************************************************** from sage.misc.superseded import deprecation +from sage.sets.disjoint_set cimport DisjointSet def is_connected(G): @@ -416,7 +419,7 @@ def connected_components_sizes(G): return [len(cc) for cc in connected_components(G, sort=False)] -def blocks_and_cut_vertices(G, algorithm="Tarjan_Boost", sort=False, key=None): +def blocks_and_cut_vertices(G, algorithm='Tarjan_Boost', sort=False, key=None): """ Return the blocks and cut vertices of the graph. @@ -430,17 +433,17 @@ def blocks_and_cut_vertices(G, algorithm="Tarjan_Boost", sort=False, key=None): INPUT: - - ``algorithm`` -- string (default: ``"Tarjan_Boost"``); the algorithm to + - ``algorithm`` -- string (default: ``'Tarjan_Boost'``); the algorithm to use among: - - ``"Tarjan_Boost"`` (default) -- Tarjan's algorithm (Boost + - ``'Tarjan_Boost'`` -- default; Tarjan's algorithm (Boost implementation) - - ``"Tarjan_Sage"`` -- Tarjan's algorithm (Sage implementation) + - ``'Tarjan_Sage'`` -- Tarjan's algorithm (Sage implementation) - ``sort`` -- boolean (default: ``False``); whether to sort vertices inside the components and the list of cut vertices - **currently only available for ``"Tarjan_Sage"``** + **currently only available for ``'Tarjan_Sage'``** - ``key`` -- a function (default: ``None``); a function that takes a vertex as its one argument and returns a value that can be used for @@ -473,10 +476,10 @@ def blocks_and_cut_vertices(G, algorithm="Tarjan_Boost", sort=False, key=None): ([[0, 1, 4, 2, 3], [0, 6, 9, 7, 8]], [0]) sage: rings.blocks_and_cut_vertices() ([[0, 1, 4, 2, 3], [0, 6, 9, 7, 8]], [0]) - sage: B, C = blocks_and_cut_vertices(rings, algorithm="Tarjan_Sage", sort=True) + sage: B, C = blocks_and_cut_vertices(rings, algorithm='Tarjan_Sage', sort=True) sage: B, C ([[0, 1, 2, 3, 4], [0, 6, 7, 8, 9]], [0]) - sage: B2, C2 = blocks_and_cut_vertices(rings, algorithm="Tarjan_Sage", sort=False) + sage: B2, C2 = blocks_and_cut_vertices(rings, algorithm='Tarjan_Sage', sort=False) sage: Set(map(Set, B)) == Set(map(Set, B2)) and set(C) == set(C2) True @@ -502,7 +505,7 @@ def blocks_and_cut_vertices(G, algorithm="Tarjan_Boost", sort=False, key=None): sage: rings = graphs.CycleGraph(10) sage: rings.merge_vertices([0, 5]) sage: rings = rings.to_directed() - sage: blocks_and_cut_vertices(rings, algorithm="Tarjan_Boost") + sage: blocks_and_cut_vertices(rings, algorithm='Tarjan_Boost') ([[0, 1, 4, 2, 3], [0, 6, 9, 7, 8]], [0]) TESTS:: @@ -732,13 +735,160 @@ def blocks_and_cuts_tree(G): return g +def is_edge_cut(G, edges): + """ + Check whether ``edges`` form an edge cut. + + A set of edges is an edge cut of a graph if its removal increases the number + of connected components. In a digraph, we consider the number of (weakly) + connected components. + + This method is not working for (di)graphs with multiple edges. Furthermore, + edge labels are ignored. + + INPUT: + + - ``G`` -- a (di)graph + + - ``edges`` -- a set of edges + + EXAMPLES: + + A cycle graph of order 4:: + + sage: from sage.graphs.connectivity import is_edge_cut + sage: G = graphs.CycleGraph(4) + sage: is_edge_cut(G, [(1, 2)]) + False + sage: is_edge_cut(G, [(1, 2), (2, 3)]) + True + sage: is_edge_cut(G, [(1, 2), (3, 0)]) + True + + A pending edge is a cut-edge:: + + sage: G.add_edge((0, 5, 'silly')) + sage: is_edge_cut(G, [(0, 5, 'silly')]) + True + + Edge labels are ignored, even if specified:: + + sage: G.add_edge((2, 5, 'xyz')) + sage: is_edge_cut(G, [(0, 5), (2, 5)]) + True + sage: is_edge_cut(G, [(0, 5), (2, 5, 'xyz')]) + True + sage: is_edge_cut(G, [(0, 5, 'silly'), (2, 5)]) + True + sage: is_edge_cut(G, [(0, 5, 'aa'), (2, 5, 'bb')]) + True + + The graph can have loops:: + + sage: G.allow_loops(True) + sage: G.add_edge(0, 0) + sage: is_edge_cut(G, [(0, 5), (2, 5)]) + True + sage: is_edge_cut(G, [(0, 0), (0, 5), (2, 5)]) + True + + Multiple edges are not allowed:: + + sage: G.allow_multiple_edges(True) + sage: is_edge_cut(G, [(0, 5), (2, 5)]) + Traceback (most recent call last): + ... + ValueError: This method is not known to work on graphs with + multiedges. Perhaps this method can be updated to handle them, but in + the meantime if you want to use it please disallow multiedges using + allow_multiple_edges(). + + An error is raised if an element of ``edges`` is not an edge of `G`:: + + sage: G = graphs.CycleGraph(4) + sage: is_edge_cut(G, [(0, 2)]) + Traceback (most recent call last): + ... + ValueError: edge (0, 2) is not an edge of the graph + + For digraphs, this method considers the number of (weakly) connected + components:: + + sage: G = digraphs.Circuit(4) + sage: is_edge_cut(G, [(0, 1)]) + False + sage: G = digraphs.Circuit(4) + sage: is_edge_cut(G, [(0, 1), (1, 2)]) + True + + For disconnected (di)graphs, the method checks if the number of (weakly) + connected components increases:: + + sage: G = graphs.CycleGraph(4) * 2 + sage: is_edge_cut(G, [(1, 2), (2, 3)]) + True + sage: G = digraphs.Circuit(4) * 2 + sage: is_edge_cut(G, [(0, 1), (1, 2)]) + True + """ + G._scream_if_not_simple(allow_loops=True) + + cdef set C = set() # set of edges of the potential cut + cdef set S = set() # set of incident vertices + for e in edges: + u, v = e[0], e[1] + if not G.has_edge(u, v): + raise ValueError("edge {0} is not an edge of the graph".format(repr(e))) + if u == v: + # We ignore loops + continue + if G.degree(u) == 1 or G.degree(v) == 1: + # e is a pending edge and so a cut-edge + return True + S.add(u) + S.add(v) + C.add((u, v)) + if not G.is_directed(): + C.add((v, u)) + + cdef list queue + cdef set seen + DS = DisjointSet(G) + + for comp in G.connected_components(): + if not S.intersection(comp): + # This component is not involved in the cut + continue + + # We run a DFS in comp from any vertex and avoid edges in C + start = comp[0] + queue = [start] + seen = set(queue) + while queue: + v = queue.pop() + for e in G.edge_iterator(vertices=[v], labels=False, ignore_direction=True, sort_vertices=False): + if e in C: + continue + w = e[1] if e[0] == v else e[0] + if w not in seen: + seen.add(w) + DS.union(v, w) + queue.append(w) + + # We now check if some vertices of comp have not been reached + if len(set(DS.find(v) for v in comp)) > 1: + return True + + return False + + def is_cut_edge(G, u, v=None, label=None): """ - Returns True if the input edge is a cut-edge or a bridge. + Check whether the edge ``(u, v)`` is a cut-edge or a bridge of graph ``G``. A cut edge (or bridge) is an edge that when removed increases - the number of connected components. This function works with - simple graphs as well as graphs with loops and multiedges. In + the number of connected components. This function works with + simple graphs as well as graphs with loops and multiedges. In a digraph, a cut edge is an edge that when removed increases the number of (weakly) connected components. @@ -754,7 +904,7 @@ def is_cut_edge(G, u, v=None, label=None): OUTPUT: - - Returns True if (u,v) is a cut edge, False otherwise + - Returns ``True`` if (u,v) is a cut edge, False otherwise EXAMPLES:: @@ -787,20 +937,7 @@ def is_cut_edge(G, u, v=None, label=None): Traceback (most recent call last): ... ValueError: edge not in graph - - TESTS: - - If ``G`` is not a Sage graph, an error is raised:: - - sage: is_cut_edge('I am not a graph',0) - Traceback (most recent call last): - ... - TypeError: the input must be a Sage graph """ - from sage.graphs.generic_graph import GenericGraph - if not isinstance(G, GenericGraph): - raise TypeError("the input must be a Sage graph") - if label is None: if v is None: try: @@ -835,58 +972,64 @@ def is_cut_edge(G, u, v=None, label=None): return sol -def is_cut_vertex(G, u, weak=False): +def is_vertex_cut(G, cut, weak=False): r""" - Check whether the input vertex is a cut-vertex. + Check whether the input vertices form a vertex cut. - A vertex is a cut-vertex if its removal from the (di)graph increases the - number of (strongly) connected components. Isolated vertices or leafs are - not cut-vertices. This function works with simple graphs as well as graphs - with loops and multiple edges. + A set of vertices is a vertex cut if its removal from the (di)graph + increases the number of (strongly) connected components. This function works + with simple graphs as well as graphs with loops and multiple edges. INPUT: - ``G`` -- a Sage (Di)Graph - - ``u`` -- a vertex + - ``cut`` -- a set of vertices - ``weak`` -- boolean (default: ``False``); whether the connectivity of directed graphs is to be taken in the weak sense, that is ignoring edges orientations - OUTPUT: - - Return ``True`` if ``u`` is a cut-vertex, and ``False`` otherwise. - EXAMPLES: - Giving a LollipopGraph(4,2), that is a complete graph with 4 vertices with a - pending edge:: + Giving a cycle graph of order 4:: - sage: from sage.graphs.connectivity import is_cut_vertex - sage: G = graphs.LollipopGraph(4, 2) - sage: is_cut_vertex(G, 0) + sage: from sage.graphs.connectivity import is_vertex_cut + sage: G = graphs.CycleGraph(4) + sage: is_vertex_cut(G, [0, 1]) False - sage: is_cut_vertex(G, 3) + sage: is_vertex_cut(G, [0, 2]) True - sage: G.is_cut_vertex(3) + + Giving a disconnected graph:: + + sage: from sage.graphs.connectivity import is_vertex_cut + sage: G = graphs.CycleGraph(4) * 2 + sage: G.connected_components() + [[0, 1, 2, 3], [4, 5, 6, 7]] + sage: is_vertex_cut(G, [0, 2]) + True + sage: is_vertex_cut(G, [4, 6]) + True + sage: is_vertex_cut(G, [0, 6]) + False + sage: is_vertex_cut(G, [0, 4, 6]) True Comparing the weak and strong connectivity of a digraph:: - sage: from sage.graphs.connectivity import is_strongly_connected sage: D = digraphs.Circuit(6) - sage: is_strongly_connected(D) + sage: D.is_strongly_connected() True - sage: is_cut_vertex(D, 2) + sage: is_vertex_cut(D, [2]) True - sage: is_cut_vertex(D, 2, weak=True) + sage: is_vertex_cut(D, [2], weak=True) False Giving a vertex that is not in the graph:: sage: G = graphs.CompleteGraph(4) - sage: is_cut_vertex(G, 7) + sage: is_vertex_cut(G, [7]) Traceback (most recent call last): ... ValueError: vertex (7) is not a vertex of the graph @@ -895,7 +1038,7 @@ def is_cut_vertex(G, u, weak=False): If ``G`` is not a Sage graph, an error is raised:: - sage: is_cut_vertex('I am not a graph', 0) + sage: is_vertex_cut('I am not a graph', [0]) Traceback (most recent call last): ... TypeError: the input must be a Sage graph @@ -904,68 +1047,144 @@ def is_cut_vertex(G, u, weak=False): if not isinstance(G, GenericGraph): raise TypeError("the input must be a Sage graph") - if u not in G: - raise ValueError("vertex ({0}) is not a vertex of the graph".format(repr(u))) + cdef set cutset = set(cut) + for u in cutset: + if u not in G: + raise ValueError("vertex ({0}) is not a vertex of the graph".format(repr(u))) - # Initialization - cdef set CC - cdef list neighbors_func - if not G.is_directed() or weak: - # Weak connectivity - - if G.degree(u) < 2: - # An isolated or a leaf vertex is not a cut vertex - return False - - neighbors_func = [G.neighbor_iterator] - start = next(G.neighbor_iterator(u)) - CC = set(G) + if len(cutset) >= G.order() - 1: + # A vertex cut must be of size at most n - 2 + return False + # We deal with graphs with multiple (strongly) connected components + cdef list CC + if G.is_directed() and not weak: + CC = G.strongly_connected_components() else: - # Strong connectivity for digraphs - - if not G.out_degree(u) or not G.in_degree(u): - # A vertex without in or out neighbors is not a cut vertex - return False + CC = G.connected_components(sort=False) + if len(CC) > 1: + for comp in CC: + subcut = cutset.intersection(comp) + if subcut and is_vertex_cut(G.subgraph(comp), subcut, weak=weak): + return True + return False - # We consider only the strongly connected component containing u - CC = set(strongly_connected_component_containing_vertex(G, u)) + cdef list boundary = G.vertex_boundary(cutset) + if not boundary: + # We need at least 1 vertex in the boundary of the cut + return False - # We perform two DFS starting from an out neighbor of u and avoiding - # u. The first DFS follows the edges directions, and the second is - # in the reverse order. If both allow to reach all neighbors of u, - # then u is not a cut vertex - neighbors_func = [G.neighbor_out_iterator, G.neighbor_in_iterator] - start = next(G.neighbor_out_iterator(u)) + cdef list cases = [(G.neighbor_iterator, boundary)] + if not weak and G.is_directed(): + # Strong connectivity for digraphs. + # We perform two DFS starting from an out neighbor of cut and avoiding + # cut. The first DFS follows the edges directions, and the second is + # in the reverse order. If both allow to reach all neighbors of cut, + # then it is not a vertex cut. + # We set data for the reverse order + in_boundary = set() + for u in cutset: + in_boundary.update(G.neighbor_in_iterator(u)) + in_boundary.difference_update(cutset) + if not in_boundary: + return False + cases.append((G.neighbor_in_iterator, list(in_boundary))) - CC.discard(u) - CC.discard(start) cdef list queue cdef set seen cdef set targets + start = boundary[0] - for neighbors in neighbors_func: + for neighbors, this_boundary in cases: - # We perform a DFS starting from a neighbor of u and avoiding u + # We perform a DFS starting from start and avoiding cut queue = [start] - seen = set(queue) - targets = CC.intersection(G.neighbor_iterator(u)) + seen = set(cutset) + seen.add(start) + targets = set(this_boundary) targets.discard(start) - while queue and targets: + while queue: v = queue.pop() for w in neighbors(v): - if w not in seen and w in CC: + if w not in seen: seen.add(w) queue.append(w) targets.discard(w) - # If some neighbors cannot be reached, u is a cut vertex. + # If some neighbors cannot be reached, we have a vertex cut if targets: return True return False +def is_cut_vertex(G, u, weak=False): + r""" + Check whether the input vertex is a cut-vertex. + + A vertex is a cut-vertex if its removal from the (di)graph increases the + number of (strongly) connected components. Isolated vertices or leaves are + not cut-vertices. This function works with simple graphs as well as graphs + with loops and multiple edges. + + INPUT: + + - ``G`` -- a Sage (Di)Graph + + - ``u`` -- a vertex + + - ``weak`` -- boolean (default: ``False``); whether the connectivity of + directed graphs is to be taken in the weak sense, that is ignoring edges + orientations + + OUTPUT: + + Return ``True`` if ``u`` is a cut-vertex, and ``False`` otherwise. + + EXAMPLES: + + Giving a LollipopGraph(4,2), that is a complete graph with 4 vertices with a + pending edge:: + + sage: from sage.graphs.connectivity import is_cut_vertex + sage: G = graphs.LollipopGraph(4, 2) + sage: is_cut_vertex(G, 0) + False + sage: is_cut_vertex(G, 3) + True + sage: G.is_cut_vertex(3) + True + + Comparing the weak and strong connectivity of a digraph:: + + sage: D = digraphs.Circuit(6) + sage: D.is_strongly_connected() + True + sage: is_cut_vertex(D, 2) + True + sage: is_cut_vertex(D, 2, weak=True) + False + + Giving a vertex that is not in the graph:: + + sage: G = graphs.CompleteGraph(4) + sage: is_cut_vertex(G, 7) + Traceback (most recent call last): + ... + ValueError: vertex (7) is not a vertex of the graph + + TESTS: + + If ``G`` is not a Sage graph, an error is raised:: + + sage: is_cut_vertex('I am not a graph', 0) + Traceback (most recent call last): + ... + TypeError: the input must be a Sage graph + """ + return is_vertex_cut(G, [u], weak=weak) + + def edge_connectivity(G, value_only=True, implementation=None, @@ -1002,14 +1221,14 @@ def edge_connectivity(G, - ``implementation`` -- string (default: ``None``); selects an implementation: - - ``None`` (default) -- selects the best implementation available + - ``None`` -- default; selects the best implementation available - - ``"boost"`` -- use the Boost graph library (which is much more + - ``'boost'`` -- use the Boost graph library (which is much more efficient). It is not available when ``edge_labels=True``, and it is unreliable for directed graphs (see :issue:`18753`). - -``"Sage"`` -- use Sage's implementation based on integer linear - programming + - ``'Sage'`` -- use Sage's implementation based on integer linear + programming - ``use_edge_labels`` -- boolean (default: ``False``) @@ -1024,7 +1243,7 @@ def edge_connectivity(G, - When set to ``True``, also returns the two sets of vertices that are disconnected by the cut. Implies ``value_only=False``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1032,7 +1251,7 @@ def edge_connectivity(G, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -1091,26 +1310,26 @@ def edge_connectivity(G, It is the case for graphs which are not connected :: sage: g = 2 * graphs.PetersenGraph() - sage: edge_connectivity(g, implementation="sage") + sage: edge_connectivity(g, implementation='sage') 0.0 For directed graphs, the strong connectivity is tested through the dedicated function:: sage: g = digraphs.ButterflyGraph(3) - sage: edge_connectivity(g, implementation="sage") + sage: edge_connectivity(g, implementation='sage') 0.0 We check that the result with Boost is the same as the result without Boost:: sage: g = graphs.RandomGNP(15, .3) - sage: (edge_connectivity(g, implementation="boost") # needs sage.numerical.mip - ....: == edge_connectivity(g, implementation="sage")) + sage: (edge_connectivity(g, implementation='boost') # needs sage.numerical.mip + ....: == edge_connectivity(g, implementation='sage')) True Boost interface also works with directed graphs:: - sage: edge_connectivity(digraphs.Circuit(10), implementation="boost", + sage: edge_connectivity(digraphs.Circuit(10), implementation='boost', ....: vertices=True) [1, [(0, 1)], [{0}, {1, 2, 3, 4, 5, 6, 7, 8, 9}]] @@ -1120,12 +1339,12 @@ def edge_connectivity(G, sage: g = digraphs.Path(3) sage: edge_connectivity(g) 0.0 - sage: edge_connectivity(g, implementation="boost") + sage: edge_connectivity(g, implementation='boost') 1 sage: g.add_edge(1, 0) sage: edge_connectivity(g) 0.0 - sage: edge_connectivity(g, implementation="boost") + sage: edge_connectivity(g, implementation='boost') 0 TESTS: @@ -1134,8 +1353,8 @@ def edge_connectivity(G, sage: for i in range(10): # needs sage.numerical.mip ....: g = graphs.RandomGNP(30, 0.3) - ....: e1 = edge_connectivity(g, implementation="boost") - ....: e2 = edge_connectivity(g, implementation="sage") + ....: e1 = edge_connectivity(g, implementation='boost') + ....: e2 = edge_connectivity(g, implementation='sage') ....: assert (e1 == e2) Disconnected graphs and ``vertices=True``:: @@ -1342,7 +1561,7 @@ def vertex_connectivity(G, value_only=True, sets=False, k=None, solver=None, ver connectivity of the (di)graph is larger or equal to `k`. The method thus outputs a boolean only. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1350,7 +1569,7 @@ def vertex_connectivity(G, value_only=True, sets=False, k=None, solver=None, ver :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -1472,6 +1691,16 @@ def vertex_connectivity(G, value_only=True, sets=False, k=None, solver=None, ver sage: G.add_edge(0, 1) sage: G.vertex_connectivity(value_only=False, verbose=1) # needs sage.numerical.mip (3, []) + + Check that :issue:`38723` is fixed:: + + sage: G = graphs.SierpinskiGasketGraph(3) + sage: G.vertex_connectivity(k=1) # needs sage.numerical.mip + True + sage: G.vertex_connectivity(k=2) # needs sage.numerical.mip + True + sage: G.vertex_connectivity(k=3) # needs sage.numerical.mip + False """ from sage.graphs.generic_graph import GenericGraph if not isinstance(G, GenericGraph): @@ -1486,8 +1715,8 @@ def vertex_connectivity(G, value_only=True, sets=False, k=None, solver=None, ver # We follow the convention of is_connected, is_biconnected and # is_strongly_connected return k == 1 - if (g.is_directed() and k > min(min(g.in_degree()), min(g.out_degree()))) \ - or (not g.is_directed() and (k > min(g.degree()))): + if ((g.is_directed() and k > min(min(g.in_degree()), min(g.out_degree()))) + or (not g.is_directed() and (k > min(g.degree())))): return False value_only = True sets = False @@ -1519,7 +1748,7 @@ def vertex_connectivity(G, value_only=True, sets=False, k=None, solver=None, ver return 1 if k is None else (k == 1) if not G.is_triconnected(): - return 2 if k is None else (k == 2) + return 2 if k is None else (k <= 2) elif k == 3: return True @@ -1637,7 +1866,7 @@ def is_strongly_connected(G): def strongly_connected_components_digraph(G, keep_labels=False): r""" - Return the digraph of the strongly connected components + Return the digraph of the strongly connected components. The digraph of the strongly connected components of a graph `G` has a vertex per strongly connected component included in `G`. There is an edge from a @@ -1778,7 +2007,7 @@ def strongly_connected_components_subgraphs(G): def strongly_connected_component_containing_vertex(G, v): """ - Return the strongly connected component containing a given vertex + Return the strongly connected component containing a given vertex. INPUT: @@ -1820,7 +2049,6 @@ def strongly_connected_component_containing_vertex(G, v): Traceback (most recent call last): ... ValueError: vertex ('z') is not a vertex of the DiGraph - """ from sage.graphs.digraph import DiGraph if not isinstance(G, DiGraph): @@ -1848,7 +2076,7 @@ def strong_articulation_points(G): algorithm described in [ILS2012]_. The time complexity is dominated by the time complexity of the immediate dominators finding algorithm. - OUTPUT: The list of strong articulation points. + OUTPUT: the list of strong articulation points EXAMPLES: @@ -2075,7 +2303,7 @@ def cleave(G, cut_vertices=None, virtual_edges=True, solver=None, verbose=0, INPUT: - - ``G`` -- a Graph. + - ``G`` -- a Graph - ``cut_vertices`` -- iterable container of vertices (default: ``None``); a set of vertices representing a vertex cut of ``G``. If no vertex cut is @@ -2086,7 +2314,7 @@ def cleave(G, cut_vertices=None, virtual_edges=True, solver=None, verbose=0, edges to the sides of the cut or not. A virtual edge is an edge between a pair of vertices of the cut that are not connected by an edge in ``G``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -2094,14 +2322,14 @@ def cleave(G, cut_vertices=None, virtual_edges=True, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers over an inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. - OUTPUT: A triple `(S, C, f)`, where + OUTPUT: a triple `(S, C, f)`, where - `S` is a list of the graphs that are sides of the vertex cut. @@ -2263,7 +2491,7 @@ def cleave(G, cut_vertices=None, virtual_edges=True, solver=None, verbose=0, return cut_sides, cocycles, virtual_cut_graph -def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, +def spqr_tree(G, algorithm='Hopcroft_Tarjan', solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" Return an SPQR-tree representing the triconnected components of the graph. @@ -2273,17 +2501,17 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, them. A node of a SPQR-tree, and the graph associated with it, can be one of the following four types: - - ``"S"`` -- the associated graph is a cycle with at least three vertices. - ``"S"`` stands for ``series``. + - ``'S'`` -- the associated graph is a cycle with at least three vertices + ``'S'`` stands for ``series`` - - ``"P"`` -- the associated graph is a dipole graph, a multigraph with two - vertices and three or more edges. ``"P"`` stands for ``parallel``. + - ``'P'`` -- the associated graph is a dipole graph, a multigraph with two + vertices and three or more edges. ``'P'`` stands for ``parallel`` - - ``"Q"`` -- the associated graph has a single real edge. This trivial case - is necessary to handle the graph that has only one edge. + - ``'Q'`` -- the associated graph has a single real edge. This trivial case + is necessary to handle the graph that has only one edge - - ``"R"`` -- the associated graph is a 3-connected graph that is not a cycle - or dipole. ``"R"`` stands for ``rigid``. + - ``'R'`` -- the associated graph is a 3-connected graph that is not a cycle + or dipole. ``'R'`` stands for ``rigid`` This method decomposes a biconnected graph into cycles, cocycles, and 3-connected blocks summed over cocycles, and arranges them as a SPQR-tree. @@ -2297,17 +2525,17 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, - ``G`` -- the input graph - - ``algorithm`` -- string (default: ``"Hopcroft_Tarjan"``); the algorithm to + - ``algorithm`` -- string (default: ``'Hopcroft_Tarjan'``); the algorithm to use among: - - ``"Hopcroft_Tarjan"`` (default) -- use the algorithm proposed by + - ``'Hopcroft_Tarjan'`` -- default; use the algorithm proposed by Hopcroft and Tarjan in [Hopcroft1973]_ and later corrected by Gutwenger and Mutzel in [Gut2001]_. See :class:`~sage.graphs.connectivity.TriconnectivitySPQR`. - - ``"cleave"`` -- using method :meth:`~sage.graphs.connectivity.cleave` + - ``'cleave'`` -- using method :meth:`~sage.graphs.connectivity.cleave` - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -2315,7 +2543,7 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -2377,7 +2605,7 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, True sage: G = Graph('LlCG{O@?GBoMw?') - sage: T = spqr_tree(G, algorithm="Hopcroft_Tarjan") + sage: T = spqr_tree(G, algorithm='Hopcroft_Tarjan') sage: G.is_isomorphic(spqr_tree_to_graph(T)) True sage: T2 = spqr_tree(G, algorithm='cleave') # needs sage.numerical.mip @@ -2399,26 +2627,26 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, sage: from collections import Counter sage: G = graphs.PetersenGraph() - sage: T = G.spqr_tree(algorithm="Hopcroft_Tarjan") + sage: T = G.spqr_tree(algorithm='Hopcroft_Tarjan') sage: Counter(u[0] for u in T) Counter({'R': 1}) - sage: T = G.spqr_tree(algorithm="cleave") # needs sage.numerical.mip + sage: T = G.spqr_tree(algorithm='cleave') # needs sage.numerical.mip sage: Counter(u[0] for u in T) # needs sage.numerical.mip Counter({'R': 1}) sage: for u,v in list(G.edges(labels=False, sort=False)): ....: G.add_path([u, G.add_vertex(), G.add_vertex(), v]) - sage: T = G.spqr_tree(algorithm="Hopcroft_Tarjan") + sage: T = G.spqr_tree(algorithm='Hopcroft_Tarjan') sage: sorted(Counter(u[0] for u in T).items()) [('P', 15), ('R', 1), ('S', 15)] - sage: T = G.spqr_tree(algorithm="cleave") # needs sage.numerical.mip + sage: T = G.spqr_tree(algorithm='cleave') # needs sage.numerical.mip sage: sorted(Counter(u[0] for u in T).items()) # needs sage.numerical.mip [('P', 15), ('R', 1), ('S', 15)] sage: for u,v in list(G.edges(labels=False, sort=False)): ....: G.add_path([u, G.add_vertex(), G.add_vertex(), v]) - sage: T = G.spqr_tree(algorithm="Hopcroft_Tarjan") + sage: T = G.spqr_tree(algorithm='Hopcroft_Tarjan') sage: sorted(Counter(u[0] for u in T).items()) [('P', 60), ('R', 1), ('S', 75)] - sage: T = G.spqr_tree(algorithm="cleave") # long time # needs sage.numerical.mip + sage: T = G.spqr_tree(algorithm='cleave') # long time # needs sage.numerical.mip sage: sorted(Counter(u[0] for u in T).items()) # long time # needs sage.numerical.mip [('P', 60), ('R', 1), ('S', 75)] @@ -2436,7 +2664,7 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0, ... ValueError: graph is not biconnected - sage: spqr_tree(Graph(), algorithm="easy") + sage: spqr_tree(Graph(), algorithm='easy') Traceback (most recent call last): ... NotImplementedError: SPQR tree algorithm 'easy' is not implemented @@ -2605,7 +2833,7 @@ def spqr_tree_to_graph(T): INPUT: - - ``T`` -- a SPQR tree as returned by :meth:`spqr_tree`. + - ``T`` -- a SPQR tree as returned by :meth:`spqr_tree` OUTPUT: a (multi) graph @@ -2635,22 +2863,51 @@ def spqr_tree_to_graph(T): sage: H.is_isomorphic(G) True - TESTS:: + TESTS: + + Check that the method is working for the empty SPQR tree:: sage: H = spqr_tree_to_graph(Graph()) sage: H.is_isomorphic(Graph()) True + + Check that :issue:`38527` is fixed:: + + sage: from sage.graphs.connectivity import spqr_tree, spqr_tree_to_graph + sage: G = Graph('LlCG{O@?GBoMw?') + sage: T1 = spqr_tree(G, algorithm="Hopcroft_Tarjan") + sage: T2 = spqr_tree(G, algorithm="cleave") + sage: T1.is_isomorphic(T2) + True + sage: G1 = spqr_tree_to_graph(T1) + sage: G2 = spqr_tree_to_graph(T2) + sage: G.is_isomorphic(G1) + True + sage: G.is_isomorphic(G2) + True """ from sage.graphs.graph import Graph from collections import Counter count_G = Counter() count_P = Counter() + vertex_to_int = dict() for t, g in T: + for u in g: + if u not in vertex_to_int: + vertex_to_int[u] = len(vertex_to_int) if t in ['P', 'Q']: - count_P.update(g.edge_iterator()) + for u, v, label in g.edge_iterator(): + if vertex_to_int[u] < vertex_to_int[v]: + count_P[u, v, label] += 1 + else: + count_P[v, u, label] += 1 else: - count_G.update(g.edge_iterator()) + for u, v, label in g.edge_iterator(): + if vertex_to_int[u] < vertex_to_int[v]: + count_G[u, v, label] += 1 + else: + count_G[v, u, label] += 1 G = Graph(multiedges=True) for e, num in count_G.items(): @@ -2770,7 +3027,7 @@ cdef _LinkedList_concatenate(_LinkedList * lst1, _LinkedList * lst2): cdef str _LinkedList_to_string(_LinkedList * ll): """ - Return a string representation of self. + Return a string representation of ``self``. """ cdef _LinkedListNode * temp = ll.head cdef list s = [] @@ -2788,9 +3045,9 @@ cdef class _Component: This class is used to store a connected component. It contains: - ``edge_list`` -- list of edges belonging to the component, - stored as a :class:`_LinkedList`. + stored as a :class:`_LinkedList` - - ``component_type`` -- the type of the component. + - ``component_type`` -- the type of the component - 0 if bond. - 1 if polygon. @@ -2802,9 +3059,9 @@ cdef class _Component: INPUT: - - ``edge_list`` -- list of edges to be added to the component. + - ``edge_list`` -- list of edges to be added to the component - - `type_c` -- type of the component (0, 1, or 2). + - ``type_c`` -- type of the component (0, 1, or 2) TESTS:: @@ -2899,18 +3156,18 @@ cdef class TriconnectivitySPQR: them. A node of a SPQR-tree, and the graph associated with it, can be one of the following four types: - - ``"S"`` -- the associated graph is a cycle with at least three vertices. - ``"S"`` stands for ``series`` and is also called a ``polygon``. + - ``'S'`` -- the associated graph is a cycle with at least three vertices + ``'S'`` stands for ``series`` and is also called a ``polygon`` - - ``"P"`` -- the associated graph is a dipole graph, a multigraph with two - vertices and three or more edges. ``"P"`` stands for ``parallel`` and the + - ``'P'`` -- the associated graph is a dipole graph, a multigraph with two + vertices and three or more edges. ``'P'`` stands for ``parallel`` and the node is called a ``bond``. - - ``"Q"`` -- the associated graph has a single real edge. This trivial case + - ``'Q'`` -- the associated graph has a single real edge. This trivial case is necessary to handle the graph that has only one edge. - - ``"R"`` -- the associated graph is a 3-vertex-connected graph that is not - a cycle or dipole. ``"R"`` stands for ``rigid``. + - ``'R'`` -- the associated graph is a 3-vertex-connected graph that is not + a cycle or dipole. ``'R'`` stands for ``rigid``. The edges of the tree indicate the 2-vertex cuts of the graph. @@ -4227,17 +4484,17 @@ cdef class TriconnectivitySPQR: separating them. A node of a SPQR-tree, and the graph associated with it, can be one of the following four types: - - ``"S"`` -- the associated graph is a cycle with at least three vertices. - ``"S"`` stands for ``series``. + - ``'S'`` -- the associated graph is a cycle with at least three vertices. + ``'S'`` stands for ``series``. - - ``"P"`` -- the associated graph is a dipole graph, a multigraph with - two vertices and three or more edges. ``"P"`` stands for ``parallel``. + - ``'P'`` -- the associated graph is a dipole graph, a multigraph with + two vertices and three or more edges. ``'P'`` stands for ``parallel``. - - ``"Q"`` -- the associated graph has a single real edge. This trivial + - ``'Q'`` -- the associated graph has a single real edge. This trivial case is necessary to handle the graph that has only one edge. - - ``"R"`` -- the associated graph is a 3-connected graph that is not a - cycle or dipole. ``"R"`` stands for ``rigid``. + - ``'R'`` -- the associated graph is a 3-connected graph that is not a + cycle or dipole. ``'R'`` stands for ``rigid``. The edges of the tree indicate the 2-vertex cuts of the graph. diff --git a/src/sage/graphs/convexity_properties.pyx b/src/sage/graphs/convexity_properties.pyx index c8a321ece81..f292cae3eed 100644 --- a/src/sage/graphs/convexity_properties.pyx +++ b/src/sage/graphs/convexity_properties.pyx @@ -117,7 +117,7 @@ cdef class ConvexityProperties: elements `z` with `d_{G}(u,w) + d_{G}(w,v) = d_{G}(u,v)`. This is not in general equal to `h(\{u,v\})` ! - Nothing says these recommandations will actually lead to any actual + Nothing says these recommendations will actually lead to any actual improvements. There are just some ideas remembered while writing this code. Trying to optimize may well lead to lost in efficiency on many instances. @@ -142,7 +142,7 @@ cdef class ConvexityProperties: def __init__(self, G): r""" - Constructor + Constructor. EXAMPLES:: @@ -215,7 +215,7 @@ cdef class ConvexityProperties: def __dealloc__(self): r""" - Destructor + Destructor. EXAMPLES:: @@ -223,13 +223,12 @@ cdef class ConvexityProperties: sage: g = graphs.PetersenGraph() sage: ConvexityProperties(g) - """ binary_matrix_free(self._cache_hull_pairs) cdef list _vertices_to_integers(self, vertices): r""" - Converts a list of vertices to a list of integers with the cached data. + Convert a list of vertices to a list of integers with the cached data. """ return [self._dict_vertices_to_integers[v] for v in vertices] @@ -296,7 +295,7 @@ cdef class ConvexityProperties: INPUT: - * ``vertices`` -- A list of vertices. + - ``vertices`` -- list of vertices EXAMPLES:: @@ -352,11 +351,11 @@ cdef class ConvexityProperties: INPUT: - * ``value_only`` -- boolean (default: ``True``); whether to return only + - ``value_only`` -- boolean (default: ``True``); whether to return only the hull number (default) or a minimum set whose convex hull is the whole graph - * ``verbose`` -- boolean (default: ``False``); whether to display + - ``verbose`` -- boolean (default: ``False``); whether to display information on the LP **COMPLEXITY:** @@ -507,11 +506,9 @@ def geodetic_closure(G, S): each vertex `u \in S`, the algorithm first performs a breadth first search from `u` to get distances, and then identifies the vertices of `G` lying on a shortest path from `u` to any `v\in S` using a reversal traversal from - vertices in `S`. This algorithm has time complexity in - `O(|S|(n + m) + (n + m\log{m}))` for ``SparseGraph``, - `O(|S|(n + m) + n^2\log{m})` for ``DenseGraph`` and space complexity in - `O(n + m)` (the extra `\log` factor is due to ``init_short_digraph`` being - called with ``sort_neighbors=True``). + vertices in `S`. This algorithm has time complexity in `O(|S|(n + m))` for + ``SparseGraph``, `O(|S|(n + m) + n^2)` for ``DenseGraph`` and + space complexity in `O(n + m)`. INPUT: @@ -758,7 +755,7 @@ def is_geodetic(G): # Copy the graph as a short digraph cdef int n = G.order() cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G), sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G)) # Allocate some data structures cdef MemoryAllocator mem = MemoryAllocator() diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index 1b650b73a1b..54fa7ed4eb3 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -262,7 +262,7 @@ class DiGraph(GenericGraph): `__ digraph, or `igraph `__ digraph. - - ``pos`` -- dict (default: ``None``); a positioning dictionary. For + - ``pos`` -- dictionary (default: ``None``); a positioning dictionary. For example, the spring layout from NetworkX for the 5-cycle is:: {0: [-0.91679746, 0.88169588], @@ -272,7 +272,7 @@ class DiGraph(GenericGraph): 4: [-1.125 ,-0.50118505]} - ``name`` -- string (default: ``None``); gives the graph a name (e.g., - name="complete") + name='complete') - ``loops`` -- boolean (default: ``None``); whether to allow loops (ignored if data is an instance of the DiGraph class) @@ -286,24 +286,24 @@ class DiGraph(GenericGraph): - ``format`` -- string (default: ``None``); if set to ``None``, :class:`DiGraph` tries to guess input's format. To avoid this possibly time-consuming step, one of the following values can be specified (see - description above): ``"int"``, ``"dig6"``, ``"rule"``, - ``"list_of_edges"``, ``"dict_of_lists"``, ``"dict_of_dicts"``, - ``"adjacency_matrix"``, ``"weighted_adjacency_matrix"``, - ``"incidence_matrix"``, ``"NX"``, ``"igraph"``. + description above): ``'int'``, ``'dig6'``, ``'rule'``, + ``'list_of_edges'``, ``'dict_of_lists'``, ``'dict_of_dicts'``, + ``'adjacency_matrix'``, ``'weighted_adjacency_matrix'``, + ``'incidence_matrix'``, ``"NX"``, ``'igraph'``. - ``sparse`` -- boolean (default: ``True``); ``sparse=True`` is an alias for ``data_structure="sparse"``, and ``sparse=False`` is an alias for ``data_structure="dense"`` - - ``data_structure`` -- string (default: ``"sparse"``); one of the following + - ``data_structure`` -- string (default: ``'sparse'``); one of the following (for more information, see :mod:`~sage.graphs.base.overview`): - * ``"dense"`` -- selects the :mod:`~sage.graphs.base.dense_graph` backend + * ``'dense'`` -- selects the :mod:`~sage.graphs.base.dense_graph` backend - * ``"sparse"`` -- selects the :mod:`~sage.graphs.base.sparse_graph` + * ``'sparse'`` -- selects the :mod:`~sage.graphs.base.sparse_graph` backend - * ``"static_sparse"`` -- selects the + * ``'static_sparse'`` -- selects the :mod:`~sage.graphs.base.static_sparse_backend` (this backend is faster than the sparse backend and smaller in memory, and it is immutable, so that the resulting graphs can be used as dictionary keys). @@ -482,8 +482,8 @@ class DiGraph(GenericGraph): sage: import networkx sage: g = networkx.DiGraph({0:[1,2,3], 2:[4]}) sage: G = DiGraph(g) - sage: G_imm = DiGraph(G, data_structure="static_sparse") - sage: H_imm = DiGraph(G, data_structure="static_sparse") + sage: G_imm = DiGraph(G, data_structure='static_sparse') + sage: H_imm = DiGraph(G, data_structure='static_sparse') sage: H_imm is G_imm False sage: H_imm == G_imm == G @@ -521,7 +521,7 @@ class DiGraph(GenericGraph): _directed = True def __init__(self, data=None, pos=None, loops=None, format=None, - weighted=None, data_structure="sparse", + weighted=None, data_structure='sparse', vertex_labels=True, name=None, multiedges=None, convert_empty_dict_labels_to_None=None, sparse=True, immutable=False, hash_labels=None): @@ -581,7 +581,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, ....: 3:{5:4},4:{5:1,6:5},5:{4:1,6:7,5:1}} sage: grafo3 = DiGraph(B, weighted=True) sage: matad = grafo3.weighted_adjacency_matrix() # needs sage.modules - sage: grafo4 = DiGraph(matad, format="adjacency_matrix", weighted=True) # needs sage.modules + sage: grafo4 = DiGraph(matad, format='adjacency_matrix', weighted=True) # needs sage.modules sage: grafo4.shortest_path(0, 6, by_weight=True) # needs sage.modules [0, 1, 2, 5, 4, 6] @@ -613,7 +613,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, Unknown input format:: - sage: DiGraph(4, format="HeyHeyHey") + sage: DiGraph(4, format='HeyHeyHey') Traceback (most recent call last): ... ValueError: unknown input format 'HeyHeyHey' @@ -873,7 +873,7 @@ def dig6_string(self): r""" Return the ``dig6`` representation of the digraph as an ASCII string. - This is only valid for single (no multiple edges) digraphs on at most + This is only valid for simple (no multiple edges) digraphs on at most `2^{18} - 1 = 262143` vertices. .. NOTE:: @@ -893,6 +893,9 @@ def dig6_string(self): sage: D = DiGraph({0: [1, 2], 1: [2], 2: [3], 3: [0]}) sage: D.dig6_string() 'CW`_' + sage: L = DiGraph({0: [1, 2], 1: [2], 2: [3], 3: [3]}) + sage: L.dig6_string() + 'CW`C' TESTS:: @@ -937,7 +940,7 @@ def is_directed_acyclic(self, certificate=False): OUTPUT: - * When ``certificate=False``, returns a boolean value. + * When ``certificate=False``, returns a boolean value * When ``certificate=True``: @@ -1025,13 +1028,13 @@ def to_undirected(self, data_structure=None, sparse=None): INPUT: - - ``data_structure`` -- string (default: ``None``); one of - ``"sparse"``, ``"static_sparse"``, or ``"dense"``. See the - documentation of :class:`Graph` or :class:`DiGraph`. + - ``data_structure`` -- string (default: ``None``); one of + ``'sparse'``, ``'static_sparse'``, or ``'dense'``. See the + documentation of :class:`Graph` or :class:`DiGraph`. - - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an - alias for ``data_structure="sparse"``, and ``sparse=False`` is an - alias for ``data_structure="dense"``. + - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an + alias for ``data_structure="sparse"``, and ``sparse=False`` is an + alias for ``data_structure="dense"``. EXAMPLES:: @@ -1057,7 +1060,6 @@ def to_undirected(self, data_structure=None, sparse=None): {0: 'foo', 1: None, 2: None} sage: G.get_vertices() {0: 'foo', 1: None, 2: None} - """ if sparse is not None: if data_structure is not None: @@ -1132,7 +1134,7 @@ def incoming_edges(self, vertices, labels=True): - ``vertices`` -- a vertex or a list of vertices - ``labels`` -- boolean (default: ``True``); whether to return edges as - pairs of vertices, or as triples containing the labels. + pairs of vertices, or as triples containing the labels EXAMPLES:: @@ -1151,7 +1153,7 @@ def outgoing_edge_iterator(self, vertices, labels=True): - ``vertices`` -- a vertex or a list of vertices - ``labels`` -- boolean (default: ``True``); whether to return edges as - pairs of vertices, or as triples containing the labels. + pairs of vertices, or as triples containing the labels EXAMPLES:: @@ -1179,7 +1181,7 @@ def outgoing_edges(self, vertices, labels=True): - ``vertices`` -- a vertex or a list of vertices - ``labels`` -- boolean (default: ``True``); whether to return edges as - pairs of vertices, or as triples containing the labels. + pairs of vertices, or as triples containing the labels EXAMPLES:: @@ -1316,7 +1318,7 @@ def in_degree(self, vertices=None, labels=False): if vertices in self: return self._backend.in_degree(vertices) elif labels: - return {v: d for v, d in self.in_degree_iterator(vertices, labels=labels)} + return dict(self.in_degree_iterator(vertices, labels=labels)) return list(self.in_degree_iterator(vertices, labels=labels)) def in_degree_iterator(self, vertices=None, labels=False): @@ -1386,7 +1388,7 @@ def out_degree(self, vertices=None, labels=False): if vertices in self: return self._backend.out_degree(vertices) elif labels: - return {v: d for v, d in self.out_degree_iterator(vertices, labels=labels)} + return dict(self.out_degree_iterator(vertices, labels=labels)) return list(self.out_degree_iterator(vertices, labels=labels)) def out_degree_iterator(self, vertices=None, labels=False): @@ -1443,9 +1445,7 @@ def sources(self): r""" Return a list of sources of the digraph. - OUTPUT: - - - list of the vertices of the digraph that have no edges going into them + OUTPUT: list of the vertices of the digraph that have no edges going into them EXAMPLES:: @@ -1462,9 +1462,7 @@ def sinks(self): """ Return a list of sinks of the digraph. - OUTPUT: - - - list of the vertices of the digraph that have no edges beginning at them + OUTPUT: list of the vertices of the digraph that have no edges beginning at them EXAMPLES:: @@ -1539,7 +1537,7 @@ def feedback_edge_set(self, constraint_generation=True, value_only=False, use constraint generation when solving the Mixed Integer Linear Program. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1547,7 +1545,7 @@ def feedback_edge_set(self, constraint_generation=True, value_only=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -1909,7 +1907,7 @@ def reverse_edge(self, u, v=None, label=None, inplace=True, multiedges=None): EXAMPLES: - If ``inplace`` is ``True`` (default value), ``self`` is modified:: + If ``inplace`` is ``True`` (default), ``self`` is modified:: sage: D = DiGraph([(0, 1 ,2)]) sage: D.reverse_edge(0, 1) @@ -2096,11 +2094,11 @@ def reverse_edges(self, edges, inplace=True, multiedges=None): INPUT: - - ``edges`` -- a list of edges in the DiGraph. + - ``edges`` -- list of edges in the DiGraph - ``inplace`` -- boolean (default: ``True``); if ``False``, a new digraph is created and returned as output, otherwise ``self`` is - modified. + modified - ``multiedges`` -- boolean (default: ``None``); if ``True``, input graph will be forced to allow parallel edges when necessary (for more @@ -2108,11 +2106,11 @@ def reverse_edges(self, edges, inplace=True, multiedges=None): .. SEEALSO:: - :meth:`~DiGraph.reverse_edge` -- Reverses a single edge. + :meth:`~DiGraph.reverse_edge` -- reverses a single edge EXAMPLES: - If ``inplace`` is ``True`` (default value), ``self`` is modified:: + If ``inplace`` is ``True`` (default), ``self`` is modified:: sage: D = DiGraph({ 0: [1, 1, 3], 2: [3, 3], 4: [1, 5]}, multiedges=true) sage: D.reverse_edges([[0, 1], [0, 3]]) @@ -2214,16 +2212,16 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, INPUT: - ``v`` -- either a single vertex or a list of vertices. If it is not - specified, then it is taken to be all vertices. + specified, then it is taken to be all vertices - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); one of the following algorithms: - ``'BFS'`` -- the computation is done through a BFS centered on each - vertex successively. Works only if ``by_weight==False``. + vertex successively. Works only if ``by_weight==False`` - ``'Floyd-Warshall-Cython'`` -- a Cython implementation of the Floyd-Warshall algorithm. Works only if ``by_weight==False`` and @@ -2239,7 +2237,7 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, allowed. - ``'Dijkstra_Boost'`` -- the Dijkstra algorithm, implemented in Boost - (works only with positive weights). + (works only with positive weights) - ``'Johnson_Boost'`` -- the Johnson algorithm, implemented in Boost (works also with negative weights, if there is no negative @@ -2247,7 +2245,7 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, vertices of ``self``. - ``'From_Dictionary'`` -- uses the (already computed) distances, that - are provided by input variable ``dist_dict``. + are provided by input variable ``dist_dict`` - ``None`` (default): Sage chooses the best algorithm: ``'From_Dictionary'`` if ``dist_dict`` is not None, ``'BFS'`` for @@ -2263,11 +2261,11 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check that the ``weight_function`` outputs a number for each edge - - ``dist_dict`` -- a dictionary (default: ``None``); a dict of dicts of + - ``dist_dict`` -- dictionary (default: ``None``); a dict of dicts of distances (used only if ``algorithm=='From_Dictionary'``) - ``with_labels`` -- boolean (default: ``False``); whether to return a - list or a dictionary keyed by vertices. + list or a dictionary keyed by vertices EXAMPLES:: @@ -2429,7 +2427,7 @@ def radius(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); see method :meth:`eccentricity` for the list of available algorithms @@ -2498,7 +2496,7 @@ def diameter(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); one of the following algorithms: @@ -2668,7 +2666,7 @@ def center(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); see method :meth:`eccentricity` for the list of available algorithms @@ -2739,7 +2737,7 @@ def periphery(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); see method :meth:`eccentricity` for the list of available algorithms @@ -2813,20 +2811,18 @@ def _all_cycles_iterator_vertex(self, vertex, starting_vertices=None, simple=Fal (e.g. ``['a', 'b', 'c', 'a']`` and ``['b', 'c', 'a', 'b']``). Otherwise, all cycles are enumerated. - - ``max_length`` -- non negative integer (default: ``None``); the + - ``max_length`` -- nonnegative integer (default: ``None``); the maximum length of the enumerated paths. If set to ``None``, then all lengths are allowed. - ``trivial`` -- boolean (default: ``False``); if set to ``True``, then - the empty paths are also enumerated. + the empty paths are also enumerated - ``remove_acyclic_edges`` -- boolean (default: ``True``); whether acyclic edges must be removed from the graph. Used to avoid recomputing it for each vertex - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -2933,16 +2929,14 @@ def all_cycles_iterator(self, starting_vertices=None, simple=False, (e.g. ``['a', 'b', 'c', 'a']`` and ``['b', 'c', 'a', 'b']``). Otherwise, all cycles are enumerated. - - ``max_length`` -- non negative integer (default: ``None``); the + - ``max_length`` -- nonnegative integer (default: ``None``); the maximum length of the enumerated paths. If set to ``None``, then all lengths are allowed. - ``trivial`` -- boolean (default: ``False``); if set to ``True``, then - the empty paths are also enumerated. + the empty paths are also enumerated - OUTPUT: - - iterator + OUTPUT: iterator .. SEEALSO:: @@ -3080,16 +3074,14 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, (e.g. ``['a', 'b', 'c', 'a']`` and ``['b', 'c', 'a', 'b']``). Otherwise, all cycles are enumerated. - - ``max_length`` -- non negative integer (default: ``None``); the + - ``max_length`` -- nonnegative integer (default: ``None``); the maximum length of the enumerated paths. If set to ``None``, then all lengths are allowed. - ``trivial`` -- boolean (default: ``False``); if set to ``True``, then - the empty paths are also enumerated. - - OUTPUT: + the empty paths are also enumerated - list + OUTPUT: list .. NOTE:: @@ -3220,7 +3212,6 @@ def path_semigroup(self): Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices sage: list(F) # needs sage.libs.flint [e_1, e_2, e_3, a, c, b, a*b, c*b] - """ from sage.quivers.path_semigroup import PathSemigroup return PathSemigroup(self) @@ -3244,11 +3235,11 @@ def auslander_reiten_quiver(self): # Directed Acyclic Graphs (DAGs) - def topological_sort(self, implementation="default"): + def topological_sort(self, implementation='default'): """ Return a topological sort of the digraph if it is acyclic. - If the digraph contains a directed cycle, a :class:`TypeError` + If the digraph contains a directed cycle, a :exc:`TypeError` is raised. As topological sorts are not necessarily unique, different implementations may yield different results. @@ -3259,15 +3250,15 @@ def topological_sort(self, implementation="default"): INPUT: - - ``implementation`` -- string (default: ``"default"``); either use the + - ``implementation`` -- string (default: ``'default'``); either use the default Cython implementation, or the default NetworkX library (``implementation = "NetworkX"``) .. SEEALSO:: - - :meth:`is_directed_acyclic` -- Tests whether a directed graph is - acyclic (can also join a certificate -- a topological sort or a - circuit in the graph). + - :meth:`is_directed_acyclic` -- tests whether a directed graph is + acyclic (can also join a certificate; a topological sort or a + circuit in the graph) EXAMPLES:: @@ -3330,7 +3321,7 @@ def topological_sort_generator(self): Return an iterator over all topological sorts of the digraph if it is acyclic. - If the digraph contains a directed cycle, a :class:`TypeError` + If the digraph contains a directed cycle, a :exc:`TypeError` is raised. A topological sort is an ordering of the vertices of the digraph such @@ -3371,7 +3362,7 @@ def topological_sort_generator(self): # Visualization - def layout_acyclic(self, rankdir="up", **options): + def layout_acyclic(self, rankdir='up', **options): """ Return a ranked layout so that all edges point upward. @@ -3420,7 +3411,6 @@ def layout_acyclic(self, rankdir="up", **options): sage: pos = H.layout_acyclic(rankdir='left') sage: pos[1][0] < pos[0][0] - .5 True - """ if have_dot2tex(): return self.layout_graphviz(rankdir=rankdir, **options) @@ -3501,9 +3491,7 @@ def level_sets(self): r""" Return the level set decomposition of the digraph. - OUTPUT: - - - a list of non empty lists of vertices of this graph + OUTPUT: list of non empty lists of vertices of this graph The level set decomposition of the digraph is a list `l` such that the level `l[i]` contains all the vertices having all their predecessors in @@ -3710,7 +3698,7 @@ def flow_polytope(self, edges=None, ends=None, backend=None): ``(1, 3, None)``, then ``(1, 3)`` will not do! - ``ends`` -- (default: ``(self.sources(), self.sinks())``) a - pair `(S, T)` of an iterable `S` and an iterable `T`. + pair `(S, T)` of an iterable `S` and an iterable `T` - ``backend`` -- string or ``None`` (default); the backend to use; see :meth:`sage.geometry.polyhedron.constructor.Polyhedron` @@ -3989,20 +3977,18 @@ def out_branchings(self, source, spanning=True): contains all vertices of the digraph. If no spanning out branching rooted at ``source`` exist, raises - ValueError or return non spanning out branching rooted at ``source``, - depending on the value of ``spanning``. + :exc:`ValueError` or return non spanning out branching rooted at + ``source``, depending on the value of ``spanning``. INPUT: - - ``source`` -- vertex used as the source for all out branchings. + - ``source`` -- vertex used as the source for all out branchings - ``spanning`` -- boolean (default: ``True``); if ``False`` return maximum out branching from ``source``. Otherwise, return spanning out branching if exists. - OUTPUT: - - An iterator over the out branchings rooted in the given source. + OUTPUT: an iterator over the out branchings rooted in the given source .. SEEALSO:: @@ -4100,7 +4086,7 @@ def _rec_out_branchings(depth): This function makes use of the following to keep track of partial out branchings: - - ``list_edges`` -- list of edges in self. + - ``list_edges`` -- list of edges in self - ``list_merged_edges`` -- list of edges that are currently merged - ``graph`` -- a copy of self where edges have an appropriate label """ @@ -4163,7 +4149,7 @@ def _rec_out_branchings(depth): def _singleton_out_branching(): r""" - Returns a DiGraph containing only ``source`` and no edges. + Return a DiGraph containing only ``source`` and no edges. """ D = DiGraph() D.add_vertex(source) @@ -4207,20 +4193,18 @@ def in_branchings(self, source, spanning=True): contains all vertices of the digraph. If no spanning in branching rooted at ``source`` exist, raises - ValueError or return non spanning in branching rooted at ``source``, - depending on the value of ``spanning``. + :exc:`ValueError` or return non spanning in branching rooted at + ``source``, depending on the value of ``spanning``. INPUT: - - ``source`` -- vertex used as the source for all in branchings. + - ``source`` -- vertex used as the source for all in branchings - ``spanning`` -- boolean (default: ``True``); if ``False`` return maximum in branching to ``source``. Otherwise, return spanning in branching if exists. - OUTPUT: - - An iterator over the in branchings rooted in the given source. + OUTPUT: an iterator over the in branchings rooted in the given source .. SEEALSO:: @@ -4318,7 +4302,7 @@ def _rec_in_branchings(depth): This function makes use of the following to keep track of partial in branchings: - - ``list_edges`` -- list of edges in self. + - ``list_edges`` -- list of edges in self - ``list_merged_edges`` -- list of edges that are currently merged - ``graph`` -- a copy of self where edges have an appropriate label """ @@ -4381,7 +4365,7 @@ def _rec_in_branchings(depth): def _singleton_in_branching(): r""" - Returns a DiGraph containing only ``source`` and no edges. + Return a DiGraph containing only ``source`` and no edges. """ D = DiGraph() D.add_vertex(source) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index 7ae9fe248fa..b374392163e 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -28,6 +28,7 @@ :meth:`~DiGraphGenerators.ImaseItoh` | Return the digraph of Imase and Itoh of order `n` and degree `d`. :meth:`~DiGraphGenerators.Kautz` | Return the Kautz digraph of degree `d` and diameter `D`. :meth:`~DiGraphGenerators.nauty_directg` | Return an iterator yielding digraphs using nauty's ``directg`` program. + :meth:`~DiGraphGenerators.nauty_posetg` | Return an iterator yielding Hasse diagrams of posets using nauty's ``genposetg`` program. :meth:`~DiGraphGenerators.Paley` | Return a Paley digraph on `q` vertices. :meth:`~DiGraphGenerators.Path` | Return a directed path on `n` vertices. :meth:`~DiGraphGenerators.RandomDirectedAcyclicGraph` | Return a random (weighted) directed acyclic graph of order `n`. @@ -48,6 +49,7 @@ - Emily A. Kirkman (2006) - Michael C. Yurko (2009) - David Coudert (2012) +- Janmenjaya Panda (2024) Functions and methods --------------------- @@ -57,6 +59,7 @@ # and Emily A. Kirkman # Copyright (C) 2009 Michael C. Yurko # Copyright (C) 2012 David Coudert +# Copyright (C) 2024 Janmenjaya Panda # # 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 @@ -118,7 +121,7 @@ class DiGraphGenerators: INPUT: - ``vertices`` -- natural number or ``None`` to infinitely generate bigger - and bigger digraphs. + and bigger digraphs - ``property`` -- any property to be tested on digraphs before generation @@ -214,7 +217,7 @@ def ButterflyGraph(self, n, vertices='strings'): INPUT: - - ``n`` -- a non negative integer; the dimension of the butterfly graph + - ``n`` -- nonnegative integer; the dimension of the butterfly graph - ``vertices`` -- string (default: ``'strings'``); specifies whether the vertices are zero-one strings (default) or tuples over GF(2) @@ -340,7 +343,7 @@ def Path(self, n): sage: g.automorphism_group().cardinality() # needs sage.groups 1 """ - g = DiGraph(n, name="Path") + g = DiGraph(n, name='Path') if n: g.add_path(list(range(n))) @@ -357,7 +360,7 @@ def StronglyRegular(self, n): INPUT: - - ``n`` -- integer, the number of vertices of the digraph. + - ``n`` -- integer; the number of vertices of the digraph .. SEEALSO:: @@ -385,7 +388,6 @@ def StronglyRegular(self, n): Traceback (most recent call last): ... ValueError: strongly regular digraph with 73 vertices not yet implemented - """ from sage.combinat.matrices.hadamard_matrix import skew_hadamard_matrix from sage.matrix.constructor import ones_matrix, identity_matrix @@ -559,14 +561,14 @@ def tournaments_nauty(self, n, ``None`` (default), then the min/max out-degree is not constrained - ``debug`` -- boolean (default: ``False``); if ``True`` the first line - of genbg's output to standard error is captured and the first call to - the generator's ``next()`` function will return this line as a string. - A line leading with ">A" indicates a successful initiation of the - program with some information on the arguments, while a line beginning - with ">E" indicates an error with the input. + of gentourng's output to standard error is captured and the first call + to the generator's ``next()`` function will return this line as a + string. A line leading with ">A" indicates a successful initiation of + the program with some information on the arguments, while a line + beginning with ">E" indicates an error with the input. - ``options`` -- string; anything else that should be forwarded as input - to Nauty's genbg. See its documentation for more information : + to Nauty's gentourng. See its documentation for more information : ``_. EXAMPLES:: @@ -635,7 +637,7 @@ def tournaments_nauty(self, n, yield G - def nauty_directg(self, graphs, options="", debug=False): + def nauty_directg(self, graphs, options='', debug=False): r""" Return an iterator yielding digraphs using nauty's ``directg`` program. @@ -651,7 +653,7 @@ def nauty_directg(self, graphs, options="", debug=False): :class:`Graph`. The graph6 string of these graphs is used as an input for ``directg``. - - ``options`` -- a string passed to ``directg`` as if it was run at + - ``options`` -- string passed to ``directg`` as if it was run at a system command line. Available options from ``directg --help``:: -e | -e: specify a value or range of the total number of arcs @@ -665,7 +667,7 @@ def nauty_directg(self, graphs, options="", debug=False): parts. Splitting is done per input graph independently. - ``debug`` -- boolean (default: ``False``); if ``True`` ``directg`` - standard error and standard output are displayed. + standard error and standard output are displayed EXAMPLES:: @@ -677,7 +679,7 @@ def nauty_directg(self, graphs, options="", debug=False): Digraph on 3 vertices sage: dgs[0]._bit_vector() '001001000' - sage: len(list(digraphs.nauty_directg(graphs.PetersenGraph(), options="-o"))) + sage: len(list(digraphs.nauty_directg(graphs.PetersenGraph(), options='-o'))) 324 Generate non-isomorphic acyclic orientations:: @@ -701,7 +703,7 @@ def nauty_directg(self, graphs, options="", debug=False): ... ValueError: directg output options [-u|-T|-G] are not allowed sage: next(digraphs.nauty_directg(graphs.nauty_geng("-c 3"), - ....: options="-o", debug=True)) + ....: options='-o', debug=True)) &BH? &BGO &B?o @@ -759,6 +761,63 @@ def nauty_directg(self, graphs, options="", debug=False): if line and line[0] == '&': yield DiGraph(line[1:], format='dig6') + def nauty_posetg(self, options='', debug=False): + r""" + Return a generator which creates all posets using ``nauty``. + + Here a poset is seen through its Hasse diagram, which is + an acyclic and transitively reduced digraph. + + INPUT: + + - ``options`` -- string (default: ``""``); a string passed to + ``genposetg`` as if it was run at a system command line. + At a minimum, you *must* pass the number of vertices you desire + and a choice between ``o`` and ``t`` for the output order. + + - ``debug`` -- boolean (default: ``False``); if ``True`` the first line + of ``genposetg``'s output to standard error is captured and the first + call to the generator's ``next()`` function will return this line as a + string. A line leading with ">A" indicates a successful initiation of + the program with some information on the arguments, while a line + beginning with ">E" indicates an error with the input. + + The possible options, obtained as output of ``genposetg --help``:: + + n: the number of vertices, between 0 and 16 + o: digraph6 output in arbitrary order + t: digraph6 output in topological order + + EXAMPLES:: + + sage: gen = digraphs.nauty_posetg("5 o") + sage: len(list(gen)) + 63 + + This coincides with :oeis:`A000112`. + """ + import shlex + from sage.features.nauty import NautyExecutable + geng_path = NautyExecutable("genposetg").absolute_filename() + sp = subprocess.Popen(shlex.quote(geng_path) + f" {options}", shell=True, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, close_fds=True, + encoding='latin-1') + msg = sp.stderr.readline() + if debug: + yield msg + elif msg.startswith('>E'): + raise ValueError('wrong format of parameter option') + gen = sp.stdout + while True: + try: + s = next(gen) + except StopIteration: + # Exhausted list of graphs from nauty genposetg + return + G = DiGraph(s[1:-1], format='dig6') + yield G + def Complete(self, n, loops=False): r""" Return the complete digraph on `n` vertices. @@ -818,7 +877,7 @@ def Circuit(self, n): sage: len(circuit.strongly_connected_components()) == 1 True """ - g = DiGraph(n, name="Circuit") + g = DiGraph(n, name='Circuit') if n == 1: g.allow_loops(True) @@ -834,6 +893,9 @@ def Circulant(self, n, integers): r""" Return a circulant digraph on `n` vertices from a set of integers. + A circulant digraph of order `n` has an arc from vertex `i` to + vertex `i+j \pmod{n}`, for each `j` in ``integers``. + INPUT: - ``n`` -- integer; number of vertices @@ -842,18 +904,30 @@ def Circulant(self, n, integers): that there is an edge from `i` to `j` if and only if `(j-i) \pmod{n}` is an integer - EXAMPLES:: + EXAMPLES: - sage: digraphs.Circulant(13,[3,5,7]) - Circulant graph ([3, 5, 7]): Digraph on 13 vertices + Construct and show the circulant graph [3, 5, 7], a digraph on 13 + vertices:: - TESTS:: + sage: g = digraphs.Circulant(13, [3, 5, 7]) + sage: g.show() # long time # needs sage.plot + + The Koh-Tindell digraph [LM2024]_ is the circulant digraph of order 7 + with parameters `[1, 5]`. This `2`-diregular digraph is + vertex-transitive but not arc-transitive. The associated bipartite + digraph of the Koh-Tindell digraph is a Pfaffian orientation of the + Heawood graph. Construct and show the Koh-Tindell digraph:: - sage: digraphs.Circulant(13,[3,5,7,"hey"]) + sage: kohTindellDigraph = digraphs.Circulant(7, [1, 5]) + sage: kohTindellDigraph.show() # long time # needs sage.plot + + TESTS: + + sage: digraphs.Circulant(13, [3, 5, 7, "hey"]) Traceback (most recent call last): ... ValueError: the list must contain only integers - sage: digraphs.Circulant(3,[3,5,7,3.4]) + sage: digraphs.Circulant(3, [3, 5, 7, 3.4]) Traceback (most recent call last): ... ValueError: the list must contain only integers @@ -897,7 +971,7 @@ def DeBruijn(self, k, n, vertices='strings'): of the resulting digraph is the cardinality of the set of letters. - ``n`` -- integer; length of words in the De Bruijn digraph when - ``vertices == 'strings'``, and also the diameter of the digraph. + ``vertices == 'strings'``, and also the diameter of the digraph - ``vertices`` -- string (default: ``'strings'``); whether the vertices are words over an alphabet (default) or integers @@ -1150,7 +1224,6 @@ def Kautz(self, k, D, vertices='strings'): are words over an alphabet (default) or integers (``vertices='strings'``) - EXAMPLES:: sage: # needs sage.combinat @@ -1234,7 +1307,7 @@ def Kautz(self, k, D, vertices='strings'): raise ValueError("degree must be greater than or equal to one") # We start building the set of vertices - V = [i for i in my_alphabet] + V = list(my_alphabet) for i in range(D - 1): VV = [] for w in V: @@ -1278,7 +1351,7 @@ def RandomDirectedAcyclicGraph(self, n, p, weight_max=None): - ``p`` -- probability of an edge - - ``weight_max`` -- (default: ``None``); by default, the returned DAG is + - ``weight_max`` -- (default: ``None``) by default, the returned DAG is unweighted. When ``weight_max`` is set to a positive integer, edges are assigned a random integer weight between ``1`` and ``weight_max``. @@ -1488,7 +1561,9 @@ def RandomDirectedGNM(self, n, m, loops=False): sage: D.num_verts() 10 sage: D.loops() - [(0, 0, None), (1, 1, None), (2, 2, None), (3, 3, None), (4, 4, None), (5, 5, None), (6, 6, None), (7, 7, None), (8, 8, None), (9, 9, None)] + [(0, 0, None), (1, 1, None), (2, 2, None), (3, 3, None), + (4, 4, None), (5, 5, None), (6, 6, None), (7, 7, None), + (8, 8, None), (9, 9, None)] TESTS:: @@ -1582,7 +1657,7 @@ def RandomDirectedGNM(self, n, m, loops=False): if is_dense: for u in range(n): for v in range(n): - if ((u != v) or loops) and (not (v in adj[u])): + if ((u != v) or loops) and (v not in adj[u]): D.add_edge(u, v) return D diff --git a/src/sage/graphs/distances_all_pairs.pyx b/src/sage/graphs/distances_all_pairs.pyx index 85a1d1ee263..23d2e1c79d7 100644 --- a/src/sage/graphs/distances_all_pairs.pyx +++ b/src/sage/graphs/distances_all_pairs.pyx @@ -304,8 +304,7 @@ cdef inline all_pairs_shortest_path_BFS(gg, # Copying the whole graph to obtain the list of neighbors quicker than by # calling out_neighbors cdef short_digraph sd - init_short_digraph(sd, gg, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, gg, edge_labelled=False, vertex_list=int_to_vertex) c_all_pairs_shortest_path_BFS(sd, predecessors, distances, eccentricity) @@ -413,7 +412,7 @@ def shortest_path_all_pairs(G): cdef unsigned short * c_distances_all_pairs(G, vertex_list=None) noexcept: r""" - Returns the matrix of distances in G. + Return the matrix of distances in G. The matrix `M` returned is of length `n^2`, and the distance between vertices `u` and `v` is `M[u,v]`. The integer corresponding to a vertex is @@ -492,7 +491,7 @@ def distances_all_pairs(G): def is_distance_regular(G, parameters=False): r""" - Test if the graph is distance-regular + Test if the graph is distance-regular. A graph `G` is distance-regular if for any integers `j,k` the value of `|\{x:d_G(x,u)=j,x\in V(G)\} \cap \{y:d_G(y,v)=j,y\in V(G)\}|` is constant @@ -546,7 +545,6 @@ def is_distance_regular(G, parameters=False): ([1, None], [None, 1]) sage: graphs.Tutte12Cage().is_distance_regular(parameters=True) # needs networkx ([3, 2, 2, 2, 2, 2, None], [None, 1, 1, 1, 1, 1, 3]) - """ cdef int i, u, v, d, b, c, k cdef int n = G.order() @@ -939,28 +937,28 @@ cdef uint32_t * c_eccentricity_DHV(short_digraph sd) except NULL: return ecc_upper_bound -def eccentricity(G, algorithm="standard", vertex_list=None): +def eccentricity(G, algorithm='standard', vertex_list=None): r""" Return the vector of eccentricities in G. The array returned is of length `n`, and its `i`-th component is the - eccentricity of the ith vertex in ``G.vertices(sort=True)``. + eccentricity of the `i`-th vertex in ``G.vertices(sort=True)``. INPUT: - - ``G`` -- a Graph or a DiGraph. + - ``G`` -- a Graph or a DiGraph - ``algorithm`` -- string (default: ``'standard'``); name of the method used - to compute the eccentricity of the vertices. + to compute the eccentricity of the vertices - - ``'standard'`` -- Computes eccentricity by performing a BFS from each - vertex. + - ``'standard'`` -- computes eccentricity by performing a BFS from each + vertex - - ``'bounds'`` -- Computes eccentricity using the fast algorithm proposed - in [TK2013]_ for undirected graphs. + - ``'bounds'`` -- computes eccentricity using the fast algorithm proposed + in [TK2013]_ for undirected graphs - - ``'DHV'`` -- Computes all eccentricities of undirected graph using the - algorithm proposed in [Dragan2018]_. + - ``'DHV'`` -- computes all eccentricities of undirected graph using the + algorithm proposed in [Dragan2018]_ - ``vertex_list`` -- list (default: ``None``); a list of `n` vertices specifying a mapping from `(0, \ldots, n-1)` to vertex labels in `G`. When @@ -1058,8 +1056,7 @@ def eccentricity(G, algorithm="standard", vertex_list=None): ecc = c_eccentricity(G, vertex_list=int_to_vertex) else: - init_short_digraph(sd, G, edge_labelled=False, vertex_list=vertex_list, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=vertex_list) if algorithm == "DHV": ecc = c_eccentricity_DHV(sd) @@ -1166,7 +1163,7 @@ cdef tuple diameter_lower_bound_2Dsweep(short_digraph g, - ``g`` -- a short_digraph - - ``rev_g`` -- a copy of `g` with edges reversed. + - ``rev_g`` -- a copy of `g` with edges reversed - ``source`` -- starting node of the forward and backward BFS @@ -1279,7 +1276,6 @@ cdef tuple diameter_lower_bound_multi_sweep(short_digraph g, - ``g`` -- a short_digraph - ``source`` -- starting node of the BFS - """ # The while loop below might not be entered so we have to make sure that # s and d which are returned are initialized. @@ -1351,7 +1347,6 @@ cdef uint32_t diameter_iFUB(short_digraph g, - ``g`` -- a short_digraph - ``source`` -- starting node of the first BFS - """ cdef uint32_t i, LB, m cdef uint32_t n = g.n @@ -1682,11 +1677,11 @@ def diameter(G, algorithm=None, source=None): - ``algorithm`` -- string (default: ``None``); specifies the algorithm to use among: - - ``'standard'`` -- Computes the diameter of the input (di)graph as the + - ``'standard'`` -- computes the diameter of the input (di)graph as the largest eccentricity of its vertices. This is the classical algorithm with time complexity in `O(nm)`. - - ``'2sweep'`` -- Computes a lower bound on the diameter of an + - ``'2sweep'`` -- computes a lower bound on the diameter of an unweighted undirected graph using 2 BFS, as proposed in [MLH2008]_. It first selects a vertex `v` that is at largest distance from an initial vertex source using BFS. Then it performs a second BFS from `v`. The @@ -1694,15 +1689,15 @@ def diameter(G, algorithm=None, source=None): of `G`. The time complexity of this algorithm is linear in the size of `G`. - - ``'2Dsweep'`` -- Computes lower bound on the diameter of an unweighted + - ``'2Dsweep'`` -- computes lower bound on the diameter of an unweighted directed graph using directed version of ``2sweep`` as proposed in [Broder2000]_. If the digraph is not strongly connected, the returned value is infinity. - - ``'DHV'`` -- Computes diameter of unweighted undirected graph using the - algorithm proposed in [Dragan2018]_. + - ``'DHV'`` -- computes diameter of unweighted undirected graph using the + algorithm proposed in [Dragan2018]_ - - ``'multi-sweep'`` -- Computes a lower bound on the diameter of an + - ``'multi-sweep'`` -- computes a lower bound on the diameter of an unweighted undirected graph using several iterations of the ``2sweep`` algorithms [CGHLM2013]_. Roughly, it first uses ``2sweep`` to identify two vertices `u` and `v` that are far apart. Then it selects a vertex @@ -1712,12 +1707,12 @@ def diameter(G, algorithm=None, source=None): This process is repeated as long as the lower bound on the diameter is improved. - - ``'iFUB'`` -- The iFUB (iterative Fringe Upper Bound) algorithm, + - ``'iFUB'`` -- the iFUB (iterative Fringe Upper Bound) algorithm, proposed in [CGILM2010]_, computes the exact value of the diameter of an unweighted undirected graph. It is based on the following observation: The diameter of the graph is equal to the maximum eccentricity of - a vertex. Let `v` be any vertex, and let `V` be partitionned into + a vertex. Let `v` be any vertex, and let `V` be partitioned into `A\cup B` where: .. MATH:: @@ -1740,7 +1735,7 @@ def diameter(G, algorithm=None, source=None): by the remark above. The worst case time complexity of the iFUB algorithm is `O(nm)`, but it can be very fast in practice. - - ``'DiFUB'`` -- The directed version of iFUB (iterative Fringe Upper + - ``'DiFUB'`` -- the directed version of iFUB (iterative Fringe Upper Bound) algorithm. See the code's documentation and [CGLM2012]_ for more details. If the digraph is not strongly connected, the returned value is infinity. @@ -1839,8 +1834,7 @@ def diameter(G, algorithm=None, source=None): # module sage.graphs.base.static_sparse_graph cdef list int_to_vertex = list(G) cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef short_digraph rev_sd # to store copy of sd with edges reversed # and we map the source to an int in [0,n-1] @@ -1942,8 +1936,7 @@ def radius_DHV(G): cdef list int_to_vertex = list(G) cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef uint32_t source, ecc_source cdef uint32_t antipode, ecc_antipode @@ -2060,8 +2053,7 @@ def wiener_index(G): # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G), - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G)) # allocated some data structures cdef bitset_t seen @@ -2117,7 +2109,7 @@ cdef uint64_t c_szeged_index_low_memory(short_digraph sd) noexcept: EXAMPLES:: - sage: graphs.CycleGraph(4).szeged_index(algorithm="low") + sage: graphs.CycleGraph(4).szeged_index(algorithm='low') 16 """ cdef size_t n = sd.n @@ -2213,7 +2205,7 @@ cdef uint64_t c_szeged_index_high_memory(short_digraph sd) noexcept: EXAMPLES:: - sage: graphs.CycleGraph(4).szeged_index(algorithm="high") + sage: graphs.CycleGraph(4).szeged_index(algorithm='high') 16 """ cdef int n = sd.n @@ -2272,24 +2264,16 @@ def szeged_index(G, algorithm=None): - ``algorithm`` -- string (default: ``None``); algorithm to use among: - - ``"low"`` -- algorithm with time complexity in `O(nm)` and space + - ``'low'`` -- algorithm with time complexity in `O(nm)` and space complexity in `O(m)`. This implementation is currently valid only for simple (without loops or multiple edges) connected graphs. - - ``"high"`` -- algorithm with time complexity in `O(nm)` and space + - ``'high'`` -- algorithm with time complexity in `O(nm)` and space complexity in `O(n^2)`. It cannot be used on graphs with more than `65536 = 2^{16}` vertices. - By default (``None``), the ``"low"`` algorithm is used for graphs and the - ``"high"`` algorithm for digraphs. - - .. NOTE:: - As the graph is converted to a short_digraph, the complexity for the - case ``algorithm == "high"`` has an extra `O(m+n)` for ``SparseGraph`` - and `O(n^2)` for ``DenseGraph``. If ``algorithm == "low"``, the extra - complexity is `O(n + m\log{m})` for ``SparseGraph`` and `O(n^2\log{m})` - for ``DenseGraph`` (because ``init_short_digraph`` is called with - ``sort_neighbors=True``). + By default (``None``), the ``'low'`` algorithm is used for graphs and the + ``'high'`` algorithm for digraphs. EXAMPLES: @@ -2339,22 +2323,22 @@ def szeged_index(G, algorithm=None): Wrong name of algorithm:: - sage: szeged_index(Graph(1), algorithm="wheel") + sage: szeged_index(Graph(1), algorithm='wheel') Traceback (most recent call last): ... ValueError: unknown algorithm 'wheel' Algorithm `"low"` is for graphs without loops or multiple edges:: - sage: szeged_index(Graph([(0, 0)], loops=True), algorithm="low") + sage: szeged_index(Graph([(0, 0)], loops=True), algorithm='low') Traceback (most recent call last): ... ValueError: the 'low' algorithm is for simple connected undirected graphs only - sage: szeged_index(Graph([(0, 1), (0, 1)], multiedges=True), algorithm="low") + sage: szeged_index(Graph([(0, 1), (0, 1)], multiedges=True), algorithm='low') Traceback (most recent call last): ... ValueError: the 'low' algorithm is for simple connected undirected graphs only - sage: szeged_index(digraphs.Circuit(3), algorithm="low") + sage: szeged_index(digraphs.Circuit(3), algorithm='low') Traceback (most recent call last): ... ValueError: the 'low' algorithm cannot be used on digraphs @@ -2381,13 +2365,12 @@ def szeged_index(G, algorithm=None): return 0 cdef short_digraph sd + init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G)) cdef uint64_t s if algorithm == "low": - init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G), sort_neighbors=True) s = c_szeged_index_low_memory(sd) else: - init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G), sort_neighbors=False) s = c_szeged_index_high_memory(sd) free_short_digraph(sd) @@ -2519,8 +2502,8 @@ def antipodal_graph(G): This method first computes the eccentricity of all vertices and determines the diameter of the graph. Then, it for each vertex `u` with eccentricity the diameter, it computes BFS distances from `u` and add an edge in the - antipodal graph for each vertex `v` at diamter distance from `u` (i.e., for - each antipodal vertex). + antipodal graph for each vertex `v` at diameter distance from `u` + (i.e., for each antipodal vertex). The drawback of this method is that some BFS distances may be computed twice, one time to determine the eccentricities and another time is the @@ -2644,7 +2627,7 @@ def floyd_warshall(gg, paths=True, distances=False): INPUT: - - ``gg`` -- the graph on which to work. + - ``gg`` -- the graph on which to work - ``paths`` -- boolean (default: ``True``); whether to return the dictionary of shortest paths diff --git a/src/sage/graphs/domination.py b/src/sage/graphs/domination.py index 327201202be..37c0ca5fb51 100644 --- a/src/sage/graphs/domination.py +++ b/src/sage/graphs/domination.py @@ -18,7 +18,6 @@ :meth:`~greedy_dominating_set` | Return a greedy distance-`k` dominating set of the graph. :meth:`~maximum_leaf_number` | Return the maximum leaf number of the graph. - EXAMPLES: We compute the size of a minimum dominating set of the Petersen graph:: @@ -80,11 +79,11 @@ def is_dominating(G, dom, focus=None): INPUT: - ``dom`` -- iterable of vertices of ``G``; the vertices of the supposed - dominating set. + dominating set - ``focus`` -- iterable of vertices of ``G`` (default: ``None``); if specified, this method checks instead if ``dom`` dominates the vertices in - ``focus``. + ``focus`` EXAMPLES:: @@ -117,11 +116,11 @@ def is_redundant(G, dom, focus=None): INPUT: - ``dom`` -- iterable of vertices of ``G``; where we look for redundant - vertices. + vertices - ``focus`` -- iterable of vertices of ``G`` (default: ``None``); if specified, this method checks instead whether ``dom`` has a redundant - vertex in ``focus``. + vertex in ``focus`` .. WARNING:: @@ -181,10 +180,10 @@ def private_neighbors(G, vertex, dom): INPUT: - - ``vertex`` -- a vertex of ``G``. + - ``vertex`` -- a vertex of ``G`` - ``dom`` -- iterable of vertices of ``G``; the vertices possibly stealing - private neighbors from ``vertex``. + private neighbors from ``vertex`` OUTPUT: @@ -251,7 +250,7 @@ def dominating_sets(g, k=1, independent=False, total=False, connected=False, INPUT: - - ``k`` -- a non-negative integer (default: ``1``); the domination distance + - ``k`` -- nonnegative integer (default: `1`); the domination distance - ``independent`` -- boolean (default: ``False``); when ``True``, computes minimum independent dominating sets, that is minimum dominating sets that @@ -264,7 +263,7 @@ def dominating_sets(g, k=1, independent=False, total=False, connected=False, - ``connected`` -- boolean (default: ``False``); when ``True``, computes connected dominating sets (see :wikipedia:`Connected_dominating_set`) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -272,7 +271,7 @@ def dominating_sets(g, k=1, independent=False, total=False, connected=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -379,7 +378,7 @@ def dominating_sets(g, k=1, independent=False, total=False, connected=False, sage: next(g.dominating_sets(k=-1)) Traceback (most recent call last): ... - ValueError: the domination distance must be a non-negative integer + ValueError: the domination distance must be a nonnegative integer The method is robust to vertices with incomparable labels:: @@ -394,7 +393,7 @@ def dominating_sets(g, k=1, independent=False, total=False, connected=False, yield list(g) return if k < 0: - raise ValueError("the domination distance must be a non-negative integer") + raise ValueError("the domination distance must be a nonnegative integer") from sage.numerical.mip import MixedIntegerLinearProgram from sage.numerical.mip import MIPSolverException @@ -503,7 +502,7 @@ def dominating_set(g, k=1, independent=False, total=False, connected=False, valu INPUT: - - ``k`` -- a non-negative integer (default: ``1``); the domination distance + - ``k`` -- nonnegative integer (default: `1`); the domination distance - ``independent`` -- boolean (default: ``False``); when ``True``, computes a minimum independent dominating set, that is a minimum dominating set that @@ -520,7 +519,7 @@ def dominating_set(g, k=1, independent=False, total=False, connected=False, valu cardinality of the computed dominating set, or to return its list of vertices (default) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -528,7 +527,7 @@ def dominating_set(g, k=1, independent=False, total=False, connected=False, valu :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -655,7 +654,7 @@ def _peel(G, A): - ``G`` -- a graph - - ``A`` -- a set of vertices of `G` + - ``A`` -- set of vertices of `G` OUTPUT: @@ -681,7 +680,6 @@ def _peel(G, A): (4, {4, 6, 8}), (2, {2, 4, 6, 8}), (0, {0, 2, 4, 6, 8})] - """ Acomp = set(G) Acomp.difference_update(A) # Acomp = V - A @@ -716,9 +714,7 @@ def _cand_ext_enum(G, to_dom, u_next): - ``u_next`` -- a vertex of ``G`` that dominates ``to_dom`` - OUTPUT: - - An iterator over the minimal dominating sets of ``to_dom``. + OUTPUT: an iterator over the minimal dominating sets of ``to_dom`` TESTS:: @@ -808,16 +804,16 @@ def minimal_dominating_sets(G, to_dominate=None, work_on_copy=True, k=1): INPUT: - - ``G`` -- a graph. + - ``G`` -- a graph - ``to_dominate`` -- vertex iterable or ``None`` (default: ``None``); - the set of vertices to be dominated. + the set of vertices to be dominated - ``work_on_copy`` -- boolean (default: ``True``); whether or not to work on a copy of the input graph; if set to ``False``, the input graph will be - modified (relabeled). + modified (relabeled) - - ``k`` -- a non-negative integer (default: ``1``); the domination distance + - ``k`` -- nonnegative integer (default: `1`); the domination distance OUTPUT: @@ -966,7 +962,7 @@ def minimal_dominating_sets(G, to_dominate=None, work_on_copy=True, k=1): sage: next(Graph(1).minimal_dominating_sets(k=-1)) Traceback (most recent call last): ... - ValueError: the domination distance must be a non-negative integer + ValueError: the domination distance must be a nonnegative integer Trying to dominate vertices that are not part of the graph:: @@ -996,7 +992,7 @@ def tree_search(H, plng, dom, i): - ``dom`` -- a minimal dominating set of ``plng[i][1]`` - - ``i`` -- an integer, the current position in ``plng`` + - ``i`` -- integer; the current position in ``plng`` OUTPUT: @@ -1048,7 +1044,7 @@ def tree_search(H, plng, dom, i): # end of tree-search routine if k < 0: - raise ValueError("the domination distance must be a non-negative integer") + raise ValueError("the domination distance must be a nonnegative integer") if not k: yield set(G) if to_dominate is None else set(to_dominate) return @@ -1110,7 +1106,7 @@ def greedy_dominating_set(G, k=1, vertices=None, ordering=None, return_sets=Fals - ``G`` -- a Graph - - ``k`` -- integer (default: ``1``); the domination distance to consider + - ``k`` -- integer (default: `1`); the domination distance to consider - ``vertices`` -- iterable container of vertices (default: ``None``); when specified, return a dominating set of the specified vertices only @@ -1122,9 +1118,9 @@ def greedy_dominating_set(G, k=1, vertices=None, ordering=None, return_sets=Fals the order given by ``list(G)``. Otherwise, consider the vertices in the order of iteration of ``vertices``. - - ``"degree_min"`` -- consider the vertices by increasing degree + - ``'degree_min'`` -- consider the vertices by increasing degree - - ``"degree_max"`` -- consider the vertices by decreasing degree + - ``'degree_max'`` -- consider the vertices by decreasing degree - ``return_sets`` -- boolean (default: ``False``); whether to return the vertices of the dominating set only (default), or a dictionary mapping @@ -1142,19 +1138,19 @@ def greedy_dominating_set(G, k=1, vertices=None, ordering=None, return_sets=Fals sage: G = graphs.PathGraph(5) sage: sorted(greedy_dominating_set(G, ordering=None)) [0, 2, 4] - sage: sorted(greedy_dominating_set(G, ordering="degree_min")) + sage: sorted(greedy_dominating_set(G, ordering='degree_min')) [0, 2, 4] - sage: sorted(greedy_dominating_set(G, ordering="degree_max")) + sage: sorted(greedy_dominating_set(G, ordering='degree_max')) [1, 3] sage: sorted(greedy_dominating_set(G, k=2, ordering=None)) [0, 3] - sage: sorted(greedy_dominating_set(G, k=2, ordering="degree_min")) + sage: sorted(greedy_dominating_set(G, k=2, ordering='degree_min')) [0, 4] - sage: sorted(greedy_dominating_set(G, k=2, ordering="degree_max")) + sage: sorted(greedy_dominating_set(G, k=2, ordering='degree_max')) [1, 4] - sage: greedy_dominating_set(G, k=3, ordering="degree_min", return_sets=True, closest=False) + sage: greedy_dominating_set(G, k=3, ordering='degree_min', return_sets=True, closest=False) {0: {0, 1, 2, 3}, 4: {4}} - sage: greedy_dominating_set(G, k=3, ordering="degree_min", return_sets=True, closest=True) + sage: greedy_dominating_set(G, k=3, ordering='degree_min', return_sets=True, closest=True) {0: {0, 2, 3}, 4: {1, 4}} Asking for a dominating set of a subset of vertices:: @@ -1222,7 +1218,7 @@ def greedy_dominating_set(G, k=1, vertices=None, ordering=None, return_sets=Fals Check parameters:: - sage: greedy_dominating_set(G, ordering="foo") + sage: greedy_dominating_set(G, ordering='foo') Traceback (most recent call last): ... ValueError: ordering must be None, "degree_min" or "degree_max" @@ -1302,7 +1298,7 @@ def maximum_leaf_number(G, solver=None, verbose=0, integrality_tolerance=1e-3): - ``G`` -- a Graph - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1310,7 +1306,7 @@ def maximum_leaf_number(G, solver=None, verbose=0, integrality_tolerance=1e-3): :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers diff --git a/src/sage/graphs/dot2tex_utils.py b/src/sage/graphs/dot2tex_utils.py index f8eb55485ac..77446949886 100644 --- a/src/sage/graphs/dot2tex_utils.py +++ b/src/sage/graphs/dot2tex_utils.py @@ -16,8 +16,8 @@ @cached_function def have_dot2tex(): """ - Returns whether ``dot2tex`` >= 2.8.7 and graphviz are installed - and functional + Return whether ``dot2tex`` >= 2.8.7 and graphviz are installed + and functional. EXAMPLES:: @@ -29,15 +29,15 @@ def have_dot2tex(): try: import dot2tex # Test for this required feature from dot2tex 2.8.7 - return dot2tex.dot2tex("graph {}", format="positions") == {} + return dot2tex.dot2tex("graph {}", format='positions') == {} except (Exception, SystemExit): return False def assert_have_dot2tex(): """ - Tests whether ``dot2tex`` >= 2.8.7 and graphviz are installed and - functional, and raises an error otherwise + Test whether ``dot2tex`` >= 2.8.7 and graphviz are installed and + functional, and raises an error otherwise. EXAMPLES:: @@ -63,7 +63,7 @@ def assert_have_dot2tex(): print(import_error_string) raise # re-raise current exception else: - if dot2tex.dot2tex("graph {}", format="positions") != {}: + if dot2tex.dot2tex("graph {}", format='positions') != {}: raise RuntimeError(check_error_string) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index aef8e43d98e..bfaedc3fdfa 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -452,7 +452,7 @@ cdef class GabowEdgeConnectivity: Allocate data structure for the new tree/forest. This method also initializes data structures for this tree index. Data - structures for a given tree index are allocatated only once. + structures for a given tree index are allocated only once. INPUT: diff --git a/src/sage/graphs/generators/basic.py b/src/sage/graphs/generators/basic.py index 9776b561748..aef8ea49935 100644 --- a/src/sage/graphs/generators/basic.py +++ b/src/sage/graphs/generators/basic.py @@ -407,14 +407,14 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): Return a correlation graph with a node per sequence in ``seqs``. Edges are added between nodes where the corresponding sequences have a - correlation coeffecient greater than alpha. + correlation coefficient greater than alpha. If ``include_anticorrelation`` is ``True``, then edges are also added between nodes with correlation coefficient less than ``-alpha``. INPUT: - - ``seqs`` -- list of sequences, taht is a list of lists + - ``seqs`` -- list of sequences, that is a list of lists - ``alpha`` -- float; threshold on the correlation coefficient between two sequences for adding an edge @@ -440,7 +440,7 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): from numpy import corrcoef from sage.matrix.constructor import Matrix - # compute pairwise correlation coeffecients + # compute pairwise correlation coefficients corrs = corrcoef(seqs) # compare against alpha to get adjacency matrix @@ -452,7 +452,7 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): adjacency_matrix = Matrix(boolean_adjacency_matrix.astype(int)) # call graph constructor - return Graph(adjacency_matrix, format="adjacency_matrix", name="Correlation Graph") + return Graph(adjacency_matrix, format='adjacency_matrix', name="Correlation Graph") def CompleteBipartiteGraph(p, q, set_position=True): @@ -467,7 +467,7 @@ def CompleteBipartiteGraph(p, q, set_position=True): - ``p``, ``q`` -- number of vertices in each side - - ``set_position`` -- boolean (default ``True``); if set to ``True``, we + - ``set_position`` -- boolean (default: ``True``); if set to ``True``, we assign positions to the vertices so that the set of cardinality `p` is on the line `y=1` and the set of cardinality `q` is on the line `y=0`. @@ -591,7 +591,7 @@ def CompleteMultipartiteGraph(L): INPUT: - - ``L`` -- a list of integers; the respective sizes of the components + - ``L`` -- list of integers; the respective sizes of the components PLOTTING: Produce a layout of the vertices so that vertices in the same vertex set are adjacent and clearly separated from vertices in other vertex @@ -893,7 +893,7 @@ def Grid2dGraph(p, q, set_positions=True): INPUT: - - ``p`` and ``q`` -- two positive integers + - ``p``, ``q`` -- two positive integers - ``set_positions`` -- boolean (default: ``True``); whether to set the position of the nodes @@ -954,8 +954,8 @@ def GridGraph(dim_list): INPUT: - - ``dim_list`` -- a list of integers representing the number of nodes to - extend in each dimension + - ``dim_list`` -- list of integers representing the number of nodes to + extend in each dimension PLOTTING: When plotting, this graph will use the default spring-layout algorithm, unless a position dictionary is specified. @@ -1182,12 +1182,12 @@ def MoebiusLadderGraph(n): INPUT: - - ``n`` -- a non negative integer; number of nodes is `2n` + - ``n`` -- a nonnegative integer; number of nodes is `2n` OUTPUT: - ``G`` -- a Möbius ladder graph of order `2n`; note that a - :class:`ValueError` is returned if `n < 0` + :exc:`ValueError` is returned if `n < 0` EXAMPLES: @@ -1214,12 +1214,12 @@ def MoebiusLadderGraph(n): TESTS: - The input parameter must be a non negative integer:: + The input parameter must be a nonnegative integer:: sage: G = graphs.MoebiusLadderGraph(-1) Traceback (most recent call last): ... - ValueError: parameter n must be a non negative integer + ValueError: parameter n must be a nonnegative integer REFERENCES: @@ -1235,7 +1235,7 @@ def MoebiusLadderGraph(n): - Janmenjaya Panda (2024-05-26) """ if n < 0: - raise ValueError("parameter n must be a non negative integer") + raise ValueError("parameter n must be a nonnegative integer") G = Graph(2 * n, name="Moebius ladder graph") G._circle_embedding(list(range(2 * n)), angle=pi/2) @@ -1421,7 +1421,7 @@ def StarGraph(n): sage: G = graphics_array(j) sage: G.show() # long time """ - G = Graph({0: list(range(1, n + 1))}, name="Star graph", format="dict_of_lists") + G = Graph({0: list(range(1, n + 1))}, name="Star graph", format='dict_of_lists') G.set_pos({0: (0, 0)}) G._circle_embedding(list(range(1, n + 1)), angle=pi/2) return G diff --git a/src/sage/graphs/generators/chessboard.py b/src/sage/graphs/generators/chessboard.py index a76d6f98de7..4759ad917e7 100644 --- a/src/sage/graphs/generators/chessboard.py +++ b/src/sage/graphs/generators/chessboard.py @@ -59,10 +59,10 @@ def ChessboardGraphGenerator(dim_list, rook=True, rook_radius=None, - ``knight`` -- boolean (default: ``True``); indicating whether the chess piece is able to move like a knight - - ``knight_x`` -- integer (default: ``1``); indicates the number on steps + - ``knight_x`` -- integer (default: `1`); indicates the number on steps the chess piece moves in one dimension when moving like a knight - - ``knight_y`` -- integer (default: ``2``); indicates the number on steps + - ``knight_y`` -- integer (default: `2`); indicates the number on steps the chess piece moves in the second dimension when moving like a knight - ``relabel`` -- boolean (default: ``False``); indicates whether the @@ -272,7 +272,7 @@ def QueenGraph(dim_list, radius=None, relabel=False): sage: G.is_isomorphic(H) True - Also True in higher dimensions:: + Also ``True`` in higher dimensions:: sage: G = graphs.QueenGraph([3, 4, 5], radius=1) sage: H = graphs.KingGraph([5, 3, 4]) @@ -289,7 +289,6 @@ def QueenGraph(dim_list, radius=None, relabel=False): ....: H.add_edges(B.edges(sort=False)) ....: if not G.is_isomorphic(H): ....: print("that's not good!") - """ G, dimstr = ChessboardGraphGenerator(dim_list, rook=True, rook_radius=radius, @@ -346,7 +345,7 @@ def KingGraph(dim_list, radius=None, relabel=False): sage: G.is_isomorphic( H ) True - Also True in higher dimensions:: + Also ``True`` in higher dimensions:: sage: G = graphs.KingGraph( [2, 5, 4], radius=5 ) sage: H = graphs.QueenGraph( [4, 5, 2] ) @@ -386,10 +385,10 @@ def KnightGraph(dim_list, one=1, two=2, relabel=False): - ``dim_list`` -- iterable (list, set, dict); provides the dimensions `n_1, n_2, \ldots, n_d`, with `n_i \geq 1`, of the chessboard - - ``one`` -- integer (default: ``1``); indicates the number of steps in the + - ``one`` -- integer (default: `1`); indicates the number of steps in the first dimension - - ``two`` -- integer (default: ``2``); indicates the number of steps in the + - ``two`` -- integer (default: `2`); indicates the number of steps in the second dimension - ``relabel`` -- boolean (default: ``False``); indicates whether the @@ -526,7 +525,6 @@ def BishopGraph(dim_list, radius=None, relabel=False): ....: H.add_edges( graphs.KnightGraph([d,d],one=r,two=r).edges(sort=False) ) ....: if not B.is_isomorphic(H): ....: print("that's not good!") - """ G, dimstr = ChessboardGraphGenerator(dim_list, rook=False, knight=False, diff --git a/src/sage/graphs/generators/classical_geometries.py b/src/sage/graphs/generators/classical_geometries.py index da04362eef3..8cd60e5862e 100644 --- a/src/sage/graphs/generators/classical_geometries.py +++ b/src/sage/graphs/generators/classical_geometries.py @@ -3,7 +3,7 @@ Families of graphs derived from classical geometries over finite fields These include graphs of polar spaces, affine polar graphs, graphs -related to Hermitean unitals, graphs on nonisotropic points, etc +related to Hermitean unitals, graphs on nonisotropic points, etc. The methods defined here appear in :mod:`sage.graphs.graph_generators`. """ @@ -37,7 +37,7 @@ def SymplecticPolarGraph(d, q, algorithm=None): INPUT: - ``d``, ``q`` -- integers; note that only even values of `d` are accepted - by the function. + by the function - ``algorithm`` -- string (default: ``None``); if set to ``'gap'``, then the computation is carried via GAP library interface, computing totally @@ -67,17 +67,17 @@ def SymplecticPolarGraph(d, q, algorithm=None): (40, 12, 2, 4) sage: O.is_isomorphic(G) False - sage: S = graphs.SymplecticPolarGraph(6, 4, algorithm="gap") # not tested (long time) + sage: S = graphs.SymplecticPolarGraph(6, 4, algorithm='gap') # not tested (long time) sage: S.is_strongly_regular(parameters=True) # not tested (long time) (1365, 340, 83, 85) TESTS:: - sage: graphs.SymplecticPolarGraph(4,4,algorithm="gap").is_strongly_regular(parameters=True) # needs sage.libs.gap + sage: graphs.SymplecticPolarGraph(4,4,algorithm='gap').is_strongly_regular(parameters=True) # needs sage.libs.gap (85, 20, 3, 5) sage: graphs.SymplecticPolarGraph(4,4).is_strongly_regular(parameters=True) # needs sage.libs.pari (85, 20, 3, 5) - sage: graphs.SymplecticPolarGraph(4,4,algorithm="blah") + sage: graphs.SymplecticPolarGraph(4,4,algorithm='blah') Traceback (most recent call last): ... ValueError: unknown algorithm! @@ -113,7 +113,7 @@ def SymplecticPolarGraph(d, q, algorithm=None): return G -def AffineOrthogonalPolarGraph(d, q, sign="+"): +def AffineOrthogonalPolarGraph(d, q, sign='+'): r""" Return the affine polar graph `VO^+(d,q),VO^-(d,q)` or `VO(d,q)`. @@ -134,7 +134,7 @@ def AffineOrthogonalPolarGraph(d, q, sign="+"): - ``q`` -- integer; a power of a prime number, as `F_q` must exist - - ``sign`` -- string (default: ``"+"``); must be equal to ``"+"``, ``"-"``, + - ``sign`` -- string (default: ``'+'``); must be equal to ``'+'``, ``'-'``, or ``None`` to compute (respectively) `VO^+(d,q),VO^-(d,q)` or `VO(d,q)` @@ -207,7 +207,7 @@ def AffineOrthogonalPolarGraph(d, q, sign="+"): return G -def _orthogonal_polar_graph(m, q, sign="+", point_type=[0]): +def _orthogonal_polar_graph(m, q, sign='+', point_type=[0]): r""" A helper function to build ``OrthogonalPolarGraph`` and ``NO2,3,5`` graphs. @@ -218,10 +218,10 @@ def _orthogonal_polar_graph(m, q, sign="+", point_type=[0]): - ``m``, ``q`` -- integers; `q` must be a prime power - - ``sign`` -- string (default: ``"+"``); must be ``"+"`` or ``"-"`` if `m` - is even, ``"+"`` (default) otherwise + - ``sign`` -- string (default: ``'+'``); must be ``'+'`` or ``'-'`` if `m` + is even, ``'+'`` (default) otherwise - - ``point_type`` -- a list of elements from `F_q` + - ``point_type`` -- list of elements from `F_q` EXAMPLES: @@ -285,7 +285,6 @@ def _orthogonal_polar_graph(m, q, sign="+", point_type=[0]): sage: g = _orthogonal_polar_graph(5,3,point_type=[1]) sage: g.is_strongly_regular(parameters=True) (36, 15, 6, 6) - """ from sage.schemes.projective.projective_space import ProjectiveSpace from sage.modules.free_module_element import free_module_element as vector @@ -331,7 +330,7 @@ def P(x, y): return G -def OrthogonalPolarGraph(m, q, sign="+"): +def OrthogonalPolarGraph(m, q, sign='+'): r""" Return the Orthogonal Polar Graph `O^{\epsilon}(m,q)`. @@ -342,8 +341,8 @@ def OrthogonalPolarGraph(m, q, sign="+"): - ``m``, ``q`` -- integers; `q` must be a prime power - - ``sign`` -- string (default: ``"+"``); must be ``"+"`` or ``"-"`` if `m` - is even, ``"+"`` (default) otherwise + - ``sign`` -- string (default: ``'+'``); must be ``'+'`` or ``'-'`` if `m` + is even, ``'+'`` (default) otherwise EXAMPLES:: @@ -387,9 +386,9 @@ def OrthogonalPolarGraph(m, q, sign="+"): return G -def NonisotropicOrthogonalPolarGraph(m, q, sign="+", perp=None): +def NonisotropicOrthogonalPolarGraph(m, q, sign='+', perp=None): r""" - Return the Graph `NO^{\epsilon,\perp}_{m}(q)` + Return the Graph `NO^{\epsilon,\perp}_{m}(q)`. Let the vectorspace of dimension `m` over `F_q` be endowed with a nondegenerate quadratic form `F`, of type ``sign`` for `m` even. @@ -417,7 +416,7 @@ def NonisotropicOrthogonalPolarGraph(m, q, sign="+", perp=None): - ``q`` -- a power of a prime number, the size of the underlying field - - ``sign`` -- string (default: ``"+"``); must be either ``"+"`` or ``"-"`` + - ``sign`` -- string (default: ``'+'``); must be either ``'+'`` or ``'-'`` EXAMPLES: @@ -551,7 +550,7 @@ def NonisotropicOrthogonalPolarGraph(m, q, sign="+", perp=None): def _polar_graph(m, q, g, intersection_size=None): r""" - The helper function to build graphs `(D)U(m,q)` and `(D)Sp(m,q)` + The helper function to build graphs `(D)U(m,q)` and `(D)Sp(m,q)`. Building a graph on an orbit of a group `g` of `m\times m` matrices over `GF(q)` on the points (or subspaces of dimension ``m//2``) isotropic @@ -570,7 +569,7 @@ def _polar_graph(m, q, g, intersection_size=None): - ``g`` -- the group acting - - ``intersection_size`` -- (default: ``None``); if ``None``, build the graph + - ``intersection_size`` -- (default: ``None``) if ``None``, build the graph on the isotropic points, with adjacency being orthogonality w.r.t. `F`. Otherwise, build the graph on the maximal totally isotropic subspaces, with adjacency specified by ``intersection_size`` being as given. @@ -604,7 +603,7 @@ def _polar_graph(m, q, g, intersection_size=None): loops=False) -def UnitaryPolarGraph(m, q, algorithm="gap"): +def UnitaryPolarGraph(m, q, algorithm='gap'): r""" Return the Unitary Polar Graph `U(m,q)`. @@ -615,7 +614,7 @@ def UnitaryPolarGraph(m, q, algorithm="gap"): - ``m``, ``q`` -- integers; `q` must be a prime power - - ``algorithm`` -- string (default: ``"gap"``); if set to 'gap' then the + - ``algorithm`` -- string (default: ``'gap'``); if set to ``'gap'`` then the computation is carried via GAP library interface, computing totally singular subspaces, which is faster for large examples (especially with `q>2`). Otherwise it is done directly. @@ -634,11 +633,11 @@ def UnitaryPolarGraph(m, q, algorithm="gap"): TESTS:: - sage: graphs.UnitaryPolarGraph(4,3, algorithm="gap").is_strongly_regular(parameters=True) # needs sage.libs.gap + sage: graphs.UnitaryPolarGraph(4,3, algorithm='gap').is_strongly_regular(parameters=True) # needs sage.libs.gap (280, 36, 8, 4) sage: graphs.UnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # needs sage.libs.gap (280, 36, 8, 4) - sage: graphs.UnitaryPolarGraph(4,3, algorithm="foo") + sage: graphs.UnitaryPolarGraph(4,3, algorithm='foo') Traceback (most recent call last): ... ValueError: unknown algorithm! @@ -1108,7 +1107,7 @@ def T2starGeneralizedQuadrangleGraph(q, dual=False, hyperoval=None, field=None, raise RuntimeError("incorrect hyperoval size") for L in Theta.blocks(): if set(L).issubset(Pi): - if not len(HO.intersection(L)) in [0, 2]: + if len(HO.intersection(L)) not in [0, 2]: raise RuntimeError("incorrect hyperoval") L = [[y for y in z if y not in HO] @@ -1125,7 +1124,7 @@ def T2starGeneralizedQuadrangleGraph(q, dual=False, hyperoval=None, field=None, def HaemersGraph(q, hyperoval=None, hyperoval_matching=None, field=None, check_hyperoval=True): r""" - Return the Haemers graph obtained from `T_2^*(q)^*` + Return the Haemers graph obtained from `T_2^*(q)^*`. Let `q` be a power of 2. In Sect. 8.A of [BL1984]_ one finds a construction of a strongly regular graph with parameters `(q^2(q+2),q^2+q-1,q-2,q)` from @@ -1201,7 +1200,6 @@ def HaemersGraph(q, hyperoval=None, hyperoval_matching=None, field=None, check_h Haemers(8): Graph on 640 vertices sage: g.is_strongly_regular(parameters=True) # not tested (long time) # needs sage.rings.finite_rings (640, 71, 6, 8) - """ from sage.modules.free_module_element import free_module_element as vector from sage.rings.finite_rings.finite_field_constructor import GF @@ -1280,7 +1278,7 @@ def CossidentePenttilaGraph(q): INPUT: - - ``q`` -- an odd prime power. + - ``q`` -- an odd prime power EXAMPLES: @@ -1311,11 +1309,11 @@ def CossidentePenttilaGraph(q): raise ValueError('q(={}) must be an odd prime power'.format(q)) from sage.features.gap import GapPackage - GapPackage("grape", spkg="gap_packages").require() + GapPackage("grape", spkg='gap_packages').require() from sage.libs.gap.libgap import libgap adj_list = libgap.function_factory("""function(q) - local z, e, so, G, nu, G1, G0, B, T, s, O1, O2, x; + local z, e, so, G, nu, G1, G0, B, T, s, O1, O2, x, sqo; LoadPackage("grape"); G0:=SO(3,q^2); so:=GeneratorsOfGroup(G0); @@ -1380,8 +1378,8 @@ def Nowhere0WordsTwoWeightCodeGraph(q, hyperoval=None, field=None, check_hyperov particular, ``hyperoval`` we build is the classical one, i.e. a conic with the point of intersection of its tangent lines. - - ``field`` -- an instance of a finite field of order `q`, must be provided - if ``hyperoval`` is provided. + - ``field`` -- an instance of a finite field of order `q`; must be provided + if ``hyperoval`` is provided - ``check_hyperoval`` -- boolean (default: ``True``); whether to check ``hyperoval`` for correctness or not @@ -1483,7 +1481,7 @@ def OrthogonalDualPolarGraph(e, d, q): INPUT: - ``e`` -- integer; type of the orthogonal polar space to consider; - must be `-1, 0` or `1`. + must be `-1, 0` or `1` - ``d`` -- integer; diameter of the graph @@ -1607,6 +1605,6 @@ def hashable(v): == intersection_size: edges.append((i, j)) - G = Graph(edges, format="list_of_edges") + G = Graph(edges, format='list_of_edges') G.name("Dual Polar Graph on Orthogonal group (%d, %d, %d)" % (e, m, q)) return G diff --git a/src/sage/graphs/generators/degree_sequence.py b/src/sage/graphs/generators/degree_sequence.py index 5250bd9cb1a..fa3a6aebb02 100644 --- a/src/sage/graphs/generators/degree_sequence.py +++ b/src/sage/graphs/generators/degree_sequence.py @@ -97,7 +97,7 @@ def DegreeSequenceBipartite(s1, s2): True Some sequences being incompatible if, for example, their sums are different, - the functions raises a :class:`ValueError` when no graph corresponding + the functions raises a :exc:`ValueError` when no graph corresponding to the degree sequences exists:: sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,1],[5,5]) # needs sage.combinat sage.modules diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 23a52f57e5d..e7e40f40e24 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -86,7 +86,7 @@ def cocliques_HoffmannSingleton(): if len(c1.intersection(c2)) == 8: edges.append((c1, c2)) - G = Graph(edges, format="list_of_edges") + G = Graph(edges, format='list_of_edges') return G @@ -578,11 +578,11 @@ def LeonardGraph(): if M[i, j] * M[i, l] * M[k, j] * M[k, l] == -1: edges.append(((i, j), (k, l))) - D = Graph(edges, format="list_of_edges") + D = Graph(edges, format='list_of_edges') blocks = [frozenset(cl) for cl in D.cliques_maximum()] edges = [(p, b) for b in blocks for p in b] - G = Graph(edges, format="list_of_edges") + G = Graph(edges, format='list_of_edges') return G @@ -740,7 +740,7 @@ def AlternatingFormsGraph(const int n, const int q): matrices over `GF(q)` with zero diagonal. Two vertices are adjacent if and only if the difference of the two matrices has rank 2. - This grap is distance-regular with classical parameters + This graph is distance-regular with classical parameters `(\lfloor \frac n 2 \rfloor, q^2, q^2 - 1, q^{2 \lceil \frac n 2 \rceil -1})`. INPUT: @@ -1129,7 +1129,7 @@ def DoubleGrassmannGraph(const int q, const int e): r""" Return the bipartite double of the distance-`e` graph of the Grassmann graph `J_q(n,e)`. - This graph can also be descirbed as follows: + This graph can also be described as follows: Let `V` be the vector space of dimension `n` over `GF(q)`. The vertex set is the set of `e+1` or `e` subspaces of `V`. Two vertices are adjacent if one subspace is contained in the other. @@ -1301,7 +1301,7 @@ def graph_from_GQ_spread(const int s, const int t): sig_check() edges.append((p1, p2)) - return Graph(edges, format="list_of_edges") + return Graph(edges, format='list_of_edges') def GeneralisedDodecagonGraph(const int s, const int t): @@ -1423,14 +1423,14 @@ def GeneralisedOctagonGraph(const int s, const int t): EXAMPLES:: sage: # needs sage.libs.gap - sage: G = graphs.GeneralisedOctagonGraph(1, 4) - sage: G.is_distance_regular(True) + sage: G = graphs.GeneralisedOctagonGraph(1, 4) # optional - database_graphs + sage: G.is_distance_regular(True) # optional - database_graphs ([5, 4, 4, 4, None], [None, 1, 1, 1, 5]) sage: G = graphs.GeneralisedOctagonGraph(2, 4) # optional - gap_package_atlasrep internet sage: G.is_distance_regular(True) # optional - gap_package_atlasrep internet ([10, 8, 8, 8, None], [None, 1, 1, 1, 5]) - sage: G = graphs.GeneralisedOctagonGraph(5, 1) - sage: G.is_distance_regular(True) + sage: G = graphs.GeneralisedOctagonGraph(5, 1) # optional - database_graphs + sage: G.is_distance_regular(True) # optional - database_graphs ([10, 5, 5, 5, None], [None, 1, 1, 1, 2]) .. NOTE:: @@ -1792,7 +1792,7 @@ def _line_graph_generalised_polygon(H): sig_check() edges.append((l1, l2)) - return Graph(edges, format="list_of_edges") + return Graph(edges, format='list_of_edges') def _intersection_array_from_graph(G): @@ -1806,7 +1806,7 @@ def _intersection_array_from_graph(G): INPUT: - - G -- a graph + - ``G`` -- a graph EXAMPLES:: @@ -1869,8 +1869,8 @@ def is_classical_parameters_graph(list array): graphs with classical parameters, then this function returns a tuple consisting of the parameters `(d, b, \alpha, \beta)` and a fourth parameter which is the enum ``CalssicalParametersGraph`` indicating the family with - the given itersection array. - If the array doesn't belong to any classical parameter graph, then this + the given intersection array. + If the array does not belong to any classical parameter graph, then this function returns ``False``. If the array belongs to a sporadic graph rather than a family of graphs, then the function returns ``False``. This is to reduce the overlap with @@ -2539,10 +2539,10 @@ def near_polygon_graph(family, params): INPUT: - - ``family`` -- int; an element of the enum ``NearPolygonGraph``. + - ``family`` -- integer; an element of the enum ``NearPolygonGraph`` - - ``params`` -- int or tuple; the parameters needed to construct a graph - of the family ``family``. + - ``params`` -- integer or tuple; the parameters needed to construct a graph + of the family ``family`` EXAMPLES:: @@ -2707,7 +2707,7 @@ def distance_regular_graph(list arr, existence=False, check=True): - ``False`` -- if there is no graph with the given intersection array; - - ``Unknown`` -- if Sage doesn't know if such a graph exists. + - ``Unknown`` -- if Sage doesn't know if such a graph exists - ``check`` -- boolean (default: ``True``); if ``True``, then checks that the result of this function has the given intersection array @@ -2741,7 +2741,7 @@ def distance_regular_graph(list arr, existence=False, check=True): Hamming Graph with parameters 7,3: Graph on 2187 vertices sage: graphs.distance_regular_graph([66, 45, 28, 1, 6, 30]) Graph on 1024 vertices - sage: graphs.distance_regular_graph([6,5,5,5,1,1,1,6]) + sage: graphs.distance_regular_graph([6,5,5,5,1,1,1,6]) # optional - database_graphs Generalised octagon of order (1, 5): Graph on 312 vertices sage: graphs.distance_regular_graph([64, 60, 1, 1, 15, 64], check=True) Graph on 325 vertices diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index c7e1c031ebf..74e7dd01f28 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -26,7 +26,7 @@ def JohnsonGraph(n, k): r""" - Returns the Johnson graph with parameters `n, k`. + Return the Johnson graph with parameters `n, k`. Johnson graphs are a special class of undirected graphs defined from systems of sets. The vertices of the Johnson graph `J(n,k)` are the `k`-element @@ -76,7 +76,7 @@ def JohnsonGraph(n, k): def KneserGraph(n, k): r""" - Returns the Kneser Graph with parameters `n, k`. + Return the Kneser Graph with parameters `n, k`. The Kneser Graph with parameters `n,k` is the graph whose vertices are the `k`-subsets of `[0,1,\dots,n-1]`, and such @@ -148,19 +148,18 @@ def FurerGadget(k, prefix=None): INPUT: - - ``k`` -- The order of the returned Furer gadget, greater than 0. + - ``k`` -- the order of the returned Furer gadget, greater than 0 - - ``prefix`` -- Prefix of to be appended to each vertex label, - so as to individualise the returned Furer gadget. - Must be comparable for equality and hashable. + - ``prefix`` -- prefix of to be appended to each vertex label, + so as to individualise the returned Furer gadget; must be comparable for + equality and hashable OUTPUT: - - ``G`` -- The Furer gadget of order ``k`` + - ``G`` -- the Furer gadget of order ``k`` - - ``coloring`` -- A list of list of vertices, representing the - partition induced by the coloring of ``G``'s - vertices + - ``coloring`` -- list of list of vertices, representing the + partition induced by the coloring of ``G``'s vertices EXAMPLES: @@ -257,18 +256,18 @@ def CaiFurerImmermanGraph(G, twisted=False): INPUT: - - ``G`` -- An undirected graph on which to construct the - Cai-Furer-Immerman graph + - ``G`` -- an undirected graph on which to construct the + Cai-Furer-Immerman graph - - ``twisted`` -- A boolean indicating if the version to construct - is a twisted one or not + - ``twisted`` -- a boolean indicating if the version to construct + is a twisted one or not OUTPUT: - - ``H`` -- The Cai-Furer-Immerman graph on ``G`` + - ``H`` -- the Cai-Furer-Immerman graph on ``G`` - - ``coloring`` -- A list of list of vertices, representing the - partition induced by the coloring on ``H`` + - ``coloring`` -- list of list of vertices, representing the + partition induced by the coloring on ``H`` EXAMPLES: @@ -364,14 +363,14 @@ def EgawaGraph(p, s): INPUT: - ``p`` -- power to which the graph named `Y` in the reference - provided above will be raised + provided above will be raised - ``s`` -- power to which the graph named `X` in the reference - provided above will be raised + provided above will be raised OUTPUT: - - ``G`` -- The Egawa graph with parameters (p,s) + - ``G`` -- the Egawa graph with parameters (p,s) EXAMPLES: @@ -428,18 +427,17 @@ def HammingGraph(n, q, X=None): INPUT: - ``n`` -- power to which ``X`` will be raised to provide vertices - for the Hamming graph + for the Hamming graph - ``q`` -- cardinality of ``X`` - - ``X`` -- list of labels representing the vertices of the - underlying graph the Hamming graph will be based on; if - ``None`` (or left unused), the list `[0, ... , q-1]` - will be used + - ``X`` -- list of labels representing the vertices of the underlying graph + the Hamming graph will be based on; if ``None`` (or left unused), the + list `[0, ... , q-1]` will be used OUTPUT: - - ``G`` -- The Hamming graph with parameters `(n,q,X)` + - ``G`` -- the Hamming graph with parameters `(n,q,X)` EXAMPLES: @@ -505,9 +503,9 @@ def BalancedTree(r, h): INPUT: - - ``r`` -- positive integer `\geq 2`. The degree of the root node. + - ``r`` -- positive integer `\geq 2`; the degree of the root node - - ``h`` -- positive integer `\geq 1`. The height of the balanced tree. + - ``h`` -- positive integer `\geq 1`; the height of the balanced tree OUTPUT: @@ -596,7 +594,7 @@ def BalancedTree(r, h): def BarbellGraph(n1, n2): r""" - Returns a barbell graph with `2*n_1 + n_2` nodes. + Return a barbell graph with `2 n_1 + n_2` nodes. The argument `n_1` must be greater than or equal to 2. @@ -605,15 +603,15 @@ def BarbellGraph(n1, n2): INPUT: - - ``n1`` -- integer `\geq 2`. The order of each of the two - complete graphs. + - ``n1`` -- integer `\geq 2`; the order of each of the two + complete graphs - - ``n2`` -- nonnegative integer. The order of the path graph - connecting the two complete graphs. + - ``n2`` -- nonnegative integer; the order of the path graph + connecting the two complete graphs OUTPUT: - A barbell graph of order `2*n_1 + n_2`. A :class:`ValueError` is + A barbell graph of order `2*n_1 + n_2`. A :exc:`ValueError` is returned if `n_1 < 2` or `n_2 < 0`. PLOTTING: @@ -714,7 +712,7 @@ def BarbellGraph(n1, n2): def LollipopGraph(n1, n2): r""" - Returns a lollipop graph with `n_1 + n_2` nodes. + Return a lollipop graph with `n_1 + n_2` nodes. A lollipop graph is a path graph (order `n_2`) connected to a complete graph (order `n_1`). (A barbell graph minus one of the bells). @@ -885,9 +883,9 @@ def AztecDiamondGraph(n): def DipoleGraph(n): r""" - Returns a dipole graph with n edges. + Return a dipole graph with `n` edges. - A dipole graph is a multigraph consisting of 2 vertices connected with n + A dipole graph is a multigraph consisting of 2 vertices connected with `n` parallel edges. EXAMPLES: @@ -927,7 +925,7 @@ def DipoleGraph(n): def BubbleSortGraph(n): r""" - Returns the bubble sort graph `B(n)`. + Return the bubble sort graph `B(n)`. The vertices of the bubble sort graph are the set of permutations on `n` symbols. Two vertices are adjacent if one can be obtained @@ -943,12 +941,12 @@ def BubbleSortGraph(n): INPUT: - - ``n`` -- positive integer. The number of symbols to permute. + - ``n`` -- positive integer. The number of symbols to permute OUTPUT: The bubble sort graph `B(n)` on `n` symbols. If `n < 1`, a - :class:`ValueError` is returned. + :exc:`ValueError` is returned. EXAMPLES:: @@ -1055,7 +1053,6 @@ def chang_graphs(): sage: [T8.seidel_switching(x, inplace=False).is_isomorphic(G) # needs sage.modules ....: for x, G in zip(s, chang_graphs)] [True, True, True] - """ g1 = Graph("[}~~EebhkrRb_~SoLOIiAZ?LBBxDb?bQcggjHKEwoZFAaiZ?Yf[?dxb@@tdWGkwn", loops=False, multiedges=False) @@ -1068,19 +1065,17 @@ def chang_graphs(): def CirculantGraph(n, adjacency): r""" - Returns a circulant graph with `n` nodes. + Return a circulant graph with `n` nodes. A circulant graph has the property that the vertex `i` is connected with the vertices `i+j` and `i-j` for each `j` in ``adjacency``. INPUT: - - ``n`` -- number of vertices in the graph - ``adjacency`` -- the list of `j` values - PLOTTING: Upon construction, the position dictionary is filled to override the spring-layout algorithm. By convention, each circulant graph will be displayed with the first (0) node at the top, with @@ -1187,27 +1182,27 @@ def CubeGraph(n, embedding=1): - ``n`` -- integer; the dimension of the cube graph - - ``embedding`` -- integer (default: ``1``); two embeddings of the `n`-cube + - ``embedding`` -- integer (default: `1`); two embeddings of the `n`-cube are available: - - ``1``: the `n`-cube is projected inside a regular `2n`-gonal polygon by + - ``1`` -- the `n`-cube is projected inside a regular `2n`-gonal polygon by a skew orthogonal projection. See the :wikipedia:`Hypercube` for more details. - - ``2``: orthogonal projection of the `n`-cube. This orientation shows + - ``2`` -- orthogonal projection of the `n`-cube. This orientation shows columns of independent vertices such that the neighbors of a vertex are located in the columns on the left and on the right. The number of vertices in each column represents rows in Pascal's triangle. See for instance the :wikipedia:`10-cube` for more details. - - ``3``: oblique projection of the `n`-cube. Oblique projection involves + - ``3`` -- oblique projection of the `n`-cube. Oblique projection involves aligning one face parallel to the viewer and projecting at a specified angle, maintaining equal size for edges parallel to one axis while applying fixed foreshortening to others. This method simplifies the representation of a four-dimensional hypercube onto a two-dimensional plane, offering a geometrically consistent visualization. - - ``None`` or ``O``: no embedding is provided + - ``None`` or ``O`` -- no embedding is provided EXAMPLES: @@ -1320,7 +1315,7 @@ def CubeGraph(n, embedding=1): def GoethalsSeidelGraph(k, r): r""" - Returns the graph `\text{Goethals-Seidel}(k,r)`. + Return the graph `\text{Goethals-Seidel}(k,r)`. The graph `\text{Goethals-Seidel}(k,r)` comes from a construction presented in Theorem 2.4 of [GS1970]_. It relies on a :func:`(v,k)-BIBD @@ -1380,13 +1375,13 @@ def GoethalsSeidelGraph(k, r): for i in range(n): PP[i, i] = 0 - G = Graph(PP, format="seidel_adjacency_matrix") + G = Graph(PP, format='seidel_adjacency_matrix') return G def DorogovtsevGoltsevMendesGraph(n): """ - Construct the n-th generation of the Dorogovtsev-Goltsev-Mendes + Construct the `n`-th generation of the Dorogovtsev-Goltsev-Mendes graph. EXAMPLES:: @@ -1408,7 +1403,7 @@ def DorogovtsevGoltsevMendesGraph(n): def FoldedCubeGraph(n): r""" - Returns the folded cube graph of order `2^{n-1}`. + Return the folded cube graph of order `2^{n-1}`. The folded cube graph on `2^{n-1}` vertices can be obtained from a cube graph on `2^n` vertices by merging together opposed @@ -1461,7 +1456,7 @@ def FriendshipGraph(n): INPUT: - ``n`` -- positive integer; the number of copies of `C_3` to use in - constructing `F_n`. + constructing `F_n` OUTPUT: @@ -1677,7 +1672,7 @@ def fib(level, node, y): def GeneralizedPetersenGraph(n, k): r""" - Returns a generalized Petersen graph with `2n` nodes. The variables + Return a generalized Petersen graph with `2n` nodes. The variables `n`, `k` are integers such that `n>2` and `0 (n - 1) // 2: raise ValueError("k must be in 1<= k <=floor((n-1)/2)") - G = Graph(2 * n, name="Generalized Petersen graph (n="+str(n)+",k="+str(k)+")") + G = Graph(2 * n, name="Generalized Petersen graph (n='+str(n)+',k="+str(k)+")") for i in range(n): G.add_edge(i, (i+1) % n) G.add_edge(i, i+n) @@ -2090,7 +2085,7 @@ def TabacjnGraph(n, a, b, r): def HararyGraph(k, n): r""" - Returns the Harary graph on `n` vertices and connectivity `k`, where + Return the Harary graph on `n` vertices and connectivity `k`, where `2 \leq k < n`. A `k`-connected graph `G` on `n` vertices requires the minimum degree @@ -2158,9 +2153,9 @@ def HyperStarGraph(n, k): INPUT: - - ``n`` -- non-negative integer; length of the binary strings + - ``n`` -- nonnegative integer; length of the binary strings - - ``k`` -- non-negative integer; number of 1s per binary string + - ``k`` -- nonnegative integer; number of 1s per binary string EXAMPLES:: @@ -2175,22 +2170,22 @@ def HyperStarGraph(n, k): sage: graphs.HyperStarGraph(-1, 1) Traceback (most recent call last): ... - ValueError: parameters n and k must be non-negative integers satisfying n >= k >= 0 + ValueError: parameters n and k must be nonnegative integers satisfying n >= k >= 0 sage: graphs.HyperStarGraph(1, -1) Traceback (most recent call last): ... - ValueError: parameters n and k must be non-negative integers satisfying n >= k >= 0 + ValueError: parameters n and k must be nonnegative integers satisfying n >= k >= 0 sage: graphs.HyperStarGraph(1, 2) Traceback (most recent call last): ... - ValueError: parameters n and k must be non-negative integers satisfying n >= k >= 0 + ValueError: parameters n and k must be nonnegative integers satisfying n >= k >= 0 AUTHORS: - Michael Yurko (2009-09-01) """ if n < 0 or k < 0 or k > n: - raise ValueError("parameters n and k must be non-negative integers " + raise ValueError("parameters n and k must be nonnegative integers " "satisfying n >= k >= 0") if not n: adj = {} @@ -2237,11 +2232,11 @@ def LCFGraph(n, shift_list, repeats): INPUT: - - ``n`` -- the number of nodes. + - ``n`` -- the number of nodes - - ``shift_list`` -- a list of integer shifts mod `n`. + - ``shift_list`` -- a list of integer shifts mod `n` - - ``repeats`` -- the number of times to repeat the process. + - ``repeats`` -- the number of times to repeat the process EXAMPLES:: @@ -2283,7 +2278,7 @@ def LCFGraph(n, shift_list, repeats): def MycielskiGraph(k=1, relabel=True): r""" - Returns the `k`-th Mycielski Graph. + Return the `k`-th Mycielski Graph. The graph `M_k` is triangle-free and has chromatic number equal to `k`. These graphs show, constructively, that there @@ -2307,10 +2302,10 @@ def MycielskiGraph(k=1, relabel=True): INPUT: - - ``k`` Number of steps in the construction process. + - ``k`` -- number of steps in the construction process - - ``relabel`` Relabel the vertices so their names are the integers - ``range(n)`` where ``n`` is the number of vertices in the graph. + - ``relabel`` -- relabel the vertices so their names are the integers + ``range(n)`` where ``n`` is the number of vertices in the graph EXAMPLES: @@ -2397,7 +2392,7 @@ def MycielskiStep(g): def NKStarGraph(n, k): r""" - Returns the `(n,k)`-star graph. + Return the `(n,k)`-star graph. The vertices of the `(n,k)`-star graph are the set of all arrangements of `n` symbols into labels of length `k`. There are two adjacency rules for the @@ -2460,7 +2455,7 @@ def NKStarGraph(n, k): def NStarGraph(n): r""" - Returns the `n`-star graph. + Return the `n`-star graph. The vertices of the `n`-star graph are the set of permutations on `n` symbols. There is an edge between two vertices if their labels differ @@ -2508,7 +2503,7 @@ def NStarGraph(n): def OddGraph(n): r""" - Returns the Odd Graph with parameter `n`. + Return the Odd Graph with parameter `n`. The Odd Graph with parameter `n` is defined as the Kneser Graph with parameters `2n-1,n-1`. @@ -2546,7 +2541,7 @@ def OddGraph(n): def PaleyGraph(q): r""" - Paley graph with `q` vertices + Paley graph with `q` vertices. Parameter `q` must be the power of a prime number and congruent to 1 mod 4. @@ -2590,7 +2585,7 @@ def PaleyGraph(q): def PasechnikGraph(n): r""" - Pasechnik strongly regular graph on `(4n-1)^2` vertices + Pasechnik strongly regular graph on `(4n-1)^2` vertices. A strongly regular graph with parameters of the orthogonal array graph :func:`~sage.graphs.graph_generators.GraphGenerators.OrthogonalArrayBlockGraph`, @@ -2631,7 +2626,7 @@ def PasechnikGraph(n): def SquaredSkewHadamardMatrixGraph(n): r""" - Pseudo-`OA(2n,4n-1)`-graph from a skew Hadamard matrix of order `4n` + Pseudo-`OA(2n,4n-1)`-graph from a skew Hadamard matrix of order `4n`. A strongly regular graph with parameters of the orthogonal array graph :func:`~sage.graphs.graph_generators.GraphGenerators.OrthogonalArrayBlockGraph`, @@ -2726,17 +2721,17 @@ def SwitchedSquaredSkewHadamardMatrixGraph(n): def HanoiTowerGraph(pegs, disks, labels=True, positions=True): r""" - Returns the graph whose vertices are the states of the + Return the graph whose vertices are the states of the Tower of Hanoi puzzle, with edges representing legal moves between states. INPUT: - ``pegs`` -- the number of pegs in the puzzle, 2 or greater - ``disks`` -- the number of disks in the puzzle, 1 or greater - - ``labels`` -- default: ``True``, if ``True`` the graph contains + - ``labels`` -- (default: ``True``) if ``True`` the graph contains more meaningful labels, see explanation below. For large instances, turn off labels for much faster creation of the graph. - - ``positions`` -- default: ``True``, if ``True`` the graph contains + - ``positions`` -- (default: ``True``) if ``True`` the graph contains layout information. This creates a planar layout for the case of three pegs. For large instances, turn off layout information for much faster creation of the graph. @@ -2831,7 +2826,7 @@ def HanoiTowerGraph(pegs, disks, labels=True, positions=True): Some facts about this graph with `p` pegs and `d` disks: - - only automorphisms are the "obvious" ones -- renumber the pegs. + - only automorphisms are the "obvious" ones -- renumber the pegs - chromatic number is less than or equal to `p` - independence number is `p^{d-1}` @@ -2864,7 +2859,6 @@ def HanoiTowerGraph(pegs, disks, labels=True, positions=True): AUTHOR: - Rob Beezer, (2009-12-26), with assistance from Su Doree - """ # sanitize input from sage.rings.integer import Integer @@ -2975,7 +2969,7 @@ def HanoiTowerGraph(pegs, disks, labels=True, positions=True): def line_graph_forbidden_subgraphs(): r""" - Returns the 9 forbidden subgraphs of a line graph. + Return the 9 forbidden subgraphs of a line graph. See the :wikipedia:`Line_graph` for more information. @@ -2994,7 +2988,6 @@ def line_graph_forbidden_subgraphs(): Graph on 6 vertices, Graph on 6 vertices, Graph on 5 vertices] - """ from sage.graphs.graph import Graph from sage.graphs.generators.basic import ClawGraph @@ -3060,7 +3053,7 @@ def line_graph_forbidden_subgraphs(): def petersen_family(generate=False): r""" - Returns the Petersen family + Return the Petersen family. The Petersen family is a collection of 7 graphs which are the forbidden minors of the linklessly embeddable graphs. For more information see the @@ -3068,7 +3061,7 @@ def petersen_family(generate=False): INPUT: - - ``generate`` (boolean) -- whether to generate the family from the + - ``generate`` -- boolean; whether to generate the family from the `\Delta-Y` transformations. When set to ``False`` (default) a hardcoded version of the graphs (with a prettier layout) is returned. @@ -3170,7 +3163,7 @@ def SierpinskiGasketGraph(n): INPUT: - - `n` -- an integer + - ``n`` -- integer OUTPUT: @@ -3402,7 +3395,7 @@ def rec(H, kk): def WheelGraph(n): """ - Returns a Wheel graph with n nodes. + Return a Wheel graph with `n` nodes. A Wheel graph is a basic structure where one node is connected to all other nodes and those (outer) nodes are connected cyclically. @@ -3573,11 +3566,11 @@ def WindmillGraph(k, n): def trees(vertices): r""" - Returns a generator of the distinct trees on a fixed number of vertices. + Return a generator of the distinct trees on a fixed number of vertices. INPUT: - - ``vertices`` -- the size of the trees created. + - ``vertices`` -- the size of the trees created OUTPUT: @@ -3620,7 +3613,7 @@ def trees(vertices): return iter(TreeIterator(vertices)) -def nauty_gentreeg(options="", debug=False): +def nauty_gentreeg(options='', debug=False): r""" Return a generator which creates non-isomorphic trees from nauty's gentreeg program. @@ -3717,7 +3710,7 @@ def nauty_gentreeg(options="", debug=False): ... ValueError: wrong format of parameter options sage: list(graphs.nauty_gentreeg("3 -x", debug=True)) - ['>E Usage: ...gentreeg [-D#] [-Z#:#] [-ulps] [-q] n [res/mod] ... + ['>E Usage: ...gentreeg [-D#] [-Z#:#] [-ulps] [-q] n... [res/mod] ... sage: list(graphs.nauty_gentreeg("3", debug=True)) ['>A ...gentreeg ...\n', Graph on 3 vertices] """ @@ -3760,10 +3753,10 @@ def RingedTree(k, vertex_labels=True): INPUT: - - ``k`` -- the number of levels of the ringed tree. + - ``k`` -- the number of levels of the ringed tree - - ``vertex_labels`` (boolean) -- whether to label vertices as binary words - (default) or as integers. + - ``vertex_labels`` -- boolean; whether to label vertices as binary words + (default) or as integers EXAMPLES:: @@ -3828,16 +3821,16 @@ def RingedTree(k, vertex_labels=True): def MathonPseudocyclicMergingGraph(M, t): r""" - Mathon's merging of classes in a pseudo-cyclic 3-class association scheme + Mathon's merging of classes in a pseudo-cyclic 3-class association scheme. Construct strongly regular graphs from p.97 of [BL1984]_. INPUT: - - ``M`` -- the list of matrices in a pseudo-cyclic 3-class association scheme. - The identity matrix must be the first entry. + - ``M`` -- the list of matrices in a pseudo-cyclic 3-class association scheme; + the identity matrix must be the first entry - - ``t`` (integer) -- the number of the graph, from 0 to 2. + - ``t`` -- integer; the number of the graph, from 0 to 2 .. SEEALSO:: @@ -3901,7 +3894,7 @@ def MathonPseudocyclicStronglyRegularGraph(t, G=None, L=None): INPUT: - - ``t`` -- a positive integer + - ``t`` -- positive integer - ``G`` -- if ``None`` (default), try to construct the necessary graph with parameters `(4t+1,2t,t-1,t)`, otherwise use the user-supplied one, @@ -3948,12 +3941,12 @@ def MathonPseudocyclicStronglyRegularGraph(t, G=None, L=None): sage: G3x3 = graphs.MathonPseudocyclicStronglyRegularGraph(2, G=G, L=L) sage: G3x3.is_strongly_regular(parameters=True) (441, 220, 109, 110) - sage: G3x3.automorphism_group(algorithm="bliss").order() # optional - bliss + sage: G3x3.automorphism_group(algorithm='bliss').order() # optional - bliss 27 sage: G9 = graphs.MathonPseudocyclicStronglyRegularGraph(2) sage: G9.is_strongly_regular(parameters=True) (441, 220, 109, 110) - sage: G9.automorphism_group(algorithm="bliss").order() # optional - bliss + sage: G9.automorphism_group(algorithm='bliss').order() # optional - bliss 9 TESTS:: @@ -4034,7 +4027,7 @@ def Acon(i, j): def TuranGraph(n, r): r""" - Returns the Turan graph with parameters `n, r`. + Return the Turan graph with parameters `n, r`. Turan graphs are complete multipartite graphs with `n` vertices and `r` subsets, denoted `T(n,r)`, with the property that the sizes of the subsets @@ -4119,9 +4112,9 @@ def MuzychukS6Graph(n, d, Phi='fixed', Sigma='fixed', verbose=False): INPUT: - - ``n`` (integer) -- a prime power + - ``n`` -- integer; a prime power - - ``d`` (integer) -- must be odd if `n` is odd + - ``d`` -- integer; must be odd if `n` is odd - ``Phi`` is an optional parameter of the construction; it must be either @@ -4137,9 +4130,10 @@ def MuzychukS6Graph(n, d, Phi='fixed', Sigma='fixed', verbose=False): - ``'fixed'`` -- this will generate a fixed default `\Sigma`, or - - ``'random'`` -- `\Sigma` is generated at random. + - ``'random'`` -- `\Sigma` is generated at random - - ``verbose`` (Boolean) -- default is ``False``. If ``True``, print progress information + - ``verbose`` -- boolean (default: ``False``); if ``True``, print progress + information .. SEEALSO:: @@ -4203,9 +4197,9 @@ def MuzychukS6Graph(n, d, Phi='fixed', Sigma='fixed', verbose=False): from sage.rings.integer_ring import ZZ from time import time - assert d > 1, 'd must be at least 2' + assert d > 1, 'd must be at least 2' assert is_even(n * (d-1)), 'n must be even or d must be odd' - assert is_prime_power(n), 'n must be a prime power' + assert is_prime_power(n), 'n must be a prime power' t = time() # build L, L_i and the design @@ -4369,9 +4363,9 @@ def CubeConnectedCycle(d): INPUT: - - ``d`` -- The dimension of the desired hypercube as well as the length - of the cycle to be placed at each vertex of the `d`-dimensional - hypercube. `d` must be a positive integer. + - ``d`` -- positive integer; the dimension of the desired hypercube as well + as the length of the cycle to be placed at each vertex of the + `d`-dimensional hypercube EXAMPLES: @@ -4430,3 +4424,321 @@ def CubeConnectedCycle(d): G.add_edge((x, y), (x ^ (1 << y), y)) return G + + +def StaircaseGraph(n): + r""" + Return a staircase graph with `2n` nodes + + For `n \geq 3`, the staircase graph of order `2n` is the graph obtained + from the ladder graph of order `2n - 2`, i.e., ``graphs.LadderGraph(n - 1)`` + by introducing two new nodes `2n - 2` and `2n - 1`, and then joining the + node `2n - 2` with `0` and `n - 1`, the node `2n - 1` with `n - 2` and + `2n - 3`, and the nodes `2n - 2` and `2n - 1` with each other. + + Note that ``graphs.StaircaseGraph(4)`` is also known as the ``Bicorn + graph``. It is the only brick that has a unique `b`-invariant edge. + + PLOTTING: + + Upon construction, the position dictionary is filled to override + the spring-layout algorithm. By convention, each staircase graph will be + displayed horizontally, with the first `n - 1` nodes displayed from left to + right on the top horizontal line, the second `n - 1` nodes displayed from + left to right on the middle horizontal line, and the last two nodes + displayed at the bottom two corners. + + INPUT: + + - ``n`` -- an integer at least 3; number of nodes is `2n` + + OUTPUT: + + - ``G`` -- a staircase graph of order `2n`; note that a + :class:`ValueError` is returned if `n < 3` + + EXAMPLES: + + Construct and show a staircase graph with 10 nodes:: + + sage: g = graphs.StaircaseGraph(5) + sage: g.show() # long time # needs sage.plot + + Construct and show the Bicorn graph. Note that the edge `(1, 4)` is the + unique `b`-invariant edge:: + + sage: bicornGraph = graphs.StaircaseGraph(4) + sage: bicornGraph.show() # long time # needs sage.plot + + Create several staircase graphs in a Sage graphics array:: + + sage: # needs sage.plots + sage: g = [] + sage: j = [] + sage: for i in range(9): + ....: k = graphs.StaircaseGraph(i+3) + ....: g.append(k) + sage: for i in range(3): + ....: n = [] + ....: for m in range(3): + ....: n.append(g[3*i + m].plot(vertex_size=50 - 4*(3*i+m), vertex_labels=False)) + ....: j.append(n) + sage: G = graphics_array(j) + sage: G.show() # long time + + TESTS: + + The input parameter must be an integer that is at least 3:: + + sage: G = graphs.StaircaseGraph(2) + Traceback (most recent call last): + ... + ValueError: parameter n must be at least 3 + + REFERENCES: + + - [LM2024]_ + + .. SEEALSO:: + + :meth:`~sage.graphs.graph_generators.GraphGenerators.LadderGraph` + + AUTHORS: + + - Janmenjaya Panda (2024-06-09) + """ + if n < 3: + raise ValueError("parameter n must be at least 3") + + pos_dict = { + 0: (0, 1), + n - 2: (n, 1), + 2*n - 2: (0, -1), + 2*n - 1: (n, -1) + } + + edges = [ + (0, n - 1), + (0, 2*n - 2), + (n - 2, 2*n - 3), + (n - 2, 2*n - 1), + (n - 1, 2*n - 2), + (2*n - 3, 2*n - 1), + (2*n - 2, 2*n - 1) + ] + + for v in range(1, n - 2): + pos_dict[v] = (v + 1, 1) + edges.append((v, v + n - 1)) + + for v in range(n - 1, 2*n - 2): + pos_dict[v] = (v - n + 2, 0) + + G = Graph(2 * n, pos=pos_dict, name="Staircase graph") + G.add_edges(edges) + G.add_path(list(range(n - 1))) + G.add_path(list(range(n - 1, 2*n - 2))) + return G + + +def BiwheelGraph(n): + r""" + Return a biwheel graph with `2n` nodes + + For `n \geq 4`, the biwheel graph of order `2n` is the planar + bipartite graph obtained from the cycle graph of order `2n - 2`, i.e., + ``graphs.CycleGraph(2*n - 2)`` (called the `rim` of the biwheel graph) by + introducing two new nodes `2n - 2` and `2n - 1` (called the *hubs* of the + biwheel graph), and then joining the node `2n - 2` with the odd indexed + nodes up to `2n - 3` and joining the node `2n - 1` with the even indexed + nodes up to `2n - 4`. + + PLOTTING: + + Upon construction, the position dictionary is filled to override + the spring-layout algorithm. By convention, each biwheel graph will be + displayed with the first (0) node at the right if `n` is even or + otherwise at an angle `\pi / (2n - 2)` with respect to the origin, with the + rest of the nodes up to `2n - 3` following in a counterclockwise manner. + Note that the last two nodes, i.e., the hubs `2n - 2` and `2n - 1` will + be displayed at the coordinates `(-1/3, 0)` and `(1/3, 0)` respectively. + + INPUT: + + - ``n`` -- an integer at least 4; number of nodes is `2n` + + OUTPUT: + + - ``G`` -- a biwheel graph of order `2n`; note that a + :class:`ValueError` is returned if `n < 4` + + EXAMPLES: + + Construct and show a biwheel graph with 10 nodes:: + + sage: g = graphs.BiwheelGraph(5) + sage: g.show() # long time # needs sage.plot + sage: g.is_planar() + True + sage: g.is_bipartite() + True + + Create several biwheel graphs in a Sage graphics array:: + + sage: # needs sage.plots + sage: g = [] + sage: j = [] + sage: for i in range(9): + ....: k = graphs.BiwheelGraph(i+4) + ....: g.append(k) + sage: for i in range(3): + ....: n = [] + ....: for m in range(3): + ....: n.append(g[3*i + m].plot(vertex_size=50 - 4*(3*i+m), vertex_labels=False)) + ....: j.append(n) + sage: G = graphics_array(j) + sage: G.show() # long time + + TESTS: + + The input parameter must be an integer that is at least 4:: + + sage: G = graphs.BiwheelGraph(3) + Traceback (most recent call last): + ... + ValueError: parameter n must be at least 4 + + REFERENCES: + + - [LM2024]_ + + .. SEEALSO:: + + :meth:`~sage.graphs.graph_generators.GraphGenerators.WheelGraph`, + :meth:`~sage.graphs.graph_generators.GraphGenerators.TruncatedBiwheelGraph` + + AUTHORS: + + - Janmenjaya Panda (2024-06-09) + """ + if n < 4: + raise ValueError("parameter n must be at least 4") + + angle_param = 0 + + if n % 2: + from math import pi + angle_param = pi / (2*n - 2) + + G = Graph(2 * n, name="Biwheel graph") + pos_dict = G._circle_embedding(list(range(2*n - 2)), angle=angle_param, return_dict=True) + edges = [] + + from sage.rings.rational_field import QQ + pos_dict[2*n - 2] = (-QQ((1, 3)), 0) + pos_dict[2*n - 1] = (QQ((1, 3)), 0) + + for i in range(2*n - 2): + if i % 2 == 0: + edges += [(i, 2*n - 1)] + else: + edges += [(i, 2*n - 2)] + + G.set_pos(pos_dict) + G.add_cycle(list(range(2*n - 2))) + G.add_edges(edges) + return G + + +def TruncatedBiwheelGraph(n): + r""" + Return a truncated biwheel graph with `2n` nodes + + For `n \geq 3`, the truncated biwheel graph of order `2n` is the graph + obtained from the path graph of order `2n - 2`, i.e., + ``graphs.PathGraph(2*n - 2)`` by introducing two new nodes `2n - 2` and + `2n - 1`, and then joining the node `2n - 2` with the odd indexed nodes + up to `2n - 3`, joining the node `2n - 1` with the even indexed nodes up to + `2n - 4` and adding the edges `(0, 2n - 2)` and `(2n - 3, 2n - 1)`. + + PLOTTING: + + Upon construction, the position dictionary is filled to override the + spring-layout algorithm. By convention, each truncated biwheel graph will + be displayed horizontally, with the first `2n - 2` nodes displayed from + left to right on the middle horizontal line and the nodes `2n - 2` and + `2n - 1` displayed at the top and the bottom central positions + respectively. + + INPUT: + + - ``n`` -- an integer at least 3; number of nodes is `2n` + + OUTPUT: + + - ``G`` -- a truncated biwheel graph of order `2n`; note that a + :class:`ValueError` is returned if `n < 3` + + EXAMPLES: + + Construct and show a truncated biwheel graph with 10 nodes:: + + sage: g = graphs.TruncatedBiwheelGraph(5) + sage: g.show() # long time # needs sage.plot + + Create several truncated biwheel graphs in a Sage graphics array:: + + sage: # needs sage.plots + sage: g = [] + sage: j = [] + sage: for i in range(9): + ....: k = graphs.TruncatedBiwheelGraph(i+3) + ....: g.append(k) + sage: for i in range(3): + ....: n = [] + ....: for m in range(3): + ....: n.append(g[3*i + m].plot(vertex_size=50 - 4*(3*i+m), vertex_labels=False)) + ....: j.append(n) + sage: G = graphics_array(j) + sage: G.show() # long time + + TESTS: + + The input parameter must be an integer that is at least 3:: + + sage: G = graphs.TruncatedBiwheelGraph(2) + Traceback (most recent call last): + ... + ValueError: parameter n must be at least 3 + + REFERENCES: + + - [LM2024]_ + + .. SEEALSO:: + + :meth:`~sage.graphs.graph_generators.GraphGenerators.WheelGraph`, + :meth:`~sage.graphs.graph_generators.GraphGenerators.BiwheelGraph` + + AUTHORS: + + - Janmenjaya Panda (2024-06-09) + """ + if n < 3: + raise ValueError("parameter n must be at least 3") + + pos_dict = {2*n - 2: (0, n), 2*n - 1: (0, -n)} + edges = [(0, 2*n - 2), (2*n - 3, 2*n - 1)] + + for v in range(2*n - 2): + pos_dict[v] = (2*(v-n) + 3, 0) + if v % 2 == 0: + edges += [(v, 2*n - 1)] + else: + edges += [(v, 2*n - 2)] + + G = Graph(2 * n, pos=pos_dict, name="Truncated biwheel graph") + G.add_path(list(range(2*n - 2))) + G.add_edges(edges) + + return G diff --git a/src/sage/graphs/generators/intersection.py b/src/sage/graphs/generators/intersection.py index 7087ca21752..3cdb3c681b8 100644 --- a/src/sage/graphs/generators/intersection.py +++ b/src/sage/graphs/generators/intersection.py @@ -31,7 +31,7 @@ def IntervalGraph(intervals, points_ordered=False): INPUT: - - ``intervals`` -- the list of pairs `(a_i,b_i)` defining the graph. + - ``intervals`` -- the list of pairs `(a_i,b_i)` defining the graph - ``points_ordered`` -- states whether every interval `(a_i,b_i)` of `intervals` satisfies `a_i= 0 and p <= 1): raise ValueError("parameter p is a probability, and so should be a real value between 0 and 1") @@ -290,9 +289,9 @@ def RandomRegularBipartite(n1, n2, d1, set_position=False, seed=None): - ``n1``, ``n2`` -- number of vertices in each side - - ``d1`` -- degree of the vertices in the set of cardinality `n1`. + - ``d1`` -- degree of the vertices in the set of cardinality `n1` - - ``set_position`` -- boolean (default ``False``); if set to ``True``, we + - ``set_position`` -- boolean (default: ``False``); if set to ``True``, we assign positions to the vertices so that the set of cardinality `n1` is on the line `y=1` and the set of cardinality `n2` is on the line `y=0`. @@ -450,16 +449,16 @@ def RandomBlockGraph(m, k, kmax=None, incidence_structure=False, seed=None): INPUT: - - ``m`` -- integer; number of blocks (at least one). + - ``m`` -- integer; number of blocks (at least one) - - ``k`` -- integer; minimum number of vertices of a block (at least two). + - ``k`` -- integer; minimum number of vertices of a block (at least two) - - ``kmax`` -- integer (default: ``None``) By default, each block has `k` + - ``kmax`` -- integer (default: ``None``); by default, each block has `k` vertices. When the parameter `kmax` is specified (with `kmax \geq k`), the number of vertices of each block is randomly chosen between `k` and `kmax`. - - ``incidence_structure`` -- boolean (default: ``False``) when set to + - ``incidence_structure`` -- boolean (default: ``False``); when set to ``True``, the incidence structure of the graphs is returned instead of the graph itself, that is the list of the lists of vertices in each block. This is useful for the creation of some hypergraphs. @@ -613,7 +612,7 @@ def RandomBoundedToleranceGraph(n, seed=None): INPUT: - - ``n`` -- number of vertices of the random graph. + - ``n`` -- number of vertices of the random graph - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) @@ -666,9 +665,9 @@ def RandomGNM(n, m, dense=False, seed=None): INPUT: - - ``n`` -- number of vertices. + - ``n`` -- number of vertices - - ``m`` -- number of edges. + - ``m`` -- number of edges - ``dense`` -- whether to use NetworkX's :func:`dense_gnm_random_graph` or :func:`gnm_random_graph` @@ -825,7 +824,7 @@ def RandomHolmeKim(n, m, p, seed=None): def RandomIntervalGraph(n, seed=None): r""" - Returns a random interval graph. + Return a random interval graph. An interval graph is built from a list `(a_i,b_i)_{1\leq i \leq n}` of intervals : to each interval of the list is associated one @@ -845,6 +844,11 @@ def RandomIntervalGraph(n, seed=None): used to create the graph are saved with the graph and can be recovered using ``get_vertex()`` or ``get_vertices()``. + .. SEEALSO:: + + - :meth:`sage.graphs.generators.intersection.IntervalGraph` + - :meth:`sage.graphs.generators.random.RandomProperIntervalGraph` + INPUT: - ``n`` -- integer; the number of vertices in the random graph @@ -863,18 +867,207 @@ def RandomIntervalGraph(n, seed=None): """ if seed is not None: set_random_seed(seed) - from sage.misc.prandom import random from sage.graphs.generators.intersection import IntervalGraph intervals = [tuple(sorted((random(), random()))) for i in range(n)] return IntervalGraph(intervals, True) +def RandomProperIntervalGraph(n, seed=None): + r""" + Return a random proper interval graph. + + An interval graph is built from a list `(a_i,b_i)_{1\leq i \leq n}` of + intervals : to each interval of the list is associated one vertex, two + vertices being adjacent if the two corresponding (closed) intervals + intersect. An interval graph is proper if no interval of the list properly + contains another interval. + Observe that proper interval graphs coincide with unit interval graphs. + See the :wikipedia:`Interval_graph` for more details. + + This method implements the random proper interval graph generator proposed + in [SYKU2010]_ which outputs graphs with uniform probability. The time + complexity of this generator is in `O(n^3)`. + + .. NOTE:: + + The vertices are named 0, 1, 2, and so on. The intervals + used to create the graph are saved with the graph and can + be recovered using ``get_vertex()`` or ``get_vertices()``. + + .. SEEALSO:: + + - :meth:`sage.graphs.generators.intersection.IntervalGraph` + - :meth:`sage.graphs.generators.random.RandomIntervalGraph` + + INPUT: + + - ``n`` -- positive integer; the number of vertices of the graph + + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + + EXAMPLES:: + + sage: from sage.graphs.generators.random import RandomProperIntervalGraph + sage: G = RandomProperIntervalGraph(10) + sage: G.is_interval() + True + + TESTS:: + + sage: from sage.graphs.generators.random import RandomProperIntervalGraph + sage: RandomProperIntervalGraph(0) + Graph on 0 vertices + sage: RandomProperIntervalGraph(1) + Graph on 1 vertex + sage: RandomProperIntervalGraph(-1) + Traceback (most recent call last): + ... + ValueError: parameter n must be >= 0 + """ + if seed is not None: + set_random_seed(seed) + if n < 0: + raise ValueError('parameter n must be >= 0') + if not n: + return Graph() + + from sage.graphs.generators.intersection import IntervalGraph + + if n == 1: + return IntervalGraph([[0, 1]]) + + from sage.combinat.combinat import catalan_number + from sage.functions.other import binomial + + # let np = n' = n - 1 + np = n - 1 + + # Choose case 1 with probability C(n') / (C(n') + binomial(n', n' // 2)) + cnp = catalan_number(np) + if random() < cnp / (cnp + binomial(np, np // 2)): + # Case 1: Generate a balanced nonnegative string (that can be + # reversible) of length 2n' as follows. We generate the sequence of '[' + # and ']' from left to right. Assume we have already chosen k symbols + # x_1x_2...x_k, with k < 2n'. The next symbol x_{k+1} is '[' with + # probability (h_x(k) + 2) (r - h_x(k) + 1) / (2 (r + 1) (h_x(k) + 1)) + # where r = 2n' - k - 1 and + # h_x(k) = 0 if k == 0, h_x(k - 1) + 1 if x_i == 0 else h_x(k - 1) - 1. + # + # Since the i-th interval starts at the i-th symbol [ and ends at the + # i-th symbol ], we directly build the intervals + intervals = [[0, 2*n] for _ in range(n)] + L = 1 # next starting interval + R = 0 # next ending interval + hx = [0] + r = 2 * np - 1 + for k in range(2 * np): + # Choose symbol x_{k+1} + if random() < ((hx[k] + 2) * (r - hx[k] + 1)) / (2 * (r + 1) * (hx[k] + 1)): + # We have choosen symbol [, so we start an interval + hx.append(hx[k] + 1) + intervals[L][0] = k + 1 + L += 1 + else: + # We have choosen symbol ], so we end an interval + hx.append(hx[k] - 1) + intervals[R][1] = k + 1 + R += 1 + r -= 1 + # Add the last symbol, ], to get a sequence of length 2*n + intervals[R][1] = k + 2 + + # Finally return the interval graph + return IntervalGraph(intervals) + + # Otherwise, generate a balanced nonnegative reversible string of length + # 2n'. This case happens with small probability and is way more complex. + # The string is of the form x_1x_2...x_ny_n..y_2y_1, where y_i is ] if x_i + # is [, and [ otherwise. + + from sage.misc.cachefunc import cached_function + + @cached_function + def compute_C(n, h): + """ + Return C(n, h) as defined below. + + Recall that the Catalan number is C(n) = binomial(2n, n) / (n + 1) + and let C(n, h) = 0 if h > n. The following equations hold for each + integers i and k with 0 <= i <= k. + + 1. C(2k, 2i + 1) = 0, C(2k + 1, 2i) = 0, + 2. C(2k, 0) = C(k), C(k, k) = 1, and + 3. C(k, i) = C(k - 1, i - 1) + C(k - 1, i + 1). + """ + if h > n: + return 0 + if n % 2 != h % 2: + # C(2k, 2i + 1) = 0 and C(2k + 1, 2i) = 0 + # i.e., if n and h have different parity + return 0 + if n == h: + return 1 + if not h and not n % 2: + # C(2k, 0) = C(k) + return catalan_number(n // 2) + # Otherwise, C(k, i) = C(k - 1, i - 1) + C(k - 1, i + 1) + return compute_C(n - 1, h - 1) + compute_C(n - 1, h + 1) + + # We first fill an array hx of length n, backward, and then use it to choose + # the symbols x_1x_2...x_n (and so symbols y_n...y_2y_1). + hx = [0] * n + hx[1] = 1 + # Set hx[np] = h with probability C(np, h) / binomial(np, np // 2) + number = randint(0, binomial(np, np // 2)) + total = 0 + for h in range(np + 1): + total += compute_C(np, h) + if number < total: + break + hx[np] = h + + x = [']'] + y = ['['] + for i in range(np - 1, 0, -1): + # Choose symbol x_i + if random() < (hx[i + 1] + 2) * (i - hx[i + 1] + 1) / (2 * (i + 1) * (hx[i + 1] + 1)): + hx[i] = hx[i + 1] + 1 + x.append(']') + y.append('[') + else: + hx[i] = hx[i + 1] - 1 + x.append('[') + y.append(']') + x.append('[') + x.reverse() + y.append(']') + x.extend(y) + + # We now turn the sequence of symbols to proper intervals. + # The i-th intervals starts from the index of the i-th symbol [ in + # symbols and ends at the position of the i-th symbol ]. + intervals = [[0, 2 * n] for _ in range(n)] + L = 0 # next starting interval + R = 0 # next ending interval + for pos, symbol in enumerate(x): + if symbol == '[': + intervals[L][0] = pos + L += 1 + else: + intervals[R][1] = pos + R += 1 + + # We finally return the resulting interval graph + return IntervalGraph(intervals) + + # Random Chordal Graphs def growing_subtrees(T, k): r""" - Return a list of the vertex sets of ``n`` randomly chosen subtrees of ``T``. + Return a list of the vertex sets of `n` randomly chosen subtrees of `T`. For a tree of order `n`, the collection contains `n` subtrees with maximum order `k` and average order `\frac{k + 1}{2}`. @@ -929,7 +1122,7 @@ def growing_subtrees(T, k): def connecting_nodes(T, l): r""" - Return a list of the vertex sets of ``n`` randomly chosen subtrees of ``T``. + Return a list of the vertex sets of `n` randomly chosen subtrees of `T`. This method is part of :meth:`~sage.graphs.generators.random.RandomChordalGraph`. @@ -1028,7 +1221,7 @@ def connecting_nodes(T, l): def pruned_tree(T, f, s): r""" - Return a list of the vertex sets of ``n`` randomly chosen subtrees of ``T``. + Return a list of the vertex sets of `n` randomly chosen subtrees of `T`. This method is part of :meth:`~sage.graphs.generators.random.RandomChordalGraph`. @@ -1050,7 +1243,7 @@ def pruned_tree(T, f, s): - ``T`` -- a tree - ``f`` -- a rational number; the edge deletion fraction. This value must be - chosen in `[0..1]`. + chosen in `[0..1]` - ``s`` -- a real number between 0 and 1; selection barrier for the size of trees @@ -1107,7 +1300,7 @@ def pruned_tree(T, f, s): return S -def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, seed=None): +def RandomChordalGraph(n, algorithm='growing', k=None, l=None, f=None, s=None, seed=None): r""" Return a random chordal graph of order ``n``. @@ -1127,23 +1320,23 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, s - ``n`` -- integer; the number of nodes of the graph - - ``algorithm`` -- string (default: ``"growing"``); the choice of the + - ``algorithm`` -- string (default: ``'growing'``); the choice of the algorithm for randomly selecting `n` subtrees of a random tree of order `n`. Possible choices are: - - ``"growing"`` -- for each subtree `T_i`, the algorithm picks a size + - ``'growing'`` -- for each subtree `T_i`, the algorithm picks a size `k_i` randomly from `[1,k]`. Then a random node of `T` is chosen as the first node of `T_i`. In each of the subsequent `k_i - 1` iterations, it picks a random node in the neighborhood of `T_i` and adds it to `T_i`. - - ``"connecting"`` -- for each subtree `T_i`, it first selects `k_i` nodes + - ``'connecting'`` -- for each subtree `T_i`, it first selects `k_i` nodes of `T`, where `k_i` is a random integer from a Poisson distribution with mean `l`. `T_i` is then generated to be the minimal subtree containing the selected `k_i` nodes. This implies that a subtree will most likely have many more nodes than those selected initially, and this must be taken into consideration when choosing `l`. - - ``"pruned"`` -- for each subtree `T_i`, it randomly selects a fraction + - ``'pruned'`` -- for each subtree `T_i`, it randomly selects a fraction `f` of the edges on the tree and removes them. The number of edges to delete, say `l`, is calculated as `\lfloor (n - 1) f \rfloor`, which will leave `l + 1` subtrees in total. Then, it determines the sizes of the `l @@ -1178,13 +1371,13 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, s EXAMPLES:: sage: from sage.graphs.generators.random import RandomChordalGraph - sage: T = RandomChordalGraph(20, algorithm="growing", k=5) + sage: T = RandomChordalGraph(20, algorithm='growing', k=5) sage: T.is_chordal() True - sage: T = RandomChordalGraph(20, algorithm="connecting", l=3) # needs numpy + sage: T = RandomChordalGraph(20, algorithm='connecting', l=3) # needs numpy sage: T.is_chordal() # needs numpy True - sage: T = RandomChordalGraph(20, algorithm="pruned", f=1/3, s=.5) + sage: T = RandomChordalGraph(20, algorithm='pruned', f=1/3, s=.5) sage: T.is_chordal() True @@ -1197,19 +1390,19 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, s Traceback (most recent call last): ... NotImplementedError: unknown algorithm 'Carmen Cru' - sage: RandomChordalGraph(3, algorithm="growing", k=0) + sage: RandomChordalGraph(3, algorithm='growing', k=0) Traceback (most recent call last): ... ValueError: parameter k must be >= 1 - sage: RandomChordalGraph(3, algorithm="connecting", l=0) + sage: RandomChordalGraph(3, algorithm='connecting', l=0) Traceback (most recent call last): ... ValueError: parameter l must be > 0 - sage: RandomChordalGraph(3, algorithm="pruned", f=2) + sage: RandomChordalGraph(3, algorithm='pruned', f=2) Traceback (most recent call last): ... ValueError: parameter f must be 0 <= f <= 1 - sage: RandomChordalGraph(3, algorithm="pruned", s=1) + sage: RandomChordalGraph(3, algorithm='pruned', s=1) Traceback (most recent call last): ... ValueError: parameter s must be 0 < s < 1 @@ -1291,15 +1484,12 @@ def RandomLobster(n, p, q, seed=None): - ``n`` -- expected number of vertices in the backbone - - ``p`` -- probability of adding an edge to the - backbone + - ``p`` -- probability of adding an edge to the backbone - - ``q`` -- probability of adding an edge (claw) to the - arms + - ``q`` -- probability of adding an edge (claw) to the arms - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random - number generator (default: ``None``). - + number generator (default: ``None``) EXAMPLES: @@ -1333,7 +1523,7 @@ def RandomLobster(n, p, q, seed=None): def RandomTree(n, seed=None): r""" - Returns a random tree on `n` nodes numbered `0` through `n-1`. + Return a random tree on `n` nodes numbered `0` through `n-1`. By Cayley's theorem, there are `n^{n-2}` trees with vertex set `\{0,1,\dots,n-1\}`. This constructor chooses one of these uniformly @@ -1348,7 +1538,7 @@ def RandomTree(n, seed=None): INPUT: - - ``n`` -- number of vertices in the tree + - ``n`` -- number of vertices in the tree - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) @@ -1433,7 +1623,6 @@ def RandomTreePowerlaw(n, gamma=3, tries=1000, seed=None): - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) - EXAMPLES: We check that the generated graph is a tree:: @@ -1703,7 +1892,7 @@ def RandomShell(constructor, seed=None): INPUT: - - ``constructor`` -- a list of 3-tuples `(n, m, d)`, each representing a + - ``constructor`` -- list of 3-tuples `(n, m, d)`, each representing a shell, where: - ``n`` -- the number of vertices in the shell @@ -1801,9 +1990,9 @@ def _auxiliary_random_forest_word(n, k): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``k`` -- an integer + - ``k`` -- integer OUTPUT: @@ -1899,10 +2088,10 @@ def _contour_and_graph_from_words(pendant_word, forest_word): - ``seq`` is a sequence of pairs (label, integer) representing the contour walk along the `k`-gonal forest associated with the words - ``pendant_word`` and ``forest_word``. + ``pendant_word`` and ``forest_word`` - - ``G`` is the `k`-gonal forest associated with the words ``pendant_word`` - and ``forest_word``. + - ``G`` -- the `k`-gonal forest associated with the words ``pendant_word`` + and ``forest_word`` The underlying bijection from words to `k`-gonal forests is described in Section 5.1 of [PS2006]_. The ``pendant_word`` corresponds to the factor @@ -2038,8 +2227,8 @@ def RandomTriangulation(n, set_position=False, k=3, seed=None): - ``k`` -- the size of the outer face - - ``set_position`` -- boolean (default ``False``); if set to ``True``, this - will compute coordinates for a planar drawing of the graph. + - ``set_position`` -- boolean (default: ``False``); if set to ``True``, this + will compute coordinates for a planar drawing of the graph - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) @@ -2163,7 +2352,7 @@ def rotate_word_to_next_occurrence(word): assert graph.num_edges() == 3*n - 3 - k assert graph.num_verts() == n if set_position: - graph.layout(layout="planar", save_pos=True) + graph.layout(layout='planar', save_pos=True) return graph @@ -2187,13 +2376,11 @@ def blossoming_contour(t, shift=0, seed=None): INPUT: - - `t` -- a binary tree (non-empty) - - - ``shift`` -- an integer (default `0`), used as a starting index + - ``t`` -- a binary tree (non-empty) - OUTPUT: + - ``shift`` -- integer (default: `0`); used as a starting index - contour word of a random blossoming of `t` + OUTPUT: contour word of a random blossoming of `t` EXAMPLES:: @@ -2266,7 +2453,7 @@ def RandomBicubicPlanar(n, seed=None): INPUT: - `n` -- an integer (at least `1`) + - ``n`` -- integer (at least `1`) - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) @@ -2395,7 +2582,7 @@ def RandomUnitDiskGraph(n, radius=.1, side=1, seed=None): - ``n`` -- number of nodes - - ``radius`` -- float (default: ``0.1``); two vertices at distance less than + - ``radius`` -- float (default: `0.1`); two vertices at distance less than ``radius`` are connected by an edge - ``side`` -- float (default: ``1``); indicate the side of the area in which diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index 50b1905b7b0..d490eda7830 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -7,6 +7,7 @@ # Copyright (C) 2006 Robert L. Miller # and Emily A. Kirkman # Copyright (C) 2009 Michael C. Yurko +# Copyright (C) 2024 Janmenjaya Panda # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of @@ -39,7 +40,6 @@ def HarborthGraph(): Harborth Graph: Graph on 52 vertices sage: g.is_regular(4) True - """ g = Graph(':s_OGKI?@_?g[QABAo__YEFCp@?iIEbqHWuWLbbh?}[OfcXpGhNHdYPY_SgdYX]' 'pZkfJPuo[lfZHys^mFcDs}`pG{UNNgoHC}DIgrI[qjMhTyDQrQlVydrBYmWkn', @@ -133,7 +133,7 @@ def HarriesGraph(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two embeddings are available, + - ``embedding`` -- integer (default: `1`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -252,7 +252,7 @@ def HarriesWongGraph(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two embeddings are available, + - ``embedding`` -- integer (default: `1`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -449,7 +449,7 @@ def Cell600(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two different embeddings for a + - ``embedding`` -- integer (default: `1`); two different embeddings for a plot EXAMPLES:: @@ -802,7 +802,7 @@ def Balaban10Cage(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two embeddings are available, + - ``embedding`` -- integer (default: `1`); two embeddings are available, and can be selected by setting ``embedding`` to be either 1 or 2 EXAMPLES:: @@ -870,7 +870,7 @@ def Balaban11Cage(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); three embeddings are available, + - ``embedding`` -- integer (default: `1`); three embeddings are available, and can be selected by setting ``embedding`` to be 1, 2, or 3 - The first embedding is the one appearing on page 9 of the Fifth Annual @@ -1111,7 +1111,7 @@ def BiggsSmithGraph(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two embeddings are available, + - ``embedding`` -- integer (default: `1`); two embeddings are available, and can be selected by setting ``embedding`` to be 1 or 2 EXAMPLES: @@ -1142,7 +1142,6 @@ def BiggsSmithGraph(embedding=1): Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 - """ L = [16, 24, -38, 17, 34, 48, -19, 41, -35, 47, -20, 34, -36, 21, 14, 48, -16, -36, -43, 28, -17, 21, 29, -43, 46, -24, @@ -1752,7 +1751,7 @@ def CameronGraph(): from sage.groups.perm_gps.permgroup_named import MathieuGroup from itertools import combinations g = Graph(name="Cameron Graph") - sets = MathieuGroup(22).orbit((1, 2, 3, 7, 10, 20), action="OnSets") + sets = MathieuGroup(22).orbit((1, 2, 3, 7, 10, 20), action='OnSets') for s in sets: for a, b, c, d in combinations(set(s), 4): g.add_edges([((a, b), (c, d)), ((a, c), (b, d)), ((a, d), (b, c))]) @@ -1900,6 +1899,168 @@ def CoxeterGraph(): return g +def CubeplexGraph(embedding='LM'): + r""" + Return the Cubeplex graph. + + The Cubeplex graph is the cubic hamiltonian graph of order 12 that + corresponds to the graph labeled as `\Gamma_1` in Fischer and Little + [FiLi2001]_. It has LCF notation `[-6, -5, -3, -6, 3, 5, -6, -3, 5, -6, -5, + 3]`. + + The Fischer-Little Theorem [FiLi2001]_ may be stated as follows [LM2024]_: + + A near-bipartite graph is non-Pfaffian if and only if it contains one of + the graphs `K_{3, 3}`, `\Gamma_1` and `\Gamma_2` as an `S`-minor. + + Norine and Thomas [NT2007]_ use the term ``Cubeplex`` to describe one of + the 12-vertex cubic graphs, `\Gamma_1` and `\Gamma_2`, as defined by + Fischer and Little [FiLi2001]_. However, the figure in their paper that + supposedly provides embeddings for the graphs labeled Cubeplex and Twinplex + actually shows both embeddings corresponding to Fischer and Little's + `\Gamma_1`, which is the Cubeplex graph. Followingly, for + ``embedding='NT'``, we present only the embedding that is shown by the + labeling ``Cubeplex`` in the paper of Norine and Thomas [NT2007]_. + + PLOTTING: + + Upon construction, the position dictionary is filled to override + the spring-layout algorithm. For different values of the parameter + ``embedding``, the Cubeplex graph is displayed as it is mentioned in the + respective paper/ book. + + INPUT: + + - ``embedding`` -- string (default: ``'LM'``) + + - ``'LM'`` displays the embedding as shown for `\Gamma_1` by Lucchesi and + Murty [LM2024]_ + + - ``'FL'`` displays the embedding as shown for `\Gamma_1` by Fischer and + Little [FiLi2001]_ + + - ``'NT'`` displays the embedding as shown for the ``Cubeplex`` by Norine + and Thomas [NT2007]_ + + OUTPUT: + + - ``G`` -- the Cubeplex graph; note that a :class:`ValueError` is returned + if ``embedding`` is none of ``'FT'``, ``'NT'`` or ``'LM'`` + + EXAMPLES: + + Construct and show the Cubeplex graph:: + + sage: g = graphs.CubeplexGraph() + sage: g.name() + 'Cubeplex Graph' + sage: g.order() + 12 + sage: g.size() + 18 + sage: g.girth() + 4 + sage: g.diameter() + 3 + sage: g.is_hamiltonian() + True + sage: g.crossing_number() + 1 + sage: g.show() # long time # needs sage.plot + + TESTS: + + Note that all three embeddings refer to the same graph, the Cubeplex graph, + aka `\Gamma_1`:: + + sage: fl = graphs.CubeplexGraph(embedding='FL') + sage: nt = graphs.CubeplexGraph(embedding='NT') + sage: lm = graphs.CubeplexGraph(embedding='LM') + sage: fl.is_isomorphic(nt) and fl.is_isomorphic(lm) + True + + The input parameter must be one of 'FL', 'NT' or 'LM':: + + sage: g = graphs.CubeplexGraph(embedding='embedding') + Traceback (most recent call last): + ... + ValueError: parameter 'embedding' must be 'FL', 'NT' or 'LM' + + .. SEEALSO:: + + :meth:`~sage.graphs.graph_generators.GraphGenerators.TwinplexGraph` + + AUTHORS: + + - Janmenjaya Panda (2024-08-03) + """ + if embedding == 'FL': + from math import pi + + G = Graph(12, name='Cubeplex Graph') + G.add_cycle(list(range(12))) + + G.add_edges([ + (0, 3), (1, 6), (2, 8), + (4, 9), (5, 11), (7, 10) + ]) + + G._circle_embedding(list(range(12)), angle=2*pi/3) + + elif embedding == 'NT': + pos_dict = { + 0: (1, 2), + 1: (3, 2), + 2: (0, 1), + 3: (1, 1), + 4: (2, 1), + 5: (3, 1), + 6: (4, 1), + 7: (0, -1), + 8: (1, 0), + 9: (2, 0), + 10: (3, 0), + 11: (4, -1), + } + + G = Graph(12, pos=pos_dict, name='Cubeplex Graph') + G.add_edges([ + (0, 2), (0, 4), (0, 6), + (1, 3), (1, 5), (1, 6), + (2, 7), (2, 8), (3, 7), + (3, 8), (4, 9), (4, 10), + (5, 9), (5, 10), (6, 11), + (7, 11), (8, 9), (10, 11) + ]) + + elif embedding == 'LM': + from math import pi + + pos_dict = { + 8: (0, 1), + 9: (1, 0), + 10: (-3*cos(pi/16), -3*sin(pi/16)), + 11: (3*cos(pi/16), -3*sin(pi/16)) + } + + for v in range(8): + t = pi * (v+2)/4 + pos_dict[v] = (-2*cos(t), 2*sin(t)) + + G = Graph(12, pos=pos_dict, name='Cubeplex Graph') + + G.add_cycle(list(range(8))) + G.add_edges([ + (0, 8), (1, 11), (2, 9), (3, 11), (4, 8), + (5, 10), (6, 9), (7, 10), (8, 9), (10, 11) + ]) + + else: + raise ValueError("parameter 'embedding' must be 'FL', 'NT' or 'LM'") + + return G + + def DejterGraph(): r""" Return the Dejter graph. @@ -2196,7 +2357,7 @@ def EllinghamHorton54Graph(): 40: [41, 45, 46], 41: [47], 42: [48, 43], 43: [49, 44], 44: [50, 45], 45: [51], 46: [49], 50: [52], 51: [53], 52: [53]} - g = Graph(data=edge_dict, format="dict_of_lists", + g = Graph(data=edge_dict, format='dict_of_lists', name="Ellingham-Horton 54-graph") # The set of vertices on top is 0..15 @@ -2429,7 +2590,7 @@ def FlowerSnark(): d = {0: [1, 14, 15], 1: [2, 11], 2: [3, 7], 3: [2, 4, 16], 4: [5, 14], 5: [6, 10], 6: [5, 7, 17], 8: [7, 9, 13], 9: [10, 18], 11: [10, 12], 12: [13, 19], 13: [14], 15: [19], 16: [15, 17], 18: [17, 19]} - g = Graph(d, format="dict_of_lists", name="Flower Snark") + g = Graph(d, format='dict_of_lists', name="Flower Snark") g._circle_embedding(range(15), radius=2.5, angle=pi/2) g._circle_embedding(range(15, 20), radius=1, angle=pi/2) return g @@ -2718,7 +2879,7 @@ def GrayGraph(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two embeddings are available, + - ``embedding`` -- integer (default: `1`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -2953,7 +3114,7 @@ def GritsenkoGraph(): (33, 49), (33, 51), (33, 57), (33, 61)] # use the union of the orbits of a on the edges return Graph(reduce(lambda x, y: x + y, - map(lambda o: a.orbit(o, action='OnSets'), edges)), + (a.orbit(o, action='OnSets') for o in edges)), format='list_of_edges', name="Gritsenko strongly regular graph") @@ -2986,9 +3147,7 @@ def HigmanSimsGraph(relabel=True): vertex `z` (zero through four) of that pentagon or pentagram. See [Haf2004]_ for more. - OUTPUT: - - The Higman-Sims graph. + OUTPUT: the Higman-Sims graph EXAMPLES: @@ -3419,7 +3578,7 @@ def LjubljanaGraph(embedding=1): INPUT: - - ``embedding`` -- integer (default: ``1``); two embeddings are available, + - ``embedding`` -- integer (default: `1`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -3515,7 +3674,7 @@ def LivingstoneGraph(): from sage.graphs.graph import Graph G = JankoGroup(1) g = Graph(name="Livingstone Graph") - g.add_edges(map(tuple, G.orbit((1, 24), action="OnSets"))) + g.add_edges(map(tuple, G.orbit((1, 24), action='OnSets'))) return g @@ -3541,7 +3700,7 @@ def M22Graph(): (77, 16, 0, 4) """ from sage.groups.perm_gps.permgroup_named import MathieuGroup - sets = [tuple(_) for _ in MathieuGroup(22).orbit((1, 2, 3, 7, 10, 20), action="OnSets")] + sets = [tuple(_) for _ in MathieuGroup(22).orbit((1, 2, 3, 7, 10, 20), action='OnSets')] g = Graph([sets, lambda x, y: not any(xx in y for xx in x)], name="M22 Graph") g.relabel() ordering = [0, 1, 3, 4, 5, 6, 7, 10, 12, 19, 20, 31, 2, 24, 35, 34, 22, 32, @@ -3611,7 +3770,7 @@ def McGeeGraph(embedding=2): INPUT: - - ``embedding`` -- integer (default: ``2``); two embeddings are available, + - ``embedding`` -- integer (default: `2`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -3817,6 +3976,88 @@ def MoserSpindle(): return Graph(edge_dict, pos=pos_dict, name="Moser spindle") +def MurtyGraph(): + r""" + Return the Murty graph. + + Consider the complete bipartite graph `K_{3, 3}`. There is a set of three + black vertices and a set of three white vertices. Now, consider splicing + the complete graph `K_4` with one of the black vertices, this generates the + graph `K_4 \odot K_{3, 3}`. The Murty graph is obtained from + `K_4 \odot K_{3, 3}` with the addition of an edge joining the remaining two + black vertices. The Murty graph is free of conformal bicycles; in + other words, the Murty graph is an example of a graph that is Birkhoff-von + Neumann as well as PM-compact. + + This is the smallest brick that is Birkhoff-von Neumann, aka a solid + brick, but is not odd-intercyclic. It is in this context that + Prof. U.S.R. Murty first stumbled upon this graph, and it also appears in + the work of Carvalho, Lucchesi, and Murty [CLM2006]_. + + PLOTTING: + + Upon construction, the position dictionary is filled to override + the spring-layout algorithm. By convention, the Murty graph is + displayed as mentioned in the paper [CKWL2019]_, with the first two + (noncubic) vertices on the top row, the second three vertices (that form a + stable set) in the middle row, and the remaining three vertices (that form + a triangle) at the bottom. + + OUTPUT: + + - ``G`` -- the Murty graph + + EXAMPLES: + + Construct and show the Murty graph:: + + sage: g = graphs.MurtyGraph() + sage: g.name() + 'Murty Graph' + sage: g.order() + 8 + sage: g.size() + 13 + sage: g.girth() + 3 + sage: g.diameter() + 2 + sage: g.is_hamiltonian() + True + sage: g.show() # long time # needs sage.plot + + REFERENCES: + + - [CKWL2019]_ + - [CLM2006]_ + - [LM2024]_ + + AUTHORS: + + - Janmenjaya Panda (2024-08-03) + """ + pos_dict = { + 0: (-0.5, sqrt(3)/2), + 1: (0.5, sqrt(3)/2), + 2: (-1, 0), + 3: (0, 0), + 4: (1, 0), + 5: (-0.5, -1 - sqrt(3)/2), + 6: (0, -1), + 7: (0.5, -1 - sqrt(3)/2) + } + + G = Graph(8, pos=pos_dict, name="Murty Graph") + + G.add_edge(0, 1) + for v in range(2, 5): + G.add_edges([(0, v), (1, v), (v, v+3)]) + + G.add_edges([(5, 6), (5, 7), (6, 7)]) + + return G + + def NauruGraph(embedding=2): """ Return the Nauru Graph. @@ -3825,7 +4066,7 @@ def NauruGraph(embedding=2): INPUT: - - ``embedding`` -- integer (default: ``2``); two embeddings are available, + - ``embedding`` -- integer (default: `2`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -4376,6 +4617,102 @@ def TietzeGraph(): return g +def TricornGraph(): + r""" + Return the Tricorn graph. + + The Tricorn graph is obtained by splicing a complete graph `K_4` with the + the triangular circular ladder graph `\overline{C_6}`. (Note that this + generates a unqiue graph as both of the graphs `K_4` and `\overline{C_6}` + are vertex-transitive). It is a nonsolid brick. This matching covered graph + is one of the ten extremal cubic bricks. (A matching covered graph `G` is + *extremal* if `\Phi(G) = dim(\mathcal{Lin}(G))`, where `\Phi(G)` denotes + the number of perfect matchings of `G`, and `dim(\mathcal{Lin}(G))` stands + for the dimension of the linear space of `G`). + + The Tricorn graph has no removable doubletons and has precisely three + removable edges. The wheel graph `W_5` and the complete graph `K_4` are + matching minors of the Tricorn graph. + + As per a theorem of Lovász [Lov1983]_, each non bipartite matching covered + graph has a conformal subgraph which is either a bi-subdivision of `K_4` or + of `\overline{C_6}` or both. In their paper, Kothari and Murty [KM2015]_ + characterized those planar bricks that are free of `\overline{C_6}` (that + is, the planar bricks that do not contain a bi-subdivision of + `\overline{C_6}` as a conformal subgraph). Besides two infinite families of + matching covered graphs (odd wheel graphs and staircase graphs of order + *4k*), the Tricorn graph is the only exception brick that is simple, planar + and free of `\overline{C_6}`. + + PLOTTING: + + Upon construction, the position dictionary is filled to override + the spring-layout algorithm. By convention, the Tricorn graph is + displayed as mentioned in the book [LM2024]_, with the central vertex being + the `0`-th one. Rest of the nine vertices are shown in groups of three, + one on the top, rest two on the bottom left and on the bottom right + corners respectively. + + OUTPUT: + + - ``G`` -- the Tricorn graph + + EXAMPLES: + + Construct and show the Tricorn graph; note that the edges `(2, 3)`, + `(5, 6)` and `(8, 9)` are the only removable edges of the Tricorn + graph:: + + sage: g = graphs.TricornGraph() + sage: g.name() + 'Tricorn Graph' + sage: g.order() + 10 + sage: g.size() + 15 + sage: g.girth() + 3 + sage: g.diameter() + 3 + sage: g.is_hamiltonian() + True + sage: g.show() # long time # needs sage.plot + + REFERENCES: + + - [KM2015]_ + - [LM2024]_ + - [Lov1983]_ + + AUTHORS: + + - Janmenjaya Panda (2024-08-02) + """ + pos_dict = { + 0: (0, 0), + 1: (0, 1), + 2: (1/2, 1 + sqrt(3)/2), + 3: (-1/2, 1 + sqrt(3)/2), + 4: (-sqrt(3)/2, -1/2), + 5: (-sqrt(3)/2 - 1, -1/2), + 6: (-sqrt(3)/2 - 1/2, -1/2 - sqrt(3)/2), + 7: (sqrt(3)/2, -1/2), + 8: (sqrt(3)/2 + 1/2, -1/2 - sqrt(3)/2), + 9: (sqrt(3)/2 + 1, -1/2) + } + + G = Graph(10, pos=pos_dict, name="Tricorn Graph") + + for v in range(1, 8, 3): + G.add_edges([ + (0, v), (v, v+1), + (v, v+2), (v+1, v+2), + (v+2, int((-v**2 + 7*v + 4)/2)) + ]) + + return G + + def TruncatedIcosidodecahedralGraph(): r""" Return the truncated icosidodecahedron. @@ -4464,7 +4801,7 @@ def TutteCoxeterGraph(embedding=2): INPUT: - - ``embedding`` -- integer (default: ``2``); two embeddings are available, + - ``embedding`` -- integer (default: `2`); two embeddings are available, and can be selected by setting ``embedding`` to 1 or 2 EXAMPLES:: @@ -4575,6 +4912,204 @@ def TutteGraph(): return g +def TwinplexGraph(embedding='LM'): + r""" + Return the Twinplex graph. + + The Twinplex graph is a cubic hamiltonian graph of order 12 with the graph + crossing number 2 and has a girth 5 (that is the maximal girth among all + cubic graphs on 12 vertices [CHNP2020]_). It corresponds to the graph + labeled as `\Gamma_2` by Fischer and Little [FiLi2001]_. The Twinplex graph + has LCF notation `[-5, -4, 4, -4, 4, 5, -4, 5, -4, 4, -5, 4]`. + + The Fischer-Little Theorem [FiLi2001]_ may be stated as follows [LM2024]_: + + A near-bipartite graph is non-Pfaffian if and only if it contains one of + the graphs `K_{3, 3}`, `\Gamma_1` and `\Gamma_2` as an `S`-minor. + + Norine and Thomas [NT2007]_ use the term ``Twinplex`` to describe one of + the 12-vertex cubic graphs, `\Gamma_1` and `\Gamma_2`, as defined by + Fischer and Little [FiLi2001]_. However, the figure in their paper that + supposedly provides embeddings for the graphs labeled Cubeplex and Twinplex + actually shows both embeddings corresponding to Fischer and Little's + `\Gamma_1`, which is the Cubeplex graph. Followingly, for + ``embedding='NT'``, we present a correct version of the Twinplex graph + with a slight modification of the embedding that is labeled as ``Twinplex`` + in the paper of Norine and Thomas [NT2007]_. + + PLOTTING: + + Upon construction, the position dictionary is filled to override + the spring-layout algorithm. For different values of the parameter + ``embedding``, the Twinplex graph is displayed as it is mentioned in the + respective paper/ book. Note that for ``embedding='NT'``, a correct + embedding of the Twinplex graph is displayed with a minor modification to + the (incorrect) embedding shown in the paper [NT2007]_. + + INPUT: + + - ``embedding`` -- string (default: ``'LM'``) + + - ``'LM'`` displays the embedding as shown for `\Gamma_2` by Lucchesi and + Murty [LM2024]_ + + - ``'FL'`` displays the embedding as shown for `\Gamma_2` by Fischer and + Little [FiLi2001]_ + + - ``'NT'`` displays the correct embedding with a minor modification to + the one shown as the (incorrect) ``Twinplex`` by Norine and Thomas + [NT2007]_ + + - ``'RST'`` displays the embedding as shown for the ``Twinplex`` by + Robertson, Seymour and Thomas [RST2019]_ + + OUTPUT: + + - ``G`` -- the Twinplex graph; note that a :class:`ValueError` is returned + if ``embedding`` is none of ``'FT'``, ``'NT'``, ``'RST'`` or ``'LM'`` + + EXAMPLES: + + Construct and show the Twinplex graph:: + + sage: g = graphs.TwinplexGraph() + sage: g.name() + 'Twinplex Graph' + sage: g.order() + 12 + sage: g.size() + 18 + sage: g.girth() + 5 + sage: g.diameter() + 3 + sage: g.is_hamiltonian() + True + sage: g.crossing_number() + 2 + sage: g.show() # long time # needs sage.plot + + TESTS: + + Note that all four embeddings refer to the same graph, the Twinplex graph, + aka `\Gamma_2`:: + + sage: fl = graphs.TwinplexGraph(embedding='FL') + sage: nt = graphs.TwinplexGraph(embedding='NT') + sage: rst = graphs.TwinplexGraph(embedding='RST') + sage: lm = graphs.TwinplexGraph(embedding='LM') + sage: all(fl.is_isomorphic(g) for g in (nt, rst, lm)) + True + + The input parameter must be one of 'FL', 'NT', 'RST' or 'LM':: + + sage: g = graphs.TwinplexGraph(embedding='embedding') + Traceback (most recent call last): + ... + ValueError: parameter 'embedding' must be 'FL', 'NT', 'LM' or 'RST' + + .. SEEALSO:: + + :meth:`~sage.graphs.graph_generators.GraphGenerators.CubeplexGraph` + + AUTHORS: + + - Janmenjaya Panda (2024-08-03) + """ + if embedding == 'FL': + from math import pi + + G = Graph(12, name='Twinplex Graph') + G.add_cycle(list(range(12))) + + G.add_edges([ + (0, 8), (1, 5), (2, 9), + (3, 7), (4, 11), (6, 10) + ]) + + G._circle_embedding(list(range(12)), angle=5*pi/12) + + elif embedding == 'NT': + pos_dict = { + 0: (1, 2), + 1: (3, 2), + 2: (0, 1), + 3: (1, 1), + 4: (2, 1), + 5: (3, 1), + 6: (4, 1), + 7: (0, -1), + 8: (1, 0), + 9: (2, 0), + 10: (3, 0), + 11: (4, -1), + } + + G = Graph(12, pos=pos_dict, name='Twinplex Graph') + G.add_edges([ + (0, 2), (0, 4), (0, 6), + (1, 3), (1, 5), (1, 6), + (2, 7), (2, 9), (3, 7), + (3, 8), (4, 8), (4, 10), + (5, 9), (5, 10), (6, 11), + (7, 11), (8, 9), (10, 11) + ]) + + elif embedding == 'RST': + pos_dict = { + 0: (-1, 3), + 1: (1, 3), + 2: (3, 1), + 3: (3, -1), + 4: (1, -3), + 5: (-1, -3), + 6: (-3, -1), + 7: (-3, 1), + 8: (-1, 1), + 9: (1, 1), + 10: (1, -1), + 11: (-1, -1) + } + + G = Graph(12, pos=pos_dict, name='Twinplex Graph') + + G.add_cycle(list(range(8))) + G.add_edges([ + (0, 4), (1, 8), (2, 10), + (3, 9), (5, 10), (6, 8), + (7, 11), (8, 9), (9, 11), + (10, 11) + ]) + + elif embedding == 'LM': + from math import pi + + pos_dict = { + 8: (0, 1), + 9: (1, 0), + 10: (-3*cos(pi/16), -3*sin(pi/16)), + 11: (3*cos(pi/16), -3*sin(pi/16)) + } + + for v in range(8): + t = pi * (v+2)/4 + pos_dict[v] = (-2*cos(t), 2*sin(t)) + + G = Graph(12, pos=pos_dict, name='Twinplex Graph') + + G.add_cycle(list(range(8))) + G.add_edges([ + (0, 8), (1, 11), (2, 9), (3, 10), (4, 8), + (5, 11), (6, 9), (7, 10), (8, 9), (10, 11) + ]) + + else: + raise ValueError("parameter 'embedding' must be 'FL', 'NT'," + " 'LM' or 'RST'") + + return G + + def WagnerGraph(): """ Return the Wagner Graph. @@ -4738,7 +5273,7 @@ def _EllipticLinesProjectivePlaneScheme(k): gp = libgap.Action(g, libgap.Orbit(g, l, libgap.OnLines), libgap.OnLines) orbitals = gp.Orbits(list(product(gp.Orbit(1), gp.Orbit(1))), libgap.OnTuples) - mats = map(lambda o: [(int(x[0]) - 1, int(x[1]) - 1) for x in o], orbitals) + mats = ([(int(x[0]) - 1, int(x[1]) - 1) for x in o] for o in orbitals) return [matrix((q * (q - 1)) // 2, lambda i, j: 1 if (i, j) in x else 0) for x in mats] @@ -4768,7 +5303,6 @@ def MathonStronglyRegularGraph(t): sage: G = graphs.MathonStronglyRegularGraph(2) sage: G.is_strongly_regular(parameters=True) (784, 297, 116, 110) - """ from sage.graphs.generators.families import MathonPseudocyclicMergingGraph ES = _EllipticLinesProjectivePlaneScheme(3) @@ -4868,7 +5402,7 @@ def my_abs(M): return Graph([e for e, v in D.dict().items() if v == 1], multiedges=False, - name="Janko-Kharaghani") + name='Janko-Kharaghani') def JankoKharaghaniTonchevGraph(): @@ -4939,7 +5473,7 @@ def JankoKharaghaniTonchevGraph(): 301, 304, 308, 309, 310, 312, 313, 314, 316, 317, 318) Gamma = Graph(multiedges=False, name='Janko-Kharaghani-Tonchev') for i, b in ((1, B1), (163, B163)): - for j in map(lambda x: x[0], st.OrbitsDomain(b)): + for j in (x[0] for x in st.OrbitsDomain(b)): Gamma.add_edges(map(tuple, G.Orbit(libgap.Set([i, j]), libgap.OnSets))) Gamma.relabel(range(Gamma.order())) return Gamma @@ -5114,7 +5648,7 @@ def pi_vec(x): int_to_matrix[i + 1] = N(vec) M2 = matrix.block([[int_to_matrix[x] for x in R] for R in W.rows()]) - g = Graph(M2, name="Ionin-Kharaghani") + g = Graph(M2, name='Ionin-Kharaghani') return g @@ -5136,7 +5670,7 @@ def U42Graph216(): from sage.libs.gap.libgap import libgap from sage.features.gap import GapPackage - GapPackage("grape", spkg="gap_packages").require() + GapPackage("grape", spkg='gap_packages').require() adj_list = libgap.function_factory("""function() local gg, hl, o216, a216, x, h, re, G; @@ -5183,7 +5717,7 @@ def U42Graph540(): from sage.libs.gap.libgap import libgap from sage.features.gap import GapPackage - GapPackage("grape", spkg="gap_packages").require() + GapPackage("grape", spkg='gap_packages').require() adj_list = libgap.function_factory("""function() local f, o540, a540, x, oh, h, lo, G; diff --git a/src/sage/graphs/generators/world_map.py b/src/sage/graphs/generators/world_map.py index 588689d516c..5ccd80a0908 100644 --- a/src/sage/graphs/generators/world_map.py +++ b/src/sage/graphs/generators/world_map.py @@ -30,7 +30,7 @@ def AfricaMap(continental=False, year=2018): - ``continental`` -- boolean (default: ``False``); whether to only return states in the continental Africa or all African states - - ``year`` -- integer (default: ``2018``); reserved for future use + - ``year`` -- integer (default: 2018); reserved for future use EXAMPLES:: @@ -116,7 +116,7 @@ def EuropeMap(continental=False, year=2018): - ``continental`` -- boolean (default: ``False``); whether to only return states in the continental Europe or all European states - - ``year`` -- integer (default: ``2018``); reserved for future use + - ``year`` -- integer (default: 2018); reserved for future use EXAMPLES:: diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 063931ae274..9786af20367 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -80,7 +80,7 @@ :meth:`~GenericGraph.clear` | Empty the graph of vertices and edges and removes name, associated objects, and position information. :meth:`~GenericGraph.degree` | Return the degree (in + out for digraphs) of a vertex or of vertices. :meth:`~GenericGraph.average_degree` | Return the average degree of the graph. - :meth:`~GenericGraph.degree_histogram` | Return a list, whose ith entry is the frequency of degree i. + :meth:`~GenericGraph.degree_histogram` | Return a list, whose `i`-th entry is the frequency of degree i. :meth:`~GenericGraph.degree_iterator` | Return an iterator over the degrees of the (di)graph. :meth:`~GenericGraph.degree_sequence` | Return the degree sequence of this (di)graph. :meth:`~GenericGraph.random_subgraph` | Return a random subgraph containing each vertex with probability ``p``. @@ -90,8 +90,8 @@ :meth:`~GenericGraph.complement` | Return the complement of the (di)graph. :meth:`~GenericGraph.line_graph` | Return the line graph of the (di)graph. :meth:`~GenericGraph.to_simple` | Return a simple version of itself (i.e., undirected and loops and multiple edges are removed). - :meth:`~GenericGraph.disjoint_union` | Return the disjoint union of self and other. - :meth:`~GenericGraph.union` | Return the union of self and other. + :meth:`~GenericGraph.disjoint_union` | Return the disjoint union of ``self`` and ``other``. + :meth:`~GenericGraph.union` | Return the union of ``self`` and ``other``. :meth:`~GenericGraph.relabel` | Relabel the vertices of ``self`` :meth:`~GenericGraph.degree_to_cell` | Return the number of edges from vertex to an edge in cell. :meth:`~GenericGraph.subgraph` | Return the subgraph containing the given vertices and edges. @@ -104,11 +104,11 @@ :widths: 30, 70 :delim: | - :meth:`~GenericGraph.cartesian_product` | Return the Cartesian product of self and other. - :meth:`~GenericGraph.tensor_product` | Return the tensor product, also called the categorical product, of self and other. - :meth:`~GenericGraph.lexicographic_product` | Return the lexicographic product of self and other. - :meth:`~GenericGraph.strong_product` | Return the strong product of self and other. - :meth:`~GenericGraph.disjunctive_product` | Return the disjunctive product of self and other. + :meth:`~GenericGraph.cartesian_product` | Return the Cartesian product of ``self`` and ``other``. + :meth:`~GenericGraph.tensor_product` | Return the tensor product, also called the categorical product, of ``self`` and ``other``. + :meth:`~GenericGraph.lexicographic_product` | Return the lexicographic product of ``self`` and ``other``. + :meth:`~GenericGraph.strong_product` | Return the strong product of ``self`` and ``other``. + :meth:`~GenericGraph.disjunctive_product` | Return the disjunctive product of ``self`` and ``other``. **Paths and cycles:** @@ -161,10 +161,10 @@ :widths: 30, 70 :delim: | - :meth:`~GenericGraph.coarsest_equitable_refinement` | Return the coarsest partition which is finer than the input partition, and equitable with respect to self. + :meth:`~GenericGraph.coarsest_equitable_refinement` | Return the coarsest partition which is finer than the input partition, and equitable with respect to ``self``. :meth:`~GenericGraph.automorphism_group` | Return the largest subgroup of the automorphism group of the (di)graph whose orbit partition is finer than the partition given. - :meth:`~GenericGraph.is_vertex_transitive` | Return whether the automorphism group of self is transitive within the partition provided - :meth:`~GenericGraph.is_isomorphic` | Test for isomorphism between self and other. + :meth:`~GenericGraph.is_vertex_transitive` | Return whether the automorphism group of ``self`` is transitive within the partition provided + :meth:`~GenericGraph.is_isomorphic` | Test for isomorphism between ``self`` and ``other``. :meth:`~GenericGraph.canonical_label` | Return the canonical graph. :meth:`~GenericGraph.is_cayley` | Check whether the graph is a Cayley graph. @@ -189,7 +189,7 @@ :meth:`~GenericGraph.is_geodetic` | Check whether the input (di)graph is geodetic. :meth:`~GenericGraph.is_independent_set` | Check whether ``vertices`` is an independent set of ``self`` :meth:`~GenericGraph.is_transitively_reduced` | Test whether the digraph is transitively reduced. - :meth:`~GenericGraph.is_equitable` | Check whether the given partition is equitable with respect to self. + :meth:`~GenericGraph.is_equitable` | Check whether the given partition is equitable with respect to ``self``. :meth:`~GenericGraph.is_self_complementary` | Check whether the graph is self-complementary. **Traversals:** @@ -214,7 +214,7 @@ :delim: | :meth:`~GenericGraph.centrality_betweenness` | Return the betweenness centrality - :meth:`~GenericGraph.centrality_closeness` | Returns the closeness centrality (1/average distance to all vertices) + :meth:`~GenericGraph.centrality_closeness` | Return the closeness centrality (1/average distance to all vertices) :meth:`~GenericGraph.distance` | Return the (directed) distance from u to v in the (di)graph :meth:`~GenericGraph.distance_all_pairs` | Return the distances between all pairs of vertices. :meth:`~GenericGraph.distances_distribution` | Return the distances distribution of the (di)graph in a dictionary. @@ -243,8 +243,10 @@ :meth:`~GenericGraph.connected_components_sizes` | Return the sizes of the connected components as a list. :meth:`~GenericGraph.blocks_and_cut_vertices` | Compute the blocks and cut vertices of the graph. :meth:`~GenericGraph.blocks_and_cuts_tree` | Compute the blocks-and-cuts tree of the graph. - :meth:`~GenericGraph.is_cut_edge` | Return True if the input edge is a cut-edge or a bridge. - :meth:`~GenericGraph.is_cut_vertex` | Return True if the input vertex is a cut-vertex. + :meth:`~GenericGraph.is_cut_edge` | Check whether the input edge is a cut-edge or a bridge. + :meth:`~GenericGraph.`is_edge_cut` | Check whether the input edges form an edge cut. + :meth:`~GenericGraph.is_cut_vertex` | Check whether the input vertex is a cut-vertex. + :meth:`~GenericGraph.is_vertex_cut` | Check whether the input vertices form a vertex cut. :meth:`~GenericGraph.edge_cut` | Return a minimum edge cut between vertices `s` and `t` :meth:`~GenericGraph.vertex_cut` | Return a minimum vertex cut between non-adjacent vertices `s` and `t` :meth:`~GenericGraph.flow` | Return a maximum flow in the graph from ``x`` to ``y`` @@ -257,7 +259,7 @@ :meth:`~GenericGraph.transitive_reduction` | Return a transitive reduction of a graph. :meth:`~GenericGraph.min_spanning_tree` | Return the edges of a minimum spanning tree. :meth:`~GenericGraph.spanning_trees_count` | Return the number of spanning trees in a graph. - :meth:`~GenericGraph.dominator_tree` | Returns a dominator tree of the graph. + :meth:`~GenericGraph.dominator_tree` | Return a dominator tree of the graph. :meth:`~GenericGraph.connected_subgraph_iterator` | Iterator over the induced connected subgraphs of order at most `k` **Plot/embedding-related methods:** @@ -295,6 +297,7 @@ :meth:`~GenericGraph.show3d` | Plot the graph using :class:`~sage.plot.plot3d.tachyon.Tachyon`, and shows the resulting plot. :meth:`~GenericGraph.graphviz_string` | Return a representation in the ``dot`` language. :meth:`~GenericGraph.graphviz_to_file_named` | Write a representation in the ``dot`` language in a file. + :meth:`~GenericGraph.tikz` | Return a :class:`~sage.misc.latex_standalone.TikzPicture` object representing the (di)graph. **Algorithmically hard stuff:** @@ -488,7 +491,7 @@ def __init__(self): def __setstate__(self, state): r""" - Set the state from a pickle dict + Set the state from a pickle dict. TESTS:: @@ -503,7 +506,7 @@ def __setstate__(self, state): def __add__(self, other): """ - Return a graph isomorphic to disjoint union of this graph with `other`. + Return a graph isomorphic to disjoint union of this graph with ``other``. Labels of the resulting graph will always be consecutive integers starting from zero. @@ -540,18 +543,19 @@ def __add__(self, other): def __eq__(self, other): """ - Compare self and other for equality. + Compare ``self`` and ``other`` for equality. Do not call this method directly. That is, for ``G.__eq__(H)`` write ``G == H``. Two graphs are considered equal if the following hold: - - they are either both directed, or both undirected; - - they have the same settings for loops, multiedges, and weightedness; - - they have the same set of vertices; - - they have the same (multi)set of arrows/edges, where labels of - arrows/edges are taken into account if *and only if* the graphs are - considered weighted. See :meth:`~GenericGraph.weighted`. + + - they are either both directed, or both undirected + - they have the same settings for loops, multiedges, and weightedness + - they have the same set of vertices + - they have the same (multi)set of arrows/edges, where labels of + arrows/edges are taken into account if *and only if* the graphs are + considered weighted. See :meth:`~GenericGraph.weighted`. Note that this is *not* an isomorphism test. @@ -600,7 +604,6 @@ def __eq__(self, other): sage: bar.weighted(True) sage: foo == bar False - """ # inputs must be (di)graphs: if not isinstance(other, GenericGraph): @@ -624,7 +627,7 @@ def _use_labels_for_hash(self): Helper method for method ``__hash__``. This method checks whether parameter ``hash_labels`` has been specified - by the user. Otherwise, defaults to the value of parameter ``weigthed``. + by the user. Otherwise, defaults to the value of parameter ``weighted``. TESTS:: @@ -666,7 +669,7 @@ def __hash__(self): ... TypeError: This graph is mutable, and thus not hashable. Create an immutable copy by `g.copy(immutable=True)` - sage: G_imm = Graph(G, data_structure="static_sparse") + sage: G_imm = Graph(G, data_structure='static_sparse') sage: G_imm == G True sage: {G_imm: 1}[G_imm] # indirect doctest @@ -677,9 +680,9 @@ def __hash__(self): TESTS: Equality and hash do not depend on ordering of vertices. In other words, - `G1 == G2` can be `True` even when + `G1 == G2` can be ``True`` even when `G1.vertices(sort=True) == G2.vertices(sort=True)` is - `False`. This is parts 1 and 2 of issue :issue:`17086`. :: + ``False``. This is parts 1 and 2 of issue :issue:`17086`. :: sage: import functools sage: @functools.total_ordering @@ -831,8 +834,11 @@ def __str__(self): def _bit_vector(self): """ - Return a string representing the edges of the (simple) graph for - ``graph6`` and ``dig6`` strings. + Return a string representing the edges of the graph for ``graph6`` + and ``dig6`` strings. + + The graph must be simple; loops are allowed only if the graph is + directed, and multiple edges are never allowed. EXAMPLES:: @@ -862,7 +868,7 @@ def _bit_vector(self): sage: P.canonical_label(algorithm='sage')._bit_vector() '001100001111000000011010100110100011' """ - self._scream_if_not_simple() + self._scream_if_not_simple(allow_loops=self._directed) n = self.order() if self._directed: total_length = n * n @@ -934,6 +940,190 @@ def _latex_(self): return self.latex_options().latex() + def tikz(self, format='dot2tex', edge_labels=None, + color_by_label=False, prog='dot', rankdir='down', + standalone_config=None, usepackage=None, + usetikzlibrary=None, macros=None, + use_sage_preamble=None, **kwds): + r""" + Return a TikzPicture of the graph. + + If graphviz and dot2tex are available, it uses these packages for + placements of vertices and edges. + + INPUT: + + - ``format`` -- string (default: ``None``), ``'dot2tex'`` or + ``'tkz_graph'``. If ``None``, it is set to ``'dot2tex'`` if + dot2tex is present, otherwise it is set to ``'tkz_graph'``. + - ``edge_labels`` -- bool (default: ``None``), if ``None`` + it is set to ``True`` if and only if format is ``'dot2tex'`` + - ``color_by_label`` -- boolean or dictionary or function (default: + ``False``); whether to color each edge with a different color + according to its label; the colors are chosen along a rainbow, unless + they are specified by a function or dictionary mapping labels to + colors; + + When using format ``'dot2tex'``, the following inputs are considered: + + - ``prog`` -- string (default: ``'dot'``) the program used for the + layout corresponding to one of the software of the graphviz + suite: 'dot', 'neato', 'twopi', 'circo' or 'fdp'. + - ``rankdir`` -- string (default: ``'down'``), direction of graph layout + when prog is ``'dot'``, possible values are ``'down'``, + ``'up'``, ``'right'`` and ``'left'``. + - ``subgraph_clusters`` -- (default: ``[]``) a list of lists of + vertices, if supported by the layout engine, nodes belonging to + the same cluster subgraph are drawn together, with the entire + drawing of the cluster contained within a bounding rectangle. + + Additionnal keywords arguments are forwarded to + :meth:`sage.graphs.graph_latex.GraphLatex.set_option`. + + The following inputs define the preamble of the latex standalone + document class file containing the tikzpicture: + + - ``standalone_config`` -- list of strings (default: ``["border=4mm"]``); + latex document class standalone configuration options + - ``usepackage`` -- list of strings (default: ``[]``); latex + packages + - ``usetikzlibrary`` -- list of strings (default: ``[]``); tikz + libraries to use + - ``macros`` -- list of strings (default: ``[]``); list of + newcommands needed for the picture + - ``use_sage_preamble`` -- bool (default: ``None``), if ``None`` + it is set to ``True`` if and only if format is ``'tkz_graph'`` + + OUTPUT: + + An instance of :mod:`sage.misc.latex_standalone.TikzPicture`. + + .. NOTE:: + + Prerequisite: dot2tex optional Sage package and graphviz must be + installed when using format ``'dot2tex'``. + + EXAMPLES:: + + sage: g = graphs.PetersenGraph() + sage: tikz = g.tikz() # optional - dot2tex graphviz # long time + sage: _ = tikz.pdf(view=False) # optional - dot2tex graphviz latex # long time + + :: + + sage: tikz = g.tikz(format='tkz_graph') + sage: _ = tikz.pdf(view=False) # optional - latex + + Using another value for ``prog``:: + + sage: tikz = g.tikz(prog='neato') # optional - dot2tex graphviz # long time + sage: _ = tikz.pdf() # optional - dot2tex graphviz latex # long time + + Using ``color_by_label`` with default rainbow colors:: + + sage: G = DiGraph({0: {1: 333, 2: 444}, 1: {0: 444}, 2: {0: 555}}) + sage: t = G.tikz(color_by_label=True) # optional - dot2tex graphviz # long time + sage: _ = t.pdf(view=False) # optional - dot2tex graphviz latex # long time + + Using ``color_by_label`` with colors given as a dictionary:: + + sage: G = DiGraph({0: {1: 333, 2: 444}, 1: {0: 444}, 2: {0: 555}}) + sage: cbl = {333:'orange', 444: 'yellow', 555: 'purple'} + sage: t = G.tikz(color_by_label=cbl) # optional - dot2tex graphviz # long time + sage: _ = t.pdf(view=False) # optional - dot2tex graphviz latex # long time + + Using ``color_by_label`` with colors given as a function:: + + sage: G = DiGraph({0: {1: -333, 2: -444}, 1: {0: 444}, 2: {0: 555}}) + sage: cbl = lambda label:'green' if label >= 0 else 'orange' + sage: t = G.tikz(color_by_label=cbl) # optional - dot2tex graphviz # long time + sage: _ = t.pdf(view=False) # optional - dot2tex graphviz latex # long time + + Using another value for ``rankdir``:: + + sage: tikz = g.tikz(rankdir='right') # optional - dot2tex graphviz # long time + sage: _ = tikz.pdf(view=False) # optional - dot2tex graphviz latex # long time + + Using subgraphs clusters (broken when using labels, see + :issue:`22070`):: + + sage: S = FiniteSetMaps(5) + sage: I = S((0,1,2,3,4)) + sage: a = S((0,1,3,0,0)) + sage: b = S((0,2,4,1,0)) + sage: roots = [I] + sage: succ = lambda v: [v*a,v*b,a*v,b*v] + sage: R = RecursivelyEnumeratedSet(roots, succ) + sage: G = R.to_digraph() + sage: G + Looped multi-digraph on 27 vertices + sage: C = G.strongly_connected_components() + sage: tikz = G.tikz(subgraph_clusters=C)# optional - dot2tex graphviz # long time + sage: tikz.add_usepackage('amstext') # optional - dot2tex graphviz # long time + sage: _ = tikz.pdf(view=False) # optional - dot2tex graphviz latex # long time + + An example coming from ``graphviz_string`` documentation in SageMath:: + + sage: # needs sage.symbolic + sage: f(x) = -1 / x + sage: g(x) = 1 / (x + 1) + sage: G = DiGraph() + sage: G.add_edges((i, f(i), f) for i in (1, 2, 1/2, 1/4)) + sage: G.add_edges((i, g(i), g) for i in (1, 2, 1/2, 1/4)) + sage: tikz = G.tikz(format='dot2tex') # optional - dot2tex graphviz # long time + sage: _ = tikz.pdf(view=False) # optional - dot2tex graphviz latex # long time + sage: def edge_options(data): + ....: u, v, label = data + ....: options = {"color": {f: "red", g: "blue"}[label]} + ....: if (u,v) == (1/2, -2): options["label"] = "coucou"; options["label_style"] = "string" + ....: if (u,v) == (1/2,2/3): options["dot"] = "x=1,y=2" + ....: if (u,v) == (1, -1): options["label_style"] = "latex" + ....: if (u,v) == (1, 1/2): options["dir"] = "back" + ....: return options + sage: tikz = G.tikz(format='dot2tex', # optional - dot2tex graphviz # long time + ....: edge_options=edge_options) + sage: _ = tikz.pdf(view=False) # optional - dot2tex graphviz latex # long time + """ + # use format dot2tex by default + if format is None: + from sage.features import PythonModule + if PythonModule("dot2tex").is_present(): + format = 'dot2tex' + else: + format = 'tkz_graph' + + # by default draw edge_labels for dot2tex but not for tkz_graph + # (because tkz_graph draws None everywhere which is ugly, whereas + # dot2tex ignores the labels when they are ``None``) + if edge_labels is None: + if format == 'tkz_graph': + edge_labels = False + elif format == 'dot2tex': + edge_labels = True + + self.latex_options().set_options(format=format, + edge_labels=edge_labels, color_by_label=color_by_label, + prog=prog, rankdir=rankdir, **kwds) + + # by default use sage preamble only for format tkz_graph + # because content generated by tkz_graph depends on it + if use_sage_preamble is None: + if format == 'tkz_graph': + use_sage_preamble = True + elif format == 'dot2tex': + use_sage_preamble = False + + if standalone_config is None: + standalone_config = ["border=4mm"] + + from sage.misc.latex_standalone import TikzPicture + return TikzPicture(self._latex_(), + standalone_config=standalone_config, + usepackage=usepackage, + usetikzlibrary=usetikzlibrary, + macros=macros, + use_sage_preamble=use_sage_preamble) + def _matrix_(self, R=None, vertices=None): """ Return the adjacency matrix of the graph over the specified ring. @@ -1013,7 +1203,7 @@ def is_immutable(self): def copy(self, weighted=None, data_structure=None, sparse=None, immutable=None, hash_labels=None): """ - Change the graph implementation + Change the graph implementation. INPUT: @@ -1024,8 +1214,8 @@ def copy(self, weighted=None, data_structure=None, sparse=None, immutable=None, for ``data_structure="sparse"``, and ``sparse=False`` is an alias for ``data_structure="dense"``. Only used when ``data_structure=None``. - - ``data_structure`` -- string (default: ``None``); one of ``"sparse"``, - ``"static_sparse"``, or ``"dense"``. See the documentation of + - ``data_structure`` -- string (default: ``None``); one of ``'sparse'``, + ``'static_sparse'``, or ``'dense'``. See the documentation of :class:`Graph` or :class:`DiGraph`. - ``immutable`` -- boolean (default: ``None``); whether to create a @@ -1039,7 +1229,7 @@ def copy(self, weighted=None, data_structure=None, sparse=None, immutable=None, * ``immutable=False`` means that the created graph is mutable. When used to copy an immutable graph, the data structure used is - ``"sparse"`` unless anything else is specified. + ``'sparse'`` unless anything else is specified. - ``hash_labels`` -- boolean (default: ``None``); whether to include edge labels during hashing of the copy. This parameter defaults to @@ -1054,9 +1244,7 @@ def copy(self, weighted=None, data_structure=None, sparse=None, immutable=None, and the ``_immutable`` flag, then ``self`` is returned rather than a copy (unless one of the optional arguments is used). - OUTPUT: - - A Graph object. + OUTPUT: a Graph object .. WARNING:: @@ -1168,11 +1356,11 @@ def copy(self, weighted=None, data_structure=None, sparse=None, immutable=None, Bad input:: - sage: G.copy(data_structure="sparse", sparse=False) + sage: G.copy(data_structure='sparse', sparse=False) Traceback (most recent call last): ... ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value - sage: G.copy(data_structure="sparse", immutable=True) + sage: G.copy(data_structure='sparse', immutable=True) Traceback (most recent call last): ... ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value @@ -1183,11 +1371,11 @@ def copy(self, weighted=None, data_structure=None, sparse=None, immutable=None, Which backend? :: - sage: G.copy(data_structure="sparse")._backend + sage: G.copy(data_structure='sparse')._backend - sage: G.copy(data_structure="dense")._backend + sage: G.copy(data_structure='dense')._backend - sage: G.copy(data_structure="static_sparse")._backend + sage: G.copy(data_structure='static_sparse')._backend sage: G.copy(immutable=True)._backend @@ -1370,13 +1558,13 @@ def export_to_file(self, filename, format=None, **kwds): EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: filename = tmp_filename(ext=".pajek") + sage: filename = tmp_filename(ext='.pajek') sage: g.export_to_file(filename) # needs networkx sage: import networkx # needs networkx sage: G_networkx = networkx.read_pajek(filename) # needs networkx sage: Graph(G_networkx).is_isomorphic(g) # needs networkx True - sage: filename = tmp_filename(ext=".edgelist") + sage: filename = tmp_filename(ext='.edgelist') sage: g.export_to_file(filename, data=False) # needs networkx sage: h = Graph(networkx.read_edgelist(filename)) # needs networkx sage: g.is_isomorphic(h) # needs networkx @@ -1505,7 +1693,7 @@ def networkx_graph(self, weight_function=None): INPUT: - ``weight_function`` -- function (default: ``None``); a function that - takes as input an edge ``(u, v, l)`` and outputs its weight. + takes as input an edge ``(u, v, l)`` and outputs its weight EXAMPLES:: @@ -1528,7 +1716,6 @@ def networkx_graph(self, weight_function=None): OutMultiEdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), (2, 3, {'weight': 3}), (3, 4, {'weight': 5}), (3, 4, {'weight': 4})]) - """ if weight_function is not None: self._check_weight_function(weight_function) @@ -1569,12 +1756,12 @@ def igraph_graph(self, vertex_list=None, vertex_attrs={}, edge_attrs={}): This routine needs the optional package igraph to be installed: to do so, it is enough to run ``sage -i python_igraph``. For more information on the Python version of igraph, see - http://igraph.org/python/. + https://python.igraph.org/. INPUT: - ``vertex_list`` -- list (default: ``None``); defines a mapping from - the vertices of the graph to consecutive integers in ``(0, \ldots, + the vertices of the graph to consecutive integers in `(0, \ldots, n-1)`. Otherwise, the result of :meth:`vertices` will be used instead. Because :meth:`vertices` only works if the vertices can be sorted, using ``vertex_list`` is useful when working with possibly @@ -1585,25 +1772,25 @@ def igraph_graph(self, vertex_list=None, vertex_attrs={}, edge_attrs={}): containing in position `i` the label of the `i`-th vertex in the list ``vertex_list`` if it is given or in :meth:`vertices` when ``vertex_list == None`` (see - http://igraph.org/python/doc/igraph.Graph-class.html#__init__ for more + https://python.igraph.org/en/stable/api/igraph.Graph.html#__init__ for more information) - ``edge_attrs`` -- dictionary (default: ``{}``); a dictionary where the key is a string (the attribute name), and the value is an iterable containing in position `i` the label of the `i`-th edge in the list outputted by :meth:`edge_iterator` (see - http://igraph.org/python/doc/igraph.Graph-class.html#__init__ for more + https://python.igraph.org/en/stable/api/igraph.Graph.html#__init__ for more information) .. NOTE:: - In ``igraph``, a graph is weighted if the edge labels have attribute - ``weight``. Hence, to create a weighted graph, it is enough to add - this attribute. + In ``igraph``, a graph is weighted if the edge attribute ``weight`` is + present. Hence, to create a weighted graph, it is enough to add this + attribute. .. NOTE:: - Often, Sage uses its own defined types for integer/floats. These + Often, Sage uses its own defined types for integers/floats. These types may not be igraph-compatible (see example below). EXAMPLES: @@ -1654,7 +1841,7 @@ def igraph_graph(self, vertex_list=None, vertex_attrs={}, edge_attrs={}): sage: H.vs()['name'] == V # optional - python_igraph True - Sometimes, Sage integer/floats are not compatible with igraph:: + Sometimes, Sage integers/floats are not compatible with igraph:: sage: G = Graph([(0, 1, 2)]) sage: E = list(G.edge_iterator()) @@ -1752,9 +1939,7 @@ def to_dictionary(self, edge_labels=False, multiple_edges=False): - ``multiple_edges`` -- boolean (default: ``False``); whether to include multiple edges in the output - OUTPUT: - - The output depends on the input: + OUTPUT: the output depends on the input: * If ``edge_labels == False`` and ``multiple_edges == False``, the output is a dictionary associating to each vertex the list of its @@ -1910,7 +2095,7 @@ def _vertex_indices_and_keys(self, vertices=None, *, sort=None): INPUT: - - ``vertices`` -- list, ``None``, or ``True`` (default: ``None``) + - ``vertices`` -- list; ``None``, or ``True`` (default: ``None``) - when a list, the `i`-th row and column of the matrix correspond to the `i`-th vertex in the ordering of ``vertices``, @@ -1921,11 +2106,11 @@ def _vertex_indices_and_keys(self, vertices=None, *, sort=None): a matrix, where the module's basis is indexed by the vertices. - ``sort`` -- boolean or ``None`` (default); passed to :meth:`vertices` - when ``vertices`` is not a list. + when ``vertices`` is not a list OUTPUT: pair of: - - ``vertex_indices`` -- a dictionary mapping vertices to numerical indices, + - ``vertex_indices`` -- dictionary mapping vertices to numerical indices, - ``keys`` -- either a tuple of basis keys (when using a :class:`CombinatorialFreeModule`) or ``None`` (when using a :class:`FreeModule`, :func:`matrix`). @@ -1977,7 +2162,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds - ``sparse`` -- boolean (default: ``None``); whether to represent with a sparse matrix - - ``vertices`` -- list, ``None``, or ``True`` (default: ``None``); + - ``vertices`` -- list; ``None``, or ``True`` (default: ``None``) - when a list, the `i`-th row and column of the matrix correspond to the `i`-th vertex in the ordering of ``vertices``, @@ -1988,14 +2173,14 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds a matrix, where the module's basis is indexed by the vertices. If the vertices are not comparable, the keyword ``vertices`` must be - used to specify an ordering, or a :class:`TypeError` exception will + used to specify an ordering, or a :exc:`TypeError` exception will be raised. - ``base_ring`` -- a ring (default: ``ZZ``); the base ring of the matrix - space to use. + space to use - ``**kwds`` -- other keywords to pass to - :func:`~sage.matrix.constructor.matrix`. + :func:`~sage.matrix.constructor.matrix` EXAMPLES:: @@ -2208,7 +2393,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None - ``sparse`` -- boolean (default: ``True``); whether to use a sparse or a dense matrix - - ``vertices`` -- list, ``None``, or ``True`` (default: ``None``); + - ``vertices`` -- list; ``None``, or ``True`` (default: ``None``) - when a list, the `i`-th row of the matrix corresponds to the `i`-th vertex in the ordering of ``vertices``, @@ -2217,7 +2402,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None - when ``True``, construct a morphism of free modules instead of a matrix, where the codomain's basis is indexed by the vertices. - - ``edges`` -- list, ``None``, or ``True`` (default: ``None``); + - ``edges`` -- list; ``None``, or ``True`` (default: ``None``) - when a list, the `i`-th column of the matrix corresponds to the `i`-th edge in the ordering of ``edges``, @@ -2227,10 +2412,10 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None where the domain's basis is indexed by the edges. - ``base_ring`` -- a ring (default: ``ZZ``); the base ring of the matrix - space to use. + space to use - ``**kwds`` -- other keywords to pass to - :func:`~sage.matrix.constructor.matrix`. + :func:`~sage.matrix.constructor.matrix` EXAMPLES:: @@ -2470,7 +2655,7 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): when working with possibly non-sortable objects in Python 3. - ``base_ring`` -- a ring (default: determined from the weights); the base - ring of the matrix space to use. + ring of the matrix space to use - ``**kwds`` -- other keywords to pass to the subfunction :meth:`distance_all_pairs` or to @@ -2597,7 +2782,7 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, - ``sparse`` -- boolean (default: ``True``); whether to use a sparse or a dense matrix - - ``vertices`` -- list, ``None``, or ``True`` (default: ``None``); + - ``vertices`` -- list; ``None``, or ``True`` (default: ``None``) - when a list, the `i`-th row and column of the matrix correspond to the `i`-th vertex in the ordering of ``vertices``, @@ -2608,15 +2793,15 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, a matrix, where the module's basis is indexed by the vertices. If the vertices are not comparable, the keyword ``vertices`` must be - used to specify an ordering, or a :class:`TypeError` exception will + used to specify an ordering, or a :exc:`TypeError` exception will be raised. - - ``default_weight`` -- (default: ``None``); specifies the weight to + - ``default_weight`` -- (default: ``None``) specifies the weight to replace any ``None`` edge label. When not specified an error is raised if the label of an edge is ``None``. - ``base_ring`` -- a ring (default: determined from the weights); the base - ring of the matrix space to use. + ring of the matrix space to use - ``**kwds`` -- other keywords to pass to :func:`~sage.matrix.constructor.matrix` @@ -2762,7 +2947,7 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl INPUT: - - ``weighted`` -- boolean (default: ``None``); + - ``weighted`` -- boolean (default: ``None``) - If ``True``, the weighted adjacency matrix is used for `M`, and the diagonal matrix `D` takes into account the weight of edges (replace @@ -2774,7 +2959,7 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl is weighted. - ``indegree`` -- boolean (default: ``True``); this parameter is - considered only for digraphs. + considered only for digraphs - If ``True``, each diagonal entry of `D` is equal to the in-degree of the corresponding vertex @@ -2784,7 +2969,7 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl By default, ``indegree`` is set to ``True`` - - ``normalized`` -- boolean (default: ``False``); + - ``normalized`` -- boolean (default: ``False``) - If ``True``, the returned matrix is `D^{-1/2}(D+M)D^{-1/2}` for signless and `D^{-1/2}(D-M)D^{-1/2}` otherwise, a normalized @@ -2795,13 +2980,13 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl - Else, the matrix `D+M` for signless and `D-M` otherwise is returned - - ``signless`` -- boolean (default: ``False``); + - ``signless`` -- boolean (default: ``False``) - If ``True``, `D+M` is used in calculation of Kirchhoff matrix - Else, `D-M` is used in calculation of Kirchhoff matrix - - ``vertices`` -- list, ``None``, or ``True`` (default: ``None``); + - ``vertices`` -- list; ``None``, or ``True`` (default: ``None``) - when a list, the `i`-th row and column of the matrix correspond to the `i`-th vertex in the ordering of ``vertices``, @@ -2812,7 +2997,7 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl a matrix, where the module's basis is indexed by the vertices. If the vertices are not comparable, the keyword ``vertices`` must be - used to specify an ordering, or a :class:`TypeError` exception will + used to specify an ordering, or a :exc:`TypeError` exception will be raised. Note that any additional keywords will be passed on to either the @@ -2911,7 +3096,6 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl B⎜-1 3 -2 0⎟ C⎜-3 -2 5 0⎟ D⎝-4 0 0 4⎠ - """ from sage.matrix.constructor import diagonal_matrix, matrix @@ -3109,8 +3293,8 @@ def _check_embedding_validity(self, embedding=None, boolean=True): test. If set to ``None`` (default), the test is performed on ``_embedding`` - - ``boolean`` -- boolean (default: ``True``); -- whether to return a - boolean answer or raise a :class:`ValueError` exception + - ``boolean`` -- boolean (default: ``True``); whether to return a + boolean answer or raise a :exc:`ValueError` exception if the embedding is invalid EXAMPLES:: @@ -3149,7 +3333,6 @@ def _check_embedding_validity(self, embedding=None, boolean=True): Traceback (most recent call last): ... ValueError: the list associated with vertex 1 contains >1 occurrences of [0] - """ if embedding is None: try: @@ -3199,7 +3382,7 @@ def connected(u, v): def has_loops(self): """ - Return whether there are loops in the (di)graph + Return whether there are loops in the (di)graph. EXAMPLES:: @@ -3243,7 +3426,7 @@ def has_loops(self): def allows_loops(self): """ - Return whether loops are permitted in the (di)graph + Return whether loops are permitted in the (di)graph. EXAMPLES:: @@ -3287,7 +3470,7 @@ def allows_loops(self): def allow_loops(self, new, check=True): """ - Change whether loops are permitted in the (di)graph + Change whether loops are permitted in the (di)graph. INPUT: @@ -3340,7 +3523,7 @@ def allow_loops(self, new, check=True): def loop_edges(self, labels=True): """ - Return a list of all loops in the (di)graph + Return a list of all loops in the (di)graph. INPUT: @@ -3425,7 +3608,7 @@ def loop_edges(self, labels=True): def number_of_loops(self): """ - Return the number of edges that are loops + Return the number of edges that are loops. EXAMPLES:: @@ -3449,7 +3632,7 @@ def number_of_loops(self): def loop_vertices(self): """ - Return a list of vertices with loops + Return a list of vertices with loops. EXAMPLES:: @@ -3620,7 +3803,7 @@ def allow_multiple_edges(self, new, check=True, keep_label='any'): .. WARNING:: ``'min'`` and ``'max'`` only works if the labels can be compared. A - :class:`TypeError` might be raised when working with non-comparable + :exc:`TypeError` might be raised when working with non-comparable objects. EXAMPLES: @@ -4152,7 +4335,7 @@ def weighted(self, new=None): sage: H.weighted(True) sage: H == G False - sage: G_imm = Graph(G, data_structure="static_sparse") + sage: G_imm = Graph(G, data_structure='static_sparse') sage: G_imm == G True sage: G_imm.weighted() @@ -4170,7 +4353,6 @@ def weighted(self, new=None): False sage: G_mut == H True - """ if new is not None: if self.is_immutable(): @@ -4665,13 +4847,13 @@ def eulerian_circuit(self, return_vertices=False, labels=True, path=False): INPUT: - ``return_vertices`` -- boolean (default: ``False``); optionally - provide a list of vertices for the path + provide a list of vertices for the path - ``labels`` -- boolean (default: ``True``); whether to return edges - with labels (3-tuples) + with labels (3-tuples) - ``path`` -- boolean (default: ``False``); find an Eulerian path - instead + instead OUTPUT: @@ -4806,7 +4988,7 @@ def eulerian_circuit(self, return_vertices=False, labels=True, path=False): def min_spanning_tree(self, weight_function=None, - algorithm="Prim_Boost", + algorithm='Prim_Boost', starting_vertex=None, check=False, by_weight=False, @@ -4823,24 +5005,24 @@ def min_spanning_tree(self, INPUT: - - ``algorithm`` -- string (default: ``"Prim_Boost"``); the algorithm to + - ``algorithm`` -- string (default: ``'Prim_Boost'``); the algorithm to use in computing a minimum spanning tree of ``G``. The following algorithms are supported: - - ``"Prim_Boost"`` -- Prim's algorithm (Boost implementation) + - ``'Prim_Boost'`` -- Prim's algorithm (Boost implementation) - - ``"Prim_fringe"`` -- a variant of Prim's algorithm that ignores the + - ``'Prim_fringe'`` -- a variant of Prim's algorithm that ignores the labels on the edges - - ``"Prim_edge"`` -- a variant of Prim's algorithm + - ``'Prim_edge'`` -- a variant of Prim's algorithm - - ``"Kruskal"`` -- Kruskal's algorithm + - ``'Kruskal'`` -- Kruskal's algorithm - - ``"Filter_Kruskal"`` -- a variant of Kruskal's algorithm [OSS2009]_ + - ``'Filter_Kruskal'`` -- a variant of Kruskal's algorithm [OSS2009]_ - - ``"Kruskal_Boost"`` -- Kruskal's algorithm (Boost implementation) + - ``'Kruskal_Boost'`` -- Kruskal's algorithm (Boost implementation) - - ``"Boruvka"`` -- Boruvka's algorithm + - ``'Boruvka'`` -- Boruvka's algorithm - ``NetworkX`` -- uses NetworkX's minimum spanning tree implementation @@ -4867,7 +5049,7 @@ def min_spanning_tree(self, in the graph are weighted, otherwise all edges have weight 1 - ``check_weight`` -- boolean (default: ``True``); whether to check that - the ``weight_function`` outputs a number for each edge. + the ``weight_function`` outputs a number for each edge OUTPUT: @@ -5463,7 +5645,7 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa in the graph are weighted, otherwise all edges have weight 1 - ``check_weight`` -- boolean (default: ``True``); whether to check that - the ``weight_function`` outputs a number for each edge. + the ``weight_function`` outputs a number for each edge EXAMPLES:: @@ -5789,7 +5971,7 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, set_embedding=True, boundary=None, ordered=False, set_pos=False): r""" - Check whether the graph is circular planar (outerplanar) + Check whether the graph is circular planar (outerplanar). A graph is circular planar if it has a planar embedding in which all vertices can be drawn in order on a circle. This method can also be used @@ -6135,7 +6317,6 @@ def layout_planar(self, set_embedding=False, on_embedding=None, Traceback (most recent call last): ... ValueError: Petersen graph is not a planar graph - """ from sage.graphs.graph import Graph from sage.graphs.schnyder import _triangulate, _normal_label, _realizer, _compute_coordinates @@ -6365,7 +6546,7 @@ def genus(self, set_embedding=True, on_embedding=None, minimal=True, maximal=Fal - ``ordered`` -- boolean (default: ``True``); if ``circular`` is ``True``, then whether or not the boundary order may be permuted - (default is ``True``, which means the boundary order is preserved) + (default: ``True``, which means the boundary order is preserved) EXAMPLES:: @@ -6434,7 +6615,6 @@ def genus(self, set_embedding=True, on_embedding=None, minimal=True, maximal=Fal sage: G = graphs.RandomBlockGraph(10, 5) sage: G.genus() 10 - """ if not self.is_connected(): raise TypeError("the input Graph must be connected to use Euler's Formula to compute minimal genus") @@ -6922,7 +7102,6 @@ def planar_dual(self, embedding=None): Implement the method for graphs that are not 3-vertex-connected, or at least have a faster 3-vertex-connectivity test (:issue:`24635`). - """ self._scream_if_not_simple() @@ -6960,15 +7139,14 @@ def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, INPUT: - - ``vertices`` -- the vertices to be connected by the Steiner - Tree. + - ``vertices`` -- the vertices to be connected by the Steiner Tree - ``weighted`` -- boolean (default: ``False``); whether to consider the graph as weighted, and use each edge's label as a weight, considering ``None`` as a weight of `1`. If ``weighted=False`` (default) all edges are considered to have a weight of `1`. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -6976,7 +7154,7 @@ def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7116,21 +7294,21 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None - ``algorithm`` -- string (default: ``None``); specify the algorithm to use among: - * ``"Roskind-Tarjan"`` -- use the algorithm proposed by Roskind and + * ``'Roskind-Tarjan'`` -- use the algorithm proposed by Roskind and Tarjan [RT1985]_ for finding edge-disjoint spanning-trees in undirected simple graphs in time `O(m\log{m} + k^2n^2)`. - * ``"MILP"`` -- use a mixed integer linear programming + * ``'MILP'`` -- use a mixed integer linear programming formulation. This is the default method for directed graphs. - * ``None`` -- use ``"Roskind-Tarjan"`` for undirected graphs and - ``"MILP"`` for directed graphs. + * ``None`` -- use ``'Roskind-Tarjan'`` for undirected graphs and + ``'MILP'`` for directed graphs. - ``root`` -- vertex (default: ``None``); root of the disjoint arborescences when the graph is directed. If set to ``None``, the first vertex in the graph is picked. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7138,7 +7316,7 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7207,12 +7385,12 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None sage: # needs sage.numerical.mip sage: g = graphs.RandomGNP(12, .7) sage: k = Integer(g.edge_connectivity()) // 2 - sage: trees = g.edge_disjoint_spanning_trees(k, algorithm="MILP") + sage: trees = g.edge_disjoint_spanning_trees(k, algorithm='MILP') sage: all(t.is_tree() for t in trees) True sage: all(g.order() == t.size() + 1 for t in trees) True - sage: trees = g.edge_disjoint_spanning_trees(k, algorithm="Roskind-Tarjan") + sage: trees = g.edge_disjoint_spanning_trees(k, algorithm='Roskind-Tarjan') sage: all(t.is_tree() for t in trees) True sage: all(g.order() == t.size() + 1 for t in trees) @@ -7258,19 +7436,19 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None sage: # needs sage.numerical.mip sage: Graph().edge_disjoint_spanning_trees(0, algorithm=None) [] - sage: Graph().edge_disjoint_spanning_trees(0, algorithm="Roskind-Tarjan") + sage: Graph().edge_disjoint_spanning_trees(0, algorithm='Roskind-Tarjan') [] - sage: Graph().edge_disjoint_spanning_trees(0, algorithm="MILP") + sage: Graph().edge_disjoint_spanning_trees(0, algorithm='MILP') [] - sage: Graph().edge_disjoint_spanning_trees(0, algorithm="foo") + sage: Graph().edge_disjoint_spanning_trees(0, algorithm='foo') Traceback (most recent call last): ... ValueError: algorithm must be None, "Rosking-Tarjan" or "MILP" for undirected graphs sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm=None) [] - sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm="MILP") + sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm='MILP') [] - sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm="foo") + sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm='foo') Traceback (most recent call last): ... ValueError: algorithm must be None or "MILP" for directed graphs @@ -7365,6 +7543,22 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None p.add_constraint(pos[root, c] + BFS[u] <= pos[u, c]) # We now solve this program and extract the solution + + from sage.numerical.backends.glpk_backend import GLPKBackend + if isinstance(p.get_backend(), GLPKBackend): + # The MIP approach with GLPK is prone to compiler and + # optimization-level weirdness on some hardware: + # + # * https://github.com/sagemath/sage/issues/34575 + # * https://github.com/sagemath/sage/issues/38831 + # + # Disabling the presolver manages to perturb reality just + # enough in the one scenario that we doctest explicitly to + # "fix" the problem. It's also limited enough in scope + # that it probably hasn't badly broken some other use + # case. + p.solver_parameter("presolve_intopt", False) + try: p.solve(log=verbose) except MIPSolverException: @@ -7383,11 +7577,11 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None return classes def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, - algorithm="FF", solver=None, verbose=0, *, integrality_tolerance=1e-3): + algorithm='FF', solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" Return a minimum edge cut between vertices `s` and `t`. - A minimum edge cut between two vertices `s` and `t` of self is a set `A` + A minimum edge cut between two vertices `s` and `t` of ``self`` is a set `A` of edges of minimum weight such that the graph obtained by removing `A` from the graph is disconnected. For more information, see the :wikipedia:`Cut_(graph_theory)`. @@ -7428,7 +7622,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, * If ``algorithm = None``, the problem is solved using the default maximum flow algorithm (see :meth:`flow`) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7436,7 +7630,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7499,7 +7693,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, If algorithm is set to an exotic value:: sage: g = graphs.PetersenGraph() - sage: g.edge_cut(0, 1, algorithm="Divination") + sage: g.edge_cut(0, 1, algorithm='Divination') Traceback (most recent call last): ... ValueError: the algorithm argument has to be equal to "FF", "LP", "igraph", or None @@ -7509,18 +7703,18 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, sage: g = graphs.RandomGNP(20,.3) sage: for u,v in g.edges(sort=True, labels=False): ....: g.set_edge_label(u,v,round(random(),5)) - sage: g.edge_cut(0, 1, algorithm="FF") == g.edge_cut(0, 1, algorithm="LP") # needs sage.numerical.mip + sage: g.edge_cut(0, 1, algorithm='FF') == g.edge_cut(0, 1, algorithm='LP') # needs sage.numerical.mip True - sage: g.edge_cut(0, 1, algorithm="FF") == g.edge_cut(0, 1, algorithm="igraph") # optional - python_igraph + sage: g.edge_cut(0, 1, algorithm='FF') == g.edge_cut(0, 1, algorithm='igraph') # optional - python_igraph True Rounded return value when using the LP method:: sage: g = graphs.PappusGraph() - sage: g.edge_cut(1, 2, value_only=True, algorithm="LP") # needs sage.numerical.mip + sage: g.edge_cut(1, 2, value_only=True, algorithm='LP') # needs sage.numerical.mip 3 - :issue:`12797`:: + Check that :issue:`12797` and :issue:`38713` are fixed:: sage: G = Graph([(0, 3, 1), (0, 4, 1), (1, 2, 1), (2, 3, 1), (2, 4, 1)]) sage: G.edge_cut(0, 1, value_only=False, use_edge_labels=True) @@ -7529,7 +7723,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, sage: G.edge_cut(0, 1, value_only=False, use_edge_labels=True) [1, [(2, 1, 1)]] sage: G.edge_cut(0, 1, value_only=False, use_edge_labels=True, algorithm='LP') # needs sage.numerical.mip - (1, [(2, 1)]) + (1, [(2, 1, 1)]) """ self._scream_if_not_simple(allow_loops=True) if vertices: @@ -7582,9 +7776,10 @@ def weight(x): # frozensets otherwise if g.is_directed(): def good_edge(e): - return e + return (e[0], e[1]) else: - good_edge = frozenset + def good_edge(e): + return frozenset((e[0], e[1])) # Some vertices belong to part 1, others to part 0 p.add_constraint(v[s], min=0, max=0) @@ -7597,7 +7792,7 @@ def good_edge(e): # Adjacent vertices can belong to different parts only if the # edge that connects them is part of the cut - for x, y in g.edge_iterator(labels=None): + for x, y in g.edge_iterator(labels=False): p.add_constraint(v[x] + b[good_edge((x, y))] - v[y], min=0) else: @@ -7605,7 +7800,7 @@ def good_edge(e): p.set_objective(p.sum(weight(w) * b[good_edge((x, y))] for x, y, w in g.edge_iterator())) # Adjacent vertices can belong to different parts only if the # edge that connects them is part of the cut - for x, y in g.edge_iterator(labels=None): + for x, y in g.edge_iterator(labels=False): p.add_constraint(v[x] + b[good_edge((x, y))] - v[y], min=0) p.add_constraint(v[y] + b[good_edge((x, y))] - v[x], min=0) @@ -7620,7 +7815,7 @@ def good_edge(e): return obj answer = [obj] - answer.append([e for e in g.edge_iterator(labels=False) if b[good_edge(e)]]) + answer.append([e for e in g.edge_iterator(labels=True) if b[good_edge(e)]]) if vertices: v = p.get_values(v, convert=bool, tolerance=integrality_tolerance) @@ -7655,7 +7850,7 @@ def vertex_cut(self, s, t, value_only=True, vertices=False, solver=None, verbose the two sets of vertices that are disconnected by the cut. Implies ``value_only`` set to ``False``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7663,7 +7858,7 @@ def vertex_cut(self, s, t, value_only=True, vertices=False, solver=None, verbose :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7784,7 +7979,7 @@ def multiway_cut(self, vertices, value_only=False, use_edge_labels=False, defined by its label (if an edge has no label, `1` is assumed), or to compute a cut of minimum cardinality (i.e., edge weights are set to 1) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7792,7 +7987,7 @@ def multiway_cut(self, vertices, value_only=False, use_edge_labels=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7923,7 +8118,7 @@ def max_cut(self, value_only=True, use_edge_labels=False, vertices=False, two sets of vertices that are disconnected by the cut. This implies ``value_only=False``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7931,7 +8126,7 @@ def max_cut(self, value_only=True, use_edge_labels=False, vertices=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -8085,7 +8280,7 @@ def longest_cycle(self, induced=False, use_edge_labels=False, considered as a weight of `1`), or to compute a cycle with the largest possible number of edges (i.e., edge weights are set to 1) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -8093,8 +8288,8 @@ def longest_cycle(self, induced=False, use_edge_labels=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of - verbosity; set to ``0`` by default, which means quiet + - ``verbose`` -- integer (default: 0); sets the level of + verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers over an inexact base ring; see @@ -8372,7 +8567,7 @@ def F(e): best.set_pos({u: pp for u, pp in G.get_pos().items() if u in best}) return (best_w, best) if use_edge_labels else best - def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", + def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm='MILP', solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" Return a longest path of ``self``. @@ -8384,14 +8579,14 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", argument is set to ``None`` by default, which means that no constraint is set upon the first vertex in the path. - This parameter can only be used when ``algorithm`` is ``"MILP"``. + This parameter can only be used when ``algorithm`` is ``'MILP'``. - ``t`` -- a vertex (default: ``None``); forces the destination of the path (the method then returns the longest path ending at ``t``). The argument is set to ``None`` by default, which means that no constraint is set upon the last vertex in the path. - This parameter can only be used when ``algorithm`` is ``"MILP"``. + This parameter can only be used when ``algorithm`` is ``'MILP'``. - ``use_edge_labels`` -- boolean (default: ``False``); whether to compute a path with maximum weight where the weight of an edge is @@ -8399,21 +8594,21 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", considered as a weight of `1`), or to compute a path with the longest possible number of edges (i.e., edge weights are set to 1) - This parameter can only be used when ``algorithm`` is ``"MILP"``. + This parameter can only be used when ``algorithm`` is ``'MILP'``. - - ``algorithm`` -- string (default: ``"MILP"``); the algorithm to use - among ``"MILP"``, ``"backtrack"`` and ``"heuristic"``: + - ``algorithm`` -- string (default: ``'MILP'``); the algorithm to use + among ``'MILP'``, ``'backtrack'`` and ``'heuristic'``: - * ``"MILP"`` returns an exact answer. + * ``'MILP'`` returns an exact answer. - * ``"backtrack"`` is renamed ``"heuristic"`` (:issue:`36574`). + * ``'backtrack'`` is renamed ``'heuristic'`` (:issue:`36574`). - * ``"heuristic"`` is a randomized heuristic for finding a long path in + * ``'heuristic'`` is a randomized heuristic for finding a long path in an unweighted (di)graph. This heuristic does not take into account parameters ``s``, ``t`` and ``use_edge_labels``. An error is raised if these parameters are set. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -8421,7 +8616,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -8456,7 +8651,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", The heuristic totally agrees:: sage: g = graphs.PetersenGraph() - sage: p = g.longest_path(algorithm="heuristic").edges(sort=True, labels=False) + sage: p = g.longest_path(algorithm='heuristic').edges(sort=True, labels=False) sage: len(p) 9 @@ -8481,7 +8676,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", The argument ``algorithm`` must be either ``'backtrack'``, ``'heuristic'`` or ``'MILP'``:: - sage: graphs.PetersenGraph().longest_path(algorithm="abc") + sage: graphs.PetersenGraph().longest_path(algorithm='abc') Traceback (most recent call last): ... ValueError: algorithm must be either 'backtrack', 'heuristic' or 'MILP' @@ -8823,8 +9018,8 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, hamiltonian path. This parameter is considered only if ``use_edge_labels == True``. - - ``algorithm`` -- string (default: ``"MILP"``); the algorithm the use - among ``"MILP"`` and ``"backtrack"``; two remarks on this respect: + - ``algorithm`` -- string (default: ``'MILP'``); the algorithm the use + among ``'MILP'`` and ``'backtrack'``; two remarks on this respect: * While the MILP formulation returns an exact answer, the backtrack algorithm is a randomized heuristic. @@ -8832,7 +9027,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, * The backtrack algorithm does not support edge weighting, so setting ``use_edge_labels=True`` will force the use of the MILP algorithm. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -8840,7 +9035,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -8994,7 +9189,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, new_t = ones.pop() if not use_edge_labels and algorithm == "backtrack": - path = g.longest_path(s=new_s, t=new_t, algorithm="backtrack") + path = g.longest_path(s=new_s, t=new_t, algorithm='backtrack') return path if path.order() == g.order() else None # @@ -9051,7 +9246,7 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, verbose=0, verbose_constraints=False, *, integrality_tolerance=1e-3): r""" - Solve the traveling salesman problem (TSP) + Solve the traveling salesman problem (TSP). Given a graph (resp. a digraph) `G` with weighted edges, the traveling salesman problem consists in finding a Hamiltonian cycle (resp. circuit) @@ -9073,7 +9268,7 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, (or Hamiltonian cycle). This parameter is considered only if ``use_edge_labels == True``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -9088,7 +9283,7 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, When ``constraint_generation = None``, constraint generation is used whenever the graph has a density larger than 70%. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``verbose_constraints`` -- boolean (default: ``False``); whether to @@ -9579,7 +9774,7 @@ def hamiltonian_cycle(self, algorithm='tsp', solver=None, constraint_generation= - ``algorithm`` -- string (default: ``'tsp'``); one of 'tsp' or 'backtrack' - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -9594,7 +9789,7 @@ def hamiltonian_cycle(self, algorithm='tsp', solver=None, constraint_generation= When ``constraint_generation = None``, constraint generation is used whenever the graph has a density larger than 70%. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``verbose_constraints`` -- boolean (default: ``False``); whether to @@ -9607,7 +9802,7 @@ def hamiltonian_cycle(self, algorithm='tsp', solver=None, constraint_generation= OUTPUT: If using the ``'tsp'`` algorithm, returns a Hamiltonian cycle/circuit if - it exists; otherwise, raises a ``EmptySetError`` exception. If using the + it exists; otherwise, raises a :exc:`EmptySetError` exception. If using the ``'backtrack'`` algorithm, returns a pair ``(B, P)``. If ``B`` is ``True`` then ``P`` is a Hamiltonian cycle and if ``B`` is ``False``, ``P`` is a longest path found by the algorithm. Observe that if ``B`` is @@ -9666,7 +9861,6 @@ def hamiltonian_cycle(self, algorithm='tsp', solver=None, constraint_generation= sage: G = graphs.CubeGraph(3) sage: G.hamiltonian_cycle(algorithm='backtrack') (True, [...]) - """ if self.order() < 2: raise ValueError("the traveling salesman problem is not defined for empty or one-element graph") @@ -9705,7 +9899,7 @@ def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, the minimum cardinal of a minimum vertex set, or the ``Set`` of vertices of a minimal feedback vertex set - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -9713,7 +9907,7 @@ def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``constraint_generation`` -- boolean (default: ``True``); whether to @@ -9967,12 +10161,12 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, - ``algorithm`` -- string (default: ``None``); the algorithm to use among: - * ``"FF"``, a Python implementation of the Ford-Fulkerson algorithm + * ``'FF'``, a Python implementation of the Ford-Fulkerson algorithm (only available when ``vertex_bound = False``) - * ``"LP"``, the flow problem is solved using Linear Programming + * ``'LP'``, the flow problem is solved using Linear Programming - * ``"igraph"``, the ``igraph`` implementation of the Goldberg-Tarjan + * ``'igraph'``, the ``igraph`` implementation of the Goldberg-Tarjan algorithm is used (only available when ``igraph`` is installed and ``vertex_bound = False``) @@ -9980,7 +10174,7 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, True``, otherwise, we use ``igraph`` if it is available, ``FF`` if it is not available. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -9988,12 +10182,12 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, :class:`MixedIntegerLinearProgram `. - Only useful when algorithm ``"LP"`` is used to solve the flow problem. + Only useful when algorithm ``'LP'`` is used to solve the flow problem. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - Only useful when algorithm ``"LP"`` is used to solve the flow problem. + Only useful when algorithm ``'LP'`` is used to solve the flow problem. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers over an inexact base ring; see @@ -10056,18 +10250,18 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, = True``:: sage: g = graphs.PetersenGraph() - sage: g.flow(0, 1, vertex_bound=True, algorithm="FF") + sage: g.flow(0, 1, vertex_bound=True, algorithm='FF') Traceback (most recent call last): ... ValueError: this method does not support both vertex_bound=True and algorithm='FF' - sage: g.flow(0, 1, vertex_bound=True, algorithm="igraph") + sage: g.flow(0, 1, vertex_bound=True, algorithm='igraph') Traceback (most recent call last): ... ValueError: this method does not support both vertex_bound=True and algorithm='igraph' Or if the method is different from the expected values:: - sage: g.flow(0, 1, algorithm="Divination") + sage: g.flow(0, 1, algorithm='Divination') Traceback (most recent call last): ... ValueError: the algorithm argument has to be equal to either "FF", "LP", "igraph", or None @@ -10078,11 +10272,11 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, sage: g = graphs.RandomGNP(20, .3) sage: for u, v in g.edge_iterator(labels=False): ....: g.set_edge_label(u, v, round(random(), 5)) - sage: flow_ff = g.flow(0, 1, algorithm="FF") - sage: flow_lp = g.flow(0, 1, algorithm="LP") # needs sage.numerical.mip + sage: flow_ff = g.flow(0, 1, algorithm='FF') + sage: flow_lp = g.flow(0, 1, algorithm='LP') # needs sage.numerical.mip sage: abs(flow_ff - flow_lp) < 0.01 # needs sage.numerical.mip True - sage: flow_igraph = g.flow(0, 1, algorithm="igraph") # optional - python_igraph + sage: flow_igraph = g.flow(0, 1, algorithm='igraph') # optional - python_igraph sage: abs(flow_ff - flow_igraph) < 0.00001 # optional - python_igraph True """ @@ -10269,10 +10463,10 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler INPUT: - - ``k`` -- integer (default: ``6``); when set to a positive integer + - ``k`` -- integer (default: `6`); when set to a positive integer `\geq 2`, search for a `k`-nowhere zero flow - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -10280,7 +10474,7 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -10645,11 +10839,11 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, INPUT: - - ``terminals`` -- a list of pairs `(s_i, t_i)` or triples `(s_i, t_i, + - ``terminals`` -- list of pairs `(s_i, t_i)` or triples `(s_i, t_i, w_i)` representing a flow from `s_i` to `t_i` of intensity `w_i`. When the pairs are of size `2`, an intensity of `1` is assumed. - - ``integer`` boolean (default: ``True``); whether to require an integer + - ``integer`` -- boolean (default: ``True``); whether to require an integer multicommodity flow - ``use_edge_labels`` -- boolean (default: ``False``); whether to @@ -10663,7 +10857,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, units of flow even though ``vertex_bound`` is set to ``True``, as this parameter is meant to represent topological properties. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -10671,7 +10865,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -10823,14 +11017,14 @@ def capacity_sum(i, u, v): def _build_flow_graph(self, flow, integer): r""" - Build a "clean" flow graph + Build a "clean" flow graph. This method first builds the flow graph, and then looks for circuits and removes them. INPUT: - - ``flow`` -- a dictionary associating positive numerical values to + - ``flow`` -- dictionary associating positive numerical values to edges - ``integer`` -- boolean; whether the values from ``flow`` are the @@ -10916,7 +11110,7 @@ def disjoint_routed_paths(self, pairs, solver=None, verbose=0, - ``pairs`` -- list of pairs of vertices - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -10924,7 +11118,7 @@ def disjoint_routed_paths(self, pairs, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -10957,7 +11151,7 @@ def disjoint_routed_paths(self, pairs, solver=None, verbose=0, except EmptySetError: raise EmptySetError("the disjoint routed paths do not exist") - def edge_disjoint_paths(self, s, t, algorithm="FF", solver=None, verbose=False, + def edge_disjoint_paths(self, s, t, algorithm='FF', solver=None, verbose=False, *, integrality_tolerance=1e-3): r""" Return a list of edge-disjoint paths between two vertices. @@ -10971,14 +11165,14 @@ def edge_disjoint_paths(self, s, t, algorithm="FF", solver=None, verbose=False, INPUT: - - ``algorithm`` -- string (default: ``"FF"``); the algorithm to use + - ``algorithm`` -- string (default: ``'FF'``); the algorithm to use among: - * ``"FF"``, a Python implementation of the Ford-Fulkerson algorithm + * ``'FF'``, a Python implementation of the Ford-Fulkerson algorithm - * ``"LP"``, the flow problem is solved using Linear Programming + * ``'LP'``, the flow problem is solved using Linear Programming - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -10986,18 +11180,18 @@ def edge_disjoint_paths(self, s, t, algorithm="FF", solver=None, verbose=False, :class:`MixedIntegerLinearProgram `. - Only used when `àlgorithm`` is ``"LP"``. + Only used when ``algorithm`` is ``'LP'``. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - Only used when `àlgorithm`` is ``"LP"``. + Only used when ``algorithm`` is ``'LP'``. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers over an inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. - Only used when `àlgorithm`` is ``"LP"``. + Only used when ``algorithm`` is ``'LP'``. .. NOTE:: @@ -11042,9 +11236,9 @@ def vertex_disjoint_paths(self, s, t, solver=None, verbose=0, INPUT: - - ``s``, ``t`` -- two vertices of the graph. + - ``s``, ``t`` -- two vertices of the graph - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -11052,7 +11246,7 @@ def vertex_disjoint_paths(self, s, t, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -11111,17 +11305,17 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, INPUT: - - ``alpha`` -- float (default: ``0.85``); damping parameter for + - ``alpha`` -- float (default: `0.85`); damping parameter for PageRank. ``alpha`` is the click-through probability useful for preventing sinks. The probability at any step, that an imaginary surfer who is randomly clicking on links will continue is a damping factor d. - - ``personalization`` -- dict (default: ``None``); a dictionary keyed - by vertices associating to each vertex a value. The personalization - can be specified for a subset of the vertices, if not specified a - nodes personalization value will be taken as zero. The sum of the - values must be nonzero. + - ``personalization`` -- dictionary (default: ``None``); a dictionary + keyed by vertices associating to each vertex a value. The + personalization can be specified for a subset of the vertices, if not + specified a nodes personalization value will be taken as zero. The + sum of the values must be nonzero. By default (``None``), a uniform distribution is used. - ``by_weight`` -- boolean (default: ``False``); if ``True``, the edges @@ -11134,9 +11328,9 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, is not ``None``, else ``1`` as a weight. - ``check_weight`` -- boolean (default: ``True``); whether to check that - the ``weight_function`` outputs a number for each edge. + the ``weight_function`` outputs a number for each edge - - ``dangling`` -- dict (default: ``None``); a dictionary keyed by a + - ``dangling`` -- dictionary (default: ``None``); a dictionary keyed by a vertex the outedge of "dangling" vertices, (i.e., vertices without any outedges) points to and the dict value is the weight of that outedge. By default, dangling vertices are given outedges according @@ -11145,16 +11339,16 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, dict. - ``algorithm`` -- string (default: ``None``); the algorithm to use in - computing PageRank of ``G``. The following algorithms are - supported: + computing PageRank of ``G``. The following algorithms are + supported: - - ``NetworkX`` -- uses NetworkX's default implementation (Scipy as of 2.6) + - ``'NetworkX'`` -- uses NetworkX's default implementation (Scipy as of 2.6) - - ``"Scipy"`` -- uses Scipy's PageRank algorithm implementation + - ``'Scipy'`` -- uses Scipy's PageRank algorithm implementation - - ``"igraph"`` -- uses igraph's PageRank algorithm implementation + - ``'igraph'`` -- uses igraph's PageRank algorithm implementation - - ``"None"`` -- uses best implementation available + - ``None`` -- uses best implementation available OUTPUT: a dictionary containing the PageRank value of each node @@ -11169,7 +11363,7 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, sage: G = graphs.CycleGraph(4) sage: G.pagerank(algorithm="Networkx") # needs networkx {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25} - sage: G.pagerank(alpha=0.50, algorithm="igraph") # abs tol 1e-9, optional - python_igraph + sage: G.pagerank(alpha=0.50, algorithm='igraph') # abs tol 1e-9, optional - python_igraph {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25} sage: G = Graph([(1, 2, 40), (2, 3, 50), (3, 4, 60), ....: (1, 4, 70), (4, 5, 80), (5, 6, 20)]) @@ -11180,28 +11374,28 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(algorithm="NetworkX", by_weight=True) # abs tol 1e-9 # needs networkx + sage: G.pagerank(algorithm='NetworkX', by_weight=True) # abs tol 1e-9 # needs networkx {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, 4: 0.3063198690713853, 5: 0.1700057609707141, 6: 0.05390084497706962} - sage: G.pagerank(algorithm="Scipy") # abs tol 1e-9 # needs networkx scipy + sage: G.pagerank(algorithm='Scipy') # abs tol 1e-9 # needs networkx scipy {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(algorithm="Scipy", by_weight=True) # abs tol 1e-9 # needs networkx scipy + sage: G.pagerank(algorithm='Scipy', by_weight=True) # abs tol 1e-9 # needs networkx scipy {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, 4: 0.3063198690713853, 5: 0.1700057609707141, 6: 0.05390084497706962} - sage: G.pagerank(algorithm="igraph") # abs tol 1e-9, optional - python_igraph + sage: G.pagerank(algorithm='igraph') # abs tol 1e-9, optional - python_igraph {1: 0.16112198303979128, 2: 0.16195368558382262, 3: 0.16112198303979125, @@ -11226,7 +11420,7 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, TESTS:: sage: G = Graph([(1, 2), (2, 3), (3, 4), (1, 3)]) - sage: G.pagerank(algorithm="NetworkX", # needs networkx + sage: G.pagerank(algorithm='NetworkX', # needs networkx ....: personalization={1:0, 2:3, 3:-2, 4:-1}) Traceback (most recent call last): ... @@ -11235,7 +11429,6 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, .. SEEALSO:: * :wikipedia:`PageRank` - """ if not self.order(): return {} @@ -11292,9 +11485,7 @@ def add_vertex(self, name=None): with numeric labels, then ``G.add_vertex()`` could potentially be slow, if ``name=None``. - OUTPUT: - - If ``name=None``, the new vertex name is returned. ``None`` otherwise. + OUTPUT: if ``name=None``, the new vertex name is returned. ``None`` otherwise EXAMPLES:: @@ -11307,7 +11498,6 @@ def add_vertex(self, name=None): sage: D = DiGraph(); D.add_vertex(); D 0 Digraph on 1 vertex - """ return self._backend.add_vertex(name) @@ -11345,7 +11535,6 @@ def add_vertices(self, vertices): sage: G.add_vertices([1, 2, 3]) sage: G.add_vertices([4, None, None, 5]) [0, 6] - """ return self._backend.add_vertices(vertices) @@ -11433,7 +11622,6 @@ def delete_vertices(self, vertices): Deleting a non-existent vertex will raise an exception, in which case none of the vertices in ``vertices`` is deleted. - EXAMPLES:: sage: D = DiGraph({0: [1, 2, 3, 4, 5], 1: [2], 2: [3], 3: [4], 4: [5], 5: [1]}) @@ -11629,7 +11817,7 @@ def random_edge_iterator(self, *args, **kwds): INPUT: - ``*args`` and ``**kwds`` -- arguments to be passed down to the - :meth:`edge_iterator` method. + :meth:`edge_iterator` method EXAMPLES: @@ -11765,7 +11953,6 @@ def set_vertex(self, vertex, object): - ``object`` -- object to associate to vertex - EXAMPLES:: sage: T = graphs.TetrahedralGraph() @@ -11854,7 +12041,7 @@ def vertex_iterator(self, vertices=None, degree=None, vertex_property=None): - ``vertices`` -- iterated vertices are these intersected with the vertices of the (di)graph - - ``degree`` -- a nonnegative integer (default: ``None``); + - ``degree`` -- nonnegative integer (default: ``None``); a vertex ``v`` is kept if ``degree(v) == degree`` - ``vertex_property`` -- function (default: ``None``); a function @@ -11931,7 +12118,7 @@ def neighbor_iterator(self, vertex, closed=False): - ``vertex`` -- a vertex of ``self`` - - ``closed`` -- a boolean (default: ``False``); whether to + - ``closed`` -- boolean (default: ``False``); whether to return the closed neighborhood of ``vertex``, i.e., including ``vertex``, or the open neighborhood in which ``vertex`` is included only if there is a loop on that vertex. @@ -12005,7 +12192,7 @@ def vertices(self, sort=False, key=None, degree=None, vertex_property=None): vertex as its one argument and returns a value that can be used for comparisons in the sorting algorithm (we must have ``sort=True``) - - ``degree`` -- a nonnegative integer (default: ``None``); + - ``degree`` -- nonnegative integer (default: ``None``); a vertex ``v`` is kept if ``degree(v) == degree`` - ``vertex_property`` -- function (default: ``None``); a function @@ -12026,7 +12213,6 @@ def vertices(self, sort=False, key=None, degree=None, vertex_property=None): sorting of the edges, use the ``key`` argument, as illustrated in the examples below. - EXAMPLES:: sage: P = graphs.PetersenGraph() @@ -12107,7 +12293,7 @@ def neighbors(self, vertex, closed=False): - ``vertex`` -- a vertex of ``self`` - - ``closed`` -- a boolean (default: ``False``); whether to + - ``closed`` -- boolean (default: ``False``); whether to return the closed neighborhood of ``vertex``, i.e., including ``vertex``, or the open neighborhood in which ``vertex`` is included only if there is a loop on that vertex. @@ -12135,7 +12321,7 @@ def merge_vertices(self, vertices): `\exists v'\in S: (u,v')\in G`. The new vertex is named after the first vertex in the list given in - argument. If this first name is `None`, a new vertex is created. + argument. If this first name is ``None``, a new vertex is created. In the case of multigraphs, the multiplicity is preserved. @@ -12203,7 +12389,6 @@ def merge_vertices(self, vertices): sage: G = Graph(edgelist, loops=True, multiedges=False) sage: G.merge_vertices([0, 2, 1]); G.edges(sort=True) [(0, 0, 'c')] - """ if len(vertices) <= 1: return None @@ -12263,7 +12448,7 @@ def add_edge(self, u, v=None, label=None): You must either use the ``label`` keyword:: sage: G = Graph() - sage: G.add_edge((1, 2), label="label") + sage: G.add_edge((1, 2), label='label') sage: G.edges(sort=False) [(1, 2, 'label')] @@ -12310,7 +12495,7 @@ def add_edges(self, edges, loops=True): INPUT: - ``edges`` -- an iterable of edges, given either as ``(u, v)`` - or ``(u, v, label)``. + or ``(u, v, label)`` - ``loops`` -- boolean (default: ``True``); if ``False``, remove all loops ``(v, v)`` from the input iterator. If ``None``, remove loops @@ -12374,7 +12559,7 @@ def subdivide_edge(self, *args): INPUT: The following forms are all accepted to subdivide `8` times the edge - between vertices `1` and `2` labeled with ``"my_label"``. + between vertices `1` and `2` labeled with ``'my_label'``. - ``G.subdivide_edge( 1, 2, 8 )`` - ``G.subdivide_edge( (1, 2), 8 )`` @@ -12494,7 +12679,7 @@ def subdivide_edges(self, edges, k): INPUT: - - ``edges`` -- a list of edges + - ``edges`` -- list of edges - ``k`` -- integer; common length of the subdivisions @@ -12600,7 +12785,6 @@ def delete_edge(self, u, v=None, label=None): True sage: C.has_edge( (4, 5, 'label') ) # correct! False - """ if label is None: if v is None: @@ -12736,7 +12920,7 @@ def contract_edges(self, edges): INPUT: - - ``edges`` -- a list containing 2-tuples or 3-tuples that represent + - ``edges`` -- list containing 2-tuples or 3-tuples that represent edges EXAMPLES:: @@ -12898,7 +13082,7 @@ def set_edge_label(self, u, v, l): - ``u``, ``v`` -- the vertices (and direction if digraph) of the edge - - ``l`` -- the new label + - ``l`` -- the new label EXAMPLES:: @@ -13048,15 +13232,14 @@ def edges(self, vertices=None, labels=True, sort=False, key=None, the sorting algorithm - ``ignore_direction`` -- boolean (default: ``False``); only applies to - directed graphs. If ``True``, searches across edges in either - direction. + directed graphs. If ``True``, searches across edges in either + direction. - ``sort_vertices`` -- boolean (default: ``True``); only applies to undirected graphs. If ``True``, sort the ends of the edges. Not sorting the ends is faster. - - OUTPUT: A :class:`~EdgesView`. + OUTPUT: a :class:`~EdgesView` .. WARNING:: @@ -13312,11 +13495,11 @@ def edge_iterator(self, vertices=None, labels=True, ignore_direction=False, sort vertices or ``None`` - ``labels`` -- boolean (default: ``True``); if ``False``, each edge is - a tuple `(u,v)` of vertices + a tuple `(u,v)` of vertices - ``ignore_direction`` -- boolean (default: ``False``); only applies to - directed graphs. If ``True``, searches across edges in either - direction. + directed graphs. If ``True``, searches across edges in either + direction. - ``sort_vertices`` -- boolean (default: ``True``); only applies to undirected graphs. If ``True``, sort the ends of the edges. @@ -13403,7 +13586,7 @@ def edges_incident(self, vertices=None, labels=True, sort=False): vertices or ``None`` - ``labels`` -- boolean (default: ``True``); if ``False``, each edge is - a tuple `(u,v)` of vertices + a tuple `(u,v)` of vertices - ``sort`` -- boolean (default: ``False``); if ``True`` the returned list is sorted @@ -14083,7 +14266,7 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm INPUT: - - ``vertices`` -- (default: ``None``); an iterable container of + - ``vertices`` -- (default: ``None``) an iterable container of vertices, e.g. a list, set, graph, file or numeric array. If not passed (i.e., ``None``), defaults to the entire graph. @@ -14249,7 +14432,7 @@ def _subgraph_by_deleting(self, vertices=None, edges=None, inplace=False, INPUT: - - ``vertices`` -- (default: ``None``); an iterable container of + - ``vertices`` -- (default: ``None``) an iterable container of vertices, e.g. a list, set, graph, file or numeric array. If not passed (i.e., ``None``), defaults to the entire graph. @@ -14534,7 +14717,6 @@ def subgraph_search(self, G, induced=False): sage: C = G.subgraph_search(graphs.CycleGraph(4)) # needs sage.modules sage: C.edges(sort=True) # needs sage.modules [(0, 1, 0), (0, 3, 0), (1, 2, 1), (2, 3, 2)] - """ # return the first graph found by method subgraph_search_iterator for g in self.subgraph_search_iterator(G, induced=induced, return_graphs=True): @@ -14856,7 +15038,7 @@ def random_subgraph(self, p, inplace=False): vertices = [v for v in self if random() < p] return self.subgraph(vertices=vertices, inplace=inplace) - def is_chordal(self, certificate=False, algorithm="B"): + def is_chordal(self, certificate=False, algorithm='B'): r""" Check whether the given graph is chordal. @@ -14884,7 +15066,7 @@ def is_chordal(self, certificate=False, algorithm="B"): INPUT: - ``certificate`` -- boolean (default: ``False``); whether to return a - certificate. + certificate * If ``certificate = False`` (default), returns ``True`` or ``False`` accordingly. @@ -14898,8 +15080,8 @@ def is_chordal(self, certificate=False, algorithm="B"): ``Graph`` object) is an induced subgraph of ``self`` isomorphic to a hole. - - ``algorithm`` -- string (default: ``"B"``); the algorithm to choose - among ``"A"`` or ``"B"``. While they will agree on whether the given + - ``algorithm`` -- string (default: ``'B'``); the algorithm to choose + among ``'A'`` or ``'B'``. While they will agree on whether the given graph is chordal, they cannot be expected to return the same certificates. @@ -15255,9 +15437,9 @@ def is_interval(self, certificate=False): INPUT: - - ``certificate`` -- boolean (default: ``False``); + - ``certificate`` -- boolean (default: ``False``) - - When ``certificate=False``, returns ``True`` is the graph is an + - When ``certificate=False``, returns ``True`` if the graph is an interval graph and ``False`` otherwise - When ``certificate=True``, returns either ``(False, None)`` or @@ -15450,7 +15632,7 @@ def is_gallai_tree(self): def is_clique(self, vertices=None, directed_clique=False, induced=True, loops=False): """ - Check whether a set of vertices is a clique + Check whether a set of vertices is a clique. A clique is a set of vertices such that there is exactly one edge between any two vertices. @@ -15458,7 +15640,7 @@ def is_clique(self, vertices=None, directed_clique=False, induced=True, loops=Fa INPUT: - ``vertices`` -- a single vertex or an iterable container of vertices - (default: ``None); when set, check whether the set of vertices is a + (default: ``None``); when set, check whether the set of vertices is a clique, otherwise check whether ``self`` is a clique - ``directed_clique`` -- boolean (default: ``False``); if set to @@ -15693,7 +15875,7 @@ def is_independent_set(self, vertices=None): INPUT: - ``vertices`` -- a single vertex or an iterable container of vertices - (default: ``None); when set, check whether the given set of vertices + (default: ``None``); when set, check whether the given set of vertices is an independent set, otherwise, check whether the set of vertices of ``self`` is an independent set @@ -15796,7 +15978,6 @@ def is_subgraph(self, other, induced=True, up_to_isomorphism=False): Traceback (most recent call last): ... ValueError: the input parameter must be a DiGraph - """ from sage.graphs.graph import Graph from sage.graphs.digraph import DiGraph @@ -15836,7 +16017,7 @@ def cluster_triangles(self, nbunch=None, implementation=None): INPUT: - - ``nbunch`` -- a list of vertices (default: ``None); the vertices to + - ``nbunch`` -- list of vertices (default: ``None``); the vertices to inspect. If ``nbunch=None``, returns data for all vertices in the graph. @@ -15858,19 +16039,19 @@ def cluster_triangles(self, nbunch=None, implementation=None): :: sage: G = graphs.RandomGNP(20, .3) - sage: d1 = G.cluster_triangles(implementation="networkx") # needs networkx - sage: d2 = G.cluster_triangles(implementation="dense_copy") - sage: d3 = G.cluster_triangles(implementation="sparse_copy") + sage: d1 = G.cluster_triangles(implementation='networkx') # needs networkx + sage: d2 = G.cluster_triangles(implementation='dense_copy') + sage: d3 = G.cluster_triangles(implementation='sparse_copy') sage: d1 == d2 and d1 == d3 # needs networkx True TESTS:: - sage: DiGraph().cluster_triangles(implementation="networkx") # needs networkx + sage: DiGraph().cluster_triangles(implementation='networkx') # needs networkx Traceback (most recent call last): ... ValueError: the 'networkx' implementation does not support directed graphs - sage: Graph().cluster_triangles(implementation="welcome") + sage: Graph().cluster_triangles(implementation='welcome') Traceback (most recent call last): ... ValueError: the implementation can only be 'networkx', 'sparse_copy', 'dense_copy' or None @@ -15948,7 +16129,6 @@ def clustering_average(self, implementation=None): ....: for impl in impls] sage: max(coeffs) - min(coeffs) # tol abs 1e-12 0 - """ if implementation is None: from sage.graphs.base.dense_graph import DenseGraphBackend @@ -16161,7 +16341,7 @@ def distance(self, u, v, by_weight=False, weight_function=None, check_weight=Tru is not ``None``, else ``1`` as a weight. - ``check_weight`` -- boolean (default: ``True``); whether to check that - the ``weight_function`` outputs a number for each edge. + the ``weight_function`` outputs a number for each edge EXAMPLES:: @@ -16193,8 +16373,8 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, INPUT: - - ``by_weight`` boolean (default: `False``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + - ``by_weight`` -- boolean (default: ``False``); if ``True``, the edges in + the graph are weighted. If ``False``, all edges have weight 1. - ``algorithm`` -- string (default: ``None``); one of the following algorithms: @@ -16231,11 +16411,9 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, is not ``None``, else ``1`` as a weight. - ``check_weight`` -- boolean (default: ``True``); whether to check that - the ``weight_function`` outputs a number for each edge. + the ``weight_function`` outputs a number for each edge - OUTPUT: - - A doubly indexed dictionary + OUTPUT: a doubly indexed dictionary .. NOTE:: @@ -16298,11 +16476,9 @@ def power(self, k): INPUT: - ``k`` -- integer; the maximum path length for considering edges in - the power graph. - - OUTPUT: + the power graph - - The kth power graph based on shortest distances between nodes. + OUTPUT: the `k`-th power graph based on shortest distances between nodes EXAMPLES: @@ -16328,7 +16504,7 @@ def power(self, k): sage: PG = G.power(-2) Traceback (most recent call last): ... - ValueError: distance must be a non-negative integer, not -2 + ValueError: distance must be a nonnegative integer, not -2 Testing when k = 0:: @@ -16350,7 +16526,7 @@ def power(self, k): sage: PG = G.power(Infinity) Traceback (most recent call last): ... - ValueError: distance must be a non-negative integer, not +Infinity + ValueError: distance must be a nonnegative integer, not +Infinity Testing on graph with multiple edges:: @@ -16480,7 +16656,7 @@ def girth(self, certificate=False): return self._girth_bfs(odd=False, certificate=certificate) - def odd_girth(self, algorithm="bfs", certificate=False): + def odd_girth(self, algorithm='bfs', certificate=False): r""" Return the odd girth of the graph. @@ -16490,9 +16666,9 @@ def odd_girth(self, algorithm="bfs", certificate=False): INPUT: - - ``algorithm`` -- string (default: ``"bfs"``); the algorithm to use: + - ``algorithm`` -- string (default: ``'bfs'``); the algorithm to use: - - ``"bfs"`` -- BFS-based algorithm + - ``'bfs'`` -- BFS-based algorithm - any algorithm accepted by :meth:`~sage.matrix.matrix_integer_dense.Matrix_integer_dense.charpoly` @@ -16707,7 +16883,7 @@ def centrality_betweenness(self, k=None, normalized=True, weight=None, INPUT: - ``normalized`` -- boolean (default: ``True``); if set to ``False``, - result is not normalized. + result is not normalized - ``k`` -- integer (default: ``None``); if set to an integer, use ``k`` node samples to estimate betweenness. Higher values give better @@ -16725,7 +16901,7 @@ def centrality_betweenness(self, k=None, normalized=True, weight=None, rationals or on ``double`` C variables. Not available when ``algorithm="NetworkX"``. - - ``algorithm`` -- string (default: ``None``); can be either ``"Sage"`` + - ``algorithm`` -- string (default: ``None``); can be either ``'Sage'`` (see :mod:`~sage.graphs.centrality`), ``"NetworkX"`` or ``"None"``. In the latter case, Sage's algorithm will be used whenever possible. @@ -16762,8 +16938,8 @@ def centrality_betweenness(self, k=None, normalized=True, weight=None, sage: tests = ([graphs.RandomGNP(30,.1) for i in range(10)]+ # needs networkx ....: [digraphs.RandomDirectedGNP(30,.1) for i in range(10)]) sage: for g in tests: # needs networkx - ....: r1 = g.centrality_betweenness(algorithm="Sage",exact=0) - ....: r2 = g.centrality_betweenness(algorithm="Sage",exact=1) + ....: r1 = g.centrality_betweenness(algorithm='Sage',exact=0) + ....: r2 = g.centrality_betweenness(algorithm='Sage',exact=1) ....: r3 = g.centrality_betweenness(algorithm="NetworkX") ....: for x in g: ....: if max([r1[x],r2[x],r3[x]])-min([r1[x],r2[x],r3[x]]) > 0.01: @@ -16823,7 +16999,7 @@ def centrality_closeness(self, vert=None, by_weight=False, algorithm=None, INPUT: - ``vert`` -- the vertex or the list of vertices we want to analyze. If - ``None`` (default), all vertices are considered. + ``None`` (default), all vertices are considered - ``by_weight`` -- boolean (default: ``False``); if ``True``, the edges in the graph are weighted, and otherwise all edges have weight 1 @@ -16863,7 +17039,7 @@ def centrality_closeness(self, vert=None, by_weight=False, algorithm=None, weight, if ``l`` is not ``None``, else ``1`` as a weight. - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check - that the ``weight_function`` outputs a number for each edge. + that the ``weight_function`` outputs a number for each edge OUTPUT: @@ -16994,7 +17170,6 @@ def centrality_closeness(self, vert=None, by_weight=False, algorithm=None, sage: all( sum(abs(ci[v] - cj[v]) for v in g if g.degree(v)) < 1e-12 ....: for ci, cj in itertools.combinations(c, 2) ) True - """ by_weight, weight_function = self._get_weight_function(by_weight=by_weight, weight_function=weight_function, @@ -17106,8 +17281,8 @@ def triangles_count(self, algorithm=None): - ``'iter'`` iterates over the pairs of neighbors of each vertex. No copy of the graph is performed - - ``None`` -- for undirected graphs, uses ``"sparse_copy"`` or - ``"dense_copy"`` depending on whether the graph is stored as dense + - ``None`` -- for undirected graphs, uses ``'sparse_copy'`` or + ``'dense_copy'`` depending on whether the graph is stored as dense or sparse. For directed graphs, uses ``'iter'``. EXAMPLES: @@ -17157,7 +17332,7 @@ def triangles_count(self, algorithm=None): Traceback (most recent call last): ... ValueError: unknown algorithm "tip top" - sage: digraphs.Path(5).triangles_count(algorithm="sparse_copy") + sage: digraphs.Path(5).triangles_count(algorithm='sparse_copy') Traceback (most recent call last): ... ValueError: the value of algorithm(=sparse_copy) must be 'iter' or None for directed graphs @@ -17741,8 +17916,8 @@ def shortest_paths(self, u, by_weight=False, algorithm=None, - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check that the weight_function outputs a number for each edge - - ``cutoff`` -- integer (default: ``None``); integer depth to stop - search (used only if ``algorithm=='BFS'``) + - ``cutoff`` -- integer (default: ``None``); depth to stop search (used + only if ``algorithm=='BFS'``) EXAMPLES: @@ -18055,10 +18230,10 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, Checking that distances are equal regardless of the algorithm used:: sage: g = graphs.Grid2dGraph(5,5) - sage: d1 = g.shortest_path_lengths((0,0), algorithm="BFS") + sage: d1 = g.shortest_path_lengths((0,0), algorithm='BFS') sage: d2 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_NetworkX") # needs networkx - sage: d3 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_Boost") - sage: d4 = g.shortest_path_lengths((0,0), algorithm="Bellman-Ford_Boost") + sage: d3 = g.shortest_path_lengths((0,0), algorithm='Dijkstra_Boost') + sage: d4 = g.shortest_path_lengths((0,0), algorithm='Bellman-Ford_Boost') sage: d1 == d2 == d3 == d4 # needs networkx True """ @@ -18244,28 +18419,28 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None, Checking that distances are equal regardless of the algorithm used:: sage: g = graphs.Grid2dGraph(5,5) - sage: d1, _ = g.shortest_path_all_pairs(algorithm="BFS") - sage: d2, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall-Cython") - sage: d3, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall-Python") + sage: d1, _ = g.shortest_path_all_pairs(algorithm='BFS') + sage: d2, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall-Cython') + sage: d3, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall-Python') sage: d4, _ = g.shortest_path_all_pairs(algorithm="Dijkstra_NetworkX") # needs networkx - sage: d5, _ = g.shortest_path_all_pairs(algorithm="Dijkstra_Boost") - sage: d6, _ = g.shortest_path_all_pairs(algorithm="Johnson_Boost") - sage: d7, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall_Boost") - sage: d8, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall_SciPy") # needs scipy + sage: d5, _ = g.shortest_path_all_pairs(algorithm='Dijkstra_Boost') + sage: d6, _ = g.shortest_path_all_pairs(algorithm='Johnson_Boost') + sage: d7, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall_Boost') + sage: d8, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall_SciPy') # needs scipy sage: d1 == d2 == d3 == d4 == d5 == d6 == d7 == d8 # needs networkx scipy True Checking that distances are equal regardless of the algorithm used:: sage: g = digraphs.RandomDirectedGNM(6,12) - sage: d1, _ = g.shortest_path_all_pairs(algorithm="BFS") - sage: d2, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall-Cython") - sage: d3, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall-Python") + sage: d1, _ = g.shortest_path_all_pairs(algorithm='BFS') + sage: d2, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall-Cython') + sage: d3, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall-Python') sage: d4, _ = g.shortest_path_all_pairs(algorithm="Dijkstra_NetworkX") # needs networkx - sage: d5, _ = g.shortest_path_all_pairs(algorithm="Dijkstra_Boost") - sage: d6, _ = g.shortest_path_all_pairs(algorithm="Johnson_Boost") - sage: d7, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall_Boost") - sage: d8, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall_SciPy") # needs scipy + sage: d5, _ = g.shortest_path_all_pairs(algorithm='Dijkstra_Boost') + sage: d6, _ = g.shortest_path_all_pairs(algorithm='Johnson_Boost') + sage: d7, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall_Boost') + sage: d8, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall_SciPy') # needs scipy sage: d1 == d2 == d3 == d4 == d5 == d6 == d7 == d8 # needs networkx scipy True @@ -18276,18 +18451,18 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None, sage: import random sage: for v, w in g.edges(labels=False, sort=False): ....: g.add_edge(v, w, random.uniform(1, 10)) - sage: d1, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall-Python") + sage: d1, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall-Python') sage: d2, _ = g.shortest_path_all_pairs(algorithm="Dijkstra_NetworkX") # needs networkx - sage: d3, _ = g.shortest_path_all_pairs(algorithm="Dijkstra_Boost") - sage: d4, _ = g.shortest_path_all_pairs(algorithm="Johnson_Boost") - sage: d5, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall_Boost") - sage: d6, _ = g.shortest_path_all_pairs(algorithm="Floyd-Warshall_SciPy") # needs scipy + sage: d3, _ = g.shortest_path_all_pairs(algorithm='Dijkstra_Boost') + sage: d4, _ = g.shortest_path_all_pairs(algorithm='Johnson_Boost') + sage: d5, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall_Boost') + sage: d6, _ = g.shortest_path_all_pairs(algorithm='Floyd-Warshall_SciPy') # needs scipy sage: d1 == d2 == d3 == d4 == d5 == d6 # needs networkx scipy True Checking a random path is valid:: - sage: dist, path = g.shortest_path_all_pairs(algorithm="BFS") + sage: dist, path = g.shortest_path_all_pairs(algorithm='BFS') sage: u,v = g.random_vertex(), g.random_vertex() sage: p = [v] sage: while p[0] is not None: @@ -18345,7 +18520,7 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None, Wrong name for ``algorithm``:: - sage: g.shortest_path_all_pairs(algorithm="Bob") + sage: g.shortest_path_all_pairs(algorithm='Bob') Traceback (most recent call last): ... ValueError: unknown algorithm "Bob" @@ -18353,11 +18528,11 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None, Algorithms that do not work with weights:: sage: g = Graph({0: {1:1}, 1: {2:1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, sparse=True) - sage: g.shortest_path_all_pairs(algorithm="BFS", by_weight=True) + sage: g.shortest_path_all_pairs(algorithm='BFS', by_weight=True) Traceback (most recent call last): ... ValueError: algorithm 'BFS' does not work with weights - sage: g.shortest_path_all_pairs(algorithm="Floyd-Warshall-Cython", by_weight=True) + sage: g.shortest_path_all_pairs(algorithm='Floyd-Warshall-Cython', by_weight=True) Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Cython' does not work with weights @@ -18365,7 +18540,7 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None, Dijkstra with negative weights:: sage: g = Graph({0: {1:1}, 1: {2:1}, 2: {3: 1}, 3: {4: -2}, 4: {0: -2}}) - sage: g.shortest_path_all_pairs(algorithm="Dijkstra_Boost", by_weight=True) + sage: g.shortest_path_all_pairs(algorithm='Dijkstra_Boost', by_weight=True) Traceback (most recent call last): ... RuntimeError: Dijkstra algorithm does not work with negative weights, use Bellman-Ford instead @@ -18420,6 +18595,9 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None, M = self.adjacency_matrix(vertices=int_to_vertex) # We call the Floyd-Warshall method from SciPy + import numpy # to ensure numpy 2.0 compatibility + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") from numpy import array as np_array from scipy.sparse.csgraph import floyd_warshall dd, pp = floyd_warshall(np_array(M), directed=self.is_directed(), @@ -18528,7 +18706,7 @@ def wiener_index(self, by_weight=False, algorithm=None, - For ``by_weight==False`` only: - ``'BFS'`` -- the computation is done through a BFS centered on - each vertex successively. + each vertex successively - ``'Floyd-Warshall-Cython'`` -- the Cython implementation of the Floyd-Warshall algorithm. Usually slower than ``'BFS'``. @@ -18824,7 +19002,7 @@ def breadth_first_search(self, start, ignore_direction=False, - :meth:`depth_first_search ` -- depth-first search for fast compiled graphs. - - :meth:`depth_first_search` -- depth-first search for generic graphs. + - :meth:`depth_first_search` -- depth-first search for generic graphs EXAMPLES:: @@ -18921,14 +19099,14 @@ def breadth_first_search(self, start, ignore_direction=False, sage: list(G.breadth_first_search(1, report_distance=True, edges=True)) Traceback (most recent call last): ... - ValueError: parameters edges and report_distance cannot be True simultaneously + ValueError: parameters edges and report_distance cannot be ``True`` simultaneously """ from sage.rings.semirings.non_negative_integer_semiring import NN if (distance is not None and distance not in NN): - raise ValueError("distance must be a non-negative integer, not {0}".format(distance)) + raise ValueError("distance must be a nonnegative integer, not {0}".format(distance)) if (report_distance and edges): - raise ValueError("parameters edges and report_distance cannot be True simultaneously") + raise ValueError("parameters edges and report_distance cannot be ``True`` simultaneously") # Preferably use the Cython implementation if (neighbors is None and not isinstance(start, list) and distance is None @@ -18951,7 +19129,7 @@ def breadth_first_search(self, start, ignore_direction=False, # Non-existing start vertex is detected later if distance > 0. if not distance: for v in queue: - if not v[0] in self: + if v[0] not in self: raise LookupError("start vertex ({0}) is not a vertex of the graph".format(v[0])) for v, d in queue: @@ -19082,7 +19260,6 @@ def depth_first_search(self, start, ignore_direction=False, [1, 3, 6, 4, 5, 7, 2] sage: list(D.depth_first_search(1, ignore_direction=True, edges=True)) [(1, 3), (3, 6), (6, 7), (7, 5), (5, 4), (1, 2)] - """ # Preferably use the Cython implementation if (neighbors is None and not isinstance(start, list) @@ -19356,7 +19533,6 @@ def complement(self): Graph on 10 vertices sage: g.complement() Graph on 10 vertices - """ self._scream_if_not_simple() @@ -19393,7 +19569,7 @@ def to_simple(self, to_undirected=True, keep_label='any', immutable=None): .. WARNING:: ``'min'`` and ``'max'`` only works if the labels can be compared. A - :class:`TypeError` might be raised when working with non-comparable + :exc:`TypeError` might be raised when working with non-comparable objects. - ``immutable`` -- boolean (default: ``Non``); whether to create a @@ -19434,7 +19610,7 @@ def to_simple(self, to_undirected=True, keep_label='any', immutable=None): g = g.copy(immutable=True) return g - def disjoint_union(self, other, labels="pairs", immutable=None): + def disjoint_union(self, other, labels='pairs', immutable=None): """ Return the disjoint union of ``self`` and ``other``. @@ -19482,7 +19658,6 @@ def disjoint_union(self, other, labels="pairs", immutable=None): Custom path disjoint_union Cycle graph: Graph on 5 vertices sage: J.vertices(sort=True) [(0, 'a'), (0, 'b'), (1, 0), (1, 1), (1, 2)] - """ if (self._directed and not other._directed) or (not self._directed and other._directed): raise TypeError('both arguments must be of the same class') @@ -19586,8 +19761,8 @@ def union(self, other, immutable=None): raise TypeError('both arguments must be of the same class') multiedges = self.allows_multiple_edges() or other.allows_multiple_edges() - loops = self.allows_loops() or other.allows_loops() - weighted = self.weighted() and other.weighted() + loops = self.allows_loops() or other.allows_loops() + weighted = self.weighted() and other.weighted() if self._directed: from sage.graphs.digraph import DiGraph @@ -20163,16 +20338,16 @@ def is_transitively_reduced(self): # Visualization - def _color_by_label(self, format='hex', as_function=False, default_color="black"): + def _color_by_label(self, format='hex', as_function=False, default_color='black'): """ - Coloring of the edges according to their label for plotting + Color the edges according to their label for plotting. INPUT: - ``format`` -- "rgbtuple", "hex", ``True`` (same as "hex"), or a - function or dictionary assigning colors to labels (default: "hex") + function or dictionary assigning colors to labels (default: ``'hex'``) - - ``default_color`` -- a string (default: ``"black"``); the color of the + - ``default_color`` -- string (default: ``'black'``); the color of the labels. Setting ``default_color=None`` is the same as ``default_color="black"``. @@ -20180,7 +20355,7 @@ def _color_by_label(self, format='hex', as_function=False, default_color="black" coloring as a function assigning a color to each label, or as a dictionary mapping colors to list of edges - OUTPUT: A coloring of the edges of this graph. + OUTPUT: a coloring of the edges of this graph If ``as_function`` is ``True``, then the coloring is returned as a function assigning a color to each label. Otherwise (the default, for @@ -20343,14 +20518,14 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options): INPUT: - ``layout`` -- string (default: ``None``); specifies a layout algorithm - among ``"acyclic"``, ``"acyclic_dummy"``, ``"circular"``, - ``"ranked"``, ``"graphviz"``, ``"planar"``, ``"spring"``, - ``"forest"`` or ``"tree"`` + among ``'acyclic'``, ``'acyclic_dummy'``, ``'circular'``, + ``'ranked'``, ``'graphviz'``, ``'planar'``, ``'spring'``, + ``'forest'`` or ``'tree'`` - ``pos`` -- dictionary (default: ``None``); a dictionary of positions - - ``dim`` -- integer (default: ``2``); the number of dimensions of the - layout, 2 or 3 + - ``dim`` -- integer (default: `2`); the number of dimensions of the + layout, `2` or `3` - ``save_pos`` -- boolean (default: ``False``); whether to save the positions @@ -20377,7 +20552,7 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options): ('1', 0): [0.89..., -0.42...], ('1', 1): [2.26..., -0.87...]} - sage: g.layout(layout="acyclic_dummy", save_pos=True) + sage: g.layout(layout='acyclic_dummy', save_pos=True) {('0', 0): [0.3..., 0], ('0', 1): [0.3..., 1], ('1', 0): [0.6..., 0], @@ -20410,7 +20585,7 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options): sage: from sage.graphs.graph_plot import layout_options sage: for key, value in sorted(layout_options.items()): ....: print("option {} : {}".format(key, value)) - option by_component : Whether to do the spring layout by connected component -- a boolean. + option by_component : Whether to do the spring layout by connected component -- boolean. option dim : The dimension of the layout -- 2 or 3. option forest_roots : An iterable specifying which vertices to use as roots for the ``layout='forest'`` option. If no root is specified for a tree, then one is chosen close to the center of the tree. Ignored unless ``layout='forest'``. option heights : A dictionary mapping heights to the list of vertices at this height. @@ -20434,7 +20609,7 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options): ``'acyclic'`` layout. See :meth:`.layout_graphviz` for installation instructions. - A subclass may implement another layout algorithm ``"blah"``, by + A subclass may implement another layout algorithm ``'blah'``, by implementing a method ``.layout_blah``. It may override the default layout by overriding :meth:`.layout_default`, and similarly override the predefined layouts. @@ -20476,9 +20651,9 @@ def layout_spring(self, by_component=True, **options): INPUT: - - ``by_components`` -- boolean (default: ``True``); + - ``by_components`` -- boolean (default: ``True``) - - ``**options`` -- options for method + - ``**options`` -- options for method :meth:`~sage.graphs.generic_graph_pyx.spring_layout_fast` OUTPUT: a dictionary mapping vertices to positions @@ -20494,7 +20669,7 @@ def layout_spring(self, by_component=True, **options): 4: [2.14..., -0.30...], 5: [2.80..., 0.22...]} sage: g = graphs.LadderGraph(7) - sage: g.plot(layout="spring") # needs sage.plot + sage: g.plot(layout='spring') # needs sage.plot Graphics object consisting of 34 graphics primitives """ return spring_layout_fast(self, by_component=by_component, **options) @@ -20503,17 +20678,17 @@ def layout_spring(self, by_component=True, **options): def layout_ranked(self, heights=None, dim=2, spring=False, **options): """ - Return a ranked layout for this graph + Return a ranked layout for this graph. INPUT: - ``heights`` -- dictionary (default: ``None``); a dictionary mapping heights to the list of vertices at this height - - ``dim`` -- integer (default: ``2``); the number of dimensions of the - layout, 2 or 3 + - ``dim`` -- integer (default: `2`); the number of dimensions of the + layout, `2` or `3` - - ``spring`` -- boolean (default: ``False``); + - ``spring`` -- boolean (default: ``False``) - ``**options`` -- options for method :meth:`~sage.graphs.generic_graph_pyx.spring_layout_fast` @@ -20534,7 +20709,7 @@ def layout_ranked(self, heights=None, dim=2, spring=False, **options): 4: [1.33..., 1], 5: [1.33..., 2]} sage: g = graphs.LadderGraph(7) - sage: g.plot(layout="ranked", heights={i: (i, i+7) for i in range(7)}) # needs sage.plot + sage: g.plot(layout='ranked', heights={i: (i, i+7) for i in range(7)}) # needs sage.plot Graphics object consisting of 34 graphics primitives """ assert heights is not None @@ -20579,14 +20754,14 @@ def layout_ranked(self, heights=None, dim=2, spring=False, **options): def layout_extend_randomly(self, pos, dim=2): """ - Extend randomly a partial layout + Extend randomly a partial layout. INPUT: - - ``pos`` -- a dictionary mapping vertices to positions + - ``pos`` -- dictionary mapping vertices to positions - - ``dim`` -- integer (default: ``2``); the number of dimensions of the - layout, 2 or 3 + - ``dim`` -- integer (default: `2`); the number of dimensions of the + layout, `2` or `3` OUTPUT: a dictionary mapping vertices to positions @@ -20623,26 +20798,26 @@ def layout_extend_randomly(self, pos, dim=2): def layout_circular(self, dim=2, center=(0, 0), radius=1, shift=0, angle=0, **options): r""" - Return a circular layout for this graph + Return a circular layout for this graph. INPUT: - - ``dim`` -- integer (default: ``2``); the number of dimensions of the - layout, 2 or 3 + - ``dim`` -- integer (default: `2`); the number of dimensions of the + layout, `2` or `3` - ``center`` -- tuple (default: ``(0, 0)``); position of the center of the circle - - ``radius`` -- (default: 1); the radius of the circle + - ``radius`` -- (default: 1) the radius of the circle - - ``shift`` -- (default: 0); rotation of the circle. A value of + - ``shift`` -- (default: 0) rotation of the circle. A value of ``shift=1`` will replace in the drawing the `i`-th element of the list by the `(i-1)`-th. Non-integer values are admissible, and a value of `\alpha` corresponds to a rotation of the circle by an angle of `\alpha 2\pi/n` (where `n` is the number of vertices set on the circle). - - ``angle`` -- (default: 0); rotate the embedding of all vertices. For + - ``angle`` -- (default: 0) rotate the embedding of all vertices. For instance, when ``angle == 0``, the first vertex get position ``(center[0] + radius, center[1])``. With a value of `\pi/2`, the first vertex get position ``(center[0], center[1] + radius)``. @@ -20662,7 +20837,7 @@ def layout_circular(self, dim=2, center=(0, 0), radius=1, shift=0, angle=0, **op 4: (0.43..., -0.90...), 5: (0.97..., -0.22...), 6: (0.78..., 0.62...)} - sage: G.plot(layout="circular") # needs sage.plot + sage: G.plot(layout='circular') # needs sage.plot Graphics object consisting of 22 graphics primitives """ assert dim == 2, "3D circular layout not implemented" @@ -20671,7 +20846,7 @@ def layout_circular(self, dim=2, center=(0, 0), radius=1, shift=0, angle=0, **op radius=1, shift=0, angle=pi/2, return_dict=True) - def layout_forest(self, tree_orientation="down", forest_roots=None, + def layout_forest(self, tree_orientation='down', forest_roots=None, **options): """ Return an ordered forest layout for this graph. @@ -20735,7 +20910,7 @@ def layout_forest(self, tree_orientation="down", forest_roots=None, forest_roots=forest_roots, **options) - def layout_tree(self, tree_orientation="down", tree_root=None, + def layout_tree(self, tree_orientation='down', tree_root=None, dim=2, **options): r""" Return an ordered tree layout for this graph. @@ -20754,8 +20929,8 @@ def layout_tree(self, tree_orientation="down", tree_root=None, which the tree is growing, can be ``'up'``, ``'down'``, ``'left'`` or ``'right'`` - - ``dim`` -- integer (default: ``2``); the number of dimensions of the - layout, 2 or 3 + - ``dim`` -- integer (default: `2`); the number of dimensions of the + layout, `2` or `3` - ``**options`` -- other parameters not used here @@ -20768,7 +20943,7 @@ def layout_tree(self, tree_orientation="down", tree_root=None, EXAMPLES:: sage: G = graphs.RandomTree(80) - sage: G.plot(layout="tree", tree_orientation="right") # needs sage.plot + sage: G.plot(layout='tree', tree_orientation='right') # needs sage.plot Graphics object consisting of 160 graphics primitives sage: T = graphs.RandomLobster(25, 0.3, 0.3) # needs networkx @@ -20790,7 +20965,7 @@ def layout_tree(self, tree_orientation="down", tree_root=None, 6: [0.0, -2]} sage: G = graphs.BalancedTree(2, 4) # needs networkx - sage: G.plot(layout="tree", tree_root=0, tree_orientation="up") # needs networkx sage.plot + sage: G.plot(layout='tree', tree_root=0, tree_orientation='up') # needs networkx sage.plot Graphics object consisting of 62 graphics primitives Using the embedding when it exists:: @@ -20808,7 +20983,7 @@ def layout_tree(self, tree_orientation="down", tree_root=None, 6: [2.0, -1], 7: [1.0, -2], 8: [0.0, -2]} - sage: T.plot(layout="tree", tree_root=3) # needs sage.plot + sage: T.plot(layout='tree', tree_root=3) # needs sage.plot Graphics object consisting of 18 graphics primitives TESTS:: @@ -20878,7 +21053,7 @@ def layout_tree(self, tree_orientation="down", tree_root=None, def slide(v, dx): """ - shift the vertex ``v`` and its descendants to the right by ``dx`` + Shift the vertex ``v`` and its descendants to the right by ``dx``. Precondition: ``v`` and its descendants have already had their positions computed. @@ -20956,8 +21131,8 @@ def layout_graphviz(self, dim=2, prog='dot', **options): INPUT: - - ``dim`` -- integer (default: ``2``); the number of dimensions of the - layout, 2 or 3 + - ``dim`` -- integer (default: `2`); the number of dimensions of the + layout, `2` or `3` - ``prog`` -- one of "dot", "neato", "twopi", "circo", or "fdp" @@ -20980,7 +21155,7 @@ def layout_graphviz(self, dim=2, prog='dot', **options): ('...', ...): [...,...], ('...', ...): [...,...], ('...', ...): [...,...]} - sage: g.plot(layout="graphviz") # optional - dot2tex graphviz + sage: g.plot(layout='graphviz') # optional - dot2tex graphviz Graphics object consisting of 29 graphics primitives Note: the actual coordinates are not deterministic @@ -20989,16 +21164,16 @@ def layout_graphviz(self, dim=2, prog='dot', **options): layout program. One may specify an alternative layout program:: sage: # optional - dot2tex graphviz - sage: g.plot(layout="graphviz", prog="dot") + sage: g.plot(layout='graphviz', prog='dot') Graphics object consisting of 29 graphics primitives - sage: g.plot(layout="graphviz", prog="neato") + sage: g.plot(layout='graphviz', prog='neato') Graphics object consisting of 29 graphics primitives - sage: g.plot(layout="graphviz", prog="twopi") + sage: g.plot(layout='graphviz', prog='twopi') Graphics object consisting of 29 graphics primitives - sage: g.plot(layout="graphviz", prog="fdp") + sage: g.plot(layout='graphviz', prog='fdp') Graphics object consisting of 29 graphics primitives sage: g = graphs.BalancedTree(5,2) # needs networkx - sage: g.plot(layout="graphviz", prog="circo") # needs networkx + sage: g.plot(layout='graphviz', prog='circo') # needs networkx Graphics object consisting of 62 graphics primitives .. TODO:: @@ -21039,7 +21214,7 @@ def layout_graphviz(self, dim=2, prog='dot', **options): key_to_vertex = {key(v): v for v in self} import dot2tex - positions = dot2tex.dot2tex(self.graphviz_string(**options), format="positions", prog=prog) + positions = dot2tex.dot2tex(self.graphviz_string(**options), format='positions', prog=prog) return {key_to_vertex[key]: pos for key, pos in positions.items()} @@ -21049,7 +21224,7 @@ def _layout_bounding_box(self, pos): INPUT: - - ``pos`` -- a dictionary of positions + - ``pos`` -- dictionary of positions EXAMPLES:: @@ -21098,18 +21273,18 @@ def _circle_embedding(self, vertices, center=(0, 0), radius=1, shift=0, angle=0, ``list(vertices)``. - ``center`` -- tuple (default: `(0, 0)`); position of the center of the - circle. + circle - - ``radius`` -- (default: 1); the radius of the circle. + - ``radius`` -- (default: 1) the radius of the circle - - ``shift`` -- (default: 0); rotation of the circle. A value of + - ``shift`` -- (default: 0) rotation of the circle. A value of ``shift=1`` will replace in the drawing the `i`-th element of the list by the `(i-1)`-th. Non-integer values are admissible, and a value of `\alpha` corresponds to a rotation of the circle by an angle of `\alpha 2\pi/n` (where `n` is the number of vertices set on the circle). - - ``angle`` -- (default: 0); rotate the embedding of all vertices. For + - ``angle`` -- (default: 0) rotate the embedding of all vertices. For instance, when ``angle == 0``, the first vertex get position ``(center[0] + radius, center[1])``. With a value of `\pi/2`, the first vertex get position ``(center[0], center[1] + radius)``. @@ -21190,9 +21365,9 @@ def _line_embedding(self, vertices, first=(0, 0), last=(0, 1), return_dict=False etc.). The order of the vertices in the line embedding is given by ``list(vertices)``. - - ``first`` -- tuple (default: `(0, 0)`); first coordinate of the line. + - ``first`` -- tuple (default: `(0, 0)`); first coordinate of the line - - ``last`` -- tuple (default: `(0, 1)`); last coordinate of the line. + - ``last`` -- tuple (default: `(0, 1)`); last coordinate of the line - ``return_dict`` -- boolean (default: ``False``); by default the computed positions of the specified vertices are stored in the @@ -21295,7 +21470,7 @@ def graphplot(self, **options): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -21377,7 +21552,7 @@ def plot(self, **options): - ``vertex_size`` -- size of vertices displayed - ``vertex_shape`` -- the shape to draw the vertices, for example - ``"o"`` for circle or ``"s"`` for square. Whole list is available at + ``'o'`` for circle or ``'s'`` for square. Whole list is available at https://matplotlib.org/api/markers_api.html. (Not available for multiedge digraphs.) @@ -21404,7 +21579,7 @@ def plot(self, **options): - ``iterations`` -- integer; how many iterations of the spring layout algorithm to go through, if applicable - - ``color_by_label`` -- a boolean or dictionary or function (default: + - ``color_by_label`` -- boolean or dictionary or function (default: ``False``); whether to color each edge with a different color according to its label; the colors are chosen along a rainbow, unless they are specified by a function or dictionary mapping labels to @@ -21423,7 +21598,7 @@ def plot(self, **options): Otherwise, then one is chosen at random. Ignored unless ``layout='tree'``. - - ``tree_orientation`` -- string (default: ``"down"``); one of "up" or + - ``tree_orientation`` -- string (default: ``'down'``); one of "up" or "down". If "up" (resp., "down"), then the root of the tree will appear on the bottom (resp., top) and the tree will grow upwards (resp. downwards). Ignored unless ``layout='tree'``. @@ -21611,7 +21786,7 @@ def plot(self, **options): :: sage: t = DiGraph('JCC???@A??GO??CO??GO??') - sage: t.plot(layout='tree', tree_root=0, tree_orientation="up") # needs sage.plot + sage: t.plot(layout='tree', tree_root=0, tree_orientation='up') # needs sage.plot Graphics object consisting of 22 graphics primitives sage: D = DiGraph({0: [1, 2, 3], 2: [1, 4], 3: [0]}) sage: D.plot() # needs sage.plot @@ -21659,30 +21834,29 @@ def plot(self, **options): """ return self.graphplot(**options).plot() - def show(self, method="matplotlib", **kwds): + def show(self, method='matplotlib', **kwds): """ Show the (di)graph. INPUT: - - ``method`` -- string (default: ``"matplotlib"``); method to use to - display the graph, either ``"matplotlib"``, or ``"js"`` to visualize + - ``method`` -- string (default: ``'matplotlib'``); method to use to + display the graph, either ``'matplotlib'``, or ``'js'`` to visualize it in a browser using `d3.js `_. - Any other argument supported by the drawing functions: - - ``"matplotlib"`` -- see :meth:`GenericGraph.plot + - ``'matplotlib'`` -- see :meth:`GenericGraph.plot ` and :meth:`sage.plot.graphics.Graphics.show` - - ``"js"`` -- see :meth:`~sage.graphs.graph_plot_js.gen_html_code` + - ``'js'`` -- see :meth:`~sage.graphs.graph_plot_js.gen_html_code` EXAMPLES:: sage: C = graphs.CubeGraph(8) sage: P = C.plot(vertex_labels=False, vertex_size=0, graph_border=True) # needs sage.plot sage: P.show() # long time (3s on sage.math, 2011), needs sage.plot - """ if method == "js": from sage.graphs.graph_plot_js import gen_html_code @@ -21719,9 +21893,9 @@ def plot3d(self, bgcolor=(1, 1, 1), - ``bgcolor`` -- rgb tuple (default: ``(1,1,1)``) - - ``vertex_size`` -- float (default: ``0.06``) + - ``vertex_size`` -- float (default: `0.06`) - - ``vertex_labels`` -- a boolean (default: ``False``); whether to + - ``vertex_labels`` -- boolean (default: ``False``); whether to display vertices using text labels instead of spheres - ``vertex_colors`` -- dictionary (default: ``None``); optional @@ -21736,15 +21910,15 @@ def plot3d(self, bgcolor=(1, 1, 1), :mod:`~sage.plot.plot3d.tachyon` (default: ``(0,0,0)``), and each entry is a list of edges. - - ``color_by_label`` -- a boolean or dictionary or function (default: + - ``color_by_label`` -- boolean or dictionary or function (default: ``False``) whether to color each edge with a different color according to its label; the colors are chosen along a rainbow, unless they are specified by a function or dictionary mapping labels to colors; this option is incompatible with ``edge_color`` and ``edge_colors``. - - ``edge_size`` -- float (default: ``0.02``) + - ``edge_size`` -- float (default: `0.02`) - - ``edge_size2`` -- float (default: ``0.0325``); used for + - ``edge_size2`` -- float (default: `0.0325`); used for :class:`~sage.plot.plot3d.tachyon.Tachyon` sleeves - ``pos3d`` -- a position dictionary for the vertices @@ -21976,9 +22150,9 @@ def show3d(self, bgcolor=(1, 1, 1), vertex_colors=None, vertex_size=0.06, - ``bgcolor`` -- rgb tuple (default: ``(1,1,1)``) - - ``vertex_size`` -- float (default: ``0.06``) + - ``vertex_size`` -- float (default: `0.06`) - - ``vertex_labels`` -- a boolean (default: ``False``); whether to + - ``vertex_labels`` -- boolean (default: ``False``); whether to display vertices using text labels instead of spheres - ``vertex_colors`` -- dictionary (default: ``None``); optional @@ -21993,15 +22167,15 @@ def show3d(self, bgcolor=(1, 1, 1), vertex_colors=None, vertex_size=0.06, :mod:`~sage.plot.plot3d.tachyon` (default: ``(0,0,0)``), and each entry is a list of edges. - - ``color_by_label`` -- a boolean or dictionary or function (default: + - ``color_by_label`` -- boolean or dictionary or function (default: ``False``) whether to color each edge with a different color according to its label; the colors are chosen along a rainbow, unless they are specified by a function or dictionary mapping labels to colors; this option is incompatible with ``edge_color`` and ``edge_colors``. - - ``edge_size`` -- float (default: ``0.02``) + - ``edge_size`` -- float (default: `0.02`) - - ``edge_size2`` -- float (default: ``0.0325``); used for + - ``edge_size2`` -- float (default: `0.0325`); used for :class:`~sage.plot.plot3d.tachyon.Tachyon` sleeves - ``pos3d`` -- a position dictionary for the vertices @@ -22098,7 +22272,7 @@ def get_label(vertex): return get_label # String representation to be used by other programs - @options(labels="string", + @options(labels='string', vertex_labels=True, edge_labels=False, edge_color=None, edge_colors=None, edge_options=(), @@ -22115,8 +22289,8 @@ def graphviz_string(self, **options): INPUT: - - ``labels`` -- string (default: ``"string"``); either ``"string"`` or - ``"latex"``. If labels is ``"string"``, latex commands are not + - ``labels`` -- string (default: ``'string'``); either ``'string'`` or + ``'latex'``. If labels is ``'string'``, latex commands are not interpreted. This option stands for both vertex labels and edge labels. @@ -22126,14 +22300,14 @@ def graphviz_string(self, **options): - ``edge_labels`` -- boolean (default: ``False``); whether to add the labels on edges - - ``edge_color`` -- (default: ``None``); specify a default color for the + - ``edge_color`` -- (default: ``None``) specify a default color for the edges. The color could be one of - - a name given as a string such as ``"blue"`` or ``"orchid"`` + - a name given as a string such as ``'blue'`` or ``'orchid'`` - - a HSV sequence in a string such as ``".52,.386,.22"`` + - a HSV sequence in a string such as ``'.52,.386,.22'`` - - a hexadecimal code such as ``"#DA3305"`` + - a hexadecimal code such as ``'#DA3305'`` - a 3-tuple of floating point (to be interpreted as RGB tuple). In this case the 3-tuple is converted in hexadecimal code. @@ -22143,7 +22317,7 @@ def graphviz_string(self, **options): not to be complete in which case the default color is used. See the option ``edge_color`` for a description of valid color formats. - - ``color_by_label`` -- a boolean or dictionary or function (default: + - ``color_by_label`` -- boolean or dictionary or function (default: ``False``); whether to color each edge with a different color according to its label; the colors are chosen along a rainbow, unless they are specified by a function or dictionary mapping labels to @@ -22155,11 +22329,11 @@ def graphviz_string(self, **options): dictionary of options for this edge - ``rankdir`` -- ``'left'``, ``'right'``, ``'up'``, or ``'down'`` - (default: ``'down'``, for consistency with ``graphviz``): the + (default: ``'down'``, for consistency with ``graphviz``); the preferred ranking direction for acyclic layouts; see the ``rankdir`` option of ``graphviz``. - - ``subgraph_clusters`` -- a list of lists of vertices (default: + - ``subgraph_clusters`` -- list of lists of vertices (default: ``[]``); From [dotspec]_: "If supported, the layout engine will do the layout so that the nodes belonging to the cluster are drawn together, with the entire drawing of the cluster contained within a bounding @@ -22188,7 +22362,7 @@ def graphviz_string(self, **options): A variant, with the labels in latex, for post-processing with ``dot2tex``:: - sage: print(G.graphviz_string(edge_labels=True, labels="latex")) + sage: print(G.graphviz_string(edge_labels=True, labels='latex')) graph { node [shape="plaintext"]; node_0 [label=" ", texlbl="$0$"]; @@ -22206,7 +22380,7 @@ def graphviz_string(self, **options): sage: G = DiGraph({0: {1: None, 2: None}, 1: {2: None}, 2: {3: 'foo'}, 3: {}}, ....: sparse=True) - sage: print(G.graphviz_string(edge_color="red")) + sage: print(G.graphviz_string(edge_color='red')) digraph { node_0 [label="0"]; node_1 [label="1"]; @@ -22228,7 +22402,7 @@ def graphviz_string(self, **options): sage: G = DiGraph() sage: G.add_edges((i, f(i), f) for i in (1, 2, 1/2, 1/4)) sage: G.add_edges((i, g(i), g) for i in (1, 2, 1/2, 1/4)) - sage: print(G.graphviz_string(labels="latex", # random + sage: print(G.graphviz_string(labels='latex', # random ....: edge_labels=True)) digraph { node [shape="plaintext"]; @@ -22255,7 +22429,7 @@ def graphviz_string(self, **options): node_4 -> node_9 [label=" ", texlbl="$x \ {\mapsto}\ \frac{1}{x + 1}$"]; } - sage: print(G.graphviz_string(labels="latex", # random # needs sage.symbolic + sage: print(G.graphviz_string(labels='latex', # random # needs sage.symbolic ....: color_by_label=True)) digraph { node [shape="plaintext"]; @@ -22282,7 +22456,7 @@ def graphviz_string(self, **options): node_4 -> node_9 [color = "#00ffff"]; } - sage: print(G.graphviz_string(labels="latex", # random # needs sage.symbolic + sage: print(G.graphviz_string(labels='latex', # random # needs sage.symbolic ....: color_by_label={f: "red", g: "blue"})) digraph { node [shape="plaintext"]; @@ -22314,7 +22488,7 @@ def graphviz_string(self, **options): alternative ranking directions for this layout:: sage: D = DiGraph([(1, 2)]) - sage: print(D.graphviz_string(rankdir="up")) + sage: print(D.graphviz_string(rankdir='up')) digraph { rankdir=BT node_0 [label="1"]; @@ -22322,14 +22496,14 @@ def graphviz_string(self, **options): node_0 -> node_1; } - sage: print(D.graphviz_string(rankdir="down")) + sage: print(D.graphviz_string(rankdir='down')) digraph { node_0 [label="1"]; node_1 [label="2"]; node_0 -> node_1; } - sage: print(D.graphviz_string(rankdir="left")) + sage: print(D.graphviz_string(rankdir='left')) digraph { rankdir=RL node_0 [label="1"]; @@ -22337,7 +22511,7 @@ def graphviz_string(self, **options): node_0 -> node_1; } - sage: print(D.graphviz_string(rankdir="right")) + sage: print(D.graphviz_string(rankdir='right')) digraph { rankdir=LR node_0 [label="1"]; @@ -22350,13 +22524,13 @@ def graphviz_string(self, **options): tuple thereof) which maps each edge to a dictionary of options. Valid options are - - ``"color"`` - - ``"dot"`` (a string containing a sequence of options in ``dot`` format) - - ``"label"`` (a string) - - ``"label_style"`` (``"string"`` or ``"latex"``) - - ``"edge_string"`` (``"--"`` or ``"->"``) - - ``"dir"`` (``"forward"``, ``"back"``, ``"both"`` or ``"none"``) - - ``"backward"`` (boolean), instead of defining the edge in the + - ``'color'`` + - ``'dot'`` (a string containing a sequence of options in ``dot`` format) + - ``'label'`` (a string) + - ``'label_style'`` (``'string'`` or ``'latex'``) + - ``'edge_string'`` (``'--'`` or ``'->'``) + - ``'dir'`` (``'forward'``, ``'back'``, ``'both'`` or ``'none'``) + - ``'backward'`` (boolean), instead of defining the edge in the graphviz string as ``u -> v`` it draws it as ``v -> u [dir=back]`` and instead of ``u -> v [dir=back]`` it draws it as ``v -> u``, this changes the way it is drawn by Graphviz's dot @@ -22418,7 +22592,7 @@ def graphviz_string(self, **options): node_9 [label="1"]; node_10 [label="2"]; - node_2 -> node_3 [label="coucou", color = "red"]; + node_2 -> node_3 [label='coucou', color = "red"]; node_2 -> node_7 [x=1,y=2, color = "blue"]; node_4 -> node_5 [color = "red"]; node_4 -> node_8 [color = "blue"]; @@ -22705,7 +22879,7 @@ def graphviz_string(self, **options): for f in edge_option_functions: edge_options.update(f((u, v, label))) - if not edge_options['edge_string'] in ['--', '->']: + if edge_options['edge_string'] not in ['--', '->']: raise ValueError("edge_string(='{}') in edge_options dict for " "the edge ({}, {}) should be '--' or '->'" .format(edge_options['edge_string'], u, v)) @@ -22775,7 +22949,7 @@ def graphviz_to_file_named(self, filename, **options): ....: 2: {0: None, 1: None, 3: 'foo'}, 3: {2: 'foo'}}, ....: sparse=True) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(mode="a+t") as f: + sage: with tempfile.NamedTemporaryFile(mode='a+t') as f: ....: G.graphviz_to_file_named(f.name, edge_labels=True) ....: print(f.read()) graph { @@ -22790,7 +22964,7 @@ def graphviz_to_file_named(self, filename, **options): node_2 -- node_3 [label="foo"]; } """ - with open(filename, 'wt') as file: + with open(filename, "w") as file: file.write(self.graphviz_string(**options)) # Spectrum @@ -22885,7 +23059,7 @@ def characteristic_polynomial(self, var='x', laplacian=False): INPUT: - - ``x`` -- (default: ``'x'``); the variable of the characteristic + - ``x`` -- (default: ``'x'``) the variable of the characteristic polynomial - ``laplacian`` -- boolean (default: ``False``); if ``True``, use the @@ -23034,7 +23208,7 @@ def eigenspaces(self, laplacian=False): INPUT: - ``laplacian`` -- boolean (default: ``False``); if ``True``, use the - Laplacian matrix (see :meth:`kirchhoff_matrix`) + Laplacian matrix (see :meth:`kirchhoff_matrix`) OUTPUT: @@ -23144,28 +23318,28 @@ def eigenspaces(self, laplacian=False): def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, complete_partial_function=True, immutable=None): r""" - Relabels the vertices of ``self`` + Relabel the vertices of ``self``. INPUT: - - ``perm`` -- a function, dictionary, iterable, permutation, or - ``None`` (default: ``None``) + - ``perm`` -- a function, dictionary, iterable, permutation, or + ``None`` (default: ``None``) - - ``inplace`` -- a boolean (default: ``True``) + - ``inplace`` -- boolean (default: ``True``) - - ``return_map`` -- a boolean (default: ``False``) + - ``return_map`` -- boolean (default: ``False``) - - ``check_input`` (boolean) -- whether to test input for - correctness. *This can potentially be very time-consuming !*. + - ``check_input`` -- boolean; whether to test input for + correctness. *This can potentially be very time-consuming !* - - ``complete_partial_function`` (boolean) -- whether to automatically - complete the permutation if some elements of the graph are not - associated with any new name. In this case, those elements are not - relabeled *This can potentially be very time-consuming !*. + - ``complete_partial_function`` -- boolean; whether to automatically + complete the permutation if some elements of the graph are not + associated with any new name. In this case, those elements are not + relabeled *This can potentially be very time-consuming !*. - - ``immutable`` (boolean) -- with ``inplace=False``, whether to create - a mutable/immutable relabelled copy. ``immutable=None`` (default) - means that the graph and its copy will behave the same way. + - ``immutable`` -- boolean; with ``inplace=False``, whether to create + a mutable/immutable relabelled copy. ``immutable=None`` (default) + means that the graph and its copy will behave the same way. If ``perm`` is a function ``f``, then each vertex ``v`` is relabeled to ``f(v)``. @@ -23467,7 +23641,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c def degree_to_cell(self, vertex, cell): """ - Returns the number of edges from vertex to an edge in cell. In the + Return the number of edges from vertex to an edge in cell. In the case of a digraph, returns a tuple (in_degree, out_degree). EXAMPLES:: @@ -23500,8 +23674,8 @@ def degree_to_cell(self, vertex, cell): def is_equitable(self, partition, quotient_matrix=False): """ - Checks whether the given partition is equitable with respect to - self. + Check whether the given partition is equitable with respect to + ``self``. A partition is equitable with respect to a graph if for every pair of cells C1, C2 of the partition, the number of edges from a vertex @@ -23509,16 +23683,14 @@ def is_equitable(self, partition, quotient_matrix=False): INPUT: + - ``partition`` -- list of lists - - ``partition`` -- a list of lists - - - ``quotient_matrix`` -- (default: ``False``) if True, and - the partition is equitable, returns a matrix over the integers - whose rows and columns represent cells of the partition, and whose - i,j entry is the number of vertices in cell j adjacent to each - vertex in cell i (since the partition is equitable, this is well - defined) - + - ``quotient_matrix`` -- boolean (default: ``False``); if ``True``, and + the partition is equitable, returns a matrix over the integers + whose rows and columns represent cells of the partition, and whose + i,j entry is the number of vertices in cell j adjacent to each + vertex in cell i (since the partition is equitable, this is well + defined) EXAMPLES:: @@ -23584,7 +23756,7 @@ def is_equitable(self, partition, quotient_matrix=False): def coarsest_equitable_refinement(self, partition, sparse=True): r""" Return the coarsest partition which is finer than the input - partition, and equitable with respect to self. + partition, and equitable with respect to ``self``. A partition is equitable with respect to a graph if for every pair of cells `C_1`, `C_2` of the partition, the number of edges from a vertex @@ -23595,10 +23767,10 @@ def coarsest_equitable_refinement(self, partition, sparse=True): INPUT: - - ``partition`` -- a list of lists + - ``partition`` -- list of lists - ``sparse`` -- boolean (default: ``False``); whether to use sparse or - dense representation - for small graphs, use dense for speed + dense representation - for small graphs, use dense for speed EXAMPLES:: @@ -23683,28 +23855,28 @@ def automorphism_group(self, partition=None, verbosity=0, INPUT: - - ``partition`` -- default is the unit partition, - otherwise computes the subgroup of the full automorphism group - respecting the partition. + - ``partition`` -- default is the unit partition, + otherwise computes the subgroup of the full automorphism group + respecting the partition. - - ``edge_labels`` -- default ``False``, otherwise allows - only permutations respecting edge labels. + - ``edge_labels`` -- (default: ``False``) whether to allow + only permutations respecting edge labels - - ``order`` -- (default ``False``) if ``True``, compute the - order of the automorphism group + - ``order`` -- (default: ``False``) if ``True``, compute the + order of the automorphism group - - ``return_group`` -- default ``True`` + - ``return_group`` -- (default: ``True``) - - ``orbits`` -- returns the orbits of the group acting - on the vertices of the graph + - ``orbits`` -- returns the orbits of the group acting + on the vertices of the graph - - ``algorithm`` -- If ``algorithm = "bliss"``, the automorphism group is + - ``algorithm`` -- if ``algorithm='bliss'``, the automorphism group is computed using the optional package bliss (http://www.tcs.tkk.fi/Software/bliss/index.html). Setting it to - ``"sage"`` uses Sage's implementation. If set to ``None`` (default), bliss + ``'sage'`` uses Sage's implementation. If set to ``None`` (default), bliss is used when available. - OUTPUT: The order of the output is group, order, orbits. However, there + OUTPUT: the order of the output is group, order, orbits. However, there are options to turn each of these on or off. EXAMPLES: @@ -23770,10 +23942,10 @@ def automorphism_group(self, partition=None, verbosity=0, sage: G.automorphism_group(edge_labels=True) # needs sage.groups Permutation Group with generators [(1,4)(2,3)] - sage: G.automorphism_group(edge_labels=True, algorithm="bliss") # optional - bliss + sage: G.automorphism_group(edge_labels=True, algorithm='bliss') # optional - bliss Permutation Group with generators [(1,4)(2,3)] - sage: G.automorphism_group(edge_labels=True, algorithm="sage") # needs sage.groups + sage: G.automorphism_group(edge_labels=True, algorithm='sage') # needs sage.groups Permutation Group with generators [(1,4)(2,3)] :: @@ -23829,7 +24001,7 @@ def automorphism_group(self, partition=None, verbosity=0, TESTS: - We get a :class:`KeyError` when given an invalid partition (:issue:`6087`):: + We get a :exc:`KeyError` when given an invalid partition (:issue:`6087`):: sage: g = graphs.CubeGraph(3) sage: g.relabel() @@ -23858,7 +24030,7 @@ def automorphism_group(self, partition=None, verbosity=0, sage: g = graphs.PetersenGraph() sage: ag = g.automorphism_group() # needs sage.groups - sage: all(len(ag.orbit(e, action="OnPairs")) == 30 # needs sage.groups + sage: all(len(ag.orbit(e, action='OnPairs')) == 30 # needs sage.groups ....: for e in g.edge_iterator(labels=False)) True @@ -24048,9 +24220,9 @@ def is_vertex_transitive(self, partition=None, verbosity=0, edge_labels=False, order=False, return_group=True, orbits=False): """ - Returns whether the automorphism group of self is transitive within + Return whether the automorphism group of ``self`` is transitive within the partition provided, by default the unit partition of the - vertices of self (thus by default tests for vertex transitivity in + vertices of ``self`` (thus by default tests for vertex transitivity in the usual sense). EXAMPLES:: @@ -24102,7 +24274,7 @@ def is_hamiltonian(self, solver=None, constraint_generation=None, INPUT: - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -24110,12 +24282,12 @@ def is_hamiltonian(self, solver=None, constraint_generation=None, :class:`MixedIntegerLinearProgram `. - - ``constraint_generation`` (boolean) -- whether to use constraint + - ``constraint_generation`` -- boolean; whether to use constraint generation when solving the Mixed Integer Linear Program. When ``constraint_generation = None``, constraint generation is used whenever the graph has a density larger than 70%. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``verbose_constraints`` -- boolean (default: ``False``); whether to @@ -24178,11 +24350,11 @@ def is_hamiltonian(self, solver=None, constraint_generation=None, def is_isomorphic(self, other, certificate=False, verbosity=0, edge_labels=False): r""" - Tests for isomorphism between self and other. + Test for isomorphism between ``self`` and ``other``. INPUT: - - ``certificate`` -- if True, then output is `(a, b)`, where `a` + - ``certificate`` -- if ``True``, then output is `(a, b)`, where `a` is a boolean and `b` is either a map or ``None`` - ``edge_labels`` -- boolean (default: ``False``); if ``True`` allows @@ -24406,7 +24578,6 @@ def is_isomorphic(self, other, certificate=False, verbosity=0, edge_labels=False (True, {6: 'x', 7: 'y'}) sage: A.is_isomorphic(B, certificate=True, edge_labels=True) (False, None) - """ if not self.order() and not other.order(): return (True, None) if certificate else True @@ -24516,15 +24687,15 @@ class by some canonization function `c`. If `G` and `H` are graphs, to this set partition will be computed. The default is the unit set partition. - - ``certificate`` -- boolean (default: ``False``). When set to + - ``certificate`` -- boolean (default: ``False``); when set to ``True``, a dictionary mapping from the vertices of the (di)graph to its canonical label will also be returned. - - ``edge_labels`` -- boolean (default: ``False``). When set to - ``True``, allows only permutations respecting edge labels. + - ``edge_labels`` -- boolean (default: ``False``); when set to + ``True``, allows only permutations respecting edge labels - - ``algorithm`` -- a string (default: ``None``). The algorithm to use; - currently available: + - ``algorithm`` -- string (default: ``None``); the algorithm to use. + Currently available: * ``'bliss'``: use the optional package bliss (http://www.tcs.tkk.fi/Software/bliss/index.html); @@ -24536,7 +24707,7 @@ class by some canonization function `c`. If `G` and `H` are graphs, Make sure you always compare canonical forms obtained by the same algorithm. - - ``return_graph`` -- boolean (default: ``True``). When set to + - ``return_graph`` -- boolean (default: ``True``); when set to ``False``, returns the list of edges of the canonical graph instead of the canonical graph; only available when ``'bliss'`` is explicitly set as algorithm. @@ -24593,11 +24764,11 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: G.add_edges( [(0,1,'a'),(1,2,'b'),(2,3,'c'),(3,4,'b'),(4,0,'a')] ) sage: G.canonical_label(edge_labels=True) Graph on 5 vertices - sage: G.canonical_label(edge_labels=True, algorithm="bliss", # optional - bliss + sage: G.canonical_label(edge_labels=True, algorithm='bliss', # optional - bliss ....: certificate=True) (Graph on 5 vertices, {0: 4, 1: 3, 2: 1, 3: 0, 4: 2}) - sage: G.canonical_label(edge_labels=True, algorithm="sage", + sage: G.canonical_label(edge_labels=True, algorithm='sage', ....: certificate=True) (Graph on 5 vertices, {0: 4, 1: 3, 2: 0, 3: 1, 4: 2}) @@ -24772,18 +24943,19 @@ def is_cayley(self, return_group=False, mapping=False, INPUT: - - ``return_group`` (boolean; ``False``) -- If ``True``, return a group for - which the graph is a Cayley graph. + - ``return_group`` -- boolean (default: ``False``); if ``True``, return + a group for which the graph is a Cayley graph - - ``mapping`` (boolean; ``False``) -- If ``True``, return a mapping from - vertices to group elements. + - ``mapping`` -- boolean (default: ``False``); if ``True``, return a + mapping from vertices to group elements - - ``generators`` (boolean; ``False``) -- If ``True``, return the generating - set of the Cayley graph. + - ``generators`` -- boolean (default: ``False``); if ``True``, return + the generating set of the Cayley graph - - ``allow_disconnected`` (boolean; ``False``) -- If ``True``, disconnected - graphs are considered Cayley if they can be obtained from the Cayley - construction with a generating set that does not generate the group. + - ``allow_disconnected`` -- boolean (default: ``False``); if ``True``, + disconnected graphs are considered Cayley if they can be obtained + from the Cayley construction with a generating set that does not + generate the group. ALGORITHM: @@ -25032,7 +25204,9 @@ def is_self_complementary(self): from sage.graphs.connectivity import blocks_and_cut_vertices from sage.graphs.connectivity import blocks_and_cuts_tree from sage.graphs.connectivity import is_cut_edge + from sage.graphs.connectivity import is_edge_cut from sage.graphs.connectivity import is_cut_vertex + from sage.graphs.connectivity import is_vertex_cut from sage.graphs.connectivity import edge_connectivity from sage.graphs.connectivity import vertex_connectivity from sage.graphs.distances_all_pairs import szeged_index @@ -25076,7 +25250,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): absolute eigenvalue of the adjacency matrix) - ``nonedgesonly`` -- boolean (default: ``True``); if ``True``, value - for each edge present in the graph is set to zero. + for each edge present in the graph is set to zero - ``vertices`` -- list (default: ``None``); the ordering of the vertices defining how they should appear in the matrix. By default, @@ -25197,7 +25371,7 @@ def katz_centrality(self, alpha, u=None): - ``u`` -- the vertex whose Katz centrality needs to be measured (default: ``None``) - OUTPUT: a list containing the Katz centrality of each vertex if u=None + OUTPUT: list containing the Katz centrality of each vertex if u=None otherwise Katz centrality of the vertex u. EXAMPLES: @@ -25247,7 +25421,6 @@ def katz_centrality(self, alpha, u=None): 21/379 sage: (graphs.PathGraph(3) + graphs.PathGraph(4)).katz_centrality(1/20) {0: 11/199, 1: 21/199, 2: 11/199, 3: 21/379, 4: 41/379, 5: 41/379, 6: 21/379} - """ n = self.order() if n == 0: @@ -25509,9 +25682,10 @@ def tachyon_vertex_plot(g, bgcolor=(1, 1, 1), dictionary used for the plot. INPUT: - - ``pos3d`` -- a 3D layout of the vertices - - various rendering options + - ``pos3d`` -- a 3D layout of the vertices + + - various rendering options EXAMPLES:: @@ -25611,7 +25785,7 @@ def graph_isom_equivalent_non_edge_labeled_graph(g, partition=None, standard_lab vertices as a list of lists of vertices. If given, the partition of the vertices is as well relabeled - - ``standard_label`` -- (default: ``None``); edges in ``g`` with + - ``standard_label`` -- (default: ``None``) edges in ``g`` with this label are preserved in the new graph - ``return_relabeling`` -- boolean (default: ``False``); whether @@ -25626,7 +25800,7 @@ def graph_isom_equivalent_non_edge_labeled_graph(g, partition=None, standard_lab that attributes of ``g`` are *not* copied for speed issues, only edges and vertices. - - ``ignore_edge_labels`` -- boolean (default: ``False``): if + - ``ignore_edge_labels`` -- boolean (default: ``False``); if ``True``, ignore edge labels, so when constructing the new graph, only multiple edges are replaced with vertices. Labels on multiple edges are ignored -- only the multiplicity is relevant, @@ -25854,7 +26028,7 @@ def graph_isom_equivalent_non_edge_labeled_graph(g, partition=None, standard_lab # The groups are ordered by increasing multiplicity edge_partition = [tmp[mu] for mu in sorted(tmp.keys())] - # Now the edges are partitionned according to the multiplicity they + # Now the edges are partitioned according to the multiplicity they # represent, and edge labels are forgotten. else: diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index 9c6690bb8c5..a350ceeba86 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -123,7 +123,7 @@ def layout_split(layout_function, G, **options): def spring_layout_fast(G, iterations=50, int dim=2, vpos=None, bint rescale=True, bint height=False, by_component=False, **options): """ - Spring force model layout + Spring force model layout. This function primarily acts as a wrapper around :func:`run_spring`, converting to and from raw C types. @@ -134,7 +134,7 @@ def spring_layout_fast(G, iterations=50, int dim=2, vpos=None, bint rescale=True INPUT: - - ``by_component`` -- a boolean + - ``by_component`` -- boolean EXAMPLES:: @@ -272,25 +272,21 @@ cdef run_spring(int iterations, dimension_t _dim, double* pos, int* edges, int n INPUT: - iterations -- number of steps to take - _dim -- number of dimensions of freedom. Provide a value of type - `D_TWO` for 2 dimensions, or type `D_THREE` for three - dimensions. The actual value does not matter: only its - type is important. - pos -- already initialized initial positions - Each vertex is stored as [dim] consecutive doubles. - These doubles are then placed consecutively in the array. - For example, if dim=3, we would have - pos = [x_1, y_1, z_1, x_2, y_2, z_2, ... , x_n, y_n, z_n] - edges -- List of edges, sorted lexicographically by the first - (smallest) vertex, terminated by -1, -1. - The first two entries represent the first edge, and so on. - n -- number of vertices in the graph - height -- if True, do not update the last coordinate ever - - OUTPUT: - - Modifies contents of pos. + - ``iterations`` -- number of steps to take + - ``_dim`` -- number of dimensions of freedom. Provide a value of type `D_TWO` + for 2 dimensions, or type `D_THREE` for three dimensions. The actual + value does not matter: only its type is important. + - ``pos`` -- already initialized initial positions. Each vertex is stored as + [dim] consecutive doubles. These doubles are then placed consecutively + in the array. For example, if dim=3, we would have + pos = [x_1, y_1, z_1, x_2, y_2, z_2, ... , x_n, y_n, z_n] + - ``edges`` -- List of edges, sorted lexicographically by the first (smallest) + vertex, terminated by -1, -1. The first two entries represent the first + edge, and so on. + - ``n`` -- number of vertices in the graph + - ``height`` -- if ``True``, do not update the last coordinate ever + + OUTPUT: modifies contents of pos AUTHOR: @@ -417,7 +413,7 @@ def int_to_binary_string(n): INPUT: - - ``n`` (integer) + - ``n`` -- integer EXAMPLES:: @@ -447,7 +443,7 @@ def binary_string_to_graph6(x): INPUT: - - ``x`` -- a binary string. + - ``x`` -- a binary string EXAMPLES:: @@ -474,7 +470,7 @@ def small_integer_to_graph6(n): INPUT: - - ``n`` (integer) + - ``n`` -- integer EXAMPLES:: @@ -501,7 +497,7 @@ def length_and_string_from_graph6(s): INPUT: - ``s`` -- a graph6 string describing a binary vector (and encoding its - length). + length) EXAMPLES:: @@ -536,7 +532,7 @@ def length_and_string_from_graph6(s): def binary_string_from_graph6(s, n): r""" - Decode a binary string from its graph6 representation + Decode a binary string from its graph6 representation. This helper function is the inverse of `R` from [McK2015]_. @@ -544,7 +540,7 @@ def binary_string_from_graph6(s, n): - ``s`` -- a graph6 string - - ``n`` -- the length of the binary string encoded by ``s``. + - ``n`` -- the length of the binary string encoded by ``s`` EXAMPLES:: @@ -582,7 +578,7 @@ def binary_string_from_dig6(s, n): - ``s`` -- a graph6 string - - ``n`` -- the length of the binary string encoded by ``s``. + - ``n`` -- the length of the binary string encoded by ``s`` EXAMPLES:: @@ -637,11 +633,10 @@ cdef class SubgraphSearch: .. NOTE:: This algorithm does not take vertex/edge labels into account. - """ def __init__(self, G, H, induced=False): r""" - Constructor + Constructor. This constructor only checks there is no inconsistency in the input : `G` and `H` are both graphs or both digraphs and that `H` @@ -705,7 +700,7 @@ cdef class SubgraphSearch: def cardinality(self): r""" - Returns the number of labelled subgraphs of `G` isomorphic to + Return the number of labelled subgraphs of `G` isomorphic to `H`. .. NOTE:: @@ -807,7 +802,7 @@ cdef class SubgraphSearch: def __cinit__(self, G, H, induced=False): r""" - Cython constructor + Cython constructor. This method initializes all the C values. @@ -895,7 +890,7 @@ cdef class SubgraphSearch: def __next__(self): r""" - Returns the next isomorphic subgraph if any, and raises a + Return the next isomorphic subgraph if any, and raises a ``StopIteration`` otherwise. EXAMPLES:: @@ -981,20 +976,18 @@ cdef class SubgraphSearch: cdef inline bint vectors_equal(int n, int *a, int *b) noexcept: r""" - Tests whether the two given vectors are equal. Two integer vectors + Test whether the two given vectors are equal. Two integer vectors `a = (a_1, a_2, \dots, a_n)` and `b = (b_1, b_2, \dots, b_n)` are equal iff `a_i = b_i` for all `i = 1, 2, \dots, n`. See the function ``_test_vectors_equal_inferior()`` for unit tests. INPUT: - - ``n`` -- positive integer; length of the vectors. - - - ``a``, ``b`` -- two vectors of integers. + - ``n`` -- positive integer; length of the vectors - OUTPUT: + - ``a``, ``b`` -- two vectors of integers - - ``True`` if ``a`` and ``b`` are the same vector; ``False`` otherwise. + OUTPUT: ``True`` if ``a`` and ``b`` are the same vector; ``False`` otherwise """ cdef int i for i in range(n): @@ -1004,7 +997,7 @@ cdef inline bint vectors_equal(int n, int *a, int *b) noexcept: cdef inline bint vectors_inferior(int n, int *a, int *b) noexcept: r""" - Tests whether the second vector of integers is inferior to the first. Let + Test whether the second vector of integers is inferior to the first. Let `u = (u_1, u_2, \dots, u_k)` and `v = (v_1, v_2, \dots, v_k)` be two integer vectors of equal length. Then `u` is said to be less than (or inferior to) `v` if `u_i \leq v_i` for all `i = 1, 2, \dots, k`. See @@ -1015,9 +1008,9 @@ cdef inline bint vectors_inferior(int n, int *a, int *b) noexcept: INPUT: - - ``n`` -- positive integer; length of the vectors. + - ``n`` -- positive integer; length of the vectors - - ``a``, ``b`` -- two vectors of integers. + - ``a``, ``b`` -- two vectors of integers OUTPUT: @@ -1182,14 +1175,14 @@ cpdef tuple find_hamiltonian(G, long max_iter=100000, long reset_bound=30000, - ``max_iter`` -- maximum number of iterations - ``reset_bound`` -- number of iterations before restarting the - procedure + procedure - ``backtrack_bound`` -- number of iterations to elapse before - discarding the last 5 vertices of the path. + discarding the last 5 vertices of the path - - ``find_path`` -- (default: ``False``) if set to ``True``, will - search a Hamiltonian path; if ``False``, will search for a - Hamiltonian cycle + - ``find_path`` -- boolean (default: ``False``); if set to ``True``, will + search a Hamiltonian path. If ``False``, will search for a Hamiltonian + cycle. OUTPUT: @@ -1381,8 +1374,7 @@ cpdef tuple find_hamiltonian(G, long max_iter=100000, long reset_bound=30000, # static copy of the graph for more efficient operations cdef list int_to_vertex = list(G) cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=True) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef short_digraph rev_sd cdef bint reverse = False if directed: @@ -1572,7 +1564,7 @@ def transitive_reduction_acyclic(G): INPUT: - - ``G`` -- an acyclic digraph. + - ``G`` -- an acyclic digraph EXAMPLES:: diff --git a/src/sage/graphs/genus.pyx b/src/sage/graphs/genus.pyx index 0ef32627af8..ec524fd1a7a 100644 --- a/src/sage/graphs/genus.pyx +++ b/src/sage/graphs/genus.pyx @@ -235,7 +235,6 @@ cdef class simple_connected_genus_backtracker: sage: gb = sage.graphs.genus.simple_connected_genus_backtracker(G._backend.c_graph()[0]) sage: gb.get_embedding() {} - """ if not self.num_verts: return {} @@ -402,7 +401,7 @@ cdef class simple_connected_genus_backtracker: def genus(self, int style=1, int cutoff=0, bint record_embedding=False): r""" - Compute the minimal or maximal genus of self's graph. + Compute the minimal or maximal genus of ``self``'s graph. Note, this is a remarkably naive algorithm for a very difficult problem. Most interesting cases will take millennia to finish, with the exception @@ -410,10 +409,10 @@ cdef class simple_connected_genus_backtracker: INPUT: - - ``style`` -- integer (default: ``1``); find minimum genus if 1, + - ``style`` -- integer (default: `1`); find minimum genus if 1, maximum genus if 2 - - ``cutoff`` -- integer (default: ``0``); stop searching if search style + - ``cutoff`` -- integer (default: `0`); stop searching if search style is 1 and ``genus`` `\leq` ``cutoff``, or if style is 2 and ``genus`` `\geq` ``cutoff``. This is useful where the genus of the graph has a known bound. @@ -422,9 +421,7 @@ cdef class simple_connected_genus_backtracker: to remember the best embedding seen. This embedding can be retrieved with ``self.get_embedding()``. - OUTPUT: - - the minimal or maximal genus for self's graph. + OUTPUT: the minimal or maximal genus for ``self``'s graph EXAMPLES:: @@ -480,8 +477,8 @@ cdef class simple_connected_genus_backtracker: """ Here's the main backtracking routine. - We iterate over all embeddings of self's graph by considering all - cyclic orderings of `self.vertex_darts`. We use the Steinhaus- + We iterate over all embeddings of ``self``'s graph by considering all + cyclic orderings of ``self.vertex_darts``. We use the Steinhaus- Johnson-Trotter algorithm to enumerate these by walking over a poly-ary Gray code, and each time the Gray code would flip a bit, we apply the next adjacent transposition from S-J-T at that vertex. @@ -588,7 +585,6 @@ def simple_connected_graph_genus(G, set_embedding=False, check=True, minimal=Tru REFERENCES: [1] http://www.springerlink.com/content/0776127h0r7548v7/ - """ cdef int style, cutoff oG = G # original graph diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 3eda130f4d8..33029f74c5c 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -199,7 +199,7 @@ sage: G = Graph(M); G Graph on 10 vertices sage: G.plot().show() # or G.show() # needs sage.plot - sage: DiGraph(matrix(2, [0,0,-1,1]), format="incidence_matrix") + sage: DiGraph(matrix(2, [0,0,-1,1]), format='incidence_matrix') Traceback (most recent call last): ... ValueError: there must be two nonzero entries (-1 & 1) per column @@ -362,7 +362,7 @@ sage: G = graphs.RandomGNP(15,.3) sage: G.show() # needs sage.plot -And you can view it in three dimensions via jmol with ``show3d()``. :: +And you can view it in three dimensions with ``show3d()``. :: sage: G.show3d() # needs sage.plot @@ -528,13 +528,13 @@ class Graph(GenericGraph): 3: [-1, 1]} - ``name`` -- (must be an explicitly named parameter, i.e., - ``name="complete")`` gives the graph a name + ``name='complete')`` gives the graph a name - ``loops`` -- boolean (default: ``None``); whether to allow loops (ignored - if data is an instance of the ``Graph`` class) + if data is an instance of the ``Graph`` class) - ``multiedges`` -- boolean (default: ``None``); whether to allow multiple - edges (ignored if data is an instance of the ``Graph`` class). + edges (ignored if data is an instance of the ``Graph`` class) - ``weighted`` -- boolean (default: ``None``); whether graph thinks of itself as weighted or not. See @@ -542,11 +542,11 @@ class Graph(GenericGraph): - ``format`` -- if set to ``None`` (default), :class:`Graph` tries to guess input's format. To avoid this possibly time-consuming step, one of the - following values can be specified (see description above): ``"int"``, - ``"graph6"``, ``"sparse6"``, ``"rule"``, ``"list_of_edges"``, - ``"dict_of_lists"``, ``"dict_of_dicts"``, ``"adjacency_matrix"``, - ``"weighted_adjacency_matrix"``, ``"seidel_adjacency_matrix"``, - ``"incidence_matrix"``, ``"NX"``, ``"igraph"``. + following values can be specified (see description above): ``'int'``, + ``'graph6'``, ``'sparse6'``, ``'rule'``, ``'list_of_edges'``, + ``'dict_of_lists'``, ``'dict_of_dicts'``, ``'adjacency_matrix'``, + ``'weighted_adjacency_matrix'``, ``'seidel_adjacency_matrix'``, + ``'incidence_matrix'``, ``"NX"``, ``'igraph'``. - ``sparse`` -- boolean (default: ``True``); ``sparse=True`` is an alias for ``data_structure="sparse"``, and ``sparse=False`` is an alias for @@ -555,13 +555,13 @@ class Graph(GenericGraph): - ``data_structure`` -- one of the following (for more information, see :mod:`~sage.graphs.base.overview`) - * ``"dense"`` -- selects the :mod:`~sage.graphs.base.dense_graph` + * ``'dense'`` -- selects the :mod:`~sage.graphs.base.dense_graph` backend. - * ``"sparse"`` -- selects the :mod:`~sage.graphs.base.sparse_graph` + * ``'sparse'`` -- selects the :mod:`~sage.graphs.base.sparse_graph` backend. - * ``"static_sparse"`` -- selects the + * ``'static_sparse'`` -- selects the :mod:`~sage.graphs.base.static_sparse_backend` (this backend is faster than the sparse backend and smaller in memory, and it is immutable, so that the resulting graphs can be used as dictionary keys). @@ -580,9 +580,9 @@ class Graph(GenericGraph): is the number of vertices. - ``convert_empty_dict_labels_to_None`` -- this arguments sets the default - edge labels used by NetworkX (empty dictionaries) to be replaced by - ``None``, the default Sage edge label. It is set to ``True`` iff a - NetworkX graph is on the input. + edge labels used by NetworkX (empty dictionaries) to be replaced by + ``None``, the default Sage edge label. It is set to ``True`` iff a + NetworkX graph is on the input. EXAMPLES: @@ -788,7 +788,7 @@ class Graph(GenericGraph): ....: regular_symmetric_hadamard_matrix_with_constant_diagonal as rshcd) sage: m = rshcd(16,1) - matrix.identity(16) # needs sage.combinat sage.modules sage: Graph(m, # needs sage.combinat sage.modules - ....: format="seidel_adjacency_matrix").is_strongly_regular(parameters=True) + ....: format='seidel_adjacency_matrix').is_strongly_regular(parameters=True) (16, 6, 2, 2) #. List of edges, or labelled edges:: @@ -880,7 +880,7 @@ class Graph(GenericGraph): TESTS:: - sage: Graph(4, format="HeyHeyHey") + sage: Graph(4, format='HeyHeyHey') Traceback (most recent call last): ... ValueError: Unknown input format 'HeyHeyHey' @@ -893,16 +893,16 @@ class Graph(GenericGraph): sage: # needs sage.modules sage: m = matrix([[0, -1], [-1, 0]]) - sage: Graph(m, format="seidel_adjacency_matrix") + sage: Graph(m, format='seidel_adjacency_matrix') Graph on 2 vertices sage: m[0,1] = 1 - sage: Graph(m, format="seidel_adjacency_matrix") + sage: Graph(m, format='seidel_adjacency_matrix') Traceback (most recent call last): ... ValueError: the adjacency matrix of a Seidel graph must be symmetric sage: m[0,1] = -1; m[1,1] = 1 # needs sage.modules - sage: Graph(m, format="seidel_adjacency_matrix") # needs sage.modules + sage: Graph(m, format='seidel_adjacency_matrix') # needs sage.modules Traceback (most recent call last): ... ValueError: the adjacency matrix of a Seidel graph must have 0s on the main diagonal @@ -922,7 +922,7 @@ class Graph(GenericGraph): _directed = False def __init__(self, data=None, pos=None, loops=None, format=None, - weighted=None, data_structure="sparse", + weighted=None, data_structure='sparse', vertex_labels=True, name=None, multiedges=None, convert_empty_dict_labels_to_None=None, sparse=True, immutable=False, hash_labels=None): @@ -993,7 +993,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, sage: B = {0:{1:2,2:5,3:4},1:{2:2,4:7},2:{3:1,4:4,5:3},3:{5:4},4:{5:1,6:5},5:{6:7}} sage: grafo3 = Graph(B, weighted=True) sage: matad = grafo3.weighted_adjacency_matrix() # needs sage.modules - sage: grafo4 = Graph(matad, format="adjacency_matrix", weighted=True) # needs sage.modules + sage: grafo4 = Graph(matad, format='adjacency_matrix', weighted=True) # needs sage.modules sage: grafo4.shortest_path(0, 6, by_weight=True) # needs sage.modules [0, 1, 2, 5, 4, 6] @@ -1351,8 +1351,8 @@ def sparse6_string(self): :: - sage: G = Graph(loops=True, multiedges=True, data_structure="sparse") - sage: Graph(':?', data_structure="sparse") == G + sage: G = Graph(loops=True, multiedges=True, data_structure='sparse') + sage: Graph(':?', data_structure='sparse') == G True TESTS:: @@ -1474,7 +1474,7 @@ def is_directed(self): @doc_index("Graph properties") def is_tree(self, certificate=False, output='vertex'): r""" - Tests if the graph is a tree + Test if the graph is a tree. The empty graph is defined to be not a tree. @@ -1634,7 +1634,7 @@ def vertices_to_edges(x): @doc_index("Graph properties") def is_forest(self, certificate=False, output='vertex'): """ - Tests if the graph is a forest, i.e. a disjoint union of trees. + Test if the graph is a forest, i.e. a disjoint union of trees. INPUT: @@ -1799,7 +1799,6 @@ def is_block_graph(self): - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices` - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cuts_tree` - EXAMPLES:: sage: G = graphs.RandomBlockGraph(6, 2, kmax=4) @@ -2041,7 +2040,7 @@ def apex_vertices(self, k=None): sage: G.apex_vertices(k=-1) Traceback (most recent call last): ... - ValueError: parameter k must be a non negative integer + ValueError: parameter k must be a nonnegative integer The graph might be mutable or immutable:: @@ -2052,7 +2051,7 @@ def apex_vertices(self, k=None): if k is None: k = self.order() elif k < 0: - raise ValueError("parameter k must be a non negative integer") + raise ValueError("parameter k must be a nonnegative integer") # Easy cases: null graph, subgraphs of K_5 and K_3,3 if self.order() <= 5 or (self.order() <= 6 and self.is_bipartite()): @@ -2130,7 +2129,7 @@ def apex_vertices(self, k=None): @doc_index("Graph properties") def is_overfull(self): r""" - Tests whether the current graph is overfull. + Test whether the current graph is overfull. A graph `G` on `n` vertices and `m` edges is said to be overfull if: @@ -2228,7 +2227,7 @@ def is_overfull(self): @doc_index("Graph properties") def is_even_hole_free(self, certificate=False): r""" - Tests whether ``self`` contains an induced even hole. + Test whether ``self`` contains an induced even hole. A Hole is a cycle of length at least 4 (included). It is said to be even (resp. odd) if its length is even (resp. odd). @@ -2327,7 +2326,7 @@ def is_even_hole_free(self, certificate=False): @doc_index("Graph properties") def is_odd_hole_free(self, certificate=False): r""" - Tests whether ``self`` contains an induced odd hole. + Test whether ``self`` contains an induced odd hole. A Hole is a cycle of length at least 4 (included). It is said to be even (resp. odd) if its length is even (resp. odd). @@ -2398,7 +2397,7 @@ def is_odd_hole_free(self, certificate=False): @doc_index("Graph properties") def is_triangle_free(self, algorithm='dense_graph', certificate=False): r""" - Check whether ``self`` is triangle-free + Check whether ``self`` is triangle-free. INPUT: @@ -2406,7 +2405,7 @@ def is_triangle_free(self, algorithm='dense_graph', certificate=False): to use among: - ``'matrix'`` -- tests if the trace of the adjacency matrix is - positive. + positive - ``'bitset'`` -- encodes adjacencies into bitsets and uses fast bitset operations to test if the input graph contains a @@ -2520,7 +2519,7 @@ def is_triangle_free(self, algorithm='dense_graph', certificate=False): @doc_index("Graph properties") def is_split(self): r""" - Returns ``True`` if the graph is a Split graph, ``False`` otherwise. + Return ``True`` if the graph is a Split graph, ``False`` otherwise. A Graph `G` is said to be a split graph if its vertices `V(G)` can be partitioned into two sets `K` and `I` such that the vertices of `K` @@ -2539,7 +2538,6 @@ def is_split(self): where `\omega = max \{i:d_i\geq i-1\}`. - EXAMPLES: Split graphs are, in particular, chordal graphs. Hence, The Petersen @@ -2589,7 +2587,7 @@ def is_split(self): @doc_index("Algorithmically hard stuff") def is_perfect(self, certificate=False): r""" - Tests whether the graph is perfect. + Test whether the graph is perfect. A graph `G` is said to be perfect if `\chi(H)=\omega(H)` hold for any induced subgraph `H\subseteq_i G` (and so for `G` itself, too), where @@ -2604,7 +2602,7 @@ def is_perfect(self, certificate=False): INPUT: - ``certificate`` -- boolean (default: ``False``); whether to return a - certificate. + certificate OUTPUT: @@ -2682,7 +2680,6 @@ def is_perfect(self, certificate=False): Traceback (most recent call last): ... ValueError: This method is only defined for simple graphs, and yours is not one of them ! - """ if self.has_multiple_edges() or self.has_loops(): raise ValueError("This method is only defined for simple graphs," @@ -2706,7 +2703,7 @@ def is_perfect(self, certificate=False): @doc_index("Graph properties") def is_edge_transitive(self): r""" - Check if self is an edge transitive graph. + Check if ``self`` is an edge transitive graph. A graph is edge-transitive if its automorphism group acts transitively on its edge set. @@ -2751,7 +2748,7 @@ def is_edge_transitive(self): @doc_index("Graph properties") def is_arc_transitive(self): r""" - Check if self is an arc-transitive graph + Check if ``self`` is an arc-transitive graph. A graph is arc-transitive if its automorphism group acts transitively on its pairs of adjacent vertices. @@ -2791,7 +2788,7 @@ def is_arc_transitive(self): @doc_index("Graph properties") def is_half_transitive(self): """ - Check if self is a half-transitive graph. + Check if ``self`` is a half-transitive graph. A graph is half-transitive if it is both vertex and edge transitive but not arc-transitive. @@ -2828,7 +2825,7 @@ def is_half_transitive(self): @doc_index("Graph properties") def is_semi_symmetric(self): """ - Check if self is semi-symmetric. + Check if ``self`` is semi-symmetric. A graph is semi-symmetric if it is regular, edge-transitive but not vertex-transitive. @@ -2925,7 +2922,7 @@ def is_path(self): def degree_constrained_subgraph(self, bounds, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Returns a degree-constrained subgraph. + Return a degree-constrained subgraph. Given a graph `G` and two functions `f, g:V(G)\rightarrow \mathbb Z` such that `f \leq g`, a degree-constrained subgraph in `G` is @@ -2934,7 +2931,7 @@ def degree_constrained_subgraph(self, bounds, solver=None, verbose=0, INPUT: - - ``bounds`` -- (default: ``None``); Two possibilities: + - ``bounds`` -- (default: ``None``) two possibilities: - A dictionary whose keys are the vertices, and values a pair of real values ``(min,max)`` corresponding to the values @@ -2944,7 +2941,7 @@ def degree_constrained_subgraph(self, bounds, solver=None, verbose=0, real values ``(min,max)`` corresponding to the values `(f(v),g(v))`. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -2952,7 +2949,7 @@ def degree_constrained_subgraph(self, bounds, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -3028,7 +3025,7 @@ def weight(x): @doc_index("Connectivity, orientations, trees") def strong_orientation(self): r""" - Returns a strongly connected orientation of the current graph. + Return a strongly connected orientation of the current graph. An orientation of an undirected graph is a digraph obtained by giving an unique direction to each of its edges. An orientation is said to be @@ -3040,9 +3037,7 @@ def strong_orientation(self): the orientation returned will ensure that each 2-connected component has a strongly connected orientation. - OUTPUT: - - A digraph representing an orientation of the current graph. + OUTPUT: a digraph representing an orientation of the current graph .. NOTE:: @@ -3084,7 +3079,6 @@ def strong_orientation(self): sage: g = Graph([(1,2),(1,2)], multiedges=True) sage: g.strong_orientation() Multi-digraph on 2 vertices - """ from sage.graphs.digraph import DiGraph d = DiGraph(multiedges=self.allows_multiple_edges()) @@ -3147,7 +3141,7 @@ def strong_orientation(self): def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Returns an orientation of ``self`` with the smallest possible maximum + Return an orientation of ``self`` with the smallest possible maximum outdegree. Given a Graph `G`, it is polynomial to compute an orientation `D` of the @@ -3165,7 +3159,7 @@ def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verb - When set to ``False`` (default), gives a weight of 1 to all the edges. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -3173,7 +3167,7 @@ def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verb :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -3257,12 +3251,12 @@ def outgoing(u, e, variable): def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, *, integrality_tolerance=1e-3): r""" - Computes an orientation of ``self`` such that every vertex `v` has + Compute an orientation of ``self`` such that every vertex `v` has out-degree less than `b(v)` INPUT: - - ``bound`` -- Maximum bound on the out-degree. Can be of three + - ``bound`` -- maximum bound on the out-degree. Can be of three different types : * An integer `k`. In this case, computes an orientation whose maximum @@ -3274,7 +3268,7 @@ def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, * A function associating to each vertex its associated maximum out-degree. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -3282,7 +3276,7 @@ def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -3292,7 +3286,7 @@ def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, OUTPUT: A DiGraph representing the orientation if it exists. - A :class:`ValueError` exception is raised otherwise. + A :exc:`ValueError` exception is raised otherwise. ALGORITHM: @@ -3357,7 +3351,6 @@ def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, ....: all( D.out_degree(v) <= b(v) for v in g ) or ....: D.size() != g.size()): ....: print("Something wrong happened") - """ self._scream_if_not_simple() from sage.graphs.digraph import DiGraph @@ -3432,8 +3425,8 @@ def orientations(self, data_structure=None, sparse=None): INPUT: - - ``data_structure`` -- one of ``"sparse"``, ``"static_sparse"``, or - ``"dense"``; see the documentation of :class:`Graph` or + - ``data_structure`` -- one of ``'sparse'``, ``'static_sparse'``, or + ``'dense'``; see the documentation of :class:`Graph` or :class:`DiGraph`; default is the data structure of ``self`` - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an alias @@ -3617,7 +3610,7 @@ def chromatic_index(self, solver=None, verbose=0, *, integrality_tolerance=1e-3) INPUT: - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -3625,7 +3618,7 @@ def chromatic_index(self, solver=None, verbose=0, *, integrality_tolerance=1e-3) :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -3684,7 +3677,7 @@ def chromatic_index(self, solver=None, verbose=0, *, integrality_tolerance=1e-3) integrality_tolerance=integrality_tolerance) @doc_index("Coloring") - def chromatic_number(self, algorithm="DLX", solver=None, verbose=0, + def chromatic_number(self, algorithm='DLX', solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" Return the minimal number of colors needed to color the vertices of the @@ -3692,31 +3685,31 @@ def chromatic_number(self, algorithm="DLX", solver=None, verbose=0, INPUT: - - ``algorithm`` -- string (default: ``"DLX"``); one of the following + - ``algorithm`` -- string (default: ``'DLX'``); one of the following algorithms: - - ``"DLX"`` (default): the chromatic number is computed using the + - ``'DLX'`` (default): the chromatic number is computed using the dancing link algorithm. It is inefficient speedwise to compute the chromatic number through the dancing link algorithm because this algorithm computes *all* the possible colorings to check that one exists. - - ``"CP"``: the chromatic number is computed using the coefficients of + - ``'CP'``: the chromatic number is computed using the coefficients of the chromatic polynomial. Again, this method is inefficient in terms of speed and it only useful for small graphs. - - ``"MILP"``: the chromatic number is computed using a mixed integer + - ``'MILP'``: the chromatic number is computed using a mixed integer linear program. The performance of this implementation is affected by whether optional MILP solvers have been installed (see the :mod:`MILP module `, or Sage's tutorial on Linear Programming). - - ``"parallel"``: all the above algorithms are executed in parallel + - ``'parallel'``: all the above algorithms are executed in parallel and the result is returned as soon as one algorithm ends. Observe that the speed of the above algorithms depends on the size and structure of the graph. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -3724,7 +3717,7 @@ def chromatic_number(self, algorithm="DLX", solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -3739,13 +3732,13 @@ def chromatic_number(self, algorithm="DLX", solver=None, verbose=0, EXAMPLES:: sage: G = Graph({0: [1, 2, 3], 1: [2]}) - sage: G.chromatic_number(algorithm="DLX") + sage: G.chromatic_number(algorithm='DLX') 3 - sage: G.chromatic_number(algorithm="MILP") + sage: G.chromatic_number(algorithm='MILP') 3 - sage: G.chromatic_number(algorithm="CP") # needs sage.libs.flint + sage: G.chromatic_number(algorithm='CP') # needs sage.libs.flint 3 - sage: G.chromatic_number(algorithm="parallel") + sage: G.chromatic_number(algorithm='parallel') 3 A bipartite graph has (by definition) chromatic number 2:: @@ -3780,17 +3773,17 @@ def chromatic_number(self, algorithm="DLX", solver=None, verbose=0, TESTS:: sage: G = Graph() - sage: G.chromatic_number(algorithm="DLX") + sage: G.chromatic_number(algorithm='DLX') 0 - sage: G.chromatic_number(algorithm="MILP") + sage: G.chromatic_number(algorithm='MILP') 0 - sage: G.chromatic_number(algorithm="CP") # needs sage.libs.flint + sage: G.chromatic_number(algorithm='CP') # needs sage.libs.flint 0 - sage: G.chromatic_number(algorithm="parallel") + sage: G.chromatic_number(algorithm='parallel') 0 sage: G = Graph({0: [1, 2, 3], 1: [2]}) - sage: G.chromatic_number(algorithm="foo") + sage: G.chromatic_number(algorithm='foo') Traceback (most recent call last): ... ValueError: the 'algorithm' keyword must be set to either 'DLX', 'MILP', 'CP' or 'parallel' @@ -3829,14 +3822,14 @@ def func(alg): raise ValueError("the 'algorithm' keyword must be set to either 'DLX', 'MILP', 'CP' or 'parallel'") @doc_index("Coloring") - def coloring(self, algorithm="DLX", hex_colors=False, solver=None, verbose=0, + def coloring(self, algorithm='DLX', hex_colors=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" Return the first (optimal) proper vertex-coloring found. INPUT: - - ``algorithm`` -- Select an algorithm from the following supported + - ``algorithm`` -- select an algorithm from the following supported algorithms: - If ``algorithm="DLX"`` (default), the coloring is computed using the @@ -3848,9 +3841,9 @@ def coloring(self, algorithm="DLX", hex_colors=False, solver=None, verbose=0, the :mod:`MILP module `). - ``hex_colors`` -- boolean (default: ``False``); if ``True``, return a - dictionary which can easily be used for plotting. + dictionary which can easily be used for plotting - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -3858,7 +3851,7 @@ def coloring(self, algorithm="DLX", hex_colors=False, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -3873,8 +3866,8 @@ def coloring(self, algorithm="DLX", hex_colors=False, solver=None, verbose=0, EXAMPLES:: sage: G = Graph("Fooba") - sage: P = G.coloring(algorithm="MILP") - sage: Q = G.coloring(algorithm="DLX") + sage: P = G.coloring(algorithm='MILP') + sage: Q = G.coloring(algorithm='DLX') sage: def are_equal_colorings(A, B): ....: return Set(map(Set, A)) == Set(map(Set, B)) sage: are_equal_colorings(P, [[1, 2, 3], [0, 5, 6], [4]]) @@ -3885,9 +3878,9 @@ def coloring(self, algorithm="DLX", hex_colors=False, solver=None, verbose=0, sage: # needs sage.plot sage: G.plot(partition=P) Graphics object consisting of 16 graphics primitives - sage: G.coloring(hex_colors=True, algorithm="MILP") + sage: G.coloring(hex_colors=True, algorithm='MILP') {'#0000ff': [4], '#00ff00': [0, 6, 5], '#ff0000': [2, 1, 3]} - sage: H = G.coloring(hex_colors=True, algorithm="DLX"); H + sage: H = G.coloring(hex_colors=True, algorithm='DLX'); H {'#0000ff': [4], '#00ff00': [1, 2, 3], '#ff0000': [0, 5, 6]} sage: G.plot(vertex_colors=H) Graphics object consisting of 16 graphics primitives @@ -3899,7 +3892,7 @@ def coloring(self, algorithm="DLX", hex_colors=False, solver=None, verbose=0, TESTS:: - sage: G.coloring(algorithm="foo") + sage: G.coloring(algorithm='foo') Traceback (most recent call last): ... ValueError: The 'algorithm' keyword must be set to either 'DLX' or 'MILP'. @@ -4129,413 +4122,105 @@ def asc(sigma): ret += M.term(sigma.to_composition(), t**asc(sigma)) return ret - @doc_index("Leftovers") - def matching(self, value_only=False, algorithm="Edmonds", - use_edge_labels=False, solver=None, verbose=0, - *, integrality_tolerance=1e-3): + @doc_index("Coloring") + def tutte_symmetric_function(self, R=None, t=None): r""" - Return a maximum weighted matching of the graph represented by the list - of its edges. - - For more information, see the :wikipedia:`Matching_(graph_theory)`. + Return the Tutte symmetric function of ``self``. - Given a graph `G` such that each edge `e` has a weight `w_e`, a maximum - matching is a subset `S` of the edges of `G` of maximum weight such that - no two edges of `S` are incident with each other. - - As an optimization problem, it can be expressed as: + Let `G` be a graph. The Tutte symmetric function `XB_G` of the graph + `G` was introduced in [Sta1998]_. We present the equivalent definition + given in [CS2022]_. .. MATH:: - \mbox{Maximize : }&\sum_{e\in G.edges()} w_e b_e\\ - \mbox{Such that : }&\forall v \in G, - \sum_{(u,v)\in G.edges()} b_{(u,v)}\leq 1\\ - &\forall x\in G, b_x\mbox{ is a binary variable} - - INPUT: - - - ``value_only`` -- boolean (default: ``False``); when set to ``True``, - only the cardinal (or the weight) of the matching is returned - - - ``algorithm`` -- string (default: ``"Edmonds"``) - - - ``"Edmonds"`` selects Edmonds' algorithm as implemented in NetworkX - - - ``"LP"`` uses a Linear Program formulation of the matching problem - - - ``use_edge_labels`` -- boolean (default: ``False``) - - - when set to ``True``, computes a weighted matching where each edge - is weighted by its label (if an edge has no label, `1` is assumed) - - - when set to ``False``, each edge has weight `1` - - - ``solver`` -- string (default: ``None``); specify a Mixed Integer - Linear Programming (MILP) solver to be used. If set to ``None``, the - default one is used. For more information on MILP solvers and which - default solver is used, see the method :meth:`solve - ` of the class - :class:`MixedIntegerLinearProgram - `. - - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity: - set to 0 by default, which means quiet (only useful when ``algorithm - == "LP"``) - - - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. - - OUTPUT: - - - When ``value_only=False`` (default), this method returns an - :class:`EdgesView` containing the edges of a maximum matching of `G`. - - - When ``value_only=True``, this method returns the sum of the - weights (default: ``1``) of the edges of a maximum matching of `G`. - The type of the output may vary according to the type of the edge - labels and the algorithm used. - - ALGORITHM: - - The problem is solved using Edmond's algorithm implemented in NetworkX, - or using Linear Programming depending on the value of ``algorithm``. - - EXAMPLES: - - Maximum matching in a Pappus Graph:: - - sage: g = graphs.PappusGraph() - sage: g.matching(value_only=True) # needs sage.networkx - 9 - - Same test with the Linear Program formulation:: - - sage: g = graphs.PappusGraph() - sage: g.matching(algorithm="LP", value_only=True) # needs sage.numerical.mip - 9 - - .. PLOT:: - - g = graphs.PappusGraph() - sphinx_plot(g.plot(edge_colors={"red":g.matching()})) - - TESTS: - - When ``use_edge_labels`` is set to ``False``, with Edmonds' algorithm - and LP formulation:: - - sage: g = Graph([(0,1,0), (1,2,999), (2,3,-5)]) - sage: sorted(g.matching()) # needs sage.networkx - [(0, 1, 0), (2, 3, -5)] - sage: sorted(g.matching(algorithm="LP")) # needs sage.numerical.mip - [(0, 1, 0), (2, 3, -5)] - - When ``use_edge_labels`` is set to ``True``, with Edmonds' algorithm and - LP formulation:: - - sage: g = Graph([(0,1,0), (1,2,999), (2,3,-5)]) - sage: g.matching(use_edge_labels=True) # needs sage.networkx - [(1, 2, 999)] - sage: g.matching(algorithm="LP", use_edge_labels=True) # needs sage.numerical.mip - [(1, 2, 999)] - - With loops and multiedges:: - - sage: edge_list = [(0,0,5), (0,1,1), (0,2,2), (0,3,3), (1,2,6) - ....: , (1,2,3), (1,3,3), (2,3,3)] - sage: g = Graph(edge_list, loops=True, multiedges=True) - sage: m = g.matching(use_edge_labels=True) # needs sage.networkx - sage: type(m) # needs sage.networkx - - sage: sorted(m) # needs sage.networkx - [(0, 3, 3), (1, 2, 6)] - - TESTS: - - If ``algorithm`` is set to anything different from ``"Edmonds"`` or - ``"LP"``, an exception is raised:: + XB_G = \sum_{\pi \vdash V} (1+t)^{e(\pi)} \tilde{m}_{\lambda(\pi)}, - sage: g = graphs.PappusGraph() - sage: g.matching(algorithm="somethingdifferent") - Traceback (most recent call last): - ... - ValueError: algorithm must be set to either "Edmonds" or "LP" - """ - from sage.rings.real_mpfr import RR - - def weight(x): - if x in RR: - return x - else: - return 1 - - W = {} - L = {} - for u, v, l in self.edge_iterator(): - if u is v: - continue - fuv = frozenset((u, v)) - if fuv not in L or (use_edge_labels and W[fuv] < weight(l)): - L[fuv] = l - if use_edge_labels: - W[fuv] = weight(l) - - if algorithm == "Edmonds": - import networkx - g = networkx.Graph() - if use_edge_labels: - for (u, v), w in W.items(): - g.add_edge(u, v, weight=w) - else: - for u, v in L: - g.add_edge(u, v) - d = networkx.max_weight_matching(g) - if value_only: - if use_edge_labels: - return sum(W[frozenset(e)] for e in d) - return Integer(len(d)) + where the sum ranges over all set-partitions `\pi` of the vertex set + `V`, `\lambda(\pi)` is the partition determined by the sizes of the + blocks of `\pi`, and `e(\pi)` is the number of edges whose endpoints + lie in the same block of `\pi`. In particular, the coefficients of + `XB_G` when expanded in terms of augmented monomial symmetric functions + are polynomials in `t` with non-negative integer coefficients. - return EdgesView(Graph([(u, v, L[frozenset((u, v))]) for u, v in d], - format='list_of_edges')) + For an integer partition `\lambda = 1^{r_1}2^{r_2}\cdots` expressed in + the exponential notation, the augmented monomial symmetric function + is defined as - elif algorithm == "LP": - g = self - from sage.numerical.mip import MixedIntegerLinearProgram - # returns the weight of an edge considering it may not be - # weighted ... - p = MixedIntegerLinearProgram(maximization=True, solver=solver) - b = p.new_variable(binary=True) - if use_edge_labels: - p.set_objective(p.sum(w * b[fe] for fe, w in W.items())) - else: - p.set_objective(p.sum(b[fe] for fe in L)) - # for any vertex v, there is at most one edge incident to v in - # the maximum matching - for v in g: - p.add_constraint(p.sum(b[frozenset(e)] for e in self.edge_iterator(vertices=[v], labels=False) - if e[0] != e[1]), max=1) - - p.solve(log=verbose) - b = p.get_values(b, convert=bool, tolerance=integrality_tolerance) - if value_only: - if use_edge_labels: - return sum(w for fe, w in W.items() if b[fe]) - return Integer(sum(1 for fe in L if b[fe])) - - return EdgesView(Graph([(u, v, L[frozenset((u, v))]) - for u, v in L if b[frozenset((u, v))]], - format='list_of_edges')) - - raise ValueError('algorithm must be set to either "Edmonds" or "LP"') - - @doc_index("Leftovers") - def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, - *, integrality_tolerance=0.001): - r""" - Check whether this graph is factor-critical. - - A graph of order `n` is factor-critical if every subgraph of `n-1` - vertices have a perfect matching, hence `n` must be odd. See - :wikipedia:`Factor-critical_graph` for more details. + .. MATH:: - This method implements the algorithm proposed in [LR2004]_ and we assume - that a graph of order one is factor-critical. The time complexity of the - algorithm is linear if a near perfect matching is given as input (i.e., - a matching such that all vertices but one are incident to an edge of the - matching). Otherwise, the time complexity is dominated by the time - needed to compute a maximum matching of the graph. + \tilde{m}_{\lambda} = \left(\prod_{i} r_i! \right) m_{\lambda}. INPUT: - - ``matching`` -- (default: ``None``); a near perfect matching of the - graph, that is a matching such that all vertices of the graph but one - are incident to an edge of the matching. It can be given using any - valid input format of :class:`~sage.graphs.graph.Graph`. - - If set to ``None``, a matching is computed using the other parameters. - - - ``algorithm`` -- string (default: ``Edmonds``); the algorithm to use - to compute a maximum matching of the graph among + - ``R`` -- (default: the parent of ``t``) the base ring for the symmetric + functions - - ``"Edmonds"`` selects Edmonds' algorithm as implemented in NetworkX + - ``t`` -- (default: `t` in `\ZZ[t]`) the parameter `t` - - ``"LP"`` uses a Linear Program formulation of the matching problem - - - ``solver`` -- string (default: ``None``); specify a Mixed Integer - Linear Programming (MILP) solver to be used. If set to ``None``, the - default one is used. For more information on MILP solvers and which - default solver is used, see the method :meth:`solve - ` of the class - :class:`MixedIntegerLinearProgram - `. - - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity: - set to 0 by default, which means quiet (only useful when ``algorithm - == "LP"``) - - - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. - - EXAMPLES: - - Odd length cycles and odd cliques of order at least 3 are - factor-critical graphs:: - - sage: [graphs.CycleGraph(2*i + 1).is_factor_critical() for i in range(5)] # needs networkx - [True, True, True, True, True] - sage: [graphs.CompleteGraph(2*i + 1).is_factor_critical() for i in range(5)] # needs networkx - [True, True, True, True, True] - - More generally, every Hamiltonian graph with an odd number of vertices - is factor-critical:: - - sage: G = graphs.RandomGNP(15, .2) - sage: G.add_path([0..14]) - sage: G.add_edge(14, 0) - sage: G.is_hamiltonian() - True - sage: G.is_factor_critical() # needs networkx - True - - Friendship graphs are non-Hamiltonian factor-critical graphs:: - - sage: [graphs.FriendshipGraph(i).is_factor_critical() for i in range(1, 5)] # needs networkx - [True, True, True, True] - - Bipartite graphs are not factor-critical:: + EXAMPLES:: - sage: G = graphs.RandomBipartite(randint(1, 10), randint(1, 10), .5) # needs numpy - sage: G.is_factor_critical() # needs numpy - False + sage: p = SymmetricFunctions(ZZ).p() # needs sage.combinat sage.modules + sage: G = Graph([[1,2],[2,3],[3,4],[4,1],[1,3]]) + sage: XB_G = G.tutte_symmetric_function(); XB_G # needs sage.combinat sage.modules + 24*m[1, 1, 1, 1] + (10*t+12)*m[2, 1, 1] + (4*t^2+10*t+6)*m[2, 2] + + (2*t^3+8*t^2+10*t+4)*m[3, 1] + + (t^5+5*t^4+10*t^3+10*t^2+5*t+1)*m[4] + sage: p(XB_G) # needs sage.combinat sage.modules + p[1, 1, 1, 1] + 5*t*p[2, 1, 1] + 2*t^2*p[2, 2] + + (2*t^3+8*t^2)*p[3, 1] + (t^5+5*t^4+8*t^3)*p[4] - Graphs with even order are not factor critical:: + Graphs are allowed to have multiedges and loops:: - sage: G = graphs.RandomGNP(10, .5) - sage: G.is_factor_critical() - False + sage: G = Graph([[1,2],[2,3],[2,3]], multiedges = True) + sage: XB_G = G.tutte_symmetric_function(); XB_G # needs sage.combinat sage.modules + 6*m[1, 1, 1] + (t^2+3*t+3)*m[2, 1] + (t^3+3*t^2+3*t+1)*m[3] - One can specify a matching:: + We check that at `t = -1`, we recover the usual chromatic symmetric + function:: - sage: F = graphs.FriendshipGraph(4) - sage: M = F.matching() # needs networkx - sage: F.is_factor_critical(matching=M) # needs networkx - True - sage: F.is_factor_critical(matching=Graph(M)) # needs networkx + sage: G = Graph([[1,2],[1,2],[2,3],[3,4],[4,5]], multiedges=True) + sage: XB_G = G.tutte_symmetric_function(t=-1); XB_G # needs sage.combinat sage.modules + 120*m[1, 1, 1, 1, 1] + 36*m[2, 1, 1, 1] + 12*m[2, 2, 1] + + 2*m[3, 1, 1] + m[3, 2] + sage: X_G = G.chromatic_symmetric_function(); X_G # needs sage.combinat sage.modules + p[1, 1, 1, 1, 1] - 4*p[2, 1, 1, 1] + 3*p[2, 2, 1] + 3*p[3, 1, 1] + - 2*p[3, 2] - 2*p[4, 1] + p[5] + sage: XB_G == X_G # needs sage.combinat sage.modules True - - TESTS: - - Giving a wrong matching:: - - sage: G = graphs.RandomGNP(15, .3) - sage: while not G.is_biconnected(): - ....: G = graphs.RandomGNP(15, .3) - sage: M = G.matching() # needs networkx - sage: G.is_factor_critical(matching=M[:-1]) # needs networkx - Traceback (most recent call last): - ... - ValueError: the input is not a near perfect matching of the graph - sage: G.is_factor_critical(matching=G.edges(sort=True)) - Traceback (most recent call last): - ... - ValueError: the input is not a matching - sage: M = [(2*i, 2*i + 1) for i in range(9)] - sage: G.is_factor_critical(matching=M) - Traceback (most recent call last): - ... - ValueError: the input is not a matching of the graph """ - if self.order() == 1: - return True - - # The graph must have an odd number of vertices, be 2-edge connected, so - # without bridges, and not bipartite - if (not self.order() % 2 or not self.is_connected() or - list(self.bridges()) or self.is_bipartite()): - return False - - if matching: - # We check that the input matching is a valid near perfect matching - # of the graph. - M = Graph(matching) - if any(d != 1 for d in M.degree()): - raise ValueError("the input is not a matching") - if not M.is_subgraph(self, induced=False): - raise ValueError("the input is not a matching of the graph") - if (self.order() != M.order() + 1) or (self.order() != 2*M.size() + 1): - raise ValueError("the input is not a near perfect matching of the graph") - else: - # We compute a maximum matching of the graph - M = Graph(self.matching(algorithm=algorithm, solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance)) - - # It must be a near-perfect matching - if self.order() != M.order() + 1: - return False + from sage.combinat.sf.sf import SymmetricFunctions + from sage.combinat.set_partition import SetPartitions + from sage.misc.misc_c import prod + from collections import Counter - # We find the unsaturated vertex u, i.e., the only vertex of the graph - # not in M - for u in self: - if u not in M: - break + if t is None: + t = ZZ['t'].gen() + if R is None: + R = t.parent() + m = SymmetricFunctions(R).m() + ret = m.zero() + V = self.vertices() + M = Counter(self.edge_iterator(labels=False)) + fact = [1] + fact.extend(fact[-1] * i for i in range(1, len(V)+1)) + + def mono(pi): + arcs = 0 + for s in pi: + for u in s: + arcs += sum(M[(u, v)] for v in s if self.has_edge(u, v)) + return arcs - # We virtually build an M-alternating tree T - from queue import Queue - Q = Queue() - Q.put(u) - even = set([u]) - odd = set() - pred = {u: u} - rank = {u: 0} - - while not Q.empty(): - x = Q.get() - for y in self.neighbor_iterator(x): - if y in odd: - continue - elif y in even: - # Search for the nearest common ancestor t of x and y - P = [x] - R = [y] - while P[-1] != R[-1]: - if rank[P[-1]] > rank[R[-1]]: - P.append(pred[P[-1]]) - elif rank[P[-1]] < rank[R[-1]]: - R.append(pred[R[-1]]) - else: - P.append(pred[P[-1]]) - R.append(pred[R[-1]]) - t = P.pop() - R.pop() - # Set t as pred of all vertices of the chains and add - # vertices marked odd to the queue - for a in itertools.chain(P, R): - pred[a] = t - rank[a] = rank[t] + 1 - if a in odd: - even.add(a) - odd.discard(a) - Q.put(a) - else: # y has not been visited yet - z = next(M.neighbor_iterator(y)) - odd.add(y) - even.add(z) - Q.put(z) - pred[y] = x - pred[z] = y - rank[y] = rank[x] + 1 - rank[z] = rank[y] + 1 - - # The graph is factor critical if all vertices are marked even - return len(even) == self.order() + for pi in SetPartitions(V): + pa = pi.to_partition() + ret += prod(fact[i] for i in pa.to_exp()) * m[pa] * (1+t)**mono(pi) + return ret @doc_index("Algorithmically hard stuff") def has_homomorphism_to(self, H, core=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Checks whether there is a homomorphism between two graphs. + Check whether there is a homomorphism between two graphs. A homomorphism from a graph `G` to a graph `H` is a function `\phi:V(G)\mapsto V(H)` such that for any edge `uv \in E(G)` the pair @@ -4548,13 +4233,13 @@ def has_homomorphism_to(self, H, core=False, solver=None, verbose=0, INPUT: - - ``H`` -- the graph to which ``self`` should be sent. + - ``H`` -- the graph to which ``self`` should be sent - ``core`` -- boolean (default: ``False``; whether to minimize the size of the mapping's image (see note below). This is set to ``False`` by default. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -4562,7 +4247,7 @@ def has_homomorphism_to(self, H, core=False, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -4664,7 +4349,7 @@ def fractional_clique_number(self, solver='PPL', verbose=0, INPUT: - - ``solver`` -- (default: ``"PPL"``); specify a Linear Program (LP) + - ``solver`` -- (default: ``'PPL'``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`solve @@ -4674,11 +4359,11 @@ def fractional_clique_number(self, solver='PPL', verbose=0, .. NOTE:: - The default solver used here is ``"PPL"`` which provides exact + The default solver used here is ``'PPL'`` which provides exact results, i.e. a rational number, although this may be slower that using other solvers. - - ``verbose`` -- integer (default: `0`); sets the level of verbosity of + - ``verbose`` -- integer (default: 0); sets the level of verbosity of the LP solver - ``check_components`` -- boolean (default: ``True``); whether the @@ -4714,14 +4399,14 @@ def maximum_average_degree(self, value_only=True, solver=None, verbose=0): INPUT: - - ``value_only`` -- boolean (default: ``True``); + - ``value_only`` -- boolean (default: ``True``) - If ``value_only=True``, only the numerical value of the `MAD` is returned. - Else, the subgraph of `G` realizing the `MAD` is returned. - - ``solver`` -- (default: ``None``); specify a Linear Program (LP) + - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method @@ -4729,7 +4414,7 @@ def maximum_average_degree(self, value_only=True, solver=None, verbose=0): of the class :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. EXAMPLES: @@ -4810,7 +4495,7 @@ def maximum_average_degree(self, value_only=True, solver=None, verbose=0): # Paying attention to numerical error : # The zero values could be something like 0.000000000001 # so I can not write l > 0 - # And the non-zero, though they should be equal to + # And the nonzero, though they should be equal to # 1/(order of the optimal subgraph) may be a bit lower # setting the minimum to 1/(10 * size of the whole graph ) @@ -4841,10 +4526,10 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, INPUT: - - ``family`` -- A list of lists defining the family `F` (actually, a - Family of subsets of ``G.vertices(sort=False)``). + - ``family`` -- list of lists defining the family `F` (actually, a + Family of subsets of ``G.vertices(sort=False)``) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -4852,7 +4537,7 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -4968,9 +4653,9 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran INPUT: - - ``H`` -- The minor to find for in the current graph. + - ``H`` -- the minor to find for in the current graph - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -4978,7 +4663,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -4987,7 +4672,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran - ``induced`` -- boolean (default: ``False``); if ``True``, returns an induced minor isomorphic to `H` if it exists, and raises a - :class:`ValueError` otherwise. + :exc:`ValueError` otherwise. OUTPUT: @@ -5233,7 +4918,7 @@ def centrality_degree(self, v=None): INPUT: - ``v`` -- a vertex (default: ``None``); set to ``None`` (default) to - get a dictionary associating each vertex with its centrality degree. + get a dictionary associating each vertex with its centrality degree .. SEEALSO:: @@ -5287,19 +4972,19 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, INPUT: - ``v`` -- either a single vertex or a list of vertices. If it is not - specified, then it is taken to be all vertices. + specified, then it is taken to be all vertices - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); one of the following algorithms: - ``'BFS'`` -- the computation is done through a BFS centered on each - vertex successively. Works only if ``by_weight==False``. + vertex successively. Works only if ``by_weight==False`` - ``'DHV'`` -- the computation is done using the algorithm proposed in - [Dragan2018]_. Works only if ``self`` has non-negative edge weights + [Dragan2018]_. Works only if ``self`` has nonnegative edge weights and ``v is None`` or ``v`` should contain all vertices of ``self``. For more information see method :func:`sage.graphs.distances_all_pairs.eccentricity` and @@ -5319,7 +5004,7 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, allowed. - ``'Dijkstra_Boost'`` -- the Dijkstra algorithm, implemented in Boost - (works only with positive weights). + (works only with positive weights) - ``'Johnson_Boost'`` -- the Johnson algorithm, implemented in Boost (works also with negative weights, if there is no negative @@ -5327,7 +5012,7 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, vertices of ``self``. - ``'From_Dictionary'`` -- uses the (already computed) distances, that - are provided by input variable ``dist_dict``. + are provided by input variable ``dist_dict`` - ``None`` (default): Sage chooses the best algorithm: ``'From_Dictionary'`` if ``dist_dict`` is not None, ``'BFS'`` for @@ -5343,11 +5028,11 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, - ``check_weight`` -- boolean (default: ``True``); if ``True``, we check that the ``weight_function`` outputs a number for each edge - - ``dist_dict`` -- a dictionary (default: ``None``); a dict of dicts of + - ``dist_dict`` -- dictionary (default: ``None``); a dict of dicts of distances (used only if ``algorithm=='From_Dictionary'``) - ``with_labels`` -- boolean (default: ``False``); whether to return a - list or a dictionary keyed by vertices. + list or a dictionary keyed by vertices EXAMPLES:: @@ -5536,12 +5221,12 @@ def radius(self, by_weight=False, algorithm='DHV', weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - - ``algorithm`` -- string (default: ``'DHV'``). + - ``algorithm`` -- string (default: ``'DHV'``) - - ``'DHV'`` -- Radius computation is done using the algorithm proposed - in [Dragan2018]_. Works for graph with non-negative edge weights. + - ``'DHV'`` -- radius computation is done using the algorithm proposed + in [Dragan2018]_. Works for graph with nonnegative edge weights For more information see method :func:`sage.graphs.distances_all_pairs.radius_DHV` and :func:`sage.graphs.base.boost_graph.radius_DHV`. @@ -5622,7 +5307,7 @@ def diameter(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); one of the following algorithms: @@ -5644,7 +5329,7 @@ def diameter(self, by_weight=False, algorithm=None, weight_function=None, allowed. - ``'DHV'`` -- diameter computation is done using the algorithm - proposed in [Dragan2018]_. Works only for non-negative edge weights. + proposed in [Dragan2018]_. Works only for nonnegative edge weights For more information see method :func:`sage.graphs.distances_all_pairs.diameter_DHV` and :func:`sage.graphs.base.boost_graph.diameter_DHV`. @@ -5760,7 +5445,7 @@ def center(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); see method :meth:`eccentricity` for the list of available algorithms @@ -5832,7 +5517,7 @@ def periphery(self, by_weight=False, algorithm=None, weight_function=None, INPUT: - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge - weights are taken into account; if False, all edges have weight 1 + weights are taken into account; if ``False``, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); see method :meth:`eccentricity` for the list of available algorithms @@ -5885,7 +5570,7 @@ def distance_graph(self, dist): INPUT: - - ``dist`` -- a nonnegative integer or a list of nonnegative integers; + - ``dist`` -- nonnegative integer or a list of nonnegative integers; specified distance(s) for the connecting vertices. ``Infinity`` may be used here to describe vertex pairs in separate components. @@ -6060,13 +5745,13 @@ def to_directed(self, data_structure=None, sparse=None): INPUT: - - ``data_structure`` -- one of ``"sparse"``, ``"static_sparse"``, or - ``"dense"``. See the documentation of :class:`Graph` or - :class:`DiGraph`. + - ``data_structure`` -- one of ``'sparse'``, ``'static_sparse'``, or + ``'dense'``. See the documentation of :class:`Graph` or + :class:`DiGraph`. - - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an - alias for ``data_structure="sparse"``, and ``sparse=False`` is an - alias for ``data_structure="dense"``. + - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an + alias for ``data_structure="sparse"``, and ``sparse=False`` is an + alias for ``data_structure="dense"``. EXAMPLES:: @@ -6155,7 +5840,7 @@ def to_undirected(self): return self.copy() @doc_index("Basic methods") - def join(self, other, labels="pairs", immutable=None): + def join(self, other, labels='pairs', immutable=None): r""" Return the join of ``self`` and ``other``. @@ -6288,11 +5973,11 @@ def seidel_switching(self, s, inplace=True): INPUT: - - ``s`` -- a list of vertices of ``self``. + - ``s`` -- list of vertices of ``self`` - ``inplace`` -- boolean (default: ``True``); whether to do the modification inplace, or to return a copy of the graph after - switching. + switching EXAMPLES:: @@ -6321,7 +6006,7 @@ def seidel_switching(self, s, inplace=True): @doc_index("Leftovers") def twograph(self): r""" - Return the two-graph of ``self`` + Return the two-graph of ``self``. Returns the :class:`two-graph ` with the triples @@ -6352,7 +6037,7 @@ def twograph(self): .. SEEALSO:: - :meth:`~sage.combinat.designs.twographs.TwoGraph.descendant` -- - computes the descendant graph of the two-graph of self at a vertex + computes the descendant graph of the two-graph of ``self`` at a vertex - :func:`~sage.combinat.designs.twographs.twograph_descendant` -- ditto, but much faster. @@ -6374,7 +6059,7 @@ def twograph(self): T.append([x, y, z]) T = TwoGraph(T) - T.relabel({i: v for i, v in enumerate(self)}) + T.relabel(dict(enumerate(self))) return T @@ -6387,8 +6072,8 @@ def write_to_eps(self, filename, **options): INPUT: - - ``filename`` -- a string - - ``**options`` -- same layout options as :meth:`.layout` + - ``filename`` -- string + - ``**options`` -- same layout options as :meth:`.layout` EXAMPLES:: @@ -6428,9 +6113,9 @@ def topological_minor(self, H, vertices=False, paths=False, solver=None, verbose INPUT: - - ``H`` -- The topological minor to find in the current graph. + - ``H`` -- the topological minor to find in the current graph - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -6438,7 +6123,7 @@ def topological_minor(self, H, vertices=False, paths=False, solver=None, verbose :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -6642,7 +6327,7 @@ def flow_balance(C, v): # Cliques @doc_index("Clique-related methods") - def cliques_maximal(self, algorithm="native"): + def cliques_maximal(self, algorithm='native'): """ Return the list of all maximal cliques. @@ -6652,9 +6337,9 @@ def cliques_maximal(self, algorithm="native"): INPUT: - - ``algorithm`` -- can be set to ``"native"`` (default) to use Sage's + - ``algorithm`` -- can be set to ``'native'`` (default) to use Sage's own implementation, or to ``"NetworkX"`` to use NetworkX' - implementation of the Bron and Kerbosch Algorithm [BK1973]_. + implementation of the Bron and Kerbosch Algorithm [BK1973]_ .. NOTE:: @@ -6699,7 +6384,7 @@ def cliques_maximal(self, algorithm="native"): sage: g = graphs.RandomGNP(20,.7) sage: s1 = Set(map(Set, g.cliques_maximal(algorithm="NetworkX"))) # needs networkx - sage: s2 = Set(map(Set, g.cliques_maximal(algorithm="native"))) + sage: s2 = Set(map(Set, g.cliques_maximal(algorithm='native'))) sage: s1 == s2 # needs networkx True """ @@ -6712,7 +6397,7 @@ def cliques_maximal(self, algorithm="native"): raise ValueError("Algorithm must be equal to 'native' or to 'NetworkX'.") @doc_index("Clique-related methods") - def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, + def clique_maximum(self, algorithm='Cliquer', solver=None, verbose=0, *, integrality_tolerance=1e-3): """ Return the vertex set of a maximal order complete subgraph. @@ -6733,7 +6418,7 @@ def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, (``_). Note that the MCQD package must be installed. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -6741,7 +6426,7 @@ def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -6773,18 +6458,17 @@ def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, Through a Linear Program:: - sage: len(C.clique_maximum(algorithm="MILP")) + sage: len(C.clique_maximum(algorithm='MILP')) 4 TESTS: Wrong algorithm:: - sage: C.clique_maximum(algorithm="BFS") + sage: C.clique_maximum(algorithm='BFS') Traceback (most recent call last): ... NotImplementedError: Only 'MILP', 'Cliquer' and 'mcqd' are supported. - """ self._scream_if_not_simple(allow_multiple_edges=True) if algorithm == "Cliquer": @@ -6798,10 +6482,10 @@ def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, raise NotImplementedError("Only 'MILP', 'Cliquer' and 'mcqd' are supported.") @doc_index("Clique-related methods") - def clique_number(self, algorithm="Cliquer", cliques=None, solver=None, verbose=0, + def clique_number(self, algorithm='Cliquer', cliques=None, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Return the order of the largest clique of the graph + Return the order of the largest clique of the graph. This is also called as the clique number. @@ -6832,7 +6516,7 @@ def clique_number(self, algorithm="Cliquer", cliques=None, solver=None, verbose= - ``cliques`` -- an optional list of cliques that can be input if already computed. Ignored unless ``algorithm=="networkx"``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -6840,7 +6524,7 @@ def clique_number(self, algorithm="Cliquer", cliques=None, solver=None, verbose= :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -6881,11 +6565,11 @@ def clique_number(self, algorithm="Cliquer", cliques=None, solver=None, verbose= TESTS:: sage: g = graphs.PetersenGraph() - sage: g.clique_number(algorithm="MILP") # needs sage.numerical.mip + sage: g.clique_number(algorithm='MILP') # needs sage.numerical.mip 2 sage: for i in range(10): # optional - mcqd # needs sage.numerical.mip ....: g = graphs.RandomGNP(15,.5) - ....: if g.clique_number() != g.clique_number(algorithm="mcqd"): + ....: if g.clique_number() != g.clique_number(algorithm='mcqd'): ....: print("This is dead wrong !") """ self._scream_if_not_simple(allow_loops=False) @@ -6917,11 +6601,10 @@ def cliques_number_of(self, vertices=None, cliques=None): INPUT: - - ``vertices`` -- the vertices to inspect (default is entire graph) + - ``vertices`` -- the vertices to inspect (default: entire graph) - ``cliques`` -- list of cliques (if already computed) - EXAMPLES:: sage: C = Graph('DJ{') @@ -7059,7 +6742,7 @@ def cliques_get_clique_bipartite(self, **kwds): return BipartiteGraph(G, check=False) @doc_index("Algorithmically hard stuff") - def independent_set(self, algorithm="Cliquer", value_only=False, reduction_rules=True, + def independent_set(self, algorithm='Cliquer', value_only=False, reduction_rules=True, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" Return a maximum independent set. @@ -7097,12 +6780,12 @@ def independent_set(self, algorithm="Cliquer", value_only=False, reduction_rules only the size of a maximum independent set is returned. Otherwise, a maximum independent set is returned as a list of vertices. - - ``reduction_rules`` -- (default: ``True``); specify if the reductions + - ``reduction_rules`` -- (default: ``True``) specify if the reductions rules from kernelization must be applied as pre-processing or not. See [ACFLSS04]_ for more details. Note that depending on the instance, it might be faster to disable reduction rules. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7110,7 +6793,7 @@ def independent_set(self, algorithm="Cliquer", value_only=False, reduction_rules :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7134,7 +6817,7 @@ def independent_set(self, algorithm="Cliquer", value_only=False, reduction_rules As a linear program:: sage: C = graphs.PetersenGraph() - sage: len(C.independent_set(algorithm="MILP")) # needs sage.numerical.mip + sage: len(C.independent_set(algorithm='MILP')) # needs sage.numerical.mip 4 .. PLOT:: @@ -7152,11 +6835,11 @@ def independent_set(self, algorithm="Cliquer", value_only=False, reduction_rules return [u for u in self if u not in my_cover] @doc_index("Algorithmically hard stuff") - def vertex_cover(self, algorithm="Cliquer", value_only=False, + def vertex_cover(self, algorithm='Cliquer', value_only=False, reduction_rules=True, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Return a minimum vertex cover of self represented by a set of vertices. + Return a minimum vertex cover of ``self`` represented by a set of vertices. A minimum vertex cover of a graph is a set `S` of vertices such that each edge is incident to at least one element of `S`, and such that `S` @@ -7176,16 +6859,16 @@ def vertex_cover(self, algorithm="Cliquer", value_only=False, INPUT: - - ``algorithm`` -- string (default: ``"Cliquer"``). Indicating which + - ``algorithm`` -- string (default: ``'Cliquer'``); indicating which algorithm to use. It can be one of those values. - - ``"Cliquer"`` will compute a minimum vertex cover using the Cliquer - package. + - ``'Cliquer'`` will compute a minimum vertex cover using the Cliquer + package - - ``"MILP"`` will compute a minimum vertex cover through a mixed - integer linear program. + - ``'MILP'`` will compute a minimum vertex cover through a mixed + integer linear program - - ``"mcqd"`` will use the MCQD solver + - ``'mcqd'`` will use the MCQD solver (``_). Note that the MCQD package must be installed. @@ -7193,12 +6876,12 @@ def vertex_cover(self, algorithm="Cliquer", value_only=False, only the size of a minimum vertex cover is returned. Otherwise, a minimum vertex cover is returned as a list of vertices. - - ``reduction_rules`` -- (default: ``True``); specify if the reductions + - ``reduction_rules`` -- (default: ``True``) specify if the reductions rules from kernelization must be applied as pre-processing or not. See [ACFLSS04]_ for more details. Note that depending on the instance, it might be faster to disable reduction rules. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -7206,7 +6889,7 @@ def vertex_cover(self, algorithm="Cliquer", value_only=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -7231,8 +6914,8 @@ def vertex_cover(self, algorithm="Cliquer", value_only=False, The two algorithms should return the same result:: sage: g = graphs.RandomGNP(10, .5) - sage: vc1 = g.vertex_cover(algorithm="MILP") # needs sage.numerical.mip - sage: vc2 = g.vertex_cover(algorithm="Cliquer") + sage: vc1 = g.vertex_cover(algorithm='MILP') # needs sage.numerical.mip + sage: vc2 = g.vertex_cover(algorithm='Cliquer') sage: len(vc1) == len(vc2) # needs sage.numerical.mip True @@ -7271,12 +6954,12 @@ def vertex_cover(self, algorithm="Cliquer", value_only=False, Testing mcqd:: - sage: graphs.PetersenGraph().vertex_cover(algorithm="mcqd", value_only=True) # optional - mcqd + sage: graphs.PetersenGraph().vertex_cover(algorithm='mcqd', value_only=True) # optional - mcqd 6 Given a wrong algorithm:: - sage: graphs.PetersenGraph().vertex_cover(algorithm="guess") + sage: graphs.PetersenGraph().vertex_cover(algorithm='guess') Traceback (most recent call last): ... ValueError: the algorithm must be "Cliquer", "MILP" or "mcqd" @@ -7528,7 +7211,6 @@ def ear_decomposition(self): Traceback (most recent call last): ... ValueError: ear decomposition is defined for graphs of order at least 3 - """ # Ear decomposition of a graph of order < 3 is []. if self.order() < 3: @@ -7609,7 +7291,7 @@ def traverse(start, pointer): return chains @doc_index("Clique-related methods") - def cliques_vertex_clique_number(self, algorithm="cliquer", vertices=None, + def cliques_vertex_clique_number(self, algorithm='cliquer', vertices=None, cliques=None): """ Return a dictionary of sizes of the largest maximal cliques containing @@ -7624,14 +7306,14 @@ def cliques_vertex_clique_number(self, algorithm="cliquer", vertices=None, INPUT: - - ``algorithm`` -- either ``cliquer`` or ``networkx`` + - ``algorithm`` -- either ``cliquer`` or ``networkx`` - - ``cliquer`` -- This wraps the C program Cliquer [NO2003]_. + - ``cliquer`` -- this wraps the C program Cliquer [NO2003]_ - - ``networkx`` -- This function is based on NetworkX's implementation - of the Bron and Kerbosch Algorithm [BK1973]_. + - ``networkx`` -- this function is based on NetworkX's implementation + of the Bron and Kerbosch Algorithm [BK1973]_ - - ``vertices`` -- the vertices to inspect (default is entire graph). + - ``vertices`` -- the vertices to inspect (default: entire graph). Ignored unless ``algorithm=='networkx'``. - ``cliques`` -- list of cliques (if already computed). Ignored unless @@ -7644,11 +7326,11 @@ def cliques_vertex_clique_number(self, algorithm="cliquer", vertices=None, {0: 2, 1: 4, 2: 4, 3: 4, 4: 4} sage: E = C.cliques_maximal(); E [[0, 4], [1, 2, 3, 4]] - sage: C.cliques_vertex_clique_number(cliques=E, algorithm="networkx") # needs networkx + sage: C.cliques_vertex_clique_number(cliques=E, algorithm='networkx') # needs networkx {0: 2, 1: 4, 2: 4, 3: 4, 4: 4} sage: F = graphs.Grid2dGraph(2,3) - sage: F.cliques_vertex_clique_number(algorithm="networkx") # needs networkx + sage: F.cliques_vertex_clique_number(algorithm='networkx') # needs networkx {(0, 0): 2, (0, 1): 2, (0, 2): 2, (1, 0): 2, (1, 1): 2, (1, 2): 2} sage: F.cliques_vertex_clique_number(vertices=[(0, 1), (1, 2)]) # needs sage.plot {(0, 1): 2, (1, 2): 2} @@ -7687,7 +7369,7 @@ def cliques_containing_vertex(self, vertices=None, cliques=None): INPUT: - - ``vertices`` -- the vertices to inspect (default is entire graph) + - ``vertices`` -- the vertices to inspect (default: entire graph) - ``cliques`` -- list of cliques (if already computed) @@ -7754,10 +7436,10 @@ def cliques_containing_vertex(self, vertices=None, cliques=None): @doc_index("Clique-related methods") def clique_complex(self): """ - Return the clique complex of self. + Return the clique complex of ``self``. - This is the largest simplicial complex on the vertices of self whose - 1-skeleton is self. + This is the largest simplicial complex on the vertices of ``self`` whose + 1-skeleton is ``self``. This is only makes sense for undirected simple graphs. @@ -7776,7 +7458,6 @@ def clique_complex(self): True sage: x==i.clique_complex() True - """ if self.is_directed() or self.has_loops() or self.has_multiple_edges(): raise ValueError("Self must be an undirected simple graph to have a clique complex.") @@ -7788,7 +7469,7 @@ def clique_complex(self): @doc_index("Clique-related methods") def clique_polynomial(self, t=None): r""" - Return the clique polynomial of self. + Return the clique polynomial of ``self``. This is the polynomial where the coefficient of `t^n` is the number of cliques in the graph with `n` vertices. The constant term of the clique @@ -7805,7 +7486,6 @@ def clique_polynomial(self, t=None): sage: g = graphs.CycleGraph(4) sage: g.clique_polynomial() 4*t^2 + 4*t + 1 - """ if t is None: R = PolynomialRing(ZZ, 't') @@ -7864,7 +7544,7 @@ def cores(self, k=None, with_labels=False): INPUT: - - ``k`` -- integer (default: ``None``); + - ``k`` -- integer (default: ``None``) * If ``k = None`` (default), returns the core number for each vertex. @@ -7930,7 +7610,7 @@ def cores(self, k=None, with_labels=False): """ self._scream_if_not_simple(allow_multiple_edges=True) if k is not None and k < 0: - raise ValueError("parameter k must be a non negative integer") + raise ValueError("parameter k must be a nonnegative integer") if not self or not self.size(): if k is not None: return ([], list(self)) if not k else (list(self), []) @@ -8039,9 +7719,9 @@ def modular_decomposition(self, algorithm=None, style='tuple'): - ``style`` -- string (default: ``'tuple'``); specifies the output format: - - ``'tuple'`` -- as nested tuples. + - ``'tuple'`` -- as nested tuples - - ``'tree'`` -- as :class:`~sage.combinat.rooted_tree.LabelledRootedTree`. + - ``'tree'`` -- as :class:`~sage.combinat.rooted_tree.LabelledRootedTree` OUTPUT: @@ -8049,9 +7729,9 @@ def modular_decomposition(self, algorithm=None, style='tuple'): * The type of the current module : - * ``"PARALLEL"`` - * ``"PRIME"`` - * ``"SERIES"`` + * ``'PARALLEL'`` + * ``'PRIME'`` + * ``'SERIES'`` * The list of submodules (as list of pairs ``(type, list)``, recursively...) or the vertex's name if the module is a singleton. @@ -8138,7 +7818,7 @@ def modular_decomposition(self, algorithm=None, style='tuple'): .. SEEALSO:: - - :meth:`is_prime` -- Tests whether a graph is prime. + - :meth:`is_prime` -- tests whether a graph is prime - :class:`~sage.combinat.rooted_tree.LabelledRootedTree`. @@ -8159,9 +7839,9 @@ def modular_decomposition(self, algorithm=None, style='tuple'): Singleton Vertex:: sage: Graph(1).modular_decomposition() - (PRIME, [0]) + 0 sage: Graph(1).modular_decomposition(style='tree') - PRIME[0[]] + 0[] Vertices may be arbitrary --- check that :issue:`24898` is fixed:: @@ -8209,8 +7889,7 @@ def modular_decomposition(self, algorithm=None, style='tuple'): if not self.order(): D = None elif self.order() == 1: - D = create_prime_node() - D.children.append(create_normal_node(self.vertices(sort=False)[0])) + D = create_normal_node(next(self.vertex_iterator())) else: D = habib_maurer_algorithm(self) @@ -8279,7 +7958,6 @@ def is_polyhedral(self) -> bool: sage: G = Graph([[1, 2, 3], [[1, 2], [3, 1], [1, 2], [2, 3]]], multiedges=True) sage: G.is_polyhedral() False - """ return (not self.has_loops() and not self.has_multiple_edges() @@ -8287,7 +7965,7 @@ def is_polyhedral(self) -> bool: and self.is_planar()) @doc_index("Graph properties") - def is_circumscribable(self, solver="ppl", verbose=0): + def is_circumscribable(self, solver='ppl', verbose=0): """ Test whether the graph is the graph of a circumscribed polyhedron. @@ -8300,7 +7978,7 @@ def is_circumscribable(self, solver="ppl", verbose=0): INPUT: - - ``solver`` -- (default: ``"ppl"``); specify a Linear Program (LP) + - ``solver`` -- (default: ``'ppl'``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`solve @@ -8308,7 +7986,7 @@ def is_circumscribable(self, solver="ppl", verbose=0): :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. EXAMPLES:: @@ -8405,7 +8083,7 @@ def is_circumscribable(self, solver="ppl", verbose=0): return solution > 0 @doc_index("Graph properties") - def is_inscribable(self, solver="ppl", verbose=0): + def is_inscribable(self, solver='ppl', verbose=0): """ Test whether the graph is the graph of an inscribed polyhedron. @@ -8416,7 +8094,7 @@ def is_inscribable(self, solver="ppl", verbose=0): INPUT: - - ``solver`` -- (default: ``"ppl"``); specify a Linear Program (LP) + - ``solver`` -- (default: ``'ppl'``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`solve @@ -8424,7 +8102,7 @@ def is_inscribable(self, solver="ppl", verbose=0): :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. EXAMPLES:: @@ -8518,7 +8196,7 @@ def is_prime(self, algorithm=None): def _gomory_hu_tree(self, vertices, algorithm=None): r""" - Return a Gomory-Hu tree associated to self. + Return a Gomory-Hu tree associated to ``self``. This function is the private counterpart of ``gomory_hu_tree()``, with the difference that it has an optional argument needed for recursive @@ -8528,7 +8206,7 @@ def _gomory_hu_tree(self, vertices, algorithm=None): INPUT: - - ``vertices`` -- a set of "real" vertices, as opposed to the fakes one + - ``vertices`` -- set of "real" vertices, as opposed to the fakes one introduced during the computations. This variable is useful for the algorithm and for recursion purposes. @@ -8608,7 +8286,7 @@ def _gomory_hu_tree(self, vertices, algorithm=None): @doc_index("Connectivity, orientations, trees") def gomory_hu_tree(self, algorithm=None): r""" - Return a Gomory-Hu tree of self. + Return a Gomory-Hu tree of ``self``. Given a tree `T` with labeled edges representing capacities, it is very easy to determine the maximum flow between any pair of vertices : @@ -8627,9 +8305,7 @@ def gomory_hu_tree(self, algorithm=None): method. Refer to its documentation for allowed values and default behaviour. - OUTPUT: - - A graph with labeled edges + OUTPUT: a graph with labeled edges EXAMPLES: @@ -8707,20 +8383,20 @@ def two_factor_petersen(self, solver=None, verbose=0, *, integrality_tolerance=1 Petersen's 2-factor decomposition theorem asserts that any `2r`-regular graph `G` can be decomposed into 2-factors. Equivalently, it means that - the edges of any `2r`-regular graphs can be partitionned in `r` sets + the edges of any `2r`-regular graphs can be partitioned in `r` sets `C_1,\dots,C_r` such that for all `i`, the set `C_i` is a disjoint union of cycles (a 2-regular graph). As any graph of maximal degree `\Delta` can be completed into a regular graph of degree `2\lceil\frac\Delta 2\rceil`, this result also means - that the edges of any graph of degree `\Delta` can be partitionned in + that the edges of any graph of degree `\Delta` can be partitioned in `r=2\lceil\frac\Delta 2\rceil` sets `C_1,\dots,C_r` such that for all `i`, the set `C_i` is a graph of maximal degree `2` (a disjoint union of paths and cycles). INPUT: - - ``solver`` -- string (default: ``None``); specify a Mixed Integer + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -8728,7 +8404,7 @@ def two_factor_petersen(self, solver=None, verbose=0, *, integrality_tolerance=1 :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP @@ -8760,7 +8436,6 @@ def two_factor_petersen(self, solver=None, verbose=0, *, integrality_tolerance=1 sage: cl = g.two_factor_petersen() # needs sage.numerical.mip sage: g.plot(edge_colors={'black':cl[0], 'red':cl[1]}) # needs sage.numerical.mip sage.plot Graphics object consisting of 73 graphics primitives - """ self._scream_if_not_simple() d = self.eulerian_orientation() @@ -8806,9 +8481,7 @@ def kirchhoff_symanzik_polynomial(self, name='t'): - ``name`` -- name of the variables (default: ``'t'``) - OUTPUT: - - - a polynomial with integer coefficients + OUTPUT: a polynomial with integer coefficients ALGORITHM: @@ -9035,223 +8708,6 @@ def ihara_zeta_function_inverse(self): T[2 * j + 1, 2 * i] = 1 return T.charpoly('t').reverse() - @doc_index("Leftovers") - def perfect_matchings(self, labels=False): - r""" - Return an iterator over all perfect matchings of the graph. - - ALGORITHM: - - Choose a vertex `v`, then recurse through all edges incident to `v`, - removing one edge at a time whenever an edge is added to a matching. - - INPUT: - - - ``labels`` -- boolean (default: ``False``); when ``True``, the edges - in each perfect matching are triples (containing the label as the - third element), otherwise the edges are pairs. - - .. SEEALSO:: - - :meth:`matching` - - EXAMPLES:: - - sage: G=graphs.GridGraph([2,3]) - sage: for m in G.perfect_matchings(): - ....: print(sorted(m)) - [((0, 0), (0, 1)), ((0, 2), (1, 2)), ((1, 0), (1, 1))] - [((0, 0), (1, 0)), ((0, 1), (0, 2)), ((1, 1), (1, 2))] - [((0, 0), (1, 0)), ((0, 1), (1, 1)), ((0, 2), (1, 2))] - - sage: G = graphs.CompleteGraph(4) - sage: for m in G.perfect_matchings(labels=True): - ....: print(sorted(m)) - [(0, 1, None), (2, 3, None)] - [(0, 2, None), (1, 3, None)] - [(0, 3, None), (1, 2, None)] - - sage: G = Graph([[1,-1,'a'], [2,-2, 'b'], [1,-2,'x'], [2,-1,'y']]) - sage: sorted(sorted(m) for m in G.perfect_matchings(labels=True)) - [[(-2, 1, 'x'), (-1, 2, 'y')], [(-2, 2, 'b'), (-1, 1, 'a')]] - - sage: G = graphs.CompleteGraph(8) - sage: mpc = G.matching_polynomial().coefficients(sparse=False)[0] # needs sage.libs.flint - sage: len(list(G.perfect_matchings())) == mpc # needs sage.libs.flint - True - - sage: G = graphs.PetersenGraph().copy(immutable=True) - sage: [sorted(m) for m in G.perfect_matchings()] - [[(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)], - [(0, 1), (2, 7), (3, 4), (5, 8), (6, 9)], - [(0, 4), (1, 2), (3, 8), (5, 7), (6, 9)], - [(0, 4), (1, 6), (2, 3), (5, 8), (7, 9)], - [(0, 5), (1, 2), (3, 4), (6, 8), (7, 9)], - [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]] - - sage: list(Graph().perfect_matchings()) - [[]] - - sage: G = graphs.CompleteGraph(5) - sage: list(G.perfect_matchings()) - [] - """ - if not self: - yield [] - return - if self.order() % 2 or any(len(cc) % 2 for cc in self.connected_components(sort=False)): - return - - def rec(G): - """ - Iterator over all perfect matchings of a simple graph `G`. - """ - if not G: - yield [] - return - if G.order() % 2 == 0: - v = next(G.vertex_iterator()) - Nv = list(G.neighbor_iterator(v)) - G.delete_vertex(v) - for u in Nv: - Nu = list(G.neighbor_iterator(u)) - G.delete_vertex(u) - for partial_matching in rec(G): - partial_matching.append((u, v)) - yield partial_matching - G.add_vertex(u) - G.add_edges((u, nu) for nu in Nu) - G.add_vertex(v) - G.add_edges((v, nv) for nv in Nv) - - # We create a mutable copy of the graph and remove its loops, if any - G = self.copy(immutable=False) - G.allow_loops(False) - - # We create a mapping from frozen unlabeled edges to (labeled) edges. - # This ease for instance the manipulation of multiedges (if any) - edges = {} - for e in G.edges(sort=False, labels=labels): - f = frozenset(e[:2]) - if f in edges: - edges[f].append(e) - else: - edges[f] = [e] - - # We now get rid of multiple edges, if any - G.allow_multiple_edges(False) - - # For each unlabeled matching, we yield all its possible labelings - for m in rec(G): - yield from itertools.product(*[edges[frozenset(e)] for e in m]) - - @doc_index("Leftovers") - def has_perfect_matching(self, algorithm="Edmonds", solver=None, verbose=0, - *, integrality_tolerance=1e-3): - r""" - Return whether this graph has a perfect matching. - INPUT: - - - ``algorithm`` -- string (default: ``"Edmonds"``) - - - ``"Edmonds"`` uses Edmonds' algorithm as implemented in NetworkX to - find a matching of maximal cardinality, then check whether this - cardinality is half the number of vertices of the graph. - - - ``"LP_matching"`` uses a Linear Program to find a matching of - maximal cardinality, then check whether this cardinality is half the - number of vertices of the graph. - - - ``"LP"`` uses a Linear Program formulation of the perfect matching - problem: put a binary variable ``b[e]`` on each edge `e`, and for - each vertex `v`, require that the sum of the values of the edges - incident to `v` is 1. - - - ``solver`` -- string (default: ``None``); specify a Mixed Integer - Linear Programming (MILP) solver to be used. If set to ``None``, the - default one is used. For more information on MILP solvers and which - default solver is used, see the method :meth:`solve - ` of the class - :class:`MixedIntegerLinearProgram - `. - - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity: - set to 0 by default, which means quiet (only useful when - ``algorithm == "LP_matching"`` or ``algorithm == "LP"``) - - - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. - - OUTPUT: - - A boolean. - - EXAMPLES:: - - sage: graphs.PetersenGraph().has_perfect_matching() # needs networkx - True - sage: graphs.WheelGraph(6).has_perfect_matching() # needs networkx - True - sage: graphs.WheelGraph(5).has_perfect_matching() # needs networkx - False - sage: graphs.PetersenGraph().has_perfect_matching(algorithm="LP_matching") # needs sage.numerical.mip - True - sage: graphs.WheelGraph(6).has_perfect_matching(algorithm="LP_matching") # needs sage.numerical.mip - True - sage: graphs.WheelGraph(5).has_perfect_matching(algorithm="LP_matching") - False - sage: graphs.PetersenGraph().has_perfect_matching(algorithm="LP_matching") # needs sage.numerical.mip - True - sage: graphs.WheelGraph(6).has_perfect_matching(algorithm="LP_matching") # needs sage.numerical.mip - True - sage: graphs.WheelGraph(5).has_perfect_matching(algorithm="LP_matching") - False - - TESTS:: - - sage: G = graphs.EmptyGraph() - sage: all(G.has_perfect_matching(algorithm=algo) # needs networkx - ....: for algo in ['Edmonds', 'LP_matching', 'LP']) - True - - Be careful with isolated vertices:: - - sage: G = graphs.PetersenGraph() - sage: G.add_vertex(11) - sage: any(G.has_perfect_matching(algorithm=algo) # needs networkx - ....: for algo in ['Edmonds', 'LP_matching', 'LP']) - False - """ - if self.order() % 2: - return False - if algorithm == "Edmonds": - return len(self) == 2*self.matching(value_only=True, - use_edge_labels=False, - algorithm="Edmonds") - elif algorithm == "LP_matching": - return len(self) == 2*self.matching(value_only=True, - use_edge_labels=False, - algorithm="LP", - solver=solver, - verbose=verbose, - integrality_tolerance=integrality_tolerance) - elif algorithm == "LP": - from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException - p = MixedIntegerLinearProgram(solver=solver) - b = p.new_variable(binary=True) - for v in self: - edges = self.edges_incident(v, labels=False) - if not edges: - return False - p.add_constraint(p.sum(b[frozenset(e)] for e in edges) == 1) - try: - p.solve(log=verbose) - return True - except MIPSolverException: - return False - raise ValueError('algorithm must be set to "Edmonds", "LP_matching" or "LP"') - @doc_index("Leftovers") def effective_resistance(self, i, j, *, base_ring=None): r""" @@ -9558,7 +9014,7 @@ def least_effective_resistance(self, nonedgesonly=True): INPUT: - - ``nonedgesonly`` -- Boolean (default: `True`); if true, assign zero + - ``nonedgesonly`` -- boolean (default: ``True``); if ``True``, assign zero resistance to pairs of adjacent vertices OUTPUT: list @@ -9592,7 +9048,7 @@ def least_effective_resistance(self, nonedgesonly=True): resistances * :meth:`effective_resistance` -- - compuetes effective resistance for a single node pair + computes effective resistance for a single node pair * See :wikipedia:`Resistance_distance` for more details. @@ -9780,7 +9236,7 @@ def most_common_neighbors(self, nonedgesonly=True): INPUT: - ``nonedgesonly`` -- boolean (default: ``True``); if ``True``, assigns - `0` value to adjacent vertices. + `0` value to adjacent vertices OUTPUT: list of tuples of edge pairs @@ -9860,7 +9316,7 @@ def arboricity(self, certificate=False): INPUT: - ``certificate`` -- boolean (default: ``False``); whether to return - a certificate. + a certificate OUTPUT: @@ -9983,9 +9439,7 @@ def folded_graph(self, check=False): graph is antipodal. If ``check`` is ``True`` and the graph is not antipodal, then return ``False``. - OUTPUT: - - This function returns a new graph and ``self`` is not touched. + OUTPUT: this function returns a new graph and ``self`` is not touched .. NOTE:: @@ -10073,9 +9527,7 @@ def antipodal_graph(self): two vertices are adjacent if their distance in `G` is equal to the diameter of `G`. - OUTPUT: - - A new graph. ``self`` is not touched. + OUTPUT: a new graph. ``self`` is not touched EXAMPLES:: @@ -10129,12 +9581,10 @@ def bipartite_double(self, extended=False): INPUT: - - ``extended`` -- boolean (default: ``False``); Whether to return the + - ``extended`` -- boolean (default: ``False``); whether to return the extended bipartite double, or only the bipartite double (default) - OUTPUT: - - A graph; ``self`` is left untouched. + OUTPUT: a graph; ``self`` is left untouched EXAMPLES:: @@ -10227,6 +9677,7 @@ def bipartite_double(self, extended=False): from sage.graphs.graph_decompositions.clique_separators import atoms_and_clique_separators from sage.graphs.graph_decompositions.bandwidth import bandwidth from sage.graphs.graph_decompositions.cutwidth import cutwidth + from sage.graphs.graph_decompositions.slice_decomposition import slice_decomposition matching_polynomial = LazyImport('sage.graphs.matchpoly', 'matching_polynomial', at_startup=True) from sage.graphs.cliquer import all_max_clique as cliques_maximum from sage.graphs.cliquer import all_cliques @@ -10239,7 +9690,10 @@ def bipartite_double(self, extended=False): from sage.graphs.tutte_polynomial import tutte_polynomial from sage.graphs.lovasz_theta import lovasz_theta from sage.graphs.partial_cube import is_partial_cube - from sage.graphs.orientations import strong_orientations_iterator, random_orientation, acyclic_orientations + from sage.graphs.orientations import orient + from sage.graphs.orientations import strong_orientations_iterator + from sage.graphs.orientations import random_orientation + from sage.graphs.orientations import acyclic_orientations from sage.graphs.connectivity import bridges, cleave, spqr_tree from sage.graphs.connectivity import is_triconnected from sage.graphs.comparability import is_comparability @@ -10255,6 +9709,12 @@ def bipartite_double(self, extended=False): from sage.graphs.graph_coloring import fractional_chromatic_number from sage.graphs.graph_coloring import fractional_chromatic_index from sage.graphs.hyperbolicity import hyperbolicity + from sage.graphs.matching import has_perfect_matching + from sage.graphs.matching import is_bicritical + from sage.graphs.matching import is_factor_critical + from sage.graphs.matching import is_matching_covered + from sage.graphs.matching import matching + from sage.graphs.matching import perfect_matchings _additional_categories = { @@ -10283,6 +9743,7 @@ def bipartite_double(self, extended=False): "is_permutation" : "Graph properties", "tutte_polynomial" : "Algorithmically hard stuff", "lovasz_theta" : "Leftovers", + "orient" : "Connectivity, orientations, trees", "strong_orientations_iterator" : "Connectivity, orientations, trees", "random_orientation" : "Connectivity, orientations, trees", "acyclic_orientations" : "Connectivity, orientations, trees", @@ -10303,7 +9764,13 @@ def bipartite_double(self, extended=False): "fractional_chromatic_number" : "Coloring", "fractional_chromatic_index" : "Coloring", "geodetic_closure" : "Leftovers", - "hyperbolicity" : "Distances", + "hyperbolicity" : "Distances", + "has_perfect_matching" : "Matching", + "is_bicritical" : "Matching", + "is_factor_critical" : "Matching", + "is_matching_covered" : "Matching", + "matching" : "Matching", + "perfect_matchings" : "Matching" } __doc__ = __doc__.replace("{INDEX_OF_METHODS}", gen_thematic_rest_table_index(Graph, _additional_categories)) diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 3f8c892f30e..30fb0cf3a53 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -149,22 +149,22 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, INPUT: - * ``G`` -- a graph + - ``G`` -- a graph - * ``n`` -- a positive integer; the number of colors + - ``n`` -- positive integer; the number of colors - * ``count_only`` -- boolean (default: ``False``); when set to ``True``, it + - ``count_only`` -- boolean (default: ``False``); when set to ``True``, it returns 1 for each coloring and ignores other parameters - * ``hex_colors`` -- boolean (default: ``False``); when set to ``False``, + - ``hex_colors`` -- boolean (default: ``False``); when set to ``False``, colors are labeled [0, 1, ..., `n - 1`], otherwise the RGB Hex labeling is used - * ``vertex_color_dict`` -- boolean (default: ``False``); when set to + - ``vertex_color_dict`` -- boolean (default: ``False``); when set to ``True``, it returns a dictionary ``{vertex: color}``, otherwise it returns a dictionary ``{color: [list of vertices]}`` - * ``color_classes`` -- boolean (default: ``False``); when set to ``True``, + - ``color_classes`` -- boolean (default: ``False``); when set to ``True``, the method returns only a list of the color classes and ignores parameters ``hex_colors`` and ``vertex_color_dict`` @@ -234,7 +234,7 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, ....: print(C) Traceback (most recent call last): ... - ValueError: n must be non-negative + ValueError: n must be nonnegative sage: G = Graph({0: [1], 1: [2]}) sage: for c in all_graph_colorings(G, 2, vertex_color_dict=True): ....: print(c) @@ -267,7 +267,7 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, if not n or n > G.order(): return if n < 0: - raise ValueError("n must be non-negative") + raise ValueError("n must be nonnegative") cdef list V = list(G) @@ -338,7 +338,7 @@ cpdef first_coloring(G, n=0, hex_colors=False): INPUT: - - ``n`` -- integer (default: 0); the minimal number of colors to try + - ``n`` -- integer (default: 0); the minimal number of colors to try - ``hex_colors`` -- boolean (default: ``False``); when set to ``True``, the partition returned is a dictionary whose keys are colors and whose values @@ -368,13 +368,13 @@ cpdef first_coloring(G, n=0, hex_colors=False): cpdef number_of_n_colorings(G, n): r""" - Compute the number of `n`-colorings of a graph + Compute the number of `n`-colorings of a graph. INPUT: - ``G`` -- a graph - - ``n`` -- a positive integer; the number of colors + - ``n`` -- positive integer; the number of colors EXAMPLES:: @@ -467,7 +467,7 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, INPUT: - - ``g`` -- a graph. + - ``g`` -- a graph - ``k`` -- integer (default: ``None``); tests whether the graph is `k`-colorable. The function returns a partition of the vertex set in `k` @@ -484,7 +484,7 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, partition returned is a dictionary whose keys are colors and whose values are the color classes (ideal for plotting). - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -492,7 +492,7 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -750,7 +750,7 @@ def fractional_chromatic_number(G, solver='PPL', verbose=0, - ``G`` -- a graph - - ``solver`` -- (default: ``"PPL"``); specify a Linear Program (LP) solver + - ``solver`` -- (default: ``'PPL'``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`solve ` of the @@ -759,11 +759,11 @@ def fractional_chromatic_number(G, solver='PPL', verbose=0, .. NOTE:: - The default solver used here is ``"PPL"`` which provides exact + The default solver used here is ``'PPL'`` which provides exact results, i.e. a rational number, although this may be slower that using other solvers. - - ``verbose`` -- integer (default: `0`); sets the level of verbosity of + - ``verbose`` -- integer (default: 0); sets the level of verbosity of the LP solver - ``check_components`` -- boolean (default: ``True``); whether the method is @@ -828,7 +828,7 @@ def fractional_chromatic_number(G, solver='PPL', verbose=0, return obj -def fractional_chromatic_index(G, solver="PPL", verbose_constraints=False, verbose=0): +def fractional_chromatic_index(G, solver='PPL', verbose_constraints=False, verbose=0): r""" Return the fractional chromatic index of the graph. @@ -861,7 +861,7 @@ def fractional_chromatic_index(G, solver="PPL", verbose_constraints=False, verbo - ``G`` -- a graph - - ``solver`` -- (default: ``"PPL"``); specify a Linear Program (LP) solver + - ``solver`` -- (default: ``'PPL'``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`solve ` of the @@ -870,7 +870,7 @@ def fractional_chromatic_index(G, solver="PPL", verbose_constraints=False, verbo .. NOTE:: - The default solver used here is ``"PPL"`` which provides exact + The default solver used here is ``'PPL'`` which provides exact results, i.e. a rational number, although this may be slower that using other solvers. Be aware that this method may loop endlessly when using some non exact solvers as reported in :issue:`23658` and @@ -879,7 +879,7 @@ def fractional_chromatic_index(G, solver="PPL", verbose_constraints=False, verbo - ``verbose_constraints`` -- boolean (default: ``False``); whether to display which constraints are being generated - - ``verbose`` -- integer (default: `0`); sets the level of verbosity of the + - ``verbose`` -- integer (default: 0); sets the level of verbosity of the LP solver EXAMPLES: @@ -1003,7 +1003,7 @@ def grundy_coloring(g, k, value_only=True, solver=None, verbose=0, coloring)`` is returned, where ``coloring`` is a dictionary associating its color (integer) to each vertex of the graph. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1011,7 +1011,7 @@ def grundy_coloring(g, k, value_only=True, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -1157,7 +1157,7 @@ def b_coloring(g, k, value_only=True, solver=None, verbose=0, coloring)`` is returned, where ``coloring`` is a dictionary associating its color (integer) to each vertex of the graph. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1165,7 +1165,7 @@ def b_coloring(g, k, value_only=True, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -1302,7 +1302,7 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No INPUT: - - ``g`` -- a graph. + - ``g`` -- a graph - ``value_only`` -- boolean (default: ``False``): @@ -1320,7 +1320,7 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No - When set to ``False``, tries to find a `\Delta`-edge-coloring using Mixed Integer Linear Programming (MILP). If impossible, returns a - `(\Delta + 1)`-edge-coloring. Please note that determinating if the + `(\Delta + 1)`-edge-coloring. Please note that determining if the chromatic index of a graph equals `\Delta` is computationally difficult, and could take a long time. @@ -1328,7 +1328,7 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No partition returned is a dictionary whose keys are colors and whose values are the color classes (ideal for plotting) - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1336,7 +1336,7 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -1542,9 +1542,7 @@ def _vizing_edge_coloring(g): - ``g`` -- a graph - OUTPUT: - - a partition of the edge set into at most `\Delta + 1` matchings + OUTPUT: a partition of the edge set into at most `\Delta + 1` matchings .. SEEALSO:: @@ -1807,7 +1805,7 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, - If ``value_only = False``, returns the color classes according to the value of ``hex_colors`` - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1815,7 +1813,7 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -2005,7 +2003,7 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, - If ``value_only = False``, returns the color classes according to the value of ``hex_colors`` - - ``k`` -- integer; the number of colors to use. + - ``k`` -- integer; the number of colors to use - If ``k > 0``, computes an acyclic edge coloring using `k` colors. @@ -2015,7 +2013,7 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, - If ``k = None``, computes a decomposition using the least possible number of colors. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -2023,7 +2021,7 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py index 653201c3d10..8549b208af6 100644 --- a/src/sage/graphs/graph_database.py +++ b/src/sage/graphs/graph_database.py @@ -99,7 +99,7 @@ def data_to_degseq(data, graph6=None): """ degseq = Integer(data).digits(10) if not degseq: - # compute number of 0's in list from graph6 string + # compute number of 0s in list from graph6 string from sage.graphs.generic_graph_pyx import length_and_string_from_graph6 return length_and_string_from_graph6(str(graph6))[0] * [0] return degseq @@ -266,12 +266,12 @@ def __init__(self, query_string, database=None, param_tuple=None): INPUT: - - ``query_string`` -- a string representing the SQL query + - ``query_string`` -- string representing the SQL query - - ``database`` -- (default: ``None``); the :class:`~GraphDatabase` + - ``database`` -- (default: ``None``) the :class:`~GraphDatabase` instance to query (if ``None`` then a new instance is created) - - ``param_tuple`` -- a tuple of strings (default: ``None``); what to + - ``param_tuple`` -- tuple of strings (default: ``None``); what to replace question marks in ``query_string`` with (optional, but a good idea) @@ -343,8 +343,8 @@ class located in :mod:`sage.databases.sql_db` to make the query - ``graph_db`` -- :class:`~GraphDatabase` (default: ``None``); instance to apply the query to (If ``None``, then a new instance is created) - - ``query_dict`` -- dict (default: ``None``); a dictionary specifying - the query itself. Format is: ``{'table_name': 'tblname', + - ``query_dict`` -- dictionary (default: ``None``); a dictionary + specifying the query itself. Format is: ``{'table_name': 'tblname', 'display_cols': ['col1', 'col2'], 'expression': [col, operator, value]}``. If not ``None``, ``query_dict`` will take precedence over all other arguments. @@ -728,7 +728,7 @@ class GraphDatabase(SQLDatabase): def __init__(self): """ - Graph Database + Graph Database. This class interfaces with the ``sqlite`` database ``graphs.db``. It is an immutable database that inherits from diff --git a/src/sage/graphs/graph_decompositions/bandwidth.pyx b/src/sage/graphs/graph_decompositions/bandwidth.pyx index 61bacd2daf5..a491bb50acd 100644 --- a/src/sage/graphs/graph_decompositions/bandwidth.pyx +++ b/src/sage/graphs/graph_decompositions/bandwidth.pyx @@ -6,7 +6,7 @@ Definition ---------- The bandwidth `bw(M)` of a matrix `M` is the smallest integer `k` such that all -non-zero entries of `M` are at distance `k` from the diagonal. The bandwidth +nonzero entries of `M` are at distance `k` from the diagonal. The bandwidth `bw(G)` of an undirected graph `G` is the minimum bandwidth of the adjacency matrix of `G`, over all possible relabellings of its vertices. @@ -209,7 +209,6 @@ def bandwidth(G, k=None): Traceback (most recent call last): ... ValueError: this method only works on unweighted graphs - """ if G.is_directed(): raise ValueError("this method only works on undirected graphs") diff --git a/src/sage/graphs/graph_decompositions/clique_separators.pyx b/src/sage/graphs/graph_decompositions/clique_separators.pyx index 0bd02e3b5db..3cb10805b8a 100644 --- a/src/sage/graphs/graph_decompositions/clique_separators.pyx +++ b/src/sage/graphs/graph_decompositions/clique_separators.pyx @@ -172,12 +172,6 @@ def atoms_and_clique_separators(G, tree=False, rooted_tree=False, separators=Fal :meth:`~sage.graphs.traversals.maximum_cardinality_search_M` graph traversal and has time complexity in `O(|V|\cdot|E|)`. - .. NOTE:: - As the graph is converted to a short_digraph (with - ``sort_neighbors=True``), the complexity has an extra - `O(|V|+|E|\log{|E|})` for ``SparseGraph`` and `O(|V|^2\log{|E|})` for - ``DenseGraph``. - If the graph is not connected, we insert empty separators between the lists of separators of each connected components. See the examples below for more details. @@ -464,8 +458,7 @@ def atoms_and_clique_separators(G, tree=False, rooted_tree=False, separators=Fal # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=True) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) # variables for the manipulation of the short digraph cdef uint32_t** p_vertices = sd.neighbors diff --git a/src/sage/graphs/graph_decompositions/cutwidth.pyx b/src/sage/graphs/graph_decompositions/cutwidth.pyx index 8aa99a242c9..7929eac7a86 100644 --- a/src/sage/graphs/graph_decompositions/cutwidth.pyx +++ b/src/sage/graphs/graph_decompositions/cutwidth.pyx @@ -108,15 +108,15 @@ optimal layout for the cutwidth of `G`. **Variables:** -- `x_v^k` -- Variable set to 1 if vertex `v` is placed in the ordering at - position `i` with `i\leq k`, and 0 otherwise. +- `x_v^k` -- variable set to 1 if vertex `v` is placed in the ordering at + position `i` with `i\leq k`, and 0 otherwise -- `y_{u,v}^{k}` -- Variable set to 1 if one of `u` or `v` is at a position +- `y_{u,v}^{k}` -- variable set to 1 if one of `u` or `v` is at a position `i\leq k` and the other is at a position `j>k`, and so we have to count edge `uv` at position `k`. Otherwise, `y_{u,v}^{k}=0`. The value of `y_{u,v}^{k}` is a xor of the values of `x_u^k` and `x_v^k`. -- `z` -- Objective value to minimize. It is equal to the maximum over all +- `z` -- objective value to minimize. It is equal to the maximum over all position `k` of the number of edges with one extremity at position at most `k` and the other at position strictly more than `k`, that is `\sum_{uv\in E}y_{u,v}^{k}`. @@ -263,7 +263,7 @@ def width_of_cut_decomposition(G, L): # Front end method for cutwidth ################################################################################ -def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, +def cutwidth(G, algorithm='exponential', cut_off=0, solver=None, verbose=False, *, integrality_tolerance=1e-3): r""" Return the cutwidth of the graph and the corresponding vertex ordering. @@ -272,21 +272,21 @@ def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, - ``G`` -- a Graph or a DiGraph - - ``algorithm`` -- string (default: ``"exponential"``); algorithm to use + - ``algorithm`` -- string (default: ``'exponential'``); algorithm to use among: - - ``exponential`` -- Use an exponential time and space algorithm based on + - ``exponential`` -- use an exponential time and space algorithm based on dynamic programming. This algorithm only works on graphs with strictly less than 32 vertices. - - ``MILP`` -- Use a mixed integer linear programming formulation. This - algorithm has no size restriction but could take a very long time. + - ``MILP`` -- use a mixed integer linear programming formulation. This + algorithm has no size restriction but could take a very long time - ``cut_off`` -- integer (default: 0); used to stop the search as soon as a solution with width at most ``cut_off`` is found, if any. If this bound cannot be reached, the best solution found is returned. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -295,7 +295,7 @@ def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, `. - ``verbose`` -- boolean (default: ``False``); whether to display - information on the computations. + information on the computations - ``integrality_tolerance`` -- float; parameter for use with MILP solvers over an inexact base ring; see @@ -337,15 +337,15 @@ def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, sage: from sage.graphs.graph_decompositions.cutwidth import cutwidth sage: for i in range(2): # long time # needs sage.numerical.mip ....: G = graphs.RandomGNP(7, 0.3) - ....: ve, le = cutwidth(G, algorithm="exponential") - ....: vm, lm = cutwidth(G, algorithm="MILP", solver='GLPK') + ....: ve, le = cutwidth(G, algorithm='exponential') + ....: vm, lm = cutwidth(G, algorithm='MILP', solver='GLPK') ....: if ve != vm: ....: raise ValueError("Something goes wrong!") Given a wrong algorithm:: sage: from sage.graphs.graph_decompositions.cutwidth import cutwidth - sage: cutwidth(graphs.PathGraph(2), algorithm="SuperFast") + sage: cutwidth(graphs.PathGraph(2), algorithm='SuperFast') Traceback (most recent call last): ... ValueError: algorithm "SuperFast" has not been implemented yet, please contribute @@ -370,9 +370,9 @@ def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, sage: from sage.graphs.graph_decompositions.cutwidth import cutwidth sage: G = Graph([(0, 1)]) - sage: cutwidth(G, algorithm="exponential") + sage: cutwidth(G, algorithm='exponential') (1, [0, 1]) - sage: cutwidth(G, algorithm="MILP", solver='GLPK') # needs sage.numerical.mip + sage: cutwidth(G, algorithm='MILP', solver='GLPK') # needs sage.numerical.mip (1, [0, 1]) Cutwidth of a disconnected graph:: @@ -380,9 +380,9 @@ def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, sage: from sage.graphs.graph_decompositions.cutwidth import cutwidth sage: G = Graph(5) sage: G.add_edge(2, 3) - sage: cutwidth(G, algorithm="exponential") + sage: cutwidth(G, algorithm='exponential') (1, [2, 3, 0, 1, 4]) - sage: cutwidth(G, algorithm="MILP", solver='GLPK') # needs sage.numerical.mip + sage: cutwidth(G, algorithm='MILP', solver='GLPK') # needs sage.numerical.mip (1, [2, 3, 0, 1, 4]) """ from sage.graphs.graph import Graph @@ -494,7 +494,6 @@ def cutwidth_dyn(G, lower_bound=0): Traceback (most recent call last): ... ValueError: the specified lower bound must be an integer - """ from sage.graphs.graph import Graph if not isinstance(G, Graph): @@ -617,7 +616,7 @@ def cutwidth_MILP(G, lower_bound=0, solver=None, verbose=0, optimal. If the given bound is too high, the algorithm might not be able to find a feasible solution. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -625,7 +624,7 @@ def cutwidth_MILP(G, lower_bound=0, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers diff --git a/src/sage/graphs/graph_decompositions/fast_digraph.pyx b/src/sage/graphs/graph_decompositions/fast_digraph.pyx index 2d28ccf4d05..a661509d23d 100644 --- a/src/sage/graphs/graph_decompositions/fast_digraph.pyx +++ b/src/sage/graphs/graph_decompositions/fast_digraph.pyx @@ -117,7 +117,7 @@ cdef inline int compute_out_neighborhood_cardinality(FastDigraph g, int S) noexc - ``g`` -- a FastDigraph - - ``S`` -- an integer describing the set + - ``S`` -- integer describing the set EXAMPLES:: diff --git a/src/sage/graphs/graph_decompositions/graph_products.pyx b/src/sage/graphs/graph_decompositions/graph_products.pyx index 98bfb6ec0f5..187f6a7ec09 100644 --- a/src/sage/graphs/graph_decompositions/graph_products.pyx +++ b/src/sage/graphs/graph_decompositions/graph_products.pyx @@ -153,7 +153,7 @@ def is_cartesian_product(g, certificate=False, relabeling=False): - :meth:`sage.graphs.generic_graph.GenericGraph.cartesian_product` - :mod:`~sage.graphs.graph_decompositions.graph_products` -- a module on - graph products. + graph products .. NOTE:: diff --git a/src/sage/graphs/graph_decompositions/meson.build b/src/sage/graphs/graph_decompositions/meson.build new file mode 100644 index 00000000000..0d9778ae2ba --- /dev/null +++ b/src/sage/graphs/graph_decompositions/meson.build @@ -0,0 +1,64 @@ +tdlib = cc.find_library('tdlib', required: false, disabler: true) +# Cannot be found via pkg-config +rw = cc.find_library('rw') + +py.install_sources( + 'all.py', + 'all__sagemath_tdlib.py', + 'fast_digraph.pxd', + 'modular_decomposition.py', + 'rankwidth.pxd', + 'slice_decomposition.pxd', + 'tree_decomposition.pxd', + 'vertex_separation.pxd', + subdir: 'sage/graphs/graph_decompositions', +) + +extension_data = { + 'bandwidth' : files('bandwidth.pyx'), + 'cutwidth' : files('cutwidth.pyx'), + 'fast_digraph' : files('fast_digraph.pyx'), + 'graph_products' : files('graph_products.pyx'), + 'rankwidth' : files('rankwidth.pyx'), + 'tree_decomposition' : files('tree_decomposition.pyx'), + 'vertex_separation' : files('vertex_separation.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/graphs/graph_decompositions', + install: true, + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, cysignals, gmp, rw], + ) +endforeach + +extension_data_cpp = { + 'clique_separators': files('clique_separators.pyx'), + 'slice_decomposition' : files('slice_decomposition.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/graphs/graph_decompositions', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, cysignals, gmp, rw], + ) +endforeach + +py.extension_module( + 'tdlib', + sources: 'tdlib.pyx', + subdir: 'sage/graphs/graph_decompositions', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, cysignals, tdlib], +) + diff --git a/src/sage/graphs/graph_decompositions/modular_decomposition.py b/src/sage/graphs/graph_decompositions/modular_decomposition.py index 03e9231bd65..001f127d63d 100644 --- a/src/sage/graphs/graph_decompositions/modular_decomposition.py +++ b/src/sage/graphs/graph_decompositions/modular_decomposition.py @@ -160,14 +160,14 @@ def __init__(self, node_type): def set_node_split(self, node_split): """ - Add node_split to the node split of self. + Add node_split to the node split of ``self``. ``LEFT_SPLIT`` and ``RIGHT_SPLIT`` can exist together in ``self`` as ``BOTH_SPLIT``. INPUT: - - ``node_split`` -- node_split to be added to self + - ``node_split`` -- ``node_split`` to be added to ``self`` EXAMPLES:: @@ -282,11 +282,9 @@ def __eq__(self, other): def create_prime_node(): """ - Return a prime node with no children + Return a prime node with no children. - OUTPUT: - - A node object with node_type set as NodeType.PRIME + OUTPUT: a node object with ``node_type`` set as ``NodeType.PRIME`` EXAMPLES:: @@ -300,11 +298,9 @@ def create_prime_node(): def create_parallel_node(): """ - Return a parallel node with no children - - OUTPUT: + Return a parallel node with no children. - A node object with node_type set as NodeType.PARALLEL + OUTPUT: a node object with ``node_type`` set as ``NodeType.PARALLEL`` EXAMPLES:: @@ -318,11 +314,9 @@ def create_parallel_node(): def create_series_node(): """ - Return a series node with no children + Return a series node with no children. - OUTPUT: - - A node object with node_type set as NodeType.SERIES + OUTPUT: a node object with ``node_type`` set as ``NodeType.SERIES`` EXAMPLES:: @@ -336,15 +330,14 @@ def create_series_node(): def create_normal_node(vertex): """ - Return a normal node with no children + Return a normal node with no children. INPUT: - ``vertex`` -- vertex number - OUTPUT: - - A node object representing the vertex with node_type set as NodeType.NORMAL + OUTPUT: a node object representing the vertex with ``node_type`` set as + ``NodeType.NORMAL`` EXAMPLES:: @@ -360,7 +353,7 @@ def create_normal_node(vertex): def print_md_tree(root): """ - Print the modular decomposition tree + Print the modular decomposition tree. INPUT: @@ -387,7 +380,7 @@ def print_md_tree(root): def recursive_print_md_tree(root, level): """ - Print the modular decomposition tree at root + Print the modular decomposition tree at root. INPUT: @@ -461,7 +454,7 @@ def gamma_classes(graph): def habib_maurer_algorithm(graph, g_classes=None): """ - Compute the modular decomposition by the algorithm of Habib and Maurer + Compute the modular decomposition by the algorithm of Habib and Maurer. Compute the modular decomposition of the given graph by the algorithm of Habib and Maurer [HM1979]_ . If the graph is disconnected or its complement @@ -483,9 +476,7 @@ def habib_maurer_algorithm(graph, g_classes=None): are the gamma classes of the graph, and whose keys are a frozenset of the vertices corresponding to the class. Used internally. - OUTPUT: - - The modular decomposition tree of the graph. + OUTPUT: the modular decomposition tree of the graph EXAMPLES: @@ -671,9 +662,7 @@ def test_modular_decomposition(tree_root, graph): - ``graph`` -- graph whose modular decomposition tree needs to be tested - OUTPUT: - - ``True`` if input tree is a modular decomposition else ``False`` + OUTPUT: ``True`` if input tree is a modular decomposition else ``False`` EXAMPLES:: @@ -755,7 +744,7 @@ def test_maximal_modules(tree_root, graph): def get_vertices(component_root): """ - Compute the list of vertices in the (co)component + Compute the list of vertices in the (co)component. INPUT: @@ -906,7 +895,7 @@ def form_module(index, other_index, tree_root, graph): # Function implemented for testing def test_module(module, graph): """ - Test whether input module is actually a module + Test whether input module is actually a module. INPUT: @@ -914,9 +903,7 @@ def test_module(module, graph): - ``graph`` -- input sage graph which contains the module - OUTPUT: - - ``True`` if input module is a module by definition else ``False`` + OUTPUT: ``True`` if input module is a module by definition else ``False`` EXAMPLES:: @@ -1073,9 +1060,7 @@ def nested_tuple_to_tree(nest): - ``nest`` -- a nested tuple of the form returned by :meth:`tree_to_nested_tuple` - OUTPUT: - - The root node of a modular decomposition tree. + OUTPUT: the root node of a modular decomposition tree EXAMPLES:: @@ -1146,7 +1131,7 @@ def node_id(root): def relabel_tree(root, perm): r""" - Relabel the leaves of a tree according to a dictionary + Relabel the leaves of a tree according to a dictionary. INPUT: @@ -1225,10 +1210,10 @@ def test_gamma_modules(trials, vertices, prob, verbose=False): - ``vertices`` -- the size of the graph to use - - ``prob`` -- the probability that any given edge is in the graph. - See :meth:`~sage.graphs.generators.random.RandomGNP` for more details. + - ``prob`` -- the probability that any given edge is in the graph + See :meth:`~sage.graphs.generators.random.RandomGNP` for more details - - ``verbose`` -- print information on each trial. + - ``verbose`` -- print information on each trial EXAMPLES:: @@ -1289,10 +1274,10 @@ def random_md_tree(max_depth, max_fan_out, leaf_probability): INPUT: - - ``max_depth`` -- the maximum depth of the tree. + - ``max_depth`` -- the maximum depth of the tree - ``max_fan_out`` -- the maximum number of children a node can have - (must be >=4 as a prime node must have at least 4 vertices). + (must be >=4 as a prime node must have at least 4 vertices) - ``leaf_probability`` -- the probability that a subtree is a leaf diff --git a/src/sage/graphs/graph_decompositions/slice_decomposition.pxd b/src/sage/graphs/graph_decompositions/slice_decomposition.pxd new file mode 100644 index 00000000000..fcd14a25300 --- /dev/null +++ b/src/sage/graphs/graph_decompositions/slice_decomposition.pxd @@ -0,0 +1,17 @@ +from libcpp.vector cimport vector + +from sage.structure.sage_object cimport SageObject +from sage.graphs.base.c_graph cimport CGraph + +cdef void extended_lex_BFS( + CGraph cg, vector[int] &sigma, vector[int] *sigma_inv, + int initial_v_int, vector[int] *pred, vector[size_t] *xslice_len, + vector[vector[int]] *lex_label) except * + +cdef class SliceDecomposition(SageObject): + cdef tuple sigma + cdef dict sigma_inv + cdef vector[size_t] xslice_len + cdef dict lex_label + cdef object _graph_class + cdef object _underlying_graph diff --git a/src/sage/graphs/graph_decompositions/slice_decomposition.pyx b/src/sage/graphs/graph_decompositions/slice_decomposition.pyx new file mode 100644 index 00000000000..39a85485dfa --- /dev/null +++ b/src/sage/graphs/graph_decompositions/slice_decomposition.pyx @@ -0,0 +1,1079 @@ +# cython: binding=True +# distutils: language = c++ +# distutils: extra_compile_args = -std=c++11 +r""" +Slice decomposition + +This module implements an extended lexBFS algorithm for computing the slice +decomposition of undirected graphs and the class :class:`~SliceDecomposition` to +represent such decompositions. + +A formal definition of slice decompositions can be found in Section 3.2 of +[TCHP2008]_ and a description of the extended lexBFS algorithm is given in +Section 3.3 of [TCHP2008]_. + +AUTHORS: + +- Cyril Bouvier (2024-06-25): initial version +""" +# **************************************************************************** +# Copyright (C) 2024 Cyril Bouvier +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from libcpp.algorithm cimport swap +from cython.operator cimport dereference as deref + +from sage.graphs.base.c_graph cimport CGraphBackend +from sage.data_structures.bitset_base cimport bitset_in + +cdef void extended_lex_BFS( + CGraph cg, vector[int] &sigma, vector[int] *sigma_inv, + int initial_v_int, vector[int] *pred, vector[size_t] *xslice_len, + vector[vector[int]] *lex_label) except *: + r""" + Perform a extended lexicographic breadth first search (LexBFS) on the + undirected graph `G`. + + In addition to computing a LexBFS ordering, the extended LexBFS algorithm + can be used to compute the slice decomposition of the graph. + + This function implements the `O(n+m)` time algorithm proposed in [HMPV2000]_ + and [TCHP2008]_. + + INPUT: + + - ``cg`` -- a ``CGraph``. This function ignores loops and multiple edges and + assumes that the graph is undirected. + + - ``sigma`` -- vector of ``int`` to store the ordering of the vertices + resulting from the LexBFS traversal. At the end, the vector will have size + `n` (the number of vertices of the graph). + + - ``sigma_inv`` -- a pointer to a vector to store the inverse of the + permutation ``sigma``. ``sigma_inv`` can be ``NULL`` if the caller does + not need it (but, note that, the inverse of ``sigma`` is still needed by + the algorithm, so it does not save time nor memory to have ``sigma_inv`` + equal to ``NULL``). At the end, if ``sigma_inv`` is not NULL, the vector + pointer by it will have size `n` (the number of vertices of the graph) + and will satisfy: + * sigma[deref(sigma_inv)[v_int]] = v_int + * deref(sigma_inv)[sigma[i]] = i + + - ``initial_v_int`` -- the first vertex to consider. It can be `-1`; in this + case the first active vertex (corresponding to the first bit set in + ``cg.active_vertices``) will be taken as first vertex. + + - ``pred`` -- a pointer to a vector of int to store the predecessor of a + vertex in the LexBFS traversal. ``pred`` can be ``NULL`` if the caller + does not need it (and the information will not be computed by the + algorithm). At the end, if ``pred`` is not NULL, the vector pointer by it + will have size `n` (the number of vertices of the graph) and pred[i] will + be either -1 (if sigma[i] as no predecessor) or a positive value less than + n such that the predecessor of sigma[i] is sigma[pred[i]]. + + - ``xslice_len`` -- a pointer to a vector of size_t to store the length of + the x-slices associated with the lexBFS traversal. ``xslice_len`` can be + ``NULL`` if the caller does not need it (and the information will not be + computed by the algorithm). At the end, if ``xslice_len`` is not NULL, the + vector pointer by it will have size `n` (the number of vertices of the + graph) and the length of the x-slice starting at sigma[i] will be + xslice_len[i]. + + - ``lex_label`` -- a pointer to a vector of vector[int] to store the + lexicographic labels associated with the lexBFS traversal. ``lex_label`` + can be ``NULL`` if the caller does not need it (and the information will + not be computed by the algorithm). At the end, if ``lex_label`` is not + NULL, the vector pointer by it will have size `n` (the number of + vertices of the graph) and the lexicographic label of sigma[i] + will given by lex_label[i]. + + ALGORITHM: + + This algorithm uses the notion of *partition refinement* to determine the + exact position of the vertices in the ordering. + + Consider an ordering `\sigma` of the vertices. For a vertex `v`, we define + `N_i(v) = \{u | u \in N(v) \text{ and } \sigma(u) < i\}`, that is the subset + of neighbors of `v` appearing before the `i`-th vertex in the ordering + `\sigma`. Now, a part of an ordering `\sigma` is a set of consecutive + vertices, `S = \{u | i \leq \sigma(u) \leq j\}`, such that for any `u \in + S`, we have `N_i(u) = N_i(\sigma^{-1}(i))` and for any `v` such that `j < + \sigma(v)`, `N_i(v) \neq N_i(\sigma^{-1}(i))`. The *head* of a part is the + first position of its vertices. + + The algorithm starts with a single part containing all vertices. Then, when + the position of the `i`-th vertex `v` is fixed, it explores the neighbors of + `v` that have not yet been ordered. Consider a part `S` such that `N(x)\cap + S \neq \emptyset`. The algorithm will rearrange the ordering of the vertices + in `S` so that the first vertices are the neighbors of `v`. The subpart + containing the neighbors of `v` is assigned a new name, and the head of `S` + is set to the position of the first vertex of `S \setminus N(v)` in the + ordering `\sigma`. + + Observe that each arc of the graph can induce the subdivision of a part. + Hence, the algorithm can use up to `m + 1` different parts. + + The time complexity of this algorithm is in `O(n + m)`, and our + implementation follows that complexity ``SparseGraph``. For ``DenseGraph``, + the complexity is `O(n^2)`. See [HMPV2000]_ and [TCHP2008]_ for more + details. + + This implementation of extended LexBFS offers some guarantee on the order in + which the vertices appear in the computed ordering: in case of a tie between + lexicographic labels during the computation, this function will "choose" the + vertices in the order in which they appear during the enumeration of the + neighbors of their last common neighbor. + For example, if `(u_0, ..., u_k)` is the beginning of the ordering being + computed and the vertices `v` and `w` currently have the same lexicographic + label (it means that they have the same neighbors in `(u_0, ..., u_k)`). + Let call `u_j` their last neighbor in the current ordering (*i.e.*, for all + `i > j`, `u_i` is not a neighbor of `v` and `w`). This implementation + will choose `v` for the next vertex of the ordering if and only if `v` + appeared before `w` when the neighbors of `u_j` where enumerated. + + One possible use of this guarantee is that the caller can reorder the + adjacency list of vertices (by using, for example, a static sparse graph) + to force the computed LexBFS order to respect a previous one. + + EXAMPLES:: + + To see how it can be used, see the code of the lex_BFS method (in + traversals.pyx) or of the class SliceDecomposition in this module. + + TESTS: + + Indirect doctests:: + + sage: G = graphs.HouseGraph() + sage: G.slice_decomposition() + [0[1[2]] [3] [4]] + sage: G.lex_BFS(algorithm="fast") + [0, 1, 2, 3, 4] + """ + cdef int n = cg.num_verts + # Variables for the partition refinement algorithm + cdef size_t max_nparts = cg.num_arcs // 2 + 1 + cdef bint need_to_delete_sigma_inv = sigma_inv == NULL + if sigma_inv == NULL: + sigma_inv = new vector[int]() + cdef vector[size_t] part_of = vector[size_t](n, 0) + cdef vector[size_t] part_len # only used if xslice_len != NULL (see below) + cdef vector[size_t] part_head = vector[size_t](max_nparts) + cdef vector[size_t] subpart = vector[size_t](max_nparts) + cdef size_t p, part_of_i, nparts, old_nparts + # Temporary variables + cdef int max_degree = 0 + cdef int i, j, k, l, u_int, v_int, t_int + + # Resize vectors + sigma.resize(n) + deref(sigma_inv).resize(cg.active_vertices.size) + if pred != NULL: + deref(pred).clear() + deref(pred).resize(n, -1) # initialize pred[i] to -1 for 0 <= i < n + if xslice_len != NULL: + deref(xslice_len).resize(n) + part_len.resize(max_nparts) + if lex_label != NULL: + deref(lex_label).resize(n) + + # Initialize the position of vertices in sigma (and compute max_degree) + if initial_v_int >= 0: + sigma[0] = initial_v_int + deref(sigma_inv)[initial_v_int] = 0 + i = 1 + else: + i = 0 + for v_int in range( cg.active_vertices.size): + if bitset_in(cg.active_vertices, v_int): + if v_int != initial_v_int: + sigma[i] = v_int + deref(sigma_inv)[v_int] = i + i = i + 1 + max_degree = max(max_degree, cg.out_degrees[v_int]) + + # Variables needed to iterate over neighbors of a vertex + cdef int nneighbors + cdef vector[int] neighbors = vector[int](max_degree) + + # Initialize partition: one part containing all the vertices + nparts = 1 + # all element of part_of are already initialized to 0 + part_head[0] = 0 + subpart[0] = 0 + if xslice_len != NULL: + part_len[0] = n + + # Main loop + for i in range(n): + old_nparts = nparts + + part_of_i = part_of[i] + + # put i out of its part (updating part_len if needed) + part_head[part_of_i] += 1 + if xslice_len != NULL: + deref(xslice_len)[i] = part_len[part_of_i] + part_len[part_of_i] -= 1 + + v_int = sigma[i] + + # Iterate over the neighbors of v + nneighbors = cg.out_neighbors_unsafe (v_int, neighbors.data(), max_degree) + for k in range(nneighbors): + u_int = neighbors[k] + j = deref(sigma_inv)[u_int] # get the position of u + if j <= i: + continue # already taken care of + + if lex_label != NULL: + deref(lex_label)[j].push_back (v_int) + + p = part_of[j] # get the part of u + l = part_head[p] # get the beginning of the part containing u + + # if not last and next elem belongs in the same part (ie #part >= 2) + if l < n - 1 and part_of[l + 1] == p: + if l != j: # not already first elem of the part + # Place u at the position of the head of the part + t_int = sigma[l] + deref(sigma_inv)[t_int], deref(sigma_inv)[u_int] = j, l + sigma[j], sigma[l] = t_int, u_int + if lex_label != NULL: + swap[vector[int]](deref(lex_label)[j], + deref(lex_label)[l]) + j = l + part_head[p] += 1 # move the head of the part to next elem + + # if part p was not already cut in two during this iteration, we + # create a new part using subpart + if subpart[p] < old_nparts: + subpart[p] = nparts + part_head[nparts] = j + if xslice_len != NULL: + part_len[nparts] = 0 + subpart[nparts] = 0 + nparts += 1 + + # Finally, we update the name of the part for position j and set v + # as predecessor of u + part_of[j] = subpart[p] + if xslice_len != NULL: + part_len[p] -= 1 + part_len[subpart[p]] += 1 + if pred != NULL: + deref(pred)[j] = i + + if need_to_delete_sigma_inv: + del sigma_inv + + +def slice_decomposition(G, initial_vertex=None): + r""" + Compute a slice decomposition of the simple undirected graph + + INPUT: + + - ``G`` -- a Sage graph. + + - ``initial_vertex`` -- (default: ``None``); the first vertex to consider. + + OUTPUT: + + An object of type :class:`~sage.graphs.graph_decompositions.slice_decomposition.SliceDecomposition` + that represents a slice decomposition of ``G`` + + .. NOTE:: + + Loops and multiple edges are ignored during the computation of the slice + decomposition. + + ALGORITHM: + + The method use the algorithm based on "partition refinement" described in + [HMPV2000]_ and [TCHP2008]_. + The time complexity of this algorithm is in `O(n + m)`, and our + implementation follows that complexity for ``SparseGraph``. For + ``DenseGraph``, the complexity is `O(n^2)`. + + EXAMPLES: + + Slice decomposition of the Petersen Graph:: + + sage: G = graphs.PetersenGraph() + sage: SD = G.slice_decomposition(); SD + [0[1[4[5]]] [2[6]] [3] [9] [7] [8]] + + The graph can have loops or multiple edges but they are ignored:: + + sage: H = Graph(G,loops=True,multiedges=True) + sage: H.add_edges([(4, 4), (2, 2), (1, 6)]) + sage: SD2 = H.slice_decomposition() + sage: SD2 == SD + True + sage: SD2.underlying_graph() == G.to_simple(immutable=True) + True + + The tree corresponding to the slice decomposition can be displayed using + ``view``:: + + sage: from sage.graphs.graph_latex import check_tkz_graph + sage: check_tkz_graph() # random - depends on Tex installation + sage: view(G) # not tested + sage: latex(G) # to obtain the corresponding LaTeX code + \begin{tikzpicture} + ... + \end{tikzpicture} + + Slice decompositions are only defined for undirected graphs:: + + sage: from sage.graphs.graph_decompositions.slice_decomposition import slice_decomposition + sage: slice_decomposition(DiGraph()) + Traceback (most recent call last): + ... + ValueError: parameter G must be an undirected graph + """ + return SliceDecomposition(G, initial_vertex=initial_vertex) + + +cdef class SliceDecomposition(SageObject): + + def __init__(self, G, initial_vertex=None): + r""" + Represents a slice decomposition of a simple directed graph. + + INPUT: + + - ``G`` -- a Sage graph. + + - ``initial_vertex`` -- (default: ``None``); the first vertex to + consider. + + .. SEEALSO:: + + * :meth:`~slice_decomposition` -- compute a slice decomposition of + the simple undirected graph + * Section 3.2 of [TCHP2008]_ for a formal definition. + + EXAMPLES: + + The constructor of the :class:`~SliceDecomposition` class is called by + the :meth:`~slice_decomposition` method of undirected graphs:: + + sage: from sage.graphs.graph_decompositions.slice_decomposition import SliceDecomposition + sage: G = graphs.PetersenGraph() + sage: SliceDecomposition(G) == G.slice_decomposition() + True + + The vertex appearing first in the slice decomposition can be specified:: + + sage: from sage.graphs.graph_decompositions.slice_decomposition import SliceDecomposition + sage: SliceDecomposition(graphs.PetersenGraph(), initial_vertex=3) + [3[2[4[8]]] [1[7]] [0] [9] [6] [5]] + + Slice decompositions are not defined for directed graphs:: + + sage: from sage.graphs.graph_decompositions.slice_decomposition import SliceDecomposition + sage: SliceDecomposition(DiGraph()) + Traceback (most recent call last): + ... + ValueError: parameter G must be an undirected graph + + .. automethod:: __getitem__ + """ + if G.is_directed(): + raise ValueError("parameter G must be an undirected graph") + + if initial_vertex is not None and initial_vertex not in G: + raise LookupError(f"vertex ({initial_vertex}) is not a vertex of the graph") + + cdef CGraphBackend Gbackend = G._backend + cdef CGraph cg = Gbackend.cg() + + self._graph_class = type(G) + + cdef int initial_v_int + if initial_vertex is not None: + # we already checked that initial_vertex is in G + initial_v_int = Gbackend.get_vertex(initial_vertex) + else: + initial_v_int = -1 + + cdef vector[int] sigma + cdef vector[vector[int]] lex_label + + # Compute the slice decomposition using the extended lexBFS algorithm + extended_lex_BFS(cg, sigma, NULL, initial_v_int, NULL, + &(self.xslice_len), &lex_label) + + # Translate the results with the actual vertices of the graph + self.sigma = tuple(Gbackend.vertex_label(v_int) for v_int in sigma) + self.sigma_inv = {v: i for i, v in enumerate(self.sigma)} + self.lex_label = {i: tuple(Gbackend.vertex_label(v_int) for v_int in lli) + for i, lli in enumerate(lex_label)} + + def __eq__(self, other): + """ + Return whether ``self`` and ``other`` are equal. + + TESTS:: + + sage: G = graphs.PetersenGraph() + sage: SD = G.slice_decomposition() + sage: SD == SD + True + sage: SD == G.slice_decomposition() + True + + sage: P3 = graphs.PathGraph(3) + sage: SD1 = P3.slice_decomposition(initial_vertex=0) + sage: SD2 = P3.slice_decomposition(initial_vertex=2) + sage: SD1 == SD2 + False + sage: SD3 = graphs.CompleteGraph(3).slice_decomposition() + sage: SD1 == SD3 # same lexBFS but different slice for 1 + False + sage: SD4 = Graph([(0,1), (0,2)]).slice_decomposition() + sage: SD3 == SD4 # same lexBFS and slices but different active edges + False + """ + if not isinstance(other, type(self)): + return False + + cdef SliceDecomposition sd = other + + return self.sigma_inv == sd.sigma_inv \ + and self.lex_label == sd.lex_label \ + and self.xslice_len == sd.xslice_len + + def __hash__(self): + r""" + Compute a hash of a ``SliceDecomposition`` object. + + TESTS:: + + sage: P3 = graphs.PathGraph(3) + sage: SD1 = P3.slice_decomposition(initial_vertex=0) + sage: SD2 = P3.slice_decomposition(initial_vertex=2) + sage: len({SD1: 1, SD2: 2}) # indirect doctest + 2 + """ + return hash((tuple(self.sigma_inv.items()), + tuple(self.lex_label.items()), + tuple(self.xslice_len))) + + def __getitem__(self, v): + r""" + Return the data about the x-slice of the vertex `v`. + + INPUT: + + - ``v`` -- a vertex of the graph corresponding to the slice + decomposition. + + OUTPUT: + + A dictionnary with the keys: + + * ``"pivot"`` -- the vertex `v` given as parameter + + * ``"slice"`` -- the slice of `v` (see :meth:`~slice`) + + * ``"active_edges"`` -- the actives edges of `v` (see + :meth:`~active_edges`) + + * ``"lexicographic_label"`` -- the lexicographic label of `v` (see + :meth:`~lexicographic_label`) + + * ``"sequence"`` -- the x-slice sequence of `v` (see + :meth:`~xslice_sequence`) + + This method can also be called via :meth:`xslice_data`. + + EXAMPLES: + + :: + + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x') + sage: SD.xslice_data('a') + {'active_edges': [('a', 'b'), + ('a', 'c'), + ('a', 'd'), + ('a', 'e'), + ('a', 'f'), + ('c', 'g'), + ('d', 'g'), + ('f', 'g')], + 'lexicographic_label': ['x'], + 'pivot': 'a', + 'sequence': [['a'], ['b', 'c', 'd', 'e', 'f'], ['g']], + 'slice': ['a', 'b', 'c', 'd', 'e', 'f', 'g']} + sage: SD.xslice_data('u') + {'active_edges': [], + 'lexicographic_label': ['a', 'b', 'c', 'd', 'e', 'f', 'g'], + 'pivot': 'u', + 'sequence': [['u'], ['y', 'z']], + 'slice': ['u', 'y', 'z']} + + Some values of the returned dictionnary can be obtained via other + methods (:meth:`~slice`, :meth:`~xslice_sequence`, + :meth:`~active_edges`, :meth:`~lexicographic_label`):: + + sage: SD.slice('a') + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + sage: SD.xslice_data('a')['slice'] + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + + sage: SD.xslice_sequence('a') + [['a'], ['b', 'c', 'd', 'e', 'f'], ['g']] + sage: SD.xslice_data('a')['sequence'] + [['a'], ['b', 'c', 'd', 'e', 'f'], ['g']] + + sage: SD.active_edges('b') == SD.xslice_data('b')['active_edges'] + True + + sage: SD.lexicographic_label('u') + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + sage: SD.xslice_data('u')['lexicographic_label'] + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + + TESTS:: + + sage: G = graphs.RandomGNP(15, 0.3) + sage: SD = G.slice_decomposition() + sage: all(SD[v]['slice'] == SD.slice(v) for v in G) + True + sage: all(SD[v]['sequence'] == SD.xslice_sequence(v) for v in G) + True + sage: all(SD[v]['active_edges'] == SD.active_edges(v) for v in G) + True + sage: all(SD[v]['lexicographic_label'] == SD.lexicographic_label(v) for v in G) + True + + sage: SD = graphs.PetersenGraph().slice_decomposition() + sage: SD['John'] + Traceback (most recent call last): + ... + LookupError: vertex (John) does not appear in the slice decomposition + """ + if v not in self.sigma_inv: + raise LookupError(f"vertex ({v}) does not appear in the slice " + "decomposition") + cdef size_t i = self.sigma_inv[v] + return {'pivot': v, + 'slice': self._slice(i), + 'sequence': self._xslice_sequence(i), + 'lexicographic_label': self._xslice_lex_label(i), + 'active_edges': self._xslice_active_edges(i), + } + + def lexBFS_order(self): + r""" + Return the lexBFS order corresponding to the slice decomposition. + + EXAMPLES:: + + sage: from sage.graphs.traversals import _is_valid_lex_BFS_order + sage: G = graphs.PetersenGraph(); SD = G.slice_decomposition() + sage: SD.lexBFS_order() + [0, 1, 4, 5, 2, 6, 3, 9, 7, 8] + sage: _is_valid_lex_BFS_order(G, SD.lexBFS_order()) + True + + TESTS:: + + sage: from sage.graphs.traversals import _is_valid_lex_BFS_order + sage: for _ in range(5): + ....: G = graphs.RandomGNP(15, 0.3) + ....: SD = G.slice_decomposition() + ....: _is_valid_lex_BFS_order(G, SD.lexBFS_order()) + True + True + True + True + True + """ + return list(self.sigma) + + def xslice_data(self, v): + r""" + Return the data about the x-slice of the vertex `v`. + + This method is a wrapper around :meth:`SliceDecomposition.__getitem__` + + TESTS:: + + sage: G = graphs.RandomGNP(15, 0.3) + sage: SD = G.slice_decomposition() + sage: all(SD[v] == SD.xslice_data(v) for v in G) + True + """ + return self[v] + + def slice(self, v): + r""" + Return the slice of the vertex `v`. + + The slice of `v` is the list of vertices `u` such that the neighbors of + `u` that are before `v` in the lexBFS order are that same that the + neighbors of `v` that are before `v` in the lexBFS order (*i.e.*, the + lexicographic label of `v`). It can be shown that it is a factor of the + lexBFS order. + + INPUT: + + - ``v`` -- a vertex of the graph corresponding to the slice + decomposition. + + OUTPUT: + + A list of vertices + + EXAMPLES: + + :: + + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x') + sage: SD.slice('a') + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + + The vertices of the slice have the same neighborhood "on the left":: + + sage: pos = lambda v: SD.lexBFS_order().index(v) + sage: lla = set(SD.lexicographic_label('a')) + sage: all(lla == {u for u in G.neighbors(v) if pos(u) < pos('a')} \ + ....: for v in SD.slice('a')) + True + + The slice is a factor of the lexBFS order:: + + sage: ''.join(SD.slice('a')) in ''.join(SD.lexBFS_order()) + True + + The slice of the initial vertex is the whole graph:: + + sage: SD.slice('x') == SD.lexBFS_order() + True + + TESTS:: + + sage: SD.slice('Michael') + Traceback (most recent call last): + ... + LookupError: vertex (Michael) does not appear in the slice decomposition + """ + if v not in self.sigma_inv: + raise LookupError(f"vertex ({v}) does not appear in the slice " + "decomposition") + cdef size_t i = self.sigma_inv[v] + return self._slice(i) + + def xslice_sequence(self, v): + r""" + Return the x-slice sequence of the vertex `v`. + + INPUT: + + - ``v`` -- a vertex of the graph corresponding to the slice + decomposition. + + OUTPUT: + + A list of list corresponding to the x-slice sequence of ``v``. + + EXAMPLES: + + :: + + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x') + sage: SD.xslice_sequence('x') + [['x'], ['a', 'b', 'c', 'd', 'e', 'f', 'g'], ['u', 'y', 'z'], ['v', 'w']] + sage: SD.xslice_sequence('a') + [['a'], ['b', 'c', 'd', 'e', 'f'], ['g']] + + The flatten x-slice sequence of a vertex corresponds to the slice of the + same vertex:: + + sage: from itertools import chain + sage: all(list(chain(*SD.xslice_sequence(v))) == SD.slice(v) \ + ....: for v in G) + True + + The first list of the sequence is always a singleton containing the + input vertex:: + + sage: all(SD.xslice_sequence(v)[0] == [v] for v in G) + True + + If the length of the slice if more than 1, the second list of the + sequence is either, all the remaining vertices of the slice of `v`, if + `v` is isolated in the subgraph induced by the slice of `v`, or the + neighbors of `v` in the subgraph induced by the slice of `v`:: + + sage: all(SD.xslice_sequence(v)[1] == SD.slice(v)[1:] for v in G \ + ....: if G.subgraph(SD.slice(v)).degree(v) == 0 \ + ....: and len(SD.slice(v)) > 1) + True + sage: for v in G: + ....: if len(SD.slice(v)) > 1: + ....: xslice_seq = SD.xslice_sequence(v) + ....: S = G.subgraph(SD.slice(v)) + ....: if S.degree(v) > 0: + ....: set(xslice_seq[1]) == set(S.neighbor_iterator(v)) + True + True + True + True + + TESTS:: + + sage: SD = graphs.PetersenGraph().slice_decomposition() + sage: SD.xslice_sequence('Terry') + Traceback (most recent call last): + ... + LookupError: vertex (Terry) does not appear in the slice decomposition + """ + if v not in self.sigma_inv: + raise LookupError(f"vertex ({v}) does not appear in the slice " + "decomposition") + cdef size_t i = self.sigma_inv[v] + return self._xslice_sequence(i) + + def lexicographic_label(self, v): + r""" + Return the lexicographic label of the vertex `v`. + + The lexicographic label of a vertex `v` is the list of all the + neighbors of `v` that appear before `v` in the lexBFS ordering + corresponding to the slice decomposition. + + INPUT: + + - ``v`` -- a vertex of the graph corresponding to the slice + decomposition. + + OUTPUT: + + A list of vertices. + + EXAMPLES:: + + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x') + sage: SD.lexicographic_label('f') + ['x', 'a', 'c', 'd'] + sage: pos = lambda v: SD.lexBFS_order().index(v) + sage: set(SD.lexicographic_label('f')) \ + ....: == {v for v in G.neighbors('f') if pos(v) < pos('f')} + True + + TESTS:: + + sage: SD = graphs.PetersenGraph().slice_decomposition() + sage: SD.lexicographic_label('Eric') + Traceback (most recent call last): + ... + LookupError: vertex (Eric) does not appear in the slice decomposition + """ + if v not in self.sigma_inv: + raise LookupError(f"vertex ({v}) does not appear in the slice " + "decomposition") + cdef size_t i = self.sigma_inv[v] + return self._xslice_lex_label(i) + + def active_edges(self, v): + r""" + Return the active edges of the vertex `v`. + + An edge `(u, w)` is said to be active for `v` if `u` and `w` belongs + to two differents slices of the x-slice sequence of `v`. Note that it + defines a partition of the edges of the underlying graph. + + INPUT: + + - ``v`` -- a vertex of the graph corresponding to the slice + decomposition. + + OUTPUT: + + A list of edges + + EXAMPLES: + + :: + + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x') + sage: SD.xslice_sequence('a') + [['a'], ['b', 'c', 'd', 'e', 'f'], ['g']] + sage: ('c', 'g') in SD.active_edges('a') + True + sage: ('a', 'c') in SD.active_edges('a') + True + sage: ('c', 'd') in SD.active_edges('a') # c and d in same slice + False + sage: ('a', 'u') in SD.active_edges('a') # u not in x-slice of a + False + + The set of active edges of every vertex is a partition of the edges:: + + sage: from itertools import chain + sage: E = list(chain(*(SD.active_edges(v) for v in G))) + sage: G.size() == len(E) == len(set(E)) \ + ....: and all(G.has_edge(u, w) for v in G for u, w in SD.active_edges(v)) + True + + TESTS:: + + sage: SD = graphs.PetersenGraph().slice_decomposition() + sage: SD.active_edges('Graham') + Traceback (most recent call last): + ... + LookupError: vertex (Graham) does not appear in the slice decomposition + """ + if v not in self.sigma_inv: + raise LookupError(f"vertex ({v}) does not appear in the slice " + "decomposition") + cdef size_t i = self.sigma_inv[v] + return self._xslice_active_edges(i) + + def _slice(self, size_t idx): + r""" + This method is for internal use only + + TESTS: + + Indirect doctests:: + + sage: SD = graphs.HouseGraph().slice_decomposition() + sage: SD.slice(1) + [1, 2] + """ + return list(self.sigma[idx:idx+self.xslice_len[idx]]) + + def _xslice_sequence(self, size_t idx): + r""" + This method is for internal use only + + TESTS: + + Indirect doctests:: + + sage: SD = graphs.HouseGraph().slice_decomposition() + sage: SD.xslice_sequence(0) + [[0], [1, 2], [3], [4]] + """ + cdef size_t l = self.xslice_len[idx] + cdef size_t j = idx + 1 + cdef size_t lj + + S = [ [self.sigma[idx]] ] + while j < idx + l: + lj = self.xslice_len[j] + S.append(list(self.sigma[j:j+lj])) + j += lj + assert j == idx + l, "slice decomposition is ill-formed" + return S + + def _xslice_lex_label(self, size_t idx): + r""" + This method is for internal use only + + TESTS: + + Indirect doctests:: + + sage: SD = graphs.HouseGraph().slice_decomposition() + sage: SD.lexicographic_label(3) + [1, 2] + """ + return list(self.lex_label[idx]) + + def _xslice_active_edges(self, size_t idx): + r""" + This method is for internal use only + + TESTS: + + Indirect doctests:: + + sage: SD = graphs.HouseGraph().slice_decomposition() + sage: SD.active_edges(0) + [(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)] + """ + cdef size_t l = self.xslice_len[idx] + cdef size_t llv_prefix = len(self.lex_label[idx]) + cdef size_t j = idx + 1 + cdef size_t lj + + A = [] + while j < idx + l: + lj = self.xslice_len[j] + llj = self.lex_label[j] + for u in self.sigma[j:j+lj]: + for w in llj[llv_prefix:]: + A.append((w, u)) + j += lj + assert j == idx + l, "slice decomposition is ill-formed" + return A + + def underlying_graph(self): + r""" + Return the underlying graph corresponding to the slice decomposition. + + If `G` was the graph given as parameter to compute the slice + decomposition, the underlying graph corresponds to ``G.to_simple()`` + where labels are ignored, *i.e.*, it is the input graph without loops, + multiple edges and labels. + + .. NOTE:: + + This method is mostly defined to test the computation of + lexicographic labels and actives edges. + + EXAMPLES: + + :: + + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x') + sage: SD.underlying_graph() == G + True + + The graph can have loops or multiple edges but they are ignored:: + + sage: G = graphs.CubeConnectedCycle(2) # multiple edges + sage: SD = G.slice_decomposition() + sage: SD.underlying_graph() == G.to_simple(immutable=True) + True + + sage: G = graphs.CubeConnectedCycle(1) # loops + sage: SD = G.slice_decomposition() + sage: SD.underlying_graph() == G.to_simple(immutable=True) + True + + TESTS:: + + sage: for _ in range(5): + ....: G = graphs.RandomGNP(15, 0.3) + ....: SD = G.slice_decomposition() + ....: SD.underlying_graph() == G + True + True + True + True + True + """ + if not hasattr(self, '_underlying_graph'): + vertices = self.sigma + edges = [(u, v) for i, v in enumerate(self.sigma) + for u in self.lex_label[i]] + data = [vertices, edges] + Gclass = self._graph_class + self._underlying_graph = Gclass(data, format='vertices_and_edges', + immutable=True) + return self._underlying_graph + + def _repr_(self): + r""" + Return a string representation of a ``SliceDecomposition`` object. + + TESTS:: + + sage: G = graphs.PetersenGraph(); SD = G.slice_decomposition() + sage: repr(SD) + '[0[1[4[5]]] [2[6]] [3] [9] [7] [8]]' + sage: G = Graph('L~mpn~Nrv{^o~_').relabel('abcdefguvwxyz',inplace=False) + sage: SD = G.slice_decomposition(initial_vertex='x'); repr(SD) + '[x[a[b[c[d]] [e[f]]] [g]] [u[y[z]]] [v[w]]]' + """ + def inner_repr(idx): + l = self.xslice_len[idx] + S = [] + if l > 1: + j = idx + 1 + while j < idx + l: + lj = self.xslice_len[j] + S.append(inner_repr(j)) + j += lj + assert j == idx + l, "slice decomposition is ill-formed" + return f'{self.sigma[idx]}' + ' '.join(f'[{s}]' for s in S) + return f'[{inner_repr(0)}]' + + def _latex_(self): + r""" + Return a string to render, using `\LaTeX`, the slice decomposition as a + tree. + + TESTS:: + + sage: from sage.graphs.graph_latex import check_tkz_graph + sage: check_tkz_graph() # random - depends on Tex installation + sage: G = graphs.PetersenGraph(); SD = G.slice_decomposition() + sage: latex(SD) + \begin{tikzpicture} + ... + v0 -- {l0, v1, v4, v6, v7, v8, v9}; + v1 -- {l1, v2}; + v2 -- {l2, v3}; + v3 -- {l3}; + v4 -- {l4, v5}; + v5 -- {l5}; + v6 -- {l6}; + v7 -- {l7}; + v8 -- {l8}; + v9 -- {l9}; + ... + \end{tikzpicture} + + """ + from sage.misc.latex import latex + + latex.add_package_to_preamble_if_available("tikz") + latex.add_to_preamble(r"\usetikzlibrary{arrows,shapes,fit}") + latex.add_to_preamble(r"\usetikzlibrary{graphs,graphdrawing}") + latex.add_to_preamble(r"\usegdlibrary{trees}") + + # Call latex() on all vertices + sigma_latex = [ latex(v) for v in self.sigma ] + slices = [[] for _ in self.sigma] + + lines = [ r"\begin{tikzpicture}" ] + lines.append(r"\graph [tree layout,level distance=0,level sep=1em," + r"sibling distance=0,sibling sep=0.6em," + r"tail anchor=center,head anchor=north," + r"nodes={draw,rectangle,inner xsep=0.2em},edges={thick}]") + lines.append("{") + bo, bc = "{", "}" # to write { and } in f-strings + # Create the nodes and leaves of the slice decomposition tree + for i in range(len(self.sigma)): + l = self.xslice_len[i] + label = r"\ ".join(sigma_latex[i:i+l]) + lines.append(f" v{i}[as={bo}${label}${bc}];") + lines.append(f" l{i}[draw=none,as={bo}${sigma_latex[i]}${bc}];") + j = i + 1 + slices[i].append(f"l{i}") + while j < i + l: + slices[i].append(f"v{j}") + j += self.xslice_len[j] + # Create the edges of the slice decomposition tree + for i, S in enumerate(slices): + lines.append(f" v{i} -- " + "{" + ", ".join(S) + "};") + lines.append("};") + # Add dahsed red boxes around xslices + for i, S in enumerate(slices): + fit=" ".join(f"({s})" for s in S) + lines.append(rf"\node (s{i}) [rectangle,inner xsep=0.2em,draw=red," + f"densely dashed,fit={fit}]{bo}{bc};") + + lines.append(r"\end{tikzpicture}") + return "\n".join(lines) diff --git a/src/sage/graphs/graph_decompositions/tdlib.pyx b/src/sage/graphs/graph_decompositions/tdlib.pyx index 9940aa84883..847f6f49116 100644 --- a/src/sage/graphs/graph_decompositions/tdlib.pyx +++ b/src/sage/graphs/graph_decompositions/tdlib.pyx @@ -140,7 +140,6 @@ def treedecomposition_exact(G, lb=-1): sage: T = tdlib.treedecomposition_exact(G) sage: G = graphs.PetersenGraph() sage: T = tdlib.treedecomposition_exact(G) - """ cdef vector[unsigned int] V_G, E_G, E_T cdef vector[vector[int]] V_T @@ -172,9 +171,7 @@ def get_width(T): - ``T`` -- a tree decomposition - OUTPUT: - - - The width of ``T`` + OUTPUT: the width of ``T`` EXAMPLES:: diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 8382cb85cdf..8ed9ee9d224 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -450,14 +450,14 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals when ``k`` is not ``None`` or when ``algorithm == 'tdlib'``. - ``certificate`` -- boolean (default: ``False``); whether to return the - tree-decomposition itself. + tree-decomposition itself - - ``algorithm`` -- whether to use ``"sage"`` or ``"tdlib"`` (requires the + - ``algorithm`` -- whether to use ``'sage'`` or ``'tdlib'`` (requires the installation of the :ref:`spkg_sagemath_tdlib` package). The default behaviour is to use 'tdlib' if it is available, and Sage's own algorithm when it is not. - ``nice`` -- boolean (default: ``False``); whether or not to return the - nice tree decomposition, provided ``certificate`` is ``True``. + nice tree decomposition, provided ``certificate`` is ``True`` OUTPUT: @@ -826,9 +826,7 @@ def make_nice_tree_decomposition(graph, tree_decomp): - ``tree_decomp`` -- a tree decomposition - OUTPUT: - - A nice tree decomposition. + OUTPUT: a nice tree decomposition .. WARNING:: @@ -1081,9 +1079,7 @@ def label_nice_tree_decomposition(nice_TD, root, directed=False): tree decomposition as a directed graph rooted at vertex ``root`` or as an undirected graph - OUTPUT: - - A nice tree decomposition with nodes labelled. + OUTPUT: a nice tree decomposition with nodes labelled EXAMPLES:: @@ -1361,7 +1357,7 @@ cdef class TreelengthConnected: ... ValueError: the graph is not connected - The parameter `k` must be non-negative:: + The parameter `k` must be nonnegative:: sage: TreelengthConnected(Graph(1), k=-1) Traceback (most recent call last): @@ -1439,11 +1435,11 @@ cdef class TreelengthConnected: if self.n <= 1 or (self.k_is_defined and self.n <= k): if certificate: if self.n: - self.tree = Graph({Set(G): []}, format="dict_of_lists", name=self.name) + self.tree = Graph({Set(G): []}, format='dict_of_lists', name=self.name) else: self.tree = Graph(name=self.name) self.length = 0 if self.n <= 1 else G.diameter(algorithm='DHV') - self.leq_k = True # We know that k is non negative + self.leq_k = True # We know that k is nonnegative return if self.k_is_defined and not k: @@ -1453,7 +1449,7 @@ cdef class TreelengthConnected: if G.is_clique(): if certificate: - self.tree = Graph({Set(G): []}, format="dict_of_lists", name=self.name) + self.tree = Graph({Set(G): []}, format='dict_of_lists', name=self.name) self.length = 1 self.leq_k = True return @@ -1485,7 +1481,7 @@ cdef class TreelengthConnected: if self.k_is_defined and k >= self.diameter: # All vertices fit in one bag if certificate: - self.tree = Graph({Set(G): []}, format="dict_of_lists", name=self.name) + self.tree = Graph({Set(G): []}, format='dict_of_lists', name=self.name) self.length = self.diameter self.leq_k = True return @@ -1508,7 +1504,7 @@ cdef class TreelengthConnected: def __dealloc__(self): r""" - Destroy the object + Destroy the object. TESTS:: @@ -1650,7 +1646,7 @@ cdef class TreelengthConnected: from sage.graphs.graph import Graph T = Graph([(good_label(x), good_label(y)) for x, y in TD if x != y], - format="list_of_edges") + format='list_of_edges') self.tree = reduced_tree_decomposition(T) self.tree.name(self.name) return True @@ -1900,7 +1896,7 @@ def treelength(G, k=None, certificate=False): answer = 0 if k is None else True if certificate: if G: - answer = answer, Graph({Set(G): []}, format="dict_of_lists", name=name) + answer = answer, Graph({Set(G): []}, format='dict_of_lists', name=name) else: answer = answer, Graph(name=name) return answer @@ -1947,7 +1943,7 @@ def treelength(G, k=None, certificate=False): ga = G.subgraph(atom) if ga.is_clique(): if certificate: - result.append(Graph({Set(atom): []}, format="dict_of_lists")) + result.append(Graph({Set(atom): []}, format='dict_of_lists')) continue gc, certif = ga.canonical_label(certificate=True) diff --git a/src/sage/graphs/graph_decompositions/vertex_separation.pyx b/src/sage/graphs/graph_decompositions/vertex_separation.pyx index 2b45805348e..e83c05d2c0e 100644 --- a/src/sage/graphs/graph_decompositions/vertex_separation.pyx +++ b/src/sage/graphs/graph_decompositions/vertex_separation.pyx @@ -136,16 +136,16 @@ sets such that an ordering `v_1, ..., v_n` of the vertices correspond to **Variables:** -- `y_v^t` -- Variable set to 1 if `v\in S_t`, and 0 otherwise. The order of +- `y_v^t` -- variable set to 1 if `v\in S_t`, and 0 otherwise. The order of `v` in the layout is the smallest `t` such that `y_v^t==1`. -- `u_v^t` -- Variable set to 1 if `v\not \in S_t` and `v` has an in-neighbor in +- `u_v^t` -- variable set to 1 if `v\not \in S_t` and `v` has an in-neighbor in `S_t`. It is set to 0 otherwise. -- `x_v^t` -- Variable set to 1 if either `v\in S_t` or if `v` has an in-neighbor +- `x_v^t` -- variable set to 1 if either `v\in S_t` or if `v` has an in-neighbor in `S_t`. It is set to 0 otherwise. -- `z` -- Objective value to minimize. It is equal to the maximum over all step +- `z` -- objective value to minimize. It is equal to the maximum over all step `t` of the number of vertices such that `u_v^t==1`. **MILP formulation:** @@ -294,7 +294,6 @@ def lower_bound(G): This method runs in exponential time but has no memory constraint. - EXAMPLES: On a circuit:: @@ -321,7 +320,6 @@ def lower_bound(G): Traceback (most recent call last): ... ValueError: the (di)graph can have at most 31 vertices - """ from sage.graphs.graph import Graph from sage.graphs.digraph import DiGraph @@ -369,7 +367,7 @@ def lower_bound(G): def linear_ordering_to_path_decomposition(G, L): """ - Return the path decomposition encoded in the ordering L + Return the path decomposition encoded in the ordering L. INPUT: @@ -377,9 +375,7 @@ def linear_ordering_to_path_decomposition(G, L): - ``L`` -- a linear ordering for G - OUTPUT: - - A path graph whose vertices are the bags of the path decomposition. + OUTPUT: a path graph whose vertices are the bags of the path decomposition EXAMPLES: @@ -471,10 +467,10 @@ def linear_ordering_to_path_decomposition(G, L): # Front end methods for path decomposition and vertex separation # ################################################################## -def pathwidth(self, k=None, certificate=False, algorithm="BAB", verbose=False, +def pathwidth(self, k=None, certificate=False, algorithm='BAB', verbose=False, max_prefix_length=20, max_prefix_number=10**6, *, solver=None): r""" - Compute the pathwidth of ``self`` (and provides a decomposition) + Compute the pathwidth of ``self`` (and provides a decomposition). INPUT: @@ -486,19 +482,19 @@ def pathwidth(self, k=None, certificate=False, algorithm="BAB", verbose=False, - ``certificate`` -- boolean (default: ``False``); whether to return the path-decomposition itself - - ``algorithm`` -- string (default: ``"BAB"``); algorithm to use among: + - ``algorithm`` -- string (default: ``'BAB'``); algorithm to use among: - - ``"BAB"`` -- Use a branch-and-bound algorithm. This algorithm has no + - ``'BAB'`` -- use a branch-and-bound algorithm. This algorithm has no size restriction but could take a very long time on large graphs. It can also be used to test is the input graph has pathwidth `\leq k`, in which cas it will return the first found solution with width `\leq k` is ``certificate==True``. - - ``exponential`` -- Use an exponential time and space algorithm. This - algorithm only works of graphs on less than 32 vertices. + - ``exponential`` -- use an exponential time and space algorithm. This + algorithm only works of graphs on less than 32 vertices - - ``MILP`` -- Use a mixed integer linear programming formulation. This - algorithm has no size restriction but could take a very long time. + - ``MILP`` -- use a mixed integer linear programming formulation. This + algorithm has no size restriction but could take a very long time - ``verbose`` -- boolean (default: ``False``); whether to display information on the computations @@ -511,7 +507,7 @@ def pathwidth(self, k=None, certificate=False, algorithm="BAB", verbose=False, number of stored prefixes used to prevent using too much memory. This parameter is used only when ``algorithm=="BAB"``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -568,7 +564,7 @@ def pathwidth(self, k=None, certificate=False, algorithm="BAB", verbose=False, Given a wrong algorithm:: sage: from sage.graphs.graph_decompositions.vertex_separation import pathwidth - sage: pathwidth(Graph(), algorithm="SuperFast") + sage: pathwidth(Graph(), algorithm='SuperFast') Traceback (most recent call last): ... ValueError: algorithm "SuperFast" has not been implemented yet, please contribute @@ -597,7 +593,7 @@ def pathwidth(self, k=None, certificate=False, algorithm="BAB", verbose=False, return (pw <= k, linear_ordering_to_path_decomposition(self, L)) if certificate else pw <= k -def path_decomposition(G, algorithm="BAB", cut_off=None, upper_bound=None, verbose=False, +def path_decomposition(G, algorithm='BAB', cut_off=None, upper_bound=None, verbose=False, max_prefix_length=20, max_prefix_number=10**6): r""" Return the pathwidth of the given graph and the ordering of the vertices @@ -607,28 +603,28 @@ def path_decomposition(G, algorithm="BAB", cut_off=None, upper_bound=None, verbo - ``G`` -- a Graph - - ``algorithm`` -- string (default: ``"BAB"``); algorithm to use among: + - ``algorithm`` -- string (default: ``'BAB'``); algorithm to use among: - - ``"BAB"`` -- Use a branch-and-bound algorithm. This algorithm has no + - ``'BAB'`` -- use a branch-and-bound algorithm. This algorithm has no size restriction but could take a very long time on large graphs. It can also be used to test is the input (di)graph has vertex separation at most ``upper_bound`` or to return the first found solution with vertex separation less or equal to a ``cut_off`` value. - - ``exponential`` -- Use an exponential time and space algorithm. This - algorithm only works of graphs on less than 32 vertices. + - ``exponential`` -- use an exponential time and space algorithm. This + algorithm only works of graphs on less than 32 vertices - - ``MILP`` -- Use a mixed integer linear programming formulation. This - algorithm has no size restriction but could take a very long time. + - ``MILP`` -- use a mixed integer linear programming formulation. This + algorithm has no size restriction but could take a very long time - ``upper_bound`` -- integer (default: ``None``); parameter used by the - ``"BAB"`` algorithm. If specified, the algorithm searches for a solution + ``'BAB'`` algorithm. If specified, the algorithm searches for a solution with ``width < upper_bound``. It helps cutting branches. However, if the given upper bound is too low, the algorithm may not be able to find a solution. - ``cut_off`` -- integer (default: ``None``); parameter used by the - ``"BAB"`` algorithm. This bound allows us to stop the search as soon as a + ``'BAB'`` algorithm. This bound allows us to stop the search as soon as a solution with width at most ``cut_off`` is found, if any. If this bound cannot be reached, the best solution found is returned, unless a too low ``upper_bound`` is given. @@ -659,11 +655,11 @@ def path_decomposition(G, algorithm="BAB", cut_off=None, upper_bound=None, verbo sage: from sage.graphs.graph_decompositions.vertex_separation import path_decomposition sage: g = graphs.CycleGraph(6) - sage: pw, L = path_decomposition(g, algorithm="BAB"); pw + sage: pw, L = path_decomposition(g, algorithm='BAB'); pw 2 - sage: pw, L = path_decomposition(g, algorithm="exponential"); pw + sage: pw, L = path_decomposition(g, algorithm='exponential'); pw 2 - sage: pw, L = path_decomposition(g, algorithm="MILP"); pw # needs sage.numerical.mip + sage: pw, L = path_decomposition(g, algorithm='MILP'); pw # needs sage.numerical.mip 2 TESTS: @@ -679,11 +675,10 @@ def path_decomposition(G, algorithm="BAB", cut_off=None, upper_bound=None, verbo Given a wrong algorithm:: sage: from sage.graphs.graph_decompositions.vertex_separation import path_decomposition - sage: path_decomposition(Graph(), algorithm="SuperFast") + sage: path_decomposition(Graph(), algorithm='SuperFast') Traceback (most recent call last): ... ValueError: algorithm "SuperFast" has not been implemented yet, please contribute - """ from sage.graphs.graph import Graph if not isinstance(G, Graph): @@ -694,7 +689,7 @@ def path_decomposition(G, algorithm="BAB", cut_off=None, upper_bound=None, verbo max_prefix_number=max_prefix_number) -def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbose=False, +def vertex_separation(G, algorithm='BAB', cut_off=None, upper_bound=None, verbose=False, max_prefix_length=20, max_prefix_number=10**6, *, solver=None, integrality_tolerance=1e-3): r""" @@ -705,28 +700,28 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos - ``G`` -- a Graph or a DiGraph - - ``algorithm`` -- string (default: ``"BAB"``); algorithm to use among: + - ``algorithm`` -- string (default: ``'BAB'``); algorithm to use among: - - ``"BAB"`` -- Use a branch-and-bound algorithm. This algorithm has no + - ``'BAB'`` -- use a branch-and-bound algorithm. This algorithm has no size restriction but could take a very long time on large graphs. It can also be used to test is the input (di)graph has vertex separation at most ``upper_bound`` or to return the first found solution with vertex separation less or equal to a ``cut_off`` value. - - ``exponential`` -- Use an exponential time and space algorithm. This - algorithm only works of graphs on less than 32 vertices. + - ``exponential`` -- use an exponential time and space algorithm. This + algorithm only works of graphs on less than 32 vertices - - ``MILP`` -- Use a mixed integer linear programming formulation. This - algorithm has no size restriction but could take a very long time. + - ``MILP`` -- use a mixed integer linear programming formulation. This + algorithm has no size restriction but could take a very long time - ``upper_bound`` -- integer (default: ``None``); parameter used by the - ``"BAB"`` algorithm. If specified, the algorithm searches for a solution + ``'BAB'`` algorithm. If specified, the algorithm searches for a solution with ``width < upper_bound``. It helps cutting branches. However, if the given upper bound is too low, the algorithm may not be able to find a solution. - ``cut_off`` -- integer (default: ``None``); parameter used by the - ``"BAB"`` algorithm. This bound allows us to stop the search as soon as a + ``'BAB'`` algorithm. This bound allows us to stop the search as soon as a solution with width at most ``cut_off`` is found, if any. If this bound cannot be reached, the best solution found is returned, unless a too low ``upper_bound`` is given. @@ -742,7 +737,7 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos number of stored prefixes used to prevent using too much memory. This parameter is used only when ``algorithm=="BAB"``. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -767,19 +762,19 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos sage: # needs sage.combinat sage: G = digraphs.DeBruijn(2,3) - sage: vs,L = vertex_separation(G, algorithm="BAB"); vs + sage: vs,L = vertex_separation(G, algorithm='BAB'); vs 2 - sage: vs,L = vertex_separation(G, algorithm="exponential"); vs + sage: vs,L = vertex_separation(G, algorithm='exponential'); vs 2 - sage: vs,L = vertex_separation(G, algorithm="MILP"); vs # needs sage.numerical.mip + sage: vs,L = vertex_separation(G, algorithm='MILP'); vs # needs sage.numerical.mip 2 sage: G = graphs.Grid2dGraph(3,3) - sage: vs,L = vertex_separation(G, algorithm="BAB"); vs + sage: vs,L = vertex_separation(G, algorithm='BAB'); vs 3 - sage: vs,L = vertex_separation(G, algorithm="exponential"); vs + sage: vs,L = vertex_separation(G, algorithm='exponential'); vs 3 - sage: vs,L = vertex_separation(G, algorithm="MILP"); vs # needs sage.numerical.mip + sage: vs,L = vertex_separation(G, algorithm='MILP'); vs # needs sage.numerical.mip 3 Digraphs with multiple strongly connected components:: @@ -806,7 +801,7 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation sage: G = graphs.PetersenGraph() - sage: vs, L = vertex_separation(G, algorithm="MILP", solver="SCIP"); vs # optional - pyscipopt, needs sage.numerical.mip + sage: vs, L = vertex_separation(G, algorithm='MILP', solver='SCIP'); vs # optional - pyscipopt, needs sage.numerical.mip 5 TESTS: @@ -814,7 +809,7 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos Given a wrong algorithm:: sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation - sage: vertex_separation(Graph(), algorithm="SuperFast") + sage: vertex_separation(Graph(), algorithm='SuperFast') Traceback (most recent call last): ... ValueError: algorithm "SuperFast" has not been implemented yet, please contribute @@ -885,7 +880,7 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos L.extend(LH) # We also update the cut_off parameter that could speed up - # resolution for other components (used when algorithm=="BAB") + # resolution for other components (used when algorithm=='BAB') cut_off = max(cut_off, vs) return vs, L @@ -1110,17 +1105,15 @@ def is_valid_ordering(G, L): INPUT: - - ``G`` -- a Graph or a DiGraph. - - - ``L`` -- an ordered list of the vertices of ``G``. + - ``G`` -- a Graph or a DiGraph + - ``L`` -- an ordered list of the vertices of ``G`` OUTPUT: Returns ``True`` if `L` is a valid vertex ordering for `G`, and ``False`` otherwise. - EXAMPLES: Path decomposition of a cycle:: @@ -1290,7 +1283,7 @@ def _vertex_separation_MILP_formulation(G, integrality=False, solver=None): no impact on the validity of the solution, but it is sometimes faster to solve the problem using binary variables only. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1298,9 +1291,7 @@ def _vertex_separation_MILP_formulation(G, integrality=False, solver=None): :class:`MixedIntegerLinearProgram `. - OUTPUT: - - - the :class:`~sage.numerical.mip.MixedIntegerLinearProgram` + OUTPUT: the :class:`~sage.numerical.mip.MixedIntegerLinearProgram` - :class:`sage.numerical.mip.MIPVariable` objects ``x``, ``u``, ``y``, ``z``. @@ -1396,7 +1387,7 @@ def vertex_separation_MILP(G, integrality=False, solver=None, verbose=0, no impact on the validity of the solution, but it is sometimes faster to solve the problem using binary variables only. - - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method :meth:`solve @@ -1404,7 +1395,7 @@ def vertex_separation_MILP(G, integrality=False, solver=None, verbose=0, :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- float; parameter for use with MILP solvers @@ -1517,7 +1508,7 @@ def vertex_separation_BAB(G, INPUT: - - ``G`` -- a Graph or a DiGraph. + - ``G`` -- a Graph or a DiGraph - ``cut_off`` -- integer (default: ``None``); bound to consider in the branch and bound algorithm. This allows us to stop the search as soon as a @@ -1539,9 +1530,7 @@ def vertex_separation_BAB(G, - ``verbose`` -- boolean (default: ``False``); display some information when set to ``True`` - OUTPUT: - - - ``width`` -- the computed vertex separation + OUTPUT: ``width`` -- the computed vertex separation - ``seq`` -- an ordering of the vertices of width ``width`` diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 2d6841eb719..812a16e8b4d 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -114,6 +114,7 @@ def wrap_name(x): "cocliques_HoffmannSingleton", "ConwaySmith_for_3S7", "CoxeterGraph", + "CubeplexGraph", "DesarguesGraph", "DejterGraph", "distance_3_doubly_truncated_Golay_code_graph", @@ -173,6 +174,7 @@ def wrap_name(x): "MeredithGraph", "MoebiusKantorGraph", "MoserSpindle", + "MurtyGraph", "NauruGraph", "PappusGraph", "PoussinGraph", @@ -189,12 +191,14 @@ def wrap_name(x): "SzekeresSnarkGraph", "ThomsenGraph", "TietzeGraph", + "TricornGraph", "TruncatedIcosidodecahedralGraph", "TruncatedTetrahedralGraph", "TruncatedWittGraph", "Tutte12Cage", "TutteCoxeterGraph", "TutteGraph", + "TwinplexGraph", "U42Graph216", "U42Graph540", "WagnerGraph", @@ -229,6 +233,7 @@ def wrap_name(x): "BalancedTree", "BarbellGraph", "BilinearFormsGraph", + "BiwheelGraph", "BubbleSortGraph", "CaiFurerImmermanGraph", "chang_graphs", @@ -286,8 +291,10 @@ def wrap_name(x): "SierpinskiGasketGraph", "SquaredSkewHadamardMatrixGraph", "SwitchedSquaredSkewHadamardMatrixGraph", + "StaircaseGraph", "strongly_regular_graph", "trees", + "TruncatedBiwheelGraph", "nauty_gentreeg", "triangulations", "TuranGraph", @@ -367,6 +374,7 @@ def wrap_name(x): "RandomPartialKTree", "RandomLobster", "RandomNewmanWattsStrogatz", + "RandomProperIntervalGraph", "RandomRegular", "RandomShell", "RandomToleranceGraph", @@ -458,6 +466,9 @@ def wrap_name(x): - Janmenjaya Panda (2024-05-26): added MoebiusLadderGraph +- Janmenjaya Panda (2024-06-09): added StaircaseGraph, BiwheelGraph and + TruncatedBiwheelGraph + Functions and methods --------------------- @@ -514,7 +525,7 @@ class GraphGenerators: INPUT: - ``vertices`` -- a natural number or ``None`` to infinitely generate - bigger and bigger graphs. + bigger and bigger graphs - ``property`` -- (default: ``lambda x: True``) any property to be tested on graphs before generation, but note that in general the @@ -549,20 +560,20 @@ class GraphGenerators: not hold, then all the graphs generated will satisfy the property, but there will be some missing. - - ``size`` -- (default: ``None``) the size of the graph to be generated. + - ``size`` -- (default: ``None``) the size of the graph to be generated - - ``degree_sequence`` -- (default: ``None``) a sequence of non-negative integers, + - ``degree_sequence`` -- (default: ``None``) a sequence of nonnegative integers, or ``None``. If specified, the generated graphs will have these integers for degrees. In this case, property and size are both ignored. - - ``loops`` -- (default: ``False``) whether to allow loops in the graph - or not. + - ``loops`` -- boolean (default: ``False``); whether to allow loops in the graph + or not - - ``sparse`` -- (default: ``True``); whether to use a sparse or dense data + - ``sparse`` -- (default: ``True``) whether to use a sparse or dense data structure. See the documentation of :class:`~sage.graphs.graph.Graph`. - - ``copy`` (boolean) -- If set to ``True`` (default) + - ``copy`` -- boolean; if set to ``True`` (default) this method makes copies of the graphs before returning them. If set to ``False`` the method returns the graph it is working on. The second alternative is faster, but modifying @@ -738,7 +749,7 @@ class GraphGenerators: def __call__(self, vertices=None, property=None, augment='edges', size=None, degree_sequence=None, loops=False, sparse=True, copy=True): """ - Accesses the generator of isomorphism class representatives. + Access the generator of isomorphism class representatives. Iterates over distinct, exhaustive representatives. See the docstring of this class for full documentation. @@ -855,13 +866,13 @@ def extra_property(x): else: raise NotImplementedError - def nauty_geng(self, options="", debug=False): + def nauty_geng(self, options='', debug=False): r""" Return a generator which creates graphs from nauty's geng program. INPUT: - - ``options`` -- string (default: ``""``); a string passed to ``geng`` + - ``options`` -- string (default: ``''``); a string passed to ``geng`` as if it was run at a system command line. At a minimum, you *must* pass the number of vertices you desire. Sage expects the graphs to be in nauty's "graph6" format, do not set an option to change this @@ -998,14 +1009,14 @@ def nauty_geng(self, options="", debug=False): G = graph.Graph(s[:-1], format='graph6') yield G - def nauty_genbg(self, options="", debug=False): + def nauty_genbg(self, options='', debug=False): r""" - Return a generator which creates bipartite graphs from nauty's ``genbg`` + Return a generator which creates bipartite graphs from nauty's ``genbgL`` program. INPUT: - - ``options`` -- string (default: ``""``); a string passed to ``genbg`` + - ``options`` -- string (default: ``""``); a string passed to ``genbgL`` as if it was run at a system command line. At a minimum, you *must* pass the number of vertices you desire in each side. Sage expects the bipartite graphs to be in nauty's "graph6" format, do not set an @@ -1018,12 +1029,12 @@ def nauty_genbg(self, options="", debug=False): the program with some information on the arguments, while a line beginning with ">E" indicates an error with the input. - The possible options, obtained as output of ``genbg --help``:: + The possible options, obtained as output of ``genbgL --help``:: n1 : the number of vertices in the first class. - We must have n1=1..24. + We must have n1=1..30. n2 : the number of vertices in the second class. - We must have n2=0..32 and n1+n2=1..32. + We must have n2=0..64 and n1+n2=1..64. mine:maxe : : a range for the number of edges :0 means ' or more' except in the case 0:0 res/mod : only generate subset res out of subsets 0..mod-1 @@ -1051,8 +1062,8 @@ def nauty_genbg(self, options="", debug=False): -v : display counts by number of edges to stderr -l : canonically label output graphs - Options which cause ``genbg`` to use an output format different than the - ``graph6`` format are not listed above (``-s``, ``-a``) as they will + Options which cause ``genbgL`` to use an output format different than + the ``graph6`` format are not listed above (``-s``, ``-a``) as they will confuse the creation of a Sage graph. Option ``-q`` which suppress auxiliary output (except from ``-v``) should never be used as we are unable to recover the partition of the vertices of the bipartite graph @@ -1106,16 +1117,16 @@ def nauty_genbg(self, options="", debug=False): sage: len(list(gen)) 17 - The ``debug`` switch can be used to examine ``genbg``'s reaction to the + The ``debug`` switch can be used to examine ``genbgL``'s reaction to the input in the ``options`` string. A message starting with ">A" indicates success and a message starting with ">E" indicates a failure:: sage: gen = graphs.nauty_genbg("2 3", debug=True) sage: print(next(gen)) - >A ...genbg n=2+3 e=0:6 d=0:0 D=3:2 + >A ...genbg... n=2+3 e=0:6 d=0:0 D=3:2 sage: gen = graphs.nauty_genbg("-c2 3", debug=True) sage: next(gen) - '>E Usage: ...genbg [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... + '>E Usage: ...genbg... [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... Check that the partition of the bipartite graph is consistent:: @@ -1134,34 +1145,35 @@ def nauty_genbg(self, options="", debug=False): ... ValueError: wrong format of parameter options sage: list(graphs.nauty_genbg("-c1 2", debug=True)) - ['>E Usage: ...genbg [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... + ['>E Usage: ...genbg... [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... sage: list(graphs.nauty_genbg("-c 1 2", debug=True)) - ['>A ...genbg n=1+2 e=2:2 d=1:1 D=2:1 c...\n', Bipartite graph on 3 vertices] + ['>A ...genbg... n=1+2 e=2:2 d=1:1 D=2:1 c...\n', Bipartite graph on 3 vertices] - We must have n1=1..24, n2=0..32 and n1+n2=1..32 (:issue:`34179`):: + We must have n1=1..30, n2=0..64 and n1+n2=1..64 (:issue:`34179`, + :issue:`38618`):: - sage: next(graphs.nauty_genbg("25 1", debug=False)) + sage: next(graphs.nauty_genbg("31 1", debug=False)) Traceback (most recent call last): ... ValueError: wrong format of parameter options - sage: next(graphs.nauty_genbg("25 1", debug=True)) - '>E ...genbg: must have n1=1..24, n1+n2=1..32... - sage: next(graphs.nauty_genbg("24 9", debug=True)) - '>E ...genbg: must have n1=1..24, n1+n2=1..32... - sage: next(graphs.nauty_genbg("1 31", debug=False)) - Bipartite graph on 32 vertices - sage: next(graphs.nauty_genbg("1 32", debug=True)) - '>E ...genbg: must have n1=1..24, n1+n2=1..32... - sage: next(graphs.nauty_genbg("0 32", debug=True)) - '>E ...genbg: must have n1=1..24, n1+n2=1..32... + sage: next(graphs.nauty_genbg("31 1", debug=True)) + '>E ...genbg...: must have n1=1..30, n1+n2=1..64... + sage: next(graphs.nauty_genbg("30 40", debug=True)) + '>E ...genbg...: must have n1=1..30, n1+n2=1..64... + sage: next(graphs.nauty_genbg("1 63", debug=False)) + Bipartite graph on 64 vertices + sage: next(graphs.nauty_genbg("1 64", debug=True)) + '>E ...genbg...: must have n1=1..30, n1+n2=1..64... + sage: next(graphs.nauty_genbg("0 2", debug=True)) + '>E ...genbg...: must have n1=1..30, n1+n2=1..64... sage: next(graphs.nauty_genbg("2 0", debug=False)) Bipartite graph on 2 vertices sage: next(graphs.nauty_genbg("2 -1", debug=True)) - '>E Usage: ...genbg [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... + '>E Usage: ...genbg... [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... """ import shlex from sage.features.nauty import NautyExecutable - genbg_path = NautyExecutable("genbg").absolute_filename() + genbg_path = NautyExecutable("genbgL").absolute_filename() sp = subprocess.Popen(shlex.quote(genbg_path) + " {0}".format(options), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, @@ -1193,12 +1205,12 @@ def nauty_genbg(self, options="", debug=False): try: s = next(gen) except StopIteration: - # Exhausted list of bipartite graphs from nauty genbg + # Exhausted list of bipartite graphs from nauty genbgL return G = BipartiteGraph(s[:-1], format='graph6', partition=partition) yield G - def nauty_genktreeg(self, options="", debug=False): + def nauty_genktreeg(self, options='', debug=False): r""" Return a generator which creates all `k`-trees using nauty.. @@ -1321,15 +1333,15 @@ def cospectral_graphs(self, vertices, matrix_function=None, graphs=None): INPUT: - - ``vertices`` -- The number of vertices in the graphs to be tested + - ``vertices`` -- the number of vertices in the graphs to be tested - - ``matrix_function`` -- A function taking a graph and giving back + - ``matrix_function`` -- a function taking a graph and giving back a matrix. This defaults to the adjacency matrix. The spectra examined are the spectra of these matrices. - - ``graphs`` -- One of three things: + - ``graphs`` -- one of three things: - - ``None`` (default) -- test all graphs having ``vertices`` + - ``None`` -- default; test all graphs having ``vertices`` vertices - a function taking a graph and returning ``True`` or ``False`` @@ -1435,7 +1447,7 @@ def cospectral_graphs(self, vertices, matrix_function=None, graphs=None): def _read_planar_code(self, code_input): r""" - Returns a generator for the plane graphs in planar code format in + Return a generator for the plane graphs in planar code format in the file code_input (see [BM2016]_). A file with planar code starts with a header ``>>planar_code<<``. @@ -1450,7 +1462,7 @@ def _read_planar_code(self, code_input): INPUT: - - ``code_input`` -- a file containing valid planar code data. + - ``code_input`` -- a file containing valid planar code data OUTPUT: @@ -1542,15 +1554,15 @@ def _read_planar_code(self, code_input): def fullerenes(self, order, ipr=False): r""" - Returns a generator which creates fullerene graphs using + Return a generator which creates fullerene graphs using the buckygen generator (see [BGM2012]_). INPUT: - - ``order`` -- a positive even integer smaller than or equal to 254. - This specifies the number of vertices in the generated fullerenes. + - ``order`` -- a positive even integer smaller than or equal to 254 + This specifies the number of vertices in the generated fullerenes - - ``ipr`` -- (default: ``False``); if ``True`` only fullerenes that + - ``ipr`` -- (default: ``False``) if ``True`` only fullerenes that satisfy the Isolated Pentagon Rule are generated. This means that no pentagonal faces share an edge. @@ -1620,7 +1632,7 @@ def fullerenes(self, order, ipr=False): """ # number of vertices should be positive if order < 0: - raise ValueError("number of vertices should be non-negative") + raise ValueError("number of vertices should be nonnegative") # buckygen can only output fullerenes on up to 254 vertices if order > 254: @@ -1649,18 +1661,18 @@ def fullerenes(self, order, ipr=False): def fusenes(self, hexagon_count, benzenoids=False): r""" - Returns a generator which creates fusenes and benzenoids using + Return a generator which creates fusenes and benzenoids using the benzene generator (see [BCH2002]_). Fusenes are planar polycyclic hydrocarbons with all bounded faces hexagons. Benzenoids are fusenes that are subgraphs of the hexagonal lattice. INPUT: - - ``hexagon_count`` -- a positive integer smaller than or equal to 30. - This specifies the number of hexagons in the generated benzenoids. + - ``hexagon_count`` -- positive integer smaller than or equal to 30; + this specifies the number of hexagons in the generated benzenoids - - ``benzenoids`` -- (default: ``False``); if ``True`` only benzenoids are - generated. + - ``benzenoids`` -- (default: ``False``) if ``True`` only benzenoids are + generated OUTPUT: @@ -1701,7 +1713,7 @@ def fusenes(self, hexagon_count, benzenoids=False): 6505 """ if hexagon_count < 0: - raise ValueError("number of hexagons should be non-negative") + raise ValueError("number of hexagons should be nonnegative") # benzene is only built for fusenes with up to 30 hexagons if hexagon_count > 30: @@ -1945,24 +1957,24 @@ def planar_graphs(self, order, minimum_degree=None, INPUT: - - ``order`` -- a positive integer smaller than or equal to 64. - This specifies the number of vertices in the generated graphs. + - ``order`` -- positive integer smaller than or equal to 64; + this specifies the number of vertices in the generated graphs - - ``minimum_degree`` -- (default: ``None``); a value `\geq 1` and `\leq + - ``minimum_degree`` -- (default: ``None``) a value `\geq 1` and `\leq 5`, or ``None``. This specifies the minimum degree of the generated graphs. If this is ``None`` and the order is 1, then this is set to 0. If this is ``None`` and the minimum connectivity is specified, then this is set to the same value as the minimum connectivity. If the minimum connectivity is also equal to ``None``, then this is set to 1. - - ``minimum_connectivity`` -- (default: ``None``); a value `\geq 1` + - ``minimum_connectivity`` -- (default: ``None``) a value `\geq 1` and `\leq 3`, or ``None``. This specifies the minimum connectivity of the generated graphs. If this is ``None`` and the minimum degree is specified, then this is set to the minimum of the minimum degree and 3. If the minimum degree is also equal to ``None``, then this is set to 1. - - ``exact_connectivity`` -- (default: ``False``); if ``True`` only + - ``exact_connectivity`` -- (default: ``False``) if ``True`` only graphs with exactly the specified connectivity will be generated. This option cannot be used with ``minimum_connectivity=3``, or if the minimum connectivity is not explicitly set. @@ -1976,12 +1988,12 @@ def planar_graphs(self, order, minimum_degree=None, - ``maximum_face_size`` -- integer (default: ``None``); upper bound on the size of a face and so on the maximum degree of the dual graph - - ``only_bipartite`` -- (default: ``False``); if ``True`` only bipartite + - ``only_bipartite`` -- (default: ``False``) if ``True`` only bipartite graphs will be generated. This option cannot be used for graphs with a minimum degree larger than 3. - - ``dual`` -- (default: ``False``); if ``True`` return instead the - planar duals of the generated graphs. + - ``dual`` -- (default: ``False``) if ``True`` return instead the + planar duals of the generated graphs OUTPUT: @@ -2072,7 +2084,7 @@ def planar_graphs(self, order, minimum_degree=None, True """ if order < 0: - raise ValueError("number of vertices should be non-negative") + raise ValueError("number of vertices should be nonnegative") # plantri can only output general planar graphs on up to 64 vertices if order > 64: @@ -2174,34 +2186,34 @@ def triangulations(self, order, minimum_degree=None, minimum_connectivity=None, INPUT: - - ``order`` -- a positive integer smaller than or equal to 64. - This specifies the number of vertices in the generated triangulations. + - ``order`` -- positive integer smaller than or equal to 64; + this specifies the number of vertices in the generated triangulations - - ``minimum_degree`` -- (default: ``None``); a value `\geq 3` and `\leq 5`, + - ``minimum_degree`` -- (default: ``None``) a value `\geq 3` and `\leq 5`, or ``None``. This specifies the minimum degree of the generated triangulations. If this is ``None`` and the minimum connectivity is specified, then this is set to the same value as the minimum connectivity. If the minimum connectivity is also equal to ``None``, then this is set to 3. - - ``minimum_connectivity`` -- (default: ``None``); a value `\geq 3` and + - ``minimum_connectivity`` -- (default: ``None``) a value `\geq 3` and `\leq 5`, or ``None``. This specifies the minimum connectivity of the generated triangulations. If this is ``None`` and the minimum degree is specified, then this is set to the minimum of the minimum degree and 3. If the minimum degree is also equal to ``None``, then this is set to 3. - - ``exact_connectivity`` -- (default: ``False``); if ``True`` only + - ``exact_connectivity`` -- (default: ``False``) if ``True`` only triangulations with exactly the specified connectivity will be generated. This option cannot be used with ``minimum_connectivity=3``, or if the minimum connectivity is not explicitly set. - - ``only_eulerian`` -- (default: ``False``); if ``True`` only Eulerian + - ``only_eulerian`` -- (default: ``False``) if ``True`` only Eulerian triangulations will be generated. This option cannot be used if the minimum degree is explicitly set to anything else than 4. - - ``dual`` -- (default: ``False``); if ``True`` return instead the - planar duals of the generated graphs. + - ``dual`` -- (default: ``False``) if ``True`` return instead the + planar duals of the generated graphs OUTPUT: @@ -2296,7 +2308,7 @@ def triangulations(self, order, minimum_degree=None, minimum_connectivity=None, [12, 12] """ if order < 0: - raise ValueError("number of vertices should be non-negative") + raise ValueError("number of vertices should be nonnegative") # plantri can only output planar triangulations on up to 64 vertices if order > 64: @@ -2360,17 +2372,17 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None INPUT: - - ``order`` -- a positive integer smaller than or equal to 64. - This specifies the number of vertices in the generated quadrangulations. + - ``order`` -- positive integer smaller than or equal to 64; + this specifies the number of vertices in the generated quadrangulations - - ``minimum_degree`` -- default: ``None``; a value `\geq 2` and `\leq + - ``minimum_degree`` -- (default: ``None``) a value `\geq 2` and `\leq 3`, or ``None``. This specifies the minimum degree of the generated quadrangulations. If this is ``None`` and the minimum connectivity is specified, then this is set to the same value as the minimum connectivity. If the minimum connectivity is also equal to ``None``, then this is set to 2. - - ``minimum_connectivity`` -- default: ``None``; a value `\geq 2` and + - ``minimum_connectivity`` -- (default: ``None``) a value `\geq 2` and `\leq 3`, or ``None``. This specifies the minimum connectivity of the generated quadrangulations. If this is ``None`` and the option ``no_nonfacial_quadrangles`` is set to ``True``, then this is set to @@ -2378,12 +2390,12 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None then this is set to the minimum degree. If the minimum degree is also equal to ``None``, then this is set to 3. - - ``no_nonfacial_quadrangles`` -- default: ``False``; if ``True`` only + - ``no_nonfacial_quadrangles`` -- (default: ``False``) if ``True`` only quadrangulations with no non-facial quadrangles are generated. This option cannot be used if ``minimum_connectivity`` is set to 2. - - ``dual`` -- default: ``False``; if ``True`` return instead the - planar duals of the generated graphs. + - ``dual`` -- (default: ``False``) if ``True`` return instead the + planar duals of the generated graphs OUTPUT: @@ -2439,7 +2451,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None [10, 10] """ if order < 0: - raise ValueError("number of vertices should be non-negative") + raise ValueError("number of vertices should be nonnegative") # plantri can only output planar quadrangulations on up to 64 vertices if order > 64: @@ -2535,6 +2547,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None cocliques_HoffmannSingleton = staticmethod(distance_regular.cocliques_HoffmannSingleton) ConwaySmith_for_3S7 = staticmethod(distance_regular.ConwaySmith_for_3S7) CoxeterGraph = staticmethod(smallgraphs.CoxeterGraph) + CubeplexGraph = staticmethod(smallgraphs.CubeplexGraph) DejterGraph = staticmethod(smallgraphs.DejterGraph) DesarguesGraph = staticmethod(smallgraphs.DesarguesGraph) distance_3_doubly_truncated_Golay_code_graph = staticmethod(distance_regular.distance_3_doubly_truncated_Golay_code_graph) @@ -2595,6 +2608,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None MeredithGraph = staticmethod(smallgraphs.MeredithGraph) MoebiusKantorGraph = staticmethod(smallgraphs.MoebiusKantorGraph) MoserSpindle = staticmethod(smallgraphs.MoserSpindle) + MurtyGraph = staticmethod(smallgraphs.MurtyGraph) NauruGraph = staticmethod(smallgraphs.NauruGraph) PappusGraph = staticmethod(smallgraphs.PappusGraph) PoussinGraph = staticmethod(smallgraphs.PoussinGraph) @@ -2611,12 +2625,14 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None SzekeresSnarkGraph = staticmethod(smallgraphs.SzekeresSnarkGraph) ThomsenGraph = staticmethod(smallgraphs.ThomsenGraph) TietzeGraph = staticmethod(smallgraphs.TietzeGraph) + TricornGraph = staticmethod(smallgraphs.TricornGraph) Tutte12Cage = staticmethod(smallgraphs.Tutte12Cage) TruncatedIcosidodecahedralGraph = staticmethod(smallgraphs.TruncatedIcosidodecahedralGraph) TruncatedTetrahedralGraph = staticmethod(smallgraphs.TruncatedTetrahedralGraph) TruncatedWittGraph = staticmethod(distance_regular.TruncatedWittGraph) TutteCoxeterGraph = staticmethod(smallgraphs.TutteCoxeterGraph) TutteGraph = staticmethod(smallgraphs.TutteGraph) + TwinplexGraph = staticmethod(smallgraphs.TwinplexGraph) U42Graph216 = staticmethod(smallgraphs.U42Graph216) U42Graph540 = staticmethod(smallgraphs.U42Graph540) WagnerGraph = staticmethod(smallgraphs.WagnerGraph) @@ -2645,6 +2661,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None BalancedTree = staticmethod(families.BalancedTree) BarbellGraph = staticmethod(families.BarbellGraph) BilinearFormsGraph = staticmethod(distance_regular.BilinearFormsGraph) + BiwheelGraph = staticmethod(families.BiwheelGraph) BubbleSortGraph = staticmethod(families.BubbleSortGraph) CaiFurerImmermanGraph = staticmethod(families.CaiFurerImmermanGraph) chang_graphs = staticmethod(families.chang_graphs) @@ -2699,10 +2716,12 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None SierpinskiGasketGraph = staticmethod(families.SierpinskiGasketGraph) SquaredSkewHadamardMatrixGraph = staticmethod(families.SquaredSkewHadamardMatrixGraph) SwitchedSquaredSkewHadamardMatrixGraph = staticmethod(families.SwitchedSquaredSkewHadamardMatrixGraph) + StaircaseGraph = staticmethod(families.StaircaseGraph) strongly_regular_graph = staticmethod(strongly_regular_db.strongly_regular_graph) TabacjnGraph = staticmethod(families.TabacjnGraph) TadpoleGraph = staticmethod(families.TadpoleGraph) trees = staticmethod(families.trees) + TruncatedBiwheelGraph = staticmethod(families.TruncatedBiwheelGraph) nauty_gentreeg = staticmethod(families.nauty_gentreeg) TuranGraph = staticmethod(families.TuranGraph) UstimenkoGraph = staticmethod(distance_regular.UstimenkoGraph) @@ -2768,6 +2787,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None RandomIntervalGraph = staticmethod(random.RandomIntervalGraph) RandomLobster = staticmethod(random.RandomLobster) RandomNewmanWattsStrogatz = staticmethod(random.RandomNewmanWattsStrogatz) + RandomProperIntervalGraph = staticmethod(random.RandomProperIntervalGraph) RandomRegular = staticmethod(random.RandomRegular) RandomShell = staticmethod(random.RandomShell) RandomKTree = staticmethod(random.RandomKTree) @@ -2806,19 +2826,15 @@ def canaug_traverse_vert(g, aut_gens, max_verts, property, dig=False, loops=Fals INPUT: + - ``g`` -- current position on the tree - - ``g`` -- current position on the tree. - - - ``aut_gens`` -- list of generators of Aut(g), in - list notation. - - - ``max_verts`` -- when to retreat. + - ``aut_gens`` -- list of generators of Aut(g), in list notation - - ``property`` -- check before traversing below g. + - ``max_verts`` -- when to retreat - - ``degree_sequence`` -- specify a degree sequence to try to - obtain. + - ``property`` -- check before traversing below g + - ``degree_sequence`` -- specify a degree sequence to try to obtain EXAMPLES:: @@ -2998,14 +3014,11 @@ def canaug_traverse_edge(g, aut_gens, property, dig=False, loops=False, sparse=T INPUT: + - ``g`` -- current position on the tree - - ``g`` -- current position on the tree. - - - ``aut_gens`` -- list of generators of Aut(g), in - list notation. - - - ``property`` -- check before traversing below g. + - ``aut_gens`` -- list of generators of Aut(g), in list notation + - ``property`` -- check before traversing below g EXAMPLES:: diff --git a/src/sage/graphs/graph_generators_pyx.pyx b/src/sage/graphs/graph_generators_pyx.pyx index 033e8b22adc..04b20d3229b 100644 --- a/src/sage/graphs/graph_generators_pyx.pyx +++ b/src/sage/graphs/graph_generators_pyx.pyx @@ -57,7 +57,7 @@ def RandomGNP(n, p, bint directed=False, bint loops=False, seed=None): sage: from numpy import mean # needs numpy sage: abs(mean([RandomGNP(200, .2).density() for i in range(30)]) - .2) < .001 # needs numpy - True + ...True... sage: RandomGNP(150, .2, loops=True) Traceback (most recent call last): ... diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index b60ebde2e31..678fdbcf32e 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -144,6 +144,13 @@ def from_dig6(G, dig6_string): sage: from_dig6(g, digraphs.Circuit(10).dig6_string()) sage: g.is_isomorphic(digraphs.Circuit(10)) True + + The string may represent a directed graph with loops:: + + sage: L = DiGraph(loops=True) + sage: from_dig6(L, 'CW`C') + sage: L.edges(labels=False, sort=True) + [(0, 1), (0, 2), (1, 2), (2, 3), (3, 3)] """ from .generic_graph_pyx import length_and_string_from_graph6, binary_string_from_dig6 if isinstance(dig6_string, bytes): @@ -444,7 +451,7 @@ def from_dict_of_dicts(G, M, loops=False, multiedges=False, weighted=False, conv - ``G`` -- a graph - - ``M`` -- a dictionary of dictionaries + - ``M`` -- dictionary of dictionaries - ``loops``, ``multiedges``, ``weighted`` -- booleans (default: ``False``); whether to consider the graph as having loops, multiple edges, or weights @@ -541,7 +548,7 @@ def from_dict_of_lists(G, D, loops=False, multiedges=False, weighted=False): - ``G`` -- a :class:`Graph` or :class:`DiGraph` - - ``D`` -- a dictionary of lists + - ``D`` -- dictionary of lists - ``loops``, ``multiedges``, ``weighted`` -- booleans (default: ``False``); whether to consider the graph as having loops, multiple edges, or weights diff --git a/src/sage/graphs/graph_latex.py b/src/sage/graphs/graph_latex.py index bb1b727eda9..f0fb9329002 100644 --- a/src/sage/graphs/graph_latex.py +++ b/src/sage/graphs/graph_latex.py @@ -251,7 +251,7 @@ here we color in red all edges touching the vertex ``0``:: sage: g = graphs.PetersenGraph() - sage: g.set_latex_options(format="dot2tex", edge_options=lambda u_v_label: {"color": "red"} if u_v_label[0] == 0 else {}) + sage: g.set_latex_options(format='dot2tex', edge_options=lambda u_v_label: {"color": "red"} if u_v_label[0] == 0 else {}) sage: latex(g) # optional - dot2tex graphviz \begin{tikzpicture}[>=latex,line join=bevel,] ... @@ -622,19 +622,19 @@ def set_option(self, option_name, option_value=None): INPUT: - - ``option_name`` -- a string for a latex option contained in the list - ``sage.graphs.graph_latex.GraphLatex.__graphlatex_options``. - A :class:`ValueError` is raised if the option is not allowed. + - ``option_name`` -- string for a latex option contained in the list + ``sage.graphs.graph_latex.GraphLatex.__graphlatex_options``; + a :exc:`ValueError` is raised if the option is not allowed - - ``option_value`` -- a value for the option. If omitted, or set to - ``None``, the option will use the default value. + - ``option_value`` -- a value for the option; if omitted, or set to + ``None``, the option will use the default value The output can be either handled internally by ``Sage``, or delegated to the external software ``dot2tex`` and ``graphviz``. This is controlled by the option ``format``: - ``format`` -- string (default: ``'tkz_graph'``); either ``'dot2tex'`` - or ``'tkz_graph'``. + or ``'tkz_graph'`` If format is ``'dot2tex'``, then all the LaTeX generation will be delegated to ``dot2tex`` (which must be installed). @@ -652,17 +652,17 @@ def set_option(self, option_name, option_value=None): effort. For a custom appearance set this to ``'Custom'`` and use the options described below to override the default values. - - ``units`` -- string (default: ``'cm'``) -- a natural unit of + - ``units`` -- string (default: ``'cm'``); a natural unit of measurement used for all dimensions. Possible values are: ``'in'``, ``'mm'``, ``'cm'``, ``'pt'``, ``'em'``, ``'ex'``. - - ``scale`` -- float (default: ``1.0``); a dimensionless number that + - ``scale`` -- float (default: `1.0`); a dimensionless number that multiplies every linear dimension. So you can design at sizes you are accustomed to, then shrink or expand to meet other needs. Though fonts do not scale. - ``graphic_size`` -- tuple (default: ``(5, 5)``); overall dimensions - (width, length) of the bounding box around the entire graphic image. + (width, length) of the bounding box around the entire graphic image - ``margins`` -- 4-tuple (default: ``(0, 0, 0, 0)``); portion of graphic given over to a plain border as a tuple of four numbers: (left, right, @@ -677,7 +677,7 @@ def set_option(self, option_name, option_value=None): pre-built style and modify it (other than editing the latex string by hand after the fact). - - ``vertex_color`` -- (default: ``'black'``); a single color to use as + - ``vertex_color`` -- (default: ``'black'``) a single color to use as the default for outline of vertices. For the ``sphere`` shape this color is used for the entire vertex, which is drawn with a 3D shading. Colors must be specified as a string recognized by the matplotlib @@ -687,19 +687,19 @@ def set_option(self, option_name, option_value=None): These color specifications are consistent throughout the options for a ``tikzpicture``. - - ``vertex_colors`` -- a dictionary whose keys are vertices of the graph + - ``vertex_colors`` -- dictionary whose keys are vertices of the graph and whose values are colors. These will be used to color the outline of vertices. See the explanation above for the ``vertex_color`` option to see possible values. These values need only be specified for a proper subset of the vertices. Specified values will supersede a default value. - - ``vertex_fill_color`` -- (default: ``'white'``); a single color to use + - ``vertex_fill_color`` -- (default: ``'white'``) a single color to use as the default for the fill color of vertices. See the explanation above for the ``vertex_color`` option to see possible values. This color is ignored for the ``sphere`` vertex shape. - - ``vertex_fill_colors`` -- a dictionary whose keys are vertices of the + - ``vertex_fill_colors`` -- dictionary whose keys are vertices of the graph and whose values are colors. These will be used to fill the interior of vertices. See the explanation above for the ``vertex_color`` option to see possible values. These values need only @@ -713,7 +713,7 @@ def set_option(self, option_name, option_value=None): ``vertex_color`` and ``vertex_colors``, which are normally used for the outline of the vertex. - - ``vertex_shapes`` -- a dictionary whose keys are vertices of the graph + - ``vertex_shapes`` -- dictionary whose keys are vertices of the graph and whose values are shapes. See ``vertex_shape`` for the allowable possibilities. @@ -724,7 +724,7 @@ def set_option(self, option_name, option_value=None): parameter), while still containing labels. However, if labels are not of a uniform size, then the vertices will not be either. - - ``vertex_sizes`` -- a dictionary of sizes for some of the vertices. + - ``vertex_sizes`` -- dictionary of sizes for some of the vertices - ``vertex_labels`` -- boolean (default: ``True``); determine whether or not to display the vertex labels. If ``False`` subsequent options @@ -738,33 +738,33 @@ def set_option(self, option_name, option_value=None): representation according to the ``_repr`` method. Support for arbitrarily-complicated mathematics is not especially robust. - - ``vertex_label_color`` -- (default: ``'black'``); a single color to + - ``vertex_label_color`` -- (default: ``'black'``) a single color to use as the default for labels of vertices. See the explanation above for the ``vertex_color`` option to see possible values. - - ``vertex_label_colors`` -- a dictionary whose keys are vertices of the + - ``vertex_label_colors`` -- dictionary whose keys are vertices of the graph and whose values are colors. These will be used for the text of the labels of vertices. See the explanation above for the ``vertex_color`` option to see possible values. These values need only be specified for a proper subset of the vertices. Specified values will supersede a default value. - - ``vertex_label_placement`` -- (default: ``'center'``); if ``'center'`` + - ``vertex_label_placement`` -- (default: ``'center'``) if ``'center'`` the label is centered in the interior of the vertex and the vertex will expand to contain the label. Giving instead a pair of numbers will place the label exterior to the vertex at a certain distance from the edge, and at an angle to the positive x-axis, similar in spirit to polar coordinates. - - ``vertex_label_placements`` -- a dictionary of placements indexed by + - ``vertex_label_placements`` -- dictionary of placements indexed by the vertices. See the explanation for ``vertex_label_placement`` for the possible values. - - ``edge_color`` -- (default: ``'black'``); a single color to use as the + - ``edge_color`` -- (default: ``'black'``) a single color to use as the default for an edge. See the explanation above for the ``vertex_color`` option to see possible values. - - ``edge_colors`` -- a dictionary whose keys are edges of the graph and + - ``edge_colors`` -- dictionary whose keys are edges of the graph and whose values are colors. These will be used to color the edges. See the explanation above for the ``vertex_color`` option to see possible values. These values need only be specified for a proper subset of the @@ -774,13 +774,13 @@ def set_option(self, option_name, option_value=None): second color running down the middle. This can be a useful effect for highlighting edge crossings. - - ``edge_fill_color`` -- (default: ``'black'``); a single color to use + - ``edge_fill_color`` -- (default: ``'black'``) a single color to use as the default for the fill color of an edge. The boolean switch - ``edge_fills`` must be set to True for this to have an effect. See + ``edge_fills`` must be set to ``True`` for this to have an effect. See the explanation above for the ``vertex_color`` option to see possible values. - - ``edge_fill_colors`` -- a dictionary whose keys are edges of the graph + - ``edge_fill_colors`` -- dictionary whose keys are edges of the graph and whose values are colors. See the explanation above for the ``vertex_color`` option to see possible values. These values need only be specified for a proper subset of the vertices. Specified @@ -790,7 +790,7 @@ def set_option(self, option_name, option_value=None): edges. Note that ``tkz-graph`` does not interpret this number for loops. - - ``edge_thicknesses`` -- a dictionary of thicknesses for some of the + - ``edge_thicknesses`` -- dictionary of thicknesses for some of the edges of a graph. These values need only be specified for a proper subset of the vertices. Specified values will supersede a default value. @@ -804,11 +804,11 @@ def set_option(self, option_name, option_value=None): ``vertex_labels_math`` option, which behaves identically. Support for arbitrarily-complicated mathematics is not especially robust. - - ``edge_label_color`` -- (default: ``'black'``); a single color to use + - ``edge_label_color`` -- (default: ``'black'``) a single color to use as the default for labels of edges. See the explanation above for the ``vertex_color`` option to see possible values. - - ``edge_label_colors`` -- a dictionary whose keys are edges of the + - ``edge_label_colors`` -- dictionary whose keys are edges of the graph and whose values are colors. These will be used for the text of the labels of edges. See the explanation above for the ``vertex_color`` option to see possible values. These values need only @@ -822,11 +822,11 @@ def set_option(self, option_name, option_value=None): ``True`` means the label is rotated to follow the direction of the edge it labels. - - ``edge_label_slopes`` -- a dictionary of booleans, indexed by some + - ``edge_label_slopes`` -- dictionary of booleans, indexed by some subset of the edges. See the ``edge_label_sloped`` option for a description of sloped edge labels. - - ``edge_label_placement`` -- (default: 0.50); either a number between + - ``edge_label_placement`` -- (default: 0.50) either a number between 0.0 and 1.0, or one of: ``'above'``, ``'below'``, ``'left'``, ``'right'``. These adjust the location of an edge label along an edge. A number specifies how far along the edge the label is located. @@ -835,7 +835,7 @@ def set_option(self, option_name, option_value=None): the midpoint of the edge. The default value of ``0.50`` places the label on the midpoint of the edge. - - ``edge_label_placements`` -- a dictionary of edge placements, indexed + - ``edge_label_placements`` -- dictionary of edge placements, indexed by the edges. See the ``edge_label_placement`` option for a description of the allowable values. @@ -845,7 +845,7 @@ def set_option(self, option_name, option_value=None): specifying a compass point (North, South, East, West) as one of ``'NO'``, ``'SO'``, ``'EA'``, ``'WE'``. - - ``loop_placements`` -- a dictionary of loop placements. See the + - ``loop_placements`` -- dictionary of loop placements. See the ``loop_placements`` option for the allowable values. While loops are technically edges, this dictionary is indexed by vertices. @@ -857,10 +857,10 @@ def set_option(self, option_name, option_value=None): ``'dot'``, ``'neato'``, ``'twopi'``, ``'circo'`` or ``'fdp'``. - ``edge_labels`` -- boolean (default: ``False)``; whether to display - the labels on edges. + the labels on edges - ``edge_colors`` -- a color; can be used to set a global color to the - edge of the graph. + edge of the graph - ``color_by_label`` -- boolean (default: ``False``); colors the edges according to their labels @@ -870,9 +870,7 @@ def set_option(self, option_name, option_value=None): same cluster subgraph are drawn together, with the entire drawing of the cluster contained within a bounding rectangle. - OUTPUT: - - There are none. Success happens silently. + OUTPUT: none; success happens silently EXAMPLES: @@ -1172,7 +1170,7 @@ def set_option(self, option_name, option_value=None): raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, x in value.items(): - if not type(x) in [int, Integer, float, RealLiteral] or not x >= 0.0: + if type(x) not in [int, Integer, float, RealLiteral] or not x >= 0.0: raise ValueError('%s option for %s needs to be a positive number, not %s' % (name, key, x)) elif name in boolean_dicts: if not isinstance(value, dict): @@ -1350,7 +1348,6 @@ def latex(self): \end{scope} ... \end{tikzpicture} - """ format = self.get_option('format') if format == "tkz_graph": @@ -1434,7 +1431,7 @@ def dot2tex_picture(self): new_edge_colors[col] = [edge] options['edge_colors'] = new_edge_colors - dotdata = self._graph.graphviz_string(labels="latex", **options) + dotdata = self._graph.graphviz_string(labels='latex', **options) import dot2tex return dot2tex.dot2tex(dotdata, format='tikz', @@ -1565,6 +1562,21 @@ def tkz_picture(self): % % \end{tikzpicture} + + For a complicated vertex, a TeX box is used. :: + + sage: B = crystals.Tableaux(['B', 2], shape=[1]) + sage: latex(B) + \begin{tikzpicture} + ... + \newsavebox{\vertex} + \sbox{\vertex}{${\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{$\begin{array}[b]{*{1}c}\cline{1-1} + \lr{1}\\\cline{1-1} + \end{array}$} + }$}\Vertex[style={minimum size=1.0cm,draw=cv0,fill=cfv0,text=clv0,shape=circle},LabelOut=false,L=\usebox{\vertex},x=...,y=...]{v0} + ... + \end{tikzpicture} """ # This routine does not handle multiple edges # It will properly handle digraphs where a pair of vertices has an edge @@ -1941,48 +1953,66 @@ def translate(p): s += [str(round(el_color[edge][2], 4)), '}\n'] s += ['%\n'] - # Create each vertex + # Create vertices + v = [] + box = '' + used = False for u in vertex_list: - s += ['\\Vertex['] + t = [r'\Vertex['] # colors, shapes, sizes, labels/placement for 'Custom' style if customized: - s += ['style={'] # begin style list - s += ['minimum size=', str(round(float(scale * v_size[u]), 4)), + t += ['style={'] # begin style list + t += ['minimum size=', str(round(float(scale * v_size[u]), 4)), units, ','] - s += ['draw=', vertex_color_names[u], ','] - s += ['fill=', vertex_fill_color_names[u], ','] + t += ['draw=', vertex_color_names[u], ','] + t += ['fill=', vertex_fill_color_names[u], ','] if vertex_labels: - s += ['text=', vertex_label_color_names[u], ','] + t += ['text=', vertex_label_color_names[u], ','] if v_shape[u] == 'sphere': - s += ['shape=circle,shading=ball,line width=0pt,ball color=', vertex_color_names[u], ','] + t += ['shape=circle,shading=ball,line width=0pt,ball color=', vertex_color_names[u], ','] else: - s += ['shape=', v_shape[u]] - s += ['},'] # end style list + t += ['shape=', v_shape[u]] + t += ['},'] # end style list if vertex_labels: if vl_placement[u] == 'center': - s += ['LabelOut=false,'] + t += ['LabelOut=false,'] else: - s += ['LabelOut=true,'] - s += ['Ldist=', str(round(float(scale * vl_placement[u][0]), 4)), units, ','] - s += ['Lpos=', str(round(float(vl_placement[u][1]), 4)), ','] # degrees, no units + t += ['LabelOut=true,'] + t += ['Ldist=', str(round(float(scale * vl_placement[u][0]), 4)), units, ','] + t += ['Lpos=', str(round(float(vl_placement[u][1]), 4)), ','] # degrees, no units else: - s += ['NoLabel,'] + t += ['NoLabel,'] # vertex label information is available to all pre-built styles # but may be ignored by the style, so not apparent if vertex_labels or not customized: if vertex_labels_math and not (isinstance(u, str) and u[0] == '$' and u[-1] == '$'): - lab = r'\hbox{$%s$}' % latex(u) + ltx = str(latex(u)) + if '\\' in ltx: # complicated case; use \sbox + box = r'\sbox{\vertex}{$' + ltx + '$}' + lab = r'\usebox{\vertex}' + else: + lab = r'\hbox{$%s$}' % ltx else: lab = r'\hbox{%s}' % u - s += ['L=', lab, ','] + t += ['L=', lab, ','] scaled_pos = translate(pos[u]) - s += ['x=', str(round(float(scale * scaled_pos[0]), 4)), units, ','] - s += ['y=', str(round(float(scale * scaled_pos[1]), 4)), units] - s += [']'] - s += ['{', prefix, str(index_of_vertex[u]), '}\n'] + t += ['x=', str(round(float(scale * scaled_pos[0]), 4)), units, ','] + t += ['y=', str(round(float(scale * scaled_pos[1]), 4)), units] + t += [']'] + t += ['{', prefix, str(index_of_vertex[u]), '}\n'] + if box: + v += [box] + t + box = '' + used = True + else: + v += t + if used: + s += [r'\newsavebox{\vertex}' + '\n'] + v + else: + s += v s += ['%\n'] - # Create each edge or loop + # Create edges and loops for e in self._graph.edges(sort=False): edge = (e[0], e[1]) loop = e[0] == e[1] diff --git a/src/sage/graphs/graph_list.py b/src/sage/graphs/graph_list.py index 6994a821948..4109d5d738a 100644 --- a/src/sage/graphs/graph_list.py +++ b/src/sage/graphs/graph_list.py @@ -241,7 +241,7 @@ def _to_graph6(graphs, file=None, output_list=False, sparse=False): def to_graphics_array(graph_list, **kwds): """ - Draw all graphs in a graphics array + Draw all graphs in a graphics array. INPUT: diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 6e36a195197..40b6ecc764d 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -168,7 +168,7 @@ 'Which graphviz layout program to use -- one of ' '"circo", "dot", "fdp", "neato", or "twopi".', 'by_component': - 'Whether to do the spring layout by connected component -- a boolean.'} + 'Whether to do the spring layout by connected component -- boolean.'} graphplot_options = layout_options.copy() @@ -1033,7 +1033,6 @@ def show(self, **kwds): P = C.graphplot(vertex_labels=False, vertex_size=0, graph_border=True) sphinx_plot(P) - """ # Setting the default values if needed for k, value in DEFAULT_SHOW_OPTIONS.items(): @@ -1334,7 +1333,7 @@ def plot(self, **kwds): t = DiGraph('JCC???@A??GO??CO??GO??') sphinx_plot(t.graphplot(layout='tree', tree_root=0, - tree_orientation="up")) + tree_orientation='up')) More examples:: @@ -1467,7 +1466,7 @@ def layout_tree(self, root, orientation): INPUT: - - ``root`` -- the root vertex. + - ``root`` -- the root vertex - ``orientation`` -- whether to place the root at the top or at the bottom: @@ -1492,7 +1491,7 @@ def layout_tree(self, root, orientation): children = {root: T.neighbors(root)} # Always make a copy of the children because they get eaten - stack = [[u for u in children[root]]] + stack = [list(children[root])] stick = [root] parent = {u: root for u in children[root]} pos = {} diff --git a/src/sage/graphs/graph_plot_js.py b/src/sage/graphs/graph_plot_js.py index 1ce82ff1a44..7ef9057d3b2 100644 --- a/src/sage/graphs/graph_plot_js.py +++ b/src/sage/graphs/graph_plot_js.py @@ -16,7 +16,7 @@ - ``vertices`` -- each vertex is a dictionary defining : - - ``name`` -- The vertex's label + - ``name`` -- the vertex's label - ``group`` -- the vertex' color (integer) @@ -28,7 +28,7 @@ - ``target`` -- the ID (int) of the edge's destination - - ``color`` -- the edge's color (integer) + - ``color`` -- the edge's color (integer) - ``value`` -- thickness of the edge @@ -40,7 +40,7 @@ center of the edge. It defines the curve of the edge, which can be useful for multigraphs. -- ``pos`` -- a list whose `i` th element is a dictionary defining the position +- ``pos`` -- list whose `i` th element is a dictionary defining the position of the `i` th vertex It also contains the definition of some numerical/boolean variables whose @@ -73,9 +73,9 @@ Functions --------- """ +from pathlib import Path from sage.misc.temporary_file import tmp_filename from sage.misc.lazy_import import lazy_import -import os lazy_import("sage.plot.colors", "rainbow") # **************************************************************************** @@ -120,12 +120,12 @@ def gen_html_code(G, - ``vertex_partition`` -- list (default: ``[]``); a list of lists representing a partition of the vertex set. Vertices are then colored in - the graph according to the partition + the graph according to the partition. - - ``vertex_colors`` -- dict (default: ``None``); a dictionary representing a - partition of the vertex set. Keys are colors (ignored) and values are - lists of vertices. Vertices are then colored in the graph according to the - partition + - ``vertex_colors`` -- dictionary (default: ``None``); a dictionary + representing a partition of the vertex set. Keys are colors (ignored) and + values are lists of vertices. Vertices are then colored in the graph + according to the partition. - ``edge_partition`` -- list (default: ``[]``); same as ``vertex_partition``, with edges instead @@ -134,24 +134,24 @@ def gen_html_code(G, previously computed position of nodes into account if there is one, or to compute a spring layout - - ``vertex_size`` -- integer (default: ``7``); the size of a vertex' circle + - ``vertex_size`` -- integer (default: 7); the size of a vertex' circle - - ``edge_thickness`` -- integer (default: ``4``); thickness of an edge + - ``edge_thickness`` -- integer (default: 4); thickness of an edge - - ``charge`` -- integer (default: ``-120``); the vertices' charge. Defines + - ``charge`` -- integer (default: -120); the vertices' charge. Defines how they repulse each other. See ``_ for more information - - ``link_distance`` -- integer (default: ``30``); see + - ``link_distance`` -- integer (default: 30); see ``_ for more information - - ``link_strength`` -- integer (default: ``2``); see + - ``link_strength`` -- integer (default: 2); see ``_ for more information - - ``gravity`` -- float (default: ``0.04``); see + - ``gravity`` -- float (default: 0.04); see ``_ for more information @@ -165,15 +165,15 @@ def gen_html_code(G, EXAMPLES:: - sage: graphs.RandomTree(50).show(method="js") # optional - internet + sage: graphs.RandomTree(50).show(method='js') # optional - internet sage: g = graphs.PetersenGraph() - sage: g.show(method="js", vertex_partition=g.coloring()) # optional - internet + sage: g.show(method='js', vertex_partition=g.coloring()) # optional - internet - sage: graphs.DodecahedralGraph().show(method="js", # optional - internet + sage: graphs.DodecahedralGraph().show(method='js', # optional - internet ....: force_spring_layout=True) - sage: graphs.DodecahedralGraph().show(method="js") # optional - internet + sage: graphs.DodecahedralGraph().show(method='js') # optional - internet sage: # needs sage.combinat sage: g = digraphs.DeBruijn(2, 2) @@ -183,7 +183,7 @@ def gen_html_code(G, sage: g.add_edge("10", "10", "c") sage: g.add_edge("10", "10", "d") sage: g.add_edge("01", "11", "1") - sage: g.show(method="js", vertex_labels=True, edge_labels=True, # optional - internet + sage: g.show(method='js', vertex_labels=True, edge_labels=True, # optional - internet ....: link_distance=200, gravity=.05, charge=-500, ....: edge_partition=[[("11", "12", "2"), ("21", "21", "a")]], ....: edge_thickness=4) @@ -317,14 +317,13 @@ def gen_html_code(G, "edge_thickness": int(edge_thickness)}) from sage.env import SAGE_EXTCODE, SAGE_SHARE - js_code_file = open(SAGE_EXTCODE + "/graphs/graph_plot_js.html", 'r') - js_code = js_code_file.read().replace("// GRAPH_DATA_HEREEEEEEEEEEE", string) - js_code_file.close() + with open(Path(SAGE_EXTCODE) / "graphs" / "graph_plot_js.html") as f: + js_code = f.read().replace("// GRAPH_DATA_HEREEEEEEEEEEE", string) # Add d3.js script depending on whether d3js package is installed. - d3js_filepath = os.path.join(SAGE_SHARE, 'd3js', 'd3.min.js') - if os.path.exists(d3js_filepath): - with open(d3js_filepath, 'r') as d3js_code_file: + d3js_filepath = Path(SAGE_SHARE) / 'd3js' / 'd3.min.js' + if d3js_filepath.exists(): + with open(d3js_filepath) as d3js_code_file: d3js_script = '' else: d3js_script = '' diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 440a82de3d1..bf24e7d3d97 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -273,13 +273,13 @@ cdef tuple hyperbolicity_basic_algorithm(int N, INPUT: - - ``N`` -- number of vertices of the graph. + - ``N`` -- number of vertices of the graph - ``distances`` -- path distance matrix (see the distance_all_pairs - module). + module) - ``verbose`` -- boolean (default: ``False``); set to ``True`` to display - some information during execution. + some information during execution OUTPUT: @@ -291,7 +291,6 @@ cdef tuple hyperbolicity_basic_algorithm(int N, - ``certificate`` -- 4-tuple of vertices maximizing the value `h`. If no such 4-tuple is found, the empty list [] is returned. - """ cdef int a, b, c, d, hh, h_LB cdef list certificate @@ -419,8 +418,7 @@ cdef inline distances_and_far_apart_pairs(gg, # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph cdef short_digraph sd - init_short_digraph(sd, gg, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, gg, edge_labelled=False, vertex_list=int_to_vertex) cdef uint32_t** p_vertices = sd.neighbors cdef uint32_t* p_tmp cdef uint32_t* end @@ -510,14 +508,14 @@ cdef inline pair** sort_pairs(uint32_t N, OUTPUT: - - ``nb_p`` -- the number of pairs to be included; + - ``nb_p`` -- the number of pairs to be included; - - ``nb_pairs_of_length`` -- an array containing in position k the number - of pairs (i,j) that are included and such that values[i][j] = k. + - ``nb_pairs_of_length`` -- an array containing in position k the number + of pairs (i,j) that are included and such that values[i][j] = k - - ``pairs_of_length`` -- this function returns this array, containing in - position k a pointer to the first included pair (i,j) such that - values[i][j] = k. + - ``pairs_of_length`` -- this function returns this array, containing in + position k a pointer to the first included pair (i,j) such that + values[i][j] = k. """ # pairs_of_length[d] is the list of pairs of vertices at distance d cdef pair** pairs_of_length = check_allocarray(D + 1, sizeof(pair*)) @@ -600,20 +598,20 @@ cdef tuple hyperbolicity_BCCM(int N, - ``distances`` -- path distance matrix - ``far_apart_pairs`` -- 0/1 matrix of far-apart pairs. Pair ``(i,j)`` is - far-apart if ``far_apart_pairs[i][j]\neq 0``. + far-apart if ``far_apart_pairs[i][j]\neq 0`` - ``D`` -- diameter of the graph - ``h_LB`` -- lower bound on the hyperbolicity - - ``approximation_factor`` -- When the approximation factor is set to some + - ``approximation_factor`` -- when the approximation factor is set to some value larger than 1.0, the function stop computations as soon as the ratio between the upper bound and the best found solution is less than the approximation factor. When the approximation factor is 1.0, the problem is solved optimally. - - ``additive_gap`` -- When sets to a positive number, the function stop - computations as soon as the difference between the upper bound and the + - ``additive_gap`` -- when set to a positive number, the function stop + computations as soon as the difference between the upper bound and the best found solution is less than additive gap. When the gap is 0.0, the problem is solved optimally. @@ -624,18 +622,18 @@ cdef tuple hyperbolicity_BCCM(int N, This function returns a tuple ( h, certificate, h_UB ), where: - - ``h`` -- is an integer. When 4-tuples with hyperbolicity larger or equal + - ``h`` -- integer; when 4-tuples with hyperbolicity larger or equal to `h_LB are found, h is the maximum computed value and so twice the hyperbolicity of the graph. If no such 4-tuple is found, it returns -1. - - ``certificate`` -- is a list of vertices. When 4-tuples with + - ``certificate`` -- is a list of vertices; when 4-tuples with hyperbolicity larger that h_LB are found, certificate is the list of the 4 vertices for which the maximum value (and so the hyperbolicity of the graph) has been computed. If no such 4-tuple is found, it returns the empty list []. - - ``h_UB`` -- is an integer equal to the proven upper bound for `h`. When - ``h == h_UB``, the returned solution is optimal. + - ``h_UB`` -- integer equal to the proven upper bound for `h`; when + ``h == h_UB``, the returned solution is optimal """ cdef MemoryAllocator mem = MemoryAllocator() cdef int h = 0, hh # can get negative value @@ -858,42 +856,42 @@ cdef tuple hyperbolicity_CCL(int N, - ``distances`` -- path distance matrix - ``far_apart_pairs`` -- 0/1 matrix of far-apart pairs. Pair ``(i,j)`` is - far-apart if ``far_apart_pairs[i][j]\neq 0``. + far-apart if ``far_apart_pairs[i][j]\neq 0`` - ``D`` -- diameter of the graph - ``h_LB`` -- lower bound on the hyperbolicity - - ``approximation_factor`` -- When the approximation factor is set to some + - ``approximation_factor`` -- when the approximation factor is set to some value larger than 1.0, the function stop computations as soon as the ratio between the upper bound and the best found solution is less than the approximation factor. When the approximation factor is 1.0, the problem is solved optimally. - - ``additive_gap`` -- When sets to a positive number, the function stop - computations as soon as the difference between the upper bound and the + - ``additive_gap`` -- when set to a positive number, the function stop + computations as soon as the difference between the upper bound and the best found solution is less than additive gap. When the gap is 0.0, the problem is solved optimally. - - ``verbose`` -- (default: ``False``) is boolean set to ``True`` to display + - ``verbose`` -- boolean (default: ``False``); set to ``True`` to display some information during execution OUTPUT: This function returns a tuple ( h, certificate, h_UB ), where: - - ``h`` -- is an integer. When 4-tuples with hyperbolicity larger or equal + - ``h`` -- integer; when 4-tuples with hyperbolicity larger or equal to `h_LB are found, h is the maximum computed value and so twice the hyperbolicity of the graph. If no such 4-tuple is found, it returns -1. - - ``certificate`` -- is a list of vertices. When 4-tuples with + - ``certificate`` -- is a list of vertices; when 4-tuples with hyperbolicity larger that h_LB are found, certificate is the list of the 4 vertices for which the maximum value (and so the hyperbolicity of the graph) has been computed. If no such 4-tuple is found, it returns the empty list []. - - ``h_UB`` -- is an integer equal to the proven upper bound for `h`. When - ``h == h_UB``, the returned solution is optimal. + - ``h_UB`` -- integer equal to the proven upper bound for `h`; when + ``h == h_UB``, the returned solution is optimal """ cdef int hh # can get negative value cdef int a, b, c, d, h, h_UB @@ -1072,7 +1070,7 @@ def hyperbolicity(G, - ``G`` -- a connected Graph - - ``algorithm`` -- (default: ``'BCCM'``); specifies the algorithm to use + - ``algorithm`` -- (default: ``'BCCM'``) specifies the algorithm to use among: - ``'basic'`` is an exhaustive algorithm considering all possible @@ -1098,30 +1096,30 @@ def hyperbolicity(G, The ``additive_gap`` and ``approximation_factor`` parameters cannot be used in combination with this method and so are ignored. - - ``approximation_factor`` -- (default: None) When the approximation factor + - ``approximation_factor`` -- (default: ``None``) when the approximation factor is set to some value (larger than 1.0), the function stop computations as soon as the ratio between the upper bound and the best found solution is less than the approximation factor. When the approximation factor is 1.0, the problem is solved optimally. This parameter is used only when the chosen algorithm is ``'CCL'``, ``'CCL+FA'``, or ``'BCCM'``. - - ``additive_gap`` -- (default: None) When sets to a positive number, the + - ``additive_gap`` -- (default: ``None``) when set to a positive number, the function stop computations as soon as the difference between the upper bound and the best found solution is less than additive gap. When the gap is 0.0, the problem is solved optimally. This parameter is used only when the chosen algorithm is ``'CCL'`` or ``'CCL+FA'``, or ``'BCCM'``. - - ``verbose`` -- (default: ``False``) is a boolean set to True to display + - ``verbose`` -- boolean (default: ``False``); set to ``True`` to display some information during execution: new upper and lower bounds, etc. OUTPUT: This function returns the tuple ( delta, certificate, delta_UB ), where: - - ``delta`` -- the hyperbolicity of the graph (half-integer value). + - ``delta`` -- the hyperbolicity of the graph (half-integer value) - ``certificate`` -- is the list of the 4 vertices for which the maximum - value has been computed, and so the hyperbolicity of the graph. + value has been computed, and so the hyperbolicity of the graph - ``delta_UB`` -- is an upper bound for ``delta``. When ``delta == delta_UB``, the returned solution is optimal. Otherwise, the approximation @@ -1493,8 +1491,8 @@ cdef dict __hyperbolicity_distribution__(int N, unsigned short** distances): OUTPUT: - - ``hdict`` -- A dictionary such that hdict[i] is the number of 4-tuples of - hyperbolicity i among the considered 4-tuples. + - ``hdict`` -- dictionary such that hdict[i] is the number of 4-tuples of + hyperbolicity i among the considered 4-tuples """ # We initialize the table of hyperbolicity. We use an array of unsigned long # int instead of a dictionary since it is much faster. @@ -1549,12 +1547,12 @@ cdef dict __hyperbolicity_sampling__(int N, unsigned short** distances, uint64_t - ``distances`` -- matrix of distances in the graph - - ``sampling_size`` -- number of 4-tuples considered. Default value is 1000. + - ``sampling_size`` -- number of 4-tuples considered. Default value is 1000 OUTPUT: - - ``hdict`` -- A dictionary such that hdict[i] is the number of 4-tuples of - hyperbolicity i among the considered 4-tuples. + - ``hdict`` -- dictionary such that hdict[i] is the number of 4-tuples of + hyperbolicity i among the considered 4-tuples """ cdef int i, a, b, c, d cdef uint64_t j @@ -1608,21 +1606,21 @@ def hyperbolicity_distribution(G, algorithm='sampling', sampling_size=10**6): INPUT: - - ``G`` -- a Graph. + - ``G`` -- a Graph - - ``algorithm`` -- (default: 'sampling') When algorithm is 'sampling', it + - ``algorithm`` -- (default: ``'sampling'``) when algorithm is 'sampling', it returns the distribution of the hyperbolicity over a sample of ``sampling_size`` 4-tuples. When algorithm is 'exact', it computes the distribution of the hyperbolicity over all 4-tuples. Be aware that the computation time can be HUGE. - ``sampling_size`` -- (default: `10^6`) number of 4-tuples considered in - the sampling. Used only when ``algorithm == 'sampling'``. + the sampling. Used only when ``algorithm == 'sampling'`` OUTPUT: - - ``hdict`` -- A dictionary such that hdict[i] is the number of 4-tuples of - hyperbolicity i. + - ``hdict`` -- dictionary such that hdict[i] is the number of 4-tuples of + hyperbolicity i EXAMPLES: diff --git a/src/sage/graphs/hypergraph_generators.py b/src/sage/graphs/hypergraph_generators.py index 642bb3f98e3..b4bae7292cf 100644 --- a/src/sage/graphs/hypergraph_generators.py +++ b/src/sage/graphs/hypergraph_generators.py @@ -44,40 +44,40 @@ def nauty(self, number_of_sets, number_of_vertices, regular=False, uniform=False, max_intersection=None, connected=False, - debug=False, options=""): + debug=False, options=''): r""" Enumerate hypergraphs up to isomorphism using Nauty. INPUT: - - ``number_of_sets`` -- integer, at most 64 minus ``number_of_vertices`` + - ``number_of_sets`` -- integer; at most 64 minus ``number_of_vertices`` - - ``number_of_vertices`` -- integer, at most 30 + - ``number_of_vertices`` -- integer; at most 30 - ``multiple_sets`` -- boolean (default: ``False``); whether to allow - several sets of the hypergraph to be equal. + several sets of the hypergraph to be equal - ``vertex_min_degree``, ``vertex_max_degree`` -- integers (default: ``None``); define the maximum and minimum degree of an element from - the ground set (i.e. the number of sets which contain it). + the ground set (i.e. the number of sets which contain it) - ``set_min_size``, ``set_max_size`` -- integers (default: ``None``); - define the maximum and minimum size of a set. + define the maximum and minimum size of a set - - ``regular`` -- integers (default: ``False``); if set to an integer + - ``regular`` -- integer (default: ``False``); if set to an integer value `k`, requires the hypergraphs to be `k`-regular. It is actually a shortcut for the corresponding min/max values. - - ``uniform`` -- integers (default: ``False``); if set to an integer + - ``uniform`` -- integer (default: ``False``); if set to an integer value `k`, requires the hypergraphs to be `k`-uniform. It is actually a shortcut for the corresponding min/max values. - - ``max_intersection`` -- integers (default: ``None``); constraints the + - ``max_intersection`` -- integer (default: ``None``); constraints the maximum cardinality of the intersection of two sets from the - hypergraphs. + hypergraphs - ``connected`` -- boolean (default: ``False``); whether to require the - hypergraphs to be connected. + hypergraphs to be connected - ``debug`` -- boolean (default: ``False``); if ``True`` the first line of genbgL's output to standard error is captured and the first call to @@ -86,7 +86,7 @@ def nauty(self, number_of_sets, number_of_vertices, program with some information on the arguments, while a line beginning with ">E" indicates an error with the input. - - ``options`` -- string (default: ``""``) -- anything else that should + - ``options`` -- string (default: ``''``); anything else that should be forwarded as input to Nauty's genbgL. See its documentation for more information : ``_. @@ -95,9 +95,7 @@ def nauty(self, number_of_sets, number_of_vertices, For genbgL the *first class* elements are vertices, and *second class* elements are the hypergraph's sets. - OUTPUT: - - A tuple of tuples. + OUTPUT: a tuple of tuples EXAMPLES: @@ -248,7 +246,7 @@ def UniformRandomUniform(self, n, k, m): sage: hypergraphs.UniformRandomUniform(-52, 3, 17) Traceback (most recent call last): ... - ValueError: number of vertices should be non-negative + ValueError: number of vertices should be nonnegative sage: hypergraphs.UniformRandomUniform(52.9, 3, 17) Traceback (most recent call last): ... @@ -256,7 +254,7 @@ def UniformRandomUniform(self, n, k, m): sage: hypergraphs.UniformRandomUniform(52, -3, 17) Traceback (most recent call last): ... - ValueError: the uniformity should be non-negative + ValueError: the uniformity should be nonnegative sage: hypergraphs.UniformRandomUniform(52, I, 17) # needs sage.symbolic Traceback (most recent call last): ... @@ -268,7 +266,7 @@ def UniformRandomUniform(self, n, k, m): # Construct the vertex set if n < 0: - raise ValueError("number of vertices should be non-negative") + raise ValueError("number of vertices should be nonnegative") try: nverts = Integer(n) except TypeError: @@ -277,7 +275,7 @@ def UniformRandomUniform(self, n, k, m): # Construct the edge set if k < 0: - raise ValueError("the uniformity should be non-negative") + raise ValueError("the uniformity should be nonnegative") try: uniformity = Integer(k) except TypeError: @@ -325,7 +323,7 @@ def BinomialRandomUniform(self, n, k, p): sage: hypergraphs.BinomialRandomUniform(-50, 3, 0.17) Traceback (most recent call last): ... - ValueError: number of vertices should be non-negative + ValueError: number of vertices should be nonnegative sage: hypergraphs.BinomialRandomUniform(50.9, 3, 0.17) Traceback (most recent call last): ... @@ -333,7 +331,7 @@ def BinomialRandomUniform(self, n, k, p): sage: hypergraphs.BinomialRandomUniform(50, -3, 0.17) Traceback (most recent call last): ... - ValueError: the uniformity should be non-negative + ValueError: the uniformity should be nonnegative sage: hypergraphs.BinomialRandomUniform(50, I, 0.17) Traceback (most recent call last): ... @@ -341,13 +339,13 @@ def BinomialRandomUniform(self, n, k, p): """ from sage.rings.integer import Integer if n < 0: - raise ValueError("number of vertices should be non-negative") + raise ValueError("number of vertices should be nonnegative") try: nverts = Integer(n) except TypeError: raise ValueError("number of vertices should be an integer") if k < 0: - raise ValueError("the uniformity should be non-negative") + raise ValueError("the uniformity should be nonnegative") try: uniformity = Integer(k) except TypeError: diff --git a/src/sage/graphs/independent_sets.pyx b/src/sage/graphs/independent_sets.pyx index ad761878d06..c880d9df424 100644 --- a/src/sage/graphs/independent_sets.pyx +++ b/src/sage/graphs/independent_sets.pyx @@ -40,10 +40,10 @@ cdef class IndependentSets: - ``G`` -- a graph - ``maximal`` -- boolean (default: ``False``); whether to only consider - (inclusionwise) maximal independent sets. + (inclusionwise) maximal independent sets - ``complement`` -- boolean (default: ``False``); whether to consider the - graph's complement (i.e. cliques instead of independent sets). + graph's complement (i.e. cliques instead of independent sets) ALGORITHM: @@ -129,7 +129,7 @@ cdef class IndependentSets: """ def __init__(self, G, maximal=False, complement=False): r""" - Constructor for this class + Constructor for this class. TESTS:: @@ -330,11 +330,11 @@ cdef class IndependentSets: def __contains__(self, S): r""" - Check whether the set is an independent set (possibly maximal) + Check whether the set is an independent set (possibly maximal). INPUT: - - ``S`` -- a set of vertices to be tested. + - ``S`` -- set of vertices to be tested TESTS: diff --git a/src/sage/graphs/isgci.py b/src/sage/graphs/isgci.py index 2315ea4679d..f8bcf801d7e 100644 --- a/src/sage/graphs/isgci.py +++ b/src/sage/graphs/isgci.py @@ -293,7 +293,7 @@ What ISGCI knows is that perfect graphs contain unimodular graph which contain bipartite graphs. Therefore bipartite graphs are perfect ! -.. note:: +.. NOTE:: The inclusion digraph is **NOT ACYCLIC**. Indeed, several entries exist in the ISGCI database which represent the same graph class, for instance @@ -655,7 +655,7 @@ def get_class(self, id): INPUT: - - ``id`` (string) -- the desired class' ID + - ``id`` -- string; the desired class' ID .. SEEALSO:: @@ -719,9 +719,7 @@ def inclusions(self): r""" Return the graph class inclusions. - OUTPUT: - - a list of dictionaries + OUTPUT: list of dictionaries Upon the first call, this loads the database from the local XML file. Subsequent calls are cached. @@ -799,7 +797,7 @@ def _download_db(self): data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) u = urlopen('https://www.graphclasses.org/data.zip', context=default_context()) - with tempfile.NamedTemporaryFile(suffix=".zip") as f: + with tempfile.NamedTemporaryFile(suffix='.zip') as f: f.write(u.read()) z = zipfile.ZipFile(f.name) @@ -834,7 +832,7 @@ def _parse_db(self): inclusions = DB['Inclusions']['incl'] # Parses the list of ISGCI small graphs - smallgraph_file = open(os.path.join(data_dir, _SMALLGRAPHS_FILE), 'r') + smallgraph_file = open(os.path.join(data_dir, _SMALLGRAPHS_FILE)) smallgraphs = {} for line in smallgraph_file.readlines(): @@ -849,7 +847,7 @@ def _parse_db(self): def update_db(self): r""" - Updates the ISGCI database by downloading the latest version from + Update the ISGCI database by downloading the latest version from internet. This method downloads the ISGCI database from the website @@ -877,7 +875,7 @@ def update_db(self): def _get_ISGCI(self): r""" - Returns the contents of the ISGCI database. + Return the contents of the ISGCI database. This method is mostly for internal use, but often provides useful information during debugging operations. @@ -901,7 +899,7 @@ def _get_ISGCI(self): def show_all(self): r""" - Prints all graph classes stored in ISGCI + Print all graph classes stored in ISGCI. EXAMPLES:: @@ -974,11 +972,9 @@ def _XML_to_dict(root): INPUT: - - ``root`` -- an ``xml.etree.cElementTree.ElementTree`` object. - - OUTPUT: + - ``root`` -- an ``xml.etree.cElementTree.ElementTree`` object - A dictionary representing the XML data. + OUTPUT: a dictionary representing the XML data EXAMPLES:: diff --git a/src/sage/graphs/isoperimetric_inequalities.pyx b/src/sage/graphs/isoperimetric_inequalities.pyx index 5fd13cade15..731cfc00040 100644 --- a/src/sage/graphs/isoperimetric_inequalities.pyx +++ b/src/sage/graphs/isoperimetric_inequalities.pyx @@ -110,8 +110,7 @@ def cheeger_constant(g): cdef unsigned long vmin = 1 # value of the volume for the min cdef int i - init_short_digraph(sd, g, edge_labelled=False, vertex_list=list(g), - sort_neighbors=False) + init_short_digraph(sd, g, edge_labelled=False, vertex_list=list(g)) subgraph = check_malloc(sd.n * sizeof(int)) bitsubgraph = check_malloc(sd.n * sizeof(int)) @@ -245,8 +244,7 @@ def edge_isoperimetric_number(g): cdef int u = 0 # current vertex cdef int i - init_short_digraph(sd, g, edge_labelled=False, vertex_list=list(g), - sort_neighbors=False) + init_short_digraph(sd, g, edge_labelled=False, vertex_list=list(g)) cdef unsigned long bmin = sd.neighbors[1] - sd.neighbors[0] # value of boundary for the min cdef unsigned long vmin = 1 # value of the volume for the min diff --git a/src/sage/graphs/line_graph.pyx b/src/sage/graphs/line_graph.pyx index 796e15d44ab..e54caf52897 100644 --- a/src/sage/graphs/line_graph.pyx +++ b/src/sage/graphs/line_graph.pyx @@ -134,7 +134,7 @@ def is_line_graph(g, certificate=False): INPUT: - - ``certificate`` (boolean) -- whether to return a certificate along with + - ``certificate`` -- boolean; whether to return a certificate along with the boolean result. Here is what happens when ``certificate = True``: - If the graph is not a line graph, the method returns a pair ``(b, @@ -293,12 +293,12 @@ def line_graph(g, labels=True): .. SEEALSO:: - - The :mod:`line_graph ` module. + - The :mod:`line_graph ` module - :meth:`~sage.graphs.graph_generators.GraphGenerators.line_graph_forbidden_subgraphs` - -- the forbidden subgraphs of a line graph. + -- the forbidden subgraphs of a line graph - - :meth:`~Graph.is_line_graph` -- tests whether a graph is a line graph. + - :meth:`~Graph.is_line_graph` -- tests whether a graph is a line graph EXAMPLES:: @@ -421,7 +421,7 @@ def root_graph(g, verbose=False): - ``g`` -- a graph - ``verbose`` -- boolean (default: ``False``); display some information - about what is happening inside of the algorithm. + about what is happening inside of the algorithm .. WARNING:: diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py new file mode 100644 index 00000000000..457ccc16a75 --- /dev/null +++ b/src/sage/graphs/matching.py @@ -0,0 +1,1641 @@ +r""" +Matching + +This module implements the functions pertaining to matching of undirected +graphs. A *matching* in a graph is a set of pairwise nonadjacent links +(nonloop edges). In other words, a matching in a graph is the edge set of an +1-regular subgraph. A matching is called a *perfect* *matching* if it the +subgraph generated by a set of matching edges spans the graph, i.e. it's the +edge set of an 1-regular spanning subgraph. + +The implemented methods are listed below: + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :meth:`~has_perfect_matching` | Return whether the graph has a perfect matching + :meth:`~is_bicritical` | Check if the graph is bicritical + :meth:`~is_factor_critical` | Check whether the graph is factor-critical + :meth:`~is_matching_covered` | Check if the graph is matching covered + :meth:`~matching` | Return a maximum weighted matching of the graph represented by the list of its edges + :meth:`~perfect_matchings` | Return an iterator over all perfect matchings of the graph + :meth:`~M_alternating_even_mark` | Return the vertices reachable from the provided vertex via an even alternating path starting with a non-matching edge + +AUTHORS: + +- Robert L. Miller (2006-10-22): initial implementations + +- Janmenjaya Panda (2024-06-17): added + :meth:`~M_alternating_even_mark`, + :meth:`~is_bicritical` and + :meth:`~is_matching_covered` + + +Methods +------- +""" + +# **************************************************************************** +# Copyright (C) 2006 Robert L. Miller +# 2024 Janmenjaya Panda +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.rings.integer import Integer +from sage.graphs.views import EdgesView + + +def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, + *, integrality_tolerance=1e-3): + r""" + Return whether the graph has a perfect matching + + INPUT: + + - ``algorithm`` -- string (default: ``'Edmonds'``) + + - ``'Edmonds'`` uses Edmonds' algorithm as implemented in NetworkX to + find a matching of maximal cardinality, then check whether this + cardinality is half the number of vertices of the graph. + + - ``'LP_matching'`` uses a Linear Program to find a matching of + maximal cardinality, then check whether this cardinality is half the + number of vertices of the graph. + + - ``'LP'`` uses a Linear Program formulation of the perfect matching + problem: put a binary variable ``b[e]`` on each edge `e`, and for + each vertex `v`, require that the sum of the values of the edges + incident to `v` is 1. + + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: 0); sets the level of verbosity: + set to 0 by default, which means quiet (only useful when + ``algorithm == "LP_matching"`` or ``algorithm == "LP"``) + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: boolean + + EXAMPLES:: + + sage: graphs.PetersenGraph().has_perfect_matching() # needs networkx + True + sage: graphs.WheelGraph(6).has_perfect_matching() # needs networkx + True + sage: graphs.WheelGraph(5).has_perfect_matching() # needs networkx + False + sage: graphs.PetersenGraph().has_perfect_matching(algorithm='LP_matching') # needs sage.numerical.mip + True + sage: graphs.WheelGraph(6).has_perfect_matching(algorithm='LP_matching') # needs sage.numerical.mip + True + sage: graphs.WheelGraph(5).has_perfect_matching(algorithm='LP_matching') + False + sage: graphs.PetersenGraph().has_perfect_matching(algorithm='LP_matching') # needs sage.numerical.mip + True + sage: graphs.WheelGraph(6).has_perfect_matching(algorithm='LP_matching') # needs sage.numerical.mip + True + sage: graphs.WheelGraph(5).has_perfect_matching(algorithm='LP_matching') + False + + TESTS:: + + sage: G = graphs.EmptyGraph() + sage: all(G.has_perfect_matching(algorithm=algo) # needs networkx + ....: for algo in ['Edmonds', 'LP_matching', 'LP']) + True + + Be careful with isolated vertices:: + + sage: G = graphs.PetersenGraph() + sage: G.add_vertex(11) + sage: any(G.has_perfect_matching(algorithm=algo) # needs networkx + ....: for algo in ['Edmonds', 'LP_matching', 'LP']) + False + """ + if G.order() % 2: + return False + + if algorithm == "Edmonds": + return len(G) == 2*G.matching(value_only=True, + use_edge_labels=False, + algorithm='Edmonds') + elif algorithm == "LP_matching": + return len(G) == 2*G.matching(value_only=True, + use_edge_labels=False, + algorithm='LP', + solver=solver, + verbose=verbose, + integrality_tolerance=integrality_tolerance) + elif algorithm == "LP": + from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException + p = MixedIntegerLinearProgram(solver=solver) + b = p.new_variable(binary=True) + for v in G: + edges = G.edges_incident(v, labels=False) + if not edges: + return False + p.add_constraint(p.sum(b[frozenset(e)] for e in edges) == 1) + try: + p.solve(log=verbose) + return True + except MIPSolverException: + return False + raise ValueError('algorithm must be set to "Edmonds", "LP_matching" or "LP"') + + +def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, + solver=None, verbose=0, *, integrality_tolerance=0.001): + r""" + Check if the graph is bicritical + + A nontrivial graph `G` is *bicritical* if `G - u - v` has a perfect + matching for any two distinct vertices `u` and `v` of `G`. Bicritical + graphs are special kind of matching covered graphs. Each maximal barrier of + a bicritical graph is a singleton. Thus, for a bicritical graph, the + canonical partition of the vertex set is the set of sets where each set is + an indiviudal vertex. Three-connected bicritical graphs, aka *bricks*, play + an important role in the theory of matching covered graphs. + + This method implements the algorithm proposed in [LZ2001]_ and we + assume that a connected graph of order two is bicritical, whereas a + disconnected graph of the same order is not. The time complexity of + the algorithm is `\mathcal{O}(|V| \cdot |E|)`, if a perfect matching of + the graph is given, where `|V|` and `|E|` are the order and the size of + the graph respectively. Otherwise, time complexity may be dominated by + the time needed to compute a maximum matching of the graph. + + Note that a :class:`ValueError` is returned if the graph has loops or if + the graph is trivial, i.e., it has at most one vertex. + + INPUT: + + - ``matching`` -- (default: ``None``); a perfect matching of the + graph, that can be given using any valid input format of + :class:`~sage.graphs.graph.Graph`. + + If set to ``None``, a matching is computed using the other parameters. + + - ``algorithm`` -- string (default: ``'Edmonds'``); the algorithm to be + used to compute a maximum matching of the graph among + + - ``'Edmonds'`` selects Edmonds' algorithm as implemented in NetworkX, + + - ``'LP'`` uses a Linear Program formulation of the matching problem. + + - ``coNP_certificate`` -- boolean (default: ``False``); if set to + ``True`` a set of pair of vertices (say `u` and `v`) is returned such + that `G - u - v` does not have a perfect matching if `G` is not + bicritical or otherwise ``None`` is returned. + + - ``solver`` -- string (default: ``None``); specify a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: ``0``); sets the level of verbosity: + set to 0 by default, which means quiet (only useful when ``algorithm + == 'LP'``). + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: + + - A boolean indicating whether the graph is bicritical or not. + + - If ``coNP_certificate`` is set to ``True``, a set of pair of vertices + is returned in case the graph is not bicritical otherwise ``None`` is + returned. + + EXAMPLES: + + The Petersen graph is bicritical:: + + sage: G = graphs.PetersenGraph() + sage: G.is_bicritical() + True + + A graph (without a self-loop) is bicritical if and only if the underlying + simple graph is bicritical:: + + sage: G = graphs.PetersenGraph() + sage: G.allow_multiple_edges(True) + sage: G.add_edge(0, 5) + sage: G.is_bicritical() + True + + A nontrivial circular ladder graph whose order is not divisible by 4 is bicritical:: + + sage: G = graphs.CircularLadderGraph(5) + sage: G.is_bicritical() + True + + The graph obtained by splicing two bicritical graph is also bicritical. + For instance, `K_4` with one extra (multiple) edge (say `G := K_4^+`) is + bicritical. Let `H := K_4^+ \odot K_4^+` such that `H` is free of multiple + edge. The graph `H` is also bicritical:: + + sage: G = graphs.CompleteGraph(4) + sage: G.allow_multiple_edges(True) + sage: G.add_edge(0, 1) + sage: G.is_bicritical() + True + sage: H = Graph() + sage: H.add_edges([ + ....: (0, 1), (0, 2), (0, 3), (0, 4), (1, 2), + ....: (1, 5), (2, 5), (3, 4), (3, 5), (4, 5) + ....: ]) + sage: H.is_bicritical() + True + + A graph (of order more than two) with more that one component is not bicritical:: + + sage: cycle1 = graphs.CycleGraph(4) + sage: cycle2 = graphs.CycleGraph(6) + sage: cycle2.relabel(lambda v: v + 4) + sage: G = Graph() + sage: G.add_edges(cycle1.edges() + cycle2.edges()) + sage: len(G.connected_components(sort=False)) + 2 + sage: G.is_bicritical() + False + + A graph (of order more than two) with a cut-vertex is not bicritical:: + + sage: G = graphs.CycleGraph(6) + sage: G.add_edges([(5, 6), (5, 7), (6, 7)]) + sage: G.is_cut_vertex(5) + True + sage: G.has_perfect_matching() + True + sage: G.is_bicritical() + False + + A connected graph of order two is assumed to be bicritical, whereas the + disconnected graph of the same order is not:: + + sage: G = graphs.CompleteBipartiteGraph(1, 1) + sage: G.is_bicritical() + True + sage: G = graphs.CompleteBipartiteGraph(2, 0) + sage: G.is_bicritical() + False + + A bipartite graph of order three or more is not bicritical:: + + sage: G = graphs.CompleteBipartiteGraph(3, 3) + sage: G.has_perfect_matching() + True + sage: G.is_bicritical() + False + + One may specify a matching:: + + sage: G = graphs.WheelGraph(10) + sage: M = G.matching() + sage: G.is_bicritical(matching=M) + True + sage: H = graphs.HexahedralGraph() + sage: N = H.matching() + sage: H.is_bicritical(matching=N) + False + + One may ask for a co-`\mathcal{NP}` certificate:: + + sage: G = graphs.CompleteGraph(14) + sage: G.is_bicritical(coNP_certificate=True) + (True, None) + sage: H = graphs.CircularLadderGraph(20) + sage: M = H.matching() + sage: H.is_bicritical(matching=M, coNP_certificate=True) + (False, {0, 2}) + + TESTS: + + If the graph is trivial:: + + sage: G = Graph() + sage: G.is_bicritical() + Traceback (most recent call last): + ... + ValueError: the graph is trivial + sage: H = graphs.CycleGraph(1) + sage: H.is_bicritical() + Traceback (most recent call last): + ... + ValueError: the graph is trivial + + Providing with a wrong matching:: + + sage: G = graphs.CompleteGraph(6) + sage: M = Graph(G.matching()) + sage: M.add_edges([(0, 1), (0, 2)]) + sage: G.is_bicritical(matching=M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: N = Graph(G.matching()) + sage: N.add_edge(6, 7) + sage: G.is_bicritical(matching=N) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + sage: J = Graph() + sage: J.add_edges([(0, 1), (2, 3)]) + sage: G.is_bicritical(matching=J) + Traceback (most recent call last): + ... + ValueError: the input is not a perfect matching of the graph + + Providing with a graph with a self-loop:: + + sage: G = graphs.CompleteGraph(4) + sage: G.allow_loops(True) + sage: G.add_edge(0, 0) + sage: G.is_bicritical() + Traceback (most recent call last): + ... + ValueError: This method is not known to work on graphs with loops. + Perhaps this method can be updated to handle them, but in the meantime + if you want to use it please disallow loops using allow_loops(). + + REFERENCES: + + - [LM2024]_ + + - [LZ2001]_ + + .. SEEALSO:: + :meth:`~sage.graphs.graph.Graph.is_factor_critical`, + :meth:`~sage.graphs.graph.Graph.is_matching_covered` + + AUTHORS: + + - Janmenjaya Panda (2024-06-17) + """ + # The graph must be simple + G._scream_if_not_simple(allow_multiple_edges=True) + + # The graph must be nontrivial + if G.order() < 2: + raise ValueError("the graph is trivial") + + # A graph of order two is assumed to be bicritical + if G.order() == 2: + if G.is_connected(): + return (True, None) if coNP_certificate else True + else: + return (False, None) if coNP_certificate else False + + # The graph must have an even number of vertices + if G.order() % 2: + return (False, set(list(G)[:2])) if coNP_certificate else False + + # The graph must be connected + if not G.is_connected(): + if not coNP_certificate: + return False + + components = G.connected_components(sort=False) + + # Check if there is an odd component with at least three vertices + for component in components: + if len(component) % 2 and len(component) > 2: + return (False, set(component[:2])) + + # Check if there are at least two even components + components_of_even_order = [component for component in components if len(component) % 2 == 0] + if len(components_of_even_order) > 1: + return (False, set([components_of_even_order[0][0], components_of_even_order[1][0]])) + + # Or otherwise there is at most one even component with at least two trivial odd components + u, v = None, None + + for component in components: + if u is not None and not len(component) % 2: + v = component[0] + return (False, set([u, v])) + elif len(component) == 1: + u = component[0] + + # Bipartite graphs of order at least three are not bicritical + if G.is_bipartite(): + if not coNP_certificate: + return False + + A, B = G.bipartite_sets() + + if len(A) > 1: + return (False, set(list(A)[:2])) + return (False, set(list(B)[:2])) + + # A graph (without a self-loop) is bicritical if and only if the underlying + # simple graph is bicritical + G_simple = G.to_simple() + + from sage.graphs.graph import Graph + if matching: + # The input matching must be a valid perfect matching of the graph + M = Graph(matching) + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + raise ValueError("the input is not a matching of the graph") + if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + raise ValueError("the input is not a perfect matching of the graph") + else: + # A maximum matching of the graph is computed + M = Graph(G_simple.matching(algorithm=algorithm, solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance)) + + # It must be a perfect matching + if G_simple.order() != M.order(): + u, v = next(M.edge_iterator(labels=False)) + return (False, set([u, v])) if coNP_certificate else False + + # G is bicritical if and only if for each vertex u with its M-matched neighbor being v, + # every vertex of the graph distinct from v must be reachable from u through an even length + # M-alternating uv-path starting with an edge not in M and ending with an edge in M + + for u in G_simple: + v = next(M.neighbor_iterator(u)) + + even = M_alternating_even_mark(G_simple, u, M) + + for w in G_simple: + if w != v and w not in even: + return (False, set([v, w])) if coNP_certificate else False + + return (True, None) if coNP_certificate else True + + +def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbose=0, + *, integrality_tolerance=0.001): + r""" + Check whether the graph is factor-critical. + + A graph of order `n` is *factor-critical* if every subgraph of `n-1` + vertices have a perfect matching, hence `n` must be odd. See + :wikipedia:`Factor-critical_graph` for more details. + + This method implements the algorithm proposed in [LR2004]_ and we assume + that a graph of order one is factor-critical. The time complexity of the + algorithm is linear if a near perfect matching is given as input (i.e., + a matching such that all vertices but one are incident to an edge of the + matching). Otherwise, the time complexity is dominated by the time + needed to compute a maximum matching of the graph. + + INPUT: + + - ``matching`` -- (default: ``None``); a near perfect matching of the + graph, that is a matching such that all vertices of the graph but one + are incident to an edge of the matching. It can be given using any + valid input format of :class:`~sage.graphs.graph.Graph`. + + If set to ``None``, a matching is computed using the other parameters. + + - ``algorithm`` -- string (default: ``'Edmonds'``); the algorithm to use + to compute a maximum matching of the graph among + + - ``'Edmonds'`` selects Edmonds' algorithm as implemented in NetworkX + + - ``'LP'`` uses a Linear Program formulation of the matching problem + + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: 0); sets the level of verbosity: + set to 0 by default, which means quiet (only useful when ``algorithm + == "LP"``) + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + EXAMPLES: + + Odd length cycles and odd cliques of order at least 3 are + factor-critical graphs:: + + sage: [graphs.CycleGraph(2*i + 1).is_factor_critical() for i in range(5)] # needs networkx + [True, True, True, True, True] + sage: [graphs.CompleteGraph(2*i + 1).is_factor_critical() for i in range(5)] # needs networkx + [True, True, True, True, True] + + More generally, every Hamiltonian graph with an odd number of vertices + is factor-critical:: + + sage: G = graphs.RandomGNP(15, .2) + sage: G.add_path([0..14]) + sage: G.add_edge(14, 0) + sage: G.is_hamiltonian() + True + sage: G.is_factor_critical() # needs networkx + True + + Friendship graphs are non-Hamiltonian factor-critical graphs:: + + sage: [graphs.FriendshipGraph(i).is_factor_critical() for i in range(1, 5)] # needs networkx + [True, True, True, True] + + Bipartite graphs are not factor-critical:: + + sage: G = graphs.RandomBipartite(randint(1, 10), randint(1, 10), .5) # needs numpy + sage: G.is_factor_critical() # needs numpy + False + + Graphs with even order are not factor critical:: + + sage: G = graphs.RandomGNP(10, .5) + sage: G.is_factor_critical() + False + + One can specify a matching:: + + sage: F = graphs.FriendshipGraph(4) + sage: M = F.matching() # needs networkx + sage: F.is_factor_critical(matching=M) # needs networkx + True + sage: F.is_factor_critical(matching=Graph(M)) # needs networkx + True + + TESTS: + + Giving a wrong matching:: + + sage: G = graphs.RandomGNP(15, .3) + sage: while not G.is_biconnected(): + ....: G = graphs.RandomGNP(15, .3) + sage: M = G.matching() # needs networkx + sage: G.is_factor_critical(matching=M[:-1]) # needs networkx + Traceback (most recent call last): + ... + ValueError: the input is not a near perfect matching of the graph + sage: G.is_factor_critical(matching=G.edges(sort=True)) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: M = [(2*i, 2*i + 1) for i in range(9)] + sage: G.is_factor_critical(matching=M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + """ + if G.order() == 1: + return True + + # The graph must have an odd number of vertices, be 2-edge connected, so + # without bridges, and not bipartite + if (not G.order() % 2 or not G.is_connected() or + list(G.bridges()) or G.is_bipartite()): + return False + + from sage.graphs.graph import Graph + if matching: + # We check that the input matching is a valid near perfect matching + # of the graph. + M = Graph(matching) + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + if not M.is_subgraph(G, induced=False): + raise ValueError("the input is not a matching of the graph") + if (G.order() != M.order() + 1) or (G.order() != 2*M.size() + 1): + raise ValueError("the input is not a near perfect matching of the graph") + else: + # We compute a maximum matching of the graph + M = Graph(G.matching(algorithm=algorithm, solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance)) + + # It must be a near-perfect matching + if G.order() != M.order() + 1: + return False + + # We find the unsaturated vertex u, i.e., the only vertex of the graph + # not in M + for u in G: + if u not in M: + break + + # We virtually build an M-alternating tree T + from queue import Queue + Q = Queue() + Q.put(u) + even = set([u]) + odd = set() + pred = {u: u} + rank = {u: 0} + + while not Q.empty(): + x = Q.get() + for y in G.neighbor_iterator(x): + if y in odd: + continue + elif y in even: + # Search for the nearest common ancestor t of x and y + P = [x] + R = [y] + while P[-1] != R[-1]: + if rank[P[-1]] > rank[R[-1]]: + P.append(pred[P[-1]]) + elif rank[P[-1]] < rank[R[-1]]: + R.append(pred[R[-1]]) + else: + P.append(pred[P[-1]]) + R.append(pred[R[-1]]) + t = P.pop() + R.pop() + # Set t as pred of all vertices of the chains and add + # vertices marked odd to the queue + import itertools + + for a in itertools.chain(P, R): + pred[a] = t + rank[a] = rank[t] + 1 + if a in odd: + even.add(a) + odd.discard(a) + Q.put(a) + else: # y has not been visited yet + z = next(M.neighbor_iterator(y)) + odd.add(y) + even.add(z) + Q.put(z) + pred[y] = x + pred[z] = y + rank[y] = rank[x] + 1 + rank[z] = rank[y] + 1 + + # The graph is factor critical if all vertices are marked even + return len(even) == G.order() + + +def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=False, + solver=None, verbose=0, *, integrality_tolerance=0.001): + r""" + Check if the graph is matching covered. + + A connected nontrivial graph wherein each edge participates in some + perfect matching is called a *matching* *covered* *graph*. + + If a perfect matching of the graph is provided, for bipartite graph, + this method implements a linear time algorithm as proposed in [LM2024]_ + that is based on the following theorem: + + Given a connected bipartite graph `G[A, B]` with a perfect matching + `M`. Construct a directed graph `D` from `G` such that `V(D) := V(G)` + and for each edge in `G` direct the corresponding edge from `A` to `B` + in `D`, if it is in `M` or otherwise direct it from `B` to `A`. The + graph `G` is matching covered if and only if `D` is strongly connected. + + For nonbipartite graph, if a perfect matching of the graph is provided, + this method implements an `\mathcal{O}(|V| \cdot |E|)` algorithm, where + `|V|` and `|E|` are the order and the size of the graph respectively. + This implementation is inspired by the `M`-`alternating` `tree` `search` + method explained in [LZ2001]_. For nonbipartite graph, the + implementation is based on the following theorem: + + Given a nonbipartite graph `G` with a perfect matching `M`. The + graph `G` is matching covered if and only if for each edge `uv` + not in `M`, there exists an `M`-`alternating` odd length `uv`-path + starting and ending with edges not in `M`. + + The time complexity may be dominated by the time needed to compute a + maximum matching of the graph, in case a perfect matching is not + provided. Also, note that for a disconnected or a trivial or a + graph with a loop, a :class:`ValueError` is returned. + + INPUT: + + - ``matching`` -- (default: ``None``); a perfect matching of the + graph, that can be given using any valid input format of + :class:`~sage.graphs.graph.Graph`. + + If set to ``None``, a matching is computed using the other parameters. + + - ``algorithm`` -- string (default: ``'Edmonds'``); the algorithm to be + used to compute a maximum matching of the graph among + + - ``'Edmonds'`` selects Edmonds' algorithm as implemented in NetworkX, + + - ``'LP'`` uses a Linear Program formulation of the matching problem. + + - ``coNP_certificate`` -- boolean (default: ``False``); if set to + ``True`` an edge of the graph, that does not participate in any + perfect matching, is returned if `G` is not matching covered or + otherwise ``None`` is returned. + + - ``solver`` -- string (default: ``None``); specify a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: ``0``); sets the level of verbosity: + set to 0 by default, which means quiet (only useful when ``algorithm + == 'LP'``). + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: + + - A boolean indicating whether the graph is matching covered or not. + + - If ``coNP_certificate`` is set to ``True``, an edge is returned in + case the graph is not matching covered otherwise ``None`` is + returned. + + EXAMPLES: + + The Petersen graph is matching covered:: + + sage: G = graphs.PetersenGraph() + sage: G.is_matching_covered() + True + + A graph (without a self-loop) is matching covered if and only if the + underlying simple graph is matching covered:: + + sage: G = graphs.PetersenGraph() + sage: G.allow_multiple_edges(True) + sage: G.add_edge(0, 5) + sage: G.is_matching_covered() + True + + A corollary to Tutte's fundamental result [Tut1947]_, as a + strengthening of Petersen's Theorem, states that every 2-connected + cubic graph is matching covered:: + + sage: G = Graph() + sage: G.add_edges([ + ....: (0, 1), (0, 2), (0, 3), + ....: (1, 2), (1, 4), (2, 4), + ....: (3, 5), (3, 6), (4, 7), + ....: (5, 6), (5, 7), (6, 7) + ....: ]) + sage: G.vertex_connectivity() + 2 + sage: degree_sequence = G.degree_sequence() + sage: min(degree_sequence) == max(degree_sequence) == 3 + True + sage: G.is_matching_covered() + True + + A connected bipartite graph `G[A, B]`, with `|A| = |B| \geq 2`, is + matching covered if and only if `|N(X)| \geq |X| + 1`, for all + `X \subset A` such that `1 \leq |X| \leq |A| - 1`. For instance, + the Hexahedral graph is matching covered, but not the path graphs on + even number of vertices, even though they have a perfect matching:: + + sage: G = graphs.HexahedralGraph() + sage: G.is_bipartite() + True + sage: G.is_matching_covered() + True + sage: P = graphs.PathGraph(10) + sage: P.is_bipartite() + True + sage: M = Graph(P.matching()) + sage: set(P) == set(M) + True + sage: P.is_matching_covered() + False + + A connected bipartite graph `G[A, B]` of order six or more is matching + covered if and only if `G - a - b` has a perfect matching for some + vertex `a` in `A` and some vertex `b` in `B`:: + + sage: G = graphs.CircularLadderGraph(8) + sage: G.is_bipartite() + True + sage: G.is_matching_covered() + True + sage: A, B = G.bipartite_sets() + sage: # needs random + sage: import random + sage: a = random.choice(list(A)) + sage: b = random.choice(list(B)) + sage: G.delete_vertices([a, b]) + sage: M = Graph(G.matching()) + sage: set(M) == set(G) + True + sage: cycle1 = graphs.CycleGraph(4) + sage: cycle2 = graphs.CycleGraph(6) + sage: cycle2.relabel(lambda v: v + 4) + sage: H = Graph() + sage: H.add_edges(cycle1.edges() + cycle2.edges()) + sage: H.add_edge(3, 4) + sage: H.is_bipartite() + True + sage: H.is_matching_covered() + False + sage: H.delete_vertices([3, 4]) + sage: N = Graph(H.matching()) + sage: set(N) == set(H) + False + + One may specify a matching:: + + sage: G = graphs.WheelGraph(20) + sage: M = Graph(G.matching()) + sage: G.is_matching_covered(matching=M) + True + sage: J = graphs.CycleGraph(4) + sage: J.add_edge(0, 2) + sage: N = J.matching() + sage: J.is_matching_covered(matching=N) + False + + One may ask for a co-`\mathcal{NP}` certificate:: + + sage: G = graphs.CompleteGraph(14) + sage: G.is_matching_covered(coNP_certificate=True) + (True, None) + sage: H = graphs.PathGraph(20) + sage: M = H.matching() + sage: H.is_matching_covered(matching=M, coNP_certificate=True) + (False, (1, 2, None)) + + TESTS: + + If the graph is not connected:: + + sage: cycle1 = graphs.CycleGraph(4) + sage: cycle2 = graphs.CycleGraph(6) + sage: cycle2.relabel(lambda v: v + 4) + sage: G = Graph() + sage: G.add_edges(cycle1.edges() + cycle2.edges()) + sage: len(G.connected_components(sort=False)) + 2 + sage: G.is_matching_covered() + Traceback (most recent call last): + ... + ValueError: the graph is not connected + + If the graph is trivial:: + + sage: G = Graph() + sage: G.is_matching_covered() + Traceback (most recent call last): + ... + ValueError: the graph is trivial + sage: H = graphs.CycleGraph(1) + sage: H.is_matching_covered() + Traceback (most recent call last): + ... + ValueError: the graph is trivial + + Providing with a wrong matching:: + + sage: G = graphs.CompleteGraph(6) + sage: M = Graph(G.matching()) + sage: M.add_edges([(0, 1), (0, 2)]) + sage: G.is_matching_covered(matching=M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: N = Graph(G.matching()) + sage: N.add_edge(6, 7) + sage: G.is_matching_covered(matching=N) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + sage: J = Graph() + sage: J.add_edges([(0, 1), (2, 3)]) + sage: G.is_matching_covered(matching=J) + Traceback (most recent call last): + ... + ValueError: the input is not a perfect matching of the graph + + Providing with a graph with a self-loop:: + + sage: G = graphs.PetersenGraph() + sage: G.allow_loops(True) + sage: G.add_edge(0, 0) + sage: G.is_matching_covered() + Traceback (most recent call last): + ... + ValueError: This method is not known to work on graphs with loops. Perhaps this method can be updated to handle them, but in the meantime if you want to use it please disallow loops using allow_loops(). + + REFERENCES: + + - [LM2024]_ + + - [LZ2001]_ + + - [Tut1947]_ + + .. SEEALSO:: + :meth:`~sage.graphs.graph.Graph.is_factor_critical`, + :meth:`~sage.graphs.graph.Graph.is_bicritical` + + AUTHORS: + + - Janmenjaya Panda (2024-06-23) + """ + G._scream_if_not_simple(allow_multiple_edges=True) + + # The graph must be nontrivial + if G.order() < 2: + raise ValueError("the graph is trivial") + + # The graph must be connected + if not G.is_connected(): + raise ValueError("the graph is not connected") + + # The graph must have an even order + if G.order() % 2: + return (False, next(G.edge_iterator())) if coNP_certificate else False + + # If the underlying simple graph is a complete graph of order two, + # the graph is matching covered + if G.order() == 2: + return (True, None) if coNP_certificate else True + + # A graph (without a self-loop) is matching covered if and only if the + # underlying simple graph is matching covered + G_simple = G.to_simple() + + from sage.graphs.graph import Graph + if matching: + # The input matching must be a valid perfect matching of the graph + M = Graph(matching) + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + raise ValueError("the input is not a matching of the graph") + if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + raise ValueError("the input is not a perfect matching of the graph") + else: + # A maximum matching of the graph is computed + M = Graph(G_simple.matching(algorithm=algorithm, solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance)) + + # It must be a perfect matching + if G_simple.order() != M.order(): + return (False, next(M.edge_iterator())) if coNP_certificate else False + + # Biparite graph: + # + # Given a connected bipartite graph G[A, B] with a perfect matching M. + # Construct a directed graph D from G such that V(D) := V(G) and + # for each edge in G direct the corresponding edge from A to B in D, + # if it is in M or otherwise direct it from B to A. The graph G is + # matching covered if and only if D is strongly connected. + + if G_simple.is_bipartite(): + A, _ = G_simple.bipartite_sets() + color = dict() + + for u in G_simple: + color[u] = 0 if u in A else 1 + + from sage.graphs.digraph import DiGraph + H = DiGraph() + + for u, v in G_simple.edge_iterator(labels=False): + if color[u]: + u, v = v, u + + if M.has_edge(u, v): + H.add_edge(u, v) + else: + H.add_edge(v, u) + + # Check if H is strongly connected using Kosaraju's algorithm + def dfs(J, v, visited, orientation): + stack = [v] # a stack of vertices + + while stack: + v = stack.pop() + + if v not in visited: + visited[v] = True + + if orientation == 'in': + for u in J.neighbors_out(v): + if u not in visited: + stack.append(u) + + elif orientation == 'out': + for u in J.neighbors_in(v): + if u not in visited: + stack.append(u) + else: + raise ValueError('Unknown orientation') + + root = next(H.vertex_iterator()) + + visited_in = {} + dfs(H, root, visited_in, 'in') + + visited_out = {} + dfs(H, root, visited_out, 'out') + + for edge in H.edge_iterator(): + u, v, _ = edge + if (u not in visited_in) or (v not in visited_out): + if not M.has_edge(edge): + return (False, edge) if coNP_certificate else False + + return (True, None) if coNP_certificate else True + + # Nonbipartite graph: + # + # Given a nonbipartite graph G with a perfect matching M. The graph G is + # matching covered if and only if for each edge uv not in M, there exists + # an M-alternating odd length uv-path starting and ending with edges not + # in M. + + for u in G_simple: + v = next(M.neighbor_iterator(u)) + + even = M_alternating_even_mark(G_simple, u, M) + + for w in G_simple.neighbor_iterator(v): + if w != u and w not in even: + return (False, (v, w)) if coNP_certificate else False + + return (True, None) if coNP_certificate else True + + +def matching(G, value_only=False, algorithm='Edmonds', + use_edge_labels=False, solver=None, verbose=0, + *, integrality_tolerance=1e-3): + r""" + Return a maximum weighted matching of the graph represented by the list + of its edges + + For more information, see the :wikipedia:`Matching_(graph_theory)`. + + Given a graph `G` such that each edge `e` has a weight `w_e`, a maximum + matching is a subset `S` of the edges of `G` of maximum weight such that + no two edges of `S` are incident with each other. + + As an optimization problem, it can be expressed as: + + .. MATH:: + + \mbox{Maximize : }&\sum_{e\in G.edges()} w_e b_e\\ + \mbox{Such that : }&\forall v \in G, + \sum_{(u,v)\in G.edges()} b_{(u,v)}\leq 1\\ + &\forall x\in G, b_x\mbox{ is a binary variable} + + INPUT: + + - ``value_only`` -- boolean (default: ``False``); when set to ``True``, + only the cardinal (or the weight) of the matching is returned + + - ``algorithm`` -- string (default: ``'Edmonds'``) + + - ``'Edmonds'`` selects Edmonds' algorithm as implemented in NetworkX + + - ``'LP'`` uses a Linear Program formulation of the matching problem + + - ``use_edge_labels`` -- boolean (default: ``False``) + + - when set to ``True``, computes a weighted matching where each edge + is weighted by its label (if an edge has no label, `1` is assumed) + + - when set to ``False``, each edge has weight `1` + + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: 0); sets the level of verbosity: + set to 0 by default, which means quiet (only useful when ``algorithm + == "LP"``) + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: + + - When ``value_only=False`` (default), this method returns an + :class:`EdgesView` containing the edges of a maximum matching of `G`. + + - When ``value_only=True``, this method returns the sum of the + weights (default: ``1``) of the edges of a maximum matching of `G`. + The type of the output may vary according to the type of the edge + labels and the algorithm used. + + ALGORITHM: + + The problem is solved using Edmond's algorithm implemented in NetworkX, + or using Linear Programming depending on the value of ``algorithm``. + + EXAMPLES: + + Maximum matching in a Pappus Graph:: + + sage: g = graphs.PappusGraph() + sage: g.matching(value_only=True) # needs sage.networkx + 9 + + Same test with the Linear Program formulation:: + + sage: g = graphs.PappusGraph() + sage: g.matching(algorithm='LP', value_only=True) # needs sage.numerical.mip + 9 + + .. PLOT:: + + g = graphs.PappusGraph() + sphinx_plot(g.plot(edge_colors={"red":g.matching()})) + + TESTS: + + When ``use_edge_labels`` is set to ``False``, with Edmonds' algorithm + and LP formulation:: + + sage: g = Graph([(0,1,0), (1,2,999), (2,3,-5)]) + sage: sorted(g.matching()) # needs sage.networkx + [(0, 1, 0), (2, 3, -5)] + sage: sorted(g.matching(algorithm='LP')) # needs sage.numerical.mip + [(0, 1, 0), (2, 3, -5)] + + When ``use_edge_labels`` is set to ``True``, with Edmonds' algorithm and + LP formulation:: + + sage: g = Graph([(0,1,0), (1,2,999), (2,3,-5)]) + sage: g.matching(use_edge_labels=True) # needs sage.networkx + [(1, 2, 999)] + sage: g.matching(algorithm='LP', use_edge_labels=True) # needs sage.numerical.mip + [(1, 2, 999)] + + With loops and multiedges:: + + sage: edge_list = [(0,0,5), (0,1,1), (0,2,2), (0,3,3), (1,2,6) + ....: , (1,2,3), (1,3,3), (2,3,3)] + sage: g = Graph(edge_list, loops=True, multiedges=True) + sage: m = g.matching(use_edge_labels=True) # needs sage.networkx + sage: type(m) # needs sage.networkx + + sage: sorted(m) # needs sage.networkx + [(0, 3, 3), (1, 2, 6)] + + TESTS: + + If ``algorithm`` is set to anything different from ``'Edmonds'`` or + ``'LP'``, an exception is raised:: + + sage: g = graphs.PappusGraph() + sage: g.matching(algorithm='somethingdifferent') + Traceback (most recent call last): + ... + ValueError: algorithm must be set to either "Edmonds" or "LP" + """ + from sage.rings.real_mpfr import RR + + def weight(x): + if x in RR: + return x + else: + return 1 + + W = {} + L = {} + for u, v, l in G.edge_iterator(): + if u is v: + continue + fuv = frozenset((u, v)) + if fuv not in L or (use_edge_labels and W[fuv] < weight(l)): + L[fuv] = l + if use_edge_labels: + W[fuv] = weight(l) + + if algorithm == "Edmonds": + import networkx + g = networkx.Graph() + if use_edge_labels: + for (u, v), w in W.items(): + g.add_edge(u, v, weight=w) + else: + for u, v in L: + g.add_edge(u, v) + d = networkx.max_weight_matching(g) + if value_only: + if use_edge_labels: + return sum(W[frozenset(e)] for e in d) + return Integer(len(d)) + + from sage.graphs.graph import Graph + return EdgesView(Graph([(u, v, L[frozenset((u, v))]) for u, v in d], + format='list_of_edges')) + + elif algorithm == "LP": + g = G + from sage.numerical.mip import MixedIntegerLinearProgram + # returns the weight of an edge considering it may not be + # weighted ... + p = MixedIntegerLinearProgram(maximization=True, solver=solver) + b = p.new_variable(binary=True) + if use_edge_labels: + p.set_objective(p.sum(w * b[fe] for fe, w in W.items())) + else: + p.set_objective(p.sum(b[fe] for fe in L)) + # for any vertex v, there is at most one edge incident to v in + # the maximum matching + for v in g: + p.add_constraint(p.sum(b[frozenset(e)] for e in G.edge_iterator(vertices=[v], labels=False) + if e[0] != e[1]), max=1) + + p.solve(log=verbose) + b = p.get_values(b, convert=bool, tolerance=integrality_tolerance) + if value_only: + if use_edge_labels: + return sum(w for fe, w in W.items() if b[fe]) + return Integer(sum(1 for fe in L if b[fe])) + + from sage.graphs.graph import Graph + return EdgesView(Graph([(u, v, L[frozenset((u, v))]) + for u, v in L if b[frozenset((u, v))]], + format='list_of_edges')) + + raise ValueError('algorithm must be set to either "Edmonds" or "LP"') + + +def perfect_matchings(G, labels=False): + r""" + Return an iterator over all perfect matchings of the graph + + ALGORITHM: + + Choose a vertex `v`, then recurse through all edges incident to `v`, + removing one edge at a time whenever an edge is added to a matching. + + INPUT: + + - ``labels`` -- boolean (default: ``False``); when ``True``, the edges + in each perfect matching are triples (containing the label as the + third element), otherwise the edges are pairs. + + .. SEEALSO:: + + :meth:`matching` + + EXAMPLES:: + + sage: G=graphs.GridGraph([2,3]) + sage: for m in G.perfect_matchings(): + ....: print(sorted(m)) + [((0, 0), (0, 1)), ((0, 2), (1, 2)), ((1, 0), (1, 1))] + [((0, 0), (1, 0)), ((0, 1), (0, 2)), ((1, 1), (1, 2))] + [((0, 0), (1, 0)), ((0, 1), (1, 1)), ((0, 2), (1, 2))] + + sage: G = graphs.CompleteGraph(4) + sage: for m in G.perfect_matchings(labels=True): + ....: print(sorted(m)) + [(0, 1, None), (2, 3, None)] + [(0, 2, None), (1, 3, None)] + [(0, 3, None), (1, 2, None)] + + sage: G = Graph([[1,-1,'a'], [2,-2, 'b'], [1,-2,'x'], [2,-1,'y']]) + sage: sorted(sorted(m) for m in G.perfect_matchings(labels=True)) + [[(-2, 1, 'x'), (-1, 2, 'y')], [(-2, 2, 'b'), (-1, 1, 'a')]] + + sage: G = graphs.CompleteGraph(8) + sage: mpc = G.matching_polynomial().coefficients(sparse=False)[0] # needs sage.libs.flint + sage: len(list(G.perfect_matchings())) == mpc # needs sage.libs.flint + True + + sage: G = graphs.PetersenGraph().copy(immutable=True) + sage: [sorted(m) for m in G.perfect_matchings()] + [[(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)], + [(0, 1), (2, 7), (3, 4), (5, 8), (6, 9)], + [(0, 4), (1, 2), (3, 8), (5, 7), (6, 9)], + [(0, 4), (1, 6), (2, 3), (5, 8), (7, 9)], + [(0, 5), (1, 2), (3, 4), (6, 8), (7, 9)], + [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]] + + sage: list(Graph().perfect_matchings()) + [[]] + + sage: G = graphs.CompleteGraph(5) + sage: list(G.perfect_matchings()) + [] + """ + if not G: + yield [] + return + if G.order() % 2 or any(len(cc) % 2 for cc in G.connected_components(sort=False)): + return + + def rec(G): + """ + Iterator over all perfect matchings of a simple graph `G`. + """ + if not G: + yield [] + return + if G.order() % 2 == 0: + v = next(G.vertex_iterator()) + Nv = list(G.neighbor_iterator(v)) + G.delete_vertex(v) + for u in Nv: + Nu = list(G.neighbor_iterator(u)) + G.delete_vertex(u) + for partial_matching in rec(G): + partial_matching.append((u, v)) + yield partial_matching + G.add_vertex(u) + G.add_edges((u, nu) for nu in Nu) + G.add_vertex(v) + G.add_edges((v, nv) for nv in Nv) + + # We create a mutable copy of the graph and remove its loops, if any + G_copy = G.copy(immutable=False) + G_copy.allow_loops(False) + + # We create a mapping from frozen unlabeled edges to (labeled) edges. + # This ease for instance the manipulation of multiedges (if any) + edges = {} + for e in G_copy.edges(sort=False, labels=labels): + f = frozenset(e[:2]) + if f in edges: + edges[f].append(e) + else: + edges[f] = [e] + + # We now get rid of multiple edges, if any + G_copy.allow_multiple_edges(False) + + # For each unlabeled matching, we yield all its possible labelings + import itertools + + for m in rec(G_copy): + yield from itertools.product(*[edges[frozenset(e)] for e in m]) + + +def M_alternating_even_mark(G, vertex, matching): + r""" + Return the vertices reachable from ``vertex`` via an even alternating path + starting with a non-matching edge + + This method implements the algorithm proposed in [LR2004]_. Note that + the complexity of the algorithm is linear in number of edges. + + INPUT: + + - ``vertex`` -- a vertex of the graph + + - ``matching`` -- a matching of the graph; it can be given using any + valid input format of :class:`~sage.graphs.graph.Graph` + + OUTPUT: + + - ``even`` -- the set of vertices each of which is reachable from the + provided vertex through a path starting with an edge not in the + matching and ending with an edge in the matching; note that a note that a + :class:`ValueError` is returned if the graph is not simple + + EXAMPLES: + + Show the list of required vertices for a graph `G` with a matching `M` + for a vertex `u`:: + + sage: G = graphs.CycleGraph(3) + sage: M = G.matching() + sage: M + [(0, 2, None)] + sage: from sage.graphs.matching import M_alternating_even_mark + sage: S0 = M_alternating_even_mark(G, 0, M) + sage: S0 + {0} + sage: S1 = M_alternating_even_mark(G, 1, M) + sage: S1 + {0, 1, 2} + + The result is equivalent for the underlying simple graph of the provided + graph, if the other parameters provided are the same:: + + sage: G = graphs.CompleteBipartiteGraph(3, 3) + sage: G.allow_multiple_edges(True) + sage: G.add_edge(0, 3) + sage: M = G.matching() + sage: u = 0 + sage: from sage.graphs.matching import M_alternating_even_mark + sage: S = M_alternating_even_mark(G, u, M) + sage: S + {0, 1, 2} + sage: T = M_alternating_even_mark(G.to_simple(), u, M) + sage: T + {0, 1, 2} + + For a factor critical graph `G` (for instance, a wheel graph of an odd + order) with a near perfect matching `M` and `u` being the (unique) + `M`-exposed vertex, each vertex in `G` is reachable from `u` through an + even length `M`-alternating path as described above:: + + sage: G = graphs.WheelGraph(11) + sage: M = Graph(G.matching()) + sage: G.is_factor_critical(M) + True + sage: for v in G: + ....: if v not in M: + ....: break + ....: + sage: from sage.graphs.matching import M_alternating_even_mark + sage: S = M_alternating_even_mark(G, v, M) + sage: S == set(G) + True + + For a matching covered graph `G` (for instance, `K_4 \odot K_{3,3}`) with a + perfect matching `M` and for some vertex `u` with `v` being its `M`-matched + neighbor, each neighbor of `v` is reachable from `u` through an even length + `M`-alternating path as described above:: + + sage: G = Graph() + sage: G.add_edges([ + ....: (0, 2), (0, 3), (0, 4), (1, 2), + ....: (1, 3), (1, 4), (2, 5), (3, 6), + ....: (4, 7), (5, 6), (5, 7), (6, 7) + ....: ]) + sage: M = Graph(G.matching()) + sage: G.is_matching_covered(M) + True + sage: u = 0 + sage: v = next(M.neighbor_iterator(u)) + sage: from sage.graphs.matching import M_alternating_even_mark + sage: S = M_alternating_even_mark(G, u, M) + sage: (set(G.neighbor_iterator(v))).issubset(S) + True + + For a bicritical graph `G` (for instance, the Petersen graph) with a + perfect matching `M` and for some vertex `u` with its `M`-matched neighbor + being `v`, each vertex of the graph distinct from `v` is reachable from `u` + through an even length `M`-alternating path as described above:: + + sage: G = graphs.PetersenGraph() + sage: M = Graph(G.matching()) + sage: G.is_bicritical(M) + True + sage: import random + sage: u = random.choice(list(G)) # needs random + sage: v = next(M.neighbor_iterator(u)) + sage: from sage.graphs.matching import M_alternating_even_mark + sage: S = M_alternating_even_mark(G, u, M) + sage: S == (set(G) - {v}) + True + + TESTS: + + Giving a wrong vertex:: + + sage: G = graphs.HexahedralGraph() + sage: M = G.matching() + sage: u = G.order() + sage: from sage.graphs.matching import M_alternating_even_mark + sage: S = M_alternating_even_mark(G, u, M) + Traceback (most recent call last): + ... + ValueError: '8' is not a vertex of the graph + + Giving a wrong matching:: + + sage: from sage.graphs.matching import M_alternating_even_mark + sage: G = graphs.CompleteGraph(6) + sage: M = [(0, 1), (0, 2)] + sage: u = 0 + sage: S = M_alternating_even_mark(G, u, M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: G = graphs.CompleteBipartiteGraph(3, 3) + sage: M = [(2*i, 2*i + 1) for i in range(4)] + sage: u = 0 + sage: S = M_alternating_even_mark(G, u, M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + + REFERENCES: + + - [LR2004]_ + + .. SEEALSO:: + :meth:`~sage.graphs.graph.Graph.is_factor_critical`, + :meth:`~sage.graphs.graph.Graph.is_matching_covered`, + :meth:`~sage.graphs.graph.Graph.is_bicritical` + + AUTHORS: + + - Janmenjaya Panda (2024-06-17) + """ + # The input vertex must be a valid vertex of the graph + if vertex not in G: + raise ValueError("'{}' is not a vertex of the graph".format(vertex)) + + # The result is equivalent for the underlying simple graph of the provided + # graph. So, the underlying simple graph is considered for implementational + # simplicity. + G_simple = G.to_simple() + + # The input matching must be a valid matching of the graph + from sage.graphs.graph import Graph + M = Graph(matching) + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + raise ValueError("the input is not a matching of the graph") + + # Build an M-alternating tree T rooted at vertex + import itertools + from queue import Queue + + q = Queue() + q.put(vertex) + + even = set([vertex]) + odd = set() + predecessor = {vertex: vertex} + rank = {vertex: 0} + + if vertex in M: + u = next(M.neighbor_iterator(vertex)) + predecessor[u] = None + rank[u] = -1 + odd.add(u) + + while not q.empty(): + x = q.get() + for y in G_simple.neighbor_iterator(x): + if y in odd: + continue + elif y in even: + # Search t := LCA(x, y) + ancestor_x = [x] + ancestor_y = [y] + + # Loop over until the nearest common ancestor of x and y is reached + while ancestor_x[-1] != ancestor_y[-1]: + if rank[ancestor_x[-1]] > rank[ancestor_y[-1]]: + ancestor_x.append(predecessor[ancestor_x[-1]]) + elif rank[ancestor_x[-1]] < rank[ancestor_y[-1]]: + ancestor_y.append(predecessor[ancestor_y[-1]]) + else: + ancestor_x.append(predecessor[ancestor_x[-1]]) + ancestor_y.append(predecessor[ancestor_y[-1]]) + + lcs = ancestor_x.pop() + ancestor_y.pop() + # Set t as pred of all vertices of the chains and add + # vertices marked odd to the queue + next_rank_to_lcs_rank = rank[lcs] + 1 + for a in itertools.chain(ancestor_x, ancestor_y): + predecessor[a] = lcs + rank[a] = next_rank_to_lcs_rank + + if a in odd: + even.add(a) + odd.discard(a) + q.put(a) + + elif y in M: + # y has not been visited yet + z = next(M.neighbor_iterator(y)) + odd.add(y) + even.add(z) + q.put(z) + + predecessor[y] = x + predecessor[z] = y + + rank[y] = rank[x] + 1 + rank[z] = rank[y] + 1 + + return even \ No newline at end of file diff --git a/src/sage/graphs/matchpoly.pyx b/src/sage/graphs/matchpoly.pyx index b289679d7b2..4fe8549ad6c 100644 --- a/src/sage/graphs/matchpoly.pyx +++ b/src/sage/graphs/matchpoly.pyx @@ -10,7 +10,7 @@ This module contains the following methods: :widths: 30, 70 :delim: | - :meth:`matching_polynomial` | Computes the matching polynomial of a given graph + :meth:`matching_polynomial` | Compute the matching polynomial of a given graph. :meth:`complete_poly` | Compute the matching polynomial of the complete graph on `n` vertices. AUTHORS: @@ -53,7 +53,7 @@ x = polygen(ZZ, 'x') def matching_polynomial(G, complement=True, name=None): r""" - Computes the matching polynomial of the graph `G`. + Compute the matching polynomial of the graph `G`. If `p(G, k)` denotes the number of `k`-matchings (matchings with `k` edges) in `G`, then the matching polynomial is defined as [God1993]_: @@ -64,11 +64,11 @@ def matching_polynomial(G, complement=True, name=None): INPUT: - - ``complement`` -- (default: ``True``) whether to use Godsil's duality + - ``complement`` -- boolean (default: ``True``); whether to use Godsil's duality theorem to compute the matching polynomial from that of the graphs - complement (see ALGORITHM). + complement (see ALGORITHM) - - ``name`` -- optional string for the variable name in the polynomial + - ``name`` -- (optional) string for the variable name in the polynomial .. NOTE:: diff --git a/src/sage/graphs/mcqd.pyx b/src/sage/graphs/mcqd.pyx index 1399a8d6257..6e6be4389cc 100644 --- a/src/sage/graphs/mcqd.pyx +++ b/src/sage/graphs/mcqd.pyx @@ -7,11 +7,11 @@ from memory_allocator cimport MemoryAllocator def mcqd(G): """ - Computes the max clique using MCQD + Compute the max clique using MCQD. INPUT: - - ``G`` -- A graph + - ``G`` -- a graph TESTS:: diff --git a/src/sage/graphs/meson.build b/src/sage/graphs/meson.build new file mode 100644 index 00000000000..dbc1808f107 --- /dev/null +++ b/src/sage/graphs/meson.build @@ -0,0 +1,138 @@ +bliss = cc.find_library('bliss', required: false, disabler: true) +mcqd = cc.find_library('mcqd', required: false, disabler: true) +cliquer = cc.find_library('cliquer') + +# Cannot be found via pkg-config +planarity = cc.find_library('planarity') + +py.install_sources( + 'all.py', + 'all__sagemath_bliss.py', + 'all__sagemath_mcqd.py', + 'all__sagemath_tdlib.py', + 'bipartite_graph.py', + 'cliquer.pxd', + 'cographs.py', + 'connectivity.pxd', + 'convexity_properties.pxd', + 'digraph.py', + 'digraph_generators.py', + 'distances_all_pairs.pxd', + 'domination.py', + 'dot2tex_utils.py', + 'generic_graph.py', + 'generic_graph_pyx.pxd', + 'graph.py', + 'graph_database.py', + 'graph_editor.py', + 'graph_generators.py', + 'graph_input.py', + 'graph_latex.py', + 'graph_list.py', + 'graph_plot.py', + 'graph_plot_js.py', + 'hypergraph_generators.py', + 'independent_sets.pxd', + 'isgci.py', + 'lovasz_theta.py', + 'matching.py', + 'mcqd.pxd', + 'orientations.py', + 'partial_cube.py', + 'pq_trees.py', + 'print_graphs.py', + 'schnyder.py', + 'traversals.pxd', + 'trees.pxd', + 'tutte_polynomial.py', + subdir: 'sage/graphs', +) + +extension_data = { + 'asteroidal_triples' : files('asteroidal_triples.pyx'), + 'centrality' : files('centrality.pyx'), + 'chrompoly' : files('chrompoly.pyx'), + 'cliquer' : files('cliquer.pyx'), + 'comparability' : files('comparability.pyx'), + 'connectivity' : files('connectivity.pyx'), + 'convexity_properties' : files('convexity_properties.pyx'), + 'distances_all_pairs' : files('distances_all_pairs.pyx'), + 'generic_graph_pyx' : files('generic_graph_pyx.pyx'), + 'genus' : files('genus.pyx'), + 'graph_generators_pyx' : files('graph_generators_pyx.pyx'), + 'hyperbolicity' : files('hyperbolicity.pyx'), + 'independent_sets' : files('independent_sets.pyx'), + 'isoperimetric_inequalities' : files('isoperimetric_inequalities.pyx'), + 'line_graph' : files('line_graph.pyx'), + 'matchpoly' : files('matchpoly.pyx'), + 'planarity' : files('planarity.pyx'), + 'spanning_tree' : files('spanning_tree.pyx'), + 'strongly_regular_db' : files('strongly_regular_db.pyx'), + 'trees' : files('trees.pyx'), + 'views' : files('views.pyx'), + 'weakly_chordal' : files('weakly_chordal.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/graphs', + install: true, + include_directories: [ + inc_cpython, + inc_data_structures, + inc_flint, + inc_rings, + ], + dependencies: [py_dep, cysignals, cliquer, flint, gmp, planarity], + ) +endforeach + +extension_data_cpp = { + 'edge_connectivity': files('edge_connectivity.pyx'), + 'graph_coloring': files('graph_coloring.pyx'), + 'path_enumeration': files('path_enumeration.pyx'), + 'traversals': files('traversals.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/graphs', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_data_structures, + inc_flint, + inc_rings, + ], + dependencies: [py_dep, cysignals, flint, gmp, planarity], + ) +endforeach + +py.extension_module( + 'bliss', + sources: files('bliss.pyx'), + subdir: 'sage/graphs', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_data_structures, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, bliss], +) + +py.extension_module( + 'mcqd', + sources: files('mcqd.pyx'), + subdir: 'sage/graphs', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_data_structures, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, mcqd], +) + +subdir('base') +subdir('generators') +subdir('graph_decompositions') diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 1ecb283ba2a..26dc4df7722 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -12,6 +12,8 @@ :widths: 30, 70 :delim: | + :meth:`orient` | Return an oriented version of `G` according the input function `f`. + :meth:`acyclic_orientations` | Return an iterator over all acyclic orientations of an undirected graph `G`. :meth:`strong_orientations_iterator` | Return an iterator over all strong orientations of a graph `G` :meth:`random_orientation` | Return a random orientation of a graph `G` @@ -28,7 +30,7 @@ # **************************************************************************** # Copyright (C) 2017 Kolja Knauer # 2017 Petru Valicov -# 2017-2023 David Coudert +# 2017-2024 David Coudert # # 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 @@ -41,6 +43,183 @@ from sage.graphs.digraph import DiGraph +def orient(G, f, weighted=None, data_structure=None, sparse=None, + immutable=None, hash_labels=None): + r""" + Return an oriented version of `G` according the input function `f`. + + INPUT: + + - ``G`` -- an undirected graph + + - ``f`` -- a function that inputs an edge and outputs an orientation of this + edge + + - ``weighted`` -- boolean (default: ``None``); weightedness for the oriented + digraph. By default (``None``), the graph and its orientation will behave + the same. + + - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an alias for + ``data_structure="sparse"``, and ``sparse=False`` is an alias for + ``data_structure="dense"``. Only used when ``data_structure=None``. + + - ``data_structure`` -- string (default: ``None``); one of ``'sparse'``, + ``'static_sparse'``, or ``'dense'``. See the documentation of + :class:`DiGraph`. + + - ``immutable`` -- boolean (default: ``None``); whether to create a + mutable/immutable digraph. Only used when ``data_structure=None``. + + * ``immutable=None`` (default) means that the graph and its orientation + will behave the same way. + + * ``immutable=True`` is a shortcut for ``data_structure='static_sparse'`` + + * ``immutable=False`` means that the created digraph is mutable. When used + to orient an immutable graph, the data structure used is ``'sparse'`` + unless anything else is specified. + + - ``hash_labels`` -- boolean (default: ``None``); whether to include edge + labels during hashing of the oriented digraph. This parameter defaults to + ``True`` if the graph is weighted. This parameter is ignored when + parameter ``immutable`` is not ``True``. Beware that trying to hash + unhashable labels will raise an error. + + OUTPUT: a :class:`DiGraph` object + + .. NOTE:: + + This method behaves similarly to method + :meth:`~sage.graphs.generic_graph.GenericGraph.copy`. That is, the + returned digraph uses the same data structure by default, unless the + user asks to use another data structure, and the attributes of the input + graph are copied. + + EXAMPLES:: + + sage: G = graphs.CycleGraph(4); G + Cycle graph: Graph on 4 vertices + sage: D = G.orient(lambda e:e if e[0] < e[1] else (e[1], e[0], e[2])); D + Orientation of Cycle graph: Digraph on 4 vertices + sage: sorted(D.edges(labels=False)) + [(0, 1), (0, 3), (1, 2), (2, 3)] + + TESTS: + + We make sure that one can get an immutable orientation by providing the + ``data_structure`` optional argument:: + + sage: def foo(e): + ....: return e if e[0] < e[1] else (e[1], e[0], e[2]) + sage: G = graphs.CycleGraph(4) + sage: D = G.orient(foo, data_structure='static_sparse') + sage: D.is_immutable() + True + sage: D = G.orient(foo, immutable=True) + sage: D.is_immutable() + True + + Bad input:: + + sage: G.orient(foo, data_structure='sparse', sparse=False) + Traceback (most recent call last): + ... + ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value + sage: G.orient(foo, data_structure='sparse', immutable=True) + Traceback (most recent call last): + ... + ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value + sage: G.orient(foo, immutable=True, sparse=False) + Traceback (most recent call last): + ... + ValueError: there is no dense immutable backend at the moment + + Which backend? :: + + sage: G.orient(foo, data_structure='sparse')._backend + + sage: G.orient(foo, data_structure='dense')._backend + + sage: G.orient(foo, data_structure='static_sparse')._backend + + sage: G.orient(foo, immutable=True)._backend + + sage: G.orient(foo, immutable=True, sparse=True)._backend + + sage: G.orient(foo, immutable=False, sparse=True)._backend + + sage: G.orient(foo, immutable=False, sparse=False)._backend + + sage: G.orient(foo, data_structure=None, immutable=None, sparse=True)._backend + + sage: G.orient(foo, data_structure=None, immutable=None, sparse=False)._backend + + sage: G.orient(foo, data_structure=None, immutable=None, sparse=None)._backend + + sage: H = Graph(data_structure='dense') + sage: H.orient(foo, data_structure=None, immutable=None, sparse=None)._backend + + """ + # Which data structure should be used ? + if data_structure is not None: + # data_structure is already defined so there is nothing left to do + # here. Did the user try to define too much ? + if immutable is not None or sparse is not None: + raise ValueError("you cannot define 'immutable' or 'sparse' " + "when 'data_structure' has a value") + # At this point, data_structure is None. + elif immutable is True: + data_structure = 'static_sparse' + if sparse is False: + raise ValueError("there is no dense immutable backend at the moment") + elif immutable is False: + # If the user requests a mutable digraph and input is immutable, we + # choose the 'sparse' cgraph backend. Unless the user explicitly + # asked for something different. + if G.is_immutable(): + data_structure = 'dense' if sparse is False else 'sparse' + elif sparse is True: + data_structure = "sparse" + elif sparse is False: + data_structure = "dense" + + if data_structure is None: + from sage.graphs.base.dense_graph import DenseGraphBackend + if isinstance(G._backend, DenseGraphBackend): + data_structure = "dense" + else: + data_structure = "sparse" + + if weighted is None: + weighted = G.weighted() + + edges = (f(e) for e in G.edge_iterator()) + D = DiGraph([G, edges], format='vertices_and_edges', + data_structure=data_structure, + loops=G.allows_loops(), + multiedges=G.allows_multiple_edges(), + name=f"Orientation of {G.name()}", + pos=copy(G._pos), weighted=weighted, + hash_labels=hash_labels) + + attributes_to_copy = ('_assoc', '_embedding') + for attr in attributes_to_copy: + if hasattr(G, attr): + copy_attr = {} + old_attr = getattr(G, attr) + if isinstance(old_attr, dict): + for v, value in old_attr.items(): + try: + copy_attr[v] = value.copy() + except AttributeError: + copy_attr[v] = copy(value) + setattr(D, attr, copy_attr) + else: + setattr(D, attr, copy(old_attr)) + + return D + + def acyclic_orientations(G): r""" Return an iterator over all acyclic orientations of an undirected graph `G`. @@ -61,32 +240,41 @@ def acyclic_orientations(G): INPUT: - - ``G`` -- an undirected graph. - - OUTPUT: + - ``G`` -- an undirected graph - - An iterator over all acyclic orientations of the input graph. + OUTPUT: an iterator over all acyclic orientations of the input graph .. NOTE:: - The function assumes that the input graph is undirected and the edges are unlabelled. + The function assumes that the input graph is undirected and the edges + are unlabelled. EXAMPLES: - To count number acyclic orientations for a graph:: + To count the number of acyclic orientations for a graph:: sage: g = Graph([(0, 3), (0, 4), (3, 4), (1, 3), (1, 2), (2, 3), (2, 4)]) sage: it = g.acyclic_orientations() sage: len(list(it)) 54 - Test for arbitary vertex labels:: + Test for arbitrary vertex labels:: - sage: g_str = Graph([('abc', 'def'), ('ghi', 'def'), ('xyz', 'abc'), ('xyz', 'uvw'), ('uvw', 'abc'), ('uvw', 'ghi')]) + sage: g_str = Graph([('abc', 'def'), ('ghi', 'def'), ('xyz', 'abc'), + ....: ('xyz', 'uvw'), ('uvw', 'abc'), ('uvw', 'ghi')]) sage: it = g_str.acyclic_orientations() sage: len(list(it)) 42 + Check that the method returns properly relabeled acyclic digraphs:: + + sage: g = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)]) + sage: orientations = set([frozenset(d.edges(labels=false)) for d in g.acyclic_orientations()]) + sage: len(orientations) + 18 + sage: all(d.is_directed_acyclic() for d in g.acyclic_orientations()) + True + TESTS: To count the number of acyclic orientations for a graph with 0 vertices:: @@ -125,7 +313,6 @@ def acyclic_orientations(G): sage: len(list(Graph([(0, 1), (1, 2), (2, 0)]).acyclic_orientations())) 6 - """ if not G.size(): # A graph without edge cannot be oriented @@ -294,8 +481,9 @@ def helper(G, globO, m, k): # Iterate over acyclic orientations and create relabeled graphs for orientation in orientations: - relabeled_graph = DiGraph([(reverse_vertex_labels[u], reverse_vertex_labels[v], label) for (u, v), label in orientation.items()]) - yield relabeled_graph + D = DiGraph([(u, v) if label else (v, u) for (u, v), label in orientation.items()]) + D.relabel(perm=reverse_vertex_labels, inplace=True) + yield D def strong_orientations_iterator(G): @@ -326,11 +514,9 @@ def strong_orientations_iterator(G): INPUT: - - ``G`` -- an undirected graph. - - OUTPUT: + - ``G`` -- an undirected graph - - an iterator which will produce all strong orientations of this graph. + OUTPUT: an iterator which will produce all strong orientations of this graph .. NOTE:: @@ -447,17 +633,15 @@ def _strong_orientations_of_a_mixed_graph(Dg, V, E): INPUT: - - ``Dg`` -- the mixed graph. The undirected edges are doubly oriented. + - ``Dg`` -- the mixed graph. The undirected edges are doubly oriented - ``V`` -- the set of vertices - ``E`` -- the set of undirected edges (they are oriented in both ways); - No labels are allowed. - - OUTPUT: + no labels are allowed - - an iterator which will produce all strong orientations of the input - partially directed graph. + OUTPUT: an iterator which will produce all strong orientations of the input + partially directed graph EXAMPLES:: @@ -474,7 +658,7 @@ def _strong_orientations_of_a_mixed_graph(Dg, V, E): while i < length: u, v = E[i] Dg.delete_edge(u, v) - if not (v in Dg.depth_first_search(u)): + if v not in Dg.depth_first_search(u): # del E[i] in constant time E[i] = E[-1] E.pop() @@ -485,7 +669,7 @@ def _strong_orientations_of_a_mixed_graph(Dg, V, E): else: Dg.add_edge(u, v) Dg.delete_edge(v, u) - if not (u in Dg.depth_first_search(v)): + if u not in Dg.depth_first_search(v): # del E[i] in constant time E[i] = E[-1] E.pop() @@ -524,7 +708,7 @@ def random_orientation(G): INPUT: - - ``G`` -- a Graph. + - ``G`` -- a Graph EXAMPLES:: diff --git a/src/sage/graphs/partial_cube.py b/src/sage/graphs/partial_cube.py index 79b1edc957c..7512f5acd1f 100644 --- a/src/sage/graphs/partial_cube.py +++ b/src/sage/graphs/partial_cube.py @@ -23,7 +23,7 @@ **Tokens** and their **action**: in the terminology of [Epp2008]_, a token represents a transition of the form: - *switch the k-th bit of the binary string from 0 to 1* + *switch the `k`-th bit of the binary string from 0 to 1* Each token can be matched with a 'reversed' token that performs the same switch in the opposite direction. Alternatively, a token can be @@ -104,9 +104,9 @@ def breadth_first_level_search(G, start): INPUT: - - ``G`` -- a graph to perform the search on. + - ``G`` -- a graph to perform the search on - - ``start`` -- vertex or list of vertices from which to start the traversal. + - ``start`` -- vertex or list of vertices from which to start the traversal EXAMPLES:: @@ -120,7 +120,6 @@ def breadth_first_level_search(G, start): '20': set(), '21': set(), '22': set()}] - """ neighbors = G.neighbor_out_iterator visited = set() @@ -150,9 +149,9 @@ def depth_first_traversal(G, start): INPUT: - - ``G`` -- a graph to perform the search on. + - ``G`` -- a graph to perform the search on - - ``start`` -- vertex or list of vertices from which to start the traversal. + - ``start`` -- vertex or list of vertices from which to start the traversal OUTPUT: diff --git a/src/sage/graphs/path_enumeration.pyx b/src/sage/graphs/path_enumeration.pyx index d9f12035528..50b992692e4 100644 --- a/src/sage/graphs/path_enumeration.pyx +++ b/src/sage/graphs/path_enumeration.pyx @@ -57,7 +57,7 @@ def all_paths(G, start, end, use_multiedges=False, report_edges=False, labels=Fa - ``end`` -- a vertex of a graph, where to end - ``use_multiedges`` -- boolean (default: ``False``); this parameter is - used only if the graph has multiple edges. + used only if the graph has multiple edges - If ``False``, the graph is considered as simple and an edge label is arbitrarily selected for each edge as in @@ -203,7 +203,6 @@ def all_paths(G, start, end, use_multiedges=False, report_edges=False, labels=Fa [[(0, 3), (3, 5)]] sage: G.all_paths(0, 5, report_edges=True, use_multiedges=True) [[(0, 3), (3, 5)], [(0, 3), (3, 5)]] - """ if start not in G: raise LookupError("start vertex ({0}) is not a vertex of the graph".format(start)) @@ -320,15 +319,15 @@ def shortest_simple_paths(self, source, target, weight_function=None, in the graph are weighted, otherwise all edges have weight 1 - ``check_weight`` -- boolean (default: ``True``); whether to check that the - ``weight_function`` outputs a number for each edge. + ``weight_function`` outputs a number for each edge - ``algorithm`` -- string (default: ``None``); the algorithm to use in computing ``k`` shortest paths of ``self``. The following algorithms are supported: - - ``"Yen"`` -- Yen's algorithm [Yen1970]_ + - ``'Yen'`` -- Yen's algorithm [Yen1970]_ - - ``"Feng"`` -- an improved version of Yen's algorithm but that works only + - ``'Feng'`` -- an improved version of Yen's algorithm but that works only for directed graphs [Feng2014]_ - ``report_edges`` -- boolean (default: ``False``); whether to report paths @@ -347,9 +346,9 @@ def shortest_simple_paths(self, source, target, weight_function=None, sage: g = DiGraph([(1, 2, 20), (1, 3, 10), (1, 4, 30), ....: (2, 5, 20), (3, 5, 10), (4, 5, 30)]) - sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm="Yen")) + sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm='Yen')) [[1, 3, 5], [1, 2, 5], [1, 4, 5]] - sage: list(g.shortest_simple_paths(1, 5, algorithm="Yen")) + sage: list(g.shortest_simple_paths(1, 5, algorithm='Yen')) [[1, 2, 5], [1, 3, 5], [1, 4, 5]] sage: list(g.shortest_simple_paths(1, 1)) [[1]] @@ -358,21 +357,21 @@ def shortest_simple_paths(self, source, target, weight_function=None, [(20, [(1, 3, 10), (3, 5, 10)]), (40, [(1, 2, 20), (2, 5, 20)]), (60, [(1, 4, 30), (4, 5, 30)])] - sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm="Feng", + sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm='Feng', ....: report_edges=True, report_weight=True)) [(20, [(1, 3), (3, 5)]), (40, [(1, 2), (2, 5)]), (60, [(1, 4), (4, 5)])] sage: list(g.shortest_simple_paths(1, 5, report_edges=True, report_weight=True)) [(2, [(1, 4), (4, 5)]), (2, [(1, 3), (3, 5)]), (2, [(1, 2), (2, 5)])] sage: list(g.shortest_simple_paths(1, 5, by_weight=True, report_edges=True)) [[(1, 3), (3, 5)], [(1, 2), (2, 5)], [(1, 4), (4, 5)]] - sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm="Feng", + sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm='Feng', ....: report_edges=True, labels=True)) [[(1, 3, 10), (3, 5, 10)], [(1, 2, 20), (2, 5, 20)], [(1, 4, 30), (4, 5, 30)]] sage: g = Graph([(1, 2, 20), (1, 3, 10), (1, 4, 30), (2, 5, 20), ....: (3, 5, 10), (4, 5, 30), (1, 6, 100), (5, 6, 5)]) sage: list(g.shortest_simple_paths(1, 6, by_weight = True)) [[1, 3, 5, 6], [1, 2, 5, 6], [1, 4, 5, 6], [1, 6]] - sage: list(g.shortest_simple_paths(1, 6, algorithm="Yen")) + sage: list(g.shortest_simple_paths(1, 6, algorithm='Yen')) [[1, 6], [1, 2, 5, 6], [1, 3, 5, 6], [1, 4, 5, 6]] sage: list(g.shortest_simple_paths(1, 6, ....: report_edges=True, report_weight=True, labels=True)) @@ -404,7 +403,7 @@ def shortest_simple_paths(self, source, target, weight_function=None, ....: (5, 6, 100), (4, 7, 3), (7, 6, 4), (3, 8, 5), ....: (8, 9, 2), (9, 6, 2), (9, 10, 7), (9, 11, 10), ....: (11, 6, 8), (10, 6, 2)]) - sage: list(g.shortest_simple_paths(1, 6, algorithm="Yen", by_weight=True)) + sage: list(g.shortest_simple_paths(1, 6, algorithm='Yen', by_weight=True)) [[1, 2, 3, 4, 7, 6], [1, 2, 3, 8, 9, 6], [1, 2, 3, 8, 9, 10, 6], @@ -422,7 +421,7 @@ def shortest_simple_paths(self, source, target, weight_function=None, (18, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 10, 7), (6, 10, 2)]), (27, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 11, 10), (6, 11, 8)]), (105, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 2), (5, 6, 100)])] - sage: list(g.shortest_simple_paths(1, 6, algorithm="Yen")) + sage: list(g.shortest_simple_paths(1, 6, algorithm='Yen')) [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 7, 6], [1, 2, 3, 8, 9, 6], @@ -432,7 +431,7 @@ def shortest_simple_paths(self, source, target, weight_function=None, ....: (1, 7, 1), (7, 8, 1), (8, 5, 1), (1, 6, 1), ....: (6, 9, 1), (9, 5, 1), (4, 2, 1), (9, 3, 1), ....: (9, 10, 1), (10, 5, 1), (9, 11, 1), (11, 10, 1)]) - sage: list(g.shortest_simple_paths(1, 5, algorithm="Feng")) + sage: list(g.shortest_simple_paths(1, 5, algorithm='Feng')) [[1, 7, 8, 5], [1, 6, 9, 5], [1, 6, 9, 10, 5], @@ -1189,7 +1188,7 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None, cdef dict dist cdef dict successor dist, successor = shortest_paths(reverse_graph, target, weight_function=reverse_weight_function, - algorithm="Dijkstra_Boost") + algorithm='Dijkstra_Boost') # successor is a child node in the shortest path subtree cdef dict reduced_cost = {(e[0], e[1]): weight_function(e) + dist[e[1]] - dist[e[0]] @@ -1400,15 +1399,15 @@ def _all_paths_iterator(self, vertex, ending_vertices=None, two arcs share a head or share a tail, i.e. every vertex in the path is entered at most once and exited at most once. - - ``max_length`` -- non negative integer (default: ``None``); the + - ``max_length`` -- nonnegative integer (default: ``None``); the maximum length of the enumerated paths. If set to ``None``, then all lengths are allowed. - ``trivial`` -- boolean (default: ``False``); if set to ``True``, then - the empty paths are also enumerated. + the empty paths are also enumerated - ``use_multiedges`` -- boolean (default: ``False``); this parameter is - used only if the graph has multiple edges. + used only if the graph has multiple edges - If ``False``, the graph is considered as simple and an edge label is arbitrarily selected for each edge as in @@ -1432,9 +1431,7 @@ def _all_paths_iterator(self, vertex, ending_vertices=None, pass information about edge multiplicities of the graph, if ``None`` edge multiplicity values are computed inside the method. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -1667,15 +1664,15 @@ def all_paths_iterator(self, starting_vertices=None, ending_vertices=None, two arcs share a head or share a tail, i.e. every vertex in the path is entered at most once and exited at most once. - - ``max_length`` -- non negative integer (default: ``None``); the + - ``max_length`` -- nonnegative integer (default: ``None``); the maximum length of the enumerated paths. If set to ``None``, then all lengths are allowed. - ``trivial`` -- boolean (default: ``False``); if set to ``True``, then - the empty paths are also enumerated. + the empty paths are also enumerated - ``use_multiedges`` -- boolean (default: ``False``); this parameter is - used only if the graph has multiple edges. + used only if the graph has multiple edges - If ``False``, the graph is considered as simple and an edge label is arbitrarily selected for each edge as in @@ -1695,9 +1692,7 @@ def all_paths_iterator(self, starting_vertices=None, ending_vertices=None, is simply a pair ``(u, v)`` of vertices. Otherwise a list of edges along with its edge labels are used to represent the path. - OUTPUT: - - iterator + OUTPUT: iterator AUTHOR: @@ -1904,15 +1899,15 @@ def all_simple_paths(self, starting_vertices=None, ending_vertices=None, - ``ending_vertices`` -- iterable (default: ``None``); allowed ending vertices of the paths. If ``None``, then all vertices are allowed. - - ``max_length`` -- non negative integer (default: ``None``); the + - ``max_length`` -- nonnegative integer (default: ``None``); the maximum length of the enumerated paths. If set to ``None``, then all lengths are allowed. - ``trivial`` -- boolean (default: ``False``); if set to ``True``, then - the empty paths are also enumerated. + the empty paths are also enumerated - ``use_multiedges`` -- boolean (default: ``False``); this parameter is - used only if the graph has multiple edges. + used only if the graph has multiple edges - If ``False``, the graph is considered as simple and an edge label is arbitrarily selected for each edge as in @@ -1932,9 +1927,7 @@ def all_simple_paths(self, starting_vertices=None, ending_vertices=None, is simply a pair ``(u, v)`` of vertices. Otherwise a list of edges along with its edge labels are used to represent the path. - OUTPUT: - - list + OUTPUT: list .. NOTE:: diff --git a/src/sage/graphs/planarity.pyx b/src/sage/graphs/planarity.pyx index 987669d97fe..0234aa4f707 100644 --- a/src/sage/graphs/planarity.pyx +++ b/src/sage/graphs/planarity.pyx @@ -94,7 +94,6 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False): ....: assert is_planar(G, set_embedding=set_embedding, set_pos=set_pos) ....: assert (hasattr(G, '_embedding') and G._embedding is not None) == set_embedding, (set_embedding, set_pos) ....: assert (hasattr(G, '_pos') and G._pos is not None) == set_pos, (set_embedding, set_pos) - """ g._scream_if_not_simple() if set_pos and not g.is_connected(): @@ -135,6 +134,7 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False): elif status == NONEMBEDDABLE: # We now know that the graph is nonplanar. if not kuratowski: + gp_Free(&theGraph) return False # With just the current edges, we have a nonplanar graph, # so to isolate a kuratowski subgraph, just keep going. @@ -150,6 +150,7 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False): if status == NONEMBEDDABLE: # Kuratowski subgraph isolator if not kuratowski: + gp_Free(&theGraph) return False g_dict = {} for i in range(1, theGraph.N + 1): diff --git a/src/sage/graphs/pq_trees.py b/src/sage/graphs/pq_trees.py index 016336f7405..998e35fd845 100644 --- a/src/sage/graphs/pq_trees.py +++ b/src/sage/graphs/pq_trees.py @@ -236,16 +236,14 @@ def reorder_sets(sets): INPUT: - - ``sets`` -- a list of instances of ``list, Set`` or ``set`` + - ``sets`` -- list of instances of ``list, Set`` or ``set`` - ALGORITHM: - - PQ-Trees + ALGORITHM: PQ-Trees EXAMPLES: There is only one way (up to reversal) to represent contiguously - the sequence ofsets `\{i-1, i, i+1\}`:: + the sequence of sets `\{i-1, i, i+1\}`:: sage: from sage.graphs.pq_trees import reorder_sets sage: seq = [Set([i-1,i,i+1]) for i in range(1,15)] @@ -289,7 +287,7 @@ class PQ: def __init__(self, seq): r""" - Construction of a PQ-Tree + Construction of a PQ-Tree. EXAMPLES:: @@ -313,7 +311,7 @@ def __init__(self, seq): def reverse(self): r""" - Recursively reverses ``self`` and its children + Recursively reverse ``self`` and its children. EXAMPLES:: @@ -333,8 +331,8 @@ def reverse(self): def __contains__(self, v): r""" - Tests whether there exists an element of ``self`` containing - an element ``v`` + Test whether there exists an element of ``self`` containing + an element ``v``. INPUT: @@ -353,7 +351,7 @@ def __contains__(self, v): def __iter__(self): r""" - Iterates over the children of ``self``. + Iterate over the children of ``self``. EXAMPLES:: @@ -369,7 +367,7 @@ def __iter__(self): def number_of_children(self): r""" - Returns the number of children of ``self`` + Return the number of children of ``self``. EXAMPLES:: @@ -382,7 +380,7 @@ def number_of_children(self): def ordering(self): r""" - Returns the current ordering given by listing the leaves from + Return the current ordering given by listing the leaves from left to right. EXAMPLES:: @@ -401,9 +399,9 @@ def ordering(self): return value - def __repr__(self): + def __repr__(self) -> str: r""" - Succintly represents ``self``. + Succinctly represent ``self``. EXAMPLES:: @@ -416,7 +414,7 @@ def __repr__(self): def simplify(self, v, left=False, right=False): r""" - Returns a simplified copy of self according to the element ``v`` + Return a simplified copy of ``self`` according to the element ``v``. If ``self`` is a partial P-tree for ``v``, we would like to restrict the permutations of its children to permutations @@ -502,9 +500,9 @@ def simplify(self, v, left=False, right=False): def flatten(self): r""" - Returns a flattened copy of ``self`` + Return a flattened copy of ``self``. - If self has only one child, we may as well consider its + If ``self`` has only one child, we may as well consider its child's children, as ``self`` encodes no information. This method recursively "flattens" trees having only on PQ-tree child, and returns it. @@ -531,7 +529,7 @@ class P(PQ): """ def set_contiguous(self, v): r""" - Updates ``self`` so that the sets containing ``v`` are + Update ``self`` so that the sets containing ``v`` are contiguous for any admissible permutation of its subtrees. INPUT: @@ -540,7 +538,7 @@ def set_contiguous(self, v): OUTPUT: - According to the cases : + According to the cases: * ``(EMPTY, ALIGNED)`` if no set of the tree contains an occurrence of ``v`` @@ -558,7 +556,7 @@ def set_contiguous(self, v): In any case, the sets containing ``v`` are contiguous when this function ends. If there is no possibility of doing so, the function - raises a :class:`ValueError` exception. + raises a :exc:`ValueError` exception. EXAMPLES: @@ -803,14 +801,14 @@ def orderings(self): class Q(PQ): r""" - A Q-Tree is a PQ-Tree whose children are ordered up to reversal + A Q-Tree is a PQ-Tree whose children are ordered up to reversal. For more information, see the documentation of :mod:`sage.graphs.pq_trees`. """ def set_contiguous(self, v): r""" - Updates ``self`` so that the sets containing ``v`` are + Update ``self`` so that the sets containing ``v`` are contiguous for any admissible permutation of its subtrees. INPUT: @@ -819,7 +817,7 @@ def set_contiguous(self, v): OUTPUT: - According to the cases : + According to the cases: * ``(EMPTY, ALIGNED)`` if no set of the tree contains an occurrence of ``v`` @@ -837,7 +835,7 @@ def set_contiguous(self, v): In any case, the sets containing ``v`` are contiguous when this function ends. If there is no possibility of doing so, the function - raises a :class:`ValueError` exception. + raises a :exc:`ValueError` exception. EXAMPLES: @@ -1104,7 +1102,7 @@ def cardinality(self): def orderings(self): r""" - Iterates over all orderings of the sets allowed by the structure + Iterate over all orderings of the sets allowed by the structure. .. SEEALSO:: diff --git a/src/sage/graphs/schnyder.py b/src/sage/graphs/schnyder.py index b22ab6d3302..fc4e76e917f 100644 --- a/src/sage/graphs/schnyder.py +++ b/src/sage/graphs/schnyder.py @@ -41,12 +41,10 @@ def _triangulate(g, comb_emb): INPUT: - - g -- the graph to triangulate + - ``g`` -- the graph to triangulate - ``comb_emb`` -- a planar combinatorial embedding of g - OUTPUT: - - A list of edges that are added to the graph (in place) + OUTPUT: a list of edges that are added to the graph (in place) EXAMPLES:: @@ -153,13 +151,11 @@ def _normal_label(g, comb_emb, external_face): INPUT: - - g -- the graph to find the normal labeling of (g must be triangulated) + - ``g`` -- the graph to find the normal labeling of (g must be triangulated) - ``comb_emb`` -- a planar combinatorial embedding of g - ``external_face`` -- the list of three edges in the external face of g - OUTPUT: - - x -- tuple with entries + OUTPUT: x; tuple with entries x[0] = dict of dicts of normal labeling for each vertex of g and each adjacent neighbors u,v (u < v) of vertex: @@ -368,8 +364,8 @@ def _realizer(g, x, example=False): INPUT: - - g -- the graph to compute the realizer of - - x -- tuple with entries + - ``g`` -- the graph to compute the realizer of + - ``x`` -- tuple with entries x[0] = dict of dicts representing a normal labeling of g. For each vertex of g and each adjacent neighbors u,v (u < v) of @@ -378,9 +374,7 @@ def _realizer(g, x, example=False): x[1] = (v1, v2, v3) tuple of the three external vertices (also the roots of each tree) - OUTPUT: - - - x -- tuple with entries + OUTPUT: x; tuple with entries x[0] = dict of lists of TreeNodes: @@ -402,7 +396,6 @@ def _realizer(g, x, example=False): sage: _realizer(g, tn) ({0: []}, (1, 0, 2)) - """ normal_labeling, (v1, v2, v3) = x realizer = DiGraph() @@ -465,8 +458,8 @@ def _compute_coordinates(g, x): INPUT: - - g -- the graph to compute the coordinates of - - x -- tuple with entries + - ``g`` -- the graph to compute the coordinates of + - ``x`` -- tuple with entries x[0] = dict of tree nodes for the three trees with each external vertex as root: @@ -516,7 +509,7 @@ def _compute_coordinates(g, x): for v in g.vertices(sort=False): if v not in [t1.label, t2.label, t3.label]: # Computing coordinates for v - r = list((0, 0, 0)) + r = [0, 0, 0] for i in [0, 1, 2]: # Computing size of region i: @@ -566,7 +559,7 @@ class TreeNode: INPUT: - ``parent`` -- the parent TreeNode of ``self`` - - ``children`` -- a list of TreeNode children of ``self`` + - ``children`` -- list of TreeNode children of ``self`` - ``label`` -- the associated realizer vertex label EXAMPLES:: @@ -591,7 +584,7 @@ def __init__(self, parent=None, children=None, label=None): INPUT: - ``parent`` -- the parent TreeNode of ``self`` - - ``children`` -- a list of TreeNode children of ``self`` + - ``children`` -- list of TreeNode children of ``self`` - ``label`` -- the associated realizer vertex label EXAMPLES:: @@ -620,9 +613,9 @@ def __init__(self, parent=None, children=None, label=None): def compute_number_of_descendants(self): """ - Computes the number of descendants of self and all descendants. + Compute the number of descendants of ``self`` and all descendants. - For each TreeNode, sets result as attribute self.number_of_descendants + For each TreeNode, sets result as attribute ``self.number_of_descendants``. EXAMPLES:: @@ -640,7 +633,6 @@ def compute_number_of_descendants(self): sage: tn.compute_depth_of_self_and_children() sage: tn3.depth 2 - """ n = 1 for child in self.children: @@ -650,9 +642,9 @@ def compute_number_of_descendants(self): def compute_depth_of_self_and_children(self): """ - Computes the depth of self and all descendants. + Compute the depth of ``self`` and all descendants. - For each TreeNode, sets result as attribute self.depth + For each TreeNode, sets result as ``attribute self.depth``. EXAMPLES:: @@ -711,16 +703,16 @@ def minimal_schnyder_wood(graph, root_edge=None, minimal=True, check=True): INPUT: - - graph -- a planar triangulation, given by a graph with an embedding. + - ``graph`` -- a planar triangulation, given by a graph with an embedding - - root_edge -- a pair of vertices (default is from ``-1`` to ``-2``) - The third boundary vertex is then determined using the orientation and - will be labelled ``-3``. + - ``root_edge`` -- a pair of vertices (default: from ``-1`` to ``-2``); + the third boundary vertex is then determined using the orientation and + will be labelled ``-3`` - - minimal -- boolean (default ``True``), whether to return a - minimal or a maximal Schnyder wood. + - ``minimal`` -- boolean (default: ``True``); whether to return a + minimal or a maximal Schnyder wood - - check -- boolean (default ``True``), whether to check if the input + - ``check`` -- boolean (default: ``True``); whether to check if the input is a planar triangulation OUTPUT: diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index c041bb471c8..cc73b401668 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -53,7 +53,7 @@ def kruskal(G, by_weight=True, weight_function=None, check_weight=False, check=F - ``G`` -- an undirected graph - ``by_weight`` -- boolean (default: ``True``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + the graph are weighted. If ``False``, all edges have weight 1. - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, @@ -262,7 +262,7 @@ def kruskal_iterator(G, by_weight=True, weight_function=None, check_weight=False - ``G`` -- an undirected graph - ``by_weight`` -- boolean (default: ``True``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + the graph are weighted. If ``False``, all edges have weight 1. - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, @@ -294,9 +294,7 @@ def kruskal_iterator(G, by_weight=True, weight_function=None, check_weight=False it directly instead of using it indirectly via :meth:`sage.graphs.generic_graph.GenericGraph.min_spanning_tree`. - OUTPUT: - - The edges of a minimum spanning tree of ``G``, one by one. + OUTPUT: the edges of a minimum spanning tree of ``G``, one by one .. SEEALSO:: :func:`kruskal` @@ -368,7 +366,7 @@ def kruskal_iterator_from_edges(edges, union_find, by_weight=True, forest - ``by_weight`` -- boolean (default: ``True``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + the graph are weighted. If ``False``, all edges have weight 1. - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, @@ -379,9 +377,7 @@ def kruskal_iterator_from_edges(edges, union_find, by_weight=True, - ``check_weight`` -- boolean (default: ``False``); whether to check that the ``weight_function`` outputs a number for each edge - OUTPUT: - - The edges of a minimum spanning tree of ``G``, one by one. + OUTPUT: the edges of a minimum spanning tree of ``G``, one by one .. SEEALSO:: @@ -446,11 +442,11 @@ def filter_kruskal(G, threshold=10000, by_weight=True, weight_function=None, - ``G`` -- an undirected graph - ``threshold`` -- integer (default: 10000); maximum number of edges on - which to run kruskal algorithm. Above that value, edges are partitioned - into sets of size at most ``threshold`` + which to run kruskal algorithm. Above that value, edges are partitioned + into sets of size at most ``threshold`` - ``by_weight`` -- boolean (default: ``True``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + the graph are weighted. If ``False``, all edges have weight 1. - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, @@ -519,11 +515,11 @@ def filter_kruskal_iterator(G, threshold=10000, by_weight=True, weight_function= - ``G`` -- an undirected graph - ``threshold`` -- integer (default: 10000); maximum number of edges on - which to run kruskal algorithm. Above that value, edges are partitioned - into sets of size at most ``threshold`` + which to run kruskal algorithm. Above that value, edges are partitioned + into sets of size at most ``threshold`` - ``by_weight`` -- boolean (default: ``True``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + the graph are weighted. If ``False``, all edges have weight 1. - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, @@ -545,9 +541,7 @@ def filter_kruskal_iterator(G, threshold=10000, by_weight=True, weight_function= - Does ``G`` have self-loops? - Does ``G`` have multiple edges? - OUTPUT: - - The edges of a minimum spanning tree of ``G``, one by one. + OUTPUT: the edges of a minimum spanning tree of ``G``, one by one .. SEEALSO:: @@ -718,10 +712,10 @@ def boruvka(G, by_weight=True, weight_function=None, check_weight=True, check=Fa INPUT: - - ``G`` -- an undirected graph. + - ``G`` -- an undirected graph - ``by_weight`` -- boolean (default: ``True``); if ``True``, the edges in - the graph are weighted; if ``False``, all edges have weight 1. + the graph are weighted. If ``False``, all edges have weight 1 - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, @@ -952,7 +946,7 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct not convertible to a float, an error is raised) - ``check_weight`` -- boolean (default: ``True``); whether to check that - the ``weight_function`` outputs a number for each edge. + the ``weight_function`` outputs a number for each edge .. SEEALSO:: @@ -1303,7 +1297,7 @@ def edge_disjoint_spanning_trees(G, k, by_weight=False, weight_function=None, ch sage: edge_disjoint_spanning_trees(G, -1) Traceback (most recent call last): ... - ValueError: parameter k must be a non-negative integer + ValueError: parameter k must be a nonnegative integer sage: edge_disjoint_spanning_trees(G, 0) [] sage: edge_disjoint_spanning_trees(G, 1) @@ -1332,14 +1326,14 @@ def edge_disjoint_spanning_trees(G, k, by_weight=False, weight_function=None, ch from sage.graphs.graph import Graph msg_no_solution = "this graph does not contain the required number of trees/arborescences" if k < 0: - raise ValueError("parameter k must be a non-negative integer") + raise ValueError("parameter k must be a nonnegative integer") elif not k: return [] elif k == 1: E = G.min_spanning_tree() if not E and G.order() != 1: raise EmptySetError(msg_no_solution) - return [Graph([G, E], format="vertices_and_edges")] + return [Graph([G, E], format='vertices_and_edges')] elif k > 1 + min(G.degree()) // 2: raise EmptySetError(msg_no_solution) @@ -1359,7 +1353,7 @@ def edge_disjoint_spanning_trees(G, k, by_weight=False, weight_function=None, ch # This is not a requirement of the algorithm as we can use the mapping # edge_index. However, it is convenient to maintain the forest as graphs to # simplify some operations. - H = Graph([G, []], format="vertices_and_edges") + H = Graph([G, []], format='vertices_and_edges') F = [H.copy() for _ in range(k + 1)] # We consider the edges by increasing weight diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index ac26256a1d3..0fa241ba218 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -431,7 +431,6 @@ def is_orthogonal_polar(int v, int k, int l, int mu): (, 8, 2, '-') sage: is_orthogonal_polar(130,48,20,16) # needs sage.rings.finite_rings (, 6, 3, '+') - """ r, s = eigenvalues(v, k, l, mu) if r is None: @@ -1058,7 +1057,7 @@ def is_polhill(int v, int k, int l, int mu): [(1, 2), (3, 2), (2, 1), (2, 3), (2, 2)]] D = [[G(e) for e in x] for x in D] - # The K_i are hyperplanes partitionning the nonzero elements of + # The K_i are hyperplanes partitioning the nonzero elements of # GF(2^s)^2. See section 6. s = 3 G1 = GF(2**s,'x') @@ -1174,7 +1173,7 @@ def is_RSHCD(int v, int k, int l, int mu): def SRG_from_RSHCD(v, k, l, mu, existence=False, check=True): r""" - Return a `(v,k,l,mu)`-strongly regular graph from a RSHCD + Return a `(v,k,l,mu)`-strongly regular graph from a RSHCD. This construction appears in 8.D of [BL1984]_. For more information, see :func:`~sage.combinat.matrices.hadamard_matrix.regular_symmetric_hadamard_matrix_with_constant_diagonal`. @@ -1183,13 +1182,12 @@ def SRG_from_RSHCD(v, k, l, mu, existence=False, check=True): - ``v``, ``k``, ``l``, ``mu`` -- integers - - ``existence`` (boolean) -- whether to return a graph or to test if Sage - can build such a graph. + - ``existence`` -- boolean; whether to return a graph or to test if Sage + can build such a graph - - ``check`` (boolean) -- whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to ``True`` - by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES: @@ -1243,7 +1241,7 @@ def SRG_from_RSHCD(v, k, l, mu, existence=False, check=True): if list(H.column(0)[1:]).count(1) == k: H = -H G = Graph((J(n) - I(n) - H + H[0, 0]*I(n)) / 2, - loops=False, multiedges=False, format="adjacency_matrix") + loops=False, multiedges=False, format='adjacency_matrix') if check: assert G.is_strongly_regular(parameters=True) == (v, k, l, mu) return G @@ -1611,7 +1609,6 @@ def is_switch_skewhad(int v, int k, int l, int mu): sage: from sage.graphs.strongly_regular_db import is_switch_skewhad sage: t = is_switch_skewhad(5,5,5,5); t # needs sage.combinat sage.modules - """ from sage.combinat.matrices.hadamard_matrix import skew_hadamard_matrix from sage.graphs.generators.families import SwitchedSquaredSkewHadamardMatrixGraph @@ -1718,7 +1715,6 @@ def is_nowhere0_twoweight(int v, int k, int l, int mu): sage: t = is_nowhere0_twoweight(1800, 728, 268, 312); t # needs sage.libs.pari (, 16) sage: t = is_nowhere0_twoweight(5,5,5,5); t # needs sage.libs.pari - """ from sage.graphs.generators.classical_geometries import Nowhere0WordsTwoWeightCodeGraph cdef int q @@ -1746,7 +1742,6 @@ cdef eigenvalues(int v, int k, int l, int mu): INPUT: - ``v``, ``k``, ``l``, ``mu`` -- integers - """ # See 1.3.1 of [Distance-regular graphs] b = (mu-l) @@ -1858,7 +1853,7 @@ cpdef latin_squares_graph_parameters(int v, int k, int l,int mu): OUTPUT: - - ``(g, n)`` -- parameters of an `L_g(n)` graph, or `None` + - ``(g, n)`` -- parameters of an `L_g(n)` graph, or ``None`` TESTS:: @@ -1882,7 +1877,7 @@ cpdef latin_squares_graph_parameters(int v, int k, int l,int mu): def _H_3_cayley_graph(L): r""" - return the `L`-Cayley graph of the group `H_3` from Prop. 12 in [JK2003]_. + Return the `L`-Cayley graph of the group `H_3` from Prop. 12 in [JK2003]_. INPUT: @@ -1976,7 +1971,7 @@ def SRG_105_32_4_12(): a = IG.automorphism_group() h = a.stabilizer(a.domain()[0]) o = next(x for x in h.orbits() if len(x) == 32)[0] - e = a.orbit((a.domain()[0], o), action="OnSets") + e = a.orbit((a.domain()[0], o), action='OnSets') G = Graph() G.add_edges(e) G.name('Aut L(3,4) on flags') @@ -2105,7 +2100,7 @@ def SRG_176_105_68_54(): def SRG_210_99_48_45(): r""" - Return a strongly regular graph with parameters `(210, 99, 48, 45)` + Return a strongly regular graph with parameters `(210, 99, 48, 45)`. This graph is from Example 4.2 in [KPRWZ2010]_. One considers the action of the symmetric group `S_7` on the 210 digraphs isomorphic to the @@ -2370,7 +2365,7 @@ def strongly_regular_from_two_weight_code(L): INPUT: - - ``L`` -- a two-weight linear code, or its generating matrix. + - ``L`` -- a two-weight linear code, or its generating matrix EXAMPLES:: @@ -2424,7 +2419,7 @@ def SRG_416_100_36_20(): def SRG_560_208_72_80(): r""" - Return a `(560,208,72,80)`-strongly regular graph + Return a `(560,208,72,80)`-strongly regular graph. This graph is obtained as the union of 4 orbits of sets of cardinality 2 (among the 13 that exist) of the group `Sz(8)`. @@ -2473,8 +2468,8 @@ def strongly_regular_from_two_intersection_set(M): INPUT: - - `M` -- a `|S| \times k` matrix with entries in `F_q` representing the points of - the 2-intersection set. We assume that the first non-zero entry of each row is + - ``M`` -- a `|S| \times k` matrix with entries in `F_q` representing the points of + the 2-intersection set. We assume that the first nonzero entry of each row is equal to `1`, that is, they give points in homogeneous coordinates. The implementation does not check that `S` is actually a 2-intersection set. @@ -2512,7 +2507,7 @@ def strongly_regular_from_two_intersection_set(M): def SRG_120_63_30_36(): r""" - Return a `(120,63,30,36)`-strongly regular graph + Return a `(120,63,30,36)`-strongly regular graph. It is the distance-2 graph of :meth:`JohnsonGraph(10,3) `. @@ -2530,7 +2525,7 @@ def SRG_120_63_30_36(): def SRG_126_25_8_4(): r""" - Return a `(126,25,8,4)`-strongly regular graph + Return a `(126,25,8,4)`-strongly regular graph. It is the distance-(1 or 4) graph of :meth:`JohnsonGraph(9,4) `. @@ -2548,7 +2543,7 @@ def SRG_126_25_8_4(): def SRG_175_72_20_36(): r""" - Return a `(175,72,20,36)`-strongly regular graph + Return a `(175,72,20,36)`-strongly regular graph. This graph is obtained from the line graph of :meth:`~sage.graphs.graph_generators.GraphGenerators.HoffmanSingletonGraph`. Setting @@ -2569,7 +2564,7 @@ def SRG_175_72_20_36(): def SRG_176_90_38_54(): r""" - Return a `(176,90,38,54)`-strongly regular graph + Return a `(176,90,38,54)`-strongly regular graph. This graph is obtained from :func:`~sage.graphs.strongly_regular_db.SRG_175_72_20_36` @@ -2603,7 +2598,7 @@ def SRG_176_90_38_54(): def SRG_630_85_20_10(): r""" - Return a `(630,85,20,10)`-strongly regular graph + Return a `(630,85,20,10)`-strongly regular graph. This graph is the line graph of `pg(5,18,2)`; its point graph is :func:`~sage.graphs.strongly_regular_db.SRG_175_72_20_36`. @@ -2624,7 +2619,7 @@ def SRG_630_85_20_10(): mc = [0, 1, 5, 6, 12, 13, 16, 17, 22, 23, 29, 33, 39, 42, 47] assert(hs.subgraph(mc).is_regular(k=0)) # a maximum coclique assert(hs.subgraph(P).is_regular(k=3)) - h = hs.automorphism_group().stabilizer(mc, action="OnSets") + h = hs.automorphism_group().stabilizer(mc, action='OnSets') l = h.orbit(tuple((x[0], x[1]) for x in hs.subgraph(P).matching()), "OnSetsSets") return IntersectionGraph(l) @@ -2632,7 +2627,7 @@ def SRG_630_85_20_10(): def SRG_126_50_13_24(): r""" - Return a `(126,50,13,24)`-strongly regular graph + Return a `(126,50,13,24)`-strongly regular graph. This graph is a subgraph of :meth:`~sage.graphs.strongly_regular_db.SRG_175_72_20_36`. @@ -2786,24 +2781,23 @@ def strongly_regular_graph(int v, int k, int l, int mu=-1, bint existence=False, INPUT: - - ``v``, ``k``, ``l``, ``mu`` -- integers -- note that ``mu``, if unspecified, is - automatically determined from ``v``, ``k``, ``l``. + - ``v``, ``k``, ``l``, ``mu`` -- ``integers`` -- note that ``mu``, if unspecified, is + automatically determined from ``v``, ``k``, ``l`` - - ``existence`` (boolean;``False``) -- instead of building the graph, + - ``existence`` -- boolean;``False``; instead of building the graph, return: - ``True`` -- meaning that a `(v,k,\lambda,\mu)`-strongly regular graph - exists. + exists - ``Unknown`` -- meaning that Sage does not know if such a strongly - regular graph exists (see :mod:`sage.misc.unknown`). + regular graph exists (see :mod:`sage.misc.unknown`) - - ``False`` -- meaning that no such strongly regular graph exists. + - ``False`` -- meaning that no such strongly regular graph exists - - ``check`` -- (boolean) Whether to check that output is correct before - returning it. As this is expected to be useless (but we are cautious - guys), you may want to disable it whenever you want speed. Set to - ``True`` by default. + - ``check`` -- boolean (default: ``True``); whether to check that output is + correct before returning it. As this is expected to be useless, you may + want to disable it whenever you want speed. EXAMPLES: @@ -2914,7 +2908,7 @@ def strongly_regular_graph(int v, int k, int l, int mu=-1, bint existence=False, def strongly_regular_graph_lazy(int v, int k, int l, int mu=-1, bint existence=False): r""" - return a promise to build an `(v,k,l,mu)`-srg + Return a promise to build an `(v,k,l,mu)`-srg. Return a promise to build an `(v,k,l,mu)`-srg as a tuple `t`, with `t[0]` a function to evaluate on `*t[1:]`. @@ -3052,7 +3046,7 @@ def apparently_feasible_parameters(int n): INPUT: - - ``n`` (integer) -- return all a-priori feasible tuples `(v,k,\lambda,\mu)` + - ``n`` -- integer; return all a-priori feasible tuples `(v,k,\lambda,\mu)` for `v # David Coudert +# 2024 Cyril Bouvier # # 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 @@ -47,15 +72,166 @@ from memory_allocator cimport MemoryAllocator from sage.graphs.base.static_sparse_graph cimport init_short_digraph from sage.graphs.base.static_sparse_graph cimport free_short_digraph from sage.graphs.base.static_sparse_graph cimport out_degree +from sage.graphs.base.c_graph cimport CGraph, CGraphBackend +from sage.graphs.graph_decompositions.slice_decomposition cimport \ + extended_lex_BFS + + +def _lex_order_common(G, algo, reverse, tree, initial_vertex): + r""" + Perform a lexicographic search (LexBFS, LexUP, LexDFS or LexDOWN) on the + graph. + + INPUT: + + - ``G`` -- a sage graph + + - ``algo`` -- string; the name of the actual algorithm among: + + - ``"lex_BFS"`` + + - ``"lex_UP"`` + + - ``"lex_DFS"`` + + - ``"lex_DOWN"`` + + - ``reverse`` -- whether to return the vertices in discovery order, or the + reverse + + - ``tree`` -- whether to return the discovery directed tree (each vertex + being linked to the one that saw it last) + + - ``initial_vertex`` -- the first vertex to consider, can be None + + .. NOTE:: + + Loops and multiple edges are ignored and directed graphs are considered + as undirected graphs. + + ALGORITHM: + + See the documentation of the :mod:`~sage.graphs.traversals` module. + + TESTS: + + Lex ordering of a graph on one vertex:: + + sage: Graph(1).lex_BFS(tree=True, algorithm="slow") + ([0], Digraph on 1 vertex) + sage: Graph(1).lex_UP(tree=True) + ([0], Digraph on 1 vertex) + sage: Graph(1).lex_DFS(tree=True) + ([0], Digraph on 1 vertex) + sage: Graph(1).lex_DOWN(tree=True) + ([0], Digraph on 1 vertex) + + Lex ordering of an empty (di)graph is an empty sequence:: + + sage: g = Graph() + sage: g.lex_BFS(algorithm="slow") + [] + sage: g.lex_BFS(algorithm="slow", tree=True) + ([], Digraph on 0 vertices) + sage: g.lex_UP() + [] + sage: g.lex_UP(tree=True) + ([], Digraph on 0 vertices) + sage: g.lex_DFS() + [] + sage: g.lex_DFS(tree=True) + ([], Digraph on 0 vertices) + sage: g.lex_DOWN() + [] + sage: g.lex_DFS(tree=True) + ([], Digraph on 0 vertices) + + Lex UP ordering of a symmetric digraph should be the same as the Lex UP + ordering of the corresponding undirected graph:: + + sage: G = Graph([(1, 2), (1, 3), (2, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 5), (5, 6)]) + sage: H = DiGraph(G) + sage: G.lex_BFS(algorithm="slow") == H.lex_BFS(algorithm="slow") + True + sage: G.lex_UP() == H.lex_UP() + True + sage: G.lex_DFS() == H.lex_DFS() + True + sage: G.lex_DOWN() == H.lex_DOWN() + True + + ``initial_vertex`` should be a valid graph vertex:: + + sage: G = graphs.CompleteGraph(6) + sage: G.lex_BFS(initial_vertex='foo', algorithm="slow") + Traceback (most recent call last): + ... + ValueError: 'foo' is not a graph vertex + sage: G.lex_UP(initial_vertex='foo') + Traceback (most recent call last): + ... + ValueError: 'foo' is not a graph vertex + sage: G.lex_DFS(initial_vertex='foo') + Traceback (most recent call last): + ... + ValueError: 'foo' is not a graph vertex + sage: G.lex_DOWN(initial_vertex='foo') + Traceback (most recent call last): + ... + ValueError: 'foo' is not a graph vertex + """ + if initial_vertex is not None and initial_vertex not in G: + raise ValueError(f"'{initial_vertex}' is not a graph vertex") + + if algo not in ("lex_BFS", "lex_UP", "lex_DFS", "lex_DOWN"): + raise ValueError(f"unknown algorithm '{algo}'") + + cdef size_t n = G.order() + cdef list sigma = [] + cdef dict predecessor = {} + + cdef bint right = algo in ("lex_BFS", "lex_UP") + cdef bint decr = algo in ("lex_BFS", "lex_DOWN") + + cdef size_t cur_label = n if decr else -1 + cdef int label_incr = -1 if decr else 1 + + # Perform the search + lexicographic_label = {u: deque() for u in G} + if initial_vertex is not None: + # append or appendleft does not matter here, as the deque is empty + lexicographic_label[initial_vertex].append(cur_label) + while lexicographic_label: + u = max(lexicographic_label, key=lexicographic_label.get) + lexicographic_label.pop(u) + sigma.append(u) + cur_label += label_incr + for v in G.neighbor_iterator(u): # graphs are considered undirected + if v in lexicographic_label: + if right: + lexicographic_label[v].append(cur_label) + else: + lexicographic_label[v].appendleft(cur_label) + predecessor[v] = u + + if reverse: + sigma.reverse() + + if tree: + from sage.graphs.digraph import DiGraph + edges = predecessor.items() + g = DiGraph([G, edges], format='vertices_and_edges', sparse=True) + return sigma, g + return sigma def _is_valid_lex_BFS_order(G, L): r""" - Check whether `L` is a valid lex BFS ordering of the vertices of `G`. + Check whether ``L`` is a valid LexBFS ordering of the vertices of ``G``. Given two vertices `a` and `b` of `G = (V, E)`, we write `a < b` if `a` has a smaller label than `b`, and so if `a` is after `b` in the ordering `L`. - It is proved in [DNB1996]_ that any lex BFS ordering satisfies that, + It is proved in [DNB1996]_ that any LexBFS ordering satisfies that, if `a < b < c` and `ac \in E` and `bc \not\in E`, then there exists `d\in V` such that `c < d`, `db \in E` and `da \not\in E`. @@ -65,6 +241,21 @@ def _is_valid_lex_BFS_order(G, L): - ``L`` -- list; an ordering of the vertices of `G` + OUTPUT: + + - ``True`` if ``L`` is a LexBFS ordering of ``G``; ``False`` otherwise + + .. NOTE:: + + Loops and multiple edges are ignored for LexBFS ordering and directed + graphs are considered as undirected graphs. + + .. SEEALSO:: + + * :wikipedia:`Lexicographic_breadth-first_search` + * :meth:`~sage.graphs.generic_graph.GenericGraph.lex_BFS` -- perform a + lexicographic depth first search (LexBFS) on the graph + TESTS:: sage: from sage.graphs.traversals import _is_valid_lex_BFS_order @@ -76,8 +267,19 @@ def _is_valid_lex_BFS_order(G, L): sage: G = DiGraph("I?O@??A?CCA?A??C??") sage: _is_valid_lex_BFS_order(G, [0, 7, 1, 2, 3, 4, 5, 8, 6, 9]) + False + sage: _is_valid_lex_BFS_order(G, G.lex_BFS()) + True + sage: H = G.to_undirected() + sage: _is_valid_lex_BFS_order(H, G.lex_BFS()) + True + sage: _is_valid_lex_BFS_order(G, H.lex_BFS()) True """ + # Convert G to a simple undirected graph + if G.has_loops() or G.has_multiple_edges() or G.is_directed(): + G = G.to_simple(immutable=False, to_undirected=True) + cdef int n = G.order() if set(L) != set(G): @@ -86,11 +288,9 @@ def _is_valid_lex_BFS_order(G, L): cdef dict L_inv = {u: i for i, u in enumerate(L)} cdef int pos_a, pos_b, pos_c - neighbors = G.neighbor_in_iterator if G.is_directed() else G.neighbor_iterator - for pos_a in range(n - 1, -1, -1): a = L[pos_a] - for c in neighbors(a): + for c in G.neighbor_iterator(a): pos_c = L_inv[c] if pos_c > pos_a: continue @@ -99,132 +299,13 @@ def _is_valid_lex_BFS_order(G, L): if G.has_edge(c, b): continue if any(L_inv[d] < pos_c and not G.has_edge(d, a) - for d in neighbors(b)): + for d in G.neighbor_iterator(b)): # The condition is satisfied for a < b < c continue return False return True -cdef lex_BFS_fast_short_digraph(short_digraph sd, uint32_t *sigma, uint32_t *pred): - r""" - Perform a lexicographic breadth first search (LexBFS) on the graph. - - This method implements the `O(n+m)` time algorithm proposed in [HMPV2000]_. - - The method assumes that the initial vertex is vertex `0` and feeds input - arrays ``sigma`` and ``pred`` with respectively the ordering of the vertices - and the predecessor in the traversal. - - This algorithm uses the notion of *slices*, i.e., subsets of consecutive - vertices in the ordering, and iteratively refines the slices by subdividing - them into sub-slices to determine the exact position of the vertices in the - ordering. - - Consider an ordering `\sigma` of the vertices. For a vertex `v`, we define - `N_i(v) = \{u | u \in N(v) \text{ and } \sigma(u) < i\}`, that is the subset - of neighbors of `v` appearing before the `i`-th vertex in the ordering - `\sigma`. Now, a slice of an ordering `\sigma` is a set of consecutive - vertices, `S = \{u | i \leq \sigma(u) \leq j\}`, such that for any `u \in - S`, we have `N_i(u) = N_i(\sigma^{-1}(i))` and for any `v` such that `j < - \sigma(v)`, `N_i(v) \neq N_i(\sigma^{-1}(i))`. The *head* of a slice is the - first position of its vertices. - - The algorithm starts with a single slice containing all vertices. Then, when - the position of the `i`-th vertex `v` is fixed, it explores the neighbors of - `v` that have not yet been ordered. Consider a slice `S` such that `N(x)\cap - S \neq \emptyset`. The algorithm will rearrange the ordering of the vertices - in `S` so that the first vertices are the neighbors of `v`. The sub-slice - containing the neighbors of `v` is assigned a new slice name, and the head - of slice `S` is set to the position of the first vertex of `S \setminus - N(v)` in the ordering `\sigma`. - - Observe that each arc of the graph can induce the subdivision of a - slice. Hence, the algorithm can use up to `m + 1` different slices. - - INPUT: - - - ``sd`` -- a ``short_digraph`` - - - ``sigma`` -- array of size ``n`` to store the ordering of the vertices - resulting from the LexBFS traversal from vertex 0. This method assumes - that this array has already been allocated. However, there is no need to - initialize it. - - - ``pred`` -- array of size ``n`` to store the predecessor of a vertex in - the LexBFS traversal from vertex 0. This method assumes that this array - has already been allocated and initialized (e.g., ``pred[i] = i``). - - EXAMPLES: - - Lex BFS ordering of the 3-sun graph:: - - sage: g = Graph([(1, 2), (1, 3), (2, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 5), (5, 6)]) - sage: g.lex_BFS(algorithm="fast") - [1, 2, 3, 5, 4, 6] - """ - cdef uint32_t n = sd.n - cdef uint32_t n_slice = sd.m + 1 - cdef MemoryAllocator mem = MemoryAllocator() - cdef uint32_t *sigma_inv = mem.allocarray(n, sizeof(uint32_t)) - cdef uint32_t *slice_of = mem.allocarray(n, sizeof(uint32_t)) - cdef uint32_t *slice_head = mem.allocarray(n_slice, sizeof(uint32_t)) - cdef uint32_t *subslice = mem.allocarray(n_slice, sizeof(uint32_t)) - cdef uint32_t i, j, k, l, a, old_k, v - cdef int wi - - # Initialize slices (slice_of, slice_head, subslice) to 0 - memset(slice_of, 0, n * sizeof(uint32_t)) - slice_head[0] = 0 - subslice[0] = 0 - - # Initialize the position of vertices in sigma - for i in range(n): - sigma[i] = i - sigma_inv[i] = i - - k = 1 - for i in range(n): - old_k = k - v = sigma[i] - - # We update the labeling of all unordered neighbors of v - for wi in range(out_degree(sd, v)): - w = sd.neighbors[v][wi] - j = sigma_inv[w] - if j <= i: - # w has already been ordered - continue - - # Get the name of the slice for position j - a = slice_of[j] - if slice_head[a] <= i: - # This slice cannot start at a position less than i - slice_head[a] = i + 1 - - # Get the position of the head of the slice - l = slice_head[a] - if l < n - 1 and slice_of[l + 1] == a: - if l != j: - # Place w at the position of the head of the slice - u = sigma[l] - sigma_inv[u], sigma_inv[w] = j, l - sigma[j], sigma[l] = u, w - j = l - slice_head[a] += 1 - if subslice[a] < old_k: - # Form a new slice - subslice[a] = k - slice_head[k] = j - subslice[k] = 0 - k += 1 - - # Finally, we update the name of the slice for position j and set v - # as predecessor of w - slice_of[j] = subslice[a] - pred[w] = v - - def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast"): r""" Perform a lexicographic breadth first search (LexBFS) on the graph. @@ -238,59 +319,38 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") - ``tree`` -- boolean (default: ``False``); whether to return the discovery directed tree (each vertex being linked to the one that saw - it for the first time) + it last) - - ``initial_vertex`` -- (default: ``None``); the first vertex to + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider - - ``algorithm`` -- string (default: ``"fast"``); algorithm to use among: + - ``algorithm`` -- string (default: ``'fast'``); algorithm to use among: - - ``"slow"`` -- This algorithm maintains for each vertex left in the graph - a code corresponding to the vertices already removed. The vertex of - maximal code (according to the lexicographic order) is then removed, and - the codes are updated. See for instance [CK2008]_ for more details. The - time complexity of this algorithm as described in [CK2008]_ is in - `O(n + m)`, where `n` is the number of vertices and `m` is the number of - edges, but our implementation is in `O(n^2)`. + - ``'slow'`` -- it use the generic algorithm for all the lexicographic + searchs. See the documentation of the :mod:`~sage.graphs.traversals` + module for more details. - - ``"fast"`` -- This algorithm uses the notion of *slices* to refine the - position of the vertices in the ordering. The time complexity of this - algorithm is in `O(n + m)`, and our implementation follows that - complexity for ``SparseGraph``. For ``DenseGraph``, the complexity is - `O(n^2)`. See [HMPV2000]_ and next section for more details. + - ``'fast'`` -- this algorithm uses the notion of *partition refinement* + to determine the position of the vertices in the ordering. The time + complexity of this algorithm is in `O(n + m)`, and our implementation + follows that complexity for ``SparseGraph``. For ``DenseGraph``, + the complexity is `O(n^2)`. See [HMPV2000]_ and [TCHP2008]_ for more + details. This algorithm is also used to compute slice decompositions of + undirected graphs, a more thorough description can be found in the + documentation of the + :mod:`~sage.graphs.graph_decompositions.slice_decomposition` module. - ALGORITHM: + .. NOTE:: - The ``"fast"`` algorithm is the `O(n + m)` time algorithm proposed in - [HMPV2000]_, where `n` is the number of vertices and `m` is the number of - edges. It uses the notion of *slices*, i.e., subsets of consecutive vertices - in the ordering, and iteratively refines the slices by subdividing them into - sub-slices to determine the exact position of the vertices in the ordering. - - Consider an ordering `\sigma` of the vertices. For a vertex `v`, we define - `N_i(v) = \{u | u \in N(v) \text{ and } \sigma(u) < i\}`, that is the subset - of neighbors of `v` appearing before the `i`-th vertex in the ordering - `\sigma`. Now, a slice of an ordering `\sigma` is a set of consecutive - vertices, `S = \{u | i \leq \sigma(u) \leq j\}`, such that for any `u \in - S`, we have `N_i(u) = N_i(\sigma^{-1}(i))` and for any `v` such that `j < - \sigma(v)`, `N_i(v) \neq N_i(\sigma^{-1}(i))`. The *head* of a slice is the - first position of its vertices. - - The algorithm starts with a single slice containing all vertices. Then, when - the position of the `i`-th vertex `v` is fixed, it explores the neighbors of - `v` that have not yet been ordered. Consider a slice `S` such that `N(x)\cap - S \neq \emptyset`. The algorithm will rearrange the ordering of the vertices - in `S` so that the first vertices are the neighbors of `v`. The sub-slice - containing the neighbors of `v` is assigned a new slice name, and the head - of slice `S` is set to the position of the first vertex of `S \setminus - N(v)` in the ordering `\sigma`. - - Observe that each arc of the graph can induce the subdivision of a - slice. Hence, the algorithm can use up to `m + 1` different slices. + Loops and multiple edges are ignored during the computation of + ``lex_BFS`` and directed graphs are converted to undirected graphs. .. SEEALSO:: * :wikipedia:`Lexicographic_breadth-first_search` + * :mod:`~sage.graphs.graph_decompositions.slice_decomposition` module + and :meth:`~sage.graphs.graph.Graph.slice_decomposition` -- compute a + slice decomposition of the graph using an extended lex BFS algorithm * :meth:`~sage.graphs.generic_graph.GenericGraph.lex_DFS` -- perform a lexicographic depth first search (LexDFS) on the graph * :meth:`~sage.graphs.generic_graph.GenericGraph.lex_UP` -- perform a @@ -303,7 +363,7 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") A Lex BFS is obviously an ordering of the vertices:: sage: g = graphs.CompleteGraph(6) - sage: len(g.lex_BFS()) == g.order() + sage: set(g.lex_BFS()) == set(g) True Lex BFS ordering of the 3-sun graph:: @@ -315,10 +375,11 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") The method also works for directed graphs:: sage: G = DiGraph([(1, 2), (2, 3), (1, 3)]) - sage: G.lex_BFS(initial_vertex=2, algorithm="slow") - [2, 3, 1] - sage: G.lex_BFS(initial_vertex=2, algorithm="fast") - [2, 3, 1] + sage: correct_anwsers = [[2, 1, 3], [2, 3, 1]] + sage: G.lex_BFS(initial_vertex=2, algorithm='slow') in correct_anwsers + True + sage: G.lex_BFS(initial_vertex=2, algorithm='fast') in correct_anwsers + True For a Chordal Graph, a reversed Lex BFS is a Perfect Elimination Order:: @@ -340,9 +401,9 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") sage: # needs sage.combinat sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000', algorithm="fast") + sage: G.lex_BFS(initial_vertex='000', algorithm='fast') ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_BFS(initial_vertex='000', algorithm="slow") + sage: G.lex_BFS(initial_vertex='000', algorithm='slow') ['000', '001', '100', '010', '011', '110', '101', '111'] sage: G.lex_DFS(initial_vertex='000') ['000', '001', '100', '010', '101', '110', '011', '111'] @@ -358,122 +419,94 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") sage: from sage.graphs.traversals import _is_valid_lex_BFS_order sage: G = graphs.RandomChordalGraph(15) sage: v0 = ZZ.random_element(G.order()) - sage: L = G.lex_BFS(initial_vertex=v0, algorithm="fast") + sage: L = G.lex_BFS(initial_vertex=v0, algorithm='fast') sage: _is_valid_lex_BFS_order(G, L) True - sage: L = G.lex_BFS(initial_vertex=v0, algorithm="slow") + sage: L = G.lex_BFS(initial_vertex=v0, algorithm='slow') sage: _is_valid_lex_BFS_order(G, L) True sage: G = digraphs.RandomDirectedGNP(15, .3) sage: v0 = ZZ.random_element(G.order()) - sage: L = G.lex_BFS(initial_vertex=v0, algorithm="fast") + sage: L = G.lex_BFS(initial_vertex=v0, algorithm='fast') sage: _is_valid_lex_BFS_order(G, L) True - sage: L = G.lex_BFS(initial_vertex=v0, algorithm="slow") + sage: L = G.lex_BFS(initial_vertex=v0, algorithm='slow') sage: _is_valid_lex_BFS_order(G, L) True Lex BFS ordering of a graph on one vertex:: - sage: Graph(1).lex_BFS(tree=True) + sage: Graph(1).lex_BFS(algorithm="fast", tree=True) ([0], Digraph on 1 vertex) Lex BFS ordering of an empty (di)graph is an empty sequence:: sage: g = Graph() - sage: g.lex_BFS() + sage: g.lex_BFS(algorithm="fast") [] + sage: g.lex_BFS(algorithm="fast", tree=True) + ([], Digraph on 0 vertices) Lex BFS ordering of a symmetric digraph should be the same as the Lex BFS ordering of the corresponding undirected graph:: sage: G = Graph([(1, 2), (1, 3), (2, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 5), (5, 6)]) sage: H = DiGraph(G) - sage: G.lex_BFS() == H.lex_BFS() + sage: G.lex_BFS(algorithm="fast") == H.lex_BFS(algorithm="fast") True ``initial_vertex`` should be a valid graph vertex:: sage: G = graphs.CompleteGraph(6) - sage: G.lex_BFS(initial_vertex='foo') + sage: G.lex_BFS(algorithm="fast", initial_vertex='foo') Traceback (most recent call last): ... ValueError: 'foo' is not a graph vertex - """ if initial_vertex is not None and initial_vertex not in G: - raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) - if algorithm not in ['slow', 'fast']: - raise ValueError("unknown algorithm '{}'".format(algorithm)) - if tree: - from sage.graphs.digraph import DiGraph + raise ValueError(f"'{initial_vertex}' is not a graph vertex") - # Loops and multiple edges are not needed in Lex BFS - if G.has_loops() or G.has_multiple_edges(): - G = G.to_simple(immutable=False) + if algorithm == "slow": + return _lex_order_common(G, "lex_BFS", reverse, tree, initial_vertex) - cdef size_t n = G.order() - if not n: - return ([], DiGraph(sparse=True)) if tree else [] + if algorithm != "fast": + raise ValueError(f"unknown algorithm '{algorithm}'") - # Build adjacency list of G - cdef list int_to_v = list(G) - - # If an initial vertex is given, we place it at first position - cdef size_t i - if initial_vertex is not None: - i = int_to_v.index(initial_vertex) - int_to_v[0], int_to_v[i] = int_to_v[i], int_to_v[0] - - # Copying the whole graph to obtain the list of neighbors quicker than by - # calling out_neighbors. This data structure is well documented in the - # module sage.graphs.base.static_sparse_graph - cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v, - sort_neighbors=False) + cdef size_t n = G.order() - # Initialize the predecessors array - cdef MemoryAllocator mem = MemoryAllocator() - cdef uint32_t *sigma_int = mem.allocarray(n, sizeof(uint32_t)) - cdef uint32_t *pred = mem.allocarray(n, sizeof(uint32_t)) - for i in range(n): - pred[i] = i + # For algorithm "fast" we need to convert G to an undirected graph + if G.is_directed(): + G = G.to_undirected() + # Initialize variables needed by the fast and slow algorithms + cdef CGraphBackend Gbackend = G._backend + cdef CGraph cg = Gbackend.cg() cdef list sigma = [] - cdef set vertices - cdef list code - cdef int now, v, vi, int_neighbor + cdef dict predecessor = {} + # Initialize variables needed by the fast algorithm + cdef vector[int] sigma_int + cdef vector[int] pred + # Initialize variables needed by the slow algorithm + cdef dict lexicographic_label + # Temporary variables + cdef int vi, i, initial_v_int # Perform Lex BFS - if algorithm == "fast": - lex_BFS_fast_short_digraph(sd, sigma_int, pred) - sigma = [int_to_v[sigma_int[i]] for i in range(n)] - - else: # "slow" algorithm - vertices = set(range(n)) - code = [[] for i in range(n)] - - # The initial_vertex is at position 0 and so named 0 in sd - code[0].append(n + 1) - now = 1 - while vertices: - v = max(vertices, key=code.__getitem__) - vertices.remove(v) - sigma.append(int_to_v[v]) - for vi in range(out_degree(sd, v)): - int_neighbor = sd.neighbors[v][vi] - if int_neighbor in vertices: - code[int_neighbor].append(n - now) - pred[int_neighbor] = v - now += 1 - - free_short_digraph(sd) + if initial_vertex is not None: + # we already checked that initial_vertex is in G + initial_v_int = Gbackend.get_vertex(initial_vertex) + else: + initial_v_int = -1 + extended_lex_BFS(cg, sigma_int, NULL, initial_v_int, &pred, NULL, NULL) + sigma = [ Gbackend.vertex_label(vi) for vi in sigma_int ] + predecessor = { u: sigma[i] for u, i in zip(sigma, pred) if i != -1 } if reverse: sigma.reverse() if tree: - edges = [(int_to_v[i], int_to_v[pred[i]]) for i in range(n) if pred[i] != i] + from sage.graphs.digraph import DiGraph + edges = predecessor.items() g = DiGraph([G, edges], format='vertices_and_edges', sparse=True) return sigma, g return sigma @@ -492,25 +525,15 @@ def lex_UP(G, reverse=False, tree=False, initial_vertex=None): - ``tree`` -- boolean (default: ``False``); whether to return the discovery directed tree (each vertex being linked to the one that saw - it for the first time) + it last) - - ``initial_vertex`` -- (default: ``None``); the first vertex to + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider - ALGORITHM: - - This algorithm maintains for each vertex left in the graph a code - corresponding to the vertices already removed. The vertex of maximal - code (according to the lexicographic order) is then removed, and the - codes are updated. During the `i`-th iteration of the algorithm `i` is - appended to the codes of all neighbors of the selected vertex that are left - in the graph. - - Time complexity is `O(n+m)` for ``SparseGraph`` and `O(n^2)` for - ``DenseGraph`` where `n` is the number of vertices and `m` is the number of - edges. + .. NOTE:: - See [Mil2017]_ for more details on the algorithm. + Loops and multiple edges are ignored during the computation of + ``lex_UP`` and directed graphs are converted to undirected graphs. .. SEEALSO:: @@ -521,12 +544,16 @@ def lex_UP(G, reverse=False, tree=False, initial_vertex=None): * :meth:`~sage.graphs.generic_graph.GenericGraph.lex_DOWN` -- perform a lexicographic DOWN search (LexDOWN) on the graph + ALGORITHM: + + See the documentation of the :mod:`~sage.graphs.traversals` module. + EXAMPLES: A Lex UP is obviously an ordering of the vertices:: sage: g = graphs.CompleteGraph(6) - sage: len(g.lex_UP()) == g.order() + sage: set(g.lex_UP()) == set(g) True Lex UP ordering of the 3-sun graph:: @@ -538,8 +565,9 @@ def lex_UP(G, reverse=False, tree=False, initial_vertex=None): The method also works for directed graphs:: sage: G = DiGraph([(1, 2), (2, 3), (1, 3)]) - sage: G.lex_UP(initial_vertex=2) - [2, 3, 1] + sage: correct_anwsers = [[2, 1, 3], [2, 3, 1]] + sage: G.lex_UP(initial_vertex=2) in correct_anwsers + True Different orderings for different traversals:: @@ -553,104 +581,8 @@ def lex_UP(G, reverse=False, tree=False, initial_vertex=None): ['000', '001', '010', '101', '110', '111', '011', '100'] sage: G.lex_DOWN(initial_vertex='000') ['000', '001', '100', '011', '010', '110', '111', '101'] - - TESTS: - - Lex UP ordering of a graph on one vertex:: - - sage: Graph(1).lex_UP(tree=True) - ([0], Digraph on 1 vertex) - - Lex UP ordering of an empty (di)graph is an empty sequence:: - - sage: g = Graph() - sage: g.lex_UP() - [] - - Lex UP ordering of a symmetric digraph should be the same as the Lex UP - ordering of the corresponding undirected graph:: - - sage: G = Graph([(1, 2), (1, 3), (2, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 5), (5, 6)]) - sage: H = DiGraph(G) - sage: G.lex_UP() == H.lex_UP() - True - - ``initial_vertex`` should be a valid graph vertex:: - - sage: G = graphs.CompleteGraph(6) - sage: G.lex_UP(initial_vertex='foo') - Traceback (most recent call last): - ... - ValueError: 'foo' is not a graph vertex - """ - if initial_vertex is not None and initial_vertex not in G: - raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) - - # Loops and multiple edges are not needed in Lex UP - if G.allows_loops() or G.allows_multiple_edges(): - G = G.to_simple(immutable=False) - - cdef int nV = G.order() - - if not nV: - if tree: - from sage.graphs.digraph import DiGraph - g = DiGraph(sparse=True) - return [], g - return [] - - # Build adjacency list of G - cdef list int_to_v = list(G) - - cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v, - sort_neighbors=False) - - # Perform Lex UP - - cdef list code = [[] for i in range(nV)] - - def l_func(x): - return code[x] - - cdef list value = [] - - # Initialize the predecessors array - cdef MemoryAllocator mem = MemoryAllocator() - cdef int *pred = mem.allocarray(nV, sizeof(int)) - memset(pred, -1, nV * sizeof(int)) - - cdef set vertices = set(range(nV)) - - cdef int source = 0 if initial_vertex is None else int_to_v.index(initial_vertex) - code[source].append(nV + 1) - - cdef int now = 1, v, int_neighbor - while vertices: - v = max(vertices, key=l_func) - vertices.remove(v) - for i in range(0, out_degree(sd, v)): - int_neighbor = sd.neighbors[v][i] - if int_neighbor in vertices: - code[int_neighbor].append(now) - pred[int_neighbor] = v - value.append(int_to_v[v]) - now += 1 - - free_short_digraph(sd) - - if reverse: - value.reverse() - - if tree: - from sage.graphs.digraph import DiGraph - g = DiGraph(sparse=True) - g.add_vertices(G) - edges = [(int_to_v[i], int_to_v[pred[i]]) for i in range(nV) if pred[i] != -1] - g.add_edges(edges) - return value, g - return value + return _lex_order_common(G, "lex_UP", reverse, tree, initial_vertex) def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): @@ -666,24 +598,15 @@ def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): - ``tree`` -- boolean (default: ``False``); whether to return the discovery directed tree (each vertex being linked to the one that saw - it for the first time) + it last) - - ``initial_vertex`` -- (default: ``None``); the first vertex to + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider - ALGORITHM: - - This algorithm maintains for each vertex left in the graph a code - corresponding to the vertices already removed. The vertex of maximal - code (according to the lexicographic order) is then removed, and the - codes are updated. Lex DFS differs from Lex BFS only in the way codes are - updated after each iteration. - - Time complexity is `O(n+m)` for ``SparseGraph`` and `O(n^2)` for - ``DenseGraph`` where `n` is the number of vertices and `m` is the number of - edges. + .. NOTE:: - See [CK2008]_ for more details on the algorithm. + Loops and multiple edges are ignored during the computation of + ``lex_DFS`` and directed graphs are converted to undirected graphs. .. SEEALSO:: @@ -694,12 +617,16 @@ def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): * :meth:`~sage.graphs.generic_graph.GenericGraph.lex_DOWN` -- perform a lexicographic DOWN search (LexDOWN) on the graph + ALGORITHM: + + See the documentation of the :mod:`~sage.graphs.traversals` module. + EXAMPLES: A Lex DFS is obviously an ordering of the vertices:: sage: g = graphs.CompleteGraph(6) - sage: len(g.lex_DFS()) == g.order() + sage: set(g.lex_DFS()) == set(g) True Lex DFS ordering of the 3-sun graph:: @@ -711,8 +638,9 @@ def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): The method also works for directed graphs:: sage: G = DiGraph([(1, 2), (2, 3), (1, 3)]) - sage: G.lex_DFS(initial_vertex=2) - [2, 3, 1] + sage: correct_anwsers = [[2, 1, 3], [2, 3, 1]] + sage: G.lex_DFS(initial_vertex=2) in correct_anwsers + True Different orderings for different traversals:: @@ -726,105 +654,8 @@ def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): ['000', '001', '010', '101', '110', '111', '011', '100'] sage: G.lex_DOWN(initial_vertex='000') ['000', '001', '100', '011', '010', '110', '111', '101'] - - TESTS: - - Lex DFS ordering of a graph on one vertex:: - - sage: Graph(1).lex_DFS(tree=True) - ([0], Digraph on 1 vertex) - - Lex DFS ordering of an empty (di)graph is an empty sequence:: - - sage: g = Graph() - sage: g.lex_DFS() - [] - - Lex DFS ordering of a symmetric digraph should be the same as the Lex DFS - ordering of the corresponding undirected graph:: - - sage: G = Graph([(1, 2), (1, 3), (2, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 5), (5, 6)]) - sage: H = DiGraph(G) - sage: G.lex_DFS() == H.lex_DFS() - True - - ``initial_vertex`` should be a valid graph vertex:: - - sage: G = graphs.CompleteGraph(6) - sage: G.lex_DFS(initial_vertex='foo') - Traceback (most recent call last): - ... - ValueError: 'foo' is not a graph vertex - """ - if initial_vertex is not None and initial_vertex not in G: - raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) - - # Loops and multiple edges are not needed in Lex DFS - if G.allows_loops() or G.allows_multiple_edges(): - G = G.to_simple(immutable=False) - - cdef int nV = G.order() - - if not nV: - if tree: - from sage.graphs.digraph import DiGraph - g = DiGraph(sparse=True) - return [], g - return [] - - # Build adjacency list of G - cdef list int_to_v = list(G) - - cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v, - sort_neighbors=False) - - # Perform Lex DFS - - # We are using deque in order to prepend items in list efficiently - cdef list code = [deque([]) for i in range(nV)] - - def l_func(x): - return code[x] - - cdef list value = [] - - # initialize the predecessors array - cdef MemoryAllocator mem = MemoryAllocator() - cdef int *pred = mem.allocarray(nV, sizeof(int)) - memset(pred, -1, nV * sizeof(int)) - - cdef set vertices = set(range(nV)) - - cdef int source = 0 if initial_vertex is None else int_to_v.index(initial_vertex) - code[source].appendleft(0) - - cdef int now = 1, v, int_neighbor - while vertices: - v = max(vertices, key=l_func) - vertices.remove(v) - for i in range(0, out_degree(sd, v)): - int_neighbor = sd.neighbors[v][i] - if int_neighbor in vertices: - code[int_neighbor].appendleft(now) - pred[int_neighbor] = v - value.append(int_to_v[v]) - now += 1 - - free_short_digraph(sd) - - if reverse: - value.reverse() - - if tree: - from sage.graphs.digraph import DiGraph - g = DiGraph(sparse=True) - g.add_vertices(G) - edges = [(int_to_v[i], int_to_v[pred[i]]) for i in range(nV) if pred[i] != -1] - g.add_edges(edges) - return value, g - return value + return _lex_order_common(G, "lex_DFS", reverse, tree, initial_vertex) def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): @@ -840,25 +671,15 @@ def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): - ``tree`` -- boolean (default: ``False``); whether to return the discovery directed tree (each vertex being linked to the one that saw - it for the first time) + it) - - ``initial_vertex`` -- (default: ``None``); the first vertex to + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider - ALGORITHM: - - This algorithm maintains for each vertex left in the graph a code - corresponding to the vertices already removed. The vertex of maximal - code (according to the lexicographic order) is then removed, and the - codes are updated. During the `i`-th iteration of the algorithm `n-i` is - prepended to the codes of all neighbors of the selected vertex that are left - in the graph. - - Time complexity is `O(n+m)` for ``SparseGraph`` and `O(n^2)` for - ``DenseGraph`` where `n` is the number of vertices and `m` is the number of - edges. + .. NOTE:: - See [Mil2017]_ for more details on the algorithm. + Loops and multiple edges are ignored during the computation of + ``lex_DOWN`` and directed graphs are converted to undirected graphs. .. SEEALSO:: @@ -869,12 +690,16 @@ def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): * :meth:`~sage.graphs.generic_graph.GenericGraph.lex_UP` -- perform a lexicographic UP search (LexUP) on the graph + ALGORITHM: + + See the documentation of the :mod:`~sage.graphs.traversals` module. + EXAMPLES: A Lex DOWN is obviously an ordering of the vertices:: sage: g = graphs.CompleteGraph(6) - sage: len(g.lex_DOWN()) == g.order() + sage: set(g.lex_DOWN()) == set(g) True Lex DOWN ordering of the 3-sun graph:: @@ -886,8 +711,9 @@ def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): The method also works for directed graphs:: sage: G = DiGraph([(1, 2), (2, 3), (1, 3)]) - sage: G.lex_DOWN(initial_vertex=2) - [2, 3, 1] + sage: correct_anwsers = [[2, 1, 3], [2, 3, 1]] + sage: G.lex_DOWN(initial_vertex=2) in correct_anwsers + True Different orderings for different traversals:: @@ -901,105 +727,8 @@ def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): ['000', '001', '010', '101', '110', '111', '011', '100'] sage: G.lex_DOWN(initial_vertex='000') ['000', '001', '100', '011', '010', '110', '111', '101'] - - TESTS: - - Lex DOWN ordering of a graph on one vertex:: - - sage: Graph(1).lex_DOWN(tree=True) - ([0], Digraph on 1 vertex) - - Lex DOWN ordering of an empty (di)graph is an empty sequence:: - - sage: g = Graph() - sage: g.lex_DOWN() - [] - - Lex DOWN ordering of a symmetric digraph should be the same as the Lex DOWN - ordering of the corresponding undirected graph:: - - sage: G = Graph([(1, 2), (1, 3), (2, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 5), (5, 6)]) - sage: H = DiGraph(G) - sage: G.lex_DOWN() == H.lex_DOWN() - True - - ``initial_vertex`` should be a valid graph vertex:: - - sage: G = graphs.CompleteGraph(6) - sage: G.lex_DOWN(initial_vertex='foo') - Traceback (most recent call last): - ... - ValueError: 'foo' is not a graph vertex - """ - if initial_vertex is not None and initial_vertex not in G: - raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) - - # Loops and multiple edges are not needed in Lex DOWN - if G.allows_loops() or G.allows_multiple_edges(): - G = G.to_simple(immutable=False) - - cdef int nV = G.order() - - if not nV: - if tree: - from sage.graphs.digraph import DiGraph - g = DiGraph(sparse=True) - return [], g - return [] - - # Build adjacency list of G - cdef list int_to_v = list(G) - - cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v, - sort_neighbors=False) - - # Perform Lex DOWN - - # We are using deque in order to prepend items in list efficiently - cdef list code = [deque([]) for i in range(nV)] - - def l_func(x): - return code[x] - - cdef list value = [] - - # initialize the predecessors array - cdef MemoryAllocator mem = MemoryAllocator() - cdef int *pred = mem.allocarray(nV, sizeof(int)) - memset(pred, -1, nV * sizeof(int)) - - cdef set vertices = set(range(nV)) - - cdef int source = 0 if initial_vertex is None else int_to_v.index(initial_vertex) - code[source].appendleft(0) - - cdef int now = 1, v, int_neighbor - while vertices: - v = max(vertices, key=l_func) - vertices.remove(v) - for i in range(0, out_degree(sd, v)): - int_neighbor = sd.neighbors[v][i] - if int_neighbor in vertices: - code[int_neighbor].appendleft(nV - now) - pred[int_neighbor] = v - value.append(int_to_v[v]) - now += 1 - - free_short_digraph(sd) - - if reverse: - value.reverse() - - if tree: - from sage.graphs.digraph import DiGraph - g = DiGraph(sparse=True) - g.add_vertices(G) - edges = [(int_to_v[i], int_to_v[pred[i]]) for i in range(nV) if pred[i] != -1] - g.add_edges(edges) - return value, g - return value + return _lex_order_common(G, "lex_DOWN", reverse, tree, initial_vertex) def lex_M(self, triangulation=False, labels=False, initial_vertex=None, algorithm=None): @@ -1024,7 +753,7 @@ def lex_M(self, triangulation=False, labels=False, initial_vertex=None, algorith - ``labels`` -- boolean (default: ``False``); whether to return the labels assigned to each vertex - - ``initial_vertex`` -- (default: ``None``); the first vertex to + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider - ``algorithm`` -- string (default: ``None``); one of the following @@ -1129,7 +858,6 @@ def lex_M(self, triangulation=False, labels=False, initial_vertex=None, algorith Traceback (most recent call last): ... ValueError: 'foo' is not a graph vertex - """ if initial_vertex is not None and initial_vertex not in self: raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) @@ -1185,7 +913,7 @@ def lex_M_slow(G, triangulation=False, labels=False, initial_vertex=None): - ``labels`` -- boolean (default: ``False``); whether to return the labels assigned to each vertex - - ``initial_vertex`` -- (default: ``None``); the first vertex to + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider. If not specified, an arbitrary vertex is chosen. OUTPUT: @@ -1252,7 +980,6 @@ def lex_M_slow(G, triangulation=False, labels=False, initial_vertex=None): Traceback (most recent call last): ... ValueError: 'foo' is not a graph vertex - """ if initial_vertex is not None and initial_vertex not in G: raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) @@ -1339,7 +1066,7 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): - ``triangulation`` -- boolean (default: ``False``); whether to return the triangulation of given graph produced by the method - - ``initial_vertex`` -- (default: ``None``); the first vertex to consider + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider OUTPUT: @@ -1400,7 +1127,6 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): Traceback (most recent call last): ... ValueError: 'foo' is not a graph vertex - """ if initial_vertex is not None and initial_vertex not in G: raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) @@ -1419,8 +1145,7 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): int_to_v[0], int_to_v[i] = int_to_v[i], int_to_v[0] cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v) cdef uint32_t* p_tmp cdef uint32_t* p_end @@ -1610,7 +1335,7 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None discovery directed tree (each vertex being linked to the one that saw it for the first time) - - ``initial_vertex`` -- (default: ``None``); the first vertex to consider + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider OUTPUT: @@ -1683,8 +1408,7 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None raise ValueError("vertex ({0}) is not a vertex of the graph".format(initial_vertex)) cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef uint32_t** p_vertices = sd.neighbors cdef uint32_t* p_tmp cdef uint32_t* p_end @@ -1742,7 +1466,7 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None if tree: D = DiGraph([int_to_vertex, [(int_to_vertex[i], int_to_vertex[pred[i]]) for i in range(N) if pred[i] != i]], - format="vertices_and_edges") + format='vertices_and_edges') return alpha, D return alpha @@ -1786,7 +1510,7 @@ cdef maximum_cardinality_search_M_short_digraph(short_digraph sd, int initial_ve - ``sd`` -- a ``short_digraph`` as documented in :mod:`~sage.graphs.base.static_sparse_graph` - - ``initial_vertex`` -- int; initial vertex for the search + - ``initial_vertex`` -- integer; initial vertex for the search - ``alpha`` -- int array of size `N`; the computed ordering of MCS-M @@ -1938,7 +1662,7 @@ def maximum_cardinality_search_M(G, initial_vertex=None): - ``G`` -- a Sage graph - - ``initial_vertex`` -- (default: ``None``); the first vertex to consider + - ``initial_vertex`` -- (default: ``None``) the first vertex to consider OUTPUT: a tuple `(\alpha, F, X)`, where @@ -2058,8 +1782,7 @@ def maximum_cardinality_search_M(G, initial_vertex=None): # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex, - sort_neighbors=False) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef MemoryAllocator mem = MemoryAllocator() cdef int* alpha = mem.calloc(N, sizeof(int)) diff --git a/src/sage/graphs/trees.pyx b/src/sage/graphs/trees.pyx index 2fd64e9ef43..bcaab0c88ad 100644 --- a/src/sage/graphs/trees.pyx +++ b/src/sage/graphs/trees.pyx @@ -55,7 +55,7 @@ cdef class TreeIterator: def __init__(self, int vertices): r""" - Initializes an iterator over all trees with `n` vertices. + Initialize an iterator over all trees with `n` vertices. EXAMPLES:: @@ -93,7 +93,7 @@ cdef class TreeIterator: def __iter__(self): r""" - Returns an iterator over all the trees with `n` vertices. + Return an iterator over all the trees with `n` vertices. EXAMPLES:: @@ -106,7 +106,7 @@ cdef class TreeIterator: def __next__(self): r""" - Returns the next tree with `n` vertices + Return the next tree with `n` vertices. EXAMPLES:: diff --git a/src/sage/graphs/tutte_polynomial.py b/src/sage/graphs/tutte_polynomial.py index fcd7acd6d3d..042fb4c286b 100644 --- a/src/sage/graphs/tutte_polynomial.py +++ b/src/sage/graphs/tutte_polynomial.py @@ -9,7 +9,7 @@ :widths: 30, 70 :delim: | - :func:`tutte_polynomial` | Computes the Tutte polynomial of the input graph + :func:`tutte_polynomial` | Compute the Tutte polynomial of the input graph Authors: @@ -250,7 +250,7 @@ def __init__(self, graph, end_points, interior, is_cycle): @property def s(self): """ - Returns the number of distinct edges in this ear. + Return the number of distinct edges in this ear. EXAMPLES:: @@ -266,7 +266,7 @@ def s(self): @property def vertices(self): """ - Returns the vertices of this ear. + Return the vertices of this ear. EXAMPLES:: @@ -282,7 +282,7 @@ def vertices(self): @lazy_attribute def unlabeled_edges(self): """ - Returns the edges in this ear. + Return the edges in this ear. EXAMPLES:: @@ -468,7 +468,7 @@ def __call__(self, graph): def _cache_key(G): """ - Return the key used to cache the result for the graph G + Return the key used to cache the result for the graph G. This is used by the decorator :func:`_cached`. @@ -484,7 +484,7 @@ def _cache_key(G): def _cached(func): """ - Wrapper used to cache results of the function `func` + Wrapper used to cache results of the function `func`. This uses the function :func:`_cache_key`. @@ -520,11 +520,11 @@ def tutte_polynomial(G, edge_selector=None, cache=None): INPUT: - - ``edge_selector`` (optional; method) this argument allows the user + - ``edge_selector`` -- method (optional); this argument allows the user to specify his own heuristic for selecting edges used in the deletion contraction recurrence - - ``cache`` -- (optional; dict) a dictionary to cache the Tutte + - ``cache`` -- (optional) dictionary to cache the Tutte polynomials generated in the recursive process. One will be created automatically if not provided. @@ -600,7 +600,7 @@ def tutte_polynomial(G, edge_selector=None, cache=None): @_cached def _tutte_polynomial_internal(G, x, y, edge_selector, cache=None): """ - Does the recursive computation of the Tutte polynomial. + Do the recursive computation of the Tutte polynomial. INPUT: diff --git a/src/sage/graphs/views.pyx b/src/sage/graphs/views.pyx index 95da1be4b64..8dd73c928d4 100644 --- a/src/sage/graphs/views.pyx +++ b/src/sage/graphs/views.pyx @@ -204,7 +204,7 @@ cdef class EdgesView: sage: G.has_edge(1, 0) False - We can consider only the edges between two specifed sets of vertices:: + We can consider only the edges between two specified sets of vertices:: sage: G = Graph([(0, 1), (1, 2)]) sage: E = EdgesView(G, vertices=[0], vertices2=[1], labels=False) diff --git a/src/sage/graphs/weakly_chordal.pyx b/src/sage/graphs/weakly_chordal.pyx index aa91cfa9cdc..37961e273e5 100644 --- a/src/sage/graphs/weakly_chordal.pyx +++ b/src/sage/graphs/weakly_chordal.pyx @@ -10,9 +10,9 @@ contains the following functions: :widths: 30, 70 :delim: | - :meth:`~sage.graphs.weakly_chordal.is_long_hole_free` | Tests whether ``g`` contains an induced cycle of length at least 5. - :meth:`~sage.graphs.weakly_chordal.is_long_antihole_free` | Tests whether ``g`` contains an induced anticycle of length at least 5. - :meth:`~sage.graphs.weakly_chordal.is_weakly_chordal` | Tests whether ``g`` is weakly chordal. + :meth:`~sage.graphs.weakly_chordal.is_long_hole_free` | Test whether ``g`` contains an induced cycle of length at least 5. + :meth:`~sage.graphs.weakly_chordal.is_long_antihole_free` | Test whether ``g`` contains an induced anticycle of length at least 5. + :meth:`~sage.graphs.weakly_chordal.is_weakly_chordal` | Test whether ``g`` is weakly chordal. Author: @@ -136,7 +136,7 @@ cdef inline is_long_hole_free_process(g, short_digraph sd, bitset_t dense_graph, def is_long_hole_free(g, certificate=False): r""" - Tests whether ``g`` contains an induced cycle of length at least 5. + Test whether ``g`` contains an induced cycle of length at least 5. INPUT: @@ -213,8 +213,7 @@ def is_long_hole_free(g, certificate=False): cdef int n = g.order() cdef list id_label = list(g) cdef short_digraph sd - init_short_digraph(sd, g, edge_labelled=False, vertex_list=id_label, - sort_neighbors=False) + init_short_digraph(sd, g, edge_labelled=False, vertex_list=id_label) # Make a dense copy of the graph for quick adjacency tests cdef bitset_t dense_graph @@ -364,7 +363,7 @@ cdef inline is_long_antihole_free_process(g, short_digraph sd, bitset_t dense_gr def is_long_antihole_free(g, certificate=False): r""" - Tests whether the given graph contains an induced subgraph that is + Test whether the given graph contains an induced subgraph that is isomorphic to the complement of a cycle of length at least 5. INPUT: @@ -508,12 +507,12 @@ def is_long_antihole_free(g, certificate=False): def is_weakly_chordal(g, certificate=False): r""" - Tests whether the given graph is weakly chordal, i.e., the graph and its + Test whether the given graph is weakly chordal, i.e., the graph and its complement have no induced cycle of length at least 5. INPUT: - - ``certificate`` -- Boolean value (default: ``False``) whether to + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate. If ``certificate = False``, return ``True`` or ``False`` according to the graph. If ``certificate = True``, return @@ -528,9 +527,9 @@ def is_weakly_chordal(g, certificate=False): contain an induced cycle of length at least 5. Using is_long_hole_free() and is_long_antihole_free() yields a run time - of `O(n+m^2)` for ``SparseGraph`` and `O(n^2\log{m} + m^2)` for - ``DenseGraph`` (where `n` is the number of vertices and `m` is the number of - edges of the graph). + of `O(n+m^2)` for ``SparseGraph`` and `O(n^2 + m^2)` for ``DenseGraph`` + (where `n` is the number of vertices and `m` is the number of edges of the + graph). EXAMPLES: @@ -548,7 +547,6 @@ def is_weakly_chordal(g, certificate=False): sage: graphs.EmptyGraph().is_weakly_chordal() True - """ if g.order() < 5: return (True, []) if certificate else True diff --git a/src/sage/groups/abelian_gps/abelian_aut.py b/src/sage/groups/abelian_gps/abelian_aut.py index 9fa9515f934..7108f311a48 100644 --- a/src/sage/groups/abelian_gps/abelian_aut.py +++ b/src/sage/groups/abelian_gps/abelian_aut.py @@ -94,7 +94,7 @@ class AbelianGroupAutomorphism(ElementLibGAP): - ``x`` -- a libgap element - ``parent`` -- the parent :class:`~AbelianGroupAutomorphismGroup_gap` - - ``check`` -- bool (default: ``True``) checks if ``x`` is an element + - ``check`` -- boolean (default: ``True``); checks if ``x`` is an element of the group EXAMPLES:: @@ -481,7 +481,7 @@ class AbelianGroupAutomorphismGroup_subgroup(AbelianGroupAutomorphismGroup_gap): INPUT: - ``ambient`` -- the ambient group - - ``generators`` -- a tuple of gap elements of the ambient group + - ``generators`` -- tuple of gap elements of the ambient group EXAMPLES:: diff --git a/src/sage/groups/abelian_gps/abelian_group.py b/src/sage/groups/abelian_gps/abelian_group.py index b13be80cc16..0ad20d9d4fa 100644 --- a/src/sage/groups/abelian_gps/abelian_group.py +++ b/src/sage/groups/abelian_gps/abelian_group.py @@ -15,9 +15,9 @@ \vec{k} = (0, \dots, 0, k_1, \dots, k_t) -where there are `r` zeroes and `t` non-zero values. To construct this +where there are `r` zeroes and `t` nonzero values. To construct this Abelian group in Sage, you can either specify all entries of `\vec{k}` -or only the non-zero entries together with the total number of +or only the nonzero entries together with the total number of generators:: sage: AbelianGroup([0,0,0,2,3]) @@ -324,7 +324,7 @@ def word_problem(words, g, verbose=False): return [[words[indi - 1], powi] for indi, powi in zip(indices, powers)] -def _normalize(n, gens_orders=None, names="f"): +def _normalize(n, gens_orders=None, names='f'): """ Helper function for :func:`AbelianGroup`. Beat some sense into the arguments. @@ -334,7 +334,7 @@ def _normalize(n, gens_orders=None, names="f"): INPUT: - See :func:`AbelianGroup` + See :func:`AbelianGroup`. OUTPUT: @@ -383,26 +383,26 @@ def _normalize(n, gens_orders=None, names="f"): return (gens_orders, names) -def AbelianGroup(n, gens_orders=None, names="f"): +def AbelianGroup(n, gens_orders=None, names='f'): r""" Create the multiplicative abelian group in `n` generators with given orders of generators (which need not be prime powers). INPUT: - - ``n`` -- integer (optional). If not specified, will be derived - from ``gens_orders``. + - ``n`` -- integer (optional); if not specified, will be derived + from ``gens_orders`` - - ``gens_orders`` -- a list of non-negative integers in the form + - ``gens_orders`` -- list of nonnegative integers in the form `[a_0, a_1, \dots, a_{n-1}]`, typically written in increasing order. This list is padded with zeros if it has length less than `n`. The orders of the commuting generators, with `0` denoting an infinite cyclic factor. - - ``names`` -- (optional) names of generators + - ``names`` -- (optional) names of generators Alternatively, you can also give input in the form - ``AbelianGroup(gens_orders, names="f")``, where the names keyword + ``AbelianGroup(gens_orders, names='f')``, where the names keyword argument must be explicitly named. OUTPUT: @@ -422,7 +422,7 @@ def AbelianGroup(n, gens_orders=None, names="f"): b^2*c^3*d sage: F = AbelianGroup(3, [2]*3); F Multiplicative Abelian group isomorphic to C2 x C2 x C2 - sage: H = AbelianGroup([2,3], names="xy"); H + sage: H = AbelianGroup([2,3], names='xy'); H Multiplicative Abelian group isomorphic to C2 x C3 sage: AbelianGroup(5) Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z @@ -486,7 +486,7 @@ class AbelianGroup_class(UniqueRepresentation, AbelianGroupBase): (commuting) generators. Zero denotes an infinite cyclic generator. - - ``names`` -- names of the group generators (optional). + - ``names`` -- names of the group generators (optional) EXAMPLES:: @@ -564,7 +564,7 @@ def is_isomorphic(left, right): INPUT: - - ``right`` -- anything. + - ``right`` -- anything OUTPUT: boolean; whether ``left`` and ``right`` are isomorphic as abelian groups @@ -676,17 +676,17 @@ def __bool__(self) -> bool: return not self.is_trivial() @cached_method - def dual_group(self, names="X", base_ring=None): + def dual_group(self, names='X', base_ring=None): """ Return the dual group. INPUT: - ``names`` -- string or list of strings. The generator names - for the dual group. + for the dual group - - ``base_ring`` -- the base ring. If ``None`` (default), then - a suitable cyclotomic field is picked automatically. + - ``base_ring`` -- the base ring; if ``None`` (default), then + a suitable cyclotomic field is picked automatically OUTPUT: the :class:`dual abelian group ` @@ -861,7 +861,7 @@ def _libgap_(self): Requires the optional ``gap_packages`` for infinite groups:: - sage: G = AbelianGroup(3, [0,3,4], names="abc") + sage: G = AbelianGroup(3, [0,3,4], names='abc') sage: libgap(G) # optional - gap_package_polycyclic Pcp-group with orders [ 0, 3, 4 ] """ @@ -872,7 +872,7 @@ def _libgap_(self): # Make sure to LoadPackage("Polycyclic") in gap from sage.features.gap import GapPackage - GapPackage("polycyclic", spkg="gap_packages").require() + GapPackage("polycyclic", spkg='gap_packages').require() return libgap.AbelianPcpGroup(self.gens_orders()) def _gap_init_(self): @@ -889,7 +889,7 @@ def _gap_init_(self): Requires the optional ``gap_packages`` for infinite groups:: - sage: G = AbelianGroup(3,[0,3,4], names="abc"); G + sage: G = AbelianGroup(3,[0,3,4], names='abc'); G Multiplicative Abelian group isomorphic to Z x C3 x C4 sage: G._gap_init_() # optional - gap_package_polycyclic 'AbelianPcpGroup([0, 3, 4])' @@ -899,7 +899,7 @@ def _gap_init_(self): from sage.features.gap import GapPackage # Make sure to LoadPackage("Polycyclic") in gap - GapPackage("polycyclic", spkg="gap_packages").require() + GapPackage("polycyclic", spkg='gap_packages').require() return 'AbelianPcpGroup(%s)' % list(self.gens_orders()) def gen(self, i=0): @@ -1192,7 +1192,7 @@ def _repr_(self) -> str: g = self._group_notation(eldv) return "Multiplicative Abelian group isomorphic to " + g - def subgroup(self, gensH, names="f"): + def subgroup(self, gensH, names='f'): """ Create a subgroup of this group. @@ -1293,7 +1293,7 @@ def __iter__(self): sage: L[0] = 0 sage: list(G) [1, b, b^2, a, a*b, a*b^2] - sage: G = AbelianGroup([1], names="a") + sage: G = AbelianGroup([1], names='a') sage: list(G) [1] sage: G = AbelianGroup([]) @@ -1616,7 +1616,7 @@ class AbelianGroup_subgroup(AbelianGroup_class): There should be a way to coerce an element of a subgroup into the ambient group. """ - def __init__(self, ambient, gens, names="f", category=None): + def __init__(self, ambient, gens, names='f', category=None): """ EXAMPLES:: @@ -1646,7 +1646,7 @@ def __init__(self, ambient, gens, names="f", category=None): 5 sage: z.order() 64 - sage: A = AbelianGroup(5, [3, 5, 5, 7, 8], names="abcde") + sage: A = AbelianGroup(5, [3, 5, 5, 7, 8], names='abcde') sage: a,b,c,d,e = A.gens() sage: A.subgroup([a,b]) Multiplicative Abelian subgroup isomorphic to C3 x C5 generated by {a, b} @@ -1658,7 +1658,7 @@ def __init__(self, ambient, gens, names="f", category=None): Multiplicative Abelian subgroup isomorphic to C4 x C5 x C5 x C7 generated by {b, c, d, e^2} sage: B.gens_orders() (4, 5, 5, 7) - sage: A = AbelianGroup(4,[1009, 2003, 3001, 4001], names="abcd") + sage: A = AbelianGroup(4,[1009, 2003, 3001, 4001], names='abcd') sage: a,b,c,d = A.gens() sage: B = A.subgroup([a^3,b,c,d]) sage: B.gens_orders() @@ -1667,7 +1667,7 @@ def __init__(self, ambient, gens, names="f", category=None): 24266473210027 sage: B.order() 24266473210027 - sage: A = AbelianGroup(4, [1008, 2003, 3001, 4001], names="abcd") + sage: A = AbelianGroup(4, [1008, 2003, 3001, 4001], names='abcd') sage: a,b,c,d = A.gens() sage: B = A.subgroup([a^3,b,c,d]); B Multiplicative Abelian subgroup isomorphic @@ -1676,7 +1676,7 @@ def __init__(self, ambient, gens, names="f", category=None): Infinite groups can also be handled:: sage: # needs sage.libs.gap # optional - gap_package_polycyclic - sage: G = AbelianGroup([3,4,0], names="abc") + sage: G = AbelianGroup([3,4,0], names='abc') sage: a,b,c = G.gens() sage: F = G.subgroup([a, b^2, c]); F Multiplicative Abelian subgroup isomorphic to C2 x C3 x Z @@ -1808,7 +1808,7 @@ def equals(left, right): EXAMPLES:: sage: # needs sage.libs.gap # optional - gap_package_polycyclic - sage: G = AbelianGroup(3, [2,3,4], names="abc"); G + sage: G = AbelianGroup(3, [2,3,4], names='abc'); G Multiplicative Abelian group isomorphic to C2 x C3 x C4 sage: a,b,c = G.gens() sage: F = G.subgroup([a,b^2]); F @@ -1882,7 +1882,7 @@ def gens(self) -> tuple: def gen(self, n): """ - Return the nth generator of this subgroup. + Return the `n`-th generator of this subgroup. EXAMPLES:: diff --git a/src/sage/groups/abelian_gps/abelian_group_element.py b/src/sage/groups/abelian_gps/abelian_group_element.py index 172a671906c..956fff7bd9a 100644 --- a/src/sage/groups/abelian_gps/abelian_group_element.py +++ b/src/sage/groups/abelian_gps/abelian_group_element.py @@ -13,7 +13,6 @@ - Volker Braun (2012-11) port to new Parent base. Use tuples for immutables. - EXAMPLES: Recall an example from abelian groups:: @@ -105,7 +104,7 @@ def as_permutation(self): EXAMPLES:: - sage: G = AbelianGroup(3, [2,3,4], names="abc"); G + sage: G = AbelianGroup(3, [2,3,4], names='abc'); G Multiplicative Abelian group isomorphic to C2 x C3 x C4 sage: a,b,c = G.gens() sage: Gp = G.permutation_group(); Gp # needs sage.groups @@ -149,7 +148,7 @@ def word_problem(self, words): EXAMPLES:: sage: # needs sage.libs.gap - sage: G = AbelianGroup(2, [2,3], names="xy") + sage: G = AbelianGroup(2, [2,3], names='xy') sage: x,y = G.gens() sage: x.word_problem([x,y]) [[x, 1]] diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py index 45a6a8bdd1a..199aa935f56 100644 --- a/src/sage/groups/abelian_gps/abelian_group_gap.py +++ b/src/sage/groups/abelian_gps/abelian_group_gap.py @@ -562,7 +562,7 @@ def quotient(self, N): INPUT: - ``N`` -- a subgroup - - ``check`` -- bool (default: ``True``) check if `N` is normal + - ``check`` -- boolean (default: ``True``); check if `N` is normal EXAMPLES:: @@ -584,7 +584,7 @@ def subgroup(self, gens): INPUT: - - ``gens`` -- a list of elements coercible into this group + - ``gens`` -- list of elements coercible into this group OUTPUT: a subgroup @@ -626,7 +626,7 @@ class AbelianGroupGap(AbelianGroup_gap): INPUT: - - ``generator_orders`` -- a list of nonnegative integers where `0` + - ``generator_orders`` -- list of nonnegative integers where `0` gives a factor isomorphic to `\ZZ` OUTPUT: an abelian group @@ -857,11 +857,12 @@ def retract(self, x): """ Convert an element of the ambient group into this subgroup. - The terminology comes from the category framework and the more general notion of a subquotient. + The terminology comes from the category framework and the more general + notion of a subquotient. INPUT: - - ``x`` -- an element of the ambient group that actually lies in this subgroup. + - ``x`` -- an element of the ambient group that actually lies in this subgroup OUTPUT: the corresponding element of this subgroup diff --git a/src/sage/groups/abelian_gps/abelian_group_morphism.py b/src/sage/groups/abelian_gps/abelian_group_morphism.py index eb41400065a..c635ad32cb6 100644 --- a/src/sage/groups/abelian_gps/abelian_group_morphism.py +++ b/src/sage/groups/abelian_gps/abelian_group_morphism.py @@ -55,10 +55,10 @@ class AbelianGroupMorphism(Morphism): EXAMPLES:: - sage: G = AbelianGroup(3,[2,3,4],names="abc"); G + sage: G = AbelianGroup(3,[2,3,4],names='abc'); G Multiplicative Abelian group isomorphic to C2 x C3 x C4 sage: a,b,c = G.gens() - sage: H = AbelianGroup(2,[2,3],names="xy"); H + sage: H = AbelianGroup(2,[2,3],names='xy'); H Multiplicative Abelian group isomorphic to C2 x C3 sage: x,y = H.gens() @@ -124,10 +124,10 @@ def _libgap_(self): EXAMPLES:: - sage: G = AbelianGroup(3,[2,3,4],names="abc"); G + sage: G = AbelianGroup(3,[2,3,4],names='abc'); G Multiplicative Abelian group isomorphic to C2 x C3 x C4 sage: a,b,c = G.gens() - sage: H = AbelianGroup(2,[2,3],names="xy"); H + sage: H = AbelianGroup(2,[2,3],names='xy'); H Multiplicative Abelian group isomorphic to C2 x C3 sage: x,y = H.gens() sage: phi = AbelianGroupMorphism(H,G,[x,y],[a,b]) # optional - gap_package_polycyclic @@ -156,19 +156,19 @@ def kernel(self): EXAMPLES:: - sage: H = AbelianGroup(3,[2,3,4],names="abc"); H + sage: H = AbelianGroup(3,[2,3,4],names='abc'); H Multiplicative Abelian group isomorphic to C2 x C3 x C4 sage: a,b,c = H.gens() - sage: G = AbelianGroup(2,[2,3],names="xy"); G + sage: G = AbelianGroup(2,[2,3],names='xy'); G Multiplicative Abelian group isomorphic to C2 x C3 sage: x,y = G.gens() sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) # optional - gap_package_polycyclic sage: phi.kernel() # optional - gap_package_polycyclic Group([ ]) - sage: H = AbelianGroup(3,[2,2,2],names="abc") + sage: H = AbelianGroup(3,[2,2,2],names='abc') sage: a,b,c = H.gens() - sage: G = AbelianGroup(2,[2,2],names="x") + sage: G = AbelianGroup(2,[2,2],names='x') sage: x,y = G.gens() sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,a]) # optional - gap_package_polycyclic sage: phi.kernel() # optional - gap_package_polycyclic @@ -188,10 +188,10 @@ def image(self, S): EXAMPLES:: - sage: G = AbelianGroup(2,[2,3],names="xy") + sage: G = AbelianGroup(2,[2,3],names='xy') sage: x,y = G.gens() sage: subG = G.subgroup([x]) # optional - gap_package_polycyclic - sage: H = AbelianGroup(3,[2,3,4],names="abc") + sage: H = AbelianGroup(3,[2,3,4],names='abc') sage: a,b,c = H.gens() sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) # optional - gap_package_polycyclic sage: phi.image(subG) # optional - gap_package_polycyclic @@ -206,9 +206,9 @@ def _call_(self, g): EXAMPLES:: - sage: H = AbelianGroup(3, [2,3,4], names="abc") + sage: H = AbelianGroup(3, [2,3,4], names='abc') sage: a,b,c = H.gens() - sage: G = AbelianGroup(2, [2,3], names="xy") + sage: G = AbelianGroup(2, [2,3], names='xy') sage: x,y = G.gens() sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b]) # optional - gap_package_polycyclic sage: phi(y*x) # optional - gap_package_polycyclic diff --git a/src/sage/groups/abelian_gps/dual_abelian_group.py b/src/sage/groups/abelian_gps/dual_abelian_group.py index aaa231b0f81..1c353a90136 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group.py @@ -109,12 +109,12 @@ class DualAbelianGroup_class(UniqueRepresentation, AbelianGroupBase): EXAMPLES:: - sage: F = AbelianGroup(5,[3,5,7,8,9], names="abcde") + sage: F = AbelianGroup(5,[3,5,7,8,9], names='abcde') sage: F.dual_group() Dual of Abelian Group isomorphic to Z/3Z x Z/5Z x Z/7Z x Z/8Z x Z/9Z over Cyclotomic Field of order 2520 and degree 576 - sage: F = AbelianGroup(4,[15,7,8,9], names="abcd") + sage: F = AbelianGroup(4,[15,7,8,9], names='abcd') sage: F.dual_group(base_ring=CC) # needs sage.rings.real_mpfr Dual of Abelian Group isomorphic to Z/15Z x Z/7Z x Z/8Z x Z/9Z over Complex Field with 53 bits of precision @@ -127,7 +127,7 @@ def __init__(self, G, names, base_ring): EXAMPLES:: - sage: F = AbelianGroup(5,[3,5,7,8,9], names="abcde") + sage: F = AbelianGroup(5,[3,5,7,8,9], names='abcde') sage: F.dual_group() Dual of Abelian Group isomorphic to Z/3Z x Z/5Z x Z/7Z x Z/8Z x Z/9Z over Cyclotomic Field of order 2520 and degree 576 @@ -233,8 +233,8 @@ def random_element(self): sage: # needs sage.rings.real_mpfr sage: N = 43^2 - 1 - sage: G = AbelianGroup([N], names="a") - sage: Gd = G.dual_group(names="A", base_ring=CC) + sage: G = AbelianGroup([N], names='a') + sage: Gd = G.dual_group(names='A', base_ring=CC) sage: a, = G.gens() sage: A, = Gd.gens() sage: x = a^(N/4); y = a^(N/3); z = a^(N/14) @@ -257,7 +257,7 @@ def gen(self, i=0): EXAMPLES:: sage: F = AbelianGroup(3, [1,2,3], names='a') - sage: Fd = F.dual_group(names="A") + sage: Fd = F.dual_group(names='A') sage: Fd.0 1 sage: Fd.1 @@ -338,9 +338,9 @@ def __contains__(self, X): EXAMPLES:: - sage: F = AbelianGroup(5,[2, 3, 5, 7, 8], names="abcde") + sage: F = AbelianGroup(5,[2, 3, 5, 7, 8], names='abcde') sage: a,b,c,d,e = F.gens() - sage: Fd = F.dual_group(names="ABCDE") + sage: Fd = F.dual_group(names='ABCDE') sage: A,B,C,D,E = Fd.gens() sage: A*B^2*D^7 in Fd True @@ -383,8 +383,8 @@ def list(self): EXAMPLES:: - sage: G = AbelianGroup([2,3], names="ab") - sage: Gd = G.dual_group(names="AB") + sage: G = AbelianGroup([2,3], names='ab') + sage: Gd = G.dual_group(names='AB') sage: Gd.list() (1, B, B^2, A, A*B, A*B^2) """ @@ -399,15 +399,15 @@ def __iter__(self): EXAMPLES:: - sage: G = AbelianGroup([2,3], names="ab") - sage: Gd = G.dual_group(names="AB") + sage: G = AbelianGroup([2,3], names='ab') + sage: Gd = G.dual_group(names='AB') sage: [X for X in Gd] [1, B, B^2, A, A*B, A*B^2] sage: # needs sage.rings.real_mpfr sage: N = 43^2 - 1 - sage: G = AbelianGroup([N], names="a") - sage: Gd = G.dual_group(names="A", base_ring=CC) + sage: G = AbelianGroup([N], names='a') + sage: Gd = G.dual_group(names='A', base_ring=CC) sage: a, = G.gens() sage: A, = Gd.gens() sage: x = a^(N/4) diff --git a/src/sage/groups/abelian_gps/dual_abelian_group_element.py b/src/sage/groups/abelian_gps/dual_abelian_group_element.py index 048666b020f..db6683910b2 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group_element.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group_element.py @@ -5,11 +5,11 @@ To obtain the dual group of a finite Abelian group, use the :meth:`~sage.groups.abelian_gps.abelian_group.dual_group` method:: - sage: F = AbelianGroup([2,3,5,7,8], names="abcde") + sage: F = AbelianGroup([2,3,5,7,8], names='abcde') sage: F Multiplicative Abelian group isomorphic to C2 x C3 x C5 x C7 x C8 - sage: Fd = F.dual_group(names="ABCDE"); Fd + sage: Fd = F.dual_group(names='ABCDE'); Fd Dual of Abelian Group isomorphic to Z/2Z x Z/3Z x Z/5Z x Z/7Z x Z/8Z over Cyclotomic Field of order 840 and degree 192 @@ -100,9 +100,9 @@ def __call__(self, g): EXAMPLES:: - sage: F = AbelianGroup(5, [2,3,5,7,8], names="abcde") + sage: F = AbelianGroup(5, [2,3,5,7,8], names='abcde') sage: a,b,c,d,e = F.gens() - sage: Fd = F.dual_group(names="ABCDE") + sage: Fd = F.dual_group(names='ABCDE') sage: A,B,C,D,E = Fd.gens() sage: A*B^2*D^7 A*B^2 @@ -117,9 +117,9 @@ def __call__(self, g): TESTS:: - sage: F = AbelianGroup(1, [7], names="a") + sage: F = AbelianGroup(1, [7], names='a') sage: a, = F.gens() - sage: Fd = F.dual_group(names="A", base_ring=GF(29)) + sage: Fd = F.dual_group(names='A', base_ring=GF(29)) sage: A, = Fd.gens() sage: A(a) # needs sage.libs.pari 16 @@ -150,8 +150,8 @@ def word_problem(self, words): EXAMPLES:: - sage: G = AbelianGroup(5,[3, 5, 5, 7, 8], names="abcde") - sage: Gd = G.dual_group(names="abcde") + sage: G = AbelianGroup(5,[3, 5, 5, 7, 8], names='abcde') + sage: Gd = G.dual_group(names='abcde') sage: a,b,c,d,e = Gd.gens() sage: u = a^3*b*c*d^2*e^5 sage: v = a^2*b*c^2*d^3*e^3 diff --git a/src/sage/groups/abelian_gps/element_base.py b/src/sage/groups/abelian_gps/element_base.py index 7712049e219..abaff8a225a 100644 --- a/src/sage/groups/abelian_gps/element_base.py +++ b/src/sage/groups/abelian_gps/element_base.py @@ -30,7 +30,7 @@ class AbelianGroupElementBase(MultiplicativeGroupElement): """ - Base class for abelian group elements + Base class for abelian group elements. The group element is defined by a tuple whose ``i``-th entry is an integer in the range from 0 (inclusively) to ``G.gen(i).order()`` @@ -39,16 +39,16 @@ class AbelianGroupElementBase(MultiplicativeGroupElement): INPUT: - - ``exponents`` -- ``1`` or a list/tuple/iterable of integers. The + - ``exponents`` -- ``1`` or a list/tuple/iterable of integers; the exponent vector (with respect to the parent generators) defining - the group element. + the group element - - ``parent`` -- Abelian group. The parent of the group element. + - ``parent`` -- abelian group; the parent of the group element EXAMPLES:: sage: F = AbelianGroup(3,[7,8,9]) - sage: Fd = F.dual_group(names="ABC") # needs sage.rings.number_field + sage: Fd = F.dual_group(names='ABC') # needs sage.rings.number_field sage: A,B,C = Fd.gens() # needs sage.rings.number_field sage: A*B^-1 in Fd # needs sage.rings.number_field True @@ -61,7 +61,7 @@ def __init__(self, parent, exponents): EXAMPLES:: sage: F = AbelianGroup(3,[7,8,9]) - sage: Fd = F.dual_group(names="ABC") # needs sage.rings.number_field + sage: Fd = F.dual_group(names='ABC') # needs sage.rings.number_field sage: A,B,C = Fd.gens() # needs sage.rings.number_field sage: A*B^-1 in Fd # needs sage.rings.number_field True @@ -148,9 +148,9 @@ def list(self): EXAMPLES:: sage: # needs sage.rings.number_field - sage: F = AbelianGroup(5,[2, 3, 5, 7, 8], names="abcde") + sage: F = AbelianGroup(5,[2, 3, 5, 7, 8], names='abcde') sage: a,b,c,d,e = F.gens() - sage: Ad = F.dual_group(names="ABCDE") + sage: Ad = F.dual_group(names='ABCDE') sage: A,B,C,D,E = Ad.gens() sage: (A*B*C^2*D^20*E^65).exponents() (1, 1, 2, 6, 1) diff --git a/src/sage/groups/abelian_gps/values.py b/src/sage/groups/abelian_gps/values.py index c38edcfb9f9..43f9e29cb75 100644 --- a/src/sage/groups/abelian_gps/values.py +++ b/src/sage/groups/abelian_gps/values.py @@ -84,19 +84,19 @@ def AbelianGroupWithValues(values, n, gens_orders=None, names='f', check=False, INPUT: - - ``values`` -- a list/tuple/iterable of values that you want to + - ``values`` -- list/tuple/iterable of values that you want to associate to the generators - - ``n`` -- integer (optional). If not specified, will be derived - from ``gens_orders`` + - ``n`` -- integer (optional); if not specified, will be derived + from ``gens_orders`` - - ``gens_orders`` -- a list of non-negative integers in the form + - ``gens_orders`` -- list of nonnegative integers in the form `[a_0, a_1, \dots, a_{n-1}]`, typically written in increasing order. This list is padded with zeros if it has length less than n. The orders of the commuting generators, with `0` denoting an infinite cyclic factor. - - ``names`` -- (optional) names of generators + - ``names`` -- (optional) names of generators - ``values_group`` -- a parent or ``None`` (default). The common parent of the values. This might be a group, but can also just @@ -358,12 +358,12 @@ class AbelianGroupWithValues_class(AbelianGroup_class): INPUT: - ``generator_orders`` -- tuple of integers; the orders of the - generators. + generators - ``names`` -- string or list of strings; the names for the generators - ``values`` -- tuple the same length as the number of - generators; the values assigned to the generators. + generators; the values assigned to the generators - ``values_group`` -- the common parent of the values diff --git a/src/sage/groups/additive_abelian/additive_abelian_group.py b/src/sage/groups/additive_abelian/additive_abelian_group.py index bbf91165437..b88fdb4846e 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_group.py +++ b/src/sage/groups/additive_abelian/additive_abelian_group.py @@ -23,7 +23,7 @@ def AdditiveAbelianGroup(invs, remember_generators=True): - ``remember_generators`` -- boolean (default: ``True``); whether or not to fix a set of generators (corresponding to the given invariants, which - need not be in Smith form). + need not be in Smith form) OUTPUT: the abelian group `\bigoplus_i \ZZ / n_i \ZZ`, where `n_i` are the invariants @@ -409,7 +409,7 @@ class AdditiveAbelianGroup_fixed_gens(AdditiveAbelianGroup_class): """ def __init__(self, cover, rels, gens): r""" - Standard initialisation function + Standard initialisation function. EXAMPLES:: diff --git a/src/sage/groups/additive_abelian/additive_abelian_wrapper.py b/src/sage/groups/additive_abelian/additive_abelian_wrapper.py index 966b3137cdb..75488f0772d 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_wrapper.py +++ b/src/sage/groups/additive_abelian/additive_abelian_wrapper.py @@ -6,7 +6,6 @@ object from any given set of elements in some given parent, as long as an ``_add_`` method has been defined. - EXAMPLES: We create a toy example based on the Mordell-Weil group of an elliptic curve over `\QQ`:: @@ -709,8 +708,7 @@ def _expand_basis_pgroup(p, alphas, vals, beta, h, rel): q = rel[i].p_primary_part(p) alphas[i] *= rel[i] // q rel[i] = q - if q < min_r: - min_r = q + min_r = min(q, min_r) if min_r == float('inf'): raise ValueError('rel must have at least one nonzero entry') val_rlast = rel[-1].valuation(p) diff --git a/src/sage/groups/additive_abelian/qmodnz.py b/src/sage/groups/additive_abelian/qmodnz.py index 8ae0dd35728..8bca7cbb460 100644 --- a/src/sage/groups/additive_abelian/qmodnz.py +++ b/src/sage/groups/additive_abelian/qmodnz.py @@ -47,12 +47,11 @@ class QmodnZ(Parent, UniqueRepresentation): #. ``QmodnZ(n)``, where - - `n` -- a rational number (including 0 or negative rational numbers). + - ``n`` -- a rational number (including 0 or negative rational numbers) #. ``QQ/(n*ZZ)``, where - - `n` -- integer (including 0 or negative integers). - + - ``n`` -- integer (including 0 or negative integers) OUTPUT: the abelian group `\Q/n\Z` diff --git a/src/sage/groups/additive_abelian/qmodnz_element.py b/src/sage/groups/additive_abelian/qmodnz_element.py index b3ebe8e2335..2978a665a36 100644 --- a/src/sage/groups/additive_abelian/qmodnz_element.py +++ b/src/sage/groups/additive_abelian/qmodnz_element.py @@ -76,7 +76,7 @@ def __init__(self, parent, x, construct=False): def lift(self): r""" - Return the smallest non-negative rational number reducing to + Return the smallest nonnegative rational number reducing to this element. EXAMPLES:: @@ -109,8 +109,8 @@ def _integer_(self, Z): r""" Lift to `\Z`. - This is the smallest non-negative integer reducing to this element, - or a :class:`ValueError` if none exists. + This is the smallest nonnegative integer reducing to this element, + or a :exc:`ValueError` if none exists. TESTS:: @@ -263,7 +263,7 @@ def division_by(self, other): Division of `x` by `m` does not yield a well defined result, since there are `m` elements `y` of `\Q/n\Z` with the property that `x = my`. We return the one - with the smallest non-negative lift. + with the smallest nonnegative lift. EXAMPLES:: diff --git a/src/sage/groups/affine_gps/affine_group.py b/src/sage/groups/affine_gps/affine_group.py index 07b63d4a2bc..d20f209788f 100644 --- a/src/sage/groups/affine_gps/affine_group.py +++ b/src/sage/groups/affine_gps/affine_group.py @@ -88,15 +88,15 @@ class AffineGroup(UniqueRepresentation, Group): - Degree and base ring: - * ``degree`` -- An integer. The degree of the affine group, that - is, the dimension of the affine space the group is acting on. + * ``degree`` -- integer; the degree of the affine group, that + is, the dimension of the affine space the group is acting on - * ``ring`` -- A ring or an integer. The base ring of the affine + * ``ring`` -- a ring or an integer; the base ring of the affine space. If an integer is given, it must be a prime power and the corresponding finite field is constructed. - * ``var`` -- (default: ``'a'``) Keyword argument to specify the finite - field generator name in the case where ``ring`` is a prime power. + * ``var`` -- (default: ``'a'``) keyword argument to specify the finite + field generator name in the case where ``ring`` is a prime power EXAMPLES:: @@ -230,7 +230,7 @@ def _element_constructor_check(self, A, b): """ Verify that ``A``, ``b`` define an affine group element. - This raises a :class:`TypeError` if the input does not define + This raises a :exc:`TypeError` if the input does not define a valid group element. This is called from the group element constructor and can be @@ -391,7 +391,7 @@ def linear(self, A): - ``A`` -- anything that determines a matrix - OUTPUT: The affine group element `x \mapsto A x` + OUTPUT: the affine group element `x \mapsto A x` EXAMPLES:: @@ -412,7 +412,7 @@ def translation(self, b): - ``b`` -- anything that determines a vector - OUTPUT: The affine group element `x \mapsto x + b` + OUTPUT: the affine group element `x \mapsto x + b` EXAMPLES:: diff --git a/src/sage/groups/affine_gps/euclidean_group.py b/src/sage/groups/affine_gps/euclidean_group.py index 000210ddeab..97677c777d1 100644 --- a/src/sage/groups/affine_gps/euclidean_group.py +++ b/src/sage/groups/affine_gps/euclidean_group.py @@ -76,15 +76,15 @@ class EuclideanGroup(AffineGroup): - Degree and base ring: - * ``degree`` -- An integer. The degree of the affine group, that - is, the dimension of the affine space the group is acting on. + * ``degree`` -- integer; the degree of the affine group, that + is, the dimension of the affine space the group is acting on - * ``ring`` -- A ring or an integer. The base ring of the affine + * ``ring`` -- a ring or an integer; the base ring of the affine space. If an integer is given, it must be a prime power and the corresponding finite field is constructed. - * ``var`` -- (default: ``'a'``) Keyword argument to specify the finite - field generator name in the case where ``ring`` is a prime power. + * ``var`` -- (default: ``'a'``) keyword argument to specify the finite + field generator name in the case where ``ring`` is a prime power EXAMPLES:: @@ -170,7 +170,7 @@ def _element_constructor_check(self, A, b): OUTPUT: - The return value is ignored. You must raise a :class:`TypeError` if + The return value is ignored. You must raise a :exc:`TypeError` if the input does not define a valid group element. TESTS:: diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index e2a6cd290c6..fff5881868f 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -61,11 +61,11 @@ class AffineGroupElement(MultiplicativeGroupElement): - ``parent`` -- the parent affine group - - ``convert`` -- bool (default: ``True``); whether to convert + - ``convert`` -- boolean (default: ``True``); whether to convert ``A`` into the correct matrix space and ``b`` into the correct vector space - - ``check`` -- bool (default: ``True``); whether to do some + - ``check`` -- boolean (default: ``True``); whether to do some checks or just accept the input as valid As a special case, ``A`` can be a matrix obtained from @@ -73,7 +73,7 @@ class AffineGroupElement(MultiplicativeGroupElement): that case, the group element defining that matrix is reconstructed. - OUTPUT: The affine group element `x \mapsto Ax + b` + OUTPUT: the affine group element `x \mapsto Ax + b` EXAMPLES:: @@ -145,7 +145,7 @@ def A(self): """ Return the general linear part of an affine group element. - OUTPUT: The matrix `A` of the affine group element `Ax + b` + OUTPUT: the matrix `A` of the affine group element `Ax + b` EXAMPLES:: @@ -162,7 +162,7 @@ def b(self): """ Return the translation part of an affine group element. - OUTPUT: The vector `b` of the affine group element `Ax + b` + OUTPUT: the vector `b` of the affine group element `Ax + b` EXAMPLES:: diff --git a/src/sage/groups/all.py b/src/sage/groups/all.py index 66f3a106e54..601ba6c7ec0 100644 --- a/src/sage/groups/all.py +++ b/src/sage/groups/all.py @@ -32,6 +32,10 @@ lazy_import('sage.groups.semimonomial_transformations.semimonomial_transformation_group', 'SemimonomialTransformationGroup') -lazy_import('sage.groups.group_exp', ['GroupExp', 'GroupExp_Class', 'GroupExpElement']) +lazy_import('sage.groups.group_exp', 'GroupExp') +lazy_import('sage.groups.group_exp', ['GroupExp_Class', 'GroupExpElement'], + deprecation=38238) -lazy_import('sage.groups.group_semidirect_product', ['GroupSemidirectProduct', 'GroupSemidirectProductElement']) +lazy_import('sage.groups.group_semidirect_product', 'GroupSemidirectProduct') +lazy_import('sage.groups.group_semidirect_product', 'GroupSemidirectProductElement', + deprecation=38238) diff --git a/src/sage/groups/artin.py b/src/sage/groups/artin.py index 306569e546b..2339394224e 100644 --- a/src/sage/groups/artin.py +++ b/src/sage/groups/artin.py @@ -21,13 +21,14 @@ # http://www.gnu.org/licenses/ # ***************************************************************************** -from sage.misc.cachefunc import cached_method -from sage.groups.free_group import FreeGroup -from sage.groups.finitely_presented import FinitelyPresentedGroup, FinitelyPresentedGroupElement from sage.combinat.root_system.coxeter_matrix import CoxeterMatrix from sage.combinat.root_system.coxeter_group import CoxeterGroup +from sage.groups.free_group import FreeGroup +from sage.groups.finitely_presented import FinitelyPresentedGroup, FinitelyPresentedGroupElement +from sage.misc.cachefunc import cached_method from sage.rings.infinity import Infinity from sage.structure.richcmp import richcmp, rich_to_bool +from sage.structure.unique_representation import UniqueRepresentation class ArtinGroupElement(FinitelyPresentedGroupElement): @@ -51,7 +52,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: a string; a valid LaTeX math command sequence + OUTPUT: string; a valid LaTeX math command sequence TESTS:: @@ -329,7 +330,7 @@ def _left_normal_form_coxeter(self): return tuple([-delta] + form) -class ArtinGroup(FinitelyPresentedGroup): +class ArtinGroup(UniqueRepresentation, FinitelyPresentedGroup): r""" An Artin group. @@ -508,7 +509,7 @@ def cardinality(self): """ Return the number of elements of ``self``. - OUTPUT: Infinity + OUTPUT: infinity EXAMPLES:: @@ -530,7 +531,7 @@ def as_permutation_group(self): """ Return an isomorphic permutation group. - This raises a :class:`ValueError` error since Artin groups are + This raises a :exc:`ValueError` error since Artin groups are infinite and have no corresponding permutation group. EXAMPLES:: diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index d963a7b2e6a..8945175cf7a 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -119,7 +119,7 @@ class Braid(FiniteTypeArtinGroupElement): """ def _richcmp_(self, other, op): """ - Compare ``self`` and ``other`` + Compare ``self`` and ``other``. TESTS:: @@ -373,9 +373,7 @@ def alexander_polynomial(self, var='t', normalized=True): - ``normalized`` -- boolean (default: ``True``); whether to return the normalized Alexander polynomial - OUTPUT: - - The Alexander polynomial of the braid closure of the braid. + OUTPUT: the Alexander polynomial of the braid closure of the braid This is computed using the reduced Burau representation. The unnormalized Alexander polynomial is a Laurent polynomial, @@ -467,7 +465,7 @@ def permutation(self, W=None): def plot(self, color='rainbow', orientation='bottom-top', gap=0.05, aspect_ratio=1, axes=False, **kwds): """ - Plot the braid + Plot the braid. The following options are available: @@ -491,14 +489,14 @@ def plot(self, color='rainbow', orientation='bottom-top', gap=0.05, aspect_ratio * ``'left-right'``, the braid is printed from left to right - - ``gap`` -- floating point number (default: 0.05). determines - the size of the gap left when a strand goes under another. + - ``gap`` -- floating point number (default: 0.05); determines + the size of the gap left when a strand goes under another - ``aspect_ratio`` -- floating point number (default: - ``1``). The aspect ratio. + ``1``); the aspect ratio - ``**kwds`` -- other keyword options that are passed to - :meth:`~sage.plot.bezier_path` and :meth:`~sage.plot.line`. + :meth:`~sage.plot.bezier_path` and :meth:`~sage.plot.line` EXAMPLES:: @@ -522,7 +520,7 @@ def plot(self, color='rainbow', orientation='bottom-top', gap=0.05, aspect_ratio sage: B. = BraidGroup(3) sage: b = t^-1*s^2 - sage: b.plot(orientation="left-right", color="red") # needs sage.plot + sage: b.plot(orientation='left-right', color='red') # needs sage.plot Graphics object consisting of 12 graphics primitives """ from sage.plot.bezier_path import bezier_path @@ -618,7 +616,7 @@ def plot3d(self, color='rainbow'): sage: b = B([1, 2, 3, 1, 2, 1]) sage: b.plot3d() # needs sage.plot sage.symbolic Graphics3d Object - sage: b.plot3d(color="red") # needs sage.plot sage.symbolic + sage: b.plot3d(color='red') # needs sage.plot sage.symbolic Graphics3d Object sage: b.plot3d(color=["red", "blue", "red", "blue"]) # needs sage.plot sage.symbolic Graphics3d Object @@ -669,8 +667,8 @@ def LKB_matrix(self, variables='x,y'): INPUT: - - ``variables`` -- string (default: ``'x,y'``). A string - containing the names of the variables, separated by a comma. + - ``variables`` -- string (default: ``'x,y'``); a string + containing the names of the variables, separated by a comma OUTPUT: the matrix corresponding to the Lawrence-Krammer-Bigelow representation of the braid @@ -726,9 +724,7 @@ def TL_matrix(self, drain_size, variab=None, sparse=True): - ``sparse`` -- boolean (default: ``True``); whether or not the result should be given as a sparse matrix - OUTPUT: - - The matrix of the TL representation of the braid. + OUTPUT: the matrix of the TL representation of the braid The parameter ``sparse`` can be set to ``False`` if it is expected that the resulting matrix will not be sparse. We @@ -801,7 +797,7 @@ def links_gould_matrix(self, symbolics=False): INPUT: - - ``symbolics`` -- boolean (default ``False``). If set to ``True`` the + - ``symbolics`` -- boolean (default: ``False``); if set to ``True`` the coefficients will be contained in the symbolic ring. Per default they are elements of a quotient ring of a three variate Laurent polynomial ring. @@ -841,7 +837,7 @@ def links_gould_polynomial(self, varnames=None, use_symbolics=False): INPUT: - - ``varnames`` -- string (default ``t0, t1``) + - ``varnames`` -- string (default: ``'t0, t1'``) OUTPUT: a Laurent polynomial in the given variable names @@ -892,7 +888,7 @@ def links_gould_polynomial(self, varnames=None, use_symbolics=False): # Since the result of the calculation is known to be a Laurent polynomial # in t0 and t1 all exponents of ltemp must be divisable by 2 L = ltemp.parent() - lred = L({(k[0]/2, k[1]/2): v for k, v in ltemp.dict().items()}) + lred = L({(k[0]/2, k[1]/2): v for k, v in ltemp.monomial_coefficients().items()}) t0, t1 = R.gens() return lred(t0, t1) @@ -900,7 +896,7 @@ def tropical_coordinates(self): r""" Return the tropical coordinates of ``self`` in the braid group `B_n`. - OUTPUT: a list of `2n` tropical integers + OUTPUT: list of `2n` tropical integers EXAMPLES:: @@ -1311,7 +1307,7 @@ def _annular_khovanov_complex_cached(self, qagrad, ring=None): INPUT: - - ``qagrad`` -- a tuple of the quantum and annular grading to compute + - ``qagrad`` -- tuple of the quantum and annular grading to compute - ``ring`` -- (default: ``ZZ``) the coefficient ring @@ -1356,14 +1352,14 @@ def _annular_khovanov_complex_cached(self, qagrad, ring=None): def annular_khovanov_complex(self, qagrad=None, ring=None): r""" Return the annular Khovanov complex of the closure of a braid, - as defined in [BG2013]_ + as defined in [BG2013]_. INPUT: - ``qagrad`` -- tuple of quantum and annular grading for which to compute - the chain complex. If not specified all gradings are computed. + the chain complex; if not specified all gradings are computed - - ``ring`` -- (default: ``ZZ``) the coefficient ring. + - ``ring`` -- (default: ``ZZ``) the coefficient ring OUTPUT: @@ -1980,7 +1976,7 @@ def sliding_circuits(self): """ Return the sliding circuits of the braid. - OUTPUT: a list of sliding circuits. Each sliding circuit is itself + OUTPUT: list of sliding circuits. Each sliding circuit is itself a list of braids. EXAMPLES:: @@ -2286,7 +2282,7 @@ def __init__(self, words): ....: ) = fig_8.deformed_burau_matrix().parent().base_ring().gens() sage: q = bp_1.base_ring().gen() sage: Q = RightQuantumWord(ap_1*cp_1 + q**3*bm_2*bp_1*am_0*cm_0) - sage: TestSuite(Q).run(skip="_test_pickling") + sage: TestSuite(Q).run(skip='_test_pickling') """ self._algebra = words.parent() self.q = self._algebra.base_ring().gen() @@ -2505,7 +2501,7 @@ def __init__(self, names): INPUT: - - ``names`` -- a tuple of strings; the names of the generators + - ``names`` -- tuple of strings; the names of the generators TESTS:: @@ -2620,7 +2616,7 @@ def as_permutation_group(self): """ Return an isomorphic permutation group. - OUTPUT: this raises a :class:`ValueError` error since braid groups + OUTPUT: this raises a :exc:`ValueError` error since braid groups are infinite TESTS:: @@ -2734,7 +2730,7 @@ def _links_gould_representation(self, symbolics=False): INPUT: - - ``symbolics`` -- boolean (default ``False``). If set to ``True`` the + - ``symbolics`` -- boolean (default: ``False``); if set to ``True`` the coefficients will be contained in the symbolic ring. Per default they are elements of a quotient ring of a three variate Laurent polynomial ring. @@ -2978,7 +2974,7 @@ def TL_basis_with_drain(self, drain_size): A basis element is specified as a list of integers obtained by considering the pairings as obtained as the 'highest term' of trivalent trees marked by Jones--Wenzl projectors (see e.g. [Wan2010]_). - In practice, this is a list of non-negative integers whose first + In practice, this is a list of nonnegative integers whose first element is ``drain_size``, whose last element is `0`, and satisfying that consecutive integers have difference `1`. Moreover, the length of each basis element is `n + 1`. @@ -2991,7 +2987,7 @@ def TL_basis_with_drain(self, drain_size): - ``drain_size`` -- integer between 0 and the number of strands (both inclusive) - OUTPUT: a list of basis elements, each of which is a list of integers + OUTPUT: list of basis elements, each of which is a list of integers EXAMPLES: @@ -3173,7 +3169,7 @@ def TL_representation(self, drain_size, variab=None): entries of the matrices; if ``None``, then use a default variable in `\ZZ[A,A^{-1}]` - OUTPUT: a list of matrices corresponding to the representations of each + OUTPUT: list of matrices corresponding to the representations of each of the standard generators and their inverses EXAMPLES:: @@ -3320,7 +3316,7 @@ def _element_from_libbraiding(self, nf): INPUT: - - ``nf`` -- a list of lists, as returned by libbraiding + - ``nf`` -- list of lists, as returned by libbraiding EXAMPLES:: @@ -3365,7 +3361,7 @@ def presentation_two_generators(self, isomorphisms=False): INPUT: - - ``isomorphism`` -- boolean (default ``False``); if ``True``, then an isomorphism + - ``isomorphism`` -- boolean (default: ``False``); if ``True``, then an isomorphism from ``self`` and the isomorphic group and its inverse is also returned EXAMPLES:: @@ -3412,7 +3408,7 @@ def epimorphisms(self, H): INPUT: - - `H` -- another group + - ``H`` -- another group EXAMPLES:: @@ -3461,7 +3457,7 @@ def BraidGroup(n=None, names='s'): group is assumed to have one more strand than generators. - ``names`` -- string or list/tuple/iterable of strings (default: - ``'x'``). The generator names or name prefix. + ``'x'``); the generator names or name prefix EXAMPLES:: diff --git a/src/sage/groups/cactus_group.py b/src/sage/groups/cactus_group.py index c8d6ba7241f..c1c1f696992 100644 --- a/src/sage/groups/cactus_group.py +++ b/src/sage/groups/cactus_group.py @@ -78,7 +78,7 @@ def __init__(self, n): sage: J3 = groups.misc.Cactus(3) sage: it = iter(J3) sage: elts = [next(it) for _ in range(100)] - sage: TestSuite(J3).run(elements=elts[::7], skip="_test_enumerated_set_contains") + sage: TestSuite(J3).run(elements=elts[::7], skip='_test_enumerated_set_contains') We run this test separately because the words grow very long, very quickly. This means the code needs to check a lot of normalizations, @@ -135,7 +135,7 @@ def _WG(self): G = Graph([list(range(len(PS))), [[i,j,-1] for j in range(1, len(PS)) for i in range(j) if PS[i] & PS[j] not in [frozenset(), PS[i], PS[j]]] - ], format="vertices_and_edges") + ], format='vertices_and_edges') self._subsets = PS self._subsets_inv = {X: i for i,X in enumerate(PS)} return G diff --git a/src/sage/groups/class_function.py b/src/sage/groups/class_function.py index 5d4dc0c1505..1e69c3d6080 100644 --- a/src/sage/groups/class_function.py +++ b/src/sage/groups/class_function.py @@ -4,7 +4,7 @@ This module implements a wrapper of GAP's ClassFunction function. -.. NOTE: +.. NOTE:: The ordering of the columns of the character table of a group corresponds to the ordering of the list. However, in general there is @@ -250,9 +250,7 @@ def domain(self): r""" Return the domain of the ``self``. - OUTPUT: - - The underlying group of the class function. + OUTPUT: the underlying group of the class function EXAMPLES:: @@ -293,7 +291,7 @@ def __call__(self, g): def __add__(self, other): r""" - Return the sum of the characters of ``self`` and other. + Return the sum of the characters of ``self`` and ``other``. INPUT: @@ -483,14 +481,14 @@ def symmetric_power(self, n): def exterior_power(self, n): r""" - Return the antisymmetrized product of ``self`` with itself ``n`` + Return the antisymmetrized product of ``self`` with itself `n` times. INPUT: - - ``n`` -- positive integer. + - ``n`` -- positive integer - OUTPUT: the ``n``-th antisymmetrized power of ``self`` as a :class:`ClassFunction` + OUTPUT: the `n`-th antisymmetrized power of ``self`` as a :class:`ClassFunction` EXAMPLES:: @@ -509,7 +507,7 @@ def exterior_power(self, n): def scalar_product(self, other): r""" - Return the scalar product of ``self`` with other. + Return the scalar product of ``self`` with ``other``. EXAMPLES:: @@ -540,7 +538,7 @@ def is_irreducible(self): def degree(self): r""" - Return the degree of the character self. + Return the degree of the character ``self``. EXAMPLES:: diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index 257b400f1c7..e407b9d1326 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -22,7 +22,7 @@ Coxeter realized these groups as subgroups of unitary groups with respect to a certain Hermitian form over the complex numbers (in fact over `\QQ` -adjoined with a primitive 12-th root of unity). +adjoined with a primitive `12`-th root of unity). In "Einige endliche Faktorgruppen der Zopfgruppen" (Math. Z., 163 (1978), 291-302) J. Assion considered two series `S(m)` and `U(m)` of finite @@ -91,6 +91,8 @@ from sage.groups.braid import BraidGroup from sage.misc.cachefunc import cached_method from sage.rings.integer import Integer +from sage.structure.unique_representation import UniqueRepresentation + try: from sage.libs.gap.element import GapElement @@ -282,7 +284,7 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: CBG3 = CubicBraidGroup(3) - sage: sorted(CBG3) # indirect doctest + sage: sorted(CBG3) # indirect doctest, random output [(c0*c1^-1)^2, c0*c1^-1*c0, c0^-1*c1*c0^-1, c0^-1*c1^-1*c0, c1*c0^-1*c1, c0^-1*c1^-1*c0^-1, c0^-1*c1^-1, c1^-1*c0*c1^-1, c0*c1^-1*c0^-1, c0^-1*c1, c0^-1*c1*c0, c0*c1^-1, c1*c0^-1, @@ -368,7 +370,7 @@ def burau_matrix(self, root_bur=None, domain=None, characteristic=None, - ``root_bur`` -- six (resp. twelfth) root of unity in some field (default: root of unity over `\QQ`) - - ``domain`` -- (default: cyclotomic field of order 3 and degree 2, resp. + - ``domain`` -- (default: cyclotomic field of order 3 and degree 2, resp. the domain of `root_bur` if given) base ring for the Burau matrix - ``characteristic`` -- integer giving the characteristic of the domain (default: 0 or the characteristic of ``domain`` if given) @@ -565,7 +567,7 @@ def conv2domain(laur_pol): # Class CubicBraidGroup # ############################################################################## -class CubicBraidGroup(FinitelyPresentedGroup): +class CubicBraidGroup(UniqueRepresentation, FinitelyPresentedGroup): r""" Factor groups of the Artin braid group mapping their generators to elements of order 3. @@ -669,7 +671,7 @@ class type(Enum): r""" Enum class to select the type of the group: - - ``Coxeter`` -- ``'C'`` the full cubic braid group. + - ``Coxeter`` -- ``'C'`` the full cubic braid group - ``AssionS`` -- ``'S'`` finite factor group of type S considered by Assion - ``AssionU`` -- ``'U'`` finite factor group of type U considered by Assion @@ -750,7 +752,6 @@ def __init__(self, names, cbg_type=None): n = Integer(len(names)) if n < 1: raise ValueError("the number of strands must be an integer larger than one") - if cbg_type is None: cbg_type = CubicBraidGroup.type.Coxeter if not isinstance(cbg_type, CubicBraidGroup.type): @@ -995,7 +996,7 @@ def _test_matrix_group(self, **options): matrix_grpF4 = self.as_matrix_group(root_bur=r64) self._internal_test_attached_group(matrix_grpF4, tester) - if self.strands() < 5 or self._cbg_type == CubicBraidGroup.type.Coxeter: + if self.strands() < 5 or self._cbg_type == CubicBraidGroup.type.Coxeter: matrix_grpF5 = self.as_matrix_group(characteristic=5) self._internal_test_attached_group(matrix_grpF5, tester) @@ -1040,7 +1041,7 @@ def _create_classical_realization(self, just_embedded=False): - self._classical_group This is the classical group returned by as_classical_group method. - self._classical_base_group this only differs in special cases for Assion groups from the former. - self._classical_invariant_form invariant form of the classical base group. - - self._centralizing_matrix for Assion groups: element in classical base group commuting with self. + - self._centralizing_matrix for Assion groups: element in classical base group commuting with ``self``. - self._centralizing_element image under natural map of the former one in the projective classical group. - self._classical_embedding as subgroup of classical base group (if different from classical group). @@ -1150,7 +1151,7 @@ def create_sympl_realization(self, m): INPUT: - - ``m`` -- integer; the dimension of the classical groups + - ``m`` -- integer; the dimension of the classical groups vector-space of operation The function calculates the centralizing matrix and the @@ -1180,7 +1181,7 @@ def create_sympl_realization(self, m): # to the invariant bilinear form. # ----------------------------------------------------------- xbas = [bas[mhalf - i - 1] for i in range(mhalf)] - ybas = [bas[mhalf + i] for i in range(mhalf)] + ybas = [bas[mhalf + i] for i in range(mhalf)] # ----------------------------------------------------------- # computing the List of transvection vectors according to @@ -1200,7 +1201,7 @@ def create_sympl_realization(self, m): def transvec2mat(v, bas=bas, bform=bform, fact=1): t = [x + fact*(x * bform * v) * v for x in bas] - return matrix(bform.base_ring(), t) + return matrix(bform.base_ring(), t) # ------------------------------------------------------------------------------ # setting the centralizing matrix for the case of projective group realization @@ -1223,7 +1224,7 @@ def create_unitary_realization(self, m): INPUT: - - ``m`` -- integer; the dimension of the classical groups + - ``m`` -- integer; the dimension of the classical groups vector-space of operation The function calculates the centralizing_matrix and the @@ -1469,7 +1470,7 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' - ``root_bur`` -- (default: root of unity over `\QQ`) six (resp. twelfth) root of unity in some field - - ``domain`` -- (default: cyclotomic field of order 3 and degree 2, resp. + - ``domain`` -- (default: cyclotomic field of order 3 and degree 2, resp. the domain of ``root_bur`` if given) base ring for the Burau matrix - ``characteristic`` -- integer (optional); the characteristic of the domain; if none of the keywords ``root_bur``, ``domain`` and diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 4bb52ee4efb..9b5f7e422d6 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -130,7 +130,6 @@ from sage.arith.misc import GCD as gcd from sage.categories.morphism import SetMorphism -from sage.functions.generalized import sign from sage.groups.free_group import FreeGroup from sage.groups.free_group import FreeGroupElement from sage.groups.group import Group @@ -143,7 +142,8 @@ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing from sage.rings.rational_field import QQ from sage.sets.set import Set -from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.richcmp import richcmp, richcmp_method +from sage.structure.unique_representation import CachedRepresentation class GroupMorphismWithGensImages(SetMorphism): @@ -319,7 +319,7 @@ def __call__(self, *values, **kwds): INPUT: - - ``*values`` -- a list/tuple/iterable of the same length as + - ``*values`` -- list/tuple/iterable of the same length as the number of generators - ``check=True`` -- boolean keyword (default: ``True``); whether to @@ -362,50 +362,6 @@ def __call__(self, *values, **kwds): return super().__call__(values) -def wrap_FpGroup(libgap_fpgroup): - """ - Wrap a GAP finitely presented group. - - This function changes the comparison method of - ``libgap_free_group`` to comparison by Python ``id``. If you want - to put the LibGAP free group into a container ``(set, dict)`` then you - should understand the implications of - :meth:`~sage.libs.gap.element.GapElement._set_compare_by_id`. To - be safe, it is recommended that you just work with the resulting - Sage :class:`FinitelyPresentedGroup`. - - INPUT: - - - ``libgap_fpgroup`` -- a LibGAP finitely presented group - - OUTPUT: a Sage :class:`FinitelyPresentedGroup` - - EXAMPLES: - - First construct a LibGAP finitely presented group:: - - sage: F = libgap.FreeGroup(['a', 'b']) - sage: a_cubed = F.GeneratorsOfGroup()[0] ^ 3 - sage: P = F / libgap([ a_cubed ]); P - - sage: type(P) - - - Now wrap it:: - - sage: from sage.groups.finitely_presented import wrap_FpGroup - sage: wrap_FpGroup(P) - Finitely presented group < a, b | a^3 > - """ - assert libgap_fpgroup.IsFpGroup() - libgap_fpgroup._set_compare_by_id() - from sage.groups.free_group import wrap_FreeGroup - free_group = wrap_FreeGroup(libgap_fpgroup.FreeGroupOfFpGroup()) - relations = tuple(free_group(rel.UnderlyingElement()) - for rel in libgap_fpgroup.RelatorsOfFpGroup()) - return FinitelyPresentedGroup(free_group, relations) - - class RewritingSystem: """ A class that wraps GAP's rewriting systems. @@ -509,7 +465,7 @@ def __repr__(self): def free_group(self): """ - The free group after which the rewriting system is defined + The free group after which the rewriting system is defined. EXAMPLES:: @@ -730,7 +686,8 @@ def make_confluent(self): raise ValueError('could not make the system confluent') -class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation, Group, ParentLibGAP): +@richcmp_method +class FinitelyPresentedGroup(GroupMixinLibGAP, CachedRepresentation, Group, ParentLibGAP): """ A class that wraps GAP's Finitely Presented Groups. @@ -739,7 +696,9 @@ class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation, Group, Pare You should use :meth:`~sage.groups.free_group.FreeGroup_class.quotient` to construct finitely presented groups as quotients of free - groups. + groups. Any class inheriting this one should define + ``__reduce__ = CachedRepresentation.__reduce__`` + after importing ``CachedRepresentation``. EXAMPLES:: @@ -770,7 +729,7 @@ class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation, Group, Pare """ Element = FinitelyPresentedGroupElement - def __init__(self, free_group, relations, category=None): + def __init__(self, free_group, relations, category=None, libgap_fpgroup=None): """ The Python constructor. @@ -786,6 +745,25 @@ def __init__(self, free_group, relations, category=None): sage: J is H True + sage: A5 = libgap(AlternatingGroup(5)) + sage: A5gapfp = A5.IsomorphismFpGroup().Range() + sage: A5gapfp + + sage: A5sage = A5gapfp.sage(); A5sage; + Finitely presented group < A_5.1, A_5.2 | A_5.1^5*A_5.2^-5, A_5.1^5*(A_5.2^-1*A_5.1^-1)^2, (A_5.1^-2*A_5.2^2)^2 > + sage: A5sage.inject_variables() + Traceback (most recent call last): + ... + ValueError: variable names have not yet been set using self._assign_names(...) + + Check that pickling works:: + + sage: G = FreeGroup(2) / [2 * (1, 2, -1, -2)] + sage: loads(dumps(G)) + Finitely presented group < x0, x1 | (x0*x1*x0^-1*x1^-1)^2 > + sage: G.__reduce__()[1][1] + (Free Group on generators {x0, x1}, ((x0*x1*x0^-1*x1^-1)^2,)) + sage: TestSuite(H).run() sage: TestSuite(J).run() """ @@ -794,11 +772,47 @@ def __init__(self, free_group, relations, category=None): assert isinstance(relations, tuple) self._free_group = free_group self._relations = relations - self._assign_names(free_group.variable_names()) - parent_gap = free_group.gap() / libgap([rel.gap() for rel in relations]) - ParentLibGAP.__init__(self, parent_gap) + try: + self._assign_names(free_group.variable_names()) + except ValueError: + pass + if libgap_fpgroup is None: + libgap_fpgroup = free_group.gap() / libgap([rel.gap() for rel in relations]) + ParentLibGAP.__init__(self, libgap_fpgroup) Group.__init__(self, category=category) + def __hash__(self): + """ + Make hashable. + + EXAMPLES:: + + sage: G = FreeGroup(2) / [(1, 2, 2, 1)] + sage: G.__hash__() == hash((G.free_group(), G.relations())) + True + """ + return hash((self._free_group, self._relations)) + + def __richcmp__(self, other, op): + """ + Rich comparison of ``self`` and ``other``. + + EXAMPLES:: + + sage: G1 = FreeGroup(2) / [(1, 2, 2, 1, 2, 1)] + sage: G2 = libgap(G1).sage() + sage: G1 == G2 + True + sage: G1 is G2 + False + """ + if not isinstance(other, self.__class__): + from sage.structure.richcmp import op_NE + return (op == op_NE) + self_data = (self._free_group, self._relations) + other_data = (other._free_group, other._relations) + return richcmp(self_data, other_data, op) + def _repr_(self) -> str: """ Return a string representation. @@ -812,7 +826,7 @@ def _repr_(self) -> str: sage: H._repr_() 'Finitely presented group < a, b | a, b^3 >' """ - gens = ', '.join(self.variable_names()) + gens = ', '.join(self._free_group._gen_names) rels = ', '.join(str(r) for r in self.relations()) return 'Finitely presented group ' + '< ' + gens + ' | ' + rels + ' >' @@ -945,7 +959,7 @@ def as_permutation_group(self, limit=4096000): A Sage :func:`~sage.groups.perm_gps.permgroup.PermutationGroup`. If the number of cosets exceeds the given ``limit``, a - :class:`ValueError` is returned. + :exc:`ValueError` is returned. EXAMPLES:: @@ -1003,10 +1017,10 @@ def direct_product(self, H, reduced=False, new_names=True): - ``H`` -- a finitely presented group - - ``reduced`` -- (default: ``False``) boolean; if ``True``, then + - ``reduced`` -- boolean (default: ``False``); if ``True``, then attempt to reduce the presentation of the product group - - ``new_names`` -- (default: ``True``) boolean; If ``True``, then + - ``new_names`` -- boolean (default: ``True``); if ``True``, then lexicographical variable names are assigned to the generators of the group to be returned. If ``False``, the group to be returned keeps the generator names of the two groups forming the direct @@ -1115,23 +1129,23 @@ def semidirect_product(self, H, hom, check=True, reduced=False): INPUT: - - ``H`` -- Finitely presented group which is implicitly acted on + - ``H`` -- finitely presented group which is implicitly acted on by ``self`` and can be naturally embedded as a normal subgroup - of the semidirect product. + of the semidirect product - - ``hom`` -- Homomorphism from ``self`` to the automorphism group + - ``hom`` -- homomorphism from ``self`` to the automorphism group of ``H``. Given as a pair, with generators of ``self`` in the first slot and the images of the corresponding generators in the second. These images must be automorphisms of ``H``, given again as a pair of generators and images. - - ``check`` -- Boolean (default ``True``). If ``False`` the defining + - ``check`` -- boolean (default: ``True``); if ``False`` the defining homomorphism and automorphism images are not tested for validity. This test can be costly with large groups, so it can be bypassed if the user is confident that his morphisms are valid. - - ``reduced`` -- Boolean (default ``False``). If ``True`` then the - method attempts to reduce the presentation of the output group. + - ``reduced`` -- boolean (default: ``False``); if ``True`` then the + method attempts to reduce the presentation of the output group OUTPUT: @@ -1344,8 +1358,8 @@ def abelianization_map(self): sage: H = G.quotient([g1^2, g2*g1*g2^(-1)*g1^(-1), g1*g3^(-2), g0^4]) sage: H.abelianization_map() Group morphism: - From: Finitely presented group < g0, g1, g2, g3 | g1^2, g2*g1*g2^-1*g1^-1, g1*g3^-2, g0^4 > - To: Finitely presented group < f2, f3, f4 | f2^-1*f3^-1*f2*f3, f2^-1*f4^-1*f2*f4, f3^-1*f4^-1*f3*f4, f2^4, f3^4 > + From: Finitely presented group < g0, g1, g2, g3 | g1^2, g2*g1*g2^-1*g1^-1, g1*g3^-2, g0^4 > + To: Finitely presented group < f1, f2, f3 | f1^4, f2^-1*f1^-1*f2*f1, f2^4, f3^-1*f1^-1*f3*f1, f3^-1*f2^-1*f3*f2 > sage: g = FreeGroup(0) / [] sage: g.abelianization_map() Group endomorphism of Finitely presented group < | > @@ -1357,7 +1371,7 @@ def abelianization_map(self): hom_ab_fp = ab_libgap.IsomorphismFpGroup() ab_libgap_fp = hom_ab_fp.Range() hom_simply = ab_libgap_fp.IsomorphismSimplifiedFpGroup() - ab = wrap_FpGroup(hom_simply.Range()) + ab = hom_simply.Range().sage() images = [] for f in self.gens(): f0 = hom_ab_libgap.Image(f) @@ -1365,7 +1379,7 @@ def abelianization_map(self): f2 = hom_simply.Image(f1) L = f2.UnderlyingElement().LetterRepAssocWord() images.append(ab([int(j) for j in L])) - return self.hom(codomain=ab, im_gens=images) + return self.hom(codomain=ab, im_gens=images, check=False) @cached_method def abelianization_to_algebra(self, ring=QQ): @@ -1375,17 +1389,17 @@ def abelianization_to_algebra(self, ring=QQ): INPUT: - - ``ring`` -- (default: ``QQ``); the base ring for + - ``ring`` -- (default: ``QQ``) the base ring for the group algebra of ``self`` OUTPUT: - ``ab`` -- the abelianization of ``self`` as a finitely presented group - with a minimal number `n` of generators. - - ``R`` -- a Laurent polynomial ring with `n` variables with base ring ``ring``. - - ``ideal`` -- a list of generators of an ideal ``I`` in ``R`` such that ``R/I`` + with a minimal number `n` of generators + - ``R`` -- a Laurent polynomial ring with `n` variables with base ring ``ring`` + - ``ideal`` -- list of generators of an ideal ``I`` in ``R`` such that ``R/I`` is the group algebra of the abelianization over ``ring`` - - ``image`` -- a list with the images of the generators of ``self`` in ``R/I`` + - ``image`` -- list with the images of the generators of ``self`` in ``R/I`` EXAMPLES:: @@ -1394,10 +1408,10 @@ def abelianization_to_algebra(self, ring=QQ): Defining g0, g1, g2, g3 sage: H = G.quotient([g1^2, g2*g1*g2^(-1)*g1^(-1), g1*g3^(-2), g0^4]) sage: H.abelianization_to_algebra() - (Finitely presented group < f2, f3, f4 | f2^-1*f3^-1*f2*f3, f2^-1*f4^-1*f2*f4, - f3^-1*f4^-1*f3*f4, f2^4, f3^4 >, - Multivariate Laurent Polynomial Ring in f2, f3, f4 over Rational Field, - [f2^4 - 1, f3^4 - 1], [f2^-1*f3^-2, f3^-2, f4, f3]) + (Finitely presented group < f1, f2, f3 | f1^4, f2^-1*f1^-1*f2*f1, f2^4, f3^-1*f1^-1*f3*f1, f3^-1*f2^-1*f3*f2 >, + Multivariate Laurent Polynomial Ring in f1, f2, f3 over Rational Field, + [f1^4 - 1, f2^4 - 1], + [f1^3*f2^2, f2^2, f3, f2]) sage: g=FreeGroup(0) / [] sage: g.abelianization_to_algebra() (Finitely presented group < | >, Rational Field, [], []) @@ -1438,12 +1452,9 @@ def simplification_isomorphism(self): sage: H = G / [a*b*c, a*b^2, c*b/c^2] sage: I = H.simplification_isomorphism() sage: I - Generic morphism: + Group morphism: From: Finitely presented group < a, b, c | a*b*c, a*b^2, c*b*c^-2 > To: Finitely presented group < b | > - Defn: a |--> b^-2 - b |--> b - c |--> b sage: I(a) b^-2 sage: I(b) @@ -1455,21 +1466,26 @@ def simplification_isomorphism(self): sage: F = FreeGroup(1) sage: G = F.quotient([F.0]) - sage: G.simplification_isomorphism() - Generic morphism: + sage: h = G.simplification_isomorphism(); h + Group morphism: From: Finitely presented group < x | x > To: Finitely presented group < | > - Defn: x |--> 1 + sage: h(G.gen(0)) + 1 ALGORITHM: Uses GAP. """ II = self.gap().IsomorphismSimplifiedFpGroup() - codomain = wrap_FpGroup(II.Range()) - phi = lambda x: codomain(II.ImageElm(x.gap())) - HS = self.Hom(codomain) - return GroupMorphismWithGensImages(HS, phi) + cod = II.Range().sage() + phi = [cod(II.ImageElm(x)) for x in self.gap().GeneratorsOfGroup()] + return self.hom(codomain=cod, im_gens=phi, check=False) + # II = self.gap().IsomorphismSimplifiedFpGroup() + # codomain = II.Range().sage() + # phi = lambda x: codomain(II.ImageElm(x.gap())) + # HS = self.Hom(codomain) + # return GroupMorphismWithGensImages(HS, phi) def simplified(self): """ @@ -1543,48 +1559,44 @@ def epimorphisms(self, H): sage: F = FreeGroup(3) sage: G = F / [F([1, 2, 3, 1, 2, 3]), F([1, 1, 1])] sage: H = AlternatingGroup(3) - sage: G.epimorphisms(H) - [Generic morphism: - From: Finitely presented group < x0, x1, x2 | x0*x1*x2*x0*x1*x2, x0^3 > - To: Alternating group of order 3!/2 as a permutation group - Defn: x0 |--> () - x1 |--> (1,3,2) - x2 |--> (1,2,3), - Generic morphism: - From: Finitely presented group < x0, x1, x2 | x0*x1*x2*x0*x1*x2, x0^3 > - To: Alternating group of order 3!/2 as a permutation group - Defn: x0 |--> (1,3,2) - x1 |--> () - x2 |--> (1,2,3), - Generic morphism: - From: Finitely presented group < x0, x1, x2 | x0*x1*x2*x0*x1*x2, x0^3 > - To: Alternating group of order 3!/2 as a permutation group - Defn: x0 |--> (1,3,2) - x1 |--> (1,2,3) - x2 |--> (), - Generic morphism: - From: Finitely presented group < x0, x1, x2 | x0*x1*x2*x0*x1*x2, x0^3 > - To: Alternating group of order 3!/2 as a permutation group - Defn: x0 |--> (1,2,3) - x1 |--> (1,2,3) - x2 |--> (1,2,3)] + sage: for quo in G.epimorphisms(H): + ....: for a in G.gens(): + ....: print(a, "|-->", quo(a)) + ....: print("-----") + x0 |--> () + x1 |--> (1,3,2) + x2 |--> (1,2,3) + ----- + x0 |--> (1,3,2) + x1 |--> () + x2 |--> (1,2,3) + ----- + x0 |--> (1,3,2) + x1 |--> (1,2,3) + x2 |--> () + ----- + x0 |--> (1,2,3) + x1 |--> (1,2,3) + x2 |--> (1,2,3) + ----- ALGORITHM: Uses libgap's GQuotients function. """ - from sage.misc.misc_c import prod - HomSpace = self.Hom(H) + # from sage.misc.misc_c import prod + # HomSpace = self.Hom(H) Gg = libgap(self) Hg = libgap(H) gquotients = Gg.GQuotients(Hg) res = [] # the following closure is needed to attach a specific value of quo to # each function in the different morphisms - fmap = lambda tup: (lambda a: H(prod(tup[abs(i)-1]**sign(i) for i in a.Tietze()))) + # fmap = lambda tup: (lambda a: H(prod(tup[abs(i)-1]**sign(i) for i in a.Tietze()))) for quo in gquotients: - tup = tuple(H(quo.ImageElm(i.gap()).sage()) for i in self.gens()) - fhom = GroupMorphismWithGensImages(HomSpace, fmap(tup)) + # tup = tuple(H(quo.ImageElm(i.gap()).sage()) for i in self.gens()) + # fhom = GroupMorphismWithGensImages(HomSpace, fmap(tup)) + fhom = self.hom(codomain=H, im_gens=[H(quo.ImageElm(a.gap())) for a in self.gens()]) res.append(fhom) return res @@ -1673,7 +1685,7 @@ def abelian_alexander_matrix(self, ring=QQ, simplified=True): [] sage: G = FreeGroup(3)/[(2, 1, 1), (1, 2, 2, 3, 3)] sage: A, ideal = G.abelian_alexander_matrix(simplified=True); A - [-f3^2 - f3^4 - f3^6 f3^3 + f3^6] + [-f1^2 - f1^4 - f1^6 f1^3 + f1^6] sage: g = FreeGroup(1) / [] sage: g.abelian_alexander_matrix() ([], []) @@ -1736,7 +1748,7 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): INPUT: - ``ring`` -- (default: ``QQ``) the base ring of the group algebra - - ``groebner`` -- boolean (default: ``False``); If set to + - ``groebner`` -- boolean (default: ``False``); if set to ``True`` the minimal associated primes of the ideals and their groebner bases are computed; ignored if the base ring is not a field @@ -1773,11 +1785,11 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): 3: Ideal (1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring} sage: G = FreeGroup(2)/[(1,2,1,-2,-1,-2)] sage: G.characteristic_varieties() - {0: Ideal (0) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 1: Ideal (-1 + 2*f2 - 2*f2^2 + f2^3) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 2: Ideal (1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} + {0: Ideal (0) of Univariate Laurent Polynomial Ring in f1 over Rational Field, + 1: Ideal (-1 + 2*f1 - 2*f1^2 + f1^3) of Univariate Laurent Polynomial Ring in f1 over Rational Field, + 2: Ideal (1) of Univariate Laurent Polynomial Ring in f1 over Rational Field} sage: G.characteristic_varieties(groebner=True) - {0: [0], 1: [-1 + f2, 1 - f2 + f2^2], 2: []} + {0: [0], 1: [-1 + f1, 1 - f1 + f1^2], 2: []} sage: G = FreeGroup(2)/[3 * (1, ), 2 * (2, )] sage: G.characteristic_varieties(groebner=True) {0: [-1 + F1, 1 + F1, 1 - F1 + F1^2, 1 + F1 + F1^2], 1: [1 - F1 + F1^2], 2: []} diff --git a/src/sage/groups/fqf_orthogonal.py b/src/sage/groups/fqf_orthogonal.py index 47dac17281b..5da64f03212 100644 --- a/src/sage/groups/fqf_orthogonal.py +++ b/src/sage/groups/fqf_orthogonal.py @@ -64,7 +64,7 @@ class FqfIsometry(AbelianGroupAutomorphism): - ``parent`` -- the parent :class:`~FqfOrthogonalGroup` - ``x`` -- a libgap element - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) EXAMPLES:: @@ -275,7 +275,7 @@ def _preserves_form(self, f): INPUT: - Something that acts on the domain. + - ``f`` -- something that acts on the domain EXAMPLES:: @@ -387,10 +387,10 @@ class ActionOnFqf(Action): INPUT: - - ``orthogonal_grp`` -- an instance of :class:`GroupOfIsometries` + - ``orthogonal_grp`` -- an instance of :class:`GroupOfIsometries` - ``fqf`` -- a torsion quadratic module - - ``on_subquotient`` -- bool (default: ``False``) - - ``is_left`` -- bool (default: ``False``) + - ``on_subquotient`` -- boolean (default: ``False``) + - ``is_left`` -- boolean (default: ``False``) EXAMPLES:: @@ -407,7 +407,7 @@ class ActionOnFqf(Action): """ def __init__(self, orthogonal_grp, fqf, on_subquotient=False, is_left=False): r""" - Initialize the action + Initialize the action. TESTS:: @@ -495,12 +495,10 @@ def _isom_fqf(A, B=None): - ``A`` -- a torsion quadratic module - ``B`` -- (default: ``None``) a torsion quadratic module - OUTPUT: - - A list of generators of the orthogonal group of A. + OUTPUT: list of generators of the orthogonal group of A If ``B`` is given, this returns instead a single isometry of `A` and `B` - or raises a :class:`ValueError` if `A` and `B` are not isometric. + or raises a :exc:`ValueError` if `A` and `B` are not isometric. EXAMPLES:: @@ -525,9 +523,9 @@ def orbits(G, L): INPUT: - ``G`` -- an fqf_orthognal group - - ``L`` -- a list of tuples of elements of the domain of ``G`` + - ``L`` -- list of tuples of elements of the domain of ``G`` - A list of orbit representatives of `L` + OUTPUT: list of orbit representatives of `L` """ D = G.invariant_form() A = G.domain() diff --git a/src/sage/groups/free_group.py b/src/sage/groups/free_group.py index 09eb12d6a1c..bc952896e67 100644 --- a/src/sage/groups/free_group.py +++ b/src/sage/groups/free_group.py @@ -63,7 +63,7 @@ from sage.categories.groups import Groups from sage.groups.group import Group from sage.groups.libgap_wrapper import ParentLibGAP, ElementLibGAP -from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.unique_representation import CachedRepresentation from sage.libs.gap.libgap import libgap from sage.libs.gap.element import GapElement from sage.rings.integer import Integer @@ -72,6 +72,7 @@ from sage.misc.misc_c import prod from sage.structure.sequence import Sequence from sage.structure.element import coercion_model, parent +from sage.structure.richcmp import richcmp, richcmp_method def is_FreeGroup(x): @@ -115,7 +116,7 @@ def _lexi_gen(zeroes=False): Python generator object which outputs a character from the alphabet on each ``next()`` call in lexicographical order. The integer `i` is appended - to the output string on the `i^{th}` iteration through the alphabet. + to the output string on the `i`-th iteration through the alphabet. EXAMPLES:: @@ -142,7 +143,6 @@ def _lexi_gen(zeroes=False): sage: ls = [next(test) for i in range(500)] sage: ls[234], ls[260] ('a9', 'a10') - """ count = Integer(0) while True: @@ -243,7 +243,7 @@ def _latex_(self): r""" Return a LaTeX representation. - OUTPUT: a string; a valid LaTeX math command sequence + OUTPUT: string; a valid LaTeX math command sequence EXAMPLES:: @@ -362,14 +362,14 @@ def fox_derivative(self, gen, im_gens=None, ring=None): derivative will be computed. If this is `x_j`, then the method will return `\partial_j`. - - ``im_gens`` (optional) -- the images of the generators + - ``im_gens`` -- (optional) the images of the generators (given as a list or iterable). This is the list `(a_1, a_2, \ldots, a_n)`. If not provided, it defaults to `(x_1, x_2, \ldots, x_n)` in the group ring `\ZZ [F]`. - - ``ring`` (optional) -- the ring in which the elements + - ``ring`` -- (optional) the ring in which the elements of the list `(a_1, a_2, \ldots, a_n)` lie. If not provided, this ring is inferred from these elements. @@ -488,7 +488,7 @@ def syllables(self): OUTPUT: The tuple of syllables. Each syllable is given as a pair - `(x_i, e_i)` consisting of a generator and a non-zero integer. + `(x_i, e_i)` consisting of a generator and a nonzero integer. EXAMPLES:: @@ -606,7 +606,7 @@ def FreeGroup(n=None, names='x', index_set=None, abelian=False, **kwds): - ``index_set`` -- (optional) an index set for the generators; if specified then the optional keyword ``abelian`` can be used - - ``abelian`` -- (default: ``False``) whether to construct a free + - ``abelian`` -- boolean (default: ``False``); whether to construct a free abelian group or a free group .. NOTE:: @@ -673,58 +673,13 @@ def FreeGroup(n=None, names='x', index_set=None, abelian=False, **kwds): from sage.groups.indexed_free_group import IndexedFreeGroup return IndexedFreeGroup(index_set, names=names, **kwds) - return FreeGroup_class(names) + return FreeGroup_class(names, **kwds) -def wrap_FreeGroup(libgap_free_group): +@richcmp_method +class FreeGroup_class(CachedRepresentation, Group, ParentLibGAP): """ - Wrap a LibGAP free group. - - This function changes the comparison method of - ``libgap_free_group`` to comparison by Python ``id``. If you want - to put the LibGAP free group into a container (set, dict) then you - should understand the implications of - :meth:`~sage.libs.gap.element.GapElement._set_compare_by_id`. To - be safe, it is recommended that you just work with the resulting - Sage :class:`FreeGroup_class`. - - INPUT: - - - ``libgap_free_group`` -- a LibGAP free group - - OUTPUT: a Sage :class:`FreeGroup_class` - - EXAMPLES: - - First construct a LibGAP free group:: - - sage: F = libgap.FreeGroup(['a', 'b']) - sage: type(F) - - - Now wrap it:: - - sage: from sage.groups.free_group import wrap_FreeGroup - sage: wrap_FreeGroup(F) - Free Group on generators {a, b} - - TESTS: - - Check that we can do it twice (see :issue:`12339`) :: - - sage: G = libgap.FreeGroup(['a', 'b']) - sage: wrap_FreeGroup(G) - Free Group on generators {a, b} - """ - assert libgap_free_group.IsFreeGroup() - libgap_free_group._set_compare_by_id() - names = tuple( str(g) for g in libgap_free_group.GeneratorsOfGroup() ) - return FreeGroup_class(names, libgap_free_group) - - -class FreeGroup_class(UniqueRepresentation, Group, ParentLibGAP): - """ - A class that wraps GAP's FreeGroup + A class that wraps GAP's FreeGroup. See :func:`FreeGroup` for details. @@ -737,13 +692,13 @@ class FreeGroup_class(UniqueRepresentation, Group, ParentLibGAP): """ Element = FreeGroupElement - def __init__(self, generator_names, libgap_free_group=None): + def __init__(self, generator_names, gap_group=None): """ Python constructor. INPUT: - - ``generator_names`` -- a tuple of strings; the names of the + - ``generator_names`` -- tuple of strings; the names of the generators - ``libgap_free_group`` -- a LibGAP free group (default: ``None``); @@ -758,15 +713,55 @@ def __init__(self, generator_names, libgap_free_group=None): sage: G.variable_names() ('a', 'b') """ - self._assign_names(generator_names) - if libgap_free_group is None: - libgap_free_group = libgap.FreeGroup(generator_names) - ParentLibGAP.__init__(self, libgap_free_group) + if gap_group is None: + gap_group = libgap.FreeGroup(generator_names) + ParentLibGAP.__init__(self, gap_group) if not generator_names: cat = Groups().Finite() else: cat = Groups().Infinite() Group.__init__(self, category=cat) + self._gen_names = generator_names + try: + self._assign_names(generator_names) + except ValueError: + pass + + def __hash__(self): + """ + Make hashable. + + EXAMPLES:: + + sage: F = FreeGroup(3) + sage: F.__hash__() == hash(F._gen_names) + True + """ + return hash(self._gen_names) + + def __richcmp__(self, other, op): + """ + Rich comparison of ``self`` and ``other``. + + EXAMPLES:: + + sage: G1 = FreeGroup('a, b') + sage: gg = libgap.FreeGroup('x', 'y') + sage: G2 = FreeGroup('a, b', gap_group=gg) + sage: G1 == G2 + True + sage: G1 is G2 + False + sage: G3 = FreeGroup('x, y') + sage: G1 == G3 + False + sage: G2 == G3 + False + """ + if not isinstance(other, self.__class__): + from sage.structure.richcmp import op_NE + return (op == op_NE) + return richcmp(self._gen_names, other._gen_names, op) def _repr_(self): """ @@ -778,7 +773,7 @@ def _repr_(self): sage: G._repr_() 'Free Group on generators {a, b}' """ - return 'Free Group on generators {' + ', '.join(self.variable_names()) + '}' + return 'Free Group on generators {' + ', '.join(self._gen_names) + '}' def rank(self): """ @@ -812,7 +807,7 @@ def _gap_init_(self): sage: G._gap_init_() 'FreeGroup(["x0", "x1", "x2"])' """ - gap_names = [ '"' + s + '"' for s in self.variable_names() ] + gap_names = ['"' + s + '"' for s in self._gen_names] gen_str = ', '.join(gap_names) return 'FreeGroup(['+gen_str+'])' @@ -868,9 +863,9 @@ def _element_constructor_(self, *args, **kwds): except AttributeError: return self.element_class(self, x, **kwds) if isinstance(P, FreeGroup_class): - names = {P._names[abs(i)-1] for i in x.Tietze()} - if names.issubset(self._names): - return self([i.sign()*(self._names.index(P._names[abs(i)-1])+1) + names = {P._gen_names[abs(i)-1] for i in x.Tietze()} + if names.issubset(self._gen_names): + return self([i.sign()*(self._gen_names.index(P._gen_names[abs(i)-1])+1) for i in x.Tietze()]) else: raise ValueError('generators of %s not in the group' % x) @@ -907,7 +902,7 @@ def quotient(self, relations, **kwds): INPUT: - - ``relations`` -- a list/tuple/iterable with the elements of + - ``relations`` -- list/tuple/iterable with the elements of the free group - further named arguments, that are passed to the constructor of a finitely presented group diff --git a/src/sage/groups/galois_group.py b/src/sage/groups/galois_group.py index 36495c846ad..5a4e706272d 100644 --- a/src/sage/groups/galois_group.py +++ b/src/sage/groups/galois_group.py @@ -37,7 +37,7 @@ def _alg_key(self, algorithm=None, recompute=False): sage: R. = ZZ[] sage: K. = NumberField(x^3 + 2*x + 2) # needs sage.rings.number_field sage: G = K.galois_group() # needs sage.rings.number_field - sage: _alg_key(G, algorithm="pari", recompute=True) # needs sage.rings.number_field + sage: _alg_key(G, algorithm='pari', recompute=True) # needs sage.rings.number_field 'pari' """ if recompute: @@ -56,7 +56,7 @@ class _GMixin: @lazy_attribute def _default_algorithm(self): """ - A string, the default algorithm used for computing the Galois group + A string, the default algorithm used for computing the Galois group. EXAMPLES:: diff --git a/src/sage/groups/galois_group_perm.py b/src/sage/groups/galois_group_perm.py index 3b81e0d5908..61a6e709c01 100644 --- a/src/sage/groups/galois_group_perm.py +++ b/src/sage/groups/galois_group_perm.py @@ -17,7 +17,7 @@ class GaloisGroup_perm(_GaloisMixin, PermutationGroup_generic): - ``field`` -- a field, separable over its base - - ``names`` -- a string or tuple of length 1, giving a variable name for + - ``names`` -- string or tuple of length 1, giving a variable name for the splitting field - ``gc_numbering`` -- boolean, whether to express permutations in terms of @@ -88,7 +88,7 @@ def _deg(self): r""" The number of moved points in the permutation representation. - This will be the degree of the original number field if `_gc_numbering`` + This will be the degree of the original number field if ``_gc_numbering`` is ``False``, or the degree of the Galois closure otherwise. EXAMPLES:: diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index e676bc547ed..69acc7c654d 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -300,10 +300,10 @@ def __init__(self, P, n, P0=None, indexed=False, operation='+', op=None): INPUT: - - ``P`` -- step value: any Sage object on which a binary operation is defined - - ``n`` -- number of multiples: non-negative integer - - ``P0`` -- offset (default 0): Sage object which can be 'added' to P - - ``indexed`` -- boolean (default ``False``) + - ``P`` -- step value; any Sage object on which a binary operation is defined + - ``n`` -- number of multiples; nonnegative integer + - ``P0`` -- offset (default: 0); Sage object which can be 'added' to P + - ``indexed`` -- boolean (default: ``False``) If ``indexed==False``, then the iterator delivers ``P0+i*P`` (if ``operation=='+'``) or ``P0*P**i`` (if @@ -392,13 +392,13 @@ def bsgs(a, b, bounds, operation='*', identity=None, inverse=None, op=None): - ``bounds`` -- a 2-tuple of integers ``(lower,upper)`` with ``0<=lower<=upper`` - ``operation`` -- string: ``'*'``, ``'+'``, other - ``identity`` -- the identity element of the group - - ``inverse()`` -- function of 1 argument ``x``, returning inverse of ``x`` - - ``op()`` -- function of 2 arguments ``x``, ``y`` returning ``x*y`` in the group + - ``inverse`` -- function of 1 argument ``x``, returning inverse of ``x`` + - ``op`` -- function of 2 arguments ``x``, ``y`` returning ``x*y`` in the group OUTPUT: An integer `n` such that `a^n = b` (or `na = b`). If no - such `n` exists, this function raises a :class:`ValueError` exception. + such `n` exists, this function raises a :exc:`ValueError` exception. .. NOTE:: @@ -526,11 +526,11 @@ def discrete_log_rho(a, base, ord=None, operation='*', identity=None, inverse=No - ``base`` -- a group element - ``ord`` -- the order of ``base`` or ``None``, in this case we try to compute it - - ``operation`` -- a string (default: ``'*'``) denoting whether we + - ``operation`` -- string (default: ``'*'``); denoting whether we are in an additive group or a multiplicative one - ``identity`` -- the group's identity - - ``inverse()`` -- function of 1 argument ``x``, returning inverse of ``x`` - - ``op()`` -- function of 2 arguments ``x``, ``y``, returning ``x*y`` in the group + - ``inverse`` -- function of 1 argument ``x``, returning inverse of ``x`` + - ``op`` -- function of 2 arguments ``x``, ``y``, returning ``x*y`` in the group - ``hash_function`` -- having an efficient hash function is critical for this algorithm (see examples) @@ -570,7 +570,7 @@ def discrete_log_rho(a, base, ord=None, operation='*', identity=None, inverse=No ... ValueError: for Pollard rho algorithm the order of the group must be prime - If it fails to find a suitable logarithm, it raises a :class:`ValueError`:: + If it fails to find a suitable logarithm, it raises a :exc:`ValueError`:: sage: I = IntegerModRing(171980) sage: discrete_log_rho(I(31002), I(15501)) # needs sage.libs.pari @@ -717,7 +717,7 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i assuming that ``ord`` is a multiple of the order of the base `b`. If ``ord`` is not specified, an attempt is made to compute it. - If no such `n` exists, this function raises a :class:`ValueError` exception. + If no such `n` exists, this function raises a :exc:`ValueError` exception. .. WARNING:: @@ -984,14 +984,14 @@ def discrete_log_lambda(a, base, bounds, operation='*', identity=None, inverse=N INPUT: - - a -- a group element - - base -- a group element - - bounds -- a couple (lb,ub) representing the range where we look for a logarithm - - operation -- string: '+', '*' or 'other' - - identity -- the identity element of the group - - inverse() -- function of 1 argument ``x`` returning inverse of ``x`` - - op() -- function of 2 arguments ``x``, ``y`` returning ``x*y`` in the group - - hash_function -- having an efficient hash function is critical for this algorithm + - ``a`` -- a group element + - ``base`` -- a group element + - ``bounds`` -- a couple (lb,ub) representing the range where we look for a logarithm + - ``operation`` -- string: '+', '*' or 'other' + - ``identity`` -- the identity element of the group + - ``inverse`` -- function of 1 argument ``x`` returning inverse of ``x`` + - ``op`` -- function of 2 arguments ``x``, ``y`` returning ``x*y`` in the group + - ``hash_function`` -- having an efficient hash function is critical for this algorithm OUTPUT: integer `n` such that `a=base^n` (or `a=n*base`) @@ -1025,7 +1025,6 @@ def discrete_log_lambda(a, base, bounds, operation='*', identity=None, inverse=N AUTHOR: -- Yann Laigle-Chapuy (2009-01-25) - """ from sage.rings.integer import Integer from operator import mul, add @@ -1201,13 +1200,13 @@ def order_from_multiple(P, m, plist=None, factorization=None, check=True, INPUT: - ``P`` -- a Sage object which is a group element - - ``m`` -- a Sage integer which is a multiple of the order of ``P``, + - ``m`` -- Sage integer which is a multiple of the order of ``P``, i.e. we require that ``m*P=0`` (or ``P**m=1``) - ``check`` -- a Boolean (default: ``True``), indicating whether we check if ``m`` really is a multiple of the order - ``factorization`` -- the factorization of ``m``, or ``None`` in which case this function will need to factor ``m`` - - ``plist`` -- a list of the prime factors of ``m``, or ``None``. Kept for compatibility only, + - ``plist`` -- list of the prime factors of ``m``, or ``None``. Kept for compatibility only, prefer the use of ``factorization`` - ``operation`` -- string: ``'+'`` (default), ``'*'`` or ``None`` - ``identity`` -- the identity element of the group @@ -1258,6 +1257,17 @@ def order_from_multiple(P, m, plist=None, factorization=None, check=True, sage: K. = GF(3^60) sage: order_from_multiple(a, 3^60 - 1, operation='*', check=False) 42391158275216203514294433200 + + TESTS: + + Check that :issue:`38489` is fixed:: + + sage: from sage.groups.generic import order_from_multiple + sage: plist = [43, 257, 547, 881] + sage: m = prod(plist[:-1]) + sage: elt = Zmod(m)(plist[-1]) + sage: order_from_multiple(elt, m, plist=plist) + 6044897 """ Z = integer_ring.ZZ @@ -1326,6 +1336,8 @@ def _order_from_multiple_helper(Q, L, S): if abs(sum_left + v - (S / 2)) > abs(sum_left - (S / 2)): break sum_left += v + if not 0 < k < l: + k = l // 2 L1 = L[:k] L2 = L[k:] # recursive calls @@ -1354,14 +1366,14 @@ def order_from_bounds(P, bounds, d=None, operation='+', - ``d`` -- (optional) a positive integer; only ``m`` which are multiples of this will be considered - - ``operation`` -- string: ``'+'`` (default ) or ``'*'`` or other. + - ``operation`` -- string; ``'+'`` (default) or ``'*'`` or other. If other, the following must be supplied: - - ``identity`` -- the identity element for the group; - - ``inverse()`` -- a function of one argument giving the inverse - of a group element; - - ``op()`` -- a function of 2 arguments defining the group binary - operation. + - ``identity`` -- the identity element for the group + - ``inverse`` -- a function of one argument giving the inverse + of a group element + - ``op`` -- a function of 2 arguments defining the group binary + operation .. NOTE:: @@ -1540,14 +1552,14 @@ def merge_points(P1, P2, operation='+', - ``P1`` -- a pair `(g_1,n_1)` where `g_1` is a group element of order `n_1` - ``P2`` -- a pair `(g_2,n_2)` where `g_2` is a group element of order `n_2` - - ``operation`` -- string: ``'+'`` (default) or ``'*'`` or other. If + - ``operation`` -- string; ``'+'`` (default) or ``'*'`` or other. If other, the following must be supplied: - - ``identity`` -- the identity element for the group; - - ``inverse()`` -- a function of one argument giving the inverse - of a group element; - - ``op()`` -- a function of 2 arguments defining the group - binary operation. + - ``identity`` -- the identity element for the group + - ``inverse`` -- a function of one argument giving the inverse + of a group element + - ``op`` -- a function of 2 arguments defining the group + binary operation OUTPUT: a pair `(g_3,n_3)` where `g_3` has order `n_3=\hbox{lcm}(n_1,n_2)` @@ -1626,7 +1638,7 @@ def structure_description(G, latex=False): INPUT: - - ``latex`` -- a boolean (default: ``False``); if ``True``, return a + - ``latex`` -- boolean (default: ``False``); if ``True``, return a LaTeX formatted string OUTPUT: string diff --git a/src/sage/groups/group.pyx b/src/sage/groups/group.pyx index 0a62fa0f12e..b5047594a9c 100644 --- a/src/sage/groups/group.pyx +++ b/src/sage/groups/group.pyx @@ -286,7 +286,7 @@ cdef class FiniteGroup(Group): def __init__(self, base=None, category=None): """ - The Python constructor + The Python constructor. TESTS:: diff --git a/src/sage/groups/group_exp.py b/src/sage/groups/group_exp.py index 49f2315eae3..a8677c05e4c 100644 --- a/src/sage/groups/group_exp.py +++ b/src/sage/groups/group_exp.py @@ -14,15 +14,16 @@ # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** + from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups -from sage.categories.groups import Groups -from sage.structure.element import MultiplicativeGroupElement -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.parent import Parent -from sage.categories.morphism import SetMorphism from sage.categories.functor import Functor +from sage.categories.groups import Groups from sage.categories.homset import Hom +from sage.categories.morphism import SetMorphism +from sage.structure.element import MultiplicativeGroupElement from sage.structure.element_wrapper import ElementWrapper +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation class GroupExp(Functor): @@ -59,7 +60,7 @@ class GroupExp(Functor): -3 sage: x.parent() Multiplicative form of Integer Ring - sage: EZ(-1)*EZ(6) == EZ(5) + sage: EZ(-1) * EZ(6) == EZ(5) True sage: EZ(3)^(-1) -3 @@ -71,22 +72,22 @@ class GroupExp(Functor): sage: L = RootSystem(['A',2]).ambient_space() sage: EL = E(L) - sage: W = L.weyl_group(prefix="s") + sage: W = L.weyl_group(prefix='s') sage: s2 = W.simple_reflection(2) sage: def my_action(mu): ....: return s2.action(mu) sage: from sage.categories.morphism import SetMorphism sage: from sage.categories.homset import Hom - sage: f = SetMorphism(Hom(L,L,CommutativeAdditiveGroups()), my_action) + sage: f = SetMorphism(Hom(L, L, CommutativeAdditiveGroups()), my_action) sage: F = E(f); F - Generic endomorphism of Multiplicative form of Ambient space of the Root system of type ['A', 2] + Generic endomorphism of + Multiplicative form of Ambient space of the Root system of type ['A', 2] sage: v = L.an_element(); v (2, 2, 3) sage: y = F(EL(v)); y (2, 3, 2) sage: y.parent() Multiplicative form of Ambient space of the Root system of type ['A', 2] - """ def __init__(self): r""" @@ -114,8 +115,8 @@ def _apply_functor(self, x): OUTPUT: an isomorphic group whose operation is multiplication rather than addition - In the following example, ``self`` is the functor `GroupExp()`, - `x` is the additive group `QQ^2`, and the output group is stored as `EQ2`. + In the following example, ``self`` is the functor ``GroupExp()``, + ``x`` is the additive group ``QQ^2``, and the output group is stored as ``EQ2``. EXAMPLES:: @@ -145,8 +146,6 @@ def _apply_functor_to_morphism(self, f): OUTPUT: the above homomorphism, but between the corresponding multiplicative groups - - The above homomorphism, but between the corresponding multiplicative groups. - In the following example, ``self`` is the functor :class:`GroupExp` and `f` is an endomorphism of the additive group of integers. @@ -156,7 +155,7 @@ def _apply_functor_to_morphism(self, f): ....: return x + x sage: from sage.categories.morphism import SetMorphism sage: from sage.categories.homset import Hom - sage: f = SetMorphism(Hom(ZZ,ZZ,CommutativeAdditiveGroups()),double) + sage: f = SetMorphism(Hom(ZZ, ZZ, CommutativeAdditiveGroups()), double) sage: E = GroupExp() sage: EZ = E._apply_functor(ZZ) sage: F = E._apply_functor_to_morphism(f) @@ -164,7 +163,7 @@ def _apply_functor_to_morphism(self, f): True sage: F.codomain() == EZ True - sage: F(EZ(3)) == EZ(3)*EZ(3) + sage: F(EZ(3)) == EZ(3) * EZ(3) True """ new_domain = self._apply_functor(f.domain()) @@ -172,6 +171,7 @@ def _apply_functor_to_morphism(self, f): new_f = lambda a: new_codomain(f(a.value)) return SetMorphism(Hom(new_domain, new_codomain, Groups()), new_f) + class GroupExpElement(ElementWrapper, MultiplicativeGroupElement): r""" An element in the exponential of a commutative additive group. @@ -184,15 +184,15 @@ class GroupExpElement(ElementWrapper, MultiplicativeGroupElement): EXAMPLES:: + sage: from sage.groups.group_exp import GroupExpElement sage: G = QQ^2 sage: EG = GroupExp()(G) - sage: z = GroupExpElement(EG, vector(QQ, (1,-3))); z + sage: z = GroupExpElement(EG, vector(QQ, (1, -3))); z (1, -3) sage: z.parent() Multiplicative form of Vector space of dimension 2 over Rational Field - sage: EG(vector(QQ,(1,-3)))==z + sage: EG(vector(QQ, (1, -3))) == z True - """ def __init__(self, parent, x): r""" @@ -202,7 +202,7 @@ def __init__(self, parent, x): sage: EG = GroupExp()(G) sage: x = EG.an_element(); x (1, 0) - sage: TestSuite(x).run(skip = "_test_category") + sage: TestSuite(x).run(skip="_test_category") See the documentation of :meth:`sage.structure.element_wrapper.ElementWrapper.__init__` for the reason behind skipping the category test. @@ -233,7 +233,7 @@ def __mul__(self, x): sage: x = G(2) sage: x.__mul__(G(3)) 5 - sage: G.product(G(2),G(3)) + sage: G.product(G(2), G(3)) 5 """ return GroupExpElement(self.parent(), self.value + x.value) @@ -245,7 +245,7 @@ class GroupExp_Class(UniqueRepresentation, Parent): INPUT: - - `G` -- a commutative additive group + - ``G`` -- a commutative additive group OUTPUT: the multiplicative form of `G` @@ -260,7 +260,7 @@ def __init__(self, G): EXAMPLES:: sage: EG = GroupExp()(QQ^2) - sage: TestSuite(EG).run(skip = "_test_elements") + sage: TestSuite(EG).run(skip="_test_elements") """ if G not in CommutativeAdditiveGroups(): raise TypeError("%s must be a commutative additive group" % G) @@ -286,7 +286,7 @@ def _element_constructor_(self, x): EXAMPLES:: sage: G = GroupExp()(ZZ) - sage: G(4) # indirect doctest + sage: G(4) # indirect doctest 4 """ return GroupExpElement(self, x) diff --git a/src/sage/groups/group_semidirect_product.py b/src/sage/groups/group_semidirect_product.py index 7adc1868f8d..7287a79f614 100644 --- a/src/sage/groups/group_semidirect_product.py +++ b/src/sage/groups/group_semidirect_product.py @@ -33,8 +33,8 @@ def _repr_(self): sage: def twist(x,y): ....: return y - sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), # indirect doctest - ....: WeylGroup(['A',3],prefix="t"), twist) + sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), # indirect doctest + ....: WeylGroup(['A',3],prefix='t'), twist) Semidirect product of Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) acting on Weyl Group of type ['A', 3] @@ -72,7 +72,7 @@ def __invert__(self): sage: L = RootSystem(['A',2]).root_lattice() sage: from sage.groups.group_exp import GroupExp sage: EL = GroupExp()(L) - sage: W = L.weyl_group(prefix="s") + sage: W = L.weyl_group(prefix='s') sage: def twist(w,v): ....: return EL(w.action(v.value)) sage: G = GroupSemidirectProduct(W, EL, twist, prefix1='t') @@ -102,7 +102,7 @@ def to_opposite(self): Root lattice of the Root system of type ['A', 2] sage: from sage.groups.group_exp import GroupExp sage: EL = GroupExp()(L) - sage: W = L.weyl_group(prefix="s"); W + sage: W = L.weyl_group(prefix='s'); W Weyl Group of type ['A', 2] (as a matrix group acting on the root lattice) sage: def twist(w,v): @@ -141,14 +141,14 @@ class GroupSemidirectProduct(CartesianProduct): INPUT: - - ``G`` and ``H`` -- multiplicative groups + - ``G``, ``H`` -- multiplicative groups - ``twist`` -- (default: ``None``) a function defining a homomorphism (see below) - - ``act_to_right`` -- ``True`` or ``False`` (default: ``True``) - - ``prefix0`` -- (default: ``None``) optional string - - ``prefix1`` -- (default: ``None``) optional string - - ``print_tuple`` -- ``True`` or ``False`` (default: ``False``) - - ``category`` -- A category (default: ``Groups()``) + - ``act_to_right`` -- boolean (default: ``True``) + - ``prefix0`` -- string (default: ``None``) + - ``prefix1`` -- string (default: ``None``) + - ``print_tuple`` -- boolean (default: ``False``) + - ``category`` -- a category (default: ``Groups()``) A semidirect product of groups `G` and `H` is a group structure on the Cartesian product `G \times H` whose product agrees with that @@ -228,7 +228,7 @@ class GroupSemidirectProduct(CartesianProduct): sage: # needs sage.rings.number_field sage: cartan_type = CartanType(['A',2]) - sage: W = WeylGroup(cartan_type, prefix="s") + sage: W = WeylGroup(cartan_type, prefix='s') sage: def twist(w,v): ....: return w*v*(~w) sage: WW = GroupSemidirectProduct(W, W, twist=twist, print_tuple=True) @@ -256,8 +256,8 @@ def __init__(self, G, H, twist=None, act_to_right=True, prefix0=None, ....: return y sage: import __main__ sage: __main__.twist = twist - sage: G = GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), - ....: WeylGroup(['A',3],prefix="t"), twist) + sage: G = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), + ....: WeylGroup(['A',3],prefix='t'), twist) sage: TestSuite(G).run() The ``__main__`` business is a trick to pass the pickling test. @@ -299,8 +299,8 @@ def act_to_right(self): sage: def twist(x,y): ....: return y - sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), - ....: WeylGroup(['A',3],prefix="t"), twist).act_to_right() + sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), + ....: WeylGroup(['A',3],prefix='t'), twist).act_to_right() True """ return self._act_to_right @@ -313,8 +313,8 @@ def _repr_(self): sage: def twist(x,y): ....: return y - sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), # indirect doctest - ....: WeylGroup(['A',3],prefix="t"), twist) + sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), # indirect doctest + ....: WeylGroup(['A',3],prefix='t'), twist) Semidirect product of Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) acting on Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space) @@ -336,8 +336,8 @@ def _element_constructor_(self, x): ....: return y sage: import __main__ sage: __main__.twist = twist - sage: g = GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), - ....: WeylGroup(['A',3],prefix="t"), twist).an_element() + sage: g = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), + ....: WeylGroup(['A',3],prefix='t'), twist).an_element() sage: TestSuite(g).run() """ def type_error(): @@ -493,8 +493,8 @@ def construction(self): sage: def twist(x,y): ....: return y - sage: H = GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), - ....: WeylGroup(['A',3],prefix="t"), twist) + sage: H = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), + ....: WeylGroup(['A',3],prefix='t'), twist) sage: H.construction() """ return None diff --git a/src/sage/groups/indexed_free_group.py b/src/sage/groups/indexed_free_group.py index 02a4838d77c..ad484532f13 100644 --- a/src/sage/groups/indexed_free_group.py +++ b/src/sage/groups/indexed_free_group.py @@ -347,9 +347,7 @@ def _element_constructor_(self, x=None): sage: G({1: 3, -2: 12}) F[-2]^12*F[1]^3 sage: G(-5) - Traceback (most recent call last): - ... - TypeError: unable to convert -5, use gen() instead + F[-5] TESTS:: diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index 931d22ccdc5..3491c9f9db0 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -9,7 +9,7 @@ If your group implementation uses libgap, then you should add :class:`GroupMixinLibGAP` as the first class that you are deriving from. This ensures that it properly overrides any default methods that -just raise :class:`NotImplementedError`. +just raise :exc:`NotImplementedError`. """ from sage.libs.gap.libgap import libgap @@ -578,7 +578,7 @@ def group_id(self): def exponent(self): r""" - Computes the exponent of the group. + Compute the exponent of the group. The exponent `e` of a group `G` is the LCM of the orders of its elements, that is, `e` is the smallest integer such that `g^e = 1` @@ -678,7 +678,7 @@ def character(self, values): INPUT: - - ``values`` -- a list of values of the character + - ``values`` -- list of values of the character OUTPUT: a group character diff --git a/src/sage/groups/libgap_morphism.py b/src/sage/groups/libgap_morphism.py index e0f75e7bd4f..3bcb28c1f94 100644 --- a/src/sage/groups/libgap_morphism.py +++ b/src/sage/groups/libgap_morphism.py @@ -48,8 +48,8 @@ class GroupMorphism_libgap(Morphism): - ``homset`` -- the parent - ``gap_hom`` -- a :class:`sage.libs.gap.element.GapElement` consisting of a group homomorphism - - ``check`` -- (default: ``True``) check if the ``gap_hom`` is a group - homomorphism; this can be expensive + - ``check`` -- boolean (default: ``True``); check if the ``gap_hom`` is a group + homomorphism (this can be expensive) EXAMPLES:: diff --git a/src/sage/groups/libgap_wrapper.pyx b/src/sage/groups/libgap_wrapper.pyx index ddba766e94d..fe09dc080c1 100644 --- a/src/sage/groups/libgap_wrapper.pyx +++ b/src/sage/groups/libgap_wrapper.pyx @@ -88,7 +88,7 @@ class ParentLibGAP(SageObject): - ``libgap_parent`` -- the libgap element that is the parent in GAP - - ``ambient`` -- A derived class of :class:`ParentLibGAP` or + - ``ambient`` -- a derived class of :class:`ParentLibGAP` or ``None`` (default); the ambient class if ``libgap_parent`` has been defined as a subgroup @@ -216,7 +216,7 @@ class ParentLibGAP(SageObject): INPUT: - - ``generators`` -- a list/tuple/iterable of group elements. + - ``generators`` -- list/tuple/iterable of group elements OUTPUT: the subgroup generated by ``generators`` @@ -481,7 +481,7 @@ cdef class ElementLibGAP(MultiplicativeGroupElement): def __init__(self, parent, libgap_element): """ - The Python constructor + The Python constructor. TESTS:: @@ -595,7 +595,7 @@ cdef class ElementLibGAP(MultiplicativeGroupElement): r""" Return a LaTeX representation. - OUTPUT: a string; a valid LaTeX math command sequence + OUTPUT: string; a valid LaTeX math command sequence EXAMPLES:: diff --git a/src/sage/groups/lie_gps/nilpotent_lie_group.py b/src/sage/groups/lie_gps/nilpotent_lie_group.py index 1164f28e056..aa9f6bd0dc8 100644 --- a/src/sage/groups/lie_gps/nilpotent_lie_group.py +++ b/src/sage/groups/lie_gps/nilpotent_lie_group.py @@ -83,7 +83,7 @@ class NilpotentLieGroup(Group, DifferentiableManifold): - ``L`` -- the Lie algebra of the Lie group; must be a finite dimensional nilpotent Lie algebra with basis over a topological field, e.g. `\QQ` or `\RR` - - ``name`` -- a string; name (symbol) given to the Lie group + - ``name`` -- string; name (symbol) given to the Lie group Two types of exponential coordinates are defined on any nilpotent Lie group using the basis of the Lie algebra, diff --git a/src/sage/groups/matrix_gps/coxeter_group.py b/src/sage/groups/matrix_gps/coxeter_group.py index b6a9e211ff0..1fc089d94c4 100644 --- a/src/sage/groups/matrix_gps/coxeter_group.py +++ b/src/sage/groups/matrix_gps/coxeter_group.py @@ -176,14 +176,14 @@ class CoxeterMatrixGroup(UniqueRepresentation, FinitelyGeneratedMatrixGroup_gene We can also create Coxeter groups from Cartan types using the ``implementation`` keyword:: - sage: W = CoxeterGroup(['D',5], implementation="reflection"); W + sage: W = CoxeterGroup(['D',5], implementation='reflection'); W Finite Coxeter group over Integer Ring with Coxeter matrix: [1 3 2 2 2] [3 1 3 2 2] [2 3 1 3 3] [2 2 3 1 2] [2 2 3 2 1] - sage: W = CoxeterGroup(['H',3], implementation="reflection"); W # needs sage.libs.gap sage.rings.number_field + sage: W = CoxeterGroup(['H',3], implementation='reflection'); W # needs sage.libs.gap sage.rings.number_field Finite Coxeter group over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? with Coxeter matrix: @@ -198,7 +198,7 @@ def __classcall_private__(cls, data, base_ring=None, index_set=None): EXAMPLES:: - sage: W1 = CoxeterGroup(['A',2], implementation="reflection", base_ring=ZZ) + sage: W1 = CoxeterGroup(['A',2], implementation='reflection', base_ring=ZZ) sage: W2 = CoxeterGroup([[1,3],[3,1]], index_set=(1,2)) sage: W1 is W2 True @@ -362,7 +362,7 @@ def _coerce_map_from_(self, P): sage: W2 = WeylGroup(["A",4]) sage: W._coerce_map_from_(W2) True - sage: W3 = WeylGroup(["A",4], implementation="permutation") + sage: W3 = WeylGroup(["A",4], implementation='permutation') sage: W._coerce_map_from_(W3) True sage: W4 = WeylGroup(["A",3]) @@ -513,7 +513,7 @@ def simple_reflection(self, i): EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: W.simple_reflection(1) [-1 1 0] [ 0 1 0] @@ -727,7 +727,7 @@ def first_descent(self, side='right', index_set=None, positive=False): EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: a,b,c = W.gens() sage: elt = b*a*c sage: elt.first_descent() @@ -766,11 +766,11 @@ def descents(self, side='right', index_set=None, positive=False): - ``index_set`` -- (default: all of them) a subset (as a list or iterable) of the nodes of the Dynkin diagram - ``side`` -- (default: ``'right'``) ``'left'`` or ``'right'`` - - ``positive`` -- (default: ``False``) boolean + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: a,b,c = W.gens() sage: elt = b*a*c sage: elt.descents() @@ -809,7 +809,7 @@ def has_right_descent(self, i): `\ell(ws) < \ell(w)` then `w(\alpha_s) < 0`. Thus `i \in I` is a right descent if `w(\alpha_{s_i}) < 0` or equivalently if the matrix representing `w` has all entries - of the `i`-th column being non-positive. + of the `i`-th column being nonpositive. INPUT: @@ -817,7 +817,7 @@ def has_right_descent(self, i): EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: a,b,c = W.gens() sage: elt = b*a*c sage: [elt.has_right_descent(i) for i in [1, 2, 3]] @@ -836,7 +836,7 @@ def canonical_matrix(self): EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: a,b,c = W.gens() sage: elt = a*b*c sage: elt.canonical_matrix() @@ -847,7 +847,7 @@ def canonical_matrix(self): return self.matrix() @cached_method - def action_on_root_indices(self, i, side="left"): + def action_on_root_indices(self, i, side='left'): """ Return the action on the set of roots. @@ -855,7 +855,7 @@ def action_on_root_indices(self, i, side="left"): EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: w = W.w0 sage: w.action_on_root_indices(0) 11 @@ -896,7 +896,7 @@ def _matrix_test_right_descent(M, i, n, zero): EXAMPLES:: sage: from sage.groups.matrix_gps.coxeter_group import _matrix_test_right_descent - sage: W = CoxeterGroup(['A',3], implementation="reflection") + sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: a,b,c = W.gens() sage: elt = b*a*c sage: zero = W.base_ring().zero() diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py index 909e92b80cc..b8dd5b8c01d 100644 --- a/src/sage/groups/matrix_gps/finitely_generated.py +++ b/src/sage/groups/matrix_gps/finitely_generated.py @@ -83,7 +83,7 @@ def normalize_square_matrices(matrices): """ Find a common space for all matrices. - OUTPUT: a list of matrices, all elements of the same matrix space + OUTPUT: list of matrices, all elements of the same matrix space EXAMPLES:: diff --git a/src/sage/groups/matrix_gps/finitely_generated_gap.py b/src/sage/groups/matrix_gps/finitely_generated_gap.py index 70c45d59162..d3403f22f40 100644 --- a/src/sage/groups/matrix_gps/finitely_generated_gap.py +++ b/src/sage/groups/matrix_gps/finitely_generated_gap.py @@ -118,7 +118,7 @@ def as_permutation_group(self, algorithm=None, seed=None): sage: G.cardinality() 21499084800 sage: P = G.as_permutation_group() - sage: Psmaller = G.as_permutation_group(algorithm="smaller", seed=6) + sage: Psmaller = G.as_permutation_group(algorithm='smaller', seed=6) sage: P.cardinality() 21499084800 sage: P.degree() @@ -426,7 +426,7 @@ def molien_series(self, chi=None, return_series=True, prec=20, variable='t'): INPUT: - ``chi`` -- (default: trivial character) a linear group character of this group - - ``return_series`` -- boolean (default: ``True``) if ``True``, then returns + - ``return_series`` -- boolean (default: ``True``); if ``True``, then returns the Molien series as a power series, ``False`` as a rational function - ``prec`` -- integer (default: 20); power series default precision (possibly infinite, in which case it is computed lazily) @@ -835,7 +835,7 @@ def invariants_of_degree(self, deg, chi=None, R=None): INPUT: - - ``degree`` -- a positive integer + - ``degree`` -- positive integer - ``chi`` -- (default: trivial character) a linear group character of this group diff --git a/src/sage/groups/matrix_gps/group_element.pyx b/src/sage/groups/matrix_gps/group_element.pyx index 952cdc0c6c2..5d00aa727bf 100644 --- a/src/sage/groups/matrix_gps/group_element.pyx +++ b/src/sage/groups/matrix_gps/group_element.pyx @@ -127,10 +127,10 @@ cdef class MatrixGroupElement_generic(MultiplicativeGroupElement): - ``parent`` -- the parent - - ``check`` -- bool (default: ``True``); if ``True``, then + - ``check`` -- boolean (default: ``True``); if ``True``, then do some type checking - - ``convert`` -- bool (default: ``True``); if ``True``, then + - ``convert`` -- boolean (default: ``True``); if ``True``, then convert ``M`` to the right matrix space EXAMPLES:: diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index b24e845b8f1..e5d7d637fdf 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -37,10 +37,10 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): - ``parent`` -- the parent - - ``check`` -- bool (default: ``True``); if ``True``, do some + - ``check`` -- boolean (default: ``True``); if ``True``, do some type checking - - ``convert`` -- bool (default: ``True``); if ``True``, convert + - ``convert`` -- boolean (default: ``True``); if ``True``, convert ``M`` to the right matrix space """ def __init__(self, parent, M, check=True, convert=True): @@ -210,7 +210,7 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): entries = self.gap().Flat() MS = self.parent().matrix_space() ring = MS.base_ring() - m = MS([x.sage(ring=ring) for x in entries]) + m = MS([ring(x) for x in entries]) m.set_immutable() return m @@ -310,7 +310,7 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): INPUT: - - ``gens`` -- a list/tuple/iterable of elements (or objects + - ``gens`` -- list/tuple/iterable of elements (or objects that can be converted to group elements), or ``None`` (default); by default, the generators of the parent group are used @@ -318,7 +318,7 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): OUTPUT: A factorization object that contains information about the - order of factors and the exponents. A :class:`ValueError` is raised + order of factors and the exponents. A :exc:`ValueError` is raised if the group element cannot be written as a word in ``gens``. ALGORITHM: diff --git a/src/sage/groups/matrix_gps/heisenberg.py b/src/sage/groups/matrix_gps/heisenberg.py index 8a262ddf1c7..f101c27153b 100644 --- a/src/sage/groups/matrix_gps/heisenberg.py +++ b/src/sage/groups/matrix_gps/heisenberg.py @@ -122,7 +122,7 @@ def __init__(self, n=1, R=0): sage: H = groups.matrix.Heisenberg(n=2, R=4) sage: TestSuite(H).run() # long time sage: H = groups.matrix.Heisenberg(n=3) - sage: TestSuite(H).run(max_runs=30, skip="_test_elements") # long time + sage: TestSuite(H).run(max_runs=30, skip='_test_elements') # long time sage: H = groups.matrix.Heisenberg(n=2, R=GF(4)) sage: TestSuite(H).run() # long time diff --git a/src/sage/groups/matrix_gps/isometries.py b/src/sage/groups/matrix_gps/isometries.py index c39c0e3bd80..8e0df5f154b 100644 --- a/src/sage/groups/matrix_gps/isometries.py +++ b/src/sage/groups/matrix_gps/isometries.py @@ -52,15 +52,15 @@ class GroupOfIsometries(FinitelyGeneratedMatrixGroup_gap): INPUT: - - ``degree`` -- integer, the degree (matrix size) of the matrix + - ``degree`` -- integer; the degree (matrix size) of the matrix - ``base_ring`` -- ring, the base ring of the matrices - - ``gens`` -- a list of matrices over the base ring + - ``gens`` -- list of matrices over the base ring - ``invariant_bilinear_form`` -- a symmetric matrix - ``category`` -- (default: ``None``) a category of groups - - ``check`` -- bool (default: ``True``) check if the generators + - ``check`` -- boolean (default: ``True``); check if the generators preserve the bilinear form - ``invariant_submodule`` -- a submodule preserved by the group action - (default: ``None``) registers an action on this submodule + (default: ``None``); registers an action on this submodule - ``invariant_quotient_module`` -- a quotient module preserved by the group action (default: ``None``) registers an action on this quotient module @@ -267,9 +267,9 @@ class GroupActionOnSubmodule(Action): INPUT: - - ``MatrixGroup`` -- an instance of :class:`GroupOfIsometries` + - ``MatrixGroup`` -- an instance of :class:`GroupOfIsometries` - ``submodule`` -- an invariant submodule - - ``is_left`` -- bool (default: ``False``) + - ``is_left`` -- boolean (default: ``False``) EXAMPLES:: @@ -290,7 +290,7 @@ class GroupActionOnSubmodule(Action): """ def __init__(self, MatrixGroup,submodule, is_left=False): r""" - Initialize the action + Initialize the action. TESTS:: @@ -356,7 +356,7 @@ class GroupActionOnQuotientModule(Action): INPUT: - - ``MatrixGroup`` -- the group acting + - ``MatrixGroup`` -- the group acting :class:`GroupOfIsometries` - ``submodule`` -- an invariant quotient module - ``is_left`` -- boolean (default: ``False``) diff --git a/src/sage/groups/matrix_gps/linear.py b/src/sage/groups/matrix_gps/linear.py index bd77d7ce19a..113a93cca44 100644 --- a/src/sage/groups/matrix_gps/linear.py +++ b/src/sage/groups/matrix_gps/linear.py @@ -89,13 +89,13 @@ def GL(n, R, var='a'): INPUT: - - ``n`` -- a positive integer. + - ``n`` -- positive integer - - ``R`` -- ring or an integer. If an integer is specified, the - corresponding finite field is used. + - ``R`` -- ring or an integer; if an integer is specified, the + corresponding finite field is used - ``var`` -- variable used to represent generator of the finite - field, if needed. + field, if needed EXAMPLES:: @@ -310,7 +310,7 @@ def _check_matrix(self, x, *args): raise TypeError('matrix must have determinant one') else: if x.determinant() == 0: - raise TypeError('matrix must non-zero determinant') + raise TypeError('matrix must nonzero determinant') def order(self): r""" diff --git a/src/sage/groups/matrix_gps/matrix_group.py b/src/sage/groups/matrix_gps/matrix_group.py index 8cd34aa4cb1..a11ca5a4448 100644 --- a/src/sage/groups/matrix_gps/matrix_group.py +++ b/src/sage/groups/matrix_gps/matrix_group.py @@ -134,10 +134,10 @@ def _check_matrix(self, x, *args): - ``x`` -- a Sage matrix in the correct matrix space (degree and base ring) - - ``*args`` -- optional other representations of ``x``, + - ``*args`` -- (optional) other representations of ``x``, depending on the group implementation. Ignored by default - OUTPUT: a :class:`TypeError` must be raised if ``x`` is invalid + OUTPUT: a :exc:`TypeError` must be raised if ``x`` is invalid EXAMPLES:: @@ -189,7 +189,7 @@ def subgroup(self, generators, check=True): INPUT: - - ``generators`` -- a list/tuple/iterable of group elements of ``self`` + - ``generators`` -- list/tuple/iterable of group elements of ``self`` - ``check`` -- boolean (default: ``True``); whether to check that each matrix is invertible @@ -596,12 +596,12 @@ def is_trivial(self): True sage: SL(2, ZZ).is_trivial() False - sage: CoxeterGroup(['B',3], implementation="matrix").is_trivial() + sage: CoxeterGroup(['B',3], implementation='matrix').is_trivial() False TESTS:: - sage: CoxeterGroup(['A',0], implementation="matrix").is_trivial() + sage: CoxeterGroup(['A',0], implementation='matrix').is_trivial() True sage: MatrixGroup([matrix(SR, [[1,x], [0,1]])]).is_trivial() False diff --git a/src/sage/groups/matrix_gps/matrix_group_gap.py b/src/sage/groups/matrix_gps/matrix_group_gap.py index d7de4c75f6e..552fcde3ff6 100644 --- a/src/sage/groups/matrix_gps/matrix_group_gap.py +++ b/src/sage/groups/matrix_gps/matrix_group_gap.py @@ -201,7 +201,7 @@ def _check_matrix(self, x_sage, x_gap): - ``x_gap`` -- the corresponding LibGAP matrix - OUTPUT: a :class:`TypeError` must be raised if ``x`` is invalid + OUTPUT: a :exc:`TypeError` must be raised if ``x`` is invalid EXAMPLES:: @@ -228,11 +228,11 @@ def subgroup(self, generators, check=True): INPUT: - - ``generators`` -- a list/tuple/iterable of group elements of ``self`` - - ``check`` -- boolean (default: ``True``). Whether to check that each + - ``generators`` -- list/tuple/iterable of group elements of ``self`` + - ``check`` -- boolean (default: ``True``); whether to check that each matrix is invertible - OUTPUT: The subgroup generated by ``generators`` as an instance of + OUTPUT: the subgroup generated by ``generators`` as an instance of :class:`FinitelyGeneratedMatrixGroup_gap` EXAMPLES:: diff --git a/src/sage/groups/matrix_gps/meson.build b/src/sage/groups/matrix_gps/meson.build new file mode 100644 index 00000000000..43968d8ed59 --- /dev/null +++ b/src/sage/groups/matrix_gps/meson.build @@ -0,0 +1,45 @@ +py.install_sources( + 'all.py', + 'binary_dihedral.py', + 'catalog.py', + 'coxeter_group.py', + 'finitely_generated.py', + 'finitely_generated_gap.py', + 'group_element.pxd', + 'group_element_gap.pxd', + 'heisenberg.py', + 'homset.py', + 'isometries.py', + 'linear.py', + 'linear_gap.py', + 'matrix_group.py', + 'matrix_group_gap.py', + 'morphism.py', + 'named_group.py', + 'named_group_gap.py', + 'orthogonal.py', + 'orthogonal_gap.py', + 'pickling_overrides.py', + 'symplectic.py', + 'symplectic_gap.py', + 'unitary.py', + 'unitary_gap.py', + subdir: 'sage/groups/matrix_gps', +) + +extension_data = { + 'group_element' : files('group_element.pyx'), + 'group_element_gap' : files('group_element_gap.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/groups/matrix_gps', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/groups/matrix_gps/named_group.py b/src/sage/groups/matrix_gps/named_group.py index 142ea68ddfb..64d2b932662 100644 --- a/src/sage/groups/matrix_gps/named_group.py +++ b/src/sage/groups/matrix_gps/named_group.py @@ -67,16 +67,15 @@ def normalize_args_vectorspace(*args, **kwds): * Degree and base ring: - - ``degree`` -- integer. The degree of the affine group, that - is, the dimension of the affine space the group is acting on. + - ``degree`` -- integer; the degree of the affine group, that + is, the dimension of the affine space the group is acting on - ``ring`` -- a ring or an integer. The base ring of the affine space. If an integer is given, it must be a prime power and the corresponding finite field is constructed. - - ``var='a'`` -- optional keyword argument to specify the finite - field generator name in the case where ``ring`` is a prime - power. + - ``var='a'`` -- (optional) keyword argument to specify the finite + field generator name in the case where ``ring`` is a prime power OUTPUT: a pair ``(degree, ring)`` @@ -136,7 +135,7 @@ def normalize_args_invariant_form(R, d, invariant_form): - ``d`` -- integer giving the dimension of the module the classical group is operating on - - ``invariant_form`` -- (optional) instances being accepted by + - ``invariant_form`` -- (optional) instances being accepted by the matrix-constructor that define a `d \times d` square matrix over R describing the bilinear form to be kept invariant by the classical group @@ -209,7 +208,7 @@ def __init__(self, degree, base_ring, special, sage_name, latex_string, the constructor of :class:`sage.groups.matrix_gps.matrix_group.MatrixGroup_generic` - - ``invariant_form`` -- (optional) square-matrix of the given + - ``invariant_form`` -- (optional) square-matrix of the given degree over the given base_ring describing a bilinear form to be kept invariant by the group diff --git a/src/sage/groups/matrix_gps/orthogonal.py b/src/sage/groups/matrix_gps/orthogonal.py index 4d0a2e00994..0e8536fed5f 100644 --- a/src/sage/groups/matrix_gps/orthogonal.py +++ b/src/sage/groups/matrix_gps/orthogonal.py @@ -112,7 +112,7 @@ def normalize_args_e(degree, ring, e): - ``ring`` -- a ring; the base ring of the affine space - - ``e`` -- integer, one of `+1`, `0`, `-1`. Only relevant for + - ``e`` -- integer; one of `+1`, `0`, `-1`. Only relevant for finite fields and if the degree is even. A parameter that distinguishes inequivalent invariant forms. diff --git a/src/sage/groups/matrix_gps/symplectic.py b/src/sage/groups/matrix_gps/symplectic.py index efafae72e3c..bbcf92b1bcf 100644 --- a/src/sage/groups/matrix_gps/symplectic.py +++ b/src/sage/groups/matrix_gps/symplectic.py @@ -69,7 +69,7 @@ def Sp(n, R, var='a', invariant_form=None): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``R`` -- ring or an integer; if an integer is specified, the corresponding finite field is used @@ -77,7 +77,7 @@ def Sp(n, R, var='a', invariant_form=None): - ``var`` -- (default: ``'a'``) variable used to represent generator of the finite field, if needed - - ``invariant_form`` -- (optional) instances being accepted by + - ``invariant_form`` -- (optional) instances being accepted by the matrix-constructor which define a `n \times n` square matrix over ``R`` describing the alternating form to be kept invariant by the symplectic group diff --git a/src/sage/groups/matrix_gps/unitary.py b/src/sage/groups/matrix_gps/unitary.py index e36e01693ca..e16ffb6a46b 100644 --- a/src/sage/groups/matrix_gps/unitary.py +++ b/src/sage/groups/matrix_gps/unitary.py @@ -171,7 +171,7 @@ def GU(n, R, var='a', invariant_form=None): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``R`` -- ring or an integer; if an integer is specified, the corresponding finite field is used @@ -283,7 +283,7 @@ def SU(n, R, var='a', invariant_form=None): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``R`` -- ring or an integer; if an integer is specified, the corresponding finite field is used diff --git a/src/sage/groups/meson.build b/src/sage/groups/meson.build new file mode 100644 index 00000000000..3e2ffbb471c --- /dev/null +++ b/src/sage/groups/meson.build @@ -0,0 +1,57 @@ +py.install_sources( + 'all.py', + 'artin.py', + 'braid.py', + 'cactus_group.py', + 'class_function.py', + 'conjugacy_classes.py', + 'cubic_braid.py', + 'finitely_presented.py', + 'finitely_presented_catalog.py', + 'finitely_presented_named.py', + 'fqf_orthogonal.py', + 'free_group.py', + 'galois_group.py', + 'galois_group_perm.py', + 'generic.py', + 'group.pxd', + 'group_exp.py', + 'group_semidirect_product.py', + 'groups_catalog.py', + 'indexed_free_group.py', + 'kernel_subgroup.py', + 'libgap_group.py', + 'libgap_mixin.py', + 'libgap_morphism.py', + 'libgap_wrapper.pxd', + 'old.pxd', + 'pari_group.py', + 'raag.py', + subdir: 'sage/groups', +) + +extension_data = { + 'group' : files('group.pyx'), + 'libgap_wrapper' : files('libgap_wrapper.pyx'), + 'old' : files('old.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/groups', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + +install_subdir('abelian_gps', install_dir: sage_install_dir / 'groups') +install_subdir('additive_abelian', install_dir: sage_install_dir / 'groups') +install_subdir('affine_gps', install_dir: sage_install_dir / 'groups') +install_subdir('lie_gps', install_dir: sage_install_dir / 'groups') +subdir('matrix_gps') +install_subdir('misc_gps', install_dir: sage_install_dir / 'groups') +subdir('perm_gps') +subdir('semimonomial_transformations') diff --git a/src/sage/groups/misc_gps/argument_groups.py b/src/sage/groups/misc_gps/argument_groups.py index edbdb7b7bad..43c2ef98770 100644 --- a/src/sage/groups/misc_gps/argument_groups.py +++ b/src/sage/groups/misc_gps/argument_groups.py @@ -61,7 +61,7 @@ class AbstractArgument(MultiplicativeGroupElement): - ``element`` -- an element of parent's base - - ``normalize`` -- a boolean (default: ``True``) + - ``normalize`` -- boolean (default: ``True``) """ def __init__(self, parent, element, normalize=True): @@ -108,7 +108,7 @@ def __init__(self, parent, element, normalize=True): @staticmethod def _normalize_(element): r""" - Normalizes the given element. + Normalize the given element. INPUT: @@ -396,13 +396,13 @@ class UnitCirclePoint(AbstractArgument): - ``exponent`` -- a number (of a subset of the reals) - - ``normalize`` -- a boolean (default: ``True``) + - ``normalize`` -- boolean (default: ``True``) """ @staticmethod def _normalize_(exponent): r""" - Normalizes the given exponent so that it is in `[0,1)`. + Normalize the given exponent so that it is in `[0,1)`. INPUT: @@ -1043,7 +1043,7 @@ class ArgumentByElement(AbstractArgument): - ``element`` -- a nonzero element of the parent's base - - ``normalize`` -- a boolean (default: ``True``) + - ``normalize`` -- boolean (default: ``True``) """ def __init__(self, parent, element, normalize=True): @@ -1064,7 +1064,7 @@ def __init__(self, parent, element, normalize=True): @staticmethod def _normalize_(element): r""" - Normalizes the given element. + Normalize the given element. This is the identity for :class:`ArgumentByElement`. @@ -1380,7 +1380,7 @@ class Sign(AbstractArgument): - ``element`` -- a nonzero element of the parent's base - - ``normalize`` -- a boolean (default: ``True``) + - ``normalize`` -- boolean (default: ``True``) """ def __init__(self, parent, element, normalize=True): @@ -1402,7 +1402,7 @@ def __init__(self, parent, element, normalize=True): @staticmethod def _normalize_(element): r""" - Normalizes the given element. + Normalize the given element. This is the identity for :class:`Sign`. @@ -1697,7 +1697,7 @@ class ArgumentGroupFactory(UniqueFactory): The factory will analyze ``data`` and interpret it as ``specification`` or ``domain``. - - ``specification`` -- a string + - ``specification`` -- string The following is possible: @@ -1713,12 +1713,12 @@ class ArgumentGroupFactory(UniqueFactory): a string representing a SageMath parent which is interpreted as ``domain`` - - ``domain`` -- a SageMath parent representing a subset of the complex plane. - An instance of :class:`ArgumentByElementGroup` will be created with the given - ``domain``. + - ``domain`` -- a SageMath parent representing a subset of the complex plane; + an instance of :class:`ArgumentByElementGroup` will be created with the given + ``domain`` - - ``exponents`` -- a SageMath parent representing a subset of the reals. - An instance of :class`UnitCircleGroup` will be created with the given + - ``exponents`` -- a SageMath parent representing a subset of the reals; + an instance of :class`UnitCircleGroup` will be created with the given ``exponents`` Exactly one of ``data``, ``specification``, ``exponents`` has to be provided. diff --git a/src/sage/groups/perm_gps/constructor.py b/src/sage/groups/perm_gps/constructor.py index ab912f7667d..63c9aecd5d3 100644 --- a/src/sage/groups/perm_gps/constructor.py +++ b/src/sage/groups/perm_gps/constructor.py @@ -35,7 +35,7 @@ def PermutationGroupElement(g, parent=None, check=True): r""" - Builds a permutation from ``g``. + Build a permutation from ``g``. INPUT: @@ -53,8 +53,8 @@ def PermutationGroupElement(g, parent=None, check=True): it is mandatory if you want a permutation on a domain different from `\{1, \ldots, n\}` - - ``check`` -- (default: ``True``) whether additional check are performed; - setting it to ``False`` is likely to result in faster code + - ``check`` -- boolean (default: ``True``); whether additional check are + performed. Setting it to ``False`` is likely to result in faster code. EXAMPLES: @@ -167,11 +167,11 @@ def standardize_generator(g, convert_dict=None, as_cycles=False): - ``convert_dict`` -- (optional) a dictionary used to convert the points to a number compatible with GAP - - ``as_cycles`` -- (default: ``False``) whether the output should be + - ``as_cycles`` -- boolean (default: ``False``); whether the output should be as cycles or in one-line notation OUTPUT: the permutation in as a list in one-line notation or a list of - cycles as tuples. + cycles as tuples EXAMPLES:: diff --git a/src/sage/groups/perm_gps/cubegroup.py b/src/sage/groups/perm_gps/cubegroup.py index 1ea023b502d..8eadbac39f1 100644 --- a/src/sage/groups/perm_gps/cubegroup.py +++ b/src/sage/groups/perm_gps/cubegroup.py @@ -563,7 +563,7 @@ def __init__(self): EXAMPLES:: sage: rubik = CubeGroup() - sage: TestSuite(rubik).run(skip="_test_enumerated_set_contains") # because the group is very large + sage: TestSuite(rubik).run(skip='_test_enumerated_set_contains') # because the group is very large TESTS: @@ -684,18 +684,18 @@ def parse(self, mv, check=True): INPUT: - - ``mv`` -- Can one of the following: + - ``mv`` -- can one of the following: - - ``list`` -- list of facets (as returned by - self.facets()) + - ``list`` -- list of facets (as returned by + self.facets()) - - ``dict`` -- list of faces (as returned by - ``self.faces()``) + - ``dict`` -- list of faces (as returned by + ``self.faces()``) - - ``str`` -- either cycle notation (passed to GAP) or - a product of generators or Singmaster notation + - ``str`` -- either cycle notation (passed to GAP) or + a product of generators or Singmaster notation - - ``perm_group element`` -- returned as an element of ``self`` + - ``perm_group element`` -- returned as an element of ``self`` - ``check`` -- check if the input is valid @@ -845,9 +845,9 @@ def move(self, mv): INPUT: - - ``mv`` -- A string of the form ``Xa*Yb*...``, + - ``mv`` -- string of the form ``Xa*Yb*...``, where ``X``, ``Y``, ... are in ``R``, ``L``, ``F``, ``B``, ``U``, - ``D`` and ``a``, ``b``, ... are integers. + ``D`` and ``a``, ``b``, ... are integers EXAMPLES:: @@ -982,8 +982,8 @@ def plot3d_cube(self, mv, title=True): INPUT: - - ``mv`` -- A string in the Singmaster notation - - ``title`` -- (Default: ``True``) Display the title information + - ``mv`` -- string in the Singmaster notation + - ``title`` -- boolean (default: ``True``); display the title information The first one below is "superflip+4 spot" (in 26q\* moves) and the second one is the superflip (in 20f\* moves). Type show(P) to view @@ -1018,7 +1018,7 @@ def plot3d_cube(self, mv, title=True): return P return P - def legal(self, state, mode="quiet"): + def legal(self, state, mode='quiet'): r""" Return 1 (true) if the dictionary ``state`` (in the same format as returned by the faces method) represents a legal @@ -1237,7 +1237,7 @@ def __init__(self, state=None, history=[], colors=[lpurple,yellow,red,green,oran if isinstance(state, str): state = self._group.faces(state) if not isinstance(state, PermutationGroupElement): - legal, state = self._group.legal(state, mode="gimme_group_element") + legal, state = self._group.legal(state, mode='gimme_group_element') if not legal: raise ValueError("not a legal cube") self._state = state @@ -1337,11 +1337,11 @@ def cubie(self, size, gap, x, y, z, colors, stickers=True): INPUT: - - ``size`` -- The size of the cubie - - ``gap`` -- The gap between cubies - - ``x``, ``y``, ``z`` -- The position of the cubie - - ``colors`` -- The list of colors - - ``stickers`` -- (Default ``True``) Boolean to display stickers + - ``size`` -- the size of the cubie + - ``gap`` -- the gap between cubies + - ``x``, ``y``, ``z`` -- the position of the cubie + - ``colors`` -- the list of colors + - ``stickers`` -- boolean (default: ``True``); whether to display stickers EXAMPLES:: @@ -1420,7 +1420,7 @@ def __richcmp__(self, other, op): return NotImplemented return richcmp(self._state, other._state, op) - def solve(self, algorithm="hybrid", timeout=15): + def solve(self, algorithm='hybrid', timeout=15): r""" Solve the Rubik's cube. @@ -1429,13 +1429,13 @@ def solve(self, algorithm="hybrid", timeout=15): - ``algorithm`` -- must be one of the following: - ``hybrid`` -- try ``kociemba`` for timeout seconds, then ``dietz`` - - ``kociemba`` -- Use Dik T. Winter's program + - ``kociemba`` -- use Dik T. Winter's program (reasonable speed, few moves) - - ``dietz`` -- Use Eric Dietz's cubex program + - ``dietz`` -- use Eric Dietz's cubex program (fast but lots of moves) - - ``optimal`` -- Use Michael Reid's optimal program + - ``optimal`` -- use Michael Reid's optimal program (may take a long time) - - ``gap`` -- Use GAP word solution (can be slow) + - ``gap`` -- use GAP word solution (can be slow) Any choice other than ``gap`` requires the optional package ``rubiks``. Otherwise, the ``gap`` algorithm is used. @@ -1487,7 +1487,7 @@ def solve(self, algorithm="hybrid", timeout=15): elif algorithm == "gap": solver = CubeGroup() - return solver.solve(self._state, algorithm="gap") + return solver.solve(self._state, algorithm='gap') else: raise ValueError(f"Unrecognized algorithm: {algorithm}") diff --git a/src/sage/groups/perm_gps/meson.build b/src/sage/groups/perm_gps/meson.build new file mode 100644 index 00000000000..e986fcd964a --- /dev/null +++ b/src/sage/groups/perm_gps/meson.build @@ -0,0 +1,28 @@ +py.install_sources( + 'all.py', + 'constructor.py', + 'cubegroup.py', + 'permgroup.py', + 'permgroup_element.pxd', + 'permgroup_morphism.py', + 'permgroup_named.py', + 'permutation_groups_catalog.py', + 'symgp_conjugacy_class.py', + subdir: 'sage/groups/perm_gps', +) + +extension_data = {'permgroup_element' : files('permgroup_element.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/groups/perm_gps', + install: true, + include_directories: [inc_cpython, inc_ext, inc_rings], + dependencies: [py_dep, cysignals, gap, gmp], + ) +endforeach + +subdir('partn_ref') +subdir('partn_ref2') diff --git a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx index 4547cc5863a..f8d9aaf2c1b 100644 --- a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +++ b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx @@ -193,7 +193,6 @@ def test_intersect_parabolic_with_alternating(int n=9, list partition=[[0,1,2],[ 2520 sage: tipwa(9, [[0,1,2,3],[4,5,6,7,8]]) 1440 - """ cdef aut_gp_and_can_lab *output cdef Integer I = Integer(0) @@ -264,7 +263,6 @@ def coset_rep(list perm=[0,1,2,3,4,5], list gens=[[1,2,3,4,5,0]]): ....: reps.append(r) sage: len(reps) 8 - """ cdef int i, n = len(perm) assert all(len(g) == n for g in gens) @@ -319,7 +317,7 @@ cdef aut_gp_and_can_lab *allocate_agcl_output(int n) noexcept: cdef void deallocate_agcl_output(aut_gp_and_can_lab *output) noexcept: r""" - Deallocates an aut_gp_and_can_lab struct. + Deallocate an aut_gp_and_can_lab struct. """ if output is not NULL: SC_dealloc(output.group) @@ -329,7 +327,7 @@ cdef void deallocate_agcl_output(aut_gp_and_can_lab *output) noexcept: cdef agcl_work_space *allocate_agcl_work_space(int n) noexcept: r""" - Allocates work space for the get_aut_gp_and_can_lab function. It can be + Allocate work space for the get_aut_gp_and_can_lab function. It can be input to the function in which case it must be deallocated after the function is called. """ @@ -412,35 +410,36 @@ cdef aut_gp_and_can_lab *get_aut_gp_and_can_lab(void *S, Traverse the search space for subgroup/canonical label calculation. INPUT: - S -- pointer to the structure - partition -- PartitionStack representing a partition of the points - len_partition -- length of the partition - n -- the number of points (points are assumed to be 0,1,...,n-1) - canonical_label -- whether to search for canonical label; if True, return + + - ``S`` -- pointer to the structure + - ``partition`` -- PartitionStack representing a partition of the points + - ``len_partition`` -- length of the partition + - ``n`` -- the number of points (points are assumed to be 0,1,...,n-1) + - ``canonical_label`` -- whether to search for canonical label; if True, return the permutation taking S to its canonical label - all_children_are_equivalent -- pointer to a function + - ``all_children_are_equivalent`` -- pointer to a function INPUT: - PS -- pointer to a partition stack - S -- pointer to the structure + - ``PS`` -- pointer to a partition stack + - ``S`` -- pointer to the structure OUTPUT: - bint -- returns True if it can be determined that all refinements below - the current one will result in an equivalent discrete partition - refine_and_return_invariant -- pointer to a function + bint; returns ``True`` if it can be determined that all refinements below + the current one will result in an equivalent discrete partition + - ``refine_and_return_invariant`` -- pointer to a function INPUT: - PS -- pointer to a partition stack - S -- pointer to the structure - alpha -- an array consisting of numbers, which indicate the starting - positions of the cells to refine against (will likely be modified) + - ``PS`` -- pointer to a partition stack + - ``S`` -- pointer to the structure + - ``alpha`` -- an array consisting of numbers, which indicate the starting + positions of the cells to refine against (will likely be modified) OUTPUT: - int -- returns an invariant under application of arbitrary permutations - compare_structures -- pointer to a function + integer; returns an invariant under application of arbitrary permutations + - ``compare_structures`` -- pointer to a function INPUT: - gamma_1, gamma_2 -- (list) permutations of the points of S1 and S2 - S1, S2 -- pointers to the structures - degree -- degree of gamma_1 and 2 + - ``gamma_1``, ``gamma_2`` -- (list) permutations of the points of S1 and S2 + - ``S1``, ``S2`` -- pointers to the structures + - ``degree`` -- degree of gamma_1 and 2 OUTPUT: - int -- 0 if gamma_1(S1) = gamma_2(S2), otherwise -1 or 1 (see docs for cmp), - such that the set of all structures is well-ordered + integer; 0 if gamma_1(S1) = gamma_2(S2), otherwise -1 or 1 (see docs for cmp), + such that the set of all structures is well-ordered .. NOTE:: @@ -448,7 +447,6 @@ cdef aut_gp_and_can_lab *get_aut_gp_and_can_lab(void *S, cell, the smallest element occurs first! OUTPUT: a pointer to a ``aut_gp_and_can_lab`` struct - """ cdef PartitionStack *current_ps cdef PartitionStack *first_ps diff --git a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx index 3898e611707..2775842c09d 100644 --- a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +++ b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx @@ -400,74 +400,63 @@ cdef iterator *setup_canonical_generator(int degree, - ``all_children_are_equivalent`` -- pointer to a function INPUT: - PS -- pointer to a partition stack - S -- pointer to the structure + - ``PS`` -- pointer to a partition stack + - ``S`` -- pointer to the structure OUTPUT: - bint -- returns True if it can be determined that all refinements below - the current one will result in an equivalent discrete partition - + bint; returns ``True`` if it can be determined that all refinements below + the current one will result in an equivalent discrete partition - ``refine_and_return_invariant`` -- pointer to a function INPUT: - PS -- pointer to a partition stack - S -- pointer to the structure - alpha -- an array consisting of numbers, which indicate the starting - positions of the cells to refine against (will likely be modified) + - ``PS`` -- pointer to a partition stack + - ``S`` -- pointer to the structure + - ``alpha`` -- an array consisting of numbers, which indicate the starting + positions of the cells to refine against (will likely be modified) OUTPUT: - int -- returns an invariant under application of arbitrary permutations - + integer; returns an invariant under application of arbitrary permutations - ``compare_structures`` -- pointer to a function INPUT: - gamma_1, gamma_2 -- (list) permutations of the points of S1 and S2 - S1, S2 -- pointers to the structures - degree -- degree of gamma_1 and 2 + - ``gamma_1``, ``gamma_2`` -- (list) permutations of the points of S1 and S2 + - ``S1``, ``S2`` -- pointers to the structures + - ``degree`` -- degree of gamma_1 and 2 OUTPUT: - int -- 0 if gamma_1(S1) = gamma_2(S2), otherwise -1 or 1 (see docs for cmp), - such that the set of all structures is well-ordered - + integer; 0 if gamma_1(S1) = gamma_2(S2), otherwise -1 or 1 (see docs for cmp), + such that the set of all structures is well-ordered - ``generate_children`` -- pointer to a function INPUT: - S -- pointer to the structure - group -- pointer to an automorphism group (canonical relabeling is not guaranteed) - it -- preallocated iterator struct + - ``S`` -- pointer to the structure + - ``group`` -- pointer to an automorphism group (canonical relabeling is not guaranteed) + - ``it`` -- preallocated iterator struct OUTPUT: - iterator * -- pointer to an iterator over inequivalent augmentations of S - + iterator *; pointer to an iterator over inequivalent augmentations of S - ``apply_augmentation`` -- pointer to a function INPUT: - parent -- object to augment - aug -- the augmentation - child -- space to put the augmented object - degree -- pointer to an int, function should store the degree of the augmented object here - mem_err -- pointer where memory error can be reported - OUTPUT: - pointer to child - + - ``parent`` -- object to augment + - ``aug`` -- the augmentation + - ``child`` -- space to put the augmented object + - ``degree`` -- pointer to an int, function should store the degree of the augmented object here + - ``mem_err`` -- pointer where memory error can be reported + OUTPUT: pointer to child - ``free_object`` -- pointer to a function INPUT: - child -- object to be freed - + - ``child`` -- object to be freed - ``free_iter_data`` -- pointer to a function INPUT: - data -- data part of an iterator struct - + - ``data`` -- data part of an iterator struct - ``free_aug`` -- pointer to a function INPUT: - aug -- augmentation to be freed - + - ``aug`` -- augmentation to be freed - ``canonical_parent`` -- pointer to a function INPUT: - child -- pointer to the structure - parent -- space to store the canonical parent - permutation -- array representing a relabeling of the child - degree -- pointer to store the degree of the parent - mem_err -- pointer for indicating memory errors - OUTPUT: - pointer to the parent + - ``child`` -- pointer to the structure + - ``parent`` -- space to store the canonical parent + - ``permutation`` -- array representing a relabeling of the child + - ``degree`` -- pointer to store the degree of the parent + - ``mem_err`` -- pointer for indicating memory errors + OUTPUT: pointer to the parent - ``max_depth`` -- maximum depth of augmentations to be made from the seed object S OUTPUT: a pointer to an iterator of objects - """ if max_depth <= 1: raise ValueError("maximum depth (%d) must be at least two" % max_depth) diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pxd b/src/sage/groups/perm_gps/partn_ref/data_structures.pxd index a71fa3cadd8..1cbb95231d5 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pxd +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pxd @@ -14,6 +14,8 @@ from libc.string cimport memcpy from libc.stdlib cimport rand from sage.libs.gmp.mpz cimport * +from cysignals.memory cimport sig_free + cdef enum: # The following is for the automorphism group computation, says what the @@ -136,16 +138,51 @@ cdef inline void OP_join(OrbitPartition *OP, int m, int n) noexcept: if m_root != n_root: OP.num_cells -= 1 + +cdef inline void OP_make_set(OrbitPartition *OP) noexcept: + cdef int i, n = OP.degree + cdef int *new_parent, *new_rank, *new_mcr, *new_size + + cdef int *int_array = sig_malloc(4*(n+1) * sizeof(int)) + if int_array is NULL: + raise MemoryError("MemoryError allocating int_array in make_set method") + + OP.degree = n + 1 + OP.num_cells = OP.num_cells + 1 + new_parent = int_array + new_rank = int_array + (n + 1) + new_mcr = int_array + (2*n + 2) + new_size = int_array + (3 * n + 3) + + memcpy(new_parent, OP.parent, n * sizeof(int)) + memcpy(new_rank, OP.rank, n * sizeof(int)) + memcpy(new_mcr, OP.mcr, n * sizeof(int)) + memcpy(new_size, OP.size, n * sizeof(int)) + + new_parent[n] = n + new_rank[n] = 0 + new_mcr[n] = n + new_size[n] = 1 + + sig_free(OP.parent) + + OP.parent = new_parent + OP.rank = new_rank + OP.mcr = new_mcr + OP.size = new_size + cdef inline int OP_merge_list_perm(OrbitPartition *OP, int *gamma) noexcept: """ Joins the cells of OP which intersect the same orbit of gamma. INPUT: - gamma - an integer array representing i -> gamma[i]. + + - ``gamma`` - an integer array representing ``i -> gamma[i]``. OUTPUT: - 1 - something changed - 0 - orbits of gamma all contained in cells of OP + + - 1 -- something changed + - 0 -- orbits of gamma all contained in cells of OP """ cdef int i, i_root, gamma_i_root, changed = 0 for i from 0 <= i < OP.degree: @@ -218,7 +255,7 @@ cdef inline bint PS_is_fixed(PartitionStack *PS, int m) noexcept: cdef inline int PS_clear(PartitionStack *PS) noexcept: """ - Sets the current partition to the first shallower one, i.e. forgets about + Set the current partition to the first shallower one, i.e. forgets about boundaries between cells that are new to the current level. """ cdef int i, cur_start = 0 @@ -242,7 +279,7 @@ cdef inline int PS_move_all_mins_to_front(PartitionStack *PS) noexcept: cdef inline int PS_get_perm_from(PartitionStack *PS1, PartitionStack *PS2, int *gamma) noexcept: """ Store the permutation determined by PS2[i] -> PS1[i] for each i, where PS[i] - denotes the entry of the ith cell of the discrete partition PS. + denotes the entry of the `i`-th cell of the discrete partition PS. """ cdef int i for i from 0 <= i < PS1.degree: @@ -319,14 +356,13 @@ cdef inline int split_point_and_refine(PartitionStack *PS, int v, void *S, the refinement function. INPUT: - PS -- the partition stack to refine - v -- the point to split - S -- the structure - refine_and_return_invariant -- the refinement function provided - cells_to_refine_by -- an array, contents ignored - group -- the containing group, NULL for full S_n - perm_stack -- represents a partial traversal decomposition for group - + - ``PS`` -- the partition stack to refine + - ``v`` -- the point to split + - ``S`` -- the structure + - ``refine_and_return_invariant`` -- the refinement function provided + - ``cells_to_refine_by`` -- an array, contents ignored + - ``group`` -- the containing group, NULL for full S_n + - ``perm_stack`` -- represents a partial traversal decomposition for group """ PS.depth += 1 PS_clear(PS) @@ -384,7 +420,7 @@ cdef inline void SC_identify(int *perm, int degree) noexcept: cdef inline void SC_add_base_point(StabilizerChain *SC, int b) noexcept: """ - Adds base point b to the end of SC. Assumes b is not already in the base. + Add base point b to the end of SC. Assumes b is not already in the base. """ cdef int i, n = SC.degree SC.orbit_sizes[SC.base_size] = 1 @@ -480,8 +516,8 @@ cdef inline int SC_update_tree(StabilizerChain *SC, int level, int *pi, int num_ cdef inline void SC_order(StabilizerChain *SC, int i, mpz_t order) noexcept: """ - Gives the order of the stabilizer of base points up to but not including the - i-th, storing it to ``order``, which must be already initialized. + Give the order of the stabilizer of base points up to but not including the + `i`-th, storing it to ``order``, which must be already initialized. To get the order of the full group, let ``i = 0``. """ @@ -515,7 +551,7 @@ cdef inline bint SC_contains(StabilizerChain *SC, int level, int *pi, bint modif cdef inline void SC_random_element(StabilizerChain *SC, int level, int *perm) noexcept: """ - Gives a random element of the level-th stabilizer. For a random element of the + Give a random element of the level-th stabilizer. For a random element of the whole group, set level to 0. Must have level < SC.base_size. """ cdef int i, x, n = SC.degree @@ -532,7 +568,7 @@ cdef inline void update_perm_stack(StabilizerChain *group, int level, int point, int *perm_stack) noexcept: """ Ensure that perm_stack[level] is gamma_0^{-1}...gamma_{level-1}^{-1}, where - each gamma_i represents the coset representative at the ith level determined + each gamma_i represents the coset representative at the `i`-th level determined by our current position in the search tree. For internal use within the automorphism group, canonical label and double diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx index b707727c2c9..28672d00038 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx @@ -121,7 +121,6 @@ def OP_represent(int n, merges, perm): 8 -> 8, root: size=1, mcr=8, rank=0 Deallocating OrbitPartition. Done. - """ cdef int i print("Allocating OrbitPartition...") @@ -455,7 +454,6 @@ def PS_represent(partition, splits): 0100000000 Deallocating PartitionStacks. Done. - """ cdef int i, n = sum([len(cell) for cell in partition]) cdef int *gamma @@ -779,7 +777,7 @@ cdef int SC_realloc_bitsets(StabilizerChain *SC, unsigned long size) noexcept: cdef StabilizerChain *SC_copy(StabilizerChain *SC, int level) noexcept: """ - Creates a copy of the first `level` levels of SC. Must have 0 < level. + Create a copy of the first `level` levels of SC. Must have 0 < level. Return a null pointer in case of allocation failure. """ @@ -1354,7 +1352,6 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, ....: test_stab_chain_fns_7(n, 0, 1, 1) sage: test_stab_chain_fns_7(20, 1, 1, 1) sage: test_stab_chain_fns_7(20, 0, 1, 1) - """ if gap: from sage.groups.perm_gps.permgroup import PermutationGroup @@ -1623,11 +1620,10 @@ cdef int sort_by_function(PartitionStack *PS, int start, int *degrees) noexcept: INPUT: - - PS -- the partition stack to be checked - - start -- beginning index of the cell to be sorted - - degrees -- the values to be sorted by, must have extra scratch space for a + - ``PS`` -- the partition stack to be checked + - ``start`` -- beginning index of the cell to be sorted + - ``degrees`` -- the values to be sorted by, must have extra scratch space for a total of `3*n+1` - """ cdef int n = PS.degree cdef int i, j, max, max_location diff --git a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx index 10430b64355..d4cedec1f3c 100644 --- a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx +++ b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx @@ -168,7 +168,6 @@ def coset_eq(list perm1=[0,1,2,3,4,5], list perm2=[1,2,3,4,5,0], list gens=[[1,2 ....: reps.append(p) sage: len(reps) 8 - """ cdef int i, n = len(perm1) assert all(len(g) == n for g in gens+[perm2]) @@ -202,7 +201,7 @@ def coset_eq(list perm1=[0,1,2,3,4,5], list perm2=[1,2,3,4,5,0], list gens=[[1,2 cdef dc_work_space *allocate_dc_work_space(int n) noexcept: r""" - Allocates work space for the double_coset function. It can be + Allocate work space for the double_coset function. It can be input to the function in which case it must be deallocated after the function is called. """ @@ -252,7 +251,7 @@ cdef dc_work_space *allocate_dc_work_space(int n) noexcept: cdef void deallocate_dc_work_space(dc_work_space *work_space) noexcept: r""" - Deallocates work space for the double_coset function. + Deallocate work space for the double_coset function. """ if work_space is NULL: return @@ -281,38 +280,38 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order Traverse the search space for double coset calculation. INPUT: - S1, S2 -- pointers to the structures - partition1 -- PartitionStack of depth 0 and degree n, - whose first partition is of the points of S1 - ordering2 -- an ordering of the points of S2 representing a second partition - n -- the number of points (points are assumed to be 0,1,...,n-1) - all_children_are_equivalent -- pointer to a function + - ``S1``, ``S2`` -- pointers to the structures + - ``partition1`` -- PartitionStack of depth 0 and degree n, + whose first partition is of the points of S1 + - ``ordering2`` -- an ordering of the points of S2 representing a second partition + - ``n`` -- the number of points (points are assumed to be 0,1,...,n-1) + - ``all_children_are_equivalent`` -- pointer to a function INPUT: - PS -- pointer to a partition stack - S -- pointer to the structure + - ``PS`` -- pointer to a partition stack + - ``S`` -- pointer to the structure OUTPUT: - bint -- returns True if it can be determined that all refinements below - the current one will result in an equivalent discrete partition - refine_and_return_invariant -- pointer to a function + bint; returns True if it can be determined that all refinements below + the current one will result in an equivalent discrete partition + - ``refine_and_return_invariant`` -- pointer to a function INPUT: - PS -- pointer to a partition stack - S -- pointer to the structure - alpha -- an array consisting of numbers, which indicate the starting - positions of the cells to refine against (will likely be modified) + - ``PS`` -- pointer to a partition stack + -n``S`` -- pointer to the structure + - ``alpha`` -- an array consisting of numbers, which indicate the starting + positions of the cells to refine against (will likely be modified) OUTPUT: - int -- returns an invariant under application of arbitrary permutations + integer; returns an invariant under application of arbitrary permutations compare_structures -- pointer to a function INPUT: - gamma_1, gamma_2 -- (list) permutations of the points of S1 and S2 - S1, S2 -- pointers to the structures - degree -- degree of gamma_1 and 2 + - ``gamma_1``, ``gamma_2`` -- (list) permutations of the points of S1 and S2 + - ``S1``, ``S2`` -- pointers to the structures + - ``degree`` -- degree of gamma_1 and 2 OUTPUT: - int -- 0 if gamma_1(S1) = gamma_2(S2), otherwise -1 or 1 (see docs for cmp), - such that the set of all structures is well-ordered - input_group -- either a specified group to limit the search to, - or NULL for the full symmetric group - isom -- space to store the isomorphism to, - or NULL if isomorphism is not needed + integer; 0 if gamma_1(S1) = gamma_2(S2), otherwise -1 or 1 (see docs for cmp), + such that the set of all structures is well-ordered + - ``input_group`` -- either a specified group to limit the search to, + or NULL for the full symmetric group + - ``isom`` -- space to store the isomorphism to, + or NULL if isomorphism is not needed .. NOTE:: diff --git a/src/sage/groups/perm_gps/partn_ref/meson.build b/src/sage/groups/perm_gps/partn_ref/meson.build new file mode 100644 index 00000000000..092b0d0b2c8 --- /dev/null +++ b/src/sage/groups/perm_gps/partn_ref/meson.build @@ -0,0 +1,41 @@ +py.install_sources( + 'all.py', + 'automorphism_group_canonical_label.pxd', + 'canonical_augmentation.pxd', + 'data_structures.pxd', + 'double_coset.pxd', + 'refinement_binary.pxd', + 'refinement_graphs.pxd', + 'refinement_lists.pxd', + 'refinement_matrices.pxd', + 'refinement_python.pxd', + 'refinement_sets.pxd', + subdir: 'sage/groups/perm_gps/partn_ref', +) + +extension_data = { + 'automorphism_group_canonical_label' : files( + 'automorphism_group_canonical_label.pyx', + ), + 'canonical_augmentation' : files('canonical_augmentation.pyx'), + 'data_structures' : files('data_structures.pyx'), + 'double_coset' : files('double_coset.pyx'), + 'refinement_binary' : files('refinement_binary.pyx'), + 'refinement_graphs' : files('refinement_graphs.pyx'), + 'refinement_lists' : files('refinement_lists.pyx'), + 'refinement_matrices' : files('refinement_matrices.pyx'), + 'refinement_python' : files('refinement_python.pyx'), + 'refinement_sets' : files('refinement_sets.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/groups/perm_gps/partn_ref', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index 9f44aaec67b..1b8ace1cae0 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -479,8 +479,8 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): INPUT: - - ``partition`` -- an optional list of lists partition of the columns. - default is the unit partition. + - ``partition`` -- an optional list of lists partition of the columns + default is the unit partition EXAMPLES:: @@ -631,18 +631,17 @@ cdef int refine_by_bip_degree(PartitionStack *col_ps, void *S, int *cells_to_ref INPUT: - - col_ps -- a partition stack, whose finest partition is the partition to be refined - - S -- a binary code struct object - - cells_to_refine_by -- a list of pointers to cells to check degrees against + - ``col_ps`` -- a partition stack, whose finest partition is the partition to be refined + - ``S`` -- a binary code struct object + - ``cells_to_refine_by`` -- list of pointers to cells to check degrees against in refining the other cells (updated in place) - - ctrb_len -- how many cells in cells_to_refine_by + - ``ctrb_len`` -- how many cells in cells_to_refine_by OUTPUT: An integer $I$ invariant under the orbits of $S_n$. That is, if $\gamma$ is a permutation of the columns, then $$ I(G, PS, cells_to_refine_by) = I( \gamma(G), \gamma(PS), \gamma(cells_to_refine_by) ) .$$ - """ cdef BinaryCodeStruct BCS = S cdef int current_cell_against = 0 @@ -961,11 +960,11 @@ cdef inline int word_degree(PartitionStack *word_ps, BinaryCodeStruct BCS, int e INPUT: - - word_ps -- the partition stack to be checked - - col_ps -- corresponding partition stack on columns - - BCS -- a binary code struct object - - entry -- the position of the vertex in question in the entries of word_ps - - cell_index -- the starting position of the cell in question in the entries of PS + - ``word_ps`` -- the partition stack to be checked + - ``col_ps`` -- corresponding partition stack on columns + - ``BCS`` -- a binary code struct object + - ``entry`` -- the position of the vertex in question in the entries of word_ps + - ``cell_index`` -- the starting position of the cell in question in the entries of PS """ cdef bitset_t cell, word cdef int h @@ -991,11 +990,11 @@ cdef inline int col_degree(PartitionStack *col_ps, BinaryCodeStruct BCS, int ent INPUT: - - col_ps -- the partition stack to be checked - - word_ps -- corresponding partition stack on words - - BCS -- a binary code struct object - - entry -- the position of the vertex in question in the entries of word_ps - - cell_index -- the starting position of the cell in question in the entries of PS + - ``col_ps`` -- the partition stack to be checked + - ``word_ps`` -- corresponding partition stack on words + - ``BCS`` -- a binary code struct object + - ``entry`` -- the position of the vertex in question in the entries of word_ps + - ``cell_index`` -- the starting position of the cell in question in the entries of PS """ cdef bitset_t word bitset_init(word, BCS.degree) @@ -1016,9 +1015,9 @@ cdef inline int sort_by_function_codes(PartitionStack *PS, int start, int *degre INPUT: - - PS -- the partition stack to be checked - - start -- beginning index of the cell to be sorted - - degrees -- the values to be sorted by + - ``PS`` -- the partition stack to be checked + - ``start`` -- beginning index of the cell to be sorted + - ``degrees`` -- the values to be sorted by - count, count_max, output -- scratch space """ cdef int i, j, max, max_location diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx index 34c911c51bf..1258ea280ab 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx @@ -186,18 +186,18 @@ def search_tree(G_in, partition, lab=True, dig=False, dict_rep=False, certificat INPUT: - ``G_in`` -- a Sage graph - - ``partition`` -- a list of lists representing a partition of the vertices - - ``lab`` -- if True, compute and return the canonical label in addition to the + - ``partition`` -- list of lists representing a partition of the vertices + - ``lab`` -- if ``True``, compute and return the canonical label in addition to the automorphism group - - ``dig`` -- set to True for digraphs and graphs with loops. If True, does not + - ``dig`` -- set to ``True`` for digraphs and graphs with loops; if ``True``, does not use optimizations based on Lemma 2.25 in [1] that are valid only for - simple graphs. + simple graphs - ``dict_rep`` -- if ``True``, return a dictionary with keys the vertices of the input graph G_in and values elements of the set the permutation group acts on. (The point is that graphs are arbitrarily labelled, often 0..n-1, and permutation groups always act on 1..n. This dictionary maps vertex labels (such as 0..n-1) to the domain of the permutations.) - - ``certificate`` -- if ``True``, return the permutation from G to its canonical label. + - ``certificate`` -- if ``True``, return the permutation from G to its canonical label - ``verbosity`` -- currently ignored - ``use_indicator_function`` -- option to turn off indicator function (``True`` is generally faster) @@ -518,7 +518,7 @@ cdef int refine_by_degree(PartitionStack *PS, void *S, int *cells_to_refine_by, refined - ``S`` -- a graph struct object, which contains scratch space, the graph in question, and some flags - - ``cells_to_refine_by`` -- a list of pointers to cells to check degrees against + - ``cells_to_refine_by`` -- list of pointers to cells to check degrees against in refining the other cells (updated in place). Must be allocated to length at least the degree of PS, since the array may grow - ``ctrb_len`` -- how many cells in cells_to_refine_by @@ -779,7 +779,6 @@ def all_labeled_graphs(n): 3 4 4 11 5 34 - """ from sage.graphs.graph import Graph TE = [] @@ -801,7 +800,7 @@ def all_labeled_graphs(n): def random_tests(num=10, n_max=60, perms_per_graph=5): """ - Tests to make sure that C(gamma(G)) == C(G) for random permutations gamma + Test to make sure that C(gamma(G)) == C(G) for random permutations gamma and random graphs G, and that isomorphic returns an isomorphism. INPUT: @@ -1300,7 +1299,6 @@ def generate_dense_graphs_edge_addition(int n, bint loops, G=None, depth=None, 1044 sage: generate_dense_graphs_edge_addition(8,0) # long time (about 14 seconds at 2.4 GHz) 12346 - """ from sage.graphs.graph import Graph cdef iterator *graph_iterator @@ -1573,7 +1571,6 @@ def generate_dense_graphs_vert_addition(int n, base_G=None, sage: from sage.groups.perm_gps.partn_ref.refinement_graphs import generate_dense_graphs_vert_addition sage: generate_dense_graphs_vert_addition(10, base_G=Graph('HEhf^rs')) 11 - """ from sage.graphs.graph import Graph cdef iterator *graph_iterator diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx index 8946d7211c2..e15683bdd77 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx @@ -26,14 +26,13 @@ from sage.groups.perm_gps.partn_ref.double_coset cimport double_coset, int_cmp def is_isomorphic(self, other): r""" Return the bijection as a permutation if two lists are isomorphic, return - False otherwise. + ``False`` otherwise. EXAMPLES:: sage: from sage.groups.perm_gps.partn_ref.refinement_lists import is_isomorphic sage: is_isomorphic([0,0,1],[1,0,0]) [1, 2, 0] - """ cdef int i, n = len(self) cdef PartitionStack *part diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx index 6a9d97be641..57bf05e2e6d 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx @@ -130,7 +130,7 @@ cdef class MatrixStruct: INPUT: - ``partition`` -- an optional list of lists partition of the columns; - default is the unit partition. + default is the unit partition EXAMPLES:: @@ -303,11 +303,11 @@ def random_tests(n=10, nrows_max=50, ncols_max=50, nsymbols_max=10, perms_per_ma INPUT: - - n -- run tests on this many matrices - - nrows_max -- test matrices with at most this many rows - - ncols_max -- test matrices with at most this many columns - - perms_per_matrix -- test each matrix with this many random permutations - - nsymbols_max -- maximum number of distinct symbols in the matrix + - ``n`` -- run tests on this many matrices + - ``nrows_max`` -- test matrices with at most this many rows + - ``ncols_max`` -- test matrices with at most this many columns + - ``perms_per_matrix`` -- test each matrix with this many random permutations + - ``nsymbols_max`` -- maximum number of distinct symbols in the matrix This code generates n random matrices M on at most ncols_max columns and at most nrows_max rows. The density of entries in the basis is chosen randomly diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx index 9408c620367..0623c237b76 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx @@ -204,7 +204,7 @@ cdef class PythonPartitionStack: def set_entry(self, int i, int entry): """ - Set the ith entry of the entries array to entry. + Set the `i`-th entry of the entries array to entry. EXAMPLES:: @@ -219,7 +219,7 @@ cdef class PythonPartitionStack: def get_entry(self, int i): """ - Get the ith entry of the entries array. + Get the `i`-th entry of the entries array. EXAMPLES:: @@ -247,7 +247,7 @@ cdef class PythonPartitionStack: def set_level(self, int i, int level): """ - Set the ith entry of the levels array to entry. + Set the `i`-th entry of the levels array to entry. EXAMPLES:: @@ -264,7 +264,7 @@ cdef class PythonPartitionStack: def get_level(self, int i): """ - Get the ith entry of the levels array. + Get the `i`-th entry of the levels array. EXAMPLES:: @@ -450,7 +450,6 @@ def aut_gp_and_can_lab_python(S, partition, n, 48) sage: factorial(4)*factorial(2) 48 - """ obj_wrapper = PythonObjectWrapper(S, all_children_are_equivalent, refine_and_return_invariant, compare_structures, n) cdef aut_gp_and_can_lab *output @@ -492,7 +491,7 @@ def double_coset_python(S1, S2, partition1, ordering2, n, refine_and_return_invariant, compare_structures): """ - Calls the double coset function. + Call the double coset function. INPUT: @@ -533,7 +532,6 @@ def double_coset_python(S1, S2, partition1, ordering2, n, sage: double_coset_python([0,0,1], [1,0,0], [[0,1,2]], [0,1,2], 3, acae, rari, compare_lists) [1, 2, 0] - """ obj_wrapper1 = PythonObjectWrapper(S1, all_children_are_equivalent, refine_and_return_invariant, compare_structures, n) obj_wrapper2 = PythonObjectWrapper(S2, all_children_are_equivalent, refine_and_return_invariant, compare_structures, n) diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx index ea55086d204..669e149ff09 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx @@ -135,7 +135,6 @@ def set_stab_py(generators, sett, relab=False): ([], [7, 8, 6, 3, 4, 5, 2, 0, 1]) sage: set_stab_py([[0,2,1,4,3,5,8,7,6],[8,7,6,3,5,4,2,1,0]], [0,3,5,6,8], True) ([], [2, 1, 0, 5, 4, 3, 7, 6, 8]) - """ if len(generators) == 0: return [] @@ -696,11 +695,11 @@ def sets_modulo_perm_group(list generators, int max_size, INPUT: - - ``generators`` -- (list of lists) list of generators in list form - - ``max_size`` -- (int) maximum size of subsets to be generated - - ``indicate_mem_err`` -- (bool) whether to raise an error - if we run out of memory, or simply append a :class:`MemoryError` - instance to the end of the output + - ``generators`` -- list of generators in list form + - ``max_size`` -- integer; maximum size of subsets to be generated + - ``indicate_mem_err`` -- boolean; whether to raise an error. + If we run out of memory, or simply append a :exc:`MemoryError` + instance to the end of the output. EXAMPLES:: diff --git a/src/sage/groups/perm_gps/partn_ref2/meson.build b/src/sage/groups/perm_gps/partn_ref2/meson.build new file mode 100644 index 00000000000..ca6fadbfda9 --- /dev/null +++ b/src/sage/groups/perm_gps/partn_ref2/meson.build @@ -0,0 +1,19 @@ +py.install_sources( + 'all.py', + 'refinement_generic.pxd', + subdir: 'sage/groups/perm_gps/partn_ref2', +) + +extension_data = {'refinement_generic' : files('refinement_generic.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/groups/perm_gps/partn_ref2', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_partn_ref2], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx b/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx index 668e8d55af5..af1960e4632 100644 --- a/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx +++ b/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx @@ -282,7 +282,7 @@ cdef class _BestValStore: cdef long * get_row(self, int i) noexcept: r""" - Return the i-th row. + Return the `i`-th row. If this row is not yet initialized (i >= self.storage_length), then we extend the array and fill the new positions @@ -494,15 +494,15 @@ cdef class PartitionRefinement_generic: ##################################################################### cdef bint _inner_min_(self, int pos, bint * inner_group_changed) noexcept: """ - Minimize the node by the action of the inner group on the ith position. + Minimize the node by the action of the inner group on the `i`-th position. INPUT: - - ``pos`` -- A position in ``range(self.n)`` + - ``pos`` -- a position in ``range(self.n)`` - ``inner_group_changed`` -- will be set to ``True`` if `G_y` got smaller OUTPUT: ``True`` if and only if the actual node compares less or equal - to the candidate for the canonical form. + to the candidate for the canonical form """ raise NotImplementedError @@ -825,12 +825,12 @@ cdef class PartitionRefinement_generic: There are to possibilities depending on the flag ``self._is_candidate_initialized``: - - ``True``: There is another leaf equal to this node. This defines an automorphism - which we add to the group of known automorphisms stored in - ``self._known_automorphisms``. - - ``False``: We have shown, that the current leaf is smaller than all - other leaf nodes already visited. We set it to be the - candidate for the canonical form. + - ``True`` -- There is another leaf equal to this node. This defines an automorphism + which we add to the group of known automorphisms stored in + ``self._known_automorphisms``. + - ``False`` -- We have shown, that the current leaf is smaller than all + other leaf nodes already visited. We set it to be the + candidate for the canonical form. """ from sage.libs.gap.libgap import libgap cdef int i @@ -865,7 +865,7 @@ cdef class PartitionRefinement_generic: # BACKTRACK_WITHLATEX_DEBUG = 1 in the setup.py script when # building this module! ########################################################################### - cdef void _latex_act_node(self, str comment="", int printlvl=0) noexcept: + cdef void _latex_act_node(self, str comment='', int printlvl=0) noexcept: r""" Append the actual node as a string of latex-commands to ``self._latex_debug_string``. diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 2d265216519..1d3b0bab92c 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -165,7 +165,7 @@ def load_hap(): sage: sage.groups.perm_gps.permgroup.load_hap() # optional - gap_package_hap """ from sage.features.gap import GapPackage - GapPackage("hap", spkg="gap_packages").require() + GapPackage("hap", spkg='gap_packages').require() libgap.load_package("hap") @@ -205,7 +205,7 @@ def wrapped(self, n, p=0): def direct_product_permgroups(P): """ - Takes the direct product of the permutation groups listed in ``P``. + Take the direct product of the permutation groups listed in ``P``. EXAMPLES:: @@ -269,12 +269,12 @@ def PermutationGroup(gens=None, *args, **kwds): INPUT: - - ``gens`` -- (default: ``None``) list of generators + - ``gens`` -- (default: ``None``) list of generators - - ``gap_group`` -- (optional) a gap permutation group + - ``gap_group`` -- (optional) a gap permutation group - - ``canonicalize`` -- boolean (default: ``True``); if ``True``, - sort generators and remove duplicates + - ``canonicalize`` -- boolean (default: ``True``); if ``True``, + sort generators and remove duplicates OUTPUT: a permutation group @@ -387,7 +387,6 @@ def PermutationGroup(gens=None, *args, **kwds): ... DeprecationWarning: gap_group, domain, canonicalize, category will become keyword only See https://github.com/sagemath/sage/issues/31510 for details. - """ if not isinstance(gens, ExpectElement) and hasattr(gens, '_permgroup_'): return gens._permgroup_() @@ -451,7 +450,7 @@ def __init__(self, gens=None, gap_group=None, canonicalize=True, - ``gap_group`` -- a gap or libgap permutation group, or a string defining one (default: ``None``) - - ``canonicalize`` -- bool (default: ``True``); if ``True``, + - ``canonicalize`` -- boolean (default: ``True``); if ``True``, sort generators and remove duplicates OUTPUT: a permutation group @@ -618,7 +617,7 @@ def construction(self): @cached_method def _has_natural_domain(self): """ - Return whether the underlying domain is of the form (1,...,n) + Return whether the underlying domain is of the form (1,...,n). EXAMPLES:: @@ -1164,7 +1163,7 @@ def __iter__(self): return self._iteration_monogen() else: # TODO: this is too slow for moderatly small permutation groups - return self.iteration(algorithm="SGS") + return self.iteration(algorithm='SGS') def _iteration_monogen(self): r""" @@ -1188,24 +1187,24 @@ def _iteration_monogen(self): h *= g yield h - def iteration(self, algorithm="SGS"): + def iteration(self, algorithm='SGS'): """ Return an iterator over the elements of this group. INPUT: - - ``algorithm`` -- (default: ``"SGS"``) either + - ``algorithm`` -- (default: ``'SGS'``) either - * ``"SGS"`` -- using strong generating system - * ``"BFS"`` -- a breadth first search on the Cayley graph with + * ``'SGS'`` -- using strong generating system + * ``'BFS'`` -- a breadth first search on the Cayley graph with respect to ``self.gens()`` - * ``"DFS"`` -- a depth first search on the Cayley graph with + * ``'DFS'`` -- a depth first search on the Cayley graph with respect to ``self.gens()`` .. NOTE:: - In general, the algorithm ``"SGS"`` is faster. Yet, for - small groups, ``"BFS"`` and ``"DFS"`` might be faster. + In general, the algorithm ``'SGS'`` is faster. Yet, for + small groups, ``'BFS'`` and ``'DFS'`` might be faster. .. NOTE:: @@ -1219,10 +1218,10 @@ def iteration(self, algorithm="SGS"): sage: list(G.iteration()) [(), (1,2,3), (1,3,2), (2,3), (1,2), (1,3)] - sage: list(G.iteration(algorithm="BFS")) + sage: list(G.iteration(algorithm='BFS')) [(), (2,3), (1,2), (1,2,3), (1,3,2), (1,3)] - sage: list(G.iteration(algorithm="DFS")) + sage: list(G.iteration(algorithm='DFS')) [(), (1,2), (1,3,2), (1,3), (1,2,3), (2,3)] TESTS:: @@ -1235,9 +1234,9 @@ def iteration(self, algorithm="SGS"): sage: sum(1 for x in A.iteration()) == 60000 True - sage: sum(1 for x in A.iteration(algorithm="BFS")) == 60000 + sage: sum(1 for x in A.iteration(algorithm='BFS')) == 60000 True - sage: sum(1 for x in A.iteration(algorithm="DFS")) == 60000 + sage: sum(1 for x in A.iteration(algorithm='DFS')) == 60000 True """ if algorithm == "SGS": @@ -1250,7 +1249,7 @@ def elements(SGS): for g in S: yield s._mul_(g) - SGS = self.strong_generating_system(implementation="gap") + SGS = self.strong_generating_system(implementation='gap') return elements(SGS) elif algorithm in ["BFS", "DFS"]: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet @@ -1447,7 +1446,7 @@ def one(self): def exponent(self): r""" - Computes the exponent of the group. + Compute the exponent of the group. The exponent `e` of a group `G` is the LCM of the orders of its elements, that is, `e` is the smallest integer such that `g^e=1` for all @@ -1581,6 +1580,96 @@ def smallest_moved_point(self): p = self._libgap_().SmallestMovedPoint() return self._domain_from_gap[Integer(p)] + @cached_method + def disjoint_direct_product_decomposition(self): + r""" + Return the finest partition of the underlying set such that ``self`` + is isomorphic to the direct product of the projections of ``self`` + onto each part of the partition. Each part is a union of orbits + of ``self``. + + The algorithm is from [CJ2022]_, which runs in time polynomial in + `n \cdot |X|`, where `n` is the degree of the group and `|X|` is + the size of a generating set, see Theorem 4.5. + + EXAMPLES: + + The example from the original paper:: + + sage: H = PermutationGroup([[(1,2,3),(7,9,8),(10,12,11)],[(4,5,6),(7,8,9),(10,11,12)],[(5,6),(8,9),(11,12)],[(7,8,9),(10,11,12)]]) + sage: S = H.disjoint_direct_product_decomposition(); S + {{1, 2, 3}, {4, 5, 6, 7, 8, 9, 10, 11, 12}} + sage: A = libgap.Stabilizer(H, list(S[0]), libgap.OnTuples); A + Group([ (7,8,9)(10,11,12), (5,6)(8,9)(11,12), (4,5,6)(7,8,9)(10,11,12) ]) + sage: B = libgap.Stabilizer(H, list(S[1]), libgap.OnTuples); B + Group([ (1,2,3) ]) + sage: T = PermutationGroup(gap_group=libgap.DirectProduct(A,B)) + sage: T.is_isomorphic(H) + True + sage: PermutationGroup(PermutationGroup(gap_group=A).gens(),domain=list(S[1])).disjoint_direct_product_decomposition() + {{4, 5, 6, 7, 8, 9, 10, 11, 12}} + sage: PermutationGroup(PermutationGroup(gap_group=B).gens(),domain=list(S[0])).disjoint_direct_product_decomposition() + {{1, 2, 3}} + + An example with a different domain:: + + sage: PermutationGroup([[('a','c','d'),('b','e')]]).disjoint_direct_product_decomposition() + {{'a', 'c', 'd'}, {'b', 'e'}} + sage: PermutationGroup([[('a','c','d','b','e')]]).disjoint_direct_product_decomposition() + {{'a', 'b', 'c', 'd', 'e'}} + + Counting the number of "connected" permutation groups of degree `n`:: + + sage: seq = [sum(1 for G in SymmetricGroup(n).conjugacy_classes_subgroups() if len(G.disjoint_direct_product_decomposition()) == 1) for n in range(1,8)]; seq + [1, 1, 2, 6, 6, 27, 20] + sage: oeis(seq) # optional -- internet + 0: A005226: Number of atomic species of degree n; also number of connected permutation groups of degree n. + """ + from sage.combinat.set_partition import SetPartition + from sage.sets.disjoint_set import DisjointSet + H = self._libgap_() + # sort each orbit and order list by smallest element of each orbit + O = libgap.List([libgap.ShallowCopy(orbit) for orbit in libgap.Orbits(H)]) + for orbit in O: + libgap.Sort(orbit) + O.Sort() + num_orbits = len(O) + OrbitMapping = dict() + for i in range(num_orbits): + for x in O[i]: + OrbitMapping[x] = i + C = libgap.StabChain(H, libgap.Concatenation(O)) + X = libgap.StrongGeneratorsStabChain(C) + P = DisjointSet(num_orbits) + R = libgap.List([]) + identity = libgap.Identity(H) + for i in range(num_orbits-1): + libgap.Append(R, O[i]) + Xp = libgap.List([]) + while True: + try: + if libgap.IsSubset(O[i], C['orbit']): + C = C['stabilizer'] + else: + break + except ValueError: + break + for x in X: + xs = libgap.SiftedPermutation(C, x) + if xs != identity: + libgap.Add(Xp, xs) + if libgap.RestrictedPerm(xs, O[i+1]) != identity: + cj = OrbitMapping[libgap.SmallestMovedPoint(libgap.RestrictedPerm(x, R))] + P.union(i+1, cj) + else: + libgap.Add(Xp, x) + X = Xp + return SetPartition([ + [self._domain_from_gap[Integer(x)] + for i in part + for x in O[i]] for part in P] + + [[x] for x in self.fixed_points()]) + def representative_action(self, x, y): r""" Return an element of ``self`` that maps `x` to `y` if it exists. @@ -1591,7 +1680,7 @@ def representative_action(self, x, y): INPUT: - - ``x``, ``y`` -- two elements of the domain. + - ``x``, ``y`` -- two elements of the domain EXAMPLES:: @@ -1651,27 +1740,27 @@ def orbits(self): for orbit in orbits.sage()) @cached_method - def orbit(self, point, action="OnPoints"): + def orbit(self, point, action='OnPoints'): """ Return the orbit of a point under a group action. INPUT: - ``point`` -- can be a point or any of the list above, depending on the - action to be considered. + action to be considered - - ``action`` -- string. if ``point`` is an element from the domain, a + - ``action`` -- string; if ``point`` is an element from the domain, a tuple of elements of the domain, a tuple of tuples [...], this - variable describes how the group is acting. + variable describes how the group is acting The actions currently available through this method are - ``"OnPoints"``, ``"OnTuples"``, ``"OnSets"``, ``"OnPairs"``, - ``"OnSetsSets"``, ``"OnSetsDisjointSets"``, - ``"OnSetsTuples"``, ``"OnTuplesSets"``, - ``"OnTuplesTuples"``. They are taken from GAP's list of + ``'OnPoints'``, ``'OnTuples'``, ``'OnSets'``, ``'OnPairs'``, + ``'OnSetsSets'``, ``'OnSetsDisjointSets'``, + ``'OnSetsTuples'``, ``'OnTuplesSets'``, + ``'OnTuplesTuples'``. They are taken from GAP's list of group actions, see ``gap.help('Group Actions')``. - It is set to ``"OnPoints"`` by default. See below for examples. + It is set to ``'OnPoints'`` by default. See below for examples. OUTPUT: @@ -1707,7 +1796,7 @@ def orbit(self, point, action="OnPoints"): Action of `S_4` on sets of disjoint sets:: sage: S4 = groups.permutation.Symmetric(4) - sage: O = S4.orbit(((1,2),(3,4)), action="OnSetsDisjointSets") + sage: O = S4.orbit(((1,2),(3,4)), action='OnSetsDisjointSets') sage: {1, 2} in O[0] and {3, 4} in O[0] True sage: {1, 4} in O[1] and {2, 3} in O[1] @@ -1807,7 +1896,7 @@ def transversals(self, point): self._domain_to_gap[i])) for i in self.orbit(point)] - def stabilizer(self, point, action="OnPoints"): + def stabilizer(self, point, action='OnPoints'): """ Return the subgroup of ``self`` which stabilize the given position. ``self`` and its stabilizers must have same degree. @@ -1815,9 +1904,9 @@ def stabilizer(self, point, action="OnPoints"): INPUT: - ``point`` -- a point of the :meth:`domain`, or a set of points - depending on the value of ``action``. + depending on the value of ``action`` - - ``action`` -- (string; default ``"OnPoints"``) should the group be + - ``action`` -- string (default: ``'OnPoints'``); should the group be considered to act on points (``action="OnPoints"``) or on sets of points (``action="OnSets"``)? In the latter case, the first argument must be a subset of :meth:`domain`. @@ -1909,7 +1998,7 @@ def base(self, seed=None): INPUT: - - ``seed`` (default: ``None``), if given must be a + - ``seed`` -- (default: ``None``) if given must be a subset of the domain of a base. When used, an attempt to create a base containing all or part of ``seed`` will be made. @@ -1947,7 +2036,7 @@ def base(self, seed=None): stab_chain = self._libgap_().StabChain(seed).BaseStabChain().sage() return [self._domain_from_gap[x] for x in stab_chain] - def strong_generating_system(self, base_of_group=None, implementation="sage"): + def strong_generating_system(self, base_of_group=None, implementation='sage'): r""" Return a Strong Generating System of ``self`` according the given base for the right action of ``self`` on itself. @@ -1974,21 +2063,21 @@ def strong_generating_system(self, base_of_group=None, implementation="sage"): a list containing the integers `1, 2, \ldots , d` in any order, where `d` is the degree of ``self`` - - ``implementation`` -- (default: ``"sage"``) either + - ``implementation`` -- (default: ``'sage'``) either - * ``"sage"`` -- use the direct implementation in Sage + * ``'sage'`` -- use the direct implementation in Sage - * ``"gap"`` -- if used, the ``base_of_group`` must be ``None`` + * ``'gap'`` -- if used, the ``base_of_group`` must be ``None`` and the computation is directly performed in GAP - OUTPUT: a list of lists of permutations from the group, which forms a + OUTPUT: list of lists of permutations from the group, which forms a strong generating system .. WARNING:: - The outputs for implementations ``"sage"`` and ``"gap"`` differ: + The outputs for implementations ``'sage'`` and ``'gap'`` differ: First, the output is reversed, and second, it might be that - ``"sage"`` does not contain the trivial subgroup while ``"gap"`` + ``'sage'`` does not contain the trivial subgroup while ``'gap'`` does. Also, both algorithms might yield different results based on the @@ -2034,7 +2123,7 @@ def strong_generating_system(self, base_of_group=None, implementation="sage"): sage: A = PermutationGroup([(1,2),(1,2,3,4,5,6,7,8,9)]) sage: X = A.strong_generating_system() - sage: Y = A.strong_generating_system(implementation="gap") + sage: Y = A.strong_generating_system(implementation='gap') sage: [len(x) for x in X] [9, 8, 7, 6, 5, 4, 3, 2, 1] sage: [len(y) for y in Y] @@ -2339,7 +2428,7 @@ def group_primitive_id(self): OUTPUT: A positive integer, following GAP's conventions. A - :class:`ValueError` is raised if the group is not primitive. + :exc:`ValueError` is raised if the group is not primitive. EXAMPLES:: @@ -2470,7 +2559,7 @@ def intersection(self, other): INPUT: - - ``other`` -- a permutation group. + - ``other`` -- a permutation group OUTPUT: @@ -2652,28 +2741,28 @@ def direct_product(self, other, maps=True): representation for the direct product. The direct product of permutation groups will be a permutation group again. For a direct product ``D``, the GAP operation ``Embedding(D,i)`` returns the - homomorphism embedding the i-th factor into ``D``. The GAP operation - ``Projection(D,i)`` gives the projection of ``D`` onto the i-th factor. + homomorphism embedding the `i`-th factor into ``D``. The GAP operation + ``Projection(D,i)`` gives the projection of ``D`` onto the `i`-th factor. This method returns a 5-tuple: a permutation group and 4 morphisms. INPUT: - - ``self``, ``other`` -- permutation groups + - ``self``, ``other`` -- permutation groups OUTPUT: - - ``D`` -- a direct product of the inputs, returned as - a permutation group as well + - ``D`` -- a direct product of the inputs, returned as + a permutation group as well - - ``iota1`` -- an embedding of ``self`` into ``D`` + - ``iota1`` -- an embedding of ``self`` into ``D`` - - ``iota2`` -- an embedding of ``other`` into ``D`` + - ``iota2`` -- an embedding of ``other`` into ``D`` - - ``pr1`` -- the projection of ``D`` onto ``self`` (giving a - splitting ``1 - other - D - self - 1``) + - ``pr1`` -- the projection of ``D`` onto ``self`` (giving a + splitting ``1 - other - D - self - 1``) - - ``pr2`` -- the projection of ``D`` onto ``other`` (giving a - splitting ``1 - self - D - other - 1``) + - ``pr2`` -- the projection of ``D`` onto ``other`` (giving a + splitting ``1 - self - D - other - 1``) EXAMPLES:: @@ -2727,16 +2816,16 @@ def semidirect_product(self, N, mapping, check=True): INPUT: - - ``N`` -- A group which is acted on by ``self`` and + - ``N`` -- a group which is acted on by ``self`` and naturally embeds as a normal subgroup of the returned semidirect - product. + product - - ``mapping`` -- A pair of lists that together define a + - ``mapping`` -- a pair of lists that together define a homomorphism, `\phi :` ``self`` `\rightarrow` Aut(``N``), by giving, in the second list, the images of the generators of ``self`` - in the order given in the first list. + in the order given in the first list - - ``check`` -- A boolean that, if set to ``False``, will skip the + - ``check`` -- a boolean that, if set to ``False``, will skip the initial tests which are made on ``mapping``. This may be beneficial for large ``N``, since in such cases the injectivity test can be expensive. Set to ``True`` by default. @@ -2768,7 +2857,6 @@ def semidirect_product(self, N, mapping, check=True): of the generators of ``self`` are placed on additional letters and adjoined to the output's generators of ``self``. - EXAMPLES: Perhaps the most common example of a semidirect product comes @@ -2886,20 +2974,21 @@ def semidirect_product(self, N, mapping, check=True): raise ValueError(msg) # create a parallel list of the automorphisms of N in GAP - libgap.eval('N := Group({})'.format(list(N.gens()))) - gens_string = ",".join(str(x) for x in N.gens()) - homomorphism_cmd = 'alpha := GroupHomomorphismByImages(N, N, [{0}],[{1}])' - libgap.eval('morphisms := []') + N_gap = libgap.eval(f'Group({list(N.gens())})') + morphisms = libgap.eval('[]') + libgap_gens = N_gap.GeneratorsOfGroup() for alpha in mapping[1]: - images_string = ",".join(str(alpha(n)) for n in N.gens()) - libgap.eval(homomorphism_cmd.format(gens_string, images_string)) - libgap.eval('Add(morphisms, alpha)') + images = [alpha(g) for g in N.gens()] + alpha_gap = N_gap.GroupHomomorphismByImages(N_gap, + libgap_gens, images) + morphisms.Add(alpha_gap) # create the necessary homomorphism from self into the # automorphism group of N in GAP - libgap.eval('H := Group({0})'.format(mapping[0])) - libgap.eval('phi := GroupHomomorphismByImages(H, AutomorphismGroup(N),{},morphisms)'.format(mapping[0])) - libgap.eval('sdp := SemidirectProduct(H, phi, N)') - return PermutationGroup(gap_group='sdp') + H = libgap.eval(f'Group({mapping[0]})') + phi = H.GroupHomomorphismByImages(N_gap.AutomorphismGroup(), + H.GeneratorsOfGroup(), morphisms) + sdp = H.SemidirectProduct(phi, N_gap) + return PermutationGroup(gap_group=sdp) def holomorph(self): r""" @@ -2959,11 +3048,11 @@ def holomorph(self): - Kevin Halasz (2012-08-14) """ - libgap.eval('G := Group({})'.format(list(self.gens()))) - libgap.eval('aut := AutomorphismGroup(G)') - libgap.eval('alpha := InverseGeneralMapping(NiceMonomorphism(aut))') - libgap.eval('product := SemidirectProduct(NiceObject(aut),alpha,G)') - return PermutationGroup(gap_group='product') + G = libgap.eval(f'Group({list(self.gens())})') + aut = G.AutomorphismGroup() + alpha = aut.NiceMonomorphism().InverseGeneralMapping() + product = aut.NiceObject().SemidirectProduct(alpha, G) + return PermutationGroup(gap_group=product) def subgroup(self, gens=None, gap_group=None, domain=None, category=None, canonicalize=True, check=True): """ @@ -3020,18 +3109,16 @@ def as_finitely_presented_group(self, reduced=False): INPUT: - - ``reduced`` -- (default ``False``) if ``True``, :meth:`FinitelyPresentedGroup.simplified - ` + - ``reduced`` -- (default: ``False``) if ``True``, + :meth:`FinitelyPresentedGroup.simplified ` is called, attempting to simplify the presentation of the finitely presented group - to be returned. + to be returned OUTPUT: finite presentation of ``self``, obtained by taking the image of the isomorphism returned by the GAP function ``IsomorphismFpGroupByGenerators`` - ALGORITHM: - - Uses GAP. + ALGORITHM: uses GAP EXAMPLES:: @@ -3153,7 +3240,7 @@ def commutator(self, other=None): INPUT: - - ``other`` -- (default: ``None``) a permutation group. + - ``other`` -- (default: ``None``) a permutation group OUTPUT: @@ -3250,7 +3337,7 @@ def commutator(self, other=None): @hap_decorator def cohomology(self, n, p=0): r""" - Computes the group cohomology `H^n(G, F)`, where `F = \ZZ` + Compute the group cohomology `H^n(G, F)`, where `F = \ZZ` if `p=0` and `F = \ZZ / p \ZZ` if `p > 0` is a prime. Wraps HAP's ``GroupHomology`` function, written by Graham Ellis. @@ -3335,7 +3422,7 @@ def cohomology_part(self, n, p=0): @hap_decorator def homology(self, n, p=0): r""" - Computes the group homology `H_n(G, F)`, where + Compute the group homology `H_n(G, F)`, where `F = \ZZ` if `p=0` and `F = \ZZ / p \ZZ` if `p > 0` is a prime. Wraps HAP's ``GroupHomology`` function, written by Graham Ellis. @@ -3382,7 +3469,7 @@ def homology(self, n, p=0): @hap_decorator def homology_part(self, n, p=0): r""" - Computes the `p`-part of the group homology + Compute the `p`-part of the group homology `H_n(G, F)`, where `F = \ZZ` if `p=0` and `F = \ZZ / p \ZZ` if `p > 0` is a prime. Wraps HAP's ``Homology`` function, written by Graham Ellis, applied to the @@ -3729,7 +3816,7 @@ def has_regular_subgroup(self, return_group=False): INPUT: - - ``return_group`` -- (boolean) If ``True``, a regular + - ``return_group`` -- boolean; if ``True``, a regular subgroup is returned if there is one, and ``None`` if there isn't. When ``return_group=False`` (default), only a boolean indicating whether such a group exists is returned instead. @@ -3776,7 +3863,7 @@ def blocks_all(self, representatives=True): INPUT: - - ``representative`` -- (boolean) whether to return all possible block + - ``representative`` -- boolean; whether to return all possible block systems of imprimitivity or only one of their representatives (the block can be obtained from its representative set `S` by computing the orbit of `S` under ``self``). @@ -3850,10 +3937,10 @@ def cosets(self, S, side='right'): INPUT: - - ``S`` -- a subgroup of ``self``. An error is raised - if ``S`` is not a subgroup. + - ``S`` -- a subgroup of ``self``; an error is raised + if ``S`` is not a subgroup - - ``side`` -- (default: ``'right'``) Determines if right cosets or + - ``side`` -- (default: ``'right'``) determines if right cosets or left cosets are returned. ``side`` refers to where the representative is placed in the products forming the cosets and thus allowable values are only ``'right'`` and ``'left'``. @@ -4015,7 +4102,7 @@ def cosets(self, S, side='right'): def minimal_generating_set(self): r""" - Return a minimal generating set + Return a minimal generating set. EXAMPLES:: @@ -4213,9 +4300,9 @@ def isomorphism_to(self, right): INPUT: - - ``self`` -- this group + - ``self`` -- this group - - ``right`` -- a permutation group + - ``right`` -- a permutation group OUTPUT: ``None``, or a morphism of permutation groups @@ -4262,9 +4349,9 @@ def is_isomorphic(self, right): INPUT: - - ``self`` -- this group + - ``self`` -- this group - - ``right`` -- a permutation group + - ``right`` -- a permutation group OUTPUT: boolean; ``True`` if ``self`` and ``right`` are isomorphic groups; ``False`` otherwise @@ -4545,7 +4632,7 @@ def is_primitive(self, domain=None): INPUT: - - ``domain`` (optional) + - ``domain`` -- optional .. SEEALSO:: @@ -5000,10 +5087,10 @@ def __init__(self, ambient, gens=None, gap_group=None, domain=None, - ``gens`` -- the generators of the subgroup - ``gap_group`` -- a GAP permutation group contained in the ambient group; - constructed from ``gens`` if not given. + constructed from ``gens`` if not given - - ``check`` -- ``True``: checks if ``gens`` are indeed elements of the - ambient group + - ``check`` -- boolean (default: ``True``); checks if ``gens`` are + indeed elements of the ambient group - ``canonicalize`` -- boolean (default: ``True``); if ``True``, sort generators and remove duplicates @@ -5271,10 +5358,10 @@ def __init__(self, gens, action, domain, gap_group=None, category=None, canonica - ``gap_group`` -- a gap or libgap permutation group, or a string defining one (default: ``None``), this is currently not supported - - ``canonicalize`` -- bool (default: ``True``); if ``True``, + - ``canonicalize`` -- boolean (default: ``True``); if ``True``, sort generators and remove duplicates - OUTPUT: a finite group action given as a permutation group. + OUTPUT: a finite group action given as a permutation group EXAMPLES:: @@ -5313,7 +5400,7 @@ def __init__(self, gens, action, domain, gap_group=None, category=None, canonica def orbits(self): """ - Returns the orbits of the elements of the domain under the + Return the orbits of the elements of the domain under the default group action. EXAMPLES:: diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 4d6a67fe41b..b0150295f1f 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -96,6 +96,8 @@ Check that :issue:`13569` is fixed:: (1,2), (1,3), (1,3), (2,3), (1,2), (1,2), (1,3), (2,3)] """ +# hi + # **************************************************************************** # Copyright (C) 2006 William Stein # Copyright (C) 2006 David Joyner @@ -288,14 +290,13 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): INPUT: - - ``g`` -- defines element - - - ``parent`` -- defines parent group (``g`` must be in - parent if specified, or a :class:`TypeError` is raised) + - ``g`` -- defines element - - ``check`` -- bool (default: ``True``); if ``False`` assumes ``g`` - is a gap element in parent (if specified) + - ``parent`` -- defines parent group (``g`` must be in + parent if specified, or a :exc:`TypeError` is raised) + - ``check`` -- boolean (default: ``True``); if ``False`` assumes ``g`` + is a gap element in parent (if specified) EXAMPLES: @@ -597,8 +598,8 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): ... ValueError: invalid data to initialize a permutation """ - cdef UInt2* p2 - cdef UInt4* p4 + cdef const UInt2* p2 + cdef const UInt4* p4 cdef int i cdef UInt d @@ -976,7 +977,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): INPUT: - - ``i`` -- integer + - ``i`` -- integer OUTPUT: a permutation group element @@ -1039,9 +1040,9 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): def __call__(self, i): r""" - Return the image of the integer i under this permutation. - Alternately, if i is a list, tuple or string, returns the result of - self acting on i. + Return the image of the integer `i` under this permutation. + Alternately, if `i` is a list, tuple or string, returns the result of + ``self`` acting on `i`. EXAMPLES:: @@ -1688,7 +1689,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): sign(sigma) = (-1)^{\sum_c len(c)-1} - where the sum is over cycles in self. + where the sum is over cycles in ``self``. """ cdef int cycle_len_sum = 0 cdef int i, k @@ -1792,7 +1793,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): INPUT: - - ``singletons`` -- boolean (default: ``False``) whether or not consider the + - ``singletons`` -- boolean (default: ``False``); whether or not consider the cycle that correspond to fixed point EXAMPLES:: @@ -1873,10 +1874,10 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): - ``g`` -- an element of the permutation group ``self.parent()`` - - ``singletons`` -- ``True`` or ``False`` depending on whether or not + - ``singletons`` -- boolean depending on whether or not trivial cycles should be counted (default: ``True``) - - ``as_list`` -- ``True`` or ``False`` depending on whether the cycle + - ``as_list`` -- boolean depending on whether the cycle type should be returned as a :class:`list` or as a :class:`Partition` (default: ``False``) @@ -1910,7 +1911,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): from sage.combinat.partition import _Partitions return _Partitions(cycle_type) - def has_descent(self, i, side="right", positive=False): + def has_descent(self, i, side='right', positive=False): r""" Return whether ``self`` has a left (resp. right) descent at position ``i``. If ``positive`` is ``True``, then test for a non @@ -1924,8 +1925,8 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): INPUT: - ``i`` -- an element of the index set - - ``side`` -- ``"left"`` or ``"right"`` (default: ``"right"``) - - ``positive`` -- a boolean (default: ``False``) + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``positive`` -- boolean (default: ``False``) EXAMPLES:: @@ -1936,13 +1937,13 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): False sage: s = S.simple_reflections() sage: x = s[1]*s[2] - sage: x.has_descent(1, side="right") + sage: x.has_descent(1, side='right') False - sage: x.has_descent(2, side="right") + sage: x.has_descent(2, side='right') True - sage: x.has_descent(1, side="left") + sage: x.has_descent(1, side='left') True - sage: x.has_descent(2, side="left") + sage: x.has_descent(2, side='left') False sage: S._test_has_descent() @@ -1998,13 +1999,13 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): INPUT: - - ``words`` -- a list of elements of the ambient group, generating + - ``words`` -- list of elements of the ambient group, generating a subgroup - - ``display`` -- boolean (default ``True``) whether to display + - ``display`` -- boolean (default: ``True``); whether to display additional information - - ``as_list`` -- boolean (default ``False``) whether to return + - ``as_list`` -- boolean (default: ``False``); whether to return the result as a list of pairs (generator, exponent) OUTPUT: diff --git a/src/sage/groups/perm_gps/permgroup_morphism.py b/src/sage/groups/perm_gps/permgroup_morphism.py index c0596d94b85..69f12016e60 100644 --- a/src/sage/groups/perm_gps/permgroup_morphism.py +++ b/src/sage/groups/perm_gps/permgroup_morphism.py @@ -247,8 +247,8 @@ def __init__(self, G, H, gens=None): r""" Some python code for wrapping GAP's ``GroupHomomorphismByImages`` function but only for permutation groups. Can be expensive if G is - large. This returns "fail" if gens does not generate self or if the map - does not extend to a group homomorphism, self - other. + large. This returns "fail" if gens does not generate ``self`` or if the map + does not extend to a group homomorphism, ``self`` - ``other``. EXAMPLES:: diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index c1f2683907b..d7dd1bdb2c4 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -153,7 +153,7 @@ class PermutationGroup_symalt(PermutationGroup_unique): @staticmethod def __classcall__(cls, domain): """ - Normalizes the input of the constructor into a set + Normalize the input of the constructor into a set. INPUT: @@ -187,10 +187,10 @@ def __classcall__(cls, domain): try: domain = Integer(domain) except TypeError: - raise TypeError("domain (={}) must be an integer >= 0 or a finite set (but domain has type {})".format(domain, type(domain))) + raise TypeError(f"domain (={domain}) must be an integer >= 0 or a finite set (but domain has type {type(domain)})") if domain < 0: - raise ValueError("domain (={}) must be an integer >= 0 or a list".format(domain)) + raise ValueError(f"domain (={domain}) must be an integer >= 0 or a list") domain = list(range(1, domain + 1)) v = FiniteEnumeratedSet(domain) else: @@ -208,7 +208,7 @@ class SymmetricGroup(PermutationGroup_symalt): INPUT: - - ``n`` -- a positive integer, or list or tuple thereof + - ``n`` -- positive integer, or list or tuple thereof .. NOTE:: @@ -273,8 +273,8 @@ def __init__(self, domain=None): self._domain = domain self._deg = len(self._domain) - self._domain_to_gap = {key: i+1 for i, key in enumerate(self._domain)} - self._domain_from_gap = {i+1: key for i, key in enumerate(self._domain)} + self._domain_to_gap = {key: i + 1 for i, key in enumerate(self._domain)} + self._domain_from_gap = {i + 1: key for i, key in enumerate(self._domain)} # Create the generators for the symmetric group if self._deg <= 1: @@ -299,7 +299,7 @@ def _gap_init_(self, gap=None): sage: S._gap_init_() 'SymmetricGroup(3)' """ - return 'SymmetricGroup({})'.format(self.degree()) + return f'SymmetricGroup({self.degree()})' @cached_method def index_set(self): @@ -340,7 +340,7 @@ def _repr_(self): sage: A = SymmetricGroup([2,3,7]); A Symmetric group of order 3! as a permutation group """ - return "Symmetric group of order {}! as a permutation group".format(self.degree()) + return f"Symmetric group of order {self.degree()}! as a permutation group" def _coerce_map_from_(self, G): """ @@ -381,7 +381,7 @@ def _from_cactus_group_element(self, x): def cartan_type(self): r""" - Return the Cartan type of ``self`` + Return the Cartan type of ``self``. The symmetric group `S_n` is a Coxeter group of type `A_{n-1}`. @@ -426,6 +426,50 @@ def simple_reflection(self, i): """ return self([(i, self._domain[self._domain.index(i)+1])], check=False) + @cached_method + def reflection_index_set(self): + r""" + Return the index set of the reflections of ``self``. + + .. SEEALSO:: + + - :meth:`reflection` + - :meth:`reflections` + + EXAMPLES:: + + sage: S5 = SymmetricGroup(5) + sage: S5.reflection_index_set() + (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) + """ + return tuple(range(len(self.reflections()))) + + def reflection(self, i): + r""" + Return the `i`-th reflection of ``self``. + + For `i` in `1,\dots,N`, this gives the `i`-th reflection of + ``self``. + + .. SEEALSO:: + + - :meth:`reflections_index_set` + - :meth:`reflections` + + EXAMPLES:: + + sage: S4 = SymmetricGroup(4) + sage: for i in S4.reflection_index_set(): + ....: print('%s %s'%(i, S4.reflection(i))) + 0 (1,2) + 1 (1,3) + 2 (1,4) + 3 (2,3) + 4 (2,4) + 5 (3,4) + """ + return self.reflections()[i] + def reflections(self): """ Return the list of all reflections in ``self``. @@ -658,11 +702,9 @@ def algebra(self, base_ring, category=None): (3,5) """ from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra - domain = self.domain() - if list(domain) == list(range(1, len(domain) + 1)): + if all(i == j for i, j in enumerate(self.domain(), start=1)): return SymmetricGroupAlgebra(base_ring, self, category=category) - else: - return super().algebra(base_ring) + return super().algebra(base_ring) Element = SymmetricGroupElement @@ -674,7 +716,7 @@ def __init__(self, domain=None): INPUT: - - ``n`` -- a positive integer, or list or tuple thereof + - ``n`` -- positive integer, or list or tuple thereof .. NOTE:: @@ -728,7 +770,7 @@ def _repr_(self): def _gap_init_(self, gap=None): """ - Returns the string used to create this group in GAP. + Return the string used to create this group in GAP. EXAMPLES:: @@ -749,7 +791,7 @@ def __init__(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer .. NOTE:: @@ -839,7 +881,7 @@ class DiCyclicGroup(PermutationGroup_unique): INPUT: - - ``n`` -- a positive integer, two or greater + - ``n`` -- positive integer, two or greater OUTPUT: @@ -948,11 +990,11 @@ class DiCyclicGroup(PermutationGroup_unique): """ def __init__(self, n): r""" - The dicyclic group of order `4*n`, as a permutation group. + The dicyclic group of order `4n`, as a permutation group. INPUT: - n -- a positive integer, two or greater + - ``n`` -- a positive integer; 2 or greater EXAMPLES:: @@ -1077,7 +1119,7 @@ def __init__(self, n): INPUT: - - ``n`` -- integer among `\{1,2,3\}`. + - ``n`` -- integer among `\{1,2,3\}` EXAMPLES:: @@ -1111,7 +1153,7 @@ def _repr_(self): class SuzukiSporadicGroup(PermutationGroup_unique): def __init__(self): r""" - Suzuki Sporadic Group + Suzuki Sporadic Group. EXAMPLES:: @@ -1216,7 +1258,7 @@ class GeneralDihedralGroup(PermutationGroup_generic): INPUT: - - ``factors`` -- a list of the sizes of the cyclic factors of the + - ``factors`` -- list of the sizes of the cyclic factors of the abelian group being dihedralized (this will be sorted once entered) @@ -1349,7 +1391,6 @@ class GeneralDihedralGroup(PermutationGroup_generic): AUTHOR: - Kevin Halasz (2012-7-12) - """ def __init__(self, factors): r""" @@ -1425,7 +1466,7 @@ def __init__(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer OUTPUT: the dihedral group of order `2n`, as a permutation group @@ -1517,7 +1558,7 @@ def __init__(self, p, m): - ``p`` -- a prime number that is the prime underlying this p-group - - ``m`` -- a positive integer such that the order of this + - ``m`` -- positive integer such that the order of this group is the `p^m`. Be aware that, for even `p`, `m` must be greater than 3, while for odd `p`, `m` must be greater than 2. @@ -1658,7 +1699,7 @@ def __init__(self, m): INPUT: - - ``m`` -- a positive integer; the power of 2 that is the + - ``m`` -- positive integer; the power of 2 that is the group's order OUTPUT: @@ -1767,7 +1808,7 @@ def __init__(self, n): INPUT: - - ``n`` -- a positive integer in {9, 10, 11, 12, 21, 22, 23, 24}. + - ``n`` -- positive integer in {9, 10, 11, 12, 21, 22, 23, 24} OUTPUT: the Mathieu group of degree `n`, as a permutation group @@ -1817,7 +1858,7 @@ def __init__(self, d, n): INPUT: - - ``d`` -- non-negative integer; the degree + - ``d`` -- nonnegative integer; the degree - ``n`` -- positive integer; the index of the group in the GAP database, starting at 1 @@ -1888,7 +1929,7 @@ def __init__(self, d, n): def transitive_number(self): """ - Return the index of this group in the GAP database, starting at 1 + Return the index of this group in the GAP database, starting at 1. EXAMPLES:: @@ -1899,7 +1940,7 @@ def transitive_number(self): def degree(self): """ - Return the degree of this permutation group + Return the degree of this permutation group. EXAMPLES:: @@ -1948,14 +1989,13 @@ def TransitiveGroups(d=None): ... NotImplementedError: only the transitive groups of degree at most 31 are available in GAP's database - """ if d is None: return TransitiveGroupsAll() d = Integer(d) if d < 0: - raise ValueError("a transitive group acts on a non negative integer number of positions") + raise ValueError("a transitive group acts on a nonnegative integer number of positions") return TransitiveGroupsOfDegree(d) @@ -2090,7 +2130,7 @@ def __getitem__(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -2148,7 +2188,7 @@ def __call__(self, G): for H in self: if H.is_isomorphic(G): return H - raise ValueError("{} is not a transitive group of degree {}".format(G, self._degree)) + raise ValueError(f"{G} is not a transitive group of degree {self._degree}") @cached_method def cardinality(self): @@ -2209,9 +2249,9 @@ class PrimitiveGroup(PermutationGroup_unique): INPUT: - - ``d`` -- non-negative integer. the degree of the group. + - ``d`` -- nonnegative integer; the degree of the group - - ``n`` -- positive integer. the index of the group in the GAP + - ``n`` -- positive integer; the index of the group in the GAP database, starting at 1 OUTPUT: the ``n``-th primitive group of degree ``d`` @@ -2252,9 +2292,7 @@ def __init__(self, d, n): """ The Python constructor. - INPUT/OUTPUT: - - See :class:`PrimitiveGroup`. + INPUT/OUTPUT: see :class:`PrimitiveGroup` TESTS:: @@ -2312,7 +2350,7 @@ def group_primitive_id(self): def PrimitiveGroups(d=None): """ - Return the set of all primitive groups of a given degree ``d`` + Return the set of all primitive groups of a given degree ``d``. INPUT: @@ -2354,7 +2392,7 @@ def PrimitiveGroups(d=None): else: d = Integer(d) if d < 0: - raise ValueError("a primitive group acts on a non negative integer number of positions") + raise ValueError("a primitive group acts on a nonnegative integer number of positions") return PrimitiveGroupsOfDegree(d) @@ -2413,7 +2451,7 @@ def __contains__(self, G): INPUT: - - `G` -- anything. + - ``G`` -- anything OUTPUT: boolean @@ -2486,7 +2524,7 @@ def __contains__(self, G): INPUT: - - `G` -- anything. + - ``G`` -- anything OUTPUT: boolean @@ -2507,7 +2545,7 @@ def __getitem__(self, n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -2656,7 +2694,7 @@ def __init__(self, n, q, name='a'): self._base_ring = GF(q, name=name) self._n = n - def __str__(self): + def __str__(self) -> str: """ EXAMPLES:: @@ -2733,16 +2771,13 @@ def __init__(self, n, q, name='a'): q = q.cardinality() if q not in NonNegativeIntegers(): raise ValueError('q must be a prime power or a finite field') - if n == 1: - id = 'Group([()])' - else: - id = 'PSL(%s,%s)' % (n, q) + id = 'Group([()])' if n == 1 else f'PSL({n},{q})' PermutationGroup_generic.__init__(self, gap_group=id) self._q = q self._base_ring = GF(q, name=name) self._n = n - def __str__(self): + def __str__(self) -> str: """ EXAMPLES:: @@ -2798,8 +2833,8 @@ def ramification_module_decomposition_hurwitz_curve(self): F = self.base_ring() q = F.order() - libgap.Read(str(Path(SAGE_EXTCODE) / 'gap' / 'joyner' / - 'hurwitz_crv_rr_sp.gap')) + libgap.Read(Path(SAGE_EXTCODE) / 'gap' / 'joyner' / + 'hurwitz_crv_rr_sp.gap') mults = libgap.eval(f"ram_module_hurwitz({q})") return mults.sage() @@ -2842,8 +2877,8 @@ def ramification_module_decomposition_modular_curve(self): raise ValueError("degree must be 2") F = self.base_ring() q = F.order() - libgap.Read(str(Path(SAGE_EXTCODE) / 'gap' / 'joyner' / - 'modular_crv_rr_sp.gap')) + libgap.Read(Path(SAGE_EXTCODE) / 'gap' / 'joyner' / + 'modular_crv_rr_sp.gap') mults = libgap.eval(f"ram_module_X({q})") return mults.sage() @@ -2899,7 +2934,7 @@ def __init__(self, n, q, name='a'): self._base_ring = GF(q, name=name) self._n = n - def __str__(self): + def __str__(self) -> str: """ EXAMPLES:: @@ -2931,11 +2966,12 @@ def __init__(self, n, q, name='a'): INPUT: - - n -- positive integer; the degree - - q -- prime power; the size of the ground field - - name -- (default: 'a') variable name of indeterminate of finite field GF(q) + - ``n`` -- positive integer; the degree + - ``q`` -- prime power; the size of the ground field + - ``name`` -- (default: ``'a'``) variable name of indeterminate of finite + field `\GF(q)` - OUTPUT: PSU(n,q) + OUTPUT: PSU(`n`,`q`) .. NOTE:: @@ -3091,7 +3127,7 @@ def base_ring(self): """ return self._base_ring - def __str__(self): + def __str__(self) -> str: """ EXAMPLES:: @@ -3468,16 +3504,14 @@ class SmallPermutationGroup(PermutationGroup_generic): sage: G = SmallPermutationGroup(12,4); G Group of order 12 and GAP Id 4 as a permutation group sage: G.gens() - ((1,2)(3,5)(4,10)(6,8)(7,12)(9,11), - (1,3)(2,5)(4,7)(6,9)(8,11)(10,12), - (1,4,8)(2,6,10)(3,7,11)(5,9,12)) + ((4,5), (1,2), (3,4,5)) sage: G.character_table() # needs sage.rings.number_field [ 1 1 1 1 1 1] - [ 1 -1 -1 1 1 -1] + [ 1 -1 1 -1 1 -1] [ 1 -1 1 1 -1 1] - [ 1 1 -1 1 -1 -1] - [ 2 0 -2 -1 0 1] - [ 2 0 2 -1 0 -1] + [ 1 1 1 -1 -1 -1] + [ 2 0 -1 -2 0 1] + [ 2 0 -1 2 0 -1] sage: def numgps(n): return ZZ(libgap.NumberSmallGroups(n)) sage: all(SmallPermutationGroup(n,k).id() == [n,k] ....: for n in [1..64] for k in [1..numgps(n)]) @@ -3486,11 +3520,11 @@ class SmallPermutationGroup(PermutationGroup_generic): sage: H.is_abelian() False sage: [H.centralizer(g) for g in H.conjugacy_classes_representatives()] - [Subgroup generated by [(1,2)(3,6)(4,5), (1,3,5)(2,4,6)] of + [Subgroup generated by [(1,3), (2,3)] of (Group of order 6 and GAP Id 1 as a permutation group), - Subgroup generated by [(1,2)(3,6)(4,5)] of + Subgroup generated by [(2,3)] of (Group of order 6 and GAP Id 1 as a permutation group), - Subgroup generated by [(1,3,5)(2,4,6), (1,5,3)(2,6,4)] of + Subgroup generated by [(1,2,3)] of (Group of order 6 and GAP Id 1 as a permutation group)] """ diff --git a/src/sage/groups/raag.py b/src/sage/groups/raag.py index 22c44cb2312..4313f500319 100644 --- a/src/sage/groups/raag.py +++ b/src/sage/groups/raag.py @@ -90,7 +90,7 @@ class RightAngledArtinGroup(ArtinGroup): INPUT: - ``G`` -- a graph - - ``names`` -- a string or a list of generator names + - ``names`` -- string or list of generator names EXAMPLES:: diff --git a/src/sage/groups/semimonomial_transformations/meson.build b/src/sage/groups/semimonomial_transformations/meson.build new file mode 100644 index 00000000000..402cb5244e5 --- /dev/null +++ b/src/sage/groups/semimonomial_transformations/meson.build @@ -0,0 +1,22 @@ +py.install_sources( + 'all.py', + 'semimonomial_transformation.pxd', + 'semimonomial_transformation_group.py', + subdir: 'sage/groups/semimonomial_transformations', +) + +extension_data = { + 'semimonomial_transformation' : files('semimonomial_transformation.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/groups/semimonomial_transformations', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx b/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx index 013e27fa28a..72042533883 100644 --- a/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx +++ b/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx @@ -235,7 +235,7 @@ cdef class SemimonomialTransformation(MultiplicativeGroupElement): def __repr__(self): """ - String representation of `self`. + String representation of ``self``. EXAMPLES:: diff --git a/src/sage/groups/semimonomial_transformations/semimonomial_transformation_group.py b/src/sage/groups/semimonomial_transformations/semimonomial_transformation_group.py index 50b5e5741d5..108d8542c87 100644 --- a/src/sage/groups/semimonomial_transformations/semimonomial_transformation_group.py +++ b/src/sage/groups/semimonomial_transformations/semimonomial_transformation_group.py @@ -152,13 +152,13 @@ def _element_constructor_(self, arg1, v=None, perm=None, autom=None, check=True) INPUT: - - ``arg1`` (optional) -- either the integers 0, 1 or an element of ``self`` + - ``arg1`` -- (optional) either the integers 0, 1 or an element of ``self`` - - ``v`` (optional) -- a vector of length ``self.degree()`` + - ``v`` -- (optional) a vector of length ``self.degree()`` - - ``perm`` (optional) -- a permutation of degree ``self.degree()`` + - ``perm`` -- (optional) a permutation of degree ``self.degree()`` - - ``autom`` (optional) -- an automorphism of the ring + - ``autom`` -- (optional) an automorphism of the ring EXAMPLES:: diff --git a/src/sage/homology/chain_complex.py b/src/sage/homology/chain_complex.py index fd43e81fd14..2f050801f25 100644 --- a/src/sage/homology/chain_complex.py +++ b/src/sage/homology/chain_complex.py @@ -73,7 +73,7 @@ def _latex_module(R, m): INPUT: - ``R`` -- a commutative ring - - ``m`` -- non-negative integer + - ``m`` -- nonnegative integer This is used by the ``_latex_`` method for chain complexes. @@ -101,30 +101,28 @@ def ChainComplex(data=None, base_ring=None, grading_group=None, INPUT: - ``data`` -- the data defining the chain complex; see below for - more details. + more details The following keyword arguments are supported: - - ``base_ring`` -- a commutative ring (optional), the ring over + - ``base_ring`` -- a commutative ring (optional); the ring over which the chain complex is defined. If this is not specified, it is determined by the data defining the chain complex. - ``grading_group`` -- a additive free abelian group (optional, - default ``ZZ``), the group over which the chain complex is - indexed. + default ``ZZ``); the group over which the chain complex is + indexed - ``degree_of_differential`` -- element of grading_group - (default: ``1``). The degree of the differential. + (default: ``1``); the degree of the differential - - ``degree`` -- alias for ``degree_of_differential``. + - ``degree`` -- alias for ``degree_of_differential`` - - ``check`` -- boolean (default: ``True``). If ``True``, + - ``check`` -- boolean (default: ``True``); if ``True``, check that each consecutive pair of differentials are - composable and have composite equal to zero. + composable and have composite equal to zero - OUTPUT: - - A chain complex. + OUTPUT: a chain complex .. WARNING:: @@ -323,7 +321,7 @@ class Chain_class(ModuleElement): def __init__(self, parent, vectors, check=True): r""" - A Chain in a Chain Complex + A Chain in a Chain Complex. A chain is collection of module elements for each module `C_n` of the chain complex `(C_n, d_n)`. There is no restriction on @@ -425,7 +423,6 @@ def _ascii_art_(self): sage: C = ChainComplex(base_ring=ZZ) sage: ascii_art(C()) 0 - """ from sage.typeset.ascii_art import AsciiArt @@ -485,15 +482,15 @@ def _unicode_art_(self): from sage.typeset.unicode_art import UnicodeArt def arrow_art(d): - d_str = [u' d_{0} '.format(d)] - arrow = u' <' + u'─' * (len(d_str[0]) - 3) + u' ' + d_str = [' d_{0} '.format(d)] + arrow = ' <' + '─' * (len(d_str[0]) - 3) + ' ' d_str.append(arrow) return UnicodeArt(d_str, baseline=0) def vector_art(d): v = self.vector(d) if not v.degree(): - return UnicodeArt([u'0']) + return UnicodeArt(['0']) w = matrix(v).transpose() return w._unicode_art_() @@ -502,27 +499,25 @@ def vector_art(d): for ordered in chain_complex.ordered_degrees(): ordered = list(reversed(ordered)) if not ordered: - return UnicodeArt([u'0']) + return UnicodeArt(['0']) result_ordered = vector_art(ordered[0] + chain_complex.degree_of_differential()) for n in ordered: result_ordered += arrow_art(n) + vector_art(n) result = [result_ordered] + result if len(result) == 0: - return UnicodeArt([u'0']) + return UnicodeArt(['0']) concatenated = result[0] for r in result[1:]: - concatenated += UnicodeArt([u' ... ']) + r + concatenated += UnicodeArt([' ... ']) + r return concatenated def is_cycle(self): """ Return whether the chain is a cycle. - OUTPUT: - - Boolean. Whether the elements of the chain are in the kernel - of the differentials. + OUTPUT: boolean; whether the elements of the chain are in the kernel + of the differentials EXAMPLES:: @@ -544,7 +539,7 @@ def is_boundary(self): OUTPUT: - Boolean. Whether the elements of the chain are in the image of + boolean; whether the elements of the chain are in the image of the differentials. EXAMPLES:: @@ -570,7 +565,7 @@ def is_boundary(self): def _add_(self, other): """ - Module addition + Module addition. EXAMPLES:: @@ -594,7 +589,7 @@ def _add_(self, other): def _lmul_(self, scalar): """ - Scalar multiplication + Scalar multiplication. EXAMPLES:: @@ -766,7 +761,7 @@ def random_element(self): @cached_method def rank(self, degree, ring=None): r""" - Return the rank of a differential + Return the rank of a differential. INPUT: @@ -851,7 +846,7 @@ def nonzero_degrees(self): @cached_method def ordered_degrees(self, start=None, exclude_first=False): r""" - Sort the degrees in the order determined by the differential + Sort the degrees in the order determined by the differential. INPUT: @@ -860,12 +855,10 @@ def ordered_degrees(self, start=None, exclude_first=False): - ``exclude_first`` -- boolean (optional; default: ``False``); whether to exclude the lowest degree -- this is a - handy way to just get the degrees of the non-zero modules, + handy way to just get the degrees of the nonzero modules, as the domain of the first differential is zero. - OUTPUT: - - If ``start`` has been specified, the longest tuple of degrees + OUTPUT: if ``start`` has been specified, the longest tuple of degrees * containing ``start`` (unless ``start`` would be the first and ``exclude_first=True``), @@ -875,7 +868,7 @@ def ordered_degrees(self, start=None, exclude_first=False): * such that none of the corresponding differentials are `0\times 0`. If ``start`` has not been specified, a tuple of such tuples of - degrees. One for each sequence of non-zero differentials. They + degrees. One for each sequence of nonzero differentials. They are returned in sort order. EXAMPLES:: @@ -926,11 +919,9 @@ def ordered_degrees(self, start=None, exclude_first=False): def degree_of_differential(self): """ - Return the degree of the differentials of the complex - - OUTPUT: + Return the degree of the differentials of the complex. - An element of the grading group. + OUTPUT: an element of the grading group EXAMPLES:: @@ -1045,7 +1036,7 @@ def free_module(self, degree=None): INPUT: - - ``degree`` -- an element of the grading group or ``None`` (default). + - ``degree`` -- an element of the grading group or ``None`` (default) OUTPUT: @@ -1072,7 +1063,7 @@ def free_module(self, degree=None): def __hash__(self): """ - The hash is formed by combining the hashes of + The hash is formed by combining the hashes of. - the base ring - the differentials -- the matrices and their degrees @@ -1393,7 +1384,7 @@ def betti(self, deg=None, base_ring=None): INPUT: - ``deg`` -- an element of the grading group for the chain - complex or None (default ``None``); if ``None``, + complex or ``None`` (default: ``None``); if ``None``, then return every Betti number, as a dictionary indexed by degree, or if an element of the grading group, then return the Betti number in that degree @@ -1442,11 +1433,11 @@ def torsion_list(self, max_prime, min_prime=2): INPUT: - - ``max_prime`` -- prime number; search for torsion mod `p` for - all `p` strictly less than this number + - ``max_prime`` -- prime number; search for torsion mod `p` for + all `p` strictly less than this number - - ``min_prime`` -- prime (default: 2); search for - torsion mod `p` for primes at least as big as this + - ``min_prime`` -- prime (default: 2); search for + torsion mod `p` for primes at least as big as this Return a list of pairs `(p, d)` where `p` is a prime at which there is torsion and `d` is a list of dimensions in which this @@ -1562,7 +1553,7 @@ def shift(self, n=1): INPUT: - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) The *shift* operation is also sometimes called *translation* or *suspension*. @@ -1730,33 +1721,33 @@ def _unicode_art_(self): def arrow_art(n): d_n = self.differential(n) if not d_n.nrows() or not d_n.ncols(): - return UnicodeArt([u'<──']) + return UnicodeArt(['<──']) d_str = list(d_n._unicode_art_()) - arrow = u'<' + u'─' * (len(d_str[0]) - 1) + arrow = '<' + '─' * (len(d_str[0]) - 1) d_str.append(arrow) return UnicodeArt(d_str) def module_art(n): C_n = self.free_module(n) if not C_n.rank(): - return UnicodeArt([u' 0 ']) + return UnicodeArt([' 0 ']) else: - return UnicodeArt([u' C_{0} '.format(n)]) + return UnicodeArt([' C_{0} '.format(n)]) result = [] for ordered in self.ordered_degrees(): ordered = list(reversed(ordered)) if not ordered: - return UnicodeArt([u'0']) + return UnicodeArt(['0']) result_ordered = module_art(ordered[0] + self.degree_of_differential()) for n in ordered: result_ordered += arrow_art(n) + module_art(n) result = [result_ordered] + result if len(result) == 0: - return UnicodeArt([u'0']) + return UnicodeArt(['0']) concatenated = result[0] for r in result[1:]: - concatenated += UnicodeArt([u' ... ']) + r + concatenated += UnicodeArt([' ... ']) + r return concatenated def _latex_(self): @@ -1826,7 +1817,7 @@ def cartesian_product(self, *factors, **kwds): INPUT: - - ``subdivide`` -- (default: ``False``) whether to subdivide the + - ``subdivide`` -- boolean (default: ``False``); whether to subdivide the the differential matrices EXAMPLES:: @@ -1954,7 +1945,7 @@ def tensor(self, *factors, **kwds): INPUT: - - ``subdivide`` -- (default: ``False``) whether to subdivide the + - ``subdivide`` -- boolean (default: ``False``); whether to subdivide the the differential matrices .. TODO:: diff --git a/src/sage/homology/chain_complex_homspace.py b/src/sage/homology/chain_complex_homspace.py index 1170b50b885..00fa8f1671a 100644 --- a/src/sage/homology/chain_complex_homspace.py +++ b/src/sage/homology/chain_complex_homspace.py @@ -121,7 +121,6 @@ def is_ChainComplexHomspace(x): use 'isinstance(..., ChainComplexHomspace)' instead. See https://github.com/sagemath/sage/issues/38184 for details. True - """ from sage.misc.superseded import deprecation deprecation(38184, @@ -144,7 +143,6 @@ class ChainComplexHomspace(sage.categories.homset.Homset): from Chain complex with at most 5 nonzero terms over Integer Ring to Chain complex with at most 5 nonzero terms over Integer Ring in Category of chain complexes over Integer Ring - """ def __call__(self, f): """ @@ -162,6 +160,5 @@ def __call__(self, f): sage: y = G(f) sage: x == y True - """ return ChainComplexMorphism(f, self.domain(), self.codomain()) diff --git a/src/sage/homology/chain_complex_morphism.py b/src/sage/homology/chain_complex_morphism.py index af68bf0c906..96080c9e33b 100644 --- a/src/sage/homology/chain_complex_morphism.py +++ b/src/sage/homology/chain_complex_morphism.py @@ -331,7 +331,6 @@ def __neg__(self): [ 0 -1 0 0] [ 0 0 -1 0] [ 0 0 0 -1]} - """ f = dict() for i in self._matrix_dictionary.keys(): @@ -431,7 +430,7 @@ def __mul__(self, x): [2] Before :issue:`19065`, the following multiplication produced a - :class:`KeyError` because `f` was not explicitly defined in degree 2:: + :exc:`KeyError` because `f` was not explicitly defined in degree 2:: sage: C0 = ChainComplex({0: zero_matrix(ZZ, 0, 1)}) sage: C1 = ChainComplex({1: zero_matrix(ZZ, 0, 1)}) diff --git a/src/sage/homology/chain_homotopy.py b/src/sage/homology/chain_homotopy.py index 3b5dece7d91..ae3324623f2 100644 --- a/src/sage/homology/chain_homotopy.py +++ b/src/sage/homology/chain_homotopy.py @@ -64,7 +64,7 @@ class ChainHomotopy(Morphism): - ``matrices`` -- dictionary of matrices, keyed by dimension - ``f`` -- chain map `C \to D` - - ``g`` (optional) -- chain map `C \to D` + - ``g`` -- (optional) chain map `C \to D` The dictionary ``matrices`` defines ``H`` by specifying the matrix defining it in each degree: the entry `m` corresponding to key `i` diff --git a/src/sage/homology/chains.py b/src/sage/homology/chains.py index b9a54940943..41bdf06776c 100644 --- a/src/sage/homology/chains.py +++ b/src/sage/homology/chains.py @@ -25,17 +25,17 @@ from sage.structure.element import coercion_model -class CellComplexReference(): +class CellComplexReference: def __init__(self, cell_complex, degree, cells=None): """ - Auxiliary base class for chains and cochains + Auxiliary base class for chains and cochains. INPUT: - - ``cell_complex`` -- The cell complex to reference + - ``cell_complex`` -- the cell complex to reference - - ``degree`` -- integer. The degree of the (co)chains + - ``degree`` -- integer; the degree of the (co)chains - ``cells`` -- tuple of cells or ``None``. Does not necessarily have to be the cells in the given degree, for computational purposes this @@ -60,11 +60,9 @@ def __init__(self, cell_complex, degree, cells=None): def cell_complex(self): """ - Return the underlying cell complex + Return the underlying cell complex. - OUTPUT: - - A cell complex. + OUTPUT: a cell complex EXAMPLES:: @@ -76,11 +74,9 @@ def cell_complex(self): def degree(self): """ - Return the dimension of the cells - - OUTPUT: + Return the dimension of the cells. - Integer. The dimension of the cells. + OUTPUT: integer; the dimension of the cells EXAMPLES:: @@ -99,7 +95,7 @@ class Chains(CellComplexReference, CombinatorialFreeModule): - ``n_cells`` -- tuple of `n`-cells, which thus forms a basis for this module - - ``base_ring`` -- optional (default `\ZZ`) + - ``base_ring`` -- (default: `\ZZ`) One difference between chains and cochains is notation. In a simplicial complex, for example, a simplex ``(0,1,2)`` is written @@ -175,9 +171,7 @@ def dual(self): """ Return the cochains. - OUTPUT: - - The cochains of the same cells with the same base ring. + OUTPUT: the cochains of the same cells with the same base ring EXAMPLES:: @@ -200,9 +194,7 @@ def chain_complex(self): """ Return the chain complex. - OUTPUT: - - Chain complex, see :mod:`sage.homology.chain_complex`. + OUTPUT: chain complex, see :mod:`sage.homology.chain_complex` EXAMPLES:: @@ -225,11 +217,9 @@ class Element(CombinatorialFreeModule.Element): def to_complex(self): """ - Return the corresponding chain complex element + Return the corresponding chain complex element. - OUTPUT: - - An element of the chain complex, see :mod:`sage.homology.chain_complex`. + OUTPUT: an element of the chain complex, see :mod:`sage.homology.chain_complex` EXAMPLES:: @@ -251,11 +241,9 @@ def to_complex(self): def boundary(self): """ - Return the boundary of the chain - - OUTPUT: + Return the boundary of the chain. - The boundary as a chain in one degree lower. + OUTPUT: the boundary as a chain in one degree lower EXAMPLES:: @@ -278,11 +266,9 @@ def boundary(self): def is_cycle(self): """ - Test whether the chain is a cycle - - OUTPUT: + Test whether the chain is a cycle. - Boolean. Whether the :meth:`boundary` vanishes. + OUTPUT: boolean; whether the :meth:`boundary` vanishes EXAMPLES:: @@ -304,12 +290,10 @@ def is_cycle(self): def is_boundary(self): """ - Test whether the chain is a boundary + Test whether the chain is a boundary. - OUTPUT: - - Boolean. Whether the chain is the :meth:`boundary` of a chain in one - degree higher. + OUTPUT: boolean; whether the chain is the :meth:`boundary` of a + chain in one degree higher EXAMPLES:: @@ -338,7 +322,7 @@ class Cochains(CellComplexReference, CombinatorialFreeModule): - ``n_cells`` -- tuple of `n`-cells, which thus forms a basis for this module - - ``base_ring`` -- optional (default `\ZZ`) + - ``base_ring`` -- (default: `\ZZ`) One difference between chains and cochains is notation. In a simplicial complex, for example, a simplex ``(0,1,2)`` is written @@ -413,11 +397,9 @@ def __init__(self, cell_complex, degree, cells=None, base_ring=None): def dual(self): """ - Return the chains - - OUTPUT: + Return the chains. - The chains of the same cells with the same base ring. + OUTPUT: the chains of the same cells with the same base ring EXAMPLES:: @@ -440,9 +422,7 @@ def cochain_complex(self): """ Return the cochain complex. - OUTPUT: - - Cochain complex, see :mod:`sage.homology.chain_complex`. + OUTPUT: cochain complex, see :mod:`sage.homology.chain_complex` EXAMPLES:: @@ -466,11 +446,9 @@ class Element(CombinatorialFreeModule.Element): def to_complex(self): """ - Return the corresponding cochain complex element - - OUTPUT: + Return the corresponding cochain complex element. - An element of the cochain complex, see :mod:`sage.homology.chain_complex`. + OUTPUT: an element of the cochain complex, see :mod:`sage.homology.chain_complex` EXAMPLES:: @@ -492,11 +470,9 @@ def to_complex(self): def coboundary(self): r""" - Return the coboundary of this cochain + Return the coboundary of this cochain. - OUTPUT: - - The coboundary as a cochain in one degree higher. + OUTPUT: the coboundary as a cochain in one degree higher EXAMPLES:: @@ -519,11 +495,9 @@ def coboundary(self): def is_cocycle(self): """ - Test whether the cochain is a cocycle - - OUTPUT: + Test whether the cochain is a cocycle. - Boolean. Whether the :meth:`coboundary` vanishes. + OUTPUT: boolean; whether the :meth:`coboundary` vanishes EXAMPLES:: @@ -545,12 +519,10 @@ def is_cocycle(self): def is_coboundary(self): """ - Test whether the cochain is a coboundary - - OUTPUT: + Test whether the cochain is a coboundary. - Boolean. Whether the cochain is the :meth:`coboundary` of a cochain - in one degree lower. + OUTPUT: boolean; whether the cochain is the :meth:`coboundary` of a cochain + in one degree lower EXAMPLES:: diff --git a/src/sage/homology/free_resolution.py b/src/sage/homology/free_resolution.py index 29c33e4e2a6..89b3352c560 100644 --- a/src/sage/homology/free_resolution.py +++ b/src/sage/homology/free_resolution.py @@ -230,7 +230,7 @@ def _repr_module(self, i): INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: @@ -271,11 +271,11 @@ def _repr_module(self, i): @abstract_method def differential(self, i): r""" - Return the ``i``-th differential map. + Return the `i`-th differential map. INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer TESTS:: @@ -375,7 +375,7 @@ def _repr_(self): INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: @@ -409,11 +409,11 @@ def __len__(self): def __getitem__(self, i): r""" - Return the ``i``-th free module of this resolution. + Return the `i`-th free module of this resolution. INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: @@ -443,11 +443,11 @@ def __getitem__(self, i): def differential(self, i): r""" - Return the ``i``-th differential map. + Return the `i`-th differential map. INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: @@ -542,11 +542,11 @@ def differential(self, i): def matrix(self, i): r""" - Return the matrix representing the ``i``-th differential map. + Return the matrix representing the `i`-th differential map. INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer EXAMPLES:: diff --git a/src/sage/homology/graded_resolution.py b/src/sage/homology/graded_resolution.py index ceadd15c2de..76361480d8e 100644 --- a/src/sage/homology/graded_resolution.py +++ b/src/sage/homology/graded_resolution.py @@ -101,12 +101,11 @@ class GradedFiniteFreeResolution(FiniteFreeResolution): - ``degrees`` -- (default: a list with all entries `1`) a list of integers or integer vectors giving degrees of variables of `S` - - ``shifts`` -- a list of integers or integer vectors giving shifts of + - ``shifts`` -- list of integers or integer vectors giving shifts of degrees of `n` summands of the free module `M`; this is a list of zero degrees of length `n` by default - - ``name`` -- a string; name of the base ring - + - ``name`` -- string; name of the base ring """ def __init__(self, module, degrees=None, shifts=None, name='S', **kwds): r""" @@ -337,7 +336,7 @@ def __init__(self, module, degrees=None, *args, **kwds): sage: M = matrix([[x^3, 3*x^3, 5*x^3], ....: [0, x, 2*x]]) sage: res = FreeResolution(M, graded=True) - sage: TestSuite(res).run(skip="_test_pickling") + sage: TestSuite(res).run(skip='_test_pickling') """ super().__init__(module, degrees=degrees, *args, **kwds) @@ -422,11 +421,11 @@ class GradedFiniteFreeResolution_singular(GradedFiniteFreeResolution, FiniteFree - ``degrees`` -- (default: a list with all entries `1`) a list of integers or integer vectors giving degrees of variables of `S` - - ``shifts`` -- a list of integers or integer vectors giving shifts of + - ``shifts`` -- list of integers or integer vectors giving shifts of degrees of `n` summands of the free module `M`; this is a list of zero degrees of length `n` by default - - ``name`` -- a string; name of the base ring + - ``name`` -- string; name of the base ring - ``algorithm`` -- Singular algorithm to compute a resolution of ``ideal`` diff --git a/src/sage/homology/hochschild_complex.py b/src/sage/homology/hochschild_complex.py index ea42164ef9d..a6412a1afc8 100644 --- a/src/sage/homology/hochschild_complex.py +++ b/src/sage/homology/hochschild_complex.py @@ -113,7 +113,7 @@ def _repr_(self): sage: SGA = SymmetricGroupAlgebra(QQ, 3) sage: T = SGA.trivial_representation() - sage: T.rename("Trivial representation of SGA") + sage: T.rename('Trivial representation of SGA') sage: SGA.hochschild_complex(T) Hochschild complex of Symmetric group algebra of order 3 over Rational Field with coefficients in Trivial representation of SGA @@ -184,7 +184,7 @@ def module(self, d): # Symmetric group algebra of order 3 over Rational Field """ if d < 0: - raise ValueError("only defined for non-negative degree") + raise ValueError("only defined for nonnegative degree") return tensor([self._M] + [self._A] * d) @cached_method @@ -668,7 +668,7 @@ def arrow_art(d): def _add_(self, other): """ - Module addition + Module addition. EXAMPLES:: @@ -703,7 +703,7 @@ def _add_(self, other): def _lmul_(self, scalar): """ - Scalar multiplication + Scalar multiplication. EXAMPLES:: diff --git a/src/sage/homology/homology_morphism.py b/src/sage/homology/homology_morphism.py index 01308d46b9e..6db0315945f 100644 --- a/src/sage/homology/homology_morphism.py +++ b/src/sage/homology/homology_morphism.py @@ -52,11 +52,11 @@ class InducedHomologyMorphism(Morphism): - ``map`` -- the map of simplicial complexes - ``base_ring`` -- a field (default: ``QQ``) - - ``cohomology`` -- boolean (default: ``False``). If + - ``cohomology`` -- boolean (default: ``False``); if ``True``, return the induced map in cohomology rather than - homology. + homology - .. note:: + .. NOTE:: This is not intended to be used directly by the user, but instead via the method @@ -136,9 +136,9 @@ def __init__(self, map, base_ring=None, cohomology=False): - ``map`` -- the map of simplicial complexes - ``base_ring`` -- a field (default: ``QQ``) - - ``cohomology`` -- boolean (default: ``False``). If + - ``cohomology`` -- boolean (default: ``False``); if ``True``, return the induced map in cohomology rather than - homology. + homology EXAMPLES:: diff --git a/src/sage/homology/homology_vector_space_with_basis.py b/src/sage/homology/homology_vector_space_with_basis.py index 04b880f814e..64d3186fea7 100644 --- a/src/sage/homology/homology_vector_space_with_basis.py +++ b/src/sage/homology/homology_vector_space_with_basis.py @@ -70,7 +70,7 @@ class HomologyVectorSpaceWithBasis(CombinatorialFreeModule): - ``base_ring`` -- must be a field - ``cell_complex`` -- the cell complex whose homology we are computing - - ``cohomology`` -- (default: ``False``) if ``True``, return + - ``cohomology`` -- boolean (default: ``False``); if ``True``, return the cohomology as a module - ``category`` -- (optional) a subcategory of modules with basis @@ -340,7 +340,6 @@ def _repr_term(self, i): sage: co = simplicial_complexes.KleinBottle().cohomology_ring(GF(2)) sage: co.basis()[1,0] # indirect doctest h^{1,0} - """ sym = '^' if self._cohomology else '_' return 'h{}{{{},{}}}'.format(sym, i[0], i[1]) @@ -445,7 +444,7 @@ def _test_duality(self, **options): tester = self._tester(**options) dual = self.dual() dims = [a[0] for a in self._indices] - for dim in range(max(max(dims), tester._max_runs) + 1): + for dim in range(max(max(dims), tester._max_runs) + 1): n = len(self.basis(dim)) m = matrix(n, n, [a.eval(b) for a in self.basis(dim) for b in dual.basis(dim)]) tester.assertEqual(m, 1, f"error in dimension {dim}") @@ -634,7 +633,7 @@ def _acted_upon_(self, a, self_on_left): = \langle f, \phi_L (a \otimes x) \rangle, for `f \in H_m`, `a \in A^n`, and `x \in - H^{m-n}`. Somewhat more succintly, we define the action `f + H^{m-n}`. Somewhat more succinctly, we define the action `f \cdot a` by .. MATH:: @@ -934,7 +933,6 @@ def cup_product(self, other): sage: a,b = K.cohomology_ring(QQ).basis(2) sage: a**0 h^{0,0} + h^{0,1} - """ return self * other @@ -1282,7 +1280,7 @@ def steenrod_module_map(self, deg_domain, deg_codomain, side='left'): - ``deg_codomain`` -- the degree of the codomain in the cohomology ring - - ``side`` -- (default ``'left'``) whether we are computing + - ``side`` -- (default: ``'left'``) whether we are computing the action as a left module action or a right module We will write this with respect to the left action; @@ -1419,7 +1417,7 @@ def sum_indices(k, i_k_plus_one, S_k_plus_one): INPUT: - - ``k`` -- non-negative integer + - ``k`` -- nonnegative integer - ``i_k_plus_one`` -- the positive integer `i_{k+1}` - ``S_k_plus_one`` -- the integer `S(k+1)` diff --git a/src/sage/homology/koszul_complex.py b/src/sage/homology/koszul_complex.py index 22a1ceb5d80..005d876a04c 100644 --- a/src/sage/homology/koszul_complex.py +++ b/src/sage/homology/koszul_complex.py @@ -53,7 +53,7 @@ class KoszulComplex(ChainComplex_class, UniqueRepresentation): INPUT: - ``R`` -- the base ring - - ``elements`` -- a tuple of elements of ``R`` + - ``elements`` -- tuple of elements of `R` EXAMPLES:: diff --git a/src/sage/homology/matrix_utils.py b/src/sage/homology/matrix_utils.py index 4f10ae415a3..b44a25060d5 100644 --- a/src/sage/homology/matrix_utils.py +++ b/src/sage/homology/matrix_utils.py @@ -33,7 +33,7 @@ def dhsw_snf(mat, verbose=False): INPUT: - - ``mat`` -- an integer matrix, either sparse or dense. + - ``mat`` -- integer matrix, either sparse or dense (They use the transpose of the matrix considered here, so they use rows instead of columns.) @@ -56,7 +56,7 @@ def dhsw_snf(mat, verbose=False): Suppose that there were `N` of these. The resulting matrix should be much smaller; we then feed it - to Sage's ``elementary_divisors`` function, and prepend `N` 1's to + to Sage's ``elementary_divisors`` function, and prepend `N` 1s to account for the rows deleted in the previous step. EXAMPLES:: diff --git a/src/sage/homology/tests.py b/src/sage/homology/tests.py index 206617843a9..5ac7d67bfb2 100644 --- a/src/sage/homology/tests.py +++ b/src/sage/homology/tests.py @@ -17,10 +17,9 @@ def random_chain_complex(level=1): random matrix in a random degree, with differential of degree either 1 or -1. The matrix is randomly sparse or dense. - :param level: measure of complexity: the larger this is, the - larger the matrix can be, and the larger its degree can be in - the chain complex. - :type level: positive integer; optional, default 1 + - ``level`` -- positive integer (default: 1); measure of complexity. The larger + this is, the larger the matrix can be, and the larger its degree can be + in the chain complex. EXAMPLES:: @@ -47,12 +46,11 @@ def random_simplicial_complex(level=1, p=0.5): """ Return a random simplicial complex. - :param level: measure of complexity: the larger this is, the more - vertices and therefore the larger the possible dimension of the - complex. - :type level: positive integer; optional, default 1 - :param p: probability, passed on to ``simplicial_complexes.RandomComplex`` - :type p: float between 0 and 1; optional; default 0.5 + - ``level`` -- positive integer (default: 1); measure of complexity. The + larger this is, the more vertices and therefore the larger the possible + dimension of the complex. + - ``p`` -- float between 0 and 1 (default: 0.5); probability, passed on to + ``simplicial_complexes.RandomComplex`` EXAMPLES:: diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 16fadc5b594..7aa5ac779d9 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -153,7 +153,7 @@ def library_wrapper(): def html(obj): r""" - Shorthand to pretty print HTML + Shorthand to pretty print HTML. EXAMPLES:: @@ -231,9 +231,9 @@ def taylor_polynomial(title, f, order: int): @library_interact( title=lambda: text_control("

Definite integral

"), - f=lambda: input_box(default="3*x", label="$f(x)=$"), - g=lambda: input_box(default="x^2", label="$g(x)=$"), - interval=lambda: range_slider(-10, 10, default=(0, 3), label="Interval"), + f=lambda: input_box(default='3*x', label="$f(x)=$"), + g=lambda: input_box(default='x^2', label="$g(x)=$"), + interval=lambda: range_slider(-10, 10, default=(0, 3), label='Interval'), x_range=lambda: range_slider(-10, 10, default=(0, 3), label="plot range (x)"), selection=lambda: selector( ["f", "g", "f and g", "f - g"], default="f and g", label="Select" @@ -278,11 +278,11 @@ def definite_integral(title, f, g, interval, x_range, selection): # Plot function f. if selection != "g": - f_plot = plot(f(x), x, x_range, color="blue", thickness=1.5) + f_plot = plot(f(x), x, x_range, color='blue', thickness=1.5) # Color and calculate the area between f and the horizontal axis. if selection == "f" or selection == "f and g": - f_plot += plot(f(x), x, interval, color="blue", fill=True, fillcolor="blue", fillalpha=0.15) + f_plot += plot(f(x), x, interval, color='blue', fill=True, fillcolor='blue', fillalpha=0.15) text += r"$\int_{%.2f}^{%.2f}(\color{Blue}{f(x)})\,\mathrm{d}x=\int_{%.2f}^{%.2f}(%s)\,\mathrm{d}x=%.2f$" % ( interval[0], interval[1], interval[0], interval[1], @@ -295,8 +295,8 @@ def definite_integral(title, f, g, interval, x_range, selection): # Plot function g. Also color and calculate the area between g and the horizontal axis. if selection == "g" or selection == "f and g": - g_plot = plot(g(x), x, x_range, color="green", thickness=1.5) - g_plot += plot(g(x), x, interval, color="green", fill=True, fillcolor="yellow", fillalpha=0.5) + g_plot = plot(g(x), x, x_range, color='green', thickness=1.5) + g_plot += plot(g(x), x, interval, color='green', fill=True, fillcolor='yellow', fillalpha=0.5) text += r"$\int_{%.2f}^{%.2f}(\color{Green}{g(x)})\,\mathrm{d}x=\int_{%.2f}^{%.2f}(%s)\,\mathrm{d}x=%.2f$" % ( interval[0], interval[1], interval[0], interval[1], @@ -306,9 +306,9 @@ def definite_integral(title, f, g, interval, x_range, selection): # Plot function f-g. Also color and calculate the area between f-g and the horizontal axis. if selection == "f - g": - g_plot = plot(g(x), x, x_range, color="green", thickness=1.5) - g_plot += plot(g(x), x, interval, color="green", fill=f(x), fillcolor="red", fillalpha=0.15) - h_plot = plot(f(x)-g(x), x, interval, color="red", thickness=1.5, fill=True, fillcolor="red", fillalpha=0.15) + g_plot = plot(g(x), x, x_range, color='green', thickness=1.5) + g_plot += plot(g(x), x, interval, color='green', fill=f(x), fillcolor='red', fillalpha=0.15) + h_plot = plot(f(x)-g(x), x, interval, color='red', thickness=1.5, fill=True, fillcolor='red', fillalpha=0.15) text = r"$\int_{%.2f}^{%.2f}(\color{Red}{f(x)-g(x)})\,\mathrm{d}x=\int_{%.2f}^{%.2f}(%s)\,\mathrm{d}x=%.2f$" % ( interval[0], interval[1], interval[0], interval[1], @@ -322,7 +322,7 @@ def definite_integral(title, f, g, interval, x_range, selection): @library_interact( title=lambda: text_control("

Derivative grapher

"), - function=lambda: input_box(default="x^5-3*x^3+1", label="Function:"), + function=lambda: input_box(default='x^5-3*x^3+1', label='Function:'), x_range=lambda: range_slider(-15, 15, 0.1, default=(-2, 2), label="Range (x)"), y_range=lambda: range_slider(-15, 15, 0.1, default=(-8, 6), label="Range (y)"), ) @@ -355,7 +355,7 @@ def function_derivative(title, function, x_range, y_range): f = symbolic_expression(function).function(x) df = derivative(f, x) ddf = derivative(df, x) - plots = plot(f(x), x_range, thickness=1.5) + plot(df(x), x_range, color="green") + plot(ddf(x), x_range, color="red") + plots = plot(f(x), x_range, thickness=1.5) + plot(df(x), x_range, color='green') + plot(ddf(x), x_range, color='red') if y_range == (0,0): show(plots, xmin=x_range[0], xmax=x_range[1]) else: @@ -368,9 +368,9 @@ def function_derivative(title, function, x_range, y_range): @library_interact( title=lambda: text_control("

Difference quotient

"), - f=lambda: input_box(default="sin(x)", label="f(x)"), - interval=lambda: range_slider(0, 10, 0.1, default=(0.0, 10.0), label="Range"), - a=lambda: slider(0, 10, None, 5.5, label="$a$"), + f=lambda: input_box(default='sin(x)', label="f(x)"), + interval=lambda: range_slider(0, 10, 0.1, default=(0.0, 10.0), label='Range'), + a=lambda: slider(0, 10, None, 5.5, label='$a$'), x0=lambda: slider(0, 10, None, 2.5, label="$x_0$ (start point)"), ) def difference_quotient(title, f, interval, a, x0): @@ -413,19 +413,19 @@ def difference_quotient(title, f, interval, a, x0): f_height = fmax - fmin measure_y = fmin - 0.1*f_height - measure_0 = line2d([(x0, measure_y), (a, measure_y)], rgbcolor="black") - measure_1 = line2d([(x0, measure_y + 0.02*f_height), (x0, measure_y-0.02*f_height)], rgbcolor="black") - measure_2 = line2d([(a, measure_y + 0.02*f_height), (a, measure_y-0.02*f_height)], rgbcolor="black") - text_x0 = text("x0", (x0, measure_y - 0.05*f_height), rgbcolor="black") - text_a = text("a", (a, measure_y - 0.05*f_height), rgbcolor="black") + measure_0 = line2d([(x0, measure_y), (a, measure_y)], rgbcolor='black') + measure_1 = line2d([(x0, measure_y + 0.02*f_height), (x0, measure_y-0.02*f_height)], rgbcolor='black') + measure_2 = line2d([(a, measure_y + 0.02*f_height), (a, measure_y-0.02*f_height)], rgbcolor='black') + text_x0 = text("x0", (x0, measure_y - 0.05*f_height), rgbcolor='black') + text_a = text("a", (a, measure_y - 0.05*f_height), rgbcolor='black') measure = measure_0 + measure_1 + measure_2 + text_x0 + text_a tanf = symbolic_expression((f(x0)-f(a))*(x-a)/(x0-a)+f(a)).function(x) fplot = plot(f(x), x, interval[0], interval[1]) - tanplot = plot(tanf(x), x, interval[0], interval[1], rgbcolor="#FF0000") - points = point([(x0, f(x0)), (a, f(a))], pointsize=20, rgbcolor="#005500") - dashline = line2d([(x0, f(x0)), (x0, f(a)), (a, f(a))], rgbcolor="#005500", linestyle="--") + tanplot = plot(tanf(x), x, interval[0], interval[1], rgbcolor='#FF0000') + points = point([(x0, f(x0)), (a, f(a))], pointsize=20, rgbcolor='#005500') + dashline = line2d([(x0, f(x0)), (x0, f(a)), (a, f(a))], rgbcolor='#005500', linestyle='--') html('

Difference Quotient

') show(fplot + tanplot + points + dashline + measure, xmin=interval[0], xmax=interval[1], ymin=fmin-0.2*f_height, ymax=fmax) html(r"
$\text{Line's equation:}$") @@ -497,9 +497,9 @@ def quadratic_equation(A, B, C): html(calc % (B, dis1, A, B, dis2, (2*A), sol)) @library_interact( - a0=lambda: slider(0, 360, 1, 30, label="A"), - a1=lambda: slider(0, 360, 1, 180, label="B"), - a2=lambda: slider(0, 360, 1, 300, label="C"), + a0=lambda: slider(0, 360, 1, 30, label='A'), + a1=lambda: slider(0, 360, 1, 180, label='B'), + a2=lambda: slider(0, 360, 1, 300, label='C'), ) def trigonometric_properties_triangle(a0, a1, a2): r""" @@ -563,7 +563,7 @@ def area(alpha, a, b): unit_circle = circle((0, 0), 1, aspect_ratio=1) # Triangle - triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor="black") + triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor='black') triangle_points = point(xy, pointsize=30) # Labels of the angles drawn in a distance from points @@ -612,41 +612,41 @@ def unit_circle(function, x): # Unit Circle C = circle((0, 0), 1, figsize=[5, 5], aspect_ratio=1) - C_line = line([(0, 0), (xy[0], xy[1])], rgbcolor="black") - C_point = point((xy[0], xy[1]), pointsize=40, rgbcolor="green") - C_inner = parametric_plot((cos(t), sin(t)), (t, 0, x + 0.001), color="green", thickness=3) - C_outer = parametric_plot((0.1 * cos(t), 0.1 * sin(t)), (t, 0, x + 0.001), color="black") + C_line = line([(0, 0), (xy[0], xy[1])], rgbcolor='black') + C_point = point((xy[0], xy[1]), pointsize=40, rgbcolor='green') + C_inner = parametric_plot((cos(t), sin(t)), (t, 0, x + 0.001), color='green', thickness=3) + C_outer = parametric_plot((0.1 * cos(t), 0.1 * sin(t)), (t, 0, x + 0.001), color='black') C_graph = C + C_line + C_point + C_inner + C_outer # Graphics related to the graph of the function - G_line = line([(0, 0), (x, 0)], rgbcolor="green", thickness=3) - G_point = point((x, 0), pointsize=30, rgbcolor="green") + G_line = line([(0, 0), (x, 0)], rgbcolor='green', thickness=3) + G_point = point((x, 0), pointsize=30, rgbcolor='green') G_graph = G_line + G_point # Sine if function == 0: Gf = plot(sin(t), t, 0, 2*pi, axes_labels=("x", "sin(x)")) - Gf_point = point((x, sin(x)), pointsize=30, rgbcolor="red") - Gf_line = line([(x, 0),(x, sin(x))], rgbcolor="red") - Cf_point = point((0, xy[1]), pointsize=40, rgbcolor="red") - Cf_line1 = line([(0, 0), (0, xy[1])], rgbcolor="red", thickness=3) - Cf_line2 = line([(0, xy[1]), (xy[0], xy[1])], rgbcolor="purple", linestyle="--") + Gf_point = point((x, sin(x)), pointsize=30, rgbcolor='red') + Gf_line = line([(x, 0),(x, sin(x))], rgbcolor='red') + Cf_point = point((0, xy[1]), pointsize=40, rgbcolor='red') + Cf_line1 = line([(0, 0), (0, xy[1])], rgbcolor='red', thickness=3) + Cf_line2 = line([(0, xy[1]), (xy[0], xy[1])], rgbcolor='purple', linestyle='--') # Cosine elif function == 1: Gf = plot(cos(t), t, 0, 2*pi, axes_labels=("x", "cos(x)")) - Gf_point = point((x, cos(x)), pointsize=30, rgbcolor="red") - Gf_line = line([(x, 0), (x, cos(x))], rgbcolor="red") - Cf_point = point((xy[0], 0), pointsize=40, rgbcolor="red") - Cf_line1 = line([(0, 0), (xy[0], 0)], rgbcolor="red", thickness=3) - Cf_line2 = line([(xy[0], 0), (xy[0], xy[1])], rgbcolor="purple", linestyle="--") + Gf_point = point((x, cos(x)), pointsize=30, rgbcolor='red') + Gf_line = line([(x, 0), (x, cos(x))], rgbcolor='red') + Cf_point = point((xy[0], 0), pointsize=40, rgbcolor='red') + Cf_line1 = line([(0, 0), (xy[0], 0)], rgbcolor='red', thickness=3) + Cf_line2 = line([(xy[0], 0), (xy[0], xy[1])], rgbcolor='purple', linestyle='--') # Tangent else: Gf = plot(tan(t), t, 0, 2*pi, ymin=-8, ymax=8, axes_labels=("x", "tan(x)")) - Gf_point = point((x, tan(x)), pointsize=30, rgbcolor="red") - Gf_line = line([(x, 0), (x, tan(x))], rgbcolor="red") - Cf_point = point((1, tan(x)), pointsize=40, rgbcolor="red") - Cf_line1 = line([(1, 0), (1, tan(x))], rgbcolor="red", thickness=3) - Cf_line2 = line([(xy[0], xy[1]), (1, tan(x))], rgbcolor="purple", linestyle="--") + Gf_point = point((x, tan(x)), pointsize=30, rgbcolor='red') + Gf_line = line([(x, 0), (x, tan(x))], rgbcolor='red') + Cf_point = point((1, tan(x)), pointsize=40, rgbcolor='red') + Cf_line1 = line([(1, 0), (1, tan(x))], rgbcolor='red', thickness=3) + Cf_line2 = line([(xy[0], xy[1]), (1, tan(x))], rgbcolor='purple', linestyle='--') C_graph += Cf_point + Cf_line1 + Cf_line2 G_graph += Gf + Gf_point + Gf_line @@ -656,14 +656,14 @@ def unit_circle(function, x): @library_interact( title=lambda: text_control("

Special points in triangle

"), - a0=lambda: slider(0, 360, 1, 30, label="A"), - a1=lambda: slider(0, 360, 1, 180, label="B"), - a2=lambda: slider(0, 360, 1, 300, label="C"), - show_median=lambda: checkbox(False, label="Medians"), + a0=lambda: slider(0, 360, 1, 30, label='A'), + a1=lambda: slider(0, 360, 1, 180, label='B'), + a2=lambda: slider(0, 360, 1, 300, label='C'), + show_median=lambda: checkbox(False, label='Medians'), show_pb=lambda: checkbox(False, label="Perpendicular Bisectors"), - show_alt=lambda: checkbox(False, label="Altitudes"), + show_alt=lambda: checkbox(False, label='Altitudes'), show_ab=lambda: checkbox(False, label="Angle Bisectors"), - show_incircle=lambda: checkbox(False, label="Incircle"), + show_incircle=lambda: checkbox(False, label='Incircle'), show_euler=lambda: checkbox(False, label="Euler's Line"), ) def special_points( @@ -749,7 +749,7 @@ def line_to_points(x1_y1, x2_y2, **plot_kwargs): C = circle((0, 0), 1, aspect_ratio=1) # Triangle - triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor="black") + triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor='black') triangle_points = point(xy, pointsize=30) # Side lengths (bc, ca, ab) corresponding to triangle vertices (a, b, c) @@ -778,34 +778,34 @@ def line_to_points(x1_y1, x2_y2, **plot_kwargs): # Angle Bisectors if show_ab: - a_ab = line([xy[0], half(a, 1, 2, 0)], rgbcolor="blue", alpha=0.6) - b_ab = line([xy[1], half(a, 2, 0, 1)], rgbcolor="blue", alpha=0.6) - c_ab = line([xy[2], half(a, 0, 1, 2)], rgbcolor="blue", alpha=0.6) - ab_point = point(incircle_center, rgbcolor="blue", pointsize=28) + a_ab = line([xy[0], half(a, 1, 2, 0)], rgbcolor='blue', alpha=0.6) + b_ab = line([xy[1], half(a, 2, 0, 1)], rgbcolor='blue', alpha=0.6) + c_ab = line([xy[2], half(a, 0, 1, 2)], rgbcolor='blue', alpha=0.6) + ab_point = point(incircle_center, rgbcolor='blue', pointsize=28) ab_graph = a_ab + b_ab + c_ab + ab_point else: ab_graph = Graphics() # Medians if show_median: - a_median = line([xy[0], a_middle[0]], rgbcolor="green", alpha=0.6) - b_median = line([xy[1], a_middle[1]], rgbcolor="green", alpha=0.6) - c_median = line([xy[2], a_middle[2]], rgbcolor="green", alpha=0.6) + a_median = line([xy[0], a_middle[0]], rgbcolor='green', alpha=0.6) + b_median = line([xy[1], a_middle[1]], rgbcolor='green', alpha=0.6) + c_median = line([xy[2], a_middle[2]], rgbcolor='green', alpha=0.6) median_point = point( ( (xy[0][0]+xy[1][0]+xy[2][0])/3.0, (xy[0][1]+xy[1][1]+xy[2][1])/3.0 - ), rgbcolor="green", pointsize=28) + ), rgbcolor='green', pointsize=28) median_graph = a_median + b_median + c_median + median_point else: median_graph = Graphics() # Perpendicular Bisectors if show_pb: - a_pb = line_to_points(a_middle[0], half(a, 1, 2, 0), rgbcolor="red", alpha=0.6) - b_pb = line_to_points(a_middle[1], half(a, 2, 0, 1), rgbcolor="red", alpha=0.6) - c_pb = line_to_points(a_middle[2], half(a, 0, 1, 2), rgbcolor="red", alpha=0.6) - pb_point = point((0, 0), rgbcolor="red", pointsize=28) + a_pb = line_to_points(a_middle[0], half(a, 1, 2, 0), rgbcolor='red', alpha=0.6) + b_pb = line_to_points(a_middle[1], half(a, 2, 0, 1), rgbcolor='red', alpha=0.6) + c_pb = line_to_points(a_middle[2], half(a, 0, 1, 2), rgbcolor='red', alpha=0.6) + pb_point = point((0, 0), rgbcolor='red', pointsize=28) pb_graph = a_pb + b_pb + c_pb + pb_point else: pb_graph = Graphics() @@ -814,12 +814,12 @@ def line_to_points(x1_y1, x2_y2, **plot_kwargs): if show_alt: xA, xB, xC = xy[0][0], xy[1][0], xy[2][0] yA, yB, yC = xy[0][1], xy[1][1], xy[2][1] - a_alt = plot(((xC-xB)*x+(xB-xC)*xA)/(yB-yC)+yA, (x,-3,3), rgbcolor="brown", alpha=0.6) - b_alt = plot(((xA-xC)*x+(xC-xA)*xB)/(yC-yA)+yB, (x,-3,3), rgbcolor="brown", alpha=0.6) - c_alt = plot(((xB-xA)*x+(xA-xB)*xC)/(yA-yB)+yC, (x,-3,3), rgbcolor="brown", alpha=0.6) + a_alt = plot(((xC-xB)*x+(xB-xC)*xA)/(yB-yC)+yA, (x,-3,3), rgbcolor='brown', alpha=0.6) + b_alt = plot(((xA-xC)*x+(xC-xA)*xB)/(yC-yA)+yB, (x,-3,3), rgbcolor='brown', alpha=0.6) + c_alt = plot(((xB-xA)*x+(xA-xB)*xC)/(yA-yB)+yC, (x,-3,3), rgbcolor='brown', alpha=0.6) alt_lx = (xA*xB*(yA-yB)+xB*xC*(yB-yC)+xC*xA*(yC-yA)-(yA-yB)*(yB-yC)*(yC-yA))/(xC*yB-xB*yC+xA*yC-xC*yA+xB*yA-xA*yB) alt_ly = (yA*yB*(xA-xB)+yB*yC*(xB-xC)+yC*yA*(xC-xA)-(xA-xB)*(xB-xC)*(xC-xA))/(yC*xB-yB*xC+yA*xC-yC*xA+yB*xA-yA*xB) - alt_intersection = point((alt_lx, alt_ly), rgbcolor="brown", pointsize=28) + alt_intersection = point((alt_lx, alt_ly), rgbcolor='brown', pointsize=28) alt_graph = a_alt + b_alt + c_alt + alt_intersection else: alt_graph = Graphics() @@ -832,7 +832,7 @@ def line_to_points(x1_y1, x2_y2, **plot_kwargs): (xy[0][0]+xy[1][0]+xy[2][0])/3.0, (xy[0][1]+xy[1][1]+xy[2][1])/3.0 ), - rgbcolor="purple", + rgbcolor='purple', thickness=2, alpha=0.7 ) @@ -892,7 +892,7 @@ def coin(n, interval): @library_interact( title=lambda: text_control("

Bisection method

"), f=lambda: input_box("x^2-2", label="f(x)"), - interval=lambda: range_slider(-5, 5, default=(0, 4), label="range"), + interval=lambda: range_slider(-5, 5, default=(0, 4), label='range'), d=lambda: slider(1, 8, 1, 3, label="$10^{-d}$ precision"), maxn=lambda: slider(0, 50, 1, 10, label="max iterations"), ) @@ -971,7 +971,7 @@ def _bisection_method(f, a, b, maxn, eps): @library_interact( title=lambda: text_control("

Secant method for numerical root finding

"), f=lambda: input_box("x^2-2", label="f(x)"), - interval=lambda: range_slider(-5, 5, default=(0, 4), label="range"), + interval=lambda: range_slider(-5, 5, default=(0, 4), label='range'), d=lambda: slider(1, 16, 1, 3, label="10^-d precision"), maxn=lambda: slider(0, 15, 1, 10, label="max iterations"), ) @@ -1033,7 +1033,7 @@ def _secant_method(f, a, b, maxn, h): L = sum(line([(c,k*i), (d,k*i)]) for i, (c,d) in enumerate(intervals) ) L += sum(line([(c,k*i-k/4), (c,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) L += sum(line([(d,k*i-k/4), (d,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) - S = sum(line([(c,f(c)), (d,f(d)), (d-(d-c)*f(d)/(f(d)-f(c)), 0)], color="green") for (c, d) in intervals) + S = sum(line([(c,f(c)), (d,f(d)), (d-(d-c)*f(d)/(f(d)-f(c)), 0)], color='green') for (c, d) in intervals) show(P + L + S, xmin=a, xmax=b) @@ -1043,7 +1043,7 @@ def _secant_method(f, a, b, maxn, h): c=lambda: slider(-10, 10, default=6, label="Start ($x$)"), d=lambda: slider(1, 16, 1, 3, label="$10^{-d}$ precision"), maxn=lambda: slider(0, 15, 1, 10, label="max iterations"), - interval=lambda: range_slider(-10, 10, default=(0, 6), label="Interval"), + interval=lambda: range_slider(-10, 10, default=(0, 6), label='Interval'), list_steps=lambda: checkbox(default=False, label="List steps"), ) def newton_method(title, f, c, d, maxn, interval, list_steps): @@ -1059,7 +1059,7 @@ def newton_method(title, f, c, d, maxn, interval, list_steps): - ``d`` -- slider for the precision (`10^{-d}`) - ``maxn`` -- max number of iterations - ``interval`` -- range slider for the search interval - - ``list_steps`` -- checkbox, if true shows the steps numerically + - ``list_steps`` -- checkbox, if ``True`` shows the steps numerically EXAMPLES: @@ -1104,10 +1104,10 @@ def _newton_method(f, c, maxn, h): s.append([i+1, c, f(c), (c-h)*f(c+h)]) pretty_print(table(s, header_row=True)) else: - P = plot(f, x, interval, color="blue") - L = sum(line([(c, 0), (c, f(c))], color="green") for c in midpoints[:-1]) + P = plot(f, x, interval, color='blue') + L = sum(line([(c, 0), (c, f(c))], color='green') for c in midpoints[:-1]) for i in range(len(midpoints) - 1): - L += line([(midpoints[i], f(midpoints[i])), (midpoints[i+1], 0)], color="red") + L += line([(midpoints[i], f(midpoints[i])), (midpoints[i+1], 0)], color='red') show(P + L, xmin=interval[0], xmax=interval[1], ymin=P.ymin(), ymax=P.ymax()) @@ -1240,7 +1240,7 @@ def trapezoid_integration( @library_interact( title=lambda: text_control("

Simpson integration

"), - f=lambda: input_box(default="x*sin(x)+x+1", label="$f(x)=$"), + f=lambda: input_box(default='x*sin(x)+x+1', label="$f(x)=$"), n=lambda: slider(2, 100, 2, 6, label="# divisions"), interval_input=lambda: selector( ["from slider", "from keyboard"], @@ -1321,11 +1321,11 @@ def parabola(a, b, c): for i in range(0, n-1, 2): p = parabola((xs[i],ys[i]),(xs[i+1],ys[i+1]),(xs[i+2],ys[i+2])) - parabolas += plot(p(x=x), (x, xs[i], xs[i+2]), color="red") - lines += line([(xs[i],ys[i]), (xs[i],0), (xs[i+2],0)],color="red") - lines += line([(xs[i+1],ys[i+1]), (xs[i+1],0)], linestyle="-.", color="red") + parabolas += plot(p(x=x), (x, xs[i], xs[i+2]), color='red') + lines += line([(xs[i],ys[i]), (xs[i],0), (xs[i+2],0)],color='red') + lines += line([(xs[i+1],ys[i+1]), (xs[i+1],0)], linestyle='-.', color='red') - lines += line([(xs[-1],ys[-1]), (xs[-1],0)], color="red") + lines += line([(xs[-1],ys[-1]), (xs[-1],0)], color='red') html(r'Function $f(x)=%s$' % latex(f(x))) @@ -1393,7 +1393,7 @@ def parabola(a, b, c): @library_interact( title=lambda: text_control("

Riemann integral with random sampling

"), - f=lambda: input_box("x^2+1", label="$f(x)=$", width=40), + f=lambda: input_box("x^2+1", label='$f(x)=$', width=40), n=lambda: slider(1, 30, 1, 5, label="# divisions"), hr1=lambda: text_control("
"), interval_input=lambda: selector( @@ -1420,7 +1420,7 @@ def riemann_sum( auto_update=False, ): r""" - Interact explaining the definition of Riemann integral + Interact explaining the definition of Riemann integral. INPUT: @@ -1464,12 +1464,13 @@ def riemann_sum( b = interval_g[0][1] func = symbolic_expression(f).function(x) division = [a]+[a+random()*(b-a) for i in range(n-1)]+[b] - division = sorted([i for i in division]) + division = sorted(division) xs = [division[i]+random()*(division[i+1]-division[i]) for i in range(n)] ys = [func(x_val) for x_val in xs] rects = Graphics() for i in range(n): - body = [[division[i],0],[division[i],ys[i]],[division[i+1],ys[i]],[division[i+1],0]] + body = [[division[i], 0], [division[i], ys[i]], + [division[i+1], ys[i]], [division[i+1], 0]] if ys[i].n() > 0: color_rect = 'green' else: @@ -1486,7 +1487,7 @@ def riemann_sum( ["$i$", "$[x_{i-1},x_i]$", r"$\eta_i$", r"$f(\eta_i)$", "$x_{i}-x_{i-1}$"] ] + [ [i+1,[division[i],division[i+1]],xs[i],ys[i],delka_intervalu[i]] for i in range(n) - ], header_row=True)) + ], header_row=True)) html(r'Riemann sum: $\displaystyle\sum_{i=1}^{%s} f(\eta_i)(x_i-x_{i-1})=%s$ ' % (latex(n),latex(sum([ys[i]*delka_intervalu[i] for i in range(n)])))) @@ -1500,7 +1501,7 @@ def riemann_sum( @library_interact( f=lambda: sin(x), g=lambda: cos(x), - xrange=lambda: range_slider(-3, 3, default=(0, 1), label="x-range"), + xrange=lambda: range_slider(-3, 3, default=(0, 1), label='x-range'), yrange=lambda: "auto", a=lambda: 1, action=lambda: selector( @@ -1544,7 +1545,7 @@ def function_tool(f, g, xrange, yrange, a, action, do_plot): - ``yrange`` -- range for plotting ('auto' is default, otherwise a tuple) - ``a`` -- factor ``a`` - ``action`` -- select given operation on or combination of functions - - ``do_plot`` -- if true, a plot is drawn + - ``do_plot`` -- if ``True``, a plot is drawn EXAMPLES: @@ -1658,7 +1659,7 @@ def function_tool(f, g, xrange, yrange, a, action, do_plot): zoom_x=lambda: range_slider(-2, 2, 0.01, (-1.5, 1.5), label="Zoom X"), zoom_y=lambda: range_slider(-2, 2, 0.01, (-1.5, 1.5), label="Zoom Y"), plot_points=lambda: slider(20, 400, 20, default=150, label="plot points"), - dpi=lambda: slider(20, 200, 10, default=80, label="dpi"), + dpi=lambda: slider(20, 200, 10, default=80, label='dpi'), ) def julia(expo, c_real, c_imag, iterations, zoom_x, zoom_y, plot_points, dpi): r""" @@ -1712,7 +1713,7 @@ def julia(expo, c_real, c_imag, iterations, zoom_x, zoom_y, plot_points, dpi): zoom_x=lambda: range_slider(-2, 2, 0.01, (-2, 1), label="Zoom X"), zoom_y=lambda: range_slider(-2, 2, 0.01, (-1.5, 1.5), label="Zoom Y"), plot_points=lambda: slider(20, 400, 20, default=150, label="plot points"), - dpi=lambda: slider(20, 200, 10, default=80, label="dpi"), + dpi=lambda: slider(20, 200, 10, default=80, label='dpi'), ) def mandelbrot(expo, iterations, zoom_x, zoom_y, plot_points, dpi): r""" @@ -1809,12 +1810,12 @@ def cellular_automaton(N, rule_number, size): @library_interact( - interval=lambda: range_slider(1, 4000, 10, default=(1, 1000), label="range"), + interval=lambda: range_slider(1, 4000, 10, default=(1, 1000), label='range'), show_factors=lambda: True, highlight_primes=lambda: True, show_curves=lambda: True, n=lambda: slider(1, 200, 1, default=89, label="number $n$"), - dpi=lambda: slider(10, 300, 10, default=100, label="dpi"), + dpi=lambda: slider(10, 300, 10, default=100, label='dpi'), ) def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n, dpi): r""" @@ -1826,9 +1827,9 @@ def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n, INPUT: - ``interval`` -- range slider to specify start and end - - ``show_factors`` -- if true, show factors - - ``highlight_primes`` -- if true, prime numbers are highlighted - - ``show_curves`` -- if true, curves are plotted + - ``show_factors`` -- if ``True``, show factors + - ``highlight_primes`` -- if ``True``, prime numbers are highlighted + - ``show_curves`` -- if ``True``, curves are plotted - ``n`` -- number `n` - ``dpi`` -- dots per inch resolution for plotting diff --git a/src/sage/interacts/library_cython.pyx b/src/sage/interacts/library_cython.pyx index 6647629d44c..52c68dd5922 100644 --- a/src/sage/interacts/library_cython.pyx +++ b/src/sage/interacts/library_cython.pyx @@ -62,7 +62,6 @@ cpdef mandel(ff_m, z, int iterations): sage: ff_m = fast_callable(f, vars=[z,c], domain=CDF) sage: mandel(ff_m, CDF(1,1), 3) 1.0 + 3.0*I - """ c = z for i in range(iterations): diff --git a/src/sage/interacts/meson.build b/src/sage/interacts/meson.build new file mode 100644 index 00000000000..4889c06f9fa --- /dev/null +++ b/src/sage/interacts/meson.build @@ -0,0 +1,24 @@ +py.install_sources( + 'algebra.py', + 'all.py', + 'calculus.py', + 'fractals.py', + 'geometry.py', + 'library.py', + 'statistics.py', + subdir: 'sage/interacts', +) + +extension_data = {'library_cython' : files('library_cython.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/interacts', + install: true, + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index 1a707eb1d16..461d8a342bd 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -25,7 +25,7 @@ - Bill Page (2006-10): Created this (based on Maxima interface) - .. note:: + .. NOTE:: Bill Page put a huge amount of effort into the Sage Axiom interface over several days during the Sage Days 2 coding @@ -35,7 +35,7 @@ - Bill Page (2007-08): Minor modifications to support axiom4sage-0.3 -.. note:: +.. NOTE:: The axiom4sage-0.3.spkg is based on an experimental version of the FriCAS fork of the Axiom project by Waldek Hebisch that uses @@ -43,7 +43,7 @@ clisp. If the string "error" (case insensitive) occurs in the output of -anything from axiom, a :class:`RuntimeError` exception is raised. +anything from axiom, a :exc:`RuntimeError` exception is raised. EXAMPLES: We evaluate a very simple expression in axiom. @@ -279,7 +279,7 @@ def _read_in_file_command(self, filename): def _quit_string(self): """ - Returns the string used to quit Axiom. + Return the string used to quit Axiom. EXAMPLES:: @@ -299,7 +299,7 @@ def _quit_string(self): def _commands(self): """ - Returns a list of commands available. This is done by parsing the + Return a list of commands available. This is done by parsing the result of the first section of the output of ')what things'. EXAMPLES:: @@ -322,7 +322,7 @@ def _commands(self): def _tab_completion(self, verbose=True, use_disk_cache=True): """ - Returns a list of all the commands defined in Axiom and optionally + Return a list of all the commands defined in Axiom and optionally (per default) store them to disk. EXAMPLES:: @@ -383,7 +383,6 @@ def set(self, var, value): sage: axiom.set('xx', '2') #optional - axiom sage: axiom.get('xx') #optional - axiom '2' - """ cmd = '%s := %s' % (var, value) out = self._eval_line(cmd, reformat=False) @@ -525,7 +524,7 @@ def _object_class(self): def _function_element_class(self): """ - Returns the Axiom function element class. + Return the Axiom function element class. EXAMPLES:: @@ -615,7 +614,7 @@ def _richcmp_(self, other, op): def type(self): """ - Returns the type of an AxiomElement. + Return the type of an AxiomElement. EXAMPLES:: @@ -644,9 +643,9 @@ def __len__(self): def __getitem__(self, n): r""" - Return the n-th element of this list. + Return the `n`-th element of this list. - .. note:: + .. NOTE:: Lists are 1-based. @@ -677,7 +676,7 @@ def __getitem__(self, n): def comma(self, *args): """ - Returns a Axiom tuple from self and args. + Return an Axiom tuple from ``self`` and ``args``. EXAMPLES:: @@ -724,7 +723,7 @@ def _latex_(self): def as_type(self, type): """ - Returns self as type. + Return ``self`` as type. EXAMPLES:: @@ -734,7 +733,6 @@ def as_type(self, type): 1.2 sage: _.type() #optional - axiom DoubleFloat - """ P = self._check_valid() type = P(type) @@ -752,7 +750,6 @@ def unparsed_input_form(self): x + 1 sage: a.unparsed_input_form() #optional - axiom 'x*x+1' - """ P = self._check_valid() s = P.eval('unparse(%s::InputForm)' % self._name) @@ -768,7 +765,7 @@ def unparsed_input_form(self): def _sage_(self): """ - Convert self to a Sage object. + Convert ``self`` to a Sage object. EXAMPLES:: @@ -824,8 +821,6 @@ def _sage_(self): y^2 + x^2 + 1/2 sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field - - """ P = self._check_valid() type = str(self.type()) @@ -949,7 +944,7 @@ def __init__(self, parent, name): def is_AxiomElement(x): """ - Return True if ``x`` is of type :class:`AxiomElement`. + Return ``True`` if ``x`` is of type :class:`AxiomElement`. EXAMPLES:: @@ -973,7 +968,7 @@ def is_AxiomElement(x): def reduce_load_Axiom(): """ - Returns the Axiom interface object defined in + Return the Axiom interface object defined in sage.interfaces.axiom. EXAMPLES:: @@ -1000,7 +995,6 @@ def axiom_console(): Issue )summary for a summary of useful system commands. Issue )quit to leave AXIOM and return to shell. ----------------------------------------------------------------------------- - """ from sage.repl.rich_output.display_manager import get_display_manager if not get_display_manager().is_in_terminal(): diff --git a/src/sage/interfaces/cleaner.py b/src/sage/interfaces/cleaner.py index 54bfac779ac..f731205b652 100644 --- a/src/sage/interfaces/cleaner.py +++ b/src/sage/interfaces/cleaner.py @@ -1,3 +1,4 @@ +# sage_setup: distribution = sagemath-repl """ Interface to the Sage cleaner diff --git a/src/sage/interfaces/ecm.py b/src/sage/interfaces/ecm.py index ae1379861f2..7d1ac74b7c1 100644 --- a/src/sage/interfaces/ecm.py +++ b/src/sage/interfaces/ecm.py @@ -68,116 +68,116 @@ def __init__(self, B1=10, B2=None, **kwds): INPUT: - - ``B1`` -- integer. Stage 1 bound + - ``B1`` -- integer; Stage 1 bound - - ``B2`` -- integer. Stage 2 bound (or interval B2min-B2max) + - ``B2`` -- integer; Stage 2 bound (or interval B2min-B2max) In addition the following keyword arguments can be used: - - ``x0`` -- integer `x`. use `x` as initial point + - ``x0`` -- integer `x`; use `x` as initial point - - ``sigma`` -- integer `s`. Use s as curve generator [ecm] + - ``sigma`` -- integer `s`; use s as curve generator [ecm] - - ``A`` -- integer `a`. Use a as curve parameter [ecm] + - ``A`` -- integer `a`; use a as curve parameter [ecm] - - ``k`` -- integer `n`. Perform `>= n` steps in stage 2 + - ``k`` -- integer `n`; perform `>= n` steps in stage 2 - - ``power`` -- integer `n`. Use `x^n` for Brent-Suyama's + - ``power`` -- integer `n`; use `x^n` for Brent-Suyama's extension - - ``dickson`` -- integer `n`. Use `n`-th Dickson's polynomial + - ``dickson`` -- integer `n`; use `n`-th Dickson's polynomial for Brent-Suyama's extension - - ``c`` -- integer `n`. Perform `n` runs for each input + - ``c`` -- integer `n`; perform `n` runs for each input - - ``pm1`` -- boolean. perform P-1 instead of ECM + - ``pm1`` -- boolean; perform P-1 instead of ECM - - ``pp1`` -- boolean. perform P+1 instead of ECM + - ``pp1`` -- boolean; perform P+1 instead of ECM - - ``q`` -- boolean. quiet mode + - ``q`` -- boolean; quiet mode - - ``v`` -- boolean. verbose mode + - ``v`` -- boolean; verbose mode - - ``timestamp`` -- boolean. print a time stamp with each number + - ``timestamp`` -- boolean; print a time stamp with each number - - ``mpzmod`` -- boolean. use GMP's mpz_mod for mod reduction + - ``mpzmod`` -- boolean; use GMP's mpz_mod for mod reduction - - ``modmuln`` -- boolean. use Montgomery's MODMULN for mod reduction + - ``modmuln`` -- boolean; use Montgomery's MODMULN for mod reduction - - ``redc`` -- boolean. use Montgomery's REDC for mod reduction + - ``redc`` -- boolean; use Montgomery's REDC for mod reduction - - ``nobase2`` -- boolean. Disable special base-2 code + - ``nobase2`` -- boolean; disable special base-2 code - - ``base2`` -- integer `n`. Force base 2 mode with 2^n+1 (n>0) + - ``base2`` -- integer `n`; force base 2 mode with 2^n+1 (n>0) or 2^n-1 (n<0) - - ``save`` -- string filename. Save residues at end of stage 1 + - ``save`` -- string filename; save residues at end of stage 1 to file - - ``savea`` -- string filename. Like -save, appends to + - ``savea`` -- string filename; Like -save, appends to existing files - - ``resume`` -- string filename. Resume residues from file, + - ``resume`` -- string filename; resume residues from file, reads from stdin if file is "-" - - ``primetest`` -- boolean. Perform a primality test on input + - ``primetest`` -- boolean; perform a primality test on input - - ``treefile`` -- string. Store product tree of F in files f.0 + - ``treefile`` -- string; store product tree of F in files f.0 f.1 ... - - ``i`` -- integer. increment B1 by this constant on each run + - ``i`` -- integer; increment B1 by this constant on each run - - ``I`` -- integer `f`. auto-calculated increment for B1 - multiplied by `f` scale factor. + - ``I`` -- integer `f`; auto-calculated increment for B1 + multiplied by `f` scale factor - - ``inp`` -- string. Use file as input (instead of redirecting + - ``inp`` -- string; use file as input (instead of redirecting stdin) - - ``b`` -- boolean. Use breadth-first mode of file processing + - ``b`` -- boolean; use breadth-first mode of file processing - - ``d`` -- boolean. Use depth-first mode of file processing + - ``d`` -- boolean; use depth-first mode of file processing (default) - - ``one`` -- boolean. Stop processing a candidate if a factor + - ``one`` -- boolean; stop processing a candidate if a factor is found (looping mode ) - - ``n`` -- boolean. Run ecm in 'nice' mode (below normal + - ``n`` -- boolean; run ecm in 'nice' mode (below normal priority) - - ``nn`` -- boolean. Run ecm in 'very nice' mode (idle + - ``nn`` -- boolean; run ecm in 'very nice' mode (idle priority) - - ``t`` -- integer `n`. Trial divide candidates before P-1, - P+1 or ECM up to `n`. + - ``t`` -- integer `n`; trial divide candidates before P-1, + P+1 or ECM up to `n` - - ``ve`` -- integer `n`. Verbosely show short (`< n` + - ``ve`` -- integer `n`; verbosely show short (`< n` character) expressions on each loop - - ``B2scale`` -- integer. Multiplies the default B2 value + - ``B2scale`` -- integer; multiplies the default B2 value - - ``go`` -- integer. Preload with group order val, which can + - ``go`` -- integer; preload with group order val, which can be a simple expression, or can use N as a placeholder for - the number being factored. + the number being factored - - ``prp`` -- string. use shell command cmd to do large + - ``prp`` -- string; use shell command cmd to do large primality tests - - ``prplen`` -- integer. only candidates longer than this + - ``prplen`` -- integer; only candidates longer than this number of digits are 'large' - - ``prpval`` -- integer. value>=0 which indicates the prp - command foundnumber to be PRP. + - ``prpval`` -- integer; value>=0 which indicates the prp + command foundnumber to be PRP - - ``prptmp`` -- file. outputs n value to temp file prior to + - ``prptmp`` -- file; outputs n value to temp file prior to running (NB. gets deleted) - - ``prplog`` -- file. otherwise get PRP results from this file + - ``prplog`` -- file; otherwise get PRP results from this file (NB. gets deleted) - - ``prpyes`` -- string. Literal string found in prplog file + - ``prpyes`` -- string; literal string found in prplog file when number is PRP - - ``prpno`` -- string. Literal string found in prplog file + - ``prpno`` -- string; literal string found in prplog file when number is composite """ self._cmd = self._make_cmd(B1, B2, kwds) @@ -203,14 +203,12 @@ def _run_ecm(self, cmd, n): INPUT: - - ``cmd`` -- list of strings. The command. + - ``cmd`` -- list of strings; the command - - ``n`` -- integer suitable for ECM. No argument checking is - performed. + - ``n`` -- integer suitable for ECM; no argument checking is + performed - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -233,11 +231,9 @@ def __call__(self, n): INPUT: - - ``n`` -- integer. - - OUTPUT: + - ``n`` -- integer - String. The ECM output. + OUTPUT: string; the ECM output EXAMPLES:: @@ -277,28 +273,25 @@ def interact(self): 65: 850000000, 70: 2900000000} - def _B1_table_value(self, factor_digits, min=15, max=70): + def _B1_table_value(self, factor_digits, min_val=15, max_val=70): """ Return key in ``_recommended_B1_list``. INPUT: - - ``factor_digits`` -- integer. Number of digits. + - ``factor_digits`` -- integer; number of digits - - ``min``, ``max`` -- integer. Min and max values. + - ``min``, ``max`` -- integer; min and max values - OUTPUT: - - Integer. A key in _recommended_B1_list. + OUTPUT: integer; a key in ``_recommended_B1_list`` EXAMPLES:: sage: ecm._B1_table_value(33) 35 """ - if factor_digits < min: - factor_digits = min - if factor_digits > max: + factor_digits = max(factor_digits, min_val) + if factor_digits > max_val: raise ValueError('too many digits') step = 5 return ((factor_digits + step - 1) // step) * step @@ -309,7 +302,7 @@ def recommended_B1(self, factor_digits): INPUT: - - ``factor_digits`` -- integer. Number of digits. + - ``factor_digits`` -- integer; number of digits OUTPUT: @@ -340,9 +333,9 @@ def _parse_output(self, n, out): INPUT: - - ``n`` -- integer. The ECM input number. + - ``n`` -- integer; the ECM input number - - ``out`` -- string. The stdout from the ECM invocation. + - ``out`` -- string; the stdout from the ECM invocation OUTPUT: @@ -420,7 +413,7 @@ def _parse_output(self, n, out): return result raise ValueError('failed to parse ECM output') - def one_curve(self, n, factor_digits=None, B1=2000, algorithm="ECM", **kwds): + def one_curve(self, n, factor_digits=None, B1=2000, algorithm='ECM', **kwds): """ Run one single ECM (or P-1/P+1) curve on input n. @@ -430,18 +423,18 @@ def one_curve(self, n, factor_digits=None, B1=2000, algorithm="ECM", **kwds): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``factor_digits`` -- integer. Decimal digits estimate of the - wanted factor. + - ``factor_digits`` -- integer; decimal digits estimate of the + wanted factor - - ``B1`` -- integer. Stage 1 bound (default 2000) + - ``B1`` -- integer; Stage 1 bound (default: 2000) - - ``algorithm`` -- either "ECM" (default), "P-1" or "P+1" + - ``algorithm`` -- either "ECM" (default); "P-1" or "P+1" OUTPUT: - a list ``[p, q]`` where p and q are integers and n = p * q. + A list ``[p, q]`` where p and q are integers and n = p * q. If no factor was found, then p = 1 and q = n. .. WARNING:: @@ -457,10 +450,10 @@ def one_curve(self, n, factor_digits=None, B1=2000, algorithm="ECM", **kwds): sage: f.one_curve(n, B1=10000, sigma=1022170541) [79792266297612017, 6366805760909027985741435139224233] sage: n = 432132887883903108009802143314445113500016816977037257 - sage: f.one_curve(n, B1=500000, algorithm="P-1") + sage: f.one_curve(n, B1=500000, algorithm='P-1') [67872792749091946529, 6366805760909027985741435139224233] sage: n = 2088352670731726262548647919416588631875815083 - sage: f.one_curve(n, B1=2000, algorithm="P+1", x0=5) + sage: f.one_curve(n, B1=2000, algorithm='P+1', x0=5) [328006342451, 6366805760909027985741435139224233] """ n = self._validate(n) @@ -509,7 +502,6 @@ def _find_factor(self, n, factor_digits, B1, **kwds): """ n = self._validate(n) kwds.setdefault('c', 1000000000) - kwds.setdefault('I', 1) if factor_digits is not None: B1 = self.recommended_B1(factor_digits) kwds['one'] = True @@ -526,15 +518,15 @@ def find_factor(self, n, factor_digits=None, B1=2000, **kwds): INPUT: - - ``n`` -- a positive integer, + - ``n`` -- positive integer - - ``factor_digits`` -- integer or ``None`` (default). Decimal - digits estimate of the wanted factor. + - ``factor_digits`` -- integer or ``None`` (default); decimal + digits estimate of the wanted factor - - ``B1`` -- integer. Stage 1 bound (default 2000). This is - used as bound if ``factor_digits`` is not specified. + - ``B1`` -- integer; Stage 1 bound (default: 2000). This is + used as bound if ``factor_digits`` is not specified - - ``kwds`` -- optional keyword parameters. + - ``kwds`` -- optional keyword parameters OUTPUT: @@ -587,23 +579,21 @@ def factor(self, n, factor_digits=None, B1=2000, proof=False, **kwds): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - - ``factor_digits`` -- integer or ``None`` (default). Optional - guess at how many digits are in the smallest factor. + - ``factor_digits`` -- integer or ``None`` (default); optional + guess at how many digits are in the smallest factor - ``B1`` -- initial lower bound, defaults to 2000 (15 digit - factors). Used if ``factor_digits`` is not specified. + factors); used if ``factor_digits`` is not specified - - ``proof`` -- boolean (default: ``False``). Whether to prove - that the factors are prime. + - ``proof`` -- boolean (default: ``False``); whether to prove + that the factors are prime - - ``kwds`` -- keyword arguments to pass to ecm-gmp. See help - for :class:`ECM` for more details. - - OUTPUT: + - ``kwds`` -- keyword arguments to pass to ecm-gmp; see help + for :class:`ECM` for more details - A list of integers whose product is n. + OUTPUT: list of integers whose product is `n` .. NOTE:: @@ -697,7 +687,7 @@ def time(self, n, factor_digits, verbose=False): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``factor_digits`` -- the (estimated) number of digits of the smallest factor @@ -792,14 +782,13 @@ def _validate(self, n): INPUT: - - ``n`` -- integer. + - ``n`` -- integer OUTPUT: - The integer as a Sage integer. This function raises a - ValueError if the two conditions listed above are not both - satisfied. It is here because GMP-ECM silently ignores all - digits of input after the 4095th! + The integer as a Sage integer. This function raises a :exc:`ValueError` + if the two conditions listed above are not both satisfied. It is here + because GMP-ECM silently ignores all digits of input after the 4095th! EXAMPLES:: diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 2e16fd3b2e4..91f8efcf651 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -85,7 +85,7 @@ # "return", "break", or "continue", raising an exception, ...) -class gc_disabled(): +class gc_disabled: """ This is a "with" statement context manager. Garbage collection is disabled within its scope. Nested usage is properly handled. @@ -180,11 +180,11 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, """ Changes the server and the command to use for this interface. - This raises a :class:`RuntimeError` if the interface is already started. + This raises a :exc:`RuntimeError` if the interface is already started. INPUT: - - ``server`` -- string or ``None`` (default); name of a remote host to connect to using ``ssh``. + - ``server`` -- string or ``None`` (default); name of a remote host to connect to using ``ssh`` - ``command`` -- one of: @@ -295,7 +295,7 @@ def _send(self, cmd): def is_running(self): """ - Return True if self is currently running. + Return ``True`` if ``self`` is currently running. """ if self._expect is None: return False @@ -374,7 +374,6 @@ def pid(self): sage: gap.quit() sage: pid == gap.pid() False - """ if self._expect is None: self._start() @@ -448,7 +447,7 @@ def _install_hints_ssh_through_gate(self): their own way. If this all works, you can then make calls like: - math = Mathematica(server="remote_for_sage") + math = Mathematica(server='remote_for_sage') """ def _do_cleaner(self): @@ -635,8 +634,8 @@ def quit(self, verbose=False): INPUT: - - ``verbose`` -- (boolean, default ``False``) print a message - when quitting this process? + - ``verbose`` -- boolean (default: ``False``); whether to print a + message when quitting the process EXAMPLES:: @@ -712,7 +711,7 @@ def _send_interrupt(self): def _local_tmpfile(self): """ - Return a filename that is used to buffer long command lines for this interface + Return a filename that is used to buffer long command lines for this interface. INPUT: @@ -768,7 +767,7 @@ def _local_tmpfile(self): # FriCAS uses the ".input" suffix, and the other # interfaces are suffix-agnostic, so using ".input" here # lets us avoid a subclass override for FriCAS. - with NamedTemporaryFile(suffix=".input", delete=False) as f: + with NamedTemporaryFile(suffix='.input', delete=False) as f: self.__local_tmpfile = f.name atexit.register(lambda: os.remove(f.name)) return self.__local_tmpfile @@ -818,11 +817,11 @@ def _eval_line_using_file(self, line, restart_if_needed=True): INPUT: - - ``line`` -- (string) a command. - - ``restart_if_needed`` -- (optional bool, default ``True``) -- - If it is ``True``, the command evaluation is evaluated + - ``line`` -- string; a command + - ``restart_if_needed`` -- boolean (default: ``True``); + if it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an - :class:`EOFError` occurred. + :exc:`EOFError` occurred. TESTS:: @@ -851,7 +850,6 @@ def _eval_line_using_file(self, line, restart_if_needed=True): sage: singular(3) Singular crashed -- automatically restarting. 3 - """ with open(self._local_tmpfile(), 'w') as F: F.write(line + '\n') @@ -916,15 +914,15 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if INPUT: - - ``line`` -- (string) a command. - - ``allow_use_file`` (optional bool, default ``True``) -- + - ``line`` -- string; a command + - ``allow_use_file`` -- boolean (default: ``True``); allow to evaluate long commands using :meth:`_eval_line_using_file`. - - ``wait_for_prompt`` (optional bool, default ``True``) -- + - ``wait_for_prompt`` -- boolean (default: ``True``); wait until the prompt appears in the sub-process' output. - - ``restart_if_needed`` (optional bool, default ``True``) -- - If it is ``True``, the command evaluation is evaluated + - ``restart_if_needed`` -- boolean (default: ``True``); + if it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an - :class:`EOFError` occurred. + :exc:`EOFError` occurred. TESTS:: @@ -982,7 +980,6 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if sage: singular('2+3') Singular crashed -- automatically restarting. 5 - """ if allow_use_file and wait_for_prompt and self._eval_using_file_cutoff and len(line) > self._eval_using_file_cutoff: return self._eval_line_using_file(line) @@ -1186,10 +1183,10 @@ def _expect_expr(self, expr=None, timeout=None): INPUT: - - ``expr`` -- None or a string or list of strings - (default: None) + - ``expr`` -- ``None`` or a string or list of strings + (default: ``None``) - - ``timeout`` -- None or a number (default: None) + - ``timeout`` -- ``None`` or a number (default: ``None``) EXAMPLES: @@ -1269,7 +1266,7 @@ def _sendstr(self, string): INPUT: - - ``string`` -- a string + - ``string`` -- string EXAMPLES: We illustrate this function using the Singular interface:: @@ -1359,32 +1356,34 @@ def _synchronize(self, cmd='1+%s;\n'): ########################################################################### def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file=True, - split_lines="nofile", **kwds): + split_lines='nofile', **kwds): """ INPUT: - - ``code`` -- text to evaluate + - ``code`` -- text to evaluate - - ``strip`` -- bool; whether to strip output prompts, - etc. (ignored in the base class). + - ``strip`` -- boolean; whether to strip output prompts, + etc. (ignored in the base class) - - ``locals`` -- None (ignored); this is used for compatibility - with the Sage notebook's generic system interface. + - ``locals`` -- None (ignored); this is used for compatibility + with the Sage notebook's generic system interface - - ``allow_use_file`` -- bool (default: ``True``); if True and ``code`` exceeds an - interface-specific threshold then ``code`` will be communicated - via a temporary file rather that the character-based interface. - If False then the code will be communicated via the character interface. + - ``allow_use_file`` -- boolean (default: ``True``); if ``True`` and + ``code`` exceeds an interface-specific threshold then ``code`` will + be communicated via a temporary file rather that the character-based + interface. If ``False`` then the code will be communicated via the + character interface. - - ``split_lines`` -- Tri-state (default: "nofile"); if "nofile" then ``code`` is sent line by line - unless it gets communicated via a temporary file. - If True then ``code`` is sent line by line, but some lines individually - might be sent via temporary file. Depending on the interface, this may transform - grammatical ``code`` into ungrammatical input. - If False, then the whole block of code is evaluated all at once. + - ``split_lines`` -- Tri-state (default: ``'nofile'``); if "nofile" + then ``code`` is sent line by line unless it gets communicated via a + temporary file. If ``True`` then ``code`` is sent line by line, but + some lines individually might be sent via temporary file. Depending + on the interface, this may transform grammatical ``code`` into + ungrammatical input. If ``False``, then the whole block of code is + evaluated all at once. - - ``**kwds`` -- All other arguments are passed onto the _eval_line - method. An often useful example is reformat=False. + - ``**kwds`` -- all other arguments are passed onto the ``_eval_line`` + method. An often useful example is ``reformat=False``. """ if synchronize: try: @@ -1476,7 +1475,7 @@ class FunctionElement(InterfaceFunctionElement): def is_ExpectElement(x): """ - Return True if ``x`` is of type :class:`ExpectElement` + Return ``True`` if ``x`` is of type :class:`ExpectElement`. This function is deprecated; use :func:`isinstance` (of :class:`sage.interfaces.abc.ExpectElement`) instead. @@ -1529,10 +1528,10 @@ def __init__(self, parent, value, is_name=False, name=None): def __hash__(self): """ - Return the hash of self. + Return the hash of ``self``. This is a default implementation of hash - which just takes the hash of the string of self. + which just takes the hash of the string of ``self``. """ return hash('%s%s' % (self, self._session_number)) @@ -1582,11 +1581,11 @@ def __init__(self, interface, silent=False, stdout=None): INPUT: - - ``interface`` -- the interface whose communication shall be dumped. + - ``interface`` -- the interface whose communication shall be dumped - ``silent`` -- if ``True`` this context does nothing - - ``stdout`` -- optional parameter for alternative stdout device (default: ``None``) + - ``stdout`` -- (optional) parameter for alternative stdout device (default: ``None``) EXAMPLES:: diff --git a/src/sage/interfaces/four_ti_2.py b/src/sage/interfaces/four_ti_2.py index 7815c9eda62..8d93ce9c5e3 100644 --- a/src/sage/interfaces/four_ti_2.py +++ b/src/sage/interfaces/four_ti_2.py @@ -41,7 +41,7 @@ import os -class FourTi2(): +class FourTi2: r""" An interface to the program 4ti2. @@ -119,9 +119,9 @@ def write_matrix(self, mat, filename): INPUT: - - ``mat`` -- A matrix of integers or something that can be - converted to that. - - ``filename`` -- A file name not including a path. + - ``mat`` -- a matrix of integers or something that can be + converted to that + - ``filename`` -- a file name not including a path EXAMPLES:: @@ -144,8 +144,8 @@ def write_single_row(self, row, filename): INPUT: - - ``row`` -- A list of integers. - - ``filename`` -- A file name not including a path. + - ``row`` -- list of integers + - ``filename`` -- a file name not including a path EXAMPLES:: @@ -164,11 +164,11 @@ def write_array(self, array, nrows, ncols, filename): INPUT: - - ``array`` -- A matrix of integers. Can be represented as a list - of lists. - - ``nrows`` -- The number of rows in ``array``. - - ``ncols`` -- The number of columns in ``array``. - - ``file`` -- A file name not including a path. + - ``array`` -- a matrix of integers. Can be represented as a list + of lists + - ``nrows`` -- the number of rows in ``array`` + - ``ncols`` -- the number of columns in ``array`` + - ``file`` -- a file name not including a path EXAMPLES:: @@ -189,11 +189,9 @@ def read_matrix(self, filename): INPUT: - - ``filename`` -- The name of the file to read from. + - ``filename`` -- the name of the file to read from - OUTPUT: - - The data from the file as a matrix over `\ZZ`. + OUTPUT: the data from the file as a matrix over `\ZZ` EXAMPLES:: @@ -236,11 +234,9 @@ def _process_input(self, kwds): INPUT: - - ``kwds`` -- A dict controlling what data is written to what files. - - OUTPUT: + - ``kwds`` -- dictionary controlling what data is written to what files - The value of the key ``project``. + OUTPUT: the value of the key ``project`` EXAMPLES:: @@ -283,10 +279,10 @@ def call(self, command, project, verbose=True, *, options=()): INPUT: - - ``command`` -- The 4ti2 program to run. - - ``project`` -- The file name of the project to run on. - - ``verbose`` -- Display the output of 4ti2 if ``True``. - - ``options`` -- A list of strings to pass to the program. + - ``command`` -- the 4ti2 program to run + - ``project`` -- the file name of the project to run on + - ``verbose`` -- display the output of 4ti2 if ``True`` + - ``options`` -- list of strings to pass to the program EXAMPLES:: @@ -333,7 +329,6 @@ def zsolve(self, mat=None, rel=None, rhs=None, sign=None, lat=None, project=None [1 2 3] [0 0 0], [], [1 1 1] ] - """ project = self._process_input(locals()) self.call('zsolve', project, options=['-q']) @@ -441,7 +436,6 @@ def ppi(self, n): [-1 -1 1] [-3 0 1] [ 1 -2 1] - """ self.call('ppi', f'{n} 2> /dev/null') return self.read_matrix('ppi%s.gra' % n) @@ -522,13 +516,13 @@ def _magic3x3(self): """ from sage.matrix.constructor import matrix return matrix(ZZ, 7, 9, - [[1, 1, 1, -1, -1, -1, 0, 0, 0], - [1, 1, 1, 0, 0, 0, -1, -1, -1], - [0, 1, 1, -1, 0, 0, -1, 0, 0], - [1, 0, 1, 0, -1, 0, 0, -1, 0], - [1, 1, 0, 0, 0, -1, 0, 0, -1], - [0, 1, 1, 0, -1, 0, 0, 0, -1], - [1, 1, 0, 0, -1, 0, -1, 0, 0]]) + [[1, 1, 1, -1, -1, -1, 0, 0, 0], + [1, 1, 1, 0, 0, 0, -1, -1, -1], + [0, 1, 1, -1, 0, 0, -1, 0, 0], + [1, 0, 1, 0, -1, 0, 0, -1, 0], + [1, 1, 0, 0, 0, -1, 0, 0, -1], + [0, 1, 1, 0, -1, 0, 0, 0, -1], + [1, 1, 0, 0, -1, 0, -1, 0, 0]]) # The instance that should be used outside this file. diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 630283d5262..5982c225439 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -19,7 +19,6 @@ - Martin Rubey, Bill Page (2016-08): Completely separate from Axiom, implement more complete translation from FriCAS to SageMath types. - EXAMPLES:: sage: fricas('3 * 5') @@ -280,7 +279,7 @@ def __init__(self, name='fricas', command=None, sage: fricas(I) %i - sage: integrate(sin(x)*exp(I*x), x, -pi, 0, algorithm="fricas") + sage: integrate(sin(x)*exp(I*x), x, -pi, 0, algorithm='fricas') 1/2*I*pi sage: fricas(I*sin(x)).sage() @@ -380,7 +379,6 @@ def _quit_string(self): sage: fricas.quit() sage: fricas.pid() == p False - """ return ')quit' @@ -463,11 +461,9 @@ def _read_in_file_command(self, filename): INPUT: - - ``filename``, a string ending in '.input'. - - OUTPUT: + - ``filename`` -- string ending in '.input'. - - a string with the command for reading filename without output. + OUTPUT: string with the command for reading filename without output TESTS: @@ -475,7 +471,6 @@ def _read_in_file_command(self, filename): sage: len(fricas([i for i in range(600)])) # indirect doctest 600 - """ if not filename.endswith('.input'): raise ValueError("the filename must end with .input") @@ -486,7 +481,6 @@ def _remote_tmpfile(self): """ Return a remote tmpfile ending with ".input" used to buffer long command lines sent to FriCAS. - """ try: return self.__remote_tmpfile @@ -515,13 +509,11 @@ def _check_errors(self, line, output): INPUT: - - ``line``, a string that was sent to FriCAS. + - ``line`` -- string that was sent to FriCAS - - ``output``, a string returned by FriCAS + - ``output`` -- string returned by FriCAS - OUTPUT: - - None + OUTPUT: none TESTS:: @@ -552,7 +544,6 @@ def _check_errors(self, line, output): Perhaps you should use "@" to indicate the required return type, or "$" to specify which version of the function you need. - """ # otherwise there might be a message m = re.search(r"\|startKeyedMsg\|\n(.*)\n\|endOfKeyedMsg\|", @@ -656,17 +647,16 @@ def set(self, var, value): INPUT: - - ``var``, ``value``: strings, the first representing a valid - FriCAS variable identifier, the second a FriCAS expression. + - ``var``, ``value`` -- strings; the first representing a valid + FriCAS variable identifier, the second a FriCAS expression - OUTPUT: None + OUTPUT: none EXAMPLES:: sage: fricas.set('xx', '2') sage: fricas.get('xx') '2' - """ cmd = '%s%s%s;' % (var, self._assign_symbol(), value) output = self.eval(cmd, reformat=False) @@ -735,19 +725,18 @@ def get_string(self, var): sage: var("a b"); f = 1/(1+a*cos(x)) (a, b) - sage: lF = integrate(f, x, algorithm="fricas") + sage: lF = integrate(f, x, algorithm='fricas') sage: (diff(lF[0], x) - f).simplify_trig() 0 sage: (diff(lF[1], x) - f).simplify_trig() 0 - sage: f = 1/(b*x^2+a); lF = integrate(f, x, algorithm="fricas"); lF + sage: f = 1/(b*x^2+a); lF = integrate(f, x, algorithm='fricas'); lF [1/2*log((2*a*b*x + (b*x^2 - a)*sqrt(-a*b))/(b*x^2 + a))/sqrt(-a*b), arctan(sqrt(a*b)*x/a)/sqrt(a*b)] sage: (diff(lF[0], x) - f).simplify_trig() 0 sage: (diff(lF[1], x) - f).simplify_trig() 0 - """ # strip removes leading and trailing whitespace, after that # we can assume that the first and the last character are @@ -763,7 +752,6 @@ def get_integer(self, var): sage: fricas.get_integer('factorial 1111') == factorial(1111) True - """ return int(self.get_unparsed_InputForm(str(var))) @@ -790,7 +778,7 @@ def get_unparsed_InputForm(self, var): - catch errors, especially when InputForm is not available: - - for example when integration returns ``"failed"`` + - for example when integration returns ``'failed'`` - ``UnivariatePolynomial`` @@ -800,7 +788,6 @@ def get_unparsed_InputForm(self, var): sage: fricas.get_unparsed_InputForm('1..3') '(1..3)$Segment(PositiveInteger())' - """ return self.get_string('unparse((%s)::InputForm)' % var) @@ -812,7 +799,6 @@ def get_InputForm(self, var): sage: fricas.get_InputForm('1..3') '(($elt (Segment (PositiveInteger)) SEGMENT) 1 3)' - """ return self.get_string('sageprint((%s)::InputForm)' % str(var)) @@ -904,7 +890,7 @@ def __reduce__(self): return reduce_load_fricas, tuple([]) def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file=True, - split_lines="nofile", reformat=True, **kwds): + split_lines='nofile', reformat=True, **kwds): """ Evaluate ``code`` using FriCAS. @@ -913,7 +899,7 @@ def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file= INPUT: - - ``reformat`` -- bool; remove the output markers when True. + - ``reformat`` -- boolean; remove the output markers when True This can also be used to pass system commands to FriCAS. @@ -925,7 +911,6 @@ def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file= '' sage: fricas("x") x - """ output = Expect.eval(self, code, strip=strip, synchronize=synchronize, locals=locals, @@ -1203,11 +1188,9 @@ def _get_sage_type(self, domain): """ INPUT: - - ``domain``, a FriCAS SExpression + - ``domain`` -- a FriCAS SExpression - OUTPUT: - - - a corresponding Sage type + OUTPUT: a corresponding Sage type EXAMPLES:: @@ -1309,7 +1292,6 @@ def _parse_and_eval(s, start=0): Traceback (most recent call last): ... TypeError: cannot coerce arguments: no canonical coercion from to Symbolic Ring - """ a = start while s[a] in FriCASElement._WHITESPACE: @@ -1348,7 +1330,6 @@ def _parse_list(s, start=0): sage: FriCASElement._parse_list('(bcd)') (bcd(), 4) - """ a = start assert s[a] == FriCASElement._LEFTBRACKET @@ -1386,8 +1367,8 @@ def _parse_other(s, start=0, make_fun=False): - ``s`` -- string - ``start`` -- integer; specifies where the symbol begins - - ``make_fun`` -- (default: ``False``) a Boolean; specifying - whether the atom should be interpreted as a function call + - ``make_fun`` -- boolean (default: ``False``); whether the atom should + be interpreted as a function call TESTS:: @@ -1401,12 +1382,12 @@ def _parse_other(s, start=0, make_fun=False): This function cannot use the symbol table to translate symbols which are not function calls, as :issue:`31849` shows - - ``D`` would erroneously be interpreted as differential + ``D`` would erroneously be interpreted as differential then:: sage: var("D") D - sage: integrate(D/x, x, algorithm="fricas") + sage: integrate(D/x, x, algorithm='fricas') D*log(x) However, it does have to check for constants, for example @@ -1414,7 +1395,6 @@ def _parse_other(s, start=0, make_fun=False): sage: FriCASElement._parse_other("%pi") (pi, 2) - """ a = start b = len(s) @@ -1469,7 +1449,6 @@ def _parse_string(s, start=0): sage: FriCASElement._parse_string('"(b c)"') ('(b c)', 6) - """ a = start assert s[a] == FriCASElement._STRINGMARKER @@ -1592,7 +1571,7 @@ def _sage_expression(fricas_InputForm): Check that :issue:`25987` is fixed:: - sage: integrate(lambert_w(x), x, algorithm="fricas") + sage: integrate(lambert_w(x), x, algorithm='fricas') (x*lambert_w(x)^2 - x*lambert_w(x) + x)/lambert_w(x) Check that :issue:`25838` is fixed:: @@ -1984,7 +1963,7 @@ def _sage_(self): if head == "Factored": l = P.new('[[f.factor, f.exponent] for f in factors(%s)]' % self._name).sage() - return Factorization([(p, e) for p, e in l]) + return Factorization(list(l)) if head == "UnivariatePolynomial": base_ring = self._get_sage_type(domain[2]) @@ -2084,7 +2063,6 @@ def __init__(self, object, name): upperCase! sage: a.upperCase_e() "HELLO" - """ if name.endswith("_q"): name = name[:-2] + "?" @@ -2106,7 +2084,6 @@ def __init__(self, parent, name): upperCase? sage: fricas.upperCase_e upperCase! - """ if name.endswith("_q"): name = name[:-2] + "?" diff --git a/src/sage/interfaces/frobby.py b/src/sage/interfaces/frobby.py index 498a5a6da58..75200dc0694 100644 --- a/src/sage/interfaces/frobby.py +++ b/src/sage/interfaces/frobby.py @@ -37,14 +37,12 @@ def __call__(self, action, input=None, options=[], verbose=False): INPUT: - - action -- A string telling Frobby what to do. - - input -- None or a string that is passed to Frobby as standard in. - - options -- A list of options without the dash in front. - - verbose -- bool (default: false) Print detailed information. + - ``action`` -- string telling Frobby what to do + - ``input`` -- ``None`` or string that is passed to Frobby as standard in + - ``options`` -- list of options without the dash in front + - ``verbose`` -- boolean (default: ``False``); print detailed information - OUTPUT: - - - string -- What Frobby wrote to the standard output stream. + OUTPUT: string; what Frobby wrote to the standard output stream EXAMPLES: @@ -104,11 +102,9 @@ def alexander_dual(self, monomial_ideal): INPUT: - - monomial_ideal -- The monomial ideal to decompose. + - ``monomial_ideal`` -- the monomial ideal to decompose - OUTPUT: - - The monomial corresponding to the Alexander dual. + OUTPUT: the monomial corresponding to the Alexander dual EXAMPLES: @@ -131,8 +127,6 @@ def alexander_dual(self, monomial_ideal): sage: I=R.ideal([prod([R.gen(i-1) for i in a]) for a in t.facets()]) sage: len(frobby.alexander_dual(I).gens()) 643 - - """ frobby_input = self._ideal_to_string(monomial_ideal) frobby_output = self('alexdual', input=frobby_input) @@ -140,7 +134,7 @@ def alexander_dual(self, monomial_ideal): def hilbert(self, monomial_ideal): r""" - Computes the multigraded Hilbert-Poincaré series of the input + Compute the multigraded Hilbert-Poincaré series of the input ideal. Use the -univariate option to get the univariate series. The Hilbert-Poincaré series of a monomial ideal is the sum of all @@ -151,13 +145,11 @@ def hilbert(self, monomial_ideal): INPUT: - - monomial_ideal -- A monomial ideal. + - ``monomial_ideal`` -- a monomial ideal OUTPUT: - - A polynomial in the same ring as the ideal. + A polynomial in the same ring as the ideal. EXAMPLES:: @@ -165,7 +157,6 @@ def hilbert(self, monomial_ideal): sage: I=[d*b*c,b^2*c,b^10,d^10]*R # optional - frobby sage: frobby.hilbert(I) # optional - frobby d^10*b^10*c + d^10*b^10 + d^10*b*c + b^10*c + d^10 + b^10 + d*b^2*c + d*b*c + b^2*c + 1 - """ frobby_input = self._ideal_to_string(monomial_ideal) frobby_output = self('hilbert', input=frobby_input) @@ -189,7 +180,7 @@ def associated_primes(self, monomial_ideal): INPUT: - - monomial_ideal -- The monomial ideal to decompose. + - ``monomial_ideal`` -- the monomial ideal to decompose OUTPUT: @@ -203,7 +194,6 @@ def associated_primes(self, monomial_ideal): sage: frobby.associated_primes(I) # optional - frobby [Ideal (d, b) of Multivariate Polynomial Ring in d, b, c over Rational Field, Ideal (d, b, c) of Multivariate Polynomial Ring in d, b, c over Rational Field] - """ frobby_input = self._ideal_to_string(monomial_ideal) frobby_output = self('assoprimes', input=frobby_input) @@ -224,11 +214,9 @@ def dimension(self, monomial_ideal): INPUT: - - monomial_ideal -- The monomial ideal to decompose. - - OUTPUT: + - ``monomial_ideal`` -- the monomial ideal to decompose - The dimension of the zero set of the ideal. + OUTPUT: the dimension of the zero set of the ideal EXAMPLES:: @@ -236,7 +224,6 @@ def dimension(self, monomial_ideal): sage: I=[d*b*c,b^2*c,b^10,d^10]*R # optional - frobby sage: frobby.dimension(I) # optional - frobby 1 - """ frobby_input = self._ideal_to_string(monomial_ideal) frobby_output = self('dimension', input=frobby_input) @@ -250,7 +237,7 @@ def irreducible_decomposition(self, monomial_ideal): INPUT: - - monomial_ideal -- The monomial ideal to decompose. + - ``monomial_ideal`` -- the monomial ideal to decompose OUTPUT: @@ -309,9 +296,9 @@ def _parse_ideals(self, string, ring): INPUT: - - string -- The string to be parsed. - - ring -- The ring within which to construct the irreducible - monomial ideals within. + - ``string`` -- the string to be parsed + - ``ring`` -- the ring within which to construct the irreducible + monomial ideals within OUTPUT: @@ -327,7 +314,6 @@ def _parse_ideals(self, string, ring): sage: frobby._parse_ideals(string, ring) [Ideal (x*y^2*z^3, y^5) of Multivariate Polynomial Ring in x, y, z over Rational Field, Ideal (x*y^2*z^3, x^4*y^5*z^6) of Multivariate Polynomial Ring in x, y, z over Rational Field] - """ lines = string.split('\n') if lines[-1] == '': @@ -359,7 +345,7 @@ def _parse_4ti2_matrix(self, string): INPUT: - - string -- The string to be parsed. + - ``string`` -- the string to be parsed OUTPUT: @@ -412,11 +398,9 @@ def _ideal_to_string(self, monomial_ideal): INPUT: - - monomial_ideal -- The monomial ideal to be formatted as a string. + - ``monomial_ideal`` -- the monomial ideal to be formatted as a string - OUTPUT: - - A string in 4ti2 format representing the ideal. + OUTPUT: string in ``4ti2`` format representing the ideal EXAMPLES:: @@ -446,11 +430,9 @@ def _monomial_to_string(self, monomial): INPUT: - - monomial -- The monomial whose exponent vector is to be formatted. - - OUTPUT: + - ``monomial`` -- the monomial whose exponent vector is to be formatted - A string representing the exponent vector of monomial. + OUTPUT: string representing the exponent vector of monomial EXAMPLES:: diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index f093e865d4c..139f8b3acf5 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -9,13 +9,13 @@ The interface offers three pieces of functionality: -#. ``gap_console()`` -- A function that dumps you into +#. ``gap_console()`` -- a function that dumps you into an interactive command-line GAP session. -#. ``gap(expr)`` -- Evaluation of arbitrary GAP +#. ``gap(expr)`` -- evaluation of arbitrary GAP expressions, with the result returned as a string. -#. ``gap.new(expr)`` -- Creation of a Sage object that +#. ``gap.new(expr)`` -- creation of a Sage object that wraps a GAP object. This provides a Pythonic interface to GAP. For example, if ``f=gap.new(10)``, then ``f.Factors()`` returns the prime factorization of @@ -129,7 +129,7 @@ The GAP interface reads in even very long input (using files) in a robust manner, as long as you are creating a new object. -.. note:: +.. NOTE:: Using ``gap.eval`` for long input is much less robust, and is not recommended. @@ -254,7 +254,6 @@ class Gap_generic(ExtraTabCompletion, Expect): - Franco Saliola (Feb 2010): refactored to separate out the generic code - """ _identical_function = "IsIdenticalObj" @@ -299,7 +298,7 @@ def _synchronize(self, timeout=0.5, cmd='%s;'): def interrupt(self, tries=None, timeout=1, quit_on_fail=True): """ - Interrupt the GAP process + Interrupt the GAP process. Gap installs a SIGINT handler, we call it directly instead of trying to sent Ctrl-C. Unlike @@ -379,13 +378,12 @@ def _assign_symbol(self): sage: gap = Gap() sage: print(gap._assign_symbol()) := - """ return ":=" def _quit_string(self): """ - Returns the string used to quit GAP. + Return the string used to quit GAP. EXAMPLES:: @@ -405,7 +403,7 @@ def _quit_string(self): def _read_in_file_command(self, filename): r""" - Returns the command use to read in a file in GAP. + Return the command use to read in a file in GAP. EXAMPLES:: @@ -425,7 +423,7 @@ def _read_in_file_command(self, filename): def _continuation_prompt(self): """ - Returns the continuation prompt in GAP. + Return the continuation prompt in GAP. EXAMPLES:: @@ -438,7 +436,7 @@ def load_package(self, pkg, verbose=False): """ Load the Gap package with the given name. - If loading fails, raise a :class:`RuntimeError` exception. + If loading fails, raise a :exc:`RuntimeError` exception. TESTS:: @@ -461,17 +459,16 @@ def eval(self, x, newlines=False, strip=True, split_lines=True, **kwds): INPUT: - - ``s`` -- string containing GAP code. + - ``s`` -- string containing GAP code - - ``newlines`` -- bool (default: ``True``); if False, - remove all backslash-newlines inserted by the GAP output - formatter. + - ``newlines`` -- boolean (default: ``True``); if ``False``, + remove all backslash-newlines inserted by the GAP output formatter - - ``strip`` -- ignored + - ``strip`` -- ignored - - ``split_lines`` -- bool (default: ``True``); if True then each - line is evaluated separately. If False, then the whole - block of code is evaluated all at once. + - ``split_lines`` -- boolean (default: ``True``); if ``True`` then each + line is evaluated separately. If ``False``, then the whole + block of code is evaluated all at once. EXAMPLES:: @@ -632,15 +629,15 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if INPUT: - - ``line`` -- (string) a command. - - ``allow_use_file`` (optional bool, default ``True``) -- - allow to evaluate long commands using :meth:`_eval_line_using_file`. - - ``wait_for_prompt`` (optional bool, default ``True``) -- - wait until the prompt appears in the sub-process' output. - - ``restart_if_needed`` (optional bool, default ``True``) -- - If it is ``True``, the command evaluation is evaluated + - ``line`` -- string; a command + - ``allow_use_file`` -- boolean (default: ``True``); + allow to evaluate long commands using :meth:`_eval_line_using_file` + - ``wait_for_prompt`` -- boolean (default: ``True``); + wait until the prompt appears in the sub-process' output + - ``restart_if_needed`` -- boolean (default: ``True``); + if it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an - :class:`EOFError` occurred. + :exc:`EOFError` occurred. TESTS:: @@ -775,7 +772,7 @@ def _contains(self, v1, v2): def _true_symbol(self): """ - Returns the symbol for truth in GAP. + Return the symbol for truth in GAP. EXAMPLES:: @@ -788,7 +785,7 @@ def _true_symbol(self): def _false_symbol(self): """ - Returns the symbol for falsity in GAP. + Return the symbol for falsity in GAP. EXAMPLES:: @@ -801,7 +798,7 @@ def _false_symbol(self): def _equality_symbol(self): """ - Returns the symbol for equality in GAP. + Return the symbol for equality in GAP. EXAMPLES:: @@ -816,7 +813,7 @@ def _equality_symbol(self): def version(self): """ - Returns the version of GAP being used. + Return the version of GAP being used. EXAMPLES:: @@ -827,7 +824,7 @@ def version(self): def function_call(self, function, args=None, kwds=None): """ - Calls the GAP function with args and kwds. + Call the GAP function with ``args`` and ``kwds``. EXAMPLES:: @@ -899,11 +896,9 @@ def get_record_element(self, record, name): INPUT: - ``record`` -- a GAP record - - ``name`` -- str + - ``name`` -- string - OUTPUT: - - - :class:`GapElement` + OUTPUT: :class:`GapElement` EXAMPLES:: @@ -1005,7 +1000,6 @@ def is_string(self): True sage: gap('[1,2,3]').is_string() False - """ return bool(self.IsString()) @@ -1136,7 +1130,7 @@ def __reduce__(self): def _next_var_name(self): r""" - Returns the next unused variable name. + Return the next unused variable name. Note that names starting with dollar signs are valid GAP identifiers, but need to be escaped with a backslash starting @@ -1216,7 +1210,7 @@ def _start(self): def _function_class(self): """ - Returns the GapFunction class. + Return the GapFunction class. EXAMPLES:: @@ -1232,7 +1226,7 @@ def _function_class(self): def cputime(self, t=None): r""" - Returns the amount of CPU time that the GAP session has used. If + Return the amount of CPU time that the GAP session has used. If ``t`` is not None, then it returns the difference between the current CPU time and ``t``. @@ -1320,7 +1314,7 @@ def help(self, s, pager=True): sline = int(sline) - 1 if self.is_remote(): self._get_tmpfile() - with open(self._local_tmpfile(), "r", + with open(self._local_tmpfile(), encoding=gap_encoding) as fobj: help = fobj.read() if pager: @@ -1428,7 +1422,7 @@ def console(self): def _object_class(self): """ - Returns the GapElement class. + Return the GapElement class. EXAMPLES:: @@ -1450,7 +1444,7 @@ def _an_element_(self): def _function_element_class(self): """ - Returns the GapFunctionElement class. + Return the GapFunctionElement class. EXAMPLES:: @@ -1464,11 +1458,9 @@ def _function_element_class(self): @cached_method def _tab_completion(self): """ - Return additional tab completion entries - - OUTPUT: + Return additional tab completion entries. - List of strings + OUTPUT: list of strings EXAMPLES:: @@ -1573,9 +1565,7 @@ def _tab_completion(self): """ Return additional tab completion entries. - OUTPUT: - - List of strings + OUTPUT: list of strings EXAMPLES:: @@ -1633,7 +1623,7 @@ def _instancedoc_(self): def is_GapElement(x): """ - Return True if ``x`` is a :class:`GapElement` + Return ``True`` if ``x`` is a :class:`GapElement`. This function is deprecated; use :func:`isinstance` (of :class:`sage.interfaces.abc.GapElement`) instead. @@ -1720,7 +1710,7 @@ def intmod_gap_to_sage(x): r""" INPUT: - - x -- Gap integer mod ring element + - ``x`` -- Gap integer mod ring element EXAMPLES:: @@ -1770,7 +1760,7 @@ def intmod_gap_to_sage(x): def reduce_load_GAP(): """ - Returns the GAP interface object defined in sage.interfaces.gap. + Return the GAP interface object defined in ``sage.interfaces.gap``. EXAMPLES:: diff --git a/src/sage/interfaces/gap3.py b/src/sage/interfaces/gap3.py index 2781ac4f994..de6a35586e3 100644 --- a/src/sage/interfaces/gap3.py +++ b/src/sage/interfaces/gap3.py @@ -52,7 +52,7 @@ The interface to GAP3 offers the following functionality. -#. ``gap3(expr)`` -- Evaluation of arbitrary GAP3 expressions, with the +#. ``gap3(expr)`` -- evaluation of arbitrary GAP3 expressions, with the result returned as a Sage object wrapping the corresponding GAP3 element:: sage: # optional - gap3 @@ -296,9 +296,9 @@ def __init__(self, command=gap3_cmd): INPUT: - - command -- string (default "gap3"); points to the gap3 - executable on your system; by default, it is assumed the - executable is in your path. + - command -- string (default: ``'gap3'``); points to the gap3 + executable on your system. By default, it is assumed the + executable is in your path. EXAMPLES:: @@ -624,13 +624,11 @@ def _install_hints(self): @cached_method def _tab_completion(self): """ - Return additional tab completion entries + Return additional tab completion entries. - Currently this is empty + Currently this is empty. - OUTPUT: - - List of strings + OUTPUT: list of strings EXAMPLES:: @@ -645,7 +643,7 @@ def _tab_completion(self): class GAP3Element(GapElement_generic): r""" - A GAP3 element + A GAP3 element. .. NOTE:: @@ -658,11 +656,11 @@ class GAP3Element(GapElement_generic): - ``value`` -- the GAP3 command as a string - - ``is_name`` -- bool (default: ``False``); if True, then ``value`` is + - ``is_name`` -- boolean (default: ``False``); if ``True``, then ``value`` is the variable name for the object - - ``name`` -- str (default: ``None``); the variable name to use for the - object. If ``None``, then a variable name is generated. + - ``name`` -- string (default: ``None``); the variable name to use for the + object. If ``None``, then a variable name is generated .. NOTE:: @@ -771,7 +769,7 @@ def _latex_(self): class GAP3Record(GAP3Element): r""" - A GAP3 record + A GAP3 record. .. NOTE:: @@ -788,9 +786,7 @@ def recfields(self): Return a list of the fields for the record. (Record fields are akin to object attributes in Sage.) - OUTPUT: - - - list of strings -- the field records + OUTPUT: list of strings -- the field records EXAMPLES:: @@ -813,9 +809,7 @@ def operations(self): r""" Return a list of the GAP3 operations for the record. - OUTPUT: - - - list of strings -- operations of the record + OUTPUT: list of strings -- operations of the record EXAMPLES:: @@ -864,7 +858,7 @@ def __getattr__(self, attrname): def _tab_completion(self): r""" - Defines the list of methods and attributes that will appear for tab + Define the list of methods and attributes that will appear for tab completion. OUTPUT: diff --git a/src/sage/interfaces/gap_workspace.py b/src/sage/interfaces/gap_workspace.py index 70bb584fdef..c7df7ffaed1 100644 --- a/src/sage/interfaces/gap_workspace.py +++ b/src/sage/interfaces/gap_workspace.py @@ -20,19 +20,19 @@ from sage.env import DOT_SAGE, HOSTNAME, GAP_ROOT_PATHS -def gap_workspace_file(system="gap", name="workspace", dir=None): +def gap_workspace_file(system='gap', name='workspace', dir=None): r""" Return the filename for the GAP workspace. INPUT: - - ``system`` -- the name of the system, either ``"gap"`` or - ``"libgap"`` + - ``system`` -- the name of the system, either ``'gap'`` or + ``'libgap'`` - - ``name`` -- the kind of workspace, usually ``"workspace"`` but + - ``name`` -- the kind of workspace, usually ``'workspace'`` but the library interface also uses other files - - ``dir`` -- the directory where the workspaces should be stored. + - ``dir`` -- the directory where the workspaces should be stored By default, this is ``DOT_SAGE/gap`` EXAMPLES:: @@ -79,7 +79,7 @@ def prepare_workspace_dir(dir=None): INPUT: - - ``dir`` -- the directory where the workspaces should be stored. + - ``dir`` -- the directory where the workspaces should be stored By default, this is ``DOT_SAGE/gap`` OUTPUT: the actual workspace directory diff --git a/src/sage/interfaces/genus2reduction.py b/src/sage/interfaces/genus2reduction.py index 8cd13286830..913188f9182 100644 --- a/src/sage/interfaces/genus2reduction.py +++ b/src/sage/interfaces/genus2reduction.py @@ -192,7 +192,7 @@ def divisors_to_string(divs): - ``divs`` -- a (possibly empty) list of numbers - OUTPUT: a string representation of these numbers + OUTPUT: string representation of these numbers EXAMPLES:: diff --git a/src/sage/interfaces/gfan.py b/src/sage/interfaces/gfan.py index d8f2157034f..a37e8825b5b 100644 --- a/src/sage/interfaces/gfan.py +++ b/src/sage/interfaces/gfan.py @@ -47,20 +47,20 @@ from sage.misc.decorators import rename_keyword -class Gfan(): +class Gfan: """ Interface to Anders Jensen's Groebner Fan program. """ @rename_keyword(deprecation=33468, I='input') def __call__(self, input, cmd='', verbose=False, format=None): r""" - Call Groebner Fan program with given input + Call Groebner Fan program with given input. INPUT: - - ``input`` -- string, input - - ``cmd`` -- string (default:``''``), GFan command - - ``verbose`` -- bool (default:``False``) + - ``input`` -- string; input + - ``cmd`` -- string (default: ``''``); GFan command + - ``verbose`` -- boolean (default: ``False``) EXAMPLES:: @@ -90,7 +90,6 @@ def __call__(self, input, cmd='', verbose=False, format=None): doctest:...: DeprecationWarning: use the option 'input' instead of 'I' See https://github.com/sagemath/sage/issues/33468 for details. - """ if format is not None: from sage.misc.superseded import deprecation diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 2464d5c4664..5894980b332 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -1,3 +1,4 @@ +# sage.doctest: needs giac r""" Pexpect Interface to Giac @@ -25,7 +26,6 @@ $SAGE_LOCAL/share/giac/doc/en/cascmd_local/index.html - EXAMPLES:: sage: giac('3 * 5') @@ -48,7 +48,7 @@ If the string "error" (case insensitive) occurs in the output of -anything from Giac, a :class:`RuntimeError` exception is raised. +anything from Giac, a :exc:`RuntimeError` exception is raised. Tutorial -------- @@ -481,7 +481,6 @@ def console(self): Press CTRL and D simultaneously to finish session Type ?commandname for help 0>> - """ giac_console() @@ -610,7 +609,6 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if sage: giac_result = giac(h1) + giac(h2) sage: bool(giac_result.sage() == x) True - """ with gc_disabled(): z = Expect._eval_line(self, line, allow_use_file=allow_use_file, @@ -629,8 +627,8 @@ def eval(self, code, strip=True, **kwds): INPUT: - - code -- str - - strip -- Default is True and removes ``\n`` + - ``code`` -- str + - ``strip`` -- default is ``True`` and removes ``\n`` EXAMPLES:: @@ -772,7 +770,7 @@ def help(self, string): INPUT: - - ``string`` -- a string to search for in the giac help system + - ``string`` -- string to search for in the giac help system EXAMPLES:: @@ -804,7 +802,6 @@ def version(self): sage: giac.version() "giac... - """ return giac('version()') @@ -814,7 +811,7 @@ class GiacFunction(ExpectFunction): def _instancedoc_(self): """ Return the Giac help for this function. This gets called when - doing "?" on self. + doing ``?`` on ``self``. EXAMPLES:: @@ -830,7 +827,7 @@ class GiacFunctionElement(FunctionElement): def _instancedoc_(self): """ Return the Giac help for this function. This gets called when - doing "?" on self. + doing ``?`` on ``self``. EXAMPLES:: @@ -845,7 +842,7 @@ def _instancedoc_(self): class GiacElement(ExpectElement): def __float__(self): """ - Return a floating point version of self. + Return a floating point version of ``self``. EXAMPLES:: @@ -858,7 +855,7 @@ def __float__(self): def unapply(self, var): """ - Creates a Giac function in the given arguments from a Giac symbol. + Create a Giac function in the given arguments from a Giac symbol. EXAMPLES:: @@ -888,7 +885,7 @@ def __hash__(self): def _richcmp_(self, other, op): """ - Compare equality between self and other, using giac. + Compare equality between ``self`` and ``other``, using giac. These examples are optional, and require Giac to be installed. You do not need to install any Sage packages for this. @@ -1012,7 +1009,6 @@ def _latex_(self): sage: gf = giac('(x^4 - y)/(y^2-3*x)') sage: latex(gf) # output changed slightly from 1.5.0-63 to 1.5.0-87 \frac{...x^{4}...-...y...}{...y^{2}-3...x...} - """ s = self.parent().eval('latex(%s)' % self.name()) if s.startswith('"'): @@ -1145,19 +1141,17 @@ def _sage_(self, locals=None): def integral(self, var='x', min=None, max=None): r""" - Return the integral of self with respect to the variable x. + Return the integral of ``self`` with respect to the variable `x`. INPUT: + - ``var`` -- variable - - ``var`` -- variable - - - ``min`` -- default: None - - - ``max`` -- default: None + - ``min`` -- (default: ``None``) + - ``max`` -- (default: ``None``) - This returns the definite integral if xmin is not None, otherwise + This returns the definite integral if xmin is not ``None``, otherwise an indefinite integral. EXAMPLES:: @@ -1185,17 +1179,17 @@ def integral(self, var='x', min=None, max=None): def sum(self, var, min=None, max=None): r""" - Return the sum of self with respect to the variable x. + Return the sum of ``self`` with respect to the variable `x`. INPUT: - - ``var`` -- variable + - ``var`` -- variable - - ``min`` -- default: None + - ``min`` -- (default: ``None``) - - ``max`` -- default: None + - ``max`` -- (default: ``None``) - This returns the definite integral if xmin is not None, otherwise + This returns the definite integral if xmin is not ``None``, otherwise an indefinite integral. EXAMPLES:: diff --git a/src/sage/interfaces/gnuplot.py b/src/sage/interfaces/gnuplot.py index 3b3d7db7b9b..f9ddc8da914 100644 --- a/src/sage/interfaces/gnuplot.py +++ b/src/sage/interfaces/gnuplot.py @@ -63,22 +63,18 @@ def plot(self, cmd, file=None, verbose=True, reset=True): INPUT: + - ``cmd`` -- string - - ``cmd`` -- string + - ``file`` -- string (default: ``None``); if specified save + plot to given file, which may be either an eps (default) or png file - - ``file`` -- string (default: None), if specified save - plot to given file, which may be either an eps (default) or png - file. - - - ``verbose`` -- print some info - - - ``reset`` -- True: reset gnuplot before making - graph + - ``verbose`` -- print some info + - ``reset`` -- true; reset gnuplot before making graph OUTPUT: displays graph - .. note:: + .. NOTE:: Note that ``^`` s are replaced by ``**`` s before being passed to gnuplot. """ @@ -144,19 +140,18 @@ def plot3d_parametric(self, f='cos(u)*(3 + v*cos(u/2)), sin(u)*(3 + v*cos(u/2)), INPUT: - - ``f`` -- (string) a function of two variables, e.g., - 'cos(u)\*(3 + v\*cos(u/2)), sin(u)\*(3 + v\*cos(u/2)), - v\*sin(u/2)' + - ``f`` -- string; a function of two variables, e.g., + ``'cos(u)\*(3 + v\*cos(u/2)), sin(u)\*(3 + v\*cos(u/2)), v\*sin(u/2)'`` - - ``range1`` -- (string) range of values for one - variable, e.g., '[u=-pi:pi]' + - ``range1`` -- string; range of values for one + variable, e.g., ``'[u=-pi:pi]'`` - - ``range2`` -- (string) range of values for another - variable, e.g., '[v=-0.2:0.2]' + - ``range2`` -- string; range of values for another + variable, e.g., ``'[v=-0.2:0.2]'`` - - ``samples`` -- (int) number of sample points to use + - ``samples`` -- integer; number of sample points to use - - ``title`` -- (string) title of the graph. + - ``title`` -- string; title of the graph EXAMPLES:: @@ -181,7 +176,7 @@ def plot3d_parametric(self, f='cos(u)*(3 + v*cos(u/2)), sin(u)*(3 + v*cos(u/2)), def interact(self, cmd): import tempfile - with tempfile.NamedTemporaryFile(mode="w+t") as f: + with tempfile.NamedTemporaryFile(mode='w+t') as f: f.write(cmd + '\n pause -1 "Press return to continue (no further rotation possible)"') os.system(f'gnuplot -persist {f.name}') diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 9459396d3e4..b98c050d889 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -167,14 +167,18 @@ class Gp(ExtraTabCompletion, Expect): INPUT: - - ``stacksize`` (int, default 10000000) -- the initial PARI - stacksize in bytes (default 10MB) - - ``script_subdirectory`` (string, default None) -- name of the subdirectory of SAGE_EXTCODE/pari from which to read scripts - - ``logfile`` (string, default None) -- log file for the pexpect interface + - ``stacksize`` -- integer (default: 10000000); the initial PARI + stacksize in bytes (default: 10MB) + - ``script_subdirectory`` -- string (default: ``None``); name of the + subdirectory of ``SAGE_EXTCODE/pari`` from which to read scripts + - ``logfile`` -- string (default: ``None``); log file for the pexpect + interface - ``server`` -- name of remote server - ``server_tmpdir`` -- name of temporary directory on remote server - - ``init_list_length`` (int, default 1024) -- length of initial list of local variables. - - ``seed`` (int, default random) -- random number generator seed for pari + - ``init_list_length`` -- integer (default: 1024); length of initial + list of local variables + - ``seed`` -- integer (default: random); random number generator seed + for pari EXAMPLES:: @@ -193,14 +197,18 @@ def __init__(self, stacksize=10000000, # 10MB INPUT: - - ``stacksize`` (int, default 10000000) -- the initial PARI - stacksize in bytes (default 10MB) - - ``script_subdirectory`` (string, default None) -- name of the subdirectory of SAGE_EXTCODE/pari from which to read scripts - - ``logfile`` (string, default None) -- log file for the pexpect interface + - ``stacksize`` -- integer (default: 10000000); the initial PARI + stacksize in bytes (default: 10MB) + - ``script_subdirectory`` -- string (default: ``None``); name of the + subdirectory of SAGE_EXTCODE/pari from which to read scripts + - ``logfile`` -- string (default: ``None``); log file for the pexpect + interface - ``server`` -- name of remote server - ``server_tmpdir`` -- name of temporary directory on remote server - - ``init_list_length`` (int, default 1024) -- length of initial list of local variables. - - ``seed`` (int,default random nonzero 31 bit integer) -- value of random seed + - ``init_list_length`` -- integer (default: 1024); length of initial + list of local variables. + - ``seed`` -- integer (default random nonzero 31 bit integer); value of + random seed EXAMPLES:: @@ -290,7 +298,7 @@ def __reduce__(self): def _function_class(self): """ - Returns the GpFunction class. + Return the GpFunction class. EXAMPLES:: @@ -303,7 +311,7 @@ def _function_class(self): def _quit_string(self): """ - Returns the string used to quit the GP interpreter. + Return the string used to quit the GP interpreter. EXAMPLES:: @@ -324,7 +332,7 @@ def _quit_string(self): def _read_in_file_command(self, filename): r""" - Returns the string used to read filename into GP. + Return the string used to read filename into GP. EXAMPLES:: @@ -376,7 +384,7 @@ def get_precision(self): def set_precision(self, prec): """ - Sets the PARI precision (in decimal digits) for real + Set the PARI precision (in decimal digits) for real computations, and returns the old value. .. NOTE:: @@ -415,7 +423,7 @@ def get_series_precision(self): def set_series_precision(self, prec=None): """ - Sets the PARI power series precision, and returns the old precision. + Set the PARI power series precision, and returns the old precision. EXAMPLES:: @@ -466,9 +474,8 @@ def cputime(self, t=None): INPUT: - - - ``t`` -- (default: None); if not None, then returns - time since t + - ``t`` -- (default: ``None``) if not None, then returns + time since t .. warning:: @@ -501,9 +508,9 @@ def set_default(self, var, value): INPUT: - - ``var`` (string) -- the name of a PARI gp - configuration variable. (See ``gp.default()`` for a list.) - - ``value`` -- the value to set the variable to. + - ``var`` -- string; the name of a PARI gp + configuration variable (see ``gp.default()`` for a list) + - ``value`` -- the value to set the variable to EXAMPLES:: @@ -526,12 +533,10 @@ def get_default(self, var): INPUT: - - ``var`` (string) -- the name of a PARI gp - configuration variable. (See ``gp.default()`` for a list.) - - OUTPUT: + - ``var`` -- string; the name of a PARI gp + configuration variable (see ``gp.default()`` for a list) - (string) the value of the variable. + OUTPUT: string; the value of the variable EXAMPLES:: @@ -553,7 +558,7 @@ def set(self, var, value): INPUT: - - ``var`` (string) -- a valid GP variable identifier + - ``var`` -- string; a valid GP variable identifier - ``value`` -- a value for the variable EXAMPLES:: @@ -573,7 +578,7 @@ def get(self, var): INPUT: - - ``var`` (string) -- a valid GP variable identifier + - ``var`` -- string; a valid GP variable identifier EXAMPLES:: @@ -589,7 +594,7 @@ def kill(self, var): INPUT: - - ``var`` (string) -- a valid GP variable identifier + - ``var`` -- string; a valid GP variable identifier EXAMPLES:: @@ -673,7 +678,7 @@ def console(self): def version(self): """ - Returns the version of GP being used. + Return the version of GP being used. EXAMPLES:: @@ -684,7 +689,7 @@ def version(self): def _object_class(self): """ - Returns the GpElement class. + Return the GpElement class. EXAMPLES:: @@ -697,7 +702,7 @@ def _object_class(self): def _function_element_class(self): """ - Returns the GpFunctionElement class. + Return the GpFunctionElement class. EXAMPLES:: @@ -710,7 +715,7 @@ def _function_element_class(self): def _true_symbol(self): """ - Returns the symbol used for truth in GP. + Return the symbol used for truth in GP. EXAMPLES:: @@ -726,7 +731,7 @@ def _true_symbol(self): def _false_symbol(self): """ - Returns the symbol used for falsity in GP. + Return the symbol used for falsity in GP. EXAMPLES:: @@ -742,7 +747,7 @@ def _false_symbol(self): def _equality_symbol(self): """ - Returns the symbol used for equality in GP. + Return the symbol used for equality in GP. EXAMPLES:: @@ -758,7 +763,7 @@ def _equality_symbol(self): def _exponent_symbol(self): """ - Returns the symbol to denote the exponent of a number in GP. + Return the symbol to denote the exponent of a number in GP. EXAMPLES:: @@ -775,7 +780,7 @@ def _exponent_symbol(self): def help(self, command): r""" - Returns GP's help for ``command``. + Return GP's help for ``command``. EXAMPLES:: @@ -786,7 +791,7 @@ def help(self, command): def new_with_bits_prec(self, s, precision=0): r""" - Creates a GP object from s with ``precision`` bits of + Create a GP object from s with ``precision`` bits of precision. GP actually automatically increases this precision to the nearest word (i.e. the next multiple of 32 on a 32-bit machine, or the next multiple of 64 on a 64-bit machine). @@ -955,11 +960,11 @@ def __bool__(self): def _complex_mpfr_field_(self, CC): """ - Return ComplexField element of self. + Return ComplexField element of ``self``. INPUT: - - ``CC`` -- a Complex or Real Field. + - ``CC`` -- a Complex or Real Field EXAMPLES:: @@ -982,7 +987,7 @@ def _complex_mpfr_field_(self, CC): def _complex_double_(self, CDF): """ - Returns this value as a CDF element. + Return this value as a CDF element. EXAMPLES:: @@ -1046,7 +1051,7 @@ def _tab_completion(self): def is_GpElement(x): """ - Return True if ``x`` is of type :class:`GpElement` + Return ``True`` if ``x`` is of type :class:`GpElement`. This function is deprecated; use :func:`isinstance` (of :class:`sage.interfaces.abc.GpElement`) instead. @@ -1074,7 +1079,7 @@ def is_GpElement(x): def reduce_load_GP(): """ - Returns the GP interface object defined in sage.interfaces.gp. + Return the GP interface object defined in ``sage.interfaces.gp``. EXAMPLES:: diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 9b398ded62f..6f2fb118968 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -179,7 +179,7 @@ def interact(self): Press :kbd:`Ctrl` + :kbd:`D` or type 'quit' or 'exit' to exit and return to Sage. - .. note:: + .. NOTE:: This is completely different than the console() member function. The console function opens a new copy of the @@ -275,7 +275,7 @@ def __call__(self, x, name=None): Check conversion of Booleans (:issue:`28705`):: - sage: giac(True) + sage: giac(True) # needs giac true sage: maxima(True) true @@ -320,10 +320,10 @@ def __call__(self, x, name=None): def _coerce_from_special_method(self, x): """ - Tries to coerce to self by calling a special underscore method. + Try to coerce to ``self`` by calling a special underscore method. - If no such method is defined, raises an AttributeError instead of a - TypeError. + If no such method is defined, raises an :exc:`AttributeError` instead + of a :exc:`TypeError`. """ s = '_%s_' % self.name() if s == '_maxima_lib_': @@ -343,7 +343,7 @@ def _coerce_impl(self, x, use_special=True): Check that python type ``complex`` can be converted (:issue:`31775`):: - sage: giac(complex(I))**2 # should not return `j^2` + sage: giac(complex(I))**2 # should not return `j^2` # needs giac -1 """ if isinstance(x, bool): @@ -434,7 +434,7 @@ def _inequality_symbol(self): def _relation_symbols(self): """ - Returns a dictionary with operators as the keys and their + Return a dictionary with operators as the keys and their string representation as the values. EXAMPLES:: @@ -444,13 +444,16 @@ def _relation_symbols(self): sage: symbols[operator.eq] '==' """ - return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()), - (operator.lt, self._lessthan_symbol()), (operator.le, "<="), - (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")]) + return {operator.eq: self._equality_symbol(), + operator.ne: self._inequality_symbol(), + operator.lt: self._lessthan_symbol(), + operator.le: "<=", + operator.gt: self._greaterthan_symbol(), + operator.ge: ">="} def _exponent_symbol(self): """ - Return the symbol used to denote ``*10^`` in floats, e.g 'e' in 1.5e6 + Return the symbol used to denote ``*10^`` in floats, e.g 'e' in 1.5e6. EXAMPLES:: @@ -549,7 +552,7 @@ def _function_element_class(self): def _convert_args_kwds(self, args=None, kwds=None): """ - Converts all of the args and kwds to be elements of this + Convert all of the ``args`` and ``kwds`` to be elements of this interface. EXAMPLES:: @@ -579,7 +582,7 @@ def _convert_args_kwds(self, args=None, kwds=None): def _check_valid_function_name(self, function): """ - Checks to see if function is a valid function name in this + Check to see if function is a valid function name in this interface. If it is not, an exception is raised. Otherwise, nothing is done. @@ -618,7 +621,7 @@ def function_call(self, function, args=None, kwds=None): def _function_call_string(self, function, args, kwds): """ - Returns the string used to make function calls. + Return the string used to make function calls. EXAMPLES:: @@ -713,7 +716,7 @@ def _instancedoc_(self): def is_InterfaceElement(x): """ - Return True if ``x`` is of type :class:`InterfaceElement`. + Return ``True`` if ``x`` is of type :class:`InterfaceElement`. EXAMPLES:: @@ -789,7 +792,7 @@ def __len__(self): def __reduce__(self): """ - The default linearisation is to return self's parent, + The default linearisation is to return ``self``'s parent, which will then get the items returned by :meth:`_reduce` as arguments to reconstruct the element. @@ -843,7 +846,6 @@ def __reduce__(self): Traceback (most recent call last): ... TypeError: unable to make sense of Maxima expression '"abc"' in Sage - """ return self.parent(), (self._reduce(),) @@ -851,11 +853,11 @@ def _reduce(self): """ Helper for pickling. - By default, if self is a string, then the representation of + By default, if ``self`` is a string, then the representation of that string is returned (not the string itself). Otherwise, it is attempted to return the corresponding Sage object. - If this fails with a NotImplementedError, the string - representation of self is returned instead. + If this fails with a :exc:`NotImplementedError`, the string + representation of ``self`` is returned instead. EXAMPLES:: @@ -890,7 +892,6 @@ def _reduce(self): ....: # does not accidentally lead to success sage: loads(b) [1] "abc" - """ if self.is_string(): return repr(self.sage()) @@ -921,8 +922,8 @@ def _instancedoc_(self): def __hash__(self): """ - Returns the hash of self. This is a default implementation of hash - which just takes the hash of the string of self. + Return the hash of ``self``. This is a default implementation of hash + which just takes the hash of the string of ``self``. """ return hash('%s' % self) @@ -961,7 +962,6 @@ def _richcmp_(self, other, op): sage: gap('DihedralGroup(8)')==gap('DihedralGroup(8)') False - """ P = self._check_valid() try: @@ -1161,7 +1161,6 @@ def __repr__(self): sage: singular.quit() sage: s (invalid Singular object -- The singular session in which this object was defined is no longer running.) - """ try: self._check_valid() @@ -1197,12 +1196,12 @@ def _repr_(self): sage: gap(2) 2 sage: x = var('x') - sage: giac(x) + sage: giac(x) # needs giac sageVARx - sage: giac(5) + sage: giac(5) # needs giac 5 sage: M = matrix(QQ,2,range(4)) - sage: giac(M) + sage: giac(M) # needs giac [[0,1],[2,3]] sage: x = var('x') # optional - maple sage: maple(x) # optional - maple @@ -1217,7 +1216,6 @@ def _repr_(self): sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat sage: S = mupad.examples.SymmetricFunctions(); S # optional - mupad-Combinat examples::SymmetricFunctions(Dom::ExpressionField()) - """ P = self.parent() try: @@ -1238,7 +1236,7 @@ def __getattr__(self, attrname): def get_using_file(self): """ Return this element's string representation using a file. Use this - if self has a huge string representation. It'll be way faster. + if ``self`` has a huge string representation. It'll be way faster. EXAMPLES:: @@ -1254,7 +1252,7 @@ def get_using_file(self): def hasattr(self, attrname): """ - Returns whether the given attribute is already defined by this + Return whether the given attribute is already defined by this object, and in particular is not dynamically generated. EXAMPLES:: @@ -1318,7 +1316,6 @@ def bool(self): False sage: singular(1).bool() True - """ return bool(self) @@ -1344,7 +1341,7 @@ def __bool__(self): By default this returns ``True`` for elements that are considered to be not ``False`` by the interface (:issue:`28705`):: - sage: bool(giac('"a"')) + sage: bool(giac('"a"')) # needs giac True """ P = self._check_valid() @@ -1396,9 +1393,9 @@ def _rational_(self): def name(self, new_name=None): """ - Returns the name of self. If new_name is passed in, then this - function returns a new object identical to self whose name is - new_name. + Return the name of ``self``. If ``new_name`` is passed in, then this + function returns a new object identical to ``self`` whose name is + ``new_name``. Note that this can overwrite existing variables in the system. @@ -1447,11 +1444,11 @@ def _operation(self, operation, other=None): INPUT: - - ``operation`` -- a string representing the operation - being performed. For example, '*', or '1/'. + - ``operation`` -- string representing the operation + being performed; for example, '*', or '1/' - - ``other`` -- the other operand. If ``other`` is ``None``, - then the operation is assumed to be unary rather than binary. + - ``other`` -- the other operand; if ``other`` is ``None``, + then the operation is assumed to be unary rather than binary OUTPUT: an interface element diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py index add4b453b3d..f8f497172b9 100644 --- a/src/sage/interfaces/jmoldata.py +++ b/src/sage/interfaces/jmoldata.py @@ -52,7 +52,7 @@ def __init__(self): def is_jvm_available(self): """ - Returns True if the Java Virtual Machine is available and False if not. + Return ``True`` if the Java Virtual Machine is available and ``False`` if not. EXAMPLES: @@ -81,7 +81,6 @@ def jmolpath(self): sage: JData = JmolData() sage: JData.jmolpath() # needs jmol '.../JmolData.jar' - """ jmolpath = JmolDataJar().absolute_filename() @@ -89,7 +88,7 @@ def jmolpath(self): def is_jmol_available(self): """ - Returns True if jmol is available and False if not. + Return ``True`` if jmol is available and ``False`` if not. EXAMPLES: @@ -120,24 +119,22 @@ def export_image(self, INPUT: - - targetfile -- the full path to the file where the image - should be written. - - - datafile -- full path to the data file Jmol can read or - text of a script telling Jmol what to read or load. + - ``targetfile`` -- the full path to the file where the image + should be written - - datafile_cmd -- (default ``'script'``) ``'load'`` or ``'script'`` - should be ``"load"`` for a data file. + - ``datafile`` -- full path to the data file Jmol can read or + text of a script telling Jmol what to read or load - - image_type -- (default ``"PNG"``) ``'PNG'`` ``'JPG'`` or ``'GIF'`` + - ``datafile_cmd`` -- (default: ``'script'``) ``'load'`` or ``'script'`` + should be ``'load'`` for a data file - - figsize -- number (default 5) equal to (pixels/side)/100 + - ``image_type`` -- (default: ``"PNG"``) ``'PNG'`` ``'JPG'`` or ``'GIF'`` - OUTPUT: + - ``figsize`` -- number (default: 5) equal to (pixels/side)/100 - Image file, .png, .gif or .jpg (default .png) + OUTPUT: image file, .png, .gif or .jpg (default: .png) - .. note:: + .. NOTE:: Examples will generate an error message if a functional Java Virtual Machine (JVM) is not installed on the machine the Sage instance is running on. @@ -147,7 +144,7 @@ def export_image(self, Programmers using this module should check that the JVM is available before making calls to avoid the user getting error messages. Check for the JVM using the function - :meth:`is_jvm_available`, which returns True if a JVM is available. + :meth:`is_jvm_available`, which returns ``True`` if a JVM is available. EXAMPLES: @@ -171,12 +168,12 @@ def export_image(self, sage: JData = JmolData() sage: D = dodecahedron() # needs sage.plot sage: from tempfile import NamedTemporaryFile - sage: archive = NamedTemporaryFile(suffix=".zip") + sage: archive = NamedTemporaryFile(suffix='.zip') sage: D.export_jmol(archive.name) # needs sage.plot sage: archive_native = archive.name sage: script = f'set defaultdirectory "f{archive_native}"\n' sage: script += 'script SCRIPT\n' - sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional - java, needs sage.plot + sage: with NamedTemporaryFile(suffix='.png') as testfile: # optional - java, needs sage.plot ....: JData.export_image(targetfile=testfile.name, ....: datafile=script, ....: image_type="PNG") @@ -196,7 +193,7 @@ def export_image(self, imagescript = 'write {} {!r}\n'.format(image_type, target_native) size_arg = "%sx%s" % (figsize * 100, figsize * 100) # Scratch file for Jmol errors - scratchout = tmp_filename(ext=".txt") + scratchout = tmp_filename(ext='.txt') with open(scratchout, 'w') as jout: # Now call the java application and write the file. env = dict(os.environ) diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index c86180e920b..ddcc2128588 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -142,7 +142,7 @@ ext1 := 1, ext2 := Unassign -.. note:: +.. NOTE:: For some very large numbers KASH's integer factorization seems much faster than PARI's (which is the default in Sage). @@ -405,7 +405,7 @@ The KASH interface reads in even very long input (using files) in a robust manner, as long as you are creating a new object. -.. note:: +.. NOTE:: Using ``kash.eval`` for long input is much less robust, and is not recommended. @@ -460,11 +460,12 @@ def __init__(self, server_tmpdir=None): """ INPUT: - max_workspace_size -- (default: None) - set maximal workspace memory usage to - stands for byte-wise allocation - k stands for kilobyte-wise allocation - m stands for megabyte-wise allocation + + - ``max_workspace_size`` -- (default: ``None``) + set maximal workspace memory usage to + stands for byte-wise allocation + k stands for kilobyte-wise allocation + m stands for megabyte-wise allocation """ cmd = "kash3 -b -c -d " if max_workspace_size is not None: @@ -541,14 +542,12 @@ def eval(self, x, newlines=False, strip=True, **kwds): INPUT: + - ``s`` -- string containing Kash code - - ``s`` -- string containing Kash code. - - - ``newlines`` -- bool (default: ``True``); if False, - remove all backslash-newlines inserted by the Kash output - formatter. + - ``newlines`` -- boolean (default: ``True``); if ``False``, + remove all backslash-newlines inserted by the Kash output formatter - - ``strip`` -- ignored + - ``strip`` -- ignored """ x = str(x) x = x.rstrip() @@ -763,7 +762,6 @@ def _sage_(self, locals={}, *args): sage541.1^2 + sage541.1 sage: ka.sage({kR.1: x}) # optional -- kash x^2 + x - """ string = self._sage_repr() @@ -791,7 +789,7 @@ def __repr__(self): def is_KashElement(x): """ - Returns True if ``x`` is of type :class:`KashElement`. + Return ``True`` if ``x`` is of type :class:`KashElement`. EXAMPLES:: diff --git a/src/sage/interfaces/kenzo.py b/src/sage/interfaces/kenzo.py index 16d4bb25708..00de1d4b455 100644 --- a/src/sage/interfaces/kenzo.py +++ b/src/sage/interfaces/kenzo.py @@ -119,15 +119,13 @@ def Sphere(n): r""" - Return the ``n`` dimensional sphere as a Kenzo simplicial set. + Return the `n` dimensional sphere as a Kenzo simplicial set. INPUT: - ``n`` -- the dimension of the sphere - OUTPUT: - - - A :class:`KenzoSimplicialSet` + OUTPUT: a :class:`KenzoSimplicialSet` EXAMPLES:: @@ -145,21 +143,19 @@ def Sphere(n): def MooreSpace(m, n): r""" - Return the Moore space ``M(m, n)`` as a Kenzo simplicial set. + Return the Moore space `M(m, n)` as a Kenzo simplicial set. - The Moore space ``M(m, n)`` is the space whose n'th homology group - is isomorphic to the cyclic group of order ``m``, and the rest of the + The Moore space `M(m, n)` is the space whose `n`-th homology group + is isomorphic to the cyclic group of order `m`, and the rest of the homology groups are trivial. INPUT: - - ``m`` -- A positive integer. The order of the nontrivial homology group. - - - ``n`` -- The dimension in which the homology is not trivial + - ``m`` -- positive integer; the order of the nontrivial homology group - OUTPUT: + - ``n`` -- the dimension in which the homology is not trivial - - A KenzoSimplicialSet + OUTPUT: a KenzoSimplicialSet EXAMPLES:: @@ -184,14 +180,12 @@ def EilenbergMacLaneSpace(G, n): INPUT: - - ``G`` -- group. Currently only ``ZZ`` and the additive group of two - elements are supported. + - ``G`` -- group; currently only ``ZZ`` and the additive group of two + elements are supported - ``n`` -- the dimension in which the homotopy is not trivial - OUTPUT: - - - A :class:`KenzoSimplicialGroup` + OUTPUT: a :class:`KenzoSimplicialGroup` EXAMPLES:: @@ -219,12 +213,12 @@ def EilenbergMacLaneSpace(G, n): class KenzoObject(SageObject): r""" - Wrapper to Kenzo objects + Wrapper to Kenzo objects. INPUT: - ``kenzo_object`` -- a wrapper around a Kenzo object - (which is an ecl object). + (which is an ecl object) """ def __init__(self, kenzo_object): @@ -243,7 +237,6 @@ def __init__(self, kenzo_object): sage: s2 [K1 Simplicial-Set] sage: TestSuite(s2).run(skip='_test_pickling') - """ self._kenzo = kenzo_object @@ -272,15 +265,15 @@ class KenzoSpectralSequence(KenzoObject): def group(self, p, i, j): r""" - Return the ``i,j``'th group of the ``p`` page. + Return the ``i,j``-th group of the ``p`` page. INPUT: - - ``p`` -- the page to take the group from. + - ``p`` -- the page to take the group from - - ``i`` -- the column where the group is taken from. + - ``i`` -- the column where the group is taken from - - ``j`` -- the row where the group is taken from. + - ``j`` -- the row where the group is taken from EXAMPLES:: @@ -301,15 +294,15 @@ def group(self, p, i, j): def matrix(self, p, i, j): r""" Return the matrix that determines the differential from the - ``i,j``'th group of the ``p``'th page. + ``i,j``-th group of the ``p``-th page. INPUT: - - ``p`` -- the page. + - ``p`` -- the page - - ``i`` -- the column of the differential domain. + - ``i`` -- the column of the differential domain - - ``j`` -- the row of the differential domain. + - ``j`` -- the row of the differential domain EXAMPLES:: @@ -342,11 +335,11 @@ def differential(self, p, i, j): INPUT: - - ``p`` -- the page. + - ``p`` -- the page - - ``i`` -- the column of the differential domain. + - ``i`` -- the column of the differential domain - - ``j`` -- the row of the differential domain. + - ``j`` -- the row of the differential domain EXAMPLES:: @@ -377,15 +370,15 @@ def table(self, p, i1, i2, j1, j2): INPUT: - - ``p`` -- the page to print. + - ``p`` -- the page to print - -- ``i1`` -- the first column to print. + -- ``i1`` -- the first column to print - -- ``i2`` -- the last column to print. + -- ``i2`` -- the last column to print - -- ``j1`` -- the first row to print. + -- ``j1`` -- the first row to print - -- ``j2`` -- the last row to print. + -- ``j2`` -- the last row to print EXAMPLES:: @@ -421,16 +414,14 @@ class KenzoChainComplex(KenzoObject): """ def homology(self, n): r""" - Return the ``n``'th homology group of the chain complex associated to this + Return the `n`-th homology group of the chain complex associated to this kenzo object. INPUT: - ``n`` -- the dimension in which compute the homology - OUTPUT: - - - A homology group. + OUTPUT: a homology group EXAMPLES:: @@ -446,10 +437,10 @@ def homology(self, n): m1 = __chcm_mat__(echcm1, n) m2 = __chcm_mat__(echcm1, n + 1) homology = __homologie__(m1, m2) - lhomomology = [i for i in EclListIterator(homology)] + lhomomology = list(EclListIterator(homology)) res = [] for component in lhomomology: - pair = [i for i in EclListIterator(component)] + pair = list(EclListIterator(component)) res.append(pair[0].python()) return HomologyGroup(len(res), ZZ, res) @@ -459,11 +450,9 @@ def tensor_product(self, other): INPUT: - - ``other`` -- The Kenzo object with which to compute the tensor product - - OUTPUT: + - ``other`` -- The Kenzo object with which to compute the tensor product - - A :class:`KenzoChainComplex` + OUTPUT: a :class:`KenzoChainComplex` EXAMPLES:: @@ -486,11 +475,9 @@ def basis(self, dim): INPUT: - - ``dim`` -- An integer number - - OUTPUT: + - ``dim`` -- integer - - A list of the form ['G"dim"G0', 'G"dim"G1', 'G"dim"G2', ...]. + OUTPUT: list of the form ['G"dim"G0', 'G"dim"G1', 'G"dim"G2', ...] EXAMPLES:: @@ -518,9 +505,7 @@ def identity_morphism(self): r""" Return the identity morphism (degree 0) between ``self`` and itself. - OUTPUT: - - - A :class:`KenzoChainComplexMorphism` + OUTPUT: a :class:`KenzoChainComplexMorphism` EXAMPLES:: @@ -541,14 +526,14 @@ def null_morphism(self, target=None, degree=None): INPUT: - - ``target`` -- A KenzoChainComplex or None (default). - - ``degree`` -- An integer number or None (default). + - ``target`` -- a KenzoChainComplex or ``None`` (default) + - ``degree`` -- integer or ``None`` (default) OUTPUT: - A :class:`KenzoChainComplexMorphism` representing the null morphism between - ``self`` and ``target`` of degree ``degree``. If ``target`` takes None value, - ``self`` is assumed as the target chain complex; if ``degree`` takes None value, + ``self`` and ``target`` of degree ``degree``. If ``target`` takes ``None`` value, + ``self`` is assumed as the target chain complex; if ``degree`` takes ``None`` value, 0 is assumed as the degree of the null morphism. EXAMPLES:: @@ -587,10 +572,10 @@ def differential(self, dim=None, comb=None): INPUT: - - ``dim`` -- An integer number or None (default) + - ``dim`` -- integer or ``None`` (default) - - ``comb`` -- A list representing a formal sum of generators in the module - of dimension ``dim`` or None (default). For example, to represent + - ``comb`` -- list representing a formal sum of generators in the module + of dimension ``dim`` or ``None`` (default). For example, to represent G7G12 + 3*G7G0 - 5*G7G3 we use the list [3, 'G7G0', -5, 'G7G3', 1, 'G7G12']. Note that the generators must be in ascending order respect to the number after the second G in their representation; the parameter @@ -599,10 +584,10 @@ def differential(self, dim=None, comb=None): OUTPUT: - - If ``dim`` and ``comb`` are not None, it returns a Kenzo combination + - If ``dim`` and ``comb`` are not ``None``, it returns a Kenzo combination representing the differential of the formal combination represented by ``comb`` in the chain complex ``self`` in dimension ``dim``. On the other - hand, if `dim`` or ``comb`` (or both) take None value, the differential + hand, if ``dim`` or ``comb`` (or both) take ``None`` value, the differential :class:`KenzoMorphismChainComplex` of ``self`` is returned. EXAMPLES:: @@ -643,7 +628,7 @@ def differential(self, dim=None, comb=None): def orgn(self): r""" - Return the :orgn slot of Kenzo, which stores as a list the origin of the object + Return the :orgn slot of Kenzo, which stores as a list the origin of the object. EXAMPLES:: @@ -670,16 +655,14 @@ class KenzoSimplicialSet(KenzoChainComplex): def loop_space(self, n=1): r""" - Return the ``n`` th iterated loop space. + Return the `n`-th iterated loop space. INPUT: - ``n`` -- (default: 1) the number of times to iterate the loop space construction - OUTPUT: - - - A :class:`KenzoSimplicialGroup` + OUTPUT: a :class:`KenzoSimplicialGroup` EXAMPLES:: @@ -703,9 +686,7 @@ def cartesian_product(self, other): - ``other`` -- the Kenzo simplicial set with which the product is made - OUTPUT: - - - A :class:`KenzoSimplicialSet` + OUTPUT: a :class:`KenzoSimplicialSet` EXAMPLES:: @@ -726,9 +707,7 @@ def suspension(self): r""" Return the suspension of the simplicial set. - OUTPUT: - - - A :class:`KenzoSimplicialSet` + OUTPUT: a :class:`KenzoSimplicialSet` EXAMPLES:: @@ -745,7 +724,7 @@ def suspension(self): def homotopy_group(self, n): """ - Return the n'th homotopy group of ``self`` + Return the `n`-th homotopy group of ``self``. INPUT: @@ -780,9 +759,7 @@ def em_spectral_sequence(self): r""" Return the Eilenberg-Moore spectral sequence of ``self``. - OUTPUT: - - - A :class:`KenzoSpectralSequence` + OUTPUT: a :class:`KenzoSpectralSequence` EXAMPLES:: @@ -812,9 +789,7 @@ def sw_spectral_sequence(self): r""" Return the Serre sequence of the first step of the Whitehead tower. - OUTPUT: - - - A :class:`KenzoSpectralSequence` + OUTPUT: a :class:`KenzoSpectralSequence` EXAMPLES:: @@ -839,11 +814,9 @@ def serre_spectral_sequence(self): r""" Return the spectral sequence of ``self``. - The object self must be created as a cartesian product (twisted or not). - - OUTPUT: + The object ``self`` must be created as a cartesian product (twisted or not). - - A :class:`KenzoSpectralSequence` + OUTPUT: a :class:`KenzoSpectralSequence` EXAMPLES:: @@ -877,9 +850,7 @@ def wedge(self, other): - ``other`` -- the Kenzo simplicial set with which the wedge is made - OUTPUT: - - - A :class:`KenzoSimplicialSet` + OUTPUT: a :class:`KenzoSimplicialSet` EXAMPLES:: @@ -904,9 +875,7 @@ def join(self, other): - ``other`` -- the Kenzo simplicial set with which the join is made - OUTPUT: - - - A :class:`KenzoSimplicialSet` + OUTPUT: a :class:`KenzoSimplicialSet` EXAMPLES:: @@ -931,9 +900,7 @@ def smash_product(self, other): - ``other`` -- the Kenzo simplicial set with which the smash product is made - OUTPUT: - - - A :class:`KenzoSimplicialSet` + OUTPUT: a :class:`KenzoSimplicialSet` EXAMPLES:: @@ -960,9 +927,7 @@ def classifying_space(self): r""" Return the classifying space. - OUTPUT: - - - A :class:`KenzoSimplicialGroup` + OUTPUT: a :class:`KenzoSimplicialGroup` EXAMPLES:: @@ -985,7 +950,7 @@ def k2s_matrix(kmatrix): INPUT: - - ``kmatrix`` -- An array in ECL + - ``kmatrix`` -- an array in ECL EXAMPLES:: @@ -1008,11 +973,9 @@ def s2k_matrix(smatrix): INPUT: - - ``smatrix`` -- A matrix in Sage + - ``smatrix`` -- a matrix in Sage - OUTPUT: - - - A :class:`EclObject` + OUTPUT: a :class:`EclObject` EXAMPLES:: @@ -1035,11 +998,9 @@ def s2k_dictmat(sdictmat): INPUT: - - ``sdictmat`` -- A dictionary in Sage - - OUTPUT: + - ``sdictmat`` -- dictionary in Sage - - A :class:`EclObject` + OUTPUT: a :class:`EclObject` EXAMPLES:: @@ -1049,7 +1010,6 @@ def s2k_dictmat(sdictmat): sage: d = {1 : A, 2 : B} sage: s2k_dictmat(d) # optional - kenzo - """ rslt = EclObject([]) for k in sdictmat.keys(): @@ -1063,11 +1023,9 @@ def pairing(slist): INPUT: - - ``slist`` -- A list in Sage + - ``slist`` -- list in Sage - OUTPUT: - - - A :class:`EclObject` + OUTPUT: a :class:`EclObject` EXAMPLES:: @@ -1084,16 +1042,14 @@ def pairing(slist): def KChainComplex(chain_complex): r""" - Construct a KenzoChainComplex from a ChainComplex of degree = -1 in + Construct a KenzoChainComplex from a ChainComplex of degree `-1` in Sage. INPUT: - - ``chain_complex`` -- A ChainComplex of degree = -1 - - OUTPUT: + - ``chain_complex`` -- a ChainComplex of degree `-1` - - A KenzoChainComplex + OUTPUT: a KenzoChainComplex EXAMPLES:: @@ -1122,15 +1078,13 @@ def SChainComplex(kchaincomplex, start=0, end=15): INPUT: - - ``kchaincomplex`` -- A KenzoChainComplex + - ``kchaincomplex`` -- a KenzoChainComplex - - ``start`` -- An integer number (default: 0) + - ``start`` -- integer (default: 0) - - ``end`` -- An integer number greater than or equal to ``start`` (default: 15) + - ``end`` -- integer greater than or equal to ``start`` (default: 15) - OUTPUT: - - - A ChainComplex + OUTPUT: a ChainComplex EXAMPLES:: @@ -1173,13 +1127,11 @@ def SAbstractSimplex(simplex, dim): INPUT: - - ``simplex`` -- An abstract simplex of Kenzo. - - - ``dim`` -- The dimension of ``simplex``. + - ``simplex`` -- an abstract simplex of Kenzo - OUTPUT: + - ``dim`` -- the dimension of ``simplex`` - - An AbstractSimplex. + OUTPUT: an AbstractSimplex EXAMPLES:: @@ -1212,11 +1164,9 @@ def KAbstractSimplex(simplex): INPUT: - - ``simplex`` -- An AbstractSimplex. + - ``simplex`` -- an AbstractSimplex - OUTPUT: - - - An abstract simplex of Kenzo. + OUTPUT: an abstract simplex of Kenzo EXAMPLES:: @@ -1242,11 +1192,9 @@ def KFiniteSimplicialSet(sset): INPUT: - - ``sset`` -- A finite SimplicialSet. - - OUTPUT: + - ``sset`` -- a finite SimplicialSet - - A finite simplicial set of Kenzo. + OUTPUT: a finite simplicial set of Kenzo EXAMPLES:: @@ -1309,13 +1257,11 @@ def SFiniteSimplicialSet(ksimpset, limit): INPUT: - - ``ksimpset`` -- A finite simplicial set in Kenzo. - - - ``limit`` -- A natural number. + - ``ksimpset`` -- a finite simplicial set in Kenzo - OUTPUT: + - ``limit`` -- a natural number - - A finite SimplicialSet. + OUTPUT: a finite SimplicialSet EXAMPLES:: @@ -1363,7 +1309,7 @@ def SFiniteSimplicialSet(ksimpset, limit): bases.append(lbasis_k) names.append(names_k) all_simplices = __sfinitesimplicialset_aux1__(ksimpset._kenzo, limit) - lall_simplices = [i for i in EclListIterator(all_simplices)] + lall_simplices = list(EclListIterator(all_simplices)) dim = 1 for Kdim in lall_simplices: for simp in Kdim: @@ -1392,9 +1338,7 @@ def source_complex(self): r""" Return the source chain complex of the morphism. - OUTPUT: - - - A :class:`KenzoChainComplex` + OUTPUT: a :class:`KenzoChainComplex` EXAMPLES:: @@ -1419,9 +1363,7 @@ def target_complex(self): r""" Return the target chain complex of the morphism. - OUTPUT: - - - A :class:`KenzoChainComplex` + OUTPUT: a :class:`KenzoChainComplex` EXAMPLES:: @@ -1446,9 +1388,7 @@ def degree(self): r""" Return the degree of the morphism. - OUTPUT: - - - An integer number, the degree of the morphism. + OUTPUT: integer; the degree of the morphism EXAMPLES:: @@ -1479,9 +1419,9 @@ def evaluation(self, dim, comb): INPUT: - - ``dim`` -- An integer number + - ``dim`` -- integer - - ``comb`` -- A list representing a formal sum of generators in the module + - ``comb`` -- list representing a formal sum of generators in the module of dimension ``dim``. For example, to represent G7G12 + 3*G7G0 - 5*G7G3 we use the list [3, 'G7G0', -5, 'G7G3', 1, 'G7G12']. Note that the generators must be in ascending order respect to the number after the @@ -1563,9 +1503,7 @@ def opposite(self): r""" Return the opposite morphism of ``self``, i.e., -1 x ``self``. - OUTPUT: - - - A :class:`KenzoChainComplexMorphism` + OUTPUT: a :class:`KenzoChainComplexMorphism` EXAMPLES:: @@ -1609,8 +1547,9 @@ def composite(self, object=None): INPUT: - - ``object`` -- A KenzoChainComplexMorphism instance, a KenzoChainComplex instance, a tuple - of KenzoChainComplexMorphism and KenzoChainComplex instances, or None (default). + - ``object`` -- a KenzoChainComplexMorphism instance, a + KenzoChainComplex instance, a tuple of KenzoChainComplexMorphism and + KenzoChainComplex instances, or ``None`` (default). OUTPUT: @@ -1619,7 +1558,7 @@ def composite(self, object=None): the composite of ``self`` and the differential morphism of ``object`` is returned; if ``object`` is a tuple, the composite of ``self`` and the morphisms or the differential morphisms of the given chain complexes in ``object`` is returned (if ``object`` is - None, ``self`` morphism is returned). + ``None``, ``self`` morphism is returned). EXAMPLES:: @@ -1657,13 +1596,14 @@ def sum(self, object=None): INPUT: - - ``object`` -- A KenzoChainComplexMorphism instance, a tuple of KenzoChainComplexMorphism - instances or None (default). + - ``object`` -- a KenzoChainComplexMorphism instance, a tuple of + KenzoChainComplexMorphism instances or ``None`` (default) OUTPUT: - - A :class:`KenzoChainComplexMorphism`, sum of the morphism ``self`` and the morphism(s) - given by ``object`` (if ``object`` is None, ``self`` morphism is returned). + A :class:`KenzoChainComplexMorphism`, sum of the morphism ``self`` + and the morphism(s given by ``object`` (if ``object`` is ``None``, + ``self`` morphism is returned). EXAMPLES:: @@ -1717,20 +1657,20 @@ def sum(self, object=None): def substract(self, object=None): r""" - Return a morphism, difference of the morphism ``self`` and the morphism(s) given by the - parameter ``object``. + Return a morphism, difference of the morphism ``self`` and the + morphism(s) given by the parameter ``object``. INPUT: - - ``object`` -- A KenzoChainComplexMorphism instance, a tuple of KenzoChainComplexMorphism - instances or None (default). + - ``object`` -- a KenzoChainComplexMorphism instance, a tuple of + KenzoChainComplexMorphism instances or ``None`` (default) OUTPUT: - - A :class:`KenzoChainComplexMorphism`, difference of the morphism ``self`` and the - morphism(s) given by ``object`` (if ``object`` is None, ``self`` morphism is returned). - For example, if ``object`` = (mrph1, mrph2, mrph3) the result is - ``self`` - mrph1 - mrph2 - mrph3. + A :class:`KenzoChainComplexMorphism`, difference of the morphism + ``self`` and the morphism(s) given by ``object`` (if ``object`` is + ``None``, ``self`` morphism is returned). For example, if ``object`` = + (mrph1, mrph2, mrph3) the result is ``self`` - mrph1 - mrph2 - mrph3. EXAMPLES:: @@ -1789,9 +1729,9 @@ def change_source_target_complex(self, source=None, target=None): INPUT: - - ``source`` -- A KenzoChainComplex instance or None (default). + - ``source`` -- a KenzoChainComplex instance or ``None`` (default) - - ``target`` -- A KenzoChainComplex instance or None (default). + - ``target`` -- a KenzoChainComplex instance or ``None`` (default) OUTPUT: @@ -1838,9 +1778,9 @@ def destructive_change_source_target_complex(self, source=None, target=None): INPUT: - - ``source`` -- A KenzoChainComplex instance or None (default). + - ``source`` -- a KenzoChainComplex instance or ``None`` (default) - - ``target`` -- A KenzoChainComplex instance or None (default). + - ``target`` -- a KenzoChainComplex instance or ``None`` (default) OUTPUT: @@ -1884,24 +1824,22 @@ def build_morphism(source_complex, target_complex, degree, algorithm, strategy, INPUT: - - ``source_complex`` -- The source object as a KenzoChainComplex instance + - ``source_complex`` -- the source object as a KenzoChainComplex instance - - ``target_complex`` -- The target object as a KenzoChainComplex instance + - ``target_complex`` -- the target object as a KenzoChainComplex instance - - ``degree`` -- An integer number representing the degree of the morphism + - ``degree`` -- integer representing the degree of the morphism - - ``algorithm`` -- A Lisp function defining the mapping (:intr slot in Kenzo) + - ``algorithm`` -- a Lisp function defining the mapping (:intr slot in Kenzo) - - ``strategy`` -- The strategy (:strt slot in Kenzo), which must be one of + - ``strategy`` -- the strategy (:strt slot in Kenzo), which must be one of the two strings ``gnrt`` or ``cmbn``, depending if the ``algorithm`` (a Lisp function) uses as arguments a degree and a generator or a combination, respectively. - - ``orgn`` -- A list containing a description about the origin of the morphism - - OUTPUT: + - ``orgn`` -- list containing a description about the origin of the morphism - - A :class:`KenzoChainComplexMorphism` + OUTPUT: a :class:`KenzoChainComplexMorphism` EXAMPLES:: @@ -1928,15 +1866,13 @@ def build_morphism(source_complex, target_complex, degree, algorithm, strategy, def morphism_dictmat(morphism): r""" - Computes a list of matrices in ECL associated to a morphism in Sage. + Compute a list of matrices in ECL associated to a morphism in Sage. INPUT: - - ``morphism`` -- A morphism of chain complexes - - OUTPUT: + - ``morphism`` -- a morphism of chain complexes - - A :class:`EclObject` + OUTPUT: a :class:`EclObject` EXAMPLES:: @@ -1962,11 +1898,9 @@ def KChainComplexMorphism(morphism): INPUT: - - ``morphism`` -- A morphism of chain complexes + - ``morphism`` -- a morphism of chain complexes - OUTPUT: - - - A :class:`KenzoChainComplexMorphism` + OUTPUT: a :class:`KenzoChainComplexMorphism` EXAMPLES:: @@ -1991,15 +1925,13 @@ def KChainComplexMorphism(morphism): def s2k_listofmorphisms(l): r""" - Computes a list of morphisms of chain complexes in Kenzo from a list of morphisms in Sage. + Compute a list of morphisms of chain complexes in Kenzo from a list of morphisms in Sage. INPUT: - - ``l`` -- A list of morphisms of chain complexes - - OUTPUT: + - ``l`` -- list of morphisms of chain complexes - - A :class:`EclObject` + OUTPUT: a :class:`EclObject` EXAMPLES:: @@ -2025,11 +1957,9 @@ def BicomplexSpectralSequence(l): INPUT: - - ``l`` -- A list of morphisms of chain complexes - - OUTPUT: + - ``l`` -- list of morphisms of chain complexes - - A :class:`KenzoSpectralSequence` + OUTPUT: a :class:`KenzoSpectralSequence` EXAMPLES:: diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 6923be55d53..775b8cff908 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -21,13 +21,13 @@ def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False, raw_output=False, verbose=False, **kwds): r""" - Call to the program count from LattE integrale + Call to the program count from LattE integrale. INPUT: - ``arg`` -- a cdd or LattE description string - - ``ehrhart_polynomial``, ``multivariate_generating_function`` -- to + - ``ehrhart_polynomial``, ``multivariate_generating_function`` -- to compute Ehrhart polynomial or multivariate generating function instead of just counting points @@ -205,7 +205,7 @@ def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False, if not ans: # opening a file is slow (30e-6s), so we read the file # numOfLatticePoints only in case of a IndexError above - with open(tempd.name + '/numOfLatticePoints', 'r') as f: + with open(tempd.name + '/numOfLatticePoints') as f: ans = f.read() if raw_output: @@ -222,23 +222,21 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v INPUT: - - ``arg`` -- a cdd or LattE description string. - - - ``polynomial`` -- multivariate polynomial or valid LattE polynomial description string. - If given, the valuation parameter of LattE is set to integrate, and is set to volume otherwise. + - ``arg`` -- a cdd or LattE description string - - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for - polytope triangulation or 'cone-decompose' for tangent cone decomposition method. + - ``polynomial`` -- multivariate polynomial or valid LattE polynomial description string + If given, the valuation parameter of LattE is set to integrate, and is set to volume otherwise - - ``raw_output`` -- if ``True`` then return directly the output string from LattE. + - ``algorithm`` -- (default: ``'triangulate'``) the integration method; use 'triangulate' for + polytope triangulation or 'cone-decompose' for tangent cone decomposition method - - ``verbose`` -- if ``True`` then return directly verbose output from LattE. + - ``raw_output`` -- if ``True`` then return directly the output string from LattE - - For all other options of the integrate program, consult the LattE manual. + - ``verbose`` -- if ``True`` then return directly verbose output from LattE - OUTPUT: + - For all other options of the integrate program, consult the LattE manual - Either a string (if ``raw_output`` if set to ``True``) or a rational. + OUTPUT: either a string (if ``raw_output`` if set to ``True``) or a rational EXAMPLES:: @@ -425,11 +423,9 @@ def to_latte_polynomial(polynomial): INPUT: - - ``polynomial`` -- a multivariate polynomial. - - OUTPUT: + - ``polynomial`` -- a multivariate polynomial - A string that describes the monomials list and exponent vectors. + OUTPUT: string that describes the monomials list and exponent vectors TESTS: diff --git a/src/sage/interfaces/lie.py b/src/sage/interfaces/lie.py index 71413162fd5..1824d2efcdb 100644 --- a/src/sage/interfaces/lie.py +++ b/src/sage/interfaces/lie.py @@ -17,7 +17,6 @@ To access the LiE interpreter directly, run lie_console(). - EXAMPLES:: sage: a4 = lie('A4') # optional - lie @@ -805,7 +804,6 @@ def _sage_(self): [ 3 -5 -2 9] sage: lie('-1X[1,1]').sage() # optional - lie -x0*x1 - """ t = self.type() if t == 'grp': diff --git a/src/sage/interfaces/lisp.py b/src/sage/interfaces/lisp.py index 158ed0f91c7..a324d7b76a8 100644 --- a/src/sage/interfaces/lisp.py +++ b/src/sage/interfaces/lisp.py @@ -82,7 +82,7 @@ def __init__(self, prompt='> ', # This is the command that starts up your program - command="ecl", + command='ecl', server=server, server_tmpdir=server_tmpdir, @@ -291,7 +291,7 @@ def console(self): def version(self): """ - Returns the version of Lisp being used. + Return the version of Lisp being used. EXAMPLES:: @@ -342,9 +342,9 @@ def _false_symbol(self): def _equality_symbol(self): """ - We raise a NotImplementedError when _equality_symbol is called since - equality testing in Lisp does not use infix notation and cannot be - done the same way as in the other interfaces. + We raise a :exc:`NotImplementedError` when ``_equality_symbol`` is + called since equality testing in Lisp does not use infix notation and + cannot be done the same way as in the other interfaces. EXAMPLES:: @@ -369,8 +369,8 @@ def help(self, command): def function_call(self, function, args=None, kwds=None): """ - Calls the Lisp function with given args and kwds. - For Lisp functions, the kwds are ignored. + Call the Lisp function with given ``args`` and ``kwds``. + For Lisp functions, the ``kwds`` are ignored. EXAMPLES:: @@ -404,7 +404,6 @@ def _richcmp_(self, other, op): False sage: two == 2 True - """ P = self._check_valid() if parent(other) is not P: diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 866ef8e1fbf..da15f7c26e4 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -14,13 +14,13 @@ The Macaulay2 interface offers three pieces of functionality: -- ``macaulay2_console()`` -- A function that dumps you - into an interactive command-line Macaulay2 session. +- ``macaulay2_console()`` -- a function that dumps you + into an interactive command-line Macaulay2 session -- ``macaulay2.eval(expr)`` -- Evaluation of arbitrary Macaulay2 - expressions, with the result returned as a string. +- ``macaulay2.eval(expr)`` -- evaluation of arbitrary Macaulay2 + expressions, with the result returned as a string -- ``macaulay2(expr)`` -- Creation of a Sage object that wraps a +- ``macaulay2(expr)`` -- creation of a Sage object that wraps a Macaulay2 object. This provides a Pythonic interface to Macaulay2. For example, if ``f = macaulay2(10)``, then ``f.gcd(25)`` returns the GCD of `10` and `25` computed using Macaulay2. @@ -152,7 +152,7 @@ def remove_output_labels(s) -> str: Return type: string - .. note:: + .. NOTE:: If ``s`` consists of several outputs and their labels have different width, it is possible that some strings will have leading @@ -255,8 +255,8 @@ def _read_in_file_command(self, filename): INPUT: - - filename: the name of the file to be loaded and executed - (type: string) + - ``filename`` -- string; the name of the file to be loaded and + executed OUTPUT: @@ -310,8 +310,8 @@ def eval(self, code, strip=True, **kwds): INPUT: - - code -- str - - strip -- ignored + - ``code`` -- string + - ``strip`` -- ignored EXAMPLES:: @@ -343,8 +343,8 @@ def set_seed(self, seed=None): INPUT: - - ``seed`` -- number (default: ``None``). If ``None``, it - is set to a random number. + - ``seed`` -- number (default: ``None``); if ``None``, it + is set to a random number OUTPUT: the new seed @@ -401,7 +401,7 @@ def get(self, var): - ``var`` -- string; the name of the variable in Macaulay2 - OUTPUT: a string of the textual representation of the variable in + OUTPUT: string of the textual representation of the variable in Macaulay2 EXAMPLES:: @@ -427,7 +427,7 @@ def set(self, var, value): INPUT: - ``var`` -- string; the name of the variable in Macaulay2 - - ``value`` -- a string to evaluate + - ``value`` -- string to evaluate EXAMPLES:: @@ -544,7 +544,6 @@ def console(self): Macaulay 2, version 1.1 with packages: Classic, Core, Elimination, IntegralClosure, LLLBases, Parsing, PrimaryDecomposition, SchurRings, TangentCone ... - """ macaulay2_console() @@ -584,7 +583,7 @@ def _install_hints(self): def _left_list_delim(self): """ - Returns the Macaulay2 left delimiter for lists. + Return the Macaulay2 left delimiter for lists. EXAMPLES:: @@ -595,7 +594,7 @@ def _left_list_delim(self): def _right_list_delim(self): """ - Returns the Macaulay2 right delimiter for lists. + Return the Macaulay2 right delimiter for lists. EXAMPLES:: @@ -606,7 +605,7 @@ def _right_list_delim(self): def _true_symbol(self): """ - Returns the Macaulay2 symbol for True. + Return the Macaulay2 symbol for True. EXAMPLES:: @@ -617,7 +616,7 @@ def _true_symbol(self): def _false_symbol(self): """ - Returns the Macaulay2 symbol for False. + Return the Macaulay2 symbol for False. EXAMPLES:: @@ -628,7 +627,7 @@ def _false_symbol(self): def _equality_symbol(self): """ - Returns the Macaulay2 symbol for equality. + Return the Macaulay2 symbol for equality. EXAMPLES:: @@ -674,12 +673,10 @@ def ideal(self, *gens): INPUT: - - gens -- list or tuple of Macaulay2 objects (or objects that can be + - ``gens`` -- list or tuple of Macaulay2 objects (or objects that can be made into Macaulay2 objects via evaluation) - OUTPUT: - - the Macaulay2 ideal generated by the given list of gens + OUTPUT: the Macaulay2 ideal generated by the given list of gens EXAMPLES:: @@ -693,7 +690,6 @@ def ideal(self, *gens): {-7} | xy6-2xy5+xy4-y7+2y6-y5 | {-5} | x2y3-x2y2-2xy4+2xy3+y5-y4 | {-3} | x3-3x2y+3xy2-y3 | - """ if len(gens) == 1 and isinstance(gens[0], (list, tuple)): gens = gens[0] @@ -712,8 +708,8 @@ def ring(self, base_ring='ZZ', vars='[x]', order='Lex'): INPUT: - ``base_ring`` -- base ring (see examples below) - - ``vars`` -- a tuple or string that defines the variable names - - ``order`` -- string (default: 'Lex'); the monomial order + - ``vars`` -- tuple or string that defines the variable names + - ``order`` -- string (default: ``'Lex'``); the monomial order OUTPUT: a Macaulay2 ring @@ -850,7 +846,6 @@ def new_from(self, type, value): MutableList{...3...} sage: list(l) # optional - macaulay2 [1, 2, 3] - """ type = self(type) value = self(value) @@ -1001,8 +996,8 @@ def name(self, new_name=None): INPUT: - - ``new_name`` -- string (default: ``None``). If ``None``, return the - name of this element; else return a new object identical to ``self`` + - ``new_name`` -- string (default: ``None``); if ``None``, return the + name of this element. Else return a new object identical to ``self`` whose name is ``new_name``. Note that this can overwrite existing variables in the system. @@ -1085,7 +1080,6 @@ def __setitem__(self, index, value): sage: l[0] = 4 # optional - macaulay2 sage: list(l) # optional - macaulay2 [4, 2, 3] - """ P = self.parent() index = P(index) @@ -1113,7 +1107,7 @@ def __call__(self, x): def __floordiv__(self, x): """ - Quotient of division of self by other. This is denoted //. + Quotient of division of ``self`` by ``other``. This is denoted ``//``. EXAMPLES:: @@ -1141,7 +1135,7 @@ def __floordiv__(self, x): def __mod__(self, x): """ - Remainder of division of self by other. This is denoted %. + Remainder of division of ``self`` by ``other``. This is denoted ``%``. EXAMPLES:: @@ -1256,7 +1250,6 @@ def subs(self, *args, **kwds): sage: a = a.substitute(P) sage: a.sage().parent() Univariate Polynomial Ring in x over Finite Field of size 7 - """ return self.__getattr__("substitute")(*args, **kwds) @@ -1363,8 +1356,8 @@ def dot(self, x): def _operator(self, opstr, x): """ - Returns the infix binary operation specified by opstr applied - to self and x. + Return the infix binary operation specified by opstr applied + to ``self`` and x. EXAMPLES:: @@ -1399,7 +1392,6 @@ def starstar(self, x): sage: a = macaulay2([1,2]).set() # optional - macaulay2 sage: a.starstar(a) # optional - macaulay2 set {(1, 1), (1, 2), (2, 1), (2, 2)} - """ return self._operator("**", x) @@ -1570,7 +1562,6 @@ def _sage_(self): 2*x*y^18 + y^14 sage: f.parent() # optional - macaulay2 Quotient of Multivariate Polynomial Ring in x, y over Finite Field of size 7 by the ideal (x^3 - y^2) - """ repr_str = str(self) cls_str = str(self.cls()) @@ -1871,7 +1862,7 @@ def _sage_src_(self): def is_Macaulay2Element(x): """ - Return True if ``x`` is a :class:`Macaulay2Element` + Return ``True`` if ``x`` is a :class:`Macaulay2Element`. This function is deprecated; use :func:`isinstance` (of :class:`sage.interfaces.abc.Macaulay2Element`) instead. diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index 4cf4a77f8bf..3ec584931cc 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -5,7 +5,7 @@ system. This system provides extensive functionality for number theory, group theory, combinatorics and algebra. -.. note:: +.. NOTE:: You must have Magma installed on your computer for this interface to work. Magma is not free, so it is @@ -14,15 +14,15 @@ The Magma interface offers three pieces of functionality: -#. ``magma_console()`` -- A function that dumps you into an interactive command-line Magma session. +#. ``magma_console()`` -- a function that dumps you into an interactive command-line Magma session. -#. ``magma.new(obj)`` and alternatively ``magma(obj)`` -- Creation of a Magma object from a Sage object ``obj``. +#. ``magma.new(obj)`` and alternatively ``magma(obj)`` -- creation of a Magma object from a Sage object ``obj``. This provides a Pythonic interface to Magma. For example, if ``f=magma.new(10)``, then ``f.Factors()`` returns the prime factorization of 10 computed using Magma. If obj is a string containing an arbitrary Magma expression, then the expression is evaluated in Magma to create a Magma object. An example is ``magma.new('10 div 3')``, which returns Magma integer 3. -#. ``magma.eval(expr)`` -- Evaluation of the Magma expression ``expr``, with the result returned as a string. +#. ``magma.eval(expr)`` -- evaluation of the Magma expression ``expr``, with the result returned as a string. Type ``magma.[tab]`` for a list of all functions available from your Magma. Type ``magma.Function?`` for Magma's help about the Magma ``Function``. @@ -281,7 +281,7 @@ class Magma(ExtraTabCompletion, Expect): object, and ``magma.eval(...)`` to run a string using Magma (and get the result back as a string). - .. note:: + .. NOTE:: If you do not own a local copy of Magma, try using the ``magma_free`` command instead, which uses the free demo web @@ -309,23 +309,23 @@ def __init__(self, script_subdirectory=None, """ INPUT: - - ``script_subdirectory`` -- directory where scripts - are read from + - ``script_subdirectory`` -- directory where scripts + are read from - - ``logfile`` -- output logged to this file + - ``logfile`` -- output logged to this file - - ``server`` -- address of remote server + - ``server`` -- address of remote server - ``server_tmpdir`` -- temporary directory to use in remote server - - ``user_config`` -- if True, then local user - configuration files will be read by Magma. If False (the default), - then Magma is started with the -n option which suppresses user - configuration files. + - ``user_config`` -- if ``True``, then local user + configuration files will be read by Magma. If ``False`` (the default), + then Magma is started with the -n option which suppresses user + configuration files. - - ``seed`` -- Seed to use in the random number generator. + - ``seed`` -- seed to use in the random number generator - - ``command`` -- (Default: 'magma') The command to execute to start Magma. + - ``command`` -- (default: ``'magma'``) the command to execute to start Magma EXAMPLES:: @@ -344,8 +344,8 @@ def __init__(self, script_subdirectory=None, seed = os.getenv('SAGE_MAGMA_SEED') Expect.__init__(self, - name="magma", - prompt=">>SAGE>>", + name='magma', + prompt='>>SAGE>>', command=command, server=server, server_tmpdir=server_tmpdir, @@ -420,15 +420,11 @@ def _read_in_file_command(self, filename): INPUT: - - - ``filename`` -- string - + - ``filename`` -- string OUTPUT: - - - ``string`` -- a magma command - + - ``string`` -- a magma command EXAMPLES:: @@ -446,11 +442,9 @@ def _post_process_from_file(self, s): INPUT: + - ``s`` -- string - - ``s`` -- a string - - - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -471,15 +465,13 @@ def _post_process_from_file(self, s): def __getattr__(self, attrname): """ Return a formal wrapper around a Magma function, or raise an - AttributeError if attrname starts with an underscore. + :exc:`AttributeError` if attrname starts with an underscore. INPUT: + - ``attrname`` -- string - - ``attrname`` -- a string - - - OUTPUT: MagmaFunction instance + OUTPUT: :class:`MagmaFunction` instance EXAMPLES:: @@ -509,10 +501,9 @@ def eval(self, x, strip=True, **kwds): INPUT: - - ``x`` -- string of code - - - ``strip`` -- ignored + - ``x`` -- string of code + - ``strip`` -- ignored OUTPUT: string @@ -552,7 +543,6 @@ def eval(self, x, strip=True, **kwds): True sage: magma.eval("[a,b];") # optional - magma '[ 3, 5 ]' - """ x = self._preparse(x) x = str(x).rstrip() @@ -615,11 +605,9 @@ def set(self, var, value): INPUT: + - ``var`` -- string; a variable name - - ``var`` -- string; a variable name - - - ``value`` -- string; what to set var equal to - + - ``value`` -- string; what to set var equal to EXAMPLES:: @@ -637,17 +625,10 @@ def get(self, var): INPUT: + - ``var`` -- string; name of a variable defined in the + Magma session - - ``var`` -- string; name of a variable defined in the - Magma session - - - OUTPUT: - - - - ``string`` -- string representation of the value of - the variable. - + OUTPUT: string representation of the value of the variable EXAMPLES:: @@ -663,13 +644,11 @@ def objgens(self, value, gens): INPUT: - - ``value`` -- something coercible to an element of this Magma - interface + interface - ``gens`` -- string; comma separated list of variable names - OUTPUT: new Magma element that is equal to value with given gens EXAMPLES:: @@ -706,14 +685,12 @@ def __call__(self, x, gens=None): INPUT: + - ``x`` -- object - - ``x`` -- object - - - ``gens`` -- string; names of generators of self, - separated by commas + - ``gens`` -- string; names of generators of self, + separated by commas - - OUTPUT: MagmaElement + OUTPUT: :class:`MagmaElement` EXAMPLES:: @@ -816,10 +793,10 @@ def __call__(self, x, gens=None): def _coerce_from_special_method(self, x): """ - Tries to coerce to self by calling a special underscore method. + Try to coerce to ``self`` by calling a special underscore method. - If no such method is defined, raises an AttributeError instead of a - TypeError. + If no such method is defined, raises an :exc:`AttributeError` instead + of a :exc:`TypeError`. EXAMPLES:: @@ -852,11 +829,9 @@ def _with_names(self, s, names): INPUT: + - ``s`` -- string - - ``s`` -- string - - - ``names`` -- list of strings - + - ``names`` -- list of strings OUTPUT: string @@ -875,9 +850,7 @@ def clear(self, var): INPUT: - - - ``var`` -- a string - + - ``var`` -- string EXAMPLES:: @@ -926,16 +899,12 @@ def cputime(self, t=None): INPUT: - - - ``t`` -- float (default: None); if not None, return - cputime since t - + - ``t`` -- float (default: ``None``); if not None, return + cputime since t OUTPUT: - - - ``float`` -- seconds - + - ``float`` -- seconds EXAMPLES:: @@ -959,7 +928,7 @@ def chdir(self, dir): INPUT: - - ``dir`` -- a string + - ``dir`` -- string EXAMPLES:: @@ -982,9 +951,7 @@ def attach(self, filename): INPUT: - - - ``filename`` -- a string - + - ``filename`` -- string EXAMPLES: Attaching a file that exists is fine:: @@ -1012,9 +979,7 @@ def attach_spec(self, filename): INPUT: - - - ``filename`` -- a string - + - ``filename`` -- string EXAMPLES:: @@ -1043,16 +1008,14 @@ def load(self, filename): INPUT: - - - ``filename`` -- string - + - ``filename`` -- string OUTPUT: output printed when loading the file EXAMPLES:: sage: from tempfile import NamedTemporaryFile as NTF - sage: with NTF(mode="w+t", suffix=".m") as f: # optional - magma + sage: with NTF(mode='w+t', suffix='.m') as f: # optional - magma ....: _ = f.write('function f(n) return n^2; end function;\nprint "hi";') ....: print(magma.load(f.name)) Loading ".../a.m" @@ -1120,20 +1083,19 @@ def function_call(self, function, args=[], params={}, nvals=1): INPUT: + - ``function`` -- string, a Magma function name - - ``function`` -- string, a Magma function name - - - ``args`` -- list of objects coercible into this magma - interface - - - ``params`` -- Magma parameters, passed in after a - colon + - ``args`` -- list of objects coercible into this magma + interface - - ``nvals`` -- number of return values from the - function to ask Magma for + - ``params`` -- Magma parameters, passed in after a + colon + - ``nvals`` -- number of return values from the + function to ask Magma for - OUTPUT: MagmaElement or tuple of nvals MagmaElement's + OUTPUT: instance of :class:`MagmaElement` or a tuple of ``nvals`` many + :class:`MagmaElement` instances EXAMPLES:: @@ -1178,11 +1140,9 @@ def _do_call(self, code, nvals): INPUT: + - ``code`` -- string; code to evaluate - - ``code`` -- a string; code to evaluate - - - ``nvals`` -- an integer; number of return values - + - ``nvals`` -- integer; number of return values OUTPUT: nvals distinct values @@ -1232,7 +1192,7 @@ def _do_call(self, code, nvals): def bar_call(self, left, name, gens, nvals=1): """ - This is a wrapper around the Magma constructor + This is a wrapper around the Magma constructor. nameleft gens @@ -1240,18 +1200,16 @@ def bar_call(self, left, name, gens, nvals=1): INPUT: + - ``left`` -- something coerceable to a magma object - - ``left`` -- something coerceable to a magma object - - - ``name`` -- name of the constructor, e.g., sub, quo, - ideal, etc. - - - ``gens`` -- if a list/tuple, each item is coerced to - magma; otherwise gens itself is converted to magma + - ``name`` -- name of the constructor, e.g., sub, quo, + ideal, etc. - - ``nvals`` -- positive integer; number of return - values + - ``gens`` -- if a list/tuple, each item is coerced to + magma; otherwise gens itself is converted to magma + - ``nvals`` -- positive integer; number of return + values OUTPUT: a single magma object if nvals == 1; otherwise a tuple of nvals magma objects. @@ -1420,11 +1378,9 @@ def version(self): OUTPUT: + - ``numbers`` -- 3-tuple: major, minor, etc. - - ``numbers`` -- 3-tuple: major, minor, etc. - - - ``string`` -- version as a string - + - ``string`` -- version as a string EXAMPLES:: @@ -1442,9 +1398,7 @@ def help(self, s): INPUT: - - - ``s`` -- string - + - ``s`` -- string OUTPUT: string @@ -1474,14 +1428,12 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): INPUT: + - ``verbose`` -- boolean (default: ``True``); whether to + verbosely output status info the first time the command list is + built - - ``verbose`` -- bool (default: ``True``); whether to - verbosely output status info the first time the command list is - built - - - ``use_disk_cache`` -- bool (default: ``True``); use - cached command list, which is saved to disk. - + - ``use_disk_cache`` -- boolean (default: ``True``); use + cached command list, which is saved to disk OUTPUT: list of strings @@ -1536,12 +1488,10 @@ def ideal(self, L): INPUT: + - ``L`` -- list of elements of a Sage multivariate + polynomial ring - - ``L`` -- a list of elements of a Sage multivariate - polynomial ring. - - - OUTPUT: The magma ideal generated by the elements of L. + OUTPUT: the magma ideal generated by the elements of L EXAMPLES:: @@ -1574,9 +1524,9 @@ def set_verbose(self, type, level): INPUT: - - ``type`` -- string (e.g. 'Groebner') + - ``type`` -- string (e.g. 'Groebner') - - ``level`` -- integer >= 0 + - ``level`` -- integer >= 0 EXAMPLES:: @@ -1596,10 +1546,8 @@ def get_verbose(self, type): INPUT: - - - ``type`` -- string (e.g. 'Groebner'), see Magma - documentation - + - ``type`` -- string (e.g. 'Groebner'), see Magma + documentation EXAMPLES:: @@ -1828,13 +1776,14 @@ def _instancedoc_(self): def is_MagmaElement(x): """ - Return True if ``x`` is of type :class:`MagmaElement`, and False otherwise. + Return ``True`` if ``x`` is of type :class:`MagmaElement`, and ``False`` + otherwise. INPUT: - - ``x`` -- any object + - ``x`` -- any object - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -1901,15 +1850,15 @@ def __getattr__(self, attrname): """ INPUT: - - ``attrname`` -- string + - ``attrname`` -- string - OUTPUT: a Magma function partially evaluated with self as the first - input. + OUTPUT: a Magma function partially evaluated with ``self`` as the first + input - .. note:: + .. NOTE:: If the input ``attrname`` starts with an underscore, an - :class:`AttributeError` is raised so that the actual + :exc:`AttributeError` is raised so that the actual Python _ method/value can be accessed. EXAMPLES:: @@ -2121,16 +2070,15 @@ def AssignNames(self, names): def gen(self, n): """ - Return the n-th generator of this Magma element. Note that - generators are 1-based in Magma rather than 0 based! + Return the `n`-th generator of this Magma element. Note that + generators are 1-based in Magma rather than 0-based! INPUT: - - - ``n`` -- a *positive* integer + - ``n`` -- *positive* integer - OUTPUT: MagmaElement + OUTPUT: :class:`MagmaElement` EXAMPLES:: @@ -2162,7 +2110,7 @@ def gens(self) -> tuple: """ Return generators for ``self``. - If self is named X in Magma, this function evaluates X.1, X.2, + If ``self`` is named X in Magma, this function evaluates X.1, X.2, etc., in Magma until an error occurs. It then returns a Sage tuple of the resulting X.i. Note - I don't think there is a Magma command that returns the list of valid X.i. There are numerous ad hoc @@ -2201,9 +2149,9 @@ def gens(self) -> tuple: def gen_names(self): """ - Return list of Magma variable names of the generators of self. + Return list of Magma variable names of the generators of ``self``. - .. note:: + .. NOTE:: As illustrated below, these are not the print names of the the generators of the Magma object, but special variable @@ -2226,11 +2174,11 @@ def gen_names(self): def evaluate(self, *args): r""" - Evaluate self at the inputs. + Evaluate ``self`` at the inputs. INPUT: - - ``*args`` -- import arguments + - ``*args`` -- import arguments OUTPUT: self(\*args) @@ -2292,7 +2240,7 @@ def __iter__(self): .. warning:: - Internally this constructs the list of elements in self in + Internally this constructs the list of elements in ``self`` in Magma, which is not a lazy operation. This is because Magma doesn't have a notion of lazy iterators, unfortunately. @@ -2338,8 +2286,8 @@ def __len__(self): def _polynomial_(self, R): """ - Try to convert self into a polynomial in the univariate polynomial - ring R. + Try to convert ``self`` into a polynomial in the univariate polynomial + ring `R`. EXAMPLES:: @@ -2356,32 +2304,30 @@ def _polynomial_(self, R): def _latex_(self): r""" - Return latex representation of self. + Return latex representation of ``self``. AUTHORS: - Jennifer Balakrishnan - Types that are nicely latex include: - - - - rationals + Types that are nicely latexed include: - - matrices + - rationals - - polynomials + - matrices - - binary quadratic forms + - polynomials - - elements of quadratic, cyclotomic number fields, and general - number fields + - binary quadratic forms - - points + - elements of quadratic, cyclotomic number fields, and general + number fields - - elliptic curves + - points - - power series + - elliptic curves + - power series IMPLEMENTATION: Calls latex.m, which is in SAGE_EXTCODE/magma/latex.m @@ -2465,7 +2411,7 @@ def _latex_(self): sage: latex(magma('(-1/(2+x + O(x^3)))')) \frac{-1}{2}+\frac{1}{4}x-\frac{1}{8}x^{2}+O(x^{3}) - p-adic Numbers:: + `p`-adic Numbers:: sage: latex(magma('pAdicField(7,4)!9333294394/49')) # optional - magma 4\cdot{}7^{-2} + 5\cdot{}7^{-1} + 5+ 6\cdot{}7^{1} + O(7^{2}) @@ -2479,8 +2425,10 @@ def _latex_(self): def set_magma_attribute(self, attrname, value): """ - INPUT: attrname - string value - something coercible to a - MagmaElement + INPUT: + + - ``attrname`` -- string + - ``value`` -- something coercible to a MagmaElement EXAMPLES:: @@ -2502,7 +2450,7 @@ def get_magma_attribute(self, attrname): Return value of a given Magma attribute. This is like selfattrname in Magma. - OUTPUT: MagmaElement + OUTPUT: :class:`MagmaElement` EXAMPLES:: @@ -2539,19 +2487,17 @@ def _tab_completion(self): Return all Magma functions that have this Magma element as first input. This is used for tab completion. - .. note:: + .. NOTE:: This function can unfortunately be slow if there are a very - large number of functions, e.g., when self is an + large number of functions, e.g., when ``self`` is an integer. (This could be fixed by the addition of an appropriate function to the Magma kernel, which is something that can only be done by the Magma developers.) OUTPUT: - - - ``list`` -- sorted list of distinct strings - + - ``list`` -- sorted list of distinct strings EXAMPLES:: @@ -2570,13 +2516,13 @@ def _tab_completion(self): def methods(self, any=False): """ - Return signatures of all Magma intrinsics that can take self as the + Return signatures of all Magma intrinsics that can take ``self`` as the first argument, as strings. INPUT: - - ``any`` -- (bool: default is False) if True, also - include signatures with Any as first argument. + - ``any`` -- boolean (default: ``False``); if ``True``, also + include signatures with Any as first argument OUTPUT: list of strings @@ -2602,8 +2548,8 @@ def methods(self, any=False): def __floordiv__(self, x): """ - Quotient of division of self by other. This is denoted // ("div" in - magma). + Quotient of division of ``self`` by ``other``. This is denoted ``//`` + (``div`` in magma). EXAMPLES:: @@ -2685,11 +2631,11 @@ def __bool__(self): def sub(self, gens): """ - Return the sub-object of self with given gens. + Return the sub-object of ``self`` with given gens. INPUT: - - ``gens`` -- object or list/tuple of generators + - ``gens`` -- object or list/tuple of generators EXAMPLES:: @@ -2707,24 +2653,20 @@ def sub(self, gens): def quo(self, gens, **args): """ - Return the quotient of self by the given object or list of + Return the quotient of ``self`` by the given object or list of generators. INPUT: - - - ``gens`` -- object or list/tuple of generators + - ``gens`` -- object or list/tuple of generators - further named arguments that are ignored - OUTPUT: + - ``magma element`` -- the quotient object - - ``magma element`` -- the quotient object - - - ``magma element`` -- mapping from self to the - quotient object - + - ``magma element`` -- mapping from ``self`` to the + quotient object EXAMPLES:: @@ -2756,19 +2698,15 @@ def quo(self, gens, **args): def ideal(self, gens): """ - Return the ideal of self with given list of generators. + Return the ideal of ``self`` with given list of generators. INPUT: - - - ``gens`` -- object or list/tuple of generators - + - ``gens`` -- object or list/tuple of generators OUTPUT: - - - ``magma element`` -- a Magma ideal - + - ``magma element`` -- a Magma ideal EXAMPLES:: @@ -2840,7 +2778,7 @@ def __init__(self, verbosity=1, style='magma'): - ``style`` -- if "magma" the full Magma log is printed; if 'sage' only the current degree and the number of pairs in - the queue is printed (default: "magma"). + the queue is printed (default: ``'magma'``). EXAMPLES:: @@ -2968,8 +2906,7 @@ def write(self, s): pol_curr, col_curr = map(int, match.groups()) if pol_curr != 0: - if self.max_deg < self.curr_deg: - self.max_deg = self.curr_deg + self.max_deg = max(self.max_deg, self.curr_deg) if style == "sage" and verbosity >= 1: print("Leading term degree: %2d. Critical pairs: %d." % diff --git a/src/sage/interfaces/magma_free.py b/src/sage/interfaces/magma_free.py index 34d5b70f29a..5938e9fa4af 100644 --- a/src/sage/interfaces/magma_free.py +++ b/src/sage/interfaces/magma_free.py @@ -26,8 +26,10 @@ def magma_free_eval(code, strip=True, columns=0): Use the free online MAGMA calculator to evaluate the given input code and return the answer as a string. - LIMITATIONS: The code must evaluate in at most 20 seconds - and there is a limitation on the amount of RAM. + .. WARNING:: + + The code must evaluate in at most 120 seconds + and there is a limitation on the amount of RAM. EXAMPLES:: diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index ce42a9b87db..5929582742e 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -37,7 +37,7 @@ (x-y)*(x^4+x^3*y+x^2*y^2+x*y^3+y^4) If the string "error" (case insensitive) occurs in the output of -anything from Maple, a :class:`RuntimeError` exception is raised. +anything from Maple, a :exc:`RuntimeError` exception is raised. Tutorial -------- @@ -750,10 +750,8 @@ def source(self, s): INPUT: - - - ``s`` -- a string representing the function whose - source code you want - + - ``s`` -- string representing the function whose + source code you want EXAMPLES:: @@ -785,8 +783,8 @@ def help(self, string): INPUT: - - ``string`` -- a string to search for in the maple help - system + - ``string`` -- string to search for in the maple help + system EXAMPLES:: @@ -802,7 +800,7 @@ def with_package(self, package): INPUT: - - ``package`` -- string + - ``package`` -- string EXAMPLES: Some functions are unknown to Maple until you use with to include the appropriate package. @@ -852,7 +850,7 @@ class MapleFunction(ExpectFunction): def _instancedoc_(self): """ Return the Maple help for this function. This gets called when - doing "?" on self. + doing ``?`` on ``self``. EXAMPLES:: @@ -923,7 +921,7 @@ class MapleElement(ExtraTabCompletion, ExpectElement): def __float__(self): """ - Return a floating point version of self. + Return a floating point version of ``self``. EXAMPLES:: @@ -936,7 +934,7 @@ def __float__(self): def __hash__(self): """ - Return a 64-bit integer representing the hash of self. Since + Return a 64-bit integer representing the hash of ``self``. Since Python uses 32-bit hashes, it will automatically convert the result of this to a 32-bit hash. @@ -961,7 +959,7 @@ def __hash__(self): def _richcmp_(self, other, op): """ - Compare equality between self and other, using maple. + Compare equality between ``self`` and ``other``, using maple. These examples are optional, and require Maple to be installed. You don't need to install any Sage packages for this. @@ -1093,7 +1091,7 @@ def _latex_(self): sage: print(maple(pi - e^3)._latex_()) # optional - maple \pi-{{\rm e}^{3}} - .. note:: + .. NOTE:: Some expressions might require the Maple style file ``maple2e.sty`` in order to latex correctly. @@ -1102,11 +1100,11 @@ def _latex_(self): def op(self, i=None): """ - Return the i-th operand of this expression. + Return the `i`-th operand of this expression. INPUT: - - i -- an integer or ``None`` + - ``i`` -- integer or ``None`` EXAMPLES:: diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 44b3176489e..71f233746e7 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -627,7 +627,7 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if def _function_call_string(self, function, args, kwds): """ - Returns the string used to make function calls. + Return the string used to make function calls. EXAMPLES:: @@ -649,7 +649,7 @@ def _right_func_delim(self): return "]" ########################################### - # System -- change directory, etc + # System -- change directory, etc. ########################################### def chdir(self, dir): """ @@ -677,7 +677,7 @@ def _assign_symbol(self): def _exponent_symbol(self): """ - Returns the symbol used to denote the exponent of a number in + Return the symbol used to denote the exponent of a number in Mathematica. EXAMPLES:: @@ -925,11 +925,9 @@ def __len__(self): @cached_method def _is_graphics(self): """ - Test whether the mathematica expression is graphics + Test whether the mathematica expression is graphics. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -942,14 +940,14 @@ def _is_graphics(self): def save_image(self, filename, ImageSize=600): r""" - Save a mathematica graphics + Save a mathematica graphics. INPUT: - - ``filename`` -- string. The filename to save as. The - extension determines the image file format. + - ``filename`` -- string; the filename to save as. The + extension determines the image file format - - ``ImageSize`` -- integer. The size of the resulting image. + - ``ImageSize`` -- integer; the size of the resulting image EXAMPLES:: @@ -967,7 +965,7 @@ def save_image(self, filename, ImageSize=600): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -1010,7 +1008,7 @@ def show(self, ImageSize=600): INPUT: - - ``ImageSize`` -- integer. The size of the resulting image. + - ``ImageSize`` -- integer; the size of the resulting image OUTPUT: @@ -1069,7 +1067,7 @@ def __bool__(self): def n(self, *args, **kwargs): r""" - Numerical approximation by converting to Sage object first + Numerical approximation by converting to Sage object first. Convert the object into a Sage object and return its numerical approximation. See documentation of the function @@ -1130,11 +1128,9 @@ def request_wolfram_alpha(input, verbose=False): INPUT: - ``input`` -- string - - ``verbose`` -- bool (default: ``False``) - - OUTPUT: + - ``verbose`` -- boolean (default: ``False``) - json + OUTPUT: json EXAMPLES:: @@ -1231,16 +1227,14 @@ def request_wolfram_alpha(input, verbose=False): def parse_moutput_from_json(page_data, verbose=False): r""" - Return the list of outputs found in the json (with key ``'moutput'``) + Return the list of outputs found in the json (with key ``'moutput'``). INPUT: - ``page_data`` -- json obtained from Wolfram Alpha - - ``verbose`` -- bool (default: ``False``) + - ``verbose`` -- boolean (default: ``False``) - OUTPUT: - - list of unicode strings + OUTPUT: list of unicode strings EXAMPLES:: @@ -1296,15 +1290,13 @@ def parse_moutput_from_json(page_data, verbose=False): def symbolic_expression_from_mathematica_string(mexpr): r""" - Translate a mathematica string into a symbolic expression + Translate a mathematica string into a symbolic expression. INPUT: - ``mexpr`` -- string - OUTPUT: - - symbolic expression + OUTPUT: symbolic expression EXAMPLES:: diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index b6ffbd3d4f2..3104fefe665 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -341,7 +341,7 @@ :: sage: mathics('10.^80') # optional - mathics - 1.*^80 + 1.×10^80 sage: mathics('10.^80').sage() # optional - mathics 1.00000000000000e80 @@ -483,6 +483,7 @@ def __init__(self, self._seed = seed self._initialized = False # done lazily self._session = None + os.environ['MATHICS_CHARACTER_ENCODING'] = 'ASCII' # see :issue:`37395` def _lazy_init(self): r""" @@ -512,6 +513,8 @@ def _start(self): """ if not self._session: from mathics.session import MathicsSession + from mathics.core.load_builtin import import_and_load_builtins + import_and_load_builtins() self._session = MathicsSession() from sage.interfaces.sympy import sympy_init sympy_init() @@ -601,13 +604,13 @@ def get(self, var): sage: mathics.set('u', '2*x +E') # optional - mathics sage: mathics.get('u') # optional - mathics - 'E + 2 x' + '2 x + E' """ return self.eval(var) def _function_call_string(self, function, args, kwds): """ - Returns the string used to make function calls. + Return the string used to make function calls. EXAMPLES:: @@ -653,7 +656,7 @@ def _right_func_delim(self): return "]" # ######################################### - # System -- change directory, etc + # System -- change directory, etc. # ######################################### def chdir(self, dir): """ @@ -705,7 +708,7 @@ def _assign_symbol(self): def _exponent_symbol(self): r""" - Returns the symbol used to denote the exponent of a number in + Return the symbol used to denote the exponent of a number in Mathics. EXAMPLES:: @@ -717,9 +720,9 @@ def _exponent_symbol(self): sage: bignum = mathics('10.^80') # optional - mathics sage: repr(bignum) # optional - mathics - '1.*^80' + '1.×10^80' sage: repr(bignum).replace(mathics._exponent_symbol(), 'e').strip() # optional - mathics - '1.e80' + '1.×10^80' """ return '*^' @@ -732,7 +735,6 @@ def _object_class(self): sage: mathics._object_class() - """ return MathicsElement @@ -772,34 +774,25 @@ def help(self, cmd, long=False): EXAMPLES:: sage: mathics.help('Sin') # optional - mathics - "\n 'Sin[z]'\n returns the sine of z.\n" + 'sine function\n' sage: print(_) # optional - mathics - - 'Sin[z]' - returns the sine of z. + sine function sage: print(mathics.help('Sin', long=True)) # optional - mathics - - 'Sin[z]' - returns the sine of z. + sine function Attributes[Sin] = {Listable, NumericFunction, Protected} sage: print(mathics.Factorial.__doc__) # optional - mathics - - 'Factorial[n]' - 'n!' - computes the factorial of n. + factorial sage: u = mathics('Pi') # optional - mathics sage: print(u.Cos.__doc__) # optional - mathics - - 'Cos[z]' - returns the cosine of z. + cosine function """ if long: @@ -852,7 +845,7 @@ class MathicsElement(ExtraTabCompletion, InterfaceElement): sage: expr = res.last_eval; expr sage: type(expr) - + Applying Mathics methods:: @@ -863,8 +856,6 @@ class MathicsElement(ExtraTabCompletion, InterfaceElement): 'System`E' sage: me.is_inexact() False - sage: me.is_symbol() - True Conversion to Sage:: @@ -876,7 +867,7 @@ def _tab_completion(self): r""" Return a list of all methods of this object. - .. note:: + .. NOTE:: Currently returns all methods of :class:`mathics.expression.Expression`. @@ -1056,7 +1047,6 @@ def _sage_(self, locals={}): bla sage: bla^2 - mb 0 - """ if locals: # if locals are given we use `_sage_repr` @@ -1107,9 +1097,7 @@ def _is_graphics(self): """ Test whether the mathics expression is graphics. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1121,14 +1109,14 @@ def _is_graphics(self): def save_image(self, filename, ImageSize=600): r""" - Save a mathics graphics + Save a mathics graphics. INPUT: - - ``filename`` -- string. The filename to save as. The - extension determines the image file format. + - ``filename`` -- string; the filename to save as. The + extension determines the image file format - - ``ImageSize`` -- integer. The size of the resulting image. + - ``ImageSize`` -- integer; the size of the resulting image EXAMPLES:: @@ -1145,7 +1133,7 @@ def save_image(self, filename, ImageSize=600): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -1188,7 +1176,7 @@ def show(self, ImageSize=600): INPUT: - - ``ImageSize`` -- integer. The size of the resulting image. + - ``ImageSize`` -- integer; the size of the resulting image OUTPUT: @@ -1255,7 +1243,7 @@ def __bool__(self): def n(self, *args, **kwargs): r""" - Numerical approximation by converting to Sage object first + Numerical approximation by converting to Sage object first. Convert the object into a Sage object and return its numerical approximation. See documentation of the function diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index 61f5563f4a6..7e701f515f3 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -192,7 +192,7 @@ def __reduce__(self): def _read_in_file_command(self, filename): """ - Returns the command used to read in and execute a file in Matlab. + Return the command used to read in and execute a file in Matlab. EXAMPLES:: @@ -268,7 +268,7 @@ def get(self, var): def strip_answer(self, s): r""" - Returns the string s with Matlab's answer prompt removed. + Return the string s with Matlab's answer prompt removed. EXAMPLES:: @@ -294,7 +294,6 @@ def chdir(self, directory): sage: matlab.chdir('/') # optional - matlab sage: matlab.pwd() # optional - matlab / - """ self.eval("cd('{0}')".format(directory)) @@ -302,9 +301,11 @@ def sage2matlab_matrix_string(self, A): """ Return a matlab matrix from a Sage matrix. - INPUT: A Sage matrix with entries in the rationals or reals. + INPUT: + + - ``A`` -- Sage matrix with entries in the rationals or reals - OUTPUT: A string that evaluates to a Matlab matrix. + OUTPUT: string that evaluates to a Matlab matrix EXAMPLES:: @@ -347,7 +348,6 @@ def _matrix_(self, R): sage: a = matlab('eye(50)') # optional - matlab sage: matrix(RR, a) # optional - matlab 50 x 50 dense matrix over Real Field with 53 bits of precision - """ from sage.matrix.constructor import matrix matlab = self.parent() diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index dd63daa08a8..96158d73039 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -35,7 +35,7 @@ If the string "error" (case insensitive) occurs in the output of -anything from Maxima, a :class:`RuntimeError` exception is raised. +anything from Maxima, a :exc:`RuntimeError` exception is raised. EXAMPLES: We evaluate a very simple expression in Maxima. @@ -410,7 +410,7 @@ The MAXIMA interface reads in even very long input (using files) in a robust manner, as long as you are creating a new object. -.. note:: +.. NOTE:: Using ``maxima.eval`` for long input is much less robust, and is not recommended. @@ -625,7 +625,6 @@ def _start(self): sage: m._start() sage: m.is_running() True - """ Expect._start(self) self._sendline(r":lisp (defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\\partial)) l r lop rop ))") @@ -777,8 +776,6 @@ def _eval_line(self, line, allow_use_file=False, Traceback (most recent call last): ... TypeError: Error executing code in Maxima... - - """ if len(line) == 0: return '' @@ -975,7 +972,7 @@ def lisp(self, cmd): """ Send a lisp command to Maxima. - .. note:: + .. NOTE:: The output of this command is very raw - not pretty. @@ -1120,7 +1117,7 @@ def _object_function_class(self): def is_MaximaElement(x): """ - Return True if ``x`` is of type :class:`MaximaElement`. + Return ``True`` if ``x`` is of type :class:`MaximaElement`. EXAMPLES:: diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 68c465d71c9..b8df280857c 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -114,7 +114,7 @@ def __init__(self, name='maxima_abstract'): Interface.__init__(self, name) ########################################### - # System -- change directory, etc + # System -- change directory, etc. ########################################### def chdir(self, dir): r""" @@ -189,9 +189,7 @@ def help(self, s): - ``s`` -- string - OUTPUT: - - Maxima's help for ``s`` + OUTPUT: Maxima's help for ``s`` EXAMPLES:: @@ -211,9 +209,7 @@ def example(self, s): - ``s`` -- string - OUTPUT: - - Maxima's examples for ``s`` + OUTPUT: Maxima's examples for ``s`` EXAMPLES:: @@ -374,8 +370,6 @@ def console(self): maxima session from this interface. To interact with this session, you should instead use ``maxima.interact()``. - INPUT: none - OUTPUT: none EXAMPLES:: @@ -402,12 +396,12 @@ def console(self): def cputime(self, t=None): r""" - Returns the amount of CPU time that this Maxima session has used. + Return the amount of CPU time that this Maxima session has used. INPUT: - - ``t`` -- float (default: None); If \var{t} is not None, then - it returns the difference between the current CPU time and \var{t}. + - ``t`` -- float (default: ``None``); if \var{t} is not None, then + it returns the difference between the current CPU time and \var{t} OUTPUT: float @@ -427,8 +421,6 @@ def version(self): r""" Return the version of Maxima that Sage includes. - INPUT: none - OUTPUT: none EXAMPLES:: @@ -446,8 +438,6 @@ def _assign_symbol(self): r""" Return the assign symbol in Maxima. - INPUT: none - OUTPUT: string EXAMPLES:: @@ -465,8 +455,6 @@ def _true_symbol(self): """ Return the true symbol in Maxima. - INPUT: none - OUTPUT: string EXAMPLES:: @@ -482,8 +470,6 @@ def _false_symbol(self): """ Return the false symbol in Maxima. - INPUT: none - OUTPUT: string EXAMPLES:: @@ -497,9 +483,7 @@ def _false_symbol(self): def _equality_symbol(self): """ - Returns the equality symbol in Maxima. - - INPUT: none + Return the equality symbol in Maxima. OUTPUT: string @@ -516,9 +500,7 @@ def _equality_symbol(self): def _inequality_symbol(self): """ - Returns the inequality symbol in Maxima. - - INPUT: none + Return the inequality symbol in Maxima. OUTPUT: string @@ -535,8 +517,6 @@ def _function_class(self): """ Return the Python class of Maxima functions. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -550,8 +530,6 @@ def _object_class(self): """ Return the Python class of Maxima elements. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -565,8 +543,6 @@ def _function_element_class(self): """ Return the Python class of Maxima functions of elements. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -580,8 +556,6 @@ def _object_function_class(self): """ Return the Python class of Maxima user-defined functions. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -601,14 +575,14 @@ def function(self, args, defn, rep=None, latex=None): INPUT: - - ``args`` -- a string with variable names separated by - commas + - ``args`` -- string with variable names separated by + commas - - ``defn`` -- a string (or Maxima expression) that - defines a function of the arguments in Maxima. + - ``defn`` -- string (or Maxima expression) that + defines a function of the arguments in Maxima - ``rep`` -- an optional string; if given, this is how - the function will print. + the function will print OUTPUT: Maxima function @@ -669,7 +643,7 @@ def function(self, args, defn, rep=None, latex=None): # INPUT: -# flag -- bool (default: ``True``) +# flag -- boolean (default: ``True``) # EXAMPLES:: @@ -692,11 +666,11 @@ def plot2d(self, *args): INPUT: - - ``f`` -- a string representing a function (such as - f="sin(x)") [var, xmin, xmax] + - ``f`` -- string representing a function (such as + f="sin(x)") [var, xmin, xmax] - ``options`` -- an optional string representing plot2d - options in gnuplot format + options in gnuplot format EXAMPLES:: @@ -715,18 +689,18 @@ def plot2d_parametric(self, r, var, trange, nticks=50, options=None): INPUT: - - ``r`` -- a string representing a function (such as - r="[x(t),y(t)]") + - ``r`` -- string representing a function (such as + r="[x(t),y(t)]") - - ``var`` -- a string representing the variable (such - as var = "t") + - ``var`` -- string representing the variable (such + as var = "t") - ``trange`` -- [tmin, tmax] are numbers with tmintmax - - ``nticks`` -- int (default: 50) + - ``nticks`` -- integer (default: 50) - ``options`` -- an optional string representing plot2d - options in gnuplot format + options in gnuplot format EXAMPLES:: @@ -762,8 +736,8 @@ def plot3d(self, *args): INPUT: - - ``f`` -- a string representing a function (such as - f="sin(x)") [var, min, max] + - ``f`` -- string representing a function (such as + f="sin(x)") [var, min, max] - ``args`` should be of the form '[x, xmin, xmax]', '[y, ymin, ymax]', '[grid, nx, ny]', options @@ -787,17 +761,17 @@ def plot3d_parametric(self, r, vars, urange, vrange, options=None): INPUT: - - ``x``, ``y``, ``z`` -- a string representing a function (such - as ``x="u2+v2"``, ...) vars is a list or two strings - representing variables (such as vars = ["u","v"]) + - ``x``, ``y``, ``z`` -- string representing a function (such + as ``x="u2+v2"``, ...) vars is a list or two strings + representing variables (such as vars = ["u","v"]) - ``urange`` -- [umin, umax] - ``vrange`` -- [vmin, vmax] are lists of numbers with - umin umax, vmin vmax + umin umax, vmin vmax - - ``options`` -- optional string representing plot2d - options in gnuplot format + - ``options`` -- (optional) string representing plot2d + options in gnuplot format OUTPUT: displays a plot on screen or saves to a file @@ -835,18 +809,18 @@ def plot3d_parametric(self, r, vars, urange, vrange, options=None): def de_solve(self, de, vars, ics=None): """ - Solves a 1st or 2nd order ordinary differential equation (ODE) in + Solve a 1st or 2nd order ordinary differential equation (ODE) in two variables, possibly with initial conditions. INPUT: - - ``de`` -- a string representing the ODE + - ``de`` -- string representing the ODE - - ``vars`` -- a list of strings representing the two - variables. + - ``vars`` -- list of strings representing the two + variables - ``ics`` -- a triple of numbers [a,b1,b2] representing - y(a)=b1, y'(a)=b2 + y(a)=b1, y'(a)=b2 EXAMPLES:: @@ -877,20 +851,20 @@ def de_solve(self, de, vars, ics=None): def de_solve_laplace(self, de, vars, ics=None): """ - Solves an ordinary differential equation (ODE) using Laplace + Solve an ordinary differential equation (ODE) using Laplace transforms. INPUT: - - ``de`` -- a string representing the ODE (e.g., de = - "diff(f(x),x,2)=diff(f(x),x)+sin(x)") + - ``de`` -- string representing the ODE (e.g., de = + "diff(f(x),x,2)=diff(f(x),x)+sin(x)") - - ``vars`` -- a list of strings representing the - variables (e.g., vars = ["x","f"]) + - ``vars`` -- list of strings representing the + variables (e.g., ``vars = ["x","f"]``) - - ``ics`` -- a list of numbers representing initial - conditions, with symbols allowed which are represented by strings - (eg, f(0)=1, f'(0)=2 is ics = [0,1,2]) + - ``ics`` -- list of numbers representing initial + conditions, with symbols allowed which are represented by strings + (eg, f(0)=1, f'(0)=2 is ics = [0,1,2]) EXAMPLES:: @@ -911,7 +885,7 @@ def de_solve_laplace(self, de, vars, ics=None): dx ! !x = 0 - .. note:: + .. NOTE:: The second equation sets the values of `f(0)` and `f'(0)` in Maxima, so subsequent ODEs involving these @@ -932,10 +906,10 @@ def solve_linear(self, eqns, vars): INPUT: - - ``eqns`` -- a list of m strings; each representing a linear + - ``eqns`` -- list of m strings; each representing a linear question in m = n variables - - ``vars`` -- a list of n strings; each + - ``vars`` -- list of n strings; each representing a variable EXAMPLES:: @@ -966,7 +940,7 @@ def unit_quadratic_integer(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -1002,18 +976,18 @@ def plot_list(self, ptsx, ptsy, options=None): INPUT: - ``ptsx`` -- [x1,...,xn], where the xi and yi are - real, + real, - ``ptsy`` -- [y1,...,yn] - - ``options`` -- a string representing maxima plot2d - options. + - ``options`` -- string representing maxima plot2d + options The points are (x1,y1), (x2,y2), etc. This function requires maxima 5.9.2 or newer. - .. note:: + .. NOTE:: More that 150 points can sometimes lead to the program hanging. Why? @@ -1051,7 +1025,7 @@ def plot_multilist(self, pts_list, options=None): Requires maxima 5.9.2 at least. - .. note:: + .. NOTE:: More that 150 points can sometimes lead to the program hanging. @@ -1113,8 +1087,6 @@ def __str__(self): """ Printing an object explicitly gives ASCII art. - INPUT: none - OUTPUT: string EXAMPLES:: @@ -1133,8 +1105,6 @@ def __bool__(self): """ Convert ``self`` into a boolean. - INPUT: none - OUTPUT: boolean EXAMPLES:: @@ -1208,8 +1178,6 @@ def _sage_(self): This is useful for automatic coercions in addition to other things. - INPUT: none - OUTPUT: Sage object EXAMPLES:: @@ -1290,8 +1258,6 @@ def __complex__(self): """ Return a complex number equivalent to this Maxima object. - INPUT: none - OUTPUT: complex EXAMPLES:: @@ -1383,8 +1349,6 @@ def real(self): """ Return the real part of this Maxima element. - INPUT: none - OUTPUT: Maxima real EXAMPLES:: @@ -1398,8 +1362,6 @@ def imag(self): """ Return the imaginary part of this Maxima element. - INPUT: none - OUTPUT: Maxima real EXAMPLES:: @@ -1411,9 +1373,7 @@ def imag(self): def numer(self): """ - Return numerical approximation to self as a Maxima object. - - INPUT: none + Return numerical approximation to ``self`` as a Maxima object. OUTPUT: Maxima object @@ -1430,8 +1390,6 @@ def str(self): """ Return string representation of this Maxima object. - INPUT: none - OUTPUT: string EXAMPLES:: @@ -1444,15 +1402,15 @@ def str(self): def diff(self, var='x', n=1): """ - Return the n-th derivative of self. + Return the `n`-th derivative of ``self``. INPUT: - - ``var`` -- variable (default: 'x') + - ``var`` -- variable (default: ``'x'``) - ``n`` -- integer (default: 1) - OUTPUT: n-th derivative of self with respect to the variable var + OUTPUT: `n`-th derivative of ``self`` with respect to the variable var EXAMPLES:: @@ -1482,8 +1440,8 @@ def nintegral(self, var='x', a=0, b=1, desired_relative_error='1e-8', maximum_num_subintervals=200): r""" - Return a numerical approximation to the integral of self from a to - b. + Return a numerical approximation to the integral of ``self`` from `a` + to `b`. INPUT: @@ -1493,18 +1451,16 @@ def nintegral(self, var='x', a=0, b=1, - ``b`` -- upper endpoint of integration - - ``desired_relative_error`` -- (default: '1e-8') the - desired relative error + - ``desired_relative_error`` -- (default: ``'1e-8'``) the + desired relative error - ``maximum_num_subintervals`` -- (default: 200) - maxima number of subintervals - - OUTPUT: + maxima number of subintervals - - approximation to the integral + OUTPUT: approximation to the integral - estimated absolute error of the - approximation + approximation - the number of integrand evaluations @@ -1546,19 +1502,17 @@ def nintegral(self, var='x', a=0, b=1, def integral(self, var='x', min=None, max=None): r""" - Return the integral of self with respect to the variable x. + Return the integral of ``self`` with respect to the variable `x`. INPUT: - ``var`` -- variable - - ``min`` -- default: None + - ``min`` -- (default: ``None``) - - ``max`` -- default: None + - ``max`` -- (default: ``None``) - OUTPUT: - - - the definite integral if xmin is not None + OUTPUT: the definite integral if xmin is not ``None`` - an indefinite integral otherwise @@ -1599,8 +1553,6 @@ def __float__(self): """ Return floating point version of this Maxima element. - INPUT: none - OUTPUT: real EXAMPLES:: @@ -1621,8 +1573,6 @@ def __len__(self): """ Return the length of a list. - INPUT: none - OUTPUT: integer EXAMPLES:: @@ -1636,11 +1586,11 @@ def __len__(self): def dot(self, other): """ - Implements the notation self . other. + Implement the notation ``self . other``. INPUT: - - ``other`` -- matrix; argument to dot. + - ``other`` -- matrix; argument to dot OUTPUT: Maxima matrix @@ -1657,7 +1607,7 @@ def dot(self, other): def __getitem__(self, n): r""" - Return the n-th element of this list. + Return the `n`-th element of this list. INPUT: @@ -1665,7 +1615,7 @@ def __getitem__(self, n): OUTPUT: Maxima object - .. note:: + .. NOTE:: Lists are 0-based when accessed via the Sage interface, not 1-based as they are in the Maxima interpreter. @@ -1691,9 +1641,7 @@ def __getitem__(self, n): def __iter__(self): """ - Return an iterator for self. - - INPUT: none + Return an iterator for ``self``. OUTPUT: iterator @@ -1753,8 +1701,6 @@ def _latex_(self): r""" Return Latex representation of this Maxima object. - INPUT: none - OUTPUT: string This calls the tex command in Maxima, then does a little @@ -1818,7 +1764,7 @@ def _tab_completion(self, verbose=False): def _matrix_(self, R): r""" - If self is a Maxima matrix, return the corresponding Sage matrix + If ``self`` is a Maxima matrix, return the corresponding Sage matrix over the Sage ring `R`. INPUT: @@ -1828,7 +1774,7 @@ def _matrix_(self, R): OUTPUT: matrix This may or may not work depending in how complicated the entries - of self are! It only works if the entries of self can be coerced as + of ``self`` are! It only works if the entries of ``self`` can be coerced as strings to produce meaningful elements of `R`. EXAMPLES:: @@ -1866,7 +1812,7 @@ def _matrix_(self, R): def partial_fraction_decomposition(self, var='x'): """ - Return the partial fraction decomposition of self with respect to + Return the partial fraction decomposition of ``self`` with respect to the variable var. INPUT: @@ -1899,11 +1845,11 @@ def _operation(self, operation, other=None): INPUT: - - ``operation`` -- a string representing the operation - being performed. For example, '*', or '1/'. + - ``operation`` -- string representing the operation + being performed. For example, '*', or '1/' - ``other`` -- the other operand. If ``other`` is ``None``, - then the operation is assumed to be unary rather than binary. + then the operation is assumed to be unary rather than binary OUTPUT: Maxima object @@ -1990,11 +1936,7 @@ def __reduce__(self): """ Implement __reduce__ for ``MaximaAbstractElementFunction``. - INPUT: none - - OUTPUT: - - A couple consisting of: + OUTPUT: a couple consisting of: - the function to call for unpickling @@ -2038,8 +1980,6 @@ def _repr_(self): """ Return print representation of this Maxima function. - INPUT: none - OUTPUT: string EXAMPLES:: @@ -2069,16 +2009,14 @@ def _latex_(self): def arguments(self, split=True): r""" - Returns the arguments of this Maxima function. + Return the arguments of this Maxima function. INPUT: - - ``split`` -- boolean; if True return a tuple of strings, + - ``split`` -- boolean; if ``True`` return a tuple of strings, otherwise return a string of comma-separated arguments - OUTPUT: - - - a string if ``split`` is False + OUTPUT: string if ``split`` is False - a list of strings if ``split`` is True @@ -2100,11 +2038,7 @@ def arguments(self, split=True): def definition(self): """ - Returns the definition of this Maxima function as a string. - - INPUT: none - - OUTPUT: string + Return the definition of this Maxima function as a string. EXAMPLES:: @@ -2116,7 +2050,7 @@ def definition(self): def integral(self, var): """ - Returns the integral of self with respect to the variable var. + Return the integral of ``self`` with respect to the variable var. INPUT: @@ -2155,12 +2089,12 @@ def _operation(self, operation, f=None): INPUT: - - ``operation`` -- A string representing the operation - being performed. For example, '\*', or '1/'. + - ``operation`` -- string representing the operation + being performed. For example, '\*', or '1/' - - ``f`` -- The other operand. If f is - ``None``, then the operation is assumed to be unary - rather than binary. + - ``f`` -- the other operand; if ``f`` is + ``None``, then the operation is assumed to be unary + rather than binary EXAMPLES:: diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index 7fadf1e27c1..1b1e97f3578 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -343,8 +343,6 @@ class MaximaLib(MaximaAbstract): """ Interface to Maxima as a Library. - INPUT: none - OUTPUT: Maxima interface as a Library EXAMPLES:: @@ -392,7 +390,7 @@ def __init__(self): def _coerce_from_special_method(self, x): r""" - Coerce ``x`` into self trying to call a special underscore method. + Coerce ``x`` into ``self`` trying to call a special underscore method. INPUT: @@ -415,11 +413,7 @@ def __reduce__(self): r""" Implement __reduce__ for ``MaximaLib``. - INPUT: none - - OUTPUT: - - A couple consisting of: + OUTPUT: a couple consisting of: - the function to call for unpickling @@ -442,12 +436,12 @@ def _eval_line(self, line, locals=None, reformat=True, **kwds): - ``line`` -- string; text to evaluate - - ``locals`` -- None (ignored); this is used for compatibility with the - Sage notebook's generic system interface. + - ``locals`` -- ``None`` (ignored); this is used for compatibility with the + Sage notebook's generic system interface - ``reformat`` -- boolean; whether to strip output or not - - ``**kwds`` -- All other arguments are currently ignored. + - ``**kwds`` -- all other arguments are currently ignored OUTPUT: string representing Maxima output @@ -502,7 +496,7 @@ def lisp(self, cmd): OUTPUT: ECL object - .. note:: + .. NOTE:: The output of this command is very raw - not pretty. @@ -520,9 +514,9 @@ def set(self, var, value): INPUT: - - ``var`` -- string + - ``var`` -- string - - ``value`` -- string + - ``value`` -- string OUTPUT: none @@ -592,12 +586,10 @@ def _create(self, value, name=None): - ``value`` -- string or ECL object - - ``name`` -- string (default: None); name to use for the variable, + - ``name`` -- string (default: ``None``); name to use for the variable, an automatically generated name is used if this is none - OUTPUT: - - - string; the name of the created variable + OUTPUT: string; the name of the created variable EXAMPLES: @@ -641,8 +633,6 @@ def _function_class(self): r""" Return the Python class of Maxima functions. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -657,8 +647,6 @@ def _object_class(self): r""" Return the Python class of Maxima elements. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -673,8 +661,6 @@ def _function_element_class(self): r""" Return the Python class of Maxima functions of elements. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -689,8 +675,6 @@ def _object_function_class(self): r""" Return the Python class of Maxima user-defined functions. - INPUT: none - OUTPUT: type EXAMPLES:: @@ -810,7 +794,6 @@ def sr_integral(self, *args): 0.124756040961038 sage: a.imag().abs() < 3e-17 True - """ try: return max_to_sr(maxima_eval(([max_integrate], @@ -928,7 +911,6 @@ def sr_prod(self, *args): factorial(n) sage: symbolic_product(2*x,x,1,n) 2^n*factorial(n) - """ try: return max_to_sr(maxima_eval([[max_ratsimp], @@ -1013,7 +995,6 @@ def sr_limit(self, expr, v, a, dir=None): sage: limit(gamma(x + 1/2)/(sqrt(x)*gamma(x)), x=infinity) 1 sage: _ = m.eval('domain: complex') - """ try: L = [sr_to_max(SR(aa)) for aa in [expr, v, a]] @@ -1075,7 +1056,7 @@ def _missing_assumption(self, errstr): def is_MaximaLibElement(x): r""" - Return True if ``x`` is of type :class:`MaximaLibElement`. + Return ``True`` if ``x`` is of type :class:`MaximaLibElement`. EXAMPLES:: @@ -1115,8 +1096,6 @@ def ecl(self): r""" Return the underlying ECL object of this MaximaLib object. - INPUT: none - OUTPUT: ECL object EXAMPLES:: @@ -1265,8 +1244,8 @@ def reduce_load_MaximaLib(): sage.functions.other.conjugate: "$CONJUGATE", } # we compile the dictionary -sage_op_dict = dict([(k, EclObject(sage_op_dict[k])) for k in sage_op_dict]) -max_op_dict = dict([(sage_op_dict[k], k) for k in sage_op_dict]) +sage_op_dict = {k: EclObject(sage_op_dict[k]) for k in sage_op_dict} +max_op_dict = {sage_op_dict[k]: k for k in sage_op_dict} # Here we correct the dictionaries for some simple operators @@ -1414,7 +1393,7 @@ def mlist_to_sage(expr): - ``expr`` -- ECL object; a Maxima MLIST expression (i.e., a list) - OUTPUT: a Python list of converted expressions. + OUTPUT: a Python list of converted expressions EXAMPLES:: @@ -1458,7 +1437,7 @@ def max_at_to_sage(expr): subsvalues = {v.lhs(): v.rhs() for v in max_to_sr(subsarg)} else: v = max_to_sr(subsarg) - subsvalues = dict([(v.lhs(), v.rhs())]) + subsvalues = {v.lhs(): v.rhs()} return SR(arg).subs(subsvalues) @@ -1573,7 +1552,7 @@ def pyobject_to_max(obj): OUTPUT: ECL object - .. note:: + .. NOTE:: This uses functions defined in sage.libs.ecl. @@ -1678,7 +1657,7 @@ def sr_to_max(expr): return EclObject(special_sage_to_max[op](*[sr_to_max(o) for o in expr.operands()])) elif op == tuple: return EclObject(([mlist], list(sr_to_max(op) for op in expr.operands()))) - elif not (op in sage_op_dict): + elif op not in sage_op_dict: # Maxima does some simplifications automatically by default # so calling maxima(expr) can change the structure of expr # op_max=caar(maxima(expr).ecl()) diff --git a/src/sage/interfaces/meson.build b/src/sage/interfaces/meson.build new file mode 100644 index 00000000000..4a12245d532 --- /dev/null +++ b/src/sage/interfaces/meson.build @@ -0,0 +1,79 @@ +py.install_sources( + 'abc.py', + 'all.py', + 'all__sagemath_polyhedra.py', + 'axiom.py', + 'cleaner.py', + 'ecm.py', + 'expect.py', + 'four_ti_2.py', + 'fricas.py', + 'frobby.py', + 'gap.py', + 'gap3.py', + 'gap_workspace.py', + 'genus2reduction.py', + 'gfan.py', + 'giac.py', + 'gnuplot.py', + 'gp.py', + 'interface.py', + 'jmoldata.py', + 'kash.py', + 'kenzo.py', + 'latte.py', + 'lie.py', + 'lisp.py', + 'macaulay2.py', + 'magma.py', + 'magma_free.py', + 'maple.py', + 'mathematica.py', + 'mathics.py', + 'matlab.py', + 'maxima.py', + 'maxima_abstract.py', + 'maxima_lib.py', + 'mupad.py', + 'mwrank.py', + 'octave.py', + 'phc.py', + 'polymake.py', + 'povray.py', + 'process.pxd', + 'psage.py', + 'qepcad.py', + 'qsieve.py', + 'quit.py', + 'r.py', + 'read_data.py', + 'rubik.py', + 'sage-maxima.lisp', + 'sage0.py', + 'scilab.py', + 'singular.py', + 'sympy.py', + 'sympy_wrapper.py', + 'tab_completion.py', + 'tachyon.py', + 'tests.py', + 'tides.py', + subdir: 'sage/interfaces', +) + +extension_data = { + 'process' : files('process.pyx'), + 'sagespawn' : files('sagespawn.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/interfaces', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/interfaces/mupad.py b/src/sage/interfaces/mupad.py index cd36a6356cc..074350d9230 100644 --- a/src/sage/interfaces/mupad.py +++ b/src/sage/interfaces/mupad.py @@ -151,7 +151,6 @@ def __reduce__(self): sage: Mupad().__reduce__() (, ()) - """ return reduce_load_mupad, tuple([]) @@ -190,7 +189,6 @@ def _install_hints(self): In order to use the MuPAD interface you need to have MuPAD installed ... - """ return """ In order to use the MuPAD interface you need to have MuPAD installed @@ -229,7 +227,6 @@ def console(self): | *--|-* All rights reserved. |/ |/ *----* Licensed to: ... - """ mupad_console() @@ -239,7 +236,6 @@ def eval(self, code, strip=True, **kwds): sage: mupad.eval('2+2') # optional - mupad 4 - """ s = Expect.eval(self, code, **kwds) return AsciiArtString(s) @@ -255,7 +251,6 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, Traceback (most recent call last): ... RuntimeError: Unknown slot "x::asdf" [slot] - """ if self._expect is None: self._start() @@ -323,7 +318,6 @@ def get(self, var): sage: mupad.set('a', 4) # optional - mupad sage: mupad.get('a').strip() # optional - mupad '4' - """ s = self.eval('%s' % var) i = s.find('=') @@ -470,7 +464,6 @@ def _tab_completion(self): 'addRow', ... 'wiedemann'] - """ res = self._parent.completions(self._name+"::", strip=True) return res if res != [] else self._parent._tab_completion() @@ -485,7 +478,6 @@ def _instancedoc_(self): sage: x = mupad('x') # optional - mupad sage: x.diff.__doc__ # optional - mupad No help on diff available - """ return self._obj.parent().help(self._name) @@ -566,7 +558,6 @@ def __getattr__(self, attrname): sage: x = mupad('x') # optional - mupad-Combinat sage: x.diff(x) # optional - mupad-Combinat 1 - """ if attrname[:1] == "_": if attrname not in self.__dict__: @@ -615,7 +606,7 @@ def _latex_(self): def __len__(self): r""" - The analogue in MuPAD of Python's len is the method nops + The analogue in MuPAD of Python's len is the method nops. EXAMPLES:: @@ -638,7 +629,6 @@ def __len__(self): sage: [int(x) for x in mupad("{1,2,3,5}") ] # optional - mupad [1, 2, 3, 5] - """ return mupad.nops(self) @@ -673,7 +663,6 @@ def mupad_console(): | *--|-* All rights reserved. |/ |/ *----* Licensed to: ... - """ from sage.repl.rich_output.display_manager import get_display_manager if not get_display_manager().is_in_terminal(): diff --git a/src/sage/interfaces/mwrank.py b/src/sage/interfaces/mwrank.py index 63dcb214bdf..8d6af9b81d6 100644 --- a/src/sage/interfaces/mwrank.py +++ b/src/sage/interfaces/mwrank.py @@ -24,23 +24,23 @@ instances = {} -def Mwrank(options="", server=None, server_tmpdir=None): +def Mwrank(options='', server=None, server_tmpdir=None): """ Create and return an mwrank interpreter, with given options. INPUT: - - ``options`` -- string; passed when starting mwrank. - The format is:: + - ``options`` -- string; passed when starting mwrank. + The format is:: -h help prints this info and quits -q quiet turns OFF banner display and prompt -v n verbosity sets verbosity to n (default=1) - -o PARI/GP output turns ON extra PARI/GP short output (default is OFF) + -o PARI/GP output turns ON extra PARI/GP short output (default: OFF) -p n precision sets precision to n decimals (default=15) -b n quartic bound bound on quartic point search (default=10) -x n n aux number of aux primes used for sieving (default=6) - -l list turns ON listing of points (default ON unless v=0) + -l list turns ON listing of points (default: ON, unless v=0) -s selmer_only if set, computes Selmer rank only (default: not set) -d skip_2nd_descent if set, skips the second descent for curves with 2-torsion (default: not set) -S n sat_bd upper bound on saturation primes (default=100, -1 for automatic) @@ -56,7 +56,6 @@ def Mwrank(options="", server=None, server_tmpdir=None): Curve [0,0,1,-1,0] : Rank = 1 Generator 1 is [0:-1:1]; height 0.051... Regulator = 0.051... - """ global instances try: @@ -79,11 +78,11 @@ def Mwrank(options="", server=None, server_tmpdir=None): def validate_mwrank_input(s): r""" - Returns a string suitable for mwrank input, or raises an error. + Return a string suitable for mwrank input, or raises an error. INPUT: - - `s` -- one of the following: + - ``s`` -- one of the following: - a list or tuple of 5 integers [a1,a2,a3,a4,a6] or (a1,a2,a3,a4,a6) - a string of the form '[a1,a2,a3,a4,a6]' or 'a1 a2 a3 a4 a6' where a1, a2, a3, a4, a6 are integers @@ -91,7 +90,7 @@ def validate_mwrank_input(s): OUTPUT: For valid input, a string of the form '[a1,a2,a3,a4,a6]'. - For invalid input a :class:`ValueError` is raised. + For invalid input a :exc:`ValueError` is raised. EXAMPLES: @@ -124,7 +123,6 @@ def validate_mwrank_input(s): Traceback (most recent call last): ... ValueError: 0 -1 1 -7 is not valid input to mwrank - """ if isinstance(s, (list, tuple)): from sage.rings.integer_ring import ZZ @@ -150,21 +148,21 @@ class Mwrank_class(Expect): """ Interface to the Mwrank interpreter. """ - def __init__(self, options="", server=None, server_tmpdir=None): + def __init__(self, options='', server=None, server_tmpdir=None): """ INPUT: - - ``options`` -- string; passed when starting mwrank. - The format is:: + - ``options`` -- string; passed when starting mwrank. + The format is:: -h help prints this info and quits -q quiet turns OFF banner display and prompt -v n verbosity sets verbosity to n (default=1) - -o PARI/GP output turns ON extra PARI/GP short output (default is OFF) + -o PARI/GP output turns ON extra PARI/GP short output (default: OFF) -p n precision sets precision to n decimals (default=15) -b n quartic bound bound on quartic point search (default=10) -x n n aux number of aux primes used for sieving (default=6) - -l list turns ON listing of points (default ON unless v=0) + -l list turns ON listing of points (default: ON, unless v=0) -s selmer_only if set, computes Selmer rank only (default: not set) -d skip_2nd_descent if set, skips the second descent for curves with 2-torsion (default: not set) -S n sat_bd upper bound on saturation primes (default=100, -1 for automatic) @@ -245,8 +243,8 @@ def __call__(self, cmd): TESTS: - Invalid input raises an ValueError (see :issue:`10108`); this includes - syntactically valid input which defines a singular curve:: + Invalid input raises an :exc:`ValueError` (see :issue:`10108`); this + includes syntactically valid input which defines a singular curve:: sage: mwrank(10) Traceback (most recent call last): @@ -262,7 +260,6 @@ def __call__(self, cmd): Traceback (most recent call last): ... ValueError: Invalid input ([0,0,0,-3,2]) to mwrank (singular curve) - """ try: s = validate_mwrank_input(cmd) @@ -281,7 +278,7 @@ def eval(self, s, **kwds): INPUT: - - ``s`` (str) -- a Sage object which when converted to a string + - ``s`` -- string; a Sage object which when converted to a string gives valid input to ``mwrank``. The conversion is done by :meth:`validate_mwrank_input`. Possible formats are: @@ -296,7 +293,7 @@ def eval(self, s, **kwds): .. NOTE:: - If a :class:`RuntimeError` exception is raised, then the mwrank + If a :exc:`RuntimeError` exception is raised, then the mwrank interface is restarted and the command is retried once. EXAMPLES:: @@ -332,7 +329,6 @@ def console(self): sage: mwrank.console() # not tested: expects console input Program mwrank: ... - """ mwrank_console() @@ -343,7 +339,7 @@ def console(self): def _reduce_load_mwrank(): """ - Return the standard mwrank instance + Return the standard mwrank instance. EXAMPLES:: diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index 93bd12ade5a..5241989836b 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -486,7 +486,7 @@ def version(self): def solve_linear_system(self, A, b): r""" - Use octave to compute a solution x to A\*x = b, as a list. + Use Octave to compute a solution x to ``A*x = b``, as a list. INPUT: @@ -494,7 +494,7 @@ def solve_linear_system(self, A, b): - ``b`` -- m-vector b entries in `\QQ` or `\RR` (resp) - OUTPUT: A list x (if it exists) which solves M\*x = b + OUTPUT: list x (if it exists) which solves ``M*x = b`` EXAMPLES:: @@ -531,9 +531,11 @@ def sage2octave_matrix_string(self, A): """ Return an octave matrix from a Sage matrix. - INPUT: A Sage matrix with entries in the rationals or reals. + INPUT: + + - ``A`` - Sage matrix with entries in the rationals or reals - OUTPUT: A string that evaluates to an Octave matrix. + OUTPUT: string that evaluates to an Octave matrix EXAMPLES:: @@ -555,16 +557,13 @@ def de_system_plot(self, f, ics, trange): INPUT: + - ``f`` -- a pair of strings representing the + differential equations; the independent variable must be called x + and the dependent variable must be called y - - ``f`` -- a pair of strings representing the - differential equations; The independent variable must be called x - and the dependent variable must be called y. - - - ``ics`` -- a pair [x0,y0] such that x(t0) = x0, y(t0) - = y0 - - - ``trange`` -- a pair [t0,t1] + - ``ics`` -- a pair [x0,y0] such that x(t0) = x0, y(t0) = y0 + - ``trange`` -- a pair [t0,t1] OUTPUT: a gnuplot window appears @@ -607,7 +606,7 @@ def _object_class(self): def to_complex(octave_string, R): r""" - Helper function to convert octave complex number + Helper function to convert octave complex number. TESTS:: diff --git a/src/sage/interfaces/phc.py b/src/sage/interfaces/phc.py index 23dd8f3546e..3aa5964352b 100644 --- a/src/sage/interfaces/phc.py +++ b/src/sage/interfaces/phc.py @@ -52,12 +52,10 @@ def get_solution_dicts(output_file_contents, input_ring, get_failures=True): INPUT: - - output_file_contents -- phc solution output as a string - - input_ring -- a PolynomialRing that variable names can be coerced into + - ``output_file_contents`` -- phc solution output as a string + - ``input_ring`` -- a PolynomialRing that variable names can be coerced into - OUTPUT: - - a list of dictionaries of solutions + OUTPUT: list of dictionaries of solutions EXAMPLES:: @@ -103,12 +101,10 @@ def get_classified_solution_dicts(output_file_contents, input_ring, get_failures INPUT: - - output_file_contents -- phc solution output as a string - - input_ring -- a PolynomialRing that variable names can be coerced into - - OUTPUT: + - ``output_file_contents`` -- phc solution output as a string + - ``input_ring`` -- a PolynomialRing that variable names can be coerced into - - a dictionary of lists if dictionaries of solutions, classifies by type + OUTPUT: a dictionary of lists if dictionaries of solutions, classifies by type EXAMPLES:: @@ -189,8 +185,8 @@ def __init__(self, output_file_contents, input_ring): INPUT: - - output_file_contents: the string output of PHCpack - - input_ring: for coercion of the variables into the desired ring. + - ``output_file_contents`` -- the string output of PHCpack + - ``input_ring`` -- for coercion of the variables into the desired ring EXAMPLES:: @@ -269,9 +265,7 @@ def classified_solution_dicts(self): - None - OUTPUT: - - - A dictionary of lists of dictionaries of solutions + OUTPUT: a dictionary of lists of dictionaries of solutions EXAMPLES:: @@ -297,10 +291,9 @@ def solution_dicts(self, get_failures=False): INPUT: - - self -- for access to self_out_file_contents, the string - of raw PHCpack output. - - - get_failures (optional) -- a boolean. The default (False) + - ``self`` -- for access to self_out_file_contents, the string + of raw PHCpack output + - ``get_failures`` -- boolean (default: ``False``); the default is to not process failed homotopies. These either lie on positive-dimensional components or at infinity. @@ -340,15 +333,13 @@ def solutions(self, get_failures=False): INPUT: - - self -- for access to self_out_file_contents, the string - of raw PHCpack output. - - get_failures (optional) -- a boolean. The default (False) + - ``self`` -- for access to self_out_file_contents, the string + of raw PHCpack output + - ``get_failures`` -- boolean (default: ``False``); the default is to not process failed homotopies. These either lie on positive-dimensional components or at infinity. - OUTPUT: - - - solutions: a list of lists of ComplexField-valued solutions. + OUTPUT: solutions: a list of lists of ComplexField-valued solutions EXAMPLES:: @@ -427,12 +418,10 @@ def _output_from_command_list(self, command_list, polys, verbose=False): INPUT: - - command_list -- a list of commands to phc - - polys -- a polynomial system as a list of polynomials - - OUTPUT: + - ``command_list`` -- list of commands to phc + - ``polys`` -- a polynomial system as a list of polynomials - - an output string from phc + OUTPUT: an output string from phc EXAMPLES:: @@ -486,12 +475,11 @@ def _input_file(self, polys): INPUT: - - polys -- a list of polynomials in a Sage polynomial ring + - ``polys`` -- list of polynomials in a Sage polynomial ring over a field that embeds into the complex numbers - OUTPUT: - - a PHC input file (as a text string) that describes these polynomials + OUTPUT: a PHC input file (as a text string) that describes these + polynomials EXAMPLES:: @@ -510,18 +498,16 @@ def _input_file(self, polys): def _parse_path_file(self, input_filename, verbose=False): """ - Takes a phpack output file containing path tracking information + Take a phpack output file containing path tracking information and parses it into a list of lists of dictionaries - i.e. a list of solutions paths, where each solution path is a list of dictionaries of variable and homotopy parameter values. INPUT: - - input_filename -- file must have path-tracking information + - ``input_filename`` -- file must have path-tracking information - OUTPUT: - - - a list of lists of dictionaries, described above + OUTPUT: list of lists of dictionaries, described above EXAMPLES:: @@ -639,21 +625,23 @@ def _path_track_file(self, start_filename_or_string, polys, input_ring, c_skew=0 def path_track(self, start_sys, end_sys, input_ring, c_skew=.001, saved_start=None): """ - This function computes homotopy paths between the solutions of start_sys and end_sys. + This function computes homotopy paths between the solutions of + ``start_sys`` and ``end_sys``. INPUT: - - start_sys -- a square polynomial system, given as a list of polynomials - - end_sys -- same type as start_sys - - input_ring -- for coercion of the variables into the desired ring. - - c_skew -- optional. the imaginary part of homotopy multiplier; nonzero values - are often necessary to avoid intermediate path collisions - - saved_start -- optional. A phc output file. If not given, start system solutions - are computed via the phc.blackbox function. - - OUTPUT: + - ``start_sys`` -- a square polynomial system, given as a list of + polynomials + - ``end_sys`` -- same type as ``start_sys`` + - ``input_ring`` -- for coercion of the variables into the desired ring + - ``c_skew`` -- (optional) the imaginary part of homotopy multiplier; + nonzero values are often necessary to avoid intermediate path + collisions + - ``saved_start`` -- (optional) a phc output file; if not given, start + system solutions are computed via the ``phc.blackbox`` function - - a list of paths as dictionaries, with the keys variables and t-values on the path. + OUTPUT: list of paths as dictionaries, with the keys variables and + t-values on the path EXAMPLES:: @@ -681,18 +669,19 @@ def plot_paths_2d(self, start_sys, end_sys, input_ring, c_skew=.001, endpoints=T INPUT: - - start_sys -- a square polynomial system, given as a list of polynomials - - end_sys -- same type as start_sys - - input_ring -- for coercion of the variables into the desired ring. - - c_skew -- optional. the imaginary part of homotopy multiplier; nonzero values - are often necessary to avoid intermediate path collisions - - endpoints -- optional. Whether to draw in the ends of paths as points. - - saved_start -- optional. A phc output file. If not given, start system solutions - are computed via the phc.blackbox function. - - OUTPUT: + - ``start_sys`` -- a square polynomial system, given as a list of + polynomials + - ``end_sys`` -- same type as start_sys + - ``input_ring`` -- for coercion of the variables into the desired ring + - ``c_skew`` -- (optional) the imaginary part of homotopy multiplier; + nonzero values are often necessary to avoid intermediate path + collisions + - ``endpoints`` -- (optional) whether to draw in the ends of paths as + points + - ``saved_start`` -- (optional) a phc output file; if not given, start + system solutions are computed via the ``phc.blackbox`` function - - lines and points of solution paths + OUTPUT: lines and points of solution paths EXAMPLES:: @@ -742,13 +731,11 @@ def mixed_volume(self, polys, verbose=False): INPUT: - - polys -- a list of multivariate polynomials (elements of a multivariate + - ``polys`` -- list of multivariate polynomials (elements of a multivariate polynomial ring). - - verbose -- print lots of verbose information about what this function does. + - ``verbose`` -- print lots of verbose information about what this function does - OUTPUT: - - - The mixed volume. + OUTPUT: the mixed volume EXAMPLES:: @@ -783,19 +770,17 @@ def start_from(self, start_filename_or_string, polys, input_ring, path_track_fil INPUT: - - start_filename_or_string -- the filename for a phcpack start system, + - ``start_filename_or_string`` -- the filename for a phcpack start system, or the contents of such a file as a string. Variable names must match the inputring variables. The value of the homotopy variable t should be 1, not 0. - - polys -- a list of multivariate polynomials (elements of a multivariate + - ``polys`` -- list of multivariate polynomials (elements of a multivariate polynomial ring). - input_ring: for coercion of the variables into the desired ring. - path_track_file: whether to save path-tracking information - - verbose -- print lots of verbose information about what this function does. - - OUTPUT: + - ``verbose`` -- print lots of verbose information about what this function does - - A solution in the form of a PHCObject. + OUTPUT: a solution in the form of a PHCObject EXAMPLES:: @@ -887,14 +872,12 @@ def blackbox(self, polys, input_ring, verbose=False): INPUT: - - polys -- a list of multivariate polynomials (elements of a multivariate + - ``polys`` -- list of multivariate polynomials (elements of a multivariate polynomial ring). - - input_ring -- for coercion of the variables into the desired ring. - - verbose -- print lots of verbose information about what this function does. - - OUTPUT: + - ``input_ring`` -- for coercion of the variables into the desired ring + - ``verbose`` -- print lots of verbose information about what this function does - - a PHC_Object object containing the phcpack output string. + OUTPUT: a PHC_Object object containing the phcpack output string EXAMPLES:: diff --git a/src/sage/interfaces/polymake.py b/src/sage/interfaces/polymake.py index a3418e1a773..94ad62153a9 100644 --- a/src/sage/interfaces/polymake.py +++ b/src/sage/interfaces/polymake.py @@ -59,7 +59,6 @@ class PolymakeError(RuntimeError): Traceback (most recent call last): ... PolymakeError: Unquoted string "foo" may clash with future reserved word... - """ pass @@ -86,7 +85,6 @@ def polymake_console(command=''): 4ti2, bliss, cdd, latte, libnormaliz, lrs, permlib, ppl, sketch, sympol, threejs, tikz, topcom, tosimplex For more details: show_credits; polytope > - """ from sage.repl.rich_output.display_manager import get_display_manager if not get_display_manager().is_in_terminal(): @@ -149,7 +147,7 @@ def version(self): """ return self.get('$Polymake::Version') - # Pickling etc + # Pickling, etc. def __reduce__(self): """ @@ -158,7 +156,6 @@ def __reduce__(self): sage: from sage.interfaces.polymake import polymake sage: loads(dumps(polymake)) is polymake True - """ return reduce_load_Polymake, () @@ -173,7 +170,6 @@ def _object_class(self): cube of dimension 3 sage: type(C) # optional - jupymake - """ return PolymakeElement @@ -211,7 +207,6 @@ def _function_element_class(self): N_FACETS : FACETS precondition : COMBINATORIAL_DIM ( F_VECTOR : N_FACETS, N_RAYS, GRAPH.N_EDGES, DUAL_GRAPH.N_EDGES, COMBINATORIAL_DIM ) F_VECTOR : N_FACETS, N_RAYS, GRAPH.N_EDGES, DUAL_GRAPH.N_EDGES, COMBINATORIAL_DIM - """ return PolymakeFunctionElement @@ -221,7 +216,6 @@ def function_call(self, function, args=None, kwds=None): sage: polymake.rand_sphere(4, 30, seed=15) # optional - jupymake # indirect doctest Random spherical polytope of dimension 4; seed=15... - """ args, kwds = self._convert_args_kwds(args, kwds) self._check_valid_function_name(function) @@ -232,7 +226,7 @@ def function_call(self, function, args=None, kwds=None): def _function_call_string(self, function, args, kwds): """ - Returns the string used to make function calls. + Return the string used to make function calls. EXAMPLES:: @@ -247,7 +241,6 @@ def _function_call_string(self, function, args, kwds): 1 7 7 sage: c.GROUP full combinatorial group - """ if kwds: if args: @@ -347,7 +340,6 @@ def console(self): Traceback (most recent call last): ... NotImplementedError: Please use polymake_console() function or the .interact() method - """ raise NotImplementedError("Please use polymake_console() function or the .interact() method") @@ -361,7 +353,6 @@ def _install_hints(self): Please install the optional polymake package for sage or install polymake system-wide (use the shell command 'sage --info polymake' for more information) - """ return "Please install the optional polymake package for sage" + os.linesep + "or install polymake system-wide" + os.linesep + "(use the shell command 'sage --info polymake' for more information)" @@ -383,7 +374,6 @@ def _start(self): sage: 'normal_fan' in dir(polymake) # optional - jupymake False - """ self.application("polytope") self.eval('use Scalar::Util qw(reftype);') @@ -430,7 +420,7 @@ def _read_in_file_command(self, filename): def _next_var_name(self): r""" - Returns the next unused variable name. + Return the next unused variable name. TESTS:: @@ -464,7 +454,6 @@ def clear(self, var): 1 sage: polymake._next_var_name() in old True - """ self._available_vars.append(_name_pattern.search(var).group()) @@ -496,15 +485,14 @@ def _create(self, value, name=None): EXAMPLES:: sage: # optional - jupymake - sage: polymake._create("('foo', 'bar')", name="my_array") + sage: polymake._create("('foo', 'bar')", name='my_array') '@my_array' sage: print(polymake.eval('print join(", ", @my_array);')) foo, bar - sage: polymake._create('"foobar"', name="my_string") + sage: polymake._create('"foobar"', name='my_string') '$my_string[0]' sage: print(polymake.eval('print $my_string[0];')) foobar - """ name = self._next_var_name() if name is None else name self.set(name, value) @@ -591,7 +579,6 @@ def set(self, var, value): 1 0 0 0 3/2 0 0 0 0 sage: P.F_VECTOR # optional - jupymake 9 36 84 126 126 84 36 9 - """ if isinstance(value, str): value = value.strip().rstrip(';').strip() @@ -612,8 +599,6 @@ def get(self, cmd): sage: polymake('cube(3)') # optional - jupymake cube of dimension 3 - - """ return self.eval("print {};".format(cmd)).strip() @@ -623,8 +608,9 @@ def help(self, topic, pager=True): INPUT: - - ``topic``, a string - - ``pager``, optional bool, default ``True``: When True, display help, otherwise return as a string. + - ``topic`` -- string + - ``pager`` -- boolean (default: ``True``); when ``True``, display + help, otherwise return as a string EXAMPLES:: @@ -654,7 +640,7 @@ def help(self, topic, pager=True): 4: objects/PointConfiguration/properties/Triangulation and volume/TRIANGULATION 5: objects/Polytope/properties/Triangulation and volume/TRIANGULATION - If an unknown help topic is requested, a :class:`PolymakeError` + If an unknown help topic is requested, a :exc:`PolymakeError` results:: sage: polymake.help('Triangulation') # optional - jupymake @@ -729,8 +715,9 @@ def application(self, app): INPUT: - - ``app``, a string, one of "common", "fulton", "group", "matroid", "topaz", - "fan", "graph", "ideal", "polytope", "tropical" + - ``app`` -- string; one of ``'common'``, ``'fulton'``, ``'group'``, + ``'matroid'``, ``'topaz'``, ``'fan'``, ``'graph'``, ``'ideal'``, + ``'polytope'``, ``'tropical'`` EXAMPLES: @@ -808,7 +795,6 @@ def application(self, app): Traceback (most recent call last): ... PolymakeError: Unknown application killerapp - """ if app not in ["common", "fulton", "group", "matroid", "topaz", "fan", "graph", "ideal", "polytope", "tropical"]: raise ValueError("Unknown polymake application '{}'".format(app)) @@ -839,7 +825,6 @@ def new_object(self, name, *args, **kwds): 1 3 1 8 sage: q.full_typename() 'Polytope' - """ try: f = self.__new[name] @@ -874,7 +859,6 @@ class PolymakeElement(ExtraTabCompletion, InterfaceElement): sage: p.VERTICES[2][2] # optional - jupymake 1450479926727001/2251799813685248 - """ def _repr_(self): """ @@ -958,7 +942,6 @@ def _repr_(self): 'Map' sage: p.TWO_FACE_SIZES # optional - jupymake {(3 20)} - """ T1, T2 = self.typeof() P = self._check_valid() @@ -1019,7 +1002,6 @@ def _richcmp_(self, other, op): 12 30 20 sage: p1.get_member('list_properties') == p2.get_member('list_properties') # optional - jupymake False - """ P = self._check_valid() if P.eval("print {} {} {};".format(self.name(), P._equality_symbol(), other.name())).strip() == P._true_symbol(): @@ -1041,7 +1023,6 @@ def __bool__(self): False sage: bool(polymake(1)) # optional - jupymake True - """ P = self._check_valid() t = P._true_symbol() @@ -1085,7 +1066,6 @@ def known_properties(self): 'CONE_DIM', ... 'VERTICES_IN_FACETS'] - """ P = self._check_valid() try: @@ -1108,7 +1088,6 @@ def _member_list(self): ... 'WEAKLY_CENTERED', ...] - """ # return the members of a "big" object. P = self._check_valid() @@ -1135,7 +1114,6 @@ def typename(self): 'Polytope' sage: c.VERTICES.typename() # optional - jupymake 'Matrix' - """ P = self._check_valid() try: @@ -1154,7 +1132,6 @@ def full_typename(self): 'Polytope' sage: c.VERTICES.full_typename() # optional - jupymake 'Matrix' - """ P = self._check_valid() try: @@ -1173,7 +1150,6 @@ def qualified_typename(self): 'polytope::Polytope' sage: c.VERTICES.qualified_typename() # optional - jupymake 'common::Matrix' - """ P = self._check_valid() try: @@ -1204,7 +1180,6 @@ def _tab_completion(self): 'zonotope', 'zonotope_tiling_lattice', 'zonotope_vertices_fukuda'] - """ return sorted(self._member_list()+self.parent()._tab_completion()) @@ -1260,7 +1235,6 @@ def __getattr__(self, attrname): Member function 'contains' of Polymake::polytope::Polytope__Rational object sage: c.contains(V) true - """ P = self._check_valid() if attrname[:1] == "_": @@ -1348,7 +1322,6 @@ def get_member(self, attrname): sage: p.type() # optional - jupymake Polytope[SAGE...] - """ P = self._check_valid() return P('{}->{}'.format(self.name(), attrname)) @@ -1420,7 +1393,6 @@ def __len__(self): 20 sage: len(p.list_properties()) >= 12 # optional - jupymake True - """ P = self._check_valid() T1, T2 = self.typeof() @@ -1470,7 +1442,7 @@ def typeof(self): def _sage_(self): """ - Convert self to a Sage object. + Convert ``self`` to a Sage object. EXAMPLES:: @@ -1521,7 +1493,6 @@ def _sage_(self): A 3-dimensional polyhedron in (Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?)^3 defined as the convex hull of 12 vertices - """ T1, T2 = self.typeof() self._check_valid() @@ -1627,7 +1598,6 @@ def _sage_doc_(self): (5) (5) (0 3) (1 -1) . - """ P = self._check_valid() # according to Julian Pfeifle, the only case in which the fully qualified @@ -1683,17 +1653,18 @@ class PolymakeFunctionElement(InterfaceFunctionElement): Member function 'contains' of Polymake::polytope::Polytope__Rational object sage: c.contains(V) true - """ def __init__(self, obj, name, memberfunction=False): """ INPUT: - - Polymake object that this function is bound to - - name (string): It actually says how to call this function in polymake. - So, if it is a member function, it will look like `"$SAGE123[0]->func_name"`. - - ``memberfunction`` (bool, default: ``False``): Whether this is a member function - or a plain function applied with this element as first argument. + - ``obj`` -- Polymake object that this function is bound to + - ``name`` -- string; it actually says how to call this function in + polymake. So, if it is a member function, it will look like + `"$SAGE123[0]->func_name"`. + - ``memberfunction`` -- boolean (default: ``False``); whether this is a + member function or a plain function applied with this element as + first argument EXAMPLES:: @@ -1702,7 +1673,6 @@ def __init__(self, obj, name, memberfunction=False): minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object) sage: p.get_schedule # optional - jupymake Member function 'get_schedule' of Polymake::polytope::Polytope__Rational object - """ self._obj = obj self._name = name @@ -1717,7 +1687,6 @@ def _repr_(self): minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object) sage: p.contains # optional - jupymake Member function 'contains' of Polymake::polytope::Polytope__Rational object - """ if self._is_memberfunc: return "Member function '{}' of {} object".format(self._name.split("->")[-1], self._obj.typeof()[0]) @@ -1736,7 +1705,6 @@ def __call__(self, *args, **kwds): cdd.convex_hull.canon: POINTED, RAYS, LINEALITY_SPACE : INPUT_RAYS sage: p.minkowski_sum_fukuda(p).F_VECTOR # optional - jupymake # not tested 13 33 22 - """ if self._is_memberfunc: return self._obj._check_valid().function_call(self._name, list(args), kwds) @@ -1793,7 +1761,6 @@ def _sage_doc_(self): 1 -2 2 1 -1 3 1 1 3 - """ P = self._obj._check_valid() return P.help(self._name.split("->")[-1], pager=False) @@ -1956,7 +1923,7 @@ def eval(self, code, **kwds): sage: set_verbose(0) If polymake raises an error, the polymake *interface* raises - a :class:`PolymakeError`:: + a :exc:`PolymakeError`:: sage: polymake.eval('FOOBAR(3);') # optional - jupymake Traceback (most recent call last): diff --git a/src/sage/interfaces/povray.py b/src/sage/interfaces/povray.py index b892cb112cd..6e7a6c8ef94 100644 --- a/src/sage/interfaces/povray.py +++ b/src/sage/interfaces/povray.py @@ -16,9 +16,7 @@ class POVRay: - ``outfile`` -- the filename you want to save your result to - ``**kwargs`` -- additionally keyword arguments you want to pass to POVRay - OUTPUT: - - Image is written to the file you specified in outfile + OUTPUT: image is written to the file you specified in outfile EXAMPLES: diff --git a/src/sage/interfaces/process.pyx b/src/sage/interfaces/process.pyx index 016de82a30f..4003324f7aa 100644 --- a/src/sage/interfaces/process.pyx +++ b/src/sage/interfaces/process.pyx @@ -37,15 +37,15 @@ cdef class ContainChildren(): INPUT: - - ``exitcode`` -- (integer, default 0) exit code to use when a + - ``exitcode`` -- integer (default: 0); exit code to use when a child process tries to exit the with block normally (not due to an exception) - - ``exceptcode`` -- (integer, default 1) exit code to use when a + - ``exceptcode`` -- integer (default: 1); exit code to use when a child process tries to exit the with block due to an exception - - ``silent`` -- (boolean, default ``False``) if ``False``, print - exceptions raised by the child process. + - ``silent`` -- boolean (default: ``False``); if ``False``, print + exceptions raised by the child process EXAMPLES:: @@ -186,7 +186,7 @@ def terminate(sp, interval=1, signals=[signal.SIGTERM, signal.SIGKILL]): INPUT: - ``sp`` -- a `subprocess.Popen` instance - - ``interval`` -- (float, default 1) interval in seconds between + - ``interval`` -- float (default: 1); interval in seconds between termination attempts - ``signals`` -- (list, default [signal.SIGTERM, signal.SIGKILL]) the signals to send the process in order to terminate it diff --git a/src/sage/interfaces/psage.py b/src/sage/interfaces/psage.py index ec583218c1e..96d4233bbeb 100644 --- a/src/sage/interfaces/psage.py +++ b/src/sage/interfaces/psage.py @@ -72,7 +72,6 @@ def _repr_(self): sage: from sage.interfaces.psage import PSage sage: PSage() # indirect doctest A running non-blocking (parallel) instance of Sage (number ...) - """ return 'A running non-blocking (parallel) instance of Sage (number %s)' % (self._number) diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index 1d1c81dac68..df9f1583c86 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -627,7 +627,7 @@ def _qepcad_atoms(formula): INPUT: - - `formula` (string) -- a quantifier-free formula. + - ``formula`` -- string; a quantifier-free formula .. NOTE:: @@ -773,7 +773,7 @@ def __init__(self, memcells=None, Qepcad """ Expect.__init__(self, - name="QEPCAD", + name='QEPCAD', # yuck: when QEPCAD first starts, # it doesn't give prompts prompt="\nEnter an .*:\r", @@ -809,7 +809,7 @@ def __init__(self, formula, A logfile can be specified with ``logfile``. If ``verbose=True`` is given, then the logfile is automatically - set to ``sys.stdout``, so all QEPCAD interaction is echoed to + set to ``sys.stdout.buffer``, so all QEPCAD interaction is echoed to the terminal. You can set the amount of memory that QEPCAD allocates with @@ -839,7 +839,7 @@ def __init__(self, formula, self._cell_cache = {} if verbose: - logfile = sys.stdout + logfile = sys.stdout.buffer varlist = None if vars is not None: @@ -1528,7 +1528,7 @@ def qepcad(formula, assume=None, interact=False, solution=None, sage: qepcad(qf.all_but_finitely_many(x, a*x^2 + b*x + c != 0)) # not tested (random order) b /= 0 \/ a /= 0 \/ c /= 0 - The non-zeroes are continuous iff there are no zeroes or if + The nonzeroes are continuous iff there are no zeroes or if the polynomial is zero. :: sage: qepcad(qf.connected_subset(x, a*x^2 + b*x + c != 0)) # not tested (random order) @@ -1871,12 +1871,12 @@ def _combine_formulas(self, formulas): INPUT: - - ``formulas`` -- a list of unquantified formulas + - ``formulas`` -- list of unquantified formulas OUTPUT: - - form_strs -- a list of formulas as strings - - vars -- a frozenset of all variables in the formulas + - ``form_strs`` -- list of formulas as strings + - ``vars`` -- frozenset of all variables in the formulas EXAMPLES:: @@ -1947,7 +1947,7 @@ def atomic(self, lhs, op='=', rhs=0): def formula(self, formula): r""" - Constructs a QEPCAD formula from the given input. + Construct a QEPCAD formula from the given input. INPUT: diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index d93cdf2730a..c7c1643be83 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -1,3 +1,4 @@ +# sage_setup: distribution = sagemath-repl """ Quitting interfaces """ @@ -24,7 +25,6 @@ def sage_spawned_process_file(): sage: from sage.interfaces.quit import sage_spawned_process_file sage: len(sage_spawned_process_file()) > 1 True - """ # This is the old value of SAGE_TMP. Until sage-cleaner is # completely removed, we need to leave these spawned_processes @@ -88,7 +88,7 @@ def kill_spawned_jobs(verbose=False): """ INPUT: - - ``verbose`` -- bool (default: ``False``); if ``True``, display a + - ``verbose`` -- boolean (default: ``False``); if ``True``, display a message each time a process is sent a kill signal EXAMPLES:: @@ -124,7 +124,7 @@ def kill_spawned_jobs(verbose=False): def is_running(pid): """ - Return True if and only if there is a process with id pid running. + Return ``True`` if and only if there is a process with id pid running. """ try: os.kill(int(pid), 0) diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py index 33addb28afa..b44fe1381ff 100644 --- a/src/sage/interfaces/r.py +++ b/src/sage/interfaces/r.py @@ -156,7 +156,7 @@ Distributions:: - sage: r.options(width="60") + sage: r.options(width='60') $width [1] 80 @@ -347,7 +347,7 @@ def _setup_r_to_sage_converter(): '_Names': ['Min.', '1st Qu.', 'Median', 'Mean', '3rd Qu.', 'Max.'], '_r_class': ['summaryDefault', 'table']} - sage: r.options(width="60").sage() + sage: r.options(width='60').sage() {'DATA': {'width': 60}, '_Names': 'width'} The conversion can handle "not a number", infinity, imaginary values and @@ -606,7 +606,7 @@ def _start(self): def png(self, *args, **kwds): """ - Creates an R PNG device. + Create an R PNG device. This should primarily be used to save an R graphic to a custom file. Note that when using this in the notebook, one must plot in the same cell that @@ -645,7 +645,7 @@ def png(self, *args, **kwds): def convert_r_list(self, l): r""" - Converts an R list to a Python list. + Convert an R list to a Python list. EXAMPLES:: @@ -772,11 +772,11 @@ def _install_hints(self): def _source(self, s): """ - Returns the source code of an R function as a string. + Return the source code of an R function as a string. INPUT: - - s -- the name of the function as a string + - ``s`` -- the name of the function as a string EXAMPLES:: @@ -793,9 +793,9 @@ def source(self, s): INPUT: - - s -- a string representing the function whose source code you want to see + - ``s`` -- string representing the function whose source code you want to see - OUTPUT: string -- source code + OUTPUT: string; source code EXAMPLES:: @@ -836,12 +836,12 @@ def library(self, library_name): """ Load the library library_name into the R interpreter. - This function raises an ImportError if the given library + This function raises an :exc:`ImportError` if the given library is not known. INPUT: - - library_name -- string + - ``library_name`` -- string EXAMPLES:: @@ -870,13 +870,13 @@ def library(self, library_name): def available_packages(self): """ - Returns a list of all available R package names. + Return a list of all available R package names. This list is not necessarily sorted. OUTPUT: list of strings - .. note:: + .. NOTE:: This requires an internet connection. The CRAN server is that is checked is defined at the top of sage/interfaces/r.py. @@ -912,7 +912,7 @@ def _object_class(self): def _true_symbol(self): """ - Return the symbol that represents True in R. + Return the symbol that represents ``True`` in R. OUTPUT: string @@ -927,7 +927,7 @@ def _true_symbol(self): def _false_symbol(self): """ - Return the symbol that represents True in R. + Return the symbol that represents ``True`` in R. OUTPUT: string @@ -971,12 +971,14 @@ def _loaded_package_pages(self, topic): def help(self, command): """ - Returns help string for a given command. + Return help string for a given command. INPUT: - - command -- a string - OUTPUT: HelpExpression -- a subclass of string whose __repr__ method is __str__, so it prints nicely + - ``command`` -- string + + OUTPUT: HelpExpression; a subclass of string whose ``__repr__`` + method is ``__str__``, so it prints nicely EXAMPLES:: @@ -1016,7 +1018,7 @@ def _assign_symbol(self): def _left_list_delim(self): """ - Return the left delimiter for lists in R, which is 'c(' + Return the left delimiter for lists in R, which is 'c('. OUTPUT: string @@ -1029,7 +1031,7 @@ def _left_list_delim(self): def _right_list_delim(self): """ - Return the right delimiter for lists in R, which is 'c(' + Return the right delimiter for lists in R, which is 'c('. OUTPUT: string @@ -1042,7 +1044,7 @@ def _right_list_delim(self): def console(self): """ - Runs the R console as a separate new R process. + Run the R console as a separate new R process. EXAMPLES:: @@ -1058,7 +1060,7 @@ def function_call(self, function, args=None, kwds=None): """ Return the result of calling an R function, with given args and keyword args. - OUTPUT: RElement -- an object in R + OUTPUT: RElement; an object in R EXAMPLES:: @@ -1083,10 +1085,10 @@ def call(self, function_name, *args, **kwds): def _an_element_(self): """ - Returns an element belonging to the R interpreter. This is used + Return an element belonging to the R interpreter. This is used behind the scenes when doing things like comparisons, etc. - OUTPUT: RElement -- an R element. + OUTPUT: RElement; an R element EXAMPLES:: @@ -1103,8 +1105,8 @@ def set(self, var, value): INPUT: - - var -- a string - - value -- a string + - ``var`` -- string + - ``value`` -- string EXAMPLES:: @@ -1116,11 +1118,11 @@ def set(self, var, value): def get(self, var): """ - Returns the string representation of the variable var. + Return the string representation of the variable var. INPUT: - - var -- a string + - ``var`` -- string OUTPUT: string @@ -1134,9 +1136,9 @@ def get(self, var): def na(self): """ - Returns the NA in R. + Return the NA in R. - OUTPUT: RElement -- an element of R + OUTPUT: RElement; an element of R EXAMPLES:: @@ -1152,9 +1154,9 @@ def completions(self, s): INPUT: - - s -- string + - ``s`` -- string - OUTPUT: list -- a list of strings + OUTPUT: list of strings EXAMPLES:: @@ -1168,7 +1170,7 @@ def _commands(self): """ Return list of all commands defined in R. - OUTPUT: list -- a sorted list of strings + OUTPUT: list; a sorted list of strings EXAMPLES:: @@ -1214,11 +1216,12 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): INPUT: - - verbose -- bool (default: ``True``); if True, display debugging information - - use_disk_cache -- bool (default: ``True``); if True, use the disk cache of - tab completions to save time. + - ``verbose`` -- boolean (default: ``True``); if ``True``, display + debugging information + - ``use_disk_cache`` -- boolean (default: ``True``); if ``True``, use + the disk cache of tab completions to save time - OUTPUT: list -- list of string + OUTPUT: list of string EXAMPLES:: @@ -1299,7 +1302,7 @@ def plot(self, *args, **kwds): sage: r.quartz() sage: r.hist("rnorm(100)") sage: r.library("lattice") - sage: r.histogram(x = "~ wt | cyl", data="mtcars") + sage: r.histogram(x = '~ wt | cyl', data='mtcars') sage: r.dev_off() In the notebook, one can use r.png() to open the device, but @@ -1333,15 +1336,15 @@ def eval(self, code, *args, **kwds): def _r_to_sage_name(self, s): """ - Returns a Sage/Python identifier from an R one. This involves + Return a Sage/Python identifier from an R one. This involves replacing periods with underscores, <- with __, and prepending _ in front of Python keywords. INPUT: - - s -- a string + - ``s`` -- string - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -1389,13 +1392,13 @@ def _sage_to_r_name(self, s): def __getitem__(self, s): """ - Returns the RFunction with name s. + Return the RFunction with name s. INPUT: - - s -- a string + - ``s`` -- string - OUTPUT: RFunction -- the R function that in R has name s + OUTPUT: RFunction; the R function that in R has name s EXAMPLES:: @@ -1408,11 +1411,11 @@ def __getitem__(self, s): def chdir(self, dir): """ - Changes the working directory to ``dir`` + Changes the working directory to ``dir``. INPUT: - - ``dir`` -- the directory to change to. + - ``dir`` -- the directory to change to EXAMPLES:: @@ -1439,7 +1442,7 @@ def _tab_completion(self): """ Return a list of all methods of this object. - .. note:: + .. NOTE:: Currently returns all R commands. @@ -1482,7 +1485,6 @@ def is_string(self): True sage: r([1,2,3]).is_string() False - """ return isinstance(self.sage(), str) @@ -1507,7 +1509,7 @@ def __getattr__(self, attrname): INPUT: - - attrname -- string + - ``attrname`` -- string OUTPUT: RFunctionElement @@ -1533,11 +1535,12 @@ def __getattr__(self, attrname): def __getitem__(self, n): """ - Return element(s) of self. + Return element(s) of ``self``. INPUT: - - n -- an integer, a tuple, a string that makes sense to R, or an RElement + - ``n`` -- integer, a tuple, a string that makes sense to R, or an + RElement OUTPUT: RElement @@ -1593,11 +1596,12 @@ def __getitem__(self, n): def __bool__(self): """ - Implements bool(self). + Implement ``bool(self)``. - .. note:: + .. NOTE:: - bool(self) will only return True if self == 0 contains a FALSE in its representation. + bool(self) will only return ``True`` if ``self == 0`` contains a + FALSE in its representation. EXAMPLES:: @@ -1620,10 +1624,10 @@ def _comparison(self, other, symbol): INPUT: - - other -- RElement - - symbol -- string + - ``other`` -- RElement + - ``symbol`` -- string - OUTPUT: RElement -- output is an R element; not a bool! + OUTPUT: RElement; output is an R element (not a bool!) TESTS:: @@ -1641,9 +1645,9 @@ def __eq__(self, other): INPUT: - - other -- RElement + - ``other`` -- RElement - OUTPUT: RElement -- an R element; not a bool! + OUTPUT: RElement; an R element (not a bool!) EXAMPLES: @@ -1661,9 +1665,9 @@ def __lt__(self, other): INPUT: - - other -- RElement + - ``other`` -- RElement - OUTPUT: RElement -- an R element; not a bool! + OUTPUT: RElement; an R element (not a bool!) EXAMPLES: @@ -1681,9 +1685,9 @@ def __gt__(self, other): INPUT: - - other -- RElement + - ``other`` -- RElement - OUTPUT: RElement -- an R element; not a bool! + OUTPUT: RElement; an R element (not a bool!) EXAMPLES: @@ -1701,9 +1705,9 @@ def __le__(self, other): INPUT: - - other -- RElement + - ``other`` -- RElement - OUTPUT: RElement -- an R element; not a bool! + OUTPUT: RElement; an R element (not a bool!) EXAMPLES:: @@ -1719,9 +1723,9 @@ def __ge__(self, other): INPUT: - - other -- RElement + - ``other`` -- RElement - OUTPUT: RElement -- an R element; not a bool! + OUTPUT: RElement; an R element (not a bool!) EXAMPLES:: @@ -1737,26 +1741,25 @@ def __ne__(self, other): INPUT: - - other -- RElement + - ``other`` -- RElement - OUTPUT: RElement -- an R element; not a bool! + OUTPUT: RElement; an R element (not a bool!) EXAMPLES:: sage: x = r([10.4,5.6,3.1,6.4,21.7]) sage: x != 10.4 [1] FALSE TRUE TRUE TRUE TRUE - """ return self._comparison(other, "!=") def dot_product(self, other): """ - Implements the notation self . other. + Implement the notation ``self . other``. INPUT: - - self, other -- R elements + - ``self``, ``other`` -- R elements OUTPUT: R element @@ -1782,7 +1785,7 @@ def dot_product(self, other): def _sage_(self): r""" - Returns Sage representation of the R object. + Return Sage representation of the R object. R objects are basic C structures, of different kind, that can be stacked together. This is similar to Python lists with @@ -1790,7 +1793,7 @@ def _sage_(self): names, they are translated to a Python dictionary, with anonymous list entries called ``#{number}``. - OUTPUT: object -- Python object + OUTPUT: object; Python object EXAMPLES:: @@ -1849,7 +1852,7 @@ def __reduce__(self): def _instancedoc_(self): """ - Returns the help for self as a string. + Return the help for ``self`` as a string. EXAMPLES:: @@ -1872,7 +1875,7 @@ def _instancedoc_(self): def _sage_src_(self): """ - Returns the source code of self. + Return the source code of ``self``. EXAMPLES:: @@ -1904,9 +1907,9 @@ def __init__(self, parent, name, r_name=None): INPUT: - - parent -- the R interface - - name -- the name of the function for Python - - r_name -- the name of the function in R itself (which can have dots in it) + - ``parent`` -- the R interface + - ``name`` -- the name of the function for Python + - ``r_name`` -- the name of the function in R itself (which can have dots in it) EXAMPLES:: @@ -1947,7 +1950,7 @@ def __ne__(self, other): def _instancedoc_(self): """ - Returns the help for self. + Return the help for ``self``. EXAMPLES:: @@ -1969,14 +1972,13 @@ def _instancedoc_(self): def _sage_src_(self): """ - Returns the source of self. + Return the source of ``self``. EXAMPLES:: sage: length = r.length sage: print(length._sage_src_()) function (x) .Primitive("length") - """ M = self._parent return M.source(self._name) @@ -1994,13 +1996,13 @@ def __call__(self, *args, **kwds): def is_RElement(x): """ - Return True if x is an element in an R interface. + Return ``True`` if x is an element in an R interface. INPUT: - - x -- object + - ``x`` -- object - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/interfaces/read_data.py b/src/sage/interfaces/read_data.py index 15d71a06b12..325c8ce5cb1 100644 --- a/src/sage/interfaces/read_data.py +++ b/src/sage/interfaces/read_data.py @@ -12,17 +12,15 @@ def read_data(f, t): r""" - Read data from file 'f' and class 't' (one element per line), + Read data from file ``f`` and class ``t`` (one element per line), and returns a list of elements. INPUT: - - 'f' -- a file name - - 't' -- a class (objects will be coerced to that class) + - ``f`` -- a file name + - ``t`` -- a class (objects will be coerced to that class) - OUTPUT: - - a list of elements of class 't' + OUTPUT: list of elements of class ``t`` EXAMPLES:: @@ -38,7 +36,7 @@ def read_data(f, t): sage: l = read_data(indata, RealField(17)); l [1.234, 5.678] """ - with open(f, "r") as fp: + with open(f) as fp: l = [] while True: s = fp.readline().strip() diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 7843b799416..eb72c0a7186 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -35,12 +35,11 @@ class Sage(ExtraTabCompletion, Expect): INPUT: - - - ``server`` -- (optional); if specified runs Sage on a - remote machine with address. You must have ssh keys setup so you - can login to the remote machine by typing "ssh remote_machine" and - no password, call _install_hints_ssh() for hints on how to do - that. + - ``server`` -- (optional) if specified runs Sage on a + remote machine with address. You must have ssh keys setup so you + can login to the remote machine by typing "ssh remote_machine" and + no password, call _install_hints_ssh() for hints on how to do + that. The version of Sage should be the same as on the local machine, @@ -126,8 +125,7 @@ class Sage(ExtraTabCompletion, Expect): The double quotes are needed because the call to s3 first evaluates its arguments using the s interpreter, so the call to s3 is passed - ``s('"x"')``, which is the string ``"x"`` - in the s interpreter. + ``s('"x"')``, which is the string ``'x'`` in the s interpreter. """ def __init__(self, logfile=None, @@ -246,7 +244,6 @@ def __call__(self, x): sage: sage0(axiom(x^2+1)) #optional - axiom x^2 + 1 - """ if isinstance(x, ExpectElement): if x.parent() is self: @@ -289,7 +286,7 @@ def _quit_string(self): def preparse(self, x): """ - Returns the preparsed version of the string s. + Return the preparsed version of the string s. EXAMPLES:: @@ -308,11 +305,9 @@ def eval(self, line, strip=True, **kwds): INPUT: + - ``line`` -- input line of code - - ``line`` -- input line of code - - - ``strip`` -- ignored - + - ``strip`` -- ignored EXAMPLES:: @@ -355,8 +350,8 @@ def clear(self, var): """ Clear the variable named var. - Note that the exact format of the NameError for a cleared variable - is slightly platform dependent, see :issue:`10539`. + Note that the exact format of the :exc:`NameError` for a cleared + variable is slightly platform dependent, see :issue:`10539`. EXAMPLES:: @@ -459,7 +454,7 @@ class SageElement(ExpectElement): def _rich_repr_(self, display_manager, **kwds): """ - Disable rich output + Disable rich output. This is necessary because otherwise our :meth:`__getattr__` would be called. @@ -503,7 +498,7 @@ def __getattr__(self, attrname): def _sage_(self): """ - Return local copy of self. + Return local copy of ``self``. EXAMPLES:: diff --git a/src/sage/interfaces/sagespawn.pyx b/src/sage/interfaces/sagespawn.pyx index f146fa01ddb..9cd5bf799c1 100644 --- a/src/sage/interfaces/sagespawn.pyx +++ b/src/sage/interfaces/sagespawn.pyx @@ -40,13 +40,13 @@ class SageSpawn(spawn): """ Spawn a subprocess in a pseudo-tty. - - ``*args``, ``**kwds``: see :class:`pexpect.spawn`. + - ``*args``, ``**kwds`` -- see :class:`pexpect.spawn` - ``name`` -- human-readable name for this process, used for - display purposes only. + display purposes only - ``quit_string`` -- (default: ``None``) if not ``None``, send - this string to the child process before killing it. + this string to the child process before killing it EXAMPLES:: @@ -217,7 +217,7 @@ class SagePtyProcess(PtyProcess): INPUT: - ``interval`` -- (default: 5) how much seconds to wait between - sending two signals. + sending two signals EXAMPLES: diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index c650d8f9ba2..c2d689ef059 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -220,7 +220,7 @@ def __init__(self, maxread=None, script_subdirectory=None, logfile=None, server=None, server_tmpdir=None, seed=None): """ - Initializes the Scilab class. + Initialize the Scilab class. EXAMPLES:: @@ -275,7 +275,7 @@ def set_seed(self, seed=None): def _quit_string(self): """ - Returns the string used to quit the pexpect interface. + Return the string used to quit the pexpect interface. EXAMPLES:: @@ -330,7 +330,7 @@ def eval(self, command, *args, **kwds): def whos(self, name=None, typ=None): """ - Returns information about current objects. + Return information about current objects. Arguments: nam: first characters of selected names typ: name of selected Scilab variable type @@ -386,13 +386,12 @@ def console(self): EXAMPLES:: sage: scilab.console() # optional - scilab; not tested - """ scilab_console() def version(self): """ - Returns the version of the Scilab software used. + Return the version of the Scilab software used. EXAMPLES:: @@ -406,10 +405,10 @@ def sage2scilab_matrix_string(self, A): Return a Scilab matrix from a Sage matrix. INPUT: - A Sage matrix with entries in the rationals or reals. - OUTPUT: - A string that evaluates to a Scilab matrix. + - ``A`` -- Sage matrix with entries in the rationals or reals + + OUTPUT: string that evaluates to a Scilab matrix EXAMPLES:: @@ -423,7 +422,7 @@ def sage2scilab_matrix_string(self, A): def _object_class(self): """ - Returns the class of the object. + Return the class of the object. EXAMPLES:: @@ -460,7 +459,7 @@ def __getitem__(self, n): def __setitem__(self, n, value): """ - Sets an element of a matrix. + Set an element of a matrix. EXAMPLES:: diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index c0ab80e0a68..ed883b07105 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -12,16 +12,16 @@ your computer; this should be the case, since Singular is included with Sage. The interface offers three pieces of functionality: -#. ``singular_console()`` -- A function that dumps you +#. ``singular_console()`` -- a function that dumps you into an interactive command-line Singular session. -#. ``singular(expr, type='def')`` -- Creation of a +#. ``singular(expr, type='def')`` -- creation of a Singular object. This provides a Pythonic interface to Singular. For example, if ``f=singular(10)``, then ``f.factorize()`` returns the factorization of `10` computed using Singular. -#. ``singular.eval(expr)`` -- Evaluation of arbitrary +#. ``singular.eval(expr)`` -- evaluation of arbitrary Singular expressions, with the result returned as a string. Of course, there are polynomial rings and ideals in Sage as well @@ -538,7 +538,6 @@ def _send_interrupt(self): True sage: 3*a 3 - """ # Work around for Singular bug # http://www.singular.uni-kl.de:8002/trac/ticket/727 @@ -580,12 +579,12 @@ def eval(self, x, allow_semicolon=True, strip=True, **kwds): INPUT: - - ``x`` -- string (of code) + - ``x`` -- string (of code) - - ``allow_semicolon`` -- default: ``False``; if False then - raise a :class:`TypeError` if the input line contains a semicolon. + - ``allow_semicolon`` -- (default: ``False``) if ``False`` then + raise a :exc:`TypeError` if the input line contains a semicolon - - ``strip`` -- ignored + - ``strip`` -- ignored EXAMPLES:: @@ -700,7 +699,6 @@ def set(self, type, name, value): sage: singular.set('int', 'y', '5') sage: singular.eval('defined(%s)'%n) '0' - """ cmd = ''.join('if(defined(%s)){kill %s;};' % (v, v) for v in self.__to_clear) @@ -741,7 +739,6 @@ def clear(self, var): sage: a = singular(3) sage: singular.get('x') '`x`' - """ # We add the variable to the list of vars to clear when we do an eval. # We queue up all the clears and do them at once to avoid synchronizing @@ -752,7 +749,7 @@ def clear(self, var): def _create(self, value, type='def'): """ - Creates a new variable in the Singular session and returns the name + Create a new variable in the Singular session and returns the name of that variable. EXAMPLES:: @@ -774,7 +771,7 @@ def __call__(self, x, type='def'): could be anything, and can be recovered using X.name(). The object X returned can be used like any Sage object, and wraps - an object in self. The standard arithmetic operators work. Moreover + an object in ``self``. The standard arithmetic operators work. Moreover if foo is a function then X.foo(y,z,...) calls foo(X, y, z, ...) and returns the corresponding object. @@ -855,8 +852,8 @@ def lib(self, lib, reload=False): Load the Singular library named lib. Note that if the library was already loaded during this session it - is not reloaded unless the optional reload argument is True (the - default is False). + is not reloaded unless the optional reload argument is ``True`` (the + default is ``False``). EXAMPLES:: @@ -882,10 +879,8 @@ def ideal(self, *gens): INPUT: - - - ``gens`` -- list or tuple of Singular objects (or - objects that can be made into Singular objects via evaluation) - + - ``gens`` -- list or tuple of Singular objects (or + objects that can be made into Singular objects via evaluation) OUTPUT: the Singular ideal generated by the given list of gens @@ -930,7 +925,7 @@ def ideal(self, *gens): def list(self, x): r""" - Creates a list in Singular from a Sage list ``x``. + Create a list in Singular from a Sage list ``x``. EXAMPLES:: @@ -1052,19 +1047,17 @@ def ring(self, char=0, vars='(x)', order='lp', check=None): INPUT: + - ``char`` -- string; a string specifying the characteristic + of the base ring, in the format accepted by Singular (see + examples below) - - ``char`` (string) -- a string specifying the characteristic - of the base ring, in the format accepted by Singular (see - examples below). - - - ``vars`` -- a tuple or string defining the variable names - - - ``order`` (string) -- the monomial order (default: "lp") + - ``vars`` -- tuple or string defining the variable names + - ``order`` -- string; the monomial order (default: ``'lp'``) OUTPUT: a Singular ring - .. note:: + .. NOTE:: This function is *not* identical to calling the Singular ``ring`` function. In particular, it also attempts to @@ -1139,7 +1132,7 @@ def ring(self, char=0, vars='(x)', order='lp', check=None): def string(self, x): """ - Creates a Singular string from a Sage string. Note that the Sage + Create a Singular string from a Sage string. Note that the Sage string has to be "double-quoted". EXAMPLES:: @@ -1151,7 +1144,7 @@ def string(self, x): def set_ring(self, R): """ - Sets the current Singular ring to R. + Set the current Singular ring to `R`. EXAMPLES:: @@ -1395,8 +1388,6 @@ def _repr_(self): sage: M T[1,1],y, 0, 1 - - """ s = super()._repr_() if self._name in s: @@ -1479,19 +1470,17 @@ def __len__(self): def __setitem__(self, n, value): """ - Set the n-th element of self to x. + Set the `n`-th element of ``self`` to `x`. INPUT: + - ``n`` -- integer *or* a 2-tuple (for setting + matrix elements) - - ``n`` -- an integer *or* a 2-tuple (for setting - matrix elements) + - ``value`` -- anything (is coerced to a Singular + object if it is not one already) - - ``value`` -- anything (is coerced to a Singular - object if it is not one already) - - - OUTPUT: Changes elements of self. + OUTPUT: changes elements of ``self`` EXAMPLES:: @@ -1636,7 +1625,6 @@ def sage_global_ring(self): AUTHOR: - Simon King (2011-06-06) - """ # extract the ring of coefficients singular = self.parent() @@ -1712,16 +1700,15 @@ def sage_poly(self, R=None, kcache=None): INPUT: + - ``R`` -- (default: ``None``) an optional polynomial ring. + If it is provided, then you have to make sure that it + matches the current singular ring as, e.g., returned by + ``singular.current_ring()``. By default, the output of + :meth:`sage_global_ring` is used. - - ``R`` -- (default: None); an optional polynomial ring. - If it is provided, then you have to make sure that it - matches the current singular ring as, e.g., returned by - singular.current_ring(). By default, the output of - :meth:`sage_global_ring` is used. - - - ``kcache`` -- (default: None); an optional dictionary - for faster finite field lookups, this is mainly useful for finite - extension fields + - ``kcache`` -- (default: ``None``) an optional dictionary + for faster finite field lookups, this is mainly useful for finite + extension fields OUTPUT: MPolynomial @@ -1732,7 +1719,7 @@ def sage_poly(self, R=None, kcache=None): sage: f = R('a^20*x^2*y+a^10+x') sage: f._singular_().sage_poly(R) == f True - sage: R = PolynomialRing(GF(2^8,'a'), 'x', implementation="singular") + sage: R = PolynomialRing(GF(2^8,'a'), 'x', implementation='singular') sage: f = R('a^20*x^3+x^2+a^10') sage: f._singular_().sage_poly(R) == f True @@ -1786,7 +1773,7 @@ def sage_poly(self, R=None, kcache=None): - Simon King (2011-06-06): Deal with Singular's short polynomial representation, automatic construction of a polynomial ring, if it is not explicitly given. - .. note:: + .. NOTE:: For very simple polynomials ``eval(SingularElement.sage_polystring())`` is faster than @@ -1797,7 +1784,7 @@ def sage_poly(self, R=None, kcache=None): # TODO: Refactor imports to move this to the top from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.polydict import ETuple from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular from sage.rings.quotient_ring import QuotientRing_generic @@ -1888,7 +1875,7 @@ def sage_poly(self, R=None, kcache=None): return R(sage_repr) - elif is_PolynomialRing(R) and (ring_is_fine or can_convert_to_singular(R)): + elif isinstance(R, PolynomialRing_general) and (ring_is_fine or can_convert_to_singular(R)): sage_repr = [0] * int(self.deg() + 1) @@ -1922,12 +1909,12 @@ def sage_matrix(self, R, sparse=True): INPUT: - - ``R`` -- (default: None); an optional ring, over which - the resulting matrix is going to be defined. - By default, the output of :meth:`sage_global_ring` is used. + - ``R`` -- (default: ``None``) an optional ring, over which + the resulting matrix is going to be defined. + By default, the output of :meth:`sage_global_ring` is used. - - ``sparse`` -- (default: ``True``); determines whether the - resulting matrix is sparse or not. + - ``sparse`` -- boolean (default: ``True``); whether the + resulting matrix is sparse or not EXAMPLES:: @@ -1962,7 +1949,7 @@ def sage_matrix(self, R, sparse=True): def _sage_(self, R=None): r""" - Convert self to Sage. + Convert ``self`` to Sage. EXAMPLES:: @@ -2086,13 +2073,12 @@ def is_string(self): True sage: singular('1').is_string() False - """ return self.type() == 'string' def set_ring(self): """ - Sets the current ring in Singular to be self. + Set the current ring in Singular to be ``self``. EXAMPLES:: @@ -2133,7 +2119,7 @@ def sage_flattened_str_list(self): def sage_structured_str_list(self): r""" - If self is a Singular list of lists of Singular elements, returns + If ``self`` is a Singular list of lists of Singular elements, return corresponding Sage list of lists of strings. EXAMPLES:: @@ -2237,16 +2223,14 @@ def _singular_(self): def attrib(self, name, value=None): """ - Get and set attributes for self. + Get and set attributes for ``self``. INPUT: + - ``name`` -- string to choose the attribute - - ``name`` -- string to choose the attribute - - - ``value`` -- boolean value or None for reading, - (default:None) - + - ``value`` -- boolean value or ``None`` for reading, + (default: ``None``) VALUES: isSB - the standard basis property is set by all commands computing a standard basis like groebner, std, stdhilb etc.; used @@ -2336,7 +2320,7 @@ def _instancedoc_(self): def is_SingularElement(x): r""" - Return True is ``x`` is of type :class:`SingularElement`. + Return ``True`` if ``x`` is of type :class:`SingularElement`. This function is deprecated; use :func:`isinstance` (of :class:`sage.interfaces.abc.SingularElement`) instead. @@ -2426,7 +2410,6 @@ def get_docstring(name): True sage: 'standard.lib' in get_docstring('groebner') True - """ if not nodes: generate_docstring_dictionary() @@ -2502,7 +2485,7 @@ class SingularGBLogPrettyPrinter: deg_lead = re.compile(r"\d+") # the degree of the leading terms is currently d # SlimGB - red_para = re.compile(r"M\[(\d+),(\d+)\]") # parallel reduction of n elements with m non-zero output elements + red_para = re.compile(r"M\[(\d+),(\d+)\]") # parallel reduction of n elements with m nonzero output elements red_betr = re.compile("b") # exchange of a reductor by a 'better' one non_mini = re.compile("e") # a new reductor with non-minimal leading term @@ -2554,7 +2537,7 @@ def write(self, s): sage: s3.write("(S:1337)") Performing complete reduction of 1337 elements. sage: s3.write("M[389,12]") - Parallel reduction of 389 elements with 12 non-zero output elements. + Parallel reduction of 389 elements with 12 nonzero output elements. """ verbosity = self.verbosity @@ -2631,12 +2614,11 @@ def write(self, s): if verbosity >= 1: print("Leading term degree: %2d." % int(token)) self.curr_deg = int(token) - if self.max_deg < self.curr_deg: - self.max_deg = self.curr_deg + self.max_deg = max(self.max_deg, self.curr_deg) elif re.match(SingularGBLogPrettyPrinter.red_para, token) and verbosity >= 3: m, n = re.match(SingularGBLogPrettyPrinter.red_para, token).groups() - print("Parallel reduction of %s elements with %s non-zero output elements." % (m, n)) + print("Parallel reduction of %s elements with %s nonzero output elements." % (m, n)) elif re.match(SingularGBLogPrettyPrinter.red_betr, token) and verbosity >= 3: print("Replaced reductor by 'better' one.") @@ -2672,7 +2654,7 @@ def __init__(self, singular=None): INPUT: - - ``singular`` -- Singular instance (default: default instance) + - ``singular`` -- Singular instance (default: default instance) EXAMPLES:: @@ -2704,7 +2686,7 @@ def __init__(self, singular=None): sage: (7*a-420*c^3+158*c^2+8*c-7)/7 < (a+2*b+2*c-1) True - .. note:: + .. NOTE:: This context is used automatically internally whenever a Groebner basis is computed so the user does not need to use @@ -2807,7 +2789,7 @@ def singular_gb_standard_options(func): ... ' return self.basis.reduced()\n'], ...) - .. note:: + .. NOTE:: This decorator is used automatically internally so the user does not need to use it manually. diff --git a/src/sage/interfaces/sympy.py b/src/sage/interfaces/sympy.py index d291727ee0e..5a380a86271 100644 --- a/src/sage/interfaces/sympy.py +++ b/src/sage/interfaces/sympy.py @@ -418,8 +418,8 @@ def _sympysage_Subs(self): sage: from sympy.core.singleton import S """ args = self.args - substi = dict([(args[1][i]._sage_(), args[2][i]._sage_()) - for i in range(len(args[1]))]) + substi = {args[1][i]._sage_(): args[2][i]._sage_() + for i in range(len(args[1]))} return args[0]._sage_().subs(substi) @@ -765,7 +765,7 @@ def _sympysage_piecewise(self): sage: assert ex == sp._sage_() sage: _ = var('y, z') - sage: (x^y - z).integrate(y, algorithm="sympy") + sage: (x^y - z).integrate(y, algorithm='sympy') -y*z + cases(((log(x) != 0, x^y/log(x)), (1, y))) """ from sage.functions.other import cases @@ -1197,7 +1197,7 @@ def sympy_init(): def check_expression(expr, var_symbols, only_from_sympy=False): """ - Does ``eval(expr)`` both in Sage and SymPy and does other checks. + Do ``eval(expr)`` both in Sage and SymPy and other checks. EXAMPLES:: diff --git a/src/sage/interfaces/sympy_wrapper.py b/src/sage/interfaces/sympy_wrapper.py index 5ad6095a787..40c96d60d26 100644 --- a/src/sage/interfaces/sympy_wrapper.py +++ b/src/sage/interfaces/sympy_wrapper.py @@ -157,7 +157,6 @@ def _contains(self, element): Traceback (most recent call last): ... TypeError: did not evaluate to a bool: None - """ if element.is_symbol: # keep symbolic diff --git a/src/sage/interfaces/tab_completion.py b/src/sage/interfaces/tab_completion.py index ca106a67273..29865b54d9e 100644 --- a/src/sage/interfaces/tab_completion.py +++ b/src/sage/interfaces/tab_completion.py @@ -27,11 +27,11 @@ import builtins -class ExtraTabCompletion(): +class ExtraTabCompletion: def __dir__(self): """ - Add to the dir() output + Add to the ``dir()`` output. This is used by IPython to read off the tab completions. @@ -58,14 +58,12 @@ def completions(s, globs): INPUT: - - ``s`` -- a string + - ``s`` -- string - - ``globs`` -- a string: object dictionary; context in which to + - ``globs`` -- string: object dictionary; context in which to search for completions, e.g., :func:`globals()` - OUTPUT: - - a list of strings + OUTPUT: list of strings EXAMPLES:: @@ -73,7 +71,7 @@ def completions(s, globs): sage: import sage.interfaces.tab_completion as s sage: p = x**2 + 1 sage: s.completions('p.co',globals()) # indirect doctest - ['p.coefficients',...] + ['p.coefficient',...] sage: s.completions('dic',globals()) # indirect doctest ['dickman_rho', 'dict'] diff --git a/src/sage/interfaces/tachyon.py b/src/sage/interfaces/tachyon.py index 024092fdc8f..c4596c825d3 100644 --- a/src/sage/interfaces/tachyon.py +++ b/src/sage/interfaces/tachyon.py @@ -695,48 +695,46 @@ class TachyonRT(SageObject): r""" - The Tachyon Ray Tracer + The Tachyon Ray Tracer. Usage: ``tachyon_rt(model, outfile='sage.png', verbose=1, block=True, extra_opts='')`` INPUT: - - ``model`` -- a string that describes a 3d model in - the Tachyon modeling format. Type ``sage.interfaces.tachyon?`` for a - description of this format. + - ``model`` -- string that describes a 3d model in + the Tachyon modeling format. Type ``sage.interfaces.tachyon?`` for a + description of this format. - - ``outfile`` -- (default: 'sage.png') output filename; - the extension of the filename determines the type. Supported types - include: + - ``outfile`` -- (default: ``'sage.png'``) output filename; + the extension of the filename determines the type. Supported types + include: - - ``tga`` -- 24-bit (uncompressed) + - ``tga`` -- 24-bit (uncompressed) - - ``bmp`` -- 24-bit Windows BMP (uncompressed) + - ``bmp`` -- 24-bit Windows BMP (uncompressed) - - ``ppm`` -- 24-bit PPM (uncompressed) + - ``ppm`` -- 24-bit PPM (uncompressed) - - ``rgb`` -- 24-bit SGI RGB (uncompressed) + - ``rgb`` -- 24-bit SGI RGB (uncompressed) - - ``png`` -- 24-bit PNG (compressed, lossless) + - ``png`` -- 24-bit PNG (compressed, lossless) - - ``verbose`` -- integer; (default: 1) + - ``verbose`` -- integer; (default: 1) - - ``0`` -- silent + - ``0`` -- silent - - ``1`` -- some output + - ``1`` -- some output - - ``2`` -- very verbose output + - ``2`` -- very verbose output - - ``block`` -- bool (default: ``True``); if False, run the - rendering command in the background. + - ``block`` -- boolean (default: ``True``); if ``False``, run the + rendering command in the background - - ``extra_opts`` -- passed directly to tachyon command - line. Use tachyon_rt.usage() to see some of the possibilities. + - ``extra_opts`` -- passed directly to tachyon command + line. Use ``tachyon_rt.usage()`` to see some of the possibilities - OUTPUT: - - - Some text may be displayed onscreen. + OUTPUT: some text may be displayed onscreen - The file outfile is created. @@ -746,7 +744,8 @@ class TachyonRT(SageObject): """ def _repr_(self): """ - Returns a brief description of this interface object (the Tachyon raytracer written by John Stone). + Return a brief description of this interface object (the Tachyon + raytracer written by John Stone). TESTS:: @@ -763,15 +762,15 @@ def __call__(self, model, outfile='sage.png', verbose=1, extra_opts=''): INPUT: - - ``model`` -- string. The tachyon model. + - ``model`` -- string; the tachyon model - - ``outfile`` -- string, default ``'sage.png'``. The filename - to save the model to. + - ``outfile`` -- string (default: ``'sage.png'``); the filename + to save the model to - - ``verbose`` -- 0, 1, (default) or 2. The verbosity level. + - ``verbose`` -- 0, 1, (default) or 2; the verbosity level - - ``extra_opts`` -- string (default: empty string). Extra - options that will be appended to the tachyon commandline. + - ``extra_opts`` -- string (default: empty string); extra + options that will be appended to the tachyon commandline EXAMPLES:: @@ -838,7 +837,9 @@ def __call__(self, model, outfile='sage.png', verbose=1, extra_opts=''): def usage(self, use_pager=True): """ - Returns the basic description of using the Tachyon raytracer (simply what is returned by running tachyon with no input). The output is paged unless use_pager=False. + Return the basic description of using the Tachyon raytracer (simply + what is returned by running tachyon with no input). The output is + paged unless ``use_pager=False``. TESTS:: @@ -861,7 +862,7 @@ def usage(self, use_pager=True): @cached_method def version(self): """ - Returns the version of the Tachyon raytracer being used. + Return the version of the Tachyon raytracer being used. TESTS:: @@ -879,7 +880,7 @@ def version(self): def help(self, use_pager=True): """ - Deprecated: type 'sage.interfaces.tachyon?' for help + Deprecated: type 'sage.interfaces.tachyon?' for help. TESTS:: diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index 309046f30ac..c1076496cea 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -56,11 +56,11 @@ def subexpressions_list(f, pars=None): INPUT: - - ``f`` -- a symbolic function of several components. + - ``f`` -- a symbolic function of several components - - ``pars`` -- a list of the parameters that appear in the function + - ``pars`` -- list of the parameters that appear in the function this should be the symbolic constants that appear in f but are not - arguments. + arguments OUTPUT: @@ -74,7 +74,6 @@ def subexpressions_list(f, pars=None): For the trigonometric functions, some extra expressions will be added. These extra expressions will be used later to compute their derivatives. - EXAMPLES:: sage: from sage.interfaces.tides import subexpressions_list @@ -145,8 +144,6 @@ def subexpressions_list(f, pars=None): ('cos', y), ('add', sin(y), x^2), ('exp', x^2 + sin(y))]) - - """ from sage.functions.trig import sin, cos, arcsin, arctan, arccos variables = f[0].arguments() @@ -332,8 +329,6 @@ def remove_repeated(l1, l2): ('add', 1, -a^2), ('pow', -a^2 + 1, 0.5), ('asin', a)]) - - """ for i in range(len(l1)-1): j = i+1 @@ -361,7 +356,6 @@ def remove_constants(l1,l2): sage: remove_constants(l1,l2) sage: l1, l2 ([a*cos(7), a*cos(7) + 1], [('mul', cos(7), a), ('add', 1, a*cos(7))]) - """ i = 0 while i < len(l1): @@ -379,25 +373,25 @@ def genfiles_mintides(integrator, driver, f, ics, initial, final, delta, INPUT: - - ``integrator`` -- the name of the integrator file. + - ``integrator`` -- the name of the integrator file - - ``driver`` -- the name of the driver file. + - ``driver`` -- the name of the driver file - - ``f`` -- the function that determines the differential equation. + - ``f`` -- the function that determines the differential equation - - ``ics`` -- a list or tuple with the initial conditions. + - ``ics`` -- list or tuple with the initial conditions - - ``initial`` -- the initial time for the integration. + - ``initial`` -- the initial time for the integration - - ``final`` -- the final time for the integration. + - ``final`` -- the final time for the integration - - ``delta`` -- the step of the output. + - ``delta`` -- the step of the output - - ``tolrel`` -- the relative tolerance. + - ``tolrel`` -- the relative tolerance - - ``tolabs`` -- the absolute tolerance. + - ``tolabs`` -- the absolute tolerance - - ``output`` -- the name of the file that the compiled integrator will write to + - ``output`` -- the name of the file that the compiled integrator will write to This function creates two files, integrator and driver, that can be used later with the min_tides library [TIDES]_. @@ -462,8 +456,6 @@ def genfiles_mintides(integrator, driver, f, ics, initial, final, delta, sage: l[18] ' \tv[0] = 3.1415926535897931 ; \n' sage: shutil.rmtree(tempdir) - - """ RR = RealField() @@ -639,33 +631,33 @@ def genfiles_mpfr(integrator, driver, f, ics, initial, final, delta, INPUT: - - ``integrator`` -- the name of the integrator file. + - ``integrator`` -- the name of the integrator file - - ``driver`` -- the name of the driver file. + - ``driver`` -- the name of the driver file - - ``f`` -- the function that determines the differential equation. + - ``f`` -- the function that determines the differential equation - - ``ics`` -- a list or tuple with the initial conditions. + - ``ics`` -- list or tuple with the initial conditions - - ``initial`` -- the initial time for the integration. + - ``initial`` -- the initial time for the integration - - ``final`` -- the final time for the integration. + - ``final`` -- the final time for the integration - - ``delta`` -- the step of the output. + - ``delta`` -- the step of the output - ``parameters`` -- the variables inside the function that should be treated - as parameters. + as parameters - ``parameter_values`` -- the values of the parameters for the particular - initial value problem. + initial value problem - ``dig`` -- the number of digits of precision that will be used in the integration - - ``tolrel`` -- the relative tolerance. + - ``tolrel`` -- the relative tolerance - - ``tolabs`` -- the absolute tolerance. + - ``tolabs`` -- the absolute tolerance - - ``output`` -- the name of the file that the compiled integrator will write to + - ``output`` -- the name of the file that the compiled integrator will write to This function creates two files, integrator and driver, that can be used later with the tides library ([TIDES]_). @@ -743,7 +735,6 @@ def genfiles_mpfr(integrator, driver, f, ics, initial, final, delta, sage: l[24] '\tmpfr_set_str(v[0], "3.141592653589793238462643383279502884197169399375101", 10, TIDES_RND);\n' sage: shutil.rmtree(tempdir) - """ if parameters is None: parameters = [] diff --git a/src/sage/knots/all.py b/src/sage/knots/all.py index d25acbda1a3..5e456b752b3 100644 --- a/src/sage/knots/all.py +++ b/src/sage/knots/all.py @@ -1,5 +1,4 @@ from sage.misc.lazy_import import lazy_import -from sage.features.databases import DatabaseKnotInfo lazy_import('sage.knots.knot', ['Knot', 'Knots']) lazy_import('sage.knots.link', 'Link') diff --git a/src/sage/knots/free_knotinfo_monoid.py b/src/sage/knots/free_knotinfo_monoid.py new file mode 100644 index 00000000000..d62e6743c79 --- /dev/null +++ b/src/sage/knots/free_knotinfo_monoid.py @@ -0,0 +1,507 @@ +# sage_setup: distribution = sagemath-graphs +r""" +Free monoid generated by prime knots available via the +:class:`~sage.knots.knotinfo.KnotInfoBase` class. + +A generator of this free abelian monoid is a prime knot according to +the list at `KnotInfo `__. A fully +amphicheiral prime knot is represented by exactly one generator with +the corresponding name. For non-chiral prime knots, there are +additionally one or three generators with the suffixes ``m``, ``r`` +and ``c`` which specify the mirror and reverse images according to +their symmetry type. + +AUTHORS: + +- Sebastian Oehms June 2024: initial version +""" + +############################################################################## +# Copyright (C) 2024 Sebastian Oehms +# +# 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. +# http://www.gnu.org/licenses/ +############################################################################## + +from sage.knots.knotinfo import SymmetryMutant +from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, + IndexedFreeAbelianMonoidElement) +from sage.misc.cachefunc import cached_method +from sage.structure.unique_representation import UniqueRepresentation + + +class FreeKnotInfoMonoidElement(IndexedFreeAbelianMonoidElement): + """ + An element of an indexed free abelian monoid. + """ + def as_knot(self): + r""" + Return the knot represented by ``self``. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: FKIM.inject_variables(select=3) + Defining K3_1 + Defining K3_1m + sage: K = K3_1^2 * K3_1m + sage: K.as_knot() + Knot represented by 9 crossings + """ + wl = self.to_word_list() + P = self.parent() + if len(wl) == 1: + name = wl[0] + L = P._index_dict[name][0].link() + if name.endswith(SymmetryMutant.mirror_image.value): + return L.mirror_image() + if name.endswith(SymmetryMutant.reverse.value): + return L.reverse() + if name.endswith(SymmetryMutant.concordance_inverse.value): + return L.mirror_image().reverse() + return L + else: + from sage.misc.misc_c import prod + return prod(P.gen(wl[i]).as_knot() for i in range(len(wl))) + + def to_knotinfo(self): + r""" + Return a word representing ``self`` as a list of pairs. + + Each pair ``(ki, sym)`` consists of a + :class:`~sage.knots.knotinfo.KnotInfoBase` instance ``ki`` and + :class:`~sage.knots.knotinfo.SymmetryMutant` instance ``sym``. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: FKIM.inject_variables(select=3) + Defining K3_1 + Defining K3_1m + sage: K = K3_1^2 * K3_1m + sage: K.to_knotinfo() + [(, ), + (, ), + (, )] + """ + wl = self.to_word_list() + P = self.parent() + return [P._index_dict[w] for w in wl] + + +class FreeKnotInfoMonoid(IndexedFreeAbelianMonoid): + + Element = FreeKnotInfoMonoidElement + + @staticmethod + def __classcall_private__(cls, max_crossing_number=6, prefix=None, **kwds): + r""" + Normalize input to ensure a unique representation. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FreeKnotInfoMonoid() + Free abelian monoid of knots with at most 6 crossings + sage: FreeKnotInfoMonoid(5) + Free abelian monoid of knots with at most 5 crossings + """ + if not prefix: + prefix = 'KnotInfo' + # We skip the IndexedMonoid__classcall__ + return UniqueRepresentation.__classcall__(cls, max_crossing_number, + prefix=prefix, **kwds) + + def __init__(self, max_crossing_number, category=None, prefix=None, **kwds): + r""" + Initialize ``self`` with generators belonging to prime knots with + at most ``max_crossing_number`` crossings. + + TESTS: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: FKIM4 = FreeKnotInfoMonoid(4) + sage: TestSuite(FKIM).run() + sage: TestSuite(FKIM4).run() + """ + self._max_crossing_number = None + self._set_index_dictionary(max_crossing_number=max_crossing_number) + from sage.sets.finite_enumerated_set import FiniteEnumeratedSet + indices = FiniteEnumeratedSet(self._index_dict) + super().__init__(indices, prefix) + + def _from_knotinfo(self, knotinfo, symmetry_mutant): + r""" + Return the name on the generator for the given ``symmetry_mutant`` + of the given entry ``knotinfo`` if the KnotInfo database. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: from sage.knots.knotinfo import SymmetryMutant + sage: FKIM = FreeKnotInfoMonoid() + sage: ki = KnotInfo.K5_2 + sage: FKIM._from_knotinfo(ki, SymmetryMutant.itself) + 'K5_2' + sage: FKIM._from_knotinfo(ki, SymmetryMutant.concordance_inverse) + 'K5_2c' + """ + if symmetry_mutant == SymmetryMutant.itself: + return knotinfo.name + else: + return '%s%s' % (knotinfo.name, symmetry_mutant.value) + + def _set_index_dictionary(self, max_crossing_number=6): + r""" + Set or expand the set of generators. + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FreeKnotInfoMonoid() + Free abelian monoid of knots with at most 6 crossings + + TESTS:: + + sage: from sage.features.databases import DatabaseKnotInfo + sage: F = DatabaseKnotInfo() + sage: F.hide() + sage: FreeKnotInfoMonoid(7) # indirect doctest + Traceback (most recent call last): + ... + sage.features.FeatureNotPresentError: database_knotinfo is not available. + Feature `database_knotinfo` is hidden. + Use method `unhide` to make it available again. + sage: F.unhide() + """ + if max_crossing_number > 6: + from sage.features.databases import DatabaseKnotInfo + DatabaseKnotInfo().require() + + current_max_crossing_number = self._max_crossing_number + if not current_max_crossing_number: + current_max_crossing_number = - 1 + self._index_dict = {} + self._max_crossing_number = max_crossing_number + + def add_index(ki, sym): + self._index_dict[self._from_knotinfo(ki, sym)] = (ki, sym) + + from sage.knots.knotinfo import KnotInfo + for K in KnotInfo: + ncr = K.crossing_number() + if ncr <= current_max_crossing_number: + continue + if ncr > self._max_crossing_number: + break + for sym in SymmetryMutant: + if sym.is_minimal(K): + add_index(K, sym) + if current_max_crossing_number > 0: + from sage.sets.finite_enumerated_set import FiniteEnumeratedSet + self._indices = FiniteEnumeratedSet(self._index_dict) + + def _repr_(self): + """ + Return a string representation of ``self``. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FreeKnotInfoMonoid(4) + Free abelian monoid of knots with at most 4 crossings + """ + return "Free abelian monoid of knots with at most %s crossings" % self._max_crossing_number + + def _element_constructor_(self, x=None): + """ + Create an element of this abelian monoid from ``x``. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: K = KnotInfo.K5_1.link().mirror_image() + sage: FKIM(K) + KnotInfo['K5_1m'] + """ + if isinstance(x, tuple): + if len(x) == 2: + ki, sym = x + from sage.knots.knotinfo import KnotInfoBase + if isinstance(ki, KnotInfoBase) and isinstance(sym, SymmetryMutant): + mcr = ki.crossing_number() + if mcr > self._max_crossing_number: + self._set_index_dictionary(max_crossing_number=mcr) + + sym_min = min([sym] + sym.matches(ki)) + return self.gen(self._from_knotinfo(ki, sym_min)) + + from sage.knots.knot import Knot + from sage.knots.link import Link + if not isinstance(x, Knot): + if isinstance(x, Link): + x = Knot(x.pd_code()) + if isinstance(x, Knot): + return self.from_knot(x) + return self.element_class(self, x) + + @cached_method + def _check_elements(self, knot, elems): + r""" + Return a matching item from the list in ``elems`` if it exists. + Elsewise return ``None``. This is a helper method for .meth:`from_knot`. + + INPUT: + + - ``knot`` -- an instance of :class:`~sage.knots.knot.Knot` + - ``elems`` -- a tuple of elements of ``self`` + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: FKIM.inject_variables(select=3) + Defining K3_1 + Defining K3_1m + sage: elems = (K3_1, K3_1m) + sage: K = Knots().from_table(3, 1) + sage: FKIM._check_elements(K, elems) + KnotInfo['K3_1m'] + sage: K = Knots().from_table(4, 1) + sage: FKIM._check_elements(K, elems) is None + True + """ + for e in elems: + k = e.as_knot() + if knot.pd_code() == k.pd_code(): + return e + if knot._markov_move_cmp(k.braid()): + return e + return None + + @cached_method + def _search_composition(self, max_cr, knot, hpoly): + r""" + Add KnotInfo items to the list of candidates that have + matching Homfly polynomial. + + INPUT: + + - ``max_cr`` -- max number of crossing to stop searching + - ``knot`` -- instance of :class:`~sage.knots.knot.Knot` + - ``hpoly`` -- Homfly polynomial to search for a component + + OUTPUT: + + A tuple of elements of ``self`` that match a (not necessarily prime or + proper) component of the given knot having the given Homfly polynomial. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: FKIM.inject_variables(select=3) + Defining K3_1 + Defining K3_1m + sage: KI = K3_1 * K3_1m + sage: K = KI.as_knot() + sage: h = K3_1.to_knotinfo()[0][0].homfly_polynomial() + sage: FKIM._search_composition(3, K, h) + (KnotInfo['K3_1'],) + """ + from sage.knots.knotinfo import KnotInfo + + def hp_mirr(hp): + v, z = hp.parent().gens() + return hp.subs({v: ~v, z: z}) + + former_cr = 3 + res = [] + for K in KnotInfo: + if not K.is_knot(): + break + c = K.crossing_number() + if c < 3: + continue + if c > max_cr: + break + hp = K.homfly_polynomial() + hp_sym = {s: hp for s in SymmetryMutant if s.is_minimal(K)} + hpm = hp_mirr(hp) + if hp != hpm: + hp_sym[SymmetryMutant.mirror_image] = hpm + if SymmetryMutant.concordance_inverse in hp_sym.keys(): + hp_sym[SymmetryMutant.concordance_inverse] = hpm + + for sym_mut in hp_sym.keys(): + hps = hp_sym[sym_mut] + if hps.divides(hpoly): + Kgen = self((K, sym_mut)) + h = hpoly // hps + if h.is_unit(): + res += [Kgen] + else: + res_rec = self._search_composition(max_cr - c, knot, h) + if res_rec: + res += [Kgen * k for k in res_rec] + if c > former_cr and res: + k = self._check_elements(knot, tuple(res)) + if k: + # matching item found + return tuple([k]) + former_cr = c + + return tuple(sorted(set(res))) + + @cached_method + def _from_knot(self, knot): + """ + Create a tuple of element of this abelian monoid which possibly + represent ``knot``. This method caches the performance relevant + part of :meth:`from_knot`. + + INPUT: + + - ``knot`` -- an instance of :class:`~sage.knots.knot.Knot` + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: K = KnotInfo.K5_1.link().mirror_image() + sage: FKIM._from_knot(K) + (KnotInfo['K5_1m'],) + """ + hp = knot.homfly_polynomial(normalization='vz') + return self._search_composition(13, knot, hp) + + def from_knot(self, knot, unique=True): + """ + Create an element of this abelian monoid from ``knot``. + + INPUT: + + - ``knot`` -- an instance of :class:`~sage.knots.knot.Knot` + + - ``unique`` -- boolean (default is ``True``). This only affects the case + where a unique identification is not possible. If set to ``False`` you + can obtain a matching list (see explanation of the output below) + + OUTPUT: + + An instance of the element class of ``self`` per default. If the keyword + argument ``unique`` then a list of such instances is returned. + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid() + sage: K = KnotInfo.K5_1.link().mirror_image() + sage: FKIM.from_knot(K) + KnotInfo['K5_1m'] + + sage: # optional - database_knotinfo + sage: K = Knot(KnotInfo.K9_12.braid()) + sage: FKIM.from_knot(K) # long time + Traceback (most recent call last): + ... + NotImplementedError: this (possibly non prime) knot cannot be + identified uniquely by KnotInfo + use keyword argument `unique` to obtain more details + sage: FKIM.from_knot(K, unique=False) # long time + [KnotInfo['K4_1']*KnotInfo['K5_2'], KnotInfo['K9_12']] + """ + hp = knot.homfly_polynomial(normalization='vz') + num_summands = sum(e for _, e in hp.factor()) + if num_summands == 1: + return knot.get_knotinfo() + + res = self._from_knot(knot) + if res: + if len(res) == 1: + if unique: + return res[0] + return [res[0]] # to be consistent with get_knotinfo + k = self._check_elements(knot, res) + if k: + if unique: + return k + return [k] # to be consistent with get_knotinfo + + if res and not unique: + return sorted(set(res)) + if unique and len(res) > 1: + non_unique_hint = '\nuse keyword argument `unique` to obtain more details' + raise NotImplementedError('this (possibly non prime) knot cannot be identified uniquely by KnotInfo%s' % non_unique_hint) + raise NotImplementedError('this (possibly non prime) knot cannot be identified by KnotInfo') + + def inject_variables(self, select=None, verbose=True): + """ + Inject ``self`` with its name into the namespace of the + Python code from which this function is called. + + INPUT: + + - ``select`` -- instance of :class:`~sage.knots.knotinfo.KnotInfoBase`, + :class:`~sage.knots.knotinfo.KnotInfoSeries` or an integer. In all + cases the input is used to restrict the injected generators to the + according subset (number of crossings in the case of integer) + - ``verbose`` -- boolean (optional, default ``True``) to suppress + the message printed on the invocation + + EXAMPLES:: + + sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + sage: FKIM = FreeKnotInfoMonoid(5) + sage: FKIM.inject_variables(select=3) + Defining K3_1 + Defining K3_1m + sage: FKIM.inject_variables(select=KnotInfo.K5_2) + Defining K5_2 + Defining K5_2m + sage: FKIM.inject_variables(select=KnotInfo.K5_2.series()) + Defining K5_1 + Defining K5_1m + sage: FKIM.inject_variables() + Defining K0_1 + Defining K4_1 + """ + from sage.knots.knotinfo import KnotInfoBase, KnotInfoSeries + from sage.rings.integer import Integer + gen_list = [] + idx_dict = self._index_dict + max_crn = self._max_crossing_number + gens = self.gens() + if select: + if isinstance(select, KnotInfoBase): + crn = select.crossing_number() + if crn > max_crn: + self._set_index_dictionary(max_crossing_number=crn) + gen_list += [k for k, v in idx_dict.items() if v[0] == select] + elif isinstance(select, KnotInfoSeries): + for v in select: + self.inject_variables(select=v) + return + elif type(select) is int or isinstance(select, Integer): + crn = select + if crn > max_crn: + self._set_index_dictionary(max_crossing_number=crn) + gen_list += [k for k, v in idx_dict.items() + if v[0].crossing_number() == crn] + else: + raise TypeError('cannot select generators by %s' % select) + else: + gen_list = list(idx_dict.keys()) + + from sage.repl.user_globals import set_global, get_globals + for name in gen_list: + if name not in get_globals().keys(): + set_global(name, gens[name]) + if verbose: + print("Defining %s" % (name)) diff --git a/src/sage/knots/gauss_code.py b/src/sage/knots/gauss_code.py index 9d5a816d577..560b6831bfc 100644 --- a/src/sage/knots/gauss_code.py +++ b/src/sage/knots/gauss_code.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs """ Helper functions related to Gauss codes of knots diff --git a/src/sage/knots/knot.py b/src/sage/knots/knot.py index 9d6a73cbfbf..aaa01cdade9 100644 --- a/src/sage/knots/knot.py +++ b/src/sage/knots/knot.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs sage.groups r""" Knots @@ -46,7 +47,7 @@ class Knot(Link, Element, metaclass=InheritComparisonClasscallMetaclass): INPUT: - ``data`` -- see :class:`Link` for the allowable inputs - - ``check`` -- optional, default ``True``. If ``True``, make sure + - ``check`` -- boolean (default: ``True``); if ``True``, make sure that the data define a knot, not a link EXAMPLES: @@ -147,14 +148,6 @@ def _unicode_art_(self): """ Return unicode art for the knot. - INPUT: - - - a knot - - OUTPUT: - - - unicode art for the knot - EXAMPLES:: sage: W = Knots() @@ -207,14 +200,14 @@ def _unicode_art_(self): x, y, xx, yy = xx, yy, x, y if y < b: if xx < a: - M[a][b] = u"╯" + M[a][b] = "╯" else: - M[a][b] = u"╮" + M[a][b] = "╮" else: if xx < a: - M[a][b] = u"╰" + M[a][b] = "╰" else: - M[a][b] = u"╭" + M[a][b] = "╭" for ab, cd in graphe.edge_iterator(labels=False): a, b = ab @@ -222,21 +215,21 @@ def _unicode_art_(self): if a == c: b, d = sorted((b, d)) for i in range(b + 1, d): - M[a][i] = u"─" + M[a][i] = "─" else: a, c = sorted((a, c)) for i in range(a + 1, c): - M[i][b] = u"│" + M[i][b] = "│" if style == 0: - H = u"┿" - V = u"╂" + H = "┿" + V = "╂" elif style == 1: - H = u"━" - V = u"┃" + H = "━" + V = "┃" elif style == 2: - H = u"─" - V = u"│" + H = "─" + V = "│" for x, y in hori: M[x][y] = H @@ -271,10 +264,12 @@ def dt_code(self): sage: K = Knot([[1,5,2,4],[5,3,6,2],[3,1,4,6]]) sage: K.dt_code() [4, 6, 2] + sage: B = BraidGroup(4) sage: K = Knot(B([1, 2, 1, 2])) sage: K.dt_code() [4, -6, 8, -2] + sage: K = Knot([[[1, -2, 3, -4, 5, -1, 2, -3, 4, -5]], ....: [1, 1, 1, 1, 1]]) sage: K.dt_code() @@ -401,9 +396,7 @@ def connected_sum(self, other): - ``other`` -- a knot - OUTPUT: - - A knot equivalent to the connected sum of ``self`` and ``other``. + OUTPUT: a knot equivalent to the connected sum of ``self`` and ``other`` EXAMPLES:: @@ -542,11 +535,9 @@ def from_gauss_code(self, gauss): INPUT: - - a signed Gauss code - - OUTPUT: + - ``gauss`` -- a signed Gauss code - - a knot + OUTPUT: a knot EXAMPLES:: @@ -578,11 +569,10 @@ def from_dowker_code(self, code): INPUT: - a list of signed even numbers, the Dowker-Thistlethwaite code of a knot - - OUTPUT: + - ``code`` -- list of signed even numbers; the Dowker-Thistlethwaite + code of a knot - a knot + OUTPUT: a knot .. WARNING:: @@ -630,11 +620,9 @@ def from_table(self, n, k): INPUT: - ``n`` -- the crossing number - - ``k`` -- a positive integer + - ``k`` -- positive integer - OUTPUT: - - the knot `K_{n,k}` in the Rolfsen table + OUTPUT: the knot `K_{n,k}` in the Rolfsen table EXAMPLES:: @@ -678,9 +666,11 @@ def from_table(self, n, k): """ if n > 10: raise ValueError('more than 10 crossings, not in the knot table') - from sage.groups.braid import BraidGroup if (n, k) in small_knots_table: m, word = small_knots_table[(n, k)] + + from sage.groups.braid import BraidGroup + G = BraidGroup(m) return Knot(G(word)) else: diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 611d502a3d0..b0ff60eefa5 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs sage.groups r""" Access to the KnotInfo database @@ -156,7 +157,7 @@ True sage: K.is_amphicheiral() True - sage: K.jones_polynomial() + sage: K.jones_polynomial() # needs sage.symbolic t^2 - t - 1/t + 1/t^2 + 1 sage: K.kauffman_polynomial() a^2*z^2 + a*z^3 - a^2 - a*z + 2*z^2 + a^-1*z^3 - 1 - a^-1*z + a^-2*z^2 - a^-2 @@ -203,7 +204,7 @@ ....: [17,19,8,18], [9,10,11,14], [10,12,13,11], ....: [12,19,15,13], [20,16,14,15], [16,20,17,2]]) sage: L.get_knotinfo() - (, ) + KnotInfo['K0_1'] REFERENCES: @@ -251,8 +252,8 @@ def eval_knotinfo(string, locals={}, to_tuple=True): INPUT: - - ``string`` -- string that gives a value of some database entry - - ``locals`` -- dictionary of locals passed to ``sage_eval`` + - ``string`` -- string that gives a value of some database entry + - ``locals`` -- dictionary of locals passed to ``sage_eval`` EXAMPLES:: @@ -280,6 +281,7 @@ def eval_knotinfo(string, locals={}, to_tuple=True): new_string = new_string.replace(';', ',') return sage_eval(new_string, locals=locals) + def knotinfo_int(string): r""" Preparse a string from the KnotInfo database representing an integer. @@ -305,13 +307,14 @@ def knotinfo_int(string): else: return int(string) + def knotinfo_bool(string): r""" Preparse a string from the KnotInfo database representing a boolean. INPUT: - - ``string`` -- string that gives a value of some database entry + - ``string`` -- string that gives a value of some database entry EXAMPLES:: @@ -349,9 +352,9 @@ class of an oriented pair, `K = (S_3, S_1)`, with `S_i` """ itself = 's' reverse = 'r' - concordance_inverse = 'mr' + concordance_inverse = 'c' mirror_image = 'm' - mixed = 'x' # to be used in connection with KnotInfoSeries + mixed = 'x' # to be used in connection with KnotInfoSeries unknown = '?' def __gt__(self, other): @@ -365,14 +368,103 @@ def __gt__(self, other): [, , , - , , + , ] """ # We use the reversal of the alphabetical order of the values so that # `itself` occurs before the mirrored cases return self.value < other.value + def rev(self): + r""" + Return the reverse of ``self``. + + EXAMPLES:: + + sage: from sage.knots.knotinfo import SymmetryMutant + sage: all( sym.rev().rev() == sym for sym in SymmetryMutant) + True + """ + if self is SymmetryMutant.itself: + return SymmetryMutant.reverse + elif self is SymmetryMutant.reverse: + return SymmetryMutant.itself + elif self is SymmetryMutant.mirror_image: + return SymmetryMutant.concordance_inverse + elif self is SymmetryMutant.concordance_inverse: + return SymmetryMutant.mirror_image + return self + + def mir(self): + r""" + Return the mirror image of ``self``. + + EXAMPLES:: + + sage: from sage.knots.knotinfo import SymmetryMutant + sage: all( sym.mir().mir() == sym for sym in SymmetryMutant) + True + """ + if self is SymmetryMutant.itself: + return SymmetryMutant.mirror_image + elif self is SymmetryMutant.reverse: + return SymmetryMutant.concordance_inverse + elif self is SymmetryMutant.mirror_image: + return SymmetryMutant.itself + elif self is SymmetryMutant.concordance_inverse: + return SymmetryMutant.reverse + return self + + def matches(self, link): + r""" + Return the list of other symmetry mutants that give isotopic links + with respect to ``link`` and ``self``. For ``self`` is + ``SymmetryMutant.unknown`` a boolean is returned which is ``True`` + if the chirality of ``link`` is unknown. + + EXAMPLES:: + + sage: from sage.knots.knotinfo import SymmetryMutant + sage: SymmetryMutant.itself.matches(KnotInfo.K6_1) + [] + sage: SymmetryMutant.mirror_image.matches(KnotInfo.K6_1) + [] + """ + rev = link.is_reversible() + achp = link.is_amphicheiral(positive=True) + ach = link.is_amphicheiral() + if self is SymmetryMutant.unknown: + if rev is None or ach is None or achp is None: + return True + else: + return False + res = [] + if rev: + res.append(self.rev()) + if achp: + res.append(self.mir()) + if ach: + res.append(self.rev().mir()) + return res + + def is_minimal(self, link): + r""" + Return whether ``self`` is minimal among its matching mutants. + + EXAMPLES:: + + sage: from sage.knots.knotinfo import SymmetryMutant + sage: SymmetryMutant.itself.is_minimal(KnotInfo.K6_1) + True + sage: SymmetryMutant.concordance_inverse.is_minimal(KnotInfo.K6_1) + False + """ + if self in [SymmetryMutant.unknown, SymmetryMutant.mixed]: + return False + matches = self.matches(link) + return all(self < other for other in matches) + # --------------------------------------------------------------------------------- # KnotInfoBase @@ -414,7 +506,7 @@ def __gt__(self, other): True """ if self.__class__ is other.__class__: - tups = (not self.is_knot(), self.crossing_number(), self.value) + tups = (not self.is_knot(), self.crossing_number(), self.value) tupo = (not other.is_knot(), other.crossing_number(), other.value) return tups > tupo return NotImplemented @@ -530,7 +622,7 @@ def _homfly_pol_ring(self, var1, var2): sage: L._homfly_pol_ring('u', 'v') Multivariate Laurent Polynomial Ring in u, v over Integer Ring """ - K3_1 = Knots().from_table(3,1) + K3_1 = Knots().from_table(3, 1) return K3_1.homfly_polynomial(var1=var1, var2=var2).parent() @cached_method @@ -542,7 +634,7 @@ def pd_notation(self, original=False): INPUT: - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string OUTPUT: @@ -584,7 +676,7 @@ def dt_notation(self, original=False): INPUT: - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string OUTPUT: @@ -627,13 +719,9 @@ def gauss_notation(self, original=False): INPUT: - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string - OUTPUT: - - Python list of - EXAMPLES:: sage: L = KnotInfo.L4a1_0 @@ -661,7 +749,7 @@ def braid_notation(self, original=False): INPUT: - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string OUTPUT: @@ -702,7 +790,7 @@ def braid_notation(self, original=False): return (1, ) braid_notation = eval_knotinfo(braid_notation) - if type(braid_notation) is list: + if type(braid_notation) in (list, tuple): # in some cases there are a pair of braid representations # in the database. If this is the case we select the # corresponding to the braid index. @@ -741,7 +829,6 @@ def braid_index(self): Traceback (most recent call last): ... NotImplementedError: this integer is not provided by the database - """ if self.is_knot(): return knotinfo_int(self[self.items.braid_index]) @@ -871,7 +958,7 @@ def three_genus(self): EXAMPLES:: - sage: KnotInfo.K5_2.three_genus() # optional - databsase_knotinfo + sage: KnotInfo.K5_2.three_genus() # optional - database_knotinfo 1 Note that this differs from the corresponding result in Sage @@ -899,8 +986,8 @@ def signature(self): EXAMPLES:: - sage: KnotInfo.K5_2.signature() # optional - databsase_knotinfo - 1 + sage: KnotInfo.K5_2.signature() # optional - database_knotinfo + -2 """ return knotinfo_int(self[self.items.signature]) @@ -970,7 +1057,7 @@ class of an oriented pair, `K = (S_3, S_1)`, with `S_i` if not self.is_knot(): raise NotImplementedError('this is only available for knots') - symmetry_type = self[self.items.symmetry_type].strip() # for example K10_88 is a case with trailing whitespaces + symmetry_type = self[self.items.symmetry_type].strip() # for example K10_88 is a case with trailing whitespaces if not symmetry_type and self.crossing_number() == 0: return 'fully amphicheiral' return symmetry_type @@ -1015,13 +1102,11 @@ def is_amphicheiral(self, positive=False): INPUT: - - ``positive`` -- boolean (default: ``False``) whether to check + - ``positive`` -- boolean (default: ``False``); whether to check if ``self`` is positive or negative amphicheiral (see documentation of :meth:`symmetry_type`) - OUTPUT: - - Boolean or ``None`` if this cannot be determined. + OUTPUT: boolean or ``None`` if this cannot be determined ``True`` if ``self`` is fully or negative amphicheiral per default. If ``positive`` is set to ``True`` than fully and positive amphicheiral @@ -1098,6 +1183,23 @@ def is_amphicheiral(self, positive=False): return None + @cached_method + def is_hyperbolic(self): + r""" + Return whether ``self`` is hyperbolic. + + EXAMPLES:: + + sage: KnotInfo.K3_1.is_hyperbolic() + False + sage: KnotInfo.K5_2.is_hyperbolic() + True + """ + geometric_type = self[self.items.geometric_type] + if geometric_type == 'hyperbolic': + return True + return False + @cached_method def is_alternating(self): r""" @@ -1224,6 +1326,38 @@ def is_oriented(self): """ return not knotinfo_bool(self[self.items.unoriented]) + @cached_method + def cosmetic_crossing_conjecture_verified(self): + r""" + Return whether the Cosmetic Crossing Conjecture has been verified + for ``self``. + + From the KnotInfo `description page `__: + + A crossing change in a diagram of a knot ``K`` is called cosmetic if + the resulting diagram also represents ``K``. The cosmetic crossing + conjecture posits that for any knot ``K``, the only cosmetic crossing + changes are nugatory, i.e. there exists an embedded 2-sphere in + ``S3`` which intersects K only at the two points of the relevant + crossing. Conversely, it is not hard to see that any nugatory + crossing change is cosmetic. + + EXAMPLES:: + + sage: knots = [K for K in KnotInfo if K.is_knot() and K.crossing_number() < 10] + sage: all(K.cosmetic_crossing_conjecture_verified() for K in knots) + True + """ + cosmetic_crossing = self[self.items.cosmetic_crossing] + if self.crossing_number() == 0: + return True + if not cosmetic_crossing or cosmetic_crossing == 'Unknown': + return False + verified = not knotinfo_bool(cosmetic_crossing) + if not knotinfo_bool(cosmetic_crossing): + return True + raise AssertionError(f'{self} is a counterexample to the cosmetic crossing conjecture') + @cached_method def homfly_polynomial(self, var1='v', var2='z', original=False): r""" @@ -1243,9 +1377,9 @@ def homfly_polynomial(self, var1='v', var2='z', original=False): INPUT: - - ``var1`` -- string (default ``v``) for the name of the first variable - - ``var2`` -- string (default ``z``) for the name of the second variable - - ``original`` -- boolean (default ``False``) if set to + - ``var1`` -- string (default: ``'v'``); for the name of the first variable + - ``var2`` -- string (default: ``'z'``); for the name of the second variable + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string OUTPUT: @@ -1322,7 +1456,7 @@ def homfly_polynomial(self, var1='v', var2='z', original=False): homfly_polynomial = homfly_polynomial.strip('}') L, M = R.gens() - lc = {'v': L, 'z':M} + lc = {'v': L, 'z': M} return eval_knotinfo(homfly_polynomial, locals=lc) @cached_method @@ -1349,7 +1483,7 @@ def kauffman_polynomial(self, var1='a', var2='z', original=False): - ``var1`` -- (default: ``'a'``) the first variable - ``var2`` -- (default: ``'z'``) the second variable - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string OUTPUT: @@ -1361,14 +1495,16 @@ def kauffman_polynomial(self, var1='a', var2='z', original=False): EXAMPLES:: sage: L = KnotInfo.L2a1_1 + sage: K = KnotInfo.K4_1 + sage: L.kauffman_polynomial() a^-1*z - a^-1*z^-1 + a^-2 + a^-3*z - a^-3*z^-1 - sage: K = KnotInfo.K4_1 sage: K.kauffman_polynomial() a^2*z^2 + a*z^3 - a^2 - a*z + 2*z^2 + a^-1*z^3 - 1 - a^-1*z + a^-2*z^2 - a^-2 Comparison with Jones polynomial:: + sage: # needs sage.symbolic sage: k = _ sage: a, z = k.variables() sage: j = K.jones_polynomial(skein_normalization=True) @@ -1404,7 +1540,7 @@ def kauffman_polynomial(self, var1='a', var2='z', original=False): return R.one() a, z = R.gens() - lc = {'a': a, 'z': z} + lc = {'a': a, 'z': z} return R(eval_knotinfo(kauffman_polynomial, locals=lc)) @cached_method @@ -1429,17 +1565,17 @@ def jones_polynomial(self, variab=None, skein_normalization=False, puiseux=False INPUT: - - ``variab`` -- variable (default: ``None``) used according to :meth:`Link.jones_polynomial` - - ``skein_normalization`` -- boolean (default: ``False``) used according - to :meth:`Link.jones_polynomial` - - ``puiseux`` -- boolean (default ``True``) only used in case + - ``variab`` -- variable (default: ``None``); used according to + :meth:`Link.jones_polynomial` + - ``skein_normalization`` -- boolean (default: ``False``); used + according to :meth:`Link.jones_polynomial` + - ``puiseux`` -- boolean (default: ``True``); only used in case ``skein_normalization=False``. If set to ``True`` instead of an element of the symbolic ring an instance of :class:`~sage.rings.puiseux_series_ring_element.PuiseuxSeries` is returned - - ``original`` -- boolean (default ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string - - ``use_sqrt`` -- boolean (default ``False``) see the note below - + - ``use_sqrt`` -- boolean (default: ``False``); see the note below OUTPUT: @@ -1467,7 +1603,7 @@ def jones_polynomial(self, variab=None, skein_normalization=False, puiseux=False EXAMPLES:: sage: K = KnotInfo.K4_1 - sage: Kj = K.jones_polynomial(); Kj + sage: Kj = K.jones_polynomial(); Kj # needs sage.symbolic t^2 - t - 1/t + 1/t^2 + 1 sage: Kjs = K.jones_polynomial(skein_normalization=True); Kjs A^-8 - A^-4 + 1 - A^4 + A^8 @@ -1477,17 +1613,17 @@ def jones_polynomial(self, variab=None, skein_normalization=False, puiseux=False for proper links:: sage: L = KnotInfo.L2a1_1 - sage: Lj = L.jones_polynomial(); Lj + sage: Lj = L.jones_polynomial(); Lj # needs sage.symbolic -x^5 - x - sage: Ljt = L.jones_polynomial(use_sqrt=True); Ljt + sage: Ljt = L.jones_polynomial(use_sqrt=True); Ljt # needs sage.symbolic -t^(5/2) - sqrt(t) sage: Ljp = L.jones_polynomial(puiseux=True); Ljp -t^(1/2) - t^(5/2) sage: Ljs = L.jones_polynomial(skein_normalization=True); Ljs -A^2 - A^10 - sage: Lj.parent() + sage: Lj.parent() # needs sage.symbolic Symbolic Ring - sage: Ljt.parent() + sage: Ljt.parent() # needs sage.symbolic Symbolic Ring sage: Ljp.parent() Puiseux Series Ring in t over Integer Ring @@ -1497,17 +1633,17 @@ def jones_polynomial(self, variab=None, skein_normalization=False, puiseux=False Comparison with Sage's results:: sage: k = K.link() - sage: kj = k.jones_polynomial() - sage: bool(Kj == kj) + sage: kj = k.jones_polynomial() # needs sage.symbolic + sage: bool(Kj == kj) # needs sage.symbolic True sage: kjs = k.jones_polynomial(skein_normalization=True) sage: Kjs == kjs True sage: l = L.link() - sage: lj = l.jones_polynomial() - sage: bool(Lj == lj) + sage: lj = l.jones_polynomial() # needs sage.symbolic + sage: bool(Lj == lj) # needs sage.symbolic False - sage: bool(Ljt == lj) # see note above + sage: bool(Ljt == lj) # see note above # needs sage.symbolic True sage: ljs = l.jones_polynomial(skein_normalization=True) sage: Ljs == ljs @@ -1517,6 +1653,8 @@ def jones_polynomial(self, variab=None, skein_normalization=False, puiseux=False of the positive crossings of the right-handed trefoil):: sage: K3_1 = KnotInfo.K3_1 + + sage: # needs sage.symbolic sage: K3_1j = K3_1.jones_polynomial() sage: L2a1_1j = Ljt # see note above sage: R = L2a1_1j.parent() @@ -1575,24 +1713,24 @@ def jones_polynomial(self, variab=None, skein_normalization=False, puiseux=False R = SR if not jones_polynomial and self.crossing_number() == 0: - return R(1) + return R.one() t = R(variab) if skein_normalization: if self.is_knot(): - lc = {'t': t**4} + lc = {'t': t**4} else: - lc = {'x': t**2} + lc = {'x': t**2} else: if self.is_knot(): - lc = {'t': t} + lc = {'t': t} elif puiseux: - lc = {'x': t**(1/2)} + lc = {'x': t**(1/2)} elif use_sqrt: from sage.misc.functional import sqrt - lc = {'x': sqrt(t)} + lc = {'x': sqrt(t)} else: - lc = {'x': t} + lc = {'x': t} return R(eval_knotinfo(jones_polynomial, locals=lc)) @@ -1617,9 +1755,9 @@ def alexander_polynomial(self, var='t', original=False, laurent_poly=False): INPUT: - ``var`` -- (default: ``'t'``) the variable - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string - - ``laurent_poly`` -- boolean (default ``False``) see the note below + - ``laurent_poly`` -- boolean (default: ``False``); see the note below OUTPUT: @@ -1678,7 +1816,7 @@ def alexander_polynomial(self, var='t', original=False, laurent_poly=False): return R.one() t, = R.gens() - lc = {'t': t} + lc = {'t': t} ap = R(eval_knotinfo(alexander_polynomial, locals=lc)) if not laurent_poly or ap.is_constant(): return ap @@ -1707,7 +1845,7 @@ def conway_polynomial(self, var='t', original=False): INPUT: - ``var`` -- (default: ``'t'``) the variable - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string OUTPUT: @@ -1725,7 +1863,7 @@ def conway_polynomial(self, var='t', original=False): sage: Lc = L.conway_polynomial(); Lc t^3 - Comparision to Sage's results:: + Comparison to Sage's results:: sage: Kc == K.link().conway_polynomial() True @@ -1734,7 +1872,7 @@ def conway_polynomial(self, var='t', original=False): Launch the KnotInfo description web-page:: - sage: K.items.conway_polynomial.description_webpage() # not tested + sage: K.items.conway_polynomial.description_webpage() # not tested True """ conway_polynomial = self[self.items.conway_polynomial] @@ -1749,7 +1887,7 @@ def conway_polynomial(self, var='t', original=False): return R.one() t, = R.gens() - lc = {'z': t} + lc = {'z': t} return R(eval_knotinfo(conway_polynomial, locals=lc)) @cached_method @@ -1831,7 +1969,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, False - Comparision to Sage's results:: + Comparison to Sage's results:: sage: Kk == K.link().khovanov_polynomial() True @@ -1963,11 +2101,11 @@ def link(self, use_item=db.columns().pd_notation, snappy=False): - ``self.items.dt_notation`` (only for knots and ``snappy=False``) - ``self.items.gauss_notation`` (only for knots and ``snappy=False``) - - ``snappy`` boolean (default ``False``) if set to ``True`` + - ``snappy`` -- boolean (default: ``False``); if set to ``True`` the target of the conversion is the ``pip`` installable package `SnapPy `__ (explicitely, ``spherogram.links.invariants.Link``). - If SnapPy is not installed an :class:`ImportError` is raised. To + If SnapPy is not installed an :exc:`ImportError` is raised. To install SnapPy use ``sage -pip install snappy``. .. NOTE:: @@ -2096,9 +2234,7 @@ def is_unique(self): r""" Return whether there is no other isotopic link in the database or not. - OUTPUT: - - Boolean or ``None`` if this cannot be determined. + OUTPUT: boolean or ``None`` if this cannot be determined EXAMPLES:: @@ -2150,7 +2286,7 @@ def is_recoverable(self, unique=True): INPUT: - - ``unique`` -- boolean (default: ``True``) if set to ``False`` + - ``unique`` -- boolean (default: ``True``); if set to ``False`` it is only checked if ``self`` is among the recovered items EXAMPLES:: @@ -2167,8 +2303,13 @@ def is_recoverable(self, unique=True): False sage: L5a1_0.is_recoverable(unique=False) True + + TESTS: + + sage: KnotInfo.K12a_165.is_recoverable(unique=False) # optional - database_knotinfo, long time + True """ - def recover(mirror, braid): + def recover(sym_mut, braid): r""" Check if ``self`` can be recovered form its associated Sage link. @@ -2177,37 +2318,42 @@ def recover(mirror, braid): l = self.link(self.items.braid_notation) else: l = self.link() - if mirror: - if self.is_amphicheiral(): - # no need to test again - return True + if sym_mut is SymmetryMutant.mirror_image: l = l.mirror_image() + elif sym_mut is SymmetryMutant.reverse: + l = l.reverse() + elif sym_mut is SymmetryMutant.concordance_inverse: + l = l.mirror_image().reservse() - def check_result(L, m): + def check_result(res): r""" Check a single result from ``get_knotinfo``. """ + if type(res) is tuple: + L, s = res + else: + L, s = res.to_knotinfo()[0] + if not isinstance(L, KnotInfoBase): + return False if L != self: return False - if mirror: - return m is SymmetryMutant.mirror_image - else: - return m is SymmetryMutant.itself + return s == sym_mut try: - L, m = l.get_knotinfo() - if isinstance(L, KnotInfoBase): - return check_result(L,m) - elif unique: - return False + res = l.get_knotinfo(unique=unique) except NotImplementedError: - if unique: - return False - Llist = l.get_knotinfo(unique=False) - return any(check_result(L, m) for (L, m) in Llist) + return False + if unique: + return check_result(res) + else: + return any(check_result(r) for r in res) from sage.misc.misc import some_tuples - return all(recover(mirror, braid) for mirror, braid in some_tuples([True, False], 2, 4)) + if SymmetryMutant.unknown.matches(self): + sym_muts = [SymmetryMutant.unknown] + else: + sym_muts = [s for s in SymmetryMutant if s.is_minimal(self)] + return all(recover(sym, braid) for sym, braid in some_tuples(sym_muts, 2, 8)) def inject(self, verbose=True): """ @@ -2216,7 +2362,7 @@ def inject(self, verbose=True): INPUT: - - ``verbose`` -- boolean (default: ``True``) to suppress + - ``verbose`` -- boolean (default: ``True``); whether to suppress the message printed on the invocation EXAMPLES:: @@ -2239,11 +2385,11 @@ def series(self, oriented=False): INPUT: - - ``oriented`` -- boolean (default: ``False``) it only affects proper links. - By default the items of the series will be again series of links - collecting all orientation mutants of an unoriented name. To obtain - the series of the individual links this keyword has to be set to - ``True``. + - ``oriented`` -- boolean (default: ``False``); it only affects proper + links. By default the items of the series will be again series of + links collecting all orientation mutants of an unoriented name. To + obtain the series of the individual links this keyword has to be set + to ``True``. EXAMPLES:: @@ -2273,11 +2419,11 @@ def diagram(self, single=False, new=0, autoraise=True): INPUT: - - ``single`` -- boolean (default ``False``) if set to ``True`` only one - diagram is shown. - - ``new`` -- ``int`` according to :func:`open` of :mod:`webbrowser` + - ``single`` -- boolean (default: ``False``); if set to ``True`` only one + diagram is shown + - ``new`` -- integer according to :func:`open` of :mod:`webbrowser` (``0`` default, ``1`` new window, ``2`` new tab) - - ``autoraise`` -- boolean (default ``True``) + - ``autoraise`` -- boolean (default: ``True``) EXAMPLES:: @@ -2304,9 +2450,9 @@ def knot_atlas_webpage(self, new=0, autoraise=True): INPUT: - - ``new`` -- ``int`` according to :func:`open` of :mod:`webbrowser` + - ``new`` -- integer according to :func:`open` of :mod:`webbrowser` (``0`` default, ``1`` new window, ``2`` new tab) - - ``autoraise`` -- boolean (default ``True``) + - ``autoraise`` -- boolean (default: ``True``) EXAMPLES:: @@ -2323,9 +2469,9 @@ def knotilus_webpage(self, new=0, autoraise=True): INPUT: - - ``new`` -- ``int`` according to :func:`open` of :mod:`webbrowser` + - ``new`` -- integer according to :func:`open` of :mod:`webbrowser` (``0`` default, ``1`` new window, ``2`` new tab) - - ``autoraise`` -- boolean (default ``True``) + - ``autoraise`` -- boolean (default: ``True``) EXAMPLES:: @@ -2347,11 +2493,11 @@ class KnotInfoSeries(UniqueRepresentation, SageObject): INPUT: - - ``crossing_number`` -- integer giving the crossing numer of this series + - ``crossing_number`` -- integer giving the crossing number of this series of links - - ``is_knot`` -- boolean whether this series is a series of knots + - ``is_knot`` -- boolean; whether this series is a series of knots or proper links - - ``is_alternating`` -- boolean whether this series is restriced to + - ``is_alternating`` -- boolean; whether this series is restricted to alternating links or not This is not relevant for knots with less than 11 crossings - ``name_unoriented`` -- string restricting the series to all links with @@ -2402,24 +2548,24 @@ def list(self, oriented=False, comp=None, det=None, homfly=None): INPUT: - - ``oriented`` -- boolean (default: ``False``) it only affects + - ``oriented`` -- boolean (default: ``False``); it only affects series of proper links. By default the list items of a series of proper links are again series of links collecting all orientation types of an unoriented name. To obtain the list of the individual links this - keyword has to be set to ``True`` + keyword has to be set to ``True``. - - ``comp`` (default: ``None``) if given an integer for this + - ``comp`` -- (default: ``None``) if given an integer for this keyword the list is restriced to links having the according number - of components. This keyword implies ``oriented=True`` + of components. This keyword implies ``oriented=True``. - - ``det`` (default: ``None``) if given an integer for this + - ``det`` -- (default: ``None``) if given an integer for this keyword the list is restriced to links having the according value - for its determinant. This keyword implies ``oriented=True`` + for its determinant. This keyword implies ``oriented=True``. - - ``homfly`` (default: ``None``) if given a HOMFLY-PT polynomial + - ``homfly`` -- (default: ``None``) if given a HOMFLY-PT polynomial having ``normalization='vz'`` for this keyword the list is restriced to links having the according value for its HOMFLY-PT polynomial. This - keyword implies ``oriented=True`` + keyword implies ``oriented=True``. EXAMPLES:: @@ -2494,16 +2640,16 @@ def lower_list(self, oriented=False, comp=None, det=None, homfly=None): INPUT: - - ``oriented`` -- boolean (default: ``False``) see the + - ``oriented`` -- boolean (default: ``False``); see the description for :meth:`list` - - ``comp`` (default: ``None``) see the description for + - ``comp`` -- (default: ``None``) see the description for :meth:`list` - - ``det`` (default: ``None``) see the description for + - ``det`` -- (default: ``None``) see the description for :meth:`list` - - ``homfly`` (default: ``None``) see the description for + - ``homfly`` -- (default: ``None``) see the description for :meth:`list` EXAMPLES:: @@ -2526,7 +2672,7 @@ def lower_list(self, oriented=False, comp=None, det=None, homfly=None): l = [] cr = self._crossing_number if cr > 0: - LS = type(self)(cr - 1, self._is_knot, self._is_alternating, self._name_unoriented ) + LS = type(self)(cr - 1, self._is_knot, self._is_alternating, self._name_unoriented) l = LS.lower_list(oriented=oriented, comp=comp, det=det, homfly=homfly) return l + self.list(oriented=oriented, comp=comp, det=det, homfly=homfly) @@ -2561,12 +2707,12 @@ def __getitem__(self, item): [, , ] """ from sage.rings.integer import Integer - if not type(item) in (int, Integer): + if type(item) not in (int, Integer): raise ValueError('item must be an integer') l = self.list() max_item = len(l) if item < 0 or item > max_item: - raise ValueError('item must be non negative and smaller than %s' % (max_item)) + raise ValueError('item must be nonnegative and smaller than %s' % (max_item)) return l[item] @@ -2604,7 +2750,7 @@ def __call__(self, item): return self[item] from sage.rings.integer import Integer - if not type(item) in (int, Integer): + if type(item) not in (int, Integer): raise ValueError('item must be an integer') l = self.list() max_item = len(l) + 1 @@ -2653,10 +2799,10 @@ def is_recoverable(self, unique=True, max_samples=8): INPUT: - - ``unique`` -- boolean (default: ``True``) see + - ``unique`` -- boolean (default: ``True``); see :meth:`KnotInfoBase.is_recoverable` - - ``max_samples`` -- non negative integer or ``infinity`` (optional, - default ``8``) limits the number of items to check (random sample). + - ``max_samples`` -- nonnegative integer or ``infinity`` + (default: `8`); limits the number of items to check (random sample). If set to ``infinity`` then no limit is set. EXAMPLES:: @@ -2689,20 +2835,23 @@ def _test_recover(self, **options): EXAMPLES:: - sage: TestSuite(KnotInfo.L5a1_0.series()).run(verbose=True) # indirec doctest + sage: TestSuite(KnotInfo.L5a1_0.series()).run(verbose=True) # indirect doctest running ._test_category() . . . pass running ._test_new() . . . pass running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass running ._test_recover() . . . pass - sage: TestSuite(KnotInfo.K6_1.series()).run(max_samples=infinity) # indirec doctest + sage: TestSuite(KnotInfo.K6_1.series()).run(max_samples=infinity) # indirect doctest """ tester = options['tester'] max_samples = tester._max_samples - if max_samples: - tester.assertTrue(self.is_recoverable(unique=False, max_samples=max_samples)) - else: - tester.assertTrue(self.is_recoverable(unique=False)) + try: + if max_samples: + tester.assertTrue(self.is_recoverable(unique=False, max_samples=max_samples)) + else: + tester.assertTrue(self.is_recoverable(unique=False)) + except ImportError: + pass def inject(self, verbose=True): r""" @@ -2711,12 +2860,11 @@ def inject(self, verbose=True): INPUT: - - ``verbose`` -- boolean (default: ``True``) to suppress + - ``verbose`` -- boolean (default: ``True``); to suppress the message printed on the invocation EXAMPLES:: - sage: from sage.knots.knotinfo import KnotInfoSeries sage: KnotInfoSeries(6, True, True).inject() Defining K6 sage: K6(2) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index d95b4271a35..e6d23ac01b6 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs sage.groups r""" Links @@ -55,22 +56,26 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.matrix.constructor import matrix +from copy import deepcopy, copy +from itertools import combinations + from sage.rings.integer_ring import ZZ from sage.graphs.digraph import DiGraph from sage.graphs.graph import Graph from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer -from sage.numerical.mip import MixedIntegerLinearProgram -from sage.functions.generalized import sign -from sage.homology.chain_complex import ChainComplex from sage.misc.flatten import flatten from sage.misc.cachefunc import cached_method -from copy import deepcopy, copy -from itertools import combinations from sage.structure.sage_object import SageObject +lazy_import("sage.functions.generalized", "sign") +lazy_import('sage.groups.braid', ['Braid', 'BraidGroup']) +lazy_import('sage.homology.chain_complex', 'ChainComplex') +lazy_import('sage.matrix.constructor', 'matrix') +lazy_import('sage.numerical.mip', 'MixedIntegerLinearProgram') +lazy_import("sage.symbolic.ring", "SR") + class Link(SageObject): r""" @@ -88,11 +93,9 @@ class Link(SageObject): - The closure of a braid is a link:: sage: B = BraidGroup(8) - sage: L = Link(B([-1, -1, -1, -2, 1, -2, 3, -2, 3])) - sage: L + sage: L = Link(B([-1, -1, -1, -2, 1, -2, 3, -2, 3])); L Link with 1 component represented by 9 crossings - sage: L = Link(B([1, 2, 1, -2, -1])) - sage: L + sage: L = Link(B([1, 2, 1, -2, -1])); L Link with 2 components represented by 5 crossings .. NOTE:: @@ -164,8 +167,7 @@ class Link(SageObject): We can construct links from the braid group:: sage: B = BraidGroup(4) - sage: L = Link(B([-1, -1, -1, -2, 1, -2, 3, -2])) - sage: L + sage: L = Link(B([-1, -1, -1, -2, 1, -2, 3, -2])); L Link with 2 components represented by 8 crossings .. PLOT:: @@ -177,8 +179,7 @@ class Link(SageObject): :: - sage: L = Link(B([1, 2, 1, 3])) - sage: L + sage: L = Link(B([1, 2, 1, 3])); L Link with 2 components represented by 4 crossings .. PLOT:: @@ -291,10 +292,10 @@ def __init__(self, data): sage: TestSuite(L).run() sage: L = Link(B([1, 2, 1])) sage: TestSuite(L).run() + sage: L = Link(B.one()) + sage: L = Link([[1, 1, 2, 2]]) sage: TestSuite(L).run() - - sage: L = Link(B.one()) sage: L = Link([]) sage: L = Link([[], []]) @@ -329,8 +330,7 @@ def __init__(self, data): Verify that :issue:`29692` is fixed:: sage: B = BraidGroup(5) - sage: L = Link(B([3,4,3,-4])) - sage: L + sage: L = Link(B([3,4,3,-4])); L Link with 1 component represented by 4 crossings sage: L.braid() s0*s1*s0*s1^-1 @@ -367,7 +367,6 @@ def __init__(self, data): self._braid = None else: - from sage.groups.braid import Braid, BraidGroup if isinstance(data, Braid): # Remove all unused strands support = sorted(set().union(*((abs(x), abs(x) + 1) for x in data.Tietze()))) @@ -405,9 +404,7 @@ def arcs(self, presentation='pd'): following negative one; of there exist a closed arc, it is returned as a list of positive numbers only - OUTPUT: - - A list of lists representing the arcs based upon ``presentation``. + OUTPUT: list of lists representing the arcs based upon ``presentation`` EXAMPLES:: @@ -477,9 +474,7 @@ def fundamental_group(self, presentation='wirtinger'): * ``'braid'`` -- the presentation is given by the braid action on the free group (see chapter 2 of [Bir1975]_) - OUTPUT: - - - a finitely presented group + OUTPUT: a finitely presented group EXAMPLES:: @@ -493,20 +488,21 @@ def fundamental_group(self, presentation='wirtinger'): of the figure eight knot correspond to isomorphic groups:: sage: K8 = Knot([[[1, -2, 4, -3, 2, -1, 3, -4]], [1, 1, -1, -1]]) - sage: GA = K8.fundamental_group() - sage: GA + sage: GA = K8.fundamental_group(); GA Finitely presented group < x0, x1, x2, x3 | x2*x0*x3^-1*x0^-1, x0*x2*x1^-1*x2^-1, x1*x3^-1*x2^-1*x3, x3*x1^-1*x0^-1*x1 > - sage: GB = K8.fundamental_group(presentation='braid') - sage: GB - Finitely presented group < x0, x1, x2 | x1*x2^-1*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0^-1, x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-2, x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1 > + sage: GB = K8.fundamental_group(presentation='braid'); GB + Finitely presented group + < x0, x1, x2 | x1*x2^-1*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0^-1, + x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-2, + x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1 > sage: GA.simplified() - Finitely presented group < x0, x1 | - x1^-1*x0*x1*x0^-1*x1*x0*x1^-1*x0^-1*x1*x0^-1 > + Finitely presented group + < x0, x1 | x1^-1*x0*x1*x0^-1*x1*x0*x1^-1*x0^-1*x1*x0^-1 > sage: GB.simplified() - Finitely presented group < x0, x2 | - x2^-1*x0*x2^-1*x0^-1*x2*x0*x2^-1*x0*x2*x0^-1 > + Finitely presented group + < x0, x2 | x2^-1*x0*x2^-1*x0^-1*x2*x0*x2^-1*x0*x2*x0^-1 > """ from sage.groups.free_group import FreeGroup if presentation == 'braid': @@ -539,9 +535,9 @@ def _repr_(self): EXAMPLES:: sage: B = BraidGroup(8) - sage: L = Link(B([1, 2, 1, 2])) - sage: L + sage: L = Link(B([1, 2, 1, 2])); L Link with 1 component represented by 4 crossings + sage: L = Link([[[-1, 2], [-3, 4], [1, 3, -4, -2]], [-1, -1, 1, 1]]) sage: L Link with 3 components represented by 4 crossings @@ -614,7 +610,7 @@ def braid(self, remove_loops=False): INPUT: - - ``remove_loops`` -- boolean (default: ``False``). If set to ``True`` + - ``remove_loops`` -- boolean (default: ``False``); if set to ``True`` loops will be removed first. This can reduce the number of strands needed for an ambient isotopic braid closure. However, this can lead to a loss of the regular isotopy. @@ -1168,13 +1164,13 @@ def _khovanov_homology_cached(self, height, ring=ZZ): EXAMPLES:: sage: K = Link([[[1, -2, 3, -1, 2, -3]],[-1, -1, -1]]) - sage: K._khovanov_homology_cached(-5) + sage: K._khovanov_homology_cached(-5) # needs sage.modules ((-3, 0), (-2, Z), (-1, 0), (0, 0)) The figure eight knot:: sage: L = Link([[1, 6, 2, 7], [5, 2, 6, 3], [3, 1, 4, 8], [7, 5, 8, 4]]) - sage: L._khovanov_homology_cached(-1) + sage: L._khovanov_homology_cached(-1) # needs sage.modules ((-2, 0), (-1, Z), (0, Z), (1, 0), (2, 0)) """ crossings = self.pd_code() @@ -1205,7 +1201,7 @@ def _khovanov_homology_cached(self, height, ring=ZZ): else: m = matrix(ring, len(bases[(i,j)]), 0) complexes[i] = m.transpose() - if not (i-1, j) in bases: + if (i-1, j) not in bases: complexes[i-1] = matrix(ring, len(bases[(i,j)]), 0) homologies = ChainComplex(complexes).homology() return tuple(sorted(homologies.items())) @@ -1233,7 +1229,7 @@ def khovanov_homology(self, ring=ZZ, height=None, degree=None): EXAMPLES:: sage: K = Link([[[1, -2, 3, -1, 2, -3]],[-1, -1, -1]]) - sage: K.khovanov_homology() + sage: K.khovanov_homology() # needs sage.modules {-9: {-3: Z}, -7: {-3: 0, -2: C2}, -5: {-3: 0, -2: Z, -1: 0, 0: 0}, @@ -1243,21 +1239,23 @@ def khovanov_homology(self, ring=ZZ, height=None, degree=None): The figure eight knot:: sage: L = Link([[1, 6, 2, 7], [5, 2, 6, 3], [3, 1, 4, 8], [7, 5, 8, 4]]) - sage: L.khovanov_homology(height=-1) + sage: L.khovanov_homology(height=-1) # needs sage.modules {-1: {-2: 0, -1: Z, 0: Z, 1: 0, 2: 0}} The Hopf link:: + sage: # needs sage.modules sage: B = BraidGroup(2) sage: b = B([1, 1]) sage: K = Link(b) - sage: K.khovanov_homology(degree = 2) + sage: K.khovanov_homology(degree=2) {2: {2: 0}, 4: {2: Z}, 6: {2: Z}} TESTS: Check that :issue:`31001` is fixed:: + sage: # needs sage.modules sage: L = Link([]) sage: L.khovanov_homology() {-1: {0: Z}, 1: {0: Z}} @@ -1332,12 +1330,14 @@ def oriented_gauss_code(self): EXAMPLES:: - sage: L = Link([[1, 10, 2, 11], [6, 3, 7, 2], [3, 9, 4, 12], [9, 6, 10, 5], [8, 4, 5, 1], [11, 7, 12, 8]]) + sage: L = Link([[1, 10, 2, 11], [6, 3, 7, 2], [3, 9, 4, 12], + ....: [9, 6, 10, 5], [8, 4, 5, 1], [11, 7, 12, 8]]) sage: L.oriented_gauss_code() [[[-1, 2, -3, 5], [4, -2, 6, -5], [-4, 1, -6, 3]], [-1, 1, 1, 1, -1, -1]] sage: L = Link([[1, 3, 2, 4], [6, 2, 3, 1], [7, 5, 8, 4], [5, 7, 6, 8]]) sage: L.oriented_gauss_code() [[[-1, 2], [-3, 4], [1, 3, -4, -2]], [-1, -1, 1, 1]] + sage: B = BraidGroup(8) sage: b = B([1, 1, 1, 1, 1]) sage: L = Link(b) @@ -1349,6 +1349,7 @@ def oriented_gauss_code(self): sage: L = Link([]) sage: L.oriented_gauss_code() [[], []] + sage: L = Link(BraidGroup(2).one()) sage: L.oriented_gauss_code() [[], []] @@ -1415,6 +1416,7 @@ def pd_code(self): sage: L = Link([[[1, -2, 3, -4, 2, -1, 4, -3]], [1, 1, -1, -1]]) sage: L.pd_code() [[6, 2, 7, 1], [2, 6, 3, 5], [8, 3, 1, 4], [4, 7, 5, 8]] + sage: B = BraidGroup(2) sage: b = B([1, 1, 1, 1, 1]) sage: L = Link(b) @@ -1432,6 +1434,7 @@ def pd_code(self): sage: L = Link([[], []]) sage: L.pd_code() [] + sage: L = Link(BraidGroup(2).one()) sage: L.pd_code() [] @@ -1520,10 +1523,12 @@ def gauss_code(self): sage: L = Link([[1, 4, 2, 3], [4, 1, 3, 2]]) sage: L.gauss_code() [[-1, 2], [1, -2]] + sage: B = BraidGroup(8) sage: L = Link(B([1, -2, 1, -2, -2])) sage: L.gauss_code() [[-1, 3, -4, 5], [1, -2, 4, -5, 2, -3]] + sage: L = Link([[[-1, 2], [-3, 4], [1, 3, -4, -2]], [-1, -1, 1, 1]]) sage: L.gauss_code() [[-1, 2], [-3, 4], [1, 3, -4, -2]] @@ -1547,9 +1552,11 @@ def dowker_notation(self): EXAMPLES:: - sage: L = Link([[[-1, 2, -3, 4, 5, 1, -2, 6, 7, 3, -4, -7, -6,-5]], [-1, -1, -1, -1, 1, -1, 1]]) + sage: L = Link([[[-1, 2, -3, 4, 5, 1, -2, 6, 7, 3, -4, -7, -6,-5]], + ....: [-1, -1, -1, -1, 1, -1, 1]]) sage: L.dowker_notation() [(1, 6), (7, 2), (3, 10), (11, 4), (14, 5), (13, 8), (12, 9)] + sage: B = BraidGroup(4) sage: L = Link(B([1, 2, 1, 2])) sage: L.dowker_notation() @@ -1655,6 +1662,7 @@ def _homology_generators(self): EXAMPLES:: + sage: # needs sage.modules sage: B = BraidGroup(4) sage: L = Link(B([-1, 3, 1, 3])) sage: L._homology_generators() @@ -1694,6 +1702,7 @@ def seifert_matrix(self): EXAMPLES:: + sage: # needs sage.modules sage: B = BraidGroup(4) sage: L = Link(B([-1, 3, 1, 3])) sage: L.seifert_matrix() @@ -1856,6 +1865,7 @@ def signature(self): EXAMPLES:: + sage: # needs sage.modules sage: B = BraidGroup(4) sage: L = Link(B([-1, 3, 1, 3])) sage: L.signature() @@ -1878,8 +1888,8 @@ def omega_signature(self, omega): INPUT: - - `\omega` -- a complex number of modulus 1. This is assumed to be - coercible to ``QQbar``. + - `\omega` -- a complex number of modulus 1; this is assumed to be + coercible to ``QQbar`` This is defined as the signature of the Hermitian matrix @@ -1898,6 +1908,7 @@ def omega_signature(self, omega): EXAMPLES:: + sage: # needs sage.modules sage.rings.number_field sage: B = BraidGroup(4) sage: K = Knot(B([1,1,1,2,-1,2,-3,2,-3])) sage: omega = QQbar.zeta(3) @@ -1923,6 +1934,7 @@ def alexander_polynomial(self, var='t'): We begin by computing the Alexander polynomial for the figure-eight knot:: + sage: # needs sage.modules sage: B = BraidGroup(3) sage: L = Link(B([1, -2, 1, -2])) sage: L.alexander_polynomial() @@ -1933,11 +1945,12 @@ def alexander_polynomial(self, var='t'): sage: L = Link([[3,1,2,4],[8,9,1,7],[5,6,7,3],[4,18,6,5], ....: [17,19,8,18],[9,10,11,14],[10,12,13,11], ....: [12,19,15,13],[20,16,14,15],[16,20,17,2]]) - sage: L.alexander_polynomial() + sage: L.alexander_polynomial() # needs sage.modules 1 Some additional examples:: + sage: # needs sage.modules sage: B = BraidGroup(2) sage: L = Link(B([1])) sage: L.alexander_polynomial() @@ -1953,6 +1966,7 @@ def alexander_polynomial(self, var='t'): When the Seifert surface is disconnected, the Alexander polynomial is defined to be `0`:: + sage: # needs sage.modules sage: B = BraidGroup(4) sage: L = Link(B([1,3])) sage: L.alexander_polynomial() @@ -1960,6 +1974,7 @@ def alexander_polynomial(self, var='t'): TESTS:: + sage: # needs sage.modules sage: B = BraidGroup(4) sage: L = Link(B([-1, 3, 1, 3])) sage: L.alexander_polynomial() @@ -1997,6 +2012,7 @@ def conway_polynomial(self): EXAMPLES:: + sage: # needs sage.modules sage: B = BraidGroup(3) sage: L = Link(B([1, -2, 1, -2])) sage: L.conway_polynomial() @@ -2057,17 +2073,17 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ): EXAMPLES:: sage: K = Link([[[1, -2, 3, -1, 2, -3]],[-1, -1, -1]]) - sage: K.khovanov_polynomial() + sage: K.khovanov_polynomial() # needs sage.modules q^-1 + q^-3 + q^-5*t^-2 + q^-9*t^-3 - sage: K.khovanov_polynomial(base_ring=GF(2)) + sage: K.khovanov_polynomial(base_ring=GF(2)) # needs sage.modules q^-1 + q^-3 + q^-5*t^-2 + q^-7*t^-2 + q^-9*t^-3 The figure eight knot:: sage: L = Link([[1, 6, 2, 7], [5, 2, 6, 3], [3, 1, 4, 8], [7, 5, 8, 4]]) - sage: L.khovanov_polynomial(var1='p') + sage: L.khovanov_polynomial(var1='p') # needs sage.modules p^5*t^2 + p*t + p + p^-1 + p^-1*t^-1 + p^-5*t^-2 - sage: L.khovanov_polynomial(var1='p', var2='s', base_ring=GF(4)) + sage: L.khovanov_polynomial(var1='p', var2='s', base_ring=GF(4)) # needs sage.modules sage.rings.finite_rings p^5*s^2 + p^3*s^2 + p*s + p + p^-1 + p^-1*s^-1 + p^-3*s^-1 + p^-5*s^-2 The Hopf link:: @@ -2075,7 +2091,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ): sage: B = BraidGroup(2) sage: b = B([1, 1]) sage: K = Link(b) - sage: K.khovanov_polynomial() + sage: K.khovanov_polynomial() # needs sage.modules q^6*t^2 + q^4*t^2 + q^2 + 1 .. SEEALSO:: :meth:`khovanov_homology` @@ -2100,6 +2116,7 @@ def determinant(self): EXAMPLES:: + sage: # needs sage.modules sage: B = BraidGroup(4) sage: L = Link(B([-1, 2, 1, 2])) sage: L.determinant() @@ -2117,6 +2134,7 @@ def determinant(self): TESTS:: + sage: # needs sage.modules sage: B = BraidGroup(3) sage: Link(B([1, 2, 1, -2, -1])).determinant() 0 @@ -2205,10 +2223,12 @@ def orientation(self): EXAMPLES:: - sage: L = Link([[1, 2, 5, 4], [3, 7, 6, 5], [4, 6, 9, 8], [7, 11, 10, 9], [8, 10, 13, 1], [11, 3, 2, 13]]) + sage: L = Link([[1, 2, 5, 4], [3, 7, 6, 5], [4, 6, 9, 8], [7, 11, 10, 9], + ....: [8, 10, 13, 1], [11, 3, 2, 13]]) sage: L.orientation() [-1, 1, -1, 1, -1, 1] - sage: L = Link([[1, 6, 2, 7], [7, 2, 8, 3], [3, 10, 4, 11], [11, 4, 12, 5], [14, 6, 1, 5], [13, 8, 14, 9], [12, 10, 13, 9]]) + sage: L = Link([[1, 6, 2, 7], [7, 2, 8, 3], [3, 10, 4, 11], [11, 4, 12, 5], + ....: [14, 6, 1, 5], [13, 8, 14, 9], [12, 10, 13, 9]]) sage: L.orientation() [-1, -1, -1, -1, 1, -1, 1] sage: L = Link([[1, 3, 3, 2], [2, 5, 5, 4], [4, 7, 7, 1]]) @@ -2243,18 +2263,23 @@ def seifert_circles(self): sage: L = Link([[[1, -2, 3, -4, 2, -1, 4, -3]], [1, 1, -1, -1]]) sage: L.seifert_circles() [[1, 7, 5, 3], [2, 6], [4, 8]] - sage: L = Link([[[-1, 2, 3, -4, 5, -6, 7, 8, -2, -5, 6, 1, -8, -3, 4, -7]], [-1, -1, -1, -1, 1, 1, -1, 1]]) + sage: L = Link([[[-1, 2, 3, -4, 5, -6, 7, 8, -2, -5, 6, 1, -8, -3, 4, -7]], + ....: [-1, -1, -1, -1, 1, 1, -1, 1]]) sage: L.seifert_circles() [[1, 13, 9, 3, 15, 5, 11, 7], [2, 10, 6, 12], [4, 16, 8, 14]] - sage: L = Link([[[-1, 2, -3, 4, 5, 1, -2, 6, 7, 3, -4, -7, -6, -5]], [-1, -1, -1, -1, 1, -1, 1]]) + sage: L = Link([[[-1, 2, -3, 4, 5, 1, -2, 6, 7, 3, -4, -7, -6, -5]], + ....: [-1, -1, -1, -1, 1, -1, 1]]) sage: L.seifert_circles() [[1, 7, 3, 11, 5], [2, 8, 14, 6], [4, 12, 10], [9, 13]] - sage: L = Link([[1, 7, 2, 6], [7, 3, 8, 2], [3, 11, 4, 10], [11, 5, 12, 4], [14, 5, 1, 6], [13, 9, 14, 8], [12, 9, 13, 10]]) + sage: L = Link([[1, 7, 2, 6], [7, 3, 8, 2], [3, 11, 4, 10], [11, 5, 12, 4], + ....: [14, 5, 1, 6], [13, 9, 14, 8], [12, 9, 13, 10]]) sage: L.seifert_circles() [[1, 7, 3, 11, 5], [2, 8, 14, 6], [4, 12, 10], [9, 13]] - sage: L = Link([[[-1, 2, -3, 5], [4, -2, 6, -5], [-4, 1, -6, 3]], [-1, 1, 1, 1, -1, -1]]) + sage: L = Link([[[-1, 2, -3, 5], [4, -2, 6, -5], [-4, 1, -6, 3]], + ....: [-1, 1, 1, 1, -1, -1]]) sage: L.seifert_circles() [[1, 11, 8], [2, 7, 12, 4, 5, 10], [3, 9, 6]] + sage: B = BraidGroup(2) sage: L = Link(B([1, 1, 1])) sage: L.seifert_circles() @@ -2288,7 +2313,7 @@ def seifert_circles(self): while a not in par: par.append(a) posnext = C[(C.index(a) - 1) % 4] - if tails[posnext] == C and not [posnext] in result: + if tails[posnext] == C and [posnext] not in result: a = posnext else: a = C[(C.index(a) + 1) % 4] @@ -2310,22 +2335,29 @@ def regions(self): EXAMPLES:: - sage: L = Link([[[-1, +2, -3, 4, +5, +1, -2, +6, +7, 3, -4, -7, -6,-5]],[-1, -1, -1, -1, 1, -1, 1]]) + sage: L = Link([[[-1, +2, -3, 4, +5, +1, -2, +6, +7, 3, -4, -7, -6,-5]], + ....: [-1, -1, -1, -1, 1, -1, 1]]) sage: L.regions() - [[14, -5, 12, -9], [13, 9], [11, 5, 1, 7, 3], [10, -3, 8, -13], [6, -1], [4, -11], [2, -7], [-2, -6, -14, -8], [-4, -10, -12]] + [[14, -5, 12, -9], [13, 9], [11, 5, 1, 7, 3], [10, -3, 8, -13], + [6, -1], [4, -11], [2, -7], [-2, -6, -14, -8], [-4, -10, -12]] sage: L = Link([[[1, -2, 3, -4, 2, -1, 4, -3]],[1, 1, -1, -1]]) sage: L.regions() [[8, 4], [7, -4, 1], [6, -1, -3], [5, 3, -8], [2, -5, -7], [-2, -6]] - sage: L = Link([[[-1, +2, 3, -4, 5, -6, 7, 8, -2, -5, +6, +1, -8, -3, 4, -7]],[-1, -1, -1, -1, 1, 1, -1, 1]]) + sage: L = Link([[[-1, +2, 3, -4, 5, -6, 7, 8, -2, -5, +6, +1, -8, -3, 4, -7]], + ....: [-1, -1, -1, -1, 1, 1, -1, 1]]) sage: L.regions() - [[16, 8, 14, 4], [15, -4], [13, -8, 1], [12, -1, -7], [11, 7, -16, 5], [10, -5, -15, -3], [9, 3, -14], [6, -11], [2, -9, -13], [-2, -12, -6, -10]] + [[16, 8, 14, 4], [15, -4], [13, -8, 1], [12, -1, -7], [11, 7, -16, 5], + [10, -5, -15, -3], [9, 3, -14], [6, -11], [2, -9, -13], [-2, -12, -6, -10]] + sage: B = BraidGroup(2) sage: L = Link(B([-1, -1, -1])) sage: L.regions() [[6, -5], [5, 1, 3], [4, -3], [2, -1], [-2, -6, -4]] - sage: L = Link([[[1, -2, 3, -4], [-1, 5, -3, 2, -5, 4]], [-1, 1, 1, -1, -1]]) + sage: L = Link([[[1, -2, 3, -4], [-1, 5, -3, 2, -5, 4]], + ....: [-1, 1, 1, -1, -1]]) sage: L.regions() - [[10, -4, -7], [9, 7, -3], [8, 3], [6, -9, -2], [5, 2, -8, 4], [1, -5], [-1, -10, -6]] + [[10, -4, -7], [9, 7, -3], [8, 3], [6, -9, -2], [5, 2, -8, 4], + [1, -5], [-1, -10, -6]] sage: L = Link([[1, 3, 3, 2], [2, 4, 4, 5], [5, 6, 6, 7], [7, 8, 8, 1]]) sage: L.regions() [[-3], [-4], [-6], [-8], [7, 1, 2, 5], [-1, 8, -7, 6, -5, 4, -2, 3]] @@ -2540,36 +2572,36 @@ def reverse(self): EXAMPLES:: - sage: K3 = Knot([[5, 2, 4, 1], [3, 6, 2, 5], [1, 4, 6, 3]]) - sage: K3r = K3.reverse(); K3r.pd_code() - [[4, 1, 5, 2], [2, 5, 3, 6], [6, 3, 1, 4]] - sage: K3 == K3r - True + sage: K3 = Knot([[5, 2, 4, 1], [3, 6, 2, 5], [1, 4, 6, 3]]) + sage: K3r = K3.reverse(); K3r.pd_code() + [[4, 1, 5, 2], [2, 5, 3, 6], [6, 3, 1, 4]] + sage: K3 == K3r + True a non reversable knot:: - sage: K8_17 = Knot([[6, 1, 7, 2], [14, 7, 15, 8], [8, 4, 9, 3], - ....: [2, 14, 3, 13], [12, 6, 13, 5], [4, 10, 5, 9], - ....: [16, 11, 1, 12], [10, 15, 11, 16]]) - sage: K8_17r = K8_17.reverse() - sage: b = K8_17.braid(); b - s0^2*s1^-1*(s1^-1*s0)^2*s1^-1 - sage: br = K8_17r.braid(); br - s0^-1*s1*s0^-2*s1^2*s0^-1*s1 - sage: b.is_conjugated(br) - False - sage: b == br.reverse() - False - sage: b.is_conjugated(br.reverse()) - True - sage: K8_17b = Link(b) - sage: K8_17br = K8_17b.reverse() - sage: bbr = K8_17br.braid(); bbr - (s1^-1*s0)^2*s1^-2*s0^2 - sage: br == bbr - False - sage: br.is_conjugated(bbr) - True + sage: K8_17 = Knot([[6, 1, 7, 2], [14, 7, 15, 8], [8, 4, 9, 3], + ....: [2, 14, 3, 13], [12, 6, 13, 5], [4, 10, 5, 9], + ....: [16, 11, 1, 12], [10, 15, 11, 16]]) + sage: K8_17r = K8_17.reverse() + sage: b = K8_17.braid(); b + s0^2*s1^-1*(s1^-1*s0)^2*s1^-1 + sage: br = K8_17r.braid(); br + s0^-1*s1*s0^-2*s1^2*s0^-1*s1 + sage: b.is_conjugated(br) + False + sage: b == br.reverse() + False + sage: b.is_conjugated(br.reverse()) + True + sage: K8_17b = Link(b) + sage: K8_17br = K8_17b.reverse() + sage: bbr = K8_17br.braid(); bbr + (s1^-1*s0)^2*s1^-2*s0^2 + sage: br == bbr + False + sage: br.is_conjugated(bbr) + True """ if self._reverse: return self._reverse @@ -2675,7 +2707,7 @@ def jones_polynomial(self, variab=None, skein_normalization=False, algorithm='jo sage: L = Link([[3,1,2,4],[8,9,1,7],[5,6,7,3],[4,18,6,5], ....: [17,19,8,18],[9,10,11,14],[10,12,13,11], ....: [12,19,15,13],[20,16,14,15],[16,20,17,2]]) - sage: L.jones_polynomial() + sage: L.jones_polynomial() # needs sage.symbolic 1 The Ochiai unknot:: @@ -2683,21 +2715,21 @@ def jones_polynomial(self, variab=None, skein_normalization=False, algorithm='jo sage: L = Link([[[1,-2,-3,-8,-12,13,-14,15,-7,-1,2,-4,10,11,-13,12, ....: -11,-16,4,3,-5,6,-9,7,-15,14,16,-10,8,9,-6,5]], ....: [-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1]]) - sage: L.jones_polynomial() # long time + sage: L.jones_polynomial() # long time # needs sage.symbolic 1 Two unlinked unknots:: sage: B = BraidGroup(4) sage: b = B([1, 3]) - sage: Link(b).jones_polynomial() + sage: Link(b).jones_polynomial() # needs sage.symbolic -sqrt(t) - 1/sqrt(t) The Hopf link:: sage: B = BraidGroup(2) sage: b = B([-1,-1]) - sage: Link(b).jones_polynomial() + sage: Link(b).jones_polynomial() # needs sage.symbolic -1/sqrt(t) - 1/t^(5/2) Different representations of the trefoil and one of its mirror:: @@ -2726,12 +2758,13 @@ def jones_polynomial(self, variab=None, skein_normalization=False, algorithm='jo sage: B = BraidGroup(4) sage: K11n42 = Link(B([1, -2, 3, -2, 3, -2, -2, -1, 2, -3, -3, 2, 2])) sage: K11n34 = Link(B([1, 1, 2, -3, 2, -3, 1, -2, -2, -3, -3])) - sage: bool(K11n42.jones_polynomial() == K11n34.jones_polynomial()) + sage: bool(K11n42.jones_polynomial() == K11n34.jones_polynomial()) # needs sage.symbolic True The two algorithms for computation give the same result when the trace closure of the braid representation is the link itself:: + sage: # needs sage.symbolic sage: L = Link([[[-1, 2, -3, 4, 5, 1, -2, 6, 7, 3, -4, -7, -6, -5]], ....: [-1, -1, -1, -1, 1, -1, 1]]) sage: jonesrep = L.jones_polynomial(algorithm='jonesrep') @@ -2750,17 +2783,17 @@ def jones_polynomial(self, variab=None, skein_normalization=False, algorithm='jo 2 sage: L.number_of_components() 1 - sage: b.jones_polynomial() + sage: b.jones_polynomial() # needs sage.symbolic -sqrt(t) - 1/sqrt(t) - sage: L.jones_polynomial() + sage: L.jones_polynomial() # needs sage.symbolic 1 - sage: L.jones_polynomial(algorithm='statesum') + sage: L.jones_polynomial(algorithm='statesum') # needs sage.symbolic 1 TESTS:: sage: L = Link([]) - sage: L.jones_polynomial(algorithm='statesum') + sage: L.jones_polynomial(algorithm='statesum') # needs sage.symbolic 1 sage: L.jones_polynomial(algorithm='other') @@ -2931,9 +2964,7 @@ def homfly_polynomial(self, var1=None, var2=None, normalization='lm'): polynomials of three links that vary only in one crossing; that is the positive, negative, or smoothed links respectively - OUTPUT: - - A Laurent polynomial over the integers. + OUTPUT: a Laurent polynomial over the integers .. NOTE:: @@ -2949,13 +2980,13 @@ def homfly_polynomial(self, var1=None, var2=None, normalization='lm'): sage: g = BraidGroup(2).gen(0) sage: K = Knot(g^5) - sage: K.homfly_polynomial() + sage: K.homfly_polynomial() # needs sage.libs.homfly L^-4*M^4 - 4*L^-4*M^2 + 3*L^-4 - L^-6*M^2 + 2*L^-6 The Hopf link:: sage: L = Link([[1,4,2,3],[4,1,3,2]]) - sage: L.homfly_polynomial('x', 'y') + sage: L.homfly_polynomial('x', 'y') # needs sage.libs.homfly -x^-1*y + x^-1*y^-1 + x^-3*y^-1 Another version of the Hopf link where the orientation @@ -2963,18 +2994,18 @@ def homfly_polynomial(self, var1=None, var2=None, normalization='lm'): and `y \mapsto M`:: sage: L = Link([[1,3,2,4], [4,2,3,1]]) - sage: L.homfly_polynomial() + sage: L.homfly_polynomial() # needs sage.libs.homfly L^3*M^-1 - L*M + L*M^-1 sage: L = Link([[1,3,2,4], [4,2,3,1]]) - sage: L.homfly_polynomial(normalization='az') + sage: L.homfly_polynomial(normalization='az') # needs sage.libs.homfly a^3*z^-1 - a*z - a*z^-1 The figure-eight knot:: sage: L = Link([[2,5,4,1], [5,3,7,6], [6,9,1,4], [9,7,3,2]]) - sage: L.homfly_polynomial() + sage: L.homfly_polynomial() # needs sage.libs.homfly -L^2 + M^2 - 1 - L^-2 - sage: L.homfly_polynomial('a', 'z', 'az') + sage: L.homfly_polynomial('a', 'z', 'az') # needs sage.libs.homfly a^2 - z^2 - 1 + a^-2 The "monster" unknot:: @@ -2982,18 +3013,20 @@ def homfly_polynomial(self, var1=None, var2=None, normalization='lm'): sage: L = Link([[3,1,2,4], [8,9,1,7], [5,6,7,3], [4,18,6,5], ....: [17,19,8,18], [9,10,11,14], [10,12,13,11], ....: [12,19,15,13], [20,16,14,15], [16,20,17,2]]) - sage: L.homfly_polynomial() + sage: L.homfly_polynomial() # needs sage.libs.homfly 1 Comparison with KnotInfo:: - sage: KI, m = K.get_knotinfo(); KI, m - (, ) + sage: # needs sage.libs.homfly + sage: KI = K.get_knotinfo(mirror_version=False); KI + sage: K.homfly_polynomial(normalization='vz') == KI.homfly_polynomial() True The knot `9_6`:: + sage: # needs sage.libs.homfly sage: B = BraidGroup(3) sage: K = Knot(B([-1,-1,-1,-1,-1,-1,-2,1,-2,-2])) sage: K.homfly_polynomial() @@ -3007,6 +3040,7 @@ def homfly_polynomial(self, var1=None, var2=None, normalization='lm'): This works with isolated components:: + sage: # needs sage.libs.homfly sage: L = Link([[[1, -1], [2, -2]], [1, 1]]) sage: L2 = Link([[1, 4, 2, 3], [2, 4, 1, 3]]) sage: L2.homfly_polynomial() @@ -3025,7 +3059,7 @@ def homfly_polynomial(self, var1=None, var2=None, normalization='lm'): Check that :issue:`30346` is fixed:: sage: L = Link([]) - sage: L.homfly_polynomial() + sage: L.homfly_polynomial() # needs sage.libs.homfly 1 REFERENCES: @@ -3101,11 +3135,9 @@ def links_gould_polynomial(self, varnames='t0, t1'): INPUT: - - ``varnames`` -- string (default ``t0, t1``) - - OUTPUT: + - ``varnames`` -- string (default: ``'t0, t1'``) - A Laurent polynomial in the given variable names. + OUTPUT: a Laurent polynomial in the given variable names EXAMPLES:: @@ -3127,12 +3159,11 @@ def _coloring_matrix(self, n=None): - ``n`` -- the number of colors to consider (if ommitted the value of the determinant of ``self`` will be taken) - OUTPUT: - - a matrix over the residue class ring of integers modulo ``n``. + OUTPUT: a matrix over the residue class ring of integers modulo ``n`` EXAMPLES:: + sage: # needs sage.libs.pari sage.modules sage: K = Link([[[1, -2, 3, -1, 2, -3]], [1, 1, 1]]) sage: K._coloring_matrix(3) [2 2 2] @@ -3188,13 +3219,13 @@ def is_colorable(self, n=None): We show that the trefoil knot is 3-colorable:: sage: K = Link([[[1, -2, 3, -1, 2, -3]], [1, 1, 1]]) - sage: K.is_colorable(3) + sage: K.is_colorable(3) # needs sage.libs.pari sage.modules True But the figure eight knot is not:: sage: K8 = Link([[[1, -2, 4, -3, 2, -1, 3, -4]], [1, 1, -1, -1]]) - sage: K8.is_colorable(3) + sage: K8.is_colorable(3) # needs sage.libs.pari sage.modules False But it is colorable with respect to the value of its determinant:: @@ -3246,7 +3277,7 @@ def colorings(self, n=None): EXAMPLES:: sage: K = Link([[[1, -2, 3, -1, 2, -3]], [1, 1, 1]]) - sage: K.colorings(3) + sage: K.colorings(3) # needs sage.libs.pari sage.modules [{(1, 2): 0, (3, 4): 1, (5, 6): 2}, {(1, 2): 0, (3, 4): 2, (5, 6): 1}, {(1, 2): 1, (3, 4): 0, (5, 6): 2}, @@ -3293,9 +3324,9 @@ def colorings(self, n=None): def coloring_maps(self, n=None, finitely_presented=False): r""" - Return the ``n``-coloring maps of ``self``. These are group + Return the `n`-coloring maps of ``self``. These are group homomorphisms from the fundamental group of ``self`` to the - ``n``-th dihedral group. + `n`-th dihedral group. INPUT: @@ -3303,14 +3334,14 @@ def coloring_maps(self, n=None, finitely_presented=False): of the determinant of ``self`` will be taken). Note that there are no coloring maps if n is coprime to the determinant of ``self`` - - ``finitely_presented`` (default ``False``) whether to choose the - dihedral groups as finitely presented groups. If not set to ``True`` - they are represented as permutation groups. + - ``finitely_presented`` -- boolean (default: ``False``); whether to + choose the dihedral groups as finitely presented groups. If not set + to ``True`` they are represented as permutation groups. OUTPUT: a list of group homomporhisms from the fundamental group of ``self`` - to the ``n``-th dihedral group (represented according to the key + to the `n`-th dihedral group (represented according to the key argument ``finitely_presented``). EXAMPLES:: @@ -3394,10 +3425,10 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, components - ``solver`` -- the linear solver to use, see - :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. + :class:`~sage.numerical.mip.MixedIntegerLinearProgram` - - ``color`` -- (default: 'blue') a color or a coloring (as returned - by :meth:`colorings`. + - ``color`` -- string (default: ``'blue'``); a color or a coloring (as + returned by :meth:`colorings` The usual keywords for plots can be used here too. @@ -3406,7 +3437,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, We construct the simplest version of the unknot:: sage: L = Link([[2, 1, 1, 2]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3419,7 +3450,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, We construct a more interesting example of the unknot:: sage: L = Link([[2, 1, 4, 5], [3, 5, 6, 7], [4, 1, 9, 6], [9, 2, 3, 7]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3430,10 +3461,10 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, The "monster" unknot:: - sage: L = Link([[3,1,2,4],[8,9,1,7],[5,6,7,3],[4,18,6,5], - ....: [17,19,8,18],[9,10,11,14],[10,12,13,11], - ....: [12,19,15,13],[20,16,14,15],[16,20,17,2]]) - sage: L.plot() + sage: L = Link([[3,1,2,4], [8,9,1,7], [5,6,7,3], [4,18,6,5], + ....: [17,19,8,18], [9,10,11,14], [10,12,13,11], + ....: [12,19,15,13], [20,16,14,15], [16,20,17,2]]) + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3449,7 +3480,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, sage: L = Link([[[1,-2,-3,-8,-12,13,-14,15,-7,-1,2,-4,10,11,-13,12, ....: -11,-16,4,3,-5,6,-9,7,-15,14,16,-10,8,9,-6,5]], ....: [-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3463,7 +3494,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, One of the representations of the trefoil knot:: sage: L = Link([[1, 5, 2, 4], [5, 3, 6, 2], [3, 1, 4, 6]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of 14 graphics primitives .. PLOT:: @@ -3475,7 +3506,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, The figure-eight knot:: sage: L = Link([[2, 1, 4, 5], [5, 6, 7, 3], [6, 4, 1, 9], [9, 2, 3, 7]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3489,7 +3520,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, sage: L = Link([[4,2,5,1], [10,3,11,4], [5,16,6,17], [7,12,8,13], ....: [18,9,19,10], [2,11,3,12], [13,20,14,21], [15,6,16,7], ....: [22,18,1,17], [8,19,9,20], [21,14,22,15]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3503,7 +3534,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, One of the representations of the Hopf link:: sage: L = Link([[1, 4, 2, 3], [4, 1, 3, 2]]) - sage: L.plot() + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3514,8 +3545,9 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, Plotting links with multiple isolated components:: - sage: L = Link([[[-1, 2, -3, 1, -2, 3], [4, -5, 6, -4, 5, -6]], [1, 1, 1, 1, 1, 1]]) - sage: L.plot() + sage: L = Link([[[-1, 2, -3, 1, -2, 3], [4, -5, 6, -4, 5, -6]], + ....: [1, 1, 1, 1, 1, 1]]) + sage: L.plot() # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3530,7 +3562,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, sage: B = BraidGroup(4) sage: b = B([1,2,3,1,2,-1,-3,2,3]) sage: L = Link(b) - sage: L.plot(color=L.colorings()[0]) + sage: L.plot(color=L.colorings()[0]) # needs sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3545,6 +3577,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, Check that :issue:`20315` is fixed:: + sage: # needs sage.plot sage: L = Link([[2,1,4,5], [5,6,7,3], [6,4,1,9], [9,2,3,7]]) sage: L.plot(solver='GLPK') Graphics object consisting of ... graphics primitives @@ -3875,7 +3908,7 @@ def _markov_move_cmp(self, braid): to the given braid in the following sense. If both braids have the same number of strands it is checked if they are conjugated to each other in their common braid group (Markov move I). If the number of strands differs, - the braid having less strands is extended by Markov moves II (appendening + the braid having less strands is extended by Markov moves II (appending the largest generator or its inverse recursively) until a common braid group can be achieved, where conjugation is tested. @@ -3943,15 +3976,15 @@ def _knotinfo_matching_list(self): OUTPUT: A tuple ``(l, proved)`` where ``l`` is the matching list and ``proved`` a boolean - telling if the entries of ``l`` are checked to be isotopic to self or not. + telling if the entries of ``l`` are checked to be isotopic to ``self`` or not. EXAMPLES:: sage: KnotInfo.L5a1_0.inject() Defining L5a1_0 - sage: ML = L5a1_0.link()._knotinfo_matching_list(); ML + sage: ML = L5a1_0.link()._knotinfo_matching_list(); ML # needs sage.libs.homfly ([, ], True) - sage: ML == Link(L5a1_0.braid())._knotinfo_matching_list() + sage: ML == Link(L5a1_0.braid())._knotinfo_matching_list() # needs sage.libs.homfly True Care is needed for links having non irreducible HOMFLY-PT polynomials:: @@ -3959,9 +3992,8 @@ def _knotinfo_matching_list(self): sage: k4_1 = KnotInfo.K4_1.link() sage: k5_2 = KnotInfo.K5_2.link() sage: k = k4_1.connected_sum(k5_2) - sage: k._knotinfo_matching_list() # optional - database_knotinfo + sage: k._knotinfo_matching_list() # optional - database_knotinfo # needs sage.libs.homfly ([], False) - """ from sage.knots.knotinfo import KnotInfoSeries pd_code = self.pd_code() @@ -3971,8 +4003,7 @@ def _knotinfo_matching_list(self): # set the limits for the KnotInfoSeries if cr > 11 and co > 1: cr = 11 - if cr > 13: - cr = 13 + cr = min(cr, 13) Hp = self.homfly_polynomial(normalization='vz') @@ -4001,7 +4032,7 @@ def _knotinfo_matching_list(self): Sn = KnotInfoSeries(cr, is_knot, False) la = Sa.lower_list(oriented=True, comp=co, det=det, homfly=Hp) ln = Sn.lower_list(oriented=True, comp=co, det=det, homfly=Hp) - l = sorted(list(set(la + ln))) + l = sorted(set(la + ln)) br = self.braid() br_ind = br.strands() @@ -4025,7 +4056,7 @@ def _knotinfo_matching_list(self): def _knotinfo_matching_dict(self): r""" - Return a dictionary mapping items of the enum :class:`~sage.knots.knotinfo.SymmetryType` + Return a dictionary mapping items of the enum :class:`~sage.knots.knotinfo.SymmetryMutant` to list of links from the KnotInfo and LinkInfo databases which match the properties of the according symmetry mutant of ``self`` as much as possible. @@ -4033,7 +4064,7 @@ def _knotinfo_matching_dict(self): OUTPUT: A pair (``match_lists, proves``) of dictionaries with keys from the - enum :class:`~sage.knots.knotinfo.SymmetryType`. The first dictionary maps these keys to + enum :class:`~sage.knots.knotinfo.SymmetryMutant`. The first dictionary maps these keys to the corresponding matching list and ``proves`` maps them to booleans telling if the entries of the corresponding ``match_lists`` are checked to be isotopic to the symmetry mutant of ``self`` or not. @@ -4045,18 +4076,18 @@ def _knotinfo_matching_dict(self): sage: L4a1_0.link()._knotinfo_matching_dict() ({: [], : [], - : [], - : []}, + : [], + : []}, {: True, : True, - : False, - : False}) + : False, + : False}) """ from sage.knots.knotinfo import SymmetryMutant mutant = {} mutant[SymmetryMutant.itself] = self - mutant[SymmetryMutant.mirror_image] = self.mirror_image() mutant[SymmetryMutant.reverse] = self.reverse() + mutant[SymmetryMutant.mirror_image] = self.mirror_image() mutant[SymmetryMutant.concordance_inverse] = mutant[SymmetryMutant.mirror_image].reverse() match_lists = {k: list(mutant[k]._knotinfo_matching_list()[0]) for k in mutant.keys()} proves = {k: mutant[k]._knotinfo_matching_list()[1] for k in mutant.keys()} @@ -4068,22 +4099,26 @@ def get_knotinfo(self, mirror_version=True, unique=True): INPUT: - - ``mirror_version`` -- boolean (default is ``True``). If set to ``False`` + - ``mirror_version`` -- boolean (default: ``True``); if set to ``False`` the result of the method will be just the instance of :class:`~sage.knots.knotinfo.KnotInfoBase` (by default the result is a tuple of the instance and an enum, see explanation of the output below) - - ``unique`` -- boolean (default is ``True``). This only affects the case + - ``unique`` -- boolean (default: ``True``); this only affects the case where a unique identification is not possible. If set to ``False`` you - can obtain a matching list (see explanation of the output below) + can obtain a matching list (see explanation of the output below). OUTPUT: - A tuple ``(K, m)`` where ``K`` is an instance of :class:`~sage.knots.knotinfo.KnotInfoBase` - and ``m`` an instance of :class:`~sage.knots.knotinfo.SymmetryMutant` - (for chiral links) specifying the symmetry mutant of ``K`` to which - ``self`` is isotopic. The value of ``m`` is ``unknown`` if it cannot - be determined uniquely and the keyword option ``unique=False`` is given. + If ``self`` is a knot, then an element of the free monoid over prime + knots constructed from the KnotInfo database is returned. More explicitly + this is an element of :class:`~sage.knots.free_knotinfo_monoid.FreeKnotInfoMonoidElement`. + Else a tuple ``(K, m)`` is returned where ``K`` is an instance of + :class:`~sage.knots.knotinfo.KnotInfoBase` and ``m`` an instance of + :class:`~sage.knots.knotinfo.SymmetryMutant` (for chiral links) specifying + the symmetry mutant of ``K`` to which ``self`` is isotopic. The value of + ``m`` is ``unknown`` if it cannot be determined uniquely and the keyword + option ``unique=False`` is given. For proper links, if the orientation mutant cannot be uniquely determined, K will be a series of links gathering all links having the same unoriented @@ -4093,7 +4128,7 @@ def get_knotinfo(self, mirror_version=True, unique=True): (that is: ``m`` is suppressed). If it is not possible to determine a unique result - a :class:`NotImplementedError` + a :exc:`NotImplementedError` will be raised. To avoid this you can set ``unique`` to ``False``. You will get a list of matching candidates instead. @@ -4117,43 +4152,44 @@ def get_knotinfo(self, mirror_version=True, unique=True): EXAMPLES:: sage: # optional - database_knotinfo - sage: from sage.knots.knotinfo import KnotInfo sage: L = Link([[4,1,5,2], [10,4,11,3], [5,17,6,16], [7,13,8,12], ....: [18,10,19,9], [2,12,3,11], [13,21,14,20], [15,7,16,6], ....: [22,17,1,18], [8,20,9,19], [21,15,22,14]]) sage: L.get_knotinfo() - (, ) + KnotInfo['K11n_121m'] sage: K = KnotInfo.K10_25 sage: l = K.link() sage: l.get_knotinfo() - (, ) + KnotInfo['K10_25'] sage: k11 = KnotInfo.K11n_82.link() sage: k11m = k11.mirror_image() sage: k11mr = k11m.reverse() sage: k11mr.get_knotinfo() - (, ) + KnotInfo['K11n_82m'] sage: k11r = k11.reverse() sage: k11r.get_knotinfo() - (, ) + KnotInfo['K11n_82'] sage: k11rm = k11r.mirror_image() sage: k11rm.get_knotinfo() - (, ) + KnotInfo['K11n_82m'] - Knots with more than 13 and proper links having more than 11 crossings - cannot be identified. In addition non prime links or even links whose - HOMFLY-PT polynomial is not irreducible cannot be identified:: + Knots with more than 13 and multi-component links having more than 11 + crossings cannot be identified. In addition non prime multi-component + links or even links whose HOMFLY-PT polynomial is not irreducible cannot + be identified:: sage: b, = BraidGroup(2).gens() sage: Link(b**13).get_knotinfo() # optional - database_knotinfo - (, ) + KnotInfo['K13a_4878'] sage: Link(b**14).get_knotinfo() Traceback (most recent call last): ... NotImplementedError: this link having more than 11 crossings cannot be determined - sage: Link([[1, 4, 2, 5], [3, 8, 4, 1], [5, 2, 6, 3], [6, 10, 7, 9], [10, 8, 9, 7]]) + sage: Link([[1, 4, 2, 5], [3, 8, 4, 1], [5, 2, 6, 3], + ....: [6, 10, 7, 9], [10, 8, 9, 7]]) Link with 2 components represented by 5 crossings - sage: _.get_knotinfo() + sage: _.get_knotinfo() # needs sage.libs.homfly Traceback (most recent call last): ... NotImplementedError: this (possibly non prime) link cannot be determined @@ -4164,7 +4200,7 @@ def get_knotinfo(self, mirror_version=True, unique=True): ....: [17,19,8,18], [9,10,11,14], [10,12,13,11], ....: [12,19,15,13], [20,16,14,15], [16,20,17,2]]) sage: L.get_knotinfo() - (, ) + KnotInfo['K0_1'] Usage of option ``mirror_version``:: @@ -4181,10 +4217,7 @@ def get_knotinfo(self, mirror_version=True, unique=True): NotImplementedError: this link cannot be uniquely determined use keyword argument `unique` to obtain more details sage: l.get_knotinfo(unique=False) - [(, ), - (, ), - (, ), - (, )] + [KnotInfo['K10_25'], KnotInfo['K10_56']] sage: t = (1, -2, 1, 1, -2, 1, -2, -2) sage: l8 = Link(BraidGroup(3)(t)) sage: l8.get_knotinfo() @@ -4200,15 +4233,12 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: l12.get_knotinfo() Traceback (most recent call last): ... - NotImplementedError: this link having more than 11 crossings cannot be uniquely determined + NotImplementedError: this link having more than 11 crossings + cannot be uniquely determined use keyword argument `unique` to obtain more details sage: l12.get_knotinfo(unique=False) [(, ), - (, ), - (, ), - (, - ), - (, ), + (, ), (, ), (, )] @@ -4220,10 +4250,8 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: L2a1.get_knotinfo() (Series of links L2a1, ) sage: L2a1.get_knotinfo(unique=False) - [(, ), - (, ), - (, ), - (, )] + [(, ), + (, )] sage: KnotInfo.L5a1_0.inject() Defining L5a1_0 @@ -4236,21 +4264,19 @@ def get_knotinfo(self, mirror_version=True, unique=True): [, ] sage: l5.get_knotinfo(unique=False) [(, ), - (, ), - (, ), - (, )] + (, )] Clarifying the series around the Perko pair (:wikipedia:`Perko_pair`):: sage: for i in range(160, 166): # optional - database_knotinfo ....: K = Knots().from_table(10, i) ....: print('%s_%s' %(10, i), '--->', K.get_knotinfo()) - 10_160 ---> (, ) - 10_161 ---> (, ) - 10_162 ---> (, ) - 10_163 ---> (, ) - 10_164 ---> (, ) - 10_165 ---> (, ) + 10_160 ---> KnotInfo['K10_160'] + 10_161 ---> KnotInfo['K10_161m'] + 10_162 ---> KnotInfo['K10_162'] + 10_163 ---> KnotInfo['K10_163'] + 10_164 ---> KnotInfo['K10_164'] + 10_165 ---> KnotInfo['K10_165m'] Clarifying ther Perko series against `SnapPy `__:: @@ -4268,16 +4294,16 @@ def get_knotinfo(self, mirror_version=True, unique=True): ....: K = K10(i) ....: k = K.link(K.items.name, snappy=True) ....: print(k, '--->', k.sage_link().get_knotinfo()) - ---> (, ) - ---> (, ) - ---> (, ) - ---> (, ) - ---> (, ) - ---> (, ) + ---> KnotInfo['K10_160'] + ---> KnotInfo['K10_161m'] + ---> KnotInfo['K10_161'] + ---> KnotInfo['K10_162'] + ---> KnotInfo['K10_163'] + ---> KnotInfo['K10_164'] sage: snappy.Link('10_166') sage: _.sage_link().get_knotinfo() - (, ) + KnotInfo['K10_165m'] Another pair of confusion (see the corresponding `Warning `__):: @@ -4286,11 +4312,23 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: Ks10_86 = snappy.Link('10_86') sage: Ks10_83 = snappy.Link('10_83') sage: Ks10_86.sage_link().get_knotinfo(unique=False) - [(, ), - (, )] + [KnotInfo['K10_83c'], KnotInfo['K10_83m']] sage: Ks10_83.sage_link().get_knotinfo(unique=False) - [(, ), - (, )] + [KnotInfo['K10_86'], KnotInfo['K10_86r']] + + Non prime knots can be detected, as well:: + + sage: b = BraidGroup(4)((1, 2, 2, 2, -1, 2, 2, 2, -3, -3, -3)) + sage: Kb = Knot(b) + sage: Kb.get_knotinfo() + KnotInfo['K3_1']^2*KnotInfo['K3_1m'] + + sage: K = Link([[4, 2, 5, 1], [8, 6, 9, 5], [6, 3, 7, 4], [2, 7, 3, 8], + ....: [10, 15, 11, 16], [12, 21, 13, 22], [14, 11, 15, 12], [16, 9, 17, 10], + ....: [18, 25, 19, 26], [20, 23, 21, 24], [22, 13, 23, 14], [24, 19, 25, 20], + ....: [26, 17, 1, 18]]) + sage: K.get_knotinfo() # optional - database_knotinfo, long time + KnotInfo['K4_1']*KnotInfo['K9_2m'] TESTS:: @@ -4298,18 +4336,10 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: L = KnotInfo.L10a171_1_1_0 sage: l = L.link(L.items.braid_notation) sage: l.get_knotinfo(unique=False) - [(, - ), - (, - ), - (, - ), - (, - ), - (, ), - (, ), - (, ), - (, )] + [(, ), + (, ), + (, ), + (, )] sage: KnotInfo.L10a151_0_0.link().get_knotinfo() Traceback (most recent call last): ... @@ -4327,9 +4357,6 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: L1.get_knotinfo() == L2.get_knotinfo() True """ - # ToDo: extension to non prime links in which case an element of the monoid - # over :class:`KnotInfo` should be returned - non_unique_hint = '\nuse keyword argument `unique` to obtain more details' from sage.knots.knotinfo import SymmetryMutant @@ -4341,37 +4368,36 @@ def answer(L): if not mirror_version: return L - chiral = True - ach = L.is_amphicheiral() - achp = L.is_amphicheiral(positive=True) - rev = L.is_reversible() - if ach is None and achp is None and rev is None: - if unique: - raise NotImplementedError('this link cannot be uniquely determined (unknown chirality)%s' % non_unique_hint) - chiral = None - elif ach and achp: - chiral = False + def find_mutant(proved=True): + r""" + Return the according symmetry mutant from the matching list + and removes the entry from the list. + """ + for k in match_lists: + if proved: + prove = proves[k] or any(proves[m] for m in k.matches(L)) + if not prove: + continue + if k.is_minimal(L): + lk = match_lists[k] + if L in lk: + lk.remove(L) + return k sym_mut = None - if chiral is None: + if SymmetryMutant.unknown.matches(L): + if unique: + raise NotImplementedError('this link cannot be uniquely determined (unknown chirality)%s' % non_unique_hint) sym_mut = SymmetryMutant.unknown - elif not chiral: - sym_mut = SymmetryMutant.itself - else: - for k in match_lists: - lk = match_lists[k] - if proves[k] and L in lk: - lk.remove(L) - sym_mut = k - break if not sym_mut: - for k in match_lists: - lk = match_lists[k] - if L in lk: - lk.remove(L) - sym_mut = k - break + sym_mut = find_mutant() + + if not sym_mut: + sym_mut = find_mutant(proved=False) + + if not unique and not sym_mut: + return None if not sym_mut: # In case of a chiral link this means that the HOMFLY-PT @@ -4382,6 +4408,11 @@ def answer(L): if unique and sym_mut is SymmetryMutant.unknown: raise NotImplementedError('symmetry mutant of this link cannot be uniquely determined%s' % non_unique_hint) + if L.is_knot(): + from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + FKIM = FreeKnotInfoMonoid() + return FKIM((L, sym_mut)) + return L, sym_mut def answer_unori(S): @@ -4396,7 +4427,7 @@ def answer_unori(S): if all(i is SymmetryMutant.mirror_image for i in sym_mut): # all matching links are mirrored to self return S, SymmetryMutant.mirror_image - if all(i is SymmetryMutant.itself for i in sym_mut): + if all(i is SymmetryMutant.itself for i in sym_mut): # all matching links are self itself return S, SymmetryMutant.itself if any(i is SymmetryMutant.unknown for i in sym_mut): @@ -4411,18 +4442,33 @@ def answer_list(l): argument ``unique``. """ if not unique: - return sorted(set([answer(L) for L in l])) + ansl = [] + for L in l: + a = answer(L) + if a: + ansl.append(a) + return sorted(set(ansl)) if len(set(l)) == 1: return answer(l[0]) if not l[0].is_knot(): S = l[0].series(oriented=True) - if set(list(S)) == set(l): + if set(S) == set(l): return answer_unori(S) raise NotImplementedError('this link cannot be uniquely determined%s' % non_unique_hint) + H = self.homfly_polynomial(normalization='vz') + num_fac = sum(exp for f, exp in H.factor()) + if num_fac > 1 and self.is_knot(): + # we cannot be sure if this is a prime knot (see the example for the connected + # sum of K4_1 and K5_2 in the doctest of :meth:`_knotinfo_matching_list`) + # Therefor we calculate it directly in the free KnotInfo monoid + from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid + FKIM = FreeKnotInfoMonoid() + return FKIM.from_knot(self, unique=unique) + match_lists, proves = self._knotinfo_matching_dict() # first add only proved matching lists @@ -4460,11 +4506,7 @@ def answer_list(l): # we cannot not be sure if this link is recorded in the KnotInfo database raise NotImplementedError('this link having more than 11 crossings cannot be%s determined%s' % uniq_txt) - H = self.homfly_polynomial(normalization='vz') - - if sum(exp for f, exp in H.factor()) > 1: - # we cannot be sure if this is a prime link (see the example for the connected - # sum of K4_1 and K5_2 in the doctest of :meth:`_knotinfo_matching_list`) + if num_fac > 1: raise NotImplementedError('this (possibly non prime) link cannot be%s determined%s' % uniq_txt) if not l: @@ -4553,7 +4595,6 @@ def is_isotopic(self, other): verbose 1 (... link.py, is_isotopic) identified by KnotInfoSeries ([, ], SymmetryMutant.reverse) True sage: set_verbose(0) - """ from sage.misc.verbose import verbose if not isinstance(other, Link): diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index f8a7465521f..cc06d96c503 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -34,7 +34,6 @@ from sage.structure.sage_object import SageObject from sage.rings.complex_mpfr import ComplexField from sage.rings.integer import Integer -from sage.misc.sage_eval import sage_eval from sage.misc.verbose import verbose import sage.interfaces.gp from sage.env import SAGE_EXTCODE @@ -42,7 +41,7 @@ class Dokchitser(SageObject): r""" - Dokchitser's `L`-functions Calculator + Dokchitser's `L`-functions Calculator. Create a Dokchitser `L`-series with @@ -51,10 +50,10 @@ class Dokchitser(SageObject): where - - ``conductor`` -- integer, the conductor + - ``conductor`` -- integer; the conductor - ``gammaV`` -- list of Gamma-factor parameters, e.g. [0] for - Riemann zeta, [0,1] for ell.curves, (see examples). + Riemann zeta, [0,1] for ell.curves, (see examples) - ``weight`` -- positive real number, usually an integer e.g. 1 for Riemann zeta, 2 for `H^1` of curves/`\QQ` @@ -66,9 +65,9 @@ class Dokchitser(SageObject): included - ``residues`` -- vector of residues of `L^*(s)` in those poles or - set residues='automatic' (default value) + set ``residues='automatic'`` (default) - - ``prec`` -- integer (default: 53) number of *bits* of precision + - ``prec`` -- integer (default: 53); number of *bits* of precision RIEMANN ZETA FUNCTION: @@ -232,7 +231,7 @@ def __del__(self): def gp(self): """ Return the gp interpreter that is used to implement this Dokchitser - L-function. + `L`-function. EXAMPLES:: @@ -254,7 +253,7 @@ def gp(self): template = string.Template(tf.read()) from tempfile import NamedTemporaryFile - with NamedTemporaryFile(suffix=".gp", mode="w+t") as f: + with NamedTemporaryFile(suffix='.gp', mode='w+t') as f: f.write(template.substitute(i=str(self.__instance))) f.flush() self.__gp.read(f.name) @@ -365,7 +364,7 @@ def num_coeffs(self, T=1): 4 Verify that ``num_coeffs`` works with non-real spectral - parameters, e.g. for the L-function of the level 10 Maass form + parameters, e.g. for the `L`-function of the level 10 Maass form with eigenvalue 2.7341055592527126:: sage: ev = 2.7341055592527126 @@ -388,21 +387,20 @@ def init_coeffs(self, v, cutoff=1, INPUT: - - ``v`` -- list of complex numbers or string (pari function of k) + - ``v`` -- list of complex numbers or string (pari function of k) - - ``cutoff`` -- real number = 1 (default: 1) + - ``cutoff`` -- real number (default: 1) - - ``w`` -- list of complex numbers or string (pari function of k) + - ``w`` -- list of complex numbers or string (pari function of k) - - ``pari_precode`` -- some code to execute in pari - before calling initLdata + - ``pari_precode`` -- some code to execute in pari + before calling initLdata - - ``max_imaginary_part`` -- (default: 0): redefine if - you want to compute L(s) for s having large imaginary part, + - ``max_imaginary_part`` -- (default: 0) redefine if + you want to compute L(s) for s having large imaginary part - - ``max_asymp_coeffs`` -- (default: 40): at most this - many terms are generated in asymptotic series for phi(t) and - G(s,t). + - ``max_asymp_coeffs`` -- (default: 40) at most this + many terms are generated in asymptotic series for phi(t) and G(s,t) EXAMPLES:: @@ -410,8 +408,8 @@ def init_coeffs(self, v, cutoff=1, sage: pari_precode = 'tau(n)=(5*sigma(n,3)+7*sigma(n,5))*n/12 - 35*sum(k=1,n-1,(6*k-4*(n-k))*sigma(k,3)*sigma(n-k,5))' sage: L.init_coeffs('tau(k)', pari_precode=pari_precode) - Evaluate the resulting L-function at a point, and compare with - the answer that one gets "by definition" (of L-function + Evaluate the resulting `L`-function at a point, and compare with + the answer that one gets "by definition" (of `L`-function attached to a modular form):: sage: L(14) @@ -479,10 +477,6 @@ def repl(m): self.__init = (v, cutoff, w, pari_precode, max_imaginary_part, max_asymp_coeffs) - def __to_CC(self, s): - s = s.replace('.E', '.0E').replace(' ', '') - return self.__CC(sage_eval(s, locals={'I': self.__CC.gen(0)})) - def _clear_value_cache(self): del self.__values @@ -490,7 +484,7 @@ def __call__(self, s, c=None): r""" INPUT: - - ``s`` -- complex number + - ``s`` -- complex number .. NOTE:: @@ -516,6 +510,7 @@ def __call__(self, s, c=None): except KeyError: pass z = self._gp_call_inst('L', s) + CC = self.__CC if 'pole' in z: print(z) raise ArithmeticError @@ -526,10 +521,10 @@ def __call__(self, s, c=None): i = z.rfind('\n') msg = z[:i].replace('digits', 'decimal digits') verbose(msg, level=-1) - ans = self.__to_CC(z[i + 1:]) + ans = CC(z[i + 1:]) self.__values[s] = ans return ans - ans = self.__to_CC(z) + ans = CC(z) self.__values[s] = ans return ans @@ -574,14 +569,11 @@ def taylor_series(self, a=0, k=6, var='z'): INPUT: - - ``a`` -- complex number (default: 0); point about - which to expand + - ``a`` -- complex number (default: 0); point about which to expand - - ``k`` -- integer (default: 6), series is - `O(``var``^k)` + - ``k`` -- integer (default: 6); series is `O(``var``^k)` - - ``var`` -- string (default: 'z'), variable of power - series + - ``var`` -- string (default: ``'z'``); variable of power series EXAMPLES:: @@ -645,26 +637,26 @@ def check_functional_equation(self, T=1.2): and also determines the residues if ``self.poles != []`` and residues='automatic'. - More specifically: for `T>1` (default 1.2), + More specifically: for `T>1` (default: 1.2), ``self.check_functional_equation(T)`` should ideally return 0 (to the current precision). - - if what this function returns does not look like 0 at all, - probably the functional equation is wrong (i.e. some of the - parameters gammaV, conductor etc., or the coefficients are wrong), + - if what this function returns does not look like 0 at all, + probably the functional equation is wrong (i.e. some of the + parameters gammaV, conductor etc., or the coefficients are wrong), - - if checkfeq(T) is to be used, more coefficients have to be - generated (approximately T times more), e.g. call cflength(1.3), - initLdata("a(k)",1.3), checkfeq(1.3) + - if checkfeq(T) is to be used, more coefficients have to be + generated (approximately T times more), e.g. call cflength(1.3), + initLdata("a(k)",1.3), checkfeq(1.3) - - T=1 always (!) returns 0, so T has to be away from 1 + - T=1 always (!) returns 0, so T has to be away from 1 - - default value `T=1.2` seems to give a reasonable - balance + - default value `T=1.2` seems to give a reasonable + balance - - if you don't have to verify the functional equation or the - L-values, call num_coeffs(1) and initLdata("a(k)",1), you need - slightly less coefficients. + - if you don't have to verify the functional equation or the + L-values, call num_coeffs(1) and initLdata("a(k)",1), you need + slightly less coefficients. EXAMPLES:: @@ -698,8 +690,8 @@ def set_coeff_growth(self, coefgrow): INPUT: - - ``coefgrow`` -- string that evaluates to a PARI - function of n that defines a coefgrow function. + - ``coefgrow`` -- string that evaluates to a PARI function of n that + defines a coefgrow function EXAMPLES:: diff --git a/src/sage/lfunctions/lcalc.py b/src/sage/lfunctions/lcalc.py index 45b0e93b540..f695712abc1 100644 --- a/src/sage/lfunctions/lcalc.py +++ b/src/sage/lfunctions/lcalc.py @@ -6,7 +6,7 @@ functionality compiled in and is a standard part of Sage. -.. note:: +.. NOTE:: Each call to ``lcalc`` runs a complete ``lcalc`` process. On a typical Linux system, this @@ -44,22 +44,19 @@ class LCalc(SageObject): r""" - Rubinstein's `L`-functions Calculator + Rubinstein's `L`-functions Calculator. Type ``lcalc.[tab]`` for a list of useful commands that are implemented using the command line interface, but return objects that make sense in Sage. For each command the possible - inputs for the L-function are: + inputs for the `L`-function are: - - ``"`` -- (default) the Riemann zeta function + - ``"`` -- (default) the Riemann zeta function - - ``'tau'`` -- the L function of the Ramanujan delta - function - - - elliptic curve E -- where E is an elliptic curve over - `\QQ`; defines `L(E,s)` + - ``'tau'`` -- the L function of the Ramanujan delta function + - ``E`` -- an elliptic curve over `\QQ`; defines `L(E,s)` You can also use the complete command-line interface of Rubinstein's `L`-functions calculations program via this @@ -108,12 +105,9 @@ def zeros(self, n, L=''): INPUT: + - ``n`` -- integer - - ``n`` -- integer - - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - + - ``L`` -- defines `L`-function (default: Riemann zeta function) This function also checks the Riemann Hypothesis and makes sure no zeros are missed. This means it looks for several dozen zeros to @@ -144,13 +138,9 @@ def zeros_in_interval(self, x, y, stepsize, L=''): INPUT: + - ``x, y, stepsize`` -- positive floating point numbers - - ``x, y, stepsize`` -- positive floating point - numbers - - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - + - ``L`` -- defines `L`-function (default: Riemann zeta function) OUTPUT: list of pairs (zero, S(T)). @@ -177,12 +167,9 @@ def value(self, s, L=''): INPUT: + - ``s`` -- complex number - - ``s`` -- complex number - - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - + - ``L`` -- defines `L`-function (default: Riemann zeta function) EXAMPLES:: @@ -210,21 +197,14 @@ def values_along_line(self, s0, s1, number_samples, L=''): INPUT: + - ``s0, s1`` -- complex numbers - - ``s0, s1`` -- complex numbers + - ``number_samples`` -- integer - - ``number_samples`` -- integer - - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - - - OUTPUT: - - - - ``list`` -- list of pairs (s, zeta(s)), where the s - are equally spaced sampled points on the line from s0 to s1. + - ``L`` -- defines `L`-function (default: Riemann zeta function) + OUTPUT: list of pairs `(s, L(s))`, where the `s` are equally spaced + sampled points on the line from `s_0` to `s_1` EXAMPLES:: @@ -276,7 +256,6 @@ def values_along_line(self, s0, s1, number_samples, L=''): 2.0 sage: values[4][1] # abs tol 1e-8 0.552975867 + 0.0*I - """ L = self._compute_L(L) CC = ComplexField(prec) @@ -301,22 +280,15 @@ def twist_values(self, s, dmin, dmax, L=''): INPUT: + - ``s`` -- complex numbers - - ``s`` -- complex numbers + - ``dmin`` -- integer - - ``dmin`` -- integer + - ``dmax`` -- integer - - ``dmax`` -- integer - - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - - - OUTPUT: - - - - ``list`` -- list of pairs (d, L(s,chi_d)) + - ``L`` -- defines `L`-function (default: Riemann zeta function) + OUTPUT: list of pairs `(d, L(s,\chi_d))` EXAMPLES:: @@ -372,23 +344,16 @@ def twist_zeros(self, n, dmin, dmax, L=''): INPUT: + - ``n`` -- integer - - ``n`` -- integer - - - ``dmin`` -- integer + - ``dmin`` -- integer - - ``dmax`` -- integer + - ``dmax`` -- integer - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - - - OUTPUT: - - - - ``dict`` -- keys are the discriminants `d`, - and values are list of corresponding zeros. + - ``L`` -- defines `L`-function (default: Riemann zeta function) + OUTPUT: dictionary; keys are the discriminants `d`, and values are list + of corresponding zeros EXAMPLES:: @@ -421,14 +386,11 @@ def analytic_rank(self, L=''): INPUT: - - - ``L`` -- defines `L`-function (default: - Riemann zeta function) - + - ``L`` -- defines `L`-function (default: Riemann zeta function) OUTPUT: integer - .. note:: + .. NOTE:: Of course this is not provably correct in general, since it is an open problem to compute analytic ranks provably diff --git a/src/sage/lfunctions/meson.build b/src/sage/lfunctions/meson.build new file mode 100644 index 00000000000..cf0ffe05e17 --- /dev/null +++ b/src/sage/lfunctions/meson.build @@ -0,0 +1,22 @@ +py.install_sources( + 'all.py', + 'dokchitser.py', + 'lcalc.py', + 'pari.py', + 'sympow.py', + subdir: 'sage/lfunctions', +) + +extension_data = {'zero_sums' : files('zero_sums.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/lfunctions', + install: true, + include_directories: [inc_flint], + dependencies: [py_dep, flint, gmp], + ) +endforeach + diff --git a/src/sage/lfunctions/pari.py b/src/sage/lfunctions/pari.py index 807f48efea6..db07629dcfd 100644 --- a/src/sage/lfunctions/pari.py +++ b/src/sage/lfunctions/pari.py @@ -1,7 +1,7 @@ """ `L`-functions from PARI -This is a wrapper around the general PARI L-functions functionality. +This is a wrapper around the general PARI `L`-functions functionality. AUTHORS: @@ -26,7 +26,7 @@ from sage.rings.power_series_ring import PowerSeriesRing -class lfun_generic(): +class lfun_generic: r""" Create a PARI `L`-function (:pari:`lfun` instance). @@ -36,10 +36,10 @@ class lfun_generic(): where - - ``conductor`` -- integer, the conductor + - ``conductor`` -- integer; the conductor - ``gammaV`` -- list of Gamma-factor parameters, e.g. [0] for - Riemann zeta, [0,1] for ell.curves, (see examples). + Riemann zeta, [0,1] for ell.curves, (see examples) - ``weight`` -- positive real number, usually an integer e.g. 1 for Riemann zeta, 2 for `H^1` of curves/`\QQ` @@ -51,7 +51,7 @@ class lfun_generic(): included - ``residues`` -- vector of residues of `L^*(s)` in those poles or - set residues='automatic' (default value) + set ``residues='automatic'`` (default) - ``init`` -- list of coefficients @@ -63,7 +63,7 @@ class lfun_generic(): sage: lf = lfun_generic(conductor=1, gammaV=[0], weight=1, eps=1, poles=[1], residues=[1]) sage: lf.init_coeffs([1]*2000) - Now we can wrap this PARI L-function into one Sage L-function:: + Now we can wrap this PARI `L`-function into one Sage `L`-function:: sage: L = LFunction(lf); L L-series of conductor 1 and weight 1 @@ -118,11 +118,11 @@ def init_coeffs(self, v, cutoff=None, w=1): INPUT: - - ``v`` -- list of complex numbers or unary function + - ``v`` -- list of complex numbers or unary function - - ``cutoff`` -- unused + - ``cutoff`` -- unused - - ``w`` -- list of complex numbers or unary function + - ``w`` -- list of complex numbers or unary function EXAMPLES:: @@ -131,8 +131,8 @@ def init_coeffs(self, v, cutoff=None, w=1): sage: pari_coeffs = pari('k->vector(k,n,(5*sigma(n,3)+7*sigma(n,5))*n/12 - 35*sum(k=1,n-1,(6*k-4*(n-k))*sigma(k,3)*sigma(n-k,5)))') sage: lf.init_coeffs(pari_coeffs) - Evaluate the resulting L-function at a point, and compare with - the answer that one gets "by definition" (of L-function + Evaluate the resulting `L`-function at a point, and compare with + the answer that one gets "by definition" (of `L`-function attached to a modular form):: sage: L = LFunction(lf) @@ -182,7 +182,7 @@ def init_coeffs(self, v, cutoff=None, w=1): def __pari__(self): """ - Return the PARI L-function object. + Return the PARI `L`-function object. EXAMPLES:: @@ -205,14 +205,12 @@ def __pari__(self): def lfun_character(chi): """ - Create the L-function of a primitive Dirichlet character. + Create the `L`-function of a primitive Dirichlet character. If the given character is not primitive, it is replaced by its associated primitive character. - OUTPUT: - - one :pari:`lfun` object + OUTPUT: one :pari:`lfun` object EXAMPLES:: @@ -256,11 +254,9 @@ def lfun_character(chi): def lfun_hgm(motif, t): """ - Create the L-function of an hypergeometric motive. - - OUTPUT: + Create the `L`-function of an hypergeometric motive. - one :pari:`lfun` object + OUTPUT: one :pari:`lfun` object EXAMPLES:: @@ -278,11 +274,9 @@ def lfun_hgm(motif, t): def lfun_elliptic_curve(E): """ - Create the L-function of an elliptic curve. + Create the `L`-function of an elliptic curve. - OUTPUT: - - one :pari:`lfun` object + OUTPUT: one :pari:`lfun` object EXAMPLES:: @@ -309,9 +303,7 @@ def lfun_number_field(K): """ Create the Dedekind zeta function of a number field. - OUTPUT: - - one :pari:`lfun` object + OUTPUT: one :pari:`lfun` object EXAMPLES:: @@ -333,15 +325,15 @@ def lfun_number_field(K): def lfun_eta_quotient(scalings, exponents): """ - Return the L-function of an eta-quotient. + Return the `L`-function of an eta-quotient. This uses :pari:`lfunetaquo`. INPUT: - - scalings -- a list of integers, the scaling factors + - ``scalings`` -- list of integers; the scaling factors - - exponents -- a list of integers, the exponents + - ``exponents`` -- list of integers; the exponents EXAMPLES:: @@ -368,7 +360,7 @@ def lfun_eta_quotient(scalings, exponents): def lfun_delta(): """ - Return the L-function of Ramanujan's Delta modular form. + Return the `L`-function of Ramanujan's Delta modular form. EXAMPLES:: @@ -382,7 +374,7 @@ def lfun_delta(): def lfun_quadratic_form(qf): """ - Return the L-function of a positive definite quadratic form. + Return the `L`-function of a positive definite quadratic form. This uses :pari:`lfunqf`. @@ -401,7 +393,7 @@ def lfun_quadratic_form(qf): def lfun_genus2(C): """ - Return the L-function of a curve of genus 2. + Return the `L`-function of a curve of genus 2. INPUT: @@ -444,14 +436,14 @@ def lfun_genus2(C): class LFunction(SageObject): r""" - Build the L-function from a PARI L-function. + Build the `L`-function from a PARI `L`-function. .. RUBRIC:: Rank 1 elliptic curve We compute with the `L`-series of a rank `1` curve. :: sage: E = EllipticCurve('37a') - sage: L = E.lseries().dokchitser(algorithm="pari"); L + sage: L = E.lseries().dokchitser(algorithm='pari'); L PARI L-function associated to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: L(1) 0.000000000000000 @@ -472,7 +464,7 @@ class LFunction(SageObject): `L`-series of a rank `2` elliptic curve:: sage: E = EllipticCurve('389a') - sage: L = E.lseries().dokchitser(algorithm="pari") + sage: L = E.lseries().dokchitser(algorithm='pari') sage: L.num_coeffs() 163 sage: L.derivative(1, E.rank()) @@ -486,7 +478,7 @@ class LFunction(SageObject): sage: x = var('x') sage: K = NumberField(x**4 - x**2 - 1,'a') - sage: L = K.zeta_function(algorithm="pari") + sage: L = K.zeta_function(algorithm='pari') sage: L.conductor 400 sage: L.num_coeffs() @@ -515,12 +507,12 @@ class LFunction(SageObject): """ def __init__(self, lfun, prec=None): """ - Initialization of the L-function from a PARI L-function. + Initialization of the `L`-function from a PARI `L`-function. INPUT: - - lfun -- a PARI :pari:`lfun` object or an instance of :class:`lfun_generic` - - prec -- integer (default: 53) number of *bits* of precision + - ``lfun`` -- a PARI :pari:`lfun` object or an instance of :class:`lfun_generic` + - ``prec`` -- integer (default: 53); number of *bits* of precision EXAMPLES:: @@ -592,11 +584,11 @@ def num_coeffs(self, T=1): EXAMPLES:: sage: E = EllipticCurve('11a') - sage: L = E.lseries().dokchitser(algorithm="pari") + sage: L = E.lseries().dokchitser(algorithm='pari') sage: L.num_coeffs() 27 sage: E = EllipticCurve('5077a') - sage: L = E.lseries().dokchitser(algorithm="pari") + sage: L = E.lseries().dokchitser(algorithm='pari') sage: L.num_coeffs() 591 @@ -612,7 +604,7 @@ def num_coeffs(self, T=1): def Lambda(self, s): """ - Evaluate the completed L-function at s. + Evaluate the completed `L`-function at s. EXAMPLES:: @@ -653,13 +645,13 @@ def hardy(self, t): def derivative(self, s, D=1): """ - Return the derivative of the L-function at point s and order D. + Return the derivative of the `L`-function at point s and order D. INPUT: - - ``s`` -- complex number + - ``s`` -- complex number - - ``D`` -- optional integer (default 1) + - ``D`` -- integer (default: 1) EXAMPLES:: @@ -681,13 +673,11 @@ def taylor_series(self, s, k=6, var='z'): INPUT: - - ``s`` -- complex number; point about which to expand + - ``s`` -- complex number; point about which to expand - - ``k`` -- optional integer (default: 6), series is - `O(``var``^k)` + - ``k`` -- integer (default: 6); series is `O(``var``^k)` - - ``var`` -- optional string (default: 'z'), variable of power - series + - ``var`` -- string (default: ``'z'``); variable of power series EXAMPLES:: @@ -697,7 +687,7 @@ def taylor_series(self, s, k=6, var='z'): sage: L.taylor_series(2, 3) 1.64493406684823 - 0.937548254315844*z + 0.994640117149451*z^2 + O(z^3) sage: E = EllipticCurve('37a') - sage: L = E.lseries().dokchitser(algorithm="pari") + sage: L = E.lseries().dokchitser(algorithm='pari') sage: L.taylor_series(1) 0.000000000000000 + 0.305999773834052*z + 0.186547797268162*z^2 - 0.136791463097188*z^3 + 0.0161066468496401*z^4 + 0.0185955175398802*z^5 + O(z^6) @@ -705,7 +695,7 @@ def taylor_series(self, s, k=6, var='z'): precision:: sage: E = EllipticCurve('389a') - sage: L = E.lseries().dokchitser(200,algorithm="pari") + sage: L = E.lseries().dokchitser(200,algorithm='pari') sage: L.taylor_series(1, 3) 2...e-63 + (...e-63)*z + 0.75931650028842677023019260789472201907809751649492435158581*z^2 + O(z^3) @@ -751,11 +741,11 @@ def _clear_value_cache(self): def __call__(self, s): r""" - Return the value of the L-function at point ``s``. + Return the value of the `L`-function at point ``s``. INPUT: - - ``s`` -- complex number + - ``s`` -- complex number .. NOTE:: @@ -766,7 +756,7 @@ def __call__(self, s): EXAMPLES:: sage: E = EllipticCurve('5077a') - sage: L = E.lseries().dokchitser(100, algorithm="pari") + sage: L = E.lseries().dokchitser(100, algorithm='pari') sage: L(1) 0.00000000000000000000000000000 sage: L(1 + I) diff --git a/src/sage/lfunctions/sympow.py b/src/sage/lfunctions/sympow.py index f500221e398..8368b150eab 100644 --- a/src/sage/lfunctions/sympow.py +++ b/src/sage/lfunctions/sympow.py @@ -2,11 +2,11 @@ Watkins symmetric power `L`-function calculator SYMPOW is a package to compute special values of symmetric power -elliptic curve L-functions. It can compute up to about 64 digits of +elliptic curve `L`-functions. It can compute up to about 64 digits of precision. This interface provides complete access to sympow, which is a standard part of Sage (and includes the extra data files). -.. note:: +.. NOTE:: Each call to ``sympow`` runs a complete ``sympow`` process. This incurs about 0.2 seconds @@ -56,7 +56,7 @@ class Sympow(SageObject): r""" - Watkins Symmetric Power `L`-function Calculator + Watkins Symmetric Power `L`-function Calculator. Type ``sympow.[tab]`` for a list of useful commands that are implemented using the command line interface, but return @@ -100,22 +100,15 @@ def L(self, E, n, prec): INPUT: + - ``E`` -- elliptic curve - - ``E`` -- elliptic curve + - ``n`` -- even integer - - ``n`` -- even integer + - ``prec`` -- integer - - ``prec`` -- integer + OUTPUT: real number to prec digits of precision as a string - - OUTPUT: - - - - ``string`` -- real number to prec digits of precision - as a string. - - - .. note:: + .. NOTE:: Before using this function for the first time for a given `n`, you may have to type ``sympow('-new_data n')``, @@ -156,26 +149,24 @@ def L(self, E, n, prec): def Lderivs(self, E, n, prec, d): r""" - Return `0^{th}` to `d^{th}` derivatives of + Return `0`-th to `d`-th derivatives of `L(\mathrm{Sym}^{(n)}(E,s)` to prec digits of precision, where `s` is the right edge if `n` is even and the center if `n` is odd. INPUT: + - ``E`` -- elliptic curve - - ``E`` -- elliptic curve - - - ``n`` -- integer (even or odd) - - - ``prec`` -- integer + - ``n`` -- integer (even or odd) - - ``d`` -- integer + - ``prec`` -- integer + - ``d`` -- integer - OUTPUT: a string, exactly as output by sympow + OUTPUT: string, exactly as output by sympow - .. note:: + .. NOTE:: To use this function you may have to run a few commands like ``sympow('-new_data 1d2')``, each which takes a @@ -207,15 +198,11 @@ def modular_degree(self, E): INPUT: - - - ``E`` -- elliptic curve over Q - + - ``E`` -- elliptic curve over Q OUTPUT: - - - ``integer`` -- modular degree - + - ``integer`` -- modular degree EXAMPLES: We compute the modular degrees of the lowest known conductor curves of the first few ranks:: @@ -246,24 +233,20 @@ def analytic_rank(self, E): INPUT: - - - ``E`` -- elliptic curve over Q - + - ``E`` -- elliptic curve over Q OUTPUT: + - ``integer`` -- analytic rank - - ``integer`` -- analytic rank - - - ``string`` -- leading coefficient (as string) + - ``string`` -- leading coefficient (as string) - .. note:: + .. NOTE:: - The analytic rank is *not* computed provably correctly in - general. + The analytic rank is *not* computed provably correctly in general. - .. note:: + .. NOTE:: In computing the analytic rank we consider `L^{(r)}(E,1)` to be `0` if @@ -303,7 +286,7 @@ def analytic_rank(self, E): def new_data(self, n): """ - Pre-compute data files needed for computation of n-th symmetric + Pre-compute data files needed for computation of `n`-th symmetric powers. """ print(self('-new_data %s' % n)) @@ -376,11 +359,11 @@ def help(self): sympow('-new_data 6d0h') -will add the data for the 0th derivative of the 6th Hecke power, and +will add the data for the `0`-th derivative of the `6`-th Hecke power, and sympow('-new_data 4c') -will add data for the 4th symmetric power for curves with CM +will add data for the `4`-th symmetric power for curves with CM (these need to be done separately for powers divisible by 4). The mesh files are stored in binary form, and thus endian-ness is a diff --git a/src/sage/lfunctions/zero_sums.pyx b/src/sage/lfunctions/zero_sums.pyx index ce1d06f118c..cefed0fd4ef 100644 --- a/src/sage/lfunctions/zero_sums.pyx +++ b/src/sage/lfunctions/zero_sums.pyx @@ -44,9 +44,8 @@ cdef NCPUS cdef class LFunctionZeroSum_abstract(SageObject): r""" - Abstract class for computing certain sums over zeros of a motivic L-function + Abstract class for computing certain sums over zeros of a motivic `L`-function without having to determine the zeros themselves. - """ cdef _pi # Pi to 64 bits cdef _euler_gamma # Euler-Mascheroni constant = 0.5772... @@ -61,16 +60,14 @@ cdef class LFunctionZeroSum_abstract(SageObject): Set or return the number of CPUs to be used in parallel computations. If called with no input, the number of CPUs currently set is returned; - else this value is set to n. If n is 0 then the number of CPUs is set + else this value is set to `n`. If `n` is 0 then the number of CPUs is set to the max available. INPUT: - - ``n`` -- (default: ``None``) If not ``None``, a nonnegative integer - - OUTPUT: + - ``n`` -- (default: ``None``) if not ``None``, a nonnegative integer - If n is not ``None``, returns a positive integer + OUTPUT: if `n` is not ``None``, returns a positive integer EXAMPLES:: @@ -144,9 +141,9 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - - ``include_euler_gamma`` -- bool (default: ``True``); if set to + - ``include_euler_gamma`` -- boolean (default: ``True``); if set to ``False``, return the constant `\log(N)/2 - \log(2\pi)`, i.e., do - not subtract off the Euler-Mascheroni constant. + not subtract the Euler-Mascheroni constant EXAMPLES:: @@ -165,20 +162,18 @@ cdef class LFunctionZeroSum_abstract(SageObject): Return a list of Dirichlet coefficient of the logarithmic derivative of the `L`-function attached to ``self``, shifted so that the critical line lies on the imaginary axis, up to and - including n. + including `n`. - The i-th element of the returned list is a[i]. + The `i`-th element of the returned list is ``a[i]``. INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer - - ``python_floats`` -- bool (default: ``False``); if ``True`` return a list of - Python floats instead of Sage Real Double Field elements. - - OUTPUT: + - ``python_floats`` -- boolean (default: ``False``); if ``True`` return + a list of Python floats instead of Sage Real Double Field elements - A list of real numbers + OUTPUT: list of real numbers .. SEEALSO:: @@ -224,13 +219,12 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - - ``s`` -- A complex number + - ``s`` -- complex number - - ``include_constant_term`` -- (default: ``True``) boolean; if set - to ``False``, - only the value of the sum over `k` is returned without subtracting - off the Euler-Mascheroni constant, i.e. the returned value is - equal to `\sum_{k=1}^{\infty} \frac{s-1}{k(k+s-1)}`. + - ``include_constant_term`` -- boolean (default: ``True``); if set + to ``False``, only the value of the sum over `k` is returned without + subtracting the Euler-Mascheroni constant, i.e., the returned value + is equal to `\sum_{k=1}^{\infty} \frac{s-1}{k(k+s-1)}` OUTPUT: @@ -298,10 +292,10 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - - ``s`` -- Real or complex value + - ``s`` -- real or complex value - - ``num_terms`` -- (default: 10000) the maximum number of terms - summed in the Dirichlet series. + - ``num_terms`` -- integer (default: 10000); the maximum number of + terms summed in the Dirichlet series OUTPUT: @@ -410,10 +404,10 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - - ``s`` -- Real or complex value + - ``s`` -- real or complex value - - ``num_terms`` -- (default: 10000) the maximum number of terms - summed in the Dirichlet series. + - ``num_terms`` -- integer (default: 10000); the maximum number of + terms summed in the Dirichlet series OUTPUT: @@ -457,7 +451,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): Ls = self.logarithmic_derivative(2 - s, num_terms) return (-self._C1 - self.digamma(2 - s) - Ls[0], Ls[1]) - def zerosum(self, Delta=1, tau=0, function="sincsquared_fast", ncpus=None): + def zerosum(self, Delta=1, tau=0, function='sincsquared_fast', ncpus=None): r""" Bound from above the analytic rank of the form attached to ``self``. @@ -473,7 +467,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - ``Delta`` -- positive real number (default: 1) parameter denoting the - tightness of the zero sum. + tightness of the zero sum - ``tau`` -- real parameter (default: 0) denoting the offset of the sum to be computed. When `\tau=0` the sum will converge to the analytic rank @@ -483,27 +477,27 @@ cdef class LFunctionZeroSum_abstract(SageObject): Currently only implemented for the sincsquared and cauchy functions; otherwise ignored. - - ``function`` -- string (default: "sincsquared_fast"); the function + - ``function`` -- string (default: ``'sincsquared_fast'``); the function `f(x)` as described above. Currently implemented options for `f` are - ``sincsquared`` -- `f(x) = \left(\frac{\sin(\pi x)}{\pi x}\right)^2` - - ``gaussian`` -- `f(x) = e^{-x^2}` + - ``gaussian`` -- `f(x) = e^{-x^2}` - - ``sincsquared_fast`` -- Same as "sincsquared", but implementation + - ``sincsquared_fast`` -- same as "sincsquared", but implementation optimized for elliptic curve `L`-functions, and tau must be 0. self must be attached to an elliptic curve over `\QQ` given by its global minimal model, otherwise the returned result will be incorrect. - - ``sincsquared_parallel`` -- Same as "sincsquared_fast", but optimized - for parallel computation with large (>2.0) `\Delta` values. self must + - ``sincsquared_parallel`` -- same as "sincsquared_fast", but optimized + for parallel computation with large (>2.0) `\Delta` values. ``self`` must be attached to an elliptic curve over `\QQ` given by its global minimal model, otherwise the returned result will be incorrect. - ``cauchy`` -- `f(x) = \frac{1}{1+x^2}`; this is only computable to - low precision, and only when `\Delta < 2`. + low precision, and only when `\Delta < 2` - - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer + - ``ncpus`` -- (default: ``None``) if not ``None``, a positive integer defining the number of CPUs to be used for the computation. If left as ``None``, the maximum available number of CPUs will be used. Only implemented for algorithm="sincsquared_parallel"; ignored @@ -536,17 +530,17 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z = LFunctionZeroSum(E) sage: E.lseries().zeros(3) [0.000000000, 0.000000000, 2.87609907] - sage: Z.zerosum(Delta=1,function="sincsquared_fast") # tol 1.0e-13 + sage: Z.zerosum(Delta=1,function='sincsquared_fast') # tol 1.0e-13 2.037500084595065 - sage: Z.zerosum(Delta=1,function="sincsquared_parallel") # tol 1.0e-11 + sage: Z.zerosum(Delta=1,function='sincsquared_parallel') # tol 1.0e-11 2.037500084595065 - sage: Z.zerosum(Delta=1,function="sincsquared") # tol 1.0e-13 + sage: Z.zerosum(Delta=1,function='sincsquared') # tol 1.0e-13 2.0375000845950644 - sage: Z.zerosum(Delta=1,tau=2.876,function="sincsquared") # tol 1.0e-13 + sage: Z.zerosum(Delta=1,tau=2.876,function='sincsquared') # tol 1.0e-13 1.075551295651154 - sage: Z.zerosum(Delta=1,tau=1.2,function="sincsquared") # tol 1.0e-13 + sage: Z.zerosum(Delta=1,tau=1.2,function='sincsquared') # tol 1.0e-13 0.10831555377490683 - sage: Z.zerosum(Delta=1,function="gaussian") # tol 1.0e-13 + sage: Z.zerosum(Delta=1,function='gaussian') # tol 1.0e-13 2.056890425029435 """ # If Delta>6.95, then exp(2*pi*Delta)>sys.maxsize, so we get overflow @@ -582,7 +576,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - ``Delta`` -- positive real number (default: 1) parameter denoting the - tightness of the zero sum. + tightness of the zero sum - ``tau`` -- real parameter (default: 0) denoting the offset of the sum to be computed. When tau=0 the sum will converge from above to the @@ -698,7 +692,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): def _zerosum_gaussian(self, Delta=1): r""" - Return an upper bound on the analytic rank of the L-series attached + Return an upper bound on the analytic rank of the `L`-series attached to ``self`` by computing `\sum_{\gamma} f(\Delta*\gamma)`, where `\gamma` ranges over the imaginary parts of the zeros of `L_E(s)` along the critical strip, and `f(x) = \exp(-x^2)`. @@ -784,8 +778,8 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - - ``Delta`` -- positive real number (default: 1) parameter denoting the - tightness of the zero sum. + - ``Delta`` -- positive real number (default: 1); parameter denoting the + tightness of the zero sum - ``tau`` -- real parameter (default: 0) denoting the offset of the sum to be computed. When tau=0 the sum will converge from above to the @@ -794,8 +788,8 @@ cdef class LFunctionZeroSum_abstract(SageObject): be 1 (assuming GRH, the zero is simple); otherwise the limit will be 0. - - ``num_terms`` -- positive integer (default: ``None``): the number of - terms computed in the truncated Dirichlet series for the L-function + - ``num_terms`` -- positive integer (default: ``None``); the number of + terms computed in the truncated Dirichlet series for the `L`-function attached to ``self``. If left at ``None``, this is set to `\ceil(e^{2 \pi \Delta})`, the same number of terms used in the other zero sum methods for this value of Delta. @@ -896,7 +890,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): r""" - Subclass for computing certain sums over zeros of an elliptic curve L-function + Subclass for computing certain sums over zeros of an elliptic curve `L`-function without having to determine the zeros themselves. """ cdef _E # The Elliptic curve attached to self @@ -904,18 +898,18 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): def __init__(self, E, N=None, ncpus=1): r""" - Initialize self. + Initialize ``self``. INPUT: - - ``E`` -- An elliptic curve defined over the rational numbers + - ``E`` -- an elliptic curve defined over the rational numbers - - ``N`` -- (default: ``None``) If not ``None``, a positive integer equal to + - ``N`` -- (default: ``None``) if not ``None``, a positive integer equal to the conductor of E. This is passable so that rank estimation can be done for curves whose (large) conductor has been precomputed. - - ``ncpus`` -- (default: 1) The number of CPUs to use for computations. - If set to ``None``, the max available amount will be used. + - ``ncpus`` -- (default: 1) the number of CPUs to use for computations; + if set to ``None``, the max available amount will be used EXAMPLES:: @@ -991,8 +985,8 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): def cn(self, n): r""" - Return the nth Dirichlet coefficient of the logarithmic - derivative of the L-function attached to ``self``, shifted so that + Return the `n`-th Dirichlet coefficient of the logarithmic + derivative of the `L`-function attached to ``self``, shifted so that the critical line lies on the imaginary axis. The returned value is @@ -1006,7 +1000,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer OUTPUT: @@ -1101,7 +1095,6 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): summand for the sinc^2 sum at prime values for when sqrt(bound) < n < bound, bound = exp(t) Called in self._zerosum_sincsquared_fast() method - """ ap = self._e.ellap(n) p = n @@ -1123,7 +1116,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): tightness of the zero sum, and thus the closeness of the returned estimate to the actual analytic rank of the form attached to ``self`` - - ``bad_primes`` -- (default: ``None``) If not ``None``, a list of primes dividing + - ``bad_primes`` -- (default: ``None``) if not ``None``, a list of primes dividing the level of the form attached to ``self``. This is passable so that this method can be run on curves whose conductor is large enough to warrant precomputing bad primes. @@ -1254,7 +1247,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): def _get_residue_data(self, n): r""" - Method called by self._zerosum_sincsquared_parallel() to determine + Method called by ``self._zerosum_sincsquared_parallel()`` to determine the optimal residue class breakdown when sieving for primes. Return a list of small primes, the product thereof, and a list of @@ -1262,19 +1255,19 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): INPUT: - - ``n`` -- Positive integer denoting the number of required chunks. + - ``n`` -- positive integer denoting the number of required chunks OUTPUT: A triple ``(small_primes, M, residue_chunks)`` such that - - ``small_primes`` -- a list of small primes + - ``small_primes`` -- list of small primes - ``modulus`` -- the product of the small primes - - ``residue_chunks`` -- a list of lists consisting of all integers - less than the modulus that are coprime to it, broken into n - sublists of approximately equal size. + - ``residue_chunks`` -- list of lists consisting of all integers + less than the modulus that are coprime to it, broken into `n` + sublists of approximately equal size EXAMPLES:: @@ -1401,12 +1394,12 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): tightness of the zero sum, and thus the closeness of the returned estimate to the actual analytic rank of the form attached to ``self``. - - ``bad_primes`` -- (default: ``None``) If not ``None``, a list of primes dividing + - ``bad_primes`` -- (default: ``None``) if not ``None``, a list of primes dividing the level of the form attached to ``self``. This is passable so that this method can be run on curves whose conductor is large enough to warrant precomputing bad primes. - - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer + - ``ncpus`` -- (default: ``None``) if not ``None``, a positive integer defining the number of CPUs to be used for the computation. If left as ``None``, the maximum available number of CPUs will be used. @@ -1435,7 +1428,6 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: Z = LFunctionZeroSum(E) sage: print(Z._zerosum_sincsquared_parallel(Delta=1.5,ncpus=2)) # tol 1.0e-11 0.01047120600865063 - """ # If Delta>6.619, then we will most likely get overflow: some ap values # will be too large to fit into a c int @@ -1524,11 +1516,11 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): def analytic_rank_upper_bound(self, max_Delta=None, adaptive=True, - root_number="compute", + root_number='compute', bad_primes=None, ncpus=None): r""" - Return an upper bound for the analytic rank of the L-function + Return an upper bound for the analytic rank of the `L`-function `L_E(s)` attached to ``self``, conditional on the Generalized Riemann Hypothesis, via computing the zero sum `\sum_{\gamma} f(\Delta\gamma)`, where `\gamma` ranges over the imaginary parts of the zeros of `L(E,s)` @@ -1544,7 +1536,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): INPUT: - - ``max_Delta`` -- (default: ``None``) If not ``None``, a positive real value + - ``max_Delta`` -- (default: ``None``) if not ``None``, a positive real value specifying the maximum Delta value used in the zero sum; larger values of Delta yield better bounds - but runtime is exponential in Delta. If left as ``None``, Delta is set @@ -1555,7 +1547,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): results show that for about 99.7% of all curves the returned value is the actual analytic rank. - - ``adaptive`` -- (default: ``True``) Boolean + - ``adaptive`` -- boolean (default: ``True``) - If ``True``, the computation is first run with small and then successively larger Delta values up to max_Delta. If at any @@ -1565,24 +1557,24 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): - If ``False``, the computation is run a single time with Delta=max_Delta, and the resulting bound returned. - - ``root_number`` -- (default: "compute") String or integer + - ``root_number`` -- (default: ``'compute'``) string or integer - - ``"compute"`` -- the root number of self is computed and used to - (possibly) lower the analytic rank estimate by 1. - - ``"ignore"`` -- the above step is omitted + - ``'compute'`` -- the root number of ``self`` is computed and used to + (possibly) lower the analytic rank estimate by 1 + - ``'ignore'`` -- the above step is omitted - ``1`` -- this value is assumed to be the root number of - self. This is passable so that rank estimation can be done for + ``self``. This is passable so that rank estimation can be done for curves whose root number has been precomputed. - ``-1`` -- this value is assumed to be the root number of - self. This is passable so that rank estimation can be done for + ``self``. This is passable so that rank estimation can be done for curves whose root number has been precomputed. - - ``bad_primes`` -- (default: ``None``) If not ``None``, a list of the primes + - ``bad_primes`` -- (default: ``None``) if not ``None``, a list of the primes of bad reduction for the curve attached to ``self``. This is passable so that rank estimation can be done for curves of large conductor whose bad primes have been precomputed. - - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer + - ``ncpus`` -- (default: ``None``) if not ``None``, a positive integer defining the maximum number of CPUs to be used for the computation. If left as ``None``, the maximum available number of CPUs will be used. Note: Multiple processors will only be used for Delta values >= 1.75. @@ -1601,9 +1593,9 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): OUTPUT: - A non-negative integer greater than or equal to the analytic rank of - self. If the returned value is 0 or 1 (the latter if parity is not - False), then this is the true analytic rank of self. + A nonnegative integer greater than or equal to the analytic rank of + ``self``. If the returned value is 0 or 1 (the latter if parity is not + ``False``), then this is the true analytic rank of ``self``. .. NOTE:: @@ -1645,7 +1637,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: for r in range(9): ....: E = elliptic_curves.rank(r)[0] ....: print((r, E.analytic_rank_upper_bound(max_Delta=1, - ....: adaptive=False,root_number="ignore"))) + ....: adaptive=False,root_number='ignore'))) (0, 0) (1, 1) (2, 2) @@ -1665,9 +1657,9 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: r = E.rank(); r 0 sage: Z = LFunctionZeroSum(E) - sage: Z.analytic_rank_upper_bound(max_Delta=1,root_number="ignore") + sage: Z.analytic_rank_upper_bound(max_Delta=1,root_number='ignore') 1 - sage: Z.analytic_rank_upper_bound(max_Delta=1.3,root_number="ignore") + sage: Z.analytic_rank_upper_bound(max_Delta=1.3,root_number='ignore') 0 Knowing the root number of E allows us to use smaller Delta values @@ -1675,7 +1667,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): :: - sage: Z.analytic_rank_upper_bound(max_Delta=0.6,root_number="compute") + sage: Z.analytic_rank_upper_bound(max_Delta=0.6,root_number='compute') 0 The are a small number of curves which have pathologically low-lying @@ -1819,12 +1811,10 @@ def LFunctionZeroSum(X, *args, **kwds): INPUT: - - ``X`` -- A motivic object. Currently only implemented for X = an elliptic curve - over the rational numbers. - - OUTPUT: + - ``X`` -- a motivic object; currently only implemented for X = an elliptic curve + over the rational numbers - An LFunctionZeroSum object. + OUTPUT: an LFunctionZeroSum object EXAMPLES:: diff --git a/src/sage/libs/arb/arith.pyx b/src/sage/libs/arb/arith.pyx index 8bc843aa2a3..bd498f13f43 100644 --- a/src/sage/libs/arb/arith.pyx +++ b/src/sage/libs/arb/arith.pyx @@ -69,7 +69,7 @@ def hilbert_class_polynomial(D): - ``D`` -- negative integer - OUTPUT: an integer polynomial. + OUTPUT: integer polynomial EXAMPLES:: diff --git a/src/sage/libs/arb/meson.build b/src/sage/libs/arb/meson.build new file mode 100644 index 00000000000..aa98fb8ff3a --- /dev/null +++ b/src/sage/libs/arb/meson.build @@ -0,0 +1,33 @@ +py.install_sources( + '__init__.py', + 'acb.pxd', + 'acb_calc.pxd', + 'acb_elliptic.pxd', + 'acb_hypgeom.pxd', + 'acb_mat.pxd', + 'acb_modular.pxd', + 'acb_poly.pxd', + 'arb.pxd', + 'arb_fmpz_poly.pxd', + 'arb_hypgeom.pxd', + 'arb_wrap.h', + 'arf.pxd', + 'bernoulli.pxd', + 'mag.pxd', + 'types.pxd', + subdir: 'sage/libs/arb', +) + +extension_data = {'arith' : files('arith.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/arb', + install: true, + include_directories: [inc_cpython, inc_flint, inc_rings], + dependencies: [py_dep, flint, gmp, mpfr], + ) +endforeach + diff --git a/src/sage/libs/braiding.pyx b/src/sage/libs/braiding.pyx index f3849a55d7e..fb856c918c9 100644 --- a/src/sage/libs/braiding.pyx +++ b/src/sage/libs/braiding.pyx @@ -66,7 +66,6 @@ def conjugatingbraid(braid1, braid2): sage: c = B([1,2]) sage: conjugatingbraid(b,c) [[0], [2]] - """ nstrands = max(braid1.parent().strands(), braid2.parent().strands()) l1 = braid1.Tietze() @@ -98,7 +97,6 @@ def leftnormalform(braid): sage: b = B([1,2,1,-2]) sage: leftnormalform(b) [[0], [2, 1]] - """ nstrands = braid.parent().strands() l1 = braid.Tietze() @@ -129,7 +127,6 @@ def rightnormalform(braid): sage: b = B([1,2,1,-2]) sage: rightnormalform(b) [[2, 1], [0]] - """ nstrands = braid.parent().strands() l1 = braid.Tietze() @@ -148,9 +145,7 @@ def greatestcommondivisor(braid1, braid2): - ``braid1`` -- a braid - ``braid2`` -- a braid - OUTPUT: - - A list of lists representing the gcd of ``braid1`` and ``braid2``. + OUTPUT: list of lists representing the gcd of ``braid1`` and ``braid2`` EXAMPLES:: @@ -160,7 +155,6 @@ def greatestcommondivisor(braid1, braid2): sage: b2 = B([2, 2, 2]) sage: greatestcommondivisor(b1, b2) [[-1], [2, 1]] - """ nstrands = max(braid1.parent().strands(), braid2.parent().strands()) l1 = braid1.Tietze() @@ -180,9 +174,7 @@ def leastcommonmultiple(braid1, braid2): - ``braid1`` -- a braid - ``braid2`` -- a braid - OUTPUT: - - A list of lists representing the lcm of ``braid1`` and ``braid2``. + OUTPUT: list of lists representing the lcm of ``braid1`` and ``braid2`` EXAMPLES:: @@ -222,7 +214,6 @@ def centralizer(braid): sage: b = B([1,2,-1]) sage: centralizer(b) [[[-1], [2, 1], [1, 2]], [[0], [1], [1, 2], [2]]] - """ nstrands = braid.parent().strands() lnf = leftnormalform(braid) @@ -248,9 +239,7 @@ def supersummitset(braid): - ``braid`` -- a braid - OUTPUT: - - A list of lists representing the super summit set of ``braid``. + OUTPUT: list of lists representing the super summit set of ``braid`` EXAMPLES:: @@ -259,7 +248,6 @@ def supersummitset(braid): sage: b = B([1,2,-1]) sage: supersummitset(b) [[[0], [2]], [[0], [1]]] - """ nstrands = braid.parent().strands() l = braid.Tietze() @@ -345,9 +333,7 @@ def rigidity(braid): - ``braid`` -- a braid - OUTPUT: - - The rigidity of the braid. + OUTPUT: the rigidity of the braid EXAMPLES:: @@ -356,7 +342,6 @@ def rigidity(braid): sage: c = B([1,1,1,2,2]) sage: rigidity(c) 3 - """ nstrands = braid.parent().strands() l = braid.Tietze() diff --git a/src/sage/libs/coxeter3/coxeter.pyx b/src/sage/libs/coxeter3/coxeter.pyx index 0ce4f0a9b10..6f8a651e7eb 100644 --- a/src/sage/libs/coxeter3/coxeter.pyx +++ b/src/sage/libs/coxeter3/coxeter.pyx @@ -55,7 +55,7 @@ cdef class String: def __hash__(self): """ - Return the hash of this String + Return the hash of this String. This is the hash of the tuple consisting of the class name and the name of this type. @@ -595,9 +595,7 @@ cdef class CoxGroup(SageObject): - ``w`` -- a word for an element of ``self``, not necessarily reduced - OUTPUT: - - - a reduced expression for ``w`` + OUTPUT: a reduced expression for ``w`` EXAMPLES:: @@ -623,7 +621,6 @@ cdef class CoxGroup(SageObject): [2 3 1 3 2] [2 2 3 1 3] [2 2 2 3 1] - """ from sage.matrix.constructor import matrix rank = self.rank() @@ -750,13 +747,12 @@ cdef class CoxGroupElement: sage: w = W([1,2,3]) sage: w.parent_group() Coxeter group of type A and rank 5 - """ return self._parent_group def __getitem__(self, i): """ - Return the `i^{th}` entry of this element. + Return the `i`-th entry of this element. EXAMPLES:: @@ -798,7 +794,6 @@ cdef class CoxGroupElement: sage: W = CoxGroup(['A',5]) sage: w = W([1,2,3]); w [1, 2, 3] - """ return repr(list(self)) @@ -944,7 +939,7 @@ cdef class CoxGroupElement: def is_two_sided_descent(self, s): """ - Return whether ``s`` is a two sided descent of ``self``. + Return whether ``s`` is a two-sided descent of ``self``. EXAMPLES:: @@ -1006,7 +1001,6 @@ cdef class CoxGroupElement: [2, 1, 2] sage: w.normal_form() [1, 2, 1] - """ cdef CoxGroupElement res = self._new() self.group.normalForm(res.word) diff --git a/src/sage/libs/coxeter3/coxeter_group.py b/src/sage/libs/coxeter3/coxeter_group.py index 5fa494d4ea3..845feb2fd38 100644 --- a/src/sage/libs/coxeter3/coxeter_group.py +++ b/src/sage/libs/coxeter3/coxeter_group.py @@ -36,7 +36,6 @@ def __classcall__(cls, cartan_type, *args, **options): Coxeter group of type ['B', 2] implemented by Coxeter3 sage: CoxeterGroup(CartanType(['B', 3]).relabel({1: 3, 2: 2, 3: 1})) Coxeter group of type ['B', 3] relabelled by {1: 3, 2: 2, 3: 1} implemented by Coxeter3 - """ from sage.combinat.root_system.cartan_type import CartanType ct = CartanType(cartan_type) @@ -146,7 +145,6 @@ def one(self): sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') sage: W.one() [] - """ return self.element_class(self, []) @@ -194,7 +192,7 @@ def rank(self): def is_finite(self): """ - Return True if this is a finite Coxeter group. + Return ``True`` if this is a finite Coxeter group. EXAMPLES:: @@ -216,7 +214,6 @@ def length(self, x): 2 sage: W.length(W([1,1])) 0 - """ return x.length() @@ -237,7 +234,6 @@ def coxeter_matrix(self): [2 3 1] sage: m.index_set() == W.index_set() True - """ return CoxeterMatrix(self._coxgroup.coxeter_matrix(), self.index_set()) @@ -265,7 +261,6 @@ def _an_element_(self): sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') sage: W._an_element_() [] - """ return self.element_class(self, []) @@ -293,8 +288,9 @@ def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): INPUT: - ``u``, ``v`` -- elements of the underlying Coxeter group - - ``constant_term_one`` -- (default: ``True``) True uses the constant equals one convention, - False uses the Leclerc-Thibon convention + - ``constant_term_one`` -- boolean (default: ``True``); ``True`` uses + the constant equals one convention, ``False`` uses the Leclerc-Thibon + convention .. SEEALSO:: @@ -345,7 +341,7 @@ def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): We check that Coxeter3 and Sage's implementation give the same results:: sage: C = CoxeterGroup(['B', 3], implementation='coxeter3') - sage: W = WeylGroup("B3",prefix="s") + sage: W = WeylGroup("B3",prefix='s') sage: [s1,s2,s3] = W.simple_reflections() sage: R. = LaurentPolynomialRing(QQ) sage: KL = KazhdanLusztigPolynomial(W,q) @@ -540,7 +536,6 @@ def __getitem__(self, i): 1 sage: w0[1] 2 - """ # Allow the error message to be raised by the underlying element return self.value[i] @@ -625,7 +620,7 @@ def has_right_descent(self, i): def has_left_descent(self, i): """ - Return True if ``i`` is a left descent of this element. + Return ``True`` if ``i`` is a left descent of this element. EXAMPLES:: diff --git a/src/sage/libs/coxeter3/decl.pxd b/src/sage/libs/coxeter3/decl.pxd index 4f9c7b0c186..1f968c418bf 100644 --- a/src/sage/libs/coxeter3/decl.pxd +++ b/src/sage/libs/coxeter3/decl.pxd @@ -33,7 +33,6 @@ cdef extern from "coxeter/coxtypes.h" namespace "coxtypes": ctypedef unsigned short Length ctypedef Ulong StarOp # for numbering star operations - ################# # CoxWord # ################# diff --git a/src/sage/libs/coxeter3/meson.build b/src/sage/libs/coxeter3/meson.build new file mode 100644 index 00000000000..83cbd2b46cd --- /dev/null +++ b/src/sage/libs/coxeter3/meson.build @@ -0,0 +1,23 @@ +coxeter3 = cc.find_library('coxeter3', required: false, disabler: true) +py.install_sources( + '__init__.py', + 'all__sagemath_coxeter3.py', + 'coxeter.pxd', + 'coxeter_group.py', + 'decl.pxd', + subdir: 'sage/libs/coxeter3', +) + +extension_data_cpp = {'coxeter': files('coxeter.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/coxeter3', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [], + dependencies: [py_dep, cysignals, coxeter3], + ) +endforeach diff --git a/src/sage/libs/ecl.pxd b/src/sage/libs/ecl.pxd index 19472171403..202d0824e37 100644 --- a/src/sage/libs/ecl.pxd +++ b/src/sage/libs/ecl.pxd @@ -147,7 +147,6 @@ cdef extern from "ecl/ecl.h": ecl_character ecl_char(cl_object s, cl_index i) ecl_character ecl_char_set(cl_object s, cl_index i, ecl_character c) - # S-expr evaluation and function calls cl_object cl_safe_eval(cl_object form, cl_object env, cl_object value) diff --git a/src/sage/libs/ecl.pyx b/src/sage/libs/ecl.pyx index 1cc38a3ab3a..aaede566da6 100644 --- a/src/sage/libs/ecl.pyx +++ b/src/sage/libs/ecl.pyx @@ -26,7 +26,7 @@ from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational from cpython.object cimport Py_EQ, Py_NE -# it would be preferrable to let bint_symbolp wrap an efficient macro +# it would be preferable to let bint_symbolp wrap an efficient macro # but the macro provided in object.h doesn't seem to work cdef bint bint_symbolp(cl_object obj) noexcept: return not(cl_symbolp(obj) == ECL_NIL) @@ -140,7 +140,7 @@ def test_sigint_before_ecl_sig_on(): def test_ecl_options(): """ - Print an overview of the ECL options + Print an overview of the ECL options. TESTS:: @@ -386,7 +386,7 @@ def shutdown_ecl(): # these should be all non-immediate EclObject wrapped objects def print_objects(): r""" - Print GC-protection list + Print GC-protection list. Diagnostic function. ECL objects that are bound to Python objects need to be protected from being garbage collected. We do this by including them @@ -666,7 +666,6 @@ cdef class EclObject: sage: EclObject('"Mαξιμα"') - """ cdef cl_object obj # the wrapped object cdef cl_object node # linked list pointer: car(node) == obj @@ -681,7 +680,7 @@ cdef class EclObject: def __init__(self, *args): r""" - Create an EclObject + Create an EclObject. See EclObject for full documentation. @@ -690,7 +689,6 @@ cdef class EclObject: sage: from sage.libs.ecl import * sage: EclObject([None,true,false]) - """ if not args: return @@ -703,7 +701,7 @@ cdef class EclObject: def __reduce__(self): r""" - This is used for pickling. Not implemented + This is used for pickling. Not implemented. Ecl does not natively support serialization of its objects, so the python wrapper class EclObject does not support pickling. There are @@ -735,13 +733,12 @@ cdef class EclObject: sage: L = EclObject([1,2,("three",'"four"')]) sage: L.python() [1, 2, ('THREE', '"four"')] - """ return ecl_to_python(self.obj) def __dealloc__(self): r""" - Deallocate EclObject + Deallocate EclObject. It is important to remove the GC preventing reference to the object upon deletion of the wrapper. @@ -751,7 +748,6 @@ cdef class EclObject: sage: from sage.libs.ecl import * sage: L=EclObject("symbol") sage: del L - """ if self.node: remove_node(self.node) @@ -769,7 +765,6 @@ cdef class EclObject: sage: L=EclObject("symbol") sage: repr(L) '' - """ return "" @@ -786,7 +781,6 @@ cdef class EclObject: sage: L=EclObject("symbol") sage: str(L) 'SYMBOL' - """ cdef cl_object s s = cl_write_to_string(1, self.obj) @@ -794,7 +788,7 @@ cdef class EclObject: def __hash__(self): r""" - Return a hash value of the object + Return a hash value of the object. Returns the hash value returned by SXHASH, which is a routine that is specified in Common Lisp. According to the specification, lisp objects that @@ -818,13 +812,12 @@ cdef class EclObject: sage: hash(L) #random 140404060 - """ return ecl_fixint(cl_sxhash(self.obj)) def __call__(self, *args): r""" - Apply self to arguments. + Apply ``self`` to arguments. EXAMPLES:: @@ -832,7 +825,6 @@ cdef class EclObject: sage: sqr=EclObject("(lambda (x) (* x x))").eval() sage: sqr(10) - """ lispargs = EclObject(list(args)) return ecl_wrap(ecl_safe_apply(self.obj, (lispargs).obj)) @@ -879,7 +871,7 @@ cdef class EclObject: def __iter__(self): r""" - Implements the iterator protocol for EclObject. + Implement the iterator protocol for EclObject. EclObject implements the iterator protocol for lists. This means one can use an EclObject in the context where an iterator is @@ -926,13 +918,12 @@ cdef class EclObject: Traceback (most recent call last): ... TypeError: ECL object is not iterable - """ return EclListIterator(self) def eval(self): r""" - Evaluate object as an S-Expression + Evaluate object as an S-Expression. EXAMPLES:: @@ -942,7 +933,6 @@ cdef class EclObject: sage: S.eval() - """ cdef cl_object o o=ecl_safe_eval(self.obj) @@ -952,7 +942,7 @@ cdef class EclObject: def cons(self, EclObject d): r""" - apply cons to self and argument and return the result. + Apply cons to ``self`` and argument and return the result. EXAMPLES:: @@ -961,7 +951,6 @@ cdef class EclObject: sage: b=EclObject(2) sage: a.cons(b) - """ return ecl_wrap(cl_cons(self.obj, d.obj)) @@ -979,7 +968,6 @@ cdef class EclObject: sage: L.rplaca(a) sage: L - """ if not(bint_consp(self.obj)): raise TypeError("rplaca can only be applied to a cons") @@ -999,7 +987,6 @@ cdef class EclObject: sage: L.rplacd(a) sage: L - """ if not(bint_consp(self.obj)): raise TypeError("rplacd can only be applied to a cons") @@ -1007,7 +994,7 @@ cdef class EclObject: def car(self): r""" - Return the car of self + Return the car of ``self``. EXAMPLES:: @@ -1032,7 +1019,7 @@ cdef class EclObject: def cdr(self): r""" - Return the cdr of self + Return the cdr of ``self``. EXAMPLES:: @@ -1057,7 +1044,7 @@ cdef class EclObject: def caar(self): r""" - Return the caar of self + Return the caar of ``self``. EXAMPLES:: @@ -1082,7 +1069,7 @@ cdef class EclObject: def cadr(self): r""" - Return the cadr of self + Return the cadr of ``self``. EXAMPLES:: @@ -1107,7 +1094,7 @@ cdef class EclObject: def cdar(self): r""" - Return the cdar of self + Return the cdar of ``self``. EXAMPLES:: @@ -1132,7 +1119,7 @@ cdef class EclObject: def cddr(self): r""" - Return the cddr of self + Return the cddr of ``self``. EXAMPLES:: @@ -1157,7 +1144,7 @@ cdef class EclObject: def fixnump(self): r""" - Return True if self is a fixnum, False otherwise + Return ``True`` if ``self`` is a fixnum, ``False`` otherwise. EXAMPLES:: @@ -1166,13 +1153,12 @@ cdef class EclObject: True sage: EclObject(2**200).fixnump() False - """ return bint_fixnump(self.obj) def characterp(self): r""" - Return True if self is a character, False otherwise + Return ``True`` if ``self`` is a character, ``False`` otherwise. Strings are not characters @@ -1181,13 +1167,12 @@ cdef class EclObject: sage: from sage.libs.ecl import * sage: EclObject('"a"').characterp() False - """ return bint_characterp(self.obj) def nullp(self): r""" - Return True if self is NIL, False otherwise + Return ``True`` if ``self`` is NIL, ``False`` otherwise. EXAMPLES:: @@ -1201,7 +1186,7 @@ cdef class EclObject: def listp(self): r""" - Return True if self is a list, False otherwise. NIL is a list. + Return ``True`` if ``self`` is a list, ``False`` otherwise. NIL is a list. EXAMPLES:: @@ -1215,7 +1200,7 @@ cdef class EclObject: def consp(self): r""" - Return True if self is a cons, False otherwise. NIL is not a cons. + Return ``True`` if ``self`` is a cons, ``False`` otherwise. NIL is not a cons. EXAMPLES:: @@ -1229,7 +1214,7 @@ cdef class EclObject: def atomp(self): r""" - Return True if self is atomic, False otherwise. + Return ``True`` if ``self`` is atomic, ``False`` otherwise. EXAMPLES:: @@ -1238,13 +1223,12 @@ cdef class EclObject: True sage: EclObject([[]]).atomp() False - """ return bint_atomp(self.obj) def symbolp(self): r""" - Return True if self is a symbol, False otherwise. + Return ``True`` if ``self`` is a symbol, ``False`` otherwise. EXAMPLES:: @@ -1253,7 +1237,6 @@ cdef class EclObject: True sage: EclObject([[]]).symbolp() False - """ return bint_symbolp(self.obj) @@ -1279,13 +1262,12 @@ cdef class EclListIterator: Traceback (most recent call last): ... TypeError: ECL object is not iterable - """ cdef EclObject current def __init__(EclListIterator self, EclObject o): r""" - Initialize EclListIterator + Initialize EclListIterator. EXAMPLES:: @@ -1293,7 +1275,6 @@ cdef class EclListIterator: sage: I=EclListIterator(EclObject("(1 2 3)")) sage: type(I) - """ if not o.listp(): raise TypeError("ECL object is not iterable") @@ -1301,7 +1282,7 @@ cdef class EclListIterator: def __iter__(EclListIterator self): r""" - Return self + Return ``self``. It seems standard that iterators return themselves if asked to produce an iterator. @@ -1312,13 +1293,12 @@ cdef class EclListIterator: sage: I=EclListIterator(EclObject("(1 2 3)")) sage: id(I) == id(I.__iter__()) True - """ return self def __next__(EclListIterator self): r""" - Get next element from iterator + Get next element from iterator. EXAMPLES:: @@ -1334,7 +1314,6 @@ cdef class EclListIterator: Traceback (most recent call last): ... StopIteration - """ if self.current.nullp(): @@ -1356,7 +1335,7 @@ cdef EclObject ecl_wrap(cl_object o): # convenience routine to more easily evaluate strings cpdef EclObject ecl_eval(str s): r""" - Read and evaluate string in Lisp and return the result + Read and evaluate string in Lisp and return the result. EXAMPLES:: @@ -1374,7 +1353,6 @@ cpdef EclObject ecl_eval(str s): sage: _(4711) - """ cdef cl_object o o = ecl_safe_eval(python_to_ecl(s, True)) diff --git a/src/sage/libs/eclib/constructor.py b/src/sage/libs/eclib/constructor.py index 4a782cf5a61..79d28b90c1c 100644 --- a/src/sage/libs/eclib/constructor.py +++ b/src/sage/libs/eclib/constructor.py @@ -6,10 +6,12 @@ def CremonaModularSymbols(level, sign=0, cuspidal=False, verbose=0): INPUT: - - ``level`` -- an integer >= 2 (at least 2, not just positive!) - - ``sign`` -- an integer either 0 (the default) or 1 or -1. - - ``cuspidal`` -- (default: ``False``); if True, compute only the cuspidal subspace - - ``verbose`` -- (default: ``False``): if True, print verbose information while creating space + - ``level`` -- integer; at least 2, not just positive! + - ``sign`` -- integer (default: 0); either 0 or 1 or -1 + - ``cuspidal`` -- boolean (default: ``False``); if ``True``, compute only + the cuspidal subspace + - ``verbose`` -- boolean (default: ``False``); if ``True``, print verbose + information while creating space EXAMPLES:: @@ -44,7 +46,7 @@ def CremonaModularSymbols(level, sign=0, cuspidal=False, verbose=0): sage: M Cremona Modular Symbols space of dimension 7 for Gamma_0(43) of weight 2 with sign 0 - The input must be valid or a :class:`ValueError` is raised:: + The input must be valid or a :exc:`ValueError` is raised:: sage: M = CremonaModularSymbols(-1) Traceback (most recent call last): diff --git a/src/sage/libs/eclib/homspace.pyx b/src/sage/libs/eclib/homspace.pyx index d9bb6150540..a502062ff79 100644 --- a/src/sage/libs/eclib/homspace.pyx +++ b/src/sage/libs/eclib/homspace.pyx @@ -29,10 +29,10 @@ cdef class ModularSymbols: INPUT: - - ``level`` (int) -- the level: an integer, at least 2. - - ``sign`` (int, default 0) -- the sign: 0, +1 or -1 - - ``cuspidal`` (boolean, default: ``False``) -- True for cuspidal homology - - ``verbose`` (int, default 0) -- verbosity level + - ``level`` -- integer; the level: at least 2 + - ``sign`` -- integer (default: 0); the sign: 0, +1 or -1 + - ``cuspidal`` -- boolean (default: ``False``); ``True`` for cuspidal homology + - ``verbose`` -- integer (default: 0); verbosity level EXAMPLES:: @@ -164,11 +164,11 @@ cdef class ModularSymbols: - ``p`` -- a prime number - - ``dual`` -- (default: ``False``) whether to compute the Hecke - operator acting on the dual space, i.e., the - transpose of the Hecke operator + - ``dual`` -- boolean (default: ``False``); whether to compute the + Hecke operator acting on the dual space, i.e., the transpose of the + Hecke operator - - ``verbose`` -- (default: ``False``) print verbose output + - ``verbose`` -- boolean (default: ``False``); print verbose output OUTPUT: @@ -224,11 +224,11 @@ cdef class ModularSymbols: - ``p`` -- a prime number - - ``dual`` -- (default: ``False``) whether to compute the Hecke - operator acting on the dual space, i.e., the - transpose of the Hecke operator + - ``dual`` -- boolean (default: ``False``); whether to compute the + Hecke operator acting on the dual space, i.e., the transpose of the Hecke + operator - - ``verbose`` -- (default: ``False``) print verbose output + - ``verbose`` -- boolean (default: ``False``); print verbose output OUTPUT: diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index 6c15997c09f..a5e65a37d4d 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -9,7 +9,7 @@ :class:`EllipticCurve ` and call methods that are implemented using this module. -.. note:: +.. NOTE:: This interface is a direct library-level interface to ``eclib``, including the 2-descent program ``mwrank``. @@ -47,10 +47,10 @@ class mwrank_EllipticCurve(SageObject): INPUT: - - ``ainvs`` (list or tuple) -- a list of 5 or less integers, the - coefficients of a nonsingular Weierstrass equation. + - ``ainvs`` -- list or tuple list of 5 or less integers, the + coefficients of a nonsingular Weierstrass equation - - ``verbose`` (bool, default ``False``) -- verbosity flag. If ``True``, + - ``verbose`` -- boolean (default: ``False``); verbosity flag. If ``True``, then all Selmer group computations will be verbose. EXAMPLES: @@ -146,8 +146,8 @@ def set_verbose(self, verbose): INPUT: - - ``verbose`` (int) -- if positive, print lots of output when - doing 2-descent. + - ``verbose`` -- integer; if positive, print lots of output when + doing 2-descent EXAMPLES:: @@ -196,7 +196,7 @@ def set_verbose(self, verbose): def _curve_data(self): r""" - Returns the underlying :class:`_Curvedata` class for this mwrank elliptic curve. + Return the underlying :class:`_Curvedata` class for this mwrank elliptic curve. EXAMPLES:: @@ -212,7 +212,7 @@ def _curve_data(self): def ainvs(self): r""" - Returns the `a`-invariants of this mwrank elliptic curve. + Return the `a`-invariants of this mwrank elliptic curve. EXAMPLES:: @@ -224,7 +224,7 @@ def ainvs(self): def isogeny_class(self, verbose=False): r""" - Returns the isogeny class of this mwrank elliptic curve. + Return the isogeny class of this mwrank elliptic curve. EXAMPLES:: @@ -236,7 +236,7 @@ def isogeny_class(self, verbose=False): def __repr__(self): r""" - Returns the string representation of this mwrank elliptic curve. + Return the string representation of this mwrank elliptic curve. EXAMPLES:: @@ -256,42 +256,34 @@ def __repr__(self): ' '.join([coeff(a4), 'x']) if a4 else '', ' '.join([" +" if a6 > 0 else " -", str(abs(a6))]) if a6 else '']) - def two_descent(self, - verbose=True, - selmer_only=False, - first_limit=20, - second_limit=8, - n_aux=-1, - second_descent=True): + def two_descent(self, verbose=True, selmer_only=False, first_limit=20, + second_limit=8, n_aux=-1, second_descent=True): r""" Compute 2-descent data for this curve. INPUT: - - ``verbose`` (bool, default ``True``) -- print what mwrank is doing. + - ``verbose`` -- boolean (default: ``True``); print what mwrank is doing - - ``selmer_only`` (bool, default ``False``) -- ``selmer_only`` switch. + - ``selmer_only`` -- boolean (default: ``False``); ``selmer_only`` switch - - ``first_limit`` (int, default 20) -- bound on `|x|+|z|` in - quartic point search. + - ``first_limit`` -- integer (default: 20); bound on `|x|+|z|` in + quartic point search - - ``second_limit`` (int, default 8) -- bound on - `\log \max(|x|,|z|)`, i.e. logarithmic. + - ``second_limit`` -- integer (default: 8); bound on + `\log \max(|x|,|z|)`, i.e. logarithmic - - ``n_aux`` (int, default -1) -- (only relevant for general + - ``n_aux`` -- integer (default: -1); (only relevant for general 2-descent when 2-torsion trivial) number of primes used for quartic search. ``n_aux=-1`` causes default (8) to be used. Increase for curves of higher rank. - - ``second_descent`` (bool, default ``True``) -- (only relevant + - ``second_descent`` -- boolean (default: ``True``); (only relevant for curves with 2-torsion, where mwrank uses descent via 2-isogeny) flag determining whether or not to do second descent. *Default strongly recommended.* - - OUTPUT: - - Nothing -- nothing is returned. + OUTPUT: nothing TESTS: @@ -357,7 +349,7 @@ def two_descent(self, def __two_descent_data(self): r""" - Returns the 2-descent data for this elliptic curve. + Return the 2-descent data for this elliptic curve. EXAMPLES:: @@ -374,7 +366,7 @@ def conductor(self): Return the conductor of this curve, computed using Cremona's implementation of Tate's algorithm. - .. note:: + .. NOTE:: This is independent of PARI's. @@ -388,7 +380,7 @@ def conductor(self): def rank(self): """ - Returns the rank of this curve, computed using :meth:`two_descent()`. + Return the rank of this curve, computed using :meth:`two_descent()`. In general this may only be a lower bound for the rank; an upper bound may be obtained using the function :meth:`rank_bound()`. @@ -410,13 +402,12 @@ def rank(self): 0 sage: E.certain() False - """ return self.__two_descent_data().getrank() def rank_bound(self): """ - Returns an upper bound for the rank of this curve, computed + Return an upper bound for the rank of this curve, computed using :meth:`two_descent()`. If the curve has no 2-torsion, this is equal to the 2-Selmer @@ -460,13 +451,12 @@ def rank_bound(self): 0 sage: E.certain() False - """ return self.__two_descent_data().getrankbound() def selmer_rank(self): r""" - Returns the rank of the 2-Selmer group of the curve. + Return the rank of the 2-Selmer group of the curve. EXAMPLES: @@ -510,7 +500,6 @@ def selmer_rank(self): 0 sage: E.certain() False - """ return self.__two_descent_data().getselmer() @@ -536,13 +525,13 @@ def saturate(self, bound=-1, lower=2): INPUT: - - ``bound`` (int, default -1) -- If `-1`, saturate at *all* + - ``bound`` -- integer (default: -1); if `-1`, saturate at *all* primes by computing a bound on the saturation index, otherwise saturate at all primes up to the minimum of - ``bound`` and the saturation index bound. + ``bound`` and the saturation index bound - - ``lower`` (int, default 2) -- Only saturate at primes not - less than this. + - ``lower`` -- integer (default: 2); only saturate at primes not + less than this EXAMPLES: @@ -584,7 +573,7 @@ def gens(self) -> list: def certain(self): r""" - Returns ``True`` if the last :meth:`two_descent()` call provably correctly + Return ``True`` if the last :meth:`two_descent()` call provably correctly computed the rank. If :meth:`two_descent()` hasn't been called, then it is first called by :meth:`certain()` using the default parameters. @@ -675,21 +664,21 @@ class mwrank_MordellWeil(SageObject): INPUT: - - ``curve`` (:class:`mwrank_EllipticCurve`) -- the underlying - elliptic curve. + - ``curve`` -- :class:`mwrank_EllipticCurve`; the underlying + elliptic curve - - ``verbose`` (bool, default ``False``) -- verbosity flag (controls - amount of output produced in point searches). + - ``verbose`` -- boolean (default: ``False``); verbosity flag (controls + amount of output produced in point searches) - - ``pp`` (int, default 1) -- process points flag (if nonzero, + - ``pp`` -- integer (default: 1); process points flag (if nonzero, the points found are processed, so that at all times only a `\ZZ`-basis for the subgroup generated by the points found - so far is stored; if zero, no processing is done and all + so far is stored. If zero, no processing is done and all points found are stored). - - ``maxr`` (int, default 999) -- maximum rank (quit point + - ``maxr`` -- integer (default: 999); maximum rank (quit point searching once the points found generate a subgroup of this - rank; useful if an upper bound for the rank is already + rank. Useful if an upper bound for the rank is already known). EXAMPLES:: @@ -850,13 +839,13 @@ def process(self, v, saturation_bound=0): INPUT: - - ``v`` (list of 3-tuples or lists of ints or Integers) -- a + - ``v`` -- list of 3-tuples or lists of ints or Integers; a list of triples of integers, which define points on the - curve. + curve - - ``saturation_bound`` (int, default 0) -- saturate at primes up to - ``saturation_bound``, or at *all* primes if ``saturation_bound`` is -1; when ``saturation_bound`` - is 0 (the default), do no saturation.. + - ``saturation_bound`` -- integer (default: 0); saturate at primes up to + ``saturation_bound``, or at *all* primes if ``saturation_bound`` is + -1. When ``saturation_bound`` is 0 (the default), do no saturation. OUTPUT: @@ -1000,7 +989,7 @@ def regulator(self): Return the regulator of the points in this subgroup of the Mordell-Weil group. - .. note:: + .. NOTE:: ``eclib`` can compute the regulator to arbitrary precision, but the interface currently returns the output as a ``float``. @@ -1025,9 +1014,7 @@ def rank(self): """ Return the rank of this subgroup of the Mordell-Weil group. - OUTPUT: - - (int) The rank of this subgroup of the Mordell-Weil group. + OUTPUT: integer EXAMPLES:: @@ -1067,7 +1054,6 @@ def rank(self): 0.417143558758384 We do in fact now have a full Mordell-Weil basis. - """ return self.__mw.rank() @@ -1076,13 +1062,13 @@ def saturate(self, max_prime=-1, min_prime=2): INPUT: - - ``max_prime`` (int, default -1) -- If `-1` (the default), an + - ``max_prime`` -- integer (default: -1); if `-1`, an upper bound is computed for the primes at which the subgroup may not be saturated, and saturation is performed for all primes up to this bound. Otherwise, the bound used is the minimum of ``max_prime`` and the computed bound. - - ``min_prime`` (int, default 2) -- only do saturation at + - ``min_prime`` -- integer (default: 2); only do saturation at primes no less than this. (For example, if the points have been found via :meth:`two_descent` they should already be 2-saturated so a value of 3 is appropriate.) @@ -1091,18 +1077,18 @@ def saturate(self, max_prime=-1, min_prime=2): (3-tuple) (``ok``, ``index``, ``unsatlist``) where: - - ``ok`` (bool) -- ``True`` if and only if the saturation was + - ``ok`` -- boolean; ``True`` if and only if the saturation was provably successful at all primes attempted. If the default was used for ``max_prime``, then ``True`` indicates that the subgroup is saturated at *all* primes. - - ``index`` (int) -- the index of the group generated by the - original points in their saturation. + - ``index`` -- integer; the index of the group generated by the + original points in their saturation - - ``unsatlist`` (list of ints) -- list of primes at which - saturation could not be proved or achieved. + - ``unsatlist`` -- list of ints list of primes at which + saturation could not be proved or achieved - .. note:: + .. NOTE:: In versions up to v20190909, ``eclib`` used floating point methods based on elliptic logarithms to divide points, and @@ -1111,7 +1097,7 @@ def saturate(self, max_prime=-1, min_prime=2): on division polynomials, which should mean that such failures does not happen. - .. note:: + .. NOTE:: We emphasize that if this function returns ``True`` as the first return argument (``ok``), and if the default was used @@ -1230,7 +1216,6 @@ def saturate(self, max_prime=-1, min_prime=2): index of the points in their saturation is at most 3, then proves saturation at 2 and at 3, by reducing the points modulo all primes of good reduction up to 11, respectively 13. - """ ok, index, unsat = self.__mw.saturate(int(max_prime), int(min_prime)) return bool(ok), int(str(index)), unsat @@ -1242,10 +1227,10 @@ def search(self, height_limit=18, verbose=False): INPUT: - - ``height_limit`` (float, default: 18) -- search up to this - logarithmic height. + - ``height_limit``-- float (default: 18); search up to this + logarithmic height - .. note:: + .. NOTE:: On 32-bit machines, this *must* be < 21.48 (`31\log(2)`) else `\exp(h_{\text{lim}}) > 2^{31}` and overflows. On 64-bit machines, it @@ -1254,15 +1239,15 @@ def search(self, height_limit=18, verbose=False): by (roughly) `\exp(1.5)=4.5`, so searching up to even 20 takes a very long time. - .. note:: + .. NOTE:: The search is carried out with a quadratic sieve, using code adapted from a version of Michael Stoll's ``ratpoints`` program. It would be preferable to use a newer version of ``ratpoints``. - - ``verbose`` (bool, default ``False``) -- turn verbose operation on - or off. + - ``verbose`` -- boolean (default: ``False``)turn verbose operation on + or off EXAMPLES: @@ -1311,11 +1296,9 @@ def points(self): Return a list of the generating points in this Mordell-Weil group. - OUTPUT: - - (list) A list of lists of length 3, each holding the + OUTPUT: list of lists of length 3, each holding the primitive integer coordinates `[x,y,z]` of a generating - point. + point EXAMPLES:: diff --git a/src/sage/libs/eclib/mat.pyx b/src/sage/libs/eclib/mat.pyx index e43fd01cec6..a5ef4f45c68 100644 --- a/src/sage/libs/eclib/mat.pyx +++ b/src/sage/libs/eclib/mat.pyx @@ -151,7 +151,7 @@ cdef class Matrix: def add_scalar(self, scalar s): """ - Return new matrix obtained by adding s to each diagonal entry of self. + Return new matrix obtained by adding `s` to each diagonal entry of ``self``. EXAMPLES:: @@ -193,7 +193,7 @@ cdef class Matrix: INPUT: - - ``sparse`` -- (default: ``True``) whether the return matrix has + - ``sparse`` -- boolean (default: ``True``); whether the return matrix has a sparse representation EXAMPLES:: diff --git a/src/sage/libs/eclib/meson.build b/src/sage/libs/eclib/meson.build new file mode 100644 index 00000000000..dd6ecc3f581 --- /dev/null +++ b/src/sage/libs/eclib/meson.build @@ -0,0 +1,31 @@ +py.install_sources( + '__init__.pxd', + '__init__.py', + 'all.py', + 'constructor.py', + 'homspace.pxd', + 'interface.py', + 'mat.pxd', + 'newforms.pxd', + subdir: 'sage/libs/eclib', +) + +extension_data_cpp = { + 'homspace': files('homspace.pyx'), + 'mat': files('mat.pyx'), + 'mwrank': files('mwrank.pyx'), + 'newforms': files('newforms.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/eclib', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ext, inc_flint, inc_ntl, inc_rings], + dependencies: [py_dep, cysignals, ec, flint, gmp], + ) +endforeach + diff --git a/src/sage/libs/eclib/mwrank.pyx b/src/sage/libs/eclib/mwrank.pyx index c4f9ed87d18..6765ac296ed 100644 --- a/src/sage/libs/eclib/mwrank.pyx +++ b/src/sage/libs/eclib/mwrank.pyx @@ -85,9 +85,7 @@ def get_precision(): Return the working floating point bit precision of mwrank, which is equal to the global NTL real number precision. - OUTPUT: - - (int) The current precision in bits. + OUTPUT: integer; the current precision in bits See also :meth:`set_precision`. @@ -101,7 +99,7 @@ def get_precision(): def set_precision(n): """ - Sets the working floating point bit precision of mwrank, which is + Set the working floating point bit precision of mwrank, which is equal to the global NTL real number precision. NTL real number bit precision. This has a massive effect on the @@ -111,7 +109,7 @@ def set_precision(n): INPUT: - - ``n`` -- a positive integer: the number of bits of precision. + - ``n`` -- positive integer; the number of bits of precision .. warning:: @@ -146,9 +144,9 @@ def initprimes(filename, verb=False): INPUT: - - ``filename`` (string) -- the name of a file of primes. + - ``filename`` -- string; the name of a file of primes - - ``verb`` (bool: default ``False``) -- verbose or not? + - ``verb`` -- boolean (default: ``False``); verbose or not EXAMPLES:: @@ -187,7 +185,7 @@ cdef class _bigint: """ cdef bigint* x - def __init__(self, x="0"): + def __init__(self, x='0'): """ Constructor for bigint class. @@ -252,18 +250,16 @@ cdef make_bigint(bigint* x): cdef class _Curvedata: # cython class wrapping eclib's Curvedata class cdef Curvedata* x - def __init__(self, a1, a2, a3, - a4, a6, min_on_init=0): + def __init__(self, a1, a2, a3, a4, a6, min_on_init=0): """ Constructor for Curvedata class. INPUT: - - ``a1``, ``a2``, ``a3``, ``a4``, ``a6`` (int) -- integer - coefficients of a Weierstrass equation (must be - nonsingular). + - ``a1``, ``a2``, ``a3``, ``a4``, ``a6`` -- integer coefficients of a + Weierstrass equation (must be nonsingular) - - ``min_on_init`` (int, default 0) -- flag controlling whether + - ``min_on_init`` -- integer (default: 0); flag controlling whether the constructed curve is replaced by a global minimal model. If nonzero then this minimisation does take place. @@ -312,11 +308,7 @@ cdef class _Curvedata: # cython class wrapping eclib's Curvedata class def __repr__(self): r""" - String representation of Curvedata - - OUTPUT: - - (string) the Curvedata as a string + String representation of Curvedata. EXAMPLES:: @@ -340,7 +332,7 @@ cdef class _Curvedata: # cython class wrapping eclib's Curvedata class OUTPUT: - (float) A non-negative real number `B` such that for every + (float) A nonnegative real number `B` such that for every rational point on this elliptic curve `E`, `h(P)\le\hat{h}(P) + B`, where `h(P)` is the naive height and `\hat{h}(P)` the canonical height. @@ -369,7 +361,7 @@ cdef class _Curvedata: # cython class wrapping eclib's Curvedata class OUTPUT: - (float) A non-negative real number `B` such that for every + (float) A nonnegative real number `B` such that for every rational point on this elliptic curve `E`, `h(P)\le\hat{h}(P) + B`, where `h(P)` is the naive height and `\hat{h}(P)` the canonical height. @@ -403,7 +395,7 @@ cdef class _Curvedata: # cython class wrapping eclib's Curvedata class OUTPUT: - (float) A non-negative real number `B` such that for every + (float) A nonnegative real number `B` such that for every rational point on this elliptic curve `E`, `h(P)\le\hat{h}(P) + B`, where `h(P)` is the naive height and `\hat{h}(P)` the canonical height. This is the minimum of the Silverman and @@ -492,7 +484,6 @@ cdef class _Curvedata: # cython class wrapping eclib's Curvedata class 14 sage: E.isogeny_class() ([[1, 0, 1, 4, -6], [1, 0, 1, -36, -70], [1, 0, 1, -1, 0], [1, 0, 1, -171, -874], [1, 0, 1, -11, 12], [1, 0, 1, -2731, -55146]], [[0, 2, 3, 3, 0, 0], [2, 0, 0, 0, 3, 3], [3, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2], [0, 3, 2, 0, 0, 0], [0, 3, 0, 2, 0, 0]]) - """ sig_on() s = string_sigoff(Curvedata_isogeny_class(self.x, verbose)) @@ -507,12 +498,11 @@ def parse_point_list(s): INPUT: - - ``s`` (string) -- string representation of a list of points, for - example '[]', '[[1:2:3]]', or '[[1:2:3],[4:5:6]]'. + - ``s`` -- string representation of a list of points; for + example '[]', '[[1:2:3]]', or '[[1:2:3],[4:5:6]]' - OUTPUT: - - (list) a list of triples of integers, for example [], [[1,2,3]], [[1,2,3],[4,5,6]]. + OUTPUT: list of triples of integers, for example [], [[1,2,3]], + [[1,2,3],[4,5,6]] EXAMPLES:: @@ -523,7 +513,6 @@ def parse_point_list(s): [[1, 2, 3]] sage: parse_point_list('[[1:2:3],[4:5:6]]') [[1, 2, 3], [4, 5, 6]] - """ s = s.replace(":", ",").replace(" ", "") if s == '[]': @@ -546,21 +535,20 @@ cdef class _mw: INPUT: - - ``curve`` (_Curvedata) -- an elliptic curve + - ``curve`` -- _Curvedata; an elliptic curve - - ``verb`` (bool, default ``False``) -- verbosity flag (controls + - ``verb`` -- boolean (default: ``False``); verbosity flag (controls amount of output produced in point searches) - - ``pp`` (int, default 1) -- process points flag (if nonzero, + - ``pp`` -- integer (default: 1); process points flag (if nonzero, the points found are processed, so that at all times only a `\ZZ`-basis for the subgroup generated by the points found - so far is stored; if zero, no processing is done and all + so far is stored. If zero, no processing is done and all points found are stored). - - ``maxr`` (int, default 999) -- maximum rank (quit point + - ``maxr`` -- integer (default: 999); maximum rank (quit point searching once the points found generate a subgroup of this - rank; useful if an upper bound for the rank is already - known). + rank. Useful if an upper bound for the rank is already known). EXAMPLES:: @@ -649,7 +637,6 @@ cdef class _mw: sage: EQ = _mw(E, pp=0) sage: EQ.search(1); EQ [[-3:0:1], [-2:3:1], [-14:25:8], [-1:3:1], [0:2:1], [2:13:8], [1:0:1], [2:0:1], [18:7:8], [3:3:1], [4:6:1], [36:69:64], [68:-25:64], [12:35:27]] - """ self.curve = curve.x self.x = new mw(curve.x, verb, pp, maxr) @@ -690,16 +677,15 @@ cdef class _mw: INPUT: - - ``point`` (tuple or list) -- tuple or list of 3 integers. - An ``ArithmeticError`` is raised if the point is not on the - curve. + - ``point`` -- tuple or list of 3 integers; an :exc:`ArithmeticError` is + raised if the point is not on the curve - - ``saturation_bound`` (int, default 0) --saturate at primes up to ``saturation_bound``. - No saturation is done if ``saturation_bound=0``. If ``saturation_bound=-1`` then + - ``saturation_bound`` -- integer (default: 0); saturate at primes up + to ``saturation_bound``. No saturation is done if + ``saturation_bound=0``. If ``saturation_bound=-1`` then saturation is done at all primes, by computing a bound on the saturation index. Note that it is more efficient to add - several points at once and then saturate just once at the - end. + several points at once and then saturate just once at the end. .. NOTE:: @@ -738,7 +724,6 @@ cdef class _mw: sage: EQ.process([4,8,1]) sage: EQ [[-1:1:1], [0:-1:1]] - """ if not isinstance(point, (tuple, list)) and len(point) == 3: raise TypeError("point must be a list or tuple of length 3.") @@ -838,14 +823,14 @@ cdef class _mw: INPUT: - - ``sat_bnd`` (int, default -1) -- upper bound on primes at + - ``sat_bnd`` -- integer (default: -1); upper bound on primes at which to saturate. If -1 (default), compute a bound for the primes which may not be saturated, and use that. Otherwise, the bound used is the minimum of the value of ``sat_bnd`` and the computed bound. - - ``sat_low_bd`` (int, default 2) -- only do saturation at - prime not less than this. For exampe, if the points have + - ``sat_low_bd`` -- integer (default: 2); only do saturation at + prime not less than this. For example, if the points have been found via 2-descent they should already be 2-saturated, and ``sat_low_bd=3`` is appropriate. @@ -896,7 +881,6 @@ cdef class _mw: (1, 1, '[ ]') sage: EQ [[494:-5720:6859]] - """ cdef long index cdef char* s @@ -912,13 +896,13 @@ cdef class _mw: INPUT: - - ``h_lim`` (int) -- bound on logarithmic naive height of points + - ``h_lim`` -- integer; bound on logarithmic naive height of points - - ``moduli_option`` (int, default 0) -- option for sieving + - ``moduli_option`` -- integer (default: 0); option for sieving strategy. The default (0) uses an adapted version of Stoll's ratpoints code and is recommended. - - ``verb`` (int, default 0) -- level of verbosity. If 0, no + - ``verb`` -- integer (default: 0); level of verbosity. If 0, no output. If positive, the points are output as found and some details of the processing, finding linear relations, and partial saturation are output. @@ -932,9 +916,7 @@ cdef class _mw: will always contain a `\ZZ`-span of the saturation of the points found, modulo torsion. - OUTPUT: - - None. The effect of the search is to update the list of generators. + OUTPUT: none; the effect of the search is to update the list of generators EXAMPLES:: @@ -1001,25 +983,25 @@ cdef class _two_descent: INPUT: - - ``curvedata`` (_Curvedata) -- the curve on which to do descent. + - ``curvedata`` -- _Curvedata; the curve on which to do descent - - ``verb`` (int, default 1) -- verbosity level. + - ``verb`` -- integer (default: 1); verbosity level - - ``sel`` (int, default 0) -- Selmer-only flag. If 1, only + - ``sel`` -- integer (default: 0); Selmer-only flag. If 1, only the 2-Selmer group will be computed, with no rational points. Useful as a faster way of getting an upper bound on the rank. - - ``firstlim`` (int, default 20) -- naive height bound on + - ``firstlim`` -- integer (default: 20); naive height bound on first point search on quartic homogeneous spaces (before testing local solubility; very simple search with no overheads). - - ``secondlim`` (int, default 8) -- naive height bound on + - ``secondlim`` -- integer (default: 8); naive height bound on second point search on quartic homogeneous spaces (after testing local solubility; sieve-assisted search) - - ``n_aux`` (int, default -1) -- If positive, the number of + - ``n_aux`` -- integer (default: -1); if positive, the number of auxiliary primes used in sieve-assisted search for quartics. If -1 (the default) use a default value (set in the eclib code in ``src/qrank/mrank1.cc`` in DEFAULT_NAUX: currently 8). @@ -1028,15 +1010,13 @@ cdef class _two_descent: expected to be of rank > 6 to one or two more than the expected rank. - - ``second_descent`` (int, default 1) -- flag specifying + - ``second_descent`` -- integer (default: 1); flag specifying whether or not a second descent will be carried out (yes if 1, the default; no if 0). Only relevant for curves with 2-torsion. Recommended left as the default except for experts interested in details of Selmer groups. - OUTPUT: - - None + OUTPUT: none EXAMPLES:: @@ -1167,9 +1147,7 @@ cdef class _two_descent: """ Return the success flag (after doing a 2-descent). - OUTPUT: - - (bool) Flag indicating whether or not 2-descent was successful. + OUTPUT: boolean flag indicating whether or not 2-descent was successful EXAMPLES:: @@ -1196,9 +1174,7 @@ cdef class _two_descent: """ Return the certainty flag (after doing a 2-descent). - OUTPUT: - - (bool) ``True`` if the rank upper and lower bounds are equal. + OUTPUT: boolean; ``True`` if the rank upper and lower bounds are equal EXAMPLES:: @@ -1227,18 +1203,16 @@ cdef class _two_descent: INPUT: - - ``saturation_bound`` (int) -- an upper bound on the primes + - ``saturation_bound`` -- integer; an upper bound on the primes `p` at which `p`-saturation will be carried out, or -1, in which case ``eclib`` will compute an upper bound on the saturation index. - - ``lower`` (int, default 3) -- do no `p`-saturation for `p` + - ``lower`` -- integer (default: 3); do no `p`-saturation for `p` less than this. The default is 3 since the points found during 2-descent will be 2-saturated. - OUTPUT: - - None. + OUTPUT: none EXAMPLES:: @@ -1280,7 +1254,7 @@ cdef class _two_descent: .. NOTE:: - You must call ``saturate()`` first, or a ``RunTimeError`` + You must call ``saturate()`` first, or a :exc:`RunTimeError` will be raised. OUTPUT: diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 65bd5412db5..d2af433a801 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -134,11 +134,11 @@ cdef class ECModularSymbol: - ``E``- an elliptic curve defined over Q. - - ``sign`` (int) -- 0 or +1. If +1, only plus modular symbols + - ``sign`` -- integer; 0 or +1. If +1, only plus modular symbols of this sign are available. If 0, modular symbols of both signs are available but the construction is more expensive. - - ``nap`` -- (int, default 1000): the number of ap of E to use + - ``nap`` -- integer (default: 1000); the number of ap of E to use in determining the normalisation of the modular symbols. Note that eclib will increase this to 100*sqrt(N) if necessary. @@ -240,18 +240,20 @@ cdef class ECModularSymbol: return "Modular symbol with sign %s over Rational Field attached to %s"%(self.sign, self._E) def __call__(self, r, sign=None, base_at_infinity=True): - """ - Computes the value of self on {0,r} or {oo,r} for rational r. + r""" + Compute the value of ``self`` on `\{0,r\}` or `\{\infty, r\}` for + rational `r`. INPUT: - - ``r`` (rational) -- a rational number + - ``r`` -- rational; a rational number - - ``sign`` (int) -- either +1, -1 or 0. If the sign of the - space is +1, only sign +1 is allowed. Default: self.sign, or +1 when self.sign=0. + - ``sign`` -- integer; either +1, -1 or 0. If the sign of the + space is +1, only sign +1 is allowed. Default: ``self.sign``, or +1 + when ``self.sign==0``. - - ``base_at_infinity`` (bool) -- if True, evaluates - {oo,r}. otherwise (default) evaluates {0,r}. + - ``base_at_infinity`` -- boolean; if ``True``, evaluates + `\{\infty, r\}`. Otherwise (default) evaluates `\{0,r\}`. OUTPUT: diff --git a/src/sage/libs/flint/fmpz_poly_sage.pyx b/src/sage/libs/flint/fmpz_poly_sage.pyx index d86d025a3e0..3904e397e27 100644 --- a/src/sage/libs/flint/fmpz_poly_sage.pyx +++ b/src/sage/libs/flint/fmpz_poly_sage.pyx @@ -87,9 +87,9 @@ cdef class Fmpz_poly(SageObject): sage: f[2] == 10**100000 True """ - if isinstance(value, Integer) : + if isinstance(value, Integer): fmpz_poly_set_coeff_mpz(self.poly, i, (value).value) - else : + else: fmpz_poly_set_coeff_si(self.poly, i, value) def __getitem__(self, i): @@ -111,7 +111,7 @@ cdef class Fmpz_poly(SageObject): def __repr__(self): """ - Print self according to the native FLINT format. + Print ``self`` according to the native FLINT format. EXAMPLES:: @@ -126,7 +126,7 @@ cdef class Fmpz_poly(SageObject): def degree(self): """ - The degree of self. + The degree of ``self``. EXAMPLES:: @@ -144,7 +144,7 @@ cdef class Fmpz_poly(SageObject): def list(self): """ - Return self as a list of coefficients, lowest terms first. + Return ``self`` as a list of coefficients, lowest terms first. EXAMPLES:: @@ -189,7 +189,7 @@ cdef class Fmpz_poly(SageObject): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. EXAMPLES:: @@ -239,7 +239,7 @@ cdef class Fmpz_poly(SageObject): def __pow__(self, n, dummy): """ - Return self raised to the power of n. + Return ``self`` raised to the power of `n`. EXAMPLES:: @@ -267,7 +267,7 @@ cdef class Fmpz_poly(SageObject): def pow_truncate(self, exp, n): """ - Return self raised to the power of exp mod x^n. + Return ``self`` raised to the power of ``exp`` mod `x^n`. EXAMPLES:: @@ -310,7 +310,7 @@ cdef class Fmpz_poly(SageObject): def div_rem(self, Fmpz_poly other): """ - Return self / other, self, % other. + Return ``self / other, self % other``. EXAMPLES:: @@ -336,9 +336,9 @@ cdef class Fmpz_poly(SageObject): fmpz_poly_divrem(Q.poly, R.poly, self.poly, other.poly) return Q, R - def left_shift(self, unsigned long n) : + def left_shift(self, unsigned long n): """ - Left shift self by n. + Left shift ``self`` by `n`. EXAMPLES:: @@ -353,9 +353,9 @@ cdef class Fmpz_poly(SageObject): return res - def right_shift(self, unsigned long n) : + def right_shift(self, unsigned long n): """ - Right shift self by n. + Right shift ``self`` by `n`. EXAMPLES:: @@ -383,9 +383,9 @@ cdef class Fmpz_poly(SageObject): fmpz_poly_pseudo_divrem(Q.poly, R.poly, &d, self.poly, other.poly) return Q, R, d - def derivative(self) : + def derivative(self): """ - Return the derivative of self. + Return the derivative of ``self``. EXAMPLES:: @@ -407,7 +407,7 @@ cdef class Fmpz_poly(SageObject): def truncate(self, n): """ - Return the truncation of self at degree n. + Return the truncation of ``self`` at degree `n`. EXAMPLES:: @@ -424,7 +424,7 @@ cdef class Fmpz_poly(SageObject): def _unsafe_mutate_truncate(self, n): """ - Return the truncation of self at degree n. + Return the truncation of ``self`` at degree `n`. Don't do this unless you know there are no other references to this polynomial!!!!! @@ -443,7 +443,7 @@ cdef class Fmpz_poly(SageObject): def _sage_(self, var='x'): """ - Return self as an element of the sage ZZ[var]. + Return ``self`` as an element of the sage ``ZZ[var]``. EXAMPLES:: diff --git a/src/sage/libs/flint/meson.build b/src/sage/libs/flint/meson.build new file mode 100644 index 00000000000..fe12b28b5f7 --- /dev/null +++ b/src/sage/libs/flint/meson.build @@ -0,0 +1,177 @@ +py.install_sources( + '__init__.py', + 'acb.pxd', + 'acb_calc.pxd', + 'acb_dft.pxd', + 'acb_dirichlet.pxd', + 'acb_elliptic.pxd', + 'acb_hypgeom.pxd', + 'acb_macros.pxd', + 'acb_mat.pxd', + 'acb_mat_macros.pxd', + 'acb_modular.pxd', + 'acb_poly.pxd', + 'acb_poly_macros.pxd', + 'acb_theta.pxd', + 'acf.pxd', + 'aprcl.pxd', + 'arb.pxd', + 'arb_calc.pxd', + 'arb_fmpz_poly.pxd', + 'arb_fpwrap.pxd', + 'arb_hypgeom.pxd', + 'arb_macros.pxd', + 'arb_mat.pxd', + 'arb_mat_macros.pxd', + 'arb_poly.pxd', + 'arf.pxd', + 'arith.pxd', + 'bernoulli.pxd', + 'bool_mat.pxd', + 'ca.pxd', + 'ca_ext.pxd', + 'ca_field.pxd', + 'ca_mat.pxd', + 'ca_poly.pxd', + 'ca_vec.pxd', + 'calcium.pxd', + 'd_mat.pxd', + 'd_vec.pxd', + 'dirichlet.pxd', + 'dlog.pxd', + 'double_extras.pxd', + 'double_interval.pxd', + 'fexpr.pxd', + 'fexpr_builtin.pxd', + 'fft.pxd', + 'flint.pxd', + 'flint_ntl_wrap.h', + 'flint_wrap.h', + 'fmpq.pxd', + 'fmpq_mat.pxd', + 'fmpq_mat_macros.pxd', + 'fmpq_mpoly.pxd', + 'fmpq_mpoly_factor.pxd', + 'fmpq_poly.pxd', + 'fmpq_poly_macros.pxd', + 'fmpq_poly_sage.pxd', + 'fmpq_vec.pxd', + 'fmpz.pxd', + 'fmpz_extras.pxd', + 'fmpz_factor.pxd', + 'fmpz_factor_sage.pxd', + 'fmpz_lll.pxd', + 'fmpz_macros.pxd', + 'fmpz_mat.pxd', + 'fmpz_mat_macros.pxd', + 'fmpz_mod.pxd', + 'fmpz_mod_mat.pxd', + 'fmpz_mod_mpoly.pxd', + 'fmpz_mod_mpoly_factor.pxd', + 'fmpz_mod_poly.pxd', + 'fmpz_mod_poly_factor.pxd', + 'fmpz_mod_vec.pxd', + 'fmpz_mpoly.pxd', + 'fmpz_mpoly_factor.pxd', + 'fmpz_mpoly_q.pxd', + 'fmpz_poly.pxd', + 'fmpz_poly_factor.pxd', + 'fmpz_poly_macros.pxd', + 'fmpz_poly_mat.pxd', + 'fmpz_poly_q.pxd', + 'fmpz_poly_sage.pxd', + 'fmpz_vec.pxd', + 'fmpzi.pxd', + 'fq.pxd', + 'fq_default.pxd', + 'fq_default_mat.pxd', + 'fq_default_poly.pxd', + 'fq_default_poly_factor.pxd', + 'fq_embed.pxd', + 'fq_mat.pxd', + 'fq_nmod.pxd', + 'fq_nmod_embed.pxd', + 'fq_nmod_mat.pxd', + 'fq_nmod_mpoly.pxd', + 'fq_nmod_mpoly_factor.pxd', + 'fq_nmod_poly.pxd', + 'fq_nmod_poly_factor.pxd', + 'fq_nmod_vec.pxd', + 'fq_poly.pxd', + 'fq_poly_factor.pxd', + 'fq_vec.pxd', + 'fq_zech.pxd', + 'fq_zech_embed.pxd', + 'fq_zech_mat.pxd', + 'fq_zech_poly.pxd', + 'fq_zech_poly_factor.pxd', + 'fq_zech_vec.pxd', + 'gr.pxd', + 'gr_generic.pxd', + 'gr_mat.pxd', + 'gr_mpoly.pxd', + 'gr_poly.pxd', + 'gr_special.pxd', + 'gr_vec.pxd', + 'hypgeom.pxd', + 'long_extras.pxd', + 'mag.pxd', + 'mag_macros.pxd', + 'mpf_mat.pxd', + 'mpf_vec.pxd', + 'mpfr_mat.pxd', + 'mpfr_vec.pxd', + 'mpn_extras.pxd', + 'mpoly.pxd', + 'nf.pxd', + 'nf_elem.pxd', + 'nmod.pxd', + 'nmod_mat.pxd', + 'nmod_mpoly.pxd', + 'nmod_mpoly_factor.pxd', + 'nmod_poly.pxd', + 'nmod_poly_factor.pxd', + 'nmod_poly_mat.pxd', + 'nmod_vec.pxd', + 'ntl_interface.pxd', + 'padic.pxd', + 'padic_mat.pxd', + 'padic_poly.pxd', + 'partitions.pxd', + 'perm.pxd', + 'profiler.pxd', + 'qadic.pxd', + 'qfb.pxd', + 'qqbar.pxd', + 'qsieve.pxd', + 'thread_pool.pxd', + 'types.pxd', + 'ulong_extras.pxd', + subdir: 'sage/libs/flint', +) + +extension_data = { + 'arith' : files('arith.pyx'), + 'arith_sage' : files('arith_sage.pyx'), + 'flint_sage' : files('flint_sage.pyx'), + 'fmpq_poly_sage' : files('fmpq_poly_sage.pyx'), + 'fmpz_factor_sage' : files('fmpz_factor_sage.pyx'), + 'fmpz_poly' : files('fmpz_poly.pyx'), + 'fmpz_poly_sage' : files('fmpz_poly_sage.pyx'), + 'qsieve' : files('qsieve.pyx'), + 'qsieve_sage' : files('qsieve_sage.pyx'), + 'ulong_extras' : files('ulong_extras.pyx'), + 'ulong_extras_sage' : files('ulong_extras_sage.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/flint', + install: true, + include_directories: [inc_cpython, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, flint, gmp, mpfr], + ) +endforeach + diff --git a/src/sage/libs/flint/nmod_poly_linkage.pxi b/src/sage/libs/flint/nmod_poly_linkage.pxi index f9340b416a8..b1be0216a2e 100644 --- a/src/sage/libs/flint/nmod_poly_linkage.pxi +++ b/src/sage/libs/flint/nmod_poly_linkage.pxi @@ -474,13 +474,13 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t INPUT: - - ``x`` -- polynomial; the base. + - ``x`` -- polynomial; the base - - ``e`` -- integer; the exponent. + - ``e`` -- integer; the exponent - - ``modulus`` -- polynomial or NULL; if not NULL, then perform a modular exponentiation. + - ``modulus`` -- polynomial or NULL; if not NULL, then perform a modular exponentiation - - ``n`` -- integer; not used, but all polynomials' coefficients are understood modulo ``n``. + - ``n`` -- integer; not used, but all polynomials' coefficients are understood modulo ``n`` EXAMPLES:: @@ -577,18 +577,37 @@ cdef inline int celement_gcd(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsi True sage: (G//d)*d == G True + + Check that we catch a case where FLINT fails. These generate the unit + ideal, so their GCD should be 1 (or another unit):: + + sage: R. = Integers(121)[] + sage: f = 11*x^2 + 1 + sage: f - 61*x*f.derivative() + 1 + sage: gcd(f, f.derivative()) + Traceback (most recent call last): + ... + RuntimeError: FLINT gcd calculation failed """ if celement_is_zero(b, n): nmod_poly_set(res, a) return 0 - # A check that the leading coefficients are invertible is *not* sufficient + # FLINT provides no interface for detecting errors here try: sig_on() - nmod_poly_gcd(res, a, b) - sig_off() + try: + nmod_poly_gcd(res, a, b) + finally: + sig_off() except RuntimeError: - raise ValueError("non-invertible elements encountered during GCD") + raise RuntimeError("FLINT gcd calculation failed") + + cdef unsigned long leadcoeff = nmod_poly_get_coeff_ui(res, nmod_poly_degree(res)) + cdef unsigned long modulus = nmod_poly_modulus(res) + if n_gcd(modulus, leadcoeff) == 1: + nmod_poly_make_monic(res, res) cdef inline int celement_xgcd(nmod_poly_t res, nmod_poly_t s, nmod_poly_t t, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: """ @@ -617,8 +636,26 @@ cdef inline int celement_xgcd(nmod_poly_t res, nmod_poly_t s, nmod_poly_t t, nmo True sage: (G//d)*d == G True + + TESTS: + + Ensure that :issue:`38537` is fixed:: + + sage: k = Zmod(2**16) + sage: R. = k[] + sage: u = x + 10161 + sage: v = x + 10681 + sage: u.xgcd(v) + Traceback (most recent call last): + ... + ValueError: non-invertible elements encountered during XGCD """ - nmod_poly_xgcd(res, s, t, a, b) + try: + sig_on() + nmod_poly_xgcd(res, s, t, a, b) + sig_off() + except RuntimeError: + raise ValueError("non-invertible elements encountered during XGCD") cdef factor_helper(Polynomial_zmod_flint poly, bint squarefree=False): diff --git a/src/sage/libs/flint/qsieve.pxd b/src/sage/libs/flint/qsieve.pxd index 7bd1bf5b862..9f40fb53daa 100644 --- a/src/sage/libs/flint/qsieve.pxd +++ b/src/sage/libs/flint/qsieve.pxd @@ -24,7 +24,7 @@ cdef extern from "flint_wrap.h": void qsieve_init_poly_next(qs_t qs_inf, slong i) noexcept void qsieve_compute_C(fmpz_t C, qs_t qs_inf, qs_poly_t poly) noexcept void qsieve_do_sieving(qs_t qs_inf, unsigned char * sieve, qs_poly_t poly) noexcept - void qsieve_do_sieving2(qs_t qs_inf, unsigned char * seive, qs_poly_t poly) noexcept + void qsieve_do_sieving2(qs_t qs_inf, unsigned char * sieve, qs_poly_t poly) noexcept slong qsieve_evaluate_candidate(qs_t qs_inf, ulong i, unsigned char * sieve, qs_poly_t poly) noexcept slong qsieve_evaluate_sieve(qs_t qs_inf, unsigned char * sieve, qs_poly_t poly) noexcept slong qsieve_collect_relations(qs_t qs_inf, unsigned char * sieve) noexcept diff --git a/src/sage/libs/flint/qsieve_sage.pyx b/src/sage/libs/flint/qsieve_sage.pyx index 93c2ce6b7ed..e172c7cb93e 100644 --- a/src/sage/libs/flint/qsieve_sage.pyx +++ b/src/sage/libs/flint/qsieve_sage.pyx @@ -19,7 +19,7 @@ def qsieve(n): INPUT: - - ``n`` -- an integer; neither prime nor a perfect power. + - ``n`` -- integer; neither prime nor a perfect power OUTPUT: @@ -43,7 +43,6 @@ def qsieve(n): Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined - """ n = Integer(n) diff --git a/src/sage/libs/gap/assigned_names.py b/src/sage/libs/gap/assigned_names.py index e8d1f1707cc..216bee639ec 100644 --- a/src/sage/libs/gap/assigned_names.py +++ b/src/sage/libs/gap/assigned_names.py @@ -37,17 +37,15 @@ def load_or_compute(name, function): """ - Helper to load a cached value or compute it + Helper to load a cached value or compute it. INPUT: - - ``name`` -- string. Part of the cache filename + - ``name`` -- string; part of the cache filename - - ``function`` -- function. To compute the value if not cached. + - ``function`` -- function; to compute the value if not cached - OUTPUT: - - The value of ``function``, possibly cached. + OUTPUT: the value of ``function``, possibly cached EXAMPLES:: @@ -72,11 +70,9 @@ def load_or_compute(name, function): def list_keywords(): """ - Return the GAP reserved keywords - - OUTPUT: + Return the GAP reserved keywords. - Tuple of strings. + OUTPUT: tuple of strings EXAMPLES:: @@ -93,11 +89,9 @@ def list_keywords(): def list_globals(): """ - Return the GAP reserved keywords + Return the GAP reserved keywords. - OUTPUT: - - Tuple of strings. + OUTPUT: tuple of strings EXAMPLES:: @@ -118,11 +112,9 @@ def list_globals(): def list_functions(): """ - Return the GAP documented global functions - - OUTPUT: + Return the GAP documented global functions. - Tuple of strings. + OUTPUT: tuple of strings EXAMPLES:: diff --git a/src/sage/libs/gap/context_managers.py b/src/sage/libs/gap/context_managers.py index b42e9c02f4f..611708ad96b 100644 --- a/src/sage/libs/gap/context_managers.py +++ b/src/sage/libs/gap/context_managers.py @@ -45,7 +45,7 @@ from sage.libs.gap.libgap import libgap -class GlobalVariableContext(): +class GlobalVariableContext: def __init__(self, variable, value): """ @@ -57,9 +57,9 @@ def __init__(self, variable, value): INPUT: - - ``variable`` -- string. The variable name. + - ``variable`` -- string; the variable name - - ``value`` -- anything that defines a GAP object. + - ``value`` -- anything that defines a GAP object EXAMPLES:: @@ -75,7 +75,7 @@ def __init__(self, variable, value): def __enter__(self): """ - Called when entering the with-block + Called when entering the with-block. EXAMPLES:: @@ -91,7 +91,7 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): """ - Called when exiting the with-block + Called when exiting the with-block. EXAMPLES:: diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 0a8fab40e0d..6345c898c66 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -5,6 +5,9 @@ This document describes the individual wrappers for various GAP elements. For general information about GAP, you should read the :mod:`~sage.libs.gap.libgap` module documentation. """ + +# hi + # **************************************************************************** # Copyright (C) 2012 Volker Braun # @@ -22,6 +25,8 @@ from sage.libs.gap.gap_includes cimport * from sage.libs.gap.libgap import libgap from sage.libs.gap.util cimport * from sage.libs.gap.util import GAPError +from sage.libs.gmp.mpz cimport * +from sage.libs.gmp.pylong cimport mpz_get_pylong from sage.cpython.string cimport str_to_bytes, char_to_str from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -41,11 +46,9 @@ cdef Obj make_gap_list(sage_list) except NULL: INPUT: - - ``a`` -- list of :class:`GapElement`. - - OUTPUT: + - ``a`` -- list of :class:`GapElement` - The list of the elements in ``a`` as a Gap ``Obj``. + OUTPUT: list of the elements in ``a`` as a Gap ``Obj`` """ cdef Obj l cdef GapElement elem @@ -72,7 +75,7 @@ cdef Obj make_gap_matrix(sage_list, gap_ring) except NULL: INPUT: - - ``sage_list`` -- list of :class:`GapElement`. + - ``sage_list`` -- list of :class:`GapElement` - ``gap_ring`` -- the base ring @@ -186,11 +189,9 @@ cdef Obj make_gap_record(sage_dict) except NULL: INPUT: - - ``a`` -- list of :class:`GapElement`. - - OUTPUT: + - ``a`` -- list of :class:`GapElement` - The list of the elements in ``a`` as a Gap ``Obj``. + OUTPUT: the list of the elements in ``a`` as a Gap ``Obj`` TESTS:: @@ -221,11 +222,9 @@ cdef Obj make_gap_integer(sage_int) except NULL: INPUT: - - ``sage_int`` -- a Sage integer. + - ``sage_int`` -- Sage integer - OUTPUT: - - The integer as a GAP ``Obj``. + OUTPUT: the integer as a GAP ``Obj`` TESTS:: @@ -241,11 +240,9 @@ cdef Obj make_gap_string(sage_string) except NULL: INPUT: - - ``sage_string`` -- a Python str. - - OUTPUT: + - ``sage_string`` -- a Python str - The string as a GAP ``Obj``. + OUTPUT: the string as a GAP ``Obj`` TESTS:: @@ -268,7 +265,7 @@ cdef Obj make_gap_string(sage_string) except NULL: cdef GapElement make_any_gap_element(parent, Obj obj): """ - Return the GAP element wrapper of ``obj`` + Return the GAP element wrapper of ``obj``. The most suitable subclass of GapElement is determined automatically. Use this function to wrap GAP objects unless you @@ -362,7 +359,7 @@ cdef GapElement make_GapElement(parent, Obj obj): - ``parent`` -- the parent of the new :class:`GapElement` - - ``obj`` -- a GAP object. + - ``obj`` -- a GAP object OUTPUT: @@ -414,7 +411,7 @@ cdef class GapElement(RingElement): sage: libgap(0) 0 - If Gap finds an error while evaluating, a :class:`GAPError` + If Gap finds an error while evaluating, a :exc:`GAPError` exception is raised:: sage: libgap.eval('1/0') @@ -422,7 +419,7 @@ cdef class GapElement(RingElement): ... GAPError: Error, Rational operations: must not be zero - Also, a ``GAPError`` is raised if the input is not a simple expression:: + Also, a :exc:`GAPError` is raised if the input is not a simple expression:: sage: libgap.eval('1; 2; 3') Traceback (most recent call last): @@ -444,7 +441,7 @@ cdef class GapElement(RingElement): def __init__(self): """ - The ``GapElement`` constructor + The ``GapElement`` constructor. Users must use the ``libgap`` instance to construct instances of :class:`GapElement`. Cython programmers must use @@ -491,7 +488,7 @@ cdef class GapElement(RingElement): def __dealloc__(self): r""" - The Cython destructor + The Cython destructor. TESTS:: @@ -546,14 +543,14 @@ cdef class GapElement(RingElement): cpdef GapElement deepcopy(self, bint mut): r""" - Return a deepcopy of this Gap object + Return a deepcopy of this Gap object. Note that this is the same thing as calling ``StructuralCopy`` but much faster. INPUT: - - ``mut`` -- (boolean) whether to return a mutable copy + - ``mut`` -- boolean; whether to return a mutable copy EXAMPLES:: @@ -653,9 +650,7 @@ cdef class GapElement(RingElement): This is only useful for libgap development purposes. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -669,7 +664,7 @@ cdef class GapElement(RingElement): def __dir__(self): """ - Customize tab completion + Customize tab completion. EXAMPLES:: @@ -778,7 +773,7 @@ cdef class GapElement(RingElement): cpdef _set_compare_by_id(self): """ - Set comparison to compare by ``id`` + Set comparison to compare by ``id``. By default, GAP is used to compare GAP objects. However, this is not defined for all GAP objects. To have GAP play @@ -816,13 +811,13 @@ cdef class GapElement(RingElement): cpdef _assert_compare_by_id(self): """ - Ensure that comparison is by ``id`` + Ensure that comparison is by ``id``. See :meth:`_set_compare_by_id`. OUTPUT: - This method returns nothing. A ``ValueError`` is raised if + This method returns nothing. A :exc:`ValueError` is raised if :meth:`_set_compare_by_id` has not been called on this libgap object. @@ -861,7 +856,7 @@ cdef class GapElement(RingElement): OUTPUT: Boolean, depending on the comparison of ``self`` and - ``other``. Raises a ``ValueError`` if GAP does not support + ``other``. Raises a :exc:`ValueError` if GAP does not support comparison of ``self`` and ``other``, unless :meth:`_set_compare_by_id` was called on both ``self`` and ``other``. @@ -880,7 +875,7 @@ cdef class GapElement(RingElement): True GAP does not have a comparison function for two ``FreeGroup`` - objects. LibGAP signals this by raising a ``ValueError`` :: + objects. LibGAP signals this by raising a :exc:`ValueError` :: sage: F1 = libgap.FreeGroup(['a']) sage: F2 = libgap.FreeGroup(['a']) @@ -1182,9 +1177,7 @@ cdef class GapElement(RingElement): """ Return whether the wrapped GAP object is a function. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1201,9 +1194,7 @@ cdef class GapElement(RingElement): r""" Return whether the wrapped GAP object is a GAP List. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1218,9 +1209,7 @@ cdef class GapElement(RingElement): r""" Return whether the wrapped GAP object is a GAP record. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1235,9 +1224,7 @@ cdef class GapElement(RingElement): r""" Return whether the wrapped GAP object is a GAP boolean. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1253,9 +1240,7 @@ cdef class GapElement(RingElement): r""" Return whether the wrapped GAP object is a GAP string. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1268,9 +1253,7 @@ cdef class GapElement(RingElement): r""" Return whether the wrapped GAP object is a GAP permutation. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1286,7 +1269,7 @@ cdef class GapElement(RingElement): def sage(self): r""" - Return the Sage equivalent of the :class:`GapElement` + Return the Sage equivalent of the :class:`GapElement`. EXAMPLES:: @@ -1340,12 +1323,22 @@ cdef class GapElement(RingElement): sage: p.sage().parent() Fraction Field of Univariate Polynomial Ring in x over Integer Ring + sage: G0 = libgap.SymplecticGroup(4,2) + sage: P = G0.IsomorphismFpGroup().Range() + sage: G = P.sage() + sage: G.gap() == P + True + + sage: F0 = libgap.FreeGroup(2) + sage: F = F0.sage() + sage: F.gap() is F0 + True + TESTS: Check :issue:`30496`:: sage: x = libgap.Integers.Indeterminate("x") - sage: p = x^2 - 2*x sage: p.sage() x^2 - 2*x @@ -1393,6 +1386,20 @@ cdef class GapElement(RingElement): # that we can convert return [item.sage() for item in self.AsList()] + elif self.IsFreeGroup(): + from sage.groups.free_group import FreeGroup_class + names = tuple(str(g) for g in self.GeneratorsOfGroup()) + return FreeGroup_class(names, gap_group=self) + + elif self.IsFpGroup(): + from sage.groups.free_group import FreeGroup + from sage.groups.finitely_presented import FinitelyPresentedGroup + # names = tuple(str(g).replace(".", "_") for g in self.FreeGroupOfFpGroup().GeneratorsOfGroup()) + F = self.FreeGroupOfFpGroup().sage() + relations = tuple(F(rel.LetterRepAssocWord().sage()) + for rel in self.RelatorsOfFpGroup()) + return FinitelyPresentedGroup(F, relations, libgap_fpgroup=self) + raise NotImplementedError('cannot construct equivalent Sage object') @@ -1402,7 +1409,7 @@ cdef class GapElement(RingElement): cdef GapElement_Integer make_GapElement_Integer(parent, Obj obj): r""" - Turn a Gap integer object into a GapElement_Integer Sage object + Turn a Gap integer object into a GapElement_Integer Sage object. EXAMPLES:: @@ -1437,9 +1444,7 @@ cdef class GapElement_Integer(GapElement): is subject to the usual size limits. Larger integers are stored in GAP as GMP integers. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1474,14 +1479,12 @@ cdef class GapElement_Integer(GapElement): def sage(self, ring=None): r""" - Return the Sage equivalent of the :class:`GapElement_Integer` + Return the Sage equivalent of the :class:`GapElement_Integer`. - - ``ring`` -- Integer ring or ``None`` (default). If not - specified, a the default Sage integer ring is used. + - ``ring`` -- integer ring or ``None`` (default); if not + specified, the default Sage integer ring is used - OUTPUT: - - A Sage integer + OUTPUT: a Sage integer EXAMPLES:: @@ -1497,6 +1500,8 @@ cdef class GapElement_Integer(GapElement): TESTS:: + sage: libgap(0).sage() + 0 sage: large = libgap.eval('2^130'); large 1361129467683753853853498429727072845824 sage: large.sage() @@ -1507,17 +1512,31 @@ cdef class GapElement_Integer(GapElement): sage: huge.sage().ndigits() 10000 """ + cdef UInt* x + cdef Int size + cdef int c_sign + cdef int c_size + cdef mpz_t output if ring is None: ring = ZZ - if self.is_C_int(): - return ring(GAP_ValueInt(self.value)) - else: - # TODO: waste of time! - # gap integers are stored as a mp_limb_t and we have a much more direct - # conversion implemented in mpz_get_pylong(mpz_srcptr z) - # (see sage.libs.gmp.pylong) - string = self.String().sage() - return ring(string) + try: + GAP_Enter() + if self.is_C_int(): + return ring(GAP_ValueInt(self.value)) + else: + # gap integers are stored as a mp_limb_t + size = GAP_SizeInt(self.value) # count limbs and extract sign + if size > 0: + c_sign = 1 + c_size = size + else: # Must have size < 0, or else self.value == 0 and self.is_C_int() == True + c_sign = -1 + c_size = -size + x = GAP_AddrInt(self.value) # pointer to limbs + mpz_roinit_n(output, x, c_size) + return ring(c_sign*mpz_get_pylong(output)) + finally: + GAP_Leave() _integer_ = sage @@ -1556,7 +1575,7 @@ cdef class GapElement_Integer(GapElement): cdef GapElement_Float make_GapElement_Float(parent, Obj obj): r""" - Turn a Gap macfloat object into a GapElement_Float Sage object + Turn a Gap macfloat object into a GapElement_Float Sage object. EXAMPLES:: @@ -1591,14 +1610,12 @@ cdef class GapElement_Float(GapElement): """ def sage(self, ring=None): r""" - Return the Sage equivalent of the :class:`GapElement_Float` + Return the Sage equivalent of the :class:`GapElement_Float`. - - ``ring`` -- a floating point field or ``None`` (default). If not - specified, the default Sage ``RDF`` is used. - - OUTPUT: + - ``ring`` -- a floating point field or ``None`` (default); if not + specified, the default Sage ``RDF`` is used - A Sage double precision floating point number + OUTPUT: a Sage double precision floating point number EXAMPLES:: @@ -1628,7 +1645,7 @@ cdef class GapElement_Float(GapElement): cdef GapElement_IntegerMod make_GapElement_IntegerMod(parent, Obj obj): r""" - Turn a Gap integer object into a :class:`GapElement_IntegerMod` Sage object + Turn a Gap integer object into a :class:`GapElement_IntegerMod` Sage object. EXAMPLES:: @@ -1675,17 +1692,15 @@ cdef class GapElement_IntegerMod(GapElement): def sage(self, ring=None): r""" - Return the Sage equivalent of the :class:`GapElement_IntegerMod` + Return the Sage equivalent of the :class:`GapElement_IntegerMod`. INPUT: - - ``ring`` -- Sage integer mod ring or ``None`` (default). If - not specified, a suitable integer mod ringa is used - automatically. + - ``ring`` -- Sage integer mod ring or ``None`` (default); if + not specified, a suitable integer mod ring is used + automatically - OUTPUT: - - A Sage integer modulo another integer. + OUTPUT: a Sage integer modulo another integer EXAMPLES:: @@ -1699,8 +1714,21 @@ cdef class GapElement_IntegerMod(GapElement): # ring = self.DefaultRing().sage() characteristic = self.Characteristic().sage() ring = ZZ.quotient_ring(characteristic) - return self.lift().sage(ring=ring) + return ring(self.lift()) + def _integer_(self, R): + r""" + TESTS:: + + sage: n = libgap.ZmodnZObj(13, 123) + sage: ZZ(n) + 13 + sage: ZZ(-n) + 110 + sage: ZZ(0*n) + 0 + """ + return self.lift()._integer_(R) ############################################################################ ### GapElement_FiniteField ##################################################### @@ -1708,7 +1736,7 @@ cdef class GapElement_IntegerMod(GapElement): cdef GapElement_FiniteField make_GapElement_FiniteField(parent, Obj obj): r""" - Turn a GAP finite field object into a :class:`GapElement_FiniteField` Sage object + Turn a GAP finite field object into a :class:`GapElement_FiniteField` Sage object. EXAMPLES:: @@ -1822,6 +1850,8 @@ cdef class GapElement_FiniteField(GapElement): a^2 + a + 1 sage: n.sage(ring=GF(2^8, 'a')) a^7 + a^6 + a^4 + a^2 + a + 1 + sage: (n^3).sage() + 1 Check that :issue:`23153` is fixed:: @@ -1908,12 +1938,10 @@ cdef class GapElement_Cyclotomic(GapElement): INPUT: - ``ring`` -- a Sage cyclotomic field or ``None`` - (default). If not specified, a suitable minimal cyclotomic - field will be constructed. - - OUTPUT: + (default); if not specified, a suitable minimal cyclotomic + field will be constructed - A Sage cyclotomic field element. + OUTPUT: a Sage cyclotomic field element EXAMPLES:: @@ -2004,12 +2032,10 @@ cdef class GapElement_Rational(GapElement): INPUT: - - ``ring`` -- the Sage rational ring or ``None`` (default). If - not specified, the rational ring is used automatically. - - OUTPUT: + - ``ring`` -- the Sage rational ring or ``None`` (default); if + not specified, the rational ring is used automatically - A Sage rational number. + OUTPUT: a Sage rational number EXAMPLES:: @@ -2147,11 +2173,9 @@ cdef class GapElement_Ring(GapElement): INPUT: - ``**kwds`` -- keywords that are passed on to the ``ring_`` - method. + method - OUTPUT: - - A Sage ring. + OUTPUT: a Sage ring EXAMPLES:: @@ -2223,13 +2247,13 @@ cdef class GapElement_Boolean(GapElement): def sage(self): r""" - Return the Sage equivalent of the :class:`GapElement` + Return the Sage equivalent of the :class:`GapElement`. OUTPUT: A Python boolean if the values is either true or false. GAP booleans can have the third value ``Fail``, in which case a - ``ValueError`` is raised. + :exc:`ValueError` is raised. EXAMPLES:: @@ -2261,9 +2285,7 @@ cdef class GapElement_Boolean(GapElement): This is syntactic sugar for using libgap. See the examples below. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -2320,9 +2342,7 @@ cdef class GapElement_String(GapElement): r""" Convert this :class:`GapElement_String` to a Python string. - OUTPUT: - - A Python string. + OUTPUT: a Python string EXAMPLES:: @@ -2354,11 +2374,9 @@ cdef GapElement_Function make_GapElement_Function(parent, Obj obj): - ``parent`` -- the parent of the new :class:`GapElement` - - ``obj`` -- a GAP function object. - - OUTPUT: + - ``obj`` -- a GAP function object - A :class:`GapElement_Function` instance. + OUTPUT: a :class:`GapElement_Function` instance EXAMPLES:: @@ -2385,11 +2403,9 @@ cdef class GapElement_Function(GapElement): def __repr__(self): r""" - Return a string representation - - OUTPUT: + Return a string representation. - String. + OUTPUT: string EXAMPLES:: @@ -2408,7 +2424,7 @@ cdef class GapElement_Function(GapElement): INPUT: - ``*args`` -- arguments. Will be converted to `GapElement` if - they are not already of this type. + they are not already of this type OUTPUT: @@ -2424,31 +2440,22 @@ cdef class GapElement_Function(GapElement): sage: b Sym( [ 1 .. 4 ] ) - sage: sorted(a(b)) - [Group(()), - Sym( [ 1 .. 4 ] ), - Alt( [ 1 .. 4 ] ), - Group([ (1,4)(2,3), (1,2)(3,4) ])] + sage: [x.StructureDescription() for x in sorted(a(b))] + ["1", "S4", "A4", "C2 x C2"] sage: libgap.eval("a := NormalSubgroups") sage: libgap.eval("b := SymmetricGroup(4)") Sym( [ 1 .. 4 ] ) sage: libgap.collect() - sage: sorted(libgap.eval('a') (libgap.eval('b'))) - [Group(()), - Sym( [ 1 .. 4 ] ), - Alt( [ 1 .. 4 ] ), - Group([ (1,4)(2,3), (1,2)(3,4) ])] + sage: [x.StructureDescription() for x in sorted(libgap.eval('a') (libgap.eval('b')))] + ["1", "S4", "A4", "C2 x C2"] sage: a = libgap.eval('a') sage: b = libgap.eval('b') sage: libgap.collect() - sage: sorted(a(b)) - [Group(()), - Sym( [ 1 .. 4 ] ), - Alt( [ 1 .. 4 ] ), - Group([ (1,4)(2,3), (1,2)(3,4) ])] + sage: [x.StructureDescription() for x in sorted(a(b))] + ["1", "S4", "A4", "C2 x C2"] Not every ``GapElement`` is callable:: @@ -2533,7 +2540,7 @@ cdef class GapElement_Function(GapElement): def _instancedoc_(self): r""" - Return the help string + Return the help string. EXAMPLES:: @@ -2564,13 +2571,11 @@ cdef GapElement_MethodProxy make_GapElement_MethodProxy(parent, Obj function, Ga - ``parent`` -- the parent of the new :class:`GapElement` - - ``obj`` -- a GAP function object. + - ``obj`` -- a GAP function object - - ``base_object`` -- The first argument to be inserted into the function. + - ``base_object`` -- the first argument to be inserted into the function - OUTPUT: - - A :class:`GapElement_MethodProxy` instance. + OUTPUT: a :class:`GapElement_MethodProxy` instance EXAMPLES:: @@ -2616,7 +2621,7 @@ cdef class GapElement_MethodProxy(GapElement_Function): INPUT: - ``*args`` -- arguments. Will be converted to `GapElement` if - they are not already of this type. + they are not already of this type OUTPUT: @@ -2695,7 +2700,7 @@ cdef class GapElement_List(GapElement): def __bool__(self): r""" - Return True if the list is non-empty, as with Python ``list``s. + Return ``True`` if the list is non-empty, as with Python ``list``s. EXAMPLES:: @@ -2712,9 +2717,7 @@ cdef class GapElement_List(GapElement): r""" Return the length of the list. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -2733,7 +2736,7 @@ cdef class GapElement_List(GapElement): INPUT: - - ``i`` -- integer. + - ``i`` -- integer OUTPUT: @@ -2786,7 +2789,7 @@ cdef class GapElement_List(GapElement): def __setitem__(self, i, elt): r""" - Set the ``i``-th item of this list + Set the `i`-th item of this list. EXAMPLES:: @@ -2865,11 +2868,9 @@ cdef class GapElement_List(GapElement): def sage(self, **kwds): r""" - Return the Sage equivalent of the :class:`GapElement` - - OUTPUT: + Return the Sage equivalent of the :class:`GapElement`. - A Python list. + OUTPUT: a Python list EXAMPLES:: @@ -2888,9 +2889,7 @@ cdef class GapElement_List(GapElement): lists of lists. This function converts a GAP list of lists to a Sage matrix. - OUTPUT: - - A Sage matrix. + OUTPUT: a Sage matrix EXAMPLES:: @@ -2930,7 +2929,7 @@ cdef class GapElement_List(GapElement): if ring is None: ring = entries.DefaultRing().sage() MS = MatrixSpace(ring, n, m) - return MS([x.sage(ring=ring) for x in entries]) + return MS([ring(x) for x in entries]) _matrix_ = matrix @@ -2941,9 +2940,7 @@ cdef class GapElement_List(GapElement): GAP does not have a special vector data type, they are just lists. This function converts a GAP list to a Sage vector. - OUTPUT: - - A Sage vector. + OUTPUT: a Sage vector EXAMPLES:: @@ -3010,7 +3007,7 @@ cdef class GapElement_Permutation(GapElement): def sage(self, parent=None): r""" - Return the Sage equivalent of the :class:`GapElement` + Return the Sage equivalent of the :class:`GapElement`. If the permutation group is given as parent, this method is *much* faster. @@ -3091,9 +3088,7 @@ cdef class GapElement_Record(GapElement): r""" Return the length of the record. - OUTPUT: - - Integer. The number of entries in the record. + OUTPUT: integer; the number of entries in the record EXAMPLES:: @@ -3107,9 +3102,7 @@ cdef class GapElement_Record(GapElement): r""" Iterate over the elements of the record. - OUTPUT: - - A :class:`GapElement_RecordIterator`. + OUTPUT: a :class:`GapElement_RecordIterator` EXAMPLES:: @@ -3128,7 +3121,7 @@ cdef class GapElement_Record(GapElement): INPUT: - - ``py_name`` -- a python string. + - ``py_name`` -- a python string OUTPUT: @@ -3153,11 +3146,9 @@ cdef class GapElement_Record(GapElement): INPUT: - - ``name`` -- string. + - ``name`` -- string - OUTPUT: - - The record element labelled by ``name`` as a :class:`GapElement`. + OUTPUT: the record element labelled by ``name`` as a :class:`GapElement` EXAMPLES:: @@ -3178,7 +3169,7 @@ cdef class GapElement_Record(GapElement): def sage(self): r""" - Return the Sage equivalent of the :class:`GapElement` + Return the Sage equivalent of the :class:`GapElement`. EXAMPLES:: @@ -3205,14 +3196,14 @@ cdef class GapElement_Record(GapElement): cdef class GapElement_RecordIterator(): r""" - Iterator for :class:`GapElement_Record` + Iterator for :class:`GapElement_Record`. Since Cython does not support generators yet, we implement the older iterator specification with this auxiliary class. INPUT: - - ``rec`` -- the :class:`GapElement_Record` to iterate over. + - ``rec`` -- the :class:`GapElement_Record` to iterate over EXAMPLES:: @@ -3229,7 +3220,7 @@ cdef class GapElement_RecordIterator(): INPUT: - - ``rec`` -- the :class:`GapElement_Record` to iterate over. + - ``rec`` -- the :class:`GapElement_Record` to iterate over EXAMPLES:: diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 1ed4378a6c7..35107d3d4a0 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -74,6 +74,8 @@ cdef extern from "gap/libgap-api.h" nogil: bint GAP_IsSmallInt(Obj) Obj GAP_NewObjIntFromInt(Int val) Int GAP_ValueInt(Obj) + Int GAP_SizeInt(Obj) + UInt* GAP_AddrInt(Obj) bint GAP_IsList(Obj lst) UInt GAP_LenList(Obj lst) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 328a5096160..8218d51a5cd 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -72,7 +72,7 @@ corresponding Sage datatype: #. GAP booleans ``true`` / ``false`` to Sage booleans ``True`` / ``False``. The third GAP boolean value ``fail`` raises a - ``ValueError``. + :exc:`ValueError`. #. GAP integers to Sage integers. @@ -134,7 +134,7 @@ convert the entries into Sage objects, you should use the Now ``rec['a']`` is a Sage integer. We have not implemented the conversion of the GAP symmetric group to the Sage symmetric group yet, -so you end up with a ``NotImplementedError`` exception object. The +so you end up with a :exc:`NotImplementedError` exception object. The exception is returned and not raised so that you can work with the partial result. @@ -176,6 +176,8 @@ AUTHORS: libgap API """ +# hi + ############################################################################### # Copyright (C) 2009, William Stein # Copyright (C) 2012, Volker Braun @@ -257,9 +259,7 @@ class Gap(Parent): """ Whether a coercion from `S` exists. - INPUT / OUTPUT: - - See :mod:`sage.structure.parent`. + INPUT / OUTPUT: see :mod:`sage.structure.parent` EXAMPLES:: @@ -276,11 +276,9 @@ class Gap(Parent): INPUT: - - ``x`` -- anything that defines a GAP object. + - ``x`` -- anything that defines a GAP object - OUTPUT: - - A :class:`GapElement`. + OUTPUT: a :class:`GapElement` EXAMPLES:: @@ -296,7 +294,6 @@ class Gap(Parent): [ 1/3, 2/3, 4/5 ] sage: libgap(vector((1/3, 0.8, 3))) [ 0.333333, 0.8, 3. ] - """ initialize() if isinstance(x, GapElement): @@ -328,7 +325,7 @@ class Gap(Parent): INPUT: - - ``M`` -- a matrix. + - ``M`` -- a matrix OUTPUT: @@ -362,7 +359,7 @@ class Gap(Parent): We gracefully handle the case that the conversion fails (:issue:`18039`):: - sage: F.
= GF(9, modulus="first_lexicographic") # needs sage.rings.finite_rings + sage: F. = GF(9, modulus='first_lexicographic') # needs sage.rings.finite_rings sage: libgap(Matrix(F, [[a]])) # needs sage.rings.finite_rings Traceback (most recent call last): ... @@ -383,12 +380,10 @@ class Gap(Parent): INPUT: - - ``gap_command`` -- a string containing a valid gap command - without the trailing semicolon. + - ``gap_command`` -- string containing a valid gap command + without the trailing semicolon - OUTPUT: - - A :class:`GapElement`. + OUTPUT: a :class:`GapElement` EXAMPLES:: @@ -413,7 +408,7 @@ class Gap(Parent): def load_package(self, pkg): """ - If loading fails, raise a :class:`RuntimeError` exception. + If loading fails, raise a :exc:`RuntimeError` exception. TESTS:: @@ -438,7 +433,7 @@ class Gap(Parent): @cached_method def function_factory(self, function_name): """ - Return a GAP function wrapper + Return a GAP function wrapper. This is almost the same as calling ``libgap.eval(function_name)``, but faster and makes it @@ -446,7 +441,7 @@ class Gap(Parent): INPUT: - - ``function_name`` -- string. The name of a GAP function. + - ``function_name`` -- string; the name of a GAP function OUTPUT: @@ -465,13 +460,13 @@ class Gap(Parent): def set_global(self, variable, value): """ - Set a GAP global variable + Set a GAP global variable. INPUT: - - ``variable`` -- string. The variable name. + - ``variable`` -- string; the variable name - - ``value`` -- anything that defines a GAP object. + - ``value`` -- anything that defines a GAP object EXAMPLES:: @@ -490,11 +485,11 @@ class Gap(Parent): def unset_global(self, variable): """ - Remove a GAP global variable + Remove a GAP global variable. INPUT: - - ``variable`` -- string. The variable name. + - ``variable`` -- string; the variable name EXAMPLES:: @@ -514,16 +509,16 @@ class Gap(Parent): def get_global(self, variable): """ - Get a GAP global variable + Get a GAP global variable. INPUT: - - ``variable`` -- string. The variable name. + - ``variable`` -- string; the variable name OUTPUT: A :class:`~sage.libs.gap.element.GapElement` wrapping the GAP - output. A ``ValueError`` is raised if there is no such + output. A :exc:`ValueError` is raised if there is no such variable in GAP. EXAMPLES:: @@ -539,17 +534,15 @@ class Gap(Parent): def global_context(self, variable, value): """ - Temporarily change a global variable + Temporarily change a global variable. INPUT: - - ``variable`` -- string. The variable name. + - ``variable`` -- string; the variable name - - ``value`` -- anything that defines a GAP object. - - OUTPUT: + - ``value`` -- anything that defines a GAP object - A context manager that sets/reverts the given global variable. + OUTPUT: a context manager that sets/reverts the given global variable EXAMPLES:: @@ -590,9 +583,7 @@ class Gap(Parent): r""" Return a :class:`GapElement`. - OUTPUT: - - A :class:`GapElement`. + OUTPUT: a :class:`GapElement` EXAMPLES:: @@ -605,9 +596,7 @@ class Gap(Parent): """ Return (integer) zero in GAP. - OUTPUT: - - A :class:`GapElement`. + OUTPUT: a :class:`GapElement` EXAMPLES:: @@ -646,9 +635,7 @@ class Gap(Parent): r""" Return a string representation of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -660,7 +647,7 @@ class Gap(Parent): @cached_method def __dir__(self): """ - Customize tab completion + Customize tab completion. EXAMPLES:: @@ -677,12 +664,12 @@ class Gap(Parent): INPUT: - - ``name`` -- string. The name of the GAP function you want to - call. + - ``name`` -- string; the name of the GAP function you want to + call OUTPUT: - A :class:`GapElement`. A ``AttributeError`` is raised + A :class:`GapElement`. A :exc:`AttributeError` is raised if there is no such function or global variable. EXAMPLES:: @@ -705,7 +692,7 @@ class Gap(Parent): def show(self): """ - Return statistics about the GAP owned object list + Return statistics about the GAP owned object list. This includes the total memory allocated by GAP as returned by ``libgap.eval('TotalMemoryAllocated()'), as well as garbage collection @@ -718,7 +705,7 @@ class Gap(Parent): allocated for GAP objects (see ``libgap.eval('TotalMemoryAllocated()')``). - .. note:: + .. NOTE:: Slight complication is that we want to do it without accessing libgap objects, so we don't create new GapElements as a side @@ -755,9 +742,7 @@ class Gap(Parent): Return the number of GAP objects that are being tracked by GAP. - OUTPUT: - - An integer + OUTPUT: integer EXAMPLES:: @@ -768,7 +753,7 @@ class Gap(Parent): def collect(self): """ - Manually run the garbage collector + Manually run the garbage collector. EXAMPLES:: diff --git a/src/sage/libs/gap/meson.build b/src/sage/libs/gap/meson.build new file mode 100644 index 00000000000..2302a169cb2 --- /dev/null +++ b/src/sage/libs/gap/meson.build @@ -0,0 +1,38 @@ +py.install_sources( + 'all.py', + 'all_documented_functions.py', + 'assigned_names.py', + 'context_managers.py', + 'element.pxd', + 'gap_functions.py', + 'gap_globals.py', + 'gap_includes.pxd', + 'operations.py', + 'sage.gaprc', + 'saved_workspace.py', + 'test.py', + 'test_long.py', + 'util.pxd', + subdir: 'sage/libs/gap', +) + +# Ensure that the gaprc file is installed also in editable mode +fs.copyfile('sage.gaprc') + +extension_data = { + 'element' : files('element.pyx'), + 'libgap' : files('libgap.pyx'), + 'util' : files('util.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/gap', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gap, gmp], + ) +endforeach + diff --git a/src/sage/libs/gap/operations.py b/src/sage/libs/gap/operations.py index 434d1a01511..b2106583f0b 100644 --- a/src/sage/libs/gap/operations.py +++ b/src/sage/libs/gap/operations.py @@ -31,11 +31,11 @@ class OperationInspector(SageObject): def __init__(self, libgap_element): """ - Information about operations that can act on a given LibGAP element + Information about operations that can act on a given LibGAP element. INPUT: - - ``libgap_element`` -- libgap element. + - ``libgap_element`` -- libgap element EXAMPLES:: @@ -48,11 +48,9 @@ def __init__(self, libgap_element): def _repr_(self): """ - Return the string representation + Return the string representation. - OUTPUT: - - String + OUTPUT: string EXAMPLES:: @@ -66,11 +64,9 @@ def _repr_(self): @property def obj(self): """ - The first argument for the operations - - OUTPUT: + The first argument for the operations. - A Libgap object. + OUTPUT: a Libgap object EXAMPLES:: @@ -83,11 +79,9 @@ def obj(self): def operations(self): """ - Return the GAP operations for :meth:`obj` + Return the GAP operations for :meth:`obj`. - OUTPUT: - - List of GAP operations + OUTPUT: list of GAP operations EXAMPLES:: @@ -106,11 +100,9 @@ def mfi(o): def op_names(self): """ - Return the names of the operations - - OUTPUT: + Return the names of the operations. - List of strings + OUTPUT: list of strings EXAMPLES:: diff --git a/src/sage/libs/gap/saved_workspace.py b/src/sage/libs/gap/saved_workspace.py index fdaf18f4644..c26993ac638 100644 --- a/src/sage/libs/gap/saved_workspace.py +++ b/src/sage/libs/gap/saved_workspace.py @@ -14,7 +14,7 @@ def timestamp(): """ - Return a time stamp for (lib)gap + Return a time stamp for (lib)gap. OUTPUT: @@ -51,8 +51,8 @@ def workspace(name='workspace'): INPUT: - - ``name`` -- string. A name that will become part of the - workspace filename. + - ``name`` -- string; a name that will become part of the + workspace filename OUTPUT: diff --git a/src/sage/libs/gap/test.py b/src/sage/libs/gap/test.py index eee697218ee..73dad049dc9 100644 --- a/src/sage/libs/gap/test.py +++ b/src/sage/libs/gap/test.py @@ -8,7 +8,7 @@ def test_write_to_file(): """ - Test that libgap can write to files + Test that libgap can write to files. See :issue:`16502`, :issue:`15833`. @@ -20,7 +20,7 @@ def test_write_to_file(): fname = tmp_filename() message = "Ceci n'est pas une groupe" libgap.PrintTo(fname, message) - with open(fname, 'r') as f: + with open(fname) as f: assert f.read() == message SystemFile = libgap.function_factory('StringFile') assert SystemFile(fname).sage() == message diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index 3e75d71ff06..8509ae35e55 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -2,6 +2,8 @@ Utility functions for GAP """ +# hi + #***************************************************************************** # Copyright (C) 2012 Volker Braun # @@ -38,7 +40,7 @@ from sage.interfaces.gap_workspace import prepare_workspace_dir cdef class ObjWrapper(): """ - Wrapper for GAP master pointers + Wrapper for GAP master pointers. EXAMPLES:: @@ -55,13 +57,11 @@ cdef class ObjWrapper(): INPUT: - - ``lhs``, ``rhs`` -- :class:`ObjWrapper`. - - - ``op`` -- integer. The comparison operation to be performed. + - ``lhs``, ``rhs`` -- :class:`ObjWrapper` - OUTPUT: + - ``op`` -- integer; the comparison operation to be performed - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -91,7 +91,7 @@ cdef class ObjWrapper(): def __hash__(self): """ - Return a hash value + Return a hash value. EXAMPLES:: @@ -297,7 +297,7 @@ cdef Obj gap_eval(str gap_string) except? NULL: INPUT: - - ``gap_string`` -- string. A valid statement in GAP. + - ``gap_string`` -- string; a valid statement in GAP OUTPUT: @@ -370,7 +370,7 @@ cdef Obj gap_eval(str gap_string) except? NULL: # here if the error handler was set; but in case it wasn't # let's still check the result... nresults = GAP_LenList(result) - if nresults > 1: # to mimick the old libGAP + if nresults > 1: # to mimic the old libGAP # TODO: Get rid of this restriction eventually? raise GAPError("can only evaluate a single statement") @@ -433,7 +433,7 @@ cdef void error_handler() noexcept with gil: """ The libgap error handler. - If an error occurred, we raise a ``GAPError``; when the original + If an error occurred, we raise a :exc:`GAPError`; when the original ``GAP_EvalString`` returns, this exception will be seen. TODO: We should probably prevent re-entering this function if we diff --git a/src/sage/libs/giac/__init__.py b/src/sage/libs/giac/__init__.py index 874cfe4e54f..ef2267c4378 100644 --- a/src/sage/libs/giac/__init__.py +++ b/src/sage/libs/giac/__init__.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.giac """ Wrappers for Giac functions @@ -35,7 +36,7 @@ # Remarks for doctests: # 1) The first time that the c++ library giac is loaded a message appears. -# This message is version and arch dependant. +# This message is version and arch dependent. # 2) When proba_epsilon is too bad (>1e-6?) setting it to a better value # will give an additional message like the following one: # Restoring proba epsilon to 1e-6 from 1e-12 @@ -57,7 +58,6 @@ def __enter__(self): sage: with GiacSettingsDefaultContext(): giacsettings.proba_epsilon = 1e-12 sage: giacsettings.proba_epsilon < 1e-14 True - """ self.proba_epsilon = giacsettings.proba_epsilon self.threads = giacsettings.threads @@ -74,7 +74,6 @@ def __exit__(self, typ, value, tb): sage: with GiacSettingsDefaultContext(): giacsettings.proba_epsilon = 1e-30 sage: giacsettings.proba_epsilon < 1e-20 False - """ # Restore the debug level first to not have messages at each modification libgiac('debug_infolevel')(self.debuginfolevel) @@ -104,7 +103,6 @@ def local_giacsettings(func): True sage: gp0, Gamma(a)=int(e^{-t}*t^{a-1},t=0..inf)) and Gamma(a)=Gamma(a+1)/a and Gamma(a,b)=ugamma(a,b). - See also: 1/ Psi 2/ Beta 3/ ugamma 4/ igamma + See also: 1/ Psi 2/ Beta 3/ ugamma 4/ igamma Ex1:Gamma(5) Ex2:Gamma(1/2) Ex3:Gamma(gamma(-5.1)) Ex4:Gamma(-5.1,2.1) - ''' return GiacMethods['Gamma'](self,*args) @@ -210,11 +194,10 @@ cdef class GiacMethods_base: Help for Heaviside: Heaviside(Real) Function equal to 0 if x<0 and 1 if x>=0. - See also: 1/ Dirac 2/ laplace + See also: 1/ Dirac 2/ laplace Ex1:Heaviside(1) Ex2:Heaviside(-1) Ex3:Heaviside(0) - ''' return GiacMethods['Heaviside'](self,*args) @@ -223,9 +206,8 @@ cdef class GiacMethods_base: Help for JordanBlock: JordanBlock(Expr(a),Intg(n)) Returns an n*n matrix with a on the diagonal, 1 above and 0 everywhere else. - See also: 1/ jordan + See also: 1/ jordan Ex1:JordanBlock(7,3) - ''' return GiacMethods['JordanBlock'](self,*args) @@ -234,10 +216,9 @@ cdef class GiacMethods_base: Help for LU: LU(Mtrx(A),Var(L),Var(U),Var(P)) For a numerical matrix A, stores in L a lower triangular matrix, in U an upper triangular matrix and in P a permutation matrix such that P*A=L*U. - See also: 1/ lu 2/ QR + See also: 1/ lu 2/ QR Ex1:LU([[1,2],[3,4]],L,U,P) Ex2:LU([[6,12,18],[5,14,31],[3,8,18]],L,U,P) - ''' return GiacMethods['LU'](self,*args) @@ -249,7 +230,6 @@ cdef class GiacMethods_base: Ex1:LambertW(1.0) Ex2:LambertW(ln(4)) Ex3:LambertW(-0.1,-1) - ''' return GiacMethods['LambertW'](self,*args) @@ -258,9 +238,8 @@ cdef class GiacMethods_base: Help for Li: Li(Expr) Logarithm integral Li(x)=Ei(ln(x)) primitive of 1/ln(x). - See also: 1/ Si 2/ Ci 3/ Ei + See also: 1/ Si 2/ Ci 3/ Ei Ex1:Li(2.0) - ''' return GiacMethods['Li'](self,*args) @@ -269,9 +248,8 @@ cdef class GiacMethods_base: Help for Line: Line(Expr(a),Expr(b),Expr(c),Expr(d)) Draws the segment [a+i*b,c+i*d]. - See also: 1/ segment + See also: 1/ segment Ex1:Line(-1,-2,1,2) - ''' return GiacMethods['Line'](self,*args) @@ -280,9 +258,8 @@ cdef class GiacMethods_base: Help for LineHorz: LineHorz(Expr(a)) Draws the horizontal line y=a. - See also: 1/ Line 2/ LineVert + See also: 1/ Line 2/ LineVert Ex1:LineHorz(-1) - ''' return GiacMethods['LineHorz'](self,*args) @@ -291,13 +268,12 @@ cdef class GiacMethods_base: Help for LineTan: LineTan(Expr(f(x)),[Var],Expr(a)) Draws the tangent to y=f(x) at x=a. Do not use parentheses or put the parenthesis around the entire expression. - See also: 1/ tangent 2/ droite_tangente + See also: 1/ tangent 2/ droite_tangente Ex1: LineTan sin(x),pi/4 Ex2: LineTan sin(t),t=pi/4) Ex3: LineTan sin(t),t,pi/4 Ex4: LineTan x^2-x,1 Ex5: (LineTan sin(t),t,pi/4) - ''' return GiacMethods['LineTan'](self,*args) @@ -306,9 +282,8 @@ cdef class GiacMethods_base: Help for LineVert: LineVert(Expr(a)) Draws the vertical line x=a. - See also: 1/ Line 2/ LineHorz + See also: 1/ Line 2/ LineHorz Ex1:LineVert(2) - ''' return GiacMethods['LineVert'](self,*args) @@ -317,10 +292,9 @@ cdef class GiacMethods_base: Help for Phi: Phi(Intg(n)) Euler's function (euler(n)=card({p1 sum(1/n^a,n,1,+infinity). - See also: 1/ sum + See also: 1/ sum Ex1:Zeta(2) - ''' return GiacMethods['Zeta'](self,*args) @@ -507,10 +466,9 @@ cdef class GiacMethods_base: Help for a2q: a2q(Mtrx,VectVar) a2q(A,X)=the quadratic form q associated to A, X=vector of variables. - See also: 1/ q2a + See also: 1/ q2a Ex1:a2q([[1,2],[4,4]],[x,y]) Ex2:a2q([[1,3],[3,4]],[x,y]) - ''' return GiacMethods['a2q'](self,*args) @@ -519,13 +477,12 @@ cdef class GiacMethods_base: Help for abcuv: abcuv(Poly(a),Poly(b),Poly(c),[Var]) Returns [u,v] such that au+bv=c for 3 polynomials a,b,c. - See also: 1/ egcd 2/ iabcuv + See also: 1/ egcd 2/ iabcuv Ex1:abcuv(x^2+2*x+1,x^2-1,x+1) Ex2:abcuv(X^2+2*X+1,X^2-1,X+1,X) Ex3:abcuv(x^2+2*x+1,x^2-1,x^3+1) Ex4:abcuv(X^2+2*X+1,X^2-1,X^3+1,X) Ex5:abcuv([1,2,1],[1,0,-1],[1,0,0,1]) - ''' return GiacMethods['abcuv'](self,*args) @@ -534,10 +491,9 @@ cdef class GiacMethods_base: Help for about: about(Var(a)) Returns the hypothesis made with assume on the variable a. - See also: 1/ assume 2/ purge + See also: 1/ assume 2/ purge Ex1:about(a) Ex2:about(n) - ''' return GiacMethods['about'](self,*args) @@ -546,12 +502,11 @@ cdef class GiacMethods_base: Help for abs: abs(Cplx||LstCplx) Returns the absolute value or the norm of its argument. - See also: 1/ arg + See also: 1/ arg Ex1:abs(-4) Ex2:abs(1+2*i) Ex3:abs((1+2*i)^2) Ex4:abs([-2,1+i,-4]) - ''' return GiacMethods['abs'](self,*args) @@ -560,12 +515,11 @@ cdef class GiacMethods_base: Help for abscissa: abscissa(Pnt or Vect) Returns the abscissa of a point or a vector. - See also: 1/ ordinate 2/ affix 3/ cote 4/ coordinates + See also: 1/ ordinate 2/ affix 3/ cote 4/ coordinates Ex1:abscissa(point(1+2*i)) Ex2:abscissa(point(i)-point(1+2*i)) Ex3:abscissa(-1-i) Ex4:abscissa(point(1,2,3)) - ''' return GiacMethods['abscissa'](self,*args) @@ -574,9 +528,8 @@ cdef class GiacMethods_base: Help for accumulate_head_tail: accumulate_head_tail(Lst(l),Intg(p),Intg(q)) Returns the list where the first p and the last q elements of l are replaced by their sum. - See also: 1/ + See also: 1/ Ex1:accumulate_head_tail([0,1,2,3,4,5,6,7,8,9],3,2) - ''' return GiacMethods['accumulate_head_tail'](self,*args) @@ -585,9 +538,8 @@ cdef class GiacMethods_base: Help for acos: acos(Expr) Arccosine. - See also: 1/ cos 2/ acosh + See also: 1/ cos 2/ acosh Ex1:acos(0) - ''' return GiacMethods['acos'](self,*args) @@ -596,10 +548,9 @@ cdef class GiacMethods_base: Help for acos2asin: acos2asin(Expr) Replaces arccos(x) by pi/2-arcsin(x) in the argument. - See also: 1/ acos2atan + See also: 1/ acos2atan Ex1:acos2asin(acos(x)+asin(x)) Ex2:acos2asin(2*acos(x)) - ''' return GiacMethods['acos2asin'](self,*args) @@ -608,10 +559,9 @@ cdef class GiacMethods_base: Help for acos2atan: acos2atan(Expr) Replaces arccos(x) by pi/2-arctan(x/sqrt(1-x^2)) in the argument. - See also: 1/ acos2asin + See also: 1/ acos2asin Ex1:acos2atan(2*acos(x)) Ex2:acos2atan(acos(sqrt(1-x^2))+acos(x)) - ''' return GiacMethods['acos2atan'](self,*args) @@ -620,9 +570,8 @@ cdef class GiacMethods_base: Help for acosh: acosh(Expr) Hyperbolic arccosine. - See also: 1/ cosh 2/ acos + See also: 1/ cosh 2/ acos Ex1:acosh(1) - ''' return GiacMethods['acosh'](self,*args) @@ -631,9 +580,8 @@ cdef class GiacMethods_base: Help for acot: acot(Expr) Arccotangent. - See also: 1/ atan 2/ arccos + See also: 1/ atan 2/ arccos Ex1:acot(0) - ''' return GiacMethods['acot'](self,*args) @@ -642,10 +590,9 @@ cdef class GiacMethods_base: Help for acsc: acsc(Expr) Arccosecant: acsc(x)=asin(1/x). - See also: 1/ asin 2/ csc + See also: 1/ asin 2/ csc Ex1:acsc(1) Ex2:acsc(2) - ''' return GiacMethods['acsc'](self,*args) @@ -654,8 +601,7 @@ cdef class GiacMethods_base: Help for acyclic: acyclic(Opt) Option for the random_network command. - See also: 1/ random_network - + See also: 1/ random_network ''' return GiacMethods['acyclic'](self,*args) @@ -664,7 +610,7 @@ cdef class GiacMethods_base: Help for add: add(Expr,Var,VarMin(a),VarMax(b),[VarStep(p)]) Discrete sum (with 2 or 4 arguments return then sum from a to b if a<=b or of the opposite of the sum from b+1 to a-1 if a>b+1 or 0 if a=b+1) or the discrete primitive or sum of the elements of a list or a sequence. - See also: 1/ + + See also: 1/ + Ex1:add(1/n^2,n,1,17) Ex2:add(1/n^2,n=1..17) Ex3:add(1/n^2,n,17,1) @@ -675,7 +621,6 @@ cdef class GiacMethods_base: Ex8:add([[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9]]) Ex9:add(1/(x*(x+1)),x) Ex10:add(cos(n*x),n) - ''' return GiacMethods['add'](self,*args) @@ -684,9 +629,8 @@ cdef class GiacMethods_base: Help for add_arc: add_arc(Graph(G),Edge(e)||Trail(T)||Lst(E)) Returns a modified copy of digraph G with added arc e (or trail T or list of arcs E). - See also: 1/ add_edge 2/ delete_arc 3/ digraph 4/ edges 5/ has_arc 6/ trail + See also: 1/ add_edge 2/ delete_arc 3/ digraph 4/ edges 5/ has_arc 6/ trail Ex1:add_arc(digraph(trail(1,2,3,4,5,1)),[[1,3],[2,4]]) - ''' return GiacMethods['add_arc'](self,*args) @@ -695,9 +639,8 @@ cdef class GiacMethods_base: Help for add_edge: add_edge(Graph(G),Edge(e)||Trail(T)||Lst(E)) Returns a modified copy of undirected graph G with added edge e (or trail T or list of edges E). - See also: 1/ add_arc 2/ delete_edge 3/ edges 4/ graph 5/ has_edge 6/ trail + See also: 1/ add_arc 2/ delete_edge 3/ edges 4/ graph 5/ has_edge 6/ trail Ex1:add_edge(graph(trail(1,2,3,4)),[4,1]) - ''' return GiacMethods['add_edge'](self,*args) @@ -706,9 +649,8 @@ cdef class GiacMethods_base: Help for add_vertex: add_vertex(Graph(G),Vrtx(v)||Lst(V)) Returns a modified copy of G with added vertex v [or vertices from list V]. - See also: 1/ add_arc 2/ add_edge 3/ delete_vertex + See also: 1/ add_arc 2/ add_edge 3/ delete_vertex Ex1:add_vertex(cycle_graph(5),["a","b"]) - ''' return GiacMethods['add_vertex'](self,*args) @@ -717,10 +659,9 @@ cdef class GiacMethods_base: Help for additionally: additionally(Expr) Makes an additionally assumption on a variable. - See also: 1/ purge 2/ about 3/ assume + See also: 1/ purge 2/ about 3/ assume Ex1: assume(n,integer);additionally(n>5) Ex2: assume(n,integer);assume(n>=2,additionally) - ''' return GiacMethods['additionally'](self,*args) @@ -729,9 +670,8 @@ cdef class GiacMethods_base: Help for addtable: addtable(fourier||laplace,f(x),F(s),Var(x),Var(s)) Stores an unknown Fourier/Laplace transform pair (f,F). - See also: 1/ fourier 2/ laplace + See also: 1/ fourier 2/ laplace Ex1:addtable(fourier,y(x),Y(s),x,s) - ''' return GiacMethods['addtable'](self,*args) @@ -740,9 +680,8 @@ cdef class GiacMethods_base: Help for adjacency_matrix: adjacency_matrix(Graph(G)) Returns the adjacency matrix of G (rows and columns are indexed by the vertices). - See also: 1/ neighbors + See also: 1/ neighbors Ex1:adjacency_matrix(graph(trail(1,2,3,4,2,5,1,3))) - ''' return GiacMethods['adjacency_matrix'](self,*args) @@ -751,9 +690,8 @@ cdef class GiacMethods_base: Help for adjoint_matrix: adjoint_matrix(Mtrx) Returns the characteristic polynomial of A and the comatrix of A-xI. - See also: 1/ pcar + See also: 1/ pcar Ex1:adjoint_matrix([[1,i],[2,3]]) - ''' return GiacMethods['adjoint_matrix'](self,*args) @@ -762,11 +700,10 @@ cdef class GiacMethods_base: Help for affix: affix(Pnt||Vect) Complex number equal to the affix of a point or of a vector. - See also: 1/ point 2/ vector + See also: 1/ point 2/ vector Ex1:affix(point(i)) Ex2:affix(point(i)-point(1+2*i)) Ex3:affix([1,2]) - ''' return GiacMethods['affix'](self,*args) @@ -775,11 +712,10 @@ cdef class GiacMethods_base: Help for algsubs: algsubs(Equal(Xpr1=Xpr2),Expr(Xpr)) Substitutes in the expression Xpr, the algebraic expression Xpr1 by the algebraic expression Xpr2. - See also: 1/ subst 2/ subs + See also: 1/ subst 2/ subs Ex1:algsubs(x^2=u,1+x^2+x^4) Ex2:algsubs(a*b/c=d, 2*a*b^2/c) Ex3:algsubs(2a=p^2-q^2,algsubs(2c=p^2+q^2,c^2-a^2)) - ''' return GiacMethods['algsubs'](self,*args) @@ -788,9 +724,8 @@ cdef class GiacMethods_base: Help for algvar: algvar(Expr) List of the variables by ascending algebraic extension order. - See also: 1/ lvar 2/ lname + See also: 1/ lvar 2/ lname Ex1:algvar(sqrt(x)+y) - ''' return GiacMethods['algvar'](self,*args) @@ -799,10 +734,9 @@ cdef class GiacMethods_base: Help for all_trig_solutions: all_trig_solutions(:=Intg(0 or 1)) Pseudo-variable to return the general solution (all_trig_solutions:=1) or principal solution (all_trig_solutions:=0). - See also: 1/ cas_setup + See also: 1/ cas_setup Ex1: all_trig_solutions:=1 Ex2: all_trig_solutions:=0 - ''' return GiacMethods['all_trig_solutions'](self,*args) @@ -811,9 +745,8 @@ cdef class GiacMethods_base: Help for allpairs_distance: allpairs_distance(Graph(G)) Returns a square matrix D of order equal to the number of vertices in G such that D(i,j) is the distance between i-th and j-th vertex of the (weighted) graph G. - See also: 1/ dijkstra 2/ graph_diameter 3/ vertex_distance + See also: 1/ dijkstra 2/ graph_diameter 3/ vertex_distance Ex1:allpairs_distance(graph(%{[1,2],[1,3],[1,4],[1,5],[2,3],[3,4],[4,5],[5,2]%})) - ''' return GiacMethods['allpairs_distance'](self,*args) @@ -822,9 +755,8 @@ cdef class GiacMethods_base: Help for alog10: alog10(Expr) Function x->10^x. - See also: 1/ log10 + See also: 1/ log10 Ex1:alog10(3) - ''' return GiacMethods['alog10'](self,*args) @@ -833,9 +765,8 @@ cdef class GiacMethods_base: Help for altitude: altitude((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) altitude(A,B,C) draws the altitude through A of the triangle ABC. - See also: 1/ perpendicular 2/ orthogonal 3/ orthocenter 4/ common_perpendicular + See also: 1/ perpendicular 2/ orthogonal 3/ orthocenter 4/ common_perpendicular Ex1:altitude(-1,1-i,i) - ''' return GiacMethods['altitude'](self,*args) @@ -844,13 +775,12 @@ cdef class GiacMethods_base: Help for angle: angle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) angle(A,B,C) is the value of the measure of the angle (AB,AC). - See also: 1/ triangle 2/ bissector 3/ legend 4/ labels 5/ angleat 6/ angleatraw + See also: 1/ triangle 2/ bissector 3/ legend 4/ labels 5/ angleat 6/ angleatraw Ex1:angle(point(0),point(i),point(1)) Ex2:angle(0,1,i) Ex3:angle(0,1,i,"") Ex4:angle(0,1,i,"a") Ex5:angle(i,1,1+i,"b") - ''' return GiacMethods['angle'](self,*args) @@ -859,10 +789,9 @@ cdef class GiacMethods_base: Help for angle_radian: angle_radian(:=Intg(0 or 1)) Pseudo-variable to work with radians (angle_radian:=1) or degrees (angle_radian:=0). - See also: 1/ cas_setup + See also: 1/ cas_setup Ex1: angle_radian:=1 Ex2: angle_radian:=0 - ''' return GiacMethods['angle_radian'](self,*args) @@ -871,9 +800,8 @@ cdef class GiacMethods_base: Help for angleat: angleat(Pnt(A),Pnt(B),Pnt(C),(Pnt or Cplx(z0))) angleat(A,B,C,z0) displays at point(z0) with a legend, the value of the measure of the angle (AB,AC). - See also: 1/ angle 2/ angleatraw 3/ legend + See also: 1/ angle 2/ angleatraw 3/ legend Ex1: A:=point(0);B:=point(1);C:=point(i);angleat(A,B,C,-2-i) - ''' return GiacMethods['angleat'](self,*args) @@ -882,9 +810,8 @@ cdef class GiacMethods_base: Help for angleatraw: angleatraw(Pnt(A)),Pnt(B),Pnt(C),(Pnt or Cplx(z0))) angleatraw(A,B,C,z0) displays at point(z0), the value of the measure of the angle (AB,AC). - See also: 1/ angle 2/ angleat + See also: 1/ angle 2/ angleat Ex1: A:=point(0);B:=point(1);C:=point(i);angleatraw(A,B,C,-2-i) - ''' return GiacMethods['angleatraw'](self,*args) @@ -893,11 +820,10 @@ cdef class GiacMethods_base: Help for ans: ans(Intg(n)) Returns the (n+1)th answer of the command history if n>=0 or, the (-n)th previous answer if n<0 (by default n=-1 for the previous answer). - See also: 1/ quest + See also: 1/ quest Ex1:ans() Ex2:ans(2) Ex3:ans(-2) - ''' return GiacMethods['ans'](self,*args) @@ -906,9 +832,8 @@ cdef class GiacMethods_base: Help for antiprism_graph: antiprism_graph(Intg(n)) Returns the antiprism graph of order n. - See also: 1/ prism_graph + See also: 1/ prism_graph Ex1:antiprism_graph(5) - ''' return GiacMethods['antiprism_graph'](self,*args) @@ -917,14 +842,13 @@ cdef class GiacMethods_base: Help for append: append((Lst||Set||Str(L),Elem)) Append an element to a set or at the end of a list or of a string (L:=append(L,a) or L.append(a)). - See also: 1/ concat 2/ prepend + See also: 1/ concat 2/ prepend Ex1:append([1,2,4],6) Ex2:append(%{1,2,4%},6) Ex3: L:=[1,2,4];L:=append(L,6) Ex4: L:=[1,2,4];L.append(6) Ex5: S:=set[1,2,4];S:=append(S,6) Ex6: S:=set[1,2,4];S.append(6) - ''' return GiacMethods['append'](self,*args) @@ -933,10 +857,9 @@ cdef class GiacMethods_base: Help for apply: apply(Fnc(f),Lst(l)) Applies the function f at the elements of the list l (option matrix for a matrix). - See also: 1/ map 2/ unapply 3/ matrix + See also: 1/ map 2/ unapply 3/ matrix Ex1:apply(x->x^3,[1,2,3]) Ex2:apply(x->x+1,[[1,2,3],[1,2,3]],matrix) - ''' return GiacMethods['apply'](self,*args) @@ -945,14 +868,13 @@ cdef class GiacMethods_base: Help for approx: approx(Expr,[Int]) Numerical evaluation of the first argument (we can give the number of digits as second argument). - See also: 1/ evalb 2/ eval + See also: 1/ evalb 2/ eval Ex1:approx(2/3) Ex2:approx(2/3,2) Ex3:approx(2*sin(1)) Ex4:approx(2*sin(1),40) Ex5:approx(sqrt(2)+pi) Ex6:approx(sqrt(2)+pi,30) - ''' return GiacMethods['approx'](self,*args) @@ -961,12 +883,11 @@ cdef class GiacMethods_base: Help for arc: arc(Pnt, Pnt, Real,[Var(C)],[Var(r)],[Opt(segment)]) Draws a circular arc given by 2 vertices and the central angle [Xcas will put the center in C and the radius in r]. - See also: 1/ circle 2/ segment 3/ plotparam + See also: 1/ circle 2/ segment 3/ plotparam Ex1:arc(0,1,pi/4) Ex2:arc(i,1,pi/4,C,r) Ex3:arc(i,1,pi/4,segment) Ex4:arc(i,1,pi/4,segment,affichage=1+rempli) - ''' return GiacMethods['arc'](self,*args) @@ -975,11 +896,10 @@ cdef class GiacMethods_base: Help for arcLen: arcLen(Expr(Xpr) or Lst([Xpr1,Xpr2]),Var,Real(a),Real(b)) Returns the length of the arc of the curve defined by y=Xpr(or by x=Xpr1,y=Xpr2) when the parameter values are between a and b. - See also: 1/ int + See also: 1/ int Ex1:arcLen(t^2,t,1,2) Ex2:arcLen([t,t^2],t,1,2) Ex3:arcLen([cos(t),sin(t)],t,1,2) - ''' return GiacMethods['arcLen'](self,*args) @@ -988,9 +908,8 @@ cdef class GiacMethods_base: Help for arccos: arccos(Expr) Arccosine. - See also: 1/ cos 2/ acosh + See also: 1/ cos 2/ acosh Ex1:arccos(0) - ''' return GiacMethods['arccos'](self,*args) @@ -999,9 +918,8 @@ cdef class GiacMethods_base: Help for arccosh: arccosh(Expr) Hyperbolic arccosine. - See also: 1/ cosh 2/ acos + See also: 1/ cosh 2/ acos Ex1:arccosh(1) - ''' return GiacMethods['arccosh'](self,*args) @@ -1010,11 +928,10 @@ cdef class GiacMethods_base: Help for arclen: arclen(Expr(Xpr) or Lst([Xpr1,Xpr2]),Var,Real(a),Real(b)) Returns the length of the arc of the curve defined by y=Xpr(or by x=Xpr1,y=Xpr2) when the parameter values are between a and b. - See also: 1/ int + See also: 1/ int Ex1:arclen(t^2,t,1,2) Ex2:arclen([t,t^2],t,1,2) Ex3:arclen([cos(t),sin(t)],t,1,2) - ''' return GiacMethods['arclen'](self,*args) @@ -1023,9 +940,8 @@ cdef class GiacMethods_base: Help for arcsin: arcsin(Expr) Arcsine. - See also: 1/ sin + See also: 1/ sin Ex1:arcsin(0) - ''' return GiacMethods['arcsin'](self,*args) @@ -1034,9 +950,8 @@ cdef class GiacMethods_base: Help for arcsinh: arcsinh(Expr) Hyperbolic arcsine. - See also: 1/ sinh 2/ asin + See also: 1/ sinh 2/ asin Ex1:arcsinh(0) - ''' return GiacMethods['arcsinh'](self,*args) @@ -1045,9 +960,8 @@ cdef class GiacMethods_base: Help for arctan: arctan(Expr) Arctangent. - See also: 1/ tan 2/ atanh + See also: 1/ tan 2/ atanh Ex1:arctan(0) - ''' return GiacMethods['arctan'](self,*args) @@ -1056,9 +970,8 @@ cdef class GiacMethods_base: Help for arctanh: arctanh(Expr) Hyperbolic arctangent. - See also: 1/ atan 2/ tanh + See also: 1/ atan 2/ tanh Ex1:arctanh(0) - ''' return GiacMethods['arctanh'](self,*args) @@ -1067,7 +980,7 @@ cdef class GiacMethods_base: Help for area: area(Polygone || Expr,x=a..b,[n],[Method]) Algebraic area of a circle, a circular arc or of a (star) polygon (e.g. triangle, square, ...) or of the area below a curve, optionally with a quadrature method (trapezoid,left_rectangle,right_rectangle,middle_point,simpson,rombergt,rombergm). - See also: 1/ trapezoid 2/ perimeter 3/ areaatraw 4/ areaat 5/ areaplot + See also: 1/ trapezoid 2/ perimeter 3/ areaatraw 4/ areaat 5/ areaplot Ex1:area(triangle(0,1,i)) Ex2:area(square(0,2)) Ex3:area(circle(0,2)) @@ -1075,7 +988,6 @@ cdef class GiacMethods_base: Ex5:area(x^2,x=0..1,5,trapezoid) Ex6:area(x^2,x=0..1,5,simpson) Ex7:area(x^2,x=0..1,5,rombergm) - ''' return GiacMethods['area'](self,*args) @@ -1084,13 +996,12 @@ cdef class GiacMethods_base: Help for areaat: areaat(Polygone, Pnt||Cplx(z0)) Displays at point(z0), with a legend, the algebraic area of a circle or of a (star) polygon (e.g. triangle, square, ...) - See also: 1/ area 2/ areaatraw 3/ polygon 4/ perimeteratraw 5/ areaplot + See also: 1/ area 2/ areaatraw 3/ polygon 4/ perimeteratraw 5/ areaplot Ex1: t:=triangle(0,1,i);areaat(t,(1+i)/2) Ex2: c:=square(0,2);areaat(c,1+i) Ex3: c2:=circle(0,2);areaat(c2,1+i) Ex4: p:=polygon(0,1,i);areaat(p,1+i) Ex5: A:=point(0);B:=point(1+i);c:=carre(A,B);areaat(c,i) - ''' return GiacMethods['areaat'](self,*args) @@ -1099,13 +1010,12 @@ cdef class GiacMethods_base: Help for areaatraw: areaatraw(Polygone, Pnt||Cplx(z0)) Displays at point(z0), the algebraic area of a circle or of a (star-)polygon (e.g. triangle, square, ...) - See also: 1/ area 2/ areaat 3/ polygon 4/ perimeteratraw 5/ areaplot + See also: 1/ area 2/ areaat 3/ polygon 4/ perimeteratraw 5/ areaplot Ex1:areaatraw(triangle(0,1,i),(1+i)/2) Ex2:areaatraw(square(0,2),1+i) Ex3:areaatraw(circle(0,2),1+i) Ex4:areaatraw(polygon(0,1,i),1+i) Ex5: A:=point(0);B:=point(1+i);c:=carre(A,B);areaatraw(c,i) - ''' return GiacMethods['areaatraw'](self,*args) @@ -1114,11 +1024,10 @@ cdef class GiacMethods_base: Help for areaplot: areaplot(Expr,x=a..b,[n],[Method]) Displays the area below a curve, optionally with a quadrature method (trapezoid,left_rectangle,right_rectangle,middle_point). - See also: 1/ integrate 2/ plot 3/ area 4/ areaat 5/ areaatraw + See also: 1/ integrate 2/ plot 3/ area 4/ areaat 5/ areaatraw Ex1:areaplot(sin(x),x=0..pi) Ex2:areaplot(x^2,x=0..1,5,trapezoid) Ex3:areaplot(x^2,x=0..1,5,middle_point) - ''' return GiacMethods['areaplot'](self,*args) @@ -1127,11 +1036,10 @@ cdef class GiacMethods_base: Help for arg: arg(Expr) Returns the argument of a complex number. - See also: 1/ abs + See also: 1/ abs Ex1:arg(1+i) Ex2:arg(1+2*i) Ex3:arg((1+2*i)^2) - ''' return GiacMethods['arg'](self,*args) @@ -1140,10 +1048,9 @@ cdef class GiacMethods_base: Help for array: array(Opt) Option for convert for definitions of sparse matrices. - See also: 1/ convert 2/ table + See also: 1/ convert 2/ table Ex1: A[0..2,0..2]:=1;A[0..1,1..2]:=2;convert(A,array) Ex2: B[0..1,1..2]:=1;B[2,2]:=2;convert(B,array) - ''' return GiacMethods['array'](self,*args) @@ -1152,9 +1059,8 @@ cdef class GiacMethods_base: Help for arrivals: arrivals(Graph(G),[Vrtx(v)]) Returns the list of vertices in digraph G which are connected by v with arcs such that heads are in v. If v is omitted, a list of arrivals is computed for every vertex in G. - See also: 1/ in_degree + See also: 1/ in_degree Ex1:arrivals(digraph(%{[1,2],[1,3],[2,3]%}),1) - ''' return GiacMethods['arrivals'](self,*args) @@ -1163,10 +1069,9 @@ cdef class GiacMethods_base: Help for articulation_points: articulation_points(Graph(G)) Returns the list of articulation points (cut vertices) of G. - See also: 1/ biconnected_components 2/ is_biconnected 3/ is_connected 4/ is_triconnected + See also: 1/ biconnected_components 2/ is_biconnected 3/ is_connected 4/ is_triconnected Ex1:articulation_points(path_graph(5)) Ex2:articulation_points(cycle_graph(5)) - ''' return GiacMethods['articulation_points'](self,*args) @@ -1175,9 +1080,8 @@ cdef class GiacMethods_base: Help for asin: asin(Expr) Arcsine. - See also: 1/ sin + See also: 1/ sin Ex1:asin(0) - ''' return GiacMethods['asin'](self,*args) @@ -1186,10 +1090,9 @@ cdef class GiacMethods_base: Help for asin2acos: asin2acos(Expr) Replaces arcsin(x) by pi/2-arccos(x) in the argument. - See also: 1/ asin2atan + See also: 1/ asin2atan Ex1:asin2acos(acos(x)+asin(x)) Ex2:asin2acos(2*asin(x)) - ''' return GiacMethods['asin2acos'](self,*args) @@ -1198,10 +1101,9 @@ cdef class GiacMethods_base: Help for asin2atan: asin2atan(Expr) Replaces arcsin(x) by arctan(x/sqrt(1-x^2)) in the argument. - See also: 1/ asin2acos + See also: 1/ asin2acos Ex1:asin2atan(2*asin(x)) Ex2:asin2atan(asin(sqrt(1-x^2))+asin(x)) - ''' return GiacMethods['asin2atan'](self,*args) @@ -1210,9 +1112,8 @@ cdef class GiacMethods_base: Help for asinh: asinh(Expr) Hyperbolic arcsine. - See also: 1/ sinh 2/ asin + See also: 1/ sinh 2/ asin Ex1:asinh(0) - ''' return GiacMethods['asinh'](self,*args) @@ -1221,10 +1122,9 @@ cdef class GiacMethods_base: Help for assign_edge_weights: assign_edge_weights(Graph(G),Seq(m,n)||Intrv(a..b)) Assigns random edge weights to the edges of G and returns a modified copy of G. If integers n and m such that n>=m are specified, weights are integers randomly chosen in [m,n]. If an interval a..b is specified, weights are uniformly distributed in the interval [a,b). - See also: 1/ set_edge_weight 2/ get_edge_weight 3/ weight_matrix 4/ random_digraph 5/ random_tournament + See also: 1/ set_edge_weight 2/ get_edge_weight 3/ weight_matrix 4/ random_digraph 5/ random_tournament Ex1:assign_edge_weights(digraph(trail(1,2,3,4,1)),1,9) Ex2:assign_edge_weights(digraph(trail(1,2,3,4,1)),0..1) - ''' return GiacMethods['assign_edge_weights'](self,*args) @@ -1233,7 +1133,7 @@ cdef class GiacMethods_base: Help for assume: assume(Expr) Makes an assumption on a variable. - See also: 1/ purge 2/ about 3/ additionally + See also: 1/ purge 2/ about 3/ additionally Ex1:assume(a>0) Ex2:assume(a=0.3) Ex3:assume(a:=[pi/4,0,pi/2]) @@ -1244,7 +1144,6 @@ cdef class GiacMethods_base: Ex8:assume((a>=2 and a<4) or a>6) Ex9:assume(a>=2);additionally(a<6) Ex10:assume(a) - ''' return GiacMethods['assume'](self,*args) @@ -1253,10 +1152,9 @@ cdef class GiacMethods_base: Help for at: at(Lst(l)||Mtrx(m),Index(j)||Lst([j,k])) at(l,j) (or at(m,[j,k])) is the element of the list l (or matrix m) for index=j (or for index j,k). - See also: 1/ of + See also: 1/ of Ex1:at([10,11,12],1) Ex2:at([[1,2],[3,4]],[1,0]) - ''' return GiacMethods['at'](self,*args) @@ -1265,9 +1163,8 @@ cdef class GiacMethods_base: Help for atan: atan(Expr) Arctangent. - See also: 1/ tan 2/ atanh + See also: 1/ tan 2/ atanh Ex1:atan(0) - ''' return GiacMethods['atan'](self,*args) @@ -1276,8 +1173,7 @@ cdef class GiacMethods_base: Help for atan2acos: atan2acos(Expr) Replaces arctan(x) by pi/2-arccos(x/sqrt(1+x^2)) in the argument. - See also: 1/ atan2acos(atan(x)) - + See also: 1/ atan2acos(atan(x)) ''' return GiacMethods['atan2acos'](self,*args) @@ -1286,8 +1182,7 @@ cdef class GiacMethods_base: Help for atan2asin: atan2asin(Expr) Replaces arctan(x) by arcsin(x/sqrt(1+x^2)) in the argument. - See also: 1/ atan2asin(atan(x)) - + See also: 1/ atan2asin(atan(x)) ''' return GiacMethods['atan2asin'](self,*args) @@ -1296,9 +1191,8 @@ cdef class GiacMethods_base: Help for atanh: atanh(Expr) Hyperbolic arctangent. - See also: 1/ atan 2/ tanh + See also: 1/ atan 2/ tanh Ex1:atanh(0) - ''' return GiacMethods['atanh'](self,*args) @@ -1307,11 +1201,10 @@ cdef class GiacMethods_base: Help for atrig2ln: atrig2ln(Expr) Rewrites the expression containing inverse trigonometric functions into logarithmic functions. - See also: 1/ trig2exp 2/ exp2trig + See also: 1/ trig2exp 2/ exp2trig Ex1:atrig2ln(atan(x)) Ex2:atrig2ln(asin(x)) Ex3:atrig2ln(acos(x)) - ''' return GiacMethods['atrig2ln'](self,*args) @@ -1320,13 +1213,12 @@ cdef class GiacMethods_base: Help for augment: augment(Lst,Lst||Seq,Seq||Str,Str||Mtrx,Mtrx) Concatenates two lists or two strings or two sequences or 2 matrices; L:=concat(L,L1) or L.concat(L1). - See also: 1/ append 2/ cat 3/ semi_augment 4/ border 5/ + + See also: 1/ append 2/ cat 3/ semi_augment 4/ border 5/ + Ex1:augment([1,2],[3,4,5]) Ex2:augment("bon","jour") Ex3:augment([[1,2],[3,4]],[[4,5,6],[6,7,8]]) Ex4: L:=[1,2];L.concat([3,4,5]) Ex5: S:="abcd";S.concat("efghi") - ''' return GiacMethods['augment'](self,*args) @@ -1335,9 +1227,8 @@ cdef class GiacMethods_base: Help for auto_correlation: auto_correlation(Lst) Returns the cross-correlation of the given signal with itself. - See also: 1/ cross_correlation 2/ correlation + See also: 1/ cross_correlation 2/ correlation Ex1:auto_correlation([1,-1,0,2,1]) - ''' return GiacMethods['auto_correlation'](self,*args) @@ -1346,14 +1237,13 @@ cdef class GiacMethods_base: Help for autosimplify: autosimplify(Cmds) The argument is a command that Xcas will use to rewrite answers (initial value is regroup and for no simplification it is nop or 0). - See also: 1/ simplify 2/ factor 3/ regroup + See also: 1/ simplify 2/ factor 3/ regroup Ex1:autosimplify(nop) Ex2:autosimplify(0) Ex3:autosimplify(regroup) Ex4:autosimplify(1) Ex5:autosimplify(factor) Ex6:autosimplify(simplify) - ''' return GiacMethods['autosimplify'](self,*args) @@ -1362,10 +1252,9 @@ cdef class GiacMethods_base: Help for avance: avance(NULL or Real(n)) The turtle takes n steps forward (by default n=10). - See also: 1/ recule 2/ saute + See also: 1/ recule 2/ saute Ex1: avance 30 Ex2:avance(30) - ''' return GiacMethods['avance'](self,*args) @@ -1374,11 +1263,10 @@ cdef class GiacMethods_base: Help for avgRC: avgRC(Expr(Xpr),Var(Var),[Real(h)]) Returns (Xpr(var+h)-Xpr(Var))/h (by default h=0.001). - See also: 1/ nDeriv + See also: 1/ nDeriv Ex1:avgRC(f(x),x,h) Ex2:avgRC(x^2,x,0.1) Ex3:avgRC(x^2,x) - ''' return GiacMethods['avgRC'](self,*args) @@ -1387,10 +1275,9 @@ cdef class GiacMethods_base: Help for axes: axes(Opt) Global option (Maple compatibility) of a graphic command to put or not the axes. - See also: 1/ line_width 2/ gl_showaxes 3/ switch_axes + See also: 1/ line_width 2/ gl_showaxes 3/ switch_axes Ex1: axes=0;segment(0,point(1,1)) Ex2: axes=1;segment(0,point(1,1),epaisseur=5) - ''' return GiacMethods['axes'](self,*args) @@ -1400,7 +1287,6 @@ cdef class GiacMethods_base: axis(xmin,xmax,ymin,ymax,[zmin,zmaz]) Defines the graphic display Ex1:axis(-2,4,-1,6) - ''' return GiacMethods['axis'](self,*args) @@ -1409,11 +1295,10 @@ cdef class GiacMethods_base: Help for back: back(Vect or Seq or Str) Returns the last element of a vector or a sequence or a string. - See also: 1/ inter 2/ head 3/ mid 4/ left 5/ right + See also: 1/ inter 2/ head 3/ mid 4/ left 5/ right Ex1:back(1,2,3) Ex2:back([1,2,3]) Ex3:back("bonjour") - ''' return GiacMethods['back'](self,*args) @@ -1422,10 +1307,9 @@ cdef class GiacMethods_base: Help for backward: backward(NULL or Real(n)) The turtle takes n steps back (by default n=10). - See also: 1/ avance 2/ saute + See also: 1/ avance 2/ saute Ex1: recule 30 Ex2:backward(30) - ''' return GiacMethods['backward'](self,*args) @@ -1434,9 +1318,8 @@ cdef class GiacMethods_base: Help for baisse_crayon: baisse_crayon(NULL) Presses the pencil down so that the turtle move with traces. - See also: 1/ leve_crayon 2/ crayon + See also: 1/ leve_crayon 2/ crayon Ex1:baisse_crayon() - ''' return GiacMethods['baisse_crayon'](self,*args) @@ -1445,8 +1328,7 @@ cdef class GiacMethods_base: Help for bandwidth: bandwidth(Opt) Option for the kernel_density command. - See also: 1/ kernel_density 2/ bins - + See also: 1/ kernel_density 2/ bins ''' return GiacMethods['bandwidth'](self,*args) @@ -1455,11 +1337,10 @@ cdef class GiacMethods_base: Help for bar_plot: bar_plot(Mtrx) Draws a barplot of a one variable statistical series. - See also: 1/ camembert 2/ histogram 3/ frequencies + See also: 1/ camembert 2/ histogram 3/ frequencies Ex1:bar_plot([["France",6],["Allemagne",12],["Suisse",5]]) Ex2:bar_plot([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:bar_plot([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) - ''' return GiacMethods['bar_plot'](self,*args) @@ -1468,11 +1349,10 @@ cdef class GiacMethods_base: Help for barplot: barplot(Mtrx) Draws a barplot of a one variable statistical series. - See also: 1/ camembert 2/ histogram 3/ frequencies + See also: 1/ camembert 2/ histogram 3/ frequencies Ex1:barplot([["France",6],["Allemagne",12],["Suisse",5]]) Ex2:barplot([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:barplot([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) - ''' return GiacMethods['barplot'](self,*args) @@ -1481,9 +1361,8 @@ cdef class GiacMethods_base: Help for bartlett_hann_window: bartlett_hann_window(Lst,[Interval(n1..n2)]) Applies the Bartlett-Hann windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(bartlett_hann_window(randvector(1000,0..1))) - ''' return GiacMethods['bartlett_hann_window'](self,*args) @@ -1492,11 +1371,10 @@ cdef class GiacMethods_base: Help for barycenter: barycenter([Pnt,Real],[Pnt,Real],[Pnt,Real]) barycenter([point1,coeff1],...) draws the barycenter of point1 with weight coeff1... - See also: 1/ isobarycenter 2/ midpoint + See also: 1/ isobarycenter 2/ midpoint Ex1:barycenter([point(-1),1],[point(1+i),2],[point(1-i),1]) Ex2:barycenter([[point(-1),1],[point(1+i),2],[point(1-i),1]]) Ex3:barycenter([point(-1),point(1+i),point(1-i)],[1,2,1]) - ''' return GiacMethods['barycenter'](self,*args) @@ -1505,11 +1383,10 @@ cdef class GiacMethods_base: Help for base: base(Opt) Option for convert : convert(p,base,b)= [a0,a1,..an] or convert([a0,a1,..an],base,b)=p with p=a0+a1*b+....an*b^(n-1). - See also: 1/ convert 2/ horner 3/ revlist + See also: 1/ convert 2/ horner 3/ revlist Ex1: convert(123,base,8) Ex2: convert([3,7,1],base,8) Ex3: horner(revlist([3,7,1]),8) - ''' return GiacMethods['base'](self,*args) @@ -1518,9 +1395,8 @@ cdef class GiacMethods_base: Help for basis: basis(Lst(vector1,..,vectorn)) Extracts a basis from a spanning set of vectors. - See also: 1/ ker 2/ ibasis + See also: 1/ ker 2/ ibasis Ex1:basis([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) - ''' return GiacMethods['basis'](self,*args) @@ -1529,11 +1405,10 @@ cdef class GiacMethods_base: Help for batons: batons(Mtrx) Draws for k=0..nrows, the segments (xk,0)-(xk,yk) where xk=element row k column 0 and yk=element row k column j (j=1..ncols). - See also: 1/ polygonplot 2/ scatterplot 3/ listplot + See also: 1/ polygonplot 2/ scatterplot 3/ listplot Ex1:batons([1,3],[2,5],[3,2]) Ex2:batons([[1,3],[2,5],[3,2]]) Ex3:batons([1,2,3],[3,5,2]) - ''' return GiacMethods['batons'](self,*args) @@ -1542,9 +1417,8 @@ cdef class GiacMethods_base: Help for bellman_ford: bellman_ford(Graph(G),Vrtx(s),Vrtx(t)||Lst(T)) Returns the length of the shortest path resp. paths from s to vertex t resp. vertices in T in weighted graph G. - See also: 1/ dijkstra 2/ shortest_path + See also: 1/ dijkstra 2/ shortest_path Ex1:bellman_ford(graph(%{[[1,2],-1],[[2,3],-3],[[3,4],-7],[[4,5],-3],[[5,6],-3],[[1,6],-3]%}),1,4) - ''' return GiacMethods['bellman_ford'](self,*args) @@ -1553,10 +1427,9 @@ cdef class GiacMethods_base: Help for bernoulli: bernoulli(Intg||(Intg,Var)) bernoulli(n) is the n-th number of Bernoulli and bernoulli(n,x) is the n-th polynomial of Bernoulli and the second argument is the variable. - See also: 1/ + See also: 1/ Ex1:bernoulli(6) Ex2:bernoulli(6,x) - ''' return GiacMethods['bernoulli'](self,*args) @@ -1565,10 +1438,9 @@ cdef class GiacMethods_base: Help for besselJ: besselJ(Real(x),Int(p)) besselJ(x,p) returns the Bessel function of the first kind Jp(x). - See also: 1/ BesselJ 2/ BesselY 3/ besselY + See also: 1/ BesselJ 2/ BesselY 3/ besselY Ex1:besselJ(sqrt(2),2) Ex2:besselJ(sqrt(2),-2) - ''' return GiacMethods['besselJ'](self,*args) @@ -1577,10 +1449,9 @@ cdef class GiacMethods_base: Help for besselY: besselY(Real(x),Int(p)) besselY(x,p) returns the Bessel function of the second kind Yp(x). - See also: 1/ BesselY 2/ BesselJ 3/ besselJ + See also: 1/ BesselY 2/ BesselJ 3/ besselJ Ex1:besselY(sqrt(2),2) Ex2:besselY(sqrt(2),-2) - ''' return GiacMethods['besselY'](self,*args) @@ -1589,9 +1460,8 @@ cdef class GiacMethods_base: Help for betad: betad(Real(a>0),Real(b>0),Real(0<=x<=1)) Returns the probability density of the Beta law (=Gamma(a+b)*x^(a-1)*(1-x)^(b-1)/(Gamma(a)*Gamma(b))). - See also: 1/ betad_cdf 2/ betad_icdf + See also: 1/ betad_cdf 2/ betad_icdf Ex1:betad(2.2,1.5,0.8) - ''' return GiacMethods['betad'](self,*args) @@ -1600,10 +1470,9 @@ cdef class GiacMethods_base: Help for betad_cdf: betad_cdf(Real(a>0),Real(b>0),Real(0<=x0<=1),[Real(0<=y0<=1)]) Returns the probability that a Beta random variable (with a and b as parameters) is less than x0 or between x0 and y0. - See also: 1/ betad 2/ betad_icdf + See also: 1/ betad 2/ betad_icdf Ex1:betad_cdf(2,1,0.2) Ex2:betad_cdf(2,1,0.1,0.3) - ''' return GiacMethods['betad_cdf'](self,*args) @@ -1612,10 +1481,9 @@ cdef class GiacMethods_base: Help for betad_icdf: betad_icdf(Real(a>0),Real(b>0),Real(0<=p<=1)) Returns h such that the probability that a Beta random variable is less than h is p (0<=p<=1). - See also: 1/ betad_cdf 2/ betad + See also: 1/ betad_cdf 2/ betad Ex1:betad_icdf(2,1,0.95) Ex2:betad_icdf(2,1,0.5) - ''' return GiacMethods['betad_icdf'](self,*args) @@ -1624,10 +1492,9 @@ cdef class GiacMethods_base: Help for betavariate: betavariate(Real(a),Real(b)) Returns a random real according to the Beta distribution with parameters a>0 and b>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:betavariate(1,2) Ex2:betavariate(1.5,4) - ''' return GiacMethods['betavariate'](self,*args) @@ -1636,12 +1503,11 @@ cdef class GiacMethods_base: Help for bezier: bezier(Lst,[plot]) Bezier curve defined by control points. - See also: 1/ parameq + See also: 1/ parameq Ex1:bezier(1,1+i,2+i,3-i,plot) Ex2:bezier(point([0,0,0]),point([1,1,0]),point([0,1,1]),plot) Ex3: parameq(bezier(1,1+i,2+i,3-i)) Ex4: parameq(bezier(point([0,0,0]),point([1,1,0]),point([0,1,1]))) - ''' return GiacMethods['bezier'](self,*args) @@ -1650,11 +1516,10 @@ cdef class GiacMethods_base: Help for bezout_entiers: bezout_entiers(Intg,Intg) Extended greatest common divisor of 2 integers. - See also: 1/ gcd 2/ iabcuv 3/ egcd + See also: 1/ gcd 2/ iabcuv 3/ egcd Ex1:bezout_entiers(45,75) Ex2:bezout_entiers(21,28) Ex3:bezout_entiers(30,49) - ''' return GiacMethods['bezout_entiers'](self,*args) @@ -1663,9 +1528,8 @@ cdef class GiacMethods_base: Help for biconnected_components: biconnected_components(Graph(G)) Returns the biconnected components of G as a list of lists of vertices. - See also: 1/ articulation_points 2/ is_biconnected 3/ is_connected 4/ trail + See also: 1/ articulation_points 2/ is_biconnected 3/ is_connected 4/ trail Ex1:biconnected_components(graph(trail(1,2,3,4,2),trail(4,5,6,7,5))) - ''' return GiacMethods['biconnected_components'](self,*args) @@ -1674,7 +1538,7 @@ cdef class GiacMethods_base: Help for binomial: binomial(Intg(n),Intg(k),[Real(p in 0..1)]) Returns comb(n,k)*p^k*(1-p)^(n-k) or comb(n,k) if no 3rd argument. - See also: 1/ binomial_cdf 2/ binomial_icdf 3/ multinomial 4/ randvector 5/ ranm + See also: 1/ binomial_cdf 2/ binomial_icdf 3/ multinomial 4/ randvector 5/ ranm Ex1:binomial(4,2) Ex2:binomial(4,0,0.5) Ex3:binomial(4,2,0.5) @@ -1682,7 +1546,6 @@ cdef class GiacMethods_base: Ex5: assume(p>=0 and p<=1);binomial(4,p,2) Ex6: randvector(6,binomial,4,0.2) Ex7: ranm(4,6,binomial,4,0.7) - ''' return GiacMethods['binomial'](self,*args) @@ -1691,11 +1554,10 @@ cdef class GiacMethods_base: Help for binomial_cdf: binomial_cdf(Intg(n),Real(p),Real(x),[Real(y)]) Returns Proba(X<=x) or Proba(x<=X<=y) when X follows the B(n,p) law. - See also: 1/ binomial 2/ binomial_icdf + See also: 1/ binomial 2/ binomial_icdf Ex1:binomial_cdf(4,0.5,2) Ex2:binomial_cdf(4,0.1,2) Ex3:binomial_cdf(4,0.5,2,3) - ''' return GiacMethods['binomial_cdf'](self,*args) @@ -1704,10 +1566,9 @@ cdef class GiacMethods_base: Help for binomial_icdf: binomial_icdf(Intg(n),Real(p),Real(t)) Returns h such as Proba(X<=h)=t when X follows the B(n,p) law. - See also: 1/ binomial 2/ binomial_cdf + See also: 1/ binomial 2/ binomial_cdf Ex1:binomial_icdf(4,0.5,0.68) Ex2:binomial_icdf(4,0.1,0.95) - ''' return GiacMethods['binomial_icdf'](self,*args) @@ -1716,8 +1577,7 @@ cdef class GiacMethods_base: Help for bins: bins(Opt) Option for the kernel_density command. - See also: 1/ kernel_density 2/ bandwidth - + See also: 1/ kernel_density 2/ bandwidth ''' return GiacMethods['bins'](self,*args) @@ -1726,8 +1586,7 @@ cdef class GiacMethods_base: Help for bipartite: bipartite(Opt) Option for the draw_graph command - See also: 1/ draw_graph - + See also: 1/ draw_graph ''' return GiacMethods['bipartite'](self,*args) @@ -1736,9 +1595,8 @@ cdef class GiacMethods_base: Help for bipartite_matching: bipartite_matching(Graph(G)) Returns the list of edges in a maximum matching of the undirected unweighted bipartite graph G. - See also: 1/ is_bipartite 2/ maximum_matching + See also: 1/ is_bipartite 2/ maximum_matching Ex1:bipartite_matching(graph("desargues")) - ''' return GiacMethods['bipartite_matching'](self,*args) @@ -1747,14 +1605,13 @@ cdef class GiacMethods_base: Help for bisection_solver: bisection_solver(Opt) Argument for fsolve giving the method for solving a numerical equation. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve(cos(x)=x,x,0..1,bisection_solver) Ex2: fsolve(cos(x)=x,x,0..1,brent_solver) Ex3: fsolve(cos(x)=x,x,0..1,falsepos_solver) Ex4: fsolve(cos(x)=x,x,0,newton_solver) Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) - ''' return GiacMethods['bisection_solver'](self,*args) @@ -1763,9 +1620,8 @@ cdef class GiacMethods_base: Help for bisector: bisector((Pnt(A) or Cplx),(Pnt(B) or Cplx),(Pnt(C) or Cplx)) Draws the bisector of the angle (AB,AC) given by 3 points A,B,C. - See also: 1/ angle 2/ exbisector + See also: 1/ angle 2/ exbisector Ex1:bisector(0,1,i) - ''' return GiacMethods['bisector'](self,*args) @@ -1774,9 +1630,8 @@ cdef class GiacMethods_base: Help for bit_depth: bit_depth(Lst(clip)) Returns the bit depth of an audio clip. - See also: 1/ channels 2/ channel_data 3/ duration 4/ samplerate + See also: 1/ channels 2/ channel_data 3/ duration 4/ samplerate Ex1:bit_depth(readwav("/some/file")) - ''' return GiacMethods['bit_depth'](self,*args) @@ -1785,9 +1640,8 @@ cdef class GiacMethods_base: Help for bitand: bitand(Intg,Intg) Logical bit and. - See also: 1/ bitxor 2/ bitor + See also: 1/ bitxor 2/ bitor Ex1:bitand(0x12,0x38) - ''' return GiacMethods['bitand'](self,*args) @@ -1796,9 +1650,8 @@ cdef class GiacMethods_base: Help for bitor: bitor(Intg,Intg) Inclusive logical bit or. - See also: 1/ bitxor 2/ bitand + See also: 1/ bitxor 2/ bitand Ex1:bitor(0x12,0x38) - ''' return GiacMethods['bitor'](self,*args) @@ -1807,9 +1660,8 @@ cdef class GiacMethods_base: Help for bitxor: bitxor(Intg,Intg) Exclusive logical bit or. - See also: 1/ bitor 2/ bitand + See also: 1/ bitor 2/ bitand Ex1:bitxor(0x12,0x38) - ''' return GiacMethods['bitxor'](self,*args) @@ -1818,9 +1670,8 @@ cdef class GiacMethods_base: Help for blackman_harris_window: blackman_harris_window(Lst,[Interval(n1..n2)]) Applies the Blackman-Harris windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ bartlett_hann_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ bartlett_hann_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(blackman_harris_window(randvector(1000,0..1))) - ''' return GiacMethods['blackman_harris_window'](self,*args) @@ -1829,9 +1680,8 @@ cdef class GiacMethods_base: Help for blackman_window: blackman_window(Lst,[Real(a)],[Interval(n1..n2)]) Applies the Blackman windowing function with parameter a (by default a=0.16) to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ bartlett_harris_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ bartlett_harris_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(blackman_window(randvector(1000,0..1))) - ''' return GiacMethods['blackman_window'](self,*args) @@ -1840,10 +1690,9 @@ cdef class GiacMethods_base: Help for blockmatrix: blockmatrix(Intg(n),Intg(m),Lst) Returns the matrix obtained from the list divided into n lists of dimension m. - See also: 1/ list2mat + See also: 1/ list2mat Ex1:blockmatrix(2,3,[idn(2),idn(2),idn(2),idn(2),idn(2),idn(2)]) Ex2:blockmatrix(2,2,[idn(2),newMat(2,3),newMat(3,2),idn(3)]) - ''' return GiacMethods['blockmatrix'](self,*args) @@ -1852,9 +1701,8 @@ cdef class GiacMethods_base: Help for bohman_window: bohman_window(Lst,[Interval(n1..n2)]) Applies the Bohman windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bartlett_hann_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bartlett_hann_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(bohman_window(randvector(1000,0..1))) - ''' return GiacMethods['bohman_window'](self,*args) @@ -1863,10 +1711,9 @@ cdef class GiacMethods_base: Help for border: border(Mtrx(A),Lst(b)) Returns the matrix obtained by augmenting A with b as the last column, if nrows(A)=size(b), border(A,b)=tran(append(tran(A),b)). - See also: 1/ tran 2/ append 3/ augment + See also: 1/ tran 2/ append 3/ augment Ex1:border([[1,2,3,4],[4,5,6,8],[7,8,9,10]],[1,3,5]) Ex2:border([[1,2,3],[4,5,6],[7,8,9]],[1,0,1]) - ''' return GiacMethods['border'](self,*args) @@ -1875,9 +1722,8 @@ cdef class GiacMethods_base: Help for boxcar: boxcar(Real(a),Real(b),Expr(x)) Returns the value at x of the boxcar function corresponding to a and b. - See also: 1/ rect 2/ Heaviside + See also: 1/ rect 2/ Heaviside Ex1:boxcar(1,2,x) - ''' return GiacMethods['boxcar'](self,*args) @@ -1886,12 +1732,11 @@ cdef class GiacMethods_base: Help for boxwhisker: boxwhisker(Lst,[Lst],[x=a..b||y=a..b]) Box and Whisker plot for a statistical series. - See also: 1/ quartiles + See also: 1/ quartiles Ex1:boxwhisker([-1,1,2,2.2,3,4,-2,5]) Ex2:boxwhisker([1,2,3,5,10,4],x=1..2) Ex3:boxwhisker([1,2,3,5,10,4],[1,2,3,1,2,3]) Ex4:boxwhisker([[6,0,1,3,4,2,5],[0,1,3,4,2,5,6],[1,3,4,2,5,6,0],[3,4,2,5,6,0,1],[4,2,5,6,0,1,3],[2,5,6,0,1,3,4]]) - ''' return GiacMethods['boxwhisker'](self,*args) @@ -1900,14 +1745,13 @@ cdef class GiacMethods_base: Help for brent_solver: brent_solver(Opt) Argument for fsolve giving the method for solving a numerical equation. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve(cos(x)=x,x,0..1,bisection_solver) Ex2: fsolve(cos(x)=x,x,0..1,brent_solver) Ex3: fsolve(cos(x)=x,x,0..1,falsepos_solver) Ex4: fsolve(cos(x)=x,x,0,newton_solver) Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) - ''' return GiacMethods['brent_solver'](self,*args) @@ -1916,10 +1760,9 @@ cdef class GiacMethods_base: Help for bvpsolve: bvpsolve(Expr(f(x,y,y')),Lst(x=a..b,y),Lst(y(a),y(b),[y'(1)]),[options]) Returns an approximation of the function y (and optionally of y') on the interval a..b. - See also: 1/ odesolve + See also: 1/ odesolve Ex1:bvpsolve((32+2x^3-y*diff(y(x),x))/8,[x=1..3,y],[17,43/3],20) Ex2:bvpsolve((x^2*diff(y(x),x)^2-9y^2+4x^6)/x^5,[x=1..2,y],[0,ln(256),1],10,output=spline) - ''' return GiacMethods['bvpsolve'](self,*args) @@ -1928,11 +1771,10 @@ cdef class GiacMethods_base: Help for cFactor: cFactor(Expr) Factorization of the expression in ℂ (on the Gaussian integers if there are more than 2 variables). - See also: 1/ factor + See also: 1/ factor Ex1:cFactor(x^2*y+y) Ex2:cFactor(x^2*y^2+y^2+4*x^2+4) Ex3:cFactor(x^2*y^2+y^2+2*x^2+2) - ''' return GiacMethods['cFactor'](self,*args) @@ -1941,12 +1783,11 @@ cdef class GiacMethods_base: Help for cSolve: cSolve(LstEq,LstVar) Returns the list of complex solutions of an equation or a matrix where the rows are ℂ-solutions of a system of polynomial equations. - See also: 1/ cZeros 2/ solve 3/ fslove + See also: 1/ cZeros 2/ solve 3/ fslove Ex1:cSolve(x^4-1,x) Ex2:cSolve(x^4-y^4 and x+y=2,[x,y]) Ex3:cSolve(x^4-y^4 and x+y=0 and x^2=2*x,[x,y]) Ex4:cSolve(u*v-u=v and v^2=u,[u,v]) - ''' return GiacMethods['cSolve'](self,*args) @@ -1955,10 +1796,9 @@ cdef class GiacMethods_base: Help for cZeros: cZeros(Expr(Xpr)||LstExpr, [Var||LstVar]) Returns the list of complex solutions of Xpr=0 or the matrix where the rows are the solutions of the system : Xpr1=0,Xpr2=0... - See also: 1/ solve + See also: 1/ solve Ex1:cZeros(x^2-1) Ex2:cZeros([x^2-1,x^2-y^2],[x,y]) - ''' return GiacMethods['cZeros'](self,*args) @@ -1967,11 +1807,10 @@ cdef class GiacMethods_base: Help for camembert: camembert(Mtrx) Draws pie chart of a one variable statistical series. - See also: 1/ bar_plot + See also: 1/ bar_plot Ex1:camembert([["France",6],["Allemagne",12],["Suisse",5]]) Ex2:camembert([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:camembert([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) - ''' return GiacMethods['camembert'](self,*args) @@ -1980,10 +1819,9 @@ cdef class GiacMethods_base: Help for canonical_form: canonical_form(Trinom(a*x^2+b*x+c),[Var]) Canonical_form of a 2nd degree polynomial. - See also: 1/ + See also: 1/ Ex1:canonical_form(2*x^2-12*x+1) Ex2:canonical_form(2*a^2-12*a+1,a) - ''' return GiacMethods['canonical_form'](self,*args) @@ -1992,9 +1830,8 @@ cdef class GiacMethods_base: Help for canonical_labeling: canonical_labeling(Graph(G)) Returns the permutation representing the canonical labeling of G. - See also: 1/ isomorphic_copy 2/ relabel_vertices + See also: 1/ isomorphic_copy 2/ relabel_vertices Ex1:canonical_labeling(graph("petersen")) - ''' return GiacMethods['canonical_labeling'](self,*args) @@ -2003,9 +1840,8 @@ cdef class GiacMethods_base: Help for cartesian_product: cartesian_product(Seq(G1,G2,..)) Returns the Cartesian product of graphs G1, G2, ... with vertices labelled as "u:v:..." where u, v, ... are vertices from G1, G2, ..., respectively. - See also: 1/ tensor_product + See also: 1/ tensor_product Ex1:cartesian_product(graph(trail(1,2,3,4,5,2)),star_graph(3)) - ''' return GiacMethods['cartesian_product'](self,*args) @@ -2014,9 +1850,8 @@ cdef class GiacMethods_base: Help for cauchy: cauchy(Real(x0),Real(a),Real(x)) Returns the density of probability at x of the Cauchy law with parameters x0 and a (by default x0=0 and a=1). - See also: 1/ cauchy_cdf 2/ cauchy_icdf + See also: 1/ cauchy_cdf 2/ cauchy_icdf Ex1:cauchy(0.0,2.0,1.0) - ''' return GiacMethods['cauchy'](self,*args) @@ -2025,10 +1860,9 @@ cdef class GiacMethods_base: Help for cauchy_cdf: cauchy_cdf(Real(x0),Real(a),Real(x),[Real(y)]) Returns the probability that a Cauchy random variable is less than x. - See also: 1/ cauchyd 2/ cauchy_icdf + See also: 1/ cauchyd 2/ cauchy_icdf Ex1:cauchy_cdf(0.0,2.0,2.1) Ex2:cauchy_cdf(2,3,-1.9,1.4) - ''' return GiacMethods['cauchy_cdf'](self,*args) @@ -2037,9 +1871,8 @@ cdef class GiacMethods_base: Help for cauchy_icdf: cauchy_icdf(Real(x0),Real(a),Real(p)) Returns h such that the probability that a Cauchy random variable is less than h is p (0<=p<=1). - See also: 1/ cauchy_cdf 2/ cauchy + See also: 1/ cauchy_cdf 2/ cauchy Ex1:cauchy_icdf(0.0,2.0,0.95) - ''' return GiacMethods['cauchy_icdf'](self,*args) @@ -2048,9 +1881,8 @@ cdef class GiacMethods_base: Help for cauchyd: cauchyd(Real(x0),Real(a),Real(x)) Returns the density of probability at x of the Cauchy law with parameters x0 and a (by default x0=0 and a=1). - See also: 1/ cauchy_cdf 2/ cauchy_icdf + See also: 1/ cauchy_cdf 2/ cauchy_icdf Ex1:cauchyd(0.0,2.0,1.0) - ''' return GiacMethods['cauchyd'](self,*args) @@ -2059,10 +1891,9 @@ cdef class GiacMethods_base: Help for cauchyd_cdf: cauchyd_cdf(Real(x0),Real(a),Real(x),[Real(y)]) Returns the probability that a Cauchy random variable is less than x. - See also: 1/ cauchyd 2/ cauchy_icdf + See also: 1/ cauchyd 2/ cauchy_icdf Ex1:cauchyd_cdf(0.0,2.0,2.1) Ex2:cauchyd_cdf(2,3,-1.9,1.4) - ''' return GiacMethods['cauchyd_cdf'](self,*args) @@ -2071,9 +1902,8 @@ cdef class GiacMethods_base: Help for cauchyd_icdf: cauchyd_icdf(Real(x0),Real(a),Real(p)) Returns h such that the probability that a Cauchy random variable is less than h is p (0<=p<=1). - See also: 1/ cauchy_cdf 2/ cauchy + See also: 1/ cauchy_cdf 2/ cauchy Ex1:cauchyd_icdf(0.0,2.0,0.95) - ''' return GiacMethods['cauchyd_icdf'](self,*args) @@ -2082,12 +1912,11 @@ cdef class GiacMethods_base: Help for cdf: cdf(Func,FuncParams) Cumulative distribution function. - See also: 1/ icdf 2/ binomial_cdf 3/ normald_cdf 4/ plotcdf + See also: 1/ icdf 2/ binomial_cdf 3/ normald_cdf 4/ plotcdf Ex1:cdf(binomial,10,0.5,4) Ex2:cdf(normald,0.0,1.0,2.0) Ex3:cdf([1,3,4,3,5,6],4) Ex4:cdf([1,3,4,3,5,6],plot) - ''' return GiacMethods['cdf'](self,*args) @@ -2096,10 +1925,9 @@ cdef class GiacMethods_base: Help for ceil: ceil(Real or Cplx) Returns the smallest integer >= to the argument. - See also: 1/ floor 2/ round + See also: 1/ floor 2/ round Ex1:ceil(-4.2) Ex2:ceil(4.3+2.4*i) - ''' return GiacMethods['ceil'](self,*args) @@ -2108,10 +1936,9 @@ cdef class GiacMethods_base: Help for ceiling: ceiling(Real or Cplx) Returns the smallest integer >= to the argument. - See also: 1/ floor 2/ round + See also: 1/ floor 2/ round Ex1:ceiling(-4.2) Ex2:ceiling(4.3+2.4*i) - ''' return GiacMethods['ceiling'](self,*args) @@ -2120,10 +1947,9 @@ cdef class GiacMethods_base: Help for center: center(Crcle) Shows the center of a circle. - See also: 1/ circle 2/ radius + See also: 1/ circle 2/ radius Ex1:center(circle(1+i,2)) Ex2:center(circumcircle(0,1,1+i)) - ''' return GiacMethods['center'](self,*args) @@ -2132,10 +1958,9 @@ cdef class GiacMethods_base: Help for center2interval: center2interval(LstVal(l),[Real(a0)]) Returns the list of intervals beginning with a0 and with l as centers. - See also: 1/ interval2center + See also: 1/ interval2center Ex1:center2interval([2,5,9],1) Ex2:center2interval([2,5,8]) - ''' return GiacMethods['center2interval'](self,*args) @@ -2144,10 +1969,9 @@ cdef class GiacMethods_base: Help for centered_cube: centered_cube(Pnt(A),Pnt(B),Pnt(C)) Draws the direct cube with center A, vertex B and such that the plane ABC contains an axis of symmetry of the cube. - See also: 1/ parallelepiped 2/ cube 3/ icosahedron 4/ dodecahedron 5/ octahedron 6/ centered_tetrahedron + See also: 1/ parallelepiped 2/ cube 3/ icosahedron 4/ dodecahedron 5/ octahedron 6/ centered_tetrahedron Ex1:centered_cube([0,0,0],[3,0,0],[0,0,1]) Ex2:centered_cube(evalf([0,0,0],[3,2,4],[1,1,0])) - ''' return GiacMethods['centered_cube'](self,*args) @@ -2156,10 +1980,9 @@ cdef class GiacMethods_base: Help for centered_tetrahedron: centered_tetrahedron(Pnt(A),Pnt(B),Pnt(C)) Draws the regular direct pyramid with center A, vertex B and a vertex in the plane (A,B,C). - See also: 1/ cube 2/ tetrahedron 3/ icosahedron 4/ dodecahedron 5/ octahedron + See also: 1/ cube 2/ tetrahedron 3/ icosahedron 4/ dodecahedron 5/ octahedron Ex1:centered_tetrahedron([0,0,0],[3,0,0],[0,1,0]) Ex2:centered_tetrahedron(evalf([0,0,0],[3,2,4],[1,1,0])) - ''' return GiacMethods['centered_tetrahedron'](self,*args) @@ -2168,11 +1991,10 @@ cdef class GiacMethods_base: Help for cfactor: cfactor(Expr) Factorization of the expression in ℂ (on the Gaussian integers if there are more than 2 variables). - See also: 1/ factor + See also: 1/ factor Ex1:cfactor(x^2*y+y) Ex2:cfactor(x^2*y^2+y^2+4*x^2+4) Ex3:cfactor(x^2*y^2+y^2+2*x^2+2) - ''' return GiacMethods['cfactor'](self,*args) @@ -2181,10 +2003,9 @@ cdef class GiacMethods_base: Help for cfsolve: cfsolve(Expr,Var,[Guess or Interval],[Method]) Numerical solution of an equation or a system of equations on ℂ. - See also: 1/ fsolve 2/ nSolve 3/ csolve 4/ solve + See also: 1/ fsolve 2/ nSolve 3/ csolve 4/ solve Ex1:cfsolve(cos(x)=2) Ex2:cfsolve([x^2+y+2,x+y^2+2],[x,y]) - ''' return GiacMethods['cfsolve'](self,*args) @@ -2193,10 +2014,9 @@ cdef class GiacMethods_base: Help for changebase: changebase(Mtrx(A),Mtrx(P)) Returns the matrix B=inv(P)*A*P. - See also: 1/ + See also: 1/ Ex1:changebase([[1,2],[1,3]],[[1,1],[0,1]]) Ex2:changebase([[1,2],[1,3]],[[1,0],[1,1]]) - ''' return GiacMethods['changebase'](self,*args) @@ -2205,12 +2025,11 @@ cdef class GiacMethods_base: Help for channel_data: channel_data(Lst(clip),[Intg(chn) or matrix],[range=a..b]) Extracts the data from an audio clip (optionally specifying the channel and range). - See also: 1/ bit_depth 2/ channels 3/ duration 4/ samplerate + See also: 1/ bit_depth 2/ channels 3/ duration 4/ samplerate Ex1:channel_data(readwav("/some/file")) Ex2:channel_data(readwav("/some/file"),matrix) Ex3:channel_data(readwav("/some/file"),2) Ex4:channel_data(readwav("/some/file"),matrix,range=1.0..2.5) - ''' return GiacMethods['channel_data'](self,*args) @@ -2219,9 +2038,8 @@ cdef class GiacMethods_base: Help for channels: channels(Lst(clip)) Returns the number of channels in audio clip. - See also: 1/ bit_depth 2/ channel_data 3/ duration 4/ samplerate + See also: 1/ bit_depth 2/ channel_data 3/ duration 4/ samplerate Ex1:channels(readwav("/some/file")) - ''' return GiacMethods['channels'](self,*args) @@ -2230,10 +2048,9 @@ cdef class GiacMethods_base: Help for char: char(Intg or Lst(Intg)) Returns the string corresponding to the character code of the argument. - See also: 1/ asc 2/ ord + See also: 1/ asc 2/ ord Ex1:char(65) Ex2:char([65,66,67]) - ''' return GiacMethods['char'](self,*args) @@ -2242,12 +2059,11 @@ cdef class GiacMethods_base: Help for charpoly: charpoly(Mtrx,[Var]) List of the coefficients of the characteristic polynomial of a matrix or characteristic polynomial of a matrix with the second argument as variable. - See also: 1/ jordan 2/ egv 3/ egvl 4/ companion 5/ rat_jordan 6/ pmin 7/ adjoint_matrix + See also: 1/ jordan 2/ egv 3/ egvl 4/ companion 5/ rat_jordan 6/ pmin 7/ adjoint_matrix Ex1:charpoly([[1,2],[3,4]]) Ex2:charpoly([[1,2],[3,4]],x) Ex3:charpoly([[1,2,3],[1,3,6],[2,5,7]]) Ex4:charpoly([[1,2,3],[1,3,6],[2,5,7]],z) - ''' return GiacMethods['charpoly'](self,*args) @@ -2256,10 +2072,9 @@ cdef class GiacMethods_base: Help for chinrem: chinrem([Lst||Expr,Lst||Expr],[Lst||Expr,Lst||Expr]) Chinese remainder for polynomials written as lists or no. - See also: 1/ ichinrem + See also: 1/ ichinrem Ex1:chinrem([x+2,x^2+1],[x+1,x^2+x+1]) Ex2:chinrem([[1,2],[1,0,1]],[[1,1],[1,1,1]]) - ''' return GiacMethods['chinrem'](self,*args) @@ -2268,12 +2083,11 @@ cdef class GiacMethods_base: Help for chisquare: chisquare(Intg(n),Real(x0)) Returns the probability density of the Chi^2 law at x0 (n is the number of degrees of freedom). - See also: 1/ chisquare_cdf 2/ chisquare_icdf 3/ randvector 4/ ranm + See also: 1/ chisquare_cdf 2/ chisquare_icdf 3/ randvector 4/ ranm Ex1:chisquare(2,3.2) Ex2:chisquare(4,10.5) Ex3: randvector(3,chisquare,2) Ex4: ranm(4,3,chisquare,2) - ''' return GiacMethods['chisquare'](self,*args) @@ -2282,10 +2096,9 @@ cdef class GiacMethods_base: Help for chisquare_cdf: chisquare_cdf(Intg(n),Real(x0)) Returns the probability that a Chi^2 random variable is less than x0 (n is the number of degrees of freedom). - See also: 1/ UTPC 2/ chisquare_icdf 3/ chisquared + See also: 1/ UTPC 2/ chisquare_icdf 3/ chisquared Ex1:chisquare_cdf(2,6.1) Ex2:chisquare_cdf(4,6.1) - ''' return GiacMethods['chisquare_cdf'](self,*args) @@ -2294,10 +2107,9 @@ cdef class GiacMethods_base: Help for chisquare_icdf: chisquare_icdf(Intg(n),Real(p)) Returns h such as the probability that a Chi^2 random variable is less than h is p (n is the number of degrees of freedom and 0<=p<=1). - See also: 1/ chisquare_cdf 2/ chisquared + See also: 1/ chisquare_cdf 2/ chisquared Ex1:chisquare_icdf(2,0.95) Ex2:chisquare_icdf(4,0.05) - ''' return GiacMethods['chisquare_icdf'](self,*args) @@ -2306,12 +2118,11 @@ cdef class GiacMethods_base: Help for chisquared: chisquared(Intg(n),Real(x0)) Returns the probability density of the Chi^2 law at x0 (n is the number of degrees of freedom). - See also: 1/ chisquare_cdf 2/ chisquare_icdf 3/ randvector 4/ ranm + See also: 1/ chisquare_cdf 2/ chisquare_icdf 3/ randvector 4/ ranm Ex1:chisquared(2,3.2) Ex2:chisquared(4,10.5) Ex3: randvector(3,chisquare,2) Ex4: ranm(4,3,chisquare,2) - ''' return GiacMethods['chisquared'](self,*args) @@ -2320,10 +2131,9 @@ cdef class GiacMethods_base: Help for chisquared_cdf: chisquared_cdf(Intg(n),Real(x0)) Returns the probability that a Chi^2 random variable is less than x0 (n is the number of degrees of freedom). - See also: 1/ UTPC 2/ chisquare_icdf 3/ chisquared + See also: 1/ UTPC 2/ chisquare_icdf 3/ chisquared Ex1:chisquared_cdf(2,6.1) Ex2:chisquared_cdf(4,6.1) - ''' return GiacMethods['chisquared_cdf'](self,*args) @@ -2332,10 +2142,9 @@ cdef class GiacMethods_base: Help for chisquared_icdf: chisquared_icdf(Intg(n),Real(p)) Returns h such as the probability that a Chi^2 random variable is less than h is p (n is the number of degrees of freedom and 0<=p<=1). - See also: 1/ chisquare_cdf 2/ chisquared + See also: 1/ chisquare_cdf 2/ chisquared Ex1:chisquared_icdf(2,0.95) Ex2:chisquared_icdf(4,0.05) - ''' return GiacMethods['chisquared_icdf'](self,*args) @@ -2344,7 +2153,7 @@ cdef class GiacMethods_base: Help for chisquaret: chisquaret(Data,[Func],[FuncParams]) Chi^2 test : fitness between 2 (or n) samples or between 1 sample and a distribution law (multinomial or given by a law). - See also: 1/ normalt 2/ studentt 3/ kolmogorovt + See also: 1/ normalt 2/ studentt 3/ kolmogorovt Ex1:chisquaret([57,54]) Ex2:chisquaret([1,1,1,1,1,0,0,1,0,0,1,1,1,0,1,1,0,1,1,0,0,0,0],[.4,.6]) Ex3:chisquaret([57,30],[.6,.4]) @@ -2354,7 +2163,6 @@ cdef class GiacMethods_base: Ex7:chisquaret(ranv(1000,normald,0,.2),normald) Ex8:chisquaret([11,16,17,22,14,10],[1/6,1/6,1/6,1/6,1/6,1/6]) Ex9:chisquaret([11,16,17,22,14,10],[(1/6)$6]) - ''' return GiacMethods['chisquaret'](self,*args) @@ -2363,12 +2171,11 @@ cdef class GiacMethods_base: Help for choice: choice(Lst(L)) choice(L)=rand(L)=one extracted element of L. - See also: 1/ rand 2/ sample + See also: 1/ rand 2/ sample Ex1:choice([1,2,3,4,5,6]) Ex2:choice(["r","r","r","b","n"]) Ex3: L:=[1,2,3,4,5,6];L:=choice(L) Ex4: L:=[1,2,3,4,5,6];L.choice() - ''' return GiacMethods['choice'](self,*args) @@ -2377,9 +2184,8 @@ cdef class GiacMethods_base: Help for cholesky: cholesky(Mtrx) For a numerical symmetric matrix A, returns L matrix such that A=L*tran(L). - See also: 1/ lu 2/ qr 3/ gauss + See also: 1/ lu 2/ qr 3/ gauss Ex1:cholesky([[3,1],[1,4]]) - ''' return GiacMethods['cholesky'](self,*args) @@ -2388,10 +2194,9 @@ cdef class GiacMethods_base: Help for chr: chr(Intg or Lst(Intg)) Returns the string corresponding to the character code of the argument. - See also: 1/ asc 2/ ord + See also: 1/ asc 2/ ord Ex1:chr(65) Ex2:chr([65,66,67]) - ''' return GiacMethods['chr'](self,*args) @@ -2400,13 +2205,12 @@ cdef class GiacMethods_base: Help for chrem: chrem(LstIntg(a,b,c....),LstIntg(p,q,r,....)) Chinese remainders for integers or for polynomials. - See also: 1/ gcd 2/ fracmod 3/ chinrem 4/ ichinrem + See also: 1/ gcd 2/ fracmod 3/ chinrem 4/ ichinrem Ex1:chrem(symbolique.) Ex2:chrem([2,3],[7,5]) Ex3:chrem([2,4,6],[3,5,7]) Ex4:chrem([2,4,6,7],[3,5,7,11]) Ex5:chrem([2*x+1,4*x+2,6*x-1,x+1],[3,5,7,11]) - ''' return GiacMethods['chrem'](self,*args) @@ -2415,10 +2219,9 @@ cdef class GiacMethods_base: Help for chromatic_index: chromatic_index(Graph(G),[Lst(cols)]) Returns the number of colors in the minimal edge coloring of G. If an unassigned identifier cols is given, the coloring is stored to it. - See also: 1/ minimal_edge_coloring 2/ chromatic_number + See also: 1/ minimal_edge_coloring 2/ chromatic_number Ex1:chromatic_index(graph("petersen")) Ex2:chromatic_index(graph("dodecahedron"),colors) - ''' return GiacMethods['chromatic_index'](self,*args) @@ -2428,7 +2231,6 @@ cdef class GiacMethods_base: chromatic_number(Graph(G)) Returns the chromatic number of G. Ex1:chromatic_number(graph("petersen")) - ''' return GiacMethods['chromatic_number'](self,*args) @@ -2437,10 +2239,9 @@ cdef class GiacMethods_base: Help for chromatic_polynomial: chromatic_polynomial(Graph(G),[Var(t)]) Returns the chromatic polynomial [or its value at point t] of undirected unweighted graph G. - See also: 1/ flow_polynomial 2/ reliability_polynomial 3/ tutte_polynomial + See also: 1/ flow_polynomial 2/ reliability_polynomial 3/ tutte_polynomial Ex1:chromatic_polynomial(graph("petersen")) Ex2:chromatic_polynomial(graph("petersen"),3) - ''' return GiacMethods['chromatic_polynomial'](self,*args) @@ -2449,7 +2250,7 @@ cdef class GiacMethods_base: Help for circle: circle((Pnt(M) or Cplx(M),(Pnt(N) or Cplx(zN)),[Real(a)],[Real(b)],[Var(A)],[Var(B)]) Define for 2-d a circle with a diameter MN (arg1=M or zM,arg2=N) or with center and radius (arg1=M or zM,arg2=zN) and (center=M and radius=abs(zN)) [or the arc AB, A angle a, B angle b, (MN=angle 0) or M(M+zN)=angle 0] or by its equation and for 3-d with a diameter and a third point. - See also: 1/ circumcircle 2/ incircle 3/ excircle 4/ center 5/ radius 6/ sphere 7/ Circle + See also: 1/ circumcircle 2/ incircle 3/ excircle 4/ center 5/ radius 6/ sphere 7/ Circle Ex1:circle(0,point(2*i)) Ex2:circle(i,i) Ex3:circle(i,1) @@ -2458,7 +2259,6 @@ cdef class GiacMethods_base: Ex6:circle(x^2+y^2-x-y) Ex7:circle(cercle(point([-1,0,0]),point([1,0,0]),point([0,2,0]))) Ex8:circle(cercle([-1,0,0],point([1,0,0]),[0,2,0])) - ''' return GiacMethods['circle'](self,*args) @@ -2467,9 +2267,8 @@ cdef class GiacMethods_base: Help for circumcircle: circumcircle((Pnt or Cplx),(Pnt or Cplx),((Pnt or Cplx)) circumcircle(A,B,C)=circumcircle of the triangle ABC. - See also: 1/ circle 2/ incircle 3/ excircle + See also: 1/ circle 2/ incircle 3/ excircle Ex1:circumcircle(0,1,1+i) - ''' return GiacMethods['circumcircle'](self,*args) @@ -2478,13 +2277,12 @@ cdef class GiacMethods_base: Help for classes: classes(Lst(l),[ClassMin],[ClassSize||Lst(Center)]) Returns the matrix [[class,number],...] obtained with class_min and class_size: see init of geo or argument 2 and 3 or with the list of centers. - See also: 1/ histogram 2/ cumulated_frequencies 3/ bar_plot 4/ frequencies + See also: 1/ histogram 2/ cumulated_frequencies 3/ bar_plot 4/ frequencies Ex1:classes([1,1.2,1.4,1.6,1.8,2,2.5]) Ex2:classes([1,1.2,1.4,1.6,1.8,2,2.5],1.2,0.5) Ex3:classes([1,1.2,1.4,1.6,1.8,2,2.5],1,[1.2,1.6,2,2.4]) Ex4:classes([1,1.2,1.4,1.6,1.8,2,2.5],1,[1.2,1.6,2.2]) Ex5:classes([0,0.5,1,1.5,2,2.5,3,3.5,4],[0..2,2..4,4..6]) - ''' return GiacMethods['classes'](self,*args) @@ -2493,9 +2291,8 @@ cdef class GiacMethods_base: Help for clear: clear(NULL) Clears the list of pixels. - See also: 1/ set_pixel 2/ show_pixels + See also: 1/ set_pixel 2/ show_pixels Ex1:clear() - ''' return GiacMethods['clear'](self,*args) @@ -2504,11 +2301,10 @@ cdef class GiacMethods_base: Help for clique_cover: clique_cover(Graph(G),[Intg(k)]) Returns a clique vertex cover of G [containing at most k cliques]. - See also: 1/ clique_cover_number 2/ maximal_cliques + See also: 1/ clique_cover_number 2/ maximal_cliques Ex1:clique_cover(graph("petersen")) Ex2:clique_cover(cycle_graph(5)) Ex3:clique_cover(graph_complement(complete_graph(3,4))) - ''' return GiacMethods['clique_cover'](self,*args) @@ -2517,11 +2313,10 @@ cdef class GiacMethods_base: Help for clique_cover_number: clique_cover_number(Graph(G)) Returns the clique cover number of G. - See also: 1/ clique_cover 3/ maximal_cliques + See also: 1/ clique_cover 3/ maximal_cliques Ex1:clique_cover_number(graph("petersen")) Ex2:clique_cover_number(cycle_graph(5)) Ex3:clique_cover_number(graph_complement(complete_graph(3,4))) - ''' return GiacMethods['clique_cover_number'](self,*args) @@ -2530,9 +2325,8 @@ cdef class GiacMethods_base: Help for clique_number: clique_number(Graph(G)) Returns the clique number of G, which is equal to the size of a maximum clique in G. - See also: 1/ maximum_clique + See also: 1/ maximum_clique Ex1:clique_number(graph_complement(complete_graph(3,4))) - ''' return GiacMethods['clique_number'](self,*args) @@ -2541,11 +2335,10 @@ cdef class GiacMethods_base: Help for clique_stats: clique_stats(Graph(G),[Intg(k)||Intrv(m..n)]) Returns the list of numbers of maximal cliques of size s in G for each s. If parameter k is given, the number of k-cliques is returned. If an interval m..n is given, only cliques with size between m and n (inclusive) are counted (m also may be +infinity). - See also: 1/ maximum_clique 2/ clique_cover + See also: 1/ maximum_clique 2/ clique_cover Ex1:clique_stats(random_graph(50,0.5)) Ex2:clique_stats(random_graph(50,0.5),5) Ex3:clique_stats(random_graph(50,0.5),3..5) - ''' return GiacMethods['clique_stats'](self,*args) @@ -2554,10 +2347,9 @@ cdef class GiacMethods_base: Help for clustering_coefficient: clustering_coefficient(Graph(G),[Vrtx(v)]) Returns the average clustering coefficient of undirected graph G, or the local clustering coefficient of the vertex v in G. - See also: 1/ network_transitivity 2/ number_of_triangles + See also: 1/ network_transitivity 2/ number_of_triangles Ex1:clustering_coefficient(graph(%{[1,2],[2,3],[2,4],[3,4],[4,1]%})) Ex2:clustering_coefficient(graph(%{[1,2],[2,3],[2,4],[3,4],[4,1]%}),2) - ''' return GiacMethods['clustering_coefficient'](self,*args) @@ -2566,11 +2358,10 @@ cdef class GiacMethods_base: Help for coeff: coeff(Expr(P),[Var]) Returns the list of coefficients of a polynomial with respect to the 2nd argument or the coefficient of degree the 3rd argument. - See also: 1/ pcoeff 2/ fcoeff + See also: 1/ pcoeff 2/ fcoeff Ex1:coeff(x*3+2) Ex2:coeff(5*y^2-3,y) Ex3:coeff(5*y^2-3,y,2) - ''' return GiacMethods['coeff'](self,*args) @@ -2579,11 +2370,10 @@ cdef class GiacMethods_base: Help for coeffs: coeffs(Expr(P),[Var]) Returns the list of coefficients of a polynomial with respect to the 2nd argument or the coefficient of degree the 3rd argument. - See also: 1/ pcoeff 2/ fcoeff + See also: 1/ pcoeff 2/ fcoeff Ex1:coeffs(x*3+2) Ex2:coeffs(5*y^2-3,y) Ex3:coeffs(5*y^2-3,y,2) - ''' return GiacMethods['coeffs'](self,*args) @@ -2592,11 +2382,10 @@ cdef class GiacMethods_base: Help for col: col(Mtrx(A),Intg(n)||Interval(n1..n2)) Returns column n or the sequence of the columns n1..n2 of the matrix A, or optional argument of count,count_eq,count_inf,count_sup. - See also: 1/ row 2/ count 3/ count_eq 4/ count_inf 5/ count_sup + See also: 1/ row 2/ count 3/ count_eq 4/ count_inf 5/ count_sup Ex1:col([[1,2,3],[4,5,6],[7,8,9]],1) Ex2:col([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3: count_eq(3,[[3,2,3],[4,3,2],[3,2,1]],col) - ''' return GiacMethods['col'](self,*args) @@ -2605,10 +2394,9 @@ cdef class GiacMethods_base: Help for colDim: colDim(Mtrx) Number of columns of a matrix. - See also: 1/ rowdim + See also: 1/ rowdim Ex1:colDim([[1,2,3],[4,5,6]]) Ex2:colDim([[1,2],[3,4],[5,6]]) - ''' return GiacMethods['colDim'](self,*args) @@ -2617,10 +2405,9 @@ cdef class GiacMethods_base: Help for colNorm: colNorm(Vect or Mtrx) Returns the max of the l1_norm of the columns of a matrix: colNorm(a_{j,k})=max_k(sum_j(|a_{j,k}|)). - See also: 1/ norm + See also: 1/ norm Ex1:colNorm([[1,2],[3,-4]]) Ex2:colNorm([[1,2,3,-4],[-5,3,2,1]]) - ''' return GiacMethods['colNorm'](self,*args) @@ -2629,9 +2416,8 @@ cdef class GiacMethods_base: Help for colSwap: colSwap(Mtrx(A),Intg(n1),Intg(n2)) Returns the matrix obtained from A by swapping the n1-th column and the n2-th column. - See also: 1/ rowSwap + See also: 1/ rowSwap Ex1:colSwap([[1,2],[3,4],[5,6]],0,1) - ''' return GiacMethods['colSwap'](self,*args) @@ -2640,10 +2426,9 @@ cdef class GiacMethods_base: Help for coldim: coldim(Mtrx) Number of columns of a matrix. - See also: 1/ rowdim + See also: 1/ rowdim Ex1:coldim([[1,2,3],[4,5,6]]) Ex2:coldim([[1,2],[3,4],[5,6]]) - ''' return GiacMethods['coldim'](self,*args) @@ -2652,11 +2437,10 @@ cdef class GiacMethods_base: Help for collect: collect(Poly or LstPoly) Integer factorization of a polynomial (or of a list of poly). - See also: 1/ factor 2/ factors + See also: 1/ factor 2/ factors Ex1:collect(x^2-4) Ex2:collect(x^2-2) Ex3:collect([x^2-2,x^2-4]) - ''' return GiacMethods['collect'](self,*args) @@ -2665,10 +2449,9 @@ cdef class GiacMethods_base: Help for colnorm: colnorm(Vect or Mtrx) Returns the max of the l1_norm of the columns of a matrix: colNorm(a_{j,k})=max_k(sum_j(|a_{j,k}|)). - See also: 1/ norm + See also: 1/ norm Ex1:colnorm([[1,2],[3,-4]]) Ex2:colnorm([[1,2,3,-4],[-5,3,2,1]]) - ''' return GiacMethods['colnorm'](self,*args) @@ -2677,7 +2460,7 @@ cdef class GiacMethods_base: Help for color: color([GeoObj or legende],Intg) Draws a geometrical object with colors black=0 red=1 green=2 yellow=3 blue=4, filled with the color in the interior of a closed curve,line_width_n (00 (by default a=1 for sine window) to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ bartlett_hann_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ bartlett_hann_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(cosine_window(randvector(1000,0..1),1.5)) - ''' return GiacMethods['cosine_window'](self,*args) @@ -3260,9 +2999,8 @@ cdef class GiacMethods_base: Help for cot: cot(Expr) Cotangent. - See also: 1/ acot 2/ tan + See also: 1/ acot 2/ tan Ex1:cot(pi/2) - ''' return GiacMethods['cot'](self,*args) @@ -3271,10 +3009,9 @@ cdef class GiacMethods_base: Help for cote: cote(Vect) Third coordinate (z) of a 3-d point. - See also: 1/ abscissa 2/ ordinate 3/ coordinates + See also: 1/ abscissa 2/ ordinate 3/ coordinates Ex1:cote(point[1,2,3]) Ex2:cote(point(1,2,3)) - ''' return GiacMethods['cote'](self,*args) @@ -3283,7 +3020,7 @@ cdef class GiacMethods_base: Help for count: count(Fnc(f)||LstIntg,(Lst||Mtrx)(l),[Opt(row||col)]) Returns f(l[0])+f(l[1])+...+f(l[size(l)-1]) or counts the number of occurrences if the argument is a vector of integers. - See also: 1/ count_eq 2/ count_inf 3/ count_sup + See also: 1/ count_eq 2/ count_inf 3/ count_sup Ex1:count(id,[-2/5,-1,0,1,2,3/5]) Ex2:count(1,[-2,-1,0,1,2,3]) Ex3:count([1,3,1,1,2,10,3]) @@ -3294,7 +3031,6 @@ cdef class GiacMethods_base: Ex8:count((x)->x>2,[[3,5/2],[4,1]],col) Ex9:count((x)->x>2 && x<4,[[3,9/2],[4,1]]) Ex10:count((x)->x<2 || x>4,[[3,9/2],[4,1]]) - ''' return GiacMethods['count'](self,*args) @@ -3303,12 +3039,11 @@ cdef class GiacMethods_base: Help for count_eq: count_eq(Real(a),(Lst||Mtrx)(L),[Opt(row||col)]) Returns the number of elements of L equal to a. - See also: 1/ count 2/ count_inf 3/ count_sup + See also: 1/ count 2/ count_inf 3/ count_sup Ex1:count_eq(1,[-2,1,0,1,2,-3]) Ex2:count_eq(4,[[3,4],[4,1]]) Ex3:count_eq(4,[[3,4],[4,1]],row) Ex4:count_eq(4,[[3,4],[4,1]],col) - ''' return GiacMethods['count_eq'](self,*args) @@ -3317,12 +3052,11 @@ cdef class GiacMethods_base: Help for count_inf: count_inf(Real(a),(Lst||Mtrx)(L),[Opt(row||col)]) Returns the number of elements of L strictly less than a. - See also: 1/ count 2/ count_eq 3/ count_sup + See also: 1/ count 2/ count_eq 3/ count_sup Ex1:count_inf(1,[-2,-1,0,1,2,3]) Ex2:count_inf(4,[[3,5],[4,1]]) Ex3:count_inf(4,[[3,5],[4,1]],row) Ex4:count_inf(4,[[3,5],[4,1]],col) - ''' return GiacMethods['count_inf'](self,*args) @@ -3331,12 +3065,11 @@ cdef class GiacMethods_base: Help for count_sup: count_sup(Real(a),(Lst||Mtrx)(L),[Opt(row||col)]) Returns the number of elements of L strictly greater than a. - See also: 1/ count 2/ count_inf 3/ count_eq + See also: 1/ count 2/ count_inf 3/ count_eq Ex1:count_sup(1,[-2,-1,0,1,2,3]) Ex2:count_sup(3,[[3,5],[4,1]]) Ex3:count_sup(3,[[3,5],[4,1]],row) Ex4:count_sup(3,[[3,5],[4,1]],col) - ''' return GiacMethods['count_sup'](self,*args) @@ -3345,7 +3078,7 @@ cdef class GiacMethods_base: Help for courbe_parametrique: courbe_parametrique(Cplx||Lst,Var||Lst(Var)) plotparam(a(x)+i*b(x),x=x0..x1) draws the curve X=a(x),Y=b(x) x=x0..x1 or plotparam([a(u,v),b(u,v),c(u,v)],[u=u0..u1,v=v0..v1]) draws the surface X=a(u,v),Y=b(u,v),Z=c(u,v) u=u0..u1 and v=v0..v1. - See also: 1/ plotfunc 2/ plotpolar 3/ arc + See also: 1/ plotfunc 2/ plotpolar 3/ arc Ex1:courbe_parametrique(sin(t)+i*cos(t),t) Ex2:courbe_parametrique(exp(i*t),t=0..pi/2,affichage=1) Ex3:courbe_parametrique(exp(i*t),t=0..pi/2,affichage=1+rempli) @@ -3354,7 +3087,6 @@ cdef class GiacMethods_base: Ex6:courbe_parametrique(sin(x)+i*cos(x),x=0..1,tstep=0.01) Ex7:courbe_parametrique([v*cos(u),v*sin(u),v],[u,v]) Ex8:courbe_parametrique([v*cos(u),v*sin(u),v],[u=0..pi,v=0..3],ustep=0.1,vstep=0.2) - ''' return GiacMethods['courbe_parametrique'](self,*args) @@ -3363,10 +3095,9 @@ cdef class GiacMethods_base: Help for courbe_polaire: courbe_polaire(Expr,Var,VarMin,VarMax) plotpolar(f(x),x,a,b) draws the polar curve r=f(x) for x in [a,b]. - See also: 1/ plotparam 2/ plotfunc 3/ plotpolar + See also: 1/ plotparam 2/ plotfunc 3/ plotpolar Ex1:courbe_polaire(sin(2*x),x,0,pi) Ex2:courbe_polaire(sin(2*x),x,0,pi,tstep=0.1) - ''' return GiacMethods['courbe_polaire'](self,*args) @@ -3375,9 +3106,8 @@ cdef class GiacMethods_base: Help for covariance: covariance(Lst||Mtrx,[Lst]) Returns the covariance of the elements of its argument. - See also: 1/ correlation 2/ covariance_correlation + See also: 1/ correlation 2/ covariance_correlation Ex1:covariance([[1,2],[1,1],[4,7]]) - ''' return GiacMethods['covariance'](self,*args) @@ -3386,9 +3116,8 @@ cdef class GiacMethods_base: Help for covariance_correlation: covariance_correlation(Lst||Mtrx,[Lst]) Returns the list of the covariance and the correlation of the elements of its argument. - See also: 1/ covariance 2/ correlation + See also: 1/ covariance 2/ correlation Ex1:covariance_correlation([[1,2],[1,1],[4,7]]) - ''' return GiacMethods['covariance_correlation'](self,*args) @@ -3397,11 +3126,10 @@ cdef class GiacMethods_base: Help for cpartfrac: cpartfrac(RatFrac) Performs partial fraction decomposition in ℂ of a fraction. - See also: 1/ factor 2/ normal + See also: 1/ factor 2/ normal Ex1:cpartfrac((x)/(4-x^2)) Ex2:cpartfrac((x^2-2*x+3)/(x^2-3*x+2)) Ex3:cpartfrac(a/(z*(z-b)),z) - ''' return GiacMethods['cpartfrac'](self,*args) @@ -3410,9 +3138,8 @@ cdef class GiacMethods_base: Help for crationalroot: crationalroot(Poly(P)) Returns the list of complex rational roots of P without indicating the multiplicity. - See also: 1/ proot 2/ froot 3/ complexroot 4/ rationalroot 5/ realroot + See also: 1/ proot 2/ froot 3/ complexroot 4/ rationalroot 5/ realroot Ex1:crationalroot(2*x^3+(-5-7*i)*x^2+(-4+14*i)*x+8-4*i) - ''' return GiacMethods['crationalroot'](self,*args) @@ -3421,12 +3148,11 @@ cdef class GiacMethods_base: Help for crayon: crayon(Color) Changes the color of the pencil (without parameter, returns the current color). - See also: 1/ leve_crayon 2/ baisse_crayon + See also: 1/ leve_crayon 2/ baisse_crayon Ex1: crayon vert Ex2:crayon(rouge) Ex3:crayon(5) Ex4:crayon(gomme) - ''' return GiacMethods['crayon'](self,*args) @@ -3435,13 +3161,12 @@ cdef class GiacMethods_base: Help for createwav: createwav(Lst(data),[opts]) Returns an audio clip from data, optionally setting channel count, bit depth, sample rate, duration and normalization level. - See also: 1/ readwav 2/ writewav 3/ playsnd + See also: 1/ readwav 2/ writewav 3/ playsnd Ex1:createwav(duration=3.5) Ex2:createwav(sin(2*pi*440*soundsec(2)),samplerate=48000) Ex3:createwav(sin(2*pi*440*soundsec(2)),bit_depth=8) Ex4:createwav(10*sin(2*pi*440*soundsec(2)),normalize=-3) Ex5: t:=soundsec(3):;L,R:=sin(2*pi*440*t),sin(2*pi*445*t):;createwav([L,R]) - ''' return GiacMethods['createwav'](self,*args) @@ -3450,10 +3175,9 @@ cdef class GiacMethods_base: Help for cross: cross(Vect(v1),Vect(v2)) Wedge product. - See also: 1/ dot + See also: 1/ dot Ex1:cross([1,2],[3,4]) Ex2:cross([1,2,3],[4,5,6]) - ''' return GiacMethods['cross'](self,*args) @@ -3462,10 +3186,9 @@ cdef class GiacMethods_base: Help for crossP: crossP(Vect(v1),Vect(v2)) Wedge product. - See also: 1/ dot + See also: 1/ dot Ex1:crossP([1,2],[3,4]) Ex2:crossP([1,2,3],[4,5,6]) - ''' return GiacMethods['crossP'](self,*args) @@ -3474,9 +3197,8 @@ cdef class GiacMethods_base: Help for cross_correlation: cross_correlation(cross_correlation(Lst(u),Lst(v))) Returns the cross_correlation of two signals u and v. - See also: 1/ auto_correlation 2/ correlation + See also: 1/ auto_correlation 2/ correlation Ex1:cross_correlation([1,2],[3,4,5]) - ''' return GiacMethods['cross_correlation'](self,*args) @@ -3485,10 +3207,9 @@ cdef class GiacMethods_base: Help for cross_point: cross_point(Opt) Option of the display command for a point. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) - ''' return GiacMethods['cross_point'](self,*args) @@ -3497,11 +3218,10 @@ cdef class GiacMethods_base: Help for cross_ratio: cross_ratio(Pnt or Cplx(a),Pnt or Cplx(b),Pnt or Cplx(c),Pnt or Cplx(d)) Returns the complex number equal to ((c-a)/(c-b))/((d-a)/(d-b)). - See also: 1/ harmonic_conjugate 2/ is_conjugate + See also: 1/ harmonic_conjugate 2/ is_conjugate Ex1:cross_ratio(i,2+i,3/2+i,3+i) Ex2:cross_ratio(0,1+i,1,i) Ex3:cross_ratio(0,1,2,3) - ''' return GiacMethods['cross_ratio'](self,*args) @@ -3510,10 +3230,9 @@ cdef class GiacMethods_base: Help for crossproduct: crossproduct(Vect(v1),Vect(v2)) Wedge product. - See also: 1/ dot + See also: 1/ dot Ex1:crossproduct([1,2],[3,4]) Ex2:crossproduct([1,2,3],[4,5,6]) - ''' return GiacMethods['crossproduct'](self,*args) @@ -3522,9 +3241,8 @@ cdef class GiacMethods_base: Help for csc: csc(Expr) Cosecant: csc(x)=1/sin(x). - See also: 1/ sin 2/ acsc + See also: 1/ sin 2/ acsc Ex1:csc(pi/2) - ''' return GiacMethods['csc'](self,*args) @@ -3533,12 +3251,11 @@ cdef class GiacMethods_base: Help for csolve: csolve(LstEq,LstVar) Returns the list of complex solutions of an equation or a matrix where the rows are ℂ-solutions of a system of polynomial equations. - See also: 1/ cZeros 2/ solve 3/ fslove + See also: 1/ cZeros 2/ solve 3/ fslove Ex1:csolve(x^4-1,x) Ex2:csolve(x^4-y^4 and x+y=2,[x,y]) Ex3:csolve(x^4-y^4 and x+y=0 and x^2=2*x,[x,y]) Ex4:csolve(u*v-u=v and v^2=u,[u,v]) - ''' return GiacMethods['csolve'](self,*args) @@ -3547,9 +3264,8 @@ cdef class GiacMethods_base: Help for csv2gen: csv2gen(Strng(filename),Strng(sep),Strng(nl),Strng(decsep),Strng(eof),[string]) Reads a file (or string) in CSV format. - See also: 1/ read + See also: 1/ read Ex1:csv2gen("mat.txt",",",char(10),".") - ''' return GiacMethods['csv2gen'](self,*args) @@ -3558,13 +3274,12 @@ cdef class GiacMethods_base: Help for cube: cube(Pnt(A),Pnt(B),Pnt(C)) Draws the direct cube with vertices A,B with a face in the plane (A,B,C). - See also: 1/ parallelepiped 2/ cylinder 3/ icosahedron 4/ dodecahedron 5/ octahedron 6/ tetrahedron 7/ centered_cube - Ex1:cube([0,0,0],[3,0,0],[0,0,1]) - Ex2: A,B,C:=point(1,0,0),point(1,1,0),point(0,1,0);c:=cube(A,B,C);A,B,C,D,E,F,G,H:=sommets(c); - Ex3: A,B,K:=point(1,0,0),point(1,1,0),point(0,2,0);c:=cube(A,B,C);A,B,C,D,E,F,G,H:=sommets(c); - Ex4: c:=cube([0,0,0],[1,0,0],[0,1,0]);c1,c2,c4,c3,c5,c6,c7,c8:=sommets(c); - Ex5: c:=cube([0,0,0],[0,2,0],[0,0,1]);c1,c2,c4,c3,c5,c6,c7,c8:=sommets(c); - + See also: 1/ parallelepiped 2/ cylinder 3/ icosahedron 4/ dodecahedron 5/ octahedron 6/ tetrahedron 7/ centered_cube + Ex1: cube([0,0,0],[3,0,0],[0,0,1]) + Ex2: A,B,C:=point(1,0,0),point(1,1,0),point(0,1,0);c:=cube(A,B,C);A,B,C,D,E,F,G,H:=sommets(c); + Ex3: A,B,K:=point(1,0,0),point(1,1,0),point(0,2,0);c:=cube(A,B,C);A,B,C,D,E,F,G,H:=sommets(c); + Ex4: c:=cube([0,0,0],[1,0,0],[0,1,0]);c1,c2,c4,c3,c5,c6,c7,c8:=sommets(c); + Ex5: c:=cube([0,0,0],[0,2,0],[0,0,1]);c1,c2,c4,c3,c5,c6,c7,c8:=sommets(c); ''' return GiacMethods['cube'](self,*args) @@ -3573,11 +3288,10 @@ cdef class GiacMethods_base: Help for cumSum: cumSum(Lst(l)||Seq||Str) Returns the list (or the sequence or the string) lr where the elements are the cumulative sum of the list l: lr[k]=sum(l[j],j=0..k) (or lr=sum(l[j],j=0..k)$(k=0..size(l)-1)). - See also: 1/ sum + See also: 1/ sum Ex1:cumSum([0,1,2,3,4]) Ex2:cumSum(1.2,3,4.5,6) Ex3:cumSum("a","b","c","d") - ''' return GiacMethods['cumSum'](self,*args) @@ -3586,11 +3300,10 @@ cdef class GiacMethods_base: Help for cumsum: cumsum(Lst(l)||Seq||Str) Returns the list (or the sequence or the string) lr where the elements are the cumulative sum of the list l: lr[k]=sum(l[j],j=0..k) (or lr=sum(l[j],j=0..k)$(k=0..size(l)-1)). - See also: 1/ sum + See also: 1/ sum Ex1:cumsum([0,1,2,3,4]) Ex2:cumsum(1.2,3,4.5,6) Ex3:cumsum("a","b","c","d") - ''' return GiacMethods['cumsum'](self,*args) @@ -3599,13 +3312,12 @@ cdef class GiacMethods_base: Help for cumulated_frequencies: cumulated_frequencies(Lst || Mtrx) Draws the diagram of the cumulated frequencies (rows=[value,frequencies]) - See also: 1/ histogram 2/ classes 3/ bar_plot + See also: 1/ histogram 2/ classes 3/ bar_plot Ex1:cumulated_frequencies([1,2,1,1,2,1,2,4,3,3]) Ex2:cumulated_frequencies([(rand(6)+1)$(k=1..100)]) Ex3:cumulated_frequencies([[1,0.3],[2,0.5],[3,0.2]]) Ex4:cumulated_frequencies([[1..2,0.3],[2..3,0.5],[3..4,0.2]]) Ex5:cumulated_frequencies([[1..2,0.3,0.5],[2..3,0.5,0.2],[3..4,0.2,0.3]]) - ''' return GiacMethods['cumulated_frequencies'](self,*args) @@ -3614,9 +3326,8 @@ cdef class GiacMethods_base: Help for curl: curl(Lst(A,B,C),Lst(x,y,z)) curl([A,B,C],[x,y,z])=[dC/dy-dB/dz,dA/dz-dC/dx,dB/dx-dA/dy]. - See also: 1/ derive 2/ divergence + See also: 1/ derive 2/ divergence Ex1:curl([2*x*y,x*z,y*z],[x,y,z]) - ''' return GiacMethods['curl'](self,*args) @@ -3627,7 +3338,6 @@ cdef class GiacMethods_base: Content of the matrix editor or spreadsheet. Ex1:current_sheet(1,2) Ex2:current_sheet(A1..A5,B,G) - ''' return GiacMethods['current_sheet'](self,*args) @@ -3636,7 +3346,7 @@ cdef class GiacMethods_base: Help for curvature: curvature(Curve,Point) Curvature of curve C at point M. - See also: 1/ osculating_circle 2/ evolute + See also: 1/ osculating_circle 2/ evolute Ex1:curvature(plot(x^2),point(1,1)) Ex2:curvature([5*cos(t),5*sin(t)],t) Ex3:curvature([t,t^2],t) @@ -3644,7 +3354,6 @@ cdef class GiacMethods_base: Ex5:curvature([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t) Ex6:curvature([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t,7) Ex7: trigcos(curvature([2*cos(t),2*sin(t),3*t],t)) - ''' return GiacMethods['curvature'](self,*args) @@ -3653,8 +3362,7 @@ cdef class GiacMethods_base: Help for curve: curve(Expr) Reserved word. - See also: 1/ - + See also: 1/ ''' return GiacMethods['curve'](self,*args) @@ -3663,10 +3371,9 @@ cdef class GiacMethods_base: Help for cyan: cyan(Opt) Option of the display command to display with color. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),red) Ex2: F:=display(point(2+1.5*i),point_point+green) - ''' return GiacMethods['cyan'](self,*args) @@ -3675,9 +3382,8 @@ cdef class GiacMethods_base: Help for cycle2perm: cycle2perm(Cycle) Converts the cycle c to a permutation. - See also: 1/ cycles2permu 2/ permu2cycles + See also: 1/ cycles2permu 2/ permu2cycles Ex1:cycle2perm([1,3,5]) - ''' return GiacMethods['cycle2perm'](self,*args) @@ -3686,10 +3392,9 @@ cdef class GiacMethods_base: Help for cycle_graph: cycle_graph(Intg(n)||Lst(V)) Returns a cyclic graph with n vertices (or with vertices from list V). - See also: 1/ graph 2/ path_graph + See also: 1/ graph 2/ path_graph Ex1:cycle_graph(4) Ex2:cycle_graph(["one","two","three","four","five"]) - ''' return GiacMethods['cycle_graph'](self,*args) @@ -3698,9 +3403,8 @@ cdef class GiacMethods_base: Help for cycleinv: cycleinv(Cycle(c)) Returns the inverse cycle of the cycle c. - See also: 1/ perminv + See also: 1/ perminv Ex1:cycleinv([1,3,5]) - ''' return GiacMethods['cycleinv'](self,*args) @@ -3709,9 +3413,8 @@ cdef class GiacMethods_base: Help for cycles2permu: cycles2permu(Lst(Cycle)) Converts a product of cycles into a permutation. - See also: 1/ permu2cycles 2/ cycle2perm + See also: 1/ permu2cycles 2/ cycle2perm Ex1:cycles2permu([[1,3,5],[3,4]]) - ''' return GiacMethods['cycles2permu'](self,*args) @@ -3720,9 +3423,8 @@ cdef class GiacMethods_base: Help for cyclotomic: cyclotomic(Expr) N-th cyclotomic polynomial. - See also: 1/ none + See also: 1/ none Ex1:cyclotomic(20) - ''' return GiacMethods['cyclotomic'](self,*args) @@ -3731,10 +3433,9 @@ cdef class GiacMethods_base: Help for cylinder: cylinder(Pnt(A),Vect(v),Real(r),[Real(h)]) Draws a cylinder with axis (A,v), with radius r [and with altitude h]. - See also: 1/ half_cone 2/ cone + See also: 1/ half_cone 2/ cone Ex1:cylinder([0,0,0],[0,1,0],2) Ex2:cylinder([0,0,0],[0,1,0],2,-3) - ''' return GiacMethods['cylinder'](self,*args) @@ -3743,10 +3444,9 @@ cdef class GiacMethods_base: Help for dash_line: dash_line(Opt) Option of the display command for a line. - See also: 1/ display + See also: 1/ display Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) - ''' return GiacMethods['dash_line'](self,*args) @@ -3755,10 +3455,9 @@ cdef class GiacMethods_base: Help for dashdot_line: dashdot_line(Opt) Option of the display command for a line. - See also: 1/ display + See also: 1/ display Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) - ''' return GiacMethods['dashdot_line'](self,*args) @@ -3767,10 +3466,9 @@ cdef class GiacMethods_base: Help for dashdotdot_line: dashdotdot_line(Opt) Option of the display command for a line. - See also: 1/ display + See also: 1/ display Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) - ''' return GiacMethods['dashdotdot_line'](self,*args) @@ -3781,7 +3479,6 @@ cdef class GiacMethods_base: dayofweek(d,m,y) returns the day of the given date (day,month,year) : 0 for sunday, 1 for monday ...6 for saturday. Ex1:dayofweek(21,4,2014) Ex2:dayofweek(15,10,1582) - ''' return GiacMethods['dayofweek'](self,*args) @@ -3790,12 +3487,12 @@ cdef class GiacMethods_base: Help for deSolve: deSolve(Eq,[TimeVar],FncVar) Solves a differential equation or a differential linear system with constant coefficients. - See also: 1/ integrate 2/ diff 3/ odesolve 4/ plotode 5/ plotfiefd + See also: 1/ integrate 2/ diff 3/ odesolve 4/ plotode 5/ plotfiefd Ex1:deSolve(y'+x*y=0) Ex2:deSolve(y'+x*y=0,y) Ex3:deSolve(y'+x*y=0,[0,1]) Ex4:deSolve([y'+x*y=0,y(0)=1],y) - Ex5:deSolve([y'=[[1,2],[2,1]]*y+[x,x+1],y(0)=[1,2]]) + Ex5:deSolve([y'=[[1,2],[2,1]]*y+[x,x+1],y(0)=[1,2]]) Ex6:deSolve(y''+y=0,y) Ex7:deSolve([y''+y=sin(x),y(0)=1,y'(0)=2],y) Ex8:deSolve([y''+y=sin(x),y(0)=1,y'(0)=2],x,y) @@ -3807,7 +3504,6 @@ cdef class GiacMethods_base: Ex14:deSolve([z''+2*z'+z,z(0)=1,z'(0)=0],z(u)) Ex15:deSolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],t,z) Ex16:deSolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],z(t)) - ''' return GiacMethods['deSolve'](self,*args) @@ -3816,10 +3512,9 @@ cdef class GiacMethods_base: Help for debut_enregistrement: debut_enregistrement(Var(nom_du_dessin)) Begins recording the commands making up the drawing; the name of the resulting procedure is the argument. - See also: 1/ fin_enregistrement + See also: 1/ fin_enregistrement Ex1:debut_enregistrement(maison) Ex2:debut_enregistrement(arbre) - ''' return GiacMethods['debut_enregistrement'](self,*args) @@ -3828,11 +3523,10 @@ cdef class GiacMethods_base: Help for degree: degree(Poly(P),Var(Var)) Degree of the polynomial P with respect to the second argument. - See also: 1/ valuation 2/ size 3/ total_degree + See also: 1/ valuation 2/ size 3/ total_degree Ex1:degree(x^3+x) Ex2:degree([1,0,1,0]) Ex3:degree(x^3+x*y,y) - ''' return GiacMethods['degree'](self,*args) @@ -3841,9 +3535,8 @@ cdef class GiacMethods_base: Help for degree_sequence: degree_sequence(Graph(G)) Returns the list of degrees of vertices of G (arc directions are ignored). - See also: 1/ is_graphic_sequence 2/ is_regular 2/ sequence_graph 3/ vertex_degree + See also: 1/ is_graphic_sequence 2/ is_regular 2/ sequence_graph 3/ vertex_degree Ex1:degree_sequence(graph(trail(1,2,3,4,2))) - ''' return GiacMethods['degree_sequence'](self,*args) @@ -3852,11 +3545,10 @@ cdef class GiacMethods_base: Help for delcols: delcols(Mtrx(A),Interval(n1..n2)||n1) Returns the matrix where the columns n1..n2 (or n1) of the matrix A are deleted. - See also: 1/ delrows + See also: 1/ delrows Ex1:delcols([[1,2,3],[4,5,6],[7,8,9]],1..1) Ex2:delcols([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3:delcols([[1,2,3],[4,5,6],[7,8,9]],1) - ''' return GiacMethods['delcols'](self,*args) @@ -3865,9 +3557,8 @@ cdef class GiacMethods_base: Help for delete_arc: delete_arc(Graph(G),Edge(e)||Trail(T)||Lst(E)) Returns a modified copy of digraph G with arc e (or trail T or list of arcs E) removed. - See also: 1/ add_arc 2/ delete_edge 3/ digraph 4/ edges 5/ has_arc 6/ trail + See also: 1/ add_arc 2/ delete_edge 3/ digraph 4/ edges 5/ has_arc 6/ trail Ex1:delete_arc(digraph(trail(1,2,3,4,5,1)),[5,1]) - ''' return GiacMethods['delete_arc'](self,*args) @@ -3876,9 +3567,8 @@ cdef class GiacMethods_base: Help for delete_edge: delete_edge(Graph(G),Edge(e)||Trail(T)||Lst(E)) Returns a modified copy of undirected graph G with edge e (or trail T or list of edges E) removed. - See also: 1/ add_edge 2/ delete_arc 3/ edges 4/ graph 5/ has_edge 6/ trail + See also: 1/ add_edge 2/ delete_arc 3/ edges 4/ graph 5/ has_edge 6/ trail Ex1:delete_edge(cycle_graph(4),[1,2]) - ''' return GiacMethods['delete_edge'](self,*args) @@ -3887,9 +3577,8 @@ cdef class GiacMethods_base: Help for delete_vertex: delete_vertex(Graph(G),Vrtx(v)||Lst(V)) Returns a modified copy of G with vertex v (or vertices from V) removed. - See also: 1/ add_vertex 2/ induced_subgraph + See also: 1/ add_vertex 2/ induced_subgraph Ex1:delete_vertex(cycle_graph(5),[1,4]) - ''' return GiacMethods['delete_vertex'](self,*args) @@ -3898,11 +3587,10 @@ cdef class GiacMethods_base: Help for delrows: delrows(Mtrx(A),Interval(n1..n2)||n1) Returns the matrix where the rows n1..n2 (or n1) of the matrix A are deleted. - See also: 1/ delcols + See also: 1/ delcols Ex1:delrows([[1,2,3],[4,5,6],[7,8,9]],1..1) Ex2:delrows([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3:delrows([[1,2,3],[4,5,6],[7,8,9]],1) - ''' return GiacMethods['delrows'](self,*args) @@ -3911,10 +3599,9 @@ cdef class GiacMethods_base: Help for deltalist: deltalist(Lst) Returns the list of the differences of two terms in succession. - See also: 1/ + See also: 1/ Ex1:deltalist([1,4,8,9]) Ex2:deltalist([1,8,4,9]) - ''' return GiacMethods['deltalist'](self,*args) @@ -3923,11 +3610,10 @@ cdef class GiacMethods_base: Help for denom: denom(Frac(a/b) or RatFrac) Returns the denominator of the simplified fraction. - See also: 1/ getDenom 2/ getNum 3/ numer 4/ f2nd + See also: 1/ getDenom 2/ getNum 3/ numer 4/ f2nd Ex1:denom(25/15) Ex2:denom((x^3-1)/(x^2-1)) Ex3:denom(1+(x^3-1)/x^2) - ''' return GiacMethods['denom'](self,*args) @@ -3936,10 +3622,9 @@ cdef class GiacMethods_base: Help for densityplot: densityplot(Expr,[x=xrange,y=yrange],[z],[xstep],[ystep]) Shows in the plane with colors the graph of an expression of 2 variables. - See also: 1/ plotfunc 2/ plotcontour + See also: 1/ plotfunc 2/ plotcontour Ex1:densityplot(x^2-y^2,[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex2:densityplot(x^2-y^2,[x=-2..2,y=-2..2],z=-2..2,xstep=0.1,ystep=0.1) - ''' return GiacMethods['densityplot'](self,*args) @@ -3948,9 +3633,8 @@ cdef class GiacMethods_base: Help for departures: departures(Graph(G),[Vrtx(v)]) Returns the list of vertices of digraph G which are connected by v with arcs such that tails are in v. If v is omitted, a list of departures is computed for every vertex in G. - See also: 1/ out_degree + See also: 1/ out_degree Ex1:departures(digraph(%{[1,2],[1,3],[2,3]%}),1) - ''' return GiacMethods['departures'](self,*args) @@ -3959,7 +3643,7 @@ cdef class GiacMethods_base: Help for derive: derive(Expr or Fnc,[SeqVar or LstVar],[n]) Returns the derivative with respect to the 2nd argument. - See also: 1/ ' 2/ function_diff 3/ integrate 4/ taux_accroissement 5/ implicitdiff + See also: 1/ ' 2/ function_diff 3/ integrate 4/ taux_accroissement 5/ implicitdiff Ex1:derive(x^3-x) Ex2:derive(x^3-x,x,3) Ex3:derive(x^3-x,quote(x)$3) @@ -3968,7 +3652,6 @@ cdef class GiacMethods_base: Ex6:derive(x*y+z*y,y,z) Ex7:derive(x*y+z*y,[y,z]) Ex8: f(x):=sin(2x);g:=diff(f);h:=diff(diff(f)) - ''' return GiacMethods['derive'](self,*args) @@ -3977,7 +3660,7 @@ cdef class GiacMethods_base: Help for deriver: deriver(Expr or Fnc,[SeqVar or LstVar],[n]) Returns the derivative with respect to the 2nd argument. - See also: 1/ ' 2/ function_diff 3/ integrate 4/ taux_accroissement 5/ implicitdiff + See also: 1/ ' 2/ function_diff 3/ integrate 4/ taux_accroissement 5/ implicitdiff Ex1:deriver(x^3-x) Ex2:deriver(x^3-x,x,3) Ex3:deriver(x^3-x,quote(x)$3) @@ -3986,7 +3669,6 @@ cdef class GiacMethods_base: Ex6:deriver(x*y+z*y,y,z) Ex7:deriver(x*y+z*y,[y,z]) Ex8: f(x):=sin(2x);g:=diff(f);h:=diff(diff(f)) - ''' return GiacMethods['deriver'](self,*args) @@ -3995,12 +3677,12 @@ cdef class GiacMethods_base: Help for desolve: desolve(Eq,[TimeVar],FncVar) Solves a differential equation or a differential linear system with constant coefficients. - See also: 1/ integrate 2/ diff 3/ odesolve 4/ plotode 5/ plotfiefd + See also: 1/ integrate 2/ diff 3/ odesolve 4/ plotode 5/ plotfiefd Ex1:desolve(y'+x*y=0) Ex2:desolve(y'+x*y=0,y) Ex3:desolve(y'+x*y=0,[0,1]) Ex4:desolve([y'+x*y=0,y(0)=1],y) - Ex5:desolve([y'=[[1,2],[2,1]]*y+[x,x+1],y(0)=[1,2]]) + Ex5:desolve([y'=[[1,2],[2,1]]*y+[x,x+1],y(0)=[1,2]]) Ex6:desolve(y''+y=0,y) Ex7:desolve([y''+y=sin(x),y(0)=1,y'(0)=2],y) Ex8:desolve([y''+y=sin(x),y(0)=1,y'(0)=2],x,y) @@ -4012,7 +3694,6 @@ cdef class GiacMethods_base: Ex14:desolve([z''+2*z'+z,z(0)=1,z'(0)=0],z(u)) Ex15:desolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],t,z) Ex16:desolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],z(t)) - ''' return GiacMethods['desolve'](self,*args) @@ -4021,11 +3702,10 @@ cdef class GiacMethods_base: Help for dessine_tortue: dessine_tortue([Intg(n)]) Draws the full (or not full if n=1) triangle representing the turtle. - See also: 1/ crayon + See also: 1/ crayon Ex1:dessine_tortue() Ex2:dessine_tortue(0) Ex3:dessine_tortue(1) - ''' return GiacMethods['dessine_tortue'](self,*args) @@ -4034,10 +3714,9 @@ cdef class GiacMethods_base: Help for det: det(Mtrx) Determinant of a square matrix M. - See also: 1/ rref 2/ det_minor 3/ Det + See also: 1/ rref 2/ det_minor 3/ Det Ex1:det([[1,2],[3,4]]) Ex2:det([[1,2,3],[1,3,6],[2,5,7]]) - ''' return GiacMethods['det'](self,*args) @@ -4046,9 +3725,8 @@ cdef class GiacMethods_base: Help for det_minor: det_minor(Mtrx(A)) Returns the determinant calculated with the calculus of minors. - See also: 1/ det + See also: 1/ det Ex1:det_minor([[1,2],[3,4]]) - ''' return GiacMethods['det_minor'](self,*args) @@ -4057,13 +3735,12 @@ cdef class GiacMethods_base: Help for developper: developper(Expr) Full distribution of * and / over + and -. - See also: 1/ texpand 2/ normal 3/ simplify 4/ ratnormal + See also: 1/ texpand 2/ normal 3/ simplify 4/ ratnormal Ex1:developper((x+y)*(z+1)) Ex2:developper((a+b+c)/d) Ex3:developper((y+x)*(z+y)*(x+z)) Ex4:developper((x+3)^4) Ex5:developper((2*x-2*1)*(x^2-3*x+2)+(x^2-2*x+3)*(2*x-3*1)) - ''' return GiacMethods['developper'](self,*args) @@ -4072,11 +3749,10 @@ cdef class GiacMethods_base: Help for developper_transcendant: developper_transcendant(Expr) Expands transcendental expressions. - See also: 1/ tcollect 2/ tlin 3/ lin 4/ trigexpand + See also: 1/ tcollect 2/ tlin 3/ lin 4/ trigexpand Ex1:developper_transcendant(sin(2*x)+exp(x+y)) Ex2:developper_transcendant(cos(x+y)) Ex3:developper_transcendant(cos(3*x)) - ''' return GiacMethods['developper_transcendant'](self,*args) @@ -4085,13 +3761,12 @@ cdef class GiacMethods_base: Help for dfc: dfc(Real(x0),Int(n)||Real(eps)) Returns the continued fraction development at x0 of order n or with precision eps. - See also: 1/ dfc2f 2/ convert + See also: 1/ dfc2f 2/ convert Ex1:dfc(sqrt(2),5) Ex2:dfc(pi,4) Ex3:dfc(evalf(pi),1e-09) Ex4: convert(sqrt(2),confrac,'dev');dev Ex5: convert(9976/6961,confrac,'l');l - ''' return GiacMethods['dfc'](self,*args) @@ -4100,10 +3775,9 @@ cdef class GiacMethods_base: Help for dfc2f: dfc2f(LstFrac_Cont)) Converts a continued fraction into a real. - See also: 1/ dfc 2/ convert + See also: 1/ dfc 2/ convert Ex1:dfc2f([1,1,1]) Ex2:dfc2f([1,2,[2]]) - ''' return GiacMethods['dfc2f'](self,*args) @@ -4112,14 +3786,13 @@ cdef class GiacMethods_base: Help for diag: diag(Lst(l)||(Mtrx(A),[left||right||lu])||Lst(l),Lst(d),Lst(u)) With 1 argument returns either the diagonal matrix with diagonal l or the diagonal of A, with 2 arguments returns the large left (lower) triangular part of A or the large right (upper) triangular part of A or factors A into 3 parts : strict left (lower) triangular, diagonal, strict right (upper) triangular and with 3 arguments returns the tridiagonal matrix with diagonals l,d,u. - See also: 1/ identity 2/ lu 3/ BlockDiagonal 4/ upper 5/ lower + See also: 1/ identity 2/ lu 3/ BlockDiagonal 4/ upper 5/ lower Ex1:diag([[1,2],[3,4]]) Ex2:diag([1,2,3]) Ex3:diag([[1,2],[3,4]],left) Ex4:diag([[1,2],[3,4]],right) Ex5:diag([[1,2],[3,4]],lu) Ex6:diag([1,2],[3,4,5],[6,7]) - ''' return GiacMethods['diag'](self,*args) @@ -4128,7 +3801,7 @@ cdef class GiacMethods_base: Help for diff: diff(Expr or Fnc,[SeqVar or LstVar],[n]) Returns the derivative with respect to the 2nd argument. - See also: 1/ ' 2/ function_diff 3/ integrate 4/ taux_accroissement 5/ implicitdiff + See also: 1/ ' 2/ function_diff 3/ integrate 4/ taux_accroissement 5/ implicitdiff Ex1:diff(x^3-x) Ex2:diff(x^3-x,x,3) Ex3:diff(x^3-x,quote(x)$3) @@ -4137,7 +3810,6 @@ cdef class GiacMethods_base: Ex6:diff(x*y+z*y,y,z) Ex7:diff(x*y+z*y,[y,z]) Ex8: f(x):=sin(2x);g:=diff(f);h:=diff(diff(f)) - ''' return GiacMethods['diff'](self,*args) @@ -4146,10 +3818,9 @@ cdef class GiacMethods_base: Help for digraph: digraph([Lst(V)],[Set(E)],[Mtrx(A)],[options]) Create a directed (un)weighted graph from vertices V, edges E and/or adjacency or weight matrix A. All parameters are optional. - See also: 1/ graph 2/ trail + See also: 1/ graph 2/ trail Ex1:digraph(%{[1,2],[2,3],[3,4],[4,1]%}) Ex2:digraph([a,b,c,d],%{[[a,b],1.0],[[a,c],2.3],[[b,d],3.1],[[c,d],4]%}) - ''' return GiacMethods['digraph'](self,*args) @@ -4158,9 +3829,8 @@ cdef class GiacMethods_base: Help for dijkstra: dijkstra(Graph(G),Vrtx(v),[Vrtx(w)||Lst(W)]) Returns the cheapest weighted path from vertex v to w (or to vertices from W) in undirected graph G. Output is in the form [[v1,v2,...,vk],d] (or list of these) where v1,v2,...,vk are vertices along each path and d is the weight of the path. - See also: 1/ allpairs_distance 2/ shortest_path + See also: 1/ allpairs_distance 2/ shortest_path Ex1:dijkstra(graph(%{[[1,2],1],[[2,3],3],[[3,4],7],[[4,5],3],[[5,6],3],[[1,6],3]%}),1,4) - ''' return GiacMethods['dijkstra'](self,*args) @@ -4169,9 +3839,8 @@ cdef class GiacMethods_base: Help for dim: dim(Mtrx) Returns the list which gives the dimension of the matrix specified as argument. - See also: 1/ rowdim 2/ coldim 3/ sizes 4/ size + See also: 1/ rowdim 2/ coldim 3/ sizes 4/ size Ex1:dim([[1,2,3],[4,5,6]]) - ''' return GiacMethods['dim'](self,*args) @@ -4180,8 +3849,7 @@ cdef class GiacMethods_base: Help for directed: directed(Opt) Option for graph and digraph commands. - See also: 1/ weighted 2/ graph 3/ digraph - + See also: 1/ weighted 2/ graph 3/ digraph ''' return GiacMethods['directed'](self,*args) @@ -4190,9 +3858,8 @@ cdef class GiacMethods_base: Help for discard_edge_attribute: discard_edge_attribute(Graph(G),Edge(e),Seq(tag1=value1,tag2=value2,..)) Discards the attributes with tags tag1, tag2, ... assigned to edge e in G and returns the modified copy of G. - See also: 1/ get_edge_attribute 2/ set_edge_attribute 3/ list_edge_attributes + See also: 1/ get_edge_attribute 2/ set_edge_attribute 3/ list_edge_attributes Ex1:discard_edge_attribute(cycle_graph(3),[1,2],"cost") - ''' return GiacMethods['discard_edge_attribute'](self,*args) @@ -4201,9 +3868,8 @@ cdef class GiacMethods_base: Help for discard_graph_attribute: discard_graph_attribute(Graph(G),Seq(tag1=value1,tag2=value2,..)) Discards the graph attributes with tags tag1, tag2, ... and returns the modified copy of G. - See also: 1/ get_graph_attribute 2/ set_graph_attribute 3/ list_graph_attributes + See also: 1/ get_graph_attribute 2/ set_graph_attribute 3/ list_graph_attributes Ex1:discard_graph_attribute(cycle_graph(3),"name") - ''' return GiacMethods['discard_graph_attribute'](self,*args) @@ -4212,9 +3878,8 @@ cdef class GiacMethods_base: Help for discard_vertex_attribute: discard_vertex_attribute(Graph(G),Vrtx(v),Seq(tag1=value1,tag2=value2,..)) Discards the attributes with tags tag1, tag2, ... assigned to vertex v in G and returns the modified copy of G. - See also: 1/ get_vertex_attribute 2/ set_vertex_attribute 3/ list_vertex_attributes + See also: 1/ get_vertex_attribute 2/ set_vertex_attribute 3/ list_vertex_attributes Ex1:discard_vertex_attribute(cycle_graph(3),1,"supply") - ''' return GiacMethods['discard_vertex_attribute'](self,*args) @@ -4223,9 +3888,8 @@ cdef class GiacMethods_base: Help for disjoint_union: disjoint_union(Seq(G1,G2,...)) Returns the disjoint union of the graphs G1, G2, ... Vertices in the resulting graph are labelled with "k:v", where k is index of the corresponding k-th graph Gk and v is vertex in Gk. - See also: 1/ graph_join 2/ graph_union + See also: 1/ graph_join 2/ graph_union Ex1:disjoint_union(is_connected(disjoint_union(cycle_graph(5),path_graph(4)))) - ''' return GiacMethods['disjoint_union'](self,*args) @@ -4234,7 +3898,7 @@ cdef class GiacMethods_base: Help for display: display([GeoObj or legende],Intg) Draws a geometrical object with colors black=0 red=1 green=2 yellow=3 blue=4, filled with the color in the interior of a closed curve,line_width_n (0=0 or, the (-n)th previous question if n<0 (by default n=-1 for the previous question). - See also: 1/ ans + See also: 1/ ans Ex1:entry() Ex2:entry(2) Ex3:entry(-2) - ''' return GiacMethods['entry'](self,*args) @@ -4916,10 +4528,9 @@ cdef class GiacMethods_base: Help for envelope: envelope(Expr(Xpr),Var(t)||[x,y,t]) Returns the envelope of the curves with equation Xpr=0 as t varies. - See also: 1/ tangent 2/ locus + See also: 1/ tangent 2/ locus Ex1:envelope(y+x*tan(t)-2*sin(t),t) Ex2:envelope(v+u*tan(t)-3*sin(t),[u,v,t]) - ''' return GiacMethods['envelope'](self,*args) @@ -4928,9 +4539,8 @@ cdef class GiacMethods_base: Help for epsilon: epsilon(NULL) Returns the value of epsilon of the CAS configuration. - See also: 1/ epsilon2zero + See also: 1/ epsilon2zero Ex1:epsilon() - ''' return GiacMethods['epsilon'](self,*args) @@ -4939,9 +4549,8 @@ cdef class GiacMethods_base: Help for epsilon2zero: epsilon2zero(Expr) Values < epsilon are replaced by zero. - See also: 1/ evalf + See also: 1/ evalf Ex1:epsilon2zero(1e-13+x+5) - ''' return GiacMethods['epsilon2zero'](self,*args) @@ -4950,11 +4559,10 @@ cdef class GiacMethods_base: Help for equal: equal(Expr,Expr) Prefixed version of =. - See also: 1/ = 2/ equal2diff 3/ equal2list 4/ left 5/ right + See also: 1/ = 2/ equal2diff 3/ equal2list 4/ left 5/ right Ex1: 2*x=4 Ex2:equal(2*x,4) Ex3:equal(x^2-3x+2,0) - ''' return GiacMethods['equal'](self,*args) @@ -4963,10 +4571,9 @@ cdef class GiacMethods_base: Help for equal2diff: equal2diff(Equal) A=B or equal(A,B) is converted into the difference A-B. - See also: 1/ left 2/ right 3/ equal2list 4/ equal 5/ = + See also: 1/ left 2/ right 3/ equal2list 4/ equal 5/ = Ex1:equal2diff(x=2) Ex2:equal2diff(equal(x,2)) - ''' return GiacMethods['equal2diff'](self,*args) @@ -4975,10 +4582,9 @@ cdef class GiacMethods_base: Help for equal2list: equal2list(Equal) A=B or equal(A,B) is converted into the list [A,B]. - See also: 1/ left 2/ right 3/ equal2diff 4/ equal 5/ = + See also: 1/ left 2/ right 3/ equal2diff 4/ equal 5/ = Ex1:equal2list(x=2) Ex2:equal2list(equal(x,2)) - ''' return GiacMethods['equal2list'](self,*args) @@ -4987,9 +4593,8 @@ cdef class GiacMethods_base: Help for equation: equation(GeoObj, VectParam) equation returns the cartesian equation of a curve. - See also: 1/ parameq + See also: 1/ parameq Ex1:equation(line(1-i,i),[x,y]) - ''' return GiacMethods['equation'](self,*args) @@ -4998,12 +4603,11 @@ cdef class GiacMethods_base: Help for equilateral_triangle: equilateral_triangle((Pnt(A) or Cplx),(Pnt(B) or Cplx),[Pnt(P)],[Var(C)]) equilateral_triangle(A,B) (resp equilateral_triangle(A,B,P)) draws the direct equilateral triangle ABC with side AB (resp in the half-plane ABP). - See also: 1/ triangle + See also: 1/ triangle Ex1:equilateral_triangle(point(1+i),0) Ex2:equilateral_triangle(0,1+i,C) Ex3:equilateral_triangle(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:equilateral_triangle(point(0,0,0),point(3,3,3),point(0,0,3),C) - ''' return GiacMethods['equilateral_triangle'](self,*args) @@ -5012,10 +4616,9 @@ cdef class GiacMethods_base: Help for erf: erf(Real(x0)) Returns the approximate value of 2/sqrt(pi)*int(exp(-t^2),t,0,x0). - See also: 1/ erfc + See also: 1/ erfc Ex1:erf(1) Ex2:erf(1/(sqrt(2)))*1/2 - ''' return GiacMethods['erf'](self,*args) @@ -5024,10 +4627,9 @@ cdef class GiacMethods_base: Help for erfc: erfc(Real(x0)) Returns the approximate value of 2/sqrt(pi)*int(exp(-t^2),t,x0,+infinity). - See also: 1/ erf + See also: 1/ erf Ex1:erfc(1) Ex2:erfc(1/(sqrt(2)))*1/2 - ''' return GiacMethods['erfc'](self,*args) @@ -5036,10 +4638,9 @@ cdef class GiacMethods_base: Help for error: error(Str) Generates the display of an error in a program. - See also: 1/ try 2/ catch + See also: 1/ try 2/ catch Ex1:error("Argument should be integer") Ex2:error("je provoque une erreur") - ''' return GiacMethods['error'](self,*args) @@ -5048,10 +4649,9 @@ cdef class GiacMethods_base: Help for est_permu: est_permu(Lst) Returns 1 if the argument is a permutation and 0 otherwise. - See also: 1/ is_cycle 2/ permu2cycles + See also: 1/ is_cycle 2/ permu2cycles Ex1:est_permu([4,2,3,1]) Ex2:est_permu([4,2,3,1,0]) - ''' return GiacMethods['est_permu'](self,*args) @@ -5060,10 +4660,9 @@ cdef class GiacMethods_base: Help for euler: euler(Intg(n)) Euler's function (euler(n)=card({p=0):; euler_lagrange(sqrt((1+y'^2)/y),t,y) - ''' return GiacMethods['euler_lagrange'](self,*args) @@ -5100,7 +4697,6 @@ cdef class GiacMethods_base: Ex3: purge(a,b,c);eval_level(1);a:=b+1; b:=c+1;c:=3; Ex4: purge(a,b,c);eval_level(2);a:=b+1; b:=c+1;c:=3; Ex5: purge(a,b,c);eval_level(3);a:=b+1; b:=c+1;c:=3; - ''' return GiacMethods['eval_level'](self,*args) @@ -5109,11 +4705,10 @@ cdef class GiacMethods_base: Help for evala: evala(Expr) Simplifies the expression. - See also: 1/ simplify + See also: 1/ simplify Ex1:evala(2*x+y=1) Ex2:evala(2*x*2) Ex3:evala((2*x+1)^2) - ''' return GiacMethods['evala'](self,*args) @@ -5122,10 +4717,9 @@ cdef class GiacMethods_base: Help for evalb: evalb(Expr) Boolean evaluation of the argument. - See also: 1/ evalf 2/ eval + See also: 1/ evalf 2/ eval Ex1:evalb(a==2) Ex2:evalb(sqrt(2)+pi>a) - ''' return GiacMethods['evalb'](self,*args) @@ -5134,10 +4728,9 @@ cdef class GiacMethods_base: Help for evalc: evalc(Expr) Returns a complex expression simplified to the format real+i*imag. - See also: 1/ normal + See also: 1/ normal Ex1:evalc(-3+4*i+exp(i)) Ex2:evalc(1/(x+y*i)) - ''' return GiacMethods['evalc'](self,*args) @@ -5146,14 +4739,13 @@ cdef class GiacMethods_base: Help for evalf: evalf(Expr,[Int]) Numerical evaluation of the first argument (we can give the number of digits as second argument). - See also: 1/ evalb 2/ eval + See also: 1/ evalb 2/ eval Ex1:evalf(2/3) Ex2:evalf(2/3,2) Ex3:evalf(2*sin(1)) Ex4:evalf(2*sin(1),40) Ex5:evalf(sqrt(2)+pi) Ex6:evalf(sqrt(2)+pi,30) - ''' return GiacMethods['evalf'](self,*args) @@ -5162,9 +4754,8 @@ cdef class GiacMethods_base: Help for evalm: evalm(Expr) Evaluates its argument. - See also: 1/ evalf + See also: 1/ evalf Ex1:evalm(2*sin(pi)) - ''' return GiacMethods['evalm'](self,*args) @@ -5173,10 +4764,9 @@ cdef class GiacMethods_base: Help for even: even(Intg(n)) Returns 1 if the integer is even, else returns 0. - See also: 1/ odd + See also: 1/ odd Ex1:even(6) Ex2:even(1251) - ''' return GiacMethods['even'](self,*args) @@ -5185,11 +4775,10 @@ cdef class GiacMethods_base: Help for evolute: evolute(Curve) Evolute of a curve C. - See also: 1/ curvature 2/ osculating_circle + See also: 1/ curvature 2/ osculating_circle Ex1:evolute(plot(x^2)) Ex2:evolute([t,t^2],t) Ex3:evolute([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t) - ''' return GiacMethods['evolute'](self,*args) @@ -5198,12 +4787,11 @@ cdef class GiacMethods_base: Help for exact: exact(Expr) Converts the expression to a rational or real expression. - See also: 1/ + See also: 1/ Ex1:exact(-2) Ex2:exact(1.5) Ex3:exact(1.4141) Ex4:exact(0.156381102937) - ''' return GiacMethods['exact'](self,*args) @@ -5212,9 +4800,8 @@ cdef class GiacMethods_base: Help for exbisector: exbisector((Pnt(A) or Cplx),(Pnt(B) or Cplx),(Pnt(C) or Cplx)) Draws the exterior bisector of the angle (AB,AC) given by 3 points A,B,C. - See also: 1/ angle 2/ bisector + See also: 1/ angle 2/ bisector Ex1:exbisector(0,1,i) - ''' return GiacMethods['exbisector'](self,*args) @@ -5223,9 +4810,8 @@ cdef class GiacMethods_base: Help for excircle: excircle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) excircle(A,B,C) draws the A-excircle of the triangle ABC. - See also: 1/ incircle 2/ circumcircle + See also: 1/ incircle 2/ circumcircle Ex1:excircle(0,1,1+i) - ''' return GiacMethods['excircle'](self,*args) @@ -5234,12 +4820,11 @@ cdef class GiacMethods_base: Help for execute: execute(Str) Instruction transforming a string into a command or into a number. - See also: 1/ string + See also: 1/ string Ex1:execute("ifactor(54)") Ex2:execute("123") Ex3:execute("0123") Ex4:execute(sin,x) - ''' return GiacMethods['execute'](self,*args) @@ -5248,10 +4833,9 @@ cdef class GiacMethods_base: Help for exp: exp(Expr or Opt) Exponential or option of the convert or convertir command (id trig2exp). - See also: 1/ ln 2/ convert 3/ trig2exp + See also: 1/ ln 2/ convert 3/ trig2exp Ex1:exp(0) Ex2: convert(cos(x),exp) - ''' return GiacMethods['exp'](self,*args) @@ -5260,10 +4844,9 @@ cdef class GiacMethods_base: Help for exp2list: exp2list(Expr) Returns the list made with the righthand member of (var=expr0 or var=expr1), to be used after solve in TI mode. - See also: 1/ list2exp + See also: 1/ list2exp Ex1:exp2list((x=2) or (x=0)) Ex2:exp2list((x=3 and y=9) or (x=-1 and y=1) ) - ''' return GiacMethods['exp2list'](self,*args) @@ -5272,10 +4855,9 @@ cdef class GiacMethods_base: Help for exp2pow: exp2pow(Expr) Transforms exp(n*ln(x)) to x^n. - See also: 1/ pow2exp + See also: 1/ pow2exp Ex1:exp2pow(exp(3*ln(x))) Ex2:exp2pow(exp(x*ln(x))) - ''' return GiacMethods['exp2pow'](self,*args) @@ -5284,10 +4866,9 @@ cdef class GiacMethods_base: Help for exp2trig: exp2trig(Expr) Transforms the complex exponential into sine and cosine. - See also: 1/ trig2exp 2/ atrig2ln + See also: 1/ trig2exp 2/ atrig2ln Ex1:exp2trig(exp(i*x)) Ex2:exp2trig(exp(-i*x)) - ''' return GiacMethods['exp2trig'](self,*args) @@ -5296,13 +4877,12 @@ cdef class GiacMethods_base: Help for expand: expand(Expr) Full distribution of * and / over + and -. - See also: 1/ texpand 2/ normal 3/ simplify 4/ ratnormal + See also: 1/ texpand 2/ normal 3/ simplify 4/ ratnormal Ex1:expand((x+y)*(z+1)) Ex2:expand((a+b+c)/d) Ex3:expand((y+x)*(z+y)*(x+z)) Ex4:expand((x+3)^4) Ex5:expand((2*x-2*1)*(x^2-3*x+2)+(x^2-2*x+3)*(2*x-3*1)) - ''' return GiacMethods['expand'](self,*args) @@ -5311,9 +4891,8 @@ cdef class GiacMethods_base: Help for expexpand: expexpand(Expr) Expands exponentials. - See also: 1/ texpand 2/ lnexpand 3/ trigexpand + See also: 1/ texpand 2/ lnexpand 3/ trigexpand Ex1:expexpand(exp(3*x)) - ''' return GiacMethods['expexpand'](self,*args) @@ -5322,9 +4901,8 @@ cdef class GiacMethods_base: Help for expln: expln(Opt) Option of the convert or convertir command (id trig2exp). - See also: 1/ exp 2/ ln 3/ convert 4/ trig2exp + See also: 1/ exp 2/ ln 3/ convert 4/ trig2exp Ex1: convert(cos(x),expln) - ''' return GiacMethods['expln'](self,*args) @@ -5333,12 +4911,11 @@ cdef class GiacMethods_base: Help for exponential: exponential(Real(lambda),Real(x)) Returns the probability density at x of the exponential law of parameter lambda. - See also: 1/ exponential_cdf 2/ exponential_icdf 3/ randvector 4/ ranm + See also: 1/ exponential_cdf 2/ exponential_icdf 3/ randvector 4/ ranm Ex1:exponential(2.1,3.5) Ex2:exponential(2.1,0.5) Ex3: randvector(3,exponential,1.2) Ex4: ranm(4,3,exponential,1.2) - ''' return GiacMethods['exponential'](self,*args) @@ -5347,10 +4924,9 @@ cdef class GiacMethods_base: Help for exponential_cdf: exponential_cdf(Real(lambda),Real(x0),[Real(y0)]) Returns the probability that a exponential random variable of parameter lambda is less than x0 (or between x0 and y0). - See also: 1/ exponentiald 2/ exponential_icdf + See also: 1/ exponentiald 2/ exponential_icdf Ex1:exponential_cdf(4.2,2.1) Ex2:exponential_cdf(4.2,2.1,3.2) - ''' return GiacMethods['exponential_cdf'](self,*args) @@ -5359,10 +4935,9 @@ cdef class GiacMethods_base: Help for exponential_icdf: exponential_icdf(Real(lambda),Real(x0),Real(p)) Returns h such that the probability that a exponential random variable of parameter lambda is less than h is p (0<=p<=1). - See also: 1/ exponential_cdf 2/ exponentiald + See also: 1/ exponential_cdf 2/ exponentiald Ex1:exponential_icdf(4.2,0.95) Ex2:exponential_icdf(4.2,0.6) - ''' return GiacMethods['exponential_icdf'](self,*args) @@ -5371,10 +4946,9 @@ cdef class GiacMethods_base: Help for exponential_regression: exponential_regression(Lst||Mtrx(A),[Lst]) Returns the coefficients (a,b) of y=b*a^x : it is the best exponential which approx the points where the coordinates are the rows of A (or the 2 lists). - See also: 1/ logarithmic_regression + See also: 1/ logarithmic_regression Ex1:exponential_regression([[1.0,2.0],[0.0,1.0],[4.0,7.0]]) Ex2:exponential_regression([1.0,0.0,4.0],[2.0,1.0,7.0]) - ''' return GiacMethods['exponential_regression'](self,*args) @@ -5383,10 +4957,9 @@ cdef class GiacMethods_base: Help for exponential_regression_plot: exponential_regression_plot(Lst||Mtrx(A),[Lst]) Returns the plot of y=b*a^x : it is the best exponential which approx the points where the coordinates are the rows of A (or the 2 lists). - See also: 1/ logarithmic_regression_plot + See also: 1/ logarithmic_regression_plot Ex1:exponential_regression_plot([[1.0,2.0],[0.0,1.0],[4.0,7.0]]) Ex2:exponential_regression_plot([1.0,0.0,4.0],[2.0,1.0,7.0]) - ''' return GiacMethods['exponential_regression_plot'](self,*args) @@ -5395,12 +4968,11 @@ cdef class GiacMethods_base: Help for exponentiald: exponentiald(Real(lambda),Real(x)) Returns the probability density at x of the exponential law of parameter lambda. - See also: 1/ exponential_cdf 2/ exponential_icdf 3/ randvector 4/ ranm + See also: 1/ exponential_cdf 2/ exponential_icdf 3/ randvector 4/ ranm Ex1:exponentiald(2.1,3.5) Ex2:exponentiald(2.1,0.5) Ex3: randvector(3,exponential,1.2) Ex4: ranm(4,3,exponential,1.2) - ''' return GiacMethods['exponentiald'](self,*args) @@ -5409,10 +4981,9 @@ cdef class GiacMethods_base: Help for exponentiald_cdf: exponentiald_cdf(Real(lambda),Real(x0),[Real(y0)]) Returns the probability that a exponential random variable of parameter lambda is less than x0 (or between x0 and y0). - See also: 1/ exponentiald 2/ exponential_icdf + See also: 1/ exponentiald 2/ exponential_icdf Ex1:exponentiald_cdf(4.2,2.1) Ex2:exponentiald_cdf(4.2,2.1,3.2) - ''' return GiacMethods['exponentiald_cdf'](self,*args) @@ -5421,10 +4992,9 @@ cdef class GiacMethods_base: Help for exponentiald_icdf: exponentiald_icdf(Real(lambda),Real(x0),Real(p)) Returns h such that the probability that a exponential random variable of parameter lambda is less than h is p (0<=p<=1). - See also: 1/ exponential_cdf 2/ exponentiald + See also: 1/ exponential_cdf 2/ exponentiald Ex1:exponentiald_icdf(4.2,0.95) Ex2:exponentiald_icdf(4.2,0.6) - ''' return GiacMethods['exponentiald_icdf'](self,*args) @@ -5433,9 +5003,8 @@ cdef class GiacMethods_base: Help for export_graph: export_graph(Graph(G),Str("path/to/graphname")) Writes G to the file 'graphname.dot' in directory 'path/to' in dot format, returns 1 on success and 0 on failure. - See also: 1/ import_graph + See also: 1/ import_graph Ex1:export_graph(complete_graph(5),"K5") - ''' return GiacMethods['export_graph'](self,*args) @@ -5444,11 +5013,10 @@ cdef class GiacMethods_base: Help for export_mathml: export_mathml(Expr,[display||content]) Converts an expression to presentation or content MathML block. - See also: 1/ mathml 2/ latex + See also: 1/ mathml 2/ latex Ex1:export_mathml(a+2*b) Ex2:export_mathml(a+2*b,display) Ex3:export_mathml(a+2*b,content) - ''' return GiacMethods['export_mathml'](self,*args) @@ -5457,10 +5025,9 @@ cdef class GiacMethods_base: Help for expovariate: expovariate(Real(a)) Returns a random real according to the exponential distribution with parameter a>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:expovariate(1) Ex2:expovariate(2) - ''' return GiacMethods['expovariate'](self,*args) @@ -5469,12 +5036,11 @@ cdef class GiacMethods_base: Help for expr: expr(Str) Instruction transforming a string into a command or into a number. - See also: 1/ string + See also: 1/ string Ex1:expr("ifactor(54)") Ex2:expr("123") Ex3:expr("0123") Ex4:expr(sin,x) - ''' return GiacMethods['expr'](self,*args) @@ -5483,13 +5049,12 @@ cdef class GiacMethods_base: Help for extend: extend(Lst,Lst||Seq,Seq||Str,Str||Mtrx,Mtrx) Concatenates two lists or two strings or two sequences or 2 matrices; L:=concat(L,L1) or L.concat(L1). - See also: 1/ append 2/ cat 3/ semi_augment 4/ border 5/ + + See also: 1/ append 2/ cat 3/ semi_augment 4/ border 5/ + Ex1:extend([1,2],[3,4,5]) Ex2:extend("bon","jour") Ex3:extend([[1,2],[3,4]],[[4,5,6],[6,7,8]]) Ex4: L:=[1,2];L.concat([3,4,5]) Ex5: S:="abcd";S.concat("efghi") - ''' return GiacMethods['extend'](self,*args) @@ -5498,11 +5063,10 @@ cdef class GiacMethods_base: Help for extract_measure: extract_measure(Var) extract_measure gives as answer the value calculated by the argument. - See also: 1/ angleatraw 2/ distanceatraw 3/ angleat 4/ distanceat 5/ slopeatraw 6/ areaatraw 7/ perimeteratraw 8/ slopeat 5/ areaat 10/ perimeterat + See also: 1/ angleatraw 2/ distanceatraw 3/ angleat 4/ distanceat 5/ slopeatraw 6/ areaatraw 7/ perimeteratraw 8/ slopeat 5/ areaat 10/ perimeterat Ex1:extract_measure(distanceatraw(0,1+i,(1+i)/2)) Ex2:extract_measure(angleatraw(0,1,1+i,1)) Ex3: A:=point(0);B:=point(1+i);a:=distanceatraw(A,B,(1+i)/2);extract_measure(a) - ''' return GiacMethods['extract_measure'](self,*args) @@ -5556,7 +5120,7 @@ cdef class GiacMethods_base: Ex43:extrema(4x*y-x^4-y^4,[x,y]) Ex44:extrema(x*sin(y),[x,y]) Ex45:extrema(x^4+y^4,[x,y]) - Ex46:extrema(x^3*y-x*y^3,[x,y]) + Ex46:extrema(x^3*y-x*y^3,[x,y]) Ex47:extrema(x^2+y^2+z^2,x^4+y^4+z^4=1,[x,y,z]) Ex48:extrema(3x+3y+8z,[x^2+z^2=1,y^2+z^2=1],[x,y,z]) Ex49:extrema(2x^2+y^2,x^4-x^2+y^2=5,[x,y]) @@ -5565,10 +5129,9 @@ cdef class GiacMethods_base: Ex52:extrema(ln(x)+2*ln(y)+3*ln(z)+4*ln(u)+5*ln(v),x+y+z+u+v=1,[x,y,z,u,v]) Ex53:extrema(x*y*z,-2x^3+15x^2*y+11y^3-24y=0,[x,y,z]) Ex54:extrema(x+y-exp(x)-exp(y)-exp(x+y),[x,y]) - Ex55:extrema(x^2*sin(y)-4*x,[x,y]) + Ex55:extrema(x^2*sin(y)-4*x,[x,y]) Ex56:extrema((1+y*sinh(x))/(1+y^2+tanh(x)^2),[x,y]) Ex57:extrema((1+y*sinh(x))/(1+y^2+tanh(x)^2),y=x^2,[x,y]) - ''' return GiacMethods['extrema'](self,*args) @@ -5577,11 +5140,10 @@ cdef class GiacMethods_base: Help for ezgcd: ezgcd(Poly,Poly) GCD of 2 polynomials with at least 2 variables, with the ezgcd algorithm. - See also: 1/ gcd 2/ modgcd 3/ heugcd 4/ psrgcd + See also: 1/ gcd 2/ modgcd 3/ heugcd 4/ psrgcd Ex1:ezgcd(x^2-2*xy+y^2-1,x-y) Ex2:ezgcd((x+1)^4-y^4,(x+1-y)^2) Ex3:ezgcd((x+y-1)*(x+y+1),(x+y+1)^2) - ''' return GiacMethods['ezgcd'](self,*args) @@ -5590,10 +5152,9 @@ cdef class GiacMethods_base: Help for f2nd: f2nd(Frac or RatFrac) Returns the list built with the numerator and the denominator of the simplified fraction. - See also: 1/ simp2 2/ numer 3/ denom 4/ getNum 5/ getDenom + See also: 1/ simp2 2/ numer 3/ denom 4/ getNum 5/ getDenom Ex1:f2nd(42/12) Ex2:f2nd((x^2+2*x+1)/(x^2-1)) - ''' return GiacMethods['f2nd'](self,*args) @@ -5602,10 +5163,9 @@ cdef class GiacMethods_base: Help for fMax: fMax(Expr,[Var]) Returns the abscissa of the maximum of the expression. - See also: 1/ fMin + See also: 1/ fMin Ex1:fMax(-x^2+2*x+1,x) Ex2:fMax(-x^2+2*x+1,x=1..2) - ''' return GiacMethods['fMax'](self,*args) @@ -5614,12 +5174,11 @@ cdef class GiacMethods_base: Help for fMin: fMin(Expr,[Var]) Returns the abscissa of the minimum of the expression. - See also: 1/ fMax + See also: 1/ fMax Ex1:fMin(x^2-2*x+1,x) Ex2:fMin(x^2-2*x+1,x=1..2) Ex3:fMin((x-3)^2+(y-5)^2+1,[],[x,y],[1,1]) Ex4:fMin((x-3)^2+(y-5)^2+1,[x+y^2=1],[x,y],[1,1]) - ''' return GiacMethods['fMin'](self,*args) @@ -5628,13 +5187,12 @@ cdef class GiacMethods_base: Help for fPart: fPart(Real||LstReal) Returns the fractional part (if x<0 then frac(x)+floor(x)+1=x else frac(x)+floor(x)=x). - See also: 1/ floor 2/ iPart 3/ trunc + See also: 1/ floor 2/ iPart 3/ trunc Ex1:fPart(1/2) Ex2:fPart(-1/2) Ex3:fPart(1.2) Ex4:fPart(-1.2) Ex5:fPart([3.4,sqrt(2)]) - ''' return GiacMethods['fPart'](self,*args) @@ -5643,10 +5201,9 @@ cdef class GiacMethods_base: Help for faces: faces(Polygon or Polyedr(P)) Returns the list of the faces (1 face=matrix(n,3) where the n rows are the n vertices of the face) of the polyhedron P. - See also: 1/ polyhedron + See also: 1/ polyhedron Ex1:faces(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex2:faces(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6]))[2] - ''' return GiacMethods['faces'](self,*args) @@ -5655,10 +5212,9 @@ cdef class GiacMethods_base: Help for facteurs_premiers: facteurs_premiers(Intg(a) or LstIntg) Returns the list of prime factors of an integer (each factor is followed by its multiplicity). - See also: 1/ ifactor 2/ factors + See also: 1/ ifactor 2/ factors Ex1:facteurs_premiers(36) Ex2:facteurs_premiers([36,52]) - ''' return GiacMethods['facteurs_premiers'](self,*args) @@ -5667,11 +5223,10 @@ cdef class GiacMethods_base: Help for factor: factor(Expr) Factors a polynomial. - See also: 1/ ifactor 2/ cfactor 3/ partfrac 4/ normal + See also: 1/ ifactor 2/ cfactor 3/ partfrac 4/ normal Ex1:factor(x^4-1) Ex2:factor(x^4-4,sqrt(2)) Ex3:factor(x^4+12*x^3+54*x^2+108*x+81) - ''' return GiacMethods['factor'](self,*args) @@ -5680,10 +5235,9 @@ cdef class GiacMethods_base: Help for factor_xn: factor_xn(Poly(P)) Factors x^n in P (n=degree of polynomial P). - See also: 1/ ifactor 2/ partfrac 3/ normal + See also: 1/ ifactor 2/ partfrac 3/ normal Ex1:factor_xn(x^4-1) Ex2:factor_xn(x^4+12*x^3+54*x^2+108*x+81) - ''' return GiacMethods['factor_xn'](self,*args) @@ -5692,10 +5246,9 @@ cdef class GiacMethods_base: Help for factorial: factorial(Intg(n)|| Real(a)) factorial(n)=n!. For non-integers, factorial(a)=a! = G(a + 1). This calculates the Gamma function. - See also: 1/ comb 2/ perm + See also: 1/ comb 2/ perm Ex1:factorial(4) Ex2:factorial(1.2) - ''' return GiacMethods['factorial'](self,*args) @@ -5704,11 +5257,10 @@ cdef class GiacMethods_base: Help for factoriser: factoriser(Expr) Factors a polynomial. - See also: 1/ ifactor 2/ cfactor 3/ partfrac 4/ normal + See also: 1/ ifactor 2/ cfactor 3/ partfrac 4/ normal Ex1:factoriser(x^4-1) Ex2:factoriser(x^4-4,sqrt(2)) Ex3:factoriser(x^4+12*x^3+54*x^2+108*x+81) - ''' return GiacMethods['factoriser'](self,*args) @@ -5717,10 +5269,9 @@ cdef class GiacMethods_base: Help for factoriser_entier: factoriser_entier(Intg(a)) Factorization of an integer into prime factors. - See also: 1/ factor 2/ ecm_factor + See also: 1/ factor 2/ ecm_factor Ex1:factoriser_entier(50) Ex2:factoriser_entier(123456789) - ''' return GiacMethods['factoriser_entier'](self,*args) @@ -5729,11 +5280,10 @@ cdef class GiacMethods_base: Help for factoriser_sur_C: factoriser_sur_C(Expr) Factorization of the expression in ℂ (on the Gaussian integers if there are more than 2 variables). - See also: 1/ factor + See also: 1/ factor Ex1:factoriser_sur_C(x^2*y+y) Ex2:factoriser_sur_C(x^2*y^2+y^2+4*x^2+4) Ex3:factoriser_sur_C(x^2*y^2+y^2+2*x^2+2) - ''' return GiacMethods['factoriser_sur_C'](self,*args) @@ -5742,10 +5292,9 @@ cdef class GiacMethods_base: Help for factors: factors(Poly or LstPoly) Returns the list of prime factors of a polynomial (each factor is followed by its multiplicity). - See also: 1/ factor 2/ ifactors + See also: 1/ factor 2/ ifactors Ex1:factors(x^4-1) Ex2:factors([x^2,x^2-1]) - ''' return GiacMethods['factors'](self,*args) @@ -5754,9 +5303,8 @@ cdef class GiacMethods_base: Help for fadeev: fadeev(Opt) Option of the pcar or charpoly command to specify the algorithm. - See also: 1/ pcar + See also: 1/ pcar Ex1: pcar([[4,1,-2],[1,2,-1],[2,1,0]],fadeev) - ''' return GiacMethods['fadeev'](self,*args) @@ -5765,9 +5313,8 @@ cdef class GiacMethods_base: Help for false: false() Boolean equal to false or 0. - See also: 1/ true + See also: 1/ true Ex1: a:=false - ''' return GiacMethods['false'](self,*args) @@ -5776,14 +5323,13 @@ cdef class GiacMethods_base: Help for falsepos_solver: falsepos_solver(Opt) Argument for fsolve giving the method for solving a numerical equation. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve(cos(x)=x,x,0..1,bisection_solver) Ex2: fsolve(cos(x)=x,x,0..1,brent_solver) Ex3: fsolve(cos(x)=x,x,0..1,falsepos_solver) Ex4: fsolve(cos(x)=x,x,0,newton_solver) Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) - ''' return GiacMethods['falsepos_solver'](self,*args) @@ -5792,9 +5338,8 @@ cdef class GiacMethods_base: Help for fclose: fclose(File(f)) Closes the file f. - See also: 1/ fprint 2/ fopen + See also: 1/ fprint 2/ fopen Ex1:fclose(f) - ''' return GiacMethods['fclose'](self,*args) @@ -5803,9 +5348,8 @@ cdef class GiacMethods_base: Help for fcoeff: fcoeff(Lst(root||pole,order)) Returns the polynomial described by the list (root or pole, order). - See also: 1/ pcoeff 2/ froot 3/ proot + See also: 1/ pcoeff 2/ froot 3/ proot Ex1:fcoeff([1,2,0,1,3,-1]) - ''' return GiacMethods['fcoeff'](self,*args) @@ -5814,13 +5358,12 @@ cdef class GiacMethods_base: Help for fdistrib: fdistrib(Expr) Full distribution of * and / over + and -. - See also: 1/ texpand 2/ normal 3/ simplify 4/ ratnormal + See also: 1/ texpand 2/ normal 3/ simplify 4/ ratnormal Ex1:fdistrib((x+y)*(z+1)) Ex2:fdistrib((a+b+c)/d) Ex3:fdistrib((y+x)*(z+y)*(x+z)) Ex4:fdistrib((x+3)^4) Ex5:fdistrib((2*x-2*1)*(x^2-3*x+2)+(x^2-2*x+3)*(2*x-3*1)) - ''' return GiacMethods['fdistrib'](self,*args) @@ -5829,10 +5372,9 @@ cdef class GiacMethods_base: Help for fft: fft(Vect or (Vect(L),Intg(a),Intg(p)) Fast Fourier Transform in ℝ or in the field ℤ/pℤ, with a as primitive n-th root of 1 (n=size(L)). - See also: 1/ ifft + See also: 1/ ifft Ex1:fft([1,2,3,4,0,0,0,0]) Ex2:fft(ranm(128),22798,35969) - ''' return GiacMethods['fft'](self,*args) @@ -5841,13 +5383,12 @@ cdef class GiacMethods_base: Help for fieldplot: fieldplot(Expr,VectVar,[Opt]) fieldplot(f(t,y),[t,y]) draws the plotfield of the diff equation y'=f(t,y). - See also: 1/ interactive_plotode 2/ odeplot 3/ odesolve 4/ desolve + See also: 1/ interactive_plotode 2/ odeplot 3/ odesolve 4/ desolve Ex1:fieldplot(sin(t*y),[t=-5..5,y=-3..3],xstep=0.5,ystep=0.5) Ex2:fieldplot(-t*y,[t,y]) Ex3:fieldplot(-t*y,[t,y],normalize) Ex4:fieldplot(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) Ex5:fieldplot(-t*y,[t=-6.868..6.868,y=-6.868..6.868],normalize) - ''' return GiacMethods['fieldplot'](self,*args) @@ -5856,13 +5397,12 @@ cdef class GiacMethods_base: Help for find: find(Expr,Vect) List of positions of an object in a list, a string or a set. - See also: 1/ index 2/ member + See also: 1/ index 2/ member Ex1:find(1,[3,x,1,2,1,3]) Ex2:find(2,[0,1,3,2,4,2,5])[0] Ex3:find("a","abracadabrant") Ex4:find("ab","abracadabrant") Ex5:find(1,%{4,3,1,2%}) - ''' return GiacMethods['find'](self,*args) @@ -5871,11 +5411,10 @@ cdef class GiacMethods_base: Help for find_cycles: find_cycles(Graph(G,[length=k||l..u])) Returns the list of elementary cycles of the digraph G. If option "length" is specified, only cycles of length k resp. of length between l and u are returned. - See also: 1/ is_acyclic + See also: 1/ is_acyclic Ex1:find_cycles(digraph(%{[1,2],[1,3],[3,1],[1,4],[2,3],[4,3],[4,5],[5,3],[5,6],[7,6],[8,6],[8,7]%})) Ex2:find_cycles(digraph(%{[1,2],[1,3],[3,1],[1,4],[2,3],[4,3],[4,5],[5,3],[5,6],[7,6],[8,6],[8,7]%}),length=3) Ex3:find_cycles(digraph(%{[1,2],[1,3],[3,1],[1,4],[2,3],[4,3],[4,5],[5,3],[5,6],[7,6],[8,6],[8,7]%}),length=3..4) - ''' return GiacMethods['find_cycles'](self,*args) @@ -5884,9 +5423,8 @@ cdef class GiacMethods_base: Help for findhelp: findhelp(Cmd) Returns help about the command (if ? is infixed see when) . - See also: 1/ ifte 2/ when + See also: 1/ ifte 2/ when Ex1:findhelp(ifactor) - ''' return GiacMethods['findhelp'](self,*args) @@ -5895,12 +5433,11 @@ cdef class GiacMethods_base: Help for fisher: fisher(Intg(n),Intg(m),Real(x0)) Returns the probability density of the Fisher-Snedecor law (n and m are the numbers of degrees of freedom). - See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm + See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm Ex1:fisher(4,10,2.1) Ex2:fisher(4,4,2.1) Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) - ''' return GiacMethods['fisher'](self,*args) @@ -5909,10 +5446,9 @@ cdef class GiacMethods_base: Help for fisher_cdf: fisher_cdf(Intg(n),Intg(m),Real(x0)) Returns the probability that a Fisher-Snedecor random variable is less than x0 (n and m are the numbers of degrees of freedom). - See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd + See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd Ex1:fisher_cdf(4,4,2.1) Ex2:fisher_cdf(4,10,3.5) - ''' return GiacMethods['fisher_cdf'](self,*args) @@ -5921,10 +5457,9 @@ cdef class GiacMethods_base: Help for fisher_icdf: fisher_icdf(Intg(n),Intg(m),Real(p)) Returns h such as the probability that a Fisher-Snedecor random variable is less than h is p (n and m are the numbers of degrees of freedom and 0<=p<=1). - See also: 1/ fisher_cdf 2/ fisherd + See also: 1/ fisher_cdf 2/ fisherd Ex1:fisher_icdf(4,10,0.95) Ex2:fisher_icdf(4,10,0.05) - ''' return GiacMethods['fisher_icdf'](self,*args) @@ -5933,12 +5468,11 @@ cdef class GiacMethods_base: Help for fisherd: fisherd(Intg(n),Intg(m),Real(x0)) Returns the probability density of the Fisher-Snedecor law (n and m are the numbers of degrees of freedom). - See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm + See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm Ex1:fisherd(4,10,2.1) Ex2:fisherd(4,4,2.1) Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) - ''' return GiacMethods['fisherd'](self,*args) @@ -5947,10 +5481,9 @@ cdef class GiacMethods_base: Help for fisherd_cdf: fisherd_cdf(Intg(n),Intg(m),Real(x0)) Returns the probability that a Fisher-Snedecor random variable is less than x0 (n and m are the numbers of degrees of freedom). - See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd + See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd Ex1:fisherd_cdf(4,4,2.1) Ex2:fisherd_cdf(4,10,3.5) - ''' return GiacMethods['fisherd_cdf'](self,*args) @@ -5959,10 +5492,9 @@ cdef class GiacMethods_base: Help for fisherd_icdf: fisherd_icdf(Intg(n),Intg(m),Real(p)) Returns h such as the probability that a Fisher-Snedecor random variable is less than h is p (n and m are the numbers of degrees of freedom and 0<=p<=1). - See also: 1/ fisher_cdf 2/ fisherd + See also: 1/ fisher_cdf 2/ fisherd Ex1:fisherd_icdf(4,10,0.95) Ex2:fisherd_icdf(4,10,0.05) - ''' return GiacMethods['fisherd_icdf'](self,*args) @@ -5971,11 +5503,10 @@ cdef class GiacMethods_base: Help for fitdistr: fitdistr(Lst(L),Fnc(D)) Returns the distribution of type D which fits most closely to the i.i.d. samples in the list L. - See also: 1/ normald 2/ poisson 3/ exponentiald 4/ geometric 5/ gammad 6/ betad 7/ cauchyd 8/ weibulld 9/ sample 10/ randvector 11/ randvar + See also: 1/ normald 2/ poisson 3/ exponentiald 4/ geometric 5/ gammad 6/ betad 7/ cauchyd 8/ weibulld 9/ sample 10/ randvector 11/ randvar Ex1:fitdistr(randvector(1000,weibulld,1/2,1),weibull) Ex2: X:=randvar(normal,stddev=9.5):;Y:=randvar(normal,stddev=1.5):;S:=sample(eval(X/Y,0),1000):;Z:=fitdistr(S,cauchy) Ex3: X:=randvar(normal,mean=5,variance=2):;S:=sample(exp(X),1000):;fitdistr(log(S),normal) - ''' return GiacMethods['fitdistr'](self,*args) @@ -5984,9 +5515,8 @@ cdef class GiacMethods_base: Help for flatten: flatten(Lst) Recursively flatten a list containing lists. - See also: 1/ mat2list + See also: 1/ mat2list Ex1:flatten([[1,[2,3],4],[5,6]]) - ''' return GiacMethods['flatten'](self,*args) @@ -5995,12 +5525,11 @@ cdef class GiacMethods_base: Help for float2rational: float2rational(Expr) Converts the expression to a rational or real expression. - See also: 1/ + See also: 1/ Ex1:float2rational(-2) Ex2:float2rational(1.5) Ex3:float2rational(1.4141) Ex4:float2rational(0.156381102937) - ''' return GiacMethods['float2rational'](self,*args) @@ -6009,10 +5538,9 @@ cdef class GiacMethods_base: Help for floor: floor(Real or Cplx) Returns the greatest integer <= to the argument. - See also: 1/ round 2/ ceil 3/ iPart 4/ trunc + See also: 1/ round 2/ ceil 3/ iPart 4/ trunc Ex1:floor(-2.5) Ex2:floor(2.5-4.2*i) - ''' return GiacMethods['floor'](self,*args) @@ -6021,10 +5549,9 @@ cdef class GiacMethods_base: Help for flow_polynomial: flow_polynomial(Graph(G),[Var(x)]) Returns the flow polynomial [or its value at point x] of undirected unweighted graph G. - See also: 1/ chromatic_polynomial 2/ reliability_polynomial 3/ tutte_polynomial + See also: 1/ chromatic_polynomial 2/ reliability_polynomial 3/ tutte_polynomial Ex1:flow_polynomial(graph("tetrahedron")) Ex2:flow_polynomial(graph("tetrahedron"),5) - ''' return GiacMethods['flow_polynomial'](self,*args) @@ -6034,7 +5561,6 @@ cdef class GiacMethods_base: fmod(Real(a),Real(b)) Returns a mod b for a and b floats. Ex1:fmod(10.0,pi) - ''' return GiacMethods['fmod'](self,*args) @@ -6043,9 +5569,8 @@ cdef class GiacMethods_base: Help for foldl: foldl(op,id,Seq(r1,r2,...)) Returns the composition of the binary operator or function op, with an identity or initial value id onto its arguments r1, r2, ..., associating from the left. - See also: 1/ apply 2/ foldr 3/ map + See also: 1/ apply 2/ foldr 3/ map Ex1:foldl(F,init,a,b,c) - ''' return GiacMethods['foldl'](self,*args) @@ -6054,9 +5579,8 @@ cdef class GiacMethods_base: Help for foldr: foldr(op,id,Seq(r1,r2,...)) Returns the composition of the binary operator or function op, with an identity or initial value id onto its arguments r1, r2, ..., associating from the right. - See also: 1/ apply 2/ foldl 3/ map + See also: 1/ apply 2/ foldl 3/ map Ex1:foldr(F,init,a,b,c) - ''' return GiacMethods['foldr'](self,*args) @@ -6065,13 +5589,12 @@ cdef class GiacMethods_base: Help for fonction_derivee: fonction_derivee(Fnc(f)) Returns the derivative function of the function f. - See also: 1/ diff 2/ ' 3/ @ + See also: 1/ diff 2/ ' 3/ @ Ex1:fonction_derivee(sin+id) Ex2:fonction_derivee(sq@sin+id) Ex3:fonction_derivee(ln)(x,y) Ex4:fonction_derivee(ln)([x,y]) - Ex5: (function_diff @@3)(ln)('x') - + Ex5: (function_diff @@3)(ln)('x') ''' return GiacMethods['fonction_derivee'](self,*args) @@ -6080,10 +5603,9 @@ cdef class GiacMethods_base: Help for forward: forward(NULL or Real(n)) The turtle takes n steps forward (by default n=10). - See also: 1/ recule 2/ saute + See also: 1/ recule 2/ saute Ex1: avance 30 Ex2:forward(30) - ''' return GiacMethods['forward'](self,*args) @@ -6092,7 +5614,7 @@ cdef class GiacMethods_base: Help for fourier: fourier(Expr(f(x)),[Var(x),[Var(s)]]) Returns the Fourier transform F(s) of f(x). - See also: 1/ ifourier 2/ fourier_cn 3/ fft + See also: 1/ ifourier 2/ fourier_cn 3/ fft Ex1:fourier(x/(x^3-19x+30),x,s) Ex2:fourier((x^2+1)/(x^2-1),x,s) Ex3:fourier(3x^2+2x+1,x,s) @@ -6109,7 +5631,6 @@ cdef class GiacMethods_base: Ex14:fourier(Gamma(1+i*x/3),x,s) Ex15:fourier(atan(x/4)/x,x,s) Ex16:fourier(piecewise(x<=-1,exp(x+1),x<=1,1,exp(2-2x)),x,s) - ''' return GiacMethods['fourier'](self,*args) @@ -6118,10 +5639,9 @@ cdef class GiacMethods_base: Help for fourier_an: fourier_an(Expr(f(x)),Var(x),Period(T),Intg(n),Real(a)) Returns the n-th Fourier coefficient an=2/T*integrate(f(x)*cos(2*pi*n*x/T),a,a+T). - See also: 1/ fourier_cn 2/ fourier_bn 3/ assume + See also: 1/ fourier_cn 2/ fourier_bn 3/ assume Ex1:fourier_an(x^2,x,2,0,-1) Ex2:fourier_an(x^2,x,2,n,-1) - ''' return GiacMethods['fourier_an'](self,*args) @@ -6130,10 +5650,9 @@ cdef class GiacMethods_base: Help for fourier_bn: fourier_bn(Expr(f(x)),Var(x),Period(T),Intg(n),Real(a)) Returns the n-th Fourier coefficient bn=2/T*integrate(f(x)*sin(2*pi*n*x/T),a,a+T). - See also: 1/ fourier_cn 2/ fourier_an 3/ assume + See also: 1/ fourier_cn 2/ fourier_an 3/ assume Ex1:fourier_bn(x^2,x,2,0,-1) Ex2:fourier_bn(x^2,x,2,n,-1) - ''' return GiacMethods['fourier_bn'](self,*args) @@ -6142,10 +5661,9 @@ cdef class GiacMethods_base: Help for fourier_cn: fourier_cn(Expr(f(x)),Var(x),Period(T),Intg(n),Real(a)) Returns the n-th Fourier coefficient cn=1/T*integrate(f(x)*exp(-2*i*pi*n*x/T),a,a+T). - See also: 1/ fourier_an 2/ fourier_bn 3/ assume + See also: 1/ fourier_an 2/ fourier_bn 3/ assume Ex1:fourier_cn(x^2,x,2,0,-1) Ex2:fourier_cn(x^2,x,2,n,-1) - ''' return GiacMethods['fourier_cn'](self,*args) @@ -6154,11 +5672,10 @@ cdef class GiacMethods_base: Help for fprint: fprint(File(f),Var,[Var,Var...]) Writes in the file f some data. - See also: 1/ fopen 2/ fclose + See also: 1/ fopen 2/ fclose Ex1:fprint(f,x+1,"2") Ex2:fprint(f,"blabla") Ex3:fprint(f,Unquoted,"blabla") - ''' return GiacMethods['fprint'](self,*args) @@ -6167,13 +5684,12 @@ cdef class GiacMethods_base: Help for frac: frac(Real||LstReal) Returns the fractional part (if x<0 then frac(x)+floor(x)+1=x else frac(x)+floor(x)=x). - See also: 1/ floor 2/ iPart 3/ trunc + See also: 1/ floor 2/ iPart 3/ trunc Ex1:frac(1/2) Ex2:frac(-1/2) Ex3:frac(1.2) Ex4:frac(-1.2) Ex5:frac([3.4,sqrt(2)]) - ''' return GiacMethods['frac'](self,*args) @@ -6182,9 +5698,8 @@ cdef class GiacMethods_base: Help for fracmod: fracmod(Expr(Xpr),Intg(n)) Returns the fraction a/b such as b*Xpr=a mod n, -sqrt(n)/20),Real(b>0),Real(x>=0)) Returns the probability density of the Gamma law (=x^(a-1)*exp(-b*x)*b^a/Gamma(a)). - See also: 1/ gammad_cdf; 2/ gammad_icdf + See also: 1/ gammad_cdf; 2/ gammad_icdf Ex1:gammad(2.2,1.5,0.8) - ''' return GiacMethods['gammad'](self,*args) @@ -6318,10 +5823,9 @@ cdef class GiacMethods_base: Help for gammad_cdf: gammad_cdf(Real(a>0),Real(b>0),Real(x0>=0),[Real(y0>=0)]) Returns the probability that a Gamma random variable (with a and b as parameters) is less than x0 or between x0 and y0. - See also: 1/ gammad 2/ gammad_icdf + See also: 1/ gammad 2/ gammad_icdf Ex1:gammad_cdf(2,1,2.96) Ex2:gammad_cdf(2,1,1.4,2.96) - ''' return GiacMethods['gammad_cdf'](self,*args) @@ -6330,10 +5834,9 @@ cdef class GiacMethods_base: Help for gammad_icdf: gammad_icdf(Real(a>0),Real(b>0),Real(0<=p<=1)) Returns h such that the probability that a Gamma random variable is less than h is p (0<=p<=1). - See also: 1/ gammad_cdf 2/ gammad + See also: 1/ gammad_cdf 2/ gammad Ex1:gammad_icdf(2,1,0.95) Ex2:gammad_icdf(2,1,0.5) - ''' return GiacMethods['gammad_icdf'](self,*args) @@ -6342,10 +5845,9 @@ cdef class GiacMethods_base: Help for gammavariate: gammavariate(Real(a),Real(b)) Returns a random real according to the Gamma distribution with parameters a>0 and b>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:gammavariate(1,2) Ex2:gammavariate(1.5,4) - ''' return GiacMethods['gammavariate'](self,*args) @@ -6354,9 +5856,8 @@ cdef class GiacMethods_base: Help for gauss: gauss(Expr,VectVar) Splits a quadratic form as a sum/difference of squares. - See also: 1/ cholesky + See also: 1/ cholesky Ex1:gauss(x^2+2*a*x*y,[x,y]) - ''' return GiacMethods['gauss'](self,*args) @@ -6365,12 +5866,11 @@ cdef class GiacMethods_base: Help for gauss15: gauss15(Opt) Option of the area command. - See also: 1/ area + See also: 1/ area Ex1: area(x^2,x=0..1,5,simpson) Ex2: area(x^2,x=0..1,5,rombergt) Ex3: area(x^2,x=0..1,5,rombergm) Ex4:gauss15(area(x^2,x=0..1,5,gauss15)) - ''' return GiacMethods['gauss15'](self,*args) @@ -6379,12 +5879,11 @@ cdef class GiacMethods_base: Help for gauss_seidel_linsolve: gauss_seidel_linsolve([Real(omega)],Mtrx(A),Vect(b),Real(eps),[Int(maxiter)]) Resolution of a linear system A*X=b by the iterative Gauss-Seidel method (by defaut omega=1) or by relaxation method, with eps as error margin and a number of iterations less than maxiter. - See also: 1/ jacobi_linsolve 2/ linsolve + See also: 1/ jacobi_linsolve 2/ linsolve Ex1: a:=[[100,2],[2,100]];gauss_seidel_linsolve(a,[0,1],1e-12); - Ex2: a:=[[100,2],[2,100]];gauss_seidel_linsolve(table(a),[0,1],1e-12); + Ex2: a:=[[100,2],[2,100]];gauss_seidel_linsolve(table(a),[0,1],1e-12); Ex3: a:=[[100,2],[2,100]];gauss_seidel_linsolve(1.5,a,[0,1],1e-12); - Ex4: a:=[[100,2],[2,100]];gauss_seidel_linsolve(1.5,table(a),[0,1],1e-12); - + Ex4: a:=[[100,2],[2,100]];gauss_seidel_linsolve(1.5,table(a),[0,1],1e-12); ''' return GiacMethods['gauss_seidel_linsolve'](self,*args) @@ -6393,9 +5892,8 @@ cdef class GiacMethods_base: Help for gaussian_window: gaussian_window(Lst,[Real(a)],[Interval(n1..n2)]) Applies the Gaussian windowing function with parameter 0= b (default a=0.2 and b=1/6.) - See also: 1/ gbasis 2/ gbasis_max_pairs 3/ gbasis_reinject + See also: 1/ gbasis 2/ gbasis_max_pairs 3/ gbasis_reinject Ex1:gbasis_reinject(0.1) Ex2:gbasis_reinject(0.1,0.05) - ''' return GiacMethods['gbasis_reinject'](self,*args) @@ -6470,9 +5963,8 @@ cdef class GiacMethods_base: Help for gbasis_simult_primes: gbasis_simult_primes(Intg) Gbasis fine-tuning: maximal number of Groebner basis modulo a prime that are computed simultaneously to rebuild a Groebner basis over Q (default 16). Set it to a smaller value if short in memory. - See also: 1/ gbasis 2/ gbasis_max_pairs 3/ gbasis_reinject + See also: 1/ gbasis 2/ gbasis_max_pairs 3/ gbasis_reinject Ex1:gbasis_simult_primes(3) - ''' return GiacMethods['gbasis_simult_primes'](self,*args) @@ -6481,13 +5973,12 @@ cdef class GiacMethods_base: Help for gcd: gcd((Intg(a) or Poly),(Intg(b) or Poly)) Returns the greatest common divisor of 2 polynomials of several variables or of 2 integers or of 2 rationals. - See also: 1/ lcm 2/ euler 2/ modgcd 3/ ezgcd 4/ psrgcd 5/ heugcd 6/ Gcd + See also: 1/ lcm 2/ euler 2/ modgcd 3/ ezgcd 4/ psrgcd 5/ heugcd 6/ Gcd Ex1:gcd(45,75) Ex2:gcd(15/7,50/9) Ex3:gcd(x^2-2*x+1,x^3-1) Ex4:gcd(t^2-2*t+1,t^2+t-2) Ex5:gcd((x^2-1)*(y^2-1)*z^2,x^3*y^3*z+(-(y^3))*z+x^3*z-z) - ''' return GiacMethods['gcd'](self,*args) @@ -6496,12 +5987,11 @@ cdef class GiacMethods_base: Help for gcdex: gcdex((Poly or Lst),(Poly or Lst),[Var]) Extended greatest common divisor of 2 polynomials. - See also: 1/ gcd 2/ iegcd + See also: 1/ gcd 2/ iegcd Ex1:gcdex((x-1)^2,x^3-1) Ex2:gcdex((X-1)^2,X^3-1,X) Ex3:gcdex([1,-2,1],[1,0,0,-1]) Ex4:gcdex([1,-2,1],[1,-1,2]) - ''' return GiacMethods['gcdex'](self,*args) @@ -6510,11 +6000,10 @@ cdef class GiacMethods_base: Help for genpoly: genpoly(Poly(P),Intg(b),Var) Returns the reconstruction of a n-variables polynomial Q(-b/2<=coef<=b/2) from an (n-1)-variable polynomial P and a base b (subst(Q,var=b)=P). - See also: 1/ + See also: 1/ Ex1:genpoly(15,4,x) Ex2:genpoly(7*y+5,6,x) Ex3:genpoly(7*y-5*z,10,x) - ''' return GiacMethods['genpoly'](self,*args) @@ -6523,12 +6012,11 @@ cdef class GiacMethods_base: Help for geometric: geometric(Real(p),Intg(k)) Returns the value at k of the geometric law with parameter p (0cos(2*x)) Ex4:getType(1.414) - ''' return GiacMethods['getType'](self,*args) @@ -6611,9 +6093,8 @@ cdef class GiacMethods_base: Help for get_edge_attribute: get_edge_attribute(Graph(G),Edge(e),Seq(tag1=value1,tag2=value2,..)) Returns the attributes tag1, tag2, ... assigned to edge e in G as a sequence of the corresponding values. - See also: 1/ discard_edge_attribute 2/ set_edge_attribute 3/ list_edge_attributes + See also: 1/ discard_edge_attribute 2/ set_edge_attribute 3/ list_edge_attributes Ex1:get_edge_attribute(cycle_graph(3),[1,2],"cost") - ''' return GiacMethods['get_edge_attribute'](self,*args) @@ -6622,9 +6103,8 @@ cdef class GiacMethods_base: Help for get_edge_weight: get_edge_weight(Graph(G),Edge(e)) Returns the weight of the edge e in the weighted graph G. - See also: 1/ is_weighted 2/ make_weighted 3/ set_edge_weight 4/ weight_matrix + See also: 1/ is_weighted 2/ make_weighted 3/ set_edge_weight 4/ weight_matrix Ex1:get_edge_weight(graph(%{[[1,2],5],[[2,3],6]%}),[1,2]) - ''' return GiacMethods['get_edge_weight'](self,*args) @@ -6633,9 +6113,8 @@ cdef class GiacMethods_base: Help for get_graph_attribute: get_graph_attribute(Graph(G),Seq(tag1=value1,tag2=value2,..)) Return the graph attributes tag1, tag2, ..., as a sequence of the corresponding values. - See also: 1/ discard_graph_attribute 2/ set_graph_attribute 3/ list_graph_attributes + See also: 1/ discard_graph_attribute 2/ set_graph_attribute 3/ list_graph_attributes Ex1:get_graph_attribute(cycle_graph(3),"name") - ''' return GiacMethods['get_graph_attribute'](self,*args) @@ -6644,9 +6123,8 @@ cdef class GiacMethods_base: Help for get_vertex_attribute: get_vertex_attribute(Graph(G),Vrtx(v),Seq(tag1=value1,tag2=value2,..)) Returns the attributes tag1, tag2, ... assigned to vertex v in G as a sequence of the corresponding values. - See also: 1/ discard_vertex_attribute 2/ set_vertex_attribute 3/ list_vertex_attributes + See also: 1/ discard_vertex_attribute 2/ set_vertex_attribute 3/ list_vertex_attributes Ex1:get_vertex_attribute(cycle_graph(3),1,"supply") - ''' return GiacMethods['get_vertex_attribute'](self,*args) @@ -6655,10 +6133,9 @@ cdef class GiacMethods_base: Help for girth: girth(Graph(G)) Returns the length of the shortest cycle in the undirected unweighted graph G. - See also: 1/ odd_girth + See also: 1/ odd_girth Ex1:girth(graph("petersen")) Ex2:girth(hypercube_graph(3)) - ''' return GiacMethods['girth'](self,*args) @@ -6667,10 +6144,9 @@ cdef class GiacMethods_base: Help for gl_showaxes: gl_showaxes(Opt=Boolean) Option that shows or hides axes. - See also: 1/ switch_axes 2/ axes + See also: 1/ switch_axes 2/ axes Ex1: gl_showaxes=true;plot(sin(x)) - Ex2: gl_showaxes=false;plot(sin(x)) - + Ex2: gl_showaxes=false;plot(sin(x)) ''' return GiacMethods['gl_showaxes'](self,*args) @@ -6679,9 +6155,8 @@ cdef class GiacMethods_base: Help for grad: grad(Expr(Xpr),LstVar) Returns the gradient of the expression Xpr. - See also: 1/ hessian + See also: 1/ hessian Ex1:grad(2*x^2*y-x*z^3,[x,y,z]) - ''' return GiacMethods['grad'](self,*args) @@ -6690,10 +6165,9 @@ cdef class GiacMethods_base: Help for gramschmidt: gramschmidt(Basis(B),ScalarProd(Sp)) Returns an orthonormal basis of E with basis B for the scalar product Sp. - See also: 1/ + See also: 1/ Ex1:gramschmidt(-2) Ex2:gramschmidt([1,1+x],(p,q)->integrate(p*q,x,-1,1)) - ''' return GiacMethods['gramschmidt'](self,*args) @@ -6702,7 +6176,7 @@ cdef class GiacMethods_base: Help for graph: graph([Lst(V)],[Set(E)],[Mtrx(A)],[options]) Create an (un)directed (un)weighted graph from vertices V, edges E, and/or adjacency or weight matrix A. All parameters are optional. - See also: 1/ digraph 2/ trail + See also: 1/ digraph 2/ trail Ex1:graph(5) Ex2:graph([a,b,c]) Ex3:graph([1,2,3],%{[1,2],[2,3],[3,1]%}) @@ -6710,7 +6184,6 @@ cdef class GiacMethods_base: Ex5:graph([a,b,c],[[0,2,0],[2,0,3],[0,3,0]]) Ex6:graph("petersen") Ex7:graph([[0,1,1,0],[1,0,0,1],[1,0,0,0],[0,1,0,0]]) - ''' return GiacMethods['graph'](self,*args) @@ -6719,9 +6192,8 @@ cdef class GiacMethods_base: Help for graph_automorphisms: graph_automorphisms(Graph(G)) Returns the sequence of generators of Aut(G), the automorphism group of G. Each element is a permutation in the form of list of disjoint cycles. - See also: 1/ cycles2permu 2/ isomorphic_copy 3/ permute_vertices + See also: 1/ cycles2permu 2/ isomorphic_copy 3/ permute_vertices Ex1:graph_automorphisms(graph("petersen")) - ''' return GiacMethods['graph_automorphisms'](self,*args) @@ -6730,10 +6202,9 @@ cdef class GiacMethods_base: Help for graph_charpoly: graph_charpoly(Graph(G),[Var(x)]) Returns the value p(x) of the characteristic polynomial p of G. If x is omitted, a list of coefficients of p is returned. - See also: 1/ graph_spectrum 2/ charpoly + See also: 1/ graph_spectrum 2/ charpoly Ex1:graph_charpoly(graph(%{[1,2],[2,3]%})) Ex2:graph_charpoly(graph("shrikhande")) - ''' return GiacMethods['graph_charpoly'](self,*args) @@ -6742,9 +6213,8 @@ cdef class GiacMethods_base: Help for graph_complement: graph_complement(Graph(G)) Return the graph with the same vertex set as G, but whose edge (arc) set consists of the edges (arcs) not present in G. - See also: 1/ edges + See also: 1/ edges Ex1:graph_complement(cycle_graph(5)) - ''' return GiacMethods['graph_complement'](self,*args) @@ -6753,9 +6223,8 @@ cdef class GiacMethods_base: Help for graph_diameter: graph_diameter(Graph(G)) Returns the maximum distance between a pair of vertices in G or +infinity if G is disconnected. - See also: 1/ allpairs_distance 2/ dijkstra 3/ shortest_path 4/ vertex_distance + See also: 1/ allpairs_distance 2/ dijkstra 3/ shortest_path 4/ vertex_distance Ex1:graph_diameter(graph("petersen")) - ''' return GiacMethods['graph_diameter'](self,*args) @@ -6764,9 +6233,8 @@ cdef class GiacMethods_base: Help for graph_equal: graph_equal(Graph(G1),Graph(G2)) Returns true iff the input graphs G1 and G2 are equal, that is when the sets of vertices and edges of G1 and G2, as well as the orderings of vertices in both graphs, mutually coincide. If the graphs are weighted (they must both be (un)weighted and (un)directed), weights given to the same edge in two graphs must be equal. - See also: 1/ edges 2/ graph_vertices + See also: 1/ edges 2/ graph_vertices Ex1:graph_equal(graph([1,2,3],%{[1,2],[2,3],[3,1]%}),graph(trail(1,2,3,1))) - ''' return GiacMethods['graph_equal'](self,*args) @@ -6775,9 +6243,8 @@ cdef class GiacMethods_base: Help for graph_join: graph_join(Graph(G),Graph(H)) Returns the graph obtained by connecting every vertex from G with every vertex from H. The vertex labels in the resulting graph are strings of form "1:u" and "2:v" where u and v are vertices from G and H, respectively. - See also: 1/ disjoint_union 2/ graph_union + See also: 1/ disjoint_union 2/ graph_union Ex1:graph_join(edges(graph_join(cycle_graph(3),graph(2)))) - ''' return GiacMethods['graph_join'](self,*args) @@ -6786,9 +6253,8 @@ cdef class GiacMethods_base: Help for graph_power: graph_power(Graph(G),Intg(k)) Returns the k-th power of G, where two vertices are connected iff there exists a path of length at most k in the original graph. - See also: 1/ adjacency matrix 2/ graph_diameter 3/ shortest_path + See also: 1/ adjacency matrix 2/ graph_diameter 3/ shortest_path Ex1:graph_power(edges(graph_power(path_graph(5),3))) - ''' return GiacMethods['graph_power'](self,*args) @@ -6797,10 +6263,9 @@ cdef class GiacMethods_base: Help for graph_rank: graph_rank(Graph(G),[Lst(E)]) Returns the graph rank of G. If optional set E of edges is given, the rank of the spanning subgraph of G with edge set E is returned. - See also: 1/ connected_components 2/ number_of_vertices + See also: 1/ connected_components 2/ number_of_vertices Ex1:graph_rank(graph(%{[1,2],[3,4],[4,5]%})) Ex2:graph_rank(graph(%{[1,2],[3,4],[4,5]%}),[[1,2],[3,4]) - ''' return GiacMethods['graph_rank'](self,*args) @@ -6809,9 +6274,8 @@ cdef class GiacMethods_base: Help for graph_spectrum: graph_spectrum(Graph(G)) Returns the graph spectrum of G as a list of lists with two elements, each containing an eigenvalue and its multiplicity. - See also: 1/ graph_charpoly 2/ seidel_spectrum 3/ is_integer_graph + See also: 1/ graph_charpoly 2/ seidel_spectrum 3/ is_integer_graph Ex1:graph_spectrum(cycle_graph(5)) - ''' return GiacMethods['graph_spectrum'](self,*args) @@ -6820,9 +6284,8 @@ cdef class GiacMethods_base: Help for graph_union: graph_union(Seq(G1,G2,...)) Returns the union of the graphs G1, G2, ... The set of vertices of the resulting graph is the union of the sets of vertices of the input graphs and the set of edges of the resulting graph is the union of sets of edges of the input graphs. If the input graphs are weighted, the weight of any common edge is the sum of the weights of that edge in G1, G2, ... - See also: 1/ disjoint_union 2/ graph_join + See also: 1/ disjoint_union 2/ graph_join Ex1:graph_union(edges(graph_union(cycle_graph(4),path_graph(5)))) - ''' return GiacMethods['graph_union'](self,*args) @@ -6831,9 +6294,8 @@ cdef class GiacMethods_base: Help for graph_vertices: graph_vertices(Graph(G)) Return the list of vertices in G. - See also: 1/ add_vertex 2/ graph 3/ neighbors 4/ permute_vertices 5/ relabel_vertices + See also: 1/ add_vertex 2/ graph 3/ neighbors 4/ permute_vertices 5/ relabel_vertices Ex1:graph_vertices(graph(%{[a,c],[b,c],[a,b]%})) - ''' return GiacMethods['graph_vertices'](self,*args) @@ -6842,11 +6304,10 @@ cdef class GiacMethods_base: Help for greduce: greduce(Poly,LstPoly,LstVar,[order]) Returns the remainder of the division of a polynomial by a Groebner basis. - See also: 1/ gbasis + See also: 1/ gbasis Ex1:greduce(x*y-1,[x^2-y^2,2*x*y-y^2,y^3],[x,y]) Ex2:greduce(x1^2*x3^2,[x3^3-1,-x2^2-x2*x3-x3^2,x1+x2+x3],[x1,x2,x3],tdeg) Ex3:greduce(x1^2*x3^2-x2,[x3^3-1,-x2^2-x2*x3-x3^2,x1+x2+x3],[x1,x2,x3]) - ''' return GiacMethods['greduce'](self,*args) @@ -6855,9 +6316,8 @@ cdef class GiacMethods_base: Help for greedy_color: greedy_color(Graph(G),[Permu(p)]) Returns the list of vertex colors (positive integers) obtained by coloring vertices one at a time [in the order given by permutation p], assigning to it the smallest available color. - See also: 1/ is_vertex_colorable 2/ chromatic_number + See also: 1/ is_vertex_colorable 2/ chromatic_number Ex1:greedy_color(graph("petersen")) - ''' return GiacMethods['greedy_color'](self,*args) @@ -6866,9 +6326,8 @@ cdef class GiacMethods_base: Help for grid_graph: grid_graph(Intg(m),Intg(n),[triangle]) Returns a [triangular] grid graph on m*n vertices, where m,n>=2. - See also: 1/ torus_grid_graph + See also: 1/ torus_grid_graph Ex1:grid_graph(5,8) - ''' return GiacMethods['grid_graph'](self,*args) @@ -6877,9 +6336,8 @@ cdef class GiacMethods_base: Help for groupermu: groupermu(Permut(a),Permut(b)) Returns the group of permutations generated by a and b. - See also: 1/ + See also: 1/ Ex1:groupermu([1,2,0],[3,1,2,0]) - ''' return GiacMethods['groupermu'](self,*args) @@ -6888,10 +6346,9 @@ cdef class GiacMethods_base: Help for hadamard: hadamard(Mtrx,Mtrx) Hadamard bound of a matrix or element by element multiplication of 2 matrices. - See also: 1/ .* 2/ * + See also: 1/ .* 2/ * Ex1:hadamard([[1,2],[3,4]]) Ex2:hadamard([[1,2],[3,4]],[[3,4],[5,6]]) - ''' return GiacMethods['hadamard'](self,*args) @@ -6900,10 +6357,9 @@ cdef class GiacMethods_base: Help for half_cone: half_cone(Pnt(A),Vect(v),Real(t),[Real(h)]) Draws a half-cone with vertex A, direction v and with half_angle=t [and with altitude h]. - See also: 1/ cone 2/ cylinder + See also: 1/ cone 2/ cylinder Ex1:half_cone([0,0,0],[0,0,1],pi/6) Ex2:half_cone([0,0,0],[0,1,1],pi/6,-4) - ''' return GiacMethods['half_cone'](self,*args) @@ -6912,10 +6368,9 @@ cdef class GiacMethods_base: Help for half_line: half_line((Pnt or Cplx),(Pnt or Cplx)) half_line(A,B) draws the half-line AB with A as origin. - See also: 1/ line + See also: 1/ line Ex1:half_line(i,1+i) Ex2:half_line(point(i),point(1+i)) - ''' return GiacMethods['half_line'](self,*args) @@ -6927,7 +6382,6 @@ cdef class GiacMethods_base: Ex1:halftan(sin(x)) Ex2:halftan(cos(x)) Ex3:halftan(tan(x)) - ''' return GiacMethods['halftan'](self,*args) @@ -6936,9 +6390,8 @@ cdef class GiacMethods_base: Help for halftan_hyp2exp: halftan_hyp2exp(ExprTrig) Transforms the trigonometric functions in tan(x/2) and hyperbolic functions to exp. - See also: 1/ hyp2exp 2/ halftan + See also: 1/ hyp2exp 2/ halftan Ex1:halftan_hyp2exp(sin(x)+sinh(x)) - ''' return GiacMethods['halftan_hyp2exp'](self,*args) @@ -6947,9 +6400,8 @@ cdef class GiacMethods_base: Help for halt: halt(NULL) Puts a program in step-by-step debug mode. - See also: 1/ + See also: 1/ Ex1:halt() - ''' return GiacMethods['halt'](self,*args) @@ -6959,7 +6411,6 @@ cdef class GiacMethods_base: hamdist(Intg,Intg) Bitwise Hamming distance. Ex1:hamdist(0x12,0x38) - ''' return GiacMethods['hamdist'](self,*args) @@ -6968,9 +6419,8 @@ cdef class GiacMethods_base: Help for hamming_window: hamming_window(Lst,[Interval(n1..n2)]) Applies the Hamming windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ bartlett_hann_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ bartlett_hann_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(hamming_window(randvector(1000,0..1))) - ''' return GiacMethods['hamming_window'](self,*args) @@ -6979,9 +6429,8 @@ cdef class GiacMethods_base: Help for hann_poisson_window: hann_poisson_window(Lst,[Interval(n1..n2)]) Applies the Hann-Poisson windowing function with parameter a (by default a=1) to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ bartlett_hann_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ bartlett_hann_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(hann_poisson_window(randvector(1000,0..1),2)) - ''' return GiacMethods['hann_poisson_window'](self,*args) @@ -6990,9 +6439,8 @@ cdef class GiacMethods_base: Help for hann_window: hann_window(Lst,[Interval(n1..n2)]) Applies the Hann windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ bartlett_hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ bartlett_hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(hann_window(randvector(1000,0..1))) - ''' return GiacMethods['hann_window'](self,*args) @@ -7001,12 +6449,11 @@ cdef class GiacMethods_base: Help for harmonic_conjugate: harmonic_conjugate(Line or Pnt(A),Line or Pnt(B),Line or Pnt(C)) Returns the harmonic conjugate C with respect to A and B of 3 points or of 3 parallel or concurrent lines or the line of conjugates of a point with respect to 2 lines. - See also: 1/ is_harmonic 2/ harmonic_division + See also: 1/ is_harmonic 2/ harmonic_division Ex1:harmonic_conjugate(0,2,3/2) Ex2:harmonic_conjugate(0,1+i,2+2*i) Ex3:harmonic_conjugate(line(0,1+i),line(0,3+i),line(0,i)) Ex4:harmonic_conjugate(line(0,1+i),line(0,3+i),point(3/2+i)) - ''' return GiacMethods['harmonic_conjugate'](self,*args) @@ -7015,12 +6462,11 @@ cdef class GiacMethods_base: Help for harmonic_division: harmonic_division(Pnt or Line,Pnt or Line,Pnt or Line,Var) Returns 4 points (resp lines) and affects the last argument, such that the 4 points (resp lines) are in a harmonic division and assigns the fourth point to the variable name. - See also: 1/ harmonic_conjugate 2/ is_harmonic + See also: 1/ harmonic_conjugate 2/ is_harmonic Ex1:harmonic_division(0,2,3/2,D) Ex2:harmonic_division(0,1+i,2+2*i,D) Ex3:harmonic_division(line(i,0),line(i,1+i),line(i,3+2*i),D) Ex4:harmonic_division(line(0,1+i),line(0,3+i),line(0,i),D) - ''' return GiacMethods['harmonic_division'](self,*args) @@ -7029,10 +6475,9 @@ cdef class GiacMethods_base: Help for has: has(Expr,Var) Checks if a variable is in an expression. - See also: 1/ lname 2/ lvar + See also: 1/ lname 2/ lvar Ex1:has(x+y,x) Ex2:has(x+y,n) - ''' return GiacMethods['has'](self,*args) @@ -7041,10 +6486,9 @@ cdef class GiacMethods_base: Help for has_arc: has_arc(Graph(G),Edge(e)) Returns true iff the arc e=[i,j] is contained in digraph G or, if e={i,j} is a set, iff G has both edges [i,j] and [j,i]. - See also: 1/ edges 2/ has_edge + See also: 1/ edges 2/ has_edge Ex1:has_arc(digraph(trail(1,2,3,4,1)),[4,2]) Ex2:has_arc(digraph(trail(1,2,3,4,1)),%{4,2%}) - ''' return GiacMethods['has_arc'](self,*args) @@ -7053,9 +6497,8 @@ cdef class GiacMethods_base: Help for has_edge: has_edge(Graph(G),Edge(e)) Returns true iff the edge e=[i,j] is contained in undirected graph G. - See also: 1/ edges 2/ has_arc + See also: 1/ edges 2/ has_arc Ex1:has_edge(graph(trail(1,2,3,4,1)),[2,4]) - ''' return GiacMethods['has_edge'](self,*args) @@ -7064,7 +6507,7 @@ cdef class GiacMethods_base: Help for hasard: hasard(Intg(n) or Interval(p..n) or NULL,[Intg(b1) or Lst(L)],[Intg(b2)]) (hasard n)=a random integer (resp (hasard p,n)=a real or hasard(p..n)=a real function) with uniform distribution in 0..n-1 (resp in [p;n])(hasard= (hasard 0,1)=a random real in [0,1[) or hasard(n,b1,b2)=n integers between b1 and b2 or hasard(n,L)=n elements of L. If hasard has only one argument, () are not necessary (compatibility with turtle language). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ srand + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ srand Ex1: hasard 4 Ex2: hasard(4) Ex3:hasard(0,2) @@ -7072,7 +6515,6 @@ cdef class GiacMethods_base: Ex5: f:=hasard 0..2 Ex6:hasard(3,1,10) Ex7:hasard(3,["r","r","r","b","n"]) - ''' return GiacMethods['hasard'](self,*args) @@ -7081,11 +6523,10 @@ cdef class GiacMethods_base: Help for head: head(Vect or Seq or Str) Shows the first element of a vector or a sequence or a string. - See also: 1/ back 2/ tail 3/ mid 4/ left 5/ right + See also: 1/ back 2/ tail 3/ mid 4/ left 5/ right Ex1:head(1,2,3) Ex2:head([1,2,3]) Ex3:head("bonjour") - ''' return GiacMethods['head'](self,*args) @@ -7094,11 +6535,10 @@ cdef class GiacMethods_base: Help for heading: heading(NULL or Real) Returns the turtle cap in degrees or turns the turtle in the direction given by the argument. - See also: 1/ position 2/ initialise + See also: 1/ position 2/ initialise Ex1: cap Ex2:heading() Ex3:heading(cap 90) - ''' return GiacMethods['heading'](self,*args) @@ -7107,8 +6547,7 @@ cdef class GiacMethods_base: Help for heapify: heapify(List) Partial ordering of a list as a heap. - See also: 1/ heappush 2/ heappop - + See also: 1/ heappush 2/ heappop ''' return GiacMethods['heapify'](self,*args) @@ -7117,8 +6556,7 @@ cdef class GiacMethods_base: Help for heappop: heappop(List) Removes and returns the root node of a heap. - See also: 1/ heapify 2/ heappush - + See also: 1/ heapify 2/ heappush ''' return GiacMethods['heappop'](self,*args) @@ -7127,8 +6565,7 @@ cdef class GiacMethods_base: Help for heappush: heappush(List,Object) Adds an object in a heap. - See also: 1/ heapify 2/ heappop - + See also: 1/ heapify 2/ heappop ''' return GiacMethods['heappush'](self,*args) @@ -7137,10 +6574,9 @@ cdef class GiacMethods_base: Help for hermite: hermite(Intg(n)||Matr(A)) Returns the Hermite polynomial of degree n or the Hermite normal form for a matrix with polynomial coefficients (I,U such that I*A=U). - See also: 1/ legendre 2/ laguerre 3/ smith 4/ ihermite 5/ ismith + See also: 1/ legendre 2/ laguerre 3/ smith 4/ ihermite 5/ ismith Ex1:hermite(3) Ex2: n:=5; a:=ranm(n,n) % 17; l,u:=hermite(x-a);normal(l*(x-a)-u); - ''' return GiacMethods['hermite'](self,*args) @@ -7149,13 +6585,12 @@ cdef class GiacMethods_base: Help for hessenberg: hessenberg(Mtrx(A),[Intg(n)]) Matrix reduction to Hessenberg form. Returns [P,B] such that B=inv(P)*A*P, by default n=0 the result is exact else the result is numeric. For n=-1 B is triangular, n=-2 P is orthogonal and if n is prime the result is mod n. - See also: 1/ SCHUR + See also: 1/ SCHUR Ex1:hessenberg([[1,2,3],[4,5,6],[7,8,1]]) Ex2:hessenberg([[1,2,3,4],[4,5,6,7],[7,8,9,0],[0,1,2,3]]) Ex3:hessenberg([[1,2,3],[4,5,6],[7,8,1]],-1) Ex4:hessenberg([[1,2,3],[4,5,6],[7,8,1]],-2) Ex5:hessenberg([[1,2,3],[4,5,6],[7,8,1]],3) - ''' return GiacMethods['hessenberg'](self,*args) @@ -7164,9 +6599,8 @@ cdef class GiacMethods_base: Help for hessian: hessian(Expr(Xpr),LstVar) Returns the hessian of the expression Xpr. - See also: 1/ grad + See also: 1/ grad Ex1:hessian(2*x^2*y-x*z,[x,y,z]) - ''' return GiacMethods['hessian'](self,*args) @@ -7175,9 +6609,8 @@ cdef class GiacMethods_base: Help for heugcd: heugcd(Poly,Poly) GCD of 2 polynomials, with the algorithm called heuristic pgcd. - See also: 1/ gcd 2/ modgcd 3/ ezgcd 4/ psrgcd + See also: 1/ gcd 2/ modgcd 3/ ezgcd 4/ psrgcd Ex1:heugcd(x^4-1,(x-1)^2) - ''' return GiacMethods['heugcd'](self,*args) @@ -7186,12 +6619,11 @@ cdef class GiacMethods_base: Help for hexagon: hexagon(Pnt(A)||Cplx,Pnt(B)||Cplx,[Pnt(P)],[Var(C)],[Var(D)],[Var(E)],[Var(F)]) Returns and draws the hexagon of side AB (ABCDEF is direct) (in the plane ABP). - See also: 1/ isopolygon 2/ polygon + See also: 1/ isopolygon 2/ polygon Ex1:hexagon(i,1+i) Ex2:hexagon(i,1+i,C,D,E,F) Ex3:hexagon(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:hexagon(point(0,0,0),point(3,3,3),point(0,0,3),C,D,E,F) - ''' return GiacMethods['hexagon'](self,*args) @@ -7200,9 +6632,8 @@ cdef class GiacMethods_base: Help for highlight_edges: highlight_edges(Graph(G),Edge(e)||Lst(E),[Color(c)||Lst(C)]) Changes color of edge e resp. colors of edges in E of the input graph V to c resp C (by default red) and returns the modified copy of G. - See also: 1/ highlight_vertex 2/ highlight_subgraph 3/ highlight_trail + See also: 1/ highlight_vertex 2/ highlight_subgraph 3/ highlight_trail Ex1: draw_graph(highlight_edges(cycle_graph(3),[1,2])) - ''' return GiacMethods['highlight_edges'](self,*args) @@ -7211,9 +6642,8 @@ cdef class GiacMethods_base: Help for highlight_subgraph: highlight_subgraph(Graph(G),Graph(S)||Lst(S1,S2,..),Seq(c1,c2)) Changes colors of edges and vertices from the sugbraph S or list of subgraphs S1, S2, ... of G to c1 and c2, respectively (red and green by default), and returns the modified copy of G. - See also: 1/ highlight_edges 2/ highlight_vertex 3/ highlight_trail + See also: 1/ highlight_edges 2/ highlight_vertex 3/ highlight_trail Ex1: draw_graph(highlight_subgraph(cycle_graph(5),path_graph(3))) - ''' return GiacMethods['highlight_subgraph'](self,*args) @@ -7222,9 +6652,8 @@ cdef class GiacMethods_base: Help for highlight_trail: highlight_trail(Graph(G),Trail(t)||Lst(T),[Color(c)||Lst(C)]) Changes colors of edges in G which lie along the trail t resp. trails in T to c resp. C (by default red) and returns the modified copy of G. - See also: 1/ highlight_edges 2/ highlight_subgraph 3/ highlight_vertex + See also: 1/ highlight_edges 2/ highlight_subgraph 3/ highlight_vertex Ex1: draw_graph(highlight_trail(cycle_graph(5),trail(1,2,3),green) - ''' return GiacMethods['highlight_trail'](self,*args) @@ -7233,9 +6662,8 @@ cdef class GiacMethods_base: Help for highlight_vertex: highlight_vertex(Graph(G),Vrtx(v)||Lst(V),[Color(c)||Lst(C)]) Changes the color of vertex v resp. colors of vertices from V in G to c resp. C (green by default) and returns the modified copy of G. - See also: 1/ highlight_edges 2/ highlight_subgraph 3/ highlight_trail + See also: 1/ highlight_edges 2/ highlight_subgraph 3/ highlight_trail Ex1: draw_graph(highlight_vertex(cycle_graph(3),1)) - ''' return GiacMethods['highlight_vertex'](self,*args) @@ -7244,9 +6672,8 @@ cdef class GiacMethods_base: Help for highpass: highpass(Lst(s),Real(c),[Intg(samplerate)]) Returns the result of applying a simple first-order highpass RC filter with cutoff frequency c (the default samplerate is 44100) to the given signal s. - See also: 1/ lowpass 2/ moving_average + See also: 1/ lowpass 2/ moving_average Ex1: f:=unapply(periodic(sign(x),x,-1/880,1/880),x):;s:=createwav(apply(f,soundsec(1))):;playsnd(highpass(s,5000)) - ''' return GiacMethods['highpass'](self,*args) @@ -7255,9 +6682,8 @@ cdef class GiacMethods_base: Help for hilbert: hilbert(Intg(n)) Returns the order n Hilbert matrix : Hjk=1/(j+k+1) j,k=1..n. - See also: 1/ + See also: 1/ Ex1:hilbert(4) - ''' return GiacMethods['hilbert'](self,*args) @@ -7266,7 +6692,7 @@ cdef class GiacMethods_base: Help for histogram: histogram(Lst(data),[Lst(eff) || Intg(nc) || Real(classmin)],[Real(classsize)]) Draws the histogram of data, optional arguments are eff (number of data for each data element) or nc the number of classes or the classes minimum and size. - See also: 1/ cumulated_frequencies 2/ classes 3/ bar_plot 4/ frequencies + See also: 1/ cumulated_frequencies 2/ classes 3/ bar_plot 4/ frequencies Ex1:histogram([1,2,1,1,2,1,2,4,3,3]) Ex2:histogram([1,2,1,1,2,1,2,4,3,3],0.5,1) Ex3:histogram(seq(rand(1000),k,0,100),0,100) @@ -7275,7 +6701,6 @@ cdef class GiacMethods_base: Ex6:histogram([[1.5..1.65,50],[1.65..1.7,20],[1.7..1.8,30]]) Ex7:histogram(seq(rand(1000),k,0,100),0,100) Ex8:histogram(seq(rand(1000),k,0,100),10) - ''' return GiacMethods['histogram'](self,*args) @@ -7284,11 +6709,10 @@ cdef class GiacMethods_base: Help for hold: hold(Expr) Returns its argument unevaluated (and also a:=quote(a) purges a). - See also: 1/ + See also: 1/ Ex1:hold(1+2) Ex2:hold(1/x+1/(x-1)) Ex3:hold((x+1)*(x-1)) - ''' return GiacMethods['hold'](self,*args) @@ -7299,7 +6723,6 @@ cdef class GiacMethods_base: Make P homogeneous by adding a variable (by default t) Ex1:homogeneize(x^2-1) Ex2:homogeneize(x^2-y,z) - ''' return GiacMethods['homogeneize'](self,*args) @@ -7308,12 +6731,11 @@ cdef class GiacMethods_base: Help for homothety: homothety(Pnt(C),Real(k),Pnt(A)) homothety(C,k,A)=point A1 such as vect(C,A1)=k*vect(C,A) i.e in 2d it is the similarity with center C, coeff abs(k) and angle arg(k). - See also: 1/ similarity 2/ inversion + See also: 1/ similarity 2/ inversion Ex1:homothety(1+i,1/3,i) Ex2:homothety(point(1,1,1),1/3,point(0,1,0)) Ex3: h:=homothety(1+i,1/3);h(i) Ex4: h:=homothety(point(1,1,1),1/3);h(point(0,1,0)) - ''' return GiacMethods['homothety'](self,*args) @@ -7322,12 +6744,11 @@ cdef class GiacMethods_base: Help for horner: horner(Poly(P),Real(a)) Returns the value of P(a) calculated with Horner's method. With horner(list_alpha_i,list_x_i,x), evals an interpolation polynomial from the divided differences of x. - See also: 1/ convert 2/ base 3/ revlist + See also: 1/ convert 2/ base 3/ revlist Ex1:horner(x^2+1,2) Ex2:horner([1,0,1],2) Ex3:horner(x^2+y*x+y^3-1,2,y) Ex4: X:=[0.0,1.0,2.0]; A:=lagrange(X,exp,lagrange); horner(A,X,1.5); - ''' return GiacMethods['horner'](self,*args) @@ -7336,14 +6757,13 @@ cdef class GiacMethods_base: Help for hybrid_solver: hybrid_solver(Opt) Argument for fsolve giving the method for solving a system of numerical equations. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],dnewton_solver) Ex2: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrid_solver) Ex3: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrids_solver) Ex4: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridj_solver) Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) - ''' return GiacMethods['hybrid_solver'](self,*args) @@ -7352,14 +6772,13 @@ cdef class GiacMethods_base: Help for hybridj_solver: hybridj_solver(Opt) Argument for fsolve giving the method for solving a system of numerical equations. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],dnewton_solver) Ex2: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrid_solver) Ex3: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrids_solver) Ex4: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridj_solver) Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) - ''' return GiacMethods['hybridj_solver'](self,*args) @@ -7368,14 +6787,13 @@ cdef class GiacMethods_base: Help for hybrids_solver: hybrids_solver(Opt) Argument for fsolve giving the method for solving a system of numerical equations. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],dnewton_solver) Ex2: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrid_solver) Ex3: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrids_solver) Ex4: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridj_solver) Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) - ''' return GiacMethods['hybrids_solver'](self,*args) @@ -7384,14 +6802,13 @@ cdef class GiacMethods_base: Help for hybridsj_solver: hybridsj_solver(Opt) Argument for fsolve giving the method for solving a system of numerical equations. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],dnewton_solver) Ex2: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrid_solver) Ex3: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrids_solver) Ex4: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridj_solver) Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) - ''' return GiacMethods['hybridsj_solver'](self,*args) @@ -7400,9 +6817,8 @@ cdef class GiacMethods_base: Help for hyp2exp: hyp2exp(ExprHyperb) Transforms the hyperbolic functions to the exponential function. - See also: 1/ halftan_hyp2exp + See also: 1/ halftan_hyp2exp Ex1:hyp2exp(cosh(x)) - ''' return GiacMethods['hyp2exp'](self,*args) @@ -7411,12 +6827,11 @@ cdef class GiacMethods_base: Help for hyperbola: hyperbola(Focus(F1),Focus(F2),(Pnt(M) or Real(a))) hyperbola(F1,F2,M)=hyperbola with foci F1,F2 through M or (|MF1-MF2|=2*a geo2d) and hyperbola(p(x,y)) draws the conic if deg(p)=2. - See also: 1/ ellipse 2/ parabola + See also: 1/ ellipse 2/ parabola Ex1:hyperbola(-1,1,point(1+i)) Ex2:hyperbola(-1,1,sqrt(5)-1) Ex3:hyperbola(point(-1,0,0),point(1,0,0),point(1,1,1)) Ex4:hyperbola(x^2-y^2+y+2) - ''' return GiacMethods['hyperbola'](self,*args) @@ -7425,9 +6840,8 @@ cdef class GiacMethods_base: Help for hypercube_graph: hypercube_graph(Intg(n)) Constructs and returns the hypercube graph in dimension n (with 2^n vertices). - See also: 1/ graph + See also: 1/ graph Ex1:hypercube_graph(3) - ''' return GiacMethods['hypercube_graph'](self,*args) @@ -7436,11 +6850,10 @@ cdef class GiacMethods_base: Help for iPart: iPart(Real||LstReal) Returns the argument without its fractional part (type=DOM_FLOAT). - See also: 1/ fPart 2/ floor 3/ trunc + See also: 1/ fPart 2/ floor 3/ trunc Ex1:iPart(4.3) Ex2:iPart(sqrt(2)) Ex3:iPart(4.3,sqrt(2)) - ''' return GiacMethods['iPart'](self,*args) @@ -7449,11 +6862,10 @@ cdef class GiacMethods_base: Help for iabcuv: iabcuv(Intg(a),Intg(b),Intg(c)) Returns [u,v] such that au+bv=c for 3 integers a,b,c. - See also: 1/ iegcd 2/ abcuv + See also: 1/ iegcd 2/ abcuv Ex1:iabcuv(21,28,7) Ex2:iabcuv(21,28,14) Ex3:iabcuv(21,28,1) - ''' return GiacMethods['iabcuv'](self,*args) @@ -7462,9 +6874,8 @@ cdef class GiacMethods_base: Help for ibasis: ibasis(Lst(Vect,..,Vect),Lst(Vect,..,Vect)) Basis of the intersection of two vector spaces. - See also: 1/ basis + See also: 1/ basis Ex1:ibasis([[1,0,0],[0,1,0]],[[1,1,1],[0,0,1]]) - ''' return GiacMethods['ibasis'](self,*args) @@ -7473,13 +6884,12 @@ cdef class GiacMethods_base: Help for ibpdv: ibpdv(Expr(f(x)),Expr(v(x)),[Var(x)],[Real(a)],[Real(b)]) Integration by parts of f(x)=u(x)*v'(x) with f(x) as 1st argument and v(x) (or 0) as 2nd argument. You can specify a variable of integration and also calculate the integral (bounds a and b). - See also: 1/ ibpu 2/ int + See also: 1/ ibpu 2/ int Ex1:ibpdv(ln(x),x) Ex2:ibpdv(ln(x),x,x,1,3) Ex3:ibpdv(x*ln(x),x^2/2) Ex4:ibpdv([x*ln(x),-1],0) Ex5:ibpdv(ibpdv(ln(x),x,x,2,3),0,x,2,3) - ''' return GiacMethods['ibpdv'](self,*args) @@ -7488,13 +6898,12 @@ cdef class GiacMethods_base: Help for ibpu: ibpu(Expr(f(x)),Expr(u(x)),[Var(x)],[Real(a)],[Real(b)]) Integration by parts of f(x)=u(x)*v'(x) with f(x) as 1st argument and u(x) (or 0) as 2nd argument. You can specify a variable of integration and also calculate the integral (bounds a and b). - See also: 1/ ibpdv 2/ int + See also: 1/ ibpdv 2/ int Ex1:ibpu(ln(x),ln(x)) Ex2:ibpu(ln(x),ln(x),x,1,3) Ex3:ibpu(x*ln(x),ln(x)) Ex4:ibpu([x*ln(x),-1],0) Ex5:ibpu(ibpu(ln(x),ln(x),x,2,3),0,x,2,3) - ''' return GiacMethods['ibpu'](self,*args) @@ -7503,10 +6912,9 @@ cdef class GiacMethods_base: Help for icdf: icdf(Func,FuncParams) Inverse cumulative distribution function. - See also: 1/ cdf 2/ binomial_icdf 3/ normald_icdf + See also: 1/ cdf 2/ binomial_icdf 3/ normald_icdf Ex1:icdf(binomial,10,0.5,0.6) Ex2:icdf(normald,0.0,1.0,0.975) - ''' return GiacMethods['icdf'](self,*args) @@ -7515,12 +6923,11 @@ cdef class GiacMethods_base: Help for ichinrem: ichinrem(LstIntg(a,p),LstIntg(b,q)) Chinese remainders for integers. - See also: 1/ gcd 2/ fracmod 3/ chinrem 4/ chrem + See also: 1/ gcd 2/ fracmod 3/ chinrem 4/ chrem Ex1:ichinrem([2,7],[3,5]) Ex2:ichinrem([2%7,3%5]) Ex3:ichinrem([2%7,3%5,1%9]) Ex4:ichinrem([(x+1)%2,(x+2)%3,(3*x-1)%5]) - ''' return GiacMethods['ichinrem'](self,*args) @@ -7529,12 +6936,11 @@ cdef class GiacMethods_base: Help for ichrem: ichrem(LstIntg(a,p),LstIntg(b,q)) Chinese remainders for integers. - See also: 1/ gcd 2/ fracmod 3/ chinrem 4/ chrem + See also: 1/ gcd 2/ fracmod 3/ chinrem 4/ chrem Ex1:ichrem([2,7],[3,5]) Ex2:ichrem([2%7,3%5]) Ex3:ichrem([2%7,3%5,1%9]) Ex4:ichrem([(x+1)%2,(x+2)%3,(3*x-1)%5]) - ''' return GiacMethods['ichrem'](self,*args) @@ -7543,10 +6949,9 @@ cdef class GiacMethods_base: Help for icomp: icomp(Intg(n),Intg(k),[zeros=true||false]) Returns the list of compositions of n into k parts. - See also: 1/ sum + See also: 1/ sum Ex1:icomp(4,2) Ex2:icomp(6,3,zeros=false) - ''' return GiacMethods['icomp'](self,*args) @@ -7555,10 +6960,9 @@ cdef class GiacMethods_base: Help for icontent: icontent(Poly,[Var]) GCD of the integer coefficients of a polynomial. - See also: 1/ + See also: 1/ Ex1:icontent(24x^3+6x^2-12x+18) Ex2:icontent(24t^3+6t^2-12t+18,t) - ''' return GiacMethods['icontent'](self,*args) @@ -7567,10 +6971,9 @@ cdef class GiacMethods_base: Help for icosahedron: icosahedron(Pnt(A),Pnt(B),Pnt(C)) Draws an icosahedron with center A, vertex B and such that the plane ABC contains one vertex among the 5 nearest vertices from B. - See also: 1/ octahedron 2/ dodecahedron 3/ cube 4/ tetrahedron + See also: 1/ octahedron 2/ dodecahedron 3/ cube 4/ tetrahedron Ex1:icosahedron([0,0,0],[sqrt(5),0,0],[1,2,0]) Ex2:icosahedron(evalf([0,0,0],[3,2,4],[1,1,0])) - ''' return GiacMethods['icosahedron'](self,*args) @@ -7579,9 +6982,8 @@ cdef class GiacMethods_base: Help for id: id(Seq) The name of the identity function (ℝ^n -> ℝ^n). - See also: 1/ sq 2/ sqrt + See also: 1/ sq 2/ sqrt Ex1:id(1,2,3) - ''' return GiacMethods['id'](self,*args) @@ -7590,10 +6992,9 @@ cdef class GiacMethods_base: Help for identity: identity(Intg(n)) Returns the identity matrix of specified dimension n. - See also: 1/ ranm + See also: 1/ ranm Ex1:identity(3) Ex2:identity(5) - ''' return GiacMethods['identity'](self,*args) @@ -7602,10 +7003,9 @@ cdef class GiacMethods_base: Help for idivis: idivis(Intg(a) or LstIntg) Returns the list of divisors of an integer. - See also: 1/ divis 2/ ifactors + See also: 1/ divis 2/ ifactors Ex1:idivis(36) Ex2:idivis([36,49]) - ''' return GiacMethods['idivis'](self,*args) @@ -7614,10 +7014,9 @@ cdef class GiacMethods_base: Help for idn: idn(Intg(n)) Returns the identity matrix of specified dimension n. - See also: 1/ ranm + See also: 1/ ranm Ex1:idn(3) Ex2:idn(5) - ''' return GiacMethods['idn'](self,*args) @@ -7626,11 +7025,10 @@ cdef class GiacMethods_base: Help for iegcd: iegcd(Intg,Intg) Extended greatest common divisor of 2 integers. - See also: 1/ gcd 2/ iabcuv 3/ egcd + See also: 1/ gcd 2/ iabcuv 3/ egcd Ex1:iegcd(45,75) Ex2:iegcd(21,28) Ex3:iegcd(30,49) - ''' return GiacMethods['iegcd'](self,*args) @@ -7639,10 +7037,9 @@ cdef class GiacMethods_base: Help for ifactor: ifactor(Intg(a)) Factorization of an integer into prime factors. - See also: 1/ factor 2/ ecm_factor + See also: 1/ factor 2/ ecm_factor Ex1:ifactor(50) Ex2:ifactor(123456789) - ''' return GiacMethods['ifactor'](self,*args) @@ -7651,10 +7048,9 @@ cdef class GiacMethods_base: Help for ifactors: ifactors(Intg(a) or LstIntg) Returns the list of prime factors of an integer (each factor is followed by its multiplicity). - See also: 1/ ifactor 2/ factors + See also: 1/ ifactor 2/ factors Ex1:ifactors(36) Ex2:ifactors([36,52]) - ''' return GiacMethods['ifactors'](self,*args) @@ -7663,7 +7059,7 @@ cdef class GiacMethods_base: Help for ifourier: ifourier(Expr(F(s)),[Var(s),[Var(x)]]) Returns the inverse Fourier transform f(x) of F(s). - See also: 1/ fourier 2/ fourier_cn 3/ ifft + See also: 1/ fourier 2/ fourier_cn 3/ ifft Ex1:ifourier(2*pi*(Dirac(s)-sign(s)*sin(s)),s,x) Ex2:ifourier(-2/(s^2-1),s,x) Ex3:ifourier(pi/(exp(pi*s/4)+exp(-pi*s/4)),s,x) @@ -7671,7 +7067,6 @@ cdef class GiacMethods_base: Ex5:ifourier(pi*ugamma(0,4*abs(s)),s,x) Ex6:ifourier(fourier(exp(-abs(x)),x,s)^2,s,x) Ex7:ifourier(sinc(s),s,x) - ''' return GiacMethods['ifourier'](self,*args) @@ -7680,11 +7075,10 @@ cdef class GiacMethods_base: Help for igamma: igamma(Real(a),Real(x),[1]) Calculates of gamma at a point (a,x). If a and x>0, igamma(a,x)=int(e^{-t}*t^{a-1},t=0..x), (igamma(a,x,1)=igamma(a,x)/Gamma(a)). - See also: 1/ Psi 2/ Beta 3/ Gamma 3/ ugamma + See also: 1/ Psi 2/ Beta 3/ Gamma 3/ ugamma Ex1:igamma(5.0,2.0) Ex2:igamma(-5.1,2.1) Ex3:igamma(5.0,2.0,1) - ''' return GiacMethods['igamma'](self,*args) @@ -7693,13 +7087,12 @@ cdef class GiacMethods_base: Help for igcd: igcd((Intg(a) or Poly),(Intg(b) or Poly)) Returns the greatest common divisor of 2 polynomials of several variables or of 2 integers or of 2 rationals. - See also: 1/ lcm 2/ euler 2/ modgcd 3/ ezgcd 4/ psrgcd 5/ heugcd 6/ Gcd + See also: 1/ lcm 2/ euler 2/ modgcd 3/ ezgcd 4/ psrgcd 5/ heugcd 6/ Gcd Ex1:igcd(45,75) Ex2:igcd(15/7,50/9) Ex3:igcd(x^2-2*x+1,x^3-1) Ex4:igcd(t^2-2*t+1,t^2+t-2) Ex5:igcd((x^2-1)*(y^2-1)*z^2,x^3*y^3*z+(-(y^3))*z+x^3*z-z) - ''' return GiacMethods['igcd'](self,*args) @@ -7708,11 +7101,10 @@ cdef class GiacMethods_base: Help for igcdex: igcdex(Intg,Intg) Extended greatest common divisor of 2 integers. - See also: 1/ gcd 2/ iabcuv 3/ egcd + See also: 1/ gcd 2/ iabcuv 3/ egcd Ex1:igcdex(45,75) Ex2:igcdex(21,28) Ex3:igcdex(30,49) - ''' return GiacMethods['igcdex'](self,*args) @@ -7721,10 +7113,9 @@ cdef class GiacMethods_base: Help for ihermite: ihermite(Mtrx(A)) Hermite normal form of a matrix with coefficients in ℤ : returns L,U such that L is invertible in ℤ, U is upper triangular and U=L*A. - See also: 1/ ismith + See also: 1/ ismith Ex1:ihermite([[9,-36,30], [-36,192,-180], [30,-180,180]]) Ex2:ihermite([[1,2,3],[4,5,6],[7,8,9]]) - ''' return GiacMethods['ihermite'](self,*args) @@ -7733,11 +7124,10 @@ cdef class GiacMethods_base: Help for ilaplace: ilaplace(Expr,[Var],[IlapVar]) Inverse Laplace transform of a rational fraction. - See also: 1/ laplace 2/ ztrans 3/ invztrans 4/ Heaviside + See also: 1/ laplace 2/ ztrans 3/ invztrans 4/ Heaviside Ex1:ilaplace(1/(x^2+1)^2) Ex2:ilaplace(s/(s^4-1),s,x) Ex3:ilaplace(exp(-s)/s,s,x) - ''' return GiacMethods['ilaplace'](self,*args) @@ -7746,11 +7136,10 @@ cdef class GiacMethods_base: Help for im: im(Cplx) Returns the imaginary part of a complex number. - See also: 1/ re 2/ conj + See also: 1/ re 2/ conj Ex1:im(1+2*i) Ex2:im((1+2*i)^2) Ex3:im([1+2*i,(1+2*i)^2]) - ''' return GiacMethods['im'](self,*args) @@ -7759,11 +7148,10 @@ cdef class GiacMethods_base: Help for imag: imag(Cplx) Returns the imaginary part of a complex number. - See also: 1/ re 2/ conj + See also: 1/ re 2/ conj Ex1:imag(1+2*i) Ex2:imag((1+2*i)^2) Ex3:imag([1+2*i,(1+2*i)^2]) - ''' return GiacMethods['imag'](self,*args) @@ -7772,10 +7160,9 @@ cdef class GiacMethods_base: Help for image: image(Mtrx(M)) Image of a linear map with matrix M. - See also: 1/ ker 2/ rref + See also: 1/ ker 2/ rref Ex1:image([[1,2],[3,6]]) Ex2:image([[1,2,3],[1,3,6],[2,5,9]]) - ''' return GiacMethods['image'](self,*args) @@ -7784,7 +7171,7 @@ cdef class GiacMethods_base: Help for implicitdiff: implicitdiff(constr,[depvars],y,diffvars) Implicit differentiation. - See also: 1/ diff + See also: 1/ diff Ex1:implicitdiff(x^2*y+y^2=1,y,x) Ex2:implicitdiff(R=P*V/T,P,T) Ex3:implicitdiff([x^2+y=z,x+y*z=1],[y(x),z(x)],y,x) @@ -7803,7 +7190,6 @@ cdef class GiacMethods_base: Ex16:implicitdiff(x*y*z,-2x^3+15x^2*y+11y^3-24y=0,[x,z,y],order=1) Ex17:implicitdiff(x*y*z,-2x^3+15x^2*y+11y^3-24y=0,[x,z,y],order=2,[1,-1,0]) Ex18: pd:=implicitdiff(x*y*z,-2x^3+15x^2*y+11y^3-24y=0,[x,z,y],order=4,[0,z,0]);pd[4,0,0] - ''' return GiacMethods['implicitdiff'](self,*args) @@ -7812,7 +7198,7 @@ cdef class GiacMethods_base: Help for implicitplot: implicitplot(Expr,Var1,Var2) plotimplicit(f(x,y),x,y) or plotimplicit(f(x,y),[x,y]) draws graph of f(x,y)=0. - See also: 1/ plotcontour 2/ unfactored 3/ plotinequation + See also: 1/ plotcontour 2/ unfactored 3/ plotinequation Ex1:implicitplot(x^2+y^2-1,x,y) Ex2:implicitplot(x^4+y^4=x^2-y^2) Ex3:implicitplot(x^2+y^2-1,x,y,unfactored) @@ -7822,7 +7208,6 @@ cdef class GiacMethods_base: Ex7:implicitplot(y^3=x^3-x^2,[x,y],xstep=0.1,ystep=0.1) Ex8:implicitplot((x+5)^2+(y+4)^2-1,x=-6..-4,y=-5..-3) Ex9:implicitplot((x+5)^2+(y+4)^2-1,[x=-6..-4,y=-5..-3]) - ''' return GiacMethods['implicitplot'](self,*args) @@ -7832,7 +7217,6 @@ cdef class GiacMethods_base: import_graph(Str("path/to/graphname[.dot]")) Returns the graph constructed from instructions in the file 'path/to/graphname.dot' (in dot format), or "undef" on failure. Ex1:import_graph("K5.dot") - ''' return GiacMethods['import_graph'](self,*args) @@ -7841,10 +7225,9 @@ cdef class GiacMethods_base: Help for inString: inString(Str(l),Elem(e)) Tests if e is in the string l (returns -1 or k if l[k]=e). - See also: 1/ contains + See also: 1/ contains Ex1:inString("abcd","b") Ex2:inString("abcd","e") - ''' return GiacMethods['inString'](self,*args) @@ -7853,10 +7236,9 @@ cdef class GiacMethods_base: Help for in_ideal: in_ideal(Poly,Lst,LstVar,[order]) Checks whether a polynomial or list of polynomials belongs to an ideal given by a Grobner basis (2nd argument) with respect to a variable list. - See also: 1/ gbasis 2/ greduce + See also: 1/ gbasis 2/ greduce Ex1:in_ideal((x+y)^2,[y^2,x^2+2*x*y],[x,y]) Ex2:in_ideal(x+y,[y^2,x^2+2*x*y],[x,y]) - ''' return GiacMethods['in_ideal'](self,*args) @@ -7865,9 +7247,8 @@ cdef class GiacMethods_base: Help for incidence_matrix: incidence_matrix(Graph(G)) Returns the incidence matrix of G whose rows are indexed by the vertices and columns by the edges (in order defined by the command 'edges'). - See also: 1/ incident_edges + See also: 1/ incident_edges Ex1:incidence_matrix(graph("tetrahedron")) - ''' return GiacMethods['incidence_matrix'](self,*args) @@ -7876,9 +7257,8 @@ cdef class GiacMethods_base: Help for incident_edges: incident_edges(Graph(G),Vrtx(v)) Returns the list of all edges incident to the vertex v of G (or to the vertices in the list v). - See also: 1/ adjacency_matrix 2/ vertex_degree 3/ incidence_matrix 4/ neighbors + See also: 1/ adjacency_matrix 2/ vertex_degree 3/ incidence_matrix 4/ neighbors Ex1:incident_edges(cycle_graph(8),[1,5,7]) - ''' return GiacMethods['incident_edges'](self,*args) @@ -7887,9 +7267,8 @@ cdef class GiacMethods_base: Help for incircle: incircle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) incircle(A,B,C) draws the incircle of the triangle ABC. - See also: 1/ excircle 2/ circumcircle + See also: 1/ excircle 2/ circumcircle Ex1:incircle(0,1,1+i) - ''' return GiacMethods['incircle'](self,*args) @@ -7898,10 +7277,9 @@ cdef class GiacMethods_base: Help for increasing_power: increasing_power(:=Intg(0 or 1)) Pseudo-variable to control the display of polynomials. - See also: 1/ cas_setup + See also: 1/ cas_setup Ex1: increasing_power:=1 Ex2: increasing_power:=0 - ''' return GiacMethods['increasing_power'](self,*args) @@ -7910,9 +7288,8 @@ cdef class GiacMethods_base: Help for independence_number: independence_number(Graph(G)) Returns the independence number of G. - See also: 1/ clique_number 2/ graph_complement 3/ maximum_clique 4/ maximum_independent_set + See also: 1/ clique_number 2/ graph_complement 3/ maximum_clique 4/ maximum_independent_set Ex1:independence_number(complete_graph(3,4)) - ''' return GiacMethods['independence_number'](self,*args) @@ -7921,9 +7298,8 @@ cdef class GiacMethods_base: Help for indets: indets(Expr) List of variables in the expression. - See also: 1/ has 2/ lvar + See also: 1/ has 2/ lvar Ex1:indets(exp(x)*2*sin(y)) - ''' return GiacMethods['indets'](self,*args) @@ -7932,12 +7308,11 @@ cdef class GiacMethods_base: Help for index: index(Vect,Expr) Index of the first position of an object in a list, a string or a set or returns an error message. - See also: 1/ find 2/ member + See also: 1/ find 2/ member Ex1:index([3,x,1,2,1,3],1) Ex2:index([0,1,3,2,4,2,5],2) Ex3:index(%{4,3,1,2%},1) Ex4:index("abracadabrant","c") - ''' return GiacMethods['index'](self,*args) @@ -7946,9 +7321,8 @@ cdef class GiacMethods_base: Help for induced_subgraph: induced_subgraph(Graph(G),Lst(V)) Returns the subgraph of G induced by the vertices in list V. - See also: 1/ subgraph + See also: 1/ subgraph Ex1:induced_subgraph(cycle_graph(6),[1,2,6]) - ''' return GiacMethods['induced_subgraph'](self,*args) @@ -7957,12 +7331,11 @@ cdef class GiacMethods_base: Help for inequationplot: inequationplot(Expr,[x=xrange,y=yrange],[xstep],[ystep]) Shows the graph of the solutions of inequalities with 2 variables. - See also: 1/ plotfunc 2/ plotcontour 3/ plotdensity 4/ plotimplicit + See also: 1/ plotfunc 2/ plotcontour 3/ plotdensity 4/ plotimplicit Ex1:inequationplot(x^2-y^2<3) Ex2:inequationplot(x^2-y^2<3,[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex3:inequationplot(3-(x^2-y^2),[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex4:inequationplot([x+y>3,x^2ln(a*b^n) for integers n. - See also: 1/ texpand + See also: 1/ texpand Ex1:lncollect(ln(x)+2*ln(y)) - ''' return GiacMethods['lncollect'](self,*args) @@ -9904,9 +9124,8 @@ cdef class GiacMethods_base: Help for lnexpand: lnexpand(Expr) Expands logarithms. - See also: 1/ texpand 2/ expexpand 3/ trigexpand + See also: 1/ texpand 2/ expexpand 3/ trigexpand Ex1:lnexpand(ln(3*x)) - ''' return GiacMethods['lnexpand'](self,*args) @@ -9915,10 +9134,9 @@ cdef class GiacMethods_base: Help for locus: locus(Pnt,Elem) locus(M,A) draws the locus of M (or locus(d,A) draws the envelope of d) when A:=element(C) (C is a curve). The example instructions below must be written in a geometric level on different lines. - See also: 1/ envelope 2/ trace + See also: 1/ envelope 2/ trace Ex1: A:=element(circle(i,1+i));M:=homothety(0,2,A);locus(M,A) Ex2: A:=element(line(x=0));d:=perpen_bisector(1,A);locus(d,A) - ''' return GiacMethods['locus'](self,*args) @@ -9927,11 +9145,10 @@ cdef class GiacMethods_base: Help for log: log(Expr or Opt) Natural logarithm or option of the convert or convertir command (id trig2exp). - See also: 1/ exp 2/ convert 3/ trig2exp 4/ log10 + See also: 1/ exp 2/ convert 3/ trig2exp 4/ log10 Ex1:log(1) Ex2:log(e) Ex3: convert(cos(x),ln) - ''' return GiacMethods['log'](self,*args) @@ -9940,9 +9157,8 @@ cdef class GiacMethods_base: Help for log10: log10(Expr) Common logarithm (base 10). - See also: 1/ alog10 2/ ln + See also: 1/ alog10 2/ ln Ex1:log10(10) - ''' return GiacMethods['log10'](self,*args) @@ -9951,10 +9167,9 @@ cdef class GiacMethods_base: Help for logarithmic_regression: logarithmic_regression(Lst||Mtrx(A),[Lst]) Returns the coefficients a and b of y=a*ln(x)+b : it is the best logarithm which approx the points where the coordinates are the rows of A (or the 2 lists). - See also: 1/ exponential_regression + See also: 1/ exponential_regression Ex1:logarithmic_regression([[1.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]]) Ex2:logarithmic_regression([1.0,2.0,3.0,4.0],[1.0,4.0,9.0,16.0]) - ''' return GiacMethods['logarithmic_regression'](self,*args) @@ -9963,10 +9178,9 @@ cdef class GiacMethods_base: Help for logarithmic_regression_plot: logarithmic_regression_plot(Lst||Mtrx(A),[Lst]) Returns the plot of y=a*ln(x)+b : it is the best logarithm which approx the points where the coordinates are the rows of A (or the 2 lists). - See also: 1/ exponential_regression_plot + See also: 1/ exponential_regression_plot Ex1:logarithmic_regression_plot([[1.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]]) Ex2:logarithmic_regression_plot([1.0,2.0,3.0,4.0],[1.0,4.0,9.0,16.0]) - ''' return GiacMethods['logarithmic_regression_plot'](self,*args) @@ -9975,10 +9189,9 @@ cdef class GiacMethods_base: Help for logb: logb(Real) Logarithm with base b. - See also: 1/ log 2/ log10 + See also: 1/ log 2/ log10 Ex1:logb(5,2) Ex2:logb(7,10) - ''' return GiacMethods['logb'](self,*args) @@ -9987,10 +9200,9 @@ cdef class GiacMethods_base: Help for logistic_regression: logistic_regression(Lst(L),Real(x0),Real(y0)) Returns y,y',C,y'max,xmax,R : y is a logistic function (sol of y'/y=a*y+b), such that y(x0)=y0 and where [y'(x0),y'(x0+1)...] is the best approximation of L. - See also: 1/ polynomial_regression 2/ power_regression 3/ linear_regression + See also: 1/ polynomial_regression 2/ power_regression 3/ linear_regression Ex1:logistic_regression(evalf([1,2,4,6,8,7,5]),1,2) Ex2:logistic_regression([0.0,1.0,2.0,3.0,4.0],0.0,1.0) - ''' return GiacMethods['logistic_regression'](self,*args) @@ -9999,10 +9211,9 @@ cdef class GiacMethods_base: Help for logistic_regression_plot: logistic_regression_plot(Lst(L),Real(x0),Real(y0)) Returns the plot of a logistic function y such that y(x0)=y0 and where [y'(x0),y'(x0+1)...] is the best approximation of L. - See also: 1/ polynomial_regression_plot 2/ power_regression_plot 3/ linear_regression_plot + See also: 1/ polynomial_regression_plot 2/ power_regression_plot 3/ linear_regression_plot Ex1:logistic_regression_plot(evalf([1,2,4,6,8,7,5]),1,2) Ex2:logistic_regression_plot([0.0,1.0,2.0,3.0,4.0],0.0,1.0) - ''' return GiacMethods['logistic_regression_plot'](self,*args) @@ -10011,10 +9222,9 @@ cdef class GiacMethods_base: Help for lower: lower(Mtrx||Strng) Returns the lower triangular matrix (under the diagonal, included) or writes a string in lowercase. - See also: 1/ diag 2/ upper + See also: 1/ diag 2/ upper Ex1:lower([[1,2,3],[4,5,6],[7,8,9]]) Ex2:lower("HELLO") - ''' return GiacMethods['lower'](self,*args) @@ -10023,10 +9233,9 @@ cdef class GiacMethods_base: Help for lowest_common_ancestor: lowest_common_ancestor(Graph(T),Vrtx(r),Seq(u,v)||Lst([u1,v1],[u2,v2],...)) Returns the lowest common ancestor of nodes u and v in the tree graph T with root r, or the list of lowest common ancestors of all pairs [uk,vk]. - See also: 1/ is_tree 2/ tree_height + See also: 1/ is_tree 2/ tree_height Ex1: T:=random_tree(30); lowest_common_ancestor(T,15,10,20) Ex2: T:=random_tree(30); lowest_common_ancestor(T,15,[[10,20],[11,19]]) - ''' return GiacMethods['lowest_common_ancestor'](self,*args) @@ -10035,9 +9244,8 @@ cdef class GiacMethods_base: Help for lowpass: lowpass(Lst(s),Real(c),[Intg(samplerate)]) Returns the result of applying a simple first-order lowpass RC filter with cutoff frequency c (the default samplerate is 44100) to the given signal s. - See also: 1/ highpass 2/ moving_average + See also: 1/ highpass 2/ moving_average Ex1: f:=unapply(periodic(sign(x),x,-1/880,1/880),x):;s:=createwav(apply(f,soundsec(1))):;playsnd(lowpass(s,1000)) - ''' return GiacMethods['lowpass'](self,*args) @@ -10046,8 +9254,7 @@ cdef class GiacMethods_base: Help for lp_assume: lp_assume(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_assume'](self,*args) @@ -10056,8 +9263,7 @@ cdef class GiacMethods_base: Help for lp_bestprojection: lp_bestprojection(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_bestprojection'](self,*args) @@ -10066,8 +9272,7 @@ cdef class GiacMethods_base: Help for lp_binary: lp_binary(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_binary'](self,*args) @@ -10076,8 +9281,7 @@ cdef class GiacMethods_base: Help for lp_binaryvariables: lp_binaryvariables(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_binaryvariables'](self,*args) @@ -10086,8 +9290,7 @@ cdef class GiacMethods_base: Help for lp_breadthfirst: lp_breadthfirst(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_breadthfirst'](self,*args) @@ -10096,8 +9299,7 @@ cdef class GiacMethods_base: Help for lp_depthfirst: lp_depthfirst(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_depthfirst'](self,*args) @@ -10106,8 +9308,7 @@ cdef class GiacMethods_base: Help for lp_depthlimit: lp_depthlimit(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_depthlimit'](self,*args) @@ -10116,8 +9317,7 @@ cdef class GiacMethods_base: Help for lp_firstfractional: lp_firstfractional(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_firstfractional'](self,*args) @@ -10126,8 +9326,7 @@ cdef class GiacMethods_base: Help for lp_gaptolerance: lp_gaptolerance(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_gaptolerance'](self,*args) @@ -10136,8 +9335,7 @@ cdef class GiacMethods_base: Help for lp_hybrid: lp_hybrid(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_hybrid'](self,*args) @@ -10146,8 +9344,7 @@ cdef class GiacMethods_base: Help for lp_initialpoint: lp_initialpoint(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_initialpoint'](self,*args) @@ -10156,8 +9353,7 @@ cdef class GiacMethods_base: Help for lp_integer: lp_integer(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_integer'](self,*args) @@ -10166,8 +9362,7 @@ cdef class GiacMethods_base: Help for lp_integertolerance: lp_integertolerance(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_integertolerance'](self,*args) @@ -10176,8 +9371,7 @@ cdef class GiacMethods_base: Help for lp_integervariables: lp_integervariables(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_integervariables'](self,*args) @@ -10186,8 +9380,7 @@ cdef class GiacMethods_base: Help for lp_interiorpoint: lp_interiorpoint(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_interiorpoint'](self,*args) @@ -10196,8 +9389,7 @@ cdef class GiacMethods_base: Help for lp_iterationlimit: lp_iterationlimit(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_iterationlimit'](self,*args) @@ -10206,8 +9398,7 @@ cdef class GiacMethods_base: Help for lp_lastfractional: lp_lastfractional(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_lastfractional'](self,*args) @@ -10216,8 +9407,7 @@ cdef class GiacMethods_base: Help for lp_maxcuts: lp_maxcuts(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_maxcuts'](self,*args) @@ -10226,8 +9416,7 @@ cdef class GiacMethods_base: Help for lp_maximize: lp_maximize(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_maximize'](self,*args) @@ -10236,8 +9425,7 @@ cdef class GiacMethods_base: Help for lp_method: lp_method(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_method'](self,*args) @@ -10246,8 +9434,7 @@ cdef class GiacMethods_base: Help for lp_mostfractional: lp_mostfractional(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_mostfractional'](self,*args) @@ -10256,8 +9443,7 @@ cdef class GiacMethods_base: Help for lp_nodelimit: lp_nodelimit(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_nodelimit'](self,*args) @@ -10266,8 +9452,7 @@ cdef class GiacMethods_base: Help for lp_nodeselect: lp_nodeselect(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_nodeselect'](self,*args) @@ -10276,8 +9461,7 @@ cdef class GiacMethods_base: Help for lp_nonnegative: lp_nonnegative(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_nonnegative'](self,*args) @@ -10286,8 +9470,7 @@ cdef class GiacMethods_base: Help for lp_nonnegint: lp_nonnegint(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_nonnegint'](self,*args) @@ -10296,8 +9479,7 @@ cdef class GiacMethods_base: Help for lp_pseudocost: lp_pseudocost(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_pseudocost'](self,*args) @@ -10306,8 +9488,7 @@ cdef class GiacMethods_base: Help for lp_simplex: lp_simplex(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_simplex'](self,*args) @@ -10316,8 +9497,7 @@ cdef class GiacMethods_base: Help for lp_timelimit: lp_timelimit(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_timelimit'](self,*args) @@ -10326,8 +9506,7 @@ cdef class GiacMethods_base: Help for lp_variables: lp_variables(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_variables'](self,*args) @@ -10336,8 +9515,7 @@ cdef class GiacMethods_base: Help for lp_varselect: lp_varselect(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_varselect'](self,*args) @@ -10346,8 +9524,7 @@ cdef class GiacMethods_base: Help for lp_verbose: lp_verbose(Opt) Options for lpsolve command. - See also: 1/ lpsolve - + See also: 1/ lpsolve ''' return GiacMethods['lp_verbose'](self,*args) @@ -10356,7 +9533,7 @@ cdef class GiacMethods_base: Help for lpsolve: lpsolve(Expr(o),[List(c)],[bounds],[options]) Solves a (mixed integer/binary) LP problem in general form. - See also: 1/ nlpsolve 2/ fsolve + See also: 1/ nlpsolve 2/ fsolve Ex1:lpsolve(2x+y-z+4,[x<=1,y>=2,x+3y-z=2,2x-y+z<=8,-x+y<=5]) Ex2:lpsolve(-4x-5y,[x+2y<=6,5x+4y<=20,0<=x,0<=y]) Ex3:lpsolve(-7x+2y,[4x-12y<=20,-x+3y<=3],x=-5..5,y=0..inf,lp_maximize=true) @@ -10372,7 +9549,6 @@ cdef class GiacMethods_base: Ex13:lpsolve(x1+x2,[2x1+5x2<=16,6x1+5x2<=30],assume=nonnegint,lp_maximize) Ex14:lpsolve(8x1+11x2+6x3+4x4,[5x1+7x2+4x3+3x4<=14],assume=lp_binary,lp_maximize) Ex15:lpsolve(x1+x2,[1867x1+1913x2=3618894],assume=nonnegint,lp_verbose=true) - ''' return GiacMethods['lpsolve'](self,*args) @@ -10381,9 +9557,8 @@ cdef class GiacMethods_base: Help for lsmod: lsmod(NULL) Displays the installed dynamic libraries. - See also: 1/ insmod 2/ rmmod + See also: 1/ insmod 2/ rmmod Ex1:lsmod() - ''' return GiacMethods['lsmod'](self,*args) @@ -10392,10 +9567,9 @@ cdef class GiacMethods_base: Help for lsq: lsq(Mtrx(A),(Mtrx || Vect)(B)) Returns the vector (resp matrix) X which is the minimum of the euclidean (resp Frobenius) norm of A*X-B corresponding to the linear system A*X=B when B is a vector (resp matrix). - See also: 1/ lu 2/ QR + See also: 1/ lu 2/ QR Ex1:lsq([[1,2],[3,4]],[5,11]) Ex2:lsq([[1,2],[3,4]],[[5,-1],[11,-1]]) - ''' return GiacMethods['lsq'](self,*args) @@ -10404,10 +9578,9 @@ cdef class GiacMethods_base: Help for lu: lu(Mtrx) For a numerical matrix A, returns p permutation, L and U such that PA=LU (P=permu2mat(p)). - See also: 1/ qr 2/ cholesky 3/ LU + See also: 1/ qr 2/ cholesky 3/ LU Ex1:lu([[1,2],[3,4]]) Ex2:lu([[6,12,18],[5,14,31],[3,8,18]]) - ''' return GiacMethods['lu'](self,*args) @@ -10416,10 +9589,9 @@ cdef class GiacMethods_base: Help for lvar: lvar(Expr) List of variables of an object (with rational dependence). - See also: 1/ lname 2/ has + See also: 1/ lname 2/ has Ex1:lvar(exp(x)*2*sin(y)) Ex2:lvar(exp(x)*2*sin(y)+ln(x)) - ''' return GiacMethods['lvar'](self,*args) @@ -10428,9 +9600,8 @@ cdef class GiacMethods_base: Help for mRow: mRow(Expr(Xpr),Mtrx(A),Intg(n1)) Multiplies row n1 of the matrix A by Xpr. - See also: 1/ rowAdd 2/ mRowAdd + See also: 1/ rowAdd 2/ mRowAdd Ex1:mRow(12,[[1,2],[3,4],[5,6]],0) - ''' return GiacMethods['mRow'](self,*args) @@ -10439,9 +9610,8 @@ cdef class GiacMethods_base: Help for mRowAdd: mRowAdd(Expr(Xpr),Mtrx(A),Intg(n1),Intg(n2)) Multiplies row n1 of the matrix A by Xpr, then adds it to the row n2. - See also: 1/ rowAdd 2/ mRow + See also: 1/ rowAdd 2/ mRow Ex1:mRowAdd(12,[[1,2],[3,4],[5,6]],0,2) - ''' return GiacMethods['mRowAdd'](self,*args) @@ -10450,10 +9620,9 @@ cdef class GiacMethods_base: Help for magenta: magenta(Opt) Option of the display command to display with color. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),red) Ex2: F:=display(point(2+1.5*i),point_point+green) - ''' return GiacMethods['magenta'](self,*args) @@ -10462,9 +9631,8 @@ cdef class GiacMethods_base: Help for make_directed: make_directed(Graph(G),[Mrtx(A)]) Returns the copy of undirected graph G in which every edge is converted to a pair of arcs [and with weights specified by matrix A]. - See also: 1/ is_directed 2/ make_weighted 3/ underlying_graph + See also: 1/ is_directed 2/ make_weighted 3/ underlying_graph Ex1:make_directed(cycle_graph(4),[[0,0,0,1],[2,0,1,3],[0,1,0,4],[5,0,4,0]]) - ''' return GiacMethods['make_directed'](self,*args) @@ -10473,9 +9641,8 @@ cdef class GiacMethods_base: Help for make_weighted: make_weighted(Graph(G),[Mrtx(M)]) Returns a copy of G with edge/arc weights set as specified by matrix M. If M is omitted, a square matrix of ones is used. If G is undirected, M is assumed to be symmetric. - See also: 1/ get_edge_weight 2/ is_weighted 3/ make_directed 4/ set_edge_weight 5/ underlying_graph 6/ weight_matrix + See also: 1/ get_edge_weight 2/ is_weighted 3/ make_directed 4/ set_edge_weight 5/ underlying_graph 6/ weight_matrix Ex1:make_weighted(cycle_graph(3),[[0,2,3],[2,0,1],[3,1,0]]) - ''' return GiacMethods['make_weighted'](self,*args) @@ -10484,12 +9651,11 @@ cdef class GiacMethods_base: Help for makelist: makelist(Fnc,InitVal,FinalVal,StepVal) Returns a list made with a function or with a constant. - See also: 1/ seq 2/ range 3/ makemat 4/ $ + See also: 1/ seq 2/ range 3/ makemat 4/ $ Ex1:makelist(x->x^2,1,10,2) Ex2:makelist(4,1,10) Ex3:makelist(4,5,10) Ex4:makelist(x->ifte(x<5,"A","B"),1,10) - ''' return GiacMethods['makelist'](self,*args) @@ -10498,11 +9664,10 @@ cdef class GiacMethods_base: Help for makemat: makemat(Fnct(f),RowsNumb,ColsNumb) Creates a matrix. - See also: 1/ matrix + See also: 1/ matrix Ex1:makemat((j,k)->j+k,3,2) Ex2:makemat((j,k)->1/(j+k+1),2,3) Ex3:makemat(sqrt(2),2,3) - ''' return GiacMethods['makemat'](self,*args) @@ -10511,9 +9676,8 @@ cdef class GiacMethods_base: Help for makesuite: makesuite(Vect||Lst) Returns a sequence made with a vector. - See also: 1/ makevector 2/ op + See also: 1/ makevector 2/ op Ex1:makesuite([1,2,3]) - ''' return GiacMethods['makesuite'](self,*args) @@ -10522,9 +9686,8 @@ cdef class GiacMethods_base: Help for makevector: makevector(Seq) Returns a vector made with a sequence. - See also: 1/ makesuite + See also: 1/ makesuite Ex1:makevector(1,2,3) - ''' return GiacMethods['makevector'](self,*args) @@ -10533,11 +9696,10 @@ cdef class GiacMethods_base: Help for map: map(Lst(l),Fnc(f)) Applies the function f at the elements of the list l or at a polynomial of internal format. - See also: 1/ apply 2/ set 3/ unapply + See also: 1/ apply 2/ set 3/ unapply Ex1:map([1,2,3],x->x^3) Ex2:map([1,2,3],unapply(x^3,x)) Ex3:map(%%%{1,[2,0]%%%}+%%%{2,[1,1]%%%},(a,b,c)->a*(b+2*c)) - ''' return GiacMethods['map'](self,*args) @@ -10546,8 +9708,7 @@ cdef class GiacMethods_base: Help for maple2mupad: maple2mupad(Str("Name_Maplefile"),Str("Name_Mupadfile")) maple2mupad("file1","file2") translates file1(Maple) to file2(MuPAD). - See also: 1/ maple2xcas - + See also: 1/ maple2xcas ''' return GiacMethods['maple2mupad'](self,*args) @@ -10556,8 +9717,7 @@ cdef class GiacMethods_base: Help for maple2xcas: maple2xcas(Str("NameMapleFile"),Str("NameXcasFile")) maple2xcas("file1","file2") translates file1(Maple) to file2(Xcas). - See also: 1/ maple2mupad - + See also: 1/ maple2mupad ''' return GiacMethods['maple2xcas'](self,*args) @@ -10566,9 +9726,8 @@ cdef class GiacMethods_base: Help for maple_ifactors: maple_ifactors(Intg(n)) Returns 1 or -1 for the sign and the prime factors with their multiplicity of n in a matrix, such as ifactors in Maple. - See also: 1/ ifactors + See also: 1/ ifactors Ex1:maple_ifactors(120) - ''' return GiacMethods['maple_ifactors'](self,*args) @@ -10577,10 +9736,9 @@ cdef class GiacMethods_base: Help for maple_mode: maple_mode(Intg(0) or 1 or 2 or 3) Switches to mode Xcas (0), Maple (1), Mupad (2), TI89 (3). - See also: 1/ python_compat + See also: 1/ python_compat Ex1:maple_mode(1) Ex2:maple_mode(0) - ''' return GiacMethods['maple_mode'](self,*args) @@ -10589,9 +9747,8 @@ cdef class GiacMethods_base: Help for markov: markov(Mtrx(M),[Real(eps)]) Computation of the proper elements of a Markov chain transition matrix M, returns the list of sequence of positive recurrent states, the list of corresponding invariant probabilities, the list of other strongly connected components, the list of probabilities to end up in the sequence of recurrent states. - See also: 1/ randmarkov 2/ plotproba + See also: 1/ randmarkov 2/ plotproba Ex1:markov([[0,0,1/2,0,1/2],[0,0,1,0,0],[1/4,1/4,0,1/4,1/4],[0,0,1/2,0,1/2],[0,0,0,0,1]]) - ''' return GiacMethods['markov'](self,*args) @@ -10600,9 +9757,8 @@ cdef class GiacMethods_base: Help for mat2list: mat2list(Mtrx) Returns the list of the terms of the matrix. - See also: 1/ list2mat 2/ flatten + See also: 1/ list2mat 2/ flatten Ex1:mat2list([[1,8],[4,9]]) - ''' return GiacMethods['mat2list'](self,*args) @@ -10611,9 +9767,8 @@ cdef class GiacMethods_base: Help for mathml: mathml(Expr) Converts the expression into a string to display maths for the web. - See also: 1/ export_mathml 2/ latex + See also: 1/ export_mathml 2/ latex Ex1:mathml(1/2) - ''' return GiacMethods['mathml'](self,*args) @@ -10622,9 +9777,8 @@ cdef class GiacMethods_base: Help for matpow: matpow(Mtrx,Intg(n)) Calculates the nth power of a matrix by jordanization. - See also: 1/ &^ 2/ ^ + See also: 1/ &^ 2/ ^ Ex1:matpow([[1,2],[3,4]],n) - ''' return GiacMethods['matpow'](self,*args) @@ -10633,12 +9787,11 @@ cdef class GiacMethods_base: Help for matrix: matrix(Intg(p),Intg(q),(Fnc(f) or Val(a))) Makes a matrix m(j,k) with p rows and q cols, m(j,k)=f(j,k) or m(j,k)=a : the index start at 0 or 1 according to the mode (Xcas or Maple) (or option of apply) or make a matrix with a table. - See also: 1/ makemat 2/ makelist 3/ apply + See also: 1/ makemat 2/ makelist 3/ apply Ex1:matrix(2,3,(j,k)->1/(j+k+1)) Ex2:matrix(3,2,(j,k)->j+k) Ex3:matrix(2,3,4) - Ex4: A[0..2,0..2]:=1;A[0..1,1..2]:=2;a:=matrix(A) - + Ex4: A[0..2,0..2]:=1;A[0..1,1..2]:=2;a:=matrix(A) ''' return GiacMethods['matrix'](self,*args) @@ -10647,12 +9800,11 @@ cdef class GiacMethods_base: Help for matrix_norm: matrix_norm(Mtrx,[2]||[inf]) Matrix norm induced by l1norm or by l2norm or by linfinty norm. - See also: 1/ l1norm 2/ l2 norm 3/ linfnorm 4/ frobenius_norm + See also: 1/ l1norm 2/ l2 norm 3/ linfnorm 4/ frobenius_norm Ex1:matrix_norm([[1,2,3],[3,-9,6],[4,5,6]]) Ex2:matrix_norm([[1,2,3],[3,-9,6],[4,5,6]],1) Ex3:matrix_norm([[1,2,3],[3,-9,6],[4,5,6]],2) Ex4:matrix_norm([[1,2,3],[3,-9,6],[4,5,6]],inf) - ''' return GiacMethods['matrix_norm'](self,*args) @@ -10661,9 +9813,8 @@ cdef class GiacMethods_base: Help for max: max(Seq||Lst) Maximum of elements of a sequence or a list of reals. - See also: 1/ min + See also: 1/ min Ex1:max(25,35) - ''' return GiacMethods['max'](self,*args) @@ -10672,9 +9823,8 @@ cdef class GiacMethods_base: Help for maxflow: maxflow(Graph(G),Vrtx(s),Vrtx(t)) Returns the optimal value for the max flow problem for network G with the source s and sink t along with an optimal flow (as a matrix). - See also: 1/ minimum_cut + See also: 1/ minimum_cut Ex1:maxflow(digraph(%{[[1,2],2],[[2,3],4],[[3,4],3],[[1,5],3],[[5,2],1],[[5,4],2]%}),1,4) - ''' return GiacMethods['maxflow'](self,*args) @@ -10683,9 +9833,8 @@ cdef class GiacMethods_base: Help for maximal_independent_set: maximal_independent_set(Graph(G)) Returns a maximal set of mutually independent (non-adjacent) vertices in G. - See also: 1/ maximum_independent_set + See also: 1/ maximum_independent_set Ex1:maximal_independent_set(graph("petersen")) - ''' return GiacMethods['maximal_independent_set'](self,*args) @@ -10702,7 +9851,6 @@ cdef class GiacMethods_base: Ex6:maximize(sqrt(x^2+y^2)-z,[x^2+y^2<=16,x+y+z=10],[x,y,z]) Ex7:maximize((1+x^2+3y+5x-4*x*y)/(1+x^2+y^2),x^2/4+y^2/3=9,[x,y]) Ex8:maximize(cos(x)^2+cos(y)^2,x+y=pi/4,[x,y],locus) - ''' return GiacMethods['maximize'](self,*args) @@ -10711,9 +9859,8 @@ cdef class GiacMethods_base: Help for maximum_clique: maximum_clique(Graph(G)) Returns the maximum clique of undirected graph G as a list of vertices. - See also: 1/ clique_number 2/ is_clique 3/ maximum_independent_set + See also: 1/ clique_number 2/ is_clique 3/ maximum_independent_set Ex1:maximum_clique(graph_complement(complete_graph(3,4))) - ''' return GiacMethods['maximum_clique'](self,*args) @@ -10722,9 +9869,8 @@ cdef class GiacMethods_base: Help for maximum_degree: maximum_degree(Graph(G)) Returns the largest degree among the vertices of G. - See also: 1/ minimum_degree 2/ vertex_degree + See also: 1/ minimum_degree 2/ vertex_degree Ex1:maximum_degree(digraph(trail(1,2,3,4,5,6,4,7,8,2))) - ''' return GiacMethods['maximum_degree'](self,*args) @@ -10733,9 +9879,8 @@ cdef class GiacMethods_base: Help for maximum_independent_set: maximum_independent_set(Graph(G)) Returns the maximum independent vertex set of G. - See also: 1/ clique_number 2/ graph_complement 3/ independence_number 4/ maximum_clique + See also: 1/ clique_number 2/ graph_complement 3/ independence_number 4/ maximum_clique Ex1:maximum_independent_set(complete_graph(3,4)) - ''' return GiacMethods['maximum_independent_set'](self,*args) @@ -10744,9 +9889,8 @@ cdef class GiacMethods_base: Help for maximum_matching: maximum_matching(Graph(G)) Returns the list of edges representing maximum matching in G. - See also: 1/ maximum_independent_set + See also: 1/ maximum_independent_set Ex1: G:=graph("soccerball"); draw_graph(highlight_edges(G,maximum_matching(G))) - ''' return GiacMethods['maximum_matching'](self,*args) @@ -10755,11 +9899,10 @@ cdef class GiacMethods_base: Help for maxnorm: maxnorm(Vect or Mtrx) Norm with the max of a vector (or of a matrix): maxnorm([x1,x2,..,xn])=max(|x1|,..,|xn|). - See also: 1/ l2norm 2/ l1norm + See also: 1/ l2norm 2/ l1norm Ex1:maxnorm([1,2]) Ex2:maxnorm([1,2,3,-4]) Ex3:maxnorm([[1,2],[3,-4]]) - ''' return GiacMethods['maxnorm'](self,*args) @@ -10768,11 +9911,10 @@ cdef class GiacMethods_base: Help for mean: mean(Lst||Mtrx,[Lst]) Mean of a list with the second argument as weight or of the columns of a matrix. - See also: 1/ stddev + See also: 1/ stddev Ex1:mean([1,2,3]) Ex2:mean([1,2,3],[1,2,3]) Ex3:mean([[1,2,3],[1,2,3]]) - ''' return GiacMethods['mean'](self,*args) @@ -10781,10 +9923,9 @@ cdef class GiacMethods_base: Help for median: median(Lst||Mtrx,[Lst]) Returns the median of a list with the second argument as weight or of the columns of a matrix. - See also: 1/ quartiles + See also: 1/ quartiles Ex1:median([1,2,3,5,10,4]) Ex2:median([1,2,3,5,10,4],[1,2,3,1,2,3]) - ''' return GiacMethods['median'](self,*args) @@ -10793,9 +9934,8 @@ cdef class GiacMethods_base: Help for median_line: median_line((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) median_line(A,B,C) draws the median-line through A of the triangle ABC. - See also: 1/ midpoint 2/ perpen_bisector + See also: 1/ midpoint 2/ perpen_bisector Ex1:median_line(-1,1-i,i) - ''' return GiacMethods['median_line'](self,*args) @@ -10804,10 +9944,9 @@ cdef class GiacMethods_base: Help for member: member(Elem(e),(Lst(l) or Set(l))) Tests if e is in the list or set l (=0, or k+1 with l[k]=e). - See also: 1/ contains 2/ est_element 3/ find 4/ index + See also: 1/ contains 2/ est_element 3/ find 4/ index Ex1:member(1,[4,3,1,2]) Ex2:member(1,%{4,3,1,2%}) - ''' return GiacMethods['member'](self,*args) @@ -10819,7 +9958,6 @@ cdef class GiacMethods_base: Ex1:mgf(normald,1,0) Ex2:mgf(poisson,5) Ex3:mgf(binomial,n,p) - ''' return GiacMethods['mgf'](self,*args) @@ -10828,13 +9966,12 @@ cdef class GiacMethods_base: Help for mid: mid(Lst(l) or Str(l),Intg(d),Intg(n)) Returns the extracted list of l with n elements (by default n=size(l)-d) and beginning at index d. - See also: 1/ head 2/ tail 3/ left 4/ right 5/ subMat + See also: 1/ head 2/ tail 3/ left 4/ right 5/ subMat Ex1:mid([0,1,2,3,4,5,6],2,3) Ex2:mid([0,1,2,3,4,5,6],2) Ex3:mid("azertyuiop",2,4) Ex4:mid("azertyuiop",2) Ex5:mid([[1,2],[3,4],[5,6]],1) - ''' return GiacMethods['mid'](self,*args) @@ -10843,14 +9980,13 @@ cdef class GiacMethods_base: Help for middle_point: middle_point(Opt) Option of the plotarea command and of the area command. - See also: 1/ plotarea 2/ area + See also: 1/ plotarea 2/ area Ex1: plotarea(x^2,x=0..1,5,trapezoid) Ex2: plotarea(x^2,x=0..1,5,middle_point) Ex3: plotarea(x^2,x=0..1,5,right_rectangle) Ex4: plotarea(x^2,x=0..1,5,left_rectangle) Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) - ''' return GiacMethods['middle_point'](self,*args) @@ -10859,9 +9995,8 @@ cdef class GiacMethods_base: Help for midpoint: midpoint((Pnt or Cplx),(Pnt or Cplx)) midpoint(A,B) draws the midpoint of the segment AB. - See also: 1/ median_line 2/ perpen_bisector + See also: 1/ median_line 2/ perpen_bisector Ex1:midpoint(-2,2i) - ''' return GiacMethods['midpoint'](self,*args) @@ -10870,9 +10005,8 @@ cdef class GiacMethods_base: Help for min: min(Seq||Lst) Minimum of elements of a sequence or a list of reals. - See also: 1/ max + See also: 1/ max Ex1:min(25,35) - ''' return GiacMethods['min'](self,*args) @@ -10881,10 +10015,9 @@ cdef class GiacMethods_base: Help for minimal_edge_coloring: minimal_edge_coloring(Graph(G),[sto]) Finds the minimal edge coloring of G and returns the sequence n,L where n is the class of G (1 for D colors and 2 for D+1 colors) and L is the list of colors of edges of G as returned by the edges command, or a copy of G with colored edges if the option 'sto' is specified. - See also: 1/ chromatic_index 2/ minimal_vertex_coloring 3/ edges + See also: 1/ chromatic_index 2/ minimal_vertex_coloring 3/ edges Ex1:minimal_edge_coloring(graph("petersen")) Ex2: G:=minimal_edge_coloring(graph("dodecahedron"),sto); draw_graph(G) - ''' return GiacMethods['minimal_edge_coloring'](self,*args) @@ -10893,9 +10026,8 @@ cdef class GiacMethods_base: Help for minimal_spanning_tree: minimal_spanning_tree(Graph(G)) Returns the minimal spanning tree of undirected graph G. - See also: 1/ spanning_tree + See also: 1/ spanning_tree Ex1:minimal_spanning_tree(graph([[0,1,0,4,0,0],[1,0,1,0,4,0],[0,1,0,3,0,1],[4,0,3,0,1,0],[0,4,0,1,0,4],[0,0,1,0,4,0]])) - ''' return GiacMethods['minimal_spanning_tree'](self,*args) @@ -10904,10 +10036,9 @@ cdef class GiacMethods_base: Help for minimal_vertex_coloring: minimal_vertex_coloring(Graph(G),[sto]) Computes the minimal vertex coloring for G and returns the colors in the order of vertices. If optional parameter "sto" is given, the colors are assigned to vertices and the modified copy of G is returned. - See also: 1/ chromatic_number 2/ is_vertex_colorable + See also: 1/ chromatic_number 2/ is_vertex_colorable Ex1:minimal_vertex_coloring(graph("petersen")) Ex2: draw_graph(minimal_vertex_coloring(graph("petersen"),sto)) - ''' return GiacMethods['minimal_vertex_coloring'](self,*args) @@ -10926,7 +10057,6 @@ cdef class GiacMethods_base: Ex8:minimax(abs(x)*sqrt(abs(x)),x=-2..2,15) Ex9:minimax(min(1/cosh(3*sin(x)),sin(9x/10)),x=-3..4,30) Ex10:minimax(when(x==0,0,exp(-1/x^2)),x=-1..1,25) - ''' return GiacMethods['minimax'](self,*args) @@ -10943,7 +10073,6 @@ cdef class GiacMethods_base: Ex6:minimize(sqrt(x^2+y^2)-z,[x^2+y^2<=16,x+y+z=10],[x,y,z]) Ex7:minimize((1+x^2+3y+5x-4*x*y)/(1+x^2+y^2),x^2/4+y^2/3=9,[x,y]) Ex8:minimize(cos(x)^2+cos(y)^2,x+y=pi/4,[x,y],locus) - ''' return GiacMethods['minimize'](self,*args) @@ -10952,9 +10081,8 @@ cdef class GiacMethods_base: Help for minimum_cut: minimum_cut(Graph(G),Vrtx(s),Vrtx(t)) Returns the list of edges forming a minimum cut in a directed graph G with the source s and sink t. - See also: 1/ maxflow + See also: 1/ maxflow Ex1:minimum_cut(digraph(%{[[1,2],2],[[2,3],4],[[3,4],3],[[1,5],3],[[5,2],1],[[5,4],2]%}),1,4) - ''' return GiacMethods['minimum_cut'](self,*args) @@ -10963,9 +10091,8 @@ cdef class GiacMethods_base: Help for minimum_degree: minimum_degree(Graph(G)) Returns the smallest degree among the vertices of G. - See also: 1/ maximum_degree 2/ vertex_degree + See also: 1/ maximum_degree 2/ vertex_degree Ex1:minimum_degree(digraph(trail(1,2,3,4,5,6,4,7,8,2))) - ''' return GiacMethods['minimum_degree'](self,*args) @@ -10974,11 +10101,10 @@ cdef class GiacMethods_base: Help for mkisom: mkisom(Vect,(Sign(1) or -1)) Matrix of an isometry given by its proper elements. - See also: 1/ isom + See also: 1/ isom Ex1:mkisom([1,2],1) Ex2:mkisom([[1,0,0],pi/3],-1) Ex3:mkisom(pi,1) - ''' return GiacMethods['mkisom'](self,*args) @@ -10987,9 +10113,8 @@ cdef class GiacMethods_base: Help for mksa: mksa(Unit) Converts units to the MKSA international unit system. - See also: 1/ convert 2/ ufactor + See also: 1/ convert 2/ ufactor Ex1:mksa(1_N) - ''' return GiacMethods['mksa'](self,*args) @@ -10998,9 +10123,8 @@ cdef class GiacMethods_base: Help for modgcd: modgcd(Poly,Poly) GCD of 2 polynomials, with the modular algorithm. - See also: 1/ gcd 2/ heugcd 3/ ezgcd 4/ psrgcd + See also: 1/ gcd 2/ heugcd 3/ ezgcd 4/ psrgcd Ex1:modgcd(x^4-1,(x-1)^2) - ''' return GiacMethods['modgcd'](self,*args) @@ -11009,11 +10133,10 @@ cdef class GiacMethods_base: Help for mods: mods(Intg,Intg) Returns the Euclidean symmetric remainder of two integers. - See also: 1/ irem 2/ iquo 3/ mod 4/ fracmod + See also: 1/ irem 2/ iquo 3/ mod 4/ fracmod Ex1:mods(8,3) Ex2:mods(10,4) Ex3:mods(11,7) - ''' return GiacMethods['mods'](self,*args) @@ -11023,7 +10146,6 @@ cdef class GiacMethods_base: monotonic() Returns a real that increases as time passes Ex1:monotonic() - ''' return GiacMethods['monotonic'](self,*args) @@ -11032,9 +10154,8 @@ cdef class GiacMethods_base: Help for montre_tortue: montre_tortue(NULL) Shows the turtle. - See also: 1/ cache_tortue + See also: 1/ cache_tortue Ex1:montre_tortue() - ''' return GiacMethods['montre_tortue'](self,*args) @@ -11043,12 +10164,11 @@ cdef class GiacMethods_base: Help for moustache: moustache(Lst,[Lst],[x=a..b||y=a..b]) Box and Whisker plot for a statistical series. - See also: 1/ quartiles + See also: 1/ quartiles Ex1:moustache([-1,1,2,2.2,3,4,-2,5]) Ex2:moustache([1,2,3,5,10,4],x=1..2) Ex3:moustache([1,2,3,5,10,4],[1,2,3,1,2,3]) Ex4:moustache([[6,0,1,3,4,2,5],[0,1,3,4,2,5,6],[1,3,4,2,5,6,0],[3,4,2,5,6,0,1],[4,2,5,6,0,1,3],[2,5,6,0,1,3,4]]) - ''' return GiacMethods['moustache'](self,*args) @@ -11057,9 +10177,8 @@ cdef class GiacMethods_base: Help for moving_average: moving_average(Lst(A),Intg(n)) Applies a moving average filter of length n to a signal sample A, and returns its result as an array of length nops(A)-n+1. - See also: 1/ lowpass + See also: 1/ lowpass Ex1: snd:=soundsec(2):;data:=0.5*threshold(3*sin(2*pi*220*snd),[-1.0,1.0])+randvector(length(snd),normald,0,0.05):;moving_average(data,25) - ''' return GiacMethods['moving_average'](self,*args) @@ -11068,9 +10187,8 @@ cdef class GiacMethods_base: Help for moyal: moyal(Expr,Expr,VectVar) Moyal product of 2 symbols. - See also: 1/ + See also: 1/ Ex1:moyal(x^2+y^4,x^4-y^2,[x,y],5) - ''' return GiacMethods['moyal'](self,*args) @@ -11079,11 +10197,10 @@ cdef class GiacMethods_base: Help for moyenne: moyenne(Lst||Mtrx,[Lst]) Mean of a list with the second argument as weight or of the columns of a matrix. - See also: 1/ stddev + See also: 1/ stddev Ex1:moyenne([1,2,3]) Ex2:moyenne([1,2,3],[1,2,3]) Ex3:moyenne([[1,2,3],[1,2,3]]) - ''' return GiacMethods['moyenne'](self,*args) @@ -11092,7 +10209,7 @@ cdef class GiacMethods_base: Help for mul: mul(Expr||Lst,[Var||Lst],[Intg(a)],[Intg(b)],[Intg(p)]) Multiplies the values of the expression when the variable go from a to b with a step p (product(expression,var,begin,end,step) by default p=1) or product of the elements of a list or product element by element of 2 lists or matrices. - See also: 1/ sum + See also: 1/ sum Ex1:mul(n,n,1,10,2) Ex2:mul(1/n,n,1,10) Ex3:mul(1/n,n,11,1) @@ -11100,7 +10217,6 @@ cdef class GiacMethods_base: Ex5:mul([2,3,4,5]) Ex6:mul([2,3,4],[5,6,7]) Ex7:mul([[2,3,4],[5,6,7]],[[2,3,4],[5,6,7]]) - ''' return GiacMethods['mul'](self,*args) @@ -11109,10 +10225,9 @@ cdef class GiacMethods_base: Help for mult_c_conjugate: mult_c_conjugate(Expr) Returns the expression after multiplication by the complex conjugate of the denominator (or of the numerator if no denominator). - See also: 1/ mult_conjugate + See also: 1/ mult_conjugate Ex1:mult_c_conjugate(1/(3+i*2)) Ex2:mult_c_conjugate(3+i*2) - ''' return GiacMethods['mult_c_conjugate'](self,*args) @@ -11121,10 +10236,9 @@ cdef class GiacMethods_base: Help for mult_conjugate: mult_conjugate(Expr) Returns the expression after multiplication by the conjugate of the denominator (or of the numerator if no denominator). - See also: 1/ mult_c_conjugate + See also: 1/ mult_c_conjugate Ex1:mult_conjugate(sqrt(3)-sqrt(2)) Ex2:mult_conjugate(1/(sqrt(3)-sqrt(2))) - ''' return GiacMethods['mult_conjugate'](self,*args) @@ -11133,12 +10247,11 @@ cdef class GiacMethods_base: Help for multinomial: multinomial(Intg(n),Vect(p),Vect(k)) Returns n!/(k0!*k1!*..;kj!)*(p0^k0*p1^k1..*pj^kj) (sum(p)=1 and sum(k)=n). - See also: 1/ binomial 2/ randvector 3/ ranm + See also: 1/ binomial 2/ randvector 3/ ranm Ex1:multinomial(10,[0.5,0.5],[3,7]) Ex2:multinomial(10,[0.2,0.3,0.5],[1,3,6]) Ex3: randvector(3,multinomial,[1/2,1/3,1/6]) Ex4: ranm(4,3,multinomial,[1/2,1/3,1/6]) - ''' return GiacMethods['multinomial'](self,*args) @@ -11147,10 +10260,9 @@ cdef class GiacMethods_base: Help for multiplier_conjugue: multiplier_conjugue(Expr) Returns the expression after multiplication by the conjugate of the denominator (or of the numerator if no denominator). - See also: 1/ mult_c_conjugate + See also: 1/ mult_c_conjugate Ex1:multiplier_conjugue(sqrt(3)-sqrt(2)) Ex2:multiplier_conjugue(1/(sqrt(3)-sqrt(2))) - ''' return GiacMethods['multiplier_conjugue'](self,*args) @@ -11159,10 +10271,9 @@ cdef class GiacMethods_base: Help for multiplier_conjugue_complexe: multiplier_conjugue_complexe(Expr) Returns the expression after multiplication by the complex conjugate of the denominator (or of the numerator if no denominator). - See also: 1/ mult_conjugate + See also: 1/ mult_conjugate Ex1:multiplier_conjugue_complexe(1/(3+i*2)) Ex2:multiplier_conjugue_complexe(3+i*2) - ''' return GiacMethods['multiplier_conjugue_complexe'](self,*args) @@ -11171,11 +10282,10 @@ cdef class GiacMethods_base: Help for multiply: multiply(Intg or Lst, Intg or Lst) Returns the product of the 2 arguments. - See also: 1/ * + See also: 1/ * Ex1:multiply(41,-4) Ex2:multiply([4,1],[-4,2]) Ex3:multiply([[4,1],[-4,1]],[[4,1],[-4,1]]) - ''' return GiacMethods['multiply'](self,*args) @@ -11184,8 +10294,7 @@ cdef class GiacMethods_base: Help for mupad2maple: mupad2maple(Str("NameMupadFile"),Str("NameMapleFile")) mupad2maple("file1","file2") translates file1(MuPAD) to file2(Maple). - See also: 1/ mupad2xcas - + See also: 1/ mupad2xcas ''' return GiacMethods['mupad2maple'](self,*args) @@ -11194,8 +10303,7 @@ cdef class GiacMethods_base: Help for mupad2xcas: mupad2xcas(Str("NameMupadFile"),Str("NameXcasFile")) mupad2xcas("file1","file2") translates file1(MuPAD) to file2(Xcas). - See also: 1/ mupad2maple - + See also: 1/ mupad2maple ''' return GiacMethods['mupad2xcas'](self,*args) @@ -11204,10 +10312,9 @@ cdef class GiacMethods_base: Help for mycielski: mycielski(Graph(G)) Returns the Mycielskian of undirected graph G. - See also: 1/ chromatic_number 2/ number_of_triangles + See also: 1/ chromatic_number 2/ number_of_triangles Ex1:mycielski(graph("petersen")) Ex2: is_isomorphic(mycielski(mycielski(path_graph(2))),graph("grotzsch")) - ''' return GiacMethods['mycielski'](self,*args) @@ -11216,9 +10323,8 @@ cdef class GiacMethods_base: Help for nCr: nCr(Intg(n),Intg(r)) comb(n,r)=number of combinations of r objects taken among n : n!/(r!(n-r)!) (If n<0 comb(n,r)=n(n-1)..(n-r+1)/r!). - See also: 1/ factorial 2/ perm + See also: 1/ factorial 2/ perm Ex1:nCr(4,2) - ''' return GiacMethods['nCr'](self,*args) @@ -11227,11 +10333,10 @@ cdef class GiacMethods_base: Help for nDeriv: nDeriv(Expr(Xpr),Var(Var),[Real(h)]) Returns an approximation of the derivative number at a point: (Xpr(var+h)-Xpr(var-h))/(2*h) (by default h=0.001). - See also: 1/ avgRC + See also: 1/ avgRC Ex1:nDeriv(f(x),x,h) Ex2:nDeriv(x^2,x,0.1) Ex3:nDeriv(x^2,x) - ''' return GiacMethods['nDeriv'](self,*args) @@ -11240,11 +10345,10 @@ cdef class GiacMethods_base: Help for nInt: nInt(Expr(f(x)),Var(x),Real(a),Real(b)) Returns the approximate value of integrate(f(x),x,a,b) by Romberg's method. - See also: 1/ integrate 2/ gaussquad + See also: 1/ integrate 2/ gaussquad Ex1:nInt(exp(x^2),x,0,1) Ex2:nInt(x^2,x,0,1) Ex3:nInt(exp(-x^2),x,-1,1) - ''' return GiacMethods['nInt'](self,*args) @@ -11253,9 +10357,8 @@ cdef class GiacMethods_base: Help for nPr: nPr(Intg(n),Intg(p)) perm(n,p)=number of arrangements of p objects taken among n : n!/(n-p)! - See also: 1/ comb 2/ factorial + See also: 1/ comb 2/ factorial Ex1:nPr(4,2) - ''' return GiacMethods['nPr'](self,*args) @@ -11264,10 +10367,9 @@ cdef class GiacMethods_base: Help for nSolve: nSolve(Expr,Var,[Guess or Interval],[Method]) Numerical solution of an equation or a system of equations. - See also: 1/ solve 2/ fsolve 3/ csolve + See also: 1/ solve 2/ fsolve 3/ csolve Ex1:nSolve(cos(x)=x,x) Ex2:nSolve(cos(x)=x,x=1.3) - ''' return GiacMethods['nSolve'](self,*args) @@ -11276,10 +10378,9 @@ cdef class GiacMethods_base: Help for ncols: ncols(Mtrx) Number of columns of a matrix. - See also: 1/ rowdim + See also: 1/ rowdim Ex1:ncols([[1,2,3],[4,5,6]]) Ex2:ncols([[1,2],[3,4],[5,6]]) - ''' return GiacMethods['ncols'](self,*args) @@ -11288,11 +10389,10 @@ cdef class GiacMethods_base: Help for negbinomial: negbinomial(Intg(n),Intg(k),Real(p in 0..1)) Returns comb(n+k-1,k)*p^k*(1-p)^n. - See also: 1/ negbinomial_cdf 2/ negbinomial_icdf 3/ binomial + See also: 1/ negbinomial_cdf 2/ negbinomial_icdf 3/ binomial Ex1:negbinomial(4,0,0.5) Ex2:negbinomial(4,2,0.6) Ex3:negbinomial(4,6,0.3) - ''' return GiacMethods['negbinomial'](self,*args) @@ -11301,11 +10401,10 @@ cdef class GiacMethods_base: Help for negbinomial_cdf: negbinomial_cdf(Intg(n),Real(p),Real(x),[Real(y)]) Returns Proba(X<=x) or Proba(x<=X<=y) when X follows the negbinomial(n,p) law. - See also: 1/ negbinomial 2/ negbinomial_icdf + See also: 1/ negbinomial 2/ negbinomial_icdf Ex1:negbinomial_cdf(4,0.5,2) Ex2:negbinomial_cdf(4,0.1,2) Ex3:negbinomial_cdf(4,0.5,2,3) - ''' return GiacMethods['negbinomial_cdf'](self,*args) @@ -11314,10 +10413,9 @@ cdef class GiacMethods_base: Help for negbinomial_icdf: negbinomial_icdf(Intg(n),Real(p),Real(t)) Returns h such as Proba(X<=h)=t when X follows the negbinomial(n,p) law. - See also: 1/ negbinomial 2/ negbinomial_cdf + See also: 1/ negbinomial 2/ negbinomial_cdf Ex1:negbinomial_icdf(4,0.5,0.68) Ex2:negbinomial_icdf(4,0.1,0.95) - ''' return GiacMethods['negbinomial_icdf'](self,*args) @@ -11326,9 +10424,8 @@ cdef class GiacMethods_base: Help for neighbors: neighbors(Graph(G),[Vrtx(v)]) Returns the list of vertices adjacent to vertex v of G. If v is omitted, a list of adjacency lists of all vertices in G is returned. - See also: 1/ adjacency_matrix 2/ vertex_degree 3/ in_degree 3/ out_degree + See also: 1/ adjacency_matrix 2/ vertex_degree 3/ in_degree 3/ out_degree Ex1:neighbors(digraph(trail(1,2,3,4,5,6,4,7,8,2)),4) - ''' return GiacMethods['neighbors'](self,*args) @@ -11337,9 +10434,8 @@ cdef class GiacMethods_base: Help for network_transitivity: network_transitivity(Graph(G)) Returns the transitivity (also called triangle density or global clustering coefficient) of G. - See also: 1/ clustering_coefficient 2/ number_of_triangles + See also: 1/ clustering_coefficient 2/ number_of_triangles Ex1:network_transitivity(graph(%{[1,2],[2,3],[2,4],[3,4],[4,1]%})) - ''' return GiacMethods['network_transitivity'](self,*args) @@ -11348,9 +10444,8 @@ cdef class GiacMethods_base: Help for newList: newList(Intg(n)) Returns the list made with n zeros. - See also: 1/ newMat 2/ makelist + See also: 1/ newMat 2/ makelist Ex1:newList(4) - ''' return GiacMethods['newList'](self,*args) @@ -11359,9 +10454,8 @@ cdef class GiacMethods_base: Help for newMat: newMat(Intg(n),Intg(p)) Returns the list with n rows and p columns, made with zeros. - See also: 1/ newList 2/ makemat + See also: 1/ newList 2/ makemat Ex1:newMat(2,3) - ''' return GiacMethods['newMat'](self,*args) @@ -11370,12 +10464,11 @@ cdef class GiacMethods_base: Help for newton: newton(Expr(f(x)),Var(x),[ApproxVal(a),NumIter(p)]) newton(f(x),x,a,p)=one root of f(x) by Newton method beginning with a and p iterations (by default p=20). - See also: 1/ rootof + See also: 1/ rootof Ex1:newton(x^2-2,x) Ex2:newton(x^2-2,x,2) Ex3:newton(x^2-2,x,-2) Ex4:newton(x^2-2,x,2,5,1e-7) - ''' return GiacMethods['newton'](self,*args) @@ -11384,14 +10477,13 @@ cdef class GiacMethods_base: Help for newton_solver: newton_solver(Opt) Argument for fsolve giving the method for solving a numerical equation. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve(cos(x)=x,x,0..1,bisection_solver) Ex2: fsolve(cos(x)=x,x,0..1,brent_solver) Ex3: fsolve(cos(x)=x,x,0..1,falsepos_solver) Ex4: fsolve(cos(x)=x,x,0,newton_solver) Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) - ''' return GiacMethods['newton_solver'](self,*args) @@ -11400,14 +10492,13 @@ cdef class GiacMethods_base: Help for newtonj_solver: newtonj_solver(Opt) Argument for fsolve giving the method for solving a system of numerical equations. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],dnewton_solver) Ex2: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrid_solver) Ex3: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybrids_solver) Ex4: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridj_solver) Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) - ''' return GiacMethods['newtonj_solver'](self,*args) @@ -11416,10 +10507,9 @@ cdef class GiacMethods_base: Help for nextperm: nextperm(Intg(n)) Returns the next permutation with the lexicographic order. - See also: 1/ prevperm 2/ is_permu + See also: 1/ prevperm 2/ is_permu Ex1:nextperm([0,2,1,3]) Ex2:nextperm([0,3,2,1]) - ''' return GiacMethods['nextperm'](self,*args) @@ -11428,10 +10518,9 @@ cdef class GiacMethods_base: Help for nextprime: nextprime(Intg(a)) Next prime or pseudo-prime after a given integer. - See also: 1/ prevprime 2/ is_prime 3/ ithprime + See also: 1/ prevprime 2/ is_prime 3/ ithprime Ex1:nextprime(9856989898990) Ex2:nextprime(97160249868928888261606009) - ''' return GiacMethods['nextprime'](self,*args) @@ -11440,7 +10529,7 @@ cdef class GiacMethods_base: Help for nlpsolve: nlpsolve(objective, [constr], [bd], [opts]) Solves a nonlinear programming problem of optimizing the objective obj under constraints constr (list of equations and/or inequations) and within bounds bd (sequence of x=a..b) with optional options (for example setting an initial point). - See also: 1/ lpsolve 2/ fsolve 3/ fMin 4/ fMax + See also: 1/ lpsolve 2/ fsolve 3/ fMin 4/ fMax Ex1:nlpsolve((x1-10)^3+(x2-20)^3,[(x1-5)^2+(x2-5)^2>=100,(x2-5)^2+(x1-6)^2<=82.81],nlp_initialpoint=[x1=20.1,x2=5.84]) Ex2:nlpsolve(sin(x1+x2)+(x1-x2)^2-1.5x1+2.5x2+1,x1=-1.5..4,x2=-3..3) Ex3:nlpsolve(ln(1+x1^2)-x2,[(1+x1^2)^2+x2^2=4]) @@ -11448,10 +10537,9 @@ cdef class GiacMethods_base: Ex5:nlpsolve(-x1*x2*x3,[72-x1-2x2-2x3>=0],x1=0..20,x2=0..11,x3=0..42) Ex6:nlpsolve(2-1/120*x1*x2*x3*x4*x5,[x1<=1,x2<=2,x3<=3,x4<=4,x5<=5],assume=nlp_nonnegative) Ex7:nlpsolve(sin(x)/x,x=1..30) - Ex8:nlpsolve(x^3+2x*y-2y^2,x=-10..10,y=-10..10,nlp_initialpoint=[x=3,y=4],maximize) + Ex8:nlpsolve(x^3+2x*y-2y^2,x=-10..10,y=-10..10,nlp_initialpoint=[x=3,y=4],maximize) Ex9:nlpsolve(w^3*(v-w)^2+(w-x-1)^2+(x-y-2)^2+(y-z-3)^2,[w+x+y+z<=5,3z+2v=3],assume=nlp_nonnegative) Ex10:nlpsolve(sin(x)*Psi(x),x=1..20,nlp_initialpoint=[x=16]) - ''' return GiacMethods['nlpsolve'](self,*args) @@ -11461,7 +10549,6 @@ cdef class GiacMethods_base: nodisp(Expr) Displays Done in place of a value. Ex1:nodisp(A:=ranm(50,50)) - ''' return GiacMethods['nodisp'](self,*args) @@ -11470,10 +10557,9 @@ cdef class GiacMethods_base: Help for non_recursive_normal: non_recursive_normal(Expr) Simplifies the expressions, but without simplification inside of non-rational expressions. - See also: 1/ normal + See also: 1/ normal Ex1:non_recursive_normal(sin(x+x)+sin(2*x)+x+x) Ex2:non_recursive_normal(sin(2*x)+sin(2*x)+x+x) - ''' return GiacMethods['non_recursive_normal'](self,*args) @@ -11482,9 +10568,8 @@ cdef class GiacMethods_base: Help for nop: nop(NULL) No OPeration instruction. - See also: 1/ + See also: 1/ Ex1:nop() - ''' return GiacMethods['nop'](self,*args) @@ -11493,11 +10578,10 @@ cdef class GiacMethods_base: Help for nops: nops(Lst or Str or Seq) Returns the size of a list, a string or a sequence. - See also: 1/ sizes 2/ dim 3/ degree + See also: 1/ sizes 2/ dim 3/ degree Ex1:nops([1,2,3]) Ex2:nops("bonjour") Ex3:nops(1,2,3) - ''' return GiacMethods['nops'](self,*args) @@ -11506,12 +10590,11 @@ cdef class GiacMethods_base: Help for norm: norm(Vect or Mtrx) Returns the l2 norm of a vector = sqrt(x1^2+x2^2+...xn^2) or matrix norm induced by l2 norm. - See also: 1/ maxnorm 2/ l1norm + See also: 1/ maxnorm 2/ l1norm Ex1:norm([1,2]) Ex2:norm([1,2,3,-4]) Ex3:norm([[1,2],[3,-4]]) Ex4:norm([[1,2,3],[3,-9,6],[4,5,6]]) - ''' return GiacMethods['norm'](self,*args) @@ -11520,11 +10603,10 @@ cdef class GiacMethods_base: Help for normal: normal(Expr) Simplifies the expression. - See also: 1/ simplify + See also: 1/ simplify Ex1:normal(2*x+y=1) Ex2:normal(2*x*2) Ex3:normal((2*x+1)^2) - ''' return GiacMethods['normal'](self,*args) @@ -11533,11 +10615,10 @@ cdef class GiacMethods_base: Help for normal_cdf: normal_cdf(Real(mu),Real(sigma),Real(x0),[Real(y0)]) Returns the probability that a Normal random variable is less than x0 or between x0 and y0 (mu is the mean and sigma the standard deviation). - See also: 1/ UTPN 2/ normal_icdf 3/ normald + See also: 1/ UTPN 2/ normal_icdf 3/ normald Ex1:normal_cdf(1.96) Ex2:normal_cdf(1,2,2.96*sqrt(2)) Ex3:normal_cdf(1,2,1.4*sqrt(2),2.96*sqrt(2)) - ''' return GiacMethods['normal_cdf'](self,*args) @@ -11546,10 +10627,9 @@ cdef class GiacMethods_base: Help for normal_icdf: normal_icdf(Real(mu),Real(sigma),Real(p)) Returns h such as the probability that a Normal random variable is less than h is p (mu is the mean and sigma the standard deviation and 0<=p<=1). - See also: 1/ normal_cdf 2/ normald + See also: 1/ normal_cdf 2/ normald Ex1:normal_icdf(0.95) Ex2:normal_icdf(1,2,0.95) - ''' return GiacMethods['normal_icdf'](self,*args) @@ -11558,12 +10638,11 @@ cdef class GiacMethods_base: Help for normald: normald(Real(mu),Real(sigma),Real(x0)) Returns the probability density of the Normal law (mu is the mean and sigma the standard deviation). - See also: 1/ normal_cdf 2/ normal_icdf 3/ randvector 4/ ranm + See also: 1/ normal_cdf 2/ normal_icdf 3/ randvector 4/ ranm Ex1:normald(1) Ex2:normald(1,2,3.5) Ex3: randvector(3,normald,1,0.5) Ex4: ranm(4,3,normald,1,0.5) - ''' return GiacMethods['normald'](self,*args) @@ -11572,11 +10651,10 @@ cdef class GiacMethods_base: Help for normald_cdf: normald_cdf(Real(mu),Real(sigma),Real(x0),[Real(y0)]) Returns the probability that a Normal random variable is less than x0 or between x0 and y0 (mu is the mean and sigma the standard deviation). - See also: 1/ UTPN 2/ normal_icdf 3/ normald + See also: 1/ UTPN 2/ normal_icdf 3/ normald Ex1:normald_cdf(1.96) Ex2:normald_cdf(1,2,2.96*sqrt(2)) Ex3:normald_cdf(1,2,1.4*sqrt(2),2.96*sqrt(2)) - ''' return GiacMethods['normald_cdf'](self,*args) @@ -11585,10 +10663,9 @@ cdef class GiacMethods_base: Help for normald_icdf: normald_icdf(Real(mu),Real(sigma),Real(p)) Returns h such as the probability that a Normal random variable is less than h is p (mu is the mean and sigma the standard deviation and 0<=p<=1). - See also: 1/ normal_cdf 2/ normald + See also: 1/ normal_cdf 2/ normald Ex1:normald_icdf(0.95) Ex2:normald_icdf(1,2,0.95) - ''' return GiacMethods['normald_icdf'](self,*args) @@ -11597,12 +10674,11 @@ cdef class GiacMethods_base: Help for normalize: normalize(Lst||Cplx) Returns the vector divided by its l2norm. It is also an option for plotfield. - See also: 1/ l2norm + See also: 1/ l2norm Ex1:normalize(3+4*i) Ex2:normalize([3,4]) Ex3: fieldplot(-t*y,[t,y],normalize) Ex4: fieldplot(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) - ''' return GiacMethods['normalize'](self,*args) @@ -11611,10 +10687,9 @@ cdef class GiacMethods_base: Help for normalt: normalt(Lst,Real,[Real],Fnc,[Real]) Z-Test/normal law: arg1=[success,trial] or [mean,sample size] or data, arg2=proportion or data, arg3 optional if data=sigma, arg4 alternative '!=' or '>' or '<', arg5 optional alpha confidence level. - See also: 1/ studentt 2/ chisquaret 3/ kolmogorovt + See also: 1/ studentt 2/ chisquaret 3/ kolmogorovt Ex1:normalt([10,30],.5,.02,'!=',0.1) Ex2:normalt([0.48,50],0.5,0.1,'<') - ''' return GiacMethods['normalt'](self,*args) @@ -11623,10 +10698,9 @@ cdef class GiacMethods_base: Help for normalvariate: normalvariate(Real(mu),Real(sigma)) Returns a random real with normal distribution N(mu,sigma). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randpoisson 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randpoisson 8/ randgeometric 9/ randmultinomial Ex1:normalvariate(0,1) Ex2:normalvariate(2,1) - ''' return GiacMethods['normalvariate'](self,*args) @@ -11635,9 +10709,8 @@ cdef class GiacMethods_base: Help for nprimes: nprimes(Intg(n)) Counts the number of primes less than n. - See also: 1/ ithprime 2/ prevprime 3/ nextprime 4/ isprime + See also: 1/ ithprime 2/ prevprime 3/ nextprime 4/ isprime Ex1:nprimes(20) - ''' return GiacMethods['nprimes'](self,*args) @@ -11646,10 +10719,9 @@ cdef class GiacMethods_base: Help for nrows: nrows(Mtrx) Number of rows of a matrix. - See also: 1/ ncols + See also: 1/ ncols Ex1:nrows([[1,2,3],[4,5,6]]) Ex2:nrows([[1,2],[3,4],[5,6]]) - ''' return GiacMethods['nrows'](self,*args) @@ -11658,9 +10730,8 @@ cdef class GiacMethods_base: Help for nuage_points: nuage_points(Mtrx) Draws for k=0..nrows, the points (xk,yk) where xk=element row k column 0 and yk=element row k column j (j=1..ncols). - See also: 1/ polygonplot 2/ polygonscatterplot 3/ listplot + See also: 1/ polygonplot 2/ polygonscatterplot 3/ listplot Ex1:nuage_points([[1,2,3],[2,0,1],[-1,2,3]]) - ''' return GiacMethods['nuage_points'](self,*args) @@ -11669,10 +10740,9 @@ cdef class GiacMethods_base: Help for nullspace: nullspace(Mtrx) Kernel of a linear map with matrix M. - See also: 1/ image 2/ rref 3/ Nullspace + See also: 1/ image 2/ rref 3/ Nullspace Ex1:nullspace([[1,2],[3,6]]) Ex2:nullspace([[1,2,3],[1,3,6],[2,5,9]]) - ''' return GiacMethods['nullspace'](self,*args) @@ -11681,9 +10751,8 @@ cdef class GiacMethods_base: Help for number_of_edges: number_of_edges(Graph(G)) Returns the number of edges/arcs of G. - See also: 1/ edges 2/ number_of_vertices + See also: 1/ edges 2/ number_of_vertices Ex1:number_of_edges(complete_graph(5)) - ''' return GiacMethods['number_of_edges'](self,*args) @@ -11692,10 +10761,9 @@ cdef class GiacMethods_base: Help for number_of_spanning_trees: number_of_spanning_trees(Graph(G)) Returns the number of spanning trees in undirected graph G. - See also: 1/ spanning_tree + See also: 1/ spanning_tree Ex1:number_of_spanning_trees(complete_graph(4)) Ex2:number_of_spanning_trees(graph(trail(1,2,3,4,1,3))) - ''' return GiacMethods['number_of_spanning_trees'](self,*args) @@ -11704,9 +10772,8 @@ cdef class GiacMethods_base: Help for number_of_triangles: number_of_triangles(Graph(G)) Returns the number of 3-cliques if G is undirected resp. the number of directed cycles on 3 vertices if G is directed. - See also: 1/ is_clique 2/ maximal_clique + See also: 1/ is_clique 2/ maximal_clique Ex1:number_of_triangles(graph("tetrahedron")) - ''' return GiacMethods['number_of_triangles'](self,*args) @@ -11715,9 +10782,8 @@ cdef class GiacMethods_base: Help for number_of_vertices: number_of_vertices(Graph(G)) Returns the number of vertices of G. - See also: 1/ graph_vertices 2/ number_of_edges + See also: 1/ graph_vertices 2/ number_of_edges Ex1:number_of_vertices(graph("petersen")) - ''' return GiacMethods['number_of_vertices'](self,*args) @@ -11726,11 +10792,10 @@ cdef class GiacMethods_base: Help for numer: numer(Frac(a/b) or RatFrac) Returns the numerator of the simplified fraction. - See also: 1/ getNum 2/ getDenom 3/ denom 4/ f2nd + See also: 1/ getNum 2/ getDenom 3/ denom 4/ f2nd Ex1:numer(25/15) Ex2:numer((x^3-1)/(x^2-1)) Ex3:numer(1+(x^3-1)/x^2) - ''' return GiacMethods['numer'](self,*args) @@ -11739,10 +10804,9 @@ cdef class GiacMethods_base: Help for octahedron: octahedron(Pnt(A),Pnt(B),Pnt(C)) Draws an octahedron with center A, vertex B and such that the plane ABC contains 4 vertices. - See also: 1/ icosahedron 2/ dodecahedron 3/ cube 4/ tetrahedron + See also: 1/ icosahedron 2/ dodecahedron 3/ cube 4/ tetrahedron Ex1:octahedron([0,0,0],[0,0,5],[0,5,0]) Ex2:octahedron(evalf([0,0,0],[3,2,4],[1,1,0])) - ''' return GiacMethods['octahedron'](self,*args) @@ -11751,10 +10815,9 @@ cdef class GiacMethods_base: Help for odd: odd(Intg(n)) Returns 1 if the integer is odd, else returns 0. - See also: 1/ even + See also: 1/ even Ex1:odd(6) Ex2:odd(1251) - ''' return GiacMethods['odd'](self,*args) @@ -11763,10 +10826,9 @@ cdef class GiacMethods_base: Help for odd_girth: odd_girth(Graph(G)) Returns the length of the shortest odd cycle in the undirected unweighted graph G. - See also: 1/ girth + See also: 1/ girth Ex1:odd_girth(graph("petersen")) Ex2:odd_girth(hypercube_graph(3)) - ''' return GiacMethods['odd_girth'](self,*args) @@ -11775,9 +10837,8 @@ cdef class GiacMethods_base: Help for odd_graph: odd_graph(Intg(n)) Returns the odd graph of order n as Kneser graph K(2n-1,n-1), where n<=8. - See also: 1/ kneser_graph + See also: 1/ kneser_graph Ex1:odd_graph(3) - ''' return GiacMethods['odd_graph'](self,*args) @@ -11786,7 +10847,7 @@ cdef class GiacMethods_base: Help for odeplot: odeplot(Expr,VectVar,VectInitCond) odeplot(f(t,y),[t,y],[t0,y0]) draws the solution of y'=f(t,y) and y(t0)=y0 or of the system [x'=g(t,x,y),y'=h(t,x,y)] with x(t0)=x0 and y(t0)=y0. - See also: 1/ interactive_plotode 2/ fieldplot 3/ odesolve 4/ desolve + See also: 1/ interactive_plotode 2/ fieldplot 3/ odesolve 4/ desolve Ex1:odeplot(sin(t*y),[t,y],[0,1]) Ex2:odeplot(sin(t*y),[t=-10..10,y],[0,1]) Ex3:odeplot(sin(t*y),[t=-3..3,y],[0,1],tstep=0.1,color=vert) @@ -11794,7 +10855,6 @@ cdef class GiacMethods_base: Ex5:odeplot([x-0.3*x*y, 0.3*x*y-y], [t,x,y],[0,0.3,0.7],plan) Ex6:odeplot([-y+b,-1+(x-a)^2+(y-b)^2],[t=-3..3,x,y],[0,a+1,b+0.5],plan) Ex7:odeplot(5*[-y,x],[t=0..1,x,y],[0,0.3,0.7],tstep=0.05,plan) - ''' return GiacMethods['odeplot'](self,*args) @@ -11803,13 +10863,12 @@ cdef class GiacMethods_base: Help for odesolve: odesolve(Expr,VectVar,VectInitCond,FinalVal,[tstep=Val,curve]) odesolve(f(t,y),[t,y],[t0,y0],t1)=odesolve(t0..t1,f,y0)=y(t1) for y approx sol of y'=f(t,y) and y(t0)=y0 with y=vector for systems. - See also: 1/ plotode 2/ plotfield 3/ interactive_plotode 4/ desolve + See also: 1/ plotode 2/ plotfield 3/ interactive_plotode 4/ desolve Ex1:odesolve(sin(t*y),[t,y],[0,1],2) Ex2:odesolve(0..2,(t,y)->sin(t*y),1) Ex3:odesolve(0..pi,(t,v)->{[-v[1],v[0]]},[0,1]) Ex4:odesolve(sin(t*y),t=0..2,y,1,tstep=0.5) Ex5:odesolve(sin(t*y),t=0..2,y,1,tstep=0.5,curve) - ''' return GiacMethods['odesolve'](self,*args) @@ -11818,13 +10877,12 @@ cdef class GiacMethods_base: Help for op: op(Op or Fnc) Returns the arguments of an operator as a sequence. - See also: 1/ sommet 2/ quote 3/ makesuite + See also: 1/ sommet 2/ quote 3/ makesuite Ex1:op(quote(gcd(45,126))) Ex2:op('gcd(45,126)') Ex3:op('1+2')[1] Ex4:op([1,2,3]) Ex5:op(set[1,2,3]) - ''' return GiacMethods['op'](self,*args) @@ -11833,10 +10891,9 @@ cdef class GiacMethods_base: Help for open_polygon: open_polygon(LstPnt||LstCplx) Returns and draws the polygonal line where its vertices are the element of l. - See also: 1/ isopolygon 2/ quadrilateral + See also: 1/ isopolygon 2/ quadrilateral Ex1:open_polygon(i,1+i,2-i,-1,-1+i/2) Ex2:open_polygon(point(0,0,0),point(3,3,3),point(0,0,3),point(3,0,0)) - ''' return GiacMethods['open_polygon'](self,*args) @@ -11845,11 +10902,10 @@ cdef class GiacMethods_base: Help for ord: ord(Char||LstChar) Returns the ASCII code of a character or of the first character of a string. - See also: 1/ asc 2/ char + See also: 1/ asc 2/ char Ex1:ord("A") Ex2:ord("ABC") Ex3:ord(["a","b","c"]) - ''' return GiacMethods['ord'](self,*args) @@ -11860,7 +10916,6 @@ cdef class GiacMethods_base: Returns element order of g in (Z/nZ)^* or in a finite field. Ex1:order(3 % 7) Ex2: GF(3,5,g); order(g^2+g+1); - ''' return GiacMethods['order'](self,*args) @@ -11869,10 +10924,9 @@ cdef class GiacMethods_base: Help for order_size: order_size(Expr) Remainder (O term) of a series expansion: limit(x^a*order_size(x),x=0)=0 if a>0. - See also: 1/ series + See also: 1/ series Ex1:order_size(x) Ex2: limit(sqrt(x)*order_size(x),x=0) - ''' return GiacMethods['order_size'](self,*args) @@ -11881,12 +10935,11 @@ cdef class GiacMethods_base: Help for ordinate: ordinate(Pnt or Vect) Returns the ordinate of a point or a vector. - See also: 1/ abscissa 2/ affix 3/ cote 4/ coordinates + See also: 1/ abscissa 2/ affix 3/ cote 4/ coordinates Ex1:ordinate(point(1+2*i)) Ex2:ordinate(point(i)-point(1+2*i)) Ex3:ordinate(-1-i) Ex4:ordinate(point(1,2,3)) - ''' return GiacMethods['ordinate'](self,*args) @@ -11895,11 +10948,10 @@ cdef class GiacMethods_base: Help for orthocenter: orthocenter((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) Shows the orthocenter of a triangle or of the triangle made with 3 points. - See also: 1/ altitude 2/ triangle + See also: 1/ altitude 2/ triangle Ex1:orthocenter(1+i,2,i) Ex2:orthocenter(point(1+i),point(2),point(i)) Ex3:orthocenter(triangle(0,1,1+i)) - ''' return GiacMethods['orthocenter'](self,*args) @@ -11908,10 +10960,9 @@ cdef class GiacMethods_base: Help for orthogonal: orthogonal((Pnt),(Line or Plan)) orthogonal(A,line(B,C)) draws the orthogonal plane of line BC through A and orthogonal(A,plane(B,C,D)) draws the orthogonal line of plane(B,C,D) through A. - See also: 1/ altitude 2/ perpendicular + See also: 1/ altitude 2/ perpendicular Ex1:orthogonal(point(0,0,0),line(point(1,0,0),point(0,1,0))) Ex2:orthogonal(point(0,0,0),plane(point(1,0,0),point(0,1,0),point(0,0,1))) - ''' return GiacMethods['orthogonal'](self,*args) @@ -11920,14 +10971,13 @@ cdef class GiacMethods_base: Help for osculating_circle: osculating_circle(Curve,Point) Osculating circle at point M to the curve C. - See also: 1/ curvature 2/ evolute + See also: 1/ curvature 2/ evolute Ex1:osculating_circle(plot(x^2),point(1,1)) Ex2:osculating_circle([5*cos(t),5*sin(t)],t,0) Ex3:osculating_circle([t,t^2],t) Ex4:osculating_circle([t,t^2],t,1) Ex5:osculating_circle([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t) Ex6:osculating_circle([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t,7) - ''' return GiacMethods['osculating_circle'](self,*args) @@ -11936,9 +10986,8 @@ cdef class GiacMethods_base: Help for p1oc2: p1oc2(Permut,Cycle) Returns the permutation product of p1 and c2. - See also: 1/ c1op2 2/ p1op2 + See also: 1/ c1op2 2/ p1op2 Ex1:p1oc2([0,2,1],[2,1,3]) - ''' return GiacMethods['p1oc2'](self,*args) @@ -11947,9 +10996,8 @@ cdef class GiacMethods_base: Help for p1op2: p1op2(Permut,Permut) Returns the permutation product of p1 and p2. - See also: 1/ c1op2 2/ p1oc2 + See also: 1/ c1op2 2/ p1oc2 Ex1:p1op2([0,2,1],[1,0,3,2]) - ''' return GiacMethods['p1op2'](self,*args) @@ -11961,7 +11009,6 @@ cdef class GiacMethods_base: Ex1:pa2b2(17) Ex2:pa2b2(209) Ex3:pa2b2(229) - ''' return GiacMethods['pa2b2'](self,*args) @@ -11970,9 +11017,8 @@ cdef class GiacMethods_base: Help for pade: pade(Expr(Xpr), Var(x), (Intg(n) || Poly(N)), Intg(p)) Pade approximation P/Q=Xpr mod x^(n+1) or mod N with degree(P)3,x^20 (by default a=1) to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ bartlett_hann_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ bartlett_hann_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(poisson_window(randvector(1000,0..1),0.5)) - ''' return GiacMethods['poisson_window'](self,*args) @@ -12932,10 +11905,9 @@ cdef class GiacMethods_base: Help for polar: polar(Crcle,Pnt or Cplxe(A)) Returns the line of the conjugated points of A with respect to the circle. - See also: 1/ pole 2/ is_conjugate + See also: 1/ pole 2/ is_conjugate Ex1:polar(circle(0,1),point(1+i)/2) Ex2:polar(circle(0,1),point(1+i)) - ''' return GiacMethods['polar'](self,*args) @@ -12944,12 +11916,11 @@ cdef class GiacMethods_base: Help for polar_coordinates: polar_coordinates(Pnt or Cplx or LstRectCoord) Returns the list of the norm and of the argument of the affix of a point (for 2D) or of a complex number or of the list of rectangular coordinates. - See also: 1/ abscissapoint 2/ ordinate 3/ rectangular_coordinates 4/ polar_point + See also: 1/ abscissapoint 2/ ordinate 3/ rectangular_coordinates 4/ polar_point Ex1:polar_coordinates(point(1+2*i)) Ex2:polar_coordinates(-1-i) Ex3:polar_coordinates([-1,2]) Ex4:polar_coordinates(point(1+2*i)-point(-1+i)) - ''' return GiacMethods['polar_coordinates'](self,*args) @@ -12958,10 +11929,9 @@ cdef class GiacMethods_base: Help for polar_point: polar_point(Real(r),Real(t)) Returns the point (for 2D) with the arguments r and t as polar coordinates (i.e. with r*exp(i*t) as affix). - See also: 1/ abscissa 2/ ordinate 3/ polar_coordinates 4/ rectangular_coordinates 5/ point + See also: 1/ abscissa 2/ ordinate 3/ polar_coordinates 4/ rectangular_coordinates 5/ point Ex1:polar_point(1,pi/4) Ex2:polar_point(2,-pi/3) - ''' return GiacMethods['polar_point'](self,*args) @@ -12970,10 +11940,9 @@ cdef class GiacMethods_base: Help for polarplot: polarplot(Expr,Var,VarMin,VarMax) plotpolar(f(x),x,a,b) draws the polar curve r=f(x) for x in [a,b]. - See also: 1/ plotparam 2/ plotfunc 3/ plotpolar + See also: 1/ plotparam 2/ plotfunc 3/ plotpolar Ex1:polarplot(sin(2*x),x,0,pi) Ex2:polarplot(sin(2*x),x,0,pi,tstep=0.1) - ''' return GiacMethods['polarplot'](self,*args) @@ -12982,10 +11951,9 @@ cdef class GiacMethods_base: Help for pole: pole(Crcle,Line) Returns the point having the line as polar with respect to the circle . - See also: 1/ polar 2/ is_conjugate + See also: 1/ polar 2/ is_conjugate Ex1:pole(circle(0,1),line(i,1)) Ex2:pole(circle(0,1),line((1+i),2)) - ''' return GiacMethods['pole'](self,*args) @@ -12994,12 +11962,11 @@ cdef class GiacMethods_base: Help for poly2symb: poly2symb(Lst,Var) Gives the polynomial (or its value) : the first argument is the vector of coefficients and the second argument is the variable (by default x). - See also: 1/ e2r 2/ symb2poly + See also: 1/ e2r 2/ symb2poly Ex1:poly2symb([1,2,3]) Ex2:poly2symb([1,2,3],x) Ex3:poly2symb([1,2,3],-1) Ex4:poly2symb([1,2,-1],y) - ''' return GiacMethods['poly2symb'](self,*args) @@ -13008,10 +11975,9 @@ cdef class GiacMethods_base: Help for polyEval: polyEval(Vect,Real(x0)) Evaluates at a point x0, a polynomial given by its coefficients. - See also: 1/ proot 2/ pcoeff + See also: 1/ proot 2/ pcoeff Ex1:polyEval([1,0,-2],1) Ex2:polyEval([1,2,-25,-26,120],8) - ''' return GiacMethods['polyEval'](self,*args) @@ -13020,10 +11986,9 @@ cdef class GiacMethods_base: Help for polygon: polygon(LstPnt||LstCplx) Returns and draws the polygon where its vertices are the elements of l. - See also: 1/ isopolygon 2/ quadrilateral 3/ convexhull 4/ hexagon + See also: 1/ isopolygon 2/ quadrilateral 3/ convexhull 4/ hexagon Ex1:polygon(i,1+i,2-i,-1,-1+i/2) Ex2:polygon(point(0,0,0),point(3,3,3),point(0,0,3),point(3,0,0)) - ''' return GiacMethods['polygon'](self,*args) @@ -13032,11 +11997,10 @@ cdef class GiacMethods_base: Help for polygone_rempli: polygone_rempli(Intg(n)) The argument is an integer <-1 which gives the number of previous turtle positions drawing a polygon and created this full polygon. - See also: 1/ + See also: 1/ Ex1: repete(4,avance 40,tourne_droite);polygone_rempli -8 Ex2: repete(3,avance 40,tourne_droite 120);polygone_rempli -6 Ex3: repete(3,avance 40,avance 40,tourne_droite 120);polygone_rempli -9 - ''' return GiacMethods['polygone_rempli'](self,*args) @@ -13045,9 +12009,8 @@ cdef class GiacMethods_base: Help for polygonplot: polygonplot(Mtrx) Draws the polygons joining for j fixed and for k=0..nrows, the points (xk,yk) where xk=element row k column 0 and yk=element row k column j, after the xk are sorted (we obtain ncols-1 polygons). - See also: 1/ scatterplot 2/ listplot 3/ polygonscatterplot + See also: 1/ scatterplot 2/ listplot 3/ polygonscatterplot Ex1:polygonplot([[1,2,3],[2,0,1],[-1,2,3]]) - ''' return GiacMethods['polygonplot'](self,*args) @@ -13056,9 +12019,8 @@ cdef class GiacMethods_base: Help for polygonscatterplot: polygonscatterplot(Mtrx) Draws the points (xk,yk) and the polygons joining for j fixed and for k=0..nrows, the points (xk,yk) where xk=element row k column 0 et yk=element row k column j, after the xk are sorted (we obtain ncols-1 polygons). - See also: 1/ scatterplot 2/ polygonplot 3/ listplot + See also: 1/ scatterplot 2/ polygonplot 3/ listplot Ex1:polygonscatterplot([[1,2,3],[2,0,1],[-1,2,3]]) - ''' return GiacMethods['polygonscatterplot'](self,*args) @@ -13067,9 +12029,8 @@ cdef class GiacMethods_base: Help for polyhedron: polyhedron(SeqPnt(A,B,C...)) Draws a convex polyhedron with vertices among the arguments. - See also: 1/ cube 2/ parallelepiped + See also: 1/ cube 2/ parallelepiped Ex1:polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6]) - ''' return GiacMethods['polyhedron'](self,*args) @@ -13078,13 +12039,12 @@ cdef class GiacMethods_base: Help for polynom: polynom(Opt) Option of the convert or convertir command and of the taylor and series commands (list=>n-poly or series=>poly). - See also: 1/ poly2symb 2/ taylor 3/ series 4/ convert + See also: 1/ poly2symb 2/ taylor 3/ series 4/ convert Ex1: convert([[10,[3,1]],[12,[2,2]]],polynom) Ex2: convert(taylor(sin(x)),polynom) Ex3: convert(series(sin(x),x=0,6),polynom) Ex4: taylor(sin(x),x=0,5,polynom) Ex5: series(sin(x),x=0,6,,polynom) - ''' return GiacMethods['polynom'](self,*args) @@ -13093,11 +12053,10 @@ cdef class GiacMethods_base: Help for polynomial_regression: polynomial_regression(Lst||Mtrx(A),[Lst],Intg(n)) Returns the coefficients (an,...a1,a0) of y=an*x^n+..a1x+a0 : it is the best polynomial which approx the points where the coordinates are the rows of A (or the 2 lists) (n is the 2nd argument). - See also: 1/ linear_regression 2/ power_regression + See also: 1/ linear_regression 2/ power_regression Ex1:polynomial_regression([[1.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]],3) Ex2:polynomial_regression([[0.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]],3) Ex3:polynomial_regression([0.0,2.0,3.0,4.0],[1.0,4.0,9.0,16.0],3) - ''' return GiacMethods['polynomial_regression'](self,*args) @@ -13106,11 +12065,10 @@ cdef class GiacMethods_base: Help for polynomial_regression_plot: polynomial_regression_plot(Lst||Mtrx(A),[Lst],Intg(n)) Returns the plot of y=an*x^n+..a1x+a0 : it is the best polynomial which approx the points where the coordinates are the rows of A (or the 2 lists) (n is the 2nd argument). - See also: 1/ linear_regression_plot 2/ power_regression_plot + See also: 1/ linear_regression_plot 2/ power_regression_plot Ex1:polynomial_regression_plot([[1.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]],3) Ex2:polynomial_regression_plot([[0.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]],3) Ex3:polynomial_regression_plot([0.0,2.0,3.0,4.0],[1.0,4.0,9.0,16.0],3) - ''' return GiacMethods['polynomial_regression_plot'](self,*args) @@ -13119,11 +12077,10 @@ cdef class GiacMethods_base: Help for position: position(NULL or LstCoord) Returns the turtle position in pixels or puts the turtle at the position given by the argument with the same direction. - See also: 1/ cap 2/ initialise + See also: 1/ cap 2/ initialise Ex1:position() Ex2:position(50,70) Ex3:position([50,70]) - ''' return GiacMethods['position'](self,*args) @@ -13132,9 +12089,8 @@ cdef class GiacMethods_base: Help for poslbdLMQ: poslbdLMQ(Poly(P)) Returns a lower bound on the values of the positive roots of P. Akritas-Strzebonski-Vigklas' Local Max Quadratic (LMQ) method is used. - See also: 1/ posubLMQ 2/ VAS_positive 3/ realroot + See also: 1/ posubLMQ 2/ VAS_positive 3/ realroot Ex1:poslbdLMQ(x^3-7*x+7) - ''' return GiacMethods['poslbdLMQ'](self,*args) @@ -13143,9 +12099,8 @@ cdef class GiacMethods_base: Help for posubLMQ: posubLMQ(Poly(P)) Returns an upper bound on the values of the positive roots of P. Akritas-Strzebonski-Vigklas' Local Max Quadratic (LMQ) method is used. - See also: 1/ poslbdLMQ 2/ VAS_positive 3/ realroot + See also: 1/ poslbdLMQ 2/ VAS_positive 3/ realroot Ex1:posubLMQ(x^3-7*x+7) - ''' return GiacMethods['posubLMQ'](self,*args) @@ -13154,9 +12109,8 @@ cdef class GiacMethods_base: Help for potential: potential(Vect(V),VectVar) Returns U such that derive(U,Vector_of_variable)=V. - See also: 1/ derive 2/ vpotential + See also: 1/ derive 2/ vpotential Ex1:potential([2*x*y+3,x^2-4*z,-4*y],[x,y,z]) - ''' return GiacMethods['potential'](self,*args) @@ -13165,9 +12119,8 @@ cdef class GiacMethods_base: Help for pow2exp: pow2exp(Expr) Converts powers to exponentials. - See also: 1/ exp2pow + See also: 1/ exp2pow Ex1:pow2exp(a^b) - ''' return GiacMethods['pow2exp'](self,*args) @@ -13176,11 +12129,10 @@ cdef class GiacMethods_base: Help for power_regression: power_regression(Lst|Mtrx(A),[Lst]) Returns the coefficients (m,b) of y=b*x^m : it is the best monomial which approx the points where the coordinates are the rows of A (or the 2 lists). - See also: 1/ polynomial_regression 2/ linear_regressiont + See also: 1/ polynomial_regression 2/ linear_regressiont Ex1:power_regression([[1.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]]) Ex2:power_regression([[1.0,2.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]]) Ex3:power_regression([1.0,2.0,3.0,4.0],[2.0,4.0,9.0,16.0]) - ''' return GiacMethods['power_regression'](self,*args) @@ -13189,11 +12141,10 @@ cdef class GiacMethods_base: Help for power_regression_plot: power_regression_plot(Lst||Mtrx(A),[Lst]) Returns the plot of y=b*x^m : it is the best monomial which approx the points where the coordinates are the rows of A (or the 2 lists). - See also: 1/ polynomial_regression_plot 2/ linear_regression_plot + See also: 1/ polynomial_regression_plot 2/ linear_regression_plot Ex1:power_regression_plot([[1.0,1.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]]) Ex2:power_regression_plot([[1.0,2.0],[2.0,4.0],[3.0,9.0],[4.0,16.0]]) Ex3:power_regression_plot([1.0,2.0,3.0,4.0],[2.0,4.0,9.0,16.0]) - ''' return GiacMethods['power_regression_plot'](self,*args) @@ -13202,10 +12153,9 @@ cdef class GiacMethods_base: Help for powermod: powermod(Intg(a),Intg(n),Intg(p),[Expr(P(x))],[Var]) Computes a^n modulo p or modulo p,P(x) (fast algorithm). - See also: 1/ pow 2/ ^ + See also: 1/ pow 2/ ^ Ex1:powermod(17,452,19) Ex2:powermod(x+1,452,19,x^4+x+1,x) - ''' return GiacMethods['powermod'](self,*args) @@ -13214,10 +12164,9 @@ cdef class GiacMethods_base: Help for powerpc: powerpc(Cercle,Pnt or Cplx) Returns the real number d^2-R^2 (d=distance between point and center, R=radius). - See also: 1/ radical_axis + See also: 1/ radical_axis Ex1:powerpc(circle(0,1+i),3+i) Ex2:powerpc(circle(0,point(1+i)),3+i) - ''' return GiacMethods['powerpc'](self,*args) @@ -13226,10 +12175,9 @@ cdef class GiacMethods_base: Help for powexpand: powexpand(Expr) Expands the expression as a function of the exponent. - See also: 1/ + See also: 1/ Ex1:powexpand(2^(x+y)) Ex2:powexpand(3^(2*x)) - ''' return GiacMethods['powexpand'](self,*args) @@ -13238,10 +12186,9 @@ cdef class GiacMethods_base: Help for powmod: powmod(Intg(a),Intg(n),Intg(p),[Expr(P(x))],[Var]) Computes a^n modulo p or modulo p,P(x) (fast algorithm). - See also: 1/ pow 2/ ^ + See also: 1/ pow 2/ ^ Ex1:powmod(17,452,19) Ex2:powmod(x+1,452,19,x^4+x+1,x) - ''' return GiacMethods['powmod'](self,*args) @@ -13250,14 +12197,13 @@ cdef class GiacMethods_base: Help for prepend: prepend(Lst||Set||Str(L),Elem(n)) Adds an element to a set or at the beginning of a list or of a string (L:=prepend(L,a) or L.prepend(a)). - See also: 1/ append 2/ concat + See also: 1/ append 2/ concat Ex1:prepend([1,2],3) Ex2:prepend(set[1,2],3) Ex3: L:=[1,2];L:=prepend(L,3) - Ex4: L:=[1,2];L.prepend(L,3) + Ex4: L:=[1,2];L.prepend(L,3) Ex5: S:=set[1,2];S:=prepend(L,3) Ex6: S:=set[1,2];S.prepend(L,3) - ''' return GiacMethods['prepend'](self,*args) @@ -13266,12 +12212,11 @@ cdef class GiacMethods_base: Help for preval: preval(Expr(F(Var)),Real(a),Real(b),[Var]) Returns F(b)-F(a). - See also: 1/ subst 2/ int + See also: 1/ subst 2/ int Ex1:preval(x^2-2,2,3) Ex2:preval(y^2-2,2,3,y) Ex3:preval(int(x),0,1) Ex4:preval(int(y,y),0,1,y) - ''' return GiacMethods['preval'](self,*args) @@ -13280,10 +12225,9 @@ cdef class GiacMethods_base: Help for prevperm: prevperm(Intg(n)) Returns the previous permutation with the lexicographic order. - See also: 1/ nextperm 2/ is_permu + See also: 1/ nextperm 2/ is_permu Ex1:prevperm([0,1,3,2]) Ex2:prevperm([0,1,2,3]) - ''' return GiacMethods['prevperm'](self,*args) @@ -13292,10 +12236,9 @@ cdef class GiacMethods_base: Help for prevprime: prevprime(Intg(a)) Previous prime or pseudo-prime before a given integer a. - See also: 1/ nextprime 2/ is_prime 3/ ithprime + See also: 1/ nextprime 2/ is_prime 3/ ithprime Ex1:prevprime(9856989898999) Ex2:prevprime(97160249868928888261606009) - ''' return GiacMethods['prevprime'](self,*args) @@ -13304,10 +12247,9 @@ cdef class GiacMethods_base: Help for primpart: primpart(Poly(P),[Var]) Returns the polynomial P divided by the gcd of its coefficients. - See also: 1/ content + See also: 1/ content Ex1:primpart(2x^2+10x+6) Ex2:primpart(2t^2+10t+6,t) - ''' return GiacMethods['primpart'](self,*args) @@ -13316,10 +12258,9 @@ cdef class GiacMethods_base: Help for printf: printf(Expr) 2d printing. - See also: 1/ print + See also: 1/ print Ex1:printf(sqrt(2)) Ex2:printf("%gen+%gen=%gen",a,b,a+b) - ''' return GiacMethods['printf'](self,*args) @@ -13328,9 +12269,8 @@ cdef class GiacMethods_base: Help for prism: prism(LstPnt([A,B,C,D]),Pnt(A1)) Draws a prism with plane base ABCD...and with edges parallel to AA1 (the faces are parallelograms). - See also: 1/ cube 2/ polyhedron + See also: 1/ cube 2/ polyhedron Ex1:prism([[0,0,0],[5,0,0],[0,5,0],[-5,5,0]],[0,0,5]) - ''' return GiacMethods['prism'](self,*args) @@ -13339,9 +12279,8 @@ cdef class GiacMethods_base: Help for prism_graph: prism_graph(Intg(n)) Returns the generalized Petersen graph GP(n,1). - See also: 1/ antiprism_graph 2/ web_graph + See also: 1/ antiprism_graph 2/ web_graph Ex1:prism_graph(5) - ''' return GiacMethods['prism_graph'](self,*args) @@ -13350,7 +12289,7 @@ cdef class GiacMethods_base: Help for product: product(Expr||Lst,[Var||Lst],[Intg(a)],[Intg(b)],[Intg(p)]) Multiplies the values of the expression when the variable go from a to b with a step p (product(expression,var,begin,end,step) by default p=1) or product of the elements of a list or product element by element of 2 lists or matrices. - See also: 1/ sum + See also: 1/ sum Ex1:product(n,n,1,10,2) Ex2:product(1/n,n,1,10) Ex3:product(1/n,n,11,1) @@ -13358,7 +12297,6 @@ cdef class GiacMethods_base: Ex5:product([2,3,4,5]) Ex6:product([2,3,4],[5,6,7]) Ex7:product([[2,3,4],[5,6,7]],[[2,3,4],[5,6,7]]) - ''' return GiacMethods['product'](self,*args) @@ -13367,11 +12305,10 @@ cdef class GiacMethods_base: Help for projection: projection(Curve,Pnt) projection(C,A) is the orthogonal projection of A on the curve C. - See also: 1/ perpendicular + See also: 1/ perpendicular Ex1: H:=projection(line(i,1-i),1+i) Ex2: K:=projection(circle(0,1),1+i) Ex3: J:=projection(circle(0,1),point(1+2*i)) - ''' return GiacMethods['projection'](self,*args) @@ -13380,12 +12317,11 @@ cdef class GiacMethods_base: Help for proot: proot(Vect||Poly,[Intg(n)]) Returns all computed roots of a polynomial given by its coefficients (may not work if roots are not simple). - See also: 1/ pcoeff 2/ peval 3/ realroot 4/ complexroot 5/ rationalroot 6/ crationalroot + See also: 1/ pcoeff 2/ peval 3/ realroot 4/ complexroot 5/ rationalroot 6/ crationalroot Ex1:proot([1,0,-2]) Ex2:proot(x^2-2) Ex3:proot([1,2,-25,-26,120]) Ex4:proot(x^4+5x-3,30) - ''' return GiacMethods['proot'](self,*args) @@ -13394,10 +12330,9 @@ cdef class GiacMethods_base: Help for propFrac: propFrac(Frac or RatFrac) Simplifies and writes the fraction (or rational fraction) A/B as Q+R/B with R=0 or, the (-n)th previous question if n<0 (by default n=-1 for the previous question). - See also: 1/ ans + See also: 1/ ans Ex1:quest() Ex2:quest(2) Ex3:quest(-2) - ''' return GiacMethods['quest'](self,*args) @@ -13604,11 +12523,10 @@ cdef class GiacMethods_base: Help for quo: quo((Vect or Poly),(Vect or Poly),[Var]) Euclidean quotient of 2 polynomials. - See also: 1/ rem 2/ quorem 3/ Quo 4/ iquo + See also: 1/ rem 2/ quorem 3/ Quo 4/ iquo Ex1:quo([1,2,3,4],[-1,2]) Ex2:quo(x^3+2x^2+3x+4,-x+2) Ex3:quo(t^3+2t^2+3t+4,-t+2,t) - ''' return GiacMethods['quo'](self,*args) @@ -13617,12 +12535,11 @@ cdef class GiacMethods_base: Help for quorem: quorem((Vect or Poly),(Vect or Poly),[Var]) Euclidean quotient and remainder of 2 polynomials. - See also: 1/ rem 2/ quo 3/ iquorem + See also: 1/ rem 2/ quo 3/ iquorem Ex1:quorem([1,2,3,4],[-1,2]) Ex2:quorem(x^3+2x^2+3x+4,-x+2) Ex3:quorem(t^3+2t^2+3t+4,-t+2,t) Ex4:quorem(t^4-1,(t+1)^2,t) - ''' return GiacMethods['quorem'](self,*args) @@ -13631,11 +12548,10 @@ cdef class GiacMethods_base: Help for quote: quote(Expr) Returns its argument unevaluated (and also a:=quote(a) purges a). - See also: 1/ + See also: 1/ Ex1:quote(1+2) Ex2:quote(1/x+1/(x-1)) Ex3:quote((x+1)*(x-1)) - ''' return GiacMethods['quote'](self,*args) @@ -13644,12 +12560,11 @@ cdef class GiacMethods_base: Help for r2e: r2e(Lst,Var) Gives the polynomial (or its value) : the first argument is the vector of coefficients and the second argument is the variable (by default x). - See also: 1/ e2r 2/ symb2poly + See also: 1/ e2r 2/ symb2poly Ex1:r2e([1,2,3]) Ex2:r2e([1,2,3],x) Ex3:r2e([1,2,3],-1) Ex4:r2e([1,2,-1],y) - ''' return GiacMethods['r2e'](self,*args) @@ -13658,10 +12573,9 @@ cdef class GiacMethods_base: Help for radical_axis: radical_axis(Crcle,Crcle) Returns the line of points with same powerpc with respect to the 2 circles. - See also: 1/ powerpc + See also: 1/ powerpc Ex1:radical_axis(circle(0,1+i),circle(1,1+i)) Ex2:radical_axis(circle(0,point(1+i)),circle(1,point(1+i))) - ''' return GiacMethods['radical_axis'](self,*args) @@ -13670,9 +12584,8 @@ cdef class GiacMethods_base: Help for radius: radius(Crcle) radius(C) gives the radius of the circle C. - See also: 1/ center 2/ circle + See also: 1/ center 2/ circle Ex1:radius(incircle(-1,1-i,i)) - ''' return GiacMethods['radius'](self,*args) @@ -13681,9 +12594,8 @@ cdef class GiacMethods_base: Help for ramene: ramene(Str(fich_name)) Reads variables and their values from the file fich_name. - See also: 1/ write 2/ readrgb 3/ readwav 4/ csv2gen + See also: 1/ write 2/ readrgb 3/ readwav 4/ csv2gen Ex1:ramene("toto") - ''' return GiacMethods['ramene'](self,*args) @@ -13692,7 +12604,7 @@ cdef class GiacMethods_base: Help for rand: rand(Intg(n) or Interval(p..n) or NULL,[Intg(b1) or Lst(L)],[Intg(b2)]) rand(n)=a random integer (resp rand(p,n)=a real or rand(p..n)=a real function) with uniform distribution in 0..n-1 (resp in [p;n])(rand()=rand(0,1)=a real in [0,1[) or rand(n,b1,b2)=n integers between b1 and b2 or rand(n,L)=list of n elements of L. - See also: 1/ srand 2/ randpoly 3/ ranm 4/ randvector 5/ hasard + See also: 1/ srand 2/ randpoly 3/ ranm 4/ randvector 5/ hasard Ex1:rand(4) Ex2:rand() Ex3:rand(0,2) @@ -13704,7 +12616,6 @@ cdef class GiacMethods_base: Ex9: L:=["r","r","r","b","n"];L3:=L.rand(3) Ex10: L:=["r","r","r","b","n"];a:=rand(L) Ex11: L:=["r","r","r","b","n"];a:=L.rand() - ''' return GiacMethods['rand'](self,*args) @@ -13713,7 +12624,7 @@ cdef class GiacMethods_base: Help for randMat: randMat(Intg(n), [Intg(m)],[Interval or quote(DistribLaw)]) Returns a list of size n or an n*m matrix that contains random integers in the range -99 through 99 with uniform distribution or contains random numbers according to the law put between quotes. - See also: 1/ idn 2/ randPoly 3/ rand 4/ randvector + See also: 1/ idn 2/ randPoly 3/ rand 4/ randvector Ex1:randMat(3) Ex2:randMat(3,2) Ex3:randMat(3,2,6) @@ -13727,7 +12638,6 @@ cdef class GiacMethods_base: Ex11:randMat(3,2,1..2) Ex12:randMat(3,5,multinomial,[1/2,1/3,1/6],["R","V","B"]) Ex13: GF(2,8,g);ranm(3,3,g) - ''' return GiacMethods['randMat'](self,*args) @@ -13736,10 +12646,9 @@ cdef class GiacMethods_base: Help for randNorm: randNorm(Real(mu),Real(sigma)) Returns a random real with normal distribution N(mu,sigma). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randpoisson 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randpoisson 8/ randgeometric 9/ randmultinomial Ex1:randNorm(0,1) Ex2:randNorm(2,1) - ''' return GiacMethods['randNorm'](self,*args) @@ -13748,14 +12657,13 @@ cdef class GiacMethods_base: Help for randPoly: randPoly([Var(Var)],Intg(n),[law]) Returns a polynomial with variable var (or x), of degree n and where the coefficients are random integers in the range -99 through 99 with uniform distribution or according to a law. - See also: 1/ ranm 2/ randvector + See also: 1/ ranm 2/ randvector Ex1:randPoly(5) Ex2:randPoly(t,8) Ex3:randPoly(t,8,-1..1) Ex4:randPoly([x,y],[10,3]) Ex5:randPoly([x,y],[10,3],1 mod 7) Ex6: GF(2,8,g);randpoly(t,8,g);randpoly([x,y],[2,3],g) - ''' return GiacMethods['randPoly'](self,*args) @@ -13764,10 +12672,9 @@ cdef class GiacMethods_base: Help for randbetad: randbetad(Real(a),Real(b)) Returns a random real according to the Beta distribution with parameters a>0 and b>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:randbetad(1,2) Ex2:randbetad(1.5,4) - ''' return GiacMethods['randbetad'](self,*args) @@ -13776,10 +12683,9 @@ cdef class GiacMethods_base: Help for randbinomial: randbinomial(Intg(n),Real(p)) Returns a random integer with binomial distribution B(n,p) i.e. the number of successes in n independant tests where for each test, the success of probability is p. - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randnorm 7/ randpoisson 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randnorm 7/ randpoisson 8/ randgeometric 9/ randmultinomial Ex1:randbinomial(10,0.4) Ex2:randbinomial(100,0.8) - ''' return GiacMethods['randbinomial'](self,*args) @@ -13788,10 +12694,9 @@ cdef class GiacMethods_base: Help for randchisquare: randchisquare(Intg(n)) Returns a random integer with chi^2 distribution, χ^2(n). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial Ex1:randchisquare(5) Ex2:randchisquare(2) - ''' return GiacMethods['randchisquare'](self,*args) @@ -13800,10 +12705,9 @@ cdef class GiacMethods_base: Help for randexp: randexp(Real(a)) Returns a random real according to the exponential distribution with parameter a>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:randexp(1) Ex2:randexp(2) - ''' return GiacMethods['randexp'](self,*args) @@ -13812,10 +12716,9 @@ cdef class GiacMethods_base: Help for randfisher: randfisher(Intg(n),Intg(m)) Returns a random integer with Fisher-Snedecor distribution F(n,m). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial Ex1:randfisher(5,2) Ex2:randfisher(2,4) - ''' return GiacMethods['randfisher'](self,*args) @@ -13824,10 +12727,9 @@ cdef class GiacMethods_base: Help for randgammad: randgammad(Real(a),Real(b)) Returns a random real according to the Gamma distribution with parameters a>0 and b>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:randgammad(1,2) Ex2:randgammad(1.5,4) - ''' return GiacMethods['randgammad'](self,*args) @@ -13836,9 +12738,8 @@ cdef class GiacMethods_base: Help for randgeometric: randgeometric(Real(p)) Returns a random integer following the geometric distribution with parameter p. - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randnorm 7/ randpoisson 8/ randbinomial 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randnorm 7/ randpoisson 8/ randbinomial 9/ randmultinomial Ex1:randgeometric(0.4) - ''' return GiacMethods['randgeometric'](self,*args) @@ -13847,10 +12748,9 @@ cdef class GiacMethods_base: Help for randint: randint(Intg(n1),Intg(n2)) randint(n1,n2)=an integer in [n1, n2] or [n2,n1]. - See also: 1/ rand + See also: 1/ rand Ex1:randint(1,10) Ex2:randint(-1,-10) - ''' return GiacMethods['randint'](self,*args) @@ -13859,10 +12759,9 @@ cdef class GiacMethods_base: Help for randmarkov: randmarkov(Mtrx(M) || Vctr(v),Intg(i0),[Intg(n)]) Returns a random sequence of n states (Markov chain) starting from i0, with probability transition matrix M, or returns a stochastic matrix with p recurrent loops v=[n1,..,np] and i0 transient states. - See also: 1/ markov 2/ plotproba + See also: 1/ markov 2/ plotproba Ex1:randmarkov([[0,0,1/2,0,1/2],[0,0,1,0,0],[1/4,1/4,0,1/4,1/4],[0,0,1/2,0,1/2],[0,0,0,0,1]],2,20) Ex2:randmarkov([1,2,1,3],4) - ''' return GiacMethods['randmarkov'](self,*args) @@ -13871,7 +12770,7 @@ cdef class GiacMethods_base: Help for randmatrix: randmatrix(Intg(n), [Intg(m)],[Interval or quote(DistribLaw)]) Returns a list of size n or an n*m matrix that contains random integers in the range -99 through 99 with uniform distribution or contains random numbers according to the law put between quotes. - See also: 1/ idn 2/ randPoly 3/ rand 4/ randvector + See also: 1/ idn 2/ randPoly 3/ rand 4/ randvector Ex1:randmatrix(3) Ex2:randmatrix(3,2) Ex3:randmatrix(3,2,6) @@ -13885,7 +12784,6 @@ cdef class GiacMethods_base: Ex11:randmatrix(3,2,1..2) Ex12:randmatrix(3,5,multinomial,[1/2,1/3,1/6],["R","V","B"]) Ex13: GF(2,8,g);ranm(3,3,g) - ''' return GiacMethods['randmatrix'](self,*args) @@ -13894,10 +12792,9 @@ cdef class GiacMethods_base: Help for randmultinomial: randmultinomial(List(P),[List(K)]) Returns a random index or list element according to a multinomial distribution probability list P. - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randnorm 7/ randpoisson 8/ randgeometric 9/ randbinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randnorm 7/ randpoisson 8/ randgeometric 9/ randbinomial Ex1:randmultinomial([1/2,1/3,1/6]) Ex2:randmultinomial([1/2,1/3,1/6],["R","V","B"]) - ''' return GiacMethods['randmultinomial'](self,*args) @@ -13906,10 +12803,9 @@ cdef class GiacMethods_base: Help for randnorm: randnorm(Real(mu),Real(sigma)) Returns a random real with normal distribution N(mu,sigma). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randpoisson 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randpoisson 8/ randgeometric 9/ randmultinomial Ex1:randnorm(0,1) Ex2:randnorm(2,1) - ''' return GiacMethods['randnorm'](self,*args) @@ -13918,7 +12814,7 @@ cdef class GiacMethods_base: Help for random: random(Intg(n) or Interval(p..n) or NULL,[Intg(b1) or Lst(L)],[Intg(b2)]) rand(n)=a random integer (resp rand(p,n)=a real or rand(p..n)=a real function) with uniform distribution in 0..n-1 (resp in [p;n])(rand()=rand(0,1)=a real in [0,1[) or rand(n,b1,b2)=n integers between b1 and b2 or rand(n,L)=list of n elements of L. - See also: 1/ srand 2/ randpoly 3/ ranm 4/ randvector 5/ hasard + See also: 1/ srand 2/ randpoly 3/ ranm 4/ randvector 5/ hasard Ex1:random(4) Ex2:random() Ex3:random(0,2) @@ -13930,7 +12826,6 @@ cdef class GiacMethods_base: Ex9: L:=["r","r","r","b","n"];L3:=L.rand(3) Ex10: L:=["r","r","r","b","n"];a:=rand(L) Ex11: L:=["r","r","r","b","n"];a:=L.rand() - ''' return GiacMethods['random'](self,*args) @@ -13939,10 +12834,9 @@ cdef class GiacMethods_base: Help for random_bipartite_graph: random_bipartite_graph(Intg(n)||Lst(a,b),Real(p)||Intg(m)) Returns a random undirected unweighted bipartite graph with n vertices where each possible edge is present with probability p or where m edges are created at random. When the first argument is list [a,b] of integers, two groups of vertices with sizes a and b are created. - See also: 1/ random_digraph 2/ random_graph 3/ random_planar_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree + See also: 1/ random_digraph 2/ random_graph 3/ random_planar_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree Ex1:random_bipartite_graph(10,0.5) Ex2:random_bipartite_graph([2,3],1.0) - ''' return GiacMethods['random_bipartite_graph'](self,*args) @@ -13951,10 +12845,9 @@ cdef class GiacMethods_base: Help for random_digraph: random_digraph(Intg(n)||Lst(V),Real(p)||Intg(m)) Returns a random directed unweighted graph with n vertices (list V of labels may me specified) where two vertices are connected with probability p or where m edges are created at random. - See also: 1/ random_bipartite_graph 2/ random_graph 3/ random_planar_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree + See also: 1/ random_bipartite_graph 2/ random_graph 3/ random_planar_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree Ex1:random_digraph(8,0.5) Ex2:random_digraph(8,10) - ''' return GiacMethods['random_digraph'](self,*args) @@ -13963,10 +12856,9 @@ cdef class GiacMethods_base: Help for random_graph: random_graph(Intg(n)||Lst(V),Real(p)||Intg(m)) Returns a random undirected unweighted graph with n vertices (list V of labels may be specified) where two vertices are connected with probability p or where m edges are created at random. - See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_planar_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree + See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_planar_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree Ex1:random_graph(8,0.5) Ex2:random_graph(8,10) - ''' return GiacMethods['random_graph'](self,*args) @@ -13975,11 +12867,10 @@ cdef class GiacMethods_base: Help for random_network: random_network(Intg(a),Intg(b),[Real(p)],[opts]) Returns a random network with b grid frames of size a*a in which every edge appears with the probability p (by default 0.5). - See also: 1/ is_network 2/ maxflow + See also: 1/ is_network 2/ maxflow Ex1:random_network(3,3) Ex2:random_network(3,3,acyclic) Ex3:random_network(3,4,0.75) - ''' return GiacMethods['random_network'](self,*args) @@ -13988,8 +12879,7 @@ cdef class GiacMethods_base: Help for random_planar_graph: random_planar_graph(Intg(n)||Lst(V),Real(p),[Intg(c)]) Returns a random planar graph with n vertices, which can also be specified as a list V of their labels, obtained by trying to remove each edge of a random triangulated graph with probability 0<=p<1 [c is connectivity level : 0 - any, 1 - connected, 2 - biconnected, 3 - triconnected (by default, c=1)]. - See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree - + See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_regular_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree ''' return GiacMethods['random_planar_graph'](self,*args) @@ -13998,9 +12888,8 @@ cdef class GiacMethods_base: Help for random_regular_graph: random_regular_graph(Intg(n)||Lst(V),Intg(d),[connected]) Returns a random d-regular graph with n vertices, which may be specified as list V of their labels. - See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree + See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree Ex1:random_regular_graph(100,80,connected) - ''' return GiacMethods['random_regular_graph'](self,*args) @@ -14009,9 +12898,8 @@ cdef class GiacMethods_base: Help for random_sequence_graph: random_sequence_graph(Lst(L)) Returns a random undirected graph with degree sequence L. - See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree + See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_sequence_graph 6/ random_tournament 7/ random_tree Ex1:random_sequence_graph([1,3,3,2,1,2,2,2,3,3]) - ''' return GiacMethods['random_sequence_graph'](self,*args) @@ -14020,9 +12908,8 @@ cdef class GiacMethods_base: Help for random_tournament: random_tournament(Intg(n)||Lst(V)) Returns a random tournament graph with n vertices, which may be specified as list V of their labels. - See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_regular_graph 6/ random_sequence_graph 7/ random_tree + See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_regular_graph 6/ random_sequence_graph 7/ random_tree Ex1:random_tournament(5) - ''' return GiacMethods['random_tournament'](self,*args) @@ -14031,8 +12918,7 @@ cdef class GiacMethods_base: Help for random_tree: random_tree(Intg(n)||Lst(V),[Intg(d)||root[=Vrtx(v)]]) Returns a random tree graph with n vertices, which may be specified as list V of their labels [with the upper bound d (positive integer) for the degree of graph or 'root' for rooted trees]. - See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_regular_graph 6/ random_sequence_graph 7/ random_tournament - + See also: 1/ random_bipartite_graph 2/ random_digraph 3/ random_graph 4/ random_planar_graph 5/ random_regular_graph 6/ random_sequence_graph 7/ random_tournament ''' return GiacMethods['random_tree'](self,*args) @@ -14041,7 +12927,7 @@ cdef class GiacMethods_base: Help for random_variable: random_variable(Lst(W)||Mtrx(M)||Fnc(f),[params]) Returns a random variable from a probability density function f or from list of weights (discrete variable). - See also: 1/ randvector 2/ randmatrix 3/ rand + See also: 1/ randvector 2/ randmatrix 3/ rand Ex1:random_variable(fisher,2,3) Ex2:random_variable([["apple",1/3],["orange",1/4],["pear",1/5],["plum",13/60]]) Ex3:random_variable(k->1-(k/10)^2,range=-10..10) @@ -14052,7 +12938,6 @@ cdef class GiacMethods_base: Ex8:random_variable(weibull,mean=12.5,variance=1) Ex9:random_variable(uniform,mean=10,stddev=2) Ex10:random_variable(uniform,e..pi) - ''' return GiacMethods['random_variable'](self,*args) @@ -14061,13 +12946,12 @@ cdef class GiacMethods_base: Help for randperm: randperm(Intg(n)||Lst(L)) Returns a random permutation of [0,1,2,..,n-1] or of the list L. - See also: 1/ permu2cycles 2/ is_permu 3/ permu2mat + See also: 1/ permu2cycles 2/ is_permu 3/ permu2mat Ex1:randperm(4) Ex2:randperm(7) Ex3:randperm([1,3,5,7,9]) Ex4: L:=[1,3,5,7,9];L:=randperm(L) Ex5: L:=[1,3,5,7,9];L.randperm() - ''' return GiacMethods['randperm'](self,*args) @@ -14076,10 +12960,9 @@ cdef class GiacMethods_base: Help for randpoisson: randpoisson(Real(λ)) Returns a random integer with poisson distribution P(λ). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial Ex1:randpoisson(5.4) Ex2:randpoisson(2.8) - ''' return GiacMethods['randpoisson'](self,*args) @@ -14088,14 +12971,13 @@ cdef class GiacMethods_base: Help for randpoly: randpoly([Var(Var)],Intg(n),[law]) Returns a polynomial with variable var (or x), of degree n and where the coefficients are random integers in the range -99 through 99 with uniform distribution or according to a law. - See also: 1/ ranm 2/ randvector + See also: 1/ ranm 2/ randvector Ex1:randpoly(5) Ex2:randpoly(t,8) Ex3:randpoly(t,8,-1..1) Ex4:randpoly([x,y],[10,3]) Ex5:randpoly([x,y],[10,3],1 mod 7) Ex6: GF(2,8,g);randpoly(t,8,g);randpoly([x,y],[2,3],g) - ''' return GiacMethods['randpoly'](self,*args) @@ -14104,10 +12986,9 @@ cdef class GiacMethods_base: Help for randseed: randseed() srand returns an integer and initializes the sequence of random numbers. - See also: 1/ RandSeed + See also: 1/ RandSeed Ex1:randseed(12) Ex2: srand - ''' return GiacMethods['randseed'](self,*args) @@ -14116,10 +12997,9 @@ cdef class GiacMethods_base: Help for randstudent: randstudent(Intg(n)) Returns a random integer with Student distribution S(n). - See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial + See also: 1/ rand 2/ randpoly 3/ ranm 4/ randvector 5/ randexp 6/ randbinomial 7/ randnorm 8/ randgeometric 9/ randmultinomial Ex1:randstudent(5) Ex2:randstudent(2) - ''' return GiacMethods['randstudent'](self,*args) @@ -14128,7 +13008,7 @@ cdef class GiacMethods_base: Help for randvar: randvar(Lst(W)||Mtrx(M)||Fnc(f),[params]) Returns a random variable from a probability density function f or from list of weights (discrete variable). - See also: 1/ randvector 2/ randmatrix 3/ rand + See also: 1/ randvector 2/ randmatrix 3/ rand Ex1:randvar(fisher,2,3) Ex2:randvar([["apple",1/3],["orange",1/4],["pear",1/5],["plum",13/60]]) Ex3:randvar(k->1-(k/10)^2,range=-10..10) @@ -14139,7 +13019,6 @@ cdef class GiacMethods_base: Ex8:randvar(weibull,mean=12.5,variance=1) Ex9:randvar(uniform,mean=10,stddev=2) Ex10:randvar(uniform,e..pi) - ''' return GiacMethods['randvar'](self,*args) @@ -14148,7 +13027,7 @@ cdef class GiacMethods_base: Help for randvector: randvector(Intg(n), [Intg(m)],[Interval or quote(DistribLaw)]) Returns a list of size n that contains random integers in the range -99 through 99 (or in 0..m-1) with uniform distribution or contains random numbers according to the law put between quotes. - See also: 1/ idn 2/ randPoly 3/ rand 4/ ranm + See also: 1/ idn 2/ randPoly 3/ rand 4/ ranm Ex1:randvector(3) Ex2:randvector(3,6) Ex3:randvector(3,normald,0,1) @@ -14159,7 +13038,6 @@ cdef class GiacMethods_base: Ex8:randvector(3,'rand(3)') Ex9:randvector(3,1..2) Ex10: GF(2,8,g);randvector(3,g) - ''' return GiacMethods['randvector'](self,*args) @@ -14168,10 +13046,9 @@ cdef class GiacMethods_base: Help for randweibulld: randweibulld(Real(a),Real(b)) Returns a random real according to the Weibull distribution with parameters a>0 and b>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:randweibulld(1,2) Ex2:randweibulld(1.5,4) - ''' return GiacMethods['randweibulld'](self,*args) @@ -14180,10 +13057,9 @@ cdef class GiacMethods_base: Help for rank: rank(Mtrx) Returns the rank of the matrix. - See also: 1/ det 2/ image + See also: 1/ det 2/ image Ex1:rank([[1,1,2],[2,1,3],[3,1,4]]) Ex2:rank([[1,1,2],[2,1,3],[3,1,5]]) - ''' return GiacMethods['rank'](self,*args) @@ -14192,7 +13068,7 @@ cdef class GiacMethods_base: Help for ranm: ranm(Intg(n), [Intg(m)],[Interval or quote(DistribLaw)]) Returns a list of size n or an n*m matrix that contains random integers in the range -99 through 99 with uniform distribution or contains random numbers according to the law put between quotes. - See also: 1/ idn 2/ randPoly 3/ rand 4/ randvector + See also: 1/ idn 2/ randPoly 3/ rand 4/ randvector Ex1:ranm(3) Ex2:ranm(3,2) Ex3:ranm(3,2,6) @@ -14206,7 +13082,6 @@ cdef class GiacMethods_base: Ex11:ranm(3,2,1..2) Ex12:ranm(3,5,multinomial,[1/2,1/3,1/6],["R","V","B"]) Ex13: GF(2,8,g);ranm(3,3,g) - ''' return GiacMethods['ranm'](self,*args) @@ -14215,7 +13090,7 @@ cdef class GiacMethods_base: Help for ranv: ranv(Intg(n), [Intg(m)],[Interval or quote(DistribLaw)]) Returns a list of size n that contains random integers in the range -99 through 99 (or in 0..m-1) with uniform distribution or contains random numbers according to the law put between quotes. - See also: 1/ idn 2/ randPoly 3/ rand 4/ ranm + See also: 1/ idn 2/ randPoly 3/ rand 4/ ranm Ex1:ranv(3) Ex2:ranv(3,6) Ex3:ranv(3,normald,0,1) @@ -14226,7 +13101,6 @@ cdef class GiacMethods_base: Ex8:ranv(3,'rand(3)') Ex9:ranv(3,1..2) Ex10: GF(2,8,g);randvector(3,g) - ''' return GiacMethods['ranv'](self,*args) @@ -14235,9 +13109,8 @@ cdef class GiacMethods_base: Help for rassembler_trigo: rassembler_trigo(Expr) Collects trigonometric expressions. - See also: 1/ texpand 2/ tlin + See also: 1/ texpand 2/ tlin Ex1:rassembler_trigo(sin(x)+cos(x)) - ''' return GiacMethods['rassembler_trigo'](self,*args) @@ -14246,11 +13119,10 @@ cdef class GiacMethods_base: Help for rat_jordan: rat_jordan(Mtrx) Returns the list made by the transition matrix and the rational Jordan form of a matrix. - See also: 1/ egv 2/ egvl 3/ jordan 4/ companion + See also: 1/ egv 2/ egvl 3/ jordan 4/ companion Ex1:rat_jordan([[0,2],[1,0]]) Ex2:rat_jordan([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex3:rat_jordan([[1,1,-1,2,-1],[2,0,1,-4,-1],[0,1,1,1,1],[0,1,2,0,1],[0,0,-3,3,-1]]) - ''' return GiacMethods['rat_jordan'](self,*args) @@ -14259,11 +13131,10 @@ cdef class GiacMethods_base: Help for rational: rational(Opt) DOM_RAT or rational is the type of a rational, as returned by the type command. It is also an option of the assume command. - See also: 1/ type 2/ assume 3/ DOM_INT 4/ DOM_FLOAT + See also: 1/ type 2/ assume 3/ DOM_INT 4/ DOM_FLOAT Ex1: assume(a,rational) Ex2: assume(a,DOM_RAT) Ex3: a:=1/2;type(a) - ''' return GiacMethods['rational'](self,*args) @@ -14272,9 +13143,8 @@ cdef class GiacMethods_base: Help for rationalroot: rationalroot(Poly(P)) Returns the list of rational roots of P without indicating the multiplicity. - See also: 1/ proot 2/ froot 3/ complexroot 4/ realroot 5/ crationalroot + See also: 1/ proot 2/ froot 3/ complexroot 4/ realroot 5/ crationalroot Ex1:rationalroot(2*x^3-9*x^2+13*x-6) - ''' return GiacMethods['rationalroot'](self,*args) @@ -14283,11 +13153,10 @@ cdef class GiacMethods_base: Help for ratnormal: ratnormal(Expr) Rewrites as an irreducible rational fraction. - See also: 1/ normal 2/ simplify 3/ factor 4/ expand + See also: 1/ normal 2/ simplify 3/ factor 4/ expand Ex1:ratnormal((x^2-1)/(x^3-1)) Ex2:ratnormal(c/d+b/d+a/d) Ex3:ratnormal((x^2-1)/(x^3-1)+(x-1)/(x^3-1)+1) - ''' return GiacMethods['ratnormal'](self,*args) @@ -14296,10 +13165,9 @@ cdef class GiacMethods_base: Help for rdiv: rdiv(Expr(a),Expr(b)) Division of a by b (prefixed version of /). - See also: 1/ / + See also: 1/ / Ex1:rdiv(3,5) Ex2:rdiv(3.2,5.4) - ''' return GiacMethods['rdiv'](self,*args) @@ -14308,11 +13176,10 @@ cdef class GiacMethods_base: Help for re: re(Cplx or LstCplx) Returns the real part of a complex number. - See also: 1/ im 2/ conj + See also: 1/ im 2/ conj Ex1:re(1+2*i) Ex2:re((1+2*i)^2) Ex3:re([1+2*i,(1+2*i)^2]) - ''' return GiacMethods['re'](self,*args) @@ -14321,9 +13188,8 @@ cdef class GiacMethods_base: Help for read: read(Str(fich_name)) Reads variables and their values from the file fich_name. - See also: 1/ write 2/ readrgb 3/ readwav 4/ csv2gen + See also: 1/ write 2/ readrgb 3/ readwav 4/ csv2gen Ex1:read("toto") - ''' return GiacMethods['read'](self,*args) @@ -14332,10 +13198,9 @@ cdef class GiacMethods_base: Help for readrgb: readrgb(Str(s),[Intg(w)],[Intg(h)]) Reads a picture file, using it's natural dimensions, or using specified dimensions. - See also: 1/ writergb 2/ readwav + See also: 1/ writergb 2/ readwav Ex1:readrgb("image.png") Ex2:readrgb("image.png",50,50) - ''' return GiacMethods['readrgb'](self,*args) @@ -14344,9 +13209,8 @@ cdef class GiacMethods_base: Help for readwav: readwav(Str(s)) Reads a WAV sound file. - See also: 1/ writewav 2/ readrgb + See also: 1/ writewav 2/ readrgb Ex1:readwav("pop.wav") - ''' return GiacMethods['readwav'](self,*args) @@ -14355,11 +13219,10 @@ cdef class GiacMethods_base: Help for real: real(Cplx or LstCplx) Returns the real part of a complex number. - See also: 1/ im 2/ conj + See also: 1/ im 2/ conj Ex1:real(1+2*i) Ex2:real((1+2*i)^2) Ex3:real([1+2*i,(1+2*i)^2]) - ''' return GiacMethods['real'](self,*args) @@ -14368,14 +13231,13 @@ cdef class GiacMethods_base: Help for realroot: realroot([sturm],Poly(P),[Real(l)],[Cplx(a)],[Cplx(b)]) Returns the list of intervals of length <=l containing the real roots of P inside a..b with their multiplicity. By default the Vincent-Akritas-Strzebonski (VAS) method is used. realroot(sturm,P) uses Sturm's method. - See also: 1/ proot 2/ froot 3/ complexroot 4/ rationalroot 5/ crationalroot 6/ sturmab 7/ VAS + See also: 1/ proot 2/ froot 3/ complexroot 4/ rationalroot 5/ crationalroot 6/ sturmab 7/ VAS Ex1:realroot(x^3+7,0.1) Ex2:realroot(x^3-7*x+7) Ex3:realroot(sturm,x^3-7*x+7) Ex4:realroot(x^5-2*x^4+x^3+1) Ex5:realroot(x^5-2*x^4+x^3+1,0.1) Ex6:realroot(x^3+x+8,1e-5,-4,4) - ''' return GiacMethods['realroot'](self,*args) @@ -14384,10 +13246,9 @@ cdef class GiacMethods_base: Help for reciprocation: reciprocation(Crcle,Lst(Pnt,Line)) Returns the list where the points (resp lines) are replaced with their polars (resp poles) with respect to the circle C. - See also: 1/ pole 2/ polar + See also: 1/ pole 2/ polar Ex1:reciprocation(circle(0,1),[point((1+i)/2), line(1,-1+i)]) Ex2:reciprocation(circle(0,1),[line(1+i,2),point(1+i*2)]) - ''' return GiacMethods['reciprocation'](self,*args) @@ -14396,9 +13257,8 @@ cdef class GiacMethods_base: Help for rect: rect(Expr(x)) Returns the value of the rectangle function at x. - See also: 1/ boxcar 2/ tri 3/ Heaviside + See also: 1/ boxcar 2/ tri 3/ Heaviside Ex1:rect(x/2) - ''' return GiacMethods['rect'](self,*args) @@ -14407,12 +13267,11 @@ cdef class GiacMethods_base: Help for rectangle: rectangle(Pnt(A)||Cplx,Pnt(B)||Cplx,Real(k)||Pnt(P)||Lst(P,k),[Var(D)],[Var(C)]) Returns and draws the rectangle ABCD, AD=k*AB; if k>0 ABCD is direct else indirect (in the plane ABP AD=AP or AD=k*AB). - See also: 1/ quadrilateral 2/ square + See also: 1/ quadrilateral 2/ square Ex1:rectangle(-i,1,2) Ex2:rectangle(-i,1,-2,D,C) Ex3:rectangle(point(0,0,0),point(3,3,3),point(0,0,3),D,C) Ex4:rectangle(point(0,0,0),point(3,3,3),2,D,C) - ''' return GiacMethods['rectangle'](self,*args) @@ -14421,14 +13280,13 @@ cdef class GiacMethods_base: Help for rectangle_droit: rectangle_droit(Opt) Option of the plotarea command and of the area command. - See also: 1/ plotarea 2/ area + See also: 1/ plotarea 2/ area Ex1: plotarea(x^2,x=0..1,5,trapezoid) Ex2: plotarea(x^2,x=0..1,5,middle_point) Ex3: plotarea(x^2,x=0..1,5,right_rectangle) Ex4: plotarea(x^2,x=0..1,5,left_rectangle) Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) - ''' return GiacMethods['rectangle_droit'](self,*args) @@ -14437,14 +13295,13 @@ cdef class GiacMethods_base: Help for rectangle_gauche: rectangle_gauche(Opt) Option of the plotarea command and of the area command. - See also: 1/ plotarea 2/ area + See also: 1/ plotarea 2/ area Ex1: plotarea(x^2,x=0..1,5,trapezoid) Ex2: plotarea(x^2,x=0..1,5,middle_point) Ex3: plotarea(x^2,x=0..1,5,right_rectangle) Ex4: plotarea(x^2,x=0..1,5,left_rectangle) Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) - ''' return GiacMethods['rectangle_gauche'](self,*args) @@ -14453,11 +13310,10 @@ cdef class GiacMethods_base: Help for rectangle_plein: rectangle_plein(Real(a),[Real(b)]) Draws a full direct rectangle (resp square) with sides a,b (resp a) from the turtle position and on the left (by default b=a). - See also: 1/ triangle_plein + See also: 1/ triangle_plein Ex1: rectangle_plein 20 Ex2:rectangle_plein(20) Ex3:rectangle_plein(20,40) - ''' return GiacMethods['rectangle_plein'](self,*args) @@ -14466,10 +13322,9 @@ cdef class GiacMethods_base: Help for rectangular_coordinates: rectangular_coordinates(LstPolCoord) Returns the list of the abscissa and of the ordinate of a point given by the list of its polar coordinates. - See also: 1/ abscissa 2/ ordinate 3/ rectangular_coordinates 4/ polar_point + See also: 1/ abscissa 2/ ordinate 3/ rectangular_coordinates 4/ polar_point Ex1:rectangular_coordinates([1,pi/4]) Ex2:rectangular_coordinates(polar_point(1,pi/4)) - ''' return GiacMethods['rectangular_coordinates'](self,*args) @@ -14478,10 +13333,9 @@ cdef class GiacMethods_base: Help for recule: recule(NULL or Real(n)) The turtle takes n steps back (by default n=10). - See also: 1/ avance 2/ saute + See also: 1/ avance 2/ saute Ex1: recule 30 Ex2:recule(30) - ''' return GiacMethods['recule'](self,*args) @@ -14490,10 +13344,9 @@ cdef class GiacMethods_base: Help for red: red(Opt) Option of the display command to display with color. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),red) Ex2: F:=display(point(2+1.5*i),point_point+green) - ''' return GiacMethods['red'](self,*args) @@ -14502,12 +13355,11 @@ cdef class GiacMethods_base: Help for reduced_conic: reduced_conic(Expr,[LstVar]) Returns the origin and the matrix of a base in which the conic given by its equation is reduced, 0 or 1 (0 if the conic is degenerate) and the equation of the conic in this base and also its parametric equation. - See also: 1/ gauss 2/ conic + See also: 1/ gauss 2/ conic Ex1:reduced_conic(x^2+2*x-2*y+1) Ex2:reduced_conic(a*x^2-2*x*y+a*y^2-2*x+2*y+3,[x,y]) Ex3:reduced_conic(2*u^2+2*u*v+2*v^2+5*u+3,[u,v]) Ex4:reduced_conic((x+y)^2-2*x+1,x,y) - ''' return GiacMethods['reduced_conic'](self,*args) @@ -14516,12 +13368,11 @@ cdef class GiacMethods_base: Help for reduced_quadric: reduced_quadric(Expr, [LstVar]) Returns the origin and the matrix of a basis in which the quadric (given by its equation) is reduced, the list of its eigenvalues, the equation of the quadric in this basis and its parametric equation. - See also: 1/ gauss 2/ quadric + See also: 1/ gauss 2/ quadric Ex1:reduced_quadric(4*x^2+y^2+z^2-4*x*y+4*x*z-2*y*z+8*x-4*y+4*z+2) Ex2:reduced_quadric(x^2+3*y^2-3*z^2-8*y*z+2*z*x-4*x*y-1,x,y,z) Ex3:reduced_quadric((u+v)*(v-w)+3*u-5*v,[u,v,w]) Ex4:reduced_quadric(7*x^2+4*y^2+4*z^2+4*x*y-4*x*z-2*y*z-4*x+5*y+4*z-18,[x,y,z]) - ''' return GiacMethods['reduced_quadric'](self,*args) @@ -14530,10 +13381,9 @@ cdef class GiacMethods_base: Help for ref: ref(Mtrx(M)) Gaussian reduction of AX=b (M=A|(-b)). - See also: 1/ rref 2/ det + See also: 1/ rref 2/ det Ex1:ref([[3,1,-2],[3,2,2]]) Ex2:ref([[2,1,1,-1],[1,1,2,-1],[1,2,1,-4]]) - ''' return GiacMethods['ref'](self,*args) @@ -14542,11 +13392,10 @@ cdef class GiacMethods_base: Help for reflection: reflection((Pnt(A) or Line(D)),(Pnt(C) or Curve(C))) reflection(D,C) (or reflection(A,C))=symmetry of C with the symmetry-line D (or sym-point A). - See also: 1/ rotation 2/ translation + See also: 1/ rotation 2/ translation Ex1:reflection(line(0,1+i),A) Ex2:reflection(B,A) Ex3:reflection(line(0,1+i),circle(i,1+i)) - ''' return GiacMethods['reflection'](self,*args) @@ -14555,9 +13404,8 @@ cdef class GiacMethods_base: Help for regroup: regroup(Expr) Collects terms in an expression. - See also: 1/ simplify 2/ normal + See also: 1/ simplify 2/ normal Ex1:regroup(x+3*x+5*4/x) - ''' return GiacMethods['regroup'](self,*args) @@ -14566,9 +13414,8 @@ cdef class GiacMethods_base: Help for relabel_vertices: relabel_vertices(Graph(G),Lst(L)) Returns a copy of G with vertex labels changed to those in the list L. - See also: 1/ graph_vertices 2/ isomorphic_copy 3/ permute_vertices + See also: 1/ graph_vertices 2/ isomorphic_copy 3/ permute_vertices Ex1:relabel_vertices(graph([a,b,c]),["first","second","third"]) - ''' return GiacMethods['relabel_vertices'](self,*args) @@ -14577,10 +13424,9 @@ cdef class GiacMethods_base: Help for reliability_polynomial: reliability_polynomial(Graph(G),[Var(p)]) Returns the reliability polynomial [or its value at point p] of undirected graph G. If G is weighted, all weights must be positive integers and are interpreted as edge multiplicities. - See also: 1/ chromatic_polynomial 2/ flow_polynomial 3/ tutte_polynomial + See also: 1/ chromatic_polynomial 2/ flow_polynomial 3/ tutte_polynomial Ex1:reliability_polynomial(graph("petersen")) Ex2:reliability_polynomial(graph("petersen"),0.5) - ''' return GiacMethods['reliability_polynomial'](self,*args) @@ -14589,11 +13435,10 @@ cdef class GiacMethods_base: Help for rem: rem((Vect or Poly),(Vect or Poly),[Var]) Euclidean remainder of 2 polynomials. - See also: 1/ quo 2/ quorem 3/ Rem 4/ irem + See also: 1/ quo 2/ quorem 3/ Rem 4/ irem Ex1:rem([1,2,3,4],[-1,2]) Ex2:rem(x^3+2x^2+3x+4,-x+2) Ex3:rem(t^3+2t^2+3t+4,-t+2,t) - ''' return GiacMethods['rem'](self,*args) @@ -14602,12 +13447,11 @@ cdef class GiacMethods_base: Help for remain: remain(Intg(a),Intg(b)) Euclidean remainder of 2 integers. - See also: 1/ iquo 2/ smod 3/ rem 4/ mod + See also: 1/ iquo 2/ smod 3/ rem 4/ mod Ex1:remain(125,15) Ex2:remain(125,41) Ex3:remain(-7,3) Ex4:remain(25+12*i,5+7*i) - ''' return GiacMethods['remain'](self,*args) @@ -14616,10 +13460,9 @@ cdef class GiacMethods_base: Help for remove: remove(FncBool(f)||a,Lst(l)) Remove the occurrences a of l or the elements a such that f(a)=true. - See also: 1/ select 2/ suppress + See also: 1/ select 2/ suppress Ex1:remove(x->x>=5,[1,2,6,7]) Ex2:remove(5,[1,2,5,6,7,5]) - ''' return GiacMethods['remove'](self,*args) @@ -14628,10 +13471,9 @@ cdef class GiacMethods_base: Help for reorder: reorder(Expr, LstVar) Reorders the variables in E according to the order of the 2nd argument. - See also: 1/ + See also: 1/ Ex1:reorder(-2) Ex2:reorder(x^2+2*x+y^2,[y,x]) - ''' return GiacMethods['reorder'](self,*args) @@ -14640,10 +13482,9 @@ cdef class GiacMethods_base: Help for resample: resample(Lst(clip),[Intg(s),[Intg(q)]]) Returns a copy of the input audio clip resampled to the rate s (by default 44100), optionally with quality level q (from 0 to 4, by default 2). - See also: 1/ samplerate 2/ playsnd 3/ readwav 4/ writewav + See also: 1/ samplerate 2/ playsnd 3/ readwav 4/ writewav Ex1:resample(readwav("/some/file"),48000) Ex2:resample(readwav("/some/file"),48000,3) - ''' return GiacMethods['resample'](self,*args) @@ -14652,12 +13493,11 @@ cdef class GiacMethods_base: Help for residue: residue(Expr,Var(v),Cplx(a)) Returns the residue in a of the expression with v as variable. - See also: 1/ series + See also: 1/ series Ex1:residue(1/z,z,0) Ex2:residue(5/z,z=0) Ex3:residue(cos(z)/(z*(z-b)),z,0) Ex4:residue(c/(z*(z-b)),z=b) - ''' return GiacMethods['residue'](self,*args) @@ -14666,12 +13506,11 @@ cdef class GiacMethods_base: Help for resoudre: resoudre(Expr,[Var]) Solves a (or a set of) polynomial equation. - See also: 1/ linsolve 2/ proot 3/ fsolve 4/ csolve 5/ nSolve + See also: 1/ linsolve 2/ proot 3/ fsolve 4/ csolve 5/ nSolve Ex1:resoudre(x^2-3=1) Ex2:resoudre(x^3-3*y,y) Ex3:resoudre([y-z=0,z-x=0,x-y=0,x-1+y+z=0],[x,y,z]) Ex4:resoudre([x^2-y^2=0,x^2-z^2=0],[x,y,z]) - ''' return GiacMethods['resoudre'](self,*args) @@ -14680,12 +13519,11 @@ cdef class GiacMethods_base: Help for resoudre_dans_C: resoudre_dans_C(LstEq,LstVar) Returns the list of complex solutions of an equation or a matrix where the rows are ℂ-solutions of a system of polynomial equations. - See also: 1/ cZeros 2/ solve 3/ fslove + See also: 1/ cZeros 2/ solve 3/ fslove Ex1:resoudre_dans_C(x^4-1,x) Ex2:resoudre_dans_C(x^4-y^4 and x+y=2,[x,y]) Ex3:resoudre_dans_C(x^4-y^4 and x+y=0 and x^2=2*x,[x,y]) Ex4:resoudre_dans_C(u*v-u=v and v^2=u,[u,v]) - ''' return GiacMethods['resoudre_dans_C'](self,*args) @@ -14694,17 +13532,16 @@ cdef class GiacMethods_base: Help for resoudre_systeme_lineaire: resoudre_systeme_lineaire(LstLinEq,LstVar) Linear equations system solver. - See also: 1/ solve 2/ proot 3/ simult 4/ gaussjord 5/ pivot 6/ ref 7/ conjugate_gradient + See also: 1/ solve 2/ proot 3/ simult 4/ gaussjord 5/ pivot 6/ ref 7/ conjugate_gradient Ex1:resoudre_systeme_lineaire([x+y+z=1,x-y=2,2*x-z=3],[x,y,z]) Ex2:resoudre_systeme_lineaire([m*x+y=a,x+m*y=b],[x,y]) Ex3:resoudre_systeme_lineaire([x+y-z-1,x-y+1,x-y-z-1]%2,[x,y,z]) Ex4:resoudre_systeme_lineaire([[3,4],[1,2]],[0,1]) - Ex5: p,l,u:=lu([[3,4],[1,2]]); linsolve(p,l,u,[0,1]) + Ex5: p,l,u:=lu([[3,4],[1,2]]); linsolve(p,l,u,[0,1]) Ex6:resoudre_systeme_lineaire([2*x+y+z=1,x+y+2*z=1,x+2*y+z=4],[x,y,z]) Ex7:resoudre_systeme_lineaire([[2,1,1],[1,1,2],[1,2,1]],[1,1,4]) Ex8: p,l,u:=lu([[2,1,1],[1,1,2],[1,2,1]]);linsolve(p,l,u,[1,1,4]) Ex9: a:=[[100,2],[2,100]];linsolve(evalf(a),[0,1]); - ''' return GiacMethods['resoudre_systeme_lineaire'](self,*args) @@ -14713,10 +13550,9 @@ cdef class GiacMethods_base: Help for resultant: resultant(Poly,Poly,Var) Resultant of two polynomials. - See also: 1/ sylvester 2/ gcd + See also: 1/ sylvester 2/ gcd Ex1:resultant(x^2-1,x^3-1,x) Ex2:resultant(x^3-p*x+q,3*x^2-p,x) - ''' return GiacMethods['resultant'](self,*args) @@ -14729,7 +13565,6 @@ cdef class GiacMethods_base: Ex2: L:=[1,2,3,4];L:=revlist(L) Ex3: L:=[1,2,3,4];L.revlist() Ex4: L:=[1,2,3,4];L.reverse() - ''' return GiacMethods['reverse'](self,*args) @@ -14738,9 +13573,8 @@ cdef class GiacMethods_base: Help for reverse_graph: reverse_graph(Graph(G)) Returns the copy of G with the directions of all edges reversed. - See also: 1/ digraph + See also: 1/ digraph Ex1:reverse_graph(digraph(%{[1,2],[1,3],[2,3]%})) - ''' return GiacMethods['reverse_graph'](self,*args) @@ -14749,9 +13583,8 @@ cdef class GiacMethods_base: Help for reverse_rsolve: reverse_rsolve(Vect(v)) If v=[v_0 ... v_(2n-1)], returns [b_n,...,b_0] such that b_n*v_{n+k}+...+b_0*v_k=0 for k=0..n-1. - See also: 1/ rsolve + See also: 1/ rsolve Ex1:reverse_rsolve([1,-1,3,3]) - ''' return GiacMethods['reverse_rsolve'](self,*args) @@ -14760,9 +13593,8 @@ cdef class GiacMethods_base: Help for revert: revert(Expr) Returns the inverse expansion of a series expansion at 0. - See also: 1/ series + See also: 1/ series Ex1:revert(x+x^2+x^4) - ''' return GiacMethods['revert'](self,*args) @@ -14771,8 +13603,7 @@ cdef class GiacMethods_base: Help for revlex: revlex(Opt) Option of the gbasis or greduce command to specify an order for monomials (complete degree then inverse lexicographic order). - See also: 1/ gbasis 2/ greduce - + See also: 1/ gbasis 2/ greduce ''' return GiacMethods['revlex'](self,*args) @@ -14785,7 +13616,6 @@ cdef class GiacMethods_base: Ex2: L:=[1,2,3,4];L:=revlist(L) Ex3: L:=[1,2,3,4];L.revlist() Ex4: L:=[1,2,3,4];L.reverse() - ''' return GiacMethods['revlist'](self,*args) @@ -14794,14 +13624,13 @@ cdef class GiacMethods_base: Help for rgb: rgb(Opt) Option of the display (or affichage) command to defined colors RGB. - See also: 1/ display 2/ filled + See also: 1/ display 2/ filled Ex1: redcolor:=rgb(0.99,0,0);display(square(0,2+i),filled+redcolor) Ex2: greencolor:=rgb(0,0.99,0);display(square(0,2+i),filled+greencolor) Ex3: bluecolor:=rgb(0,0,0.99);display(square(0,2+i),filled+bluecolor) Ex4: greycolor:=rgb(0.5,0.5,0.5);display(square(0,2+i),filled+greycolor) Ex5: F:=display(square(0,2+i),filled+rgb(rand(),rand(),rand())) Ex6: L:=rand(),rand(),rand();affichage(square(0,2+i),rgb(L)+rempli);legend(0.2,[L]) - ''' return GiacMethods['rgb'](self,*args) @@ -14810,13 +13639,12 @@ cdef class GiacMethods_base: Help for rhombus: rhombus(Pnt(A)||Cplx,Pnt(B)||Cplx,Angle(a)||Pnt(P)||Lst(P,a)),[Var(C)],[Var(D)]) Returns and draws the rhombus ABCD such that the angle (AB,AD)=a (or in the plane ABP angle(AB,AD)=angle(AB,AP) or such that angle(AB,AD)=a). - See also: 1/ square 2/ quadrilateral + See also: 1/ square 2/ quadrilateral Ex1:rhombus(i,1+i,pi/4) Ex2:rhombus(i,1+i,pi/4,C,D) Ex3:rhombus(point(0,0,0),point(3,3,3),[point(0,0,3),pi/4]) Ex4:rhombus(point(0,0,0),point(3,3,3),point(0,0,3),C,D) Ex5:rhombus(point(0,0,0),point(3,3,3),[point(0,0,3),pi/4],C,D) - ''' return GiacMethods['rhombus'](self,*args) @@ -14825,10 +13653,9 @@ cdef class GiacMethods_base: Help for rhombus_point: rhombus_point(Opt) Option of the display command for a point. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) - ''' return GiacMethods['rhombus_point'](self,*args) @@ -14837,12 +13664,11 @@ cdef class GiacMethods_base: Help for rhs: rhs(Equal(a=b) or Interval(a..b) or Str,Intg) Returns the right part of an equality, of an interval, of a list or of a string. - See also: 1/ left 2/ mid 3/ tail 4/ head + See also: 1/ left 2/ mid 3/ tail 4/ head Ex1:rhs(a=b) Ex2:rhs(x^2+1=5) Ex3:rhs(1..5) Ex4:rhs("abcdefg",3) - ''' return GiacMethods['rhs'](self,*args) @@ -14851,9 +13677,8 @@ cdef class GiacMethods_base: Help for riemann_window: riemann_window(Lst,[Interval(n1..n2)]) Applies the Riemann windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ bartlett_hann_window 12/ triangle_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ bartlett_hann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(riemann_window(randvector(1000,0..1))) - ''' return GiacMethods['riemann_window'](self,*args) @@ -14862,12 +13687,11 @@ cdef class GiacMethods_base: Help for right: right(Equal(a=b) or Interval(a..b) or Str,Intg) Returns the right part of an equality, of an interval, of a list or of a string. - See also: 1/ left 2/ mid 3/ tail 4/ head + See also: 1/ left 2/ mid 3/ tail 4/ head Ex1:right(a=b) Ex2:right(x^2+1=5) Ex3:right(1..5) Ex4:right("abcdefg",3) - ''' return GiacMethods['right'](self,*args) @@ -14876,14 +13700,13 @@ cdef class GiacMethods_base: Help for right_rectangle: right_rectangle(Opt) Option of the plotarea command and of the area command. - See also: 1/ plotarea 2/ area + See also: 1/ plotarea 2/ area Ex1: plotarea(x^2,x=0..1,5,trapezoid) Ex2: plotarea(x^2,x=0..1,5,middle_point) Ex3: plotarea(x^2,x=0..1,5,right_rectangle) Ex4: plotarea(x^2,x=0..1,5,left_rectangle) Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) - ''' return GiacMethods['right_rectangle'](self,*args) @@ -14892,13 +13715,12 @@ cdef class GiacMethods_base: Help for right_triangle: right_triangle((Pnt(A) or Cplx),(Pnt(B) or Cplx),(Real(k) or Pnt(P) or Lst(P,k)),[Var(C)]) Draws the A_rectangular triangle ABC with AC=k*AB (or in the plane ABP AC=AP or AC=k*AB). - See also: 1/ triangle + See also: 1/ triangle Ex1:right_triangle(1,i,tan(pi/3)) Ex2:right_triangle(1,i,1/2,C) Ex3:right_triangle(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:right_triangle(point(0,0,0),point(3,3,3),[point(0,0,3),1/2],C) Ex5:right_triangle(point(0,0,0),point(3,3,3),[point(0,0,3),1/2],C) - ''' return GiacMethods['right_triangle'](self,*args) @@ -14907,11 +13729,10 @@ cdef class GiacMethods_base: Help for risch: risch(Expr,[Var]) Returns a primitive of the expression calculated with the Risch algorithm. - See also: 1/ int + See also: 1/ int Ex1:risch(ln(x),x) Ex2:risch(ln(x)) Ex3:risch(exp(x^2),x) - ''' return GiacMethods['risch'](self,*args) @@ -14920,9 +13741,8 @@ cdef class GiacMethods_base: Help for rm_a_z: rm_a_z(NULL) Erases all the variable name made up of only one lowercase a..z character. - See also: 1/ rm_all_vars + See also: 1/ rm_all_vars Ex1:rm_a_z() - ''' return GiacMethods['rm_a_z'](self,*args) @@ -14931,9 +13751,8 @@ cdef class GiacMethods_base: Help for rm_all_vars: rm_all_vars(NULL) Erases all the variable names. - See also: 1/ rm_a_z + See also: 1/ rm_a_z Ex1:rm_all_vars() - ''' return GiacMethods['rm_all_vars'](self,*args) @@ -14942,9 +13761,8 @@ cdef class GiacMethods_base: Help for rmbreakpoint: rmbreakpoint(Intg) Removes a breakpoint. - See also: 1/ breakpoint + See also: 1/ breakpoint Ex1:rmbreakpoint(1) - ''' return GiacMethods['rmbreakpoint'](self,*args) @@ -14953,9 +13771,8 @@ cdef class GiacMethods_base: Help for rmmod: rmmod(Str(pwd)) Removes the installed dynamic libraries. - See also: 1/ lsmod 2/ insmod + See also: 1/ lsmod 2/ insmod Ex1:rmmod("/home/parisse/giac/src/libprogfr.so") - ''' return GiacMethods['rmmod'](self,*args) @@ -14964,9 +13781,8 @@ cdef class GiacMethods_base: Help for rmwatch: rmwatch(Var) Clears a variables from the table of displayed variables in step/step. - See also: 1/ watch + See also: 1/ watch Ex1:rmwatch(a) - ''' return GiacMethods['rmwatch'](self,*args) @@ -14975,11 +13791,10 @@ cdef class GiacMethods_base: Help for romberg: romberg(Expr(f(x)),Var(x),Real(a),Real(b)) Returns the approximate value of integrate(f(x),x,a,b) by Romberg's method. - See also: 1/ integrate 2/ gaussquad + See also: 1/ integrate 2/ gaussquad Ex1:romberg(exp(x^2),x,0,1) Ex2:romberg(x^2,x,0,1) Ex3:romberg(exp(-x^2),x,-1,1) - ''' return GiacMethods['romberg'](self,*args) @@ -14988,12 +13803,11 @@ cdef class GiacMethods_base: Help for rombergm: rombergm(Opt) Option of the area command. - See also: 1/ area + See also: 1/ area Ex1: area(x^2,x=0..1,5,simpson) Ex2: area(x^2,x=0..1,5,rombergt) Ex3: area(x^2,x=0..1,5,rombergm) Ex4:rombergm(area(x^2,x=0..1,5,gauss15)) - ''' return GiacMethods['rombergm'](self,*args) @@ -15002,12 +13816,11 @@ cdef class GiacMethods_base: Help for rombergt: rombergt(Opt) Option of the area command. - See also: 1/ area + See also: 1/ area Ex1: area(x^2,x=0..1,5,simpson) Ex2: area(x^2,x=0..1,5,rombergt) Ex3: area(x^2,x=0..1,5,rombergm) Ex4:rombergt(area(x^2,x=0..1,5,gauss15)) - ''' return GiacMethods['rombergt'](self,*args) @@ -15016,12 +13829,11 @@ cdef class GiacMethods_base: Help for rond: rond(Real(r),[Real(a)],[Real(b)]) Draws a circle (resp a arc) with radius r (resp and with angle (0,a) or (a,b)), tangent at the turtle position. - See also: 1/ disque + See also: 1/ disque Ex1: rond 30 Ex2:rond(40) Ex3:rond(40,90) Ex4:rond(40,10,100) - ''' return GiacMethods['rond'](self,*args) @@ -15030,12 +13842,11 @@ cdef class GiacMethods_base: Help for root: root(Expr(a),Expr(b)) Returns b^(1/a) (root(2,3)=sqrt(3)). - See also: 1/ + See also: 1/ Ex1:root(3,2) Ex2:root(1/3,2) Ex3:root(3,1.2) Ex4:root(3.2,1.2) - ''' return GiacMethods['root'](self,*args) @@ -15044,11 +13855,10 @@ cdef class GiacMethods_base: Help for rootof: rootof(LstPoly(P),LstPoly(Q)) Polynomial in terms of a root of an irreducible polynomial on Q. Returns P(a) with a the greatest root of Q. - See also: 1/ + See also: 1/ Ex1: normal(1/rootof([1,0],[1,0,10,0,1])) Ex2: normal(1/rootof([1,0,0],[1,1,0,-1])) - Ex3: rootof(x^4+x+1):='j'; normal(j^5); - + Ex3: rootof(x^4+x+1):='j'; normal(j^5); ''' return GiacMethods['rootof'](self,*args) @@ -15057,10 +13867,9 @@ cdef class GiacMethods_base: Help for roots: roots(Poly,[Var]) Returns a matrix having 2 columns and where the rows are the roots of the polynomial with their multiplicity (for 1 variable). - See also: 1/ proot 2/ cZeros + See also: 1/ proot 2/ cZeros Ex1:roots(t^3-1,t) Ex2:roots(x^5-2*x^4+x^3) - ''' return GiacMethods['roots'](self,*args) @@ -15069,7 +13878,7 @@ cdef class GiacMethods_base: Help for rotate: rotate(Lst||Str(L),[Intg(n)]) Returns the list where the last element [or the tail beginning with the n-th element] is moved to the first element (by default n=-1);L:=rotate(L,n) or L.rotate(n). - See also: 1/ tail 2/ mid 3/ shift + See also: 1/ tail 2/ mid 3/ shift Ex1:rotate([0,1,2,3],2) Ex2:rotate([[1,2,3],[4,5,6],[7,8,9]]) Ex3:rotate([0,1,2,3,4]) @@ -15078,7 +13887,6 @@ cdef class GiacMethods_base: Ex6: L:=[0,1,2,3,4];L.rotate() Ex7: L:=[0,1,2,3];L:=rotate([0,1,2,3],2) Ex8: L:=[0,1,2,3];L.rotate(2) - ''' return GiacMethods['rotate'](self,*args) @@ -15087,13 +13895,12 @@ cdef class GiacMethods_base: Help for rotation: rotation((Pnt(B) or Cplx or Dr3),Angle(a1),(Pnt(A) or Curve)) rotation(B,a1,A) (resp rotation(d,a1,A)) is the transformation of A by rotation with center B (resp of axis d) and angle a1. - See also: 1/ translation 2/ reflection + See also: 1/ translation 2/ reflection Ex1:rotation(point(1+i),pi/2,point(i)) Ex2:rotation(1+i,pi/3,line(i,1)) Ex3:rotation(line(x=y,y=z),pi/2,point(1,-1,2)) Ex4: r:=rotation(1+i,pi/2);r(i) Ex5: r:=rotation(line(x=y,y=z),pi/2);r(point(1,-1,2)) - ''' return GiacMethods['rotation'](self,*args) @@ -15102,13 +13909,12 @@ cdef class GiacMethods_base: Help for round: round(Real or Cplx,[Intg(n)]) Rounds the real or complex to the nearest integer (resp the nearest decimal number) or to the nearest element of ℤ[i], (resp with n decimals). - See also: 1/ floor 2/ ceil + See also: 1/ floor 2/ ceil Ex1:round(2.5) Ex2:round(-2.4) Ex3:round(-2.5+i*2.4) Ex4:round(1.237,2) Ex5:round(sqrt(2)+i*sqrt(5),4) - ''' return GiacMethods['round'](self,*args) @@ -15117,11 +13923,10 @@ cdef class GiacMethods_base: Help for row: row(Mtrx(A),Intg(n)||Interval(n1..n2)) Returns row n or the sequence of the rows n1..n2 of the matrix A, or optional argument of count,count_eq,count_inf,count_sup. - See also: 1/ col 2/ count 3/ count_eq 4/ count_inf 5/ count_sup + See also: 1/ col 2/ count 3/ count_eq 4/ count_inf 5/ count_sup Ex1:row([[1,2,3],[4,5,6],[7,8,9]],1) Ex2:row([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3: count_eq(3,[[1,2,3],[4,3,2],[3,2,1]],row) - ''' return GiacMethods['row'](self,*args) @@ -15130,9 +13935,8 @@ cdef class GiacMethods_base: Help for rowAdd: rowAdd(Mtrx(A),Intg(n1),Intg(n2)) Returns the matrix obtained from A by replacing the n2-th row by the sum of the n1-th and n2-th rows. - See also: 1/ rowSwap + See also: 1/ rowSwap Ex1:rowAdd([[1,2],[3,4],[5,6]],1,2) - ''' return GiacMethods['rowAdd'](self,*args) @@ -15141,10 +13945,9 @@ cdef class GiacMethods_base: Help for rowDim: rowDim(Mtrx) Number of rows of a matrix. - See also: 1/ ncols + See also: 1/ ncols Ex1:rowDim([[1,2,3],[4,5,6]]) Ex2:rowDim([[1,2],[3,4],[5,6]]) - ''' return GiacMethods['rowDim'](self,*args) @@ -15153,10 +13956,9 @@ cdef class GiacMethods_base: Help for rowNorm: rowNorm(Vect or Mtrx) Returns the max of the l1_norm of the rows of a matrix: rowNorm(a_{j,k})=max_j(sum_k(|a_{j,k}|)). - See also: 1/ norm + See also: 1/ norm Ex1:rowNorm([[1,2],[3,-4]]) Ex2:rowNorm([[1,2,3,-4],[-5,3,2,1]]) - ''' return GiacMethods['rowNorm'](self,*args) @@ -15165,9 +13967,8 @@ cdef class GiacMethods_base: Help for rowSwap: rowSwap(Mtrx(A),Intg(n1),Intg(n2)) Returns the matrix obtained from A by swapping the n1-th row and the n2-th row. - See also: 1/ rowAdd 2/ colSwap + See also: 1/ rowAdd 2/ colSwap Ex1:rowSwap([[1,2],[3,4],[5,6]],1,2) - ''' return GiacMethods['rowSwap'](self,*args) @@ -15176,10 +13977,9 @@ cdef class GiacMethods_base: Help for rowdim: rowdim(Mtrx) Number of rows of a matrix. - See also: 1/ ncols + See also: 1/ ncols Ex1:rowdim([[1,2,3],[4,5,6]]) Ex2:rowdim([[1,2],[3,4],[5,6]]) - ''' return GiacMethods['rowdim'](self,*args) @@ -15188,10 +13988,9 @@ cdef class GiacMethods_base: Help for rownorm: rownorm(Vect or Mtrx) Returns the max of the l1_norm of the rows of a matrix: rowNorm(a_{j,k})=max_j(sum_k(|a_{j,k}|)). - See also: 1/ norm + See also: 1/ norm Ex1:rownorm([[1,2],[3,-4]]) Ex2:rownorm([[1,2,3,-4],[-5,3,2,1]]) - ''' return GiacMethods['rownorm'](self,*args) @@ -15200,10 +13999,9 @@ cdef class GiacMethods_base: Help for rowspace: rowspace(Mtrx(A), [Var(d)]) Returns a matrix where the rows are a basis of the vector space generated by the rows of the matrix A [d is the dimension of this space]. - See also: 1/ colspace + See also: 1/ colspace Ex1:rowspace([[1,2,3],[1,2,3],[1,2,4],[1,2,5]]) Ex2:rowspace([[1,2,3],[1,3,6],[2,5,9]],d) - ''' return GiacMethods['rowspace'](self,*args) @@ -15212,9 +14010,8 @@ cdef class GiacMethods_base: Help for rowswap: rowswap(Mtrx(A),Intg(n1),Intg(n2)) Returns the matrix obtained from A by swapping the n1-th row and the n2-th row. - See also: 1/ rowAdd 2/ colSwap + See also: 1/ rowAdd 2/ colSwap Ex1:rowswap([[1,2],[3,4],[5,6]],1,2) - ''' return GiacMethods['rowswap'](self,*args) @@ -15223,12 +14020,11 @@ cdef class GiacMethods_base: Help for rref: rref(Mtrx(M),[Intg(k)]||Opt) Row reduction to echelon form of AX=b (M=A|(-b)) [Reduction on columns 0..k-1]. - See also: 1/ ker 2/ image 3/ det 4/ Rref 5/ pivot 6/ ref 7/ keep_pivot + See also: 1/ ker 2/ image 3/ det 4/ Rref 5/ pivot 6/ ref 7/ keep_pivot Ex1:rref([[3,1,-2],[3,2,2]]) Ex2:rref([[2,1,1,-1],[1,1,2,-1],[1,2,1,-4]]) Ex3:rref([[2,1,1,-1],[1,1,2,-1],[1,2,1,-4]],2) Ex4:rref([[1,1,0,0,-a1],[0,1,1,0,-a2],[0,0,1,1,-a3],[1,0,0,1,-a4]],keep_pivot) - ''' return GiacMethods['rref'](self,*args) @@ -15237,13 +14033,12 @@ cdef class GiacMethods_base: Help for rsolve: rsolve((Expr or LstExpr),(Var or LstVar),(InitVal or LstInitVal)) Gives the value of a recurrent sequence or of a system of recurrent sequences. - See also: 1/ seqsolve 2/ plotseq 3/ tableseq 4/ reverse_rsolve + See also: 1/ seqsolve 2/ plotseq 3/ tableseq 4/ reverse_rsolve Ex1:rsolve(u(n+1)=2*u(n)+n,u(n),u(0)=1) Ex2:rsolve(u(n+1)=2*u(n)+n,u(n),u(1)^2=1) Ex3:rsolve(u(n+1)=(u(n)-1)/(u(n)-2),u(n),u(0)=4) Ex4:rsolve(u(n+2)=u(n)+2*u(n+1)+n+1,u(n),[u(0)=0,u(1)=1]) Ex5:rsolve([u(n+1)=3*v(n)+u(n),v(n+1)=v(n)+u(n)],[u(n),v(n)],[u(0)=1,v(0)=2]) - ''' return GiacMethods['rsolve'](self,*args) @@ -15252,10 +14047,9 @@ cdef class GiacMethods_base: Help for same: same(Expr,Expr) Equality test. - See also: 1/ + See also: 1/ Ex1:same(a,b) Ex2:same((2-1)^2,2^2-2*2+1) - ''' return GiacMethods['same'](self,*args) @@ -15264,14 +14058,13 @@ cdef class GiacMethods_base: Help for sample: sample(Lst(L),Intg(n)) sample(L,n)= rand(n,L)=list of the n extracted elements of L without replacement. - See also: 1/ rand + See also: 1/ rand Ex1:sample([1,2,3,4,5,6],6) Ex2:sample([1,2,3,4,5,6],3) Ex3:sample(["r","r","r","b","n"],3) Ex4: L:=[1,2,3,4,5,6];L:=sample(L,3) Ex5: L:=[1,2,3,4,5,6];L.sample(3) - Ex6: - + Ex6: ''' return GiacMethods['sample'](self,*args) @@ -15280,9 +14073,8 @@ cdef class GiacMethods_base: Help for samplerate: samplerate(Lst(clip)) Returns the sampling rate of an audio clip, in Hertz. - See also: 1/ bit_depth 2/ channels 3/ channel_data 4/ duration + See also: 1/ bit_depth 2/ channels 3/ channel_data 4/ duration Ex1:samplerate(readwav("/some/file")) - ''' return GiacMethods['samplerate'](self,*args) @@ -15291,13 +14083,12 @@ cdef class GiacMethods_base: Help for sans_factoriser: sans_factoriser(Opt.) Option of the plotimplicit command. - See also: 1/ plotimplicit + See also: 1/ plotimplicit Ex1: plotimplicit(x^2+y^2-1,x,y,unfactored) Ex2: plotimplicit(x^2+y^2-1,[x,y],unfactored) Ex3: plotimplicit(x^2+y^2+z^2-1,x,y,z,xstep=0.2,ystep=0.2,zstep=0.2,unfactored) Ex4: plotimplicit(x^2+y^2+z^2-1,[x,y,z],xstep=0.2,ystep=0.2,zstep=0.2,unfactored) Ex5: plotimplicit(x^2+y^2+z^2-1,x=0..1,y=0..1,z=0..1,xstep=0.2,ystep=0.2,zstep=0.2,unfactored) - ''' return GiacMethods['sans_factoriser'](self,*args) @@ -15306,10 +14097,9 @@ cdef class GiacMethods_base: Help for saute: saute(NULL or Real(n)) The turtle takes n steps forward without traces (by default n=10). - See also: 1/ avance 2/ recule + See also: 1/ avance 2/ recule Ex1: saute 30 Ex2:saute(30) - ''' return GiacMethods['saute'](self,*args) @@ -15318,11 +14108,10 @@ cdef class GiacMethods_base: Help for scalarProduct: scalarProduct(Vect(v1),Vect(v2)) Scalar product. - See also: 1/ * 2/ cross 3/ .* 4/ hadamard + See also: 1/ * 2/ cross 3/ .* 4/ hadamard Ex1:scalarProduct([1,2],[3,4]) Ex2:scalarProduct([3,2,4],[3,2,4]) Ex3:scalarProduct([[1,2],[3,4]],[[3,2],[4,5]]) - ''' return GiacMethods['scalarProduct'](self,*args) @@ -15331,11 +14120,10 @@ cdef class GiacMethods_base: Help for scalar_product: scalar_product(Vect(v1),Vect(v2)) Scalar product. - See also: 1/ * 2/ cross 3/ .* 4/ hadamard + See also: 1/ * 2/ cross 3/ .* 4/ hadamard Ex1:scalar_product([1,2],[3,4]) Ex2:scalar_product([3,2,4],[3,2,4]) Ex3:scalar_product([[1,2],[3,4]],[[3,2],[4,5]]) - ''' return GiacMethods['scalar_product'](self,*args) @@ -15344,9 +14132,8 @@ cdef class GiacMethods_base: Help for scatterplot: scatterplot(Mtrx) Draws for k=0..nrows, the points (xk,yk) where xk=element row k column 0 and yk=element row k column j (j=1..ncols). - See also: 1/ polygonplot 2/ polygonscatterplot 3/ listplot + See also: 1/ polygonplot 2/ polygonscatterplot 3/ listplot Ex1:scatterplot([[1,2,3],[2,0,1],[-1,2,3]]) - ''' return GiacMethods['scatterplot'](self,*args) @@ -15355,10 +14142,9 @@ cdef class GiacMethods_base: Help for schur: schur(Mtrx(A)) Matrix reduction to Hessenberg form. Returns [P,B] such that B=inv(P)*A*P:SCHUR(A)=hessenberg(A,-1). - See also: 1/ hessenberg + See also: 1/ hessenberg Ex1:schur([[1,2,3],[4,5,6],[7,8,1]]) Ex2:schur([[1,2,3,4],[4,5,6,7],[7,8,9,0],[0,1,2,3]]) - ''' return GiacMethods['schur'](self,*args) @@ -15367,9 +14153,8 @@ cdef class GiacMethods_base: Help for sec: sec(Expr) Secant: sec(x)=1/cos(x). - See also: 1/ cos 2/ asec + See also: 1/ cos 2/ asec Ex1:sec(pi/3) - ''' return GiacMethods['sec'](self,*args) @@ -15378,14 +14163,13 @@ cdef class GiacMethods_base: Help for secant_solver: secant_solver(Opt) Argument for fsolve giving the method for solving a numerical equation. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve(cos(x)=x,x,0..1,bisection_solver) Ex2: fsolve(cos(x)=x,x,0..1,brent_solver) Ex3: fsolve(cos(x)=x,x,0..1,falsepos_solver) Ex4: fsolve(cos(x)=x,x,0,newton_solver) Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) - ''' return GiacMethods['secant_solver'](self,*args) @@ -15394,7 +14178,7 @@ cdef class GiacMethods_base: Help for segment: segment((Pnt or Cplx or Lst([xM,yM])),(Pnt or Cplx or Lst([xN,yN]),[Var],[Var] or Opt) segment(A,B) draws the segment AB and segment([xM,yM],[xN,yN]) draws the vector as origin [xM,yM], of coordinates [xN,yN] (i.e draws segment(M,point(M+N)) or Option of the arc command. - See also: 1/ line 2/ arc + See also: 1/ line 2/ arc Ex1:segment(i,1+i) Ex2:segment(point(i),point(1+i)) Ex3:segment(point(i),point(1+i),A,B) @@ -15402,7 +14186,6 @@ cdef class GiacMethods_base: Ex5:segment([-1,0],point([-1,0]+[2,1])) Ex6: arc(i,1,pi/4,segment) Ex7: affichage( arc(i,1,pi/4,segment),1+rempli) - ''' return GiacMethods['segment'](self,*args) @@ -15411,9 +14194,8 @@ cdef class GiacMethods_base: Help for seidel_spectrum: seidel_spectrum(Graph(G)) Returns the Seidel spectrum of G as a list of lists with two elements, each containing an eigenvalue and its multiplicity. - See also: 1/ graph_spectrum + See also: 1/ graph_spectrum Ex1:seidel_spectrum(graph("clebsch")) - ''' return GiacMethods['seidel_spectrum'](self,*args) @@ -15422,9 +14204,8 @@ cdef class GiacMethods_base: Help for seidel_switch: seidel_switch(Graph(G),Lst(V)) Returns a copy of G in which the edges between vertices in list V and vertices not in V are inverted (replaced with a set of edges from V to other vertices which are not present in G). - See also: 1/ neighbors 2/ graph_complement + See also: 1/ neighbors 2/ graph_complement Ex1:seidel_switch(cycle_graph(5),[1,2]) - ''' return GiacMethods['seidel_switch'](self,*args) @@ -15433,10 +14214,9 @@ cdef class GiacMethods_base: Help for select: select(FncBool(f),Lst(l)) Selects the elements e of l such that f(e)=true. - See also: 1/ remove 2/ range + See also: 1/ remove 2/ range Ex1:select(x->x>=5,[1,2,6,7]) Ex2:select(x->isprime(x),range(20)).^2 - ''' return GiacMethods['select'](self,*args) @@ -15445,9 +14225,8 @@ cdef class GiacMethods_base: Help for semi_augment: semi_augment(Mtrx(A),Mtrx(B)) Returns a matrix made with A and B, with n1+n2 rows and p columns if dim(A)=[n1,p] and dim(B)=[n2,p]. - See also: 1/ augment + See also: 1/ augment Ex1:semi_augment([[68,-21],[56,59],[1,2]],[[68,-21],[56,59]]) - ''' return GiacMethods['semi_augment'](self,*args) @@ -15455,8 +14234,8 @@ cdef class GiacMethods_base: r'''From Giac's documentation: Help for seq: seq(Expr(Xpr),Var(Var)=Int(a..b),[Real(p)]||Expr(Xpr),Var(Var),Real(a),Real(b),[Real(p)]) - Returns the sequence (2 or 3 arg) or the list (4 or 5 arg) obtained when var goes from a to b (step p) in Xpr (or the Xpr is repeated n times or returns the sequence of reals from a to b (step p)). And also seq(expression,variable,list) is equivalent to map(list,unapply(expression,variable)) - See also: 1/ $ 2/ makelist 3/ range 4/ map 5/ unapply + Returns the sequence (2 or 3 arg) or the list (4 or 5 arg) obtained when var goes from a to b (step p) in Xpr (or the Xpr is repeated n times or returns the sequence of reals from a to b (step p)). And also seq(expression,variable,list) is equivalent to map(list,unapply(expression,variable)) + See also: 1/ $ 2/ makelist 3/ range 4/ map 5/ unapply Ex1:seq(0.3,4) Ex2:seq(t,4) Ex3:seq(0,0) @@ -15466,9 +14245,8 @@ cdef class GiacMethods_base: Ex7:seq(2^k,k,0,8) Ex8:seq(2^k,k,0,8,2) Ex9:seq(x^3,x,[1,2,3]) - Ex10: [seq(0.3..2,0.2)] + Ex10: [seq(0.3..2,0.2)] Ex11: a:=(1,2,3);eval(seq(a,4)) - ''' return GiacMethods['seq'](self,*args) @@ -15477,11 +14255,10 @@ cdef class GiacMethods_base: Help for seqplot: seqplot(Expr(f(Var)),Var=[a,xm,xM],Intg(p)) For seeing the pth terms of the sequence u(0)=a,u(n)=f(u(n-1)). - See also: 1/ seqsolve 2/ rsolve + See also: 1/ seqsolve 2/ rsolve Ex1:seqplot(sqrt(2+x),6,5) Ex2:seqplot(sqrt(2+t),t=6,5) Ex3:seqplot(sqrt(2+x),x=[6,1,7],5,affichage=epaisseur_ligne_2) - ''' return GiacMethods['seqplot'](self,*args) @@ -15490,14 +14267,13 @@ cdef class GiacMethods_base: Help for seqsolve: seqsolve((Expr or LstExpr),(Var or LstVar),(InitVal or LstInitVal)) Gives the value of a recurrent sequence (u_{n+1}=f(u_n) or u_{n+k}=f(u_n,u_{n+1}...u_{n+k-1})) or of a system of recurrent sequences. - See also: 1/ rsolve 2/ plotseq 3/ tableseq + See also: 1/ rsolve 2/ plotseq 3/ tableseq Ex1:seqsolve(2x+n,[x,n],1) Ex2:seqsolve(2x+n*3^n,[x,n],1) Ex3:seqsolve(x+y,[x,y,n],[1,1]) Ex4:seqsolve(x+2*y+n+1,[x,y,n],[0,1]) Ex5:seqsolve([x+2*y,n+1+x],[x,y,n],[0,1]) Ex6:seqsolve([x+2*y+n+1,x],[x,y,n],[0,1]) - ''' return GiacMethods['seqsolve'](self,*args) @@ -15506,9 +14282,8 @@ cdef class GiacMethods_base: Help for sequence_graph: sequence_graph(Lst(L)) Returns an undirected graph with the degree sequence equal to the list L. - See also: 1/ degree_sequence 2/ is_graphic_sequence + See also: 1/ degree_sequence 2/ is_graphic_sequence Ex1:sequence_graph(degree_sequence(sequence_graph([3,2,4,2,3,4,5,7]))) - ''' return GiacMethods['sequence_graph'](self,*args) @@ -15517,13 +14292,13 @@ cdef class GiacMethods_base: Help for series: series(Expr,Equal(var=limit_point),[Order],[Dir(1,0,-1)]) Series expansion at finite or infinite points. - See also: 1/ limit 2/ taylor 3/ pad 4/ polynom 5/ truncate + See also: 1/ limit 2/ taylor 3/ pad 4/ polynom 5/ truncate Ex1:series(sin(x)/x,x=0) Ex2:series(sin(x),x=0,6,polynom) Ex3:series(ln(x+x^2)-ln(x),x=0,1) Ex4:series((x^4+x+2)/(x^2+1),x=0,5) Ex5: series("h",8); ln(1+h); - Ex6:series(1/(1+x+y),[x,y],[0,0],5) + Ex6:series(1/(1+x+y),[x,y],[0,0],5) Ex7:series(sin(x*y),[x,y],[1,pi/2],3) Ex8:series(sin((1+h*t)*(pi/2+k*t)),t=0,3,polynom)(t=1) Ex9:series(y^2/x^3,[x,y],[1,-1],3) @@ -15531,7 +14306,6 @@ cdef class GiacMethods_base: Ex11:series(subst(sin(x+y)+cos(y*x),[x,y],h*[x,y]),h=0,6,polynom) Ex12:series(subst(sin(x+y)+cos(y*x),[x,y],h*[x,y]),h=0,6,polynom)(h=1) Ex13: truncate(series(sin(x),x=0,6),6) - ''' return GiacMethods['series'](self,*args) @@ -15540,9 +14314,8 @@ cdef class GiacMethods_base: Help for set_edge_attribute: set_edge_attribute(Graph(G),Edge(e),Seq(tag1=value1,tag2=value2,..)) Stores the attributes to edge e and returns the modified copy of G. - See also: 1/ discard_edge_attribute 2/ get_edge_attribute 3/ list_edge_attributes + See also: 1/ discard_edge_attribute 2/ get_edge_attribute 3/ list_edge_attributes Ex1:set_edge_attribute(cycle_graph(3),[1,2],"cost"=12.4) - ''' return GiacMethods['set_edge_attribute'](self,*args) @@ -15551,9 +14324,8 @@ cdef class GiacMethods_base: Help for set_edge_weight: set_edge_weight(Graph(G),Edge(e),Real(w)) Sets the weight of the edge e in the weighted graph G to w and returns the modified copy of G. - See also: 1/ is_weighted 2/ get_edge_weight 3/ make_weighted 4/ weight_matrix + See also: 1/ is_weighted 2/ get_edge_weight 3/ make_weighted 4/ weight_matrix Ex1:set_edge_weight(graph(%{[1,2],[2,3]%}),[1,2],5) - ''' return GiacMethods['set_edge_weight'](self,*args) @@ -15562,9 +14334,8 @@ cdef class GiacMethods_base: Help for set_graph_attribute: set_graph_attribute(Graph(G),Seq(tag1=value1,tag2=value2,..)) Stores the attributes where each tag is a string, and returns the modified copy of G. - See also: 1/ discard_graph_attribute 2/ get_graph_attribute 3/ list_graph_attributes + See also: 1/ discard_graph_attribute 2/ get_graph_attribute 3/ list_graph_attributes Ex1:set_graph_attribute(cycle_graph(3),"name"="cycle graph") - ''' return GiacMethods['set_graph_attribute'](self,*args) @@ -15573,9 +14344,8 @@ cdef class GiacMethods_base: Help for set_pixel: set_pixel(Intg(x),Intg(y),Intg(col)) Pixel on and adds to the list of pixels. Run show_pixels() to display - See also: 1/ clear 2/ show_pixels 3/ draw_line 4/ draw_rectangle 5/ draw_polygon + See also: 1/ clear 2/ show_pixels 3/ draw_line 4/ draw_rectangle 5/ draw_polygon Ex1: clear(); set_pixel(4); draw_pixel(1,2,red); show_pixels(); - ''' return GiacMethods['set_pixel'](self,*args) @@ -15584,9 +14354,8 @@ cdef class GiacMethods_base: Help for set_vertex_attribute: set_vertex_attribute(Graph(G),Vrtx(v),Seq(tag1=value1,tag2=value2,..)) Stores the attributes to vertex v and returns the modified copy of G. - See also: 1/ discard_vertex_attribute 2/ get_vertex_attribute 3/ list_vertex_attributes + See also: 1/ discard_vertex_attribute 2/ get_vertex_attribute 3/ list_vertex_attributes Ex1:set_vertex_attribute(cycle_graph(3),1,"supply"=27) - ''' return GiacMethods['set_vertex_attribute'](self,*args) @@ -15595,9 +14364,8 @@ cdef class GiacMethods_base: Help for set_vertex_positions: set_vertex_positions(Graph(G),Lst(vp)) Sets the coordinates, given in the list vp, to the vertices of G and returns the modified copy of G. - See also: 1/ draw_graph + See also: 1/ draw_graph Ex1: G:=graph([1,2,3,4,5,6],%{[1,2],[1,4],[4,5],[2,5],[2,3],[3,6],[5,6]%}); G:=set_vertex_positions(G,[[0,0],[0.5,0],[1,0],[0,0.5],[0.5,0.5],[1,0.5]]) - ''' return GiacMethods['set_vertex_positions'](self,*args) @@ -15606,13 +14374,12 @@ cdef class GiacMethods_base: Help for shift: shift(Lst,[Intg(n)]) Returns the list where the last element [or the tail beginning with the n-th element] is moved to the first element and then completed with 0s (by default n=-1);L:=shift(L,2) o L.shift(2). - See also: 1/ rotate 2/ tail + See also: 1/ rotate 2/ tail Ex1:shift([0,1,2,3],2) Ex2:shift([0,1,2,3]) Ex3:shift([0,1,2,3,4]) Ex4: L:=[0,1,2,3];L:=shift(L,2) Ex5: L:=[0,1,2,3];L.shift(2) - ''' return GiacMethods['shift'](self,*args) @@ -15621,14 +14388,13 @@ cdef class GiacMethods_base: Help for shift_phase: shift_phase(Expr) shift_phase returns the expressions where the phase of the evaluated trigonometric expressions is increased by pi/2. - See also: 1/ series + See also: 1/ series Ex1:shift_phase(sin(x)) Ex2:shift_phase('sin(x+pi/2)') Ex3:shift_phase(x+sin(x)) Ex4:shift_phase(x+sin(x)) Ex5:shift_phase(cos(t)) Ex6:shift_phase(tan(u)) - ''' return GiacMethods['shift_phase'](self,*args) @@ -15637,9 +14403,8 @@ cdef class GiacMethods_base: Help for shortest_path: shortest_path(Graph(G),Vrtx(s),Vrtx(t)||Lst(T)) Returns the shortest path from vertex s to vertex t in G. If such path does not exist, returns an empty list. If vector T of vertices from G is given, the list of shortest paths from s to each t int T is returned. - See also: 1/ dijkstra 2/ vertex_distance + See also: 1/ dijkstra 2/ vertex_distance Ex1:shortest_path(cycle_graph(6),1,5) - ''' return GiacMethods['shortest_path'](self,*args) @@ -15648,9 +14413,8 @@ cdef class GiacMethods_base: Help for show_pixels: show_pixels(NULL) Displays the list of pixels. - See also: 1/ set_pixel 2/ clear + See also: 1/ set_pixel 2/ clear Ex1:show_pixels() - ''' return GiacMethods['show_pixels'](self,*args) @@ -15659,13 +14423,12 @@ cdef class GiacMethods_base: Help for shuffle: shuffle(Intg(n)||Lst(L)) Returns a random permutation of [0,1,2,..,n-1] or of the list L. - See also: 1/ permu2cycles 2/ is_permu 3/ permu2mat + See also: 1/ permu2cycles 2/ is_permu 3/ permu2mat Ex1:shuffle(4) Ex2:shuffle(7) Ex3:shuffle([1,3,5,7,9]) Ex4: L:=[1,3,5,7,9];L:=randperm(L) Ex5: L:=[1,3,5,7,9];L.randperm() - ''' return GiacMethods['shuffle'](self,*args) @@ -15674,13 +14437,12 @@ cdef class GiacMethods_base: Help for sierpinski_graph: sierpinski_graph(Intg(n),Intg(k),[triangle]) Returns Sierpiński (triangle) graph S(n,k) (resp. ST(n,k)). - See also: 1/ graph + See also: 1/ graph Ex1:sierpinski_graph(2,4) Ex2:sierpinski_graph(4,3) Ex3:sierpinski_graph(3,4) Ex4:sierpinski_graph(3,2) Ex5:sierpinski_graph(3,3,at_triangle) - ''' return GiacMethods['sierpinski_graph'](self,*args) @@ -15689,10 +14451,9 @@ cdef class GiacMethods_base: Help for sign: sign(Expr) Returns the sign (-1,0,+1) of its argument. - See also: 1/ abs + See also: 1/ abs Ex1:sign(-4) Ex2:sign(4-5) - ''' return GiacMethods['sign'](self,*args) @@ -15701,9 +14462,8 @@ cdef class GiacMethods_base: Help for signature: signature(Permut) Returns the signature of a permutation. - See also: 1/ permu2cycles 2/ is_permu + See also: 1/ permu2cycles 2/ is_permu Ex1:signature([1,0,3,4,2]) - ''' return GiacMethods['signature'](self,*args) @@ -15712,10 +14472,9 @@ cdef class GiacMethods_base: Help for signe: signe(Str(s)) Writes the string s with the font 20 at the point [10,10]. - See also: 1/ ecris + See also: 1/ ecris Ex1:signe("Thomas") Ex2:signe(Thomas) - ''' return GiacMethods['signe'](self,*args) @@ -15724,12 +14483,11 @@ cdef class GiacMethods_base: Help for similarity: similarity(Pnt or Dr3,Real,Angle,Pnt) similarity(B,k,a1,A)=transformation of A in the similarity (center B or axis d, coeff k,angle a1) (or also homothety(B,k*exp(i*a1),A)). - See also: 1/ homothety + See also: 1/ homothety Ex1:similarity(1+i,2,pi/3,i) Ex2:similarity(line(x=y,y=z),2,pi/3,point(-1,2,1)) Ex3: s:=similarity(1+i,2,pi/3);s(i) Ex4: s:=similarity(line(x=y,y=z),2,pi/3),s(point(-1,2,1)) - ''' return GiacMethods['similarity'](self,*args) @@ -15738,10 +14496,9 @@ cdef class GiacMethods_base: Help for simp2: simp2(Intg(A) or Poly(A),Intg(B) or Poly(B)) Returns the list [A/gcd(A,B),B/gcd(A,B)]. - See also: 1/ gcd + See also: 1/ gcd Ex1:simp2(12,18) Ex2:simp2(x^3-1,x^2-1) - ''' return GiacMethods['simp2'](self,*args) @@ -15755,7 +14512,6 @@ cdef class GiacMethods_base: Ex3:simplex_reduce([[-3,2],[1,1]],[3,4],[1,2]) Ex4:simplex_reduce([[-3,2,1,0,3],[1,1,0,1,4],[-1,-2,0,0,0]]) Ex5:simplex_reduce([[2,1,1,1,0,0,2],[1,2,3,0,1,0,5],[2,2,1,0,0,1,6],[-3,-1,-3,1,-1,2,0]]) - ''' return GiacMethods['simplex_reduce'](self,*args) @@ -15764,11 +14520,10 @@ cdef class GiacMethods_base: Help for simplifier: simplifier(Expr) Simplifies an expression. - See also: 1/ normal + See also: 1/ normal Ex1:simplifier(4*atan(1/5)-atan(1/239)) Ex2:simplifier(texpand((sin(3*x)+sin(7*x))/sin(5*x))) Ex3:simplifier(texpand((cos(3*x)+cos(7*x))/cos(5*x))) - ''' return GiacMethods['simplifier'](self,*args) @@ -15777,11 +14532,10 @@ cdef class GiacMethods_base: Help for simplify: simplify(Expr) Simplifies an expression. - See also: 1/ normal + See also: 1/ normal Ex1:simplify(4*atan(1/5)-atan(1/239)) Ex2:simplify(texpand((sin(3*x)+sin(7*x))/sin(5*x))) Ex3:simplify(texpand((cos(3*x)+cos(7*x))/cos(5*x))) - ''' return GiacMethods['simplify'](self,*args) @@ -15790,12 +14544,11 @@ cdef class GiacMethods_base: Help for simpson: simpson(Opt) Option of the area command. - See also: 1/ area + See also: 1/ area Ex1: area(x^2,x=0..1,5,simpson) Ex2: area(x^2,x=0..1,5,rombergt) Ex3: area(x^2,x=0..1,5,rombergm) Ex4:simpson(area(x^2,x=0..1,5,gauss15)) - ''' return GiacMethods['simpson'](self,*args) @@ -15804,10 +14557,9 @@ cdef class GiacMethods_base: Help for simult: simult(Mtrx(A),Mtrx(B)) Returns the matrix where the column of index k is solution of A*X=column of index k of B (=B[0..nr-1,k..k] with nr=number of rows of B). - See also: 1/ rref 2/ linsolve + See also: 1/ rref 2/ linsolve Ex1:simult([[3,1],[3,2]],[[-2],[2]]) Ex2:simult([[3,1],[3,2]],[[-2,1],[2,-1]]) - ''' return GiacMethods['simult'](self,*args) @@ -15816,10 +14568,9 @@ cdef class GiacMethods_base: Help for sin: sin(Expr or Opt) Sine or option of the convert or convertir command (id trigsin). - See also: 1/ asin 2/ convert 3/ trigsin + See also: 1/ asin 2/ convert 3/ trigsin Ex1:sin(0) Ex2: convert(cos(x)^4+sin(x)^2,sin) - ''' return GiacMethods['sin'](self,*args) @@ -15828,9 +14579,8 @@ cdef class GiacMethods_base: Help for sin2costan: sin2costan(Expr) Replaces sin(x) by cos(x)*tan(x) in the argument. - See also: 1/ tan2sincos 2/ cos2sintan 3/ tan2sincos2 4/ tan2cossin2 + See also: 1/ tan2sincos 2/ cos2sintan 3/ tan2sincos2 4/ tan2cossin2 Ex1:sin2costan(sin(x)) - ''' return GiacMethods['sin2costan'](self,*args) @@ -15839,9 +14589,8 @@ cdef class GiacMethods_base: Help for sinc: sinc(Expr(x)) Returns the value of the cardinal sine function at x. - See also: 1/ sin + See also: 1/ sin Ex1:sinc(pi*x) - ''' return GiacMethods['sinc'](self,*args) @@ -15850,11 +14599,10 @@ cdef class GiacMethods_base: Help for sincos: sincos(Expr or Opt) Transforms the complex exponential into sine and cosine (id exp2trig) or option of the convert or convertir command (id sincos). - See also: 1/ trig2trig 2/ trig2exp 3/ atrig2ln 4/ convert + See also: 1/ trig2trig 2/ trig2exp 3/ atrig2ln 4/ convert Ex1:sincos(exp(i*x)) Ex2:sincos(exp(-i*x)) Ex3: convert(exp(i*x),sincos) - ''' return GiacMethods['sincos'](self,*args) @@ -15863,7 +14611,7 @@ cdef class GiacMethods_base: Help for single_inter: single_inter(Curve,Curve,[Pnt(A)||LstPnt(L)]) Gives one of the points of intersection of 2 curves or surfaces (or the intersection near A or not in L). - See also: 1/ intersect 2/ head + See also: 1/ intersect 2/ head Ex1:single_inter(line(i,1-i),line(0,1)) Ex2:single_inter(line(i,1-i),circle(0,1)) Ex3:single_inter(line(i,1+2*i),circle(0,1),[point(i)]) @@ -15871,7 +14619,6 @@ cdef class GiacMethods_base: Ex5:single_inter(circle(1,sqrt(2)),circle(0,1)) Ex6:single_inter(plane(x=y),plane(y=z)) Ex7:single_inter(line(x=y+1,y=2*z),plane(y=z)) - ''' return GiacMethods['single_inter'](self,*args) @@ -15880,9 +14627,8 @@ cdef class GiacMethods_base: Help for sinh: sinh(Expr) Hyperbolic sine. - See also: 1/ asinh + See also: 1/ asinh Ex1:sinh(0) - ''' return GiacMethods['sinh'](self,*args) @@ -15891,9 +14637,8 @@ cdef class GiacMethods_base: Help for sizes: sizes(Lst or Str or Seq) Returns the list of sizes of a list of lists. - See also: 1/ size 2/ dim + See also: 1/ size 2/ dim Ex1:sizes([[1,2,3],[1,2],[1]]) - ''' return GiacMethods['sizes'](self,*args) @@ -15902,7 +14647,7 @@ cdef class GiacMethods_base: Help for slope: slope(Line||Pnt||Cplx,[Pnt||Cplx]) Returns the slope of the line defined in the argument or is an attribute of line. - See also: 1/ line 2/ tangent 3/ LinTan 4/ slopeatraw 5/ slopeat + See also: 1/ line 2/ tangent 3/ LinTan 4/ slopeatraw 5/ slopeat Ex1:slope(line(1,2i)) Ex2:slope(segment(1,2i)) Ex3:slope(1,2i) @@ -15911,7 +14656,6 @@ cdef class GiacMethods_base: Ex6:slope(tangent(plotfunc(sin(x)),pi/4)) Ex7:slope(LineTan(sin(x),pi/4)) Ex8: line(point(1,2),slope=-1) - ''' return GiacMethods['slope'](self,*args) @@ -15920,11 +14664,10 @@ cdef class GiacMethods_base: Help for slopeat: slopeat(Line, Pnt||Cplx(z0)) slopeat(d,z0) displays at the point(z0), with a legend, the value of the slope of the line or segment d. - See also: 1/ slope 2/ slopeatraw + See also: 1/ slope 2/ slopeatraw Ex1: A:=point(0);B:=point(1+i);slopeat(droite(A,B),(1+i)/2) Ex2: s:=segment(1-i,i);slopeat(s,point(0.4)) Ex3: t:=tangent(plotfunc(sin(x)),pi/4);slopeat(t,0) - ''' return GiacMethods['slopeat'](self,*args) @@ -15933,12 +14676,11 @@ cdef class GiacMethods_base: Help for slopeatraw: slopeatraw(Line, Pnt||Cplx(z0)) slopeatraw(d,z0) displays at point(z0), the value of the slope of the line or segment d. - See also: 1/ slope 2/ slopeat + See also: 1/ slope 2/ slopeat Ex1: A:=point(0);B:=point(1+i);slopeatraw(droite(A,B),(1+i)/2) Ex2: s:=segment(1-i,i);slopeatraw(s,point(0.4)) Ex3:slopeatraw(tangent(plotfunc(sin(x)),pi/4),0) Ex4:slopeatraw((LineTan sin(x),pi/4),i) - ''' return GiacMethods['slopeatraw'](self,*args) @@ -15947,10 +14689,9 @@ cdef class GiacMethods_base: Help for smith: smith(Mtrx(A)) Smith normal form of a matrix with polynomial coefficients : returns U,D,V such that U and V are invertible, D is diagonal, and U*A*V=D. - See also: 1/ hermite 2/ ismith 3/ ihermite + See also: 1/ hermite 2/ ismith 3/ ihermite Ex1: n:=10; A:=ranm(n,n) % 17; U,D,V:=smith(x*idn(n)-A);normal(U*(x*idn(n)-A)*V-D); diag(D); Ex2: GF(3,5,g); n:=3; A:=ranm(n,n,g); U,D,V:=smith(x*idn(n)-A);normal(U*(x*idn(n)-A)*V-D); diag(D); - ''' return GiacMethods['smith'](self,*args) @@ -15959,11 +14700,10 @@ cdef class GiacMethods_base: Help for smod: smod(Intg,Intg) Returns the Euclidean symmetric remainder of two integers. - See also: 1/ irem 2/ iquo 3/ mod 4/ fracmod + See also: 1/ irem 2/ iquo 3/ mod 4/ fracmod Ex1:smod(8,3) Ex2:smod(10,4) Ex3:smod(11,7) - ''' return GiacMethods['smod'](self,*args) @@ -15972,12 +14712,11 @@ cdef class GiacMethods_base: Help for snedecor: snedecor(Intg(n),Intg(m),Real(x0)) Returns the probability density of the Fisher-Snedecor law (n and m are the numbers of degrees of freedom). - See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm + See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm Ex1:snedecor(4,10,2.1) Ex2:snedecor(4,4,2.1) Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) - ''' return GiacMethods['snedecor'](self,*args) @@ -15986,10 +14725,9 @@ cdef class GiacMethods_base: Help for snedecor_cdf: snedecor_cdf(Intg(n),Intg(m),Real(x0)) Returns the probability that a Fisher-Snedecor random variable is less than x0 (n and m are the numbers of degrees of freedom). - See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd + See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd Ex1:snedecor_cdf(4,4,2.1) Ex2:snedecor_cdf(4,10,3.5) - ''' return GiacMethods['snedecor_cdf'](self,*args) @@ -15998,10 +14736,9 @@ cdef class GiacMethods_base: Help for snedecor_icdf: snedecor_icdf(Intg(n),Intg(m),Real(p)) Returns h such as the probability that a Fisher-Snedecor random variable is less than h is p (n and m are the numbers of degrees of freedom and 0<=p<=1). - See also: 1/ fisher_cdf 2/ fisherd + See also: 1/ fisher_cdf 2/ fisherd Ex1:snedecor_icdf(4,10,0.95) Ex2:snedecor_icdf(4,10,0.05) - ''' return GiacMethods['snedecor_icdf'](self,*args) @@ -16010,12 +14747,11 @@ cdef class GiacMethods_base: Help for snedecord: snedecord(Intg(n),Intg(m),Real(x0)) Returns the probability density of the Fisher-Snedecor law (n and m are the numbers of degrees of freedom). - See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm + See also: 1/ fisher_cdf 2/ fisher_icdf 3/ randvector 4/ ranm Ex1:snedecord(4,10,2.1) Ex2:snedecord(4,4,2.1) Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) - ''' return GiacMethods['snedecord'](self,*args) @@ -16024,10 +14760,9 @@ cdef class GiacMethods_base: Help for snedecord_cdf: snedecord_cdf(Intg(n),Intg(m),Real(x0)) Returns the probability that a Fisher-Snedecor random variable is less than x0 (n and m are the numbers of degrees of freedom). - See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd + See also: 1/ UTPF 2/ fisher_icdf 3/ fisherd Ex1:snedecord_cdf(4,4,2.1) Ex2:snedecord_cdf(4,10,3.5) - ''' return GiacMethods['snedecord_cdf'](self,*args) @@ -16036,10 +14771,9 @@ cdef class GiacMethods_base: Help for snedecord_icdf: snedecord_icdf(Intg(n),Intg(m),Real(p)) Returns h such as the probability that a Fisher-Snedecor random variable is less than h is p (n and m are the numbers of degrees of freedom and 0<=p<=1). - See also: 1/ fisher_cdf 2/ fisherd + See also: 1/ fisher_cdf 2/ fisherd Ex1:snedecord_icdf(4,10,0.95) Ex2:snedecord_icdf(4,10,0.05) - ''' return GiacMethods['snedecord_icdf'](self,*args) @@ -16048,10 +14782,9 @@ cdef class GiacMethods_base: Help for solid_line: solid_line(Opt) Option of the display command for a line. - See also: 1/ display + See also: 1/ display Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) - ''' return GiacMethods['solid_line'](self,*args) @@ -16060,12 +14793,11 @@ cdef class GiacMethods_base: Help for solve: solve(Expr,[Var]) Solves a (or a set of) polynomial equation. - See also: 1/ linsolve 2/ proot 3/ fsolve 4/ csolve 5/ nSolve + See also: 1/ linsolve 2/ proot 3/ fsolve 4/ csolve 5/ nSolve Ex1:solve(x^2-3=1) Ex2:solve(x^3-3*y,y) Ex3:solve([y-z=0,z-x=0,x-y=0,x-1+y+z=0],[x,y,z]) Ex4:solve([x^2-y^2=0,x^2-z^2=0],[x,y,z]) - ''' return GiacMethods['solve'](self,*args) @@ -16074,7 +14806,7 @@ cdef class GiacMethods_base: Help for somme: somme(Expr,Var,VarMin(a),VarMax(b),[VarStep(p)]) Discrete sum (with 2 or 4 arguments return then sum from a to b if a<=b or of the opposite of the sum from b+1 to a-1 if a>b+1 or 0 if a=b+1) or the discrete primitive or sum of the elements of a list or a sequence. - See also: 1/ + + See also: 1/ + Ex1:somme(1/n^2,n,1,17) Ex2:somme(1/n^2,n=1..17) Ex3:somme(1/n^2,n,17,1) @@ -16085,7 +14817,6 @@ cdef class GiacMethods_base: Ex8:somme([[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9]]) Ex9:somme(1/(x*(x+1)),x) Ex10:somme(cos(n*x),n) - ''' return GiacMethods['somme'](self,*args) @@ -16094,10 +14825,9 @@ cdef class GiacMethods_base: Help for sommet: sommet(Op or Fnct) Returns the top of an operator. - See also: 1/ feuille 2/ quote + See also: 1/ feuille 2/ quote Ex1:sommet(quote(gcd(45,123))) Ex2:sommet('gcd(45,123)') - ''' return GiacMethods['sommet'](self,*args) @@ -16106,13 +14836,12 @@ cdef class GiacMethods_base: Help for sort: sort(LstReal or Seq [Fnc]) Returns the sorted list (or sequence) with increasing order according to the second argument which defines a weak strict ordering or sorts and collects equal terms in sums and products. - See also: 1/ SortA 2/ SortD + See also: 1/ SortA 2/ SortD Ex1:sort([3,2,2,4,1,0]) Ex2:sort(3,2.1,2,4,1,0) Ex3:sort([3,4,2],(x,y)->x>y) Ex4:sort([[1,2],[2,3],[4,3]],(x,y)->when(x[1]==y[1],x[0]>y[0],x[1]>y[1])) Ex5:sort(y*x*2+x*y) - ''' return GiacMethods['sort'](self,*args) @@ -16121,11 +14850,10 @@ cdef class GiacMethods_base: Help for sorta: sorta(LstReal||Seq×||Mtrx) Sorts the list in increasing order or sorts the columns of the matrix so the first row is in increasing order. - See also: 1/ SortA 2/ sortd 3/ sort + See also: 1/ SortA 2/ sortd 3/ sort Ex1:sorta(3,4,2) Ex2:sorta([3,4,2]) Ex3:sorta([[3,4,2],[6,4,5]]) - ''' return GiacMethods['sorta'](self,*args) @@ -16134,11 +14862,10 @@ cdef class GiacMethods_base: Help for sortd: sortd(LstReal||Seq||Mtrx) Sorts the list in decreasing order or sorts the columns of the matrix so the first row is in decreasing order. - See also: 1/ SortD 2/ sorta 3/ sort + See also: 1/ SortD 2/ sorta 3/ sort Ex1:sortd(3,4,2) Ex2:sortd([3,4,2]) Ex3:sortd([[3,4,2],[6,4,5]]) - ''' return GiacMethods['sortd'](self,*args) @@ -16147,13 +14874,12 @@ cdef class GiacMethods_base: Help for sorted: sorted(LstReal or Seq [Fnc]) Returns the sorted list (or sequence) with increasing order according to the second argument which defines a weak strict ordering or sorts and collects equal terms in sums and products. - See also: 1/ SortA 2/ SortD + See also: 1/ SortA 2/ SortD Ex1:sorted([3,2,2,4,1,0]) Ex2:sorted(3,2.1,2,4,1,0) Ex3:sorted([3,4,2],(x,y)->x>y) Ex4:sorted([[1,2],[2,3],[4,3]],(x,y)->when(x[1]==y[1],x[0]>y[0],x[1]>y[1])) Ex5:sorted(y*x*2+x*y) - ''' return GiacMethods['sorted'](self,*args) @@ -16162,10 +14888,9 @@ cdef class GiacMethods_base: Help for soundsec: soundsec(Intg(n),[Intg(N)]) Generates a vector coding n seconds of time/N (default N=44100). - See also: 1/ readwav 2/ writewav 3/ playsnd + See also: 1/ readwav 2/ writewav 3/ playsnd Ex1:soundsec(1) Ex2:soundsec(1,22100) - ''' return GiacMethods['soundsec'](self,*args) @@ -16174,10 +14899,9 @@ cdef class GiacMethods_base: Help for spanning_tree: spanning_tree(Graph(G),[Vrtx(r)]) Returns a spanning tree of undirected graph G [with the vertex r as the root node]. - See also: 1/ number_of_spanning_trees 2/ minimal_spanning_tree + See also: 1/ number_of_spanning_trees 2/ minimal_spanning_tree Ex1:spanning_tree(graph("petersen")) Ex2:spanning_tree(graph("petersen"),5) - ''' return GiacMethods['spanning_tree'](self,*args) @@ -16186,10 +14910,9 @@ cdef class GiacMethods_base: Help for sphere: sphere((Pnt or Vect),(Pnt or Real)) sphere(A,B) (resp sphere(A,r)) draws the sphere with diameter AB (resp center A and radius r) in 3D space. - See also: 1/ circle + See also: 1/ circle Ex1:sphere([0,0,0],[2,2,2]) Ex2:sphere([1,1,1],1) - ''' return GiacMethods['sphere'](self,*args) @@ -16198,9 +14921,8 @@ cdef class GiacMethods_base: Help for spline: spline(Lst(lx),Lst(ly),Var(x),Intg(d)) Natural spline through the points given by the lx and ly lists, variable x, degree d. - See also: 1/ lagrange + See also: 1/ lagrange Ex1:spline([0,1,2],[1,3,0],x,3) - ''' return GiacMethods['spline'](self,*args) @@ -16209,10 +14931,9 @@ cdef class GiacMethods_base: Help for split: split(Expr(Xpr),Lst(var1,var2)) Splits the two variables var1,var2 of the expression Xpr (without denominator) or returns [0]. - See also: 1/ factor + See also: 1/ factor Ex1:split(x^3*y^2-y^2+x^3-1,[x,y]) Ex2:split(x^3*y^2-y^2+x^3+1,[x,y]) - ''' return GiacMethods['split'](self,*args) @@ -16221,8 +14942,7 @@ cdef class GiacMethods_base: Help for spring: spring(Opt) Option for the draw_graph command. - See also: 1/ planar 2/ tree 3/ draw_graph - + See also: 1/ planar 2/ tree 3/ draw_graph ''' return GiacMethods['spring'](self,*args) @@ -16231,10 +14951,9 @@ cdef class GiacMethods_base: Help for sq: sq(Seq) Is the name of the function (ℝ^n -> ℝ)=sum of the squares of the arguments. - See also: 1/ sqrt + See also: 1/ sqrt Ex1:sq(5) Ex2:sq(1,2,3) - ''' return GiacMethods['sq'](self,*args) @@ -16243,10 +14962,9 @@ cdef class GiacMethods_base: Help for sqrfree: sqrfree(Expr) Factorization of the its argument gathering the terms with the same exponent. - See also: 1/ factor + See also: 1/ factor Ex1:sqrfree(x^4-2*x^2+1) Ex2:sqrfree((x-2)^7*(x+2)^7*(x^4-2*x^2+1)) - ''' return GiacMethods['sqrfree'](self,*args) @@ -16255,10 +14973,9 @@ cdef class GiacMethods_base: Help for sqrt: sqrt(Expr) Square root. - See also: 1/ surd 2/ ^ + See also: 1/ surd 2/ ^ Ex1:sqrt(50) Ex2:sqrt(x^2) - ''' return GiacMethods['sqrt'](self,*args) @@ -16267,12 +14984,11 @@ cdef class GiacMethods_base: Help for square: square((Pnt(A) or Cplx),(Pnt(B) or Cplx),[Pnt(P),Var(C),Var(D)]) Returns and draws the square of side AB (ABCD is direct) (in the plane ABP). - See also: 1/ rhombus 2/ quadrilateral + See also: 1/ rhombus 2/ quadrilateral Ex1:square(i,1+i) Ex2:square(i,1+i,C,D) Ex3:square(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:square(point(0,0,0),point(3,3,3),point(0,0,3),C,D) - ''' return GiacMethods['square'](self,*args) @@ -16281,10 +14997,9 @@ cdef class GiacMethods_base: Help for square_point: square_point(Opt) Option of the display command for a point. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) - ''' return GiacMethods['square_point'](self,*args) @@ -16293,10 +15008,9 @@ cdef class GiacMethods_base: Help for srand: srand() srand returns an integer and initializes the sequence of random numbers. - See also: 1/ RandSeed + See also: 1/ RandSeed Ex1:srand(12) Ex2: srand - ''' return GiacMethods['srand'](self,*args) @@ -16305,9 +15019,8 @@ cdef class GiacMethods_base: Help for sst: sst(NULL) Steps 1 instruction. - See also: 1/ + See also: 1/ Ex1:sst() - ''' return GiacMethods['sst'](self,*args) @@ -16316,9 +15029,8 @@ cdef class GiacMethods_base: Help for sst_in: sst_in(NULL) Enters into a function in step-by-step mode. - See also: 1/ + See also: 1/ Ex1:sst_in() - ''' return GiacMethods['sst_in'](self,*args) @@ -16327,9 +15039,8 @@ cdef class GiacMethods_base: Help for st_ordering: st_ordering(Graph(G),Vrtx(s),Vrtx(t)) Returns ST numbering for the biconnected graph G with source s and sink (target) t. - See also: 1/ is_biconnected + See also: 1/ is_biconnected Ex1:st_ordering(graph("petersen"),1,2) - ''' return GiacMethods['st_ordering'](self,*args) @@ -16338,9 +15049,8 @@ cdef class GiacMethods_base: Help for star_graph: star_graph(Intg(n)) Returns the complete bipartite graph complete_graph(1,n). - See also: 1/ complete_graph 2/ wheel_graph + See also: 1/ complete_graph 2/ wheel_graph Ex1:star_graph(5) - ''' return GiacMethods['star_graph'](self,*args) @@ -16349,10 +15059,9 @@ cdef class GiacMethods_base: Help for star_point: star_point(Opt) Option of the display command for a point. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) - ''' return GiacMethods['star_point'](self,*args) @@ -16361,11 +15070,10 @@ cdef class GiacMethods_base: Help for stdDev: stdDev(Lst||Mtrx,[Lst]) Returns an unbiased estimate of the population standard deviation of the sample (first argument) with an optional list of weight as second argument. - See also: 1/ mean 2/ stddev + See also: 1/ mean 2/ stddev Ex1:stdDev([1,2,3]) Ex2:stdDev([1,2,3],[1,2,1]) Ex3:stdDev([[1,2,3],[5,6,7]]) - ''' return GiacMethods['stdDev'](self,*args) @@ -16374,11 +15082,10 @@ cdef class GiacMethods_base: Help for stddev: stddev(Lst||Mtrx,[Lst]) Returns the standard deviation of the elements of its argument with an optional second argument as weight or the list of standard deviations of the columns of a matrix. - See also: 1/ mean 2/ variance 3/ stddevp + See also: 1/ mean 2/ variance 3/ stddevp Ex1:stddev([1,2,3]) Ex2:stddev([1,2,3],[1,2,1]) Ex3:stddev([[1,2,3],[5,6,7]]) - ''' return GiacMethods['stddev'](self,*args) @@ -16387,11 +15094,10 @@ cdef class GiacMethods_base: Help for stddevp: stddevp(Lst||Mtrx,[Lst]) Returns an unbiased estimate of the population standard deviation of the sample (first argument) with an optional list of weight as second argument. - See also: 1/ mean 2/ stddev + See also: 1/ mean 2/ stddev Ex1:stddevp([1,2,3]) Ex2:stddevp([1,2,3],[1,2,1]) Ex3:stddevp([[1,2,3],[5,6,7]]) - ''' return GiacMethods['stddevp'](self,*args) @@ -16400,14 +15106,13 @@ cdef class GiacMethods_base: Help for steffenson_solver: steffenson_solver(Opt) Argument for fsolve giving the method for solving a numerical equation. - See also: 1/ fsolve + See also: 1/ fsolve Ex1: fsolve(cos(x)=x,x,0..1,bisection_solver) Ex2: fsolve(cos(x)=x,x,0..1,brent_solver) Ex3: fsolve(cos(x)=x,x,0..1,falsepos_solver) Ex4: fsolve(cos(x)=x,x,0,newton_solver) Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) - ''' return GiacMethods['steffenson_solver'](self,*args) @@ -16416,9 +15121,8 @@ cdef class GiacMethods_base: Help for stereo2mono: stereo2mono(Lst(clip)) Returns an audio clip with all channels in the input clip downmixed to a single one. - See also: 1/ channel_data 2/ mean 3/ createwav + See also: 1/ channel_data 2/ mean 3/ createwav Ex1:stereo2mono(readwav("/some/file")) - ''' return GiacMethods['stereo2mono'](self,*args) @@ -16427,12 +15131,11 @@ cdef class GiacMethods_base: Help for str: str(Expr or Opt) Returns the evaluated expression as a string or is an option of the convert or convertir command (id string). - See also: 1/ expr 2/ format 3/ convert + See also: 1/ expr 2/ format 3/ convert Ex1:str(1.23) Ex2:str(a:=12) Ex3:str(quote(a:=12)) Ex4: convert(quote(a:=12),string) - ''' return GiacMethods['str'](self,*args) @@ -16441,9 +15144,8 @@ cdef class GiacMethods_base: Help for strongly_connected_components: strongly_connected_components(Graph(G)) Returns the list of strongly connected components in digraph G. - See also: 1/ connected_components 2/ is_connected 3/ is_strongly_connected + See also: 1/ connected_components 2/ is_connected 3/ is_strongly_connected Ex1:strongly_connected_components(digraph([1,2,3],%{[1,2],[1,3],[2,3],[3,2]%})) - ''' return GiacMethods['strongly_connected_components'](self,*args) @@ -16452,10 +15154,9 @@ cdef class GiacMethods_base: Help for student: student(Intg(n),Real(x0)) Returns the probability density of the Student law (n is the number of degrees of freedom). - See also: 1/ student_cdf 2/ student_icdf + See also: 1/ student_cdf 2/ student_icdf Ex1:student(3,5.2) Ex2:student(1,5.2) - ''' return GiacMethods['student'](self,*args) @@ -16464,10 +15165,9 @@ cdef class GiacMethods_base: Help for student_cdf: student_cdf(Intg(n),Real(x0)) Returns the probability that a Student random variable is less than x0 (n is the number of degrees of freedom). - See also: 1/ UTPT 2/ student_icdf 3/ studentd + See also: 1/ UTPT 2/ student_icdf 3/ studentd Ex1:student_cdf(3,2.35) Ex2:student_cdf(3,-3.2) - ''' return GiacMethods['student_cdf'](self,*args) @@ -16476,10 +15176,9 @@ cdef class GiacMethods_base: Help for student_icdf: student_icdf(Intg(n),Real(p)) Returns h such as the probability that a Student random variable is less than h is p (n is the number of degrees of freedom and 0<=p<=1). - See also: 1/ student_cdf 2/ studentd + See also: 1/ student_cdf 2/ studentd Ex1:student_icdf(3,0.95) Ex2:student_icdf(3,0.05) - ''' return GiacMethods['student_icdf'](self,*args) @@ -16488,10 +15187,9 @@ cdef class GiacMethods_base: Help for studentd: studentd(Intg(n),Real(x0)) Returns the probability density of the Student law (n is the number of degrees of freedom). - See also: 1/ student_cdf 2/ student_icdf + See also: 1/ student_cdf 2/ student_icdf Ex1:studentd(3,5.2) Ex2:studentd(1,5.2) - ''' return GiacMethods['studentd'](self,*args) @@ -16500,10 +15198,9 @@ cdef class GiacMethods_base: Help for studentt: studentt(Lst,Real,[Real],Fnc,[Real]) T-Test/Student law: arg1=[success,trial] or [mean,sample size] or data, arg2=proportion or data, arg3 optional if data=sigma, arg4 alternative '!=' or '>' or '<', arg5 optional alpha confidence level. - See also: 1/ normalt 2/ chisquaret 3/ kolmogorovt + See also: 1/ normalt 2/ chisquaret 3/ kolmogorovt Ex1:studentt([10,20],.5,.02,'!=',0.1) Ex2:studentt([0.48,20],0.5,0.1,'<') - ''' return GiacMethods['studentt'](self,*args) @@ -16512,13 +15209,12 @@ cdef class GiacMethods_base: Help for sturm: sturm(Poly,[Var],[Cplx(a)],[Cplx(b)]) Sturm sequence corresponding to a polynomial or number of sign changes of this polynomial in ]a;b]. - See also: 1/ sturmseq 2/ sturmab + See also: 1/ sturmseq 2/ sturmab Ex1:sturm(x^3-1,x) Ex2:sturm(x^5-x^3,x) Ex3:sturm((x^5-x^3)/(x+2),x) Ex4:sturm(x^5-x^3,x,-2,5) Ex5:sturm(x^3-1,x,-2-i,5+3i) - ''' return GiacMethods['sturm'](self,*args) @@ -16527,10 +15223,9 @@ cdef class GiacMethods_base: Help for sturmab: sturmab(Poly,Var,Cplx(a),Cplx(b)) Number of sign changes of a polynomial in ]a;b] or of complex roots in a..b if a or b is non-real. - See also: 1/ sturm 2/ sturmseq 3/ realroot + See also: 1/ sturm 2/ sturmseq 3/ realroot Ex1:sturmab(x^3-1,x,-2,5) Ex2:sturmab(x^3-1,x,-2-i,5+3i) - ''' return GiacMethods['sturmab'](self,*args) @@ -16539,11 +15234,10 @@ cdef class GiacMethods_base: Help for sturmseq: sturmseq(Poly,[Var]) Sturm sequence corresponding to a polynomial or to a rational fraction. - See also: 1/ sturm 2/ sturmab + See also: 1/ sturm 2/ sturmab Ex1:sturmseq(x^3-1,x) Ex2:sturmseq(x^5-x^3,x) Ex3:sturmseq((x^5-x^3)/(x+2),x) - ''' return GiacMethods['sturmseq'](self,*args) @@ -16552,10 +15246,9 @@ cdef class GiacMethods_base: Help for style: style(Opt) Local option (Maple compatibility) of a graphic command to plot a line with dots with style=point. - See also: 1/ line_width + See also: 1/ line_width Ex1: segment(0,point(1,1),style=point) Ex2: line(y=x,style=point,display=green+line_width_2) - ''' return GiacMethods['style'](self,*args) @@ -16564,9 +15257,8 @@ cdef class GiacMethods_base: Help for subMat: subMat(Mtrx(A),Intg(n1),Intg(n2),Intg(n3),Intg(n4).) Extracts a sub matrix with first element=A[n1,n2] and last element=A[n3,n4]. - See also: 1/ mid + See also: 1/ mid Ex1:subMat([[1,2],[3,4],[5,6]],1,0,2,1) - ''' return GiacMethods['subMat'](self,*args) @@ -16575,9 +15267,8 @@ cdef class GiacMethods_base: Help for subdivide_edges: subdivide_edges(Graph(G),Lst(E),[Intg(r)]) Inserts r (by default 1) new vertices to each edge/arc in G contained in the list E (which may be a single edge/arc) and returns the modified copy of G. New vertices are labelled with smallest available integers. - See also: 1/ edges + See also: 1/ edges Ex1:subdivide_edges(complete_graph(2,3),[[1,3],[1,4]],2) - ''' return GiacMethods['subdivide_edges'](self,*args) @@ -16586,9 +15277,8 @@ cdef class GiacMethods_base: Help for subgraph: subgraph(Graph(G),Lst(E)) Returns the subgraph of G defined by the edges in list E. - See also: 1/ induced_subgraph 2/ highlight_subgraph + See also: 1/ induced_subgraph 2/ highlight_subgraph Ex1:subgraph(complete_graph(5),[[1,2],[2,3],[3,4],[4,1]]) - ''' return GiacMethods['subgraph'](self,*args) @@ -16597,11 +15287,10 @@ cdef class GiacMethods_base: Help for subs: subs(Expr or Var=value,Var=value or Expr) Equivalent of subst except in maple_mode where the arguments are switched over, in maple_mode choose the second example. - See also: 1/ subst 2/ maple_mode 3/ algsubs 4/ () + See also: 1/ subst 2/ maple_mode 3/ algsubs 4/ () Ex1:subs(1/(4+x^2),x=2) Ex2:subs(x=2,1/(4+x^2)) Ex3: f:=1/(4+x^2);f(x=2) - ''' return GiacMethods['subs'](self,*args) @@ -16614,7 +15303,6 @@ cdef class GiacMethods_base: Ex2:subsop([[1,2],[3,4]],[1,1]=5) Ex3:subsop([[1,2],[3,4]],1=[10,8]) Ex4:subsop([0,1,2,3],'1=NULL') - ''' return GiacMethods['subsop'](self,*args) @@ -16623,7 +15311,7 @@ cdef class GiacMethods_base: Help for subst: subst(Expr,Var(v)=value(a)) Substitutes a value for a variable in an expression. - See also: 1/ eval 2/ algsubs 3/ subs 4/ () + See also: 1/ eval 2/ algsubs 3/ subs 4/ () Ex1:subst(1/(4+x^2),x=2) Ex2:subst(1/(x^2+y^2),x=2,y=3) Ex3:subst(1/(x^2+y^2+z^2),[x=2,y=3,z=1]) @@ -16631,7 +15319,6 @@ cdef class GiacMethods_base: Ex5:subst('integrate(sin(x^2)*x,x)',x=sqrt(t)) Ex6:subst('sum(x^(n+1)/((n+p+1)*(n+1)),n,0,inf)',n=k-1) Ex7: f:=1/(x^2+y^2;f(x=2,y=3) - ''' return GiacMethods['subst'](self,*args) @@ -16640,7 +15327,7 @@ cdef class GiacMethods_base: Help for substituer: substituer(Expr,Var(v)=value(a)) Substitutes a value for a variable in an expression. - See also: 1/ eval 2/ algsubs 3/ subs 4/ () + See also: 1/ eval 2/ algsubs 3/ subs 4/ () Ex1:substituer(1/(4+x^2),x=2) Ex2:substituer(1/(x^2+y^2),x=2,y=3) Ex3:substituer(1/(x^2+y^2+z^2),[x=2,y=3,z=1]) @@ -16648,7 +15335,6 @@ cdef class GiacMethods_base: Ex5:substituer('integrate(sin(x^2)*x,x)',x=sqrt(t)) Ex6:substituer('sum(x^(n+1)/((n+p+1)*(n+1)),n,0,inf)',n=k-1) Ex7: f:=1/(x^2+y^2;f(x=2,y=3) - ''' return GiacMethods['substituer'](self,*args) @@ -16657,12 +15343,11 @@ cdef class GiacMethods_base: Help for subtype: subtype(Expr) Returns 1 for a sequence,2 for a set, 10 for a polynomial and 0 otherwise. - See also: 1/ DOM_LIST 2/ type + See also: 1/ DOM_LIST 2/ type Ex1:subtype(1,2,3) Ex2:subtype(set[1,2,3]) Ex3:subtype(poly1[1,2,3]) Ex4:subtype([1,2,3]) - ''' return GiacMethods['subtype'](self,*args) @@ -16671,7 +15356,7 @@ cdef class GiacMethods_base: Help for sum: sum(Expr,Var,VarMin(a),VarMax(b),[VarStep(p)]) Discrete sum (with 2 or 4 arguments return then sum from a to b if a<=b or of the opposite of the sum from b+1 to a-1 if a>b+1 or 0 if a=b+1) or the discrete primitive or sum of the elements of a list or a sequence. - See also: 1/ + + See also: 1/ + Ex1:sum(1/n^2,n,1,17) Ex2:sum(1/n^2,n=1..17) Ex3:sum(1/n^2,n,17,1) @@ -16682,7 +15367,6 @@ cdef class GiacMethods_base: Ex8:sum([[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9]]) Ex9:sum(1/(x*(x+1)),x) Ex10:sum(cos(n*x),n) - ''' return GiacMethods['sum'](self,*args) @@ -16691,11 +15375,10 @@ cdef class GiacMethods_base: Help for sum_riemann: sum_riemann(Expr(Xpr),Lst(var1,var2)) Returns an equivalent when var1=+infinity of the sum of Xpr(var1,var2) for var2 from 1 to var1 when the sum is a Riemann sum. - See also: 1/ + See also: 1/ Ex1:sum_riemann(1/(n+k),[n,k]) Ex2:sum_riemann(n/(n^2+k),[n,k]) Ex3:sum_riemann(n/(n^2+k^2),[n,k]) - ''' return GiacMethods['sum_riemann'](self,*args) @@ -16704,12 +15387,11 @@ cdef class GiacMethods_base: Help for suppress: suppress(Vect(L)||Str(l),Intg(n)) Returns L without the element of index n; L:=suppress(L,n) or L.suppress(n). - See also: 1/ tail 2/ mid 3/ remove 4/ insert + See also: 1/ tail 2/ mid 3/ remove 4/ insert Ex1:suppress([0,1,2,3],2) Ex2:suppress("0123",2) Ex3: L:=[0,1,2,3];L:=suppress(L,2) Ex4: L:=[0,1,2,3];L.suppress(2) - ''' return GiacMethods['suppress'](self,*args) @@ -16718,10 +15400,9 @@ cdef class GiacMethods_base: Help for surd: surd(Expr,Intg(n)) Power 1/n. - See also: 1/ sqrt 2/ ^ + See also: 1/ sqrt 2/ ^ Ex1:surd(8,3) Ex2:surd(-8,3) - ''' return GiacMethods['surd'](self,*args) @@ -16731,7 +15412,6 @@ cdef class GiacMethods_base: svd(Mtrx(A)) For a square numerical real matrix A, returns U orthogonal, S vector of singular values, Q orthogonal such that A=U*diag(S)*tran(Q). Ex1:svd([[1,2],[3,4]]) - ''' return GiacMethods['svd'](self,*args) @@ -16740,9 +15420,8 @@ cdef class GiacMethods_base: Help for swapcol: swapcol(Mtrx(A),Intg(n1),Intg(n2)) Returns the matrix obtained from A by swapping the n1-th column and the n2-th column. - See also: 1/ rowSwap + See also: 1/ rowSwap Ex1:swapcol([[1,2],[3,4],[5,6]],0,1) - ''' return GiacMethods['swapcol'](self,*args) @@ -16751,9 +15430,8 @@ cdef class GiacMethods_base: Help for swaprow: swaprow(Mtrx(A),Intg(n1),Intg(n2)) Returns the matrix obtained from A by swapping the n1-th row and the n2-th row. - See also: 1/ rowAdd 2/ colSwap + See also: 1/ rowAdd 2/ colSwap Ex1:swaprow([[1,2],[3,4],[5,6]],1,2) - ''' return GiacMethods['swaprow'](self,*args) @@ -16762,11 +15440,10 @@ cdef class GiacMethods_base: Help for switch_axes: switch_axes([Intg(0 or 1)]) switch_axes() puts or erases the axes of the graphic-screen. - See also: 1/ gl_showaxes 2/ axes + See also: 1/ gl_showaxes 2/ axes Ex1:switch_axes() Ex2:switch_axes(0) Ex3:switch_axes(1) - ''' return GiacMethods['switch_axes'](self,*args) @@ -16775,10 +15452,9 @@ cdef class GiacMethods_base: Help for sylvester: sylvester(Poly,Poly,Var) Sylvester matrix of two polynomials. - See also: 1/ resultant + See also: 1/ resultant Ex1:sylvester(x^2-1,x^3-1,x) Ex2:sylvester(x^3-p*x+q,3*x^2-p,x) - ''' return GiacMethods['sylvester'](self,*args) @@ -16787,14 +15463,13 @@ cdef class GiacMethods_base: Help for symb2poly: symb2poly(Expr, LstVar or [Var]) Returns the coefficients of a polynomial with respect to the 2nd argument or if the second argument is a list the internal format of the polynomial. - See also: 1/ poly2symb 2/ r2e + See also: 1/ poly2symb 2/ r2e Ex1:symb2poly(x*3+2.1) Ex2:symb2poly(3*x*y+2*y+1,y) Ex3:symb2poly(3*x*y+2*y+1,x,y) Ex4:symb2poly(3*x*y+2*y+1,[x,y]) Ex5:symb2poly(-x^4+x*3*y+2+y^2*z,[x,y,z]) Ex6:symb2poly(-x^4+x*3*y+2+y^2*z,[x,y,z]) - ''' return GiacMethods['symb2poly'](self,*args) @@ -16803,12 +15478,11 @@ cdef class GiacMethods_base: Help for symbol: symbol(Opt) DOM_SYMBOLIC or symbol is the type of a symbolic variable, as returned by the type command. It is also an option of the assume command. - See also: 1/ type 2/ assume 3/ DOM_INT 4/ DOM_FLOAT + See also: 1/ type 2/ assume 3/ DOM_INT 4/ DOM_FLOAT Ex1: assume(a,symbol) Ex2: assume(a,DOM_SYMBOLIC) Ex3: a:=sqrt(2);type(a) Ex4: type(2x+1) - ''' return GiacMethods['symbol'](self,*args) @@ -16817,9 +15491,8 @@ cdef class GiacMethods_base: Help for syst2mat: syst2mat(LstLinEq,LstVar) Returns the matrix M=A|(-b) associate to the system Y=AX+b. - See also: 1/ linsolve 2/ rref + See also: 1/ linsolve 2/ rref Ex1:syst2mat([x-y=1,x+2*y],[x,y]) - ''' return GiacMethods['syst2mat'](self,*args) @@ -16828,9 +15501,8 @@ cdef class GiacMethods_base: Help for tCollect: tCollect(Expr) Collects trigonometric expressions. - See also: 1/ texpand 2/ tlin + See also: 1/ texpand 2/ tlin Ex1:tCollect(sin(x)+cos(x)) - ''' return GiacMethods['tCollect'](self,*args) @@ -16839,11 +15511,10 @@ cdef class GiacMethods_base: Help for tExpand: tExpand(Expr) Expands transcendental expressions. - See also: 1/ tcollect 2/ tlin 3/ lin 4/ trigexpand + See also: 1/ tcollect 2/ tlin 3/ lin 4/ trigexpand Ex1:tExpand(sin(2*x)+exp(x+y)) Ex2:tExpand(cos(x+y)) Ex3:tExpand(cos(3*x)) - ''' return GiacMethods['tExpand'](self,*args) @@ -16852,11 +15523,10 @@ cdef class GiacMethods_base: Help for table: table(SeqEqual(index=value)) Defines an array where the indices are strings or real numbers or defines a table with a matrix. - See also: 1/ matrix 2/ convert 3/ array + See also: 1/ matrix 2/ convert 3/ array Ex1:table(3=-10,"a"=10,"b"=20,"c"=30,"d"=40) - Ex2: A:=[[0,1],[2,3]];table(A) + Ex2: A:=[[0,1],[2,3]];table(A) Ex3: B:=table([1,2]=12,[2,5]=25);matrix(B) - ''' return GiacMethods['table'](self,*args) @@ -16865,10 +15535,9 @@ cdef class GiacMethods_base: Help for tablefunc: tablefunc(Expr,Var) Table of values of a function : you must be in a spreadsheet. - See also: 1/ tabvar 2/ tableseq + See also: 1/ tabvar 2/ tableseq Ex1:tablefunc(sin(x),x) Ex2:tablefunc(x^2-x-2,x) - ''' return GiacMethods['tablefunc'](self,*args) @@ -16877,10 +15546,9 @@ cdef class GiacMethods_base: Help for tableseq: tableseq(Expr,(Var or LstVar),(InitVal or LstInitVal)) Table of values of a sequence (in a spreadsheet.) - See also: 1/ tablefunc + See also: 1/ tablefunc Ex1:tableseq(cos(x),x,0.0) Ex2:tableseq(x+y,[x,y],[1,1]) - ''' return GiacMethods['tableseq'](self,*args) @@ -16889,11 +15557,10 @@ cdef class GiacMethods_base: Help for tabsign: tabsign(Expr,Var) Table of signs of a function. - See also: 1/ tablefunc 2/ tabvar + See also: 1/ tablefunc 2/ tabvar Ex1:tabsign(x^2-x,x) Ex2:tabsign(x^2,x,-3,5) Ex3:tabsign(sin(x),x) - ''' return GiacMethods['tabsign'](self,*args) @@ -16902,13 +15569,12 @@ cdef class GiacMethods_base: Help for tabvar: tabvar(Expr,Var) Table of variations of a function with its graph on DispG. - See also: 1/ tablefunc 2/ tabsign + See also: 1/ tablefunc 2/ tabsign Ex1:tabvar(sin(x),x) Ex2:tabvar(1/ln(x^2-1),x,diff=1) Ex3:tabvar(x^2+x+1,x) Ex4:tabvar(x^2,x,-3,5) Ex5:tabvar([sin(2t),cos(3t)]) - ''' return GiacMethods['tabvar'](self,*args) @@ -16917,11 +15583,10 @@ cdef class GiacMethods_base: Help for tail: tail(Lst or Seq or Str) Returns the list (or sequence or string) without its first element. - See also: 1/ head 2/ mid 3/ left 4/ right 5/ back + See also: 1/ head 2/ mid 3/ left 4/ right 5/ back Ex1:tail([3,2,4,1,0]) Ex2:tail(3,2,4,1,0) Ex3:tail("bonjour") - ''' return GiacMethods['tail'](self,*args) @@ -16930,11 +15595,10 @@ cdef class GiacMethods_base: Help for tan: tan(Expr) Tangent or option of the convert or convertir command (id halftan). - See also: 1/ atan or Opt 2/ convert 3/ halftan + See also: 1/ atan or Opt 2/ convert 3/ halftan Ex1:tan(0) Ex2:tan(pi/4) Ex3: convert(tan(x),tan) - ''' return GiacMethods['tan'](self,*args) @@ -16943,9 +15607,8 @@ cdef class GiacMethods_base: Help for tan2cossin2: tan2cossin2(Expr) Replaces tan(x) by (1-cos(2*x))/sin(2*x) in the argument. - See also: 1/ tan2sincos2 2/ tan2sincos 3/ sin2costan 4/ cos2sintan + See also: 1/ tan2sincos2 2/ tan2sincos 3/ sin2costan 4/ cos2sintan Ex1:tan2cossin2(tan(x)) - ''' return GiacMethods['tan2cossin2'](self,*args) @@ -16954,9 +15617,8 @@ cdef class GiacMethods_base: Help for tan2sincos: tan2sincos(Expr) Replaces tan(x) by sin(x)/cos(x) in the argument. - See also: 1/ sin2costan 2/ cos2sintan 3/ tan2sincos2 4/ tan2cossin2 + See also: 1/ sin2costan 2/ cos2sintan 3/ tan2sincos2 4/ tan2cossin2 Ex1:tan2sincos(tan(x)) - ''' return GiacMethods['tan2sincos'](self,*args) @@ -16965,9 +15627,8 @@ cdef class GiacMethods_base: Help for tan2sincos2: tan2sincos2(Expr) Replaces tan(x) by sin(2*x)/(1+cos(2*x)) in the argument. - See also: 1/ tan2cossin2 2/ tan2sincos 3/ sin2costan 4/ cos2sintan + See also: 1/ tan2cossin2 2/ tan2sincos 3/ sin2costan 4/ cos2sintan Ex1:tan2sincos2(tan(x)) - ''' return GiacMethods['tan2sincos2'](self,*args) @@ -16976,7 +15637,7 @@ cdef class GiacMethods_base: Help for tangent: tangent(Curve(C),Pnt(A)) tangent(C,A) draws the tangents (line or plane) to C through A. - See also: 1/ LineTan 2/ droite_tangente + See also: 1/ LineTan 2/ droite_tangente Ex1:tangent(circle(i,1+i),A) Ex2:tangent(plotfunc(sin(x)),3*pi/4) Ex3:tangent(plotfunc(sin(x)),point(3*pi/4+i*sqrt(2)/2)) @@ -16985,7 +15646,6 @@ cdef class GiacMethods_base: Ex6:tangent(plotparam(3*exp(t/2)*exp(i*t),t),7) Ex7:tangent(plotpolar(3*exp(t/2),t),7) Ex8: equation(tangente([2*cos(t),2*sin(t),3*t],t)) - ''' return GiacMethods['tangent'](self,*args) @@ -16994,7 +15654,7 @@ cdef class GiacMethods_base: Help for tangente: tangente(Curve(C),Pnt(A)) tangent(C,A) draws the tangents (line or plane) to C through A. - See also: 1/ LineTan 2/ droite_tangente + See also: 1/ LineTan 2/ droite_tangente Ex1:tangente(circle(i,1+i),A) Ex2:tangente(plotfunc(sin(x)),3*pi/4) Ex3:tangente(plotfunc(sin(x)),point(3*pi/4+i*sqrt(2)/2)) @@ -17003,7 +15663,6 @@ cdef class GiacMethods_base: Ex6:tangente(plotparam(3*exp(t/2)*exp(i*t),t),7) Ex7:tangente(plotpolar(3*exp(t/2),t),7) Ex8: equation(tangente([2*cos(t),2*sin(t),3*t],t)) - ''' return GiacMethods['tangente'](self,*args) @@ -17012,10 +15671,9 @@ cdef class GiacMethods_base: Help for tanh: tanh(Expr) Hyperbolic tangent. - See also: 1/ atanh 2/ hyp2exp + See also: 1/ atanh 2/ hyp2exp Ex1:tanh(0) Ex2:tanh(hyp2exp(tanh(1))) - ''' return GiacMethods['tanh'](self,*args) @@ -17024,11 +15682,10 @@ cdef class GiacMethods_base: Help for taux_accroissement: taux_accroissement(Expr,Var,Val1,(Val1+Var or Val2)) Returns the rate of change of an expression when the variable goes from Val1 to Val2 (by default Var=x). - See also: 1/ diff 2/ limit + See also: 1/ diff 2/ limit Ex1:taux_accroissement(x^2,1,1+h) Ex2:taux_accroissement(x^2,1,2) Ex3:taux_accroissement(a^2,a,1,1+h) - ''' return GiacMethods['taux_accroissement'](self,*args) @@ -17037,7 +15694,7 @@ cdef class GiacMethods_base: Help for taylor: taylor(Expr,[Var=limit_point],[Order]) Series expansion at finite or infinite points (by default x=0, and relative order=5). - See also: 1/ series 2/ limit 3/ pade 4/ polynom + See also: 1/ series 2/ limit 3/ pade 4/ polynom Ex1:taylor(sin(x)/x,x,0) Ex2:taylor(sin(x),x=0,5,polynom) Ex3:taylor(ln(y+y^2)-ln(y),y) @@ -17045,10 +15702,9 @@ cdef class GiacMethods_base: Ex5:taylor(ln(x+x^2)-ln(x),x=0,2) Ex6:taylor(ln(x+x^2)-ln(x),x=1,2) Ex7:taylor((x^4+x+2)/(x^2+1),x,5) - Ex8:taylor(sin(t*x+t*y)+cos(t*x*t*y),t=0,6,polynom)(h=1) + Ex8:taylor(sin(t*x+t*y)+cos(t*x*t*y),t=0,6,polynom)(h=1) Ex9:taylor(sin((1+h*t)*(pi/2+k*t)),t=0,3,polynom)(t=1) Ex10:taylor((-1+k*t)^2/(1+h*t)^3,t=0,3,polynom)(t=1) - ''' return GiacMethods['taylor'](self,*args) @@ -17057,9 +15713,8 @@ cdef class GiacMethods_base: Help for tchebyshev1: tchebyshev1(Intg(n)) Returns the n-th Tchebyshev polynomial of first kind. - See also: 1/ tchebyshev2 2/ hermite + See also: 1/ tchebyshev2 2/ hermite Ex1:tchebyshev1(3) - ''' return GiacMethods['tchebyshev1'](self,*args) @@ -17068,9 +15723,8 @@ cdef class GiacMethods_base: Help for tchebyshev2: tchebyshev2(Intg(n)) Returns the nt-h Tchebyshev polynomial of second kind. - See also: 1/ tchebyshev1 2/ hermite + See also: 1/ tchebyshev1 2/ hermite Ex1:tchebyshev2(3) - ''' return GiacMethods['tchebyshev2'](self,*args) @@ -17079,10 +15733,9 @@ cdef class GiacMethods_base: Help for tcoeff: tcoeff(Poly||Lst) Returns the coefficient of the term of lowest degree of a polynomial (t=trailing). - See also: 1/ lcoeff + See also: 1/ lcoeff Ex1:tcoeff(-2*x^3+x^2+7*x) Ex2:tcoeff([-2,1,7,0]) - ''' return GiacMethods['tcoeff'](self,*args) @@ -17091,9 +15744,8 @@ cdef class GiacMethods_base: Help for tcollect: tcollect(Expr) Collects trigonometric expressions. - See also: 1/ texpand 2/ tlin + See also: 1/ texpand 2/ tlin Ex1:tcollect(sin(x)+cos(x)) - ''' return GiacMethods['tcollect'](self,*args) @@ -17102,8 +15754,7 @@ cdef class GiacMethods_base: Help for tdeg: tdeg(Opt) Option of the gbasis or greduce command to specify an order for monomials (complete degree then lexicographic order). - See also: 1/ gbasis 2/ greduce - + See also: 1/ gbasis 2/ greduce ''' return GiacMethods['tdeg'](self,*args) @@ -17112,9 +15763,8 @@ cdef class GiacMethods_base: Help for tensor_product: tensor_product(Seq(G1,G2,..)) Returns the tensor product of the input graphs G1, G2, ... with vertices labelled as "u:v:..." where u, v, ... are vertices from G1, G2, ..., respectively. - See also: 1/ cartesian_product + See also: 1/ cartesian_product Ex1:tensor_product(graph(trail(1,2,3,4,5,2)),star_graph(3)) - ''' return GiacMethods['tensor_product'](self,*args) @@ -17123,10 +15773,9 @@ cdef class GiacMethods_base: Help for tetrahedron: tetrahedron(Pnt(A),Pnt(B),Pnt(C),[Pnt(D)]) Draws the regular direct pyramid ABCD with vertices A,B and a face in the plane (A,B,C) when there is 3 arguments and the pyramid ABCD when there are 4 arguments. - See also: 1/ cube 2/ cylinder 3/ icosahedron 4/ dodecahedron 5/ octahedron + See also: 1/ cube 2/ cylinder 3/ icosahedron 4/ dodecahedron 5/ octahedron Ex1:tetrahedron([0,0,0],[3,0,0],[0,1,0]) Ex2:tetrahedron([0,0,0],[3,0,0],[0,3,0],[0,0,4]) - ''' return GiacMethods['tetrahedron'](self,*args) @@ -17135,11 +15784,10 @@ cdef class GiacMethods_base: Help for texpand: texpand(Expr) Expands transcendental expressions. - See also: 1/ tcollect 2/ tlin 3/ lin 4/ trigexpand + See also: 1/ tcollect 2/ tlin 3/ lin 4/ trigexpand Ex1:texpand(sin(2*x)+exp(x+y)) Ex2:texpand(cos(x+y)) Ex3:texpand(cos(3*x)) - ''' return GiacMethods['texpand'](self,*args) @@ -17148,10 +15796,9 @@ cdef class GiacMethods_base: Help for thickness: thickness(Opt) Option (Maple compatibility) of a graphic command to define the thickness of lines. - See also: 1/ line_width + See also: 1/ line_width Ex1: segment(0,point(1,1),thickness=5) Ex2: segment(0,point(1,1),epaisseur=5) - ''' return GiacMethods['thickness'](self,*args) @@ -17160,10 +15807,9 @@ cdef class GiacMethods_base: Help for threshold: threshold(Lst,Real(bound)[=Expr(repl)] or Lst[Real(lower)[=Expr(rl)],Real(upper)[=Expr(ru)]],[Fnc(compare)],[abs[=true or false]]) Performs thresholding operations on a list of real or complex numbers. - See also: 1/ max 2/ min + See also: 1/ max 2/ min Ex1:threshold([1,3,2,4,5,4,3,2,3,1],3,'>=') Ex2:threshold([-10,-5,0,5,10],7=a,abs=true) - ''' return GiacMethods['threshold'](self,*args) @@ -17172,10 +15818,9 @@ cdef class GiacMethods_base: Help for throw: throw(Str) Generates the display of an error in a program. - See also: 1/ try 2/ catch + See also: 1/ try 2/ catch Ex1:throw("Argument should be integer") Ex2:throw("je provoque une erreur") - ''' return GiacMethods['throw'](self,*args) @@ -17184,10 +15829,9 @@ cdef class GiacMethods_base: Help for title: title(Opt) Global option of a graphic command to put a title in a graphic. - See also: 1/ line_width + See also: 1/ line_width Ex1: title="segment";segment(0,point(1,1),epaisseur=5) Ex2: titre="segment";segment(0,point(1,1),epaisseur=5) - ''' return GiacMethods['title'](self,*args) @@ -17196,10 +15840,9 @@ cdef class GiacMethods_base: Help for titre: titre(Opt) Global option of a graphic command to put a title in a graphic. - See also: 1/ line_width + See also: 1/ line_width Ex1: title="segment";segment(0,point(1,1),epaisseur=5) Ex2: titre="segment";segment(0,point(1,1),epaisseur=5) - ''' return GiacMethods['titre'](self,*args) @@ -17208,10 +15851,9 @@ cdef class GiacMethods_base: Help for tlin: tlin(ExprTrig) Trigonometric linearization. - See also: 1/ texpand 2/ lin + See also: 1/ texpand 2/ lin Ex1:tlin(sin(x)^3) Ex2:tlin(cos(x)*cos(y)) - ''' return GiacMethods['tlin'](self,*args) @@ -17220,10 +15862,9 @@ cdef class GiacMethods_base: Help for tonnetz: tonnetz(Intg(a),Intg(b),Intg(c),[Intg(d)]) Returns the graph corresponding to the [a,b,c] resp. [a,b,c,d] tone network (tonnetz) used in neo-Riemannian music theory. - See also: 1/ is_regular 2/ clique_stats + See also: 1/ is_regular 2/ clique_stats Ex1:tonnetz(3,4,5) Ex2:tonnetz(2,3,3,4) - ''' return GiacMethods['tonnetz'](self,*args) @@ -17232,9 +15873,8 @@ cdef class GiacMethods_base: Help for topologic_sort: topologic_sort(Graph(G)) Returns the list of vertices sorted according to the topological ordering in the directed acyclic graph G. - See also: 1/ digraph 2/ is_acyclic + See also: 1/ digraph 2/ is_acyclic Ex1:topologic_sort(digraph(%{[c,a],[c,b],[c,d],[a,d],[b,d],[a,b]%})) - ''' return GiacMethods['topologic_sort'](self,*args) @@ -17243,9 +15883,8 @@ cdef class GiacMethods_base: Help for topological_sort: topological_sort(Graph(G)) Returns the list of vertices sorted according to the topological ordering in the directed acyclic graph G. - See also: 1/ digraph 2/ is_acyclic + See also: 1/ digraph 2/ is_acyclic Ex1:topological_sort(digraph(%{[c,a],[c,b],[c,d],[a,d],[b,d],[a,b]%})) - ''' return GiacMethods['topological_sort'](self,*args) @@ -17254,9 +15893,8 @@ cdef class GiacMethods_base: Help for torus_grid_graph: torus_grid_graph(Intg(m),Intg(n)) Returns a torus grid graph on m*n vertices, where m,n>=3. - See also: 1/ grid_graph + See also: 1/ grid_graph Ex1:torus_grid_graph(6,12) - ''' return GiacMethods['torus_grid_graph'](self,*args) @@ -17265,9 +15903,8 @@ cdef class GiacMethods_base: Help for total_degree: total_degree(Poly(P),Lst(Vars)) Total degree of the polynomial P with respect to the second argument. - See also: 1/ valuation 2/ size 3/ degree + See also: 1/ valuation 2/ size 3/ degree Ex1:total_degree(x^3*y+x*y,[x,y]) - ''' return GiacMethods['total_degree'](self,*args) @@ -17276,10 +15913,9 @@ cdef class GiacMethods_base: Help for tourne_droite: tourne_droite(NULL or Real(n)) The turtle turns right by n degrees (by default n=90). - See also: 1/ tourne_gauche 2/ pas_de_cote + See also: 1/ tourne_gauche 2/ pas_de_cote Ex1: tourne_droite 60 Ex2:tourne_droite(60) - ''' return GiacMethods['tourne_droite'](self,*args) @@ -17288,10 +15924,9 @@ cdef class GiacMethods_base: Help for tourne_gauche: tourne_gauche(NULL or Real(n)) The turtle turns left by n degrees (by defaults n=90). - See also: 1/ tourne_droite + See also: 1/ tourne_droite Ex1: tourne_gauche 60 Ex2:tourne_gauche(60) - ''' return GiacMethods['tourne_gauche'](self,*args) @@ -17304,7 +15939,6 @@ cdef class GiacMethods_base: Ex2:tpsolve([7,10,8,8,9,6],[9,6,12,8,10],[[36,40,32,43,29],[28,27,29,40,38],[34,35,41,29,31],[41,42,35,27,36],[25,28,40,34,38],[31,30,43,38,40]]) Ex3:tpsolve([95,70,165,165],[195,150,30,45,75],[[15,M,45,M,0],[12,40,M,M,0],[0,15,25,25,0],[M,0,M,12,0]]) Ex4:tpsolve([1,1,1,1],[1,1,1,1],[[10,12,9,11],[5,10,7,8],[12,14,13,11],[8,15,11,9]]) - ''' return GiacMethods['tpsolve'](self,*args) @@ -17313,12 +15947,11 @@ cdef class GiacMethods_base: Help for trace: trace(Mtrx or GeoObj) Returns the trace of a square matrix or draws the trace of a geometric object when the parameter changes (see Trace in Menu button of a geometric level and write only one instruction on each line). - See also: 1/ det 2/ lieu + See also: 1/ det 2/ lieu Ex1:trace([[1,2,3],[1,3,6],[2,5,7]]) Ex2:trace([[1+i,2,3],[1,3,6],[2,5,9-i]]) Ex3: assume(a=[0.7,-5,5,0.1]);trace(point(a-i*a)) Ex4: assume(a=[0.7,-5,5,0.1]);trace(inter_unique(droite(y=a*x+a),droite(y=2*a*x+1))) - ''' return GiacMethods['trace'](self,*args) @@ -17327,9 +15960,8 @@ cdef class GiacMethods_base: Help for trail: trail(Seq(V)) Returns a trail of vertices from V (inert command). - See also: 1/ graph 2/ digraph + See also: 1/ graph 2/ digraph Ex1:trail(1,2,3,4,1) - ''' return GiacMethods['trail'](self,*args) @@ -17338,10 +15970,9 @@ cdef class GiacMethods_base: Help for trail2edges: trail2edges(Trail(T)) Converts a trail T to the list of its edges. - See also: 1/ subgraph 2/ trail + See also: 1/ subgraph 2/ trail Ex1:trail2edges(trail(1,2,3,4,1,3)) Ex2:trail2edges([1,2,3,4,1,3]) - ''' return GiacMethods['trail2edges'](self,*args) @@ -17350,10 +15981,9 @@ cdef class GiacMethods_base: Help for trames: trames(Opt) Option of animate and animate3d commands to give the number of pictures. - See also: 1/ animate 2/ animate3d + See also: 1/ animate 2/ animate3d Ex1: animate(sin(x*t),x=-pi..pi,t=-3..3,frames=30) Ex2: animate3d(x^2+t*y^2,[x=-2..2,y=-2..2],t=-3..3,frames=10) - ''' return GiacMethods['trames'](self,*args) @@ -17362,11 +15992,10 @@ cdef class GiacMethods_base: Help for tran: tran(Mtrx) Transposes a matrix (without conjugation). - See also: 1/ conj 2/ trn + See also: 1/ conj 2/ trn Ex1:tran([[1,2,3],[1,3,6],[2,5,7]]) Ex2:tran([[1+i,2,3],[1,3,6],[2,5,9-i]]) Ex3:tran(conj([[1+i,2,3],[1,3,6],[2,5,9-i]])) - ''' return GiacMethods['tran'](self,*args) @@ -17375,9 +16004,8 @@ cdef class GiacMethods_base: Help for transitive_closure: transitive_closure(Graph(G),[weighted[=true||false]]) Returns the [weighted, by default false] transitive closure of G. - See also: 1/ allpairs_distance 2/ is_connected 3/ shortest_path 4/ vertex_distance + See also: 1/ allpairs_distance 2/ is_connected 3/ shortest_path 4/ vertex_distance Ex1:transitive_closure(digraph([1,2,3,4,5,6],%{[1,2],[2,3],[2,4],[4,5],[3,5]%}),weighted) - ''' return GiacMethods['transitive_closure'](self,*args) @@ -17386,12 +16014,11 @@ cdef class GiacMethods_base: Help for translation: translation(Vect, Pnt(C)) translation(B-A,C) (resp translation([a,b,c],C)) is the translation of C in the translation of vector AB (resp [a,b,c]). - See also: 1/ rotation 2/ reflection + See also: 1/ rotation 2/ reflection Ex1:translation(1+i,i) Ex2:translation([1,1,1],point([1,2,3])) Ex3: t:=translation(1+i);t(i) Ex4: t:=translation([1,1,1]);t(point([1,2,3])) - ''' return GiacMethods['translation'](self,*args) @@ -17400,11 +16027,10 @@ cdef class GiacMethods_base: Help for transpose: transpose(Mtrx) Transposes a matrix (without conjugation). - See also: 1/ conj 2/ trn + See also: 1/ conj 2/ trn Ex1:transpose([[1,2,3],[1,3,6],[2,5,7]]) Ex2:transpose([[1+i,2,3],[1,3,6],[2,5,9-i]]) Ex3:transpose(conj([[1+i,2,3],[1,3,6],[2,5,9-i]])) - ''' return GiacMethods['transpose'](self,*args) @@ -17413,14 +16039,13 @@ cdef class GiacMethods_base: Help for trapeze: trapeze(Opt) Option of the plotarea command and of the area command. - See also: 1/ plotarea 2/ area + See also: 1/ plotarea 2/ area Ex1: plotarea(x^2,x=0..1,5,trapezoid) Ex2: plotarea(x^2,x=0..1,5,middle_point) Ex3: plotarea(x^2,x=0..1,5,right_rectangle) Ex4: plotarea(x^2,x=0..1,5,left_rectangle) Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) - ''' return GiacMethods['trapeze'](self,*args) @@ -17429,14 +16054,13 @@ cdef class GiacMethods_base: Help for trapezoid: trapezoid(Opt) Option of the plotarea command and of the area command. - See also: 1/ plotarea 2/ area + See also: 1/ plotarea 2/ area Ex1: plotarea(x^2,x=0..1,5,trapezoid) Ex2: plotarea(x^2,x=0..1,5,middle_point) Ex3: plotarea(x^2,x=0..1,5,right_rectangle) Ex4: plotarea(x^2,x=0..1,5,left_rectangle) Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) - ''' return GiacMethods['trapezoid'](self,*args) @@ -17445,13 +16069,12 @@ cdef class GiacMethods_base: Help for traveling_salesman: traveling_salesman(Graph(G),[Mtrx(M)],[opts]) Returns a Hamiltonian cycle in an unweighted graph G or solves traveling salesman problem if G is weighted (matrix M can be used for edge weights), returning a sequence containing the minimal cost and the corresponding Hamiltonian cycle. - See also: 1/ is_hamiltonian + See also: 1/ is_hamiltonian Ex1:traveling_salesman(hypercube_graph(5)) Ex2:traveling_salesman(digraph(%{[[1,2],1],[[1,3],2],[[2,3],2],[[2,4],3],[[3,2],3],[[3,4],2],[[4,1],1]%})) Ex3: M:=randmatrix(4,4,99); traveling_salesman(graph("tetrahedron"),M) Ex4: G:=set_vertex_positions(complete_graph(42),[randvector(2,1000)$(k=1..42)]); traveling_salesman(G,vertex_distance) Ex5: G:=set_vertex_positions(complete_graph(120),[randvector(2,1000)$(k=1..120)]); c,T:=traveling_salesman(G,vertex_distance,approx) - ''' return GiacMethods['traveling_salesman'](self,*args) @@ -17460,8 +16083,7 @@ cdef class GiacMethods_base: Help for tree: tree(Opt) Option for the draw_graph command. - See also: 1/ planar 2/ spring 3/ draw_graph - + See also: 1/ planar 2/ spring 3/ draw_graph ''' return GiacMethods['tree'](self,*args) @@ -17470,9 +16092,8 @@ cdef class GiacMethods_base: Help for tree_height: tree_height(Graph(T),Vrtx(r)) Returns the height of the tree graph T with r as the root node. - See also: 1/ is_tree 2/ random_tree + See also: 1/ is_tree 2/ random_tree Ex1:tree_height(graph(%{[1,2],[2,3],[2,4],[4,5]%}),1) - ''' return GiacMethods['tree_height'](self,*args) @@ -17481,9 +16102,8 @@ cdef class GiacMethods_base: Help for tri: tri(Expr(x)) Returns the value of the triangle function at x. - See also: 1/ rect 2/ Heaviside + See also: 1/ rect 2/ Heaviside Ex1:tri(x-1) - ''' return GiacMethods['tri'](self,*args) @@ -17492,11 +16112,10 @@ cdef class GiacMethods_base: Help for triangle: triangle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) triangle(A,B,C) draws the triangle ABC. - See also: 1/ equilateral_triangle 2/ isosceles_triangle 3/ right_triangle + See also: 1/ equilateral_triangle 2/ isosceles_triangle 3/ right_triangle Ex1:triangle(point(1+i),1,0) Ex2:triangle(0,1,1+i) Ex3:triangle(point(0,0,0),point(3,3,3),point(0,3,3)) - ''' return GiacMethods['triangle'](self,*args) @@ -17509,7 +16128,6 @@ cdef class GiacMethods_base: Ex2:triangle_paper(1,pi/3,sqrt(3)/2,x=-1..4,y=-2..2) Ex3:triangle_paper(papier_triangule(1,pi/3,sqrt(3)/2,x=-2..6,y=-4*sqrt(3)..4*sqrt(3))) Ex4:triangle_paper(0.5,3*pi/4,0.5) - ''' return GiacMethods['triangle_paper'](self,*args) @@ -17518,12 +16136,11 @@ cdef class GiacMethods_base: Help for triangle_plein: triangle_plein(Real(a),[Real(b)],[Real(t)]) Draws a full direct triangle with sides a,b and with angle t, from the turtle position (by default t=90 or (b=a and t=60)). - See also: 1/ rectangle_plein + See also: 1/ rectangle_plein Ex1: triangle_plein 30 Ex2:triangle_plein(30) Ex3:triangle_plein(30,40) Ex4:triangle_plein(30,40,60) - ''' return GiacMethods['triangle_plein'](self,*args) @@ -17532,10 +16149,9 @@ cdef class GiacMethods_base: Help for triangle_point: triangle_point(Opt) Option of the display command for a point. - See also: 1/ display + See also: 1/ display Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) - ''' return GiacMethods['triangle_point'](self,*args) @@ -17544,9 +16160,8 @@ cdef class GiacMethods_base: Help for triangle_window: triangle_window(Lst,[Intg(d)],[Interval(n1..n2)]) Applies the triangular windowing function with parameter d in {-1,0,1} (by default L=0) to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ bartlett_hann_window 13/ tukey_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ bartlett_hann_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(triangle_window(randvector(1000,0..1),1)) - ''' return GiacMethods['triangle_window'](self,*args) @@ -17555,9 +16170,8 @@ cdef class GiacMethods_base: Help for trig2exp: trig2exp(Expr) Replaces in the argument the trigonometric functions by complex exponentials without linearisation. - See also: 1/ exp2trig 2/ atrig2ln + See also: 1/ exp2trig 2/ atrig2ln Ex1:trig2exp(sin(x)) - ''' return GiacMethods['trig2exp'](self,*args) @@ -17566,9 +16180,8 @@ cdef class GiacMethods_base: Help for trigcos: trigcos(Expr) Simplifies the argument with the formulas sin(x)^2+cos(x)^2=1 and tan(x)=sin(x)/cos(x) privileging cosine. - See also: 1/ trigsin 2/ trigtan + See also: 1/ trigsin 2/ trigtan Ex1:trigcos(sin(x)^4+sin(x)^2) - ''' return GiacMethods['trigcos'](self,*args) @@ -17577,9 +16190,8 @@ cdef class GiacMethods_base: Help for trigexpand: trigexpand(Expr) Expands trigonometric functions. - See also: 1/ texpand 2/ lnexpand 3/ expexpand + See also: 1/ texpand 2/ lnexpand 3/ expexpand Ex1:trigexpand(sin(3*x)) - ''' return GiacMethods['trigexpand'](self,*args) @@ -17588,10 +16200,9 @@ cdef class GiacMethods_base: Help for triginterp: triginterp(List,Var=xmin..xmax) Returns a trigonometric polynomial interpolation (with respect to variable x) of the points with ordinate given in list y and the abscissa equally spaced between a and b. - See also: 1/ lagrange 2/ thiele + See also: 1/ lagrange 2/ thiele Ex1:triginterp([11,10,17,24,32,26,23,19],x=0..21) Ex2:triginterp([11,10,17,24,32,26,23,19],0,21,x) - ''' return GiacMethods['triginterp'](self,*args) @@ -17600,9 +16211,8 @@ cdef class GiacMethods_base: Help for trigsimplify: trigsimplify(Expr) Simplifies a trigonometric expression. - See also: 1/ simplify + See also: 1/ simplify Ex1:trigsimplify(3*sin(x)-4*sin(x)^3) - ''' return GiacMethods['trigsimplify'](self,*args) @@ -17611,9 +16221,8 @@ cdef class GiacMethods_base: Help for trigsin: trigsin(Expr) Simplifies the argument with the formulas sin(x)^2+cos(x)^2=1 and tan(x)=sin(x)/cos(x) privileging sine. - See also: 1/ trigcos 2/ trigtan + See also: 1/ trigcos 2/ trigtan Ex1:trigsin(cos(x)^4+sin(x)^2) - ''' return GiacMethods['trigsin'](self,*args) @@ -17622,9 +16231,8 @@ cdef class GiacMethods_base: Help for trigtan: trigtan(Expr) Simplifies the argument with the formulas sin(x)^2+cos(x)^2=1 and tan(x)=sin(x)/cos(x) privileging tangent. - See also: 1/ trigsin 2/ trigcos + See also: 1/ trigsin 2/ trigcos Ex1:trigtan(cos(x)^4+sin(x)^2) - ''' return GiacMethods['trigtan'](self,*args) @@ -17633,9 +16241,8 @@ cdef class GiacMethods_base: Help for trn: trn(Mtrx) Returns the adjoint matrix of A =tran(conj(A)). - See also: 1/ tran 2/ conj + See also: 1/ tran 2/ conj Ex1:trn([[1,2+i],[3,4]]) - ''' return GiacMethods['trn'](self,*args) @@ -17644,9 +16251,8 @@ cdef class GiacMethods_base: Help for true: true() Boolean equal to true or 1. - See also: 1/ false + See also: 1/ false Ex1: a:=true - ''' return GiacMethods['true'](self,*args) @@ -17655,13 +16261,12 @@ cdef class GiacMethods_base: Help for trunc: trunc(Real||LstReal,Int(n)) Truncates value to n decimal places (by default n=0). Accepts complex numbers.(type=DOM_COMPLEX or DOM_FLOAT). - See also: 1/ fPart 2/ floor 3/ iPart + See also: 1/ fPart 2/ floor 3/ iPart Ex1:trunc(4.3) Ex2:trunc(sqrt(2),3) Ex3:trunc([4.3333,sqrt(2)]) Ex4:trunc([4.3333,sqrt(2)],2) Ex5:trunc(sqrt(2)+i*sqrt(5),4) - ''' return GiacMethods['trunc'](self,*args) @@ -17670,9 +16275,8 @@ cdef class GiacMethods_base: Help for truncate: truncate(Poly(P),Intg(n)) Truncates the polynomial P at order n. - See also: 1/ series + See also: 1/ series Ex1:truncate((x^2+x)^2,3) - ''' return GiacMethods['truncate'](self,*args) @@ -17681,9 +16285,8 @@ cdef class GiacMethods_base: Help for truncate_graph: truncate_graph(Graph(G)) Returns the graph obtained by truncating the biconnected planar graph G. - See also: 1/ is_biconnected 2/ is_planar 3/ plane_dual + See also: 1/ is_biconnected 2/ is_planar 3/ plane_dual Ex1:truncate_graph(graph("tetrahedron")) - ''' return GiacMethods['truncate_graph'](self,*args) @@ -17692,9 +16295,8 @@ cdef class GiacMethods_base: Help for tsimplify: tsimplify(Expr) Lowers the number of non rational variables. - See also: 1/ simplify + See also: 1/ simplify Ex1:tsimplify(exp(2*x)+exp(x)) - ''' return GiacMethods['tsimplify'](self,*args) @@ -17703,9 +16305,8 @@ cdef class GiacMethods_base: Help for tuer: tuer(NULL) Stop step-by-step execution of a program (with debug). - See also: 1/ + See also: 1/ Ex1:tuer() - ''' return GiacMethods['tuer'](self,*args) @@ -17714,9 +16315,8 @@ cdef class GiacMethods_base: Help for tukey_window: tukey_window(Lst,[Real(a)],[Interval(n1..n2)]) Applies the Tukey windowing function with parameter a in [0,1] (by default a=0.5) to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ bartlett_hann_window 14/ welch_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ bartlett_hann_window 14/ welch_window Ex1: scatterplot(tukey_window(randvector(1000,0..1),0.4)) - ''' return GiacMethods['tukey_window'](self,*args) @@ -17725,10 +16325,9 @@ cdef class GiacMethods_base: Help for tutte_polynomial: tutte_polynomial(Graph(G),[Var(x),Var(y)]) Returns the Tutte polynomial [or its value at point (x,y)] of undirected graph G. If G is weighted, all weights must be positive integers and are interpreted as edge multiplicities. - See also: 1/ chromatic_polynomial 2/ flow_polynomial 3/ reliability_polynomial 4/ delete_edge 5/ contract_edge + See also: 1/ chromatic_polynomial 2/ flow_polynomial 3/ reliability_polynomial 4/ delete_edge 5/ contract_edge Ex1:tutte_polynomial(graph("tetrahedron")) Ex2:tutte_polynomial(graph("tetrahedron"),1,1) - ''' return GiacMethods['tutte_polynomial'](self,*args) @@ -17737,9 +16336,8 @@ cdef class GiacMethods_base: Help for two_edge_connected_components: two_edge_connected_components(Graph(G)) Returns the list of two-edge-connected components of undirected graph G, each of them represented by the list of its vertices. - See also: 1/ is_two_edge_connected 2/ connected_components + See also: 1/ is_two_edge_connected 2/ connected_components Ex1:two_edge_connected_components(graph(trail(1,2,3,4,5,3,1),trail(5,6,7,8,6))) - ''' return GiacMethods['two_edge_connected_components'](self,*args) @@ -17748,9 +16346,8 @@ cdef class GiacMethods_base: Help for ufactor: ufactor(Unit,Unit) Factors a unit in a unit object. - See also: 1/ convert 2/ mksa 3/ usimplify + See also: 1/ convert 2/ mksa 3/ usimplify Ex1:ufactor(100_C,1_A) - ''' return GiacMethods['ufactor'](self,*args) @@ -17759,10 +16356,9 @@ cdef class GiacMethods_base: Help for ugamma: ugamma(Real(a),Real(x),[1]) Calculates ugamma function at a point (a,x):if a and x>=0 ugamma(a,x)=int(e^{-t}*t^{a-1},t=x..inf),(ugamma(a,x)+igamma(a,x)=Gamma(a)). - See also: 1/ Psi 2/ Beta 3/ Gamma 4/ igamma + See also: 1/ Psi 2/ Beta 3/ Gamma 4/ igamma Ex1:ugamma(5.0,2.0) Ex2:ugamma(-5.1,2.1) - ''' return GiacMethods['ugamma'](self,*args) @@ -17771,10 +16367,9 @@ cdef class GiacMethods_base: Help for unapply: unapply(Expr,Var) Returns a function defined by an expression. - See also: 1/ apply + See also: 1/ apply Ex1:unapply(2*x^2,x) Ex2: f(x):=x*exp(x);g:=unapply(diff(f(x),x),x) - ''' return GiacMethods['unapply'](self,*args) @@ -17783,10 +16378,9 @@ cdef class GiacMethods_base: Help for unarchive: unarchive(Str(namefich),Seq(Var)) Reads the value of a variable or of a list of variables which are in the file given as argument (file created with archive). - See also: 1/ archive 2/ Archive 3/ Unarchiv + See also: 1/ archive 2/ Archive 3/ Unarchiv Ex1:unarchive("toto") Ex2:unarchive("aa.txt") - ''' return GiacMethods['unarchive'](self,*args) @@ -17795,9 +16389,8 @@ cdef class GiacMethods_base: Help for underlying_graph: underlying_graph(Graph(G)) Returns the graph obtained by stripping directions and weights from arcs (pairs of arcs connecting the same vertices are merged to a single edge). - See also: 1/ is_directed 2/ is_weighted 3/ make_directed 4/ make_weighted + See also: 1/ is_directed 2/ is_weighted 3/ make_directed 4/ make_weighted Ex1:underlying_graph(digraph(trail(1,2,3,4,1))) - ''' return GiacMethods['underlying_graph'](self,*args) @@ -17806,13 +16399,12 @@ cdef class GiacMethods_base: Help for unfactored: unfactored(Opt.) Option of the plotimplicit command. - See also: 1/ plotimplicit + See also: 1/ plotimplicit Ex1: plotimplicit(x^2+y^2-1,x,y,unfactored) Ex2: plotimplicit(x^2+y^2-1,[x,y],unfactored) Ex3: plotimplicit(x^2+y^2+z^2-1,x,y,z,xstep=0.2,ystep=0.2,zstep=0.2,unfactored) Ex4: plotimplicit(x^2+y^2+z^2-1,[x,y,z],xstep=0.2,ystep=0.2,zstep=0.2,unfactored) Ex5: plotimplicit(x^2+y^2+z^2-1,x=0..1,y=0..1,z=0..1,xstep=0.2,ystep=0.2,zstep=0.2,unfactored) - ''' return GiacMethods['unfactored'](self,*args) @@ -17821,12 +16413,11 @@ cdef class GiacMethods_base: Help for uniform: uniform(Real(a),Real(b),Real(x)) Returns the probability density at x of the uniform law on [a,b]. - See also: 1/ uniform_cdf 2/ uniform_icdf 3/ randvector 4/ ranm + See also: 1/ uniform_cdf 2/ uniform_icdf 3/ randvector 4/ ranm Ex1:uniform(2,5,4) Ex2:uniform(1.2,3.5,3) Ex3: randvector(3,uniform,1.2,3.5) Ex4: ranm(4,3,uniform,1.2,3.5) - ''' return GiacMethods['uniform'](self,*args) @@ -17835,10 +16426,9 @@ cdef class GiacMethods_base: Help for uniform_cdf: uniform_cdf(Real(a),Real(b),Real(x0),[Real(y0)]) Returns the probability that a uniform random variable on [a,b] is less than x0 (or between x0 and y0). - See also: 1/ uniformd 2/ uniform_icdf + See also: 1/ uniformd 2/ uniform_icdf Ex1:uniform_cdf(3.2,5.7,4.4) Ex2:uniform_cdf(3.2,5.7,4.4,5.4) - ''' return GiacMethods['uniform_cdf'](self,*args) @@ -17847,10 +16437,9 @@ cdef class GiacMethods_base: Help for uniform_icdf: uniform_icdf(Real(a),Real(b),Real(p)) Returns h such that the probability that a uniform random variable on [a,b] is less than h is p (0<=p<=1). - See also: 1/ uniform_cdf 2/ uniformd + See also: 1/ uniform_cdf 2/ uniformd Ex1:uniform_icdf(4.2,10.3,0.95) Ex2:uniform_icdf(3.2,5.7,0.48) - ''' return GiacMethods['uniform_icdf'](self,*args) @@ -17859,12 +16448,11 @@ cdef class GiacMethods_base: Help for uniformd: uniformd(Real(a),Real(b),Real(x)) Returns the probability density at x of the uniform law on [a,b]. - See also: 1/ uniform_cdf 2/ uniform_icdf 3/ randvector 4/ ranm + See also: 1/ uniform_cdf 2/ uniform_icdf 3/ randvector 4/ ranm Ex1:uniformd(2,5,4) Ex2:uniformd(1.2,3.5,3) Ex3: randvector(3,uniform,1.2,3.5) Ex4: ranm(4,3,uniform,1.2,3.5) - ''' return GiacMethods['uniformd'](self,*args) @@ -17873,10 +16461,9 @@ cdef class GiacMethods_base: Help for uniformd_cdf: uniformd_cdf(Real(a),Real(b),Real(x0),[Real(y0)]) Returns the probability that a uniform random variable on [a,b] is less than x0 (or between x0 and y0). - See also: 1/ uniformd 2/ uniform_icdf + See also: 1/ uniformd 2/ uniform_icdf Ex1:uniformd_cdf(3.2,5.7,4.4) Ex2:uniformd_cdf(3.2,5.7,4.4,5.4) - ''' return GiacMethods['uniformd_cdf'](self,*args) @@ -17885,10 +16472,9 @@ cdef class GiacMethods_base: Help for uniformd_icdf: uniformd_icdf(Real(a),Real(b),Real(p)) Returns h such that the probability that a uniform random variable on [a,b] is less than h is p (0<=p<=1). - See also: 1/ uniform_cdf 2/ uniformd + See also: 1/ uniform_cdf 2/ uniformd Ex1:uniformd_icdf(4.2,10.3,0.95) Ex2:uniformd_icdf(3.2,5.7,0.48) - ''' return GiacMethods['uniformd_icdf'](self,*args) @@ -17897,12 +16483,11 @@ cdef class GiacMethods_base: Help for unitV: unitV(Lst||Cplx) Returns the vector divided by its l2norm. It is also an option for plotfield. - See also: 1/ l2norm + See also: 1/ l2norm Ex1:unitV(3+4*i) Ex2:unitV([3,4]) Ex3: fieldplot(-t*y,[t,y],normalize) Ex4: fieldplot(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) - ''' return GiacMethods['unitV'](self,*args) @@ -17911,9 +16496,8 @@ cdef class GiacMethods_base: Help for unquote: unquote(Expr) Evaluates a quoted expression (for example purge(c);a:=c;unquote(a):=3; put 3 in the variables a and c). - See also: 1/ quote + See also: 1/ quote Ex1:unquote(a) - ''' return GiacMethods['unquote'](self,*args) @@ -17922,10 +16506,9 @@ cdef class GiacMethods_base: Help for upper: upper(Mtrx||Strng) Returns the upper triangular matrix (over the diagonal, included) or writes a string in uppercase. - See also: 1/ diag 2/ lower + See also: 1/ diag 2/ lower Ex1:upper([[1,2,3],[4,5,6],[7,8,9]]) Ex2:upper("hello") - ''' return GiacMethods['upper'](self,*args) @@ -17934,10 +16517,9 @@ cdef class GiacMethods_base: Help for user_operator: user_operator(Str(R),Fnc(f),Opt(Binary||Unary||Delete)) Defines a binary operator and returns 0 (failure) or 1(success). - See also: 1/ + See also: 1/ Ex1:user_operator("R",(x,y)->x*y+x+y,Binary) Ex2:user_operator("R",(x,y)->x*y+x+y,Delete) - ''' return GiacMethods['user_operator'](self,*args) @@ -17946,9 +16528,8 @@ cdef class GiacMethods_base: Help for usimplify: usimplify(Unit) Simplifies a unit in a unit object. - See also: 1/ convert 2/ mksa 3/ ufactor + See also: 1/ convert 2/ mksa 3/ ufactor Ex1:usimplify(100_(W*s)) - ''' return GiacMethods['usimplify'](self,*args) @@ -17957,12 +16538,11 @@ cdef class GiacMethods_base: Help for valuation: valuation(Poly(P)) Returns the valuation (degree of the term of lowest degree) of the polynomial P. - See also: 1/ degree 2/ tcoeff + See also: 1/ degree 2/ tcoeff Ex1:valuation(x^4+x^3) Ex2:valuation([1,1,0,0,0]) Ex3:valuation(x^5+3*x^2) Ex4:valuation([5,0,0,3,0,0]) - ''' return GiacMethods['valuation'](self,*args) @@ -17971,9 +16551,8 @@ cdef class GiacMethods_base: Help for vandermonde: vandermonde(Vect(V)) Returns the Vandermonde matrix=[V^0,V^1,..]. - See also: 1/ det + See also: 1/ det Ex1:vandermonde([1,2,a]) - ''' return GiacMethods['vandermonde'](self,*args) @@ -17982,10 +16561,9 @@ cdef class GiacMethods_base: Help for variables_are_files: variables_are_files(:=Intg(0 or 1)) Pseudo-variable to specify if you want to save the variables as file "nameofthevariable.cas". - See also: 1/ cas_setup + See also: 1/ cas_setup Ex1: variables_are_files:=1 Ex2: variables_are_files:=0 - ''' return GiacMethods['variables_are_files'](self,*args) @@ -17994,11 +16572,10 @@ cdef class GiacMethods_base: Help for variance: variance(Lst||Mtrx,[Lst]) Returns the variance of a list with the second argument as weights or the list of variances of the columns of a matrix. - See also: 1/ stddev 2/ mean + See also: 1/ stddev 2/ mean Ex1:variance([3,4,2]) Ex2:variance([1,2,3],[1,2,1]) Ex3:variance([[1,2,3],[5,6,7]]) - ''' return GiacMethods['variance'](self,*args) @@ -18007,9 +16584,8 @@ cdef class GiacMethods_base: Help for version: version(NULL) Returns the giac version number; for example, you are using : giac 0.4.0 - See also: 1/ + See also: 1/ Ex1:version() - ''' return GiacMethods['version'](self,*args) @@ -18018,11 +16594,10 @@ cdef class GiacMethods_base: Help for vertex_connectivity: vertex_connectivity(Graph(G)) Returns the largest integer k such that undirected connected graph G remains connected when fewer than k vertices are removed. - See also: 1/ edge_connectivity 2/ is_connected + See also: 1/ edge_connectivity 2/ is_connected Ex1:vertex_connectivity(graph("petersen")) Ex2:vertex_connectivity(graph("clebsch")) Ex3:vertex_connectivity(complete_graph(5)) - ''' return GiacMethods['vertex_connectivity'](self,*args) @@ -18031,9 +16606,8 @@ cdef class GiacMethods_base: Help for vertex_degree: vertex_degree(Graph(G),Vrtx(v)) Returns the degree of the vertex v in G (i.e. the number of edges incident to v). - See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_in_degree 6/ vertex_out_degree + See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_in_degree 6/ vertex_out_degree Ex1:vertex_degree(digraph(trail(1,2,3,4,2)),2) - ''' return GiacMethods['vertex_degree'](self,*args) @@ -18042,10 +16616,9 @@ cdef class GiacMethods_base: Help for vertex_distance: vertex_distance(Graph(G),Vrtx(s),Vrtx(t)||Lst(T)) Returns the number of edges in the shortest path from vertex s to vertex t in G. If such path does not exist, returns +infinity. For vector T of vertices from G returns the list of distances from s to each vertex t in T. - See also: 1/ allpairs_distance 2/ graph_diameter 3/ dijkstra 4/ shortest_path + See also: 1/ allpairs_distance 2/ graph_diameter 3/ dijkstra 4/ shortest_path Ex1:vertex_distance(graph("petersen"),1,4) Ex2:vertex_distance(graph("petersen"),1,[2,4]) - ''' return GiacMethods['vertex_distance'](self,*args) @@ -18054,9 +16627,8 @@ cdef class GiacMethods_base: Help for vertex_in_degree: vertex_in_degree(Graph(G),Vrtx(v)) Returns the number of arcs in G entering the vertex v. - See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_degree 6/ vertex_out_degree + See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_degree 6/ vertex_out_degree Ex1:vertex_in_degree(digraph(trail(1,2,3,4,2)),2) - ''' return GiacMethods['vertex_in_degree'](self,*args) @@ -18065,9 +16637,8 @@ cdef class GiacMethods_base: Help for vertex_out_degree: vertex_out_degree(Graph(G),Vrtx(v)) Returns the number of arcs in G emanating from the vertex v. - See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_degree 6/ vertex_in_degree + See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_degree 6/ vertex_in_degree Ex1:vertex_out_degree(digraph(trail(1,2,3,4,2)),2) - ''' return GiacMethods['vertex_out_degree'](self,*args) @@ -18076,11 +16647,10 @@ cdef class GiacMethods_base: Help for vertices: vertices(Polygon or Polyedr(P)) Returns the list of the vertices of the polygon or polyhedron P. - See also: 1/ isosceles_triangle 2/ polyhedron + See also: 1/ isosceles_triangle 2/ polyhedron Ex1:vertices(isosceles_triangle(0,1,pi/4)) Ex2:vertices(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex3:vertices(isosceles_triangle(0,1,pi/4))[2] - ''' return GiacMethods['vertices'](self,*args) @@ -18089,11 +16659,10 @@ cdef class GiacMethods_base: Help for vertices_abc: vertices_abc(Polygon or Polyedr(P)) Returns the list of the vertices of the polygon or polyhedron P. - See also: 1/ isosceles_triangle 2/ polyhedron + See also: 1/ isosceles_triangle 2/ polyhedron Ex1:vertices_abc(isosceles_triangle(0,1,pi/4)) Ex2:vertices_abc(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex3:vertices_abc(isosceles_triangle(0,1,pi/4))[2] - ''' return GiacMethods['vertices_abc'](self,*args) @@ -18102,11 +16671,10 @@ cdef class GiacMethods_base: Help for vertices_abca: vertices_abca(Polygon or Polyedr(P)) Returns the closed list [A,B,...A] of the vertices of the polygon or polyhedron P. - See also: 1/ isosceles_triangle 2/ polyhedron + See also: 1/ isosceles_triangle 2/ polyhedron Ex1:vertices_abca(isosceles_triangle(0,1,pi/4)) Ex2:vertices_abca(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex3:vertices_abca(isosceles_triangle(0,1,pi/4))[2] - ''' return GiacMethods['vertices_abca'](self,*args) @@ -18115,9 +16683,8 @@ cdef class GiacMethods_base: Help for vpotential: vpotential(Vect(V),LstVar) Returns U such that curl(U)=V. - See also: 1/ curl 2/ potential + See also: 1/ curl 2/ potential Ex1:vpotential([2*x*y+3,x^2-4*z,-2*y*z],[x,y,z]) - ''' return GiacMethods['vpotential'](self,*args) @@ -18126,9 +16693,8 @@ cdef class GiacMethods_base: Help for web_graph: web_graph(Intg(a),Intg(b)) Returns a web graph on a*b vertices, where a>=3 and b>=2. - See also: 1/ prism_graph 2/ wheel_graph + See also: 1/ prism_graph 2/ wheel_graph Ex1:web_graph(5,3) - ''' return GiacMethods['web_graph'](self,*args) @@ -18137,11 +16703,10 @@ cdef class GiacMethods_base: Help for weibull: weibull(Real(k),Real(lambda),Real(theta),Real(x)) Returns the density of probability at x of the Weibull law with parameters k, lambda, theta (by default theta=0). - See also: 1/ weibull_cdf 2/ weibull_icdf + See also: 1/ weibull_cdf 2/ weibull_icdf Ex1:weibull(2.1,1.2,1.3) Ex2:weibull(2.1,1.2,0.0,1.3) Ex3:weibull(2.1,1.2,0.5,1.8) - ''' return GiacMethods['weibull'](self,*args) @@ -18150,13 +16715,12 @@ cdef class GiacMethods_base: Help for weibull_cdf: weibull_cdf(Real(k),Real(lambda),Real(theta),Real(x0)) Returns the probability that a Weibull random variable of parameters k, lambda, theta is less than x0. - See also: 1/ weibulld 2/ weibull_icdf + See also: 1/ weibulld 2/ weibull_icdf Ex1:weibull_cdf(2.1,1.2,1.9) Ex2:weibull_cdf(2.1,1.2,0.0,1.9) Ex3:weibull_cdf(2.2,1.5,0.4,1.9) Ex4:weibull_cdf(2.2,1.5,0.4,1.2) Ex5:weibull_cdf(2.2,1.5,0.4,1.2,1.9) - ''' return GiacMethods['weibull_cdf'](self,*args) @@ -18165,10 +16729,9 @@ cdef class GiacMethods_base: Help for weibull_icdf: weibull_icdf(Real(k),Real(lambda),Real(theta),Real(p)) Returns h such that the probability that a Weibull random variable of parameters k, lambda, theta is less than h is p (0<=p<=1). - See also: 1/ weibull_cdf 2/ weibull + See also: 1/ weibull_cdf 2/ weibull Ex1:weibull_icdf(4.2,1.3,0.0,0.95) Ex2:weibull_icdf(2.2,1.5,0.4,0.632) - ''' return GiacMethods['weibull_icdf'](self,*args) @@ -18177,11 +16740,10 @@ cdef class GiacMethods_base: Help for weibulld: weibulld(Real(k),Real(lambda),Real(theta),Real(x)) Returns the density of probability at x of the Weibull law with parameters k, lambda, theta (by default theta=0). - See also: 1/ weibull_cdf 2/ weibull_icdf + See also: 1/ weibull_cdf 2/ weibull_icdf Ex1:weibulld(2.1,1.2,1.3) Ex2:weibulld(2.1,1.2,0.0,1.3) Ex3:weibulld(2.1,1.2,0.5,1.8) - ''' return GiacMethods['weibulld'](self,*args) @@ -18190,13 +16752,12 @@ cdef class GiacMethods_base: Help for weibulld_cdf: weibulld_cdf(Real(k),Real(lambda),Real(theta),Real(x0)) Returns the probability that a Weibull random variable of parameters k, lambda, theta is less than x0. - See also: 1/ weibulld 2/ weibull_icdf + See also: 1/ weibulld 2/ weibull_icdf Ex1:weibulld_cdf(2.1,1.2,1.9) Ex2:weibulld_cdf(2.1,1.2,0.0,1.9) Ex3:weibulld_cdf(2.2,1.5,0.4,1.9) Ex4:weibulld_cdf(2.2,1.5,0.4,1.2) Ex5:weibulld_cdf(2.2,1.5,0.4,1.2,1.9) - ''' return GiacMethods['weibulld_cdf'](self,*args) @@ -18205,10 +16766,9 @@ cdef class GiacMethods_base: Help for weibulld_icdf: weibulld_icdf(Real(k),Real(lambda),Real(theta),Real(p)) Returns h such that the probability that a Weibull random variable of parameters k, lambda, theta is less than h is p (0<=p<=1). - See also: 1/ weibull_cdf 2/ weibull + See also: 1/ weibull_cdf 2/ weibull Ex1:weibulld_icdf(4.2,1.3,0.0,0.95) Ex2:weibulld_icdf(2.2,1.5,0.4,0.632) - ''' return GiacMethods['weibulld_icdf'](self,*args) @@ -18217,10 +16777,9 @@ cdef class GiacMethods_base: Help for weibullvariate: weibullvariate(Real(a),Real(b)) Returns a random real according to the Weibull distribution with parameters a>0 and b>0. - See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector + See also: 1/ rand 2/ randpoly 3/ randnorm 4/ randvector Ex1:weibullvariate(1,2) Ex2:weibullvariate(1.5,4) - ''' return GiacMethods['weibullvariate'](self,*args) @@ -18229,9 +16788,8 @@ cdef class GiacMethods_base: Help for weight_matrix: weight_matrix(Graph(G)) Returns the weight matrix of G. - See also: 1/ set_edge_weight 2/ get_edge_weights 3/ is_weighted 4/ make_weighted 5/ assign_edge_weights + See also: 1/ set_edge_weight 2/ get_edge_weights 3/ is_weighted 4/ make_weighted 5/ assign_edge_weights Ex1:weight_matrix(graph(%{[[1,2],2],[[2,3],1]%}) - ''' return GiacMethods['weight_matrix'](self,*args) @@ -18240,8 +16798,7 @@ cdef class GiacMethods_base: Help for weighted: weighted(Opt) Option for graph and digraph commands. - See also: 1/ directed 2/ graph 3/ digraph - + See also: 1/ directed 2/ graph 3/ digraph ''' return GiacMethods['weighted'](self,*args) @@ -18250,8 +16807,7 @@ cdef class GiacMethods_base: Help for weights: weights(Opt) Option for the edges command. - See also: 1/ edges - + See also: 1/ edges ''' return GiacMethods['weights'](self,*args) @@ -18260,9 +16816,8 @@ cdef class GiacMethods_base: Help for welch_window: welch_window(Lst,[Interval(n1..n2)]) Applies the Welch windowing function to the given signal u (or to the elements with indices between n1 and n2) and returns the result in a new list. - See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ bartlett_hann_window + See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ bartlett_hann_window Ex1: scatterplot(welch_window(randvector(1000,0..1))) - ''' return GiacMethods['welch_window'](self,*args) @@ -18271,9 +16826,8 @@ cdef class GiacMethods_base: Help for wheel_graph: wheel_graph(Intg(n)) Returns a wheel graph with n+1 vertices. - See also: 1/ star_graph 2/ web_graph + See also: 1/ star_graph 2/ web_graph Ex1:wheel_graph(5) - ''' return GiacMethods['wheel_graph'](self,*args) @@ -18282,11 +16836,10 @@ cdef class GiacMethods_base: Help for widget_size: widget_size(Intg(n)) Changes the character sizes of the display on the xcas screen (size=n) and with more parameters define the general configuration. - See also: 1/ cas_setup + See also: 1/ cas_setup Ex1:widget_size(20) Ex2:widget_size(8) Ex3:widget_size(20,58,49,697,563,1,1,0) - ''' return GiacMethods['widget_size'](self,*args) @@ -18295,10 +16848,9 @@ cdef class GiacMethods_base: Help for wilcoxonp: wilcoxonp(Intg,[Intg]) Distribution of the Wilcoxon or Mann-Whitney test for one or two samples. - See also: 1/ wilcoxont 2/ wilcoxons + See also: 1/ wilcoxont 2/ wilcoxons Ex1:wilcoxonp(4) Ex2:wilcoxonp(7,5) - ''' return GiacMethods['wilcoxonp'](self,*args) @@ -18307,10 +16859,9 @@ cdef class GiacMethods_base: Help for wilcoxons: wilcoxons(List,List || Real) Rank statistic of Wilcoxon or Mann-Whitney for 1 sample and one median or 2 samples. - See also: 1/ wilcoxont 2/ wilcoxonp + See also: 1/ wilcoxont 2/ wilcoxonp Ex1:wilcoxons([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , [2, 6, 10, 11, 13, 14, 15, 18, 19, 20]) Ex2:wilcoxons([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , 10) - ''' return GiacMethods['wilcoxons'](self,*args) @@ -18319,12 +16870,11 @@ cdef class GiacMethods_base: Help for wilcoxont: wilcoxont(List,List || Real,[Func],[Real]) Wilcoxon or Mann-Whitney test for one sample and a median or 2 samples. - See also: 1/ wilcoxonp 2/ wilcoxons 3/ studentt 4/ normalt + See also: 1/ wilcoxonp 2/ wilcoxons 3/ studentt 4/ normalt Ex1:wilcoxont([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , [2, 6, 10, 11, 13, 14, 15, 18, 19, 20]) Ex2:wilcoxont([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , [2, 6, 10, 11, 13, 14, 15, 18, 19, 20],0.01) Ex3:wilcoxont([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , 10,'>') Ex4:wilcoxont([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , 10,'>',0.05) - ''' return GiacMethods['wilcoxont'](self,*args) @@ -18333,11 +16883,10 @@ cdef class GiacMethods_base: Help for writergb: writergb(Str(s),Lst) Write a PNG picture file named s either from a list [[number_channels,width,height],red,green,alpha,blue] where red,green,alpha,blue are matrices of pixels color or from a matrix of grey pixels or from 3 matrices of RGB colored pixels. - See also: 1/ readrgb + See also: 1/ readrgb Ex1:writergb("image.png",[[255,0],[0,255]]) Ex2:writergb("image.png",[[255,0],[0,0]],[[0,255],[0,0]],[[0,0],[255,0]]) Ex3: a:=readrgb("rgb_image.png");writergb("brg_image.png",[a[0],a[4],a[1],a[3],a[2]]) - ''' return GiacMethods['writergb'](self,*args) @@ -18346,10 +16895,9 @@ cdef class GiacMethods_base: Help for writewav: writewav(Str(s),Lst(l)) Writes a WAV sound file. - See also: 1/ readwav + See also: 1/ readwav Ex1:writewav("la.wav",2^14*(sin(2*pi*440*soundsec(1)))) Ex2:writewav("beep.wav",[[1,16,44100,80000],[65000$10000,0$10000,65000$10000,0$10000]]) - ''' return GiacMethods['writewav'](self,*args) @@ -18358,10 +16906,9 @@ cdef class GiacMethods_base: Help for xcas_mode: xcas_mode(Intg(0) or 1 or 2 or 3) Switches to mode Xcas (0), Maple (1), Mupad (2), TI89 (3). - See also: 1/ python_compat + See also: 1/ python_compat Ex1:xcas_mode(1) Ex2:xcas_mode(0) - ''' return GiacMethods['xcas_mode'](self,*args) @@ -18370,9 +16917,8 @@ cdef class GiacMethods_base: Help for xml_print: xml_print(Str) Indents a XML code given in a string (pretty print). - See also: 1/ export_mathml + See also: 1/ export_mathml Ex1:xml_print(export_mathml(a+2*b)) - ''' return GiacMethods['xml_print'](self,*args) @@ -18382,7 +16928,6 @@ cdef class GiacMethods_base: xyztrange(SeqReal) xyztrange puts or erases the axes on the graphic-screen (cf button Cfg). Ex1:xyztrange(-5.0,5.0,-5.0,2.0,-10.0,10.0,-1.0,6.0,-5.0,5.0,-1.2384,2.0,1,0.0,1.0) - ''' return GiacMethods['xyztrange'](self,*args) @@ -18391,12 +16936,11 @@ cdef class GiacMethods_base: Help for zeros: zeros(Expr,[Var]) Returns the zeros (real or complex according to the mode) of the expression (or the matrix where the lines are the solutions of the system : expression1=0,expression2=0...). - See also: 1/ + See also: 1/ Ex1:zeros(x^2+4) Ex2:zeros(ln(x)^2-4) Ex3:zeros(ln(y)^2-2,y) Ex4:zeros([x^2-1,x^2-y^2],[x,y]) - ''' return GiacMethods['zeros'](self,*args) @@ -18405,10 +16949,9 @@ cdef class GiacMethods_base: Help for ztrans: ztrans(Expr,[Var],[ZtransVar]) z transform of a sequence. - See also: 1/ invztrans 2/ laplace 3/ invlaplace + See also: 1/ invztrans 2/ laplace 3/ invlaplace Ex1:ztrans(a^x) Ex2:ztrans(a^n,n,z) - ''' return GiacMethods['ztrans'](self,*args) @@ -18417,10 +16960,9 @@ cdef class GiacMethods_base: Help for type: type(Expr) Returns n in [1..12] that defines the type of the argument. - See also: 1/ DOM_FLOAT 2/ DOM_INT 3/ DOM_COMPLEX 4/ DOM_IDENT 5/ DOM_LIST 6/ DOM_SYMBOLIC 7/ DOM_RAT 8/ DOM_STRING 9/ DOM_FUNC 10/ subtype + See also: 1/ DOM_FLOAT 2/ DOM_INT 3/ DOM_COMPLEX 4/ DOM_IDENT 5/ DOM_LIST 6/ DOM_SYMBOLIC 7/ DOM_RAT 8/ DOM_STRING 9/ DOM_FUNC 10/ subtype Ex1:type("abc") Ex2:type([1,2,3]) - ''' return GiacMethods['type'](self,*args) @@ -18429,12 +16971,11 @@ cdef class GiacMethods_base: Help for zip: zip(Fnc2d(f),Lst(l1),Lst(l2),[Val(default)]) Returns a list whose j-th entry is f(l1[j],l2[j]): without default value its length is the minimum of the lengths of the two input lists and otherwise the shorter list is padded with the default value. - See also: 1/ + See also: 1/ Ex1:zip('+',[a,b,c,d], [1,2,3,4]) Ex2:zip('+',[a,b,c,d], [1,2,3]) Ex3:zip('+',[a,b,c,d], [1,2,3],5) Ex4:zip(sum,[a,b,c,d], [1,2,3,4]) - ''' return GiacMethods['zip'](self,*args) diff --git a/src/sage/libs/giac/giac.pxd b/src/sage/libs/giac/giac.pxd index 1d9da88d8d4..d069c04a8a1 100644 --- a/src/sage/libs/giac/giac.pxd +++ b/src/sage/libs/giac/giac.pxd @@ -193,7 +193,7 @@ cdef extern from "misc.h": int giacgencmp( gen & , gen & , context *) except + int giacgenrichcmp( gen & , gen & , int, context *) except + #NB: we use the following multiplication otherwise some giac errors make python quit: - #l=giac([1,2]); l.tranpose()*l + #l=giac([1,2]); l.transpose()*l gen GIAC_giacmul "giacmul"( gen & , gen & , context *) except + gen GIAC_giacdiv "giacdiv"( gen & , gen & , context *) except + gen GIAC_giacmod "giacmod"( gen & , gen & , context *) except + diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 111cd284ef8..4094307f0fd 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.giac # distutils: libraries = giac # distutils: language = c++ # distutils: extra_compile_args = -std=c++11 @@ -170,15 +171,8 @@ from sage.interfaces.giac import giac # Python3 compatibility ############################ -def decstring23(s): - return s.decode() - - def encstring23(s): return bytes(s, 'UTF-8') - - -listrange = list, range # End of Python3 compatibility ##################### @@ -216,7 +210,7 @@ def _giac(s): sage: (x+2*y).cos().texpand() cos(x)*(2*cos(y)^2-1)-sin(x)*2*cos(y)*sin(y) - Coercion, Pygen and internal giac variables: The most usefull objects will + Coercion, Pygen and internal giac variables: The most useful objects will be the Python object of type Pygen.:: sage: x,y,z = libgiac('x,y,z') @@ -296,14 +290,14 @@ def _giac(s): sage: A [[44,2],[3,4]] - Sparse Matrices are avaible via the table function: + Sparse Matrices are available via the table function: :: sage: A = libgiac.table(()); A # create an empty giac table table( ) - sage: A[2,3] = 33; A[0,2] = '2/7' # set non zero entries of the sparse matrix + sage: A[2,3] = 33; A[0,2] = '2/7' # set nonzero entries of the sparse matrix sage: A*A # basic matrix operation are supported with sparse matrices table( (0,3) = 66/7 @@ -517,7 +511,7 @@ def _giac(s): ``q2a``, ``isom``, ``mkisom`` - - *Finite Fieds* + - *Finite Fields* * ``%``, ``% 0``, ``mod``, ``GF``, ``powmod`` @@ -538,7 +532,6 @@ def _giac(s): - *Set* * ``intersect``, ``minus``, ``union``, ``is_element``, ``is_included`` - """ return Pygen(s).eval() @@ -548,7 +541,7 @@ def _giac(s): ####################################### cdef class GiacSetting(Pygen): """ - A class to customise the Computer Algebra System settings + A class to customise the Computer Algebra System settings. EXAMPLES:: @@ -798,7 +791,7 @@ cdef class Pygen(GiacMethods_base): #NB: the != here gives problems with the __richcmp__ function #if (s!=None): # so it's better to use isinstance - if (isinstance(s,None.__class__)): + if (isinstance(s, None.__class__)): # Do NOT replace with: self=GIACNULL (cf the doctest in __repr__ sig_on() self.gptr = new gen ((GIACNULL).gptr[0]) @@ -849,7 +842,7 @@ cdef class Pygen(GiacMethods_base): self.gptr = new gen((s).gptr[0]) sig_off() - elif isinstance(s, listrange): + elif isinstance(s, (list, range)): sig_on() self.gptr = new gen(_wrap_pylist(s),0) sig_off() @@ -867,7 +860,7 @@ cdef class Pygen(GiacMethods_base): s = s._giac_init_() except AttributeError: s = SRexpressiontoGiac(s) - if not(isinstance(s, str)): #modif python3 + if not isinstance(s, str): s = s.__str__() sig_on() self.gptr = new gen(encstring23(s),context_ptr) @@ -881,14 +874,14 @@ cdef class Pygen(GiacMethods_base): sig_on() t=GIAC_taille(self.gptr[0], 6000) sig_off() - if (t<6000) : + if t < 6000: sig_on() - result=decstring23(GIAC_print(self.gptr[0], context_ptr).c_str()) #python3 + result = GIAC_print(self.gptr[0], context_ptr).c_str().decode() sig_off() return result else: sig_on() - result=str(self.type)+"\nResult is too big for Display. If you really want to see it use print" + result = str(self.type) + "\nResult is too big for Display. If you really want to see it use print" sig_off() return result @@ -896,7 +889,7 @@ cdef class Pygen(GiacMethods_base): #if self.gptr == NULL: # return '' sig_on() - result=decstring23(GIAC_print(self.gptr[0], context_ptr).c_str()) #python3 + result = GIAC_print(self.gptr[0], context_ptr).c_str().decode() sig_off() return result @@ -907,7 +900,6 @@ cdef class Pygen(GiacMethods_base): sage: from sage.libs.giac.giac import libgiac sage: l=libgiac("seq[]");len(l) # 29552 comment28 0 - """ if (self._type == 7): sig_on() @@ -928,7 +920,7 @@ cdef class Pygen(GiacMethods_base): TESTS:: sage: from sage.libs.giac.giac import libgiac - sage: l=libgiac(list(range(10^6)));l[5] #python3 + sage: l=libgiac(list(range(10^6)));l[5] 5 sage: l[35:50:7] [35,42,49] @@ -962,19 +954,19 @@ cdef class Pygen(GiacMethods_base): if(i<0): i=i+n sig_on() - result=self.gptr[0][i] + result = self.gptr[0][i] sig_off() return _wrap_gen(result) else: raise IndexError('list index %s out of range'%(i)) else: - if isinstance(i,slice): + if isinstance(i, slice): sig_on() - result=gen(_getgiacslice(self,i),self._subtype) + result = gen(_getgiacslice(self,i),self._subtype) sig_off() return _wrap_gen(result) # add support for multi indexes - elif isinstance(i,tuple): + elif isinstance(i, tuple): if(len(i)==2): return self[i[0]][i[1]] elif(len(i)==1): @@ -1045,7 +1037,7 @@ cdef class Pygen(GiacMethods_base): def __iter__(self): """ - Pygen lists of 10^6 elements should be yield + Pygen lists of 10^6 elements should be yield. TESTS:: @@ -1067,7 +1059,7 @@ cdef class Pygen(GiacMethods_base): def eval(self): cdef gen result sig_on() - result=GIAC_protecteval(self.gptr[0],giacsettings.eval_level,context_ptr) + result = GIAC_protecteval(self.gptr[0],giacsettings.eval_level,context_ptr) sig_off() return _wrap_gen(result) @@ -1080,7 +1072,7 @@ cdef class Pygen(GiacMethods_base): if not isinstance(self, Pygen): self=Pygen(self) sig_on() - result= (self).gptr[0] + (right).gptr[0] + result = (self).gptr[0] + (right).gptr[0] sig_off() return _wrap_gen(result) @@ -1130,7 +1122,7 @@ cdef class Pygen(GiacMethods_base): if not isinstance(self, Pygen): self=Pygen(self) sig_on() - result= (self).gptr[0] - (right).gptr[0] + result = (self).gptr[0] - (right).gptr[0] sig_off() return _wrap_gen(result) @@ -1146,19 +1138,19 @@ cdef class Pygen(GiacMethods_base): """ cdef gen result if not isinstance(right, Pygen): - right=Pygen(right) + right = Pygen(right) if not isinstance(self, Pygen): - self=Pygen(self) - #result= (self).gptr[0] * (right).gptr[0] + self = Pygen(self) + #result = (self).gptr[0] * (right).gptr[0] #NB: with the natural previous method, the following error generated by #giac causes python to quit instead of an error message. #l=Pygen([1,2]);l.transpose()*l; sig_on() - result= GIAC_giacmul((self).gptr[0] , (right).gptr[0],context_ptr) + result = GIAC_giacmul((self).gptr[0], (right).gptr[0],context_ptr) sig_off() return _wrap_gen(result) -#PB / in python3 is truediv + # PB / in python3 is truediv def __div__(self, right): """ TESTS:: @@ -1171,57 +1163,57 @@ cdef class Pygen(GiacMethods_base): """ cdef gen result if not isinstance(right, Pygen): - right=Pygen(right) + right = Pygen(right) if not isinstance(self, Pygen): - self=Pygen(self) + self = Pygen(self) sig_on() - result= GIAC_giacdiv((self).gptr[0] , (right).gptr[0],context_ptr) + result = GIAC_giacdiv((self).gptr[0], (right).gptr[0],context_ptr) sig_off() return _wrap_gen(result) def __truediv__(self, right): cdef gen result if not isinstance(right, Pygen): - right=Pygen(right) + right = Pygen(right) if not isinstance(self, Pygen): - self=Pygen(self) + self = Pygen(self) sig_on() - result= (self).gptr[0] / (right).gptr[0] + result = (self).gptr[0] / (right).gptr[0] sig_off() return _wrap_gen(result) - def __pow__(self, right ,ignored): + def __pow__(self, right, ignored): cdef gen result if not isinstance(right, Pygen): - right=Pygen(right) + right = Pygen(right) if not isinstance(self, Pygen): - self=Pygen(self) + self = Pygen(self) sig_on() - result= GIAC_pow((self).gptr[0],(right).gptr[0], context_ptr ) + result = GIAC_pow((self).gptr[0], (right).gptr[0], context_ptr ) sig_off() return _wrap_gen(result) def __mod__(self, right): cdef gen result if not isinstance(right, Pygen): - right=Pygen(right) + right = Pygen(right) if not isinstance(self, Pygen): - self=Pygen(self) - #result= gen(GIAC_makenewvecteur((self).gptr[0],(right).gptr[0]),1) + self = Pygen(self) + #result = gen(GIAC_makenewvecteur((self).gptr[0],(right).gptr[0]),1) #to have an integer output: - #result= GIAC_smod(result,context_ptr) + #result = GIAC_smod(result,context_ptr) #we give a modular output: sig_on() - result= GIAC_giacmod((self).gptr[0],(right).gptr[0],context_ptr) + result = GIAC_giacmod((self).gptr[0], (right).gptr[0],context_ptr) sig_off() return _wrap_gen(result) def __neg__(self): cdef gen result if not isinstance(self, Pygen): - self=Pygen(self) + self = Pygen(self) sig_on() - result= GIAC_neg((self).gptr[0]) + result = GIAC_neg((self).gptr[0]) sig_off() return _wrap_gen(result) @@ -1234,12 +1226,12 @@ cdef class Pygen(GiacMethods_base): def savegen(self, str filename): """ - Archive a Pygen element to a file in giac compressed format. + Archive a Pygen element to a file in giac compressed format. - Use the loadgiacgen command to get back the Pygen from the file. - In C++ these files can be opened with ``giac::unarchive``. + Use the loadgiacgen command to get back the Pygen from the file. + In C++ these files can be opened with ``giac::unarchive``. - EXAMPLES:: + EXAMPLES:: sage: from sage.libs.giac.giac import * sage: f=libgiac('(x+y+z+2)**10'); g=f.normal() @@ -1262,7 +1254,7 @@ cdef class Pygen(GiacMethods_base): def redim(self, a, b=None): """ - Increase the size of a matrix when possible, otherwise return self. + Increase the size of a matrix when possible, otherwise return ``self``. EXAMPLES:: @@ -1289,7 +1281,7 @@ cdef class Pygen(GiacMethods_base): # def htmlhelp(self, str lang='en'): # """ - # Open the giac html detailled help about self in an external browser + # Open the giac html detailed help about ``self`` in an external browser # There are currently 3 supported languages: 'en', 'fr', 'el' @@ -1298,8 +1290,8 @@ cdef class Pygen(GiacMethods_base): # if (not lang in ['en', 'fr', 'el']): # lang='en' # try: - # url=decstring23(browser_help(self.gptr[0],l[lang])) #python3 - # giacbasedir=decstring23(GIAC_giac_aide_dir()) # python3 + # url=browser_help(self.gptr[0],l[lang]).decode() + # giacbasedir=GIAC_giac_aide_dir().decode() # except: # raise RuntimeError('giac docs dir not found') # print(url) @@ -1340,13 +1332,13 @@ cdef class Pygen(GiacMethods_base): \frac{...x^{4}...-...y...}{...y^{2}-3...x...} """ sig_on() - result=decstring23(GIAC_gen2tex(self.gptr[0], context_ptr).c_str()) #python3 + result = GIAC_gen2tex(self.gptr[0], context_ptr).c_str().decode() sig_off() return result def _integer_(self,Z=None): """ - Convert giac integers or modular integers to sage Integers (via gmp) + Convert giac integers or modular integers to sage Integers (via gmp). EXAMPLES:: @@ -1360,11 +1352,10 @@ cdef class Pygen(GiacMethods_base): sage: c=libgiac('2 % nextprime(2**40)') sage: ZZ(c^1000) -233775163595 - sage: Mod(2,next_prime(2^40))^1000 - ZZ(c^1000) + sage: Mod(2,next_prime(2^40))^1000 - ZZ(c^1000) 0 sage: 2^320-(c^320).sage() 0 - """ cdef Integer n = PY_NEW(Integer) typ = self._type @@ -1395,7 +1386,7 @@ cdef class Pygen(GiacMethods_base): def _rational_(self, Z=None): """ - Convert giac rationals to sage rationals + Convert giac rationals to sage rationals. EXAMPLES:: @@ -1473,19 +1464,18 @@ cdef class Pygen(GiacMethods_base): sage: sage.symbolic.expression.register_symbol(sin, {'giac':'myFun'}) sage: ex.sage() sin(x) - """ typ = self._type - if (typ != 7) : + if typ != 7: # self is not a list - if ( typ == 0 or typ == 2): + if typ == 0 or typ == 2: return ZZ(self) - elif (typ == 10): + elif typ == 10: return QQ(self) - elif (typ == 15): + elif typ == 15: # modular integer sig_on() a = _wrap_gen( (self.gptr.ref_MODptr())[0]) @@ -1494,10 +1484,10 @@ cdef class Pygen(GiacMethods_base): sig_off() return result - elif (typ == 12): + elif typ == 12: # string sig_on() - result=eval(self.__str__()) + result = eval(self.__str__()) sig_off() return result @@ -1507,14 +1497,13 @@ cdef class Pygen(GiacMethods_base): else: # self is a list sig_on() - result=[entry.sage() for entry in self] + result = [entry.sage() for entry in self] sig_off() return result def _symbolic_(self, R): r""" - Convert self object to the ring R via a basic string evaluation. (slow) - + Convert ``self`` object to the ring R via a basic string evaluation. (slow) EXAMPLES:: @@ -1538,7 +1527,7 @@ cdef class Pygen(GiacMethods_base): sage: libgiac.integrate(cos(y), y).sage() sin(π) """ - if isinstance(R,SR.__class__): + if isinstance(R, SR.__class__): # Try to convert some functions names to the symbolic ring lsymbols = symbol_table['giac'].copy() #lsymbols.update(locals) @@ -1552,7 +1541,7 @@ cdef class Pygen(GiacMethods_base): raise NotImplementedError("Unable to parse Giac output: %s" % self.__repr__()) else: try: - result=R(self.__str__()) + result = R(self.__str__()) return result except Exception: @@ -1563,7 +1552,6 @@ cdef class Pygen(GiacMethods_base): Return matrix over the (Sage) ring R where self should be a Giac matrix. The default ring is ZZ. - EXAMPLES:: sage: from sage.libs.giac.giac import * @@ -1598,7 +1586,6 @@ cdef class Pygen(GiacMethods_base): Return vector over the (Sage) ring R where self should be a Giac matrix. The default ring is ZZ. - EXAMPLES:: sage: from sage.libs.giac.giac import * @@ -1608,7 +1595,7 @@ cdef class Pygen(GiacMethods_base): sage: vector(v+v/3,QQ) (0, 4/3, 8/3, 4, 16/3, 20/3, 8, 28/3, 32/3, 12) """ - if(isinstance(R, None.__class__)): + if isinstance(R, None.__class__): R=ZZ v = self.dim() @@ -1675,7 +1662,7 @@ cdef class Pygen(GiacMethods_base): if not isinstance(self, Pygen): self = Pygen(self) sig_on() - result= giacgenrichcmp((self).gptr[0],(other).gptr[0], op, context_ptr ) + result = giacgenrichcmp((self).gptr[0],(other).gptr[0], op, context_ptr ) sig_off() return result == 1 @@ -1693,7 +1680,7 @@ cdef class Pygen(GiacMethods_base): property _subtype: def __get__(self): sig_on() - result=self.gptr.subtype + result = self.gptr.subtype sig_off() return result @@ -1794,9 +1781,9 @@ cdef vecteur _wrap_pylist(L) except +: cdef vecteur * V cdef int i - if (isinstance(L, tuple) or isinstance(L, listrange)): - n=len(L) - V=new vecteur() + if isinstance(L, (tuple, list, range)): + n = len(L) + V = new vecteur() sig_on() for i in range(n): @@ -1814,14 +1801,14 @@ cdef vecteur _getgiacslice(Pygen L,slice sl) except +: cdef vecteur * V cdef int u - if (L.type()=="DOM_LIST"): + if L.type()=="DOM_LIST": n=len(L) V=new vecteur() sig_on() # for u in range(n)[sl]: #pb python3 - (b,e,st)=sl.indices(n) - for u in range(b,e,st): + b, e, st = sl.indices(n) + for u in range(b, e, st): V.push_back((L.gptr[0])[u]) sig_off() return V[0] @@ -1869,7 +1856,7 @@ cdef gen pylongtogen(a) except +: #def giaceval(Pygen self): # cdef gen result # try: -# result=GIAC_protecteval(self.gptr[0],1,context_ptr) +# result = GIAC_protecteval(self.gptr[0],1,context_ptr) # return _wrap_gen(result) # except: # raise @@ -1879,7 +1866,7 @@ cdef gen pylongtogen(a) except +: # # cdef gen result # try: -# result=GIAC_factor(self.gptr[0],context_ptr) +# result = GIAC_factor(self.gptr[0],context_ptr) # return _wrap_gen(result) # except: # raise @@ -1889,7 +1876,7 @@ cdef gen pylongtogen(a) except +: #def giacfactors(Pygen self): # cdef gen result # try: -# result=GIAC_factors(self.gptr[0],context_ptr) +# result = GIAC_factors(self.gptr[0],context_ptr) # return _wrap_gen(result) # except: # raise @@ -1900,7 +1887,7 @@ cdef gen pylongtogen(a) except +: #def giacnormal(Pygen self): # cdef gen result # try: -# result=GIAC_normal(self.gptr[0],context_ptr) +# result = GIAC_normal(self.gptr[0],context_ptr) # return _wrap_gen(result) # except: # raise @@ -1909,8 +1896,8 @@ cdef gen pylongtogen(a) except +: #def giacgcd(Pygen a, Pygen b): # cdef gen result # try: -# result=gen( GIAC_makenewvecteur(a.gptr[0],b.gptr[0]) ,1) -# result=GIAC_gcd(result,context_ptr) +# result = gen( GIAC_makenewvecteur(a.gptr[0],b.gptr[0]) ,1) +# result = GIAC_gcd(result,context_ptr) # return _wrap_gen(result) # except: # raise @@ -1927,7 +1914,7 @@ class GiacFunction(Pygen): # a class to evaluate args before call """ A Subclass of Pygen to create functions with evaluating all the args - before call so that they are substitued by their value. + before call so that they are substituted by their value. EXAMPLES:: @@ -1990,11 +1977,12 @@ for i in moremethods: GiacMethods[i] = tmp for i in mostkeywords+moremethods: - GiacMethods[i].__doc__ = eval("Pygen."+i+".__doc__") + GiacMethods[i].__doc__ = eval("Pygen." + i + ".__doc__") # To avoid conflicts we export only these few ones. Most giac keywords will be -# avaible through: libgiac.keywordname -__all__=['Pygen','giacsettings','libgiac','loadgiacgen','GiacFunction','GiacMethods','GiacMethods_base'] +# available through: libgiac.keywordname +__all__ = ['Pygen', 'giacsettings', 'libgiac', 'loadgiacgen', 'GiacFunction', + 'GiacMethods', 'GiacMethods_base'] def loadgiacgen(str filename): @@ -2022,7 +2010,7 @@ def loadgiacgen(str filename): """ cdef gen result sig_on() - result=GIAC_unarchive( encstring23(filename), context_ptr) + result = GIAC_unarchive( encstring23(filename), context_ptr) sig_off() return _wrap_gen(result) diff --git a/src/sage/libs/giac/meson.build b/src/sage/libs/giac/meson.build new file mode 100644 index 00000000000..6dda5a6c8a7 --- /dev/null +++ b/src/sage/libs/giac/meson.build @@ -0,0 +1,17 @@ +giac = cc.find_library('giac', required: false, disabler: true) + +py.install_sources('__init__.py', 'giac.pxd', 'misc.h', subdir: 'sage/libs/giac') + +extension_data_cpp = {'giac': files('giac.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/giac', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ext, inc_rings], + dependencies: [py_dep, cysignals, giac, gmp], + ) +endforeach diff --git a/src/sage/libs/glpk/meson.build b/src/sage/libs/glpk/meson.build new file mode 100644 index 00000000000..ee265cc1579 --- /dev/null +++ b/src/sage/libs/glpk/meson.build @@ -0,0 +1,9 @@ +py.install_sources( + '__init__.py', + 'constants.pxd', + 'env.pxd', + 'graph.pxd', + 'lp.pxd', + 'types.pxd', + subdir: 'sage/libs/glpk', +) diff --git a/src/sage/libs/gmp/meson.build b/src/sage/libs/gmp/meson.build new file mode 100644 index 00000000000..31fb4f3a5fa --- /dev/null +++ b/src/sage/libs/gmp/meson.build @@ -0,0 +1,29 @@ +py.install_sources( + '__init__.py', + 'all.pxd', + 'binop.pxd', + 'misc.pxd', + 'mpf.pxd', + 'mpn.pxd', + 'mpq.pxd', + 'mpz.pxd', + 'pylong.pxd', + 'random.pxd', + 'randomize.pxd', + 'types.pxd', + subdir: 'sage/libs/gmp', +) + +extension_data = {'pylong' : files('pylong.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/gmp', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/libs/gmp/mpz.pxd b/src/sage/libs/gmp/mpz.pxd index 66c44773d17..a53a49c5188 100644 --- a/src/sage/libs/gmp/mpz.pxd +++ b/src/sage/libs/gmp/mpz.pxd @@ -199,3 +199,4 @@ cdef extern from "gmp.h": void * _mpz_realloc (mpz_t integer, mp_size_t new_alloc) mp_limb_t mpz_getlimbn (mpz_t op, mp_size_t n) size_t mpz_size (mpz_t op) + mpz_srcptr mpz_roinit_n (mpz_t x, const mp_limb_t *xp, mp_size_t xs) diff --git a/src/sage/libs/gmp/pylong.pyx b/src/sage/libs/gmp/pylong.pyx index 30366841177..41587396120 100644 --- a/src/sage/libs/gmp/pylong.pyx +++ b/src/sage/libs/gmp/pylong.pyx @@ -57,7 +57,7 @@ cdef size_t PyLong_nails = 8*sizeof(digit) - PyLong_SHIFT cdef mpz_get_pylong_large(mpz_srcptr z): """ - Convert a non-zero ``mpz`` to a Python ``long``. + Convert a nonzero ``mpz`` to a Python ``long``. """ cdef size_t nbits = mpz_sizeinbase(z, 2) cdef size_t pylong_size = (nbits + PyLong_SHIFT - 1) // PyLong_SHIFT diff --git a/src/sage/libs/gsl/meson.build b/src/sage/libs/gsl/meson.build new file mode 100644 index 00000000000..ea5eac5e93a --- /dev/null +++ b/src/sage/libs/gsl/meson.build @@ -0,0 +1,82 @@ +py.install_sources( + '__init__.py', + 'airy.pxd', + 'all.pxd', + 'array.pxd', + 'bessel.pxd', + 'blas.pxd', + 'blas_types.pxd', + 'block.pxd', + 'chebyshev.pxd', + 'clausen.pxd', + 'combination.pxd', + 'complex.pxd', + 'coulomb.pxd', + 'coupling.pxd', + 'dawson.pxd', + 'debye.pxd', + 'dilog.pxd', + 'eigen.pxd', + 'elementary.pxd', + 'ellint.pxd', + 'elljac.pxd', + 'erf.pxd', + 'errno.pxd', + 'exp.pxd', + 'expint.pxd', + 'fermi_dirac.pxd', + 'fft.pxd', + 'fit.pxd', + 'gamma.pxd', + 'gegenbauer.pxd', + 'histogram.pxd', + 'hyperg.pxd', + 'integration.pxd', + 'interp.pxd', + 'laguerre.pxd', + 'lambert.pxd', + 'legendre.pxd', + 'linalg.pxd', + 'log.pxd', + 'math.pxd', + 'matrix.pxd', + 'matrix_complex.pxd', + 'min.pxd', + 'monte.pxd', + 'ntuple.pxd', + 'odeiv.pxd', + 'permutation.pxd', + 'poly.pxd', + 'pow_int.pxd', + 'psi.pxd', + 'qrng.pxd', + 'random.pxd', + 'rng.pxd', + 'roots.pxd', + 'sort.pxd', + 'statistics.pxd', + 'sum.pxd', + 'synchrotron.pxd', + 'transport.pxd', + 'trig.pxd', + 'types.pxd', + 'vector.pxd', + 'vector_complex.pxd', + 'wavelet.pxd', + 'zeta.pxd', + subdir: 'sage/libs/gsl', +) + +extension_data = {'array' : files('array.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/gsl', + install: true, + include_directories: [inc_gsl], + dependencies: [py_dep, cysignals, gmp, gsl], + ) +endforeach + diff --git a/src/sage/libs/homfly.pyx b/src/sage/libs/homfly.pyx index 550c5f02a65..b051e67cc63 100644 --- a/src/sage/libs/homfly.pyx +++ b/src/sage/libs/homfly.pyx @@ -57,11 +57,9 @@ def homfly_polynomial_string(link): INPUT: - - ``link`` -- a string of space-separated integers representing the link + - ``link`` -- string of space-separated integers representing the link - OUTPUT: - - A string with the HOMFLY polynomial in the variables `M` and `L` + OUTPUT: string with the HOMFLY polynomial in the variables `M` and `L` EXAMPLES:: @@ -83,11 +81,7 @@ def homfly_polynomial_dict(link): INPUT: - - ``link`` -- a string of space-separated integers representing the link - - OUTPUT: - - A dictionary representing the HOMFLY polynomial. + - ``link`` -- string of space-separated integers representing the link EXAMPLES:: diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pyx b/src/sage/libs/lcalc/lcalc_Lfunction.pyx index 87023b47741..f1173543ab1 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pyx +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pyx @@ -55,7 +55,7 @@ cdef class Lfunction: def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma, lambd, pole, residue): """ - Initialization of L-function objects. + Initialization of `L`-function objects. See derived class for details, this class is not supposed to be instantiated directly. @@ -113,7 +113,7 @@ cdef class Lfunction: def __repr__(self): """ - Return string representation of this L-function. + Return string representation of this `L`-function. EXAMPLES:: @@ -128,27 +128,27 @@ cdef class Lfunction: def value(self, s, derivative=0): """ - Computes the value of the L-function at ``s`` + Compute the value of the `L`-function at ``s``. INPUT: - - ``s`` -- a complex number - - ``derivative`` -- integer (default: 0) the derivative to be evaluated - - ``rotate`` -- (default: ``False``) If True, this returns the value of the + - ``s`` -- a complex number + - ``derivative`` -- integer (default: 0); the derivative to be evaluated + - ``rotate`` -- boolean (default: ``False``); if True, this returns the value of the Hardy Z-function (sometimes called the Riemann-Siegel Z-function or - the Siegel Z-function). + the Siegel Z-function) EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # This is a quadratic character - sage: L = Lfunction_from_character(chi, type="int") + sage: L = Lfunction_from_character(chi, type='int') sage: (L.value(0.5) - 0.231750947504016).abs() < 1e-8 True sage: v = L.value(0.2 + 0.4*I) sage: (v - (0.102558603193 + 0.190840777924*I)).abs() < 1e-8 True - sage: L = Lfunction_from_character(chi, type="double") + sage: L = Lfunction_from_character(chi, type='double') sage: (L.value(0.6) - 0.274633355856345).abs() < 1e-8 True sage: v = L.value(0.6 + I) @@ -159,7 +159,7 @@ cdef class Lfunction: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] - sage: L = Lfunction_from_character(chi, type="complex") + sage: L = Lfunction_from_character(chi, type='complex') sage: v = L.value(0.5) sage: (v - (0.763747880117 + 0.21696476751*I)).abs() < 1e-8 True @@ -176,7 +176,6 @@ cdef class Lfunction: sage: v = L.value(0.4 + 0.5*I) sage: (v - (-0.450728958517 - 0.780511403019*I)).abs() < 1e-8 True - """ cdef ComplexNumber complexified_s = CCC(s) cdef c_Complex z = new_Complex(mpfr_get_d(complexified_s.__re, MPFR_RNDN), mpfr_get_d(complexified_s.__im, MPFR_RNDN)) @@ -185,7 +184,7 @@ cdef class Lfunction: def hardy_z_function(self, s): """ - Computes the Hardy Z-function of the L-function at s + Compute the Hardy Z-function of the `L`-function at s. INPUT: @@ -195,7 +194,7 @@ cdef class Lfunction: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # Quadratic character - sage: L = Lfunction_from_character(chi, type="int") + sage: L = Lfunction_from_character(chi, type='int') sage: (L.hardy_z_function(0) - 0.231750947504).abs() < 1e-8 True sage: L.hardy_z_function(0.5).imag().abs() < 1e-8 @@ -205,7 +204,7 @@ cdef class Lfunction: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] - sage: L = Lfunction_from_character(chi, type="complex") + sage: L = Lfunction_from_character(chi, type='complex') sage: (L.hardy_z_function(0) - 0.793967590477).abs() < 1e-8 True sage: L.hardy_z_function(0.5).imag().abs() < 1e-8 @@ -218,7 +217,6 @@ cdef class Lfunction: sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000) sage: (L.hardy_z_function(2.1) - (-0.006431791768)).abs() < 1e-8 True - """ #This takes s -> .5 + I*s cdef ComplexNumber complexified_s = CCC(0.5)+ CCC(0,1)*CCC(s) @@ -228,14 +226,14 @@ cdef class Lfunction: def compute_rank(self): """ - Computes the analytic rank (the order of vanishing at the center) of - of the L-function + Compute the analytic rank (the order of vanishing at the center) of + of the `L`-function. EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # This is a quadratic character - sage: L = Lfunction_from_character(chi, type="int") + sage: L = Lfunction_from_character(chi, type='int') sage: L.compute_rank() 0 @@ -246,7 +244,6 @@ cdef class Lfunction: sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000) sage: L.compute_rank() 3 - """ return self._compute_rank() @@ -260,7 +257,7 @@ cdef class Lfunction: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character - sage: L=Lfunction_from_character(chi, type="complex") + sage: L=Lfunction_from_character(chi, type='complex') sage: L._N(10) # abs tol 1e-8 4.0 """ @@ -273,9 +270,9 @@ cdef class Lfunction: """ Finds zeros on critical line between ``T1`` and ``T2`` using step size of stepsize. This function might miss zeros if step size is too - large. This function computes the zeros of the L-function by using + large. This function computes the zeros of the `L`-function by using change in signs of areal valued function whose zeros coincide with - the zeros of L-function. + the zeros of `L`-function. Use :meth:`find_zeros_via_N` for slower but more rigorous computation. @@ -285,18 +282,16 @@ cdef class Lfunction: - ``T2`` -- a real number giving the upper bound - ``stepsize`` -- step size to be used for the zero search - OUTPUT: - - list -- A list of the imaginary parts of the zeros which were found. + OUTPUT: list of the imaginary parts of the zeros which were found EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # This is a quadratic character - sage: L = Lfunction_from_character(chi, type="int") + sage: L = Lfunction_from_character(chi, type='int') sage: L.find_zeros(5,15,.1) [6.64845334472..., 9.83144443288..., 11.9588456260...] - sage: L = Lfunction_from_character(chi, type="double") + sage: L = Lfunction_from_character(chi, type='double') sage: L.find_zeros(1,15,.1) [6.64845334472..., 9.83144443288..., 11.9588456260...] @@ -304,7 +299,7 @@ cdef class Lfunction: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] - sage: L = Lfunction_from_character(chi, type="complex") + sage: L = Lfunction_from_character(chi, type='complex') sage: L.find_zeros(-8,8,.1) [-4.13290370521..., 6.18357819545...] @@ -338,7 +333,7 @@ cdef class Lfunction: their imaginary parts. This function verifies that no zeros are missed, and that all values output are indeed zeros. - If this L-function is self-dual (if its Dirichlet coefficients + If this `L`-function is self-dual (if its Dirichlet coefficients are real, up to a tolerance of 1e-6), then only the zeros with positive imaginary parts are output. Their conjugates, which are also zeros, are not output. @@ -351,22 +346,20 @@ cdef class Lfunction: size used to find zeros is refined. max_refine gives an upper limit on when lcalc should give up. Use default value unless you know what you are doing. - - ``rank`` -- integer (default: -1) analytic rank of the L-function. + - ``rank`` -- integer (default: -1); analytic rank of the `L`-function. If -1 is passed, then we attempt to compute it. (Use default if in doubt) - OUTPUT: - - list -- A list of the imaginary parts of the zeros that have been found + OUTPUT: list of the imaginary parts of the zeros that have been found EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character - sage: L = Lfunction_from_character(chi, type="int") + sage: L = Lfunction_from_character(chi, type='int') sage: L.find_zeros_via_N(3) [6.64845334472..., 9.83144443288..., 11.9588456260...] - sage: L = Lfunction_from_character(chi, type="double") + sage: L = Lfunction_from_character(chi, type='double') sage: L.find_zeros_via_N(3) [6.64845334472..., 9.83144443288..., 11.9588456260...] @@ -374,7 +367,7 @@ cdef class Lfunction: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] - sage: L = Lfunction_from_character(chi, type="complex") + sage: L = Lfunction_from_character(chi, type='complex') sage: zeros = L.find_zeros_via_N(3) sage: (zeros[0] - (-4.13290370521286)).abs() < 1e-8 True @@ -389,7 +382,6 @@ cdef class Lfunction: sage: L = Lfunction_Zeta() sage: L.find_zeros_via_N(3) [14.1347251417..., 21.0220396387..., 25.0108575801...] - """ # This is the default value for message_stamp, but we have to @@ -406,7 +398,7 @@ cdef class Lfunction: result.clear() return returnvalue - # Needs to be overriden + # Needs to be overridden cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept: raise NotImplementedError @@ -434,8 +426,8 @@ cdef class Lfunction: cdef class Lfunction_I(Lfunction): r""" - The ``Lfunction_I`` class is used to represent L-functions - with integer Dirichlet Coefficients. We assume that L-functions + The ``Lfunction_I`` class is used to represent `L`-functions + with integer Dirichlet Coefficients. We assume that `L`-functions satisfy the following functional equation. .. MATH:: @@ -452,43 +444,43 @@ cdef class Lfunction_I(Lfunction): INPUT: - - ``what_type_L`` -- integer, this should be set to 1 if the coefficients - are periodic and 0 otherwise. + - ``what_type_L`` -- integer; this should be set to 1 if the coefficients + are periodic and 0 otherwise - - ``dirichlet_coefficient`` -- List of Dirichlet coefficients of the - L-function. Only first `M` coefficients are needed if they are periodic. + - ``dirichlet_coefficient`` -- list of Dirichlet coefficients of the + `L`-function. Only first `M` coefficients are needed if they are periodic. - - ``period`` -- If the coefficients are periodic, this should be the - period of the coefficients. + - ``period`` -- if the coefficients are periodic, this should be the + period of the coefficients - - ``Q`` -- See above + - ``Q`` -- see above - - ``OMEGA`` -- See above + - ``OMEGA`` -- see above - - ``kappa`` -- List of the values of `\kappa_j` in the functional equation + - ``kappa`` -- list of the values of `\kappa_j` in the functional equation - - ``gamma`` -- List of the values of `\gamma_j` in the functional equation + - ``gamma`` -- list of the values of `\gamma_j` in the functional equation - - ``pole`` -- List of the poles of L-function + - ``pole`` -- list of the poles of `L`-function - - ``residue`` -- List of the residues of the L-function + - ``residue`` -- list of the residues of the `L`-function .. NOTE:: - If an L-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, + If an `L`-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, by replacing `s` by `s+(k-1)/2`, one can get it in the form we need. """ def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma, lambd, pole, residue): r""" - Initialize an L-function with integer coefficients + Initialize an `L`-function with integer coefficients. EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character - sage: L=Lfunction_from_character(chi, type="int") + sage: L=Lfunction_from_character(chi, type='int') sage: type(L) """ @@ -499,7 +491,7 @@ cdef class Lfunction_I(Lfunction): cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept: cdef int N = len(dirichlet_coeff) cdef Integer tmpi - cdef int * coeffs = new_ints(N+1) #lcalc ignores 0the coefficient + cdef int * coeffs = new_ints(N+1) # lcalc ignores 0th coefficient for i from 0 <= i< N by 1: tmpi=Integer(dirichlet_coeff[i]) coeffs[i+1] = mpz_get_si(tmpi.value) @@ -534,7 +526,7 @@ cdef class Lfunction_I(Lfunction): sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character - sage: L=Lfunction_from_character(chi, type="int") + sage: L=Lfunction_from_character(chi, type='int') sage: L._print_data_to_standard_output() # tol 1e-8 ----------------------------------------------- @@ -566,13 +558,13 @@ cdef class Lfunction_I(Lfunction): del_c_Lfunction_I((self.thisptr)) ############################################################################## -# Lfunction_D: L-functions with double (real) Dirichlet Coefficients +# Lfunction_D: `L`-functions with double (real) Dirichlet Coefficients ############################################################################## cdef class Lfunction_D(Lfunction): r""" - The ``Lfunction_D`` class is used to represent L-functions - with real Dirichlet coefficients. We assume that L-functions + The ``Lfunction_D`` class is used to represent `L`-functions + with real Dirichlet coefficients. We assume that `L`-functions satisfy the following functional equation. .. MATH:: @@ -589,42 +581,42 @@ cdef class Lfunction_D(Lfunction): INPUT: - - ``what_type_L`` -- integer, this should be set to 1 if the coefficients are - periodic and 0 otherwise. + - ``what_type_L`` -- integer; this should be set to 1 if the coefficients are + periodic and 0 otherwise - - ``dirichlet_coefficient`` -- List of Dirichlet coefficients of the - L-function. Only first `M` coefficients are needed if they are periodic. + - ``dirichlet_coefficient`` -- list of Dirichlet coefficients of the + `L`-function. Only first `M` coefficients are needed if they are periodic. - - ``period`` -- If the coefficients are periodic, this should be the - period of the coefficients. + - ``period`` -- if the coefficients are periodic, this should be the + period of the coefficients - - ``Q`` -- See above + - ``Q`` -- see above - - ``OMEGA`` -- See above + - ``OMEGA`` -- see above - - ``kappa`` -- List of the values of `\kappa_j` in the functional equation + - ``kappa`` -- list of the values of `\kappa_j` in the functional equation - - ``gamma`` -- List of the values of `\gamma_j` in the functional equation + - ``gamma`` -- list of the values of `\gamma_j` in the functional equation - - ``pole`` -- List of the poles of L-function + - ``pole`` -- list of the poles of `L`-function - - ``residue`` -- List of the residues of the L-function + - ``residue`` -- list of the residues of the `L`-function .. NOTE:: - If an L-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, + If an `L`-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, by replacing `s` by `s+(k-1)/2`, one can get it in the form we need. """ def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma, lambd, pole, residue): r""" - Initialize an L-function with real coefficients + Initialize an `L`-function with real coefficients. EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character - sage: L=Lfunction_from_character(chi, type="double") + sage: L=Lfunction_from_character(chi, type='double') sage: type(L) """ @@ -636,9 +628,9 @@ cdef class Lfunction_D(Lfunction): cdef int i cdef RealNumber tmpr cdef int N = len(dirichlet_coeff) - cdef double * coeffs = new_doubles(N+1)#lcalc ignores 0th position - for i from 0 <= i< N by 1: - tmpr=RRR(dirichlet_coeff[i]) + cdef double * coeffs = new_doubles(N+1) # lcalc ignores 0th position + for i in range(N): + tmpr = RRR(dirichlet_coeff[i]) coeffs[i+1] = mpfr_get_d(tmpr.value, MPFR_RNDN) self.thisptr=new_c_Lfunction_D(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r) del_doubles(coeffs) @@ -671,7 +663,7 @@ cdef class Lfunction_D(Lfunction): sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character - sage: L=Lfunction_from_character(chi, type="double") + sage: L=Lfunction_from_character(chi, type='double') sage: L._print_data_to_standard_output() # tol 1e-8 ----------------------------------------------- @@ -693,7 +685,6 @@ cdef class Lfunction_D(Lfunction): number of poles (of the completed L function) = 0 ----------------------------------------------- - """ (self.thisptr).print_data_L() @@ -709,8 +700,8 @@ cdef class Lfunction_D(Lfunction): cdef class Lfunction_C: r""" - The ``Lfunction_C`` class is used to represent L-functions - with complex Dirichlet Coefficients. We assume that L-functions + The ``Lfunction_C`` class is used to represent `L`-functions + with complex Dirichlet Coefficients. We assume that `L`-functions satisfy the following functional equation. .. MATH:: @@ -727,43 +718,43 @@ cdef class Lfunction_C: INPUT: - - ``what_type_L`` -- integer, this should be set to 1 if the coefficients are - periodic and 0 otherwise. + - ``what_type_L`` -- integer; this should be set to 1 if the coefficients are + periodic and 0 otherwise - - ``dirichlet_coefficient`` -- List of Dirichlet coefficients of the - L-function. Only first `M` coefficients are needed if they are periodic. + - ``dirichlet_coefficient`` -- list of Dirichlet coefficients of the + `L`-function. Only first `M` coefficients are needed if they are periodic. - - ``period`` -- If the coefficients are periodic, this should be the - period of the coefficients. + - ``period`` -- if the coefficients are periodic, this should be the + period of the coefficients - - ``Q`` -- See above + - ``Q`` -- see above - - ``OMEGA`` -- See above + - ``OMEGA`` -- see above - - ``kappa`` -- List of the values of `\kappa_j` in the functional equation + - ``kappa`` -- list of the values of `\kappa_j` in the functional equation - - ``gamma`` -- List of the values of `\gamma_j` in the functional equation + - ``gamma`` -- list of the values of `\gamma_j` in the functional equation - - ``pole`` -- List of the poles of L-function + - ``pole`` -- list of the poles of `L`-function - - ``residue`` -- List of the residues of the L-function + - ``residue`` -- list of the residues of the `L`-function .. NOTE:: - If an L-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, + If an `L`-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, by replacing `s` by `s+(k-1)/2`, one can get it in the form we need. """ def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma, lambd, pole, residue): r""" - Initialize an L-function with complex coefficients + Initialize an `L`-function with complex coefficients. EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] - sage: L=Lfunction_from_character(chi, type="complex") + sage: L=Lfunction_from_character(chi, type='complex') sage: type(L) """ @@ -814,7 +805,7 @@ cdef class Lfunction_C: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] - sage: L=Lfunction_from_character(chi, type="complex") + sage: L=Lfunction_from_character(chi, type='complex') sage: L._print_data_to_standard_output() # tol 1e-8 ----------------------------------------------- @@ -836,8 +827,6 @@ cdef class Lfunction_C: number of poles (of the completed L function) = 0 ----------------------------------------------- - - """ (self.thisptr).print_data_L() @@ -898,35 +887,32 @@ cdef class Lfunction_Zeta(Lfunction): # Tools ############################################################################## -def Lfunction_from_character(chi, type="complex"): +def Lfunction_from_character(chi, type='complex'): """ Given a primitive Dirichlet character, this function returns - an lcalc L-function object for the L-function of the character. + an lcalc `L`-function object for the `L`-function of the character. INPUT: - - ``chi`` -- A Dirichlet character - - ``use_type`` -- string (default: "complex") type used for the Dirichlet - coefficients. This can be "int", "double" or "complex". + - ``chi`` -- a Dirichlet character + - ``use_type`` -- string (default: ``'complex'``); type used for the Dirichlet + coefficients. This can be ``'int'``, ``'double'`` or ``'complex'``. - OUTPUT: - - L-function object for ``chi``. + OUTPUT: `L`-function object for ``chi`` EXAMPLES:: sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_character sage: Lfunction_from_character(DirichletGroup(5)[1]) L-function with complex Dirichlet coefficients - sage: Lfunction_from_character(DirichletGroup(5)[2], type="int") + sage: Lfunction_from_character(DirichletGroup(5)[2], type='int') L-function with integer Dirichlet coefficients - sage: Lfunction_from_character(DirichletGroup(5)[2], type="double") + sage: Lfunction_from_character(DirichletGroup(5)[2], type='double') L-function with real Dirichlet coefficients - sage: Lfunction_from_character(DirichletGroup(5)[1], type="int") + sage: Lfunction_from_character(DirichletGroup(5)[1], type='int') Traceback (most recent call last): ... ValueError: For non quadratic characters you must use type="complex" - """ if (not chi.is_primitive()): raise TypeError("Dirichlet character is not primitive") @@ -960,20 +946,18 @@ def Lfunction_from_character(chi, type="complex"): def Lfunction_from_elliptic_curve(E, number_of_coeffs=10000): """ - Given an elliptic curve E, return an L-function object for + Given an elliptic curve E, return an `L`-function object for the function `L(s, E)`. INPUT: - - ``E`` -- An elliptic curve - - ``number_of_coeffs`` -- integer (default: 10000) The number of - coefficients to be used when constructing the L-function object. Right + - ``E`` -- an elliptic curve + - ``number_of_coeffs`` -- integer (default: 10000); the number of + coefficients to be used when constructing the `L`-function object. Right now this is fixed at object creation time, and is not automatically set intelligently. - OUTPUT: - - L-function object for ``L(s, E)``. + OUTPUT: `L`-function object for ``L(s, E)`` EXAMPLES:: diff --git a/src/sage/libs/lcalc/meson.build b/src/sage/libs/lcalc/meson.build new file mode 100644 index 00000000000..aa6d9296948 --- /dev/null +++ b/src/sage/libs/lcalc/meson.build @@ -0,0 +1,23 @@ +lcalc = dependency('lcalc', version: '>= 2.0.0') + +py.install_sources( + '__init__.py', + 'lcalc_Lfunction.pxd', + 'lcalc_sage.h', + subdir: 'sage/libs/lcalc', +) + +extension_data_cpp = {'lcalc_Lfunction': files('lcalc_Lfunction.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/lcalc', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cypari2, cysignals, gmp, lcalc, m, mpfr, ntl], + ) +endforeach + diff --git a/src/sage/libs/libecm.pyx b/src/sage/libs/libecm.pyx index a3b457d2e31..9d53d7284d4 100644 --- a/src/sage/libs/libecm.pyx +++ b/src/sage/libs/libecm.pyx @@ -73,12 +73,13 @@ def ecmfactor(number, double B1, verbose=False, sigma=0): - ``B1`` -- bound for step 1 of ECM - - ``verbose`` (default: ``False``) -- print some debugging information + - ``verbose`` -- boolean (default: ``False``); print some debugging + information OUTPUT: Either ``(False, None)`` if no factor was found, or ``(True, f)`` - if the factor ``f`` was found. + if the factor `f` was found. EXAMPLES:: @@ -150,11 +151,13 @@ def ecmfactor(number, double B1, verbose=False, sigma=0): Some special cases:: sage: ecmfactor(1, 100) - (True, 1, ...) + Traceback (most recent call last): + ... + ValueError: Input number (1) must be greater than 1 sage: ecmfactor(0, 100) Traceback (most recent call last): ... - ValueError: Input number (0) must be positive + ValueError: Input number (0) must be greater than 1 """ cdef mpz_t n, f cdef int res @@ -165,8 +168,8 @@ def ecmfactor(number, double B1, verbose=False, sigma=0): sage_int_number = Integer(number) sage_int_sigma = Integer(sigma) - if number <= 0: - raise ValueError("Input number (%s) must be positive"%number) + if number <= 1: + raise ValueError("Input number (%s) must be greater than 1"%number) if verbose: print("Performing one curve with B1=%1.0f" % B1) diff --git a/src/sage/libs/linbox/conversion.pxd b/src/sage/libs/linbox/conversion.pxd index a443431adbb..9ca94ce79fd 100644 --- a/src/sage/libs/linbox/conversion.pxd +++ b/src/sage/libs/linbox/conversion.pxd @@ -83,8 +83,8 @@ cdef inline void set_linbox_matrix_modn_sparse(SparseMatrix_Modular_uint64& A, M INPUT: - - A -- LinBox matrix - - m -- Sage matrix + - ``A`` -- LinBox matrix + - ``m`` -- Sage matrix """ cdef c_vector_modint * row cdef size_t i, j @@ -101,8 +101,8 @@ cdef inline SparseMatrix_Modular_uint64 * new_linbox_matrix_modn_sparse(Modular_ INPUT: - - F -- LinBox field - - m -- Sage matrix + - ``F`` -- LinBox field + - ``m`` -- Sage matrix """ cdef SparseMatrix_Modular_uint64 * A = new SparseMatrix_Modular_uint64(F, m._nrows, m._ncols) set_linbox_matrix_modn_sparse(A[0], m) @@ -118,8 +118,8 @@ cdef inline void set_linbox_matrix_integer_sparse(SparseMatrix_integer& A, Matri INPUT: - - A -- LinBox matrix - - m -- Sage matrix + - ``A`` -- LinBox matrix + - ``m`` -- Sage matrix """ cdef size_t i, j, k cdef mpz_vector * v @@ -139,7 +139,7 @@ cdef inline SparseMatrix_integer * new_linbox_matrix_integer_sparse(ZRing &ZZ, M INPUT: - - m -- Sage matrix + - ``m`` -- Sage matrix """ cdef SparseMatrix_integer * A = new SparseMatrix_integer(ZZ, m._nrows, m._ncols) set_linbox_matrix_integer_sparse(A[0], m) @@ -155,7 +155,7 @@ cdef inline DenseVector_integer * new_linbox_vector_integer_dense(ZRing &ZZ, Vec INPUT: - - v -- a Sage dense integer vector + - ``v`` -- a Sage dense integer vector """ cdef cppvector[Integer] * vec = new cppvector[Integer]( v._degree) cdef size_t i @@ -173,8 +173,8 @@ cdef inline Vector_integer_dense new_sage_vector_integer_dense(P, DenseVector_in INPUT: - - P -- parent for the Sage vector - - v -- linbox vector + - ``P`` -- parent for the Sage vector + - ``v`` -- linbox vector """ cdef Vector_integer_dense res = P() cdef size_t i diff --git a/src/sage/libs/linbox/fflas.pxd b/src/sage/libs/linbox/fflas.pxd index d5b077cf045..886f5c44cfa 100644 --- a/src/sage/libs/linbox/fflas.pxd +++ b/src/sage/libs/linbox/fflas.pxd @@ -28,7 +28,6 @@ cdef extern from "fflas-ffpack/fflas-ffpack.h" namespace "FFLAS": FflasNoTrans FflasTrans - ctypedef enum FFLAS_SIDE: FflasRight diff --git a/src/sage/libs/linbox/meson.build b/src/sage/libs/linbox/meson.build new file mode 100644 index 00000000000..252a6ae0f9e --- /dev/null +++ b/src/sage/libs/linbox/meson.build @@ -0,0 +1,26 @@ +py.install_sources( + '__init__.py', + 'conversion.pxd', + 'fflas.pxd', + 'givaro.pxd', + 'linbox.pxd', + 'linbox_flint_interface.pxd', + subdir: 'sage/libs/linbox', +) + +extension_data_cpp = { + 'linbox_flint_interface': files('linbox_flint_interface.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/linbox', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_flint], + dependencies: [py_dep, blas, flint, fplll, givaro, gmp, gmpxx, linbox], + ) +endforeach + diff --git a/src/sage/libs/linkages/padics/API.pxi b/src/sage/libs/linkages/padics/API.pxi index ec69c5bbaa3..62e61551e07 100644 --- a/src/sage/libs/linkages/padics/API.pxi +++ b/src/sage/libs/linkages/padics/API.pxi @@ -17,11 +17,11 @@ file gives the function signatures. - :meth:`cadd` -- addition - :meth:`creduce` -- reduce modulo a power of the maximal ideal - :meth:`creduce_small` -- reduce modulo a power of the maximal ideal, - assuming only a single addition/subtraction. + assuming only a single addition/subtraction - :meth:`cremove` -- extract the maximum power of the uniformizer - dividing this element. + dividing this element - :meth:`cvaluation` -- return the maximum power of the uniformizer - dividing this element. + dividing this element - :meth:`cisunit` -- returns whether this element has valuation zero - :meth:`cshift` -- multiplies by a power of the uniformizer - :meth:`cshift_notrunc` -- multiplies by a power of the uniformizer, @@ -42,7 +42,7 @@ file gives the function signatures. - :meth:`chash` -- hashing - :meth:`cexpansion_next` -- gets the next digit in the series expansion - :meth:`cexpansion_getitem` -- gets a specified digit in the series expansion -- :meth:`ccoefficients` -- a list of coefficients as elements of the base ring +- :meth:`ccoefficients` -- list of coefficients as elements of the base ring - :meth:`cteichmuller` -- Teichmuller lifting - :meth:`cconv` -- conversion from other types in Sage - :meth:`cconv_mpz_t` -- conversion from mpz_t, separated for speed and @@ -83,8 +83,8 @@ cdef inline int cconstruct(celement value, PowComputer_class prime_pow) except - INPUT: - - ``unit`` -- an ``celement`` to be initialized. - - ``prime_pow`` -- the PowComputer for the ring. + - ``unit`` -- an ``celement`` to be initialized + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -94,8 +94,8 @@ cdef inline int cdestruct(celement value, PowComputer_class prime_pow) except -1 INPUT: - - ``unit`` -- an ``celement`` to be cleared. - - ``prime_pow`` -- the PowComputer for the ring. + - ``unit`` -- an ``celement`` to be cleared + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -105,12 +105,12 @@ cdef inline int ccmp(celement a, celement b, long prec, bint reduce_a, bint redu INPUT: - - ``a`` -- an ``celement``. - - ``b`` -- an ``celement``. - - ``prec`` -- a long, the precision of the comparison. - - ``reduce_a`` -- a bint, whether ``a`` needs to be reduced. - - ``reduce_b`` -- a bint, whether ``b`` needs to be reduced. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- an ``celement`` + - ``b`` -- an ``celement`` + - ``prec`` -- a long, the precision of the comparison + - ``reduce_a`` -- a bint, whether ``a`` needs to be reduced + - ``reduce_b`` -- a bint, whether ``b`` needs to be reduced + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: @@ -130,10 +130,10 @@ cdef inline int cneg(celement out, celement a, long prec, PowComputer_class prim INPUT: - - ``out`` -- an ``celement`` to store the negation. - - ``a`` -- an ``celement`` to be negated. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the negation + - ``a`` -- an ``celement`` to be negated + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -145,11 +145,11 @@ cdef inline int cadd(celement out, celement a, celement b, long prec, PowCompute INPUT: - - ``out`` -- an ``celement`` to store the sum. - - ``a`` -- an ``celement``, the first summand. - - ``b`` -- an ``celement``, the second summand. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the sum + - ``a`` -- an ``celement``, the first summand + - ``b`` -- an ``celement``, the second summand + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -159,14 +159,12 @@ cdef inline bint creduce(celement out, celement a, long prec, PowComputer_class INPUT: - - ``out`` -- an ``celement`` to store the reduction. - - ``a`` -- the element to be reduced. - - ``prec`` -- a long, the precision to reduce modulo. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the reduction + - ``a`` -- the element to be reduced + - ``prec`` -- a long, the precision to reduce modulo + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - returns True if the reduction is zero; False otherwise. + OUTPUT: returns ``True`` if the reduction is zero; ``False`` otherwise """ pass @@ -180,14 +178,14 @@ cdef inline bint creduce_small(celement out, celement a, long prec, PowComputer_ INPUT: - - ``out`` -- an ``celement`` to store the reduction. - - ``a`` -- the element to be reduced. - - ``prec`` -- a long, the precision to reduce modulo. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the reduction + - ``a`` -- the element to be reduced + - ``prec`` -- a long, the precision to reduce modulo + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: - - returns True if the reduction is zero; False otherwise. + - returns ``True`` if the reduction is zero; ``False`` otherwise. """ pass @@ -197,10 +195,10 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_class INPUT: - - ``out`` -- an ``celement`` to store the unit. - - ``a`` -- the element whose valuation and unit are desired. - - ``prec`` -- a long, used if `a = 0`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the unit + - ``a`` -- the element whose valuation and unit are desired + - ``prec`` -- a long, used if `a = 0` + - ``prime_pow`` -- the PowComputer for the ring - ``reduce_relative`` -- a bint: whether the final result should be reduced at precision ``prec`` (case ``False``) or ``prec - valuation`` (case ``True``) @@ -214,7 +212,7 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_class cdef inline long cvaluation(celement a, long prec, PowComputer_class prime_pow) except -1: """ - Returns the maximum power of the uniformizer dividing this + Return the maximum power of the uniformizer dividing this element. This function differs from :meth:`cremove` in that the unit is @@ -222,9 +220,9 @@ cdef inline long cvaluation(celement a, long prec, PowComputer_class prime_pow) INPUT: - - ``a`` -- the element whose valuation is desired. - - ``prec`` -- a long, used if `a = 0`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element whose valuation is desired + - ``prec`` -- a long, used if `a = 0` + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: @@ -235,53 +233,51 @@ cdef inline long cvaluation(celement a, long prec, PowComputer_class prime_pow) cdef inline bint cisunit(celement a, PowComputer_class prime_pow) except -1: """ - Returns whether this element has valuation zero. + Return whether this element has valuation zero. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - returns True if `a` has valuation 0, and False otherwise. + OUTPUT: returns ``True`` if `a` has valuation 0, and ``False`` otherwise """ pass cdef inline int cshift(celement out, celement rem, celement a, long n, long prec, PowComputer_class prime_pow, bint reduce_afterward) except -1: """ - Multiplies by a power of the uniformizer. + Multiply by a power of the uniformizer. INPUT: - ``out`` -- an ``celement`` to store the result. If `n >= 0` - then out will be set to `a * p^n`. + then out will be set to `a * p^n` If `n < 0`, out will be set to `a // p^-n`. - ``rem`` -- a ``celement`` to store the remainder, when `n < 0` - - ``a`` -- the element to shift. - - ``n`` -- long, the amount to shift by. - - ``prec`` -- long, a precision modulo which to reduce. - - ``prime_pow`` -- the PowComputer for the ring. - - ``reduce_afterward`` -- whether to reduce afterward. + - ``a`` -- the element to shift + - ``n`` -- long, the amount to shift by + - ``prec`` -- long, a precision modulo which to reduce + - ``prime_pow`` -- the PowComputer for the ring + - ``reduce_afterward`` -- whether to reduce afterward """ pass cdef inline int cshift_notrunc(celement out, celement a, long n, long prec, PowComputer_class prime_pow, bint reduce_afterward) except -1: """ - Multiplies by a power of the uniformizer, assuming that the + Multiply by a power of the uniformizer, assuming that the valuation of a is at least -n. INPUT: - ``out`` -- an ``celement`` to store the result. If `n >= 0` - then out will be set to `a * p^n`. + then out will be set to `a * p^n` If `n < 0`, out will be set to `a // p^-n`. - ``a`` -- the element to shift. Assumes that the valuation of a is at least -n. - - ``n`` -- long, the amount to shift by. - - ``prec`` -- long, a precision modulo which to reduce. - - ``prime_pow`` -- the PowComputer for the ring. - - ``reduce_afterward`` -- whether to reduce afterward. + - ``n`` -- long, the amount to shift by + - ``prec`` -- long, a precision modulo which to reduce + - ``prime_pow`` -- the PowComputer for the ring + - ``reduce_afterward`` -- whether to reduce afterward """ pass @@ -293,11 +289,11 @@ cdef inline int csub(celement out, celement a, celement b, long prec, PowCompute INPUT: - - ``out`` -- an ``celement`` to store the difference. - - ``a`` -- an ``celement``, the first input. - - ``b`` -- an ``celement``, the second input. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the difference + - ``a`` -- an ``celement``, the first input + - ``b`` -- an ``celement``, the second input + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -309,10 +305,10 @@ cdef inline int cinvert(celement out, celement a, long prec, PowComputer_class p INPUT: - - ``out`` -- an ``celement`` to store the inverse. - - ``a`` -- an ``celement``, the element to be inverted. - - ``prec`` -- a long, the precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the inverse + - ``a`` -- an ``celement``, the element to be inverted + - ``prec`` -- a long, the precision + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -324,11 +320,11 @@ cdef inline int cmul(celement out, celement a, celement b, long prec, PowCompute INPUT: - - ``out`` -- an ``celement`` to store the product. - - ``a`` -- an ``celement``, the first input. - - ``b`` -- an ``celement``, the second input. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the product + - ``a`` -- an ``celement``, the first input + - ``b`` -- an ``celement``, the second input + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -341,63 +337,63 @@ cdef inline int cdivunit(celement out, celement a, celement b, long prec, PowCom INPUT: - - ``out`` -- an ``celement`` to store the quotient. - - ``a`` -- an ``celement``, the first input. - - ``b`` -- an ``celement``, the second input. - - ``prec`` -- a long, the precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the quotient + - ``a`` -- an ``celement``, the first input + - ``b`` -- an ``celement``, the second input + - ``prec`` -- a long, the precision + - ``prime_pow`` -- the PowComputer for the ring """ pass cdef inline int csetone(celement out, PowComputer_class prime_pow) except -1: """ - Sets to 1. + Set to 1. INPUT: - - ``out`` -- the ``celement`` in which to store 1. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store 1 + - ``prime_pow`` -- the PowComputer for the ring """ pass cdef inline int csetzero(celement out, PowComputer_class prime_pow) except -1: """ - Sets to 0. + Set to 0. INPUT: - - ``out`` -- the ``celement`` in which to store 0. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store 0 + - ``prime_pow`` -- the PowComputer for the ring """ pass cdef inline bint cisone(celement a, PowComputer_class prime_pow) except -1: """ - Returns whether this element is equal to 1. + Return whether this element is equal to 1. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: - - returns True if `a = 1`, and False otherwise. + - returns ``True`` if `a = 1`, and ``False`` otherwise. """ pass cdef inline bint ciszero(celement a, PowComputer_class prime_pow) except -1: """ - Returns whether this element is equal to 0. + Return whether this element is equal to 0. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: - - returns True if `a = 0`, and False otherwise. + - returns ``True`` if `a = 0`, and ``False`` otherwise. """ pass @@ -407,11 +403,11 @@ cdef inline int cpow(celement out, celement a, mpz_t n, long prec, PowComputer_c INPUT: - - ``out`` -- the ``celement`` in which to store the result. - - ``a`` -- the base. - - ``n`` -- an ``mpz_t``, the exponent. - - ``prec`` -- a long, the working absolute precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store the result + - ``a`` -- the base + - ``n`` -- an ``mpz_t``, the exponent + - ``prec`` -- a long, the working absolute precision + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -421,9 +417,9 @@ cdef inline int ccopy(celement out, celement a, PowComputer_class prime_pow) exc INPUT: - - ``out`` -- the ``celement`` to store the result. - - ``a`` -- the element to copy. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` to store the result + - ``a`` -- the element to copy + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -433,8 +429,8 @@ cdef inline cpickle(celement a, PowComputer_class prime_pow): INPUT: - - ``a`` the element to pickle. - - ``prime_pow`` the PowComputer for the ring. + - ``a`` -- the element to pickle + - ``prime_pow`` the PowComputer for the ring OUTPUT: @@ -448,9 +444,9 @@ cdef inline int cunpickle(celement out, x, PowComputer_class prime_pow) except - INPUT: - - ``out`` -- the ``celement`` in which to store the result. - - ``x`` -- the result of :meth:`cpickle`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store the result + - ``x`` -- the result of :meth:`cpickle` + - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -460,10 +456,10 @@ cdef inline long chash(celement a, long ordp, long prec, PowComputer_class prime INPUT: - - ``a`` -- an ``celement`` storing the underlying element to hash. - - ``ordp`` -- a long storing the valuation. - - ``prec`` -- a long storing the precision. - - ``prime_pow`` -- a PowComputer for the ring. + - ``a`` -- an ``celement`` storing the underlying element to hash + - ``ordp`` -- a long storing the valuation + - ``prec`` -- a long storing the precision + - ``prime_pow`` -- a PowComputer for the ring """ pass @@ -474,23 +470,23 @@ cdef inline cexpansion_next(celement value, expansion_mode mode, long curpower, INPUT: - - ``value`` -- the `\pi`-adic element whose expansion is desired. + - ``value`` -- the `\pi`-adic element whose expansion is desired - ``mode`` -- either ``simple_mode`` or ``smallest_mode`` - ``curpower`` -- the current power of `\pi` for which the coefficient - is being found. Only used in ``smallest_mode``. - - ``prime_pow`` -- A ``PowComputer`` holding `\pi`-adic data. + is being found. Only used in ``smallest_mode`` + - ``prime_pow`` -- a ``PowComputer`` holding `\pi`-adic data """ pass cdef inline cexpansion_getitem(celement value, long m, PowComputer_ prime_pow): r""" - Return the `m`th `\pi`-adic digit in the ``simple_mode`` expansion. + Return the `m`-th `\pi`-adic digit in the ``simple_mode`` expansion. INPUT: - - ``value`` -- the `\pi`-adic element whose expansion is desired. - - ``m`` -- a non-negative integer: which entry in the `\pi`-adic expansion to return. - - ``prime_pow`` -- A ``PowComputer`` holding `\pi`-adic data. + - ``value`` -- the `\pi`-adic element whose expansion is desired + - ``m`` -- nonnegative integer: which entry in the `\pi`-adic expansion to return + - ``prime_pow`` -- a ``PowComputer`` holding `\pi`-adic data """ pass @@ -504,8 +500,8 @@ cdef list ccoefficients(celement x, long valshift, PowComputer_class prime_pow): INPUT: - - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part. - - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by. + - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part + - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by - ``prec`` -- a long, the (relative) precision desired, used in rational reconstruction - ``prime_pow`` -- the ``PowComputer`` of the ring """ @@ -518,11 +514,10 @@ cdef int cteichmuller(celement out, celement value, long prec, PowComputer_class INPUT: - ``out`` -- an ``celement`` which is set to a `q-1` root of unity - congruent to `value` mod `\pi`; or 0 if `a \equiv 0 - \pmod{\pi}`. - - ``value`` -- an ``celement``, the element mod `\pi` to lift. - - ``prec`` -- a long, the precision to which to lift. - - ``prime_pow`` -- the ``PowComputer`` of the ring. + congruent to `value` mod `\pi`; or 0 if `a \equiv 0 \pmod{\pi}` + - ``value`` -- an ``celement``, the element mod `\pi` to lift + - ``prec`` -- a long, the precision to which to lift + - ``prime_pow`` -- the ``PowComputer`` of the ring """ pass @@ -532,13 +527,13 @@ cdef int cconv(celement out, x, long prec, long valshift, PowComputer_class prim INPUT: - - ``out`` -- an ``celement`` to store the output. - - ``x`` -- a Sage element that can be converted to a `p`-adic element. + - ``out`` -- an ``celement`` to store the output + - ``x`` -- a Sage element that can be converted to a `p`-adic element - ``prec`` -- a long, giving the precision desired: absolute if - `valshift = 0`, relative if `valshift > 0`. + `valshift = 0`, relative if `valshift > 0` - ``valshift`` -- the power of the uniformizer to divide by before - storing the result in ``out``. - - ``prime_pow`` -- a PowComputer for the ring. + storing the result in ``out`` + - ``prime_pow`` -- a PowComputer for the ring """ pass @@ -549,14 +544,14 @@ cdef inline long cconv_mpz_t(celement out, mpz_t x, long prec, bint absolute, Po INPUT: - - ``out`` -- an ``celement`` to store the output. - - ``x`` -- an ``mpz_t`` giving the integer to be converted. + - ``out`` -- an ``celement`` to store the output + - ``x`` -- an ``mpz_t`` giving the integer to be converted - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. + relative depending on the ``absolute`` input - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -567,15 +562,15 @@ cdef inline long cconv_mpz_t(celement out, mpz_t x, long prec, bint absolute, Po cdef inline int cconv_mpz_t_out(mpz_t out, celement x, long valshift, long prec, PowComputer_class prime_pow) except -1: """ - Converts the underlying `p`-adic element into an integer if + Convert the underlying `p`-adic element into an integer if possible. - ``out`` -- stores the resulting integer as an integer between 0 - and `p^{prec + valshift}`. - - ``x`` -- an ``celement`` giving the underlying `p`-adic element. - - ``valshift`` -- a long giving the power of `p` to shift `x` by. - -` ``prec`` -- a long, the precision of ``x``: currently not used. - - ``prime_pow`` -- a PowComputer for the ring. + and `p^{prec + valshift}` + - ``x`` -- an ``celement`` giving the underlying `p`-adic element + - ``valshift`` -- a long giving the power of `p` to shift `x` by + -` ``prec`` -- a long, the precision of ``x``: currently not used + - ``prime_pow`` -- a PowComputer for the ring """ pass @@ -586,14 +581,14 @@ cdef inline long cconv_mpq_t(celement out, mpq_t x, long prec, bint absolute, Po INPUT: - - ``out`` -- an ``celement`` to store the output. - - ``x`` -- an ``mpq_t`` giving the rational to be converted. + - ``out`` -- an ``celement`` to store the output + - ``x`` -- an ``mpq_t`` giving the rational to be converted - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. + relative depending on the ``absolute`` input - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -604,16 +599,16 @@ cdef inline long cconv_mpq_t(celement out, mpq_t x, long prec, bint absolute, Po cdef inline int cconv_mpq_t_out(mpq_t out, celement x, long valshift, long prec, PowComputer_class prime_pow) except -1: """ - Converts the underlying `p`-adic element into a rational. + Convert the underlying `p`-adic element into a rational. - ``out`` -- gives a rational approximating the input. Currently - uses rational reconstruction but may change in the - future to use a more naive method. - - ``x`` -- an ``celement`` giving the underlying `p`-adic element. - - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by. - -` ``prec`` -- a long, the precision of ``x``, used in rational - reconstruction. - - ``prime_pow`` -- a PowComputer for the ring. + uses rational reconstruction but may change in the future to use a more + naive method + - ``x`` -- an ``celement`` giving the underlying `p`-adic element + - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by + - ``prec`` -- a long, the precision of ``x``, used in rational + reconstruction + - ``prime_pow`` -- a PowComputer for the ring """ pass diff --git a/src/sage/libs/linkages/padics/Polynomial_ram.pxi b/src/sage/libs/linkages/padics/Polynomial_ram.pxi index 687b5a5cf15..6863b4156c5 100644 --- a/src/sage/libs/linkages/padics/Polynomial_ram.pxi +++ b/src/sage/libs/linkages/padics/Polynomial_ram.pxi @@ -46,10 +46,7 @@ cdef inline bint creduce(celement out, celement a, long prec, PowComputer_ prime - ``prime_pow`` -- the ``PowComputer`` for the ring - OUTPUT: - - ``True`` if the reduction is zero, ``False`` otherwise - + OUTPUT: ``True`` if the reduction is zero, ``False`` otherwise """ cdef celement ared = a % prime_pow.modulus if ared is a and out is not a: @@ -83,10 +80,7 @@ cdef inline bint creduce_small(celement out, celement a, long prec, PowComputer_ - ``prime_pow`` -- the ``PowComputer`` for the ring - OUTPUT: - - ``True`` if the reduction is zero, ``False`` otherwise - + OUTPUT: ``True`` if the reduction is zero, ``False`` otherwise """ return creduce(out, a, prec, prime_pow) @@ -112,7 +106,6 @@ cdef inline long cvaluation(celement a, long prec, PowComputer_ prime_pow) excep The number of times the uniformizer divides ``a``, or ``prec`` if that is higher. - """ C = a._coeffs if not C: @@ -148,8 +141,7 @@ cdef inline int cshift(celement shifted, celement rem, celement a, long n, long - ``prime_pow`` -- the ``PowComputer`` for the ring - ``reduce_afterward`` -- whether to :meth:`creduce` ``shifted`` before - returning. - + returning """ cdef long v notrunc = False @@ -206,7 +198,7 @@ cdef inline int cshift_notrunc(celement out, celement a, long n, long prec, PowC - ``prime_pow`` -- the ``PowComputer`` for the ring - ``reduce_afterward`` -- whether to :meth:`creduce` ``out`` before - returning. + returning """ cdef long q, r @@ -249,7 +241,6 @@ cdef inline int cinvert(celement out, celement a, long prec, PowComputer_ prime_ - ``prec`` -- a ``long``, ``out`` is reduced to this precision - ``prime_pow`` -- the ``PowComputer`` for the ring - """ out._coeffs = prime_pow.invert(a, prec)._coeffs creduce(out, out, prec, prime_pow) @@ -273,7 +264,6 @@ cdef inline int cdivunit(celement out, celement a, celement b, long prec, PowCom determined - ``prime_pow`` -- the ``PowComputer`` for the ring - """ binv = prime_pow.invert(b, prec) cmul(out, a, binv, prec, prime_pow) @@ -293,7 +283,6 @@ cdef inline int cpow(celement out, celement a, mpz_t n, long prec, PowComputer_ - ``prec`` -- a ``long``, the working absolute precision - ``prime_pow`` -- the ``PowComputer`` for the ring - """ cdef Integer zn = PY_NEW(Integer) mpz_set(zn.value, n) @@ -339,13 +328,13 @@ cdef inline cexpansion_next(celement value, expansion_mode mode, long curpower, cdef inline cexpansion_getitem(celement value, long m, PowComputer_ prime_pow): """ - Return the `m`th `p`-adic digit in the ``simple_mode`` expansion. + Return the `m`-th `p`-adic digit in the ``simple_mode`` expansion. INPUT: - - ``value`` -- the `p`-adic element whose expansion is desired. - - ``m`` -- a non-negative integer: which entry in the `p`-adic expansion to return. - - ``prime_pow`` -- A ``PowComputer`` holding `p`-adic data. + - ``value`` -- the `p`-adic element whose expansion is desired + - ``m`` -- nonnegative integer; which entry in the `p`-adic expansion to return + - ``prime_pow`` -- a ``PowComputer`` holding `p`-adic data """ R = value.base_ring() p = R.prime() @@ -367,14 +356,13 @@ cdef int cteichmuller(celement out, celement value, long prec, PowComputer_ prim INPUT: - ``out`` -- a ``celement`` which is set to a `q-1`-th root of unity - congruent to ``value`` modulo π; or 0 if `a \equiv 0 \pmod{π}`. + congruent to ``value`` modulo π; or 0 if `a \equiv 0 \pmod{π}` - ``value`` -- n ``celement``, the element mod π to lift - ``prec`` -- a ``long``, the precision to which to lift - ``prime_pow`` -- the ``PowComputer`` of the ring - """ if value[0].valuation() > 0: out._coeffs = [] @@ -387,8 +375,8 @@ cdef list ccoefficients(celement x, long valshift, long prec, PowComputer_ prime INPUT: - - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part. - - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by. + - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part + - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by - ``prec`` -- a long, the (relative) precision desired, used in rational reconstruction - ``prime_pow`` -- the Powcomputer of the ring """ diff --git a/src/sage/libs/linkages/padics/Polynomial_shared.pxi b/src/sage/libs/linkages/padics/Polynomial_shared.pxi index b88b928a347..e471ce947ad 100644 --- a/src/sage/libs/linkages/padics/Polynomial_shared.pxi +++ b/src/sage/libs/linkages/padics/Polynomial_shared.pxi @@ -51,7 +51,6 @@ cdef inline int cconstruct(celement value, PowComputer_ prime_pow) except -1: For Polynomial elements, this function calls the ``__init__`` method of ``celement``. When creating ``celement`` instances, we use ``__new__`` which does not call ``__init__``, because of the metaclass that we are using. - """ value.__init__(prime_pow.poly_ring) @@ -69,7 +68,6 @@ cdef inline int cdestruct(celement value, PowComputer_ prime_pow) except -1: This function has no effect for polynomials. There is no manual garbage collection necessary, as ``celement`` is a managed Python type. - """ pass @@ -100,7 +98,6 @@ cdef inline int ccmp(celement a, celement b, long prec, bint reduce_a, bint redu - ``reduce_b`` -- whether ``b`` is already reduced with respect to ``prec`` - ``prime_pow`` -- the ``PowComputer`` for the ring - """ if not (reduce_a or reduce_b): return 0 if a == b else 1 @@ -142,7 +139,6 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_ prime The number of times the uniformizer divides ``a``, or ``prec`` if ``a`` is zero. - """ if a == 0: return prec @@ -162,7 +158,6 @@ cdef inline bint cisunit(celement a, PowComputer_ prime_pow) except -1: - ``a`` -- the ``celement`` to test - ``prime_pow`` -- the ``PowComputer`` for the ring - """ return cvaluation(a, 1, prime_pow) == 0 @@ -181,7 +176,6 @@ cdef inline int cneg(celement out, celement a, long prec, PowComputer_ prime_pow - ``prec`` -- a ``long``, the precision - ``prime_pow`` -- the ``PowComputer`` for the ring - """ cdef celement ma = -a if ma is a: @@ -206,7 +200,6 @@ cdef inline int cadd(celement out, celement a, celement b, long prec, PowCompute - ``prec`` -- a ``long``, the precision - ``prime_pow`` -- the ``PowComputer`` for the ring - """ cdef celement sm = a + b if sm is a or sm is b: @@ -231,7 +224,6 @@ cdef inline int csub(celement out, celement a, celement b, long prec, PowCompute - ``prec`` -- a ``long``, the precision - ``prime_pow`` -- the ``PowComputer`` for the ring - """ cdef celement df = a - b if df is a or df is b: @@ -256,7 +248,6 @@ cdef inline int cmul(celement out, celement a, celement b, long prec, PowCompute - ``prec`` -- a ``long``, the precision - ``prime_pow`` -- the ``PowComputer`` for the ring - """ cdef celement pd = a*b if pd is a or pd is b: @@ -273,7 +264,6 @@ cdef inline int csetone(celement out, PowComputer_ prime_pow) except -1: - ``out`` -- the ``celement`` in which to store 1 - ``prime_pow`` -- the ``PowComputer`` for the ring - """ out._coeffs = [prime_pow.base_ring(1)] @@ -286,7 +276,6 @@ cdef inline int csetzero(celement out, PowComputer_ prime_pow) except -1: - ``out`` -- the ``celement`` in which to store 0 - ``prime_pow`` -- the ``PowComputer`` for the ring - """ out._coeffs = [] @@ -299,7 +288,6 @@ cdef inline bint cisone(celement a, PowComputer_ prime_pow) except -1: - ``a`` -- the element to test - ``prime_pow`` -- the ``PowComputer`` for the ring - """ return a.is_one() @@ -312,7 +300,6 @@ cdef inline bint ciszero(celement a, PowComputer_ prime_pow) except -1: - ``a`` -- the element to test - ``prime_pow`` -- the ``PowComputer`` for the ring - """ return a.is_zero() @@ -327,7 +314,6 @@ cdef inline int ccopy(celement out, celement a, PowComputer_ prime_pow) except - - ``a`` -- the element from which to copy - ``prime_pow`` -- the ``PowComputer`` for the ring - """ out._coeffs = a._coeffs[:] @@ -337,10 +323,9 @@ cdef inline cpickle(celement a, PowComputer_ prime_pow): INPUT: - - ``a`` the element to pickle - - - ``prime_pow`` the ``PowComputer`` for the ring + - ``a`` -- the element to pickle + - ``prime_pow`` -- the ``PowComputer`` for the ring """ return a._coeffs @@ -355,7 +340,6 @@ cdef inline int cunpickle(celement out, x, PowComputer_ prime_pow) except -1: - ``x`` -- the result of `meth`:cpickle - ``prime_pow`` -- the ``PowComputer`` for the ring - """ out._coeffs = x @@ -372,7 +356,6 @@ cdef inline long chash(celement a, long ordp, long prec, PowComputer_ prime_pow) - ``prec`` -- the precision as a ``long`` - ``prime_pow`` -- the ``PowComputer`` for the ring - """ if ciszero(a, prime_pow): return 0 @@ -396,7 +379,6 @@ cdef int cconv(celement out, x, long prec, long valshift, PowComputer_ prime_pow the result in ``out`` - ``prime_pow`` -- a ``PowComputer`` for the ring - """ cdef celement xx, shift if valshift < 0: @@ -449,7 +431,6 @@ cdef inline long cconv_mpz_t(celement out, mpz_t x, long prec, bint absolute, Po If ``absolute`` is ``False``, the valuation that was extracted (``maxordp`` when `x = 0`). - """ cdef long valuation = maxordp @@ -482,7 +463,6 @@ cdef inline int cconv_mpz_t_out(mpz_t out, celement x, long valshift, long prec, -` ``prec`` -- a ``long``, the precision of ``x`` and ``out`` - ``prime_pow`` -- a ``PowComputer`` for the ring - """ cdef Integer n @@ -527,7 +507,6 @@ cdef inline long cconv_mpq_t(celement out, mpq_t x, long prec, bint absolute, Po If ``absolute`` is ``False``, the valuation that was extracted (``maxordp`` when `x = 0`) - """ cdef Rational r = PY_NEW(Rational) mpq_set(r.value, x) @@ -555,7 +534,6 @@ cdef inline int cconv_mpq_t_out(mpq_t out, celement x, long valshift, long prec, - ``prec`` -- a long, the precision of ``x``; ignored - ``prime_pow`` -- a ``PowComputer`` for the ring - """ cdef Rational c diff --git a/src/sage/libs/linkages/padics/fmpz_poly_unram.pxi b/src/sage/libs/linkages/padics/fmpz_poly_unram.pxi index fcacaa024d9..69cde5e4074 100644 --- a/src/sage/libs/linkages/padics/fmpz_poly_unram.pxi +++ b/src/sage/libs/linkages/padics/fmpz_poly_unram.pxi @@ -42,8 +42,8 @@ cdef inline int cconstruct(celement value, PowComputer_ prime_pow) except -1: INPUT: - - ``unit`` -- an ``celement`` to be initialized. - - ``prime_pow`` -- the PowComputer for the ring. + - ``unit`` -- an ``celement`` to be initialized + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_init(value) @@ -53,8 +53,8 @@ cdef inline int cdestruct(celement value, PowComputer_ prime_pow) except -1: INPUT: - - ``unit`` -- an ``celement`` to be cleared. - - ``prime_pow`` -- the PowComputer for the ring. + - ``unit`` -- an ``celement`` to be cleared + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_clear(value) @@ -64,12 +64,12 @@ cdef inline int ccmp(celement a, celement b, long prec, bint reduce_a, bint redu INPUT: - - ``a`` -- an ``celement``. - - ``b`` -- an ``celement``. - - ``prec`` -- a long, the precision of the comparison. - - ``reduce_a`` -- a bint, whether ``a`` needs to be reduced. - - ``reduce_b`` -- a bint, whether ``b`` needs to be reduced. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- an ``celement`` + - ``b`` -- an ``celement`` + - ``prec`` -- a long, the precision of the comparison + - ``reduce_a`` -- a bint, whether ``a`` needs to be reduced + - ``reduce_b`` -- a bint, whether ``b`` needs to be reduced + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: @@ -117,10 +117,10 @@ cdef inline int cneg(celement out, celement a, long prec, PowComputer_ prime_pow INPUT: - - ``out`` -- an ``celement`` to store the negation. - - ``a`` -- an ``celement`` to be negated. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the negation + - ``a`` -- an ``celement`` to be negated + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_neg(out, a) @@ -132,11 +132,11 @@ cdef inline int cadd(celement out, celement a, celement b, long prec, PowCompute INPUT: - - ``out`` -- an ``celement`` to store the sum. - - ``a`` -- an ``celement``, the first summand. - - ``b`` -- an ``celement``, the second summand. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the sum + - ``a`` -- an ``celement``, the first summand + - ``b`` -- an ``celement``, the second summand + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_add(out, a, b) @@ -146,14 +146,12 @@ cdef inline bint creduce(celement out, celement a, long prec, PowComputer_ prime INPUT: - - ``out`` -- an ``celement`` to store the reduction. - - ``a`` -- the element to be reduced. - - ``prec`` -- a long, the precision to reduce modulo. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the reduction + - ``a`` -- the element to be reduced + - ``prec`` -- a long, the precision to reduce modulo + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - returns True if the reduction is zero; False otherwise. + OUTPUT: ``True`` if the reduction is zero; ``False`` otherwise """ if prec == 0: csetzero(out, prime_pow) @@ -174,14 +172,12 @@ cdef inline bint creduce_small(celement out, celement a, long prec, PowComputer_ INPUT: - - ``out`` -- an ``celement`` to store the reduction. - - ``a`` -- the element to be reduced. - - ``prec`` -- a long, the precision to reduce modulo. - - ``prime_pow`` -- the PowComputer for the ring. - - OUTPUT: + - ``out`` -- an ``celement`` to store the reduction + - ``a`` -- the element to be reduced + - ``prec`` -- a long, the precision to reduce modulo + - ``prime_pow`` -- the PowComputer for the ring - - returns True if the reduction is zero; False otherwise. + OUTPUT: ``True`` if the reduction is zero; ``False`` otherwise """ return creduce(out, a, prec, prime_pow) @@ -191,10 +187,10 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_ prime INPUT: - - ``out`` -- an ``celement`` to store the unit. - - ``a`` -- the element whose valuation and unit are desired. - - ``prec`` -- a long, used if `a = 0`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the unit + - ``a`` -- the element whose valuation and unit are desired + - ``prec`` -- a long, used if `a = 0` + - ``prime_pow`` -- the PowComputer for the ring - ``reduce_relative`` -- a bint: whether the final result should be reduced at precision ``prec`` (case ``False``) or ``prec - valuation`` (case ``True``) @@ -217,7 +213,7 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_ prime cdef inline long cvaluation(celement a, long prec, PowComputer_ prime_pow) except -1: """ - Returns the maximum power of the uniformizer dividing this + Return the maximum power of the uniformizer dividing this element. This function differs from :meth:`cremove` in that the unit is @@ -225,9 +221,9 @@ cdef inline long cvaluation(celement a, long prec, PowComputer_ prime_pow) excep INPUT: - - ``a`` -- the element whose valuation is desired. - - ``prec`` -- a long, used if `a = 0`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element whose valuation is desired + - ``prec`` -- a long, used if `a = 0` + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: @@ -250,36 +246,34 @@ cdef inline long cvaluation(celement a, long prec, PowComputer_ prime_pow) excep cdef inline bint cisunit(celement a, PowComputer_ prime_pow) except -1: """ - Returns whether this element has valuation zero. + Return whether this element has valuation zero. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. - - OUTPUT: + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - - returns True if `a` has valuation 0, and False otherwise. + OUTPUT: ``True`` if `a` has valuation 0, and ``False`` otherwise """ fmpz_poly_scalar_mod_fmpz(prime_pow.poly_cisunit, a, prime_pow.fprime) return not ciszero(prime_pow.poly_cisunit, prime_pow) cdef inline int cshift(celement out, celement rem, celement a, long n, long prec, PowComputer_ prime_pow, bint reduce_afterward) except -1: """ - Mulitplies by a power of the uniformizer. + Multiplies by a power of the uniformizer. INPUT: - ``out`` -- a ``celement`` to store the result. If `n >= 0` - then out will be set to `a * p^n`. + then out will be set to `a * p^n` If `n < 0`, out will be set to `a // p^-n`. - - ``rem`` -- a ``celement`` to store the remainder of the division. - Should not be aliased with `a`. - - ``a`` -- the element to shift. - - ``n`` -- long, the amount to shift by. - - ``prec`` -- long, a precision modulo which to reduce. - - ``prime_pow`` -- the PowComputer for the ring. - - ``reduce_afterward`` -- whether to reduce afterward. + - ``rem`` -- a ``celement`` to store the remainder of the division + Should not be aliased with `a` + - ``a`` -- the element to shift + - ``n`` -- long, the amount to shift by + - ``prec`` -- long, a precision modulo which to reduce + - ``prime_pow`` -- the PowComputer for the ring + - ``reduce_afterward`` -- whether to reduce afterward """ if n > 0: fmpz_poly_zero(rem) @@ -297,20 +291,20 @@ cdef inline int cshift(celement out, celement rem, celement a, long n, long prec cdef inline int cshift_notrunc(celement out, celement a, long n, long prec, PowComputer_ prime_pow, bint reduce_afterward) except -1: """ - Mulitplies by a power of the uniformizer, assuming that the + Multiplies by a power of the uniformizer, assuming that the valuation of a is at least -n. INPUT: - ``out`` -- an ``celement`` to store the result. If `n >= 0` - then out will be set to `a * p^n`. + then out will be set to `a * p^n` If `n < 0`, out will be set to `a // p^-n`. - ``a`` -- the element to shift. Assumes that the valuation of a is at least -n. - - ``n`` -- long, the amount to shift by. - - ``prec`` -- long, a precision modulo which to reduce. - - ``prime_pow`` -- the PowComputer for the ring. - - ``reduce_afterward`` -- whether to reduce afterward. + - ``n`` -- long, the amount to shift by + - ``prec`` -- long, a precision modulo which to reduce + - ``prime_pow`` -- the PowComputer for the ring + - ``reduce_afterward`` -- whether to reduce afterward """ if n > 0: fmpz_poly_scalar_mul_fmpz(out, a, prime_pow.pow_fmpz_t_tmp(n)[0]) @@ -331,11 +325,11 @@ cdef inline int csub(celement out, celement a, celement b, long prec, PowCompute INPUT: - - ``out`` -- an ``celement`` to store the difference. - - ``a`` -- an ``celement``, the first input. - - ``b`` -- an ``celement``, the second input. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the difference + - ``a`` -- an ``celement``, the first input + - ``b`` -- an ``celement``, the second input + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_sub(out, a, b) @@ -347,10 +341,10 @@ cdef inline int cinvert(celement out, celement a, long prec, PowComputer_ prime_ INPUT: - - ``out`` -- an ``celement`` to store the inverse. - - ``a`` -- an ``celement``, the element to be inverted. - - ``prec`` -- a long, the precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the inverse + - ``a`` -- an ``celement``, the element to be inverted + - ``prec`` -- a long, the precision + - ``prime_pow`` -- the PowComputer for the ring """ sig_on() try: @@ -381,11 +375,11 @@ cdef inline int cmul(celement out, celement a, celement b, long prec, PowCompute INPUT: - - ``out`` -- an ``celement`` to store the product. - - ``a`` -- an ``celement``, the first input. - - ``b`` -- an ``celement``, the second input. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the product + - ``a`` -- an ``celement``, the first input + - ``b`` -- an ``celement``, the second input + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_mul(out, a, b) @@ -398,64 +392,60 @@ cdef inline int cdivunit(celement out, celement a, celement b, long prec, PowCom INPUT: - - ``out`` -- an ``celement`` to store the quotient. - - ``a`` -- an ``celement``, the first input. - - ``b`` -- an ``celement``, the second input. - - ``prec`` -- a long, the precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``celement`` to store the quotient + - ``a`` -- an ``celement``, the first input + - ``b`` -- an ``celement``, the second input + - ``prec`` -- a long, the precision + - ``prime_pow`` -- the PowComputer for the ring """ cinvert(prime_pow.aliasing, b, prec, prime_pow) cmul(out, a, prime_pow.aliasing, prec, prime_pow) cdef inline int csetone(celement out, PowComputer_ prime_pow) except -1: """ - Sets to 1. + Set to 1. INPUT: - - ``out`` -- the ``celement`` in which to store 1. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store 1 + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_set_ui(out, 1) cdef inline int csetzero(celement out, PowComputer_ prime_pow) except -1: """ - Sets to 0. + Set to 0. INPUT: - - ``out`` -- the ``celement`` in which to store 0. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store 0 + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_set_ui(out, 0) cdef inline bint cisone(celement a, PowComputer_ prime_pow) except -1: """ - Returns whether this element is equal to 1. + Return whether this element is equal to 1. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - returns True if `a = 1`, and False otherwise. + OUTPUT: ``True`` if `a = 1`, and ``False`` otherwise """ return fmpz_poly_is_one(a) cdef inline bint ciszero(celement a, PowComputer_ prime_pow) except -1: """ - Returns whether this element is equal to 0. + Return whether this element is equal to 0. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. - - OUTPUT: + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - - returns True if `a = 0`, and False otherwise. + OUTPUT: ``True`` if `a = 0`, and ``False`` otherwise """ return fmpz_poly_is_zero(a) @@ -465,11 +455,11 @@ cdef inline int cpow(celement out, celement a, mpz_t n, long prec, PowComputer_ INPUT: - - ``out`` -- the ``celement`` in which to store the result. - - ``a`` -- the base. - - ``n`` -- an ``mpz_t``, the exponent. - - ``prec`` -- a long, the working absolute precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store the result + - ``a`` -- the base + - ``n`` -- an ``mpz_t``, the exponent + - ``prec`` -- a long, the working absolute precision + - ``prime_pow`` -- the PowComputer for the ring """ if mpz_sgn(n) < 0: raise NotImplementedError("negative exponent") @@ -492,9 +482,9 @@ cdef inline int ccopy(celement out, celement a, PowComputer_ prime_pow) except - INPUT: - - ``out`` -- the ``celement`` to store the result. - - ``a`` -- the element to copy. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` to store the result + - ``a`` -- the element to copy + - ``prime_pow`` -- the PowComputer for the ring """ fmpz_poly_set(out, a) @@ -504,8 +494,8 @@ cdef inline cpickle(celement a, PowComputer_ prime_pow): INPUT: - - ``a`` the element to pickle. - - ``prime_pow`` the PowComputer for the ring. + - ``a`` -- the element to pickle + - ``prime_pow`` the PowComputer for the ring OUTPUT: @@ -519,9 +509,9 @@ cdef inline int cunpickle(celement out, x, PowComputer_ prime_pow) except -1: INPUT: - - ``out`` -- the ``celement`` in which to store the result. - - ``x`` -- the result of :meth:`cpickle`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``celement`` in which to store the result + - ``x`` -- the result of :meth:`cpickle` + - ``prime_pow`` -- the PowComputer for the ring """ byte_string = x.encode("UTF-8") cdef char* c_str = byte_string @@ -533,10 +523,10 @@ cdef inline long chash(celement a, long ordp, long prec, PowComputer_ prime_pow) INPUT: - - ``a`` -- a ``celement`` storing the underlying element to hash. - - ``ordp`` -- a long storing the valuation. - - ``prec`` -- a long storing the precision. - - ``prime_pow`` -- a PowComputer for the ring. + - ``a`` -- a ``celement`` storing the underlying element to hash + - ``ordp`` -- a long storing the valuation + - ``prec`` -- a long storing the precision + - ``prime_pow`` -- a PowComputer for the ring """ if ciszero(a, prime_pow): return 0 @@ -551,12 +541,12 @@ cdef inline cmodp_rep(fmpz_poly_t rep, fmpz_poly_t value, expansion_mode mode, b INPUT: - - ``rep`` -- the reduction mod p. - - ``value`` -- the element to be reduced. + - ``rep`` -- the reduction mod p + - ``value`` -- the element to be reduced - ``mode`` -- if ``smallest_mode``, the coefficients of the reduction -` will be between -p/2 and p/2 instead of between 0 and p. - - ``return_list`` -- boolean, whether to return a list of integers giving the coefficients of the expansion. - - ``prime_pow`` -- a PowComputer for the ring. +` will be between -p/2 and p/2 instead of between 0 and p + - ``return_list`` -- boolean, whether to return a list of integers giving the coefficients of the expansion + - ``prime_pow`` -- a PowComputer for the ring """ cdef long i cdef fmpz* c @@ -584,11 +574,11 @@ cdef inline cexpansion_next(fmpz_poly_t value, expansion_mode mode, long curpowe INPUT: - - ``value`` -- the `p`-adic element whose expansion is desired. + - ``value`` -- the `p`-adic element whose expansion is desired - ``mode`` -- either ``simple_mode`` or ``smallest_mode`` - ``curpower`` -- the current power of `p` for which the coefficient - is being found. Only used in ``smallest_mode``. - - ``prime_pow`` -- A ``PowComputer`` holding `p`-adic data. + is being found. Only used in ``smallest_mode`` + - ``prime_pow`` -- a ``PowComputer`` holding `p`-adic data """ if mode == teichmuller_mode: raise NotImplementedError @@ -610,13 +600,13 @@ cdef inline cexpansion_next(fmpz_poly_t value, expansion_mode mode, long curpowe cdef inline cexpansion_getitem(fmpz_poly_t value, long m, PowComputer_ prime_pow): """ - Return the `m`th `p`-adic digit in the ``simple_mode`` expansion. + Return the `m`-th `p`-adic digit in the ``simple_mode`` expansion. INPUT: - - ``value`` -- the `p`-adic element whose expansion is desired. - - ``m`` -- a non-negative integer: which entry in the `p`-adic expansion to return. - - ``prime_pow`` -- A ``PowComputer`` holding `p`-adic data. + - ``value`` -- the `p`-adic element whose expansion is desired + - ``m`` -- nonnegative integer: which entry in the `p`-adic expansion to return + - ``prime_pow`` -- a ``PowComputer`` holding `p`-adic data """ ans = [] cdef fmpz* c @@ -644,8 +634,8 @@ cdef list ccoefficients(celement x, long valshift, long prec, PowComputer_ prime INPUT: - - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part. - - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by. + - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part + - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by - ``prec`` -- a long, the (relative) precision desired, used in rational reconstruction - ``prime_pow`` -- the ``PowComputer`` of the ring """ @@ -677,9 +667,9 @@ cdef int cteichmuller(celement out, celement value, long prec, PowComputer_ prim - ``out`` -- an ``celement`` which is set to a `q-1` root of unity congruent to `value` mod `\pi`; or 0 if `a \equiv 0 \pmod{\pi}`. - - ``value`` -- an ``celement``, the element mod `\pi` to lift. - - ``prec`` -- a long, the precision to which to lift. - - ``prime_pow`` -- the ``PowComputer`` of the ring. + - ``value`` -- an ``celement``, the element mod `\pi` to lift + - ``prec`` -- a long, the precision to which to lift + - ``prime_pow`` -- the ``PowComputer`` of the ring ALGORITHM: @@ -688,7 +678,6 @@ cdef int cteichmuller(celement out, celement value, long prec, PowComputer_ prim digits coincide with `f'`. This does probably not yield quadratic convergence but taking inverses would be much more expensive than what is done here. - """ fmpz_poly_set(out, value) @@ -719,17 +708,17 @@ cdef int cconv(celement out, x, long prec, long valshift, PowComputer_ prime_pow INPUT: - - ``out`` -- an ``celement`` to store the output. + - ``out`` -- an ``celement`` to store the output - - ``x`` -- a Sage element that can be converted to a `p`-adic element. + - ``x`` -- a Sage element that can be converted to a `p`-adic element - - ``prec`` -- a long, giving the precision desired: absolute if - `valshift = 0`, relative if `valshift != 0`. + - ``prec`` -- a long, giving the precision desired; absolute if + `valshift = 0`, relative if `valshift != 0` - ``valshift`` -- the power of the uniformizer to divide by before - storing the result in ``out``. + storing the result in ``out`` - - ``prime_pow`` -- a PowComputer for the ring. + - ``prime_pow`` -- a PowComputer for the ring """ cdef long i cdef long degree @@ -757,19 +746,19 @@ cdef inline long cconv_mpq_t(celement out, mpq_t x, long prec, bint absolute, Po INPUT: - - ``out`` -- an ``celement`` to store the output. - - ``x`` -- an ``mpq_t`` giving the integer to be converted. + - ``out`` -- an ``celement`` to store the output + - ``x`` -- an ``mpq_t`` giving the integer to be converted - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. - - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + relative depending on the ``absolute`` input + - ``absolute`` -- if ``False`` then extracts the valuation and returns + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision. + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: - - If ``absolute`` is False then returns the valuation that was - extracted (``maxordp`` when `x = 0`). + If ``absolute`` is ``False`` then returns the valuation that was + extracted (``maxordp`` when `x = 0`). """ cdef long val val = cconv_mpq_t_shared(prime_pow.mpz_cconv, x, prec, absolute, prime_pow) @@ -778,7 +767,7 @@ cdef inline long cconv_mpq_t(celement out, mpq_t x, long prec, bint absolute, Po cdef inline int cconv_mpq_t_out(mpq_t out, celement x, long valshift, long prec, PowComputer_ prime_pow) except -1: """ - Converts the underlying `p`-adic element into a rational + Convert the underlying `p`-adic element into a rational. - ``out`` -- gives a rational approximating the input. Currently uses rational reconstruction but may change in the future to use a more naive method @@ -804,14 +793,14 @@ cdef inline long cconv_mpz_t(celement out, mpz_t x, long prec, bint absolute, Po INPUT: - - ``out`` -- an ``celement`` to store the output. - - ``x`` -- an ``mpz_t`` giving the integer to be converted. + - ``out`` -- an ``celement`` to store the output + - ``x`` -- an ``mpz_t`` giving the integer to be converted - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. + relative depending on the ``absolute`` input - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -825,15 +814,15 @@ cdef inline long cconv_mpz_t(celement out, mpz_t x, long prec, bint absolute, Po cdef inline int cconv_mpz_t_out(mpz_t out, celement x, long valshift, long prec, PowComputer_ prime_pow) except -1: """ - Converts the underlying `p`-adic element into an integer if + Convert the underlying `p`-adic element into an integer if possible. - ``out`` -- stores the resulting integer as an integer between 0 - and `p^{prec + valshift}`. - - ``x`` -- an ``celement`` giving the underlying `p`-adic element. - - ``valshift`` -- a long giving the power of `p` to shift `x` by. - -` ``prec`` -- a long, the precision of ``x``: currently not used. - - ``prime_pow`` -- a PowComputer for the ring. + and `p^{prec + valshift}` + - ``x`` -- an ``celement`` giving the underlying `p`-adic element + - ``valshift`` -- a long giving the power of `p` to shift `x` by + -` ``prec`` -- a long, the precision of ``x``: currently not used + - ``prime_pow`` -- a PowComputer for the ring """ cdef long degree = fmpz_poly_degree(x) if degree > 0: @@ -850,7 +839,7 @@ cdef inline int cconv_mpz_t_out(mpz_t out, celement x, long valshift, long prec, cdef cmatrix_mod_pn(celement a, long aprec, long valshift, PowComputer_ prime_pow): r""" - Returns the matrix of right multiplication by the element on + Return the matrix of right multiplication by the element on the power basis `1, x, x^2, \ldots, x^{d-1}` for this extension field. Thus the *rows* of this matrix give the images of each of the `x^i`. The entries of the matrices are diff --git a/src/sage/libs/linkages/padics/mpz.pxi b/src/sage/libs/linkages/padics/mpz.pxi index 3a555e441dc..01ff197488e 100644 --- a/src/sage/libs/linkages/padics/mpz.pxi +++ b/src/sage/libs/linkages/padics/mpz.pxi @@ -40,8 +40,8 @@ cdef inline int cconstruct(mpz_t value, PowComputer_ prime_pow) except -1: INPUT: - - ``unit`` -- an ``mpz_t`` to be initialized. - - ``prime_pow`` -- the PowComputer for the ring. + - ``unit`` -- an ``mpz_t`` to be initialized + - ``prime_pow`` -- the PowComputer for the ring """ mpz_init(value) @@ -51,8 +51,8 @@ cdef inline int cdestruct(mpz_t value, PowComputer_ prime_pow) except -1: INPUT: - - ``unit`` -- an ``mpz_t`` to be cleared. - - ``prime_pow`` -- the PowComputer for the ring. + - ``unit`` -- an ``mpz_t`` to be cleared + - ``prime_pow`` -- the PowComputer for the ring """ mpz_clear(value) @@ -62,12 +62,12 @@ cdef inline int ccmp(mpz_t a, mpz_t b, long prec, bint reduce_a, bint reduce_b, INPUT: - - ``a`` -- an ``mpz_t``. - - ``b`` -- an ``mpz_t``. - - ``prec`` -- a long, the precision of the comparison. - - ``reduce_a`` -- a bint, whether a needs to be reduced. - - ``reduce_b`` -- a bint, whether b needs to be reduced. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- an ``mpz_t`` + - ``b`` -- an ``mpz_t`` + - ``prec`` -- a long, the precision of the comparison + - ``reduce_a`` -- a bint, whether a needs to be reduced + - ``reduce_b`` -- a bint, whether b needs to be reduced + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: @@ -97,10 +97,10 @@ cdef inline int cneg(mpz_t out, mpz_t a, long prec, PowComputer_ prime_pow) exce INPUT: - - ``out`` -- an ``mpz_t`` to store the negation. - - ``a`` -- an ``mpz_t`` to be negated. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the negation + - ``a`` -- an ``mpz_t`` to be negated + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ mpz_neg(out, a) @@ -112,11 +112,11 @@ cdef inline int cadd(mpz_t out, mpz_t a, mpz_t b, long prec, PowComputer_ prime_ INPUT: - - ``out`` -- an ``mpz_t`` to store the sum. - - ``a`` -- an ``mpz_t``, the first summand. - - ``b`` -- an ``mpz_t``, the second summand. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the sum + - ``a`` -- an ``mpz_t``, the first summand + - ``b`` -- an ``mpz_t``, the second summand + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ mpz_add(out, a, b) @@ -126,14 +126,12 @@ cdef inline bint creduce(mpz_t out, mpz_t a, long prec, PowComputer_ prime_pow) INPUT: - - ``out`` -- an ``mpz_t`` to store the reduction. - - ``a`` -- the element to be reduced. - - ``prec`` -- a long, the precision to reduce modulo. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the reduction + - ``a`` -- the element to be reduced + - ``prec`` -- a long, the precision to reduce modulo + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - returns True if the reduction is zero; False otherwise. + OUTPUT: ``True`` if the reduction is zero; ``False`` otherwise """ # The following could fail if the value returned by # prime_pow.pow_mpz_t_tmp(prec) is zero. We could add a sig_on()/sig_off() @@ -151,14 +149,12 @@ cdef inline bint creduce_small(mpz_t out, mpz_t a, long prec, PowComputer_ prime INPUT: - - ``out`` -- an ``mpz_t`` to store the reduction. - - ``a`` -- the element to be reduced. - - ``prec`` -- a long, the precision to reduce modulo. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the reduction + - ``a`` -- the element to be reduced + - ``prec`` -- a long, the precision to reduce modulo + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - returns True if the reduction is zero; False otherwise. + OUTPUT: ``True`` if the reduction is zero; ``False`` otherwise """ if mpz_sgn(a) < 0: mpz_add(out, a, prime_pow.pow_mpz_t_tmp(prec)) @@ -175,10 +171,10 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_ prime INPUT: - - ``out`` -- an ``mpz_t`` to store the unit. - - ``a`` -- the element whose valuation and unit are desired. - - ``prec`` -- a long, used if `a = 0`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the unit + - ``a`` -- the element whose valuation and unit are desired + - ``prec`` -- a long, used if `a = 0` + - ``prime_pow`` -- the PowComputer for the ring - ``reduce_relative`` -- a bint: whether the final result should be reduced at precision ``prec`` (case ``False``) or ``prec - valuation`` (case ``True``) @@ -195,7 +191,7 @@ cdef inline long cremove(celement out, celement a, long prec, PowComputer_ prime cdef inline long cvaluation(mpz_t a, long prec, PowComputer_ prime_pow) except -1: """ - Returns the maximum power of the uniformizer dividing this + Return the maximum power of the uniformizer dividing this element. This function differs from :meth:`cremove` in that the unit is @@ -203,9 +199,9 @@ cdef inline long cvaluation(mpz_t a, long prec, PowComputer_ prime_pow) except - INPUT: - - ``a`` -- the element whose valuation is desired. - - ``prec`` -- a long, used if `a = 0`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``a`` -- the element whose valuation is desired + - ``prec`` -- a long, used if `a = 0` + - ``prime_pow`` -- the PowComputer for the ring OUTPUT: @@ -218,34 +214,31 @@ cdef inline long cvaluation(mpz_t a, long prec, PowComputer_ prime_pow) except - cdef inline bint cisunit(mpz_t a, PowComputer_ prime_pow) except -1: """ - Returns whether this element has valuation zero. + Return whether this element has valuation zero. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. - - OUTPUT: + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - - returns True if `a` has valuation 0, and False otherwise. + OUTPUT: ``True`` if `a` has valuation 0, and ``False`` otherwise """ return mpz_divisible_p(a, prime_pow.prime.value) == 0 cdef inline int cshift(mpz_t out, mpz_t rem, mpz_t a, long n, long prec, PowComputer_ prime_pow, bint reduce_afterward) except -1: """ - Multiplies by a power of the uniformizer. + Multiply by a power of the uniformizer. INPUT: - ``out`` -- an ``mpz_t`` to store the result. If `n >= 0` then - out will be set to `a * p^n`. If `n < 0`, out will - be set to `a // p^n`. + out will be set to `a * p^n`. If `n < 0`, out will be set to `a // p^n`. - ``rem`` -- an ``mpz_t`` to store the remainder, when `n < 0` - - ``a`` -- the element to shift. - - ``n`` -- long, the amount to shift by. - - ``prec`` -- long, a precision modulo which to reduce. - - ``prime_pow`` -- the PowComputer for the ring. - - ``reduce_afterward`` -- whether to reduce afterward. + - ``a`` -- the element to shift + - ``n`` -- long, the amount to shift by + - ``prec`` -- long, a precision modulo which to reduce + - ``prime_pow`` -- the PowComputer for the ring + - ``reduce_afterward`` -- whether to reduce afterward """ if n > 0: mpz_mul(out, a, prime_pow.pow_mpz_t_tmp(n)) @@ -260,20 +253,19 @@ cdef inline int cshift(mpz_t out, mpz_t rem, mpz_t a, long n, long prec, PowComp cdef inline int cshift_notrunc(mpz_t out, mpz_t a, long n, long prec, PowComputer_ prime_pow, bint reduce_afterward) except -1: """ - Multiplies by a power of the uniformizer, assuming that the + Multiply by a power of the uniformizer, assuming that the valuation of a is at least -n. INPUT: - ``out`` -- an ``mpz_t`` to store the result. If `n >= 0` then - out will be set to `a * p^n`. If `n < 0`, out will - be set to `a // p^n`. + out will be set to `a * p^n`. If `n < 0`, out will be set to `a // p^n`. - ``a`` -- the element to shift. Assumes that the valuation of a is at least -n. - - ``n`` -- long, the amount to shift by. - - ``prec`` -- long, a precision modulo which to reduce. - - ``prime_pow`` -- the PowComputer for the ring. - - ``reduce_afterward`` -- whether to reduce afterward. + - ``n`` -- long, the amount to shift by + - ``prec`` -- long, a precision modulo which to reduce + - ``prime_pow`` -- the PowComputer for the ring + - ``reduce_afterward`` -- whether to reduce afterward """ if n > 0: mpz_mul(out, a, prime_pow.pow_mpz_t_tmp(n)) @@ -294,11 +286,11 @@ cdef inline int csub(mpz_t out, mpz_t a, mpz_t b, long prec, PowComputer_ prime_ INPUT: - - ``out`` -- an ``mpz_t`` to store the difference. - - ``a`` -- an ``mpz_t``, the first input. - - ``b`` -- an ``mpz_t``, the second input. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the difference + - ``a`` -- an ``mpz_t``, the first input + - ``b`` -- an ``mpz_t``, the second input + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ mpz_sub(out, a, b) @@ -310,10 +302,10 @@ cdef inline int cinvert(mpz_t out, mpz_t a, long prec, PowComputer_ prime_pow) e INPUT: - - ``out`` -- an ``mpz_t`` to store the inverse. - - ``a`` -- an ``mpz_t``, the element to be inverted. - - ``prec`` -- a long, the precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the inverse + - ``a`` -- an ``mpz_t``, the element to be inverted + - ``prec`` -- a long, the precision + - ``prime_pow`` -- the PowComputer for the ring """ cdef bint success success = mpz_invert(out, a, prime_pow.pow_mpz_t_tmp(prec)) @@ -328,11 +320,11 @@ cdef inline int cmul(mpz_t out, mpz_t a, mpz_t b, long prec, PowComputer_ prime_ INPUT: - - ``out`` -- an ``mpz_t`` to store the product. - - ``a`` -- an ``mpz_t``, the first input. - - ``b`` -- an ``mpz_t``, the second input. - - ``prec`` -- a long, the precision: ignored. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the product + - ``a`` -- an ``mpz_t``, the first input + - ``b`` -- an ``mpz_t``, the second input + - ``prec`` -- a long, the precision: ignored + - ``prime_pow`` -- the PowComputer for the ring """ mpz_mul(out, a, b) @@ -345,11 +337,11 @@ cdef inline int cdivunit(mpz_t out, mpz_t a, mpz_t b, long prec, PowComputer_ pr INPUT: - - ``out`` -- an ``mpz_t`` to store the quotient. - - ``a`` -- an ``mpz_t``, the first input. - - ``b`` -- an ``mpz_t``, the second input. - - ``prec`` -- a long, the precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the quotient + - ``a`` -- an ``mpz_t``, the first input + - ``b`` -- an ``mpz_t``, the second input + - ``prec`` -- a long, the precision + - ``prime_pow`` -- the PowComputer for the ring """ cdef bint success success = mpz_invert(prime_pow.aliasing, b, prime_pow.pow_mpz_t_tmp(prec)) @@ -359,53 +351,49 @@ cdef inline int cdivunit(mpz_t out, mpz_t a, mpz_t b, long prec, PowComputer_ pr cdef inline int csetone(mpz_t out, PowComputer_ prime_pow) except -1: """ - Sets to 1. + Set to 1. INPUT: - - ``out`` -- the ``mpz_t`` in which to store 1. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``mpz_t`` in which to store 1 + - ``prime_pow`` -- the PowComputer for the ring """ mpz_set_ui(out, 1) cdef inline int csetzero(mpz_t out, PowComputer_ prime_pow) except -1: """ - Sets to 0. + Set to 0. INPUT: - - ``out`` -- the ``mpz_t`` in which to store 0. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``mpz_t`` in which to store 0 + - ``prime_pow`` -- the PowComputer for the ring """ mpz_set_ui(out, 0) cdef inline bint cisone(mpz_t out, PowComputer_ prime_pow) except -1: """ - Returns whether this element is equal to 1. + Return whether this element is equal to 1. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. - - OUTPUT: + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - - returns True if `a = 1`, and False otherwise. + OUTPUT: ``True`` if `a = 1`, and ``False`` otherwise """ return mpz_cmp_ui(out, 1) == 0 cdef inline bint ciszero(mpz_t out, PowComputer_ prime_pow) except -1: """ - Returns whether this element is equal to 0. + Return whether this element is equal to 0. INPUT: - - ``a`` -- the element to test. - - ``prime_pow`` -- the PowComputer for the ring. - - OUTPUT: + - ``a`` -- the element to test + - ``prime_pow`` -- the PowComputer for the ring - - returns True if `a = 0`, and False otherwise. + OUTPUT: ``True`` if `a = 0`, and ``False`` otherwise """ return mpz_cmp_ui(out, 0) == 0 @@ -415,11 +403,11 @@ cdef inline int cpow(mpz_t out, mpz_t a, mpz_t n, long prec, PowComputer_ prime_ INPUT: - - ``out`` -- the ``mpz_t`` in which to store the result. - - ``a`` -- the base. - - ``n`` -- an ``mpz_t``, the exponent. - - ``prec`` -- a long, the working absolute precision. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``mpz_t`` in which to store the result + - ``a`` -- the base + - ``n`` -- an ``mpz_t``, the exponent + - ``prec`` -- a long, the working absolute precision + - ``prime_pow`` -- the PowComputer for the ring """ mpz_powm(out, a, n, prime_pow.pow_mpz_t_tmp(prec)) @@ -429,9 +417,9 @@ cdef inline int ccopy(mpz_t out, mpz_t a, PowComputer_ prime_pow) except -1: INPUT: - - ``out`` -- the ``mpz_t`` to store the result. - - ``a`` -- the element to copy. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``mpz_t`` to store the result + - ``a`` -- the element to copy + - ``prime_pow`` -- the PowComputer for the ring """ mpz_set(out, a) @@ -441,12 +429,10 @@ cdef inline cpickle(mpz_t a, PowComputer_ prime_pow): INPUT: - - ``a`` the element to pickle. - - ``prime_pow`` the PowComputer for the ring. + - ``a`` -- the element to pickle + - ``prime_pow`` -- the PowComputer for the ring - OUTPUT: - - - an Integer storing ``a``. + OUTPUT: an Integer storing ``a`` """ cdef Integer pic = PY_NEW(Integer) mpz_set(pic.value, a) @@ -458,9 +444,9 @@ cdef inline int cunpickle(mpz_t out, x, PowComputer_ prime_pow) except -1: INPUT: - - ``out`` -- the ``mpz_t`` in which to store the result. - - ``x`` -- the result of :meth:`cpickle`. - - ``prime_pow`` -- the PowComputer for the ring. + - ``out`` -- the ``mpz_t`` in which to store the result + - ``x`` -- the result of :meth:`cpickle` + - ``prime_pow`` -- the PowComputer for the ring """ mpz_set(out, (x).value) @@ -470,10 +456,10 @@ cdef inline long chash(mpz_t a, long ordp, long prec, PowComputer_ prime_pow) ex INPUT: - - ``a`` -- an ``mpz_t`` storing the underlying element to hash. - - ``ordp`` -- a long storing the valuation. - - ``prec`` -- a long storing the precision. - - ``prime_pow`` -- a PowComputer for the ring. + - ``a`` -- an ``mpz_t`` storing the underlying element to hash + - ``ordp`` -- a long storing the valuation + - ``prec`` -- a long storing the precision + - ``prime_pow`` -- a PowComputer for the ring """ # This implementation is for backward compatibility and may be changed in the future cdef long n, d @@ -499,11 +485,11 @@ cdef inline cexpansion_next(mpz_t value, expansion_mode mode, long curpower, Pow INPUT: - - ``value`` -- the `p`-adic element whose expansion is desired. + - ``value`` -- the `p`-adic element whose expansion is desired - ``mode`` -- either ``simple_mode`` or ``smallest_mode`` - ``curpower`` -- the current power of `p` for which the coefficient is being found. Only used in ``smallest_mode``. - - ``prime_pow`` -- A ``PowComputer`` holding `p`-adic data. + - ``prime_pow`` -- a ``PowComputer`` holding `p`-adic data """ if mode == teichmuller_mode: raise NotImplementedError @@ -525,13 +511,13 @@ cdef inline cexpansion_next(mpz_t value, expansion_mode mode, long curpower, Pow cdef inline cexpansion_getitem(mpz_t value, long m, PowComputer_ prime_pow): """ - Return the `m`th `p`-adic digit in the ``simple_mode`` expansion. + Return the `m`-th `p`-adic digit in the ``simple_mode`` expansion. INPUT: - - ``value`` -- the `p`-adic element whose expansion is desired. - - ``m`` -- a non-negative integer: which entry in the `p`-adic expansion to return. - - ``prime_pow`` -- A ``PowComputer`` holding `p`-adic data. + - ``value`` -- the `p`-adic element whose expansion is desired + - ``m`` -- nonnegative integer; which entry in the `p`-adic expansion to return + - ``prime_pow`` -- a ``PowComputer`` holding `p`-adic data """ cdef Integer ans = PY_NEW(Integer) if m > 0: @@ -551,8 +537,8 @@ cdef list ccoefficients(mpz_t x, long valshift, long prec, PowComputer_ prime_po INPUT: - - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part. - - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by. + - ``x`` -- a ``celement`` giving the underlying `p`-adic element, or possibly its unit part + - ``valshift`` -- a long giving the power of the uniformizer to shift `x` by - ``prec`` -- a long, the (relative) precision desired, used in rational reconstruction - ``prime_pow`` -- the ``PowComputer`` of the ring """ @@ -574,11 +560,10 @@ cdef int cteichmuller(mpz_t out, mpz_t value, long prec, PowComputer_ prime_pow) INPUT: - ``out`` -- an ``mpz_t`` which is set to a `p-1` root of unity - congruent to `value` mod `p`; or 0 if `a \equiv 0 - \pmod{p}`. - - ``value`` -- an ``mpz_t``, the element mod `p` to lift. - - ``prec`` -- a long, the precision to which to lift. - - ``prime_pow`` -- the ``PowComputer`` of the ring. + congruent to `value` mod `p`; or 0 if `a \equiv 0 \pmod{p}` + - ``value`` -- an ``mpz_t``, the element mod `p` to lift + - ``prec`` -- a long, the precision to which to lift + - ``prime_pow`` -- the ``PowComputer`` of the ring """ if mpz_divisible_p(value, prime_pow.prime.value) != 0: mpz_set_ui(out, 0) @@ -617,17 +602,17 @@ cdef int cconv(mpz_t out, x, long prec, long valshift, PowComputer_ prime_pow) e INPUT: - - ``out`` -- an ``mpz_t`` to store the output. + - ``out`` -- an ``mpz_t`` to store the output - - ``x`` -- a Sage element that can be converted to a `p`-adic element. + - ``x`` -- a Sage element that can be converted to a `p`-adic element - ``prec`` -- a long, giving the precision desired: absolute if - `valshift = 0`, relative if `valshift != 0`. + `valshift = 0`, relative if `valshift != 0` - ``valshift`` -- the power of the uniformizer to divide by before - storing the result in ``out``. + storing the result in ``out`` - - ``prime_pow`` -- a PowComputer for the ring. + - ``prime_pow`` -- a PowComputer for the ring """ return cconv_shared(out, x, prec, valshift, prime_pow) @@ -638,14 +623,14 @@ cdef inline long cconv_mpq_t(mpz_t out, mpq_t x, long prec, bint absolute, PowCo INPUT: - - ``out`` -- an ``mpz_t`` to store the output. - - ``x`` -- an ``mpq_t`` giving the integer to be converted. + - ``out`` -- an ``mpz_t`` to store the output + - ``x`` -- an ``mpq_t`` giving the integer to be converted - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. + relative depending on the ``absolute`` input - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -656,7 +641,7 @@ cdef inline long cconv_mpq_t(mpz_t out, mpq_t x, long prec, bint absolute, PowCo cdef inline int cconv_mpq_t_out(mpq_t out, mpz_t x, long valshift, long prec, PowComputer_ prime_pow) except -1: """ - Converts the underlying `p`-adic element into a rational + Convert the underlying `p`-adic element into a rational. - ``out`` -- gives a rational approximating the input. Currently uses rational reconstruction but may change in the future to use a more naive method @@ -674,14 +659,14 @@ cdef inline long cconv_mpz_t(mpz_t out, mpz_t x, long prec, bint absolute, PowCo INPUT: - - ``out`` -- an ``mpz_t`` to store the output. - - ``x`` -- an ``mpz_t`` giving the integer to be converted. + - ``out`` -- an ``mpz_t`` to store the output + - ``x`` -- an ``mpz_t`` giving the integer to be converted - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. + relative depending on the ``absolute`` input - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -692,14 +677,14 @@ cdef inline long cconv_mpz_t(mpz_t out, mpz_t x, long prec, bint absolute, PowCo cdef inline int cconv_mpz_t_out(mpz_t out, mpz_t x, long valshift, long prec, PowComputer_ prime_pow) except -1: """ - Converts the underlying `p`-adic element into an integer if + Convert the underlying `p`-adic element into an integer if possible. - ``out`` -- stores the resulting integer as an integer between 0 - and `p^{prec + valshift}`. - - ``x`` -- an ``mpz_t`` giving the underlying `p`-adic element. - - ``valshift`` -- a long giving the power of `p` to shift `x` by. - -` ``prec`` -- a long, the precision of ``x``: currently not used. - - ``prime_pow`` -- a PowComputer for the ring. + and `p^{prec + valshift}` + - ``x`` -- an ``mpz_t`` giving the underlying `p`-adic element + - ``valshift`` -- a long giving the power of `p` to shift `x` by + -` ``prec`` -- a long, the precision of ``x``: currently not used + - ``prime_pow`` -- a PowComputer for the ring """ return cconv_mpz_t_out_shared(out, x, valshift, prec, prime_pow) diff --git a/src/sage/libs/linkages/padics/relaxed/API.pxi b/src/sage/libs/linkages/padics/relaxed/API.pxi index 4e9ea075bb2..07934c1322d 100644 --- a/src/sage/libs/linkages/padics/relaxed/API.pxi +++ b/src/sage/libs/linkages/padics/relaxed/API.pxi @@ -17,9 +17,9 @@ of its reduction modulo `\pi`) and propagate the carry accordingly. Our API is based on two template types (which have to be instantiated in implementations): -- ``cdigit``: the type of a digit +- ``cdigit`` -- the type of a digit -- ``celement``: the type of an element (which is then a polynomial whose +- ``celement`` -- the type of an element (which is then a polynomial whose coefficients are elements of type ``cdigit``) The remainder of the file gives the function signatures. @@ -100,7 +100,7 @@ cdef inline void digit_set_ui(cdigit a, long b): INPUT: - ``a`` -- the ``cdigit`` to set up - - ``b`` -- an integer, the value of assign + - ``b`` -- integer; the value of assign """ pass @@ -134,12 +134,12 @@ cdef inline bint digit_equal(cdigit a, cdigit b): cdef inline bint digit_equal_ui(cdigit a, long b): r""" - Comparison of a digit and an integer + Comparison of a digit and an integer. INPUT: - ``a`` -- a ``cdigit`` - - ``b`` -- an integer + - ``b`` -- integer OUTPUT: @@ -149,7 +149,7 @@ cdef inline bint digit_equal_ui(cdigit a, long b): cdef inline bint digit_is_zero(cdigit a): r""" - Comparison to zero + Comparison to zero. INPUT: @@ -163,7 +163,7 @@ cdef inline bint digit_is_zero(cdigit a): cdef inline void digit_random_init(randgen generator, long seed): r""" - Initialize the random generator with a new seed + Initialize the random generator with a new seed. INPUT: @@ -326,7 +326,7 @@ cdef inline Element element_get_sage(celement x, PowComputer_class prime_pow): cdef inline void element_set(celement x, celement y): r""" - Set an element + Set an element. INPUT: @@ -344,7 +344,7 @@ cdef inline cdigit element_get_digit(celement x, long i): INPUT: - ``x`` -- a ``celement`` - - ``i`` -- an integer + - ``i`` -- integer """ pass @@ -356,8 +356,8 @@ cdef inline void element_get_slice(celement res, celement x, long start, long le - ``res`` -- a ``celement`` to store the slice - ``x`` -- a ``celement``, the element from which the slice is extracted - - ``start`` -- an integer, the start position of the slice - - ``length`` -- an integer, the length of the slice + - ``start`` -- integer; the start position of the slice + - ``length`` -- integer; the length of the slice .. NOTE:: @@ -375,7 +375,7 @@ cdef inline void element_set_digit(celement x, cdigit a, long i): - ``x`` -- a ``celement`` - ``a`` -- a ``cdigit`` - - ``i`` -- an integer + - ``i`` -- integer """ pass @@ -386,8 +386,8 @@ cdef inline void element_set_digit_ui(celement x, long a, long i): INPUT: - ``x`` -- a ``celement`` - - ``a`` -- an integer - - ``i`` -- an integer + - ``a`` -- integer + - ``i`` -- integer """ pass @@ -399,7 +399,7 @@ cdef inline void element_set_digit_sage(celement x, Element a, long i): - ``x`` -- a ``celement`` - ``a`` -- a Sage element - - ``i`` -- an integer + - ``i`` -- integer """ pass @@ -414,7 +414,7 @@ cdef inline void element_iadd_digit(celement x, cdigit a, long i): - ``x`` -- a ``celement`` - ``a`` -- a ``cdigit`` - - ``i`` -- an integer + - ``i`` -- integer """ pass @@ -427,7 +427,7 @@ cdef inline void element_isub_digit(celement x, cdigit a, long i): - ``x`` -- a ``celement`` - ``a`` -- a ``cdigit`` - - ``i`` -- an integer + - ``i`` -- integer """ pass @@ -475,7 +475,7 @@ cdef inline void element_reduce_digit(celement x, long i, PowComputer_class prim INPUT: - ``x`` -- a ``celement``, the element to update - - ``i`` -- an integer + - ``i`` -- integer - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -488,7 +488,7 @@ cdef inline void element_reducesmall_digit(fmpz_poly_t x, long i, PowComputer_fl INPUT: - ``x`` -- a ``celement``, the element to update - - ``i`` -- an integer + - ``i`` -- integer - ``prime_pow`` -- the PowComputer for the ring """ pass @@ -501,7 +501,7 @@ cdef inline void element_reduceneg_digit(fmpz_poly_t x, long i, PowComputer_flin INPUT: - ``x`` -- a ``celement``, the element to update - - ``i`` -- an integer + - ``i`` -- integer - ``prime_pow`` -- the PowComputer for the ring """ pass diff --git a/src/sage/libs/linkages/padics/relaxed/flint.pxi b/src/sage/libs/linkages/padics/relaxed/flint.pxi index 7085fd76ac8..11ead5edef5 100644 --- a/src/sage/libs/linkages/padics/relaxed/flint.pxi +++ b/src/sage/libs/linkages/padics/relaxed/flint.pxi @@ -101,7 +101,7 @@ cdef inline void digit_set_ui(fmpz_t a, slong b) noexcept: INPUT: - ``a`` -- the ``cdigit`` to set up - - ``b`` -- an integer, the value of assign + - ``b`` -- integer; the value of assign """ fmpz_set_ui(a, b) @@ -140,7 +140,7 @@ cdef inline bint digit_equal_ui(fmpz_t a, slong b) noexcept: INPUT: - ``a`` -- a ``cdigit`` - - ``b`` -- an integer + - ``b`` -- integer OUTPUT: @@ -369,7 +369,7 @@ cdef inline fmpz* element_get_digit(fmpz_poly_t x, slong i) noexcept: INPUT: - ``x`` -- a ``celement`` - - ``i`` -- an integer + - ``i`` -- integer """ return get_coeff(x, i) @@ -381,8 +381,8 @@ cdef inline void element_get_slice(fmpz_poly_t res, fmpz_poly_t x, slong start, - ``res`` -- a ``celement`` to store the slice - ``x`` -- a ``celement``, the element from which the slice is extracted - - ``start`` -- an integer, the start position of the slice - - ``length`` -- an integer, the length of the slice + - ``start`` -- integer; the start position of the slice + - ``length`` -- integer; the length of the slice .. NOTE:: @@ -400,7 +400,7 @@ cdef inline void element_set_digit(fmpz_poly_t x, fmpz_t a, slong i) noexcept: - ``x`` -- a ``celement`` - ``a`` -- a ``cdigit`` - - ``i`` -- an integer + - ``i`` -- integer """ fmpz_poly_set_coeff_fmpz(x, i, a) @@ -411,8 +411,8 @@ cdef inline void element_set_digit_ui(fmpz_poly_t x, slong a, slong i) noexcept: INPUT: - ``x`` -- a ``celement`` - - ``a`` -- an integer - - ``i`` -- an integer + - ``a`` -- integer + - ``i`` -- integer """ fmpz_poly_set_coeff_ui(x, i, a) @@ -424,7 +424,7 @@ cdef inline void element_set_digit_sage(fmpz_poly_t x, Integer a, slong i) noexc - ``x`` -- a ``celement`` - ``a`` -- a Sage element - - ``i`` -- an integer + - ``i`` -- integer """ fmpz_poly_set_coeff_mpz(x, i, a.value) @@ -439,7 +439,7 @@ cdef inline void element_iadd_digit(fmpz_poly_t x, fmpz_t a, slong i) noexcept: - ``x`` -- a ``celement`` - ``a`` -- a ``cdigit`` - - ``i`` -- an integer + - ``i`` -- integer """ iadd_coeff(x, a, i) @@ -452,7 +452,7 @@ cdef inline void element_isub_digit(fmpz_poly_t x, fmpz_t a, slong i) noexcept: - ``x`` -- a ``celement`` - ``a`` -- a ``cdigit`` - - ``i`` -- an integer + - ``i`` -- integer """ isub_coeff(x, a, i) @@ -500,7 +500,7 @@ cdef inline void element_reduce_digit(fmpz_poly_t x, slong i, PowComputer_flint INPUT: - ``x`` -- a ``celement``, the element to update - - ``i`` -- an integer + - ``i`` -- integer - ``prime_pow`` -- the PowComputer for the ring """ reduce_coeff(x, i, prime_pow.fprime) @@ -513,7 +513,7 @@ cdef inline void element_reducesmall_digit(fmpz_poly_t x, slong i, PowComputer_f INPUT: - ``x`` -- a ``celement``, the element to update - - ``i`` -- an integer + - ``i`` -- integer - ``prime_pow`` -- the PowComputer for the ring """ reducesmall_coeff(x, i, prime_pow.fprime) @@ -526,7 +526,7 @@ cdef inline void element_reduceneg_digit(fmpz_poly_t x, slong i, PowComputer_fli INPUT: - ``x`` -- a ``celement``, the element to update - - ``i`` -- an integer + - ``i`` -- integer - ``prime_pow`` -- the PowComputer for the ring """ reduceneg_coeff(x, i, prime_pow.fprime) diff --git a/src/sage/libs/linkages/padics/unram_shared.pxi b/src/sage/libs/linkages/padics/unram_shared.pxi index 7ffbebc5f52..e3edc87bc39 100644 --- a/src/sage/libs/linkages/padics/unram_shared.pxi +++ b/src/sage/libs/linkages/padics/unram_shared.pxi @@ -1,5 +1,6 @@ cimport cython + @cython.binding(True) def frobenius_unram(self, arithmetic=True): """ @@ -8,7 +9,7 @@ def frobenius_unram(self, arithmetic=True): INPUT: - - ``self`` -- an element of an unramified extension. + - ``self`` -- an element of an unramified extension - ``arithmetic`` -- whether to apply the arithmetic Frobenius (acting by raising to the `p`-th power on the residue field). If ``False`` is provided, the image of geometric Frobenius (raising to the `(1/p)`-th @@ -39,7 +40,7 @@ def frobenius_unram(self, arithmetic=True): sage: c.frobenius().frobenius() (a + 1)*7^-1 + O(7^3) - An error will be raised if the parent of self is a ramified extension:: + An error will be raised if the parent of ``self`` is a ramified extension:: sage: x = polygen(ZZ, 'x') sage: K. = Qp(5).extension(x^2 - 5) @@ -55,7 +56,6 @@ def frobenius_unram(self, arithmetic=True): sage: x = R.random_element() sage: x.frobenius(arithmetic=false).frobenius() == x True - """ if self == 0: return self @@ -95,9 +95,9 @@ def norm_unram(self, base = None): INPUT: - - ``base`` -- a subfield of the parent `L` of this element. - The norm is the relative norm from ``L`` to ``base``. - Defaults to the absolute norm down to `\QQ_p` or `\ZZ_p`. + - ``base`` -- a subfield of the parent `L` of this element; the norm is the + relative norm from ``L`` to ``base``. Defaults to the absolute norm down + to `\QQ_p` or `\ZZ_p`. EXAMPLES:: diff --git a/src/sage/libs/lrcalc/lrcalc.py b/src/sage/libs/lrcalc/lrcalc.py index b3c788ba57f..2a5144c0934 100644 --- a/src/sage/libs/lrcalc/lrcalc.py +++ b/src/sage/libs/lrcalc/lrcalc.py @@ -215,7 +215,7 @@ def lrcoef_unsafe(outer, inner1, inner2): INPUT: - - ``outer`` -- a partition (weakly decreasing list of non-negative integers) + - ``outer`` -- a partition (weakly decreasing list of nonnegative integers) - ``inner1`` -- a partition - ``inner2`` -- a partition @@ -246,7 +246,7 @@ def lrcoef(outer, inner1, inner2): INPUT: - - ``outer`` -- a partition (weakly decreasing list of non-negative integers) + - ``outer`` -- a partition (weakly decreasing list of nonnegative integers) - ``inner1`` -- a partition - ``inner2`` -- a partition @@ -280,9 +280,9 @@ def mult(part1, part2, maxrows=None, level=None, quantum=None) -> dict: - ``part1`` -- a partition - ``part2`` -- a partition - - ``maxrows`` -- (optional) an integer - - ``level`` -- (optional) an integer - - ``quantum`` -- (optional) an element of a ring + - ``maxrows`` -- integer (optional) + - ``level`` -- integer (optional) + - ``quantum`` -- an element of a ring (optional) If ``maxrows`` is specified, then only partitions with at most this number of rows are included in the result. @@ -364,7 +364,7 @@ def skew(outer, inner, maxrows=-1) -> dict: - ``outer`` -- a partition - ``inner`` -- a partition - - ``maxrows`` -- an integer or ``None`` + - ``maxrows`` -- integer or ``None`` If ``maxrows`` is specified, then only partitions with at most this number of rows are included in the result. @@ -389,9 +389,9 @@ def coprod(part, all=0) -> dict: INPUT: - ``part`` -- a partition - - ``all`` -- an integer + - ``all`` -- integer - If ``all`` is non-zero then all terms are included in the result. + If ``all`` is nonzero then all terms are included in the result. If ``all`` is zero, then only pairs of partitions ``(part1, part2)`` for which the weight of ``part1`` is greater than or equal to the weight of ``part2`` are included; the rest of the @@ -423,9 +423,9 @@ def mult_schubert(w1, w2, rank=0) -> dict: - ``w1`` -- a permutation - ``w2`` -- a permutation - - ``rank`` -- an integer + - ``rank`` -- integer - If ``rank`` is non-zero, then only permutations from the symmetric + If ``rank`` is nonzero, then only permutations from the symmetric group `S(\mathrm{rank})` are included in the result. EXAMPLES:: @@ -451,7 +451,7 @@ def lrskew(outer, inner, weight=None, maxrows=-1): - ``outer`` -- a partition - ``inner`` -- a partition - ``weight`` -- a partition (optional) - - ``maxrows`` -- a positive integer (optional) + - ``maxrows`` -- positive integer (optional) OUTPUT: an iterator of :class:`SkewTableau` diff --git a/src/sage/libs/m4ri.pxd b/src/sage/libs/m4ri.pxd index a9c6c792c05..7fbdd35b856 100644 --- a/src/sage/libs/m4ri.pxd +++ b/src/sage/libs/m4ri.pxd @@ -19,7 +19,7 @@ cdef extern from "m4ri/m4ri.h": cdef int m4ri_radix ############## - # Maintainance + # Maintenance ############## # builds all gray codes up to a certain size diff --git a/src/sage/libs/m4rie.pxd b/src/sage/libs/m4rie.pxd index 51bbf8303d9..c56e33b6945 100644 --- a/src/sage/libs/m4rie.pxd +++ b/src/sage/libs/m4rie.pxd @@ -173,7 +173,6 @@ cdef extern from "m4rie/m4rie.h": void mzd_slice_row_add(mzd_slice_t *A, size_t sourcerow, size_t destrow) - void mzd_slice_row_clear_offset(mzd_slice_t *A, size_t row, size_t coloffset) void mzd_slice_print(mzd_slice_t *A) diff --git a/src/sage/libs/meataxe.pxd b/src/sage/libs/meataxe.pxd index 0a928e19c37..a3bbc810cdc 100644 --- a/src/sage/libs/meataxe.pxd +++ b/src/sage/libs/meataxe.pxd @@ -113,7 +113,6 @@ cdef extern from "meataxe.h": Matrix_t *MatLoad(char *fn) except? NULL int MatSave(Matrix_t *mat, char *fn) except -1 - ## Basic Arithmetic ## general rule: dest is changed, src/mat are unchanged! Matrix_t *MatTransposed(Matrix_t *src) except NULL Matrix_t *MatAdd(Matrix_t *dest, Matrix_t *src) except NULL diff --git a/src/sage/libs/meataxe.pyx b/src/sage/libs/meataxe.pyx index 46559e9e99c..09c25b45155 100644 --- a/src/sage/libs/meataxe.pyx +++ b/src/sage/libs/meataxe.pyx @@ -41,7 +41,7 @@ cdef Matrix_t *rawMatrix(int Field, list entries) except NULL: INPUT: - - ``Field`` -- Integer, the field size + - ``Field`` -- integer; the field size - ``entries`` -- list of lists, the entries of the matrix, also defining the matrix dimensions. It is *not* tested that all rows in ``entries`` have the same length, and it is assumed that both diff --git a/src/sage/libs/meson.build b/src/sage/libs/meson.build new file mode 100644 index 00000000000..61b36da51f5 --- /dev/null +++ b/src/sage/libs/meson.build @@ -0,0 +1,86 @@ +sirocco = cc.find_library('sirocco', required: false, disabler: true) +# cannot be found via pkg-config +ecl = cc.find_library('ecl') +braiding = cc.find_library('braiding') +gc = cc.find_library('gc') +homfly = cc.find_library('homfly', has_headers: ['homfly.h']) + +py.install_sources( + 'all.py', + 'all__sagemath_coxeter3.py', + 'all__sagemath_meataxe.py', + 'all__sagemath_objects.py', + 'all__sagemath_sirocco.py', + 'ecl.pxd', + 'eclsig.h', + 'gmpxx.pxd', + 'iml.pxd', + 'm4ri.pxd', + 'm4rie.pxd', + 'meataxe.pxd', + subdir: 'sage/libs', +) + +extension_data = { + 'ecl' : files('ecl.pyx'), + 'homfly' : files('homfly.pyx'), + 'libecm' : files('libecm.pyx'), + 'sirocco': files('sirocco.pyx'), + 'meataxe': files('meataxe.pyx'), +} + +dependencies = [py_dep, braiding, cysignals, ecl, ecm, gc, gmp, homfly] + +foreach name, pyx : extension_data + deps = dependencies + if name == 'sirocco' + deps += [sirocco] + elif name == 'meataxe' + deps += [mtx, meataxe] + endif + + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: deps, + ) +endforeach + +extension_data_cpp = {'braiding': files('braiding.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_rings], + dependencies: dependencies, + ) +endforeach + +subdir('arb') +subdir('coxeter3') +install_subdir('cremona', install_dir: sage_install_dir / 'libs') +subdir('eclib') +subdir('flint') +subdir('gap') +subdir('giac') +subdir('glpk') +subdir('gmp') +subdir('gsl') +subdir('lcalc') +subdir('linbox') +install_subdir('linkages', install_dir: sage_install_dir / 'libs') +install_subdir('lrcalc', install_dir: sage_install_dir / 'libs') +install_subdir('mpfr', install_dir: sage_install_dir / 'libs') +subdir('mpmath') +install_subdir('mwrank', install_dir: sage_install_dir / 'libs') +subdir('ntl') +subdir('pari') +subdir('singular') +subdir('symmetrica') diff --git a/src/sage/libs/mpmath/ext_impl.pyx b/src/sage/libs/mpmath/ext_impl.pyx index d915d9f5a9b..fdbbfa80a3a 100644 --- a/src/sage/libs/mpmath/ext_impl.pyx +++ b/src/sage/libs/mpmath/ext_impl.pyx @@ -397,7 +397,7 @@ cdef MPF_to_fixed(mpz_t r, MPF *x, long prec, bint truncate): cdef int MPF_sgn(MPF *x) noexcept: """ - Gives the sign of an MPF (-1, 0, or 1). + Give the sign of an MPF (-1, 0, or 1). """ if x.special: if x.special == S_INF: @@ -409,7 +409,7 @@ cdef int MPF_sgn(MPF *x) noexcept: cdef void MPF_neg(MPF *r, MPF *s) noexcept: """ - Sets r = -s. MPF_neg(x, x) negates in place. + Set r = -s. MPF_neg(x, x) negates in place. """ if s.special: if s.special == S_ZERO: @@ -430,7 +430,7 @@ cdef void MPF_neg(MPF *r, MPF *s) noexcept: cdef void MPF_abs(MPF *r, MPF *s) noexcept: """ - Sets r = abs(s). MPF_abs(r, r) sets the absolute value in place. + Set r = abs(s). MPF_abs(r, r) sets the absolute value in place. """ if s.special: if s.special == S_NINF: @@ -1108,7 +1108,7 @@ cdef mpz_set_ln2(mpz_t x, int prec): cdef void _cy_exp_mpfr(mpz_t y, mpz_t x, int prec) noexcept: """ - Computes y = exp(x) for fixed-point numbers y and x using MPFR, + Compute y = exp(x) for fixed-point numbers y and x using MPFR, assuming that no overflow will occur. """ cdef mpfr_t yf, xf @@ -1124,7 +1124,7 @@ cdef void _cy_exp_mpfr(mpz_t y, mpz_t x, int prec) noexcept: cdef cy_exp_basecase(mpz_t y, mpz_t x, int prec): """ - Computes y = exp(x) for fixed-point numbers y and x, assuming + Compute y = exp(x) for fixed-point numbers y and x, assuming that x is small (|x| ~< 1). At small precisions, this function is equivalent to the exp_basecase function in mpmath.libmp.exp_fixed. @@ -1261,7 +1261,7 @@ cdef MPF_complex_sqrt(MPF *c, MPF *d, MPF *a, MPF *b, MPopts opts): bneg = MPF_sgn(b) <= 0 if apos: # real part - MPF_hypot(&t, a, b, wpopts) #t = abs(a+bi) + a + MPF_hypot(&t, a, b, wpopts) # t = abs(a+bi) + a MPF_add(&t, &t, a, wpopts) MPF_set(&u, &t) mpz_sub_ui(u.exp, u.exp, 1) # u = t / 2 @@ -1276,10 +1276,10 @@ cdef MPF_complex_sqrt(MPF *c, MPF *d, MPF *a, MPF *b, MPopts opts): MPF_sub(&t, &t, a, wpopts) MPF_set(&u, &t) mpz_sub_ui(u.exp, u.exp, 1) # u = t / 2 - MPF_sqrt(d, &u, opts) # im = sqrt(u) + MPF_sqrt(d, &u, opts) # im = sqrt(u) mpz_add_ui(t.exp, t.exp, 1) # t = 2*t MPF_sqrt(&u, &t, wpopts) # u = sqrt(t) - MPF_div(c, &v, &u, opts) # re = b / u + MPF_div(c, &v, &u, opts) # re = b / u if bneg: MPF_neg(c, c) MPF_neg(d, d) @@ -1421,7 +1421,7 @@ cdef MPF_set_ln2(MPF *x, MPopts opts): def exp_fixed(Integer x, int prec, ln2=None): """ - Returns a fixed-point approximation of exp(x) where x is a fixed-point + Return a fixed-point approximation of exp(x) where x is a fixed-point number. EXAMPLES:: @@ -1430,7 +1430,6 @@ def exp_fixed(Integer x, int prec, ln2=None): sage: y = exp_fixed(1<<53, 53) sage: float(y) / 2^53 2.718281828459044 - """ cdef Integer v cdef mpz_t n, t @@ -1456,7 +1455,7 @@ def exp_fixed(Integer x, int prec, ln2=None): def cos_sin_fixed(Integer x, int prec, pi2=None): """ - Returns fixed-point approximations of cos(x), sin(x) where + Return fixed-point approximations of cos(x), sin(x) where x is a fixed-point number. EXAMPLES:: @@ -1467,7 +1466,6 @@ def cos_sin_fixed(Integer x, int prec, pi2=None): 0.5403023058681398 sage: float(s) / 2^53 0.8414709848078965 - """ cdef Integer cv, sv cdef mpfr_t t, cf, sf @@ -1511,7 +1509,7 @@ cdef mpz_log_int(mpz_t v, mpz_t n, int prec): def log_int_fixed(n, long prec, ln2=None): """ - Returns fixed-point approximation of log(n). + Return fixed-point approximation of log(n). EXAMPLES:: @@ -1520,7 +1518,6 @@ def log_int_fixed(n, long prec, ln2=None): 1.6094379124341003 sage: float(log_int_fixed(5, 53)) / 2^53 # exercise cache 1.6094379124341003 - """ global log_int_cache_initialized cdef Integer t @@ -1548,7 +1545,7 @@ def log_int_fixed(n, long prec, ln2=None): cdef _MPF_cos_python(MPF *c, MPF *x, MPopts opts): """ - Computes c = cos(x) by calling the mpmath.libmp Python implementation. + Compute c = cos(x) by calling the mpmath.libmp Python implementation. """ from mpmath.libmp.libelefun import mpf_cos_sin ct = mpf_cos_sin(MPF_to_tuple(x), opts.prec, @@ -1557,7 +1554,7 @@ cdef _MPF_cos_python(MPF *c, MPF *x, MPopts opts): cdef _MPF_sin_python(MPF *s, MPF *x, MPopts opts): """ - Computes s = sin(x) by calling the mpmath.libmp Python implementation. + Compute s = sin(x) by calling the mpmath.libmp Python implementation. """ from mpmath.libmp.libelefun import mpf_cos_sin st = mpf_cos_sin(MPF_to_tuple(x), opts.prec, @@ -1992,7 +1989,6 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, This function is not intended to be called directly; it is wrapped by the hypsum_internal function in ext_main.pyx. - """ cdef long i, j, k, n, p_mag, cancellable_real, MAX, magn cdef int have_complex_param, have_complex_arg, have_complex diff --git a/src/sage/libs/mpmath/ext_libmp.pyx b/src/sage/libs/mpmath/ext_libmp.pyx index 10d1b32eb36..487a12d45bc 100644 --- a/src/sage/libs/mpmath/ext_libmp.pyx +++ b/src/sage/libs/mpmath/ext_libmp.pyx @@ -218,7 +218,6 @@ def mpf_pow(tuple x, tuple y, int prec, str rnd='d'): sage: z = mpf_pow(x, y, 53, 'n') sage: to_float(z) 8.0 - """ cdef MPopts opts MPF_set_tuple(&tmp1, x) diff --git a/src/sage/libs/mpmath/ext_main.pyx b/src/sage/libs/mpmath/ext_main.pyx index 29d524536ea..96111f7b942 100644 --- a/src/sage/libs/mpmath/ext_main.pyx +++ b/src/sage/libs/mpmath/ext_main.pyx @@ -114,7 +114,7 @@ cdef __isint(MPF *v): cdef int MPF_set_any(MPF *re, MPF *im, x, MPopts opts, bint str_tuple_ok) except -1: """ - Sets re + im*i = x, where x is any Python number. + Set re + im*i = x, where x is any Python number. Returns 0 if unable to coerce x; 1 if x is real and re was set; 2 if x is complex and both re and im were set. @@ -386,13 +386,13 @@ cdef MPopts global_opts global_context = None cdef class Context: - cdef public mpf, mpc, constant #, def_mp_function + cdef public mpf, mpc, constant # , def_mp_function cdef public trap_complex cdef public pretty def __cinit__(ctx): """ - At present, only a single global context should exist :: + At present, only a single global context should exist:: sage: from mpmath import mp sage: type(mp) @@ -409,9 +409,9 @@ cdef class Context: def default(ctx): """ - Sets defaults. + Set defaults. - TESTS :: + TESTS:: sage: import mpmath sage: mpmath.mp.prec = 100 @@ -426,7 +426,7 @@ cdef class Context: def _get_prec(ctx): """ - Controls the working precision in bits :: + Controls the working precision in bits:: sage: from mpmath import mp sage: mp.prec = 100 @@ -440,7 +440,7 @@ cdef class Context: def _set_prec(ctx, prec): """ - Controls the working precision in bits :: + Controls the working precision in bits:: sage: from mpmath import mp sage: mp.prec = 100 @@ -454,7 +454,7 @@ cdef class Context: def _set_dps(ctx, n): """ - Controls the working precision in decimal digits :: + Controls the working precision in decimal digits:: sage: from mpmath import mp sage: mp.dps = 100 @@ -468,7 +468,7 @@ cdef class Context: def _get_dps(ctx): """ - Controls the working precision in decimal digits :: + Controls the working precision in decimal digits:: sage: from mpmath import mp sage: mp.dps = 100 @@ -487,7 +487,7 @@ cdef class Context: def _get_prec_rounding(ctx): """ - Returns the precision and rounding mode :: + Return the precision and rounding mode:: sage: from mpmath import mp sage: mp._get_prec_rounding() @@ -499,7 +499,7 @@ cdef class Context: cpdef mpf make_mpf(ctx, tuple v): """ - Creates an mpf from tuple data :: + Create an mpf from tuple data:: sage: import mpmath sage: float(mpmath.mp.make_mpf((0,1,-1,1))) @@ -512,7 +512,7 @@ cdef class Context: cpdef mpc make_mpc(ctx, tuple v): """ - Creates an mpc from tuple data :: + Create an mpc from tuple data:: sage: import mpmath sage: complex(mpmath.mp.make_mpc(((0,1,-1,1), (1,1,-2,1)))) @@ -526,7 +526,7 @@ cdef class Context: def convert(ctx, x, strings=True): """ - Converts *x* to an ``mpf``, ``mpc`` or ``mpi``. If *x* is of type ``mpf``, + Convert *x* to an ``mpf``, ``mpc`` or ``mpi``. If *x* is of type ``mpf``, ``mpc``, ``int``, ``float``, ``complex``, the conversion will be performed losslessly. @@ -534,7 +534,7 @@ cdef class Context: working precision. Strings representing fractions or complex numbers are permitted. - TESTS :: + TESTS:: sage: from mpmath import mp, convert sage: mp.dps = 15; mp.pretty = False @@ -546,7 +546,6 @@ cdef class Context: mpf('0.75') sage: convert('2+3j') mpc(real='2.0', imag='3.0') - """ cdef mpf rr cdef mpc rc @@ -614,7 +613,6 @@ cdef class Context: True sage: isinf(mpc(inf,3)) True - """ cdef int s, t, typ if isinstance(x, mpf): @@ -645,7 +643,7 @@ cdef class Context: complex number *x* is considered "normal" if its magnitude is normal. - TESTS :: + TESTS:: sage: from mpmath import isnormal, inf, nan, mpc sage: isnormal(3) @@ -686,7 +684,7 @@ cdef class Context: Return *True* if *x* is integer-valued; otherwise return *False*. - TESTS :: + TESTS:: sage: from mpmath import isint, mpf, inf sage: isint(3) @@ -737,7 +735,7 @@ cdef class Context: def fsum(ctx, terms, bint absolute=False, bint squared=False): """ - Calculates a sum containing a finite number of terms (for infinite + Calculate a sum containing a finite number of terms (for infinite series, see :func:`nsum`). The terms will be converted to mpmath numbers. For len(terms) > 2, this function is generally faster and produces more accurate results than the builtin @@ -746,7 +744,7 @@ cdef class Context: With ``squared=True`` each term is squared, and with ``absolute=True`` the absolute value of each term is used. - TESTS :: + TESTS:: sage: from mpmath import mp, fsum sage: mp.dps = 15; mp.pretty = False @@ -859,7 +857,7 @@ cdef class Context: def fdot(ctx, A, B=None, bint conjugate=False): r""" - Compute the dot product of the iterables `A` and `B`, + Compute the dot product of the iterables `A` and `B`. .. MATH:: @@ -982,10 +980,9 @@ cdef class Context: type of the parameter, and with x converted to the canonical mpmath type. - TESTS :: + TESTS:: sage: from mpmath import mp - sage: mp.pretty = True sage: (x, T) = mp._convert_param(3) sage: (x, type(x).__name__, T) (3, 'int', 'Z') @@ -993,13 +990,12 @@ cdef class Context: sage: (x, type(x).__name__, T) (mpq(5,2), 'mpq', 'Q') sage: (x, T) = mp._convert_param(2.3) - sage: (x, type(x).__name__, T) - (2.3, 'mpf', 'R') + sage: (str(x), type(x).__name__, T) + ('2.3', 'mpf', 'R') sage: (x, T) = mp._convert_param(2+3j) sage: (x, type(x).__name__, T) - ((2.0 + 3.0j), 'mpc', 'C') + (mpc(real='2.0', imag='3.0'), 'mpc', 'C') sage: mp.pretty = False - """ cdef MPF v cdef bint ismpf, ismpc @@ -1059,7 +1055,6 @@ cdef class Context: TESTS:: sage: from mpmath import * - sage: mp.pretty = True sage: mag(10), mag(10.0), mag(mpf(10)), int(ceil(log(10,2))) (4, 4, 4, 4) sage: mag(10j), mag(10+10j) @@ -1067,9 +1062,9 @@ cdef class Context: sage: mag(0.01), int(ceil(log(0.01,2))) (-6, -6) sage: mag(0), mag(inf), mag(-inf), mag(nan) - (-inf, +inf, +inf, nan) + (mpf('-inf'), mpf('+inf'), mpf('+inf'), mpf('nan')) - :: + :: sage: class MyInt(int): ....: pass @@ -1077,7 +1072,6 @@ cdef class Context: ....: pass sage: mag(MyInt(10)) 4 - """ cdef int typ if isinstance(x, (int, Integer)): @@ -1133,7 +1127,7 @@ cdef class Context: Create a high-level mpmath function from base functions working on mpf, mpc and mpi tuple data. - TESTS :: + TESTS:: sage: from mpmath import mp sage: mp.pretty = False @@ -1141,7 +1135,6 @@ cdef class Context: sage: g = mp._wrap_libmp_function(f) sage: g(mp.mpf(2)) mpf('2.0') - """ name = mpf_f.__name__[4:] doc = function_docs.__dict__.get(name, "Computes the %s of x" % doc) @@ -1153,19 +1146,18 @@ cdef class Context: @classmethod def _wrap_specfun(cls, name, f, wrap): """ - Adds the given function as a method to the context object, + Add the given function as a method to the context object, optionally wrapping it to do automatic conversions and allocating a small number of guard bits to suppress typical roundoff error. - TESTS :: + TESTS:: sage: from mpmath import mp sage: mp._wrap_specfun("foo", lambda ctx, x: ctx.prec + x, True) sage: mp.pretty = False; mp.prec = 53 sage: mp.foo(5) # 53 + 10 guard bits + 5 mpf('68.0') - """ doc = function_docs.__dict__.get(name, getattr(f, '__doc__', '')) if wrap: @@ -1199,7 +1191,7 @@ cdef class Context: """ Square root of an mpmath number x, using the Sage mpmath backend. - TESTS :: + TESTS:: sage: from mpmath import mp sage: mp.dps = 15 @@ -1209,7 +1201,6 @@ cdef class Context: (0.0 + 1.4142135623731j) sage: print(mp.sqrt(2+2j)) (1.55377397403004 + 0.643594252905583j) - """ cdef MPopts opts cdef int typx @@ -1245,7 +1236,6 @@ cdef class Context: 7.38905609893065 sage: print(mp.exp(2+2j)) (-3.07493232063936 + 6.71884969742825j) - """ cdef MPopts opts cdef int typx @@ -1277,7 +1267,6 @@ cdef class Context: -0.416146836547142 sage: print(mp.cos(2+2j)) (-1.56562583531574 - 3.29789483631124j) - """ cdef MPopts opts cdef int typx @@ -1314,7 +1303,6 @@ cdef class Context: 0.909297426825682 sage: print(mp.sin(2+2j)) (3.42095486111701 - 1.50930648532362j) - """ cdef MPopts opts cdef int typx @@ -1352,7 +1340,6 @@ cdef class Context: (0.693147180559945 + 3.14159265358979j) sage: print(mp.ln(2+2j)) (1.03972077083992 + 0.785398163397448j) - """ cdef MPopts opts cdef int typx @@ -1403,7 +1390,7 @@ cdef class wrapped_libmp_function: Create a high-level mpmath function from base functions working on mpf, mpc and mpi tuple data. - TESTS :: + TESTS:: sage: from sage.libs.mpmath.ext_main import wrapped_libmp_function sage: from mpmath import mp @@ -1431,7 +1418,7 @@ cdef class wrapped_libmp_function: """ A wrapped mpmath library function performs automatic conversions and uses the default working precision - unless overridden :: + unless overridden:: sage: from mpmath import mp sage: mp.sinh(2) @@ -1491,10 +1478,10 @@ cdef class wrapped_specfun: def __init__(self, name, f): """ - Creates an object holding a wrapped mpmath function + Create an object holding a wrapped mpmath function along with metadata (name and documentation). - TESTS :: + TESTS:: sage: import mpmath sage: from sage.libs.mpmath.ext_main import wrapped_specfun @@ -1510,14 +1497,13 @@ cdef class wrapped_specfun: """ Call wrapped mpmath function. Arguments are automatically converted to mpmath number, and the internal working precision is increased - by a few bits to suppress typical rounding errors :: + by a few bits to suppress typical rounding errors:: sage: from mpmath import mp sage: from sage.libs.mpmath.ext_main import wrapped_specfun sage: f = wrapped_specfun("f", lambda ctx, x: x + ctx.prec) sage: f("1") # 53 + 10 guard bits + 1 mpf('64.0') - """ cdef int origprec args = [global_context.convert(a) for a in args] @@ -1535,7 +1521,7 @@ cdef class mpnumber: def __richcmp__(self, other, int op): """ Comparison of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf, mpc sage: mpf(3) == mpc(3) @@ -1550,14 +1536,13 @@ cdef class mpnumber: Traceback (most recent call last): ... ValueError: cannot compare complex numbers - """ return binop(OP_RICHCMP+op, self, other, global_opts) def __add__(self, other): """ Addition of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf, mpc sage: mpf(3) + mpc(3) @@ -1570,7 +1555,7 @@ cdef class mpnumber: def __sub__(self, other): """ Subtraction of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf, mpc sage: mpf(5) - mpc(3) @@ -1583,7 +1568,7 @@ cdef class mpnumber: def __mul__(self, other): """ Multiplication of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf, mpc sage: mpf(5) * mpc(3) @@ -1596,7 +1581,7 @@ cdef class mpnumber: def __truediv__(self, other): """ Division of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf, mpc sage: mpf(10) / mpc(5) @@ -1609,7 +1594,7 @@ cdef class mpnumber: def __mod__(self, other): """ Remainder of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf sage: mpf(12) % float(7) @@ -1620,7 +1605,7 @@ cdef class mpnumber: def __pow__(self, other, mod): """ Exponentiation of mpmath numbers. Compatible numerical types - are automatically converted to mpmath numbers :: + are automatically converted to mpmath numbers:: sage: from mpmath import mpf, mpc sage: mpf(10) ** mpc(3) @@ -1635,7 +1620,7 @@ cdef class mpnumber: def ae(s, t, rel_eps=None, abs_eps=None): """ Check if two numbers are approximately equal to within the specified - tolerance (see mp.almosteq for documentation) :: + tolerance (see mp.almosteq for documentation):: sage: from mpmath import mpf, mpc sage: mpf(3).ae(mpc(3,1e-10)) @@ -1654,7 +1639,7 @@ cdef class mpf_base(mpnumber): def __hash__(self): """ - Support hashing of derived classes :: + Support hashing of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1666,7 +1651,7 @@ cdef class mpf_base(mpnumber): def __repr__(self): """ - Support repr() of derived classes :: + Support repr() of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1681,7 +1666,7 @@ cdef class mpf_base(mpnumber): def __str__(self): """ - Support str() of derived classes :: + Support str() of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1694,7 +1679,7 @@ cdef class mpf_base(mpnumber): @property def real(self): """ - Support real part of derived classes :: + Support real part of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1707,7 +1692,7 @@ cdef class mpf_base(mpnumber): @property def imag(self): """ - Support imaginary part of derived classes :: + Support imaginary part of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1719,7 +1704,7 @@ cdef class mpf_base(mpnumber): def conjugate(self): """ - Support complex conjugate of derived classes :: + Support complex conjugate of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1732,7 +1717,7 @@ cdef class mpf_base(mpnumber): @property def man(self): """ - Support mantissa extraction of derived classes :: + Support mantissa extraction of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1745,7 +1730,7 @@ cdef class mpf_base(mpnumber): @property def exp(self): """ - Support exponent extraction of derived classes :: + Support exponent extraction of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1758,7 +1743,7 @@ cdef class mpf_base(mpnumber): @property def bc(self): """ - Support bitcount extraction of derived classes :: + Support bitcount extraction of derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1771,7 +1756,7 @@ cdef class mpf_base(mpnumber): # XXX: optimize def __int__(self): """ - Support integer conversion for derived classes :: + Support integer conversion for derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1783,7 +1768,7 @@ cdef class mpf_base(mpnumber): def __float__(self): """ - Support float conversion for derived classes :: + Support float conversion for derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1795,7 +1780,7 @@ cdef class mpf_base(mpnumber): def __complex__(self): """ - Support complex conversion for derived classes :: + Support complex conversion for derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1807,7 +1792,7 @@ cdef class mpf_base(mpnumber): def to_fixed(self, prec): """ - Support conversion to a fixed-point integer for derived classes :: + Support conversion to a fixed-point integer for derived classes:: sage: from mpmath import mpf sage: from sage.libs.mpmath.ext_main import mpf_base @@ -1838,7 +1823,7 @@ cdef class mpf(mpf_base): Create an mpf from a recognized type, optionally rounding to a precision and in a direction different from the default. - TESTS :: + TESTS:: sage: from mpmath import mpf sage: mpf() @@ -1859,7 +1844,6 @@ cdef class mpf(mpf_base): mpf('0.2998046875') sage: mpf("0.3", prec=10, rounding='u') mpf('0.30029296875') - """ cdef MPopts opts opts = global_opts @@ -1872,7 +1856,7 @@ cdef class mpf(mpf_base): def __reduce__(self): """ - Support pickling :: + Support pickling:: sage: from mpmath import mpf sage: loads(dumps(mpf(0.5))) == mpf(0.5) @@ -1882,8 +1866,8 @@ cdef class mpf(mpf_base): def _get_mpf(self): """ - Returns internal representation of self as a tuple - of (sign bit, mantissa, exponent, bitcount) :: + Return internal representation of ``self`` as a tuple + of (sign bit, mantissa, exponent, bitcount):: sage: from mpmath import mp sage: mp.mpf(-3)._mpf_ @@ -1893,7 +1877,7 @@ cdef class mpf(mpf_base): def _set_mpf(self, v): """ - Sets tuple value of self (warning: unsafe) :: + Set tuple value of ``self`` (warning: unsafe):: sage: from mpmath import mp sage: x = mp.mpf(-3) @@ -1907,7 +1891,7 @@ cdef class mpf(mpf_base): def __bool__(self): """ - Returns whether the number is nonzero :: + Return whether the number is nonzero:: sage: from mpmath import mpf sage: bool(mpf(3.5)) @@ -1920,7 +1904,7 @@ cdef class mpf(mpf_base): def __hash__(self): """ Hash values are compatible with builtin Python floats - when the precision is small enough :: + when the precision is small enough:: sage: from mpmath import mpf sage: hash(mpf(2.5)) == hash(float(2.5)) @@ -1933,7 +1917,7 @@ cdef class mpf(mpf_base): @property def real(self): """ - Real part, leaves self unchanged :: + Real part, leaves ``self`` unchanged:: sage: from mpmath import mpf sage: mpf(2.5).real @@ -1944,7 +1928,7 @@ cdef class mpf(mpf_base): @property def imag(self): """ - Imaginary part, equal to zero :: + Imaginary part, equal to zero:: sage: from mpmath import mpf sage: mpf(2.5).imag @@ -1954,7 +1938,7 @@ cdef class mpf(mpf_base): def conjugate(self): """ - Complex conjugate, leaves self unchanged :: + Complex conjugate, leaves ``self`` unchanged:: sage: from mpmath import mpf sage: mpf(2.5).conjugate() @@ -1965,8 +1949,8 @@ cdef class mpf(mpf_base): @property def man(self): """ - Returns the binary mantissa of self. The result is a Sage - integer :: + Return the binary mantissa of ``self``. The result is a Sage + integer:: sage: from mpmath import mpf sage: mpf(-500.5).man @@ -1979,7 +1963,7 @@ cdef class mpf(mpf_base): @property def exp(self): """ - Returns the binary exponent of self :: + Return the binary exponent of ``self``:: sage: from mpmath import mpf sage: mpf(1/64.).exp @@ -1990,7 +1974,7 @@ cdef class mpf(mpf_base): @property def bc(self): """ - Returns the number of bits in the mantissa of self :: + Return the number of bits in the mantissa of ``self``:: sage: from mpmath import mpf sage: mpf(-256).bc @@ -2002,7 +1986,7 @@ cdef class mpf(mpf_base): def to_fixed(self, long prec): """ - Convert to a fixed-point integer of the given precision :: + Convert to a fixed-point integer of the given precision:: sage: from mpmath import mpf sage: mpf(7.25).to_fixed(30) @@ -2019,7 +2003,7 @@ cdef class mpf(mpf_base): def __int__(self): """ - Convert to a Python integer (truncating if necessary) :: + Convert to a Python integer (truncating if necessary):: sage: from mpmath import mpf sage: int(mpf(2.5)) @@ -2032,7 +2016,7 @@ cdef class mpf(mpf_base): def __float__(self): """ - Convert to a double-precision Python float :: + Convert to a double-precision Python float:: sage: from mpmath import mpf sage: float(mpf(2.5)) @@ -2044,7 +2028,7 @@ cdef class mpf(mpf_base): def __getstate__(self): """ - Support pickling :: + Support pickling:: sage: from mpmath import mpf sage: loads(dumps(mpf(3))) == mpf(3) @@ -2054,7 +2038,7 @@ cdef class mpf(mpf_base): def __setstate__(self, val): """ - Support pickling :: + Support pickling:: sage: from mpmath import mpf sage: loads(dumps(mpf(3))) == mpf(3) @@ -2064,11 +2048,10 @@ cdef class mpf(mpf_base): def __cinit__(self): """ - Create a new mpf :: + Create a new mpf:: sage: from mpmath import mpf sage: x = mpf() - """ MPF_init(&self.value) @@ -2077,7 +2060,7 @@ cdef class mpf(mpf_base): def __neg__(s): """ - Negates self, rounded to the current working precision :: + Negate ``self``, rounded to the current working precision:: sage: from mpmath import mpf sage: -mpf(2) @@ -2090,7 +2073,7 @@ cdef class mpf(mpf_base): def __pos__(s): """ - Rounds the number to the current working precision :: + Round the number to the current working precision:: sage: from mpmath import mp, mpf sage: mp.prec = 200 @@ -2110,8 +2093,8 @@ cdef class mpf(mpf_base): def __abs__(s): """ - Computes the absolute value, rounded to the current - working precision :: + Compute the absolute value, rounded to the current + working precision:: sage: from mpmath import mpf sage: abs(mpf(-2)) @@ -2124,8 +2107,8 @@ cdef class mpf(mpf_base): def sqrt(s): """ - Computes the square root, rounded to the current - working precision :: + Compute the square root, rounded to the current + working precision:: sage: from mpmath import mpf sage: mpf(2).sqrt() @@ -2135,9 +2118,12 @@ cdef class mpf(mpf_base): MPF_sqrt(&r.value, &s.value, global_opts) return r + def __round__(self, *args): + return round(float(self), *args) + def __richcmp__(self, other, int op): """ - Compares numbers :: + Compare numbers:: sage: from mpmath import mpf sage: mpf(3) > 2 @@ -2152,7 +2138,7 @@ cdef class mpf(mpf_base): cdef class constant(mpf_base): """ - Represents a mathematical constant with dynamic precision. + Represent a mathematical constant with dynamic precision. When printed or used in an arithmetic operation, a constant is converted to a regular mpf at the working precision. A regular mpf can also be obtained using the operation +x. @@ -2162,8 +2148,8 @@ cdef class constant(mpf_base): def __init__(self, func, name, docname=''): """ - Creates a constant from a function computing an mpf - tuple value :: + Create a constant from a function computing an mpf + tuple value:: sage: from mpmath import mp, mpf sage: q = mp.constant(lambda prec, rnd: mpf(0.25)._mpf_, "quarter", "q") @@ -2171,7 +2157,6 @@ cdef class constant(mpf_base): sage: q + 1 mpf('1.25') - """ self.name = name self.func = func @@ -2180,14 +2165,13 @@ cdef class constant(mpf_base): def __call__(self, prec=None, dps=None, rounding=None): """ Calling a constant is equivalent to rounding it. A - custom precision and rounding direction can also be passed :: + custom precision and rounding direction can also be passed:: sage: from mpmath import pi sage: print(pi(dps=5, rounding='d')) 3.1415901184082 sage: print(pi(dps=5, rounding='u')) 3.14159393310547 - """ prec2 = global_opts.prec rounding2 = rndmode_to_python(global_opts.rounding) @@ -2199,8 +2183,8 @@ cdef class constant(mpf_base): @property def _mpf_(self): """ - Returns the tuple value of the constant as if rounded - to an mpf at the present working precision :: + Return the tuple value of the constant as if rounded + to an mpf at the present working precision:: sage: from mpmath import pi sage: pi._mpf_ @@ -2214,17 +2198,17 @@ cdef class constant(mpf_base): def __repr__(self): """ - Represents self as a string. With mp.pretty=False, the - representation differs from that of an ordinary mpf :: + Represent ``self`` as a string. With mp.pretty=False, the + representation differs from that of an ordinary mpf:: - sage: from mpmath import mp, pi - sage: mp.pretty = True - sage: repr(pi) + sage: from mpmath import mp + sage: mp2 = mp.clone() + sage: mp2.pretty = True + sage: repr(mp2.pi) '3.14159265358979' - sage: mp.pretty = False - sage: repr(pi) + sage: mp2.pretty = False + sage: repr(mp2.pi) '' - """ if global_context.pretty: return str(self) @@ -2232,7 +2216,7 @@ cdef class constant(mpf_base): def __bool__(self): """ - Returns whether the constant is nonzero :: + Return whether the constant is nonzero:: sage: from mpmath import pi sage: bool(pi) @@ -2242,7 +2226,7 @@ cdef class constant(mpf_base): def __neg__(self): """ - Negates the constant :: + Negate the constant:: sage: from mpmath import pi sage: -pi @@ -2252,7 +2236,7 @@ cdef class constant(mpf_base): def __pos__(self): """ - Instantiates the constant as an mpf :: + Instantiate the constant as an mpf:: sage: from mpmath import pi sage: +pi @@ -2262,7 +2246,7 @@ cdef class constant(mpf_base): def __abs__(self): """ - Computes the absolute value of the constant :: + Compute the absolute value of the constant:: sage: from mpmath import pi sage: abs(pi) @@ -2272,7 +2256,7 @@ cdef class constant(mpf_base): def sqrt(self): """ - Computes the square root of the constant :: + Compute the square root of the constant:: sage: from mpmath import pi sage: print(pi.sqrt()) @@ -2283,7 +2267,7 @@ cdef class constant(mpf_base): # XXX: optimize def to_fixed(self, prec): """ - Convert to a fixed-point integer :: + Convert to a fixed-point integer:: sage: from mpmath import pi sage: float(pi.to_fixed(10) / 2.0**10) @@ -2300,7 +2284,7 @@ cdef class constant(mpf_base): # WHY is this method not inherited from the base class by Cython? def __hash__(self): """ - A constant hashes as if instantiated to a number :: + A constant hashes as if instantiated to a number:: sage: from mpmath import pi sage: hash(pi) == hash(+pi) @@ -2310,7 +2294,7 @@ cdef class constant(mpf_base): def __richcmp__(self, other, int op): """ - A constant hashes as if instantiated to a number :: + A constant hashes as if instantiated to a number:: sage: from mpmath import pi sage: pi == pi @@ -2335,12 +2319,11 @@ cdef class mpc(mpnumber): def __init__(self, real=0, imag=0): """ - Creates a new mpc:: + Create a new mpc:: sage: from mpmath import mpc sage: mpc() == mpc(0,0) == mpc(1,0)-1 == 0 True - """ cdef int typx, typy typx = MPF_set_any(&self.re, &self.im, real, global_opts, 1) @@ -2353,11 +2336,10 @@ cdef class mpc(mpnumber): def __cinit__(self): """ - Create a new mpc :: + Create a new mpc:: sage: from mpmath import mpc sage: x = mpc() - """ MPF_init(&self.re) MPF_init(&self.im) @@ -2368,7 +2350,7 @@ cdef class mpc(mpnumber): def __reduce__(self): """ - Support pickling :: + Support pickling:: sage: from mpmath import mpc sage: loads(dumps(mpc(1,3))) == mpc(1,3) @@ -2378,7 +2360,7 @@ cdef class mpc(mpnumber): def __setstate__(self, val): """ - Support pickling :: + Support pickling:: sage: from mpmath import mpc sage: loads(dumps(mpc(1,3))) == mpc(1,3) @@ -2388,14 +2370,15 @@ cdef class mpc(mpnumber): def __repr__(self): """ - TESTS :: + TESTS:: sage: from mpmath import mp - sage: mp.pretty = True - sage: repr(mp.mpc(2,3)) + sage: mp2 = mp.clone() + sage: mp2.pretty = True + sage: repr(mp2.mpc(2,3)) '(2.0 + 3.0j)' - sage: mp.pretty = False - sage: repr(mp.mpc(2,3)) + sage: mp2.pretty = False + sage: repr(mp2.mpc(2,3)) "mpc(real='2.0', imag='3.0')" """ if global_context.pretty: @@ -2406,7 +2389,7 @@ cdef class mpc(mpnumber): def __str__(s): """ - TESTS :: + TESTS:: sage: from mpmath import mp sage: str(mp.mpc(2,3)) @@ -2416,7 +2399,7 @@ cdef class mpc(mpnumber): def __bool__(self): """ - TESTS :: + TESTS:: sage: from mpmath import mp sage: bool(mp.mpc(0,1)) @@ -2434,7 +2417,7 @@ cdef class mpc(mpnumber): def __complex__(self): """ - TESTS :: + TESTS:: sage: from mpmath import mp sage: complex(mp.mpc(1,2)) == complex(1,2) @@ -2444,7 +2427,7 @@ cdef class mpc(mpnumber): def _get_mpc(self): """ - Returns tuple value of self :: + Return tuple value of ``self``:: sage: from mpmath import mp sage: mp.mpc(2,3)._mpc_ @@ -2454,7 +2437,7 @@ cdef class mpc(mpnumber): def _set_mpc(self, tuple v): """ - Sets tuple value of self (warning: unsafe) :: + Set tuple value of ``self`` (warning: unsafe):: sage: from mpmath import mp sage: x = mp.mpc(2,3) @@ -2470,7 +2453,7 @@ cdef class mpc(mpnumber): @property def real(self): """ - Returns the real part of self as an mpf :: + Return the real part of ``self`` as an mpf:: sage: from mpmath import mp sage: mp.mpc(1,2).real @@ -2483,7 +2466,7 @@ cdef class mpc(mpnumber): @property def imag(self): """ - Returns the imaginary part of self as an mpf :: + Return the imaginary part of ``self`` as an mpf:: sage: from mpmath import mp sage: mp.mpc(1,2).imag @@ -2495,7 +2478,7 @@ cdef class mpc(mpnumber): def __hash__(self): """ - Returns the hash value of self :: + Return the hash value of ``self``:: EXAMPLES:: @@ -2515,7 +2498,7 @@ cdef class mpc(mpnumber): def __neg__(s): """ - Negates the number :: + Negate the number:: sage: from mpmath import mpc sage: -mpc(1,2) @@ -2530,7 +2513,7 @@ cdef class mpc(mpnumber): def conjugate(s): """ - Returns the complex conjugate :: + Return the complex conjugate:: sage: from mpmath import mpc sage: mpc(1,2).conjugate() @@ -2545,7 +2528,7 @@ cdef class mpc(mpnumber): def __pos__(s): """ - Rounds the number to the current working precision :: + Round the number to the current working precision:: sage: from mpmath import mp sage: mp.prec = 200 @@ -2567,7 +2550,7 @@ cdef class mpc(mpnumber): def __abs__(s): """ - Returns the absolute value of self :: + Return the absolute value of ``self``:: sage: from mpmath import mpc sage: abs(mpc(3,4)) @@ -2579,7 +2562,7 @@ cdef class mpc(mpnumber): def __richcmp__(self, other, int op): """ - Complex numbers can be compared for equality :: + Complex numbers can be compared for equality:: sage: from mpmath import mpc sage: mpc(2,3) == complex(2,3) diff --git a/src/sage/libs/mpmath/meson.build b/src/sage/libs/mpmath/meson.build new file mode 100644 index 00000000000..4659da1563a --- /dev/null +++ b/src/sage/libs/mpmath/meson.build @@ -0,0 +1,27 @@ +py.install_sources( + '__init__.py', + 'all.py', + 'ext_impl.pxd', + 'ext_main.pxd', + 'utils.pxd', + subdir: 'sage/libs/mpmath', +) + +extension_data = { + 'ext_impl' : files('ext_impl.pyx'), + 'ext_libmp' : files('ext_libmp.pyx'), + 'ext_main' : files('ext_main.pyx'), + 'utils' : files('utils.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/mpmath', + install: true, + include_directories: [inc_cpython, inc_ext, inc_rings], + dependencies: [py_dep, cypari2, cysignals, gmp, mpfr], + ) +endforeach + diff --git a/src/sage/libs/mpmath/utils.pyx b/src/sage/libs/mpmath/utils.pyx index b7a4f532823..0123d4190be 100644 --- a/src/sage/libs/mpmath/utils.pyx +++ b/src/sage/libs/mpmath/utils.pyx @@ -35,7 +35,6 @@ cpdef int bitcount(n) noexcept: 2 sage: bitcount(2L) 2 - """ cdef Integer m if isinstance(n, Integer): @@ -64,7 +63,6 @@ cpdef isqrt(n): 3 sage: isqrt(10L) 3 - """ cdef Integer m, y if isinstance(n, Integer): @@ -317,7 +315,6 @@ def sage_to_mpmath(x, prec): (mpf('0.5'), mpf('1.5')) sage: a.sage_to_mpmath({'n':0.5}, 53) {'n': mpf('0.5')} - """ cdef RealNumber y if isinstance(x, Element): @@ -421,7 +418,6 @@ def call(func, *args, **kwargs): sage: a.call(a.log, -1.0r, parent=float) 3.141592653589793j - """ from mpmath import mp orig = mp.prec diff --git a/src/sage/libs/ntl/GF2X.pxd b/src/sage/libs/ntl/GF2X.pxd index 9342f63244c..2d3b5edafad 100644 --- a/src/sage/libs/ntl/GF2X.pxd +++ b/src/sage/libs/ntl/GF2X.pxd @@ -58,7 +58,6 @@ cdef extern from "ntlwrap.h": void GF2XModulus_build "build"(GF2XModulus_c F, GF2X_c f) # MUST be called before using the modulus long GF2XModulus_deg "deg"(GF2XModulus_c F) - GF2X_c GF2XModulus_GF2X "GF2X" (GF2XModulus_c m) GF2X_c GF2X_IrredPolyMod "IrredPolyMod" (GF2X_c g, GF2XModulus_c F) @@ -72,7 +71,6 @@ cdef extern from "ntlwrap.h": void GF2X_PowerXPlusAMod_pre "PowerXPlusAMod"(GF2X_c x, GF2_c a, GF2_c e, GF2XModulus_c F) void GF2X_PowerXPlusAMod_long_pre "PowerXPlusAMod"(GF2X_c x, GF2_c a, long e, GF2XModulus_c F) - # x = g(h) mod f; deg(h) < n void GF2X_CompMod "CompMod"(GF2X_c x, GF2X_c g, GF2X_c h, GF2XModulus_c F) # xi = gi(h) mod f (i=1,2), deg(h) < n. diff --git a/src/sage/libs/ntl/ZZ_pEX.pxd b/src/sage/libs/ntl/ZZ_pEX.pxd index 78be3ee13ea..df3a38602ff 100644 --- a/src/sage/libs/ntl/ZZ_pEX.pxd +++ b/src/sage/libs/ntl/ZZ_pEX.pxd @@ -82,6 +82,8 @@ cdef extern from "ntlwrap.h": void ZZ_pEX_DivRem_pre "DivRem"(ZZ_pEX_c q, ZZ_pEX_c r, ZZ_pEX_c a, ZZ_pEX_Modulus_c F) void ZZ_pEX_div_pre "div"(ZZ_pEX_c q, ZZ_pEX_c a, ZZ_pEX_Modulus_c F) + void ZZ_pEX_CompMod "CompMod"(ZZ_pEX_c x, ZZ_pEX_c f, ZZ_pEX_c g, ZZ_pEX_Modulus_c F) + void ZZ_pEX_MinPolyMod "MinPolyMod"(ZZ_pEX_c h, ZZ_pEX_c g, ZZ_pEX_c f) void ZZ_pEX_MinPolyMod_pre "MinPolyMod"(ZZ_pEX_c h, ZZ_pEX_c g, ZZ_pEX_Modulus_c F) diff --git a/src/sage/libs/ntl/conversion.pxd b/src/sage/libs/ntl/conversion.pxd index 81801682d51..8988399d2b2 100644 --- a/src/sage/libs/ntl/conversion.pxd +++ b/src/sage/libs/ntl/conversion.pxd @@ -41,8 +41,8 @@ cdef inline void set_ntl_matrix_modn_dense_float(mat_ZZ_p_c& A, ntl_ZZ_pContext_ INPUT: - - A -- NTL matrix - - m -- Sage matrix + - ``A`` -- NTL matrix + - ``m`` -- Sage matrix """ cdef size_t i, j cdef ntl_ZZ_p tmp @@ -58,8 +58,8 @@ cdef inline void set_ntl_matrix_modn_dense_double(mat_ZZ_p_c& A, ntl_ZZ_pContext INPUT: - - A -- NTL matrix - - m -- Sage matrix + - ``A`` -- NTL matrix + - ``m`` -- Sage matrix """ cdef size_t i, j cdef ntl_ZZ_p tmp @@ -75,8 +75,8 @@ cdef inline void set_ntl_matrix_modn_generic_dense(mat_ZZ_p_c& A, ntl_ZZ_pContex INPUT: - - A -- NTL matrix - - m -- Sage matrix + - ``A`` -- NTL matrix + - ``m`` -- Sage matrix """ cdef size_t i, j cdef ntl_ZZ_p tmp @@ -92,8 +92,8 @@ cdef inline void set_ntl_matrix_modn_dense(mat_ZZ_p_c& A, ntl_ZZ_pContext_class INPUT: - - A -- NTL matrix - - m -- Sage matrix + - ``A`` -- NTL matrix + - ``m`` -- Sage matrix """ if isinstance(m, Matrix_modn_dense_float): set_ntl_matrix_modn_dense_float(A, c, m) diff --git a/src/sage/libs/ntl/meson.build b/src/sage/libs/ntl/meson.build new file mode 100644 index 00000000000..7f78db280fe --- /dev/null +++ b/src/sage/libs/ntl/meson.build @@ -0,0 +1,90 @@ +py.install_sources( + 'GF2.pxd', + 'GF2E.pxd', + 'GF2EX.pxd', + 'GF2X.pxd', + 'ZZ.pxd', + 'ZZX.pxd', + 'ZZ_p.pxd', + 'ZZ_pE.pxd', + 'ZZ_pEX.pxd', + 'ZZ_pX.pxd', + '__init__.py', + 'all.py', + 'conversion.pxd', + 'convert.pxd', + 'lzz_p.pxd', + 'lzz_pX.pxd', + 'mat_GF2.pxd', + 'mat_GF2E.pxd', + 'mat_ZZ.pxd', + 'ntl_GF2.pxd', + 'ntl_GF2E.pxd', + 'ntl_GF2EContext.pxd', + 'ntl_GF2EX.pxd', + 'ntl_GF2X.pxd', + 'ntl_ZZ.pxd', + 'ntl_ZZX.pxd', + 'ntl_ZZ_p.pxd', + 'ntl_ZZ_pContext.pxd', + 'ntl_ZZ_pE.pxd', + 'ntl_ZZ_pEContext.pxd', + 'ntl_ZZ_pEX.pxd', + 'ntl_ZZ_pX.pxd', + 'ntl_lzz_p.pxd', + 'ntl_lzz_pContext.pxd', + 'ntl_lzz_pX.pxd', + 'ntl_mat_GF2.pxd', + 'ntl_mat_GF2E.pxd', + 'ntl_mat_ZZ.pxd', + 'ntl_tools.pxd', + 'ntlwrap.h', + 'ntlwrap_impl.h', + 'types.pxd', + 'vec_GF2.pxd', + 'vec_GF2E.pxd', + subdir: 'sage/libs/ntl', +) + +extension_data_cpp = { + 'convert': files('convert.pyx'), + 'error': files('error.pyx'), + 'ntl_GF2': files('ntl_GF2.pyx'), + 'ntl_GF2E': files('ntl_GF2E.pyx'), + 'ntl_GF2EContext': files('ntl_GF2EContext.pyx'), + 'ntl_GF2EX': files('ntl_GF2EX.pyx'), + 'ntl_GF2X': files('ntl_GF2X.pyx'), + 'ntl_ZZ': files('ntl_ZZ.pyx'), + 'ntl_ZZX': files('ntl_ZZX.pyx'), + 'ntl_ZZ_p': files('ntl_ZZ_p.pyx'), + 'ntl_ZZ_pContext': files('ntl_ZZ_pContext.pyx'), + 'ntl_ZZ_pE': files('ntl_ZZ_pE.pyx'), + 'ntl_ZZ_pEContext': files('ntl_ZZ_pEContext.pyx'), + 'ntl_ZZ_pEX': files('ntl_ZZ_pEX.pyx'), + 'ntl_ZZ_pX': files('ntl_ZZ_pX.pyx'), + 'ntl_lzz_p': files('ntl_lzz_p.pyx'), + 'ntl_lzz_pContext': files('ntl_lzz_pContext.pyx'), + 'ntl_lzz_pX': files('ntl_lzz_pX.pyx'), + 'ntl_mat_GF2': files('ntl_mat_GF2.pyx'), + 'ntl_mat_GF2E': files('ntl_mat_GF2E.pyx'), + 'ntl_mat_ZZ': files('ntl_mat_ZZ.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/ntl', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_ntl, + inc_rings, + inc_rings_finite, + ], + dependencies: [py_dep, cysignals, gmp, m, ntl], + ) +endforeach + diff --git a/src/sage/libs/ntl/misc.pxi b/src/sage/libs/ntl/misc.pxi index e9dcd9807b0..1724dccf1ea 100644 --- a/src/sage/libs/ntl/misc.pxi +++ b/src/sage/libs/ntl/misc.pxi @@ -10,7 +10,7 @@ cdef extern from *: cdef object string(char* s): """ - Takes a char* allocated using malloc, and converts it to a Python + Take a char* allocated using malloc, and converts it to a Python string, then deletes the allocated memory. Also unsets the signal handler, so you *must* call sig_on() right before calling this! """ @@ -22,7 +22,7 @@ cdef object string(char* s): cdef object string_delete(char* s): """ - Takes a char* allocated using C++ new, and converts it to a Python + Take a char* allocated using C++ new, and converts it to a Python string, then deletes the allocated memory. Also unsets the signal handler, so you *must* call sig_on() right before calling this! """ diff --git a/src/sage/libs/ntl/ntl_GF2.pyx b/src/sage/libs/ntl/ntl_GF2.pyx index 9d4d8a0b5e4..ab45f95dae3 100644 --- a/src/sage/libs/ntl/ntl_GF2.pyx +++ b/src/sage/libs/ntl/ntl_GF2.pyx @@ -41,7 +41,7 @@ cdef class ntl_GF2(): """ def __init__(self, v=None): r""" - Initializes a NTL bit. + Initialize a NTL bit. EXAMPLES:: @@ -61,7 +61,7 @@ cdef class ntl_GF2(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -72,7 +72,7 @@ cdef class ntl_GF2(): def __reduce__(self): """ - Serializes self. + Serialize ``self``. EXAMPLES:: @@ -84,7 +84,7 @@ cdef class ntl_GF2(): def __richcmp__(ntl_GF2 self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -237,7 +237,7 @@ cdef class ntl_GF2(): def __int__(self): """ - Return self as an int. + Return ``self`` as an int. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2E.pyx b/src/sage/libs/ntl/ntl_GF2E.pyx index b50a1233137..f0a576bd693 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_GF2E.pyx @@ -50,7 +50,7 @@ from sage.misc.randstate cimport current_randstate def ntl_GF2E_random(ntl_GF2EContext_class ctx): """ - Returns a random element from GF2E modulo the current modulus. + Return a random element from GF2E modulo the current modulus. INPUT: @@ -84,19 +84,19 @@ cdef class ntl_GF2E(): def __init__(self, x=None, modulus=None): """ - Constructs a new finite field element in GF(2**x). + Construct a new finite field element in GF(2**x). If you pass a string to the constructor please note that byte sequences and the hexadecimal notation are Little Endian in NTL. So e.g. '[0 1]' == '0x2' == x. INPUT: - x -- value to be assigned to this element. Same types as - ntl.GF2X() are accepted. - modulus -- the context/modulus of the field - OUTPUT: - a new ntl.GF2E element + - ``x`` -- value to be assigned to this element. Same types as + ``ntl.GF2X()`` are accepted. + - ``modulus`` -- the context/modulus of the field + + OUTPUT: a new ``ntl.GF2E`` element EXAMPLES:: @@ -176,7 +176,7 @@ cdef class ntl_GF2E(): def modulus_context(self): """ - Returns the structure that holds the underlying NTL GF2E modulus. + Return the structure that holds the underlying NTL GF2E modulus. EXAMPLES:: @@ -191,7 +191,7 @@ cdef class ntl_GF2E(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -204,7 +204,7 @@ cdef class ntl_GF2E(): def __copy__(self): """ - Return a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -319,7 +319,7 @@ cdef class ntl_GF2E(): def __richcmp__(ntl_GF2E self, other, int op): r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -350,7 +350,7 @@ cdef class ntl_GF2E(): def IsZero(ntl_GF2E self): """ - Returns True if this element equals zero, False otherwise. + Return ``True`` if this element equals zero, ``False`` otherwise. EXAMPLES:: @@ -365,7 +365,7 @@ cdef class ntl_GF2E(): def IsOne(ntl_GF2E self): """ - Returns True if this element equals one, False otherwise. + Return ``True`` if this element equals one, ``False`` otherwise. EXAMPLES:: @@ -380,7 +380,7 @@ cdef class ntl_GF2E(): def trace(ntl_GF2E self): """ - Returns the trace of this element. + Return the trace of this element. EXAMPLES:: @@ -397,7 +397,7 @@ cdef class ntl_GF2E(): def rep(ntl_GF2E self): """ - Returns a ntl.GF2X copy of this element. + Return a ntl.GF2X copy of this element. EXAMPLES:: @@ -414,7 +414,7 @@ cdef class ntl_GF2E(): def list(ntl_GF2E self): """ - Represents this element as a list of binary digits. + Represent this element as a list of binary digits. EXAMPLES:: @@ -425,9 +425,8 @@ cdef class ntl_GF2E(): sage: e.list() [1, 1, 1, 1, 1, 1, 1, 1] - OUTPUT: - a list of digits representing the coefficients in this element's - polynomial representation + OUTPUT: list of digits representing the coefficients in this element's + polynomial representation """ cdef int i cdef GF2X_c x = GF2E_rep(self.x) @@ -451,11 +450,9 @@ cdef class ntl_GF2E(): INPUT: - - `k` -- (optional) a field `\GF{2^d}` - - OUTPUT: + - ``k`` -- (optional) a field `\GF{2^d}` - :class:`FiniteFieldElement` over `k` + OUTPUT: :class:`FiniteFieldElement` over `k` EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2EContext.pyx b/src/sage/libs/ntl/ntl_GF2EContext.pyx index eef625bb03e..03c02253eb7 100644 --- a/src/sage/libs/ntl/ntl_GF2EContext.pyx +++ b/src/sage/libs/ntl/ntl_GF2EContext.pyx @@ -68,7 +68,7 @@ cdef class ntl_GF2EContext_class(): def __repr__(self): """ - Returns a print representation of self. + Return a print representation of ``self``. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2EX.pyx b/src/sage/libs/ntl/ntl_GF2EX.pyx index 0b7beb873df..152d8885f72 100644 --- a/src/sage/libs/ntl/ntl_GF2EX.pyx +++ b/src/sage/libs/ntl/ntl_GF2EX.pyx @@ -119,7 +119,7 @@ cdef class ntl_GF2EX(): def __richcmp__(ntl_GF2EX self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -148,7 +148,7 @@ cdef class ntl_GF2EX(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index 5e6ef736763..7f790b540e0 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -55,7 +55,7 @@ def GF2XHexOutput(have_hex=None): INPUT: - - have_hex -- if True hex representation will be used + - ``have_hex`` -- if ``True`` hex representation will be used EXAMPLES:: @@ -91,7 +91,7 @@ cdef class ntl_GF2X(): """ def __init__(self, x=[]): """ - Constructs a new polynomial over GF(2). + Construct a new polynomial over GF(2). A value may be passed to this constructor. If you pass a string to the constructor please note that byte sequences and the hexadecimal @@ -102,10 +102,10 @@ cdef class ntl_GF2X(): extension fields over GF(2) (uses modulus). INPUT: - x -- value to be assigned to this element. See examples. - OUTPUT: - a new ntl.GF2X element + - ``x`` -- value to be assigned to this element. See examples. + + OUTPUT: a new ntl.GF2X element EXAMPLES:: @@ -180,7 +180,7 @@ cdef class ntl_GF2X(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -339,7 +339,7 @@ cdef class ntl_GF2X(): def __richcmp__(ntl_GF2X self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -365,11 +365,12 @@ cdef class ntl_GF2X(): def __lshift__(ntl_GF2X self, int i): """ - Return left shift of self by i bits ( == multiplication by + Return left shift of ``self`` by i bits ( == multiplication by `X^i`). INPUT: - i -- offset/power of X + + - ``i`` -- offset/power of X EXAMPLES:: @@ -384,11 +385,12 @@ cdef class ntl_GF2X(): def __rshift__(ntl_GF2X self, int offset): """ - Return right shift of self by i bits ( == floor division by + Return right shift of ``self`` by i bits ( == floor division by `X^i`). INPUT: - i -- offset/power of X + + - ``i`` -- offset/power of X EXAMPLES:: @@ -403,10 +405,11 @@ cdef class ntl_GF2X(): def GCD(ntl_GF2X self, other): """ - Return GCD of self and other. + Return GCD of ``self`` and ``other``. INPUT: - other -- ntl.GF2X + + - ``other`` -- ntl.GF2X EXAMPLES:: @@ -425,12 +428,13 @@ cdef class ntl_GF2X(): def XGCD(ntl_GF2X self, other): """ - Return the extended gcd of self and other, i.e., elements r, s, t such that + Return the extended gcd of ``self`` and ``other``, i.e., elements r, s, t such that. r = s * self + t * other. INPUT: - other -- ntl.GF2X + + - ``other`` -- ntl.GF2X EXAMPLES:: @@ -439,7 +443,6 @@ cdef class ntl_GF2X(): sage: r,s,t = a.XGCD(b) sage: r == a*s + t*b True - """ cdef ntl_GF2X r = ntl_GF2X.__new__(ntl_GF2X) cdef ntl_GF2X s = ntl_GF2X.__new__(ntl_GF2X) @@ -453,7 +456,7 @@ cdef class ntl_GF2X(): def deg(ntl_GF2X self): """ - Returns the degree of this polynomial + Return the degree of this polynomial. EXAMPLES:: @@ -464,7 +467,7 @@ cdef class ntl_GF2X(): def list(ntl_GF2X self): """ - Represents this element as a list of binary digits. + Represent this element as a list of binary digits. EXAMPLES:: @@ -475,15 +478,14 @@ cdef class ntl_GF2X(): sage: e.list() [1, 1, 1, 1, 1, 1, 1, 1] - OUTPUT: - a list of digits representing the coefficients in this element's - polynomial representation + OUTPUT: list of digits representing the coefficients in this element's + polynomial representation """ return [self[i] for i in range(GF2X_deg(self.x)+1)] def bin(ntl_GF2X self): r""" - Returns binary representation of this element. + Return binary representation of this element. It is the same as setting \code{ntl.GF2XHexOutput(False)} and representing this element afterwards. However it should be @@ -513,9 +515,7 @@ cdef class ntl_GF2X(): representing this element afterwards. However it should be faster and preserves the HexOutput state as opposed to the above code. - OUTPUT: - - string representing this element in hexadecimal + OUTPUT: string representing this element in hexadecimal EXAMPLES:: @@ -541,12 +541,10 @@ cdef class ntl_GF2X(): INPUT: - - self -- GF2X element - - R -- PolynomialRing over GF(2) - - OUTPUT: + - ``self`` -- GF2X element + - ``R`` -- PolynomialRing over GF(2) - polynomial in R + OUTPUT: polynomial in R EXAMPLES:: @@ -569,7 +567,7 @@ cdef class ntl_GF2X(): INPUT: - - i -- degree of X + - ``i`` -- degree of X EXAMPLES:: @@ -599,9 +597,9 @@ cdef class ntl_GF2X(): def LeadCoeff(self): """ - Return the leading coefficient of self. + Return the leading coefficient of ``self``. - This is always 1 except when self == 0. + This is always 1 except when ``self == 0``. EXAMPLES:: @@ -618,7 +616,7 @@ cdef class ntl_GF2X(): def ConstTerm(self): """ - Return the constant term of self. + Return the constant term of ``self``. EXAMPLES:: @@ -635,7 +633,7 @@ cdef class ntl_GF2X(): def SetCoeff(self, int i, a): """ - Set the value of a coefficient of self. + Set the value of a coefficient of ``self``. EXAMPLES:: @@ -664,7 +662,7 @@ cdef class ntl_GF2X(): def diff(self): """ - Differentiate self. + Differentiate ``self``. EXAMPLES:: @@ -683,7 +681,7 @@ cdef class ntl_GF2X(): INPUT: - - hi -- bit position until which reverse is requested + - ``hi`` -- bit position until which reverse is requested EXAMPLES:: @@ -699,7 +697,7 @@ cdef class ntl_GF2X(): def weight(self): """ - Return the number of nonzero coefficients in self. + Return the number of nonzero coefficients in ``self``. EXAMPLES:: @@ -751,7 +749,7 @@ cdef class ntl_GF2X(): def NumBytes(self): """ - Return the number of bytes of self, i.e., floor((NumBits(self)+7)/8) + Return the number of bytes of ``self``, i.e., floor((NumBits(self)+7)/8). EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2X_linkage.pxi b/src/sage/libs/ntl/ntl_GF2X_linkage.pxi index 8f5edce14c1..7d7af70f36f 100644 --- a/src/sage/libs/ntl/ntl_GF2X_linkage.pxi +++ b/src/sage/libs/ntl/ntl_GF2X_linkage.pxi @@ -348,7 +348,6 @@ cdef inline int celement_pow(GF2X_c* res, GF2X_c* x, long e, GF2X_c *modulus, lo x sage: pow(x^2+1, 2, x^2+x+1) x + 1 - """ cdef GF2XModulus_c mod cdef GF2X_c xmod diff --git a/src/sage/libs/ntl/ntl_ZZ.pyx b/src/sage/libs/ntl/ntl_ZZ.pyx index 2821db96243..c424defd38d 100644 --- a/src/sage/libs/ntl/ntl_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_ZZ.pyx @@ -60,7 +60,7 @@ cdef class ntl_ZZ(): # See ntl.pxd for definition of data members def __init__(self, v=None): r""" - Initializes and NTL integer. + Initialize and NTL integer. EXAMPLES:: @@ -100,7 +100,7 @@ cdef class ntl_ZZ(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -120,7 +120,7 @@ cdef class ntl_ZZ(): def __richcmp__(ntl_ZZ self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -253,7 +253,7 @@ cdef class ntl_ZZ(): def __int__(self): """ - Return self as an int. + Return ``self`` as an int. EXAMPLES:: @@ -271,7 +271,7 @@ cdef class ntl_ZZ(): cdef int get_as_int(ntl_ZZ self) noexcept: r""" - Returns value as C int. + Return value as C int. Return value is only valid if the result fits into an int. @@ -298,7 +298,7 @@ cdef class ntl_ZZ(): def _integer_(self, ZZ=None): r""" - Gets the value as a sage int. + Get the value as a sage int. EXAMPLES:: @@ -314,7 +314,7 @@ cdef class ntl_ZZ(): cdef void set_from_int(ntl_ZZ self, int value) noexcept: r""" - Sets the value from a C int. + Set the value from a C int. AUTHOR: David Harvey (2006-08-05) """ @@ -322,7 +322,7 @@ cdef class ntl_ZZ(): def set_from_sage_int(self, Integer value): r""" - Sets the value from a sage int. + Set the value from a sage int. EXAMPLES:: @@ -355,7 +355,7 @@ cdef class ntl_ZZ(): def valuation(self, ntl_ZZ prime): """ Uses code in ``ntlwrap_impl.h`` to compute the number of times - prime divides self. + prime divides ``self``. EXAMPLES:: @@ -383,8 +383,8 @@ cdef class ntl_ZZ(): def val_unit(self, ntl_ZZ prime): """ - Uses code in ``ntlwrap_impl.h`` to compute p-adic valuation and - unit of self. + Uses code in ``ntlwrap_impl.h`` to compute `p`-adic valuation and + unit of ``self``. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_ZZX.pyx b/src/sage/libs/ntl/ntl_ZZX.pyx index 3e23bcd1250..3606aa27997 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pyx +++ b/src/sage/libs/ntl/ntl_ZZX.pyx @@ -152,7 +152,7 @@ cdef class ntl_ZZX(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -167,7 +167,7 @@ cdef class ntl_ZZX(): def __copy__(self): """ - Return a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -202,7 +202,7 @@ cdef class ntl_ZZX(): cdef void setitem_from_int(ntl_ZZX self, long i, int value) noexcept: r""" - Sets ith coefficient to value. + Set `i`-th coefficient to value. AUTHOR: David Harvey (2006-08-05) """ @@ -247,7 +247,7 @@ cdef class ntl_ZZX(): cdef int getitem_as_int(ntl_ZZX self, long i) noexcept: r""" - Returns ith coefficient as C int. + Return `i`-th coefficient as C int. Return value is only valid if the result fits into an int. AUTHOR: David Harvey (2006-08-05) @@ -336,7 +336,7 @@ cdef class ntl_ZZX(): def __truediv__(ntl_ZZX self, ntl_ZZX other): """ - Compute quotient self / other, if the quotient is a polynomial. + Compute quotient ``self / other``, if the quotient is a polynomial. Otherwise an Exception is raised. EXAMPLES:: @@ -394,8 +394,8 @@ cdef class ntl_ZZX(): def quo_rem(self, ntl_ZZX other): """ - Returns the unique integral q and r such that self = q*other + - r, if they exist. Otherwise raises an Exception. + Return the unique integral q and r such that ``self = q*other + + r``, if they exist. Otherwise raises an Exception. EXAMPLES:: @@ -430,7 +430,7 @@ cdef class ntl_ZZX(): def __pow__(ntl_ZZX self, long n, ignored): """ - Return the n-th nonnegative power of self. + Return the `n`-th nonnegative power of ``self``. EXAMPLES:: @@ -455,7 +455,7 @@ cdef class ntl_ZZX(): def __richcmp__(ntl_ZZX self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -482,7 +482,7 @@ cdef class ntl_ZZX(): def is_zero(self): """ - Return True exactly if this polynomial is 0. + Return ``True`` exactly if this polynomial is 0. EXAMPLES:: @@ -499,7 +499,7 @@ cdef class ntl_ZZX(): def is_one(self): """ - Return True exactly if this polynomial is 1. + Return ``True`` exactly if this polynomial is 1. EXAMPLES:: @@ -514,7 +514,7 @@ cdef class ntl_ZZX(): def is_monic(self): """ - Return True exactly if this polynomial is monic. + Return ``True`` exactly if this polynomial is monic. EXAMPLES:: @@ -537,7 +537,7 @@ cdef class ntl_ZZX(): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. EXAMPLES:: @@ -638,7 +638,7 @@ cdef class ntl_ZZX(): def pseudo_quo_rem(self, ntl_ZZX other): r""" - Performs pseudo-division: computes q and r with deg(r) < + Perform pseudo-division: computes q and r with deg(r) < deg(b), and \code{LeadCoeff(b)\^(deg(a)-deg(b)+1) a = b q + r}. Only the classical algorithm is used. @@ -680,7 +680,7 @@ cdef class ntl_ZZX(): def lcm(self, ntl_ZZX other): """ - Return the least common multiple of self and other. + Return the least common multiple of ``self`` and ``other``. EXAMPLES:: @@ -817,7 +817,7 @@ cdef class ntl_ZZX(): def is_x(self): """ - True if this is the polynomial "x". + ``True`` if this is the polynomial "x". EXAMPLES:: @@ -933,8 +933,8 @@ cdef class ntl_ZZX(): def invert_and_truncate(self, long m): """ - Compute and return the inverse of self modulo `x^m`. - The constant term of self must be 1 or -1. + Compute and return the inverse of ``self`` modulo `x^m`. + The constant term of ``self`` must be 1 or -1. EXAMPLES:: @@ -955,8 +955,8 @@ cdef class ntl_ZZX(): def multiply_mod(self, ntl_ZZX other, ntl_ZZX modulus): """ - Return self*other % modulus. The modulus must be monic with - deg(modulus) > 0, and self and other must have smaller degree. + Return ``self*other % modulus``. The modulus must be monic with + deg(modulus) > 0, and ``self`` and ``other`` must have smaller degree. EXAMPLES:: @@ -973,7 +973,7 @@ cdef class ntl_ZZX(): """ Return the trace of this polynomial modulus the modulus. The modulus must be monic, and of positive degree bigger - than the degree of self. + than the degree of ``self``. EXAMPLES:: @@ -997,7 +997,7 @@ cdef class ntl_ZZX(): sage: f.trace_list() [5, 0, -6, 0, 10] - The input polynomial must be monic or a :class:`ValueError` is raised:: + The input polynomial must be monic or a :exc:`ValueError` is raised:: sage: f = ntl.ZZX([1,2,0,3,0,2]) sage: f.trace_list() @@ -1016,7 +1016,7 @@ cdef class ntl_ZZX(): def resultant(self, ntl_ZZX other, proof=None): """ - Return the resultant of self and other. If proof = False (the + Return the resultant of ``self`` and ``other``. If proof = False (the default is proof=None, see proof.polynomial or sage.structure.proof, but the global default is True), then this function may use a randomized strategy that errors with probability no more than @@ -1041,7 +1041,7 @@ cdef class ntl_ZZX(): Return the norm of this polynomial modulo the modulus. The modulus must be monic, and of positive degree strictly - greater than the degree of self. If proof=False (the default + greater than the degree of ``self``. If proof=False (the default is proof=None, see proof.polynomial or sage.structure.proof, but the global default is proof=True) then it may use a randomized strategy that errors with probability no more than @@ -1096,7 +1096,7 @@ cdef class ntl_ZZX(): """ Return the characteristic polynomial of this polynomial modulo the modulus. The modulus must be monic of degree bigger than - self. If proof=False (the default is proof=None, see + ``self``. If proof=False (the default is proof=None, see proof.polynomial or sage.structure.proof, but the global default is proof=True), then this function may use a randomized strategy that errors with probability no more than @@ -1108,7 +1108,6 @@ cdef class ntl_ZZX(): sage: mod = ntl.ZZX([-5,2,0,0,1]) sage: f.charpoly_mod(mod) [-8846 -594 -60 14 1] - """ proof = proof_flag(proof) sig_on() @@ -1118,7 +1117,7 @@ cdef class ntl_ZZX(): """ Return the minimal polynomial of this polynomial modulo the modulus. The modulus must be monic of degree bigger than - self. In all cases, this function may use a randomized + ``self``. In all cases, this function may use a randomized strategy that errors with probability no more than `2^{-80}`. EXAMPLES:: @@ -1176,11 +1175,11 @@ cdef class ntl_ZZX(): def squarefree_decomposition(self): """ - Returns the square-free decomposition of self (a partial + Return the square-free decomposition of ``self`` (a partial factorization into square-free, relatively prime polynomials) as a list of 2-tuples, where the first element in each tuple is a factor, and the second is its exponent. - Assumes that self is primitive. + Assumes that ``self`` is primitive. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_ZZ_p.pyx b/src/sage/libs/ntl/ntl_ZZ_p.pyx index dfa016a7674..3dea1323680 100644 --- a/src/sage/libs/ntl/ntl_ZZ_p.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_p.pyx @@ -92,7 +92,7 @@ cdef class ntl_ZZ_p(): def __init__(self, v=None, modulus=None): r""" - Initializes an NTL integer mod p. + Initialize an NTL integer mod p. EXAMPLES:: @@ -173,7 +173,7 @@ cdef class ntl_ZZ_p(): def modulus_context(self): """ - Return the modulus for self. + Return the modulus for ``self``. EXAMPLES:: @@ -191,7 +191,7 @@ cdef class ntl_ZZ_p(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -203,7 +203,7 @@ cdef class ntl_ZZ_p(): def __richcmp__(ntl_ZZ_p self, other, int op): r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -336,7 +336,7 @@ cdef class ntl_ZZ_p(): def __int__(self): """ - Return self as an int. + Return ``self`` as an int. EXAMPLES:: @@ -350,7 +350,7 @@ cdef class ntl_ZZ_p(): cdef int get_as_int(ntl_ZZ_p self) noexcept: r""" - Returns value as C int. + Return value as C int. Return value is only valid if the result fits into an int. AUTHOR: David Harvey (2006-08-05) @@ -377,7 +377,7 @@ cdef class ntl_ZZ_p(): cdef void set_from_int(ntl_ZZ_p self, int value) noexcept: r""" - Sets the value from a C int. + Set the value from a C int. AUTHOR: David Harvey (2006-08-05) """ @@ -405,7 +405,7 @@ cdef class ntl_ZZ_p(): def lift(self): """ - Return a lift of self as an ntl.ZZ object. + Return a lift of ``self`` as an ntl.ZZ object. EXAMPLES:: @@ -422,7 +422,7 @@ cdef class ntl_ZZ_p(): def modulus(self): r""" - Returns the modulus as an NTL ZZ. + Return the modulus as an NTL ZZ. EXAMPLES:: @@ -466,7 +466,7 @@ cdef class ntl_ZZ_p(): def _integer_(self, ZZ=None): """ - Return a lift of self as a Sage integer. + Return a lift of ``self`` as a Sage integer. EXAMPLES:: @@ -485,7 +485,7 @@ cdef class ntl_ZZ_p(): def _sage_(self): r""" - Returns the value as a sage IntegerModRing. + Return the value as a sage IntegerModRing. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_ZZ_pContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pContext.pyx index 38f211a5ea1..0a4d5b14e68 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pContext.pyx @@ -69,7 +69,7 @@ cdef class ntl_ZZ_pContext_class(): def __repr__(self): """ - Returns a print representation of self. + Return a print representation of ``self``. EXAMPLES:: @@ -164,10 +164,11 @@ cdef class ntl_ZZ_pContext_factory(): cdef ntl_ZZ_pContext_class make_c(self, ntl_ZZ v): """ - Creates a new ZZ_pContext. + Create a new ZZ_pContext. INPUT: - v -- an ntl_ZZ + + - ``v`` -- an ntl_ZZ """ cdef ntl_ZZ_pContext_class context if v in self.context_dict: diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pyx b/src/sage/libs/ntl/ntl_ZZ_pE.pyx index 5109386a72a..2763c41cb54 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pyx @@ -68,7 +68,7 @@ cdef class ntl_ZZ_pE(): def __init__(self, v=None, modulus=None): r""" - Initializes an ntl ZZ_pE. + Initialize an ntl ZZ_pE. EXAMPLES:: @@ -175,7 +175,7 @@ cdef class ntl_ZZ_pE(): def __richcmp__(ntl_ZZ_pE self, other, int op): r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -269,7 +269,7 @@ cdef class ntl_ZZ_pE(): cdef ntl_ZZ_pX get_as_ZZ_pX(ntl_ZZ_pE self): r""" - Returns value as ntl_ZZ_pX. + Return value as ntl_ZZ_pX. """ self.c.restore_c() cdef ntl_ZZ_pX y = ntl_ZZ_pX.__new__(ntl_ZZ_pX) @@ -295,7 +295,7 @@ cdef class ntl_ZZ_pE(): cdef void set_from_ZZ_pX(ntl_ZZ_pE self, ntl_ZZ_pX value) noexcept: r""" - Sets the value from a ZZ_pX. + Set the value from a ZZ_pX. """ self.c.restore_c() self.x = ZZ_pX_to_ZZ_pE(value.x) @@ -320,7 +320,7 @@ cdef class ntl_ZZ_pE(): def modulus(self): r""" - Returns the modulus as an NTL ZZ_pX. + Return the modulus as an NTL ZZ_pX. sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1],11)) sage: n=ntl.ZZ_pE([2983,233],c) diff --git a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx index 03ff00f21d4..84f5f55f9ec 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx @@ -75,7 +75,7 @@ cdef class ntl_ZZ_pEContext_class(): def __repr__(self): """ - Returns a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -86,7 +86,7 @@ cdef class ntl_ZZ_pEContext_class(): def get_pc(self): """ - Returns the ZZ_pContext contained within self. + Return the ZZ_pContext contained within ``self``. EXAMPLES:: @@ -99,7 +99,7 @@ cdef class ntl_ZZ_pEContext_class(): def polynomial(self): """ - Returns the ZZ_pX polynomial defining self. + Return the ZZ_pX polynomial defining ``self``. EXAMPLES:: @@ -111,7 +111,7 @@ cdef class ntl_ZZ_pEContext_class(): def restore(self): """ - Manually sets the global NTL modulus to be self. + Manually set the global NTL modulus to be ``self``. This should be done automatically by all of the NTL wrapper classes. @@ -124,7 +124,7 @@ cdef class ntl_ZZ_pEContext_class(): cdef void restore_c(self) noexcept: """ - Sets the global NTL modulus to be self. + Set the global NTL modulus to be ``self``. CRUCIAL: If you are writing your own classes that use ZZ_p_c, ZZ_pX_c, ZZ_pE_c, ZZ_pEX_c then you MUST restore the context before calling off to NTL for anything. If the context has been @@ -138,9 +138,9 @@ cdef class ntl_ZZ_pEContext_class(): # from ntl_ZZ_pX import ntl_ZZ_pX # return ntl_ZZ_pX(v,modulus=self) - def ZZ_pE(self,v = None): + def ZZ_pE(self, v = None): """ - Returns a ZZ_pE object with modulus self out of the data v. + Return a ZZ_pE object with modulus ``self`` out of the data v. EXAMPLES:: @@ -153,7 +153,7 @@ cdef class ntl_ZZ_pEContext_class(): def ZZ_pEX(self, v = None): """ - Returns a ZZ_pE object with modulus self out of the data v. + Return a ZZ_pE object with modulus ``self`` out of the data v. EXAMPLES:: @@ -207,7 +207,7 @@ cdef class ntl_ZZ_pEContext_class(): def ntl_ZZ_pEContext( ntl_ZZ_pX f): """ - Creates an ntl_ZZ_pEContext. + Create an ntl_ZZ_pEContext. Such an object must be created before any ZZ_pE or ZZ_pEX objects can be used. diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index c12df77c2f0..caeaa26e984 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -155,7 +155,7 @@ cdef class ntl_ZZ_pEX(): def __repr__(self): """ - Returns a string representation of self. + Return a string representation of ``self``. TESTS:: @@ -171,7 +171,7 @@ cdef class ntl_ZZ_pEX(): def __copy__(self): """ - Return a copy of self. + Return a copy of ``self``. TESTS:: @@ -196,7 +196,7 @@ cdef class ntl_ZZ_pEX(): def get_modulus_context(self): """ - Returns the structure that holds the underlying NTL modulus. + Return the structure that holds the underlying NTL modulus. EXAMPLES:: @@ -211,7 +211,7 @@ cdef class ntl_ZZ_pEX(): def __setitem__(self, long i, a): r""" - Sets the ith coefficient of self to be a. + Set the i-th coefficient of ``self`` to be a. EXAMPLES:: @@ -234,7 +234,7 @@ cdef class ntl_ZZ_pEX(): def __getitem__(self, long i): r""" - Returns the ith coefficient of self. + Return the i-th coefficient of ``self``. EXAMPLES:: @@ -279,7 +279,7 @@ cdef class ntl_ZZ_pEX(): def __add__(ntl_ZZ_pEX self, ntl_ZZ_pEX other): """ - Adds self and other. + Add ``self`` and ``other``. EXAMPLES:: @@ -302,7 +302,7 @@ cdef class ntl_ZZ_pEX(): def __sub__(ntl_ZZ_pEX self, ntl_ZZ_pEX other): """ - Subtracts other from self. + Subtracts ``other`` from ``self``. EXAMPLES:: @@ -325,7 +325,7 @@ cdef class ntl_ZZ_pEX(): def __mul__(ntl_ZZ_pEX self, ntl_ZZ_pEX other): """ - Returns the product self * other. + Return the product ``self * other``. EXAMPLES:: @@ -354,7 +354,7 @@ cdef class ntl_ZZ_pEX(): def __truediv__(ntl_ZZ_pEX self, ntl_ZZ_pEX other): """ - Compute quotient self / other, if the quotient is a polynomial. + Compute quotient ``self / other``, if the quotient is a polynomial. Otherwise an Exception is raised. EXAMPLES:: @@ -390,7 +390,7 @@ cdef class ntl_ZZ_pEX(): function returns r. If p is not prime or the modulus is not irreducible, this - function may raise a :class:`RuntimeError` due to division by + function may raise a :exc:`RuntimeError` due to division by a noninvertible element of ZZ_p. EXAMPLES:: @@ -421,7 +421,7 @@ cdef class ntl_ZZ_pEX(): function returns (q, r). If p is not prime or the modulus is not irreducible, this function may raise a - RuntimeError due to division by a noninvertible element of ZZ_p. + :exc:`RuntimeError` due to division by a noninvertible element of ZZ_p. EXAMPLES:: @@ -467,7 +467,7 @@ cdef class ntl_ZZ_pEX(): def __pow__(ntl_ZZ_pEX self, long n, ignored): """ - Return the n-th nonnegative power of self. + Return the `n`-th nonnegative power of ``self``. EXAMPLES:: @@ -495,7 +495,7 @@ cdef class ntl_ZZ_pEX(): def __richcmp__(ntl_ZZ_pEX self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -527,7 +527,7 @@ cdef class ntl_ZZ_pEX(): def is_zero(self): """ - Return True exactly if this polynomial is 0. + Return ``True`` exactly if this polynomial is 0. EXAMPLES:: @@ -546,7 +546,7 @@ cdef class ntl_ZZ_pEX(): def is_one(self): """ - Return True exactly if this polynomial is 1. + Return ``True`` exactly if this polynomial is 1. EXAMPLES:: @@ -565,7 +565,7 @@ cdef class ntl_ZZ_pEX(): def is_monic(self): """ - Return True exactly if this polynomial is monic. + Return ``True`` exactly if this polynomial is monic. EXAMPLES:: @@ -592,7 +592,7 @@ cdef class ntl_ZZ_pEX(): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. EXAMPLES:: @@ -610,11 +610,11 @@ cdef class ntl_ZZ_pEX(): def convert_to_modulus(self, ntl_ZZ_pContext_class c): """ - Returns a new ntl_ZZ_pX which is the same as self, but considered modulo a different p (but the SAME polynomial). + Return a new ntl_ZZ_pX which is the same as self, but considered modulo a different p (but the SAME polynomial). In order for this to make mathematical sense, c.p should divide self.c.p - (in which case self is reduced modulo c.p) or self.c.p should divide c.p - (in which case self is lifted to something modulo c.p congruent to self modulo self.c.p) + (in which case ``self`` is reduced modulo c.p) or self.c.p should divide c.p + (in which case ``self`` is lifted to something modulo c.p congruent to ``self`` modulo self.c.p) EXAMPLES:: @@ -701,7 +701,7 @@ cdef class ntl_ZZ_pEX(): def gcd(self, ntl_ZZ_pEX other, check=True): """ - Returns gcd(self, other) if we are working over a field. + Return ``gcd(self, other)`` if we are working over a field. NOTE: Does not work if p is not prime or if the modulus is not irreducible. @@ -731,9 +731,9 @@ cdef class ntl_ZZ_pEX(): def xgcd(self, ntl_ZZ_pEX other): """ - Returns r,s,t such that r = s*self + t*other. + Return `r`, `s`, `t` such that ``r = s*self + t*other``. - Here r is the gcd of self and other. + Here `r` is the gcd of ``self`` and ``other``. EXAMPLES:: @@ -833,7 +833,7 @@ cdef class ntl_ZZ_pEX(): def is_x(self): """ - True if this is the polynomial "x". + ``True`` if this is the polynomial "x". EXAMPLES:: @@ -995,8 +995,8 @@ cdef class ntl_ZZ_pEX(): def invert_and_truncate(self, long m): """ - Compute and return the inverse of self modulo `x^m`. - The constant term of self must be invertible. + Compute and return the inverse of ``self`` modulo `x^m`. + The constant term of ``self`` must be invertible. EXAMPLES:: @@ -1022,8 +1022,8 @@ cdef class ntl_ZZ_pEX(): def multiply_mod(self, ntl_ZZ_pEX other, ntl_ZZ_pEX modulus): """ - Return self*other % modulus. The modulus must be monic with - deg(modulus) > 0, and self and other must have smaller degree. + Return ``self*other % modulus``. The modulus must be monic with + ``deg(modulus) > 0``, and ``self`` and ``other`` must have smaller degree. EXAMPLES:: @@ -1047,7 +1047,7 @@ cdef class ntl_ZZ_pEX(): """ Return the trace of this polynomial modulo the modulus. The modulus must be monic, and of positive degree bigger - than the degree of self. + than the degree of ``self``. EXAMPLES:: @@ -1079,7 +1079,7 @@ cdef class ntl_ZZ_pEX(): # sage: f.trace_list() # [5, 0, 14, 0, 10] # - # The input polynomial must be monic or a :class:`ValueError` is raised:: + # The input polynomial must be monic or a :exc:`ValueError` is raised:: # # sage: c=ntl.ZZ_pContext(ntl.ZZ(20)) # sage: f = c.ZZ_pX([1,2,0,3,0,2] @@ -1100,7 +1100,7 @@ cdef class ntl_ZZ_pEX(): def resultant(self, ntl_ZZ_pEX other): """ - Return the resultant of self and other. + Return the resultant of ``self`` and ``other``. EXAMPLES:: @@ -1125,7 +1125,7 @@ cdef class ntl_ZZ_pEX(): """ Return the norm of this polynomial modulo the modulus. The modulus must be monic, and of positive degree strictly greater - than the degree of self. + than the degree of ``self``. EXAMPLES:: @@ -1174,7 +1174,7 @@ cdef class ntl_ZZ_pEX(): """ Return the minimal polynomial of this polynomial modulo the modulus. The modulus must be monic of degree bigger than - self. + ``self``. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_ZZ_pX.pyx b/src/sage/libs/ntl/ntl_ZZ_pX.pyx index a39ee7ee2b5..f7e69c52128 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pX.pyx @@ -158,7 +158,7 @@ cdef class ntl_ZZ_pX(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -173,7 +173,7 @@ cdef class ntl_ZZ_pX(): def __copy__(self): """ - Return a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -193,7 +193,7 @@ cdef class ntl_ZZ_pX(): def get_modulus_context(self): """ - Return the modulus for self. + Return the modulus for ``self``. EXAMPLES:: @@ -224,7 +224,7 @@ cdef class ntl_ZZ_pX(): cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value) noexcept: r""" - Sets ith coefficient to value. + Set `i`-th coefficient to value. AUTHOR: David Harvey (2006-08-05) """ @@ -248,7 +248,7 @@ cdef class ntl_ZZ_pX(): def __getitem__(self, long i): r""" - Returns the ith entry of self. + Return the `i`-th entry of ``self``. EXAMPLES:: @@ -269,7 +269,8 @@ cdef class ntl_ZZ_pX(): cdef int getitem_as_int(ntl_ZZ_pX self, long i) noexcept: r""" - Returns ith coefficient as C int. + Return `i`-th coefficient as C int. + Return value is only valid if the result fits into an int. AUTHOR: David Harvey (2006-08-05) @@ -380,7 +381,7 @@ cdef class ntl_ZZ_pX(): def __truediv__(ntl_ZZ_pX self, ntl_ZZ_pX other): """ - Compute quotient self / other, if the quotient is a polynomial. + Compute quotient ``self / other``, if the quotient is a polynomial. Otherwise an Exception is raised. EXAMPLES:: @@ -417,7 +418,7 @@ cdef class ntl_ZZ_pX(): in ZZ_p[X] such that a = b*q + r, deg(r) < deg(b). This function returns r. - If p is not prime this function may raise a :class:`RuntimeError` + If p is not prime this function may raise a :exc:`RuntimeError` due to division by a noninvertible element of ZZ_p. EXAMPLES:: @@ -448,8 +449,8 @@ cdef class ntl_ZZ_pX(): def quo_rem(self, ntl_ZZ_pX other): """ - Returns the unique integral q and r such that self = q*other + - r, if they exist. Otherwise raises an Exception. + Return the unique integral `q` and `r` such that ``self = q*other + + r``, if they exist. Otherwise raises an Exception. EXAMPLES:: @@ -566,7 +567,7 @@ cdef class ntl_ZZ_pX(): def __richcmp__(ntl_ZZ_pX self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -596,7 +597,7 @@ cdef class ntl_ZZ_pX(): def is_zero(self): """ - Return True exactly if this polynomial is 0. + Return ``True`` exactly if this polynomial is 0. EXAMPLES:: @@ -615,7 +616,7 @@ cdef class ntl_ZZ_pX(): def is_one(self): """ - Return True exactly if this polynomial is 1. + Return ``True`` exactly if this polynomial is 1. EXAMPLES:: @@ -632,7 +633,7 @@ cdef class ntl_ZZ_pX(): def is_monic(self): """ - Return True exactly if this polynomial is monic. + Return ``True`` exactly if this polynomial is monic. EXAMPLES:: @@ -656,7 +657,7 @@ cdef class ntl_ZZ_pX(): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. EXAMPLES:: @@ -724,7 +725,7 @@ cdef class ntl_ZZ_pX(): def _left_pshift(self, ntl_ZZ n): """ - Multiplies all coefficients by n and the context by n. + Multiply all coefficients by `n` and the context by `n`. """ cdef ntl_ZZ new_c_p = ntl_ZZ.__new__(ntl_ZZ) ZZ_mul(new_c_p.x, (self.c.p).x, n.x) @@ -737,7 +738,8 @@ cdef class ntl_ZZ_pX(): def _right_pshift(self, ntl_ZZ n): """ - Divides all coefficients by n and the context by n. Only really makes sense when n divides self.c.p + Divide all coefficients by `n` and the context by `n`. Only really + makes sense when `n` divides ``self.c.p``. """ cdef ntl_ZZ new_c_p = ntl_ZZ.__new__(ntl_ZZ) ZZ_div(new_c_p.x, (self.c.p).x, n.x) @@ -772,7 +774,7 @@ cdef class ntl_ZZ_pX(): def xgcd(self, ntl_ZZ_pX other, plain=True): """ - Returns r,s,t such that r = s*self + t*other. + Return `r`, `s`, `t` such that ``r = s*self + t*other``. Here r is the resultant of a and b; if r != 0, then this function computes s and t such that: a*s + b*t = r; otherwise @@ -895,7 +897,7 @@ cdef class ntl_ZZ_pX(): def is_x(self): """ - True if this is the polynomial "x". + ``True`` if this is the polynomial "x". EXAMPLES:: @@ -915,11 +917,11 @@ cdef class ntl_ZZ_pX(): def convert_to_modulus(self, ntl_ZZ_pContext_class c): """ - Returns a new ntl_ZZ_pX which is the same as self, but considered modulo a different p. + Return a new ntl_ZZ_pX which is the same as self, but considered modulo a different p. In order for this to make mathematical sense, c.p should divide self.c.p - (in which case self is reduced modulo c.p) or self.c.p should divide c.p - (in which case self is lifted to something modulo c.p congruent to self modulo self.c.p) + (in which case ``self`` is reduced modulo c.p) or self.c.p should divide c.p + (in which case ``self`` is lifted to something modulo c.p congruent to ``self`` modulo self.c.p) EXAMPLES:: @@ -955,7 +957,7 @@ cdef class ntl_ZZ_pX(): sage: f.derivative() [7 0 19] """ - cdef ntl_ZZ_pX r = self._new() #restores context + cdef ntl_ZZ_pX r = self._new() # restores context sig_on() ZZ_pX_diff(r.x, self.x) sig_off() @@ -963,7 +965,7 @@ cdef class ntl_ZZ_pX(): def factor(self, verbose=False): """ - Return the factorization of self. Assumes self is + Return the factorization of ``self``. Assumes ``self`` is monic. NOTE: The roots are returned in a random order. @@ -1158,9 +1160,9 @@ cdef class ntl_ZZ_pX(): def invert_and_truncate(self, long m): """ - Compute and return the inverse of self modulo `x^m`. + Compute and return the inverse of ``self`` modulo `x^m`. - The constant term of self must be a unit. + The constant term of ``self`` must be a unit. EXAMPLES:: @@ -1182,7 +1184,7 @@ cdef class ntl_ZZ_pX(): def invmod(self, ntl_ZZ_pX modulus): """ - Returns the inverse of self modulo the modulus using NTL's InvMod. + Return the inverse of ``self`` modulo the modulus using NTL's InvMod. """ cdef ntl_ZZ_pX r = self._new() sig_on() @@ -1192,7 +1194,7 @@ cdef class ntl_ZZ_pX(): def invmod_newton(self, ntl_ZZ_pX modulus): """ - Returns the inverse of self modulo the modulus using Newton lifting. + Return the inverse of ``self`` modulo the modulus using Newton lifting. Only works if modulo a power of a prime, and if modulus is either unramified or Eisenstein. """ @@ -1237,8 +1239,8 @@ cdef class ntl_ZZ_pX(): def multiply_mod(self, ntl_ZZ_pX other, ntl_ZZ_pX modulus): """ - Return self*other % modulus. The modulus must be monic with - deg(modulus) > 0, and self and other must have smaller degree. + Return ``self*other % modulus``. The modulus must be monic with + ``deg(modulus) > 0``, and ``self`` and ``other`` must have smaller degree. EXAMPLES:: @@ -1259,7 +1261,7 @@ cdef class ntl_ZZ_pX(): """ Return the trace of this polynomial modulus the modulus. The modulus must be monic, and of positive degree bigger - than the degree of self. + than the degree of ``self``. EXAMPLES:: @@ -1291,7 +1293,7 @@ cdef class ntl_ZZ_pX(): sage: f.trace_list() [5, 0, 14, 0, 10] - The input polynomial must be monic or a :class:`ValueError` is raised:: + The input polynomial must be monic or a :exc:`ValueError` is raised:: sage: c = ntl.ZZ_pContext(20) sage: f = ntl.ZZ_pX([1,2,0,3,0,2],c) @@ -1313,7 +1315,7 @@ cdef class ntl_ZZ_pX(): def resultant(self, ntl_ZZ_pX other): """ - Return the resultant of self and other. + Return the resultant of ``self`` and ``other``. EXAMPLES:: @@ -1335,7 +1337,7 @@ cdef class ntl_ZZ_pX(): """ Return the norm of this polynomial modulo the modulus. The modulus must be monic, and of positive degree strictly greater - than the degree of self. + than the degree of ``self``. EXAMPLES:: @@ -1386,7 +1388,7 @@ cdef class ntl_ZZ_pX(): """ Return the characteristic polynomial of this polynomial modulo the modulus. The modulus must be monic of degree bigger than - self. + ``self``. EXAMPLES:: @@ -1406,7 +1408,7 @@ cdef class ntl_ZZ_pX(): """ Return the minimal polynomial of this polynomial modulo the modulus. The modulus must be monic of degree bigger than - self. + ``self``. EXAMPLES:: @@ -1470,6 +1472,46 @@ cdef class ntl_ZZ_pX(): #ZZ_pX_preallocate_space(&self.x, n) sig_off() + def compose_mod(self, ntl_ZZ_pX other, ntl_ZZ_pX modulus): + r""" + Compute `f(g) \bmod h`. + + To be precise about the order fo compostion, given ``self``, ``other`` + and ``modulus`` as `f(x)`, `g(x)` and `h(x)` compute `f(g(x)) \bmod h(x)`. + + INPUT: + + - ``other`` -- a polynomial `g(x)` + - ``modulus`` -- a polynomial `h(x)` + + EXAMPLES:: + + sage: c = ntl.ZZ_pContext(17) + sage: f = ntl.ZZ_pX([1,2,3],c) + sage: g = ntl.ZZ_pX([3,2,1],c) + sage: h = ntl.ZZ_pX([1,0,1],c) + sage: f.compose_mod(g, h) + [5 11] + + AUTHORS: + + - Giacomo Pope (2024-08) initial implementation + """ + cdef ntl_ZZ_pX r = self._new() + cdef ZZ_pX_Modulus_c mod + + sig_on() + # NTL requires that g is reduced + other = other % modulus + + # Build the modulus type + ZZ_pX_Modulus_build(mod, modulus.x) + + # Compute f(g) % h + ZZ_pX_CompMod(r.x, self.x, other.x, mod) + sig_off() + return r + cdef class ntl_ZZ_pX_Modulus(): """ Thin holder for ZZ_pX_Moduli. diff --git a/src/sage/libs/ntl/ntl_lzz_p.pyx b/src/sage/libs/ntl/ntl_lzz_p.pyx index 632252e8960..e364e105c68 100644 --- a/src/sage/libs/ntl/ntl_lzz_p.pyx +++ b/src/sage/libs/ntl/ntl_lzz_p.pyx @@ -178,7 +178,7 @@ cdef class ntl_zz_p(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -259,7 +259,7 @@ cdef class ntl_zz_p(): def __pow__(ntl_zz_p self, long n, ignored): """ - Return the n-th nonnegative power of self. + Return the `n`-th nonnegative power of ``self``. EXAMPLES:: @@ -302,7 +302,7 @@ cdef class ntl_zz_p(): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. EXAMPLES:: @@ -318,7 +318,7 @@ cdef class ntl_zz_p(): def __richcmp__(ntl_zz_p self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -349,7 +349,7 @@ cdef class ntl_zz_p(): def __int__(self): """ - Return self as an int. + Return ``self`` as an int. EXAMPLES:: @@ -380,7 +380,7 @@ cdef class ntl_zz_p(): def is_zero(self): """ - Return True exactly if this element is 0. + Return ``True`` exactly if this element is 0. EXAMPLES:: @@ -396,7 +396,7 @@ cdef class ntl_zz_p(): def is_one(self): """ - Return True exactly if this element is 1. + Return ``True`` exactly if this element is 1. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_lzz_pContext.pyx b/src/sage/libs/ntl/ntl_lzz_pContext.pyx index 2c1c941b9e8..9b0065332cf 100644 --- a/src/sage/libs/ntl/ntl_lzz_pContext.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pContext.pyx @@ -70,7 +70,7 @@ cdef class ntl_zz_pContext_class(): def modulus(self): """ - Print the modulus for self. + Print the modulus for ``self``. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_lzz_pX.pyx b/src/sage/libs/ntl/ntl_lzz_pX.pyx index 46537024353..4df5df47a3c 100644 --- a/src/sage/libs/ntl/ntl_lzz_pX.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pX.pyx @@ -177,7 +177,7 @@ cdef class ntl_zz_pX(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -189,7 +189,7 @@ cdef class ntl_zz_pX(): def __getitem__(self, long i): """ - Return the ith coefficient of f. + Return the i-th coefficient of f. EXAMPLES:: @@ -212,7 +212,7 @@ cdef class ntl_zz_pX(): def __setitem__(self, long i, val): """ - Set the ith coefficient of self to val. If + Set the i-th coefficient of ``self`` to val. If i is out of range, raise an exception. EXAMPLES:: @@ -234,7 +234,7 @@ cdef class ntl_zz_pX(): cdef ntl_zz_pX _new(self): """ Quick and dirty method for creating a new object with the - same zz_pContext as self. + same zz_pContext as ``self``. EXAMPLES:: @@ -249,7 +249,7 @@ cdef class ntl_zz_pX(): def __add__(ntl_zz_pX self, other): """ - Return self + other. + Return ``self + other``. EXAMPLES:: @@ -272,7 +272,7 @@ cdef class ntl_zz_pX(): def __sub__(ntl_zz_pX self, other): """ - Return self - other. + Return ``self - other``. EXAMPLES:: @@ -318,7 +318,7 @@ cdef class ntl_zz_pX(): def __truediv__(ntl_zz_pX self, other): """ - Compute quotient self / other, if the quotient is a polynomial. + Compute quotient ``self / other``, if the quotient is a polynomial. Otherwise an Exception is raised. EXAMPLES:: @@ -386,7 +386,7 @@ cdef class ntl_zz_pX(): def __pow__(ntl_zz_pX self, long n, ignored): """ - Return the n-th nonnegative power of self. + Return the `n`-th nonnegative power of ``self``. EXAMPLES:: @@ -405,9 +405,9 @@ cdef class ntl_zz_pX(): def quo_rem(ntl_zz_pX self, ntl_zz_pX right): """ - Returns the quotient and remainder when self is divided by right. + Return the quotient and remainder when ``self`` is divided by ``right``. - Specifically, this return r, q such that `self = q * right + r` + Specifically, this returns `r`, `q` such that ``self = q * right + r``. EXAMPLES:: @@ -432,14 +432,13 @@ cdef class ntl_zz_pX(): def __floordiv__(ntl_zz_pX self, ntl_zz_pX right): """ - Returns the whole part of `self / right`. + Return the whole part of ``self / right``. EXAMPLES:: sage: f = ntl.zz_pX(range(10), 19); g = ntl.zz_pX([1]*5, 19) sage: f // g ## indirect doctest [8, 18, 18, 18, 18, 9] - """ cdef ntl_zz_pX q = self._new() self.c.restore_c() @@ -450,7 +449,7 @@ cdef class ntl_zz_pX(): def __lshift__(ntl_zz_pX self, long n): """ - Shifts this polynomial to the left, which is multiplication by `x^n`. + Shift this polynomial to the left, which is multiplication by `x^n`. EXAMPLES:: @@ -465,7 +464,7 @@ cdef class ntl_zz_pX(): def __rshift__(ntl_zz_pX self, long n): """ - Shifts this polynomial to the right, which is division by `x^n` (and truncation). + Shift this polynomial to the right, which is division by `x^n` (and truncation). EXAMPLES:: @@ -480,7 +479,7 @@ cdef class ntl_zz_pX(): def diff(self): """ - The formal derivative of self. + The formal derivative of ``self``. EXAMPLES:: @@ -495,7 +494,7 @@ cdef class ntl_zz_pX(): def reverse(self): """ - Returns self with coefficients reversed, i.e. `x^n self(x^{-n})`. + Return ``self`` with coefficients reversed, i.e. ``x^n self(x^{-n})``. EXAMPLES:: @@ -510,7 +509,8 @@ cdef class ntl_zz_pX(): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. + EXAMPLES:: sage: f = ntl.zz_pX([2,0,0,1],20) @@ -527,7 +527,7 @@ cdef class ntl_zz_pX(): def __richcmp__(ntl_zz_pX self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -720,8 +720,8 @@ cdef class ntl_zz_pX(): def invert_and_truncate(self, long m): """ - Compute and return the inverse of self modulo `x^m`. - The constant term of self must be 1 or -1. + Compute and return the inverse of ``self`` modulo `x^m`. + The constant term of ``self`` must be 1 or -1. EXAMPLES:: @@ -751,7 +751,7 @@ cdef class ntl_zz_pX(): def is_zero(self): """ - Return True exactly if this polynomial is 0. + Return ``True`` exactly if this polynomial is 0. EXAMPLES:: @@ -769,7 +769,7 @@ cdef class ntl_zz_pX(): def is_one(self): """ - Return True exactly if this polynomial is 1. + Return ``True`` exactly if this polynomial is 1. EXAMPLES:: @@ -785,7 +785,7 @@ cdef class ntl_zz_pX(): def is_monic(self): """ - Return True exactly if this polynomial is monic. + Return ``True`` exactly if this polynomial is monic. EXAMPLES:: @@ -823,14 +823,13 @@ cdef class ntl_zz_pX(): Though f and g are equal, they are not the same objects in memory: sage: f is g False - """ self.c.restore_c() zz_pX_SetX(self.x) def is_x(self): """ - True if this is the polynomial "x". + ``True`` if this is the polynomial "x". EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_mat_GF2.pyx b/src/sage/libs/ntl/ntl_mat_GF2.pyx index 5ffef1c6b31..ae33d4fbb49 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2.pyx @@ -55,9 +55,9 @@ cdef class ntl_mat_GF2(): INPUT: - - nrows -- number of rows - - ncols -- number of columns - - v -- either a list or a matrix over GF(2^x) + - ``nrows`` -- number of rows + - ``ncols`` -- number of columns + - ``v`` -- either a list or a matrix over GF(2^x) EXAMPLES:: @@ -244,7 +244,7 @@ cdef class ntl_mat_GF2(): def __richcmp__(ntl_mat_GF2 self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -409,7 +409,7 @@ cdef class ntl_mat_GF2(): [0 0 0 0 0 0 0 0 0 0] ] - ``Abar`` is in row echolon form now:: + ``Abar`` is in row echelon form now:: sage: first_nonzero_indices = [Abar._sage_().row(i).nonzero_positions()[0] for i in range(A.rank())] sage: all(first_nonzero_indices[i] < first_nonzero_indices[i+1] for i in range(A.rank()-1)) @@ -522,7 +522,7 @@ cdef class ntl_mat_GF2(): def IsIdent(self, n = -1): """ - test if this matrix is the n x n identity matrix. + Test if this matrix is the n x n identity matrix. EXAMPLES:: @@ -542,7 +542,7 @@ cdef class ntl_mat_GF2(): def IsDiag(self, long n, ntl_GF2 d): """ - test if X is an n x n diagonal matrix with d on diagonal. + Test if X is an n x n diagonal matrix with d on diagonal. EXAMPLES:: @@ -573,7 +573,7 @@ cdef class ntl_mat_GF2(): sage: A_image.row_space() == Abar_image.row_space() True - X is in row echolon form:: + X is in row echelon form:: sage: first_nonzero_indices = [row.nonzero_positions()[0] for row in Abar_image.rows()] sage: all(first_nonzero_indices[i] < first_nonzero_indices[i+1] for i in range(Abar_image.nrows() - 1)) @@ -587,7 +587,7 @@ cdef class ntl_mat_GF2(): def kernel(self): """ - Computes a basis for the kernel of the map x -> x*A. where x + Compute a basis for the kernel of the map x -> x*A. where x is a row vector. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index 720310c9884..795ad9674fa 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -51,13 +51,14 @@ cdef class ntl_mat_GF2E(): """ def __init__(self, modulus = None, nrows=0, ncols=0, v=None): """ - Constructs a matrix over ntl.GF2E. + Construct a matrix over ntl.GF2E. INPUT: - modulus -- GF2E context - nrows -- number of rows - ncols -- number of columns - v -- either a list or a matrix over GF(2^x) + + - ``modulus`` -- GF2E context + - ``nrows`` -- number of rows + - ``ncols`` -- number of columns + - ``v`` -- either a list or a matrix over GF(2^x) EXAMPLES:: @@ -153,7 +154,7 @@ cdef class ntl_mat_GF2E(): def modulus_context(self): """ - Returns the structure that holds the underlying NTL GF2E modulus. + Return the structure that holds the underlying NTL GF2E modulus. EXAMPLES:: @@ -182,7 +183,7 @@ cdef class ntl_mat_GF2E(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -306,7 +307,7 @@ cdef class ntl_mat_GF2E(): def __richcmp__(ntl_mat_GF2E self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -335,7 +336,7 @@ cdef class ntl_mat_GF2E(): def NumRows(self): """ - Return the number of rows in self. + Return the number of rows in ``self``. EXAMPLES:: @@ -347,7 +348,7 @@ cdef class ntl_mat_GF2E(): def NumCols(self): """ - Return the number of columns in self. + Return the number of columns in ``self``. EXAMPLES:: @@ -428,7 +429,7 @@ cdef class ntl_mat_GF2E(): def determinant(self): """ - Returns the determinant. + Return the determinant. EXAMPLES:: @@ -474,7 +475,7 @@ cdef class ntl_mat_GF2E(): def list(self): """ - Returns a list of the entries in this matrix + Return a list of the entries in this matrix. EXAMPLES:: @@ -487,13 +488,12 @@ cdef class ntl_mat_GF2E(): True sage: all(a.modulus_context() is ctx for a in l) True - """ return [self[i,j] for i in range(self.NumRows()) for j in range(self.x.NumCols())] def IsZero(self): """ - Return True if self is zero, and false otherwise. + Return ``True`` if ``self`` is zero, and ``False`` otherwise. EXAMPLES:: @@ -513,15 +513,14 @@ cdef class ntl_mat_GF2E(): def _sage_(ntl_mat_GF2E self, k=None): """ - Returns a ``Matrix`` over a ``FiniteField`` representation + Return a ``Matrix`` over a ``FiniteField`` representation of this element. INPUT: - - ``k`` -- optional GF(2**deg) + - ``k`` -- (optional) GF(2**deg) - OUTPUT: - Matrix over k + OUTPUT: Matrix over k EXAMPLES:: @@ -549,10 +548,7 @@ cdef class ntl_mat_GF2E(): def transpose(ntl_mat_GF2E self): """ - Returns the transposed matrix of self. - - OUTPUT: - transposed Matrix + Return the transposed matrix of ``self``. EXAMPLES:: @@ -590,8 +586,8 @@ cdef class ntl_mat_GF2E(): return r def IsIdent(self, n = -1): - """ - test if A is the n x n identity matrix + r""" + Test if `A` is the `n \times n` identity matrix. EXAMPLES:: @@ -645,7 +641,7 @@ cdef class ntl_mat_GF2E(): def kernel(self): """ - Computes a basis for the kernel of the map ``x -> x*A``, where + Compute a basis for the kernel of the map ``x -> x*A``, where ``x`` is a row vector. EXAMPLES:: @@ -669,10 +665,10 @@ cdef class ntl_mat_GF2E(): INPUT: - - ``density`` -- float; proportion (roughly) to be considered for - changes - - ``nonzero`` -- Bool (default: ``False``); whether the new entries - are forced to be non-zero + - ``density`` -- float; proportion (roughly) to be considered for + changes + - ``nonzero`` -- boolean (default: ``False``); whether the new entries + are forced to be nonzero EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_mat_ZZ.pyx b/src/sage/libs/ntl/ntl_mat_ZZ.pyx index f8411113807..310bbb0006c 100644 --- a/src/sage/libs/ntl/ntl_mat_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_mat_ZZ.pyx @@ -129,7 +129,7 @@ cdef class ntl_mat_ZZ(): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -163,7 +163,7 @@ cdef class ntl_mat_ZZ(): def __sub__(ntl_mat_ZZ self, other): """ - Return self - other. + Return ``self - other``. EXAMPLES:: @@ -186,7 +186,7 @@ cdef class ntl_mat_ZZ(): def __add__(ntl_mat_ZZ self, other): """ - Return self + other. + Return ``self + other``. EXAMPLES:: @@ -209,7 +209,7 @@ cdef class ntl_mat_ZZ(): def __richcmp__(ntl_mat_ZZ self, other, int op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -237,7 +237,7 @@ cdef class ntl_mat_ZZ(): def __pow__(ntl_mat_ZZ self, long e, ignored): """ - Return self to the e power. + Return ``self`` to the e power. EXAMPLES:: @@ -269,7 +269,7 @@ cdef class ntl_mat_ZZ(): def nrows(self): """ - Return the number of rows in self. + Return the number of rows in ``self``. EXAMPLES:: @@ -281,7 +281,7 @@ cdef class ntl_mat_ZZ(): def ncols(self): """ - Return the number of columns in self. + Return the number of columns in ``self``. EXAMPLES:: @@ -362,7 +362,7 @@ cdef class ntl_mat_ZZ(): def determinant(self, deterministic=True): """ - Return the determinant of self. + Return the determinant of ``self``. EXAMPLES:: @@ -392,7 +392,7 @@ cdef class ntl_mat_ZZ(): - W is lower triangular, - the diagonal entries are positive, - - any entry below the diagonal is a non-negative number + - any entry below the diagonal is a nonnegative number strictly less than the diagonal entry in its column. This is implemented using the algorithm of [P. Domich, @@ -491,11 +491,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -561,11 +562,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -631,11 +633,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -701,11 +704,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -771,11 +775,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -841,11 +846,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -911,11 +917,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -981,11 +988,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -1051,11 +1059,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -1121,11 +1130,12 @@ cdef class ntl_mat_ZZ(): precision uniformly throughout. INPUT: - U -- optional permutation matrix (see LLL, default: None) - delta -- reduction parameter (default: 0.99) - BlockSize -- see above (default: 10) - prune -- see above (default: 0) - verbose -- print verbose output (default: ``False``) + + - ``U`` -- permutation matrix (see LLL, default: ``None``) + - ``delta`` -- reduction parameter (default: 0.99) + - ``BlockSize`` -- see above (default: 10) + - ``prune`` -- see above (default: 0) + - ``verbose`` -- print verbose output (default: ``False``) EXAMPLES:: @@ -1166,21 +1176,21 @@ cdef class ntl_mat_ZZ(): def LLL(self, a=3, b=4, return_U=False, verbose=False): r""" - Performs LLL reduction of self (puts \code{self} in an LLL form). + Perform LLL reduction of ``self`` (puts \code{self} in an LLL form). \code{self} is an `m x n` matrix, viewed as `m` rows of `n`-vectors. `m` may be less than, equal to, or greater than `n`, - and the rows need not be linearly independent. self is + and the rows need not be linearly independent. ``self`` is transformed into an LLL-reduced basis, and the return value is - the rank r of self so as det2 (see below). The first `m-r` rows - of self are zero. + the rank r of ``self`` so as det2 (see below). The first `m-r` rows + of ``self`` are zero. More specifically, elementary row transformations are - performed on \code{self} so that the non-zero rows of + performed on \code{self} so that the nonzero rows of new-\code{self} form an LLL-reduced basis for the lattice spanned by the rows of old-\code{self}. The default reduction parameter is `\delta=3/4`, which means that the squared length - of the first non-zero basis vector is no more than `2^{r-1}` + of the first nonzero basis vector is no more than `2^{r-1}` times that of the shortest vector in the lattice. det2 is calculated as the \emph{square} of the determinant of @@ -1196,7 +1206,7 @@ cdef class ntl_mat_ZZ(): The parameters a and b allow an arbitrary reduction parameter `\delta=a/b`, where `1/4 < a/b \leq 1`, where a and b are positive integers. For a basis reduced with parameter delta, the - squared length of the first non-zero basis vector is no more + squared length of the first nonzero basis vector is no more than `1/(delta-1/4)^{r-1}` times that of the shortest vector in the lattice. @@ -1205,16 +1215,17 @@ cdef class ntl_mat_ZZ(): Theory, Springer, 1993] INPUT: - a -- parameter a as described above (default: 3) - b -- parameter b as described above (default: 4) - return_U -- return U as described above - verbose -- if True NTL will produce some verbatim messages on - what's going on internally (default: ``False``) + + - ``a`` -- parameter a as described above (default: 3) + - ``b`` -- parameter b as described above (default: 4) + - ``return_U`` -- return U as described above + - ``verbose`` -- if ``True`` NTL will produce some verbatim messages on + what's going on internally (default: ``False``) OUTPUT: - (rank,det2,[U]) where rank,det2, and U are as described - above and U is an optional return value if return_U is - True. + + (rank,det2,[U]) where rank,det2, and U are as described + above and U is an optional return value if return_U is ``True``. EXAMPLES:: @@ -1260,9 +1271,9 @@ cdef class ntl_mat_ZZ(): rank = int(mat_ZZ_LLL(&det2,&self.x,int(a),int(b),int(verbose))) return rank, make_ZZ_sig_off(det2) - def LLL_FP(self, delta=0.75 , return_U=False, verbose=False): + def LLL_FP(self, delta=0.75, return_U=False, verbose=False): r""" - Performs approximate LLL reduction of \code{self} (puts + Perform approximate LLL reduction of \code{self} (puts \code{self} in an LLL form) subject to the following conditions: @@ -1294,14 +1305,16 @@ cdef class ntl_mat_ZZ(): status report is also printed every once in a while. INPUT: - delta -- as described above (0.5 <= delta < 1.0) (default: 0.75) - return_U -- return U as described above - verbose -- if True NTL will produce some verbatim messages on - what's going on internally (default: ``False``) + + - ``delta`` -- as described above (0.5 <= delta < 1.0) (default: 0.75) + - ``return_U`` -- return U as described above + - ``verbose`` -- if ``True`` NTL will produce some verbatim messages on + what's going on internally (default: ``False``) OUTPUT: - (rank,[U]) where rank and U are as described above and U - is an optional return value if return_U is True. + + (rank,[U]) where rank and U are as described above and U + is an optional return value if ``return_U`` is ``True``. EXAMPLES:: @@ -1349,7 +1362,7 @@ cdef class ntl_mat_ZZ(): def LLL_QP(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as \code{self.LLL_FP} using the + Perform the same reduction as \code{self.LLL_FP} using the same calling conventions but with quad float precision. EXAMPLES:: @@ -1373,7 +1386,7 @@ cdef class ntl_mat_ZZ(): def LLL_XD(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as \code{self.LLL_FP} using the + Perform the same reduction as \code{self.LLL_FP} using the same calling conventions but with extended exponent double precision. @@ -1398,7 +1411,7 @@ cdef class ntl_mat_ZZ(): def LLL_RR(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as \code{self.LLL_FP} using the + Perform the same reduction as \code{self.LLL_FP} using the same calling conventions but with arbitrary precision floating point numbers. @@ -1429,7 +1442,7 @@ cdef class ntl_mat_ZZ(): def G_LLL_FP(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as self.LLL_FP using the same + Perform the same reduction as self.LLL_FP using the same calling conventions but uses the Givens Orthogonalization. Givens Orthogonalization. This is a bit slower, but generally @@ -1453,7 +1466,7 @@ cdef class ntl_mat_ZZ(): def G_LLL_QP(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as self.G_LLL_FP using the same + Perform the same reduction as self.G_LLL_FP using the same calling conventions but with quad float precision. """ cdef ntl_mat_ZZ U @@ -1471,7 +1484,7 @@ cdef class ntl_mat_ZZ(): def G_LLL_XD(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as self.G_LLL_FP using the same + Perform the same reduction as self.G_LLL_FP using the same calling conventions but with extended exponent double precision. """ @@ -1490,7 +1503,7 @@ cdef class ntl_mat_ZZ(): def G_LLL_RR(self, delta, return_U=False, verbose=False): r""" - Performs the same reduction as self.G_LLL_FP using the same + Perform the same reduction as self.G_LLL_FP using the same calling conventions but with arbitrary precision floating point numbers. """ diff --git a/src/sage/libs/pari/convert_sage.pyx b/src/sage/libs/pari/convert_sage.pyx index a163dbf2b33..64386bcf632 100644 --- a/src/sage/libs/pari/convert_sage.pyx +++ b/src/sage/libs/pari/convert_sage.pyx @@ -60,12 +60,10 @@ cpdef gen_to_sage(Gen z, locals=None): - ``z`` -- PARI ``gen`` - - ``locals`` -- optional dictionary used in fallback cases that + - ``locals`` -- (optional) dictionary used in fallback cases that involve :func:`sage_eval` - OUTPUT: - - One of the following depending on the PARI type of ``z`` + OUTPUT: one of the following depending on the PARI type of ``z`` - a :class:`~sage.rings.integer.Integer` if ``z`` is an integer (type ``t_INT``) @@ -88,7 +86,7 @@ cpdef gen_to_sage(Gen z, locals=None): - a matrix if ``z`` is a matrix (type ``t_MAT``) - - a padic element (type ``t_PADIC``) + - a `p`-adic element (type ``t_PADIC``) - a :class:`~sage.rings.infinity.Infinity` if ``z`` is an infinity (type ``t_INF``) @@ -248,7 +246,7 @@ cpdef gen_to_sage(Gen z, locals=None): sage: a.parent() Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - Conversion of p-adics:: + Conversion of `p`-adics:: sage: # needs sage.rings.padics sage: z = pari('569 + O(7^8)'); z diff --git a/src/sage/libs/pari/meson.build b/src/sage/libs/pari/meson.build new file mode 100644 index 00000000000..5952060267c --- /dev/null +++ b/src/sage/libs/pari/meson.build @@ -0,0 +1,36 @@ +py.install_sources( + '__init__.py', + 'all.py', + 'convert_flint.pxd', + 'convert_gmp.pxd', + 'convert_sage.pxd', + 'convert_sage_complex_double.pxd', + 'convert_sage_real_double.pxd', + 'convert_sage_real_mpfr.pxd', + 'misc.pxd', + 'tests.py', + subdir: 'sage/libs/pari', +) + +extension_data = { + 'convert_flint' : files('convert_flint.pyx'), + 'convert_gmp' : files('convert_gmp.pyx'), + 'convert_sage' : files('convert_sage.pyx'), + 'convert_sage_complex_double' : files('convert_sage_complex_double.pyx'), + 'convert_sage_matrix' : files('convert_sage_matrix.pyx'), + 'convert_sage_real_double' : files('convert_sage_real_double.pyx'), + 'convert_sage_real_mpfr' : files('convert_sage_real_mpfr.pyx'), + 'misc' : files('misc.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/pari', + install: true, + include_directories: [inc_cpython, inc_ext, inc_flint, inc_gsl, inc_rings], + dependencies: [py_dep, cypari2, cysignals, flint, gmp, gsl, mpfr, pari], + ) +endforeach + diff --git a/src/sage/libs/pari/tests.py b/src/sage/libs/pari/tests.py index 43018a338d6..1ed571cd4b9 100644 --- a/src/sage/libs/pari/tests.py +++ b/src/sage/libs/pari/tests.py @@ -188,7 +188,7 @@ Reading a gp file:: sage: import tempfile - sage: gpfile = tempfile.NamedTemporaryFile(mode="w") + sage: gpfile = tempfile.NamedTemporaryFile(mode='w') sage: __ = gpfile.file.write("mysquare(n) = {\n") sage: __ = gpfile.file.write(" n^2;\n") sage: __ = gpfile.file.write("}\n") @@ -1195,7 +1195,7 @@ sage: k(2).__pari__().fforder(o=4) 4 -p-adic functions:: +`p`-adic functions:: sage: # needs sage.rings.padics sage: K = Qp(11,5) diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index 320044a9372..dddc452fd98 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -151,7 +151,6 @@ cdef extern from "singular/Singular/libsingular.h": void (*cfWrite)(number* a, const n_Procs_s* r) void (*cfNormalize)(number* a, const n_Procs_s* r) - bint (*cfDivBy)(number* a, number* b, const n_Procs_s* r) bint (*cfEqual)(number* a,number* b, const n_Procs_s* ) bint (*cfIsZero)(number* a, const n_Procs_s* ) # algebraic number comparison with zero @@ -160,7 +159,6 @@ cdef extern from "singular/Singular/libsingular.h": bint (*cfGreaterZero)(number* a, const n_Procs_s* ) void (*cfPower)(number* a, int i, number* * result, const n_Procs_s* r) # algebraic number power - ring *extRing int ch mpz_ptr modBase @@ -211,7 +209,6 @@ cdef extern from "singular/Singular/libsingular.h": int pCompIndex # index of components unsigned long bitmask # mask for getting single exponents - n_Procs_s* cf # coefficient field/ring int ref @@ -425,6 +422,7 @@ cdef extern from "singular/Singular/libsingular.h": cdef int si_opt_2 # previously 'verbose' cdef void * currentVoice cdef int myynest + cdef int printlevel ctypedef char * const_char_ptr "const char *" cdef extern void (*WerrorS_callback)(const_char_ptr) @@ -792,7 +790,6 @@ cdef extern from "singular/Singular/libsingular.h": number *nlCopy(number *) - # number to integer handle long SR_TO_INT(number *) @@ -812,7 +809,6 @@ cdef extern from "singular/Singular/libsingular.h": void id_Delete(ideal **, ring *) - # lifting ideal *idLift(ideal *mod, ideal *submod, ideal **rest, int goodShape, int isSB, int divide) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index a3b13cac604..c6f65eb718a 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -56,7 +56,7 @@ TESTS:: AUTHORS: - Michael Brickenstein (2009-07): initial implementation, overall design -- Martin Albrecht (2009-07): clean up, enhancements, etc +- Martin Albrecht (2009-07): clean up, enhancements, etc. - Michael Brickenstein (2009-10): extension to more Singular types - Martin Albrecht (2010-01): clean up, support for attributes - Simon King (2011-04): include the documentation provided by Singular as a code block @@ -358,7 +358,7 @@ cdef free_leftv(leftv *args, ring *r = NULL): INPUT: - - ``args`` -- a list of Singular arguments + - ``args`` -- list of Singular arguments """ args.CleanUp(r) omFreeBin(args, sleftv_bin) @@ -385,7 +385,6 @@ def is_sage_wrapper_for_singular_ring(ring): sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') sage: is_sage_wrapper_for_singular_ring(P) True - """ if isinstance(ring, MPolynomialRing_libsingular): return True @@ -420,7 +419,7 @@ def is_singular_poly_wrapper(p): def all_singular_poly_wrapper(s): """ - Tests for a sequence ``s``, whether it consists of + Test for a sequence ``s``, whether it consists of singular polynomials. EXAMPLES:: @@ -496,7 +495,7 @@ cdef class Converter(SageObject): INPUT: - - ``args`` -- a list of Python objects + - ``args`` -- list of Python objects - ``ring`` -- a multivariate polynomial ring - ``attributes`` -- an optional dictionary of Singular attributes (default: ``None``) @@ -1209,13 +1208,13 @@ cdef class SingularFunction(SageObject): INPUT: - - ``args`` -- a list of arguments + - ``args`` -- list of arguments - ``ring`` -- a multivariate polynomial ring - ``interruptible`` -- if ``True`` pressing :kbd:`Ctrl` + :kbd:`C` during the execution of this function will interrupt the computation (default: ``True``) - - ``attributes`` -- a dictionary of optional Singular + - ``attributes`` -- dictionary of optional Singular attributes assigned to Singular objects (default: ``None``) If ``ring`` is not specified, it is guessed from the given arguments. @@ -1303,7 +1302,7 @@ cdef class SingularFunction(SageObject): if dummy_ring is None: from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ - dummy_ring = PolynomialRing(QQ, "dummy", implementation="singular") # seems a reasonable default + dummy_ring = PolynomialRing(QQ, "dummy", implementation='singular') # seems a reasonable default ring = dummy_ring if not (isinstance(ring, MPolynomialRing_libsingular) or isinstance(ring, NCPolynomialRing_plural)): raise TypeError("cannot call Singular function '%s' with ring parameter of type '%s'" % (self._name,type(ring))) @@ -1331,12 +1330,12 @@ accepts the following keyword parameters: INPUT: -- ``args`` -- a list of arguments +- ``args`` -- list of arguments - ``ring`` -- a multivariate polynomial ring - ``interruptible`` -- if ``True`` pressing :kbd:`Ctrl` + :kbd:`C` during the execution of this function will interrupt the computation (default: ``True``) -- ``attributes`` -- a dictionary of optional Singular attributes +- ``attributes`` -- dictionary of optional Singular attributes assigned to Singular objects (default: ``None``) If ``ring`` is not specified, it is guessed from the given arguments. @@ -1381,7 +1380,7 @@ The Singular documentation for '%s' is given below. INPUT: - - ``args`` -- a list of Python objects + - ``args`` -- list of Python objects - ``ring`` -- an optional ring to check """ from sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense @@ -1824,13 +1823,52 @@ def lib(name): raise NameError("Singular library {!r} not found".format(name)) +def get_printlevel(): + """ + Return the value of the variable ``printlevel``. + + This is useful to switch off and back the comments. + + EXAMPLES:: + + sage: from sage.libs.singular.function import get_printlevel, set_printlevel + sage: l = get_printlevel() + sage: set_printlevel(-1) + sage: get_printlevel() + -1 + sage: set_printlevel(l) + """ + global printlevel + cdef int pl = printlevel + return pl + + +def set_printlevel(l): + """ + Set the value of the variable ``printlevel``. + + This is useful to switch off and back the comments. + + EXAMPLES:: + + sage: from sage.libs.singular.function import get_printlevel, set_printlevel + sage: l = get_printlevel() + sage: set_printlevel(2) + sage: get_printlevel() + 2 + sage: set_printlevel(l) + """ + global printlevel + printlevel = l + + def list_of_functions(packages=False): """ Return a list of all function names currently available. INPUT: - - ``packages`` -- include local functions in packages. + - ``packages`` -- include local functions in packages EXAMPLES:: diff --git a/src/sage/libs/singular/function_factory.py b/src/sage/libs/singular/function_factory.py index c4b0b52372f..939b52fab5b 100644 --- a/src/sage/libs/singular/function_factory.py +++ b/src/sage/libs/singular/function_factory.py @@ -15,7 +15,7 @@ from sage.libs.singular.function import singular_function, lib, list_of_functions -class SingularFunctionFactory(): +class SingularFunctionFactory: """ A convenient interface to libsingular functions. """ diff --git a/src/sage/libs/singular/groebner_strategy.pyx b/src/sage/libs/singular/groebner_strategy.pyx index f493b5dbbc3..4861527e697 100644 --- a/src/sage/libs/singular/groebner_strategy.pyx +++ b/src/sage/libs/singular/groebner_strategy.pyx @@ -95,7 +95,7 @@ cdef class GroebnerStrategy(SageObject): Check that :issue:`27508` is fixed:: - sage: R2. = PolynomialRing(QQ, 2, order="lex") + sage: R2. = PolynomialRing(QQ, 2, order='lex') sage: I2 = R2.ideal(["x^2 - x", "y^2 - y"]) sage: R2("x^2 + y").mod(I2), R2("x + y^2").mod(I2) (x + y, x + y) @@ -351,7 +351,6 @@ cdef class NCGroebnerStrategy(SageObject): Defining x1, x2, x3, x4, x5, x6 sage: I.reduce(x1*x2*x3 + x2^2*x4) x1*x2*x3 - """ if not isinstance(L, NCPolynomialIdeal): raise TypeError("First parameter must be an ideal in a g-algebra.") @@ -454,7 +453,6 @@ cdef class NCGroebnerStrategy(SageObject): sage: strat = NCGroebnerStrategy(I) sage: strat.ideal() == I True - """ return self._ideal @@ -529,7 +527,6 @@ cdef class NCGroebnerStrategy(SageObject): x*y^2 sage: ST.normal_form(x*y^2) y*z - """ if unlikely(p._parent is not self._parent): raise TypeError("parent(p) must be the same as this object's parent.") diff --git a/src/sage/libs/singular/meson.build b/src/sage/libs/singular/meson.build new file mode 100644 index 00000000000..52ece586caa --- /dev/null +++ b/src/sage/libs/singular/meson.build @@ -0,0 +1,34 @@ +py.install_sources( + '__init__.py', + 'decl.pxd', + 'function.pxd', + 'function_factory.py', + 'groebner_strategy.pxd', + 'polynomial.pxd', + 'ring.pxd', + 'singular.pxd', + 'standard_options.py', + subdir: 'sage/libs/singular', +) + +extension_data_cpp = { + 'function': files('function.pyx'), + 'groebner_strategy': files('groebner_strategy.pyx'), + 'option': files('option.pyx'), + 'polynomial': files('polynomial.pyx'), + 'ring': files('ring.pyx'), + 'singular': files('singular.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/singular', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ntl, inc_rings, inc_rings_finite], + dependencies: [py_dep, cysignals, givaro, gmp, singular], + ) +endforeach + diff --git a/src/sage/libs/singular/option.pyx b/src/sage/libs/singular/option.pyx index 5f788301cdb..3855fb2f732 100644 --- a/src/sage/libs/singular/option.pyx +++ b/src/sage/libs/singular/option.pyx @@ -20,15 +20,17 @@ By default, tail reductions are performed:: sage: from sage.libs.singular.option import opt, opt_ctx sage: opt['red_tail'] True - sage: std(I)[-1] + sage: red = std(I)[-1]; red d^2*e^6 + 28*b*c*d + ... If we don't want this, we can create an option context, which disables this:: sage: with opt_ctx(red_tail=False, red_sb=False): - ....: std(I)[-1] - d^2*e^6 + 8*c^3 + ... + ....: notred = std(I)[-1]; notred + d^2*e^6 + ... + sage: len(list(red)) < len(list(notred)) + True However, this does not affect the global state:: @@ -146,7 +148,7 @@ cdef class LibSingularOptions_abstract: """ INPUT: - - ``**kwds`` -- all keyword parameters are immediately applied. + - ``**kwds`` -- all keyword parameters are immediately applied EXAMPLES:: @@ -302,72 +304,72 @@ cdef class LibSingularOptions(LibSingularOptions_abstract): Supported options are: - - ``return_sb`` or ``returnSB`` -- the functions ``syz``, - ``intersect``, ``quotient``, ``modulo`` return a standard - base instead of a generating set if ``return_sb`` - is set. This option should not be used for ``lift``. + - ``return_sb`` or ``returnSB`` -- the functions ``syz``, + ``intersect``, ``quotient``, ``modulo`` return a standard + base instead of a generating set if ``return_sb`` + is set. This option should not be used for ``lift``. - - ``fast_hc`` or ``fastHC`` -- tries to find the highest corner - of the staircase (HC) as fast as possible during a standard - basis computation (only used for local orderings). + - ``fast_hc`` or ``fastHC`` -- tries to find the highest corner + of the staircase (HC) as fast as possible during a standard + basis computation (only used for local orderings). - - ``int_strategy`` or ``intStrategy`` -- avoids division of - coefficients during standard basis computations. This option - is ring dependent. By default, it is set for rings with - characteristic 0 and not set for all other rings. + - ``int_strategy`` or ``intStrategy`` -- avoids division of + coefficients during standard basis computations. This option + is ring dependent. By default, it is set for rings with + characteristic 0 and not set for all other rings. - - ``lazy`` -- uses a more lazy approach in std computations, which - was used in SINGULAR version before 2-0 (and which may lead to - faster or slower computations, depending on the example). + - ``lazy`` -- uses a more lazy approach in std computations, which + was used in SINGULAR version before 2-0 (and which may lead to + faster or slower computations, depending on the example). - - ``length`` -- select shorter reducers in std computations. + - ``length`` -- select shorter reducers in std computations - - ``not_regularity`` or ``notRegularity`` -- disables the - regularity bound for ``res`` and ``mres``. + - ``not_regularity`` or ``notRegularity`` -- disables the + regularity bound for ``res`` and ``mres`` - - ``not_sugar`` or ``notSugar`` -- disables the sugar strategy - during standard basis computation. + - ``not_sugar`` or ``notSugar`` -- disables the sugar strategy + during standard basis computation - - ``not_buckets`` or ``notBuckets`` -- disables the bucket - representation of polynomials during standard basis - computations. This option usually decreases the memory - usage but increases the computation time. It should only - be set for memory-critical standard basis computations. + - ``not_buckets`` or ``notBuckets`` -- disables the bucket + representation of polynomials during standard basis + computations. This option usually decreases the memory + usage but increases the computation time. It should only + be set for memory-critical standard basis computations. - - ``old_std`` or ``oldStd`` -- uses a more lazy approach in std - computations, which was used in SINGULAR version before 2-0 - (and which may lead to faster or slower computations, depending - on the example). + - ``old_std`` or ``oldStd`` -- uses a more lazy approach in std + computations, which was used in SINGULAR version before 2-0 + (and which may lead to faster or slower computations, depending + on the example). - - ``prot`` -- shows protocol information indicating the progress - during the following computations: ``facstd``, ``fglm``, - ``groebner``, ``lres``, ``mres``, ``minres``, ``mstd``, - ``res``, ``slimgb``, ``sres``, ``std``, ``stdfglm``, - ``stdhilb``, ``syz``. + - ``prot`` -- shows protocol information indicating the progress + during the following computations: ``facstd``, ``fglm``, + ``groebner``, ``lres``, ``mres``, ``minres``, ``mstd``, + ``res``, ``slimgb``, ``sres``, ``std``, ``stdfglm``, + ``stdhilb``, ``syz``. - - ``red_sb`` or ``redSB`` -- computes a reduced standard basis in - any standard basis computation. + - ``red_sb`` or ``redSB`` -- computes a reduced standard basis in + any standard basis computation - - ``red_tail`` or ``redTail`` -- reduction of the tails of - polynomials during standard basis computations. This option - is ring dependent. By default, it is set for rings with global - degree orderings and not set for all other rings. + - ``red_tail`` or ``redTail`` -- reduction of the tails of + polynomials during standard basis computations. This option + is ring dependent. By default, it is set for rings with global + degree orderings and not set for all other rings. - - ``red_through`` or ``redThrough`` -- for inhomogeneous input, - polynomial reductions during standard basis computations are - never postponed, but always finished through. This option is - ring dependent. By default, it is set for rings with global - degree orderings and not set for all other rings. + - ``red_through`` or ``redThrough`` -- for inhomogeneous input, + polynomial reductions during standard basis computations are + never postponed, but always finished through. This option is + ring dependent. By default, it is set for rings with global + degree orderings and not set for all other rings. - - ``sugar_crit`` or ``sugarCrit`` -- uses criteria similar to the - homogeneous case to keep more useless pairs. + - ``sugar_crit`` or ``sugarCrit`` -- uses criteria similar to the + homogeneous case to keep more useless pairs - - ``weight_m`` or ``weightM`` -- automatically computes suitable - weights for the weighted ecart and the weighted sugar method. + - ``weight_m`` or ``weightM`` -- automatically computes suitable + weights for the weighted ecart and the weighted sugar method In addition, two integer valued parameters are supported, namely: - - ``deg_bound`` or ``degBound`` -- The standard basis computation + - ``deg_bound`` or ``degBound`` -- the standard basis computation is stopped if the total (weighted) degree exceeds ``deg_bound``. ``deg_bound`` should not be used for a global ordering with inhomogeneous input. Reset this bound by setting ``deg_bound`` @@ -375,7 +377,7 @@ cdef class LibSingularOptions(LibSingularOptions_abstract): and the command: ``slimgb`` uses always the total degree with weights 1, ``std`` does so for block orderings, only. - - ``mult_bound`` or ``multBound`` -- The standard basis computation + - ``mult_bound`` or ``multBound`` -- the standard basis computation is stopped if the ideal is zero-dimensional in a ring with local ordering and its multiplicity is lower than ``mult_bound``. Reset this bound by setting ``mult_bound`` to 0. @@ -408,7 +410,6 @@ cdef class LibSingularOptions(LibSingularOptions_abstract): sage: opt['red_tail'] = True # the previous commands reset opt['red_tail'] to False sage: J.groebner_basis() [x^3*y^2 + y^3*z^2 + x^2*z^3, x^2*y^3 + x^3*z^2 + y^2*z^3, y^5, x^6, x^4*z^2 - y^4*z^2 - x^2*y*z^3 + x*y^2*z^3, z^6, y^4*z^3 - y^3*z^4 - x^2*z^5, x^3*y*z^4 - x^2*y^2*z^4 + x*y^3*z^4, x^3*z^5, x^2*y*z^5 + y^3*z^5, x*y^3*z^5] - """ def __init__(self, **kwds): """ @@ -475,27 +476,27 @@ cdef class LibSingularVerboseOptions(LibSingularOptions_abstract): Supported options are: - - ``mem`` -- shows memory usage in square brackets. - - ``yacc`` -- Only available in debug version. - - ``redefine`` -- warns about variable redefinitions. - - ``reading`` -- shows the number of characters read from a file. - - ``loadLib`` or ``load_lib`` -- shows loading of libraries. - - ``debugLib`` or ``debug_lib`` -- warns about syntax errors - when loading a library. - - ``loadProc`` or ``load_proc`` -- shows loading of procedures - from libraries. - - ``defRes`` or ``def_res`` -- shows the names of the syzygy - modules while converting ``resolution`` to ``list``. - - ``usage`` -- shows correct usage in error messages. - - ``Imap`` or ``imap`` -- shows the mapping of variables with - the ``fetch`` and ``imap`` commands. - - ``notWarnSB`` or ``not_warn_sb`` -- do not warn if - a basis is not a standard basis - - ``contentSB`` or ``content_sb`` -- avoids to divide by the - content of a polynomial in ``std`` and related algorithms. - Should usually not be used. - - ``cancelunit`` -- avoids to divide polynomials by non-constant - units in ``std`` in the local case. Should usually not be used. + - ``mem`` -- shows memory usage in square brackets + - ``yacc`` -- only available in debug version + - ``redefine`` -- warns about variable redefinitions + - ``reading`` -- shows the number of characters read from a file + - ``loadLib`` or ``load_lib`` -- shows loading of libraries + - ``debugLib`` or ``debug_lib`` -- warns about syntax errors + when loading a library + - ``loadProc`` or ``load_proc`` -- shows loading of procedures + from libraries + - ``defRes`` or ``def_res`` -- shows the names of the syzygy + modules while converting ``resolution`` to ``list`` + - ``usage`` -- shows correct usage in error messages + - ``Imap`` or ``imap`` -- shows the mapping of variables with + the ``fetch`` and ``imap`` commands + - ``notWarnSB`` or ``not_warn_sb`` -- do not warn if + a basis is not a standard basis + - ``contentSB`` or ``content_sb`` -- avoids to divide by the + content of a polynomial in ``std`` and related algorithms. + Should usually not be used. + - ``cancelunit`` -- avoids to divide polynomials by non-constant + units in ``std`` in the local case. Should usually not be used EXAMPLES:: @@ -536,7 +537,7 @@ cdef class LibSingularVerboseOptions(LibSingularOptions_abstract): def reset_default(self): """ - Return to libSingular's default verbosity options + Return to libSingular's default verbosity options. EXAMPLES:: @@ -549,7 +550,6 @@ cdef class LibSingularVerboseOptions(LibSingularOptions_abstract): sage: opt_verb.reset_default() sage: opt_verb['not_warn_sb'] False - """ from sage.libs.singular.singular import _saved_verbose_options self.global_options[0] = int(_saved_verbose_options) diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index 8908bb8a414..6f7f576cb02 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -142,11 +142,10 @@ cdef int singular_polynomial_call(poly **ret, poly *p, ring *r, list args, - ``ret`` -- a pointer to a Singular polynomial to store the result in - ``p`` -- a Singular polynomial - ``r`` -- a Singular ring - - ``args`` -- a list/tuple of elements which can be converted to - Singular polynomials using the ``(get_element)`` function - provided. + - ``args`` -- list/tuple of elements which can be converted to Singular + polynomials using the ``(get_element)`` function provided - ``(*get_element)`` -- a function to turn a Sage element into a - Singular element. + Singular element EXAMPLES:: @@ -178,7 +177,7 @@ cdef int singular_polynomial_call(poly **ret, poly *p, ring *r, list args, Loop (at most 30 times) until we have 6 consecutive zeros when calling ``leak(10000)``. Depending on the operating system, it is - possible to have several non-zero leak values in the beginning, but + possible to have several nonzero leak values in the beginning, but after a while we should get only zeros. The fact that we require 6 zeros also means that Singular's pre-allocated buckets should not be sufficient if there really would be a memory leak. :: @@ -468,7 +467,7 @@ cdef object singular_polynomial_latex(poly *p, ring *r, object base, object late sage: latex(10*x^2 + 1/2*y) 10 x^{2} + \frac{1}{2} y - Demonstrate that coefficients over non-atomic representated rings are + Demonstrate that coefficients over non-atomic represented rings are properly parenthesized (:issue:`11186`):: sage: x = var('x') @@ -591,7 +590,7 @@ cdef int singular_polynomial_length_bounded(poly *p, int bound) noexcept: INPUT: - ``p`` -- a Singular polynomial - - ``bound`` -- an integer > 0 + - ``bound`` -- integer > 0 """ cdef int count = 0 while p != NULL and count < bound: @@ -620,7 +619,7 @@ cdef int singular_polynomial_subst(poly **p, int var_index, poly *value, ring *r INPUT: - ``p`` -- a polynomial - - ``var_index`` -- an integer < ngens (zero based indexing) + - ``var_index`` -- integer < ngens (zero based indexing) - ``value`` -- a polynomial - ``r`` -- a ring """ diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index cc6d1cf9d41..f770cc483a5 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -91,7 +91,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: - ``n`` -- the number of variables (> 0) - - ``names`` -- a list of names of length ``n`` + - ``names`` -- list of names of length ``n`` - ``term_order`` -- a term ordering @@ -170,7 +170,6 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: sage: sing_print = singular_function('print') sage: sing_print(R) 'polynomial ring, over a field, global ordering\n// coefficients: QQ(s, t)\n// number of vars : 3\n// block 1 : ordering dp\n// : names x y z\n// block 2 : ordering C' - """ cdef long cexponent cdef GFInfo* _param @@ -294,12 +293,14 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: if isinstance(base_ring, RationalField): characteristic = 0 - _ring = rDefault( characteristic ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault(characteristic, nvars, _names, nblcks, + _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, FractionField_generic) and isinstance(base_ring.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base_ring.base().base_ring(), RationalField): characteristic = 1 k = PolynomialRing(RationalField(), - names=base_ring.variable_names(), order="lex", implementation="singular") + names=base_ring.variable_names(), order='lex', + implementation='singular') ngens = len(k.gens()) @@ -318,14 +319,14 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: if (_cf is NULL): raise RuntimeError("Failed to allocate _cf ring.") - _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, FractionField_generic) and isinstance(base_ring.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base_ring.base().base_ring(), FiniteField_generic): if not base_ring.base_ring().is_prime_field(): raise NotImplementedError("Transcental extension are not implemented for non-prime finite fields") characteristic = int(base_ring.characteristic()) k = PolynomialRing(base_ring.base_ring(), - names=base_ring.variable_names(), order="lex", implementation="singular") + names=base_ring.variable_names(), order='lex', implementation='singular') ngens = len(k.gens()) @@ -344,12 +345,12 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: if (_cf is NULL): raise RuntimeError("Failed to allocate _cf ring.") - _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, NumberField) and base_ring.is_absolute(): characteristic = 1 k = PolynomialRing(RationalField(), - name=base_ring.variable_name(), order="lex", implementation="singular") + name=base_ring.variable_name(), order='lex', implementation='singular') minpoly = base_ring.polynomial()(k.gen()) @@ -370,11 +371,11 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: if (_cf is NULL): raise RuntimeError("Failed to allocate _cf ring.") - _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, IntegerRing_class): _cf = nInitChar( n_Z, NULL) # integer coefficient ring - _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif (isinstance(base_ring, FiniteField_generic) and base_ring.is_prime_field()): if base_ring.characteristic() <= 2147483647: @@ -385,7 +386,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: # example for simpler ring creation interface without monomial orderings: #_ring = rDefault(characteristic, nvars, _names) - _ring = rDefault( characteristic , nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault(characteristic, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, FiniteField_generic): if base_ring.characteristic() <= 2147483647: @@ -395,7 +396,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: # TODO: This is lazy, it should only call Singular stuff not PolynomialRing() k = PolynomialRing(base_ring.prime_subfield(), - name=base_ring.variable_name(), order="lex", implementation="singular") + name=base_ring.variable_name(), order='lex', implementation='singular') minpoly = base_ring.polynomial()(k.gen()) ch = base_ring.characteristic() @@ -419,7 +420,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: if (_cf is NULL): raise RuntimeError("Failed to allocate _cf ring.") - _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, sage.rings.abc.IntegerModRing): @@ -473,12 +474,12 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: mpz_init_set_ui(_info.base, characteristic) _info.exp = 1 _cf = nInitChar( n_Zn, &_info ) - _ring = rDefault( _cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + _ring = rDefault(_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) else: raise NotImplementedError(f"polynomials over {base_ring} are not supported in Singular") - if (_ring is NULL): + if _ring is NULL: raise ValueError("Failed to allocate Singular ring.") _ring.ShortOut = 0 @@ -545,9 +546,7 @@ cdef class ring_wrapper_Py(): """ Return a hash value so that instances can be used as dictionary keys. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -562,9 +561,7 @@ cdef class ring_wrapper_Py(): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -588,9 +585,7 @@ cdef class ring_wrapper_Py(): - ``right`` -- a :class:`ring_wrapper_Py` - OUTPUT: - - True if both ``ring_wrapper_Py`` wrap the same pointer. + OUTPUT: ``True`` if both ``ring_wrapper_Py`` wrap the same pointer EXAMPLES:: @@ -627,7 +622,7 @@ cdef wrap_ring(ring* R): INPUT: - - ``R`` -- a singular ring (a C datastructure). + - ``R`` -- a singular ring (a C datastructure) OUTPUT: @@ -644,7 +639,7 @@ cdef ring *singular_ring_reference(ring *existing_ring) except NULL: INPUT: - - ``existing_ring`` -- a Singular ring. + - ``existing_ring`` -- a Singular ring OUTPUT: @@ -760,7 +755,7 @@ cpdef poison_currRing(frame, event, arg): INPUT: - ``frame``, ``event``, ``arg`` -- the standard arguments for the - CPython debugger hook. They are not used. + CPython debugger hook; they are not used OUTPUT: @@ -802,7 +797,8 @@ cpdef print_currRing(): def currRing_wrapper(): """ - Returns a wrapper for the current ring, for use in debugging ring_refcount_dict. + Return a wrapper for the current ring, for use in debugging + ``ring_refcount_dict``. EXAMPLES:: diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 465d0841396..9c7b4078583 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -69,9 +69,7 @@ cdef Rational si2sa_QQ(number *n, number **nn, ring *_ring): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - OUTPUT: - - - A sage Rational + OUTPUT: a sage Rational TESTS:: @@ -139,9 +137,7 @@ cdef Integer si2sa_ZZ(number *n, ring *_ring): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - OUTPUT: - - - A sage Integer + OUTPUT: a sage Integer TESTS:: @@ -174,11 +170,9 @@ cdef FFgivE si2sa_GFqGivaro(number *n, ring *_ring, Cache_givaro cache): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``cache`` -- A Givaro number field - - OUTPUT: + - ``cache`` -- a Givaro number field - - A sage element of ``cache`` + OUTPUT: a sage element of ``cache`` TESTS:: @@ -230,11 +224,9 @@ cdef FFgf2eE si2sa_GFqNTLGF2E(number *n, ring *_ring, Cache_ntl_gf2e cache): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``cache`` -- A ntl_gf2e number field + - ``cache`` -- a ntl_gf2e number field - OUTPUT: - - - A sage element of ``cache`` + OUTPUT: a sage element of ``cache`` TESTS:: @@ -281,11 +273,9 @@ cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``base`` -- A sage finite field + - ``base`` -- a sage finite field - OUTPUT: - - - A sage element of ``base`` + OUTPUT: a sage element of ``base`` TESTS:: @@ -345,11 +335,9 @@ cdef object si2sa_transext_QQ(number *n, ring *_ring, object base): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``base`` -- A sage FractionField - - OUTPUT: + - ``base`` -- a sage FractionField - - A sage element of ``base`` + OUTPUT: a sage element of ``base`` TESTS:: @@ -434,11 +422,9 @@ cdef object si2sa_transext_FF(number *n, ring *_ring, object base): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``base`` -- A sage FractionField - - OUTPUT: + - ``base`` -- a sage FractionField - - A sage element of ``base`` + OUTPUT: a sage element of ``base`` TESTS:: @@ -514,11 +500,9 @@ cdef object si2sa_NF(number *n, ring *_ring, object base): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``base`` -- A sage NumberField + - ``base`` -- a sage NumberField - OUTPUT: - - - A sage element of ``base`` + OUTPUT: a sage element of ``base`` TESTS:: @@ -579,11 +563,9 @@ cdef inline object si2sa_ZZmod(number *n, ring *_ring, object base): - ``_ ring`` -- a (pointer to) a singular ring, in whose coefficient field lives ``n`` - - ``base`` -- A sage IntegerModRing + - ``base`` -- a sage IntegerModRing - OUTPUT: - - - A sage element of ``base`` + OUTPUT: a sage element of ``base`` TESTS:: @@ -932,7 +914,7 @@ cdef number *sa2si_GFqGivaro(int quo, ring *_ring) noexcept: INPUT: - - ``quo`` -- a sage integer + - ``quo`` -- sage integer - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live @@ -1206,8 +1188,8 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring) noexcept: if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") - numerdic = elem.numerator().dict() - denomdic = elem.denominator().dict() + numerdic = elem.numerator().monomial_coefficients() + denomdic = elem.denominator().monomial_coefficients() if numerdic and not isinstance(list(numerdic)[0], (tuple, ETuple)): numerdic = {(k,):b for k,b in numerdic.items()} @@ -1321,8 +1303,8 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring) noexcept: if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") - numerdic = elem.numerator().dict() - denomdic = elem.denominator().dict() + numerdic = elem.numerator().monomial_coefficients() + denomdic = elem.denominator().monomial_coefficients() if numerdic and not isinstance(list(numerdic)[0], (tuple, ETuple)): numerdic = {(k,):b for k,b in numerdic.items()} @@ -1339,11 +1321,11 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring) noexcept: a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): aux1 = naCoeff - naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) + naCoeff = _ring.cf.cfMult(aux1, a, _ring.cf) _ring.cf.cfDelete(&aux1, _ring.cf) _ring.cf.cfDelete(&a, _ring.cf) aux2 = numerator - numerator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) + numerator = _ring.cf.cfAdd(aux2, naCoeff, _ring.cf) _ring.cf.cfDelete(&naCoeff, _ring.cf) _ring.cf.cfDelete(&aux2, _ring.cf) @@ -1356,7 +1338,7 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring) noexcept: a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): aux1 = naCoeff - naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) + naCoeff = _ring.cf.cfMult(aux1, a, _ring.cf) _ring.cf.cfDelete(&aux1, _ring.cf) _ring.cf.cfDelete(&a, _ring.cf) aux2 = denominator @@ -1443,11 +1425,11 @@ cdef number *sa2si_NF(object elem, ring *_ring) noexcept: rComplete(qqr,1) qqr.ShortOut = 0 - nMapFuncPtr = naSetMap( qqr.cf , _ring.cf ) # choose correct mapping function + nMapFuncPtr = naSetMap(qqr.cf, _ring.cf) # choose correct mapping function cdef poly *_p for i from 0 <= i < len(elem): nlCoeff = nlInit2gmp( mpq_numref((elem[i]).value), mpq_denref((elem[i]).value), qqr.cf ) - naCoeff = nMapFuncPtr(nlCoeff, qqr.cf , _ring.cf ) + naCoeff = nMapFuncPtr(nlCoeff, qqr.cf, _ring.cf) nlDelete(&nlCoeff, _ring.cf) # faster would be to assign the coefficient directly @@ -1566,9 +1548,9 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept: _name = omStrDup("a") _ext_names = omAlloc0(sizeof(char*)) _ext_names[0] = omStrDup(_name) - _cf = nInitChar( n_Z, NULL) # integer coefficient ring - ZZr = rDefault (_cf ,1, _ext_names) - rComplete(ZZr,1) + _cf = nInitChar(n_Z, NULL) # integer coefficient ring + ZZr = rDefault (_cf, 1, _ext_names) + rComplete(ZZr, 1) ZZr.ShortOut = 0 nn = nrzInit(0, ZZr.cf) @@ -1581,7 +1563,7 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept: cdef object si2sa(number *n, ring *_ring, object base): r""" - Create a sage number from a singular one + Create a sage number from a singular one. INPUT: @@ -1636,10 +1618,10 @@ cdef number *sa2si(Element elem, ring * _ring) noexcept: INPUT: - - ``elem`` -- a sage element from a parent. The parent must have a - corresponding singular coefficient type. + - ``elem`` -- a sage element from a parent; the parent must have a + corresponding singular coefficient type - - ``_ring`` -- a (pointer to) the singular ring where the result will live. + - ``_ring`` -- a (pointer to) the singular ring where the result will live OUTPUT: @@ -1680,7 +1662,7 @@ cdef number *sa2si(Element elem, ring * _ring) noexcept: cdef object si2sa_intvec(intvec *v): r""" - create a sage tuple from a singular vector of integers + Create a sage tuple from a singular vector of integers. INPUT: @@ -1698,7 +1680,7 @@ cdef object si2sa_intvec(intvec *v): cdef object si2sa_bigintvec(bigintmat *v): r""" - create a sage tuple from a singular vector of big integers + Create a sage tuple from a singular vector of big integers. INPUT: @@ -1726,13 +1708,13 @@ from posix.dlfcn cimport dlopen, dlclose, dlerror, RTLD_LAZY, RTLD_GLOBAL cdef int overflow_check(unsigned long e, ring *_ring) except -1: """ - Raise an ``OverflowError`` if e is > max degree per variable. + Raise an :exc:`OverflowError` if e is > max degree per variable. INPUT: - - ``e`` -- some integer representing a degree. + - ``e`` -- some integer representing a degree - - ``_ring`` -- a pointer to some ring. + - ``_ring`` -- a pointer to some ring Whether an overflow occurs or not partially depends @@ -1742,7 +1724,6 @@ cdef int overflow_check(unsigned long e, ring *_ring) except -1: which in both cases makes a maximal default exponent of 2^16-1. - EXAMPLES:: sage: P. = QQ[] @@ -1839,9 +1820,7 @@ def get_resource(id): - ``id`` -- a single-character string; see https://github.com/Singular/Singular/blob/spielwiese/resources/feResource.cc - OUTPUT: - - A string, or ``None``. + OUTPUT: string or ``None`` EXAMPLES:: diff --git a/src/sage/libs/singular/standard_options.py b/src/sage/libs/singular/standard_options.py index 341650fa6ba..476961b2f09 100644 --- a/src/sage/libs/singular/standard_options.py +++ b/src/sage/libs/singular/standard_options.py @@ -27,7 +27,6 @@ def __init__(self): sage: with LibSingularGBDefaultContext(): rgb = groebner(I) sage: rgb [84*c^4 - 40*c^3 + c^2 + c, 7*b + 210*c^3 - 79*c^2 + 3*c, 7*a - 420*c^3 + 158*c^2 + 8*c - 7] - """ from sage.libs.singular.option import opt_ctx self.libsingular_option_context = opt_ctx @@ -60,7 +59,6 @@ def __enter__(self): 5913075*c + 371438283744*d^7 - 237550027104*d^6 + 22645939824*d^5 + 11520686172*d^4 - 2024910556*d^3 - 132524276*d^2 + 30947828*d, 1971025*b - 97197721632*d^7 + 73975630752*d^6 - 12121915032*d^5 - 2760941496*d^4 + 814792828*d^3 - 1678512*d^2 - 9158924*d, 5913075*a - 159690237696*d^7 + 31246269696*d^6 + 27439610544*d^5 - 6475723368*d^4 - 838935856*d^3 + 275119624*d^2 + 4884038*d - 5913075] - """ self.libsingular_option_context.__enter__() self.libsingular_option_context.opt.reset_default() @@ -127,7 +125,7 @@ def libsingular_gb_standard_options(func): ... ' return self.basis.reduced()\n'], ...) - .. note:: + .. NOTE:: This decorator is used automatically internally so the user does not need to use it manually. diff --git a/src/sage/libs/sirocco.pyx b/src/sage/libs/sirocco.pyx index 8cca0892c55..ca3b267fa66 100644 --- a/src/sage/libs/sirocco.pyx +++ b/src/sage/libs/sirocco.pyx @@ -45,7 +45,6 @@ cpdef list[list] contpath_mp(int deg, list values, RealNumber y0r, RealNumber y0 [(0.000000000000000, 0.000000000000000, 0.000000000000000), (0.500000000000000, -0.250000000000000, 0.000000000000000), (1.00000000000000, -1.00000000000000, 0.000000000000000)] - """ cdef mpfr_t* cvalues = check_allocarray(len(values), sizeof(mpfr_t)) cdef mpfr_t* rop @@ -113,7 +112,6 @@ cpdef list[list] contpath_mp_comps(int deg, list values, RealNumber y0r, RealNum (0.750000000000000, -0.562500000000000, 0.000000000000000), (0.875000000000000, -0.765625000000000, 0.000000000000000), (1.00000000000000, -1.00000000000000, 0.000000000000000)] - """ cdef mpfr_t* cvalues = check_allocarray(len(values), sizeof(mpfr_t)) @@ -199,7 +197,6 @@ cpdef list[list] contpath(int deg, list values, double y0r, double y0i) noexcept (0.3535533905932738, -0.12500000000000003, 0.0), (0.7071067811865476, -0.5000000000000001, 0.0), (1.0, -1.0, 0.0)] - """ cdef double* rop cdef double* c_values = check_allocarray(len(values), sizeof(double)) @@ -260,7 +257,6 @@ cpdef list[list] contpath_comps(int deg, list values, double y0r, double y0i, li (0.75, -0.5625, 0.0), (0.875, -0.765625, 0.0), (1.0, -1.0, 0.0)] - """ cdef double* rop cdef double* c_values = check_allocarray(len(values), sizeof(double)) diff --git a/src/sage/libs/symmetrica/kostka.pxi b/src/sage/libs/symmetrica/kostka.pxi index d69aefc7c2c..52806829eab 100644 --- a/src/sage/libs/symmetrica/kostka.pxi +++ b/src/sage/libs/symmetrica/kostka.pxi @@ -6,9 +6,10 @@ cdef extern from 'symmetrica/def.h': INT kostka_tab(OP shape, OP content, OP result) INT kostka_tafel(OP n, OP result) + def kostka_number_symmetrica(shape, content): """ - computes the kostkanumber, i.e. the number of + Compute the kostkanumber, i.e. the number of tableaux of given shape, which is a PARTITION object, and of given content, which also is a PARTITION object, or a VECTOR object with INTEGER entries. The @@ -53,9 +54,10 @@ def kostka_number_symmetrica(shape, content): return res + def kostka_tab_symmetrica(shape, content): """ - computes the list of tableaux of given shape + Compute the list of tableaux of given shape and content. shape is a PARTITION object or a SKEWPARTITION object and content is a PARTITION object or a VECTOR object with @@ -77,8 +79,6 @@ def kostka_tab_symmetrica(shape, content): [[None, 2], [None, 3], [1]]] sage: symmetrica.kostka_tab([[2,2],[1]],[1,1,1]) [[[None, 1], [2, 3]], [[None, 2], [1, 3]]] - - """ late_import() @@ -113,9 +113,10 @@ def kostka_tab_symmetrica(shape, content): return res + def kostka_tafel_symmetrica(n): """ - Returns the table of Kostka numbers of weight n. + Return the table of Kostka numbers of weight `n`. EXAMPLES:: diff --git a/src/sage/libs/symmetrica/meson.build b/src/sage/libs/symmetrica/meson.build new file mode 100644 index 00000000000..9294ebe3b03 --- /dev/null +++ b/src/sage/libs/symmetrica/meson.build @@ -0,0 +1,18 @@ +# Cannot be found by pkg-config +symmetrica = cc.find_library('symmetrica') + +py.install_sources('__init__.py', 'all.py', subdir: 'sage/libs/symmetrica') + +extension_data = {'symmetrica' : files('symmetrica.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/libs/symmetrica', + install: true, + include_directories: [], + dependencies: [py_dep, cysignals, gmp, symmetrica], + ) +endforeach + diff --git a/src/sage/libs/symmetrica/part.pxi b/src/sage/libs/symmetrica/part.pxi index 37a3c0ff8f0..a6c1a1e2fa2 100644 --- a/src/sage/libs/symmetrica/part.pxi +++ b/src/sage/libs/symmetrica/part.pxi @@ -6,12 +6,12 @@ cdef extern from 'symmetrica/def.h': INT gupta_tafel(OP max, OP res) INT random_partition(OP nx, OP res) + def strict_to_odd_part_symmetrica(part): """ - implements the bijection between strict partitions + Implement the bijection between strict partitions and partitions with odd parts. input is a VECTOR type partition, the result is a partition of the same weight with only odd parts. - """ #Make sure that the partition is strict @@ -37,9 +37,10 @@ def strict_to_odd_part_symmetrica(part): return res + def odd_to_strict_part_symmetrica(part): """ - implements the bijection between partitions with odd parts + Implement the bijection between partitions with odd parts and strict partitions. input is a VECTOR type partition, the result is a partition of the same weight with different parts. """ @@ -70,12 +71,11 @@ def odd_to_strict_part_symmetrica(part): def q_core_symmetrica(part, d): """ - computes the q-core of a PARTITION object + Compute the q-core of a PARTITION object part. This is the remaining partition (=res) after removing of all hooks of length d (= INTEGER object). The result may be an empty object, if the whole partition disappears. - """ @@ -102,7 +102,7 @@ def q_core_symmetrica(part, d): def gupta_nm_symmetrica(n, m): """ - this routine computes the number of partitions + This routine computes the number of partitions of n with maximal part m. The result is erg. The input n,m must be INTEGER objects. The result is freed first to an empty object. The result must @@ -131,9 +131,10 @@ def gupta_nm_symmetrica(n, m): return res + def gupta_tafel_symmetrica(max): """ - it computes the table of the above values. The entry + It computes the table of the above values. The entry n,m is the result of gupta_nm. mat is freed first. max must be an INTEGER object, it is the maximum weight for the partitions. max must be different from diff --git a/src/sage/libs/symmetrica/plet.pxi b/src/sage/libs/symmetrica/plet.pxi index b1f8450c621..39cfbbe7d87 100644 --- a/src/sage/libs/symmetrica/plet.pxi +++ b/src/sage/libs/symmetrica/plet.pxi @@ -2,10 +2,8 @@ cdef extern from 'symmetrica/def.h': INT plethysm(OP s1, OP s2, OP res) INT schur_schur_plet(OP p1, OP p2, OP res) -def plethysm_symmetrica(outer, inner): - """ - """ +def plethysm_symmetrica(outer, inner): cdef OP couter = callocobject(), cinner = callocobject(), cresult = callocobject() _op_schur(outer, couter) @@ -25,9 +23,6 @@ def plethysm_symmetrica(outer, inner): def schur_schur_plet_symmetrica(outer, inner): - """ - """ - cdef OP couter = callocobject(), cinner = callocobject(), cresult = callocobject() _op_partition(outer, couter) diff --git a/src/sage/libs/symmetrica/sab.pxi b/src/sage/libs/symmetrica/sab.pxi index b7900106b35..1d5506d7bd4 100644 --- a/src/sage/libs/symmetrica/sab.pxi +++ b/src/sage/libs/symmetrica/sab.pxi @@ -10,7 +10,7 @@ cdef extern from 'symmetrica/def.h': def dimension_symmetrization_symmetrica(n, part): """ - computes the dimension of the degree of a irreducible + Compute the dimension of the degree of a irreducible representation of the GL_n, n is a INTEGER object, labeled by the PARTITION object a. """ @@ -37,7 +37,7 @@ def dimension_symmetrization_symmetrica(n, part): def bdg_symmetrica(part, perm): """ - Calculates the irreducible matrix representation + Calculate the irreducible matrix representation D^part(perm), whose entries are of integral numbers. REFERENCE: H. Boerner: @@ -64,7 +64,7 @@ def bdg_symmetrica(part, perm): def sdg_symmetrica(part, perm): """ - Calculates the irreducible matrix representation + Calculate the irreducible matrix representation D^part(perm), which consists of rational numbers. REFERENCE: G. James/ A. Kerber: @@ -91,9 +91,10 @@ def sdg_symmetrica(part, perm): return res + def odg_symmetrica(part, perm): """ - Calculates the irreducible matrix representation + Calculate the irreducible matrix representation D^part(perm), which consists of real numbers. REFERENCE: G. James/ A. Kerber: @@ -122,12 +123,8 @@ def odg_symmetrica(part, perm): def ndg_symmetrica(part, perm): - """ - - """ cdef OP cpart, cperm, cD - cpart = callocobject() cperm = callocobject() cD = callocobject() @@ -144,13 +141,10 @@ def ndg_symmetrica(part, perm): return res -def specht_dg_symmetrica(part, perm): - """ - """ +def specht_dg_symmetrica(part, perm): cdef OP cpart, cperm, cD - cpart = callocobject() cperm = callocobject() cD = callocobject() diff --git a/src/sage/libs/symmetrica/sb.pxi b/src/sage/libs/symmetrica/sb.pxi index b884d33dafd..b3bbb061596 100644 --- a/src/sage/libs/symmetrica/sb.pxi +++ b/src/sage/libs/symmetrica/sb.pxi @@ -31,7 +31,7 @@ cdef object _check_schubert(object a, OP ca): def mult_schubert_schubert_symmetrica(a, b): """ - Multiplies the Schubert polynomials a and b. + Multiply the Schubert polynomials `a` and `b`. EXAMPLES:: @@ -51,7 +51,6 @@ def mult_schubert_schubert_symmetrica(a, b): freeall(cres) raise err - sig_on() mult_schubert_schubert(ca, cb, cres) sig_off() @@ -64,9 +63,10 @@ def mult_schubert_schubert_symmetrica(a, b): return res + def t_SCHUBERT_POLYNOM_symmetrica(a): """ - Converts a Schubert polynomial to a 'regular' multivariate + Convert a Schubert polynomial to a 'regular' multivariate polynomial. EXAMPLES:: @@ -96,9 +96,10 @@ def t_SCHUBERT_POLYNOM_symmetrica(a): return res + def t_POLYNOM_SCHUBERT_symmetrica(a): """ - Converts a multivariate polynomial a to a Schubert polynomial. + Convert a multivariate polynomial a to a Schubert polynomial. EXAMPLES:: @@ -135,9 +136,10 @@ def t_POLYNOM_SCHUBERT_symmetrica(a): return res + def mult_schubert_variable_symmetrica(a, i): """ - Returns the product of a and x_i. Note that indexing with i + Return the product of `a` and `x_i`. Note that indexing with `i` starts at 1. EXAMPLES:: @@ -176,9 +178,9 @@ def mult_schubert_variable_symmetrica(a, i): def divdiff_perm_schubert_symmetrica(perm, a): r""" - Returns the result of applying the divided difference operator + Return the result of applying the divided difference operator `\delta_i` to `a` where `a` is either a permutation or a - Schubert polynomial over QQ. + Schubert polynomial over `\QQ`. EXAMPLES:: @@ -270,11 +272,12 @@ def scalarproduct_schubert_symmetrica(a, b): return res + def divdiff_schubert_symmetrica(i, a): r""" - Returns the result of applying the divided difference operator + Return the result of applying the divided difference operator `\delta_i` to `a` where `a` is either a permutation or a - Schubert polynomial over QQ. + Schubert polynomial over `\QQ`. EXAMPLES:: diff --git a/src/sage/libs/symmetrica/sc.pxi b/src/sage/libs/symmetrica/sc.pxi index 4d9fa4f009d..77fe02802a1 100644 --- a/src/sage/libs/symmetrica/sc.pxi +++ b/src/sage/libs/symmetrica/sc.pxi @@ -7,7 +7,7 @@ cdef extern from 'symmetrica/def.h': def chartafel_symmetrica(n): """ - you enter the degree of the symmetric group, as INTEGER + You enter the degree of the symmetric group, as INTEGER object and the result is a MATRIX object: the charactertable of the symmetric group of the given degree. @@ -43,7 +43,7 @@ def chartafel_symmetrica(n): def charvalue_symmetrica(irred, cls, table=None): """ - you enter a PARTITION object part, labelling the irreducible + You enter a PARTITION object part, labelling the irreducible character, you enter a PARTITION object class, labeling the class or class may be a PERMUTATION object, then result becomes the value of that character on that class or permutation. Note that the @@ -98,7 +98,7 @@ def charvalue_symmetrica(irred, cls, table=None): def kranztafel_symmetrica(a, b): r""" - you enter the INTEGER objects, say `a` and `b`, and ``res`` becomes a + You enter the INTEGER objects, say `a` and `b`, and ``res`` becomes a MATRIX object, the charactertable of `S_b \wr S_a`, ``co`` becomes a VECTOR object of classorders and ``cl`` becomes a VECTOR object of the classlabels. diff --git a/src/sage/libs/symmetrica/schur.pxi b/src/sage/libs/symmetrica/schur.pxi index 82e77d0d251..4fe867ce93a 100644 --- a/src/sage/libs/symmetrica/schur.pxi +++ b/src/sage/libs/symmetrica/schur.pxi @@ -28,7 +28,6 @@ cdef extern from 'symmetrica/def.h': INT t_HOMSYM_MONOMIAL(OP a, OP b) INT t_HOMSYM_ELMSYM(OP a, OP b) - INT t_POWSYM_SCHUR(OP a, OP b) INT t_SCHUR_POWSYM(OP a, OP b) INT t_POWSYM_HOMSYM(OP a, OP b) @@ -55,7 +54,7 @@ cdef extern from 'symmetrica/def.h': def outerproduct_schur_symmetrica(parta, partb): """ - you enter two PARTITION objects, and the result is + You enter two PARTITION objects, and the result is a SCHUR object, which is the expansion of the product of the two schurfunctions, labeled by the two PARTITION objects parta and partb. @@ -92,7 +91,7 @@ def outerproduct_schur_symmetrica(parta, partb): def dimension_schur_symmetrica(s): """ - you enter a SCHUR object a, and the result is the + You enter a SCHUR object a, and the result is the dimension of the corresponding representation of the symmetric group sn. """ @@ -115,7 +114,7 @@ def dimension_schur_symmetrica(s): def newtrans_symmetrica(perm): """ - computes the decomposition of a schubertpolynomial labeled by + Compute the decomposition of a schubertpolynomial labeled by the permutation perm, as a sum of Schurfunction. FIXME! @@ -138,7 +137,7 @@ def newtrans_symmetrica(perm): def compute_schur_with_alphabet_symmetrica(part, length, alphabet='x'): """ - Computes the expansion of a schurfunction labeled by a + Compute the expansion of a schurfunction labeled by a partition PART as a POLYNOM erg. The INTEGER length specifies the length of the alphabet. @@ -182,7 +181,7 @@ def compute_schur_with_alphabet_symmetrica(part, length, alphabet='x'): def compute_homsym_with_alphabet_symmetrica(n, length, alphabet='x'): """ - computes the expansion of a homogeneous(=complete) symmetric + Compute the expansion of a homogeneous(=complete) symmetric function labeled by a INTEGER number as a POLYNOM erg. The object number may also be a PARTITION or a HOM_SYM object. The INTEGER laenge specifies the length of the alphabet. @@ -200,7 +199,6 @@ def compute_homsym_with_alphabet_symmetrica(n, length, alphabet='x'): a^3 + 2*a^2*b + 2*a*b^2 + b^3 sage: symmetrica.compute_homsym_with_alphabet([2,1],2,'x').parent() Multivariate Polynomial Ring in x0, x1 over Integer Ring - """ late_import() cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject() @@ -229,7 +227,7 @@ def compute_homsym_with_alphabet_symmetrica(n, length, alphabet='x'): def compute_elmsym_with_alphabet_symmetrica(n, length, alphabet='x'): """ - computes the expansion of a elementary symmetric + Compute the expansion of a elementary symmetric function labeled by a INTEGER number as a POLYNOM erg. The object number may also be a PARTITION or a ELM_SYM object. The INTEGER length specifies the length of the alphabet. @@ -247,7 +245,6 @@ def compute_elmsym_with_alphabet_symmetrica(n, length, alphabet='x'): 0 sage: symmetrica.compute_elmsym_with_alphabet([3,2,1],2) 0 - """ late_import() cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject() @@ -280,7 +277,7 @@ def compute_elmsym_with_alphabet_symmetrica(n, length, alphabet='x'): def compute_monomial_with_alphabet_symmetrica(n, length, alphabet='x'): """ - computes the expansion of a monomial symmetric + Compute the expansion of a monomial symmetric function labeled by a PARTITION number as a POLYNOM erg. The INTEGER laenge specifies the length of the alphabet. @@ -296,7 +293,6 @@ def compute_monomial_with_alphabet_symmetrica(n, length, alphabet='x'): a^2 + b^2 sage: symmetrica.compute_monomial_with_alphabet(2,2,'x').parent() Multivariate Polynomial Ring in x0, x1 over Integer Ring - """ late_import() cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject() @@ -326,7 +322,7 @@ def compute_monomial_with_alphabet_symmetrica(n, length, alphabet='x'): def compute_powsym_with_alphabet_symmetrica(n, length, alphabet='x'): """ - computes the expansion of a power symmetric + Compute the expansion of a power symmetric function labeled by a INTEGER label or by a PARTITION label or a POW_SYM label as a POLYNOM erg. The INTEGER laenge specifies the length of the alphabet. @@ -343,7 +339,6 @@ def compute_powsym_with_alphabet_symmetrica(n, length, alphabet='x'): a^2 + b^2 sage: symmetrica.compute_powsym_with_alphabet([2,1],2,'a,b') a^3 + a^2*b + a*b^2 + b^3 - """ late_import() cdef OP cn = callocobject(), clength = callocobject(), cresult = callocobject() @@ -408,6 +403,7 @@ def compute_schur_with_alphabet_det_symmetrica(part, length, alphabet='x'): return res + def part_part_skewschur_symmetrica(outer, inner): """ Return the skew Schur function s_{outer/inner}. @@ -434,9 +430,10 @@ def part_part_skewschur_symmetrica(outer, inner): return res + def hall_littlewood_symmetrica(part): """ - computes the so called Hall Littlewood Polynomials, i.e. + Compute the so called Hall Littlewood Polynomials, i.e. a SCHUR object, whose coefficient are polynomials in one variable. The method, which is used for the computation is described in the paper: A.O. Morris The Characters of the group GL(n,q) @@ -464,9 +461,6 @@ def hall_littlewood_symmetrica(part): def t_SCHUR_MONOMIAL_symmetrica(schur): - """ - """ - cdef OP cschur = callocobject(), cresult = callocobject() _op_schur(schur, cschur) @@ -484,9 +478,6 @@ def t_SCHUR_MONOMIAL_symmetrica(schur): def t_SCHUR_HOMSYM_symmetrica(schur): - """ - """ - cdef OP cschur = callocobject(), cresult = callocobject() _op_schur(schur, cschur) @@ -504,9 +495,6 @@ def t_SCHUR_HOMSYM_symmetrica(schur): def t_SCHUR_ELMSYM_symmetrica(schur): - """ - """ - cdef OP cschur = callocobject(), cresult = callocobject() _op_schur(schur, cschur) @@ -524,10 +512,6 @@ def t_SCHUR_ELMSYM_symmetrica(schur): def t_SCHUR_POWSYM_symmetrica(schur): - """ - - """ - cdef OP cschur = callocobject(), cresult = callocobject() _op_schur(schur, cschur) @@ -543,10 +527,11 @@ def t_SCHUR_POWSYM_symmetrica(schur): return res + def t_POLYNOM_SCHUR_symmetrica(p): - """ - Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function - in the Schur basis. + r""" + Convert a symmetric polynomial with base ring `\QQ` or `\ZZ` into a + symmetric function in the Schur basis. """ cdef OP polynom = callocobject(), cresult = callocobject() @@ -568,10 +553,6 @@ def t_POLYNOM_SCHUR_symmetrica(p): def t_MONOMIAL_HOMSYM_symmetrica(monomial): - """ - - """ - cdef OP cmonomial = callocobject(), cresult = callocobject() _op_monomial(monomial, cmonomial) @@ -587,11 +568,8 @@ def t_MONOMIAL_HOMSYM_symmetrica(monomial): return res -def t_MONOMIAL_ELMSYM_symmetrica(monomial): - """ - - """ +def t_MONOMIAL_ELMSYM_symmetrica(monomial): cdef OP cmonomial = callocobject(), cresult = callocobject() _op_monomial(monomial, cmonomial) @@ -609,10 +587,6 @@ def t_MONOMIAL_ELMSYM_symmetrica(monomial): def t_MONOMIAL_SCHUR_symmetrica(monomial): - """ - - """ - cdef OP cmonomial = callocobject(), cresult = callocobject() _op_monomial(monomial, cmonomial) @@ -630,10 +604,6 @@ def t_MONOMIAL_SCHUR_symmetrica(monomial): def t_MONOMIAL_POWSYM_symmetrica(monomial): - """ - - """ - cdef OP cmonomial = callocobject(), cresult = callocobject() _op_monomial(monomial, cmonomial) @@ -649,10 +619,11 @@ def t_MONOMIAL_POWSYM_symmetrica(monomial): return res + def t_POLYNOM_MONOMIAL_symmetrica(p): - """ - Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function - in the monomial basis. + r""" + Convert a symmetric polynomial with base ring `\QQ` or `\ZZ` into a + symmetric function in the monomial basis. """ cdef OP polynom = callocobject(), cresult = callocobject() @@ -674,10 +645,6 @@ def t_POLYNOM_MONOMIAL_symmetrica(p): def t_ELMSYM_SCHUR_symmetrica(elmsym): - """ - - """ - cdef OP celmsym = callocobject(), cresult = callocobject() _op_elmsym(elmsym, celmsym) @@ -695,10 +662,6 @@ def t_ELMSYM_SCHUR_symmetrica(elmsym): def t_ELMSYM_POWSYM_symmetrica(elmsym): - """ - - """ - cdef OP celmsym = callocobject(), cresult = callocobject() _op_elmsym(elmsym, celmsym) @@ -714,11 +677,8 @@ def t_ELMSYM_POWSYM_symmetrica(elmsym): return res -def t_ELMSYM_MONOMIAL_symmetrica(elmsym): - """ - - """ +def t_ELMSYM_MONOMIAL_symmetrica(elmsym): cdef OP celmsym = callocobject(), cresult = callocobject() _op_elmsym(elmsym, celmsym) @@ -736,10 +696,6 @@ def t_ELMSYM_MONOMIAL_symmetrica(elmsym): def t_ELMSYM_HOMSYM_symmetrica(elmsym): - """ - - """ - cdef OP celmsym = callocobject(), cresult = callocobject() _op_elmsym(elmsym, celmsym) @@ -755,10 +711,11 @@ def t_ELMSYM_HOMSYM_symmetrica(elmsym): return res + def t_POLYNOM_ELMSYM_symmetrica(p): - """ - Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function - in the elementary basis. + r""" + Convert a symmetric polynomial with base ring `\QQ` or `\ZZ` into a + symmetric function in the elementary basis. """ cdef OP polynom = callocobject(), cresult = callocobject() @@ -780,10 +737,6 @@ def t_POLYNOM_ELMSYM_symmetrica(p): def t_HOMSYM_SCHUR_symmetrica(homsym): - """ - - """ - cdef OP chomsym = callocobject(), cresult = callocobject() _op_homsym(homsym, chomsym) @@ -799,11 +752,8 @@ def t_HOMSYM_SCHUR_symmetrica(homsym): return res -def t_HOMSYM_POWSYM_symmetrica(homsym): - """ - - """ +def t_HOMSYM_POWSYM_symmetrica(homsym): cdef OP chomsym = callocobject(), cresult = callocobject() _op_homsym(homsym, chomsym) @@ -821,10 +771,6 @@ def t_HOMSYM_POWSYM_symmetrica(homsym): def t_HOMSYM_MONOMIAL_symmetrica(homsym): - """ - - """ - cdef OP chomsym = callocobject(), cresult = callocobject() _op_homsym(homsym, chomsym) @@ -840,11 +786,8 @@ def t_HOMSYM_MONOMIAL_symmetrica(homsym): return res -def t_HOMSYM_ELMSYM_symmetrica(homsym): - """ - - """ +def t_HOMSYM_ELMSYM_symmetrica(homsym): cdef OP chomsym = callocobject(), cresult = callocobject() _op_homsym(homsym, chomsym) @@ -862,10 +805,6 @@ def t_HOMSYM_ELMSYM_symmetrica(homsym): def t_POWSYM_MONOMIAL_symmetrica(powsym): - """ - - """ - cdef OP cpowsym = callocobject(), cresult = callocobject() _op_powsym(powsym, cpowsym) @@ -883,10 +822,6 @@ def t_POWSYM_MONOMIAL_symmetrica(powsym): def t_POWSYM_SCHUR_symmetrica(powsym): - """ - - """ - cdef OP cpowsym = callocobject(), cresult = callocobject() _op_powsym(powsym, cpowsym) @@ -902,11 +837,8 @@ def t_POWSYM_SCHUR_symmetrica(powsym): return res -def t_POWSYM_ELMSYM_symmetrica(powsym): - """ - - """ +def t_POWSYM_ELMSYM_symmetrica(powsym): cdef OP cpowsym = callocobject(), cresult = callocobject() _op_powsym(powsym, cpowsym) @@ -922,11 +854,8 @@ def t_POWSYM_ELMSYM_symmetrica(powsym): return res -def t_POWSYM_HOMSYM_symmetrica(powsym): - """ - - """ +def t_POWSYM_HOMSYM_symmetrica(powsym): cdef OP cpowsym = callocobject(), cresult = callocobject() _op_powsym(powsym, cpowsym) @@ -942,10 +871,11 @@ def t_POWSYM_HOMSYM_symmetrica(powsym): return res + def t_POLYNOM_POWER_symmetrica(p): - """ - Converts a symmetric polynomial with base ring QQ or ZZ into a symmetric function - in the power sum basis. + r""" + Convert a symmetric polynomial with base ring `\QQ` or `\ZZ` into a + symmetric function in the power sum basis. """ cdef OP polynom = callocobject(), cresult = callocobject() @@ -967,8 +897,6 @@ def t_POLYNOM_POWER_symmetrica(p): def mult_schur_schur_symmetrica(s1, s2): - """ - """ cdef OP cs1 = callocobject(), cs2 = callocobject(), cresult = callocobject() _op_schur(s1, cs1) @@ -988,8 +916,6 @@ def mult_schur_schur_symmetrica(s1, s2): def mult_monomial_monomial_symmetrica(m1, m2): - """ - """ cdef OP cm1 = callocobject(), cm2 = callocobject(), cresult = callocobject() _op_monomial(m1, cm1) diff --git a/src/sage/libs/symmetrica/symmetrica.pxi b/src/sage/libs/symmetrica/symmetrica.pxi index 1dbe23a6675..def9544e2c6 100644 --- a/src/sage/libs/symmetrica/symmetrica.pxi +++ b/src/sage/libs/symmetrica/symmetrica.pxi @@ -522,9 +522,10 @@ cdef int _op(object a, OP result) except -1: else: raise TypeError("cannot convert a (= %s) to OP" % a) + def test_integer(object x): """ - Tests functionality for converting between Sage's integers + Test functionality for converting between Sage's integers and symmetrica's integers. EXAMPLES:: @@ -792,13 +793,12 @@ cdef object _py_polynom(OP a): cdef object _py_polynom_alphabet(OP a, object alphabet, object length): """ - Converts a symmetrica multivariate polynomial a to a Sage multivariate + Convert a symmetrica multivariate polynomial a to a Sage multivariate polynomials. Alphabet specifies the names of the variables which are fed into PolynomialRing. length specifies the number of variables; if it is set to 0, then the number of variables is autodetected based on the number of variables in alphabet or the result obtained from symmetrica. - """ late_import() cdef OP pointer = a @@ -941,7 +941,7 @@ cdef void* _op_elmsym(object d, OP res) noexcept: #Elementary symmetric function pointer = s_s_n(pointer) -cdef object _py_homsym(OP a): #Homogenous symmetric functions +cdef object _py_homsym(OP a): # Homogeneous symmetric functions late_import() z_elt = _py_schur_general(a) if len(z_elt) == 0: @@ -954,7 +954,7 @@ cdef object _py_homsym(OP a): #Homogenous symmetric functions z._monomial_coefficients = z_elt return z -cdef void* _op_homsym(object d, OP res) noexcept: #Homogenous symmetric functions +cdef void* _op_homsym(object d, OP res) noexcept: # Homogeneous symmetric functions cdef OP pointer = res _op_schur_general(d, res) while pointer != NULL: diff --git a/src/sage/logic/booleval.py b/src/sage/logic/booleval.py index 84da89f0c3f..3775d6e5e3a 100644 --- a/src/sage/logic/booleval.py +++ b/src/sage/logic/booleval.py @@ -45,14 +45,12 @@ def eval_formula(tree, vdict): INPUT: - - ``tree`` -- a list of three elements corresponding to a branch of a + - ``tree`` -- list of three elements corresponding to a branch of a parse tree - - ``vdict`` -- a dictionary containing variable keys and boolean values + - ``vdict`` -- dictionary containing variable keys and boolean values - OUTPUT: - - The result of the evaluation as a boolean value. + OUTPUT: the result of the evaluation as a boolean value EXAMPLES: @@ -81,12 +79,10 @@ def eval_f(tree): INPUT: - - ``tree`` -- a list of three elements corresponding to a branch of a + - ``tree`` -- list of three elements corresponding to a branch of a parse tree - OUTPUT: - - The result of the evaluation as a boolean value. + OUTPUT: the result of the evaluation as a boolean value EXAMPLES: @@ -111,15 +107,13 @@ def eval_op(op, lv, rv): INPUT: - - ``op`` -- a string or character representing a boolean operator - - - ``lv`` -- a boolean or variable + - ``op`` -- string or character representing a boolean operator - - ``rv`` -- a boolean or variable + - ``lv`` -- boolean or variable - OUTPUT: + - ``rv`` -- boolean or variable - The evaluation of ``lv op rv`` as a boolean value. + OUTPUT: the evaluation of ``lv op rv`` as a boolean value EXAMPLES: diff --git a/src/sage/logic/boolformula.py b/src/sage/logic/boolformula.py index 304664e79ba..d22c0443461 100644 --- a/src/sage/logic/boolformula.py +++ b/src/sage/logic/boolformula.py @@ -155,12 +155,12 @@ class BooleanFormula: - ``self`` -- calling object - - ``exp`` -- a string; this contains the boolean expression + - ``exp`` -- string; this contains the boolean expression to be manipulated - - ``tree`` -- a list; this contains the parse tree of the expression. + - ``tree`` -- list; this contains the parse tree of the expression - - ``vo`` -- a list; this contains the variables in the expression, in the + - ``vo`` -- list; this contains the variables in the expression, in the order that they appear; each variable only occurs once in the list """ __expression = "" @@ -188,10 +188,6 @@ def __repr__(self): r""" Return a string representation of this statement. - OUTPUT: - - A string representation of calling statement - EXAMPLES:: sage: import sage.logic.propcalc as propcalc @@ -204,9 +200,7 @@ def _latex_(self): r""" Return a LaTeX representation of this statement. - OUTPUT: - - A string containing the latex code for the statement + OUTPUT: string containing the latex code for the statement EXAMPLES:: @@ -228,9 +222,7 @@ def polish_notation(self): r""" Convert the calling boolean formula into polish notation. - OUTPUT: - - A string representation of the formula in polish notation. + OUTPUT: string representation of the formula in polish notation EXAMPLES: @@ -255,9 +247,7 @@ def tree(self): r""" Return the parse tree of this boolean expression. - OUTPUT: - - The parse tree as a nested list + OUTPUT: the parse tree as a nested list EXAMPLES: @@ -288,9 +278,7 @@ def full_tree(self): r""" Return a full syntax parse tree of the calling formula. - OUTPUT: - - The full syntax parse tree as a nested list + OUTPUT: the full syntax parse tree as a nested list EXAMPLES: @@ -327,7 +315,7 @@ def __or__(self, other): INPUT: - - ``other`` -- a boolean formula; this is the statement + - ``other`` -- boolean formula; this is the statement on the right side of the operator OUTPUT: @@ -352,12 +340,10 @@ def __and__(self, other): INPUT: - - ``other`` -- a boolean formula; this is the formula on + - ``other`` -- boolean formula; this is the formula on the right side of the operator - OUTPUT: - - A boolean formula of the form ``self & other``. + OUTPUT: a boolean formula of the form ``self & other`` EXAMPLES: @@ -377,12 +363,10 @@ def __xor__(self, other): INPUT: - - ``other`` -- a boolean formula; this is the formula on + - ``other`` -- boolean formula; this is the formula on the right side of the operator - OUTPUT: - - A boolean formula of the form ``self ^ other``. + OUTPUT: a boolean formula of the form ``self ^ other`` EXAMPLES: @@ -402,12 +386,10 @@ def __pow__(self, other): INPUT: - - ``other`` -- a boolean formula; this is the formula on + - ``other`` -- boolean formula; this is the formula on the right side of the operator - OUTPUT: - - A boolean formula of the form ``self ^ other``. + OUTPUT: a boolean formula of the form ``self ^ other`` EXAMPLES: @@ -432,9 +414,7 @@ def __invert__(self): r""" Overload the ``~`` operator to 'not' a statement. - OUTPUT: - - A boolean formula of the form ``~self``. + OUTPUT: a boolean formula of the form ``~self`` EXAMPLES: @@ -455,7 +435,7 @@ def ifthen(self, other): INPUT: - - ``other`` -- a boolean formula; this is the formula + - ``other`` -- boolean formula; this is the formula on the right side of the operator OUTPUT: @@ -480,7 +460,7 @@ def iff(self, other): INPUT: - - ``other`` -- a boolean formula; this is the formula + - ``other`` -- boolean formula; this is the formula on the right side of the operator OUTPUT: @@ -505,12 +485,10 @@ def __eq__(self, other): INPUT: - - ``other`` -- a boolean formula; this is the formula + - ``other`` -- boolean formula; this is the formula on the right side of the comparator - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if ``self`` and ``other`` are logically equivalent @@ -546,9 +524,7 @@ def truthtable(self, start=0, end=-1): - ``end`` -- (default: -1) an integer; this is the last row of the truth table to be created - OUTPUT: - - The truth table as a 2-D array + OUTPUT: the truth table as a 2-D array EXAMPLES: @@ -589,15 +565,12 @@ def truthtable(self, start=0, end=-1): exponential time function requiring `O(2^n)` time, where `n` is the number of variables in the expression. """ - max = 2 ** len(self.__vars_order) + maximum = 2 ** len(self.__vars_order) if end < 0: - end = max - if end > max: - end = max - if start < 0: - start = 0 - if start > max: - start = max + end = maximum + end = min(end, maximum) + start = max(start, 0) + start = min(start, maximum) keys, table = [], [] vars = {} for var in self.__vars_order: @@ -624,12 +597,10 @@ def evaluate(self, var_values): INPUT: - - ``var_values`` -- a dictionary; this contains the - pairs of variables and their boolean values. - - OUTPUT: + - ``var_values`` -- dictionary; this contains the + pairs of variables and their boolean values - The result of the evaluation as a boolean. + OUTPUT: the result of the evaluation as a boolean EXAMPLES: @@ -648,9 +619,7 @@ def is_satisfiable(self): r""" Determine if the formula is ``True`` for some assignment of values. - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if there is an assignment of values that makes the formula ``True``. @@ -678,9 +647,7 @@ def is_tautology(self): r""" Determine if the formula is always ``True``. - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if the formula is a tautology. @@ -709,9 +676,7 @@ def is_contradiction(self): r""" Determine if the formula is always ``False``. - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if the formula is a contradiction. @@ -748,9 +713,7 @@ def is_consequence(self, *hypotheses): - ``*hypotheses`` -- instances of :class:`BooleanFormula` - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` -- if ``self`` (the desired conclusion) is a logical consequence of the set of hypotheses @@ -832,9 +795,7 @@ def implies(self, other): - ``other`` -- instance of :class:`BooleanFormula` - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` -- if ``self`` implies ``other`` @@ -876,15 +837,13 @@ def equivalent(self, other): - ``self`` -- calling object - - ``other`` -- instance of BooleanFormula class. - - OUTPUT: + - ``other`` -- instance of BooleanFormula class - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - True - if the two formulas are logically equivalent + ``True`` -- if the two formulas are logically equivalent - False - if the two formulas are not logically equivalent + ``False`` -- if the two formulas are not logically equivalent EXAMPLES: @@ -906,9 +865,7 @@ def convert_cnf_table(self): r""" Convert boolean formula to conjunctive normal form. - OUTPUT: - - An instance of :class:`BooleanFormula` in conjunctive normal form. + OUTPUT: an instance of :class:`BooleanFormula` in conjunctive normal form EXAMPLES: @@ -960,9 +917,7 @@ def convert_cnf_recur(self): r""" Convert boolean formula to conjunctive normal form. - OUTPUT: - - An instance of :class:`BooleanFormula` in conjunctive normal form. + OUTPUT: an instance of :class:`BooleanFormula` in conjunctive normal form EXAMPLES: @@ -995,9 +950,7 @@ def satformat(self): r""" Return the satformat representation of a boolean formula. - OUTPUT: - - The satformat of the formula as a string. + OUTPUT: the satformat of the formula as a string EXAMPLES: @@ -1062,11 +1015,7 @@ def satformat(self): # This function uses the propcalc package to simplify an expression to # its minimal form. # -# INPUT: -# self -- the calling object. -# -# OUTPUT: -# A simplified expression. +# OUTPUT: a simplified expression # # EXAMPLES:: @@ -1132,13 +1081,11 @@ def convert_opt(self, tree): INPUT: - - ``tree`` -- a list; this is a branch of a + - ``tree`` -- list; this is a branch of a parse tree and can only contain the '&', '|' and '~' operators along with variables - OUTPUT: - - A 3-tuple. + OUTPUT: a 3-tuple EXAMPLES: @@ -1184,12 +1131,10 @@ def add_statement(self, other, op): - ``other`` -- instance of :class:`BooleanFormula`; this is the formula on the right of the operator - - ``op`` -- a string; this is the operator used to + - ``op`` -- string; this is the operator used to combine the two formulas - OUTPUT: - - The result as an instance of :class:`BooleanFormula`. + OUTPUT: the result as an instance of :class:`BooleanFormula` EXAMPLES: @@ -1214,15 +1159,13 @@ def get_bit(self, x, c): INPUT: - - ``x`` -- an integer; this is the number from + - ``x`` -- integer; this is the number from which to take the bit - - ``c`` -- an integer; this is the but number to + - ``c`` -- integer; this is the but number to be taken, where 0 is the low order bit - OUTPUT: - - A boolean to be determined as follows: + OUTPUT: a boolean to be determined as follows: - ``True`` if bit ``c`` of ``x`` is 1. @@ -1277,7 +1220,7 @@ def reduce_op(self, tree): INPUT: - - ``tree`` -- a list; this represents a branch + - ``tree`` -- list; this represents a branch of a parse tree OUTPUT: @@ -1326,9 +1269,7 @@ def dist_not(self, tree): - ``tree`` a list; this represents a branch of a parse tree - OUTPUT: - - A new list. + OUTPUT: a new list EXAMPLES: @@ -1365,12 +1306,10 @@ def dist_ors(self, tree): INPUT: - - ``tree`` -- a list; this represents a branch of + - ``tree`` -- list; this represents a branch of a parse tree - OUTPUT: - - A new list. + OUTPUT: a new list EXAMPLES: @@ -1405,12 +1344,10 @@ def to_infix(self, tree): INPUT: - - ``tree`` -- a list; this represents a branch + - ``tree`` -- list; this represents a branch of a parse tree - OUTPUT: - - A new list. + OUTPUT: a new list EXAMPLES: @@ -1475,12 +1412,10 @@ def get_next_op(self, str): INPUT: - - ``str`` -- a string; this contains a logical + - ``str`` -- string; this contains a logical expression - OUTPUT: - - The next operator as a string. + OUTPUT: the next operator as a string EXAMPLES: diff --git a/src/sage/logic/logic.py b/src/sage/logic/logic.py index 058da0ff633..26d8daab4e7 100644 --- a/src/sage/logic/logic.py +++ b/src/sage/logic/logic.py @@ -61,21 +61,19 @@ class SymbolicLogic: """ def statement(self, s): r""" - Return a token list to be used by other functions in the class + Return a token list to be used by other functions in the class. INPUT: - - ``s`` -- a string containing the logic expression to be manipulated + - ``s`` -- string containing the logic expression to be manipulated - - ``global vars`` -- a dictionary with variable names as keys and the + - ``global vars`` -- dictionary with variable names as keys and the variables' current boolean values as dictionary values - - ``global vars_order`` -- a list of the variables in the order + - ``global vars_order`` -- list of the variables in the order that they are found - OUTPUT: - - A list of length three containing the following in this order: + OUTPUT: list of length three containing the following in this order: 1. a list of tokens 2. a dictionary of variable/value pairs @@ -119,13 +117,13 @@ def truthtable(self, statement, start=0, end=-1): INPUT: - - ``statement`` -- a list; it contains the tokens and the two global + - ``statement`` -- list; it contains the tokens and the two global variables vars and vars_order - - ``start`` -- (default: 0) an integer; this represents the row of + - ``start`` -- integer (default: 0); this represents the row of the truth table from which to start - - ``end`` -- (default: -1) an integer; this represents the last row + - ``end`` -- integer (default: -1); this represents the last row of the truth table to be created OUTPUT: @@ -206,9 +204,7 @@ def print_table(self, table): - ``table`` -- object created by :meth:`truthtable()` method; it contains the variable values and the evaluation of the statement - OUTPUT: - - A formatted version of the truth table. + OUTPUT: a formatted version of the truth table EXAMPLES: @@ -292,9 +288,7 @@ def combine(self, statement1, statement2): - ``statement1`` -- the first statement - ``statement2`` -- the second statement - OUTPUT: - - A new statement which or'd the given statements together. + OUTPUT: a new statement which or'd the given statements together EXAMPLES:: @@ -375,13 +369,11 @@ def get_bit(x, c): INPUT: - - ``x`` -- an integer; this is the number from which to take the bit - - - ``c`` -- an integer; this is the bit number to be taken + - ``x`` -- integer; this is the number from which to take the bit - OUTPUT: + - ``c`` -- integer; this is the bit number to be taken - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if bit ``c`` of ``x`` is 1. @@ -416,11 +408,9 @@ def eval(toks): INPUT: - - ``toks`` -- a list of tokens; this represents a boolean expression - - OUTPUT: + - ``toks`` -- list of tokens; this represents a boolean expression - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if expression evaluates to ``True``. @@ -459,12 +449,10 @@ def eval_ltor_toks(lrtoks): INPUT: - - ``lrtoks`` -- a list of tokens; this represents a part of a boolean + - ``lrtoks`` -- list of tokens; this represents a part of a boolean formula that contains no inner parentheses - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if expression evaluates to ``True``. @@ -498,7 +486,7 @@ def reduce_bins(lrtoks): INPUT: - - ``lrtoks`` -- a list of tokens; this represents a part of a boolean + - ``lrtoks`` -- list of tokens; this represents a part of a boolean formula that contains no inner parentheses or monotonic operators OUTPUT: @@ -536,7 +524,7 @@ def reduce_monos(lrtoks): INPUT: - - ``lrtoks`` -- a list of tokens; this represents a part of a boolean + - ``lrtoks`` -- list of tokens; this represents a part of a boolean expression that contains now inner parentheses OUTPUT: @@ -573,12 +561,10 @@ def eval_mon_op(args): INPUT: - - ``args`` -- a list of length 2; this contains the token 'NOT' and + - ``args`` -- list of length 2; this contains the token 'NOT' and then a variable name - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` if the variable in ``args`` is ``False``. @@ -611,7 +597,7 @@ def eval_bin_op(args): INPUT: - - ``args`` -- a list of length 3; this contains a variable name, + - ``args`` -- list of length 3; this contains a variable name, then a binary operator, and then a variable name, in that order OUTPUT: @@ -663,15 +649,13 @@ def eval_and_op(lval, rval): INPUT: - - ``lval`` -- a string; this represents the value of the variable + - ``lval`` -- string; this represents the value of the variable appearing to the left of the 'and' operator - - ``rval`` -- a string; this represents the value of the variable + - ``rval`` -- string; this represents the value of the variable appearing to the right of the 'and' operator - OUTPUT: - - The result of applying 'and' to ``lval`` and ``rval`` as a string. + OUTPUT: the result of applying 'and' to ``lval`` and ``rval`` as a string .. NOTE:: @@ -697,15 +681,13 @@ def eval_or_op(lval, rval): INPUT: - - ``lval`` -- a string; this represents the value of the variable + - ``lval`` -- string; this represents the value of the variable appearing to the left of the 'or' operator - - ``rval`` -- a string; this represents the value of the variable + - ``rval`` -- string; this represents the value of the variable appearing to the right of the 'or' operator - OUTPUT: - - A string representing the result of applying 'or' to ``lval`` and ``rval``. + OUTPUT: string representing the result of applying 'or' to ``lval`` and ``rval`` .. NOTE:: @@ -731,10 +713,10 @@ def eval_ifthen_op(lval, rval): INPUT: - - ``lval`` -- a string; this represents the value of the variable + - ``lval`` -- string; this represents the value of the variable appearing to the left of the 'if then' operator - - ``rval`` -- a string;t his represents the value of the variable + - ``rval`` -- string; this represents the value of the variable appearing to the right of the 'if then' operator OUTPUT: @@ -766,10 +748,10 @@ def eval_iff_op(lval, rval): INPUT: - - ``lval`` -- a string; this represents the value of the variable + - ``lval`` -- string; this represents the value of the variable appearing to the left of the 'if and only if' operator - - ``rval`` -- a string; this represents the value of the variable + - ``rval`` -- string; this represents the value of the variable appearing to the right of the 'if and only if' operator OUTPUT: @@ -801,13 +783,11 @@ def tokenize(s, toks): INPUT: - - ``s`` -- a string; this contains a boolean expression + - ``s`` -- string; this contains a boolean expression - - ``toks`` -- a list; this will be populated with the tokens of ``s`` - - OUTPUT: + - ``toks`` -- list; this will be populated with the tokens of ``s`` - ``None``; the tokens of ``s`` are placed in ``toks``. + OUTPUT: none; the tokens of ``s`` are placed in ``toks`` .. NOTE:: diff --git a/src/sage/logic/logicparser.py b/src/sage/logic/logicparser.py index e3d74f512e1..c5431091a68 100644 --- a/src/sage/logic/logicparser.py +++ b/src/sage/logic/logicparser.py @@ -98,7 +98,7 @@ def parse(s): INPUT: - - ``s`` -- a string containing a boolean formula + - ``s`` -- string containing a boolean formula OUTPUT: @@ -133,11 +133,9 @@ def polish_parse(s): INPUT: - - ``s`` -- a string containing a boolean expression + - ``s`` -- string containing a boolean expression - OUTPUT: - - The full syntax parse tree as a nested list. + OUTPUT: the full syntax parse tree as a nested list EXAMPLES: @@ -173,9 +171,7 @@ def get_trees(*statements): - ``*statements`` -- strings or :class:`BooleanFormula` instances - OUTPUT: - - The parse trees in a list. + OUTPUT: the parse trees in a list EXAMPLES: @@ -229,12 +225,10 @@ def recover_formula(prefix_tree): INPUT: - - ``prefix_tree`` -- a list; this is a full syntax parse + - ``prefix_tree`` -- list; this is a full syntax parse tree in prefix form - OUTPUT: - - The formula as a string. + OUTPUT: the formula as a string EXAMPLES: @@ -284,12 +278,10 @@ def recover_formula_internal(prefix_tree): INPUT: - - ``prefix_tree`` -- a list; this is a simple tree + - ``prefix_tree`` -- list; this is a simple tree with at most one operator in prefix form - OUTPUT: - - The formula as a string. + OUTPUT: the formula as a string EXAMPLES: @@ -350,12 +342,10 @@ def prefix_to_infix(prefix_tree): INPUT: - - ``prefix_tree`` -- a list; this is a full syntax parse + - ``prefix_tree`` -- list; this is a full syntax parse tree in prefix form - OUTPUT: - - A list containing the tree in infix form. + OUTPUT: list containing the tree in infix form EXAMPLES: @@ -394,12 +384,10 @@ def to_infix_internal(prefix_tree): INPUT: - - ``prefix_tree`` -- a list; this is a simple parse tree + - ``prefix_tree`` -- list; this is a simple parse tree in prefix form with at most one operator - OUTPUT: - - The tree in infix form as a list. + OUTPUT: the tree in infix form as a list EXAMPLES: @@ -445,7 +433,7 @@ def tokenize(s): INPUT: - - ``s`` -- a string representation of a boolean formula + - ``s`` -- string representation of a boolean formula OUTPUT: @@ -527,9 +515,9 @@ def tree_parse(toks, polish=False): INPUT: - - ``toks`` -- a list of tokens from a boolean formula + - ``toks`` -- list of tokens from a boolean formula - - ``polish`` -- (default: ``False``) a boolean; when ``True``, + - ``polish`` -- boolean (default: ``False``); when ``True``, :func:`~sage.logic.logicparser.tree_parse()` will return the full syntax parse tree @@ -584,18 +572,16 @@ def parse_ltor(toks, n=0, polish=False): INPUT: - - ``toks`` -- a list of tokens. Each token is atomic. + - ``toks`` -- list of tokens; each token is atomic - - ``n`` -- (default: 0) an integer representing which order of + - ``n`` -- integer (default: 0) representing which order of operations are occurring - - ``polish`` -- (default: ``False``) a boolean; when ``True``, double + - ``polish`` -- boolean (default: ``False``); when ``True``, double negations are not cancelled and negated statements are turned into - list of length two. + list of length two - OUTPUT: - - The parse tree as a nested list that depends on ``polish`` as follows: + OUTPUT: the parse tree as a nested list that depends on ``polish`` as follows: - If ``False``, then return a simplified parse tree. @@ -675,9 +661,7 @@ def apply_func(tree, func): - ``func`` -- a function to be applied to each node of tree; this may be a function that comes from elsewhere in the logic module - OUTPUT: - - The new parse tree in the form of a nested list. + OUTPUT: the new parse tree in the form of a nested list EXAMPLES: diff --git a/src/sage/logic/logictable.py b/src/sage/logic/logictable.py index 90107513a0b..d317c31d5c9 100644 --- a/src/sage/logic/logictable.py +++ b/src/sage/logic/logictable.py @@ -130,7 +130,7 @@ class Truthtable: - ``t`` -- a 2-D array containing the table values - - ``vo`` -- a list of the variables in the expression in order, + - ``vo`` -- list of the variables in the expression in order, with each variable occurring only once """ def __init__(self, t, vo): @@ -163,9 +163,7 @@ def _latex_(self): r""" Return a latex representation of the calling table object. - OUTPUT: - - The latex representation of the table. + OUTPUT: the latex representation of the table EXAMPLES: @@ -203,9 +201,7 @@ def __repr__(self): r""" Return a string representation of the calling table object. - OUTPUT: - - The table as a 2-D string array. + OUTPUT: the table as a 2-D string array EXAMPLES: @@ -260,9 +256,7 @@ def get_table_list(self): r""" Return a list representation of the calling table object. - OUTPUT: - - A list representation of the table. + OUTPUT: list representation of the table EXAMPLES: @@ -272,7 +266,6 @@ def get_table_list(self): sage: s = propcalc.formula("man->monkey&human") sage: s.truthtable().get_table_list() [['man', 'monkey', 'human'], [False, False, False, True], [False, False, True, True], [False, True, False, True], [False, True, True, True], [True, False, False, False], [True, False, True, False], [True, True, False, False], [True, True, True, True]] - """ t = self.__table[:] t.insert(0, self.__vars_order) diff --git a/src/sage/logic/propcalc.py b/src/sage/logic/propcalc.py index 830185d6156..2ef5a88b3c2 100644 --- a/src/sage/logic/propcalc.py +++ b/src/sage/logic/propcalc.py @@ -154,11 +154,9 @@ def formula(s): INPUT: - - ``s`` -- a string that contains a logical expression + - ``s`` -- string that contains a logical expression - OUTPUT: - - An instance of :class:`BooleanFormula`. + OUTPUT: an instance of :class:`BooleanFormula` EXAMPLES: @@ -201,9 +199,7 @@ def get_formulas(*statements): full syntax parse tree of a formula, and a string must be a string representation of a formula - OUTPUT: - - The converted formulas in a list. + OUTPUT: the converted formulas in a list EXAMPLES: @@ -271,9 +267,7 @@ def consistent(*formulas): - ``*formulas`` -- instances of :class:`BooleanFormula` - OUTPUT: - - A boolean value to be determined as follows: + OUTPUT: a boolean value to be determined as follows: - ``True`` -- if the formulas are logically consistent diff --git a/src/sage/manifolds/calculus_method.py b/src/sage/manifolds/calculus_method.py index 859301365bf..a4888559c0f 100644 --- a/src/sage/manifolds/calculus_method.py +++ b/src/sage/manifolds/calculus_method.py @@ -46,9 +46,7 @@ def _SR_to_Sympy(expression): - ``expression`` -- ``SR`` or ``sympy`` symbolic expression - OUTPUT: - - - ``expression`` -- ``sympy`` symbolic expression + OUTPUT: ``expression`` -- ``sympy`` symbolic expression EXAMPLES:: @@ -66,7 +64,6 @@ def _SR_to_Sympy(expression): sage: _SR_to_Sympy(b) is b True - """ # Nothing to do if expression is already a SymPy object: if isinstance(expression, sympy.Basic): @@ -84,9 +81,7 @@ def _Sympy_to_SR(expression): - ``expression`` -- ``sympy`` symbolic expression - OUTPUT: - - - ``expression`` -- ``SR`` or ``sympy`` symbolic expression + OUTPUT: ``expression`` -- ``SR`` or ``sympy`` symbolic expression EXAMPLES:: @@ -102,7 +97,6 @@ def _Sympy_to_SR(expression): x^2 + sin(x)^2 == x^2 + sin(x)^2 sage: bool(_) True - """ try: return SR(expression) @@ -175,15 +169,14 @@ class CalculusMethod(SageObject): See :meth:`simplify_function` for the default simplification algorithms associated with each calculus method and :meth:`set_simplify_function` for introducing a new simplification algorithm. - """ _default = 'SR' # default calculus method _methods = ('SR', 'sympy') # implemented methods - _tranf = {'SR': _Sympy_to_SR, 'sympy': _SR_to_Sympy} # translators + _tranf = {'SR': _Sympy_to_SR, 'sympy': _SR_to_Sympy} # translators def __init__(self, current=None, base_field_type='real'): r""" - Initializes ``self``. + Initialize ``self``. TESTS:: @@ -193,7 +186,6 @@ def __init__(self, current=None, base_field_type='real'): Available calculus methods (* = current): - SR (default) (*) - sympy - """ self._current = self._default if current is None else current # Initialization of the dictionary of simplifying functions: @@ -222,11 +214,9 @@ def simplify(self, expression, method=None): - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - ``'sympy'``: SymPy - - ``None``: the current calculus method of ``self`` is used. - - OUTPUT: + - ``None``: the current calculus method of ``self`` is used - - the simplified version of ``expression`` + OUTPUT: the simplified version of ``expression`` EXAMPLES:: @@ -273,7 +263,6 @@ def simplify(self, expression, method=None): sage: cm.simplify(f, method='SR') x^2 + 1 - """ if method is None: method = self._current @@ -289,11 +278,9 @@ def is_trivial_zero(self, expression, method=None): - ``expression`` -- expression - ``method`` -- (default: ``None``) string defining the calculus method - to use; if ``None`` the current calculus method of ``self`` is used. - - OUTPUT: + to use; if ``None`` the current calculus method of ``self`` is used - - ``True`` is expression is trivially zero, ``False`` elsewhere. + OUTPUT: ``True`` is expression is trivially zero, ``False`` elsewhere EXAMPLES:: @@ -312,7 +299,6 @@ def is_trivial_zero(self, expression, method=None): False sage: cm.is_trivial_zero(f._sympy_(), method='sympy') False - """ if method is None: method = self._current @@ -347,7 +333,6 @@ def set(self, method): Traceback (most recent call last): ... NotImplementedError: method lala not implemented - """ if method not in self._methods: raise NotImplementedError("method {} not ".format(method) + @@ -360,10 +345,10 @@ def current(self): OUTPUT: - - string defining the calculus method, one of + String defining the calculus method; one of - - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - - ``'sympy'``: SymPy + - ``'SR'`` -- Sage's default symbolic engine (Symbolic Ring) + - ``'sympy'`` -- SymPy EXAMPLES:: @@ -377,7 +362,6 @@ def current(self): sage: cm.set('sympy') sage: cm.current() 'sympy' - """ return self._current @@ -441,7 +425,6 @@ def set_simplify_function(self, simplifying_func, method=None): sage: cm.simplify_function() is \ ....: sage.manifolds.utilities.simplify_chain_real True - """ if method is None: method = self._current @@ -468,9 +451,7 @@ def simplify_function(self, method=None): - ``None``: the currently active calculus method of ``self`` is assumed - OUTPUT: - - - the simplifying function + OUTPUT: the simplifying function EXAMPLES:: @@ -519,7 +500,6 @@ def simplify_function(self, method=None): Note that the simplifying functions can be customized via :meth:`set_simplify_function`. - """ if method is None: method = self._current @@ -547,7 +527,6 @@ def reset(self): Available calculus methods (* = current): - SR (default) (*) - sympy - """ self._current = self._default @@ -561,7 +540,6 @@ def _repr_(self): sage: cm = CalculusMethod(base_field_type='complex') sage: cm._repr_() 'Available calculus methods (* = current):\n - SR (default) (*)\n - sympy' - """ resu = 'Available calculus methods (* = current):\n' for method in self._methods: diff --git a/src/sage/manifolds/catalog.py b/src/sage/manifolds/catalog.py index 91b0997de7b..c3c40c42b9a 100644 --- a/src/sage/manifolds/catalog.py +++ b/src/sage/manifolds/catalog.py @@ -54,7 +54,7 @@ def Minkowski(positive_spacelike=True, names=None): INPUT: - - ``positive_spacelike`` -- (default: ``True``) if ``False``, then + - ``positive_spacelike`` -- boolean (default: ``True``); if ``False``, then the spacelike vectors yield a negative sign (i.e., the signature is `(+ - - - )`) - ``names`` -- (default: ``None``) name of the coordinates, @@ -93,7 +93,8 @@ def Minkowski(positive_spacelike=True, names=None): g[1,1], g[2,2], g[3,3] = sgn, sgn, sgn return M -def Kerr(m=1, a=0, coordinates="BL", names=None): + +def Kerr(m=1, a=0, coordinates='BL', names=None): """ Generate a Kerr spacetime. @@ -109,15 +110,13 @@ def Kerr(m=1, a=0, coordinates="BL", names=None): (`c=1`, `G=1`) - ``a`` -- (default: ``0``) angular momentum in natural units; if set to ``0``, the resulting spacetime corresponds to a Schwarzschild black hole - - ``coordinates`` -- (default: ``"BL"``) either ``"BL"`` for - Boyer-Lindquist coordinates or ``"Kerr"`` for Kerr coordinates (3+1 + - ``coordinates`` -- (default: ``'BL'``) either ``'BL'`` for + Boyer-Lindquist coordinates or ``'Kerr'`` for Kerr coordinates (3+1 version) - ``names`` -- (default: ``None``) name of the coordinates, automatically set by the shortcut operator - OUTPUT: - - - Lorentzian manifold + OUTPUT: Lorentzian manifold EXAMPLES:: @@ -153,7 +152,7 @@ def Kerr(m=1, a=0, coordinates="BL", names=None): The Kerr spacetime in Kerr coordinates:: sage: m, a = var('m, a') - sage: K. = manifolds.Kerr(m, a, coordinates="Kerr") + sage: K. = manifolds.Kerr(m, a, coordinates='Kerr') sage: K 4-dimensional Lorentzian manifold M sage: K.atlas() @@ -176,7 +175,7 @@ def Kerr(m=1, a=0, coordinates="BL", names=None): from sage.misc.functional import sqrt from sage.functions.trig import cos, sin from sage.manifolds.manifold import Manifold - M = Manifold(4, 'M', structure="Lorentzian") + M = Manifold(4, 'M', structure='Lorentzian') if coordinates == "Kerr": if names is None: names = (r't:(-oo,+oo)', r'r:(0,+oo)', r'th:(0,pi):\theta', @@ -219,6 +218,7 @@ def Kerr(m=1, a=0, coordinates="BL", names=None): raise NotImplementedError("coordinates system not implemented, see help" " for details") + def Torus(R=2, r=1, names=None): """ Generate a 2-dimensional torus embedded in Euclidean space. @@ -233,9 +233,7 @@ def Torus(R=2, r=1, names=None): - ``names`` -- (default: ``None``) name of the coordinates, automatically set by the shortcut operator - OUTPUT: - - - Riemannian manifold + OUTPUT: Riemannian manifold EXAMPLES:: @@ -257,7 +255,7 @@ def Torus(R=2, r=1, names=None): from sage.manifolds.manifold import Manifold from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace E = EuclideanSpace(3, symbols='X Y Z') - M = Manifold(2, 'T', ambient=E, structure="Riemannian") + M = Manifold(2, 'T', ambient=E, structure='Riemannian') if names is None: names = ("th", "ph") names = tuple([names[i] + ":(-pi,pi):periodic" for i in range(2)]) @@ -278,16 +276,14 @@ def RealProjectiveSpace(dim=2): This is the topological space of lines through the origin in `\RR^{d+1}`. The standard atlas consists of `d+2` charts, which sends the set `U_i = \{[x_1, x_2, \ldots, x_{d+1}] : x_i \neq 0 \}` to - `k^{d}` by dividing by `x_i` and omitting the `i`th coordinate + `k^{d}` by dividing by `x_i` and omitting the `i`-th coordinate `x_i/x_i = 1`. INPUT: - ``dim`` -- (default: ``2``) the dimension of projective space - OUTPUT: - - - ``P`` -- the projective space `\Bold{RP}^d` where `d =` ``dim``. + OUTPUT: ``P`` -- the projective space `\Bold{RP}^d` where `d =` ``dim`` EXAMPLES:: @@ -356,7 +352,6 @@ def RealProjectiveSpace(dim=2): False sage: C0(p) (1/3,) - """ from sage.manifolds.manifold import Manifold diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py index acb88bf241a..d0d3148be7e 100644 --- a/src/sage/manifolds/chart.py +++ b/src/sage/manifolds/chart.py @@ -96,7 +96,7 @@ class Chart(UniqueRepresentation, SageObject): ``coordinates`` is not provided; it must then be a tuple containing the coordinate symbols (this is guaranteed if the shortcut operator ``<,>`` is used) - - ``coord_restrictions``: Additional restrictions on the coordinates. + - ``coord_restrictions`` -- additional restrictions on the coordinates. A restriction can be any symbolic equality or inequality involving the coordinates, such as ``x > y`` or ``x^2 + y^2 != 0``. The items of the list (or set or frozenset) ``coord_restrictions`` are combined @@ -284,7 +284,6 @@ class Chart(UniqueRepresentation, SageObject): :class:`sage.manifolds.chart.RealChart` for charts on topological manifolds over `\RR`. - """ @staticmethod @@ -353,7 +352,6 @@ def __init__(self, domain, coordinates, calc_method=None, periods=None, sage: XV = V.chart('x y') sage: M.top_charts() [Chart (U, (x, y)), Chart (V, (x, y))] - """ from sage.manifolds.manifold import TopologicalManifold if not isinstance(domain, TopologicalManifold): @@ -430,7 +428,7 @@ def _parse_coordinates(cls, domain, coordinates): - a tuple of variables (as elements of ``SR``) - a dictionary with possible keys: - - ``"periods"``: a tuple of periods + - ``'periods'`` -- a tuple of periods TESTS:: @@ -490,7 +488,6 @@ def _normalize_coord_restrictions(coordinates, coord_restrictions): frozenset({(x != 0, y != 0)}) sage: Chart._normalize_coord_restrictions(coordinates, [x > y, (x != 0, y != 0), z^2 < x]) frozenset({(x != 0, y != 0), x > y, z^2 < x}) - """ def normalize(r): if isinstance(r, tuple): # or @@ -524,7 +521,6 @@ def _repr_(self): sage: X. = M.chart() sage: X Chart (M, (x, y)) - """ return 'Chart ({}, {})'.format(self.domain()._name, self._xx) @@ -543,7 +539,6 @@ def _latex_(self): '\\left(M,({\\zeta_1}, {\\zeta2})\\right)' sage: latex(Y) \left(M,({\zeta_1}, {\zeta2})\right) - """ description = r'\left(' + latex(self.domain()).strip() + ',(' n = len(self._xx) @@ -560,7 +555,6 @@ def _first_ngens(self, n): sage: preparse("c_cart. = M.chart()") "c_cart = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = c_cart._first_ngens(3)" - """ return self[:] @@ -625,9 +619,7 @@ def __call__(self, point): - ``point`` -- point in the domain of the chart - OUTPUT: - - - tuple of the coordinates of the point + OUTPUT: tuple of the coordinates of the point EXAMPLES:: @@ -638,7 +630,6 @@ def __call__(self, point): (I + 1, -I + 2) sage: X(M.an_element()) (0, 0) - """ return point.coord(self) @@ -656,7 +647,6 @@ def domain(self): sage: Y. = U.chart() sage: Y.domain() Open subset U of the 2-dimensional topological manifold M - """ return self._domain @@ -673,7 +663,6 @@ def manifold(self): 2-dimensional topological manifold M sage: X.domain() Open subset U of the 2-dimensional topological manifold M - """ return self._manifold @@ -718,7 +707,6 @@ def periods(self): sage: X. = M.chart(r"xq:period=3/2 yq:\zeta:period=2") sage: X.periods() (3/2, 2) - """ return self._periods @@ -762,7 +750,6 @@ def add_restrictions(self, restrictions): True sage: X.valid_coordinates(i, 1) False - """ from sage.misc.superseded import deprecation deprecation(32102, "Chart.add_restrictions is deprecated; provide the restrictions at the time of creating the chart") @@ -815,7 +802,6 @@ def restrict(self, subset, restrictions=None): sage: B = M.open_subset('B') sage: X_B = X.restrict(B, abs(z1)^2 + abs(z2)^2 < 1); X_B Chart (B, (z1, z2)) - """ if subset == self.domain(): return self @@ -887,7 +873,6 @@ def valid_coordinates(self, *coordinates, **kwds): True sage: Y.valid_coordinates(1, 2*i, parameters={a: 2}) False - """ if len(coordinates) != self.domain()._dim: return False @@ -910,15 +895,13 @@ def _check_restrictions(self, restrict, substitutions): INPUT: - - restrict: a tuple of conditions (combined with 'or'), a list of + - ``restrict`` -- a tuple of conditions (combined with 'or'), a list of conditions (combined with 'and') or a single coordinate condition - - substitutions: dictionary (keys: coordinates of ``self``) giving the + - ``substitutions`` -- dictionary (keys: coordinates of ``self``) giving the value of each coordinate - OUTPUT: - - - boolean stating whether the conditions are fulfilled by the - coordinate values + OUTPUT: boolean stating whether the conditions are fulfilled by the + coordinate values TESTS:: @@ -942,7 +925,6 @@ def _check_restrictions(self, restrict, substitutions): True sage: X._check_restrictions([(x0], {x: 2, y: 1}) False - """ if isinstance(restrict, tuple): # case of 'or' conditions return any(self._check_restrictions(cond, substitutions) @@ -963,7 +945,6 @@ def codomain(self): sage: X. = M.chart() sage: X.codomain() Vector space of dimension 2 over Complex Field with 53 bits of precision - """ from sage.modules.free_module import VectorSpace ambient = VectorSpace(self.manifold().base_field(), self.manifold().dimension()) @@ -1118,7 +1099,6 @@ def transition_map(self, other, transformations, intersection_name=None, sage: M.atlas() [Chart (R^2, (x, y)), Chart (U, (r, phi)), Chart (U, (x, y))] - """ dom1 = self.domain() dom2 = other.domain() @@ -1149,7 +1129,7 @@ def preimage(self, codomain_subset, name=None, latex_name=None): object with a ``__contains__`` method that accepts coordinate vectors - ``name`` -- string; name (symbol) given to the subset - - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to + - ``latex_name`` -- string (default: ``None``); LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` OUTPUT: @@ -1279,7 +1259,7 @@ def function(self, expression, calc_method=None, expansion_symbol=None, - ``expression`` -- a symbolic expression involving the chart coordinates, to represent `f(x^1,\ldots, x^n)` - - ``calc_method`` -- string (default: ``None``): the calculus method + - ``calc_method`` -- string (default: ``None``); the calculus method with respect to which the internal expression of the function must be initialized from ``expression``; one of @@ -1336,7 +1316,6 @@ def function(self, expression, calc_method=None, expansion_symbol=None, {'SR': sin(x*y)} See :class:`~sage.manifolds.chart_func.ChartFunction` for more examples. - """ parent = self.function_ring() return parent.element_class(parent, expression, calc_method=calc_method, @@ -1383,7 +1362,7 @@ def zero_function(self): sage: X.zero_function() is X.zero_function() True - Zero function on a p-adic manifold:: + Zero function on a `p`-adic manifold:: sage: # needs sage.rings.padics sage: M = Manifold(2, 'M', structure='topological', field=Qp(5)); M @@ -1394,7 +1373,6 @@ def zero_function(self): 0 sage: X.zero_function().display() (x, y) ↦ 0 - """ return self.function_ring().zero() @@ -1438,7 +1416,7 @@ def one_function(self): sage: X.one_function() is X.one_function() True - One function on a p-adic manifold:: + One function on a `p`-adic manifold:: sage: # needs sage.rings.padics sage: M = Manifold(2, 'M', structure='topological', field=Qp(5)); M @@ -1449,7 +1427,6 @@ def one_function(self): 1 + O(5^20) sage: X.one_function().display() (x, y) ↦ 1 + O(5^20) - """ return self.function_ring().one() @@ -1469,9 +1446,7 @@ def calculus_method(self): :class:`~sage.manifolds.calculus_method.CalculusMethod` for a complete documentation. - OUTPUT: - - - an instance of :class:`~sage.manifolds.calculus_method.CalculusMethod` + OUTPUT: an instance of :class:`~sage.manifolds.calculus_method.CalculusMethod` EXAMPLES: @@ -1515,7 +1490,6 @@ def calculus_method(self): sage: X.calculus_method().set('SR') sage: f.display() (x, y) ↦ x^2 + cos(y)*sin(x) - """ return self._calc_method @@ -1571,7 +1545,6 @@ def multifunction(self, *expressions): sage: type(f) - """ from sage.manifolds.chart_func import MultiCoordFunction return MultiCoordFunction(self, expressions) @@ -1635,7 +1608,7 @@ class RealChart(Chart): ``coordinates`` is not provided; it must then be a tuple containing the coordinate symbols (this is guaranteed if the shortcut operator ``<,>`` is used) - - ``coord_restrictions``: Additional restrictions on the coordinates. + - ``coord_restrictions`` -- additional restrictions on the coordinates. A restriction can be any symbolic equality or inequality involving the coordinates, such as ``x > y`` or ``x^2 + y^2 != 0``. The items of the list (or set or frozenset) ``coord_restrictions`` are combined @@ -1857,7 +1830,6 @@ class RealChart(Chart): Chart grids can be drawn in 2D or 3D graphics thanks to the method :meth:`plot`. - """ def __init__(self, domain, coordinates, calc_method=None, bounds=None, periods=None, coord_restrictions=None): @@ -1876,7 +1848,6 @@ def __init__(self, domain, coordinates, calc_method=None, bounds=None, sage: assumptions() # assumptions set in X._init_coordinates [x is real, y is real] sage: TestSuite(X).run() - """ super().__init__(domain, coordinates, calc_method=calc_method, periods=periods, coord_restrictions=coord_restrictions) @@ -1906,8 +1877,8 @@ def _parse_coordinates(cls, domain, coordinates): - a tuple of variables (as elements of ``SR``) - a dictionary with possible keys: - - ``"periods"``: a tuple of periods - - ``"bounds"``: a tuple of coordinate ranges + - ``'periods'`` -- a tuple of periods + - ``'bounds'`` -- a tuple of coordinate ranges TESTS:: @@ -2050,7 +2021,6 @@ def coord_bounds(self, i=None): [x is real] sage: assumptions(y) [y is real, y >= 0, y < 1] - """ if i is None: return self._bounds @@ -2134,7 +2104,6 @@ def coord_range(self, xx=None): sage: latex(XU.coord_range(y)) y :\ \left( -\infty, \pi \right) - """ from sage.tensor.modules.format_utilities import FormattedExpansion @@ -2252,14 +2221,13 @@ def add_restrictions(self, restrictions): sage: X_U.add_restrictions([x<0, y>1/2]) sage: X_U.coord_range() x: (-oo, 0); y: (1/2, +oo) - """ super().add_restrictions(restrictions) self._tighten_bounds() def _tighten_bounds(self): """ - Update coordinate bounds from the coordinate restrictions + Update coordinate bounds from the coordinate restrictions. EXAMPLES:: @@ -2269,7 +2237,6 @@ def _tighten_bounds(self): sage: X_U = X.restrict(U, restrictions=[x<0, y>1/2]) sage: X_U.coord_range() x: (-oo, 0); y: (1/2, +oo) - """ import operator bounds = list(self._bounds) # convert to a list for modifications @@ -2395,7 +2362,6 @@ def restrict(self, subset, restrictions=None): x: (0, 1); y: [0, 2] (periodic) sage: XU.periods() (None, 2) - """ if subset == self.domain(): return self @@ -2439,7 +2405,6 @@ def valid_coordinates(self, *coordinates, **kwds): coordinate ranges - ``parameters=None``, to set some numerical values to parameters - OUTPUT: - ``True`` if the coordinate values are admissible in the chart range @@ -2485,7 +2450,6 @@ def valid_coordinates(self, *coordinates, **kwds): False sage: XB.valid_coordinates(3/2, 1/2) True - """ n = len(coordinates) if n != self._manifold._dim: @@ -2584,7 +2548,6 @@ def valid_coordinates_numerical(self, *coordinates): False sage: XB.valid_coordinates_numerical(3/2, 1/2) True - """ # case fast callable already computed if self._fast_valid_coordinates is not None: @@ -2740,7 +2703,7 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, representing the number of points to plot the lines along which the coordinate varies, the other being kept constant; if ``plot_points`` is a single integer, it is used for all coordinate lines - - ``label_axes`` -- (default: ``True``) boolean determining whether the + - ``label_axes`` -- boolean (default: ``True``); determining whether the labels of the ambient coordinate axes shall be added to the graph; can be set to ``False`` if the graph is 3D and must be superposed with another graph @@ -3039,7 +3002,6 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, To restore the original default options, it suffices to type:: sage: X.plot.reset() - """ from sage.misc.functional import numerical_approx from sage.plot.graphics import Graphics @@ -3308,6 +3270,7 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): # ***************************************************************************** + class CoordChange(SageObject): r""" Transition map between two charts of a topological manifold. @@ -3349,7 +3312,6 @@ class CoordChange(SageObject): sage: X_to_Y.display() u = x + y v = x - y - """ def __init__(self, chart1, chart2, *transformations): r""" @@ -3366,7 +3328,6 @@ def __init__(self, chart1, chart2, *transformations): sage: type(X_to_Y) sage: TestSuite(X_to_Y).run() - """ self._n1 = len(chart1._xx) self._n2 = len(chart2._xx) @@ -3402,7 +3363,6 @@ def _repr_(self): 'Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))' sage: X_to_Y # indirect doctest Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)) - """ return "Change of coordinates from {} to {}".format(self._chart1, self._chart2) @@ -3421,7 +3381,6 @@ def _latex_(self): \left(M,(x, y)\right) \rightarrow \left(M,(u, v)\right) sage: latex(X_to_Y) # indirect doctest \left(M,(x, y)\right) \rightarrow \left(M,(u, v)\right) - """ return latex(self._chart1) + r' \rightarrow ' + latex(self._chart2) @@ -3447,7 +3406,6 @@ def __eq__(self, other): sage: X_to_Z = X.transition_map(Z, [x+y, x-y]) sage: X_to_Y == X_to_Z False - """ if other is self: return True @@ -3470,7 +3428,6 @@ def __ne__(self, other): sage: X_to_Y2 = X.transition_map(Y, [2*y, -x]) sage: X_to_Y != X_to_Y2 True - """ return not (self == other) @@ -3482,9 +3439,7 @@ def __call__(self, *coords): - ``coords`` -- values of coordinates of ``chart1`` - OUTPUT: - - - tuple of values of coordinates of ``chart2`` + OUTPUT: tuple of values of coordinates of ``chart2`` EXAMPLES:: @@ -3494,7 +3449,6 @@ def __call__(self, *coords): sage: X_to_Y = X.transition_map(Y, [x+y, x-y]) sage: X_to_Y(1,2) (3, -1) - """ return self._transf(*coords) @@ -3546,7 +3500,6 @@ def inverse(self): sage: uv_to_xy.inverse() is xy_to_uv True - """ from sage.symbolic.relation import solve if self._inverse is not None: @@ -3631,7 +3584,7 @@ def inverse(self): def set_inverse(self, *transformations, **kwds): r""" - Sets the inverse of the coordinate transformation. + Set the inverse of the coordinate transformation. This is useful when the automatic computation via :meth:`inverse()` fails. @@ -3643,10 +3596,10 @@ def set_inverse(self, *transformations, **kwds): "new" ones - ``kwds`` -- optional arguments; valid keywords are - - ``check`` (default: ``True``) -- boolean determining whether the + - ``check`` -- boolean (default: ``True``); whether the provided transformations are checked to be indeed the inverse coordinate transformations - - ``verbose`` (default: ``False``) -- boolean determining whether + - ``verbose`` -- boolean (default: ``False``); whether some details of the check are printed out; if ``False``, no output is printed if the check is passed (see example below) @@ -3736,7 +3689,6 @@ def set_inverse(self, *transformations, **kwds): Traceback (most recent call last): ... TypeError: bla is not a valid keyword argument - """ check = kwds.pop('check', True) verbose = kwds.pop('verbose', False) @@ -3803,7 +3755,6 @@ def __mul__(self, other): sage: X_to_W.display() w = 1/2*cos(x)*cos(y) - 1/2*sin(x)*sin(y) + x + y z = -1/2*cos(y)*sin(x) + 1/2*cos(x)*sin(y) + x - y - """ if not isinstance(other, CoordChange): raise TypeError("{} is not a change of coordinate".format(other)) @@ -3846,7 +3797,6 @@ def restrict(self, dom1, dom2=None): sage: X_to_Y.restrict(U) is X_to_Y_U True - """ if dom2 is None: dom2 = dom1 @@ -3885,7 +3835,6 @@ def display(self): sage: spher_to_cart.disp() x = r*cos(ph) y = r*sin(ph) - """ from sage.misc.latex import latex from sage.tensor.modules.format_utilities import FormattedExpansion diff --git a/src/sage/manifolds/chart_func.py b/src/sage/manifolds/chart_func.py index 454f6489441..aae7a2b1fff 100644 --- a/src/sage/manifolds/chart_func.py +++ b/src/sage/manifolds/chart_func.py @@ -85,9 +85,9 @@ class ChartFunction(AlgebraElement, ModuleElementWithMutability): `f(x^1, \ldots, x^n)`, where `(x^1, \ldots, x^n)` are the coordinates of the chart `(U, \varphi)` - - ``calc_method`` -- string (default: ``None``): the calculus method with + - ``calc_method`` -- string (default: ``None``); the calculus method with respect to which the internal expression of ``self`` must be initialized - from ``expression``; one of + from ``expression``. One of - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - ``'sympy'``: SymPy @@ -325,7 +325,6 @@ class ChartFunction(AlgebraElement, ModuleElementWithMutability): u(x, y)*v(x, y) .. automethod:: __call__ - """ def __init__(self, parent, expression=None, calc_method=None, @@ -360,7 +359,6 @@ def __init__(self, parent, expression=None, calc_method=None, sage: g = Y.function(i*z + 2*w); g 2*w + I*z sage: TestSuite(g).run() - """ ModuleElementWithMutability.__init__(self, parent) self._chart = parent._chart @@ -390,9 +388,7 @@ def _simplify(self, expr): - ``expr`` -- expression to simplify - OUTPUT: - - - simplified expression + OUTPUT: simplified expression EXAMPLES: @@ -401,7 +397,6 @@ def _simplify(self, expr): sage: fc = c_xy.function(x+2*y^3) sage: fc._simplify(x+x) 2*x - """ res = self._calc_method.simplify(expr) if (self._expansion_symbol is not None and @@ -413,9 +408,7 @@ def chart(self): r""" Return the chart with respect to which ``self`` is defined. - OUTPUT: - - - a :class:`~sage.manifolds.chart.Chart` + OUTPUT: a :class:`~sage.manifolds.chart.Chart` EXAMPLES:: @@ -426,7 +419,6 @@ def chart(self): Chart (M, (x, y)) sage: f.chart() is X True - """ return self._chart @@ -444,9 +436,7 @@ def scalar_field(self, name=None, latex_name=None): - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the scalar field; if ``None``, the LaTeX symbol is set to ``name`` - OUTPUT: - - - a :class:`~sage.manifolds.scalarfield.ScalarField` + OUTPUT: a :class:`~sage.manifolds.scalarfield.ScalarField` EXAMPLES: @@ -462,7 +452,6 @@ def scalar_field(self, name=None, latex_name=None): (x, y) ↦ 2*y^3 + x sage: f.coord_function(c_xy) is fc True - """ alg = self._chart.domain().scalar_field_algebra() return alg.element_class(alg, @@ -476,8 +465,8 @@ def expr(self, method=None): INPUT: - - ``method`` -- string (default: ``None``): the calculus method which - the returned expression belongs to; one of + - ``method`` -- string (default: ``None``); the calculus method which + the returned expression belongs to. One of - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - ``'sympy'``: SymPy @@ -552,7 +541,6 @@ def expr(self, method=None): 3*a*x sage: bool( f(x,3) == f.expr().subs(y=3) ) True - """ if method is None: method = self._calc_method._current @@ -580,7 +568,6 @@ def set_expr(self, calc_method, expression): - ``expression`` -- symbolic expression - EXAMPLES:: sage: M = Manifold(2, 'M', structure='topological') @@ -599,7 +586,6 @@ def set_expr(self, calc_method, expression): Traceback (most recent call last): ... ValueError: Expressions are not equal - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element cannot " @@ -625,7 +611,6 @@ def _repr_(self): 'x*y + 1' sage: f # indirect doctest x*y + 1 - """ curr = self._calc_method._current if (curr == 'SR' and @@ -647,7 +632,6 @@ def _latex_(self): \cos\left(\frac{1}{2} \, x y\right) sage: latex(f) # indirect doctest \cos\left(\frac{1}{2} \, x y\right) - """ curr = self._calc_method._current if (curr == 'SR' and @@ -686,7 +670,6 @@ def display(self): sage: X.zero_function().display() (x, y) ↦ 0 - """ from sage.typeset.unicode_characters import unicode_mapsto from sage.tensor.modules.format_utilities import FormattedExpansion @@ -756,7 +739,6 @@ def __call__(self, *coords, **options): 1 sage: type(f(pi, 1/2)) - """ if len(coords) != self._nc: raise ValueError("bad number of coordinates") @@ -811,7 +793,6 @@ def __bool__(self): True sage: X.zero_function() == 0 True - """ curr = self._calc_method._current if curr == 'SR': @@ -863,7 +844,6 @@ def is_trivial_zero(self): True sage: f == 0 True - """ curr = self._calc_method._current return self._calc_method.is_trivial_zero(self.expr(curr)) @@ -910,7 +890,6 @@ def is_trivial_one(self): True sage: f == 1 True - """ curr = self._calc_method._current return self._calc_method.is_trivial_zero(self.expr(curr) - SR.one()) @@ -932,7 +911,6 @@ def is_unit(self): sage: zero = X.function(0) sage: zero.is_unit() False - """ return not self.is_trivial_zero() @@ -940,9 +918,7 @@ def copy(self): r""" Return an exact copy of the object. - OUTPUT: - - - a :class:`ChartFunctionSymb` + OUTPUT: a :class:`ChartFunctionSymb` EXAMPLES:: @@ -963,7 +939,6 @@ def copy(self): sage: g is f False - """ resu = type(self)(self.parent()) for kk, vv in self._express.items(): @@ -1048,7 +1023,6 @@ def derivative(self, coord): 2*x sage: f.diff(y) 3 - """ from sage.calculus.functional import diff from sage.rings.integer import Integer @@ -1087,9 +1061,7 @@ def __eq__(self, other): - ``other`` -- a :class:`ChartFunction` or a value - OUTPUT: - - - ``True`` if ``self`` is equal to ``other``, or ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other``, or ``False`` otherwise TESTS: @@ -1121,7 +1093,6 @@ def __eq__(self, other): True sage: X.zero_function() == 0 True - """ if other is self: return True @@ -1165,7 +1136,6 @@ def __ne__(self, other): True sage: f != X.function(x-y) False - """ return not (self == other) @@ -1173,9 +1143,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the opposite of ``self`` + OUTPUT: the opposite of ``self`` TESTS: @@ -1190,7 +1158,6 @@ def __neg__(self): sage: -g == f True - """ curr = self._calc_method._current resu = type(self)(self.parent()) @@ -1208,9 +1175,7 @@ def __invert__(self): chart function `1/f`, where `1` of the multiplicative identity of `K`. - OUTPUT: - - - the inverse of ``self`` + OUTPUT: the inverse of ``self`` TESTS: @@ -1241,7 +1206,6 @@ def __invert__(self): True sage: g.__invert__() == f True - """ curr = self._calc_method._current if curr == 'SR': @@ -1438,7 +1402,6 @@ def _mul_(self, other): 0 sage: (f * (1/f)).expr() 1 - """ curr = self._calc_method._current if other._expansion_symbol is not None: @@ -1482,7 +1445,6 @@ def _rmul_(self, other): pi*(x + y) sage: (x * f).expr() x*(x + y) - """ curr = self._calc_method._current try: @@ -1518,7 +1480,6 @@ def _lmul_(self, other): (x, y) ↦ 2*x + 2*y sage: (f * pi).display() (x, y) ↦ pi*(x + y) - """ curr = self._calc_method._current try: @@ -1578,8 +1539,6 @@ def _div_(self, other): (x, y) ↦ (x + y)/(x**2 + y**2 + 1) sage: (f / g) == ~(g / f) True - - """ if other.is_zero(): raise ZeroDivisionError("division of a chart function by zero") @@ -1627,7 +1586,6 @@ def exp(self): (x, y) ↦ exp(x + y) sage: exp(X.zero_function()) 1 - """ curr = self._calc_method._current if curr == 'SR': @@ -1682,7 +1640,6 @@ def log(self, base=None): log(x + y)/log(2) sage: log(f, 2) log(x + y)/log(2) - """ curr = self._calc_method._current if curr == 'SR': @@ -1740,7 +1697,6 @@ def __pow__(self, exponent): (x, y) ↦ x**3 + 3*x**2*y + 3*x*y**2 + y**3 sage: pow(X.zero_function(), 3).display() (x, y) ↦ 0 - """ curr = self._calc_method._current if curr == 'SR': @@ -1773,7 +1729,6 @@ def sqrt(self): (x, y) ↦ sqrt(x + y) sage: sqrt(X.zero_function()).display() (x, y) ↦ 0 - """ curr = self._calc_method._current if curr == 'SR': @@ -1814,7 +1769,6 @@ def cos(self): cos(x*y) sage: cos(f) # equivalent to f.cos() cos(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -1860,7 +1814,6 @@ def sin(self): sin(x*y) sage: sin(f) # equivalent to f.sin() sin(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -1904,7 +1857,6 @@ def tan(self): tan(x*y) sage: tan(g).display() (x, y) ↦ tan(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -1952,7 +1904,6 @@ def arccos(self): acos(x*y) sage: arccos(f).display() (x, y) ↦ acos(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -1997,7 +1948,6 @@ def arcsin(self): asin(x*y) sage: asin(f) # equivalent to f.arcsin() asin(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2042,7 +1992,6 @@ def arctan(self): atan(x*y) sage: atan(f) # equivalent to f.arctan() atan(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2083,7 +2032,6 @@ def cosh(self): cosh(x*y) sage: cosh(f) # equivalent to f.cosh() cosh(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2124,7 +2072,6 @@ def sinh(self): sinh(x*y) sage: sinh(f) # equivalent to f.sinh() sinh(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2165,7 +2112,6 @@ def tanh(self): tanh(x*y) sage: tanh(f) # equivalent to f.tanh() tanh(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2210,7 +2156,6 @@ def arccosh(self): acosh(x*y) sage: acosh(f) # equivalent to f.arccosh() acosh(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2255,7 +2200,6 @@ def arcsinh(self): asinh(x*y) sage: asinh(f) # equivalent to f.arcsinh() asinh(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2300,7 +2244,6 @@ def arctanh(self): atanh(x*y) sage: atanh(f) # equivalent to f.arctanh() atanh(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2341,7 +2284,6 @@ def __abs__(self): Abs(x*y) sage: abs(f) # equivalent to f.abs() Abs(x*y) - """ curr = self._calc_method._current if curr == 'SR': @@ -2382,7 +2324,6 @@ def _del_derived(self): sage: f._del_derived() sage: f._der - """ self._der = None # reset of the partial derivatives @@ -2402,9 +2343,7 @@ def simplify(self): expression of ``self`` will be expanded in power series of that parameter and truncated to the given order. - OUTPUT: - - - ``self`` with its coordinate expression simplified + OUTPUT: ``self`` with its coordinate expression simplified EXAMPLES: @@ -2504,7 +2443,6 @@ def simplify(self): 1/6*t^3*x^3 + 1/2*t^2*x^2 + t*x + 1 sage: f.display() (x, y) ↦ 1/6*t^3*x^3 + 1/2*t^2*x^2 + t*x + 1 - """ curr = self._calc_method._current self._express[curr] = self._simplify(self.expr(curr)) @@ -2515,9 +2453,7 @@ def factor(self): r""" Factorize the coordinate expression of ``self``. - OUTPUT: - - - ``self`` with its expression factorized + OUTPUT: ``self`` with its expression factorized EXAMPLES: @@ -2544,7 +2480,6 @@ def factor(self): (x, y) ↦ x**2 + 2*x*y + y**2 sage: g.factor() (x + y)**2 - """ curr = self._calc_method._current self._express[curr] = self.expr().factor() @@ -2555,9 +2490,7 @@ def expand(self): r""" Expand the coordinate expression of ``self``. - OUTPUT: - - - ``self`` with its expression expanded + OUTPUT: ``self`` with its expression expanded EXAMPLES: @@ -2582,7 +2515,6 @@ def expand(self): sage: g = X.function((x - y)^2) sage: g.expand() x**2 - 2*x*y + y**2 - """ curr = self._calc_method._current self._express[curr] = self.expr().expand() @@ -2628,7 +2560,6 @@ def collect(self, s): (x, y) ↦ x**2*y**2 + x**2*y + x*y sage: f.collect(y) x**2*y**2 + y*(x**2 + x) - """ curr = self._calc_method._current self._express[curr] = self.expr().collect(s) @@ -2673,7 +2604,6 @@ def collect_common_factors(self): (x, y) ↦ x/(x**2*y + x*y) sage: g.collect_common_factors() 1/(y*(x + 1)) - """ curr = self._calc_method._current if curr == 'sympy': @@ -2683,6 +2613,7 @@ def collect_common_factors(self): self._del_derived() return self + class ChartFunctionRing(Parent, UniqueRepresentation): """ Ring of all chart functions on a chart. @@ -2720,7 +2651,6 @@ class ChartFunctionRing(Parent, UniqueRepresentation): sage: FR_Y = Y.function_ring() sage: FR_Y.has_coerce_map_from(FR_X) False - """ Element = ChartFunction @@ -2734,7 +2664,6 @@ def __init__(self, chart): sage: X. = M.chart() sage: FR = X.function_ring() sage: TestSuite(FR).run() - """ self._chart = chart Parent.__init__(self, base=SR, category=CommutativeAlgebras(SR)) @@ -2763,7 +2692,6 @@ def _element_constructor_(self, expression, calc_method=None): sage: FR_D = X_D.function_ring() sage: FR_D(f) sin(x*y) - """ if isinstance(expression, ChartFunction): if self._chart in expression._chart._subcharts: @@ -2786,7 +2714,6 @@ def _coerce_map_from_(self, other): sage: FR_D = X_D.function_ring() sage: FR_D.has_coerce_map_from(FR) True - """ if SR.has_coerce_map_from(other): return True @@ -2967,7 +2894,6 @@ class MultiCoordFunction(SageObject, Mutability): (a - b, a*b, cos(a)*e^b) sage: g(1,2) (4,) - """ def __init__(self, chart, expressions): r""" @@ -2982,7 +2908,6 @@ def __init__(self, chart, expressions): sage: type(f) sage: TestSuite(f).run() - """ self._chart = chart self._nc = len(self._chart._xx) # number of coordinates @@ -3004,7 +2929,6 @@ def _repr_(self): 'Coordinate functions (x - y, x*y, cos(x)*e^y) on the Chart (M, (x, y))' sage: f Coordinate functions (x - y, x*y, cos(x)*e^y) on the Chart (M, (x, y)) - """ return "Coordinate functions {} on the {}".format(self._functions, self._chart) @@ -3022,7 +2946,6 @@ def _latex_(self): \left(x - y, x y, \cos\left(x\right) e^{y}\right) sage: latex(f) \left(x - y, x y, \cos\left(x\right) e^{y}\right) - """ from sage.misc.latex import latex return latex(self._functions) @@ -3038,8 +2961,8 @@ def expr(self, method=None): INPUT: - - ``method`` -- string (default: ``None``): the calculus method which - the returned expressions belong to; one of + - ``method`` -- string (default: ``None``); the calculus method which + the returned expressions belong to. One of - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - ``'sympy'``: SymPy @@ -3071,7 +2994,6 @@ def expr(self, method=None): sage: f.chart().multifunction(*(f.expr())) == f True - """ return tuple(func.expr(method=method) for func in self._functions) @@ -3079,9 +3001,7 @@ def chart(self): r""" Return the chart with respect to which ``self`` is defined. - OUTPUT: - - - a :class:`~sage.manifolds.chart.Chart` + OUTPUT: a :class:`~sage.manifolds.chart.Chart` EXAMPLES:: @@ -3092,7 +3012,6 @@ def chart(self): Chart (M, (x, y)) sage: f.chart() is X True - """ return self._chart @@ -3104,9 +3023,7 @@ def __eq__(self, other): - ``other`` -- a :class:`MultiCoordFunction` - OUTPUT: - - - ``True`` if ``self`` is equal to ``other``, ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other``, ``False`` otherwise TESTS:: @@ -3122,7 +3039,6 @@ def __eq__(self, other): sage: Y. = M.chart() sage: f == Y.multifunction(u-v, u*v, cos(u*v)) False - """ if other is self: return True @@ -3159,7 +3075,6 @@ def __ne__(self, other): True sage: f != X.multifunction(x-y, x*y, cos(x*y)) False - """ return not (self == other) @@ -3188,7 +3103,6 @@ def __getitem__(self, index): cos(x*y) sage: f[0], f[1], f[2] (x - y, x*y, cos(x*y)) - """ return self._functions[index] @@ -3204,9 +3118,7 @@ def __call__(self, *coords, **options): ``simplify=False`` to disable simplification for symbolic coordinate functions - OUTPUT: - - - tuple containing the values of the `m` functions + OUTPUT: tuple containing the values of the `m` functions TESTS:: @@ -3219,7 +3131,6 @@ def __call__(self, *coords, **options): (-1, 6, cos(6)) sage: f.__call__(x,y) (x - y, x*y, cos(x*y)) - """ return tuple(func(*coords, **options) for func in self._functions) @@ -3293,9 +3204,7 @@ def jacobian_det(self): The number `m` of coordinate functions must equal the number `n` of coordinates. - OUTPUT: - - - a :class:`ChartFunction` representing the determinant + OUTPUT: a :class:`ChartFunction` representing the determinant EXAMPLES: @@ -3351,7 +3260,6 @@ def jacobian_det(self): sage: f.jacobian_det() == det(matrix([[f[i].diff(j).expr() for j in range(3)] ....: for i in range(3)])) True - """ from sage.matrix.constructor import matrix if self._nf != self._nc: @@ -3388,7 +3296,6 @@ def set_immutable(self): Ring of chart functions on Chart (M, (x, y, z)) sage: f[0].is_immutable() True - """ for func in self._functions: func.set_immutable() diff --git a/src/sage/manifolds/continuous_map.py b/src/sage/manifolds/continuous_map.py index 56f1ee139bd..2c30b796aab 100644 --- a/src/sage/manifolds/continuous_map.py +++ b/src/sage/manifolds/continuous_map.py @@ -34,6 +34,7 @@ from sage.categories.homset import Hom from sage.categories.morphism import Morphism + class ContinuousMap(Morphism): r""" Continuous map between two topological manifolds. @@ -60,7 +61,7 @@ class ContinuousMap(Morphism): - ``parent`` -- homset `\mathrm{Hom}(M,N)` to which the continuous map belongs - - ``coord_functions`` -- a dictionary of the coordinate expressions + - ``coord_functions`` -- dictionary of the coordinate expressions (as lists or tuples of the coordinates of the image expressed in terms of the coordinates of the considered point) with the pairs of charts ``(chart1, chart2)`` as keys (``chart1`` being a chart @@ -69,12 +70,12 @@ class ContinuousMap(Morphism): - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the continuous map; if ``None``, the LaTeX symbol is set to ``name`` - - ``is_isomorphism`` -- (default: ``False``) determines whether the - constructed object is a isomorphism (i.e. a homeomorphism); if set to - ``True``, then the manifolds `M` and `N` must have the same dimension - - ``is_identity`` -- (default: ``False``) determines whether the - constructed object is the identity map; if set to ``True``, - then `N` must be `M` and the entry ``coord_functions`` is not used + - ``is_isomorphism`` -- boolean (default: ``False``); determines whether the + constructed object is a isomorphism (i.e. a homeomorphism). If set to + ``True``, then the manifolds `M` and `N` must have the same dimension. + - ``is_identity`` -- boolean (default: ``False``); determines whether the + constructed object is the identity map. If set to ``True``, + then `N` must be `M` and the entry ``coord_functions`` is not used. .. NOTE:: @@ -341,7 +342,6 @@ class ContinuousMap(Morphism): True sage: ~id is id True - """ def __init__(self, parent, coord_functions=None, name=None, latex_name=None, is_isomorphism=False, is_identity=False): @@ -370,7 +370,6 @@ def __init__(self, parent, coord_functions=None, name=None, latex_name=None, Id_M: M → M (x, y) ↦ (x, y) sage: TestSuite(f).run() - """ Morphism.__init__(self, parent) domain = parent.domain() @@ -467,7 +466,6 @@ def _repr_(self): sage: f = Hom(M,M)({}, name='f', is_identity=True) sage: f Identity map f of the 2-dimensional topological manifold M - """ if self._is_identity: return "Identity map {} of the {}".format(self._name, self._domain) @@ -501,7 +499,6 @@ def _latex_(self): sage: f = Hom(M,M)({(X,X): (x+y,x*y)}, name='f', latex_name=r'\Phi') sage: latex(f) \Phi - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -530,7 +527,6 @@ def __hash__(self): sage: {f: 1}[f] 1 - """ return hash((self._domain, self._codomain)) @@ -542,9 +538,7 @@ def __eq__(self, other): - ``other`` -- a :class:`ContinuousMap` - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise TESTS:: @@ -559,7 +553,6 @@ def __eq__(self, other): sage: g = M.continuous_map(N, {(X,Y): [x+y+z, 1]}, name='g') sage: f == g False - """ if other is self: return True @@ -605,7 +598,6 @@ def __ne__(self, other): sage: g = M.continuous_map(N, {(X,Y): [x+y+z, 1]}, name='g') sage: f != g True - """ return not (self == other) @@ -622,9 +614,7 @@ def _call_(self, point): - ``point`` -- :class:`~sage.manifolds.point.TopologicalManifoldPoint`; point in the domain of ``self`` - OUTPUT: - - - image of the point by ``self`` + OUTPUT: image of the point by ``self`` EXAMPLES: @@ -659,7 +649,6 @@ def _call_(self, point): sage: q2 = rot(p2) # computation on c_spher sage: q2 == q True - """ # NB: checking that ``point`` belongs to the map's domain has been # already performed by Map.__call__(); this check is therefore not @@ -740,7 +729,6 @@ def is_identity(self): (x, y) ↦ (u, v) = (x, y) sage: a.is_identity() False - """ if self._is_identity: return True @@ -796,7 +784,6 @@ def _composition_(self, other, homset): (x, y, z) ↦ (a, b, c, d) = ((x*y + 1)*z + x + y, x*y*z^2 + (x^2*y + x*y^2)*z, x + y + z + 1, -x*y*z + 2) sage: s == f*g True - """ # This method is invoked by Map._composition (single underscore), # which is itself invoked by Map.__mul__ . The latter performs the @@ -833,8 +820,8 @@ def image(self, subset=None, inverse=None): EXAMPLES:: - sage: M = Manifold(2, 'M', structure="topological") - sage: N = Manifold(1, 'N', ambient=M, structure="topological") + sage: M = Manifold(2, 'M', structure='topological') + sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart(coord_restrictions=lambda u: [u > -1, u < 1]) sage: Phi = N.continuous_map(M, {(CN,CM): [u, u^2]}, name='Phi') @@ -875,7 +862,7 @@ def preimage(self, codomain_subset, name=None, latex_name=None): - ``codomain_subset`` -- an instance of :class:`~sage.manifolds.subset.ManifoldSubset` - ``name`` -- string; name (symbol) given to the subset - - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to + - ``latex_name`` -- string (default: ``None``); LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` OUTPUT: @@ -975,7 +962,6 @@ def _mul_(self, other): True sage: M.identity_map()._mul_(f) == f True - """ dom = self._domain return self._composition_(other, Hom(dom, dom)) @@ -1015,7 +1001,6 @@ def _init_derived(self): sage: g.inverse().restrict(U)[:] # used to be wrong [ 1 0] [ 0 1/2] - """ self._restrictions = {} # dict. of restrictions to subdomains of # self._domain @@ -1048,7 +1033,6 @@ def _del_derived(self): Homeomorphism of the 2-dimensional topological manifold M sage: f._del_derived() sage: f._inverse # has been set to None by _del_derived() - """ self._restrictions.clear() self._restrictions_graph = {(self._domain, self._codomain): self} @@ -1079,7 +1063,7 @@ def display(self, chart1=None, chart2=None): EXAMPLES: - A simple reparamentrization:: + A simple reparametrization:: sage: R. = manifolds.RealLine() sage: I = R.open_interval(0, 2*pi) @@ -1180,7 +1164,6 @@ def display(self, chart1=None, chart2=None): \frac{2 y}{x^{2} + y^{2} + 1}, \frac{x^{2} + y^{2} - 1}{x^{2} + y^{2} + 1}\right) \end{array} - """ from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_to, unicode_mapsto @@ -1362,7 +1345,6 @@ def coord_functions(self, chart1=None, chart2=None): - 2*V**2 + 6*V)/(2*(U - V)), (U**3/4 - U**2*V/4 - U*V**2/4 + U*V - U + V**3/4 - V**2 - V)/(U - V), (U**3 - U**2*V - U*V**2 - 4*U*V - 8*U + V**3 + 4*V**2 - 8*V)/(4*(U - V))) on the Chart (M, (U, V)) - """ dom1 = self._domain dom2 = self._codomain @@ -1547,7 +1529,6 @@ def expr(self, chart1=None, chart2=None): NB: a failed report can reflect a mere lack of simplification. sage: rot.expr(c_cart, c_cart) (-1/2*sqrt(3)*y + 1/2*x, 1/2*sqrt(3)*x + 1/2*y) - """ return self.coord_functions(chart1, chart2).expr() @@ -1792,7 +1773,6 @@ def add_expr(self, chart1, chart2, coord_functions): sage: q1 = rot(p1) # computation by means of spherical coordinates sage: q1 == q True - """ if self._is_identity: raise NotImplementedError("add_expr() must not be used for the identity map") @@ -1889,7 +1869,6 @@ def restrict(self, subdomain, subcodomain=None): sage: Phi.restrict(D, subcodomain=D) Continuous map from the Open subset D of the 2-dimensional topological manifold R^2 to itself - """ if subcodomain is None: if self._is_identity: @@ -1993,9 +1972,7 @@ def __invert__(self): r""" Return the inverse of ``self`` if it is an isomorphism. - OUTPUT: - - - the inverse isomorphism + OUTPUT: the inverse isomorphism EXAMPLES: @@ -2067,7 +2044,6 @@ def __invert__(self): sage: si == s True - """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve diff --git a/src/sage/manifolds/continuous_map_image.py b/src/sage/manifolds/continuous_map_image.py index c2ccb64f7a1..bbcfa672a5a 100644 --- a/src/sage/manifolds/continuous_map_image.py +++ b/src/sage/manifolds/continuous_map_image.py @@ -19,6 +19,7 @@ from sage.manifolds.subset import ManifoldSubset + class ImageManifoldSubset(ManifoldSubset): r""" Subset of a topological manifold that is a continuous image of a manifold subset. @@ -31,8 +32,8 @@ class ImageManifoldSubset(ManifoldSubset): of `\Phi` is the inverse of `\Phi` onto its image if the latter exists (NB: no check of this is performed) - ``name`` -- (default: computed from the names of the map and the subset) - string; name (symbol) given to the subset - - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to + string; name (symbol) given to the subset + - ``latex_name`` -- string (default: ``None``); LaTeX symbol to denote the subset; if none is provided, it is set to ``name`` - ``domain_subset`` -- (default: the domain of ``map``) a subset of the domain of ``map`` @@ -44,8 +45,8 @@ def __init__(self, map, inverse=None, name=None, latex_name=None, domain_subset= TESTS:: - sage: M = Manifold(2, 'M', structure="topological") - sage: N = Manifold(1, 'N', ambient=M, structure="topological") + sage: M = Manifold(2, 'M', structure='topological') + sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart(coord_restrictions=lambda u: [u > -1, u < 1]) sage: Phi = N.continuous_map(M, {(CN,CM): [u, 1 + u^2]}, name='Phi') @@ -76,8 +77,8 @@ def _repr_(self): TESTS:: - sage: M = Manifold(2, 'M', structure="topological") - sage: N = Manifold(1, 'N', ambient=M, structure="topological") + sage: M = Manifold(2, 'M', structure='topological') + sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart(coord_restrictions=lambda u: [u > -1, u < 1]) sage: Phi = N.continuous_map(M, {(CN,CM): [u, 1 + u^2]}, name='Phi') @@ -108,8 +109,8 @@ def _an_element_(self): EXAMPLES:: - sage: M = Manifold(2, 'M', structure="topological") - sage: N = Manifold(1, 'N', ambient=M, structure="topological") + sage: M = Manifold(2, 'M', structure='topological') + sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart(coord_restrictions=lambda u: [u > -1, u < 1]) sage: Phi = N.continuous_map(M, {(CN,CM): [u, 1 + u^2]}, name='Phi') @@ -127,8 +128,8 @@ def __contains__(self, point): TESTS:: - sage: M = Manifold(2, 'M', structure="topological") - sage: N = Manifold(1, 'N', ambient=M, structure="topological") + sage: M = Manifold(2, 'M', structure='topological') + sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart(coord_restrictions=lambda u: [u > -1, u < 1]) sage: Phi = N.continuous_map(M, {(CN,CM): [u, 1 + u^2]}, name='Phi') @@ -138,7 +139,6 @@ def __contains__(self, point): False sage: M((0, 1)) in Phi_N True - """ if super().__contains__(point): return True diff --git a/src/sage/manifolds/differentiable/affine_connection.py b/src/sage/manifolds/differentiable/affine_connection.py index fce8737df84..d1e25cc3e31 100644 --- a/src/sage/manifolds/differentiable/affine_connection.py +++ b/src/sage/manifolds/differentiable/affine_connection.py @@ -35,6 +35,7 @@ from sage.parallel.decorate import parallel from sage.parallel.parallelism import Parallelism + class AffineConnection(SageObject): r""" Affine connection on a smooth manifold. @@ -112,7 +113,7 @@ class AffineConnection(SageObject): :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`) - ``name`` -- name given to the affine connection - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the affine - connection; if ``None``, it is set to ``name``. + connection; if ``None``, it is set to ``name`` EXAMPLES: @@ -362,7 +363,6 @@ class AffineConnection(SageObject): True sage: nab_copy.is_immutable() False - """ def __init__(self, domain, name, latex_name=None): r""" @@ -380,7 +380,6 @@ def __init__(self, domain, name, latex_name=None): sage: X. = M.chart() sage: nab[0,1,0] = x*y*z sage: TestSuite(nab).run() - """ if not isinstance(domain, DifferentiableManifold): raise TypeError("the first argument must be a differentiable " + @@ -409,7 +408,6 @@ def _repr_(self): 'Affine connection nabla on the 5-dimensional differentiable manifold M' sage: repr(nab) # indirect doctest 'Affine connection nabla on the 5-dimensional differentiable manifold M' - """ description = "Affine connection" if self._name is not None: @@ -434,7 +432,6 @@ def _latex_(self): 'D' sage: latex(nab) # indirect doctest D - """ return self._latex_name @@ -447,7 +444,6 @@ def _init_derived(self): sage: M = Manifold(4, 'M') sage: nab = M.affine_connection('nabla', latex_name=r'\nabla') sage: nab._init_derived() - """ self._restrictions = {} # dict. of restrictions of ``self`` on some # subdomains, with the subdomains as keys @@ -470,7 +466,6 @@ def _del_derived(self): sage: M = Manifold(4, 'M') sage: nab = M.affine_connection('nabla', latex_name=r'\nabla') sage: nab._del_derived() - """ self._restrictions.clear() self._torsion = None @@ -488,9 +483,7 @@ def __eq__(self, other): - ``other`` -- an affine connection - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise TESTS:: @@ -522,7 +515,6 @@ def __eq__(self, other): sage: nab2.set_coef(f)[1,0,1] = x-y sage: (nab2 == nab) or (nab == nab2) False - """ if other is self: return True @@ -568,7 +560,6 @@ def __ne__(self, other): sage: nab1[0,1,0], nab1[0,1,1] = 1+x, x*y sage: (nab1 != nab) or (nab != nab1) False - """ return not (self == other) @@ -593,7 +584,6 @@ def domain(self): sage: nabU = U.affine_connection('D') sage: nabU.domain() Open subset U of the 3-dimensional differentiable manifold M - """ return self._domain @@ -612,7 +602,6 @@ def _new_coef(self, frame): sage: nab = M.affine_connection('nabla', latex_name=r'\nabla') sage: nab._new_coef(X.frame()) 3-indices components w.r.t. Coordinate frame (M, (∂/∂x,∂/∂y)) - """ from sage.tensor.modules.comp import Components from sage.manifolds.differentiable.scalarfield import DiffScalarField @@ -669,7 +658,6 @@ def coef(self, frame=None): [[[0, x^2, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, y*z], [0, 0, 0]]] - """ if frame is None: frame = self._domain.default_frame() @@ -778,7 +766,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such ValueError: no common frame found for the computation To keep them, use the method :meth:`add_coef` instead. - """ if self.is_immutable(): raise ValueError("the coefficients of an immutable element " @@ -825,7 +812,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such See method :meth:`coef` for the storage convention of the connection coefficients. - EXAMPLES: Setting the coefficients of an affine connection w.r.t. some coordinate @@ -869,8 +855,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such Gam^x_yx = x*y To delete them, use the method :meth:`set_coef` instead. - - """ if self.is_immutable(): raise ValueError("the coefficients of an immutable element " @@ -925,7 +909,6 @@ def del_other_coef(self, frame=None): Traceback (most recent call last): ... ValueError: no common frame found for the computation - """ if frame is None: frame = self._domain._def_frame @@ -972,7 +955,6 @@ def set_immutable(self): sage: nabU = nab.restrict(U) sage: nabU.is_immutable() True - """ for rst in self._restrictions.values(): rst.set_immutable() @@ -995,7 +977,6 @@ def is_immutable(self): sage: nab.set_immutable() sage: nab.is_immutable() True - """ return self._is_immutable @@ -1014,7 +995,6 @@ def is_mutable(self): sage: nab.set_immutable() sage: nab.is_mutable() False - """ return not self._is_immutable @@ -1051,7 +1031,6 @@ def copy(self, name, latex_name=None): sage: nab_copy.display() Gam^x_yx = x*y Gam^x_yy = x + y - """ copy = type(self)(self._domain, name, latex_name=latex_name) for dom, rst in self._restrictions.items(): @@ -1116,7 +1095,6 @@ def __getitem__(self, args): Scalar field on the 2-dimensional differentiable manifold M sage: nab.__getitem__(([X.frame(),1,2,1])).coord_function() is nab[1,2,1] True - """ if isinstance(args, list): # case of [[...]] syntax if isinstance(args[0], (int, Integer, slice)): @@ -1184,7 +1162,6 @@ def __setitem__(self, args, value): sage: nab.__setitem__((1,2,1), f) sage: nab[1,2,1] x*y - """ if isinstance(args, list): # case of [[...]] syntax if isinstance(args[0], (int, Integer, slice)): @@ -1236,12 +1213,12 @@ def display(self, frame=None, chart=None, symbol=None, latex_symbol=None, labels are used, except if ``frame`` is a coordinate frame and ``coordinate_symbols`` is set to ``True``, in which case the coordinate LaTeX symbols are used - - ``coordinate_labels`` -- (default: ``True``) boolean; if ``True``, + - ``coordinate_labels`` -- boolean (default: ``True``); if ``True``, coordinate symbols are used by default (instead of integers) as index labels whenever ``frame`` is a coordinate frame - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero connection coefficients are displayed - - ``only_nonredundant`` -- (default: ``False``) boolean; if ``True``, + - ``only_nonredundant`` -- boolean (default: ``False``); if ``True``, only nonredundant connection coefficients are displayed in case of symmetries @@ -1328,7 +1305,6 @@ def display(self, frame=None, chart=None, symbol=None, latex_symbol=None, Gam^ph_th,ph = cos(th)/sin(th) Gam^ph_ph,r = 1/r Gam^ph_ph,th = cos(th)/sin(th) - """ from sage.misc.latex import latex from sage.manifolds.differentiable.vectorframe import CoordFrame @@ -1363,9 +1339,7 @@ def restrict(self, subdomain): an instance of :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`) - OUTPUT: - - - instance of :class:`AffineConnection` representing the restriction. + OUTPUT: instance of :class:`AffineConnection` representing the restriction EXAMPLES: @@ -1398,7 +1372,6 @@ def restrict(self, subdomain): False sage: nab.restrict(U)[:] [[[0, x^2], [0, -y]], [[x + y, 0], [0, 0]]] - """ if subdomain == self._domain: return self @@ -1443,9 +1416,7 @@ def _common_frame(self, other): instance of :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal` - OUTPUT: - - - common frame; if no common frame is found, None is returned. + OUTPUT: common frame; if no common frame is found, ``None`` is returned TESTS:: @@ -1461,7 +1432,6 @@ def _common_frame(self, other): sage: u = M.vector_field() sage: u[e,:] = [-3, 2] sage: nab._common_frame(u) # no common frame is found - """ # The domain of search is restricted to other._domain: dom = other._domain @@ -1515,9 +1485,7 @@ def __call__(self, tensor): - ``tensor`` -- a tensor field `T`, of type `(k,\ell)` - OUTPUT: - - - tensor field `\nabla T`. + OUTPUT: tensor field `\nabla T` TESTS:: @@ -1534,7 +1502,6 @@ def __call__(self, tensor): See documentation of :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection` for more examples. - """ from sage.manifolds.differentiable.tensorfield_paral import \ TensorFieldParal @@ -1583,9 +1550,7 @@ def _derive_paral(self, tensor): - ``tensor`` -- a tensor field `T`, of type `(k,\ell)` - OUTPUT: - - - tensor field `\nabla T`. + OUTPUT: tensor field `\nabla T` TESTS:: @@ -1598,7 +1563,6 @@ def _derive_paral(self, tensor): sage: nab._derive_paral(v) Tensor field of type (1,1) on the 2-dimensional differentiable manifold M - """ from sage.manifolds.differentiable.scalarfield import DiffScalarField from sage.tensor.modules.comp import Components, CompWithSym @@ -1818,7 +1782,6 @@ def torsion(self): (1/8*u^3 - 1/8*u*v^2 - 1/2*u*v) du∧dv sage: 2*DDf.antisymmetrize() == nab(f).contract(nab.torsion()) True - """ if self._torsion is None: manif = self._domain @@ -1956,7 +1919,6 @@ def riemann(self): sage: r == r_backup # long time True sage: Parallelism().set(nproc=1) # switch off parallelization - """ if self._riemann is None: manif = self._domain @@ -2066,7 +2028,6 @@ def ricci(self): sage: nab.ricci() is r True - """ if self._ricci is None: self._ricci = self.riemann().trace(0,2) @@ -2189,7 +2150,6 @@ def connection_form(self, i, j, frame=None): True True True - """ if frame is None: frame = self._domain._def_frame @@ -2400,7 +2360,6 @@ def curvature_form(self, i, j, frame=None): ....: sum( omega(i,k,e).wedge(omega(k,j,e)) for k in M.irange()) ) sage: check # long time [True, True, True, True, True, True, True, True, True] - """ if frame is None: frame = self._domain._def_frame @@ -2440,7 +2399,7 @@ def set_calc_order(self, symbol, order, truncate=False): - ``order`` -- integer; the order `n` of the expansion, defined as the degree of the polynomial representing the truncated power series in ``symbol`` - - ``truncate`` -- (default: ``False``) determines whether the + - ``truncate`` -- boolean (default: ``False``); determines whether the connection coefficients are replaced by their expansions to the given order @@ -2465,7 +2424,6 @@ def set_calc_order(self, symbol, order, truncate=False): sage: nab.set_calc_order(e, 1, truncate=True) sage: nab[0, 1, 1] -e - """ for coef in self._coefficients.values(): for ind in coef.non_redundant_index_generator(): @@ -2510,7 +2468,6 @@ def __hash__(self): 1 sage: d[nab2] 2 - """ if self.is_mutable(): raise ValueError('element must be immutable in order to be ' diff --git a/src/sage/manifolds/differentiable/automorphismfield.py b/src/sage/manifolds/differentiable/automorphismfield.py index 04d099b4e4e..3556fc56e95 100644 --- a/src/sage/manifolds/differentiable/automorphismfield.py +++ b/src/sage/manifolds/differentiable/automorphismfield.py @@ -28,6 +28,7 @@ from sage.manifolds.differentiable.tensorfield import TensorField from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal + class AutomorphismField(TensorField): r""" Field of automorphisms of tangent spaces to a generic (a priori @@ -69,7 +70,7 @@ class AutomorphismField(TensorField): - ``name`` -- (default: ``None``) name given to the field - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the field; if none is provided, the LaTeX symbol is set to ``name`` - - ``is_identity`` -- (default: ``False``) determines whether the + - ``is_identity`` -- boolean (default: ``False``); determines whether the constructed object is a field of identity automorphisms EXAMPLES: @@ -136,7 +137,6 @@ class AutomorphismField(TensorField): sage: ia is ~a True - """ def __init__(self, vector_field_module, name=None, latex_name=None): r""" @@ -182,7 +182,6 @@ def __init__(self, vector_field_module, name=None, latex_name=None): .. TODO:: Fix ``_test_pickling`` (in the superclass :class:`TensorField`). - """ TensorField.__init__(self, vector_field_module, (1,1), name=name, latex_name=latex_name, @@ -205,7 +204,6 @@ def _repr_(self): sage: a # indirect doctest Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M - """ description = "Field of tangent-space " if self is self.parent().one(): @@ -225,7 +223,6 @@ def _init_derived(self): sage: M = Manifold(2, 'M') sage: a = M.automorphism_field(name='a') sage: a._init_derived() - """ TensorField._init_derived(self) self._inverse = None # inverse not set yet @@ -239,7 +236,6 @@ def _del_derived(self): sage: M = Manifold(2, 'M') sage: a = M.automorphism_field(name='a') sage: a._del_derived() - """ # First delete the derived quantities pertaining to the mother class: TensorField._del_derived(self) @@ -312,7 +308,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such ... ValueError: the components of an immutable element cannot be changed - """ comp = super().set_comp(basis=basis) self._is_identity = False # a priori @@ -385,7 +380,6 @@ class :class:`~sage.tensor.modules.comp.Components`; ... ValueError: the components of an immutable element cannot be changed - """ comp = super().add_comp(basis=basis) self._is_identity = False # a priori @@ -405,7 +399,6 @@ def _new_instance(self): differentiable manifold M sage: a._new_instance().parent() is a.parent() True - """ return type(self)(self._vmodule) @@ -483,7 +476,6 @@ def __call__(self, *arg): True sage: s.restrict(U) == a(z, w.restrict(U)) True - """ if self._is_identity: if len(arg) == 1: @@ -555,7 +547,6 @@ def copy(self, name=None, latex_name=None): sage: one = Id.copy('1'); one Field of tangent-space automorphisms 1 on the 2-dimensional differentiable manifold M - """ copy = super().copy(name=name, latex_name=latex_name) copy._is_identity = self._is_identity @@ -629,7 +620,6 @@ def __invert__(self): sage: ia is ~a True - """ if self._is_identity: return self @@ -709,7 +699,6 @@ def _mul_(self, other): sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) sage: s(w) == a(b(w)) # long time True - """ # No need for consistency check since self and other are guaranteed # to have the same parent. In particular, they are defined on the same @@ -766,7 +755,6 @@ def __mul__(self, other): True sage: s = a.__mul__(w); s # tensor product Tensor field of type (2,1) on the 2-dimensional differentiable manifold M - """ if isinstance(other, AutomorphismField): return self._mul_(other) # general linear group law @@ -803,7 +791,6 @@ def __imul__(self, other): sage: a *= b sage: a == s True - """ return self.__mul__(other) @@ -826,9 +813,7 @@ def restrict(self, subdomain, dest_map=None): subdomain of ``self._codomain``; if ``None``, the restriction of ``self.base_module().destination_map()`` to `V` is used - OUTPUT: - - - a :class:`AutomorphismField` representing the restriction + OUTPUT: a :class:`AutomorphismField` representing the restriction EXAMPLES: @@ -897,7 +882,6 @@ def restrict(self, subdomain, dest_map=None): sage: id.restrict(W)[eS_W,:] [1 0] [0 1] - """ if subdomain == self._domain: return self @@ -1003,7 +987,6 @@ class AutomorphismFieldParal(FreeModuleAutomorphism, TensorFieldParal): sage: inv is ~rot True - """ def __init__(self, vector_field_module, name=None, latex_name=None): r""" @@ -1038,7 +1021,6 @@ def __init__(self, vector_field_module, name=None, latex_name=None): [1 0] [0 1] sage: TestSuite(b).run() - """ FreeModuleAutomorphism.__init__(self, vector_field_module, name=name, latex_name=latex_name) @@ -1066,7 +1048,6 @@ def _repr_(self): sage: a # indirect doctest Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M - """ description = "Field of tangent-space " if self is self.parent().one(): @@ -1083,8 +1064,8 @@ def _del_derived(self, del_restrictions=True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the - restrictions of ``self`` to subdomains are deleted. + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the + restrictions of ``self`` to subdomains are deleted TESTS:: @@ -1092,7 +1073,6 @@ def _del_derived(self, del_restrictions=True): sage: X. = M.chart() sage: a = M.automorphism_field(name='a') sage: a._del_derived() - """ # Delete the derived quantities pertaining to the mother classes: FreeModuleAutomorphism._del_derived(self) @@ -1132,7 +1112,6 @@ def __call__(self, *arg): sage: s.display() a(z,v): U → ℝ (x, y) ↦ 2*x*y^2 + x - """ if len(arg) == 1: # the automorphism acting as such (map of a vector field to a @@ -1188,7 +1167,6 @@ def __invert__(self): sage: b is ~a True - """ from sage.matrix.constructor import matrix from sage.tensor.modules.comp import Components @@ -1262,9 +1240,7 @@ def restrict(self, subdomain, dest_map=None): ``self._codomain``; if ``None``, the restriction of ``self.base_module().destination_map()`` to `V` is used - OUTPUT: - - - a :class:`AutomorphismFieldParal` representing the restriction + OUTPUT: a :class:`AutomorphismFieldParal` representing the restriction EXAMPLES: @@ -1297,7 +1273,6 @@ def restrict(self, subdomain, dest_map=None): [0 1] sage: id.restrict(D) == D.tangent_identity_field() True - """ if subdomain == self._domain: return self @@ -1387,7 +1362,6 @@ def at(self, point): 2-dimensional differentiable manifold M sage: idp * ap == ap True - """ if point not in self._domain: raise TypeError("the {} is not in the domain of the {}".format( diff --git a/src/sage/manifolds/differentiable/automorphismfield_group.py b/src/sage/manifolds/differentiable/automorphismfield_group.py index 273deab226d..c6315670c9e 100644 --- a/src/sage/manifolds/differentiable/automorphismfield_group.py +++ b/src/sage/manifolds/differentiable/automorphismfield_group.py @@ -48,6 +48,7 @@ from sage.manifolds.differentiable.automorphismfield import (AutomorphismField, AutomorphismFieldParal) + class AutomorphismFieldGroup(UniqueRepresentation, Parent): r""" General linear group of the module of vector fields along a differentiable @@ -137,7 +138,6 @@ class AutomorphismFieldGroup(UniqueRepresentation, Parent): Id = ∂/∂x⊗dx + ∂/∂y⊗dy sage: e.display(eV) Id = ∂/∂u⊗du + ∂/∂v⊗dv - """ Element = AutomorphismField @@ -166,7 +166,6 @@ def __init__(self, vector_field_module): ``_test_elements`` does not pass due to the failure of ``_test_pickling`` in :class:`sage.manifolds.differentiable.tensorfield.TensorField`. - """ if not isinstance(vector_field_module, VectorFieldModule): raise TypeError("{} is not a module of vector fields".format( @@ -181,9 +180,7 @@ def _element_constructor_(self, comp=[], frame=None, name=None, r""" Construct a field of tangent-space automorphisms. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField` + OUTPUT: :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField` TESTS:: @@ -204,7 +201,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, differentiable manifold M sage: a.display(c_xy.frame()) a = (x^2 + 1) ∂/∂x⊗dx + (y^2 + 1) ∂/∂y⊗dy - """ if hasattr(comp, 'is_trivial_zero'): if (comp - 1).is_trivial_zero(): @@ -225,9 +221,7 @@ def _an_element_(self): r""" Construct some specific field of tangent-space automorphisms. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField` + OUTPUT: :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField` TESTS:: @@ -249,7 +243,6 @@ def _an_element_(self): 2 ∂/∂u⊗du + 2 ∂/∂v⊗dv sage: a == G.an_element() # indirect doctest True - """ resu = self.element_class(self._vmodule) for dom in resu.domain().subsets(): @@ -302,7 +295,6 @@ def one(self): sage: G.one().restrict(V)[:] [1 0] [0 1] - """ # Specific initializations for the field of identity maps: resu = self._element_constructor_(name='Id', latex_name=r'\mathrm{Id}') @@ -335,7 +327,6 @@ def _repr_(self): sage: G # indirect doctest General linear group of the Module X(M) of vector fields on the 2-dimensional differentiable manifold M - """ return "General linear group of the {}".format(self._vmodule) @@ -351,7 +342,6 @@ def _latex_(self): \mathrm{GL}\left( \mathfrak{X}\left(M\right) \right) sage: latex(G) # indirect doctest \mathrm{GL}\left( \mathfrak{X}\left(M\right) \right) - """ from sage.misc.latex import latex return r"\mathrm{GL}\left(" + latex(self._vmodule) + r"\right)" @@ -361,9 +351,7 @@ def base_module(self): Return the vector-field module of which ``self`` is the general linear group. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule` + OUTPUT: :class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule` EXAMPLES: @@ -386,7 +374,6 @@ def base_module(self): manifold M sage: G.base_module() is M.vector_field_module() True - """ return self._vmodule @@ -587,7 +574,6 @@ class AutomorphismFieldParalGroup(FreeModuleLinearGroup): TESTS:: sage: TestSuite(G).run() - """ Element = AutomorphismFieldParal @@ -606,7 +592,6 @@ def __init__(self, vector_field_module): General linear group of the Free module X(M) of vector fields on the 2-dimensional differentiable manifold M sage: TestSuite(G).run() - """ if not isinstance(vector_field_module, VectorFieldFreeModule): raise TypeError("{} is not a free module of vector fields".format( diff --git a/src/sage/manifolds/differentiable/bundle_connection.py b/src/sage/manifolds/differentiable/bundle_connection.py index c4ae9379aca..184e9641eeb 100644 --- a/src/sage/manifolds/differentiable/bundle_connection.py +++ b/src/sage/manifolds/differentiable/bundle_connection.py @@ -90,7 +90,7 @@ class BundleConnection(SageObject, Mutability): connection (1,1) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1,e_2)) = 0 - Now, we want to specify some non-zero entries:: + Now, we want to specify some nonzero entries:: sage: nab[e, 1, 2][:] = [x*z, y*z, z^2] sage: nab[e, 2, 1][:] = [x, x^2, x^3] @@ -235,7 +235,6 @@ class BundleConnection(SageObject, Mutability): ....: for k in E.irange())) sage: check # long time [True, True, True, True] - """ def __init__(self, vbundle, name, latex_name=None): @@ -258,7 +257,6 @@ def __init__(self, vbundle, name, latex_name=None): sage: nab[:] = 0 sage: nab.set_connection_form(1, 0)[:] = [x*z, y*z, z^2] sage: TestSuite(nab).run() - """ if not isinstance(vbundle, DifferentiableVectorBundle): raise TypeError("the first argument must be a differentiable " + @@ -293,7 +291,6 @@ def _repr_(self): 'Bundle connection nabla on the Differentiable real vector bundle E -> M of rank 3 over the base space 5-dimensional differentiable manifold M' - """ description = "Bundle connection" if self._name is not None: @@ -319,7 +316,6 @@ def _latex_(self): 'D' sage: latex(nab) # indirect doctest D - """ return self._latex_name @@ -333,7 +329,6 @@ def _init_derived(self): sage: E = M.vector_bundle(2, 'E') sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla') sage: nab._init_derived() - """ self._curvature_forms = {} # dict. of dict. of curvature forms # (key: local frame) @@ -349,7 +344,6 @@ def _del_derived(self): sage: E = M.vector_bundle(2, 'E') sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla') sage: nab._del_derived() - """ self._curvature_forms.clear() @@ -361,9 +355,7 @@ def __eq__(self, other): - ``other`` -- a bundle connection - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise TESTS:: @@ -387,7 +379,6 @@ def __eq__(self, other): sage: nab1[1, 0][:] = [y^2, y] sage: (nab1 == nab) and (nab == nab1) True - """ if other is self: return True @@ -441,7 +432,6 @@ def __ne__(self, other): sage: nab1[1, 0][:] = [y^2, y] sage: (nab1 != nab) or (nab != nab1) False - """ return not (self == other) @@ -464,7 +454,6 @@ def vector_bundle(self): sage: nab.vector_bundle() Differentiable real vector bundle E -> M of rank 2 over the base space 3-dimensional differentiable manifold M - """ return self._vbundle @@ -493,7 +482,6 @@ def _new_forms(self, frame): 1-form connection (2,2) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable manifold M] - """ dom = frame._domain forms_dict = {} @@ -562,7 +550,6 @@ def connection_forms(self, frame=None): 1-form connection (2,2) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1,e_2)) on the 3-dimensional differentiable manifold M] - """ if frame is None: smodule = self._vbundle.section_module(domain=self._domain) @@ -634,7 +621,6 @@ def connection_form(self, i, j, frame=None): sage: nab.connection_form(1, 0).display() connection (1,0) of bundle connection nabla w.r.t. Local frame (E|_M, (e_0,e_1)) = y^2 dx + y dy - """ return self.connection_forms(frame)[(i, j)] @@ -647,9 +633,7 @@ def __call__(self, v, s): - ``v`` -- a vector field `v` on the base space - ``s`` -- a local section `s` - OUTPUT: - - - local section `\nabla_v s` + OUTPUT: local section `\nabla_v s` TESTS:: @@ -667,7 +651,6 @@ def __call__(self, v, s): sage: nab.__call__(v, s) Section nabla_v(s) on the 2-dimensional differentiable manifold M with values in the real vector bundle E of rank 2 - """ from sage.manifolds.section import TrivialSection from sage.tensor.modules.format_utilities import format_unop_latex @@ -708,9 +691,7 @@ def _derive_trivial(self, v, s): - ``v`` -- a vector field `v` on the base space - ``s`` -- a local section `s` whose module is free - OUTPUT: - - - local section `\nabla_v s` + OUTPUT: local section `\nabla_v s` TESTS:: @@ -728,7 +709,6 @@ def _derive_trivial(self, v, s): sage: nab._derive_trivial(v, s) Section nabla_v(s) on the 2-dimensional differentiable manifold M with values in the real vector bundle E of rank 2 - """ vb = self._vbundle dom = s.domain() @@ -827,7 +807,6 @@ def add_connection_form(self, i, j, frame=None): (E|_M, (e_0,e_1)) = x^2 dx + x dy To delete them, use the method :meth:`set_connection_form` instead. - """ self._require_mutable() if frame is None: @@ -911,7 +890,6 @@ def set_connection_form(self, i, j, frame=None): the Local frame (E|_M, (f_0,f_1)) To keep them, use the method :meth:`add_connection_form` instead. - """ self._require_mutable() omega = self.add_connection_form(i, j, frame=frame) @@ -963,7 +941,6 @@ def del_other_forms(self, frame=None): ... ValueError: no basis could be found for computing the components in the Local frame (E|_M, (e_1,e_2)) - """ if frame is None: smodule = self._vbundle.section_module(domain=self._domain) @@ -1019,7 +996,6 @@ def curvature_form(self, i, j, frame=None): sage: curv.display() curvature (1,1) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1)) = dx∧dy - """ if frame is None: smodule = self._vbundle.section_module(domain=self._domain) @@ -1063,7 +1039,6 @@ def __hash__(self): sage: {nab: 1}[nab] 1 - """ self._require_immutable() if self._hash == -1: @@ -1121,7 +1096,6 @@ def __getitem__(self, args): 1-form connection (2,2) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable manifold M]] - """ # extract frame from first index: vb = self._vbundle @@ -1158,7 +1132,7 @@ def __getitem__(self, args): def __setitem__(self, args, value): r""" - Sets the components of ``self`` corresponding to the given indices. + Set the components of ``self`` corresponding to the given indices. INPUT: @@ -1194,7 +1168,6 @@ def __setitem__(self, args, value): sage: nab[e, 1, 2].display() connection (1,2) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1,e_2)) = x^2 dx + x dy - """ # extract frame from first index: vb = self._vbundle @@ -1282,7 +1255,7 @@ def display(self, frame=None, vector_frame=None, chart=None, - ``chart`` -- (default: ``None``) chart specifying the coordinate expression of the connection 1-forms; if ``None``, the default chart of the domain of ``frame`` is used - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero connection coefficients are displayed EXAMPLES: @@ -1345,7 +1318,6 @@ def display(self, frame=None, vector_frame=None, chart=None, (E|_M, (e_1,e_2)) = 0 connection (2,2) of bundle connection nabla w.r.t. Local frame (E|_M, (e_1,e_2)) = x^2 dx + y^2 dy + z^2 dz - """ vb = self._vbundle if frame is None: @@ -1428,7 +1400,6 @@ def copy(self, name, latex_name=None): (E|_M, (e_1,e_2)) = dx + x dy + y^3*z dz connection (2,1) of bundle connection nablo w.r.t. Local frame (E|_M, (e_1,e_2)) = dx + 2 dy + 3 dz - """ copy = type(self)(self._vbundle, name, latex_name=latex_name) for frame, form_dict in self._connection_forms.items(): @@ -1467,7 +1438,6 @@ def set_immutable(self): Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead - """ for form_dict in self._connection_forms.values(): for form in form_dict.values(): diff --git a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py index 86ba9eb3c6b..51f32ffb4b8 100644 --- a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py +++ b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py @@ -344,7 +344,7 @@ def __init__(self, parent, x, name=None, latex_name=None): self._latex_name = self._name else: self._latex_name = latex_name - self._mixed_forms = {} # dict. of characteristic forms of `self` + self._mixed_forms = {} # dict. of characteristic forms of self # (key: bundle connection) super().__init__(parent, x) @@ -502,9 +502,9 @@ def get_form(self, nab): # set names of components from sage.arith.misc import gcd - step = gcd(parent._degrees) # step size of (possibly) non-zero + step = gcd(parent._degrees) # step size of (possibly) nonzero for i in range(dom._dim // step + 1): - # enumerate (possibly) non-zero components + # enumerate (possibly) nonzero components comp_name = name + f'_{i}' + append_name comp_latex_name = latex_name + r'_{' + str(i) + '}' comp_latex_name += append_latex_name @@ -1065,13 +1065,11 @@ def multiplicative_sequence(q, n=None): INPUT: - - ``q`` -- polynomial to turn into its multiplicative sequence. + - ``q`` -- polynomial to turn into its multiplicative sequence - ``n`` -- (default: ``None``) the highest order `n` of the sequence; - if ``None``, the order of ``q`` is assumed. + if ``None``, the order of ``q`` is assumed - OUTPUT: - - - A symmetric polynomial representing the multiplicative sequence. + OUTPUT: a symmetric polynomial representing the multiplicative sequence EXAMPLES:: @@ -1122,14 +1120,12 @@ def additive_sequence(q, k, n=None): INPUT: - - ``q`` -- polynomial to turn into its additive sequence. + - ``q`` -- polynomial to turn into its additive sequence - ``k`` -- maximal index `k` of the sum - ``n`` -- (default: ``None``) the highest order of the sequence `n`; - if ``None``, the order of ``q`` is assumed. - - OUTPUT: + if ``None``, the order of ``q`` is assumed - - A symmetric polynomial representing the additive sequence. + OUTPUT: a symmetric polynomial representing the additive sequence EXAMPLES:: @@ -1170,7 +1166,7 @@ def fast_wedge_power(form, n): INPUT: - ``form`` -- a differential form - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -1190,7 +1186,7 @@ def fast_wedge_power(form, n): if n == 0: return form._domain._one_scalar_field elif n < 0: - raise ValueError("'n' must be non-negative") + raise ValueError("'n' must be nonnegative") val = form while not (n & 1): val = val.wedge(val) @@ -1284,9 +1280,7 @@ def get_local(self, cmat): Abstract method to get the local forms of the generators w.r.t. a given curvature form matrix ``cmat``. - OUTPUT: - - - a list containing the generator's local characteristic forms + OUTPUT: list containing the generator's local characteristic forms ALGORITHM: @@ -1481,9 +1475,7 @@ def get_local(self, cmat): r""" Return the local Pontryagin forms w.r.t. a given curvature form matrix. - OUTPUT: - - - a list containing the local characteristic Pontryagin forms + OUTPUT: list containing the local characteristic Pontryagin forms ALGORITHM:: @@ -1566,11 +1558,9 @@ def get(self, nab): INPUT: - - a metric connection `\nabla` - - OUTPUT: + - ``nab`` -- a metric connection `\nabla` - - a list containing the global characteristic Euler form + OUTPUT: list containing the global characteristic Euler form ALGORITHM: @@ -1654,9 +1644,7 @@ def get_local(self, cmat): `\left(\frac{1}{2 \pi}\right)^{\frac{k}{2}}`, where `k` is the dimension of the curvature matrix. - OUTPUT: - - - a list containing the normalized Pfaffian of a given curvature form + OUTPUT: list containing the normalized Pfaffian of a given curvature form .. NOTE:: diff --git a/src/sage/manifolds/differentiable/chart.py b/src/sage/manifolds/differentiable/chart.py index cbdad556734..bcfa37dc237 100644 --- a/src/sage/manifolds/differentiable/chart.py +++ b/src/sage/manifolds/differentiable/chart.py @@ -75,16 +75,15 @@ class DiffChart(Chart): method for computations involving coordinates of the chart; must be one of - - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - - ``'sympy'``: SymPy - - ``None``: the default of - :class:`~sage.manifolds.calculus_method.CalculusMethod` will be - used + - ``'SR'`` -- Sage's default symbolic engine (Symbolic Ring) + - ``'sympy'`` -- SymPy + - ``None`` -- the default of :class:`~sage.manifolds.calculus_method.CalculusMethod` + will be used - ``names`` -- (default: ``None``) unused argument, except if ``coordinates`` is not provided; it must then be a tuple containing the coordinate symbols (this is guaranteed if the shortcut operator ``<,>`` is used). - - ``coord_restrictions``: Additional restrictions on the coordinates. + - ``coord_restrictions`` -- additional restrictions on the coordinates. A restriction can be any symbolic equality or inequality involving the coordinates, such as ``x > y`` or ``x^2 + y^2 != 0``. The items of the list (or set or frozenset) ``coord_restrictions`` are combined @@ -273,7 +272,6 @@ class DiffChart(Chart): :class:`~sage.manifolds.differentiable.chart.RealDiffChart` for charts on differentiable manifolds over `\RR`. - """ def __init__(self, domain, coordinates, calc_method=None, periods=None, coord_restrictions=None): r""" @@ -290,7 +288,6 @@ def __init__(self, domain, coordinates, calc_method=None, periods=None, coord_re sage: assumptions() # no assumptions on x,y set by X._init_coordinates [] sage: TestSuite(X).run() - """ super().__init__(domain, coordinates, calc_method=calc_method, periods=periods, coord_restrictions=coord_restrictions) @@ -405,7 +402,6 @@ def transition_map(self, other, transformations, intersection_name=None, sage: M.atlas() [Chart (R^2, (x, y)), Chart (U, (r, phi)), Chart (U, (x, y))] - """ dom1 = self.domain() dom2 = other.domain() @@ -462,7 +458,6 @@ def frame(self): sage: ey(M.scalar_field(y)).display() 1: M → ℝ (x, y) ↦ 1 - """ return self._frame @@ -511,7 +506,6 @@ def coframe(self): sage: dy(ey).display() dy(∂/∂y): M → ℝ (x, y) ↦ 1 - """ return self._coframe @@ -562,7 +556,6 @@ def restrict(self, subset, restrictions=None): sage: B = M.open_subset('B') sage: X_B = X.restrict(B, abs(z1)^2 + abs(z2)^2 < 1); X_B Chart (B, (z1, z2)) - """ if subset == self.domain(): return self @@ -600,9 +593,7 @@ def symbolic_velocities(self, left='D', right=None): - ``right`` -- (default: ``None``) string to concatenate to the right of each coordinate functions of the chart - OUTPUT: - - - a list of symbolic expressions with the desired names + OUTPUT: list of symbolic expressions with the desired names EXAMPLES: @@ -613,25 +604,24 @@ def symbolic_velocities(self, left='D', right=None): sage: cart. = R3.chart() sage: D = cart.symbolic_velocities(); D [DX, DY, DZ] - sage: D = cart.symbolic_velocities(left='d', right="/dt"); D + sage: D = cart.symbolic_velocities(left='d', right='/dt'); D Traceback (most recent call last): ... ValueError: The name "dX/dt" is not a valid Python identifier. - sage: D = cart.symbolic_velocities(left='d', right="_dt"); D + sage: D = cart.symbolic_velocities(left='d', right='_dt'); D [dX_dt, dY_dt, dZ_dt] sage: D = cart.symbolic_velocities(left='', right="'"); D Traceback (most recent call last): ... ValueError: The name "X'" is not a valid Python identifier. - sage: D = cart.symbolic_velocities(left='', right="_dot"); D + sage: D = cart.symbolic_velocities(left='', right='_dot'); D [X_dot, Y_dot, Z_dot] sage: R. = manifolds.RealLine() sage: canon_chart = R.default_chart() sage: D = canon_chart.symbolic_velocities() ; D [Dt] - """ from sage.symbolic.ring import var @@ -728,16 +718,15 @@ class RealDiffChart(DiffChart, RealChart): method for computations involving coordinates of the chart; must be one of - - ``'SR'``: Sage's default symbolic engine (Symbolic Ring) - - ``'sympy'``: SymPy - - ``None``: the default of - :class:`~sage.manifolds.calculus_method.CalculusMethod` will be - used + - ``'SR'`` -- Sage's default symbolic engine (Symbolic Ring) + - ``'sympy'`` -- SymPy + - ``None`` -- the default of :class:`~sage.manifolds.calculus_method.CalculusMethod` + will be used - ``names`` -- (default: ``None``) unused argument, except if ``coordinates`` is not provided; it must then be a tuple containing the coordinate symbols (this is guaranteed if the shortcut operator ``<,>`` is used). - - ``coord_restrictions``: Additional restrictions on the coordinates. + - ``coord_restrictions`` -- additional restrictions on the coordinates. A restriction can be any symbolic equality or inequality involving the coordinates, such as ``x > y`` or ``x^2 + y^2 != 0``. The items of the list (or set or frozenset) ``coord_restrictions`` are combined @@ -972,7 +961,6 @@ class RealDiffChart(DiffChart, RealChart): Chart grids can be drawn in 2D or 3D graphics thanks to the method :meth:`~sage.manifolds.chart.RealChart.plot`. - """ def __init__(self, domain, coordinates, calc_method=None, bounds=None, periods=None, coord_restrictions=None): @@ -991,7 +979,6 @@ def __init__(self, domain, coordinates, calc_method=None, sage: assumptions() # assumptions set in X._init_coordinates [x is real, y is real] sage: TestSuite(X).run() - """ RealChart.__init__(self, domain, coordinates, calc_method=calc_method, bounds=bounds, periods=periods, coord_restrictions=coord_restrictions) @@ -1061,7 +1048,6 @@ def restrict(self, subset, restrictions=None): sage: a = M.point((3/2,0)) sage: a in A True - """ if subset == self.domain(): return self @@ -1083,6 +1069,7 @@ def restrict(self, subset, restrictions=None): #****************************************************************************** + class DiffCoordChange(CoordChange): r""" Transition map between two charts of a differentiable manifold. @@ -1129,7 +1116,6 @@ class DiffCoordChange(CoordChange): sage: X_to_Y.display() u = x + y v = x - y - """ def __init__(self, chart1, chart2, *transformations): r""" @@ -1150,7 +1136,6 @@ def __init__(self, chart1, chart2, *transformations): .. TODO:: fix _test_pickling - """ CoordChange.__init__(self, chart1, chart2, *transformations) # Jacobian matrix: @@ -1217,7 +1202,6 @@ def jacobian(self): sage: parent(X_to_Y.jacobian()[0,0]) Ring of chart functions on Chart (M, (x, y)) - """ return self._jacobian # has been computed in __init__ @@ -1252,6 +1236,5 @@ def jacobian_det(self): sage: parent(X_to_Y.jacobian_det()) Ring of chart functions on Chart (M, (x, y)) - """ return self._transf.jacobian_det() diff --git a/src/sage/manifolds/differentiable/curve.py b/src/sage/manifolds/differentiable/curve.py index 05e26c17023..e28e44b8adb 100644 --- a/src/sage/manifolds/differentiable/curve.py +++ b/src/sage/manifolds/differentiable/curve.py @@ -37,6 +37,7 @@ from sage.manifolds.point import ManifoldPoint from sage.manifolds.differentiable.diff_map import DiffMap + class DifferentiableCurve(DiffMap): r""" Curve in a differentiable manifold. @@ -63,10 +64,10 @@ class DifferentiableCurve(DiffMap): - ``name`` -- (default: ``None``) string; symbol given to the curve - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the curve; if none is provided, ``name`` will be used - - ``is_isomorphism`` -- (default: ``False``) determines whether the + - ``is_isomorphism`` -- boolean (default: ``False``); determines whether the constructed object is a diffeomorphism; if set to ``True``, then `M` must have dimension one - - ``is_identity`` -- (default: ``False``) determines whether the + - ``is_identity`` -- boolean (default: ``False``); determines whether the constructed object is the identity map; if set to ``True``, then `M` must be the interval `I` @@ -344,7 +345,6 @@ class DifferentiableCurve(DiffMap): sage: tau = Np[FS, 3] sage: tau 1/9*sqrt(5) - """ def __init__(self, parent, coord_expression=None, name=None, latex_name=None, is_isomorphism=False, is_identity=False): @@ -366,7 +366,6 @@ def __init__(self, parent, coord_expression=None, name=None, sage: c = Hom(I,I)({}, is_identity=True) ; c Identity map Id_(0, 2*pi) of the Real interval (0, 2*pi) sage: TestSuite(c).run() - """ if coord_expression is None: coord_functions = None @@ -400,7 +399,6 @@ def _repr_(self): Curve in the 2-dimensional differentiable manifold M sage: M.curve([cos(t), sin(2*t)], (t, 0, 2*pi), name='c') Curve c in the 2-dimensional differentiable manifold M - """ if self._codomain._dim == 1: return DiffMap._repr_(self) @@ -435,7 +433,6 @@ def __reduce__(self): sage: loads(dumps(c)) Curve in the 2-dimensional differentiable manifold M - """ return (type(self), (self.parent(), None, self._name, self._latex_name, self._is_isomorphism, self._is_identity)) @@ -449,9 +446,7 @@ def coord_expr(self, chart=None): - ``chart`` -- (default: ``None``) chart on the curve's codomain; if ``None``, the codomain's default chart is assumed - OUTPUT: - - - symbolic expression representing the curve in the above chart + OUTPUT: symbolic expression representing the curve in the above chart EXAMPLES: @@ -490,7 +485,6 @@ def coord_expr(self, chart=None): sage: c = U.curve({c_spher: (2*(1+cos(t)), t)}, (t, 0, 2*pi), name='c') sage: c.coord_expr(c_cart) (2*cos(t)^2 + 2*cos(t), 2*(cos(t) + 1)*sin(t)) - """ return self.expr(chart1=self._domain.canonical_chart(), chart2=chart) @@ -523,7 +517,6 @@ def __call__(self, t, simplify=True): Point c(t) on the 2-dimensional differentiable manifold M sage: c(t).coord(X) (cos(t), sin(t)) - """ # Case of a point in the domain: if isinstance(t, ManifoldPoint): @@ -643,7 +636,6 @@ def tangent_vector_field(self, name=None, latex_name=None): mapped into the 2-dimensional differentiable manifold M sage: vc.display(c_spher.frame().along(c.restrict(R,A))) c' = -1/5*e^(1/10*t)/(e^(1/5*t) + 1) ∂/∂th + ∂/∂ph - """ vmodule = self._domain.vector_field_module(dest_map=self) if latex_name is None: @@ -730,16 +722,16 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, prange=None, values of the parameters that may appear in the coordinate expression of the curve - - ``color`` -- (default: 'red') color of the drawn curve + - ``color`` -- (default: ``'red'``) color of the drawn curve - - ``style`` -- (default: '-') color of the drawn curve; NB: ``style`` + - ``style`` -- (default: ``'-'``) color of the drawn curve; NB: ``style`` is effective only for 2D plots - ``thickness`` -- (default: 1) thickness of the drawn curve - ``plot_points`` -- (default: 75) number of points to plot the curve - - ``label_axes`` -- (default: ``True``) boolean determining whether the + - ``label_axes`` -- boolean (default: ``True``); determining whether the labels of the coordinate axes of ``chart`` shall be added to the graph; can be set to ``False`` if the graph is 3D and must be superposed with another graph. @@ -878,7 +870,6 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, prange=None, c = R2.curve([a*cos(t) + b, a*sin(t)], (t, 0, 2*pi), name='c') g = c.plot(parameters={a: 2, b: -3}, aspect_ratio=1) sphinx_plot(g) - """ from sage.rings.infinity import Infinity from sage.misc.functional import numerical_approx @@ -1003,7 +994,6 @@ def _graphics(self, plot_curve, ambient_coords, thickness=1, sage: l = [r'$'+latex(x)+r'$', r'$'+latex(y)+r'$'] sage: graph._extra_kwds['axes_labels'] == l True - """ from sage.plot.graphics import Graphics from sage.plot.line import line diff --git a/src/sage/manifolds/differentiable/de_rham_cohomology.py b/src/sage/manifolds/differentiable/de_rham_cohomology.py index 1e38b50f753..9bc766f5a78 100644 --- a/src/sage/manifolds/differentiable/de_rham_cohomology.py +++ b/src/sage/manifolds/differentiable/de_rham_cohomology.py @@ -53,6 +53,7 @@ from .characteristic_cohomology_class import (CharacteristicCohomologyClassRing, CharacteristicCohomologyClassRingElement) + class DeRhamCohomologyClass(AlgebraElement): r""" Define a cohomology class in the de Rham cohomology ring. @@ -95,7 +96,6 @@ class DeRhamCohomologyClass(AlgebraElement): Traceback (most recent call last): ... NotImplementedError: comparison via exact forms is currently not supported - """ def __init__(self, parent, representative): r""" @@ -110,7 +110,6 @@ def __init__(self, parent, representative): sage: omega = M.diff_form(1, [1,1], name='omega', latex_name=r'\omega') sage: u = H(omega) sage: TestSuite(u).run(skip=['_test_eq', '_test_nonzero_equal']) # equality not fully supported yet - """ super().__init__(parent=parent) self._representative = representative @@ -128,7 +127,6 @@ def _repr_(self): [one] sage: H.an_element()._repr_() '[one]' - """ name = self._representative._name if name is None: @@ -151,7 +149,6 @@ def _latex_(self): \left[\omega\right] sage: u._latex_() '\\left[\\omega\\right]' - """ latex_name = self._representative._latex_name if latex_name is None: @@ -178,7 +175,6 @@ def representative(self): sage: u.representative() Mixed differential form omega on the 2-dimensional differentiable manifold M - """ return self._representative @@ -198,7 +194,6 @@ def _add_(self, other): sage: eta = M.diff_form(1, [1,-1], name='eta') sage: H(omega) + H(eta) [omega+eta] - """ return self.parent()(self.representative() + other.representative()) @@ -220,7 +215,6 @@ def cup(self, other): sage: eta = M.diff_form(1, [1,-1], name='eta') sage: H(omega).cup(H(eta)) [omega∧eta] - """ return self * other @@ -238,7 +232,6 @@ def _mul_(self, other): sage: eta = M.diff_form(1, [1,-1], name='eta') sage: H(omega) * H(eta) [omega∧eta] - """ return self.parent()(self.representative().wedge(other.representative())) @@ -255,7 +248,6 @@ def _rmul_(self, scalar): sage: omega = M.diff_form(1, [1,1], name='omega') sage: 1/2*H(omega) [1/2∧omega] - """ return self.parent(scalar * self.representative()) @@ -273,7 +265,6 @@ def _sub_(self, other): sage: eta = M.diff_form(1, [1,-1], name='eta') sage: H(omega) - H(eta) [omega-eta] - """ return self.parent()(self.representative() - other.representative()) @@ -300,7 +291,6 @@ def __eq__(self, other): Traceback (most recent call last): ... NotImplementedError: comparison via exact forms is currently not supported - """ if self is other: return True @@ -309,6 +299,7 @@ def __eq__(self, other): return True raise NotImplementedError('comparison via exact forms is currently not supported') + class DeRhamCohomologyRing(Parent, UniqueRepresentation): r""" The de Rham cohomology ring of a de Rham complex. @@ -360,7 +351,6 @@ class DeRhamCohomologyRing(Parent, UniqueRepresentation): [zero] sage: H.one() [one] - """ def __init__(self, de_rham_complex): r""" @@ -378,7 +368,6 @@ def __init__(self, de_rham_complex): ....: '_test_elements_eq_symmetric', ....: '_test_elements_eq_transitive', ....: '_test_elements_neq']) # equality not fully supported yet - """ base_field = de_rham_complex.base_ring() Parent.__init__(self, base=base_field, category=Algebras(base_field)) @@ -411,7 +400,6 @@ def _element_constructor_(self, x): ... ValueError: Mixed differential form omega on the 2-dimensional differentiable manifold M must be a closed form - """ if isinstance(x, CharacteristicCohomologyClassRingElement): x = x.representative() @@ -445,7 +433,6 @@ def _coerce_map_from_(self, other): TM over the 4-dimensional differentiable manifold M sage: H.has_coerce_map_from(C) True - """ if isinstance(other, CharacteristicCohomologyClassRing): # TODO: we need to be careful if manifolds have boundary! @@ -463,7 +450,6 @@ def _repr_(self): sage: H = C.cohomology(); H De Rham cohomology ring on the 2-dimensional differentiable manifold M - """ desc = "De Rham cohomology ring " if self._module._dest_map is self._manifold.identity_map(): @@ -491,7 +477,6 @@ def _latex_(self): 'H^*_{\\mathrm{dR}}\\left(\\mathcal{M}\\right)' sage: latex(H) # indirect doctest H^*_{\mathrm{dR}}\left(\mathcal{M}\right) - """ latex_name = r"H^*_{\mathrm{dR}}\left(" + self._manifold._latex_name if self._module._dest_map is not self._manifold.identity_map(): @@ -513,7 +498,6 @@ def _an_element_(self): sage: H = C.cohomology() sage: H.an_element() [one] - """ return self.one() @@ -532,7 +516,6 @@ def zero(self): sage: H.zero().representative() Mixed differential form zero on the 2-dimensional differentiable manifold M - """ return self.element_class(self, self._module.zero()) @@ -551,6 +534,5 @@ def one(self): sage: H.one().representative() Mixed differential form one on the 2-dimensional differentiable manifold M - """ return self.element_class(self, self._module.one()) diff --git a/src/sage/manifolds/differentiable/degenerate.py b/src/sage/manifolds/differentiable/degenerate.py index 82de8c39d74..b34fefc3a89 100644 --- a/src/sage/manifolds/differentiable/degenerate.py +++ b/src/sage/manifolds/differentiable/degenerate.py @@ -22,6 +22,7 @@ ############################################################################### + class DegenerateManifold(DifferentiableManifold): r""" @@ -122,7 +123,6 @@ def __init__(self, n, name, metric_name=None, signature=None, sage: M.metric() degenerate metric g on the 3-dimensional degenerate_metric manifold M sage: TestSuite(M).run() - """ if base_manifold and not isinstance(base_manifold, DegenerateManifold): raise TypeError("the argument 'base_manifold' must be a " + @@ -249,7 +249,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` sage: M.metric('g') is M.metric() True - """ if signature is None: signature = self._metric_signature @@ -287,7 +286,7 @@ def open_subset(self, name, latex_name=None, coord_def={}): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none is provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -337,7 +336,6 @@ def open_subset(self, name, latex_name=None, coord_def={}): g = -dx⊗dx + dy⊗dy sage: gV is g.restrict(V) True - """ resu = DegenerateManifold(self._dim, name, metric_name=self._metric_name, @@ -373,6 +371,7 @@ def open_subset(self, name, latex_name=None, coord_def={}): from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.manifolds.differentiable.tensorfield import TensorField + class TangentTensor(TensorFieldParal): r""" Let ``S`` be a lightlike submanifold embedded in a pseudo-Riemannian @@ -391,7 +390,7 @@ class TangentTensor(TensorFieldParal): Section of the lightcone of the Minkowski space with a hyperplane passing through the origin:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -427,14 +426,13 @@ class TangentTensor(TensorFieldParal): sqrt(u^2 + v^2) ∂/∂t sage: T2(xi.along(Phi)).display() sqrt(u^2 + v^2) ∂/∂t - """ def __init__(self, tensor, embedding, screen=None): r""" TESTS:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -456,7 +454,6 @@ def __init__(self, tensor, embedding, screen=None): Tensor field of type (1,1) along the degenerate hypersurface S embedded in 4-dimensional differentiable manifold M with values on the 4-dimensional Lorentzian manifold M - """ if not isinstance(tensor, TensorField): raise TypeError("the second argument must be a tensor field") @@ -487,7 +484,7 @@ def __call__(self, *args): TESTS:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -509,7 +506,6 @@ def __call__(self, *args): Vector field along the degenerate hypersurface S embedded in 4-dimensional differentiable manifold M with values on the 4-dimensional Lorentzian manifold M - """ for vector in args: try: @@ -534,7 +530,7 @@ def extension(self): Section of the lightcone of the Minkowski space with a hyperplane passing through the origin:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -557,6 +553,5 @@ def extension(self): False sage: T3 is T1 True - """ return self._tensor diff --git a/src/sage/manifolds/differentiable/degenerate_submanifold.py b/src/sage/manifolds/differentiable/degenerate_submanifold.py index 0a146853e22..a119fb57802 100644 --- a/src/sage/manifolds/differentiable/degenerate_submanifold.py +++ b/src/sage/manifolds/differentiable/degenerate_submanifold.py @@ -59,7 +59,7 @@ being `m` the inertial mass of the star. It can be seen as an open ball in a Lorentzian manifold structure on `\RR^4`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X_M. = \ ....: M.chart(r"t r:(0,oo) th:(0,pi):\theta ph:(0,2*pi):\phi") sage: var('m'); assume(m>0) @@ -77,7 +77,7 @@ A `2`-dimensional degenerate submanifold of a Lorentzian manifold:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: S @@ -172,9 +172,10 @@ if TYPE_CHECKING: from sage.manifolds.differentiable.metric import DegenerateMetric + class DegenerateSubmanifold(DegenerateManifold, DifferentiableSubmanifold): r""" - Degenerate submanifolds + Degenerate submanifolds. An *embedded (resp. immersed) degenerate submanifold of a proper pseudo-Riemannian manifold* `(M,g)` is an embedded (resp. immersed) @@ -223,7 +224,6 @@ class DegenerateSubmanifold(DegenerateManifold, DifferentiableSubmanifold): :mod:`~sage.manifolds.manifold` and :mod:`~sage.manifolds.differentiable.differentiable_submanifold` - """ def __init__(self, n, name, ambient=None, metric_name=None, signature=None, base_manifold=None, diff_degree=infinity, latex_name=None, @@ -236,12 +236,11 @@ def __init__(self, n, name, ambient=None, metric_name=None, signature=None, A `2`-dimensional degenerate submanifold of a Lorentzian manifold:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: S 2-dimensional degenerate submanifold S embedded in 4-dimensional differentiable manifold M - """ DegenerateManifold.__init__(self, n, name=name, metric_name=metric_name, @@ -295,12 +294,11 @@ def _repr_(self): A `2`-dimensional degenerate submanifold of a Lorentzian manifold:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: S.__repr__() '2-dimensional degenerate submanifold S embedded in 4-dimensional differentiable manifold M' - """ if self._ambient is None: return super(DegenerateManifold, self).__repr__() @@ -319,15 +317,13 @@ def ambient_metric(self): Return the metric of the ambient manifold. The submanifold has to be embedded - OUTPUT: - - - the metric of the ambient manifold + OUTPUT: the metric of the ambient manifold EXAMPLES: The lightcone of the 3D Minkowski space:: - sage: M = Manifold(3, 'M', structure="Lorentzian") + sage: M = Manifold(3, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -338,7 +334,6 @@ def ambient_metric(self): sage: S.set_immersion(Phi, inverse=Phi_inv); S.declare_embedding() sage: S.ambient_metric() Lorentzian metric g on the 3-dimensional Lorentzian manifold M - """ if self._ambient_metric is None: if not self._embedded or not isinstance(self._ambient, @@ -350,7 +345,7 @@ def ambient_metric(self): def default_screen(self): r""" - Return the default screen distribution + Return the default screen distribution. OUTPUT: @@ -361,7 +356,7 @@ def default_screen(self): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -380,7 +375,6 @@ def default_screen(self): screen distribution Sc along the degenerate hypersurface S embedded in 4-dimensional differentiable manifold M mapped into the 4-dimensional Lorentzian manifold M - """ return self._default_screen @@ -397,7 +391,7 @@ def list_of_screens(self): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -416,7 +410,6 @@ def list_of_screens(self): {'Sc': screen distribution Sc along the degenerate hypersurface S embedded in 4-dimensional differentiable manifold M mapped into the 4-dimensional Lorentzian manifold M} - """ return self._screens @@ -446,7 +439,7 @@ def set_transverse(self, rigging=None, normal=None): The lightcone of the 3-dimensional Minkowski space `\RR^3_1`:: - sage: M = Manifold(3, 'M', structure="Lorentzian") + sage: M = Manifold(3, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -458,15 +451,14 @@ def set_transverse(self, rigging=None, normal=None): sage: g = M.metric() sage: g[0,0], g[1,1], g[2,2] = -1,1,1 sage: S.set_transverse(rigging=t) - """ if isinstance(rigging, (list, tuple)): - rigging = [elt for elt in rigging] + rigging = list(rigging) else: if rigging is not None: rigging = [rigging] if isinstance(normal, (list, tuple)): - normal = [elt for elt in normal] + normal = list(normal) else: if normal is not None: normal = [normal] @@ -529,7 +521,7 @@ def screen(self, name, screen, rad, latex_name=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -549,11 +541,11 @@ def screen(self, name, screen, rad, latex_name=None): Lorentzian manifold M """ if isinstance(screen, (list, tuple)): - screen = [elt for elt in screen] + screen = list(screen) else: screen = [screen] if isinstance(rad, (list, tuple)): - rad = [elt for elt in rad] + rad = list(rad) else: rad = [rad] if name in self._screens: @@ -608,7 +600,7 @@ def induced_metric(self) -> DegenerateMetric: Section of the lightcone of the Minkowski space with a hyperplane passing through the origin:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -622,7 +614,6 @@ def induced_metric(self) -> DegenerateMetric: sage: h = S.induced_metric(); h # long time degenerate metric gamma on the 2-dimensional degenerate submanifold S embedded in 4-dimensional differentiable manifold M - """ if self._induced_metric is None or self._induced_metric._components == {}: self._induced_metric = self.metric() @@ -647,7 +638,7 @@ def first_fundamental_form(self): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -663,7 +654,6 @@ def first_fundamental_form(self): sage: U = M.vector_field(); U[2] = 1; V = M.vector_field(); V[3] = 1 sage: Sc = S.screen('Sc', (U,V), xi); # long time sage: h = S.first_fundamental_form() # long time - """ if self._first_fundamental_form is None: g = self.ambient_metric() @@ -705,7 +695,7 @@ def _ambient_decomposition(self, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -726,7 +716,6 @@ def _ambient_decomposition(self, screen=None): [Vector field on the 4-dimensional Lorentzian manifold M], (), [Vector field N on the 4-dimensional Lorentzian manifold M]] - """ try: normal = self._transverse['normal'] @@ -768,15 +757,13 @@ def _adapted_frame_(self, screen=None): :class:`~sage.manifolds.differentiable.degenerate_submanifold.Screen`; if ``None`` default screen is used. - OUTPUT: - - - a frame on the ambient manifold + OUTPUT: a frame on the ambient manifold EXAMPLES: A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -792,7 +779,6 @@ def _adapted_frame_(self, screen=None): sage: U = M.vector_field(); U[2] = 1; V = M.vector_field(); V[3] = 1 sage: Sc = S.screen('Sc', (U,V), xi); # long time sage: T = S._adapted_frame_(); # long time - """ if screen is None: @@ -862,15 +848,13 @@ def adapted_frame(self, screen=None): :class:`~sage.manifolds.differentiable.degenerate_submanifold.Screen`. if ``None`` default screen is used. - OUTPUT: - - - a frame on the ambient manifold along the submanifold + OUTPUT: a frame on the ambient manifold along the submanifold EXAMPLES: A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -888,7 +872,6 @@ def adapted_frame(self, screen=None): sage: T = S.adapted_frame(); T # long time Vector frame (S, (vv_0,vv_1,vv_2,vv_3)) with values on the 4-dimensional Lorentzian manifold M - """ e = self._adapted_frame_(screen).along(self.immersion()) b = e.dual_basis() @@ -937,7 +920,7 @@ def second_fundamental_form(self, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -955,7 +938,6 @@ def second_fundamental_form(self, screen=None): sage: B = S.second_fundamental_form(); # long time sage: B.display() # long time B = 0 - """ if self._ambient._dim-self._dim != 1: raise ValueError("'second_fundamental_form' is defined" + @@ -999,7 +981,7 @@ def projection(self, tensor, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1015,7 +997,6 @@ def projection(self, tensor, screen=None): sage: U = M.vector_field(); U[2] = 1; V = M.vector_field(); V[3] = 1 sage: Sc = S.screen('Sc', (U,V), xi); # long time sage: U1 = S.projection(U) # long time - """ if tensor.tensor_type()[0] != 1: raise NotImplementedError("``projection`` is implemented only for " @@ -1042,7 +1023,7 @@ def screen_projection(self, tensor, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1058,7 +1039,6 @@ def screen_projection(self, tensor, screen=None): sage: U = M.vector_field(); U[2] = 1; V = M.vector_field(); V[3] = 1 sage: Sc = S.screen('Sc', (U,V), xi); # long time sage: U1 = S.screen_projection(U); # long time - """ if tensor.tensor_type()[0] != 1: raise NotImplementedError("``projection`` is implemented only for " + @@ -1108,7 +1088,7 @@ def weingarten_map(self, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1127,7 +1107,6 @@ def weingarten_map(self, screen=None): sage: W = S.weingarten_map(); # long time sage: W.display() # long time nabla_g(xi)|X(S) = 0 - """ im = self.immersion() @@ -1165,7 +1144,7 @@ def shape_operator(self, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1184,7 +1163,6 @@ def shape_operator(self, screen=None): sage: SO = S.shape_operator(); # long time sage: SO.display() # long time A^* = 0 - """ if screen is None: screen = self.default_screen() @@ -1214,15 +1192,13 @@ def gauss_curvature(self, screen=None): :class:`~sage.manifolds.differentiable.degenerate_submanifold.Screen`. If ``None`` the default screen is used. - OUTPUT: - - - a scalar function on ``self`` + OUTPUT: a scalar function on ``self`` EXAMPLES: A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1241,7 +1217,6 @@ def gauss_curvature(self, screen=None): sage: K.display() # long time S → ℝ (u, v, w) ↦ 0 - """ if self._ambient._dim-self._dim != 1: raise ValueError("'gauss_curvature' is defined" @@ -1277,7 +1252,7 @@ def principal_directions(self, screen=None): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1295,7 +1270,6 @@ def principal_directions(self, screen=None): sage: PD = S.principal_directions() # long time sage: PD[2][0].display(T) # long time e_2 = xi - """ if self._codim != 1: raise ValueError("'principal directions' is defined" + @@ -1315,7 +1289,7 @@ def principal_directions(self, screen=None): for eigen_vector in eigen_space[1]: v = self._ambient.vector_field(name="e_{}".format(next(counter)) ).along(self.immersion()) - v[frame, :] = [elt for elt in eigen_vector] + [0] + v[frame, :] = list(eigen_vector) + [0] res.append((TangentTensor(v, self.immersion()), self.scalar_field( {chart: eigen_space[0] for chart in self.top_charts()}))) #res[-1][0].set_name("e_{}".format(next(counter))) @@ -1334,15 +1308,13 @@ def mean_curvature(self, screen=None): :class:`~sage.manifolds.differentiable.degenerate_submanifold.Screen`. If ``None`` the default screen is used. - OUTPUT: - - - the mean curvature, as a scalar field on the submanifold + OUTPUT: the mean curvature, as a scalar field on the submanifold EXAMPLES: A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1363,7 +1335,6 @@ def mean_curvature(self, screen=None): sage: m.display() # long time S → ℝ (u, v, w) ↦ 0 - """ if self._codim != 1: raise ValueError("'mean_curvature' is defined" + @@ -1395,7 +1366,7 @@ def is_tangent(self, v): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1415,7 +1386,6 @@ def is_tangent(self, v): True sage: S.is_tangent(v.along(Phi)) # long time False - """ g = self.ambient_metric() im = self.immersion() @@ -1459,7 +1429,7 @@ class Screen(VectorFieldModule): The horizon of the Schwarzschild black hole:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X_M. = \ ....: M.chart(r"t r:(0,oo) th:(0,pi):\theta ph:(0,2*pi):\phi") sage: var('m'); assume(m>0) @@ -1509,7 +1479,7 @@ def __init__(self, submanifold, name, screen, rad, latex_name=None): TESTS:: - sage: M = Manifold(3, 'M', structure="Lorentzian") + sage: M = Manifold(3, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1524,7 +1494,6 @@ def __init__(self, submanifold, name, screen, rad, latex_name=None): sage: xi = M.vector_field(); xi[0] = sqrt(x^2+y^2); xi[1] = x; xi[2] = y sage: U = M.vector_field(); U[1] = -y; U[2] = x sage: Sc = S.screen('Sc', U, xi); - """ if not isinstance(submanifold, DegenerateSubmanifold): raise TypeError("the first argument must be a null submanifold") @@ -1546,7 +1515,7 @@ def _repr_(self): TESTS:: - sage: M = Manifold(3, 'M', structure="Lorentzian") + sage: M = Manifold(3, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1564,7 +1533,6 @@ def _repr_(self): 'screen distribution Sc along the degenerate hypersurface S embedded in 3-dimensional differentiable manifold M mapped into the 3-dimensional Lorentzian manifold M' - """ description = "screen distribution "+self._name if self._dest_map is self._domain.identity_map(): @@ -1590,7 +1558,7 @@ def __getitem__(self, i): TESTS:: - sage: M = Manifold(3, 'M', structure="Lorentzian") + sage: M = Manifold(3, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(2, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1628,7 +1596,7 @@ def normal_tangent_vector(self): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1646,7 +1614,6 @@ def normal_tangent_vector(self): sage: Sc = S.screen('Sc', (U,V), xi); # long time sage: Rad = Sc.normal_tangent_vector(); Rad.display() # long time xi = ∂/∂t + ∂/∂x - """ rad = [elt.along(self._domain.immersion()) for elt in self._rad] if self._domain._codim == 1: @@ -1672,7 +1639,7 @@ def rigging(self): A degenerate hyperplane the 4-dimensional Minkowski space `\RR^4_1`:: - sage: M = Manifold(4, 'M', structure="Lorentzian") + sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X. = M.chart() sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric') sage: X_S. = S.chart() @@ -1690,7 +1657,6 @@ def rigging(self): sage: Sc = S.screen('Sc', (U,V), xi); # long time sage: rig = Sc.rigging(); rig.display() # long time N = -1/2 ∂/∂t + 1/2 ∂/∂x - """ im = self._domain.immersion() rig = [elt.along(im) for elt in self._domain._transverse['rigging']] diff --git a/src/sage/manifolds/differentiable/diff_form.py b/src/sage/manifolds/differentiable/diff_form.py index bb1c0e3d341..fb58189796e 100644 --- a/src/sage/manifolds/differentiable/diff_form.py +++ b/src/sage/manifolds/differentiable/diff_form.py @@ -22,7 +22,7 @@ - Eric Gourgoulhon, Michal Bejger (2013, 2014): initial version - Joris Vankerschaver (2010): developed a previous class, ``DifferentialForm`` (cf. :issue:`24444`), which inspired the storage of the - non-zero components as a dictionary whose keys are the indices. + nonzero components as a dictionary whose keys are the indices. - Travis Scrimshaw (2016): review tweaks REFERENCES: @@ -278,7 +278,6 @@ class DiffForm(TensorField): f*a = y*(-x**2 - 2*x*y - y**2) dx + x*(x**2 + 2*x*y + y**2) dy sage: s.display(eV) f*a = u**2*v/2 du - u**3/2 dv - """ def __init__(self, vector_field_module, degree, name=None, latex_name=None): r""" @@ -319,7 +318,6 @@ def __init__(self, vector_field_module, degree, name=None, latex_name=None): .. TODO:: Fix ``_test_pickling`` (in the superclass :class:`TensorField`). - """ TensorField.__init__(self, vector_field_module, (0, degree), name=name, latex_name=latex_name, antisym=range(degree), @@ -343,7 +341,6 @@ def _repr_(self): sage: b = M.diff_form(2) sage: b._repr_() '2-form on the 3-dimensional differentiable manifold M' - """ description = "{}-form ".format(self._tensor_rank) if self._name is not None: @@ -365,7 +362,6 @@ def _new_instance(self): True sage: a1.parent() is a.parent() True - """ return type(self)(self._vmodule, self._tensor_rank) @@ -378,7 +374,6 @@ def _del_derived(self): sage: M = Manifold(3, 'M') sage: a = M.diff_form(2, name='a') sage: a._del_derived() - """ TensorField._del_derived(self) self.exterior_derivative.clear_cache() @@ -445,7 +440,6 @@ def exterior_derivative(self) -> DiffForm: sage: v.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True - """ from sage.tensor.modules.format_utilities import ( format_unop_txt, @@ -528,7 +522,6 @@ def wedge(self, other: DiffForm) -> DiffForm: sage: t = a.wedge(f) sage: t.display() f*a = x*y dx + x^2 dy - """ if other._tensor_rank == 0: return self * other @@ -594,9 +587,7 @@ def degree(self) -> int: r""" Return the degree of ``self``. - OUTPUT: - - - integer `p` such that the differential form is a `p`-form + OUTPUT: integer `p` such that the differential form is a `p`-form EXAMPLES:: @@ -609,7 +600,6 @@ def degree(self) -> int: 1-form on the 3-dimensional differentiable manifold M sage: b.degree() 1 - """ return self._tensor_rank @@ -645,7 +635,7 @@ def hodge_dual( INPUT: - - ``nondegenerate_tensor``: a non-degenerate bilinear form defined on the same manifold + - ``nondegenerate_tensor`` -- a non-degenerate bilinear form defined on the same manifold as the current differential form; must be an instance of :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` or :class:`~sage.manifolds.differentiable.symplectic_form.SymplecticForm`. @@ -780,7 +770,7 @@ def hodge_dual( nondegenerate_tensor = self._vmodule._ambient_domain.metric() p = self.tensor_type()[1] - # For performance reasons, we raise the indicies of the volume form + # For performance reasons, we raise the indices of the volume form # and not of the differential form; in the symplectic case this is wrong by # a factor of (-1)^p, which will be corrected below eps = nondegenerate_tensor.volume_form(p) @@ -797,7 +787,7 @@ def hodge_dual( result = result * nondegenerate_tensor._indic_signat from sage.manifolds.differentiable.symplectic_form import SymplecticForm if isinstance(nondegenerate_tensor, SymplecticForm): - # correction because we lifted the indicies of the volume (see above) + # correction because we lifted the indices of the volume (see above) result = result * (-1)**p result.set_name( @@ -898,7 +888,6 @@ def interior_product(self, qvect): True sage: s.restrict(V) == 2 * a[[e_uv,1,2]] * b[[e_uv,1,2]] True - """ from sage.tensor.modules.format_utilities import is_atomic if self._domain.is_subset(qvect._domain): @@ -1033,7 +1022,7 @@ class DiffFormParal(FreeModuleAltForm, TensorFieldParal, DiffForm): sage: type(a.comp()) - Setting a component with repeated indices to a non-zero value + Setting a component with repeated indices to a nonzero value results in an error:: sage: a[1,1] = 3 @@ -1249,7 +1238,6 @@ class DiffFormParal(FreeModuleAltForm, TensorFieldParal, DiffForm): [18 15 12] sage: c.symmetries() # c has no symmetries: no symmetry; no antisymmetry - """ def __init__(self, vector_field_module: VectorFieldModule, degree: int, name: Optional[str] = None, latex_name: Optional[str] = None): @@ -1284,7 +1272,6 @@ def __init__(self, vector_field_module: VectorFieldModule, degree: int, name: Op sage: a = M.diff_form(2, [[0, x*y], [-x*y, 0]], name='a') sage: a.display() a = x*y dx∧dy - """ FreeModuleAltForm.__init__(self, vector_field_module, degree, name=name, latex_name=latex_name) @@ -1313,7 +1300,6 @@ def _repr_(self): sage: b = M.diff_form(2) sage: b._repr_() '2-form on the 3-dimensional differentiable manifold M' - """ description = "{}-form ".format(self._tensor_rank) if self._name is not None: @@ -1336,7 +1322,6 @@ def _new_instance(self): True sage: a1.parent() is a.parent() True - """ return type(self)(self._fmodule, self._tensor_rank) @@ -1351,7 +1336,6 @@ def _init_derived(self): sage: X. = M.chart() # makes M parallelizable sage: a = M.diff_form(2, name='a') sage: a._init_derived() - """ TensorFieldParal._init_derived(self) @@ -1361,7 +1345,7 @@ def _del_derived(self, del_restrictions: bool = True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the restrictions of ``self`` to subdomains are deleted TESTS:: @@ -1370,7 +1354,6 @@ def _del_derived(self, del_restrictions: bool = True): sage: X. = M.chart() # makes M parallelizable sage: a = M.diff_form(2, name='a') sage: a._del_derived() - """ TensorFieldParal._del_derived(self, del_restrictions=del_restrictions) self.exterior_derivative.clear_cache() @@ -1400,7 +1383,6 @@ def __call__(self, *args): True sage: s == a(u,v) # indirect doctest True - """ return TensorFieldParal.__call__(self, *args) @@ -1455,7 +1437,6 @@ def exterior_derivative(self) -> DiffFormParal: sage: v = M.vector_field(-y, x, t, z, name='v') sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True - """ from sage.tensor.modules.format_utilities import (format_unop_txt, format_unop_latex) @@ -1559,7 +1540,6 @@ def wedge(self, other): sage: t = a.wedge(f) sage: t.display() f*a = 2*x dx + (x^2 + x) dy + x*y*z dz - """ if other._tensor_rank == 0: return self * other @@ -1658,7 +1638,6 @@ def interior_product(self, qvect): sage: f = X.coframe()[2] # 1-form dy sage: f.interior_product(v) Scalar field zero on the 3-dimensional differentiable manifold M - """ if self._domain.is_subset(qvect._domain): if not self._ambient_domain.is_subset(qvect._ambient_domain): diff --git a/src/sage/manifolds/differentiable/diff_form_module.py b/src/sage/manifolds/differentiable/diff_form_module.py index e5497762adb..ee0dd856697 100644 --- a/src/sage/manifolds/differentiable/diff_form_module.py +++ b/src/sage/manifolds/differentiable/diff_form_module.py @@ -142,7 +142,7 @@ class DiffFormModule(UniqueRepresentation, Parent): sage: z is A.zero() True - while non-zero elements are constructed by providing their components in a + while nonzero elements are constructed by providing their components in a given vector frame:: sage: a = A([[0,3*x],[-3*x,0]], frame=eU, name='a') ; a @@ -254,7 +254,6 @@ class DiffFormModule(UniqueRepresentation, Parent): manifold M sage: a_U.display(eU) a = 3*x dx∧dy - """ Element = DiffForm @@ -284,7 +283,6 @@ def __init__(self, vector_field_module, degree): In the above test suite, ``_test_elements`` is skipped because of the ``_test_pickling`` error of the elements (to be fixed in :class:`sage.manifolds.differentiable.tensorfield.TensorField`) - """ domain = vector_field_module._domain dest_map = vector_field_module._dest_map @@ -333,7 +331,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, a = x*y dx∧dy sage: A(0) is A.zero() True - """ try: if comp.is_trivial_zero(): @@ -386,7 +383,6 @@ def _an_element_(self): sage: A = M.diff_form_module(2) sage: A._an_element_() 2-form on the 2-dimensional differentiable manifold M - """ resu = self.element_class(self._vmodule, self._degree) for oc in self._domain.open_covers(trivial=False): @@ -418,7 +414,6 @@ def _coerce_map_from_(self, other): True sage: A2._coerce_map_from_(A2U) False - """ if isinstance(other, (DiffFormModule, DiffFormFreeModule)): # coercion by domain restriction @@ -445,7 +440,6 @@ def zero(self): sage: A2 = M.diff_form_module(2) sage: A2.zero() 2-form zero on the 3-dimensional differentiable manifold M - """ zero = self._element_constructor_(name='zero', latex_name='0') for frame in self._domain._frames: @@ -469,7 +463,6 @@ def _repr_(self): sage: A2 Module Omega^2(M) of 2-forms on the 3-dimensional differentiable manifold M - """ description = "Module " if self._name is not None: @@ -494,7 +487,6 @@ def _latex_(self): '\\Omega^{2}\\left(\\mathcal{M}\\right)' sage: latex(A2) # indirect doctest \Omega^{2}\left(\mathcal{M}\right) - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -530,7 +522,6 @@ def base_module(self): sage: A2U.base_module() Module X(U) of vector fields on the Open subset U of the 3-dimensional differentiable manifold M - """ return self._vmodule @@ -563,9 +554,7 @@ def degree(self): r""" Return the degree of the differential forms in ``self``. - OUTPUT: - - - integer `p` such that ``self`` is a set of `p`-forms + OUTPUT: integer `p` such that ``self`` is a set of `p`-forms EXAMPLES:: @@ -576,12 +565,12 @@ def degree(self): 2 sage: M.diff_form_module(3).degree() 3 - """ return self._degree # ***************************************************************************** + class DiffFormFreeModule(ExtPowerDualFreeModule): r""" Free module of differential forms of a given degree `p` (`p`-forms) along @@ -665,7 +654,7 @@ class DiffFormFreeModule(ExtPowerDualFreeModule): sage: A(0) is A.zero() True - while non-zero elements are constructed by providing their components + while nonzero elements are constructed by providing their components in a given vector frame:: sage: comp = [[0,3*x,-z],[-3*x,0,4],[z,-4,0]] @@ -741,7 +730,6 @@ class DiffFormFreeModule(ExtPowerDualFreeModule): manifold M sage: a_U.display() a = 3*x dx∧dy - z dx∧dz + 4 dy∧dz - """ Element = DiffFormParal @@ -759,7 +747,6 @@ def __init__(self, vector_field_module, degree): Free module Omega^2(M) of 2-forms on the 3-dimensional differentiable manifold M sage: TestSuite(A).run() - """ domain = vector_field_module._domain dest_map = vector_field_module._dest_map @@ -806,7 +793,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, sage: f = M.scalar_field(x) sage: f in A False - """ try: if comp.is_trivial_zero(): @@ -870,7 +856,6 @@ def _coerce_map_from_(self, other): True sage: A1._coerce_map_from_(M.tensor_field_module((1,0))) False - """ if isinstance(other, (DiffFormModule, DiffFormFreeModule)): # coercion by domain restriction @@ -899,7 +884,6 @@ def _repr_(self): sage: A Free module Omega^2(M) of 2-forms on the 3-dimensional differentiable manifold M - """ description = "Free module " if self._name is not None: @@ -994,7 +978,7 @@ class VectorFieldDualFreeModule(DiffFormFreeModule): sage: A(0) is A.zero() True - while non-zero elements are constructed by providing their components + while nonzero elements are constructed by providing their components in a given vector frame:: sage: comp = [3*x,-z,4] @@ -1056,7 +1040,6 @@ def __init__(self, vector_field_module): sage: A = M.vector_field_module().dual(); A Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M sage: TestSuite(A).run() - """ DiffFormFreeModule.__init__(self, vector_field_module, 1) @@ -1072,6 +1055,5 @@ def tensor_type(self): Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M sage: A.tensor_type() (0, 1) - """ return (0, 1) diff --git a/src/sage/manifolds/differentiable/diff_map.py b/src/sage/manifolds/differentiable/diff_map.py index d684d064827..6ac44fa7fb6 100644 --- a/src/sage/manifolds/differentiable/diff_map.py +++ b/src/sage/manifolds/differentiable/diff_map.py @@ -43,6 +43,7 @@ from sage.manifolds.point import ManifoldPoint from sage.tensor.modules.free_module_morphism import FiniteRankFreeModuleMorphism + class DiffMap(ContinuousMap): r""" Differentiable map between two differentiable manifolds. @@ -82,11 +83,11 @@ class is - ``name`` -- (default: ``None``) name given to the differentiable map - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the differentiable map; if ``None``, the LaTeX symbol is set to ``name`` - - ``is_isomorphism`` -- (default: ``False``) determines whether the - constructed object is a isomorphism (i.e. a diffeomorphism); if set to + - ``is_isomorphism`` -- boolean (default: ``False``); determines whether the + constructed object is a isomorphism (i.e. a diffeomorphism). If set to ``True``, then the manifolds `M` and `N` must have the same dimension. - - ``is_identity`` -- (default: ``False``) determines whether the - constructed object is the identity map; if set to ``True``, + - ``is_identity`` -- boolean (default: ``False``); determines whether the + constructed object is the identity map. If set to ``True``, then `N` must be `M` and the entry ``coord_functions`` is not used. .. NOTE:: @@ -397,7 +398,6 @@ class is True sage: ~id is id True - """ def __init__(self, parent, coord_functions=None, name=None, latex_name=None, is_isomorphism=False, is_identity=False): @@ -426,7 +426,6 @@ def __init__(self, parent, coord_functions=None, name=None, Id_M: M → M (x, y) ↦ (x, y) sage: TestSuite(f).run() - """ ContinuousMap.__init__(self, parent, coord_functions=coord_functions, name=name, latex_name=latex_name, @@ -465,7 +464,6 @@ def _repr_(self): sage: f = Hom(M,M)({}, name='f', is_identity=True) sage: f._repr_() 'Identity map f of the 2-dimensional differentiable manifold M' - """ if self._is_identity: return "Identity map " + self._name + \ @@ -499,7 +497,6 @@ def _init_derived(self): sage: f._restrictions {} sage: f._inverse - """ ContinuousMap._init_derived(self) # derived quantities of the mother class @@ -522,7 +519,6 @@ def _del_derived(self): Diffeomorphism of the 2-dimensional differentiable manifold M sage: f._del_derived() sage: f._inverse # has been set to None by _del_derived() - """ ContinuousMap._del_derived(self) # derived quantities of the mother # class @@ -596,7 +592,6 @@ def differential(self, point: ManifoldPoint) -> FiniteRankFreeModuleMorphism: [ 1 -2] [-1 2] [ 4 -3] - """ image_point = self(point) tsp_image = image_point._manifold.tangent_space(image_point) @@ -776,7 +771,6 @@ def differential_functions(self, chart1=None, chart2=None): sage: bool( JJ[2,0] == J[2][0].expr() ) True - """ dom1 = self._domain dom2 = self._codomain @@ -821,9 +815,7 @@ def jacobian_matrix(self, chart1=None, chart2=None): `\Phi`; if none is provided, the codomain's default chart is assumed - OUTPUT: - - - the matrix `J` defined above + OUTPUT: the matrix `J` defined above EXAMPLES: @@ -845,7 +837,6 @@ def jacobian_matrix(self, chart1=None, chart2=None): [ 2*x -3*y^2] sage: J.parent() Full MatrixSpace of 3 by 2 dense matrices over Symbolic Ring - """ from sage.matrix.constructor import matrix diff_funct = self.differential_functions(chart1, chart2) @@ -954,7 +945,6 @@ def pullback(self, tensor_or_codomain_subset, name=None, latex_name=None): sage: gM = F.pullback(g) sage: gM.display() (2*cos(t) + 2) dt⊗dt - """ if not hasattr(tensor_or_codomain_subset, '_domain'): return super().pullback(tensor_or_codomain_subset, @@ -985,10 +975,7 @@ def _pullback_chart(diff_map, tensor, chart1, chart2): - ``chart1`` -- chart on the domain of ``diff_map`` - ``chart2`` -- chart on the codomain of ``diff_map`` - OUTPUT: - - - the pull back of ``tensor`` by ``diff_map`` - + OUTPUT: the pull back of ``tensor`` by ``diff_map`` """ dom1 = diff_map._domain dom2 = diff_map._codomain @@ -1038,8 +1025,8 @@ def _pullback_chart(diff_map, tensor, chart1, chart2): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in ptcomp.non_redundant_index_generator()] - ind_step = max(1, int(len(ind_list)/nproc/2)) + ind_list = list(ptcomp.non_redundant_index_generator()) + ind_step = max(1, (len(ind_list) // nproc) // 2) local_list = lol(ind_list, ind_step) # list of input parameters listParalInput = [(tcomp, chart1, chart2, coord2_1, jacob, @@ -1209,7 +1196,6 @@ def pushforward(self, tensor): the 3-dimensional differentiable manifold R^3 sage: pu.display() Psi_*(u) = -sin(t) ∂/∂x + cos(t) ∂/∂y + ∂/∂z - """ from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.tensor.modules.comp import ( diff --git a/src/sage/manifolds/differentiable/differentiable_submanifold.py b/src/sage/manifolds/differentiable/differentiable_submanifold.py index 06e861c98d0..51dd2962557 100644 --- a/src/sage/manifolds/differentiable/differentiable_submanifold.py +++ b/src/sage/manifolds/differentiable/differentiable_submanifold.py @@ -158,7 +158,6 @@ class DifferentiableSubmanifold(DifferentiableManifold, TopologicalSubmanifold): :mod:`~sage.manifolds.manifold` and :mod:`~sage.manifolds.topological_submanifold` - """ def __init__(self, n, name, field, structure, ambient=None, base_manifold=None, diff_degree=infinity, @@ -180,7 +179,6 @@ def __init__(self, n, name, field, structure, ambient=None, \Sigma sage: S.start_index() 1 - """ DifferentiableManifold.__init__(self, n, name, field, structure, base_manifold=base_manifold, @@ -212,7 +210,6 @@ def _repr_(self): sage: N 2-dimensional differentiable submanifold N embedded in the 3-dimensional differentiable manifold M - """ if self is not self._manifold: return "Open subset {} of the {}".format(self._name, self._manifold) @@ -240,7 +237,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none is provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -249,14 +246,12 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): - ``supersets`` -- (default: only ``self``) list of sets that the new open subset is a subset of - OUTPUT: - - - the open subset, as an instance of :class:`DifferentiableSubmanifold` + OUTPUT: the open subset, as an instance of :class:`DifferentiableSubmanifold` EXAMPLES:: - sage: M = Manifold(3, 'M', structure="differentiable") - sage: N = Manifold(2, 'N', ambient=M, structure="differentiable"); N + sage: M = Manifold(3, 'M', structure='differentiable') + sage: N = Manifold(2, 'N', ambient=M, structure='differentiable'); N 2-dimensional differentiable submanifold N immersed in the 3-dimensional differentiable manifold M sage: S = N.subset('S'); S @@ -281,7 +276,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): Open subset O of the 2-dimensional differentiable submanifold N embedded in the 3-dimensional differentiable manifold M - """ resu = DifferentiableSubmanifold(self._dim, name, self._field, self._structure, ambient=self._ambient, diff --git a/src/sage/manifolds/differentiable/examples/euclidean.py b/src/sage/manifolds/differentiable/examples/euclidean.py index 6a4b0bd2899..ec0f30be82c 100644 --- a/src/sage/manifolds/differentiable/examples/euclidean.py +++ b/src/sage/manifolds/differentiable/examples/euclidean.py @@ -1,10 +1,10 @@ r""" Euclidean Spaces -An *Euclidean space of dimension* `n` is an affine space `E`, whose associated +A *Euclidean space of dimension* `n` is an affine space `E`, whose associated vector space is a `n`-dimensional vector space over `\RR` and is equipped with a positive definite symmetric bilinear form, called the *scalar product* or -*dot product* [Ber1987]_. An Euclidean space of dimension `n` can also be +*dot product* [Ber1987]_. A Euclidean space of dimension `n` can also be viewed as a Riemannian manifold that is diffeomorphic to `\RR^n` and that has a flat metric `g`. The Euclidean scalar product is then that defined by the Riemannian metric `g`. @@ -419,11 +419,12 @@ ############################################################################### + class EuclideanSpace(PseudoRiemannianManifold): r""" Euclidean space. - An *Euclidean space of dimension* `n` is an affine space `E`, whose + A *Euclidean space of dimension* `n` is an affine space `E`, whose associated vector space is a `n`-dimensional vector space over `\RR` and is equipped with a positive definite symmetric bilinear form, called the *scalar product* or *dot product*. @@ -506,7 +507,7 @@ class EuclideanSpace(PseudoRiemannianManifold): sage: latex(F) \mathcal{F} - By default, an Euclidean space is created with a single coordinate chart: + By default, a Euclidean space is created with a single coordinate chart: that of Cartesian coordinates:: sage: E.atlas() @@ -556,7 +557,7 @@ class EuclideanSpace(PseudoRiemannianManifold): sage: latex(xi+ze) {\xi} + {\zeta} - Thanks to the argument ``coordinates``, an Euclidean space can be + Thanks to the argument ``coordinates``, a Euclidean space can be constructed with curvilinear coordinates initialized instead of the Cartesian ones:: @@ -641,7 +642,6 @@ class EuclideanSpace(PseudoRiemannianManifold): Riemannian metric g on the 4-dimensional Euclidean space E^4 sage: g.display() g = dx1⊗dx1 + dx2⊗dx2 + dx3⊗dx3 + dx4⊗dx4 - """ @staticmethod def __classcall_private__(cls, n=None, name=None, latex_name=None, @@ -730,14 +730,14 @@ def __init__(self, n, name=None, latex_name=None, category=None, init_coord_methods=None, unique_tag=None): r""" - Construct an Euclidean space. + Construct a Euclidean space. INPUT: This class also takes the following input: - ``base_manifold`` -- (default: ``None``) if not ``None``, must be - an Euclidean space; the created object is then an open subset + a Euclidean space; the created object is then an open subset of ``base_manifold`` - ``category`` -- (default: ``None``) to specify the category; if ``None``, @@ -762,7 +762,6 @@ def __init__(self, n, name=None, latex_name=None, sage: E.metric() Riemannian metric g on the 4-dimensional Euclidean space E^4 sage: TestSuite(E).run() - """ if name is None: name = 'E^{}'.format(n) @@ -812,7 +811,6 @@ def _repr_(self): '4-dimensional Euclidean space E^4' sage: E # indirect doctest 4-dimensional Euclidean space E^4 - """ return "{}-dimensional Euclidean space {}".format(self._dim, self._name) @@ -834,7 +832,6 @@ def _first_ngens(self, n): sage: E. = EuclideanSpace() sage: E._first_ngens(2) (u, v) - """ return self._def_chart[:] @@ -847,7 +844,6 @@ def _init_cartesian(self, symbols): sage: E = EuclideanSpace(2) sage: E._init_cartesian('x y') - """ chart = self.chart(coordinates=symbols) self._cartesian_chart = chart @@ -900,7 +896,6 @@ def cartesian_coordinates(self, symbols=None, names=None): (x1, x2, x3, x4) sage: latex(X[:]) \left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\right) - """ if self._cartesian_chart is None: if symbols is None: @@ -920,9 +915,7 @@ def cartesian_frame(self): Return the orthonormal vector frame associated with Cartesian coordinates. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.vectorframe.CoordFrame` + OUTPUT: :class:`~sage.manifolds.differentiable.vectorframe.CoordFrame` EXAMPLES:: @@ -940,7 +933,6 @@ def cartesian_frame(self): sage: E.cartesian_frame() is E.cartesian_coordinates().frame() True - """ if self._cartesian_chart is None: self.cartesian_coordinates() # creates the Cartesian chart @@ -970,7 +962,6 @@ def dist(self, p, q): sqrt(5) sage: p.dist(q) # indirect doctest sqrt(5) - """ chart = self.cartesian_coordinates() coords_p = chart(p) @@ -1040,7 +1031,6 @@ def sphere(self, radius=1, center=None, name=None, latex_name=None, See :class:`~sage.manifolds.differentiable.examples.sphere.Sphere` for more examples. - """ n = self._dim if n == 1: @@ -1052,18 +1042,19 @@ def sphere(self, radius=1, center=None, name=None, latex_name=None, ############################################################################### + class EuclideanPlane(EuclideanSpace): r""" Euclidean plane. - An *Euclidean plane* is an affine space `E`, whose associated vector space + A *Euclidean plane* is an affine space `E`, whose associated vector space is a 2-dimensional vector space over `\RR` and is equipped with a positive definite symmetric bilinear form, called the *scalar product* or *dot product*. The class :class:`EuclideanPlane` inherits from :class:`~sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold` - (via :class:`EuclideanSpace`) since an Euclidean plane can be viewed + (via :class:`EuclideanSpace`) since a Euclidean plane can be viewed as a Riemannian manifold that is diffeomorphic to `\RR^2` and that has a flat metric `g`. The Euclidean scalar product is the one defined by the Riemannian metric `g`. @@ -1120,7 +1111,7 @@ class EuclideanPlane(EuclideanSpace): EXAMPLES: - One creates an Euclidean plane ``E`` with:: + One creates a Euclidean plane ``E`` with:: sage: E. = EuclideanSpace(); E Euclidean plane E^2 @@ -1171,13 +1162,12 @@ class EuclideanPlane(EuclideanSpace): .. SEEALSO:: :ref:`EuclideanSpace_example1` - """ def __init__(self, name=None, latex_name=None, coordinates='Cartesian', symbols=None, metric_name='g', metric_latex_name=None, start_index=1, base_manifold=None, category=None, unique_tag=None): r""" - Construct an Euclidean plane. + Construct a Euclidean plane. TESTS:: @@ -1186,7 +1176,6 @@ def __init__(self, name=None, latex_name=None, coordinates='Cartesian', sage: E.metric() Riemannian metric g on the Euclidean plane E^2 sage: TestSuite(E).run() - """ if coordinates not in ['Cartesian', 'polar']: raise TypeError("unknown coordinate type") @@ -1227,7 +1216,6 @@ def _repr_(self): sage: E = EuclideanSpace(2, name='E') sage: E._repr_() 'Euclidean plane E' - """ return "Euclidean plane {}".format(self._name) @@ -1244,7 +1232,6 @@ def _init_polar(self, symbols): sage: E._init_polar(r"R Phi:\Phi") sage: E.atlas() [Chart (E^2, (x, y)), Chart (E^2, (R, Phi))] - """ coords = symbols.split() # list of strings, one per coordinate # Adding the coordinate ranges: @@ -1299,7 +1286,6 @@ def _transition_polar_cartesian(self): sage: E.change_of_frame(polar_f, cart_f)[:, polar] [ cos(ph) sin(ph)] [-sin(ph) cos(ph)] - """ # Transition maps polar chart <-> Cartesian chart chart_cart = self._cartesian_chart @@ -1416,7 +1402,6 @@ def cartesian_coordinates(self, symbols=None, names=None): sage: cartesian = E.cartesian_coordinates(symbols='u v') sage: u, v = cartesian[:] - """ if self._cartesian_chart is None: if symbols is None: @@ -1507,7 +1492,6 @@ def polar_coordinates(self, symbols=None, names=None): sage: E.polar_coordinates(symbols=r"R Th:\Theta") Chart (E^2, (r, th)) - """ if self._polar_chart is None: if symbols is None: @@ -1561,7 +1545,6 @@ def polar_frame(self): ....: e.display(E.polar_coordinates()) e_r = ∂/∂r e_ph = 1/r ∂/∂ph - """ if self._polar_frame is None: # create the polar chart and the associated orthonormal frame @@ -1617,7 +1600,7 @@ class Euclidean3dimSpace(EuclideanSpace): - ``start_index`` -- (default: 1) integer; lower value of the range of indices used for "indexed objects" in the Euclidean 3-space, e.g. coordinates of a chart - - ``base_manifold`` -- (default: ``None``) if not ``None``, must be an + - ``base_manifold`` -- (default: ``None``) if not ``None``, must be a Euclidean 3-space; the created object is then an open subset of ``base_manifold`` - ``category`` -- (default: ``None``) to specify the category; if ``None``, @@ -1700,13 +1683,12 @@ class Euclidean3dimSpace(EuclideanSpace): .. SEEALSO:: :ref:`EuclideanSpace_example2` - """ def __init__(self, name=None, latex_name=None, coordinates='Cartesian', symbols=None, metric_name='g', metric_latex_name=None, start_index=1, base_manifold=None, category=None, unique_tag=None): r""" - Construct an Euclidean 3-space. + Construct a Euclidean 3-space. TESTS:: @@ -1715,7 +1697,6 @@ def __init__(self, name=None, latex_name=None, coordinates='Cartesian', sage: E.metric() Riemannian metric g on the Euclidean space E^3 sage: TestSuite(E).run() - """ if coordinates not in ['Cartesian', 'spherical', 'cylindrical']: raise TypeError("unknown coordinate type") @@ -1765,7 +1746,6 @@ def _repr_(self): sage: E = EuclideanSpace(3, name='E') sage: E._repr_() 'Euclidean space E' - """ return "Euclidean space {}".format(self._name) @@ -1782,7 +1762,6 @@ def _init_spherical(self, symbols): sage: E._init_spherical(r"R Th:\Theta Ph:\Phi") sage: E.atlas() [Chart (E^3, (x, y, z)), Chart (E^3, (R, Th, Ph))] - """ coords = symbols.split() # list of strings, one per coordinate # Adding the coordinate ranges: @@ -1826,7 +1805,6 @@ def _init_cylindrical(self, symbols): sage: E._init_cylindrical(r"r ph:\phi z") sage: E.atlas() [Chart (E^3, (x, y, z)), Chart (E^3, (r, ph, z))] - """ coords = symbols.split() # list of strings, one per coordinate # Adding the coordinate ranges: @@ -1890,7 +1868,6 @@ def _transition_spherical_cartesian(self): [cos(ph)*sin(th) sin(ph)*sin(th) cos(th)] [cos(ph)*cos(th) cos(th)*sin(ph) -sin(th)] [ -sin(ph) cos(ph) 0] - """ # Transition maps spherical chart <-> Cartesian chart chart_cart = self._cartesian_chart @@ -1970,7 +1947,6 @@ def _transition_cylindrical_cartesian(self): [ cos(ph) sin(ph) 0] [-sin(ph) cos(ph) 0] [ 0 0 1] - """ # Transition maps cylindrical chart <-> Cartesian chart chart_cart = self._cartesian_chart @@ -2048,7 +2024,6 @@ def _transition_spherical_cylindrical(self): [ sin(th) 0 cos(th)] [ cos(th) 0 -sin(th)] [ 0 1 0] - """ # Transition maps spherical chart <-> cylindrical chart cylind = self._cylindrical_chart @@ -2159,7 +2134,6 @@ def cartesian_coordinates(self, symbols=None, names=None): sage: cartesian = E.cartesian_coordinates(symbols='u v w') sage: u, v, w = cartesian[:] - """ if self._cartesian_chart is None: if symbols is None: @@ -2256,7 +2230,6 @@ def spherical_coordinates(self, symbols=None, names=None): sage: E.spherical_coordinates(symbols=r"r th:\theta ph:\phi") Chart (E^3, (R, T, F)) - """ if self._spherical_chart is None: if symbols is None: @@ -2281,9 +2254,7 @@ def spherical_frame(self): Return the orthonormal vector frame associated with spherical coordinates. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame` + OUTPUT: :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame` EXAMPLES:: @@ -2315,7 +2286,6 @@ def spherical_frame(self): e_r = ∂/∂r e_th = 1/r ∂/∂th e_ph = 1/(r*sin(th)) ∂/∂ph - """ if self._spherical_frame is None: # create the spherical chart and the associated orthonormal frame @@ -2404,7 +2374,6 @@ def cylindrical_coordinates(self, symbols=None, names=None): sage: E.cylindrical_coordinates(symbols=r"rh:\rho ph:\phi z") Chart (E^3, (R, Phi, Z)) - """ if self._cylindrical_chart is None: if symbols is None: @@ -2429,9 +2398,7 @@ def cylindrical_frame(self): Return the orthonormal vector frame associated with cylindrical coordinates. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame` + OUTPUT: :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame` EXAMPLES:: @@ -2463,7 +2430,6 @@ def cylindrical_frame(self): e_rh = ∂/∂rh e_ph = 1/rh ∂/∂ph e_z = ∂/∂z - """ if self._cylindrical_frame is None: # create the cylindrical chart and the associated orthonormal frame @@ -2475,7 +2441,7 @@ def scalar_triple_product(self, name=None, latex_name=None): Return the scalar triple product operator, as a 3-form. The *scalar triple product* (also called *mixed product*) of three - vector fields `u`, `v` and `w` defined on an Euclidean space `E` + vector fields `u`, `v` and `w` defined on a Euclidean space `E` is the scalar field .. MATH:: @@ -2537,7 +2503,6 @@ def scalar_triple_product(self, name=None, latex_name=None): 3-form Omega on the Euclidean space E^3 sage: latex(_) \Omega - """ eps = self.volume_form() if latex_name is None: diff --git a/src/sage/manifolds/differentiable/examples/real_line.py b/src/sage/manifolds/differentiable/examples/real_line.py index be587304cfc..52b3dfad182 100644 --- a/src/sage/manifolds/differentiable/examples/real_line.py +++ b/src/sage/manifolds/differentiable/examples/real_line.py @@ -33,6 +33,7 @@ from sage.manifolds.structure import RealDifferentialStructure from sage.categories.manifolds import Manifolds + class OpenInterval(DifferentiableManifold): r""" Open interval as a 1-dimensional differentiable manifold over `\RR`. @@ -294,7 +295,6 @@ class OpenInterval(DifferentiableManifold): Chart ((1/2, 1), (t,)) sage: XK.coord_range() t: (1/2, 1) - """ @staticmethod def __classcall_private__(cls, lower, upper, ambient_interval=None, @@ -311,7 +311,6 @@ def __classcall_private__(cls, lower, upper, ambient_interval=None, sage: J = manifolds.OpenInterval(0,1, ambient_interval=I, coordinate='t') sage: I.open_interval(0,1) Real interval (0, 1) - """ if ambient_interval: # cope the UniqueRepresentation framework for subintervals and @@ -338,7 +337,6 @@ def __init__(self, lower, upper, ambient_interval=None, sage: J = manifolds.OpenInterval(-oo, 2); J Real interval (-Infinity, 2) sage: TestSuite(J).run(skip='_test_elements') # pickling of elements fails - """ if latex_name is None: if name is None: @@ -410,7 +408,6 @@ def _repr_(self): sage: I = manifolds.OpenInterval(-oo,0) sage: I Real interval (-Infinity, 0) - """ return "Real interval " + self._name @@ -435,7 +432,6 @@ def _first_ngens(self, n): sage: I = manifolds.OpenInterval(-1, 1, names=('x',)) sage: I._first_ngens(1) (x,) - """ return self._canon_chart[:] @@ -461,14 +457,12 @@ def _element_constructor_(self, coords=None, chart=None, name=None, - ``name`` -- (default: ``None``) name given to the point - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the point; if none is provided, the LaTeX symbol is set to ``name`` - - ``check_coords`` -- (default: ``True``) determines whether ``coords`` - are valid coordinates for the chart ``chart``; for symbolic - coordinates, it is recommended to set ``check_coords`` to ``False`` + - ``check_coords`` -- boolean (default: ``True``); determines whether + ``coords`` are valid coordinates for the chart ``chart``. For symbolic + coordinates, it is recommended to set ``check_coords`` to ``False``. - OUTPUT: - - - :class:`~sage.manifolds.point.TopologicalManifoldPoint` - representing a point in the current interval + OUTPUT: :class:`~sage.manifolds.point.TopologicalManifoldPoint` + representing a point in the current interval EXAMPLES:: @@ -490,7 +484,6 @@ def _element_constructor_(self, coords=None, chart=None, name=None, ... ValueError: the coordinates (8,) are not valid on the Chart ((-1, 4), (t,)) - """ if coords in SR: coords = (coords,) @@ -508,9 +501,7 @@ def _Hom_(self, other, category=None): - ``category`` -- (default: ``None``) not used here (to ensure compatibility with generic hook ``_Hom_``) - OUTPUT: - - - the set of curves `I \to M`, where `I` is ``self`` + OUTPUT: the set of curves `I \to M`, where `I` is ``self`` .. SEEALSO:: @@ -527,7 +518,6 @@ def _Hom_(self, other, category=None): Field with 53 bits of precision sage: H is Hom(I, M) True - """ from sage.manifolds.differentiable.manifold_homset import DifferentiableCurveSet return DifferentiableCurveSet(self, other) @@ -536,9 +526,7 @@ def canonical_chart(self): r""" Return the canonical chart defined on ``self``. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.chart.RealDiffChart` + OUTPUT: :class:`~sage.manifolds.differentiable.chart.RealDiffChart` EXAMPLES: @@ -556,7 +544,6 @@ def canonical_chart(self): sage: I. = manifolds.OpenInterval(0, pi) sage: I.canonical_chart() Chart ((0, pi), (x,)) - """ return self._canon_chart @@ -564,9 +551,7 @@ def canonical_coordinate(self): r""" Return the canonical coordinate defined on the interval. - OUTPUT: - - - the symbolic variable representing the canonical coordinate + OUTPUT: the symbolic variable representing the canonical coordinate EXAMPLES: @@ -595,7 +580,6 @@ def canonical_coordinate(self): sage: I. = manifolds.OpenInterval(0, pi) sage: I.canonical_coordinate() x - """ return self._canon_chart._xx[0] @@ -618,7 +602,6 @@ def lower_bound(self): 1/4 sage: J.inf() -Infinity - """ return self._lower @@ -643,7 +626,6 @@ def upper_bound(self): 3 sage: J.sup() +Infinity - """ return self._upper @@ -691,7 +673,6 @@ def open_interval(self, lower, upper, name=None, latex_name=None): sage: I.open_interval(-4, 4) is I True - """ if lower == self._lower and upper == self._upper: return self @@ -860,7 +841,6 @@ class RealLine(OpenInterval): Real number line ℝ sage: list(R.subset_family()) [Real interval (0, 1), Real number line ℝ] - """ @staticmethod def __classcall__(cls, name=unicode_mathbbR, latex_name=r'\Bold{R}', @@ -876,7 +856,6 @@ def __classcall__(cls, name=unicode_mathbbR, latex_name=r'\Bold{R}', Real number line ℝ sage: R is R1 True - """ return super().__classcall__(cls, name=name, latex_name=latex_name, @@ -896,7 +875,6 @@ def __init__(self, name=unicode_mathbbR, latex_name=r'\Bold{R}', Category of smooth connected manifolds over Real Field with 53 bits of precision sage: TestSuite(R).run(skip='_test_elements') # pickling of elements fails - """ OpenInterval.__init__(self, minus_infinity, infinity, name=name, latex_name=latex_name, coordinate=coordinate, @@ -914,6 +892,5 @@ def _repr_(self): sage: R = manifolds.RealLine(name='r') sage: R._repr_() 'Real number line r' - """ return "Real number line " + self._name diff --git a/src/sage/manifolds/differentiable/examples/sphere.py b/src/sage/manifolds/differentiable/examples/sphere.py index 387a31c10bc..43956a3ba1a 100644 --- a/src/sage/manifolds/differentiable/examples/sphere.py +++ b/src/sage/manifolds/differentiable/examples/sphere.py @@ -173,6 +173,7 @@ from sage.rings.real_mpfr import RR from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace + class Sphere(PseudoRiemannianSubmanifold): r""" Sphere smoothly embedded in Euclidean Space. @@ -284,7 +285,6 @@ class Sphere(PseudoRiemannianSubmanifold): coordinates and their transition maps is computational complex in higher dimensions. Henceforth, high computation times are expected with increasing dimension. - """ @staticmethod def __classcall_private__(cls, n=None, radius=1, ambient_space=None, @@ -308,7 +308,6 @@ def __classcall_private__(cls, n=None, radius=1, ambient_space=None, 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 sage: S._first_ngens(2) (x, y) - """ if n is None: if names is None: @@ -342,7 +341,6 @@ def __init__(self, n, radius=1, ambient_space=None, center=None, name=None, Riemannian metric g on the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 sage: TestSuite(S2).run() - """ # radius if radius <= 0: @@ -411,7 +409,6 @@ def _init_embedding(self): iota: S^2 → E^3 on A: (theta, phi) ↦ (x, y, z) = (cos(phi)*sin(theta), sin(phi)*sin(theta), cos(theta)) - """ name = 'iota' latex_name = r'\iota' @@ -429,7 +426,6 @@ def _repr_(self): '2-sphere S^2_3 of radius 3 smoothly embedded in the Euclidean space E^3' sage: S2_3 # indirect doctest 2-sphere S^2_3 of radius 3 smoothly embedded in the Euclidean space E^3 - """ s = "{}-sphere {} of radius {} smoothly embedded in " \ "the {}".format(self._dim, self._name, self._radius, self._ambient) @@ -443,7 +439,7 @@ def coordinate_charts(self, coord_name, names=None): INPUT: - - ``coord_name`` -- string describing the type of coordinates + - ``coord_name`` -- string describing the type of coordinates - ``names`` -- (default: ``None``) must be a tuple containing the coordinate symbols for the first chart in the list; if ``None``, the standard convention is used @@ -461,7 +457,6 @@ def coordinate_charts(self, coord_name, names=None): sage: stereo_charts = S1.coordinate_charts('stereographic', names=['a']) sage: stereo_charts [Chart (S^1-{NP}, (a,)), Chart (S^1-{SP}, (ap,))] - """ if coord_name not in self._coordinates: if coord_name not in self._init_coordinates: @@ -487,7 +482,6 @@ def _first_ngens(self, n): sage: S2. = manifolds.Sphere(2) sage: S2._first_ngens(2) (u, v) - """ return self._def_chart[:] @@ -507,7 +501,6 @@ def _init_chart_domains(self): Open subset S^2-{NP,SP} of the Euclidean 2-sphere S^2 of radius 1, Open subset S^2-{NP} of the Euclidean 2-sphere S^2 of radius 1, Open subset S^2-{SP} of the Euclidean 2-sphere S^2 of radius 1}) - """ # without north pole: name = self._name + '-{NP}' @@ -551,7 +544,6 @@ def _shift_coords(self, coordfunc, s='+'): (cos(phi)*sin(theta) + 1, sin(phi)*sin(theta) + 2, cos(theta) + 3) sage: S2c._shift_coords(coordfunc, s='-') (cos(phi)*sin(theta), sin(phi)*sin(theta), cos(theta)) - """ cart = self._ambient.cartesian_coordinates() c_coords = cart(self._center) @@ -586,7 +578,6 @@ def _init_spherical(self, names=None): Chart (A, (phi,)), Chart (A, (y1,)), Chart (A, (yp1,))] - """ # speed-up via simplification method... self.set_simplify_function(lambda expr: expr.simplify_trig()) @@ -740,7 +731,6 @@ def stereographic_coordinates(self, pole='north', names=None): Chart (S^3-{NP}, (y1, y2, y3)) sage: S3.stereographic_coordinates(pole='south') Chart (S^3-{SP}, (yp1, yp2, yp3)) - """ coordinates = 'stereographic' if coordinates not in self._coordinates: @@ -856,7 +846,6 @@ def spherical_coordinates(self, names=None): sage: spher.coord_range() chi: (0, pi); theta: (0, pi); phi: [-pi, pi] (periodic) - """ coordinates = 'spherical' if coordinates not in self._coordinates: @@ -906,7 +895,6 @@ def _init_stereographic(self, names, default_pole='north'): sage: S1.metric().display() g = dphi⊗dphi - """ # speed-up via simplification method... self.set_simplify_function(lambda expr: expr.simplify_rational()) @@ -1006,7 +994,6 @@ def _transition_spher_stereo(self): Chart (S^1-{NP}, (y1,)) sage: S1.coord_change(spher, stereoN.restrict(A)) Change of coordinates from Chart (A, (phi,)) to Chart (A, (y1,)) - """ # speed-up via simplification method... self.set_simplify_function(lambda expr: expr.simplify()) @@ -1108,7 +1095,6 @@ def dist(self, p, q): sage: S2_r.dist(p, q) pi*r - """ from sage.functions.trig import acos # get Euclidean points: @@ -1146,7 +1132,6 @@ def radius(self): Euclidean space E^4 sage: S2_r.radius() r - """ return self._radius @@ -1166,7 +1151,6 @@ def minimal_triangulation(self): sage: S.euler_characteristic() 2 - """ from sage.topology.simplicial_complex_examples import Sphere as SymplicialSphere return SymplicialSphere(self._dim) @@ -1195,6 +1179,5 @@ def center(self): on A: (theta, phi) ↦ (x, y, z) = (cos(phi)*sin(theta) + 1, sin(phi)*sin(theta) + 2, cos(theta) + 3) - """ return self._center diff --git a/src/sage/manifolds/differentiable/examples/symplectic_space.py b/src/sage/manifolds/differentiable/examples/symplectic_space.py index be02c965fe7..5a78277d567 100644 --- a/src/sage/manifolds/differentiable/examples/symplectic_space.py +++ b/src/sage/manifolds/differentiable/examples/symplectic_space.py @@ -16,7 +16,7 @@ # ***************************************************************************** from __future__ import annotations -from typing import Optional, Tuple +from typing import Optional from sage.categories.manifolds import Manifolds from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace @@ -43,18 +43,19 @@ def __init__( symplectic_latex_name: Optional[str] = None, start_index: int = 1, base_manifold: Optional[StandardSymplecticSpace] = None, - names: Optional[Tuple[str]] = None, + names: Optional[tuple[str]] = None, ): r""" INPUT: - ``dimension`` -- dimension of the space over the real field (has to be even) - ``name`` -- name (symbol) given to the underlying vector space; - if ``None``, the name will be set to ``'Rn'``, where ``n`` is the ``dimension`` - - ``latex_name`` -- LaTeX symbol to denote the underlying vector space; if ``None``, it is set to ``name`` + if ``None``, the name will be set to ``'Rn'``, where ``n`` is the ``dimension`` + - ``latex_name`` -- LaTeX symbol to denote the underlying vector space; + if ``None``, it is set to ``name`` - ``coordinates`` -- (default: ``'Cartesian'``) the - type of coordinates to be initialized at the Euclidean space - creation; allowed values are + type of coordinates to be initialized at the Euclidean space + creation; allowed values are - ``'Cartesian'`` (canonical coordinates on `\RR^{2n}`) - ``'polar'`` for ``dimension=2`` only (see @@ -111,7 +112,6 @@ def __init__( Inner product matrix: [0.000000000000000 -1.00000000000000] [ 1.00000000000000 0.000000000000000] - """ # Check that manifold is even dimensional if dimension % 2 == 1: diff --git a/src/sage/manifolds/differentiable/examples/symplectic_space_test.py b/src/sage/manifolds/differentiable/examples/symplectic_space_test.py index 0372470bd73..9cfdf6da123 100644 --- a/src/sage/manifolds/differentiable/examples/symplectic_space_test.py +++ b/src/sage/manifolds/differentiable/examples/symplectic_space_test.py @@ -9,7 +9,7 @@ class TestR2VectorSpace: @pytest.fixture def M(self): - return StandardSymplecticSpace(2, "R2", symplectic_name="omega") + return StandardSymplecticSpace(2, 'R2', symplectic_name='omega') @pytest.fixture def omega(self, M: StandardSymplecticSpace): @@ -25,7 +25,7 @@ def test_display(self, omega: SymplecticForm): class TestR4VectorSpace: @pytest.fixture def M(self): - return StandardSymplecticSpace(4, "R4", symplectic_name="omega") + return StandardSymplecticSpace(4, 'R4', symplectic_name='omega') @pytest.fixture def omega(self, M: StandardSymplecticSpace): diff --git a/src/sage/manifolds/differentiable/integrated_curve.py b/src/sage/manifolds/differentiable/integrated_curve.py index 3976f7c4b9d..135e6d53d32 100644 --- a/src/sage/manifolds/differentiable/integrated_curve.py +++ b/src/sage/manifolds/differentiable/integrated_curve.py @@ -361,7 +361,6 @@ class IntegratedCurve(DifferentiableCurve): color_tangent='orange') graph = c_plot_3d_1 + c_plot_3d_100 sphinx_plot(graph) - """ def __init__(self, parent, equations_rhs, velocities, @@ -423,7 +422,6 @@ def __init__(self, parent, equations_rhs, velocities, sage: t = var('t') sage: c = E.integrated_geodesic(E.metric(), (t, 0, 10), v); c Integrated geodesic in the Euclidean plane E^2 - """ from sage.symbolic.ring import SR @@ -633,7 +631,6 @@ def _repr_(self): sage: c = M.integrated_curve(eqns, D, (t,0,5), v, name='c'); c Integrated curve c in the 3-dimensional differentiable manifold M - """ description = "Integrated curve " @@ -681,7 +678,6 @@ def __reduce__(self): sage: loads(dumps(c)) Integrated curve c in the 3-dimensional differentiable manifold M - """ return (type(self), (self.parent(), self._equations_rhs, self._velocities, self._curve_parameter, @@ -696,12 +692,10 @@ def system(self, verbose=False): INPUT: - - ``verbose`` -- (default: ``False``) prints a detailed + - ``verbose`` -- boolean (default: ``False``); prints a detailed description of the curve - OUTPUT: - - - list containing + OUTPUT: list containing * the equations * the initial conditions @@ -744,7 +738,6 @@ def system(self, verbose=False): sage: sys_mute = c.system() sage: sys_mute == sys True - """ v0 = self._initial_tangent_vector @@ -812,7 +805,7 @@ def solve_analytical(self, verbose=False): zero, although the parameter range may not contain zero. Yet, assuming that it does, values of the coordinates functions at such zero initial parameter value are denoted by the name of - the coordinate function followed by the string ``"_0"``. + the coordinate function followed by the string ``'_0'``. OUTPUT: @@ -862,7 +855,6 @@ def solve_analytical(self, verbose=False): (B_0*q*x2_0 + Dx1_0*m*cos(B_0*q*t/m) + Dx2_0*m*sin(B_0*q*t/m) - Dx1_0*m)/(B_0*q), Dx3_0*t + x3_0) - """ from sage.calculus.var import function @@ -890,7 +882,7 @@ def solve_analytical(self, verbose=False): des[i] = diff(y[i],par) == des[i] for j in range(dim): coord = self._chart[:][j] # important to use '[:]' on - # 'chart' to avoid problems due to non zero starting + # 'chart' to avoid problems due to nonzero starting # index (i0) veloc = self._velocities[j] des[dim+i] = des[dim+i].substitute({coord: y[j]}) @@ -903,7 +895,7 @@ def solve_analytical(self, verbose=False): y_ics_second_half = [] for i in range(dim): coord = self._chart[:][i] # important to use '[:]' - # on 'chart' to avoid problems due to non zero + # on 'chart' to avoid problems due to nonzero # starting index (i0) veloc = self._velocities[i] str_var_coord = "{}_0".format(coord) @@ -983,14 +975,12 @@ def solve(self, step=None, method='odeint', solution_key=None, - ``parameters_values`` -- (default: ``None``) list of numerical values of the parameters present in the system defining the curve, to be substituted in the equations before integration - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the computation in progress - ``**control_param`` -- extra control parameters to be passed to the chosen solver; see the example with ``rtol`` and ``atol`` below - OUTPUT: - - - list of the numerical points of the computed solution + OUTPUT: list of the numerical points of the computed solution EXAMPLES: @@ -1059,7 +1049,6 @@ def solve(self, step=None, method='odeint', solution_key=None, ... ValueError: no available method of integration referred to as 'my method' - """ from sage.symbolic.ring import SR @@ -1077,7 +1066,7 @@ def solve(self, step=None, method='odeint', solution_key=None, t_min = self.domain().lower_bound() t_max = self.domain().upper_bound() - eqns_num = [eq for eq in self._equations_rhs] + eqns_num = list(self._equations_rhs) # 'self._equations_rhs' needs not to be modified ever, because we # want to keep track of the most general form of the equations # defining self, since those may contain parameters (which, for @@ -1318,7 +1307,7 @@ def jacobian(t,y): for j in range(dim): coord = chart[:][j] # important to use # '[:]' on 'chart' to avoid problems due - # to non zero starting index (i0) + # to nonzero starting index (i0) vel = self._velocities[j] AUX = eqns_num[i].derivative(coord) AUX2 = eqns_num[i].derivative(vel) @@ -1327,7 +1316,7 @@ def jacobian(t,y): for k in range(dim): coordin = chart[:][k] # important to # use '[:]' on 'chart' to avoid - # problems due to non zero starting + # problems due to nonzero starting # index (i0) veloc = self._velocities[k] AUX = AUX.substitute({coordin: y[k]}) @@ -1346,7 +1335,7 @@ def jacobian(t,y): for m in range(dim): coordin = chart[:][m] # important to use # '[:]' on 'chart' to avoid problems due - # to non zero starting index (i0) + # to nonzero starting index (i0) veloc = self._velocities[m] AUX3 = AUX3.substitute({coordin: y[m]}) AUX3 = AUX3.substitute({veloc: y[dim+m]}) @@ -1444,14 +1433,12 @@ def solve_across_charts(self, charts=None, step=None, solution_key=None, - ``parameters_values`` -- (default: ``None``) list of numerical values of the parameters present in the system defining the curve, to be substituted in the equations before integration - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the computation in progress - ``**control_param`` -- extra control parameters to be passed to the solver - OUTPUT: - - - list of the numerical points of the computed solution + OUTPUT: list of the numerical points of the computed solution EXAMPLES: @@ -1470,7 +1457,7 @@ def solve_across_charts(self, charts=None, step=None, solution_key=None, charts `P` en `C` (for "Polar" and "Cartesian") and their transition maps:: - sage: M = Manifold(2, 'M', structure="Riemannian") + sage: M = Manifold(2, 'M', structure='Riemannian') sage: C. = M.chart(coord_restrictions=lambda x,y: x**2+y**2 < 3**2) sage: P. = M.chart(coord_restrictions=lambda r, th: r > 2) sage: P_to_C = P.transition_map(C,(r*cos(th), r*sin(th))) @@ -1571,7 +1558,7 @@ def solve_across_charts(self, charts=None, step=None, solution_key=None, .. PLOT:: - M = Manifold(2, 'M', structure="Riemannian") + M = Manifold(2, 'M', structure='Riemannian') C= M.chart(names = ("x", "y"), coord_restrictions=lambda x,y: x**2+y**2 < 3**2) x, y = C[:] P = M.chart(names = ("r", "th"), coord_restrictions=lambda r,th: r > 2) @@ -1597,7 +1584,6 @@ def solve_across_charts(self, charts=None, step=None, solution_key=None, fig += c.plot_integrated(mapping=phi, color=["green","red"], thickness=3, plot_points=100, across_charts=True) sphinx_plot(fig) - """ import numpy as np @@ -1840,12 +1826,10 @@ def solution(self, solution_key=None, verbose=False): - ``solution_key`` -- (default: ``None``) key which the requested numerical solution is associated to; a default value is chosen if none is provided - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the solution returned - OUTPUT: - - - list of the numerical points of the solution requested + OUTPUT: list of the numerical points of the solution requested EXAMPLES: @@ -1914,12 +1898,10 @@ def interpolate(self, solution_key=None, method=None, - ``interpolation_key`` -- (default: ``None``) key which the resulting interpolation will be associated to ; a default value is given if none is provided - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the interpolation in progress - OUTPUT: - - - built interpolation object + OUTPUT: built interpolation object EXAMPLES: @@ -1971,7 +1953,6 @@ def interpolate(self, solution_key=None, method=None, ... ValueError: no available method of interpolation referred to as 'my method' - """ if solution_key is None: if 'odeint' in self._solutions: @@ -2045,12 +2026,10 @@ def interpolation(self, interpolation_key=None, verbose=False): - ``interpolation_key`` -- (default: ``None``) key which the requested interpolation is associated to; a default value is chosen if none is provided - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the interpolation object returned - OUTPUT: - - - requested interpolation object + OUTPUT: requested interpolation object EXAMPLES: @@ -2090,7 +2069,6 @@ def interpolation(self, interpolation_key=None, verbose=False): ... ValueError: no existing key 'my interp' referring to any interpolation - """ if interpolation_key is None: @@ -2122,7 +2100,7 @@ def __call__(self, t, interpolation_key=None, - ``interpolation_key`` -- (default: ``None``) key which the interpolation requested to compute the point is associated to; a default value is chosen if none is provided - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the interpolation used OUTPUT: @@ -2160,7 +2138,6 @@ def __call__(self, t, interpolation_key=None, associated with the key 'interp_T1' by default... sage: p.coordinates() # abs tol 1e-12 (1.060743337877276, -0.21538352256822146, 1.1) - """ if interpolation_key is None: @@ -2204,7 +2181,7 @@ def tangent_vector_eval_at(self, t, - ``interpolation_key`` -- (default: ``None``) key which the interpolation requested to compute the tangent vector is associated to; a default value is chosen if none is provided - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the interpolation used OUTPUT: @@ -2255,7 +2232,6 @@ def tangent_vector_eval_at(self, t, ... ValueError: no existing key 'my interp' referring to any interpolation - """ if interpolation_key is None: if 'cubic spline' in self._interpolations: @@ -2314,9 +2290,9 @@ def plot_integrated(self, chart=None, ambient_coords=None, - ``interpolation_key`` -- (default: ``None``) key associated to the interpolation object used for the plot; a default value is chosen if none is provided - - ``verbose`` -- (default: ``False``) prints information about + - ``verbose`` -- boolean (default: ``False``); prints information about the interpolation object used and the plotting in progress - - ``display_tangent`` -- (default: ``False``) determines whether + - ``display_tangent`` -- boolean (default: ``False``); determines whether some tangent vectors should also be plotted - ``color_tangent`` -- (default: ``blue``) color of the tangent vectors when these are plotted @@ -2379,7 +2355,6 @@ def plot_integrated(self, chart=None, ambient_coords=None, plot_points_tangent=10, scale=0.5, color='blue', color_tangent='red') sphinx_plot(c_plot_2d_1) - """ from sage.manifolds.chart import RealChart @@ -2889,6 +2864,7 @@ def plot_integrated(self, chart=None, ambient_coords=None, aspect_ratio=aspect_ratio, color=color, style=style, label_axes=label_axes) + class IntegratedAutoparallelCurve(IntegratedCurve): r""" Autoparallel curve on the manifold with respect to a given @@ -3173,7 +3149,7 @@ class IntegratedAutoparallelCurve(IntegratedCurve): The vectors tangent to such a curve make an angle different from 0 or `\pi/2` with the lines of latitude and longitude. Then, compute a curve such that both components of its initial - tangent vectors are non zero:: + tangent vectors are nonzero:: sage: sol = c.solve(solution_key='sol-angle', ....: parameters_values={tmin:0,tmax:2,th0:pi/4,ph0:0.1,v_th0:1,v_ph0:8}) @@ -3403,7 +3379,6 @@ class IntegratedAutoparallelCurve(IntegratedCurve): graph = graph3D_embedded_angle_curve + graph3D_embedded_loxo graph += graph3D_embedded_polar_coords sphinx_plot(graph) - """ def __init__(self, parent, affine_connection, curve_parameter, @@ -3428,7 +3403,6 @@ def __init__(self, parent, affine_connection, curve_parameter, Integrated autoparallel curve c in the 3-dimensional differentiable manifold M sage: TestSuite(c).run() - """ # setting the chart to gain access to the coordinate functions @@ -3510,7 +3484,6 @@ def _repr_(self): ....: name='c') ; c Integrated autoparallel curve c in the 3-dimensional differentiable manifold M - """ description = "Integrated autoparallel curve " @@ -3556,7 +3529,6 @@ def __reduce__(self): sage: loads(dumps(c)) Integrated autoparallel curve c in the 3-dimensional differentiable manifold M - """ return (type(self), (self.parent(), self._affine_connection, @@ -3572,7 +3544,7 @@ def system(self, verbose=False): INPUT: - - ``verbose`` -- (default: ``False``) prints a detailed + - ``verbose`` -- boolean (default: ``False``); prints a detailed description of the curve OUTPUT: @@ -3621,7 +3593,6 @@ def system(self, verbose=False): sage: sys_bis = c.system() sage: sys_bis == sys True - """ v0 = self._initial_tangent_vector @@ -3678,6 +3649,7 @@ def system(self, verbose=False): return [self._equations_rhs, v0, chart] + class IntegratedGeodesic(IntegratedAutoparallelCurve): r""" Geodesic on the manifold with respect to a given metric. @@ -3830,7 +3802,6 @@ class IntegratedGeodesic(IntegratedAutoparallelCurve): number_values=15, color='yellow') graph = graph3D_embedded_geods + graph3D_embedded_polar_coords sphinx_plot(graph) - """ def __init__(self, parent, metric, curve_parameter, @@ -3855,7 +3826,6 @@ def __init__(self, parent, metric, curve_parameter, Integrated geodesic c in the 2-dimensional Riemannian manifold S^2 sage: TestSuite(c).run() - """ affine_connection = metric.connection() @@ -3890,7 +3860,6 @@ def _repr_(self): sage: c = S2.integrated_geodesic(g, (t,0,pi), v, name='c'); c Integrated geodesic c in the 2-dimensional Riemannian manifold S^2 - """ description = "Integrated geodesic " @@ -3936,7 +3905,6 @@ def __reduce__(self): sage: loads(dumps(c)) Integrated geodesic c in the 2-dimensional Riemannian manifold S^2 - """ return (type(self), (self.parent(), self._metric, @@ -3951,12 +3919,10 @@ def system(self, verbose=False): INPUT: - - ``verbose`` -- (default: ``False``) prints a detailed + - ``verbose`` -- boolean (default: ``False``); prints a detailed description of the curve - OUTPUT: - - - list containing + OUTPUT: list containing * the equations * the initial equations @@ -3999,7 +3965,6 @@ def system(self, verbose=False): sage: sys_bis = c.system() sage: sys_bis == sys True - """ v0 = self._initial_tangent_vector diff --git a/src/sage/manifolds/differentiable/levi_civita_connection.py b/src/sage/manifolds/differentiable/levi_civita_connection.py index 6b40a99d440..55c4aca9416 100644 --- a/src/sage/manifolds/differentiable/levi_civita_connection.py +++ b/src/sage/manifolds/differentiable/levi_civita_connection.py @@ -34,6 +34,7 @@ from sage.manifolds.differentiable.affine_connection import AffineConnection from sage.manifolds.differentiable.vectorframe import CoordFrame + class LeviCivitaConnection(AffineConnection): r""" Levi-Civita connection on a pseudo-Riemannian manifold. @@ -115,7 +116,7 @@ class LeviCivitaConnection(AffineConnection): - ``name`` -- name given to the connection - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the connection - - ``init_coef`` -- (default: ``True``) determines whether the Christoffel + - ``init_coef`` -- boolean (default: ``True``); determines whether the Christoffel symbols are initialized (in the top charts on the domain, i.e. disregarding the subcharts) @@ -198,7 +199,6 @@ class LeviCivitaConnection(AffineConnection): Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,ph = 1/r Gam^ph_th,ph = cos(th)/sin(th) - """ def __init__(self, metric, name, latex_name=None, init_coef=True): r""" @@ -219,7 +219,6 @@ def __init__(self, metric, name, latex_name=None, init_coef=True): Levi-Civita connection nabla associated with the Riemannian metric g on the 2-dimensional differentiable manifold M sage: TestSuite(nab).run() - """ AffineConnection.__init__(self, metric.domain(), name, latex_name) self._metric = metric @@ -244,7 +243,6 @@ def _repr_(self): 'Levi-Civita connection nabla_g associated with the Riemannian metric g on the 5-dimensional differentiable manifold M' sage: repr(nab) # indirect doctest 'Levi-Civita connection nabla_g associated with the Riemannian metric g on the 5-dimensional differentiable manifold M' - """ description = "Levi-Civita connection" if self._name is not None: @@ -262,7 +260,6 @@ def _init_derived(self): sage: g = M.metric('g') sage: nab = g.connection() sage: nab._init_derived() - """ AffineConnection._init_derived(self) @@ -276,7 +273,6 @@ def _del_derived(self): sage: g = M.metric('g') sage: nab = g.connection() sage: nab._del_derived() - """ AffineConnection._del_derived(self) @@ -321,7 +317,6 @@ def restrict(self, subdomain): sage: nabU(g.restrict(U)).display() nabla_g(g) = 0 - """ if subdomain == self._domain: return self @@ -368,7 +363,6 @@ def _new_coef(self, frame): sage: e = M.vector_frame('e') sage: nab._new_coef(e) 3-indices components w.r.t. Vector frame (M, (e_0,e_1)) - """ from sage.tensor.modules.comp import Components, CompWithSym from sage.manifolds.differentiable.scalarfield import DiffScalarField @@ -436,7 +430,7 @@ def coef(self, frame=None): [[0, 1/r, 0], [1/r, 0, 0], [0, 0, -cos(th)*sin(th)]], [[0, 0, 1/r], [0, 0, cos(th)/sin(th)], [1/r, cos(th)/sin(th), 0]]] - The only non-zero Christoffel symbols:: + The only nonzero Christoffel symbols:: sage: gam[1,2,2], gam[1,3,3] (-r, -r*sin(th)^2) @@ -458,7 +452,7 @@ def coef(self, frame=None): [[0, 1/r, 0], [0, 0, 0], [0, 0, -cos(th)/(r*sin(th))]], [[0, 0, 1/r], [0, 0, cos(th)/(r*sin(th))], [0, 0, 0]]] - The only non-zero connection coefficients:: + The only nonzero connection coefficients:: sage: gam_e[1,2,2], gam_e[2,1,2] (-1/r, 1/r) @@ -581,7 +575,6 @@ def torsion(self): sage: t.display() 0 - """ if self._torsion is None: resu = self._domain.tensor_field(1, 2, antisym=(1,2)) @@ -822,7 +815,6 @@ def ricci(self, name=None, latex_name=None): differentiable manifold M sage: ric == 0 True - """ if self._ricci is None: if name is None: diff --git a/src/sage/manifolds/differentiable/manifold.py b/src/sage/manifolds/differentiable/manifold.py index b5bb4be4d6f..285a160e7ff 100644 --- a/src/sage/manifolds/differentiable/manifold.py +++ b/src/sage/manifolds/differentiable/manifold.py @@ -634,7 +634,6 @@ class DifferentiableManifold(TopologicalManifold): category:: sage: TestSuite(M).run() - """ def __init__(self, n, name, field, structure, base_manifold=None, diff_degree=infinity, latex_name=None, start_index=0, @@ -664,7 +663,6 @@ def __init__(self, n, name, field, structure, base_manifold=None, sage: U.category() is M.category().Subobjects() True sage: TestSuite(U).run() - """ if base_manifold is None: if category is None: @@ -731,7 +729,6 @@ def diff_degree(self): sage: M = Manifold(2, 'M', structure='differentiable', diff_degree=3) sage: M.diff_degree() 3 - """ return self._diff_degree @@ -747,7 +744,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none is provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -756,9 +753,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): - ``supersets`` -- (default: only ``self``) list of sets that the new open subset is a subset of - OUTPUT: - - - the open subset, as an instance of :class:`DifferentiableManifold` + OUTPUT: the open subset, as an instance of :class:`DifferentiableManifold` EXAMPLES: @@ -832,7 +827,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): False sage: M((-1/2,1/3)) in U True - """ resu = DifferentiableManifold(self._dim, name, self._field, self._structure, base_manifold=self._manifold, @@ -852,7 +846,7 @@ def _init_open_subset(self, resu, coord_def): INPUT: - ``resu`` -- an instance of :class:`TopologicalManifold` or - a subclass. + a subclass - ``coord_def`` -- (default: ``{}``) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -959,7 +953,6 @@ def diff_map(self, codomain, coord_functions=None, chart1=None, See the documentation of class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` for more examples. - """ homset = Hom(self, codomain) if coord_functions is None: @@ -1055,7 +1048,6 @@ def diffeomorphism(self, codomain=None, coord_functions=None, chart1=None, See the documentation of class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` for more examples. - """ if codomain is None: codomain = self @@ -1091,7 +1083,7 @@ class as the manifold. - ``name`` -- name given to the total space - ``field`` -- (default: ``'real'``) topological field giving the vector space structure to the fibers - - ``latex_name`` -- optional LaTeX name for the total space + - ``latex_name`` -- (optional) LaTeX name for the total space OUTPUT: @@ -1104,7 +1096,6 @@ class as the manifold. sage: M.vector_bundle(2, 'E') Differentiable real vector bundle E -> M of rank 2 over the base space 2-dimensional differentiable manifold M - """ from sage.manifolds.differentiable.vector_bundle \ import DifferentiableVectorBundle @@ -1135,7 +1126,6 @@ def tangent_bundle(self, dest_map=None): sage: M = Manifold(2, 'M') sage: TM = M.tangent_bundle(); TM Tangent bundle TM over the 2-dimensional differentiable manifold M - """ return self.tensor_bundle(1, 0, dest_map=dest_map) @@ -1164,7 +1154,6 @@ def cotangent_bundle(self, dest_map=None): sage: cTM = M.cotangent_bundle(); cTM Cotangent bundle T*M over the 2-dimensional differentiable manifold M - """ return self.tensor_bundle(0, 1, dest_map=dest_map) @@ -1215,7 +1204,6 @@ def tensor_bundle(self, k, l, dest_map=None): :class:`~sage.manifolds.differentiable.vector_bundle.TensorBundle` for more examples and documentation. - """ if dest_map is None: dest_map = self.identity_map() @@ -1251,7 +1239,7 @@ def vector_field_module( identity map (case of vector fields *on* `M`), otherwise ``dest_map`` must be a :class:`~sage.manifolds.differentiable.diff_map.DiffMap` - - ``force_free`` -- (default: ``False``) if set to ``True``, force + - ``force_free`` -- boolean (default: ``False``); if set to ``True``, force the construction of a *free* module (this implies that `N` is parallelizable) @@ -1377,7 +1365,6 @@ def vector_field_module( True sage: M.is_manifestly_parallelizable() True - """ from sage.manifolds.differentiable.vectorfield_module import \ VectorFieldModule, VectorFieldFreeModule @@ -1450,7 +1437,6 @@ def tensor_field_module(self, tensor_type, dest_map=None): 3-dimensional differentiable manifold M sage: TU.an_element().display() 2 ∂/∂x⊗∂/∂x⊗dx - """ return self.vector_field_module(dest_map=dest_map).tensor_module(*tensor_type) @@ -1509,7 +1495,6 @@ def diff_form_module(self, degree, dest_map=None): sage: M.diff_form_module(2) is M.diff_form_module(2) True - """ return self.vector_field_module(dest_map=dest_map).dual_exterior_power(degree) @@ -1558,7 +1543,6 @@ def mixed_form_algebra(self, dest_map=None): sage: M.mixed_form_algebra() is M.mixed_form_algebra() True - """ vmodule = self.vector_field_module(dest_map=dest_map) return MixedFormAlgebra(vmodule) @@ -1621,7 +1605,6 @@ def multivector_module(self, degree, dest_map=None): sage: M.multivector_module(2) is M.multivector_module(2) True - """ return self.vector_field_module(dest_map=dest_map).exterior_power(degree) @@ -1771,7 +1754,6 @@ def vector_field(self, *comp, **kwargs): For more examples, see :class:`~sage.manifolds.differentiable.vectorfield.VectorField` and :class:`~sage.manifolds.differentiable.vectorfield.VectorFieldParal`. - """ name = kwargs.pop('name', None) latex_name = kwargs.pop('latex_name', None) @@ -1791,7 +1773,7 @@ def tensor_field(self, *args, **kwargs): take its values on another manifold. More precisely, if `M` is the current manifold, `N` a differentiable manifold, `\Phi:\ M \rightarrow N` a differentiable map and `(k,l)` - a pair of non-negative integers, a *tensor field of type* `(k,l)` + a pair of nonnegative integers, a *tensor field of type* `(k,l)` *along* `M` *with values on* `N` is a differentiable map .. MATH:: @@ -1890,7 +1872,6 @@ def tensor_field(self, *args, **kwargs): For more examples, see :class:`~sage.manifolds.differentiable.tensorfield.TensorField` and :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal`. - """ k = args[0] l = args[1] @@ -2057,7 +2038,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` sage: s2[:] [-1 -1] [ 3 10] - """ name = kwargs.pop('name', None) latex_name = kwargs.pop('latex_name', None) @@ -2078,7 +2058,7 @@ def multivector_field(self, *args, **kwargs): multivector field take its values on another manifold. More precisely, if `M` is the current manifold, `N` a differentiable manifold, `\Phi:\ M \rightarrow N` a differentiable map and `p` - a non-negative integer, a *multivector field of degree* `p` (or + a nonnegative integer, a *multivector field of degree* `p` (or `p`-*vector field*) *along* `M` *with values on* `N` is a differentiable map @@ -2162,7 +2142,6 @@ def multivector_field(self, *args, **kwargs): :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorField` and :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal`. - """ degree = args[0] name = kwargs.pop('name', None) @@ -2184,7 +2163,7 @@ def diff_form(self, *args, **kwargs) -> DiffForm: differential form take its values on another manifold. More precisely, if `M` is the current manifold, `N` a differentiable manifold, `\Phi:\ M \rightarrow N` a differentiable map and `p` - a non-negative integer, a *differential form of degree* `p` (or + a nonnegative integer, a *differential form of degree* `p` (or `p`-*form*) *along* `M` *with values on* `N` is a differentiable map @@ -2266,7 +2245,6 @@ def diff_form(self, *args, **kwargs) -> DiffForm: For more examples, see :class:`~sage.manifolds.differentiable.diff_form.DiffForm` and :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`. - """ degree = args[0] name = kwargs.pop('name', None) @@ -2364,7 +2342,6 @@ def one_form(self, *comp, **kwargs) -> DiffForm: For more examples, see :class:`~sage.manifolds.differentiable.diff_form.DiffForm` and :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`. - """ name = kwargs.pop('name', None) latex_name = kwargs.pop('latex_name', None) @@ -2444,7 +2421,6 @@ def mixed_form(self, comp=None, name=None, latex_name=None, dest_map=None): See the documentation of class :class:`~sage.manifolds.differentiable.mixed_form.MixedForm` for more examples. - """ algebra = self.mixed_form_algebra(dest_map=dest_map) resu = algebra.element_class(algebra, name=name, latex_name=latex_name) @@ -2472,7 +2448,6 @@ def symplectic_form( sage: omega.set_comp()[1,2] = -1 sage: omega.display() omega = -dq∧dp - """ return self.vector_field_module().symplectic_form(name, latex_name) @@ -2496,7 +2471,6 @@ def poisson_tensor( sage: poisson.set_comp()[1,2] = -1 sage: poisson.display() varpi = -e_q∧e_p - """ return self.vector_field_module().poisson_tensor(name, latex_name) @@ -2591,7 +2565,6 @@ def automorphism_field(self, *comp, **kwargs): :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField` and :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`. - """ name = kwargs.pop('name', None) latex_name = kwargs.pop('latex_name', None) @@ -2668,7 +2641,6 @@ def tangent_identity_field(self, dest_map=None): For more examples, see :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`. - """ vmodule = self.vector_field_module(dest_map) return vmodule.identity_map() @@ -2722,7 +2694,6 @@ def set_orientation(self, orientation): sage: M.orientation() [Coordinate frame (U, (∂/∂x,∂/∂y)), Coordinate frame (V, (∂/∂u,∂/∂v))] - """ from .vectorframe import VectorFrame chart_type = self._structure.chart @@ -2818,7 +2789,6 @@ def orientation(self): sage: W = U.intersection(V, name='W') sage: W.orientation() [Vector frame (W, (∂/∂x,∂/∂y))] - """ if not self._orientation: # try to get an orientation from super domains: @@ -2873,7 +2843,6 @@ def default_frame(self): sage: c_xy. = M.chart() sage: M.default_frame() Coordinate frame (M, (∂/∂x,∂/∂y)) - """ return self._def_frame @@ -2899,7 +2868,6 @@ def set_default_frame(self, frame): sage: M.set_default_frame(e) sage: M.default_frame() Vector frame (M, (e_0,e_1)) - """ from sage.manifolds.differentiable.vectorframe import VectorFrame if not isinstance(frame, VectorFrame): @@ -2969,7 +2937,6 @@ def change_of_frame(self, frame1, frame2): sage: M.change_of_frame(c_xy.frame(), c_uv.frame()) is \ ....: XM.change_of_basis(c_xy.frame(), c_uv.frame()) True - """ if (frame1, frame2) not in self._frame_changes: raise ValueError("the change of frame from {} to {}".format(frame1, frame2) + @@ -2991,7 +2958,7 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal` describing the automorphism `P` that relates the basis `(e_i)` to the basis `(f_i)` according to `f_i = P(e_i)` - - ``compute_inverse`` (default: ``True``) -- if set to True, the inverse + - ``compute_inverse`` -- boolean (default: ``True``); if set to True, the inverse automorphism is computed and the change from basis `(f_i)` to `(e_i)` is set to it in the internal dictionary ``self._frame_changes`` @@ -3017,7 +2984,6 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, sage: M.change_of_frame(e,f)[e,:] [1 2] [0 3] - """ from sage.manifolds.differentiable.automorphismfield import AutomorphismFieldParal fmodule = frame1._fmodule @@ -3172,7 +3138,6 @@ def vector_frame(self, *args, **kwargs) -> VectorFrame: For more options, in particular for the choice of symbols and indices, see :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`. - """ from sage.manifolds.differentiable.vectorframe import VectorFrame # Input processing @@ -3241,7 +3206,6 @@ def _set_covering_frame(self, frame): sage: M._set_covering_frame(e) sage: M._covering_frames [Vector frame (M, (e_0,e_1))] - """ self._covering_frames.append(frame) self._parallelizable_parts = set([self]) @@ -3254,9 +3218,7 @@ def frames(self): r""" Return the list of vector frames defined on open subsets of ``self``. - OUTPUT: - - - list of vector frames defined on open subsets of ``self`` + OUTPUT: list of vector frames defined on open subsets of ``self`` EXAMPLES: @@ -3277,7 +3239,6 @@ def frames(self): [Coordinate frame (R^2, (∂/∂x,∂/∂y)), Vector frame (R^2, (e_0,e_1)), Coordinate frame (U, (∂/∂x,∂/∂y))] - """ return list(self._frames) @@ -3285,9 +3246,7 @@ def coframes(self): r""" Return the list of coframes defined on open subsets of ``self``. - OUTPUT: - - - list of coframes defined on open subsets of ``self`` + OUTPUT: list of coframes defined on open subsets of ``self`` EXAMPLES: @@ -3312,7 +3271,6 @@ def coframes(self): Coframe (R^2, (e^0,e^1)), Coordinate coframe (U, (dx,dy)), Coframe (U, (e^0,e^1))] - """ return list(self._coframes) @@ -3364,7 +3322,6 @@ def changes_of_frame(self): True sage: M.changes_of_frame()[(f,e)] == a^(-1) True - """ return self._frame_changes.copy() @@ -3397,7 +3354,6 @@ def is_manifestly_parallelizable(self): sage: X. = N.chart() sage: N.is_manifestly_parallelizable() True - """ return bool(self._covering_frames) @@ -3437,7 +3393,6 @@ def tangent_space(self, point, base_ring=None): :class:`~sage.manifolds.differentiable.tangent_space.TangentSpace` for more examples. - """ from sage.manifolds.point import ManifoldPoint from sage.manifolds.differentiable.tangent_space import TangentSpace @@ -3470,7 +3425,7 @@ def curve(self, coord_expression, param, chart=None, in both cases, if the dimension of the manifold is 1, a single coordinate expression can be passed instead of a tuple with a single element - - ``param`` -- a tuple of the type ``(t, t_min, t_max)``, where + - ``param`` -- tuple of the type ``(t, t_min, t_max)``, where * ``t`` is the curve parameter used in ``coord_expression``; * ``t_min`` is its minimal value; @@ -3486,9 +3441,7 @@ def curve(self, coord_expression, param, chart=None, - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the curve; if none is provided, ``name`` will be used - OUTPUT: - - - :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` EXAMPLES: @@ -3520,7 +3473,6 @@ def curve(self, coord_expression, param, chart=None, :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` for more examples, including plots. - """ from sage.manifolds.differentiable.examples.real_line import RealLine if not isinstance(param, (tuple, list)): @@ -3566,7 +3518,7 @@ def integrated_curve(self, equations_rhs, velocities, curve_param, equations on the velocities only - ``velocities`` -- list of the symbolic expressions used in ``equations_rhs`` to denote the velocities - - ``curve_param`` -- a tuple of the type ``(t, t_min, t_max)``, + - ``curve_param`` -- tuple of the type ``(t, t_min, t_max)``, where * ``t`` is the symbolic variable used in ``equations_rhs`` to @@ -3584,9 +3536,7 @@ def integrated_curve(self, equations_rhs, velocities, curve_param, - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the curve; if none is provided, ``name`` will be used - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve` EXAMPLES: @@ -3640,7 +3590,6 @@ def integrated_curve(self, equations_rhs, velocities, curve_param, by default... sage: tgt_vec[:] # abs tol 1e-12 [-0.8481007454066425, 0.5298350137284363, 1.0] - """ from sage.manifolds.differentiable.examples.real_line import RealLine @@ -3679,7 +3628,7 @@ def integrated_autoparallel_curve(self, affine_connection, - ``affine_connection`` -- :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection`; affine connection with respect to which the curve is autoparallel - - ``curve_param`` -- a tuple of the type ``(t, t_min, t_max)``, + - ``curve_param`` -- tuple of the type ``(t, t_min, t_max)``, where * ``t`` is the symbolic variable to be used as the parameter @@ -3700,9 +3649,7 @@ def integrated_autoparallel_curve(self, affine_connection, - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the curve; if none is provided, ``name`` will be used - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve` EXAMPLES: @@ -3775,7 +3722,6 @@ def integrated_autoparallel_curve(self, affine_connection, by default... sage: tgt_vec[:] # abs tol 1e-12 [1.000000000000011, 1.148779968412235] - """ from sage.manifolds.differentiable.examples.real_line import RealLine @@ -3816,7 +3762,7 @@ def integrated_geodesic(self, metric, curve_param, - ``metric`` -- :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` metric with respect to which the curve is a geodesic - - ``curve_param`` -- a tuple of the type ``(t, t_min, t_max)``, + - ``curve_param`` -- tuple of the type ``(t, t_min, t_max)``, where * ``t`` is the symbolic variable to be used as the parameter @@ -3837,9 +3783,7 @@ def integrated_geodesic(self, metric, curve_param, - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the curve; if none is provided, ``name`` will be used - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic` EXAMPLES: @@ -3897,7 +3841,6 @@ def integrated_geodesic(self, metric, curve_param, by default... sage: tgt_vec[:] # abs tol 1e-12 [-1.0907409234671228, 0.6205670379855032] - """ from sage.manifolds.differentiable.examples.real_line import RealLine from sage.manifolds.differentiable.manifold_homset import IntegratedGeodesicSet @@ -3949,7 +3892,6 @@ def affine_connection(self, name, latex_name=None): :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection` for more examples. - """ from sage.manifolds.differentiable.affine_connection import \ AffineConnection @@ -4002,7 +3944,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` for more examples. - """ vmodule = self.vector_field_module(dest_map) return vmodule.metric(name, signature=signature, latex_name=latex_name) @@ -4062,7 +4003,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` :class:`~sage.manifolds.differentiable.metric.DegenerateMetric` for more examples. - """ vmodule = self.vector_field_module(dest_map) dim = vmodule.ambient_domain().dimension() @@ -4115,7 +4055,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` for more examples. - """ vmodule = self.vector_field_module(dest_map) dim = vmodule.ambient_domain().dimension() @@ -4137,7 +4076,7 @@ def lorentzian_metric(self, name, signature='positive', latex_name=None, INPUT: - ``name`` -- name given to the metric - - ``signature`` -- (default: 'positive') sign of the metric + - ``signature`` -- (default: ``'positive'``) sign of the metric signature: * if set to 'positive', the signature is n-2, where n is the @@ -4181,7 +4120,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` g = dt⊗dt - dx⊗dx - dy⊗dy - dz⊗dz sage: g.signature() -2 - """ vmodule = self.vector_field_module(dest_map) dim = vmodule.ambient_domain().dimension() @@ -4217,7 +4155,6 @@ def tangent_vector(self, *args, **kwargs): - :class:`~sage.manifolds.differentiable.tangent_vector.TangentVector` representing the tangent vector at point `p` - EXAMPLES: Vector at a point `p` of the Euclidean plane:: @@ -4282,7 +4219,6 @@ def tangent_vector(self, *args, **kwargs): Traceback (most recent call last): ... ValueError: 2 components must be provided - """ basis = kwargs.pop('basis', None) name = kwargs.pop('name', None) diff --git a/src/sage/manifolds/differentiable/manifold_homset.py b/src/sage/manifolds/differentiable/manifold_homset.py index 90759e74afa..d26e1cfea91 100644 --- a/src/sage/manifolds/differentiable/manifold_homset.py +++ b/src/sage/manifolds/differentiable/manifold_homset.py @@ -49,6 +49,7 @@ from sage.manifolds.differentiable.integrated_curve import IntegratedAutoparallelCurve from sage.manifolds.differentiable.integrated_curve import IntegratedGeodesic + class DifferentiableManifoldHomset(TopologicalManifoldHomset): r""" Set of differentiable maps between two differentiable manifolds. @@ -153,7 +154,6 @@ class DifferentiableManifoldHomset(TopologicalManifoldHomset): This test suite includes more tests than in the case of ``H``, since ``E`` has some extra structure (monoid). - """ Element = DiffMap @@ -179,7 +179,6 @@ def __init__(self, domain, codomain, name=None, latex_name=None): 2-dimensional differentiable manifold M in Category of smooth manifolds over Real Field with 53 bits of precision sage: TestSuite(E).run() - """ from sage.manifolds.differentiable.manifold import \ DifferentiableManifold @@ -211,7 +210,6 @@ def _coerce_map_from_(self, other): False sage: H._coerce_map_from_(N) False - """ #!# for the time being: return False @@ -368,7 +366,6 @@ class DifferentiableCurveSet(DifferentiableManifoldHomset): The test suite is passed by ``EI``:: sage: TestSuite(EI).run() - """ Element = DifferentiableCurve @@ -405,7 +402,6 @@ def __init__(self, domain, codomain, name=None, latex_name=None): manifolds over Real Field with 53 bits of precision and Category of connected manifolds over Real Field with 53 bits of precision sage: TestSuite(H).run() - """ from sage.manifolds.differentiable.examples.real_line import OpenInterval if not isinstance(domain, OpenInterval): @@ -423,9 +419,7 @@ def _element_constructor_(self, coord_expression, name=None, `I \to M`, where `I` is a real interval and `M` some differentiable manifold. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` EXAMPLES:: @@ -438,7 +432,6 @@ def _element_constructor_(self, coord_expression, name=None, Curve c in the 2-dimensional differentiable manifold M sage: c = Hom(R, R)({}, is_identity=True) ; c Identity map Id_ℝ of the Real number line ℝ - """ # Standard construction return self.element_class(self, coord_expression=coord_expression, @@ -450,9 +443,7 @@ def _an_element_(self): r""" Construct some element of ``self``. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve` EXAMPLES:: @@ -481,7 +472,6 @@ def _an_element_(self): sage: c.display() (0, pi) → (0, pi) t ↦ 1/4*pi + 1/2*pi/(t^2 + 1) - """ from sage.rings.infinity import Infinity from sage.rings.rational_field import QQ @@ -519,6 +509,7 @@ def _an_element_(self): #****************************************************************************** + class IntegratedCurveSet(DifferentiableCurveSet): r""" Set of integrated curves in a differentiable manifold. @@ -693,7 +684,6 @@ class IntegratedCurveSet(DifferentiableCurveSet): skipped for reasons mentioned above:: sage: TestSuite(H).run(skip=["_test_one", "_test_prod"]) - """ Element = IntegratedCurve @@ -724,7 +714,6 @@ def __init__(self, domain, codomain, name=None, latex_name=None): (-1, 2) in Category of endsets of subobjects of sets and topological spaces which actually are integrated curves sage: TestSuite(H).run(skip=["_test_one", "_test_prod"]) - """ from sage.rings.infinity import Infinity @@ -768,7 +757,6 @@ def _repr_(self): Set of Morphisms from Real interval (-1, 2) to 3-dimensional differentiable manifold M in Category of homsets of topological spaces which actually are integrated curves - """ description = "Set of Morphisms " description += "from {} to {} in {} ".format(self._domain, @@ -784,9 +772,7 @@ def _element_constructor_(self, equations_rhs, velocities, `I \to M`, where `I` is a real interval and `M` some differentiable manifold. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve` EXAMPLES:: @@ -805,7 +791,6 @@ def _element_constructor_(self, equations_rhs, velocities, sage: c = H(eqns_rhs, vels, t, v, name='c') ; c Integrated curve c in the 2-dimensional differentiable manifold M - """ # Standard construction return self.element_class(self, equations_rhs, velocities, @@ -816,9 +801,7 @@ def _an_element_(self): r""" Construct some element of ``self``. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve` EXAMPLES:: @@ -876,7 +859,6 @@ def _an_element_(self): Point on the Real number line ℝ sage: p.coordinates() # abs tol 1e-12 (0.8409865343211089,) - """ from sage.categories.homset import Hom @@ -971,7 +953,6 @@ def one(self): ... ValueError: the identity is not implemented for integrated curves and associated subclasses - """ if self.codomain() != self.domain(): @@ -983,6 +964,7 @@ def one(self): #****************************************************************************** + class IntegratedAutoparallelCurveSet(IntegratedCurveSet): r""" Set of integrated autoparallel curves in a differentiable manifold. @@ -1130,7 +1112,6 @@ class IntegratedAutoparallelCurveSet(IntegratedCurveSet): skipped for reasons mentioned above:: sage: TestSuite(H).run(skip=["_test_one", "_test_prod"]) - """ Element = IntegratedAutoparallelCurve @@ -1164,7 +1145,6 @@ def __init__(self, domain, codomain, name=None, latex_name=None): topological spaces which actually are integrated autoparallel curves with respect to a certain affine connection sage: TestSuite(H).run(skip=["_test_one", "_test_prod"]) - """ from sage.rings.infinity import Infinity @@ -1209,7 +1189,6 @@ def _repr_(self): differentiable manifold M in Category of homsets of topological spaces which actually are integrated autoparallel curves with respect to a certain affine connection - """ description = "Set of Morphisms " @@ -1227,9 +1206,7 @@ def _element_constructor_(self, affine_connection, curve_parameter, autoparallel curve `I \to M`, where `I` is a real interval and `M` some differentiable manifold. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve` EXAMPLES:: @@ -1250,7 +1227,6 @@ def _element_constructor_(self, affine_connection, curve_parameter, sage: c = H(nab, t, v, name='c') ; c Integrated autoparallel curve c in the 2-dimensional differentiable manifold M - """ # Standard construction return self.element_class(self, affine_connection, @@ -1261,9 +1237,7 @@ def _an_element_(self): r""" Construct some element of ``self``. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve` EXAMPLES:: @@ -1329,7 +1303,6 @@ def _an_element_(self): Point on the Real number line ℝ sage: p.coordinates() # abs tol 1e-12 (1.0565635217644918,) - """ from sage.rings.infinity import Infinity @@ -1445,6 +1418,7 @@ def _an_element_(self): #****************************************************************************** + class IntegratedGeodesicSet(IntegratedAutoparallelCurveSet): r""" Set of integrated geodesic in a differentiable manifold. @@ -1586,7 +1560,6 @@ class IntegratedGeodesicSet(IntegratedAutoparallelCurveSet): skipped for reasons mentioned above:: sage: TestSuite(H).run(skip=["_test_one", "_test_prod"]) - """ Element = IntegratedGeodesic @@ -1620,7 +1593,6 @@ def __init__(self, domain, codomain, name=None, latex_name=None): topological spaces which actually are integrated geodesics with respect to a certain metric sage: TestSuite(H).run(skip=["_test_one", "_test_prod"]) - """ from sage.rings.infinity import Infinity @@ -1664,7 +1636,6 @@ def _repr_(self): differentiable manifold M in Category of homsets of topological spaces which actually are integrated geodesics with respect to a certain metric - """ description = "Set of Morphisms " description += "from {} to {} in {} ".format(self._domain, @@ -1681,9 +1652,7 @@ def _element_constructor_(self, metric, curve_parameter, `I \to M`, where `I` is a real interval and `M` some differentiable manifold. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic` EXAMPLES:: @@ -1702,7 +1671,6 @@ def _element_constructor_(self, metric, curve_parameter, sage: c = H(g, t, v, name='c') ; c Integrated geodesic c in the 2-dimensional differentiable manifold M - """ # Standard construction return self.element_class(self, metric, curve_parameter, @@ -1713,9 +1681,7 @@ def _an_element_(self): r""" Construct some element of ``self``. - OUTPUT: - - - :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic` + OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic` EXAMPLES:: @@ -1785,7 +1751,6 @@ def _an_element_(self): Point on the Real number line ℝ sage: p.coordinates() # abs tol 1e-12 (1.0565635217644918,) - """ from sage.categories.homset import Hom diff --git a/src/sage/manifolds/differentiable/metric.py b/src/sage/manifolds/differentiable/metric.py index 4b4c6cf1a37..e25033a8cb7 100644 --- a/src/sage/manifolds/differentiable/metric.py +++ b/src/sage/manifolds/differentiable/metric.py @@ -333,7 +333,6 @@ class PseudoRiemannianMetric(TensorField): sage: delta = M.tangent_identity_field() sage: riem == - r*(g*delta).antisymmetrize(2,3) True - """ _derived_objects = ('_connection', '_ricci_scalar', '_weyl', '_schouten', '_cotton', '_cotton_york') @@ -370,7 +369,6 @@ def __init__(self, vector_field_module, name, signature=None, - fix _test_pickling (in the superclass TensorField) - add a specific parent to the metrics, to fit with the category framework - """ TensorField.__init__(self, vector_field_module, (0,2), name=name, latex_name=latex_name, sym=(0,1)) @@ -411,7 +409,6 @@ def _repr_(self): sage: g = M.metric('g', signature=1) sage: g._repr_() 'Pseudo-Riemannian metric g on the 5-dimensional differentiable manifold M' - """ n = self._ambient_domain.dimension() s = self._signature @@ -442,7 +439,6 @@ def _new_instance(self): True sage: g1.signature() == g.signature() True - """ return type(self)(self._vmodule, 'unnamed metric', signature=self._signature, @@ -457,7 +453,6 @@ def _init_derived(self): sage: M = Manifold(5, 'M') sage: g = M.metric('g') sage: g._init_derived() - """ # Initialization of quantities pertaining to the mother class: TensorField._init_derived(self) @@ -482,7 +477,6 @@ def _del_derived(self): sage: M = Manifold(5, 'M') sage: g = M.metric('g') sage: g._del_derived() - """ # First the derived quantities from the mother class are deleted: TensorField._del_derived(self) @@ -507,7 +501,6 @@ def _del_inverse(self): sage: M = Manifold(5, 'M') sage: g = M.metric('g') sage: g._del_inverse() - """ self._inverse._restrictions.clear() self._inverse._del_derived() @@ -534,7 +527,6 @@ def signature(self): sage: h = M.metric('h', signature=0) sage: h.signature() 0 - """ return self._signature @@ -552,7 +544,7 @@ def restrict(self, subdomain, dest_map=None): `\Phi:\ U \rightarrow V`, where `V` is a subdomain of ``self._codomain`` (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) - If None, the restriction of ``self._vmodule._dest_map`` to `U` is + If ``None``, the restriction of ``self._vmodule._dest_map`` to `U` is used. OUTPUT: @@ -573,7 +565,6 @@ def restrict(self, subdomain, dest_map=None): See the top documentation of :class:`PseudoRiemannianMetric` for more examples. - """ if subdomain == self._domain: return self @@ -603,7 +594,7 @@ def restrict(self, subdomain, dest_map=None): def set(self, symbiform): r""" - Defines the metric from a field of symmetric bilinear forms + Define the metric from a field of symmetric bilinear forms. INPUT: @@ -640,7 +631,6 @@ def set(self, symbiform): sage: g.display(eV) g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv - """ if not isinstance(symbiform, TensorField): raise TypeError("the argument must be a tensor field") @@ -719,7 +709,6 @@ def inverse(self, expansion_symbol=None, order=1): Tensor field of type (1,1) on the 2-dimensional differentiable manifold S^2 sage: s == M.tangent_identity_field() True - """ # Is the inverse metric up to date? for dom, rst in self._restrictions.items(): @@ -744,7 +733,7 @@ def connection(self, name=None, latex_name=None, init_coef=True): Levi-Civita connection; if ``None``, it is set to ``name``, or if the latter is None as well, it formed from the symbol `\nabla` and the metric symbol - - ``init_coef`` -- (default: ``True``) determines whether the + - ``init_coef`` -- boolean (default: ``True``); determines whether the connection coefficients are initialized, as Christoffel symbols in the top charts of the domain of ``self`` (i.e. disregarding the subcharts) @@ -794,7 +783,6 @@ def connection(self, name=None, latex_name=None, init_coef=True): the 3-dimensional differentiable manifold R^3 sage: Dig == 0 True - """ from sage.manifolds.differentiable.levi_civita_connection import \ LeviCivitaConnection @@ -868,8 +856,6 @@ def christoffel_symbols(self, chart=None): Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,ph = 1/r Gam^ph_th,ph = cos(th)/sin(th) - - """ if chart is None: frame = self._domain._def_chart._frame @@ -905,11 +891,11 @@ def christoffel_symbols_display(self, chart=None, symbol=None, representing the LaTeX labels of each index; if ``None``, coordinate LaTeX symbols are used, except if ``coordinate_symbols`` is set to ``False``, in which case integer labels are used - - ``coordinate_labels`` -- (default: ``True``) boolean; if ``True``, + - ``coordinate_labels`` -- boolean (default: ``True``); if ``True``, coordinate symbols are used by default (instead of integers) - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero connection coefficients are displayed - - ``only_nonredundant`` -- (default: ``True``) boolean; if ``True``, + - ``only_nonredundant`` -- boolean (default: ``True``); if ``True``, only nonredundant (w.r.t. the symmetry of the last two indices) connection coefficients are displayed @@ -979,7 +965,6 @@ def christoffel_symbols_display(self, chart=None, symbol=None, Gam^2_33 = -cos(th)*sin(th) Gam^3_13 = 1/r Gam^3_23 = cos(th)/sin(th) - """ if chart is None: chart = self._domain.default_chart() @@ -1062,7 +1047,6 @@ def riemann(self, name=None, latex_name=None): [[0, sin(2*th)/(2*tan(th)) - cos(2*th)], [-sin(2*th)/(2*tan(th)) + cos(2*th), 0]]], [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]] - """ return self.connection().riemann(name, latex_name) @@ -1116,7 +1100,6 @@ def ricci(self, name=None, latex_name=None): [ 0 sin(th)^2] sage: g.ricci() == a^(-2) * g True - """ return self.connection().ricci(name, latex_name) @@ -1283,7 +1266,6 @@ def schouten(self, name=None, latex_name=None): sage: g.schouten().display() Schouten(g) = -3/8 dx⊗dx + (5/8*x^2 - 3/8) dy⊗dy - 5/8*x dy⊗dz - 5/8*x dz⊗dy + 5/8 dz⊗dz - """ n = self._ambient_domain.dimension() if n < 3: @@ -1341,7 +1323,6 @@ def cotton(self, name=None, latex_name=None): 3-dimensional differentiable manifold H^3 sage: Cot == 0 # long time True - """ n = self._ambient_domain.dimension() if n < 3: @@ -1401,7 +1382,6 @@ def cotton_york(self, name=None, latex_name=None): CY(g) = 1/2 dx⊗dx + (-x^2 + 1/2) dy⊗dy + x dy⊗dz + x dz⊗dy - dz⊗dz sage: det(CY[:]) # long time -1/4 - """ n = self._ambient_domain.dimension() if n != 3: @@ -1493,7 +1473,6 @@ def determinant(self, frame=None): sage: s = g.determinant() # determinant in M's default frame sage: s.expr() -x**2*y**2 + x - y*(x + 1) + 1 - """ from sage.matrix.constructor import matrix dom = self._domain @@ -1601,7 +1580,6 @@ def sqrt_abs_det(self, frame=None): sqrt(-x**2*y**2 - x*y + x - y + 1)/2 sage: g.sqrt_abs_det(Y.frame()).expr(Y) sqrt(-u**4 + 2*u**2*v**2 - 4*u**2 - v**4 + 4*v**2 + 16*v + 16)/8 - """ dom = self._domain if frame is None: @@ -1771,7 +1749,6 @@ def volume_form(self, contra=0): Note the minus sign in the above expression, reflecting the fact that ``eV`` is left-handed with respect to the chosen orientation. - """ dom = self._domain orient = dom.orientation() @@ -1830,7 +1807,7 @@ def hodge_star(self, pform: DiffForm) -> DiffForm: INPUT: - - ``pform``: a `p`-form `A`; must be an instance of + - ``pform`` -- a `p`-form `A`; must be an instance of :class:`~sage.manifolds.differentiable.scalarfield.DiffScalarField` for `p=0` and of :class:`~sage.manifolds.differentiable.diff_form.DiffForm` or @@ -1971,7 +1948,6 @@ def hodge_star(self, pform: DiffForm) -> DiffForm: sage: epsilon = g.volume_form() sage: g.hodge_star(a.wedge(b)) == epsilon.contract(0,a.up(g)).contract(0,b.up(g)) True - """ return pform.hodge_dual(self) @@ -2097,7 +2073,6 @@ class PseudoRiemannianMetricParal(PseudoRiemannianMetric, TensorFieldParal): inv_g = (x - 1)/(x^2*y^2 + x^2 - 1) ∂/∂x⊗∂/∂x + x*y/(x^2*y^2 + x^2 - 1) ∂/∂x⊗∂/∂y + x*y/(x^2*y^2 + x^2 - 1) ∂/∂y⊗∂/∂x - (x + 1)/(x^2*y^2 + x^2 - 1) ∂/∂y⊗∂/∂y - """ def __init__(self, vector_field_module, name, signature=None, latex_name=None): @@ -2120,7 +2095,6 @@ def __init__(self, vector_field_module, name, signature=None, - add a specific parent to the metrics, to fit with the category framework - """ TensorFieldParal.__init__(self, vector_field_module, (0,2), name=name, latex_name=latex_name, sym=(0,1)) @@ -2155,7 +2129,6 @@ def _init_derived(self): sage: X. = M.chart() # makes M parallelizable sage: g = M.metric('g') sage: g._init_derived() - """ # Initialization of quantities pertaining to the mother classes: TensorFieldParal._init_derived(self) @@ -2167,8 +2140,8 @@ def _del_derived(self, del_restrictions=True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the - restrictions of ``self`` to subdomains are deleted. + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the + restrictions of ``self`` to subdomains are deleted TESTS:: @@ -2177,7 +2150,6 @@ def _del_derived(self, del_restrictions=True): sage: g = M.metric('g') sage: g._del_derived(del_restrictions=False) sage: g._del_derived() - """ # The derived quantities from the mother classes are deleted: TensorFieldParal._del_derived(self, del_restrictions=del_restrictions) @@ -2193,7 +2165,6 @@ def _del_inverse(self): sage: X. = M.chart() # makes M parallelizable sage: g = M.metric('g') sage: g._del_inverse() - """ self._inverse._components.clear() self._inverse._del_derived() @@ -2213,7 +2184,7 @@ def restrict(self, subdomain, dest_map=None): `\Phi:\ U \rightarrow V`, where `V` is a subdomain of ``self._codomain`` (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) - If None, the restriction of ``self._vmodule._dest_map`` to `U` is + If ``None``, the restriction of ``self._vmodule._dest_map`` to `U` is used. OUTPUT: @@ -2237,7 +2208,6 @@ def restrict(self, subdomain, dest_map=None): 0 sage: gU.display() g = -dx⊗dx + dy⊗dy - """ if subdomain == self._domain: return self @@ -2287,7 +2257,6 @@ def set(self, symbiform): sage: g.set(s) sage: g.display() g = (x^2 + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (y^2 + 1) dy⊗dy - """ if not isinstance(symbiform, TensorFieldParal): raise TypeError("the argument must be a tensor field with " + @@ -2407,7 +2376,6 @@ def inverse(self, expansion_symbol=None, order=1): [ e 1 -e 0] [ 0 -e 1 -e] [ 0 0 -e 1] - """ if expansion_symbol is not None: if (self._inverse is not None and bool(self._inverse._components) @@ -2616,7 +2584,6 @@ class DegenerateMetric(TensorField): sage: g(v, v).disp() M → ℝ (x, y, z) ↦ 0 - """ def __init__(self, vector_field_module, name, signature=None, @@ -2641,8 +2608,6 @@ def __init__(self, vector_field_module, name, signature=None, sage: g.disp(e) g = (2*m/r - 1) dt⊗dt + 2*m/r dt⊗dr + 2*m/r dr⊗dt + (2*m/r + 1) dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph - - """ TensorField.__init__(self, vector_field_module, (0,2), name=name, latex_name=latex_name, sym=(0,1)) @@ -2676,7 +2641,6 @@ def _repr_(self): sage: g = M.metric('g', signature=(1,1,1)) sage: g._repr_() 'degenerate metric g on the 3-dimensional differentiable manifold M' - """ return self._final_repr("degenerate metric "+self._name + " ") @@ -2697,7 +2661,6 @@ def _new_instance(self): True sage: g1.signature() == g.signature() True - """ return type(self)(self._vmodule, 'unnamed metric', signature=self._signature, @@ -2725,13 +2688,12 @@ def signature(self): sage: g = M.metric() sage: g.signature() (0, 2, 1) - """ return self._signature def set(self, symbiform): r""" - Defines the metric from a field of symmetric bilinear forms + Define the metric from a field of symmetric bilinear forms. INPUT: @@ -2768,7 +2730,6 @@ def set(self, symbiform): sage: g.display(eV) g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv - """ if not isinstance(symbiform, TensorField): raise TypeError("the argument must be a tensor field") @@ -2802,7 +2763,7 @@ def restrict(self, subdomain, dest_map=None): `\Phi:\ U \rightarrow V`, where `V` is a subdomain of ``self._codomain`` (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) - If None, the restriction of ``self._vmodule._dest_map`` to `U` is + If ``None``, the restriction of ``self._vmodule._dest_map`` to `U` is used. OUTPUT: @@ -2823,7 +2784,6 @@ def restrict(self, subdomain, dest_map=None): See the top documentation of :class:`DegenerateMetric` for more examples. - """ if subdomain == self._domain: return self @@ -2840,7 +2800,7 @@ def restrict(self, subdomain, dest_map=None): def determinant(self): r""" - Determinant of a degenerate metric is always '0' + Determinant of a degenerate metric is always '0'. EXAMPLES:: @@ -2848,7 +2808,6 @@ def determinant(self): sage: g = S.metric('g', signature=([0,1,1])) sage: g.determinant() Scalar field zero on the 2-dimensional differentiable manifold S - """ return self._domain.zero_scalar_field() @@ -2932,7 +2891,6 @@ class DegenerateMetricParal(DegenerateMetric, TensorFieldParal): sage: g(v, v).disp() M → ℝ (x, y, z) ↦ 0 - """ def __init__(self, vector_field_module, name, signature=None, @@ -2958,8 +2916,6 @@ def __init__(self, vector_field_module, name, signature=None, + (x^2 + z^2)/(x^2 + y^2 + z^2) dy⊗dy - y*z/(x^2 + y^2 + z^2) dy⊗dz - x*z/(x^2 + y^2 + z^2) dz⊗dx - y*z/(x^2 + y^2 + z^2) dz⊗dy + (x^2 + y^2)/(x^2 + y^2 + z^2) dz⊗dz - - """ TensorFieldParal.__init__(self, vector_field_module, (0,2), name=name, latex_name=latex_name, sym=(0,1)) @@ -2983,7 +2939,7 @@ def __init__(self, vector_field_module, name, signature=None, def set(self, symbiform): r""" - Defines the metric from a field of symmetric bilinear forms + Define the metric from a field of symmetric bilinear forms. INPUT: @@ -3005,7 +2961,6 @@ def set(self, symbiform): sage: g.set(b) sage: g.display() g = dx⊗dx + dy⊗dy - """ if not isinstance(symbiform, TensorFieldParal): raise TypeError("the argument must be a tensor field with " + @@ -3038,7 +2993,7 @@ def restrict(self, subdomain, dest_map=None): `\Phi:\ U \rightarrow V`, where `V` is a subdomain of ``self._codomain`` (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) - If None, the restriction of ``self._vmodule._dest_map`` to `U` is + If ``None``, the restriction of ``self._vmodule._dest_map`` to `U` is used. OUTPUT: @@ -3058,7 +3013,6 @@ def restrict(self, subdomain, dest_map=None): See the top documentation of :class:`DegenerateMetric` for more examples. - """ if subdomain == self._domain: return self diff --git a/src/sage/manifolds/differentiable/mixed_form.py b/src/sage/manifolds/differentiable/mixed_form.py index 4ca5cf56c49..65e2a25891e 100644 --- a/src/sage/manifolds/differentiable/mixed_form.py +++ b/src/sage/manifolds/differentiable/mixed_form.py @@ -211,7 +211,6 @@ class MixedForm(AlgebraElement, ModuleElementWithMutability): Traceback (most recent call last): ... ValueError: the components of an immutable element cannot be changed - """ def __init__(self, parent, name=None, latex_name=None): r""" @@ -238,7 +237,6 @@ def __init__(self, parent, name=None, latex_name=None): sage: A = M.mixed_form_algebra() sage: F = A([x, omega, eta], name='F') sage: TestSuite(F).run(skip='_test_pickling') - """ if parent is None: raise ValueError("a parent must be provided") @@ -277,7 +275,6 @@ def _init_comp(self): [Scalar field A_0 on the 2-dimensional differentiable manifold M, 1-form A_1 on the 2-dimensional differentiable manifold M, 2-form A_2 on the 2-dimensional differentiable manifold M] - """ self._comp = [] for i in self.irange(): @@ -315,7 +312,6 @@ def _repr_(self): Mixed differential form one along the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 with values on the Euclidean space E^3 via the map iota - """ desc = "Mixed differential form " if self._name is not None: @@ -343,7 +339,6 @@ def _latex_(self): '\\omega' sage: latex(omega) # indirect doctest \omega - """ if self._name is None: return r'\text{' + repr(self) + r'}' @@ -365,7 +360,6 @@ def _new_instance(self, name=None, latex_name=None): True sage: F1.parent() is F.parent() True - """ return type(self)(self.parent(), name=name, latex_name=latex_name) @@ -417,7 +411,6 @@ def display_expansion(self, frame=None, chart=None, from_chart=None): F = (1/4*u + 1/4*v) du + (1/4*u + 1/4*v) dv + u*v du∧dv sage: F.display_expansion(e_xy) F = x dx + (2*x^2 - 2*y^2) dx∧dy - """ from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_wedge @@ -529,7 +522,6 @@ def display(self): manifold M sage: F.display() # display names of homogeneous components F = f + omega + eta - """ from sage.misc.latex import latex from sage.tensor.modules.format_utilities import FormattedExpansion @@ -574,8 +566,8 @@ def set_name(self, name=None, latex_name=None, apply_to_comp=True): - ``name`` -- (default: ``None``) name given to the mixed form - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the mixed form; if none is provided, the LaTeX symbol is set to ``name`` - - ``apply_to_comp`` -- (default: ``True``) if ``True`` all homogeneous - components will be renamed accordingly; if ``False`` only the mixed + - ``apply_to_comp`` -- boolean (default: ``True``); if ``True`` all homogeneous + components will be renamed accordingly. If ``False`` only the mixed form will be renamed EXAMPLES: @@ -665,7 +657,6 @@ def __bool__(self): True sage: F.is_zero() # indirect doctest False - """ if self._is_zero: return False @@ -683,7 +674,7 @@ def _richcmp_(self, other, op): - ``other`` -- a mixed form - ``op`` -- comparison operator for which ``self`` and ``other`` shall - be compared with. + be compared with TESTS:: @@ -712,14 +703,13 @@ def _richcmp_(self, other, op): sage: F == G # False since G has not been defined on V False sage: G.set_restriction(F.restrict(V)) - sage: F == G # True now + sage: F == G # ``True`` now True sage: H = M.mixed_form([f, 0, 0]) sage: F != H # this is fixed by issue #30108 True sage: F.parent().zero() == 0 True - """ from sage.structure.richcmp import op_NE, op_EQ if op == op_NE: @@ -787,7 +777,6 @@ def _add_(self, other): True sage: Z._add_(A) == A True - """ # Case zero: if self._is_zero: @@ -861,7 +850,6 @@ def _sub_(self, other): True sage: Z._sub_(A) == -A True - """ # Case zero: if self._is_zero: @@ -977,7 +965,6 @@ def wedge(self, other): x∧A = x^2 + x^2 dx + x*z dx∧dz sage: F = A*eta; F.display_expansion() A∧eta = x*y dy + x*y dx∧dy - y*z dx∧dy∧dz - """ # Case zero: if self._is_zero or other._is_zero: @@ -1029,7 +1016,6 @@ def _lmul_(self, other): differentiable manifold M sage: A.display_expansion() y∧(x∧F) = x^2*y^2 dx - """ try: if other.is_trivial_zero(): @@ -1108,7 +1094,6 @@ def exterior_derivative(self): sage: F.exterior_derivative() is dF True - """ resu = self._new_instance() resu[0] = self._domain.zero_scalar_field() @@ -1178,7 +1163,6 @@ def copy(self, name=None, latex_name=None): True sage: A is B False - """ resu = self._new_instance() resu._comp = [form.copy() for form in self] @@ -1189,7 +1173,7 @@ def copy(self, name=None, latex_name=None): def __setitem__(self, index, values): r""" - Sets a component with respect to some vector frame. + Set a component with respect to some vector frame. - ``index`` -- list of indices; if ``[:]`` is provided, all the components are set @@ -1210,7 +1194,6 @@ def __setitem__(self, index, values): A = f + a + b sage: A.display_expansion() A = x + y dx + x*y dx∧dy - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1261,7 +1244,6 @@ def __getitem__(self, deg): [Scalar field f on the 2-dimensional differentiable manifold M, 1-form a on the 2-dimensional differentiable manifold M, 2-form b on the 2-dimensional differentiable manifold M] - """ if self._comp is None: self._init_comp() @@ -1317,7 +1299,6 @@ def set_restriction(self, rst): A = u/(u^2 + v^2) - (u^2*v - v^3)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) du - 2*u*v^2/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) dv sage: A.restrict(U) == AU True - """ if not isinstance(rst, MixedForm): raise TypeError("the argument must be a mixed form") @@ -1345,9 +1326,7 @@ def restrict(self, subdomain, dest_map=None): used, `\Phi` being the differentiable map `S \rightarrow M` associated with the mixed form - OUTPUT: - - - :class:`MixedForm` representing the restriction + OUTPUT: :class:`MixedForm` representing the restriction EXAMPLES: @@ -1392,7 +1371,6 @@ def restrict(self, subdomain, dest_map=None): differentiable manifold M] sage: FV.display_expansion(e_uv) F = u^2/(u^4 + 2*u^2*v^2 + v^4) - (u^2*v^2 - v^4)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du - 2*u*v^3/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) dv - u^2*v^2/(u^12 + 6*u^10*v^2 + 15*u^8*v^4 + 20*u^6*v^6 + 15*u^4*v^8 + 6*u^2*v^10 + v^12) du∧dv - """ resu = type(self)(subdomain.mixed_form_algebra(dest_map=dest_map), name=self._name, latex_name=self._latex_name) @@ -1448,7 +1426,6 @@ def add_comp_by_continuation(self, frame, subdomain, chart=None): F = x + x dx - x*y/(x^8 + 4*x^6*y^2 + 6*x^4*y^4 + 4*x^2*y^6 + y^8) dx∧dy sage: F.display_expansion(e_uv) F = u/(u^2 + v^2) - (u^3 - u*v^2)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) du - 2*u^2*v/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) dv + u*v du∧dv - """ if chart is None: chart = frame._chart @@ -1479,7 +1456,6 @@ def irange(self, start=None): [0, 1, 2, 3] sage: list(a.irange(2)) [2, 3] - """ return self.parent().irange(start=start) @@ -1499,7 +1475,6 @@ def set_comp(self, i): A = A_0 + A_1 + A_2 sage: A.display_expansion() A = x^2 - y dx + x dy + (x - y) dx∧dy - """ return self[i] @@ -1520,7 +1495,6 @@ def set_immutable(self): True sage: f.is_immutable() False - """ for form in self: form.set_immutable() diff --git a/src/sage/manifolds/differentiable/mixed_form_algebra.py b/src/sage/manifolds/differentiable/mixed_form_algebra.py index 8266b19e172..26339c0d6ad 100644 --- a/src/sage/manifolds/differentiable/mixed_form_algebra.py +++ b/src/sage/manifolds/differentiable/mixed_form_algebra.py @@ -37,6 +37,7 @@ from sage.symbolic.ring import SR from sage.manifolds.differentiable.mixed_form import MixedForm + class MixedFormAlgebra(Parent, UniqueRepresentation): r""" An instance of this class represents the graded algebra of mixed forms. @@ -140,7 +141,6 @@ class MixedFormAlgebra(Parent, UniqueRepresentation): subset U of the 3-dimensional differentiable manifold M sage: OmegaU.has_coerce_map_from(Omega) True - """ Element = MixedForm @@ -165,7 +165,6 @@ def __init__(self, vector_field_module): ....: import MixedFormAlgebra sage: A = MixedFormAlgebra(M.vector_field_module()) sage: TestSuite(A).run() - """ if vector_field_module is None: raise ValueError("underlying vector field module must be provided") @@ -212,7 +211,6 @@ def _element_constructor_(self, comp, name=None, latex_name=None): sage: a = A([x,0,0], name='a'); a Mixed differential form a on the 2-dimensional differentiable manifold M - """ try: if comp.is_trivial_zero(): @@ -269,7 +267,6 @@ def _an_element_(self): sage: A._an_element_() Mixed differential form on the 2-dimensional differentiable manifold M - """ res = self.element_class(self) dom = self._domain @@ -301,7 +298,6 @@ def _coerce_map_from_(self, S): True sage: A._coerce_map_from_(AU) False - """ if isinstance(S, type(self)): # coercion by domain restriction @@ -336,7 +332,6 @@ def zero(self): sage: A.zero() Mixed differential form zero on the 3-dimensional differentiable manifold M - """ res = self.element_class(self, name='zero', latex_name='0') res._comp = [self._domain.diff_form_module(j, dest_map=self._dest_map).zero() @@ -357,7 +352,6 @@ def one(self): sage: A.one() Mixed differential form one on the 3-dimensional differentiable manifold M - """ res = self.element_class(self, name='one', latex_name='1') res._comp = [self._domain.one_scalar_field(), @@ -385,7 +379,6 @@ def vector_field_module(self): Module X(M,Phi) of vector fields along the 2-dimensional differentiable manifold M mapped into the 3-dimensional differentiable manifold N - """ return self._vmodule @@ -399,7 +392,6 @@ def _repr_(self): sage: A = M.mixed_form_algebra(); A Graded algebra Omega^*(M) of mixed differential forms on the 3-dimensional differentiable manifold M - """ desc = "Graded algebra " + self._name desc += " of mixed differential forms " @@ -427,7 +419,6 @@ def _latex_(self): '\\Omega^*\\left(\\mathcal{M}\\right)' sage: latex(A) # indirect doctest \Omega^*\left(\mathcal{M}\right) - """ return self._latex_name @@ -461,7 +452,6 @@ def differential(self, degree=None): (x, y) ↦ x sage: d0(f).display() df = dx - """ if degree is None: domain = codomain = self @@ -503,7 +493,6 @@ def cohomology(self, *args, **kwargs): sage: A.cohomology() De Rham cohomology ring on the 3-dimensional differentiable manifold M - """ from .de_rham_cohomology import DeRhamCohomologyRing return DeRhamCohomologyRing(self) @@ -533,7 +522,6 @@ def irange(self, start=None): [0, 1, 2, 3] sage: list(A.irange(2)) [2, 3] - """ imax = self._max_deg + 1 if start is None: @@ -564,6 +552,5 @@ def lift_from_homology(self, x): sage: C.lift_from_homology(a) Mixed differential form alpha on the 2-dimensional differentiable manifold M - """ return x.lift() diff --git a/src/sage/manifolds/differentiable/multivector_module.py b/src/sage/manifolds/differentiable/multivector_module.py index 51264368ccd..fa2d5fce099 100644 --- a/src/sage/manifolds/differentiable/multivector_module.py +++ b/src/sage/manifolds/differentiable/multivector_module.py @@ -141,7 +141,7 @@ class :class:`MultivectorFreeModule` must be used instead. sage: z is A.zero() True - while non-zero elements are constructed by providing their + while nonzero elements are constructed by providing their components in a given vector frame:: sage: a = A([[0,3*x],[-3*x,0]], frame=eU, name='a') ; a @@ -214,7 +214,6 @@ class :class:`MultivectorFreeModule` must be used instead. differentiable manifold M sage: a_U.display(eU) a = 3*x ∂/∂x∧∂/∂y - """ Element = MultivectorField @@ -245,7 +244,6 @@ def __init__(self, vector_field_module, degree): In the above test suite, ``_test_elements`` is skipped because of the ``_test_pickling`` error of the elements (to be fixed in :class:`sage.manifolds.differentiable.tensorfield.TensorField`) - """ domain = vector_field_module._domain dest_map = vector_field_module._dest_map @@ -298,7 +296,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, a = x*y ∂/∂x∧∂/∂y sage: A(0) is A.zero() True - """ try: if comp.is_trivial_zero(): @@ -340,7 +337,6 @@ def _an_element_(self): sage: A._an_element_() 2-vector field on the 2-dimensional differentiable manifold M - """ resu = self.element_class(self._vmodule, self._degree) for oc in self._domain.open_covers(trivial=False): @@ -369,7 +365,6 @@ def _coerce_map_from_(self, other): True sage: A2._coerce_map_from_(A2U) False - """ if isinstance(other, (MultivectorModule, MultivectorFreeModule)): # coercion by domain restriction @@ -391,7 +386,6 @@ def zero(self): sage: A2.zero() 2-vector field zero on the 3-dimensional differentiable manifold M - """ zero = self._element_constructor_(name='zero', latex_name='0') for frame in self._domain._frames: @@ -415,7 +409,6 @@ def _repr_(self): sage: A2 Module A^2(M) of 2-vector fields on the 3-dimensional differentiable manifold M - """ description = "Module " if self._name is not None: @@ -440,7 +433,6 @@ def _latex_(self): 'A^{2}\\left(\\mathcal{M}\\right)' sage: latex(A2) # indirect doctest A^{2}\left(\mathcal{M}\right) - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -476,7 +468,6 @@ def base_module(self): sage: A2U.base_module() Module X(U) of vector fields on the Open subset U of the 3-dimensional differentiable manifold M - """ return self._vmodule @@ -484,9 +475,7 @@ def degree(self): r""" Return the degree of the multivector fields in ``self``. - OUTPUT: - - - integer `p` such that ``self`` is a set of `p`-vector fields + OUTPUT: integer `p` such that ``self`` is a set of `p`-vector fields EXAMPLES:: @@ -495,12 +484,12 @@ def degree(self): 2 sage: M.multivector_module(3).degree() 3 - """ return self._degree #*********************************************************************** + class MultivectorFreeModule(ExtPowerFreeModule): r""" Free module of multivector fields of a given degree `p` (`p`-vector @@ -589,7 +578,7 @@ class MultivectorFreeModule(ExtPowerFreeModule): sage: A(0) is A.zero() True - while non-zero elements are constructed by providing their + while nonzero elements are constructed by providing their components in a given vector frame:: sage: comp = [[0,3*x,-z],[-3*x,0,4],[z,-4,0]] @@ -662,7 +651,6 @@ class MultivectorFreeModule(ExtPowerFreeModule): differentiable manifold M sage: a_U.display() a = 3*x ∂/∂x∧∂/∂y - z ∂/∂x∧∂/∂z + 4 ∂/∂y∧∂/∂z - """ Element = MultivectorFieldParal @@ -682,7 +670,6 @@ def __init__(self, vector_field_module, degree): Free module A^2(M) of 2-vector fields on the 3-dimensional differentiable manifold M sage: TestSuite(A).run() - """ domain = vector_field_module._domain dest_map = vector_field_module._dest_map @@ -725,7 +712,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, a = x ∂/∂x∧∂/∂y sage: A(0) is A.zero() True - """ try: if comp.is_trivial_zero(): @@ -775,7 +761,6 @@ def _coerce_map_from_(self, other): False sage: A2._coerce_map_from_(M.tensor_field_module((2,0))) False - """ if isinstance(other, (MultivectorModule, MultivectorFreeModule)): # coercion by domain restriction @@ -799,7 +784,6 @@ def _repr_(self): sage: A Free module A^2(M) of 2-vector fields on the 3-dimensional differentiable manifold M - """ description = "Free module " if self._name is not None: diff --git a/src/sage/manifolds/differentiable/multivectorfield.py b/src/sage/manifolds/differentiable/multivectorfield.py index 1d15c4cae41..1e739dfdd17 100644 --- a/src/sage/manifolds/differentiable/multivectorfield.py +++ b/src/sage/manifolds/differentiable/multivectorfield.py @@ -40,6 +40,7 @@ from sage.manifolds.differentiable.tensorfield import TensorField from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal + class MultivectorField(TensorField): r""" Multivector field with values on a generic (i.e. a priori not @@ -152,7 +153,6 @@ class MultivectorField(TensorField): sage: s.display(eV) f*(a∧b) = (1/2*u^5 - 1/2*u^3*v^2 - 1/2*u^2*v^3 + u^3 + 1/2*(u^4 + 2*u^2)*v) ∂/∂u∧∂/∂v - """ def __init__(self, vector_field_module, degree, name=None, latex_name=None): r""" @@ -193,7 +193,6 @@ def __init__(self, vector_field_module, degree, name=None, latex_name=None): .. TODO:: Fix ``_test_pickling`` (in the superclass :class:`TensorField`). - """ TensorField.__init__(self, vector_field_module, (degree, 0), name=name, latex_name=latex_name, antisym=range(degree), @@ -217,7 +216,6 @@ def _repr_(self): sage: b = M.multivector_field(2) sage: b._repr_() '2-vector field on the 3-dimensional differentiable manifold M' - """ description = "{}-vector field ".format(self._tensor_rank) if self._name is not None: @@ -239,7 +237,6 @@ def _new_instance(self): True sage: a1.parent() is a.parent() True - """ return type(self)(self._vmodule, self._tensor_rank) @@ -247,9 +244,7 @@ def degree(self): r""" Return the degree of ``self``. - OUTPUT: - - - integer `p` such that ``self`` is a `p`-vector field + OUTPUT: integer `p` such that ``self`` is a `p`-vector field EXAMPLES:: @@ -262,7 +257,6 @@ def degree(self): Vector field on the 3-dimensional differentiable manifold M sage: b.degree() 1 - """ return self._tensor_rank @@ -305,7 +299,6 @@ def wedge(self, other): a∧b = (-x^3 - (x - 1)*y^2) ∂/∂x∧∂/∂y sage: c.display(e_uv) a∧b = (-v^2 + u) ∂/∂u∧∂/∂v - """ from sage.typeset.unicode_characters import unicode_wedge from sage.tensor.modules.format_utilities import is_atomic @@ -458,7 +451,6 @@ def interior_product(self, form): True sage: s.restrict(V) == 2 * a[[e_uv,1,2]] * b[[e_uv,1,2]] True - """ from sage.tensor.modules.format_utilities import is_atomic if self._domain.is_subset(form._domain): @@ -631,7 +623,6 @@ def bracket(self, other): :meth:`MultivectorFieldParal.bracket` for more examples and check of standards identities involving the Schouten-Nijenhuis bracket - """ from sage.manifolds.differentiable.scalarfield import DiffScalarField pp = self._tensor_rank @@ -754,7 +745,7 @@ class MultivectorFieldParal(AlternatingContrTensor, TensorFieldParal): sage: type(a.comp()) - Setting a component with repeated indices to a non-zero value results in + Setting a component with repeated indices to a nonzero value results in an error:: sage: a[1,1] = 3 @@ -863,7 +854,6 @@ class MultivectorFieldParal(AlternatingContrTensor, TensorFieldParal): sage: ab.lie_der(a) 2-vector field on the 3-dimensional differentiable manifold R3 - """ def __init__(self, vector_field_module, degree, name=None, latex_name=None): @@ -892,7 +882,6 @@ def __init__(self, vector_field_module, degree, name=None, True sage: a1.parent() is a.parent() True - """ AlternatingContrTensor.__init__(self, vector_field_module, degree, name=name, latex_name=latex_name) @@ -921,7 +910,6 @@ def _repr_(self): sage: b = M.multivector_field(2) sage: b._repr_() '2-vector field on the 3-dimensional differentiable manifold M' - """ description = "{}-vector field ".format(self._tensor_rank) if self._name is not None: @@ -944,7 +932,6 @@ def _new_instance(self): True sage: a1.parent() is a.parent() True - """ return type(self)(self._fmodule, self._tensor_rank) @@ -959,7 +946,6 @@ def _init_derived(self): sage: X. = M.chart() # makes M parallelizable sage: a = M.multivector_field(2, name='a') sage: a._init_derived() - """ TensorFieldParal._init_derived(self) @@ -969,7 +955,7 @@ def _del_derived(self, del_restrictions=True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the restrictions of ``self`` to subdomains are deleted TESTS:: @@ -978,7 +964,6 @@ def _del_derived(self, del_restrictions=True): sage: X. = M.chart() # makes M parallelizable sage: a = M.multivector_field(2, name='a') sage: a._del_derived() - """ TensorFieldParal._del_derived(self, del_restrictions=del_restrictions) @@ -1007,7 +992,6 @@ def __call__(self, *args): True sage: s == a(b,c) # indirect doctest True - """ return TensorFieldParal.__call__(self, *args) @@ -1059,7 +1043,6 @@ def wedge(self, other): True sage: s == f.wedge(b) True - """ if other._tensor_rank == 0: # wedge product with a scalar field return self * other @@ -1177,7 +1160,6 @@ def interior_product(self, form): sage: f = X.coframe()[1] # 1-form dx sage: v.interior_product(f) Scalar field zero on the 4-dimensional differentiable manifold M - """ if self._domain.is_subset(form._domain): if not self._ambient_domain.is_subset(form._ambient_domain): @@ -1417,7 +1399,6 @@ def bracket(self, other): sage: d_ac = d.bracket(a.bracket(c)) sage: a_cd + c_da - d_ac == 0 True - """ from itertools import combinations from sage.combinat.permutation import Permutation diff --git a/src/sage/manifolds/differentiable/poisson_tensor.py b/src/sage/manifolds/differentiable/poisson_tensor.py index 41f178dff5c..51da2de5f90 100644 --- a/src/sage/manifolds/differentiable/poisson_tensor.py +++ b/src/sage/manifolds/differentiable/poisson_tensor.py @@ -86,7 +86,6 @@ class PoissonTensorField(MultivectorField): sage: varpi.bracket(varpi).display() [varpi,varpi] = 0 - """ def __init__( @@ -106,7 +105,6 @@ def __init__( sage: varpi 2-vector field varpi on the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 - """ try: vector_field_module = manifold.vector_field_module() @@ -245,7 +243,6 @@ class PoissonTensorFieldParal(PoissonTensorField, MultivectorFieldParal): 2-vector field varpi on the Euclidean plane E^2 sage: varpi.display() varpi = -e_q∧e_p - """ def __init__( @@ -264,7 +261,6 @@ def __init__( sage: poisson = PoissonTensorFieldParal(M, name='varpi', latex_name=r'\varpi') sage: poisson 2-vector field varpi on the Euclidean plane E^2 - """ PoissonTensorField.__init__(self, manifold, name, latex_name) MultivectorFieldParal.__init__(self, self._vmodule, 2, name, latex_name) diff --git a/src/sage/manifolds/differentiable/pseudo_riemannian.py b/src/sage/manifolds/differentiable/pseudo_riemannian.py index 8d3578cfe1f..505900ad0df 100644 --- a/src/sage/manifolds/differentiable/pseudo_riemannian.py +++ b/src/sage/manifolds/differentiable/pseudo_riemannian.py @@ -274,6 +274,7 @@ ############################################################################### + class PseudoRiemannianManifold(DifferentiableManifold): r""" PseudoRiemannian manifold. @@ -409,7 +410,6 @@ class PseudoRiemannianManifold(DifferentiableManifold): Lorentzian metric g on the 4-dimensional Lorentzian manifold M sage: M.metric().signature() -2 - """ def __init__(self, n, name, metric_name=None, signature=None, base_manifold=None, diff_degree=infinity, latex_name=None, @@ -430,7 +430,6 @@ def __init__(self, n, name, metric_name=None, signature=None, sage: M.metric() Pseudo-Riemannian metric g on the 4-dimensional pseudo-Riemannian manifold M sage: TestSuite(M).run() - """ if base_manifold and not isinstance(base_manifold, PseudoRiemannianManifold): raise TypeError("the argument 'base_manifold' must be a " + @@ -564,7 +563,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` sage: h = M.metric('h', signature=1); h Lorentzian metric h on the 3-dimensional Riemannian manifold M - """ if name is None or name == self._metric_name: # Default metric associated with the manifold @@ -669,7 +667,6 @@ def volume_form(self, contra=0): 3-vector field on the 3-dimensional Riemannian manifold M sage: eps3.display() ∂/∂x∧∂/∂y∧∂/∂z - """ return self.metric().volume_form(contra=contra) @@ -687,7 +684,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none is provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -738,7 +735,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): g = dx⊗dx + dy⊗dy sage: gV is g.restrict(V) True - """ resu = PseudoRiemannianManifold(self._dim, name, metric_name=self._metric_name, diff --git a/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py b/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py index 996364cf188..e791cef6781 100644 --- a/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +++ b/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py @@ -14,8 +14,8 @@ We start by declaring the ambient manifold `M` and the submanifold `N`:: - sage: M = Manifold(3, 'M', structure="Lorentzian") - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian", start_index=1) + sage: M = Manifold(3, 'M', structure='Lorentzian') + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian', start_index=1) The considered slices being spacelike hypersurfaces, they are Riemannian manifolds. @@ -263,8 +263,8 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold, Let `N` be a 2-dimensional submanifold of a 3-dimensional Riemannian manifold `M`:: - sage: M = Manifold(3, 'M', structure ="Riemannian") - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: M = Manifold(3, 'M', structure ='Riemannian') + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: N 2-dimensional Riemannian submanifold N immersed in the 3-dimensional Riemannian manifold M @@ -301,7 +301,6 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold, :mod:`~sage.manifolds.manifold` and :mod:`~sage.manifolds.differentiable.differentiable_submanifold` - """ def __init__(self, n, name, ambient=None, metric_name=None, signature=None, base_manifold=None, diff_degree=infinity, @@ -323,7 +322,7 @@ def __init__(self, n, name, ambient=None, metric_name=None, 2-dimensional Riemannian submanifold N embedded in the 3-dimensional Lorentzian manifold M sage: S = Manifold(2, 'S', latex_name=r"\Sigma", ambient=M, - ....: structure="Riemannian", start_index=1) + ....: structure='Riemannian', start_index=1) sage: latex(S) \Sigma sage: S.start_index() @@ -338,7 +337,6 @@ def __init__(self, n, name, ambient=None, metric_name=None, sage: N 4-dimensional pseudo-Riemannian submanifold N immersed in the 5-dimensional pseudo-Riemannian manifold M - """ if metric_name is None: metric_name = 'gamma' @@ -383,8 +381,8 @@ def _repr_(self): TESTS:: - sage: M = Manifold(3, 'M', structure="Lorentzian") - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: M = Manifold(3, 'M', structure='Lorentzian') + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: N 2-dimensional Riemannian submanifold N immersed in the 3-dimensional Lorentzian manifold M @@ -393,7 +391,6 @@ def _repr_(self): sage: N 2-dimensional Riemannian submanifold N embedded in the 3-dimensional Lorentzian manifold M - """ if self is not self._manifold: return "Open subset {} of the {}".format(self._name, self._manifold) @@ -422,7 +419,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none is provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -438,8 +435,8 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): EXAMPLES:: - sage: M = Manifold(3, 'M', structure="Riemannian") - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian"); N + sage: M = Manifold(3, 'M', structure='Riemannian') + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian'); N 2-dimensional Riemannian submanifold N immersed in the 3-dimensional Riemannian manifold M sage: S = N.subset('S'); S @@ -464,7 +461,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): Open subset O of the 2-dimensional Riemannian submanifold N embedded in the 3-dimensional Riemannian manifold M - """ resu = PseudoRiemannianSubmanifold(self._dim, name, ambient=self._ambient, @@ -485,21 +481,18 @@ def ambient_metric(self): r""" Return the metric of the ambient manifold. - OUTPUT: - - - the metric of the ambient manifold + OUTPUT: the metric of the ambient manifold EXAMPLES:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: N.ambient_metric() Riemannian metric g on the Euclidean space E^3 sage: N.ambient_metric().display() g = dx⊗dx + dy⊗dy + dz⊗dz sage: N.ambient_metric() is M.metric() True - """ if self._ambient_metric is None: self._ambient_metric = self._ambient.metric() @@ -558,7 +551,6 @@ def first_fundamental_form(self): embedded in the Euclidean space E^3 sage: P.induced_metric().display() g = 14 dt⊗dt - """ if self._first_fundamental_form is None: self._first_fundamental_form = super().metric() @@ -622,7 +614,7 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` gamma = 5 dt⊗dt Setting the argument ``name`` to that declared while constructing - the submanifold (default = ``'gamma'``) yields the same result:: + the submanifold (default: ``'gamma'``) yields the same result:: sage: N.metric(name='gamma') is N.metric() True @@ -636,7 +628,6 @@ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` sage: h[0, 0] = 1 # initialization sage: h.display() h = dt⊗dt - """ if name is None or name == self._metric_name: return self.first_fundamental_form() @@ -653,9 +644,7 @@ def difft(self): The result is cached, so calling this method multiple times always returns the same result at no additional cost. - OUTPUT: - - - 1-form field on the ambient manifold + OUTPUT: 1-form field on the ambient manifold EXAMPLES: @@ -663,7 +652,7 @@ def difft(self): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') sage: assume(r>0) @@ -680,7 +669,6 @@ def difft(self): sage: N.difft().display() dr = x/sqrt(x^2 + y^2 + z^2) dx + y/sqrt(x^2 + y^2 + z^2) dy + z/sqrt(x^2 + y^2 + z^2) dz - """ if self._dim_foliation == 0: raise ValueError("A foliation is needed to " @@ -700,9 +688,7 @@ def gradt(self): The result is cached, so calling this method multiple times always returns the same result at no additional cost. - OUTPUT: - - - vector field on the ambient manifold + OUTPUT: vector field on the ambient manifold EXAMPLES: @@ -710,7 +696,7 @@ def gradt(self): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') sage: assume(r>0) @@ -727,7 +713,6 @@ def gradt(self): sage: N.gradt().display() grad(r) = x/sqrt(x^2 + y^2 + z^2) e_x + y/sqrt(x^2 + y^2 + z^2) e_y + z/sqrt(x^2 + y^2 + z^2) e_z - """ if self._dim_foliation == 0: raise ValueError("A foliation is needed to perform " @@ -780,7 +765,7 @@ def normal(self): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -808,7 +793,7 @@ def normal(self): part of a foliation, in stereographic coordinates:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U, V) @@ -868,7 +853,6 @@ def normal(self): n = -cos(phi)*sin(the) e_X - sin(phi)*sin(the) e_Y - cos(the) e_Z sage: n.restrict(U).display(format_spec=spher) # long time n = -cos(phi)*sin(the) e_X - sin(phi)*sin(the) e_Y - cos(the) e_Z - """ if self._dim_foliation != 0: # case of a foliation self._normal = self._sgn * self.lapse() * self.gradt() @@ -877,7 +861,7 @@ def normal(self): # case of no foliation: max_frame = self._ambient.default_frame().along(self._immersion) self._normal = self.multivector_field(self._ambient._dim - self._dim, - name="n", + name='n', dest_map=self._immersion) # an auxiliary function: @@ -967,7 +951,7 @@ def ambient_first_fundamental_form(self): A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -995,7 +979,6 @@ def ambient_first_fundamental_form(self): sage: N.ambient_induced_metric()[:] [ x^2/(x^2 + 4) -2*x/(x^2 + 4)] [-2*x/(x^2 + 4) 4/(x^2 + 4)] - """ if self._ambient._dim - self._dim != 1: raise NotImplementedError("ambient_first_fundamental_form() is " @@ -1019,9 +1002,7 @@ def lapse(self): The result is cached, so calling this method multiple times always returns the same result at no additional cost. - OUTPUT: - - - the lapse function, as a scalar field on the ambient manifold + OUTPUT: the lapse function, as a scalar field on the ambient manifold EXAMPLES: @@ -1029,7 +1010,7 @@ def lapse(self): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -1048,7 +1029,6 @@ def lapse(self): N: E^3 → ℝ (x, y, z) ↦ 1 (th_E3, ph_E3, r_E3) ↦ 1 - """ if self._dim_foliation == 0: raise ValueError("A foliation is needed " @@ -1067,9 +1047,7 @@ def shift(self): The result is cached, so calling this method multiple times always returns the same result at no additional cost. - OUTPUT: - - - shift vector field on the ambient manifold + OUTPUT: shift vector field on the ambient manifold EXAMPLES: @@ -1077,7 +1055,7 @@ def shift(self): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -1094,7 +1072,6 @@ def shift(self): Vector field beta on the Euclidean space E^3 sage: N.shift().display() # long time beta = 0 - """ if self._dim_foliation == 0: raise ValueError("A foliation is needed " @@ -1123,7 +1100,7 @@ def ambient_second_fundamental_form(self): A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1151,7 +1128,6 @@ def ambient_second_fundamental_form(self): sage: N.ambient_extrinsic_curvature()[:] # long time [-x^2/(x^2 + 4) 2*x/(x^2 + 4)] [ 2*x/(x^2 + 4) -4/(x^2 + 4)] - """ if self._ambient._dim - self._dim != 1: raise ValueError("ambient_second_fundamental_form is defined only " @@ -1211,7 +1187,7 @@ def second_fundamental_form(self): A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1253,7 +1229,6 @@ def second_fundamental_form(self): submanifold N embedded in the 2-dimensional Riemannian manifold M sage: N.second_fundamental_form().display() K = 2*sqrt(u^4 + 2*u^2 + 2)*u/(u^6 + 3*u^4 + 4*u^2 + 2) du⊗du - """ if self._ambient._dim - self._dim != 1: raise ValueError("second_fundamental_form is defined only for" @@ -1330,7 +1305,7 @@ def projector(self): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -1355,7 +1330,6 @@ def projector(self): sage: N.projector().contract(N.normal()).display() # long time 0 - """ if self._ambient._dim - self._dim != 1: raise NotImplementedError("projector() is implemented only for " @@ -1389,7 +1363,7 @@ def project(self, tensor): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -1412,7 +1386,6 @@ def project(self, tensor): True Note that the output of ``project()`` is not cached. - """ if self._ambient._dim - self._dim != 1: raise NotImplementedError("project() is implemented only for " @@ -1439,7 +1412,7 @@ def mixed_projection(self, tensor, indices=0): INPUT: - ``tensor`` -- any tensor field, eventually along the submanifold if - no foliation is provided. + no foliation is provided - ``indices`` -- (default: ``0``) list of integers containing the indices on which the projection is made on the normal vector. By default, all projections are made on the submanifold. If @@ -1447,9 +1420,7 @@ def mixed_projection(self, tensor, indices=0): the normal vector, all the other ones with the orthogonal projection operator. - OUTPUT: - - - tensor field of rank `k`-``len(indices)`` + OUTPUT: tensor field of rank `k`-``len(indices)`` EXAMPLES: @@ -1457,7 +1428,7 @@ def mixed_projection(self, tensor, indices=0): radii:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -1496,7 +1467,6 @@ def mixed_projection(self, tensor, indices=0): E^3 → ℝ (x, y, z) ↦ 1 (th_E3, ph_E3, r_E3) ↦ 1 - """ if self._ambient._dim - self._dim != 1: raise NotImplementedError("mixed_projection() is implemented only " @@ -1539,16 +1509,14 @@ def gauss_curvature(self): The result is cached, so calling this method multiple times always returns the same result at no additional cost. - OUTPUT: - - - the Gauss curvature as a scalar field on the submanifold + OUTPUT: the Gauss curvature as a scalar field on the submanifold EXAMPLES: A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1570,7 +1538,6 @@ def gauss_curvature(self): N → ℝ on U: x ↦ -1 on V: y ↦ -1 - """ if self._ambient._dim - self._dim != 1: raise ValueError("gauss_curvature is defined only for " @@ -1595,7 +1562,7 @@ def principal_directions(self, chart): INPUT: - - ``chart`` -- chart in which the principal directions are to be + - ``chart`` -- chart in which the principal directions are to be computed OUTPUT: @@ -1608,7 +1575,7 @@ def principal_directions(self, chart): A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1628,7 +1595,6 @@ def principal_directions(self, chart): embedded in the Euclidean plane E^2, -1)] sage: N.principal_directions(stereoN)[0][0].display() # long time e_0 = ∂/∂x - """ if self._ambient._dim - self._dim != 1: raise ValueError("principal directions is defined only for " @@ -1662,7 +1628,7 @@ def principal_curvatures(self, chart): INPUT: - - ``chart`` -- chart in which the principal curvatures are to be + - ``chart`` -- chart in which the principal curvatures are to be computed OUTPUT: @@ -1675,7 +1641,7 @@ def principal_curvatures(self, chart): A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1697,7 +1663,6 @@ def principal_curvatures(self, chart): k_0: N → ℝ on U: x ↦ -1 on W: y ↦ -1 - """ if self._ambient._dim - self._dim != 1: raise ValueError("principal_curvatures is defined only for " @@ -1724,16 +1689,14 @@ def mean_curvature(self): The result is cached, so calling this method multiple times always returns the same result at no additional cost. - OUTPUT: - - - the mean curvature, as a scalar field on the submanifold + OUTPUT: the mean curvature, as a scalar field on the submanifold EXAMPLES: A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1755,7 +1718,6 @@ def mean_curvature(self): N → ℝ on U: x ↦ -1 on V: y ↦ -1 - """ if self._ambient._dim - self._dim != 1: raise ValueError("mean_curvature is defined only for " @@ -1787,7 +1749,7 @@ def shape_operator(self): A unit circle embedded in the Euclidean plane:: sage: M. = EuclideanSpace() - sage: N = Manifold(1, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') sage: U = N.open_subset('U') sage: V = N.open_subset('V') sage: N.declare_union(U,V) @@ -1807,7 +1769,6 @@ def shape_operator(self): submanifold N embedded in the Euclidean plane E^2 sage: N.shape_operator().display() # long time -∂/∂x⊗dx - """ if self._ambient._dim - self._dim != 1: raise ValueError("shape_operator is defined only for " @@ -1827,7 +1788,7 @@ def clear_cache(self): EXAMPLES:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') # foliation parameter sage: assume(r>0) @@ -1848,7 +1809,6 @@ def clear_cache(self): False sage: n == N.normal() True - """ self.difft.clear_cache() self.gradt.clear_cache() diff --git a/src/sage/manifolds/differentiable/scalarfield.py b/src/sage/manifolds/differentiable/scalarfield.py index 179909868a8..be1d6d3b97e 100644 --- a/src/sage/manifolds/differentiable/scalarfield.py +++ b/src/sage/manifolds/differentiable/scalarfield.py @@ -619,7 +619,6 @@ class DiffScalarField(ScalarField): sage: TestSuite(f).run() sage: TestSuite(zer).run() - """ def __init__(self, parent, coord_expression=None, chart=None, name=None, latex_name=None): @@ -639,7 +638,6 @@ def __init__(self, parent, coord_expression=None, chart=None, name=None, Algebra of differentiable scalar fields on the 2-dimensional differentiable manifold M sage: TestSuite(f).run() - """ ScalarField.__init__(self, parent, coord_expression=coord_expression, chart=chart, name=name, latex_name=latex_name) @@ -658,7 +656,6 @@ def _init_derived(self): sage: X. = M.chart() sage: f = M.scalar_field({X: x+y}) sage: f._init_derived() - """ ScalarField._init_derived(self) # derived quantities of the parent class self._differential = None # differential 1-form of the scalar field @@ -684,12 +681,11 @@ def _del_derived(self): sage: f._del_derived() sage: f._restrictions # restrictions are derived quantities {} - """ ScalarField._del_derived(self) # derived quantities of the mother class self._differential = None # reset of the differential # First deletes any reference to self in the vectors' dictionaries: - for vid, val in self._lie_derivatives.items(): + for val in self._lie_derivatives.values(): del val[0]._lie_der_along_self[id(self)] # Then clears the dictionary of Lie derivatives self._lie_derivatives.clear() @@ -710,7 +706,6 @@ def tensor_type(self): sage: f = M.scalar_field(x+2*y) sage: f.tensor_type() (0, 0) - """ return self._tensor_type @@ -793,7 +788,6 @@ def differential(self) -> DiffForm: 2-form ddg on the 3-dimensional differentiable manifold M sage: ddg == 0 True - """ from sage.tensor.modules.format_utilities import (format_unop_txt, format_unop_latex) @@ -873,7 +867,6 @@ def lie_derivative(self, vector): sage: f.lie_der(v).display() M → ℝ (x, y) ↦ 0 - """ # The Lie derivative is cached in _lie_derivatives if neither # the scalar field nor ``vector`` have been modified. @@ -906,14 +899,12 @@ def hodge_dual( INPUT: - - ``nondegenerate_tensor``: a non-degenerate bilinear form defined on the same manifold + - ``nondegenerate_tensor`` -- a non-degenerate bilinear form defined on the same manifold as the current differential form; must be an instance of :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` or :class:`~sage.manifolds.differentiable.symplectic_form.SymplecticForm`. - OUTPUT: - - - the `n`-form `*f` + OUTPUT: the `n`-form `*f` EXAMPLES: @@ -943,7 +934,6 @@ def hodge_dual( sage: f.hodge_dual(g) == g.hodge_star(f) True - """ from sage.tensor.modules.format_utilities import ( format_unop_txt, @@ -1009,7 +999,6 @@ def bracket(self, other): See :meth:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal.bracket` for other examples. - """ if isinstance(other, DiffScalarField): return self._domain.intersection(other._domain).zero_scalar_field() @@ -1035,9 +1024,7 @@ def wedge(self, other): - ``other`` -- a differential form or a multivector field `a` - OUTPUT: - - - the product `f a`, where `f` is ``self`` + OUTPUT: the product `f a`, where `f` is ``self`` EXAMPLES:: @@ -1050,7 +1037,6 @@ def wedge(self, other): 2-form f*a on the 2-dimensional differentiable manifold M sage: s.display() f*a = (x*y^3 + x^2*y) dx∧dy - """ return self * other @@ -1066,9 +1052,7 @@ def degree(self): :meth:`~sage.manifolds.differentiable.multivectorfield.MultivectorField.degree` (multivector fields). - OUTPUT: - - - 0 + OUTPUT: 0 EXAMPLES:: @@ -1077,7 +1061,6 @@ def degree(self): sage: f = M.scalar_field({X: x+y^2}) sage: f.degree() 0 - """ return self._tensor_rank @@ -1164,7 +1147,6 @@ def gradient(self, metric=None): Vector field grad_h(f) on the Euclidean plane E^2 sage: v.display() grad_h(f) = -cos(phi) e_r + (-r^2*sin(phi) - sin(phi)) e_phi - """ default_metric = metric is None if default_metric: @@ -1257,7 +1239,6 @@ def laplacian(self, metric=None): sage: s == f.gradient(h).div(h) True - """ default_metric = metric is None if default_metric: @@ -1334,7 +1315,6 @@ def dalembertian(self, metric=None): sage: from sage.manifolds.operators import dalembertian sage: dalembertian(f) == s True - """ default_metric = metric is None if default_metric: diff --git a/src/sage/manifolds/differentiable/scalarfield_algebra.py b/src/sage/manifolds/differentiable/scalarfield_algebra.py index 3ee079f5720..fc716f5fcc4 100644 --- a/src/sage/manifolds/differentiable/scalarfield_algebra.py +++ b/src/sage/manifolds/differentiable/scalarfield_algebra.py @@ -35,6 +35,7 @@ class `C^k` over a topological field `K` (in from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra from sage.manifolds.differentiable.scalarfield import DiffScalarField + class DiffScalarFieldAlgebra(ScalarFieldAlgebra): r""" Commutative algebra of differentiable scalar fields on a differentiable @@ -367,7 +368,6 @@ class DiffScalarFieldAlgebra(ScalarFieldAlgebra): It is passed also for `C^k(W)`:: sage: TestSuite(CW).run() - """ Element = DiffScalarField @@ -388,7 +388,6 @@ def __init__(self, domain): sage: type(CM).__base__ sage: TestSuite(CM).run() - """ ScalarFieldAlgebra.__init__(self, domain) @@ -396,7 +395,7 @@ def __init__(self, domain): def _coerce_map_from_(self, other): r""" - Determine whether coercion to self exists from other parent + Determine whether coercion to ``self`` exists from other parent. TESTS:: @@ -417,7 +416,6 @@ def _coerce_map_from_(self, other): False sage: CU._coerce_map_from_(CM) True - """ from sage.manifolds.chart_func import ChartFunctionRing @@ -447,7 +445,6 @@ def _repr_(self): 'Algebra of differentiable scalar fields on the 2-dimensional differentiable manifold M' sage: repr(CM) # indirect doctest 'Algebra of differentiable scalar fields on the 2-dimensional differentiable manifold M' - """ return "Algebra of differentiable scalar fields on " + \ "the {}".format(self._domain) diff --git a/src/sage/manifolds/differentiable/symplectic_form.py b/src/sage/manifolds/differentiable/symplectic_form.py index aa0f0caac73..52a076bfbe8 100644 --- a/src/sage/manifolds/differentiable/symplectic_form.py +++ b/src/sage/manifolds/differentiable/symplectic_form.py @@ -102,7 +102,6 @@ class SymplecticForm(DiffForm): sage: diff(omega).display() domega = 0 - """ _name: str @@ -129,7 +128,6 @@ def __init__( sage: omega Symplectic form omega on the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 - """ try: vector_field_module = manifold.vector_field_module() @@ -239,11 +237,9 @@ def restrict( - ``subdomain`` -- open subset `U` of the symplectic form's domain - ``dest_map`` -- (default: ``None``) smooth destination map `\Phi:\ U \to V`, where `V` is a subdomain of the symplectic form's domain - If None, the restriction of the initial vector field module is used. - - OUTPUT: + If ``None``, the restriction of the initial vector field module is used. - - the restricted symplectic form. + OUTPUT: the restricted symplectic form EXAMPLES:: @@ -555,7 +551,7 @@ def hodge_star(self, pform: DiffForm) -> DiffForm: INPUT: - - ``pform``: a `p`-form `A`; must be an instance of + - ``pform`` -- a `p`-form `A`; must be an instance of :class:`~sage.manifolds.differentiable.scalarfield.DiffScalarField` for `p=0` and of :class:`~sage.manifolds.differentiable.diff_form.DiffForm` or @@ -657,7 +653,7 @@ class SymplecticFormParal(SymplecticForm, DiffFormParal): Standard symplectic form on `\RR^2`:: - sage: M. = EuclideanSpace(name="R2", latex_name=r"\mathbb{R}^2") + sage: M. = EuclideanSpace(name='R2', latex_name=r"\mathbb{R}^2") sage: omega = M.symplectic_form(name='omega', latex_name=r'\omega') sage: omega Symplectic form omega on the Euclidean plane R2 @@ -683,7 +679,6 @@ def __init__( sage: omega = SymplecticFormParal(M, name='omega', latex_name=r'\omega') sage: omega Symplectic form omega on the Euclidean plane E^2 - """ try: vector_field_module = manifold.vector_field_module() @@ -729,8 +724,8 @@ def _del_derived(self, del_restrictions: bool = True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the - restrictions of ``self`` to subdomains are deleted. + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the + restrictions of ``self`` to subdomains are deleted TESTS:: @@ -762,12 +757,10 @@ def restrict( - ``subdomain`` -- open subset `U` of the symplectic form's domain - ``dest_map`` -- (default: ``None``) smooth destination map - `\Phi:\ U \rightarrow V`, where `V` is a subdomain of the symplectic form's domain - If None, the restriction of the initial vector field module is used. - - OUTPUT: + `\Phi:\ U \rightarrow V`, where `V` is a subdomain of the symplectic form's domain. + If ``None``, the restriction of the initial vector field module is used. - - the restricted symplectic form. + OUTPUT: the restricted symplectic form EXAMPLES: @@ -890,7 +883,7 @@ def poisson( self_matrix = matrix( [ [ - self.comp(frame)[i, j, chart].expr(method="SR") + self.comp(frame)[i, j, chart].expr(method='SR') for j in fmodule.irange() ] for i in fmodule.irange() diff --git a/src/sage/manifolds/differentiable/symplectic_form_test.py b/src/sage/manifolds/differentiable/symplectic_form_test.py index 5bc519af6d3..804c8956b6e 100644 --- a/src/sage/manifolds/differentiable/symplectic_form_test.py +++ b/src/sage/manifolds/differentiable/symplectic_form_test.py @@ -56,11 +56,11 @@ class TestCoherenceOfFormulas: We check it for the examples of `\R^2` and `S^2`, which should be enough. """ - @pytest.fixture(params=["R2", "S2"]) + @pytest.fixture(params=['R2', 'S2']) def M(self, request: FixtureRequest): - if request.param == "R2": - return StandardSymplecticSpace(2, "R2", symplectic_name="omega") - elif request.param == "S2": + if request.param == 'R2': + return StandardSymplecticSpace(2, 'R2', symplectic_name='omega') + elif request.param == 'S2': # Init stereographic coordinates to get a complete atlas return Sphere(2, coordinates='stereographic') @@ -158,6 +158,7 @@ def test_omega_on_one_forms_is_omega_on_dual_vectors( b = M.one_form(3,4) assert omega.on_forms(a, b) == omega(a.up(omega), b.up(omega)) + def generic_scalar_field(M: DifferentiableManifold, name: str) -> DiffScalarField: chart_functions = {chart: function(name)(*chart[:]) for chart in M.atlas()} return M.scalar_field(chart_functions, name=name) @@ -166,7 +167,7 @@ def generic_scalar_field(M: DifferentiableManifold, name: str) -> DiffScalarFiel class TestR2VectorSpace: @pytest.fixture def M(self): - return StandardSymplecticSpace(2, "R2", symplectic_name="omega") + return StandardSymplecticSpace(2, 'R2', symplectic_name='omega') @pytest.fixture def omega(self, M): @@ -187,7 +188,7 @@ def test_hamiltonian_vector_field( assert str(XH.display()) == r"XH = d(H)/dp e_q - d(H)/dq e_p" def test_flat(self, M: StandardSymplecticSpace, omega: SymplecticForm): - X = M.vector_field(1, 2, name="X") + X = M.vector_field(1, 2, name='X') assert str(X.display()) == r"X = e_q + 2 e_p" assert str(omega.flat(X).display()) == r"X_flat = 2 dq - dp" diff --git a/src/sage/manifolds/differentiable/tangent_space.py b/src/sage/manifolds/differentiable/tangent_space.py index 62cf268094e..0320b70bb93 100644 --- a/src/sage/manifolds/differentiable/tangent_space.py +++ b/src/sage/manifolds/differentiable/tangent_space.py @@ -34,6 +34,7 @@ if TYPE_CHECKING: from sage.manifolds.point import ManifoldPoint + class TangentSpace(FiniteRankFreeModule): r""" Tangent space to a differentiable manifold at a given point. @@ -228,7 +229,6 @@ class TangentSpace(FiniteRankFreeModule): :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule` for more documentation. - """ Element = TangentVector @@ -246,7 +246,6 @@ def __init__(self, point: ManifoldPoint, base_ring=None): Tangent space at Point p on the 2-dimensional differentiable manifold M sage: TestSuite(Tp).run() - """ manif = point._manifold name = "T_{} {}".format(point._name, manif._name) @@ -342,7 +341,6 @@ def _repr_(self): sage: Tp Tangent space at Point p on the 2-dimensional differentiable manifold M - """ return "Tangent space at {}".format(self._point) @@ -361,7 +359,6 @@ def _an_element_(self): manifold M sage: Tp._an_element_().display() ∂/∂x + 2 ∂/∂y - """ resu = self.element_class(self) if self._def_basis is not None: @@ -390,7 +387,6 @@ def dimension(self): sage: dim(Tp) 2 - """ # The dimension is the rank of self as a free module: return self._rank @@ -411,6 +407,5 @@ def base_point(self): Point p on the 2-dimensional differentiable manifold M sage: Tp.base_point() is p True - """ return self._point diff --git a/src/sage/manifolds/differentiable/tangent_vector.py b/src/sage/manifolds/differentiable/tangent_vector.py index d7a18d51e5f..1bd1dd5c647 100644 --- a/src/sage/manifolds/differentiable/tangent_vector.py +++ b/src/sage/manifolds/differentiable/tangent_vector.py @@ -120,7 +120,6 @@ class TangentVector(FiniteRankFreeModuleElement): :class:`~sage.tensor.modules.free_module_element.FiniteRankFreeModuleElement` for more documentation. - """ def __init__(self, parent, name=None, latex_name=None): r""" @@ -137,7 +136,6 @@ def __init__(self, parent, name=None, latex_name=None): manifold M sage: v[:] = 5, -3/2 sage: TestSuite(v).run() - """ FiniteRankFreeModuleElement.__init__(self, parent, name=name, latex_name=latex_name) @@ -159,7 +157,6 @@ def _repr_(self): 'Tangent vector v at Point p on the 2-dimensional differentiable manifold M' sage: repr(v) # indirect doctest 'Tangent vector v at Point p on the 2-dimensional differentiable manifold M' - """ from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace if isinstance(self._point.parent(), EuclideanSpace): @@ -210,10 +207,10 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, - ``scale`` -- (default: 1) value by which the length of the arrow representing the vector is multiplied - - ``color`` -- (default: 'blue') color of the arrow representing the + - ``color`` -- (default: ``'blue'``) color of the arrow representing the vector - - ``print_label`` -- (boolean; default: ``True``) determines whether a + - ``print_label`` -- boolean (default: ``True``); determines whether a label is printed next to the arrow representing the vector - ``label`` -- (string; default: ``None``) label printed next to the @@ -450,7 +447,6 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, graph_v = v.plot(mapping=F) graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9) sphinx_plot(graph_v + graph_S2) - """ from sage.plot.arrow import arrow2d from sage.plot.text import text @@ -605,7 +601,6 @@ def __call__(self, f): sage: bool( v(omega) == omega(v) ) True - """ if isinstance(f, FreeModuleAltForm): # Case of self acting on a linear form diff --git a/src/sage/manifolds/differentiable/tensorfield.py b/src/sage/manifolds/differentiable/tensorfield.py index 2a958a20640..562c62cefc8 100644 --- a/src/sage/manifolds/differentiable/tensorfield.py +++ b/src/sage/manifolds/differentiable/tensorfield.py @@ -52,7 +52,7 @@ # ***************************************************************************** from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Tuple, TypeVar, Union +from typing import TYPE_CHECKING, Optional, TypeVar, Union from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ @@ -72,8 +72,8 @@ from sage.tensor.modules.comp import Components -TensorType = Tuple[int, int] -T = TypeVar("T", bound="TensorField") +TensorType = tuple[int, int] +T = TypeVar("T", bound='TensorField') class TensorField(ModuleElementWithMutability): @@ -83,7 +83,7 @@ class TensorField(ModuleElementWithMutability): An instance of this class is a tensor field along a differentiable manifold `U` with values on a differentiable manifold `M`, via a differentiable map `\Phi: U \rightarrow M`. More precisely, given two - non-negative integers `k` and `l` and a differentiable map + nonnegative integers `k` and `l` and a differentiable map .. MATH:: @@ -407,7 +407,6 @@ class TensorField(ModuleElementWithMutability): Traceback (most recent call last): ... ValueError: the name of an immutable element cannot be changed - """ _name: Optional[str] @@ -467,7 +466,6 @@ def __init__( manifold M sage: type(t1) == type(t) True - """ if parent is None: parent = vector_field_module.tensor_module(*tensor_type) @@ -559,7 +557,6 @@ def _repr_(self): sage: t = M.tensor_field(1, 3, name='t') sage: t Tensor field t of type (1,3) on the 2-dimensional differentiable manifold M - """ # Special cases if self._tensor_type == (0,2) and self._sym == ((0,1),): @@ -588,7 +585,6 @@ def _latex_(self): sage: t = M.tensor_field(1, 3, name='t', latex_name=r'\tau') sage: latex(t) \tau - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -628,7 +624,6 @@ def set_name(self, name: Optional[str] = None, latex_name: Optional[str] = None) manifold M sage: latex(t) a - """ if self.is_immutable(): raise ValueError("the name of an immutable element " @@ -658,7 +653,6 @@ def _new_instance(self): True sage: t1.parent() is t.parent() True - """ return type(self)(self._vmodule, self._tensor_type, sym=self._sym, antisym=self._antisym, parent=self.parent()) @@ -674,7 +668,6 @@ def _final_repr(self, description: str) -> str: sage: t = M.tensor_field(1, 3, name='t') sage: t._final_repr('Tensor field t ') 'Tensor field t on the 2-dimensional differentiable manifold M' - """ if self._domain == self._ambient_domain: description += "on the {}".format(self._domain) @@ -692,7 +685,6 @@ def _init_derived(self): sage: M = Manifold(2, 'M') sage: t = M.tensor_field(1, 3, name='t') sage: t._init_derived() - """ self._lie_derivatives = {} # dict. of Lie derivatives of self (keys: id(vector)) @@ -705,10 +697,9 @@ def _del_derived(self): sage: M = Manifold(2, 'M') sage: t = M.tensor_field(1, 3, name='t') sage: t._del_derived() - """ # First deletes any reference to self in the vectors' dictionaries: - for vid, val in self._lie_derivatives.items(): + for val in self._lie_derivatives.values(): del val[0]._lie_der_along_self[id(self)] # Then clears the dictionary of Lie derivatives self._lie_derivatives.clear() @@ -731,7 +722,6 @@ def _del_restrictions(self): sage: t._del_restrictions() sage: t._restrictions {} - """ self._restrictions.clear() self._extensions_graph = {self._domain: self} @@ -782,7 +772,6 @@ def _init_components(self, *comp, **kwargs): sage: v._init_components(1/2, -1) sage: v.display() 1/2 ∂/∂x - ∂/∂y - """ comp0 = comp[0] self._is_zero = False # a priori @@ -827,7 +816,6 @@ def domain(self) -> DifferentiableManifold: sage: h = t.restrict(U) sage: h.domain() Open subset U of the 2-dimensional differentiable manifold M - """ return self._domain @@ -854,7 +842,6 @@ def base_module(self) -> VectorFieldModule: sage: XM = M.vector_field_module() sage: XM.an_element().base_module() is XM True - """ return self._vmodule @@ -876,7 +863,6 @@ def tensor_type(self) -> TensorType: sage: v = M.vector_field() sage: v.tensor_type() (1, 0) - """ return self._tensor_type @@ -898,7 +884,6 @@ def tensor_rank(self): sage: v = M.vector_field() sage: v.tensor_rank() 1 - """ return self._tensor_rank @@ -921,7 +906,6 @@ def symmetries(self): sage: t = M.tensor_field(2,2, antisym=[(0,1),(2,3)]) sage: t.symmetries() no symmetry; antisymmetries: [(0, 1), (2, 3)] - """ if not self._sym: s = "no symmetry; " @@ -953,7 +937,6 @@ def set_immutable(self): sage: a.set_immutable() sage: aU.is_immutable() True - """ for rst in self._restrictions.values(): rst.set_immutable() @@ -993,7 +976,6 @@ def set_restriction(self, rst: TensorField): sage: v.set_restriction(t) sage: v.restrict(U) == t.restrict(U) True - """ if self.is_immutable(): raise ValueError("the restrictions of an immutable element " @@ -1047,9 +1029,7 @@ def restrict( to `U` is used, `\Phi` being the differentiable map `S \rightarrow M` associated with the tensor field - OUTPUT: - - - :class:`TensorField` representing the restriction + OUTPUT: :class:`TensorField` representing the restriction EXAMPLES: @@ -1109,7 +1089,6 @@ def restrict( True sage: vU.restrict(U) is vU True - """ if (subdomain == self._domain and (dest_map is None or dest_map == self._vmodule._dest_map)): @@ -1236,7 +1215,6 @@ def _set_comp_unsafe(self, basis=None): ... ValueError: no basis could be found for computing the components in the Coordinate frame (V, (∂/∂u,∂/∂v)) - """ if basis is None: basis = self._domain._def_frame @@ -1307,7 +1285,6 @@ def set_comp(self, basis=None): ... ValueError: the components of an immutable element cannot be changed - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1370,7 +1347,6 @@ def _add_comp_unsafe(self, basis=None): sage: t.display(e_uv) t = (u + v) ∂/∂v⊗du⊗dv - """ if basis is None: basis = self._domain._def_frame @@ -1437,7 +1413,6 @@ def add_comp(self, basis=None) -> Components: ... ValueError: the components of an immutable element cannot be changed - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1512,7 +1487,6 @@ def add_comp_by_continuation(self, frame, subdomain, chart=None): a = (-4*u*v - u) ∂/∂u + (2*u^2 - 2*v^2 - v) ∂/∂v and `a` is defined on the entire manifold `S^2`. - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1538,14 +1512,14 @@ def add_expr_from_subdomain(self, frame, subdomain): - ``frame`` -- vector frame `e` in which the components are to be set - ``subdomain`` -- open subset of `e`'s domain in which the - components have additional expressions. + components have additional expressions EXAMPLES: We are going to consider a vector field in `\RR^3` along the 2-sphere:: - sage: M = Manifold(3, 'M', structure="Riemannian") - sage: S = Manifold(2, 'S', structure="Riemannian") + sage: M = Manifold(3, 'M', structure='Riemannian') + sage: S = Manifold(2, 'S', structure='Riemannian') sage: E. = M.chart() Let us define ``S`` in terms of stereographic charts:: @@ -1612,7 +1586,6 @@ def add_expr_from_subdomain(self, frame, subdomain): S → ℝ on U: (x, y) ↦ x^2 + y^2 on V: (xp, yp) ↦ 1/(xp^2 + yp^2) - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -1702,7 +1675,6 @@ def comp(self, basis=None, from_basis=None): sage: t.comp(h)[:] [ 0 -u^3*v/(v + 1)] [ 0 -u*v] - """ if basis is None: basis = self._domain._def_frame @@ -1823,7 +1795,6 @@ def display(self, frame=None, chart=None): sage: t.disp(e_uv) t = (1/2*u + 1/2) ∂/∂u⊗du + (1/2*u - 1/2) ∂/∂u⊗dv + (1/2*v + 1/2) ∂/∂v⊗du + (1/2*v - 1/2) ∂/∂v⊗dv - """ if frame is None: if chart is not None: @@ -1877,12 +1848,12 @@ def display_comp(self, frame=None, chart=None, coordinate_labels=True, - ``chart`` -- (default: ``None``) chart specifying the coordinate expression of the components; if ``None``, the default chart of the tensor field domain is used - - ``coordinate_labels`` -- (default: ``True``) boolean; if ``True``, + - ``coordinate_labels`` -- boolean (default: ``True``); if ``True``, coordinate symbols are used by default (instead of integers) as index labels whenever ``frame`` is a coordinate frame - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero components are displayed - - ``only_nonredundant`` -- (default: ``False``) boolean; if ``True``, + - ``only_nonredundant`` -- boolean (default: ``False``); if ``True``, only nonredundant components are displayed in case of symmetries EXAMPLES: @@ -1919,7 +1890,6 @@ def display_comp(self, frame=None, chart=None, coordinate_labels=True, See documentation of :meth:`sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal.display_comp` for more options. - """ if frame is None: if chart is not None: @@ -1986,7 +1956,6 @@ def __getitem__(self, args): sage: t.__getitem__('^a_a').display() M → ℝ on U: (x, y) ↦ (x + 1)*y + x - """ if isinstance(args, str): # tensor with specified indices return TensorWithIndices(self, args).update() @@ -2008,7 +1977,7 @@ def __getitem__(self, args): def __setitem__(self, args, value): r""" - Sets a component with respect to some vector frame. + Set a component with respect to some vector frame. INPUT: @@ -2038,7 +2007,6 @@ def __setitem__(self, args, value): sage: t.__setitem__(slice(None), [[x+y, -2], [3*y^2, x*y]]) sage: t.display() t = (x + y) ∂/∂x⊗dx - 2 ∂/∂x⊗dy + 3*y^2 ∂/∂y⊗dx + x*y ∂/∂y⊗dy - """ if isinstance(args, list): # case of [[...]] syntax if not isinstance(args[0], (int, Integer, slice)): @@ -2102,7 +2070,6 @@ def copy_from(self, other): s = (x + y) ∂/∂x⊗dx + 2 ∂/∂y⊗dx + (-y + 1) ∂/∂y⊗dy sage: s == t False - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -2164,7 +2131,6 @@ def copy(self, name=None, latex_name=None): (x + y) ∂/∂x⊗dx + 2 ∂/∂y⊗dx + (-y + 1) ∂/∂y⊗dy sage: s == t False - """ resu = self._new_instance() # set resu name @@ -2214,7 +2180,6 @@ def _common_subdomains(self, other): sage: sorted(t._common_subdomains(a), key=str) [Open subset U of the 2-dimensional differentiable manifold M, Open subset V of the 2-dimensional differentiable manifold M] - """ resu = [] for dom in self._restrictions: @@ -2230,9 +2195,7 @@ def __eq__(self, other): - ``other`` -- a tensor field or 0 - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise TESTS:: @@ -2345,7 +2308,6 @@ def __ne__(self, other): False sage: t != 0 True - """ return not (self == other) @@ -2353,9 +2315,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of ``self`` + OUTPUT: an exact copy of ``self`` TESTS:: @@ -2376,7 +2336,6 @@ def __pos__(self): manifold M sage: s.display(e_xy) +t = (x + y) ∂/∂x⊗dx + 2 ∂/∂y⊗dx + (-y + 1) ∂/∂y⊗dy - """ resu = self._new_instance() for dom, rst in self._restrictions.items(): @@ -2392,9 +2351,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the tensor field `-T`, where `T` is ``self`` + OUTPUT: the tensor field `-T`, where `T` is ``self`` TESTS:: @@ -2423,7 +2380,6 @@ def __neg__(self): -t = -u ∂/∂u⊗dv - v ∂/∂v⊗dv sage: s == -t # indirect doctest True - """ resu = self._new_instance() for dom, rst in self._restrictions.items(): @@ -2485,7 +2441,6 @@ def _add_(self, other): True sage: z._add_(a) == a True - """ # Case zero: if self._is_zero: @@ -2554,7 +2509,6 @@ def _sub_(self, other): True sage: z._sub_(a) == -a True - """ # Case zero: if self._is_zero: @@ -2579,7 +2533,7 @@ def _sub_(self, other): def _rmul_(self, scalar): r""" - Reflected multiplication operator: performs ``scalar * self`` + Reflected multiplication operator: performs ``scalar * self``. This is actually the multiplication by an element of the ring over which the tensor field module is constructed. @@ -2589,9 +2543,7 @@ def _rmul_(self, scalar): - ``scalar`` -- scalar field in the scalar field algebra over which the module containing ``self`` is defined - OUTPUT: - - - the tensor field ``scalar * self`` + OUTPUT: the tensor field ``scalar * self`` TESTS:: @@ -2633,7 +2585,6 @@ def _rmul_(self, scalar): True sage: z._rmul_(f) == z True - """ # Case zero: if scalar._is_zero: @@ -2755,7 +2706,6 @@ def __mul__(self, other: TensorField) -> TensorField: v**2/8) ∂/∂v⊗dv sage: s == f*a True - """ from sage.manifolds.differentiable.mixed_form import MixedForm if isinstance(other, MixedForm): @@ -2802,9 +2752,7 @@ def __truediv__(self, scalar) -> TensorField: - ``scalar`` -- scalar field in the scalar field algebra over which the module containing ``self`` is defined - OUTPUT: - - - the tensor field ``scalar * self`` + OUTPUT: the tensor field ``scalar * self`` TESTS:: @@ -2849,7 +2797,6 @@ def __truediv__(self, scalar) -> TensorField: True sage: 2*s == a True - """ resu = self._new_instance() for dom, rst in self._restrictions.items(): @@ -2930,7 +2877,6 @@ def __call__(self, *args): True sage: s.restrict(V) == t.restrict(V)(w.restrict(V)) True - """ p = len(args) if p == 1 and self._tensor_type == (1,1): @@ -3159,7 +3105,6 @@ def trace( sage: b['^k_.k'] == s # long time True - """ if using is not None: if self.tensor_type() != (0, 2): @@ -3370,7 +3315,6 @@ def contract(self, *args: Union[int, TensorField]) -> TensorField: zero: M → ℝ on U: (x, y) ↦ 0 on V: (u, v) ↦ 0 - """ nargs = len(args) for i, arg in enumerate(args): @@ -3496,7 +3440,6 @@ def symmetrize(self, *pos): For more details and examples, see :meth:`sage.tensor.modules.free_module_tensor.FreeModuleTensor.symmetrize`. - """ resu_rst = [] for rst in self._restrictions.values(): @@ -3558,7 +3501,6 @@ def antisymmetrize(self, *pos): For more details and examples, see :meth:`sage.tensor.modules.free_module_tensor.FreeModuleTensor.antisymmetrize`. - """ resu_rst = [] for rst in self._restrictions.values(): @@ -3640,7 +3582,6 @@ def lie_derivative(self, vector): sage: f = M.scalar_field({c_xy: 3*x-1, c_uv: 3/2*(u+v)-1}) sage: a.lie_der(w)(f) == w(a(f)) - a(w(f)) # long time True - """ if vector._tensor_type != (1,0): raise TypeError("the argument must be a vector field") @@ -3729,7 +3670,6 @@ def at(self, point: ManifoldPoint) -> FreeModuleTensor: a = 11/2 ∂/∂u⊗du - 3/2 ∂/∂u⊗dv + 1/2 ∂/∂v⊗du + 7/2 ∂/∂v⊗dv sage: p.coord(c_uv) # to check the above expression (5, -1) - """ if point not in self._domain: raise ValueError("the {} is not a point in the ".format(point) + @@ -3872,7 +3812,6 @@ def up( False sage: dd1tuu == t # should be true True - """ n_con = self._tensor_type[0] # number of contravariant indices = k if pos is None: @@ -4031,7 +3970,6 @@ def down( True sage: uu1tdd == t # not true, because of the order of index raising to get uu1tdd False - """ n_con = self._tensor_type[0] # number of contravariant indices = k if pos is None: @@ -4166,7 +4104,6 @@ def divergence(self, metric=None): Vector field div(v⊗w) on the Euclidean plane E^2 sage: s.display() div(v⊗w) = -y e_x + x e_y - """ n_con = self._tensor_type[0] # number of contravariant indices = k n_cov = self._tensor_type[1] # number of covariant indices = l @@ -4265,7 +4202,6 @@ def laplacian(self, metric=None): sage: Dv.display() Delta_h(v) = -(8*x^5 - 2*x^4 - x^2*y^2 + 15*x^3 - 4*x^2 + 6*x - 2)/(x^4 + 2*x^2 + 1) e_x - 3*x^3*y/(x^4 + 2*x^2 + 1) e_y - """ n_con = self._tensor_type[0] # number of contravariant indices = k trank = self._tensor_rank # k + l @@ -4357,7 +4293,6 @@ def dalembertian(self, metric=None): sage: De.display() # long time Box(e) = 0 - """ default_metric = metric is None if default_metric: @@ -4399,9 +4334,7 @@ def along(self, mapping): - ``mapping`` -- differentiable map `\Phi: U \rightarrow M` - OUTPUT: - - - tensor field `\tilde t` along `U` defined above. + OUTPUT: tensor field `\tilde t` along `U` defined above EXAMPLES: @@ -4465,7 +4398,6 @@ def along(self, mapping): True sage: wa.at(K(7*pi/4)) == eU[0].at(Phi(I(7*pi/4))) # since eU[0]=∂/∂x True - """ dom = self._domain if self._ambient_domain is not dom: @@ -4526,7 +4458,7 @@ def set_calc_order(self, symbol, order, truncate=False): - ``order`` -- integer; the order `n` of the expansion, defined as the degree of the polynomial representing the truncated power series in ``symbol`` - - ``truncate`` -- (default: ``False``) determines whether the + - ``truncate`` -- boolean (default: ``False``); determines whether the components of ``self`` are replaced by their expansions to the given order @@ -4581,7 +4513,6 @@ def set_calc_order(self, symbol, order, truncate=False): sage: a[eV,:] [-1/8*(u^2 + 2*u*v + v^2)*h^2 - 1/2*u + 1/2*v + 1, -1/8*(u^2 + 2*u*v + v^2)*h^2 + 1/2*u - 1/2*v + 1] - """ for rst in self._restrictions.values(): rst.set_calc_order(symbol, order, truncate) @@ -4609,7 +4540,7 @@ def apply_map(self, fun, frame=None, chart=None, with respect to ``chart`` of the components w.r.t. ``frame``; if ``None``, the operation ``fun`` is performed on all available coordinate expressions - - ``keep_other_components`` -- (default: ``False``) determine whether + - ``keep_other_components`` -- boolean (default: ``False``); determine whether the components with respect to vector frames distinct from ``frame`` and having the same domain as ``frame`` are kept. If ``fun`` is non-destructive, ``keep_other_components`` can be set to ``True``; @@ -4707,7 +4638,6 @@ def apply_map(self, fun, frame=None, chart=None, -2*x ∂/∂x sage: diff(w[[0]]).display() -2 dx - """ # The dictionary of components w.r.t. frame: if keep_other_components: diff --git a/src/sage/manifolds/differentiable/tensorfield_module.py b/src/sage/manifolds/differentiable/tensorfield_module.py index 42d921327e8..22d42050b89 100644 --- a/src/sage/manifolds/differentiable/tensorfield_module.py +++ b/src/sage/manifolds/differentiable/tensorfield_module.py @@ -60,7 +60,7 @@ class TensorFieldModule(UniqueRepresentation, ReflexiveModule_tensor): manifold `U` with values on a differentiable manifold `M`, via a differentiable map `U \rightarrow M`. - Given two non-negative integers `k` and `l` and a differentiable map + Given two nonnegative integers `k` and `l` and a differentiable map .. MATH:: @@ -234,7 +234,6 @@ class TensorFieldModule(UniqueRepresentation, ReflexiveModule_tensor): sage: T11.tensor_factors() [Module X(M) of vector fields on the 2-dimensional differentiable manifold M, Module Omega^1(M) of 1-forms on the 2-dimensional differentiable manifold M] - """ Element = TensorField @@ -266,7 +265,6 @@ def __init__(self, vector_field_module, tensor_type, category=None): In the above test suite, ``_test_elements`` is skipped because of the ``_test_pickling`` error of the elements (to be fixed in :class:`~sage.manifolds.differentiable.tensorfield.TensorField`) - """ domain = vector_field_module._domain dest_map = vector_field_module._dest_map @@ -318,7 +316,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, + (-y + 3) ∂/∂y⊗∂/∂y sage: T20(0) is T20.zero() True - """ try: if comp.is_trivial_zero(): @@ -411,7 +408,6 @@ def _an_element_(self): sage: T31._an_element_() Tensor field of type (3,1) on the 2-dimensional differentiable manifold M - """ resu = self.element_class(self._vmodule, self._tensor_type) for oc in self._domain.open_covers(trivial=False): @@ -445,7 +441,6 @@ def _coerce_map_from_(self, other): sage: T11 = M.tensor_field_module((1,1)) sage: T11._coerce_map_from_(M.automorphism_field_group()) True - """ from sage.manifolds.differentiable.diff_form_module import \ DiffFormModule @@ -489,7 +484,6 @@ def _repr_(self): sage: T13 # indirect doctest Module T^(1,3)(M) of type-(1,3) tensors fields on the 2-dimensional differentiable manifold M - """ description = "Module " if self._name is not None: @@ -516,7 +510,6 @@ def _latex_(self): '\\mathcal{T}^{(1,3)}\\left(M\\right)' sage: latex(T13) # indirect doctest \mathcal{T}^{(1,3)}\left(M\right) - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -545,7 +538,6 @@ def base_module(self): sage: T13.base_module().base_ring() Algebra of differentiable scalar fields on the 2-dimensional differentiable manifold M - """ return self._vmodule @@ -553,10 +545,8 @@ def tensor_type(self): r""" Return the tensor type of ``self``. - OUTPUT: - - - pair `(k,l)` of non-negative integers such that the tensor fields - belonging to this module are of type `(k,l)` + OUTPUT: pair `(k,l)` of nonnegative integers such that the tensor + fields belonging to this module are of type `(k,l)` EXAMPLES:: @@ -567,7 +557,6 @@ def tensor_type(self): sage: T20 = M.tensor_field_module((2,0)) sage: T20.tensor_type() (2, 0) - """ return self._tensor_type @@ -598,13 +587,14 @@ def zero(self): #*********************************************************************** + class TensorFieldFreeModule(TensorFreeModule): r""" Free module of tensor fields of a given type `(k,l)` along a differentiable manifold `U` with values on a parallelizable manifold `M`, via a differentiable map `U \rightarrow M`. - Given two non-negative integers `k` and `l` and a differentiable map + Given two nonnegative integers `k` and `l` and a differentiable map .. MATH:: @@ -739,7 +729,6 @@ class TensorFieldFreeModule(TensorFreeModule): [1 0 0] [0 1 0] [0 0 1] - """ Element = TensorFieldParal @@ -760,7 +749,6 @@ def __init__(self, vector_field_module, tensor_type): sage: T12 is M.tensor_field_module((1,2)) True sage: TestSuite(T12).run() - """ domain = vector_field_module._domain dest_map = vector_field_module._dest_map @@ -808,7 +796,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, + 3 ∂/∂y⊗dy⊗dy sage: T12(0) is T12.zero() True - """ try: if comp.is_trivial_zero(): @@ -913,7 +900,6 @@ def _coerce_map_from_(self, other): sage: T11 = M.tensor_field_module((1,1)) sage: T11._coerce_map_from_(M.automorphism_field_group()) True - """ from sage.manifolds.differentiable.diff_form_module import \ DiffFormFreeModule @@ -958,7 +944,6 @@ def _repr_(self): sage: T12 # indirect doctest Free module T^(1,2)(M) of type-(1,2) tensors fields on the 2-dimensional differentiable manifold M - """ description = "Free module " if self._name is not None: diff --git a/src/sage/manifolds/differentiable/tensorfield_paral.py b/src/sage/manifolds/differentiable/tensorfield_paral.py index 188f9970e24..cb0e1db14cd 100644 --- a/src/sage/manifolds/differentiable/tensorfield_paral.py +++ b/src/sage/manifolds/differentiable/tensorfield_paral.py @@ -328,7 +328,7 @@ class TensorFieldParal(FreeModuleTensor, TensorField): An instance of this class is a tensor field along a differentiable manifold `U` with values on a parallelizable manifold `M`, via a differentiable map `\Phi: U \rightarrow M`. More precisely, given two - non-negative integers `k` and `l` and a differentiable map + nonnegative integers `k` and `l` and a differentiable map .. MATH:: @@ -612,7 +612,6 @@ class TensorFieldParal(FreeModuleTensor, TensorField): sage: h[0,0], h[0,1], h[2,0] = 1+t, t^2, sin(t) sage: h.display() h = (t + 1) ∂/∂x⊗∂/∂x + t^2 ∂/∂x⊗∂/∂y + sin(t) ∂/∂z⊗∂/∂x - """ def __init__(self, vector_field_module, tensor_type, name=None, latex_name=None, sym=None, antisym=None): @@ -638,7 +637,6 @@ def __init__(self, vector_field_module, tensor_type, name=None, Free module T^(0,2)(M) of type-(0,2) tensors fields on the 2-dimensional differentiable manifold M sage: TestSuite(t).run() - """ FreeModuleTensor.__init__(self, vector_field_module, tensor_type, name=name, latex_name=latex_name, @@ -672,7 +670,6 @@ def _repr_(self): sage: t # indirect doctest Tensor field t of type (1,1) on the 2-dimensional differentiable manifold M - """ return TensorField._repr_(self) @@ -691,7 +688,6 @@ def _new_instance(self): manifold M sage: type(t._new_instance()) is type(t) True - """ return type(self)(self._fmodule, self._tensor_type, sym=self._sym, antisym=self._antisym) @@ -706,7 +702,6 @@ def _init_derived(self): sage: X. = M.chart() # makes M parallelizable sage: t = M.tensor_field(1,1, name='t') sage: t._init_derived() - """ FreeModuleTensor._init_derived(self) TensorField._init_derived(self) @@ -721,7 +716,7 @@ def _del_derived(self, del_restrictions: bool = True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the restrictions of ``self`` to subdomains are deleted TESTS:: @@ -730,7 +725,6 @@ def _del_derived(self, del_restrictions: bool = True): sage: X. = M.chart() # makes M parallelizable sage: t = M.tensor_field(1,1, name='t') sage: t._del_derived() - """ FreeModuleTensor._del_derived(self) TensorField._del_derived(self) @@ -754,7 +748,6 @@ def _preparse_display(self, basis=None, format_spec=None): (Coordinate frame (M, (∂/∂x,∂/∂y)), Chart (M, (x, y))) sage: t._preparse_display(X) # passing a chart instead of a frame (Coordinate frame (M, (∂/∂x,∂/∂y)), Chart (M, (x, y))) - """ if basis is None: basis = self._fmodule._def_basis @@ -833,7 +826,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such ... ValueError: no basis could be found for computing the components in the Vector frame (M, (e_0,e_1)) - """ if basis is None: basis = self._fmodule._def_basis @@ -922,7 +914,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such ... ValueError: no basis could be found for computing the components in the Vector frame (M, (e_0,e_1)) - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1013,7 +1004,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such t = 2 ∂/∂y⊗dx sage: t.display(e) t = x e_0⊗e^1 - """ if basis is None: basis = self._fmodule._def_basis @@ -1100,7 +1090,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such t = 2 ∂/∂y⊗dx sage: t.display(e) t = x e_0⊗e^1 - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1169,7 +1158,6 @@ class :class:`~sage.tensor.modules.comp.Components` 3-indices components w.r.t. Vector frame (M, (e_1,e_2)) sage: t.comp(e)[:] [[[0, 0], [0, 0]], [[x - 3, 0], [0, 0]]] - """ if basis is None: basis = self._fmodule._def_basis @@ -1241,7 +1229,6 @@ def _common_coord_frame(self, other): sage: c.display(a._common_coord_frame(c)) c = (1/2*x^2 - 1/2*y^2 + 1/2*x + 1/2*y + 1/2) ∂/∂x + (-1/2*x^2 + 1/2*y^2 + 1/2*x + 1/2*y + 1/2) ∂/∂y - """ from sage.manifolds.differentiable.vectorframe import CoordFrame # Compatibility checks: @@ -1404,7 +1391,6 @@ def lie_derivative(self, vector): sage: om.lie_der(v) == (v.contract(0, om.exterior_derivative(), 0) ....: + om(v).exterior_derivative()) True - """ if vector._tensor_type != (1,0): raise TypeError("the argument must be a vector field") @@ -1428,12 +1414,12 @@ def lie_derivative(self, vector): # get n processes nproc = Parallelism().get('tensor') - if nproc != 1 : + if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in resc.non_redundant_index_generator()] - ind_step = max(1, int(len(ind_list)/nproc)) + ind_list = list(resc.non_redundant_index_generator()) + ind_step = max(1, len(ind_list) // nproc) local_list = lol(ind_list, ind_step) # list of input parameters: listParalInput = [(self, vector, coord_frame, chart, ind_part) for ind_part in local_list] @@ -1537,9 +1523,7 @@ def restrict(self, subdomain: DifferentiableManifold, dest_map: Optional[DiffMap being the differentiable map `S \rightarrow M` associated with the tensor field - OUTPUT: - - - instance of :class:`TensorFieldParal` representing the restriction + OUTPUT: instance of :class:`TensorFieldParal` representing the restriction EXAMPLES: @@ -1579,7 +1563,6 @@ def restrict(self, subdomain: DifferentiableManifold, dest_map: Optional[DiffMap sage: v.restrict(M) is v True - """ if (subdomain == self._domain and (dest_map is None or dest_map == self._vmodule._dest_map)): @@ -1719,7 +1702,6 @@ def __call__(self, *args): True sage: s == t(v) # indirect doctest True - """ from sage.categories.homset import End p = len(args) @@ -1818,7 +1800,6 @@ def contract(self, *args: Union[int, TensorField]) -> TensorFieldParal: :meth:`sage.manifolds.differentiable.tensorfield.TensorField.contract` for more examples. - """ # This is to ensure the call to the TensorField version instead of # the FreeModuleTensor one @@ -1871,7 +1852,6 @@ def __mul__(self, other): + (x*y + y^2) dy⊗dx + (-x^3 - x^2*y) dy⊗dy sage: s == f*a True - """ # This is to ensure the call to the TensorField version instead of # the FreeModuleTensor one @@ -1899,12 +1879,12 @@ def display_comp(self, frame=None, chart=None, coordinate_labels=True, - ``chart`` -- (default: ``None``) chart specifying the coordinate expression of the components; if ``None``, the default chart of the tensor field domain is used - - ``coordinate_labels`` -- (default: ``True``) boolean; if ``True``, + - ``coordinate_labels`` -- boolean (default: ``True``); if ``True``, coordinate symbols are used by default (instead of integers) as index labels whenever ``frame`` is a coordinate frame - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero components are displayed - - ``only_nonredundant`` -- (default: ``False``) boolean; if ``True``, + - ``only_nonredundant`` -- boolean (default: ``False``); if ``True``, only nonredundant components are displayed in case of symmetries EXAMPLES: @@ -1994,7 +1974,6 @@ def display_comp(self, frame=None, chart=None, coordinate_labels=True, t^01_0 = (u^2 - v^2)/(u^2 + 2*u*v + v^2 + 8) t^10_0 = (u^2 - v^2)/(u^2 + 2*u*v + v^2 + 8) t^11_1 = -12/(u^2 + 2*u*v + v^2 + 8) - """ from sage.misc.latex import latex from sage.manifolds.differentiable.vectorframe import CoordFrame @@ -2131,7 +2110,6 @@ def at(self, point): True sage: vp.display() v = (1/6*pi + 1) ∂/∂x + 1/36*pi^2 ∂/∂y - """ if point not in self._domain: raise ValueError("the {} is not in the domain of ".format(point) + @@ -2169,9 +2147,7 @@ def along(self, mapping): - ``mapping`` -- differentiable map `\Phi: U \rightarrow M` - OUTPUT: - - - tensor field `\tilde t` along `U` defined above. + OUTPUT: tensor field `\tilde t` along `U` defined above EXAMPLES: @@ -2225,7 +2201,6 @@ def along(self, mapping): differentiable manifold M sage: aU.at(p) == a.at(Phi(p)) True - """ dom = self._domain if self._ambient_domain is not dom: @@ -2328,7 +2303,6 @@ def series_expansion(self, symbol: Expression, order: int) -> list[TensorFieldPa [0 1 0 0] sage: all([g_ser[1] == h1, g_ser[2] == h2]) True - """ from sage.tensor.modules.comp import Components orderp1 = order + 1 @@ -2406,7 +2380,6 @@ def truncate(self, symbol, order): [ e 1 e 0] [ 0 e 1 e] [ 0 0 e 1] - """ series = self.series_expansion(symbol, order) return sum(symbol**i * s for i, s in enumerate(series)) @@ -2438,7 +2411,7 @@ def set_calc_order(self, symbol: Expression, order: int, truncate: bool = False) - ``order`` -- integer; the order `n` of the expansion, defined as the degree of the polynomial representing the truncated power series in ``symbol`` - - ``truncate`` -- (default: ``False``) determines whether the + - ``truncate`` -- boolean (default: ``False``); determines whether the components of ``self`` are replaced by their expansions to the given order @@ -2466,7 +2439,6 @@ def set_calc_order(self, symbol: Expression, order: int, truncate: bool = False) [ e 1 e 0] [ 0 e 1 e] [ 0 0 e 1] - """ for frame in self._components: for ind in self._components[frame].non_redundant_index_generator(): diff --git a/src/sage/manifolds/differentiable/vector_bundle.py b/src/sage/manifolds/differentiable/vector_bundle.py index 3c12a81da42..79e940a19e6 100644 --- a/src/sage/manifolds/differentiable/vector_bundle.py +++ b/src/sage/manifolds/differentiable/vector_bundle.py @@ -37,6 +37,7 @@ from sage.misc.superseded import deprecated_function_alias from sage.rings.rational_field import QQ + class DifferentiableVectorBundle(TopologicalVectorBundle): r""" An instance of this class represents a differentiable vector bundle @@ -85,7 +86,6 @@ class DifferentiableVectorBundle(TopologicalVectorBundle): sage: M.diff_degree() == E.diff_degree() True - """ def __init__(self, rank, name, base_space, field='real', latex_name=None, category=None, unique_tag=None): @@ -99,7 +99,6 @@ def __init__(self, rank, name, base_space, field='real', latex_name=None, sage: DifferentiableVectorBundle(2, 'E', M) Differentiable real vector bundle E -> M of rank 2 over the base space 2-dimensional differentiable manifold M - """ diff_degree = base_space._diff_degree if category is None: @@ -130,7 +129,6 @@ def _repr_(self): sage: E._repr_() 'Differentiable real vector bundle E -> M of rank 1 over the base space 2-dimensional differentiable manifold M' - """ desc = "Differentiable " return desc + TopologicalVectorBundle._repr_object_name(self) @@ -159,7 +157,6 @@ def bundle_connection(self, name, latex_name=None): Further examples can be found in :class:`~sage.manifolds.differentiable.bundle_connection.BundleConnection`. - """ from .bundle_connection import BundleConnection return BundleConnection(self, name, latex_name) @@ -188,7 +185,6 @@ def characteristic_cohomology_class_ring(self, base=QQ): sage: 1 + p1 Characteristic cohomology class (1 + p_1)(TM) of the Tangent bundle TM over the 4-dimensional differentiable manifold M - """ from .characteristic_cohomology_class import CharacteristicCohomologyClassRing @@ -271,7 +267,6 @@ def characteristic_cohomology_class(self, *args, **kwargs): More examples can be found in :class:`~sage.manifolds.differentiable.characteristic_class.CharacteristicClass`. - """ base_ring = kwargs.get('base_ring', QQ) R = self.characteristic_cohomology_class_ring(base_ring) @@ -299,7 +294,6 @@ def diff_degree(self): sage: E = M.vector_bundle(2, 'E') sage: E.diff_degree() 3 - """ return self._diff_degree @@ -322,7 +316,6 @@ def total_space(self): sage: E = M.vector_bundle(2, 'E') sage: E.total_space() 6-dimensional differentiable manifold E - """ if self._total_space is None: from sage.manifolds.manifold import Manifold @@ -341,6 +334,7 @@ def total_space(self): # ***************************************************************************** + class TensorBundle(DifferentiableVectorBundle): r""" Tensor bundle over a differentiable manifold along a differentiable map. @@ -431,7 +425,6 @@ class TensorBundle(DifferentiableVectorBundle): sage: R_tensor_module = R.tensor_field_module((1,0), dest_map=Phi) sage: R_tensor_module is PhiTM.section_module() True - """ def __init__(self, base_space, k, l, dest_map=None): r""" @@ -448,7 +441,6 @@ def __init__(self, base_space, k, l, dest_map=None): manifold M along the Differentiable map Phi from the 2-dimensional differentiable manifold M to the 2-dimensional differentiable manifold N - """ if dest_map is None: self._dest_map = base_space.identity_map() @@ -494,7 +486,6 @@ def _init_derived(self): sage: M = Manifold(2, 'M') sage: TM = M.tangent_bundle() sage: TM._init_derived() - """ self._def_frame = None @@ -520,7 +511,6 @@ def _repr_(self): sage: T12M._repr_() 'Tensor bundle T^(1,2)M over the 2-dimensional differentiable manifold M' - """ if self._tensor_type == (1, 0): desc = "Tangent bundle " @@ -571,7 +561,6 @@ def fiber(self, point): on the 3-dimensional differentiable manifold M sage: T11M.fiber(p) is M.tangent_space(p).tensor_module(1,1) True - """ amb_point = self._dest_map(point) return self._ambient_domain.tangent_space(amb_point).tensor_module(*self._tensor_type) @@ -597,7 +586,6 @@ def atlas(self): sage: TM = M.tangent_bundle() sage: TM.atlas() [Chart (M, (x, y)), Chart (M, (u, v))] - """ return self._base_space.atlas() @@ -639,7 +627,6 @@ def section_module(self, domain=None): 2-dimensional differentiable manifold M sage: TUM is U.tensor_field_module((1,0)) True - """ if domain is None: base_space = self.base_space() @@ -730,7 +717,6 @@ def section(self, *args, **kwargs): differentiable manifold M sage: w.display() -y ∂/∂x + x ∂/∂y - """ nargs = [self._tensor_type[0], self._tensor_type[1]] nargs.extend(args) @@ -767,7 +753,7 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, :class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism` describing the automorphism `P` that relates the basis `(e_i)` to the basis `(f_i)` according to `f_i = P(e_i)` - - ``compute_inverse`` (default: ``True``) -- if set to ``True``, the inverse + - ``compute_inverse`` -- boolean (default: ``True``); if set to ``True``, the inverse automorphism is computed and the change from basis `(f_i)` to `(e_i)` is set to it in the internal dictionary ``self._frame_changes`` @@ -792,7 +778,6 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, sage: TM.change_of_frame(e,f)[e,:] [1 2] [0 3] - """ if not frame1._domain.is_subset(self._ambient_domain): raise ValueError("the frames must be defined on a subset of " @@ -853,7 +838,6 @@ def change_of_frame(self, frame1, frame2): sage: TM.change_of_frame(c_uv.frame(), c_xy.frame()) == \ ....: M.change_of_frame(c_xy.frame(), c_uv.frame()).inverse() True - """ return self._base_space.change_of_frame(frame1=frame1, frame2=frame2) @@ -912,7 +896,6 @@ def changes_of_frame(self): True sage: TM.changes_of_frame()[(f,e)] == a^(-1) True - """ base_cof = self._base_space.changes_of_frame() # Filter out all frames with respect to dest_map: @@ -932,9 +915,7 @@ def frames(self): For further details on frames on ``self`` see :meth:`local_frame`. - OUTPUT: - - - list of local frames defined on ``self`` + OUTPUT: list of local frames defined on ``self`` EXAMPLES: @@ -983,7 +964,6 @@ def frames(self): sage: PhiT11.frames() [Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional differentiable manifold M] - """ if self._dest_map.is_identity(): return self._base_space.frames() @@ -1005,9 +985,7 @@ def coframes(self): For further details on frames on ``self`` see :meth:`local_frame`. - OUTPUT: - - - list of coframes defined on ``self`` + OUTPUT: list of coframes defined on ``self`` EXAMPLES: @@ -1034,7 +1012,6 @@ def coframes(self): Coframe (R^2, (e^0,e^1)), Coordinate coframe (U, (dx,dy)), Coframe (U, (e^0,e^1))] - """ if self._dest_map.is_identity(): return self._base_space.coframes() @@ -1062,7 +1039,7 @@ def trivialization(self, coordinates='', names=None, calc_method=None): INPUT: - - ``coordinates`` -- (default: ``''`` (empty string)) string + - ``coordinates`` -- (default: ``''`` (empty string)) string defining the coordinate symbols, ranges and possible periodicities, see below - ``names`` -- (default: ``None``) unused argument, except if @@ -1130,7 +1107,6 @@ def trivialization(self, coordinates='', names=None, calc_method=None): y sage: X[:] (x, y) - """ return self._ambient_domain.chart(coordinates=coordinates, names=names, calc_method=calc_method) @@ -1196,7 +1172,6 @@ def transitions(self): (Chart (M, (x, y)), Chart (M, (r, s))): Change of coordinates from Chart (M, (x, y)) to Chart (M, (r, s))} - """ return self._ambient_domain.coord_changes() @@ -1239,7 +1214,6 @@ def transition(self, chart1, chart2): sage: TM = M.tangent_bundle() sage: TM.transition(c_xy, c_uv) # returns the coord. change above Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)) - """ return self._ambient_domain.coord_change(chart1, chart2) @@ -1315,7 +1289,6 @@ def is_manifestly_trivial(self): differentiable manifold S^2 sage: PhiTU.is_manifestly_trivial() True - """ if self._dest_map.is_identity(): # The standard case: @@ -1437,7 +1410,6 @@ def local_frame(self, *args, **kwargs): For more options, in particular for the choice of symbols and indices, see :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`. - """ domain = kwargs.pop('domain', None) if domain is None: @@ -1478,7 +1450,6 @@ def ambient_domain(self): sage: PhiT11 = R.tensor_bundle(1, 1, dest_map=Phi) sage: PhiT11.ambient_domain() 2-dimensional differentiable manifold M - """ return self._ambient_domain @@ -1508,7 +1479,6 @@ def destination_map(self): sage: PhiT11.destination_map() Differentiable map Phi from the 1-dimensional differentiable manifold R to the 2-dimensional differentiable manifold M - """ return self._dest_map @@ -1542,7 +1512,6 @@ def default_frame(self): sage: TM = M.tangent_bundle() sage: TM.default_frame() Coordinate frame (M, (∂/∂x,∂/∂y)) - """ def_bframe = self._base_space.default_frame() if self._def_frame is None and def_bframe is not None: @@ -1581,7 +1550,6 @@ def set_default_frame(self, frame): Vector frame (M, (e_0,e_1)) sage: M.default_frame() Vector frame (M, (e_0,e_1)) - """ from sage.manifolds.differentiable.vectorframe import VectorFrame if not isinstance(frame, VectorFrame): @@ -1642,7 +1610,6 @@ def set_orientation(self, orientation): sage: T12.set_orientation([e, f]) sage: T12.orientation() [Vector frame (U, (e_0,e_1)), Vector frame (V, (f_0,f_1))] - """ if self._dest_map.is_identity(): base_space = self._base_space @@ -1677,7 +1644,7 @@ def orientation(self): EXAMPLES: - In the trivial case, i.e. if the destination map is the identitiy + In the trivial case, i.e. if the destination map is the identity and the tangent bundle is covered by one frame, the orientation is easily obtained:: @@ -1741,7 +1708,6 @@ def orientation(self): sage: T11.orientation() [Coordinate frame (U, (∂/∂t,∂/∂z)), Coordinate frame (V, (∂/∂u,∂/∂v))] - """ if self._dest_map.is_identity(): self._orientation = self._base_space.orientation() diff --git a/src/sage/manifolds/differentiable/vectorfield.py b/src/sage/manifolds/differentiable/vectorfield.py index fd71f2ee2e6..44ae84089de 100644 --- a/src/sage/manifolds/differentiable/vectorfield.py +++ b/src/sage/manifolds/differentiable/vectorfield.py @@ -195,7 +195,6 @@ class VectorField(MultivectorField): v(f): W → ℝ (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y (t, u) ↦ 2*t*u + 2*t - """ def __init__(self, vector_field_module, name=None, latex_name=None): r""" @@ -229,7 +228,6 @@ def __init__(self, vector_field_module, name=None, latex_name=None): .. TODO:: Fix ``_test_pickling`` (in the superclass :class:`TensorField`). - """ MultivectorField.__init__(self, vector_field_module, 1, name=name, latex_name=latex_name) @@ -252,7 +250,6 @@ def _repr_(self): 'Vector field v on the 2-dimensional differentiable manifold M' sage: v # indirect doctest Vector field v on the 2-dimensional differentiable manifold M - """ description = "Vector field " if self._name is not None: @@ -271,7 +268,6 @@ def _new_instance(self): Vector field on the 2-dimensional differentiable manifold M sage: u.parent() is v.parent() True - """ return type(self)(self._vmodule) @@ -284,7 +280,6 @@ def _init_dependencies(self): sage: M = Manifold(2, 'M') sage: v = M.vector_field(name='v') sage: v._init_dependencies() - """ self._lie_der_along_self = {} @@ -297,10 +292,9 @@ def _del_dependencies(self): sage: M = Manifold(2, 'M') sage: v = M.vector_field(name='v') sage: v._del_dependencies() - """ if self._lie_der_along_self != {}: - for idtens, tens in self._lie_der_along_self.items(): + for tens in self._lie_der_along_self.values(): del tens._lie_derivatives[id(self)] self._lie_der_along_self.clear() @@ -337,7 +331,6 @@ def __call__(self, scalar): on V: (u, v) ↦ 2*(u^2 + v^2)/(u^4 + 2*u^2*v^2 + v^4 + 1) sage: s == f.differential()(a) True - """ if scalar._tensor_type == (0,1): # This is actually the action of the vector field on a 1-form, @@ -424,12 +417,12 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, values of the parameters that may appear in the coordinate expression of the vector field (see example below) - - ``label_axes`` -- (default: ``True``) boolean determining whether + - ``label_axes`` -- boolean (default: ``True``); determining whether the labels of the coordinate axes of ``chart`` shall be added to the graph; can be set to ``False`` if the graph is 3D and must be superposed with another graph - - ``color`` -- (default: 'blue') color of the arrows representing + - ``color`` -- (default: ``'blue'``) color of the arrows representing the vectors - ``max_range`` -- (default: 8) numerical value substituted to @@ -669,7 +662,6 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, color. To restore the original default options, it suffices to type:: sage: v.plot.reset() - """ from sage.rings.infinity import Infinity from sage.misc.functional import numerical_approx @@ -906,9 +898,7 @@ def bracket(self, other): - ``other`` -- a :class:`VectorField` - OUTPUT: - - - the :class:`VectorField` ``[self, other]`` + OUTPUT: the :class:`VectorField` ``[self, other]`` EXAMPLES:: @@ -930,7 +920,6 @@ def bracket(self, other): True sage: vw == w.lie_derivative(v) True - """ # Call of the Schouten-Nijenhuis bracket return MultivectorField.bracket(self, other) @@ -983,9 +972,7 @@ def curl(self, metric=None): :class:`~sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold`) and the latter is used to define the curl - OUTPUT: - - - instance of :class:`VectorField` representing the curl of ``self`` + OUTPUT: instance of :class:`VectorField` representing the curl of ``self`` EXAMPLES: @@ -1024,7 +1011,6 @@ def curl(self, metric=None): Vector field on the Euclidean space E^3 sage: s.display() 0 - """ if self._domain.dim() < 3: raise ValueError("the curl is not defined in dimension lower " + @@ -1140,7 +1126,6 @@ def dot_product(self, other, metric=None): sage: s.display() u.e_x: (0, 2*pi) → ℝ t ↦ cos(t) - """ default_metric = metric is None if default_metric: @@ -1238,7 +1223,6 @@ def norm(self, metric=None): sage: s.display() |C'|: (0, 2*pi) → ℝ t ↦ sqrt(4*cos(t)^4 - 3*cos(t)^2 + 1) - """ default_metric = metric is None if default_metric: @@ -1362,7 +1346,6 @@ def cross_product(self, other, metric=None): on the Euclidean space E^3 sage: w.display() C' x e_x = e_y - cos(t) e_z - """ if self._ambient_domain.dim() != 3: raise ValueError("the cross product is not defined in dimension " + @@ -1393,6 +1376,7 @@ def cross_product(self, other, metric=None): #****************************************************************************** + class VectorFieldParal(FiniteRankFreeModuleElement, MultivectorFieldParal, VectorField): r""" @@ -1598,7 +1582,6 @@ class VectorFieldParal(FiniteRankFreeModuleElement, MultivectorFieldParal, w = ∂/∂y sage: w.at(p) == v.at(Phi(p)) True - """ def __init__(self, vector_field_module, name=None, latex_name=None): r""" @@ -1628,7 +1611,6 @@ def __init__(self, vector_field_module, name=None, latex_name=None): sage: u.parent() is v.parent() True sage: TestSuite(u).run() - """ FiniteRankFreeModuleElement.__init__(self, vector_field_module, name=name, latex_name=latex_name) @@ -1658,7 +1640,6 @@ def _repr_(self) : 'Vector field v on the 2-dimensional differentiable manifold M' sage: v # indirect doctest Vector field v on the 2-dimensional differentiable manifold M - """ return VectorField._repr_(self) @@ -1675,7 +1656,6 @@ def _new_instance(self): Vector field on the 2-dimensional differentiable manifold M sage: u.parent() is v.parent() True - """ return type(self)(self._fmodule) @@ -1685,7 +1665,7 @@ def _del_derived(self, del_restrictions=True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the restrictions of ``self`` to subdomains are deleted TESTS:: @@ -1694,7 +1674,6 @@ def _del_derived(self, del_restrictions=True): sage: X. = M.chart() # makes M parallelizable sage: v = M.vector_field(name='v') sage: v._del_derived() - """ MultivectorFieldParal._del_derived(self, del_restrictions=del_restrictions) @@ -1728,7 +1707,6 @@ def __call__(self, scalar): sage: v(f).display() M → ℝ (x, y) ↦ 2*x^2*y - y^3 - """ # This method enforces VectorField.__call__ # instead of FiniteRankFreeModuleElement.__call__, which would have diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py index d5c3bc83e6a..43efcb19aa6 100644 --- a/src/sage/manifolds/differentiable/vectorfield_module.py +++ b/src/sage/manifolds/differentiable/vectorfield_module.py @@ -192,7 +192,6 @@ class VectorFieldModule(UniqueRepresentation, ReflexiveModule_base): The conversion map is actually the restriction of vector fields defined on `M` to `U`. - """ Element = VectorField @@ -223,7 +222,6 @@ def __init__(self, domain: DifferentiableManifold, dest_map: Optional[DiffMap] = In the above test suite, _test_elements is skipped because of the _test_pickling error of the elements (to be fixed in class TensorField) - """ self._domain = domain name = "X(" + domain._name @@ -266,7 +264,7 @@ def __init__(self, domain: DifferentiableManifold, dest_map: Optional[DiffMap] = def _element_constructor_(self, comp=[], frame=None, name=None, latex_name=None): r""" - Construct an element of the module + Construct an element of the module. TESTS:: @@ -281,7 +279,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, v = -x ∂/∂x + y ∂/∂y sage: XM(0) is XM.zero() True - """ try: if comp.is_trivial_zero(): @@ -318,7 +315,6 @@ def _an_element_(self): sage: XM = M.vector_field_module() sage: XM._an_element_() Vector field on the 2-dimensional differentiable manifold M - """ resu = self.element_class(self) for oc in self._domain.open_covers(trivial=False): @@ -332,7 +328,7 @@ def _an_element_(self): def _coerce_map_from_(self, other): r""" - Determine whether coercion to self exists from other parent. + Determine whether coercion to ``self`` exists from other parent. TESTS:: @@ -344,7 +340,6 @@ def _coerce_map_from_(self, other): False sage: XU._coerce_map_from_(XM) True - """ if isinstance(other, (VectorFieldModule, VectorFieldFreeModule)): return self._domain.is_subset(other._domain) and \ @@ -369,7 +364,6 @@ def _repr_(self): sage: XM # indirect doctest Module X(M) of vector fields on the 2-dimensional differentiable manifold M - """ description = "Module " if self._name is not None: @@ -394,7 +388,6 @@ def _latex_(self): '\\mathfrak{X}\\left(M\\right)' sage: latex(XM) # indirect doctest \mathfrak{X}\left(M\right) - """ if self._latex_name is None: return r"\text{" + str(self) + r"}" @@ -426,7 +419,6 @@ def domain(self) -> DifferentiableManifold: sage: XU = U.vector_field_module(dest_map=Phi) sage: XU.domain() 2-dimensional differentiable manifold U - """ return self._domain @@ -456,7 +448,6 @@ def ambient_domain(self) -> DifferentiableManifold: sage: XU = U.vector_field_module(dest_map=Phi) sage: XU.ambient_domain() 5-dimensional differentiable manifold M - """ return self._ambient_domain @@ -504,7 +495,6 @@ def destination_map(self): sage: XU.destination_map() Differentiable map Phi from the 2-dimensional differentiable manifold U to the 5-dimensional differentiable manifold M - """ return self._dest_map @@ -514,9 +504,9 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): INPUT: - - ``k`` -- non-negative integer; the contravariant rank, + - ``k`` -- nonnegative integer; the contravariant rank, the tensor type being `(k,l)` - - ``l`` -- non-negative integer; the covariant rank, + - ``l`` -- nonnegative integer; the covariant rank, the tensor type being `(k,l)` OUTPUT: @@ -552,7 +542,6 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): See :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldModule` for more examples and documentation. - """ if sym or antisym: raise NotImplementedError @@ -577,7 +566,7 @@ def exterior_power(self, p): INPUT: - - ``p`` -- non-negative integer + - ``p`` -- nonnegative integer OUTPUT: @@ -610,7 +599,6 @@ def exterior_power(self, p): :class:`~sage.manifolds.differentiable.multivector_module.MultivectorModule` for more examples and documentation. - """ try: return self._exterior_powers[p] @@ -637,7 +625,7 @@ def dual_exterior_power(self, p): INPUT: - - ``p`` -- non-negative integer + - ``p`` -- nonnegative integer OUTPUT: @@ -668,7 +656,6 @@ def dual_exterior_power(self, p): :class:`~sage.manifolds.differentiable.diff_form_module.DiffFormModule` for more examples and documentation. - """ try: return self._dual_exterior_powers[p] @@ -693,7 +680,6 @@ def dual(self): sage: XM.dual() Module Omega^1(M) of 1-forms on the 2-dimensional differentiable manifold M - """ return self.dual_exterior_power(1) @@ -725,7 +711,6 @@ def general_linear_group(self): :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldGroup` for more examples and documentation. - """ if self._general_linear_group is None: from sage.manifolds.differentiable.automorphismfield_group import \ @@ -783,7 +768,6 @@ def _tensor(self, tensor_type, name=None, latex_name=None, sym=None, :class:`~sage.manifolds.differentiable.tensorfield.TensorField` for more examples and documentation. - """ from sage.manifolds.differentiable.automorphismfield import \ AutomorphismField @@ -824,7 +808,8 @@ def _tensor(self, tensor_type, name=None, latex_name=None, sym=None, def tensor(self, *args, **kwds): r""" - Construct a tensor field on the domain of ``self`` or a tensor product of ``self`` with other modules. + Construct a tensor field on the domain of ``self`` or a tensor product + of ``self`` with other modules. If ``args`` consist of other parents, just delegate to :meth:`tensor_product`. @@ -942,7 +927,6 @@ def alternating_contravariant_tensor(self, degree, name=None, :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorField` for more examples and documentation. - """ if degree == 0: return self._domain.scalar_field(name=name, latex_name=latex_name) @@ -996,7 +980,6 @@ def alternating_form(self, degree: int, name=None, latex_name=None) -> DiffForm: :class:`~sage.manifolds.differentiable.diff_form.DiffForm` for more examples and documentation. - """ if degree == 0: return self._domain.scalar_field(name=name, latex_name=latex_name) @@ -1036,7 +1019,6 @@ def linear_form(self, name=None, latex_name=None): :class:`~sage.manifolds.differentiable.diff_form.DiffForm` for more examples and documentation. - """ return self.dual_exterior_power(1).element_class(self, 1, name=name, latex_name=latex_name) @@ -1076,7 +1058,6 @@ def automorphism(self, name=None, latex_name=None): :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField` for more examples and documentation. - """ return self.general_linear_group().element_class(self, name=name, latex_name=latex_name) @@ -1114,7 +1095,6 @@ def identity_map(self): sage: one = Id.copy('1'); one Field of tangent-space automorphisms 1 on the 2-dimensional differentiable manifold M - """ return self.general_linear_group().one() @@ -1131,7 +1111,6 @@ def zero(self): sage: XM.zero() Vector field zero on the 2-dimensional differentiable manifold M - """ zero = self.element_class(self, name='zero', latex_name='0') for frame in self._domain._frames: @@ -1153,8 +1132,8 @@ def metric(self, name: str, signature: Optional[int] = None, latex_name: Optiona INPUT: - - ``name`` -- (string) name given to the metric - - ``signature`` -- (integer; default: ``None``) signature `S` of the + - ``name`` -- string; name given to the metric + - ``signature`` -- integer (default: ``None``); signature `S` of the metric: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; if ``signature`` is not provided, @@ -1181,7 +1160,6 @@ def metric(self, name: str, signature: Optional[int] = None, latex_name: Optiona :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` for more documentation. - """ # signature: ndim = self._ambient_domain.dimension() @@ -1235,7 +1213,6 @@ def symplectic_form( sage: omega Symplectic form omega on the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 - """ from sage.manifolds.differentiable.symplectic_form import SymplecticForm @@ -1261,7 +1238,6 @@ def poisson_tensor( sage: varpi = XM.poisson_tensor(name='varpi', latex_name=r'\varpi') sage: varpi 2-vector field varpi on the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3 - """ from sage.manifolds.differentiable.poisson_tensor import PoissonTensorField @@ -1516,7 +1492,6 @@ class VectorFieldFreeModule(FiniteRankFreeModule): The Sage test suite for modules is passed:: sage: TestSuite(XM).run() - """ Element = VectorFieldParal @@ -1538,7 +1513,6 @@ def __init__(self, domain, dest_map=None): sage: XM is M.vector_field_module() True sage: TestSuite(XM).run() - """ from sage.manifolds.differentiable.scalarfield import DiffScalarField self._domain = domain @@ -1619,7 +1593,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, v = -y ∂/∂x + x ∂/∂y sage: XM(0) is XM.zero() True - """ try: if comp.is_trivial_zero(): @@ -1660,7 +1633,6 @@ def _coerce_map_from_(self, other): False sage: XU._coerce_map_from_(XM) True - """ if isinstance(other, (VectorFieldModule, VectorFieldFreeModule)): return (self._domain.is_subset(other._domain) @@ -1688,7 +1660,6 @@ def _repr_(self): sage: XM # indirect doctest Free module X(M) of vector fields on the 2-dimensional differentiable manifold M - """ description = "Free module " if self._name is not None: @@ -1728,7 +1699,6 @@ def domain(self) -> DifferentiableManifold: sage: XU = U.vector_field_module(dest_map=Phi) sage: XU.domain() 2-dimensional differentiable manifold U - """ return self._domain @@ -1760,7 +1730,6 @@ def ambient_domain(self) -> DifferentiableManifold: sage: XU = U.vector_field_module(dest_map=Phi) sage: XU.ambient_domain() 3-dimensional differentiable manifold M - """ return self._ambient_domain @@ -1809,7 +1778,6 @@ def destination_map(self) -> DiffMap: sage: XU.destination_map() Differentiable map Phi from the 2-dimensional differentiable manifold U to the 3-dimensional differentiable manifold M - """ return self._dest_map @@ -1820,9 +1788,9 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): INPUT: - - ``k`` -- non-negative integer; the contravariant rank, + - ``k`` -- nonnegative integer; the contravariant rank, the tensor type being `(k, l)` - - ``l`` -- non-negative integer; the covariant rank, + - ``l`` -- nonnegative integer; the covariant rank, the tensor type being `(k, l)` OUTPUT: @@ -1860,7 +1828,6 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldFreeModule` for more examples and documentation. - """ if sym or antisym: raise NotImplementedError @@ -1890,7 +1857,7 @@ def exterior_power(self, p): INPUT: - - ``p`` -- non-negative integer + - ``p`` -- nonnegative integer OUTPUT: @@ -1924,7 +1891,6 @@ def exterior_power(self, p): :class:`~sage.manifolds.differentiable.multivector_module.MultivectorFreeModule` for more examples and documentation. - """ try: return self._exterior_powers[p] @@ -1952,7 +1918,7 @@ def dual_exterior_power(self, p): INPUT: - - ``p`` -- non-negative integer + - ``p`` -- nonnegative integer OUTPUT: @@ -1983,7 +1949,6 @@ def dual_exterior_power(self, p): :class:`~sage.manifolds.differentiable.diff_form_module.DiffFormFreeModule` for more examples and documentation. - """ try: return self._dual_exterior_powers[p] @@ -2030,7 +1995,6 @@ def general_linear_group(self): :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldParalGroup` for more examples and documentation. - """ from sage.manifolds.differentiable.automorphismfield_group import \ AutomorphismFieldParalGroup @@ -2093,7 +2057,6 @@ def basis(self, symbol=None, latex_symbol=None, from_frame=None, See :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame` for more examples and documentation. - """ from sage.manifolds.differentiable.vectorframe import VectorFrame if symbol is None: @@ -2173,7 +2136,6 @@ def _tensor(self, tensor_type, name=None, latex_name=None, sym=None, See :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal` for more examples and documentation. - """ from sage.manifolds.differentiable.automorphismfield import ( AutomorphismField, AutomorphismFieldParal) @@ -2264,7 +2226,6 @@ def tensor_from_comp(self, tensor_type, comp, name=None, manifold M sage: t.display() t = (x + 1) dx⊗dx - y dx⊗dy + x*y dy⊗dx + (-y^2 + 2) dy⊗dy - """ from sage.tensor.modules.comp import (CompWithSym, CompFullyAntiSym) @@ -2342,7 +2303,6 @@ def sym_bilinear_form(self, name=None, latex_name=None): :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal` for more examples and documentation. - """ return self.tensor((0,2), name=name, latex_name=latex_name, sym=(0,1)) @@ -2360,8 +2320,8 @@ def metric(self, name, signature=None, latex_name=None): INPUT: - - ``name`` -- (string) name given to the metric - - ``signature`` -- (integer; default: ``None``) signature `S` of the + - ``name`` -- string; name given to the metric + - ``signature`` -- integer (default: ``None``); signature `S` of the metric: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; if ``signature`` is not provided, @@ -2389,7 +2349,6 @@ def metric(self, name, signature=None, latex_name=None): :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetricParal` for more documentation. - """ ndim = self._ambient_domain.dimension() try: diff --git a/src/sage/manifolds/differentiable/vectorframe.py b/src/sage/manifolds/differentiable/vectorframe.py index 63c293a3e56..594d2e9a729 100644 --- a/src/sage/manifolds/differentiable/vectorframe.py +++ b/src/sage/manifolds/differentiable/vectorframe.py @@ -296,7 +296,6 @@ class CoFrame(FreeModuleCoBasis): (0, 1, 0) sage: e[3](v[1]).expr(), e[3](v[2]).expr(), e[3](v[3]).expr() (0, 0, 1) - """ def __init__(self, frame, symbol, latex_symbol=None, indices=None, latex_indices=None): @@ -311,7 +310,6 @@ def __init__(self, frame, symbol, latex_symbol=None, indices=None, sage: f = CoFrame(e, 'f'); f Coframe (M, (f^0,f^1)) sage: TestSuite(f).run() - """ self._domain = frame._domain self._manifold = self._domain.manifold() @@ -346,7 +344,6 @@ def _repr_(self): sage: h = M.vector_frame('h', dest_map=phi) sage: h.coframe()._repr_() 'Coframe (M, (h^1,h^2,h^3)) with values on the 3-dimensional differentiable manifold N' - """ description = "Coframe " + self._name dest_map = self._basis.destination_map() @@ -394,7 +391,6 @@ def at(self, point): differentiable manifold M sage: fp is X.frame().at(p).dual_basis() True - """ return self._basis.at(point).dual_basis() @@ -424,7 +420,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, - ``index_position`` -- (default: ``'up'``) determines the position of the indices labelling the 1-forms of the coframe; can be either ``'down'`` or ``'up'`` - - ``include_domain`` -- (default: ``True``) boolean determining whether + - ``include_domain`` -- boolean (default: ``True``); determining whether the name of the domain is included in the beginning of the coframe name @@ -449,7 +445,6 @@ def set_name(self, symbol, latex_symbol=None, indices=None, Coframe (M, (e^x,e^y)) sage: latex(e) \left(M, \left(e^{\xi},e^{\zeta}\right)\right) - """ super().set_name(symbol, latex_symbol=latex_symbol, indices=indices, @@ -631,7 +626,6 @@ class VectorFrame(FreeModuleBasis): True sage: f in U.vector_field_module(dest_map=Phi).bases() True - """ # The following class attribute must be redefined by any derived class: @@ -657,7 +651,6 @@ def __classcall_private__(cls, vector_field_module, symbol, Coframe (M, (A,B)) sage: e is VectorFrame(XM, ('a', 'b'), symbol_dual=('A', 'B')) True - """ if isinstance(symbol, list): symbol = tuple(symbol) @@ -692,7 +685,6 @@ def __init__(self, vector_field_module, symbol, latex_symbol=None, sage: e = VectorFrame(XM, 'e', latex_symbol=r'\epsilon'); e Vector frame (M, (e_0,e_1)) sage: TestSuite(e).run() - """ from sage.manifolds.differentiable.manifold import DifferentiableManifold # Some sanity check: @@ -788,7 +780,6 @@ def _repr_(self): sage: h = M.vector_frame('h', dest_map=phi) sage: h._repr_() 'Vector frame (M, (h_1,h_2,h_3)) with values on the 3-dimensional differentiable manifold N' - """ description = "Vector frame " + self._name if self._dest_map is not self._domain.identity_map(): @@ -831,9 +822,7 @@ def _new_instance(self, symbol, latex_symbol=None, indices=None, - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol`` but for the dual coframe - OUTPUT: - - - instance of :class:`VectorFrame` + OUTPUT: instance of :class:`VectorFrame` TESTS:: @@ -841,7 +830,6 @@ def _new_instance(self, symbol, latex_symbol=None, indices=None, sage: e = M.vector_frame('e') sage: e._new_instance('f') Vector frame (M, (f_0,f_1)) - """ return VectorFrame(self._fmodule, symbol, latex_symbol=latex_symbol, indices=indices, latex_indices=latex_indices, @@ -869,7 +857,6 @@ def domain(self): sage: f = e.restrict(U) sage: f.domain() Open subset U of the 2-dimensional differentiable manifold M - """ return self._domain @@ -913,7 +900,6 @@ def ambient_domain(self): 2-dimensional differentiable manifold M sage: f.domain() 1-dimensional differentiable manifold U - """ return self._ambient_domain @@ -952,7 +938,6 @@ def destination_map(self): sage: f.destination_map() Differentiable map Phi from the 1-dimensional differentiable manifold U to the 2-dimensional differentiable manifold M - """ return self._dest_map @@ -969,7 +954,6 @@ def coframe(self): sage: X. = M.chart() sage: X.frame().coframe() Coordinate coframe (M, (dx,dy)) - """ return self._coframe @@ -1060,7 +1044,6 @@ def new_frame(self, change_of_frame, symbol, latex_symbol=None, [1/2*sqrt(3), -1/2] sage: e[1].comp(n)[:] [1/2, 1/2*sqrt(3)] - """ the_new_frame = self.new_basis(change_of_frame, symbol, latex_symbol=latex_symbol, @@ -1085,9 +1068,7 @@ def restrict(self, subdomain): - ``subdomain`` -- open subset `V` of the current frame domain `U` - OUTPUT: - - - the restriction of the current frame to `V` as a :class:`VectorFrame` + OUTPUT: the restriction of the current frame to `V` as a :class:`VectorFrame` EXAMPLES: @@ -1117,7 +1098,6 @@ def restrict(self, subdomain): True sage: e_U[2] is e[2].restrict(U) True - """ if subdomain == self._domain: return self @@ -1239,7 +1219,6 @@ def structure_coeff(self): -1/r sage: c[3,2,3] # C^3_{23} -cos(th)/(r*sin(th)) - """ from sage.tensor.modules.comp import CompWithSym @@ -1278,9 +1257,7 @@ def along(self, mapping): - ``mapping`` -- differentiable map `\Phi: U \rightarrow V` - OUTPUT: - - - vector frame `\tilde e` along `U` defined above. + OUTPUT: vector frame `\tilde e` along `U` defined above EXAMPLES: @@ -1313,7 +1290,6 @@ def along(self, mapping): sage: te is e.along(Phi) True - """ dom = self._domain if mapping.codomain().is_subset(dom): @@ -1426,7 +1402,6 @@ def at(self, point): 2-dimensional differentiable manifold M sage: fp.dual_basis() is f.coframe().at(p) True - """ # Case of a non-trivial destination map if self._from_frame is not None: @@ -1539,7 +1514,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, - ``index_position`` -- (default: ``'down'``) determines the position of the indices labelling the vector fields of the frame; can be either ``'down'`` or ``'up'`` - - ``include_domain`` -- (default: ``True``) boolean determining whether + - ``include_domain`` -- boolean (default: ``True``); determining whether the name of the domain is included in the beginning of the vector frame name @@ -1566,7 +1541,6 @@ def set_name(self, symbol, latex_symbol=None, indices=None, ....: latex_indices=[r'\alpha', r'\beta']) sage: latex(e) \left(M, \left(E_{\alpha},E_{\beta}\right)\right) - """ super().set_name(symbol, latex_symbol=latex_symbol, indices=indices, @@ -1580,6 +1554,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, #****************************************************************************** + class CoordCoFrame(CoFrame): r""" Coordinate coframe on a differentiable manifold. @@ -1652,7 +1627,6 @@ class CoordCoFrame(CoFrame): 2-form ddx on the 3-dimensional differentiable manifold M sage: dX[1].exterior_derivative() == 0 True - """ def __init__(self, coord_frame, symbol, latex_symbol=None, indices=None, latex_indices=None): @@ -1667,7 +1641,6 @@ def __init__(self, coord_frame, symbol, latex_symbol=None, indices=None, sage: f = CoordCoFrame(X.frame(), 'omega'); f Coordinate coframe (M, (omega^0,omega^1)) sage: TestSuite(f).run() - """ if not isinstance(coord_frame, CoordFrame): raise TypeError("the first argument must be a coordinate frame") @@ -1690,12 +1663,12 @@ def _repr_(self): 'Coordinate coframe (M, (dx,dy))' sage: f # indirect doctest Coordinate coframe (M, (dx,dy)) - """ return "Coordinate coframe " + self._name #****************************************************************************** + class CoordFrame(VectorFrame): r""" Coordinate frame on a differentiable manifold. @@ -1724,7 +1697,6 @@ class CoordFrame(VectorFrame): Vector field ∂/∂ph on the 2-dimensional differentiable manifold S^2 sage: latex(b) \left(S^2, \left(\frac{\partial}{\partial {\theta} },\frac{\partial}{\partial {\phi} }\right)\right) - """ # The following class attribute must be redefined by any derived class: @@ -1742,7 +1714,6 @@ def __init__(self, chart): sage: e = CoordFrame(X); e Coordinate frame (M, (∂/∂x,∂/∂y)) sage: TestSuite(e).run() - """ from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_partial @@ -1793,7 +1764,6 @@ def _repr_(self): 'Coordinate frame (M, (∂/∂x,∂/∂y))' sage: e # indirect doctest Coordinate frame (M, (∂/∂x,∂/∂y)) - """ return "Coordinate frame " + self._name @@ -1813,7 +1783,6 @@ def chart(self): sage: U = M.open_subset('U', coord_def={X: x>0}) sage: e.restrict(U).chart() Chart (U, (x, y)) - """ return self._chart @@ -1854,7 +1823,6 @@ def structure_coeff(self): positions (1, 2) sage: c == 0 True - """ from sage.tensor.modules.comp import CompWithSym # A zero CompWithSym diff --git a/src/sage/manifolds/family.py b/src/sage/manifolds/family.py index 1b150b46d89..565fa2401cc 100644 --- a/src/sage/manifolds/family.py +++ b/src/sage/manifolds/family.py @@ -28,6 +28,7 @@ from functools import total_ordering from sage.sets.family import FiniteFamily + @total_ordering class ManifoldObjectFiniteFamily(FiniteFamily): @@ -63,7 +64,6 @@ class ManifoldObjectFiniteFamily(FiniteFamily): Traceback (most recent call last): ... TypeError: all objects must have the same manifold - """ def __init__(self, objects=(), keys=None): r""" @@ -89,7 +89,6 @@ def __init__(self, objects=(), keys=None): sage: ManifoldSubsetFiniteFamily(gen) Set {I, M} of subsets of the 2-dimensional topological manifold M - """ if isinstance(objects, dict): dictionary = objects @@ -124,7 +123,6 @@ def _repr_object_type(self): sage: B = M.subset('B') sage: ManifoldObjectFiniteFamily([A, B]).__repr__() # indirect doctest 'Set {A, B} of objects of the 2-dimensional topological manifold M' - """ return "objects" @@ -163,7 +161,6 @@ def __repr__(self): sage: B = M.subset('B') sage: ManifoldObjectFiniteFamily([A, B]).__repr__() 'Set {A, B} of objects of the 2-dimensional topological manifold M' - """ if self: return "Set {} of {} of the {}".format(self._name, self._repr_object_type(), self._manifold) @@ -185,6 +182,7 @@ def _latex_(self): """ return self._latex_name + class ManifoldSubsetFiniteFamily(ManifoldObjectFiniteFamily): r""" @@ -216,7 +214,6 @@ class ManifoldSubsetFiniteFamily(ManifoldObjectFiniteFamily): Traceback (most recent call last): ... TypeError: all open subsets must have the same manifold - """ @classmethod @@ -257,7 +254,6 @@ def _repr_object_type(self): sage: B = M.subset('B') sage: ManifoldSubsetFiniteFamily([A, B]).__repr__() # indirect doctest 'Set {A, B} of subsets of the 2-dimensional topological manifold M' - """ if all(subset.is_open() for subset in self): return "open subsets" diff --git a/src/sage/manifolds/local_frame.py b/src/sage/manifolds/local_frame.py index 21b506d3eb9..42e1579640d 100644 --- a/src/sage/manifolds/local_frame.py +++ b/src/sage/manifolds/local_frame.py @@ -252,7 +252,6 @@ class LocalCoFrame(FreeModuleCoBasis): (0, 1, 0) sage: f[3](e[1]).expr(), f[3](e[2]).expr(), f[3](e[3]).expr() (0, 0, 1) - """ def __init__(self, frame, symbol, latex_symbol=None, indices=None, latex_indices=None): @@ -268,7 +267,6 @@ def __init__(self, frame, symbol, latex_symbol=None, indices=None, sage: f = LocalCoFrame(e, 'f'); f Local coframe (E|_M, (f^0,f^1)) sage: TestSuite(f).run() - """ self._domain = frame.domain() self._base_space = frame.base_space() @@ -295,7 +293,6 @@ def _repr_(self): 'Local coframe (E|_M, (e^0,e^1))' sage: f # indirect doctest Local coframe (E|_M, (e^0,e^1)) - """ desc = "Local coframe " + self._name return desc @@ -340,7 +337,6 @@ def at(self, point): topological manifold M sage: e_dual_p is e.at(p).dual_basis() True - """ return self._basis.at(point).dual_basis() @@ -370,7 +366,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, - ``index_position`` -- (default: ``'up'``) determines the position of the indices labelling the linear forms of the coframe; can be either ``'down'`` or ``'up'`` - - ``include_domain`` -- (default: ``True``) boolean determining whether + - ``include_domain`` -- boolean (default: ``True``); determining whether the name of the domain is included in the beginning of the coframe name @@ -396,7 +392,6 @@ def set_name(self, symbol, latex_symbol=None, indices=None, Local coframe (E|_M, (e^x,e^y)) sage: latex(e) \left(E|_{M}, \left(e^{\xi},e^{\zeta}\right)\right) - """ super().set_name(symbol, latex_symbol=latex_symbol, indices=indices, @@ -413,6 +408,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, #****************************************************************************** + class LocalFrame(FreeModuleBasis): r""" Local frame on a vector bundle. @@ -556,7 +552,6 @@ class LocalFrame(FreeModuleBasis): sage: f.at(p) Basis (f_1,f_2) on the Fiber of F at Point p on the 2-dimensional topological manifold N - """ # The following class attribute must be redefined by any derived class: @@ -583,7 +578,6 @@ def __classcall_private__(cls, section_module, symbol, Local coframe (E|_M, (A,B)) sage: e is LocalFrame(C0, ('a', 'b'), symbol_dual=('A', 'B')) True - """ if isinstance(symbol, list): symbol = tuple(symbol) @@ -618,7 +612,6 @@ def __init__(self, section_module, symbol, latex_symbol=None, indices=None, sage: e = LocalFrame(C0, 'e', latex_symbol=r'\epsilon'); e Local frame (E|_M, (e_0,e_1)) sage: TestSuite(e).run() - """ ### # Some sanity check: @@ -679,7 +672,6 @@ def _repr_(self): 'Local frame (E|_M, (e_0,e_1))' sage: e # indirect doctest Local frame (E|_M, (e_0,e_1)) - """ desc = "Local frame " + self._name return desc @@ -716,9 +708,7 @@ def _new_instance(self, symbol, latex_symbol=None, indices=None, - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol`` but for the dual coframe - OUTPUT: - - - instance of :class:`LocalFrame` + OUTPUT: instance of :class:`LocalFrame` TESTS:: @@ -727,7 +717,6 @@ def _new_instance(self, symbol, latex_symbol=None, indices=None, sage: e = E.local_frame('e') sage: e._new_instance('f') Local frame (E|_M, (f_0,f_1)) - """ return LocalFrame(self._fmodule, symbol, latex_symbol=latex_symbol, indices=indices, latex_indices=latex_indices, @@ -749,7 +738,6 @@ def domain(self): Local frame (E|_U, (e_0,e_1)) sage: e.domain() Open subset U of the 3-dimensional topological manifold M - """ return self._domain @@ -765,7 +753,6 @@ def base_space(self): sage: e = E.local_frame('e', domain=U) sage: e.base_space() 3-dimensional topological manifold M - """ return self._base_space @@ -784,7 +771,6 @@ def vector_bundle(self): 3-dimensional topological manifold M sage: e.vector_bundle() is E True - """ return self._vbundle @@ -800,7 +786,6 @@ def coframe(self): Local frame (E|_M, (e_0,e_1)) sage: e.coframe() Local coframe (E|_M, (e^0,e^1)) - """ return self._coframe @@ -892,7 +877,6 @@ def new_frame(self, change_of_frame, symbol, latex_symbol=None, [1/2*sqrt(3), -1/2] sage: e[2].comp(f)[:] [1/2, 1/2*sqrt(3)] - """ the_new_frame = self.new_basis(change_of_frame, symbol, latex_symbol=latex_symbol, @@ -916,9 +900,7 @@ def restrict(self, subdomain): - ``subdomain`` -- open subset `V` of the current frame domain `U` - OUTPUT: - - - the restriction of the current frame to `V` as a :class:`LocalFrame` + OUTPUT: the restriction of the current frame to `V` as a :class:`LocalFrame` EXAMPLES: @@ -954,7 +936,6 @@ def restrict(self, subdomain): True sage: f_U[2] is f[2].restrict(U) True - """ if subdomain == self._domain: return self @@ -1111,7 +1092,6 @@ def at(self, point): 2-dimensional topological manifold M sage: fp.dual_basis() is f.coframe().at(p) True - """ # Determination of the vector bundle fiber: if point not in self._domain: @@ -1209,7 +1189,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, - ``index_position`` -- (default: ``'down'``) determines the position of the indices labelling the local sections of the frame; can be either ``'down'`` or ``'up'`` - - ``include_domain`` -- (default: ``True``) boolean determining whether + - ``include_domain`` -- boolean (default: ``True``); determining whether the name of the domain is included in the beginning of the vector frame name @@ -1237,7 +1217,6 @@ def set_name(self, symbol, latex_symbol=None, indices=None, ....: latex_indices=[r'\alpha', r'\beta']) sage: latex(e) \left(E|_{M}, \left(E_{\alpha},E_{\beta}\right)\right) - """ super().set_name(symbol, latex_symbol=latex_symbol, indices=indices, @@ -1254,6 +1233,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, #****************************************************************************** + class TrivializationCoFrame(LocalCoFrame): r""" Trivialization coframe on a vector bundle. @@ -1341,7 +1321,6 @@ class `C^k` and rank `n` over the topological field `K` and over a (0, 1, 0) sage: f[3](e[1]).expr(), f[3](e[2]).expr(), f[3](e[3]).expr() (0, 0, 1) - """ def __init__(self, triv_frame, symbol, latex_symbol=None, indices=None, latex_indices=None): @@ -1357,7 +1336,6 @@ def __init__(self, triv_frame, symbol, latex_symbol=None, sage: f = TrivializationCoFrame(phi.frame(), 'omega'); f Trivialization coframe (E|_M, (omega^0,omega^1)) sage: TestSuite(f).run() - """ if not isinstance(triv_frame, TrivializationFrame): raise TypeError("the first argument must be a local trivialization " @@ -1383,12 +1361,12 @@ def _repr_(self): 'Trivialization coframe (E|_M, ((phi^*e^1),(phi^*e^2)))' sage: e # indirect doctest Trivialization coframe (E|_M, ((phi^*e^1),(phi^*e^2))) - """ return "Trivialization coframe " + self._name #****************************************************************************** + class TrivializationFrame(LocalFrame): r""" Trivialization frame on a topological vector bundle. @@ -1419,7 +1397,6 @@ class TrivializationFrame(LocalFrame): Trivialization frame (E|_U, ((phi_U^*e_1),(phi_U^*e_2))) sage: latex(phi_U.frame()) \left(E|_{U}, \left(\left(phi_U^* e_{ 1 }\right),\left(phi_U^* e_{ 2 }\right)\right)\right) - """ # The following class attribute must be redefined by any derived class: @@ -1436,7 +1413,6 @@ def __init__(self, trivialization): sage: phi = E.trivialization('phi') sage: e = phi.frame() sage: TestSuite(e).run() - """ from sage.misc.latex import latex from .trivialization import Trivialization @@ -1492,7 +1468,6 @@ def _repr_(self): 'Trivialization frame (E|_M, ((phi^*e_1),(phi^*e_2)))' sage: e # indirect doctest Trivialization frame (E|_M, ((phi^*e_1),(phi^*e_2))) - """ return "Trivialization frame " + self._name @@ -1511,6 +1486,5 @@ def trivialization(self): Trivialization (phi_U, E|_U) sage: e.trivialization() is phi_U True - """ return self._trivialization diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py index 616eab15786..c27cd0b6434 100644 --- a/src/sage/manifolds/manifold.py +++ b/src/sage/manifolds/manifold.py @@ -2,7 +2,7 @@ Topological Manifolds Given a topological field `K` (in most applications, `K = \RR` or -`K = \CC`) and a non-negative integer `n`, a *topological manifold of +`K = \CC`) and a nonnegative integer `n`, a *topological manifold of dimension* `n` *over K* is a topological space `M` such that - `M` is a Hausdorff space, @@ -365,7 +365,7 @@ class TopologicalManifold(ManifoldSubset): Topological manifold over a topological field `K`. Given a topological field `K` (in most applications, `K = \RR` or - `K = \CC`) and a non-negative integer `n`, a *topological manifold of + `K = \CC`) and a nonnegative integer `n`, a *topological manifold of dimension* `n` *over K* is a topological space `M` such that - `M` is a Hausdorff space, @@ -688,7 +688,6 @@ def _an_element_(self): True sage: p.coord() (-pi - 1, 2) - """ from sage.rings.infinity import Infinity if self._def_chart is None: @@ -781,7 +780,6 @@ def __contains__(self, point): False sage: p in V # indirect doctest False - """ # for efficiency, a quick test first: if point.parent() is self: @@ -811,7 +809,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -820,9 +818,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): - ``supersets`` -- (default: only ``self``) list of sets that the new open subset is a subset of - OUTPUT: - - - the open subset, as an instance of :class:`TopologicalManifold` + OUTPUT: the open subset, as an instance of :class:`TopologicalManifold` EXAMPLES: @@ -884,7 +880,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): True sage: M.point((1,2)) in U False - """ resu = TopologicalManifold(self._dim, name, self._field, self._structure, @@ -904,7 +899,7 @@ def _init_open_subset(self, resu, coord_def): INPUT: - ``resu`` -- an instance of :class:`TopologicalManifold` or - a subclass. + a subclass - ``coord_def`` -- (default: ``{}``) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -948,7 +943,7 @@ def get_chart(self, coordinates, domain=None): INPUT: - - ``coordinates`` -- single string composed of the coordinate symbols + - ``coordinates`` -- single string composed of the coordinate symbols separated by a space - ``domain`` -- (default: ``None``) string containing the name of the chart's domain, which must be a subset of the current manifold; if @@ -983,7 +978,6 @@ def get_chart(self, coordinates, domain=None): Chart (U, (r, ph)) sage: M.get_chart('r ph', domain='U') is Y True - """ if domain is None: dom = self @@ -1015,7 +1009,6 @@ def dimension(self): sage: dim(M) 2 - """ return self._dim @@ -1025,9 +1018,7 @@ def base_field(self): r""" Return the field on which the manifold is defined. - OUTPUT: - - - a topological field + OUTPUT: a topological field EXAMPLES:: @@ -1040,7 +1031,6 @@ def base_field(self): sage: M = Manifold(3, 'M', structure='topological', field=QQ) sage: M.base_field() Rational Field - """ return self._field @@ -1050,12 +1040,11 @@ def base_field_type(self): OUTPUT: - - a string describing the field, with three possible values: + A string describing the field, with three possible values: - - ``'real'`` for the real field `\RR` - - ``'complex'`` for the complex field `\CC` - - ``'neither_real_nor_complex'`` for a field different from `\RR` - and `\CC` + - ``'real'`` for the real field `\RR` + - ``'complex'`` for the complex field `\CC` + - ``'neither_real_nor_complex'`` for a field different from `\RR` and `\CC` EXAMPLES:: @@ -1068,7 +1057,6 @@ def base_field_type(self): sage: M = Manifold(3, 'M', structure='topological', field=QQ) sage: M.base_field_type() 'neither_real_nor_complex' - """ return self._field_type @@ -1093,7 +1081,6 @@ def start_index(self): sage: M = Manifold(3, 'M', structure='topological', start_index=1) sage: M.start_index() 1 - """ return self._sindex @@ -1109,9 +1096,7 @@ def irange(self, start=None, end=None): if ``None``, the value returned by :meth:`start_index()` plus `n - 1`, where `n` is the manifold dimension, is assumed - OUTPUT: - - - an iterable index, starting from `i_0` and ending at `i_0 + i_n` + OUTPUT: an iterable index, starting from `i_0` and ending at `i_0 + i_n` EXAMPLES: @@ -1143,7 +1128,6 @@ def irange(self, start=None, end=None): sage: next(M.irange()) == M.start_index() True - """ si = self._sindex if start is None: @@ -1248,7 +1232,6 @@ def atlas(self) -> list[Chart]: .. SEEALSO:: :meth:`top_charts` - """ return list(self._atlas) # Make a (shallow) copy @@ -1283,7 +1266,6 @@ def top_charts(self): :meth:`atlas` for the complete list of charts defined on the manifold. - """ return list(self._top_charts) # Make a (shallow) copy @@ -1315,7 +1297,6 @@ def default_chart(self): Chart (A, (t, z)) sage: A.default_chart() Chart (A, (t, z)) - """ return self._def_chart @@ -1339,7 +1320,6 @@ def set_default_chart(self, chart): sage: M.set_default_chart(c_uv) sage: M.default_chart() Chart (M, (u, v)) - """ from .chart import Chart if not isinstance(chart, Chart): @@ -1378,7 +1358,6 @@ def coord_change(self, chart1, chart2): Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)) sage: M.coord_change(c_xy, c_uv) # returns the coord. change defined above Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)) - """ if (chart1, chart2) not in self._coord_changes: raise TypeError("the change of coordinates from " + @@ -1391,9 +1370,7 @@ def coord_changes(self): Return the changes of coordinates (transition maps) defined on subsets of the manifold. - OUTPUT: - - - dictionary of changes of coordinates, with pairs of charts as keys + OUTPUT: dictionary of changes of coordinates, with pairs of charts as keys EXAMPLES: @@ -1431,7 +1408,6 @@ def coord_changes(self): Chart (M, (u, v))): Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)), (Chart (M, (x, y)), Chart (M, (r, s))): Change of coordinates from Chart (M, (x, y)) to Chart (M, (r, s))} - """ return self._coord_changes.copy() @@ -1455,7 +1431,6 @@ def is_manifestly_coordinate_domain(self): sage: Y. = M.chart() sage: M.is_manifestly_coordinate_domain() True - """ return bool(self._covering_charts) @@ -1483,7 +1458,7 @@ def chart( INPUT: - - ``coordinates`` -- (default: ``''`` (empty string)) string + - ``coordinates`` -- (default: ``''`` (empty string)) string defining the coordinate symbols, ranges and possible periodicities, see below - ``names`` -- (default: ``None``) unused argument, except if @@ -1497,7 +1472,7 @@ def chart( - ``'sympy'``: SymPy - ``None``: the current calculus method defined on the manifold is used (cf. :meth:`set_calculus_method`) - - ``coord_restrictions``: Additional restrictions on the coordinates. + - ``coord_restrictions`` -- additional restrictions on the coordinates. See below. The coordinates declared in the string ``coordinates`` are @@ -1632,7 +1607,6 @@ def chart( :class:`~sage.manifolds.chart.Chart` and :class:`~sage.manifolds.chart.RealChart` for more examples, especially regarding the coordinates ranges and restrictions. - """ if calc_method is None: calc_method = self._calculus_method @@ -1652,7 +1626,6 @@ def is_open(self): sage: M = Manifold(2, 'M', structure='topological') sage: M.is_open() True - """ return True @@ -1690,7 +1663,6 @@ def set_orientation(self, orientation): sage: M.set_orientation([c_xy, c_uv]) sage: M.orientation() [Chart (U, (x, y)), Chart (V, (u, v))] - """ chart_type = self._structure.chart if isinstance(orientation, chart_type): @@ -1778,7 +1750,6 @@ def orientation(self): sage: W = U.intersection(V, name='W') sage: W.orientation() [Chart (W, (x, y))] - """ if not self._orientation: # try to get an orientation from super domains: @@ -1840,7 +1811,6 @@ def has_orientation(self): sage: M.set_orientation([c_xy, c_uv]) sage: M.has_orientation() True - """ return bool(self.orientation()) @@ -1853,9 +1823,7 @@ def _get_min_covering(self, object_list): - list of objects having an `domain` method - OUTPUT: - - - set of objects + OUTPUT: set of objects TESTS:: @@ -1865,7 +1833,6 @@ def _get_min_covering(self, object_list): sage: c3. = M.chart() sage: M._get_min_covering([c1, c2, c3]) {Chart (M, (z,))} - """ min_obj_set = set() for obj in object_list: @@ -1891,7 +1858,7 @@ def vector_bundle(self, rank, name, field='real', latex_name=None): - ``name`` -- name given to the total space - ``field`` -- (default: ``'real'``) topological field giving the vector space structure to the fibers - - ``latex_name`` -- optional LaTeX name for the total space + - ``latex_name`` -- (optional) LaTeX name for the total space OUTPUT: @@ -1904,7 +1871,6 @@ def vector_bundle(self, rank, name, field='real', latex_name=None): sage: M.vector_bundle(2, 'E') Topological real vector bundle E -> M of rank 2 over the base space 2-dimensional topological manifold M - """ from sage.manifolds.vector_bundle import TopologicalVectorBundle return TopologicalVectorBundle(rank, name, self, field=field, @@ -1941,7 +1907,6 @@ def scalar_field_algebra(self): sage: U.scalar_field_algebra() is CU True - """ return self._scalar_field_algebra @@ -2032,7 +1997,6 @@ def scalar_field( :meth:`constant_scalar_field`, :meth:`zero_scalar_field`, :meth:`one_scalar_field` - """ if isinstance(coord_expression, dict): # check validity of entry @@ -2122,7 +2086,6 @@ def zero_scalar_field(self): Algebra of scalar fields on the 2-dimensional topological manifold M sage: f is M.scalar_field_algebra().zero() True - """ return self._zero_scalar_field @@ -2150,13 +2113,12 @@ def one_scalar_field(self): Algebra of scalar fields on the 2-dimensional topological manifold M sage: f is M.scalar_field_algebra().one() True - """ return self._one_scalar_field class options(GlobalOptions): r""" - Sets and displays the options for manifolds. If no parameters + Set and displays the options for manifolds. If no parameters are set, then the function returns a copy of the options dictionary. The ``options`` to manifolds can be accessed as the method @@ -2249,7 +2211,6 @@ def _Hom_(self, other, category=None): sage: H is Hom(M, N) True - """ return self._structure.homset(self, other) @@ -2345,7 +2306,6 @@ def continuous_map(self, codomain, coord_functions=None, chart1=None, Allow the construction of continuous maps from ``self`` to the base field (considered as a trivial 1-dimensional manifold). - """ if (not isinstance(codomain, TopologicalManifold) or codomain.base_field() != self.base_field()): @@ -2442,7 +2402,6 @@ def homeomorphism(self, codomain, coord_functions=None, chart1=None, See the documentation of :class:`~sage.manifolds.continuous_map.ContinuousMap` for more examples. - """ homset = Hom(self, codomain) if coord_functions is None: @@ -2516,7 +2475,6 @@ def identity_map(self): See :class:`~sage.manifolds.continuous_map.ContinuousMap` for the complete documentation. - """ return Hom(self, self).one() @@ -2593,7 +2551,6 @@ def set_calculus_method(self, method): :meth:`~sage.manifolds.chart.Chart.calculus_method` for a control of the calculus method chart by chart - """ self._calculus_method = method for chart in self._atlas: @@ -2713,7 +2670,6 @@ def set_simplify_function(self, simplifying_func, method=None): 1 sage: type(s.expr()) - """ for chart in self._atlas: chart.calculus_method().set_simplify_function(simplifying_func, @@ -2739,7 +2695,7 @@ def Manifold( Construct a manifold of a given type over a topological field. Given a topological field `K` (in most applications, `K = \RR` or - `K = \CC`) and a non-negative integer `n`, a *topological manifold of + `K = \CC`) and a nonnegative integer `n`, a *topological manifold of dimension* `n` *over K* is a topological space `M` such that - `M` is a Hausdorff space, @@ -2795,7 +2751,7 @@ def Manifold( - ``extra_kwds`` -- keywords meaningful only for some specific types of manifolds: - - ``diff_degree`` -- (only for differentiable manifolds; default: + - ``diff_degree`` -- (only for differentiable manifolds; default: ``infinity``): the degree of differentiability - ``ambient`` -- (only to construct a submanifold): the ambient manifold - ``metric_name`` -- (only for pseudo-Riemannian manifolds; default: diff --git a/src/sage/manifolds/manifold_homset.py b/src/sage/manifolds/manifold_homset.py index 664c8f422a7..c390233ca55 100644 --- a/src/sage/manifolds/manifold_homset.py +++ b/src/sage/manifolds/manifold_homset.py @@ -1,5 +1,5 @@ r""" -Sets of Morphisms between Topological Manifolds +Set of Morphisms between Topological Manifolds The class :class:`TopologicalManifoldHomset` implements sets of morphisms between two topological manifolds over the same topological @@ -33,6 +33,7 @@ from sage.manifolds.continuous_map import ContinuousMap from sage.misc.cachefunc import cached_method + class TopologicalManifoldHomset(UniqueRepresentation, Homset): r""" Set of continuous maps between two topological manifolds. @@ -134,7 +135,6 @@ class TopologicalManifoldHomset(UniqueRepresentation, Homset): This test suite includes more tests than in the case of ``H``, since ``E`` has some extra structure (monoid). - """ Element = ContinuousMap @@ -171,7 +171,6 @@ def __init__(self, domain, codomain, name=None, latex_name=None): sage: iota * phi Differentiable map iota from the 1-sphere S^1 of radius 1 smoothly embedded in the Euclidean plane E^2 to the Euclidean plane E^2 - """ from sage.manifolds.manifold import TopologicalManifold if not isinstance(domain, TopologicalManifold): @@ -220,7 +219,7 @@ def _element_constructor_(self, coord_functions, name=None, latex_name=None, INPUT: - - ``coord_functions`` -- a dictionary of the coordinate expressions + - ``coord_functions`` -- dictionary of the coordinate expressions (as lists or tuples of the coordinates of the image expressed in terms of the coordinates of the considered point) with the pairs of charts ``(chart1, chart2)`` as keys (``chart1`` being a chart @@ -230,10 +229,10 @@ def _element_constructor_(self, coord_functions, name=None, latex_name=None, - ``name`` -- (default: ``None``) name given to the continuous map - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the continuous map; if ``None``, the LaTeX symbol is set to ``name`` - - ``is_isomorphism`` -- (default: ``False``) determines whether the + - ``is_isomorphism`` -- boolean (default: ``False``); determines whether the constructed object is a isomorphism (i.e. a homeomorphism); if set to ``True``, then the manifolds `M` and `N` must have the same dimension - - ``is_identity`` -- (default: ``False``) determines whether the + - ``is_identity`` -- boolean (default: ``False``); determines whether the constructed object is the identity map; if set to ``True``, then `N` must be `M` and the entry ``coord_functions`` is not used @@ -244,9 +243,7 @@ def _element_constructor_(self, coord_functions, name=None, latex_name=None, continuous map, further coordinate expressions, in other charts, can be subsequently added by means of the method :meth:`add_expr` - OUTPUT: - - - a :class:`~sage.manifolds.continuous_map.ContinuousMap` + OUTPUT: a :class:`~sage.manifolds.continuous_map.ContinuousMap` EXAMPLES:: @@ -267,7 +264,6 @@ def _element_constructor_(self, coord_functions, name=None, latex_name=None, sage: id.display() Id_M: M → M (x, y) ↦ (x, y) - """ # Standard construction return self.element_class(self, coord_functions=coord_functions, @@ -279,9 +275,7 @@ def _an_element_(self): r""" Construct some element of ``self``. - OUTPUT: - - - a :class:`~sage.manifolds.continuous_map.ContinuousMap` + OUTPUT: a :class:`~sage.manifolds.continuous_map.ContinuousMap` EXAMPLES:: @@ -303,7 +297,6 @@ def _an_element_(self): sage: f(p).coord(Y) (0, 0, 0) sage: TestSuite(f).run() - """ dom = self.domain() codom = self.codomain() @@ -335,7 +328,6 @@ def _coerce_map_from_(self, other): False sage: H._coerce_map_from_(H) True - """ if isinstance(other, TopologicalManifoldHomset): return (other.domain().has_coerce_map_from(self.domain()) @@ -434,7 +426,6 @@ def one(self): to 3-dimensional topological manifold N in Category of manifolds over Real Field with 53 bits of precision is not a monoid - """ if self.codomain() != self.domain(): raise TypeError("{} is not a monoid".format(self)) diff --git a/src/sage/manifolds/operators.py b/src/sage/manifolds/operators.py index a437f4a08e0..eed5df22eb5 100644 --- a/src/sage/manifolds/operators.py +++ b/src/sage/manifolds/operators.py @@ -43,6 +43,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** + def grad(scalar): r""" Gradient operator. @@ -91,10 +92,10 @@ def grad(scalar): :meth:`~sage.manifolds.differentiable.scalarfield.DiffScalarField.gradient` of :class:`~sage.manifolds.differentiable.scalarfield.DiffScalarField` for more details and examples. - """ return scalar.gradient() + def div(tensor): r""" Divergence operator. @@ -165,10 +166,10 @@ def div(tensor): :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.divergence` of :class:`~sage.manifolds.differentiable.tensorfield.TensorField` for more details and examples. - """ return tensor.divergence() + def curl(vector): r""" Curl operator. @@ -233,10 +234,10 @@ def curl(vector): :meth:`~sage.manifolds.differentiable.vectorfield.VectorField.curl` of :class:`~sage.manifolds.differentiable.vectorfield.VectorField` for more details and examples. - """ return vector.curl() + def laplacian(field): r""" Laplace-Beltrami operator. @@ -294,10 +295,10 @@ def laplacian(field): :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.laplacian` of :class:`~sage.manifolds.differentiable.tensorfield.TensorField` for more details and examples. - """ return field.laplacian() + def dalembertian(field): r""" d'Alembert operator. @@ -350,7 +351,6 @@ def dalembertian(field): :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.dalembertian` of :class:`~sage.manifolds.differentiable.tensorfield.TensorField` for more details and examples. - """ return field.dalembertian() diff --git a/src/sage/manifolds/point.py b/src/sage/manifolds/point.py index a2bc5ff3182..b3647cc1447 100644 --- a/src/sage/manifolds/point.py +++ b/src/sage/manifolds/point.py @@ -92,6 +92,7 @@ from sage.symbolic.expression import Expression from sage.rings.integer_ring import ZZ + class ManifoldPoint(Element): r""" Point of a topological manifold. @@ -111,9 +112,9 @@ class ManifoldPoint(Element): - ``name`` -- (default: ``None``) name given to the point - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the point; if ``None``, the LaTeX symbol is set to ``name`` - - ``check_coords`` -- (default: ``True``) determines whether ``coords`` - are valid coordinates for the chart ``chart``; for symbolic - coordinates, it is recommended to set ``check_coords`` to ``False`` + - ``check_coords`` -- boolean (default: ``True``); determines whether ``coords`` + are valid coordinates for the chart ``chart``. For symbolic + coordinates, it is recommended to set ``check_coords`` to ``False``. EXAMPLES: @@ -179,7 +180,6 @@ def __init__(self, parent, coords=None, chart=None, name=None, sage: q = U((-1,2), name='q'); q Point q on the 2-dimensional topological manifold M sage: TestSuite(q).run() - """ if parent.is_empty(): raise TypeError(f'cannot define a point on the {parent} because it has been declared empty') @@ -231,7 +231,6 @@ def _repr_(self): 'Point p on the 2-dimensional topological manifold M' sage: repr(p) # indirect doctest 'Point p on the 2-dimensional topological manifold M' - """ description = "Point" if self._name is not None: @@ -258,7 +257,6 @@ def _latex_(self): '\\mathcal{P}' sage: latex(p) # indirect doctest \mathcal{P} - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -366,7 +364,6 @@ def coordinates(self, chart=None, old_chart=None): {Chart (M, (u, v)): (a - b, a + b), Chart (M, (w, z)): (a^3 - 3*a^2*b + 3*a*b^2 - b^3, a^3 + 3*a^2*b + 3*a*b^2 + b^3)} - """ if chart is None: dom = self.parent() @@ -436,7 +433,7 @@ def coordinates(self, chart=None, old_chart=None): def set_coordinates(self, coords, chart=None): r""" - Sets the point coordinates in the specified chart. + Set the point coordinates in the specified chart. Coordinates with respect to other charts are deleted, in order to avoid any inconsistency. To keep them, use the method :meth:`add_coord` @@ -484,7 +481,6 @@ def set_coordinates(self, coords, chart=None): sage: p.set_coord(Y(p), chart=Y) sage: p._coordinates {Chart (M, (u, v)): (-1, 5)} - """ self._coordinates.clear() self.add_coord(coords, chart) @@ -493,7 +489,7 @@ def set_coordinates(self, coords, chart=None): def add_coordinates(self, coords, chart=None): r""" - Adds some coordinates in the specified chart. + Add some coordinates in the specified chart. The previous coordinates with respect to other charts are kept. To clear them, use :meth:`set_coord` instead. @@ -551,7 +547,6 @@ def add_coordinates(self, coords, chart=None): sage: p.set_coordinates((-1,5), chart=Y) sage: p._coordinates {Chart (M, (u, v)): (-1, 5)} - """ if len(coords) != self.parent().manifold()._dim: raise ValueError("the number of coordinates must be equal to " + @@ -568,7 +563,7 @@ def add_coordinates(self, coords, chart=None): def __eq__(self, other): r""" - Compares the current point with another one. + Compare the current point with another one. EXAMPLES: @@ -627,7 +622,6 @@ def __eq__(self, other): sage: q = M((3*pi,1), chart=Y) sage: p == q or q == p False - """ if other is self: return True @@ -696,7 +690,7 @@ def __eq__(self, other): diff = xs - xo period = periods[ind] if period is not None: - if not (diff/period in ZZ): + if diff/period not in ZZ: return False else: if isinstance(diff, Expression) and not diff.is_trivial_zero(): @@ -719,7 +713,6 @@ def __ne__(self, other): True sage: p != M((2,-3), chart=X) False - """ return not (self == other) @@ -746,7 +739,6 @@ def __hash__(self): sage: p = M((2,-3), chart=X) sage: hash(p) == hash(M) True - """ return hash(self.parent().manifold()) @@ -942,7 +934,6 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, g = p.plot(X, ambient_coords=(y,z), label_offset=0.4) gX = X.plot(X, ambient_coords=(y,z)) sphinx_plot(g+gX) - """ from sage.plot.point import point2d from sage.plot.text import text diff --git a/src/sage/manifolds/scalarfield.py b/src/sage/manifolds/scalarfield.py index 6c1ea6e2f14..62c728ff5bb 100644 --- a/src/sage/manifolds/scalarfield.py +++ b/src/sage/manifolds/scalarfield.py @@ -1104,7 +1104,6 @@ class ScalarField(CommutativeAlgebraElement, ModuleElementWithMutability): sage: TestSuite(f).run() sage: TestSuite(zer).run() - """ _name: Optional[str] @@ -1127,7 +1126,6 @@ def __init__(self, parent, coord_expression=None, chart=None, name=None, Algebra of scalar fields on the 2-dimensional topological manifold M sage: TestSuite(f).run() - """ super().__init__(parent) # both super classes have same signature domain = parent._domain @@ -1259,7 +1257,6 @@ def is_trivial_zero(self): True sage: f == 0 True - """ if self._is_zero: return True @@ -1318,7 +1315,6 @@ def is_trivial_one(self): True sage: f == 1 True - """ return all(func.is_trivial_one() for func in self._express.values()) @@ -1338,7 +1334,6 @@ def is_unit(self): sage: zero = M.scalar_field_algebra().zero() sage: zero.is_unit() False - """ if self._is_zero: return False @@ -1353,9 +1348,7 @@ def __eq__(self, other): - ``other`` -- a scalar field (or something else) - OUTPUT: - - - ``True`` if ``self`` is equal to ``other``, ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other``, ``False`` otherwise TESTS:: @@ -1374,7 +1367,6 @@ def __eq__(self, other): True sage: h == 1 True - """ from sage.manifolds.differentiable.mixed_form import MixedForm @@ -1413,9 +1405,7 @@ def __ne__(self, other): - ``other`` -- a scalar field - OUTPUT: - - - ``True`` if ``self`` differs from ``other``, ``False`` otherwise + OUTPUT: ``True`` if ``self`` differs from ``other``, ``False`` otherwise TESTS:: @@ -1446,7 +1436,7 @@ def _init_derived(self): sage: f._init_derived() """ self._restrictions = {} - # dict. of restrictions of self on subsets + # dict. of restrictions of ``self`` on subsets # of self._domain, with the subsets as keys def _del_derived(self): @@ -1546,7 +1536,6 @@ def set_name(self, name=None, latex_name=None): Scalar field f on the 2-dimensional topological manifold M sage: latex(f) \Phi - """ if self.is_immutable(): raise ValueError("the name of an immutable element " @@ -1582,7 +1571,6 @@ def domain(self): sage: g = f.restrict(U) sage: g.domain() Open subset U of the 2-dimensional topological manifold M - """ return self._domain @@ -1597,7 +1585,6 @@ def codomain(self): sage: f = M.scalar_field(x+2*y) sage: f.codomain() Real Field with 53 bits of precision - """ return self._domain.base_field() @@ -1627,7 +1614,6 @@ def copy(self, name=None, latex_name=None): True sage: g is f False - """ result = type(self)(self.parent(), name=name, latex_name=latex_name) for chart, funct in self._express.items(): @@ -1678,7 +1664,6 @@ def copy_from(self, other): (x, y) ↦ x*y^2 sage: f == g False - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -1755,7 +1740,6 @@ def coord_function(self, chart=None, from_chart=None): Change of coordinates from Chart (M, (T, X)) to Chart (M, (t, x)) sage: f.coord_function(o2) -T^2 + X^2 - """ if chart is None: chart = self._domain._def_chart @@ -1858,7 +1842,6 @@ def expr(self, chart=None, from_chart=None): sage: f.expr() # note the SymPy exponent notation x*y**2 - """ return self.coord_function(chart, from_chart).expr() @@ -1911,7 +1894,6 @@ def set_expr(self, coord_expression, chart=None): ... ValueError: the expressions of an immutable element cannot be changed - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -1975,7 +1957,6 @@ def add_expr(self, coord_expression, chart=None): ... ValueError: the expressions of an immutable element cannot be changed - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -2045,7 +2026,6 @@ def add_expr_by_continuation(self, chart, subdomain): f: S^2 → ℝ on U: (x, y) ↦ arctan(x^2 + y^2) on V: (u, v) ↦ arctan(1/(u^2 + v^2)) - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -2083,7 +2063,6 @@ def set_restriction(self, rst): on U: (x, y) ↦ x^2 + y sage: f.restrict(U) == g True - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -2294,7 +2273,6 @@ def restrict(self, subdomain): topological manifold M sage: M.zero_scalar_field().restrict(U) is U.zero_scalar_field() True - """ if subdomain == self._domain: return self @@ -2426,7 +2404,6 @@ def common_charts(self, other): [Chart (W, (x, y))] sage: h.expr(c_xy_W) x + 2*y - """ if not isinstance(other, ScalarField): raise TypeError("the second argument must be a scalar field") @@ -2483,9 +2460,7 @@ def __call__(self, p, chart=None): are known is searched, starting from the default chart of ``self._domain`` - OUTPUT: - - - value at ``p`` + OUTPUT: value at ``p`` EXAMPLES:: @@ -2513,7 +2488,6 @@ def __call__(self, p, chart=None): -21 sage: p.coord(Y) (-3, 7) - """ # ! # it should be "if p not in self_domain:" instead, but this test is # skipped for efficiency @@ -2567,7 +2541,7 @@ def preimage(self, codomain_subset, name=None, latex_name=None): - ``codomain_subset`` -- an instance of :class:`~sage.sets.real_set.RealSet` - ``name`` -- string; name (symbol) given to the subset - - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to + - ``latex_name`` -- string (default: ``None``); LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` OUTPUT: @@ -2602,9 +2576,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of the scalar field + OUTPUT: an exact copy of the scalar field TESTS:: @@ -2615,7 +2587,6 @@ def __pos__(self): Scalar field +f on the 2-dimensional topological manifold M sage: g == f True - """ result = type(self)(self.parent()) for chart in self._express: @@ -2630,9 +2601,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the negative of the scalar field + OUTPUT: the negative of the scalar field TESTS:: @@ -2646,7 +2615,6 @@ def __neg__(self): (x, y) ↦ -x - y sage: g.__neg__() == f True - """ result = type(self)(self.parent()) for chart in self._express: @@ -2687,7 +2655,6 @@ def _add_(self, other): True sage: f._add_(M.zero_scalar_field()) == f True - """ # Trivial cases: if self.is_trivial_zero(): @@ -2736,7 +2703,6 @@ def _sub_(self, other): True sage: f._sub_(M.zero_scalar_field()) == f True - """ # Trivial cases: if self.is_trivial_zero(): @@ -2789,7 +2755,6 @@ def _mul_(self, other): True sage: f._mul_(M.one_scalar_field()) == f True - """ # Trivial cases: if self.is_trivial_zero() or other.is_trivial_zero(): @@ -2882,9 +2847,7 @@ def _lmul_(self, number): field on which the manifold is constructed (possibly represented by a symbolic expression) - OUTPUT: - - - the scalar field ``number * self`` + OUTPUT: the scalar field ``number * self`` TESTS:: @@ -2909,7 +2872,6 @@ def _lmul_(self, number): True sage: f._lmul_(1) == f True - """ # Trivial cases: try: @@ -3001,9 +2963,7 @@ def exp(self): r""" Exponential of the scalar field. - OUTPUT: - - - the scalar field `\exp f`, where `f` is the current scalar field + OUTPUT: the scalar field `\exp f`, where `f` is the current scalar field EXAMPLES:: @@ -3036,7 +2996,6 @@ def exp(self): True sage: exp(M.constant_scalar_field(1)) == M.constant_scalar_field(e) True - """ name, latex_name = self._function_name("exp", r"\exp") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3048,9 +3007,7 @@ def log(self): r""" Natural logarithm of the scalar field. - OUTPUT: - - - the scalar field `\ln f`, where `f` is the current scalar field + OUTPUT: the scalar field `\ln f`, where `f` is the current scalar field EXAMPLES:: @@ -3069,7 +3026,6 @@ def log(self): sage: exp(log(f)) == f True - """ name, latex_name = self._function_name("ln", r"\ln") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3119,7 +3075,6 @@ def __pow__(self, exponent): True sage: pow(pow(f, 1/2), 2) == f True - """ from sage.misc.latex import latex if self._name is None: @@ -3140,9 +3095,7 @@ def sqrt(self): r""" Square root of the scalar field. - OUTPUT: - - - the scalar field `\sqrt f`, where `f` is the current scalar field + OUTPUT: the scalar field `\sqrt f`, where `f` is the current scalar field EXAMPLES:: @@ -3164,7 +3117,6 @@ def sqrt(self): True sage: sqrt(M.zero_scalar_field()) == M.zero_scalar_field() True - """ name, latex_name = self._function_name("sqrt", r"\sqrt", parentheses=False) @@ -3177,9 +3129,7 @@ def cos(self): r""" Cosine of the scalar field. - OUTPUT: - - - the scalar field `\cos f`, where `f` is the current scalar field + OUTPUT: the scalar field `\cos f`, where `f` is the current scalar field EXAMPLES:: @@ -3200,7 +3150,6 @@ def cos(self): True sage: cos(M.constant_scalar_field(pi/2)) == M.zero_scalar_field() True - """ name, latex_name = self._function_name("cos", r"\cos") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3212,9 +3161,7 @@ def sin(self): r""" Sine of the scalar field. - OUTPUT: - - - the scalar field `\sin f`, where `f` is the current scalar field + OUTPUT: the scalar field `\sin f`, where `f` is the current scalar field EXAMPLES:: @@ -3235,7 +3182,6 @@ def sin(self): True sage: sin(M.constant_scalar_field(pi/2)) == M.constant_scalar_field(1) True - """ name, latex_name = self._function_name("sin", r"\sin") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3247,9 +3193,7 @@ def tan(self): r""" Tangent of the scalar field. - OUTPUT: - - - the scalar field `\tan f`, where `f` is the current scalar field + OUTPUT: the scalar field `\tan f`, where `f` is the current scalar field EXAMPLES:: @@ -3272,7 +3216,6 @@ def tan(self): True sage: tan(M.constant_scalar_field(pi/4)) == M.constant_scalar_field(1) True - """ name, latex_name = self._function_name("tan", r"\tan") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3284,9 +3227,7 @@ def arccos(self): r""" Arc cosine of the scalar field. - OUTPUT: - - - the scalar field `\arccos f`, where `f` is the current scalar field + OUTPUT: the scalar field `\arccos f`, where `f` is the current scalar field EXAMPLES:: @@ -3316,7 +3257,6 @@ def arccos(self): True sage: arccos(M.zero_scalar_field()) == M.constant_scalar_field(pi/2) True - """ name, latex_name = self._function_name("arccos", r"\arccos") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3328,9 +3268,7 @@ def arcsin(self): r""" Arc sine of the scalar field. - OUTPUT: - - - the scalar field `\arcsin f`, where `f` is the current scalar field + OUTPUT: the scalar field `\arcsin f`, where `f` is the current scalar field EXAMPLES:: @@ -3360,7 +3298,6 @@ def arcsin(self): True sage: arcsin(M.constant_scalar_field(1)) == M.constant_scalar_field(pi/2) True - """ name, latex_name = self._function_name("arcsin", r"\arcsin") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3372,9 +3309,7 @@ def arctan(self): r""" Arc tangent of the scalar field. - OUTPUT: - - - the scalar field `\arctan f`, where `f` is the current scalar field + OUTPUT: the scalar field `\arctan f`, where `f` is the current scalar field EXAMPLES:: @@ -3404,7 +3339,6 @@ def arctan(self): True sage: arctan(M.constant_scalar_field(1)) == M.constant_scalar_field(pi/4) True - """ name, latex_name = self._function_name("arctan", r"\arctan") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3416,9 +3350,7 @@ def cosh(self): r""" Hyperbolic cosine of the scalar field. - OUTPUT: - - - the scalar field `\cosh f`, where `f` is the current scalar field + OUTPUT: the scalar field `\cosh f`, where `f` is the current scalar field EXAMPLES:: @@ -3437,7 +3369,6 @@ def cosh(self): sage: cosh(M.zero_scalar_field()) == M.constant_scalar_field(1) True - """ name, latex_name = self._function_name("cosh", r"\cosh") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3449,9 +3380,7 @@ def sinh(self): r""" Hyperbolic sine of the scalar field. - OUTPUT: - - - the scalar field `\sinh f`, where `f` is the current scalar field + OUTPUT: the scalar field `\sinh f`, where `f` is the current scalar field EXAMPLES:: @@ -3470,7 +3399,6 @@ def sinh(self): sage: sinh(M.zero_scalar_field()) == M.zero_scalar_field() True - """ name, latex_name = self._function_name("sinh", r"\sinh") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3482,9 +3410,7 @@ def tanh(self): r""" Hyperbolic tangent of the scalar field. - OUTPUT: - - - the scalar field `\tanh f`, where `f` is the current scalar field + OUTPUT: the scalar field `\tanh f`, where `f` is the current scalar field EXAMPLES:: @@ -3505,7 +3431,6 @@ def tanh(self): True sage: tanh(M.zero_scalar_field()) == M.zero_scalar_field() True - """ name, latex_name = self._function_name("tanh", r"\tanh") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3548,7 +3473,6 @@ def arccosh(self): True sage: arccosh(M.constant_scalar_field(1)) == M.zero_scalar_field() True - """ name, latex_name = self._function_name("arccosh", r"\,\mathrm{arccosh}") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3591,7 +3515,6 @@ def arcsinh(self): True sage: arcsinh(M.zero_scalar_field()) == M.zero_scalar_field() True - """ name, latex_name = self._function_name("arcsinh", r"\,\mathrm{arcsinh}") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3636,7 +3559,6 @@ def arctanh(self): True sage: arctanh(M.constant_scalar_field(1/2)) == M.constant_scalar_field(log(3)/2) True - """ name, latex_name = self._function_name("arctanh", r"\,\mathrm{arctanh}") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3665,7 +3587,6 @@ def __abs__(self): sage: g.display() abs(f): M → ℝ (x, y) ↦ abs(x)*abs(y) - """ name, latex_name = self._function_name("abs", r"\,\mathrm{abs}") resu = type(self)(self.parent(), name=name, latex_name=latex_name) @@ -3707,7 +3628,7 @@ def set_calc_order(self, symbol, order, truncate=False): The order of the big `O` in the power series expansion is `n+1`, where `n` is ``order``. - - ``truncate`` -- (default: ``False``) determines whether the + - ``truncate`` -- boolean (default: ``False``); determines whether the coordinate expressions of ``self`` are replaced by their expansions to the given order @@ -3722,7 +3643,6 @@ def set_calc_order(self, symbol, order, truncate=False): sage: f.set_calc_order(t, 2, truncate=True) sage: f.expr() 1/2*t^2*x^2 - t*x + 1 - """ for expr in self._express.values(): expr._expansion_symbol = symbol @@ -3748,7 +3668,6 @@ def set_immutable(self): True sage: f.restrict(V).is_immutable() True - """ for rst in self._restrictions.values(): rst.set_immutable() @@ -3781,7 +3700,6 @@ def __hash__(self): sage: {f: 1}[f] 1 - """ if self.is_mutable(): raise ValueError('element must be immutable in order to be ' diff --git a/src/sage/manifolds/scalarfield_algebra.py b/src/sage/manifolds/scalarfield_algebra.py index 3923247367d..960b4514387 100644 --- a/src/sage/manifolds/scalarfield_algebra.py +++ b/src/sage/manifolds/scalarfield_algebra.py @@ -38,6 +38,7 @@ from sage.symbolic.ring import SymbolicRing, SR from sage.manifolds.scalarfield import ScalarField + class ScalarFieldAlgebra(UniqueRepresentation, Parent): r""" Commutative algebra of scalar fields on a topological manifold. @@ -356,7 +357,6 @@ class ScalarFieldAlgebra(UniqueRepresentation, Parent): It is passed also for `C^0(W)`:: sage: TestSuite(CW).run() - """ Element = ScalarField @@ -377,7 +377,6 @@ def __init__(self, domain): sage: type(CM).__base__ sage: TestSuite(CM).run() - """ base_field = domain.base_field() if domain.base_field_type() in ['real', 'complex']: @@ -449,7 +448,6 @@ def _element_constructor_(self, coord_expression=None, chart=None, sage: fU.display() f: U → ℝ (x, y) ↦ y^2 + x - """ try: if coord_expression.is_trivial_zero(): @@ -481,7 +479,7 @@ def _element_constructor_(self, coord_expression=None, chart=None, def _an_element_(self): r""" - Construct some element of the algebra + Construct some element of the algebra. TESTS:: @@ -493,7 +491,6 @@ def _an_element_(self): sage: f.display() M → ℝ (x, y) ↦ 2 - """ return self.element_class(self, coord_expression=2, chart='all') @@ -520,7 +517,6 @@ def _coerce_map_from_(self, other): False sage: CU._coerce_map_from_(CM) True - """ from .chart_func import ChartFunctionRing if isinstance(other, SymbolicRing): @@ -549,7 +545,6 @@ def _repr_(self): 'Algebra of scalar fields on the 2-dimensional topological manifold M' sage: CM Algebra of scalar fields on the 2-dimensional topological manifold M - """ return "Algebra of scalar fields on the {}".format(self._domain) @@ -565,7 +560,6 @@ def _latex_(self): 'C^0 \\left(M\\right)' sage: latex(CM) C^0 \left(M\right) - """ return r"C^0 \left(" + self._domain._latex_() + r"\right)" @@ -592,7 +586,6 @@ def zero(self): sage: CM.zero() is z True - """ coord_express = {chart: chart.zero_function() for chart in self._domain.atlas()} @@ -626,7 +619,6 @@ def one(self): sage: CM.one() is h True - """ coord_express = {chart: chart.one_function() for chart in self._domain.atlas()} diff --git a/src/sage/manifolds/section.py b/src/sage/manifolds/section.py index 987f9663b96..75af42a57e5 100644 --- a/src/sage/manifolds/section.py +++ b/src/sage/manifolds/section.py @@ -25,6 +25,7 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ + class Section(ModuleElementWithMutability): r""" Section in a vector bundle. @@ -209,7 +210,6 @@ class Section(ModuleElementWithMutability): Traceback (most recent call last): ... ValueError: the name of an immutable element cannot be changed - """ def __init__(self, section_module, name=None, latex_name=None): r""" @@ -237,7 +237,6 @@ def __init__(self, section_module, name=None, latex_name=None): sage: s in C0 True sage: TestSuite(s).run() - """ ModuleElementWithMutability.__init__(self, section_module) self._smodule = section_module @@ -287,7 +286,6 @@ def __bool__(self): True sage: s.is_zero() # indirect doctest False - """ if self._is_zero: return False @@ -317,7 +315,6 @@ def _repr_(self): sage: s # indirect doctest Section s on the 3-dimensional differentiable manifold M with values in the real vector bundle E of rank 2 - """ desc = "Section " if self._name is not None: @@ -341,7 +338,6 @@ def _latex_(self): '\\sigma' sage: latex(sigma) # indirect doctest \sigma - """ if self._latex_name is None: return r'\text{' + str(self) + r'}' @@ -358,7 +354,6 @@ def _init_derived(self): sage: E = M.vector_bundle(2, 'E') sage: s = E.section(name='s') sage: s._init_derived() - """ self._restrictions = {} # dict. of restrictions of self on subdomains # of self._domain, with the subdomains as keys @@ -375,7 +370,6 @@ def _del_derived(self, del_restrictions=False): sage: E = M.vector_bundle(2, 'E') sage: s = E.section(name='s') sage: s._del_derived() - """ if del_restrictions: self._restrictions.clear() @@ -415,7 +409,6 @@ def set_name(self, name=None, latex_name=None): the real vector bundle E of rank 2 sage: latex(s) a - """ if self.is_immutable(): raise ValueError("the name of an immutable element " @@ -449,7 +442,6 @@ def _new_instance(self): True sage: s1.parent() is s.parent() True - """ return type(self)(self._smodule) @@ -473,7 +465,6 @@ def _del_restrictions(self): sage: s._del_restrictions() sage: s._restrictions {} - """ self._restrictions.clear() self._extensions_graph = {self._domain: self} @@ -517,7 +508,6 @@ def _init_components(self, *comp, **kwargs): sage: s._init_components({(f, Y): [t, v^3]}) sage: s.display(f, Y) s = t f_0 + v^3 f_1 - """ comp0 = comp[0] self._is_zero = False # a priori @@ -558,7 +548,6 @@ def domain(self): sage: z = C0_U.zero() sage: z.domain() Open subset U of the 3-dimensional topological manifold M - """ return self._domain @@ -581,7 +570,6 @@ def base_module(self): Module C^0(U;E) of sections on the Open subset U of the 3-dimensional topological manifold M with values in the real vector bundle E of rank 2 - """ return self._smodule @@ -619,7 +607,6 @@ def set_restriction(self, rst): s = (x + y) (phi_U^*e_1) + x (phi_U^*e_2) sage: s.restrict(U) == sU True - """ if self.is_immutable(): raise ValueError("the restrictions of an immutable element " @@ -640,9 +627,7 @@ def restrict(self, subdomain): :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`; open subset `U` of the section domain `S` - OUTPUT: - - - :class:`Section` representing the restriction + OUTPUT: :class:`Section` representing the restriction EXAMPLES: @@ -708,7 +693,6 @@ def restrict(self, subdomain): True sage: sU.restrict(U) is sU True - """ if subdomain == self._domain: return self @@ -837,7 +821,6 @@ def _set_comp_unsafe(self, basis=None): ... ValueError: no basis could be found for computing the components in the Trivialization frame (E|_V, ((phi_V^*e_1),(phi_V^*e_2))) - """ if basis is None: basis = self._smodule.default_frame() @@ -909,8 +892,6 @@ def set_comp(self, basis=None): ... ValueError: no basis could be found for computing the components in the Trivialization frame (E|_V, ((phi_V^*e_1),(phi_V^*e_2))) - - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -982,7 +963,6 @@ def _add_comp_unsafe(self, basis=None): sage: s.display(fS) s = (u + v) (phi_V^*e_1) - """ if basis is None: basis = self._smodule.default_frame() @@ -1048,7 +1028,6 @@ def add_comp(self, basis=None): sage: s.display(fS) s = (u + v) (phi_V^*e_1) - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1130,7 +1109,6 @@ def add_comp_by_continuation(self, frame, subdomain, chart=None): (phi_V^*e_2) and `a` is defined on the entire manifold `S^2`. - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1156,7 +1134,7 @@ def add_expr_from_subdomain(self, frame, subdomain): - ``frame`` -- local frame `e` in which the components are to be set - ``subdomain`` -- open subset of `e`'s domain in which the - components have additional expressions. + components have additional expressions EXAMPLES: @@ -1214,7 +1192,6 @@ def add_expr_from_subdomain(self, frame, subdomain): S^2 → ℝ on U: (x, y) ↦ y on V: (u, v) ↦ v/(u^2 + v^2) - """ if self.is_immutable(): raise ValueError("the expressions of an immutable element " @@ -1292,7 +1269,6 @@ def comp(self, basis=None, from_basis=None): True sage: s.restrict(U).comp() is s.comp(e) True - """ if basis is None: basis = self._smodule.default_frame() @@ -1393,7 +1369,6 @@ def display(self, frame=None, chart=None): sage: s.disp(fS) s = v/(u^2 + v^2) (phi_V^*e_1) + u/(u^2 + v^2) (phi_V^*e_2) - """ if frame is None: frame = self._smodule.default_frame() @@ -1420,7 +1395,7 @@ def display_comp(self, frame=None, chart=None, only_nonzero=True): - ``chart`` -- (default: ``None``) chart specifying the coordinate expression of the components; if ``None``, the default chart of the section domain is used - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero components are displayed EXAMPLES: @@ -1449,7 +1424,6 @@ def display_comp(self, frame=None, chart=None, only_nonzero=True): See documentation of :meth:`sage.manifolds.section.TrivialSection.display_comp` for more options. - """ if frame is None: frame = self._smodule.default_frame() @@ -1520,7 +1494,6 @@ def at(self, point): s = 4 (phi_V^*e_1) + 8 (phi_V^*e_2) sage: p.coord(c_uv) # to check the above expression (5, -1) - """ if point not in self._domain: raise ValueError("the {} is not a point in the ".format(point) + @@ -1569,7 +1542,6 @@ def __getitem__(self, args): [Scalar field on the 3-dimensional topological manifold M, Scalar field on the 3-dimensional topological manifold M, Scalar field on the 3-dimensional topological manifold M] - """ if isinstance(args, str): # section with specified indices return TensorWithIndices(self, args).update() @@ -1591,7 +1563,7 @@ def __getitem__(self, args): def __setitem__(self, args, value): r""" - Sets a component with respect to some local frame. + Set a component with respect to some local frame. INPUT: @@ -1622,7 +1594,6 @@ def __setitem__(self, args, value): sage: s.__setitem__(slice(None), [x+y, 3*y^2, x*y]) sage: s.display() s = (x + y) e_0 + 3*y^2 e_1 + x*y e_2 - """ if isinstance(args, list): # case of [[...]] syntax if not isinstance(args[0], (int, Integer, slice)): @@ -1691,7 +1662,6 @@ def copy_from(self, other): t = 2 (phi_U^*e_1) + (-y + 1) (phi_U^*e_2) sage: s == t False - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1759,7 +1729,6 @@ def copy(self, name=None, latex_name=None): 2 (phi_U^*e_1) + (-y + 1) (phi_U^*e_2) sage: t == s False - """ resu = self._new_instance() # set resu name @@ -1814,7 +1783,6 @@ def _common_subdomains(self, other): sage: sorted(t._common_subdomains(s), key=str) [Open subset U of the 2-dimensional topological manifold M, Open subset V of the 2-dimensional topological manifold M] - """ resu = [] for dom in self._restrictions: @@ -1830,9 +1798,7 @@ def __eq__(self, other): - ``other`` -- a section or 0 - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise TESTS:: @@ -1869,7 +1835,6 @@ def __eq__(self, other): False sage: s.parent().zero() == 0 True - """ if other is self: return True @@ -1949,7 +1914,6 @@ def __ne__(self, other): False sage: s != 0 True - """ return not (self == other) @@ -1957,9 +1921,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of ``self`` + OUTPUT: an exact copy of ``self`` TESTS:: @@ -1985,7 +1947,6 @@ def __pos__(self): in the real vector bundle E of rank 2 sage: t.display(fU) +s = x (phi_U^*e_1) + (phi_U^*e_2) - """ resu = self._new_instance() for dom, rst in self._restrictions.items(): @@ -2000,9 +1961,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the tensor field `-T`, where `T` is ``self`` + OUTPUT: the tensor field `-T`, where `T` is ``self`` TESTS:: @@ -2036,7 +1995,6 @@ def __neg__(self): -s = (-1/2*u - 1/2*v) (phi_V^*e_1) + (-1/4*u^2 - 1/2*u*v - 1/4*v^2) (phi_V^*e_2) sage: s == -t # indirect doctest True - """ resu = self._new_instance() for dom, rst in self._restrictions.items(): @@ -2057,9 +2015,7 @@ def _add_(self, other): - ``other`` -- a section, in the same section module as ``self`` - OUTPUT: - - - the section resulting from the addition of ``self`` and ``other`` + OUTPUT: the section resulting from the addition of ``self`` and ``other`` TESTS:: @@ -2101,7 +2057,6 @@ def _add_(self, other): True sage: z._add_(s) == s True - """ # Case zero: if self._is_zero: @@ -2128,9 +2083,7 @@ def _sub_(self, other): - ``other`` -- a section in the same section module as ``self`` - OUTPUT: - - - the section resulting from the subtraction of ``other`` from ``self`` + OUTPUT: the section resulting from the subtraction of ``other`` from ``self`` TESTS:: @@ -2170,7 +2123,6 @@ def _sub_(self, other): True sage: z._sub_(s) == -s True - """ # Case zero: if self._is_zero: @@ -2191,7 +2143,7 @@ def _sub_(self, other): def _rmul_(self, scalar): r""" - Reflected multiplication operator: performs ``scalar * self`` + Reflected multiplication operator: performs ``scalar * self``. This is actually the multiplication by an element of the ring over which the tensor field module is constructed. @@ -2201,9 +2153,7 @@ def _rmul_(self, scalar): - ``scalar`` -- scalar field in the scalar field algebra over which the module containing ``self`` is defined - OUTPUT: - - - the tensor field ``scalar * self`` + OUTPUT: the tensor field ``scalar * self`` TESTS:: @@ -2250,7 +2200,6 @@ def _rmul_(self, scalar): True sage: z._rmul_(g) == z True - """ ### # Case zero: @@ -2295,7 +2244,6 @@ def set_immutable(self): True sage: sU.is_immutable() True - """ for rst in self._restrictions.values(): rst.set_immutable() @@ -2303,6 +2251,7 @@ def set_immutable(self): #****************************************************************************** + class TrivialSection(FiniteRankFreeModuleElement, Section): r""" Section in a trivial vector bundle. @@ -2381,7 +2330,6 @@ class TrivialSection(FiniteRankFreeModuleElement, Section): manifold S^3 with values in the real vector bundle E of rank 3 sage: isinstance(s.parent(), FiniteRankFreeModule) True - """ def __init__(self, section_module, name=None, latex_name=None): r""" @@ -2407,7 +2355,6 @@ def __init__(self, section_module, name=None, latex_name=None): Free module C^0(M;E) of sections on the 2-dimensional topological manifold M with values in the real vector bundle E of rank 2 sage: TestSuite(s).run() - """ FiniteRankFreeModuleElement.__init__(self, section_module, name=name, latex_name=latex_name) @@ -2430,7 +2377,6 @@ def _init_derived(self): sage: e = E.local_frame('e') # makes E trivial sage: s = E.section(name='s') sage: s._init_derived() - """ FiniteRankFreeModuleElement._init_derived(self) Section._init_derived(self) @@ -2441,7 +2387,7 @@ def _del_derived(self, del_restrictions=True): INPUT: - - ``del_restrictions`` -- (default: ``True``) determines whether the + - ``del_restrictions`` -- boolean (default: ``True``); determines whether the restrictions of ``self`` to subdomains are deleted TESTS:: @@ -2451,7 +2397,6 @@ def _del_derived(self, del_restrictions=True): sage: e = E.local_frame('e') # makes E trivial sage: s = E.section(name='s') sage: s._del_derived() - """ FiniteRankFreeModuleElement._del_derived(self) Section._del_derived(self, del_restrictions=del_restrictions) @@ -2475,7 +2420,6 @@ def _repr_(self) : sage: s # indirect doctest Section s on the 2-dimensional topological manifold M with values in the real vector bundle E of rank 2 - """ return Section._repr_(self) @@ -2495,7 +2439,6 @@ def _new_instance(self): the real vector bundle E of rank 2 sage: type(s._new_instance()) is type(s) True - """ return type(self)(self._smodule) @@ -2566,7 +2509,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such ... ValueError: no basis could be found for computing the components in the Local frame (E|_M, (f_0,f_1)) - """ if basis is None: basis = self._smodule.default_frame() @@ -2654,7 +2596,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such ... ValueError: no basis could be found for computing the components in the Local frame (E|_M, (f_0,f_1)) - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -2742,7 +2683,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such s = 2 e_0 sage: s.display(f) s = x f_0 - """ if basis is None: basis = self._smodule.default_frame() @@ -2828,7 +2768,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such s = 2 e_0 sage: s.display(f) s = x f_0 - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -2894,7 +2833,6 @@ class :class:`~sage.tensor.modules.comp.Components` 1-index components w.r.t. Local frame (E|_M, (f_1,f_2)) sage: s.comp(f)[:] [x - 3, 0] - """ if basis is None: basis = self._smodule.default_frame() @@ -2920,9 +2858,7 @@ def restrict(self, subdomain): :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`; open subset `U` of the section module domain `S` - OUTPUT: - - - instance of :class:`TrivialSection` representing the restriction + OUTPUT: instance of :class:`TrivialSection` representing the restriction EXAMPLES: @@ -2964,7 +2900,6 @@ def restrict(self, subdomain): sage: s.restrict(M) is s True - """ if subdomain == self._domain: return self @@ -3054,7 +2989,7 @@ def display_comp(self, frame=None, chart=None, only_nonzero=False): - ``chart`` -- (default: ``None``) chart specifying the coordinate expression of the components; if ``None``, the default chart of the section module domain is used - - ``only_nonzero`` -- (default: ``False``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``False``); if ``True``, only nonzero components are displayed EXAMPLES: @@ -3108,7 +3043,6 @@ def display_comp(self, frame=None, chart=None, only_nonzero=False): s^0 = 4*u/(u^2 - 2*u*v + v^2 + 4) s^1 = 0 s^2 = 1/4*u^2 - 1/4*v^2 - """ if frame is None: frame = self._smodule.default_basis() @@ -3160,7 +3094,6 @@ def at(self, point): Fiber of E at Point p on the 2-dimensional topological manifold M sage: sp.display() s = 3 e_0 + 4 e_1 - """ if point not in self._domain: raise ValueError("the {} is not in the domain of ".format(point) + diff --git a/src/sage/manifolds/section_module.py b/src/sage/manifolds/section_module.py index 94c7ca6b4ba..6192045f45a 100644 --- a/src/sage/manifolds/section_module.py +++ b/src/sage/manifolds/section_module.py @@ -34,6 +34,7 @@ from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule from sage.manifolds.section import Section, TrivialSection + class SectionModule(UniqueRepresentation, Parent): r""" Module of sections over a vector bundle `E \to M` of class `C^k` on a domain @@ -139,7 +140,6 @@ class SectionModule(UniqueRepresentation, Parent): The conversion map is actually the restriction of sections defined on `M` to `U`. - """ Element = Section @@ -170,7 +170,6 @@ def __init__(self, vbundle, domain): Module C^0(S^1;E) of sections on the 1-dimensional topological manifold S^1 with values in the real vector bundle E of rank 1 sage: TestSuite(C0).run() - """ base_space = vbundle.base_space() if not domain.is_subset(base_space): @@ -217,7 +216,6 @@ def _element_constructor_(self, comp=[], frame=None, name=None, s = -x e_0 + y e_1 sage: C0(0) is C0.zero() True - """ try: if comp.is_trivial_zero(): @@ -255,7 +253,6 @@ def _an_element_(self): sage: C0._an_element_() Section on the 2-dimensional topological manifold M with values in the real vector bundle E of rank 2 - """ resu = self.element_class(self) for oc in self._domain.open_covers(trivial=False): @@ -281,7 +278,6 @@ def _coerce_map_from_(self, other): False sage: C0_U._coerce_map_from_(C0) True - """ if isinstance(other, (SectionModule, SectionFreeModule)): return self._domain.is_subset(other._domain) @@ -308,7 +304,6 @@ def _repr_(self): sage: C0 # indirect doctest Module C^0(M;E) of sections on the 2-dimensional topological manifold M with values in the real vector bundle E of rank 2 - """ desc = "Module {} of sections on the {} with values in the {} vector " \ "bundle {} of rank {}" @@ -331,7 +326,6 @@ def _latex_(self): 'C^{\\infty}(M;E)' sage: latex(C) # indirect doctest C^{\infty}(M;E) - """ return self._latex_name @@ -350,7 +344,6 @@ def base_space(self): bundle E of rank 2 sage: C0.base_space() Open subset U of the 3-dimensional topological manifold M - """ return self._base_space @@ -369,7 +362,6 @@ def domain(self): bundle E of rank 2 sage: C0_U.domain() Open subset U of the 3-dimensional topological manifold M - """ return self._domain @@ -390,7 +382,6 @@ def vector_bundle(self): 3-dimensional topological manifold M sage: E is C0.vector_bundle() True - """ return self._vbundle @@ -410,7 +401,6 @@ def zero(self): in the real vector bundle E of rank 2 sage: z == 0 True - """ res = self.element_class(self, name='zero', latex_name='0') for frame in self._vbundle._frames: @@ -442,7 +432,6 @@ def default_frame(self): sage: e is C0.default_frame() True - """ return self._def_frame @@ -477,7 +466,6 @@ def set_default_frame(self, basis): sage: C0.default_frame().domain() Open subset U of the 3-dimensional topological manifold M - """ from .local_frame import LocalFrame if not isinstance(basis, LocalFrame): @@ -489,6 +477,7 @@ def set_default_frame(self, basis): #****************************************************************************** + class SectionFreeModule(FiniteRankFreeModule): r""" Free module of sections over a vector bundle `E \to M` of class `C^k` on a @@ -577,7 +566,6 @@ class SectionFreeModule(FiniteRankFreeModule): The test suite is passed as well:: sage: TestSuite(C0).run() - """ Element = TrivialSection @@ -598,7 +586,6 @@ def __init__(self, vbundle, domain): sage: C0 is E.section_module(force_free=True) True sage: TestSuite(C0).run() - """ from .scalarfield import ScalarField self._domain = domain @@ -639,7 +626,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, s = -x e_0 + y e_1 sage: C0(0) is C0.zero() True - """ try: if comp.is_trivial_zero(): @@ -679,7 +665,6 @@ def _coerce_map_from_(self, other): False sage: C0_U._coerce_map_from_(C0) True - """ if isinstance(other, (SectionModule, SectionFreeModule)): return self._domain.is_subset(other._domain) @@ -706,7 +691,6 @@ def _repr_(self): sage: C0 # indirect doctest Free module C^0(M;E) of sections on the 2-dimensional topological manifold M with values in the real vector bundle E of rank 2 - """ desc = "Free module {} of sections on the {} with values in the {} " \ "vector bundle {} of rank {}" @@ -731,7 +715,6 @@ def domain(self): bundle E of rank 2 sage: C0_U.domain() Open subset U of the 3-dimensional topological manifold M - """ return self._domain @@ -770,7 +753,6 @@ def vector_bundle(self): 3-dimensional topological manifold M sage: E is C0.vector_bundle() True - """ return self._vbundle @@ -826,7 +808,6 @@ def basis(self, symbol=None, latex_symbol=None, from_frame=None, See :class:`~sage.manifolds.local_frame.LocalFrame` for more examples and documentation. - """ from sage.manifolds.local_frame import LocalFrame if symbol is None: diff --git a/src/sage/manifolds/structure.py b/src/sage/manifolds/structure.py index 25ff96ac9df..ed166b6438a 100644 --- a/src/sage/manifolds/structure.py +++ b/src/sage/manifolds/structure.py @@ -35,6 +35,8 @@ # This is a slight abuse by making this a Singleton, but there is no # need to have different copies of this object. + + class TopologicalStructure(Singleton): """ The structure of a topological manifold over a general topological field. @@ -55,7 +57,6 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: TopologicalStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat @@ -80,10 +81,10 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: RealTopologicalStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat + class DifferentialStructure(Singleton): """ The structure of a differentiable manifold over a general topological @@ -105,7 +106,6 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: DifferentialStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat @@ -130,10 +130,10 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: RealDifferentialStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat + class PseudoRiemannianStructure(Singleton): """ The structure of a pseudo-Riemannian manifold. @@ -154,10 +154,10 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: PseudoRiemannianStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat + class RiemannianStructure(Singleton): """ The structure of a Riemannian manifold. @@ -178,10 +178,10 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: RiemannianStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat + class LorentzianStructure(Singleton): """ The structure of a Lorentzian manifold. @@ -202,10 +202,10 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: LorentzianStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat + class DegenerateStructure(Singleton): """ The structure of a degenerate manifold. @@ -226,6 +226,5 @@ def subcategory(self, cat): sage: from sage.categories.manifolds import Manifolds sage: DegenerateStructure().subcategory(Manifolds(RR)) Category of manifolds over Real Field with 53 bits of precision - """ return cat diff --git a/src/sage/manifolds/subset.py b/src/sage/manifolds/subset.py index bf945ebb0c1..453fa02de2f 100644 --- a/src/sage/manifolds/subset.py +++ b/src/sage/manifolds/subset.py @@ -19,7 +19,6 @@ - [Lee2011]_ - EXAMPLES: Two subsets on a manifold:: @@ -76,6 +75,7 @@ from sage.manifolds.family import ManifoldObjectFiniteFamily, ManifoldSubsetFiniteFamily from sage.manifolds.point import ManifoldPoint + class ManifoldSubset(UniqueRepresentation, Parent): r""" Subset of a topological manifold. @@ -94,7 +94,7 @@ class :class:`~sage.structure.parent.Parent`. - ``manifold`` -- topological manifold on which the subset is defined - ``name`` -- string; name (symbol) given to the subset - - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to + - ``latex_name`` -- string (default: ``None``); LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` - ``category`` -- (default: ``None``) to specify the category; if ``None``, the category for generic subsets is used @@ -144,7 +144,6 @@ class :class:`~sage.structure.parent.Parent`. True sage: p in M True - """ Element = ManifoldPoint @@ -170,7 +169,6 @@ def __init__(self, manifold, name: str, latex_name=None, category=None): ``_test_elements`` cannot be passed without a proper coordinate definition of the subset. - """ if not isinstance(name, str): raise TypeError("{} is not a string".format(name)) @@ -219,7 +217,6 @@ def _repr_(self): 'Subset A of the 2-dimensional topological manifold M' sage: repr(A) # indirect doctest 'Subset A of the 2-dimensional topological manifold M' - """ return "Subset {} of the {}".format(self._name, self._manifold) @@ -271,15 +268,15 @@ def _element_constructor_(self, coords=None, chart=None, name=None, - ``name`` -- (default: ``None``) name given to the point - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the point; if none are provided, the LaTeX symbol is set to ``name`` - - ``check_coords`` -- (default: ``True``) determines whether - ``coords`` are valid coordinates for the chart ``chart``; - for symbolic coordinates, it is recommended to set ``check_coords`` - to ``False`` + - ``check_coords`` -- boolean (default: ``True``); determines whether + ``coords`` are valid coordinates for the chart ``chart``. + For symbolic coordinates, it is recommended to set ``check_coords`` + to ``False``. OUTPUT: - - an instance of :class:`~sage.manifolds.point.ManifoldPoint` - representing a point in the current subset. + An instance of :class:`~sage.manifolds.point.ManifoldPoint` + representing a point in the current subset. EXAMPLES:: @@ -330,7 +327,6 @@ def _element_constructor_(self, coords=None, chart=None, name=None, Point p on the 2-dimensional topological manifold M sage: X(q) (-2, 3) - """ if isinstance(coords, ManifoldPoint): point = coords # for readability @@ -363,7 +359,6 @@ def _an_element_(self): Point on the 2-dimensional topological manifold M sage: p in A True - """ #!# should be improved... return self.element_class(self) @@ -409,9 +404,7 @@ def lift(self, p): - ``p`` -- point of the subset - OUTPUT: - - - the same point, considered as a point of the ambient manifold + OUTPUT: the same point, considered as a point of the ambient manifold EXAMPLES:: @@ -430,7 +423,6 @@ def lift(self, p): (1, -2) sage: (p == q) and (q == p) True - """ return self._manifold(p) @@ -442,9 +434,7 @@ def retract(self, p): - ``p`` -- point of the ambient manifold - OUTPUT: - - - the same point, considered as a point of the subset + OUTPUT: the same point, considered as a point of the subset EXAMPLES:: @@ -473,7 +463,6 @@ def retract(self, p): ... ValueError: the Point on the 2-dimensional topological manifold M is not in Open subset A of the 2-dimensional topological manifold M - """ return self(p) @@ -499,7 +488,6 @@ def manifold(self): sage: A.ambient() is A.manifold() True - """ return self._manifold @@ -520,7 +508,6 @@ def is_open(self): sage: A = M.subset('A') sage: A.is_open() False - """ return False @@ -552,7 +539,6 @@ def is_closed(self): sage: M.declare_union(N, complement_N, disjoint=True) sage: complement_N.is_closed() True - """ if self.manifold().is_subset(self): return True @@ -599,10 +585,11 @@ def open_covers(self, trivial=True, supersets=False): INPUT: - - ``trivial`` -- (default: ``True``) if ``self`` is open, include the trivial - open cover of ``self`` by itself - - ``supersets`` -- (default: ``False``) if ``True``, include open covers of - all the supersets; it can also be an iterable of supersets to include + - ``trivial`` -- boolean (default: ``True``); if ``self`` is open, + include the trivial open cover of ``self`` by itself + - ``supersets`` -- boolean (default: ``False``); if ``True``, include + open covers of all the supersets. It can also be an iterable of + supersets to include. EXAMPLES:: @@ -628,7 +615,6 @@ def open_covers(self, trivial=True, supersets=False): [Set {M} of open subsets of the 2-dimensional topological manifold M, Set {U, V} of open subsets of the 2-dimensional topological manifold M, Set {A, B, V} of open subsets of the 2-dimensional topological manifold M] - """ if supersets is False: supersets = [self] @@ -671,10 +657,11 @@ def open_cover_family(self, trivial=True, supersets=False): INPUT: - - ``trivial`` -- (default: ``True``) if ``self`` is open, include the trivial - open cover of ``self`` by itself - - ``supersets`` -- (default: ``False``) if ``True``, include open covers of - all the supersets; it can also be an iterable of supersets to include + - ``trivial`` -- boolean (default: ``True``); if ``self`` is open, + include the trivial open cover of ``self`` by itself + - ``supersets`` -- boolean (default: ``False``); if ``True``, include + open covers of all the supersets. It can also be an iterable of + supersets to include EXAMPLES:: @@ -695,7 +682,6 @@ def open_cover_family(self, trivial=True, supersets=False): sage: M.declare_union(U,V) sage: M.open_cover_family() Set {{A, B, V}, {M}, {U, V}} of objects of the 2-dimensional topological manifold M - """ return ManifoldObjectFiniteFamily(self.open_covers( trivial=trivial, supersets=supersets)) @@ -718,7 +704,6 @@ def open_supersets(self): sage: sorted(W.open_supersets(), key=lambda S: S._name) [2-dimensional topological manifold M, Open subset U of the 2-dimensional topological manifold M] - """ for superset in self._supersets: if superset.is_open(): @@ -749,7 +734,6 @@ def open_superset_family(self): sage: W = V.subset('W') sage: W.open_superset_family() Set {M, U} of open subsets of the 2-dimensional topological manifold M - """ return ManifoldSubsetFiniteFamily(self.open_supersets()) @@ -781,7 +765,6 @@ def subsets(self): sage: M.subset_family() Set {M, U, V} of subsets of the 2-dimensional topological manifold M - """ yield from self._subsets @@ -834,7 +817,6 @@ def list_of_subsets(self): {Subset V of the 2-dimensional topological manifold M, 2-dimensional topological manifold M, Open subset U of the 2-dimensional topological manifold M} - """ deprecation(31727, "the method list_of_subsets of ManifoldSubset is deprecated; use subset_family or subsets instead") return sorted(self._subsets, key=lambda x: x._name) @@ -864,7 +846,6 @@ def subset_family(self): sage: V = M.subset('V') sage: M.subset_family() Set {M, U, V} of subsets of the 2-dimensional topological manifold M - """ return ManifoldSubsetFiniteFamily(self.subsets()) @@ -874,20 +855,18 @@ def subset_digraph(self, loops=False, quotient=False, open_covers=False, points= INPUT: - - ``loops`` -- (default: ``False``) whether to include the trivial containment + - ``loops`` -- boolean (default: ``False``); whether to include the trivial containment of each subset in itself as loops of the digraph - - ``quotient`` -- (default: ``False``) whether to contract directed cycles in the graph, - replacing equivalence classes of equal subsets by a single vertex. - In this case, each vertex of the digraph is a set of :class:`ManifoldSubset` - instances. - - ``open_covers`` -- (default: ``False``) whether to include vertices for open covers - - ``points`` -- (default: ``False``) whether to include vertices for declared points; + - ``quotient`` -- boolean (default: ``False``); whether to contract directed + cycles in the graph, replacing equivalence classes of equal subsets by a + single vertex. In this case, each vertex of the digraph is a set of + :class:`ManifoldSubset` instances. + - ``open_covers`` -- boolean (default: ``False``); whether to include vertices for open covers + - ``points`` -- boolean (default: ``False``); whether to include vertices for declared points; this can also be an iterable for the points to include - ``lower_bound`` -- (default: ``None``) only include supersets of this - OUTPUT: - - A digraph. Each vertex of the digraph is either: + OUTPUT: a digraph; each vertex of the digraph is either: - a :class:`ManifoldSubsetFiniteFamily` containing one instance of :class:`ManifoldSubset`. - (if ``open_covers`` is ``True``) a tuple of :class:`ManifoldSubsetFiniteFamily` instances, @@ -949,7 +928,6 @@ def label(element): D = M.subset_digraph(open_covers=True) g3 = D.relabel(label, inplace=False).plot(layout='acyclic') sphinx_plot(graphics_array([g1, g2, g3]), figsize=(8, 3)) - """ from sage.graphs.digraph import DiGraph D = DiGraph(multiedges=False, loops=loops) @@ -1048,8 +1026,8 @@ def subset_poset(self, open_covers=False, points=False, lower_bound=None): INPUT: - - ``open_covers`` -- (default: ``False``) whether to include vertices for open covers - - ``points`` -- (default: ``False``) whether to include vertices for declared points; + - ``open_covers`` -- boolean (default: ``False``); whether to include vertices for open covers + - ``points`` -- boolean (default: ``False``); whether to include vertices for declared points; this can also be an iterable for the points to include - ``lower_bound`` -- (default: ``None``) only include supersets of this @@ -1114,7 +1092,6 @@ def label(element): P = M.subset_poset(open_covers=True) g3 = P.plot(element_labels={element: label(element) for element in P}) sphinx_plot(graphics_array([g1, g2, g3]), figsize=(8, 3)) - """ from sage.combinat.posets.posets import Poset return Poset(self.subset_digraph(open_covers=open_covers, points=points, @@ -1139,7 +1116,6 @@ def equal_subsets(self): [2-dimensional topological manifold M, Open subset U of the 2-dimensional topological manifold M, Subset V of the 2-dimensional topological manifold M] - """ for S in self.supersets(): if S in self._subsets: @@ -1162,7 +1138,6 @@ def equal_subset_family(self): sage: V.declare_equal(M) sage: V.equal_subset_family() Set {M, U, V} of subsets of the 2-dimensional topological manifold M - """ return ManifoldSubsetFiniteFamily(self.equal_subsets()) @@ -1183,7 +1158,6 @@ def supersets(self): sage: sorted(V.supersets(), key=lambda v: v._name) [2-dimensional topological manifold M, Subset V of the 2-dimensional topological manifold M] - """ yield from self._supersets @@ -1210,7 +1184,6 @@ def superset_family(self): sage: V = M.subset('V') sage: V.superset_family() Set {M, V} of subsets of the 2-dimensional topological manifold M - """ return ManifoldSubsetFiniteFamily(self.supersets()) @@ -1220,14 +1193,14 @@ def superset_digraph(self, loops=False, quotient=False, open_covers=False, point INPUT: - - ``loops`` -- (default: ``False``) whether to include the trivial containment + - ``loops`` -- boolean (default: ``False``); whether to include the trivial containment of each subset in itself as loops of the digraph - - ``quotient`` -- (default: ``False``) whether to contract directed cycles in the graph, - replacing equivalence classes of equal subsets by a single vertex. - In this case, each vertex of the digraph is a set of :class:`ManifoldSubset` - instances. - - ``open_covers`` -- (default: ``False``) whether to include vertices for open covers - - ``points`` -- (default: ``False``) whether to include vertices for declared points; + - ``quotient`` -- boolean (default: ``False``); whether to contract + directed cycles in the graph, replacing equivalence classes of equal + subsets by a single vertex. In this case, each vertex of the digraph + is a set of :class:`ManifoldSubset` instances. + - ``open_covers`` -- boolean (default: ``False``); whether to include vertices for open covers + - ``points`` -- boolean (default: ``False``); whether to include vertices for declared points; this can also be an iterable for the points to include - ``upper_bound`` -- (default: ``None``) only include subsets of this @@ -1238,7 +1211,6 @@ def superset_digraph(self, loops=False, quotient=False, open_covers=False, point sage: VW = V.union(W) sage: P = V.superset_digraph(loops=False, upper_bound=VW); P # needs sage.graphs Digraph on 2 vertices - """ if upper_bound is None: upper_bound = self._manifold @@ -1251,8 +1223,8 @@ def superset_poset(self, open_covers=False, points=False, upper_bound=None): INPUT: - - ``open_covers`` -- (default: ``False``) whether to include vertices for open covers - - ``points`` -- (default: ``False``) whether to include vertices for declared points; + - ``open_covers`` -- boolean (default: ``False``); whether to include vertices for open covers + - ``points`` -- boolean (default: ``False``); whether to include vertices for declared points; this can also be an iterable for the points to include - ``upper_bound`` -- (default: ``None``) only include subsets of this @@ -1265,7 +1237,6 @@ def superset_poset(self, open_covers=False, points=False, upper_bound=None): Finite poset containing 3 elements sage: P.plot(element_labels={element: element._name for element in P}) # needs sage.graphs sage.plot Graphics object consisting of 6 graphics primitives - """ if upper_bound is None: upper_bound = self._manifold @@ -1282,7 +1253,7 @@ def get_subset(self, name): INPUT: - - ``name`` -- (string) name of the subset + - ``name`` -- string; name of the subset OUTPUT: @@ -1311,7 +1282,6 @@ def get_subset(self, name): Open subset U of the 4-dimensional topological manifold M sage: M.get_subset('U') is U True - """ for ss in self._subsets: if ss._name == name: @@ -1355,7 +1325,7 @@ def declare_union(self, *subsets_or_families, disjoint=False): INPUT: - ``subsets_or_families`` -- finitely many subsets or iterables of subsets - - ``disjoint`` -- (default: ``False``) whether to declare the subsets + - ``disjoint`` -- boolean (default: ``False``); whether to declare the subsets pairwise disjoint EXAMPLES:: @@ -1413,7 +1383,6 @@ def label(element): P = M.subset_poset(open_covers=True); P g3 = P.plot(element_labels={element: label(element) for element in P}) sphinx_plot(graphics_array([g1, g2, g3]), figsize=(8, 3)) - """ subsets = ManifoldSubsetFiniteFamily.from_subsets_or_families(*subsets_or_families) if disjoint: @@ -1455,7 +1424,6 @@ def _declare_union_2_subsets(self, dom1, dom2): sage: M.declare_union(A, B) sage: A.union(B) 2-dimensional topological manifold M - """ if dom1 == dom2: if dom1 != self: @@ -1485,7 +1453,7 @@ def declare_equal(self, *others): INPUT: - ``others`` -- finitely many subsets or iterables of subsets of the same - manifold as ``self``. + manifold as ``self`` EXAMPLES:: @@ -1528,7 +1496,6 @@ def label(element): P = M.subset_poset() g3 = P.plot(element_labels={element: label(element) for element in P}) sphinx_plot(graphics_array([g1, g2, g3]), figsize=(8, 3)) - """ F = ManifoldSubsetFiniteFamily.from_subsets_or_families equal_sets = F(self, *others) @@ -1759,7 +1726,6 @@ def label(element): P = M.subset_poset(open_covers=True, points=[b]) g2 = P.plot(element_labels={element: label(element) for element in P}) sphinx_plot(graphics_array([g1, g2]), figsize=(8, 5)) - """ if self.has_defined_points(): raise TypeError('cannot be empty because it has defined points') @@ -1789,7 +1755,6 @@ def is_empty(self): True sage: AA.is_empty() True - """ if self.has_defined_points(subsets=False): # Fast path, do not check subsets @@ -1819,7 +1784,6 @@ def declare_nonempty(self): Traceback (most recent call last): ... TypeError: cannot be empty because it has defined points - """ if self.has_defined_points(subsets=False): # Fast path, do not check subsets @@ -1834,8 +1798,8 @@ def has_defined_points(self, subsets=True): INPUT: - - ``subsets`` -- (default: ``True``) if ``False``, only consider points that have - been defined directly on ``self``; if ``True``, also consider points on all subsets. + - ``subsets`` -- boolean (default: ``True``); if ``False``, only consider points that have + been defined directly on ``self``. If ``True``, also consider points on all subsets. EXAMPLES:: @@ -1850,7 +1814,6 @@ def has_defined_points(self, subsets=True): False sage: A.has_defined_points() True - """ if subsets: return any(subset._has_defined_points for subset in self.subsets()) @@ -1924,7 +1887,6 @@ def declare_closed(self): sage: A.declare_closed() sage: cl_B2.is_subset(A) True - """ if self.is_closed(): return @@ -1944,9 +1906,9 @@ def subset(self, name, latex_name=None, is_open=False): INPUT: - ``name`` -- name given to the subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` - - ``is_open`` -- (default: ``False``) if ``True``, the created subset + - ``is_open`` -- boolean (default: ``False``); if ``True``, the created subset is assumed to be open with respect to the manifold's topology OUTPUT: @@ -2000,7 +1962,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -2049,7 +2011,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): True sage: D.is_subset(M) True - """ if supersets is None: supersets = set() @@ -2068,7 +2029,7 @@ def _init_open_subset(self, resu, coord_def): INPUT: - ``resu`` -- an instance of :class:`TopologicalManifold` or - a subclass. + a subclass - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -2087,7 +2048,6 @@ def _init_open_subset(self, resu, coord_def): sage: cl_D._init_open_subset(D, coord_def) sage: D.is_subset(cl_D) True - """ resu._supersets.update(self._supersets) self._subsets.add(resu) @@ -2106,10 +2066,10 @@ def superset(self, name, latex_name=None, is_open=False): INPUT: - ``name`` -- name given to the superset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the superset; if none are provided, it is set to ``name`` - - ``is_open`` -- (default: ``False``) if ``True``, the created subset - is assumed to be open with respect to the manifold's topology + - ``is_open`` -- boolean (default: ``False``); if ``True``, the created + subset is assumed to be open with respect to the manifold's topology OUTPUT: @@ -2141,7 +2101,6 @@ def superset(self, name, latex_name=None, is_open=False): sage: c = a.superset('C') sage: c == b False - """ if self is self._manifold: return self @@ -2171,7 +2130,7 @@ def intersection(self, *others: ManifoldSubset, name: Optional[str] = None, late - ``name`` -- (default: ``None``) name given to the intersection in the case the latter has to be created; the default is ``self._name`` inter ``other._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the intersection in the case the latter has to be created; the default is built upon the symbol `\cap` @@ -2254,7 +2213,6 @@ def label(element): True sage: a.intersection(M) is a True - """ subsets = ManifoldSubsetFiniteFamily.from_subsets_or_families(self, *others) subset_iter = iter(self._reduce_intersection_members(subsets)) @@ -2284,7 +2242,7 @@ def _reduce_intersection_members(subsets): INPUT: - ``subsets`` -- a non-empty iterable of :class:`ManifoldSubset` instances - of the same manifold. + of the same manifold EXAMPLES:: @@ -2303,7 +2261,6 @@ def _reduce_intersection_members(subsets): Traceback (most recent call last): ... TypeError: input set must be nonempty - """ subsets = set(subsets) if not subsets: @@ -2344,10 +2301,10 @@ def _intersection_subset(self, *others, name=None, latex_name=None): INPUT: - ``others`` -- an iterable of :class:`ManifoldSubset` instances - of the same manifold. + of the same manifold - ``name`` -- (default: ``None``) name given to the intersection; the default is ``self._name`` inter [...] inter ``last_other._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the intersection; the default is built upon the symbol `\cap` EXAMPLES:: @@ -2360,7 +2317,6 @@ def _intersection_subset(self, *others, name=None, latex_name=None): Subset B1_inter_B2 of the 2-dimensional topological manifold M sage: B1._intersection_subset(B2, B3) Subset B1_inter_B2_inter_B3 of the 2-dimensional topological manifold M - """ subsets = ManifoldSubsetFiniteFamily.from_subsets_or_families(self, *others) if latex_name is None: @@ -2396,7 +2352,7 @@ def union(self, *others, name=None, latex_name=None): - ``name`` -- (default: ``None``) name given to the union in the case the latter has to be created; the default is ``self._name`` union ``other._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the union in the case the latter has to be created; the default is built upon the symbol `\cup` @@ -2486,7 +2442,6 @@ def label(element): sage: e = a.subset('E') sage: d.union(e).is_subset(a) True - """ subsets = ManifoldSubsetFiniteFamily.from_subsets_or_families(self, *others) subsets = self._reduce_union_members(subsets) @@ -2515,7 +2470,7 @@ def _reduce_union_members(subsets): INPUT: - ``subsets`` -- an iterable of :class:`ManifoldSubset` instances - of the same manifold. + of the same manifold EXAMPLES:: @@ -2530,7 +2485,6 @@ def _reduce_union_members(subsets): Set {B1_union_B2} of subsets of the 2-dimensional topological manifold M sage: M._reduce_union_members([A, B1, B2]) Set {A} of subsets of the 2-dimensional topological manifold M - """ subsets = set(subsets) @@ -2569,7 +2523,7 @@ def _union_subset(self, other, name=None, latex_name=None): - ``other`` -- an instance of :class:`ManifoldSubset` - ``name`` -- (default: ``None``) name given to the union; the default is ``self._name`` union ``other._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the union; the default is built upon the symbol `\cup` EXAMPLES:: @@ -2579,7 +2533,6 @@ def _union_subset(self, other, name=None, latex_name=None): sage: B2 = M.subset('B2') sage: B1._union_subset(B2) Subset B1_union_B2 of the 2-dimensional topological manifold M - """ if latex_name is None: if name is None: @@ -2626,11 +2579,11 @@ def complement(self, superset=None, name=None, latex_name=None, is_open=False): - ``name`` -- (default: ``None``) name given to the complement in the case the latter has to be created; the default is ``superset._name`` minus ``self._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the complement in the case the latter has to be created; the default is built upon the symbol `\setminus` - - ``is_open`` -- (default: ``False``) if ``True``, the created subset - is assumed to be open with respect to the manifold's topology + - ``is_open`` -- boolean (default: ``False``); if ``True``, the created + subset is assumed to be open with respect to the manifold's topology OUTPUT: @@ -2660,7 +2613,6 @@ def complement(self, superset=None, name=None, latex_name=None, is_open=False): Open subset M_minus_A of the 2-dimensional topological manifold M sage: A.is_closed() True - """ if superset is None: superset = self.manifold() @@ -2680,11 +2632,11 @@ def difference(self, other, name=None, latex_name=None, is_open=False): - ``name`` -- (default: ``None``) name given to the difference in the case the latter has to be created; the default is ``self._name`` minus ``other._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the difference in the case the latter has to be created; the default is built upon the symbol `\setminus` - - ``is_open`` -- (default: ``False``) if ``True``, the created subset - is assumed to be open with respect to the manifold's topology + - ``is_open`` -- boolean (default: ``False``); if ``True``, the created + subset is assumed to be open with respect to the manifold's topology OUTPUT: @@ -2725,7 +2677,6 @@ def difference(self, other, name=None, latex_name=None, is_open=False): sage: O.is_closed() and O.is_open() True - """ # See if it has been created already diffs = [] @@ -2771,7 +2722,7 @@ def closure(self, name=None, latex_name=None): - ``name`` -- (default: ``None``) name given to the difference in the case the latter has to be created; the default prepends ``cl_`` to ``self._name`` - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the difference in the case the latter has to be created; the default is built upon the operator `\mathrm{cl}` @@ -2801,7 +2752,6 @@ def closure(self, name=None, latex_name=None): Open subset D1 of the 2-dimensional topological manifold R^2 sage: D1.closure().is_subset(D2.closure()) True - """ if self.is_closed(): return self diff --git a/src/sage/manifolds/subsets/closure.py b/src/sage/manifolds/subsets/closure.py index 922d77ba263..b1eb8d37835 100644 --- a/src/sage/manifolds/subsets/closure.py +++ b/src/sage/manifolds/subsets/closure.py @@ -17,6 +17,7 @@ from sage.manifolds.subset import ManifoldSubset + class ManifoldSubsetClosure(ManifoldSubset): r""" @@ -27,8 +28,8 @@ class ManifoldSubsetClosure(ManifoldSubset): - ``subset`` -- a :class:`~sage.manifolds.subset.ManifoldSubset` - ``name`` -- (default: computed from the name of the subset) string; name (symbol) given to the closure - - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to - denote the subset; if none is provided, it is set to ``name`` + - ``latex_name`` -- string (default: ``None``); LaTeX symbol to + denote the subset. If none is provided, it is set to ``name``. EXAMPLES:: @@ -54,7 +55,6 @@ class ManifoldSubsetClosure(ManifoldSubset): sage: S.declare_closed() sage: cl_D.is_subset(S) True - """ def __init__(self, subset, name=None, latex_name=None): @@ -78,7 +78,6 @@ def __init__(self, subset, name=None, latex_name=None): False sage: cl_D == also_cl_D False - """ self._subset = subset base_manifold = subset.manifold() @@ -127,6 +126,5 @@ def is_closed(self): Topological closure cl_D of the Open subset D of the 2-dimensional topological manifold R^2 sage: cl_D.is_closed() True - """ return True diff --git a/src/sage/manifolds/subsets/pullback.py b/src/sage/manifolds/subsets/pullback.py index 95518f2ef0e..d62f9936368 100644 --- a/src/sage/manifolds/subsets/pullback.py +++ b/src/sage/manifolds/subsets/pullback.py @@ -35,7 +35,6 @@ class ManifoldSubsetPullback(ManifoldSubset): - """ Manifold subset defined as a pullback of a subset under a continuous map. @@ -104,8 +103,8 @@ class ManifoldSubsetPullback(ManifoldSubset): Using the embedding map of a submanifold:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological"); N + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological'); N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M sage: CM. = M.chart() @@ -134,7 +133,6 @@ class ManifoldSubsetPullback(ManifoldSubset): embedded in the 3-dimensional topological manifold M sage: N.point((2,0)) in D False - """ @staticmethod def __classcall_private__(cls, map, codomain_subset, inverse=None, @@ -154,7 +152,6 @@ def __classcall_private__(cls, map, codomain_subset, inverse=None, Subset x_y_inv_P of the 2-dimensional topological manifold R^2 sage: S is ManifoldSubsetPullback(c_cart, P) True - """ try: @@ -291,7 +288,6 @@ def _is_open(codomain_subset): A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 point, 3 closure_points sage: ManifoldSubsetPullback._is_open(T) False - """ if isinstance(codomain_subset, ManifoldSubset): @@ -361,7 +357,6 @@ def _interval_restriction(expr, interval): () sage: _interval_restriction(t^2, RealSet.unbounded_above_closed(0)[0]) [] - """ conjunction = [] @@ -428,7 +423,6 @@ def _realset_restriction(expr, realset): () sage: _realset_restriction(t, RealSet([-5, -4], (-1, 1), [3, 4], [6, 7])) ([t > -1, t < 1], [t >= 3, t <= 4]) - """ disjunction = [] for interval in realset: @@ -453,7 +447,7 @@ def _polyhedron_restriction(expr, polyhedron, relint=False): - ``expr`` -- a symbolic expression - ``polyhedron`` -- an instance of :class:`~sage.geometry.polyhedron.base.Polyhedron_base` - - ``relint`` -- whether the restriction should use the relative interior. + - ``relint`` -- whether the restriction should use the relative interior OUTPUT: @@ -501,12 +495,13 @@ def _coord_def(map, codomain_subset): INPUT: - - ``map`` -- an instance of :class:`ScalarField` or :class:`Chart`. + - ``map`` -- an instance of :class:`ScalarField` or :class:`Chart` - - ``codomain_subset`` -- if ``map`` is a :class:`ScalarField`, an instance of :class:`RealSet`; - if ``map`` is a :class:`Chart`, the relative interior of a polyhedron. + - ``codomain_subset`` -- if ``map`` is a :class:`ScalarField`, an + instance of :class:`RealSet`; if ``map`` is a :class:`Chart`, the + relative interior of a polyhedron - For other inputs, a :class:`NotImplementedError` will be raised. + For other inputs, a :exc:`NotImplementedError` will be raised. OUTPUT: @@ -536,7 +531,6 @@ def _coord_def(map, codomain_subset): (1, 4) sage: _coord_def(r_squared, I) {Chart (R^2, (x, y)): [x^2 + y^2 > 1, x^2 + y^2 < 4]} - """ if isinstance(map, ScalarField) and isinstance(codomain_subset, RealSet): @@ -574,7 +568,6 @@ def __init__(self, map, codomain_subset, inverse, name, latex_name): sage: cl_O = ManifoldSubsetPullback(r_squared, cl_I); cl_O Subset f_inv_[1, 4] of the 2-dimensional topological manifold R^2 sage: TestSuite(cl_O).run(skip='_test_elements') - """ if inverse is None and isinstance(map, Chart): chart = map @@ -814,7 +807,6 @@ def is_closed(self): Subset McF of the 2-dimensional topological manifold R^2 sage: McF.is_closed() True - """ if self.manifold().dimension() == 0: return True @@ -878,7 +870,6 @@ def closure(self, name=None, latex_name=None): Subset f_inv_[1, 2] of the 2-dimensional topological manifold R^2 sage: cl_O.is_closed() True - """ if self.is_closed(): return self diff --git a/src/sage/manifolds/topological_submanifold.py b/src/sage/manifolds/topological_submanifold.py index 2333e29fd06..a99e6d1fca1 100644 --- a/src/sage/manifolds/topological_submanifold.py +++ b/src/sage/manifolds/topological_submanifold.py @@ -123,8 +123,8 @@ class TopologicalSubmanifold(TopologicalManifold): Let `N` be a 2-dimensional submanifold of a 3-dimensional manifold `M`:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M @@ -173,7 +173,6 @@ class TopologicalSubmanifold(TopologicalManifold): .. SEEALSO:: :mod:`~sage.manifolds.manifold` - """ def __init__(self, n, name, field, structure, ambient=None, base_manifold=None, latex_name=None, start_index=0, @@ -183,12 +182,11 @@ def __init__(self, n, name, field, structure, ambient=None, TESTS:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M - """ TopologicalManifold.__init__(self, n, name, field, structure, base_manifold=base_manifold, @@ -215,7 +213,6 @@ def _init_immersion(self, ambient=None): sage: M = Manifold(2, 'M', structure='topological') sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: N._init_immersion(ambient=M) - """ self._immersion = None self._immersion_inv = None @@ -244,8 +241,8 @@ def _repr_(self): TESTS:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M @@ -254,7 +251,6 @@ def _repr_(self): sage: N 2-dimensional topological submanifold N embedded in the 3-dimensional topological manifold M - """ if self is not self._manifold: return "Open subset {} of the {}".format(self._name, self._manifold) @@ -282,7 +278,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): INPUT: - ``name`` -- name given to the open subset - - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the subset; if none are provided, it is set to ``name`` - ``coord_def`` -- (default: {}) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -291,14 +287,12 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): - ``supersets`` -- (default: only ``self``) list of sets that the new open subset is a subset of - OUTPUT: - - - the open subset, as an instance of :class:`TopologicalSubmanifold` + OUTPUT: the open subset, as an instance of :class:`TopologicalSubmanifold` EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological"); N + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological'); N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M sage: S = N.subset('S'); S @@ -323,7 +317,6 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): Open subset O of the 2-dimensional topological submanifold N embedded in the 3-dimensional topological manifold M - """ resu = TopologicalSubmanifold(self._dim, name, self._field, self._structure, self._ambient, @@ -343,7 +336,7 @@ def _init_open_subset(self, resu, coord_def): INPUT: - ``resu`` -- an instance of :class:`TopologicalManifold` or - a subclass. + a subclass - ``coord_def`` -- (default: ``{}``) definition of the subset in terms of coordinates; ``coord_def`` must a be dictionary with keys @@ -352,8 +345,8 @@ def _init_open_subset(self, resu, coord_def): EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: phi = N.continuous_map(M) sage: N.set_embedding(phi) sage: N @@ -413,8 +406,8 @@ def set_immersion(self, phi, inverse=None, var=None, EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M @@ -435,7 +428,6 @@ def set_immersion(self, phi, inverse=None, var=None, (x, y, z) ↦ -x^2 - y^2 + z sage: N.set_immersion(phi, inverse=phi_inv, var=t, ....: t_inverse={t: phi_inv_t}) - """ if not isinstance(phi, ContinuousMap): raise TypeError("the argument phi must be a continuous map") @@ -482,8 +474,8 @@ def declare_embedding(self): EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M @@ -504,7 +496,6 @@ def declare_embedding(self): True sage: N._embedded True - """ if not self._immersed: raise ValueError("please declare an embedding using set_immersion " @@ -539,8 +530,8 @@ def set_embedding( EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M @@ -567,7 +558,6 @@ def set_embedding( sage: N 2-dimensional topological submanifold N embedded in the 3-dimensional topological manifold M - """ self.set_immersion(phi, inverse, var, t_inverse) self.declare_embedding() @@ -606,15 +596,13 @@ def adapted_chart(self, postscript=None, latex_postscript=None): of the parameters `(t_1,\ldots,t_{m-n})`, If ``None``, ``"_" + self.ambient()._latex_()`` is used - OUTPUT: - - - list of adapted charts on `M` created from the charts of ``self`` + OUTPUT: list of adapted charts on `M` created from the charts of ``self`` EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological", + sage: M = Manifold(3, 'M', structure='topological', ....: latex_name=r"\mathcal{M}") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M @@ -645,7 +633,6 @@ def adapted_chart(self, postscript=None, latex_postscript=None): [Chart (M, (u1, v1, t1))] sage: latex(_) \left[\left(\mathcal{M},({{u}_1}, {{v}_1}, {{t}_1})\right)\right] - """ if not self._embedded: raise ValueError("an embedding is required") @@ -730,7 +717,7 @@ def plot(self, param, u, v, chart1=None, chart2=None, **kwargs): INPUT: - ``param`` -- dictionary of values indexed by the free variables - appearing in the foliation. + appearing in the foliation - ``u`` -- iterable of the values taken by the first coordinate of the surface to plot - ``v`` -- iterable of the values taken by the second coordinate of the @@ -744,8 +731,8 @@ def plot(self, param, u, v, chart1=None, chart2=None, **kwargs): EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient = M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient = M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart() sage: t = var('t') @@ -769,8 +756,8 @@ def plot(self, param, u, v, chart1=None, chart2=None, **kwargs): .. PLOT:: - M = Manifold(3, 'M', structure="topological") - N = Manifold(2, 'N', ambient = M, structure="topological") + M = Manifold(3, 'M', structure='topological') + N = Manifold(2, 'N', ambient = M, structure='topological') CM = M.chart('x y z'); x, y, z = CM[:] CN = N.chart('u v'); u, v = CN[:] t = var('t') @@ -793,7 +780,6 @@ def plot(self, param, u, v, chart1=None, chart2=None, **kwargs): .. SEEALSO:: :class:`~sage.plot.plot3d.parametric_surface.ParametricSurface` - """ if self._dim != 2 or self._ambient._dim != 3: @@ -817,8 +803,8 @@ def ambient(self) -> TopologicalManifold: EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: N.ambient() 3-dimensional topological manifold M """ @@ -830,8 +816,8 @@ def immersion(self) -> ContinuousMap: EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart() sage: t = var('t') @@ -844,7 +830,6 @@ def immersion(self) -> ContinuousMap: Continuous map from the 2-dimensional topological submanifold N immersed in the 3-dimensional topological manifold M to the 3-dimensional topological manifold M - """ if not self._immersed: raise ValueError("the submanifold is not immersed") @@ -857,8 +842,8 @@ def embedding(self) -> ContinuousMap: EXAMPLES:: - sage: M = Manifold(3, 'M', structure="topological") - sage: N = Manifold(2, 'N', ambient=M, structure="topological") + sage: M = Manifold(3, 'M', structure='topological') + sage: N = Manifold(2, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart() sage: t = var('t') @@ -871,7 +856,6 @@ def embedding(self) -> ContinuousMap: Continuous map from the 2-dimensional topological submanifold N embedded in the 3-dimensional topological manifold M to the 3-dimensional topological manifold M - """ if not self._embedded: raise ValueError("the submanifold is not embedded") @@ -886,8 +870,8 @@ def as_subset(self): EXAMPLES:: - sage: M = Manifold(2, 'M', structure="topological") - sage: N = Manifold(1, 'N', ambient=M, structure="topological") + sage: M = Manifold(2, 'M', structure='topological') + sage: N = Manifold(1, 'N', ambient=M, structure='topological') sage: CM. = M.chart() sage: CN. = N.chart(coord_restrictions=lambda u: [u > -1, u < 1]) sage: phi = N.continuous_map(M, {(CN,CM): [u, u^2]}) @@ -900,6 +884,5 @@ def as_subset(self): from the 1-dimensional topological submanifold N embedded in the 2-dimensional topological manifold M to the 2-dimensional topological manifold M - """ return self.embedding().image() diff --git a/src/sage/manifolds/trivialization.py b/src/sage/manifolds/trivialization.py index 7e822c86e5d..4c718db8ffe 100644 --- a/src/sage/manifolds/trivialization.py +++ b/src/sage/manifolds/trivialization.py @@ -24,6 +24,7 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.manifolds.local_frame import TrivializationFrame + class Trivialization(UniqueRepresentation, SageObject): r""" A local trivialization of a given vector bundle. @@ -120,7 +121,6 @@ class Trivialization(UniqueRepresentation, SageObject): [0, 1] sage: fU[1].comp(fV.restrict(W))[:] [1, 0] - """ def __init__(self, vector_bundle, name, domain, latex_name=None): @@ -133,7 +133,6 @@ def __init__(self, vector_bundle, name, domain, latex_name=None): sage: E = M.vector_bundle(2, 'E') sage: phi = E.trivialization('phi') sage: TestSuite(phi).run() - """ self._name = name if latex_name is None: @@ -162,7 +161,6 @@ def _repr_(self): sage: phi = E.trivialization('phi', domain=M) sage: phi._repr_() 'Trivialization (phi, E|_M)' - """ desc = "Trivialization (" desc += self._name + ", " @@ -180,7 +178,6 @@ def _latex_(self): sage: phi = E.trivialization('phi', domain=M, latex_name=r'\varphi') sage: phi._latex_() '\\varphi : E |_{M} \\to M \\times \\Bold{R}^1' - """ latex = self._latex_name + r' : ' latex += r'{} |_{{{}}} \to {} \times {}^{}'.format(self._vbundle._latex_name, @@ -200,7 +197,6 @@ def base_space(self): sage: phi = E.trivialization('phi', domain=U) sage: phi.base_space() 2-dimensional topological manifold M - """ return self._base_space @@ -230,7 +226,6 @@ def transition_map(self, other, transf, compute_inverse=True): sage: phi_U.transition_map(phi_V, 1) Transition map from Trivialization (phi_U, E|_U) to Trivialization (phi_V, E|_V) - """ return TransitionMap(self, other, transf, compute_inverse=compute_inverse) @@ -248,7 +243,6 @@ def vector_bundle(self): sage: phi.vector_bundle() Topological real vector bundle E -> M of rank 2 over the base space 2-dimensional topological manifold M - """ return self._vbundle @@ -264,7 +258,6 @@ def domain(self): sage: phi = E.trivialization('phi', domain=U) sage: phi.domain() Open subset U of the 2-dimensional topological manifold M - """ return self._domain @@ -287,7 +280,6 @@ def frame(self): sage: phi = E.trivialization('phi') sage: phi.frame() Trivialization frame (E|_M, ((phi^*e_1),(phi^*e_2))) - """ return self._frame @@ -306,12 +298,12 @@ def coframe(self): sage: phi = E.trivialization('phi') sage: phi.coframe() Trivialization coframe (E|_M, ((phi^*e^1),(phi^*e^2))) - """ return self._frame._coframe # ***************************************************************************** + class TransitionMap(SageObject): r""" Transition map between two trivializations. @@ -344,7 +336,7 @@ class TransitionMap(SageObject): or coordinate functions (:class:`~sage.manifolds.chart_func.ChartFunction`), or a bundle automorphism (:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`) - - ``compute_inverse`` -- (default: ``True``) determines whether the inverse + - ``compute_inverse`` -- boolean (default: ``True``); determines whether the inverse shall be computed or not EXAMPLES: @@ -369,7 +361,6 @@ class TransitionMap(SageObject): sage: phi_U_to_phi_V Transition map from Trivialization (phi_U, E|_U) to Trivialization (phi_V, E|_V) - """ def __init__(self, triv1, triv2, transf, compute_inverse=True): r""" @@ -392,7 +383,6 @@ def __init__(self, triv1, triv2, transf, compute_inverse=True): sage: phi_V = E.trivialization('phi_V', domain=V) sage: phi_U_to_phi_V = phi_U.transition_map(phi_V, [[0,1],[1,0]]) sage: TestSuite(phi_U_to_phi_V).run() - """ bs1 = triv1.base_space() bs2 = triv2.base_space() @@ -462,7 +452,6 @@ def _repr_(self): sage: phi_U_to_phi_V # indirect doctest Transition map from Trivialization (phi_U, E|_U) to Trivialization (phi_V, E|_V) - """ desc = "Transition map from {} to {}".format(self._triv1, self._triv2) return desc @@ -491,7 +480,6 @@ def _latex_(self): sage: latex(phi_U_to_phi_V) \varphi_V\circ \varphi_U^{-1}:U\cap V\times \Bold{R}^2 \to U\cap V\times \Bold{R}^2 - """ vspace_lname = r'\times {}^{}'.format(self._triv1._base_field._latex_(), self._bdl_rank) @@ -552,7 +540,6 @@ def automorphism(self): sage: aut.display(phi_U.frame().restrict(W)) phi_U^(-1)*phi_V = (phi_U^*e_1)⊗(phi_U^*e^2) + (phi_U^*e_2)⊗(phi_U^*e^1) - """ return self._automorphism @@ -577,7 +564,6 @@ def inverse(self): Transition map from Trivialization (phi_V, E|_V) to Trivialization (phi_U, E|_U) sage: phi_V_to_phi_U.automorphism() == phi_U_to_phi_V.automorphism().inverse() True - """ if self._inverse is None: self._vbundle.set_change_of_frame(self._frame1, self._frame2, @@ -592,9 +578,7 @@ def det(self): r""" Return the determinant of ``self``. - OUTPUT: - - - An instance of :class:`~sage.manifolds.scalarfield.ScalarField`. + OUTPUT: an instance of :class:`~sage.manifolds.scalarfield.ScalarField` EXAMPLES:: @@ -623,7 +607,6 @@ def det(self): det(phi_U^(-1)*phi_V): W → ℝ (x, y) ↦ -1 (u, v) ↦ -1 - """ aut = self._automorphism det = aut.det() @@ -688,7 +671,6 @@ def matrix(self): zero: W → ℝ (x, y) ↦ 0 (u, v) ↦ 0 - """ return self._automorphism.matrix(self._frame1) @@ -719,7 +701,6 @@ def __eq__(self, other): sage: phi_U_to_psi_V = phi_U.transition_map(psi_V, [[1,2],[3,-2]]) sage: phi_U_to_phi_V == phi_U_to_psi_V False - """ if other is self: return True @@ -747,6 +728,5 @@ def __ne__(self, other): sage: phi_U_to_phi_V_1 = phi_U.transition_map(phi_V, [[1,2],[2,-1]]) sage: phi_U_to_phi_V != phi_U_to_phi_V_1 True - """ return not (self == other) diff --git a/src/sage/manifolds/utilities.py b/src/sage/manifolds/utilities.py index 2ede73552da..190213eeb41 100644 --- a/src/sage/manifolds/utilities.py +++ b/src/sage/manifolds/utilities.py @@ -118,7 +118,6 @@ class SimplifySqrtReal(ExpressionTreeWalker): :func:`simplify_sqrt_real` for more examples with :class:`SimplifySqrtReal` at work. - """ def arithmetic(self, ex, operator): r""" @@ -159,7 +158,6 @@ def arithmetic(self, ex, operator): sage: a = x + 1 + sqrt(function('f')(x)^2) sage: s.arithmetic(a, a.operator()) x + abs(f(x)) + 1 - """ if operator is _pow: operands = ex.operands() @@ -263,7 +261,6 @@ class SimplifyAbsTrig(ExpressionTreeWalker): :func:`simplify_abs_trig` for more examples with :class:`SimplifyAbsTrig` at work. - """ def composition(self, ex, operator): r""" @@ -311,7 +308,6 @@ def composition(self, ex, operator): sage: a = abs(sin(cos(x))) # not simplifiable sage: s.composition(a, a.operator()) abs(sin(cos(x))) - """ if operator is abs_symbolic: argum = ex.operands()[0] # argument of abs @@ -405,7 +401,6 @@ def simplify_sqrt_real(expr): sage: simplify_sqrt_real( sqrt(x^3*diff(f(g(x)), x)^2) ) # x<0 (-x)^(3/2)*abs(D[0](f)(g(x)))*abs(diff(g(x), x)) sage: forget() # for doctests below - """ w0 = SR.wild() one_half = Rational((1,2)) @@ -495,7 +490,6 @@ def simplify_abs_trig(expr): sage: simplify_abs_trig(s) abs(sin(x))*D[0](f)(y^2) + cos(y) sage: forget() # for doctests below - """ w0 = SR.wild() if expr.has(abs_symbolic(sin(w0))) or expr.has(abs_symbolic(cos(w0))): @@ -594,7 +588,6 @@ def simplify_chain_real(expr): TESTS:: sage: forget() # for doctests below - """ if expr.number_of_operands() == 0: return expr @@ -669,7 +662,6 @@ def simplify_chain_generic(expr): TESTS:: sage: forget() # for doctests below - """ if expr.number_of_operands() == 0: return expr @@ -680,6 +672,7 @@ def simplify_chain_generic(expr): expr = expr.expand_sum() return expr + def simplify_chain_generic_sympy(expr): r""" Apply a chain of simplifications to a sympy expression. @@ -732,7 +725,6 @@ def simplify_chain_generic_sympy(expr): sage: s = (cos(2*x) - 2*cos(x)^2 + 1)._sympy_() sage: simplify_chain_generic_sympy(s) 0 - """ expr = expr.combsimp() expr = expr.trigsimp() @@ -740,6 +732,7 @@ def simplify_chain_generic_sympy(expr): expr = expr.simplify() return expr + def simplify_chain_real_sympy(expr): r""" Apply a chain of simplifications to a sympy expression, assuming the @@ -796,7 +789,6 @@ def simplify_chain_real_sympy(expr): sage: s = (cos(y)^2 + sin(y)^2)._sympy_() sage: simplify_chain_real_sympy(s) 1 - """ # TODO: introduce pure SymPy functions instead of simplify_sqrt_real and # simplify_abs_trig @@ -814,6 +806,7 @@ def simplify_chain_real_sympy(expr): #****************************************************************************** + class ExpressionNice(Expression): r""" Subclass of :class:`~sage.symbolic.expression.Expression` for a @@ -907,7 +900,6 @@ class ExpressionNice(Expression): f(x, y)*(d(f)/dy)^2 sage: latex(ExpressionNice(fun)) f\left(x, y\right) \left(\frac{\partial\,f}{\partial y}\right)^{2} - """ def __init__(self, ex): r""" @@ -923,7 +915,6 @@ def __init__(self, ex): sage: df_nice = ExpressionNice(df) sage: df_nice d(f)/dx - """ from sage.symbolic.ring import SR self._parent = SR @@ -952,7 +943,6 @@ def _repr_(self): sage: ExpressionNice(function('f')(x+y, x-y).diff(y)) d(f)/d(x + y) - d(f)/d(x - y) - """ d = self._parent._repr_element_(self) @@ -1051,7 +1041,6 @@ def _latex_(self): sage: latex(ExpressionNice(function('f')(x+y, x-y).diff(y))) \frac{\partial\,f}{\partial \left( x + y \right)} - \frac{\partial\,f}{\partial \left( x - y \right)} - """ from sage.misc.latex import latex @@ -1150,7 +1139,6 @@ def _list_derivatives(ex, list_d, exponent=0): sage: _list_derivatives(df, list_d) sage: list_d [(diff(f_x(x), x), 'f_x', {\cal F}, [0], [x], 2)] - """ op = ex.operator() operands = ex.operands() @@ -1213,7 +1201,6 @@ def _list_functions(ex, list_f): sage: list_f [(f, 'f', '(x, y)', {\cal F}, \left(x, y\right)), (g_x, 'g_x', '(x, y)', 'g_{x}', \left(x, y\right))] - """ op = ex.operator() operands = ex.operands() @@ -1245,6 +1232,7 @@ def _list_functions(ex, list_f): #****************************************************************************** + def set_axes_labels(graph, xlabel, ylabel, zlabel, **kwds): r""" Set axes labels for a 3D graphics object ``graph``. @@ -1263,9 +1251,7 @@ def set_axes_labels(graph, xlabel, ylabel, zlabel, **kwds): - ``zlabel`` -- string for the z-axis label - ``**kwds`` -- options (e.g. color) for text3d - OUTPUT: - - - the 3D graphic object with text3d labels added + OUTPUT: the 3D graphic object with text3d labels added EXAMPLES:: @@ -1278,7 +1264,6 @@ def set_axes_labels(graph, xlabel, ylabel, zlabel, **kwds): sage: ga.all # the 3D frame has now axes labels [Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object] - """ from sage.plot.plot3d.shapes2 import text3d xmin, ymin, zmin = graph.bounding_box()[0] @@ -1297,6 +1282,7 @@ def set_axes_labels(graph, xlabel, ylabel, zlabel, **kwds): graph += text3d(' ' + zlabel, (xmin1, ymin1, z1), **kwds) return graph + def exterior_derivative(form): r""" Exterior derivative of a differential form. @@ -1353,7 +1339,6 @@ def exterior_derivative(form): :class:`sage.manifolds.differentiable.diff_form.DiffFormParal.exterior_derivative` or :class:`sage.manifolds.differentiable.diff_form.DiffForm.exterior_derivative` for more examples. - """ return form.exterior_derivative() diff --git a/src/sage/manifolds/vector_bundle.py b/src/sage/manifolds/vector_bundle.py index e122cdf1125..ad830d68469 100644 --- a/src/sage/manifolds/vector_bundle.py +++ b/src/sage/manifolds/vector_bundle.py @@ -41,6 +41,7 @@ from sage.rings.integer import Integer from sage.manifolds.vector_bundle_fiber import VectorBundleFiber + class TopologicalVectorBundle(CategoryObject, UniqueRepresentation): r""" An instance of this class is a topological vector bundle `E \to B` over a @@ -188,7 +189,6 @@ class TopologicalVectorBundle(CategoryObject, UniqueRepresentation): the real vector bundle E of rank 2 sage: s in E.section_module() True - """ def __init__(self, rank, name, base_space, field='real', latex_name=None, category=None, unique_tag=None): @@ -202,7 +202,6 @@ def __init__(self, rank, name, base_space, field='real', sage: TopologicalVectorBundle(2, 'E', M) Topological real vector bundle E -> M of rank 2 over the base space 2-dimensional topological manifold M - """ if base_space is None: raise ValueError("a base space must be provided") @@ -265,7 +264,6 @@ def _init_attributes(self): sage: M = Manifold(2, 'M', structure='topological') sage: E = M.vector_bundle(2, 'E') sage: E._init_attributes() - """ self._section_modules = {} # dict of section modules with domains as # keys @@ -289,7 +287,6 @@ def base_space(self): sage: E = M.vector_bundle(2, 'E') sage: E.base_space() 2-dimensional topological manifold M - """ return self._base_space @@ -299,12 +296,11 @@ def base_field_type(self): OUTPUT: - - a string describing the field, with three possible values: + A string describing the field, with three possible values: - - ``'real'`` for the real field `\RR` - - ``'complex'`` for the complex field `\CC` - - ``'neither_real_nor_complex'`` for a field different - from `\RR` and `\CC` + - ``'real'`` for the real field `\RR` + - ``'complex'`` for the complex field `\CC` + - ``'neither_real_nor_complex'`` for a field different from `\RR` and `\CC` EXAMPLES:: @@ -312,7 +308,6 @@ def base_field_type(self): sage: E = M.vector_bundle(2, 'E', field=CC) sage: E.base_field_type() 'complex' - """ return self._field_type @@ -320,9 +315,7 @@ def base_field(self): r""" Return the field on which the fibers are defined. - OUTPUT: - - - a topological field + OUTPUT: a topological field EXAMPLES:: @@ -330,7 +323,6 @@ def base_field(self): sage: E = M.vector_bundle(2, 'E', field=CC) sage: E.base_field() Complex Field with 53 bits of precision - """ return self._field @@ -344,7 +336,6 @@ def rank(self): sage: E = M.vector_bundle(3, 'E') sage: E.rank() 3 - """ return self._rank @@ -359,7 +350,6 @@ def _repr_object_name(self): sage: E._repr_object_name() 'real vector bundle E -> M of rank 1 over the base space 2-dimensional topological manifold M' - """ desc = self.base_field_type() + " " desc += "vector bundle " @@ -379,7 +369,6 @@ def _repr_(self): sage: E._repr_() 'Topological real vector bundle E -> M of rank 1 over the base space 2-dimensional topological manifold M' - """ desc = "Topological " desc += self._repr_object_name() @@ -395,7 +384,6 @@ def _latex_(self): sage: E = M.vector_bundle(1, 'E') sage: E._latex_() 'E\\to M' - """ latex = self._latex_name latex += r'\to ' @@ -418,7 +406,6 @@ def _add_local_frame(self, frame): sage: E._add_local_frame(e) sage: E._frames [Local frame (E|_M, (e_0,e_1)), Local frame (E|_M, (e_0,e_1))] - """ self._trivial_parts.add(frame.domain()) self._frames.append(frame) @@ -447,7 +434,6 @@ def trivialization(self, name, domain=None, latex_name=None): sage: E = M.vector_bundle(2, 'E') sage: phi = E.trivialization('phi', domain=U); phi Trivialization (phi, E|_U) - """ if domain is None: domain = self._base_space @@ -458,9 +444,7 @@ def transitions(self): r""" Return the transition maps defined over subsets of the base space. - OUTPUT: - - - dictionary of transition maps, with pairs of trivializations as keys + OUTPUT: dictionary of transition maps, with pairs of trivializations as keys EXAMPLES:: @@ -480,7 +464,6 @@ def transitions(self): (Trivialization (phi_U, E|_V), Trivialization (phi_U, E|_U)): Transition map from Trivialization (phi_U, E|_V) to Trivialization (phi_U, E|_U)} - """ return self._transitions.copy() @@ -518,7 +501,6 @@ def transition(self, triv1, triv2): sage: E.transition(phi_V, phi_U) Transition map from Trivialization (phi_V, E|_V) to Trivialization (phi_U, E|_U) - """ if (triv1, triv2) not in self._transitions: raise TypeError("the transition map from " + @@ -543,7 +525,6 @@ def atlas(self): [Trivialization (phi_U, E|_U), Trivialization (phi_V, E|_V), Trivialization (phi_M, E|_M)] - """ return list(self._atlas) # Make a (shallow) copy @@ -569,7 +550,6 @@ def is_manifestly_trivial(self): Trivialization (phi_M, E|_M) sage: E.is_manifestly_trivial() True - """ return self.base_space() in self._trivial_parts @@ -584,7 +564,7 @@ def section_module(self, domain=None, force_free=False): - ``domain`` -- (default: ``None``) the domain on which the module is defined; if ``None`` the base space is assumed - - ``force_free`` -- (default: ``False``) if set to ``True``, force + - ``force_free`` -- boolean (default: ``False``); if set to ``True``, force the construction of a *free* module (this implies that `E` is trivial) OUTPUT: @@ -655,7 +635,6 @@ def section_module(self, domain=None, force_free=False): manifold RP^1 with values in the real vector bundle E of rank 1 sage: C0_U.an_element().display(phi_U.frame()) 2 (phi_U^*e_1) - """ if domain is None: domain = self._base_space @@ -694,7 +673,6 @@ def fiber(self, point): 3-dimensional topological manifold M sage: E.fiber(p) Fiber of E at Point p on the 3-dimensional topological manifold M - """ return VectorBundleFiber(self, point) @@ -789,7 +767,6 @@ def local_frame(self, *args, **kwargs): For more options, in particular for the choice of symbols and indices, see :class:`~sage.manifolds.local_frame.LocalFrame`. - """ from sage.manifolds.local_frame import LocalFrame # Input processing @@ -864,7 +841,6 @@ def section(self, *comp, **kwargs): sage: s = E.section(name='s'); s Section s on the 2-dimensional topological manifold M with values in the real vector bundle E of rank 2 - """ domain = kwargs.pop('domain', self._base_space) name = kwargs.pop('name', None) @@ -895,7 +871,6 @@ def total_space(self): sage: E = M.vector_bundle(2, 'E') sage: E.total_space() 6-dimensional topological manifold E - """ if self._total_space is None: from sage.manifolds.manifold import Manifold @@ -926,9 +901,10 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, :class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism` describing the automorphism `P` that relates the basis `(e_i)` to the basis `(f_i)` according to `f_i = P(e_i)` - - ``compute_inverse`` (default: ``True``) -- if set to True, the inverse - automorphism is computed and the change from basis `(f_i)` to `(e_i)` - is set to it in the internal dictionary ``self._frame_changes`` + - ``compute_inverse`` -- boolean (default: ``True``); if set to True, + the inverse automorphism is computed and the change from basis + `(f_i)` to `(e_i)` is set to it in the internal dictionary + ``self._frame_changes`` EXAMPLES:: @@ -951,7 +927,6 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, sage: E.change_of_frame(e,f)[e,:] [1 2] [0 3] - """ from sage.tensor.modules.free_module_automorphism import \ FreeModuleAutomorphism @@ -1003,7 +978,6 @@ def change_of_frame(self, frame1, frame2): True sage: a.inverse() == E.change_of_frame(f, e) True - """ if (frame1, frame2) not in self._frame_changes: raise ValueError("the change of frame from {} to {}".format(frame1, frame2) + @@ -1043,7 +1017,6 @@ def changes_of_frame(self): Local frame (E|_M, (f_0,f_1))): Automorphism of the Free module C^0(M;E) of sections on the 3-dimensional topological manifold M with values in the real vector bundle E of rank 2} - """ return self._frame_changes.copy() @@ -1051,9 +1024,7 @@ def frames(self): r""" Return the list of local frames defined on ``self``. - OUTPUT: - - - list of local frames defined on ``self`` + OUTPUT: list of local frames defined on ``self`` EXAMPLES:: @@ -1065,7 +1036,6 @@ def frames(self): sage: E.frames() [Trivialization frame (E|_U, ((phi_U^*e_1),(phi_U^*e_2))), Local frame (E|_V, (e_0,e_1))] - """ return list(self._frames) @@ -1073,9 +1043,7 @@ def coframes(self): r""" Return the list of coframes defined on ``self``. - OUTPUT: - - - list of coframes defined on ``self`` + OUTPUT: list of coframes defined on ``self`` EXAMPLES:: @@ -1087,7 +1055,6 @@ def coframes(self): sage: E.coframes() [Trivialization coframe (E|_U, ((phi_U^*e^1),(phi_U^*e^2))), Local coframe (E|_V, (e^0,e^1))] - """ return list(self._coframes) @@ -1107,7 +1074,6 @@ def default_frame(self): sage: e = E.local_frame('e') sage: E.default_frame() Local frame (E|_M, (e_0,e_1)) - """ return self._def_frame @@ -1131,7 +1097,6 @@ def set_default_frame(self, frame): sage: E.set_default_frame(f) sage: E.default_frame() Local frame (E|_M, (f_0,f_1)) - """ from sage.manifolds.local_frame import LocalFrame if not isinstance(frame, LocalFrame): @@ -1188,7 +1153,6 @@ def set_orientation(self, orientation): sage: E.orientation() [Local frame (E|_U, (e_0,e_1)), Local frame (E|_V, (f_0,f_1))] - """ from .local_frame import LocalFrame if isinstance(orientation, LocalFrame): @@ -1268,7 +1232,6 @@ def orientation(self): sage: E.orientation() [Local frame (E|_U, (e_0,e_1)), Local frame (E|_V, (f_0,f_1))] - """ if not self._orientation: # Trivial case: @@ -1324,7 +1287,6 @@ def has_orientation(self): sage: E.set_orientation([e, f]) sage: E.has_orientation() True - """ return bool(self.orientation()) @@ -1369,7 +1331,6 @@ def irange(self, start=None): sage: next(E.irange()) == M.start_index() True - """ si = self._base_space._sindex imax = self._rank + si diff --git a/src/sage/manifolds/vector_bundle_fiber.py b/src/sage/manifolds/vector_bundle_fiber.py index 19b5c6f6acb..325ac1582b2 100644 --- a/src/sage/manifolds/vector_bundle_fiber.py +++ b/src/sage/manifolds/vector_bundle_fiber.py @@ -21,6 +21,7 @@ from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule from sage.manifolds.vector_bundle_fiber_element import VectorBundleFiberElement + class VectorBundleFiber(FiniteRankFreeModule): r""" Fiber of a given vector bundle at a given point. @@ -156,7 +157,6 @@ class VectorBundleFiber(FiniteRankFreeModule): :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule` for more documentation. - """ Element = VectorBundleFiberElement @@ -173,7 +173,6 @@ def __init__(self, vector_bundle, point): sage: e = E.local_frame('e') sage: Ep = E.fiber(p) sage: TestSuite(Ep).run() - """ if point._manifold is not vector_bundle._base_space: raise ValueError("Point must be an element " @@ -266,7 +265,6 @@ def _repr_(self): sage: E = M.vector_bundle(2, 'E') sage: E.fiber(p)._repr_() 'Fiber of E at Point p on the 3-dimensional topological manifold M' - """ return "Fiber of {} at {}".format(self._vbundle._name, self._point) @@ -284,7 +282,6 @@ def dimension(self): sage: Ep = E.fiber(p) sage: Ep.dim() 2 - """ # The dimension is the rank of self as a free module: return self._rank @@ -308,7 +305,6 @@ def _an_element_(self): manifold M sage: Ep._an_element_().display() e_0 + 2 e_1 - """ resu = self.element_class(self) if self._def_basis is not None: @@ -331,6 +327,5 @@ def base_point(self): Point p on the 2-dimensional topological manifold M sage: p is Ep.base_point() True - """ return self._point diff --git a/src/sage/manifolds/vector_bundle_fiber_element.py b/src/sage/manifolds/vector_bundle_fiber_element.py index 3cb37025ef9..39f18691463 100644 --- a/src/sage/manifolds/vector_bundle_fiber_element.py +++ b/src/sage/manifolds/vector_bundle_fiber_element.py @@ -20,13 +20,14 @@ from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement + class VectorBundleFiberElement(FiniteRankFreeModuleElement): r""" Vector in a fiber of a vector bundle at the given point. INPUT: - - parent -- :class:`~sage.manifolds.vector_bundle_fiber.VectorBundleFiber`; + - ``parent`` -- :class:`~sage.manifolds.vector_bundle_fiber.VectorBundleFiber`; the fiber to which the vector belongs - ``name`` -- (default: ``None``) string; symbol given to the vector - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote @@ -56,7 +57,6 @@ class VectorBundleFiberElement(FiniteRankFreeModuleElement): :class:`~sage.tensor.modules.free_module_element.FiniteRankFreeModuleElement` for more documentation. - """ def __init__(self, parent, name=None, latex_name=None): r""" @@ -75,7 +75,6 @@ def __init__(self, parent, name=None, latex_name=None): topological manifold M sage: v[:] = 5, -3/2 sage: TestSuite(v).run() - """ FiniteRankFreeModuleElement.__init__(self, parent, name=name, latex_name=latex_name) @@ -102,7 +101,6 @@ def _repr_(self): sage: repr(v) # indirect doctest 'Vector v in the fiber of E at Point p on the 2-dimensional topological manifold M' - """ desc = "Vector " if self._name: diff --git a/src/sage/matrix/action.pyx b/src/sage/matrix/action.pyx index 96587b99cbc..732a1312ca1 100644 --- a/src/sage/matrix/action.pyx +++ b/src/sage/matrix/action.pyx @@ -267,7 +267,6 @@ cdef class MatrixMatrixAction(MatrixMulAction): [ 5360 7303] [ 8168 11143] [11056 15077] - """ cdef Matrix A = g cdef Matrix B = s @@ -439,7 +438,7 @@ cdef class MatrixPolymapAction(MatrixMulAction): cpdef _act_(self, mat, f): """ - Call the action + Call the action. INPUT: diff --git a/src/sage/matrix/args.pxd b/src/sage/matrix/args.pxd index 8deb4d434c9..eda2e428801 100644 --- a/src/sage/matrix/args.pxd +++ b/src/sage/matrix/args.pxd @@ -88,7 +88,7 @@ cdef class MatrixArgs: value was previously set, it must remain the same. """ if n < 0: - raise ArithmeticError("number of columns must be non-negative") + raise ArithmeticError("number of columns must be nonnegative") cdef long p = self.ncols if p != -1 and p != n: raise ValueError(f"inconsistent number of columns: should be {p} " @@ -104,7 +104,7 @@ cdef class MatrixArgs: value was previously set, it must remain the same. """ if n < 0: - raise ArithmeticError("number of rows must be non-negative") + raise ArithmeticError("number of rows must be nonnegative") cdef long p = self.nrows if p != -1 and p != n: raise ValueError(f"inconsistent number of rows: should be {p} but got {n}") diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index 4f578440df6..332eaf82df8 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -296,7 +296,7 @@ cdef class MatrixArgs: Test invalid input:: - sage: MatrixArgs(ZZ, 2, 2, entries="abcd").finalized() + sage: MatrixArgs(ZZ, 2, 2, entries='abcd').finalized() Traceback (most recent call last): ... TypeError: unable to convert 'abcd' to a matrix @@ -473,7 +473,7 @@ cdef class MatrixArgs: def __iter__(self): """ - Default iteration (dense with conversion) + Default iteration (dense with conversion). EXAMPLES:: @@ -486,14 +486,14 @@ cdef class MatrixArgs: def iter(self, bint convert=True, bint sparse=False): """ - Iteration over the entries in the matrix + Iteration over the entries in the matrix. INPUT: - - ``convert`` -- If ``True``, the entries are converted to the - base right. If ``False``, the entries are returned as given. + - ``convert`` -- if ``True``, the entries are converted to the + base right; if ``False``, the entries are returned as given - - ``sparse`` -- See OUTPUT below. + - ``sparse`` -- see OUTPUT below OUTPUT: iterator @@ -765,7 +765,7 @@ cdef class MatrixArgs: INPUT: - - ``immutable`` -- boolean; if ``True``, the result will be immutable. + - ``immutable`` -- boolean; if ``True``, the result will be immutable OUTPUT: an element of ``self.space`` @@ -819,8 +819,8 @@ cdef class MatrixArgs: INPUT: - - ``convert`` -- If ``True``, the entries are converted to the base - ring. Otherwise, the entries are returned as given. + - ``convert`` -- if ``True``, the entries are converted to the base + ring; otherwise, the entries are returned as given .. NOTE:: @@ -857,7 +857,7 @@ cdef class MatrixArgs: cdef list L if self.typ == MA_ENTRIES_SEQ_FLAT and not convert: - # Try to re-use existing list + # Try to reuse existing list if type(self.entries) is not list: L = list(self.entries) else: @@ -881,7 +881,7 @@ cdef class MatrixArgs: """ Return the entries of the matrix as a :class:`dict`. - The keys of this :class:`dict` are the non-zero positions ``(i,j)``. The + The keys of this :class:`dict` are the nonzero positions ``(i,j)``. The corresponding value is the entry at that position. Zero values are skipped. If ``convert`` is ``True``, the entries are converted to the base @@ -1500,6 +1500,21 @@ cdef class MatrixArgs: Traceback (most recent call last): ... NameError: name 'a' is not defined + + Check that :issue:`38221` is fixed:: + + sage: # needs sage.groups + sage: G = CyclicPermutationGroup(7) + sage: R = GF(2) + sage: A = G.algebra(R) + sage: matrix(A, 3, 3, A.zero()) + [0 0 0] + [0 0 0] + [0 0 0] + sage: matrix(A, 3, 3, A.one()) + [() 0 0] + [ 0 () 0] + [ 0 0 ()] """ # Check basic Python types. This is very fast, so it doesn't # hurt to do these first. @@ -1524,6 +1539,8 @@ cdef class MatrixArgs: cdef bint is_elt = isinstance(self.entries, Element) if is_elt and isinstance(self.entries, Matrix): return MA_ENTRIES_MATRIX + if is_elt and self.base is not None and self.entries.parent() == self.base: + return MA_ENTRIES_SCALAR t = type(self.entries) try: f = t._matrix_ diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index c3a236b21d3..8567f869511 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -39,9 +39,9 @@ def report(F, title, systems=['sage', 'magma'], **kwds): INPUT: - - ``F`` -- a list of callables used for benchmarking - - ``title`` -- a string describing this report - - ``systems`` -- a list of systems (supported entries are 'sage' and 'magma') + - ``F`` -- list of callables used for benchmarking + - ``title`` -- string describing this report + - ``systems`` -- list of systems (supported entries are 'sage' and 'magma') - ``**kwds`` -- keyword arguments passed to all functions in ``F`` EXAMPLES:: @@ -132,7 +132,7 @@ def nullspace_ZZ(n=200, min=0, max=2**32, system='sage'): - ``n`` -- matrix dimension (default: ``200``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - ``max`` -- maximal value for entries of matrix (default: ``2**32``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -172,7 +172,7 @@ def charpoly_ZZ(n=100, min=0, max=9, system='sage'): - ``n`` -- matrix dimension (default: ``100``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -212,7 +212,7 @@ def rank_ZZ(n=700, min=0, max=9, system='sage'): - ``n`` -- matrix dimension (default: ``700``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -251,7 +251,7 @@ def rank2_ZZ(n=400, min=0, max=2**64, system='sage'): - ``n`` -- matrix dimension (default: ``400``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - ``max`` -- maximal value for entries of matrix (default: ``2**64``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -292,7 +292,7 @@ def smithform_ZZ(n=128, min=0, max=9, system='sage'): - ``n`` -- matrix dimension (default: ``128``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -332,7 +332,7 @@ def matrix_multiply_ZZ(n=300, min=-9, max=9, system='sage', times=1): - ``n`` -- matrix dimension (default: ``300``) - ``min`` -- minimal value for entries of matrix (default: ``-9``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) - ``times`` -- number of experiments (default: ``1``) EXAMPLES:: @@ -377,7 +377,7 @@ def matrix_add_ZZ(n=200, min=-9, max=9, system='sage', times=50): - ``n`` -- matrix dimension (default: ``200``) - ``min`` -- minimal value for entries of matrix (default: ``-9``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) - ``times`` -- number of experiments (default: ``50``) EXAMPLES:: @@ -423,7 +423,7 @@ def matrix_add_ZZ_2(n=200, bits=16, system='sage', times=50): - ``n`` -- matrix dimension (default: ``200``) - ``bits`` -- bitsize of entries - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) - ``times`` -- number of experiments (default: ``50``) EXAMPLES:: @@ -446,7 +446,7 @@ def det_ZZ(n=200, min=1, max=100, system='sage'): - ``n`` -- matrix dimension (default: ``200``) - ``min`` -- minimal value for entries of matrix (default: ``1``) - ``max`` -- maximal value for entries of matrix (default: ``100``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -486,7 +486,7 @@ def det_QQ(n=300, num_bound=10, den_bound=10, system='sage'): - ``n`` -- matrix dimension (default: ``200``) - ``num_bound`` -- numerator bound, inclusive (default: ``10``) - ``den_bound`` -- denominator bound, inclusive (default: ``10``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -529,7 +529,7 @@ def vecmat_ZZ(n=300, min=-9, max=9, system='sage', times=200): - ``n`` -- matrix dimension (default: ``300``) - ``min`` -- minimal value for entries of matrix (default: ``-9``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) - ``times`` -- number of runs (default: ``200``) EXAMPLES:: @@ -570,7 +570,7 @@ def vecmat_ZZ(n=300, min=-9, max=9, system='sage', times=200): def report_GF(p=16411, **kwds): """ - Runs all the reports for finite field matrix operations, for + Run all the reports for finite field matrix operations, for prime p=16411. INPUT: @@ -578,7 +578,7 @@ def report_GF(p=16411, **kwds): - ``p`` -- ignored - ``**kwds`` -- passed through to :func:`report` - .. note:: + .. NOTE:: right now, even though p is an input, it is being ignored! If you need to check the performance for other primes, you can @@ -611,7 +611,7 @@ def nullspace_GF(n=300, p=16411, system='sage'): - ``n`` -- matrix dimension (default: 300) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) EXAMPLES:: @@ -651,7 +651,7 @@ def charpoly_GF(n=100, p=16411, system='sage'): - ``n`` -- matrix dimension (default: 100) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) EXAMPLES:: @@ -687,7 +687,7 @@ def matrix_add_GF(n=1000, p=16411, system='sage',times=100): - ``n`` -- matrix dimension (default: 300) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) - ``times`` -- number of experiments (default: ``100``) EXAMPLES:: @@ -733,7 +733,7 @@ def matrix_multiply_GF(n=100, p=16411, system='sage', times=3): - ``n`` -- matrix dimension (default: 100) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) - ``times`` -- number of experiments (default: ``3``) EXAMPLES:: @@ -777,7 +777,7 @@ def rank_GF(n=500, p=16411, system='sage'): - ``n`` -- matrix dimension (default: 300) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) EXAMPLES:: @@ -814,7 +814,7 @@ def rank2_GF(n=500, p=16411, system='sage'): - ``n`` -- matrix dimension (default: 300) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) EXAMPLES:: @@ -852,7 +852,7 @@ def det_GF(n=400, p=16411 , system='sage'): - ``n`` -- matrix dimension (default: 300) - ``p`` -- prime number (default: ``16411``) - - ``system`` -- either 'magma' or 'sage' (default: 'sage') + - ``system`` -- either 'magma' or 'sage' (default: ``'sage'``) EXAMPLES:: @@ -887,7 +887,7 @@ def det_GF(n=400, p=16411 , system='sage'): def hilbert_matrix(n): """ - Returns the Hilbert matrix of size n over rationals. + Return the Hilbert matrix of size n over rationals. EXAMPLES:: @@ -915,7 +915,7 @@ def echelon_QQ(n=100, min=0, max=9, system='sage'): - ``n`` -- matrix dimension (default: ``300``) - ``min`` -- minimal value for entries of matrix (default: ``-9``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -955,7 +955,7 @@ def inverse_QQ(n=100, min=0, max=9, system='sage'): - ``n`` -- matrix dimension (default: ``300``) - ``min`` -- minimal value for entries of matrix (default: ``-9``) - ``max`` -- maximal value for entries of matrix (default: ``9``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -995,7 +995,7 @@ def matrix_multiply_QQ(n=100, bnd=2, system='sage', times=1): - ``n`` -- matrix dimension (default: ``300``) - ``bnd`` -- numerator and denominator bound (default: ``bnd``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) - ``times`` -- number of experiments (default: ``1``) EXAMPLES:: @@ -1034,13 +1034,13 @@ def matrix_multiply_QQ(n=100, bnd=2, system='sage', times=1): # Determinant of Hilbert matrix def det_hilbert_QQ(n=80, system='sage'): """ - Runs the benchmark for calculating the determinant of the hilbert + Run the benchmark for calculating the determinant of the hilbert matrix over rationals of dimension n. INPUT: - ``n`` -- matrix dimension (default: ``300``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -1069,13 +1069,13 @@ def det_hilbert_QQ(n=80, system='sage'): # inverse of Hilbert matrix def invert_hilbert_QQ(n=40, system='sage'): """ - Runs the benchmark for calculating the inverse of the hilbert + Run the benchmark for calculating the inverse of the hilbert matrix over rationals of dimension n. INPUT: - ``n`` -- matrix dimension (default: ``300``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -1110,7 +1110,7 @@ def MatrixVector_QQ(n=1000,h=100,system='sage',times=1): - ``n`` -- matrix dimension (default: ``300``) - ``h`` -- numerator and denominator bound (default: ``bnd``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) - ``times`` -- number of experiments (default: ``1``) EXAMPLES:: @@ -1167,7 +1167,7 @@ def nullspace_RR(n=300, min=0, max=10, system='sage'): - ``n`` -- matrix dimension (default: ``300``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - ``max`` -- maximal value for entries of matrix (default: ``10``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: @@ -1207,8 +1207,8 @@ def nullspace_RDF(n=300, min=0, max=10, system='sage'): - ``n`` -- matrix dimension (default: ``300``) - ``min`` -- minimal value for entries of matrix (default: ``0``) - - ``max`` -- maximal value for entries of matrix (default: `10``) - - ``system`` -- either 'sage' or 'magma' (default: 'sage') + - ``max`` -- maximal value for entries of matrix (default: ``10``) + - ``system`` -- either ``'sage'`` or ``'magma'`` (default: ``'sage'``) EXAMPLES:: diff --git a/src/sage/matrix/berlekamp_massey.py b/src/sage/matrix/berlekamp_massey.py index a6fe70c50e6..e9284f3c08e 100644 --- a/src/sage/matrix/berlekamp_massey.py +++ b/src/sage/matrix/berlekamp_massey.py @@ -37,7 +37,7 @@ def berlekamp_massey(a): INPUT: - - ``a`` -- a list of even length of elements of a field (or domain) + - ``a`` -- list of even length of elements of a field (or domain) OUTPUT: diff --git a/src/sage/matrix/change_ring.pyx b/src/sage/matrix/change_ring.pyx index f942b753275..e5b5ee5c38f 100644 --- a/src/sage/matrix/change_ring.pyx +++ b/src/sage/matrix/change_ring.pyx @@ -15,10 +15,10 @@ def integer_to_real_double_dense(Matrix_integer_dense A): real double entries. INPUT: - A -- a dense matrix over the integers - OUTPUT: - -- a dense real double matrix + - ``A`` -- a dense matrix over the integers + + OUTPUT: a dense real double matrix EXAMPLES:: diff --git a/src/sage/matrix/compute_J_ideal.py b/src/sage/matrix/compute_J_ideal.py index f7005c04d31..4155745e856 100644 --- a/src/sage/matrix/compute_J_ideal.py +++ b/src/sage/matrix/compute_J_ideal.py @@ -131,7 +131,7 @@ def lifting(p, t, A, G): - ``p`` -- a prime element of some principal ideal domain `D` - - ``t`` -- a non-negative integer + - ``t`` -- nonnegative integer - ``A`` -- a `c\times d` matrix over `D[X]` @@ -243,7 +243,7 @@ def p_part(f, p): OUTPUT: A polynomial `g` such that `\deg g \le \deg f` and - all non-zero coefficients of `f - p g` are not divisible by `p`. + all nonzero coefficients of `f - p g` are not divisible by `p`. EXAMPLES:: @@ -262,7 +262,6 @@ def p_part(f, p): sage: g = p_part(X+1, 2) sage: g.parent() Univariate Polynomial Ring in X over Integer Ring - """ DX = f.parent() (X,) = DX.gens() @@ -359,9 +358,9 @@ def find_monic_replacements(self, p, t, pt_generators, prev_nu): - ``p`` -- a prime element of `D` - - ``t`` -- a non-negative integer + - ``t`` -- nonnegative integer - - ``pt_generators`` -- a list `(g_1, \ldots, g_s)` of polynomials in + - ``pt_generators`` -- list `(g_1, \ldots, g_s)` of polynomials in `D[X]` such that `N_{(p^t)}(B) = (g_1, \ldots, g_s) + pN_{(p^{t-1})}(B)` - ``prev_nu`` -- a `(p^{t-1})`-minimal polynomial of `B` @@ -438,9 +437,9 @@ def current_nu(self, p, t, pt_generators, prev_nu): - ``p`` -- a prime element of `D` - - ``t`` -- a positive integer + - ``t`` -- positive integer - - ``pt_generators`` -- a list `(g_1, \ldots, g_s)` of polynomials in + - ``pt_generators`` -- list `(g_1, \ldots, g_s)` of polynomials in `D[X]` such that `N_{(p^t)}(B) = (g_1, \ldots, g_s) + pN_{(p^{t-1})}(B)` - ``prev_nu`` -- a `(p^{t-1})`-minimal polynomial of `B` @@ -523,7 +522,7 @@ def mccoy_column(self, p, t, nu): - ``p`` -- a prime element in `D` - - ``t`` -- a positive integer + - ``t`` -- positive integer - ``nu`` -- a `(p^t)`-minimal polynomial of `B` @@ -557,7 +556,6 @@ def mccoy_column(self, p, t, nu): Traceback (most recent call last): ... ValueError: x^2 + x not in (2^2)-ideal - """ if not (nu(self._B) % p**t).is_zero(): raise ValueError( @@ -590,7 +588,7 @@ def p_minimal_polynomials(self, p, s_max=None): - ``p`` -- a prime in `D` - - ``s_max`` -- a positive integer (default: ``None``); if set, only + - ``s_max`` -- positive integer (default: ``None``); if set, only `(p^s)`-minimal polynomials for ``s <= s_max`` are computed (see below for details) @@ -813,9 +811,7 @@ def null_ideal(self, b=0): - ``b`` -- an element of `D` (default: 0) - OUTPUT: - - An ideal in `D[X]`. + OUTPUT: an ideal in `D[X]` EXAMPLES:: @@ -874,9 +870,7 @@ def prime_candidates(self): Determine those primes `p` where `\mu_B` might not be a `(p)`-minimal polynomial. - OUTPUT: - - A list of primes. + OUTPUT: list of primes EXAMPLES:: diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index bf19830a0ae..de060a11425 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -68,7 +68,7 @@ def matrix(*args, **kwds): - ``ncols`` -- the number of columns in the matrix, or a finite or enumerated family of arbitrary objects that index the columns of the matrix - - ``entries`` -- see examples below. + - ``entries`` -- see examples below If any of ``nrows``, ``ncols``, ``row_keys``, ``column_keys`` is given as keyword argument, then none of these may be given as @@ -76,7 +76,7 @@ def matrix(*args, **kwds): Keyword-only arguments: - - ``sparse`` -- (boolean) create a sparse matrix. This defaults to + - ``sparse`` -- boolean; create a sparse matrix. This defaults to ``True`` when the entries are given as a dictionary, otherwise defaults to ``False``. @@ -90,10 +90,9 @@ def matrix(*args, **kwds): matrix. This determines ``base_ring``, ``nrows``, ``row_keys``, ``ncols``, ``column_keys``, and ``sparse``. - - ``immutable`` -- (boolean) make the matrix immutable. By default, + - ``immutable`` -- boolean; make the matrix immutable. By default, the output matrix is mutable. - OUTPUT: a matrix or, more generally, a homomorphism between free modules diff --git a/src/sage/matrix/docs.py b/src/sage/matrix/docs.py index 3f70f122489..274796b1694 100644 --- a/src/sage/matrix/docs.py +++ b/src/sage/matrix/docs.py @@ -370,7 +370,7 @@ class derived from Matrix). They can be either sparse or dense, and * __dealloc__ -- use sig_free (only needed if allocate memory) * set_unsafe(self, size_t i, size_t j, x) -- doesn't do bounds or any other checks; assumes x is in self._base_ring * get_unsafe(self, size_t i, size_t j) -- doesn't do checks - * __richcmp__ -- always the same (I don't know why its needed -- bug in PYREX). + * __richcmp__ -- always the same (I don't know why its needed -- bug in PYREX) Note that the __init__ function must construct the all zero matrix if ``entries == None``. @@ -415,7 +415,7 @@ class derived from Matrix). They can be either sparse or dense, and * Other functions, e.g., transpose, for which knowing the specific representation can be helpful. - .. note:: + .. NOTE:: - For caching, use self.fetch and self.cache. diff --git a/src/sage/matrix/echelon_matrix.pyx b/src/sage/matrix/echelon_matrix.pyx index c075220152c..526900e2a72 100644 --- a/src/sage/matrix/echelon_matrix.pyx +++ b/src/sage/matrix/echelon_matrix.pyx @@ -25,13 +25,13 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, - ``n`` -- number of columns (or the dimension of the ambient space) - - ``sparse`` -- boolean (default is ``False``) + - ``sparse`` -- boolean (default: ``False``) - - ``copy`` -- boolean. If set to ``False`` then iterator yields the same matrix - over and over (but with different entries). Default is ``True`` which is - safer but might be slower. + - ``copy`` -- boolean (default: ``True``); if set to ``False`` then + iterator yields the same matrix over and over (but with different + entries). Default is ``True`` which is safer but might be slower. - - ``set_immutable`` -- boolean. If set to ``True`` then the output matrices + - ``set_immutable`` -- boolean; if set to ``True`` then the output matrices are immutable. This option automatically turns ``copy`` into ``True``. diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 83edc74c16d..c0d9f93e804 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -238,7 +238,7 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``copy`` -- (default: ``True``) make a copy of the ``dict`` + - ``copy`` -- boolean (default: ``True``); make a copy of the ``dict`` corresponding to ``self`` If ``copy=True``, then is safe to change the returned dictionary. @@ -391,7 +391,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: m=Matrix(QQ,2,range(0,4)) sage: m._get_cache() {} - """ if self._cache is None: self._cache = {} @@ -404,7 +403,7 @@ cdef class Matrix(sage.structure.element.Matrix): cdef check_bounds(self, Py_ssize_t i, Py_ssize_t j): """ This function gets called when you're about to access the i,j entry - of this matrix. If i, j are out of range, an :class:`IndexError` is + of this matrix. If i, j are out of range, an :exc:`IndexError` is raised. """ if i < 0 or i >= self._nrows or j < 0 or j >= self._ncols: @@ -414,10 +413,10 @@ cdef class Matrix(sage.structure.element.Matrix): """ This function gets called when you're about to change this matrix. - If self is immutable, a :class:`ValueError` is raised, since you should + If ``self`` is immutable, a :exc:`ValueError` is raised, since you should never change a mutable matrix. - If self is mutable, the cache of results about self is deleted. + If ``self`` is mutable, the cache of results about ``self`` is deleted. """ if self._is_immutable: raise ValueError("matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).") @@ -427,13 +426,13 @@ cdef class Matrix(sage.structure.element.Matrix): cdef check_bounds_and_mutability(self, Py_ssize_t i, Py_ssize_t j): """ This function gets called when you're about to set the i,j entry of - this matrix. If i or j is out of range, an :class:`IndexError` + this matrix. If i or j is out of range, an :exc:`IndexError` exception is raised. - If self is immutable, a :class:`ValueError` is raised, since you should + If ``self`` is immutable, a :exc:`ValueError` is raised, since you should never change a mutable matrix. - If self is mutable, the cache of results about self is deleted. + If ``self`` is mutable, the cache of results about ``self`` is deleted. """ if self._is_immutable: raise ValueError("matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).") @@ -500,7 +499,7 @@ cdef class Matrix(sage.structure.element.Matrix): def is_immutable(self): """ - Return True if this matrix is immutable. + Return ``True`` if this matrix is immutable. See the documentation for self.set_immutable for more details about mutability. @@ -518,7 +517,7 @@ cdef class Matrix(sage.structure.element.Matrix): def is_mutable(self): """ - Return True if this matrix is mutable. + Return ``True`` if this matrix is mutable. See the documentation for self.set_immutable for more details about mutability. @@ -625,7 +624,7 @@ cdef class Matrix(sage.structure.element.Matrix): def __iter__(self): """ - Return an iterator for the rows of self. + Return an iterator for the rows of ``self``. EXAMPLES:: @@ -637,7 +636,7 @@ cdef class Matrix(sage.structure.element.Matrix): def __getitem__(self, key): """ - Return element, row, or slice of self. + Return element, row, or slice of ``self``. INPUT: @@ -1094,7 +1093,7 @@ cdef class Matrix(sage.structure.element.Matrix): - ``key`` -- any legal indexing (i.e., such that self[key] works) - - ``value`` -- values that are used to set the elements indicated by key. + - ``value`` -- values that are used to set the elements indicated by key EXAMPLES:: @@ -1581,7 +1580,7 @@ cdef class Matrix(sage.structure.element.Matrix): cdef _coerce_element(self, x): """ - Return coercion of x into the base ring of self. + Return coercion of x into the base ring of ``self``. """ if isinstance(x, Element) and ( x)._parent is self._base_ring: return x @@ -1616,7 +1615,7 @@ cdef class Matrix(sage.structure.element.Matrix): def _test_reduce(self, **options): """ - Checks that the pickling function works. + Check that the pickling function works. EXAMPLES:: @@ -1647,8 +1646,8 @@ cdef class Matrix(sage.structure.element.Matrix): Return the matrix obtained by coercing the entries of this matrix into the given ring. - Always returns a copy (unless self is immutable, in which case - returns self). + Always returns a copy (unless ``self`` is immutable, in which case + returns ``self``). EXAMPLES:: @@ -1696,7 +1695,7 @@ cdef class Matrix(sage.structure.element.Matrix): def _test_change_ring(self, **options): """ - Checks that :meth:`change_ring` works. + Check that :meth:`change_ring` works. EXAMPLES:: @@ -1765,7 +1764,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: [A]*2 [100 x 100 dense matrix over Integer Ring, 100 x 100 dense matrix over Integer Ring] - """ from sage.matrix.constructor import options if self._nrows <= options.max_rows() and self._ncols <= options.max_cols(): @@ -1820,8 +1818,8 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``rep_mapping`` -- a dictionary or callable used to override - the usual representation of elements. + - ``rep_mapping`` -- dictionary or callable used to override + the usual representation of elements If ``rep_mapping`` is a dictionary then keys should be elements of the base ring and values the desired string @@ -1848,11 +1846,11 @@ cdef class Matrix(sage.structure.element.Matrix): use the value of ``minus_one`` as the representation of the negative of the one element. - - ``unicode`` -- boolean (default: ``False``). - Whether to use Unicode symbols instead of ASCII symbols - for brackets and subdivision lines. + - ``unicode`` -- boolean (default: ``False``); + whether to use Unicode symbols instead of ASCII symbols + for brackets and subdivision lines - - ``shape`` -- one of ``"square"`` or ``"round"`` (default: ``None``). + - ``shape`` -- one of ``'square'`` or ``'round'`` (default: ``None``). Switches between round and square brackets. The default depends on the setting of the ``unicode`` keyword argument. For Unicode symbols, the default is round brackets @@ -1886,7 +1884,7 @@ cdef class Matrix(sage.structure.element.Matrix): '[ 1 0]\n[ 2 -1]' sage: M.str(plus_one='+',minus_one='-',zero='.') '[+ .]\n[2 -]' - sage: M.str({1:"not this one",2:"II"},minus_one="*",plus_one="I") + sage: M.str({1:"not this one",2:"II"},minus_one='*',plus_one='I') '[ I 0]\n[II *]' sage: def print_entry(x): @@ -1908,7 +1906,7 @@ cdef class Matrix(sage.structure.element.Matrix): ⎜4 5│6⎟ ⎝7 8│9⎠ sage: M.subdivide([0,1,1,3], [0,2,3,3]) - sage: print(M.str(unicode=True, shape="square")) + sage: print(M.str(unicode=True, shape='square')) ⎡┼───┼─┼┼⎤ ⎢│1 2│3││⎥ ⎢┼───┼─┼┼⎥ @@ -1974,7 +1972,7 @@ cdef class Matrix(sage.structure.element.Matrix): sage: K = (A - e).kernel() sage: P = K.basis_matrix() sage: P.str() - '[ 1.000000000000000? + 0.?e-17*I -2.116651487479748? + 0.0255565807096352?*I -0.2585224251020429? + 0.288602340904754?*I -0.4847545623533090? - 1.871890760086142?*I]' + '[ 1.000000000000000? + 0.?e-17*I -2.116651487479748? + 0.0255565807096352?*I -0.2585224251020429? + 0.2886023409047535?*I -0.4847545623533090? - 1.871890760086142?*I]' Use single-row delimiters where appropriate:: @@ -2439,15 +2437,13 @@ cdef class Matrix(sage.structure.element.Matrix): def act_on_polynomial(self, f): r""" - Return the polynomial f(self\*x). + Return the polynomial ``f(self*x)``. INPUT: - - ``self`` -- an nxn matrix - - - ``f`` -- a polynomial in n variables x=(x1,...,xn) + - ``self`` -- an nxn matrix - OUTPUT: The polynomial f(self\*x). + - ``f`` -- a polynomial in n variables x=(x1,...,xn) EXAMPLES:: @@ -2577,7 +2573,7 @@ cdef class Matrix(sage.structure.element.Matrix): def swap_columns(self, Py_ssize_t c1, Py_ssize_t c2): """ - Swap columns c1 and c2 of self. + Swap columns c1 and c2 of ``self``. EXAMPLES: We create a rational matrix:: @@ -2664,7 +2660,7 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``permutation`` -- a ``PermutationGroupElement``. + - ``permutation`` -- a ``PermutationGroupElement`` EXAMPLES: We create a matrix:: @@ -2691,7 +2687,6 @@ cdef class Matrix(sage.structure.element.Matrix): [0 3 0 0 0] [0 0 0 0 4] [0 0 0 5 0] - """ self.check_mutability() for cycle in permutation.cycle_tuples(): @@ -2712,11 +2707,9 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``permutation``, a ``PermutationGroupElement`` - - OUTPUT: + - ``permutation`` -- a ``PermutationGroupElement`` - - A matrix. + OUTPUT: a matrix EXAMPLES: We create some matrix:: @@ -2762,7 +2755,7 @@ cdef class Matrix(sage.structure.element.Matrix): def swap_rows(self, r1, r2): """ - Swap rows r1 and r2 of self. + Swap rows r1 and r2 of ``self``. EXAMPLES: We create a rational matrix:: @@ -2897,9 +2890,7 @@ cdef class Matrix(sage.structure.element.Matrix): - ``permutation`` -- a ``PermutationGroupElement`` - OUTPUT: - - - A matrix. + OUTPUT: a matrix EXAMPLES: We create a matrix:: @@ -2956,9 +2947,7 @@ cdef class Matrix(sage.structure.element.Matrix): - ``row_permutation`` -- a ``PermutationGroupElement`` - ``column_permutation`` -- a ``PermutationGroupElement`` - OUTPUT: - - - A matrix. + OUTPUT: a matrix EXAMPLES: We create a matrix:: @@ -3002,9 +2991,7 @@ cdef class Matrix(sage.structure.element.Matrix): - ``row_permutation`` -- a ``PermutationGroupElement`` - ``column_permutation`` -- a ``PermutationGroupElement`` - OUTPUT: - - - A matrix. + OUTPUT: a matrix EXAMPLES: We create a matrix:: @@ -3204,18 +3191,16 @@ cdef class Matrix(sage.structure.element.Matrix): def rescale_row(self, Py_ssize_t i, s, Py_ssize_t start_col=0): """ - Replace i-th row of self by s times i-th row of self. + Replace `i`-th row of ``self`` by `s` times `i`-th row of ``self``. INPUT: + - ``i`` -- `i`-th row - - ``i`` -- ith row - - - ``s`` -- scalar - - - ``start_col`` -- only rescale entries at this column - and to the right + - ``s`` -- scalar + - ``start_col`` -- only rescale entries at this column + and to the right EXAMPLES: We rescale the second row of a matrix over the rational numbers:: @@ -3277,7 +3262,7 @@ cdef class Matrix(sage.structure.element.Matrix): def with_rescaled_row(self, Py_ssize_t i, s, Py_ssize_t start_col=0): """ - Replaces i-th row of self by s times i-th row of self, returning + Replace `i`-th row of ``self`` by s times `i`-th row of self, returning new matrix. EXAMPLES: We rescale the second row of a matrix over the integers:: @@ -3323,18 +3308,16 @@ cdef class Matrix(sage.structure.element.Matrix): def rescale_col(self, Py_ssize_t i, s, Py_ssize_t start_row=0): """ - Replace i-th col of self by s times i-th col of self. + Replace `i`-th col of ``self`` by `s` times `i`-th col of ``self``. INPUT: + - ``i`` -- `i`-th column - - ``i`` -- ith column - - - ``s`` -- scalar - - - ``start_row`` -- only rescale entries at this row - and lower + - ``s`` -- scalar + - ``start_row`` -- only rescale entries at this row + and lower EXAMPLES: We rescale the last column of a matrix over the rational numbers:: @@ -3392,7 +3375,7 @@ cdef class Matrix(sage.structure.element.Matrix): def with_rescaled_col(self, Py_ssize_t i, s, Py_ssize_t start_row=0): """ - Replaces i-th col of self by s times i-th col of self, returning + Replaces `i`-th col of ``self`` by `s` times `i`-th col of self, returning new matrix. EXAMPLES: We rescale the last column of a matrix over the @@ -3596,23 +3579,21 @@ cdef class Matrix(sage.structure.element.Matrix): Py_ssize_t r, cols, cols_index=None): """ - Set row i of self to -(row r of A), but where we only take the + Set row i of ``self`` to -(row r of A), but where we only take the given column positions in that row of A. We do not zero out the - other entries of self's row i either. + other entries of ``self``'s row i either. INPUT: + - ``i`` -- integer, index into the rows of self - - ``i`` -- integer, index into the rows of self - - - ``A`` -- a matrix + - ``A`` -- a matrix - - ``r`` -- integer, index into rows of A + - ``r`` -- integer, index into rows of A - - ``cols`` -- a *sorted* list of integers. - - - ``(cols_index`` -- ignored) + - ``cols`` -- a *sorted* list of integers + - ``(cols_index`` -- ignored) EXAMPLES:: @@ -3624,14 +3605,14 @@ cdef class Matrix(sage.structure.element.Matrix): [-4 -5 2] [ 3 4 5] """ - self.check_row_bounds_and_mutability(i,i) + self.check_row_bounds_and_mutability(i, i) if r < 0 or r >= A.nrows(): raise IndexError("invalid row") # this function exists just because it is useful for modular symbols presentations. cdef Py_ssize_t l l = 0 for k in cols: - self.set_unsafe(i,l,-A.get_unsafe(r,k)) #self[i,l] = -A[r,k] + self.set_unsafe(i, l, -A.get_unsafe(r, k)) # self[i,l] = -A[r,k] l += 1 def reverse_rows_and_columns(self): @@ -3715,7 +3696,7 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``k`` -- integer at which row/column ``self`` is mutated. + - ``k`` -- integer at which row/column ``self`` is mutated EXAMPLES: @@ -3790,17 +3771,15 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``d`` -- dictionary modelling partial entries of a diagonal matrix. - - - ``k`` -- integer for which row and column of self should be tested with the dictionary d. + - ``d`` -- dictionary modelling partial entries of a diagonal matrix - - ``sign`` -- `\pm 1`, depending on symmetric or skew-symmetric is tested. + - ``k`` -- integer for which row and column of ``self`` should be tested with the dictionary d - - ``positive`` -- if True, only positive entries for the values of the dictionary are allowed. + - ``sign`` -- `\pm 1`, depending on symmetric or skew-symmetric is tested - OUTPUT: + - ``positive`` -- if ``True``, only positive entries for the values of the dictionary are allowed - - ``L`` -- list of new keys in d + OUTPUT: ``L`` -- list of new keys in d EXAMPLES:: @@ -3833,20 +3812,30 @@ cdef class Matrix(sage.structure.element.Matrix): def _check_symmetrizability(self, return_diag=False, skew=False, positive=True): r""" - This function takes a square matrix over an *ordered integral domain* and checks if it is (skew-)symmetrizable. - A matrix `B` is (skew-)symmetrizable iff there exists an invertible diagonal matrix `D` such that `DB` is (skew-)symmetric. + This function takes a square matrix over an *ordered integral domain* + and checks if it is (skew-)symmetrizable. + + A matrix `B` is (skew-)symmetrizable iff there exists an invertible + diagonal matrix `D` such that `DB` is (skew-)symmetric. INPUT: - - ``return_diag`` -- bool(default: ``False``) if True and ``self`` is (skew)-symmetrizable the diagonal entries of the matrix `D` are returned. - - ``skew`` -- bool(default: ``False``) if True, (skew-)symmetrizability is checked. - - ``positive`` -- bool(default: ``True``) if True, the condition that `D` has positive entries is added. + - ``return_diag`` -- boolean (default: ``False``); if ``True`` and + ``self`` is (skew)-symmetrizable the diagonal entries of the matrix + `D` are returned + - ``skew`` -- boolean (default: ``False``); if ``True``, + (skew-)symmetrizability is checked + - ``positive`` -- boolean (default: ``True``); if ``True``, the + condition that `D` has positive entries is added OUTPUT: - - True -- if ``self`` is (skew-)symmetrizable and ``return_diag`` is False - - the diagonal entries of the matrix `D` such that `DB` is (skew-)symmetric -- iff ``self`` is (skew-)symmetrizable and ``return_diag`` is True - - False -- iff ``self`` is not (skew-)symmetrizable + - ``True`` -- if ``self`` is (skew-)symmetrizable and ``return_diag`` + is ``False`` + - the diagonal entries of the matrix `D` such that `DB` is + (skew-)symmetric -- iff ``self`` is (skew-)symmetrizable and + ``return_diag`` is ``True`` + - ``False`` -- iff ``self`` is not (skew-)symmetrizable EXAMPLES:: @@ -3905,8 +3894,8 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``v`` -- a list of scalars. The length can be less than - the number of rows of ``self`` but not greater. + - ``v`` -- a list of scalars. The length can be less than + the number of rows of ``self`` but not greater. OUTPUT: @@ -3982,8 +3971,8 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``v`` -- a list of scalars. The length can be less than - the number of columns of ``self`` but not greater. + - ``v`` -- a list of scalars. The length can be less than + the number of columns of ``self`` but not greater. OUTPUT: @@ -4075,7 +4064,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: m = Matrix(QQ, 1, (2,)) sage: m.is_symmetric() True - """ if self._ncols != self._nrows: return False # could be bigger than an int on a 64-bit platform, this @@ -4098,8 +4086,8 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``skew`` -- boolean (default: ``False``); Set to ``True`` to - check if the matrix is skew-Hermitian instead of Hermitian. + - ``skew`` -- boolean (default: ``False``); set to ``True`` to + check if the matrix is skew-Hermitian instead of Hermitian - ``tolerance`` -- a real number; the maximum difference we'll tolerate between entries of the given matrix and its conjugate- @@ -4199,7 +4187,7 @@ cdef class Matrix(sage.structure.element.Matrix): # The dense algorithm checks all of the on-or-below-diagonal # entries, of which there are (n^2 + n)/2. If the matrix # is sparse, however, we can get away with checking only - # the non-zero positions. This will be faster if the matrix + # the nonzero positions. This will be faster if the matrix # is truly sparse (if there are not so many of those positions) # even after taking numerical issues into account. # @@ -4469,21 +4457,29 @@ cdef class Matrix(sage.structure.element.Matrix): def is_symmetrizable(self, return_diag=False, positive=True): r""" - This function takes a square matrix over an *ordered integral domain* and checks if it is symmetrizable. - A matrix `B` is symmetrizable iff there exists an invertible diagonal matrix `D` such that `DB` is symmetric. + This function takes a square matrix over an *ordered integral domain* + and checks if it is symmetrizable. + + A matrix `B` is symmetrizable iff there exists an invertible diagonal + matrix `D` such that `DB` is symmetric. .. warning:: Expects ``self`` to be a matrix over an *ordered integral domain*. INPUT: - - ``return_diag`` -- bool(default: ``False``) if True and ``self`` is symmetrizable the diagonal entries of the matrix `D` are returned. - - ``positive`` -- bool(default: ``True``) if True, the condition that `D` has positive entries is added. + - ``return_diag`` -- boolean (default: ``False``); if ``True`` and + ``self`` is symmetrizable the diagonal entries of the matrix `D` are + returned + - ``positive`` -- boolean (default: ``True``); if ``True``, the + condition that `D` has positive entries is added OUTPUT: - - True -- if ``self`` is symmetrizable and ``return_diag`` is False - - the diagonal entries of a matrix `D` such that `DB` is symmetric -- iff ``self`` is symmetrizable and ``return_diag`` is True - - False -- iff ``self`` is not symmetrizable + - ``True`` -- if ``self`` is symmetrizable and ``return_diag`` is + ``False`` + - the diagonal entries of a matrix `D` such that `DB` is symmetric -- + iff ``self`` is symmetrizable and ``return_diag`` is ``True`` + - ``False`` -- iff ``self`` is not symmetrizable EXAMPLES:: @@ -4512,21 +4508,29 @@ cdef class Matrix(sage.structure.element.Matrix): def is_skew_symmetrizable(self, return_diag=False, positive=True): r""" - This function takes a square matrix over an *ordered integral domain* and checks if it is skew-symmetrizable. - A matrix `B` is skew-symmetrizable iff there exists an invertible diagonal matrix `D` such that `DB` is skew-symmetric. + This function takes a square matrix over an *ordered integral domain* + and checks if it is skew-symmetrizable. + A matrix `B` is skew-symmetrizable iff there exists an invertible + diagonal matrix `D` such that `DB` is skew-symmetric. .. warning:: Expects ``self`` to be a matrix over an *ordered integral domain*. INPUT: - - ``return_diag`` -- bool(default: ``False``) if True and ``self`` is skew-symmetrizable the diagonal entries of the matrix `D` are returned. - - ``positive`` -- bool(default: ``True``) if True, the condition that `D` has positive entries is added. + - ``return_diag`` -- boolean (default: ``False``); if ``True`` and + ``self`` is skew-symmetrizable the diagonal entries of the matrix `D` + are returned + - ``positive`` -- boolean (default: ``True``); if ``True``, the + condition that `D` has positive entries is added OUTPUT: - - True -- if ``self`` is skew-symmetrizable and ``return_diag`` is False - - the diagonal entries of a matrix `D` such that `DB` is skew-symmetric -- iff ``self`` is skew-symmetrizable and ``return_diag`` is True - - False -- iff ``self`` is not skew-symmetrizable + - ``True`` -- if ``self`` is skew-symmetrizable and ``return_diag`` is + ``False`` + - the diagonal entries of a matrix `D` such that `DB` is + skew-symmetric -- iff ``self`` is skew-symmetrizable and ``return_diag`` + is ``True`` + - ``False`` -- iff ``self`` is not skew-symmetrizable EXAMPLES:: @@ -4563,7 +4567,7 @@ cdef class Matrix(sage.structure.element.Matrix): def is_dense(self): """ - Return True if this is a dense matrix. + Return ``True`` if this is a dense matrix. In Sage, being dense is a property of the underlying representation, not the number of nonzero entries. @@ -4579,7 +4583,7 @@ cdef class Matrix(sage.structure.element.Matrix): def is_sparse(self): """ - Return True if this is a sparse matrix. + Return ``True`` if this is a sparse matrix. In Sage, being sparse is a property of the underlying representation, not the number of nonzero entries. @@ -4595,7 +4599,7 @@ cdef class Matrix(sage.structure.element.Matrix): def is_square(self): """ - Return True precisely if this matrix is square, i.e., has the same + Return ``True`` precisely if this matrix is square, i.e., has the same number of rows and columns. EXAMPLES:: @@ -4609,7 +4613,7 @@ cdef class Matrix(sage.structure.element.Matrix): def is_invertible(self): r""" - Return True if this matrix is invertible. + Return ``True`` if this matrix is invertible. EXAMPLES: The following matrix is invertible over `\QQ` but not over `\ZZ`. @@ -4799,8 +4803,8 @@ cdef class Matrix(sage.structure.element.Matrix): def nonpivots(self): """ - Return the list of i such that the i-th column of self is NOT a - pivot column of the reduced row echelon form of self. + Return the list of `i` such that the `i`-th column of ``self`` is NOT a + pivot column of the reduced row echelon form of ``self``. OUTPUT: sorted tuple of (Python) integers @@ -4836,13 +4840,13 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``copy`` -- (default: ``True``) it is safe to change the - resulting list (unless you give the option ``copy=False``) + - ``copy`` -- boolean (default: ``True``); it is safe to change the + resulting list (unless you give the option ``copy=False``) - - ``column_order`` -- (default: ``False``) If ``True``, - returns the list of pairs ``(i,j)`` such that ``self[i,j] != 0``, but - sorted by columns, i.e., column ``j=0`` entries occur first, then - column ``j=1`` entries, etc. + - ``column_order`` -- boolean (default: ``False``); if ``True``, + returns the list of pairs ``(i,j)`` such that ``self[i,j] != 0``, but + sorted by columns, i.e., column ``j=0`` entries occur first, then + column ``j=1`` entries, etc. EXAMPLES:: @@ -4938,7 +4942,7 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``i`` -- an integer + - ``i`` -- integer OUTPUT: list @@ -4953,7 +4957,7 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a.nonzero_positions_in_column(1) [0, 1] - You will get an ``IndexError`` if you select an invalid column:: + You will get an :exc:`IndexError` if you select an invalid column:: sage: a.nonzero_positions_in_column(2) Traceback (most recent call last): @@ -4977,7 +4981,7 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``i`` -- an integer + - ``i`` -- integer OUTPUT: list @@ -5164,9 +5168,9 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``v`` -- a free module element. + - ``v`` -- a free module element - OUTPUT: The vector times matrix product v\*A. + OUTPUT: the vector times matrix product ``v*A`` EXAMPLES:: @@ -5206,7 +5210,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: v = vector(R, [1, x]) sage: v*I (1 + O(5^5), O(5)) - """ M = self.row_ambient_module() if self._nrows != v._degree: @@ -5241,7 +5244,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: v = vector(R, [1, x]) sage: I*v (1 + O(5^5), O(5)) - """ M = self.column_ambient_module() if self._ncols != v._degree: @@ -5339,7 +5341,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a + b # indirect doctest [ 2 4] [x*y + y*x 2*y*x] - """ cdef Py_ssize_t i, j cdef Matrix A @@ -5363,7 +5364,6 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a - b # indirect doctest [ 0 0] [x*y - y*x 0] - """ cdef Py_ssize_t i, j cdef Matrix A @@ -5676,7 +5676,7 @@ cdef class Matrix(sage.structure.element.Matrix): cdef bint _will_use_strassen(self, Matrix right) except -2: """ - Whether or not matrix multiplication of self by right should be + Whether or not matrix multiplication of ``self`` by ``right`` should be done using Strassen. Overload _strassen_default_cutoff to return -1 to not use @@ -5693,7 +5693,7 @@ cdef class Matrix(sage.structure.element.Matrix): cdef bint _will_use_strassen_echelon(self) except -2: """ - Whether or not matrix multiplication of self by right should be + Whether or not matrix multiplication of ``self`` by ``right`` should be done using Strassen. Overload this in derived classes to not use Strassen by default. @@ -5708,7 +5708,7 @@ cdef class Matrix(sage.structure.element.Matrix): def __neg__(self): """ - Return the negative of self. + Return the negative of ``self``. EXAMPLES:: @@ -5727,8 +5727,8 @@ cdef class Matrix(sage.structure.element.Matrix): Return the inverse of this matrix, as a matrix over the fraction field. - Raises a ``ZeroDivisionError`` if the matrix has zero - determinant, and raises an ``ArithmeticError``, if the + Raises a :exc:`ZeroDivisionError` if the matrix has zero + determinant, and raises an :exc:`ArithmeticError`, if the inverse doesn't exist because the matrix is nonsquare. Also, note, e.g., that the inverse of a matrix over `\ZZ` is always a matrix defined over `\QQ` (even if the @@ -5791,7 +5791,7 @@ cdef class Matrix(sage.structure.element.Matrix): [ 1 422550200076076467165567735125] [1267650600228229401496703205375 422550200076076467165567735126] - Matrices over p-adics. See :issue:`17272` :: + Matrices over `p`-adics. See :issue:`17272` :: sage: # needs sage.rings.padics sage: R = ZpCA(5, 5, print_mode='val-unit') @@ -5907,7 +5907,7 @@ cdef class Matrix(sage.structure.element.Matrix): Return the inverse of this matrix in the same matrix space. The matrix must be invertible on the base ring. Otherwise, an - ``ArithmeticError`` is raised. + :exc:`ArithmeticError` is raised. The computation goes through the matrix of cofactors and avoids division. In particular the base ring does not need to have a @@ -5915,7 +5915,7 @@ cdef class Matrix(sage.structure.element.Matrix): INPUT: - - ``algorithm`` -- (default: ``None``) either ``None`` or ``"df"`` (for + - ``algorithm`` -- (default: ``None``) either ``None`` or ``'df'`` (for division free) EXAMPLES:: @@ -6287,7 +6287,8 @@ def unpickle(cls, parent, immutability, cache, data, version): def set_max_rows(n): """ - Sets the global variable max_rows (which is used in deciding how to output a matrix). + Set the global variable ``max_rows`` (which is used in deciding how to + output a matrix). EXAMPLES:: @@ -6295,7 +6296,6 @@ def set_max_rows(n): sage: set_max_rows(20) doctest:...: DeprecationWarning: 'set_max_rows' is replaced by 'matrix.options.max_rows' See https://github.com/sagemath/sage/issues/30552 for details. - """ from sage.misc.superseded import deprecation deprecation(30552, "'set_max_rows' is replaced by 'matrix.options.max_rows'") @@ -6305,7 +6305,8 @@ def set_max_rows(n): def set_max_cols(n): """ - Sets the global variable max_cols (which is used in deciding how to output a matrix). + Set the global variable ``max_cols`` (which is used in deciding how to + output a matrix). EXAMPLES:: @@ -6313,7 +6314,6 @@ def set_max_cols(n): sage: set_max_cols(50) doctest:...: DeprecationWarning: 'set_max_cols' is replaced by 'matrix.options.max_cols' See https://github.com/sagemath/sage/issues/30552 for details. - """ from sage.misc.superseded import deprecation deprecation(30552, "'set_max_cols' is replaced by 'matrix.options.max_cols'") diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index a810418389c..96a175825b3 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -32,7 +32,7 @@ cdef class Matrix(Matrix0): def _pari_init_(self): """ - Return a string defining a GP representation of self. + Return a string defining a GP representation of ``self``. EXAMPLES:: @@ -61,7 +61,7 @@ cdef class Matrix(Matrix0): def __pari__(self): """ - Return the Pari matrix corresponding to self. + Return the Pari matrix corresponding to ``self``. EXAMPLES:: @@ -92,7 +92,7 @@ cdef class Matrix(Matrix0): def _gap_init_(self): """ - Returns a string defining a gap representation of self. + Return a string defining a gap representation of ``self``. EXAMPLES:: @@ -147,7 +147,7 @@ cdef class Matrix(Matrix0): INPUT: - - ``M`` -- a matrix. + - ``M`` -- a matrix OUTPUT: @@ -216,21 +216,21 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: M = matrix(ZZ, 2, range(4)) - sage: giac(M) # needs sage.libs.giac + sage: giac(M) # needs giac [[0,1],[2,3]] sage: M = matrix(QQ, 3, [1,2,3, 4/3,5/3,6/4, 7,8,9]) - sage: giac(M) # needs sage.libs.giac + sage: giac(M) # needs giac [[1,2,3],[4/3,5/3,3/2],[7,8,9]] sage: P. = ZZ[] sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5]) - sage: giac(M) # needs sage.libs.giac + sage: giac(M) # needs giac [[-9*sageVARx^2-2*sageVARx+2,sageVARx-1],[sageVARx^2+8*sageVARx,-3*sageVARx^2+5]] sage: y = var('y') # needs sage.symbolic sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic - sage: giac(M).det().sage() # needs sage.libs.giac sage.symbolic + sage: giac(M).det().sage() # needs giac sage.symbolic (y^2*dilog(y) + y*dilog(y)*sin(y) - y + 4)/y """ s = ','.join('[' + ','.join(cf._giac_init_() for cf in row) + ']' @@ -405,7 +405,7 @@ cdef class Matrix(Matrix0): def _polymake_(self, polymake=None): """ - Tries to coerce this matrix to a polymake matrix. + Try to coerce this matrix to a polymake matrix. EXAMPLES:: @@ -424,7 +424,7 @@ cdef class Matrix(Matrix0): def _singular_(self, singular=None): """ - Tries to coerce this matrix to a singular matrix. + Try to coerce this matrix to a singular matrix. """ if singular is None: from sage.interfaces.singular import singular as singular_default @@ -510,7 +510,7 @@ cdef class Matrix(Matrix0): def _scilab_(self, scilab=None): """ - Creates a ScilabElement object based on self and returns it. + Create a ScilabElement object based on ``self`` and returns it. EXAMPLES:: @@ -605,7 +605,6 @@ cdef class Matrix(Matrix0): [] sage: sZeroRow = ZeroRow._sympy_(); sZeroRow # needs sympy Matrix(0, 2, []) - """ from sage.interfaces.sympy import sympy_init sympy_init() @@ -671,16 +670,20 @@ cdef class Matrix(Matrix0): entries = [[sib(v, 2) for v in row] for row in self.rows()] return sib.name('matrix')(self.base_ring(), entries) - def numpy(self, dtype=None): + def numpy(self, dtype=None, copy=True): """ Return the Numpy matrix associated to this matrix. INPUT: - - ``dtype`` -- The desired data-type for the array. If not given, + - ``dtype`` -- the desired data-type for the array. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. + - ``copy`` -- if `self` is already an `ndarray`, then this flag + determines whether the data is copied (the default), or whether + a view is constructed. + EXAMPLES:: sage: # needs numpy @@ -705,12 +708,15 @@ cdef class Matrix(Matrix0): Type ``numpy.typecodes`` for a list of the possible typecodes:: - sage: import numpy # needs numpy - sage: sorted(numpy.typecodes.items()) # needs numpy + sage: import numpy # needs numpy + sage: numpy.typecodes.items() # needs numpy # random [('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'), - ('AllInteger', 'bBhHiIlLqQpP'), ('Character', 'c'), ('Complex', 'FDG'), - ('Datetime', 'Mm'), ('Float', 'efdg'), ('Integer', 'bhilqp'), - ('UnsignedInteger', 'BHILQP')] + ... + + For instance, you can see possibilities for real floating point numbers:: + + sage: numpy.typecodes['Float'] # needs numpy + 'efdg' Alternatively, numpy automatically calls this function (via the magic :meth:`__array__` method) to convert Sage matrices @@ -729,7 +735,7 @@ cdef class Matrix(Matrix0): (3, 4) """ import numpy - A = numpy.matrix(self.list(), dtype=dtype) + A = numpy.matrix(self.list(), dtype=dtype, copy=copy) return numpy.resize(A,(self.nrows(), self.ncols())) # Define the magic "__array__" function so that numpy.array(m) can convert @@ -760,7 +766,7 @@ cdef class Matrix(Matrix0): def lift(self): """ - Return lift of self to the covering ring of the base ring R, + Return lift of ``self`` to the covering ring of the base ring R, which is by definition the ring returned by calling cover_ring() on R, or just R itself if the cover_ring method is not defined. @@ -800,14 +806,14 @@ cdef class Matrix(Matrix0): def lift_centered(self): """ - Apply the lift_centered method to every entry of self. + Apply the lift_centered method to every entry of ``self``. OUTPUT: - If self is a matrix over the Integers mod `n`, this method returns the - unique matrix `m` such that `m` is congruent to self mod `n` and for + If ``self`` is a matrix over the Integers mod `n`, this method returns the + unique matrix `m` such that `m` is congruent to ``self`` mod `n` and for every entry `m[i,j]` we have `-n/2 < m[i,j] \\leq n/2`. If the - coefficient ring does not have a cover_ring method, return self. + coefficient ring does not have a cover_ring method, return ``self``. EXAMPLES:: @@ -969,12 +975,12 @@ cdef class Matrix(Matrix0): def columns(self, copy=True): r""" - Return a list of the columns of self. + Return a list of the columns of ``self``. INPUT: - - ``copy`` -- (default: ``True``) if True, return a copy of the list - of columns which is safe to change. + - ``copy`` -- boolean (default: ``True``); if ``True``, return a copy of the list + of columns which is safe to change If ``self`` is a sparse matrix, columns are returned as sparse vectors, otherwise returned vectors are dense. @@ -1006,10 +1012,10 @@ cdef class Matrix(Matrix0): sage: A.columns('junk') Traceback (most recent call last): ... - ValueError: 'copy' must be True or False, not junk + ValueError: 'copy' must be ``True`` or False, not junk """ if copy not in [True, False]: - msg = "'copy' must be True or False, not {0}" + msg = "'copy' must be ``True`` or False, not {0}" raise ValueError(msg.format(copy)) x = self.fetch('columns') if x is not None: @@ -1025,12 +1031,12 @@ cdef class Matrix(Matrix0): def rows(self, copy=True): r""" - Return a list of the rows of self. + Return a list of the rows of ``self``. INPUT: - - ``copy`` -- (default: ``True``) if True, return a copy of the list - of rows which is safe to change. + - ``copy`` -- boolean (default: ``True``); if ``True``, return a copy of the list + of rows which is safe to change If ``self`` is a sparse matrix, rows are returned as sparse vectors, otherwise returned vectors are dense. @@ -1062,10 +1068,10 @@ cdef class Matrix(Matrix0): sage: A.rows('junk') Traceback (most recent call last): ... - ValueError: 'copy' must be True or False, not junk + ValueError: 'copy' must be ``True`` or False, not junk """ if copy not in [True, False]: - msg = "'copy' must be True or False, not {0}" + msg = "'copy' must be ``True`` or False, not {0}" raise ValueError(msg.format(copy)) x = self.fetch('rows') if x is not None: @@ -1081,11 +1087,11 @@ cdef class Matrix(Matrix0): def dense_columns(self, copy=True): """ - Return list of the dense columns of self. + Return list of the dense columns of ``self``. INPUT: - - ``copy`` -- (default: ``True``) if True, return a copy so you can + - ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can modify it safely EXAMPLES: @@ -1144,11 +1150,11 @@ cdef class Matrix(Matrix0): def dense_rows(self, copy=True): """ - Return list of the dense rows of self. + Return list of the dense rows of ``self``. INPUT: - - ``copy`` -- (default: ``True``) if True, return a copy so you can + - ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can modify it safely (note that the individual vectors in the copy should not be modified since they are mutable!) @@ -1203,8 +1209,8 @@ cdef class Matrix(Matrix0): INPUT: - - ``copy`` -- (default: ``True``) if True, return a copy so you can - modify it safely + - ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can + modify it safely EXAMPLES:: @@ -1279,8 +1285,8 @@ cdef class Matrix(Matrix0): INPUT: - - ``copy`` -- (default: ``True``) if True, return a copy so you can - modify it safely + - ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can + modify it safely EXAMPLES:: @@ -1357,7 +1363,7 @@ cdef class Matrix(Matrix0): def column(self, Py_ssize_t i, from_list=False): """ - Return the ``i``'th column of this matrix as a vector. + Return the ``i``-th column of this matrix as a vector. This column is a dense vector if and only if the matrix is a dense matrix. @@ -1366,13 +1372,12 @@ cdef class Matrix(Matrix0): - ``i`` -- integer - - ``from_list`` -- bool (default: ``False``); if true, returns the - ``i``'th element of ``self.columns()`` (see :func:`columns()`), + - ``from_list`` -- boolean (default: ``False``); if ``True``, returns the + ``i``-th element of ``self.columns()`` (see :func:`columns()`), which may be faster, but requires building a list of all columns the first time it is called after an entry of the matrix is changed. - EXAMPLES:: sage: a = matrix(2, 3, range(6)); a @@ -1417,7 +1422,7 @@ cdef class Matrix(Matrix0): def row(self, Py_ssize_t i, from_list=False): """ - Return the ``i``'th row of this matrix as a vector. + Return the ``i``-th row of this matrix as a vector. This row is a dense vector if and only if the matrix is a dense matrix. @@ -1426,8 +1431,8 @@ cdef class Matrix(Matrix0): - ``i`` -- integer - - ``from_list`` -- bool (default: ``False``); if true, returns the - ``i``'th element of ``self.rows()`` (see :func:`rows`), which + - ``from_list`` -- boolean (default: ``False``); if ``True``, returns the + ``i``-th element of ``self.rows()`` (see :func:`rows`), which may be faster, but requires building a list of all rows the first time it is called after an entry of the matrix is changed. @@ -1487,10 +1492,10 @@ cdef class Matrix(Matrix0): INPUT: - ``bottom`` -- a matrix, vector or free module element, whose - dimensions are compatible with ``self``. + dimensions are compatible with ``self`` - - ``subdivide`` -- (default: ``False``); request the resulting - matrix to have a new subdivision, separating ``self`` from ``bottom``. + - ``subdivide`` -- (default: ``False``) request the resulting + matrix to have a new subdivision, separating ``self`` from ``bottom`` OUTPUT: @@ -1771,15 +1776,15 @@ cdef class Matrix(Matrix0): def augment(self, right, subdivide=False): r""" - Returns a new matrix formed by appending the matrix (or vector) + Return a new matrix formed by appending the matrix (or vector) ``right`` on the right side of ``self``. INPUT: - ``right`` -- a matrix, vector or free module element, whose - dimensions are compatible with ``self``. + dimensions are compatible with ``self`` - - ``subdivide`` -- (default: ``False``); request the resulting + - ``subdivide`` -- (default: ``False``) request the resulting matrix to have a new subdivision, separating ``self`` from ``right``. @@ -1809,7 +1814,6 @@ cdef class Matrix(Matrix0): :func:`~sage.matrix.constructor.block_diagonal_matrix` useful and simpler in some instances. - EXAMPLES: Augmenting with a matrix. :: @@ -1976,7 +1980,7 @@ cdef class Matrix(Matrix0): def matrix_from_columns(self, columns): """ - Return the matrix constructed from self using columns with indices + Return the matrix constructed from ``self`` using columns with indices in the columns list. EXAMPLES:: @@ -2010,8 +2014,9 @@ cdef class Matrix(Matrix0): INPUT: - * ``dcols`` -- list of indices of columns to be deleted from self. - * ``check`` -- checks whether any index in ``dcols`` is out of range. Defaults to ``True``. + - ``dcols`` -- list of indices of columns to be deleted from ``self`` + - ``check`` -- boolean (default: ``True``); check whether any index in + ``dcols`` is out of range .. SEEALSO:: @@ -2074,7 +2079,7 @@ cdef class Matrix(Matrix0): def matrix_from_rows(self, rows): """ - Return the matrix constructed from self using rows with indices in + Return the matrix constructed from ``self`` using rows with indices in the rows list. EXAMPLES:: @@ -2107,8 +2112,9 @@ cdef class Matrix(Matrix0): INPUT: - * ``drows`` -- list of indices of rows to be deleted from ``self``. - * ``check`` -- (boolean, default: ``True``); whether to check if any index in ``drows`` is out of range. + - ``drows`` -- list of indices of rows to be deleted from ``self`` + - ``check`` -- boolean (default: ``True``); whether to check if any + index in ``drows`` is out of range .. SEEALSO:: @@ -2230,13 +2236,13 @@ cdef class Matrix(Matrix0): def submatrix(self, Py_ssize_t row=0, Py_ssize_t col=0, Py_ssize_t nrows=-1, Py_ssize_t ncols=-1): """ - Return the matrix constructed from self using the specified + Return the matrix constructed from ``self`` using the specified range of rows and columns. INPUT: - - ``row``, ``col`` -- index of the starting row and column. - Indices start at zero. + - ``row``, ``col`` -- index of the starting row and column (indices + start at zero) - ``nrows``, ``ncols`` -- (optional) number of rows and columns to take. If not provided, take all rows below and all columns to @@ -2287,13 +2293,13 @@ cdef class Matrix(Matrix0): def set_row(self, row, v): r""" - Sets the entries of row ``row`` to the entries of ``v``. + Set the entries of row ``row`` to the entries of ``v``. INPUT: - - ``row`` -- index of row to be set. + - ``row`` -- index of row to be set - - ``v`` -- a list or vector of the new entries. + - ``v`` -- list or vector of the new entries OUTPUT: @@ -2360,13 +2366,13 @@ cdef class Matrix(Matrix0): def set_column(self, col, v): r""" - Sets the entries of column ``col`` to the entries of ``v``. + Set the entries of column ``col`` to the entries of ``v``. INPUT: - - ``col`` -- index of column to be set. + - ``col`` -- index of column to be set - - ``v`` -- a list or vector of the new entries. + - ``v`` -- list or vector of the new entries OUTPUT: @@ -2658,15 +2664,15 @@ cdef class Matrix(Matrix0): def matrix_space(self, nrows=None, ncols=None, sparse=None): """ - Return the ambient matrix space of self. + Return the ambient matrix space of ``self``. INPUT: - ``nrows``, ``ncols`` -- (optional) number of rows and columns in - returned matrix space. + returned matrix space - ``sparse`` -- whether the returned matrix space uses sparse or - dense matrices. + dense matrices EXAMPLES:: @@ -2715,7 +2721,7 @@ cdef class Matrix(Matrix0): """ Create a matrix in the parent of this matrix with the given number of rows, columns, etc. The default parameters are the same as for - self. + ``self``. INPUT: @@ -2723,9 +2729,9 @@ cdef class Matrix(Matrix0): - ``nrows``, ``ncols`` -- number of rows and columns in returned matrix. If not specified, defaults to ``None`` and will give a - matrix of the same size as self. + matrix of the same size as ``self``. - ``sparse`` -- whether returned matrix is sparse or not. Defaults - to same value as self. + to same value as self The remaining three variables (``coerce``, ``entries``, and ``copy``) are used by @@ -2735,7 +2741,7 @@ cdef class Matrix(Matrix0): .. warning:: This function called with no arguments returns the zero - matrix of the same dimension and sparseness of self. + matrix of the same dimension and sparseness of ``self``. EXAMPLES:: @@ -2784,7 +2790,7 @@ cdef class Matrix(Matrix0): def block_sum(self, Matrix other): """ - Return the block matrix that has self and other on the diagonal:: + Return the block matrix that has ``self`` and ``other`` on the diagonal:: [ self 0 ] [ 0 other ] diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 0b51d5c1df7..3682c2be14e 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -120,7 +120,7 @@ _Fields = Fields() cdef class Matrix(Matrix1): """ - Base class for matrices, part 2 + Base class for matrices, part 2. TESTS:: @@ -242,7 +242,7 @@ cdef class Matrix(Matrix1): some solvers will return solutions over a larger ring than the base ring of the inputs (a typical case are rational solutions for integer linear systems). When set to ``False``, a solution - over the base ring is returned, with a :class:`ValueError` + over the base ring is returned, with a :exc:`ValueError` being raised if none exists. - ``check`` -- boolean (default: ``True``); verify the answer @@ -442,7 +442,6 @@ cdef class Matrix(Matrix1): sage: A.solve_left(b, check=False) # needs sage.symbolic (2) - """ if isinstance(B, Vector): try: @@ -477,7 +476,7 @@ cdef class Matrix(Matrix1): some solvers will return solutions over a larger ring than the base ring of the inputs (a typical case are rational solutions for integer linear systems). When set to ``False``, a solution - over the base ring is returned, with a :class:`ValueError` + over the base ring is returned, with a :exc:`ValueError` being raised if none exists. - ``check`` -- boolean (default: ``True``); verify the answer @@ -555,7 +554,7 @@ cdef class Matrix(Matrix1): ... ValueError: matrix equation has no solutions - A :class:`ValueError` is raised if the input is invalid:: + A :exc:`ValueError` is raised if the input is invalid:: sage: A = matrix(QQ, 4,2, [0, -1, 1, 0, -2, 2, 1, 0]) sage: B = matrix(QQ, 2,2, [1, 0, 1, -1]) @@ -638,7 +637,7 @@ cdef class Matrix(Matrix1): sage: A*X == B True - Solving a system over the p-adics:: + Solving a system over the `p`-adics:: sage: # needs sage.rings.padics sage: k = Qp(5, 4) @@ -899,7 +898,7 @@ cdef class Matrix(Matrix1): # first coerce both elements to parent over same base ring P = K if L is K else coercion_model.common_parent(K, L) if P not in _Fields and P.is_integral_domain() and extend: - # the non-integral-domain case is handled separatedly below + # the non-integral-domain case is handled separately below P = P.fraction_field() if L is not P: B = B.change_ring(P) @@ -1032,18 +1031,16 @@ cdef class Matrix(Matrix1): def _solve_right_general(self, B, check=True): r""" This is used internally by the ``solve_right`` command - to solve for self\*X = B when self is not square or not of full + to solve for ``self*X = B`` when ``self`` is not square or not of full rank. It does some linear algebra, then solves a full-rank square system. INPUT: + - ``B`` -- a matrix - - ``B`` -- a matrix - - - ``check`` -- bool (default: ``True``); if False, if there - is no solution this function will not detect that fact. - + - ``check`` -- boolean (default: ``True``); if ``False``, if there + is no solution this function will not detect that fact OUTPUT: matrix @@ -1239,7 +1236,7 @@ cdef class Matrix(Matrix1): def elementwise_product(self, right): r""" - Returns the elementwise product of two matrices + Return the elementwise product of two matrices of the same size (also known as the Hadamard product). INPUT: @@ -1249,7 +1246,7 @@ cdef class Matrix(Matrix1): of elements of the base rings of ``self`` and ``right`` is defined, once Sage's coercion model is applied. If the matrices have different sizes, or if multiplication - of individual entries cannot be achieved, a ``TypeError`` + of individual entries cannot be achieved, a :exc:`TypeError` will result. OUTPUT: @@ -1415,7 +1412,7 @@ cdef class Matrix(Matrix1): raise TypeError("elementwise_product() argument should be a matrix or coercible to a matrix") return (A)._elementwise_product(B) - def permanent(self, algorithm="Ryser"): + def permanent(self, algorithm='Ryser'): r""" Return the permanent of this matrix. @@ -1495,7 +1492,7 @@ cdef class Matrix(Matrix1): sage: n, w = 50, 5 sage: A = matrix(ZZ, n, n, lambda i,j: (i+j)%5 + 1 if abs(i-j) <= w else 0) - sage: A.permanent(algorithm="ButeraPernici") + sage: A.permanent(algorithm='ButeraPernici') 57766972735511097036962481710892268404670105604676932908 See Minc: Permanents, Example 2.1, p. 5. @@ -1564,7 +1561,7 @@ cdef class Matrix(Matrix1): perm = perm + sn * _binomial(n-r, m-r) * s return perm - def permanental_minor(self, Py_ssize_t k, algorithm="Ryser"): + def permanental_minor(self, Py_ssize_t k, algorithm='Ryser'): r""" Return the permanental `k`-minor of this matrix. @@ -1573,9 +1570,9 @@ cdef class Matrix(Matrix1): maximal permanental minor is just the permanent. For a (0,1)-matrix `A` the permanental `k`-minor - counts the number of different selections of `k` 1's of - `A` with no two of the 1's on the same row and no two of the - 1's on the same column. + counts the number of different selections of `k` 1s of + `A` with no two of the 1s on the same row and no two of the + 1s on the same column. See Brualdi and Ryser: Combinatorial Matrix Theory, p. 203. Note the typo `p_0(A) = 0` in that reference! For applications @@ -1590,8 +1587,8 @@ cdef class Matrix(Matrix1): - ``k`` -- the size of the minor - - ``algorithm`` -- either "Ryser" (default) or "ButeraPernici". The - Butera-Pernici algorithm is well suited for band matrices. + - ``algorithm`` -- either "Ryser" (default) or "ButeraPernici"; the + Butera-Pernici algorithm is well suited for band matrices EXAMPLES:: @@ -1681,18 +1678,18 @@ cdef class Matrix(Matrix1): INPUT: - - ``algorithm`` (default: guess) -- one of the following: + - ``algorithm`` -- (default: guess) one of the following: - - ``"numpy"`` -- Use numpy's ``linalg.pinv()`` which is - suitable over real or complex fields. + - ``'numpy'`` -- use numpy's ``linalg.pinv()`` which is + suitable over real or complex fields - - ``"exact"`` -- Use a simple algorithm which is not + - ``'exact'`` -- use a simple algorithm which is not numerically stable but useful over exact fields. Assume that no conjugation is needed, that the conjugate transpose is just the transpose. - - ``"exactconj"`` -- Like ``exact`` but use the conjugate - transpose. + - ``'exactconj'`` -- like ``exact`` but use the conjugate + transpose OUTPUT: a matrix @@ -1728,10 +1725,10 @@ cdef class Matrix(Matrix1): sage: M = matrix.hilbert(12, ring=RR) sage: (~M * M).norm() # a considerable error # needs scipy 1.3... - sage: Mx = M.pseudoinverse(algorithm="exact") + sage: Mx = M.pseudoinverse(algorithm='exact') sage: (Mx * M).norm() # huge error # needs scipy 11.5... - sage: Mx = M.pseudoinverse(algorithm="numpy") # needs numpy + sage: Mx = M.pseudoinverse(algorithm='numpy') # needs numpy sage: (Mx * M).norm() # still OK 1.00... @@ -1744,10 +1741,10 @@ cdef class Matrix(Matrix1): sage: M * M.pseudoinverse() [ 0.2500000000000000? 0.4330127018922193?*I] [-0.4330127018922193?*I 0.750000000000000?] - sage: M * M.pseudoinverse(algorithm="exactconj") + sage: M * M.pseudoinverse(algorithm='exactconj') [ 1/4 0.4330127018922193?*I] [-0.4330127018922193?*I 3/4] - sage: M * M.pseudoinverse(algorithm="exact") + sage: M * M.pseudoinverse(algorithm='exact') [ -1/2 0.866025403784439?*I] [0.866025403784439?*I 3/2] @@ -1764,21 +1761,21 @@ cdef class Matrix(Matrix1): Numpy gives a strange answer due to rounding errors:: - sage: M.pseudoinverse(algorithm="numpy") # random # needs numpy + sage: M.pseudoinverse(algorithm='numpy') # random # needs numpy [-1286742750677287/643371375338643 1000799917193445/1000799917193444] [ 519646110850445/346430740566963 -300239975158034/600479950316067] Although it is not too far off:: - sage: (~M - M.pseudoinverse(algorithm="numpy")).norm() < 1e-14 # needs numpy + sage: (~M - M.pseudoinverse(algorithm='numpy')).norm() < 1e-14 # needs numpy True TESTS:: - sage: M.pseudoinverse(algorithm="exact") + sage: M.pseudoinverse(algorithm='exact') [ -2 1] [ 3/2 -1/2] - sage: M.pseudoinverse(algorithm="whatever") + sage: M.pseudoinverse(algorithm='whatever') Traceback (most recent call last): ... ValueError: unknown algorithm 'whatever', valid values are ('numpy', 'exact', 'exactconj') @@ -1861,16 +1858,16 @@ cdef class Matrix(Matrix1): - ``self`` -- an `m` by `n` matrix - - ``algorithm`` -- a string which must be either "Ryser" or - "ButeraPernici" (default) or "Godsil"; Ryser one might be faster on - simple and small instances. Godsil only accepts input in 0,1. + - ``algorithm`` -- string which must be either ``'Ryser'`` or + ``'ButeraPernici'`` (default) or ``'Godsil'``; Ryser one might be + faster on simple and small instances. Godsil only accepts input in 0,1. - - ``complement`` -- boolean (default: ``False``) whether we consider the + - ``complement`` -- boolean (default: ``False``); whether we consider the rook vector of the complement matrix. If set to ``True`` then the matrix must have entries in {0, 1} and the complement matrix is the - one for which the 0's are replaced by 1's and 1's by 0's. + one for which the 0s are replaced by 1s and 1s by 0s. - - ``use_complement`` -- Boolean (default: ``None``) whether to compute the + - ``use_complement`` -- boolean (default: ``None``); whether to compute the rook vector of a (0,1)-matrix from its complement. By default this is determined by the density of ones in the matrix. @@ -1917,11 +1914,11 @@ cdef class Matrix(Matrix1): Different algorithms are available:: sage: A = matrix([[1,0,0,1],[0,1,1,0],[0,1,1,0],[1,0,0,1]]) - sage: A.rook_vector(algorithm="ButeraPernici") + sage: A.rook_vector(algorithm='ButeraPernici') [1, 8, 20, 16, 4] - sage: A.rook_vector(algorithm="Ryser") + sage: A.rook_vector(algorithm='Ryser') [1, 8, 20, 16, 4] - sage: A.rook_vector(algorithm="Godsil") # needs sage.graphs sage.libs.flint + sage: A.rook_vector(algorithm='Godsil') # needs sage.graphs sage.libs.flint [1, 8, 20, 16, 4] When the matrix `A` has more ones then zeroes it is usually faster @@ -1941,27 +1938,27 @@ cdef class Matrix(Matrix1): sage: R. = PolynomialRing(GF(5)) sage: A = matrix(R, [[1, x, y], [x*y, x**2+y, 0]]) - sage: A.rook_vector(algorithm="ButeraPernici") + sage: A.rook_vector(algorithm='ButeraPernici') [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Ryser") + sage: A.rook_vector(algorithm='Ryser') [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Godsil") + sage: A.rook_vector(algorithm='Godsil') Traceback (most recent call last): ... ValueError: coefficients must be zero or one, but we have 'x' in position (0,1). sage: B = A.transpose() - sage: B.rook_vector(algorithm="ButeraPernici") + sage: B.rook_vector(algorithm='ButeraPernici') [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: B.rook_vector(algorithm="Ryser") + sage: B.rook_vector(algorithm='Ryser') [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] TESTS:: - sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="ButeraPernici") + sage: matrix([[0,0],[0,0]]).rook_vector(algorithm='ButeraPernici') [1, 0, 0] - sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Ryser") + sage: matrix([[0,0],[0,0]]).rook_vector(algorithm='Ryser') [1, 0, 0] - sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Godsil") # needs sage.graphs sage.libs.flint + sage: matrix([[0,0],[0,0]]).rook_vector(algorithm='Godsil') # needs sage.graphs sage.libs.flint [1, 0, 0] sage: matrix.ones(4, 2).rook_vector("Ryser") [1, 8, 12] @@ -1993,7 +1990,7 @@ cdef class Matrix(Matrix1): algorithm = "ButeraPernici" # we first run through the coefficients of the matrix to compute the - # number of non-zero coefficients and to see whether or not it contains + # number of nonzero coefficients and to see whether or not it contains # only elements in {0,1}... but this is not always needed if complement or use_complement is None or algorithm == "Godsil": # z2 flag is True if all coefficients belong to {0,1} @@ -2027,7 +2024,7 @@ cdef class Matrix(Matrix1): complement = not complement elif algorithm == "Ryser": - b = [self.permanental_minor(k, algorithm="Ryser") + b = [self.permanental_minor(k, algorithm='Ryser') for k in range(mn + 1)] elif algorithm == "ButeraPernici": @@ -2061,7 +2058,7 @@ cdef class Matrix(Matrix1): def minors(self, k): r""" - Return the list of all `k \times k` minors of self. + Return the list of all `k \times k` minors of ``self``. Let `A` be an `m \times n` matrix and `k` an integer with `0 \leq k`, `k \leq m` and `k \leq n`. @@ -2145,18 +2142,18 @@ cdef class Matrix(Matrix1): naive formula. In the specific case of matrices over the integers modulo a non-prime, the determinant of a lift is computed over the integers. In general, the characteristic polynomial is computed either using - the Hessenberg form (specified by ``"hessenberg"``) or the generic - division-free algorithm (specified by ``"df"``). When the base ring - is an exact field, the default choice is ``"hessenberg"``, otherwise - it is ``"df"``. Note that for matrices over most rings, more + the Hessenberg form (specified by ``'hessenberg'``) or the generic + division-free algorithm (specified by ``'df'``). When the base ring + is an exact field, the default choice is ``'hessenberg'``, otherwise + it is ``'df'``. Note that for matrices over most rings, more sophisticated algorithms can be used. (Type ``A.determinant?`` to see what is done for a specific matrix ``A``.) INPUT: - - ``algorithm`` -- string: - - ``"df"`` -- Generic O(n^4) division-free algorithm - - ``"hessenberg"`` -- Use the Hessenberg form of the matrix + - ``algorithm`` -- string; one of + - ``'df'`` -- generic O(n^4) division-free algorithm + - ``'hessenberg'`` -- use the Hessenberg form of the matrix EXAMPLES:: @@ -2319,7 +2316,7 @@ cdef class Matrix(Matrix1): # seems to be quite large for Q[x].) if (algorithm is None and R in _Fields and R.is_exact()) or (algorithm == "hessenberg"): try: - charp = self.charpoly('x', algorithm="hessenberg") + charp = self.charpoly('x', algorithm='hessenberg') except ValueError: # Hessenberg algorithm not supported, so we use whatever the default algorithm is. charp = self.charpoly('x') @@ -2340,7 +2337,7 @@ cdef class Matrix(Matrix1): var = 'A0123456789' if isinstance(R, sage.rings.abc.SymbolicRing) else 'x' try: - charp = self.charpoly(var, algorithm="df") + charp = self.charpoly(var, algorithm='df') except ValueError: # Division free algorithm not supported, so we use whatever the default algorithm is. charp = self.charpoly(var) @@ -2354,7 +2351,7 @@ cdef class Matrix(Matrix1): cdef _det_by_minors(self, Py_ssize_t level): """ Compute the determinant of the upper-left level x level submatrix - of self. Does not handle degenerate cases, level MUST be >= 2 + of ``self``. Does not handle degenerate cases, level MUST be >= 2 """ cdef Py_ssize_t i if level == 2: @@ -2460,14 +2457,14 @@ cdef class Matrix(Matrix1): INPUT: - - ``algorithm`` (default: ``None``) -- string, the algorithm to use; - currently the following algorithms have been implemented: + - ``algorithm`` -- string (default: ``None``); the algorithm to use. + Currently the following algorithms have been implemented: * ``'bfl'`` -- using the Bär-Faddeev-LeVerrier algorithm * ``'definition'`` -- using the definition given by perfect matchings - - ``check`` (default: ``True``) -- boolean determining whether to + - ``check`` -- boolean (default: ``True``); whether to check ``self`` for alternatingness and squareness. This has to be set to ``False`` if ``self`` is defined over a non-discrete ring. @@ -2612,7 +2609,6 @@ cdef class Matrix(Matrix1): sage: A.pfaffian() # needs sage.combinat 2 - """ pf = self.fetch('pfaffian') # check out cache @@ -2680,12 +2676,10 @@ cdef class Matrix(Matrix1): def _pf_perfect_matchings(self): r""" - Computes the Pfaffian of ``self`` using the definition given by perfect + Compute the Pfaffian of ``self`` using the definition given by perfect matchings. - OUTPUT: - - - an element of the base ring of ``self`` representing the Pfaffian + OUTPUT: an element of the base ring of ``self`` representing the Pfaffian EXAMPLES:: @@ -2697,7 +2691,6 @@ cdef class Matrix(Matrix1): ....: (1/2, -3/2, -1, -5/2, -1/2, 0)]) sage: A._pf_perfect_matchings() # needs sage.combinat -1/2 - """ R = self._base_ring k = self._nrows @@ -2723,7 +2716,7 @@ cdef class Matrix(Matrix1): cdef _pf_bfl(self): r""" - Computes the Pfaffian of ``self`` using the Baer-Faddeev-LeVerrier + Compute the Pfaffian of ``self`` using the Baer-Faddeev-LeVerrier algorithm. .. WARNING:: @@ -2755,7 +2748,6 @@ cdef class Matrix(Matrix1): sage: A = A - A.transpose() sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() # needs sage.combinat True - """ cdef Py_ssize_t n = self._ncols cdef Py_ssize_t q = n // 2 @@ -2788,10 +2780,8 @@ cdef class Matrix(Matrix1): INPUT: - - - ``phi`` -- a morphism, so phi is callable and - phi.domain() and phi.codomain() are defined. The codomain must be a - ring. + - ``phi`` -- a morphism, so ``phi`` is callable and ``phi.domain()`` + and ``phi.codomain()`` are defined. The codomain must be a ring OUTPUT: a matrix over the codomain of phi @@ -2836,11 +2826,12 @@ cdef class Matrix(Matrix1): INPUT: - - ``sparse`` -- True to make the output a sparse matrix; default: ``False`` + - ``sparse`` -- boolean (default: ``False); ``True`` to make the output + a sparse matrix - - ``phi`` -- arbitrary Python function or callable object + - ``phi`` -- arbitrary Python function or callable object - - ``R`` -- (optional) ring + - ``R`` -- (optional) ring OUTPUT: a matrix over R @@ -2871,7 +2862,7 @@ cdef class Matrix(Matrix1): Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 - If self is subdivided, the result will be as well:: + If ``self`` is subdivided, the result will be as well:: sage: m = matrix(2, 2, srange(4)) sage: m.subdivide(None, 1); m @@ -2969,7 +2960,7 @@ cdef class Matrix(Matrix1): def minimal_polynomial(self, var='x', **kwds): r""" - This is a synonym for ``self.minpoly`` + This is a synonym for ``self.minpoly``. EXAMPLES:: @@ -2983,7 +2974,7 @@ cdef class Matrix(Matrix1): def minpoly(self, var='x', **kwds): r""" - Return the minimal polynomial of self. + Return the minimal polynomial of ``self``. This uses a simplistic - and potentially very very slow - algorithm that involves computing kernels to determine the powers of the @@ -3060,7 +3051,7 @@ cdef class Matrix(Matrix1): def charpoly(self, var='x', algorithm=None): r""" - Returns the characteristic polynomial of self, as a polynomial over + Return the characteristic polynomial of self, as a polynomial over the base ring. ALGORITHM: @@ -3069,8 +3060,8 @@ cdef class Matrix(Matrix1): In the generic case of matrices over a ring (commutative and with unity), there is a division-free algorithm, which can be accessed - using ``"df"``, with complexity `O(n^4)`. Alternatively, by - specifying ``"hessenberg"``, this method computes the Hessenberg + using ``'df'``, with complexity `O(n^4)`. Alternatively, by + specifying ``'hessenberg'``, this method computes the Hessenberg form of the matrix and then reads off the characteristic polynomial. Moreover, for matrices over number fields, this method can use PARI's charpoly implementation instead. @@ -3090,10 +3081,10 @@ cdef class Matrix(Matrix1): INPUT: - - ``var`` -- a variable name (default: 'x') - - ``algorithm`` -- string: - - ``"df"`` -- Generic `O(n^4)` division-free algorithm - - ``"hessenberg"`` -- Use the Hessenberg form of the matrix + - ``var`` -- a variable name (default: ``'x'``) + - ``algorithm`` -- string; one of + - ``'df'`` -- generic `O(n^4)` division-free algorithm + - ``'hessenberg'`` -- use the Hessenberg form of the matrix EXAMPLES: @@ -3226,7 +3217,6 @@ cdef class Matrix(Matrix1): y^2 - 3.00000000000000*y - 2.00000000000000 sage: A._cache['charpoly'] x^2 - 3.00000000000000*x - 2.00000000000000 - """ f = self.fetch('charpoly') if f is not None: @@ -3256,15 +3246,13 @@ cdef class Matrix(Matrix1): def _charpoly_df(self, var='x'): r""" - Computes the characteristic polynomial of ``self`` without divisions. + Compute the characteristic polynomial of ``self`` without divisions. INPUT: - ``var`` -- a variable name (default: ``'x'``) - OUTPUT: - - - polynomial -- the characteristic polynomial of ``self`` + OUTPUT: polynomial; the characteristic polynomial of ``self`` EXAMPLES: @@ -3330,7 +3318,6 @@ cdef class Matrix(Matrix1): Note that there is a missing minus sign in front of the last term in the penultimate line of Algorithm 3.1. - """ # Validate assertions @@ -3410,11 +3397,11 @@ cdef class Matrix(Matrix1): def fcp(self, var='x'): """ - Return the factorization of the characteristic polynomial of self. + Return the factorization of the characteristic polynomial of ``self``. INPUT: - - ``var`` -- (default: 'x') name of variable of charpoly + - ``var`` -- (default: ``'x'``) name of variable of charpoly EXAMPLES:: @@ -3431,10 +3418,10 @@ cdef class Matrix(Matrix1): def denominator(self): r""" Return the least common multiple of the denominators of the - elements of self. + elements of ``self``. If there is no denominator function for the base field, or no LCM - function for the denominators, raise a TypeError. + function for the denominators, raise a :exc:`TypeError`. EXAMPLES:: @@ -3540,13 +3527,11 @@ cdef class Matrix(Matrix1): def trace(self): """ Return the trace of self, which is the sum of the diagonal entries - of self. + of ``self``. INPUT: - - - ``self`` -- a square matrix - + - ``self`` -- a square matrix OUTPUT: element of the base ring of self @@ -3577,7 +3562,7 @@ cdef class Matrix(Matrix1): def trace_of_product(self, Matrix other): """ - Returns the trace of self * other without computing the entire product. + Return the trace of ``self * other`` without computing the entire product. EXAMPLES:: @@ -3599,7 +3584,7 @@ cdef class Matrix(Matrix1): ##################################################################################### def hessenberg_form(self): """ - Return Hessenberg form of self. + Return Hessenberg form of ``self``. If the base ring is merely an integral domain (and not a field), the Hessenberg form will (in general) only be defined over the @@ -3640,7 +3625,7 @@ cdef class Matrix(Matrix1): def hessenbergize(self): """ - Transform self to Hessenberg form. + Transform ``self`` to Hessenberg form. The hessenberg form of a matrix `A` is a matrix that is similar to `A`, so has the same characteristic polynomial @@ -3697,7 +3682,7 @@ cdef class Matrix(Matrix1): zero = self._base_ring(0) one = self._base_ring(1) for m from 1 <= m < n-1: - # Search for a non-zero entry in column m-1 + # Search for a nonzero entry in column m-1 i = -1 for r from m+1 <= r < n: if not self.get_is_zero_unsafe(r, m-1): @@ -3735,16 +3720,16 @@ cdef class Matrix(Matrix1): def _charpoly_hessenberg(self, var): """ - Transforms self in place to its Hessenberg form then computes and + Transform ``self`` in place to its Hessenberg form then computes and returns the coefficients of the characteristic polynomial of this matrix. INPUT: - - ``var`` -- name of the indeterminate of the charpoly + - ``var`` -- name of the indeterminate of the charpoly The characteristic polynomial is represented as a vector of ints, - where the constant term of the characteristic polynomial is the 0th + where the constant term of the characteristic polynomial is the `0`-th coefficient of the vector. EXAMPLES:: @@ -3763,7 +3748,7 @@ cdef class Matrix(Matrix1): if self._nrows != self._ncols: raise ArithmeticError("charpoly not defined for non-square matrix.") - # Replace self by its Hessenberg form + # Replace ``self`` by its Hessenberg form # (note the entries might now live in the fraction field) cdef Matrix H H = self.hessenberg_form() @@ -4117,25 +4102,25 @@ cdef class Matrix(Matrix1): def right_kernel_matrix(self, *args, **kwds): r""" - Returns a matrix whose rows form a basis + Return a matrix whose rows form a basis for the right kernel of ``self``. INPUT: - - ``algorithm`` -- (default: 'default'); a keyword that selects the + - ``algorithm`` -- (default: ``'default'``) a keyword that selects the algorithm employed. Allowable values are: - - 'default' -- allows the algorithm to be chosen automatically - - 'generic' -- naive algorithm usable for matrices over any field - - 'flint' -- FLINT library code for matrices over the rationals + - ``'default'`` -- allows the algorithm to be chosen automatically + - ``'generic'`` -- naive algorithm usable for matrices over any field + - ``'flint'`` -- FLINT library code for matrices over the rationals or the integers - - 'pari' -- PARI library code for matrices over number fields + - ``'pari'`` -- PARI library code for matrices over number fields or the integers - - 'padic' -- padic algorithm from IML library for matrices + - ``'padic'`` -- padic algorithm from IML library for matrices over the rationals and integers - - 'pluq' -- PLUQ matrix factorization for matrices mod 2 + - ``'pluq'`` -- PLUQ matrix factorization for matrices mod 2 - - ``basis`` -- (default: 'default'); a keyword that describes + - ``basis`` -- (default: ``'default'``) a keyword that describes the format of the basis returned. Allowable values are: - 'default': uses 'echelon' over fields; 'computed' otherwise. @@ -4569,7 +4554,7 @@ cdef class Matrix(Matrix1): Over inexact rings: - For inexact rings one should avoid echolonizing if possible:: + For inexact rings one should avoid echelonizing if possible:: sage: A = Matrix( ....: [[ 0.0, 0.5, 0.8090169944], @@ -4789,7 +4774,7 @@ cdef class Matrix(Matrix1): def left_kernel_matrix(self, *args, **kwds): r""" - Returns a matrix whose rows form a basis for the left kernel + Return a matrix whose rows form a basis for the left kernel of ``self``. This method is a thin wrapper around :meth:`right_kernel_matrix`. @@ -4807,7 +4792,7 @@ cdef class Matrix(Matrix1): def right_kernel(self, *args, **kwds): r""" - Returns the right kernel of this matrix, as a vector space or + Return the right kernel of this matrix, as a vector space or free module. This is the set of vectors ``x`` such that ``self*x = 0``. .. NOTE:: @@ -4816,24 +4801,24 @@ cdef class Matrix(Matrix1): :meth:`kernel` is exactly equal to :meth:`left_kernel`. For inexact rings use :meth:`right_kernel_matrix` with - ``basis='computed'`` to avoid echolonizing. + ``basis='computed'`` to avoid echelonizing. INPUT: - - ``algorithm`` -- (default: 'default'); a keyword that selects the + - ``algorithm`` -- (default: ``'default'``) a keyword that selects the algorithm employed. Allowable values are: - - 'default' -- allows the algorithm to be chosen automatically - - 'generic' -- naive algorithm usable for matrices over any field - - 'flint' -- FLINT library code for matrices over the rationals + - ``'default'`` -- allows the algorithm to be chosen automatically + - ``'generic'`` -- naive algorithm usable for matrices over any field + - ``'flint'`` -- FLINT library code for matrices over the rationals or the integers - - 'pari' -- PARI library code for matrices over number fields + - ``'pari'`` -- PARI library code for matrices over number fields or the integers - - 'padic' -- padic algorithm from IML library for matrices + - ``'padic'`` -- padic algorithm from IML library for matrices over the rationals and integers - - 'pluq' -- PLUQ matrix factorization for matrices mod 2 + - ``'pluq'`` -- PLUQ matrix factorization for matrices mod 2 - - ``basis`` -- (default: 'echelon'); a keyword that describes the + - ``basis`` -- (default: ``'echelon'``) a keyword that describes the format of the basis used to construct the right kernel. Allowable values are: @@ -4988,7 +4973,7 @@ cdef class Matrix(Matrix1): For matrices over the integers, several options are possible. The basis can be an LLL-reduced basis or an echelon basis. The pivot basis isnot available. A heuristic will decide whether - to use a p-adic algorithm from the IML library or an algorithm + to use a `p`-adic algorithm from the IML library or an algorithm from the PARI library. Note how specifying the algorithm can mildly influence the LLL basis. :: @@ -5175,7 +5160,8 @@ cdef class Matrix(Matrix1): def left_kernel(self, *args, **kwds): r""" - Returns the left kernel of this matrix, as a vector space or free module. + Return the left kernel of this matrix, as a vector space or free module. + This is the set of vectors ``x`` such that ``x*self = 0``. .. NOTE:: @@ -5184,24 +5170,24 @@ cdef class Matrix(Matrix1): :meth:`kernel` is exactly equal to :meth:`left_kernel`. For inexact rings use :meth:`right_kernel_matrix` with - ``basis='computed'`` (on the transpose of the matrix) to avoid echolonizing. + ``basis='computed'`` (on the transpose of the matrix) to avoid echelonizing. INPUT: - - ``algorithm`` -- (default: 'default'); a keyword that selects the + - ``algorithm`` -- (default: ``'default'``) a keyword that selects the algorithm employed. Allowable values are: - - 'default' -- allows the algorithm to be chosen automatically - - 'generic' -- naive algorithm usable for matrices over any field - - 'flint' -- FLINT library code for matrices over the rationals + - ``'default'`` -- allows the algorithm to be chosen automatically + - ``'generic'`` -- naive algorithm usable for matrices over any field + - ``'flint'`` -- FLINT library code for matrices over the rationals or the integers - - 'pari' -- PARI library code for matrices over number fields + - ``'pari'`` -- PARI library code for matrices over number fields or the integers - - 'padic' -- padic algorithm from IML library for matrices + - ``'padic'`` -- padic algorithm from IML library for matrices over the rationals and integers - - 'pluq' -- PLUQ matrix factorization for matrices mod 2 + - ``'pluq'`` -- PLUQ matrix factorization for matrices mod 2 - - ``basis`` -- (default: 'echelon'); a keyword that describes + - ``basis`` -- (default: ``'echelon'``) a keyword that describes the format of the basis used to construct the left kernel. Allowable values are: @@ -5331,29 +5317,27 @@ cdef class Matrix(Matrix1): def kernel_on(self, V, poly=None, check=True): """ - Return the kernel of self restricted to the invariant subspace V. - The result is a vector subspace of V, which is also a subspace + Return the kernel of ``self`` restricted to the invariant subspace `V`. + The result is a vector subspace of `V`, which is also a subspace of the ambient space. INPUT: - ``V`` -- vector subspace - - ``check`` -- (optional) default: ``True``; whether to check that - V is invariant under the action of self. + - ``check`` -- boolean (default: ``True``); whether to check that + `V` is invariant under the action of ``self`` - - ``poly`` -- (optional) default: None; if not None, compute instead - the kernel of poly(self) on V. - - OUTPUT: + - ``poly`` -- (default: ``None``) if not ``None``, compute instead + the kernel of ``poly(self)`` on `V` - - a subspace + OUTPUT: a subspace .. warning:: - This function does *not* check that V is in fact - invariant under self if check is False. With check False this - function is much faster. + This function does *not* check that `V` is in fact + invariant under ``self`` if check is ``False``. With check + ``False`` this function is much faster. EXAMPLES:: @@ -5433,7 +5417,7 @@ cdef class Matrix(Matrix1): Assume that the base field of this matrix has a numerator and denominator functions for its elements, e.g., it is the rational numbers or a fraction field. This function computes a basis over - the integers for the kernel of self. + the integers for the kernel of ``self``. If the matrix is not coercible into QQ, then the PID itself should be given as a second argument, as in the third example below. @@ -5469,7 +5453,6 @@ cdef class Matrix(Matrix1): with defining polynomial x^2 - x + 2 Echelon basis matrix: [ -1 -w + 1] - """ try: A, _ = self._clear_denom() @@ -5519,7 +5502,7 @@ cdef class Matrix(Matrix1): def row_module(self, base_ring=None): """ Return the free module over the base ring spanned by the rows of - self. + ``self``. EXAMPLES:: @@ -5619,7 +5602,7 @@ cdef class Matrix(Matrix1): def decomposition(self, algorithm='spin', is_diagonalizable=False, dual=False): """ - Returns the decomposition of the free module on which this matrix A + Return the decomposition of the free module on which this matrix A acts from the right (i.e., the action is x goes to x A), along with whether this matrix acts irreducibly on each factor. The factors are guaranteed to be sorted in the same way as the corresponding @@ -5637,38 +5620,34 @@ cdef class Matrix(Matrix1): INPUT: + - ``self`` -- a matrix - - ``self`` -- a matrix - - - ``algorithm`` -- 'spin' (default): algorithm involves - iterating the action of self on a vector. 'kernel': naively just - compute `ker(f_i(A))` for each factor `f_i`. + - ``algorithm`` -- string (default: ``'spin'``); ``'spin'``: involves + iterating the action of ``self`` on a vector. ``'kernel'``: naively + just compute `ker(f_i(A))` for each factor `f_i`. - - ``dual`` -- bool (default: ``False``): If True, also - returns the corresponding decomposition of V under the action of - the transpose of A. The factors are guaranteed to correspond. + - ``dual`` -- boolean (default: ``False``); if True, also + returns the corresponding decomposition of V under the action of + the transpose of A. The factors are guaranteed to correspond. - - ``is_diagonalizable`` -- if the matrix is known to - be diagonalizable, set this to True, which might speed up the - algorithm in some cases. + - ``is_diagonalizable`` -- if the matrix is known to + be diagonalizable, set this to True, which might speed up the + algorithm in some cases. .. NOTE:: If the base ring is not a field, the kernel algorithm is used. - OUTPUT: - - ``Sequence`` -- list of pairs (V,t), where V is a vector - spaces and t is a bool, and t is True exactly when the - charpoly of self on V is irreducible. - + spaces and t is a boolean, and t is ``True`` exactly when the + charpoly of ``self`` on V is irreducible. - (optional) list -- list of pairs (W,t), where W is a vector - space and t is a bool, and t is True exactly when the - charpoly of the transpose of self on W is irreducible. + space and t is a boolean, and t is ``True`` exactly when the + charpoly of the transpose of ``self`` on W is irreducible. EXAMPLES:: @@ -5718,7 +5697,7 @@ cdef class Matrix(Matrix1): - ``self`` -- a matrix with field entries - OUTPUT: a list of reduced row echelon form basis + OUTPUT: list of reduced row echelon form basis """ if not self.is_square(): raise ValueError("self must be a square matrix") @@ -5853,9 +5832,9 @@ cdef class Matrix(Matrix1): def decomposition_of_subspace(self, M, check_restrict=True, **kwds): """ - Suppose the right action of self on M leaves M invariant. Return + Suppose the right action of ``self`` on M leaves M invariant. Return the decomposition of M as a list of pairs (W, is_irred) where - is_irred is True if the charpoly of self acting on the factor W is + is_irred is ``True`` if the charpoly of ``self`` acting on the factor W is irreducible. Additional inputs besides M are passed onto the decomposition @@ -5863,10 +5842,10 @@ cdef class Matrix(Matrix1): INPUT: - - `M` -- A subspace of the free module ``self`` acts on. - - ``check_restrict`` -- A boolean (default: ``True``); Call restrict - with or without check. - - ``kwds`` -- Keywords that will be forwarded to :meth:`~.decomposition`. + - ``M`` -- a subspace of the free module ``self`` acts on + - ``check_restrict`` -- boolean (default: ``True``); call restrict + with or without check + - ``kwds`` -- keywords that will be forwarded to :meth:`~.decomposition` EXAMPLES:: @@ -5962,18 +5941,16 @@ cdef class Matrix(Matrix1): def restrict(self, V, check=True): """ - Returns the matrix that defines the action of self on the chosen + Return the matrix that defines the action of ``self`` on the chosen basis for the invariant subspace V. If V is an ambient, returns - self (not a copy of self). + ``self`` (not a copy of self). INPUT: + - ``V`` -- vector subspace - - ``V`` -- vector subspace - - - ``check`` -- (optional) default: ``True``; if False may - not check that V is invariant (hence can be faster). - + - ``check`` -- boolean (default: ``True``); if ``False`` may + not check that V is invariant (hence can be faster) OUTPUT: a matrix @@ -6035,15 +6012,14 @@ cdef class Matrix(Matrix1): def restrict_domain(self, V): """ Compute the matrix relative to the basis for V on the domain - obtained by restricting self to V, but not changing the codomain of + obtained by restricting ``self`` to V, but not changing the codomain of the matrix. This is the matrix whose rows are the images of the basis for V. INPUT: - - - ``V`` -- vector space (subspace of ambient space on - which self acts) + - ``V`` -- vector space (subspace of ambient space on + which ``self`` acts) .. SEEALSO:: @@ -6067,8 +6043,8 @@ cdef class Matrix(Matrix1): def restrict_codomain(self, V): r""" - Suppose that self defines a linear map from some domain to a - codomain that contains `V` and that the image of self is + Suppose that ``self`` defines a linear map from some domain to a + codomain that contains `V` and that the image of ``self`` is contained in `V`. This function returns a new matrix `A` that represents this linear map but as a map to `V`, in the sense that if `x` is in the domain, @@ -6077,10 +6053,8 @@ cdef class Matrix(Matrix1): INPUT: - - - ``V`` -- vector space (space of degree - ``self.ncols()``) that contains the image of self. - + - ``V`` -- vector space (space of degree + ``self.ncols()``) that contains the image of ``self`` .. SEEALSO:: @@ -6110,23 +6084,17 @@ cdef class Matrix(Matrix1): def maxspin(self, v): """ - Computes the largest integer n such that the list of vectors + Compute the largest integer n such that the list of vectors `S=[v, v*A, ..., v * A^n]` are linearly independent, and returns that list. INPUT: + - ``self`` -- matrix - - ``self`` -- Matrix - - - ``v`` -- Vector - - - OUTPUT: - - - - ``list`` -- list of Vectors + - ``v`` -- vector + OUTPUT: list of Vectors ALGORITHM: The current implementation just adds vectors to a vector space until the dimension doesn't grow. This could be optimized by @@ -6169,17 +6137,15 @@ cdef class Matrix(Matrix1): def wiedemann(self, i, t=0): """ - Application of Wiedemann's algorithm to the i-th standard basis + Application of Wiedemann's algorithm to the `i`-th standard basis vector. INPUT: + - ``i`` -- integer - - ``i`` -- an integer - - - ``t`` -- an integer (default: 0) if t is nonzero, use - only the first t linear recurrence relations. - + - ``t`` -- integer (default: 0); if t is nonzero, use + only the first t linear recurrence relations IMPLEMENTATION: This is a toy implementation. @@ -6243,7 +6209,7 @@ cdef class Matrix(Matrix1): EXAMPLES: - Pass-through first. :: + Pass-through first:: sage: A = matrix(QQ, 2, range(4)) sage: A._eigenspace_format('all') == 'all' @@ -6295,16 +6261,16 @@ cdef class Matrix(Matrix1): INPUT: - ``self`` -- a square matrix over an exact field. For inexact - matrices consult the numerical or symbolic matrix classes. + matrices consult the numerical or symbolic matrix classes - ``format`` -- one of: - - ``'all'`` -- Attempts to create every eigenspace. This will - always be possible for matrices with rational entries. - - ``'galois'`` -- For each irreducible factor of the characteristic + - ``'all'`` -- attempts to create every eigenspace. This will + always be possible for matrices with rational entries + - ``'galois'`` -- for each irreducible factor of the characteristic polynomial, a single eigenspace will be output for a - single root/eigenvalue for the irreducible factor. - - ``None`` (default) -- Uses the ``'all'`` format if the base ring is contained + single root/eigenvalue for the irreducible factor + - ``None`` -- default; uses the ``'all'`` format if the base ring is contained in an algebraically closed field which is implemented. Otherwise, uses the ``'galois'`` format. @@ -6316,7 +6282,7 @@ cdef class Matrix(Matrix1): the irreducible factors of the characteristic polynomial, even for linear factors. - - ``algebraic_multiplicity`` -- (boolean, default: ``False``); + - ``algebraic_multiplicity`` -- boolean (default: ``False``); whether to include the algebraic multiplicity of each eigenvalue in the output. See the discussion below. @@ -6665,20 +6631,20 @@ cdef class Matrix(Matrix1): INPUT: - ``self`` -- a square matrix over an exact field. For inexact - matrices consult the numerical or symbolic matrix classes. + matrices consult the numerical or symbolic matrix classes - - ``format`` -- default: ``None`` + - ``format`` -- (default: ``None``) - ``'all'`` -- attempts to create every eigenspace. This will - always be possible for matrices with rational entries. + always be possible for matrices with rational entries - ``'galois'`` -- for each irreducible factor of the characteristic polynomial, a single eigenspace will be output for a - single root/eigenvalue for the irreducible factor. - - ``None`` -- Uses the 'all' format if the base ring is contained + single root/eigenvalue for the irreducible factor + - ``None`` -- uses the 'all' format if the base ring is contained in an algebraically closed field which is implemented. Otherwise, uses the 'galois' format. - - ``var`` -- (default: 'a'); variable name used to + - ``var`` -- (default: ``'a'``) variable name used to represent elements of the root field of each irreducible factor of the characteristic polynomial. If var='a', then the root fields will be in terms of @@ -6686,7 +6652,7 @@ cdef class Matrix(Matrix1): the irreducible factors of the characteristic polynomial, even for linear factors. - - ``algebraic_multiplicity`` -- (default: ``False``); whether or + - ``algebraic_multiplicity`` -- (default: ``False``) whether or not to include the algebraic multiplicity of each eigenvalue in the output. See the discussion below. @@ -7588,7 +7554,6 @@ cdef class Matrix(Matrix1): sage: D, P = A.eigenmatrix_right() sage: (A*P - P*D).norm() < 10^(-2) True - """ D, P = self.transpose().eigenmatrix_left(None if other is None else other.transpose()) @@ -7744,13 +7709,13 @@ cdef class Matrix(Matrix1): def _echelonize_ring(self, **kwds): r""" - Echelonize self in place, where the base ring of self is assumed to + Echelonize ``self`` in place, where the base ring of ``self`` is assumed to be a ring (not a field). Right now this *only* works over ZZ and some principal ideal domains; - otherwise a ``NotImplementedError`` is raised. In the special case of + otherwise a :exc:`NotImplementedError` is raised. In the special case of sparse matrices over ZZ it makes them dense, gets the echelon form of - the dense matrix, then sets self equal to the result. + the dense matrix, then sets ``self`` equal to the result. EXAMPLES:: @@ -7829,10 +7794,10 @@ cdef class Matrix(Matrix1): else: return - def echelonize(self, algorithm="default", cutoff=0, **kwds): + def echelonize(self, algorithm='default', cutoff=0, **kwds): r""" Transform ``self`` into a matrix in echelon form over the same - base ring as self. + base ring as ``self``. .. NOTE:: @@ -7863,10 +7828,10 @@ cdef class Matrix(Matrix1): - ``'strassen'``: use a Strassen divide and conquer algorithm (if available) - - ``cutoff`` -- integer. Only used if the Strassen algorithm - is selected. + - ``cutoff`` -- integer; only used if the Strassen algorithm + is selected - - ``transformation`` -- boolean. Whether to also return the + - ``transformation`` -- boolean; whether to also return the transformation matrix. Some matrix backends do not provide this information, in which case this option is ignored. @@ -7927,7 +7892,7 @@ cdef class Matrix(Matrix1): [ 1 y/x] [ 0 0] - We check that the echelon form works for matrices over p-adics. + We check that the echelon form works for matrices over `p`-adics. See :issue:`17272`:: sage: # needs sage.rings.padics @@ -8022,7 +7987,7 @@ cdef class Matrix(Matrix1): except ArithmeticError as msg: raise NotImplementedError("%s\nEchelon form not implemented over '%s'."%(msg, basring)) - def echelon_form(self, algorithm="default", cutoff=0, **kwds): + def echelon_form(self, algorithm='default', cutoff=0, **kwds): r""" Return the echelon form of ``self``. @@ -8046,7 +8011,7 @@ cdef class Matrix(Matrix1): - ``'partial_pivoting'``: Gauss elimination, using partial pivoting (if base ring has absolute value) - - ``'scaled_partial_pivoting'``: Gauss elimination, using scaled + - ``'scaled_partial_pivoting'`` -- Gauss elimination, using scaled partial pivoting (if base ring has absolute value) - ``'scaled_partial_pivoting_valuation'``: Gauss elimination, using @@ -8055,16 +8020,16 @@ cdef class Matrix(Matrix1): - ``'strassen'``: use a Strassen divide and conquer algorithm (if available) - - ``cutoff`` -- integer. Only used if the Strassen algorithm is selected. + - ``cutoff`` -- integer; only used if the Strassen algorithm is selected - - ``transformation`` -- boolean. Whether to also return the + - ``transformation`` -- boolean; whether to also return the transformation matrix. Some matrix backends do not provide this information, in which case this option is ignored. OUTPUT: The reduced row echelon form of ``self``, as an immutable - matrix. Note that self is *not* changed by this command. Use + matrix. Note that ``self`` is *not* changed by this command. Use :meth:`echelonize` to change ``self`` in place. If the optional parameter ``transformation=True`` is @@ -8362,7 +8327,7 @@ cdef class Matrix(Matrix1): def _echelon_in_place_classical(self): """ - Transform self into echelon form and return the pivots of self. + Transform ``self`` into echelon form and return the pivots of ``self``. EXAMPLES:: @@ -8387,11 +8352,11 @@ cdef class Matrix(Matrix1): INPUT: - - ``subdivide`` -- (boolean, default: ``False``) whether to + - ``subdivide`` -- boolean (default: ``False``); whether to subdivide the returned matrix. See the description of the (output) below for details. - ``kwds`` -- additional keywords that can be passed to - the method that computes the echelon form. + the method that computes the echelon form OUTPUT: @@ -8403,7 +8368,7 @@ cdef class Matrix(Matrix1): If ``subdivide`` is ``True`` then the returned matrix has a single division among the columns and a single division among the rows. The column subdivision has `n` columns to the left and `m` - columns to the right. The row division separates the non-zero rows + columns to the right. The row division separates the nonzero rows from the zero rows, when restricted to the first `n` columns. For a nonsingular matrix the final `m` columns of the extended @@ -8590,9 +8555,7 @@ cdef class Matrix(Matrix1): a matrix under row and column permutations. See :meth:`automorphisms_of_rows_and_columns`. - OUTPUT: - - - A bipartite graph. + OUTPUT: a bipartite graph EXAMPLES:: @@ -8686,14 +8649,12 @@ cdef class Matrix(Matrix1): INPUT: - - ``check`` -- (default: ``False``) If ``True`` return a tuple of + - ``check`` -- boolean (default: ``False``); if ``True`` return a tuple of the maximal matrix and the permutations taking ``self`` to the maximal matrix. If ``False``, return only the maximal matrix. - OUTPUT: - - The maximal matrix. + OUTPUT: the maximal matrix EXAMPLES:: @@ -8863,18 +8824,16 @@ cdef class Matrix(Matrix1): INPUT: - - ``N`` -- a matrix. + - ``N`` -- a matrix - - ``check`` -- boolean (default: ``False``). If ``False`` - return Boolean indicating whether there exists a permutation of - rows and columns sending ``self`` to ``N`` and False otherwise. - If ``True`` return a tuple of a Boolean and a permutation mapping - ``self`` to ``N`` if such a permutation exists, and - (``False``, ``None``) if it does not. + - ``check`` -- boolean (default: ``False``); if ``False`` + return Boolean indicating whether there exists a permutation of + rows and columns sending ``self`` to ``N`` and ``False`` otherwise. + If ``True`` return a tuple of a Boolean and a permutation mapping + ``self`` to ``N`` if such a permutation exists, and + (``False``, ``None``) if it does not. - OUTPUT: - - A Boolean or a tuple of a Boolean and a permutation. + OUTPUT: a Boolean or a tuple of a Boolean and a permutation EXAMPLES:: @@ -8947,7 +8906,7 @@ cdef class Matrix(Matrix1): ##################################################################################### def _multiply_strassen(self, Matrix right, int cutoff=0): """ - Multiply self by the matrix right using a Strassen-based + Multiply ``self`` by the matrix right using a Strassen-based asymptotically fast arithmetic algorithm. ALGORITHM: Custom algorithm for arbitrary size matrices designed by @@ -8955,10 +8914,8 @@ cdef class Matrix(Matrix1): INPUT: - - - ``cutoff`` -- integer (default: 0 -- let class - decide). - + - ``cutoff`` -- integer (default: 0 -- let class + decide) EXAMPLES:: @@ -9081,7 +9038,7 @@ cdef class Matrix(Matrix1): def set_block(self, row, col, block): """ - Sets the sub-matrix of self, with upper left corner given by row, + Set the sub-matrix of self, with upper left corner given by row, col to block. EXAMPLES:: @@ -9110,7 +9067,7 @@ cdef class Matrix(Matrix1): def subdivide(self, row_lines=None, col_lines=None): r""" - Divides ``self`` into logical submatrices which can then be queried + Divide ``self`` into logical submatrices which can then be queried and extracted. If a subdivision already exists, this method forgets the @@ -9119,12 +9076,12 @@ cdef class Matrix(Matrix1): INPUT: - ``row_lines`` -- ``None``, an integer, or a list of - integers (lines at which self must be split) + integers (lines at which ``self`` must be split) - ``col_lines`` -- ``None``, an integer, or a list of - integers (columns at which self must be split) + integers (columns at which ``self`` must be split) - OUTPUT: ``None`` but changes ``self`` + OUTPUT: none but changes ``self`` .. NOTE:: @@ -9244,11 +9201,11 @@ cdef class Matrix(Matrix1): def subdivision(self, i, j): """ - Returns an immutable copy of the (i,j)th submatrix of self, + Return an immutable copy of the (i,j)th submatrix of ``self``, according to a previously set subdivision. Before a subdivision is set, the only valid arguments are (0,0) - which returns self. + which returns ``self``. EXAMPLES:: @@ -9302,7 +9259,7 @@ cdef class Matrix(Matrix1): def subdivision_entry(self, i, j, x, y): """ - Returns the x,y entry of the i,j submatrix of self. + Return the x,y entry of the i,j submatrix of ``self``. EXAMPLES:: @@ -9442,7 +9399,7 @@ cdef class Matrix(Matrix1): def subdivisions(self): """ - Returns the current subdivision of self. + Return the current subdivision of ``self``. EXAMPLES:: @@ -9471,12 +9428,12 @@ cdef class Matrix(Matrix1): def tensor_product(self, A, subdivide=True): r""" - Returns the tensor product of two matrices. + Return the tensor product of two matrices. INPUT: - ``A`` -- a matrix - - ``subdivide`` -- (default: ``True``); whether or not to return + - ``subdivide`` -- (default: ``True``) whether or not to return natural subdivisions with the matrix OUTPUT: @@ -9586,12 +9543,12 @@ cdef class Matrix(Matrix1): INPUT: - - ``density`` -- ``float`` (default: ``1``); upper bound for the - proportion of entries that are changed - - ``nonzero`` -- Bool (default: ``False``); if ``True``, then new - entries will be nonzero - - ``*args, **kwds`` -- Remaining parameters may be passed to the - ``random_element`` function of the base ring + - ``density`` -- ``float`` (default: ``1``); upper bound for the + proportion of entries that are changed + - ``nonzero`` -- boolean (default: ``False``); if ``True``, then new + entries will be nonzero + - ``*args, **kwds`` -- remaining parameters may be passed to the + ``random_element`` function of the base ring EXAMPLES: @@ -9674,7 +9631,7 @@ cdef class Matrix(Matrix1): def is_one(self): """ - Return True if this matrix is the identity matrix. + Return ``True`` if this matrix is the identity matrix. EXAMPLES:: @@ -9695,17 +9652,17 @@ cdef class Matrix(Matrix1): def is_scalar(self, a=None): """ - Return True if this matrix is a scalar matrix. + Return ``True`` if this matrix is a scalar matrix. INPUT: - - base_ring element a, which is chosen as self[0][0] if - a = None + - ``a`` -- base_ring element; chosen as ``self[0][0]`` if + ``a==None`` OUTPUT: - - whether self is a scalar matrix (in fact the scalar matrix - aI if a is input) + Whether ``self`` is a scalar matrix (in fact the scalar matrix + aI if a is input). EXAMPLES:: @@ -9745,9 +9702,7 @@ cdef class Matrix(Matrix1): """ Return ``True`` if this matrix is a diagonal matrix. - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -9775,17 +9730,15 @@ cdef class Matrix(Matrix1): return False return True - def is_triangular(self, side="lower") -> bool: + def is_triangular(self, side='lower') -> bool: """ Return ``True`` if this matrix is a triangular matrix. INPUT: - - ``side`` -- either ``"lower"`` (default) or ``"upper"`` - - OUTPUT: + - ``side`` -- either ``'lower'`` (default) or ``'upper'`` - boolean + OUTPUT: boolean EXAMPLES:: @@ -9883,7 +9836,7 @@ cdef class Matrix(Matrix1): def is_bistochastic(self, normalized=True): r""" - Returns ``True`` if this matrix is bistochastic. + Return ``True`` if this matrix is bistochastic. A matrix is said to be bistochastic if both the sums of the entries of each row and the sum of the entries of each column @@ -9931,7 +9884,7 @@ cdef class Matrix(Matrix1): def is_normal(self): r""" - Returns ``True`` if the matrix commutes with its conjugate-transpose. + Return ``True`` if the matrix commutes with its conjugate-transpose. OUTPUT: @@ -10129,7 +10082,7 @@ cdef class Matrix(Matrix1): def as_sum_of_permutations(self): r""" - Returns the current matrix as a sum of permutation matrices + Return the current matrix as a sum of permutation matrices. According to the Birkhoff-von Neumann Theorem, any bistochastic matrix can be written as a positive sum of permutation matrices, which also @@ -10179,7 +10132,7 @@ cdef class Matrix(Matrix1): def visualize_structure(self, maxsize=512): r""" - Visualize the non-zero entries + Visualize the nonzero entries. White pixels are put at positions with zero entries. If 'maxsize' is given, then the maximal dimension in either x or y direction is @@ -10191,7 +10144,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``maxsize`` -- integer (default: ``512``). Maximal dimension + - ``maxsize`` -- integer (default: `512`); maximal dimension in either x or y direction of the resulting image. If ``None`` or a maxsize larger than ``max(self.nrows(),self.ncols())`` is given the image will @@ -10307,7 +10260,7 @@ cdef class Matrix(Matrix1): def inverse(self): """ - Returns the inverse of self, without changing self. + Return the inverse of self, without changing ``self``. Note that one can use the Python inverse operator to obtain the inverse as well. @@ -10354,7 +10307,6 @@ cdef class Matrix(Matrix1): sage: ~M [t^-1 t^-2] [ 0 t^-1] - """ return ~self @@ -10431,9 +10383,7 @@ cdef class Matrix(Matrix1): r""" Return the adjugate of this matrix. - OUTPUT: - - - matrix -- the adjugate of the matrix + OUTPUT: matrix; the adjugate of the matrix EXAMPLES: @@ -10520,7 +10470,6 @@ cdef class Matrix(Matrix1): Note that this method does not utilise a lookup if the adjugate has already been computed previously, and it does not cache the result. This is all left to the method `adjugate`. - """ n = self._ncols @@ -10532,12 +10481,12 @@ cdef class Matrix(Matrix1): def QR(self, full=True): r""" - Returns a factorization of ``self`` as a unitary matrix + Return a factorization of ``self`` as a unitary matrix and an upper-triangular matrix. INPUT: - - ``full`` -- (default: ``True``); if ``True`` then the + - ``full`` -- (default: ``True``) if ``True`` then the returned matrices have dimensions as described below. If ``False`` the ``R`` matrix has no zero rows and the columns of ``Q`` are a basis for the column space of @@ -10548,7 +10497,7 @@ cdef class Matrix(Matrix1): If ``self`` is an `m\times n` matrix and ``full=True`` then this method returns a pair of matrices: `Q` is an `m\times m` unitary matrix (meaning its inverse is its conjugate-transpose) and `R` - is an `m\times n` upper-triangular matrix with non-negative entries + is an `m\times n` upper-triangular matrix with nonnegative entries on the diagonal. For a matrix of full rank this factorization is unique (due to the restriction to positive entries on the diagonal). @@ -10589,23 +10538,23 @@ cdef class Matrix(Matrix1): ....: [-1, 1, -6, -6, 5]]) sage: Q, R = A.QR() sage: Q - [ -0.4588314677411235? -0.1260506983326509? 0.3812120831224489? -0.394573711338418? -0.687440062597?] - [ -0.4588314677411235? 0.4726901187474409? -0.05198346588033394? 0.717294125164660? -0.220962877263?] - [ 0.2294157338705618? 0.6617661662464172? 0.6619227988762521? -0.180872093737548? 0.1964114464561?] - [ 0.6882472016116853? 0.1890760474989764? -0.2044682991293135? 0.096630296654307? -0.662888631790?] + [ -0.4588314677411235? -0.1260506983326509? 0.3812120831224489? -0.394573711338418? -0.6874400625964?] + [ -0.4588314677411235? 0.4726901187474409? -0.05198346588033394? 0.7172941251646595? -0.2209628772631?] + [ 0.2294157338705618? 0.6617661662464172? 0.6619227988762521? -0.1808720937375480? 0.1964114464561?] + [ 0.6882472016116853? 0.1890760474989764? -0.2044682991293135? 0.0966302966543065? -0.6628886317894?] [ -0.2294157338705618? 0.5357154679137663? -0.609939332995919? -0.536422031427112? 0.0245514308070?] sage: R [ 4.358898943540674? -0.4588314677411235? 13.07669683062202? 6.194224814505168? 2.982404540317303?] [ 0 1.670171752907625? 0.5987408170800917? -1.292019657909672? 6.207996892883057?] - [ 0 0 5.444401659866974? 5.468660610611130? -0.682716185228386?] - [ 0 0 0 1.027626039419836? -3.61930014968662?] - [ 0 0 0 0 0.02455143080702?] + [ 0 0 5.444401659866974? 5.468660610611130? -0.6827161852283857?] + [ 0 0 0 1.027626039419836? -3.619300149686620?] + [ 0 0 0 0 0.024551430807012?] sage: Q.conjugate_transpose()*Q - [1.000000000000000? 0.?e-18 0.?e-17 0.?e-15 0.?e-12] - [ 0.?e-18 1.000000000000000? 0.?e-16 0.?e-15 0.?e-12] - [ 0.?e-17 0.?e-16 1.000000000000000? 0.?e-15 0.?e-12] - [ 0.?e-15 0.?e-15 0.?e-15 1.000000000000000? 0.?e-12] - [ 0.?e-12 0.?e-12 0.?e-12 0.?e-12 1.000000000000?] + [1.000000000000000? 0.?e-18 0.?e-17 0.?e-16 0.?e-13] + [ 0.?e-18 1.000000000000000? 0.?e-17 0.?e-16 0.?e-13] + [ 0.?e-17 0.?e-17 1.000000000000000? 0.?e-16 0.?e-13] + [ 0.?e-16 0.?e-16 0.?e-16 1.000000000000000? 0.?e-13] + [ 0.?e-13 0.?e-13 0.?e-13 0.?e-13 1.0000000000000?] sage: Q * R == A True @@ -10621,24 +10570,24 @@ cdef class Matrix(Matrix1): sage: Q, R = A.QR() sage: Q [ -0.7302967433402215? 0.2070566455055649? + 0.5383472783144687?*I 0.2463049809998642? - 0.0764456358723292?*I 0.2381617683194332? - 0.1036596032779695?*I] - [ 0.0912870929175277? -0.2070566455055649? - 0.3778783780476559?*I 0.3786559533863032? - 0.1952221495524667?*I 0.701244450214469? - 0.364371165098660?*I] - [ 0.6390096504226938? + 0.0912870929175277?*I 0.1708217325420910? + 0.6677576817554466?*I -0.03411475806452072? + 0.04090198741767143?*I 0.3140171085506763? - 0.0825191718705412?*I] + [ 0.0912870929175277? -0.2070566455055649? - 0.3778783780476559?*I 0.3786559533863033? - 0.1952221495524667?*I 0.701244450214469? - 0.3643711650986595?*I] + [ 0.6390096504226938? + 0.0912870929175277?*I 0.1708217325420910? + 0.6677576817554466?*I -0.03411475806452072? + 0.04090198741767143?*I 0.3140171085506764? - 0.0825191718705412?*I] [ 0.1825741858350554? + 0.0912870929175277?*I -0.03623491296347385? + 0.0724698259269477?*I 0.8632284069415110? + 0.06322839976356195?*I -0.4499694867611521? - 0.0116119181208918?*I] sage: R [ 10.95445115010333? 0.?e-18 - 1.917028951268082?*I 5.385938482134133? - 2.190890230020665?*I -0.2738612787525831? - 2.190890230020665?*I] - [ 0 4.829596256417300? + 0.?e-17*I -0.869637911123373? - 5.864879483945125?*I 0.993871898426712? - 0.3054085521207082?*I] + [ 0 4.829596256417300? + 0.?e-18*I -0.869637911123373? - 5.864879483945125?*I 0.993871898426712? - 0.3054085521207082?*I] [ 0 0 12.00160760935814? + 0.?e-16*I -0.2709533402297273? + 0.4420629644486323?*I] [ 0 0 0 1.942963944258992? + 0.?e-16*I] sage: Q.conjugate_transpose()*Q [1.000000000000000? + 0.?e-19*I 0.?e-18 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] - [ 0.?e-17 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 1.000000000000000? + 0.?e-16*I 0.?e-16 + 0.?e-16*I] - [ 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 1.000000000000000? + 0.?e-15*I] + [ 0.?e-17 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-16 + 0.?e-16*I] + [ 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 1.000000000000000? + 0.?e-16*I] sage: Q*R - A [ 0.?e-17 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] - [ 0.?e-18 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-15 + 0.?e-15*I] + [ 0.?e-18 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [0.?e-17 + 0.?e-18*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] - [0.?e-18 + 0.?e-18*I 0.?e-18 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-15 + 0.?e-16*I] + [0.?e-18 + 0.?e-18*I 0.?e-18 + 0.?e-18*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] A rank-deficient rectangular matrix, with both values of the ``full`` keyword. :: @@ -10828,7 +10777,7 @@ cdef class Matrix(Matrix1): def _gram_schmidt_noscale(self): r""" - Performs Gram-Schmidt orthogonalization, with no scaling to unit vectors. + Perform Gram-Schmidt orthogonalization, with no scaling to unit vectors. INPUT: @@ -10836,16 +10785,14 @@ cdef class Matrix(Matrix1): The base ring of the matrix needs to have its fraction field implemented. - OUTPUT: - - Two matrices, ``Q`` and ``R`` such that if ``A`` represents ``self``: + OUTPUT: two matrices, ``Q`` and ``R`` such that if ``A`` represents ``self``: - ``A = Q*R`` - The columns of ``Q`` are an orthogonal set which spans the - column space of ``A``. - - The conjugate-transpose of ``Q`` times ``Q`` is a diagonal matrix. - - ``R`` is a full-rank matrix, that has all entries below the - main diagonal equal to zero. + column space of ``A`` + - The conjugate-transpose of ``Q`` times ``Q`` is a diagonal matrix + - ``R`` -- a full-rank matrix, that has all entries below the + main diagonal equal to zero This is basically a "reduced" QR decomposition of ``self`` with the distinction that the orthogonal column vectors of ``Q`` have @@ -10956,7 +10903,7 @@ cdef class Matrix(Matrix1): zero = F(0) Bstar = [] R = zero_matrix(F, n) - nnz = 0 # number non-zero rows in R, or number of nonzero vectors in Bstar + nnz = 0 # number nonzero rows in R, or number of nonzero vectors in Bstar for i in range(n): ortho = B[i] for j in range(nnz): @@ -10975,13 +10922,13 @@ cdef class Matrix(Matrix1): def gram_schmidt(self, orthonormal=False): r""" - Performs Gram-Schmidt orthogonalization on the rows of the matrix, + Perform Gram-Schmidt orthogonalization on the rows of the matrix, returning a new matrix and a matrix accomplishing the transformation. INPUT: - - ``self`` -- a matrix whose rows are to be orthogonalized. - - ``orthonormal`` -- (default: ``False``); if ``True`` the + - ``self`` -- a matrix whose rows are to be orthogonalized + - ``orthonormal`` -- (default: ``False``) if ``True`` the returned orthogonal vectors are unit vectors. This keyword is ignored if the matrix is over ``RDF`` or ``CDF`` and the results are always orthonormal. @@ -10994,11 +10941,11 @@ cdef class Matrix(Matrix1): - ``A = M*G`` - The rows of ``G`` are an orthogonal (resp. orthonormal) - set of vectors. + set of vectors - ``G`` times the conjugate-transpose of ``G`` is a diagonal - (resp. identity) matrix. - - The row space of ``G`` equals the row space of ``A``. - - ``M`` is a full-rank matrix with zeros above the diagonal. + (resp. identity) matrix + - The row space of ``G`` equals the row space of ``A`` + - ``M`` is a full-rank matrix with zeros above the diagonal For exact rings, any zero vectors produced (when the original vectors are linearly dependent) are not output, thus the @@ -11331,18 +11278,18 @@ cdef class Matrix(Matrix1): INPUT: - - ``base_ring`` -- Ring in which to compute the Jordan form. + - ``base_ring`` -- ring in which to compute the Jordan form - - ``sparse`` -- (default ``False``) If ``sparse=True``, return a sparse - matrix. + - ``sparse`` -- (default: ``False``) if ``sparse=True``, return a sparse + matrix - - ``subdivide`` -- (default ``True``) If ``subdivide=True``, the - subdivisions for the Jordan blocks in the matrix are shown. + - ``subdivide`` -- (default: ``True``) if ``subdivide=True``, the + subdivisions for the Jordan blocks in the matrix are shown - - ``transformation`` -- (default ``False``) If ``transformation=True``, - computes also the transformation matrix. + - ``transformation`` -- (default: ``False``) if ``transformation=True``, + computes also the transformation matrix - - ``eigenvalues`` -- (default ``None``) A complete set of roots, with + - ``eigenvalues`` -- (default: ``None``) a complete set of roots, with multiplicity, of the characteristic polynomial of `A`, encoded as a list of pairs, each having the form `(r, m)` with `r` a root and `m` its multiplicity. If this is ``None``, then Sage computes this @@ -11351,7 +11298,7 @@ cdef class Matrix(Matrix1): other rings, providing this list manually is the only way to compute Jordan normal forms. - - ``check_input`` -- (default ``True``) A Boolean specifying whether + - ``check_input`` -- boolean (default: ``True``); whether the list ``eigenvalues`` (if provided) has to be checked for correctness. Set this to ``False`` for a speedup if the eigenvalues are known to be correct. @@ -12040,7 +11987,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``base_field`` -- a new field to use for entries of the matrix. + - ``base_field`` -- a new field to use for entries of the matrix OUTPUT: @@ -12236,9 +12183,9 @@ cdef class Matrix(Matrix1): INPUT: - ``other`` -- a matrix, which should be square, and of the same size - as ``self``. + as ``self`` - - ``transformation`` -- (default: ``False``); if ``True``, the output + - ``transformation`` -- (default: ``False``) if ``True``, the output may include the change-of-basis matrix (also known as the similarity transformation). See below for an exact description. @@ -12306,7 +12253,7 @@ cdef class Matrix(Matrix1): provide a transformation. But Jordan form will require that the eigenvalues of the matrix can be represented within Sage, requiring the existence of the appropriate extension field. - When this is not possible, a ``RuntimeError`` is raised, as + When this is not possible, a :exc:`RuntimeError` is raised, as demonstrated in an example below. EXAMPLES: @@ -12328,9 +12275,9 @@ cdef class Matrix(Matrix1): sage: # needs sage.combinat sage.libs.pari sage: _, T = A.is_similar(B, transformation=True) sage: T - [ 1.0000000000000? + 0.?e-13*I 0.?e-13 + 0.?e-13*I 0.?e-13 + 0.?e-13*I] - [-0.6666666666667? + 0.?e-13*I 0.16666666666667? + 0.?e-14*I -0.8333333333334? + 0.?e-13*I] - [ 0.6666666666667? + 0.?e-13*I 0.?e-13 + 0.?e-13*I -0.333333333334? + 0.?e-13*I] + [ 1.00000000000000? + 0.?e-14*I 0.?e-14 + 0.?e-14*I 0.?e-14 + 0.?e-14*I] + [-0.66666666666667? + 0.?e-15*I 0.166666666666667? + 0.?e-15*I -0.83333333333334? + 0.?e-14*I] + [ 0.66666666666667? + 0.?e-14*I 0.?e-14 + 0.?e-14*I -0.33333333333333? + 0.?e-14*I] sage: T.change_ring(QQ) [ 1 0 0] [-2/3 1/6 -5/6] @@ -12408,7 +12355,7 @@ cdef class Matrix(Matrix1): eigenvalues of the matrix, which may not lie in the field used for entries of the matrix. In this unfortunate case, the computation of the transformation may fail with a - ``RuntimeError``, EVEN when the matrices are similar. This + :exc:`RuntimeError`, EVEN when the matrices are similar. This is not the case for matrices over the integers, rationals or algebraic numbers, since the computations are done in the algebraically closed field of algebraic numbers. @@ -12578,19 +12525,19 @@ cdef class Matrix(Matrix1): _, SA = A.jordan_form(transformation=True) _, SB = B.jordan_form(transformation=True) return (True, SB * SA.inverse()) - except (ValueError, RuntimeError, NotImplementedError): + except (ValueError, RuntimeError, NotImplementedError, TypeError): raise RuntimeError('unable to compute transformation for similar matrices') def symplectic_form(self): r""" - Find a symplectic form for self if self is an anti-symmetric, + Find a symplectic form for ``self`` if ``self`` is an anti-symmetric, alternating matrix defined over a field. Returns a pair (F, C) such that the rows of C form a symplectic - basis for self and F = C \* self \* C.transpose(). + basis for ``self`` and ``F = C \* self \* C.transpose()``. - Raises a :class:`ValueError` if not over a field, or self is not - anti-symmetric, or self is not alternating. + Raises a :exc:`ValueError` if not over a field, or ``self`` is not + anti-symmetric, or ``self`` is not alternating. Anti-symmetric means that `M = -M^t`. Alternating means that the diagonal of `M` is identically zero. @@ -12651,9 +12598,9 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` -- a square matrix over a field. + - ``self`` -- a square matrix over a field - - ``v`` -- a vector with a degree equal to the size of the matrix. + - ``v`` -- a vector with a degree equal to the size of the matrix There is no explicit error-checking, it is the responsibility of the calling routine to provide accurate input. @@ -12785,12 +12732,12 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` -- a square matrix with entries from a field. + - ``self`` -- a square matrix with entries from a field - ``v`` -- a vector with a degree equal to the size of the matrix - and entries compatible with the entries of the matrix. + and entries compatible with the entries of the matrix - - ``var`` -- (default: ``None``); if specified as a string or + - ``var`` -- (default: ``None``) if specified as a string or a generator of a polynomial ring, then this will be used to construct a polynomial reflecting a relation of linear dependence on the powers `A^iv` *and* this will cause @@ -12798,7 +12745,7 @@ cdef class Matrix(Matrix1): A generator must create polynomials with coefficients from the same field as the matrix entries. - - ``basis`` -- (default: ``echelon``); the basis for the + - ``basis`` -- (default: ``echelon``) the basis for the subspace is "echelonized" by default, but the keyword 'iterates' will return a subspace with a user basis equal to the largest linearly independent @@ -13007,16 +12954,13 @@ cdef class Matrix(Matrix1): def cholesky(self): r""" - Returns the Cholesky decomposition of a Hermitian matrix. - - INPUT: + Return the Cholesky decomposition of a Hermitian matrix. - A positive-definite matrix. Generally, the base ring for the - entries of the matrix needs to be a subfield of the algebraic - numbers (``QQbar``). Examples include the rational numbers - (``QQ``), some number fields, and real algebraic numbers and - the algebraic numbers themselves. Symbolic matrices can also - occasionally be factored. + Applies to a positive-definite matrix. Generally, the base ring for the + entries of the matrix needs to be a subfield of the algebraic numbers + (``QQbar``). Examples include the rational numbers (``QQ``), some + number fields, and real algebraic numbers and the algebraic numbers + themselves. Symbolic matrices can also occasionally be factored. OUTPUT: @@ -13029,7 +12973,7 @@ cdef class Matrix(Matrix1): where `L^\ast` is the conjugate-transpose. If the matrix is not positive-definite (for example, if it is not Hermitian) - then a ``ValueError`` results. + then a :exc:`ValueError` results. If possible, the output matrix will be over the fraction field of the base ring of the input matrix. If that fraction field @@ -13270,7 +13214,6 @@ cdef class Matrix(Matrix1): sage: all( matrix(R,[]).cholesky().is_immutable() # needs sage.rings.number_field ....: for R in (RR,CC,RDF,CDF,ZZ,QQ,AA,QQbar) ) True - """ cdef Matrix C # output matrix C = self.fetch('cholesky') @@ -13491,21 +13434,21 @@ cdef class Matrix(Matrix1): is the best choice for general routines that may call this for matrix entries of a variety of types. - - 'partial' -- each column is examined for + - ``'partial'`` -- each column is examined for the element with the largest absolute value and the - row containing this element is swapped into place. + row containing this element is swapped into place - - 'nonzero' -- the first nonzero element in a column - is located and the row with this element is used. + - ``'nonzero'`` -- the first nonzero element in a column + is located and the row with this element is used - ``format`` -- contents of output, see more discussion - below about output. + below about output - 'plu' (default) -- a triple; matrices P, L and U - such that A = P*L*U. + such that A = P*L*U - - 'compact' -- a pair; row permutation as a tuple, and the - matrices L and U combined into one matrix. + - ``'compact'`` -- a pair; row permutation as a tuple, and the + matrices L and U combined into one matrix OUTPUT: @@ -13971,14 +13914,14 @@ cdef class Matrix(Matrix1): INPUT: - ``self`` -- a matrix that is symmetric or Hermitian, - over a ring that has a fraction field implemented. + over a ring that has a fraction field implemented - ``algorithm`` -- ``'symmetric'`` or ``'hermitian'``, - according to the corresponding property of the matrix. + according to the corresponding property of the matrix - - ``check`` -- (default: ``True``); if ``True`` then + - ``check`` -- (default: ``True``) if ``True`` then performs the check that the matrix is consistent with the - ``algorithm`` keyword. + ``algorithm`` keyword OUTPUT: @@ -13998,7 +13941,7 @@ cdef class Matrix(Matrix1): the conjugate-transpose. If any leading principal submatrix is singular, then the - computation cannot be performed and a ``ValueError`` results. + computation cannot be performed and a :exc:`ValueError` results. Results are cached, and hence are immutable. Caching eliminates redundant computations across @@ -14231,16 +14174,16 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` -- a square matrix over a ring. The base ring - must have an implemented fraction field. + - ``self`` -- a square matrix over a ring; the base ring + must have an implemented fraction field - - ``algorithm`` -- default: ``'symmetric'``. Either - ``'symmetric'`` or ``'hermitian'``, according to if - the input matrix is symmetric or hermitian. + - ``algorithm`` -- (default: ``'symmetric'``) either + ``'symmetric'`` or ``'hermitian'``, according to whether + the input matrix is symmetric or hermitian - - ``check`` -- (default: ``True``); if ``True`` then + - ``check`` -- (default: ``True``) if ``True`` then performs the check that the matrix is consistent with the - ``algorithm`` keyword. + ``algorithm`` keyword OUTPUT: @@ -14261,7 +14204,7 @@ cdef class Matrix(Matrix1): If any leading principal submatrix (a square submatrix in the upper-left corner) is singular then this method will - fail with a ``ValueError``. + fail with a :exc:`ValueError`. ALGORITHM: @@ -14417,7 +14360,6 @@ cdef class Matrix(Matrix1): All of the real documentation, examples, and tests for this method can be found in the user-facing :meth:`block_ldlt` method. - """ cdef str cache_string = "_block_ldlt" if classical: @@ -14701,9 +14643,9 @@ cdef class Matrix(Matrix1): INPUT: - * ``classical`` -- (default: ``False``) whether or not to - attempt a classical non-block `LDL^{T}` factorization - with no row/column swaps. + - ``classical`` -- boolean (default: ``False``); whether or not to + attempt a classical non-block `LDL^{T}` factorization with no + row/column swaps. .. WARNING:: @@ -14725,7 +14667,7 @@ cdef class Matrix(Matrix1): With ``classical=True``, the permutation matrix `P` is always an identity matrix and the diagonal blocks are always - one-by-one. A ``ValueError`` is raised if the matrix has no + one-by-one. A :exc:`ValueError` is raised if the matrix has no classical `LDL^{T}` factorization. ALGORITHM: @@ -14972,7 +14914,6 @@ cdef class Matrix(Matrix1): sage: l,d = A.indefinite_factorization() sage: L == l and D == matrix.diagonal(d) True - """ cdef Py_ssize_t n # size of the matrices cdef Py_ssize_t i, j # loop indices @@ -15043,7 +14984,7 @@ cdef class Matrix(Matrix1): def is_positive_semidefinite(self): r""" - Returns whether or not this matrix is positive-semidefinite. + Return whether or not this matrix is positive-semidefinite. By SageMath convention, positive (semi)definite matrices must be either real symmetric or complex Hermitian. @@ -15165,7 +15106,6 @@ cdef class Matrix(Matrix1): ... ValueError: Could not see Finite Field in z2 of size 5^2 as a subring of the real or complex numbers - """ return self._is_positive_definite_or_semidefinite(True) @@ -15174,7 +15114,7 @@ cdef class Matrix(Matrix1): Determine if a matrix is positive-definite. A matrix `A` is positive definite if it - :meth:`~.Matrix.is_hermitian` and if, for every non-zero + :meth:`~.Matrix.is_hermitian` and if, for every nonzero vector `x`, .. MATH:: @@ -15192,7 +15132,7 @@ cdef class Matrix(Matrix1): INPUT: - ``self`` -- a matrix - - ``certificate`` -- (default: ``False``) return the + - ``certificate`` -- boolean (default: ``False``); return the lower-triangular and diagonal parts of the :meth:`block_ldlt` factorization when the matrix is positive-definite. Deprecated. @@ -15446,15 +15386,13 @@ cdef class Matrix(Matrix1): INPUT: + - ``f`` -- a function that is evaluated on each + element of this matrix - - ``f`` -- a function that is evaluated on each - element of this matrix. - - - ``indices`` -- whether or not to return the indices - and elements of this matrix that satisfy the function. + - ``indices`` -- whether or not to return the indices + and elements of this matrix that satisfy the function - - OUTPUT: If ``indices`` is not specified, return a + OUTPUT: if ``indices`` is not specified, return a matrix with 1 where `f` is satisfied and 0 where it is not. If ``indices`` is specified, return a dictionary containing the elements of this matrix satisfying `f`. @@ -15533,7 +15471,7 @@ cdef class Matrix(Matrix1): def conjugate(self): r""" Return the conjugate of self, i.e. the matrix whose entries are the - conjugates of the entries of self. + conjugates of the entries of ``self``. EXAMPLES:: @@ -15681,19 +15619,17 @@ cdef class Matrix(Matrix1): INPUT: + - ``self`` -- a matrix whose entries are coercible into ``CDF`` - - ``self`` -- a matrix whose entries are coercible into ``CDF`` - - - ``p`` -- one of the following options: + - ``p`` -- one of the following options: - - ``1`` -- the largest column-sum norm + - ``1`` -- the largest column-sum norm - - ``2 (default)`` -- the Euclidean norm + - ``2`` -- (default) the Euclidean norm - - ``Infinity`` -- the largest row-sum norm - - - ``'frob'`` -- the Frobenius (sum of squares) norm + - ``Infinity`` -- the largest row-sum norm + - ``'frob'`` -- the Frobenius (sum of squares) norm OUTPUT: RDF number @@ -15794,7 +15730,7 @@ cdef class Matrix(Matrix1): - ``algorithm`` -- ignored for matrices - OUTPUT: A matrix converted to a real or complex field + OUTPUT: a matrix converted to a real or complex field EXAMPLES:: @@ -15848,7 +15784,6 @@ cdef class Matrix(Matrix1): sage: M = matrix(3, [1,1,1,1,0,0,0,1,0]) sage: A, B = M.diagonalization(QQbar) # needs sage.rings.number_field sage: _ = A.n() # needs sage.rings.number_field - """ from sage.rings.real_mpfr import RealField from sage.rings.complex_mpfr import ComplexField @@ -15931,7 +15866,7 @@ cdef class Matrix(Matrix1): def exp(self): r""" - Calculate the exponential of this matrix X, which is the matrix + Calculate the exponential of this matrix X, which is the matrix. .. MATH:: @@ -15966,7 +15901,7 @@ cdef class Matrix(Matrix1): sage: a.exp() # needs sage.symbolic [ 1/11882424341266*((11*sqrt(227345670387496707609) + 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) + 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) 445243650/75781890129165569203*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] [ 10000/53470909535697*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) -1/11882424341266*((11*sqrt(227345670387496707609) - 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) - 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] - sage: a.change_ring(RDF).exp() # rel tol 1e-14 # needs sage.symbolic + sage: a.change_ring(RDF).exp() # rel tol 6e-14 # needs sage.symbolic [42748127.31532951 7368259.244159399] [234538976.1381042 40426191.45156228] @@ -16048,7 +15983,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``transformation`` -- a boolean (default: ``True``); whether the + - ``transformation`` -- boolean (default: ``True``); whether the matrices `U` and `V` should be returned - ``integral`` -- a subring of the base ring, boolean or ``None`` @@ -16060,7 +15995,7 @@ cdef class Matrix(Matrix1): by the denominator must map the entries into the subring; in this case the transformation matrices will have entries in this subring. - - ``exact`` -- a boolean (default: ``True``), only used for local rings/fields. + - ``exact`` -- boolean (default: ``True``); only used for local rings/fields. See ``LOCAL RINGS`` for more details. OUTPUT: @@ -16213,7 +16148,6 @@ cdef class Matrix(Matrix1): [ O(2^4) 3 + O(2^4) 11 + O(2^4)] [ 0 0 1 + O(2^5)] ) - """ R = self.base_ring() if hasattr(R, '_matrix_smith_form'): @@ -16274,11 +16208,9 @@ cdef class Matrix(Matrix1): INPUT: - - ``i`` -- an integer - - OUTPUT: + - ``i`` -- integer - An ideal on the base ring. + OUTPUT: an ideal on the base ring EXAMPLES:: @@ -16353,7 +16285,6 @@ cdef class Matrix(Matrix1): sage: M.smith_form()[0] [ 1 0 0] [ 0 x - 1 0] - """ R = self.base_ring() if not R.is_exact(): @@ -16412,7 +16343,7 @@ cdef class Matrix(Matrix1): Transform the matrix in place to hermite normal form and optionally return the transformation matrix. - The matrix is assumed to be over an Euclidean domain. In particular, + The matrix is assumed to be over a Euclidean domain. In particular, ``xgcd()`` method should be available for the elements of the domain. INPUT: @@ -16545,17 +16476,17 @@ cdef class Matrix(Matrix1): INPUT: - - ``include_zero_rows`` -- bool (default: ``True``); if False - the zero rows in the output matrix are deleted. + - ``include_zero_rows`` -- boolean (default: ``True``); if ``False`` + the zero rows in the output matrix are deleted - - ``transformation`` -- bool (default: ``False``) a matrix U such that U*self == H. + - ``transformation`` -- boolean (default: ``False``); a matrix `U` such + that ``U*self == H`` OUTPUT: - - matrix H - - (optional) transformation matrix U such that U*self == H, possibly with zero - rows deleted... - + - matrix H + - (optional) transformation matrix `U` such that ``U*self == H``, + possibly with zero rows deleted EXAMPLES:: @@ -16665,7 +16596,6 @@ cdef class Matrix(Matrix1): sage: M = A.span([x*L.0]) sage: M.0 in L True - """ if self.ncols() == 0: return self.new_matrix(self.nrows(), self.nrows(), 1), self, [] @@ -16729,11 +16659,11 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` -- a square matrix over an exact field. + - ``self`` -- a square matrix over an exact field - ``basis`` -- (default; ``True``); controls whether or not to compute a change-of-basis matrix (also called a transformation - matrix). + matrix) OUTPUT: @@ -16914,7 +16844,7 @@ cdef class Matrix(Matrix1): nonzero = j break if (nonzero != -1): - # swap column wih nonzero entry just outside block + # swap column with nonzero entry just outside block if nonzero != c+1: Z.swap_columns(c+1, nonzero) Z.swap_rows(c+1, nonzero) @@ -16972,12 +16902,12 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` -- a square matrix with entries from an exact field. + - ``self`` -- a square matrix with entries from an exact field - - ``transformation`` -- (default: ``False``); if ``True`` return a - change-of-basis matrix relating the matrix and its ZigZag form. + - ``transformation`` -- (default: ``False``) if ``True`` return a + change-of-basis matrix relating the matrix and its ZigZag form - - ``subdivide`` -- (default: ``True``); if ``True`` the ZigZag + - ``subdivide`` -- (default: ``True``) if ``True`` the ZigZag form matrix is subdivided according to the companion matrices described in the output section below. @@ -17169,7 +17099,7 @@ cdef class Matrix(Matrix1): sage: A.eigenvalues() Traceback (most recent call last): ... - NotImplementedError: algebraic closures of finite fields are only implemented for prime fields + TypeError: no canonical coercion from Finite Field in a of size 5^4 to Finite Field in z4 of size 5^4 Subdivisions are optional. :: @@ -17243,22 +17173,22 @@ cdef class Matrix(Matrix1): def rational_form(self, format='right', subdivide=True): r""" - Returns the rational canonical form, also known as Frobenius form. + Return the rational canonical form, also known as Frobenius form. INPUT: - - ``self`` -- a square matrix with entries from an exact field. + - ``self`` -- a square matrix with entries from an exact field - - ``format`` -- (default: 'right'); one of 'right', 'bottom', - 'left', 'top' or 'invariants'. The first four will cause a - matrix to be returned with companion matrices dictated by the + - ``format`` -- (default: ``'right'``) one of ``'right'``, ``'bottom'``, + ``'left'``, ``'top'`` or ``'invariants'``. The first four will cause + a matrix to be returned with companion matrices dictated by the keyword. The value 'invariants' will cause a list of lists to be returned, where each list contains coefficients of a polynomial associated with a companion matrix. - - ``subdivide`` -- (default: 'True'); if 'True' and a matrix is + - ``subdivide`` -- (default: ``'True'``) if 'True' and a matrix is returned, then it contains subdivisions delineating the - companion matrices along the diagonal. + companion matrices along the diagonal OUTPUT: @@ -17531,7 +17461,7 @@ cdef class Matrix(Matrix1): sage: A.eigenvalues() Traceback (most recent call last): ... - NotImplementedError: algebraic closures of finite fields are only implemented for prime fields + TypeError: no canonical coercion from Finite Field in a of size 7^2 to Finite Field in z2 of size 7^2 Companion matrices may be selected as any one of four different types. See the documentation for the companion matrix constructor, @@ -17685,10 +17615,10 @@ cdef class Matrix(Matrix1): INPUT: - - ``K1`` -- a polyhedral closed convex cone. + - ``K1`` -- a polyhedral closed convex cone - ``K2`` -- (default: ``K1``) the codomain cone; this matrix is - a positive operator if the image of ``K1`` is a subset of ``K2``. + a positive operator if the image of ``K1`` is a subset of ``K2`` OUTPUT: @@ -17856,7 +17786,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``K`` -- a polyhedral closed convex cone. + - ``K`` -- a polyhedral closed convex cone OUTPUT: @@ -17999,7 +17929,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``K`` -- a polyhedral closed convex cone. + - ``K`` -- a polyhedral closed convex cone OUTPUT: @@ -18095,7 +18025,6 @@ cdef class Matrix(Matrix1): ... ValueError: The base ring of the matrix is neither symbolic nor exact. - """ return (-self).is_cross_positive_on(K) @@ -18120,7 +18049,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``K`` -- a polyhedral closed convex cone. + - ``K`` -- a polyhedral closed convex cone OUTPUT: @@ -18271,7 +18200,7 @@ cdef class Matrix(Matrix1): - ``self`` -- the Gram matrix of a quadratic form or of a lattice equipped with a bilinear form - - ``flag`` -- an optional flag passed to ``qflllgram``. + - ``flag`` -- an optional flag passed to ``qflllgram`` According to :pari:`qflllgram`'s documentation the options are: - ``0`` -- (default), assume that ``self`` has either exact @@ -18324,7 +18253,7 @@ cdef class Matrix(Matrix1): [ 0 -1] [ 1 0] - However, it might fail for others, either raising a ``ValueError``:: + However, it might fail for others, either raising a :exc:`ValueError`:: sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() # needs sage.libs.pari Traceback (most recent call last): @@ -18380,7 +18309,7 @@ cdef class Matrix(Matrix1): @property def T(self): r""" - Returns the transpose of a matrix. + Return the transpose of a matrix. EXAMPLES:: @@ -18397,7 +18326,7 @@ cdef class Matrix(Matrix1): @property def C(self): r""" - Returns the conjugate matrix. + Return the conjugate matrix. EXAMPLES:: @@ -18408,14 +18337,13 @@ cdef class Matrix(Matrix1): [ -3 5 + 3*I 7 + 4*I] [ 7 - 3*I -1 - 6*I 3 - 5*I] [ 3 - 3*I -3 - 6*I 5 - 1*I] - """ return self.conjugate() @property def H(self): r""" - Returns the conjugate-transpose (Hermitian) matrix. + Return the conjugate-transpose (Hermitian) matrix. EXAMPLES:: @@ -18704,7 +18632,7 @@ def decomp_seq(v): def _choose(Py_ssize_t n, Py_ssize_t t): """ - Returns all possible sublists of length t from range(n) + Return all possible sublists of length `t` from ``range(n)``. Based on algorithm T from Knuth's taocp part 4: 7.2.1.3 p.5 This function replaces the one based on algorithm L because it is @@ -18824,7 +18752,7 @@ def _jordan_form_vector_in_difference(V, W): def _matrix_power_symbolic(A, n): r""" - Return the symbolic `n`-th power `A^n` of the matrix `A` + Return the symbolic `n`-th power `A^n` of the matrix `A`. This function implements the computation of `A^n` for symbolic `n`, relying on the Jordan normal form of `A`, available for exact rings diff --git a/src/sage/matrix/matrix_cdv.pyx b/src/sage/matrix/matrix_cdv.pyx index 7a6b1887518..238d875844f 100644 --- a/src/sage/matrix/matrix_cdv.pyx +++ b/src/sage/matrix/matrix_cdv.pyx @@ -36,7 +36,7 @@ cpdef hessenbergize_cdvf(Matrix_generic_dense H): TESTS:: sage: # needs sage.rings.padics - sage: K = Qp(5, print_mode="digits", prec=5) + sage: K = Qp(5, print_mode='digits', prec=5) sage: H = matrix(K, 3, 3, range(9)) sage: H [ 0 ...00001 ...00002] diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 07857217309..b8b193145c7 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -95,7 +95,7 @@ cdef Matrix_generic_dense acb_mat_to_matrix(acb_mat_t source, Parent CIF): - ``source`` -- an ``acb_mat_t`` - - ``precision`` -- a positive integer. + - ``precision`` -- positive integer OUTPUT: @@ -181,7 +181,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring EXAMPLES: @@ -264,7 +264,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): - ``j`` -- column - - ``x`` -- must be ComplexBall! The value to set self[i,j] to. + - ``x`` -- must be ComplexBall! The value to set ``self[i,j]`` to. EXAMPLES:: @@ -650,7 +650,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): TESTS:: - sage: mat.charpoly(algorithm="hessenberg") + sage: mat.charpoly(algorithm='hessenberg') x^5 + ([-1.8 +/- 0.04...])*x^4 + ([0.3 +/- 0.08...])*x^3 + ([+/- 0.0...])*x^2 + ([+/- ...e-4])*x + [+/- ...e-6] sage: mat.charpoly('y') diff --git a/src/sage/matrix/matrix_cyclo_dense.pyx b/src/sage/matrix/matrix_cyclo_dense.pyx index 4fdfe5f1118..f32d738df0d 100644 --- a/src/sage/matrix/matrix_cyclo_dense.pyx +++ b/src/sage/matrix/matrix_cyclo_dense.pyx @@ -119,7 +119,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring EXAMPLES: @@ -161,7 +161,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, value): """ - Set the ij-th entry of self. + Set the ij-th entry of ``self``. WARNING: This function does no bounds checking whatsoever, as the name suggests. It also assumes certain facts about the @@ -288,7 +288,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j): """ - Get the ij-th of self. + Get the ij-th of ``self``. WARNING: As the name suggests, expect segfaults if i,j are out of bounds!! This is for internal use only. @@ -433,8 +433,9 @@ cdef class Matrix_cyclo_dense(Matrix_dense): underlying data and pickle version. OUTPUT: - data -- output of pickle - version -- int + + - data; output of pickle + - version; integer EXAMPLES:: @@ -451,10 +452,11 @@ cdef class Matrix_cyclo_dense(Matrix_dense): Called when unpickling matrices. INPUT: - data -- a string - version -- int - This modifies self. + - ``data`` -- string + - ``version`` -- integer + + This modifies ``self``. EXAMPLES:: @@ -493,10 +495,11 @@ cdef class Matrix_cyclo_dense(Matrix_dense): Return the sum of two dense cyclotomic matrices. INPUT: - self, right -- dense cyclotomic matrices with the same - parents - OUTPUT: - a dense cyclotomic matrix + + - ``self``, ``right`` -- dense cyclotomic matrices with the same + parents + + OUTPUT: a dense cyclotomic matrix EXAMPLES:: @@ -521,10 +524,11 @@ cdef class Matrix_cyclo_dense(Matrix_dense): Return the difference of two dense cyclotomic matrices. INPUT: - self, right -- dense cyclotomic matrices with the same - parent - OUTPUT: - a dense cyclotomic matrix + + - ``self``, ``right`` -- dense cyclotomic matrices with the same + parent + + OUTPUT: a dense cyclotomic matrix EXAMPLES:: @@ -589,16 +593,17 @@ cdef class Matrix_cyclo_dense(Matrix_dense): Return the product of two cyclotomic dense matrices. INPUT: - self, right -- cyclotomic dense matrices with compatible - parents (same base ring, and compatible - dimensions for matrix multiplication). - OUTPUT: - cyclotomic dense matrix + - ``self``, ``right`` -- cyclotomic dense matrices with compatible + parents (same base ring, and compatible dimensions for matrix + multiplication) + + OUTPUT: cyclotomic dense matrix ALGORITHM: - Use a multimodular algorithm that involves multiplying the - two matrices modulo split primes. + + Use a multimodular algorithm that involves multiplying the two matrices + modulo split primes. EXAMPLES:: @@ -682,7 +687,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): """ Return hash of an immutable matrix. - This raises a :class:`TypeError` if input matrix is mutable. + This raises a :exc:`TypeError` if input matrix is mutable. EXAMPLES: @@ -715,7 +720,6 @@ cdef class Matrix_cyclo_dense(Matrix_dense): sage: A.set_immutable() sage: A.__hash__() # random 2347601038649299176 - """ return hash(self._matrix) @@ -797,8 +801,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): """ Return the negative of this matrix. - OUTPUT: - matrix + OUTPUT: matrix EXAMPLES:: @@ -858,7 +861,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def _rational_matrix(self): """ - Return the underlying rational matrix corresponding to self. + Return the underlying rational matrix corresponding to ``self``. EXAMPLES:: @@ -883,9 +886,8 @@ cdef class Matrix_cyclo_dense(Matrix_dense): """ Return the denominator of the entries of this matrix. - OUTPUT: - integer -- the smallest integer d so that d * self has - entries in the ring of integers + OUTPUT: integer; the smallest integer `d` so that ``d * self`` has + entries in the ring of integers EXAMPLES:: @@ -901,7 +903,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def coefficient_bound(self): r""" Return an upper bound for the (complex) absolute values of all - entries of self with respect to all embeddings. + entries of ``self`` with respect to all embeddings. Use ``self.height()`` for a sharper bound. @@ -942,10 +944,10 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def height(self): r""" - Return the height of self. + Return the height of ``self``. If we let `a_{ij}` be the `i,j` entry of self, then we define - the height of self to be + the height of ``self`` to be `\max_v \max_{i,j} |a_{ij}|_v`, @@ -983,20 +985,18 @@ cdef class Matrix_cyclo_dense(Matrix_dense): INPUT: - - ``col`` -- Integer, indicating the column; must be coercable to - ``int``, and this must lie between 0 (inclusive) and - ``self._ncols`` (exclusive), since no bounds-checking is performed - - ``nump1`` -- Integer, numerator bound plus one - - ``denp1`` -- Integer, denominator bound plus one - - ``distribution`` -- ``None`` or '1/n' (default: ``None``); if '1/n' - then ``num_bound``, ``den_bound`` are ignored and numbers are chosen - using the GMP function ``mpq_randomize_entry_recip_uniform`` - - ``nonzero`` -- Bool (default: ``False``); whether the new entries - are forced to be non-zero - - OUTPUT: + - ``col`` -- integer indicating the column; must be coercible to + ``int``, and this must lie between 0 (inclusive) and + ``self._ncols`` (exclusive), since no bounds-checking is performed + - ``nump1`` -- integer; numerator bound plus one + - ``denp1`` -- integer; denominator bound plus one + - ``distribution`` -- ``None`` or '1/n' (default: ``None``); if '1/n' + then ``num_bound``, ``den_bound`` are ignored and numbers are chosen + using the GMP function ``mpq_randomize_entry_recip_uniform`` + - ``nonzero`` -- boolean (default: ``False``); whether the new entries + are forced to be nonzero - - None, the matrix is modified in-space + OUTPUT: none, the matrix is modified in-space WARNING: @@ -1117,7 +1117,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): while col_is_zero: self._randomize_rational_column_unsafe(col, B.value, C.value, distribution) - # Check whether the new column is non-zero + # Check whether the new column is nonzero for i in range(self._degree): if not fmpq_is_zero(fmpq_mat_entry(self._matrix._matrix, i, col)): col_is_zero = False @@ -1130,7 +1130,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): while col_is_zero: self._randomize_rational_column_unsafe(col, B.value, C.value, distribution) - # Check whether the new column is non-zero + # Check whether the new column is nonzero for i in range(self._degree): if not fmpq_is_zero(fmpq_mat_entry(self._matrix._matrix, i, col)): col_is_zero = False @@ -1219,26 +1219,24 @@ cdef class Matrix_cyclo_dense(Matrix_dense): return M - def charpoly(self, var='x', algorithm="multimodular", proof=None): + def charpoly(self, var='x', algorithm='multimodular', proof=None): r""" Return the characteristic polynomial of self, as a polynomial over the base ring. INPUT: - - algorithm - - - 'multimodular' (default): reduce modulo primes, compute charpoly - mod p, and lift (very fast) - - 'pari': use pari (quite slow; comparable to Magma v2.14 though) - - 'hessenberg': put matrix in Hessenberg form (double dog slow) + - ``algorithm`` -- options: - - proof -- bool (default: None) proof flag determined by global linalg - proof. + - ``'multimodular'`` (default): reduce modulo primes, compute + charpoly mod p, and lift (very fast) + - ``'pari'``: use pari (quite slow; comparable to Magma v2.14 though) + - ``'hessenberg'``: put matrix in Hessenberg form (double dog slow) - OUTPUT: + - ``proof`` -- boolean (default: ``None``); proof flag determined by + global linalg proof - polynomial + OUTPUT: polynomial EXAMPLES:: @@ -1310,12 +1308,12 @@ cdef class Matrix_cyclo_dense(Matrix_dense): This is used internally by the multimodular charpoly algorithm. INPUT: - p -- a prime that splits completely - OUTPUT: - matrix over GF(p) whose columns correspond to the entries - of all the characteristic polynomials of the reduction of self modulo all - the primes over p. + - ``p`` -- a prime that splits completely + + OUTPUT: matrix over GF(p) whose columns correspond to the entries + of all the characteristic polynomials of the reduction of ``self`` + modulo all the primes over `p` EXAMPLES:: @@ -1347,15 +1345,15 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def _charpoly_multimodular(self, var='x', proof=None): """ - Compute the characteristic polynomial of self using a + Compute the characteristic polynomial of ``self`` using a multimodular algorithm. INPUT: - proof -- bool (default: global flag); if False, compute - using primes `p_i` until the lift modulo all - primes up to `p_i` is the same as the lift modulo - all primes up to `p_{i+3}` or the bound is - reached. + + - ``proof`` -- boolean (default: global flag); if ``False``, compute + using primes `p_i` until the lift modulo all primes up to `p_i` is + the same as the lift modulo all primes up to `p_{i+3}` or the bound + is reached EXAMPLES:: @@ -1429,15 +1427,17 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def _reductions(self, p): """ Compute the reductions modulo all primes over p of denom*self, - where denom is the denominator of self. + where denom is the denominator of ``self``. INPUT: - p -- a prime that splits completely in the base cyclotomic field. + + - ``p`` -- a prime that splits completely in the base cyclotomic field OUTPUT: - list -- of r distinct matrices modulo p, where r is - the degree of the cyclotomic base field. - denom -- an integer + + - ``list`` -- of r distinct matrices modulo p, where r is + the degree of the cyclotomic base field + - ``denom`` -- integer EXAMPLES:: @@ -1473,13 +1473,14 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def _reduction_matrix(self, p): """ INPUT: - p -- a prime that splits completely in the base field. + + - ``p`` -- a prime that splits completely in the base field OUTPUT: - -- Matrix over GF(p) whose action from the left - gives the map from O_K to GF(p) x ... x GF(p) - given by reducing modulo all the primes over p. - -- inverse of this matrix + + - Matrix over GF(p) whose action from the left gives the map from O_K + to GF(p) x ... x GF(p) given by reducing modulo all the primes over p + - inverse of this matrix EXAMPLES:: @@ -1637,13 +1638,11 @@ cdef class Matrix_cyclo_dense(Matrix_dense): INPUT: - - num_primes -- number of primes to work modulo + - ``num_primes`` -- number of primes to work modulo - - height_guess -- guess for the height of the echelon form of self - - OUTPUT: + - ``height_guess`` -- guess for the height of the echelon form of self - - matrix in reduced row echelon form + OUTPUT: matrix in reduced row echelon form EXAMPLES:: @@ -1790,21 +1789,23 @@ cdef class Matrix_cyclo_dense(Matrix_dense): def _echelon_form_one_prime(self, p): """ - Find the echelon form of self mod the primes dividing p. Return + Find the echelon form of ``self`` mod the primes dividing p. Return the rational matrix representing this lift. If the pivots of the reductions mod the primes over p are different, then no such lift - exists, and we raise a ValueError. If this happens, then the - denominator of the echelon form of self is divisible by p. (Note + exists, and we raise a :exc:`ValueError`. If this happens, then the + denominator of the echelon form of ``self`` is divisible by p. (Note that the converse need not be true.) INPUT: - p -- a prime that splits completely in the cyclotomic base field. - OUTPUT: - matrix -- Lift via CRT of the echelon forms of self modulo - each of the primes over p. - tuple -- the tuple of pivots for the echelon form of self mod the - primes dividing p + - ``p`` -- a prime that splits completely in the cyclotomic base field + + OUTPUT: tuple of + + - ``matrix`` -- Lift via CRT of the echelon forms of ``self`` modulo + each of the primes over p. + - ``tuple`` -- the tuple of pivots for the echelon form of ``self`` mod the + primes dividing p EXAMPLES:: @@ -1869,7 +1870,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): INPUT: - ``A`` -- a matrix - - ``subdivide`` -- (default: ``True``) whether or not to return + - ``subdivide`` -- boolean (default: ``True``); whether or not to return natural subdivisions with the matrix OUTPUT: diff --git a/src/sage/matrix/matrix_dense.pyx b/src/sage/matrix/matrix_dense.pyx index a954dde39d2..f26078bde7e 100644 --- a/src/sage/matrix/matrix_dense.pyx +++ b/src/sage/matrix/matrix_dense.pyx @@ -5,7 +5,7 @@ TESTS:: sage: R. = QQ[] sage: m = matrix(R,2,[0,a,b,b^2]) - sage: TestSuite(m).run(skip="_test_minpoly") + sage: TestSuite(m).run(skip='_test_minpoly') """ cimport sage.matrix.matrix as matrix @@ -97,7 +97,7 @@ cdef class Matrix_dense(matrix.Matrix): def transpose(self): """ - Returns the transpose of self, without changing self. + Return the transpose of ``self``, without changing ``self``. EXAMPLES: We create a matrix, compute its transpose, and note that the original matrix is not changed. @@ -147,7 +147,7 @@ cdef class Matrix_dense(matrix.Matrix): def antitranspose(self): """ - Returns the antitranspose of self, without changing self. + Return the antitranspose of ``self``, without changing ``self``. EXAMPLES:: @@ -171,19 +171,19 @@ cdef class Matrix_dense(matrix.Matrix): [4|1] [3|0] """ - (nc, nr) = (self.ncols(), self.nrows()) + nc, nr = self.ncols(), self.nrows() cdef Matrix_dense atrans - atrans = self.new_matrix(nrows = nc, ncols = nr, + atrans = self.new_matrix(nrows=nc, ncols=nr, copy=False, coerce=False) - cdef Py_ssize_t i,j - cdef Py_ssize_t ri,rj # reversed i and j + cdef Py_ssize_t i, j + cdef Py_ssize_t ri, rj # reversed i and j rj = nc for j from 0 <= j < nc: ri = nr - rj = rj-1 + rj -= 1 for i from 0 <= i < nr: - ri = ri-1 - atrans.set_unsafe(j , i, self.get_unsafe(ri,rj)) + ri -= 1 + atrans.set_unsafe(j, i, self.get_unsafe(ri, rj)) if self._subdivisions is not None: row_divs, col_divs = self.subdivisions() @@ -220,7 +220,7 @@ cdef class Matrix_dense(matrix.Matrix): def _elementwise_product(self, right): r""" - Returns the elementwise product of two dense + Return the elementwise product of two dense matrices with identical base rings. This routine assumes that ``self`` and ``right`` @@ -256,8 +256,8 @@ cdef class Matrix_dense(matrix.Matrix): prod = self.new_matrix(nr, nc, copy=False, coerce=False) for r in range(nr): for c in range(nc): - entry = self.get_unsafe(r,c)*other.get_unsafe(r,c) - prod.set_unsafe(r,c,entry) + entry = self.get_unsafe(r, c)*other.get_unsafe(r, c) + prod.set_unsafe(r, c, entry) return prod def _derivative(self, var=None, R=None): diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index 23415be73ac..714edb22b32 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -13,7 +13,6 @@ AUTHORS: - William Stein: many bug fixes and touch ups. - EXAMPLES:: sage: b = Mat(RDF,2,3).basis() @@ -171,7 +170,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): cpdef _sub_(self, right): """ - Return self - right + Return ``self - right``. EXAMPLES:: @@ -341,7 +340,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): import scipy import scipy.linalg from numpy.linalg import LinAlgError - try: ## Standard error reporting for Sage. + try: # Standard error reporting for Sage. M._matrix_numpy = scipy.linalg.inv(self._matrix_numpy) except LinAlgError: raise ZeroDivisionError("input matrix must be nonsingular") @@ -373,7 +372,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``p`` -- (default: 'frob'); controls which norm is used + - ``p`` -- (default: ``'frob'``) controls which norm is used to compute the condition number, allowable values are 'frob' (for the Frobenius norm), integers -2, -1, 1, 2, positive and negative infinity. See output discussion @@ -538,7 +537,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): p = -numpy.inf elif p == 'frob': p = 'fro' - elif p == 'sv' : + elif p == 'sv': p = None else: try: @@ -560,7 +559,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``p`` -- (default: 2); controls which norm is computed, + - ``p`` -- (default: 2) controls which norm is computed, allowable values are 'frob' (for the Frobenius norm), integers -2, -1, 1, 2, positive and negative infinity. See output discussion for specifics. @@ -697,7 +696,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``eps`` -- (default: ``None``); the largest number which + - ``eps`` -- (default: ``None``) the largest number which will be considered to be zero. May also be set to the string 'auto'. See the discussion below. @@ -712,10 +711,10 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): the list is the minimum of the row count and column count for the matrix. - The number of non-zero singular values will be the rank of the + The number of nonzero singular values will be the rank of the matrix. However, as a numerical matrix, it is impossible to control the difference between zero entries and very small - non-zero entries. As an informed consumer it is up to you + nonzero entries. As an informed consumer it is up to you to use the output responsibly. We will do our best, and give you the tools to work with the output, but we cannot give you a guarantee. @@ -740,7 +739,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES: Singular values close to zero have trailing digits that may vary - on different hardware. For exact matrices, the number of non-zero + on different hardware. For exact matrices, the number of nonzero singular values will equal the rank of the matrix. So for some of the doctests we round the small singular values that ideally would be zero, to control the variability across hardware. @@ -865,7 +864,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): if scipy is None: import scipy eps = 2*max(self._nrows, self._ncols)*numpy.finfo(float).eps*sv[0] eps = RDF(eps) - # locate non-zero entries + # locate nonzero entries rank = 0 while rank < diag and sv[rank] > eps: rank = rank + 1 @@ -897,11 +896,11 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): - ``A = P*L*U`` - ``P`` is a square permutation matrix, of size `m\times m`, so is all zeroes, but with exactly a single one in each - row and each column. + row and each column - ``L`` is lower-triangular, square of size `m\times m`, - with every diagonal entry equal to one. + with every diagonal entry equal to one - ``U`` is upper-triangular with size `m\times n`, i.e. - entries below the "diagonal" are all zero. + entries below the "diagonal" are all zero The computed decomposition is cached and returned on subsequent calls, thus requiring the results to be immutable. @@ -909,7 +908,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Effectively, ``P`` permutes the rows of ``A``. Then ``L`` can be viewed as a sequence of row operations on this matrix, where each operation is adding a multiple of a row to a - subsequent row. There is no scaling (thus 1's on the diagonal + subsequent row. There is no scaling (thus 1s on the diagonal of ``L``) and no row-swapping (``P`` does that). As a result ``U`` is close to being the result of Gaussian-elimination. However, round-off errors can make it hard to determine @@ -1065,7 +1064,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): solved; if ``algorithm`` is ``'symmetric'`` or ``'hermitian'``, `B` must be real symmetric or hermitian positive definite, respectively - - ``algorithm`` -- default: ``'default'`` + - ``algorithm`` -- (default: ``'default'``) - ``'default'`` -- applicable to any matrix with double-precision floating point entries. @@ -1085,7 +1084,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): This algorithm can be significantly faster than the ``'default'`` algorithm. - - ``'tol'`` -- (default: ``None``); if set to a value other than + - ``'tol'`` -- (default: ``None``) if set to a value other than ``None``, this is interpreted as a small real number used to aid in grouping eigenvalues that are numerically similar, but is ignored when ``homogeneous`` is set. See the output description for more @@ -1287,7 +1286,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): from sage.rings.real_double import RDF from sage.rings.complex_double import CDF if isinstance(other, str): - # for backward compatibilty, allow algorithm to be passed as first + # for backward compatibility, allow algorithm to be passed as first # positional argument and tol as second positional argument from sage.misc.superseded import deprecation deprecation(29243, '"algorithm" and "tol" should be used as ' @@ -1440,7 +1439,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): The SciPy routines used for these computations produce eigenvectors normalized to have length 1, but on different hardware they may vary by a complex sign. So for doctests we have normalized output by forcing - their eigenvectors to have their first non-zero entry equal to one. + their eigenvectors to have their first nonzero entry equal to one. ALGORITHM: @@ -1514,7 +1513,6 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): ....: spectrum[i][1][0] = matrix(CDF, spectrum[i][1]).echelon_form()[0] sage: spectrum [(1.0*I, [(1.0, 0.0)], 1), (1.0, [(0.0, 1.0)], 1)] - """ if not self.is_square(): raise ArithmeticError("self must be a square matrix") @@ -1598,7 +1596,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): The SciPy routines used for these computations produce eigenvectors normalized to have length 1, but on different hardware they may vary by a complex sign. So for doctests we have normalized output by forcing - their eigenvectors to have their first non-zero entry equal to one. + their eigenvectors to have their first nonzero entry equal to one. ALGORITHM: @@ -1834,7 +1832,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): def conjugate(self): r""" Return the conjugate of this matrix, i.e. the matrix whose entries are - the conjugates of the entries of self. + the conjugates of the entries of ``self``. EXAMPLES:: @@ -1871,22 +1869,22 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): r""" Return the singular value decomposition of this matrix. - The U and V matrices are not unique and may be returned with different - values in the future or on different systems. The S matrix is unique + The `U` and `V` matrices are not unique and may be returned with different + values in the future or on different systems. The `S` matrix is unique and contains the singular values in descending order. The computed decomposition is cached and returned on subsequent calls. INPUT: - - A -- a matrix + - ``A`` -- a matrix OUTPUT: - - U, S, V -- immutable matrices such that `A = U*S*V.conj().transpose()` - where U and V are orthogonal and S is zero off of the diagonal. + ``U, S, V`` -- immutable matrices such that ``A = U*S*V.conj().transpose()`` + where `U` and `V` are orthogonal and `S` is zero off of the diagonal - Note that if self is m-by-n, then the dimensions of the + Note that if ``self`` is m-by-n, then the dimensions of the matrices that this returns are (m,m), (m,n), and (n, n). .. NOTE:: @@ -2012,9 +2010,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Return a factorization into a unitary matrix and an upper-triangular matrix. - INPUT: - - Any matrix over ``RDF`` or ``CDF``. + Applies to any matrix over ``RDF`` or ``CDF``. OUTPUT: @@ -2215,13 +2211,13 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``tol`` -- (default: ``1e-12``); the largest value of the + - ``tol`` -- (default: ``1e-12``) the largest value of the absolute value of the difference between two matrix entries - for which they will still be considered equal. + for which they will still be considered equal - - ``algorithm`` -- (default: 'orthonormal'); set to 'orthonormal' - for a stable procedure and set to 'naive' for a fast - procedure. + - ``algorithm`` -- (default: ``'orthonormal'``) set to + ``'orthonormal'`` for a stable procedure and set to 'naive' for a + fast procedure OUTPUT: @@ -2345,7 +2341,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): """ if self.dimensions() == (0,0): # The "orthonormal" algorithm would otherwise fail in this - # corner case. Returning `True` is consistent with the + # corner case. Returning ``True`` is consistent with the # other implementations of this method. return True @@ -2405,11 +2401,11 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``tol`` -- (default: ``1e-12``); the largest value of the + - ``tol`` -- (default: ``1e-12``) the largest value of the absolute value of the difference between two matrix entries - for which they will still be considered equal. + for which they will still be considered equal - - ``skew`` -- (default: ``False``); Specifies the type of the + - ``skew`` -- (default: ``False``) specifies the type of the test. Set to ``True`` to check whether the matrix is skew-Hermitian. @@ -2484,7 +2480,6 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): AUTHOR: - Rob Beezer (2011-03-30) - """ import sage.rings.complex_double global numpy @@ -2524,12 +2519,12 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``tol`` -- (default: ``1e-12``); the largest value of the + - ``tol`` -- (default: ``1e-12``) the largest value of the absolute value of the difference between two matrix entries for which they will still be considered equal. - - ``algorithm`` -- string (default: "naive"); either "naive" - or "orthonormal" + - ``algorithm`` -- string (default: ``'naive'``); either ``'naive'`` + or ``'orthonormal'`` OUTPUT: @@ -2652,13 +2647,13 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``tol`` -- (default: ``1e-12``); the largest value of the + - ``tol`` -- (default: ``1e-12``) the largest value of the absolute value of the difference between two matrix entries for which they will still be considered equal. - - ``algorithm`` -- (default: 'orthonormal'); set to 'orthonormal' - for a stable procedure and set to 'naive' for a fast - procedure. + - ``algorithm`` -- (default: ``'orthonormal'``) set to + ``'orthonormal'`` for a stable procedure and set to ``'naive'`` for a + fast procedure OUTPUT: @@ -2759,7 +2754,6 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): AUTHOR: - Rob Beezer (2011-03-30) - """ if algorithm == "naive": return super()._is_hermitian(skew=True, tolerance=tol) @@ -2774,13 +2768,13 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``tol`` -- (default: ``1e-12``); the largest value of the + - ``tol`` -- (default: ``1e-12``) the largest value of the absolute value of the difference between two matrix entries for which they will still be considered equal. - - ``algorithm`` -- (default: 'orthonormal'); set to 'orthonormal' - for a stable procedure and set to 'naive' for a fast - procedure. + - ``algorithm`` -- (default: ``'orthonormal'``) set to + ``'orthonormal'`` for a stable procedure and set to ``'naive'`` for a + fast procedure OUTPUT: @@ -2970,9 +2964,9 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``base_ring`` -- optional, defaults to the base ring of ``self``. - Use this to request the base ring of the returned matrices, which - will affect the format of the results. + - ``base_ring`` -- defaults to the base ring of ``self``; use this to + request the base ring of the returned matrices, which will affect the + format of the results OUTPUT: @@ -3279,7 +3273,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): where `L^\ast` is the conjugate-transpose in the complex case, and just the transpose in the real case. If the matrix fails to be positive definite (perhaps because it is not symmetric - or Hermitian), then this function raises a ``ValueError``. + or Hermitian), then this function raises a :exc:`ValueError`. IMPLEMENTATION: @@ -3288,7 +3282,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): method and the :meth:`is_positive_definite` method compute and cache both the Cholesky decomposition and the positive-definiteness. So the :meth:`is_positive_definite` - method or catching a ``ValueError`` from the :meth:`cholesky` + method or catching a :exc:`ValueError` from the :meth:`cholesky` method are equally expensive computationally and if the decomposition exists, it is cached as a side-effect of either routine. @@ -3399,7 +3393,6 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Traceback (most recent call last): ... ValueError: matrix is not Hermitian - """ from sage.rings.real_double import RDF from sage.rings.complex_double import CDF @@ -3453,9 +3446,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): eigenvalues and only positive determinants of leading principal submatrices. - INPUT: - - Any matrix over ``RDF`` or ``CDF``. + Applies to any matrix over ``RDF`` or ``CDF``. OUTPUT: @@ -3470,7 +3461,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): method and the :meth:`cholesky` method compute and cache both the Cholesky decomposition and the positive-definiteness. So the :meth:`is_positive_definite` - method or catching a ``ValueError`` from the :meth:`cholesky` + method or catching a :exc:`ValueError` from the :meth:`cholesky` method are equally expensive computationally and if the decomposition exists, it is cached as a side-effect of either routine. @@ -3672,7 +3663,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): sage: A = matrix(RDF, 2, [1,2,3,4]); A [1.0 2.0] [3.0 4.0] - sage: A.exp() # tol 1e-14 + sage: A.exp() # tol 5e-14 [51.968956198705044 74.73656456700327] [112.10484685050491 164.07380304920997] sage: A = matrix(CDF, 2, [1,2+I,3*I,4]); A # needs sage.symbolic @@ -3685,7 +3676,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): TESTS:: sage: A = matrix(RDF, 2, [1,2,3,4]) - sage: A.exp() # tol 1e-14 + sage: A.exp() # tol 5e-14 [51.968956198705044 74.73656456700327] [112.10484685050491 164.07380304920997] @@ -3716,11 +3707,9 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): INPUT: - - ``eps`` -- Cutoff value - - OUTPUT: + - ``eps`` -- cutoff value - A modified copy of the matrix. + OUTPUT: a modified copy of the matrix EXAMPLES:: @@ -3754,15 +3743,13 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): def round(self, ndigits=0): """ Return a copy of the matrix where all entries have been rounded - to a given precision in decimal digits (default 0 digits). + to a given precision in decimal digits (default: 0 digits). INPUT: - - ``ndigits`` -- The precision in number of decimal digits - - OUTPUT: + - ``ndigits`` -- the precision in number of decimal digits - A modified copy of the matrix + OUTPUT: a modified copy of the matrix EXAMPLES:: @@ -3794,9 +3781,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): the columns, for example an algorithm which should produce an orthogonal matrix. - OUTPUT: - - A modified copy of the matrix. + OUTPUT: a modified copy of the matrix EXAMPLES:: @@ -3833,9 +3818,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): the rows, for example an algorithm which should produce an upper triangular matrix. - OUTPUT: - - A modified copy of the matrix. + OUTPUT: a modified copy of the matrix EXAMPLES:: diff --git a/src/sage/matrix/matrix_double_sparse.pyx b/src/sage/matrix/matrix_double_sparse.pyx index f6d3494cc08..0014121dcb8 100644 --- a/src/sage/matrix/matrix_double_sparse.pyx +++ b/src/sage/matrix/matrix_double_sparse.pyx @@ -14,7 +14,6 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): sage: A = matrix.random(CDF, ZZ.random_element(5), sparse=True) sage: A.__class__ - """ def is_hermitian(self, tolerance=1e-12): @@ -23,7 +22,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): entry-wise ``tolerance``. A matrix is said to be Hermitian if it is equal to its - conjugate-transpose. We default to a small but non-zero + conjugate-transpose. We default to a small but nonzero entry-wise tolerance because, otherwise, numerical issues can cause false negatives (Issue #33023). @@ -36,9 +35,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): tolerate between entries of the given matrix and its conjugate- transpose. - OUTPUT: - - A boolean, either ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -54,7 +51,6 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): sage: A = matrix.random(CDF, 2, sparse=True) sage: (A*A.conjugate_transpose()).is_hermitian() True - """ return self._is_hermitian(skew=False, tolerance=tolerance) @@ -65,7 +61,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): A matrix is said to be skew-Hermitian if it is equal to the negation of its conjugate-transpose. We default to a small but - non-zero entry-wise tolerance because, otherwise, numerical + nonzero entry-wise tolerance because, otherwise, numerical issues can cause false negatives (Issue #33023). Otherwise this method is identical to the superclass method, @@ -78,9 +74,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): tolerate between entries of the given matrix and the negation of its conjugate-transpose. - OUTPUT: - - A boolean, either ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -96,17 +90,14 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): sage: A = matrix.random(CDF, 2, sparse=True) sage: (A - A.conjugate_transpose()).is_skew_hermitian() True - """ return self._is_hermitian(skew=True, tolerance=tolerance) def cholesky(self): r""" - Returns the Cholesky decomposition of a Hermitian matrix. - - INPUT: + Return the Cholesky decomposition of a Hermitian matrix. - A positive-definite matrix over ``RDF`` or ``CDF``. + Applies to a positive-definite matrix over ``RDF`` or ``CDF``. OUTPUT: @@ -119,7 +110,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): where `L^\ast` is the conjugate-transpose. If the matrix is not positive-definite (for example, if it is not Hermitian) - then a ``ValueError`` results. + then a :exc:`ValueError` results. ALGORITHM: @@ -245,7 +236,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): cvx_L = cholmod.getfactor(cvx_symbolic) # The (I[k],J[k]) entry of cvx_L has value V[k]. But beware that V - # contains only the non-zero entries of the matrix; as a result, the + # contains only the nonzero entries of the matrix; as a result, the # dict below contains keys only for those nonzero entries. L = self.matrix_space()({ (cvx_L.I[k], cvx_L.J[k]): cvx_L.V[k] diff --git a/src/sage/matrix/matrix_generic_dense.pyx b/src/sage/matrix/matrix_generic_dense.pyx index 1ac4c3711c6..28603b5a930 100644 --- a/src/sage/matrix/matrix_generic_dense.pyx +++ b/src/sage/matrix/matrix_generic_dense.pyx @@ -61,7 +61,7 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring TESTS: @@ -151,8 +151,8 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): def __copy__(self): """ - Creates a copy of self, which may be changed without altering - self. + Create a copy of self, which may be changed without altering + ``self``. EXAMPLES:: @@ -330,7 +330,7 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): def _list(self): """ - Return reference to list of entries of self. For internal use + Return reference to list of entries of ``self``. For internal use only, since this circumvents immutability. EXAMPLES:: diff --git a/src/sage/matrix/matrix_generic_sparse.pyx b/src/sage/matrix/matrix_generic_sparse.pyx index ef4e99d890e..8c57e50b08a 100644 --- a/src/sage/matrix/matrix_generic_sparse.pyx +++ b/src/sage/matrix/matrix_generic_sparse.pyx @@ -98,7 +98,7 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse): The datastructure can potentially be optimized. Firstly, as noticed in :issue:`17663`, we lose time in using 2-tuples to store indices. - Secondly, there is no fast way to access non-zero elements in a given + Secondly, there is no fast way to access nonzero elements in a given row/column. """ def __cinit__(self): @@ -117,7 +117,7 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring TESTS:: @@ -169,7 +169,7 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse): def __bool__(self): r""" - Test whether this matrix is non-zero. + Test whether this matrix is nonzero. TESTS:: @@ -288,7 +288,6 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse): True sage: (A+D).__class__ == D.__class__ True - """ # Compute the sum of two sparse matrices. # This is complicated because of how we represent sparse matrices. @@ -346,7 +345,7 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse): def _list(self): """ - Return all entries of self as a list of numbers of rows times + Return all entries of ``self`` as a list of numbers of rows times number of columns entries. """ cdef Py_ssize_t i,j @@ -360,7 +359,7 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse): def _dict(self): """ - Return the underlying dictionary of self. + Return the underlying dictionary of ``self``. This is used in comparisons. @@ -425,10 +424,9 @@ def Matrix_sparse_from_rows(X): """ INPUT: - - ``X`` -- nonempty list of SparseVector rows - + - ``X`` -- nonempty list of ``SparseVector`` rows - OUTPUT: Sparse_matrix with those rows. + OUTPUT: ``Sparse_matrix`` with those rows EXAMPLES:: diff --git a/src/sage/matrix/matrix_gf2e_dense.pyx b/src/sage/matrix/matrix_gf2e_dense.pyx index 6a4fd3bfed2..5b7fd1fe2af 100644 --- a/src/sage/matrix/matrix_gf2e_dense.pyx +++ b/src/sage/matrix/matrix_gf2e_dense.pyx @@ -205,7 +205,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring EXAMPLES:: @@ -232,9 +232,10 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, value): """ - A[i,j] = value without bound checks + A[i,j] = value without bound checks. INPUT: + - ``i`` -- row index - ``j`` -- column index - ``value`` -- a finite field element (not checked but assumed) @@ -262,6 +263,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): Get A[i,j] without bound checks. INPUT: + - ``i`` -- row index - ``j`` -- column index @@ -297,8 +299,8 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): return mzed_read_elem(self._entries, i, j) == self._zero_word cpdef _add_(self, right): - """ - Return A+B + r""" + Return ``A+B``. INPUT: @@ -384,8 +386,8 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): return ans cdef _matrix_times_matrix_(self, Matrix right): - """ - Return A*B + r""" + Return ``A*B``. Uses the M4RIE machinery to decide which function to call. @@ -441,7 +443,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): finite field is small, there is a very high chance that ``e * B[j]`` is computed more than once for any ``e`` in the finite field. Instead, we compute all possible - multiples of ``B[j]`` and re-use this data in the inner loop. + multiples of ``B[j]`` and reuse this data in the inner loop. This is what is called a "Newton-John" table in M4RIE. INPUT: @@ -707,14 +709,12 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): INPUT: - - ``density`` -- float; proportion (roughly) to be considered for - changes - - ``nonzero`` -- Bool (default: ``False``); whether the new entries - are forced to be non-zero + - ``density`` -- float; proportion (roughly) to be considered for + changes + - ``nonzero`` -- boolean (default: ``False``); whether the new entries + are forced to be nonzero - OUTPUT: - - - None, the matrix is modified in-place + OUTPUT: none, the matrix is modified in-place EXAMPLES:: @@ -927,7 +927,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): sig_off() elif algorithm == 'builtin': - self._echelon_in_place(algorithm="classical") + self._echelon_in_place(algorithm='classical') else: raise ValueError("No algorithm '%s'."%algorithm) @@ -976,7 +976,6 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): [1 0 0] [0 1 0] [0 0 1] - """ cdef Matrix_gf2e_dense A A = Matrix_gf2e_dense.__new__(Matrix_gf2e_dense, self._parent, 0, 0, 0) @@ -993,13 +992,13 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): cdef rescale_row_c(self, Py_ssize_t row, multiple, Py_ssize_t start_col): """ - Return ``multiple * self[row][start_col:]`` + Return ``multiple * self[row][start_col:]``. INPUT: - ``row`` -- row index for row to rescale - ``multiple`` -- finite field element to scale by - - ``start_col`` -- only start at this column index. + - ``start_col`` -- only start at this column index EXAMPLES:: @@ -1039,7 +1038,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): - ``row_to`` -- row index of source - ``row_from`` -- row index of destination - - ``multiple`` -- finite field element + - ``multiple`` -- finite field element - ``start_col`` -- only start at this column index EXAMPLES:: @@ -1126,7 +1125,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): """ mzed_col_swap(self._entries, col1, col2) - def augment(self, Matrix_gf2e_dense right): + def augment(self, right): """ Augments ``self`` with ``right``. @@ -1168,21 +1167,50 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): sage: N = Matrix(K, 0, 1, 0) sage: M.augment(N) [] + + sage: A = matrix(K, 3, range(12)) + sage: B = vector(QQ, [2,5/7,1.2]) # see issue: 38448 + sage: A.augment(B).ncols() + 5 + + sage: B = vector([]) + sage: A.augment(B) == A + True """ + cdef Matrix_gf2e_dense _right cdef Matrix_gf2e_dense A - if self._nrows != right._nrows: + if not isinstance(right, Matrix_gf2e_dense): + # See issue: #36761 - Allow Vectors to be augmented + if hasattr(right, '_vector_'): + rsize = len(right) + if rsize==0: + return self.__copy__() + if self._nrows != rsize: + raise TypeError("Both numbers of rows must match.") + if self.base_ring() is not right.base_ring(): + right = right.change_ring(self.base_ring()) + from sage.matrix.matrix_space import MatrixSpace + M = MatrixSpace(self.base_ring(), nrows=rsize, ncols=1) + _right = (M(right)) + else: + raise TypeError("a matrix must be augmented with another matrix, " + "or a vector") + else: + _right = right + + if self._nrows != _right._nrows: raise TypeError("Both numbers of rows must match.") if self._ncols == 0: - return right.__copy__() - if right._ncols == 0: + return _right.__copy__() + if _right._ncols == 0: return self.__copy__() - A = self.new_matrix(ncols = self._ncols + right._ncols) + A = self.new_matrix(ncols = self._ncols + _right._ncols) if self._nrows == 0: return A - A._entries = mzed_concat(A._entries, self._entries, right._entries) + A._entries = mzed_concat(A._entries, self._entries, _right._entries) return A cdef _stack_impl(self, bottom): @@ -1323,7 +1351,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): EXAMPLES:: sage: K. = GF(2^4) - sage: A = random_matrix(K, 10, 10, algorithm="unimodular") + sage: A = random_matrix(K, 10, 10, algorithm='unimodular') sage: A.rank() 10 sage: A = matrix(K, 10, 0) @@ -1445,7 +1473,7 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): INPUT: - - ``C`` -- a list of matrices over GF(2) + - ``C`` -- list of matrices over GF(2) EXAMPLES:: diff --git a/src/sage/matrix/matrix_gfpn_dense.pyx b/src/sage/matrix/matrix_gfpn_dense.pyx index e3d704dd771..9d4e113e522 100644 --- a/src/sage/matrix/matrix_gfpn_dense.pyx +++ b/src/sage/matrix/matrix_gfpn_dense.pyx @@ -109,8 +109,8 @@ cdef class FieldConverter_class: """ INPUT: - A finite field with Givaro implementation and at most 251 - elements. These assumptions are not tested. + - ``field`` -- a finite field with Givaro implementation and at most 251 + elements. These assumptions are not tested. EXAMPLES:: @@ -202,8 +202,8 @@ cdef class PrimeFieldConverter_class(FieldConverter_class): """ INPUT: - A finite *prime* field with at most 251 elements. - This assumption is not tested. + - ``field`` -- a finite *prime* field with at most 251 elements. + This assumption is not tested. EXAMPLES:: @@ -266,7 +266,6 @@ cdef FieldConverter_class FieldConverter(field) noexcept: sage: A = MS.random_element() sage: A*2 == A+A True - """ try: return _converter_cache[field] @@ -343,7 +342,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): The documentation of the ``__init__`` methods shows further ways of creating a :class:`Matrix_gfpn_dense` instance. However, these should only be of internal use. - """ ################## ## Init, Dealloc, Copy @@ -377,7 +375,7 @@ cdef class Matrix_gfpn_dense(Matrix_dense): - ``coerce`` -- ignored - - ``mutable`` -- if False, the resulting matrix cannot be + - ``mutable`` -- if ``False``, the resulting matrix cannot be changed, and it can be used as key in a Python dictionary EXAMPLES:: @@ -563,7 +561,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 0 1 2] [ z z + 1 z + 2] [ 2*z 2*z + 1 2*z + 2] - """ if self.Data == NULL: raise IndexError("Matrix is empty") @@ -617,7 +614,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [2 3 4] sage: type(_) is MTX True - """ if not 0 <= i < j <= self.Data.Nor: raise IndexError("Indices i={}, j={} violate the condition 0 < i < j < {}".format(i,j,self.Data.Nor)) @@ -652,7 +648,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0] - """ # ASSUMPTION: value's parent is the base ring if self.Data == NULL: @@ -685,10 +680,10 @@ cdef class Matrix_gfpn_dense(Matrix_dense): INPUT: - - ``density`` (optional real number between zero and one) -- - the expected density of the resulting matrix - - ``nonzero`` (optional bool, default ``False``) -- - If true, all inserted marks are non-zero. + - ``density`` -- (optional) real number between zero and one the + expected density of the resulting matrix + - ``nonzero`` -- boolean (default: ``False``); if ``True``, all + inserted marks are nonzero EXAMPLES:: @@ -872,7 +867,7 @@ cdef class Matrix_gfpn_dense(Matrix_dense): INPUT: - ``i`` -- index of the first row to be extracted - - ``j`` -- (default: -1); -1, or index of the last + - ``j`` -- (default: -1) -1, or index of the last row to be extracted OUTPUT: @@ -900,7 +895,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [['15', '14', '1', '0', '10'], ['24', '13', '20', '1', '16'], ['18', '8', '7', '6', '17']] - """ cdef int k if self.Data: @@ -1020,7 +1014,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 1 2 y y + 1 y + 2] [ 2*y 2*y + 1 2*y + 2 0 1] [ 2 y y + 1 y + 2 2*y] - """ if self.Data == NULL or start_col >= self.Data.Noc: return @@ -1089,7 +1082,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 2 y y + 1 y + 2 2*y] sage: y-(2*y+1)/y 2 - """ if self.Data == NULL or start_col >= self.Data.Noc: return @@ -1132,7 +1124,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 2*x 2*x + 1 2*x + 2 2*x + 3 2*x + 4] [ x x + 1 x + 2 x + 3 x + 4] [ 4*x 4*x + 1 4*x + 2 4*x + 3 4*x + 4] - """ if not self.Data: raise ValueError("This matrix is empty") @@ -1149,7 +1140,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: K. = GF(125) sage: MatrixSpace(K,7,7)(x).trace() 2*x - """ if self._nrows != self._ncols: raise ValueError("self must be a square matrix") @@ -1207,7 +1197,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 2*x 1 2] [ x 1 x + 2] [ 2*x 2*x + 1 x + 2] - """ cdef Matrix_gfpn_dense Self = self cdef Matrix_gfpn_dense Right = right @@ -1234,7 +1223,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ x 1 2] [ x 2*x + 1 x + 2] [ 2*x 2*x + 1 2] - """ cdef Matrix_gfpn_dense Self = self cdef Matrix_gfpn_dense Right = right @@ -1266,7 +1254,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: N = MatrixSpace(GF(125,'x'),10,30).random_element() sage: M + (-N) == M - N == -(N - M) True - """ if self.Data == NULL: raise ValueError("The matrix must not be empty") @@ -1296,7 +1283,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: M == M*int(4) == int(4)*M True - """ if self.Data == NULL: return self.__copy__() @@ -1329,7 +1315,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: N = MatrixSpace(GF(9,'x'),500,2000).random_element() sage: M*N == M._multiply_classical(N) True - """ "multiply two meataxe matrices by the school book algorithm" if self.Data == NULL or right.Data == NULL: @@ -1351,7 +1336,7 @@ cdef class Matrix_gfpn_dense(Matrix_dense): INPUT: - ``right`` -- a matrix of dimensions suitable to do multiplication - - ``cutoff`` (optional integer) -- indicates the minimal size of submatrices + - ``cutoff`` -- (optional integer) indicates the minimal size of submatrices that will be considered in the divide-and-conquer algorithm. The size is *not* expressed by the number of rows/columns, but the rowsize expressed in bytes. Depending on the base field, one byte may represent up to eight @@ -1365,7 +1350,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: N = MatrixSpace(GF(9,'x'),600,1500).random_element() sage: M._multiply_strassen(N) == M._multiply_strassen(N,80) == M._multiply_strassen(N,2) True - """ if self.Data == NULL or right.Data == NULL: raise ValueError("The matrices must not be empty") @@ -1426,7 +1410,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 0 x + 2 2*x + 1] [ 1 x 2*x + 2] [ 2 x + 1 2*x] - """ if self.Data == NULL: return self.__copy__() @@ -1472,7 +1455,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): Traceback (most recent call last): ... ZeroDivisionError: Division by zero in file matinv.c (line 50) - """ if self.Data == NULL: raise ValueError("The matrix must not be empty") @@ -1504,7 +1486,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): [ 2 2*x] [ x 2*x + 1] [ x + 1 2*x + 2] - """ if self.Data == NULL: raise ValueError("The matrix must not be empty") @@ -1531,7 +1512,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): True sage: M^103 == 1 False - """ if self.Data == NULL: raise ValueError("The matrix must not be empty") @@ -1582,7 +1562,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: M.left_kernel_matrix() [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 1 0 0] - """ cdef Matrix_gfpn_dense OUT = self.fetch("left_kernel_matrix") if OUT is not None: @@ -1608,7 +1587,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): Use :meth:`_echelon_in_place_classical`, which can take the keyword ``reduced``. - EXAMPLES:: sage: K. = GF(25) @@ -1649,9 +1627,9 @@ cdef class Matrix_gfpn_dense(Matrix_dense): INPUT: - - ``reduced`` (default: ``True``) -- will result + - ``reduced`` -- boolean (default: ``True``); will result in the row-reduced echelon form (otherwise, only a - semi-echelon form results). + semi-echelon form results) EXAMPLES:: @@ -1740,7 +1718,6 @@ cdef class Matrix_gfpn_dense(Matrix_dense): sage: M [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - """ if self._nrows == 0 or self._ncols == 0: self.cache('in_echelon_form',True) @@ -1896,7 +1873,7 @@ def mtx_unpickle(f, int nr, int nc, data, bint m): [0 0 0 0 0] [0 0 0 0 0] - We test further corner cases. A ``ValueError`` is raised if the number + We test further corner cases. A :exc:`ValueError` is raised if the number of bytes in the pickle does not comply with either the old or the new pickle format (we test several code paths here):: diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 036d1bb7998..c0e0a1fff44 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -250,8 +250,8 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the - entries are of type :class:`Integer`. + - ``coerce`` -- if ``False``, assume without checking that the + entries are of type :class:`Integer` EXAMPLES: @@ -323,7 +323,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``j`` -- column - - ``x`` -- must be Integer! The value to set self[i,j] to. + - ``x`` -- must be Integer! The value to set ``self[i,j]`` to. EXAMPLES:: @@ -347,8 +347,8 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``j`` -- column - - ``value`` -- The value to set self[i,j] to. This will make a - copy of ``value``. + - ``value`` -- the value to set ``self[i,j]`` to; this will make a + copy of ``value`` EXAMPLES:: @@ -376,7 +376,7 @@ cdef class Matrix_integer_dense(Matrix_dense): cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j): """ - Return the (i, j) entry of self as a new Integer. + Return the (i, j) entry of ``self`` as a new Integer. .. WARNING:: @@ -430,7 +430,7 @@ cdef class Matrix_integer_dense(Matrix_dense): cdef inline int get_unsafe_int(self, Py_ssize_t i, Py_ssize_t j) noexcept: """ - Return the (i, j) entry of self as a new Integer. + Return the (i, j) entry of ``self`` as a new Integer. .. WARNING:: @@ -441,7 +441,7 @@ cdef class Matrix_integer_dense(Matrix_dense): cdef inline double get_unsafe_double(self, Py_ssize_t i, Py_ssize_t j) noexcept: """ - Return the (i, j) entry of self as a new Integer. + Return the (i, j) entry of ``self`` as a new Integer. .. WARNING:: @@ -496,7 +496,6 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: matrix(ZZ,1,3,[1,193,15])._pickle() == (b'1 61 f', 0) # indirect doctest True - """ return str_to_bytes(self._export_as_string(32), 'ascii') @@ -507,7 +506,7 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - base -- an integer <= 36; (default: 10) + - ``base`` -- integer <= 36; (default: 10) EXAMPLES:: @@ -671,7 +670,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def __bool__(self): r""" - Tests whether self is not the zero matrix. + Test whether ``self`` is not the zero matrix. EXAMPLES:: @@ -1056,9 +1055,9 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - ``v`` -- a free module element. + - ``v`` -- a free module element - OUTPUT: The vector times matrix product ``v*A``. + OUTPUT: the vector times matrix product ``v*A`` EXAMPLES:: @@ -1104,7 +1103,7 @@ cdef class Matrix_integer_dense(Matrix_dense): r""" Test whether the matrix is primitive. - An integral matrix `A` is primitive if all its entries are non-negative + An integral matrix `A` is primitive if all its entries are nonnegative and for some positive integer `n` the matrix `A^n` has all its entries positive. @@ -1185,7 +1184,7 @@ cdef class Matrix_integer_dense(Matrix_dense): try: fmpz_mat_init(m, dim, dim) - # 1. check that self._matrix is non-negative and set + # 1. check that self._matrix is nonnegative and set # m as a 0/1 matrix zero = 0 diag = 0 @@ -1245,9 +1244,9 @@ cdef class Matrix_integer_dense(Matrix_dense): """ INPUT: - - ``self`` -- a matrix + - ``self`` -- a matrix - OUTPUT: self, 1 + OUTPUT: ``self, 1`` EXAMPLES:: @@ -1268,11 +1267,10 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: + - ``var`` -- a variable name - - ``var`` -- a variable name - - - ``algorithm`` -- (optional) either 'generic', 'flint' or 'linbox'. - Default is set to 'linbox'. + - ``algorithm`` -- (default: ``'linbox'``) either ``'generic'``, + ``'flint'`` or ``'linbox'`` EXAMPLES:: @@ -1386,10 +1384,9 @@ cdef class Matrix_integer_dense(Matrix_dense): r""" INPUT: + - ``var`` -- a variable name - - ``var`` -- a variable name - - - ``algorithm`` -- (optional) either 'linbox' (default) or 'generic' + - ``algorithm`` -- either ``'linbox'`` (default) or ``'generic'`` EXAMPLES:: @@ -1471,7 +1468,7 @@ cdef class Matrix_integer_dense(Matrix_dense): Return the height of this matrix, i.e., the max absolute value of the entries of the matrix. - OUTPUT: A nonnegative integer. + OUTPUT: nonnegative integer EXAMPLES:: @@ -1709,7 +1706,7 @@ cdef class Matrix_integer_dense(Matrix_dense): Return a pair (F, C) such that the rows of C form a symplectic basis for ``self`` and ``F = C * self * C.transpose()``. - Raise a :class:`ValueError` if ``self`` is not anti-symmetric, + Raise a :exc:`ValueError` if ``self`` is not anti-symmetric, or ``self`` is not alternating. Anti-symmetric means that `M = -M^t`. Alternating means @@ -1765,7 +1762,7 @@ cdef class Matrix_integer_dense(Matrix_dense): hermite_form = echelon_form - def echelon_form(self, algorithm="default", proof=None, include_zero_rows=True, + def echelon_form(self, algorithm='default', proof=None, include_zero_rows=True, transformation=False, D=None): r""" Return the echelon form of this matrix over the integers, also known @@ -1773,9 +1770,9 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - ``algorithm`` -- String. The algorithm to use. Valid options are: + - ``algorithm`` -- string; the algorithm to use. Valid options are: - - ``'default'`` -- Let Sage pick an algorithm (default). + - ``'default'`` -- let Sage pick an algorithm (default). Up to 75 rows or columns with no transformation matrix, use pari with flag 0; otherwise, use flint. @@ -1784,7 +1781,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``'ntl'`` -- use NTL (only works for square matrices of full rank!) - - ``'padic'`` -- an asymptotically fast p-adic modular + - ``'padic'`` -- an asymptotically fast `p`-adic modular algorithm, If your matrix has large coefficients and is small, you may also want to try this. @@ -1796,25 +1793,25 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``'pari4'`` -- use PARI with flag 4 (use heuristic LLL) - - ``proof`` -- (default: ``True``); if proof=False certain - determinants are computed using a randomized hybrid p-adic - multimodular strategy until it stabilizes twice (instead of up to - the Hadamard bound). It is *incredibly* unlikely that one would - ever get an incorrect result with proof=False. + - ``proof`` -- (default: ``True``) if proof=False certain + determinants are computed using a randomized hybrid `p`-adic + multimodular strategy until it stabilizes twice (instead of up to + the Hadamard bound). It is *incredibly* unlikely that one would + ever get an incorrect result with proof=False. - - ``include_zero_rows`` -- (default: ``True``) if False, - don't include zero rows + - ``include_zero_rows`` -- boolean (default: ``True``); if ``False``, + don't include zero rows - - ``transformation`` -- if given, also compute - transformation matrix; only valid for flint and padic algorithm + - ``transformation`` -- if given, also compute + transformation matrix; only valid for flint and padic algorithm - - ``D`` -- (default: None) if given and the algorithm - is 'ntl', then D must be a multiple of the determinant and this - function will use that fact. + - ``D`` -- (default: ``None``) if given and the algorithm + is ``'ntl'``, then D must be a multiple of the determinant and this + function will use that fact OUTPUT: - The Hermite normal form (=echelon form over `\ZZ`) of self as + The Hermite normal form (=echelon form over `\ZZ`) of ``self`` as an immutable matrix. EXAMPLES:: @@ -1873,7 +1870,7 @@ cdef class Matrix_integer_dense(Matrix_dense): .. NOTE:: If 'ntl' is chosen for a non square matrix this function - raises a ValueError. + raises a :exc:`ValueError`. Special cases: 0 or 1 rows:: @@ -1996,7 +1993,7 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: m = random_matrix(ZZ, 15, 15, x=-1000, y=1000, density=0.1) sage: m.parent() Full MatrixSpace of 15 by 15 dense matrices over Integer Ring - sage: H, U = m.hermite_form(algorithm="flint", + sage: H, U = m.hermite_form(algorithm='flint', ....: transformation=True) sage: H == U*m True @@ -2116,7 +2113,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def saturation(self, p=0, proof=None, max_dets=5): r""" Return a saturation matrix of self, which is a matrix whose rows - span the saturation of the row span of self. This is not unique. + span the saturation of the row span of ``self``. This is not unique. The saturation of a `\ZZ` module `M` embedded in `\ZZ^n` is a module `S` that @@ -2127,25 +2124,21 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - ``p`` -- (default: 0); if nonzero given, saturate - only at the prime `p`, i.e., return a matrix whose row span - is a `\ZZ`-module `S` that contains self and - such that the index of `S` in its saturation is coprime to - `p`. If `p` is None, return full saturation of - self. + - ``p`` -- (default: 0) if nonzero given, saturate + only at the prime `p`, i.e., return a matrix whose row span + is a `\ZZ`-module `S` that contains ``self`` and + such that the index of `S` in its saturation is coprime to + `p`. If `p` is None, return full saturation of ``self``. - - ``proof`` -- (default: use proof.linear_algebra()); - if False, the determinant calculations are done with proof=False. + - ``proof`` -- (default: use proof.linear_algebra()); + if ``False``, the determinant calculations are done with + ``proof=False`` - - ``max_dets`` -- (default: 5); technical parameter - - max number of determinant to compute when bounding prime divisor of - self in its saturation. + - ``max_dets`` -- (default: 5) technical parameter - + max number of determinant to compute when bounding prime divisor of + ``self`` in its saturation. - - OUTPUT: - - - - ``matrix`` -- a matrix over ZZ + OUTPUT: matrix over ZZ .. NOTE:: @@ -2199,26 +2192,23 @@ cdef class Matrix_integer_dense(Matrix_dense): def index_in_saturation(self, proof=None): """ - Return the index of self in its saturation. + Return the index of ``self`` in its saturation. INPUT: + - ``proof`` -- (default: use proof.linear_algebra()); + if ``False``, the determinant calculations are done with + ``proof=False`` - - ``proof`` -- (default: use proof.linear_algebra()); - if False, the determinant calculations are done with proof=False. - - - OUTPUT: + OUTPUT: positive integer; the index of the row span of + this matrix in its saturation - - ``positive integer`` -- the index of the row span of - this matrix in its saturation + ALGORITHM: - - ALGORITHM: Use Hermite normal form twice to find an invertible - matrix whose inverse transforms a matrix with the same row span as - self to its saturation, then compute the determinant of that - matrix. + Use Hermite normal form twice to find an invertible matrix whose + inverse transforms a matrix with the same row span as ``self`` to its + saturation, then compute the determinant of that matrix. EXAMPLES:: @@ -2293,16 +2283,14 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: + - ``self`` -- matrix - - ``self`` -- matrix - - - ``algorithm`` -- (default: 'pari') + - ``algorithm`` -- (default: ``'pari'``) - - ``'pari'``: works robustly, but is slower. + - ``'pari'`` -- works robustly, but is slower. - ``'linbox'`` -- use linbox (currently off, broken) - OUTPUT: list of integers @@ -2374,12 +2362,12 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - ``transformation`` -- a boolean (default: ``True``); whether to + - ``transformation`` -- boolean (default: ``True``); whether to return the transformation matrices `U` and `V` such that `S=U\cdot - self\cdot V`. + self\cdot V` - ``integral`` -- a subring of the base ring or ``True`` (default: - ``None``); ignored for matrices with integer entries. + ``None``); ignored for matrices with integer entries .. NOTE:: @@ -2478,19 +2466,19 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - ``flag`` -- 0 (default), 1 or 2 as follows: + - ``flag`` -- 0 (default), 1 or 2 as follows: - - ``0`` -- (default) return the Frobenius form of this - matrix. + - ``0`` -- (default) return the Frobenius form of this + matrix - - ``1`` -- return only the elementary divisor - polynomials, as polynomials in var. + - ``1`` -- return only the elementary divisor + polynomials, as polynomials in var - - ``2`` -- return a two-components vector [F,B] where F + - ``2`` -- return a two-components vector [F,B] where F is the Frobenius form and B is the basis change so that - `M=B^{-1}FB`. + `M=B^{-1}FB` - - ``var`` -- a string (default: 'x') + - ``var`` -- string (default: ``'x'``) ALGORITHM: uses PARI's :pari:`matfrobenius` @@ -2558,14 +2546,14 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``algorithm`` -- determines which algorithm to use, options are: - - 'flint' -- use the algorithm from the FLINT library - - 'pari' -- use the :pari:`matkerint` function from the PARI library - - 'padic' -- use the p-adic algorithm from the IML library - - 'default' -- use a heuristic to decide which of the three above - routines is fastest. This is the default value. + - ``'flint'`` -- use the algorithm from the FLINT library + - ``'pari'`` -- use the :pari:`matkerint` function from the PARI library + - ``'padic'`` -- use the `p`-adic algorithm from the IML library + - ``'default'`` -- use a heuristic to decide which of the three above + routines is fastest. This is the default value - - ``proof`` -- this is passed to the p-adic IML algorithm. - If not specified, the global flag for linear algebra will be used. + - ``proof`` -- this is passed to the `p`-adic IML algorithm; + if not specified, the global flag for linear algebra will be used OUTPUT: @@ -2721,7 +2709,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def _ntl_(self): r""" - ntl.mat_ZZ representation of self. + ntl.mat_ZZ representation of ``self``. EXAMPLES:: @@ -2740,7 +2728,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # LLL ####################################################################### - def BKZ(self, delta=None, algorithm="fpLLL", fp=None, block_size=10, prune=0, + def BKZ(self, delta=None, algorithm='fpLLL', fp=None, block_size=10, prune=0, use_givens=False, precision=0, proof=None, **kwds): """ Return the result of running Block Korkin-Zolotarev reduction on @@ -2750,7 +2738,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``delta`` -- (default: ``0.99``) LLL parameter - - ``algorithm`` -- (default: ``"fpLLL"``) ``"fpLLL"`` or ``"NTL"`` + - ``algorithm`` -- (default: ``'fpLLL'``) ``'fpLLL'`` or ``"NTL"`` - ``fp`` -- floating point number implementation @@ -2762,7 +2750,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``'qd'`` -- NTL's QP - -``'qd1'`` -- quad doubles: Uses ``quad_float`` precision + - ``'qd1'`` -- quad doubles: Uses ``quad_float`` precision to compute Gram-Schmidt, but uses double precision in the search phase of the block reduction algorithm. This seems adequate for most purposes, and is faster than @@ -2773,7 +2761,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``'rr'`` -- arbitrary precision: NTL'RR or fpLLL's MPFR - - ``block_size`` -- (default: ``10``) Specifies the size + - ``block_size`` -- (default: ``10``) specifies the size of the blocks in the reduction. High values yield shorter vectors, but the running time increases double exponentially with ``block_size``. ``block_size`` @@ -2786,7 +2774,7 @@ cdef class Matrix_integer_dense(Matrix_dense): NTL SPECIFIC INPUT: - - ``prune`` -- (default: ``0``) The optional parameter + - ``prune`` -- (default: ``0``) the optional parameter ``prune`` can be set to any positive number to invoke the Volume Heuristic from [SH1995]_. This can significantly reduce the running time, and hence allow much bigger block size, @@ -2796,7 +2784,7 @@ cdef class Matrix_integer_dense(Matrix_dense): disabled. Recommended usage: for ``block_size==30``, set ``10 <= prune <=15``. - - ``use_givens`` -- Use Givens orthogonalization. Only + - ``use_givens`` -- use Givens orthogonalization. Only applies to approximate reduction using NTL. This is a bit slower, but generally much more stable, and is really the preferred orthogonalization strategy. For a nice @@ -2807,8 +2795,8 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``precision`` -- (default: ``0`` for automatic choice) bit precision to use if ``fp='rr'`` is set - - ``**kwds`` -- keywords to be passed to :mod:`fpylll`. See - :class:`fpylll.BKZ.Param` for details. + - ``**kwds`` -- keywords to be passed to :mod:`fpylll`; see + :class:`fpylll.BKZ.Param` for details Also, if the verbose level is at least `2`, some output is printed during the computation. @@ -2828,7 +2816,7 @@ cdef class Matrix_integer_dense(Matrix_dense): [-1 1 3] sage: A = Matrix(ZZ,3,3,range(1,10)) - sage: A.BKZ(fp="fp") + sage: A.BKZ(fp='fp') [ 0 0 0] [ 2 1 0] [-1 1 3] @@ -2948,10 +2936,10 @@ cdef class Matrix_integer_dense(Matrix_dense): R = A.to_matrix(self.new_matrix()) return R - def LLL(self, delta=None, eta=None, algorithm="fpLLL:wrapper", fp=None, prec=0, early_red=False, use_givens=False, use_siegel=False, transformation=False, **kwds): + def LLL(self, delta=None, eta=None, algorithm='fpLLL:wrapper', fp=None, prec=0, early_red=False, use_givens=False, use_siegel=False, transformation=False, **kwds): r""" Return LLL-reduced or approximated LLL reduced matrix `R` of the lattice - generated by the rows of self. + generated by the rows of ``self``. A set of vectors `(b_1, b_2, ..., b_d)` is `(\delta, \eta)`-LLL-reduced if the two following conditions hold: @@ -2988,7 +2976,7 @@ cdef class Matrix_integer_dense(Matrix_dense): ignored by NTL and pari - ``algorithm`` -- string; one of the algorithms listed below - (default: ``"fpLLL:wrapper"``). + (default: ``'fpLLL:wrapper'``) - ``fp`` -- floating point number implementation, ignored by pari: @@ -3001,42 +2989,40 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``prec`` -- (default: auto choose) precision, ignored by NTL and pari - - ``early_red`` -- (default: ``False``) perform early reduction, + - ``early_red`` -- boolean (default: ``False``); perform early reduction, ignored by NTL and pari - - ``use_givens`` -- (default: ``False``) use Givens + - ``use_givens`` -- boolean (default: ``False``); use Givens orthogonalization. Only applies to approximate reduction using NTL. This is slower but generally more stable. - - ``use_siegel`` -- (default: ``False``) use Siegel's condition + - ``use_siegel`` -- boolean (default: ``False``); use Siegel's condition instead of Lovász's condition, ignored by NTL and pari - - ``transformation`` -- (default: ``False``) also return transformation - matrix. + - ``transformation`` -- boolean (default: ``False``); also return transformation + matrix - - ``**kwds`` -- keywords to be passed to :mod:`fpylll`. See - :meth:`fpylll.LLL.reduction` for details. + - ``**kwds`` -- keywords to be passed to :mod:`fpylll`; see + :meth:`fpylll.LLL.reduction` for details Also, if the verbose level is at least `2`, some output is printed during the computation. AVAILABLE ALGORITHMS: - - ``'NTL:LLL'`` -- NTL's LLL + choice of ``fp``. - - - ``'fpLLL:heuristic'`` -- fpLLL's heuristic + choice of ``fp``. + - ``'NTL:LLL'`` -- NTL's LLL + choice of ``fp`` - - ``'fpLLL:fast'`` -- fpLLL's fast + choice of ``fp``. + - ``'fpLLL:heuristic'`` -- fpLLL's heuristic + choice of ``fp`` - - ``'fpLLL:proved'`` -- fpLLL's proved + choice of ``fp``. + - ``'fpLLL:fast'`` -- fpLLL's fast + choice of ``fp`` - - ``'fpLLL:wrapper'`` -- fpLLL's automatic choice (default). + - ``'fpLLL:proved'`` -- fpLLL's proved + choice of ``fp`` - - ``'pari'`` -- pari's qflll. + - ``'fpLLL:wrapper'`` -- fpLLL's automatic choice (default) - OUTPUT: + - ``'pari'`` -- pari's qflll - A matrix over the integers. + OUTPUT: a matrix over the integers EXAMPLES:: @@ -3086,11 +3072,11 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: U * A == R True - sage: R, U = A.LLL(algorithm="NTL:LLL", transformation=True) + sage: R, U = A.LLL(algorithm='NTL:LLL', transformation=True) sage: U * A == R True - sage: R, U = A.LLL(algorithm="pari", transformation=True) + sage: R, U = A.LLL(algorithm='pari', transformation=True) sage: U * A == R True @@ -3105,7 +3091,7 @@ cdef class Matrix_integer_dense(Matrix_dense): [0 0 0] [0 0 0] - sage: M.LLL(algorithm="pari")[0:2] + sage: M.LLL(algorithm='pari')[0:2] [0 0 0] [0 0 0] @@ -3146,7 +3132,7 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: M._cache {'rank': 2} sage: M._clear_cache() - sage: R = M.LLL(algorithm="pari") + sage: R = M.LLL(algorithm='pari') sage: M._cache {'rank': 2} @@ -3311,7 +3297,7 @@ cdef class Matrix_integer_dense(Matrix_dense): else: return R - def is_LLL_reduced(self, delta=None, eta=None): + def is_LLL_reduced(self, delta=None, eta=None, algorithm='fpLLL'): r""" Return ``True`` if this lattice is `(\delta, \eta)`-LLL reduced. See ``self.LLL`` for a definition of LLL reduction. @@ -3322,6 +3308,8 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``eta`` -- (default: `0.501`) parameter `\eta` as described above + - ``algorithm`` -- either ``'fpLLL'`` (default) or ``'sage'`` + EXAMPLES:: sage: A = random_matrix(ZZ, 10, 10) @@ -3330,6 +3318,15 @@ cdef class Matrix_integer_dense(Matrix_dense): False sage: L.is_LLL_reduced() True + + The ``'sage'`` algorithm currently does not work for matrices with + linearly dependent rows:: + + sage: A = matrix(ZZ, [[1, 2, 3], [2, 4, 6]]) + sage: A.is_LLL_reduced(algorithm='sage') + Traceback (most recent call last): + ... + ValueError: linearly dependent input for module version of Gram-Schmidt """ if eta is None: eta = 0.501 @@ -3344,20 +3341,27 @@ cdef class Matrix_integer_dense(Matrix_dense): if eta < 0.5: raise TypeError("eta must be >= 0.5") - # this is pretty slow - import sage.modules.misc - G, mu = sage.modules.misc.gram_schmidt(self.rows()) - #For any $i>j$, we have $|mu_{i, j}| <= \eta$ - for e in mu.list(): - if e.abs() > eta: - return False - - #For any $ij$, we have $|mu_{i, j}| <= \eta$ + for e in mu.list(): + if e.abs() > eta: + return False + + # For any $iu)*T_rows[i][k] + (v)*T_rows[j][k])%R @@ -5209,13 +5179,13 @@ cdef class Matrix_integer_dense(Matrix_dense): def row(self, Py_ssize_t i, from_list=False): """ - Return the i-th row of this matrix as a dense vector. + Return the `i`-th row of this matrix as a dense vector. INPUT: - - ``i`` -- integer + - ``i`` -- integer - - ``from_list`` -- ignored + - ``from_list`` -- ignored EXAMPLES:: @@ -5252,13 +5222,13 @@ cdef class Matrix_integer_dense(Matrix_dense): def column(self, Py_ssize_t i, from_list=False): """ - Return the i-th column of this matrix as a dense vector. + Return the `i`-th column of this matrix as a dense vector. INPUT: - - ``i`` -- integer + - ``i`` -- integer - - ``from_list`` -- ignored + - ``from_list`` -- ignored EXAMPLES:: @@ -5356,10 +5326,10 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - ``right`` -- a matrix, vector or free module element, whose - dimensions are compatible with ``self``. + dimensions are compatible with ``self`` - - ``subdivide`` -- default: ``False`` -- request the resulting - matrix to have a new subdivision, separating ``self`` from ``right``. + - ``subdivide`` -- (default: ``False``) request the resulting + matrix to have a new subdivision, separating ``self`` from ``right`` OUTPUT: @@ -5436,7 +5406,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def insert_row(self, Py_ssize_t index, row): """ - Create a new matrix from self with. + Create a new matrix from ``self`` with. INPUT: @@ -5492,7 +5462,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def _delete_zero_columns(self): """ - Return matrix obtained from self by deleting all zero columns along + Return matrix obtained from ``self`` by deleting all zero columns along with the positions of those columns. OUTPUT: (matrix, list of integers) @@ -5515,12 +5485,12 @@ cdef class Matrix_integer_dense(Matrix_dense): def _insert_zero_columns(self, cols): """ - Return matrix obtained by self by inserting zero columns so that + Return matrix obtained by ``self`` by inserting zero columns so that the columns with positions specified in cols are all 0. INPUT: - - ``cols`` -- list of nonnegative integers + - ``cols`` -- list of nonnegative integers OUTPUT: matrix @@ -5556,7 +5526,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def _factor_out_common_factors_from_each_row(self): """ - Very very quickly modifies self so that the gcd of the entries in + Very very quickly modify ``self`` so that the gcd of the entries in each row is 1 by dividing each row by the common gcd. EXAMPLES:: @@ -5643,10 +5613,8 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - - - ``singular`` -- Singular interface instance (default: - None) - + - ``singular`` -- Singular interface instance (default: + ``None``) EXAMPLES:: @@ -5671,7 +5639,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def transpose(self): """ - Return the transpose of self, without changing self. + Return the transpose of self, without changing ``self``. EXAMPLES: @@ -5722,7 +5690,7 @@ cdef class Matrix_integer_dense(Matrix_dense): def antitranspose(self): """ - Return the antitranspose of self, without changing self. + Return the antitranspose of ``self``, without changing ``self``. EXAMPLES:: @@ -5747,12 +5715,12 @@ cdef class Matrix_integer_dense(Matrix_dense): [4|1] [3|0] """ - nr , nc = (self._nrows, self._ncols) + nr, nc = self._nrows, self._ncols cdef Matrix_integer_dense A A = self._new(nc,nr) - cdef Py_ssize_t i,j - cdef Py_ssize_t ri,rj # reversed i and j + cdef Py_ssize_t i, j + cdef Py_ssize_t ri, rj # reversed i and j sig_on() ri = nr for i from 0 <= i < nr: @@ -5760,7 +5728,8 @@ cdef class Matrix_integer_dense(Matrix_dense): ri = ri-1 for j from 0 <= j < nc: rj = rj-1 - fmpz_init_set(fmpz_mat_entry(A._matrix,rj,ri),fmpz_mat_entry(self._matrix,i,j)) + fmpz_init_set(fmpz_mat_entry(A._matrix, rj, ri), + fmpz_mat_entry(self._matrix, i, j)) sig_off() if self._subdivisions is not None: @@ -5809,11 +5778,10 @@ cdef class Matrix_integer_dense(Matrix_dense): INPUT: - ``flag`` -- 0 (default), 1, 3 or 4 (see docstring for - ``pari.mathnf``). + ``pari.mathnf``) - - ``include_zero_rows`` -- boolean. if False, do not include - any of the zero rows at the bottom of the matrix in the - output. + - ``include_zero_rows`` -- boolean; if ``False``, do not include + any of the zero rows at the bottom of the matrix in the output .. NOTE:: @@ -5890,7 +5858,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``p`` -- a prime in `\ZZ` - - ``s_max`` -- a positive integer (default: ``None``); if set, only + - ``s_max`` -- positive integer (default: ``None``); if set, only `(p^s)`-minimal polynomials for ``s <= s_max`` are computed (see below for details) @@ -5935,9 +5903,7 @@ cdef class Matrix_integer_dense(Matrix_dense): - ``b`` -- an element of `\ZZ` (default: 0) - OUTPUT: - - An ideal in `\ZZ[X]`. + OUTPUT: an ideal in `\ZZ[X]` EXAMPLES:: @@ -6054,16 +6020,13 @@ cpdef _lift_crt(Matrix_integer_dense M, residues, moduli=None): """ INPUT: - - ``M`` -- A ``Matrix_integer_dense``. Will be modified to hold - the output. - - - ``residues`` -- a list of ``Matrix_modn_dense_template``. The - matrix to reconstruct modulo primes. + - ``M`` -- a ``Matrix_integer_dense``; will be modified to hold + the output - OUTPUT: + - ``residues`` -- list of ``Matrix_modn_dense_template``; the + matrix to reconstruct modulo primes - The matrix whose reductions modulo primes are the input - ``residues``. + OUTPUT: the matrix whose reductions modulo primes are the input ``residues`` TESTS:: diff --git a/src/sage/matrix/matrix_integer_dense_hnf.py b/src/sage/matrix/matrix_integer_dense_hnf.py index c30927c6131..e64134ea184 100644 --- a/src/sage/matrix/matrix_integer_dense_hnf.py +++ b/src/sage/matrix/matrix_integer_dense_hnf.py @@ -24,11 +24,9 @@ def max_det_prime(n): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - OUTPUT: - - a prime number + OUTPUT: a prime number EXAMPLES:: @@ -48,18 +46,18 @@ def max_det_prime(n): def det_from_modp_and_divisor(A, d, p, z_mod, moduli, z_so_far=ZZ(1), N_so_far=ZZ(1)): """ This is used for internal purposes for computing determinants - quickly (with the hybrid p-adic / multimodular algorithm). + quickly (with the hybrid `p`-adic / multimodular algorithm). INPUT: - - A -- a square matrix - - d -- a divisor of the determinant of A - - p -- a prime - - z_mod -- values of det/d (mod ...) - - moduli -- the moduli so far - - z_so_far -- for a modulus p in the list moduli, - (z_so_far mod p) is the determinant of A modulo p. - - N_so_far -- N_so_far is the product over the primes in the list moduli. + - ``A`` -- a square matrix + - ``d`` -- a divisor of the determinant of A + - ``p`` -- a prime + - ``z_mod`` -- values of det/d (mod ...) + - ``moduli`` -- the moduli so far + - ``z_so_far`` -- for a modulus p in the list moduli, + (z_so_far mod p) is the determinant of A modulo p + - ``N_so_far`` -- N_so_far is the product over the primes in the list moduli OUTPUT: @@ -97,19 +95,17 @@ def det_given_divisor(A, d, proof=True, stabilize=2): INPUT: - - ``A`` -- a square integer matrix - - ``d`` -- a nonzero integer that is assumed to divide the determinant of A - - ``proof`` -- bool (default: ``True``) compute det modulo enough primes + - ``A`` -- square integer matrix + - ``d`` -- nonzero integer that is assumed to divide the determinant of A + - ``proof`` -- boolean (default: ``True``); compute det modulo enough primes so that the determinant is computed provably correctly (via the Hadamard bound). It would be VERY hard for ``det()`` to fail even - with proof=False. - - ``stabilize`` -- int (default: 2) if proof = False, then compute + when ``proof`` is ``False``. + - ``stabilize`` -- integer (default: 2); if proof = False, then compute the determinant modulo `p` until ``stabilize`` successive modulo determinant computations stabilize. - OUTPUT: - - integer -- determinant + OUTPUT: integer; determinant EXAMPLES:: @@ -135,7 +131,7 @@ def det_given_divisor(A, d, proof=True, stabilize=2): 0 This still works, because we do not work modulo primes that divide - the determinant bound, which is found using a p-adic algorithm:: + the determinant bound, which is found using a `p`-adic algorithm:: sage: a.det(proof=False, stabilize=2) 70368442188091 @@ -194,7 +190,7 @@ def det_given_divisor(A, d, proof=True, stabilize=2): def det_padic(A, proof=True, stabilize=2): """ - Return the determinant of A, computed using a p-adic/multimodular + Return the determinant of A, computed using a `p`-adic/multimodular algorithm. INPUT: @@ -203,8 +199,8 @@ def det_padic(A, proof=True, stabilize=2): - ``proof`` -- boolean - - ``stabilize`` (default: 2) -- if proof False, number of successive primes so that - CRT det must stabilize. + - ``stabilize`` -- (default: 2) if proof False, number of successive primes so that + CRT det must stabilize EXAMPLES:: @@ -235,15 +231,13 @@ def double_det(A, b, c, proof): INPUT: - - A -- an (n-1) x n matrix - - b -- a 1 x n matrix - - c -- a 1 x n matrix - - proof -- whether or not to compute the det modulo enough times to - provably compute the determinant. - - OUTPUT: + - ``A`` -- an (n-1) x n matrix + - ``b`` -- a 1 x n matrix + - ``c`` -- a 1 x n matrix + - ``proof`` -- whether or not to compute the det modulo enough times to + provably compute the determinant - - a pair of two integers. + OUTPUT: a pair of two integers EXAMPLES:: @@ -293,13 +287,12 @@ def add_column_fallback(B, a, proof): INPUT: - B -- a square matrix (may be singular) - a -- an n x 1 matrix, where B has n rows - proof -- bool; whether to prove result correct + - ``B`` -- a square matrix (may be singular) + - ``a`` -- an n x 1 matrix, where B has n rows + - ``proof`` -- boolean; whether to prove result correct - OUTPUT: - - x -- a vector such that H' = H_B.augment(x) is the HNF of A = B.augment(a). + OUTPUT: x; a vector such that ``H' = H_B.augment(x)`` is the HNF of + ``A = B.augment(a)`` EXAMPLES:: @@ -329,20 +322,18 @@ def add_column_fallback(B, a, proof): def solve_system_with_difficult_last_row(B, a): """ - Solve B*x = a when the last row of `B` contains huge entries using - a clever trick that reduces the problem to solve C*x = a where `C` + Solve ``B*x = a`` when the last row of `B` contains huge entries using + a clever trick that reduces the problem to solve ``C*x = a`` where `C` is `B` but with the last row replaced by something small, along with one easy null space computation. The latter are both solved `p`-adically. INPUT: - - B -- a square n x n nonsingular matrix with painful big bottom row. - - a -- an n x 1 column matrix - - OUTPUT: + - ``B`` -- a square n x n nonsingular matrix with painful big bottom row + - ``a`` -- an n x 1 column matrix - - the unique solution to B*x = a. + OUTPUT: the unique solution to ``B*x = a`` EXAMPLES:: @@ -419,14 +410,14 @@ def add_column(B, H_B, a, proof): INPUT: - - B -- a square matrix (may be singular) - - H_B -- the Hermite normal form of B - - a -- an n x 1 matrix, where B has n rows - - proof -- bool; whether to prove result correct, in case we use fallback method. + - ``B`` -- a square matrix (may be singular) + - ``H_B`` -- the Hermite normal form of B + - ``a`` -- an n x 1 matrix, where B has n rows + - ``proof`` -- boolean; whether to prove result correct, in case we use fallback method OUTPUT: - - x -- a vector such that H' = H_B.augment(x) is the HNF of A = B.augment(a). + - x -- a vector such that H' = H_B.augment(x) is the HNF of A = B.augment(a) EXAMPLES:: @@ -469,14 +460,14 @@ def add_row(A, b, pivots, include_zero_rows): INPUT: - - A -- a matrix in Hermite normal form with n column - - b -- an n x 1 row matrix - - pivots -- sorted list of integers; the pivot positions of A. + - ``A`` -- a matrix in Hermite normal form with n column + - ``b`` -- an n x 1 row matrix + - ``pivots`` -- sorted list of integers; the pivot positions of A OUTPUT: - - H -- the Hermite normal form of A.stack(b). - - new_pivots -- the pivot columns of H. + - ``H`` -- the Hermite normal form of A.stack(b) + - ``new_pivots`` -- the pivot columns of H EXAMPLES:: @@ -508,11 +499,9 @@ def pivots_of_hnf_matrix(H): INPUT: - - H -- a matrix that must be HNF - - OUTPUT: + - ``H`` -- a matrix that must be HNF - - list -- list of pivots + OUTPUT: list of pivots EXAMPLES:: @@ -542,11 +531,9 @@ def hnf_square(A, proof): """ INPUT: - - a nonsingular n x n matrix A over the integers. + - ``A`` -- a nonsingular n x n matrix over the integers - OUTPUT: - - - the Hermite normal form of A. + OUTPUT: the Hermite normal form of A EXAMPLES:: @@ -568,7 +555,7 @@ def hnf_square(A, proof): # Small cases -- do not use this algorithm if n <= 3: - return A.echelon_form(algorithm="pari") + return A.echelon_form(algorithm='pari') if A.rank() < A.nrows(): raise ValueError("matrix must have full rank") @@ -675,11 +662,9 @@ def probable_pivot_rows(A): INPUT: - - A -- a matrix - - OUTPUT: + - ``A`` -- a matrix - a tuple of integers + OUTPUT: a tuple of integers EXAMPLES:: @@ -699,11 +684,9 @@ def probable_pivot_columns(A): """ INPUT: - - A -- a matrix + - ``A`` -- a matrix - OUTPUT: - - a tuple of integers + OUTPUT: a tuple of integers EXAMPLES:: @@ -729,8 +712,8 @@ def ones(H, pivots): INPUT: - - H -- matrix in Hermite form - - pivots -- list of integers (all pivot positions of H). + - ``H`` -- matrix in Hermite form + - ``pivots`` -- list of integers (all pivot positions of H) OUTPUT: @@ -770,8 +753,8 @@ def extract_ones_data(H, pivots): INPUT: - - H -- a matrix in HNF - - pivots -- list of all pivot column positions of H + - ``H`` -- a matrix in HNF + - ``pivots`` -- list of all pivot column positions of H OUTPUT: @@ -779,9 +762,9 @@ def extract_ones_data(H, pivots): where onecol, onerow, non_onecol, non_onerow are as for the ones function, and C, D, E are matrices: - - C -- submatrix of all non-onecol columns and onecol rows - - D -- all non-onecol columns and other rows - - E -- inverse of D + - ``C`` -- submatrix of all non-onecol columns and onecol rows + - ``D`` -- all non-onecol columns and other rows + - ``E`` -- inverse of D If D is not invertible or there are 0 or more than 2 non onecols, then C, D, and E are set to None. @@ -833,9 +816,7 @@ def is_in_hnf_form(H, pivots): - ``H`` -- matrix - ``pivots`` -- sorted list of integers - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -880,9 +861,9 @@ def probable_hnf(A, include_zero_rows, proof): INPUT: - - A -- a matrix - - include_zero_rows -- bool - - proof -- bool + - ``A`` -- a matrix + - ``include_zero_rows`` -- boolean + - ``proof`` -- boolean OUTPUT: @@ -1012,12 +993,10 @@ def pad_zeros(A, nrows): INPUT: - - A -- a matrix - - nrows -- an integer that is at least as big as the number of rows of A. - - OUTPUT: + - ``A`` -- a matrix + - ``nrows`` -- integer that is at least as big as the number of rows of A - a matrix with nrows rows. + OUTPUT: a matrix with nrows rows EXAMPLES:: @@ -1047,15 +1026,15 @@ def hnf(A, include_zero_rows=True, proof=True): INPUT: - - A -- an n x m matrix A over the integers. - - include_zero_rows -- bool (default: ``True``) whether or not to include zero + - ``A`` -- an n x m matrix A over the integers + - ``include_zero_rows`` -- boolean (default: ``True``); whether or not to include zero rows in the output matrix - - proof -- whether or not to prove the result correct. + - ``proof`` -- whether or not to prove the result correct - OUTPUT: + OUTPUT: tuple of: - - matrix -- the Hermite normal form of A - - pivots -- the pivot column positions of A + - ``matrix`` -- the Hermite normal form of A + - ``pivots`` -- the pivot column positions of A EXAMPLES:: @@ -1123,13 +1102,13 @@ def hnf_with_transformation(A, proof=True): INPUT: - - A -- an n x m matrix A over the integers. - - proof -- whether or not to prove the result correct. + - ``A`` -- an n x m matrix A over the integers + - ``proof`` -- whether or not to prove the result correct - OUTPUT: + OUTPUT: tuple of: - - matrix -- the Hermite normal form H of A - - U -- a unimodular matrix such that U * A = H + - ``matrix`` -- the Hermite normal form H of A + - ``U`` -- a unimodular matrix such that U * A = H EXAMPLES:: @@ -1223,17 +1202,17 @@ def benchmark_magma_hnf(nrange, bits=4): def sanity_checks(times=50, n=8, m=5, proof=True, stabilize=2, check_using_magma=True): """ - Run random sanity checks on the modular p-adic HNF with tall and wide matrices + Run random sanity checks on the modular `p`-adic HNF with tall and wide matrices both dense and sparse. INPUT: - - times -- number of times to randomly try matrices with each shape - - n -- number of rows - - m -- number of columns - - proof -- test with proof true - - stabilize -- parameter to pass to hnf algorithm when proof is False - - check_using_magma -- if True use Magma instead of PARI to check + - ``times`` -- number of times to randomly try matrices with each shape + - ``n`` -- number of rows + - ``m`` -- number of columns + - ``proof`` -- test with proof true + - ``stabilize`` -- parameter to pass to hnf algorithm when proof is False + - ``check_using_magma`` -- if ``True`` use Magma instead of PARI to check correctness of computed HNF's. Since PARI's HNF is buggy and slow (as of 2008-02-16 non-pivot entries sometimes are not normalized to be nonnegative) the default is Magma. diff --git a/src/sage/matrix/matrix_integer_dense_saturation.py b/src/sage/matrix/matrix_integer_dense_saturation.py index 5b6c181de15..b537b041e08 100644 --- a/src/sage/matrix/matrix_integer_dense_saturation.py +++ b/src/sage/matrix/matrix_integer_dense_saturation.py @@ -17,9 +17,9 @@ def p_saturation(A, p, proof=True): """ INPUT: - - A -- a matrix over ZZ - - p -- a prime - - proof -- bool (default: ``True``) + - ``A`` -- a matrix over ZZ + - ``p`` -- a prime + - ``proof`` -- boolean (default: ``True``) OUTPUT: @@ -72,12 +72,10 @@ def random_sublist_of_size(k, n): """ INPUT: - - k -- an integer - - n -- an integer + - ``k`` -- integer + - ``n`` -- integer - OUTPUT: - - a randomly chosen sublist of range(k) of size n. + OUTPUT: a randomly chosen sublist of ``range(k)`` of size `n` EXAMPLES:: @@ -119,17 +117,15 @@ def random_sublist_of_size(k, n): def solve_system_with_difficult_last_row(B, A): """ - Solve the matrix equation B*Z = A when the last row of `B` + Solve the matrix equation ``B*Z = A`` when the last row of `B` contains huge entries. INPUT: - - B -- a square n x n nonsingular matrix with painful big bottom row. - - A -- an n x k matrix. + - ``B`` -- a square n x n nonsingular matrix with painful big bottom row + - ``A`` -- an n x k matrix - OUTPUT: - - the unique solution to B*Z = A. + OUTPUT: the unique solution to ``B*Z = As`` EXAMPLES:: @@ -186,21 +182,19 @@ def solve_system_with_difficult_last_row(B, A): return X def saturation(A, proof=True, p=0, max_dets=5): - """ - Compute a saturation matrix of A. + r""" + Compute a saturation matrix of `A`. INPUT: - - A -- a matrix over ZZ - - proof -- bool (default: ``True``) - - p -- int (default: 0); if not 0 only guarantees that output is - p-saturated - - max_dets -- int (default: 4) max number of dets of submatrices to - compute. - - OUTPUT: + - ``A`` -- a matrix over `\ZZ` + - ``proof`` -- boolean (default: ``True``) + - ``p`` -- integer (default: 0); if not 0 only guarantees that output is + `p`-saturated + - ``max_dets`` -- integer (default: 4); max number of dets of submatrices to + compute - matrix -- saturation of the matrix A. + OUTPUT: matrix; saturation of the matrix `A` EXAMPLES:: @@ -299,9 +293,7 @@ def index_in_saturation(A, proof=True): - ``proof`` -- boolean (``True`` or ``False``) - OUTPUT: - - An integer + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/matrix/matrix_integer_sparse.pyx b/src/sage/matrix/matrix_integer_sparse.pyx index 4771953bb63..ca8949e5cad 100644 --- a/src/sage/matrix/matrix_integer_sparse.pyx +++ b/src/sage/matrix/matrix_integer_sparse.pyx @@ -98,8 +98,8 @@ cdef class Matrix_integer_sparse(Matrix_sparse): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the - entries are of type :class:`Integer`. + - ``coerce`` -- if ``False``, assume without checking that the + entries are of type :class:`Integer` """ ma = MatrixArgs_init(parent, entries) cdef Integer z @@ -297,7 +297,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): def _nonzero_positions_by_row(self, copy=True): """ - Returns the list of pairs (i,j) such that self[i,j] != 0. + Return the list of pairs (i,j) such that ``self[i,j] != 0``. It is safe to change the resulting list (unless you give the option copy=False). @@ -326,7 +326,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): def _nonzero_positions_by_column(self, copy=True): """ - Returns the list of pairs (i,j) such that self[i,j] != 0, but + Return the list of pairs (i,j) such that ``self[i,j] != 0``, but sorted by columns, i.e., column j=0 entries occur first, then column j=1 entries, etc. @@ -358,16 +358,14 @@ cdef class Matrix_integer_sparse(Matrix_sparse): return nzc def _mod_int(self, modulus): - """ + r""" Helper function in reducing matrices mod n. INPUT: - - `modulus` -- a number - - OUTPUT: + - ``modulus`` -- a number - This matrix, over `ZZ/nZZ`. + OUTPUT: this matrix, over `\ZZ/n\ZZ` TESTS:: @@ -375,7 +373,6 @@ cdef class Matrix_integer_sparse(Matrix_sparse): sage: B = M._mod_int(7) sage: B.parent() Full MatrixSpace of 0 by 0 sparse matrices over Ring of integers modulo 7 - """ return self._mod_int_c(modulus) @@ -424,20 +421,20 @@ cdef class Matrix_integer_sparse(Matrix_sparse): def _right_kernel_matrix(self, **kwds): r""" - Returns a pair that includes a matrix of basis vectors + Return a pair that includes a matrix of basis vectors for the right kernel of ``self``. INPUT: - ``algorithm`` -- determines which algorithm to use, options are: - - 'pari' -- use the :pari:`matkerint` function from the PARI library - - 'padic' -- use the p-adic algorithm from the IML library - - 'default' -- use a heuristic to decide which of the two above + - ``'pari'`` -- use the :pari:`matkerint` function from the PARI library + - ``'padic'`` -- use the `p`-adic algorithm from the IML library + - ``'default'`` -- use a heuristic to decide which of the two above routines is fastest. This is the default value. - - ``proof`` -- this is passed to the p-adic IML algorithm. - If not specified, the global flag for linear algebra will be used. + - ``proof`` -- this is passed to the `p`-adic IML algorithm + If not specified, the global flag for linear algebra will be used OUTPUT: @@ -539,15 +536,13 @@ cdef class Matrix_integer_sparse(Matrix_sparse): INPUT: - - self -- matrix - - algorithm -- (default: 'pari') + - ``self`` -- matrix + - ``algorithm`` -- (default: ``'pari'``) - * 'pari': works robustly, but is slower. + * 'pari': works robustly, but is slower * 'linbox' -- use linbox (currently off, broken) - OUTPUT: - - list of integers + OUTPUT: list of integers EXAMPLES:: @@ -579,12 +574,12 @@ cdef class Matrix_integer_sparse(Matrix_sparse): INPUT: - - ``transformation`` -- a boolean (default: ``True``); whether to + - ``transformation`` -- boolean (default: ``True``); whether to return the transformation matrices `U` and `V` such that `S = U\cdot - self\cdot V`. + self\cdot V` - ``integral`` -- a subring of the base ring or ``True`` (default: - ``None``); ignored for matrices with integer entries. + ``None``); ignored for matrices with integer entries This version is for sparse matrices and simply makes the matrix dense and calls the version for dense integer matrices. @@ -803,9 +798,9 @@ cdef class Matrix_integer_sparse(Matrix_sparse): TESTS:: - sage: matrix(ZZ, 0, 0, sparse=True).charpoly(algorithm="linbox") + sage: matrix(ZZ, 0, 0, sparse=True).charpoly(algorithm='linbox') 1 - sage: matrix(ZZ, 0, 0, sparse=True).charpoly(algorithm="generic") + sage: matrix(ZZ, 0, 0, sparse=True).charpoly(algorithm='generic') 1 """ if self._nrows != self._ncols: @@ -904,9 +899,9 @@ cdef class Matrix_integer_sparse(Matrix_sparse): TESTS:: - sage: matrix(ZZ, 0, 0, sparse=True).minpoly(algorithm="linbox") + sage: matrix(ZZ, 0, 0, sparse=True).minpoly(algorithm='linbox') 1 - sage: matrix(ZZ, 0, 0, sparse=True).minpoly(algorithm="generic") + sage: matrix(ZZ, 0, 0, sparse=True).minpoly(algorithm='generic') 1 """ if self._nrows != self._ncols: @@ -980,7 +975,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): def _solve_right_nonsingular_square(self, B, algorithm=None, check_rank=False): r""" - If self is a matrix `A`, then this function returns a + If ``self`` is a matrix `A`, then this function returns a vector or matrix `X` such that `A X = B`. If `B` is a vector then `X` is a vector and if `B` is a matrix, then `X` is a matrix. @@ -993,25 +988,24 @@ cdef class Matrix_integer_sparse(Matrix_sparse): INPUT: + - ``B`` -- a matrix or vector - - ``B`` -- a matrix or vector - - - ``algorithm`` -- one of the following: + - ``algorithm`` -- one of the following: - ``'linbox'`` or ``'linbox_default'`` -- (default) use LinBox and let it chooses the appropriate algorithm - - ``linbox_dense_elimination'`` -- use LinBox dense elimination + - ``linbox_dense_elimination'`` -- use LinBox dense elimination - ``'linbox_sparse_elimination'`` -- use LinBox sparse elimination - - ``'linbox_ blackbox'`` -- LinBox via a Blackbox algorithm + - ``'linbox_ blackbox'`` -- LinBox via a Blackbox algorithm - - ``'linbox_wiedemann'`` -- use LinBox implementation of - Wiedemann's algorithm + - ``'linbox_wiedemann'`` -- use LinBox implementation of + Wiedemann's algorithm - - ``'generic'`` -- use the Sage generic implementation - (via inversion) + - ``'generic'`` -- use the Sage generic implementation + (via inversion) - ``check_rank`` -- whether to check that the rank is maximal @@ -1061,22 +1055,22 @@ cdef class Matrix_integer_sparse(Matrix_sparse): def _solve_vector_linbox(self, v, algorithm=None): r""" - Return a pair ``(a, d)`` so that ``d * b = m * a`` + Return a pair ``(a, d)`` so that ``d * b = m * a``. - If there is no solution a ``ValueError`` is raised. + If there is no solution a :exc:`ValueError` is raised. INPUT: - - ``b`` -- a dense integer vector + - ``b`` -- dense integer vector - ``algorithm`` -- (optional) either ``None``, ``'dense_elimination'``, - ``'sparse_elimination'``, ``'wiedemann'`` or ``'blackbox'``. + ``'sparse_elimination'``, ``'wiedemann'`` or ``'blackbox'`` OUTPUT: a pair ``(a, d)`` consisting of - - ``a`` -- a dense integer vector + - ``a`` -- dense integer vector - - ``d`` -- an integer + - ``d`` -- integer EXAMPLES:: diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index c352b52cea2..d18140c1ce8 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -76,11 +76,9 @@ cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): INPUT: - - ``i`` -- an integer + - ``i`` -- integer - OUTPUT: - - An ideal on the base ring. + OUTPUT: an ideal on the base ring EXAMPLES:: @@ -107,7 +105,6 @@ cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): (1,) sage: [R.ideal(M.minors(i)) == M._fitting_ideal(4 - i) for i in range(5)] [True, True, True, True, True] - """ R = self.base_ring() S = R.polynomial_ring() diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 3513a97da7d..35591735e57 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -38,7 +38,7 @@ def prm_mul(p1, p2, mask_free, prec): - `p1,p2` -- polynomials as dictionaries - - ``mask_free`` -- an integer mask that give the list of free variables + - ``mask_free`` -- integer mask that give the list of free variables (the `i`-th variable is free if the `i`-th bit of ``mask_free`` is `1`) - ``prec`` -- if ``prec`` is not ``None``, truncate the product at precision ``prec`` @@ -79,13 +79,13 @@ def permanental_minor_polynomial(A, permanent_only=False, var='t', prec=None): INPUT: - - `A` -- a matrix + - ``A`` -- a matrix - - `permanent_only` -- if True, return only the permanent of `A` + - ``permanent_only`` -- if ``True``, return only the permanent of `A` - - `var` -- name of the polynomial variable + - ``var`` -- name of the polynomial variable - - `prec` -- if prec is not None, truncate the polynomial at precision `prec` + - ``prec`` -- if prec is not None, truncate the polynomial at precision `prec` The polynomial of the sums of permanental minors is @@ -109,8 +109,8 @@ def permanental_minor_polynomial(A, permanent_only=False, var='t', prec=None): - ``A`` -- matrix - - ``permanent_only`` -- optional boolean. If ``True``, only the permanent - is computed (might be faster). + - ``permanent_only`` -- boolean (default: ``False``); if ``True``, only the + permanent is computed (might be faster) - ``var`` -- a variable name @@ -243,7 +243,7 @@ def permanental_minor_polynomial(A, permanent_only=False, var='t', prec=None): \right\rangle In fact the `t^k` coefficient of `g(t)` corresponds to choosing - `k` rows of `A`; `\eta_i` is associated to the i-th column; + `k` rows of `A`; `\eta_i` is associated to the `i`-th column; nilpotency avoids having twice the same column in a product of `A`'s. For more details, see the article [BP2015]_. diff --git a/src/sage/matrix/matrix_mod2_dense.pxd b/src/sage/matrix/matrix_mod2_dense.pxd index ea3575ef3be..8b9965f89d8 100644 --- a/src/sage/matrix/matrix_mod2_dense.pxd +++ b/src/sage/matrix/matrix_mod2_dense.pxd @@ -1,4 +1,4 @@ -from .matrix_dense cimport Matrix_dense +from sage.matrix.matrix_dense cimport Matrix_dense from sage.libs.m4ri cimport * cdef class Matrix_mod2_dense(Matrix_dense): diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index e84601ac37c..07c54d6add9 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -223,7 +223,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring EXAMPLES:: @@ -330,7 +330,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse # this exists for compatibility with matrix_modn_dense cdef void set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value) noexcept: """ - Set the (i,j) entry of self to the int value. + Set the (i,j) entry of ``self`` to the int value. """ mzd_write_bit(self._entries, i, j, int(value)) @@ -352,7 +352,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - ``rep_mapping`` -- a dictionary or callable used to override + - ``rep_mapping`` -- dictionary or callable used to override the usual representation of elements. For a dictionary, keys should be elements of the base ring and values the desired string representation. @@ -365,14 +365,14 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse use the value of ``plus_one`` as the representation of the one element. - - ``minus_one`` -- Ignored. Only for compatibility with + - ``minus_one`` -- ignored. Only for compatibility with generic matrices. - - ``unicode`` -- boolean (default: ``False``). - Whether to use Unicode symbols instead of ASCII symbols - for brackets and subdivision lines. + - ``unicode`` -- boolean (default: ``False``); + whether to use Unicode symbols instead of ASCII symbols + for brackets and subdivision lines - - ``shape`` -- one of ``"square"`` or ``"round"`` (default: ``None``). + - ``shape`` -- one of ``'square'`` or ``'round'`` (default: ``None``). Switches between round and square brackets. The default depends on the setting of the ``unicode`` keyword argument. For Unicode symbols, the default is round brackets @@ -477,7 +477,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def row(self, Py_ssize_t i, from_list=False): """ - Return the ``i``'th row of this matrix as a vector. + Return the ``i``-th row of this matrix as a vector. This row is a dense vector if and only if the matrix is a dense matrix. @@ -486,8 +486,8 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse - ``i`` -- integer - - ``from_list`` -- bool (default: ``False``); if ``True``, - returns the ``i``'th element of ``self.rows()`` (see + - ``from_list`` -- boolean (default: ``False``); if ``True``, + returns the ``i``-th element of ``self.rows()`` (see :func:`rows`), which may be faster, but requires building a list of all rows the first time it is called after an entry of the matrix is changed. @@ -527,7 +527,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def columns(self, copy=True): """ - Return list of the columns of self. + Return list of the columns of ``self``. INPUT: @@ -582,7 +582,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - right -- matrix of dimension self.nrows() x self.ncols() + - ``right`` -- matrix of dimension self.nrows() x self.ncols() EXAMPLES:: @@ -620,7 +620,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - right -- matrix of dimension self.nrows() x self.ncols() + - ``right`` -- matrix of dimension self.nrows() x self.ncols() EXAMPLES:: @@ -713,8 +713,8 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - right -- Matrix - - k -- parameter `k` for the Gray Code table size. If `k=0` a suitable + - ``right`` -- Matrix + - ``k`` -- parameter `k` for the Gray Code table size. If `k=0` a suitable value is chosen by the function. (`0<= k <= 16`, default: 0) EXAMPLES:: @@ -847,7 +847,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - ``right`` -- a matrix of matching dimensions. + - ``right`` -- a matrix of matching dimensions - ``cutoff`` -- matrix dimension where M4RM should be used instead of Strassen (default: let M4RI decide) @@ -921,10 +921,10 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def __invert__(self): """ - Inverts self using the 'Method of the Four Russians' + Invert ``self`` using the 'Method of the Four Russians' inversion. - If ``self`` is not invertible a ``ZeroDivisionError`` is + If ``self`` is not invertible a :exc:`ZeroDivisionError` is raised. EXAMPLES:: @@ -971,7 +971,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def __copy__(self): """ - Returns a copy of ``self``. + Return a copy of ``self``. EXAMPLES:: @@ -991,7 +991,6 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse sage: A.echelonize() sage: A.__copy__() == A True - """ cdef Matrix_mod2_dense A A = Matrix_mod2_dense.__new__(Matrix_mod2_dense, self._parent, 0, 0, 0) @@ -1006,7 +1005,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def _list(self): """ - Returns list of the elements of ``self`` in row major + Return list of the elements of ``self`` in row major ordering. EXAMPLES:: @@ -1044,22 +1043,22 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def echelonize(self, algorithm='heuristic', cutoff=0, reduced=True, **kwds): """ - Puts self in (reduced) row echelon form. + Puts ``self`` in (reduced) row echelon form. INPUT: - - self -- a mutable matrix - - algorithm + - ``self`` -- a mutable matrix + - ``algorithm`` -- string; one of - - 'heuristic' -- uses M4RI and PLUQ (default) - - 'm4ri' -- uses M4RI - - 'pluq' -- uses PLUQ factorization - - 'classical' -- uses classical Gaussian elimination + - ``'heuristic'`` -- uses M4RI and PLUQ (default) + - ``'m4ri'`` -- uses M4RI + - ``'pluq'`` -- uses PLUQ factorization + - ``'classical'`` -- uses classical Gaussian elimination - - k -- the parameter 'k' of the M4RI algorithm. It MUST be between 1 + - ``k`` -- the parameter 'k' of the M4RI algorithm. It MUST be between 1 and 16 (inclusive). If it is not specified it will be calculated as 3/4 * log_2( min(nrows, ncols) ) as suggested in the M4RI paper. - - reduced -- return reduced row echelon form (default: ``True``) + - ``reduced`` -- return reduced row echelon form (default: ``True``) EXAMPLES:: @@ -1168,7 +1167,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def _pivots(self): """ - Returns the pivot columns of ``self`` if ``self`` is in + Return the pivot columns of ``self`` if ``self`` is in row echelon form. EXAMPLES:: @@ -1207,14 +1206,12 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - ``density`` -- float; proportion (roughly) to be considered for - changes - - ``nonzero`` -- Bool (default: ``False``); whether the new entries - are forced to be non-zero - - OUTPUT: + - ``density`` -- float; proportion (roughly) to be considered for + changes + - ``nonzero`` -- boolean (default: ``False``); whether the new entries + are forced to be nonzero - - None, the matrix is modified in-space + OUTPUT: None, the matrix is modified in-space EXAMPLES:: @@ -1379,7 +1376,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def _magma_init_(self, magma): """ - Returns a string of self in ``Magma`` form. Does not return + Return a string of ``self`` in ``Magma`` form. Does not return ``Magma`` object but string. EXAMPLES:: @@ -1425,7 +1422,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def transpose(self): """ - Returns transpose of self and leaves self untouched. + Return transpose of ``self`` and leaves ``self`` untouched. EXAMPLES:: @@ -1700,10 +1697,10 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - row -- index of start row - - col -- index of start column - - nrows -- number of rows of submatrix - - ncols -- number of columns of submatrix + - ``row`` -- index of start row + - ``col`` -- index of start column + - ``nrows`` -- number of rows of submatrix + - ``ncols`` -- number of columns of submatrix EXAMPLES:: @@ -1853,7 +1850,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse INPUT: - - approx -- return floating point approximation (default: ``False``) + - ``approx`` -- return floating point approximation (default: ``False``) EXAMPLES:: @@ -1924,7 +1921,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse def _right_kernel_matrix(self, **kwds): r""" - Returns a pair that includes a matrix of basis vectors + Return a pair that includes a matrix of basis vectors for the right kernel of ``self``. INPUT: @@ -2051,9 +2048,9 @@ def unpickle_matrix_mod2_dense_v2(r, c, data, size, immutable=False): - ``r`` -- number of rows of matrix - ``c`` -- number of columns of matrix - - ``s`` -- a string + - ``s`` -- string - ``size`` -- length of the string ``s`` - - ``immutable`` -- (default: ``False``) whether the + - ``immutable`` -- boolean (default: ``False``); whether the matrix is immutable or not EXAMPLES:: @@ -2127,13 +2124,13 @@ register_unpickle_override('sage.matrix.matrix_mod2_dense', def from_png(filename): """ - Returns a dense matrix over GF(2) from a 1-bit PNG image read from + Return a dense matrix over GF(2) from a 1-bit PNG image read from ``filename``. No attempt is made to verify that the filename string actually points to a PNG image. INPUT: - - filename -- a string + - ``filename`` -- string EXAMPLES:: @@ -2176,12 +2173,12 @@ def from_png(filename): def to_png(Matrix_mod2_dense A, filename): """ - Saves the matrix ``A`` to filename as a 1-bit PNG image. + Save the matrix ``A`` to filename as a 1-bit PNG image. INPUT: - ``A`` -- a matrix over GF(2) - - ``filename`` -- a string for a file in a writable position + - ``filename`` -- string for a file in a writable position EXAMPLES:: @@ -2219,21 +2216,21 @@ def to_png(Matrix_mod2_dense A, filename): fclose(out) -def pluq(Matrix_mod2_dense A, algorithm="standard", int param=0): +def pluq(Matrix_mod2_dense A, algorithm='standard', int param=0): """ Return PLUQ factorization of A. INPUT: - - A -- matrix - - algorithm + - ``A`` -- matrix + - ``algorithm`` -- string; one of - * 'standard' asymptotically fast (default) - * 'mmpf' M4RI inspired - * 'naive' naive cubic + * ``'standard'`` asymptotically fast (default) + * ``'mmpf'`` M4RI inspired + * ``'naive'`` naive cubic - - param -- either k for 'mmpf' is chosen or matrix multiplication cutoff - for 'standard' (default: 0) + - ``param`` -- either k for 'mmpf' is chosen or matrix multiplication cutoff + for ``'standard'`` (default: 0) EXAMPLES:: @@ -2283,20 +2280,20 @@ def pluq(Matrix_mod2_dense A, algorithm="standard", int param=0): return B, P, Q -def ple(Matrix_mod2_dense A, algorithm="standard", int param=0): +def ple(Matrix_mod2_dense A, algorithm='standard', int param=0): """ Return PLE factorization of A. INPUT: - - A -- matrix - - algorithm + - ``A`` -- matrix + - ``algorithm`` -- string; one of - - 'standard' asymptotically fast (default) - - 'russian' M4RI inspired - - 'naive' naive cubic + - ``'standard'`` asymptotically fast (default) + - ``'russian'`` M4RI inspired + - ``'naive'`` naive cubic - - param -- either k for 'mmpf' is chosen or matrix multiplication + - ``param`` -- either k for 'mmpf' is chosen or matrix multiplication cutoff for 'standard' (default: 0) EXAMPLES:: diff --git a/src/sage/matrix/matrix_modn_dense_double.pyx b/src/sage/matrix/matrix_modn_dense_double.pyx index b112ffba912..ecb41e7d5dd 100644 --- a/src/sage/matrix/matrix_modn_dense_double.pyx +++ b/src/sage/matrix/matrix_modn_dense_double.pyx @@ -47,7 +47,7 @@ include "matrix_modn_dense_template.pxi" cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): r""" - Dense matrices over `\ZZ/n\ZZ` for `n < 94906266` using LinBox's ``Modular`` + Dense matrices over `\ZZ/n\ZZ` for `n < 94906266` using LinBox's ``Modular``. These are matrices with integer entries mod ``n`` represented as floating-point numbers in a 64-bit word for use with LinBox routines. @@ -61,7 +61,7 @@ cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): def __cinit__(self): """ - The Cython constructor + The Cython constructor. TESTS:: @@ -75,7 +75,7 @@ cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): cdef void set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value) noexcept: r""" - Set the (i,j) entry of self to the int value. + Set the (i,j) entry of ``self`` to the int value. EXAMPLES:: diff --git a/src/sage/matrix/matrix_modn_dense_float.pyx b/src/sage/matrix/matrix_modn_dense_float.pyx index 73fbe175d95..13dedf8441c 100644 --- a/src/sage/matrix/matrix_modn_dense_float.pyx +++ b/src/sage/matrix/matrix_modn_dense_float.pyx @@ -44,7 +44,7 @@ include "matrix_modn_dense_template.pxi" cdef class Matrix_modn_dense_float(Matrix_modn_dense_template): r""" - Dense matrices over `\ZZ/n\ZZ` for `n < 2^{8}` using LinBox's ``Modular`` + Dense matrices over `\ZZ/n\ZZ` for `n < 2^{8}` using LinBox's ``Modular``. These are matrices with integer entries mod ``n`` represented as floating-point numbers in a 32-bit word for use with LinBox routines. @@ -57,7 +57,7 @@ cdef class Matrix_modn_dense_float(Matrix_modn_dense_template): """ def __cinit__(self): """ - The Cython constructor + The Cython constructor. TESTS:: @@ -69,7 +69,7 @@ cdef class Matrix_modn_dense_float(Matrix_modn_dense_template): cdef void set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value) noexcept: r""" - Set the (i,j) entry of self to the int value. + Set the (i,j) entry of ``self`` to the int value. EXAMPLES:: diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 500f531e3b6..36830da0549 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -403,7 +403,7 @@ cpdef __matrix_from_rows_of_matrices(X): INPUT: - ``X`` -- a nonempty list of matrices of the same size mod a - single modulus `n` + single modulus `n` EXAMPLES:: @@ -412,9 +412,9 @@ cpdef __matrix_from_rows_of_matrices(X): sage: all(list(Y[i]) == X[i].list() for i in range(10)) True - OUTPUT: A single matrix mod ``p`` whose ``i``-th row is ``X[i].list()``. + OUTPUT: a single matrix mod ``p`` whose ``i``-th row is ``X[i].list()``. - .. note:: + .. NOTE:: Do not call this function directly but use the static method ``Matrix_modn_dense_float/double._matrix_from_rows_of_matrices`` @@ -854,10 +854,9 @@ cdef class Matrix_modn_dense_template(Matrix_dense): A.subdivide(*self.subdivisions()) return A - cpdef _add_(self, right): r""" - Add two dense matrices over `\Z/n\Z` + Add two dense matrices over `\Z/n\Z`. INPUT: @@ -898,10 +897,9 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sig_off() return M - cpdef _sub_(self, right): r""" - Subtract two dense matrices over `\Z/n\Z` + Subtract two dense matrices over `\Z/n\Z`. EXAMPLES:: @@ -989,7 +987,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef _matrix_times_matrix_(self, Matrix right): """ - return ``self*right`` + Return ``self*right``. INPUT: @@ -1147,7 +1145,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef _vector_times_matrix_(self, Vector v): """ - ``v*self`` + Return ``v*self``. INPUT: @@ -1174,7 +1172,6 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: v = random_vector(Integers(16337), 10) # needs sage.rings.finite_rings sage: matrix(v*A) == matrix(v)*A True - """ if not isinstance(v, Vector_modn_dense): return (self.new_matrix(1,self._nrows, entries=v.list()) * self)[0] @@ -1204,7 +1201,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef _matrix_times_vector_(self, Vector v): """ - ``self*v`` + Return ``self*v``. EXAMPLES:: @@ -1381,7 +1378,6 @@ cdef class Matrix_modn_dense_template(Matrix_dense): (y,) sage: A._cache['charpoly_linbox'].variables() (x,) - """ cache_key = 'charpoly_%s' % algorithm g = self.fetch(cache_key) @@ -1406,10 +1402,9 @@ cdef class Matrix_modn_dense_template(Matrix_dense): self.cache(cache_key, g) return g - def minpoly(self, var='x', algorithm='linbox', proof=None): """ - Returns the minimal polynomial of`` self``. + Return the minimal polynomial of ``self``. INPUT: @@ -1418,7 +1413,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): - ``algorithm`` -- ``generic`` or ``linbox`` (default: ``linbox``) - - ``proof`` -- (default: ``True``); whether to provably return + - ``proof`` -- (default: ``True``) whether to provably return the true minimal polynomial; if ``False``, we only guarantee to return a divisor of the minimal polynomial. There are also certainly cases where the computed results is @@ -1545,7 +1540,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def _charpoly_linbox(self, var='x'): """ - Computes the characteristic polynomial using LinBox. No checks + Compute the characteristic polynomial using LinBox. No checks are performed. This function is called internally by ``charpoly``. @@ -1578,7 +1573,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): r = R(v) return r - def echelonize(self, algorithm="linbox_noefd", **kwds): + def echelonize(self, algorithm='linbox_noefd', **kwds): """ Put ``self`` in reduced row echelon form. @@ -1593,23 +1588,21 @@ cdef class Matrix_modn_dense_template(Matrix_dense): - ``linbox_noefd`` -- uses the FFPACK directly, less memory and faster (default) - ``gauss`` -- uses a custom slower `O(n^3)` Gauss - elimination implemented in Sage. + elimination implemented in Sage - ``all`` -- compute using both algorithms and verify that - the results are the same. + the results are the same - ``**kwds`` -- these are all ignored - OUTPUT: + OUTPUT: ``self`` is put in reduced row echelon form - - ``self`` is put in reduced row echelon form. + - the rank of ``self`` is computed and cached - - the rank of self is computed and cached + - the pivot columns of ``self`` are computed and cached - - the pivot columns of self are computed and cached. - - - the fact that self is now in echelon form is recorded and - cached so future calls to echelonize return immediately. + - the fact that ``self`` is now in echelon form is recorded and + cached so future calls to echelonize return immediately EXAMPLES:: @@ -1853,7 +1846,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def right_kernel_matrix(self, algorithm='linbox', basis='echelon'): r""" - Returns a matrix whose rows form a basis for the right kernel + Return a matrix whose rows form a basis for the right kernel of ``self``. If the base ring is the ring of integers modulo a composite, @@ -1962,7 +1955,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def hessenbergize(self): """ - Transforms self in place to its Hessenberg form. + Transform ``self`` in place to its Hessenberg form. EXAMPLES:: @@ -2032,19 +2025,19 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def _charpoly_hessenberg(self, var): """ - Transforms self in place to its Hessenberg form then computes + Transform ``self`` in place to its Hessenberg form then computes and returns the coefficients of the characteristic polynomial of this matrix. INPUT: - - ``var`` -- name of the indeterminate of the charpoly. + - ``var`` -- name of the indeterminate of the charpoly OUTPUT: The characteristic polynomial is represented as a vector of ints, where the constant term of the characteristic - polynomial is the 0th coefficient of the vector. + polynomial is the `0`-th coefficient of the vector. EXAMPLES:: @@ -2293,9 +2286,9 @@ cdef class Matrix_modn_dense_template(Matrix_dense): - ``row1``, ``row2`` -- the two rows to be transformed (within ``self``) - -``start_col`` -- the column of the pivots in ``row1`` and - ``row2``. It is assumed that all entries before ``start_col`` - in ``row1`` and ``row2`` are zero. + - ``start_col`` -- the column of the pivots in ``row1`` and + ``row2``. It is assumed that all entries before ``start_col`` + in ``row1`` and ``row2`` are zero. OUTPUT: @@ -2535,14 +2528,12 @@ cdef class Matrix_modn_dense_template(Matrix_dense): INPUT: - - ``density`` -- Integer; proportion (roughly) to be considered - for changes - - ``nonzero`` -- Bool (default: ``False``); whether the new - entries are forced to be non-zero - - OUTPUT: + - ``density`` -- integer; proportion (roughly) to be considered + for changes + - ``nonzero`` -- boolean (default: ``False``); whether the new + entries are forced to be nonzero - - None, the matrix is modified in-space + OUTPUT: none, the matrix is modified in-space EXAMPLES:: @@ -2650,11 +2641,11 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def _magma_init_(self, magma): """ - Returns a string representation of ``self`` in Magma form. + Return a string representation of ``self`` in Magma form. INPUT: - - ``magma`` -- a Magma session + - ``magma`` -- a Magma session OUTPUT: string @@ -2967,16 +2958,16 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def submatrix(self, Py_ssize_t row=0, Py_ssize_t col=0, Py_ssize_t nrows=-1, Py_ssize_t ncols=-1): r""" - Return the matrix constructed from self using the specified + Return the matrix constructed from ``self`` using the specified range of rows and columns. INPUT: - - ``row``, ``col`` -- index of the starting row and column. - Indices start at zero + - ``row``, ``col`` -- index of the starting row and column; + indices start at zero - ``nrows``, ``ncols`` -- (optional) number of rows and columns to - take. If not provided, take all rows below and all columns to + take; if not provided, take all rows below and all columns to the right of the starting entry .. SEEALSO:: @@ -3065,9 +3056,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): [2 3], [6 7], [10 11], [14 15] ] - OUTPUT: - - - ``list`` -- a list of matrices + OUTPUT: list of matrices """ if nrows * ncols != self._ncols: raise ValueError("nrows * ncols must equal self's number of columns") @@ -3084,7 +3073,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def matrix_from_columns(self, columns): """ - Return the matrix constructed from self using columns with indices + Return the matrix constructed from ``self`` using columns with indices in the columns list. EXAMPLES:: @@ -3114,7 +3103,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def matrix_from_rows(self, rows): """ - Return the matrix constructed from self using rows with indices in + Return the matrix constructed from ``self`` using rows with indices in the rows list. EXAMPLES:: @@ -3143,7 +3132,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): def matrix_from_rows_and_columns(self, rows, columns): """ - Return the matrix constructed from self from the given rows and + Return the matrix constructed from ``self`` from the given rows and columns. EXAMPLES:: diff --git a/src/sage/matrix/matrix_modn_sparse.pyx b/src/sage/matrix/matrix_modn_sparse.pyx index e5b7ca0b619..3334744500c 100644 --- a/src/sage/matrix/matrix_modn_sparse.pyx +++ b/src/sage/matrix/matrix_modn_sparse.pyx @@ -163,7 +163,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the + - ``coerce`` -- if ``False``, assume without checking that the entries lie in the base ring """ ma = MatrixArgs_init(parent, entries) @@ -257,7 +257,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): cdef Matrix _matrix_times_matrix_(self, Matrix _right): """ - This code is implicitly called for multiplying self by another + This code is implicitly called for multiplying ``self`` by another sparse matrix. EXAMPLES:: @@ -332,7 +332,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): def _matrix_times_matrix_dense(self, Matrix _right): """ - Multiply self by the sparse matrix _right, and return the + Multiply ``self`` by the sparse matrix ``_right``, and return the result as a dense matrix. EXAMPLES:: @@ -403,7 +403,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): cpdef _echelon_in_place(self, str algorithm): """ - Replace self by its reduction to reduced row echelon form. + Replace ``self`` by its reduction to reduced row echelon form. ALGORITHM: We use Gauss elimination, in a slightly intelligent way, in that we clear each column using a row with the minimum number of @@ -504,9 +504,8 @@ cdef class Matrix_modn_sparse(Matrix_sparse): def density(self): """ - Return the density of self, i.e., the ratio of the number of - nonzero entries of self to the total size of self. - + Return the density of ``self``, i.e., the ratio of the number of + nonzero entries of ``self`` to the total size of ``self``. EXAMPLES:: @@ -540,7 +539,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): def transpose(self): """ - Return the transpose of self. + Return the transpose of ``self``. EXAMPLES:: @@ -577,14 +576,12 @@ cdef class Matrix_modn_sparse(Matrix_sparse): def matrix_from_rows(self, rows): """ - Return the matrix constructed from self using rows with indices in + Return the matrix constructed from ``self`` using rows with indices in the rows list. INPUT: - - - ``rows`` -- list or tuple of row indices - + - ``rows`` -- list or tuple of row indices EXAMPLES:: @@ -620,7 +617,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): def matrix_from_columns(self, cols): """ - Return the matrix constructed from self using columns with indices + Return the matrix constructed from ``self`` using columns with indices in the columns list. EXAMPLES:: @@ -722,8 +719,8 @@ cdef class Matrix_modn_sparse(Matrix_sparse): INPUT: - - ``algorithm`` -- either ``"linbox"`` (only available for - matrices over prime fields) or ``"generic"`` + - ``algorithm`` -- either ``'linbox'`` (only available for + matrices over prime fields) or ``'generic'`` EXAMPLES:: @@ -736,19 +733,19 @@ cdef class Matrix_modn_sparse(Matrix_sparse): 2 sage: A._clear_cache() - sage: A.rank(algorithm="generic") + sage: A.rank(algorithm='generic') 2 sage: A._clear_cache() - sage: A.rank(algorithm="hey") + sage: A.rank(algorithm='hey') Traceback (most recent call last): ... ValueError: no algorithm 'hey' TESTS:: - sage: matrix(GF(3), 0, sparse=True).rank(algorithm="generic") + sage: matrix(GF(3), 0, sparse=True).rank(algorithm='generic') 0 - sage: matrix(GF(3), 0, sparse=True).rank(algorithm="linbox") + sage: matrix(GF(3), 0, sparse=True).rank(algorithm='linbox') 0 sage: for _ in range(50): @@ -757,8 +754,8 @@ cdef class Matrix_modn_sparse(Matrix_sparse): ....: p = random_prime(10000) ....: M = MatrixSpace(GF(p), nrows, ncols, sparse=True) ....: m = M.random_element() - ....: rank_linbox = m.rank(algorithm="linbox") - ....: rank_generic = m.rank(algorithm="generic") + ....: rank_linbox = m.rank(algorithm='linbox') + ....: rank_generic = m.rank(algorithm='generic') ....: if rank_linbox != rank_generic: ....: print(m) ....: raise RuntimeError @@ -806,7 +803,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): INPUT: - - ``algorithm`` -- either ``"linbox"`` (default) or ``"generic"``. + - ``algorithm`` -- either ``'linbox'`` (default) or ``'generic'`` EXAMPLES:: @@ -814,11 +811,11 @@ cdef class Matrix_modn_sparse(Matrix_sparse): sage: B = identity_matrix(GF(3), 4, sparse=True) sage: (A + B).det() 2 - sage: (A + B).det(algorithm="linbox") + sage: (A + B).det(algorithm='linbox') 2 - sage: (A + B).det(algorithm="generic") + sage: (A + B).det(algorithm='generic') 2 - sage: (A + B).det(algorithm="hey") + sage: (A + B).det(algorithm='hey') Traceback (most recent call last): ... ValueError: no algorithm 'hey' @@ -830,9 +827,9 @@ cdef class Matrix_modn_sparse(Matrix_sparse): TESTS:: - sage: matrix(GF(3), 0, sparse=True).det(algorithm="generic") + sage: matrix(GF(3), 0, sparse=True).det(algorithm='generic') 1 - sage: matrix(GF(3), 0, sparse=True).det(algorithm="linbox") + sage: matrix(GF(3), 0, sparse=True).det(algorithm='linbox') 1 sage: for _ in range(100): @@ -840,8 +837,8 @@ cdef class Matrix_modn_sparse(Matrix_sparse): ....: p = random_prime(10000) ....: M = MatrixSpace(GF(p), dim, sparse=True) ....: m = M.random_element() - ....: det_linbox = m.det(algorithm="linbox") - ....: det_generic = m.det(algorithm="generic") + ....: det_linbox = m.det(algorithm='linbox') + ....: det_generic = m.det(algorithm='generic') ....: assert parent(det_linbox) == m.base_ring() ....: assert parent(det_generic) == m.base_ring() ....: if det_linbox != det_generic: diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index 8117911fa38..a85918a003f 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -129,9 +129,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): This returns a list, of the position of the first nonzero entry in each row of the echelon form. - OUTPUT: - - A list of Python ints. + OUTPUT: list of Python ints EXAMPLES:: @@ -158,7 +156,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): def echelonize(self, algorithm='row_reduction', **kwds): """ - Transform self into a matrix in echelon form over the same base ring as + Transform ``self`` into a matrix in echelon form over the same base ring as ``self``. If Gauss-Bareiss algorithm is chosen, column swaps are recorded and can @@ -388,12 +386,12 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): nr,nc = self.nrows(),self.ncols() F = self.base_ring().base_ring() - cdef Matrix d = matrix(F,nr,nc) + cdef Matrix d = matrix(F, nr, nc) start_row = 0 for r from 0 <= r < nr: for c from 0 <= c < nc: - p = self.get_unsafe(r,c) + p = self.get_unsafe(r, c) if p.is_constant(): d.set_unsafe(r, c, p.constant_coefficient()) @@ -404,13 +402,13 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): r = rc break if r!=-1: - a_inverse = ~self.get_unsafe(r,c) - self.rescale_row_c(r, a_inverse , c) + a_inverse = ~self.get_unsafe(r, c) + self.rescale_row_c(r, a_inverse, c) self.swap_rows_c(r, start_row) for i from 0 <= i < nr: if i != start_row: - minus_b = -self.get_unsafe(i,c) + minus_b = -self.get_unsafe(i, c) self.add_multiple_of_row(i, start_row, minus_b, 0) start_row +=1 @@ -418,21 +416,21 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): d = d._parent(0) for i from start_row <= i < nr: for j from c+1 <= j < nc: - if self.get_unsafe(i,j).is_constant(): - d.set_unsafe(i,j, self.get_unsafe(i,j).constant_coefficient()) + if self.get_unsafe(i, j).is_constant(): + d.set_unsafe(i, j, self.get_unsafe(i, j).constant_coefficient()) - self.cache('in_echelon_form_row_reduction',True) + self.cache('in_echelon_form_row_reduction', True) def swapped_columns(self): """ - Return which columns were swapped during the Gauss-Bareiss reduction + Return which columns were swapped during the Gauss-Bareiss reduction. OUTPUT: Return a tuple representing the column swaps during the last application of the Gauss-Bareiss algorithm (see :meth:`echelon_form` for details). - The tuple as length equal to the rank of self and the value at the + The tuple as length equal to the rank of ``self`` and the value at the `i`-th position indicates the source column which was put as the `i`-th column. @@ -459,11 +457,9 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): INPUT: - - ``i`` -- an integer + - ``i`` -- integer - OUTPUT: - - An ideal on the base ring. + OUTPUT: an ideal on the base ring EXAMPLES:: @@ -485,7 +481,6 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): Ideal (1) of Multivariate Polynomial Ring in x, y, z over Rational Field sage: [R.ideal(M.minors(i)) == M._fitting_ideal(4 - i) for i in range(5)] [True, True, True, True, True] - """ minor = singular_function("minor") R = self.base_ring() diff --git a/src/sage/matrix/matrix_numpy_dense.pyx b/src/sage/matrix/matrix_numpy_dense.pyx index 6a4027bd622..e6420bf29c8 100644 --- a/src/sage/matrix/matrix_numpy_dense.pyx +++ b/src/sage/matrix/matrix_numpy_dense.pyx @@ -183,9 +183,8 @@ cdef class Matrix_numpy_dense(Matrix_dense): INPUT: - - nrows -- (default self._nrows) number of rows in returned matrix - - ncols -- (default self._ncols) number of columns in returned matrix - + - ``nrows`` -- (default: ``self._nrows``) number of rows in returned matrix + - ``ncols`` -- (default: ``self._ncols``) number of columns in returned matrix """ cdef Matrix_numpy_dense m if nrows == -1 and ncols == -1: @@ -240,7 +239,7 @@ cdef class Matrix_numpy_dense(Matrix_dense): def transpose(self): """ - Return the transpose of this matrix, without changing self. + Return the transpose of this matrix, without changing ``self``. EXAMPLES:: @@ -267,7 +266,6 @@ cdef class Matrix_numpy_dense(Matrix_dense): [] sage: m.transpose().parent() Full MatrixSpace of 3 by 0 dense matrices over Real Double Field - """ if self._nrows == 0 or self._ncols == 0: return self.new_matrix(self._ncols, self._nrows) @@ -336,7 +334,7 @@ cdef class Matrix_numpy_dense(Matrix_dense): INPUT: - - ``tol`` -- the largest value of the absolute value of the + - ``tol`` -- the largest value of the absolute value of the difference between two matrix entries for which they will still be considered equal. @@ -374,7 +372,7 @@ cdef class Matrix_numpy_dense(Matrix_dense): INPUT: - - ``dtype`` -- The desired data-type for the array. If not given, + - ``dtype`` -- the desired data-type for the array. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. diff --git a/src/sage/matrix/matrix_numpy_integer_dense.pyx b/src/sage/matrix/matrix_numpy_integer_dense.pyx index 8c449a86abf..d241ca57ac1 100644 --- a/src/sage/matrix/matrix_numpy_integer_dense.pyx +++ b/src/sage/matrix/matrix_numpy_integer_dense.pyx @@ -2,7 +2,6 @@ r""" Dense integer matrices using a NumPy backend - EXAMPLES:: sage: from sage.matrix.matrix_numpy_integer_dense import Matrix_numpy_integer_dense diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 57f7bc5338c..5b3c56ae573 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -110,11 +110,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``shifts`` -- list of integers, or ``None``. + - ``shifts`` -- list of integers, or ``None`` - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then shifts apply to the columns of the matrix and otherwise to its - rows (see the class description for more details). + rows (see the class description for more details) EXAMPLES:: @@ -140,7 +140,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): of all its entries. If the matrix is nonzero, this is a nonnegative integer; here, the degree of the zero matrix is -1. - OUTPUT: an integer. + OUTPUT: integer EXAMPLES:: @@ -188,13 +188,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then shifts apply to the columns of the matrix and otherwise to its - rows (see the class description for more details). + rows (see the class description for more details) - OUTPUT: an integer matrix. + OUTPUT: integer matrix EXAMPLES:: @@ -242,7 +242,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Return the constant coefficient of this matrix seen as a polynomial with matrix coefficients; this is also this matrix evaluated at zero. - OUTPUT: a matrix over the base field. + OUTPUT: a matrix over the base field EXAMPLES:: @@ -267,7 +267,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Return whether this polynomial matrix is constant, that is, all its entries are constant. - OUTPUT: a boolean. + OUTPUT: boolean EXAMPLES:: @@ -300,20 +300,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): entries; - if `d` is a list `(d_1,\ldots,d_m)` and ``row_wise`` is ``True``, this selects the coefficient of degree `d_i` for all entries of the - `i`th row for each `i`; + `i`-th row for each `i`; - if `d` is a list `(d_1,\ldots,d_n)` and ``row_wise`` is ``False``, this selects the coefficient of degree `d_i` for all entries of the - `j`th column for each `j`. + `j`-th column for each `j`. INPUT: - - ``d`` -- a list of integers, or an integer, + - ``d`` -- list of integers, or an integer, - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` (resp. ``False``) then `d` should be a list of length equal to the - row (resp. column) dimension of this matrix. + row (resp. column) dimension of this matrix - OUTPUT: a matrix over the base field. + OUTPUT: a matrix over the base field EXAMPLES:: @@ -392,10 +392,10 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): - if `d` is an integer, the truncation is at precision `d` for all entries; - if `d` is a list `(d_1,\ldots,d_m)` and ``row_wise`` is ``True``, all - entries of the `i`th row are truncated at precision `d_i` for each + entries of the `i`-th row are truncated at precision `d_i` for each `i`; - if `d` is a list `(d_1,\ldots,d_n)` and ``row_wise`` is ``False``, - all entries of the `j`th column are truncated at precision `d_j` for + all entries of the `j`-th column are truncated at precision `d_j` for each `j`. Here the convention for univariate polynomials is to take zero @@ -403,13 +403,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``d`` -- a list of integers, or an integer, + - ``d`` -- list of integers, or an integer, - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` (resp. ``False``) then `d` should be a list of length equal to the - row (resp. column) dimension of this matrix. + row (resp. column) dimension of this matrix - OUTPUT: a polynomial matrix. + OUTPUT: a polynomial matrix EXAMPLES:: @@ -484,9 +484,9 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): - if `d` is an integer, the shift is by `d` for all entries; - if `d` is a list `(d_1,\ldots,d_m)` and ``row_wise`` is ``True``, all - entries of the `i`th row are shifted by `d_i` for each `i`; + entries of the `i`-th row are shifted by `d_i` for each `i`; - if `d` is a list `(d_1,\ldots,d_n)` and ``row_wise`` is ``False``, - all entries of the `j`th column are shifted by `d_j` for each `j`. + all entries of the `j`-th column are shifted by `d_j` for each `j`. Shifting by `d` means multiplying by the variable to the power `d`; if `d` is negative then terms of negative degree after shifting are @@ -494,13 +494,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``d`` -- a list of integers, or an integer, + - ``d`` -- list of integers, or an integer, - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` (resp. ``False``) then `d` should be a list of length equal to the - row (resp. column) dimension of this matrix. + row (resp. column) dimension of this matrix - OUTPUT: a polynomial matrix. + OUTPUT: a polynomial matrix EXAMPLES:: @@ -590,25 +590,25 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): - if ``degree`` is not provided, then all entries are reversed with respect to the degree of the whole matrix; - if ``degree`` is a list `(d_1,\ldots,d_m)` and ``row_wise`` is - ``True``, all entries of the `i`th row are reversed with respect to + ``True``, all entries of the `i`-th row are reversed with respect to `d_i` for each `i`; - if ``degree`` is a list `(d_1,\ldots,d_n)` and ``row_wise`` is - ``False``, all entries of the `j`th column are reversed with respect + ``False``, all entries of the `j`-th column are reversed with respect to `d_j` for each `j`. INPUT: - ``degree`` -- (default: ``None``) a list of nonnegative - integers, or a nonnegative integer, + integers, or a nonnegative integer - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` (resp. ``False``) then ``degree`` should be a list of length equal to - the row (resp. column) dimension of this matrix. + the row (resp. column) dimension of this matrix - - ``entry_wise`` -- (default: ``False``) boolean, if ``True`` - then the input ``degree`` and ``row_wise`` are ignored. + - ``entry_wise`` -- boolean (default: ``False``); if ``True`` + then the input ``degree`` and ``row_wise`` are ignored - OUTPUT: a polynomial matrix. + OUTPUT: a polynomial matrix EXAMPLES:: @@ -680,7 +680,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: M.reverse([2,3,-1]) Traceback (most recent call last): ... - ValueError: degree argument must be a non-negative integer, got -1 + ValueError: degree argument must be a nonnegative integer, got -1 .. SEEALSO:: @@ -729,12 +729,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): on that univariate polynomial, and 3) converts back to a matrix of polynomials. - Raises a ``ZeroDivisionError`` if the constant matrix of ``self`` is + Raises a :exc:`ZeroDivisionError` if the constant matrix of ``self`` is not invertible (i.e. has zero determinant); raises an - ``ArithmeticError`` if ``self`` is nonsquare; and raises a - ``ValueError`` if the precision ``d`` is not positive. + :exc:`ArithmeticError` if ``self`` is nonsquare; and raises a + :exc:`ValueError` if the precision ``d`` is not positive. - INPUT: a positive integer `d` . + INPUT: + + - ``d`` -- positive integer OUTPUT: the unique polynomial matrix `B` of degree less than `d` such that `AB` and `BA` are the identity matrix modulo `x^d`, where `A` is @@ -816,15 +818,15 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): matrix `X` such that `X A = B \bmod x^d`. If `B` is a vector then `X` is a vector, and if `B` is a matrix then `X` is a matrix. - Raises ``ValueError`` if ``d`` is not strictly positive, or if there is + Raises :exc:`ValueError` if ``d`` is not strictly positive, or if there is a dimension mismatch between `A` and `B`, or if there is no solution to the given matrix equation at the specified precision. INPUT: - - ``B`` -- a polynomial matrix or polynomial vector. + - ``B`` -- a polynomial matrix or polynomial vector - - ``d`` -- a positive integer. + - ``d`` -- positive integer OUTPUT: @@ -964,15 +966,15 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): matrix `X` such that `A X = B \bmod x^d`. If `B` is a vector then `X` is a vector, and if `B` is a matrix then `X` is a matrix. - Raises ``ValueError`` if ``d`` is not strictly positive, or if there is + Raises :exc:`ValueError` if ``d`` is not strictly positive, or if there is a dimension mismatch between `A` and `B`, or if there is no solution to the given matrix equation at the specified precision. INPUT: - - ``B`` -- a polynomial matrix or polynomial vector. + - ``B`` -- a polynomial matrix or polynomial vector - - ``d`` -- a positive integer. + - ``d`` -- positive integer OUTPUT: @@ -1085,9 +1087,9 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - OUTPUT: a list of integers. + OUTPUT: list of integers REFERENCES: @@ -1160,9 +1162,9 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - OUTPUT: a list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -1234,12 +1236,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - OUTPUT: a matrix over the base field. + OUTPUT: a matrix over the base field REFERENCES: @@ -1311,14 +1313,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - one considers the row-wise shifted Popov form. + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + one considers the row-wise shifted Popov form - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if one does not allow zero rows in row reduced forms (resp. - zero columns in column reduced forms). + zero columns in column reduced forms) - OUTPUT: a boolean. + OUTPUT: boolean EXAMPLES:: @@ -1376,16 +1378,16 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if one does not allow zero rows in row reduced forms (resp. - zero columns in column reduced forms). + zero columns in column reduced forms) - OUTPUT: a boolean value. + OUTPUT: boolean REFERENCES: @@ -1456,16 +1458,16 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``return_degree`` -- (default: ``False``) boolean, ``True`` - implies that the pivot degrees are returned. + - ``return_degree`` -- boolean (default: ``False``); ``True`` + implies that the pivot degrees are returned - OUTPUT: a list of integers if ``return_degree=False``; a pair of lists - of integers otherwise. + OUTPUT: list of integers if ``return_degree=False``; a pair of lists + of integers otherwise REFERENCES: @@ -1584,19 +1586,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``ordered`` -- (default: ``False``) boolean, ``True`` if - checking for an ordered weak Popov form. + - ``ordered`` -- boolean (default: ``False``); ``True`` if + checking for an ordered weak Popov form - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if one does not allow zero rows (resp. zero columns) in - (ordered) weak Popov forms. + (ordered) weak Popov forms - OUTPUT: a boolean. + OUTPUT: boolean REFERENCES: @@ -1723,20 +1725,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - ``up_to_permutation`` -- (option, default: ``False``) boolean, ``True`` if testing Popov form up to row permutation (if working row-wise). - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if one does not allow zero rows (resp. zero columns) in - Popov forms. + Popov forms - OUTPUT: a boolean. + OUTPUT: boolean REFERENCES: @@ -1868,18 +1870,18 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``lower_echelon`` -- (default: ``False``) boolean, + - ``lower_echelon`` -- boolean (default: ``False``); ``False`` if working with upper triangular Hermite forms, ``True`` if working with lower triangular Hermite forms. - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if one does not allow zero rows (resp. zero columns) in - Hermite forms. + Hermite forms - OUTPUT: a boolean. + OUTPUT: boolean EXAMPLES:: @@ -1968,28 +1970,28 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``transformation`` -- (default: ``False``). If this - is ``True``, the transformation matrix `U` will be returned as well. + - ``transformation`` -- (default: ``False``) if this + is ``True``, the transformation matrix `U` will be returned as well - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``ordered`` -- (default: ``False``) boolean, ``True`` if - seeking an ordered weak Popov form. + - ``ordered`` -- boolean (default: ``False``); ``True`` if + seeking an ordered weak Popov form - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if zero rows (resp. zero columns) should be discarded from - the (ordered) weak Popov forms. + the (ordered) weak Popov forms OUTPUT: - - A polynomial matrix which is a weak Popov form of ``self`` if - ``transformation`` is ``False``; otherwise two polynomial matrices - which are a weak Popov form of ``self`` and the corresponding - unimodular transformation. + A polynomial matrix which is a weak Popov form of ``self`` if + ``transformation`` is ``False``; otherwise two polynomial matrices + which are a weak Popov form of ``self`` and the corresponding + unimodular transformation. ALGORITHM: @@ -2255,18 +2257,18 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``transformation`` -- (default: ``False``). If this - is ``True``, the transformation matrix `U` will be returned as well. + - ``transformation`` -- (default: ``False``) if this + is ``True``, the transformation matrix `U` will be returned as well - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if zero rows (resp. zero columns) should be discarded from - the Popov forms. + the Popov forms OUTPUT: @@ -2453,20 +2455,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``transformation`` -- (default: ``False``). If this + - ``transformation`` -- (default: ``False``) if this is ``True``, the transformation matrix `U` will be returned as well: this is a unimodular matrix over `\Bold{K}[x]` such that ``self`` equals `UR`, where `R` is the output matrix. - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``include_zero_vectors`` -- (default: ``True``) boolean, + - ``include_zero_vectors`` -- boolean (default: ``True``); ``False`` if one does not allow zero rows in row reduced forms (resp. - zero columns in column reduced forms). + zero columns in column reduced forms) OUTPUT: @@ -2496,8 +2498,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: R2.is_reduced() False - If the matrix is an `n \times 1` matrix with at least one non-zero entry, - `R` has a single non-zero entry and that entry is a scalar multiple of + If the matrix is an `n \times 1` matrix with at least one nonzero entry, + `R` has a single nonzero entry and that entry is a scalar multiple of the greatest-common-divisor of the entries of the matrix:: sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) @@ -2574,10 +2576,10 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``include_zero_rows`` -- boolean (default: ``True``); if ``False``, - the zero rows in the output matrix are deleted. + the zero rows in the output matrix are deleted - ``transformation`` -- boolean (default: ``False``); if ``True``, - return the transformation matrix. + return the transformation matrix OUTPUT: @@ -2737,7 +2739,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): remainder, or it does satisfy this degree constraint, and then this `R` can be returned as a remainder along with the quotient `Q`. - A ``ValueError`` is raised if the dimensions of ``self`` and `B` are + A :exc:`ValueError` is raised if the dimensions of ``self`` and `B` are not conformal, or if there exists no quotient and remainder. EXAMPLES: @@ -2843,7 +2845,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): with the required degree property In the latter case (rank-deficient or strictly fewer rows than columns, - with no solution to `A = XB`), there might stil be a quotient and + with no solution to `A = XB`), there might still be a quotient and remainder, in which case this method will find it via normal form computation:: @@ -2937,7 +2939,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): """ # Step 0: find parameter d (delta in above reference) cdegA = self.column_degrees() # zero columns of A --> entries -1 in cdegA - cdeg = B.column_degrees() # all non-negative since column reduced + cdeg = B.column_degrees() # all nonnegative since column reduced d = max([cdegA[i]-cdeg[i]+1 for i in range(B.nrows())]) if d<=0: # A already reduced modulo B, quotient is zero return (self.parent().zero().__copy__(), self) @@ -2972,7 +2974,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): implies the existence of a quotient and remainder as described above, and such a quotient and remainder is returned by the method. Or this matrix equation has no solution and this method fails: this raises - ``ValueError``; however this is not a proof that there is no valid + :exc:`ValueError`; however this is not a proof that there is no valid division with remainder (see the last example below). EXAMPLES:: @@ -3122,21 +3124,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): since `P` and `B` have the same row space (or column space, if ``row_wise`` is ``False``). - A ``ValueError`` is raised if the dimensions of the shifts and/or of + A :exc:`ValueError` is raised if the dimensions of the shifts and/or of the matrices are not conformal. INPUT: - - ``B`` -- polynomial matrix. + - ``B`` -- polynomial matrix - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, ``True`` if - working row-wise (see the class description). + - ``row_wise`` -- boolean (default: ``True``); ``True`` if + working row-wise (see the class description) - - ``return_quotient`` -- (default: ``False``). If this - is ``True``, the quotient will be returned as well. + - ``return_quotient`` -- (default: ``False``) if this + is ``True``, the quotient will be returned as well OUTPUT: a polynomial matrix if ``return_quotient=False``, two polynomial matrices otherwise. @@ -3274,22 +3276,22 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``pmat`` -- a polynomial matrix. + - ``pmat`` -- a polynomial matrix - - ``order`` -- a list of positive integers, or a positive integer. + - ``order`` -- list of positive integers, or a positive integer - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then the basis considered row-wise and operates on the left of - ``pmat``; otherwise it is column-wise and operates on the right of + ``pmat``. Otherwise it is column-wise and operates on the right of ``pmat``. - - ``normal_form`` -- (default: ``False``) boolean, if - ``True`` then checks for a basis in ``shifts``-Popov form. + - ``normal_form`` -- boolean (default: ``False``); if + ``True`` then checks for a basis in ``shifts``-Popov form - OUTPUT: a boolean. + OUTPUT: boolean ALGORITHM: @@ -3490,20 +3492,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``order`` -- a list of positive integers, or a positive integer. + - ``order`` -- list of positive integers, or a positive integer - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then the output basis is considered row-wise and operates on the left - of ``self``; otherwise it is column-wise and operates on the right + of ``self``. Otherwise it is column-wise and operates on the right of ``self``. - - ``normal_form`` -- (default: ``False``) boolean, if - ``True`` then the output basis is in ``shifts``-Popov form. + - ``normal_form`` -- boolean (default: ``False``); if + ``True`` then the output basis is in ``shifts``-Popov form - OUTPUT: a polynomial matrix. + OUTPUT: a polynomial matrix ALGORITHM: @@ -3649,9 +3651,9 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``order`` -- a list of positive integers. + - ``order`` -- list of positive integers - - ``shifts`` -- a list of integers. + - ``shifts`` -- list of integers OUTPUT: @@ -3793,20 +3795,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``pmat`` -- a polynomial matrix. + - ``pmat`` -- a polynomial matrix - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then the basis is considered row-wise and operates on the left of - ``pmat``; otherwise it is column-wise and operates on the right of + ``pmat``. Otherwise it is column-wise and operates on the right of ``pmat``. - - ``normal_form`` -- (default: ``False``) boolean, if - ``True`` then checks for a basis in ``shifts``-Popov form. + - ``normal_form`` -- boolean (default: ``False``); if + ``True`` then checks for a basis in ``shifts``-Popov form - OUTPUT: a boolean. + OUTPUT: boolean ALGORITHM: @@ -3923,17 +3925,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - ``shifts`` -- (default: ``None``) list of integers; - ``None`` is interpreted as ``shifts=[0,...,0]``. + ``None`` is interpreted as ``shifts=[0,...,0]`` - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then the output basis considered row-wise and operates on the left - of ``self``; otherwise it is column-wise and operates on the right + of ``self``. Otherwise it is column-wise and operates on the right of ``self``. - - ``normal_form`` -- (default: ``False``) boolean, if - ``True`` then the output basis is in ``shifts``-Popov form. + - ``normal_form`` -- boolean (default: ``False``); if + ``True`` then the output basis is in ``shifts``-Popov form - OUTPUT: a polynomial matrix. + OUTPUT: a polynomial matrix ALGORITHM: uses minimal approximant basis computation at a sufficiently large order so that the approximant basis contains @@ -4248,7 +4250,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): return completion - def basis_completion(self, row_wise=True, algorithm="approximant"): + def basis_completion(self, row_wise=True, algorithm='approximant'): r""" Return a Smith form-preserving nonsingular completion of a basis of this matrix: row-wise completing a row basis if ``row_wise`` is True; @@ -4280,24 +4282,24 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` then - compute a row-wise completion, else compute a column-wise completion. + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then + compute a row-wise completion, else compute a column-wise completion - - ``algorithm`` -- (default: ``"approximant"``) selects the + - ``algorithm`` -- (default: ``'approximant'``) selects the approach for computing the completion; currently supported: - ``"approximant"`` and ``"smith"``. + ``'approximant'`` and ``'smith'`` - OUTPUT: a matrix over the same base ring as the input matrix, which forms a - completion as defined above. + OUTPUT: a matrix over the same base ring as the input matrix, which + forms a completion as defined above ALGORITHM: - - ``approximant``: the approximant-based algorithm follows the ideas in + - ``'approximant'`` -- the approximant-based algorithm follows the ideas in [ZL2014]_ , based on polynomial reversals combined with the computation of a minimal kernel basis and a minimal approximant basis. - - ``smith``: the Smith form-based algorithm computes the Smith form of + - ``'smith'`` -- the Smith form-based algorithm computes the Smith form of this matrix along with corresponding unimodular transformations, from which a completion is readily obtained. @@ -4369,7 +4371,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: mat = matrix([[x*(x-1)*(x-2), (x-2)*(x-3)*(x-4), (x-4)*(x-5)*(x-6)]]) sage: mat [ x^3 - 3*x^2 + 2*x x^3 - 9*x^2 + 26*x - 24 x^3 - 15*x^2 + 74*x - 120] - sage: rcomp = mat.basis_completion(algorithm="smith"); rcomp + sage: rcomp = mat.basis_completion(algorithm='smith'); rcomp [ -1/12*x - 1/12 -1/12*x + 5/12 0] [ 1/12 1/12 1/24*x^2 - 13/24*x + 2] sage: mat.stack(rcomp).determinant() @@ -4382,7 +4384,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [1 0] [0 x] [0 0] - sage: ccomp = mat.basis_completion(row_wise=False, algorithm="smith") + sage: ccomp = mat.basis_completion(row_wise=False, algorithm='smith') sage: ccomp [1/2*x - 1/2] [ 1/2*x - 1] @@ -4395,7 +4397,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: field. = NumberField(x**2 - 2) sage: ring. = field[] sage: mat = matrix([[3*a*y - 1, (-8*a - 1)*y - 2*a + 1]]) - sage: rcomp = mat.basis_completion(algorithm="smith"); rcomp + sage: rcomp = mat.basis_completion(algorithm='smith'); rcomp [ 39/119*a - 30/119 -99/119*a + 67/119] sage: mat.stack(rcomp).determinant() 1 @@ -4408,28 +4410,28 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [] sage: matrix(ring, 0, 0).basis_completion(row_wise=False) [] - sage: matrix(ring, 0, 0).basis_completion(algorithm="smith") + sage: matrix(ring, 0, 0).basis_completion(algorithm='smith') [] - sage: matrix(ring, 0, 0).basis_completion(row_wise=False,algorithm="smith") + sage: matrix(ring, 0, 0).basis_completion(row_wise=False,algorithm='smith') [] sage: matrix(ring, 0, 2).basis_completion() [1 0] [0 1] sage: matrix(ring, 0, 2).basis_completion(row_wise=False) [] - sage: matrix(ring, 0, 2).basis_completion(algorithm="smith") + sage: matrix(ring, 0, 2).basis_completion(algorithm='smith') [1 0] [0 1] - sage: matrix(ring, 0, 2).basis_completion(row_wise=False,algorithm="smith") + sage: matrix(ring, 0, 2).basis_completion(row_wise=False,algorithm='smith') [] sage: matrix(ring, 2, 0).basis_completion() [] sage: matrix(ring, 2, 0).basis_completion(row_wise=False) [1 0] [0 1] - sage: matrix(ring, 2, 0).basis_completion(algorithm="smith") + sage: matrix(ring, 2, 0).basis_completion(algorithm='smith') [] - sage: matrix(ring, 2, 0).basis_completion(row_wise=False,algorithm="smith") + sage: matrix(ring, 2, 0).basis_completion(row_wise=False,algorithm='smith') [1 0] [0 1] """ @@ -4482,11 +4484,10 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): INPUT: - - ``row_wise`` -- (default: ``True``) boolean, if ``True`` then - check for row-wise completion, else check for column-wise completion. + - ``row_wise`` -- boolean (default: ``True``); if ``True`` then + check for row-wise completion, else check for column-wise completion - OUTPUT: a boolean indicating whether this matrix is a completion of - ``mat``. + OUTPUT: boolean indicating whether this matrix is a completion of ``mat`` EXAMPLES: diff --git a/src/sage/matrix/matrix_rational_dense.pyx b/src/sage/matrix/matrix_rational_dense.pyx index 60ef434904a..533f6b55c67 100644 --- a/src/sage/matrix/matrix_rational_dense.pyx +++ b/src/sage/matrix/matrix_rational_dense.pyx @@ -168,8 +168,8 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the - entries are of type :class:`Rational`. + - ``coerce`` -- if ``False``, assume without checking that the + entries are of type :class:`Rational` TESTS:: @@ -193,7 +193,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def matrix_from_columns(self, columns): """ - Return the matrix constructed from self using columns with indices + Return the matrix constructed from ``self`` using columns with indices in the columns list. EXAMPLES:: @@ -227,7 +227,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def add_to_entry(self, Py_ssize_t i, Py_ssize_t j, elt): r""" - Add ``elt`` to the entry at position ``(i,j)`` + Add ``elt`` to the entry at position ``(i,j)``. EXAMPLES:: @@ -308,7 +308,7 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: - - ``base`` -- an optional integer (default is ``10``) + - ``base`` -- integer (default: `10`) EXAMPLES:: @@ -510,7 +510,7 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``v`` -- a free module element - OUTPUT: The vector times matrix product v\*A + OUTPUT: the vector times matrix product v\*A EXAMPLES:: @@ -646,11 +646,10 @@ cdef class Matrix_rational_dense(Matrix_dense): def inverse(self, algorithm=None, check_invertible=True): """ - Return the inverse of this matrix + Return the inverse of this matrix. INPUT: - - ``algorithm`` -- an optional specification of an algorithm. It can be one of - ``None``: (default) uses flint @@ -661,8 +660,8 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``'iml'``: uses IML library - - ``check_invertible`` -- only used when ``algorithm=iml``. Whether to - check that matrix is invertible + - ``check_invertible`` -- only used when ``algorithm=iml``; whether to + check that matrix is invertible EXAMPLES:: @@ -673,40 +672,40 @@ cdef class Matrix_rational_dense(Matrix_dense): [1/2 1/2 -2] sage: a = matrix(QQ, 2, [1, 5, 17, 3]) - sage: a.inverse(algorithm="flint") + sage: a.inverse(algorithm='flint') [-3/82 5/82] [17/82 -1/82] - sage: a.inverse(algorithm="flint") * a + sage: a.inverse(algorithm='flint') * a [1 0] [0 1] sage: a = matrix(QQ, 2, [-1, 5, 12, -3]) - sage: a.inverse(algorithm="iml") + sage: a.inverse(algorithm='iml') [1/19 5/57] [4/19 1/57] - sage: a.inverse(algorithm="iml") * a + sage: a.inverse(algorithm='iml') * a [1 0] [0 1] sage: a = matrix(QQ, 4, primes_first_n(16)) - sage: a.inverse(algorithm="pari") + sage: a.inverse(algorithm='pari') [ 3/11 -12/55 -1/5 2/11] [ -5/11 -2/55 3/10 -3/22] [ -13/22 307/440 -1/10 -9/88] [ 15/22 -37/88 0 7/88] - On singular matrices this method raises a ``ZeroDivisionError``:: + On singular matrices this method raises a :exc:`ZeroDivisionError`:: sage: a = matrix(QQ, 2) - sage: a.inverse(algorithm="flint") + sage: a.inverse(algorithm='flint') Traceback (most recent call last): ... ZeroDivisionError: input matrix must be nonsingular - sage: a.inverse(algorithm="iml") + sage: a.inverse(algorithm='iml') Traceback (most recent call last): ... ZeroDivisionError: input matrix must be nonsingular - sage: a.inverse(algorithm="pari") + sage: a.inverse(algorithm='pari') Traceback (most recent call last): ... ZeroDivisionError: input matrix must be nonsingular @@ -771,8 +770,8 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``'generic'``: calls the generic Sage implementation - - ``proof`` -- bool or None; if None use - proof.linear_algebra(); only relevant for the padic algorithm. + - ``proof`` -- boolean or ``None``; if ``None`` use + proof.linear_algebra(); only relevant for the padic algorithm .. NOTE:: @@ -788,18 +787,18 @@ cdef class Matrix_rational_dense(Matrix_dense): x^3 - 17/5*x^2 - 122/15*x + 34/15 sage: m = matrix(QQ, 3, [(1/i)**j for i in range(2,5) for j in range(3)]) - sage: m.determinant(algorithm="flint") + sage: m.determinant(algorithm='flint') -1/288 sage: m = matrix(QQ, 4, [(-1)**n/n for n in range(1,17)]) - sage: m.determinant(algorithm="pari") + sage: m.determinant(algorithm='pari') 2/70945875 sage: m = matrix(QQ, 5, [1/(i+j+1) for i in range(5) for j in range(5)]) - sage: m.determinant(algorithm="integer") + sage: m.determinant(algorithm='integer') 1/266716800000 - On non-square matrices, the method raises a ``ValueError``:: + On non-square matrices, the method raises a :exc:`ValueError`:: sage: matrix(QQ, 2, 3).determinant(algorithm='flint') Traceback (most recent call last): @@ -857,7 +856,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def _det_flint(self): r""" - Return the determinant (computed using flint) + Return the determinant (computed using flint). EXAMPLES:: @@ -918,7 +917,7 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``self`` -- a matrix - OUTPUT: D\*self, D + OUTPUT: ``D*self, D`` The product is a matrix over `\ZZ`. @@ -976,10 +975,10 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: - - ``var`` -- (optional) name of the variable as a string + - ``var`` -- (optional) name of the variable as a string - - ``algorithm`` -- an optional specification of an algorithm. It can be - one of: + - ``algorithm`` -- an optional specification of an algorithm. It can be + one of: - ``None``: (default) will use flint for small dimensions and linbox otherwise @@ -990,7 +989,7 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``'generic'``: uses Sage generic implementation - OUTPUT: a polynomial over the rational numbers. + OUTPUT: a polynomial over the rational numbers EXAMPLES:: @@ -1052,15 +1051,14 @@ cdef class Matrix_rational_dense(Matrix_dense): def minpoly(self, var='x', algorithm=None): """ - Return the minimal polynomial of this matrix + Return the minimal polynomial of this matrix. INPUT: + - ``var`` -- (optional) the variable name as a string (default: ``'x'``) - - ``var`` -- (optional) the variable name as a string (default is 'x') - - - ``algorithm`` -- an optional specification of an algorithm. It can - be one of + - ``algorithm`` -- an optional specification of an algorithm. It can + be one of - ``None``: (default) will use linbox @@ -1183,11 +1181,11 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: - - ``self`` -- matrix over QQ + - ``self`` -- matrix over QQ - - ``right`` -- matrix over QQ + - ``right`` -- matrix over QQ - - ``algorithm`` + - ``algorithm`` - 'default': use whatever is the default for A\*B when A, B are over ZZ. @@ -1247,7 +1245,7 @@ cdef class Matrix_rational_dense(Matrix_dense): absolute values of all numerators and denominators of entries in this matrix. - OUTPUT: an Integer + OUTPUT: integer EXAMPLES:: @@ -1288,7 +1286,7 @@ cdef class Matrix_rational_dense(Matrix_dense): """ Return the adjugate of this matrix. - Assumes self is a square matrix (checked in adjugate). + Assumes ``self`` is a square matrix (checked in adjugate). EXAMPLES:: @@ -1343,7 +1341,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def _right_kernel_matrix(self, **kwds): r""" - Returns a pair that includes a matrix of basis vectors + Return a pair that includes a matrix of basis vectors for the right kernel of ``self``. INPUT: @@ -1419,7 +1417,7 @@ cdef class Matrix_rational_dense(Matrix_dense): # ############################################### def change_ring(self, R): """ - Create the matrix over R with entries the entries of self coerced + Create the matrix over R with entries the entries of ``self`` coerced into R. EXAMPLES:: @@ -1499,13 +1497,13 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: - - ``algorithm`` -- an optional specification of an algorithm. One of + - ``algorithm`` -- an optional specification of an algorithm. One of - ``None``: (default) uses flint for small dimension and multimodular otherwise - ``'flint'``: use the flint library, - - ``'padic'``: an algorithm based on the IML p-adic solver, + - ``'padic'``: an algorithm based on the IML `p`-adic solver, - ``'multimodular'``: uses a multimodular algorithm the uses linbox modulo many primes (likely to be faster when coefficients @@ -1513,13 +1511,13 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``'classical'``: just clear each column using Gauss elimination. - - ``height_guess``, ``**kwds`` -- all passed to the - multimodular algorithm; ignored by other algorithms. + - ``height_guess``, ``**kwds`` -- all passed to the + multimodular algorithm; ignored by other algorithms - - ``proof`` -- bool or None (default: None, see - proof.linear_algebra or sage.structure.proof). Passed to the - multimodular algorithm. Note that the Sage global default is - ``proof=True``. + - ``proof`` -- boolean or ``None`` (default: None, see + proof.linear_algebra or sage.structure.proof). Passed to the + multimodular algorithm. Note that the Sage global default is + ``proof=True``. EXAMPLES:: @@ -1702,7 +1700,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def _echelonize_padic(self): """ - Echelonize self using a p-adic nullspace algorithm. + Echelonize ``self`` using a `p`-adic nullspace algorithm. EXAMPLES:: @@ -1777,12 +1775,11 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: + - ``height_guess`` -- integer or ``None`` - - ``height_guess`` -- integer or None - - - ``proof`` -- boolean (default: None, see - proof.linear_algebra or sage.structure.proof) Note that the Sage - global default is proof=True. + - ``proof`` -- boolean (default: ``None``, see + proof.linear_algebra or sage.structure.proof); Note that the Sage + global default is ``proof=True`` EXAMPLES:: @@ -1843,7 +1840,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def decomposition(self, is_diagonalizable=False, dual=False, algorithm=None, height_guess=None, proof=None): """ - Returns the decomposition of the free module on which this matrix A + Return the decomposition of the free module on which this matrix A acts from the right (i.e., the action is x goes to x A), along with whether this matrix acts irreducibly on each factor. The factors are guaranteed to be sorted in the same way as the corresponding @@ -1865,13 +1862,12 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: + - ``is_diagonalizable`` -- ignored - - ``is_diagonalizable`` -- ignored + - ``dual`` -- whether to also return decompositions for + the dual - - ``dual`` -- whether to also return decompositions for - the dual - - - ``algorithm`` -- an optional specification of an algorithm + - ``algorithm`` -- an optional specification of an algorithm - ``None`` -- (default) use default algorithm for computing Echelon forms @@ -1879,13 +1875,13 @@ cdef class Matrix_rational_dense(Matrix_dense): - 'multimodular': much better if the answers factors have small height - - ``height_guess`` -- positive integer; only used by - the multimodular algorithm + - ``height_guess`` -- positive integer; only used by + the multimodular algorithm - - ``proof`` -- bool or None (default: None, see - proof.linear_algebra or sage.structure.proof); only used by the - multimodular algorithm. Note that the Sage global default is - proof=True. + - ``proof`` -- boolean or ``None`` (default: ``None``, see + proof.linear_algebra or sage.structure.proof); only used by the + multimodular algorithm. Note that the Sage global default is + proof=True. .. NOTE:: @@ -1913,7 +1909,6 @@ cdef class Matrix_rational_dense(Matrix_dense): [ 1 0 -1] [ 0 1 2], True) ] - """ X = self._decomposition_rational(is_diagonalizable=is_diagonalizable, echelon_algorithm=algorithm, @@ -1930,7 +1925,7 @@ cdef class Matrix_rational_dense(Matrix_dense): kernel_algorithm='default', **kwds): """ - Returns the decomposition of the free module on which this matrix A + Return the decomposition of the free module on which this matrix A acts from the right (i.e., the action is x goes to x A), along with whether this matrix acts irreducibly on each factor. The factors are guaranteed to be sorted in the same way as the corresponding @@ -1938,17 +1933,16 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: + - ``self`` -- a square matrix over the rational + numbers - - ``self`` -- a square matrix over the rational - numbers + - ``echelon_algorithm`` -- an optional algorithm to be passed to the + method ``echelon_form`` - - ``echelon_algorithm`` -- an optional algorithm to be passed to the - method ``echelon_form`` + - ``'multimodular'`` -- use this if the answers have + small height - - ``'multimodular'`` -- use this if the answers have - small height - - - ``**kwds`` -- passed on to echelon function. + - ``**kwds`` -- passed on to echelon function .. NOTE:: @@ -1959,14 +1953,12 @@ cdef class Matrix_rational_dense(Matrix_dense): will be very small, use algorithm='multimodular', height_guess=bound on height, proof=False - OUTPUT: - - - ``Sequence`` -- list of tuples (V,t), where V is a - vector spaces and t is True if and only if the charpoly of self on - V is irreducible. The tuples are in order corresponding to the - elements of the sorted list self.charpoly().factor(). + - ``Sequence`` -- list of tuples (V,t), where V is a + vector spaces and t is ``True`` if and only if the charpoly of ``self`` on + V is irreducible. The tuples are in order corresponding to the + elements of the sorted list self.charpoly().factor(). """ cdef Py_ssize_t k @@ -2209,19 +2201,17 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: - - ``density`` -- number between 0 and 1 (default: 1) - - - ``num_bound`` -- numerator bound (default: 2) + - ``density`` -- number between 0 and 1 (default: 1) - - ``den_bound`` -- denominator bound (default: 2) + - ``num_bound`` -- numerator bound (default: 2) - - ``distribution`` -- ``None`` or '1/n' (default: ``None``); if '1/n' - then ``num_bound``, ``den_bound`` are ignored and numbers are chosen - using the GMP function ``mpq_randomize_entry_recip_uniform`` + - ``den_bound`` -- denominator bound (default: 2) - OUTPUT: + - ``distribution`` -- ``None`` or '1/n' (default: ``None``); if '1/n' + then ``num_bound``, ``den_bound`` are ignored and numbers are chosen + using the GMP function ``mpq_randomize_entry_recip_uniform`` - - None, the matrix is modified in-space + OUTPUT: none; the matrix is modified in-space EXAMPLES: @@ -2474,13 +2464,13 @@ cdef class Matrix_rational_dense(Matrix_dense): - ``algorithm`` -- an optional specification of an algorithm. One of - - ``None``: (default) will use flint + - ``None`` -- (default) will use flint - - ``'flint'``: uses the flint library + - ``'flint'`` -- uses the flint library - - ``'pari'``: uses the PARI library + - ``'pari'`` -- uses the PARI library - - ``'integer'``: eliminate denominators and calls the rank function + - ``'integer'`` -- eliminate denominators and calls the rank function on the corresponding integer matrix EXAMPLES:: @@ -2523,7 +2513,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def transpose(self): """ - Returns the transpose of self, without changing self. + Return the transpose of ``self``, without changing ``self``. EXAMPLES: @@ -2579,7 +2569,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def antitranspose(self): """ - Returns the antitranspose of self, without changing self. + Return the antitranspose of ``self``, without changing ``self``. EXAMPLES:: @@ -2660,10 +2650,9 @@ cdef class Matrix_rational_dense(Matrix_dense): Py_ssize_t r, cols, cols_index=None): """ - Set row i of self to -(row r of A), but where we only take the + Set row i of ``self`` to -(row r of A), but where we only take the given column positions in that row of A. We do not zero out the - other entries of self's row i either. - + other entries of ``self``'s row i either. .. NOTE:: @@ -2671,15 +2660,13 @@ cdef class Matrix_rational_dense(Matrix_dense): INPUT: + - ``i`` -- integer, index into the rows of self - - ``i`` -- integer, index into the rows of self + - ``A`` -- a matrix - - ``A`` -- a matrix - - - ``r`` -- integer, index into rows of A - - - ``cols`` -- a *sorted* list of integers. + - ``r`` -- integer, index into rows of A + - ``cols`` -- a *sorted* list of integers EXAMPLES:: @@ -2712,8 +2699,8 @@ cdef class Matrix_rational_dense(Matrix_dense): def _add_col_j_of_A_to_col_i_of_self(self, Py_ssize_t i, Matrix_rational_dense A, Py_ssize_t j): """ - Unsafe technical function that very quickly adds the j-th column of - A to the i-th column of self. + Unsafe technical function that very quickly adds the `j`-th column of + A to the `i`-th column of ``self``. Does not check mutability. """ @@ -2779,7 +2766,7 @@ cdef class Matrix_rational_dense(Matrix_dense): def _multiply_pari(self, Matrix_rational_dense right): """ - Return the product of self and right, computed using PARI. + Return the product of ``self`` and ``right``, computed using PARI. EXAMPLES:: @@ -2837,13 +2824,13 @@ cdef class Matrix_rational_dense(Matrix_dense): def row(self, Py_ssize_t i, from_list=False): """ - Return the i-th row of this matrix as a dense vector. + Return the `i`-th row of this matrix as a dense vector. INPUT: - - ``i`` -- integer + - ``i`` -- integer - - ``from_list`` -- ignored + - ``from_list`` -- ignored EXAMPLES:: @@ -2881,13 +2868,13 @@ cdef class Matrix_rational_dense(Matrix_dense): def column(self, Py_ssize_t i, from_list=False): """ - Return the i-th column of this matrix as a dense vector. + Return the `i`-th column of this matrix as a dense vector. INPUT: - - ``i`` -- integer + - ``i`` -- integer - - ``from_list`` -- ignored + - ``from_list`` -- ignored EXAMPLES:: @@ -2968,6 +2955,9 @@ cdef class Matrix_rational_dense(Matrix_dense): [ 1/28 -1/40 -1/18] [ 1/28 -1/40 1/18] [ 0 -3/40 0] + sage: L, U = A.LLL(transformation=True) + sage: U * A == L + True sage: A = random_matrix(QQ, 10, 10) sage: d = lcm(a.denom() for a in A.list()) @@ -2975,6 +2965,9 @@ cdef class Matrix_rational_dense(Matrix_dense): True """ A, d = self._clear_denom() + if kwargs.get('transformation', False): + L, U = A.LLL(*args, **kwargs) + return L / d, U return A.LLL(*args, **kwargs) / d def is_LLL_reduced(self, delta=None, eta=None): diff --git a/src/sage/matrix/matrix_rational_sparse.pyx b/src/sage/matrix/matrix_rational_sparse.pyx index 6cf8d4fa0d0..8e9898642c3 100644 --- a/src/sage/matrix/matrix_rational_sparse.pyx +++ b/src/sage/matrix/matrix_rational_sparse.pyx @@ -76,14 +76,14 @@ cdef class Matrix_rational_sparse(Matrix_sparse): INPUT: - - ``parent`` -- a matrix space over ``QQ`` + - ``parent`` -- a matrix space over `\QQ` - ``entries`` -- see :func:`matrix` - ``copy`` -- ignored (for backwards compatibility) - - ``coerce`` -- if False, assume without checking that the - entries are of type :class:`Rational`. + - ``coerce`` -- if ``False``, assume without checking that the + entries are of type :class:`Rational` """ ma = MatrixArgs_init(parent, entries) cdef Rational z @@ -356,9 +356,7 @@ cdef class Matrix_rational_sparse(Matrix_sparse): multiple of all numerators and denominators of elements of this matrix. - OUTPUT: - - -- Integer + OUTPUT: integer EXAMPLES:: @@ -409,9 +407,7 @@ cdef class Matrix_rational_sparse(Matrix_sparse): """ Return the denominator of this matrix. - OUTPUT: - - - Sage Integer + OUTPUT: Sage Integer EXAMPLES:: @@ -427,13 +423,7 @@ cdef class Matrix_rational_sparse(Matrix_sparse): def _clear_denom(self): """ - INPUT: - - self -- a matrix - - OUTPUT: - - D*self, D + OUTPUT: ``d*self, D`` The product D*self is a matrix over ZZ @@ -483,8 +473,8 @@ cdef class Matrix_rational_sparse(Matrix_sparse): INPUT: - ``height_guess``, ``proof``, ``**kwds`` -- all passed to the multimodular - algorithm; ignored by the p-adic algorithm. + - ``height_guess``, ``proof``, ``**kwds`` -- all passed to the multimodular + algorithm; ignored by the `p`-adic algorithm OUTPUT: @@ -530,12 +520,10 @@ cdef class Matrix_rational_sparse(Matrix_sparse): """ INPUT: - ``height_guess``, ``proof``, ``**kwds`` -- all passed to the multimodular - algorithm; ignored by the p-adic algorithm. - - OUTPUT: + - ``height_guess``, ``proof``, ``**kwds`` -- all passed to the multimodular + algorithm; ignored by the `p`-adic algorithm - self is no in reduced row echelon form. + OUTPUT: ``self`` is no in reduced row echelon form EXAMPLES:: @@ -574,13 +562,13 @@ cdef class Matrix_rational_sparse(Matrix_sparse): def _echelon_form_multimodular(self, height_guess=None, proof=True): """ - Returns reduced row-echelon form using a multi-modular - algorithm. Does not change self. + Return reduced row-echelon form using a multi-modular + algorithm. Does not change ``self``. INPUT: - - height_guess -- integer or None - - proof -- boolean (default: ``True``) + - ``height_guess`` -- integer or ``None`` + - ``proof`` -- boolean (default: ``True``) """ from sage.matrix.misc import matrix_rational_echelon_form_multimodular cdef Matrix E @@ -661,17 +649,17 @@ cdef class Matrix_rational_sparse(Matrix_sparse): Py_ssize_t r, cols, cols_index=None): """ - Set row i of self to -(row r of A), but where we only take the + Set row i of ``self`` to -(row r of A), but where we only take the given column positions in that row of A. Note that we *DO* - zero out the other entries of self's row i. + zero out the other entries of ``self``'s row i. INPUT: - - i -- integer, index into the rows of self - - A -- a sparse matrix - - r -- integer, index into rows of A - - cols -- a *sorted* list of integers. - - cols_index -- (optional). But set it to this to vastly speed up + - ``i`` -- integer, index into the rows of self + - ``A`` -- a sparse matrix + - ``r`` -- integer, index into rows of A + - ``cols`` -- a *sorted* list of integers + - ``cols_index`` -- (optional) set it to this to vastly speed up calls to this function:: dict([(cols[i], i) for i in range(len(cols))]) @@ -728,7 +716,7 @@ cdef class Matrix_rational_sparse(Matrix_sparse): def _right_kernel_matrix(self, **kwds): r""" - Returns a pair that includes a matrix of basis vectors + Return a pair that includes a matrix of basis vectors for the right kernel of ``self``. INPUT: diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 71eb305c2be..267a818c433 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -105,9 +105,9 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): - ``ncols`` -- number of columns - - ``sparse`` -- (boolean) whether the matrix class should be sparse + - ``sparse`` -- boolean; whether the matrix class should be sparse - - ``implementation`` -- (``None`` or string or a matrix class) a possible + - ``implementation`` -- ``None`` or string or a matrix class; a possible implementation. See the documentation of the constructor of :class:`MatrixSpace`. EXAMPLES:: @@ -192,7 +192,6 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe, needs sage.rings.finite_rings - """ if isinstance(implementation, type): return implementation @@ -298,7 +297,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): except ImportError: pass else: - if polynomial_ring.is_PolynomialRing(R) and R.base_ring() in _Fields: + if isinstance(R, polynomial_ring.PolynomialRing_general) and R.base_ring() in _Fields: try: from . import matrix_polynomial_dense except ImportError: @@ -306,7 +305,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): else: return matrix_polynomial_dense.Matrix_polynomial_dense - elif multi_polynomial_ring_base.is_MPolynomialRing(R) and R.base_ring() in _Fields: + elif isinstance(R, multi_polynomial_ring_base.MPolynomialRing_base) and R.base_ring() in _Fields: try: from . import matrix_mpolynomial_dense except ImportError: @@ -384,7 +383,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): return Matrix_generic_dense if implementation == 'gap': - from .matrix_gap import Matrix_gap + from sage.matrix.matrix_gap import Matrix_gap return Matrix_gap raise ValueError("unknown matrix implementation %r over %r" % (implementation, R)) @@ -447,17 +446,17 @@ class MatrixSpace(UniqueRepresentation, Parent): - ``base_ring`` -- a ring - - ``nrows`` or ``row_keys`` -- (nonnegative integer) the number of rows, or + - ``nrows`` or ``row_keys`` -- nonnegative integer; the number of rows, or a finite family of arbitrary objects that index the rows of the matrix - - ``ncols`` or ``column_keys`` -- (nonnegative integer, default ``nrows``) + - ``ncols`` or ``column_keys`` -- nonnegative integer (default: ``nrows``); the number of columns, or a finite family of arbitrary objects that index the columns of the matrix - - ``sparse`` -- (boolean, default ``False``) whether or not matrices - are given a sparse representation + - ``sparse`` -- boolean (default: ``False``); whether or not matrices + are given a sparse representation - - ``implementation`` -- (optional, a string or a matrix class) a possible + - ``implementation`` -- (optional) string or matrix class; a possible implementation. Depending on the base ring, the string can be - ``'generic'`` -- on any base rings @@ -697,13 +696,13 @@ def __classcall__(cls, base_ring, :: - sage: M = MatrixSpace(ZZ, 10, implementation="flint") # needs sage.libs.flint + sage: M = MatrixSpace(ZZ, 10, implementation='flint') # needs sage.libs.flint sage: M # needs sage.libs.flint Full MatrixSpace of 10 by 10 dense matrices over Integer Ring sage: loads(M.dumps()) is M # needs sage.libs.flint True - sage: MatrixSpace(ZZ, 10, implementation="foobar") + sage: MatrixSpace(ZZ, 10, implementation='foobar') Traceback (most recent call last): ... ValueError: unknown matrix implementation 'foobar' over Integer Ring @@ -792,15 +791,15 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): - ``base_ring`` - - ``nrows`` -- (positive integer) the number of rows + - ``nrows`` -- positive integer; the number of rows - - ``ncols`` -- (positive integer, default nrows) the number of - columns + - ``ncols`` -- positive integer (default: ``nrows``); the number of + columns - - ``sparse`` -- (boolean, default ``False``) whether or not matrices - are given a sparse representation + - ``sparse`` -- boolean (default: ``False``); whether or not matrices + are given a sparse representation - - ``implementation`` -- (optional, a string or a matrix class) a possible + - ``implementation`` -- (optional) string or matrix class; a possible implementation. Depending on the base ring the string can be - ``'generic'`` -- on any base rings @@ -1022,7 +1021,6 @@ def _copy_zero(self): sage: MS = MatrixSpace(QQ,20,20) sage: MS._copy_zero False - """ if self.__is_sparse: return False @@ -1161,9 +1159,7 @@ def change_ring(self, R): INPUT: - - - ``R`` -- ring - + - ``R`` -- ring OUTPUT: a matrix space @@ -1189,7 +1185,7 @@ def base_extend(self, R): INPUT: - - ``R`` -- ring + - ``R`` -- ring OUTPUT: a matrix space @@ -1535,8 +1531,8 @@ def _latex_(self): def __len__(self): """ Return number of elements of this matrix space if it fits in - an int; raise a :class:`TypeError` if there are infinitely many - elements, and raise an :class:`OverflowError` if there are finitely + an int; raise a :exc:`TypeError` if there are infinitely many + elements, and raise an :exc:`OverflowError` if there are finitely many but more than the size of an int. EXAMPLES:: @@ -1563,7 +1559,7 @@ def __len__(self): def __iter__(self): r""" Return a generator object which iterates through the elements of - self. The order in which the elements are generated is based on a + ``self``. The order in which the elements are generated is based on a 'weight' of a matrix which is the number of iterations on the base ring that are required to reach that matrix. @@ -1883,16 +1879,16 @@ def submodule(self, gens, check=True, already_echelonized=False, INPUT: - - ``gens`` -- a list or family of elements of ``self`` + - ``gens`` -- list or family of elements of ``self`` - - ``check`` -- (default: ``True``) whether to verify that the - elements of ``gens`` are in ``self`` + - ``check`` -- boolean (default: ``True``); whether to verify that the + elements of ``gens`` are in ``self`` - - ``already_echelonized`` -- (default: ``False``) whether - the elements of ``gens`` are already in (not necessarily - reduced) echelon form + - ``already_echelonized`` -- boolean (default: ``False``); whether + the elements of ``gens`` are already in (not necessarily + reduced) echelon form - - ``unitriangular`` -- (default: ``False``) whether + - ``unitriangular`` -- boolean (default: ``False``); whether the lift morphism is unitriangular - ``support_order`` -- (optional) either something that can @@ -2009,7 +2005,6 @@ def identity_matrix(self): sage: type(M2.identity_matrix()) - """ if self.__nrows != self.__ncols: raise TypeError("identity matrix must be square") @@ -2023,7 +2018,7 @@ def identity_matrix(self): def diagonal_matrix(self, entries): """ - Create a diagonal matrix in ``self`` using the specified elements + Create a diagonal matrix in ``self`` using the specified elements. INPUT: @@ -2118,7 +2113,7 @@ def is_finite(self): def gen(self, n): """ - Return the n-th generator of this matrix space. + Return the `n`-th generator of this matrix space. This does not compute all basis matrices, so it is reasonably intelligent. @@ -2170,9 +2165,20 @@ def zero_matrix(self): False sage: MM.zero().is_mutable() False + + Check that :issue:`38221` is fixed:: + + sage: # needs sage.groups + sage: G = CyclicPermutationGroup(7) + sage: R = GF(2) + sage: A = G.algebra(R) + sage: S = MatrixSpace(A, 3, 3) + sage: S.zero_matrix() + [0 0 0] + [0 0 0] + [0 0 0] """ - zero = self.base_ring().zero() - res = self.element_class(self, zero, False, False) + res = self.element_class(self, None, False, False) res.set_immutable() return res @@ -2199,12 +2205,10 @@ def matrix(self, x=None, **kwds): - ``x`` -- data to construct a new matrix from. See :func:`matrix` - - ``coerce`` -- (default: ``True``) if False, assume without - checking that the values in ``x`` lie in the base ring + - ``coerce`` -- boolean (default: ``True``); if ``False``, assume + without checking that the values in ``x`` lie in the base ring - OUTPUT: - - - a matrix in ``self``. + OUTPUT: a matrix in ``self`` EXAMPLES:: @@ -2315,7 +2319,7 @@ def matrix_space(self, nrows=None, ncols=None, sparse=False): """ Return the matrix space with given number of rows, columns and sparsity over the same base ring as self, and defaults the same as - self. + ``self``. EXAMPLES:: @@ -2400,22 +2404,20 @@ def random_element(self, density=None, *args, **kwds): INPUT: - - ``density`` -- ``float`` or ``None`` (default: ``None``); rough - measure of the proportion of nonzero entries in the random matrix; - if set to ``None``, all entries of the matrix are randomized, - allowing for any element of the underlying ring, but if set to - a ``float``, a proportion of entries is selected and randomized to - non-zero elements of the ring - - - ``*args, **kwds`` -- remaining parameters, which may be passed to - the random_element function of the base ring. ("may be", since this - function calls the ``randomize`` function on the zero matrix, which - need not call the ``random_element`` function of the base ring at - all in general.) + - ``density`` -- ``float`` or ``None`` (default: ``None``); rough + measure of the proportion of nonzero entries in the random matrix; + if set to ``None``, all entries of the matrix are randomized, + allowing for any element of the underlying ring, but if set to + a ``float``, a proportion of entries is selected and randomized to + nonzero elements of the ring - OUTPUT: + - ``*args, **kwds`` -- remaining parameters, which may be passed to + the random_element function of the base ring. ("may be", since this + function calls the ``randomize`` function on the zero matrix, which + need not call the ``random_element`` function of the base ring at + all in general.) - - Matrix + OUTPUT: Matrix .. NOTE:: @@ -2423,7 +2425,7 @@ def random_element(self, density=None, *args, **kwds): in a newly allocated zero matrix. By default, if the user sets the value of ``density`` explicitly, this - method will enforce that these entries are set to non-zero values. + method will enforce that these entries are set to nonzero values. However, if the test for equality with zero in the base ring is too expensive, the user can override this behaviour by passing the argument ``nonzero=False`` to this method. @@ -2523,9 +2525,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -2587,19 +2587,17 @@ def _polymake_init_(self): def _random_nonzero_element(self, *args, **kwds): """ - Return a random non-zero matrix. + Return a random nonzero matrix. - This function repeatedly calls ``random_element`` until a non-zero + This function repeatedly calls ``random_element`` until a nonzero matrix is obtained. INPUT: - - ``*args``, ``**kwds`` -- Parameters that can be forwarded to the + - ``*args``, ``**kwds`` -- parameters that can be forwarded to the ``random_element`` method - OUTPUT: - - - Random non-zero matrix + OUTPUT: random nonzero matrix EXAMPLES:: @@ -2691,23 +2689,21 @@ def dict_to_list(entries, nrows, ncols): def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, checkrank=True): """ - Tests inversion, determinant and is_invertible for trivial matrices. + Test inversion, determinant and is_invertible for trivial matrices. This function is a helper to check that the inversion of trivial matrices (of size 0x0, nx0, 0xn or 1x1) is handled consistently by the various implementation of matrices. The coherency is checked through a bunch of - assertions. If an inconsistency is found, an AssertionError is raised - which should make clear what is the problem. + assertions. If an inconsistency is found, an :exc:`AssertionError` is + raised which should make clear what is the problem. INPUT: - ``ring`` -- a ring - - ``sparse`` -- a boolean - - ``checkrank`` -- a boolean + - ``sparse`` -- boolean + - ``checkrank`` -- boolean - OUTPUT: - - - nothing if everything is correct, otherwise raise an AssertionError + OUTPUT: nothing if everything is correct, otherwise raise an AssertionError The methods determinant, is_invertible, rank and inverse are checked for - the 0x0 empty identity matrix @@ -2748,7 +2744,6 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: tinv(CyclotomicField(7), sparse=False) # needs sage.rings.number_field sage: tinv(QQ['x,y'], sparse=True) sage: tinv(QQ['x,y'], sparse=False) - """ # Check that the empty 0x0 matrix is it's own inverse with det=1. ms00 = MatrixSpace(ring, 0, 0, sparse=sparse) diff --git a/src/sage/matrix/matrix_sparse.pxd b/src/sage/matrix/matrix_sparse.pxd index 7546645a6c9..7d8878ea4d8 100644 --- a/src/sage/matrix/matrix_sparse.pxd +++ b/src/sage/matrix/matrix_sparse.pxd @@ -1,4 +1,4 @@ -from .matrix cimport Matrix +from sage.matrix.matrix cimport Matrix cdef class Matrix_sparse(Matrix): pass diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index 9354558d23d..95b8969e0aa 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -228,7 +228,7 @@ cdef class Matrix_sparse(matrix.Matrix): def _multiply_classical_with_cache(Matrix_sparse left, Matrix_sparse right): """ This function computes the locations of the end of the rows/columns - in the non-zero entries list once O(rows+cols) time and space, then + in the nonzero entries list once O(rows+cols) time and space, then uses these values in the inner loops. For large matrices this can be a 2x or more speedup, but the matrices can no longer be arbitrarily large as the runtime and space requirements are no @@ -307,12 +307,10 @@ cdef class Matrix_sparse(matrix.Matrix): INPUT: - - `right` -- a ring element which must already be in the basering - of ``self`` (no coercion done here). + - ``right`` -- a ring element which must already be in the base ring + of ``self`` (no coercion done here) - OUTPUT: - - the matrix ``self * right`` + OUTPUT: the matrix ``self * right`` EXAMPLES:: @@ -659,9 +657,9 @@ cdef class Matrix_sparse(matrix.Matrix): - ``phi`` -- arbitrary Python function or callable object - - ``R`` -- (optional) ring + - ``R`` -- (optional) ring - - ``sparse`` -- (default: ``True``) whether to return + - ``sparse`` -- boolean (default: ``True``); whether to return a sparse or a dense matrix OUTPUT: a matrix over ``R`` @@ -700,7 +698,7 @@ cdef class Matrix_sparse(matrix.Matrix): sage: n[1, 2] 2 - If self is subdivided, the result will be as well:: + If ``self`` is subdivided, the result will be as well:: sage: m = matrix(2, 2, [0, 0, 3, 0]) sage: m.subdivide(None, 1); m @@ -710,7 +708,7 @@ cdef class Matrix_sparse(matrix.Matrix): [0|0] [9|0] - If the map sends zero to a non-zero value, then it may be useful to + If the map sends zero to a nonzero value, then it may be useful to get the result as a dense matrix. :: @@ -744,7 +742,7 @@ cdef class Matrix_sparse(matrix.Matrix): [ 1 1/2] [1/3 1/4] - Test subdivisions when phi maps 0 to non-zero:: + Test subdivisions when phi maps 0 to nonzero:: sage: m = matrix(2, 2, [0, 0, 3, 0]) sage: m.subdivide(None, 1); m @@ -1123,7 +1121,7 @@ cdef class Matrix_sparse(matrix.Matrix): INPUT: - - ``v`` -- a free module element + - ``v`` -- a free module element OUTPUT: the vector times matrix product ``v*A`` diff --git a/src/sage/matrix/matrix_symbolic_dense.pyx b/src/sage/matrix/matrix_symbolic_dense.pyx index 7a0dab316d8..4e64a22cd15 100644 --- a/src/sage/matrix/matrix_symbolic_dense.pyx +++ b/src/sage/matrix/matrix_symbolic_dense.pyx @@ -170,7 +170,6 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): """ Echelonize using the classical algorithm. - TESTS:: sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]]) @@ -179,7 +178,7 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): [0 1] """ - return super().echelonize(algorithm="classical", **kwds) + return super().echelonize(algorithm='classical', **kwds) def eigenvalues(self, extend=True): """ @@ -479,7 +478,7 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): INPUT: - - ``var`` -- (default: 'x') name of variable of charpoly + - ``var`` -- (default: ``'x'``) name of variable of charpoly EXAMPLES:: @@ -569,7 +568,6 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): sage: m = matrix([[x]]) sage: m.minimal_polynomial('y') y - x - """ mp = self.fetch('minpoly') if mp is None: @@ -586,7 +584,7 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): INPUT: - - ``var`` -- (default: 'x') name of variable of charpoly + - ``var`` -- (default: ``'x'``) name of variable of charpoly EXAMPLES:: @@ -605,7 +603,6 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): (x^2 - 65*x - 250) * x^3 sage: list(a.fcp()) [(x^2 - 65*x - 250, 1), (x, 3)] - """ from sage.symbolic.ring import SR sub_dict = {var: SR.var(var)} @@ -779,11 +776,9 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): INPUT: - - ``self`` -- the matrix whose entries we should simplify. + - ``self`` -- the matrix whose entries we should simplify - OUTPUT: - - A copy of ``self`` with all of its entries simplified. + OUTPUT: a copy of ``self`` with all of its entries simplified EXAMPLES: @@ -798,7 +793,6 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): sage: A.simplify_full() [ 1 sin(1/(x + 1))] [ factorial(n) x^(-a + 1)*sin(2)] - """ M = self.parent() return M([expr.simplify_full() for expr in self]) diff --git a/src/sage/matrix/matrix_symbolic_sparse.pyx b/src/sage/matrix/matrix_symbolic_sparse.pyx index 680e36c5c6c..a1acdc401b4 100644 --- a/src/sage/matrix/matrix_symbolic_sparse.pyx +++ b/src/sage/matrix/matrix_symbolic_sparse.pyx @@ -177,7 +177,6 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): """ Echelonize using the classical algorithm. - TESTS:: sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]], sparse=True) @@ -185,7 +184,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): [1 0] [0 1] """ - return super().echelonize(algorithm="classical", **kwds) + return super().echelonize(algorithm='classical', **kwds) def eigenvalues(self, extend=True): """ @@ -486,7 +485,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): INPUT: - - ``var`` -- (default: 'x') name of variable of charpoly + - ``var`` -- (default: ``'x'``) name of variable of charpoly EXAMPLES:: @@ -576,7 +575,6 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: m = matrix([[x]], sparse=True) sage: m.minimal_polynomial('y') y - x - """ mp = self.fetch('minpoly') if mp is None: @@ -593,7 +591,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): INPUT: - - ``var`` -- (default: 'x') name of variable of charpoly + - ``var`` -- (default: ``'x'``) name of variable of charpoly EXAMPLES:: @@ -612,7 +610,6 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): (x^2 - 65*x - 250) * x^3 sage: list(a.fcp()) [(x^2 - 65*x - 250, 1), (x, 3)] - """ from sage.symbolic.ring import SR sub_dict = {var: SR.var(var)} @@ -786,11 +783,9 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): INPUT: - - ``self`` -- the matrix whose entries we should simplify. + - ``self`` -- the matrix whose entries we should simplify - OUTPUT: - - A copy of ``self`` with all of its entries simplified. + OUTPUT: a copy of ``self`` with all of its entries simplified EXAMPLES: @@ -805,7 +800,6 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: A.simplify_full() [ 1 sin(1/(x + 1))] [ factorial(n) x^(-a + 1)*sin(2)] - """ M = self.parent() return M([expr.simplify_full() for expr in self]) diff --git a/src/sage/matrix/matrix_window.pyx b/src/sage/matrix/matrix_window.pyx index 4a1f057ef1e..8c79540f6ef 100644 --- a/src/sage/matrix/matrix_window.pyx +++ b/src/sage/matrix/matrix_window.pyx @@ -55,7 +55,7 @@ cdef class MatrixWindow: cpdef MatrixWindow matrix_window(MatrixWindow self, Py_ssize_t row, Py_ssize_t col, Py_ssize_t n_rows, Py_ssize_t n_cols): """ - Returns a matrix window relative to this window of the + Return a matrix window relative to this window of the underlying matrix. """ if row == 0 and col == 0 and n_rows == self._nrows and n_cols == self._ncols: @@ -121,13 +121,13 @@ cdef class MatrixWindow: cpdef matrix(MatrixWindow self): """ - Returns the underlying matrix that this window is a view of. + Return the underlying matrix that this window is a view of. """ return self._matrix cpdef to_matrix(MatrixWindow self): """ - Returns an actual matrix object representing this view. + Return an actual matrix object representing this view. """ cdef MatrixWindow w a = self._matrix.new_matrix(self._nrows, self._ncols) # zero matrix diff --git a/src/sage/matrix/meson.build b/src/sage/matrix/meson.build new file mode 100644 index 00000000000..c0841d77f34 --- /dev/null +++ b/src/sage/matrix/meson.build @@ -0,0 +1,199 @@ +iml = cc.find_library('iml') + + +py.install_sources( + 'action.pxd', + 'all.py', + 'all__sagemath_meataxe.py', + 'args.pxd', + 'benchmark.py', + 'berlekamp_massey.py', + 'compute_J_ideal.py', + 'docs.py', + 'matrix.pxd', + 'matrix0.pxd', + 'matrix1.pxd', + 'matrix2.pxd', + 'matrix_cdv.pxd', + 'matrix_complex_ball_dense.pxd', + 'matrix_complex_double_dense.pxd', + 'matrix_cyclo_dense.pxd', + 'matrix_dense.pxd', + 'matrix_domain_dense.pxd', + 'matrix_domain_sparse.pxd', + 'matrix_double_dense.pxd', + 'matrix_double_sparse.pxd', + 'matrix_gap.pxd', + 'matrix_generic_dense.pxd', + 'matrix_generic_sparse.pxd', + 'matrix_gf2e_dense.pxd', + 'matrix_gfpn_dense.pxd', + 'matrix_integer_dense.pxd', + 'matrix_integer_dense_hnf.py', + 'matrix_integer_dense_saturation.py', + 'matrix_integer_sparse.pxd', + 'matrix_laurent_mpolynomial_dense.pxd', + 'matrix_misc.py', + 'matrix_mod2_dense.pxd', + 'matrix_modn_dense_double.pxd', + 'matrix_modn_dense_float.pxd', + 'matrix_modn_sparse.pxd', + 'matrix_mpolynomial_dense.pxd', + 'matrix_numpy_dense.pxd', + 'matrix_numpy_integer_dense.pxd', + 'matrix_polynomial_dense.pxd', + 'matrix_rational_dense.pxd', + 'matrix_rational_sparse.pxd', + 'matrix_real_double_dense.pxd', + 'matrix_space.py', + 'matrix_sparse.pxd', + 'matrix_symbolic_dense.pxd', + 'matrix_symbolic_sparse.pxd', + 'matrix_window.pxd', + 'operation_table.py', + 'special.py', + 'symplectic_basis.py', + 'template.pxd', + 'tests.py', + subdir: 'sage/matrix', +) + +extension_data = { + 'action' : files('action.pyx'), + 'args' : files('args.pyx'), + 'change_ring' : files('change_ring.pyx'), + 'constructor' : files('constructor.pyx'), + 'echelon_matrix' : files('echelon_matrix.pyx'), + 'matrix0' : files('matrix0.pyx'), + 'matrix1' : files('matrix1.pyx'), + 'matrix2' : files('matrix2.pyx'), + 'matrix_cdv' : files('matrix_cdv.pyx'), + 'matrix_complex_ball_dense' : files('matrix_complex_ball_dense.pyx'), + 'matrix_complex_double_dense' : files('matrix_complex_double_dense.pyx'), + 'matrix_dense' : files('matrix_dense.pyx'), + 'matrix_double_dense' : files('matrix_double_dense.pyx'), + 'matrix_double_sparse' : files('matrix_double_sparse.pyx'), + 'matrix_gap' : files('matrix_gap.pyx'), + 'matrix_generic_dense' : files('matrix_generic_dense.pyx'), + 'matrix_generic_sparse' : files('matrix_generic_sparse.pyx'), + 'matrix_gfpn_dense' : files('matrix_gfpn_dense.pyx'), + 'matrix_laurent_mpolynomial_dense' : files( + 'matrix_laurent_mpolynomial_dense.pyx', + ), + 'matrix_numpy_dense' : files('matrix_numpy_dense.pyx'), + 'matrix_numpy_integer_dense' : files('matrix_numpy_integer_dense.pyx'), + 'matrix_polynomial_dense' : files('matrix_polynomial_dense.pyx'), + 'matrix_rational_sparse' : files('matrix_rational_sparse.pyx'), + 'matrix_real_double_dense' : files('matrix_real_double_dense.pyx'), + 'matrix_sparse' : files('matrix_sparse.pyx'), + 'matrix_symbolic_dense' : files('matrix_symbolic_dense.pyx'), + 'matrix_symbolic_sparse' : files('matrix_symbolic_sparse.pyx'), + 'matrix_window' : files('matrix_window.pyx'), + 'misc' : files('misc.pyx'), + 'misc_flint' : files('misc_flint.pyx'), + 'misc_mpfr' : files('misc_mpfr.pyx'), + 'strassen' : files('strassen.pyx'), +} + +foreach name, pyx : extension_data + dependencies = [ + py_dep, + blas, + cypari2, + cysignals, + fflas, + flint, + gd, + givaro, + gmp, + gmpxx, + iml, + linbox, + m, + m4ri, + m4rie, + mpfi, + mpfr, + ntl, + pari, + png, + zlib, + ] + if name == 'matrix_gfpn_dense' + dependencies += [mtx, meataxe] + endif + + py.extension_module( + name, + sources: pyx, + subdir: 'sage/matrix', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_ntl, + inc_numpy, + inc_rings, + inc_rings_finite, + ], + dependencies: dependencies, + ) +endforeach + +extension_data_cpp = { + 'matrix_cyclo_dense': files('matrix_cyclo_dense.pyx'), + 'matrix_gf2e_dense': files('matrix_gf2e_dense.pyx'), + 'matrix_integer_dense': files('matrix_integer_dense.pyx'), + 'matrix_integer_sparse': files('matrix_integer_sparse.pyx'), + 'matrix_mod2_dense': files('matrix_mod2_dense.pyx'), + 'matrix_modn_dense_double': files('matrix_modn_dense_double.pyx'), + 'matrix_modn_dense_float': files('matrix_modn_dense_float.pyx'), + 'matrix_modn_sparse': files('matrix_modn_sparse.pyx'), + 'matrix_mpolynomial_dense': files('matrix_mpolynomial_dense.pyx'), + 'matrix_rational_dense': files('matrix_rational_dense.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/matrix', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_ntl, + inc_numpy, + inc_rings, + inc_rings_finite, + ], + dependencies: [ + py_dep, + blas, + cypari2, + cysignals, + fflas, + flint, + gd, + givaro, + gmp, + gmpxx, + iml, + linbox, + m, + m4ri, + m4rie, + mpfi, + mpfr, + ntl, + pari, + png, + singular, + zlib, + ], + ) +endforeach + diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 5ff93f4accb..17277336e3c 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -124,16 +124,17 @@ def matrix_integer_sparse_rational_reconstruction(Matrix_integer_sparse A, Integ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, proof=None): """ - Returns reduced row-echelon form using a multi-modular - algorithm. Does not change self. + Return reduced row-echelon form using a multi-modular + algorithm. Does not change ``self``. REFERENCE: Chapter 7 of Stein's "Explicitly Computing Modular Forms". INPUT: - - height_guess -- integer or None - - proof -- boolean or None (default: None, see proof.linear_algebra or - sage.structure.proof). Note that the global Sage default is proof=True + - ``height_guess`` -- integer or ``None`` + - ``proof`` -- boolean or ``None`` (default: ``None``, see + ``proof.linear_algebra`` or ``sage.structure.proof``). Note that the + global Sage default is proof=True OUTPUT: a pair consisting of a matrix in echelon form and a tuple of pivot positions. diff --git a/src/sage/matrix/misc_flint.pyx b/src/sage/matrix/misc_flint.pyx index 3e829df4d22..2d054c9e718 100644 --- a/src/sage/matrix/misc_flint.pyx +++ b/src/sage/matrix/misc_flint.pyx @@ -27,7 +27,7 @@ def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer INPUT: - ``A`` -- matrix - - ``N`` -- an integer + - ``N`` -- integer EXAMPLES:: diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index edd2c781047..89943f90b3b 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -61,13 +61,14 @@ class OperationTable(SageObject): - ``elements`` -- (default: ``None``) A list of elements of ``S``, in forms that can be coerced into the structure, eg. their string representations. This may be used to impose an alternate - ordering on the elements of `S``, perhaps when this is used in + ordering on the elements of ``S``, perhaps when this is used in the context of a particular structure. The default is to use - whatever ordering the ``S.list()`` method returns. `elements`` + whatever ordering the ``S.list()`` method returns. ``elements`` can also be a subset which is closed under the operation, useful perhaps when the set is infinite. OUTPUT: + An object with methods that abstracts multiplication tables, addition tables, Cayley tables, etc. It should be general enough to be useful for any finite algebraic structure @@ -493,17 +494,18 @@ def _name_maker(self, names): Helper function to create names of elements of algebraic structures. INPUT: + Identical to the input for :class:`OperationTable` and :meth:`change_names`, so look there for details. OUTPUT: - - ``width`` -- an integer giving the maximum width of the strings + - ``width`` -- integer giving the maximum width of the strings describing the elements. This is used for formatting the ASCII version of the table. - - ``name_list`` -- a list of strings naming the elements, in the - same order as given by the :meth:`list` method. - - ``name_dict`` -- a dictionary giving the correspondence between the + - ``name_list`` -- list of strings naming the elements, in the + same order as given by the :meth:`list` method + - ``name_dict`` -- dictionary giving the correspondence between the strings and the actual elements. So the keys are the strings and the values are the elements of the structure. @@ -574,8 +576,7 @@ def _name_maker(self, names): width = 0 for e in self._elts: estr = repr(e) - if len(estr) > width: - width = len(estr) + width = max(len(estr), width) name_list.append(estr) elif isinstance(names, list): if len(names) != self._n: @@ -586,8 +587,7 @@ def _name_maker(self, names): if not isinstance(name, str): raise ValueError( 'list of element names must only contain strings, not %s' % name) - if len(name) > width: - width = len(name) + width = max(len(name), width) name_list.append(name) else: raise ValueError( @@ -599,12 +599,14 @@ def _name_maker(self, names): def __getitem__(self, pair): r""" - Returns the element of the table, given the elements indexing its position. + Return the element of the table, given the elements indexing its position. INPUT: - - pair -- two elements of the structure + + - ``pair`` -- two elements of the structure OUTPUT: + The element of the structure computed by the operation for the two input elements (in the order provided). @@ -659,13 +661,14 @@ def __getitem__(self, pair): def __eq__(self, other): r""" - Returns the comparison between two tables. + Return the comparison between two tables. INPUT: - - ``other`` -- a second table to compare to ``self``. + - ``other`` -- a second table to compare to ``self`` OUTPUT: + Tables are equal if they have the same operation and elements. EXAMPLES:: @@ -704,7 +707,7 @@ def __ne__(self, other): def _repr_(self): r""" - Returns a printable version of the operation table. + Return a printable version of the operation table. EXAMPLES:: @@ -729,8 +732,8 @@ def set_print_symbols(self, ascii, latex): INPUT: - ``ascii`` -- a single character for text table - - ``latex`` -- a string to represent an operation in LaTeX math mode. - Note the need for double-backslashes to escape properly. + - ``latex`` -- string to represent an operation in LaTeX math mode; + note the need for double-backslashes to escape properly EXAMPLES:: @@ -778,9 +781,9 @@ def set_print_symbols(self, ascii, latex): def column_keys(self): r""" - Returns a tuple of the elements used to build the table. + Return a tuple of the elements used to build the table. - .. note:: ``column_keys`` and ``row_keys`` are identical. + .. NOTE:: ``column_keys`` and ``row_keys`` are identical. Both list the elements in the order used to label the table. OUTPUT: @@ -809,9 +812,10 @@ def column_keys(self): def translation(self): r""" - Returns a dictionary associating names with elements. + Return a dictionary associating names with elements. OUTPUT: + A dictionary whose keys are strings used as names for entries of the table and values that are the actual elements of the algebraic structure. @@ -828,10 +832,11 @@ def translation(self): def table(self): r""" - Returns the table as a list of lists, + Return the table as a list of lists, using integers to reference the elements. OUTPUT: + The rows of the table, as a list of rows, each row being a list of integer entries. The integers correspond to the order of the elements in the headings of the table @@ -968,7 +973,8 @@ def color_table(self, element_names=True, cmap=None, **options): INPUT: - - ``element_names`` -- (default : ``True``) Whether to display text with element names on the image + - ``element_names`` -- (default: ``True``) whether to display text with + element names on the image - ``cmap`` -- (default: :obj:`matplotlib.cm.gist_rainbow`) color map for plot, see :mod:`matplotlib.cm` @@ -1029,7 +1035,8 @@ def gray_table(self, **options): INPUT: - - ``element_names`` -- (default: ``True``) whether to display text with element names on the image + - ``element_names`` -- boolean (default: ``True``); whether to display + text with element names on the image - ``**options`` -- passed on to :func:`~sage.plot.matrix_plot.matrix_plot` @@ -1051,7 +1058,7 @@ def gray_table(self, **options): def _ascii_table(self): r""" - Returns a string that is an ASCII version of the table. + Return a string that is an ASCII version of the table. EXAMPLES:: @@ -1142,7 +1149,7 @@ def _ascii_table(self): def _latex_(self): r""" - Returns a `LaTeX` version of the operation table as a string, + Return a `LaTeX` version of the operation table as a string, using a `LaTeX` ``array`` environment. EXAMPLES:: diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 38f0876d589..b81703b6fe7 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -79,13 +79,13 @@ def matrix_method(func=None, name=None): """ - Allows a function to be tab-completed on the global matrix + Allow a function to be tab-completed on the global matrix constructor object. INPUT: - - ``*function`` -- a single argument. The function that is being - decorated. + - ``*function`` -- a single argument; the function that is being + decorated - ``**kwds`` -- a single optional keyword argument ``name=``. The name of the corresponding method in the @@ -128,7 +128,7 @@ def column_matrix(*args, **kwds): r""" Construct a matrix, and then swap rows for columns and columns for rows. - .. note:: + .. NOTE:: Linear algebra in Sage favors rows over columns. So, generally, when creating a matrix, input vectors and lists are @@ -155,7 +155,7 @@ def column_matrix(*args, **kwds): The most compelling use of this function is when you have a collection of lists or vectors that you would like to become the columns of a matrix. In almost any other situation, the - :func:`matrix`` constructor can probably do the + :func:`matrix` constructor can probably do the job just as easily, or easier. :: sage: col_1 = [1,2,3] @@ -217,40 +217,39 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation INPUT: - - ``ring`` -- base ring for entries of the matrix + - ``ring`` -- base ring for entries of the matrix - - ``nrows`` -- Integer; number of rows + - ``nrows`` -- integer; number of rows - - ``ncols`` -- (default: ``None``); number of columns; if ``None`` - defaults to ``nrows`` + - ``ncols`` -- (default: ``None``) number of columns. If ``None`` + defaults to ``nrows``. - - ``algorithm`` -- (default: ``randomize``); determines what properties - the matrix will have. See examples below for possible additional - arguments. + - ``algorithm`` -- (default: ``'randomize'``) determines what properties + the matrix will have. See examples below for possible additional + arguments. - - ``randomize`` -- create a matrix of random elements from the - base ring, possibly controlling the density of non-zero entries. + - ``'randomize'`` -- create a matrix of random elements from the + base ring, possibly controlling the density of nonzero entries - - ``echelon_form`` -- creates a matrix in echelon form + - ``'echelon_form'`` -- creates a matrix in echelon form - - ``echelonizable`` -- creates a matrix that has a predictable - echelon form + - ``'echelonizable'`` -- creates a matrix that has a predictable + echelon form - - ``subspaces`` -- creates a matrix whose four subspaces, when - explored, have reasonably sized, integral valued, entries. + - ``'subspaces'`` -- creates a matrix whose four subspaces, when + explored, have reasonably sized, integral valued, entries - - ``unimodular`` -- creates a matrix of determinant 1. + - ``'unimodular'`` -- creates a matrix of determinant 1 - - ``diagonalizable`` -- creates a diagonalizable matrix whose - eigenvectors, if computed by hand, will have only integer - entries. + - ``'diagonalizable'`` -- creates a diagonalizable matrix whose + eigenvectors, if computed by hand, will have only integer entries - ``implementation`` -- (``None`` or string or a matrix class) a possible implementation. See the documentation of the constructor of :class:`~sage.matrix.matrix_space.MatrixSpace`. - - ``*args, **kwds`` -- arguments and keywords to describe additional - properties. See more detailed documentation below. + - ``*args, **kwds`` -- arguments and keywords to describe additional + properties. See more detailed documentation below .. warning:: @@ -265,11 +264,11 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation An upper bound on the absolute value of the entries may be set when the ``algorithm`` is ``echelonizable`` or ``unimodular``. In these cases it is possible for this constructor to fail with - a :class:`ValueError`. If you *must* have this routine return + a :exc:`ValueError`. If you *must* have this routine return successfully, do not set ``upper_bound``. This behavior can be partially controlled by a ``max_tries`` keyword. - .. note:: + .. NOTE:: When constructing matrices with random entries and no additional properties (i.e. when ``algorithm='randomize'``), @@ -404,7 +403,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation sage: K. = FiniteField(2^8) # needs sage.rings.finite_rings sage: type(random_matrix(K, 2, 5)) # needs sage.libs.m4ri sage.rings.finite_rings - sage: type(random_matrix(K, 2, 5, implementation="generic")) # needs sage.rings.finite_rings + sage: type(random_matrix(K, 2, 5, implementation='generic')) # needs sage.rings.finite_rings Random rational matrices. Now ``num_bound`` and ``den_bound`` control the @@ -488,7 +487,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation sage: TestSuite(A).run() Random matrices in echelon form. The ``algorithm='echelon_form'`` keyword, - along with a requested number of non-zero rows (``num_pivots``) will return + along with a requested number of nonzero rows (``num_pivots``) will return a random matrix in echelon form. When the base ring is ``QQ`` the result has integer entries. Other exact rings may be also specified. :: @@ -696,8 +695,8 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): diagonal entries. This may not be specified in combination with a NumPy array. - - ``sparse`` -- (default: ``True``); whether or not - the result has a sparse implementation. + - ``sparse`` -- boolean (default: ``True``); whether or not + the result has a sparse implementation OUTPUT: @@ -1000,11 +999,23 @@ def zero_matrix(ring, nrows=None, ncols=None, sparse=False): [0 0 0 0 0] [0 0 0 0 0] + TESTS: + + Check that :issue:`38221` is fixed:: + + sage: # needs sage.groups + sage: G = CyclicPermutationGroup(7) + sage: R = GF(2) + sage: A = G.algebra(R) + sage: zero_matrix(A, 3, 3) + [0 0 0] + [0 0 0] + [0 0 0] """ if isinstance(ring, (Integer, int)): nrows, ncols = (ring, nrows) ring = ZZ - return matrix_space.MatrixSpace(ring, nrows, ncols, sparse)(0) + return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix(None) @matrix_method @@ -1023,11 +1034,11 @@ def ones_matrix(ring, nrows=None, ncols=None, sparse=False): INPUT: - - ``ring`` -- (default: ``ZZ``); base ring for the matrix. - - ``nrows`` -- number of rows in the matrix. - - ``ncols`` -- number of columns in the matrix. - If omitted, defaults to the number of rows, producing a square matrix. - - ``sparse`` -- (default: ``False``); if ``True`` creates a sparse representation. + - ``ring`` -- (default: ``ZZ``) base ring for the matrix + - ``nrows`` -- number of rows in the matrix + - ``ncols`` -- number of columns in the matrix; + if omitted, defaults to the number of rows, producing a square matrix + - ``sparse`` -- (default: ``False``) if ``True`` creates a sparse representation OUTPUT: @@ -1103,7 +1114,7 @@ def ones_matrix(ring, nrows=None, ncols=None, sparse=False): @matrix_method def elementary_matrix(arg0, arg1=None, **kwds): r""" - Creates a square matrix that corresponds to a row operation or a column operation. + Create a square matrix that corresponds to a row operation or a column operation. FORMATS: @@ -1269,7 +1280,7 @@ def elementary_matrix(arg0, arg1=None, **kwds): sage: E3 = elementary_matrix(QQ, 4, row1=3, scale=0) Traceback (most recent call last): ... - ValueError: scale parameter of row of elementary matrix must be non-zero + ValueError: scale parameter of row of elementary matrix must be nonzero sage: E4 = elementary_matrix(QQ, 4, row1=3, row2=3, scale=12) Traceback (most recent call last): @@ -1405,7 +1416,7 @@ def elementary_matrix(arg0, arg1=None, **kwds): sage: E = elementary_matrix(ZZ, 5, col1=3, scale=0) Traceback (most recent call last): ... - ValueError: scale parameter of column of elementary matrix must be non-zero + ValueError: scale parameter of column of elementary matrix must be nonzero AUTHOR: @@ -1489,7 +1500,7 @@ def elementary_matrix(arg0, arg1=None, **kwds): elem[row2, row1] = 1 elif row2 is None and scale is not None: if scale == 0: - raise ValueError('scale parameter of {0} of elementary matrix must be non-zero'.format(opstring)) + raise ValueError('scale parameter of {0} of elementary matrix must be nonzero'.format(opstring)) elem[row1, row1] = scale if rowop: return elem @@ -1500,14 +1511,14 @@ def elementary_matrix(arg0, arg1=None, **kwds): @matrix_method def circulant(v, sparse=None): r""" - Return the circulant matrix specified by its 1st row `v` + Return the circulant matrix specified by its 1st row `v`. A circulant `n \times n` matrix specified by the 1st row `v=(v_0...v_{n-1})` is the matrix `(c_{ij})_{0 \leq i,j\leq n-1}`, where `c_{ij}=v_{j-i \mod b}`. INPUT: - - ``v`` -- a list or a vector of values + - ``v`` -- list or a vector of values - ``sparse`` -- ``None`` by default; if ``sparse`` is set to ``True``, the output will be sparse. Respectively, setting it to ``False`` produces dense output. @@ -1562,7 +1573,7 @@ def _determine_block_matrix_grid(sub_matrices): Non-zero scalars are considered to be square matrices of any size, and zeroes are considered to be zero matrices of any size. - A :class:`ValueError` is raised if there is insufficient or + A :exc:`ValueError` is raised if there is insufficient or conflicting information. TESTS:: @@ -1600,7 +1611,7 @@ def _determine_block_matrix_grid(sub_matrices): if isinstance(M, Matrix): sub_width = M.ncols() sub_height = M.nrows() - elif M: # non-zero scalar is interpreted as a square matrix + elif M: # nonzero scalar is interpreted as a square matrix if row_heights[i] is None: sub_width = col_widths[j] else: @@ -1641,7 +1652,7 @@ def _determine_block_matrix_rows(sub_matrices): Non-zero scalars are considered to be square matrices of any size, and zeroes are considered to be zero matrices of any size. - A ``ValueError`` is raised if there is insufficient or + A :exc:`ValueError` is raised if there is insufficient or conflicting information. TESTS:: @@ -1679,14 +1690,14 @@ def _determine_block_matrix_rows(sub_matrices): height = 0 # If we have a height, then we know the dimensions of any - # non-zero scalars, and can maybe compute the width + # nonzero scalars, and can maybe compute the width if height is not None and not found_zeroes: width = 0 for M in R: if isinstance(M, Matrix): width += M.ncols() else: - # non-zero scalar + # nonzero scalar width += height if total_width is None: total_width = width @@ -1711,7 +1722,7 @@ def _determine_block_matrix_rows(sub_matrices): zero_state = 0 # 0: no zeroes found # 1: consecutive zeroes found - # 2: consecutive zeroes followed by non-zero found + # 2: consecutive zeroes followed by nonzero found # 3: non-consecutive zeroes found scalars = 0 width = 0 @@ -1733,7 +1744,7 @@ def _determine_block_matrix_rows(sub_matrices): remaining_width = total_width - width # This remaining width has to be split over the - # zeroes and (non-zero) scalars + # zeroes and (nonzero) scalars if height is not None: remaining_width -= scalars * height @@ -1783,19 +1794,18 @@ def block_matrix(*args, **kwds): ``nrows`` and ``ncols`` to determine their layout), or a list of lists of matrices, where each list forms a row. - - ``ring`` -- the base ring - - - ``nrows`` -- the number of block rows + - ``ring`` -- the base ring - - ``ncols`` -- the number of block cols + - ``nrows`` -- the number of block rows - - ``sub_matrices`` -- matrices (see below for syntax) + - ``ncols`` -- the number of block cols - - ``subdivide`` -- boolean, whether or not to add - subdivision information to the matrix + - ``sub_matrices`` -- matrices (see below for syntax) - - ``sparse`` -- boolean, whether to make the resulting matrix sparse + - ``subdivide`` -- boolean, whether or not to add + subdivision information to the matrix + - ``sparse`` -- boolean, whether to make the resulting matrix sparse EXAMPLES:: @@ -2165,9 +2175,9 @@ def jordan_block(eigenvalue, size, sparse=False): INPUT: - - ``eigenvalue`` -- eigenvalue for the diagonal entries of the block - - ``size`` -- size of the square matrix - - ``sparse`` -- (default: ``False``); if ``True``, return a sparse matrix + - ``eigenvalue`` -- eigenvalue for the diagonal entries of the block + - ``size`` -- size of the square matrix + - ``sparse`` -- (default: ``False``) if ``True``, return a sparse matrix EXAMPLES:: @@ -2185,7 +2195,7 @@ def jordan_block(eigenvalue, size, sparse=False): sage: jordan_block(6.2, -1) Traceback (most recent call last): ... - ValueError: size of Jordan block must be non-negative, not -1 + ValueError: size of Jordan block must be nonnegative, not -1 """ try: size = ZZ(size) @@ -2193,7 +2203,7 @@ def jordan_block(eigenvalue, size, sparse=False): msg = "size of Jordan block needs to be an integer, not {0}" raise TypeError(msg.format(size)) if size < 0: - msg = "size of Jordan block must be non-negative, not {0}" + msg = "size of Jordan block must be nonnegative, not {0}" raise ValueError(msg.format(size)) block = diagonal_matrix([eigenvalue] * size, sparse=sparse) for i in range(size - 1): @@ -2215,10 +2225,10 @@ def companion_matrix(poly, format='right'): A symbolic expression that might also be a polynomial is not proper input, see examples below. - - ``format`` -- (default: 'right'); specifies one of four + - ``format`` -- (default: ``'right'``) specifies one of four variations of a companion matrix. Allowable values are - 'right', 'left', 'top' and 'bottom', which indicates which - border of the matrix contains the negatives of the coefficients. + ``'right'``, ``'left'``, ``'top'`` and ``'bottom'``, which indicates + which border of the matrix contains the negatives of the coefficients. OUTPUT: @@ -2382,7 +2392,7 @@ def companion_matrix(poly, format='right'): M = sage.matrix.constructor.matrix(poly.universe(), n, n) except TypeError: raise TypeError("unable to find common ring for coefficients from polynomial") - # 1's below diagonal, or above diagonal + # 1s below diagonal, or above diagonal if format in ['right', 'top']: for i in range(n - 1): M[i+1, i] = 1 @@ -2408,21 +2418,21 @@ def companion_matrix(poly, format='right'): @matrix_method def random_rref_matrix(parent, num_pivots): r""" - Generate a matrix in reduced row-echelon form with a specified number of non-zero rows. + Generate a matrix in reduced row-echelon form with a specified number of nonzero rows. INPUT: - - ``parent`` -- A matrix space specifying the base ring, dimensions and + - ``parent`` -- a matrix space specifying the base ring, dimensions and representation (dense/sparse) for the result. The base ring must be exact. - - ``num_pivots`` -- The number of non-zero rows in the result, i.e. the rank. + - ``num_pivots`` -- the number of nonzero rows in the result, i.e. the rank OUTPUT: - A matrix in reduced row echelon form with ``num_pivots`` non-zero rows. If the + A matrix in reduced row echelon form with ``num_pivots`` nonzero rows. If the base ring is `ZZ` or `QQ` then the entries are all integers. - .. note:: + .. NOTE:: It is easiest to use this function via a call to the :func:`~sage.matrix.constructor.random_matrix` @@ -2583,32 +2593,31 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): INPUT: - - ``parent`` -- A matrix space specifying the base ring, dimensions and + - ``parent`` -- a matrix space specifying the base ring, dimensions and representation (dense/sparse) for the result. The base ring must be exact. - - ``rank`` -- Rank of result, i.e the number of non-zero rows in the - reduced row echelon form. + - ``rank`` -- rank of result, i.e the number of nonzero rows in the + reduced row echelon form - - ``upper_bound`` -- If designated, size control of the matrix entries is desired. + - ``upper_bound`` -- if designated, size control of the matrix entries is desired Set ``upper_bound`` to 1 more than the maximum value entries can achieve. - If None, no size control occurs. But see the warning below. (default: None) + If ``None``, no size control occurs. But see the warning below. (default: ``None``) - - ``max_tries`` -- If designated, number of tries used to generate each new random row; + - ``max_tries`` -- if designated, number of tries used to generate each new random row;s only matters when upper_bound!=None. Used to prevent endless looping. (default: 100) - OUTPUT: - - A matrix not in reduced row-echelon form with the desired dimensions and properties. + OUTPUT: a matrix not in reduced row-echelon form with the desired + dimensions and properties .. warning:: When ``upper_bound`` is set, it is possible for this constructor to - fail with a ``ValueError``. This may happen when the ``upper_bound``, + fail with a :exc:`ValueError`. This may happen when the ``upper_bound``, ``rank`` and/or matrix dimensions are all so small that it becomes infeasible or unlikely to create the requested matrix. If you *must* have this routine return successfully, do not set ``upper_bound``. - .. note:: + .. NOTE:: It is easiest to use this function via a call to the :func:`~sage.matrix.constructor.random_matrix` @@ -2798,17 +2807,17 @@ def random_subspaces_matrix(parent, rank=None): INPUT: - - ``parent`` -- A matrix space specifying the base ring, dimensions, and + - ``parent`` -- a matrix space specifying the base ring, dimensions, and representation (dense/sparse) for the result. The base ring must be exact. - - ``rank`` -- The desired rank of the return matrix (default: None). + - ``rank`` -- the desired rank of the return matrix (default: ``None``) OUTPUT: A matrix whose natural basis vectors for its four subspaces, when computed, have reasonably sized, integral valued, entries. - .. note:: + .. NOTE:: It is easiest to use this function via a call to the :func:`~sage.matrix.constructor.random_matrix` @@ -2945,32 +2954,30 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): INPUT: - - ``parent`` -- A matrix space specifying the base ring, dimensions + - ``parent`` -- a matrix space specifying the base ring, dimensions and representation (dense/sparse) for the result. The base ring must be exact. - - ``upper_bound`` -- For large matrices over QQ or ZZ, + - ``upper_bound`` -- for large matrices over QQ or ZZ, ``upper_bound`` is the largest value matrix entries can achieve. But see the warning below. - - ``max_tries`` -- If designated, number of tries used to generate each new random row; + - ``max_tries`` -- if designated, number of tries used to generate each new random row; only matters when upper_bound!=None. Used to prevent endless looping. (default: 100) A matrix not in reduced row-echelon form with the desired dimensions and properties. - OUTPUT: - - An invertible matrix with the desired properties and determinant 1. + OUTPUT: an invertible matrix with the desired properties and determinant 1 .. warning:: When ``upper_bound`` is set, it is possible for this constructor to - fail with a ``ValueError``. This may happen when the ``upper_bound``, + fail with a :exc:`ValueError`. This may happen when the ``upper_bound``, ``rank`` and/or matrix dimensions are all so small that it becomes infeasible or unlikely to create the requested matrix. If you *must* have this routine return successfully, do not set ``upper_bound``. - .. note:: + .. NOTE:: It is easiest to use this function via a call to the :func:`~sage.matrix.constructor.random_matrix` @@ -3055,12 +3062,12 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): If eigenvalues and dimensions are not specified in a list, they will be assigned randomly. - - ``parent`` -- the desired size of the square matrix. + - ``parent`` -- the desired size of the square matrix - - ``eigenvalues`` -- the list of desired eigenvalues (default=None). + - ``eigenvalues`` -- the list of desired eigenvalues (default=None) - ``dimensions`` -- the list of dimensions corresponding to each - eigenspace (default=None). + eigenspace (default=None) OUTPUT: @@ -3068,7 +3075,7 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): eigenspaces of this matrix, if computed by hand, give basis vectors with only integer entries. - .. note:: + .. NOTE:: It is easiest to use this function via a call to the :func:`~sage.matrix.constructor.random_matrix` @@ -3271,7 +3278,7 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): def vector_on_axis_rotation_matrix(v, i, ring=None): r""" Return a rotation matrix `M` such that `det(M)=1` sending the vector - `v` on the i-th axis so that all other coordinates of `Mv` are zero. + `v` on the `i`-th axis so that all other coordinates of `Mv` are zero. .. NOTE:: @@ -3284,9 +3291,7 @@ def vector_on_axis_rotation_matrix(v, i, ring=None): - ``i`` -- integer - ``ring`` -- ring (default: ``None``) of the resulting matrix - OUTPUT: - - A matrix + OUTPUT: a matrix EXAMPLES:: @@ -3346,8 +3351,8 @@ def vector_on_axis_rotation_matrix(v, i, ring=None): @matrix_method def ith_to_zero_rotation_matrix(v, i, ring=None): r""" - Return a rotation matrix that sends the i-th coordinates of the - vector v to zero by doing a rotation with the (i-1)-th coordinate. + Return a rotation matrix that sends the `i`-th coordinates of the + vector v to zero by doing a rotation with the `(i-1)`-th coordinate. INPUT: @@ -3355,9 +3360,7 @@ def ith_to_zero_rotation_matrix(v, i, ring=None): - ``i`` -- integer - ``ring`` -- ring (default: ``None``) of the resulting matrix - OUTPUT: - - A matrix + OUTPUT: a matrix EXAMPLES:: @@ -3471,9 +3474,9 @@ def hilbert(dim, ring=QQ): INPUT: - - ``dim`` -- integer, the dimension of the Hilbert matrix + - ``dim`` -- integer; the dimension of the Hilbert matrix - - ``ring`` -- base ring (default: \\QQ) of the resulting matrix + - ``ring`` -- base ring (default: `\QQ`) of the resulting matrix EXAMPLES:: @@ -3507,7 +3510,7 @@ def vandermonde(v, ring=None): - ``v`` -- vector, the second column of the Vandermonde matrix - - ``ring`` -- base ring (default: None) of the resulting matrix + - ``ring`` -- base ring (default: ``None``) of the resulting matrix EXAMPLES: @@ -3542,7 +3545,7 @@ def toeplitz(c, r, ring=None): - ``r`` -- vector, first row of the Toeplitz matrix, counting from the second column - - ``ring`` -- base ring (default: None) of the resulting matrix + - ``ring`` -- base ring (default: ``None``) of the resulting matrix EXAMPLES: @@ -3591,10 +3594,10 @@ def hankel(c, r=None, ring=None): - ``c`` -- vector, first column of the Hankel matrix - - ``r`` -- vector (default: None), last row of the Hankel matrix, from + - ``r`` -- vector (default: ``None``); last row of the Hankel matrix, from the second to the last column - - ``ring`` -- base ring (default: None) of the resulting matrix + - ``ring`` -- base ring (default: ``None``) of the resulting matrix EXAMPLES: diff --git a/src/sage/matrix/strassen.pyx b/src/sage/matrix/strassen.pyx index 9d5e7ddadf6..978773e3a27 100644 --- a/src/sage/matrix/strassen.pyx +++ b/src/sage/matrix/strassen.pyx @@ -1,19 +1,19 @@ """ Generic Asymptotically Fast Strassen Algorithms -Sage implements asymptotically fast echelon form and matrix +This implements asymptotically fast echelon form and matrix multiplication algorithms. """ -#***************************************************************************** +# *************************************************************************** # Copyright (C) 2005, 2006 William Stein # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# *************************************************************************** from sage.matrix.matrix_window cimport MatrixWindow @@ -22,16 +22,18 @@ from cysignals.signals cimport sig_on, sig_off def strassen_window_multiply(C, A,B, cutoff): """ - Multiplies the submatrices specified by A and B, places result in + Multiply the submatrices specified by A and B, places result in C. Assumes that A and B have compatible dimensions to be multiplied, and that C is the correct size to receive the product, and that they are all defined over the same ring. - Uses strassen multiplication at high levels and then uses - MatrixWindow methods at low levels. EXAMPLES: The following matrix + Uses Strassen multiplication at high levels and then uses + MatrixWindow methods at low levels. + + EXAMPLES: The following matrix dimensions are chosen especially to exercise the eight possible parity combinations that could occur while subdividing the matrix - in the strassen recursion. The base case in both cases will be a + in the Strassen recursion. The base case in both cases will be a (4x5) matrix times a (5x6) matrix. :: @@ -96,9 +98,9 @@ cdef strassen_window_multiply_c(MatrixWindow C, MatrixWindow A, # "Memory efficient scheduling of Strassen-Winograd's matrix multiplication algorithm", # Table 1). - cdef MatrixWindow S0, S1, S2, S3, T0, T1 ,T2, T3, P0, P1, P2, P3, P4, P5, P6, U0, U1, U2, U3, U4, U5, U6 + cdef MatrixWindow S0, S1, S2, S3, T0, T1, T2, T3, P0, P1, P2, P3, P4, P5, P6, U0, U1, U2, U3, U4, U5, U6 cdef MatrixWindow X, Y - X = A.new_empty_window(A_sub_nrows, max(A_sub_ncols,B_sub_ncols)) + X = A.new_empty_window(A_sub_nrows, max(A_sub_ncols, B_sub_ncols)) Y = B.new_empty_window(A_sub_ncols, B_sub_ncols) # 1 S2 = A00-A10 in X @@ -110,7 +112,7 @@ cdef strassen_window_multiply_c(MatrixWindow C, MatrixWindow A, T2.set_to_diff(B11, B01) # 3 P6 = S2*T2 in C10 - P6 = C.matrix_window(A_sub_nrows, 0, A_sub_nrows, B_sub_ncols) + P6 = C.matrix_window(A_sub_nrows, 0, A_sub_nrows, B_sub_ncols) if have_cutoff: P6.set_to_prod(S2, T2) else: @@ -248,17 +250,19 @@ cdef subtract_strassen_product(MatrixWindow result, MatrixWindow A, MatrixWindow def strassen_echelon(MatrixWindow A, cutoff): """ Compute echelon form, in place. Internal function, call with - M.echelonize(algorithm="strassen") Based on work of Robert Bradshaw + M.echelonize(algorithm='strassen') + + Based on work of Robert Bradshaw and David Harvey at MSRI workshop in 2006. INPUT: - - ``A`` -- matrix window + - ``A`` -- matrix window - - ``cutoff`` -- size at which algorithm reverts to - naive Gaussian elimination and multiplication must be at least 1. + - ``cutoff`` -- size at which algorithm reverts to + naive Gaussian elimination and multiplication must be at least 1 - OUTPUT: The list of pivot columns + OUTPUT: the list of pivot columns EXAMPLES:: @@ -324,13 +328,13 @@ cdef strassen_echelon_c(MatrixWindow A, Py_ssize_t cutoff, Py_ssize_t mul_cutoff nrows = A.nrows() ncols = A.ncols() - if (nrows <= cutoff or ncols <= cutoff): + if nrows <= cutoff or ncols <= cutoff: return list(A.echelon_in_place()) cdef Py_ssize_t top_h, bottom_cut, bottom_h, bottom_start, top_cut cdef Py_ssize_t prev_pivot_count cdef Py_ssize_t split - split = nrows / 2 + split = nrows // 2 cdef MatrixWindow top, bottom, top_left, top_right, bottom_left, bottom_right, clear @@ -414,7 +418,7 @@ cdef strassen_echelon_c(MatrixWindow A, Py_ssize_t cutoff, Py_ssize_t mul_cutoff # let [ 0 I F ] = [ 0 I F ] top_cut = max(max(bottom_pivots) + 1, bottom_cut) - # Note: left with respect to leftmost non-zero column of bottom + # Note: left with respect to leftmost nonzero column of bottom top_left = top.matrix_window(0, bottom_start, top_h, top_cut - bottom_start) if bottom_h + top_h < ncols: @@ -485,15 +489,15 @@ class int_range: Repetitions are not considered. - Useful class for dealing with pivots in the strassen echelon, could + Useful class for dealing with pivots in the Strassen echelon, could have much more general application INPUT: It can be one of the following: - - ``indices`` -- integer, start of the unique interval - - ``range`` -- integer, length of the unique interval + - ``indices`` -- integer; start of the unique interval + - ``range`` -- integer; length of the unique interval OR @@ -501,7 +505,7 @@ class int_range: OR - - ``indices`` -- None (default), shortcut for an empty list + - ``indices`` -- ``None`` (default), shortcut for an empty list OUTPUT: @@ -555,7 +559,7 @@ class int_range: if indices is None: self._intervals = [] return - elif range is not None: + if range is not None: self._intervals = [(int(indices), int(range))] else: self._intervals = [] @@ -591,9 +595,7 @@ class int_range: r""" Return the list of intervals. - OUTPUT: - - A list of pairs of integers. + OUTPUT: list of pairs of integers EXAMPLES:: @@ -610,9 +612,7 @@ class int_range: r""" Return the (sorted) list of integers represented by this object. - OUTPUT: - - A list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -633,19 +633,14 @@ class int_range: sage: I.to_list() [1, 2, 3] """ - all = [] - for iv in self._intervals: - for i in range(iv[0], iv[0]+iv[1]): - all.append(i) - return all + return [i for iv0, iv1 in self._intervals + for i in range(iv0, iv0 + iv1)] def __iter__(self): r""" Return an iterator over the intervals. - OUTPUT: - - iterator + OUTPUT: iterator EXAMPLES:: @@ -667,9 +662,7 @@ class int_range: r""" Return the number of integers represented by this object. - OUTPUT: - - Python integer + OUTPUT: Python integer EXAMPLES:: @@ -684,10 +677,7 @@ class int_range: sage: len(I) 3 """ - len = 0 - for iv in self._intervals: - len = len + iv[1] - return int(len) + return sum(iv1 for _, iv1 in self._intervals) def __add__(self, right): r""" @@ -697,9 +687,7 @@ class int_range: - ``right`` -- an instance of ``int_range`` - OUTPUT: - - An instance of ``int_range`` + OUTPUT: an instance of ``int_range`` .. NOTE:: @@ -715,9 +703,9 @@ class int_range: sage: I + J [(1, 6), (20, 4)] """ - all = self.to_list() - all.extend(right.to_list()) - return int_range(all) + full_list = self.to_list() + full_list.extend(right.to_list()) + return int_range(full_list) def __sub__(self, right): r""" @@ -725,11 +713,9 @@ class int_range: INPUT: - - ``right`` -- an instance of ``int_range``. - - OUTPUT: + - ``right`` -- an instance of ``int_range`` - An instance of ``int_range``. + OUTPUT: an instance of ``int_range`` .. NOTE:: @@ -745,11 +731,9 @@ class int_range: sage: J - I [(6, 1), (20, 4)] """ - all = self.to_list() - for i in right.to_list(): - if i in all: - all.remove(i) - return int_range(all) + right_list = set(right.to_list()) + diff = [i for i in self.to_list() if i not in right_list] + return int_range(diff) def __mul__(self, right): r""" @@ -757,11 +741,9 @@ class int_range: INPUT: - - ``right`` -- an instance of ``int_range``. - - OUTPUT: + - ``right`` -- an instance of ``int_range`` - An instance of ``int_range``. + OUTPUT: an instance of ``int_range`` EXAMPLES:: @@ -771,23 +753,22 @@ class int_range: sage: J * I [(4, 2)] """ - intersection = [] - all = self.to_list() - for i in right.to_list(): - if i in all: - intersection.append(i) + self_list = set(self.to_list()) + intersection = [i for i in right.to_list() if i in self_list] return int_range(intersection) # Useful test code: def test(n, m, R, c=2): r""" + Test code for the Strassen algorithm. + INPUT: - ``n`` -- integer - ``m`` -- integer - ``R`` -- ring - - ``c`` -- integer (default:2) + - ``c`` -- integer (default: 2) EXAMPLES:: @@ -813,56 +794,57 @@ def test(n, m, R, c=2): # below aren't callable now without using Pyrex. -## todo: doc cutoff parameter as soon as I work out what it really means +# todo: doc cutoff parameter as soon as I work out what it really means + +# EXAMPLES: -## EXAMPLES: -## The following matrix dimensions are chosen especially to exercise the -## eight possible parity combinations that could occur while subdividing -## the matrix in the strassen recursion. The base case in both cases will -## be a (4x5) matrix times a (5x6) matrix. +# The following matrix dimensions are chosen especially to exercise the +# eight possible parity combinations that could occur while subdividing +# the matrix in the strassen recursion. The base case in both cases will +# be a (4x5) matrix times a (5x6) matrix. -## TODO -- the doctests below are currently not -## tested/enabled/working -- enable them when linear algebra -## restructing gets going. +# TODO -- the doctests below are currently not +# tested/enabled/working -- enable them when linear algebra +# restructing gets going. -## sage: dim1 = 64; dim2 = 83; dim3 = 101 -## sage: R = MatrixSpace(QQ, dim1, dim2) -## sage: S = MatrixSpace(QQ, dim2, dim3) -## sage: T = MatrixSpace(QQ, dim1, dim3) +# sage: dim1 = 64; dim2 = 83; dim3 = 101 +# sage: R = MatrixSpace(QQ, dim1, dim2) +# sage: S = MatrixSpace(QQ, dim2, dim3) +# sage: T = MatrixSpace(QQ, dim1, dim3) -## sage: A = R.random_element(range(-30, 30)) -## sage: B = S.random_element(range(-30, 30)) -## sage: C = T(0) -## sage: D = T(0) +# sage: A = R.random_element(range(-30, 30)) +# sage: B = S.random_element(range(-30, 30)) +# sage: C = T(0) +# sage: D = T(0) -## sage: A_window = A.matrix_window(0, 0, dim1, dim2) -## sage: B_window = B.matrix_window(0, 0, dim2, dim3) -## sage: C_window = C.matrix_window(0, 0, dim1, dim3) -## sage: D_window = D.matrix_window(0, 0, dim1, dim3) +# sage: A_window = A.matrix_window(0, 0, dim1, dim2) +# sage: B_window = B.matrix_window(0, 0, dim2, dim3) +# sage: C_window = C.matrix_window(0, 0, dim1, dim3) +# sage: D_window = D.matrix_window(0, 0, dim1, dim3) -## sage: from sage.matrix.strassen import strassen_window_multiply -## sage: strassen_window_multiply(C_window, A_window, B_window, 2) # use strassen method -## sage: D_window.set_to_prod(A_window, B_window) # use naive method -## sage: C_window == D_window -## True +# sage: from sage.matrix.strassen import strassen_window_multiply +# sage: strassen_window_multiply(C_window, A_window, B_window, 2) # use strassen method +# sage: D_window.set_to_prod(A_window, B_window) # use naive method +# sage: C_window == D_window +# True -## sage: dim1 = 79; dim2 = 83; dim3 = 101 -## sage: R = MatrixSpace(QQ, dim1, dim2) -## sage: S = MatrixSpace(QQ, dim2, dim3) -## sage: T = MatrixSpace(QQ, dim1, dim3) +# sage: dim1 = 79; dim2 = 83; dim3 = 101 +# sage: R = MatrixSpace(QQ, dim1, dim2) +# sage: S = MatrixSpace(QQ, dim2, dim3) +# sage: T = MatrixSpace(QQ, dim1, dim3) -## sage: A = R.random_element(range(30)) -## sage: B = S.random_element(range(30)) -## sage: C = T(0) -## sage: D = T(0) +# sage: A = R.random_element(range(30)) +# sage: B = S.random_element(range(30)) +# sage: C = T(0) +# sage: D = T(0) -## sage: A_window = A.matrix_window(0, 0, dim1, dim2) -## sage: B_window = B.matrix_window(0, 0, dim2, dim3) -## sage: C_window = C.matrix_window(0, 0, dim1, dim3) +# sage: A_window = A.matrix_window(0, 0, dim1, dim2) +# sage: B_window = B.matrix_window(0, 0, dim2, dim3) +# sage: C_window = C.matrix_window(0, 0, dim1, dim3) -## sage: strassen_window_multiply(C, A, B, 2) # use strassen method -## sage: D.set_to_prod(A, B) # use naive method +# sage: strassen_window_multiply(C, A, B, 2) # use strassen method +# sage: D.set_to_prod(A, B) # use naive method -## sage: C == D -## True +# sage: C == D +# True diff --git a/src/sage/matrix/symplectic_basis.py b/src/sage/matrix/symplectic_basis.py index db38f5f3611..47dc053a9ce 100644 --- a/src/sage/matrix/symplectic_basis.py +++ b/src/sage/matrix/symplectic_basis.py @@ -16,7 +16,7 @@ * `f_i M {f_j}^t = 0` for all `i, j`; * `e_i M {f_j}^t = 0` for all `i` not equal `j`; -and such that the non-zero terms +and such that the nonzero terms * `e_i M {f_i}^t` are "as nice as possible": 1 over fields, or integers satisfying divisibility properties otherwise. @@ -292,7 +292,7 @@ def symplectic_basis_over_field(M): fs = [] pivot = 0 while pivot < n: - # find non-zero element in row + # find nonzero element in row found_i = None for i in range(pivot, n): if E[pivot, i] != 0: @@ -312,7 +312,7 @@ def symplectic_basis_over_field(M): E.rescale_col(pivot, v) B.rescale_row(pivot, v) - # use non-zero element to clean row pivot + # use nonzero element to clean row pivot for i in range(pivot+2, n): v = - E[i, pivot] / E[pivot+1, pivot] if v != 0: @@ -320,7 +320,7 @@ def symplectic_basis_over_field(M): E.add_multiple_of_column(i, pivot+1, v) B.add_multiple_of_row(i, pivot+1, v) - # use non-zero element to clean row pivot+1 + # use nonzero element to clean row pivot+1 for i in range(pivot+2, n): v = - E[i, pivot+1] / E[pivot, pivot+1] if v != 0: @@ -506,7 +506,7 @@ def symplectic_basis_over_ZZ(M): continue _inplace_move_to_positive_pivot(E, found[0], found[1], B, pivot) - # use non-zero element to clean row pivot + # use nonzero element to clean row pivot all_zero = True u = E[pivot+1, pivot] for i in range(pivot+2, n): @@ -517,7 +517,7 @@ def symplectic_basis_over_ZZ(M): E.add_multiple_of_column(i, pivot+1, v) B.add_multiple_of_row(i, pivot+1, v) - # use non-zero element to clean row pivot+1 + # use nonzero element to clean row pivot+1 u = E[pivot, pivot+1] for i in range(pivot+2, n): v, r = (-E[i, pivot+1]).quo_rem(u) @@ -533,8 +533,8 @@ def symplectic_basis_over_ZZ(M): pivot += 2 ps.sort() - es = [ p[1] for p in ps ] - fs = [ p[1]+1 for p in ps ] + es = [p[1] for p in ps] + fs = [p[1] + 1 for p in ps] C = B.matrix_from_rows(es + fs + zeroes) F = C * M * C.transpose() return F, C diff --git a/src/sage/matroids/basis_exchange_matroid.pxd b/src/sage/matroids/basis_exchange_matroid.pxd index dc4b4aeb114..fdcfd82172f 100644 --- a/src/sage/matroids/basis_exchange_matroid.pxd +++ b/src/sage/matroids/basis_exchange_matroid.pxd @@ -46,19 +46,19 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _move_current_basis(self, X, Y) cpdef frozenset _max_independent(self, frozenset F) - cpdef int _rank(self, frozenset F) + cpdef int _rank(self, frozenset F) except? -1 cpdef frozenset _circuit(self, frozenset F) cpdef frozenset _fundamental_circuit(self, frozenset B, e) cpdef frozenset _closure(self, frozenset F) cpdef frozenset _max_coindependent(self, frozenset F) - cpdef int _corank(self, frozenset F) + cpdef int _corank(self, frozenset F) noexcept cpdef frozenset _cocircuit(self, frozenset F) cpdef frozenset _fundamental_cocircuit(self, frozenset B, e) cpdef frozenset _coclosure(self, frozenset F) cpdef frozenset _augment(self, frozenset X, frozenset Y) - cpdef bint _is_independent(self, frozenset F) + cpdef bint _is_independent(self, frozenset F) noexcept cpdef list whitney_numbers2(self) cdef _whitney_numbers2_rec(self, object f_vec, bitset_t* flats, bitset_t* todo, long elt, long rnk) @@ -90,6 +90,6 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _is_isomorphism(self, other, morphism) cdef bint __is_isomorphism(self, BasisExchangeMatroid other, morphism) noexcept - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef bint nxksrd(bitset_s *b, long n, long k, bint succ) noexcept diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 2e57bb00fdc..8d0dbf1c834 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -146,7 +146,7 @@ cdef class BasisExchangeMatroid(Matroid): sage: from sage.matroids.advanced import * sage: M = BasisExchangeMatroid(groundset=[1, 2, 3], rank=2) - sage: TestSuite(M).run(skip="_test_pickling") + sage: TestSuite(M).run(skip='_test_pickling') .. NOTE:: @@ -199,7 +199,7 @@ cdef class BasisExchangeMatroid(Matroid): - ``mapping`` -- a Python object such that ``mapping[e]`` is the new label of `e` - OUTPUT: ``None`` + OUTPUT: none .. NOTE:: @@ -652,7 +652,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__max_independent(self._output, self._input) return self.__unpack(self._output) - cpdef int _rank(self, frozenset F): + cpdef int _rank(self, frozenset F) except? -1: """ Compute the rank of a subset of the groundset. @@ -796,7 +796,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__max_coindependent(self._output, self._input) return self.__unpack(self._output) - cpdef int _corank(self, frozenset F): + cpdef int _corank(self, frozenset F) noexcept: """ Return the corank of a set. @@ -805,7 +805,7 @@ cdef class BasisExchangeMatroid(Matroid): - ``F`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - OUTPUT: integer; the corank of ``F`` + OUTPUT: integer; the corank of `F` EXAMPLES:: @@ -940,7 +940,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__augment(self._output, self._input, self._input2) return self.__unpack(self._output) - cpdef bint _is_independent(self, frozenset F): + cpdef bint _is_independent(self, frozenset F) noexcept: """ Test if input is independent. @@ -1503,6 +1503,8 @@ cdef class BasisExchangeMatroid(Matroid): - ``k`` -- integer (optional); if specified, return the size-`k` independent sets of the matroid + OUTPUT: :class:`SetSystem` + EXAMPLES:: sage: M = matroids.catalog.Fano() @@ -2001,7 +2003,7 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - ``other`` -- matroid - - ``morphism`` -- a dictionary mapping the groundset of ``self`` to + - ``morphism`` -- dictionary mapping the groundset of ``self`` to the groundset of ``other`` OUTPUT: boolean @@ -2229,7 +2231,7 @@ cdef class BasisExchangeMatroid(Matroid): return self._characteristic_setsystem()._isomorphism(other._characteristic_setsystem(), PS, PO) is not None - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. diff --git a/src/sage/matroids/basis_matroid.pxd b/src/sage/matroids/basis_matroid.pxd index 5789ad98937..fd240b01a38 100644 --- a/src/sage/matroids/basis_matroid.pxd +++ b/src/sage/matroids/basis_matroid.pxd @@ -15,7 +15,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): cdef reset_current_basis(self) - cpdef bint _is_basis(self, frozenset X) + cpdef bint _is_basis(self, frozenset X) noexcept cpdef bases_count(self) cpdef SetSystem bases(self) diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index 5ae38178df6..b74a76af956 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -133,7 +133,6 @@ cdef class BasisMatroid(BasisExchangeMatroid): 2 sage: M1.is_valid() False - """ def __init__(self, M=None, groundset=None, bases=None, nonbases=None, rank=None): """ @@ -299,7 +298,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): # a function that is very efficient for this class - cpdef bint _is_basis(self, frozenset X): + cpdef bint _is_basis(self, frozenset X) noexcept: """ Test if input is a basis. @@ -845,7 +844,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- BasisMatroid + - ``other`` -- basisMatroid - ``morphism`` -- dictionary with sends each element of the groundset of this matroid to a distinct element of the groundset of ``other`` diff --git a/src/sage/matroids/circuit_closures_matroid.pxd b/src/sage/matroids/circuit_closures_matroid.pxd index 878443d86f3..b724a49faf4 100644 --- a/src/sage/matroids/circuit_closures_matroid.pxd +++ b/src/sage/matroids/circuit_closures_matroid.pxd @@ -5,9 +5,9 @@ cdef class CircuitClosuresMatroid(Matroid): cdef dict _circuit_closures # _CC cdef int _matroid_rank # _R cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 cpdef full_rank(self) - cpdef bint _is_independent(self, frozenset F) + cpdef bint _is_independent(self, frozenset F) noexcept cpdef frozenset _max_independent(self, frozenset F) cpdef frozenset _circuit(self, frozenset F) cpdef dict circuit_closures(self) diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 4d45022484b..a4251298ebc 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -90,7 +90,7 @@ cdef class CircuitClosuresMatroid(Matroid): - ``M`` -- matroid (default: ``None``) - ``groundset`` -- groundset of a matroid (default: ``None``) - - ``circuit_closures`` -- dict (default: ``None``); the collection of + - ``circuit_closures`` -- dictionary (default: ``None``); the collection of circuit closures of a matroid presented as a dictionary whose keys are ranks, and whose values are sets of circuit closures of the specified rank @@ -179,7 +179,7 @@ cdef class CircuitClosuresMatroid(Matroid): """ return frozenset(self._groundset) - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: """ Return the rank of a set ``X``. @@ -221,7 +221,7 @@ cdef class CircuitClosuresMatroid(Matroid): """ return self._matroid_rank - cpdef bint _is_independent(self, frozenset F): + cpdef bint _is_independent(self, frozenset F) noexcept: """ Test if input is independent. diff --git a/src/sage/matroids/circuits_matroid.pxd b/src/sage/matroids/circuits_matroid.pxd index f7b938a4d6f..a3bffafce6d 100644 --- a/src/sage/matroids/circuits_matroid.pxd +++ b/src/sage/matroids/circuits_matroid.pxd @@ -9,9 +9,9 @@ cdef class CircuitsMatroid(Matroid): cdef list _sorted_C_lens cdef bint _nsc_defined cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 cpdef full_rank(self) - cpdef bint _is_independent(self, frozenset X) + cpdef bint _is_independent(self, frozenset X) noexcept cpdef frozenset _max_independent(self, frozenset X) cpdef frozenset _circuit(self, frozenset X) cpdef frozenset _closure(self, frozenset X) @@ -27,11 +27,11 @@ cdef class CircuitsMatroid(Matroid): # properties cpdef girth(self) - cpdef bint is_paving(self) + cpdef bint is_paving(self) noexcept # isomorphism and relabeling cpdef _is_isomorphic(self, other, certificate=*) cpdef relabel(self, mapping) # verification - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept diff --git a/src/sage/matroids/circuits_matroid.pyx b/src/sage/matroids/circuits_matroid.pyx index ae3be51d36f..3b3693b52f6 100644 --- a/src/sage/matroids/circuits_matroid.pyx +++ b/src/sage/matroids/circuits_matroid.pyx @@ -100,7 +100,7 @@ cdef class CircuitsMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: """ Return the rank of a set ``X``. @@ -140,7 +140,7 @@ cdef class CircuitsMatroid(Matroid): """ return self._matroid_rank - cpdef bint _is_independent(self, frozenset X): + cpdef bint _is_independent(self, frozenset X) noexcept: """ Test if input is independent. @@ -850,7 +850,7 @@ cdef class CircuitsMatroid(Matroid): from sage.rings.infinity import infinity return min(self._k_C, default=infinity) - cpdef bint is_paving(self): + cpdef bint is_paving(self) noexcept: """ Return if ``self`` is paving. @@ -869,7 +869,7 @@ cdef class CircuitsMatroid(Matroid): # verification - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if ``self`` obeys the matroid axioms. diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 38541523caa..a71674e2987 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -166,44 +166,43 @@ def Matroid(groundset=None, data=None, **kwds): INPUT: - - ``groundset`` -- (optional) If provided, the groundset of the - matroid. Otherwise, the function attempts to determine a groundset - from the data. + - ``groundset`` -- (optional) the groundset of the matroid; if not + provided, the function attempts to determine a groundset from the data Exactly one of the following inputs must be given (where ``data`` must be a positional argument and anything else must be a keyword argument): - ``data`` -- a graph or a matrix or a RevLex-Index string or a list - of independent sets containing all bases or a matroid. - - ``bases`` -- The list of bases (maximal independent sets) of the - matroid. - - ``independent_sets`` -- The list of independent sets of the matroid. - - ``circuits`` -- The list of circuits of the matroid. - - ``nonspanning_circuits`` -- The list of nonspanning circuits of the - matroid. - - ``flats`` -- The dictionary, list, or lattice of flats of the matroid. - - ``graph`` -- A graph, whose edges form the elements of the matroid. - - ``matrix`` -- A matrix representation of the matroid. - - ``reduced_matrix`` -- A reduced representation of the matroid: if + of independent sets containing all bases or a matroid + - ``bases`` -- the list of bases (maximal independent sets) of the + matroid + - ``independent_sets`` -- the list of independent sets of the matroid + - ``circuits`` -- the list of circuits of the matroid + - ``nonspanning_circuits`` -- the list of nonspanning circuits of the + matroid + - ``flats`` -- the dictionary, list, or lattice of flats of the matroid + - ``graph`` -- a graph, whose edges form the elements of the matroid + - ``matrix`` -- a matrix representation of the matroid + - ``reduced_matrix`` -- a reduced representation of the matroid: if ``reduced_matrix = A`` then the matroid is represented by `[I\ \ A]` where `I` is an - appropriately sized identity matrix. - - ``morphism`` -- A morphism representation of the matroid. - - ``reduced_morphism`` -- A reduced morphism representation of the matroid. - - ``rank_function`` -- A function that computes the rank of each subset. - Can only be provided together with a groundset. - - ``circuit_closures`` -- Either a list of tuples ``(k, C)`` with ``C`` + appropriately sized identity matrix + - ``morphism`` -- a morphism representation of the matroid + - ``reduced_morphism`` -- a reduced morphism representation of the matroid + - ``rank_function`` -- a function that computes the rank of each subset; + can only be provided together with a groundset + - ``circuit_closures`` -- either a list of tuples ``(k, C)`` with ``C`` the closure of a circuit, and ``k`` the rank of ``C``, or a dictionary - ``D`` with ``D[k]`` the set of closures of rank-``k`` circuits. - - ``revlex`` -- the encoding as a string of ``0`` and ``*`` symbols. - Used by [Mat2012]_ and explained in [MMIB2012]_. - - ``matroid`` -- An object that is already a matroid. Useful only with the - ``regular`` option. + ``D`` with ``D[k]`` the set of closures of rank-``k`` circuits + - ``revlex`` -- the encoding as a string of ``0`` and ``*`` symbols; + used by [Mat2012]_ and explained in [MMIB2012]_ + - ``matroid`` -- an object that is already a matroid; useful only with the + ``regular`` option Further options: - - ``regular`` -- (default: ``False``) boolean. If ``True``, + - ``regular`` -- boolean (default: ``False``); if ``True``, output a :class:`RegularMatroid ` instance such that, *if* the input defines a valid regular matroid, then @@ -212,10 +211,10 @@ def Matroid(groundset=None, data=None, **kwds): - ``ring`` -- any ring. If provided, and the input is a ``matrix`` or ``reduced_matrix``, output will be a linear matroid over the ring or field ``ring``. - - ``field`` -- any field. Same as ``ring``, but only fields are allowed. - - ``check`` -- (default: ``True``) boolean. If ``True`` and - ``regular`` is true, the output is checked to make sure it is a valid - regular matroid. + - ``field`` -- any field. Same as ``ring``, but only fields are allowed + - ``check`` -- boolean (default: ``True``); if ``True`` and + ``regular`` is ``True``, the output is checked to make sure it is a valid + regular matroid .. WARNING:: @@ -658,7 +657,7 @@ def Matroid(groundset=None, data=None, **kwds): Only the ``0`` symbols really matter, any symbol can be used instead of ``*``: - sage: Matroid("abcdefg", revlex="0++++++++0++++0+++++0+--++----+--++", rank=4) + sage: Matroid("abcdefg", revlex='0++++++++0++++0+++++0+--++----+--++', rank=4) Matroid of rank 4 on 7 elements with 31 bases It is checked that the input makes sense (but not that it @@ -742,7 +741,7 @@ def Matroid(groundset=None, data=None, **kwds): Traceback (most recent call last): ... TypeError: no input data given for Matroid() - sage: Matroid("abc", bases=["abc"], foo="bar") + sage: Matroid("abc", bases=["abc"], foo='bar') Traceback (most recent call last): ... TypeError: ...Matroid() got an unexpected keyword argument 'foo' @@ -762,7 +761,7 @@ def Matroid(groundset=None, data=None, **kwds): Traceback (most recent call last): ... TypeError: for rank functions, the groundset needs to be specified - sage: Matroid(matroid="rubbish") + sage: Matroid(matroid='rubbish') Traceback (most recent call last): ... TypeError: input 'rubbish' is not a matroid diff --git a/src/sage/matroids/database_collections.py b/src/sage/matroids/database_collections.py index 81b99a24d87..b5175e0b3d7 100644 --- a/src/sage/matroids/database_collections.py +++ b/src/sage/matroids/database_collections.py @@ -22,27 +22,25 @@ # **************************************************************************** -def AllMatroids(n, r=None, type="all"): +def AllMatroids(n, r=None, type='all'): r""" - Return an iterator over all matroids of certain number of elements (and, - optionally, of specific rank and type). + Iterate over all matroids of certain number of elements (and, optionally, + of specific rank and type). INPUT: - ``n`` -- integer; the number of elements of the matroids - - ``r`` -- integer (optional); the rank of the matroids; `0 \le r \le n` - - ``type`` -- string (default: ``'all'``); the type of the matroids; must + - ``r`` -- integer (optional); the rank of the matroids (`0 \le r \le n`) + - ``type`` -- string (default: ``'all'``); the type of the matroids. Must be one of the following: * ``'all'`` -- all matroids; available: (n=0-9), (n=0-12, r=0-2), (n=0-11, r=3) - * ``'unorientable'`` -- all unorientable matroids; the rank ``r`` must be + * ``'unorientable'`` -- all unorientable matroids; the rank `r` must be specified; available: (n=7-11, r=3), (n=7-9, r=4) * any other type for which there exists an ``is_type`` method; availability same as for ``'all'`` - OUTPUT: an iterator over matroids - EXAMPLES:: sage: for M in matroids.AllMatroids(2): # optional - matroid_database @@ -54,7 +52,7 @@ def AllMatroids(n, r=None, type="all"): :: - sage: for M in matroids.AllMatroids(5, 3, "simple"): # optional - matroid_database + sage: for M in matroids.AllMatroids(5, 3, 'simple'): # optional - matroid_database ....: M simple_n05_r03_#0: Matroid of rank 3 on 5 elements with 10 bases simple_n05_r03_#1: Matroid of rank 3 on 5 elements with 9 bases @@ -64,7 +62,7 @@ def AllMatroids(n, r=None, type="all"): :: sage: # optional - matroid_database - sage: for M in matroids.AllMatroids(4, type="paving"): + sage: for M in matroids.AllMatroids(4, type='paving'): ....: M paving_n04_r00_#0: Matroid of rank 0 on 4 elements with 1 bases paving_n04_r01_#0: Matroid of rank 1 on 4 elements with 4 bases @@ -86,18 +84,18 @@ def AllMatroids(n, r=None, type="all"): ....: M Traceback (most recent call last): ... - ValueError: (n=10, r=4, type="all") is not available in the database + ValueError: (n=10, r=4, type='all') is not available in the database sage: for M in matroids.AllMatroids(12, 3, "unorientable"): ....: M Traceback (most recent call last): ... - ValueError: (n=12, r=3, type="unorientable") is not available in the database - sage: for M in matroids.AllMatroids(8, type="unorientable"): + ValueError: (n=12, r=3, type='unorientable') is not available in the database + sage: for M in matroids.AllMatroids(8, type='unorientable'): ....: M Traceback (most recent call last): ... ValueError: The rank needs to be specified for type "unorientable" - sage: for M in matroids.AllMatroids(6, type="nice"): + sage: for M in matroids.AllMatroids(6, type='nice'): ....: M Traceback (most recent call last): ... @@ -227,7 +225,7 @@ def AllMatroids(n, r=None, type="all"): def OxleyMatroids(): """ - Return an iterator over Oxley's matroid collection. + Iterate over Oxley's matroid collection. EXAMPLES:: @@ -277,7 +275,7 @@ def OxleyMatroids(): def BrettellMatroids(): """ - Return an iterator over Brettell's matroid collection. + Iterate over Brettell's matroid collection. EXAMPLES:: @@ -326,7 +324,7 @@ def BrettellMatroids(): def VariousMatroids(): """ - Return an iterator over various other named matroids. + Iterate over various other named matroids. EXAMPLES:: diff --git a/src/sage/matroids/database_matroids.py b/src/sage/matroids/database_matroids.py index e964ee4836c..4c5eee2b5c0 100644 --- a/src/sage/matroids/database_matroids.py +++ b/src/sage/matroids/database_matroids.py @@ -1462,7 +1462,7 @@ def K5(groundset='abcdefghij'): Return the graphic matroid `M(K_5)`. `M(K_5)` is an excluded minor for the class of cographic matroids. It is - the `3`-dimensional Desargues configuration. + the `3`-dimensional Desargues configuration. EXAMPLES:: @@ -1776,12 +1776,12 @@ def Wheel(r, field=None, ring=None, groundset=None): INPUT: - - ``r`` -- a positive integer; the rank of the desired matroid + - ``r`` -- positive integer; the rank of the matroid - ``ring`` -- any ring; if provided, output will be a linear matroid over the ring or field ``ring``. If the ring is `\ZZ`, then output will be a regular matroid. - ``field`` -- any field; same as ``ring``, but only fields are allowed - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: the rank-`r` wheel matroid, represented as a regular matroid @@ -1853,8 +1853,8 @@ def Whirl(r, groundset=None): INPUT: - - ``r`` -- a positive integer; the rank of the desired matroid. - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``r`` -- positive integer; the rank of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: the rank-`r` whirl matroid, represented as a ternary matroid @@ -1924,10 +1924,10 @@ def Uniform(r, n, groundset=None): INPUT: - - ``r`` -- a nonnegative integer; the rank of the uniform matroid - - ``n`` -- a nonnegative integer; the number of elements of the uniform + - ``r`` -- nonnegative integer; the rank of the uniform matroid + - ``n`` -- nonnegative integer; the number of elements of the uniform matroid - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: the uniform matroid `U_{r,n}` @@ -1968,19 +1968,19 @@ def Uniform(r, n, groundset=None): def PG(n, q, x=None, groundset=None): """ - Return the projective geometry of dimension ``n`` over the finite field - of order ``q``. + Return the projective geometry of dimension `n` over the finite field + of order `q`. INPUT: - - ``n`` -- a positive integer; the dimension of the projective space. This + - ``n`` -- positive integer; the dimension of the projective space. This is one less than the rank of the resulting matroid. - - ``q`` -- a positive integer that is a prime power; the order of the + - ``q`` -- positive integer that is a prime power; the order of the finite field - - ``x`` -- a string (default: ``None``); the name of the generator of a + - ``x`` -- string (default: ``None``); the name of the generator of a non-prime field, used for non-prime fields. If not supplied, ``'x'`` is used. - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: a linear matroid whose elements are the points of `PG(n, q)` @@ -2019,14 +2019,14 @@ def AG(n, q, x=None, groundset=None): INPUT: - - ``n`` -- a positive integer; the dimension of the projective space. This + - ``n`` -- positive integer; the dimension of the projective space. This is one less than the rank of the resulting matroid. - - ``q`` -- a positive integer that is a prime power; the order of the + - ``q`` -- positive integer that is a prime power; the order of the finite field - - ``x`` -- a string (default: ``None``); the name of the generator of a + - ``x`` -- string (default: ``None``); the name of the generator of a non-prime field, used for non-prime fields. If not supplied, ``'x'`` is used. - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: a linear matroid whose elements are the points of `AG(n, q)` @@ -2064,9 +2064,9 @@ def Z(r, t=True, groundset=None): INPUT: - - ``r`` -- an integer (`r \ge 3`); the rank of the spike + - ``r`` -- integer (`r \ge 3`); the rank of the spike - ``t`` -- boolean (default: ``True``); whether the spike is tipped - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: matroid; the unique rank-`r` binary spike (tipped or tipless) @@ -2168,11 +2168,11 @@ def Spike(r, t=True, C3=[], groundset=None): INPUT: - - ``r`` -- an integer (`r \ge 3`); the rank of the spike + - ``r`` -- integer (`r \ge 3`); the rank of the spike - ``t`` -- boolean (default: ``True``); whether the spike is tipped - - ``C3`` -- a list (default: ``[]``); a list of extra nonspanning circuits. - The default (i.e. the empty list) results in a free `r`-spike - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``C3`` -- list (default: ``[]``); a list of extra nonspanning circuits. + The default (i.e. the empty list) results in a free `r`-spike. + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: matroid; a rank-`r` spike (tipped or tipless) @@ -2289,8 +2289,8 @@ def Theta(n, groundset=None): INPUT: - - ``n`` -- an integer (`n \ge 2`); the rank of the matroid - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``n`` -- integer (`n \ge 2`); the rank of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: matroid (`\Theta_n`) @@ -2362,8 +2362,8 @@ def Psi(r, groundset=None): INPUT: - - ``r`` -- an integer (`r \ge 3`); the rank of the matroid - - ``groundset`` -- a string (optional); the groundset of the matroid + - ``r`` -- integer (`r \ge 3`); the rank of the matroid + - ``groundset`` -- string (optional); the groundset of the matroid OUTPUT: matroid (`\Psi_r`) @@ -3022,7 +3022,7 @@ def KR9(groundset=None): Return the matroid `KR9`. An excluded minor for `G`-representable matroids (and - `GF(5)`-representable matroids.) In a `DY`-equivalence class of `4` + `GF(5)`-representable matroids). In a `DY`-equivalence class of `4` matroids. Has a :func:`KP8 `-minor (delete `8`). UPF is `GF(4)`. @@ -3057,7 +3057,7 @@ def KQ9(groundset=None): Return the matroid `KQ9`. An excluded minor for `G`-representable matroids (and - `GF(5)`-representable matroids.) Has a + `GF(5)`-representable matroids). Has a :func:`TQ8 `-minor` (delete `6`) and a :func:`KP8 `-minor (delete `8`). UPF is `GF(4)`. @@ -4511,7 +4511,7 @@ def VP14(groundset=None): def FV14(groundset=None): """ - Return the matroid `FV14` + Return the matroid `FV14`. An excluded minor for `P_4`-representable matroids. Not self-dual. UPF is `PT`. @@ -5187,10 +5187,10 @@ def CompleteGraphic(n, groundset=None): INPUT: - - ``n`` -- an integer, the number of vertices of the underlying complete - graph. + - ``n`` -- integer; the number of vertices of the underlying complete + graph - OUTPUT: The graphic matroid associated with the `n`-vertex complete graph. + OUTPUT: the graphic matroid associated with the `n`-vertex complete graph. This matroid has rank `n - 1`. EXAMPLES:: @@ -5231,16 +5231,16 @@ def _rename_and_relabel(M, name=None, groundset=None): INPUT: - - ``M`` -- a matroid - - ``name`` -- a string (optional) - - ``groundset`` -- a string (optional) + - ``M`` -- matroid + - ``name`` -- string (optional) + - ``groundset`` -- string (optional) OUTPUT: matroid """ if groundset is not None: if len(groundset) != len(M.groundset()): raise ValueError( - "The groundset should be of size %s (%s given)." % + "the groundset should be of size %s (%s given)" % (len(M.groundset()), len(groundset)) ) M = M.relabel(dict(zip(M.groundset(), groundset))) diff --git a/src/sage/matroids/extension.pyx b/src/sage/matroids/extension.pyx index d73b4581674..778e6d6ef70 100644 --- a/src/sage/matroids/extension.pyx +++ b/src/sage/matroids/extension.pyx @@ -51,11 +51,10 @@ cdef class CutNode: hyperplanes and closing the set to become a linear subclass again, and for adding a hyperplane to the set of *forbidden* hyperplanes, and similarly closing that set. - """ def __cinit__(self, MC, N=None): """ - Internal data structure init + Internal data structure init. EXAMPLES:: @@ -187,7 +186,7 @@ cdef class LinearSubclassesIter: INPUT: - - ``MC`` -- a member of class LinearSubclasses. + - ``MC`` -- a member of class LinearSubclasses EXAMPLES:: @@ -258,17 +257,15 @@ cdef class LinearSubclasses: INPUT: - - ``M`` -- a matroid. - - ``line_length`` -- (default: ``None``) an integer. + - ``M`` -- matroid + - ``line_length`` -- integer (default: ``None``) - ``subsets`` -- (default: ``None``) a set of subsets of the groundset of - ``M``. + ``M`` - ``splice`` -- (default: ``None``) a matroid `N` such that for some `e \in E(N)` and some `f \in E(M)`, we have - `N\setminus e= M\setminus f`. + `N\setminus e= M\setminus f` - OUTPUT: - - An enumerator for the linear subclasses of M. + OUTPUT: an enumerator for the linear subclasses of M If ``line_length`` is not ``None``, the enumeration is restricted to linear subclasses ``mc`` so containing at least one of each set of @@ -416,13 +413,13 @@ cdef class MatroidExtensions(LinearSubclasses): INPUT: - - ``M`` -- a matroid + - ``M`` -- matroid - ``e`` -- an element - - ``line_length`` (default: ``None``) -- an integer - - ``subsets`` (default: ``None``) -- a set of subsets of the groundset of + - ``line_length`` -- integer (default: ``None``) + - ``subsets`` -- (default: ``None``) a set of subsets of the groundset of ``M`` - ``splice`` -- a matroid `N` such that for some `f \in E(M)`, we have - `N\setminus e= M\setminus f`. + `N\setminus e= M\setminus f` OUTPUT: diff --git a/src/sage/matroids/flats_matroid.pxd b/src/sage/matroids/flats_matroid.pxd index 956e30f859d..23fd4ceb1ec 100644 --- a/src/sage/matroids/flats_matroid.pxd +++ b/src/sage/matroids/flats_matroid.pxd @@ -8,9 +8,9 @@ cdef class FlatsMatroid(Matroid): cdef object _L # lattice of flats cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 cpdef frozenset _closure(self, frozenset X) - cpdef bint _is_closed(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) noexcept cpdef full_rank(self) @@ -24,4 +24,4 @@ cdef class FlatsMatroid(Matroid): cpdef relabel(self, mapping) # verification - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept diff --git a/src/sage/matroids/flats_matroid.pyx b/src/sage/matroids/flats_matroid.pyx index dce9d8756fa..6842839e03f 100644 --- a/src/sage/matroids/flats_matroid.pyx +++ b/src/sage/matroids/flats_matroid.pyx @@ -42,7 +42,7 @@ cdef class FlatsMatroid(Matroid): - ``M`` -- matroid (default: ``None``) - ``groundset`` -- list (default: ``None``); the groundset of the matroid - - ``flats`` -- (default: ``None``); the dictionary of the lists of flats + - ``flats`` -- (default: ``None``) the dictionary of the lists of flats (indexed by their rank), or the list of all flats, or the lattice of flats of the matroid @@ -114,7 +114,7 @@ cdef class FlatsMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: """ Return the rank of a set ``X``. @@ -191,7 +191,7 @@ cdef class FlatsMatroid(Matroid): if f >= X: return f - cpdef bint _is_closed(self, frozenset X): + cpdef bint _is_closed(self, frozenset X) noexcept: """ Test if input is a closed set. @@ -226,7 +226,6 @@ cdef class FlatsMatroid(Matroid): - ``other`` -- matroid - ``certificate`` -- boolean (default: ``False``) - OUTPUT: boolean, and, if ``certificate=True``, a dictionary giving the isomorphism or ``None`` @@ -540,7 +539,7 @@ cdef class FlatsMatroid(Matroid): # verification - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if ``self`` obeys the matroid axioms. @@ -580,7 +579,7 @@ cdef class FlatsMatroid(Matroid): True sage: Matroid(flats=['', 'a', 'b', 'ab']).is_valid() True - sage: M = Matroid(flats=['', # missing an extention of flat ['5'] by '6' + sage: M = Matroid(flats=['', # missing an extension of flat ['5'] by '6' ....: '0','1','2','3','4','5','6','7','8','9','a','b','c', ....: '45','46','47','4c','57','5c','67','6c','7c', ....: '048','149','24a','34b','059','15a','25b','358', @@ -620,7 +619,7 @@ cdef class FlatsMatroid(Matroid): False sage: Matroid(flats={0: [[]], 1: [[0, 1], [2]], 2: [[0], [1], [0, 1, 2]]}).is_valid() False - sage: M = Matroid(flats={0: [''], # missing an extention of flat ['5'] by '6' + sage: M = Matroid(flats={0: [''], # missing an extension of flat ['5'] by '6' ....: 1: ['0','1','2','3','4','5','6','7','8','9','a','b','c'], ....: 2: ['45','46','47','4c','57','5c','67','6c','7c', ....: '048','149','24a','34b','059','15a','25b','358', diff --git a/src/sage/matroids/graphic_matroid.pxd b/src/sage/matroids/graphic_matroid.pxd index 8ec8dd9e8b0..3684ab19f0d 100644 --- a/src/sage/matroids/graphic_matroid.pxd +++ b/src/sage/matroids/graphic_matroid.pxd @@ -7,23 +7,23 @@ cdef class GraphicMatroid(Matroid): cdef dict _vertex_map cdef dict _groundset_edge_map cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 cpdef _vertex_stars(self) cpdef _minor(self, contractions, deletions) cpdef _has_minor(self, N, bint certificate=*) - cpdef int _corank(self, frozenset X) - cpdef bint _is_circuit(self, frozenset X) + cpdef int _corank(self, frozenset X) noexcept + cpdef bint _is_circuit(self, frozenset X) noexcept cpdef frozenset _closure(self, frozenset X) cpdef frozenset _max_independent(self, frozenset X) cpdef frozenset _max_coindependent(self, frozenset X) cpdef frozenset _circuit(self, frozenset X) cpdef frozenset _coclosure(self, frozenset X) - cpdef bint _is_closed(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) noexcept cpdef _is_isomorphic(self, other, certificate=*) cpdef _isomorphism(self, other) - cpdef bint is_valid(self) - cpdef bint is_graphic(self) - cpdef bint is_regular(self) + cpdef bint is_valid(self) noexcept + cpdef bint is_graphic(self) noexcept + cpdef bint is_regular(self) noexcept cpdef graph(self) cpdef vertex_map(self) cpdef list groundset_to_edges(self, X) diff --git a/src/sage/matroids/graphic_matroid.pyx b/src/sage/matroids/graphic_matroid.pyx index 2f6287fba8d..5e740e78637 100644 --- a/src/sage/matroids/graphic_matroid.pyx +++ b/src/sage/matroids/graphic_matroid.pyx @@ -186,7 +186,7 @@ cdef class GraphicMatroid(Matroid): groundset_set = frozenset(groundset) # if the provided groundset is incomplete, it gets overwritten - # invalidate `None` as label + # invalidate ``None`` as label if None in groundset_set or len(groundset_set) != G.num_edges(): groundset = range(G.num_edges()) groundset_set = frozenset(groundset) @@ -238,7 +238,7 @@ cdef class GraphicMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: """ Return the rank of a set ``X``. @@ -501,8 +501,8 @@ cdef class GraphicMatroid(Matroid): INPUT: - ``N`` -- matroid - - ``certificate`` -- (default: ``False``) if ``True``, returns the - certificate isomorphism from the minor of ``self`` to ``N`` + - ``certificate`` -- boolean (default: ``False``); if ``True``, returns + the certificate isomorphism from the minor of ``self`` to ``N`` OUTPUT: @@ -625,7 +625,7 @@ cdef class GraphicMatroid(Matroid): N = N.regular_matroid() return M._has_minor(N, certificate=certificate) - cpdef int _corank(self, frozenset X): + cpdef int _corank(self, frozenset X) noexcept: """ Return the corank of the set `X` in the matroid. @@ -653,7 +653,7 @@ cdef class GraphicMatroid(Matroid): DS_vertices.union(u, v) return len(X) - (DS_vertices.number_of_subsets() - Integer(1)) - cpdef bint _is_circuit(self, frozenset X): + cpdef bint _is_circuit(self, frozenset X) noexcept: """ Test if input is a circuit. @@ -812,7 +812,7 @@ cdef class GraphicMatroid(Matroid): - ``X`` -- an iterable container of groundset elements OUTPUT: ``frozenset`` instance containing a subset of ``X``; - a :class:`ValueError` is raised if the set contains no circuit + a :exc:`ValueError` is raised if the set contains no circuit EXAMPLES:: @@ -918,7 +918,7 @@ cdef class GraphicMatroid(Matroid): g.add_edge(e) return frozenset(XX) - cpdef bint _is_closed(self, frozenset X): + cpdef bint _is_closed(self, frozenset X) noexcept: """ Test if input is a closed set. @@ -1093,7 +1093,7 @@ cdef class GraphicMatroid(Matroid): """ return self.is_isomorphic(other, certificate=True)[1] - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: """ Test if the data obey the matroid axioms. @@ -1110,7 +1110,7 @@ cdef class GraphicMatroid(Matroid): """ return True - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: r""" Return if ``self`` is graphic. @@ -1124,7 +1124,7 @@ cdef class GraphicMatroid(Matroid): """ return True - cpdef bint is_regular(self): + cpdef bint is_regular(self) noexcept: r""" Return if ``self`` is regular. @@ -1364,8 +1364,8 @@ cdef class GraphicMatroid(Matroid): each extension - ``vertices`` -- (optional) a set of vertices over which the extension may be taken - - ``simple`` -- (default: ``False``) if true, extensions by loops and - parallel elements are not taken + - ``simple`` -- boolean (default: ``False``); if ``True``, extensions + by loops and parallel elements are not taken OUTPUT: @@ -1440,7 +1440,7 @@ cdef class GraphicMatroid(Matroid): - ``v`` -- (optional) the name of the new vertex after splitting - ``X`` -- (optional) a list of the matroid elements corresponding to edges incident to ``u`` that move to the new vertex after splitting - - ``element`` -- (optional) The name of the newly added element + - ``element`` -- (optional) the name of the newly added element OUTPUT: @@ -1573,7 +1573,7 @@ cdef class GraphicMatroid(Matroid): - ``vertices`` -- (optional) the vertices to be split - ``v`` -- (optional) the name of the new vertex - ``element`` -- (optional) the name of the new element - - ``cosimple`` -- (default: ``False``) if true, coextensions + - ``cosimple`` -- boolean (default: ``False``); if ``True``, coextensions by a coloop or series elements will not be taken OUTPUT: diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 5863a58d4eb..f7051f45c92 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -494,13 +494,13 @@ cdef class LeanMatrix: cdef shifting_all(self, P_rows, P_cols, Q_rows, Q_cols, int m): r""" Given a partial matrix `M`. If the submatrix `M` using rows - `P_rows` columns `P_cols` and submatrix using rows `Q_rows` columns - `Q_cols` can be extended to a ``m``-separator, then it returns - `True, E`, where `E` is a ``m``-separator. Otherwise it returns - `False, None` + ``P_rows`` columns ``P_cols`` and submatrix using rows ``Q_rows`` + columns ``Q_cols`` can be extended to an ``m``-separator, then it + returns ``True, E``, where `E` is an ``m``-separator. Otherwise it + returns ``False, None``. - `P_rows` and `Q_rows` must be disjoint subsets of row indices. - `P_cols` and `Q_cols` must be disjoint subsets of column indices. + ``P_rows`` and ``Q_rows`` must be disjoint subsets of row indices. + ``P_cols`` and ``Q_cols`` must be disjoint subsets of column indices. Internal version does not verify the above properties hold. @@ -514,8 +514,9 @@ cdef class LeanMatrix: OUTPUT: - - `False, None` -- if the input submatrices does not induce a `m``-separator. - - `True, E` -- if there exist a ``m``-separator ``E``. + - ``False, None`` -- if the input submatrices does not induce an + ``m``-separator + - ``True, E`` -- if there exists an ``m``-separator ``E`` """ for z in range(self.ncols()): if z in P_cols+Q_cols: @@ -540,9 +541,9 @@ cdef class LeanMatrix: optional column `z2` attached. Let `E_2` be the submatrix using rows `U_2` and columns `V_1` with optional column `z1` attached. - If `E_1` and `E_2` can be extended to a ``m``-separator, then it - returns `True, E`, where `E` is a ``m``-separator. Otherwise it - returns `False, None` + If `E_1` and `E_2` can be extended to an ``m``-separator, then it + returns ``True, E``, where `E` is an ``m``-separator. Otherwise it + returns ``False, None``. `U_1` and `U_2` must be disjoint subsets of row indices. `V_1` and `V_2` must be disjoint subsets of column indices. @@ -555,14 +556,16 @@ cdef class LeanMatrix: - ``V_2`` -- list of column indices of the first submatrix - ``U_2`` -- list of row indices of the second submatrix - ``V_1`` -- list of column indices of the second submatrix - - ``z2`` -- start by add an additional column with index `z2` to `V_2` - - ``z1`` -- start by add an additional column with index `z1` to `V_1` + - ``z2`` -- start by add an additional column with index `z2` to `V_2` + - ``z1`` -- start by add an additional column with index `z1` to `V_1` - ``m`` -- separation size OUTPUT: - - `False, None` -- if the input submatrices does not induce a `m``-separator. - - `True, (X,Y)` -- row indices `X` and column indices `Y` defines a ``m``-separator. + - ``False, None`` -- if the input submatrices does not induce an + ``m``-separator + - ``True, (X,Y)`` -- row indices `X` and column indices `Y` defines an + ``m``-separator """ # make copy because of destructive updates cdef list X_1 = list(U_1) @@ -644,8 +647,8 @@ cdef class GenericMatrix(LeanMatrix): - ``nrows`` -- number of rows - ``ncols`` -- number of columns - ``M`` -- (default: ``None``) a ``Matrix`` or ``GenericMatrix`` of - dimensions at most ``m*n``. - - ``ring`` -- (default: ``None``) a Sage ring. + dimensions at most ``m*n`` + - ``ring`` -- (default: ``None``) a Sage ring .. NOTE:: @@ -935,11 +938,11 @@ cdef class BinaryMatrix(LeanMatrix): INPUT: - - ``m`` -- Number of rows. - - ``n`` -- Number of columns. - - ``M`` -- (default: ``None``) Matrix or BinaryMatrix instance. + - ``m`` -- number of rows + - ``n`` -- number of columns + - ``M`` -- (default: ``None``) ``Matrix`` or ``BinaryMatrix`` instance. Assumption: dimensions of ``M`` are at most ``m`` by ``n``. - - ``ring`` -- (default: ``None``) ignored. + - ``ring`` -- (default: ``None``) ignored EXAMPLES:: @@ -1018,7 +1021,7 @@ cdef class BinaryMatrix(LeanMatrix): def __repr__(self): r""" - Return representation string + Return representation string. EXAMPLES:: @@ -1544,11 +1547,11 @@ cdef class TernaryMatrix(LeanMatrix): INPUT: - - ``m`` -- Number of rows. - - ``n`` -- Number of columns. + - ``m`` -- number of rows + - ``n`` -- number of columns - ``M`` -- (default: ``None``) ``Matrix`` or ``TernaryMatrix`` instance. Assumption: dimensions of ``M`` are at most ``m`` by ``n``. - - ``ring`` -- (default: ``None``) ignored. + - ``ring`` -- (default: ``None``) ignored EXAMPLES:: @@ -1646,7 +1649,7 @@ cdef class TernaryMatrix(LeanMatrix): def __repr__(self): r""" - Return representation string + Return representation string. EXAMPLES:: @@ -2101,13 +2104,13 @@ cdef class QuaternaryMatrix(LeanMatrix): INPUT: - - ``m`` -- Number of rows - - ``n`` -- Number of columns - - ``M`` -- (default: ``None``) A QuaternaryMatrix or LeanMatrix or (Sage) - Matrix instance. If not given, new matrix will be filled with zeroes. - Assumption: ``M`` has dimensions at most ``m`` times ``n``. - - ``ring`` -- (default: ``None``) A copy of GF(4). Useful for specifying - generator name. + - ``m`` -- number of rows + - ``n`` -- number of columns + - ``M`` -- (default: ``None``) ``QuaternaryMatrix`` or ``LeanMatrix`` or + (Sage) ``Matrix`` instance. If not given, new matrix will be filled with + zeroes. Assumption: ``M`` has dimensions at most ``m`` times ``n``. + - ``ring`` -- (default: ``None``) a copy of GF(4); useful for specifying + generator name EXAMPLES:: @@ -2222,7 +2225,7 @@ cdef class QuaternaryMatrix(LeanMatrix): def __repr__(self): r""" - Return representation string + Return representation string. EXAMPLES:: diff --git a/src/sage/matroids/linear_matroid.pxd b/src/sage/matroids/linear_matroid.pxd index 085a68be0f6..b0890a76148 100644 --- a/src/sage/matroids/linear_matroid.pxd +++ b/src/sage/matroids/linear_matroid.pxd @@ -62,7 +62,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef _is_3connected_shifting(self, certificate=*) cpdef _is_4connected_shifting(self, certificate=*) - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef class BinaryMatroid(LinearMatroid): cdef tuple _b_invariant, _b_partition @@ -91,8 +91,8 @@ cdef class BinaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_graphic(self) - cpdef bint is_valid(self) + cpdef bint is_graphic(self) noexcept + cpdef bint is_valid(self) noexcept cdef class TernaryMatroid(LinearMatroid): @@ -122,7 +122,7 @@ cdef class TernaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef class QuaternaryMatroid(LinearMatroid): cdef object _x_zero, _x_one @@ -149,7 +149,7 @@ cdef class QuaternaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef class RegularMatroid(LinearMatroid): cdef _bases_count, _r_invariant @@ -172,6 +172,6 @@ cdef class RegularMatroid(LinearMatroid): cpdef has_line_minor(self, k, hyperlines=*, certificate=*) cpdef _linear_extension_chains(self, F, fundamentals=*) - cpdef bint is_regular(self) - cpdef bint is_graphic(self) - cpdef bint is_valid(self) + cpdef bint is_regular(self) noexcept + cpdef bint is_graphic(self) noexcept + cpdef bint is_valid(self) noexcept diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index ebb1bf2a711..6848604f0c8 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -204,7 +204,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``matrix`` -- (default: ``None``) a matrix whose column vectors - represent the matroid. + represent the matroid - ``reduced_matrix`` -- (default: ``None``) a matrix `B` such that `[I\ \ B]` represents the matroid, where `I` is an identity matrix with the same number of rows as `B`. Only one of ``matrix`` and @@ -216,16 +216,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``ring`` -- (default: ``None``) the desired base ring of the matrix. If the base ring is different, an attempt will be made to create a new matrix with the correct base ring. - - ``keep_initial_representation`` -- (default: ``True``) decides whether + - ``keep_initial_representation`` -- boolean (default: ``True``); whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy. - OUTPUT: - - A ``LinearMatroid`` instance based on the data above. + OUTPUT: a ``LinearMatroid`` instance based on the data above .. NOTE:: @@ -496,9 +494,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): the representation is such that a basis `B'` that maximally intersects `B` is an identity matrix. - - ``reduced`` -- (default: ``False``) when ``True``, return a reduced - matrix `D` (so `[I\ \ D]` is a representation of the matroid). - Otherwise return a full representation matrix. + - ``reduced`` -- boolean (default: ``False``); when ``True``, return a + reduced matrix `D` (so `[I\ \ D]` is a representation of the + matroid). Otherwise return a full representation matrix. - ``labels`` -- (default: ``None``) when ``True``, return additionally a list of column labels (if ``reduced=False``) or a list of row @@ -506,7 +504,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): The default setting, ``None``, will not return the labels for a full matrix, but will return the labels for a reduced matrix. - - ``order`` -- sequence or ``None`` or ``True`` (default: ``None``); + - ``order`` -- sequence or ``None`` or ``True`` (default: ``None``) - when a sequence, it should be an ordering of the groundset elements, and the columns (and, in case of a reduced @@ -526,7 +524,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``(A, E)`` -- a full representation matrix ``A`` and a list ``E`` of column labels; or - ``(A, R, C)`` -- a reduced representation matrix and a list ``R`` of - row labels and a list ``C`` of column labels. + row labels and a list ``C`` of column labels If ``B == None`` and ``reduced == False`` and ``order == None`` then this method will always output the same matrix (except when @@ -697,14 +695,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``B`` -- (default: ``None``) If provided, first find a basis having - maximal intersection with ``B``. + - ``B`` -- (default: ``None``) if provided, first find a basis having + maximal intersection with ``B`` OUTPUT: - - ``R`` -- A list of row indices; corresponds to the currently used + - ``R`` -- list of row indices; corresponds to the currently used internal basis - - ``C`` -- A list of column indices; corresponds to the complement of + - ``C`` -- list of column indices; corresponds to the complement of the current internal basis EXAMPLES:: @@ -735,7 +733,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -804,7 +802,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -844,7 +842,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``other`` -- matroid; assumed to have the same base ring as ``self`` - - ``morphism`` -- a dictionary mapping the groundset of ``self`` to + - ``morphism`` -- dictionary mapping the groundset of ``self`` to the groundset of ``other`` OUTPUT: boolean @@ -1016,7 +1014,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``other`` -- matroid - - ``morphism`` -- A map from the groundset of ``self`` to the + - ``morphism`` -- a map from the groundset of ``self`` to the groundset of ``other``. See documentation of the :meth:`M.is_isomorphism() ` method for more on what is accepted as input. @@ -1091,14 +1089,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A ``LinearMatroid`` instance, of the same subclass as - ``self``. + - ``other`` -- a ``LinearMatroid`` instance, of the same subclass as + ``self`` OUTPUT: - ``None`` -- if the test is inconclusive; - ``True`` -- if the matroids were found to be field-isomorphic - - ``False`` -- if the matroids were found to be non-field-isomorphic. + - ``False`` -- if the matroids were found to be non-field-isomorphic .. NOTE:: @@ -1153,7 +1151,6 @@ cdef class LinearMatroid(BasisExchangeMatroid): :meth:`M.is_field_isomorphism() `, :meth:`M.is_field_equivalent() ` - EXAMPLES:: sage: M1 = matroids.Wheel(3) @@ -1328,9 +1325,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``deletions`` is coindependent - ``contractions`` and ``deletions`` are disjoint. - OUTPUT: - - A matroid. + OUTPUT: matroid EXAMPLES:: @@ -1364,9 +1359,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): represented by `[-A^T\ \ I_2]` for appropriately sized identity matrices `I_1, I_2`. - OUTPUT: - - The dual matroid. + OUTPUT: the dual matroid EXAMPLES:: @@ -1400,13 +1393,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``k`` -- the length of the line minor - ``hyperlines`` -- (default: ``None``) a set of flats of codimension 2. Defaults to the set of all flats of codimension 2. - - ``certificate`` (default: ``False``); If ``True`` returns ``True, F``, - where ``F`` is a flat and ``self.minor(contractions=F)`` has a - `U_{2,k}` restriction or ``False, None``. + - ``certificate`` -- (default: ``False``) if ``True`` returns + ``True, F``, where ``F`` is a flat and ``self.minor(contractions=F)`` + has a `U_{2,k}` restriction or ``False, None`` - OUTPUT: - - Boolean or tuple. + OUTPUT: boolean or tuple EXAMPLES:: @@ -1499,8 +1490,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``e`` -- an element of the groundset. - - ``f`` -- an element of the groundset. + - ``e`` -- an element of the groundset + - ``f`` -- an element of the groundset ``e`` should be in the currently active basis, and ``f`` in the currently active cobasis. @@ -1772,7 +1763,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``F`` -- A flat of codimension 2 + - ``F`` -- a flat of codimension 2 - ``a``, ``b``, ``c``, ``d`` -- elements of the groundset OUTPUT: @@ -1817,7 +1808,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``F`` -- a flat of codimension 2 - ``x`` -- an element outside ``F`` - - ``fundamentals`` -- a set of fundamental elements. + - ``fundamentals`` -- set of fundamental elements OUTPUT: @@ -1877,7 +1868,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``x`` -- an element of the groundset - ``fundamentals`` -- a subset of the base ring - - ``hyperlines`` (optional) -- a set of flats of rank=full_rank-2 + - ``hyperlines`` -- (optional) a set of flats of ``rank=full_rank-2`` OUTPUT: boolean ``True`` if each cross ratio using ``x`` is an element of ``fundamentals``. If ``hyperlines`` is specified, then the method @@ -1924,11 +1915,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``element`` -- the name of the new element. + - ``element`` -- the name of the new element - ``col`` -- (default: ``None``) a column to be appended to - ``self.representation()``. Can be any iterable. + ``self.representation()``; can be any iterable - ``chain`` -- (default: ``None``) a dictionary that maps elements of - the groundset to elements of the base ring. + the groundset to elements of the base ring OUTPUT: @@ -2004,11 +1995,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``element`` -- the name of the new element. + - ``element`` -- the name of the new element - ``row`` -- (default: ``None``) a row to be appended to - ``self.representation()``. Can be any iterable. + ``self.representation()``; can be any iterable - ``cochain`` -- (default: ``None``) a dictionary that maps elements - of the groundset to elements of the base ring. + of the groundset to elements of the base ring OUTPUT: @@ -2092,9 +2083,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``element`` -- the name of the new element. - - ``chains`` -- a list of dictionaries, each of which maps elements of - the groundset to elements of the base ring. + - ``element`` -- the name of the new element + - ``chains`` -- list of dictionaries, each of which maps elements of + the groundset to elements of the base ring OUTPUT: @@ -2140,9 +2131,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``element`` -- the name of the new element. - - ``cochains`` -- a list of dictionaries, each of which maps elements - of the groundset to elements of the base ring. + - ``element`` -- the name of the new element + - ``cochains`` -- list of dictionaries, each of which maps elements + of the groundset to elements of the base ring OUTPUT: @@ -2252,9 +2243,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``F`` -- an independent set of elements. + - ``F`` -- an independent set of elements - ``fundamentals`` -- (default: ``None``) a set elements of the base - ring. + ring OUTPUT: @@ -2329,10 +2320,12 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``F`` -- (default: ``self.groundset()``) a subset of the groundset. - - ``simple`` -- (default: ``False``) boolean + - ``F`` -- (default: ``self.groundset()``) a subset of the groundset + + - ``simple`` -- boolean (default: ``False``) + - ``fundamentals`` -- (default: ``None``) a set elements of the base - ring. + ring OUTPUT: @@ -2429,10 +2422,12 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``F`` -- (default: ``self.groundset()``) a subset of the groundset. - - ``cosimple`` -- (default: ``False``) boolean + - ``F`` -- (default: ``self.groundset()``) a subset of the groundset + + - ``cosimple`` -- boolean (default: ``False``) + - ``fundamentals`` -- (default: ``None``) a set elements of the base - ring. + ring OUTPUT: @@ -2482,11 +2477,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``element`` -- (default: ``None``) the name of the new element of - the groundset. - - ``F`` -- (default: ``None``) a subset of the groundset. - - ``simple`` -- (default: ``False``) boolean + the groundset + + - ``F`` -- (default: ``None``) a subset of the groundset + + - ``simple`` -- boolean (default: ``False``) + - ``fundamentals`` -- (default: ``None``) a set elements of the base - ring. + ring OUTPUT: @@ -2550,11 +2548,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``element`` -- (default: ``None``) the name of the new element of - the groundset. - - ``F`` -- (default: ``None``) a subset of the groundset. - - ``cosimple`` -- (default: ``False``) boolean + the groundset + + - ``F`` -- (default: ``None``) a subset of the groundset + + - ``cosimple`` -- boolean (default: ``False``) + - ``fundamentals`` -- (default: ``None``) a set elements of the base - ring. + ring OUTPUT: @@ -2613,7 +2614,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cochains = self.linear_coextension_cochains(F, cosimple=cosimple, fundamentals=fundamentals) return self._linear_coextensions(element, cochains) - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data represent an actual matroid. @@ -2671,7 +2672,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``certificate`` -- (default: ``False``) boolean; if ``True``, + - ``certificate`` -- boolean (default: ``False``); if ``True``, then return ``True, None`` if the matroid is 3-connected, and ``False,`` `X` otherwise, where `X` is a `<3`-separation @@ -2750,7 +2751,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``certificate`` -- (default: ``False``) boolean; if ``True``, + - ``certificate`` -- boolean (default: ``False``); if ``True``, then return ``True, None`` if the matroid is 4-connected, and ``False,`` `X` otherwise, where `X` is a `<4`-separation @@ -2938,7 +2939,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): ....: [0, 0, 1, 1, 3]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U35") + sage: M.rename('U35') sage: loads(dumps(M)) U35 sage: M = Matroid(Matrix(GF(7), [[1, 0, 1], [1, 0, 1]])) @@ -3026,21 +3027,19 @@ cdef class BinaryMatroid(LinearMatroid): labels. When provided, must have the correct number of elements: the number of columns of ``matrix`` or the number of rows plus the number of columns of ``reduced_matrix``. - - ``ring`` -- (default: ``None``) ignored. - - ``keep_initial_representation`` -- (default: ``True``) decides whether + - ``ring`` -- (default: ``None``) ignored + - ``keep_initial_representation`` -- boolean (default: ``True``); whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy. - - ``basis`` -- (default: ``None``) When provided, this is an ordered + - ``basis`` -- (default: ``None``) when provided, this is an ordered subset of ``groundset``, such that the submatrix of ``matrix`` indexed by ``basis`` is an identity matrix. In this case, no row reduction takes place in the initialization phase. - OUTPUT: - - A :class:`BinaryMatroid` instance based on the data above. + OUTPUT: a :class:`BinaryMatroid` instance based on the data above .. NOTE:: @@ -3244,14 +3243,14 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) If provided, first find a basis having - maximal intersection with ``B``. + - ``B`` -- (default: ``None``) if provided, first find a basis having + maximal intersection with ``B`` OUTPUT: - - ``R`` -- A list of row indices; corresponds to the currently used + - ``R`` -- list of row indices; corresponds to the currently used internal basis - - ``C`` -- A list of column indices; corresponds to the complement of + - ``C`` -- list of column indices; corresponds to the complement of the current internal basis EXAMPLES:: @@ -3285,7 +3284,7 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -3325,7 +3324,7 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -3416,7 +3415,7 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - ``other`` -- matroid - - ``morphism`` -- a dictionary mapping the groundset of ``self`` to + - ``morphism`` -- dictionary mapping the groundset of ``self`` to the groundset of ``other`` OUTPUT: boolean @@ -3536,8 +3535,8 @@ cdef class BinaryMatroid(LinearMatroid): A tuple ``(d, b, Lm, L0, Lp, p0, p1, p2)``, with the following interpretation: - - ``d`` is the :meth:`bicycle dimension `. - - ``b`` is the :meth:`Brown invariant `. + - ``d`` -- the :meth:`bicycle dimension ` + - ``b`` -- the :meth:`Brown invariant ` - ``(Lm, L0, Lp)`` is the triple of lengths of the principal tripartition. - ``(p0, p1, p2)`` are the counts of edges in a characteristic graph of the matroid, whose vertices are the union of ``F_-`` and ``F_0`` @@ -3700,9 +3699,7 @@ cdef class BinaryMatroid(LinearMatroid): - Nothing - OUTPUT: - - An ordered partition. + OUTPUT: an ordered partition sage: from sage.matroids.advanced import * sage: M = matroids.catalog.R12() @@ -3730,7 +3727,7 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``other`` -- a binary matroid. + - ``other`` -- a binary matroid OUTPUT: @@ -3775,9 +3772,7 @@ cdef class BinaryMatroid(LinearMatroid): - ``deletions`` is coindependent - ``contractions`` and ``deletions`` are disjoint. - OUTPUT: - - A matroid. + OUTPUT: matroid EXAMPLES:: @@ -3798,7 +3793,7 @@ cdef class BinaryMatroid(LinearMatroid): keep_initial_representation=False) # graphicness test - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: """ Test if the binary matroid is graphic. @@ -3867,16 +3862,14 @@ cdef class BinaryMatroid(LinearMatroid): # now self is graphic iff there is a binary vector x so that M*x = 0 and x_0 = 1, so: return BinaryMatroid(m).corank(frozenset([0])) > 0 - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. Since this is a linear matroid over the field `\GF{2}`, this is always the case. - OUTPUT: - - ``True``. + OUTPUT: ``True`` EXAMPLES:: @@ -3894,12 +3887,10 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. - - ``verify`` -- Ignored - - OUTPUT: + - ``randomized_tests`` -- ignored + - ``verify`` -- ignored - A binary matroid. + OUTPUT: a binary matroid ALGORITHM: @@ -3924,7 +3915,7 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. + - ``randomized_tests`` -- ignored OUTPUT: boolean @@ -3968,7 +3959,7 @@ cdef class BinaryMatroid(LinearMatroid): ....: [0, 0, 1, 1]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U34") + sage: M.rename('U34') sage: loads(dumps(M)) U34 sage: M = Matroid(Matrix(GF(2), [[1, 0, 1], [1, 0, 1]])) @@ -4065,8 +4056,8 @@ cdef class TernaryMatroid(LinearMatroid): labels. When provided, must have the correct number of elements: the number of columns of ``matrix`` or the number of rows plus the number of columns of ``reduced_matrix``. - - ``ring`` -- (default: ``None``) ignored. - - ``keep_initial_representation`` -- (default: ``True``) boolean. Decides + - ``ring`` -- (default: ``None``) ignored + - ``keep_initial_representation`` -- boolean (default: ``True``); decides whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, @@ -4077,9 +4068,7 @@ cdef class TernaryMatroid(LinearMatroid): by ``basis`` is an identity matrix. In this case, no row reduction takes place in the initialization phase. - OUTPUT: - - A ``TernaryMatroid`` instance based on the data above. + OUTPUT: a ``TernaryMatroid`` instance based on the data above .. NOTE:: @@ -4291,14 +4280,14 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) If provided, first find a basis having - maximal intersection with ``B``. + - ``B`` -- (default: ``None``) if provided, first find a basis having + maximal intersection with ``B`` OUTPUT: - - ``R`` -- A list of row indices; corresponds to the currently used + - ``R`` -- list of row indices; corresponds to the currently used internal basis - - ``C`` -- A list of column indices; corresponds to the complement of + - ``C`` -- list of column indices; corresponds to the complement of the current internal basis EXAMPLES:: @@ -4332,7 +4321,7 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -4372,7 +4361,7 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -4527,13 +4516,13 @@ cdef class TernaryMatroid(LinearMatroid): A tuple ``(d, c, L, La, Lb, Lc, p0, p1, p2, p3, p4, p5)``, with the following interpretation: - - ``d`` is the bicycle dimension. - - ``c`` is the character. + - ``d`` is the bicycle dimension + - ``c`` is the character - ``(L, La, Lb, Lc)`` is the triple of lengths of the principal - quadripartition. + quadripartition - ``(p0, ..., p5)`` counts of edges in a characteristic graph of the matroid whose vertex set is the groundset of the matroid, - restricted to the sets in the principal quadripartition. + restricted to the sets in the principal quadripartition EXAMPLES:: @@ -4674,12 +4663,12 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``other`` -- a ternary matroid. + - ``other`` -- a ternary matroid OUTPUT: - ``True``, if ``self`` is isomorphic to ``other``; - - ``False``, if ``self`` is not isomorphic to ``other``; + - ``False``, if ``self`` is not isomorphic to ``other``; - ``None``, if the test is inconclusive EXAMPLES:: @@ -4715,9 +4704,7 @@ cdef class TernaryMatroid(LinearMatroid): - ``deletions`` is coindependent - ``contractions`` and ``deletions`` are disjoint. - OUTPUT: - - A matroid. + OUTPUT: matroid EXAMPLES:: @@ -4737,16 +4724,14 @@ cdef class TernaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. Since this is a linear matroid over the field `\GF{3}`, this is always the case. - OUTPUT: - - ``True``. + OUTPUT: ``True`` EXAMPLES:: @@ -4764,12 +4749,10 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. - - ``verify`` -- Ignored - - OUTPUT: + - ``randomized_tests`` -- ignored + - ``verify`` -- ignored - A binary matroid. + OUTPUT: a binary matroid ALGORITHM: @@ -4839,7 +4822,7 @@ cdef class TernaryMatroid(LinearMatroid): ....: [0, 1, 0, 1], [0, 0, 1, 1]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U34") + sage: M.rename('U34') sage: loads(dumps(M)) U34 sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 1], [1, 0, 1]])) @@ -4941,21 +4924,19 @@ cdef class QuaternaryMatroid(LinearMatroid): labels. When provided, must have the correct number of elements: the number of columns of ``matrix`` or the number of rows plus the number of columns of ``reduced_matrix``. - - ``ring`` -- (default: ``None``) must be a copy of `\GF{4}`. - - ``keep_initial_representation`` -- (default: ``True``) boolean. Decides + - ``ring`` -- (default: ``None``) must be a copy of `\GF{4}` + - ``keep_initial_representation`` -- boolean (default: ``True``); decides whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy. - - ``basis`` -- (default: ``None``) When provided, this is an ordered + - ``basis`` -- (default: ``None``) when provided, this is an ordered subset of ``groundset``, such that the submatrix of ``matrix`` indexed by ``basis`` is an identity matrix. In this case, no row reduction takes place in the initialization phase. - OUTPUT: - - A ``QuaternaryMatroid`` instance based on the data above. + OUTPUT: a ``QuaternaryMatroid`` instance based on the data above .. NOTE:: @@ -5156,14 +5137,14 @@ cdef class QuaternaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) If provided, first find a basis having - maximal intersection with ``B``. + - ``B`` -- (default: ``None``) if provided, first find a basis having + maximal intersection with ``B`` OUTPUT: - - ``R`` -- A list of row indices; corresponds to the currently used + - ``R`` -- list of row indices; corresponds to the currently used internal basis - - ``C`` -- A list of column indices; corresponds to the complement of + - ``C`` -- list of column indices; corresponds to the complement of the current internal basis EXAMPLES:: @@ -5198,7 +5179,7 @@ cdef class QuaternaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -5242,7 +5223,7 @@ cdef class QuaternaryMatroid(LinearMatroid): INPUT: - - ``B`` -- (default: ``None``) a set of elements of the groundset. + - ``B`` -- (default: ``None``) a set of elements of the groundset OUTPUT: @@ -5357,12 +5338,12 @@ cdef class QuaternaryMatroid(LinearMatroid): A tuple ``(d, Lm, L0, Lp, p0, p1, p2)``, with the following interpretation: - - ``d`` is the bicycle dimension. + - ``d`` is the bicycle dimension - ``(Lm, L0, Lp)`` is the triple of lengths of the principal - tripartition. + tripartition - ``(p0, p1, p2)`` counts of edges in a characteristic graph of the matroid, whose vertices are the union of ``F_-`` and ``F_0`` from - the principal tripartition. + the principal tripartition EXAMPLES:: @@ -5447,7 +5428,7 @@ cdef class QuaternaryMatroid(LinearMatroid): INPUT: - - ``other`` -- a quaternary matroid. + - ``other`` -- a quaternary matroid OUTPUT: @@ -5487,9 +5468,7 @@ cdef class QuaternaryMatroid(LinearMatroid): - ``deletions`` is coindependent - ``contractions`` and ``deletions`` are disjoint. - OUTPUT: - - A matroid. + OUTPUT: matroid EXAMPLES:: @@ -5509,16 +5488,14 @@ cdef class QuaternaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. Since this is a linear matroid over the field `\GF{4}`, this is always the case. - OUTPUT: - - ``True``. + OUTPUT: ``True`` EXAMPLES:: @@ -5553,7 +5530,7 @@ cdef class QuaternaryMatroid(LinearMatroid): ....: [0, 0, 1, 1]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U34") + sage: M.rename('U34') sage: loads(dumps(M)) U34 @@ -5649,8 +5626,8 @@ cdef class RegularMatroid(LinearMatroid): labels. When provided, must have the correct number of elements: the number of columns of ``matrix`` or the number of rows plus the number of columns of ``reduced_matrix``. - - ``ring`` -- (default: ``None``) ignored. - - ``keep_initial_representation`` -- (default: ``True``) boolean. Decides + - ``ring`` -- (default: ``None``) ignored + - ``keep_initial_representation`` -- boolean (default: ``True``); decides whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, @@ -5661,9 +5638,7 @@ cdef class RegularMatroid(LinearMatroid): by ``basis`` is an identity matrix. In this case, no row reduction takes place in the initialization phase. - OUTPUT: - - A ``RegularMatroid`` instance based on the data above. + OUTPUT: a ``RegularMatroid`` instance based on the data above .. NOTE:: @@ -5964,10 +5939,10 @@ cdef class RegularMatroid(LinearMatroid): OUTPUT: - - ``PV`` -- A partition of the vertices of ``G``. - - ``tups`` -- A list of pairs ``(x, y)``, where ``x`` denotes the - color class of a part and ``y`` the number of elements in that part. - - ``G`` -- a graph. + - ``PV`` -- a partition of the vertices of ``G`` + - ``tups`` -- list of pairs ``(x, y)``, where ``x`` denotes the + color class of a part and ``y`` the number of elements in that part + - ``G`` -- a graph All are derived from the entries of the projection matrix `P`. The partition ``PV`` groups vertices of the form `i` by the value of @@ -6119,7 +6094,7 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``other`` -- a regular matroid. + - ``other`` -- a regular matroid OUTPUT: @@ -6152,11 +6127,9 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``other`` -- A ``RegularMatroid`` instance. - - OUTPUT: + - ``other`` -- a ``RegularMatroid`` instance - - a dictionary, if the hypergraphs are isomorphic; ``None`` otherwise. + OUTPUT: dictionary, if the hypergraphs are isomorphic; ``None`` otherwise TESTS: @@ -6195,13 +6168,11 @@ cdef class RegularMatroid(LinearMatroid): - ``k`` -- the length of the line minor - ``hyperlines`` -- (default: ``None``) a set of flats of codimension 2. Defaults to the set of all flats of codimension 2. - - ``certificate`` (default: ``False``); If ``True`` returns ``True, F``, - where ``F`` is a flat and ``self.minor(contractions=F)`` has a - `U_{2,k}` restriction or ``False, None``. - - OUTPUT: + - ``certificate`` -- (default: ``False``) if ``True`` returns + ``True, F``, where ``F`` is a flat and ``self.minor(contractions=F)`` + has a `U_{2,k}` restriction or ``False, None`` - Boolean or tuple. + OUTPUT: boolean or tuple .. SEEALSO:: @@ -6242,9 +6213,9 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``F`` -- an independent set of elements. + - ``F`` -- an independent set of elements - ``fundamentals`` -- (default: ``None``) a set elements of the base - ring. + ring OUTPUT: @@ -6268,7 +6239,7 @@ cdef class RegularMatroid(LinearMatroid): fundamentals = set([1]) return LinearMatroid._linear_extension_chains(self, F, fundamentals) - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: """ Test if the regular matroid is graphic. @@ -6299,7 +6270,7 @@ cdef class RegularMatroid(LinearMatroid): """ return BinaryMatroid(reduced_matrix=self._reduced_representation()).is_graphic() - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -6328,7 +6299,7 @@ cdef class RegularMatroid(LinearMatroid): # representation - cpdef bint is_regular(self): + cpdef bint is_regular(self) noexcept: r""" Return if ``self`` is regular. @@ -6348,12 +6319,10 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. - - ``verify`` -- Ignored - - OUTPUT: + - ``randomized_tests`` -- ignored + - ``verify`` -- ignored - A binary matroid. + OUTPUT: a binary matroid ALGORITHM: @@ -6379,7 +6348,7 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. + - ``randomized_tests`` -- ignored OUTPUT: boolean @@ -6405,12 +6374,10 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. - - ``verify`` -- Ignored - - OUTPUT: + - ``randomized_tests`` -- ignored + - ``verify`` -- ignored - A ternary matroid. + OUTPUT: a ternary matroid ALGORITHM: @@ -6436,7 +6403,7 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. + - ``randomized_tests`` -- ignored OUTPUT: boolean @@ -6483,7 +6450,7 @@ cdef class RegularMatroid(LinearMatroid): sage: M = matroids.catalog.R12() sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("R_{12}") + sage: M.rename('R_{12}') sage: loads(dumps(M)) R_{12} sage: M = RegularMatroid(Matrix(QQ, [[1, 0, 1], [1, 0, 1]])) diff --git a/src/sage/matroids/matroid.pxd b/src/sage/matroids/matroid.pxd index ca197f605b9..6218cb804f4 100644 --- a/src/sage/matroids/matroid.pxd +++ b/src/sage/matroids/matroid.pxd @@ -9,28 +9,28 @@ cdef class Matroid(SageObject): # virtual methods cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 # internal methods, assuming verified input cpdef frozenset _max_independent(self, frozenset X) cpdef frozenset _circuit(self, frozenset X) cpdef frozenset _fundamental_circuit(self, frozenset B, e) cpdef frozenset _closure(self, frozenset X) - cpdef int _corank(self, frozenset X) + cpdef int _corank(self, frozenset X) noexcept cpdef frozenset _max_coindependent(self, frozenset X) cpdef frozenset _cocircuit(self, frozenset X) cpdef frozenset _fundamental_cocircuit(self, frozenset B, e) cpdef frozenset _coclosure(self, frozenset X) cpdef frozenset _augment(self, frozenset X, frozenset Y) - cpdef bint _is_independent(self, frozenset X) - cpdef bint _is_basis(self, frozenset X) - cpdef bint _is_circuit(self, frozenset X) - cpdef bint _is_closed(self, frozenset X) - cpdef bint _is_coindependent(self, frozenset X) - cpdef bint _is_cobasis(self, frozenset X) - cpdef bint _is_cocircuit(self, frozenset X) - cpdef bint _is_coclosed(self, frozenset X) + cpdef bint _is_independent(self, frozenset X) noexcept + cpdef bint _is_basis(self, frozenset X) noexcept + cpdef bint _is_circuit(self, frozenset X) noexcept + cpdef bint _is_closed(self, frozenset X) noexcept + cpdef bint _is_coindependent(self, frozenset X) noexcept + cpdef bint _is_cobasis(self, frozenset X) noexcept + cpdef bint _is_cocircuit(self, frozenset X) noexcept + cpdef bint _is_coclosed(self, frozenset X) noexcept cpdef _minor(self, contractions, deletions) cpdef _has_minor(self, N, bint certificate=*) @@ -105,7 +105,7 @@ cdef class Matroid(SageObject): cpdef is_coclosed(self, X) # verification - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept # enumeration cpdef SetSystem circuits(self, k=*) @@ -184,8 +184,8 @@ cdef class Matroid(SageObject): cpdef _is_3connected_CE(self, certificate=*) cpdef _is_3connected_BC(self, certificate=*) cpdef _is_3connected_BC_recursion(self, basis, fund_cocircuits) - cpdef bint is_paving(self) - cpdef bint is_sparse_paving(self) + cpdef bint is_paving(self) noexcept + cpdef bint is_sparse_paving(self) noexcept cpdef girth(self) # representability @@ -195,8 +195,8 @@ cdef class Matroid(SageObject): cpdef _local_ternary_matroid(self, basis=*) cpdef ternary_matroid(self, randomized_tests=*, verify=*) cpdef is_ternary(self, randomized_tests=*) - cpdef bint is_regular(self) - cpdef bint is_graphic(self) + cpdef bint is_regular(self) noexcept + cpdef bint is_graphic(self) noexcept # matroid k-closed cpdef is_k_closed(self, int k) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 5591e14c038..0384ff81a22 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -299,7 +299,7 @@ Minors:: Testing. Note that the abstract base class does not support pickling:: sage: M = sage.matroids.matroid.Matroid() - sage: TestSuite(M).run(skip="_test_pickling") + sage: TestSuite(M).run(skip='_test_pickling') REFERENCES ========== @@ -492,7 +492,7 @@ cdef class Matroid(SageObject): """ raise NotImplementedError("subclasses need to implement this") - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: r""" Return the rank of a set ``X``. @@ -513,8 +513,9 @@ cdef class Matroid(SageObject): sage: M = sage.matroids.matroid.Matroid() sage: M._rank(frozenset([0, 1, 2])) - NotImplementedError: subclasses need to implement this + Traceback (most recent call last): ... + NotImplementedError: subclasses need to implement this """ raise NotImplementedError("subclasses need to implement this") @@ -659,7 +660,7 @@ cdef class Matroid(SageObject): OUTPUT: ``frozenset`` instance containing a subset of the groundset. - A :class:`ValueError` is raised if the set contains no circuit. + A :exc:`ValueError` is raised if the set contains no circuit. EXAMPLES:: @@ -693,8 +694,8 @@ cdef class Matroid(SageObject): INPUT: - - ``B`` -- a basis of the matroid. - - ``e`` -- an element not in ``B``. + - ``B`` -- a basis of the matroid + - ``e`` -- an element not in ``B`` OUTPUT: a set of elements @@ -732,7 +733,7 @@ cdef class Matroid(SageObject): XX.pop() return frozenset(XX) - cpdef int _corank(self, frozenset X): + cpdef int _corank(self, frozenset X) noexcept: """ Return the corank of a set. @@ -793,7 +794,7 @@ cdef class Matroid(SageObject): OUTPUT: ``frozenset`` instance containing a subset of the groundset. - A :class:`ValueError` is raised if the set contains no cocircuit. + A :exc:`ValueError` is raised if the set contains no cocircuit. EXAMPLES:: @@ -827,8 +828,8 @@ cdef class Matroid(SageObject): INPUT: - - ``B`` -- a basis of the matroid. - - ``e`` -- an element of ``B``. + - ``B`` -- a basis of the matroid + - ``e`` -- an element of ``B`` OUTPUT: a set of elements @@ -878,7 +879,7 @@ cdef class Matroid(SageObject): - ``X`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - ``Y`` -- an object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``, and disjoint from ``X``. + a subset of ``self.groundset()``, and disjoint from ``X`` OUTPUT: a subset of the groundset as a :class:`frozenset` @@ -904,7 +905,7 @@ cdef class Matroid(SageObject): # override the following methods for even better efficiency - cpdef bint _is_independent(self, frozenset X): + cpdef bint _is_independent(self, frozenset X) noexcept: """ Test if input is independent. @@ -925,7 +926,7 @@ cdef class Matroid(SageObject): """ return len(X) == self._rank(X) - cpdef bint _is_basis(self, frozenset X): + cpdef bint _is_basis(self, frozenset X) noexcept: """ Test if input is a basis. @@ -958,7 +959,7 @@ cdef class Matroid(SageObject): """ return self._is_independent(X) - cpdef bint _is_circuit(self, frozenset X): + cpdef bint _is_circuit(self, frozenset X) noexcept: """ Test if input is a circuit. @@ -990,7 +991,7 @@ cdef class Matroid(SageObject): Z.add(x) return True - cpdef bint _is_closed(self, frozenset X): + cpdef bint _is_closed(self, frozenset X) noexcept: """ Test if input is a closed set. @@ -1019,7 +1020,7 @@ cdef class Matroid(SageObject): XX.discard(y) return True - cpdef bint _is_coindependent(self, frozenset X): + cpdef bint _is_coindependent(self, frozenset X) noexcept: """ Test if input is coindependent. @@ -1040,7 +1041,7 @@ cdef class Matroid(SageObject): """ return self._corank(X) == len(X) - cpdef bint _is_cobasis(self, frozenset X): + cpdef bint _is_cobasis(self, frozenset X) noexcept: """ Test if input is a cobasis. @@ -1068,7 +1069,7 @@ cdef class Matroid(SageObject): """ return self._is_basis(self.groundset().difference(X)) - cpdef bint _is_cocircuit(self, frozenset X): + cpdef bint _is_cocircuit(self, frozenset X) noexcept: """ Test if input is a cocircuit. @@ -1100,7 +1101,7 @@ cdef class Matroid(SageObject): Z.add(x) return True - cpdef bint _is_coclosed(self, frozenset X): + cpdef bint _is_coclosed(self, frozenset X) noexcept: """ Test if input is a coclosed set. @@ -1231,7 +1232,7 @@ cdef class Matroid(SageObject): INPUT: - ``F`` -- a subset of the groundset, assumed to be a closed set of - rank `r(M) - 2`. + rank `r(M) - 2` OUTPUT: integer @@ -1256,9 +1257,9 @@ cdef class Matroid(SageObject): INPUT: - - ``element`` -- a hashable object not in ``self.groundset()``. + - ``element`` -- a hashable object not in ``self.groundset()`` - ``hyperplanes`` -- the set of hyperplanes of a linear subclass of - ``self``. + ``self`` OUTPUT: matroid @@ -1540,8 +1541,8 @@ cdef class Matroid(SageObject): INPUT: - - ``B`` -- a basis of the matroid. - - ``e`` -- an element not in ``B``. + - ``B`` -- a basis of the matroid + - ``e`` -- an element not in ``B`` OUTPUT: a set of elements @@ -1601,7 +1602,7 @@ cdef class Matroid(SageObject): INPUT: - ``X`` -- a subset (or any iterable) of the groundset - - ``k`` -- a positive integer + - ``k`` -- positive integer EXAMPLES:: @@ -1890,8 +1891,8 @@ cdef class Matroid(SageObject): INPUT: - - ``B`` -- a basis of the matroid. - - ``e`` -- an element of ``B``. + - ``B`` -- a basis of the matroid + - ``e`` -- an element of ``B`` OUTPUT: a set of elements @@ -2049,7 +2050,7 @@ cdef class Matroid(SageObject): INPUT: - ``X`` -- a subset (or any iterable) of the groundset - - ``k`` -- a positive integer + - ``k`` -- positive integer OUTPUT: boolean @@ -2305,7 +2306,7 @@ cdef class Matroid(SageObject): # verification - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -3606,7 +3607,8 @@ cdef class Matroid(SageObject): Two matroids `M` and `N` are *isomorphic* if there is a bijection `f` from the groundset of `M` to the groundset of `N` such that a subset `X` is independent in `M` if and only if `f(X)` is independent in `N`. - This method returns one isomorphism `f` from self to other, if such an isomorphism exists. + This method returns one isomorphism `f` from ``self`` to ``other``, if + such an isomorphism exists. INPUT: @@ -3899,8 +3901,8 @@ cdef class Matroid(SageObject): INPUT: - ``other`` -- matroid - - ``morphism`` -- a dictionary mapping the groundset of ``self`` to - the groundset of ``other``. + - ``morphism`` -- dictionary mapping the groundset of ``self`` to + the groundset of ``other`` OUTPUT: boolean @@ -4139,7 +4141,7 @@ cdef class Matroid(SageObject): INPUT: - - ``X`` -- Either a single element of the groundset, or a collection + - ``X`` -- either a single element of the groundset, or a collection of elements OUTPUT: the matroid obtained by contracting the element(s) in ``X`` @@ -4216,7 +4218,7 @@ cdef class Matroid(SageObject): INPUT: - - ``X`` -- Either a single element of the groundset, or a collection + - ``X`` -- either a single element of the groundset, or a collection of elements OUTPUT: the matroid obtained by deleting the element(s) in ``X`` @@ -4395,9 +4397,10 @@ cdef class Matroid(SageObject): - ``k`` -- the length of the line minor - ``hyperlines`` -- (default: ``None``) a set of flats of codimension 2. Defaults to the set of all flats of codimension 2. - - ``certificate`` -- (default: ``False``) if ``True`` returns ``(True, F)``, - where ``F`` is a flat and ``self.minor(contractions=F)`` has a - `U_{2,k}` restriction or ``(False, None)``. + - ``certificate`` -- boolean (default: ``False``); if ``True`` returns + ``(True, F)``, where ``F`` is a flat and + ``self.minor(contractions=F)`` has a `U_{2,k}` restriction or + ``(False, None)``. OUTPUT: boolean or tuple @@ -4459,8 +4462,8 @@ cdef class Matroid(SageObject): INPUT: - ``k`` -- the length of the line minor - - ``hyperlines`` -- (default: None) a set of flats of codimension 2. - The flats are assumed to be ``frozenset`` compatible. + - ``hyperlines`` -- (default: ``None``) a set of flats of codimension 2; + the flats are assumed to be ``frozenset`` compatible OUTPUT: boolean or tuple @@ -5054,7 +5057,7 @@ cdef class Matroid(SageObject): deleting the complement of that subset is :meth:`connected `. - OUTPUT: a list of subsets + OUTPUT: list of subsets .. SEEALSO:: @@ -5333,11 +5336,11 @@ cdef class Matroid(SageObject): INPUT: - ``k`` -- integer greater or equal to 1 - - ``certificate`` -- (default: ``False``) boolean; if ``True``, + - ``certificate`` -- boolean (default: ``False``); if ``True``, then return ``True, None`` if the matroid is k-connected, and ``False, X`` otherwise, where ``X`` is a ``. + OUTPUT: a :class:`TernaryMatroid ` ALGORITHM: @@ -6499,7 +6501,7 @@ cdef class Matroid(SageObject): ``False``, any output will represent ``self`` if and only if the matroid is ternary - OUTPUT: Either a + OUTPUT: either a :class:`TernaryMatroid `, or ``None`` @@ -6576,7 +6578,7 @@ cdef class Matroid(SageObject): """ return self.ternary_matroid(randomized_tests=randomized_tests, verify=True) is not None - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: r""" Return if ``self`` is graphic. @@ -6610,7 +6612,7 @@ cdef class Matroid(SageObject): return False return True - cpdef bint is_regular(self): + cpdef bint is_regular(self) noexcept: r""" Return if ``self`` is regular. @@ -6687,7 +6689,7 @@ cdef class Matroid(SageObject): INPUT: - ``C`` -- a circuit - - ``certificate`` -- boolean (default: ``False``), if ``True`` + - ``certificate`` -- boolean (default: ``False``); if ``True`` return ``True, (x, Ax, Bx)``, where ``x`` is a chord and ``Ax`` and ``Bx`` are circuits whose union is the elements of ``C`` together with ``x``, if ``False`` return ``False, None`` @@ -6736,7 +6738,7 @@ cdef class Matroid(SageObject): INPUT: - ``C`` -- a circuit - - ``certificate`` -- boolean (default: ``False``), if ``True`` + - ``certificate`` -- boolean (default: ``False``); if ``True`` return ``True, (x, Ax, Bx)``, where ``x`` is a chord and ``Ax`` and ``Bx`` are circuits whose union is the elements of ``C`` together with ``x``, if ``False`` return ``False, None`` @@ -6780,7 +6782,7 @@ cdef class Matroid(SageObject): - ``k1`` -- (optional) the integer `k_1` - ``k2`` -- (optional) the integer `k_2`; if not specified, then this method returns if ``self`` is `k_1`-chordal - - ``certificate`` -- (default: ``False``) boolean; if + - ``certificate`` -- boolean (default: ``False``); if ``True`` return ``True, C``, where ``C`` is a non ``k1`` ``k2`` circuit @@ -6860,7 +6862,7 @@ cdef class Matroid(SageObject): - ``X`` -- (default: the groundset) a subset (or any iterable) of the groundset - - ``weights`` -- a dictionary or function mapping the elements of + - ``weights`` -- dictionary or function mapping the elements of ``X`` to nonnegative weights OUTPUT: a subset of ``X`` @@ -6945,7 +6947,7 @@ cdef class Matroid(SageObject): - ``X`` -- (default: the groundset) a subset (or any iterable) of the groundset - - ``weights`` -- a dictionary or function mapping the elements of + - ``weights`` -- dictionary or function mapping the elements of ``X`` to nonnegative weights OUTPUT: a subset of ``X`` @@ -7036,7 +7038,7 @@ cdef class Matroid(SageObject): - ``X`` -- (default: the groundset) a subset (or any iterable) of the groundset - - ``weights`` -- a dictionary or function mapping the elements of + - ``weights`` -- dictionary or function mapping the elements of ``X`` to nonnegative weights OUTPUT: boolean @@ -7183,7 +7185,7 @@ cdef class Matroid(SageObject): - ``X`` -- (default: the groundset) a subset (or any iterable) of the groundset - - ``weights`` -- a dictionary or function mapping the elements of + - ``weights`` -- dictionary or function mapping the elements of ``X`` to nonnegative weights OUTPUT: boolean @@ -7197,7 +7199,6 @@ cdef class Matroid(SageObject): previously selected elements, then we check if it is coindependent with the previously selected elements with higher weight. - EXAMPLES:: sage: from sage.matroids.advanced import setprint @@ -7391,7 +7392,7 @@ cdef class Matroid(SageObject): - ``other`` -- a second matroid with the same groundset as this matroid - - ``weights`` -- a dictionary which must specify a weight for each + - ``weights`` -- dictionary which must specify a weight for each element of the common groundset OUTPUT: a subset of the groundset @@ -7721,7 +7722,7 @@ cdef class Matroid(SageObject): Return a minimum number of disjoint independent sets that covers the groundset. - OUTPUT: a list of disjoint independent sets that covers the groundset + OUTPUT: list of disjoint independent sets that covers the groundset EXAMPLES:: @@ -7980,13 +7981,13 @@ cdef class Matroid(SageObject): INPUT: - - ``solver`` -- (default: ``None``) Specify a Linear Program (LP) solver + - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to be used. If set to ``None``, the default one is used. For more information on LP solvers and which default solver is used, see the method :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. - - ``verbose`` -- integer (default: ``0``). Sets the level of verbosity + - ``verbose`` -- integer (default: 0); sets the level of verbosity of the LP solver. Set to 0 by default, which means quiet. .. SEEALSO:: @@ -8137,19 +8138,23 @@ cdef class Matroid(SageObject): INPUT: - - ``B`` -- (optional) a list containing a basis. - If internal point placement is used, these elements will be placed as vertices of a triangle. - - ``lineorders`` -- (optional) A list of lists where each of the inner lists - specify groundset elements in a certain order which will be used to draw the - corresponding line in geometric representation (if it exists). - - ``pos_method`` -- An integer specifying positioning method. + - ``B`` -- (optional) list containing a basis; if internal point + placement is used, these elements will be placed as vertices of a + triangle + - ``lineorders`` -- (optional) list of lists where each of the inner + lists specify groundset elements in a certain order which will be + used to draw the corresponding line in geometric representation (if + it exists) + - ``pos_method`` -- integer specifying positioning method - ``0``: default positioning - ``1``: use pos_dict if it is not ``None`` - - ``2``: Force directed (Not yet implemented). + - ``2``: force directed (Not yet implemented) - - ``pos_dict``: A dictionary mapping groundset elements to their (x,y) positions. - - ``save_pos``: boolean indicating that point placements (either internal or user provided) and - line orders (if provided) will be cached in the matroid (``M._cached_info``) and can be used for + - ``pos_dict`` -- dictionary mapping groundset elements to their (x,y) + positions + - ``save_pos`` -- boolean indicating that point placements (either + internal or user provided) and line orders (if provided) will be + cached in the matroid (``M._cached_info``) and can be used for reproducing the geometric representation during the same session OUTPUT: @@ -8203,19 +8208,19 @@ cdef class Matroid(SageObject): - ``lineorders`` -- (optional) a list of lists where each of the inner lists specify groundset elements in a certain order which will be used to draw the corresponding line in geometric representation (if - it exists). + it exists) - ``pos_method`` -- integer specifying the positioning method - ``0``: default positioning - ``1``: use pos_dict if it is not ``None`` - ``2``: Force directed (Not yet implemented). - - ``pos_dict`` -- a dictionary mapping groundset elements to their + - ``pos_dict`` -- dictionary mapping groundset elements to their (x, y) positions - ``save_pos`` -- boolean indicating that point placements (either internal or user provided) and line orders (if provided) will be cached in the matroid (``M._cached_info``) and can be used for reproducing the geometric representation during the same session - - ``lims`` -- a list of 4 elements ``[xmin,xmax,ymin,ymax]`` + - ``lims`` -- list of 4 elements ``[xmin,xmax,ymin,ymax]`` EXAMPLES:: @@ -8246,16 +8251,16 @@ cdef class Matroid(SageObject): cpdef _fix_positions(self, pos_dict=None, lineorders=None): """ - Cache point positions and line orders without actually plotting + Cache point positions and line orders without actually plotting. INPUT: - - ``pos_dict`` -- (optional) A dictionary mapping groundset elements to + - ``pos_dict`` -- (optional) dictionary mapping groundset elements to their (x, y) positions - - ``lineorders`` -- (optional) a list of lists where each of the inner + - ``lineorders`` -- (optional) list of lists where each of the inner lists specify groundset elements in a certain order which will be used to draw the corresponding line in geometric representation (if - it exists). + it exists) EXAMPLES:: @@ -8506,7 +8511,7 @@ cdef class Matroid(SageObject): INPUT: - - ``matroids`` -- a matroid or a list of matroids + - ``matroids`` -- matroid or a list of matroids OUTPUT: an instance of :class:`MatroidUnion ` @@ -8546,7 +8551,7 @@ cdef class Matroid(SageObject): INPUT: - - ``matroids`` -- a matroid or list of matroids + - ``matroids`` -- matroid or list of matroids OUTPUT: an instance of :class:`MatroidSum ` diff --git a/src/sage/matroids/matroids_plot_helpers.py b/src/sage/matroids/matroids_plot_helpers.py index 450c56ac049..5f09905844b 100644 --- a/src/sage/matroids/matroids_plot_helpers.py +++ b/src/sage/matroids/matroids_plot_helpers.py @@ -88,24 +88,21 @@ def it(M, B1, nB1, lps): INPUT: - - ``M`` -- A matroid. - - ``B1`` -- A list of groundset elements of ``M`` that corresponds to a - basis of matroid ``M``. - - ``nB1`` -- A list of elements in the ground set of M that corresponds to - ``M.simplify.groundset() \ B1``. - - ``lps`` -- A list of elements in the ground set of matroid M that are - loops. + - ``M`` -- matroid + - ``B1`` -- list of groundset elements of ``M`` that corresponds to a + basis of matroid ``M`` + - ``nB1`` -- list of elements in the ground set of M that corresponds to + ``M.simplify.groundset() \ B1`` + - ``lps`` -- list of elements in the ground set of matroid M that are loops - OUTPUT: - - A tuple containing 4 elements in this order: + OUTPUT: a tuple containing 4 elements in this order: 1. A dictionary containing 2-tuple (x,y) coordinates with ``M.simplify.groundset()`` elements that can be placed on the sides of the triangle as keys. 2. A list of 3 lists of elements of ``M.simplify.groundset()`` that can be placed on the 3 sides of the triangle. - 3. A list of elements of `M.simplify.groundset()`` that cane be placed + 3. A list of elements of ``M.simplify.groundset()`` that cane be placed inside the triangle in the geometric representation. 4. A list of lists of elements of ``M.simplify.groundset()`` that correspond to lines in the geometric representation other than the sides @@ -171,11 +168,13 @@ def it(M, B1, nB1, lps): # loop over L1,L2,L3 cc = interval*j pts[i[j-1]] = (cc*pt1[0]+(1-cc)*pt2[0], cc*pt1[1]+(1-cc)*pt2[1]) - trilines = [list(set(x)) for x in lines if len(x) >= 3] - curvedlines = [list(set(list(x)).difference(set(lps))) - for x in M.flats(2) if set(list(x)) not in trilines if - len(list(x)) >= 3] - nontripts = [i for i in nB1 if i not in pts.keys()] + trilines = [set(x) for x in lines if len(x) >= 3] + set_lps = set(lps) + curvedlines = [list(sx.difference(set_lps)) + for x in M.flats(2) if (sx := set(x)) not in trilines + and len(list(x)) >= 3] + nontripts = [i for i in nB1 if i not in pts] + trilines = [list(s) for s in trilines] return pts, trilines, nontripts, curvedlines @@ -185,12 +184,10 @@ def trigrid(tripts): INPUT: - - ``tripts`` -- A list of 3 lists of the form [x,y] where x and y are the - Cartesian coordinates of a point. - - OUTPUT: + - ``tripts`` -- list of 3 lists of the form [x,y] where x and y are the + Cartesian coordinates of a point - A list of lists containing 4 points in following order: + OUTPUT: list of lists containing 4 points in following order: - 1. Barycenter of 3 input points. - 2,3,4. Barycenters of 1. with 3 different 2-subsets of input points @@ -211,12 +208,12 @@ def trigrid(tripts): This method does NOT do any checks. """ pairs = [[0, 1], [1, 2], [0, 2]] - cpt = list((float(tripts[0][0]+tripts[1][0]+tripts[2][0])/3, - float(tripts[0][1]+tripts[1][1]+tripts[2][1])/3)) + cpt = [float(tripts[0][0] + tripts[1][0] + tripts[2][0]) / 3, + float(tripts[0][1] + tripts[1][1] + tripts[2][1]) / 3] grid = [cpt] - for p in pairs: - pt = list((float(tripts[p[0]][0]+tripts[p[1]][0]+cpt[0])/3, - float(tripts[p[0]][1]+tripts[p[1]][1]+cpt[1])/3)) + for p, q in pairs: + pt = [float(tripts[p][0] + tripts[q][0] + cpt[0]) / 3, + float(tripts[p][1] + tripts[q][1] + cpt[1]) / 3] grid.append(pt) return grid @@ -228,12 +225,12 @@ def addnontripts(tripts_labels, nontripts_labels, ptsdict): INPUT: - - ``tripts`` -- A list of 3 ground set elements that are to be placed on - vertices of the triangle. - - ``ptsdict`` -- A dictionary (at least) containing ground set elements in - ``tripts`` as keys and their (x,y) position as values. - - ``nontripts`` -- A list of ground set elements whose corresponding points - are to be placed inside the triangle. + - ``tripts`` -- list of 3 ground set elements that are to be placed on + vertices of the triangle + - ``ptsdict`` -- dictionary (at least) containing ground set elements in + ``tripts`` as keys and their (x,y) position as values + - ``nontripts`` -- list of ground set elements whose corresponding points + are to be placed inside the triangle OUTPUT: @@ -295,18 +292,16 @@ def createline(ptsdict, ll, lineorders2=None): INPUT: - - ``ptsdict`` -- A dictionary containing keys and their (x,y) position as - values. - - ``ll`` -- A list of keys in ``ptsdict`` through which a line is to be - drawn. - - ``lineorders2`` -- (optional) A list of ordered lists of keys in + - ``ptsdict`` -- dictionary containing keys and their (x,y) position as + values + - ``ll`` -- list of keys in ``ptsdict`` through which a line is to be + drawn + - ``lineorders2`` -- (optional) list of ordered lists of keys in ``ptsdict`` such that if ll is setwise same as any of these then points corresponding to values of the keys will be traversed in that order thus - overriding internal order deciding heuristic. + overriding internal order deciding heuristic - OUTPUT: - - A tuple containing 4 elements in this order: + OUTPUT: a tuple containing 4 elements in this order: 1. Ordered list of x-coordinates of values of keys in ``ll`` specified in ptsdict. @@ -378,17 +373,15 @@ def slp(M1, pos_dict=None, B=None): INPUT: - - ``M1`` -- A matroid. - - ``pos_dict`` -- (optional) A dictionary containing non loopy elements of - ``M`` as keys and their (x,y) positions. - as keys. While simplifying the matroid, all except one element in a - parallel class that is also specified in ``pos_dict`` will be retained. - - ``B`` -- (optional) A basis of M1 that has been chosen for placement on - vertices of triangle. - - OUTPUT: + - ``M1`` -- matroid + - ``pos_dict`` -- (optional) dictionary containing non loopy elements of + ``M`` as keys and their (x,y) positions as keys. While simplifying the + matroid, all except one element in a parallel class that is also + specified in ``pos_dict`` will be retained. + - ``B`` -- (optional) a basis of M1 that has been chosen for placement on + vertices of triangle - A tuple containing 3 elements in this order: + OUTPUT: a tuple containing 3 elements in this order: 1. Simple matroid corresponding to ``M1``. 2. Loops of matroid ``M1``. @@ -459,21 +452,19 @@ def addlp(M, M1, L, P, ptsdict, G=None, limits=None): INPUT: - - ``M`` -- A matroid. - - ``M1`` -- A simple matroid corresponding to ``M``. - - ``L`` -- List of elements in ``M.groundset()`` that are loops of matroid - ``M``. - - ``P`` -- List of elements in ``M.groundset()`` not in - ``M.simplify.groundset()`` or ``L``. - - ``ptsdict`` -- A dictionary containing elements in ``M.groundset()`` not - necessarily containing elements of ``L``. - - ``G`` -- (optional) A sage graphics object to which loops and parallel - elements of matroid `M` added . - - ``limits`` -- (optional) Current axes limits [xmin,xmax,ymin,ymax]. - - OUTPUT: + - ``M`` -- matroid + - ``M1`` -- a simple matroid corresponding to ``M`` + - ``L`` -- list of elements in ``M.groundset()`` that are loops of matroid + ``M`` + - ``P`` -- list of elements in ``M.groundset()`` not in + ``M.simplify.groundset()`` or ``L`` + - ``ptsdict`` -- dictionary containing elements in ``M.groundset()`` not + necessarily containing elements of ``L`` + - ``G`` -- (optional) a sage graphics object to which loops and parallel + elements of matroid `M` added + - ``limits`` -- (optional) current axes limits [xmin,xmax,ymin,ymax] - A 2-tuple containing: + OUTPUT: a 2-tuple containing: 1. A sage graphics object containing loops and parallel elements of matroid ``M`` @@ -562,18 +553,16 @@ def addlp(M, M1, L, P, ptsdict, G=None, limits=None): def line_hasorder(l, lodrs=None): """ - Determine if an order is specified for a line + Determine if an order is specified for a line. INPUT: - - ``l`` -- A line specified as a list of ground set elements. - - ``lordrs`` -- (optional) A list of lists each specifying an order on + - ``l`` -- a line specified as a list of ground set elements + - ``lordrs`` -- (optional) list of lists each specifying an order on a subset of ground set elements that may or may not correspond to a - line in geometric representation. + line in geometric representation - OUTPUT: - - A tuple containing 2 elements in this order: + OUTPUT: a tuple containing 2 elements in this order: 1. A boolean indicating whether there is any list in ``lordrs`` that is setwise equal to ``l``. @@ -610,10 +599,10 @@ def lineorders_union(lineorders1, lineorders2): INPUT: - - ``lineorders1`` -- A list of ordered lists specifying orders on subsets - of ground set. - - ``lineorders2`` -- A list of ordered lists specifying orders subsets of - ground set. + - ``lineorders1`` -- list of ordered lists specifying orders on subsets + of ground set + - ``lineorders2`` -- list of ordered lists specifying orders subsets of + ground set OUTPUT: @@ -650,9 +639,9 @@ def posdict_is_sane(M1, pos_dict): INPUT: - - ``M1`` -- A matroid. - - ``posdict`` -- A dictionary mapping ground set elements to (x,y) - positions. + - ``M1`` -- matroid + - ``posdict`` -- dictionary mapping ground set elements to (x,y) + positions OUTPUT: @@ -700,13 +689,11 @@ def tracklims(lims, x_i=[], y_i=[]): INPUT: - - ``lims`` -- A list with 4 elements ``[xmin,xmax,ymin,ymax]`` - - ``x_i`` -- New x values to track - - ``y_i`` -- New y values to track - - OUTPUT: + - ``lims`` -- list with 4 elements ``[xmin,xmax,ymin,ymax]`` + - ``x_i`` -- new x values to track + - ``y_i`` -- new y values to track - A list with 4 elements ``[xmin,xmax,ymin,ymax]`` + OUTPUT: list with 4 elements ``[xmin,xmax,ymin,ymax]`` EXAMPLES:: @@ -735,18 +722,18 @@ def geomrep(M1, B1=None, lineorders1=None, pd=None, sp=False): INPUT: - - ``M1`` -- A matroid. - - ``B1`` -- (optional) A list of elements in ``M1.groundset()`` that + - ``M1`` -- matroid + - ``B1`` -- (optional) list of elements in ``M1.groundset()`` that correspond to a basis of ``M1`` and will be placed as vertices of the - triangle in the geometric representation of ``M1``. - - ``lineorders1`` -- (optional) A list of ordered lists of elements of + triangle in the geometric representation of ``M1`` + - ``lineorders1`` -- (optional) list of ordered lists of elements of ``M1.groundset()`` such that if a line in geometric representation is setwise same as any of these then points contained will be traversed in - that order thus overriding internal order deciding heuristic. - - ``pd`` -- (optional) A dictionary mapping ground set elements to their - (x,y) positions. - - ``sp`` -- (optional) If True, a positioning dictionary and line orders - will be placed in ``M._cached_info``. + that order thus overriding internal order deciding heuristic + - ``pd`` -- (optional) dictionary mapping ground set elements to their + (x,y) positions + - ``sp`` -- (optional) if ``True``, a positioning dictionary and line orders + will be placed in ``M._cached_info`` OUTPUT: @@ -867,9 +854,8 @@ def geomrep(M1, B1=None, lineorders1=None, pd=None, sp=False): trilines.extend(curvedlines) else: pts2 = M._cached_info['plot_positions'] - trilines = [list(set(list(x)).difference(L | P)) - for x in M1.flats(2) - if len(list(x)) >= 3] + trilines = [list(set(x).difference(L | P)) + for x in M1.flats(2) if len(list(x)) >= 3] pl = [list(x) for x in pts2.values()] lims = tracklims([None, None, None, None], [pt[0] for pt in pl], [pt[1] for pt in pl]) diff --git a/src/sage/matroids/meson.build b/src/sage/matroids/meson.build new file mode 100644 index 00000000000..43c80789811 --- /dev/null +++ b/src/sage/matroids/meson.build @@ -0,0 +1,56 @@ +py.install_sources( + 'advanced.py', + 'all.py', + 'basis_exchange_matroid.pxd', + 'basis_matroid.pxd', + 'catalog.py', + 'circuit_closures_matroid.pxd', + 'circuits_matroid.pxd', + 'constructor.py', + 'database_collections.py', + 'database_matroids.py', + 'dual_matroid.py', + 'extension.pxd', + 'flats_matroid.pxd', + 'graphic_matroid.pxd', + 'lean_matrix.pxd', + 'linear_matroid.pxd', + 'matroid.pxd', + 'matroids_catalog.py', + 'matroids_plot_helpers.py', + 'minor_matroid.py', + 'named_matroids.py', + 'rank_matroid.py', + 'set_system.pxd', + 'union_matroid.pxd', + 'utilities.py', + subdir: 'sage/matroids', +) + +extension_data = { + 'basis_exchange_matroid' : files('basis_exchange_matroid.pyx'), + 'basis_matroid' : files('basis_matroid.pyx'), + 'circuit_closures_matroid' : files('circuit_closures_matroid.pyx'), + 'circuits_matroid' : files('circuits_matroid.pyx'), + 'extension' : files('extension.pyx'), + 'lean_matrix' : files('lean_matrix.pyx'), + 'linear_matroid' : files('linear_matroid.pyx'), + 'matroid' : files('matroid.pyx'), + 'set_system' : files('set_system.pyx'), + 'union_matroid' : files('union_matroid.pyx'), + 'unpickling' : files('unpickling.pyx'), + 'flats_matroid' : files('flats_matroid.pyx'), + 'graphic_matroid' : files('graphic_matroid.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/matroids', + install: true, + include_directories: [inc_cpython, inc_data_structures, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 1b9860b401b..68cce818f8d 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -92,10 +92,10 @@ class wraps around any matroid to provide an abstract minor. It INPUT: - ``matroid`` -- matroid - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface + - ``contractions`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()``. + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` OUTPUT: @@ -169,9 +169,7 @@ def _rank(self, X): - ``X`` -- an object with Python's ``frozenset`` interface - OUTPUT: - - The rank of ``X`` in the matroid. + OUTPUT: the rank of ``X`` in the matroid EXAMPLES:: @@ -192,9 +190,7 @@ def _corank(self, X): - ``X`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - OUTPUT: - - The corank of ``X``. + OUTPUT: the corank of ``X`` EXAMPLES:: @@ -215,9 +211,7 @@ def _max_independent(self, X): - ``X`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - OUTPUT: - - A maximal independent subset of ``X``. + OUTPUT: a maximal independent subset of ``X`` EXAMPLES:: @@ -243,9 +237,7 @@ def _closure(self, X): - ``X`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - OUTPUT: - - The smallest closed set containing ``X``. + OUTPUT: the smallest closed set containing ``X`` EXAMPLES:: @@ -254,7 +246,6 @@ def _closure(self, X): ....: contractions=set('c'), deletions={'b', 'f'}) sage: sorted(M._closure(frozenset(['a', 'e', 'd']))) ['a', 'd', 'e', 'g', 'h'] - """ return self._matroid._closure(self._contractions.union(X)).difference(self._contractions.union(self._deletions)) @@ -267,9 +258,7 @@ def _max_coindependent(self, X): - ``X`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - OUTPUT: - - A maximal coindependent subset of ``X``. + OUTPUT: a maximal coindependent subset of ``X`` EXAMPLES:: @@ -295,9 +284,7 @@ def _coclosure(self, X): - ``X`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()`` - OUTPUT: - - The smallest coclosed set containing ``X``. + OUTPUT: the smallest coclosed set containing ``X`` EXAMPLES:: @@ -306,7 +293,6 @@ def _coclosure(self, X): ....: contractions=set('c'), deletions={'b', 'f'}) sage: sorted(M._coclosure(frozenset(['a', 'b', 'c']))) ['a', 'd', 'e', 'g', 'h'] - """ return self._matroid._coclosure(self._deletions.union(X)).difference(self._contractions.union(self._deletions)) diff --git a/src/sage/matroids/rank_matroid.py b/src/sage/matroids/rank_matroid.py index 88e72748c62..7fa20b131ba 100644 --- a/src/sage/matroids/rank_matroid.py +++ b/src/sage/matroids/rank_matroid.py @@ -66,13 +66,11 @@ class RankMatroid(Matroid): INPUT: - - ``groundset`` -- the groundset of a matroid. + - ``groundset`` -- the groundset of a matroid - ``rank_function`` -- a function mapping subsets of ``groundset`` to - nonnegative integers. + nonnegative integers - OUTPUT: - - A matroid on ``groundset`` whose rank function equals ``rank_function`` + OUTPUT: a matroid on ``groundset`` whose rank function equals ``rank_function`` EXAMPLES:: @@ -84,7 +82,6 @@ class RankMatroid(Matroid): True sage: M.is_isomorphic(matroids.Uniform(3, 6)) True - """ def __init__(self, groundset, rank_function): """ @@ -171,7 +168,7 @@ def __eq__(self, other): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid OUTPUT: @@ -212,7 +209,7 @@ def __ne__(self, other): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid OUTPUT: diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index e702edc6a69..d9a2f631fbf 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -165,9 +165,7 @@ cdef class SetSystem: - ``k`` -- integer; the index of the subset in the system - OUTPUT: - - The subset at index `k`. + OUTPUT: the subset at index `k` EXAMPLES:: @@ -215,7 +213,7 @@ cdef class SetSystem: - ``mapping`` -- a Python object such that ``mapping[e]`` is the new label of `e` - OUTPUT: ``None`` + OUTPUT: none """ cdef long i E = [] @@ -290,13 +288,13 @@ cdef class SetSystem: cdef inline _subset(self, long k): """ - Return the k-th subset, in index format. + Return the `k`-th subset, in index format. """ return bitset_list(self._subsets[k]) cdef subset(self, k): """ - Return the k-th subset. + Return the `k`-th subset. """ cdef long i F = set() @@ -525,11 +523,11 @@ cdef class SetSystem: OUTPUT: - - ``P``, an equitable ordered partition of the groundset, stored as a - SetSystem. - - ``EP``, the corresponding equitable partition of the edges, stored - as a list of lists of indices of subsets of this SetSystem. - - ``h``, an integer invariant of the SetSystem. + - ``P`` -- an equitable ordered partition of the groundset, stored as a + SetSystem + - ``EP`` -- the corresponding equitable partition of the edges, stored + as a list of lists of indices of subsets of this SetSystem + - ``h`` -- integer invariant of the SetSystem EXAMPLES:: @@ -635,15 +633,15 @@ cdef class SetSystem: INPUT: - - ``other`` -- a SetSystem - - ``SP`` (optional) -- a SetSystem storing an ordered partition of the + - ``other`` -- SetSystem + - ``SP`` -- (optional) SetSystem storing an ordered partition of the groundset of ``self`` - - ``OP`` (optional) -- a SetSystem storing an ordered partition of the + - ``OP`` -- (optional) SetSystem storing an ordered partition of the groundset of ``other`` OUTPUT: - ``morphism`` -- a dictionary containing an isomorphism respecting the + ``morphism`` -- dictionary containing an isomorphism respecting the given ordered partitions, or ``None`` if no such isomorphism exists. EXAMPLES:: @@ -698,10 +696,10 @@ cdef class SetSystem: - ``is_equiv`` -- a function that determines if a given groundset isomorphism is a valid equivalence - - ``other`` -- a SetSystem - - ``SP`` (optional) -- a SetSystem storing an ordered partition of the + - ``other`` -- SetSystem + - ``SP`` -- (optional) SetSystem storing an ordered partition of the groundset of ``self`` - - ``OP`` (optional) -- a SetSystem storing an ordered partition of the + - ``OP`` -- (optional) SetSystem storing an ordered partition of the groundset of ``other`` OUTPUT: diff --git a/src/sage/matroids/union_matroid.pxd b/src/sage/matroids/union_matroid.pxd index 518ca54bba9..6542629010e 100644 --- a/src/sage/matroids/union_matroid.pxd +++ b/src/sage/matroids/union_matroid.pxd @@ -1,20 +1,19 @@ from sage.matroids.matroid cimport Matroid - cdef class MatroidUnion(Matroid): cdef list matroids cdef frozenset _groundset cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 cdef class MatroidSum(Matroid): cdef list summands cdef frozenset _groundset cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 cdef class PartitionMatroid(Matroid): cdef dict p cdef frozenset _groundset cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except? -1 diff --git a/src/sage/matroids/union_matroid.pyx b/src/sage/matroids/union_matroid.pyx index 14097ad819b..e371d5fb313 100644 --- a/src/sage/matroids/union_matroid.pyx +++ b/src/sage/matroids/union_matroid.pyx @@ -55,9 +55,7 @@ cdef class MatroidUnion(Matroid): The groundset is the set of elements that comprise the matroid. - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -68,7 +66,7 @@ cdef class MatroidUnion(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: r""" Return the rank of a set ``X``. @@ -134,7 +132,7 @@ cdef class MatroidSum(Matroid): INPUT: - - ``matroids`` -- a iterator of matroids. + - ``matroids`` -- iterator of matroids OUTPUT: @@ -186,9 +184,7 @@ cdef class MatroidSum(Matroid): The groundset is the set of elements that comprise the matroid. - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -199,7 +195,7 @@ cdef class MatroidSum(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: r""" Return the rank of a set ``X``. @@ -242,7 +238,7 @@ cdef class PartitionMatroid(Matroid): INPUT: - - ``partition`` -- an iterator of disjoint sets. + - ``partition`` -- iterator of disjoint sets OUTPUT: @@ -283,9 +279,7 @@ cdef class PartitionMatroid(Matroid): The groundset is the set of elements that comprise the matroid. - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -296,7 +290,7 @@ cdef class PartitionMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except? -1: r""" Return the rank of a set ``X``. diff --git a/src/sage/matroids/unpickling.pyx b/src/sage/matroids/unpickling.pyx index 9e41c28a477..33fa9fe7dc1 100644 --- a/src/sage/matroids/unpickling.pyx +++ b/src/sage/matroids/unpickling.pyx @@ -56,14 +56,12 @@ def unpickle_basis_matroid(version, data): INPUT: - - ``version`` -- an integer, expected to be 0 - - ``data`` -- a tuple ``(E, R, name, BB)`` in which ``E`` is the groundset + - ``version`` -- integer; expected to be 0 + - ``data`` -- tuple ``(E, R, name, BB)`` in which ``E`` is the groundset of the matroid, ``R`` is the rank, ``name`` is a custom name, and ``BB`` is the bitpacked list of bases, as pickled by Sage's ``bitset_pickle``. - OUTPUT: - - A matroid. + OUTPUT: matroid .. WARNING:: @@ -104,14 +102,12 @@ def unpickle_circuits_matroid(version, data): INPUT: - - ``version`` -- an integer, expected to be 0 - - ``data`` -- a tuple ``(E, C, name)`` in which ``E`` is the groundset + - ``version`` -- integer; expected to be 0 + - ``data`` -- tuple ``(E, C, name)`` in which ``E`` is the groundset of the matroid, ``C`` is the list of circuits , and ``name`` is a custom name. - OUTPUT: - - A matroid. + OUTPUT: matroid .. WARNING:: @@ -147,14 +143,12 @@ def unpickle_circuit_closures_matroid(version, data): INPUT: - - ``version`` -- an integer, expected to be 0 - - ``data`` -- a tuple ``(E, CC, name)`` in which ``E`` is the groundset + - ``version`` -- integer; expected to be 0 + - ``data`` -- tuple ``(E, CC, name)`` in which ``E`` is the groundset of the matroid, ``CC`` is the dictionary of circuit closures, and ``name`` is a custom name. - OUTPUT: - - A matroid. + OUTPUT: matroid .. WARNING:: @@ -190,14 +184,12 @@ def unpickle_flats_matroid(version, data): INPUT: - - ``version`` -- an integer, expected to be 0 - - ``data`` -- a tuple ``(E, F, name)`` in which ``E`` is the groundset of + - ``version`` -- integer; expected to be 0 + - ``data`` -- tuple ``(E, F, name)`` in which ``E`` is the groundset of the matroid, ``F`` is the dictionary of flats, and ``name`` is a custom name. - OUTPUT: - - A matroid. + OUTPUT: matroid .. WARNING:: @@ -234,13 +226,11 @@ def unpickle_dual_matroid(version, data): INPUT: - - ``version`` -- an integer, expected to be 0 - - ``data`` -- a tuple ``(M, name)`` in which ``M`` is - the internal matroid, and ``name`` is a custom name. - - OUTPUT: + - ``version`` -- integer; expected to be 0 + - ``data`` -- tuple ``(M, name)`` in which ``M`` is + the internal matroid, and ``name`` is a custom name - A matroid. + OUTPUT: matroid .. WARNING:: @@ -462,15 +452,13 @@ def unpickle_linear_matroid(version, data): INPUT: - - ``version`` -- an integer (currently 0). - - ``data`` -- a tuple ``(A, E, reduced, name)`` where ``A`` is the + - ``version`` -- integer (currently 0) + - ``data`` -- tuple ``(A, E, reduced, name)`` where ``A`` is the representation matrix, ``E`` is the groundset of the matroid, ``reduced`` is a boolean indicating whether ``A`` is a reduced matrix, and ``name`` is a custom name. - OUTPUT: - - A :class:`LinearMatroid` instance. + OUTPUT: :class:`LinearMatroid` .. WARNING:: @@ -482,7 +470,7 @@ def unpickle_linear_matroid(version, data): ....: [0, 1, 1, 1, 3]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U35") + sage: M.rename('U35') sage: loads(dumps(M)) U35 """ @@ -509,14 +497,12 @@ def unpickle_binary_matroid(version, data): INPUT: - - ``version`` -- an integer (currently 0). - - ``data`` -- a tuple ``(A, E, B, name)`` where ``A`` is the + - ``version`` -- integer (currently 0) + - ``data`` -- tuple ``(A, E, B, name)`` where ``A`` is the representation matrix, ``E`` is the groundset of the matroid, ``B`` is the currently displayed basis, and ``name`` is a custom name. - OUTPUT: - - A :class:`BinaryMatroid` instance. + OUTPUT: :class:`BinaryMatroid` .. WARNING:: @@ -528,7 +514,7 @@ def unpickle_binary_matroid(version, data): ....: [0, 0, 1, 1]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U34") + sage: M.rename('U34') sage: loads(dumps(M)) U34 """ @@ -555,14 +541,12 @@ def unpickle_ternary_matroid(version, data): INPUT: - - ``version`` -- an integer (currently 0). - - ``data`` -- a tuple ``(A, E, B, name)`` where ``A`` is the + - ``version`` -- integer (currently 0) + - ``data`` -- tuple ``(A, E, B, name)`` where ``A`` is the representation matrix, ``E`` is the groundset of the matroid, ``B`` is the currently displayed basis, and ``name`` is a custom name. - OUTPUT: - - A :class:`TernaryMatroid` instance. + OUTPUT: :class:`TernaryMatroid` .. WARNING:: @@ -575,7 +559,7 @@ def unpickle_ternary_matroid(version, data): ....: [0, 0, 1, 1]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U34") + sage: M.rename('U34') sage: loads(dumps(M)) U34 """ @@ -602,14 +586,12 @@ def unpickle_quaternary_matroid(version, data): INPUT: - - ``version`` -- an integer (currently 0). - - ``data`` -- a tuple ``(A, E, B, name)`` where ``A`` is the + - ``version`` -- integer (currently 0) + - ``data`` -- tuple ``(A, E, B, name)`` where ``A`` is the representation matrix, ``E`` is the groundset of the matroid, ``B`` is the currently displayed basis, and ``name`` is a custom name. - OUTPUT: - - A :class:`TernaryMatroid` instance. + OUTPUT: :class:`TernaryMatroid` .. WARNING:: @@ -622,7 +604,7 @@ def unpickle_quaternary_matroid(version, data): ....: [0, 0, 1, 1]])) sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("U34") + sage: M.rename('U34') sage: loads(dumps(M)) U34 sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], # needs sage.rings.finite_rings @@ -654,15 +636,13 @@ def unpickle_regular_matroid(version, data): INPUT: - - ``version`` -- an integer (currently 0). - - ``data`` -- a tuple ``(A, E, reduced, name)`` where ``A`` is the + - ``version`` -- integer (currently 0) + - ``data`` -- tuple ``(A, E, reduced, name)`` where ``A`` is the representation matrix, ``E`` is the groundset of the matroid, ``reduced`` is a boolean indicating whether ``A`` is a reduced matrix, and ``name`` is a custom name. - OUTPUT: - - A :class:`RegularMatroid` instance. + OUTPUT: :class:`RegularMatroid` .. WARNING:: @@ -673,7 +653,7 @@ def unpickle_regular_matroid(version, data): sage: M = matroids.catalog.R10() sage: M == loads(dumps(M)) # indirect doctest True - sage: M.rename("R_{10}") + sage: M.rename('R_{10}') sage: loads(dumps(M)) R_{10} """ @@ -704,15 +684,13 @@ def unpickle_minor_matroid(version, data): INPUT: - - ``version`` -- an integer, currently `0`. - - ``data`` -- a tuple ``(M, C, D, name)``, where ``M`` is the original + - ``version`` -- integer; currently `0` + - ``data`` -- tuple ``(M, C, D, name)``, where ``M`` is the original matroid of which the output is a minor, ``C`` is the set of contractions, ``D`` is the set of deletions, and ``name`` is a custom name. - OUTPUT: - - A :class:`MinorMatroid` instance. + OUTPUT: :class:`MinorMatroid` .. WARNING:: @@ -747,12 +725,10 @@ def unpickle_graphic_matroid(version, data): INPUT: - - ``version`` -- an integer (currently 0). - - ``data`` -- a tuple consisting of a SageMath graph and a name. - - OUTPUT: + - ``version`` -- integer (currently 0) + - ``data`` -- tuple consisting of a SageMath graph and a name - A :class:`GraphicMatroid` instance. + OUTPUT: :class:`GraphicMatroid` .. WARNING:: diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index 0ab95bb02ec..c9b903594c5 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -48,11 +48,9 @@ def setprint(X): INPUT: - - ``X`` -- Any Python object - - OUTPUT: + - ``X`` -- any Python object - ``None``. However, the function prints a nice representation of ``X``. + OUTPUT: none; however, the function prints a nice representation of ``X`` EXAMPLES: @@ -93,8 +91,8 @@ def setprint_s(X, toplevel=False): INPUT: - ``X`` -- any Python object - - ``toplevel`` -- (default: ``False``) indicates whether this is a - recursion or not. + - ``toplevel`` -- boolean (default: ``False``); indicates whether this is a + recursion or not OUTPUT: @@ -139,11 +137,9 @@ def newlabel(groundset): INPUT: - - ``groundset`` -- A set of objects. + - ``groundset`` -- set of objects - OUTPUT: - - A string not in the set ``groundset``. + OUTPUT: string not in the set ``groundset`` For direct access to ``newlabel``, run:: @@ -188,13 +184,11 @@ def sanitize_contractions_deletions(matroid, contractions, deletions): INPUT: - ``matroid`` -- a :class:`Matroid ` - instance. - - ``contractions`` -- a subset of the groundset. - - ``deletions`` -- a subset of the groundset. + instance + - ``contractions`` -- a subset of the groundset + - ``deletions`` -- a subset of the groundset - OUTPUT: - - An independent set ``C`` and a coindependent set ``D`` such that + OUTPUT: an independent set ``C`` and a coindependent set ``D`` such that ``matroid / contractions \ deletions == matroid / C \ D`` @@ -251,7 +245,7 @@ def make_regular_matroid_from_matroid(matroid): INPUT: - - ``matroid`` -- a matroid. + - ``matroid`` -- matroid OUTPUT: @@ -328,7 +322,7 @@ def get_nonisomorphic_matroids(MSet): INPUT: - - ``MSet`` -- an iterable whose members are matroids. + - ``MSet`` -- an iterable whose members are matroids OUTPUT: @@ -364,12 +358,13 @@ def spanning_forest(M): INPUT: - ``M`` -- a matrix defining a bipartite graph G. The vertices are the - rows and columns, if `M[i,j]` is non-zero, then there is an edge + rows and columns, if `M[i,j]` is nonzero, then there is an edge between row `i` and column `j`. OUTPUT: - A list of tuples `(r_i,c_i)` representing edges between row `r_i` and column `c_i`. + A list of tuples `(r_i,c_i)` representing edges between row `r_i` and + column `c_i`. EXAMPLES:: @@ -408,12 +403,13 @@ def spanning_stars(M): INPUT: - ``M`` -- a matrix defining a bipartite graph G. The vertices are the - rows and columns, if `M[i,j]` is non-zero, then there is an edge + rows and columns, if `M[i,j]` is nonzero, then there is an edge between row i and column 0. OUTPUT: - A list of tuples `(row,column)` in a spanning forest of the bipartite graph defined by ``M`` + A list of tuples `(row,column)` in a spanning forest of the bipartite graph + defined by ``M``. EXAMPLES:: @@ -492,13 +488,12 @@ def lift_cross_ratios(A, lift_map=None): INPUT: - - ``A`` -- a matrix over a ring ``source_ring``. - - ``lift_map`` -- a Python dictionary, mapping each cross ratio of ``A`` to some element - of a target ring, and such that ``lift_map[source_ring(1)] = target_ring(1)``. - - OUTPUT: + - ``A`` -- a matrix over a ring ``source_ring`` + - ``lift_map`` -- a Python dictionary, mapping each cross ratio of ``A`` to + some element of a target ring, and such that + ``lift_map[source_ring(1)] = target_ring(1)`` - - ``Z`` -- a matrix over the ring ``target_ring``. + OUTPUT: ``Z`` -- a matrix over the ring ``target_ring`` The intended use of this method is to create a (reduced) matrix representation of a matroid ``M`` over a ring ``target_ring``, given a (reduced) matrix representation of @@ -670,11 +665,9 @@ def lift_map(target): INPUT: - - ``target`` -- a string describing the target (partial) field. - - OUTPUT: + - ``target`` -- string describing the target (partial) field - - a dictionary + OUTPUT: dictionary Depending on the value of ``target``, the following lift maps will be created: @@ -750,11 +743,11 @@ def split_vertex(G, u, v=None, edges=None): INPUT: - - ``G`` -- A SageMath :class:`Graph`. - - ``u`` -- A vertex in ``G``. - - ``v`` -- (optional) The name of the new vertex after the splitting. If + - ``G`` -- a SageMath :class:`Graph` + - ``u`` -- a vertex in ``G`` + - ``v`` -- (optional) the name of the new vertex after the splitting. If ``v`` is specified and already in the graph, it must be an isolated vertex. - - ``edges`` -- (optional) An iterable container of edges on ``u`` that + - ``edges`` -- (optional) iterable container of edges on ``u`` that move to ``v`` after the splitting. If ``None``, ``v`` will be an isolated vertex. The edge labels must be specified. diff --git a/src/sage/meson.build b/src/sage/meson.build new file mode 100644 index 00000000000..687ac549c10 --- /dev/null +++ b/src/sage/meson.build @@ -0,0 +1,145 @@ +fs = import('fs') +sage_install_dir = py.get_install_dir() / 'sage' + +# Generate the configuration file +conf_data = configuration_data() +conf_data.set('PACKAGE_VERSION', '1.2.3') +conf_data.set('SAGE_ROOT', meson.current_source_dir() / '..' / '..') +# We use Python's prefix here to make it work with conda +prefix = py.get_variable('prefix', '') +conf_data.set('prefix', prefix) +datadir = fs.expanduser(get_option('datadir')) +if not fs.is_absolute(datadir) + datadir = prefix / datadir +endif +conf_data.set('SAGE_SHARE', datadir) +if not fs.exists(datadir / 'cremona') + message( + 'Warning: The specified datadir does not contain the necessary Cremona database. Either specify a different datadir or specify a correct the correct path via the environment variable SAGE_SHARE during runtime.', + ) +endif +conf_data.set('SAGE_MAXIMA', maxima.full_path()) +# Conda's ecl does not have any problems with Maxima, so nothing needs to be set here: +conf_data.set('SAGE_MAXIMA_FAS', '') +# Kenzo cannot yet be provided by the system, so we always use the SAGE_LOCAL path for now. +conf_data.set('SAGE_KENZO_FAS', '\'${prefix}\'/lib/ecl/kenzo.fas') +# It can be found, so we don't have to set anything here: +conf_data.set('NTL_INCDIR', '') +conf_data.set('NTL_LIBDIR', '') +ecl_config = find_program('ecl-config', required: true) +conf_data.set('SAGE_ECL_CONFIG', ecl_config.full_path()) +conf_data.set('SAGE_ARCHFLAGS', 'unset') +# not needed when using conda, as we then don't build any pc files +conf_data.set('SAGE_PKG_CONFIG_PATH', '') +openmp = dependency('openmp', required: false, disabler: true) +if openmp.found() + conf_data.set('OPENMP_CFLAGS', '-fopenmp') + conf_data.set('OPENMP_CXXFLAGS', '-fopenmp') +endif +gap_exe = find_program('gap') +if gap_exe.found() + gaprun = run_command( + gap_exe, + '-r', + '-q', + '--bare', + '--nointeract', + '-c', + 'Display(JoinStringsWithSeparator(GAPInfo.RootPaths,";"));', + check: true, + ) + gap_root_paths = gaprun.stdout().strip() + gap_root_paths = '${prefix}/lib/gap;${prefix}/share/gap;' + gaprun.stdout().strip() +endif +conf_data.set('GAP_ROOT_PATHS', gap_root_paths) +ecm_bin = find_program(['ecm', 'gmp-ecm'], required: true) +conf_data.set('SAGE_ECMBIN', ecm_bin.full_path()) + +config_file = configure_file( + input: '../../pkgs/sage-conf_conda/_sage_conf/_conf.py.in', + output: 'config.py', + install_dir: py.get_install_dir() / 'sage', + install: true, + configuration: conf_data, +) + +# Packages that need no processing and can be installed directly +no_processing = [ + 'databases', + 'doctest', + 'ext_data', + 'features', + 'game_theory', + 'homology', + 'knots', + 'logic', + 'manifolds', + 'parallel', + 'repl', + 'sandpiles', + 'tensor', + 'topology', + 'typeset', +] +foreach package : no_processing + install_subdir(package, install_dir: sage_install_dir) +endforeach + +py.install_sources( + config_file, + 'all.py', + 'all__sagemath_bliss.py', + 'all__sagemath_categories.py', + 'all__sagemath_coxeter3.py', + 'all__sagemath_environment.py', + 'all__sagemath_mcqd.py', + 'all__sagemath_meataxe.py', + 'all__sagemath_objects.py', + 'all__sagemath_repl.py', + 'all__sagemath_sirocco.py', + 'all__sagemath_tdlib.py', + 'all_cmdline.py', + 'env.py', + 'version.py', + subdir: 'sage', +) + +subdir('cpython') +subdir('libs') +subdir('misc') +subdir('structure') +subdir('algebras') +subdir('arith') +subdir('ext') +subdir('calculus') +subdir('categories') +subdir('coding') +subdir('combinat') +subdir('crypto') +subdir('data_structures') +subdir('functions') +subdir('games') +subdir('geometry') +subdir('graphs') +subdir('groups') +subdir('interacts') +subdir('interfaces') +subdir('lfunctions') +subdir('matrix') +subdir('matroids') +subdir('modular') +subdir('modules') +subdir('monoids') +subdir('numerical') +subdir('plot') +subdir('probability') +subdir('quadratic_forms') +subdir('quivers') +subdir('rings') +subdir('schemes') +subdir('sets') +subdir('stats') +subdir('symbolic') +subdir('tests') +subdir('dynamics') +subdir('sat') diff --git a/src/sage/misc/abstract_method.py b/src/sage/misc/abstract_method.py index a169c455ef1..fad6f3097f2 100644 --- a/src/sage/misc/abstract_method.py +++ b/src/sage/misc/abstract_method.py @@ -14,12 +14,12 @@ def abstract_method(f=None, optional=False): r""" - Abstract methods + Abstract methods. INPUT: - - ``f`` -- a function - - ``optional`` -- a boolean; defaults to ``False`` + - ``f`` -- a function + - ``optional`` -- boolean (default: ``False``) The decorator :obj:`abstract_method` can be used to declare methods that should be implemented by all concrete derived @@ -49,7 +49,7 @@ def abstract_method(f=None, optional=False): sage: A.my_method - The current policy is that a :class:`NotImplementedError` is raised + The current policy is that a :exc:`NotImplementedError` is raised when accessing the method through an instance, even before the method is called:: @@ -142,7 +142,7 @@ def abstract_method(f=None, optional=False): class AbstractMethod: def __init__(self, f, optional=False): """ - Constructor for abstract methods + Constructor for abstract methods. EXAMPLES:: @@ -184,7 +184,7 @@ def __repr__(self): def _sage_src_lines_(self): r""" - Returns the source code location for the wrapped function. + Return the source code location for the wrapped function. EXAMPLES:: @@ -201,7 +201,7 @@ def _sage_src_lines_(self): def __get__(self, instance, cls): """ - Implements the attribute access protocol. + Implement the attribute access protocol. EXAMPLES:: @@ -222,7 +222,7 @@ def __get__(self, instance, cls): def is_optional(self): """ - Returns whether an abstract method is optional or not. + Return whether an abstract method is optional or not. EXAMPLES:: @@ -242,7 +242,7 @@ def is_optional(self): def abstract_methods_of_class(cls): """ - Returns the required and optional abstract methods of the class + Return the required and optional abstract methods of the class. EXAMPLES:: diff --git a/src/sage/misc/banner.py b/src/sage/misc/banner.py index 790a4fcccb9..af46d711721 100644 --- a/src/sage/misc/banner.py +++ b/src/sage/misc/banner.py @@ -20,9 +20,7 @@ def version(): """ Return the version of Sage. - OUTPUT: - - str + OUTPUT: string EXAMPLES:: @@ -90,7 +88,7 @@ def banner(): """ Print the Sage banner. - OUTPUT: None + OUTPUT: none If the environment variable ``SAGE_BANNER`` is set to ``no``, no banner is displayed. If ``SAGE_BANNER`` is set to ``bare``, a @@ -125,13 +123,7 @@ def version_dict(): """ A dictionary describing the version of Sage. - INPUT: - - nothing - - OUTPUT: - - dictionary with keys 'major', 'minor', 'tiny', 'prerelease' + OUTPUT: dictionary with keys 'major', 'minor', 'tiny', 'prerelease' This process the Sage version string and produces a dictionary. It expects the Sage version to be in one of these forms:: @@ -188,19 +180,18 @@ def version_dict(): def require_version(major, minor=0, tiny=0, prerelease=False, print_message=False): """ - True if Sage version is at least major.minor.tiny. + Return ``True`` if Sage version is at least ``major.minor.tiny``. INPUT: - - major -- integer - - minor -- integer (default: 0) - - tiny -- float (default: 0) - - prerelease -- boolean (default: ``False``) - - print_message -- boolean (default: ``False``) - - OUTPUT: + - ``major`` -- integer + - ``minor`` -- integer (default: 0) + - ``tiny`` -- float (default: 0) + - ``prerelease`` -- boolean (default: ``False``) + - ``print_message`` -- boolean (default: ``False``) - True if major.minor.tiny is <= version of Sage, False otherwise + OUTPUT: ``True`` if ``major.minor.tiny`` is <= version of Sage, ``False`` + otherwise For example, if the Sage version number is 3.1.2, then require_version(3, 1, 3) will return False, while @@ -212,7 +203,7 @@ def require_version(major, minor=0, tiny=0, prerelease=False, if the optional argument prerelease is True, then a prerelease version of Sage counts as if it were the released version. - If optional argument print_message is True and this function + If optional argument print_message is ``True`` and this function is returning False, print a warning message. EXAMPLES:: diff --git a/src/sage/misc/benchmark.py b/src/sage/misc/benchmark.py index 66b673a6fa0..4b9aa1e8b70 100644 --- a/src/sage/misc/benchmark.py +++ b/src/sage/misc/benchmark.py @@ -12,8 +12,8 @@ def benchmark(n=-1): INPUT: - n -- int (default: -1) the benchmark number; the default - of -1 runs all the benchmarks. + - ``n`` -- integer (default: -1); the benchmark number; the default + of -1 runs all the benchmarks OUTPUT: @@ -50,7 +50,6 @@ def benchmark(n=-1): Compute the Mordell-Weil group of y^2 = x^3 + 37*x - 997. Time: ... seconds Running benchmark 8 - """ if isinstance(n, list): @@ -90,7 +89,6 @@ def bench0(): sage: print(bench0()[0]) Benchmark 0: Factor the following polynomial over the rational numbers: (x^97+19*x+1)*(x^103-19*x^97+14)*(x^100-1) - """ desc = """Benchmark 0: Factor the following polynomial over the rational numbers: (x^97+19*x+1)*(x^103-19*x^97+14)*(x^100-1)""" @@ -110,7 +108,6 @@ def bench1(): sage: from sage.misc.benchmark import * sage: print(bench1()[0]) Find the Mordell-Weil group of the elliptic curve 5077A using mwrank - """ desc = """Find the Mordell-Weil group of the elliptic curve 5077A using mwrank""" E = mwrank_EllipticCurve([0, 0, 1, -7, 6]) @@ -128,7 +125,6 @@ def bench2(): sage: from sage.misc.benchmark import * sage: print(bench2()[0]) Some basic arithmetic with very large Integer numbers: '3^1000001 * 19^100001 - """ desc = """Some basic arithmetic with very large Integer numbers: '3^1000001 * 19^100001""" t = cputime() @@ -145,7 +141,6 @@ def bench3(): sage: from sage.misc.benchmark import * sage: print(bench3()[0]) Some basic arithmetic with very large Rational numbers: '(2/3)^100001 * (17/19)^100001 - """ desc = """Some basic arithmetic with very large Rational numbers: '(2/3)^100001 * (17/19)^100001""" t = cputime() @@ -162,7 +157,6 @@ def bench4(): sage: from sage.misc.benchmark import * sage: print(bench4()[0]) Rational polynomial arithmetic using Sage. Compute (x^29+17*x-5)^200. - """ desc = """Rational polynomial arithmetic using Sage. Compute (x^29+17*x-5)^200.""" x = PolynomialRing(QQ, 'x').gen() @@ -181,7 +175,6 @@ def bench5(): sage: from sage.misc.benchmark import * sage: print(bench5()[0]) Rational polynomial arithmetic using Sage. Compute (x^19 - 18*x + 1)^50 one hundred times. - """ desc = """Rational polynomial arithmetic using Sage. Compute (x^19 - 18*x + 1)^50 one hundred times.""" x = PolynomialRing(QQ, 'x').gen() @@ -200,7 +193,6 @@ def bench6(): sage: from sage.misc.benchmark import * sage: print(bench6()[0]) Compute the p-division polynomials of y^2 = x^3 + 37*x - 997 for primes p < 40. - """ desc = """Compute the p-division polynomials of y^2 = x^3 + 37*x - 997 for primes p < 40.""" E = EllipticCurve([0, 0, 0, 37, -997]) @@ -219,7 +211,6 @@ def bench7(): sage: from sage.misc.benchmark import * sage: print(bench7()[0]) Compute the Mordell-Weil group of y^2 = x^3 + 37*x - 997. - """ desc = """Compute the Mordell-Weil group of y^2 = x^3 + 37*x - 997.""" E = EllipticCurve([0, 0, 0, 37, -997]) diff --git a/src/sage/misc/binary_tree.pyx b/src/sage/misc/binary_tree.pyx index 511e7622faa..583e397a845 100644 --- a/src/sage/misc/binary_tree.pyx +++ b/src/sage/misc/binary_tree.pyx @@ -438,7 +438,7 @@ cdef class BinaryTree: """ return self.head == NULL - def keys(BinaryTree self, order="inorder"): + def keys(BinaryTree self, order='inorder'): """ Return the keys sorted according to "order" parameter. @@ -457,7 +457,7 @@ cdef class BinaryTree: return binary_tree_list(self.head, LIST_KEYS + o) - def values(BinaryTree self, order="inorder"): + def values(BinaryTree self, order='inorder'): """ Return the keys sorted according to "order" parameter. diff --git a/src/sage/misc/bindable_class.py b/src/sage/misc/bindable_class.py index d9cfa536dc9..743b5a19da6 100644 --- a/src/sage/misc/bindable_class.py +++ b/src/sage/misc/bindable_class.py @@ -18,7 +18,7 @@ class BindableClass(metaclass=ClasscallMetaclass): """ - Bindable classes + Bindable classes. This class implements a binding behavior for nested classes that derive from it. Namely, if a nested class ``Outer.Inner`` derives @@ -100,7 +100,7 @@ class BindableClass(metaclass=ClasscallMetaclass): sage: outer.Inner > - .. note:: + .. NOTE:: This is not actually a class, but an instance of :class:`functools.partial`:: @@ -125,7 +125,7 @@ class BindableClass(metaclass=ClasscallMetaclass): @staticmethod def __classget__(cls, instance, owner): """ - Binds ``cls`` to ``instance``, returning a ``BoundClass`` + Bind ``cls`` to ``instance``, returning a ``BoundClass``. INPUT: diff --git a/src/sage/misc/c3.pyx b/src/sage/misc/c3.pyx index a3f37380faf..bd8057b361f 100644 --- a/src/sage/misc/c3.pyx +++ b/src/sage/misc/c3.pyx @@ -45,10 +45,10 @@ cpdef list C3_algorithm(object start, str bases, str attribute, bint proper): INPUT: - ``start`` -- an object; the returned list is built upon data - provided by certain attributes of ``start``. - - ``bases`` -- a string; the name of an attribute of ``start`` - providing a list of objects. - - ``attribute`` -- a string; the name of an attribute of the + provided by certain attributes of ``start`` + - ``bases`` -- string; the name of an attribute of ``start`` + providing a list of objects + - ``attribute`` -- string; the name of an attribute of the objects provided in ``getattr(start,bases)``. That attribute is supposed to provide a list. diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 5787505313c..81f66f0c680 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -155,7 +155,7 @@ class as its bases. However, this would have several drawbacks: point of truth for calculating the bases of each class. - It increases the complexity of the calculation of the MRO with - ``C3``. For example, for a linear hierachy of classes, the + ``C3``. For example, for a linear hierarchy of classes, the complexity goes from `O(n^2)` to `O(n^3)` which is not acceptable. - It increases the complexity of inspecting the classes. For example, @@ -496,7 +496,7 @@ cdef class CmpKey: def __init__(self): """ - Sets the internal category counter to zero. + Set the internal category counter to zero. EXAMPLES:: @@ -507,7 +507,7 @@ cdef class CmpKey: def __get__(self, object inst, object cls): """ - Bind the comparison key to the given instance + Bind the comparison key to the given instance. EXAMPLES:: @@ -555,7 +555,6 @@ cdef class CmpKeyNamed: True sage: Algebras(ZZ)._cmp_key != Algebras(GF(5))._cmp_key True - """ def __get__(self, object inst, object cls): """ @@ -565,7 +564,6 @@ cdef class CmpKeyNamed: True sage: Algebras(ZZ)._cmp_key != Algebras(GF(5))._cmp_key True - """ cdef dict D = cls._make_named_class_cache cdef str name = "_cmp_key" @@ -626,11 +624,11 @@ def C3_merge(list lists): cdef bint next_item_found while nbheads: - for i in range(nbheads): # from 0 <= i < nbheads: + for i in range(nbheads): O = heads[i] # Does O appear in none of the tails? ``all(O not in tail for tail in tailsets)`` next_item_found = True - for j in range(nbheads): #from 0 <= j < nbheads: + for j in range(nbheads): if j == i: continue tailset = tailsets[j] @@ -642,7 +640,7 @@ def C3_merge(list lists): # Clear O from other heads, removing the line altogether # if the tail is already empty. # j goes down so that ``del heads[j]`` does not screw up the numbering - for j in range(nbheads-1, -1, -1): # from nbheads > j >= 0: + for j in range(nbheads-1, -1, -1): if heads[j] == O: # is O tail = tails[j] if tail: @@ -862,7 +860,7 @@ cpdef tuple C3_sorted_merge(list lists, key=identity): # Find the position of the largest head which will become the next item max_i = 0 max_key = key(heads[0]) - for i in range(1, nbheads): #from 1 <= i < nbheads: + for i in range(1, nbheads): O = heads[i] O_key = key(O) if O_key > max_key: @@ -872,14 +870,14 @@ cpdef tuple C3_sorted_merge(list lists, key=identity): # Find all the bad choices max_bad = None - for i in range(max_i): #from 0 <= i < max_i: + for i in range(max_i): O = heads[i] # Does O appear in none of the tails? O_key = key(O) # replace the closure # if any(O_key in tailsets[j] for j in range(nbheads) if j != i): continue cont = False - for j from 0<=j j >= 0: + for j in range(nbheads-1, -1, -1): if heads[j] == max_value: tail = tails[j] if tail: @@ -992,7 +990,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES: See the introduction of this module :mod:`sage.misc.c3_controlled` - for many examples. Here we consider a large example, originaly + for many examples. Here we consider a large example, originally taken from the hierarchy of categories above :class:`HopfAlgebrasWithBasis`:: @@ -1055,7 +1053,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , <... 'object'>] """ @staticmethod - def __classcall__(cls, value, succ, key = None): + def __classcall__(cls, value, succ, key=None): """ EXAMPLES:: @@ -1208,7 +1206,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): @lazy_attribute def _bases_controlled(self): """ - A list of bases controlled by :meth:`C3_sorted_merge` + A list of bases controlled by :meth:`C3_sorted_merge`. This triggers the calculation of the MRO using :meth:`C3_sorted_merge`, which sets this attribute as a side @@ -1231,7 +1229,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): @lazy_attribute def mro_standard(self): """ - The MRO for this object, calculated with :meth:`C3_merge` + The MRO for this object, calculated with :meth:`C3_merge`. EXAMPLES:: diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 597dfc5d049..f78b390e031 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -468,9 +468,9 @@ def _cached_function_unpickle(module, name, cache=None): INPUT: - - ``module`` -- the name of the module to import the function from. - - ``name`` -- the name of the cached function. - - ``cache`` -- a list of cached key value pairs. + - ``module`` -- the name of the module to import the function from + - ``name`` -- the name of the cached function + - ``cache`` -- list of cached key value pairs TESTS:: @@ -499,7 +499,6 @@ def _cached_function_unpickle(module, name, cache=None): True sage: f(0) 0 - """ ret = getattr(__import__(module, fromlist=['']),name) if cache is not None: @@ -518,7 +517,6 @@ cdef class NonpicklingDict(dict): sage: d[0] = 0 sage: loads(dumps(d)) {} - """ def __reduce__(self): r""" @@ -531,7 +529,6 @@ cdef class NonpicklingDict(dict): sage: d[0] = 0 sage: d.__reduce__() (, ()) - """ return NonpicklingDict, () @@ -679,9 +676,9 @@ cdef class CachedFunction(): caching. In this example we ignore the parameter ``algorithm``:: sage: @cached_function(key=lambda x,y,algorithm: (x,y)) - ....: def mul(x, y, algorithm="default"): + ....: def mul(x, y, algorithm='default'): ....: return x*y - sage: mul(1,1,algorithm="default") is mul(1,1,algorithm="algorithm") is mul(1,1) is mul(1,1,'default') + sage: mul(1,1,algorithm='default') is mul(1,1,algorithm='algorithm') is mul(1,1) is mul(1,1,'default') True """ def __init__(self, f, *, classmethod=False, name=None, key=None, do_pickle=None): @@ -752,7 +749,6 @@ cdef class CachedFunction(): sage: f = loads(s) sage: len(f.cache) 100 - """ self.is_classmethod = classmethod self._common_init(f, None, name=name, key=key, do_pickle=do_pickle) @@ -824,7 +820,7 @@ cdef class CachedFunction(): TESTS:: sage: @cached_function(key=lambda x,y,algorithm: (x,y)) - ....: def mul(x, y, algorithm="default"): + ....: def mul(x, y, algorithm='default'): ....: return x*y sage: mul.get_key(1,1,"default") # indirect doctest (1, 1) @@ -913,7 +909,7 @@ cdef class CachedFunction(): def _sage_src_(self): """ - Returns the source code for the wrapped function. + Return the source code for the wrapped function. TESTS:: @@ -921,14 +917,13 @@ cdef class CachedFunction(): sage: g = CachedFunction(number_of_partitions) # needs sage.combinat sage: 'flint' in sage_getsource(g) # indirect doctest # needs sage.combinat True - """ from sage.misc.sageinspect import sage_getsource return sage_getsource(self.f) def _sage_src_lines_(self): r""" - Returns the list of source lines and the first line number + Return the list of source lines and the first line number of the wrapped function. TESTS:: @@ -939,7 +934,6 @@ cdef class CachedFunction(): sage: l = ' elif algorithm.startswith("macaulay2:"):\n' sage: l in sage_getsourcelines(I.groebner_basis)[0] # indirect doctest True - """ from sage.misc.sageinspect import sage_getsourcelines return sage_getsourcelines(self.f) @@ -959,7 +953,6 @@ cdef class CachedFunction(): FullArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], varargs='args', varkw='kwds', defaults=('', None, None, False), kwonlyargs=[], kwonlydefaults=None, annotations={}) - """ return sage_getargspec(self.f) @@ -1001,7 +994,6 @@ cdef class CachedFunction(): True sage: f(y) is not f(x) True - """ k = self.get_key_args_kwds(args, kwds) @@ -1019,7 +1011,7 @@ cdef class CachedFunction(): def cached(self, *args, **kwds): """ Return the result from the cache if available. If the value is - not cached, raise ``KeyError``. + not cached, raise :exc:`KeyError`. EXAMPLES:: @@ -1045,7 +1037,7 @@ cdef class CachedFunction(): def is_in_cache(self, *args, **kwds): """ - Checks if the argument list is in the cache. + Check if the argument list is in the cache. EXAMPLES:: @@ -1081,7 +1073,6 @@ cdef class CachedFunction(): 1 + O(2) sage: f.is_in_cache(x) True - """ k = self.get_key_args_kwds(args, kwds) try: @@ -1236,7 +1227,7 @@ cdef class CachedFunction(): INPUT: - ``arglist`` -- list (or iterables) of arguments for which - the method shall be precomputed. + the method shall be precomputed - ``num_processes`` -- number of processes used by :func:`~sage.parallel.decorate.parallel` @@ -1331,9 +1322,9 @@ cdef class WeakCachedFunction(CachedFunction): caching. In this example we ignore the parameter ``algorithm``:: sage: @weak_cached_function(key=lambda x,algorithm: x) - ....: def mod_ring(x, algorithm="default"): + ....: def mod_ring(x, algorithm='default'): ....: return IntegerModRing(x) - sage: mod_ring(1,algorithm="default") is mod_ring(1,algorithm="algorithm") is mod_ring(1) is mod_ring(1,'default') + sage: mod_ring(1,algorithm='default') is mod_ring(1,algorithm='algorithm') is mod_ring(1) is mod_ring(1,'default') True TESTS: @@ -1557,9 +1548,9 @@ class CachedMethodPickle(): """ INPUT: - - ``inst`` -- some instance. - - ``name`` (string) -- usually the name of an attribute - of ``inst`` to which ``self`` is assigned. + - ``inst`` -- some instance + - ``name`` -- string; usually the name of an attribute + of ``inst`` to which ``self`` is assigned TESTS:: @@ -1567,7 +1558,6 @@ class CachedMethodPickle(): sage: P = CachedMethodPickle(1, 'foo') sage: P Pickle of the cached method "foo" - """ self._instance = inst self._name = name @@ -1637,7 +1627,6 @@ class CachedMethodPickle(): [a, b] sage: J.gens Cached version of - """ self._instance.__dict__.__delitem__(self._name) CM = getattr(self._instance,self._name) @@ -1741,7 +1730,6 @@ cdef class CachedMethodCaller(CachedFunction): sage: b = loads(dumps(a)) sage: len(b.bar.cache) 1 - """ def __init__(self, CachedMethod cachedmethod, inst, *, cache=None, name=None, key=None, do_pickle=None): """ @@ -1763,7 +1751,7 @@ cdef class CachedMethodCaller(CachedFunction): """ # initialize CachedFunction. Since the cached method is actually bound # to an instance, it now makes sense to initialise the ArgumentFixer - # and re-use it for all bound cached method callers of the unbound + # and reuse it for all bound cached method callers of the unbound # cached method. if cachedmethod._cachedfunc._argument_fixer is None: cachedmethod._cachedfunc.argfix_init() @@ -1856,7 +1844,7 @@ cdef class CachedMethodCaller(CachedFunction): ....: @cached_method(key=_f_normalize) ....: def f(self, x, algorithm='default'): return x sage: a = A() - sage: a.f(1, algorithm="default") is a.f(1) is a.f(1, algorithm="algorithm") + sage: a.f(1, algorithm='default') is a.f(1) is a.f(1, algorithm='algorithm') True """ if self._argument_fixer is None: @@ -1950,7 +1938,6 @@ cdef class CachedMethodCaller(CachedFunction): True sage: a.f(y) is not a.f(x) True - """ if self._instance is None: # cached method bound to a class @@ -1975,7 +1962,7 @@ cdef class CachedMethodCaller(CachedFunction): def cached(self, *args, **kwds): """ Return the result from the cache if available. If the value is - not cached, raise ``KeyError``. + not cached, raise :exc:`KeyError`. EXAMPLES:: @@ -2057,7 +2044,7 @@ cdef class CachedMethodCaller(CachedFunction): True Any instance of ``Bar`` gets its own instance of - :class:`CachedMethodCaller``:: + :class:`CachedMethodCaller`:: sage: b1.f is b2.f False @@ -2090,7 +2077,6 @@ cdef class CachedMethodCaller(CachedFunction): -1 sage: b.f.cache {1: -1} - """ # This is for Parents or Elements that do not allow attribute assignment try: @@ -2110,7 +2096,7 @@ cdef class CachedMethodCaller(CachedFunction): pass try: if inst._cached_methods is None: - inst._cached_methods = {self._cachedmethod._cachedfunc.__name__ : Caller} + inst._cached_methods = {self._cachedmethod._cachedfunc.__name__: Caller} else: (inst._cached_methods)[self._cachedmethod._cachedfunc.__name__] = Caller except AttributeError: @@ -2126,7 +2112,7 @@ cdef class CachedMethodCaller(CachedFunction): INPUT: - ``arglist`` -- list (or iterables) of arguments for which - the method shall be precomputed. + the method shall be precomputed - ``num_processes`` -- number of processes used by :func:`~sage.parallel.decorate.parallel` @@ -2239,7 +2225,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): 4 sage: a.f.cache 4 - """ # initialize CachedFunction if isinstance(f,str): @@ -2310,7 +2295,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): False sage: I.gens._instance_call() == I.gens() True - """ return self.f(self._instance) @@ -2326,7 +2310,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): [a, b] sage: I.gens() is I.gens() True - """ if self.cache is None: f = self.f @@ -2364,7 +2347,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): sage: I.gens.set_cache(None) sage: I.gens() [a, b] - """ self.cache = value @@ -2388,7 +2370,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): sage: I.gens.clear_cache() sage: I.gens() [a, b] - """ self.cache = None @@ -2411,7 +2392,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): [x, y] sage: I.gens.is_in_cache() True - """ return self.cache is not None @@ -2463,7 +2443,7 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): Any instance of ``Bar`` gets its own instance of - :class:`CachedMethodCaller``:: + :class:`CachedMethodCaller`:: sage: b1.f is b2.f False @@ -2477,7 +2457,6 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): True sage: b2.f._instance is b2 True - """ # This is for Parents or Elements that do not allow attribute assignment try: @@ -2492,7 +2471,7 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): pass try: if inst._cached_methods is None: - inst._cached_methods = {self.__name__ : Caller} + inst._cached_methods = {self.__name__: Caller} else: (inst._cached_methods)[self.__name__] = Caller except AttributeError: @@ -2589,7 +2568,7 @@ cdef class CachedMethod(): ....: @cached_method(key=_f_normalize) ....: def f(self, x, algorithm='default'): return x sage: a = A() - sage: a.f(1, algorithm="default") is a.f(1) is a.f(1, algorithm="algorithm") + sage: a.f(1, algorithm='default') is a.f(1) is a.f(1, algorithm='algorithm') True The parameter ``do_pickle`` can be used to enable pickling of the cache. @@ -2641,7 +2620,6 @@ cdef class CachedMethod(): 1 sage: b.f() 1 - """ def __init__(self, f, name=None, key=None, do_pickle=None): """ @@ -2715,12 +2693,12 @@ cdef class CachedMethod(): def __call__(self, inst, *args, **kwds): """ - Call the cached method as a function on an instance + Call the cached method as a function on an instance. INPUT: - ``inst`` -- an instance on which the method is to be called - - Further positional or named arguments. + - further positional or named arguments EXAMPLES:: @@ -2781,7 +2759,6 @@ cdef class CachedMethod(): {((2,), ()): 4} sage: a._cache__f {((2,), ()): 4} - """ default = {} if self._cachedfunc.do_pickle else NonpicklingDict() try: @@ -2832,7 +2809,6 @@ cdef class CachedMethod(): 0 sage: a.f.cache {1: 0} - """ # This is for Parents or Elements that do not allow attribute assignment: cdef str name @@ -2876,7 +2852,7 @@ cdef class CachedMethod(): pass try: if inst._cached_methods is None: - inst._cached_methods = {name : Caller} + inst._cached_methods = {name: Caller} else: (inst._cached_methods)[name] = Caller except AttributeError: @@ -2928,7 +2904,6 @@ cdef class CachedSpecialMethod(CachedMethod): 5 sage: hash(c) 5 - """ def __get__(self, object inst, cls): """ @@ -2962,7 +2937,6 @@ cdef class CachedSpecialMethod(CachedMethod): 0 sage: a.__hash__.cache {1: 0} - """ # This is for Parents or Elements that do not allow attribute assignment: cdef str name @@ -3112,7 +3086,6 @@ def cached_method(f, name=None, key=None, do_pickle=None): sage: d = loads(dumps(c)) sage: hash(d) == hash(c) False - """ cdef str fname = name or f.__name__ if fname in special_method_names: @@ -3147,12 +3120,11 @@ cdef class CachedInParentMethod(CachedMethod): is assigned to must be hashable. Examples can be found at :mod:`~sage.misc.cachefunc`. - """ def __init__(self, f, name=None, key=None, do_pickle=None): """ - Constructs a new method with cache stored in the parent of the instance. + Construct a new method with cache stored in the parent of the instance. See also ``cached_method`` and ``cached_function``. @@ -3197,7 +3169,7 @@ cdef class CachedInParentMethod(CachedMethod): ....: @cached_in_parent_method(key=_f_normalize) ....: def f(self, x, algorithm='default'): return x sage: a = A() - sage: a.f(1, algorithm="default") is a.f(1) is a.f(1, algorithm="algorithm") + sage: a.f(1, algorithm='default') is a.f(1) is a.f(1, algorithm='algorithm') True Test that ``do_pickle`` works. Usually the contents of the cache are not @@ -3238,7 +3210,6 @@ cdef class CachedInParentMethod(CachedMethod): sage: b = loads(dumps(a)) sage: len(b.f.cache) 1 - """ self._cache_name = '_cache__' + 'element_' + (name or f.__name__) self._cachedfunc = CachedFunction(f, classmethod=True, name=name, key=key, do_pickle=do_pickle) @@ -3300,7 +3271,6 @@ cdef class CachedInParentMethod(CachedMethod): sage: a.f.cache is b.f.cache is c.f._cachedmethod._get_instance_cache(c) True - """ default = {} if self._cachedfunc.do_pickle else NonpicklingDict() if inst is None: @@ -3339,10 +3309,10 @@ class FileCache(): :class:`FileCache` is a dictionary-like class which stores keys and values on disk. The keys take the form of a tuple ``(A,K)`` - - ``A`` is a tuple of objects ``t`` where each ``t`` is an - exact object which is uniquely identified by a short string. + - ``A`` -- tuple of objects ``t`` where each ``t`` is an + exact object which is uniquely identified by a short string - - ``K`` is a tuple of tuples ``(s,v)`` where ``s`` is a valid + - ``K`` -- tuple of tuples ``(s,v)`` where ``s`` is a valid variable name and ``v`` is an exact object which is uniquely identified by a short string with letters [a-zA-Z0-9-._] @@ -3496,7 +3466,7 @@ class FileCache(): def clear(self): """ - Clear all key, value pairs from self and unlink the associated files + Clear all key, value pairs from ``self`` and unlink the associated files from the file cache. EXAMPLES:: @@ -3586,7 +3556,6 @@ class FileCache(): Traceback (most recent call last): ... KeyError: ((1, 2), (('a', 4), ('b', 2))) - """ from sage.misc.persist import load @@ -3609,7 +3578,7 @@ class FileCache(): def __setitem__(self, key, value): """ - Sets ``self[key] = value`` and stores both key and value on + Set ``self[key] = value`` and stores both key and value on disk. EXAMPLES:: @@ -3638,7 +3607,7 @@ class FileCache(): def __delitem__(self, key): """ - Delete the key,value pair from self and unlink the associated + Delete the ``key, value`` pair from ``self`` and unlink the associated files from the file cache. EXAMPLES:: diff --git a/src/sage/misc/call.py b/src/sage/misc/call.py index bc428a95115..6c52c331c3b 100644 --- a/src/sage/misc/call.py +++ b/src/sage/misc/call.py @@ -35,7 +35,7 @@ def __init__(self, name, args, kwds): def __call__(self, x, *args): """ - Gets the ``self.name`` method from ``x``, calls it with + Get the ``self.name`` method from ``x``, calls it with ``self.args`` and ``args`` as positional parameters and ``self.kwds`` as keyword parameters, and returns the result. @@ -76,7 +76,7 @@ def __repr__(self): def __eq__(self, other): """ - Equality testing + Equality testing. EXAMPLES:: @@ -91,7 +91,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Equality testing + Equality testing. EXAMPLES:: @@ -106,7 +106,7 @@ def __ne__(self, other): def __hash__(self): """ - Hash value + Hash value. This method tries to ensure that, when two ``attrcall`` objects are equal, they have the same hash value. @@ -151,11 +151,11 @@ def attrcall(name, *args, **kwds): INPUT: - - ``name`` -- a string of the name of the method you - want to call + - ``name`` -- string of the name of the method you + want to call - - ``args, kwds`` -- arguments and keywords to be passed - to the method + - ``args, kwds`` -- arguments and keywords to be passed + to the method EXAMPLES:: diff --git a/src/sage/misc/callable_dict.pyx b/src/sage/misc/callable_dict.pyx index f46998a35a4..6a133afa918 100644 --- a/src/sage/misc/callable_dict.pyx +++ b/src/sage/misc/callable_dict.pyx @@ -36,7 +36,7 @@ cdef class CallableDict(dict): sage: d('zwei') 2 - In case the input is not in the dictionary, a :class:`ValueError` + In case the input is not in the dictionary, a :exc:`ValueError` is raised, for consistency with the function call syntax:: sage: d[1] @@ -56,7 +56,7 @@ cdef class CallableDict(dict): - ``x`` -- any hashable object - A :class:`ValueError` is raised if ``x`` is not in ``self``. + A :exc:`ValueError` is raised if ``x`` is not in ``self``. TESTS:: diff --git a/src/sage/misc/citation.pyx b/src/sage/misc/citation.pyx index aca83edf22c..fbe932ba49a 100644 --- a/src/sage/misc/citation.pyx +++ b/src/sage/misc/citation.pyx @@ -57,7 +57,7 @@ def get_systems(cmd): INPUT: - - ``cmd`` -- a string to run + - ``cmd`` -- string to run .. WARNING:: diff --git a/src/sage/misc/classcall_metaclass.pyx b/src/sage/misc/classcall_metaclass.pyx index 691f7fec01e..150eace4b9a 100644 --- a/src/sage/misc/classcall_metaclass.pyx +++ b/src/sage/misc/classcall_metaclass.pyx @@ -119,7 +119,7 @@ cdef class ClasscallMetaclass(NestedClassMetaclass): def _set_classcall(cls, function): r""" - Change dynamically the classcall function for this class + Change dynamically the classcall function for this class. EXAMPLES:: @@ -400,7 +400,7 @@ cdef class ClasscallMetaclass(NestedClassMetaclass): def __contains__(cls, x): r""" - This method implements membership testing for a class + This method implements membership testing for a class. Let ``cls`` be a class in :class:`ClasscallMetaclass`, and consider a call of the form:: @@ -449,14 +449,14 @@ cdef class ClasscallMetaclass(NestedClassMetaclass): def typecall(pytype cls, *args, **kwds): r""" - Object construction + Object construction. This is a faster equivalent to ``type.__call__(cls, )``. INPUT: - - ``cls`` -- the class used for constructing the instance. It must be - a builtin type or a new style class (inheriting from :class:`object`). + - ``cls`` -- the class used for constructing the instance; it must be + a builtin type or a new style class (inheriting from :class:`object`) EXAMPLES:: diff --git a/src/sage/misc/classgraph.py b/src/sage/misc/classgraph.py index acddb183909..aa4aafe18fa 100644 --- a/src/sage/misc/classgraph.py +++ b/src/sage/misc/classgraph.py @@ -14,20 +14,22 @@ def class_graph(top, depth=5, name_filter=None, classes=None, as_graph=True): """ - Return the class inheritance graph of a module, class, or object + Return the class inheritance graph of a module, class, or object. INPUT: - - ``top`` -- the module, class, or object to start with (e.g. ``sage``, ``Integer``, ``3``) - - ``depth`` -- maximal recursion depth within submodules (default: 5) - - ``name_filter`` -- e.g. 'sage.rings' to only consider classes in :mod:`sage.rings` - - ``classes`` -- optional dictionary to be filled in (it is also returned) - - ``as_graph`` -- a boolean (default: ``True``) + - ``top`` -- the module, class, or object to start with (e.g. ``sage``, + ``Integer``, ``3``) + - ``depth`` -- maximal recursion depth within submodules (default: 5) + - ``name_filter`` -- e.g. 'sage.rings' to only consider classes in + :mod:`sage.rings` + - ``classes`` -- (optional) dictionary to be filled in (it is also returned) + - ``as_graph`` -- boolean (default: ``True``) OUTPUT: - - An oriented graph, with class names as vertices, and an edge - from each class to each of its bases. + An oriented graph, with class names as vertices, and an edge + from each class to each of its bases. EXAMPLES: @@ -70,10 +72,10 @@ def class_graph(top, depth=5, name_filter=None, classes=None, as_graph=True): 'Polynomial_padic'], 'Polynomial_padic_flat': ['Polynomial_generic_dense', 'Polynomial_padic']} - .. note:: the ``classes`` and ``as_graph`` options are mostly + .. NOTE:: the ``classes`` and ``as_graph`` options are mostly intended for internal recursive use. - .. note:: ``class_graph`` does not yet handle nested classes + .. NOTE:: ``class_graph`` does not yet handle nested classes TESTS:: diff --git a/src/sage/misc/compat.py b/src/sage/misc/compat.py index 32a4f240a41..5f27aea06a0 100644 --- a/src/sage/misc/compat.py +++ b/src/sage/misc/compat.py @@ -56,7 +56,7 @@ def _find_library(name): def find_library(name): """ - Returns the shared library filename for a given library. + Return the shared library filename for a given library. The library name is given without any prefixes or suffixes--(e.g. just "Singular", not "libSingular", as shared library naming is @@ -70,7 +70,6 @@ def find_library(name): sage: from sage.misc.compat import find_library sage: find_library('giac') # needs sage.libs.giac '...giac...' - """ result = _find_library(name) diff --git a/src/sage/misc/constant_function.pyx b/src/sage/misc/constant_function.pyx index 4eb58d7599a..59cb785883d 100644 --- a/src/sage/misc/constant_function.pyx +++ b/src/sage/misc/constant_function.pyx @@ -84,7 +84,6 @@ cdef class ConstantFunction(SageObject): sage: loads(dumps(ConstantFunction(5))) == ConstantFunction(5) # indirect doctest True - """ return ConstantFunction, (self._value,) diff --git a/src/sage/misc/converting_dict.py b/src/sage/misc/converting_dict.py index 659bf223c50..684b729ea8c 100644 --- a/src/sage/misc/converting_dict.py +++ b/src/sage/misc/converting_dict.py @@ -61,9 +61,9 @@ class KeyConvertingDict(dict): INPUT: - ``key_conversion_function`` -- a function which will be - applied to all method arguments which represent keys. - - ``data`` -- optional dictionary or sequence of key-value pairs - to initialize this mapping. + applied to all method arguments which represent keys + - ``data`` -- (optional) dictionary or sequence of key-value pairs + to initialize this mapping EXAMPLES:: @@ -104,7 +104,7 @@ def __getitem__(self, key): INPUT: - - ``key`` -- A value identifying the element, will be converted. + - ``key`` -- a value identifying the element, will be converted EXAMPLES:: @@ -123,8 +123,8 @@ def __setitem__(self, key, value): INPUT: - - ``key`` -- A value identifying the element, will be converted. - - ``value`` -- The associated value, will be left unmodified. + - ``key`` -- a value identifying the element, will be converted + - ``value`` -- the associated value, will be left unmodified EXAMPLES:: @@ -143,7 +143,7 @@ def __delitem__(self, key): INPUT: - - ``key`` -- A value identifying the element, will be converted. + - ``key`` -- a value identifying the element, will be converted EXAMPLES:: @@ -163,7 +163,7 @@ def __contains__(self, key): INPUT: - - ``key`` -- A value identifying the element, will be converted. + - ``key`` -- a value identifying the element, will be converted EXAMPLES:: @@ -184,8 +184,8 @@ def pop(self, key, *args): INPUT: - - ``key`` -- A value identifying the element, will be converted. - - ``default`` -- The value to return if the element is not mapped, optional. + - ``key`` -- a value identifying the element, will be converted + - ``default`` -- the value to return if the element is not mapped, optional EXAMPLES:: @@ -211,8 +211,8 @@ def setdefault(self, key, default=None): INPUT: - - ``key`` -- A value identifying the element, will be converted. - - ``default`` -- The value to associate with the key. + - ``key`` -- a value identifying the element, will be converted + - ``default`` -- the value to associate with the key EXAMPLES:: @@ -232,10 +232,10 @@ def update(self, *args, **kwds): INPUT: - - ``key`` -- A value identifying the element, will be converted. - - ``args`` -- A single dict or sequence of pairs. - - ``kwds`` -- Named elements require that the conversion - function accept strings. + - ``key`` -- a value identifying the element, will be converted + - ``args`` -- a single dict or sequence of pairs + - ``kwds`` -- named elements require that the conversion + function accept strings EXAMPLES:: diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 545e1227b0c..95491a5c623 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -88,33 +88,33 @@ def cython(filename, verbose=0, compile_message=False, INPUT: - - ``filename`` -- the name of the file to be compiled. Should end with - 'pyx'. + - ``filename`` -- the name of the file to be compiled; should end with + 'pyx' - - ``verbose`` (integer, default 0) -- level of verbosity. A negative + - ``verbose`` -- integer (default: 0); level of verbosity. A negative value ensures complete silence. - - ``compile_message`` (bool, default: ``False``) -- if True, print - ``'Compiling ...'`` to the standard error. + - ``compile_message`` -- boolean (default: ``False``); if ``True``, print + ``'Compiling ...'`` to the standard error - - ``use_cache`` (bool, default: ``False``) -- if True, check the + - ``use_cache`` -- boolean (default: ``False``); if ``True``, check the temporary build directory to see if there is already a corresponding .so file. If so, and if the .so file is newer than the Cython file, don't recompile, just reuse the .so file. - - ``create_local_c_file`` (bool, default: ``False``) -- if True, save a - copy of the ``.c`` or ``.cpp`` file in the current directory. + - ``create_local_c_file`` -- boolean (default: ``False``); if ``True``, save a + copy of the ``.c`` or ``.cpp`` file in the current directory - - ``annotate`` (bool, default: ``True``) -- if True, create an html file which + - ``annotate`` -- boolean (default: ``True``); if ``True``, create an html file which annotates the conversion from .pyx to .c. By default this is only created in the temporary directory, but if ``create_local_c_file`` is also True, then save a copy of the .html file in the current directory. - - ``sage_namespace`` (bool, default: ``True``) -- if True, import - ``sage.all``. + - ``sage_namespace`` -- boolean (default: ``True``); if ``True``, import + ``sage.all`` - - ``create_local_so_file`` (bool, default: ``False``) -- if True, save a - copy of the compiled .so file in the current directory. + - ``create_local_so_file`` -- boolean (default: ``False``); if ``True``, save a + copy of the compiled .so file in the current directory OUTPUT: a tuple ``(name, dir)`` where ``name`` is the name of the compiled module and ``dir`` is the directory containing @@ -523,7 +523,7 @@ def f(%s): """ % (v, expr) if verbose > 0: print(s) - tmpfile = tmp_filename(ext=".pyx") + tmpfile = tmp_filename(ext='.pyx') with open(tmpfile, 'w') as f: f.write(s) @@ -538,19 +538,17 @@ def f(%s): def cython_import(filename, **kwds): """ Compile a file containing Cython code, then import and return the - module. Raises an ``ImportError`` if anything goes wrong. + module. Raises an :exc:`ImportError` if anything goes wrong. INPUT: - - ``filename`` -- a string; name of a file that contains Cython + - ``filename`` -- string; name of a file that contains Cython code See the function :func:`sage.misc.cython.cython` for documentation for the other inputs. - OUTPUT: - - - the module that contains the compiled Cython code. + OUTPUT: the module that contains the compiled Cython code """ name, build_dir = cython(filename, **kwds) @@ -574,11 +572,11 @@ def cython_import_all(filename, globals, **kwds): from module import * - Raises an ``ImportError`` exception if anything goes wrong. + Raises an :exc:`ImportError` exception if anything goes wrong. INPUT: - - ``filename`` -- a string; name of a file that contains Cython + - ``filename`` -- string; name of a file that contains Cython code """ m = cython_import(filename, **kwds) @@ -621,7 +619,7 @@ def compile_and_load(code, **kwds): INPUT: - ``code`` -- string containing code that could be in a .pyx file - that is attached or put in a %cython block in the notebook. + that is attached or put in a %cython block in the notebook OUTPUT: a module, which results from compiling the given code and importing it @@ -656,7 +654,7 @@ def compile_and_load(code, **kwds): sage: module.evaluate_at_power_of_gen(x^3 + x - 7, 5) # long time x^15 + x^5 - 7 """ - tmpfile = tmp_filename(ext=".pyx") + tmpfile = tmp_filename(ext='.pyx') with open(tmpfile, 'w') as f: f.write(code) return cython_import(tmpfile, **kwds) @@ -689,7 +687,7 @@ def cython_compile(code, **kwds): Need to create a clever caching system so code only gets compiled once. """ - tmpfile = tmp_filename(ext=".pyx") + tmpfile = tmp_filename(ext='.pyx') with open(tmpfile, 'w') as f: f.write(code) return cython_import_all(tmpfile, get_globals(), **kwds) diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py index d0ea445207c..e91acf5b5a9 100644 --- a/src/sage/misc/decorators.py +++ b/src/sage/misc/decorators.py @@ -153,7 +153,6 @@ def sage_wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES): sage: g = square(f) sage: g(3) # this line used to fail for some people if these command were manually entered on the sage prompt 81 - """ # TRAC 9919: Workaround for bug in @update_wrapper when used with # non-function callables. @@ -230,7 +229,7 @@ def __init__(self, precedence): INPUT: - ``precedence`` -- one of ``'add'``, ``'multiply'``, or ``'or'`` - indicating the new operator's precedence in the order of operations. + indicating the new operator's precedence in the order of operations """ self.precedence = precedence @@ -373,7 +372,7 @@ def __init__(self, name, **options): def __call__(self, func): """ - Returns a wrapper around func + Return a wrapper around ``func``. EXAMPLES:: @@ -486,7 +485,6 @@ def __call__(self, func): sage: f2 = o(f) sage: f2(alpha=1) () [('__original_opts', {'alpha': 1}), ('alpha', 1), ('rgbcolor', (0, 0, 1))] - """ @sage_wraps(func) def wrapper(*args, **kwds): @@ -581,8 +579,8 @@ def __init__(self, deprecated=None, deprecation=None, **renames): INPUT: - - ``deprecation`` -- integer. The github issue number where the - deprecation was introduced. + - ``deprecation`` -- integer; the github issue number where the + deprecation was introduced - the rest of the arguments is a list of keyword arguments in the form ``renamed_option='existing_option'``. This will have the @@ -669,12 +667,10 @@ class specialize: INPUT: - - ``*args``, ``**kwargs`` -- arguments to specialize the function for. - - OUTPUT: + - ``*args``, ``**kwargs`` -- arguments to specialize the function for - - a decorator that accepts a function ``f`` and specializes it - with ``*args`` and ``**kwargs`` + OUTPUT: a decorator that accepts a function ``f`` and specializes it + with ``*args`` and ``**kwargs`` EXAMPLES:: diff --git a/src/sage/misc/defaults.py b/src/sage/misc/defaults.py index 3d75021d198..ea2719a2bf6 100644 --- a/src/sage/misc/defaults.py +++ b/src/sage/misc/defaults.py @@ -29,10 +29,10 @@ def variable_names(n, name=None): INPUT: - - ``n`` a non-negative Integer; the number of variable names to - output + - ``n`` -- a nonnegative Integer; the number of variable names to + output - ``names`` a string (default: ``None``); the root of the variable - name. + name EXAMPLES:: @@ -61,10 +61,10 @@ def latex_variable_names(n, name=None): INPUT: - - ``n`` a non-negative Integer; the number of variable names to + - ``n`` -- a nonnegative Integer; the number of variable names to output - ``names`` a string (default: ``None``); the root of the variable - name. + name EXAMPLES:: diff --git a/src/sage/misc/derivative.pyx b/src/sage/misc/derivative.pyx index 8c0bcbf3c3d..24ceb09a1db 100644 --- a/src/sage/misc/derivative.pyx +++ b/src/sage/misc/derivative.pyx @@ -68,10 +68,10 @@ def derivative_parse(args): INPUT: - args -- any iterable, interpreted as a sequence of 'variables' and - iteration counts. An iteration count is any integer type (python int - or Sage Integer). Iteration counts must be non-negative. Any object - which is not an integer is assumed to be a variable. + - ``args`` -- any iterable, interpreted as a sequence of 'variables' and + iteration counts. An iteration count is any integer type (python int + or Sage Integer). Iteration counts must be nonnegative. Any object + which is not an integer is assumed to be a variable. OUTPUT: @@ -114,7 +114,7 @@ def derivative_parse(args): sage: derivative_parse([-1]) Traceback (most recent call last): ... - ValueError: derivative counts must be non-negative + ValueError: derivative counts must be nonnegative Special case with single list argument provided:: @@ -145,7 +145,6 @@ def derivative_parse(args): [] sage: derivative_parse([x, y, x, 2, 2, y]) [x, y, x, x, None, None, y] - """ if not args: return [None] @@ -161,7 +160,7 @@ def derivative_parse(args): # process iteration count count = int(arg) if count < 0: - raise ValueError("derivative counts must be non-negative") + raise ValueError("derivative counts must be nonnegative") if not got_var: var = None for i from 0 <= i < count: @@ -182,12 +181,12 @@ def derivative_parse(args): def multi_derivative(F, args): r""" - Calls F._derivative(var) for a sequence of variables specified by args. + Call F._derivative(var) for a sequence of variables specified by args. INPUT: - - ``F`` -- any object with a ``_derivative(var)`` method. - - ``args`` -- any tuple that can be processed by :func:`derivative_parse`. + - ``F`` -- any object with a ``_derivative(var)`` method + - ``args`` -- any tuple that can be processed by :func:`derivative_parse` EXAMPLES:: diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index da0a996424b..b11b2078129 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -23,11 +23,11 @@ def runsnake(command): """ - Graphical profiling with ``runsnake`` + Graphical profiling with ``runsnake``. INPUT: - - ``command`` -- the command to be run as a string. + - ``command`` -- the command to be run as a string EXAMPLES:: @@ -60,7 +60,6 @@ def runsnake(command): - `The runsnake website `_ - ``%prun`` - :class:`Profiler` - """ import cProfile from sage.misc.temporary_file import tmp_filename @@ -80,10 +79,10 @@ def import_statement_string(module, names, lazy): - ``module`` -- the name of a module - - ``names`` -- a list of 2-tuples containing names and alias to + - ``names`` -- list of 2-tuples containing names and alias to import - - ``lazy`` -- a boolean: whether to return a lazy import statement + - ``lazy`` -- boolean; whether to return a lazy import statement EXAMPLES:: @@ -143,7 +142,7 @@ def load_submodules(module=None, exclude_pattern=None): - ``module`` -- an optional module - ``exclude_pattern`` -- an optional regular expression pattern of module - names that have to be excluded. + names that have to be excluded EXAMPLES:: @@ -311,7 +310,7 @@ def find_object_modules(obj): from sage.misc import sageinspect # see if the object is defined in its own module - # might be wrong for class instances as the instanciation might appear + # might be wrong for class instances as the instantiation might appear # outside of the module !! module_name = None if sageinspect.isclassinstance(obj): @@ -368,16 +367,16 @@ def import_statements(*objects, **kwds): INPUT: - - ``*objects`` -- a sequence of objects or comma-separated strings of names. + - ``*objects`` -- a sequence of objects or comma-separated strings of names - - ``lazy`` -- a boolean (default: ``False``) - Whether to print a lazy import statement. + - ``lazy`` -- boolean (default: ``False``); whether to print a lazy import + statement - - ``verbose`` -- a boolean (default: ``True``) - Whether to print information in case of ambiguity. + - ``verbose`` -- boolean (default: ``True``); whether to print information + in case of ambiguity - - ``answer_as_str`` -- a boolean (default: ``False``) - If ``True`` return a string instead of printing the statement. + - ``answer_as_str`` -- boolean (default: ``False``); if ``True`` return a + string instead of printing the statement EXAMPLES:: diff --git a/src/sage/misc/edit_module.py b/src/sage/misc/edit_module.py index cf39a6d2675..88132947a2e 100644 --- a/src/sage/misc/edit_module.py +++ b/src/sage/misc/edit_module.py @@ -214,7 +214,7 @@ def edit(obj, editor=None, bg=None): INPUT: - - editor -- str (default: None); If given, use specified editor. + - editor -- string (default: ``None``); if given, use specified editor. Choice is stored for next time. AUTHOR: diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 0f5537a87d0..664a86cd5bc 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -184,25 +184,25 @@ def explain_pickle(pickle=None, file=None, compress=True, **kwargs): INPUT: - - ``pickle`` -- the pickle to explain, as a string (default: ``None``) - - ``file`` -- a filename of a pickle (default: ``None``) - - ``compress`` -- if ``False``, don't attempt to decompress the pickle - (default: ``True``) - - ``in_current_sage`` -- if ``True``, produce potentially simpler code that is - tied to the current version of Sage. (default: ``False``) - - ``default_assumptions`` -- if ``True``, produce potentially simpler code that - assumes that generic unpickling code will be - used. This code may not actually work. - (default: ``False``) - - ``eval`` -- if ``True``, then evaluate the resulting code and return the - evaluated result. (default: ``False``) - - ``preparse`` -- if ``True``, then produce code to be evaluated with - Sage's preparser; if ``False``, then produce standard - Python code; if ``None``, then produce code that will work - either with or without the preparser. (default: ``True``) - - ``pedantic`` -- if ``True``, then carefully ensures that the result has - at least as much sharing as the result of cPickle - (it may have more, for immutable objects). (default: ``False``) + - ``pickle`` -- string (default: ``None``); the pickle to explain + - ``file`` -- a filename of a pickle (default: ``None``) + - ``compress`` -- boolean (default: ``True``); if ``False``, don't attempt + to decompress the pickle + - ``in_current_sage`` -- boolean (default: ``False``); if ``True``, + produce potentially simpler code that is tied to the current version of + Sage + - ``default_assumptions`` -- boolean (default: ``False``); if ``True``, + produce potentially simpler code that assumes that generic unpickling + code will be used. This code may not actually work. + - ``eval`` -- boolean (default: ``False``); if ``True``, then evaluate the + resulting code and return the evaluated result + - ``preparse`` -- if ``True``, then produce code to be evaluated with + Sage's preparser; if ``False``, then produce standard + Python code; if ``None``, then produce code that will work + either with or without the preparser. (default: ``True``) + - ``pedantic`` -- boolean (default: ``False``); if ``True``, then carefully + ensures that the result has at least as much sharing as the result of + cPickle (it may have more, for immutable objects) Exactly one of ``pickle`` (a string containing a pickle) or ``file`` (the filename of a pickle) must be provided. @@ -2482,7 +2482,7 @@ def unpickle_instantiate(fn, args): def unpickle_persistent(s): r""" - Takes an integer index and returns the persistent object with that + Take an integer index and return the persistent object with that index; works by calling whatever callable is stored in ``unpickle_persistent_loader``. Used by :func:`explain_pickle`. @@ -2498,7 +2498,7 @@ def unpickle_persistent(s): def unpickle_extension(code): r""" - Takes an integer index and returns the extension object with that + Take an integer index and return the extension object with that index. Used by :func:`explain_pickle`. EXAMPLES:: diff --git a/src/sage/misc/fast_methods.pyx b/src/sage/misc/fast_methods.pyx index 3c7e77c617a..d38c1802c45 100644 --- a/src/sage/misc/fast_methods.pyx +++ b/src/sage/misc/fast_methods.pyx @@ -101,7 +101,6 @@ cdef class WithEqualityById: True sage: a is d False - """ def __hash__(self): """ @@ -195,7 +194,7 @@ cdef class FastHashable_class: This is for internal use only. The class has a cdef attribute ``_hash``, that needs to be assigned (for example, by calling - the init method, or by a direct assignement using + the init method, or by a direct assignment using cython). This is slower than using :func:`provide_hash_by_id`, but has the advantage that the hash can be prescribed, by assigning a cdef attribute ``_hash``. @@ -226,7 +225,6 @@ cdef class FastHashable_class: sage: H = FastHashable_class(123) sage: hash(H) # indirect doctest 123 - """ return self._hash diff --git a/src/sage/misc/flatten.py b/src/sage/misc/flatten.py index 8d46445a687..df553c5aba6 100644 --- a/src/sage/misc/flatten.py +++ b/src/sage/misc/flatten.py @@ -10,13 +10,11 @@ def flatten(in_list, ltypes=(list, tuple), max_level=sys.maxsize): INPUT: - - ``in_list`` -- a list or tuple - - ``ltypes`` -- optional list of particular types to flatten + - ``in_list`` -- list or tuple + - ``ltypes`` -- (optional) list of particular types to flatten - ``max_level`` -- the maximum level to flatten - OUTPUT: - - a flat list of the entries of ``in_list`` + OUTPUT: a flat list of the entries of ``in_list`` EXAMPLES:: diff --git a/src/sage/misc/fpickle.pyx b/src/sage/misc/fpickle.pyx index 752a2a0093a..fd192f1bf02 100644 --- a/src/sage/misc/fpickle.pyx +++ b/src/sage/misc/fpickle.pyx @@ -74,11 +74,9 @@ def pickle_function(func): INPUT: - func -- a Python function + - ``func`` -- a Python function - OUTPUT: - - a string + OUTPUT: string EXAMPLES:: diff --git a/src/sage/misc/function_mangling.pyx b/src/sage/misc/function_mangling.pyx index d84f6c9bc62..79e508f19b8 100644 --- a/src/sage/misc/function_mangling.pyx +++ b/src/sage/misc/function_mangling.pyx @@ -80,11 +80,10 @@ cdef class ArgumentFixer: INPUT: - - f -- a function - - classmethod -- boolean (default: ``False``) -- True if the function - is a classmethod and therefore the first - argument is expected to be the class instance. - In that case, we ignore the first argument. + - ``f`` -- a function + - ``classmethod`` -- boolean (default: ``False``); ``True`` if the function + is a classmethod and therefore the first argument is expected to be the + class instance. In that case, we ignore the first argument. EXAMPLES:: @@ -111,7 +110,6 @@ cdef class ArgumentFixer: sage: af = ArgumentFixer(one.__init__, classmethod=True) sage: af.fix_to_pos(1,2,3,a=31,b=2,n=3) ((1, 2, 3), (('a', 31), ('b', 2), ('n', 3))) - """ def __init__(self, f, classmethod = False): try: @@ -134,16 +132,16 @@ cdef class ArgumentFixer: else: self._default_tuple = tuple(defaults) - #code = f.__code__ + # code = f.__code__ self.f = f self._ndefault = len(defaults) if classmethod: - self._nargs = len(arg_names)-1 #code.co_argcount-1 - self._arg_names = tuple(arg_names[1:]) #code.co_varnames[1:self._nargs+1] + self._nargs = len(arg_names)-1 # code.co_argcount-1 + self._arg_names = tuple(arg_names[1:]) # code.co_varnames[1:self._nargs+1] else: - self._nargs = len(arg_names) #code.co_argcount - self._arg_names = tuple(arg_names) #code.co_varnames[:self._nargs] + self._nargs = len(arg_names) # code.co_argcount + self._arg_names = tuple(arg_names) # code.co_varnames[:self._nargs] self._classmethod = classmethod cdef dict default_map @@ -169,9 +167,7 @@ cdef class ArgumentFixer: - any positional and named arguments. - OUTPUT: - - We return a tuple + OUTPUT: we return a tuple `(e_1, e_2, ..., e_k), ((n_1, v_1), ... , (n_m, v_m))` @@ -208,7 +204,6 @@ cdef class ArgumentFixer: ((4, 5, 6), (('a', 1), ('b', 2), ('c', 3), ('e', 16), ('f', 14))) sage: AF.fix_to_named(1,2,f=14) ((), (('a', 1), ('b', 2), ('c', 3), ('f', 14))) - """ cdef list ARGS = [] cdef tuple arg_names = self._arg_names @@ -238,11 +233,9 @@ cdef class ArgumentFixer: INPUT: - Any positional or named arguments - - OUTPUT: + - ``*args``, ``**kwds`` -- any positional or named arguments - We return a tuple + OUTPUT: we return a tuple `(e_1, e_2, ..., e_k), ((n_1, v_1), ... , (n_m, v_m))` @@ -302,7 +295,7 @@ cdef class ArgumentFixer: cdef Py_ssize_t i for i in range(lenargs, nargs): # in addition to the positional arguments, we take the - # ones with default values, unless they are overridded by + # ones with default values, unless they are overridden by # the named arguments. name = arg_names[i] if name in kwargs: diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 99ddcd3c772..7286501c0f1 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -193,7 +193,7 @@ def coerce(P, x): def cyclotomic_polynomial(n, var='x'): """ - Return the `n^{th}` cyclotomic polynomial. + Return the `n`-th cyclotomic polynomial. EXAMPLES:: @@ -570,7 +570,7 @@ def symbolic_sum(expression, *args, **kwds): sage: sum(x, x, 1r, 5r) # needs sage.symbolic 15 - .. note:: + .. NOTE:: #. Sage can currently only understand a subset of the output of Maxima, Maple and Mathematica, so even if the chosen backend can perform the summation the @@ -584,7 +584,6 @@ def symbolic_sum(expression, *args, **kwds): 4 sage: sum([[1], [2]], start=[]) [1, 2] - """ if hasattr(expression, 'sum'): return expression.sum(*args, **kwds) @@ -617,7 +616,7 @@ def symbolic_prod(expression, *args, **kwds): - ``'sympy'`` -- use SymPy - - ``hold`` -- (default: ``False``) if ``True`` don't evaluate + - ``hold`` -- boolean (default: ``False``); if ``True`` don't evaluate EXAMPLES:: @@ -639,7 +638,6 @@ def symbolic_prod(expression, *args, **kwds): 1/factorial(n + 1) sage: product(f(i), i, 1, n).log().log_expand() sum(log(f(i)), i, 1, n) - """ from .misc_c import prod as c_prod if hasattr(expression, 'prod'): @@ -782,7 +780,6 @@ def integral(x, *args, **kwds): ... sage: result # needs sage.symbolic -1/4 - """ if hasattr(x, 'integral'): return x.integral(*args, **kwds) @@ -1092,8 +1089,8 @@ def log(*args, **kwds): sage: log(F(9), 3) 2 - The log function also works for p-adics (see documentation for - p-adics for more information):: + The log function also works for `p`-adics (see documentation for + `p`-adics for more information):: sage: R = Zp(5); R # needs sage.rings.padics 5-adic Ring with capped relative precision 20 @@ -1191,7 +1188,7 @@ def minimal_polynomial(x, var='x'): def multiplicative_order(x): r""" Return the multiplicative order of ``x``, if ``x`` is a unit, or - raise :class:`ArithmeticError` otherwise. + raise :exc:`ArithmeticError` otherwise. EXAMPLES:: @@ -1824,22 +1821,21 @@ def _do_sqrt(x, prec=None, extend=True, all=False): INPUT: - - ``x`` -- a number - - - ``prec`` -- a positive integer (default: ``None``); when specified, - compute the square root with ``prec`` bits of precision + - ``x`` -- a number - - ``extend`` -- bool (default: ``True``); this is a placeholder, and is - always ignored since in the symbolic ring everything - has a square root. + - ``prec`` -- positive integer (default: ``None``); when specified, + compute the square root with ``prec`` bits of precision - - ``extend`` -- bool (default: ``True``); whether to extend - the base ring to find roots. The extend parameter is ignored if - ``prec`` is a positive integer. + - ``extend`` -- boolean (default: ``True``); this is a placeholder, and is + always ignored since in the symbolic ring everything + has a square root - - ``all`` -- bool (default: ``False``); whether to return - a list of all the square roots of ``x``. + - ``extend`` -- boolean (default: ``True``); whether to extend + the base ring to find roots. The extend parameter is ignored if + ``prec`` is a positive integer. + - ``all`` -- boolean (default: ``False``); whether to return + a list of all the square roots of ``x`` EXAMPLES:: @@ -1883,18 +1879,18 @@ def sqrt(x, *args, **kwds): r""" INPUT: - - ``x`` -- a number + - ``x`` -- a number - - ``prec`` -- integer (default: ``None``): if ``None``, returns - an exact square root; otherwise returns a numerical square root if - necessary, to the given bits of precision. + - ``prec`` -- integer (default: ``None``); if ``None``, returns + an exact square root. Otherwise returns a numerical square root if + necessary, to the given bits of precision. - - ``extend`` -- bool (default: ``True``); this is a placeholder, and - is always ignored or passed to the ``sqrt`` method of ``x``, - since in the symbolic ring everything has a square root. + - ``extend`` -- boolean (default: ``True``); this is a placeholder, and + is always ignored or passed to the ``sqrt`` method of ``x``, + since in the symbolic ring everything has a square root - - ``all`` -- bool (default: ``False``); if ``True``, return all - square roots of ``self``, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of ``self``, instead of just one EXAMPLES:: diff --git a/src/sage/misc/gperftools.py b/src/sage/misc/gperftools.py index d3a55a7e9d6..8e89dadef6d 100644 --- a/src/sage/misc/gperftools.py +++ b/src/sage/misc/gperftools.py @@ -52,7 +52,7 @@ class Profiler(SageObject): def __init__(self, filename=None): """ - Interface to the gperftools profiler + Interface to the gperftools profiler. INPUT: @@ -73,11 +73,9 @@ def __init__(self, filename=None): def filename(self): """ - Return the file name + Return the file name. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -90,11 +88,9 @@ def filename(self): def _repr_(self): """ - Return string representation - - OUTPUT: + Return string representation. - String. + OUTPUT: string EXAMPLES:: @@ -106,11 +102,9 @@ def _repr_(self): def _libc(self): """ - Return libc - - OUTPUT: + Return libc. - A ctypes shared library handle. + OUTPUT: a ctypes shared library handle EXAMPLES:: @@ -130,11 +124,9 @@ def _libc(self): def _libprofiler(self): """ - Return libprofiler + Return libprofiler. - OUTPUT: - - A ctypes shared library handle. + OUTPUT: a ctypes shared library handle EXAMPLES:: @@ -155,7 +147,7 @@ def _libprofiler(self): def start(self): """ - Start profiling + Start profiling. EXAMPLES:: @@ -176,7 +168,7 @@ def start(self): def stop(self): """ - Stop the CPU profiler + Stop the CPU profiler. EXAMPLES:: @@ -203,7 +195,7 @@ def _pprof(self): OUTPUT: String. The name of the gperftools ``pprof`` utility. A - ``OSError`` is raised if it cannot be found. + :exc:`OSError` is raised if it cannot be found. EXAMPLES:: @@ -235,9 +227,7 @@ def _executable(self): """ Return the name of the Sage Python interpreter. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -250,14 +240,13 @@ def _executable(self): def _call_pprof(self, *args, **kwds): """ - Run the pprof binary + Run the pprof binary. INPUT: - - ``args`` -- list of strings. The arguments to ``pprof``. + - ``args`` -- list of strings; the arguments to ``pprof`` - - ``kwds`` -- keyword arguments passed to - ``subprocess.check_call``. + - ``kwds`` -- keyword arguments passed to ``subprocess.check_call`` EXAMPLES:: @@ -273,11 +262,9 @@ def _call_pprof(self, *args, **kwds): def top(self, cumulative=True): """ - Print text report - - OUTPUT: + Print text report. - Nothing. A textual report is printed to stdout. + OUTPUT: nothing; a textual report is printed to stdout EXAMPLES:: @@ -303,15 +290,15 @@ def save(self, filename, cumulative=True, verbose=True): INPUT: - - ``filename`` -- string. The filename to save at. Must end + - ``filename`` -- string; the filename to save at. Must end with one of ``.dot``, ``.ps``, ``.pdf``, ``.svg``, ``.gif``, or ``.txt`` to specify the output file format. - - ``cumulative`` -- boolean (default: - ``True``). Whether to return cumulative timings. + - ``cumulative`` -- boolean (default: ``True``); whether to return + cumulative timings - - ``verbose`` -- boolean (default: - ``True``). Whether to print informational messages. + - ``verbose`` -- boolean (default: ``True``); whether to print + informational messages EXAMPLES:: @@ -351,9 +338,9 @@ def crun(s, evaluator): """ Profile single statement. - - ``s`` -- string. Sage code to profile. + - ``s`` -- string; Sage code to profile - - ``evaluator`` -- callable to evaluate. + - ``evaluator`` -- callable to evaluate EXAMPLES:: diff --git a/src/sage/misc/html.py b/src/sage/misc/html.py index 1fe74334d53..8732acdede0 100644 --- a/src/sage/misc/html.py +++ b/src/sage/misc/html.py @@ -47,7 +47,7 @@ class HtmlFragment(str, SageObject): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -73,11 +73,9 @@ def math_parse(s): INPUT: - - ``s`` -- a string + - ``s`` -- string - OUTPUT: - - A :class:`HtmlFragment` instance. + OUTPUT: :class:`HtmlFragment` Specifically this method does the following: @@ -96,7 +94,6 @@ def math_parse(s): This is \[2+2\]. sage: print(sage.misc.html.math_parse(r'\$2+2\$ is rendered to $2+2$.')) $2+2$ is rendered to \(2+2\). - """ # Below t always has the "parsed so far" version of s, and s is # just the part of the original input s that hasn't been parsed. @@ -166,7 +163,7 @@ def __init__(self, y): INPUT: - - ``y`` -- a string + - ``y`` -- string Note that no error checking is done on the type of ``y``. @@ -175,7 +172,7 @@ def __init__(self, y): sage: from sage.misc.html import MathJaxExpr sage: jax = MathJaxExpr(3); jax # indirect doctest 3 - sage: TestSuite(jax).run(skip ="_test_pickling") + sage: TestSuite(jax).run(skip ='_test_pickling') """ self.__y = y @@ -244,14 +241,12 @@ def __call__(self, x, combine_all=False): - ``x`` -- a Sage object - - ``combine_all`` -- boolean (Default: ``False``): If ``combine_all`` is - ``True`` and the input is a tuple, then it does not return a tuple + - ``combine_all`` -- boolean (default: ``False``); if ``combine_all`` + is ``True`` and the input is a tuple, then it does not return a tuple and instead returns a string with all the elements separated by - a single space. + a single space - OUTPUT: - - A :class:`MathJaxExpr` + OUTPUT: :class:`MathJaxExpr` EXAMPLES:: @@ -271,24 +266,22 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): - ``x`` -- a Sage object - - ``globals`` -- a globals dictionary + - ``globals`` -- a globals dictionary - - ``locals`` -- extra local variables used when - evaluating Sage code in ``x``. + - ``locals`` -- extra local variables used when + evaluating Sage code in ``x`` - - ``mode`` -- string (default: ``'display'``): - ``'display'`` for displaymath, ``'inline'`` for inline - math, or ``'plain'`` for just the LaTeX code without the - surrounding html and script tags. + - ``mode`` -- string (default: ``'display'``); + ``'display'`` for displaymath, ``'inline'`` for inline + math, or ``'plain'`` for just the LaTeX code without the + surrounding html and script tags - - ``combine_all`` -- boolean (Default: ``False``): If ``combine_all`` is - ``True`` and the input is a tuple, then it does not return a tuple + - ``combine_all`` -- boolean (default: ``False``); if ``combine_all`` + is ``True`` and the input is a tuple, then it does not return a tuple and instead returns a string with all the elements separated by - a single space. - - OUTPUT: + a single space - A :class:`MathJaxExpr` + OUTPUT: :class:`MathJaxExpr` EXAMPLES:: @@ -390,11 +383,9 @@ class HTMLFragmentFactory(SageObject): def _repr_(self): """ - Return string representation + Return string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -405,12 +396,12 @@ def _repr_(self): def __call__(self, obj, concatenate=True, strict=False): r""" - Construct a HTML fragment + Construct a HTML fragment. INPUT: - ``obj`` -- anything. An object for which you want an HTML - representation. + representation - ``concatenate`` -- if ``True``, combine HTML representations of elements of the container ``obj`` @@ -418,9 +409,7 @@ def __call__(self, obj, concatenate=True, strict=False): - ``strict`` -- if ``True``, construct an HTML representation of ``obj`` even if ``obj`` is a string - OUTPUT: - - A :class:`HtmlFragment` instance. + OUTPUT: :class:`HtmlFragment` EXAMPLES:: @@ -483,18 +472,16 @@ def __call__(self, obj, concatenate=True, strict=False): def eval(self, s, locals=None): r""" - Evaluate embedded tags + Evaluate embedded tags. INPUT: - - ``s`` -- string. + - ``s`` -- string - - ``globals`` -- dictionary. The global variables when + - ``globals`` -- dictionary; the global variables when evaluating ``s``. Default: the current global variables. - OUTPUT: - - A :class:`HtmlFragment` instance. + OUTPUT: :class:`HtmlFragment` EXAMPLES:: @@ -525,22 +512,20 @@ def eval(self, s, locals=None): def iframe(self, url, height=400, width=800): r""" - Generate an iframe HTML fragment + Generate an iframe HTML fragment. INPUT: - - ``url`` -- string. A url, either with or without URI scheme - (defaults to "http"), or an absolute file path. - - - ``height`` -- the number of pixels for the page height. - Defaults to 400. + - ``url`` -- string; a url, either with or without URI scheme + (defaults to "http"), or an absolute file path - - ``width`` -- the number of pixels for the page width. - Defaults to 800. + - ``height`` -- the number of pixels for the page height + Defaults to 400 - OUTPUT: + - ``width`` -- the number of pixels for the page width + Defaults to 800 - A :class:`HtmlFragment` instance. + OUTPUT: :class:`HtmlFragment` EXAMPLES:: @@ -586,8 +571,8 @@ def pretty_print_default(enable=True): INPUT: - - ``enable`` -- bool (default: ``True``). If ``True``, turn on - pretty printing; if ``False``, turn it off. + - ``enable`` -- boolean (default: ``True``); if ``True``, turn on + pretty printing. If ``False``, turn it off. EXAMPLES:: diff --git a/src/sage/misc/inline_fortran.py b/src/sage/misc/inline_fortran.py index 82da6982bec..ccd4b1da87c 100644 --- a/src/sage/misc/inline_fortran.py +++ b/src/sage/misc/inline_fortran.py @@ -77,14 +77,13 @@ def __call__(self, *args, **kwds): def eval(self, x, globals=None, locals=None): """ - Compile fortran code ``x`` and adds the functions in it to - ``globals``. + Compile fortran code ``x`` and adds the functions in it to ``globals``. INPUT: - - ``x`` -- Fortran code + - ``x`` -- fortran code - - ``globals`` -- a dict to which to add the functions from the + - ``globals`` -- dictionary to which to add the functions from the fortran module - ``locals`` -- ignored diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx index 852cde57220..4641b53b13d 100644 --- a/src/sage/misc/instancedoc.pyx +++ b/src/sage/misc/instancedoc.pyx @@ -137,12 +137,12 @@ cdef class InstanceDocDescriptor: INPUT: - - ``classdoc`` -- (string) class documentation + - ``classdoc`` -- string; class documentation - ``instancedoc`` -- (method) documentation for an instance - - ``attr`` -- (string, default ``__doc__``) attribute name to use - for custom docstring on the instance. + - ``attr`` -- string (default: ``__doc__``); attribute name to use + for custom docstring on the instance EXAMPLES:: @@ -171,7 +171,7 @@ cdef class InstanceDocDescriptor: cdef instancedoc cdef attr - def __init__(self, classdoc, instancedoc, attr="__doc__"): + def __init__(self, classdoc, instancedoc, attr='__doc__'): """ TESTS:: diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 32aa0c94c66..9d8fcd4a341 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -66,11 +66,11 @@ def list_function(x): r""" - Returns the LaTeX code for a list ``x``. + Return the LaTeX code for a list ``x``. INPUT: - - ``x`` -- a list + - ``x`` -- list EXAMPLES:: @@ -96,13 +96,13 @@ def list_function(x): def tuple_function(x, combine_all=False): r""" - Returns the LaTeX code for a tuple ``x``. + Return the LaTeX code for a tuple ``x``. INPUT: - - ``x`` -- a tuple + - ``x`` -- tuple - - ``combine_all`` -- boolean (default: ``False``) If ``combine_all`` is + - ``combine_all`` -- boolean (default: ``False``); if ``combine_all`` is ``True``, then it does not return a tuple and instead returns a string with all the elements separated by a single space. It does not collapse tuples which are inside tuples. @@ -127,7 +127,7 @@ def tuple_function(x, combine_all=False): def bool_function(x): r""" - Returns the LaTeX code for a boolean ``x``. + Return the LaTeX code for a boolean ``x``. INPUT: @@ -146,7 +146,7 @@ def bool_function(x): def builtin_constant_function(x): r""" - Returns the LaTeX code for a builtin constant ``x``. + Return the LaTeX code for a builtin constant ``x``. INPUT: @@ -165,14 +165,13 @@ def builtin_constant_function(x): '\\mbox{\\rm NotImplemented}' sage: builtin_constant_function(Ellipsis) '\\mbox{\\rm Ellipsis}' - """ return "\\mbox{\\rm %s}" % x def None_function(x): r""" - Returns the LaTeX code for ``None``. + Return the LaTeX code for ``None``. INPUT: @@ -210,9 +209,9 @@ def str_function(x): INPUT: - - ``x`` -- a string + - ``x`` -- string - OUTPUT: A string + OUTPUT: string EXAMPLES:: @@ -256,7 +255,7 @@ def dict_function(x): INPUT: - - ``x`` -- a dictionary + - ``x`` -- dictionary EXAMPLES:: @@ -281,7 +280,7 @@ def dict_function(x): def float_function(x): r""" - Returns the LaTeX code for a python float ``x``. + Return the LaTeX code for a python float ``x``. INPUT: @@ -336,12 +335,10 @@ class LatexExpr(str): INPUT: - - ``str`` -- a string with valid math mode LaTeX code (or something - which can be converted to such a string). - - OUTPUT: + - ``str`` -- string with valid math mode LaTeX code (or something + which can be converted to such a string) - - :class:`LatexExpr` wrapping the string representation of the input. + OUTPUT: :class:`LatexExpr` wrapping the string representation of the input EXAMPLES:: @@ -505,7 +502,7 @@ class _Latex_prefs_object(SageObject): An object that holds LaTeX global preferences. """ def __init__(self, bb=False, delimiters=["(", ")"], - matrix_column_alignment="r"): + matrix_column_alignment='r'): """ Define an object that holds LaTeX global preferences. @@ -513,7 +510,7 @@ def __init__(self, bb=False, delimiters=["(", ")"], sage: from sage.misc.latex import _Latex_prefs_object sage: latex_prefs = _Latex_prefs_object() - sage: TestSuite(latex_prefs).run(skip ="_test_pickling") + sage: TestSuite(latex_prefs).run(skip ='_test_pickling') """ self.__option = {} self.__option["blackboard_bold"] = bb @@ -596,7 +593,7 @@ def latex_extra_preamble(): def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_in_background=False): """ This runs LaTeX on the TeX file "filename.tex". It produces files - ``filename.dvi`` (or ``filename.pdf``` if ``engine`` is either ``'pdflatex'``, + ``filename.dvi`` (or ``filename.pdf`` if ``engine`` is either ``'pdflatex'``, ``'xelatex'``, or ``'lualatex'``) and if ``png`` is ``True``, ``filename.png``. If ``png`` is ``True`` and ``dvipng`` cannot convert the dvi file to png (because of postscript specials or other issues), then ``dvips`` is called, and @@ -604,21 +601,21 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i INPUT: - - ``filename`` -- string; file to process, including full path + - ``filename`` -- string; file to process, including full path - - ``debug`` -- bool (default: ``False``); whether to print - verbose debugging output + - ``debug`` -- boolean (default: ``False``); whether to print + verbose debugging output - - ``density`` -- integer (default: 150); how big output - image is. + - ``density`` -- integer (default: 150); how big output + image is - - ``engine`` -- string: latex engine to use. + - ``engine`` -- string; latex engine to use - - ``png`` -- bool (default: ``False``); whether to produce a - png file. + - ``png`` -- boolean (default: ``False``); whether to produce a + png file - - ``do_in_background`` -- bool (default: ``False``). Unused, - kept for backwards compatibility. + - ``do_in_background`` -- boolean (default: ``False``); unused, + kept for backwards compatibility OUTPUT: @@ -644,7 +641,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i sage: from sage.misc.latex import _run_latex_, _latex_file_ sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(mode="w+t", suffix=".tex") as f: # random, optional - latex + sage: with NamedTemporaryFile(mode='w+t', suffix='.tex') as f: # random, optional - latex ....: _ = f.write(_latex_file_([ZZ['x'], RR])) ....: f.flush() ....: _run_latex_(f.name) @@ -849,14 +846,12 @@ def __call__(self, x, combine_all=False): - ``x`` -- a Sage object - - ``combine_all`` -- boolean (Default: ``False``) If ``combine_all`` + - ``combine_all`` -- boolean (default: ``False``); if ``combine_all`` is ``True`` and the input is a tuple, then it does not return a tuple and instead returns a string with all the elements separated by - a single space. + a single space - OUTPUT: - - A :class:`LatexExpr` built from ``x`` + OUTPUT: a :class:`LatexExpr` built from ``x`` EXAMPLES:: @@ -931,7 +926,7 @@ def __init__(self, debug=False, slide=False, density=150, engine=None): sage: from sage.misc.latex import Latex sage: l = Latex() - sage: TestSuite(l).run(skip ="_test_pickling") + sage: TestSuite(l).run(skip ='_test_pickling') """ self.__debug = debug self.__slide = slide @@ -940,7 +935,7 @@ def __init__(self, debug=False, slide=False, density=150, engine=None): def _relation_symbols(self): """ - Returns a dictionary whose keys are attributes of the + Return a dictionary whose keys are attributes of the :mod:`operator` module and whose values are the corresponding LaTeX expressions. @@ -1252,8 +1247,8 @@ def matrix_column_alignment(self, align=None): INPUT: - - ``align`` -- a string (``'r'`` for right, ``'c'`` for center, - ``'l'`` for left) or ``None``. + - ``align`` -- string (``'r'`` for right, ``'c'`` for center, + ``'l'`` for left) or ``None`` OUTPUT: @@ -1297,7 +1292,7 @@ def has_file(self, file_name) -> bool: """ INPUT: - - ``file_name`` -- a string + - ``file_name`` -- string Tests whether the local LaTeX installation includes ``file_name``. @@ -1321,9 +1316,9 @@ def check_file(self, file_name, more_info=""): """ INPUT: - - ``file_name`` -- a string + - ``file_name`` -- string - - ``more_info`` -- a string (default: ``""``) + - ``more_info`` -- string (default: ``''``) Emit a warning if the local LaTeX installation does not include ``file_name``. The string ``more_info`` is appended @@ -1480,13 +1475,13 @@ def add_to_preamble(self, s): def add_package_to_preamble_if_available(self, package_name): r""" - Adds a ``\usepackage{package_name}`` instruction to the latex + Add a ``\usepackage{package_name}`` instruction to the latex preamble if not yet present there, and if ``package_name.sty`` is available in the LaTeX installation. INPUT: - - ``package_name`` -- a string + - ``package_name`` -- string .. SEEALSO:: @@ -1579,20 +1574,20 @@ def _latex_file_(objects, title='SAGE', debug=False, - ``objects`` -- list (or object) - - ``title`` -- string (default: 'Sage'); title for the document + - ``title`` -- string (default: ``'Sage'``); title for the document - - ``math_left`` -- string (default: '\\['), left delimiter for math mode + - ``math_left`` -- string (default: ``'\\['``); left delimiter for math mode - - ``math_right`` -- string (default: '\\]'), right delimiter for math mode + - ``math_right`` -- string (default: ``'\\]'``); right delimiter for math mode - - ``debug`` -- bool (default: ``False``); print verbose output + - ``debug`` -- boolean (default: ``False``); print verbose output - ``sep`` -- string (default: ``''``); separator between math objects - - ``tiny`` -- bool (default: ``False``); use 'tiny' font. + - ``tiny`` -- boolean (default: ``False``); use 'tiny' font - - ``extra_preamble`` -- string (default: ``''``); extra LaTeX commands, - inserted before ``"\\begin{document}"`` + - ``extra_preamble`` -- string (default: ``''``); extra LaTeX commands; + inserted before ``'\\begin{document}'`` This creates a string intended to be a LaTeX file containing the LaTeX representations of objects. It contains the following: @@ -1688,7 +1683,9 @@ def _latex_file_(objects, title='SAGE', debug=False, s = LATEX_HEADER + '\n' + MACROS + s + '\n\\end{document}' if debug: + print('----') print(s) + print('----') return s @@ -1706,21 +1703,21 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, - ``objects`` -- list (or object) - ``title`` -- string (default: ``'Sage'``); title for the - document + document - - ``debug`` -- bool (default: ``False``); print verbose - output + - ``debug`` -- boolean (default: ``False``); print verbose + output - ``sep`` -- string (default: ``''``); separator between - math objects + math objects - - ``tiny`` -- bool (default: ``False``); use tiny font. + - ``tiny`` -- boolean (default: ``False``); use tiny font - ``engine`` -- string or ``None`` (default: ``None``); can take the - following values: + following values: - ``None`` -- the value defined in the LaTeX global preferences - ``latex.engine()`` is used. + ``latex.engine()`` is used - ``'pdflatex'`` -- compilation does ``tex`` -> ``pdf`` @@ -1733,26 +1730,23 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, ``'pdflatex'`` and known to be broken when overfull hboxes are detected. - ``viewer`` -- string or ``None`` (default: ``None``); specify a viewer - to use; currently the only options are ``None`` and ``'pdf'``. + to use; currently the only options are ``None`` and ``'pdf'`` - - ``tightpage`` -- bool (default: ``True``); use the LaTeX package - ``preview`` with the 'tightpage' option. + - ``tightpage`` -- boolean (default: ``True``); use the LaTeX package + ``preview`` with the 'tightpage' option - ``margin`` -- float or ``None`` (default: ``None``); adds a margin - of ``margin`` mm; has no affect if the option ``tightpage`` is - ``False``. + of ``margin`` mm. Has no affect if the option ``tightpage`` is ``False``. - ``mode`` -- string (default: ``'inline'``); ``'display'`` for displaymath or ``'inline'`` for inline math - - ``combine_all`` -- bool (default: ``False``); if ``combine_all`` is + - ``combine_all`` -- boolean (default: ``False``); if ``combine_all`` is ``True`` and the input is a tuple, then it does not return a tuple and instead returns a string with all the elements separated by a single - space. - - OUTPUT: + space - Display typeset objects. + OUTPUT: display typeset objects The output is displayed in a separate viewer displaying a dvi (or pdf) file, with the following: the title string is printed, centered, at the @@ -1802,10 +1796,10 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, sage: from tempfile import NamedTemporaryFile sage: g = sage.misc.latex.latex_examples.graph() sage: latex.add_to_preamble(r"\usepackage{tkz-graph}") # optional - latex_package_tkz_graph - sage: with NamedTemporaryFile(mode="w+t", suffix=".tex") as f: # optional - latex latex_package_tkz_graph + sage: with NamedTemporaryFile(mode='w+t', suffix='.tex') as f: # optional - latex latex_package_tkz_graph ....: _ = f.write(_latex_file_(g)) ....: f.flush() - ....: _run_latex_(f.name, engine="pdflatex") + ....: _run_latex_(f.name, engine='pdflatex') 'pdf' sage: view(4, margin=5, debug=True) # not tested @@ -1830,13 +1824,11 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, sage: latex.extra_preamble('') # reset the preamble - sage: view(4, engine="garbage") + sage: view(4, engine='garbage') Traceback (most recent call last): ... ValueError: Unsupported LaTeX engine. - """ - if tightpage: if margin is None: margin_str = "" @@ -1879,16 +1871,16 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, tmp.cleanup() return output_file = os.path.join(tmp.name, "sage." + suffix) - # this should get changed if we switch the stuff in misc.viewer to - # producing lists + if debug: - print('viewer: "{}"'.format(viewer)) + print(f'temporary file: "{output_file}"') + print(f'viewer: "{viewer}"') # Return immediately but only clean up the temporary file after # the viewer has closed. This function is synchronous and waits # for the process to complete... def run_viewer(): - run([viewer, output_file], capture_output=True) + run([*viewer.split(), output_file], capture_output=True) tmp.cleanup() # ...but we execute it asynchronously so that view() completes @@ -1899,7 +1891,78 @@ def run_viewer(): t.daemon = True t.start() - return + +def pdf(x, filename, tiny=False, tightpage=True, margin=None, engine=None, debug=False): + """ + Create an image from the latex representation of ``x`` and save it as a pdf + file with the given filename. + + INPUT: + + - ``x`` -- a Sage object + + - ``filename`` -- the filename with which to save the image + + - ``tiny`` -- boolean (default: ``False``); if ``True``, use a tiny font + + - ``tightpage`` -- boolean (default: ``True``); use the LaTeX package + ``preview`` with the 'tightpage' option + + - ``margin`` -- float (default: no margin); width of border, only effective + with 'tight page' + + - ``engine`` -- (default: ``None``) ``'latex'``, ``'pdflatex'``, + ``'xelatex'`` or ``'lualatex'``; if ``None``, the value defined in the + LaTeX global preferences ``latex.engine()`` is used + + - ``debug`` -- boolean (default: ``False``); if ``True``, print verbose output + + EXAMPLES:: + + sage: # optional - latex + sage: from sage.misc.latex import pdf + sage: import tempfile + sage: with tempfile.NamedTemporaryFile(suffix=".pdf") as f: # random + ....: pdf(ZZ[x], f.name) + """ + from sage.plot.graphics import Graphics + if isinstance(x, Graphics): + x.save(filename) + return + + if tightpage: + if margin is None: + margin_str = "" + else: + margin_str = '\n\\setlength\\PreviewBorder{%fmm}' % margin + latex_options = {'extra_preamble': + '\\usepackage[tightpage,active]{preview}\n' + + '\\PreviewEnvironment{page}%s' % margin_str, + 'math_left': '\\begin{page}$', + 'math_right': '$\\end{page}'} + else: + latex_options = {} + + # create a string of latex code to write in a file + s = _latex_file_([x], title='', tiny=tiny, debug=debug, **latex_options) + if engine is None: + engine = _Latex_prefs._option["engine"] + # path name for permanent pdf output + abs_path_to_pdf = os.path.abspath(filename) + # temporary directory to store stuff + with TemporaryDirectory() as tmp: + tex_file = os.path.join(tmp, "sage.tex") + pdf_file = os.path.join(tmp, "sage.pdf") + # write latex string to file + with open(tex_file, 'w') as file: + file.write(s) + # run latex on the file + e = _run_latex_(tex_file, debug=debug, engine=engine) + if e == 'pdf': + # if no errors, copy pdf_file to the appropriate place + shutil.copy(pdf_file, abs_path_to_pdf) + else: + print("Latex error or no pdf was generated.") def png(x, filename, density=150, debug=False, @@ -1916,12 +1979,12 @@ def png(x, filename, density=150, debug=False, - ``density`` -- integer (default: 150) - - ``debug`` -- bool (default: ``False``); print verbose output + - ``debug`` -- boolean (default: ``False``); print verbose output - - ``do_in_background`` -- bool (default: ``False``); Unused, kept for + - ``do_in_background`` -- boolean (default: ``False``); unused, kept for backwards compatibility - - ``tiny`` -- bool (default: ``False``); use tiny font + - ``tiny`` -- boolean (default: ``False``); use tiny font - ``engine`` -- (default: ``None``) ``'latex'``, ``'pdflatex'``, ``'xelatex'`` or ``'lualatex'`` @@ -1931,7 +1994,7 @@ def png(x, filename, density=150, debug=False, sage: # optional - imagemagick latex, needs sage.plot sage: from sage.misc.latex import png sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # random + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # random ....: png(ZZ[x], f.name) """ import sage.plot.all @@ -1975,9 +2038,7 @@ def coeff_repr(c): - ``c`` -- a coefficient (i.e., an element of a ring) - OUTPUT: - - A string + OUTPUT: string EXAMPLES:: @@ -2010,7 +2071,7 @@ def repr_lincomb(symbols, coeffs): - ``coeffs`` -- list of coefficients of the symbols - OUTPUT: A string + OUTPUT: string EXAMPLES:: @@ -2141,7 +2202,7 @@ def latex_varify(a, is_fname=False): - ``a`` -- string - OUTPUT: A string + OUTPUT: string EXAMPLES:: @@ -2310,7 +2371,7 @@ class graph(SageObject): def _repr_(self): """ - String representation + String representation. EXAMPLES:: @@ -2334,7 +2395,7 @@ def _repr_(self): def _latex_(self): """ - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2379,7 +2440,7 @@ class pstricks(SageObject): def _repr_(self): """ - String representation + String representation. EXAMPLES:: @@ -2399,7 +2460,7 @@ def _repr_(self): def _latex_(self): """ - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2436,7 +2497,7 @@ class knot(SageObject): def _repr_(self): """ - String representation + String representation. EXAMPLES:: @@ -2455,7 +2516,7 @@ def _repr_(self): def _latex_(self): """ - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2485,7 +2546,7 @@ class diagram(SageObject): def _repr_(self): """ - String representation + String representation. EXAMPLES:: @@ -2503,7 +2564,7 @@ def _repr_(self): def _latex_(self): """ - LaTeX representation + LaTeX representation. EXAMPLES:: diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index 3ac23ff9c6e..fc389b32a72 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -50,9 +50,9 @@ def produce_latex_macro(name, *sample_args): INPUT: - - ``name`` -- name of macro to be defined, also name of corresponding Sage object + - ``name`` -- name of macro to be defined, also name of corresponding Sage object - - ``sample_args`` -- (optional) sample arguments for this Sage object + - ``sample_args`` -- (optional) sample arguments for this Sage object EXAMPLES:: @@ -110,7 +110,7 @@ def convert_latex_macro_to_mathjax(macro): INPUT: - - ``macro`` -- LaTeX macro definition + - ``macro`` -- LaTeX macro definition See the web page https://docs.mathjax.org/en/latest/input/tex/macros.html for a diff --git a/src/sage/misc/latex_standalone.py b/src/sage/misc/latex_standalone.py index f17083fdaf4..483e8f52035 100644 --- a/src/sage/misc/latex_standalone.py +++ b/src/sage/misc/latex_standalone.py @@ -247,21 +247,21 @@ class Standalone(SageObject): INPUT: - - ``content`` -- string, the content to be added in the document + - ``content`` -- string; the content to be added in the document between lines ``r'\begin{document}'`` and ``r'\end{document}'`` - - ``document_class_options`` -- list of strings (default: ``[]``), + - ``document_class_options`` -- list of strings (default: ``[]``); latex document class standalone options. Such options appear on the line ``\documentclass[...]{standalone}`` between the brackets. - - ``standalone_config`` -- list of strings (default: ``[]``), + - ``standalone_config`` -- list of strings (default: ``[]``); standalone configuration options. Such options are defined with - ``\standaloneconfig{...}`` - - ``usepackage`` -- list of strings (default: ``[]``), latex packages. - - ``macros`` -- list of strings (default: ``[]``), stuff you need for the picture. - - ``use_sage_preamble`` -- bool (default: ``False``), whether to include sage + ``\standaloneconfig{...}``. + - ``usepackage`` -- list of strings (default: ``[]``); latex packages + - ``macros`` -- list of strings (default: ``[]``); stuff you need for the picture + - ``use_sage_preamble`` -- boolean (default: ``False``); whether to include sage latex preamble and sage latex macros, that is, the content of :func:`sage.misc.latex.extra_preamble()`, :func:`sage.misc.latex.extra_macros()` and - :func:`sage.misc.latex_macros.sage_latex_macros()`. + :func:`sage.misc.latex_macros.sage_latex_macros()` EXAMPLES:: @@ -287,7 +287,6 @@ class Standalone(SageObject): \section{Intro} Test \end{document} - """ def __init__(self, content, document_class_options=None, standalone_config=None, usepackage=None, macros=None, @@ -401,7 +400,6 @@ def _repr_(self): \draw(19,-.5) -- (19,.5); \end{tikzpicture} \end{document} - """ lines = self._latex_file_header_lines() lines.append(r"\begin{document}") @@ -421,7 +419,7 @@ def _repr_(self): def _rich_repr_(self, display_manager, **kwds): r""" - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -484,7 +482,7 @@ def _rich_repr_(self, display_manager, **kwds): def __str__(self): r""" - Return the complete string of the standalone document class file + Return the complete string of the standalone document class file. EXAMPLES:: @@ -513,7 +511,7 @@ def __str__(self): def content(self): r""" - Return the content of the standalone document class file + Return the content of the standalone document class file. EXAMPLES:: @@ -536,7 +534,7 @@ def content(self): def add_document_class_option(self, option): r""" - Add a document class option + Add a document class option. INPUT: @@ -557,7 +555,7 @@ def add_document_class_option(self, option): def add_standalone_config(self, config): r""" - Add a standalone config + Add a standalone config. INPUT: @@ -574,13 +572,12 @@ def add_standalone_config(self, config): \begin{document} Hello World \end{document} - """ self._standalone_config.append(config) def add_usepackage(self, package): r""" - Add a ``usepackage`` line + Add a ``usepackage`` line. INPUT: @@ -597,13 +594,12 @@ def add_usepackage(self, package): \begin{document} Hello World \end{document} - """ self._usepackage.append(package) def add_macro(self, macro): r""" - Add a macro + Add a macro. INPUT: @@ -620,7 +616,6 @@ def add_macro(self, macro): \begin{document} Hello World \end{document} - """ self._macros.append(macro) @@ -630,20 +625,18 @@ def pdf(self, filename=None, view=True, program=None): INPUT: - - ``filename`` -- string (default: ``None``), the output filename. + - ``filename`` -- string (default: ``None``); the output filename. If ``None``, it saves the file in a temporary directory. - - ``view`` -- bool (default:``True``), whether to open the file in a + - ``view`` -- boolean (default: ``True``); whether to open the file in a pdf viewer. This option is ignored and automatically set to ``False`` if ``filename`` is not ``None``. - - ``program`` -- string (default:``None``) ``'pdflatex'`` or + - ``program`` -- string (default: ``None``); ``'pdflatex'`` or ``'lualatex'``. If ``None``, it uses ``'lualatex'`` if it is available, otherwise ``'pdflatex'``. - OUTPUT: - - string, path to pdf file + OUTPUT: string, path to pdf file EXAMPLES:: @@ -683,8 +676,7 @@ def pdf(self, filename=None, view=True, program=None): Traceback (most recent call last): ... CalledProcessError: Command '['...latex', '-interaction=nonstopmode', - 'tikz_...tex']' returned non-zero exit status 1. - + 'tikz_...tex']' returned nonzero exit status 1. """ from sage.features.latex import lualatex, pdflatex @@ -719,7 +711,7 @@ def pdf(self, filename=None, view=True, program=None): if result.returncode != 0: print("Command \n" " '{}'\n" - "returned non-zero exit status {}.\n" + "returned nonzero exit status {}.\n" "Here is the content of the stderr:{}\n" "Here is the content of the stdout:" "{}\n".format(' '.join(result.args), @@ -756,18 +748,16 @@ def dvi(self, filename=None, view=True, program='latex'): INPUT: - - ``filename`` -- string (default: ``None``), the output filename. - If ``None``, it saves the file in a temporary directory. + - ``filename`` -- string (default: ``None``); the output filename. + If ``None``, it saves the file in a temporary directory - - ``view`` -- bool (default:``True``), whether to open the file in a + - ``view`` -- boolean (default: ``True``); whether to open the file in a dvi viewer. This option is ignored and automatically set to ``False`` if ``filename`` is not ``None``. - - ``program`` -- string (default:``'latex'``), ``'latex'`` - - OUTPUT: + - ``program`` -- string (default: ``'latex'``); ``'latex'`` - string, path to dvi file + OUTPUT: string, path to dvi file EXAMPLES:: @@ -807,16 +797,15 @@ def dvi(self, filename=None, view=True, program='latex'): Traceback (most recent call last): ... CalledProcessError: Command '['latex', '-interaction=nonstopmode', - 'tikz_...tex']' returned non-zero exit status 1. + 'tikz_...tex']' returned nonzero exit status 1. We test the behavior when a wrong value is provided:: sage: t = Standalone('Hello World') - sage: _ = t.dvi(program='lates') + sage: _ = t.dvi(program='farniente') Traceback (most recent call last): ... - ValueError: program(=lates) should be latex - + ValueError: program(=farniente) should be latex """ from sage.features.latex import latex @@ -846,7 +835,7 @@ def dvi(self, filename=None, view=True, program='latex'): if result.returncode != 0: print("Command \n" " '{}'\n" - "returned non-zero exit status {}.\n" + "returned nonzero exit status {}.\n" "Here is the content of the stderr:{}\n" "Here is the content of the stdout:" "{}\n".format(' '.join(result.args), @@ -883,19 +872,17 @@ def png(self, filename=None, density=150, view=True): INPUT: - - ``filename`` -- string (default:``None``), the output filename. + - ``filename`` -- string (default: ``None``); the output filename. If ``None``, it saves the file in a temporary directory. - - ``density`` -- integer, (default: ``150``), horizontal and vertical + - ``density`` -- integer (default: ``150``); horizontal and vertical density of the image - - ``view`` -- bool (default:``True``), whether to open the file in a + - ``view`` -- boolean (default: ``True``); whether to open the file in a png viewer. This option is ignored and automatically set to ``False`` if ``filename`` is not ``None``. - OUTPUT: - - string, path to png file + OUTPUT: string, path to png file EXAMPLES:: @@ -917,7 +904,6 @@ def png(self, filename=None, density=150, view=True): sage: path_to_file = t.png(filename) # long time (1s) # optional - latex imagemagick sage: path_to_file[-4:] # long time (fast) # optional - latex imagemagick '.png' - """ from sage.features.imagemagick import ImageMagick ImageMagick().require() @@ -936,7 +922,7 @@ def png(self, filename=None, density=150, view=True): if result.returncode != 0: print("Command \n" " '{}'\n" - "returned non-zero exit status {}.\n" + "returned nonzero exit status {}.\n" "Here is the content of the stderr:{}\n" "Here is the content of the stdout:" "{}\n".format(' '.join(result.args), @@ -972,19 +958,17 @@ def svg(self, filename=None, view=True, program='pdftocairo'): INPUT: - - ``filename`` -- string (default:``None``), the output filename. + - ``filename`` -- string (default: ``None``); the output filename. If ``None``, it saves the file in a temporary directory. - - ``view`` -- bool (default:``True``), whether to open the file in + - ``view`` -- boolean (default: ``True``); whether to open the file in a browser. This option is ignored and automatically set to ``False`` if ``filename`` is not ``None``. - - ``program`` -- string (default:``'pdftocairo'``) ``'pdftocairo'`` or - ``'pdf2svg'``. + - ``program`` -- string (default: ``'pdftocairo'``); ``'pdftocairo'`` or + ``'pdf2svg'`` - OUTPUT: - - string, path to svg file + OUTPUT: string, path to svg file EXAMPLES:: @@ -1011,7 +995,6 @@ def svg(self, filename=None, view=True, program='pdftocairo'): ....: program='pdftocairo') sage: path_to_file[-4:] # long time (fast) # optional - latex pdftocairo '.svg' - """ # set the temporary filenames temp_filename_pdf = self.pdf(filename=None, view=False) @@ -1038,7 +1021,7 @@ def svg(self, filename=None, view=True, program='pdftocairo'): if result.returncode != 0: print("Command \n" " '{}'\n" - "returned non-zero exit status {}.\n" + "returned nonzero exit status {}.\n" "Here is the content of the stderr:{}\n" "Here is the content of the stdout:" "{}\n".format(' '.join(result.args), @@ -1074,19 +1057,17 @@ def eps(self, filename=None, view=True, program='dvips'): INPUT: - - ``filename`` -- string (default:``None``), the output filename. - If ``None``, it saves the file in a temporary directory. + - ``filename`` -- string (default: ``None``); the output filename. + If ``None``, it saves the file in a temporary directory - - ``view`` -- bool (default:``True``), whether to open the file in + - ``view`` -- boolean (default: ``True``); whether to open the file in a browser. This option is ignored and automatically set to ``False`` if ``filename`` is not ``None``. - - ``program`` -- string (default:``'dvips'``), + - ``program`` -- string (default: ``'dvips'``); ``'pdftocairo'`` or ``'dvips'`` - OUTPUT: - - string, path to eps file + OUTPUT: string, path to eps file EXAMPLES:: @@ -1123,7 +1104,6 @@ def eps(self, filename=None, view=True, program='dvips'): Traceback (most recent call last): ... ValueError: program(=convert) should be 'pdftocairo' or 'dvips' - """ if program == 'pdftocairo': @@ -1155,7 +1135,7 @@ def eps(self, filename=None, view=True, program='dvips'): if result.returncode != 0: print("Command \n" " '{}'\n" - "returned non-zero exit status {}.\n" + "returned nonzero exit status {}.\n" "Here is the content of the stderr:{}\n" "Here is the content of the stdout:" "{}\n".format(' '.join(result.args), @@ -1191,15 +1171,13 @@ def tex(self, filename=None, content_only=False, include_header=None): INPUT: - - ``filename`` -- string (default:``None``), the output filename. + - ``filename`` -- string (default: ``None``); the output filename. If ``None``, it saves the file in a temporary directory. - - ``content_only`` -- bool (default:``False``) whether to include + - ``content_only`` -- boolean (default: ``False``); whether to include the header latex part. If ``True``, it prints only the content to the file. - OUTPUT: - - string, path to tex file + OUTPUT: string, path to tex file EXAMPLES:: @@ -1223,7 +1201,6 @@ def tex(self, filename=None, content_only=False, include_header=None): sage: path_to_file = t.tex(filename) sage: path_to_file[-4:] '.tex' - """ if filename is None: from sage.misc.temporary_file import tmp_filename @@ -1268,9 +1245,7 @@ def save(self, filename, **kwds): All other keyword arguments will be passed to the plotter. - OUTPUT: - - - ``None`` + OUTPUT: none .. NOTE:: @@ -1289,7 +1264,6 @@ def save(self, filename, **kwds): sage: t.save(filename) # long time (1s) # optional - latex sage: filename = tmp_filename('temp','.eps') sage: t.save(filename) # long time (1s) # optional - latex dvips - """ ext = os.path.splitext(filename)[1].lower() if ext == '' or ext == '.sobj': @@ -1317,18 +1291,18 @@ class TikzPicture(Standalone): - ``content`` -- string, tikzpicture code starting with ``r'\begin{tikzpicture}'`` and ending with ``r'\end{tikzpicture}'`` - - ``standalone_config`` -- list of strings (default: ``[]``), - latex document class standalone configuration options. - - ``usepackage`` -- list of strings (default: ``[]``), latex - packages. - - ``usetikzlibrary`` -- list of strings (default: ``[]``), tikz libraries - to use. - - ``macros`` -- list of strings (default: ``[]``), stuff you need for the picture. - - ``use_sage_preamble`` -- bool (default: ``False``), whether to include sage + - ``standalone_config`` -- list of strings (default: ``[]``); + latex document class standalone configuration options + - ``usepackage`` -- list of strings (default: ``[]``); latex + packages + - ``usetikzlibrary`` -- list of strings (default: ``[]``); tikz libraries + to use + - ``macros`` -- list of strings (default: ``[]``); stuff you need for the picture + - ``use_sage_preamble`` -- boolean (default: ``False``); whether to include sage latex preamble and sage latex macros, that is, the content of :func:`sage.misc.latex.extra_preamble()`, :func:`sage.misc.latex.extra_macros()` and - :func:`sage.misc.latex_macros.sage_latex_macros()`. + :func:`sage.misc.latex_macros.sage_latex_macros()` EXAMPLES: @@ -1422,7 +1396,7 @@ def _latex_file_header_lines(self): def add_usetikzlibrary(self, library): r""" - Add a ``usetikzlibrary`` line + Add a ``usetikzlibrary`` line. INPUT: @@ -1442,7 +1416,6 @@ def add_usetikzlibrary(self, library): \draw (0,0) -- (1,1); \end{tikzpicture} \end{document} - """ self._usetikzlibrary.append(library) @@ -1459,9 +1432,9 @@ def from_dot_string(cls, dotdata, prog='dot'): INPUT: - ``dotdata`` -- dot format string - - ``prog`` -- string (default: ``'dot'``) the program used for the + - ``prog`` -- string (default: ``'dot'``); the program used for the layout corresponding to one of the software of the graphviz - suite: 'dot', 'neato', 'twopi', 'circo' or 'fdp'. + suite: ``'dot'``, ``'neato'``, ``'twopi'``, ``'circo'`` or ``'fdp'`` EXAMPLES:: @@ -1494,7 +1467,6 @@ def from_dot_string(cls, dotdata, prog='dot'): sage: dotdata = G.graphviz_string(labels='latex') sage: tikz = TikzPicture.from_dot_string(dotdata) # long time (3s), optional - dot2tex graphviz sage: _ = tikz.pdf() # not tested - """ from sage.features import PythonModule PythonModule("dot2tex").require() @@ -1531,21 +1503,21 @@ def from_graph(cls, graph, merge_multiedges=True, INPUT: - ``graph`` -- graph - - ``merge_multiedges`` -- bool (default: ``True``), if the graph + - ``merge_multiedges`` -- boolean (default: ``True``); if the graph has multiple edges, whether to merge the multiedges into one single edge - - ``merge_label_function`` -- function (default:``tuple``), a + - ``merge_label_function`` -- function (default: ``tuple``); a function to apply to each list of labels to be merged. It is ignored if ``merge_multiedges`` is not ``True`` or if the graph has no multiple edges. Other inputs are used for latex drawing with dot2tex and graphviz: - - ``prog`` -- string (default: ``'dot'``) the program used for the + - ``prog`` -- string (default: ``'dot'``); the program used for the layout corresponding to one of the software of the graphviz - suite: 'dot', 'neato', 'twopi', 'circo' or 'fdp'. - - ``edge_labels`` -- bool (default: ``True``) - - ``color_by_label`` -- bool (default: ``False``) + suite: ``'dot'``, ``'neato'``, ``'twopi'``, ``'circo'`` or ``'fdp'`` + - ``edge_labels`` -- boolean (default: ``True``) + - ``color_by_label`` -- boolean (default: ``False``) - ``rankdir`` -- string (default: ``'down'``) - ``subgraph_clusters`` -- (default: ``[]``) a list of lists of vertices, if supported by the layout engine, nodes belonging to @@ -1633,7 +1605,6 @@ def from_graph(cls, graph, merge_multiedges=True, ....: return options sage: tikz = TikzPicture.from_graph(G, edge_options=edge_options) # optional - dot2tex graphviz sage: _ = tikz.pdf() # not tested - """ from sage.features.latex import pdflatex pdflatex().require() @@ -1679,11 +1650,11 @@ def from_graph_with_pos(cls, graph, scale=1, merge_multiedges=True, INPUT: - ``graph`` -- graph (with predefined positions) - - ``scale`` -- number (default:``1``), tikzpicture scale - - ``merge_multiedges`` -- bool (default: ``True``), if the graph + - ``scale`` -- number (default: ``1``); tikzpicture scale + - ``merge_multiedges`` -- boolean (default: ``True``); if the graph has multiple edges, whether to merge the multiedges into one single edge - - ``merge_label_function`` -- function (default:``tuple``), a + - ``merge_label_function`` -- function (default: ``tuple``); a function to apply to each list of labels to be merged. It is ignored if ``merge_multiedges`` is not ``True`` or if the graph has no multiple edges. @@ -1813,11 +1784,11 @@ def from_poset(cls, poset, **kwds): INPUT: - ``poset`` -- poset - - ``prog`` -- string (default: ``'dot'``) the program used for the + - ``prog`` -- string (default: ``'dot'``); the program used for the layout corresponding to one of the software of the graphviz - suite: 'dot', 'neato', 'twopi', 'circo' or 'fdp'. - - ``edge_labels`` -- bool (default: ``True``) - - ``color_by_label`` -- bool (default: ``False``) + suite: ``'dot'``, ``'neato'``, ``'twopi'``, ``'circo'`` or ``'fdp'`` + - ``edge_labels`` -- boolean (default: ``True``) + - ``color_by_label`` -- boolean (default: ``False``) - ``rankdir`` -- string (default: ``'down'``) EXAMPLES:: diff --git a/src/sage/misc/lazy_attribute.pyx b/src/sage/misc/lazy_attribute.pyx index 4210fb7e081..7514aee1569 100644 --- a/src/sage/misc/lazy_attribute.pyx +++ b/src/sage/misc/lazy_attribute.pyx @@ -36,7 +36,6 @@ cdef class _lazy_attribute(): Traceback (most recent call last): ... NotImplementedError: Only instantiate wrapper python class - """ cdef public f @@ -67,8 +66,8 @@ cdef class _lazy_attribute(): sage: Parent.element_class - sage: Parent.element_class.__doc__[91:147] - 'The (default) class for the elements of this parent\n\n ' + sage: "The (default) class for the elements of this parent" in Parent.element_class.__doc__ + True sage: Parent.element_class.__name__ 'element_class' sage: Parent.element_class.__module__ @@ -88,7 +87,7 @@ cdef class _lazy_attribute(): sage: src[0] 'def banner():\n' sage: lines - 89 + 87 """ from sage.misc.sageinspect import sage_getsourcelines return sage_getsourcelines(self.f) @@ -513,7 +512,7 @@ class lazy_class_attribute(lazy_attribute): A lazy class attribute for a class is like a usual class attribute, except that, instead of being computed when the class is constructed, it is computed on the fly the first time it is accessed, either through the - class itself or trough on of its objects. + class itself or through one of its objects. This is very similar to :class:`lazy_attribute` except that the attribute is a class attribute. More precisely, once computed, the lazy class @@ -590,7 +589,7 @@ class lazy_class_attribute(lazy_attribute): """ def __get__(self, _, cls): """ - Implements the attribute access protocol. + Implement the attribute access protocol. EXAMPLES:: diff --git a/src/sage/misc/lazy_format.py b/src/sage/misc/lazy_format.py index 3d80bca7230..6ab9b586c5a 100644 --- a/src/sage/misc/lazy_format.py +++ b/src/sage/misc/lazy_format.py @@ -6,7 +6,7 @@ class LazyFormat(str): """ - Lazy format strings + Lazy format strings. .. NOTE:: @@ -27,7 +27,7 @@ class LazyFormat(str): sage: LazyFormat("Got `%s`; expected %s")%(3, 2/3) Got `3`; expected 2/3 - To demonstrate the lazyness, let us build an object with a broken + To demonstrate the laziness, let us build an object with a broken ``__repr__`` method:: sage: class IDontLikeBeingPrinted(): @@ -84,7 +84,7 @@ class LazyFormat(str): def __mod__(self, args): """ - Binds the lazy format string with its parameters + Bind the lazy format string with its parameters. EXAMPLES:: diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index 6d845188adc..cde9be93d7e 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -134,9 +134,7 @@ cpdef bint is_during_startup() noexcept: """ Return whether Sage is currently starting up. - OUTPUT: - - Boolean + OUTPUT: boolean TESTS:: @@ -229,9 +227,7 @@ cdef class LazyImport(): """ Return the wrapped object, importing it if necessary. - OUTPUT: - - - the wrapped object + OUTPUT: the wrapped object EXAMPLES:: @@ -365,7 +361,7 @@ cdef class LazyImport(): def __getattr__(self, attr): """ - Attribute lookup on self defers to attribute lookup on the + Attribute lookup on ``self`` defers to attribute lookup on the wrapped object. EXAMPLES:: @@ -382,7 +378,7 @@ cdef class LazyImport(): def __dir__(self): """ - Tab completion on self defers to completion on the wrapped + Tab completion on ``self`` defers to completion on the wrapped object. EXAMPLES:: @@ -396,7 +392,7 @@ cdef class LazyImport(): def __call__(self, *args, **kwds): """ - Calling self calls the wrapped object. + Calling ``self`` calls the wrapped object. EXAMPLES:: @@ -910,7 +906,7 @@ cdef class LazyImport(): def __copy__(self): """ - Support copy() + Support ``copy()``. TESTS:: @@ -931,7 +927,7 @@ cdef class LazyImport(): def __deepcopy__(self, memo=None): """ - Support copy() + Support ``copy()``. TESTS:: @@ -1003,16 +999,16 @@ def lazy_import(module, names, as_=None, *, INPUT: - - ``module`` -- a string representing the module to import + - ``module`` -- string representing the module to import - - ``names`` -- a string or list of strings representing the names to + - ``names`` -- string or list of strings representing the names to import from module - ``as_`` -- (optional) a string or list of strings representing the names of the objects in the importing module. This is analogous to ``from ... import ... as ...``. - - ``at_startup`` -- a boolean (default: ``False``); + - ``at_startup`` -- boolean (default: ``False``); whether the lazy import is supposed to be resolved at startup time - ``namespace`` -- the namespace where importing the names; by default, diff --git a/src/sage/misc/lazy_list.pyx b/src/sage/misc/lazy_list.pyx index cd750933860..ca65a92fc88 100644 --- a/src/sage/misc/lazy_list.pyx +++ b/src/sage/misc/lazy_list.pyx @@ -131,11 +131,11 @@ def lazy_list(data=None, initial_values=None, start=None, stop=None, step=None, #. or a standard Python container ``list`` or ``tuple``. - ``initial_values`` -- the beginning of the sequence that will not be computed from - the ``data`` provided. + the ``data`` provided - ``update_function`` -- you can also construct a lazy list from a function that takes as input a list of precomputed values and updates it with some - more values. + more values .. NOTE:: @@ -252,7 +252,7 @@ def lazy_list(data=None, initial_values=None, start=None, stop=None, step=None, def slice_unpickle(master, start, stop, step): r""" - Unpickle helper + Unpickle helper. TESTS:: @@ -293,9 +293,7 @@ def lazy_list_formatter(L, name='lazy list', - ``preview`` -- (default: ``3``) an integer specifying the number of elements shown in the representation string - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -351,7 +349,7 @@ def lazy_list_formatter(L, name='lazy list', cdef class lazy_list_generic(): r""" - A lazy list + A lazy list. EXAMPLES:: @@ -374,7 +372,7 @@ cdef class lazy_list_generic(): INPUT: - ``cache`` -- an optional list to be used as the cache. Be careful that - there is no copy. + there is no copy - ``start``, ``stop``, ``step`` -- for slices @@ -532,7 +530,7 @@ cdef class lazy_list_generic(): def __reduce__(self): r""" - Pickling support + Pickling support. EXAMPLES:: @@ -614,10 +612,10 @@ cdef class lazy_list_generic(): r""" Return the element at position ``i``. - If the index is not an integer, then raise a ``TypeError``. If the - argument is negative then raise a ``ValueError``. Finally, if the + If the index is not an integer, then raise a :exc:`TypeError`. If the + argument is negative then raise a :exc:`ValueError`. Finally, if the argument is beyond the size of that lazy list it raises a - ``IndexError``. + :exc:`IndexError`. EXAMPLES:: @@ -646,7 +644,7 @@ cdef class lazy_list_generic(): TypeError: unable to convert rational 1/2 to an integer """ if i < 0: - raise ValueError("indices must be non-negative") + raise ValueError("indices must be nonnegative") i = self.start + i * self.step if self._fit(i): @@ -655,7 +653,7 @@ cdef class lazy_list_generic(): def __call__(self, i): r""" - An alias for :meth:`get` + An alias for :meth:`get`. TESTS:: @@ -817,7 +815,7 @@ cdef class lazy_list_generic(): if step == 0: raise TypeError("step may not be 0") if step < 0 or start < 0 or stop < 0: - raise ValueError("slice indices must be non negative") + raise ValueError("slice indices must be nonnegative") step = step * self.step start = self.start + start * self.step @@ -928,8 +926,8 @@ cdef class lazy_list_from_iterator(lazy_list_generic): - ``iterator`` -- an iterator - - ``cache`` -- an optional list to be used as the cache. Be careful that - there is no copy. + - ``cache`` -- an optional list to be used as the cache; be careful that + there is no copy - ``stop`` -- an optional stop point @@ -1004,15 +1002,14 @@ cdef class lazy_list_from_function(lazy_list_generic): INPUT: - ``function`` -- a function that maps ``n`` to the element - at position ``n``. (This - function only needs to be defined for length larger than the length of - the cache.) + at position ``n`` (this function only needs to be defined for length + larger than the length of the cache) - ``cache`` -- an optional list to be used as the cache. Be careful that - there is no copy. + there is no copy - - ``stop`` -- an optional integer to specify the length of this lazy list. - (Otherwise it is considered infinite). + - ``stop`` -- an optional integer to specify the length of this lazy list + (Otherwise it is considered infinite) EXAMPLES:: @@ -1086,15 +1083,15 @@ cdef class lazy_list_from_update_function(lazy_list_generic): r""" INPUT: - - ``function`` -- a function that updates a list of precomputed values. + - ``function`` -- a function that updates a list of precomputed values The update function should take as input a list and make it longer (using either the methods ``append`` or ``extend``). If after a call to the update function the list of values is shorter a - ``RuntimeError`` will occurr. If no value is added then the lazy list + :exc:`RuntimeError` will occur. If no value is added then the lazy list is considered finite. - ``cache`` -- an optional list to be used as the cache. Be careful that - there is no copy. + there is no copy - ``stop`` -- an optional integer to specify the length of this lazy list (otherwise it is considered infinite) diff --git a/src/sage/misc/lazy_string.pyx b/src/sage/misc/lazy_string.pyx index a37b712c3cc..48a26c9b609 100644 --- a/src/sage/misc/lazy_string.pyx +++ b/src/sage/misc/lazy_string.pyx @@ -64,7 +64,7 @@ import types def is_lazy_string(obj): """ - Checks if the given object is a lazy string. + Check if the given object is a lazy string. EXAMPLES:: @@ -79,14 +79,14 @@ def is_lazy_string(obj): def lazy_string(f, *args, **kwargs): """ - Creates a lazy string. + Create a lazy string. INPUT: - - ``f``, either a callable or a (format) string + - ``f`` -- either a callable or a (format) string - positional arguments that are given to ``f``, either by calling or by applying it as a format string - - named arguments, that are forwarded to ``f`` if it is not a string + - named arguments that are forwarded to ``f`` if it is not a string EXAMPLES:: @@ -139,11 +139,11 @@ cdef class _LazyString(): INPUT: - - ``f``, either a callable or a (format) string - - ``args``, a tuple of arguments that are given to ``f``, either by calling + - ``f`` -- either a callable or a (format) string + - ``args`` -- tuple of arguments that are given to ``f``, either by calling or by applying it as a format string - - ``kwargs``, a dictionary of optional arguments, that are forwarded to ``f`` - if it is a callable. + - ``kwargs`` -- dictionary of optional arguments, that are forwarded to ``f`` + if it is a callable .. NOTE:: @@ -186,11 +186,11 @@ cdef class _LazyString(): """ INPUT: - - ``f``, either a callable or a (format) string - - ``args``, a tuple of arguments that are given to ``f``, either by calling + - ``f`` -- either a callable or a (format) string + - ``args`` -- tuple of arguments that are given to ``f``, either by calling or by applying it as a format string - - ``kwargs``, a dictionary of optional arguments, that are forwarded to ``f`` - if it is a callable. + - ``kwargs`` -- dictionary of optional arguments, that are forwarded to ``f`` + if it is a callable EXAMPLES:: @@ -326,7 +326,6 @@ cdef class _LazyString(): sage: s = lazy_string(f) sage: os.fspath(s) '/dev/null' - """ return str(self) @@ -511,8 +510,8 @@ cdef class _LazyString(): INPUT: - - ``args``, a tuple - - ``kwds``, a dict + - ``args`` -- tuple + - ``kwds`` -- dictionary .. NOTE:: diff --git a/src/sage/misc/meson.build b/src/sage/misc/meson.build new file mode 100644 index 00000000000..bd05d525252 --- /dev/null +++ b/src/sage/misc/meson.build @@ -0,0 +1,136 @@ +py.install_sources( + 'abstract_method.py', + 'all.py', + 'all__sagemath_environment.py', + 'all__sagemath_objects.py', + 'all__sagemath_repl.py', + 'allocator.pxd', + 'banner.py', + 'benchmark.py', + 'binary_tree.pxd', + 'bindable_class.py', + 'c3_controlled.pxd', + 'cachefunc.pxd', + 'call.py', + 'classcall_metaclass.pxd', + 'classgraph.py', + 'compat.py', + 'converting_dict.py', + 'copying.py', + 'cython.py', + 'decorators.py', + 'defaults.py', + 'dev_tools.py', + 'edit_module.py', + 'element_with_label.py', + 'explain_pickle.py', + 'fast_methods.pxd', + 'flatten.py', + 'func_persist.py', + 'function_mangling.pxd', + 'functional.py', + 'gperftools.py', + 'html.py', + 'inherit_comparison.pxd', + 'inline_fortran.py', + 'latex.py', + 'latex_macros.py', + 'latex_standalone.py', + 'lazy_format.py', + 'lazy_import_cache.py', + 'lazy_list.pxd', + 'lazy_string.pxd', + 'map_threaded.py', + 'mathml.py', + 'messaging.py', + 'method_decorator.py', + 'misc.py', + 'misc_c.pxd', + 'mrange.py', + 'multireplace.py', + 'namespace_package.py', + 'nested_class.pxd', + 'object_multiplexer.py', + 'package.py', + 'package_dir.py', + 'pager.py', + 'prandom.py', + 'profiler.py', + 'proof.py', + 'python.py', + 'random_testing.py', + 'randstate.pxd', + 'remote_file.py', + 'replace_dot_all.py', + 'repr.py', + 'rest_index_of_methods.py', + 'sage_eval.py', + 'sage_input.py', + 'sage_timeit.py', + 'sage_unittest.py', + 'sagedoc.py', + 'sagedoc_conf.py', + 'sageinspect.py', + 'search.pxd', + 'sh.py', + 'sphinxify.py', + 'superseded.py', + 'table.py', + 'temporary_file.py', + 'test_class_pickling.py', + 'test_nested_class.py', + 'timing.py', + 'trace.py', + 'unknown.py', + 'verbose.py', + 'viewer.py', + 'weak_dict.pxd', + subdir: 'sage/misc', +) + +extension_data = { + 'allocator' : files('allocator.pyx'), + 'binary_tree' : files('binary_tree.pyx'), + 'c3' : files('c3.pyx'), + 'c3_controlled' : files('c3_controlled.pyx'), + 'cachefunc' : files('cachefunc.pyx'), + 'callable_dict' : files('callable_dict.pyx'), + 'citation' : files('citation.pyx'), + 'classcall_metaclass' : files('classcall_metaclass.pyx'), + 'constant_function' : files('constant_function.pyx'), + 'derivative' : files('derivative.pyx'), + 'fast_methods' : files('fast_methods.pyx'), + 'fpickle' : files('fpickle.pyx'), + 'function_mangling' : files('function_mangling.pyx'), + 'inherit_comparison' : files('inherit_comparison.pyx'), + 'instancedoc' : files('instancedoc.pyx'), + 'lazy_attribute' : files('lazy_attribute.pyx'), + 'lazy_import' : files('lazy_import.pyx'), + 'lazy_list' : files('lazy_list.pyx'), + 'lazy_string' : files('lazy_string.pyx'), + 'misc_c' : files('misc_c.pyx'), + 'nested_class' : files('nested_class.pyx'), + 'parser' : files('parser.pyx'), + 'persist' : files('persist.pyx'), + 'pickle_old' : files('pickle_old.pyx'), + 'randstate' : files('randstate.pyx'), + 'reset' : files('reset.pyx'), + 'sage_ostools' : files('sage_ostools.pyx'), + 'sage_timeit_class' : files('sage_timeit_class.pyx'), + 'search' : files('search.pyx'), + 'session' : files('session.pyx'), + 'stopgap' : files('stopgap.pyx'), + 'weak_dict' : files('weak_dict.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/misc', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/misc/messaging.py b/src/sage/misc/messaging.py index d7f6703b4a9..98183875387 100644 --- a/src/sage/misc/messaging.py +++ b/src/sage/misc/messaging.py @@ -68,7 +68,7 @@ def pushover(message, **kwds): sage: sage.misc.messaging.pushover_defaults["user"] = "USER_TOKEN" sage: sage.misc.messaging.pushover("Hi, how are you?") # not tested - .. note:: + .. NOTE:: You may want to populate ``sage.misc.messaging.pushover_defaults`` with default values such as the default user in ``$HOME/.sage/init.sage``. diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index 3a11e1fc440..e5b3aed1ace 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -87,10 +87,10 @@ def try_read(obj, splitlines=False): INPUT: - ``obj`` -- typically a `file` or `io.BaseIO` object, but any other - object with a ``read()`` method is accepted. + object with a ``read()`` method is accepted - - ``splitlines`` -- `bool`, optional; if True, return a list of lines - instead of a string. + - ``splitlines`` -- boolean (default: ``False``); if ``True``, return a + list of lines instead of a string EXAMPLES:: @@ -187,9 +187,7 @@ def exactly_one_is_true(iterable): - ``iterable`` -- an iterable object - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -247,9 +245,7 @@ def newton_method_sizes(N): INPUT: - - - ``N`` -- positive integer - + - ``N`` -- positive integer EXAMPLES:: @@ -286,16 +282,16 @@ def newton_method_sizes(N): def compose(f, g): r""" - Return the composition of one-variable functions: `f \circ g` + Return the composition of one-variable functions: `f \circ g`. See also :func:`nest()` INPUT: - - `f` -- a function of one variable - - `g` -- another function of one variable - OUTPUT: - A function, such that compose(f,g)(x) = f(g(x)) + - ``f`` -- a function of one variable + - ``g`` -- another function of one variable + + OUTPUT: a function, such that compose(f,g)(x) = f(g(x)) EXAMPLES:: @@ -315,7 +311,6 @@ def compose(f, g): sage: _ = var('x') # needs sage.symbolic sage: compose(f, g)(x) # needs sage.symbolic f(g(x)) - """ return lambda x: f(g(x)) @@ -327,12 +322,12 @@ def nest(f, n, x): See also :func:`compose()` and :func:`self_compose()` INPUT: - - `f` -- a function of one variable - - `n` -- a nonnegative integer - - `x` -- any input for `f` - OUTPUT: - `f(f(...f(x)...))`, where the composition occurs n times + - ``f`` -- a function of one variable + - ``n`` -- nonnegative integer + - ``x`` -- any input for `f` + + OUTPUT: `f(f(...f(x)...))`, where the composition occurs n times EXAMPLES:: @@ -354,7 +349,6 @@ def nest(f, n, x): sage: _ = var('x') # needs sage.symbolic sage: nest(f, 0, x) # needs sage.symbolic x - """ from sage.rings.integer import Integer n = Integer(n) @@ -373,7 +367,7 @@ def nest(f, n, x): class BackslashOperator: r""" - Implements Matlab-style backslash operator for solving systems:: + Implement Matlab-style backslash operator for solving systems:: A \ b @@ -458,7 +452,7 @@ def __mul__(self, right): ################################################################# def is_iterator(it) -> bool: """ - Tests if it is an iterator. + Test if it is an iterator. The mantra ``if hasattr(it, 'next')`` was used to tests if ``it`` is an iterator. This is not quite correct since ``it`` could have a ``next`` @@ -517,11 +511,9 @@ def random_sublist(X, s): INPUT: + - ``X`` -- list - - ``X`` -- list - - - ``s`` -- floating point number between 0 and 1 - + - ``s`` -- floating point number between 0 and 1 OUTPUT: list @@ -576,12 +568,12 @@ def some_tuples(elements, repeat, bound, max_samples=None): INPUT: - ``elements`` -- an iterable - - ``repeat`` -- integer (default ``None``), the length of the tuples to be returned. + - ``repeat`` -- integer (default: ``None``); the length of the tuples to be returned. If ``None``, just returns entries from ``elements``. - ``bound`` -- the maximum number of tuples returned (ignored if ``max_samples`` given) - - ``max_samples`` -- non-negative integer (default ``None``). If given, + - ``max_samples`` -- nonnegative integer (default: ``None``); if given, then a sample of the possible tuples will be returned, - instead of the first few in the standard order. + instead of the first few in the standard order OUTPUT: @@ -661,8 +653,8 @@ def _some_tuples_sampling(elements, repeat, max_samples, n): def exists(S, P): """ - If S contains an element x such that P(x) is True, this function - returns True and the element x. Otherwise it returns False and + If S contains an element x such that P(x) is ``True``, this function + returns ``True`` and the element x. Otherwise it returns ``False`` and None. Note that this function is NOT suitable to be used in an @@ -673,20 +665,16 @@ def exists(S, P): INPUT: + - ``S`` -- object (that supports enumeration) - - ``S`` -- object (that supports enumeration) - - - ``P`` -- function that returns True or False - + - ``P`` -- function that returns ``True`` or ``False`` OUTPUT: + - ``bool`` -- whether or not P is ``True`` for some element + x of S - - ``bool`` -- whether or not P is True for some element - x of S - - - ``object`` -- x - + - ``object`` -- x EXAMPLES: lambda functions are very useful when using the exists function:: @@ -713,8 +701,8 @@ def exists(S, P): def forall(S, P): """ - If P(x) is true every x in S, return True and None. If there is - some element x in S such that P is not True, return False and x. + If `P(x)` is true every x in S, return ``True`` and ``None``. If there is + some element x in S such that P is not ``True``, return ``False`` and `x`. Note that this function is NOT suitable to be used in an if-statement or in any place where a boolean expression is @@ -724,18 +712,16 @@ def forall(S, P): INPUT: - - ``S`` -- object (that supports enumeration) + - ``S`` -- object (that supports enumeration) - - ``P`` -- function that returns True or False + - ``P`` -- function that returns ``True`` or ``False`` OUTPUT: + - ``bool`` -- whether or not P is ``True`` for all elements + of S - - ``bool`` -- whether or not P is True for all elements - of S - - - ``object`` -- x - + - ``object`` -- x EXAMPLES: lambda functions are very useful when using the forall function. As a toy example we test whether certain integers are @@ -928,9 +914,9 @@ def inject_variable(name, value, warn=True): INPUT: - - ``name`` -- a string + - ``name`` -- string - ``value`` -- anything - - ``warn`` -- a boolean (default: :obj:`False`) + - ``warn`` -- boolean (default: ``False``) EXAMPLES:: @@ -978,7 +964,7 @@ def inject_variable(name, value, warn=True): def inject_variable_test(name, value, depth): """ - A function for testing deep calls to inject_variable + A function for testing deep calls to ``inject_variable``. EXAMPLES:: @@ -1006,7 +992,7 @@ def inject_variable_test(name, value, depth): # from https://stackoverflow.com/questions/4103773/efficient-way-of-having-a-function-only-execute-once-in-a-loop def run_once(func): """ - Runs a function (successfully) only once. + Run a function (successfully) only once. The running can be reset by setting the ``has_run`` attribute to False @@ -1044,7 +1030,7 @@ def increase_recursion_limit(increment): INPUT: - - `increment`: increment to add to the current limit + - ``increment`` -- increment to add to the current limit EXAMPLES:: diff --git a/src/sage/misc/misc_c.pyx b/src/sage/misc/misc_c.pyx index 695806cdf69..2b7136ce584 100644 --- a/src/sage/misc/misc_c.pyx +++ b/src/sage/misc/misc_c.pyx @@ -37,7 +37,8 @@ cdef extern from *: def running_total(L, start=None): """ - Return a list where the i-th entry is the sum of all entries up to (and including) i. + Return a list where the `i`-th entry is the sum of all entries up to (and + including) `i`. INPUT: @@ -440,7 +441,8 @@ cpdef list normalize_index(object key, int size): INPUT: - - ``key`` -- the index key, which can be either an integer, a tuple/list of integers, or a slice. + - ``key`` -- the index key, which can be either an integer, a tuple/list of + integers, or a slice - ``size`` -- the size of the collection OUTPUT: @@ -622,10 +624,10 @@ cdef class sized_iter: - ``iterable`` -- object to be iterated over - - ``length`` -- (optional) the required length. If this is not - given, then ``len(iterable)`` will be used. + - ``length`` -- (optional) the required length; if this is not + given, then ``len(iterable)`` will be used - If the iterable does not have the given length, a ``ValueError`` is + If the iterable does not have the given length, a :exc:`ValueError` is raised during iteration. EXAMPLES:: diff --git a/src/sage/misc/mrange.py b/src/sage/misc/mrange.py index e0c2951329d..774008cdd70 100644 --- a/src/sage/misc/mrange.py +++ b/src/sage/misc/mrange.py @@ -69,7 +69,6 @@ def _is_finite(L, fallback=True): sage: from itertools import product sage: _is_finite(product([1],[1])) # does not provide is_finite() or __len__() True - """ try: return L.is_finite() @@ -106,7 +105,7 @@ def _xmrange_iter(iter_list, typ=list): sage: l1 is l2 False - However, if you would like to re-use the list object:: + However, if you would like to reuse the list object:: sage: iter = sage.misc.mrange._xmrange_iter( [[1,2],[1,3]], lambda x: x ) sage: l1 = next(iter) @@ -182,16 +181,16 @@ def mrange_iter(iter_list, typ=list): More precisely, return the iterator over all objects of type ``typ`` of n-tuples of Python ints with entries between 0 and the integers in the sizes list. The iterator is empty if sizes is empty or contains - any non-positive integer. + any nonpositive integer. INPUT: - - ``iter_list`` -- a finite iterable of finite iterables + - ``iter_list`` -- a finite iterable of finite iterables - - ``typ`` -- (default: list) a type or class; more - generally, something that can be called with a list as input. + - ``typ`` -- (default: list) a type or class; more + generally, something that can be called with a list as input - OUTPUT: a list + OUTPUT: list EXAMPLES:: @@ -228,24 +227,24 @@ class xmrange_iter: Return the multirange iterate derived from the given iterators and type. - .. note:: + .. NOTE:: This basically gives you the Cartesian product of sets. More precisely, return the iterator over all objects of type typ of n-tuples of Python ints with entries between 0 and the integers in the sizes list. The iterator is empty if sizes is empty or contains - any non-positive integer. + any nonpositive integer. Use :func:`mrange_iter` for the non-iterator form. INPUT: - - ``iter_list`` -- a list of objects usable as iterators (possibly - lists) + - ``iter_list`` -- list of objects usable as iterators (possibly + lists) - ``typ`` -- (default: list) a type or class; more generally, - something that can be called with a list as input. + something that can be called with a list as input OUTPUT: a generator @@ -336,7 +335,7 @@ def __len__(self): """ Return the cardinality of this iterator as an int. - This raises a :class:`TypeError` if the cardinality does not fit + This raises a :exc:`TypeError` if the cardinality does not fit into a Python int. EXAMPLES:: @@ -433,16 +432,16 @@ def mrange(sizes, typ=list): More precisely, return the iterator over all objects of type typ of n-tuples of Python ints with entries between 0 and the integers in the sizes list. The iterator is empty if sizes is empty or contains - any non-positive integer. + any nonpositive integer. INPUT: - - ``sizes`` -- a list of nonnegative integers + - ``sizes`` -- list of nonnegative integers - - ``typ`` -- (default: list) a type or class; more - generally, something that can be called with a list as input. + - ``typ`` -- (default: list) a type or class; more + generally, something that can be called with a list as input - OUTPUT: a list + OUTPUT: list EXAMPLES:: @@ -483,18 +482,16 @@ class xmrange: More precisely, return the iterator over all objects of type typ of n-tuples of Python ints with entries between 0 and the integers in the sizes list. The iterator is empty if sizes is empty or contains - any non-positive integer. + any nonpositive integer. Use mrange for the non-iterator form. INPUT: + - ``sizes`` -- list of nonnegative integers - - ``sizes`` -- a list of nonnegative integers - - - ``typ`` -- (default: list) a type or class; more - generally, something that can be called with a list as input. - + - ``typ`` -- (default: list) a type or class; more + generally, something that can be called with a list as input OUTPUT: a generator @@ -604,7 +601,7 @@ def cartesian_product_iterator(X): INPUT: - - ``X`` -- list or tuple of lists + - ``X`` -- list or tuple of lists OUTPUT: iterator over the Cartesian product of the elements of X @@ -639,7 +636,7 @@ def cantor_product(*args, **kwds): - a certain number of iterables - ``repeat`` -- an optional integer. If it is provided, the input is - repeated ``repeat`` times. + repeated ``repeat`` times Other keyword arguments are passed to :class:`sage.combinat.integer_lists.invlex.IntegerListsLex`. diff --git a/src/sage/misc/nested_class.pyx b/src/sage/misc/nested_class.pyx index 7e5d00c15d8..e42569abe3e 100644 --- a/src/sage/misc/nested_class.pyx +++ b/src/sage/misc/nested_class.pyx @@ -11,15 +11,15 @@ incompatible with the pickling of such classes (pickling by name):: sage: A.B.__name__ 'B' -instead of more natural ``"A.B"``. Furthermore upon pickling *and* unpickling a -class with name ``"A.B"`` in a module ``mod``, the standard cPickle module -searches for ``"A.B"`` in ``mod.__dict__`` instead of looking up ``"A"`` and -then ``"B"`` in the result. See: https://groups.google.com/forum/#!topic/sage-devel/bHBV9KWAt64 +instead of more natural ``'A.B'``. Furthermore upon pickling *and* unpickling a +class with name ``'A.B'`` in a module ``mod``, the standard cPickle module +searches for ``'A.B'`` in ``mod.__dict__`` instead of looking up ``'A'`` and +then ``'B'`` in the result. See: https://groups.google.com/forum/#!topic/sage-devel/bHBV9KWAt64 This module provides two utilities to workaround this issue: - :func:`nested_pickle` "fixes" recursively the name of the subclasses of a - class and inserts their fullname ``"A.B"`` in ``mod.__dict__`` + class and inserts their fullname ``'A.B'`` in ``mod.__dict__`` - :class:`NestedClassMetaclass` is a metaclass ensuring that :func:`nested_pickle` is called on a class upon creation. @@ -30,8 +30,8 @@ See also :mod:`sage.misc.test_nested_class`. In Python 3, nested classes, like any class for that matter, have ``__qualname__`` and the standard pickle module uses it for pickling and - unpickling. Thus the pickle module searches for ``"A.B"`` first by looking - up ``"A"`` in ``mod``, and then ``"B"`` in the result. So there is no + unpickling. Thus the pickle module searches for ``'A.B'`` first by looking + up ``'A'`` in ``mod``, and then ``'B'`` in the result. So there is no pickling problem for nested classes in Python 3, and the two utilities are not really necessary. However, :class:`NestedClassMetaclass` is used widely in Sage and affects behaviors of Sage objects in other respects than in @@ -81,7 +81,7 @@ All of this is not perfect. In the following scenario:: sage: B1.A2 -The name for ``"A1.A2"`` could potentially be set to ``"B1.A2"``. But that will work anyway. +The name for ``'A1.A2'`` could potentially be set to ``'B1.A2'``. But that will work anyway. """ import sys @@ -108,7 +108,7 @@ cpdef modify_for_nested_pickle(cls, str name_prefix, module, first_run=True): - ``module`` -- the module object to modify with the mangled name - - ``first_run`` -- optional bool (default ``True``): whether or not + - ``first_run`` -- boolean (default: ``True``); whether or not this function is run for the first time on ``cls`` NOTE: @@ -177,7 +177,6 @@ cpdef modify_for_nested_pickle(cls, str name_prefix, module, first_run=True): 'A1.B1.C1' sage: getattr(A_module, 'A1.B2.C2', 'Not found').__name__ 'A1.B2.C2' - """ cdef str name, dotted_name cdef str mod_name = module.__name__ @@ -228,8 +227,8 @@ def nested_pickle(cls): sage: nested_pickle(A) - then the name of class ``"B"`` will be modified to ``"A.B"``, and the ``"A.B"`` - attribute of the module will be set to class ``"B"``:: + then the name of class ``'B'`` will be modified to ``'A.B'``, and the ``'A.B'`` + attribute of the module will be set to class ``'B'``:: sage: A.B.__name__ 'A.B' @@ -336,12 +335,11 @@ class MainClass(object, metaclass=NestedClassMetaclass): sage: from sage.misc.nested_class import MainClass sage: print(MainClass.NestedClass.NestedSubClass.dummy.__doc__) NestedSubClass.dummy(self, x, *args, r=(1, 2, 3.4), **kwds) - File: sage/misc/nested_class.pyx (starting at line ...) + File: ...sage/misc/nested_class.pyx (starting at line ...) A dummy method to demonstrate the embedding of method signature for nested classes. ... - """ pass diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index c144cfca6f9..7ccead8cbfe 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -39,7 +39,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from typing import Dict, List, NamedTuple, Optional, Union +from typing import NamedTuple, Optional, Union import sage.env @@ -78,10 +78,10 @@ def pip_remote_version(pkg, pypi_url=DEFAULT_PYPI, ignore_URLError=False): - ``pkg`` -- the package - - ``pypi_url`` -- (string, default: standard PyPI url) an optional Python + - ``pypi_url`` -- string (default: standard PyPI url) an optional Python package repository to use - - ``ignore_URLError`` -- (default: ``False``) if set to ``True`` then no + - ``ignore_URLError`` -- boolean (default: ``False``); if set to ``True`` then no error is raised if the connection fails and the function returns ``None`` EXAMPLES: @@ -144,7 +144,7 @@ def spkg_type(name): The type as a string in ``('base', 'standard', 'optional', 'experimental')``. If no ``SPKG`` exists with the given name (or the directory ``SAGE_PKGS`` is - not avaialble), ``None`` is returned. + not available), ``None`` is returned. """ spkg_type = None from sage.env import SAGE_PKGS @@ -230,18 +230,18 @@ def is_installed(self) -> bool: return self.installed_version is not None -def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 'script'], - local: bool = False, ignore_URLError: bool = False, exclude_pip: bool = False) -> Dict[str, PackageInfo]: +def list_packages(*pkg_types: str, pkg_sources: list[str] = ['normal', 'pip', 'script'], + local: bool = False, ignore_URLError: bool = False, exclude_pip: bool = False) -> dict[str, PackageInfo]: r""" Return a dictionary of information about each package. The keys are package names and values are named tuples with the following keys: - - ``'type'``: either ``'base``, ``'standard'``, ``'optional'``, or ``'experimental'`` - - ``'source'``: either ``'normal', ``'pip'``, or ``'script'`` - - ``'installed'``: boolean - - ``'installed_version'``: ``None`` or a string - - ``'remote_version'``: string + - ``'type'`` -- either ``'base``, ``'standard'``, ``'optional'``, or ``'experimental'`` + - ``'source'`` -- either ``'normal', ``'pip'``, or ``'script'`` + - ``'installed'`` -- boolean + - ``'installed_version'`` -- ``None`` or a string + - ``'remote_version'`` -- string INPUT: @@ -253,15 +253,15 @@ def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 's If provided, list only the packages with the given source(s), otherwise list all packages. - - ``local`` -- (default: ``False``) if set to ``True``, then do not + - ``local`` -- boolean (default: ``False``); if set to ``True``, then do not consult remote (PyPI) repositories for package versions (only applicable for ``'pip'`` type) - - ``exclude_pip`` -- (default: ``False``) if set to ``True``, then + - ``exclude_pip`` -- boolean (default: ``False``); if set to ``True``, then pip packages are not considered. This is the same as removing ``'pip'`` - from ``pkg_sources``. + from ``pkg_sources`` - - ``ignore_URLError`` -- (default: ``False``) if set to ``True``, then + - ``ignore_URLError`` -- boolean (default: ``False``); if set to ``True``, then connection errors will be ignored EXAMPLES:: @@ -371,7 +371,6 @@ def _spkg_inst_dirs(): sage: from sage.misc.package import _spkg_inst_dirs sage: list(_spkg_inst_dirs()) [...] - """ last_inst_dir = None for inst_dir in (sage.env.SAGE_LOCAL_SPKG_INST, sage.env.SAGE_VENV_SPKG_INST): @@ -388,7 +387,7 @@ def installed_packages(exclude_pip=True): INPUT: - - ``exclude_pip`` -- (default: ``True``) whether "pip" packages + - ``exclude_pip`` -- boolean (default: ``True``); whether "pip" packages are excluded from the list EXAMPLES: @@ -403,9 +402,9 @@ def installed_packages(exclude_pip=True): sage: # optional - sage_spkg sage: from sage.misc.package import installed_packages sage: sorted(installed_packages().keys()) - [...'conway_polynomials', ...] - sage: installed_packages()['conway_polynomials'] # random - '0.5' + [...'gnulib', ...] + sage: installed_packages()['gnulib'] # random + 'f9b39c4e337f1dc0dd07c4f3985c476fb875d799' .. SEEALSO:: @@ -434,14 +433,13 @@ def is_package_installed(package, exclude_pip=True): - ``package`` -- the name of the package - - ``exclude_pip`` -- (default: ``True``) whether to consider pip + - ``exclude_pip`` -- boolean (default: ``True``); whether to consider pip type packages - EXAMPLES:: sage: from sage.misc.package import is_package_installed - sage: is_package_installed('conway_polynomials') # optional - sage_spkg + sage: is_package_installed('gnulib') # optional - sage_spkg True Giving just the beginning of the package name is not good enough:: @@ -470,7 +468,7 @@ def is_package_installed_and_updated(package: str) -> bool: INPUT: - - ``package`` -- the name of the package. + - ``package`` -- the name of the package EXAMPLES:: @@ -493,10 +491,10 @@ def package_versions(package_type, local=False): INPUT: - - ``package_type`` -- (string) one of ``"standard"``, ``"optional"`` or - ``"experimental"`` + - ``package_type`` -- string; one of ``'standard'``, ``'optional'`` or + ``'experimental'`` - - ``local`` -- (boolean, default: ``False``) only query local data (no internet needed) + - ``local`` -- boolean (default: ``False``); only query local data (no internet needed) For packages of the given type, return a dictionary whose entries are of the form ``'package': (installed, latest)``, where @@ -539,8 +537,8 @@ def package_manifest(package): sage: # optional - sage_spkg sage: from sage.misc.package import package_manifest - sage: manifest = package_manifest('conway_polynomials') - sage: manifest['package_name'] == 'conway_polynomials' + sage: manifest = package_manifest('gnulib') + sage: manifest['package_name'] == 'gnulib' True sage: 'files' in manifest True diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index a16f144f400..b15374e3bbc 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -106,8 +106,8 @@ def read_distribution(src_file): OUTPUT: - - a string, the name of the distribution package (``PKG``); or the empty - string if no directive was found. + A string, the name of the distribution package (``PKG``), or the empty + string if no directive was found. EXAMPLES:: @@ -251,7 +251,7 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): INPUT: - - ``path`` -- a directory name. + - ``path`` -- a directory name - ``distribution_filter`` -- (default: ``None``) only consider ``all*.py`` files whose distribution (from a @@ -307,7 +307,7 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): @contextmanager def cython_namespace_package_support(): r""" - Activate namespace package support in Cython 0.x + Activate namespace package support in Cython 0.x. See https://github.com/cython/cython/issues/2918#issuecomment-991799049 """ @@ -333,16 +333,16 @@ def walk_packages(path=None, prefix='', onerror=None): INPUT: - - ``path`` -- a list of paths to look for modules in or - ``None`` (all accessible modules). + - ``path`` -- list of paths to look for modules in or + ``None`` (all accessible modules) - - ``prefix`` -- a string to output on the front of every module name - on output. + - ``prefix`` -- string to output on the front of every module name + on output - ``onerror`` -- a function which gets called with one argument (the name of the package which was being imported) if any exception occurs while trying to import a package. If ``None``, ignore - :class:`ImportError` but propagate all other exceptions. + :exc:`ImportError` but propagate all other exceptions. EXAMPLES:: @@ -469,7 +469,7 @@ def _distribution_from_all_filename(filename): "do not change files that already have a nonempty directive")) parser.add_argument('--set', metavar='DISTRIBUTION', type=str, default=None, help="add or update the 'sage_setup: DISTRIBUTION' directive in FILES") - parser.add_argument('--from-egg-info', action="store_true", default=False, + parser.add_argument('--from-egg-info', action='store_true', default=False, help="take FILES from pkgs/DISTRIBUTION/DISTRIBUTION.egg-info/SOURCES.txt") parser.add_argument("filename", metavar='FILES', nargs='*', type=str, help=("source files or directories (default: all files from SAGE_SRC, " diff --git a/src/sage/misc/parser.pyx b/src/sage/misc/parser.pyx index e9015d1cbcc..7a2c2cc99a4 100644 --- a/src/sage/misc/parser.pyx +++ b/src/sage/misc/parser.pyx @@ -330,7 +330,7 @@ cdef class Tokenizer: cpdef int next(self) noexcept: """ - Returns the next token in the string. + Return the next token in the string. EXAMPLES:: @@ -353,7 +353,7 @@ cdef class Tokenizer: cpdef int last(self) noexcept: """ - Returns the last token seen. + Return the last token seen. EXAMPLES:: @@ -372,8 +372,8 @@ cdef class Tokenizer: cpdef int peek(self) noexcept: """ - Returns the next token that will be encountered, without changing - the state of self. + Return the next token that will be encountered, without changing + the state of ``self``. EXAMPLES:: @@ -397,8 +397,8 @@ cdef class Tokenizer: cpdef bint backtrack(self) except -2: """ - Put self in such a state that the subsequent call to next() will - return the same as if next() had not been called. + Put ``self`` in such a state that the subsequent call to ``next()`` + will return the same as if ``next()`` had not been called. Currently, one can only backtrack once. @@ -457,18 +457,18 @@ cdef class Parser: INPUT: - - make_int -- callable object to construct integers from strings (default int) - - make_float -- callable object to construct real numbers from strings (default float) - - make_var -- callable object to construct variables from strings (default str) + - ``make_int`` -- callable object to construct integers from strings (default: int) + - ``make_float`` -- callable object to construct real numbers from strings (default: float) + - ``make_var`` -- callable object to construct variables from strings (default: str) this may also be a dictionary of variable names - - make_function -- callable object to construct callable functions from strings + - ``make_function`` -- callable object to construct callable functions from strings this may also be a dictionary - - implicit_multiplication -- whether or not to accept implicit multiplication + - ``implicit_multiplication`` -- whether or not to accept implicit multiplication OUTPUT: - The evaluated expression tree given by the string, where the above - functions are used to create the leaves of this tree. + The evaluated expression tree given by the string, where the above + functions are used to create the leaves of this tree. EXAMPLES:: @@ -596,7 +596,7 @@ cdef class Parser: cpdef p_matrix(self, Tokenizer tokens): """ - Parse a matrix + Parse a matrix. EXAMPLES:: @@ -897,7 +897,6 @@ cdef class Parser: factorial(x^2) sage: p.p_factor(Tokenizer('x!^2')) factorial(x)^2 - """ operand1 = self.p_atom(tokens) cdef int token = tokens.next() @@ -976,7 +975,7 @@ cdef class Parser: # args = arg (',' arg)* | EMPTY cpdef p_args(self, Tokenizer tokens): """ - Returns a list, dict pair. + Return a ``list, dict`` pair. EXAMPLES:: @@ -1006,8 +1005,8 @@ cdef class Parser: # arg = expr | name '=' expr cpdef p_arg(self, Tokenizer tokens): """ - Returns an expr, or a (name, expr) tuple corresponding to a single - function call argument. + Return an ``expr``, or a ``(name, expr)`` tuple corresponding to a + single function call argument. EXAMPLES: @@ -1031,7 +1030,6 @@ cdef class Parser: sage: p = Parser(make_var=var) # needs sage.symbolic sage: p.p_arg(Tokenizer("[x]")) # needs sage.symbolic [x] - """ cdef int token = tokens.next() if token == NAME and tokens.peek() == c'=': diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index d299ec304cb..55540dc27b7 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -10,7 +10,7 @@ Object persistence You can load and save most Sage object to disk using the load and save member functions and commands. -.. note:: +.. NOTE:: It is impossible to save certain Sage objects to disk. For example, if `x` is a MAGMA object, i.e., a wrapper around an object @@ -142,7 +142,7 @@ def load(*filename, compress=True, verbose=True, **kwargs): Files with a ``.sage`` extension are preparsed. Also note that we can access global variables:: - sage: t = tmp_filename(ext=".sage") + sage: t = tmp_filename(ext='.sage') sage: with open(t, 'w') as f: ....: _ = f.write("a += Mod(2/3, 11)") # This evaluates to Mod(8, 11) sage: a = -1 @@ -153,7 +153,7 @@ def load(*filename, compress=True, verbose=True, **kwargs): We can load Fortran files:: sage: code = ' subroutine hello\n print *, "Hello World!"\n end subroutine hello\n' - sage: t = tmp_filename(ext=".F") + sage: t = tmp_filename(ext='.F') sage: with open(t, 'w') as f: ....: _ = f.write(code) sage: load(t) # needs numpy @@ -273,7 +273,7 @@ def save(obj, filename, compress=True, **kwargs): Check that :issue:`11577` is fixed:: sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".bar") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.bar') as f: ....: save((1,1), f.name) ....: load(f.name) (1, 1) @@ -525,7 +525,6 @@ def register_unpickle_override(module, name, callable, call_name=None): # tuple as input. All kinds of problems happen # if we don't do this. return sage.rings.integer.make_integer, (self.str(32),) - """ unpickle_override[(module, name)] = (callable, call_name) @@ -714,7 +713,7 @@ class SagePickler(_BasePickler): INPUT: - ``file_obj`` -- a readable file-like object returning ``bytes`` from - which the pickle data will be loaded. + which the pickle data will be loaded - ``persistent_id`` -- callable or None; if given this callable takes a single object to be pickled, and returns an "ID" (a key with which to @@ -788,7 +787,6 @@ class SagePickler(_BasePickler): Traceback (most recent call last): ... UnicodeDecodeError: 'ascii' codec can...t decode byte 0x80 in position 0: ordinal not in range(128) - """ def __init__(self, file_obj, persistent_id=None, py2compat=True): @@ -808,14 +806,12 @@ class SagePickler(_BasePickler): INPUT: - - ``obj`` -- the object to pickle. + - ``obj`` -- the object to pickle - ``kwargs`` -- keyword arguments passed to the - :class:`sage.misc.persist.SagePickler` constructor. - - OUTPUT: + :class:`sage.misc.persist.SagePickler` constructor - - ``pickle`` -- the pickled object as ``bytes``. + OUTPUT: ``pickle`` -- the pickled object as ``bytes`` EXAMPLES:: @@ -847,7 +843,7 @@ class SageUnpickler(_BaseUnpickler): INPUT: - ``file_obj`` -- a readable file-like object returning ``bytes`` from - which the pickle data will be loaded. + which the pickle data will be loaded - ``persistent_load`` -- callable or None; if given this callable implements loading of persistent external objects. The function @@ -856,7 +852,7 @@ class SageUnpickler(_BaseUnpickler): for more details. - ``kwargs`` -- additional keyword arguments passed to the - ``pickle.Unpickler`` constructor. + ``pickle.Unpickler`` constructor .. _pickling and unpickling external objects: https://docs.python.org/2.7/library/pickle.html#pickling-and-unpickling-external-objects @@ -894,15 +890,12 @@ class SageUnpickler(_BaseUnpickler): INPUT: - - ``data`` -- the pickle data as ``bytes``. + - ``data`` -- the pickle data as ``bytes`` - ``kwargs`` -- keyword arguments passed to the - :class:`sage.misc.persist.SageUnpickler` constructor. - - OUTPUT: - - - ``obj`` -- the object that was serialized to the given pickle data. + :class:`sage.misc.persist.SageUnpickler` constructor + OUTPUT: ``obj`` -- the object that was serialized to the given pickle data EXAMPLES:: @@ -931,9 +924,9 @@ def loads(s, compress=True, **kwargs): [ 1 2] [ 3 -4/3] - If compress is True (the default), it will try to decompress + If compress is ``True`` (the default), it will try to decompress the data with zlib and with bz2 (in turn); if neither succeeds, - it will assume the data is actually uncompressed. If compress=False + it will assume the data is actually uncompressed. If ``compress==False`` is explicitly specified, then no decompression is attempted. Further arguments are passed to python's :func:`pickle.load`. @@ -1020,7 +1013,7 @@ def picklejar(obj, dir=None): - ``obj`` -- a pickleable object - - ``dir`` -- a string or None; if None then ``dir`` defaults to + - ``dir`` -- string or ``None``; if ``None`` then ``dir`` defaults to ``DOT_SAGE/pickle_jar`` EXAMPLES:: @@ -1098,14 +1091,14 @@ def unpickle_all(target, debug=False, run_test_suite=False): INPUT: - - ``target`` -- a string; the name of a directory or of a (possibly + - ``target`` -- string; the name of a directory or of a (possibly compressed) tar archive that contains a single directory of ``.sobj`` files. The tar archive can be in any format that python's ``tarfile`` module understands; for example, ``.tar.gz`` or ``.tar.bz2``. - - ``debug`` -- a boolean (default: ``False``) + - ``debug`` -- boolean (default: ``False``) whether to report a stacktrace in case of failure - - ``run_test_suite`` -- a boolean (default: ``False``) + - ``run_test_suite`` -- boolean (default: ``False``) whether to run ``TestSuite(x).run()`` on the unpickled objects OUTPUT: @@ -1114,7 +1107,7 @@ def unpickle_all(target, debug=False, run_test_suite=False): of successfully unpickled files, and the second reporting the number (zero) of failures. If there are failures, however, then a list of failed files will be printed before either of those lines, - and the failure count will of course be non-zero. + and the failure count will of course be nonzero. .. WARNING:: @@ -1147,7 +1140,7 @@ def unpickle_all(target, debug=False, run_test_suite=False): # 706 for background. with tarfile.open(target) as tf: if hasattr(tarfile, "data_filter"): - tf.extractall(T, filter="data") + tf.extractall(T, filter='data') else: tf.extractall(T) diff --git a/src/sage/misc/prandom.py b/src/sage/misc/prandom.py index c8b41a5e95d..dbfa9ff7085 100644 --- a/src/sage/misc/prandom.py +++ b/src/sage/misc/prandom.py @@ -297,7 +297,7 @@ def expovariate(lambd): def gammavariate(alpha, beta): r""" - Gamma distribution. Not the gamma function! + Gamma distribution. (Not the gamma function.) Conditions on the parameters are alpha > 0 and beta > 0. diff --git a/src/sage/misc/profiler.py b/src/sage/misc/profiler.py index 82746c8f023..37d1e76e99c 100644 --- a/src/sage/misc/profiler.py +++ b/src/sage/misc/profiler.py @@ -82,9 +82,10 @@ class Profiler: def __init__(self, systems=[], verbose=False): """ INPUT: - systems -- a list of interfaces to other system which implements a cputime - method. The cputimes of all provided systems will be added - to the cputime of Sage itself. + + - ``systems`` -- list of interfaces to other system which implements a + cputime method. The cputimes of all provided systems will be added + to the cputime of Sage itself. """ systems = [e.cputime for e in systems] self._cputime_functions = [cputime] + list(systems) @@ -152,7 +153,7 @@ def __repr__(self): def print_last(self): """ - Prints the last profiler step + Print the last profiler step. """ if not self._checkpoints: return "" diff --git a/src/sage/misc/python.py b/src/sage/misc/python.py index d446dfe604d..fcbf8e4dafd 100644 --- a/src/sage/misc/python.py +++ b/src/sage/misc/python.py @@ -3,7 +3,7 @@ class Python: """ - Allows for evaluating a chunk of code without any preparsing. + Allow for evaluating a chunk of code without any preparsing. """ def eval(self, x, globals, locals=None): @@ -15,8 +15,8 @@ def eval(self, x, globals, locals=None): INPUT: - - ``x`` -- a string - - ``globals`` -- a dictionary + - ``x`` -- string + - ``globals`` -- dictionary - ``locals`` -- completely IGNORED EXAMPLES:: diff --git a/src/sage/misc/random_testing.py b/src/sage/misc/random_testing.py index 2625e6ec1e1..bda8cee6ba6 100644 --- a/src/sage/misc/random_testing.py +++ b/src/sage/misc/random_testing.py @@ -21,10 +21,10 @@ def random_testing(fn): INPUT: - - ``fn`` -- The function that we are wrapping for random testing. + - ``fn`` -- the function that we are wrapping for random testing The resulting function will take two additional arguments, *seed* - (default ``None``) and *print_seed* (default ``False``). The + (default: ``None``) and *print_seed* (default: ``False``). The result will set the random number seed to the given seed value (or to a truly random value, if *seed* is not specified), then call the original function. If *print_seed* is true, then the seed will diff --git a/src/sage/misc/randstate.pyx b/src/sage/misc/randstate.pyx index f1aefafd68a..79435da9ce7 100644 --- a/src/sage/misc/randstate.pyx +++ b/src/sage/misc/randstate.pyx @@ -283,7 +283,7 @@ this module correctly. Otherwise, it depends on what random number generator you want to use. -- ``gmp_randstate_t`` -- If you want to use some random number +- ``gmp_randstate_t`` -- if you want to use some random number generator that takes a ``gmp_randstate_t`` (like ``mpz_urandomm`` or ``mpfr_urandomb``), then use code like the following:: @@ -298,7 +298,7 @@ Otherwise, it depends on what random number generator you want to use. every function that wants to use it; don't cache it globally or in a class. (Such caching would break ``set_random_seed``). -- ``Python`` -- If you want to use the random number generators from +- ``Python`` -- if you want to use the random number generators from the :mod:`random` module, you have two choices. The slightly easier choice is to import functions from :mod:`sage.misc.prandom`; for instance, you can simply replace @@ -319,7 +319,7 @@ Otherwise, it depends on what random number generator you want to use. :class:`Random` object globally or in a class. (Such caching would break ``set_random_seed``). -- ``GAP`` -- If you are calling code in GAP that uses random numbers, +- ``GAP`` -- if you are calling code in GAP that uses random numbers, call ``set_seed_gap`` at the beginning of your function, like this:: from sage.misc.randstate import current_randstate @@ -332,7 +332,7 @@ Otherwise, it depends on what random number generator you want to use. don't cache it globally or in a class. (Such caching would break ``set_random_seed``). -- ``Pari`` -- If you are calling code in the Pari library that uses +- ``Pari`` -- if you are calling code in the Pari library that uses random numbers, call ``set_seed_pari`` at the beginning of your function, like this:: @@ -346,7 +346,7 @@ Otherwise, it depends on what random number generator you want to use. don't cache it globally or in a class. (Such caching would break ``set_random_seed``). -- ``Pari/gp`` -- If you are calling code in a Pari/gp subprocess that +- ``Pari/gp`` -- if you are calling code in a Pari/gp subprocess that uses random numbers, call ``set_seed_gp`` at the beginning of your function, like this:: @@ -363,7 +363,7 @@ Otherwise, it depends on what random number generator you want to use. every function that wants to use it; don't cache it globally or in a class. (Such caching would break ``set_random_seed``). -- ``NTL`` -- If you are calling code in the NTL library that uses +- ``NTL`` -- if you are calling code in the NTL library that uses random numbers, call ``set_seed_ntl`` at the beginning of your function, like this:: @@ -376,7 +376,7 @@ Otherwise, it depends on what random number generator you want to use. don't cache it globally or in a class. (Such caching would break ``set_random_seed``). -- ``libc`` -- If you are writing code that calls the libc function +- ``libc`` -- if you are writing code that calls the libc function :func:`random()`: don't! The :func:`random()` function does not give reproducible results across different operating systems, so we can't make portable doctests for the results. Instead, do:: @@ -642,7 +642,7 @@ cdef class randstate: cpdef set_seed_libc(self, bint force): r""" - Checks to see if ``self`` was the most recent :class:`randstate` + Check to see if ``self`` was the most recent :class:`randstate` to seed the libc random number generator. If not, seeds the libc random number generator. (Do not use the libc random number generator if you have a choice; its randomness is poor, @@ -667,7 +667,7 @@ cdef class randstate: cpdef set_seed_ntl(self, bint force): r""" - Checks to see if ``self`` was the most recent :class:`randstate` + Check to see if ``self`` was the most recent :class:`randstate` to seed the NTL random number generator. If not, seeds the generator. If the argument ``force`` is ``True``, seeds the generator unconditionally. @@ -693,7 +693,7 @@ cdef class randstate: def set_seed_gap(self): r""" - Checks to see if ``self`` was the most recent :class:`randstate` + Check to see if ``self`` was the most recent :class:`randstate` to seed the GAP random number generator. If not, seeds the generator. @@ -730,7 +730,7 @@ cdef class randstate: def set_seed_gp(self, gp=None): r""" - Checks to see if ``self`` was the most recent :class:`randstate` + Check to see if ``self`` was the most recent :class:`randstate` to seed the random number generator in the given instance of gp. (If no instance is given, uses the one in :class:`gp `.) If not, seeds the generator. @@ -771,7 +771,7 @@ cdef class randstate: def set_seed_pari(self): r""" - Checks to see if ``self`` was the most recent :class:`randstate` to + Check to see if ``self`` was the most recent :class:`randstate` to seed the Pari random number generator. If not, seeds the generator. @@ -807,7 +807,7 @@ cdef class randstate: cpdef int c_random(self) noexcept: r""" - Returns a 31-bit random number. Intended for internal + Return a 31-bit random number. Intended for internal use only; instead of calling ``current_randstate().c_random()``, it is equivalent (but probably faster) to call the :meth:`random ` method of this @@ -830,7 +830,7 @@ cdef class randstate: cpdef double c_rand_double(self) noexcept: r""" - Returns a random floating-point number between 0 and 1. + Return a random floating-point number between 0 and 1. EXAMPLES:: @@ -956,7 +956,7 @@ seed = randstate cpdef int random() noexcept: r""" - Returns a 31-bit random number. Intended as a drop-in replacement for + Return a 31-bit random number. Intended as a drop-in replacement for the libc :func:`random()` function. EXAMPLES:: @@ -971,7 +971,7 @@ cpdef int random() noexcept: def initial_seed(): r""" - Returns the initial seed used to create the current :class:`randstate`. + Return the initial seed used to create the current :class:`randstate`. EXAMPLES:: @@ -1031,7 +1031,7 @@ def benchmark_mt(): cpdef int _doctest_libc_random() noexcept: r""" - Returns the result of :func:`random()` from libc. + Return the result of :func:`random()` from libc. Only for use in doctests; this should not actually be used in Sage, since the resulting random number stream is not portable across diff --git a/src/sage/misc/remote_file.py b/src/sage/misc/remote_file.py index d6ffd09c5ea..7e1cfef2ea7 100644 --- a/src/sage/misc/remote_file.py +++ b/src/sage/misc/remote_file.py @@ -10,7 +10,7 @@ def get_remote_file(filename, verbose=True) -> Path: INPUT: - ``filename`` -- the URL of a file on the web, e.g., - ``"http://modular.math.washington.edu/myfile.txt"`` + ``'http://modular.math.washington.edu/myfile.txt'`` - ``verbose`` -- whether to display download status @@ -27,7 +27,6 @@ def get_remote_file(filename, verbose=True) -> Path: print("hi from the net") print(2 + 3) - """ if verbose: print("Attempting to load remote file: " + filename) diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index 2911f72b626..ea51a9b3159 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -283,11 +283,10 @@ def process_line(location, line, replacements, row_index, verbose=False): - ``line`` -- a source code line - ``replacements`` -- the array output from :func:`find_replacements` - ``row_index`` -- the line number where ``import`` appears - - ``verbose`` -- if True, issue print statements when interesting examples are found + - ``verbose`` -- if ``True``, issue print statements when interesting + examples are found - OUTPUT: - - an array ``[new_line, replacements]`` with entries + OUTPUT: an array ``[new_line, replacements]`` with entries - ``new_line`` -- the modified import statement (possibly now on several lines) - ``replacements`` -- just returns the original replacements with its index 0 element removed if ``replacements`` is nonempty @@ -348,7 +347,7 @@ def make_replacements_in_file(location, package_regex=None, verbose=False, outpu - ``location`` -- a file path - ``package_regex`` -- (default: :obj:`default_package_regex`) a regular expression matching the ``sage.PAC.KAGE.all`` package names from which we do not want to import. - - ``verbose`` -- if True, issue print statements when interesting examples are found + - ``verbose`` -- if ``True``, issue print statements when interesting examples are found - ``output`` -- a file path; if ``None``, overwrite the file given by ``location`` EXAMPLES:: @@ -398,7 +397,7 @@ def walkdir_replace_dot_all(dir, file_regex=r'.*[.](py|pyx|pxi)$', package_regex - ``file_regex`` -- a regular expression matching the file names to process - ``package_regex`` -- (default: :obj:`default_package_regex`) a regular expression matching the ``sage.PAC.KAGE.all`` package names from which we do not want to import. - - ``verbose`` -- if True, print statements when interesting examples are found + - ``verbose`` -- if ``True``, print statements when interesting examples are found - ``excluded_file_regex`` -- a regular expression matching the file names to exclude EXAMPLES:: @@ -457,8 +456,8 @@ def walkdir_replace_dot_all(dir, file_regex=r'.*[.](py|pyx|pxi)$', package_regex finally: # Print report also when interrupted if verbosity: - log_messages = sorted(log_messages.rstrip().split('\n')) - for i, message in enumerate(log_messages, start=1): + log_messages_split = sorted(log_messages.rstrip().split('\n')) + for i, message in enumerate(log_messages_split, start=1): # add index to each line print(f'{i}. {message.rstrip()}') report = 'REPORT:\n' diff --git a/src/sage/misc/repr.py b/src/sage/misc/repr.py index ae765ff154a..d0bd0396f1f 100644 --- a/src/sage/misc/repr.py +++ b/src/sage/misc/repr.py @@ -12,9 +12,7 @@ def coeff_repr(c, is_latex=False): - ``c`` -- a coefficient (i.e., an element of a ring) - OUTPUT: - - A string + OUTPUT: string EXAMPLES:: @@ -47,7 +45,7 @@ def coeff_repr(c, is_latex=False): return s -def repr_lincomb(terms, is_latex=False, scalar_mult="*", strip_one=False, +def repr_lincomb(terms, is_latex=False, scalar_mult='*', strip_one=False, repr_monomial=None, latex_scalar_mult=None): """ Compute a string representation of a linear combination of some @@ -57,15 +55,11 @@ def repr_lincomb(terms, is_latex=False, scalar_mult="*", strip_one=False, - ``terms`` -- list of terms, as pairs (support, coefficient) - ``is_latex`` -- whether to produce latex (default: ``False``) - - ``scalar_mult`` -- string representing the multiplication (default:``'*'``) + - ``scalar_mult`` -- string representing the multiplication (default: ``'*'``) - ``latex_scalar_mult`` -- latex string representing the multiplication (default: a space if ``scalar_mult`` is ``'*'``; otherwise ``scalar_mult``) - ``coeffs`` -- for backward compatibility - OUTPUT: - - - ``str`` -- a string - EXAMPLES:: sage: repr_lincomb([('a',1), ('b',-2), ('c',3)]) diff --git a/src/sage/misc/reset.pyx b/src/sage/misc/reset.pyx index e8247bb8f89..50e6a15b4c7 100644 --- a/src/sage/misc/reset.pyx +++ b/src/sage/misc/reset.pyx @@ -24,10 +24,10 @@ def reset(vars=None, attached=False): INPUT: - - ``vars`` -- a list, or space or comma separated string (default: - ``None``), variables to restore + - ``vars`` -- list or space or comma separated string (default: + ``None``); variables to restore - - ``attached`` -- boolean (default: ``False``), if ``vars`` is not ``None``, + - ``attached`` -- boolean (default: ``False``); if ``vars`` is not ``None``, whether to detach all attached files EXAMPLES:: @@ -96,8 +96,8 @@ def restore(vars=None): INPUT: - - ``vars`` -- string or list (default: ``None``), if not ``None``, restores - just the given variables to the default value. + - ``vars`` -- string or list (default: ``None``); if not ``None``, restores + just the given variables to the default value EXAMPLES:: diff --git a/src/sage/misc/rest_index_of_methods.py b/src/sage/misc/rest_index_of_methods.py index db32565e3ab..0d1d46f63b7 100644 --- a/src/sage/misc/rest_index_of_methods.py +++ b/src/sage/misc/rest_index_of_methods.py @@ -24,18 +24,18 @@ def gen_rest_table_index(obj, names=None, sort=True, only_local_functions=True, INPUT: - - ``obj`` -- a list of functions, a module or a class. If given a list of + - ``obj`` -- list of functions, a module or a class. If given a list of functions, the generated table will consist of these. If given a module or a class, all functions/methods it defines will be listed, except deprecated or those starting with an underscore. In the case of a class, note that inherited methods are not displayed. - - ``names`` -- a dictionary associating a name to a function. Takes + - ``names`` -- dictionary associating a name to a function. Takes precedence over the automatically computed name for the functions. Only used when ``list_of_entries`` is a list. - ``sort`` -- boolean (default: ``True``); whether to sort the list of - methods lexicographically. + methods lexicographically - ``only_local_functions`` -- boolean (default: ``True``); if ``list_of_entries`` is a module, ``only_local_functions = True`` means @@ -230,7 +230,7 @@ def list_of_subfunctions(root, only_local_functions=True): INPUT: - - ``root`` -- the module, or class, whose elements are to be listed. + - ``root`` -- the module, or class, whose elements are to be listed - ``only_local_functions`` -- boolean (default: ``True``); if ``root`` is a module, ``only_local_functions = True`` means that imported functions will @@ -259,7 +259,6 @@ def list_of_subfunctions(root, only_local_functions=True): sage: list_of_subfunctions(A) # needs sage.graphs ([], {: 'x'}) - """ if inspect.ismodule(root): ismodule = True @@ -305,7 +304,7 @@ def gen_thematic_rest_table_index(root, additional_categories=None, only_local_f INPUT: - - ``root`` -- the module, or class, whose elements are to be listed. + - ``root`` -- the module, or class, whose elements are to be listed - ``additional_categories`` -- dictionary (default: ``None``); a dictionary associating a category (given as a string) to a function's name. Can be @@ -355,8 +354,8 @@ def doc_index(name): INPUT: - - ``name`` -- a string, which will become the title of the index in which - this function/method will appear. + - ``name`` -- string, which will become the title of the index in which + this function/method will appear EXAMPLES:: diff --git a/src/sage/misc/sage_eval.py b/src/sage/misc/sage_eval.py index e69ee6ebda6..eba54910477 100644 --- a/src/sage/misc/sage_eval.py +++ b/src/sage/misc/sage_eval.py @@ -22,32 +22,26 @@ def sage_eval(source, locals=None, cmds='', preparse=True): INPUT: + - ``source`` -- string or object with a ``_sage_`` + method - - ``source`` -- a string or object with a ``_sage_`` - method + - ``locals`` -- evaluate in namespace of :mod:`sage.all` plus + the locals dictionary - - ``locals`` -- evaluate in namespace of :mod:`sage.all` plus - the locals dictionary + - ``cmds`` -- string; sequence of commands to be run + before source is evaluated - - ``cmds`` -- string; sequence of commands to be run - before source is evaluated. + - ``preparse`` -- boolean (default: ``True``); if ``True``, preparse the + string expression - - ``preparse`` -- (default: ``True``) if True, preparse the - string expression. - - - EXAMPLES: This example illustrates that preparsing is applied. - - :: + EXAMPLES: This example illustrates that preparsing is applied:: sage: eval('2^3') 1 sage: sage_eval('2^3') 8 - However, preparsing can be turned off. - - :: + However, preparsing can be turned off:: sage: sage_eval('2^3', preparse=False) 1 @@ -63,9 +57,7 @@ def sage_eval(source, locals=None, cmds='', preparse=True): ``from sage.all import *``. Even though ``bernoulli`` has been redefined in the local scope, when calling :func:`sage_eval` the default value meaning of :func:`bernoulli` - is used. Likewise for ``QQ`` below. - - :: + is used. Likewise for ``QQ`` below:: sage: bernoulli = lambda x : x^2 sage: bernoulli(6) @@ -85,9 +77,7 @@ def sage_eval(source, locals=None, cmds='', preparse=True): sage: parent(sage_eval('QQ(2)')) Rational Field - This example illustrates setting a variable for use in evaluation. - - :: + This example illustrates setting a variable for use in evaluation:: sage: x = 5 sage: eval('4//3 + x', {'x': 25}) @@ -128,9 +118,7 @@ def sage_eval(source, locals=None, cmds='', preparse=True): This example illustrates how :mod:`sage_eval` can be useful when evaluating the output of other computer algebra - systems. - - :: + systems:: sage: # needs sage.libs.gap sage: R. = PolynomialRing(RationalField()) diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 025b7b96f5e..08bfde6e715 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -187,20 +187,20 @@ def sage_input(x, preparse=True, verify=False, allow_locals=False): - ``x`` -- the value we want to find an input form for - - ``preparse`` -- (default ``True``) Whether to generate code that requires + - ``preparse`` -- (default: ``True``) whether to generate code that requires the preparser. With ``True``, generated code requires the preparser. With ``False``, generated code requires that the preparser not be used. With ``None``, generated code will work whether or not the preparser is used. - - ``verify`` -- (default ``False``) If ``True``, then the answer will be + - ``verify`` -- (default: ``False``) if ``True``, then the answer will be evaluated with :func:`sage_eval`, and an exception will be raised if the result is not equal to the original value. (In fact, for ``verify=True``, :func:`sage_input` is effectively run three times, with ``preparse`` set to ``True``, ``False``, and ``None``, and all three results are checked.) This is particularly useful for doctests. - - ``allow_locals`` -- (default ``False``) If ``True``, then values that + - ``allow_locals`` -- (default: ``False``) if ``True``, then values that :func:`sage_input` cannot handle are returned in a dictionary, and the returned code assumes that this dictionary is passed as the ``locals`` parameter of :func:`sage_eval`. (Otherwise, if :func:`sage_input` cannot @@ -315,16 +315,16 @@ def __init__(self, allow_locals=False, preparse=True): INPUT: - - ``allow_locals`` -- (default ``False``) If true, then values - that cannot be converted to input form will be stored in - a dictionary, which must be passed as the ``locals`` - when evaluating the result. + - ``allow_locals`` -- (default: ``False``) if true, then values + that cannot be converted to input form will be stored in + a dictionary, which must be passed as the ``locals`` + when evaluating the result. - - ``preparse`` -- (default ``True``) If true, then the result - will assume that the preparser is enabled. If false, then - the result will assume that the preparser is disabled. - If ``None``, then the result will work whether or - not the preparser is enabled. + - ``preparse`` -- (default: ``True``) if true, then the result + will assume that the preparser is enabled. If false, then + the result will assume that the preparser is disabled. + If ``None``, then the result will work whether or + not the preparser is enabled. EXAMPLES:: @@ -345,7 +345,7 @@ def __init__(self, allow_locals=False, preparse=True): def __call__(self, x, coerced=False): r""" - Tries to convert an arbitrary value ``x`` into a + Try to convert an arbitrary value ``x`` into a :class:`SageInputExpression` (an SIE). We first check to see if an SIE has been cached for ``x``; @@ -529,7 +529,7 @@ def __call__(self, x, coerced=False): def preparse(self): r""" - Checks the preparse status. + Check the preparse status. It returns ``True`` if the preparser will be enabled, ``False`` if it will be disabled, and ``None`` if the result must work whether or not @@ -551,7 +551,7 @@ def preparse(self): def int(self, n): r""" - Return a raw SIE from the integer ``n`` + Return a raw SIE from the integer ``n``. As it is raw, it may read back as a Sage Integer or a Python int, depending on its size and whether the preparser is enabled. @@ -750,7 +750,7 @@ def import_name(self, module, name, alt_name=None): def assign(self, e, val): r""" - Constructs a command that performs the assignment ``e=val``. + Construct a command that performs the assignment ``e=val``. Can only be used as an argument to the ``command`` method. @@ -1008,7 +1008,7 @@ def parent_with_gens(self, parent, sie, gen_names, name, gens_syntax=None): def gen(self, parent, n=0): r""" Given a parent, returns a :class:`SageInputExpression` for - the `n`-th (default 0) generator of the parent. + the `n`-th (default: 0) generator of the parent. EXAMPLES:: @@ -1259,7 +1259,7 @@ def __init__(self, sib): def _sie_is_simple(self): r""" - Returns ``True`` if this :class:`SageInputExpression` is simple + Return ``True`` if this :class:`SageInputExpression` is simple enough that duplicate uses are not worth caching. Normally this will be true if the expression represents a single token. @@ -1276,7 +1276,7 @@ def _sie_is_simple(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SageInputExpression`. EXAMPLES:: @@ -1772,7 +1772,7 @@ def __init__(self, sib, n): - ``sib`` -- a :class:`SageInputBuilder` - - ``n`` -- a string; the value to be printed for this expression + - ``n`` -- string; the value to be printed for this expression EXAMPLES:: @@ -1790,7 +1790,7 @@ def __init__(self, sib, n): def __repr__(self): r""" - Returns a string representing this :class:`SIE_literal_stringrep` + Return a string representing this :class:`SIE_literal_stringrep` value. EXAMPLES:: @@ -1849,10 +1849,10 @@ def __init__(self, sib, func, args, kwargs): - ``func`` -- a :class:`SageInputExpression` representing a function - - ``args`` -- a list of instances of :class:`SageInputExpression` + - ``args`` -- list of instances of :class:`SageInputExpression` representing the positional arguments - - ``kwargs`` -- a dictionary mapping strings to instances of + - ``kwargs`` -- dictionary mapping strings to instances of :class:`SageInputExpression` representing the keyword arguments EXAMPLES:: @@ -1869,7 +1869,7 @@ def __init__(self, sib, func, args, kwargs): def __repr__(self): r""" - Returns a string representing this :class:`SIE_call` value. + Return a string representing this :class:`SIE_call` value. EXAMPLES:: @@ -1887,7 +1887,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this :class:`SIE_call`. + Return a list of the immediate subexpressions of this :class:`SIE_call`. EXAMPLES:: @@ -1976,7 +1976,7 @@ def __init__(self, sib, coll, key): def __repr__(self): r""" - Returns a string representing this :class:`SIE_subscript` value. + Return a string representing this :class:`SIE_subscript` value. EXAMPLES:: @@ -1995,7 +1995,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_subscript`. EXAMPLES:: @@ -2060,7 +2060,7 @@ def __init__(self, sib, obj, attr): - ``obj`` -- a :class:`SageInputExpression` representing an object - - ``attr`` -- a string; the attribute name + - ``attr`` -- string; the attribute name EXAMPLES:: @@ -2076,7 +2076,7 @@ def __init__(self, sib, obj, attr): def __repr__(self): r""" - Returns a string representing this :class:`SIE_getattr` value. + Return a string representing this :class:`SIE_getattr` value. EXAMPLES:: @@ -2091,7 +2091,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_subscript`. EXAMPLES:: @@ -2149,10 +2149,10 @@ def __init__(self, sib, values, is_list): - ``sib`` -- a :class:`SageInputBuilder` - - ``values`` -- a list of instances of :class:`SageInputExpression` + - ``values`` -- list of instances of :class:`SageInputExpression` representing the elements of this tuple - - ``is_list`` -- is True if this class represents a list, False for a + - ``is_list`` -- is ``True`` if this class represents a list, False for a tuple EXAMPLES:: @@ -2171,7 +2171,7 @@ def __init__(self, sib, values, is_list): def __repr__(self): r""" - Returns a string representing this :class:`SIE_tuple` value. + Return a string representing this :class:`SIE_tuple` value. EXAMPLES:: @@ -2189,7 +2189,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_tuple`. EXAMPLES:: @@ -2261,7 +2261,7 @@ def __init__(self, sib, entries): - ``sib`` -- a :class:`SageInputBuilder` - - ``entries`` -- a list of pairs of :class:`SageInputExpression` + - ``entries`` -- list of pairs of :class:`SageInputExpression` representing the entries of this dict EXAMPLES:: @@ -2279,7 +2279,7 @@ def __init__(self, sib, entries): def __repr__(self): r""" - Returns a string representing this :class:`SIE_dict` value. + Return a string representing this :class:`SIE_dict` value. EXAMPLES:: @@ -2295,7 +2295,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_dict`. EXAMPLES:: @@ -2351,7 +2351,7 @@ def __init__(self, sib, op, lhs, rhs): - ``sib`` -- a :class:`SageInputBuilder` - - ``op`` -- a string representing a binary operator, such as '*' or '%' + - ``op`` -- string representing a binary operator, such as '*' or '%' - ``lhs`` -- a :class:`SageInputExpression` @@ -2371,7 +2371,7 @@ def __init__(self, sib, op, lhs, rhs): def __repr__(self): r""" - Returns a string representing this :class:`SIE_binary` value. + Return a string representing this :class:`SIE_binary` value. EXAMPLES:: @@ -2385,7 +2385,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a tuple of the immediate subexpressions of this + Return a tuple of the immediate subexpressions of this :class:`SIE_binary`. EXAMPLES:: @@ -2501,7 +2501,7 @@ def __init__(self, sib, op, operand): - ``sib`` -- a :class:`SageInputBuilder` - - ``op`` -- a string representing a unary operator, such as '-' + - ``op`` -- string representing a unary operator, such as '-' - ``operand`` -- a :class:`SageInputExpression` @@ -2519,7 +2519,7 @@ def __init__(self, sib, op, operand): def __repr__(self): r""" - Returns a string representing this :class:`SIE_unary` value. + Return a string representing this :class:`SIE_unary` value. EXAMPLES:: @@ -2533,7 +2533,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_unary`. EXAMPLES:: @@ -2691,7 +2691,7 @@ def __init__(self, sib, constr, gen_names, gens_syntax=None): - ``constr`` -- a :class:`SageInputExpression` for constructing this parent ``normally`` - - ``gen_names`` -- a tuple of generator names + - ``gen_names`` -- tuple of generator names - ``gens_syntax`` -- an optional :class:`SageInputExpression` for constructing this parent using the \sage preparser generators syntax @@ -2717,7 +2717,7 @@ def __init__(self, sib, constr, gen_names, gens_syntax=None): def __repr__(self): r""" - Returns a string representing this :class:`SIE_gens_constructor` value. + Return a string representing this :class:`SIE_gens_constructor` value. EXAMPLES:: @@ -2734,7 +2734,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_gens_constructor`. EXAMPLES:: @@ -2908,7 +2908,7 @@ class SIE_gen(SageInputExpression): def __init__(self, sib, parent, name): r""" - Initializes an instance of :class:`SIE_gen`. + Initialize an instance of :class:`SIE_gen`. INPUT: @@ -2916,7 +2916,7 @@ def __init__(self, sib, parent, name): - ``parent`` -- a :class:`SIE_gens_constructor` - - ``name`` -- a string with the name of this generator + - ``name`` -- string with the name of this generator EXAMPLES:: @@ -2932,7 +2932,7 @@ def __init__(self, sib, parent, name): def __repr__(self): r""" - Returns a string representing this :class:`SIE_gen` value. + Return a string representing this :class:`SIE_gen` value. EXAMPLES:: @@ -3060,7 +3060,7 @@ class SIE_import_name(SageInputExpression): def __init__(self, sib, module, name, alt_name=None): r""" - Initializes an instance of :class:`SIE_import_name`. + Initialize an instance of :class:`SIE_import_name`. INPUT: @@ -3094,7 +3094,7 @@ def __init__(self, sib, module, name, alt_name=None): def __repr__(self): r""" - Returns a string representing this :class:`SIE_import_name` value. + Return a string representing this :class:`SIE_import_name` value. EXAMPLES:: @@ -3194,7 +3194,7 @@ class SIE_assign(SageInputExpression): def __init__(self, sib, lhs, rhs): r""" - Initializes an instance of :class:`SIE_assign`. + Initialize an instance of :class:`SIE_assign`. INPUT: @@ -3218,7 +3218,7 @@ def __init__(self, sib, lhs, rhs): def __repr__(self): r""" - Returns a string representing this :class:`SIE_assign` command. + Return a string representing this :class:`SIE_assign` command. EXAMPLES:: @@ -3232,7 +3232,7 @@ def __repr__(self): def _sie_referenced(self): r""" - Returns a list of the immediate subexpressions of this + Return a list of the immediate subexpressions of this :class:`SIE_assign`. EXAMPLES:: @@ -3313,7 +3313,7 @@ def format(self, e, prec): - ``e`` -- a :class:`SageInputExpression` - - ``prec`` -- an integer representing a precedence level + - ``prec`` -- integer representing a precedence level First, we check to see if ``e`` should be replaced by a variable. If so, we generate the command to assign the variable, and return @@ -3521,11 +3521,10 @@ def verify_si_answer(x, answer, preparse): - ``x`` -- an arbitrary Sage value - - ``answer`` -- a string, or a :class:`SageInputAnswer` + - ``answer`` -- string, or a :class:`SageInputAnswer` - ``preparse`` -- ``True``, ``False``, or ``None`` - EXAMPLES:: sage: from sage.misc.sage_input import verify_si_answer diff --git a/src/sage/misc/sage_ostools.pyx b/src/sage/misc/sage_ostools.pyx index 31118107f20..b679af7c26f 100644 --- a/src/sage/misc/sage_ostools.pyx +++ b/src/sage/misc/sage_ostools.pyx @@ -16,13 +16,13 @@ def have_program(program, path=None): INPUT: - - ``program`` -- a string, the name of the program to check. + - ``program`` -- string, the name of the program to check - - ``path`` -- string or None. Paths to search for ``program``, + - ``path`` -- string or ``None``. Paths to search for ``program``, separated by ``os.pathsep``. If ``None``, use the :envvar:`PATH` environment variable. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -85,7 +85,7 @@ cdef file_and_fd(x, int* fd): If ``x`` is a file, return ``x`` and set ``*fd`` to its file descriptor. If ``x`` is an integer, return ``None`` and set ``*fd`` to ``x``. Otherwise, set ``*fd = -1`` and raise a - ``TypeError``. + :exc:`TypeError`. """ fd[0] = -1 try: @@ -116,7 +116,7 @@ cdef class redirection: - ``dest`` -- where the source file should be redirected to - - ``close`` -- (boolean, default: ``True``) whether to close the + - ``close`` -- boolean (default: ``True``); whether to close the destination file upon exiting the context. This is only supported if ``dest`` is a Python file. diff --git a/src/sage/misc/sage_timeit.py b/src/sage/misc/sage_timeit.py index e90eb1adb23..75828816c24 100644 --- a/src/sage/misc/sage_timeit.py +++ b/src/sage/misc/sage_timeit.py @@ -52,11 +52,10 @@ class SageTimeitResult: sage: SageTimeitResult(stats) # needs sage.symbolic 7 loops, best of 13: 3.1416 ns per loop - If the third argument is not a Python integer, a ``TypeError`` is raised:: + If the third argument is not a Python integer, a :exc:`TypeError` is raised:: sage: SageTimeitResult( (1, 2, 3, 4, 's') ) ) failed: TypeError: * wants int> - """ def __init__(self, stats, series=None): r""" @@ -104,25 +103,23 @@ def sage_timeit(stmt, globals_dict=None, preparse=None, number=0, repeat=3, prec INPUT: - - ``stmt`` -- a text string. + - ``stmt`` -- a text string - - ``globals_dict`` -- a dictionary or ``None`` (default). Evaluate + - ``globals_dict`` -- dictionary or ``None`` (default). Evaluate ``stmt`` in the context of the globals dictionary. If not set, the current ``globals()`` dictionary is used. - ``preparse`` -- (default: use globals preparser default) if - ``True`` preparse ``stmt`` using the Sage preparser. + ``True`` preparse ``stmt`` using the Sage preparser - - ``number`` -- integer, (default: 0), number of loops. + - ``number`` -- integer; (default: 0); number of loops - - ``repeat`` -- integer, (default: 3), number of - repetition. + - ``repeat`` -- integer; (default: 3); number of repetition - - ``precision`` -- integer, (default: 3), precision of - output time. + - ``precision`` -- integer; (default: 3); precision of output time - - ``seconds`` -- boolean (default: ``False``). Whether to just - return time in seconds. + - ``seconds`` -- boolean (default: ``False``); whether to just + return time in seconds OUTPUT: @@ -226,8 +223,8 @@ def sage_timeit(stmt, globals_dict=None, preparse=None, number=0, repeat=3, prec # to the shell namespace? src = timeit_.template.format(stmt=timeit_.reindent(stmt, 8), - setup="pass", init='') - code = compile(src, "", "exec") + setup='pass', init='') + code = compile(src, '', 'exec') ns = {} if not globals_dict: globals_dict = globals() diff --git a/src/sage/misc/sage_timeit_class.pyx b/src/sage/misc/sage_timeit_class.pyx index f568886574f..2438484cd10 100644 --- a/src/sage/misc/sage_timeit_class.pyx +++ b/src/sage/misc/sage_timeit_class.pyx @@ -51,18 +51,18 @@ class SageTimeit: INPUT: - - ``code`` -- string of code to evaluate; may contain newlines. + - ``code`` -- string of code to evaluate; may contain newlines - - ``globs`` -- global variables; if not given, uses module scope - globals. + - ``globs`` -- global variables; if not given, uses module scope + globals - - ``locals`` -- ignored completely. + - ``locals`` -- ignored completely - ``kwds`` -- passed onto sage_timeit. Common options are ``preparse``, ``number``, ``repeat``, ``precision``. See :func:`~sage.misc.sage_timeit.sage_timeit` for details. - OUTPUT: string -- timing information as a string + OUTPUT: string; timing information EXAMPLES:: @@ -84,15 +84,15 @@ class SageTimeit: """ INPUT: - - ``code`` -- a string. A line or block of code, which may - contain newlines. + - ``code`` -- string; a line or block of code, which may + contain newlines - - ``globals`` -- optional global variables; if not given the + - ``globals`` -- (optional) global variables; if not given the globals of the calling module are used (e.g., if using this from the command line, the globals of the command line are used). - - ``preparse`` -- Boolean or ``None`` (default). Whether or + - ``preparse`` -- boolean or ``None`` (default). Whether or not to preparse the input code using the Sage preparser. If not specified, do the same thing as whatever was set by the preparser command. diff --git a/src/sage/misc/sage_unittest.py b/src/sage/misc/sage_unittest.py index f0e281f9b68..47fe452d904 100644 --- a/src/sage/misc/sage_unittest.py +++ b/src/sage/misc/sage_unittest.py @@ -110,40 +110,40 @@ class TestSuite: running ._test_new() . . . pass running ._test_pickling() . . . pass - TODO: - - - Allow for customized behavior in case of failing assertion - (warning, error, statistic accounting). - This involves reimplementing the methods fail / failIf / ... - of unittest.TestCase in InstanceTester - - - Don't catch the exceptions if ``TestSuite(..).run()`` is called - under the debugger, or with ``%pdb`` on (how to detect this? see - ``get_ipython()``, ``IPython.Magic.shell.call_pdb``, ...) - In the mean time, see the ``catch=False`` option. - - - Run the tests according to the inheritance order, from most - generic to most specific, rather than alphabetically. Then, the - first failure will be the most relevant, the others being - usually consequences. - - - Improve integration with doctests (statistics on failing/passing tests) - - - Add proper support for nested testsuites. - - - Integration with unittest: - Make TestSuite inherit from unittest.TestSuite? - Make ``.run(...)`` accept a result object - - - Add some standard option ``proof = True``, asking for the - test method to choose appropriately the elements so as to - prove the desired property. The test method may assume that - a parent implements properly all the super categories. For - example, the ``_test_commutative`` method of the category - ``CommutativeSemigroups()`` may just check that the - provided generators commute, implicitly assuming that - generators indeed generate the semigroup (as required by - ``Semigroups()``). + .. TODO:: + + - Allow for customized behavior in case of failing assertion + (warning, error, statistic accounting). + This involves reimplementing the methods fail / failIf / ... + of unittest.TestCase in InstanceTester + + - Don't catch the exceptions if ``TestSuite(..).run()`` is called + under the debugger, or with ``%pdb`` on (how to detect this? see + ``get_ipython()``, ``IPython.Magic.shell.call_pdb``, ...) + In the mean time, see the ``catch=False`` option. + + - Run the tests according to the inheritance order, from most + generic to most specific, rather than alphabetically. Then, the + first failure will be the most relevant, the others being + usually consequences. + + - Improve integration with doctests (statistics on failing/passing tests) + + - Add proper support for nested testsuites. + + - Integration with unittest: + Make TestSuite inherit from unittest.TestSuite? + Make ``.run(...)`` accept a result object + + - Add some standard option ``proof = True``, asking for the + test method to choose appropriately the elements so as to + prove the desired property. The test method may assume that + a parent implements properly all the super categories. For + example, the ``_test_commutative`` method of the category + ``CommutativeSemigroups()`` may just check that the + provided generators commute, implicitly assuming that + generators indeed generate the semigroup (as required by + ``Semigroups()``). """ def __init__(self, instance): @@ -174,10 +174,10 @@ def run(self, category=None, skip=[], catch=True, raise_on_failure=False, INPUT: - - ``category`` -- a category; reserved for future use - - ``skip`` -- a string or list (or iterable) of strings - - ``raise_on_failure`` -- a boolean (default: ``False``) - - ``catch`` -- a boolean (default: ``True``) + - ``category`` -- a category; reserved for future use + - ``skip`` -- string or list (or iterable) of strings + - ``raise_on_failure`` -- boolean (default: ``False``) + - ``catch`` -- boolean (default: ``True``) All other options are passed down to the individual tests. @@ -197,7 +197,7 @@ def run(self, category=None, skip=[], catch=True, raise_on_failure=False, Some tests may be skipped using the ``skip`` option:: - sage: TestSuite(1).run(verbose = True, skip ="_test_pickling") + sage: TestSuite(1).run(verbose = True, skip ='_test_pickling') running ._test_category() . . . pass running ._test_eq() . . . pass running ._test_new() . . . pass @@ -388,7 +388,7 @@ class InstanceTester(unittest.TestCase): # all that much anyways) longMessage = False - def __init__(self, instance, elements=None, verbose=False, prefix="", + def __init__(self, instance, elements=None, verbose=False, prefix='', max_runs=4096, max_samples=None, **options): """ A gadget attached to an instance providing it with testing utilities. @@ -428,7 +428,7 @@ def runTest(self): def info(self, message, newline=True): """ - Display user information + Display user information. EXAMPLES:: @@ -460,7 +460,6 @@ def __repr__(self): sage: from sage.misc.sage_unittest import InstanceTester sage: InstanceTester(ZZ, verbose = True) Testing utilities for Integer Ring - """ return "Testing utilities for %s" % self._instance @@ -473,13 +472,13 @@ def some_elements(self, S=None, repeat=None): INPUT: - - ``S`` -- a set of elements to select from. By default this + - ``S`` -- set of elements to select from; by default this will use the elements passed to this tester at creation time, or the result of :meth:`.some_elements` if no elements - were specified. + were specified - - ``repeat`` -- integer (default: None). If given, instead returns - a list of tuples of length ``repeat`` from ``S``. + - ``repeat`` -- integer (default: ``None``); if given, instead returns + a list of tuples of length ``repeat`` from ``S`` OUTPUT: @@ -599,7 +598,7 @@ def __init__(self, instance): def _test_pickling(self, **options): """ - Checks that the instance in self can be pickled and unpickled properly. + Check that the instance in ``self`` can be pickled and unpickled properly. EXAMPLES:: diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 595cb8faf9f..0505f6039a9 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -127,13 +127,13 @@ def _rmcmd(s, cmd, left='', right=''): INPUT: - - ``s`` -- (string) string from which to remove the command + - ``s`` -- string; string from which to remove the command - - ``cmd`` -- (string) command to be removed. This should be a + - ``cmd`` -- string; command to be removed. This should be a command which takes a single argument, like 'emph' or 'url'; the command is removed, but its argument is not. - - ``left``, ``right`` -- (string, default: '') add these + - ``left``, ``right`` -- string (default: ``''``); add these strings at the left and right ends of the command. See the examples. @@ -200,13 +200,11 @@ def detex(s, embedded=False): - ``s`` -- string - ``embedded`` -- boolean (default: ``False``) - If ``embedded`` is False, then do the replacements in both - ``math_substitutes`` and ``nonmath_substitutes``. If True, then + If ``embedded`` is ``False``, then do the replacements in both + ``math_substitutes`` and ``nonmath_substitutes``. If ``True``, then only do ``nonmath_substitutes``. - OUTPUT: - - string + OUTPUT: string EXAMPLES:: @@ -264,7 +262,7 @@ def skip_TESTS_block(docstring): INPUT: - - ``docstring``, a string + - ``docstring`` -- string A "TESTS" block is a block starting "TESTS:" (or the same with two colons), on a line on its own, and ending either @@ -671,10 +669,7 @@ def format(s, embedded=False): EXAMPLES:: sage: from sage.misc.sagedoc import format - sage: identity_matrix(2).rook_vector.__doc__[191:263] # needs sage.modules - 'Let `A` be an `m` by `n` (0,1)-matrix. We identify `A` with a chessboard' - - sage: format(identity_matrix(2).rook_vector.__doc__[191:263]) # needs sage.modules + sage: format('Let `A` be an `m` by `n` (0,1)-matrix. We identify `A` with a chessboard') 'Let A be an m by n (0,1)-matrix. We identify A with a chessboard\n' If the first line of the string is 'nodetex', remove 'nodetex' but @@ -699,7 +694,7 @@ def format(s, embedded=False): We check that the todo Sphinx extension is correctly activated:: sage: sage.misc.sagedoc.format(sage.combinat.ranker.on_fly.__doc__) # needs sphinx - " Returns ... Todo: add tests as in combinat::rankers\n" + " Return ... Todo: add tests as in combinat::rankers\n" In the following use case, the ``nodetex`` directive would have been ignored prior to :issue:`11815`:: @@ -886,10 +881,10 @@ def _search_src_or_doc(what, string, extra1='', extra2='', extra3='', INPUT: - - ``what``: either ``'src'`` or ``'doc'``, according to whether you - are searching the documentation or source code. + - ``what`` -- either ``'src'`` or ``'doc'``, according to whether you + are searching the documentation or source code - the rest of the input is the same as :func:`search_src`, - :func:`search_doc`, and :func:`search_def`. + :func:`search_doc`, and :func:`search_def` OUTPUT: @@ -1053,45 +1048,47 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', INPUT: - - ``string`` -- a string to find in the Sage source code. + - ``string`` -- string to find in the Sage source code - ``extra1``, ..., ``extra5`` -- additional strings to require when - searching. Lines must match all of these, as well as ``string``. + searching. Lines must match all of these, as well as ``string`` - - ``whole_word`` (default: ``False``) -- if True, search for + - ``whole_word`` -- (default: ``False``) if ``True``, search for ``string`` and ``extra1`` (etc.) as whole words only. This assumes that each of these arguments is a single word, not a regular expression, and it might have unexpected results if used with regular expressions. - - ``ignore_case`` (default: ``True``) -- if False, perform a + - ``ignore_case`` -- boolean (default: ``True``); if ``False``, perform a case-sensitive search - - ``multiline`` (default: ``False``) -- if True, search more + - ``multiline`` -- (default: ``False``) if ``True``, search more than one line at a time. In this case, print any matching file names, but don't print line numbers. - - ``interact`` (default: ``True``) -- if ``False``, return + - ``interact`` -- boolean (default: ``True``); if ``False``, return a string with all the matches. Otherwise, this function returns ``None``, and the results are displayed appropriately, according to whether you are using the notebook or the command-line interface. You should not ordinarily need to use this. - - ``path_re`` (default: '') -- regular expression which - the filename (including the path) must match. + - ``path_re`` -- (default: ``''``) regular expression which + the filename (including the path) must match - - ``module`` (default: 'sage') -- the module in which to + - ``module`` -- (default: ``'sage'``) the module in which to search. The default is 'sage', the entire Sage library. If ``module`` doesn't start with "sage", then the links in the notebook output may not function. - OUTPUT: If ``interact`` is False, then return a string with all of + OUTPUT: + + If ``interact`` is ``False``, then return a string with all of the matches, separated by newlines. On the other hand, if - ``interact`` is True (the default), there is no output. Instead: + ``interact`` is ``True`` (the default), there is no output. Instead: at the command line, the search results are printed on the screen in the form ``filename:line_number:line of text``, showing the filename in which each match occurs, the line number where it - occurs, and the actual matching line. (If ``multiline`` is True, + occurs, and the actual matching line. (If ``multiline`` is ``True``, then only the filename is printed for each match.) The file paths in the output are relative to ``$SAGE_SRC``. In the notebook, each match produces a link to the actual file in which @@ -1100,9 +1097,9 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', The ``string`` and ``extraN`` arguments are treated as regular expressions, as is ``path_re``, and errors will be raised if they are invalid. The matches will be case-insensitive unless - ``ignore_case`` is False. + ``ignore_case`` is ``False``. - .. note:: + .. NOTE:: The ``extraN`` parameters are present only because ``search_src(string, *extras, interact=False)`` @@ -1218,7 +1215,6 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', matrix/matrix0.pyx:607: Get the 2 x 3 submatrix of M starting at row index and column index matrix/matrix0.pyx:924: Set the 2 x 2 submatrix of M, starting at row index and column matrix/matrix0.pyx:933: Set the 2 x 3 submatrix of M starting at row index and column - """ return _search_src_or_doc('src', string, extra1=extra1, extra2=extra2, extra3=extra3, extra4=extra4, extra5=extra5, @@ -1235,7 +1231,7 @@ def search_doc(string, extra1='', extra2='', extra3='', extra4='', INPUT: same as for :func:`search_src`. - OUTPUT: same as for :func:`search_src`. + OUTPUT: same as for :func:`search_src` EXAMPLES: @@ -1276,9 +1272,9 @@ def search_def(name, extra1='', extra2='', extra3='', extra4='', INPUT: same as for :func:`search_src`. - OUTPUT: same as for :func:`search_src`. + OUTPUT: same as for :func:`search_src` - .. note:: + .. NOTE:: The regular expression used by this function only finds function definitions that are preceded by spaces, so if you use tabs on a @@ -1325,11 +1321,11 @@ def format_search_as_html(what, results, search): INPUT: - - ``what`` -- (string) what was searched (source code or + - ``what`` -- string; what was searched (source code or documentation) - - ``results`` -- (string or list) the results of the search as a string or list of + - ``results`` -- string or list; the results of the search as a string or list of search results - - ``search`` -- (string or list) what was being searched for, either as a + - ``search`` -- string or list; what was being searched for, either as a string which is taken verbatim, or a list of multiple search terms if there were more than one @@ -1410,8 +1406,8 @@ def my_getsource(obj, oname=''): - ``obj`` -- a Sage object, function, etc. - - ``oname`` -- str (optional). A name under which the object is - known. Currently ignored by Sage. + - ``oname`` -- string (optional); a name under which the object is + known. Currently ignored by Sage OUTPUT: @@ -1451,7 +1447,7 @@ class _sage_doc: "browse_sage_doc(identity_matrix, 'html'). ``output`` can be either 'html' or 'rst': the form of the output. ``view`` is only relevant if ``output`` is ``html``; in this case, if - ``view`` is True (its default value), then open up the + ``view`` is ``True`` (its default value), then open up the documentation in a web browser. Otherwise, just output the documentation as a string. @@ -1621,11 +1617,11 @@ def _open(self, name, testing=False): INPUT: - - ``name`` -- string, name of the documentation + - ``name`` -- string; name of the documentation - - ``testing`` -- boolean (default: ``False``): if True, - then just return the URL and path-name for this document; - don't open the web browser. + - ``testing`` -- boolean (default: ``False``); if ``True``, + then just return the URL and path-name for this document + (don't open the web browser) EXAMPLES:: diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 4582d0bfb6d..1f2a39d7c78 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -170,7 +170,7 @@ def is_function_or_cython_function(obj): def isclassinstance(obj): r""" - Check if argument is instance of non built-in class + Check if argument is instance of non built-in class. INPUT: @@ -223,7 +223,9 @@ def _extract_embedded_position(docstring): If docstring has a Cython embedded position, return a tuple (original_docstring, filename, line). If not, return None. - INPUT: ``docstring`` (string) + INPUT: + + - ``docstring`` -- string EXAMPLES:: @@ -255,7 +257,6 @@ def _extract_embedded_position(docstring): sage: with open(_extract_embedded_position(func_doc)[1]) as f: # needs sage.misc.cython ....: print(f.read()) cpdef test_funct(x,y): return - """ try: res = __embedded_position_re.search(docstring) @@ -301,14 +302,16 @@ def _extract_embedded_signature(docstring, name): See :issue:`17814`. - INPUT: ``docstring`` (string) + INPUT: + + - ``docstring`` -- string EXAMPLES:: sage: from sage.misc.sageinspect import _extract_embedded_signature sage: from sage.misc.nested_class import MainClass sage: print(_extract_embedded_signature(MainClass.NestedClass.NestedSubClass.dummy.__doc__, 'dummy')[0]) - File: sage/misc/nested_class.pyx (starting at line ...) + File: ...sage/misc/nested_class.pyx (starting at line ...) ... sage: _extract_embedded_signature(MainClass.NestedClass.NestedSubClass.dummy.__doc__, 'dummy')[1] FullArgSpec(args=['self', 'x', 'r'], varargs='args', varkw='kwds', defaults=((1, 2, 3.4),), kwonlyargs=[], kwonlydefaults=None, annotations={}) @@ -460,7 +463,6 @@ class SageArgSpecVisitor(ast.NodeVisitor): 'jc' sage: visitor.visit(v.value) ['veni', 'vidi', 'vici'] - """ def visit_Name(self, node): """ @@ -481,7 +483,6 @@ def visit_Name(self, node): ['foo', 'bar'] sage: [type(vis(n)) for n in ['foo', 'bar']] [, ] - """ return node.id @@ -507,7 +508,6 @@ def visit_NameConstant(self, node): [True, False, None] sage: [type(vis(n)) for n in ['True', 'False', 'None']] [, , ] - """ return node.value @@ -535,7 +535,6 @@ def visit_arg(self, node): sage: args = ast.parse(s).body[0].args.args sage: [visitor.visit_arg(n) for n in args] ['a', 'b', 'c', 'd'] - """ return node.arg @@ -581,7 +580,6 @@ def visit_Str(self, node): sage: vis = lambda x: visitor.visit_Str(ast.parse(x).body[0].value) sage: [vis(s) for s in ['"abstract"', "'syntax'", r'''r"tr\ee"''']] ['abstract', 'syntax', 'tr\\ee'] - """ return node.value @@ -602,7 +600,6 @@ def visit_List(self, node): sage: vis = lambda x: visitor.visit_List(ast.parse(x).body[0].value) sage: [vis(l) for l in ['[]', "['s', 't', 'u']", '[[e], [], [pi]]']] [[], ['s', 't', 'u'], [['e'], [], ['pi']]] - """ return [self.visit(n) for n in node.elts] @@ -623,7 +620,6 @@ def visit_Tuple(self, node): sage: vis = lambda x: visitor.visit_Tuple(ast.parse(x).body[0].value) sage: [vis(t) for t in ['()', '(x,y)', '("Au", "Al", "Cu")']] [(), ('x', 'y'), ('Au', 'Al', 'Cu')] - """ return tuple(self.visit(n) for n in node.elts) @@ -645,7 +641,6 @@ def visit_Dict(self, node): sage: v = [vis(d) for d in ['{}', "{1:one, 'two':2, other:bother}"]] sage: [sorted(d.items(), key=lambda x: str(x[0])) for d in v] [[], [(1, 'one'), ('other', 'bother'), ('two', 2)]] - """ d = {} for k, v in zip(node.keys, node.values): @@ -669,7 +664,6 @@ def visit_BoolOp(self, node): sage: vis = lambda x: visitor.visit(ast.parse(x).body[0].value) sage: [vis(d) for d in ['True and 1', 'False or 3 or None', '3 and 4']] #indirect doctest [1, 3, 4] - """ op = node.op.__class__.__name__ L = list(node.values) @@ -702,7 +696,6 @@ def visit_Compare(self, node): sage: vis = lambda x: visitor.visit_Compare(ast.parse(x).body[0].value) sage: [vis(d) for d in ['1<2==2!=3', '1==1>2', '1<2>1', '1<3<2<4']] [True, False, True, False] - """ left = self.visit(node.left) ops = list(node.ops) @@ -748,7 +741,6 @@ def visit_BinOp(self, node): sage: vis = lambda x: visitor.visit(ast.parse(x).body[0].value) sage: [vis(d) for d in ['(3+(2*4))', '7|8', '5^3', '7/3', '7//3', '3<<4']] #indirect doctest [11, 15, 6, 2.3333333333333335, 2, 48] - """ op = node.op.__class__.__name__ if op == 'Add': @@ -813,7 +805,6 @@ def visit_UnaryOp(self, node): sage: vis = lambda x: visitor.visit_UnaryOp(ast.parse(x).body[0].value) sage: [vis(d) for d in ['+(3*2)', '-(3*2)']] [6, -6] - """ op = node.op.__class__.__name__ if op == 'Not': @@ -830,7 +821,7 @@ def _grep_first_pair_of_parentheses(s): INPUT: - - ``s`` -- a string + - ``s`` -- string OUTPUT: @@ -840,7 +831,7 @@ def _grep_first_pair_of_parentheses(s): Parentheses between single or double quotation marks do not count. If no matching pair of parentheses can be found, a - ``SyntaxError`` is raised. + :exc:`SyntaxError` is raised. EXAMPLES:: @@ -853,7 +844,6 @@ def _grep_first_pair_of_parentheses(s): Traceback (most recent call last): ... SyntaxError: The given string does not contain balanced parentheses - """ out = [] single_quote = False @@ -886,7 +876,7 @@ def _split_syntactical_unit(s): INPUT: - - ``s`` -- a string + - ``s`` -- string OUTPUT: @@ -937,7 +927,6 @@ def _split_syntactical_unit(s): sage: _split_syntactical_unit('()): pass') ('()', '): pass') - """ s = s.strip() if not s: @@ -1031,8 +1020,8 @@ def _sage_getargspec_from_ast(source): INPUT: - - ``source`` -- a string; the function's (or method's) source code - definition. The function's body is ignored. + - ``source`` -- string; the function's (or method's) source code + definition. The function's body is ignored. OUTPUT: an instance of :obj:`inspect.ArgSpec`, i.e., a named tuple @@ -1051,7 +1040,6 @@ def _sage_getargspec_from_ast(source): True sage: set(from_ast(sms.sage_getsource(x)) == inspect.getfullargspec(x) for x in [factor, identity_matrix, Graph.__init__]) # needs sage.graphs sage.modules {True} - """ ast_args = ast.parse(source.lstrip()).body[0].args @@ -1075,7 +1063,7 @@ def _sage_getargspec_cython(source): INPUT: - - ``source`` -- a string; the function's (or method's) source code + - ``source`` -- string; the function's (or method's) source code definition. The function's body is ignored. The definition may contain type definitions for the function arguments. @@ -1148,7 +1136,6 @@ def _sage_getargspec_cython(source): FullArgSpec(args=['x', 'z'], varargs=None, varkw=None, defaults=('a string', {(1, 2, 3): True}), kwonlyargs=[], kwonlydefaults=None, annotations={}) - """ defpos = source.find('def ') assert defpos > -1, "The given source does not contain 'def'" @@ -1316,7 +1303,6 @@ def sage_getfile(obj): sage: sage_getfile(range) '' - """ # We try to extract from docstrings, but not using Python's inspect # because _sage_getdoc_unformatted is more robust. @@ -1367,7 +1353,6 @@ def sage_getfile_relative(obj): 'sage/symbolic/expression.pyx' sage: sage_getfile_relative(range) '' - """ filename = sage_getfile(obj) if not filename: @@ -1593,7 +1578,6 @@ def foo(x, a='\')"', b={not (2+1==3):'bar'}): return sage: shell.run_cell('f = Foo()') sage: shell.run_cell('f??') ...the source code string... - """ from sage.misc.lazy_attribute import lazy_attribute from sage.misc.abstract_method import AbstractMethod @@ -1815,9 +1799,7 @@ def sage_getdef(obj, obj_name=''): INPUT: - ``obj`` -- function - - ``obj_name`` -- string (default: '') - - ``obj_name`` is prepended to the output. + - ``obj_name`` -- string (default: ``''``); prepended to the output EXAMPLES:: @@ -1861,14 +1843,14 @@ def _sage_getdoc_unformatted(obj): INPUT: - - ``obj`` -- a function, module, etc.: something with a docstring. + - ``obj`` -- a function, module, etc.: something with a docstring EXAMPLES:: sage: from sage.misc.sageinspect import _sage_getdoc_unformatted sage: print(_sage_getdoc_unformatted(sage.rings.integer.Integer)) Integer(x=None, base=0) - File: sage/rings/integer.pyx (starting at line ...) + File: ...sage/rings/integer.pyx (starting at line ...) The :class:`Integer` class represents arbitrary precision integers. It derives from the :class:`Element` class, so @@ -1898,7 +1880,6 @@ def _sage_getdoc_unformatted(obj): Exception: no doc here sage: _sage_getdoc_unformatted(obj) '' - """ if obj is None: return '' @@ -1931,7 +1912,7 @@ def sage_getdoc_original(obj): INPUT: - - ``obj`` -- a function, module, etc.: something with a docstring. + - ``obj`` -- a function, module, etc.: something with a docstring EXAMPLES:: @@ -1982,7 +1963,6 @@ def sage_getdoc_original(obj): sage: sage_getdoc_original(sage.plot.colors.aliceblue) == sage_getdoc_original(sage.plot.colors.Color) # needs sage.plot True - """ # typ is the type corresponding to obj, which is obj itself if # that was a type or old-style class @@ -2018,7 +1998,7 @@ def sage_getdoc(obj, obj_name='', embedded=False): INPUT: - - ``obj`` -- a function, module, etc.: something with a docstring. + - ``obj`` -- a function, module, etc.: something with a docstring EXAMPLES:: @@ -2035,7 +2015,6 @@ def sage_getdoc(obj, obj_name='', embedded=False): 'original documentation\n' sage: sage_getdoc(f1) 'specialised documentation\n' - """ import sage.misc.sagedoc if obj is None: @@ -2258,7 +2237,7 @@ def sage_getsourcelines(obj): sage: # needs sage.combinat sage: cachedfib = cached_function(fibonacci) sage: sage_getsourcelines(cachedfib)[0][0] - 'def fibonacci(n, algorithm="pari") -> Integer:\n' + "def fibonacci(n, algorithm='pari') -> Integer:\n" sage: sage_getsourcelines(type(cachedfib))[0][0] 'cdef class CachedFunction():\n' @@ -2276,7 +2255,7 @@ def sage_getsourcelines(obj): sage: sage_getsourcelines(test_func) (['def base(x):\n', ... - ' return x\n'], 7) + ' return x\n'], 8) Here are some cases that were covered in :issue:`11298`; note that line numbers may easily change, and therefore we do @@ -2343,7 +2322,6 @@ class Element: ' Ideal_generic):\n', ' def __init__(self, ring, gens, coerce=True):\n', ...) - """ # First try the method _sage_src_lines_(), which is meant to give # the source lines of an object (not of its type!). @@ -2456,16 +2434,16 @@ def sage_getvariablename(self, omit_underscore_names=True): INPUT: - - ``self`` -- any object. + - ``self`` -- any object - - ``omit_underscore_names`` -- boolean, default ``True``. + - ``omit_underscore_names`` -- boolean (default: ``True``) OUTPUT: If the user has assigned an object ``obj`` to a variable name, then return that variable name. If several variables point to ``obj``, return a sorted list of those names. If - ``omit_underscore_names`` is True (the default) then omit names + ``omit_underscore_names`` is ``True`` (the default) then omit names starting with an underscore "_". EXAMPLES:: diff --git a/src/sage/misc/search.pyx b/src/sage/misc/search.pyx index a9e7149113e..838e77268f5 100644 --- a/src/sage/misc/search.pyx +++ b/src/sage/misc/search.pyx @@ -33,13 +33,11 @@ cpdef search(object v, object x): INPUT: - - v -- a list, which is assumed sorted + - ``v`` -- list; which is assumed sorted - - x -- Python object + - ``x`` -- Python object - OUTPUT: - - bool, int + OUTPUT: boolean, integer This is implemented using the built-in ``bisect`` module. diff --git a/src/sage/misc/session.pyx b/src/sage/misc/session.pyx index 53b732309da..5012c5689d4 100644 --- a/src/sage/misc/session.pyx +++ b/src/sage/misc/session.pyx @@ -89,8 +89,8 @@ def init(state=None): INPUT: - - ``state`` -- a dictionary or ``None``; if ``None`` the :func:`locals()` - of the caller is used. + - ``state`` -- dictionary or ``None``; if ``None`` the :func:`locals()` + of the caller is used EXAMPLES:: @@ -124,12 +124,10 @@ def _is_new_var(x, v, hidden): - ``v`` -- object - - ``hidden`` -- bool; if ``True``, always return ``False`` on variables - that start with ``_``) + - ``hidden`` -- boolean; if ``True``, always return ``False`` on variables + that start with ``_`` - OUTPUT: - - A bool + OUTPUT: boolean EXAMPLES: @@ -173,18 +171,16 @@ def _is_new_var(x, v, hidden): def show_identifiers(hidden=False): r""" - Returns a list of all variable names that have been defined during + Return a list of all variable names that have been defined during this session. By default, this returns only those identifiers that don't start with an underscore. INPUT: - - ``hidden`` -- bool (Default: ``False``); If ``True``, also return - identifiers that start with an underscore. - - OUTPUT: + - ``hidden`` -- boolean (default: ``False``); if ``True``, also return + identifiers that start with an underscore - A list of variable names + OUTPUT: list of variable names EXAMPLES: @@ -260,15 +256,13 @@ def save_session(name='sage_session', verbose=False): INPUT: - - ``name`` -- string (default: 'sage_session') name of ``sobj`` - to save the session to. - - - ``verbose`` -- bool (default: ``False``) if ``True``, print - info about why certain variables can't be saved. + - ``name`` -- string (default: ``'sage_session'``); name of ``sobj`` + to save the session to - OUTPUT: + - ``verbose`` -- boolean (default: ``False``); if ``True``, print + info about why certain variables can't be saved - - Creates a file and returns silently. + OUTPUT: creates a file and returns silently EXAMPLES: diff --git a/src/sage/misc/sphinxify.py b/src/sage/misc/sphinxify.py index 66a42476669..3bd0b12b367 100644 --- a/src/sage/misc/sphinxify.py +++ b/src/sage/misc/sphinxify.py @@ -32,19 +32,18 @@ def sphinxify(docstring, format='html'): r""" - Runs Sphinx on a ``docstring``, and outputs the processed - documentation. + Run Sphinx on a ``docstring``, and output the processed documentation. INPUT: - ``docstring`` -- string; a ReST-formatted docstring - - ``format`` -- string (default: 'html'); either 'html' or - 'text' + - ``format`` -- string (default: ``'html'``); either ``'html'`` or + ``'text'`` OUTPUT: - - string -- Sphinx-processed documentation, in either HTML or + - ``string`` -- Sphinx-processed documentation, in either HTML or plain text format, depending on the value of ``format`` EXAMPLES:: diff --git a/src/sage/misc/stopgap.pyx b/src/sage/misc/stopgap.pyx index 0b3b6cb6c1e..e6f626ae9b4 100644 --- a/src/sage/misc/stopgap.pyx +++ b/src/sage/misc/stopgap.pyx @@ -25,7 +25,7 @@ def set_state(bint mode): INPUT: - - ``mode`` -- (bool); if True, enable stopgaps; otherwise, disable. + - ``mode`` -- boolean; if ``True``, enable stopgaps. Otherwise, disable. EXAMPLES:: @@ -63,9 +63,10 @@ def stopgap(message, int issue_no): INPUT: - - ``message`` -- an explanation of how an incorrect answer might be produced. + - ``message`` -- an explanation of how an incorrect answer might be produced - - ``issue_no`` -- an integer, giving the number of the Github issue tracking the underlying issue. + - ``issue_no`` -- integer; giving the number of the Github issue tracking + the underlying issue EXAMPLES:: diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index 442817e830b..6aaa8e6fb6f 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -35,11 +35,11 @@ def _check_issue_number(issue_number): INPUT: - - ``issue_number`` -- anything. + - ``issue_number`` -- anything OUTPUT: - This function returns nothing. A :class:`ValueError` or :class:`TypeError` + This function returns nothing. A :exc:`ValueError` or :exc:`TypeError` is raised if the argument cannot be a valid issue number. EXAMPLES:: @@ -74,14 +74,14 @@ def deprecation(issue_number, message, stacklevel=4): INPUT: - - ``issue_number`` -- integer. The github issue number where the - deprecation is introduced. + - ``issue_number`` -- integer; the github issue number where the + deprecation is introduced - - ``message`` -- string. An explanation why things are deprecated - and by what it should be replaced. + - ``message`` -- string; an explanation why things are deprecated + and by what it should be replaced - - ``stack_level`` -- (default: ``4``) an integer. This is passed on to - :func:`warnings.warn`. + - ``stack_level`` -- integer (default: `4`); this is passed on to + :func:`warnings.warn` EXAMPLES:: @@ -101,7 +101,7 @@ def deprecation(issue_number, message, stacklevel=4): def deprecation_cython(issue_number, message, stacklevel=3): r""" - Issue a deprecation warning -- for use in cython functions + Issue a deprecation warning -- for use in cython functions. TESTS: @@ -144,16 +144,16 @@ def warning(issue_number, message, warning_class=Warning, stacklevel=3): INPUT: - - ``issue_number`` -- integer. The github issue number where the - deprecation is introduced. + - ``issue_number`` -- integer; the github issue number where the + deprecation is introduced - - ``message`` -- string. An explanation what is going on. + - ``message`` -- string; an explanation what is going on - ``warning_class`` -- (default: ``Warning``) a class inherited - from a Python :class:`~exceptions.Warning`. + from a Python :class:`~exceptions.Warning` - - ``stack_level`` -- (default: ``3``) an integer. This is passed on to - :func:`warnings.warn`. + - ``stack_level`` -- integer (default: `3`); this is passed on to + :func:`warnings.warn` EXAMPLES:: @@ -187,13 +187,13 @@ def experimental_warning(issue_number, message, stacklevel=4): INPUT: - - ``issue_number`` -- an integer. The github issue number where the - experimental functionality was introduced. + - ``issue_number`` -- integer; the github issue number where the + experimental functionality was introduced - - ``message`` -- a string. An explanation what is going on. + - ``message`` -- string; an explanation what is going on - - ``stack_level`` -- (default: ``4``) an integer. This is passed on to - :func:`warnings.warn`. + - ``stack_level`` -- integer (default: `4`); this is passed on to + :func:`warnings.warn` EXAMPLES:: @@ -223,11 +223,11 @@ def __init__(self, issue_number, stacklevel=4): INPUT: - - ``issue_number`` -- an integer. The github issue number where this - code was introduced. + - ``issue_number`` -- integer; the github issue number where this + code was introduced - - ``stack_level`` -- (default: ``4``) an integer. This is passed on to - :func:`warnings.warn`. + - ``stack_level`` -- integer (default: `4`); this is passed on to + :func:`warnings.warn` EXAMPLES:: @@ -284,11 +284,9 @@ def __call__(self, func): INPUT: - - ``func`` -- the function to decorate. + - ``func`` -- the function to decorate - OUTPUT: - - The wrapper to this function. + OUTPUT: the wrapper to this function TESTS:: @@ -329,7 +327,7 @@ class __experimental_self_test: The test below does not issue a warning message because that warning has already been issued by a previous doc-test in the @experimental code. Note that this behaviour cannot be demonstrated within a single documentation - string: Sphinx will itself supress multiple issued warnings. + string: Sphinx will itself suppress multiple issued warnings. TESTS:: @@ -489,7 +487,6 @@ def __get__(self, inst, cls=None): 3 sage: a1.f(a2.f(0)) 3 - """ if inst is None: return self # Unbound method lookup on class @@ -511,8 +508,8 @@ def deprecated_function_alias(issue_number, func): INPUT: - - ``issue_number`` -- integer. The github issue number where the - deprecation is introduced. + - ``issue_number`` -- integer; the github issue number where the + deprecation is introduced - ``func`` -- the function or method to be aliased diff --git a/src/sage/misc/table.py b/src/sage/misc/table.py index b6065772361..086e8fd49ed 100644 --- a/src/sage/misc/table.py +++ b/src/sage/misc/table.py @@ -23,19 +23,19 @@ class table(SageObject): INPUT: - - ``rows`` (default ``None``) -- a list of lists (or list of tuples, - etc.), containing the data to be displayed. - - ``columns`` (default ``None``) -- a list of lists (etc.), containing + - ``rows`` -- (default: ``None``) list of lists (or list of tuples, + etc.), containing the data to be displayed + - ``columns`` -- (default: ``None``) list of lists (etc.), containing the data to be displayed, but stored as columns. Set either ``rows`` or ``columns``, but not both. - - ``header_row`` (default ``False``) -- if ``True``, first row is - highlighted. - - ``header_column`` (default ``False``) -- if ``True``, first column is - highlighted. - - ``frame`` (default ``False``) -- if ``True``, put a box around each - cell. - - ``align`` (default 'left') -- the alignment of each entry: either - 'left', 'center', or 'right' + - ``header_row`` -- (default: ``False``) if ``True``, first row is + highlighted + - ``header_column`` -- (default: ``False``) if ``True``, first column is + highlighted + - ``frame`` -- (default: ``False``) if ``True``, put a box around each + cell + - ``align`` -- (default: ``'left'``) the alignment of each entry: either + ``'left'``, ``'center'``, or ``'right'`` EXAMPLES:: @@ -314,11 +314,11 @@ def options(self, **kwds): INPUT: - - ``header_row`` -- if True, first row is highlighted. - - ``header_column`` -- if True, first column is highlighted. - - ``frame`` -- if True, put a box around each cell. - - ``align`` -- the alignment of each entry: either 'left', - 'center', or 'right' + - ``header_row`` -- if ``True``, first row is highlighted + - ``header_column`` -- if ``True``, first column is highlighted + - ``frame`` -- if ``True``, put a box around each cell + - ``align`` -- the alignment of each entry: either ``'left'``, + ``'center'``, or ``'right'`` EXAMPLES:: @@ -476,7 +476,7 @@ def _repr_(self) -> str: def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -575,9 +575,7 @@ def _latex_(self): dollar signs are not automatically added, so tables can include both plain text and mathematics. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -656,9 +654,7 @@ def _html_(self): visible effect in the Sage notebook, depending on the version of the notebook. - OUTPUT: - - A :class:`~sage.misc.html.HtmlFragment` instance. + OUTPUT: :class:`~sage.misc.html.HtmlFragment` EXAMPLES:: @@ -770,24 +766,22 @@ def _html_(self): def _html_table_row(self, file, row, header=False): r""" - Write table row + Write table row. Helper method used by the :meth:`_html_` method. INPUT: - - ``file`` -- file-like object. The table row data will be - written to it. - - - ``row`` -- a list with the same number of entries as each row - of the table. + - ``file`` -- file-like object; the table row data will be + written to it - - ``header`` -- bool (default: ``False``). If True, treat this as a - header row, using ```` instead of ````. + - ``row`` -- list with the same number of entries as each row + of the table - OUTPUT: + - ``header`` -- boolean (default: ``False``); if ``True``, treat this + as a header row, using ```` instead of ```` - This method returns nothing. All output is written to ``file``. + OUTPUT: this method returns nothing; all output is written to ``file`` Strings are written verbatim unless they seem to be LaTeX code, in which case they are enclosed in a ``script`` tag diff --git a/src/sage/misc/temporary_file.py b/src/sage/misc/temporary_file.py index e9fb7d121e9..998260be8eb 100644 --- a/src/sage/misc/temporary_file.py +++ b/src/sage/misc/temporary_file.py @@ -23,11 +23,10 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -import io +import atexit import os import tempfile - -import atexit +from typing import IO # Until tmp_dir() and tmp_filename() are removed, we use this directory # as the parent for all temporary files & directories created by them. @@ -41,7 +40,7 @@ # temporary directory ################################################################# -def tmp_dir(name="dir_", ext=""): +def tmp_dir(name='dir_', ext='') -> str: r""" Create and return a temporary directory in ``$HOME/.sage/temp/hostname/pid/`` @@ -50,9 +49,9 @@ def tmp_dir(name="dir_", ext=""): INPUT: - - ``name`` -- (default: ``"dir_"``) A prefix for the directory name. + - ``name`` -- (default: ``'dir_'``) a prefix for the directory name - - ``ext`` -- (default: ``""``) A suffix for the directory name. + - ``ext`` -- (default: ``''``) a suffix for the directory name OUTPUT: @@ -84,7 +83,7 @@ def tmp_dir(name="dir_", ext=""): # temporary filename ################################################################# -def tmp_filename(name="tmp_", ext=""): +def tmp_filename(name='tmp_', ext='') -> str: r""" Create and return a temporary file in ``$HOME/.sage/temp/hostname/pid/`` @@ -94,22 +93,20 @@ def tmp_filename(name="tmp_", ext=""): .. warning:: If you need a particular file extension always use - ``tmp_filename(ext=".foo")``, this will ensure that the file + ``tmp_filename(ext='.foo')``, this will ensure that the file does not yet exist. If you were to use ``tmp_filename()+".foo"``, then you might overwrite an existing file! INPUT: - - ``name`` -- (default: ``"tmp_"``) A prefix for the file name. + - ``name`` -- (default: ``'tmp_'``) a prefix for the file name - - ``ext`` -- (default: ``""``) A suffix for the file name. If you + - ``ext`` -- (default: ``''``) a suffix for the file name. If you want a filename extension in the usual sense, this should start with a dot. - OUTPUT: - - The absolute path of the temporary file created. + OUTPUT: the absolute path of the temporary file created EXAMPLES:: @@ -150,10 +147,10 @@ class atomic_write: INPUT: - - ``target_filename`` -- the name of the file to be written. - Normally, the contents of this file will be overwritten. + - ``target_filename`` -- the name of the file to be written + Normally, the contents of this file will be overwritten - - ``append`` -- (boolean, default: ``False``) if True and + - ``append`` -- boolean (default: ``False``); if ``True`` and ``target_filename`` is an existing file, then copy the current contents of ``target_filename`` to the temporary file when entering the ``with`` statement. Otherwise, the temporary file is @@ -165,12 +162,13 @@ class atomic_write: mode bits of the file were changed manually). (Not to be confused with the file opening mode.) - - ``binary`` -- (boolean, default: ``True`` on Python 2, False on Python 3) the - underlying file is opened in binary mode. If False then it is opened in - text mode and an encoding with which to write the file may be supplied. + - ``binary`` -- boolean (default: ``False``); + the underlying file is opened in binary mode. If ``False`` then it is + opened in text mode and an encoding with which to write the file may be + supplied. - ``**kwargs`` -- additional keyword arguments passed to the underlying - `io.open` call. + `io.open` call EXAMPLES:: @@ -300,7 +298,7 @@ class atomic_write: False """ def __init__(self, target_filename, append=False, mode=0o666, - binary=None, **kwargs): + binary=False, **kwargs) -> None: """ TESTS:: @@ -321,13 +319,11 @@ def __init__(self, target_filename, append=False, mode=0o666, os.umask(umask) self.mode = mode & (~umask) - # 'binary' mode is the default on Python 2, whereas 'text' mode is the - # default on Python 3--this reflects consistent handling of the default - # str type on the two platforms - self.binary = False if binary is None else binary + # 'text' mode is the default on Python 3 + self.binary = binary self.kwargs = kwargs - def __enter__(self): + def __enter__(self) -> IO: """ Create and return a temporary file in ``self.tmpdir`` (normally the same directory as the target file). @@ -335,7 +331,7 @@ def __enter__(self): If ``self.append``, then copy the current contents of ``self.target`` to the temporary file. - OUTPUT: a file returned by :func:`tempfile.NamedTemporaryFile`. + OUTPUT: a file returned by :func:`tempfile.NamedTemporaryFile` TESTS:: @@ -373,7 +369,7 @@ def __enter__(self): return self.tempfile - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, exc_type, exc_val, exc_tb) -> None: """ If the ``with`` block was successful, move the temporary file to the target file. Otherwise, delete the temporary file. @@ -429,8 +425,8 @@ class atomic_dir: INPUT: - - ``target_directory`` -- the name of the directory to be written. - If it exists then the previous contents will be kept. + - ``target_directory`` -- the name of the directory to be written; + if it exists then the previous contents will be kept EXAMPLES:: @@ -458,7 +454,7 @@ class atomic_dir: ....: h.read() 'Second' """ - def __init__(self, target_directory): + def __init__(self, target_directory) -> None: r""" TESTS:: @@ -479,7 +475,7 @@ def __enter__(self): Create and return a temporary directory in ``self.tmpdir`` (normally the same directory as the target file). - OUTPUT: a directory returned by :func:`tempfile.TemporaryDirectory`. + OUTPUT: a directory returned by :func:`tempfile.TemporaryDirectory` TESTS:: @@ -493,7 +489,7 @@ def __enter__(self): self.tempname = os.path.abspath(tdir.name) return tdir - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, exc_type, exc_val, exc_tb) -> None: """ If the ``with`` block was successful, move the temporary directory to the target directory. Otherwise, delete the temporary directory. @@ -519,7 +515,8 @@ def __exit__(self, exc_type, exc_val, exc_tb): try: os.rename(self.tempname, self.target) except OSError: - # Race: Another thread or process must have created the directory + # Race: Another thread or process must have created + # the directory pass else: # Failure: delete temporary file @@ -529,7 +526,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): _spyx_tmp = None -def spyx_tmp(): +def spyx_tmp() -> str: r""" The temporary directory used to store pyx files. diff --git a/src/sage/misc/test_class_pickling.py b/src/sage/misc/test_class_pickling.py index bcc58d3a396..ed2eb62a540 100644 --- a/src/sage/misc/test_class_pickling.py +++ b/src/sage/misc/test_class_pickling.py @@ -8,12 +8,12 @@ class bar: def metaclass(name, bases): """ - Creates a new class in this metaclass + Create a new class in this metaclass. INPUT: - - name -- a string - - bases -- a tuple of classes + - ``name`` -- string + - ``bases`` -- tuple of classes EXAMPLES:: @@ -26,7 +26,6 @@ def metaclass(name, bases): sage: c.__bases__ (<...sage.misc.test_class_pickling.bar...>, <... 'object'>) - """ print("constructing class") result = Metaclass(name, bases, {}) diff --git a/src/sage/misc/test_nested_class.py b/src/sage/misc/test_nested_class.py index 58c1808e6f0..e7791f95a3a 100644 --- a/src/sage/misc/test_nested_class.py +++ b/src/sage/misc/test_nested_class.py @@ -159,8 +159,8 @@ class B: class ABB: class B: """ - This class is broken and can't be pickled. - A warning is emmited during compilation. + This class is broken and cannot be pickled. + A warning is emitted during compilation. """ pass diff --git a/src/sage/misc/timing.py b/src/sage/misc/timing.py index fafe2a44f2b..75d73ef2db6 100644 --- a/src/sage/misc/timing.py +++ b/src/sage/misc/timing.py @@ -41,8 +41,7 @@ def cputime(t=0, subprocesses=False): from an earlier call with ``subprocesses=True``, then ``subprocesses=True`` is assumed. - - subprocesses -- (optional), include subprocesses (default: - ``False``) + - ``subprocesses`` -- boolean (default: ``False``); include subprocesses OUTPUT: @@ -229,13 +228,9 @@ def walltime(t=0): INPUT: + - ``t`` -- (optional) float, time in CPU seconds - - ``t`` -- (optional) float, time in CPU seconds - - OUTPUT: - - - ``float`` -- time in seconds - + OUTPUT: ``float`` -- time in seconds EXAMPLES:: diff --git a/src/sage/misc/trace.py b/src/sage/misc/trace.py index 1d5f383bfc5..927915a4ba5 100644 --- a/src/sage/misc/trace.py +++ b/src/sage/misc/trace.py @@ -13,12 +13,10 @@ def trace(code, preparse=True): INPUT: + - ``code`` -- string - - ``code`` -- str - - - ``preparse`` -- bool (default: ``True``); if True, run - expression through the Sage preparser. - + - ``preparse`` -- boolean (default: ``True``); if ``True``, run + expression through the Sage preparser REMARKS: This function is extremely powerful! For example, if you want to step through each line of execution of, e.g., diff --git a/src/sage/misc/unknown.py b/src/sage/misc/unknown.py index 8387f1e2a45..fddbfccb8a1 100644 --- a/src/sage/misc/unknown.py +++ b/src/sage/misc/unknown.py @@ -5,12 +5,12 @@ The ``Unknown`` object is used in Sage in several places as return value in addition to ``True`` and ``False``, in order to signal uncertainty about or inability to compute the result. ``Unknown`` can be identified -using ``is``, or by catching :class:`UnknownError` from a boolean operation. +using ``is``, or by catching :exc:`UnknownError` from a boolean operation. .. WARNING:: Calling ``bool()`` with ``Unknown`` as argument will throw an - ``UnknownError``. This also means that in the following cases, + :exc:`UnknownError`. This also means that in the following cases, ``and``, ``not``, and ``or`` fail or return a somewhat wrong value:: sage: not Unknown # should return Unknown @@ -50,7 +50,7 @@ n=0 is neither positive nor negative n=12 is positive -Using ``UnknownError``:: +Using :exc:`UnknownError`:: sage: for n in [-3, 0, 12]: ....: try: @@ -102,18 +102,18 @@ class UnknownError(TypeError): @richcmp_method class UnknownClass(UniqueRepresentation): """ - The Unknown truth value + The Unknown truth value. The ``Unknown`` object is used in Sage in several places as return value in addition to ``True`` and ``False``, in order to signal uncertainty about or inability to compute the result. ``Unknown`` can be identified - using ``is``, or by catching :class:`UnknownError` from a boolean + using ``is``, or by catching :exc:`UnknownError` from a boolean operation. .. WARNING:: Calling ``bool()`` with ``Unknown`` as argument will throw an - ``UnknownError``. This also means that applying ``and``, ``not``, + :exc:`UnknownError`. This also means that applying ``and``, ``not``, and ``or`` to ``Unknown`` might fail. TESTS:: @@ -131,7 +131,7 @@ def __repr__(self): def __bool__(self): """ - When evaluated in a boolean context ``Unknown`` raises a ``UnknownError``. + When evaluated in a boolean context ``Unknown`` raises a :exc:`UnknownError`. EXAMPLES:: diff --git a/src/sage/misc/verbose.py b/src/sage/misc/verbose.py index eeb24b08b41..189c15f883c 100644 --- a/src/sage/misc/verbose.py +++ b/src/sage/misc/verbose.py @@ -113,29 +113,26 @@ verbose_files = [] -def verbose(mesg="", t=0, level=1, caller_name=None): +def verbose(mesg='', t=0, level=1, caller_name=None): """ Print a message if the current verbosity is at least level. INPUT: + - ``mesg`` -- string; a message to print - - ``mesg`` -- str, a message to print + - ``t`` -- integer (optional); if included, will also print ``cputime(t)``, + which is the time since time ``t``. Thus ``t`` should have been obtained + with ``t=cputime()`` - - ``t`` -- int, optional, if included, will also print - cputime(t), - which is the time since time t. Thus t should have - been obtained with t=cputime() + - ``level`` -- integer (default: 1); the verbosity level of + what we are printing - - ``level`` -- int, (default: 1) the verbosity level of - what we are printing + - ``caller_name`` -- string (default: ``None``); the name + of the calling function. In most cases Python can deduce this, so + it need not be provided. - - ``caller_name`` -- string (default: None), the name - of the calling function; in most cases Python can deduce this, so - it need not be provided. - - - OUTPUT: possibly prints a message to stdout; also returns - cputime() + OUTPUT: possibly prints a message to stdout; also returns ``cputime()`` EXAMPLES:: @@ -191,13 +188,13 @@ def set_verbose(level, files='all'): INPUT: - - ``level`` -- an integer between 0 and 2, inclusive. + - ``level`` -- integer between 0 and 2, inclusive - - ``files`` (default: 'all'): list of files to make verbose, or - 'all' to make ALL files verbose (the default). + - ``files`` -- (default: ``'all'``) list of files to make verbose, or + 'all' to make ALL files verbose (the default) OUTPUT: changes the state of the verbosity flag and possibly - appends to the list of files that are verbose. + appends to the list of files that are verbose EXAMPLES:: @@ -222,9 +219,6 @@ def set_verbose(level, files='all'): def set_verbose_files(file_name): - """ - - """ if not isinstance(file_name, list): file_name = [file_name] global verbose_files @@ -232,16 +226,10 @@ def set_verbose_files(file_name): def get_verbose_files(): - """ - - """ return verbose_files def unset_verbose_files(file_name): - """ - - """ if not isinstance(file_name, list): file_name = [file_name] for X in file_name: @@ -252,10 +240,6 @@ def get_verbose(): """ Return the global Sage verbosity level. - INPUT: int level: an integer between 0 and 2, inclusive. - - OUTPUT: changes the state of the verbosity flag. - EXAMPLES:: sage: get_verbose() diff --git a/src/sage/misc/viewer.py b/src/sage/misc/viewer.py index caca6647acf..badc70a963a 100644 --- a/src/sage/misc/viewer.py +++ b/src/sage/misc/viewer.py @@ -38,9 +38,9 @@ def default_viewer(viewer=None): INPUT: - - ``viewer``: ``None`` or a string: one of 'browser', 'pdf', 'png', - 'dvi' -- return the name of the corresponding program. ``None`` - is treated the same as 'browser'. + - ``viewer`` -- ``None`` or a string; one of ``'browser'``, ``'pdf'``, + ``'png'``, ``'dvi'``. Return the name of the corresponding program. + ``None`` is treated the same as ``'browser'``. EXAMPLES:: @@ -69,7 +69,7 @@ def default_viewer(viewer=None): elif os.uname()[0] == 'Darwin': # Simple on OS X, since there is an open command that opens # anything, using the user's preferences. - BROWSER = 'open' + BROWSER = 'open -W' DVI_VIEWER = BROWSER PDF_VIEWER = BROWSER PNG_VIEWER = BROWSER @@ -149,9 +149,9 @@ def _set(self, app=None, TYPE='browser'): INPUT: - - ``app`` -- ``None`` or a string, the program to use - - ``TYPE`` -- a string, must be in the list ``VIEWERS`` defined in - :mod:`sage.misc.viewer`. Default 'browser'. + - ``app`` -- ``None`` or a string; the program to use + - ``TYPE`` -- string (default: ``'browser'``); must be in the list + ``VIEWERS`` defined in :mod:`sage.misc.viewer` EXAMPLES:: diff --git a/src/sage/misc/weak_dict.pyx b/src/sage/misc/weak_dict.pyx index f4b20c0fcd1..ce69b6a840a 100644 --- a/src/sage/misc/weak_dict.pyx +++ b/src/sage/misc/weak_dict.pyx @@ -168,7 +168,7 @@ cdef class WeakValueDictEraser: """ INPUT: - A :class:`sage.misc.weak_dict.WeakValueDictionary`. + - ``D`` -- a :class:`sage.misc.weak_dict.WeakValueDictionary` EXAMPLES:: @@ -186,7 +186,7 @@ cdef class WeakValueDictEraser: """ INPUT: - A weak reference with key. + - ``r`` -- a weak reference with key When this is called with a weak reference ``r``, then an entry from the dictionary pointed to by ``self.D`` is removed that has ``r`` as a value @@ -278,7 +278,7 @@ cdef class WeakValueDictionary(dict): the dictionary values. However, the actual deletion is postponed till after the iteration over the dictionary has finished. Hence, when the callbacks are executed, the values which the callback belongs to has - already been overridded by a new value. Therefore, the callback does not + already been overridden by a new value. Therefore, the callback does not delete the item:: sage: for k in D: # indirect doctest @@ -335,7 +335,7 @@ cdef class WeakValueDictionary(dict): INPUT: - - ``data`` -- Optional iterable of key-value pairs + - ``data`` -- (optional) iterable of key-value pairs EXAMPLES:: @@ -370,7 +370,6 @@ cdef class WeakValueDictionary(dict): sage: E = copy(D) # indirect doctest sage: set(E.items()) == set(D.items()) True - """ return WeakValueDictionary(self.items()) @@ -403,7 +402,6 @@ cdef class WeakValueDictionary(dict): sage: set(E.values()) == set(D.values()) == set(V) True - """ out = WeakValueDictionary() for k,v in self.items(): @@ -461,7 +459,7 @@ cdef class WeakValueDictionary(dict): TESTS: - Check that :issue:`15956` has been fixed, i.e., a ``TypeError`` is + Check that :issue:`15956` has been fixed, i.e., a :exc:`TypeError` is raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() @@ -469,7 +467,6 @@ cdef class WeakValueDictionary(dict): Traceback (most recent call last): ... TypeError: mutable matrices are unhashable - """ cdef PyObject* wr = PyDict_GetItemWithError(self, k) if wr != NULL: @@ -536,7 +533,7 @@ cdef class WeakValueDictionary(dict): sage: list(D.items()) [(2, Integer Ring)] - Check that :issue:`15956` has been fixed, i.e., a ``TypeError`` is + Check that :issue:`15956` has been fixed, i.e., a :exc:`TypeError` is raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() @@ -582,7 +579,7 @@ cdef class WeakValueDictionary(dict): TESTS: - Check that :issue:`15956` has been fixed, i.e., a ``TypeError`` is + Check that :issue:`15956` has been fixed, i.e., a :exc:`TypeError` is raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() @@ -590,7 +587,6 @@ cdef class WeakValueDictionary(dict): Traceback (most recent call last): ... TypeError: mutable matrices are unhashable - """ cdef PyObject* wr = PyDict_GetItemWithError(self, k) if wr == NULL: @@ -621,13 +617,12 @@ cdef class WeakValueDictionary(dict): (1, Integer Ring) Now, the dictionary is empty, and hence the next attempt to pop an - item will fail with a ``KeyError``:: + item will fail with a :exc:`KeyError`:: sage: D.popitem() Traceback (most recent call last): ... KeyError: 'popitem(): weak value dictionary is empty' - """ for k,v in self.items(): del self[k] @@ -660,7 +655,7 @@ cdef class WeakValueDictionary(dict): TESTS: - Check that :issue:`15956` has been fixed, i.e., a ``TypeError`` is + Check that :issue:`15956` has been fixed, i.e., a :exc:`TypeError` is raised for unhashable objects:: sage: # needs sage.libs.pari @@ -669,7 +664,6 @@ cdef class WeakValueDictionary(dict): Traceback (most recent call last): ... TypeError: mutable matrices are unhashable - """ cdef PyObject * wr = PyDict_GetItemWithError(self, k) if wr == NULL: @@ -701,7 +695,7 @@ cdef class WeakValueDictionary(dict): sage: D[int(10)] Integer Ring - Check that :issue:`15956` has been fixed, i.e., a ``TypeError`` is + Check that :issue:`15956` has been fixed, i.e., a :exc:`TypeError` is raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() @@ -709,7 +703,6 @@ cdef class WeakValueDictionary(dict): Traceback (most recent call last): ... TypeError: mutable matrices are unhashable - """ cdef PyObject* wr = PyDict_GetItemWithError(self, k) if wr == NULL: @@ -745,7 +738,7 @@ cdef class WeakValueDictionary(dict): sage: 3 in D False - Check that :issue:`15956` has been fixed, i.e., a ``TypeError`` is + Check that :issue:`15956` has been fixed, i.e., a :exc:`TypeError` is raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() @@ -753,7 +746,6 @@ cdef class WeakValueDictionary(dict): Traceback (most recent call last): ... TypeError: mutable matrices are unhashable - """ cdef PyObject* wr = PyDict_GetItemWithError(self, k) return (wr != NULL) and (PyWeakref_GetObject(wr) != Py_None) @@ -818,7 +810,6 @@ cdef class WeakValueDictionary(dict): sage: sorted(D.keys()) [0, 1, 2, 3, 5, 6, 7, 8, 9] - """ return list(iter(self)) @@ -882,7 +873,6 @@ cdef class WeakValueDictionary(dict): <7> <8> <9> - """ cdef PyObject *key cdef PyObject *wr @@ -1001,7 +991,6 @@ cdef class WeakValueDictionary(dict): [7] <7> [8] <8> [9] <9> - """ cdef PyObject *key cdef PyObject *wr @@ -1196,9 +1185,9 @@ cdef class CachedWeakValueDictionary(WeakValueDictionary): INPUT: - - ``data`` -- Optional iterable of key-value pairs + - ``data`` -- (optional) iterable of key-value pairs - - ``cache`` -- (default: 16) Number of values with strong + - ``cache`` -- (default: 16) number of values with strong references EXAMPLES:: diff --git a/src/sage/modular/abvar/abvar.py b/src/sage/modular/abvar/abvar.py index 2c87874503b..92b1e9f9abe 100644 --- a/src/sage/modular/abvar/abvar.py +++ b/src/sage/modular/abvar/abvar.py @@ -41,6 +41,7 @@ from sage.categories.modular_abelian_varieties import ModularAbelianVarieties from sage.matrix.constructor import matrix from sage.matrix.special import block_diagonal_matrix, identity_matrix +from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.modular.arithgroup.congroup_gamma0 import Gamma0_class @@ -69,8 +70,7 @@ ['cremona_letter_code', 'CremonaDatabase']) -from . import homspace -from . import lseries +from sage.modular.abvar import homspace, lseries from .morphism import HeckeOperator, Morphism, DegeneracyMap from .torsion_subgroup import RationalTorsionSubgroup, QQbarTorsionSubgroup from .finite_subgroup import (FiniteSubgroup_lattice, FiniteSubgroup, @@ -81,11 +81,11 @@ def is_ModularAbelianVariety(x) -> bool: """ - Return True if x is a modular abelian variety. + Return ``True`` if x is a modular abelian variety. INPUT: - - ``x`` -- object + - ``x`` -- object EXAMPLES:: @@ -98,7 +98,7 @@ def is_ModularAbelianVariety(x) -> bool: sage: is_ModularAbelianVariety(J0(37)) True - Returning True is a statement about the data type not whether or + Returning ``True`` is a statement about the data type not whether or not some abelian variety is modular:: sage: is_ModularAbelianVariety(EllipticCurve('37a')) @@ -118,27 +118,23 @@ def __init__(self, groups, base_field, is_simple=None, newform_level=None, INPUT: + - ``groups`` -- tuple of congruence subgroups - - ``groups`` -- a tuple of congruence subgroups + - ``base_field`` -- a field - - ``base_field`` -- a field + - ``is_simple`` -- boolean; whether or not ``self`` is simple - - ``is_simple`` -- bool; whether or not self is - simple + - ``newform_level`` -- if ``self`` is isogenous to a + newform abelian variety, returns the level of that abelian variety - - ``newform_level`` -- if self is isogenous to a - newform abelian variety, returns the level of that abelian variety + - ``isogeny_number`` -- which isogeny class the corresponding newform + is in; this corresponds to the Cremona letter code - - ``isogeny_number`` -- which isogeny class the - corresponding newform is in; this corresponds to the Cremona letter - code - - - ``number`` -- the t number of the degeneracy map that - this abelian variety is the image under - - - ``check`` -- whether to do some type checking on the - defining data + - ``number`` -- the t number of the degeneracy map that + this abelian variety is the image under + - ``check`` -- whether to do some type checking on the + defining data EXAMPLES: One should not create an instance of this class, but we do so anyways here as an example:: @@ -203,9 +199,9 @@ def groups(self): def is_J0(self) -> bool: """ - Return whether of not self is of the form J0(N). + Return whether or not ``self`` is of the form J0(N). - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -225,9 +221,9 @@ def is_J0(self) -> bool: def is_J1(self) -> bool: """ - Return whether of not self is of the form J1(N). + Return whether or not ``self`` is of the form J1(N). - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -332,7 +328,7 @@ def base_extend(self, K): def __contains__(self, x) -> bool: """ - Determine whether or not self contains x. + Determine whether or not ``self`` contains x. EXAMPLES:: @@ -368,11 +364,11 @@ def __richcmp__(self, other, op): """ Compare two modular abelian varieties. - If other is not a modular abelian variety, compares the types of - self and other. If other is a modular abelian variety, compares the - groups, then if those are the same, compares the newform level and - isogeny class number and degeneracy map numbers. If those are not - defined or matched up, compare the underlying lattices. + If ``other`` is not a modular abelian variety, compares the types of + ``self`` and ``other``. If ``other`` is a modular abelian variety, + compares the groups, then if those are the same, compares the newform + level and isogeny class number and degeneracy map numbers. If those are + not defined or matched up, compare the underlying lattices. EXAMPLES:: @@ -426,7 +422,8 @@ def __richcmp__(self, other, op): def __radd__(self, other): """ - Return other + self when other is 0. Otherwise raise a TypeError. + Return ``other`` + ``self`` when ``other`` is 0. Otherwise raise a + :exc:`TypeError`. EXAMPLES:: @@ -510,7 +507,7 @@ def label(self) -> str: ... ValueError: self must be simple - We illustrate that self need not equal `\delta_t(A_f)`:: + We illustrate that ``self`` need not equal `\delta_t(A_f)`:: sage: J = J0(11); phi = J.degeneracy_map(33, 1) + J.degeneracy_map(33,3) sage: B = phi.image(); B @@ -533,14 +530,14 @@ def newform(self, names=None): the newform abelian variety `A_f`. If this abelian variety is not - simple, this raises a :class:`ValueError`. + simple, this raises a :exc:`ValueError`. INPUT: - - ``names`` -- (default: ``None``) If the newform has coefficients - in a number field, then a generator name must be specified. + - ``names`` -- (default: ``None``) if the newform has coefficients + in a number field, then a generator name must be specified - OUTPUT: A newform `f` so that ``self`` is isogenous to `A_f`. + OUTPUT: a newform `f` so that ``self`` is isogenous to `A_f` EXAMPLES:: @@ -569,11 +566,9 @@ def newform(self, names=None): def newform_decomposition(self, names=None): """ Return the newforms of the simple subvarieties in the decomposition of - self as a product of simple subvarieties, up to isogeny. - - OUTPUT: + ``self`` as a product of simple subvarieties, up to isogeny. - - an array of newforms + OUTPUT: an array of newforms EXAMPLES:: @@ -591,7 +586,7 @@ def newform_label(self): abelian variety `A_f`. If this abelian variety is not simple, this raises - a :class:`ValueError`. + a :exc:`ValueError`. OUTPUT: string @@ -623,16 +618,16 @@ def elliptic_curve(self): Return an elliptic curve isogenous to ``self``. If ``self`` is not dimension 1 - with rational base ring, this raises a :class:`ValueError`. + with rational base ring, this raises a :exc:`ValueError`. The elliptic curve is found by looking it up in the CremonaDatabase. The CremonaDatabase contains all curves up to some large conductor. If a curve is not found in the - CremonaDatabase, a :class:`RuntimeError` will be raised. In + CremonaDatabase, a :exc:`RuntimeError` will be raised. In practice, only the most committed users will see this - :class:`RuntimeError`. + :exc:`RuntimeError`. - OUTPUT: an elliptic curve isogenous to ``self``. + OUTPUT: an elliptic curve isogenous to ``self`` EXAMPLES:: @@ -695,11 +690,11 @@ def elliptic_curve(self): def _isogeny_to_newform_abelian_variety(self): r""" - Return an isogeny from self to an abelian variety `A_f` + Return an isogeny from ``self`` to an abelian variety `A_f` attached to a newform. - If self is not simple (so that no such - isogeny exists), this raises a :class:`ValueError`. + If ``self`` is not simple (so that no such + isogeny exists), this raises a :exc:`ValueError`. EXAMPLES:: @@ -742,10 +737,10 @@ def _isogeny_to_newform_abelian_variety(self): def _simple_isogeny(self, other): """ - Given self and other, if both are simple, and correspond to the + Given ``self`` and ``other``, if both are simple, and correspond to the same newform with the same congruence subgroup, return an isogeny. - Otherwise, this raises a :class:`ValueError`. + Otherwise, this raises a :exc:`ValueError`. INPUT: @@ -795,11 +790,9 @@ def _Hom_(self, B, cat=None): """ INPUT: + - ``B`` -- modular abelian varieties - - ``B`` -- modular abelian varieties - - - ``cat`` -- category - + - ``cat`` -- category EXAMPLES:: @@ -826,8 +819,8 @@ def _Hom_(self, B, cat=None): def in_same_ambient_variety(self, other): """ - Return True if self and other are abelian subvarieties of the same - ambient product Jacobian. + Return ``True`` if ``self`` and ``other`` are abelian subvarieties of + the same ambient product Jacobian. EXAMPLES:: @@ -848,7 +841,7 @@ def in_same_ambient_variety(self, other): def modular_kernel(self): """ Return the modular kernel of this abelian variety, which is the - kernel of the canonical polarization of self. + kernel of the canonical polarization of ``self``. EXAMPLES:: @@ -881,8 +874,8 @@ def modular_degree(self): def intersection(self, other): """ - Return the intersection of self and other inside a common ambient - Jacobian product. + Return the intersection of ``self`` and ``other`` inside a common + ambient Jacobian product. When ``other`` is a modular abelian variety, the output will be a tuple ``(G, A)``, where ``G`` is a finite subgroup that surjects onto the @@ -893,23 +886,20 @@ def intersection(self, other): INPUT: + - ``other`` -- a modular abelian variety or a finite + group - - ``other`` -- a modular abelian variety or a finite - group + OUTPUT: if other is a modular abelian variety: - OUTPUT: If other is a modular abelian variety: + - ``G`` -- finite subgroup of self - - - ``G`` -- finite subgroup of self - - - ``A`` -- abelian variety (identity component of - intersection) + - ``A`` -- abelian variety (identity component of + intersection) If other is a finite group: - - ``G`` -- a finite group - + - ``G`` -- a finite group EXAMPLES: We intersect some abelian varieties with finite intersection. @@ -918,16 +908,24 @@ def intersection(self, other): sage: J = J0(37) sage: J[0].intersection(J[1]) - (Finite subgroup with invariants [2, 2] over QQ of Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37), Simple abelian subvariety of dimension 0 of J0(37)) + (Finite subgroup with invariants [2, 2] over QQ of Simple abelian + subvariety 37a(1,37) of dimension 1 of J0(37), Simple abelian + subvariety of dimension 0 of J0(37)) :: sage: D = list(J0(65)); D - [Simple abelian subvariety 65a(1,65) of dimension 1 of J0(65), Simple abelian subvariety 65b(1,65) of dimension 2 of J0(65), Simple abelian subvariety 65c(1,65) of dimension 2 of J0(65)] + [Simple abelian subvariety 65a(1,65) of dimension 1 of J0(65), + Simple abelian subvariety 65b(1,65) of dimension 2 of J0(65), + Simple abelian subvariety 65c(1,65) of dimension 2 of J0(65)] sage: D[0].intersection(D[1]) - (Finite subgroup with invariants [2] over QQ of Simple abelian subvariety 65a(1,65) of dimension 1 of J0(65), Simple abelian subvariety of dimension 0 of J0(65)) + (Finite subgroup with invariants [2] over QQ of Simple abelian + subvariety 65a(1,65) of dimension 1 of J0(65), Simple abelian + subvariety of dimension 0 of J0(65)) sage: (D[0]+D[1]).intersection(D[1]+D[2]) - (Finite subgroup with invariants [2] over QQbar of Abelian subvariety of dimension 3 of J0(65), Abelian subvariety of dimension 2 of J0(65)) + (Finite subgroup with invariants [2] over QQbar of Abelian + subvariety of dimension 3 of J0(65), Abelian subvariety of + dimension 2 of J0(65)) :: @@ -1021,17 +1019,17 @@ def intersection(self, other): def __add__(self, other): r""" - Return the sum of the *images* of self and other inside the + Return the sum of the *images* of ``self`` and ``other`` inside the ambient Jacobian product. - Here self and other must be abelian + Here ``self`` and ``other`` must be abelian subvarieties of the ambient Jacobian product. .. WARNING:: The sum of course only makes sense in some ambient variety, and by definition this function takes the sum of the images - of both self and other in the ambient product Jacobian. + of both ``self`` and ``other`` in the ambient product Jacobian. EXAMPLES: @@ -1100,13 +1098,11 @@ def __add__(self, other): def direct_product(self, other): """ - Compute the direct product of self and other. + Compute the direct product of ``self`` and ``other``. INPUT: - - - ``self, other`` -- modular abelian varieties - + - ``self``, ``other`` -- modular abelian varieties OUTPUT: abelian variety @@ -1128,13 +1124,11 @@ def direct_product(self, other): def __pow__(self, n): """ - Return `n^{th}` power of self. + Return `n`-th power of ``self``. INPUT: - - - ``n`` -- a nonnegative integer - + - ``n`` -- nonnegative integer OUTPUT: an abelian variety @@ -1162,7 +1156,7 @@ def __pow__(self, n): def __mul__(self, other): """ - Compute the direct product of self and other. + Compute the direct product of ``self`` and ``other``. EXAMPLES: Some modular Jacobians:: @@ -1188,17 +1182,15 @@ def __mul__(self, other): def quotient(self, other, **kwds): """ - Compute the quotient of self and other, where other is either an - abelian subvariety of self or a finite subgroup of self. + Compute the quotient of ``self`` and ``other``, where other is either an + abelian subvariety of ``self`` or a finite subgroup of ``self``. INPUT: + - ``other`` -- a finite subgroup or subvariety + - further named arguments, that are currently ignored - - ``other`` -- a finite subgroup or subvariety - - further named arguments, that are currently ignored. - - - OUTPUT: a pair (A, phi) with phi the quotient map from self to A + OUTPUT: a pair (A, phi) with phi the quotient map from ``self`` to A EXAMPLES: We quotient `J_0(33)` out by an abelian subvariety:: @@ -1228,14 +1220,12 @@ def quotient(self, other, **kwds): def __truediv__(self, other): """ - Compute the quotient of self and other, where other is either an - abelian subvariety of self or a finite subgroup of self. + Compute the quotient of ``self`` and ``other``, where other is either + an abelian subvariety of ``self`` or a finite subgroup of ``self``. INPUT: - - - ``other`` -- a finite subgroup or subvariety - + - ``other`` -- a finite subgroup or subvariety EXAMPLES: Quotient out by a finite group:: @@ -1288,21 +1278,19 @@ def __truediv__(self, other): def degeneracy_map(self, M_ls, t_ls): """ - Return the degeneracy map with domain self and given - level/parameter. If self.ambient_variety() is a product of + Return the degeneracy map with domain ``self`` and given + level/parameter. If ``self.ambient_variety()`` is a product of Jacobians (as opposed to a single Jacobian), then one can provide a list of new levels and parameters, corresponding to the ambient Jacobians in order. (See the examples below.) INPUT: + - ``M``, ``t`` -- integers level and `t`, or - - ``M, t`` -- integers level and `t`, or - - - ``Mlist, tlist`` -- if self is in a nontrivial - product ambient Jacobian, input consists of a list of levels and - corresponding list of `t`'s. - + - ``Mlist, tlist`` -- if ``self`` is in a nontrivial + product ambient Jacobian, input consists of a list of levels and + corresponding list of `t`'s. OUTPUT: a degeneracy map @@ -1375,21 +1363,18 @@ def degeneracy_map(self, M_ls, t_ls): def _quotient_by_finite_subgroup(self, G): """ - Return the quotient of self by the finite subgroup `G`. + Return the quotient of ``self`` by the finite subgroup `G`. This is used internally by the quotient and __div__ commands. INPUT: + - ``G`` -- a finite subgroup of self - - ``G`` -- a finite subgroup of self - - - OUTPUT: abelian variety - the quotient `Q` of self by `G` - + OUTPUT: - - ``morphism`` -- from self to the quotient - `Q` + - abelian variety; the quotient `Q` of ``self`` by `G` + - ``morphism`` -- from ``self`` to the quotient `Q` EXAMPLES: We quotient the elliptic curve `J_0(11)` out by its cuspidal subgroup. @@ -1424,7 +1409,6 @@ def _quotient_by_finite_subgroup(self, G): Abelian variety J0(22) of dimension 2 sage: f Abelian variety endomorphism of Abelian variety J0(22) of dimension 2 - """ if G.order() == 1: return self, self.endomorphism_ring().identity() @@ -1436,24 +1420,18 @@ def _quotient_by_finite_subgroup(self, G): def _quotient_by_abelian_subvariety(self, B): """ - Return the quotient of self by the abelian variety `B`. - This is used internally by the quotient and __div__ commands. + Return the quotient of ``self`` by the abelian variety `B`. + This is used internally by the quotient and ``__div__`` commands. INPUT: - - - ``B`` -- an abelian subvariety of self - + - ``B`` -- an abelian subvariety of ``self`` OUTPUT: + - ``abelian variety`` -- quotient `Q` of ``self`` by B - - ``abelian variety`` -- quotient `Q` of self - by B - - - ``morphism`` -- from self to the quotient - `Q` - + - ``morphism`` -- from ``self`` to the quotient `Q` EXAMPLES: We compute the new quotient of `J_0(33)`. @@ -1524,13 +1502,11 @@ def _quotient_by_abelian_subvariety(self, B): def projection(self, A, check=True): """ Given an abelian subvariety A of self, return a projection morphism - from self to A. Note that this morphism need not be unique. + from ``self`` to A. Note that this morphism need not be unique. INPUT: - - - ``A`` -- an abelian variety - + - ``A`` -- an abelian variety OUTPUT: a morphism @@ -1593,8 +1569,8 @@ def projection(self, A, check=True): def project_to_factor(self, n): """ - If self is an ambient product of Jacobians, return a projection - from self to the nth such Jacobian. + If ``self`` is an ambient product of Jacobians, return a projection + from ``self`` to the `n`-th such Jacobian. EXAMPLES:: @@ -1641,7 +1617,7 @@ def project_to_factor(self, n): def is_subvariety_of_ambient_jacobian(self): """ - Return True if self is (presented as) a subvariety of the ambient + Return ``True`` if ``self`` is (presented as) a subvariety of the ambient product Jacobian. Every abelian variety in Sage is a quotient of a subvariety of an @@ -1695,8 +1671,8 @@ def ambient_variety(self): def ambient_morphism(self): """ - Return the morphism from self to the ambient variety. This is - injective if self is natural a subvariety of the ambient product + Return the morphism from ``self`` to the ambient variety. This is + injective if ``self`` is natural a subvariety of the ambient product Jacobian. OUTPUT: morphism @@ -1716,9 +1692,7 @@ def ambient_morphism(self): [ 1 1 -2 0 2 -1] [ 0 3 -2 -1 2 0] - phi is of course injective - - :: + ``phi`` is of course injective:: sage: phi.kernel() (Finite subgroup with invariants [] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), @@ -1743,7 +1717,8 @@ def ambient_morphism(self): [ 0 0 5 10 -5 15] [ 0 0 0 15 -15 30] sage: phi.kernel()[0] - Finite subgroup with invariants [5, 15, 15] over QQ of Abelian variety factor of dimension 2 of J0(33) + Finite subgroup with invariants [5, 15, 15] over QQ of Abelian + variety factor of dimension 2 of J0(33) """ try: return self.__ambient_morphism @@ -1753,11 +1728,12 @@ def ambient_morphism(self): self.__ambient_morphism = phi return phi + @cached_method def is_ambient(self) -> bool: """ - Return True if self equals the ambient product Jacobian. + Return ``True`` if ``self`` equals the ambient product Jacobian. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -1771,13 +1747,8 @@ def is_ambient(self) -> bool: sage: (A+B+C).is_ambient() True """ - try: - return self.__is_ambient - except AttributeError: - pass L = self.lattice() - self.__is_ambient = (self.lattice() == ZZ**L.degree()) - return self.__is_ambient + return self.lattice() == ZZ**L.degree() def dimension(self): """ @@ -1831,7 +1802,7 @@ def conductor(self): def rank(self): """ - Return the rank of the underlying lattice of self. + Return the rank of the underlying lattice of ``self``. EXAMPLES:: @@ -1860,7 +1831,7 @@ def degree(self): def endomorphism_ring(self, category=None): """ - Return the endomorphism ring of self. + Return the endomorphism ring of ``self``. OUTPUT: b = self.sturm_bound() @@ -1915,12 +1886,13 @@ def sturm_bound(self): self.__sturm_bound = B return B + @cached_method def is_hecke_stable(self) -> bool: """ - Return True if self is stable under the Hecke operators of its + Return ``True`` if ``self`` is stable under the Hecke operators of its ambient Jacobian. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -1933,11 +1905,6 @@ def is_hecke_stable(self) -> bool: sage: (J0(33)[0] + J0(33)[1]).is_hecke_stable() True """ - try: - return self._is_hecke_stable - except AttributeError: - pass - # b = self.modular_symbols().sturm_bound() b = max([m.sturm_bound() for m in self._ambient_modular_symbols_spaces()]) @@ -1949,17 +1916,15 @@ def is_hecke_stable(self) -> bool: Tn_matrix = J.hecke_operator(n).matrix() for v in B: if v * Tn_matrix not in L: - self._is_hecke_stable = False return False - self._is_hecke_stable = True return True def is_subvariety(self, other) -> bool: """ - Return True if self is a subvariety of other as they sit in a + Return ``True`` if ``self`` is a subvariety of other as they sit in a common ambient modular Jacobian. In particular, this function will - only return True if self and other have exactly the same ambient + only return ``True`` if ``self`` and ``other`` have exactly the same ambient Jacobians. EXAMPLES:: @@ -2008,9 +1973,9 @@ def change_ring(self, R): def level(self): """ Return the level of this modular abelian variety, which is an - integer N (usually minimal) such that this modular abelian variety + integer `N` (usually minimal) such that this modular abelian variety is a quotient of `J_1(N)`. In the case that the ambient - variety of self is a product of Jacobians, return the LCM of their + variety of ``self`` is a product of Jacobians, return the LCM of their levels. EXAMPLES:: @@ -2030,7 +1995,7 @@ def level(self): def newform_level(self, none_if_not_known=False): """ - Write self as a product (up to isogeny) of newform abelian + Write ``self`` as a product (up to isogeny) of newform abelian varieties `A_f`. Then this function return the least common multiple of the levels of the newforms `f`, along with the corresponding group or list of groups (the groups do not @@ -2038,11 +2003,9 @@ def newform_level(self, none_if_not_known=False): INPUT: - - - ``none_if_not_known`` -- (default: ``False``) if True, - return None instead of attempting to compute the newform level, if - it isn't already known. This None result is not cached. - + - ``none_if_not_known`` -- boolean (default: ``False``); if ``True``, + return ``None`` instead of attempting to compute the newform level, + if it isn't already known. This None result is not cached. OUTPUT: integer group or list of distinct groups @@ -2074,7 +2037,7 @@ def newform_level(self, none_if_not_known=False): def zero_subvariety(self): """ - Return the zero subvariety of self. + Return the zero subvariety of ``self``. EXAMPLES:: @@ -2140,7 +2103,7 @@ def _ambient_latex_repr(self): def _ambient_lattice(self): """ - Return free lattice of rank twice the degree of self. This is the + Return free lattice of rank twice the degree of ``self``. This is the lattice corresponding to the ambient product Jacobian. OUTPUT: lattice @@ -2168,7 +2131,7 @@ def _ambient_lattice(self): def _ambient_modular_symbols_spaces(self): """ Return a tuple of the ambient cuspidal modular symbols spaces that - make up the Jacobian product that contains self. + make up the Jacobian product that contains ``self``. OUTPUT: tuple of cuspidal modular symbols spaces @@ -2193,7 +2156,7 @@ def _ambient_modular_symbols_spaces(self): def _ambient_modular_symbols_abvars(self): """ Return a tuple of the ambient modular symbols abelian varieties - that make up the Jacobian product that contains self. + that make up the Jacobian product that contains ``self``. OUTPUT: tuple of modular symbols abelian varieties @@ -2249,9 +2212,7 @@ def _ambient_hecke_matrix_on_modular_symbols(self, n): INPUT: - - - ``n`` -- an integer `\geq 1`. - + - ``n`` -- integer `\geq 1` OUTPUT: a matrix @@ -2294,14 +2255,13 @@ def rational_torsion_order(self, proof=True): INPUT: - - ``proof`` -- a boolean (default: ``True``) + - ``proof`` -- boolean (default: ``True``) OUTPUT: The order of the rational torsion subgroup of this modular abelian variety. - EXAMPLES:: sage: J0(11).rational_torsion_subgroup().order() @@ -2354,15 +2314,13 @@ def number_of_rational_points(self): def frobenius_polynomial(self, p, var='x'): """ - Computes the frobenius polynomial at `p`. + Compute the frobenius polynomial at `p`. INPUT: - ``p`` -- prime number - OUTPUT: - - a monic integral polynomial + OUTPUT: a monic integral polynomial EXAMPLES:: @@ -2413,8 +2371,8 @@ def frobenius_polynomial(self, p, var='x'): from .constructor import AbelianVariety decomp = [AbelianVariety(f) for f in self.newform_decomposition('a')] - return prod((s.frobenius_polynomial(p) for s in - decomp)) + return prod(s.frobenius_polynomial(p) for s in + decomp) f = self.newform('a') Kf = f.base_ring() eps = f.character() @@ -2499,7 +2457,7 @@ def homology(self, base_ring=ZZ): sage: J0(389).homology(ZZ) Integral Homology of Abelian variety J0(389) of dimension 32 """ - from . import homology + from sage.modular.abvar import homology try: return self._homology[base_ring] except AttributeError: @@ -2621,9 +2579,9 @@ def padic_lseries(self, p): ############################################################################### def hecke_operator(self, n): """ - Return the `n^{th}` Hecke operator on the modular abelian + Return the `n`-th Hecke operator on the modular abelian variety, if this makes sense [[elaborate]]. Otherwise raise a - ValueError. + :exc:`ValueError`. EXAMPLES: We compute `T_2` on `J_0(37)`. @@ -2660,18 +2618,15 @@ def hecke_operator(self, n): def hecke_polynomial(self, n, var='x'): r""" - Return the characteristic polynomial of the `n^{th}` Hecke - operator `T_n` acting on self. Raises an ArithmeticError - if self is not Hecke equivariant. + Return the characteristic polynomial of the `n`-th Hecke + operator `T_n` acting on ``self``. Raises an :exc:`ArithmeticError` + if ``self`` is not Hecke equivariant. INPUT: + - ``n`` -- integer `\geq 1` - - ``n`` -- integer `\geq 1` - - - ``var`` -- string (default: 'x'); valid variable - name - + - ``var`` -- string (default: ``'x'``); valid variable name EXAMPLES:: @@ -2713,11 +2668,9 @@ def _compute_hecke_polynomial(self, n, var='x'): INPUT: + - ``n`` -- positive integer - - ``n`` -- positive integer - - - ``var`` -- string (default: 'x') - + - ``var`` -- string (default: ``'x'``) EXAMPLES:: @@ -2732,7 +2685,7 @@ def _integral_hecke_matrix(self, n): Return the matrix of the Hecke operator `T_n` acting on the integral homology of this modular abelian variety, if the modular abelian variety is stable under `T_n`. Otherwise, - raise an ArithmeticError. + raise an :exc:`ArithmeticError`. EXAMPLES:: @@ -2753,7 +2706,7 @@ def _rational_hecke_matrix(self, n): Return the matrix of the Hecke operator `T_n` acting on the rational homology `H_1(A,\QQ)` of this modular abelian variety, if this action is defined. Otherwise, raise an - ArithmeticError. + :exc:`ArithmeticError`. EXAMPLES:: @@ -2804,8 +2757,8 @@ def qbar_torsion_subgroup(self): return G def rational_torsion_subgroup(self): - """ - Return the maximal torsion subgroup of self defined over QQ. + r""" + Return the maximal torsion subgroup of ``self`` defined over `\QQ`. EXAMPLES:: @@ -3081,17 +3034,15 @@ def finite_subgroup(self, X, field_of_definition=None, check=True): INPUT: + - ``X`` -- list of elements of other finite subgroups + of this modular abelian variety or elements that coerce into the + rational homology (viewed as a rational vector space); also X could + be a finite subgroup itself that is contained in this abelian + variety. - - ``X`` -- list of elements of other finite subgroups - of this modular abelian variety or elements that coerce into the - rational homology (viewed as a rational vector space); also X could - be a finite subgroup itself that is contained in this abelian - variety. - - - ``field_of_definition`` -- (default: None) field - over which this group is defined. If None try to figure out the - best base field. - + - ``field_of_definition`` -- (default: ``None``) field + over which this group is defined. If ``None`` try to figure out the + best base field. OUTPUT: a finite subgroup of a modular abelian variety @@ -3120,7 +3071,6 @@ def finite_subgroup(self, X, field_of_definition=None, check=True): Finite subgroup with invariants [2, 2] over QQ of Simple abelian subvariety 43a(1,43) of dimension 1 of J0(43) sage: B.finite_subgroup(G) Finite subgroup with invariants [2, 2] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43) - """ if isinstance(X, (list, tuple)): X = self._ambient_lattice().span(X) @@ -3148,10 +3098,9 @@ def finite_subgroup(self, X, field_of_definition=None, check=True): def torsion_subgroup(self, n): """ - If n is an integer, return the subgroup of points of order n. - Return the `n`-torsion subgroup of elements of order - dividing `n` of this modular abelian variety `A`, - i.e., the group `A[n]`. + If `n` is an integer, return the subgroup of points of order `n`. + Return the `n`-torsion subgroup of elements of order dividing `n` of + this modular abelian variety `A`, i.e., the group `A[n]`. EXAMPLES:: @@ -3189,26 +3138,22 @@ def degen_t(self, none_if_not_known=False): """ If this abelian variety is obtained via decomposition then it gets labeled with the newform label along with some information about - degeneracy maps. In particular, the label ends in a pair - `(t,N)`, where `N` is the ambient level and - `t` is an integer that divides the quotient of `N` - by the newform level. This function returns the tuple - `(t,N)`, or raises a :class:`ValueError` if self is not simple. + degeneracy maps. In particular, the label ends in a pair `(t,N)`, where + `N` is the ambient level and `t` is an integer that divides the + quotient of `N` by the newform level. This function returns the tuple + `(t,N)`, or raises a :exc:`ValueError` if ``self`` is not simple. - .. note:: + .. NOTE:: - It need not be the case that self is literally equal to the - image of the newform abelian variety under the `t^{th}` - degeneracy map. See the documentation for the label method - for more details. + It need not be the case that ``self`` is literally equal to the + image of the newform abelian variety under the `t`-th degeneracy + map. See the documentation for the label method for more details. INPUT: - - - ``none_if_not_known`` -- (default: ``False``); if - True, return None instead of attempting to compute the degen map's - `t`, if it isn't known. This None result is not cached. - + - ``none_if_not_known`` -- (default: ``False``) if ``True``, return + ``None`` instead of attempting to compute the degen map's `t`, if it + isn't known. This ``None`` result is not cached. OUTPUT: a pair (integer, integer) @@ -3247,14 +3192,13 @@ def isogeny_number(self, none_if_not_known=False): simple abelian varieties that ``self`` is in. If ``self`` is not simple, - this raises a :class:`ValueError` exception. + this raises a :exc:`ValueError` exception. INPUT: - - ``none_if_not_known`` -- bool (default: ``False``); if - ``True`` then this function may return ``None`` instead of ``True`` - or ``False`` if - we do not already know the isogeny number of ``self``. + - ``none_if_not_known`` -- boolean (default: ``False``); if + ``True`` then this function may return ``None`` instead of ``True`` + or ``False`` if we do not already know the isogeny number of ``self``. EXAMPLES: We test the ``none_if_not_known`` flag first:: @@ -3262,7 +3206,7 @@ def isogeny_number(self, none_if_not_known=False): True Of course, `J_0(33)` is not simple, so this function - raises a :class:`ValueError`:: + raises a :exc:`ValueError`:: sage: J0(33).isogeny_number() Traceback (most recent call last): @@ -3303,11 +3247,9 @@ def is_simple(self, none_if_not_known=False): INPUT: - - - ``none_if_not_known`` -- bool (default: ``False``); if - True then this function may return None instead of True of False if - we don't already know whether or not self is simple. - + - ``none_if_not_known`` -- boolean (default: ``False``); if ``True`` + then this function may return ``None`` instead of ``True`` of + ``False`` if we don't already know whether or not ``self`` is simple. EXAMPLES:: @@ -3332,18 +3274,19 @@ def is_simple(self, none_if_not_known=False): def decomposition(self, simple=True, bound=None): """ - Return a sequence of abelian subvarieties of self that are all - simple, have finite intersection and sum to self. + Return a sequence of abelian subvarieties of ``self`` that are all + simple, have finite intersection and sum to ``self``. - INPUT: simple- bool (default: ``True``) if True, all factors are - simple. If False, each factor returned is isogenous to a power of a - simple and the simples in each factor are distinct. + INPUT: + - ``simple`` -- boolean (default: ``True``); if ``True``, all factors + are simple. If ``False``, each factor returned is isogenous to a + power of a simple and the simples in each factor are distinct. - - ``bound`` -- int (default: None) if given, only use - Hecke operators up to this bound when decomposing. This can give - wrong answers, so use with caution! + - ``bound`` -- integer (default: ``None``); if given, only use + Hecke operators up to this bound when decomposing. This can give + wrong answers, so use with caution! EXAMPLES:: @@ -3523,8 +3466,7 @@ def decomposition(self, simple=True, bound=None): def _classify_ambient_factors(self, simple=True, bound=None): r""" This function implements the following algorithm, which produces - data useful in finding a decomposition or complement of self. - + data useful in finding a decomposition or complement of ``self``. #. Suppose `A_1 + \cdots + A_n` is a simple decomposition of the ambient space. @@ -3533,26 +3475,23 @@ def _classify_ambient_factors(self, simple=True, bound=None): `B_i = A_1 + \cdots + A_i`. #. For each `i`, compute the intersection `C_i` of - `B_i` and self. + `B_i` and ``self``. #. For each `i`, if the dimension of `C_i` is bigger than `C_{i-1}` put `i` in the "in" list; otherwise put `i` in the "out" list. - - Then one can show that self is isogenous to the sum of the + Then one can show that ``self`` is isogenous to the sum of the `A_i` with `i` in the "in" list. Moreover, the sum of the `A_j` with `i` in the "out" list is a - complement of self in the ambient space. + complement of ``self`` in the ambient space. INPUT: + - ``simple`` -- boolean (default: ``True``) - - ``simple`` -- bool (default: ``True``) - - - ``bound`` -- integer (default: None); if given, - passed onto decomposition function - + - ``bound`` -- integer (default: ``None``); if given, + passed onto decomposition function OUTPUT: IN list OUT list simple (or power of simple) factors @@ -3699,11 +3638,10 @@ def complement(self, A=None): INPUT: - - ``A`` -- (default: None); if given, A must be an - abelian variety that contains self, in which case the complement of - self is taken inside A. Otherwise the complement is taken in the - ambient product Jacobian. - + - ``A`` -- (default: ``None``) if given, ``A`` must be an + abelian variety that contains ``self``, in which case the complement of + ``self`` is taken inside ``A``. Otherwise the complement is taken in the + ambient product Jacobian. OUTPUT: abelian variety @@ -3749,14 +3687,14 @@ def dual(self): OUTPUT: - dual abelian variety - - morphism from self to dual + - morphism from ``self`` to dual - covering morphism from J to dual .. warning:: - This is currently only implemented when self is an abelian + This is currently only implemented when ``self`` is an abelian subvariety of the ambient Jacobian product, and the - complement of self in the ambient product Jacobian share no + complement of ``self`` in the ambient product Jacobian share no common factors. A more general implementation will require implementing computation of the intersection pairing on integral homology and the resulting Weil pairing on @@ -3822,16 +3760,14 @@ def dual(self): def _factors_with_same_label(self, other): """ - Given two modular abelian varieties self and other, this function + Given two modular abelian varieties ``self`` and ``other``, this function returns a list of simple abelian subvarieties appearing in the - decomposition of self that have the same newform labels. Each + decomposition of ``self`` that have the same newform labels. Each simple factor with a given newform label appears at most one. INPUT: - - - ``other`` -- abelian variety - + - ``other`` -- abelian variety OUTPUT: list of simple abelian varieties @@ -3887,8 +3823,8 @@ def _factors_with_same_label(self, other): def _complement_shares_no_factors_with_same_label(self): """ - Return True if no simple factor of self has the same newform_label - as any factor in a Poincaré complement of self in the ambient + Return ``True`` if no simple factor of ``self`` has the same newform_label + as any factor in a Poincaré complement of ``self`` in the ambient product Jacobian. EXAMPLES: `J_0(37)` is made up of two non-isogenous @@ -3950,8 +3886,8 @@ def _complement_shares_no_factors_with_same_label(self): def __getitem__(self, i): """ - Return the `i^{th}` decomposition factor of self - or return the slice `i` of decompositions of self. + Return the `i`-th decomposition factor of self + or return the slice `i` of decompositions of ``self``. EXAMPLES:: @@ -3991,17 +3927,13 @@ def __init__(self, groups, lattice=None, base_field=QQ, is_simple=None, newform_ INPUT: + - ``groups`` -- tuple of congruence subgroups - - ``groups`` -- a tuple of congruence subgroups - - - ``lattice`` -- (default: `\ZZ^n`) a - full lattice in `\ZZ^n`, where `n` is the - sum of the dimensions of the spaces of cuspidal modular symbols - corresponding to each `\Gamma \in` groups - - - ``base_field`` -- a field (default: - `\QQ`) + - ``lattice`` -- (default: `\ZZ^n`) a full lattice in `\ZZ^n`, where + `n` is the sum of the dimensions of the spaces of cuspidal modular + symbols corresponding to each `\Gamma \in` groups + - ``base_field`` -- a field (default: `\QQ`) EXAMPLES:: @@ -4030,10 +3962,8 @@ def lattice(self): OUTPUT: - - - ``lattice`` -- a lattice embedded in the rational - homology of the ambient product Jacobian - + - ``lattice`` -- a lattice embedded in the rational + homology of the ambient product Jacobian EXAMPLES:: @@ -4179,9 +4109,7 @@ def _set_lattice(self, lattice): INPUT: - - - ``lattice`` -- a lattice - + - ``lattice`` -- a lattice EXAMPLES: We do something evil - there's no type checking since this function is for internal use only:: @@ -4197,7 +4125,7 @@ def modular_symbols(self, sign=0): """ Return space of modular symbols (with given sign) associated to this modular abelian variety, if it can be found by cutting down - using Hecke operators. Otherwise raise a :class:`RuntimeError` + using Hecke operators. Otherwise raise a :exc:`RuntimeError` exception. EXAMPLES:: @@ -4247,15 +4175,15 @@ def modular_symbols(self, sign=0): def _compute_hecke_polynomial(self, n, var='x'): r""" - Return the characteristic polynomial of the `n^{th}` Hecke + Return the characteristic polynomial of the `n`-th Hecke operator on ``self``. - .. note:: + .. NOTE:: - If self has dimension d, then this is a polynomial of - degree d. It is not of degree 2\*d, so it is the square + If ``self`` has dimension `d`, then this is a polynomial of + degree `d`. It is not of degree `2d`, so it is the square root of the characteristic polynomial of the Hecke operator - on integral or rational homology (which has degree 2\*d). + on integral or rational homology (which has degree `2d`). EXAMPLES:: @@ -4280,16 +4208,14 @@ def _compute_hecke_polynomial(self, n, var='x'): def _integral_hecke_matrix(self, n, sign=0): """ Return the action of the Hecke operator `T_n` on the - integral homology of self. + integral homology of ``self``. INPUT: + - ``n`` -- positive integer - - ``n`` -- a positive integer - - - ``sign`` -- 0, +1, or -1; if 1 or -1 act on the +1 or - -1 quotient of the integral homology. - + - ``sign`` -- 0, +1, or -1; if 1 or -1 act on the +1 or + -1 quotient of the integral homology EXAMPLES:: @@ -4310,16 +4236,14 @@ def _integral_hecke_matrix(self, n, sign=0): def _rational_hecke_matrix(self, n, sign=0): """ Return the action of the Hecke operator `T_n` on the - rational homology of self. + rational homology of ``self``. INPUT: + - ``n`` -- positive integer - - ``n`` -- a positive integer - - - ``sign`` -- 0, +1, or -1; if 1 or -1 act on the +1 or - -1 quotient of the rational homology. - + - ``sign`` -- 0, +1, or -1; if 1 or -1 act on the +1 or + -1 quotient of the rational homology EXAMPLES:: @@ -4355,7 +4279,7 @@ def group(self): def is_subvariety(self, other): """ - Return True if self is a subvariety of other. + Return ``True`` if ``self`` is a subvariety of ``other``. EXAMPLES:: @@ -4410,11 +4334,11 @@ def is_subvariety(self, other): def is_ambient(self): """ - Return True if this abelian variety attached to a modular symbols + Return ``True`` if this abelian variety attached to a modular symbols space is attached to the cuspidal subspace of the ambient modular symbols space. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -4457,17 +4381,15 @@ def dimension(self): def new_subvariety(self, p=None): """ - Return the new or `p`-new subvariety of self. + Return the new or `p`-new subvariety of ``self``. INPUT: + - ``self`` -- a modular abelian variety - - ``self`` -- a modular abelian variety - - - ``p`` -- prime number or None (default); if p is a - prime, return the p-new subvariety. Otherwise return the full new - subvariety. - + - ``p`` -- prime number or None (default); if `p` is a + prime, return the `p`-new subvariety. Otherwise return the full new + subvariety. EXAMPLES:: @@ -4492,17 +4414,15 @@ def new_subvariety(self, p=None): def old_subvariety(self, p=None): """ - Return the old or `p`-old abelian variety of self. + Return the old or `p`-old abelian variety of ``self``. INPUT: + - ``self`` -- a modular abelian variety - - ``self`` -- a modular abelian variety - - - ``p`` -- prime number or None (default); if p is a - prime, return the p-old subvariety. Otherwise return the full old - subvariety. - + - ``p`` -- prime number or ``None`` (default); if `p` is a + prime, return the `p`-old subvariety. Otherwise return the full old + subvariety. EXAMPLES:: @@ -4530,15 +4450,16 @@ def decomposition(self, simple=True, bound=None): Decompose this modular abelian variety as a product of abelian subvarieties, up to isogeny. - INPUT: simple- bool (default: ``True``) if True, all factors are - simple. If False, each factor returned is isogenous to a power of a - simple and the simples in each factor are distinct. + INPUT: + - ``simple`` -- boolean (default: ``True``); if ``True``, all factors + are simple. If ``False``, each factor returned is isogenous to a + power of a simple and the simples in each factor are distinct. - - ``bound`` -- int (default: None) if given, only use - Hecke operators up to this bound when decomposing. This can give - wrong answers, so use with caution! + - ``bound`` -- integer (default: ``None``); if given, only use + Hecke operators up to this bound when decomposing. This can give + wrong answers, so use with caution! EXAMPLES:: @@ -4647,14 +4568,18 @@ def _modular_symbols(self): return self.__modsym def component_group_order(self, p): - """ + r""" Return the order of the component group of the special fiber - at p of the Neron model of self. + at `p` of the Neron model of ``self``. - NOTE: For bad primes, this is only implemented when the group - if Gamma0 and p exactly divides the level. + .. NOTE:: - NOTE: the input abelian variety must be simple + For bad primes, this is only implemented when the group + is `\Gamma_0` and `p` exactly divides the level. + + .. NOTE:: + + The input abelian variety must be simple. ALGORITHM: See "Component Groups of Quotients of J0(N)" by Kohel and Stein. That paper is about optimal quotients; however, section 4.1 of Conrad-Stein "Component @@ -4663,11 +4588,9 @@ def component_group_order(self, p): INPUT: - - p -- a prime number + - ``p`` -- a prime number - OUTPUT: - - - Integer + OUTPUT: integer EXAMPLES:: @@ -4766,11 +4689,9 @@ def _invariants_of_image_of_component_group_of_J0(self, p): INPUT: - - p -- integer + - ``p`` -- integer - OUTPUT: - - - list -- of elementary invariants + OUTPUT: list of elementary invariants EXAMPLES:: @@ -4801,11 +4722,9 @@ def tamagawa_number(self, p): INPUT: - - p -- a prime number - - OUTPUT: + - ``p`` -- a prime number - - Integer + OUTPUT: integer EXAMPLES:: @@ -4843,19 +4762,19 @@ def tamagawa_number(self, p): def tamagawa_number_bounds(self, p): """ - Return a divisor and multiple of the Tamagawa number of self at `p`. + Return a divisor and multiple of the Tamagawa number of ``self`` at `p`. NOTE: the input abelian variety must be simple. INPUT: - - `p` -- a prime number + - ``p`` -- a prime number OUTPUT: - - div -- integer; divisor of Tamagawa number at `p` - - mul -- integer; multiple of Tamagawa number at `p` - - mul_primes -- tuple; in case mul==0, a list of all + - ``div`` -- integer; divisor of Tamagawa number at `p` + - ``mul`` -- integer; multiple of Tamagawa number at `p` + - ``mul_primes`` -- tuple; in case ``mul==0``, a list of all primes that can possibly divide the Tamagawa number at `p` EXAMPLES:: @@ -4913,18 +4832,16 @@ def tamagawa_number_bounds(self, p): def brandt_module(self, p): """ - Return the Brandt module at p that corresponds to self. This + Return the Brandt module at p that corresponds to ``self``. This is the factor of the vector space on the ideal class set in an - order of level N in the quaternion algebra ramified at p and + order of level `N` in the quaternion algebra ramified at `p` and infinity. INPUT: - - p -- prime that exactly divides the level - - OUTPUT: + - ``p`` -- prime that exactly divides the level - - Brandt module space that corresponds to self. + OUTPUT: Brandt module space that corresponds to self EXAMPLES:: @@ -4985,7 +4902,7 @@ def sqrt_poly(f): """ Return the square root of the polynomial `f`. - .. note:: + .. NOTE:: At some point something like this should be a member of the polynomial class. For now this is just used internally by some @@ -5027,13 +4944,11 @@ def random_hecke_operator(M, t=None, p=2): INPUT: + - ``M`` -- modular symbols space - - ``M`` -- modular symbols space - - - ``t`` -- None or a Hecke operator - - - ``p`` -- a prime + - ``t`` -- ``None`` or a Hecke operator + - ``p`` -- a prime OUTPUT: Hecke operator prime @@ -5062,9 +4977,7 @@ def factor_new_space(M): INPUT: - - - ``M`` -- modular symbols space - + - ``M`` -- modular symbols space OUTPUT: list of factors @@ -5101,7 +5014,7 @@ def factor_modsym_space_new_factors(M): - ``M`` -- ambient modular symbols space - OUTPUT: list of decompositions corresponding to each new space. + OUTPUT: list of decompositions corresponding to each new space EXAMPLES:: @@ -5202,12 +5115,9 @@ def modsym_lattices(M, factors): INPUT: + - ``M`` -- modular symbols spaces - - ``M`` -- modular symbols spaces - - - ``factors`` -- Sequence - (simple_factorization_of_modsym_space) - + - ``factors`` -- sequence (simple_factorization_of_modsym_space) OUTPUT: sequence with more information for each factor (the lattice) diff --git a/src/sage/modular/abvar/abvar_ambient_jacobian.py b/src/sage/modular/abvar/abvar_ambient_jacobian.py index 115408441fd..1a7c1e82370 100644 --- a/src/sage/modular/abvar/abvar_ambient_jacobian.py +++ b/src/sage/modular/abvar/abvar_ambient_jacobian.py @@ -20,7 +20,7 @@ from sage.modular.modsym.modsym import ModularSymbols from sage.modular.modform.constructor import Newforms from sage.modular.arithgroup.all import Gamma0_class, Gamma1_class -from . import morphism +from sage.modular.abvar import morphism _cache = {} @@ -36,9 +36,7 @@ def ModAbVar_ambient_jacobian(group): INPUT: - - - ``group`` -- a congruence subgroup. - + - ``group`` -- a congruence subgroup OUTPUT: a modular abelian variety attached @@ -123,7 +121,7 @@ def _repr_(self): Abelian variety J0(11) of dimension 1 sage: A._repr_() 'Abelian variety J0(11) of dimension 1' - sage: A.rename("J_0(11)") + sage: A.rename('J_0(11)') sage: A J_0(11) @@ -156,9 +154,9 @@ def _latex_(self): def ambient_variety(self): """ - Return the ambient modular abelian variety that contains self. - Since self is a Jacobian modular abelian variety, this is just - self. + Return the ambient modular abelian variety that contains ``self``. + Since ``self`` is a Jacobian modular abelian variety, this is just + ``self``. OUTPUT: abelian variety @@ -206,7 +204,7 @@ def groups(self): def _calculate_endomorphism_generators(self): """ - Calculate generators for the endomorphism ring of self. + Calculate generators for the endomorphism ring of ``self``. EXAMPLES:: @@ -250,21 +248,20 @@ def _calculate_endomorphism_generators(self): def degeneracy_map(self, level, t=1, check=True): """ - Return the t-th degeneracy map from self to J(level). Here t must - be a divisor of either level/self.level() or self.level()/level. + Return the `t`-th degeneracy map from ``self`` to ``J(level)``. Here + `t` must be a divisor of either ``level/self.level()`` or + ``self.level()/level``. INPUT: + - ``level`` -- integer (multiple or divisor of level of + ``self``) - - ``level`` -- integer (multiple or divisor of level of - self) - - - ``t`` -- divisor of quotient of level of self and - level - - - ``check`` -- bool (default: ``True``); if True do some - checks on the input + - ``t`` -- divisor of quotient of level of ``self`` and + level + - ``check`` -- boolean (default: ``True``); if ``True`` do some + checks on the input OUTPUT: a morphism @@ -396,11 +393,9 @@ def decomposition(self, simple=True, bound=None): def newform_decomposition(self, names=None): """ Return the newforms of the simple subvarieties in the decomposition of - self as a product of simple subvarieties, up to isogeny. - - OUTPUT: + ``self`` as a product of simple subvarieties, up to isogeny. - - an array of newforms + OUTPUT: an array of newforms EXAMPLES:: diff --git a/src/sage/modular/abvar/abvar_newform.py b/src/sage/modular/abvar/abvar_newform.py index 8997ab01fdf..9568e5481cc 100644 --- a/src/sage/modular/abvar/abvar_newform.py +++ b/src/sage/modular/abvar/abvar_newform.py @@ -22,7 +22,7 @@ from sage.modular.arithgroup.all import Gamma0_class, Gamma1_class, GammaH_class from .abvar import ModularAbelianVariety_modsym_abstract -from . import homspace +from sage.modular.abvar import homspace lazy_import('sage.databases.cremona', 'cremona_letter_code') @@ -36,7 +36,8 @@ def __init__(self, f, internal_name=False): newform `f`. INPUT: - f -- a newform + + - ``f`` -- a newform EXAMPLES:: @@ -123,9 +124,7 @@ def label(self) -> str: Return canonical label that defines this newform modular abelian variety. - OUTPUT: - - string + OUTPUT: string EXAMPLES:: @@ -146,9 +145,7 @@ def factor_number(self): """ Return factor number. - OUTPUT: - - int + OUTPUT: int EXAMPLES:: diff --git a/src/sage/modular/abvar/constructor.py b/src/sage/modular/abvar/constructor.py index e4ba65049e4..53561063eaa 100644 --- a/src/sage/modular/abvar/constructor.py +++ b/src/sage/modular/abvar/constructor.py @@ -19,20 +19,19 @@ from sage.modular.modsym.space import ModularSymbolsSpace from .abvar_newform import ModularAbelianVariety_newform import sage.modular.modform.element -from . import abvar +from sage.modular.abvar import abvar _cache = {} + def _get(key): """ - Returns the cached abelian variety with given key. This is used + Return the cached abelian variety with given key. This is used internally by the abelian varieties constructor. INPUT: - - - ``key`` -- hashable - + - ``key`` -- hashable EXAMPLES:: @@ -51,25 +50,20 @@ def _get(key): return z raise ValueError("element not in cache") + def _saved(key, J): """ - Returns the cached abelian variety with given key. This is used + Return the cached abelian variety with given key. This is used internally by the abelian varieties constructor. INPUT: + - ``key`` -- hashable - - ``key`` -- hashable - - - ``J`` -- modular abelian variety - - - OUTPUT: - - - - ``J`` -- returns the modabvar, to make code that uses - this simpler + - ``J`` -- modular abelian variety + OUTPUT: ``J`` -- returns the modabvar, to make code that uses + this simpler EXAMPLES:: @@ -103,6 +97,7 @@ def J0(N): J = Gamma0(N).modular_abelian_variety() return _saved(key, J) + def J1(N): """ Return the Jacobian `J_1(N)` of the modular curve @@ -120,6 +115,7 @@ def J1(N): from sage.modular.arithgroup.all import Gamma1 return _saved(key, Gamma1(N).modular_abelian_variety()) + def JH(N, H): """ Return the Jacobian `J_H(N)` of the modular curve @@ -137,6 +133,7 @@ def JH(N, H): from sage.modular.arithgroup.all import GammaH return _saved(key, GammaH(N, H).modular_abelian_variety()) + def AbelianVariety(X): """ Create the abelian variety corresponding to the given defining @@ -144,10 +141,8 @@ def AbelianVariety(X): INPUT: - - - ``X`` -- an integer, string, newform, modsym space, - congruence subgroup or tuple of congruence subgroups - + - ``X`` -- integer, string, newform, modsym space, + congruence subgroup or tuple of congruence subgroups OUTPUT: a modular abelian variety diff --git a/src/sage/modular/abvar/cuspidal_subgroup.py b/src/sage/modular/abvar/cuspidal_subgroup.py index 1df78b66f66..7a0921076d9 100644 --- a/src/sage/modular/abvar/cuspidal_subgroup.py +++ b/src/sage/modular/abvar/cuspidal_subgroup.py @@ -59,24 +59,24 @@ True """ -#***************************************************************************** +# ***************************************************************************** # Copyright (C) 2007 William Stein # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** -from sage.matrix.constructor import matrix -from sage.modular.arithgroup.all import Gamma0_class -from sage.modular.cusps import Cusp -from sage.rings.infinity import infinity -from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ +from sage.matrix.constructor import matrix +from sage.modular.arithgroup.all import Gamma0_class +from sage.modular.cusps import Cusp +from sage.rings.infinity import infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ -from .finite_subgroup import FiniteSubgroup +from .finite_subgroup import FiniteSubgroup class CuspidalSubgroup_generic(FiniteSubgroup): @@ -87,16 +87,10 @@ def _compute_lattice(self, rational_only=False, rational_subgroup=False): INPUT: + - ``rational_only`` -- boolean (default: ``False``); if + ``True``, only use rational cusps - - ``rational_only`` -- bool (default: ``False``); if - ``True``, only use rational cusps. - - - OUTPUT: - - - - ``list`` -- list of vectors - + OUTPUT: list of vectors EXAMPLES:: @@ -216,9 +210,7 @@ def lattice(self): Returned cached tuple of vectors that define elements of the rational homology that generate this finite subgroup. - OUTPUT: - - - ``tuple`` -- cached + OUTPUT: tuple (cached) EXAMPLES:: @@ -347,21 +339,18 @@ def lattice(self): def is_rational_cusp_gamma0(c, N, data): """ - Return True if the rational number c is a rational cusp of level N. + Return ``True`` if the rational number c is a rational cusp of level N. This uses remarks in Glenn Steven's Ph.D. thesis. INPUT: + - ``c`` -- a cusp - - ``c`` -- a cusp - - - ``N`` -- a positive integer - - - ``data`` -- the list [n for n in range(2,N) if - gcd(n,N) == 1], which is passed in as a parameter purely for - efficiency reasons. + - ``N`` -- positive integer + - ``data`` -- the list [n for n in range(2,N) if gcd(n,N) == 1], which is + passed in as a parameter purely for efficiency reasons. EXAMPLES:: diff --git a/src/sage/modular/abvar/finite_subgroup.py b/src/sage/modular/abvar/finite_subgroup.py index 0adc5ce3134..cfaf762eae2 100644 --- a/src/sage/modular/abvar/finite_subgroup.py +++ b/src/sage/modular/abvar/finite_subgroup.py @@ -88,15 +88,15 @@ True """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.rings.abc @@ -328,7 +328,7 @@ def exponent(self): """ Return the exponent of this finite abelian group. - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -352,9 +352,7 @@ def intersection(self, other): INPUT: - - - ``other`` -- a finite group - + - ``other`` -- a finite group OUTPUT: a finite group @@ -440,17 +438,15 @@ def intersection(self, other): def __mul__(self, right): """ - Multiply this subgroup by the rational number right. + Multiply this subgroup by the rational number ``right``. - If right is an integer the result is a subgroup of self. If right - is a rational number `n/m`, then this group is first + If ``right`` is an integer the result is a subgroup of ``self``. If + ``right`` is a rational number `n/m`, then this group is first divided by `m` then multiplied by `n`. INPUT: - - - ``right`` -- a rational number - + - ``right`` -- a rational number OUTPUT: a subgroup @@ -611,7 +607,7 @@ def gens(self): def gen(self, n): r""" - Return `n^{th}` generator of self. + Return `n`-th generator of ``self``. EXAMPLES:: @@ -687,7 +683,6 @@ def _element_constructor_(self, x, check=True): Traceback (most recent call last): ... ValueError: ambient abelian varieties are different - """ if isinstance(x, TorsionPoint): if x.parent().abelian_variety() != self.abelian_variety(): @@ -847,18 +842,15 @@ def __init__(self, abvar, lattice, field_of_definition=None, check=True): INPUT: + - ``abvar`` -- a modular abelian variety - - ``abvar`` -- a modular abelian variety - - - ``lattice`` -- a lattice that contains the lattice of - abvar - - - ``field_of_definition`` -- the field of definition - of this finite group scheme + - ``lattice`` -- a lattice that contains the lattice of abvar - - ``check`` -- bool (default: ``True``) whether or not to - check that lattice contains the abvar lattice. + - ``field_of_definition`` -- the field of definition + of this finite group scheme + - ``check`` -- boolean (default: ``True``); whether or not to + check that lattice contains the abvar lattice EXAMPLES:: diff --git a/src/sage/modular/abvar/homology.py b/src/sage/modular/abvar/homology.py index 6a2b906fd1e..21a129072fa 100644 --- a/src/sage/modular/abvar/homology.py +++ b/src/sage/modular/abvar/homology.py @@ -69,16 +69,16 @@ class Homology(HeckeModule_free_module): action. """ def hecke_polynomial(self, n, var='x'): - """ - Return the n-th Hecke polynomial in the given variable. + r""" + Return the `n`-th Hecke polynomial in the given variable. INPUT: - - ``n`` -- positive integer + - ``n`` -- positive integer - - ``var`` -- string (default: 'x') the variable name + - ``var`` -- string (default: ``'x'``); the variable name - OUTPUT: a polynomial over ZZ in the given variable + OUTPUT: a polynomial over `\ZZ` in the given variable EXAMPLES:: @@ -142,7 +142,7 @@ def __richcmp__(self, other, op): def _repr_(self): """ - Return string representation of self. This must be defined in the + Return string representation of ``self``. This must be defined in the derived class. EXAMPLES:: @@ -158,7 +158,7 @@ def _repr_(self): def gens(self): """ - Return generators of self. + Return generators of ``self``. This is not yet implemented! @@ -174,7 +174,7 @@ def gens(self): def gen(self, n): """ - Return `n^{th}` generator of self. + Return `n`-th generator of ``self``. This is not yet implemented! @@ -248,14 +248,12 @@ def hecke_bound(self): def hecke_matrix(self, n): """ - Return the matrix of the n-th Hecke operator acting on this + Return the matrix of the `n`-th Hecke operator acting on this homology group. INPUT: - - - ``n`` -- a positive integer - + - ``n`` -- positive integer OUTPUT: a matrix over the coefficient ring of this homology group @@ -299,14 +297,13 @@ def submodule(self, U, check=True): INPUT: + - ``U`` -- submodule of ambient free module (or + something that defines one) - - ``U`` -- submodule of ambient free module (or - something that defines one) + - ``check`` -- currently ignored - - ``check`` -- currently ignored. - - .. note:: + .. NOTE:: We do *not* check that U is invariant under all Hecke operators. @@ -347,9 +344,7 @@ def __init__(self, abvar): INPUT: - - - ``abvar`` -- a modular abelian variety - + - ``abvar`` -- a modular abelian variety EXAMPLES:: @@ -378,7 +373,7 @@ def _repr_(self): def hecke_matrix(self, n): """ - Return the matrix of the n-th Hecke operator acting on this + Return the matrix of the `n`-th Hecke operator acting on this homology group. EXAMPLES:: @@ -398,7 +393,7 @@ def hecke_matrix(self, n): def hecke_polynomial(self, n, var='x'): """ - Return the n-th Hecke polynomial on this integral homology group. + Return the `n`-th Hecke polynomial on this integral homology group. EXAMPLES:: @@ -425,9 +420,7 @@ def __init__(self, abvar): INPUT: - - - ``abvar`` -- a modular abelian variety - + - ``abvar`` -- a modular abelian variety EXAMPLES:: @@ -454,7 +447,7 @@ def _repr_(self): def hecke_matrix(self, n): """ - Return the matrix of the n-th Hecke operator acting on this + Return the matrix of the `n`-th Hecke operator acting on this homology group. EXAMPLES:: @@ -479,7 +472,7 @@ def hecke_matrix(self, n): def hecke_polynomial(self, n, var='x'): """ - Return the n-th Hecke polynomial on this rational homology group. + Return the `n`-th Hecke polynomial on this rational homology group. EXAMPLES:: @@ -506,11 +499,9 @@ def __init__(self, abvar, base_ring): INPUT: + - ``abvar`` -- a modular abelian variety - - ``abvar`` -- a modular abelian variety - - - ``base_ring`` -- a commutative ring - + - ``base_ring`` -- a commutative ring EXAMPLES:: @@ -528,7 +519,7 @@ def __init__(self, abvar, base_ring): def _repr_(self): """ - Return string representation of self. + Return string representation of ``self``. EXAMPLES:: @@ -540,7 +531,7 @@ def _repr_(self): def hecke_matrix(self, n): """ - Return the matrix of the n-th Hecke operator acting on this + Return the matrix of the `n`-th Hecke operator acting on this homology group. EXAMPLES:: @@ -567,13 +558,11 @@ def __init__(self, ambient, submodule): INPUT: + - ``ambient`` -- the homology of some modular abelian + variety with ring coefficients - - ``ambient`` -- the homology of some modular abelian - variety with ring coefficients - - - ``submodule`` -- a submodule of the free module - underlying ambient - + - ``submodule`` -- a submodule of the free module + underlying ambient EXAMPLES:: diff --git a/src/sage/modular/abvar/homspace.py b/src/sage/modular/abvar/homspace.py index 8b97e675be5..30ad76f3601 100644 --- a/src/sage/modular/abvar/homspace.py +++ b/src/sage/modular/abvar/homspace.py @@ -187,7 +187,7 @@ from sage.misc.lazy_attribute import lazy_attribute -from . import morphism +from sage.modular.abvar import morphism from sage.rings.infinity import Infinity @@ -210,11 +210,9 @@ def __init__(self, domain, codomain, cat): INPUT: + - ``domain, codomain`` -- modular abelian varieties - - ``domain, codomain`` -- modular abelian varieties - - - ``cat`` -- category - + - ``cat`` -- category EXAMPLES:: @@ -409,10 +407,7 @@ def _get_matrix(self, g): INPUT: - - - ``g`` -- a matrix or morphism or object with a list - method - + - ``g`` -- a matrix or morphism or object with a list method OUTPUT: a matrix @@ -482,11 +477,11 @@ def free_module(self): def gen(self, i=0): """ - Return i-th generator of ``self``. + Return `i`-th generator of ``self``. INPUT: - - ``i`` -- an integer + - ``i`` -- integer OUTPUT: a morphism @@ -588,8 +583,8 @@ def _calculate_product_gens(self): """ For internal use. - Calculate generators for self, assuming that self is a product of - simple factors. + Calculate generators for ``self``, assuming that ``self`` is a product + of simple factors. EXAMPLES:: @@ -759,10 +754,10 @@ def __init__(self, A, gens=None, category=None): INPUT: - - ``A`` -- an abelian variety + - ``A`` -- an abelian variety - - ``gens`` -- (default: ``None``); optional; if given - should be a tuple of the generators as matrices + - ``gens`` -- (default: ``None``) if given + should be a tuple of the generators as matrices EXAMPLES:: @@ -854,11 +849,11 @@ def index_in(self, other, check=True): INPUT: - - ``other`` -- another endomorphism subring of the - same abelian variety + - ``other`` -- another endomorphism subring of the + same abelian variety - - ``check`` -- bool (default: ``True``); whether to do some - type and other consistency checks + - ``check`` -- boolean (default: ``True``); whether to do some + type and other consistency checks EXAMPLES:: @@ -907,7 +902,7 @@ def discriminant(self): Return the discriminant of this ring, which is the discriminant of the trace pairing. - .. note:: + .. NOTE:: One knows that for modular abelian varieties, the endomorphism ring should be isomorphic to an order in a @@ -947,14 +942,12 @@ def image_of_hecke_algebra(self, check_every=1): INPUT: - - ``check_every`` -- integer (default: 1) If this integer is positive, + - ``check_every`` -- integer (default: 1); if this integer is positive, this integer determines how many Hecke operators we add in before checking to see if the submodule spanned so far is maximal and - saturated. - - OUTPUT: + saturated - - The image of the Hecke algebra as a subring of ``self``. + OUTPUT: the image of the Hecke algebra as a subring of ``self`` EXAMPLES:: diff --git a/src/sage/modular/abvar/lseries.py b/src/sage/modular/abvar/lseries.py index 4d67f7b2dfd..e71e58bbcde 100644 --- a/src/sage/modular/abvar/lseries.py +++ b/src/sage/modular/abvar/lseries.py @@ -41,7 +41,7 @@ class Lseries(SageObject): """ def __init__(self, abvar): """ - Called when creating an L-series. + Called when creating an `L`-series. INPUT: @@ -60,9 +60,7 @@ def abelian_variety(self): """ Return the abelian variety that this `L`-series is attached to. - OUTPUT: - - a modular abelian variety + OUTPUT: a modular abelian variety EXAMPLES:: @@ -90,12 +88,10 @@ def __call__(self, s, prec=53): - ``s`` -- complex number - - ``prec`` -- integer (default: 53) the number of bits of precision - used in computing the lseries of the newforms. - - OUTPUT: + - ``prec`` -- integer (default: 53); the number of bits of precision + used in computing the lseries of the newforms - a complex number L(A, s). + OUTPUT: a complex number L(A, s) EXAMPLES:: @@ -124,7 +120,6 @@ def __call__(self, s, prec=53): sage: L = JH(17,[2]).lseries() sage: L(1) # needs sage.symbolic 0.386769938387780 - """ abelian_variety = self.abelian_variety() # Check for easy dimension zero case @@ -155,9 +150,7 @@ def __eq__(self, other): - ``other`` -- object - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -180,9 +173,7 @@ def __ne__(self, other): - ``other`` -- object - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -199,9 +190,7 @@ def _repr_(self): """ String representation of `L`-series. - OUTPUT: - - a string + OUTPUT: string EXAMPLES:: @@ -213,11 +202,9 @@ def _repr_(self): def vanishes_at_1(self): """ - Return True if `L(1)=0` and return False otherwise. + Return ``True`` if `L(1)=0` and return ``False`` otherwise. - OUTPUT: - - a boolean + OUTPUT: boolean EXAMPLES: @@ -272,9 +259,7 @@ def rational_part(self): Return the rational part of this `L`-function at the central critical value 1. - OUTPUT: - - a rational number + OUTPUT: a rational number EXAMPLES:: @@ -335,11 +320,9 @@ def __eq__(self, other): INPUT: - other -- object - - OUTPUT: + - ``other`` -- object - boolean + OUTPUT: boolean EXAMPLES:: @@ -364,11 +347,9 @@ def __ne__(self, other): INPUT: - other -- object - - OUTPUT: + - ``other`` -- object - boolean + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/modular/abvar/morphism.py b/src/sage/modular/abvar/morphism.py index 3b3db9e30c8..ccf87e302e7 100644 --- a/src/sage/modular/abvar/morphism.py +++ b/src/sage/modular/abvar/morphism.py @@ -90,7 +90,7 @@ def _repr_type(self): def complementary_isogeny(self): """ - Returns the complementary isogeny of self. + Return the complementary isogeny of ``self``. EXAMPLES:: @@ -119,7 +119,7 @@ def complementary_isogeny(self): def is_isogeny(self): """ - Return True if this morphism is an isogeny of abelian varieties. + Return ``True`` if this morphism is an isogeny of abelian varieties. EXAMPLES:: @@ -135,16 +135,14 @@ def is_isogeny(self): def cokernel(self): """ - Return the cokernel of self. + Return the cokernel of ``self``. OUTPUT: + - ``A`` -- an abelian variety (the cokernel) - - ``A`` -- an abelian variety (the cokernel) - - - ``phi`` -- a quotient map from self.codomain() to the - cokernel of self - + - ``phi`` -- a quotient map from ``self.codomain()`` to the + cokernel of self EXAMPLES:: @@ -192,12 +190,9 @@ def kernel(self): OUTPUT: + - ``G`` -- a finite group - - ``G`` -- a finite group - - - ``A`` -- an abelian variety (identity component of - the kernel) - + - ``A`` -- an abelian variety (identity component of the kernel) EXAMPLES: We compute the kernel of a projection map. Notice that the kernel has a nontrivial abelian variety part. @@ -249,7 +244,7 @@ def kernel(self): def factor_out_component_group(self): r""" - View self as a morphism `f:A \to B`. Then `\ker(f)` + View ``self`` as a morphism `f:A \to B`. Then `\ker(f)` is an extension of an abelian variety `C` by a finite component group `G`. This function constructs a morphism `g` with domain `A` and codomain Q isogenous to @@ -368,10 +363,7 @@ def __call__(self, X): """ INPUT: - - - ``X`` -- abelian variety, finite group, or torsion - element - + - ``X`` -- abelian variety, finite group, or torsion element OUTPUT: abelian variety, finite group, torsion element @@ -467,9 +459,7 @@ def _image_of_element(self, x): INPUT: - - - ``x`` -- a torsion point on an abelian variety - + - ``x`` -- a torsion point on an abelian variety OUTPUT: a torsion point @@ -518,9 +508,7 @@ def _image_of_finite_subgroup(self, G): - ``G`` -- a finite subgroup of the domain of ``self`` - OUTPUT: - - A finite subgroup of the codomain. + OUTPUT: a finite subgroup of the codomain EXAMPLES:: @@ -555,9 +543,7 @@ def _image_of_abvar(self, A): INPUT: - - - ``A`` -- an abelian variety - + - ``A`` -- an abelian variety OUTPUT an abelian variety @@ -615,7 +601,7 @@ class Morphism(Morphism_abstract, sage.modules.matrix_morphism.MatrixMorphism): def restrict_domain(self, sub): """ - Restrict self to the subvariety sub of self.domain(). + Restrict ``self`` to the subvariety sub of ``self.domain()``. EXAMPLES:: @@ -661,22 +647,18 @@ def restrict_domain(self, sub): class DegeneracyMap(Morphism): - def __init__(self, parent, A, t, side="left"): + def __init__(self, parent, A, t, side='left'): """ Create the degeneracy map of index t in parent defined by the matrix A. INPUT: + - ``parent`` -- a space of homomorphisms of abelian varieties - - ``parent`` -- a space of homomorphisms of abelian - varieties - - - ``A`` -- a matrix defining self - - - ``t`` -- a list of indices defining the degeneracy - map + - ``A`` -- a matrix defining self + - ``t`` -- list of indices defining the degeneracy map EXAMPLES:: @@ -692,7 +674,7 @@ def __init__(self, parent, A, t, side="left"): def t(self): """ - Return the list of indices defining self. + Return the list of indices defining ``self``. EXAMPLES:: @@ -708,7 +690,7 @@ def t(self): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -722,18 +704,16 @@ class HeckeOperator(Morphism): """ A Hecke operator acting on a modular abelian variety. """ - def __init__(self, abvar, n, side="left"): + def __init__(self, abvar, n, side='left'): """ Create the Hecke operator of index `n` acting on the abelian variety abvar. INPUT: + - ``abvar`` -- a modular abelian variety - - ``abvar`` -- a modular abelian variety - - - ``n`` -- a positive integer - + - ``n`` -- positive integer EXAMPLES:: @@ -768,14 +748,11 @@ def _repr_(self): def index(self): """ Return the index of this Hecke operator. (For example, if this is - the operator `T_n`, then the index is the integer - `n`.) + the operator `T_n`, then the index is the integer `n`.) OUTPUT: - - - ``n`` -- a (Sage) Integer - + - ``n`` -- a (Sage) Integer EXAMPLES:: @@ -822,11 +799,9 @@ def characteristic_polynomial(self, var='x'): INPUT: + - ``var`` -- string (default: ``'x'``) - - ``var`` -- a string (default: 'x') - - - OUTPUT: a polynomial in var over the rational numbers. + OUTPUT: a polynomial in var over the rational numbers EXAMPLES:: @@ -851,9 +826,7 @@ def charpoly(self, var='x'): INPUT: - - - ``var`` -- string (default: 'x') - + - ``var`` -- string (default: ``'x'``) EXAMPLES:: @@ -917,9 +890,8 @@ def action_on_homology(self, R=ZZ): def matrix(self): r""" - Return the matrix of self acting on the homology - `H_1(A, ZZ)` of this abelian variety with coefficients in - `\ZZ`. + Return the matrix of ``self`` acting on the homology + `H_1(A, ZZ)` of this abelian variety with coefficients in `\ZZ`. EXAMPLES:: diff --git a/src/sage/modular/abvar/torsion_point.py b/src/sage/modular/abvar/torsion_point.py index 23e66c2197c..51c889f1bb5 100644 --- a/src/sage/modular/abvar/torsion_point.py +++ b/src/sage/modular/abvar/torsion_point.py @@ -33,7 +33,7 @@ class TorsionPoint(ModuleElement): - ``element`` -- a `\QQ`-vector space element that represents this element in terms of the ambient rational homology - - ``check`` -- bool (default: ``True``): whether to check that + - ``check`` -- boolean (default: ``True``); whether to check that element is in the appropriate vector space EXAMPLES: @@ -97,7 +97,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - .. note:: + .. NOTE:: Since they are represented as equivalences classes of rational homology modulo integral homology, we represent @@ -196,7 +196,7 @@ def _richcmp_(self, right, op): INPUT: - ``self``, ``right`` -- elements of the same finite abelian - variety subgroup. + variety subgroup - ``op`` -- comparison operator (see :mod:`sage.structure.richcmp`) diff --git a/src/sage/modular/abvar/torsion_subgroup.py b/src/sage/modular/abvar/torsion_subgroup.py index 4b434c54c7e..99976718137 100644 --- a/src/sage/modular/abvar/torsion_subgroup.py +++ b/src/sage/modular/abvar/torsion_subgroup.py @@ -79,15 +79,15 @@ True """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.arith.misc import divisors, gcd from sage.misc.misc_c import prod @@ -115,9 +115,7 @@ def __init__(self, abvar): INPUT: - - - ``abvar`` -- a modular abelian variety - + - ``abvar`` -- a modular abelian variety EXAMPLES:: @@ -147,7 +145,7 @@ def __richcmp__(self, other, op): INPUT: - - ``other`` -- an object + - ``other`` -- an object If other is a torsion subgroup, the abelian varieties are compared. Otherwise, the generic behavior for finite abelian variety @@ -181,11 +179,9 @@ def order(self, proof=True): INPUT: - - ``proof`` -- a boolean (default: ``True``) - - OUTPUT: + - ``proof`` -- boolean (default: ``True``) - The order of this torsion subgroup. + OUTPUT: the order of this torsion subgroup EXAMPLES:: @@ -214,7 +210,6 @@ def order(self, proof=True): sage: J.rational_torsion_subgroup().order(proof=False) 408991 - """ O = self.possible_orders(proof=proof) if len(O) == 1: @@ -281,11 +276,9 @@ def possible_orders(self, proof=True): INPUT: - - ``proof`` -- a boolean (default: ``True``) - - OUTPUT: + - ``proof`` -- boolean (default: ``True``) - - an array of positive integers + OUTPUT: an array of positive integers The computation of the rational torsion order of J1(p) is conjectural and will only be used if ``proof=False``. See Section 6.2.3 of [CES2003]_. @@ -347,9 +340,7 @@ def divisor_of_order(self): Return a divisor of the order of this torsion subgroup of a modular abelian variety. - OUTPUT: - - A divisor of this torsion subgroup. + OUTPUT: a divisor of this torsion subgroup EXAMPLES:: @@ -414,7 +405,7 @@ def multiple_of_order(self, maxp=None, proof=True): INPUT: - - ``proof`` -- a boolean (default: ``True``) + - ``proof`` -- boolean (default: ``True``) The computation of the rational torsion order of J1(p) is conjectural and will only be used if proof=False. See Section 6.2.3 of [CES2003]_. @@ -477,7 +468,7 @@ def multiple_of_order(self, maxp=None, proof=True): return self._multiple_of_order_proof_false # The Gamma0 and Gamma1 case - if all((isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class) for G in A.groups())): + if all(isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class) for G in A.groups()): self._multiple_of_order = self.multiple_of_order_using_frobp() return self._multiple_of_order @@ -496,13 +487,11 @@ def multiple_of_order_using_frobp(self, maxp=None): INPUT: - - - ``maxp`` -- (default: None) If maxp is None (the - default), return gcd of best bound computed so far with bound - obtained by computing GCD's of orders modulo p until this gcd - stabilizes for 3 successive primes. If maxp is given, just use all - primes up to and including maxp. - + - ``maxp`` -- (default: ``None``) if ``maxp`` is ``None``, return gcd + of best bound computed so far with bound obtained by computing GCD's + of orders modulo `p` until this gcd stabilizes for 3 successive + primes. If ``maxp`` is given, just use all primes up to and including + ``maxp``. EXAMPLES:: @@ -580,7 +569,7 @@ def multiple_of_order_using_frobp(self, maxp=None): T = ZZ(1) self.__multiple_of_order_using_frobp = T return T - if not all((isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class) for G in A.groups())): + if not all(isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class) for G in A.groups()): raise NotImplementedError("torsion multiple only implemented for Gamma0 and Gamma1") bnd = ZZ(0) @@ -676,9 +665,7 @@ def __init__(self, abvar): INPUT: - - - ``abvar`` -- an abelian variety - + - ``abvar`` -- an abelian variety EXAMPLES:: diff --git a/src/sage/modular/arithgroup/arithgroup_element.pyx b/src/sage/modular/arithgroup/arithgroup_element.pyx index 6bcd2c58550..c47f4e453c3 100644 --- a/src/sage/modular/arithgroup/arithgroup_element.pyx +++ b/src/sage/modular/arithgroup/arithgroup_element.pyx @@ -43,7 +43,7 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): which lives in ``parent`` - ``check`` -- if ``True``, check that parent is an arithmetic - subgroup, and that `x` defines a matrix of determinant `1`. + subgroup, and that `x` defines a matrix of determinant `1` We tend not to create elements of arithmetic subgroups that are not SL2Z, in order to avoid coercion issues (that is, the other arithmetic @@ -159,8 +159,8 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): cpdef _richcmp_(self, right_r, int op): """ - Compare self to right, where right is guaranteed to have the same - parent as self. + Compare ``self`` to ``right``, where ``right`` is guaranteed to have + the same parent as ``self``. EXAMPLES:: @@ -205,7 +205,7 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): cpdef _mul_(self, right): """ - Return self * right. + Return ``self * right``. EXAMPLES:: @@ -375,8 +375,8 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): sage: G([1, 4, 0, 1]).acton(infinity) +Infinity """ - from sage.rings.infinity import is_Infinite, infinity - if is_Infinite(z): + from sage.rings.infinity import InfinityElement, infinity + if isinstance(z, InfinityElement): if self.c() != 0: return self.a() / self.c() else: diff --git a/src/sage/modular/arithgroup/arithgroup_generic.py b/src/sage/modular/arithgroup/arithgroup_generic.py index 8c7a32e2b5f..c70defa96a3 100644 --- a/src/sage/modular/arithgroup/arithgroup_generic.py +++ b/src/sage/modular/arithgroup/arithgroup_generic.py @@ -4,7 +4,7 @@ """ ################################################################################ # -# Copyright (C) 2009, The Sage Group -- http://www.sagemath.org/ +# Copyright (C) 2009, The Sage Group -- https://www.sagemath.org/ # # Distributed under the terms of the GNU General Public License (GPL) # @@ -60,7 +60,7 @@ class ArithmeticSubgroup(Group): Element = ArithmeticSubgroupElement - def __init__(self): + def __init__(self) -> None: r""" Standard init routine. @@ -74,9 +74,9 @@ def __init__(self): def _repr_(self) -> str: r""" - Return the string representation of self. + Return the string representation of ``self``. - NOTE: This function should be overridden by all subclasses. + .. NOTE:: This function should be overridden by all subclasses. EXAMPLES:: @@ -102,9 +102,9 @@ def _repr_option(self, key): def __reduce__(self): r""" - Used for pickling self. + Used for pickling ``self``. - NOTE: This function should be overridden by all subclasses. + .. NOTE:: This function should be overridden by all subclasses. EXAMPLES:: @@ -119,8 +119,8 @@ def _element_constructor_(self, x, check=True): r""" Create an element of this congruence subgroup from x. - If the optional flag check is True (default), check whether - x actually gives an element of self. + If the optional flag check is ``True`` (default), check whether + x actually gives an element of ``self``. EXAMPLES:: @@ -146,8 +146,10 @@ def _element_constructor_(self, x, check=True): def __contains__(self, x): r""" - Test if x is an element of this group. This checks that x defines (is?) a 2x2 integer matrix of determinant 1, and - then hands over to the routine _contains_sl2, which derived classes should implement. + Test if x is an element of this group. + + This checks that x defines (is?) a 2x2 integer matrix of determinant 1, and + then hands over to the routine ``_contains_sl2``, which derived classes should implement. EXAMPLES:: @@ -165,12 +167,12 @@ def __contains__(self, x): # Do not override this function! Derived classes should override # _contains_sl2. if isinstance(x, list) and len(x) == 4: - if not (x[0] in ZZ and x[1] in ZZ and x[2] in ZZ and x[3] in ZZ): + if not all(y in ZZ for y in x): return False - a,b,c,d = map(ZZ, x) + a, b, c, d = map(ZZ, x) if a*d - b*c != 1: return False - return self._contains_sl2(a,b,c,d) + return self._contains_sl2(a, b, c, d) else: if parent(x) is not SL2Z: try: @@ -178,13 +180,14 @@ def __contains__(self, x): except TypeError: return False x = y - return self._contains_sl2(x.a(),x.b(),x.c(),x.d()) + return self._contains_sl2(x.a(), x.b(), x.c(), x.d()) - def _contains_sl2(self, a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" Test whether the matrix [a,b;c,d], which may be assumed to have - determinant 1, is an element of self. This must be overridden by all - subclasses. + determinant 1, is an element of ``self``. + + This must be overridden by all subclasses. EXAMPLES:: @@ -198,7 +201,7 @@ def _contains_sl2(self, a,b,c,d): def __hash__(self): r""" - Return a hash of self. + Return a hash of ``self``. EXAMPLES:: @@ -234,10 +237,11 @@ def matrix_space(self): """ return Mat2Z - def is_parent_of(self, x): + def is_parent_of(self, x) -> bool: r""" - Check whether this group is a valid parent for the element x. Required - by Sage's testing framework. + Check whether this group is a valid parent for the element x. + + Required by Sage's testing framework. EXAMPLES:: @@ -250,16 +254,16 @@ def is_parent_of(self, x): sage: Gamma(3).is_parent_of(SL2Z(1)) True """ - return (parent(x) == SL2Z and x in self) + return parent(x) == SL2Z and x in self def coset_reps(self, G=None): r""" - Return right coset representatives for self \\ G, where G is another - arithmetic subgroup that contains self. If G = None, default to G = - SL2Z. + Return right coset representatives for ``self \\ G``, where `G` is + another arithmetic subgroup that contains ``self``. If ``G == None``, + default to ``G = SL2Z``. - For generic arithmetic subgroups G this is carried out by Todd-Coxeter - enumeration; here G is treated as a black box, implementing nothing but + For generic arithmetic subgroups `G` this is carried out by Todd-Coxeter + enumeration; here `G` is treated as a black box, implementing nothing but membership testing. EXAMPLES:: @@ -279,7 +283,7 @@ def coset_reps(self, G=None): @cached_method def todd_coxeter(self, G=None, on_right=True): r""" - Compute coset representatives for self \\ G and action of standard + Compute coset representatives for ``self \\ G`` and action of standard generators on them via Todd-Coxeter enumeration. If ``G`` is ``None``, default to ``SL2Z``. The method also computes @@ -290,23 +294,21 @@ def todd_coxeter(self, G=None, on_right=True): - ``G`` -- intermediate subgroup (currently not implemented if different from SL(2,Z)) - - ``on_right`` -- boolean (default: ``True``); if True return right coset - enumeration, if False return left one. + - ``on_right`` -- boolean (default: ``True``); if ``True`` return right + coset enumeration, if ``False`` return left one This is *extremely* slow in general. - OUTPUT: - - - a list of coset representatives + OUTPUT: list of coset representatives - a list of generators for the group - ``l`` -- list of integers that correspond to the action of the standard parabolic element [[1,1],[0,1]] of `SL(2,\ZZ)` on the cosets - of self. + of ``self``. - ``s`` -- list of integers that correspond to the action of the standard - element of order `2` [[0,-1],[1,0]] on the cosets of self. + element of order `2` [[0,-1],[1,0]] on the cosets of ``self`` EXAMPLES:: @@ -354,17 +356,17 @@ def todd_coxeter(self, G=None, on_right=True): if G != SL2Z: raise NotImplementedError("Don't know how to compute coset reps for subgroups yet") - id = SL2Z([1,0,0,1]) - l = SL2Z([1,1,0,1]) - s = SL2Z([0,-1,1,0]) + one = SL2Z.one() + l = SL2Z([1, 1, 0, 1]) + s = SL2Z([0, -1, 1, 0]) - reps = [id] # coset representatives - reps_inv = {id:0} # coset representatives index + reps = [one] # coset representatives + reps_inv = {one: 0} # coset representatives index - l_wait_back = [id] # rep with no incoming s_edge - s_wait_back = [id] # rep with no incoming l_edge - l_wait = [id] # rep with no outgoing l_edge - s_wait = [id] # rep with no outgoing s_edge + l_wait_back = [one] # rep with no incoming s_edge + s_wait_back = [one] # rep with no incoming l_edge + l_wait = [one] # rep with no outgoing l_edge + s_wait = [one] # rep with no outgoing s_edge l_edges = [None] # edges for l s_edges = [None] # edges for s @@ -390,7 +392,7 @@ def todd_coxeter(self, G=None, on_right=True): if yy in self: l_edges[reps_inv[x]] = reps_inv[v] del l_wait_back[i] - if yy != id: + if yy != one: gens.append(self(yy)) not_end = False break @@ -422,7 +424,7 @@ def todd_coxeter(self, G=None, on_right=True): if yy in self: s_edges[reps_inv[x]] = reps_inv[v] del s_wait_back[i] - if yy != id: + if yy != one: gens.append(self(yy)) not_end = False break @@ -438,7 +440,7 @@ def todd_coxeter(self, G=None, on_right=True): return reps, gens, l_edges, s_edges - def nu2(self): + def nu2(self) -> int: r""" Return the number of orbits of elliptic points of order 2 for this arithmetic subgroup. @@ -473,8 +475,9 @@ def nu2(self): # precisely when the preimages are not elliptic.) count = 0 + mati = SL2Z([0, 1, -1, 0]) for g in self.coset_reps(): - if g * SL2Z([0,1,-1,0]) * (~g) in self: + if g * mati * (~g) in self: count += 1 return count @@ -507,21 +510,19 @@ def nu3(self): return 0 count = 0 + matj = SL2Z([0, 1, -1, -1]) for g in self.coset_reps(): - if g * SL2Z([0,1,-1,-1]) * (~g) in self: + if g * matj * (~g) in self: count += 1 - if self.is_even(): - return count - else: - return count // 2 + return count if self.is_even() else count // 2 - def is_abelian(self): + def is_abelian(self) -> bool: r""" - Return True if this arithmetic subgroup is abelian. + Return ``True`` if this arithmetic subgroup is abelian. Since arithmetic subgroups are always nonabelian, this always - returns False. + returns ``False``. EXAMPLES:: @@ -536,12 +537,12 @@ def is_abelian(self): """ return False - def is_finite(self): + def is_finite(self) -> bool: r""" - Return True if this arithmetic subgroup is finite. + Return ``True`` if this arithmetic subgroup is finite. Since arithmetic subgroups are always infinite, this always - returns False. + returns ``False``. EXAMPLES:: @@ -556,12 +557,13 @@ def is_finite(self): """ return False - def is_subgroup(self, right): + def is_subgroup(self, right) -> bool: r""" - Return True if self is a subgroup of right, and False otherwise. For - generic arithmetic subgroups this is done by the absurdly slow - algorithm of checking all of the generators of self to see if they are - in right. + Return ``True`` if ``self`` is a subgroup of right, and ``False`` otherwise. + + For generic arithmetic subgroups this is done by the absurdly + slow algorithm of checking all of the generators of ``self`` + to see if they are in ``right``. EXAMPLES:: @@ -573,16 +575,12 @@ def is_subgroup(self, right): True """ # ridiculously slow generic algorithm + return all(g in right for g in self.gens()) - w = self.gens() - for g in w: - if g not in right: - return False - return True - - def is_normal(self): + def is_normal(self) -> bool: r""" - Return True precisely if this subgroup is a normal subgroup of SL2Z. + Return ``True`` precisely if this subgroup is a normal subgroup of + ``SL2Z``. EXAMPLES:: @@ -593,13 +591,13 @@ def is_normal(self): """ for x in self.gens(): for y in SL2Z.gens(): - if y*SL2Z(x)*(~y) not in self: + if y * SL2Z(x) * (~y) not in self: return False return True - def is_odd(self): + def is_odd(self) -> bool: r""" - Return True precisely if this subgroup does not contain the + Return ``True`` precisely if this subgroup does not contain the matrix -1. EXAMPLES:: @@ -615,9 +613,9 @@ def is_odd(self): """ return not self.is_even() - def is_even(self): + def is_even(self) -> bool: r""" - Return True precisely if this subgroup contains the matrix -1. + Return ``True`` precisely if this subgroup contains the matrix -1. EXAMPLES:: @@ -634,7 +632,7 @@ def is_even(self): def to_even_subgroup(self): r""" - Return the smallest even subgroup of `SL(2, \ZZ)` containing self. + Return the smallest even subgroup of `SL(2, \ZZ)` containing ``self``. EXAMPLES:: @@ -673,10 +671,10 @@ def reduce_cusp(self, c): r""" Given a cusp `c \in \mathbb{P}^1(\QQ)`, return the unique reduced cusp equivalent to c under the action of self, where a reduced cusp is an - element `\tfrac{r}{s}` with r,s coprime non-negative integers, s as + element `\tfrac{r}{s}` with r,s coprime nonnegative integers, s as small as possible, and r as small as possible for that s. - NOTE: This function should be overridden by all subclasses. + .. NOTE:: This function should be overridden by all subclasses. EXAMPLES:: @@ -690,7 +688,7 @@ def reduce_cusp(self, c): def cusps(self, algorithm='default'): r""" Return a sorted list of inequivalent cusps for ``self``, i.e. a set of - representatives for the orbits of self on `\mathbb{P}^1(\QQ)`. + representatives for the orbits of ``self`` on `\mathbb{P}^1(\QQ)`. These should be returned in a reduced form where this makes sense. @@ -744,11 +742,13 @@ def _find_cusps(self): ... NotImplementedError - NOTE: There is a generic algorithm implemented at the top level that - uses the coset representatives of self. This is *very slow* and for all - the standard congruence subgroups there is a quicker way of doing it, - so this should usually be overridden in subclasses; but it doesn't have - to be. + .. NOTE:: + + There is a generic algorithm implemented at the top level that + uses the coset representatives of ``self``. This is *very slow* and for all + the standard congruence subgroups there is a quicker way of doing it, + so this should usually be overridden in subclasses; but it doesn't have + to be. """ i = Cusp([1, 0]) L = [i] @@ -765,13 +765,14 @@ def _find_cusps(self): def are_equivalent(self, x, y, trans=False): r""" - Test whether or not cusps x and y are equivalent modulo self. + Test whether or not cusps `x` and `y` are equivalent modulo ``self``. - If self has a reduce_cusp() method, use that; otherwise do a + If ``self`` has a ``reduce_cusp()`` method, use that; otherwise do a slow explicit test. - If trans = False, returns True or False. If trans = True, then return - either False or an element of self mapping x onto y. + If ``trans == False``, returns ``True`` or ``False``. If + ``trans == True``, then return either ``False`` or an element of + ``self`` mapping `x` onto `y`. EXAMPLES:: @@ -815,11 +816,11 @@ def are_equivalent(self, x, y, trans=False): return True return False - def cusp_data(self, c): + def cusp_data(self, c) -> tuple: r""" - Return a triple (g, w, t) where g is an element of self generating the - stabiliser of the given cusp, w is the width of the cusp, and t is 1 if - the cusp is regular and -1 if not. + Return a triple `(g, w, t)` where `g` is an element of ``self`` + generating the stabiliser of the given cusp, `w` is the width of the + cusp, and `t` is 1 if the cusp is regular and -1 if not. EXAMPLES:: @@ -833,19 +834,21 @@ def cusp_data(self, c): # first find an element of SL2Z sending infinity to the given cusp w = lift_to_sl2z(c.denominator(), c.numerator(), 0) - g = SL2Z([w[3], w[1], w[2],w[0]]) + g = SL2Z([w[3], w[1], w[2], w[0]]) for d in range(1,1+self.index()): - if g * SL2Z([1,d,0,1]) * (~g) in self: + if g * SL2Z([1, d, 0, 1]) * (~g) in self: return (g * SL2Z([1,d,0,1]) * (~g), d, 1) - elif g * SL2Z([-1,-d,0,-1]) * (~g) in self: - return (g * SL2Z([-1,-d,0,-1]) * (~g), d, -1) + elif g * SL2Z([-1, -d, 0, -1]) * (~g) in self: + return (g * SL2Z([-1, -d, 0, -1]) * (~g), d, -1) raise ArithmeticError("Can't get here!") - def is_regular_cusp(self, c): + def is_regular_cusp(self, c) -> bool: r""" - Return True if the orbit of the given cusp is a regular cusp for self, - otherwise False. This is automatically true if -1 is in self. + Return ``True`` if the orbit of the given cusp is a regular cusp for + ``self``, otherwise ``False``. + + This is automatically true if -1 is in ``self``. EXAMPLES:: @@ -856,7 +859,7 @@ def is_regular_cusp(self, c): """ if self.is_even(): return True - return (self.cusp_data(c)[2] == 1) + return self.cusp_data(c)[2] == 1 def cusp_width(self, c): r""" @@ -875,7 +878,7 @@ def cusp_width(self, c): def index(self): r""" - Return the index of self in the full modular group. + Return the index of ``self`` in the full modular group. EXAMPLES:: @@ -886,7 +889,6 @@ def index(self): ... NotImplementedError """ - return len(list(self.coset_reps())) def generalised_level(self): @@ -923,11 +925,11 @@ def generalised_level(self): def projective_index(self): r""" - Return the index of the image of self in `\PSL_2(\ZZ)`. This is equal - to the index of self if self contains -1, and half of this otherwise. + Return the index of the image of ``self`` in `\PSL_2(\ZZ)`. This is equal + to the index of ``self`` if ``self`` contains -1, and half of this otherwise. This is equal to the degree of the natural map from the modular curve - of self to the `j`-line. + of ``self`` to the `j`-line. EXAMPLES:: @@ -936,15 +938,14 @@ def projective_index(self): sage: Gamma1(5).projective_index() 12 """ - if self.is_even(): return self.index() else: return self.index() // 2 - def is_congruence(self): + def is_congruence(self) -> bool: r""" - Return True if self is a congruence subgroup. + Return ``True`` if ``self`` is a congruence subgroup. EXAMPLES:: @@ -955,7 +956,6 @@ def is_congruence(self): ... NotImplementedError """ - raise NotImplementedError def genus(self): @@ -982,8 +982,9 @@ def genus(self): def farey_symbol(self): r""" - Return the Farey symbol associated to this subgroup. See the - :mod:`~sage.modular.arithgroup.farey_symbol` module for more + Return the Farey symbol associated to this subgroup. + + See the :mod:`~sage.modular.arithgroup.farey_symbol` module for more information. EXAMPLES:: @@ -995,20 +996,20 @@ def farey_symbol(self): return Farey(self) @cached_method - def generators(self, algorithm="farey"): + def generators(self, algorithm='farey'): r""" Return a list of generators for this congruence subgroup. The result is cached. INPUT: - - ``algorithm`` (string): either ``farey`` or ``todd-coxeter``. + - ``algorithm`` -- string; either ``farey`` or ``todd-coxeter`` - If ``algorithm`` is set to ``"farey"``, then the generators will be + If ``algorithm`` is set to ``'farey'``, then the generators will be calculated using Farey symbols, which will always return a *minimal* generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for more information. - If ``algorithm`` is set to ``"todd-coxeter"``, a simpler algorithm + If ``algorithm`` is set to ``'todd-coxeter'``, a simpler algorithm based on Todd-Coxeter enumeration will be used. This is *exceedingly* slow for general subgroups, and the list of generators will be far from minimal (indeed it may contain repetitions). @@ -1020,7 +1021,7 @@ def generators(self, algorithm="farey"): [1 2] [ 3 -2] [-1 0] [0 1], [ 2 -1], [ 0 -1] ] - sage: Gamma(2).generators(algorithm="todd-coxeter") + sage: Gamma(2).generators(algorithm='todd-coxeter') [ [1 2] [-1 0] [ 1 0] [-1 0] [-1 2] [-1 0] [1 0] [0 1], [ 0 -1], [-2 1], [ 0 -1], [-2 3], [ 2 -1], [2 1] @@ -1051,8 +1052,8 @@ def gens(self, *args, **kwds) -> tuple: def gen(self, i): r""" - Return the i-th generator of self, i.e. the i-th element of the - tuple self.gens(). + Return the `i`-th generator of self, i.e. the `i`-th element of the + tuple ``self.gens()``. EXAMPLES:: @@ -1064,7 +1065,7 @@ def gen(self, i): def ngens(self): r""" - Return the size of the minimal generating set of self returned by + Return the size of the minimal generating set of ``self`` returned by :meth:`generators`. EXAMPLES:: @@ -1082,24 +1083,26 @@ def ngens(self): def ncusps(self): r""" - Return the number of cusps of this arithmetic subgroup. This is - provided as a separate function since for dimension formulae in even - weight all we need to know is the number of cusps, and this can be - calculated very quickly, while enumerating all cusps is much slower. + Return the number of cusps of this arithmetic subgroup. + + This is provided as a separate function since for dimension + formulae in even weight all we need to know is the number of + cusps, and this can be calculated very quickly, while + enumerating all cusps is much slower. EXAMPLES:: sage: sage.modular.arithgroup.arithgroup_generic.ArithmeticSubgroup.ncusps(Gamma0(7)) 2 """ - return ZZ(len(self.cusps())) def nregcusps(self): r""" - Return the number of cusps of self that are "regular", i.e. their - stabiliser has a generator with both eigenvalues +1 rather than -1. If - the group contains -1, every cusp is clearly regular. + Return the number of cusps of ``self`` that are "regular", i.e. their + stabiliser has a generator with both eigenvalues +1 rather than -1. + + If the group contains -1, every cusp is clearly regular. EXAMPLES:: @@ -1110,10 +1113,11 @@ def nregcusps(self): def nirregcusps(self): r""" - Return the number of cusps of self that are "irregular", i.e. their + Return the number of cusps of ``self`` that are "irregular", i.e. their stabiliser can only be generated by elements with both eigenvalues -1 - rather than +1. If the group contains -1, every cusp is clearly - regular. + rather than +1. + + If the group contains -1, every cusp is clearly regular. EXAMPLES:: @@ -1121,14 +1125,15 @@ def nirregcusps(self): 1 """ if self.is_even(): - return 0 - else: - return ZZ(len([c for c in self.cusps() if not self.is_regular_cusp(c)])) + return ZZ.zero() + return ZZ(len([1 for c in self.cusps() if not self.is_regular_cusp(c)])) def dimension_modular_forms(self, k=2): r""" Return the dimension of the space of weight k modular forms for this - group. This is given by a standard formula in terms of k and various + group. + + This is given by a standard formula in terms of k and various invariants of the group; see Diamond + Shurman, "A First Course in Modular Forms", section 3.5 and 3.6. If k is not given, defaults to k = 2. @@ -1141,7 +1146,7 @@ def dimension_modular_forms(self, k=2): cases where one can prove solely via Riemann-Roch theory that there aren't any cusp forms (i.e. when the number of regular cusps is strictly greater than the degree of the canonical divisor). Otherwise a - NotImplementedError is raised. + :exc:`NotImplementedError` is raised. EXAMPLES:: @@ -1161,7 +1166,9 @@ def dimension_modular_forms(self, k=2): def dimension_cusp_forms(self, k=2): r""" Return the dimension of the space of weight k cusp forms for this - group. For `k \ge 2`, this is given by a standard formula in terms of k + group. + + For `k \ge 2`, this is given by a standard formula in terms of k and various invariants of the group; see Diamond + Shurman, "A First Course in Modular Forms", section 3.5 and 3.6. If k is not given, default to k = 2. @@ -1174,7 +1181,7 @@ def dimension_cusp_forms(self, k=2): where one can prove solely via Riemann-Roch theory that there aren't any cusp forms (i.e. when the number of regular cusps is strictly greater than the degree of the canonical divisor). Otherwise a - NotImplementedError is raised. + :exc:`NotImplementedError` is raised. EXAMPLES:: @@ -1191,7 +1198,7 @@ def dimension_cusp_forms(self, k=2): """ k = ZZ(k) if k <= 0: - return ZZ(0) + return ZZ.zero() if not (k % 2): # k even @@ -1206,7 +1213,7 @@ def dimension_cusp_forms(self, k=2): # k odd if self.is_even(): - return ZZ(0) + return ZZ.zero() else: e_reg = self.nregcusps() @@ -1216,7 +1223,7 @@ def dimension_cusp_forms(self, k=2): return (k-1)*(self.genus()-1) + (k // ZZ(3)) * self.nu3() + (k-2)/ZZ(2) * e_reg + (k-1)/ZZ(2) * e_irr else: if e_reg > 2*self.genus() - 2: - return ZZ(0) + return ZZ.zero() else: raise NotImplementedError("Computation of dimensions of weight 1 cusp forms spaces not implemented in general") @@ -1228,7 +1235,7 @@ def dimension_eis(self, k=2): INPUT: - - ``k`` -- an integer (default 2). + - ``k`` -- integer (default: 2) EXAMPLES:: @@ -1242,23 +1249,23 @@ def dimension_eis(self, k=2): 4 """ if k < 0: - return ZZ(0) + return ZZ.zero() if k == 0: - return ZZ(1) + return ZZ.one() - if not (k % 2): # k even + if not (k % 2): # k even if k > 2: return self.ncusps() - else: # k = 2 + else: # k = 2 return self.ncusps() - 1 - else: # k odd + else: # k odd if self.is_even(): - return 0 + return ZZ.zero() if k > 1: return self.nregcusps() - else: # k = 1 - return ZZ(self.nregcusps() / ZZ(2)) + else: # k = 1 + return ZZ(self.nregcusps() // ZZ(2)) def as_permutation_group(self): r""" @@ -1286,7 +1293,7 @@ def as_permutation_group(self): sage: P.an_element() in G True """ - _,_,l_edges,s2_edges = self.todd_coxeter() + _, _, l_edges, s2_edges = self.todd_coxeter() n = len(l_edges) s3_edges = [None] * n r_edges = [None] * n @@ -1305,12 +1312,12 @@ def as_permutation_group(self): def sturm_bound(self, weight=2): r""" - Returns the Sturm bound for modular forms of the given weight and level + Return the Sturm bound for modular forms of the given weight and level this subgroup. INPUT: - - ``weight`` -- an integer `\geq 2` (default: 2) + - ``weight`` -- integer `\geq 2` (default: 2) EXAMPLES:: diff --git a/src/sage/modular/arithgroup/arithgroup_perm.py b/src/sage/modular/arithgroup/arithgroup_perm.py index a084d46a33d..388cabfeed1 100644 --- a/src/sage/modular/arithgroup/arithgroup_perm.py +++ b/src/sage/modular/arithgroup/arithgroup_perm.py @@ -32,7 +32,7 @@ interest: - `(l,r)` as they are also semigroup generators for the semigroup of matrices - in `\SL_2(\ZZ)` with non-negative entries, + in `\SL_2(\ZZ)` with nonnegative entries, - `(l,s_2)` as they are closely related to the continued fraction algorithm, - `(s_2,s_3)` as the group `\PSL_2(\ZZ)` is the free product of the finite cyclic groups generated by these two elements. @@ -124,6 +124,7 @@ Lmi = SL2Z([1,-1,0,1]) # the inverse of Lm in SL(2,Z) Rmi = SL2Z([1,0,-1,1]) # the inverse of Rm in SL(2,Z) + def sl2z_word_problem(A): r""" Given an element of `\SL_2(\ZZ)`, express it as a word in the generators L = @@ -151,7 +152,7 @@ def sl2z_word_problem(A): output = [] # If A00 is zero - if A[0,0] == 0: + if A[0, 0] == 0: c = A[1,1] if c != 1: A = A*Lm**(c-1)*Rm*Lmi @@ -160,12 +161,12 @@ def sl2z_word_problem(A): A = A*Rm*Lmi output.extend([(1,-1),(0,1)]) - if A[0,0] < 0: # Make sure A00 is positive + if A[0, 0] < 0: # Make sure A00 is positive A = SL2Z(-1)*A output.extend([(1,-1), (0,1), (1,-1), (0,1), (1,-1), (0,1)]) if A[0,1] < 0: # if A01 is negative make it positive - n = (-A[0,1]/A[0,0]).ceil() #n s.t. 0 <= A[0,1]+n*A[0,0] < A[0,0] + n = (-A[0,1]/A[0,0]).ceil() # n s.t. 0 <= A[0,1]+n*A[0,0] < A[0,0] A = A*Lm**n output.append((0, -n)) # At this point A00>0 and A01>=0 @@ -180,10 +181,10 @@ def sl2z_word_problem(A): A = A*SL2Z([1,-n,0,1]) output.append((0, n)) - if A == SL2Z(1): + if A == SL2Z.one(): pass # done, so don't add R^0 - elif A[0,0] == 0: - c = A[1,1] + elif A[0, 0] == 0: + c = A[1, 1] if c != 1: A = A*Lm**(c-1)*Rm*Lmi output.extend([(0,1-c),(1,-1),(0, 1)]) @@ -199,6 +200,7 @@ def sl2z_word_problem(A): output.reverse() return output + def eval_sl2z_word(w): r""" Given a word in the format output by :func:`sl2z_word_problem`, convert it back @@ -216,6 +218,7 @@ def eval_sl2z_word(w): w1 = w return w0 * prod((mat[a[0]]**a[1] for a in w1), Idm) + def word_of_perms(w, p1, p2): r""" Given a word `w` as a list of 2-tuples ``(index,power)`` and permutations @@ -260,6 +263,7 @@ def word_of_perms(w, p1, p2): return M + def _equalize_perms(l): r""" Transform a list of lists into a list of lists with identical length. Each @@ -286,6 +290,7 @@ def _equalize_perms(l): # interpreted as L and R. Hence the order of the arguments is slightly # different from the class __init__ methods. + def ArithmeticSubgroup_Permutation( L=None, R=None, S2=None, S3=None, relabel=False, @@ -312,10 +317,10 @@ def ArithmeticSubgroup_Permutation( - ``S2``, ``S3``, ``L``, ``R`` -- permutations; action of matrices on the right cosets (each coset is identified to an element of `\{1,\dots,n\}` - where `1` is reserved for the identity coset). + where `1` is reserved for the identity coset) - - ``relabel`` -- boolean (default: ``False``); if True, renumber the cosets in a - canonical way. + - ``relabel`` -- boolean (default: ``False``); if ``True``, renumber the cosets in a + canonical way - ``check`` -- boolean (default: ``True``); check that the input is valid (it may be time efficient but less safe to set it to False) @@ -454,6 +459,7 @@ def ArithmeticSubgroup_Permutation( return G + class ArithmeticSubgroup_Permutation_class(ArithmeticSubgroup): r""" A subgroup of `\SL_2(\ZZ)` defined by the action of generators on its @@ -575,7 +581,7 @@ def __hash__(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -683,7 +689,7 @@ def perm_group(self): def index(self): r""" - Returns the index of this modular subgroup in the full modular group. + Return the index of this modular subgroup in the full modular group. EXAMPLES:: @@ -853,7 +859,7 @@ def relabel(self, inplace=True): def _canonical_unrooted_labels(self): r""" - Returns the smallest label among rooted label + Return the smallest label among rooted label. OUTPUT: @@ -923,7 +929,7 @@ def _canonical_unrooted_labels(self): def _canonical_rooted_labels(self, j0=0): r""" - Return the permutation which correspond to the renumbering of self in + Return the permutation which correspond to the renumbering of ``self`` in order to get canonical labels. If ``j0`` is 0 then the renumbering corresponds to the same group. If @@ -1053,7 +1059,7 @@ def _contains_sl2(self, a,b,c,d): def random_element(self, initial_steps=30): r""" - Returns a random element in this subgroup. + Return a random element in this subgroup. The algorithm uses a random walk on the Cayley graph of `\SL_2(\ZZ)` stopped at the first time it reaches the subgroup after at least @@ -1096,7 +1102,7 @@ def random_element(self, initial_steps=30): def permutation_action(self, x): r""" Given an element ``x`` of `\SL_2(\ZZ)`, compute the permutation of the - cosets of self given by right multiplication by ``x``. + cosets of ``self`` given by right multiplication by ``x``. EXAMPLES:: @@ -1112,7 +1118,7 @@ def permutation_action(self, x): def is_normal(self): r""" - Test whether the group is normal + Test whether the group is normal. EXAMPLES:: @@ -1141,7 +1147,7 @@ def is_normal(self): def _conjugate(self,j0): r""" - Return the conjugate of self rooted at j0. + Return the conjugate of ``self`` rooted at j0. EXAMPLES:: @@ -1188,15 +1194,15 @@ def coset_graph(self, INPUT: - - ``right_cosets`` -- bool (default: ``False``); right or left coset graph + - ``right_cosets`` -- boolean (default: ``False``); right or left coset graph - - ``s2_edges`` -- bool (default: ``True``); put edges associated to s2 + - ``s2_edges`` -- boolean (default: ``True``); put edges associated to s2 - - ``s3_edges`` -- bool (default: ``True``); put edges associated to s3 + - ``s3_edges`` -- boolean (default: ``True``); put edges associated to s3 - - ``l_edges`` -- bool (default: ``False``); put edges associated to l + - ``l_edges`` -- boolean (default: ``False``); put edges associated to l - - ``r_edges`` -- bool (default: ``False``); put edges associated to r + - ``r_edges`` -- boolean (default: ``False``); put edges associated to r - ``s2_label``, ``s3_label``, ``l_label``, ``r_label`` -- the labels to put on the edges corresponding to the generators action. Use ``None`` @@ -1291,18 +1297,18 @@ def generalised_level(self): def congruence_closure(self): r""" - Returns the smallest congruence subgroup containing self. If self is + Return the smallest congruence subgroup containing ``self``. If ``self`` is congruence, this is just self, but represented as a congruence subgroup - data type. If self is not congruence, then it may be larger. + data type. If ``self`` is not congruence, then it may be larger. In practice, we use the following criterion: let `m` be the generalised - level of self. If this subgroup is even, let `n = m`, else let `n = - 2m`. Then any congruence subgroup containing self contains `\Gamma(n)` + level of ``self``. If this subgroup is even, let `n = m`, else let `n = + 2m`. Then any congruence subgroup containing ``self`` contains `\Gamma(n)` (a generalisation of Wohlfahrt's theorem due to Kiming, Verrill and - Schuett). So we compute the image of self modulo `n` and return the + Schuett). So we compute the image of ``self`` modulo `n` and return the preimage of that. - .. note:: + .. NOTE:: If you just want to know if the subgroup is congruence or not, it is *much* faster to use :meth:`~is_congruence`. @@ -1484,7 +1490,7 @@ def is_congruence(self): r = R**d s = l**20 * r**onefifth * l**(-4) * ~r - #Congruence if the seven permutations below are trivial: + # Congruence if the seven permutations below are trivial: rel = ~a*~r*a*r if not rel.is_one(): verbose("Failed relation B1") @@ -1603,7 +1609,7 @@ def __init__(self, S2, S3, L, R, canonical_labels=False): def __reduce__(self): r""" - Return the data used to construct self. Used in pickling. + Return the data used to construct ``self``. Used in pickling. TESTS:: @@ -1650,7 +1656,7 @@ def is_even(self): def to_even_subgroup(self,relabel=True): r""" - Returns the group with `-Id` added in it. + Return the group with `-Id` added in it. EXAMPLES:: @@ -1784,9 +1790,9 @@ def cusp_widths(self,exp=False): INPUT: - - ``exp`` -- boolean (default: ``False``) - if True, return a dictionary with - keys the possible widths and with values the number of cusp with that - width. + - ``exp`` -- boolean (default: ``False``); if ``True``, return a + dictionary with keys the possible widths and with values the number + of cusp with that width EXAMPLES:: @@ -1831,7 +1837,7 @@ def cusp_widths(self,exp=False): def ncusps(self): r""" - Returns the number of cusps. + Return the number of cusps. EXAMPLES:: @@ -1853,6 +1859,7 @@ def ncusps(self): m += 1 return n + m//2 + class EvenArithmeticSubgroup_Permutation(ArithmeticSubgroup_Permutation_class): r""" An arithmetic subgroup of `\SL(2, \ZZ)` containing `-1`, represented @@ -1942,7 +1949,7 @@ def __reduce__(self): def is_odd(self): r""" - Returns True if this subgroup does not contain the matrix `-Id`. + Return ``True`` if this subgroup does not contain the matrix `-Id`. EXAMPLES:: @@ -1954,7 +1961,7 @@ def is_odd(self): def is_even(self): r""" - Returns True if this subgroup contains the matrix `-Id`. + Return ``True`` if this subgroup contains the matrix `-Id`. EXAMPLES:: @@ -1966,7 +1973,7 @@ def is_even(self): def nu2(self): r""" - Returns the number of orbits of elliptic points of order 2 for this + Return the number of orbits of elliptic points of order 2 for this arithmetic subgroup. EXAMPLES:: @@ -1979,7 +1986,7 @@ def nu2(self): def nu3(self): r""" - Returns the number of orbits of elliptic points of order 3 for this + Return the number of orbits of elliptic points of order 3 for this arithmetic subgroup. EXAMPLES:: @@ -2016,7 +2023,7 @@ def _spanning_tree_kulkarni(self, root=0, on_right=True): INPUT: - ``on_right`` -- boolean (default: ``True``); if ``False``, - return spanning tree for the left cosets. + return spanning tree for the left cosets OUTPUT: @@ -2027,10 +2034,10 @@ def _spanning_tree_kulkarni(self, root=0, on_right=True): of the cosets with respect to the spanning tree - ``word_reps`` -- list of lists with ``s2`` and ``s3``; word - representatives of the cosets with respect to the spanning tree. + representatives of the cosets with respect to the spanning tree - ``gens`` -- list of 3-tuples ``(in,out,label)``; the list of edges in - the graph which are not in the spanning tree. + the graph which are not in the spanning tree EXAMPLES:: @@ -2156,10 +2163,10 @@ def _spanning_tree_verrill(self, root=0, on_right=True): cosets with respect to the spanning tree - ``word_reps`` -- list of string with ``s`` and ``l`` -- word - representatives of the cosets with respect to the spanning tree. + representatives of the cosets with respect to the spanning tree - ``gens`` -- list of 3-tuples ``(in,out,label)``; the list of edges in - the graph which are not in the spanning tree. + the graph which are not in the spanning tree EXAMPLES:: @@ -2274,7 +2281,7 @@ def _spanning_tree_verrill(self, root=0, on_right=True): def todd_coxeter_s2_s3(self): r""" - Returns a 4-tuple ``(coset_reps, gens, s2, s3)`` where ``coset_reps`` + Return a 4-tuple ``(coset_reps, gens, s2, s3)`` where ``coset_reps`` are coset representatives of the subgroup, ``gens`` is a list of generators, ``s2`` and ``s3`` are the action of the matrices `S2` and `S3` on the list of cosets. @@ -2319,7 +2326,7 @@ def todd_coxeter_s2_s3(self): def todd_coxeter_l_s2(self): r""" - Returns a 4-tuple ``(coset_reps, gens, l, s2)`` where ``coset_reps`` is + Return a 4-tuple ``(coset_reps, gens, l, s2)`` where ``coset_reps`` is a list of coset representatives of the subgroup, ``gens`` a list of generators, ``l`` and ``s2`` are list that corresponds to the action of the matrix `S2` and `L` on the cosets. @@ -2440,8 +2447,8 @@ def cusp_widths(self,exp=False): def to_even_subgroup(self, relabel=True): r""" - Return the subgroup generated by self and ``-Id``. Since self is even, - this is just self. Provided for compatibility. + Return the subgroup generated by ``self`` and ``-Id``. Since ``self`` is even, + this is just ``self``. Provided for compatibility. EXAMPLES:: diff --git a/src/sage/modular/arithgroup/congroup.pyx b/src/sage/modular/arithgroup/congroup.pyx index 002e3bb02da..d55c0c0ce7c 100644 --- a/src/sage/modular/arithgroup/congroup.pyx +++ b/src/sage/modular/arithgroup/congroup.pyx @@ -52,9 +52,9 @@ def degeneracy_coset_representatives_gamma0(int N, int M, int t): INPUT: - - ``N`` -- int - - ``M`` -- int (divisor of `N`) - - ``t`` -- int (divisor of `N/M`) + - ``N`` -- integer + - ``M`` -- integer (divisor of `N`) + - ``t`` -- integer (divisor of `N/M`) OUTPUT: @@ -116,7 +116,7 @@ def degeneracy_coset_representatives_gamma0(int N, int M, int t): # total number of coset representatives that we'll find n = Gamma0(N).index() / Gamma0(M).index() k = 0 # number found so far - Ndivt = N / t + Ndivt = N // t R = check_allocarray(4 * n, sizeof(int)) halfmax = 2*(n+10) while k < n: @@ -126,10 +126,10 @@ def degeneracy_coset_representatives_gamma0(int N, int M, int t): g = arith_int.c_xgcd_int(-cc,dd,&bb,&aa) if g == 0: continue - cc = cc / g + cc = cc // g if cc % M != 0: continue - dd = dd / g + dd = dd // g # Test if we've found a new coset representative. is_new = 1 for i in range(k): @@ -165,9 +165,9 @@ def degeneracy_coset_representatives_gamma1(int N, int M, int t): INPUT: - - ``N`` -- int - - ``M`` -- int (divisor of `N`) - - ``t`` -- int (divisor of `N/M`) + - ``N`` -- integer + - ``M`` -- integer (divisor of `N`) + - ``t`` -- integer (divisor of `N/M`) OUTPUT: @@ -217,7 +217,7 @@ def degeneracy_coset_representatives_gamma1(int N, int M, int t): # total number of coset representatives that we'll find n = Gamma1(N).index() / Gamma1(M).index() d = arith_int.c_gcd_int(t, N // t) - n = n / d + n = n // d k = 0 # number found so far Ndivt = N // t R = check_allocarray(4 * n, sizeof(int)) @@ -229,10 +229,10 @@ def degeneracy_coset_representatives_gamma1(int N, int M, int t): g = arith_int.c_xgcd_int(-cc, dd, &bb, &aa) if g == 0: continue - cc = cc / g + cc = cc // g if cc % M != 0: continue - dd = dd / g + dd = dd // g if M != 1 and dd % M != 1: continue # Test if we've found a new coset representative. @@ -288,7 +288,7 @@ def generators_helper(coset_reps, level): EXAMPLES:: - sage: Gamma0(7).generators(algorithm="todd-coxeter") # indirect doctest + sage: Gamma0(7).generators(algorithm='todd-coxeter') # indirect doctest [ [1 1] [-1 0] [ 1 -1] [1 0] [1 1] [-3 -1] [-2 -1] [-5 -1] [0 1], [ 0 -1], [ 0 1], [7 1], [0 1], [ 7 2], [ 7 3], [21 4], diff --git a/src/sage/modular/arithgroup/congroup_gamma.py b/src/sage/modular/arithgroup/congroup_gamma.py index 9a3a72589bf..78d878aaf9d 100644 --- a/src/sage/modular/arithgroup/congroup_gamma.py +++ b/src/sage/modular/arithgroup/congroup_gamma.py @@ -2,13 +2,13 @@ Congruence subgroup `\Gamma(N)` """ -#***************************************************************************** +# **************************************************************************** # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.arith.misc import gcd from sage.groups.matrix_gps.finitely_generated import MatrixGroup @@ -26,6 +26,8 @@ _gamma_cache = {} + + def Gamma_constructor(N): r""" Return the congruence subgroup `\Gamma(N)`. @@ -66,7 +68,7 @@ class Gamma_class(CongruenceSubgroup): """ def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -77,7 +79,7 @@ def _repr_(self): def _latex_(self): r""" - Return the \LaTeX representation of self. + Return the \LaTeX representation of ``self``. EXAMPLES:: @@ -90,7 +92,7 @@ def _latex_(self): def __reduce__(self): """ - Used for pickling self. + Used for pickling ``self``. EXAMPLES:: @@ -101,7 +103,7 @@ def __reduce__(self): def __richcmp__(self, other, op): r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -123,7 +125,7 @@ def __richcmp__(self, other, op): def index(self): r""" - Return the index of self in the full modular group. This is given by + Return the index of ``self`` in the full modular group. This is given by .. MATH:: @@ -178,7 +180,8 @@ def ncusps(self): def nirregcusps(self): r""" - Return the number of irregular cusps of self. For principal congruence subgroups this is always 0. + Return the number of irregular cusps of ``self``. For principal + congruence subgroups this is always 0. EXAMPLES:: @@ -245,7 +248,6 @@ def reduce_cusp(self, c): sage: Gamma(7).reduce_cusp(Cusp(6,7)) Infinity - """ N = self.level() c = Cusp(c) @@ -309,7 +311,7 @@ def image_mod_n(self): def is_Gamma(x): r""" - Return True if x is a congruence subgroup of type Gamma. + Return ``True`` if x is a congruence subgroup of type Gamma. EXAMPLES:: diff --git a/src/sage/modular/arithgroup/congroup_gamma0.py b/src/sage/modular/arithgroup/congroup_gamma0.py index cfa31675ffe..ca0d050fe6f 100644 --- a/src/sage/modular/arithgroup/congroup_gamma0.py +++ b/src/sage/modular/arithgroup/congroup_gamma0.py @@ -8,8 +8,8 @@ # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.arith.misc import kronecker_symbol, divisors, euler_phi, gcd, moebius from sage.misc.cachefunc import cached_method @@ -26,7 +26,7 @@ def is_Gamma0(x): """ - Return True if x is a congruence subgroup of type Gamma0. + Return ``True`` if x is a congruence subgroup of type Gamma0. EXAMPLES:: @@ -47,6 +47,8 @@ def is_Gamma0(x): _gamma0_cache = {} + + def Gamma0_constructor(N): """ Return the congruence subgroup Gamma0(N). @@ -110,7 +112,6 @@ class Gamma0_class(GammaH_class): Modular Symbols subspace of dimension 5 of Modular Symbols space of dimension 18 for Gamma_0(100) of weight 2 with sign 1 over Rational Field - """ def __init__(self, level): @@ -144,11 +145,11 @@ def __init__(self, level): # be done if needed by the _generators_for_H and _list_of_elements_in_H # methods. # - #GammaH_class.__init__(self, level, [int(x) for x in IntegerModRing(level).unit_gens()]) + # GammaH_class.__init__(self, level, [int(x) for x in IntegerModRing(level).unit_gens()]) def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -159,7 +160,7 @@ def _repr_(self): def __reduce__(self): """ - Used for pickling self. + Used for pickling ``self``. EXAMPLES:: @@ -170,7 +171,7 @@ def __reduce__(self): def _latex_(self): r""" - Return the \LaTeX representation of self. + Return the \LaTeX representation of ``self``. EXAMPLES:: @@ -184,8 +185,8 @@ def _latex_(self): @cached_method def _generators_for_H(self): """ - Return generators for the subgroup H of the units mod - self.level() that defines self. + Return generators for the subgroup `H` of the units mod + ``self.level()`` that defines ``self``. EXAMPLES:: @@ -199,7 +200,7 @@ def _generators_for_H(self): @cached_method def _list_of_elements_in_H(self): """ - Returns a sorted list of Python ints that are representatives + Return a sorted list of Python ints that are representatives between 0 and N-1 of the elements of H. EXAMPLES:: @@ -245,10 +246,10 @@ def divisor_subgroups(self): def is_even(self): r""" - Return True precisely if this subgroup contains the matrix -1. + Return ``True`` precisely if this subgroup contains the matrix -1. Since `\Gamma0(N)` always contains the matrix -1, this always - returns True. + returns ``True``. EXAMPLES:: @@ -261,7 +262,7 @@ def is_even(self): def is_subgroup(self, right): """ - Return True if self is a subgroup of right. + Return ``True`` if ``self`` is a subgroup of ``right``. EXAMPLES:: @@ -331,21 +332,21 @@ def coset_reps(self): yield SL2Z(lift_to_sl2z(z[0], z[1], N)) @cached_method - def generators(self, algorithm="farey"): + def generators(self, algorithm='farey'): r""" Return generators for this congruence subgroup. INPUT: - - ``algorithm`` (string): either ``"farey"`` (default) or - ``"todd-coxeter"``. + - ``algorithm`` -- string; either ``'farey'`` (default) or + ``'todd-coxeter'`` - If ``algorithm`` is set to ``"farey"``, then the generators will be + If ``algorithm`` is set to ``'farey'``, then the generators will be calculated using Farey symbols, which will always return a *minimal* generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for more information. - If ``algorithm`` is set to ``"todd-coxeter"``, a simpler algorithm + If ``algorithm`` is set to ``'todd-coxeter'``, a simpler algorithm based on Todd-Coxeter enumeration will be used. This tends to return far larger sets of generators. @@ -356,7 +357,7 @@ def generators(self, algorithm="farey"): [1 1] [-1 1] [0 1], [-3 2] ] - sage: Gamma0(3).generators(algorithm="todd-coxeter") + sage: Gamma0(3).generators(algorithm='todd-coxeter') [ [1 1] [-1 0] [ 1 -1] [1 0] [1 1] [-1 0] [ 1 0] [0 1], [ 0 -1], [ 0 1], [3 1], [0 1], [ 3 -1], [-3 1] @@ -390,7 +391,7 @@ def generators(self, algorithm="farey"): def gamma_h_subgroups(self): r""" Return the subgroups of the form `\Gamma_H(N)` contained - in self, where `N` is the level of self. + in ``self``, where `N` is the level of ``self``. EXAMPLES:: @@ -446,9 +447,9 @@ def _contains_sl2(self, a,b,c,d): def _find_cusps(self): r""" Return an ordered list of inequivalent cusps for self, i.e. a - set of representatives for the orbits of self on + set of representatives for the orbits of ``self`` on `\mathbb{P}^1(\QQ)`. These are returned in a reduced - form; see self.reduce_cusp for the definition of reduced. + form; see ``self.reduce_cusp`` for the definition of reduced. ALGORITHM: Uses explicit formulae specific to `\Gamma_0(N)`: a reduced cusp on @@ -555,7 +556,7 @@ def nu3(self): def index(self): r""" - Return the index of self in the full modular group. + Return the index of ``self`` in the full modular group. This is given by @@ -579,12 +580,12 @@ def dimension_new_cusp_forms(self, k=2, p=0): INPUT: - - `k` -- an integer (default: 2), the weight. Not fully + - ``k`` -- integer (default: 2); the weight. Not fully implemented for `k = 1`. - - `p` -- integer (default: 0); if nonzero, compute the - `p`-new subspace. + - ``p`` -- integer (default: 0); if nonzero, compute the + `p`-new subspace - OUTPUT: Integer + OUTPUT: integer ALGORITHM: diff --git a/src/sage/modular/arithgroup/congroup_gamma1.py b/src/sage/modular/arithgroup/congroup_gamma1.py index 4f95a3a702d..c450d98a783 100644 --- a/src/sage/modular/arithgroup/congroup_gamma1.py +++ b/src/sage/modular/arithgroup/congroup_gamma1.py @@ -3,13 +3,13 @@ Congruence subgroup `\Gamma_1(N)` """ -#***************************************************************************** +# **************************************************************************** # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.cachefunc import cached_method @@ -23,7 +23,7 @@ def is_Gamma1(x): """ - Return True if x is a congruence subgroup of type Gamma1. + Return ``True`` if x is a congruence subgroup of type Gamma1. EXAMPLES:: @@ -44,13 +44,14 @@ def is_Gamma1(x): """ from sage.misc.superseded import deprecation deprecation(38035, "The function is_Gamma1 is deprecated; use 'isinstance(..., Gamma1_class)' instead.") - #from congroup_sl2z import is_SL2Z - #return (isinstance(x, Gamma1_class) or is_SL2Z(x)) + # from congroup_sl2z import is_SL2Z + # return (isinstance(x, Gamma1_class) or is_SL2Z(x)) return isinstance(x, Gamma1_class) _gamma1_cache = {} + def Gamma1_constructor(N): r""" Return the congruence subgroup `\Gamma_1(N)`. @@ -115,7 +116,7 @@ def __init__(self, level): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -126,7 +127,7 @@ def _repr_(self): def __reduce__(self): """ - Used for pickling self. + Used for pickling ``self``. EXAMPLES:: @@ -137,7 +138,7 @@ def __reduce__(self): def _latex_(self): r""" - Return the \LaTeX representation of self. + Return the \LaTeX representation of ``self``. EXAMPLES:: @@ -150,7 +151,7 @@ def _latex_(self): def is_even(self): """ - Return True precisely if this subgroup contains the matrix -1. + Return ``True`` precisely if this subgroup contains the matrix -1. EXAMPLES:: @@ -165,7 +166,7 @@ def is_even(self): def is_subgroup(self, right): """ - Return True if self is a subgroup of right. + Return ``True`` if ``self`` is a subgroup of ``right``. EXAMPLES:: @@ -192,21 +193,21 @@ def is_subgroup(self, right): raise NotImplementedError @cached_method - def generators(self, algorithm="farey"): + def generators(self, algorithm='farey'): r""" Return generators for this congruence subgroup. The result is cached. INPUT: - - ``algorithm`` (string): either ``farey`` (default) or - ``todd-coxeter``. + - ``algorithm`` -- string; either ``'farey'`` (default) or + ``'todd-coxeter'`` - If ``algorithm`` is set to ``"farey"``, then the generators will be + If ``algorithm`` is set to ``'farey'``, then the generators will be calculated using Farey symbols, which will always return a *minimal* generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for more information. - If ``algorithm`` is set to ``"todd-coxeter"``, a simpler algorithm + If ``algorithm`` is set to ``'todd-coxeter'``, a simpler algorithm based on Todd-Coxeter enumeration will be used. This tends to return far larger sets of generators. @@ -217,7 +218,7 @@ def generators(self, algorithm="farey"): [1 1] [ 1 -1] [0 1], [ 3 -2] ] - sage: Gamma1(3).generators(algorithm="todd-coxeter") + sage: Gamma1(3).generators(algorithm='todd-coxeter') [ [1 1] [-2 1] [1 1] [ 1 -1] [1 0] [1 1] [-5 2] [ 1 0] [0 1], [-3 1], [0 1], [ 0 1], [3 1], [0 1], [12 -5], [-3 1], @@ -320,7 +321,7 @@ def ncusps(self): def index(self): r""" - Return the index of self in the full modular group. This is given by the formula + Return the index of ``self`` in the full modular group. This is given by the formula .. MATH:: @@ -339,26 +340,26 @@ def index(self): # Dimension formulas for Gamma1, accepting a Dirichlet character as an argument. # ################################################################################## - def dimension_modular_forms(self, k=2, eps=None, algorithm="CohenOesterle"): + def dimension_modular_forms(self, k=2, eps=None, algorithm='CohenOesterle'): r""" - Return the dimension of the space of modular forms for self, or the + Return the dimension of the space of modular forms for ``self``, or the dimension of the subspace corresponding to the given character if one is supplied. INPUT: - - ``k`` -- an integer (default: 2), the weight. + - ``k`` -- integer (default: 2); the weight - - ``eps`` -- either None or a Dirichlet character modulo N, where N is - the level of this group. If this is None, then the dimension of the + - ``eps`` -- either ``None`` or a Dirichlet character modulo N, where N is + the level of this group. If this is ``None``, then the dimension of the whole space is returned; otherwise, the dimension of the subspace of forms of character eps. - - ``algorithm`` -- either "CohenOesterle" (the default) or "Quer". This - specifies the method to use in the case of nontrivial character: - either the Cohen--Oesterle formula as described in Stein's book, or - by Möbius inversion using the subgroups GammaH (a method due to - Jordi Quer). + - ``algorithm`` -- either ``'CohenOesterle'`` (the default) or + ``'Quer'``. This specifies the method to use in the case of + nontrivial character: either the Cohen--Oesterle formula as described + in Stein's book, or by Möbius inversion using the subgroups GammaH (a + method due to Jordi Quer). EXAMPLES:: @@ -368,7 +369,7 @@ def dimension_modular_forms(self, k=2, eps=None, algorithm="CohenOesterle"): sage: G = Gamma1(7*43) sage: G.dimension_modular_forms(2, eps) 32 - sage: G.dimension_modular_forms(2, eps, algorithm="Quer") + sage: G.dimension_modular_forms(2, eps, algorithm='Quer') 32 TESTS: @@ -381,16 +382,16 @@ def dimension_modular_forms(self, k=2, eps=None, algorithm="CohenOesterle"): sage: G = DirichletGroup(13, base_ring=K) sage: Gamma1(13).dimension_modular_forms(2, G[1]) 3 - sage: Gamma1(13).dimension_modular_forms(2, G[1], algorithm="Quer") + sage: Gamma1(13).dimension_modular_forms(2, G[1], algorithm='Quer') 3 sage: Gamma1(39).dimension_modular_forms(2, G[1]) 7 - sage: Gamma1(39).dimension_modular_forms(2, G[1], algorithm="Quer") + sage: Gamma1(39).dimension_modular_forms(2, G[1], algorithm='Quer') 7 """ return self.dimension_cusp_forms(k, eps, algorithm) + self.dimension_eis(k, eps, algorithm) - def dimension_cusp_forms(self, k=2, eps=None, algorithm="CohenOesterle"): + def dimension_cusp_forms(self, k=2, eps=None, algorithm='CohenOesterle'): r""" Return the dimension of the space of cusp forms for ``self``, or the dimension of the subspace corresponding to the given character if one @@ -398,18 +399,18 @@ def dimension_cusp_forms(self, k=2, eps=None, algorithm="CohenOesterle"): INPUT: - - ``k`` -- an integer (default: 2), the weight. + - ``k`` -- integer (default: 2); the weight - - ``eps`` -- either None or a Dirichlet character modulo N, where N is - the level of this group. If this is None, then the dimension of the + - ``eps`` -- either ``None`` or a Dirichlet character modulo N, where N is + the level of this group. If this is ``None``, then the dimension of the whole space is returned; otherwise, the dimension of the subspace of forms of character eps. - - ``algorithm`` -- either "CohenOesterle" (the default) or "Quer". This - specifies the method to use in the case of nontrivial character: - either the Cohen--Oesterle formula as described in Stein's book, or - by Möbius inversion using the subgroups GammaH (a method due to Jordi - Quer). Ignored for weight 1. + - ``algorithm`` -- either ``'CohenOesterle'`` (the default) or + ``'Quer'``. This specifies the method to use in the case of nontrivial + character: either the Cohen--Oesterle formula as described in Stein's + book, or by Möbius inversion using the subgroups GammaH (a method due + to Jordi Quer). Ignored for weight 1. EXAMPLES: @@ -427,7 +428,7 @@ def dimension_cusp_forms(self, k=2, eps=None, algorithm="CohenOesterle"): Via Quer's method:: - sage: Gamma1(7*43).dimension_cusp_forms(2, eps, algorithm="Quer") # needs sage.rings.number_field + sage: Gamma1(7*43).dimension_cusp_forms(2, eps, algorithm='Quer') # needs sage.rings.number_field 28 Some more examples:: @@ -487,10 +488,10 @@ def dimension_cusp_forms(self, k=2, eps=None, algorithm="CohenOesterle"): from sage.modular.dims import CohenOesterle return ZZ( K(Gamma0(N).index() * (k-1)/ZZ(12)) + CohenOesterle(eps,k) ) - else: #algorithm not in ["CohenOesterle", "Quer"]: + else: # algorithm not in ["CohenOesterle", "Quer"]: raise ValueError("Unrecognised algorithm in dimension_cusp_forms") - def dimension_eis(self, k=2, eps=None, algorithm="CohenOesterle"): + def dimension_eis(self, k=2, eps=None, algorithm='CohenOesterle'): r""" Return the dimension of the space of Eisenstein series forms for self, or the dimension of the subspace corresponding to the given character @@ -498,18 +499,18 @@ def dimension_eis(self, k=2, eps=None, algorithm="CohenOesterle"): INPUT: - - ``k`` -- an integer (default: 2), the weight. + - ``k`` -- integer (default: 2); the weight - - ``eps`` -- either None or a Dirichlet character modulo N, where N is - the level of this group. If this is None, then the dimension of the + - ``eps`` -- either ``None`` or a Dirichlet character modulo N, where N is + the level of this group. If this is ``None``, then the dimension of the whole space is returned; otherwise, the dimension of the subspace of Eisenstein series of character eps. - - ``algorithm`` -- either "CohenOesterle" (the default) or "Quer". This - specifies the method to use in the case of nontrivial character: - either the Cohen--Oesterle formula as described in Stein's book, or - by Möbius inversion using the subgroups GammaH (a method due to - Jordi Quer). + - ``algorithm`` -- either ``'CohenOesterle'`` (the default) or + ``'Quer'``. This specifies the method to use in the case of nontrivial + character: either the Cohen--Oesterle formula as described in Stein's + book, or by Möbius inversion using the subgroups GammaH (a method due + to Jordi Quer). AUTHORS: @@ -525,14 +526,14 @@ def dimension_eis(self, k=2, eps=None, algorithm="CohenOesterle"): sage: [Gamma1(36).dimension_eis(1,eps) for eps in DirichletGroup(36)] [0, 4, 3, 0, 0, 2, 6, 0, 0, 2, 3, 0] - sage: [Gamma1(36).dimension_eis(1,eps,algorithm="Quer") for eps in DirichletGroup(36)] + sage: [Gamma1(36).dimension_eis(1,eps,algorithm='Quer') for eps in DirichletGroup(36)] [0, 4, 3, 0, 0, 2, 6, 0, 0, 2, 3, 0] So do these:: sage: [Gamma1(48).dimension_eis(3,eps) for eps in DirichletGroup(48)] [0, 12, 0, 4, 0, 8, 0, 4, 12, 0, 4, 0, 8, 0, 4, 0] - sage: [Gamma1(48).dimension_eis(3,eps,algorithm="Quer") for eps in DirichletGroup(48)] + sage: [Gamma1(48).dimension_eis(3,eps,algorithm='Quer') for eps in DirichletGroup(48)] [0, 12, 0, 4, 0, 8, 0, 4, 12, 0, 4, 0, 8, 0, 4, 0] """ from .all import Gamma0 @@ -573,27 +574,27 @@ def dimension_eis(self, k=2, eps=None, algorithm="CohenOesterle"): else: return alpha - self.dimension_cusp_forms(k, eps) - else: #algorithm not in ["CohenOesterle", "Quer"]: + else: # algorithm not in ["CohenOesterle", "Quer"]: raise ValueError("Unrecognised algorithm in dimension_eis") - def dimension_new_cusp_forms(self, k=2, eps=None, p=0, algorithm="CohenOesterle"): + def dimension_new_cusp_forms(self, k=2, eps=None, p=0, algorithm='CohenOesterle'): r""" Dimension of the new subspace (or `p`-new subspace) of cusp forms of weight `k` and character `\varepsilon`. INPUT: - - ``k`` -- an integer (default: 2) + - ``k`` -- integer (default: 2) - ``eps`` -- a Dirichlet character - - ``p`` -- a prime (default: 0); just the `p`-new subspace if given + - ``p`` -- a prime (default: 0); just the `p`-new subspace if given - - ``algorithm`` -- either "CohenOesterle" (the default) or "Quer". This - specifies the method to use in the case of nontrivial character: - either the Cohen--Oesterle formula as described in Stein's book, or - by Möbius inversion using the subgroups GammaH (a method due to - Jordi Quer). + - ``algorithm`` -- either ``'CohenOesterle'`` (the default) or + ``'Quer'``. This specifies the method to use in the case of nontrivial + character: either the Cohen--Oesterle formula as described in Stein's + book, or by Möbius inversion using the subgroups GammaH (a method due + to Jordi Quer). EXAMPLES:: @@ -623,13 +624,12 @@ def dimension_new_cusp_forms(self, k=2, eps=None, p=0, algorithm="CohenOesterle" 11 sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1) for k in [2..4]] [0, 4, 0] - sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1, algorithm="Quer") for k in [2..4]] + sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1, algorithm='Quer') for k in [2..4]] [0, 4, 0] sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1^2) for k in [2..4]] [2, 0, 6] sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1^2, p=3) for k in [2..4]] [2, 0, 6] - """ if eps is None: diff --git a/src/sage/modular/arithgroup/congroup_gammaH.py b/src/sage/modular/arithgroup/congroup_gammaH.py index 1ad2042ec4b..e0cf97c74bc 100644 --- a/src/sage/modular/arithgroup/congroup_gammaH.py +++ b/src/sage/modular/arithgroup/congroup_gammaH.py @@ -45,8 +45,8 @@ def GammaH_constructor(level, H): INPUT: - - level -- an integer - - H -- either 0, 1, or a list + - ``level`` -- integer + - ``H`` -- either 0, 1, or a list * If H is a list, return `\Gamma_H(N)`, where `H` is the subgroup of `(\ZZ/N\ZZ)^*` **generated** by the elements of the list. @@ -94,7 +94,7 @@ def GammaH_constructor(level, H): def is_GammaH(x): """ - Return True if x is a congruence subgroup of type GammaH. + Return ``True`` if x is a congruence subgroup of type GammaH. EXAMPLES:: @@ -272,7 +272,7 @@ def extend(self, M): def __reduce__(self): """ - Used for pickling self. + Used for pickling ``self``. EXAMPLES:: @@ -308,7 +308,7 @@ def divisor_subgroups(self): def to_even_subgroup(self): r""" - Return the smallest even subgroup of `SL(2, \ZZ)` containing self. + Return the smallest even subgroup of `SL(2, \ZZ)` containing ``self``. EXAMPLES:: @@ -316,7 +316,6 @@ def to_even_subgroup(self): Congruence Subgroup Gamma0(11) sage: Gamma1(11).to_even_subgroup() Congruence Subgroup Gamma_H(11) with H generated by [10] - """ if self.is_even(): return self @@ -325,7 +324,7 @@ def to_even_subgroup(self): def __richcmp__(self, other, op): """ - Compare self to other. + Compare ``self`` to ``other``. The ordering on congruence subgroups of the form GammaH(N) for some H is first by level, then by the order of H, then lexicographically by H. @@ -385,8 +384,8 @@ def __richcmp__(self, other, op): def _generators_for_H(self): """ - Return generators for the subgroup H of the units mod - self.level() that defines self. + Return generators for the subgroup `H` of the units mod + ``self.level()`` that defines ``self``. EXAMPLES:: @@ -399,7 +398,7 @@ def _generators_for_H(self): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -410,7 +409,7 @@ def _repr_(self): def _latex_(self): r""" - Return the \LaTeX representation of self. + Return the \LaTeX representation of ``self``. EXAMPLES:: @@ -421,7 +420,7 @@ def _latex_(self): def _list_of_elements_in_H(self): """ - Returns a sorted list of Python ints that are representatives + Return a sorted list of Python ints that are representatives between 1 and N-1 of the elements of H. WARNING: Do not change this returned list. @@ -437,7 +436,7 @@ def _list_of_elements_in_H(self): def is_even(self): """ - Return True precisely if this subgroup contains the matrix -1. + Return ``True`` precisely if this subgroup contains the matrix -1. EXAMPLES:: @@ -452,21 +451,21 @@ def is_even(self): return int(self.level() - 1) in v @cached_method - def generators(self, algorithm="farey"): + def generators(self, algorithm='farey'): r""" Return generators for this congruence subgroup. The result is cached. INPUT: - - ``algorithm`` (string): either ``farey`` (default) or - ``todd-coxeter``. + - ``algorithm`` -- string; either ``'farey'`` (default) or + ``todd-coxeter`` - If ``algorithm`` is set to ``"farey"``, then the generators will be + If ``algorithm`` is set to ``'farey'``, then the generators will be calculated using Farey symbols, which will always return a *minimal* generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for more information. - If ``algorithm`` is set to ``"todd-coxeter"``, a simpler algorithm + If ``algorithm`` is set to ``'todd-coxeter'``, a simpler algorithm based on Todd-Coxeter enumeration will be used. This tends to return far larger sets of generators. @@ -477,7 +476,7 @@ def generators(self, algorithm="farey"): [1 1] [ 2 -1] [ 4 -3] [0 1], [ 7 -3], [ 7 -5] ] - sage: GammaH(7, [2]).generators(algorithm="todd-coxeter") + sage: GammaH(7, [2]).generators(algorithm='todd-coxeter') [ [1 1] [-13 4] [ 15 4] [-3 -1] [ 1 -1] [1 0] [1 1] [-3 -1] [0 1], [ 42 -13], [-49 -13], [ 7 2], [ 0 1], [7 1], [0 1], [ 7 2], @@ -512,9 +511,7 @@ def _coset_reduction_data_first_coord(self): - ``self`` -- a congruence subgroup Gamma_0(N), Gamma_1(N), or Gamma_H(N) - OUTPUT: - - A list v such that + OUTPUT: list v such that v[u] = (min(u*h: h in H), gcd(u,N) , @@ -587,13 +584,9 @@ def _coset_reduction_data_second_coord(self): This function specifically returns data needed for the second part of the reduction step (the second coordinate). - INPUT: - - ``self`` - OUTPUT: - a dictionary v with keys the divisors of N such that v[d] + A dictionary v with keys the divisors of N such that v[d] is the subgroup {h in H : h = 1 (mod N/d)}. EXAMPLES:: @@ -659,12 +652,10 @@ def _reduce_coset(self, uu, vv): Two integers (uu,vv) that define an element of `(Z/NZ)^2`. - - uu -- an integer - - vv -- an integer + - ``uu`` -- integer + - ``vv`` -- integer - OUTPUT: - - pair of integers that are equivalent to (uu,vv). + OUTPUT: pair of integers that are equivalent to (uu,vv) .. NOTE:: @@ -892,8 +883,8 @@ def _reduce_cusp(self, c): def _find_cusps(self): r""" - Return an ordered list of inequivalent cusps for self, i.e. a - set of representatives for the orbits of self on + Return an ordered list of inequivalent cusps for ``self``, i.e. a + set of representatives for the orbits of ``self`` on `\mathbf{P}^1(\QQ)`. These are returned in a reduced form; see self.reduce_cusp for the definition of reduced. @@ -968,8 +959,8 @@ def _contains_sl2(self, a, b, c, d): def gamma0_coset_reps(self): r""" - Return a set of coset representatives for self \\ Gamma0(N), where N is - the level of self. + Return a set of coset representatives for ``self \\ Gamma0(N)``, where + N is the level of ``self``. EXAMPLES:: @@ -991,7 +982,7 @@ def gamma0_coset_reps(self): def coset_reps(self): r""" - Return a set of coset representatives for self \\ SL2Z. + Return a set of coset representatives for ``self \\ SL2Z``. EXAMPLES:: @@ -1012,7 +1003,7 @@ def coset_reps(self): def is_subgroup(self, other): r""" - Return True if self is a subgroup of right, and False + Return ``True`` if ``self`` is a subgroup of ``right``, and ``False`` otherwise. EXAMPLES:: @@ -1110,7 +1101,6 @@ def nu3(self): AUTHORS: - Jordi Quer - """ N = self.level() H = self._list_of_elements_in_H() @@ -1138,7 +1128,6 @@ def ncusps(self): AUTHORS: - Jordi Quer - """ N = self.level() H = self._list_of_elements_in_H() @@ -1247,10 +1236,12 @@ def dimension_new_cusp_forms(self, k=2, p=0): INPUT: - - ``k`` -- an integer (default: 2), the weight. Not fully implemented for k = 1. - - ``p`` -- integer (default: 0); if nonzero, compute the `p`-new subspace. + - ``k`` -- integer (default: 2); the weight. Not fully implemented for + `k = 1`. + - ``p`` -- integer (default: 0); if nonzero, compute the `p`-new + subspace - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -1302,7 +1293,7 @@ def atkin_lehner_matrix(self, Q): an exact divisor `Q` of `N`, where `N` is the level of this group; that is, `gcd(Q, N/Q) = 1`. - .. note:: + .. NOTE:: We follow the conventions of [AL1978]_ here, so `W_Q` is given by the action of any matrix of the form `\begin{pmatrix} Qx & y \\ Nz @@ -1312,7 +1303,7 @@ def atkin_lehner_matrix(self, Q): INPUT: - - ``Q`` (integer): an integer dividing `N`, where `N` is the level of + - ``Q`` -- an integer dividing `N`, where `N` is the level of this group. If this divisor does not satisfy `gcd(Q, N/Q) = 1`, it will be replaced by the unique integer with this property having the same prime factors as `Q`. @@ -1349,11 +1340,11 @@ def characters_mod_H(self, sign=None, galois_orbits=False): INPUT: - - ``sign`` (default: None): if not None, return only characters of the - given sign + - ``sign`` -- (default: ``None``) if not ``None``, return only + characters of the given sign - - ``galois_orbits`` (default: ``False``): if True, return only one - character from each Galois orbit. + - ``galois_orbits`` -- (default: ``False``) if ``True``, return only + one character from each Galois orbit EXAMPLES:: @@ -1450,9 +1441,9 @@ def mumu(N): INPUT: - - ``N`` -- an integer at least 1 + - ``N`` -- integer at least 1 - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/modular/arithgroup/congroup_generic.py b/src/sage/modular/arithgroup/congroup_generic.py index cbd368fba31..41a09602a88 100644 --- a/src/sage/modular/arithgroup/congroup_generic.py +++ b/src/sage/modular/arithgroup/congroup_generic.py @@ -117,7 +117,7 @@ def CongruenceSubgroup_constructor(*args): def is_CongruenceSubgroup(x): r""" - Return True if x is of type CongruenceSubgroup. + Return ``True`` if x is of type CongruenceSubgroup. Note that this may be False even if `x` really is a congruence subgroup -- it tests whether `x` is "obviously" congruence, i.e.~whether it has a @@ -169,7 +169,7 @@ def __init__(self, level): def _an_element_(self): r""" - Return an element of self (mainly for use by the test suite). + Return an element of ``self`` (mainly for use by the test suite). EXAMPLES:: @@ -318,7 +318,7 @@ def __init__(self, G): def __reduce__(self): r""" - Data defining self (for pickling). + Data defining ``self`` (for pickling). EXAMPLES:: @@ -334,7 +334,7 @@ def __reduce__(self): def _contains_sl2(self, a,b,c,d): r""" - Test whether ``[a,b;c,d]`` is an element of self. + Test whether ``[a,b;c,d]`` is an element of ``self``. EXAMPLES:: @@ -369,7 +369,7 @@ def _contains_sl2(self, a,b,c,d): def to_even_subgroup(self): r""" - Return the smallest even subgroup of `SL(2, \ZZ)` containing self. + Return the smallest even subgroup of `SL(2, \ZZ)` containing ``self``. EXAMPLES:: @@ -392,7 +392,7 @@ def to_even_subgroup(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -403,7 +403,7 @@ def _repr_(self): def index(self): r""" - Return the index of self in the full modular group. This is equal to + Return the index of ``self`` in the full modular group. This is equal to the index in `SL(2, \ZZ / N\ZZ)` of the image of this group modulo `\Gamma(N)`. @@ -416,7 +416,8 @@ def index(self): def image_mod_n(self): r""" - Return the subgroup of `SL(2, \ZZ / N\ZZ)` of which this is the preimage, where `N` is the level of self. + Return the subgroup of `SL(2, \ZZ / N\ZZ)` of which this is the + preimage, where `N` is the level of ``self``. EXAMPLES:: @@ -431,6 +432,7 @@ def image_mod_n(self): """ return self.__G + class CongruenceSubgroup(CongruenceSubgroupFromGroup): r""" One of the "standard" congruence subgroups `\Gamma_0(N)`, `\Gamma_1(N)`, @@ -466,7 +468,7 @@ def __init__(self,*args, **kwds): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. NOTE: This function should be overridden by all subclasses. @@ -480,7 +482,7 @@ def _repr_(self): def modular_symbols(self, sign=0, weight=2, base_ring=QQ): """ Return the space of modular symbols of the specified weight and sign - on the congruence subgroup self. + on the congruence subgroup ``self``. EXAMPLES:: @@ -500,7 +502,7 @@ def modular_symbols(self, sign=0, weight=2, base_ring=QQ): def modular_abelian_variety(self): """ Return the modular abelian variety corresponding to the congruence - subgroup self. + subgroup ``self``. EXAMPLES:: @@ -517,7 +519,7 @@ def modular_abelian_variety(self): def _new_group_from_level(self, level): r""" Return a new group of the same type (Gamma0, Gamma1, or - GammaH) as self of the given level. In the case that self is of type + GammaH) as ``self`` of the given level. In the case that ``self`` is of type GammaH, we take the largest H inside `(\ZZ/ \text{level}\ZZ)^\times` which maps to H, namely its inverse image under the natural reduction map. @@ -568,6 +570,7 @@ def _new_group_from_level(self, level): else: raise NotImplementedError + def _minimize_level(G): r""" Utility function. Given a matrix group `G` contained in `SL(2, \ZZ / N\ZZ)` diff --git a/src/sage/modular/arithgroup/congroup_sl2z.py b/src/sage/modular/arithgroup/congroup_sl2z.py index f67ada831d3..d95c9e18764 100644 --- a/src/sage/modular/arithgroup/congroup_sl2z.py +++ b/src/sage/modular/arithgroup/congroup_sl2z.py @@ -29,7 +29,7 @@ def is_SL2Z(x): r""" - Return True if x is the modular group `\SL_2(\ZZ)`. + Return ``True`` if x is the modular group `\SL_2(\ZZ)`. EXAMPLES:: @@ -46,6 +46,7 @@ def is_SL2Z(x): deprecation(38035, "The function is_SL2Z is deprecated; use 'isinstance(..., SL2Z_class)' instead.") return isinstance(x, SL2Z_class) + class SL2Z_class(Gamma0_class): r""" The full modular group `\SL_2(\ZZ)`, regarded as a congruence @@ -87,7 +88,7 @@ def __init__(self): def __reduce__(self): """ - Used for pickling self. + Used for pickling ``self``. EXAMPLES:: @@ -98,8 +99,8 @@ def __reduce__(self): def _element_constructor_(self, x, check=True): r""" - Create an element of self from x, which must be something that can be - coerced into a 2x2 integer matrix. If check=True (the default), check + Create an element of ``self`` from x, which must be something that can be + coerced into a 2x2 integer matrix. If ``check=True`` (the default), check that x really has determinant 1. EXAMPLES:: @@ -130,7 +131,7 @@ def _contains_sl2(self,a,b,c,d): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -141,7 +142,7 @@ def _repr_(self): def _latex_(self): r""" - Return the \LaTeX representation of self. + Return the \LaTeX representation of ``self``. EXAMPLES:: @@ -154,7 +155,7 @@ def _latex_(self): def is_subgroup(self, right): """ - Return True if self is a subgroup of right. + Return ``True`` if ``self`` is a subgroup of ``right``. EXAMPLES:: @@ -170,7 +171,7 @@ def is_subgroup(self, right): def reduce_cusp(self, c): r""" Return the unique reduced cusp equivalent to c under the - action of self. Always returns Infinity, since there is only + action of ``self``. Always returns Infinity, since there is only one equivalence class of cusps for `SL_2(Z)`. EXAMPLES:: @@ -183,7 +184,7 @@ def reduce_cusp(self, c): def random_element(self, bound=100, *args, **kwds): r""" Return a random element of `\SL_2(\ZZ)` with entries whose - absolute value is strictly less than bound (default 100). + absolute value is strictly less than bound (default: 100). Additional arguments and keywords are passed to the random_element method of ZZ. @@ -250,9 +251,10 @@ def random_element(self, bound=100, *args, **kwds): SL2Z = SL2Z_class() + def _SL2Z_ref(): """ - Return SL2Z. (Used for pickling SL2Z.) + Return SL2Z. (Used for pickling SL2Z.). EXAMPLES:: diff --git a/src/sage/modular/arithgroup/farey_symbol.pyx b/src/sage/modular/arithgroup/farey_symbol.pyx index 604270aace7..c965015b41d 100644 --- a/src/sage/modular/arithgroup/farey_symbol.pyx +++ b/src/sage/modular/arithgroup/farey_symbol.pyx @@ -110,7 +110,7 @@ cdef class Farey: INPUT: - - `G` -- an arithmetic subgroup of `\PSL_2(\ZZ)` + - ``G`` -- an arithmetic subgroup of `\PSL_2(\ZZ)` EXAMPLES: @@ -279,7 +279,7 @@ cdef class Farey: [ -3 1] [-40 13] """ - gens_dict = {g:i+1 for i,g in enumerate(self.generators())} + gens_dict = {g: i+1 for i, g in enumerate(self.generators())} ans = [] for pm in self.pairing_matrices(): a, b, c, d = pm.matrix().list() @@ -305,12 +305,8 @@ cdef class Farey: @cached_method def _get_minus_one(self): r""" - If -I belongs to self, return a Tietze word representing it. - - OUTPUT: - - A Tietze word representing the element -I if it belongs to self. - Otherwise return [] + If -I belongs to ``self``, return a Tietze word representing it. + Otherwise return ``[]``. EXAMPLES:: @@ -335,7 +331,7 @@ cdef class Farey: sage: (-g.matrix()).is_one() True """ - for i,g in enumerate(self.generators()): + for i, g in enumerate(self.generators()): m = g.matrix() if (-m).is_one(): return [i + 1] @@ -346,33 +342,36 @@ cdef class Farey: return 3 * [i + 1] return [] - def word_problem(self, M, output = 'standard', check = True): + def word_problem(self, M, output='standard', check=True): r""" Solve the word problem (up to sign) using this Farey symbol. INPUT: - - ``M`` -- An element `M` of `\SL_2(\ZZ)`. - - ``output`` -- (default: ``'standard'``) Should be one of ``'standard'``, - ``'syllables'``, ``'gens'``. - - ``check`` -- (default: ``True``) Whether to check for correct input and output. + - ``M`` -- an element `M` of `\SL_2(\ZZ)` + + - ``output`` -- (default: ``'standard'``) should be one of + ``'standard'``, ``'syllables'``, ``'gens'``. + + - ``check`` -- boolean (default: ``True``); whether to check for + correct input and output OUTPUT: A solution to the word problem for the matrix `M`. The format depends on the ``output`` parameter, as follows. - - ``standard`` returns the so called the Tietze representation, - consists of a tuple of nonzero integers `i`, where if `i` > 0 - then it indicates the `i`th generator (that is, ``self.generators()[0]`` - would correspond to `i` = 1), and if `i` < 0 then it indicates - the inverse of the `i`-th generator. - - ``syllables`` returns a tuple of tuples of the form `(i,n)`, where - `(i,n)` represents ``self.generators()[i] ^ n``, + - ``'standard'`` returns the so called Tietze representation, + which consists of a tuple of nonzero integers. A positive + integer `i` indicates the `i`-th generator (that is, + ``self.generators()[i-1]``), while a negative integer `i` + indicates the inverse of the `i`-th generator. + - ``'syllables'`` returns a tuple of tuples of the form + `(i, n)`, where `(i, n)` represents ``self.generators()[i] ^ n``, whose product equals `M` up to sign. - - ``gens`` returns tuple of tuples of the form `(g,n)`, - `(g,n)` such that the product of the matrices `g^n` - equals `M` up to sign. + - ``'gens'`` returns a tuple of pairs `(g, n)`, where `g` is a + matrix and `n` an integer, such that the product of the + matrices `g^n` equals `M` up to sign. EXAMPLES:: @@ -388,7 +387,7 @@ cdef class Farey: sage: g [-5048053 586303] [-5558280 645563] - sage: F.word_problem(g, output = 'gens') + sage: F.word_problem(g, output='gens') (( [109 -10] [120 -11], 1 @@ -405,7 +404,7 @@ cdef class Farey: [17 -2] [60 -7], 1 )) - sage: F.word_problem(g, output = 'syllables') + sage: F.word_problem(g, output='syllables') ((3, 1), (10, 2), (8, -1), (5, 1)) TESTS: @@ -416,7 +415,7 @@ cdef class Farey: sage: G = Gamma0(10) sage: F = G.farey_symbol() sage: g = G([-701,-137,4600,899]) - sage: g1 = prod(F.generators()[i]**a for i,a in F.word_problem(g, output = 'syllables')) + sage: g1 = prod(F.generators()[i]**a for i, a in F.word_problem(g, output='syllables')) sage: g == g1 True @@ -429,15 +428,16 @@ cdef class Farey: Check that :issue:`20347` is solved:: sage: from sage.misc.misc_c import prod - sage: G = ArithmeticSubgroup_Permutation(S2="(1,2)(3,4)",S3="(1,2,3)") + sage: G = ArithmeticSubgroup_Permutation(S2="(1,2)(3,4)", S3="(1,2,3)") sage: S = G.farey_symbol() - sage: g1,g2 = S.generators() + sage: g1, g2 = S.generators() sage: g = g1^3 * g2^-2 * g1 * g2 sage: S.word_problem(g) (2, 2, 2, 1, 1, 1, 2, 1, 2) - sage: h = prod(S.generators()[i]**a for i,a in S.word_problem(g, output = 'syllables')) + sage: h = prod(S.generators()[i]**a for i, a in S.word_problem(g, output='syllables')) sage: g == h True + """ if output not in ['standard', 'syllables', 'gens']: raise ValueError('Unrecognized output format') @@ -467,7 +467,7 @@ cdef class Farey: if sgn == -1: beta, mbeta = mbeta, beta - gens_dict = {g:i+1 for i,g in enumerate(self.generators())} + gens_dict = {g: i+1 for i, g in enumerate(self.generators())} extra_tietze = [] if beta.is_one(): found = True @@ -504,17 +504,17 @@ cdef class Farey: for i in range(len(tietze)): t = tietze[i] tmp = tmp * gens[t-1] if t > 0 else tmp * gens[-t-1]**-1 - assert tmp.matrix() == M.matrix(),'%s %s %s' % (tietze, tmp.matrix(),M.matrix()) + assert tmp.matrix() == M.matrix(), '%s %s %s' % (tietze, tmp.matrix(), M.matrix()) if output == 'standard': return tuple(tietze) if output == 'syllables': - return tuple((a-1,len(list(g))) if a > 0 else (-a-1,-len(list(g))) for a,g in groupby(tietze)) + return tuple((a-1, len(list(g))) if a > 0 else (-a-1, -len(list(g))) for a, g in groupby(tietze)) else: # output == 'gens' - return tuple((gens[a-1],len(list(g))) if a > 0 else (gens[-a-1],-len(list(g))) for a, g in groupby(tietze)) + return tuple((gens[a-1], len(list(g))) if a > 0 else (gens[-a-1], -len(list(g))) for a, g in groupby(tietze)) def __contains__(self, M): r""" - Tests if element is in the arithmetic group of the Farey symbol + Test if element is in the arithmetic group of the Farey symbol via LLT algorithm. EXAMPLES:: @@ -536,7 +536,7 @@ cdef class Farey: def __richcmp__(self, other, op): r""" - Compare self to others. + Compare ``self`` to ``other``. EXAMPLES:: @@ -567,7 +567,6 @@ cdef class Farey: sage: FareySymbol(Gamma0(4)).__reduce__() (, ...)) - """ return Farey, (self.group, self.this_ptr.dumps()) @@ -593,14 +592,14 @@ cdef class Farey: INPUT: - - ``forced_format`` -- A format string ('plain' or 'xymatrix') - or ``None``. + - ``forced_format`` -- a format string ('plain' or 'xymatrix') + or ``None`` EXAMPLES:: - sage: FareySymbol(Gamma0(11))._latex_(forced_format = 'plain') + sage: FareySymbol(Gamma0(11))._latex_(forced_format='plain') '\\left( -\\infty\\underbrace{\\quad}_{1} 0\\underbrace{\\quad}_{2} \\frac{1}{3}\\underbrace{\\quad}_{3} \\frac{1}{2}\\underbrace{\\quad}_{2} \\frac{2}{3}\\underbrace{\\quad}_{3} 1\\underbrace{\\quad}_{1} \\infty\\right)' - sage: FareySymbol(Gamma0(11))._latex_(forced_format = 'xymatrix') + sage: FareySymbol(Gamma0(11))._latex_(forced_format='xymatrix') '\\begin{xy}\\xymatrix{& -\\infty \\ar@{-}@/_1pc/[r]_{1}& 0 \\ar@{-}@/_1pc/[r]_{2}& \\frac{1}{3} \\ar@{-}@/_1pc/[r]_{3}& \\frac{1}{2} \\ar@{-}@/_1pc/[r]_{2}& \\frac{2}{3} \\ar@{-}@/_1pc/[r]_{3}& 1 \\ar@{-}@/_1pc/[r]_{1}& \\infty }\\end{xy}' sage: 'xymatrix' in FareySymbol(Gamma0(11))._latex_() @@ -908,23 +907,23 @@ cdef class Farey: OPTIONS: - - ``fill`` -- boolean (default ``True``) fill the fundamental domain + - ``fill`` -- boolean (default: ``True``); fill the fundamental domain - - ``linestyle`` -- string (default: 'solid') The style of the line, + - ``linestyle`` -- string (default: ``'solid'``); the style of the line, which is one of 'dashed', 'dotted', 'solid', 'dashdot', or '--', ':', '-', '-.', respectively - - ``color`` -- (default: 'lightgray') fill color; fill - color for odd part of Dedekind tesselation. + - ``color`` -- (default: ``'lightgray'``) fill color for odd part of + Dedekind tesselation - - ``show_pairing`` -- boolean (default: ``True``) flag for pairing + - ``show_pairing`` -- boolean (default: ``True``); flag for pairing - - ``tesselation`` -- (default: 'Dedekind') The type of + - ``tesselation`` -- (default: ``'Dedekind'``) the type of hyperbolic tesselation which is one of - 'coset', 'Dedekind' or ``None`` respectively + ``'coset'``, ``'Dedekind'`` or ``None`` respectively - ``color_even`` -- fill color for even parts of Dedekind - tesselation (default 'white'); ignored for other tesselations + tesselation (default: ``'white'``); ignored for other tesselations - ``thickness`` -- float (default: `1`) the thickness of the line @@ -1030,6 +1029,7 @@ cdef class Farey: thickness=options['thickness']) d = g.get_minmax_data() g.set_axes_range(d['xmin'], d['xmax'], 0, options['ymax']) + g.set_aspect_ratio(1) return g diff --git a/src/sage/modular/arithgroup/meson.build b/src/sage/modular/arithgroup/meson.build new file mode 100644 index 00000000000..c4a68af3217 --- /dev/null +++ b/src/sage/modular/arithgroup/meson.build @@ -0,0 +1,65 @@ +py.install_sources( + 'all.py', + 'arithgroup_generic.py', + 'arithgroup_perm.py', + 'congroup_gamma.py', + 'congroup_gamma0.py', + 'congroup_gamma1.py', + 'congroup_gammaH.py', + 'congroup_generic.py', + 'congroup_sl2z.py', + 'tests.py', + subdir: 'sage/modular/arithgroup', +) + +extension_data = { + 'arithgroup_element' : files('arithgroup_element.pyx'), + 'congroup' : files('congroup.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modular/arithgroup', + install: true, + include_directories: [inc_cpython, inc_ext, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + +# Manually create header file, which otherwise is not found +farey_symbol_header = custom_target( + 'farey_symbol.h', + output: 'farey_symbol.h', + input: 'farey_symbol.pyx', + command: [ + cython.cmd_array(), + '--cplus', + '@INPUT@', + '-o', + '@OUTPUT@', + '-I', + join_paths(meson.current_source_dir(), '../../../'), + ], +) + +extension_data_cpp = { + 'farey_symbol': [ + files('farey.cpp', 'farey_symbol.pyx', 'sl2z.cpp'), + farey_symbol_header[0], + ], +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modular/arithgroup', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ext, inc_flint, inc_rings, inc_src], + dependencies: [py_dep, cysignals, flint, gmp, gmpxx], + ) +endforeach + diff --git a/src/sage/modular/arithgroup/tests.py b/src/sage/modular/arithgroup/tests.py index b00e39c0cda..f096b0a0429 100644 --- a/src/sage/modular/arithgroup/tests.py +++ b/src/sage/modular/arithgroup/tests.py @@ -311,7 +311,7 @@ def test_congruence_groups(self): if getattr(G, f)() != getattr(GG, f)(): raise AssertionError("results of %s does not coincide for %s" % (f, G)) - if sorted((G.cusp_width(c) for c in G.cusps())) != GG.cusp_widths(): + if sorted(G.cusp_width(c) for c in G.cusps()) != GG.cusp_widths(): raise AssertionError("Cusps widths are different for %s" % G) for _ in range(20): diff --git a/src/sage/modular/btquotients/btquotient.py b/src/sage/modular/btquotients/btquotient.py index eb0a6f0e1b3..280acec8874 100644 --- a/src/sage/modular/btquotients/btquotient.py +++ b/src/sage/modular/btquotients/btquotient.py @@ -113,12 +113,12 @@ class computes and stores the data corresponding to the INPUT: - - ``Y`` -- BruhatTitsQuotient object in which to work - - ``x`` -- Something coercible into a matrix in `GL_2(\ZZ)`. In - principle we should allow elements in `GL_2(\QQ_p)`, but it is - enough to work with integral entries + - ``Y`` -- BruhatTitsQuotient object in which to work + - ``x`` -- Something coercible into a matrix in `GL_2(\ZZ)`. In + principle we should allow elements in `GL_2(\QQ_p)`, but it is + enough to work with integral entries - ``extrapow`` -- gets added to the power attribute, and it is - used for the Hecke action. + used for the Hecke action EXAMPLES:: @@ -181,7 +181,7 @@ def __init__(self, Y, x, extrapow=0): def _repr_(self): r""" - Return the representation of self as a string. + Return the representation of ``self`` as a string. EXAMPLES:: @@ -196,7 +196,7 @@ def _repr_(self): def __eq__(self, other): """ - Return self == other + Return ``self == other``. TESTS:: @@ -229,7 +229,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Return self != other + Return ``self != other``. TESTS:: @@ -290,7 +290,7 @@ def igamma(self, embedding=None, scale=1): INPUT: - - ``embedding`` -- an integer, or a function (default: + - ``embedding`` -- integer; or a function (default: none). If ``embedding`` is None, then the image of ``self.gamma`` under the local splitting associated to ``self.Y`` is used. If ``embedding`` is an integer, then @@ -421,7 +421,7 @@ class BruhatTitsTree(SageObject, UniqueRepresentation): """ def __init__(self, p): """ - Initialize a BruhatTitsTree object for a given prime `p` + Initialize a BruhatTitsTree object for a given prime `p`. EXAMPLES:: @@ -444,8 +444,8 @@ def target(self, e, normalized=False): - ``e`` -- a 2x2 matrix with integer entries - - ``normalized`` -- boolean (default: false). If True - then the input matrix is assumed to be normalized. + - ``normalized`` -- boolean (default: ``False``); if True + then the input matrix is assumed to be normalized OUTPUT: @@ -477,12 +477,10 @@ def origin(self, e, normalized=False): - ``e`` -- a 2x2 matrix with integer entries - - ``normalized`` -- boolean (default: false). If True + - ``normalized`` -- boolean (default: ``False``); if True then the input matrix M is assumed to be normalized - OUTPUT: - - - ``e`` -- A 2x2 integer matrix + OUTPUT: ``e`` -- 2x2 integer matrix EXAMPLES:: @@ -508,11 +506,9 @@ def edge(self, M): INPUT: - - ``M`` -- a 2x2 integer matrix - - OUTPUT: + - ``M`` -- 2x2 integer matrix - - ``newM`` -- a 2x2 integer matrix + OUTPUT: ``newM`` -- 2x2 integer matrix EXAMPLES:: @@ -527,15 +523,13 @@ def edge(self, M): def lift(a): """ - Naively approximate a p-adic integer by a positive integer. + Naively approximate a `p`-adic integer by a positive integer. INPUT: - - ``a`` -- a p-adic integer. - - OUTPUT: + - ``a`` -- `p`-adic integer - An integer. + OUTPUT: integer EXAMPLES:: @@ -594,9 +588,7 @@ def vertex(self, M): - ``M`` -- 2x2 integer matrix - OUTPUT: - - - a 2x2 integer matrix + OUTPUT: a 2x2 integer matrix EXAMPLES:: @@ -655,9 +647,7 @@ def edges_leaving_origin(self): leaving the origin vertex corresponding to the homothety class of `\ZZ_p^2`. These are cached. - OUTPUT: - - - A list of size `p+1` of 2x2 integer matrices + OUTPUT: list of size `p+1` of 2x2 integer matrices EXAMPLES:: @@ -688,14 +678,14 @@ def edge_between_vertices(self, v1, v2, normalized=False): - ``v2`` -- 2x2 integer matrix - - ``normalized`` -- boolean (default: ``False``), whether the - vertices are normalized. + - ``normalized`` -- boolean (default: ``False``); whether the + vertices are normalized OUTPUT: - 2x2 integer matrix, representing the edge from ``v1`` to ``v2``. If ``v1`` and ``v2`` are not at distance `1`, raise - a :class:`ValueError`. + a :exc:`ValueError`. EXAMPLES:: @@ -731,15 +721,13 @@ def edge_between_vertices(self, v1, v2, normalized=False): def leaving_edges(self, M): r""" - Return edges leaving a vertex + Return edges leaving a vertex. INPUT: - ``M`` -- 2x2 integer matrix - OUTPUT: - - List of size `p+1` of 2x2 integer matrices + OUTPUT: list of size `p+1` of 2x2 integer matrices EXAMPLES:: @@ -763,9 +751,7 @@ def opposite(self, e): - ``e`` -- 2x2 integer matrix - OUTPUT: - - 2x2 integer matrix + OUTPUT: 2x2 integer matrix EXAMPLES:: @@ -792,9 +778,7 @@ def entering_edges(self, v): - ``v`` -- 2x2 integer matrix - OUTPUT: - - A list of size `p+1` of 2x2 integer matrices + OUTPUT: list of size `p+1` of 2x2 integer matrices EXAMPLES:: @@ -811,7 +795,7 @@ def entering_edges(self, v): def subdivide(self, edgelist, level): r""" - (Ordered) edges of self may be regarded as open balls in + (Ordered) edges of ``self`` may be regarded as open balls in `P^1(\QQ_p)`. Given a list of edges, this function return a list of edges corresponding to the level-th subdivision of the corresponding opens. That is, each open ball of the input is @@ -819,13 +803,11 @@ def subdivide(self, edgelist, level): INPUT: - - ``edgelist`` -- a list of edges - - - ``level`` -- an integer + - ``edgelist`` -- list of edges - OUTPUT: + - ``level`` -- integer - A list of 2x2 integer matrices + OUTPUT: list of 2x2 integer matrices EXAMPLES:: @@ -889,8 +871,8 @@ def find_path(self, v, boundary=None): - ``v`` -- a 2x2 matrix representing a vertex ``boundary`` - - a list of matrices (default: None). If omitted, finds the - geodesic from ``v`` to the central vertex. + - a list of matrices (default: ``None``); if omitted, finds the + geodesic from ``v`` to the central vertex OUTPUT: @@ -954,11 +936,9 @@ def find_containing_affinoid(self, z): INPUT: - ``z`` -- an element of an unramified extension of `\QQ_p` - that is not contained in `\QQ_p`. + that is not contained in `\QQ_p` - OUTPUT: - - A 2x2 integer matrix representing a vertex of ``self``. + OUTPUT: a 2x2 integer matrix representing a vertex of ``self`` EXAMPLES:: @@ -1004,7 +984,7 @@ def find_containing_affinoid(self, z): def find_geodesic(self, v1, v2, normalized=True): r""" - This function computes the geodesic between two vertices + This function computes the geodesic between two vertices. INPUT: @@ -1046,7 +1026,7 @@ def find_geodesic(self, v1, v2, normalized=True): def find_covering(self, z1, z2, level=0): r""" Compute a covering of `P^1(\QQ_p)` adapted to a certain - geodesic in self. + geodesic in ``self``. More precisely, the `p`-adic upper half plane points ``z1`` and ``z2`` reduce to vertices `v_1`, `v_2`. @@ -1057,9 +1037,7 @@ def find_covering(self, z1, z2, level=0): - ``z1``, ``z2`` -- unramified algebraic points of h_p - OUTPUT: - - a list of 2x2 integer matrices representing edges of self + OUTPUT: list of 2x2 integer matrices representing edges of self EXAMPLES:: @@ -1110,24 +1088,24 @@ class Vertex(SageObject): INPUT: - - ``p`` -- a prime integer. + - ``p`` -- prime integer - - ``label`` -- An integer which uniquely identifies this vertex. + - ``label`` -- integer which uniquely identifies this vertex - - ``rep`` -- A 2x2 matrix in reduced form representing this - vertex. + - ``rep`` -- a 2x2 matrix in reduced form representing this + vertex - - ``leaving_edges`` -- (default: empty list) A list of edges - leaving this vertex. + - ``leaving_edges`` -- (default: empty list) list of edges + leaving this vertex - - ``entering_edges`` -- (default: empty list) A list of edges - entering this vertex. + - ``entering_edges`` -- (default: empty list) list of edges + entering this vertex - - ``determinant`` -- (default: None) The determinant of ``rep``, - if known. + - ``determinant`` -- (default: ``None``) the determinant of ``rep``, + if known - - ``valuation`` -- (default: None) The valuation of the - determinant of ``rep``, if known. + - ``valuation`` -- (default: ``None``) the valuation of the + determinant of ``rep``, if known EXAMPLES:: @@ -1177,7 +1155,7 @@ def __init__(self, p, label, rep, leaving_edges=None, def _repr_(self): r""" - Return the representation of self as a string. + Return the representation of ``self`` as a string. EXAMPLES:: @@ -1189,7 +1167,7 @@ def _repr_(self): def __eq__(self, other): """ - Return self == other + Return ``self == other``. TESTS:: @@ -1214,7 +1192,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Return self != other + Return ``self != other``. TESTS:: @@ -1234,27 +1212,27 @@ class Edge(SageObject): INPUT: - - ``p`` -- a prime integer. + - ``p`` -- prime integer - - ``label`` -- An integer which uniquely identifies this edge. + - ``label`` -- integer which uniquely identifies this edge - - ``rep`` -- A 2x2 matrix in reduced form representing this edge. + - ``rep`` -- a 2x2 matrix in reduced form representing this edge - - ``origin`` -- The origin vertex of ``self``. + - ``origin`` -- the origin vertex of ``self`` - - ``target`` -- The target vertex of ``self``. + - ``target`` -- the target vertex of ``self`` - - ``links`` -- (Default: empty list) A list of elements of + - ``links`` -- (default: empty list) list of elements of `\Gamma` which identify different edges in the Bruhat-Tits tree - which are equivalent to ``self``. + which are equivalent to ``self`` - - ``opposite`` -- (Default: None) The edge opposite to ``self`` + - ``opposite`` -- (default: ``None``) the edge opposite to ``self`` - - ``determinant`` -- (Default: None) The determinant of ``rep``, - if known. + - ``determinant`` -- (default: ``None``) the determinant of ``rep``, + if known - - ``valuation`` -- (Default: None) The valuation of the - determinant of ``rep``, if known. + - ``valuation`` -- (default: ``None``) the valuation of the + determinant of ``rep``, if known EXAMPLES:: @@ -1306,7 +1284,7 @@ def __init__(self, p, label, rep, origin, target, links=None, def _repr_(self): r""" - Return the representation of self as a string. + Return the representation of ``self`` as a string. EXAMPLES:: @@ -1318,7 +1296,7 @@ def _repr_(self): def __eq__(self, other): """ - Return self == other + Return ``self == other``. TESTS:: @@ -1353,7 +1331,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Return self != other + Return ``self != other``. TESTS:: @@ -1385,20 +1363,20 @@ class BruhatTitsQuotient(SageObject, UniqueRepresentation): discriminant of the definite quaternion algebra that one is quotienting by. - - ``Nplus`` -- an integer coprime to pNminus (Default: 1). This is + - ``Nplus`` -- integer coprime to pNminus (default: 1). This is the tame level. It need not be squarefree! If Nplus is not 1 then the user currently needs magma installed due to sage's inability to compute well with nonmaximal Eichler orders in rational (definite) quaternion algebras. - - ``character`` -- a Dirichlet character (Default: None) of modulus - `pN^-N^+`. + - ``character`` -- a Dirichlet character (default: ``None``) of modulus + `pN^-N^+` - - ``use_magma`` -- boolean (default: ``False``). If True, uses Magma - for quaternion arithmetic. + - ``use_magma`` -- boolean (default: ``False``); if True, uses Magma + for quaternion arithmetic - - ``magma_session`` -- (default: None). If specified, the Magma session - to use. + - ``magma_session`` -- (default: ``None``) if specified, the Magma session + to use EXAMPLES: @@ -1551,7 +1529,7 @@ def _cache_key(self): def _repr_(self): r""" - Return the representation of self as a string. + Return the representation of ``self`` as a string. EXAMPLES:: @@ -1562,7 +1540,7 @@ def _repr_(self): def __eq__(self, other): r""" - Compare self with other. + Compare ``self`` with ``other``. EXAMPLES:: @@ -1583,7 +1561,7 @@ def __eq__(self, other): def __ne__(self, other): r""" - Compare self with other. + Compare ``self`` with ``other``. EXAMPLES:: @@ -1610,9 +1588,7 @@ def get_vertex_dict(self): This function returns the vertices of the quotient viewed as a dict. - OUTPUT: - - A python dict with the vertices of the quotient. + OUTPUT: a Python dict with the vertices of the quotient EXAMPLES:: @@ -1632,10 +1608,6 @@ def get_vertex_list(self): r""" Return a list of the vertices of the quotient. - OUTPUT: - - - A list with the vertices of the quotient. - EXAMPLES:: sage: X = BruhatTitsQuotient(37,3) @@ -1653,16 +1625,11 @@ def get_edge_list(self): Return a list of ``Edge`` which represent a fundamental domain inside the Bruhat-Tits tree for the quotient. - OUTPUT: - - A list of ``Edge``. - EXAMPLES:: sage: X = BruhatTitsQuotient(37,3) sage: len(X.get_edge_list()) 8 - """ try: return self._edge_list @@ -1677,10 +1644,6 @@ def get_list(self): together with a list of the opposite edges. This is used to work with automorphic forms. - OUTPUT: - - A list of ``Edge``. - EXAMPLES:: sage: X = BruhatTitsQuotient(37,3) @@ -1793,9 +1756,7 @@ def e3(self): e_k =\prod_{\ell\mid pN^-}\left(1-\left(\frac{-3}{\ell}\right)\right)\prod_{\ell \| N^+}\left(1+\left(\frac{-3}{\ell}\right)\right)\prod_{\ell^2\mid N^+} \nu_\ell(3) - OUTPUT: - - an integer + OUTPUT: integer EXAMPLES:: @@ -1815,9 +1776,7 @@ def e4(self): e_k =\prod_{\ell\mid pN^-}\left(1-\left(\frac{-k}{\ell}\right)\right)\prod_{\ell \| N^+}\left(1+\left(\frac{-k}{\ell}\right)\right)\prod_{\ell^2\mid N^+} \nu_\ell(k) - OUTPUT: - - an integer + OUTPUT: integer EXAMPLES:: @@ -1831,11 +1790,9 @@ def e4(self): @lazy_attribute def mu(self): """ - Compute the mu invariant of self. - - OUTPUT: + Compute the mu invariant of ``self``. - An integer. + OUTPUT: integer EXAMPLES:: @@ -1871,9 +1828,7 @@ def get_num_ordered_edges(self): the formula relating the genus `g` with the number of vertices `V` and that of unordered edges `E/2`: `E = 2(g + V - 1)`. - OUTPUT: - - - An integer + OUTPUT: integer EXAMPLES:: @@ -1888,9 +1843,7 @@ def genus_no_formula(self): Compute the genus of the quotient from the data of the quotient graph. This should agree with self.genus(). - OUTPUT: - - An integer + OUTPUT: integer EXAMPLES:: @@ -1914,15 +1867,13 @@ def genus(self): INPUT: - - level: Integer (default: None) a level. By default, use that + - ``level`` -- integer (default: ``None``); a level. By default, use that of ``self``. - - Nplus: Integer (default: None) a conductor. By default, use + - ``Nplus`` -- integer (default: ``None``); a conductor. By default, use that of ``self``. - OUTPUT: - - An integer equal to the genus + OUTPUT: integer equal to the genus EXAMPLES:: @@ -1941,9 +1892,7 @@ def dimension_harmonic_cocycles(self, k, lev=None, Nplus=None, Compute the dimension of the space of harmonic cocycles of weight `k` on ``self``. - OUTPUT: - - An integer equal to the dimension + OUTPUT: integer equal to the dimension EXAMPLES:: @@ -2014,9 +1963,7 @@ def Nplus(self): r""" Return the tame level `N^+`. - OUTPUT: - - An integer equal to `N^+`. + OUTPUT: integer equal to `N^+` EXAMPLES:: @@ -2066,9 +2013,7 @@ def prime(self): r""" Return the prime one is working with. - OUTPUT: - - An integer equal to the fixed prime `p` + OUTPUT: integer equal to the fixed prime `p` EXAMPLES:: @@ -2082,9 +2027,7 @@ def get_graph(self): r""" Return the quotient graph (and compute it if needed). - OUTPUT: - - A graph representing the quotient of the Bruhat-Tits tree. + OUTPUT: a graph representing the quotient of the Bruhat-Tits tree EXAMPLES:: @@ -2102,9 +2045,7 @@ def get_fundom_graph(self): r""" Return the fundamental domain (and computes it if needed). - OUTPUT: - - A fundamental domain for the action of `\Gamma`. + OUTPUT: a fundamental domain for the action of `\Gamma` EXAMPLES:: @@ -2122,9 +2063,7 @@ def plot(self, *args, **kwargs): r""" Plot the quotient graph. - OUTPUT: - - A plot of the quotient graph + OUTPUT: a plot of the quotient graph EXAMPLES:: @@ -2155,9 +2094,7 @@ def plot_fundom(self, *args, **kwargs): r""" Plot a fundamental domain. - OUTPUT: - - A plot of the fundamental domain. + OUTPUT: a plot of the fundamental domain EXAMPLES:: @@ -2191,12 +2128,10 @@ def is_admissible(self, D): INPUT: - - ``D`` -- an integer whose squarefree part will define the + - ``D`` -- integer whose squarefree part will define the quadratic field - OUTPUT: - - A boolean describing whether the quadratic field is admissible + OUTPUT: boolean describing whether the quadratic field is admissible EXAMPLES:: @@ -2220,11 +2155,9 @@ def _local_splitting_map(self, prec): INPUT: - - ``prec`` -- Integer. The precision of the splitting. + - ``prec`` -- integer; the precision of the splitting - OUTPUT: - - A function giving the splitting. + OUTPUT: a function giving the splitting EXAMPLES:: @@ -2249,11 +2182,9 @@ def _local_splitting(self, prec): INPUT: - - ``prec`` -- Integer. The precision of the splitting. - - OUTPUT: + - ``prec`` -- integer; the precision of the splitting - - Matrices `I`, `J`, `K` giving the splitting. + OUTPUT: matrices `I`, `J`, `K` giving the splitting EXAMPLES:: @@ -2304,7 +2235,7 @@ def _compute_embedding_matrix(self, prec, force_computation=False): INPUT: - - ``prec`` -- Integer. The precision of the embedding matrix. + - ``prec`` -- integer; the precision of the embedding matrix EXAMPLES: @@ -2454,18 +2385,16 @@ def get_embedding_matrix(self, prec=None, exact=False): INPUT: - - ``exact`` boolean (Default: ``False``). If ``True``, return an + - ``exact`` -- boolean (default: ``False``); if ``True``, return an embedding into a matrix algebra with coefficients in a number field. Otherwise, embed into matrices over `p`-adic numbers. - - ``prec`` Integer (Default: ``None``). If specified, return the + - ``prec`` -- integer (default: ``None``); if specified, return the matrix with precision ``prec``. Otherwise, return the cached matrix (with the current working precision). - OUTPUT: - - - A 4x4 matrix representing the embedding. + OUTPUT: a 4x4 matrix representing the embedding EXAMPLES:: @@ -2525,11 +2454,11 @@ def embed_quaternion(self, g, exact=False, prec=None): INPUT: - - ``g`` a row vector of size `4` whose entries represent a - quaternion in our basis. + - ``g`` -- a row vector of size `4` whose entries represent a + quaternion in our basis - - ``exact`` boolean (default: ``False``) If True, tries to embed - ``g`` into a matrix algebra over a number field. If False, + - ``exact`` -- boolean (default: ``False``); if True, tries to embed + ``g`` into a matrix algebra over a number field. If ``False``, the target is the matrix algebra over `\QQ_p`. OUTPUT: @@ -2682,9 +2611,7 @@ def get_quaternion_algebra(self): r""" Return the underlying quaternion algebra. - OUTPUT: - - The underlying definite quaternion algebra + OUTPUT: the underlying definite quaternion algebra EXAMPLES:: @@ -2703,9 +2630,7 @@ def get_eichler_order(self, magma=False, force_computation=False): r""" Return the underlying Eichler order of level `N^+`. - OUTPUT: - - An Eichler order. + OUTPUT: an Eichler order EXAMPLES:: @@ -2734,9 +2659,7 @@ def get_maximal_order(self, magma=False, force_computation=False): Return the underlying maximal order containing the Eichler order. - OUTPUT: - - A maximal order. + OUTPUT: a maximal order EXAMPLES:: @@ -2792,9 +2715,7 @@ def get_eichler_order_basis(self): r""" Return a basis for the global Eichler order. - OUTPUT: - - Basis for the underlying Eichler order of level Nplus. + OUTPUT: basis for the underlying Eichler order of level Nplus EXAMPLES:: @@ -2815,9 +2736,7 @@ def get_eichler_order_quadform(self): Eichler order of level ``Nplus``. Required for finding elements in the arithmetic subgroup Gamma. - OUTPUT: - - The norm form of the underlying Eichler order + OUTPUT: the norm form of the underlying Eichler order EXAMPLES:: @@ -2841,9 +2760,7 @@ def get_eichler_order_quadmatrix(self): This function returns the matrix of the quadratic form of the underlying Eichler order in the fixed basis. - OUTPUT: - - A 4x4 integral matrix describing the norm form. + OUTPUT: a 4x4 integral matrix describing the norm form EXAMPLES:: @@ -2975,7 +2892,7 @@ def _get_hecke_data(self, l): INPUT: - - ``l`` -- a prime l. + - ``l`` -- a prime l EXAMPLES:: @@ -2997,7 +2914,7 @@ def _get_hecke_data(self, l): while not V: V = [g for g in self._find_elements_in_order(l * p ** nninc) if prod([self._character(ZZ((v * Matrix(ZZ, 4, 1, g))[0, 0])) - / self._character((p ** (nninc // 2))) + / self._character(p ** (nninc // 2)) for v in self.get_extra_embedding_matrices()]) == 1] if not V: nninc += 2 @@ -3010,7 +2927,7 @@ def _get_hecke_data(self, l): letters = self.get_nontorsion_generators() letters += [g for g in self._find_elements_in_order(1) if prod([self._character(ZZ((v * Matrix(ZZ, 4, 1, g))[0, 0])) - / self._character((p ** (nninc // 2))) + / self._character(p ** (nninc // 2)) for v in self.get_extra_embedding_matrices()]) == 1] n_iters = 0 @@ -3069,15 +2986,15 @@ def _find_equivalent_vertex(self, v0, V=None, valuation=None): INPUT: - ``v0`` -- a 2x2 matrix in `\ZZ_p` representing a - vertex in the Bruhat-Tits tree. + vertex in the Bruhat-Tits tree - - ``V`` -- list (Default: None) If a list of Vertex is given, + - ``V`` -- list (default: ``None``); if a list of Vertex is given, restrict the search to the vertices in ``V``. Otherwise use all the vertices in a fundamental domain. - - ``valuation`` -- an integer (Default: None): The valuation + - ``valuation`` -- integer (default: ``None``); the valuation of the determinant of ``v0``, if known (otherwise it is - calculated). + calculated) OUTPUT: @@ -3117,13 +3034,13 @@ def _find_equivalent_edge(self, e0, E=None, valuation=None): INPUT: - ``e0`` -- a 2x2 matrix in `\ZZ_p` representing an - edge in the Bruhat-Tits tree. + edge in the Bruhat-Tits tree - - ``E`` -- list (Default: None) If a list of Edge is given, + - ``E`` -- list (default: ``None``); if a list of Edge is given, restrict the search to the vertices in ``E``. Otherwise use all the edges in a fundamental domain. - - ``valuation`` -- an integer (Default: None): The valuation + - ``valuation`` -- integer (default: ``None``); the valuation of the determinant of ``e0``, if known (otherwise it is calculated). @@ -3167,11 +3084,9 @@ def fundom_rep(self, v1): INPUT: - - ``v1`` -- a 2x2 matrix representing a normalized vertex. + - ``v1`` -- a 2x2 matrix representing a normalized vertex - OUTPUT: - - A ``Vertex`` equivalent to ``v1``, in the fundamental domain. + OUTPUT: a ``Vertex`` equivalent to ``v1``, in the fundamental domain EXAMPLES:: @@ -3206,18 +3121,16 @@ def _find_lattice(self, v1, v2, as_edges, m): INPUT: - - ``v1``, ``v2`` -- 2x2 matrices. They represent either a pair - of normalized vertices or a pair of normalized edges. + - ``v1``, ``v2`` -- 2x2 matrices; they represent either a pair + of normalized vertices or a pair of normalized edges - - ``as_edges`` -- boolean. If True, the inputs will be - considered as edges instead of vertices. + - ``as_edges`` -- boolean; if ``True``, the inputs will be + considered as edges instead of vertices - - ``m`` -- integer -- The valuation of the determinant of - ``v1``*``v2``. + - ``m`` -- integer; the valuation of the determinant of + ``v1``*``v2`` - OUTPUT: - - A 4x4 integer matrix whose columns encode a lattice and a 4x4 integer matrix encoding a quadratic form. + OUTPUT: a 4x4 integer matrix whose columns encode a lattice and a 4x4 integer matrix encoding a quadratic form EXAMPLES:: @@ -3252,9 +3165,9 @@ def _stabilizer(self, e, as_edge=True): INPUT: - - ``e`` -- A 2x2 matrix representing an edge or vertex + - ``e`` -- a 2x2 matrix representing an edge or vertex - - ``as_edge`` -- Boolean (Default = True). Determines whether + - ``as_edge`` -- boolean (default: ``True``); determines whether ``e`` is treated as an edge or vertex OUTPUT: @@ -3301,18 +3214,19 @@ def _nebentype_check(self, vec, twom, E, A, flag=2): INPUT: - - ``vec`` -- 4x1 integer matrix. It encodes the quaternion to - test in the basis defined by the columns of E. + - ``vec`` -- 4x1 integer matrix; it encodes the quaternion to + test in the basis defined by the columns of E - - ``twom`` -- An integer. + - ``twom`` -- integer - - ``E`` -- 4x4 integer matrix. Its columns should form a - basis for an order in the quaternion algebra. + - ``E`` -- 4x4 integer matrix; its columns should form a + basis for an order in the quaternion algebra - - ``A`` -- 4x4 integer matrix. It encodes the quadratic form on the order defined by the columns of E. + - ``A`` -- 4x4 integer matrix; it encodes the quadratic form on the + order defined by the columns of E - - ``flag`` -- integer (Default = 0). Passed to Pari for finding - minimal elements in a positive definite lattice. + - ``flag`` -- integer (default: 0); Passed to Pari for finding + minimal elements in a positive definite lattice OUTPUT: @@ -3370,19 +3284,19 @@ def _are_equivalent(self, v1, v2, as_edges=False, twom=None, - ``v1``, ``v2`` -- two 2x2 integral matrices representing either vertices or edges - - ``as_edges`` -- boolean (Default: False). Tells whether the - matrices should be interpreted as edges (if true), or as - vertices (if false) + - ``as_edges`` -- boolean (default: ``False``); whether the + matrices should be interpreted as edges (if ``True``), or as + vertices (if ``False``) - - ``twom`` -- integer (Default: None) If specified, + - ``twom`` -- integer (default: ``None``); if specified, indicates the valuation of the determinant of ``v1`` `\times` ``v2``. OUTPUT: - If the objects are equivalent, returns an element of - the arithmetic group Gamma that takes ``v1`` to ``v2``. - Otherwise returns False. + If the objects are equivalent, returns an element of + the arithmetic group `\Gamma` that takes ``v1`` to ``v2``. + Otherwise returns ``False``. EXAMPLES:: @@ -3514,9 +3428,7 @@ def _conv(self, v): Return a quaternion having coordinates in the fixed basis for the order given by ``v``. - OUTPUT: - - A quaternion. + OUTPUT: a quaternion EXAMPLES:: @@ -3541,13 +3453,13 @@ def _find_elements_in_order(self, norm, trace=None, primitive=False): INPUT: - - ``norm`` -- integer. The required reduced norm. + - ``norm`` -- integer; the required reduced norm - - ``trace`` -- integer (Default: None). If specified, returns - elements only reduced trace ``trace``. + - ``trace`` -- integer (default: ``None``); if specified, returns + elements only reduced trace ``trace`` - - ``primitive`` boolean (Default: False). If True, return only - elements that cannot be divided by `p`. + - ``primitive`` -- boolean (default: ``False``); if ``True``, return only + elements that cannot be divided by `p` EXAMPLES:: @@ -3572,7 +3484,7 @@ def _compute_quotient(self, check=True): INPUT: - - ``check`` -- Boolean (Default = True). + - ``check`` -- boolean (default: ``True``) EXAMPLES:: @@ -3728,12 +3640,10 @@ def harmonic_cocycle_from_elliptic_curve(self, E, prec=None): - ``E`` -- an elliptic curve over the rational numbers - - ``prec`` -- (default: None) If specified, the harmonic cocycle will take values + - ``prec`` -- (default: ``None``) if specified, the harmonic cocycle will take values in `\QQ_p` with precision ``prec``. Otherwise it will take values in `\ZZ`. - OUTPUT: - - A harmonic cocycle attached via modularity to the given elliptic curve. + OUTPUT: a harmonic cocycle attached via modularity to the given elliptic curve EXAMPLES:: @@ -3783,16 +3693,16 @@ def harmonic_cocycles(self, k, prec=None, basis_matrix=None, base_field=None): INPUT: - - ``k`` -- integer -- The weight. It must be even. + - ``k`` -- integer; the weight. It must be even. - - ``prec`` -- integer (default: None). If specified, the + - ``prec`` -- integer (default: ``None``); if specified, the precision for the coefficient module - - ``basis_matrix`` -- a matrix (default: None). + - ``basis_matrix`` -- a matrix (default: ``None``) - - ``base_field`` -- a ring (default: None) + - ``base_field`` -- a ring (default: ``None``) - OUTPUT: A space of harmonic cocycles + OUTPUT: a space of harmonic cocycles EXAMPLES:: @@ -3812,23 +3722,23 @@ def padic_automorphic_forms(self, U, prec=None, t=None, R=None, overconvergent=F INPUT: - - ``U`` -- A distributions module or an integer. If ``U`` is a + - ``U`` -- a distributions module or an integer. If ``U`` is a distributions module then this creates the relevant space of automorphic forms. If ``U`` is an integer then the coefficients are the (`U-2`)nd power of the symmetric representation of `GL_2(\QQ_p)`. - - ``prec`` -- A precision (default : None). If not None should - be a positive integer. + - ``prec`` -- a precision (default: ``None``). if not ``None`` should + be a positive integer - - ``t`` -- (default : None). The number of additional moments to store. If None, determine - it automatically from ``prec``, ``U`` and the ``overconvergent`` flag. + - ``t`` -- (default: ``None``) the number of additional moments to store. If ``None``, determine + it automatically from ``prec``, ``U`` and the ``overconvergent`` flag - - ``R`` -- (default : None). If specified, coefficient field of the automorphic forms. + - ``R`` -- (default: ``None``) if specified, coefficient field of the automorphic forms. If not specified it defaults to the base ring of the distributions ``U``, or to `\QQ_p` with the working precision ``prec``. - - ``overconvergent`` -- Boolean (default = False). If True, will construct overconvergent + - ``overconvergent`` -- boolean (default: ``False``); if ``True``, will construct overconvergent `p`-adic automorphic forms. Otherwise it constructs the finite dimensional space of `p`-adic automorphic forms which is isomorphic to the space of harmonic cocycles. diff --git a/src/sage/modular/btquotients/pautomorphicform.py b/src/sage/modular/btquotients/pautomorphicform.py index 992d5990b2b..53a7d2ac6f6 100644 --- a/src/sage/modular/btquotients/pautomorphicform.py +++ b/src/sage/modular/btquotients/pautomorphicform.py @@ -94,9 +94,7 @@ def __call__(self, g): - ``g`` -- a 2x2 matrix - OUTPUT: - - A 4-tuple encoding the entries of ``g``. + OUTPUT: a 4-tuple encoding the entries of ``g`` EXAMPLES:: @@ -218,9 +216,7 @@ def _add_(self, g): - ``g`` -- a harmonic cocycle - OUTPUT: - - A harmonic cocycle + OUTPUT: a harmonic cocycle EXAMPLES:: @@ -241,9 +237,7 @@ def _sub_(self, g): - ``g`` -- a harmonic cocycle - OUTPUT: - - A harmonic cocycle + OUTPUT: a harmonic cocycle EXAMPLES:: @@ -266,9 +260,7 @@ def _lmul_(self, a): - ``a`` -- a ring element - OUTPUT: - - A harmonic cocycle + OUTPUT: a harmonic cocycle EXAMPLES:: @@ -284,11 +276,11 @@ def _lmul_(self, a): def _richcmp_(self, other, op): r""" - General comparison method for ``HarmonicCocycles`` + General comparison method for ``HarmonicCocycles``. INPUT: - - ``other`` -- Another harmonic cocycle + - ``other`` -- another harmonic cocycle EXAMPLES:: @@ -366,9 +358,7 @@ def valuation(self): Return the valuation of the cocycle, defined as the minimum of the values it takes on a set of representatives. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -478,20 +468,18 @@ def riemann_sum(self, f, center=1, level=0, E=None): INPUT: - - ``f`` -- a function on `\mathbf{P}^1(\QQ_p)`. + - ``f`` -- a function on `\mathbf{P}^1(\QQ_p)` - - ``center`` -- An integer (default = 1). Center of integration. + - ``center`` -- integer (default: 1); Center of integration - - ``level`` -- An integer (default = 0). Determines the size of + - ``level`` -- integer (default: 0); Determines the size of the covering when computing the Riemann sum. Runtime is exponential in the level. - - ``E`` -- A list of edges (default = None). They should describe - a covering of `\mathbf{P}^1(\QQ_p)`. + - ``E`` -- list of edges (default: ``None``); They should describe + a covering of `\mathbf{P}^1(\QQ_p)` - OUTPUT: - - A `p`-adic number. + OUTPUT: a `p`-adic number EXAMPLES:: @@ -536,14 +524,12 @@ def modular_form(self, z=None, level=0): INPUT: - ``z`` -- an element in the quadratic unramified extension of - `\QQ_p` that is not contained in `\QQ_p` (default = None). - - - ``level`` -- an integer. How fine of a mesh should the Riemann - sum use. + `\QQ_p` that is not contained in `\QQ_p` (default: ``None``) - OUTPUT: + - ``level`` -- integer; how fine of a mesh should the Riemann + sum use - An element of the quadratic unramified extension of `\QQ_p`. + OUTPUT: an element of the quadratic unramified extension of `\QQ_p` EXAMPLES:: @@ -578,7 +564,6 @@ def modular_form(self, z=None, level=0): sage: g = A.lift(g0).modular_form(method='moments') sage: (c*x + d)^4 * f(x) == f((a*x + b)/(c*x + d)) True - """ return self.derivative(z, level, order=0) @@ -602,13 +587,13 @@ def derivative(self, z=None, level=0, order=1): INPUT: - ``z`` -- an element in the quadratic unramified extension of - `\QQ_p` that is not contained in `\QQ_p` (default = None). If ``z - = None`` then a function encoding the derivative is returned. + `\QQ_p` that is not contained in `\QQ_p` (default: ``None``); if + ``z = None`` then a function encoding the derivative is returned. - - ``level`` -- an integer. How fine of a mesh should the Riemann - sum use. + - ``level`` -- integer; how fine of a mesh should the Riemann + sum use - - ``order`` -- an integer. How many derivatives to take. + - ``order`` -- integer; how many derivatives to take OUTPUT: @@ -627,7 +612,6 @@ def derivative(self, z=None, level=0, order=1): (2*a + 2)*3 + (a + 2)*3^2 + 2*a*3^3 + 2*3^4 + O(3^5) sage: b.derivative(a,level=2,order=1) (2*a + 2)*3 + 2*a*3^2 + 3^3 + a*3^4 + O(3^5) - """ def F(z): R = PolynomialRing(z.parent(), 'x,y').fraction_field() @@ -653,7 +637,7 @@ def F(z): class BruhatTitsHarmonicCocycles(AmbientHeckeModule, UniqueRepresentation): r""" - Ensure unique representation + Ensure unique representation. EXAMPLES:: @@ -673,16 +657,16 @@ def __classcall__(cls, X, k, prec=None, basis_matrix=None, base_field=None): INPUT: - - ``X`` -- A BruhatTitsQuotient object + - ``X`` -- a BruhatTitsQuotient object - - ``k`` -- integer -- The weight. It must be even. + - ``k`` -- integer; the weight. It must be even. - - ``prec`` -- integer (default: None). If specified, the + - ``prec`` -- integer (default: ``None``); if specified, the precision for the coefficient module - - ``basis_matrix`` -- a matrix (default: None). + - ``basis_matrix`` -- a matrix (default: ``None``) - - ``base_field`` -- a ring (default: None) + - ``base_field`` -- a ring (default: ``None``) EXAMPLES:: @@ -785,9 +769,7 @@ def base_extend(self, base_ring): - ``base_ring`` -- a ring that has a coerce map from the current base ring - OUTPUT: - - A new space of HarmonicCocycles with the base extended. + OUTPUT: a new space of HarmonicCocycles with the base extended EXAMPLES:: @@ -813,9 +795,7 @@ def change_ring(self, new_base_ring): - ``new_base_ring`` -- a ring that has a coerce map from the current base ring - OUTPUT: - - New space of HarmonicCocycles with different base ring + OUTPUT: new space of HarmonicCocycles with different base ring EXAMPLES:: @@ -826,7 +806,6 @@ def change_ring(self, new_base_ring): sage: H1 = H.base_extend(Qp(5,prec=15)) # indirect doctest sage: H1.base_ring() 5-adic Field with capped relative precision 15 - """ if not new_base_ring.has_coerce_map_from(self.base_ring()): raise ValueError("No coercion defined") @@ -841,9 +820,7 @@ def rank(self): r""" Return the rank (dimension) of ``self``. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -863,13 +840,11 @@ def submodule(self, v, check=False): INPUT: - - ``v`` -- Submodule of self.free_module(). - - - ``check`` -- Boolean (default = False). + - ``v`` -- submodule of ``self.free_module()`` - OUTPUT: + - ``check`` -- boolean (default: ``False``) - Subspace of harmonic cocycles. + OUTPUT: subspace of harmonic cocycles EXAMPLES:: @@ -891,9 +866,7 @@ def is_simple(self): r""" Whether ``self`` is irreducible. - OUTPUT: - - Boolean. True if and only if ``self`` is irreducible. + OUTPUT: boolean; ``True`` if and only if ``self`` is irreducible EXAMPLES:: @@ -914,7 +887,7 @@ def is_simple(self): def _repr_(self): r""" - This returns the representation of self as a string. + This returns the representation of ``self`` as a string. EXAMPLES:: @@ -944,11 +917,9 @@ def _latex_(self): def _an_element_(self): r""" - Return an element of the ambient space + Return an element of the ambient space. - OUTPUT: - - A harmonic cocycle in self. + OUTPUT: a harmonic cocycle in self EXAMPLES:: @@ -962,12 +933,10 @@ def _an_element_(self): def _coerce_map_from_(self, S): r""" Can coerce from other BruhatTitsHarmonicCocycles or from - pAdicAutomorphicForms, also from 0 + pAdicAutomorphicForms, also from 0. - OUTPUT: - - Boolean. True if and only if ``self`` is a space of - BruhatTitsHarmonicCocycles or pAdicAutomorphicForms. + OUTPUT: boolean; ``True`` if and only if ``self`` is a space of + BruhatTitsHarmonicCocycles or pAdicAutomorphicForms EXAMPLES:: @@ -991,11 +960,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- a BruhatTitsHarmonicCocycles class. + - ``other`` -- a BruhatTitsHarmonicCocycles class - OUTPUT: - - A boolean value + OUTPUT: boolean EXAMPLES:: @@ -1018,11 +985,9 @@ def __ne__(self, other): INPUT: - - ``other`` -- a BruhatTitsHarmonicCocycles class. - - OUTPUT: + - ``other`` -- a BruhatTitsHarmonicCocycles class - A boolean value + OUTPUT: boolean EXAMPLES:: @@ -1054,11 +1019,9 @@ def _element_constructor_(self, x): INPUT: - - ``x`` -- an object coercible into a harmonic cocycle. - - OUTPUT: + - ``x`` -- an object coercible into a harmonic cocycle - A harmonic cocycle. + OUTPUT: a harmonic cocycle EXAMPLES:: @@ -1094,11 +1057,9 @@ def _element_constructor_(self, x): def free_module(self): r""" - Return the underlying free module + Return the underlying free module. - OUTPUT: - - A free module. + OUTPUT: a free module EXAMPLES:: @@ -1120,9 +1081,7 @@ def character(self): r""" The trivial character. - OUTPUT: - - The identity map. + OUTPUT: the identity map EXAMPLES:: @@ -1142,11 +1101,9 @@ def embed_quaternion(self, g, scale=1, exact=None): INPUT: - - ``g`` -- A quaternion, expressed as a 4x1 matrix. + - ``g`` -- a quaternion, expressed as a 4x1 matrix - OUTPUT: - - A 2x2 matrix with `p`-adic entries. + OUTPUT: a 2x2 matrix with `p`-adic entries EXAMPLES:: @@ -1204,7 +1161,7 @@ def basis_matrix(self): d = self._k - 1 for e in self._E: try: - g = next((g for g in S[e.label] if g[2])) + g = next(g for g in S[e.label] if g[2]) C = self._U.acting_matrix(self._Sigma0(self.embed_quaternion(g[0])), d).transpose() # Warning - Need to allow the check = True C -= self._U.acting_matrix(self._Sigma0(Matrix(QQ, 2, 2, p ** g[1])), d).transpose() # Warning - Need to allow the check = True stab_conds.append([e.label, C]) @@ -1255,18 +1212,18 @@ def basis_matrix(self): def __apply_atkin_lehner(self, q, f): r""" - Apply an Atkin-Lehner involution to a harmonic cocycle + Apply an Atkin-Lehner involution to a harmonic cocycle. INPUT: - - ``q`` -- an integer dividing the full level p*Nminus*Nplus + - ``q`` -- integer dividing the full level ``p*Nminus*Nplus`` - ``f`` -- a harmonic cocycle OUTPUT: - - The harmonic cocycle obtained by hitting ``f`` with the - Atkin-Lehner at ``q`` + The harmonic cocycle obtained by hitting ``f`` with the + Atkin-Lehner at ``q``. EXAMPLES:: @@ -1297,14 +1254,14 @@ def __apply_hecke_operator(self, l, f): INPUT: - - ``l`` -- an integer + - ``l`` -- integer - ``f`` -- a harmonic cocycle OUTPUT: - - A harmonic cocycle which is the result of applying the lth - Hecke operator to ``f`` + A harmonic cocycle which is the result of applying the `l`-th + Hecke operator to ``f``. EXAMPLES:: @@ -1341,13 +1298,13 @@ def _compute_atkin_lehner_matrix(self, d): INPUT: - - ``d`` -- an integer dividing p*Nminus*Nplus, where these - quantities are associated to the BruhatTitsQuotient self._X + - ``d`` -- integer dividing ``p*Nminus*Nplus``, where these + quantities are associated to the BruhatTitsQuotient ``self._X`` OUTPUT: - - The matrix of the Atkin-Lehner involution at ``d`` in the basis given by - self.basis_matrix + The matrix of the Atkin-Lehner involution at ``d`` in the basis given by + ``self.basis_matrix``. EXAMPLES:: @@ -1367,12 +1324,12 @@ def _compute_hecke_matrix_prime(self, l): INPUT: - - ``l`` -- a prime integer + - ``l`` -- prime integer OUTPUT: - - The matrix of `T_l` acting on the cocycles in the basis given by - self.basis_matrix + The matrix of `T_l` acting on the cocycles in the basis given by + ``self.basis_matrix``. EXAMPLES:: @@ -1393,11 +1350,9 @@ def __compute_operator_matrix(self, T): INPUT: - - ``T`` -- A linear function on the space of harmonic cocycles. - - OUTPUT: + - ``T`` -- a linear function on the space of harmonic cocycles - The matrix of ``T`` acting on the space of harmonic cocycles. + OUTPUT: the matrix of ``T`` acting on the space of harmonic cocycles EXAMPLES:: @@ -1440,11 +1395,9 @@ def __compute_operator_matrix(self, T): # # INPUT: # -# - ``x`` -- integer (default: 1) the description of the -# argument x goes here. If it contains multiple lines, all -# the lines after the first need to be indented. +# - ``x`` -- integer (default: 1) # -# - ``y`` -- integer (default: 2) the ... +# - ``y`` -- integer (default: 2) # # EXAMPLES:: # @@ -1467,9 +1420,9 @@ def __compute_operator_matrix(self, T): # # - ``ambient_module`` -- BruhatTitsHarmonicCocycles # -# - ``submodule`` -- submodule of the ambient space. +# - ``submodule`` -- submodule of the ambient space # -# - ``check`` -- (default: ``False``) whether to check that the +# - ``check`` -- boolean (default: ``False``); whether to check that the # submodule is Hecke equivariant # # EXAMPLES:: @@ -1536,7 +1489,7 @@ class pAdicAutomorphicFormElement(ModuleElement): INPUT: - - ``vec`` -- A preformatted list of data + - ``vec`` -- a preformatted list of data EXAMPLES:: @@ -1555,7 +1508,7 @@ class pAdicAutomorphicFormElement(ModuleElement): """ def __init__(self, parent, vec): """ - Create a pAdicAutomorphicFormElement + Create a pAdicAutomorphicFormElement. EXAMPLES:: @@ -1577,9 +1530,7 @@ def _add_(self, g): - ``g`` -- a `p`-adic automorphic form - OUTPUT: - - - the result of adding ``g`` to self + OUTPUT: the result of adding ``g`` to ``self`` EXAMPLES:: @@ -1602,9 +1553,7 @@ def _sub_(self, g): - ``g`` -- a `p`-adic automorphic form - OUTPUT: - - - the result of subtracting ``g`` from self + OUTPUT: the result of subtracting ``g`` from ``self`` EXAMPLES:: @@ -1623,11 +1572,11 @@ def _sub_(self, g): def _richcmp_(self, other, op): r""" - Test for equality of pAdicAutomorphicForm elements + Test for equality of pAdicAutomorphicForm elements. INPUT: - - ``other`` -- Another `p`-automorphic form + - ``other`` -- another `p`-automorphic form EXAMPLES:: @@ -1652,9 +1601,7 @@ def __bool__(self): """ Tell whether the form is zero or not. - OUTPUT: - - Boolean. ``True`` if self is zero, ``False`` otherwise. + OUTPUT: boolean; whether ``self`` is zero EXAMPLES:: @@ -1678,9 +1625,7 @@ def __getitem__(self, e1): - ``e1`` -- a matrix in `GL_2(\QQ_p)` - OUTPUT: - - - the value of self evaluated on ``e1`` + OUTPUT: the value of ``self`` evaluated on ``e1`` EXAMPLES:: @@ -1701,9 +1646,7 @@ def evaluate(self, e1): - ``e1`` -- a matrix in `GL_2(\QQ_p)` - OUTPUT: - - - the value of self evaluated on ``e1`` + OUTPUT: the value of ``self`` evaluated on ``e1`` EXAMPLES:: @@ -1730,7 +1673,7 @@ def _lmul_(self, a): INPUT: - - a scalar + - ``a`` -- a scalar EXAMPLES:: @@ -1750,15 +1693,11 @@ def _lmul_(self, a): def _repr_(self): r""" - This returns the representation of self as a string. + This returns the representation of ``self`` as a string. - If self corresponds to a modular form of weight `k`, then the + If ``self`` corresponds to a modular form of weight `k`, then the cohomological weight is `k-2`. - OUTPUT: - - A string. - EXAMPLES:: sage: X = BruhatTitsQuotient(17,3) @@ -1775,9 +1714,7 @@ def valuation(self): valuations of the values that it takes on a set of edge representatives. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -1821,7 +1758,6 @@ def _improve(self, hc): - Cameron Franc (2012-02-20) - Marc Masdeu - """ MMM = self.parent() U = MMM._U @@ -1857,14 +1793,14 @@ def integrate(self, f, center=1, level=0, method='moments'): INPUT: - - ``f`` -- An analytic function. + - ``f`` -- an analytic function - ``center`` -- 2x2 matrix over `\QQ_p` (default: 1) - ``level`` -- integer (default: 0) - - ``method`` -- string (default: 'moments'). Which method of - integration to use. Either 'moments' or 'riemann_sum'. + - ``method`` -- string (default: ``'moments'``); which method of + integration to use. Either ``'moments'`` or ``'riemann_sum'``. EXAMPLES: @@ -1940,22 +1876,22 @@ def modular_form(self, z=None, level=0, method='moments'): INPUT: - - ``z`` -- (default: None). If specified, returns the value of + - ``z`` -- (default: ``None``) if specified, returns the value of the form at the point ``z`` in the `p`-adic upper half - plane. + plane - - ``level`` -- integer (default: 0). If ``method`` is + - ``level`` -- integer (default: 0); if ``method`` is 'riemann_sum', will use a covering of `P^1(\QQ_p)` with - balls of size `p^-\mbox{level}`. + balls of size `p^-\mbox{level}` - - ``method`` -- string (default: ``moments``). It must be - either ``moments`` or ``riemann_sum``. + - ``method`` -- string (default: ``'moments'``); it must be + either ``'moments'`` or ``'riemann_sum'`` OUTPUT: - - A function from the `p`-adic upper half plane to `\CC_p`. If - an argument ``z`` was passed, returns instead the value at - that point. + A function from the `p`-adic upper half plane to `\CC_p`. If + an argument ``z`` was passed, returns instead the value at + that point. EXAMPLES: @@ -1999,24 +1935,24 @@ def derivative(self, z=None, level=0, method='moments', order=1): INPUT: - - ``z`` -- (default: None). If specified, evaluates the derivative - at the point ``z`` in the `p`-adic upper half plane. + - ``z`` -- (default: ``None``) if specified, evaluates the derivative + at the point ``z`` in the `p`-adic upper half plane - - ``level`` -- integer (default: 0). If ``method`` is + - ``level`` -- integer (default: 0); if ``method`` is 'riemann_sum', will use a covering of `P^1(\QQ_p)` with balls of size `p^-\mbox{level}`. - - ``method`` -- string (default: ``moments``). It must be - either ``moments`` or ``riemann_sum``. + - ``method`` -- string (default: ``'moments'``); it must be + either ``'moments'`` or ``'riemann_sum'`` - - ``order`` -- integer (default: 1). The order of the - derivative to be computed. + - ``order`` -- integer (default: 1); the order of the + derivative to be computed OUTPUT: - - A function from the `p`-adic upper half plane to `\CC_p`. If - an argument ``z`` was passed, returns instead the value of - the derivative at that point. + A function from the `p`-adic upper half plane to `\CC_p`. If + an argument ``z`` was passed, returns instead the value of + the derivative at that point. EXAMPLES: @@ -2059,7 +1995,6 @@ def derivative(self, z=None, level=0, method='moments', order=1): sage: f = f0.derivative() sage: (c*x + d)^4*f(x)-f((a*x + b)/(c*x + d)) O(7^5) - """ def F(z, level=level, method=method): R = PolynomialRing(z.parent(), 'x,y').fraction_field() @@ -2097,22 +2032,20 @@ def coleman(self, t1, t2, E=None, method='moments', mult=False): - ``t1``, ``t2`` -- elements of `P^1(\QQ_p)` (the endpoints of integration) - - ``E`` -- (default: None). If specified, will not compute the + - ``E`` -- (default: ``None``) if specified, will not compute the covering adapted to ``t1`` and ``t2`` and instead use the given one. In that case, ``E`` should be a list of matrices corresponding to edges describing the open balls to be considered. - - ``method`` -- string (default: 'moments'). Tells which - algorithm to use (alternative is 'riemann_sum', which is + - ``method`` -- string (default: ``'moments'``); tells which + algorithm to use (alternative is ``'riemann_sum'``, which is unsuitable for computations requiring high precision) - - ``mult`` -- boolean (default: ``False``). Whether to compute the - multiplicative version. + - ``mult`` -- boolean (default: ``False``); whether to compute the + multiplicative version - OUTPUT: - - The result of the Coleman integral + OUTPUT: the result of the Coleman integral EXAMPLES:: @@ -2180,7 +2113,7 @@ def coleman(self, t1, t2, E=None, method='moments', mult=False): assert 0 value += new if mult: - value_exp *= K.teichmuller(((b - d * t1) / (b - d * t2))) ** Integer(c_e.moment(0).rational_reconstruction()) + value_exp *= K.teichmuller((b - d * t1) / (b - d * t2)) ** Integer(c_e.moment(0).rational_reconstruction()) else: print('The available methods are either "moments" or "riemann_sum". The latter is only provided for consistency check, and should not be used in practice.') @@ -2201,25 +2134,26 @@ def __classcall__(cls, domain, U, prec=None, t=None, R=None, INPUT: - - ``domain`` -- A BruhatTitsQuotient. + - ``domain`` -- a BruhatTitsQuotient - - ``U`` -- A distributions module or an integer. If ``U`` is a + - ``U`` -- a distributions module or an integer. If ``U`` is a distributions module then this creates the relevant space of automorphic forms. If ``U`` is an integer then the coefficients are the (`U-2`)nd power of the symmetric representation of `GL_2(\QQ_p)`. - - ``prec`` -- A precision (default : None). If not None should - be a positive integer. + - ``prec`` -- a precision (default: ``None``); if not ``None`` should + be a positive integer - - ``t`` -- (default : None). The number of additional moments to store. If None, determine - it automatically from ``prec``, ``U`` and the ``overconvergent`` flag. + - ``t`` -- (default: ``None``) the number of additional moments to + store. If ``None``, determine it automatically from ``prec``, ``U`` + and the ``overconvergent`` flag. - - ``R`` -- (default : None). If specified, coefficient field of the automorphic forms. + - ``R`` -- (default: ``None``) if specified, coefficient field of the automorphic forms. If not specified it defaults to the base ring of the distributions ``U``, or to `Q_p` with the working precision ``prec``. - - ``overconvergent`` -- Boolean (default = False). If True, will construct overconvergent + - ``overconvergent`` -- boolean (default: ``False``); if ``True``, will construct overconvergent `p`-adic automorphic forms. Otherwise it constructs the finite dimensional space of `p`-adic automorphic forms which is isomorphic to the space of harmonic cocycles. @@ -2246,7 +2180,7 @@ def __classcall__(cls, domain, U, prec=None, t=None, R=None, def __init__(self, domain, U, prec=None, t=None, R=None, overconvergent=False): """ - Create a space of `p`-automorphic forms + Create a space of `p`-automorphic forms. EXAMPLES:: @@ -2300,9 +2234,7 @@ def prime(self): """ Return the underlying prime. - OUTPUT: - - - ``p`` -- a prime integer + OUTPUT: ``p`` -- prime integer EXAMPLES:: @@ -2333,11 +2265,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- another space of `p`-automorphic forms. - - OUTPUT: + - ``other`` -- another space of `p`-automorphic forms - A boolean value + OUTPUT: boolean EXAMPLES:: @@ -2360,11 +2290,9 @@ def __ne__(self, other): INPUT: - - ``other`` -- another space of `p`-automorphic forms. - - OUTPUT: + - ``other`` -- another space of `p`-automorphic forms - A boolean value + OUTPUT: boolean EXAMPLES:: @@ -2392,7 +2320,7 @@ def __hash__(self): def _repr_(self): r""" - Return the representation of self as a string. + Return the representation of ``self`` as a string. EXAMPLES:: @@ -2408,15 +2336,13 @@ def _repr_(self): def _coerce_map_from_(self, S): r""" - Can coerce from other BruhatTitsHarmonicCocycles or from pAdicAutomorphicForms + Can coerce from other BruhatTitsHarmonicCocycles or from pAdicAutomorphicForms. INPUT: - ``S`` -- a BruhatTitsHarmonicCocycle or pAdicAutomorphicForm - OUTPUT: - - A boolean value. True if and only if ``S`` is coercible into self. + OUTPUT: boolean; ``True`` if and only if `S` is coercible into ``self`` EXAMPLES:: @@ -2447,11 +2373,9 @@ def _element_constructor_(self, data): INPUT: - ``data`` -- defining data. Can be either a harmonic cocycle, or a `p`-adic automorphic form, - or a list of elements coercible into the module of coefficients of ``self``. + or a list of elements coercible into the module of coefficients of ``self`` - OUTPUT: - - A `p`-adic automorphic form. + OUTPUT: a `p`-adic automorphic form EXAMPLES:: @@ -2492,9 +2416,7 @@ def _an_element_(self): r""" Return an element of the module. - OUTPUT: - - A harmonic cocycle. + OUTPUT: a harmonic cocycle EXAMPLES:: @@ -2507,11 +2429,9 @@ def _an_element_(self): def precision_cap(self): """ - Return the precision of self. - - OUTPUT: + Return the precision of ``self``. - An integer. + OUTPUT: integer EXAMPLES:: @@ -2533,9 +2453,7 @@ def lift(self, f): - ``f`` -- a harmonic cocycle - OUTPUT: - - A `p`-adic automorphic form + OUTPUT: a `p`-adic automorphic form EXAMPLES: @@ -2569,11 +2487,9 @@ def _make_invariant(self, F): INPUT: - ``F`` -- a classical (nonoverconvergent) pAdicAutomorphicForm or - BruhatTitsHarmonicCocycle. - - OUTPUT: + BruhatTitsHarmonicCocycle - An overconvergent pAdicAutomorphicForm + OUTPUT: an overconvergent pAdicAutomorphicForm EXAMPLES:: @@ -2611,9 +2527,9 @@ def _apply_Up_operator(self, f, scale=False, original_moments=None): INPUT: - - f -- a `p`-adic automorphic form. - - scale -- (default: ``True``) whether to scale by the appropriate power of `p` - at each iteration. + - ``f`` -- a `p`-adic automorphic form + - ``scale`` -- boolean (default: ``True``); whether to scale by the appropriate power of `p` + at each iteration EXAMPLES:: diff --git a/src/sage/modular/buzzard.py b/src/sage/modular/buzzard.py index 72e72e745cc..6c88bfcf172 100644 --- a/src/sage/modular/buzzard.py +++ b/src/sage/modular/buzzard.py @@ -18,30 +18,12 @@ # # https://www.gnu.org/licenses/ ############################################################################# +from pathlib import Path -from sage.interfaces.gp import Gp -from sage.misc.sage_eval import sage_eval +from sage.env import SAGE_EXTCODE +from sage.libs.pari import pari -_gp = None - - -def gp(): - r""" - Return a copy of the GP interpreter with the appropriate files loaded. - - EXAMPLES:: - - sage: import sage.modular.buzzard - sage: sage.modular.buzzard.gp() - PARI/GP interpreter - """ - global _gp - if _gp is None: - _gp = Gp(script_subdirectory='buzzard') - _gp.read("DimensionSk.g") - _gp.read("genusn.g") - _gp.read("Tpprog.g") - return _gp +buzzard_dir = Path(SAGE_EXTCODE) / "pari" / "buzzard" # def buzzard_dimension_cusp_forms(eps, k): # r""" @@ -73,7 +55,7 @@ def gp(): def buzzard_tpslopes(p, N, kmax): r""" - Return a vector of length kmax, whose `k`'th entry + Return a vector of length kmax, whose `k`-th entry (`0 \leq k \leq k_{max}`) is the conjectural sequence of valuations of eigenvalues of `T_p` on forms of level `N`, weight `k`, and trivial character. @@ -86,6 +68,7 @@ def buzzard_tpslopes(p, N, kmax): sage: from sage.modular.buzzard import buzzard_tpslopes sage: c = buzzard_tpslopes(2,1,50) + ... sage: c[50] [4, 8, 13] @@ -107,7 +90,10 @@ def buzzard_tpslopes(p, N, kmax): - William Stein (2006-03-17): small Sage wrapper of Buzzard's scripts """ - v = gp().eval('tpslopes(%s, %s, %s)' % (p, N, kmax)) - v = sage_eval(v) - v.insert(0, []) # so v[k] = info about weight k (since python is 0-based) + pari.read(buzzard_dir / "DimensionSk.g") + pari.read(buzzard_dir / "genusn.g") + pari.read(buzzard_dir / "Tpprog.g") + # v = pari.tpslopes(p, N, kmax).sage() + v = pari('tpslopes(%s, %s, %s)' % (p, N, kmax)).sage() + v.insert(0, []) # so that v[k] = info about weight k return v diff --git a/src/sage/modular/cusps.py b/src/sage/modular/cusps.py index 27b13298e18..7a4a2628096 100644 --- a/src/sage/modular/cusps.py +++ b/src/sage/modular/cusps.py @@ -317,7 +317,7 @@ def _richcmp_(self, right, op): def is_infinity(self): """ - Returns True if this is the cusp infinity. + Return ``True`` if this is the cusp infinity. EXAMPLES:: @@ -470,28 +470,28 @@ def __neg__(self): def is_gamma0_equiv(self, other, N, transformation=None): r""" - Return whether self and other are equivalent modulo the action of + Return whether ``self`` and ``other`` are equivalent modulo the action of `\Gamma_0(N)` via linear fractional transformations. INPUT: + - ``other`` -- cusp - - ``other`` -- Cusp - - - ``N`` -- an integer (specifies the group - Gamma_0(N)) - - - ``transformation`` -- None (default) or either the string 'matrix' or 'corner'. If 'matrix', - it also returns a matrix in Gamma_0(N) that sends self to other. The matrix is chosen such that the lower left entry is as small as possible in absolute value. If 'corner' (or True for backwards compatibility), it returns only the upper left entry of such a matrix. + - ``N`` -- integer (specifies the group `\Gamma_0(N)`) + - ``transformation`` -- ``None`` (default) or either the string 'matrix' or + ``'corner'``. If ``'matrix'``, it also returns a matrix in `\Gamma_0(N)` that + sends ``self`` to ``other``. The matrix is chosen such that the lower + left entry is as small as possible in absolute value. If ``'corner'`` (or + ``True`` for backwards compatibility), it returns only the upper left + entry of such a matrix. OUTPUT: + - a boolean -- ``True`` if ``self`` and ``other`` are equivalent - - a boolean -- True if self and other are equivalent - - - a matrix or an integer- returned only if transformation is 'matrix' or 'corner', respectively. - + - a matrix or an integer -- returned only if transformation is 'matrix' + or 'corner', respectively EXAMPLES:: @@ -650,31 +650,26 @@ def is_gamma0_equiv(self, other, N, transformation=None): return (True, A) def is_gamma1_equiv(self, other, N): - """ - Return whether self and other are equivalent modulo the action of - Gamma_1(N) via linear fractional transformations. + r""" + Return whether ``self`` and ``other`` are equivalent modulo the action of + `\Gamma_1(N)` via linear fractional transformations. INPUT: + - ``other`` -- cusp - - ``other`` -- Cusp - - - ``N`` -- an integer (specifies the group - Gamma_1(N)) - + - ``N`` -- integer (specifies the group `\Gamma_1(N)`) OUTPUT: + - ``bool`` -- ``True`` if ``self`` and ``other`` are equivalent - - ``bool`` -- True if self and other are equivalent - - - ``int`` -- 0, 1 or -1, gives further information - about the equivalence: If the two cusps are u1/v1 and u2/v2, then - they are equivalent if and only if v1 = v2 (mod N) and u1 = u2 (mod - gcd(v1,N)) or v1 = -v2 (mod N) and u1 = -u2 (mod gcd(v1,N)) The - sign is +1 for the first and -1 for the second. If the two cusps - are not equivalent then 0 is returned. - + - ``int`` -- 0, 1 or -1, gives further information + about the equivalence: If the two cusps are u1/v1 and u2/v2, then + they are equivalent if and only if v1 = v2 (mod N) and u1 = u2 (mod + gcd(v1,N)) or v1 = -v2 (mod N) and u1 = -u2 (mod gcd(v1,N)) The + sign is +1 for the first and -1 for the second. If the two cusps + are not equivalent then 0 is returned. EXAMPLES:: @@ -711,9 +706,9 @@ def is_gamma1_equiv(self, other, N): def is_gamma_h_equiv(self, other, G): r""" - Return a pair (b, t), where b is True or False as self and other - are equivalent under the action of G, and t is 1 or -1, as - described below. + Return a pair ``(b, t)``, where ``b`` is ``True`` or ``False`` as + ``self`` and ``other`` are equivalent under the action of `G`, and `t` + is 1 or -1, as described below. Two cusps `u1/v1` and `u2/v2` are equivalent modulo Gamma_H(N) if and only if `v1 = h*v2 (\mathrm{mod} N)` and @@ -725,19 +720,15 @@ def is_gamma_h_equiv(self, other, G): INPUT: + - ``other`` -- cusp - - ``other`` -- Cusp - - - ``G`` -- a congruence subgroup Gamma_H(N) - + - ``G`` -- a congruence subgroup Gamma_H(N) OUTPUT: + - ``bool`` -- ``True`` if ``self`` and ``other`` are equivalent - - ``bool`` -- True if self and other are equivalent - - - ``int`` -- -1, 0, 1; extra info - + - ``int`` -- -1, 0, 1; extra info EXAMPLES:: @@ -807,7 +798,7 @@ def is_gamma_h_equiv(self, other, G): def _acted_upon_(self, g, self_on_left): r""" - Implement the left action of `SL_2(\ZZ)` on self. + Implement the left action of `SL_2(\ZZ)` on ``self``. EXAMPLES:: @@ -873,13 +864,11 @@ def galois_action(self, t, N): INPUT: - - `t` -- integer that is coprime to N - - - `N` -- positive integer (level) + - ``t`` -- integer that is coprime to N - OUTPUT: + - ``N`` -- positive integer (level) - - a cusp + OUTPUT: a cusp .. WARNING:: @@ -964,7 +953,6 @@ def galois_action(self, t, N): AUTHORS: - William Stein, 2009-04-18 - """ if self.is_infinity(): return self @@ -1066,7 +1054,7 @@ def _repr_(self): def _latex_(self): r""" - Return latex representation of self. + Return latex representation of ``self``. EXAMPLES:: diff --git a/src/sage/modular/cusps_nf.py b/src/sage/modular/cusps_nf.py index 9cf9bc3e7b8..4d120c075da 100644 --- a/src/sage/modular/cusps_nf.py +++ b/src/sage/modular/cusps_nf.py @@ -94,7 +94,7 @@ def list_of_representatives(N): INPUT: - - ``N`` -- an ideal of a number field. + - ``N`` -- an ideal of a number field OUTPUT: @@ -124,9 +124,7 @@ def NFCusps(number_field): - ``number_field`` -- a number field - OUTPUT: - - The set of cusps over the given number field. + OUTPUT: the set of cusps over the given number field EXAMPLES:: @@ -238,13 +236,12 @@ def _repr_(self): Number Field Cusps sage: kCusps.rename(); kCusps Set of all cusps of Number Field in a with defining polynomial x^2 + 2 - """ return "Set of all cusps of %s" % self.number_field() def _latex_(self): r""" - Return latex representation of self. + Return latex representation of ``self``. EXAMPLES:: @@ -332,13 +329,13 @@ class NFCusp(Element): INPUT: - - ``number_field`` -- the number field over which the cusp is defined. + - ``number_field`` -- the number field over which the cusp is defined - ``a`` -- it can be a number field element (integral or not), or - a number field cusp. + a number field cusp - ``b`` -- (optional) when present, it must be either Infinity or - coercible to an element of the number field. + coercible to an element of the number field - ``lreps`` -- (optional) a list of chosen representatives for all the ideal classes of the field. When given, the representative of the cusp @@ -786,8 +783,8 @@ def apply(self, g): INPUT: - - ``g`` -- a list of integral elements [a, b, c, d] that are the - entries of a 2x2 matrix. + - ``g`` -- list of integral elements [a, b, c, d] that are the + entries of a 2x2 matrix OUTPUT: @@ -911,13 +908,11 @@ def is_Gamma0_equivalent(self, other, N, Transformation=False): INPUT: - ``other`` -- a number field cusp or a list of two number field - elements which define a cusp. + elements which define a cusp - ``N`` -- an ideal of the number field (level) - OUTPUT: - - - bool -- ``True`` if the cusps are equivalent. + OUTPUT: boolean; ``True`` if the cusps are equivalent - a transformation matrix -- (if ``Transformation=True``) a list of integral elements [a, b, c, d] which are the entries of a 2x2 matrix @@ -1029,11 +1024,9 @@ def Gamma0_NFCusps(N): INPUT: - - ``N`` -- an integral ideal of the number field k (the level). + - ``N`` -- an integral ideal of the number field k (the level) - OUTPUT: - - A list of inequivalent number field cusps. + OUTPUT: list of inequivalent number field cusps EXAMPLES:: @@ -1122,11 +1115,9 @@ def number_of_Gamma0_NFCusps(N): INPUT: - - ``N`` -- a number field ideal. - - OUTPUT: + - ``N`` -- a number field ideal - integer -- the number of orbits of cusps under Gamma0(N)-action. + OUTPUT: integer; the number of orbits of cusps under Gamma0(N)-action EXAMPLES:: @@ -1164,10 +1155,10 @@ def NFCusps_ideal_reps_for_levelN(N, nlists=1): INPUT: - - ``N`` -- number field ideal. + - ``N`` -- number field ideal - - ``nlists`` -- optional (default 1). The number of lists of prime ideals - we want. + - ``nlists`` -- (default: 1) the number of lists of prime ideals + we want OUTPUT: @@ -1223,7 +1214,7 @@ def units_mod_ideal(I): INPUT: - - ``I`` -- number field ideal. + - ``I`` -- number field ideal OUTPUT: diff --git a/src/sage/modular/dims.py b/src/sage/modular/dims.py index 3f246ad93ad..7eef7392e76 100644 --- a/src/sage/modular/dims.py +++ b/src/sage/modular/dims.py @@ -69,7 +69,7 @@ def eisen(p): - ``p`` -- a prime - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -96,13 +96,13 @@ def CO_delta(r, p, N, eps): INPUT: - - ``r`` -- positive integer + - ``r`` -- positive integer - - ``p`` -- a prime + - ``p`` -- a prime - - ``N`` -- positive integer + - ``N`` -- positive integer - - ``eps`` -- character + - ``eps`` -- character OUTPUT: element of the base ring of the character @@ -140,13 +140,13 @@ def CO_nu(r, p, N, eps): INPUT: - - ``r`` -- positive integer + - ``r`` -- positive integer - - ``p`` -- a prime + - ``p`` -- a prime - - ``N`` -- positive integer + - ``N`` -- positive integer - - ``eps`` -- character + - ``eps`` -- character OUTPUT: element of the base ring of the character @@ -185,11 +185,11 @@ def CohenOesterle(eps, k): INPUT: - - ``eps`` -- Dirichlet character + - ``eps`` -- Dirichlet character - - ``k`` -- integer + - ``k`` -- integer - OUTPUT: element of the base ring of eps. + OUTPUT: element of the base ring of eps EXAMPLES:: @@ -219,9 +219,9 @@ def _lambda(r, s, p): INPUT: - - ``r, s, p`` -- integers + - ``r``, ``s``, ``p`` -- integers - OUTPUT: Integer + OUTPUT: integer EXAMPLES: (indirect doctest) @@ -258,12 +258,12 @@ def dimension_new_cusp_forms(X, k=2, p=0): INPUT: - - ``X`` -- integer, congruence subgroup or Dirichlet - character + - ``X`` -- integer, congruence subgroup or Dirichlet + character - - ``k`` -- weight (integer) + - ``k`` -- weight (integer) - - ``p`` -- 0 or a prime + - ``p`` -- 0 or a prime EXAMPLES:: @@ -320,10 +320,10 @@ def dimension_cusp_forms(X, k=2): INPUT: - - ``X`` -- congruence subgroup or Dirichlet character - or integer + - ``X`` -- congruence subgroup or Dirichlet character + or integer - - ``k`` -- weight (integer) + - ``k`` -- weight (integer) EXAMPLES:: @@ -416,10 +416,10 @@ def dimension_eis(X, k=2): INPUT: - - ``X`` -- congruence subgroup or Dirichlet character - or integer + - ``X`` -- congruence subgroup or Dirichlet character + or integer - - ``k`` -- weight (integer) + - ``k`` -- integer; weight EXAMPLES:: @@ -488,9 +488,9 @@ def dimension_modular_forms(X, k=2): INPUT: - - ``X`` -- congruence subgroup or Dirichlet character + - ``X`` -- congruence subgroup or Dirichlet character - - ``k`` -- weight (integer) + - ``k`` -- integer; weight EXAMPLES:: @@ -539,10 +539,10 @@ def sturm_bound(level, weight=2): INPUT: - - ``level`` -- an integer (interpreted as a level for Gamma0) or a - congruence subgroup + - ``level`` -- integer (interpreted as a level for `\Gamma0`) or a + congruence subgroup - - ``weight`` -- an integer `\geq 2` (default: 2) + - ``weight`` -- integer `\geq 2` (default: 2) EXAMPLES:: diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index e579c5090e3..1f6a7a94444 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -199,7 +199,7 @@ def __init__(self, parent, x, check=True): INPUT: - ``parent`` -- :class:`DirichletGroup`, a group of Dirichlet - characters + characters - ``x`` -- one of the following: @@ -395,7 +395,6 @@ def change_ring(self, R): sage: psi = chi.change_ring(f) sage: psi(2) -1.83697019872103e-16 - 1.00000000000000*I - """ if self.base_ring() is R: return self @@ -537,7 +536,6 @@ def _repr_short_(self): sage: chi = DirichletGroup(24).0 sage: chi._repr_short_() '[-1, 1, 1]' - """ return str(list(self.values_on_gens())) @@ -637,12 +635,12 @@ def bernoulli(self, k, algorithm='recurrence', cache=True, **opts): INPUT: - - ``k`` -- a non-negative integer + - ``k`` -- nonnegative integer - ``algorithm`` -- either ``'recurrence'`` (default) or ``'definition'`` - - ``cache`` -- if True, cache answers + - ``cache`` -- if ``True``, cache answers - ``**opts`` -- optional arguments; not used directly, but passed to the :func:`bernoulli` function if this is called @@ -686,7 +684,7 @@ def bernoulli(self, k, algorithm='recurrence', cache=True, **opts): sage: eps = DirichletGroup(9).0 sage: eps.bernoulli(3) 10*zeta6 + 4 - sage: eps.bernoulli(3, algorithm="definition") + sage: eps.bernoulli(3, algorithm='definition') 10*zeta6 + 4 TESTS: @@ -695,7 +693,6 @@ def bernoulli(self, k, algorithm='recurrence', cache=True, **opts): sage: DirichletGroup(1)[0].bernoulli(1) 1/2 - """ if cache: try: @@ -749,14 +746,14 @@ def S(n): def lfunction(self, prec=53, algorithm='pari'): """ - Return the L-function of ``self``. + Return the `L`-function of ``self``. - The result is a wrapper around a PARI L-function or around + The result is a wrapper around a PARI `L`-function or around the ``lcalc`` program. INPUT: - - ``prec`` -- precision (default 53) + - ``prec`` -- precision (default: 53) - ``algorithm`` -- 'pari' (default) or 'lcalc' @@ -830,7 +827,7 @@ def conductor(self): return Integer(cond) @cached_method - def fixed_field_polynomial(self, algorithm="pari"): + def fixed_field_polynomial(self, algorithm='pari'): r""" Given a Dirichlet character, this will return a polynomial generating the abelian extension fixed by the kernel @@ -841,9 +838,7 @@ def fixed_field_polynomial(self, algorithm="pari"): A formula by Gauss for the products of periods; see Disquisitiones §343. See the source code for more. - OUTPUT: - - - a polynomial with integer coefficients + OUTPUT: a polynomial with integer coefficients EXAMPLES:: @@ -878,7 +873,7 @@ def fixed_field_polynomial(self, algorithm="pari"): sage: psi = chi^3 sage: psi.order() 2 - sage: psi.fixed_field_polynomial(algorithm="pari") + sage: psi.fixed_field_polynomial(algorithm='pari') x^2 + x + 2 With the Sage implementation:: @@ -886,14 +881,14 @@ def fixed_field_polynomial(self, algorithm="pari"): sage: G = DirichletGroup(37) sage: chi = G.0 sage: psi = chi^18 - sage: psi.fixed_field_polynomial(algorithm="sage") + sage: psi.fixed_field_polynomial(algorithm='sage') x^2 + x - 9 sage: G = DirichletGroup(7) sage: chi = G.0^2 sage: chi Dirichlet character modulo 7 of conductor 7 mapping 3 |--> zeta6 - 1 - sage: chi.fixed_field_polynomial(algorithm="sage") + sage: chi.fixed_field_polynomial(algorithm='sage') x^3 + x^2 - 2*x - 1 sage: G = DirichletGroup(31) @@ -901,12 +896,12 @@ def fixed_field_polynomial(self, algorithm="pari"): sage: chi^6 Dirichlet character modulo 31 of conductor 31 mapping 3 |--> zeta30^6 sage: psi = chi^6 - sage: psi.fixed_field_polynomial(algorithm="sage") + sage: psi.fixed_field_polynomial(algorithm='sage') x^5 + x^4 - 12*x^3 - 21*x^2 + x + 5 sage: G = DirichletGroup(7) sage: chi = G.0 - sage: chi.fixed_field_polynomial(algorithm="sage") + sage: chi.fixed_field_polynomial(algorithm='sage') x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 sage: G = DirichletGroup(1001) @@ -914,7 +909,7 @@ def fixed_field_polynomial(self, algorithm="pari"): sage: psi = chi^3 sage: psi.order() 2 - sage: psi.fixed_field_polynomial(algorithm="sage") + sage: psi.fixed_field_polynomial(algorithm='sage') x^2 + x + 2 The algorithm must be one of `sage` or `pari`:: @@ -924,11 +919,10 @@ def fixed_field_polynomial(self, algorithm="pari"): sage: psi = chi^3 sage: psi.order() 2 - sage: psi.fixed_field_polynomial(algorithm="banana") + sage: psi.fixed_field_polynomial(algorithm='banana') Traceback (most recent call last): ... NotImplementedError: algorithm must be one of 'pari' or 'sage' - """ # this algorithm was written by Francis Clarke see issue #9407 @@ -1027,9 +1021,7 @@ def fixed_field(self): Given a Dirichlet character, this will return the abelian extension fixed by the kernel of the corresponding Galois character. - OUTPUT: - - - a number field + OUTPUT: a number field EXAMPLES:: @@ -1324,7 +1316,7 @@ def gauss_sum(self, a=1): g_a(\chi) = \sum_{r \in \ZZ/m\ZZ} \chi(r)\,\zeta^{ar}, where `m` is the modulus of `\chi` and `\zeta` is a primitive - `m^{th}` root of unity. + `m`-th root of unity. FACTS: If the modulus is a prime `p` and the character is nontrivial, then the Gauss sum has absolute value `\sqrt{p}`. @@ -1416,9 +1408,9 @@ def gauss_sum_numerical(self, prec=53, a=1): INPUT: - - ``prec`` -- integer (default: 53), *bits* of precision + - ``prec`` -- integer (default: 53); *bits* of precision - - ``a`` -- integer, as for :meth:`gauss_sum`. + - ``a`` -- integer; as for :meth:`gauss_sum` The Gauss sum associated to `\chi` is @@ -1427,7 +1419,7 @@ def gauss_sum_numerical(self, prec=53, a=1): g_a(\chi) = \sum_{r \in \ZZ/m\ZZ} \chi(r)\,\zeta^{ar}, where `m` is the modulus of `\chi` and `\zeta` is a primitive - `m^{th}` root of unity. + `m`-th root of unity. EXAMPLES:: @@ -1673,9 +1665,9 @@ def kloosterman_sum_numerical(self, prec=53, a=1, b=0): INPUT: - - ``prec`` -- integer (default: 53), *bits* of precision - - ``a`` -- integer, as for :meth:`.kloosterman_sum` - - ``b`` -- integer, as for :meth:`.kloosterman_sum`. + - ``prec`` -- integer (default: 53); *bits* of precision + - ``a`` -- integer; as for :meth:`.kloosterman_sum` + - ``b`` -- integer; as for :meth:`.kloosterman_sum` EXAMPLES:: @@ -1841,8 +1833,8 @@ def kernel(self): r""" Return the kernel of this character. - OUTPUT: Currently the kernel is returned as a list. This may - change. + OUTPUT: currently the kernel is returned as a list; this may + change EXAMPLES:: @@ -1899,7 +1891,7 @@ def minimize_base_ring(self): Return a Dirichlet character that equals this one, but over as small a subfield (or subring) of the base ring as possible. - .. note:: + .. NOTE:: This function is currently only implemented when the base ring is a number field. It is the identity function in @@ -2388,7 +2380,8 @@ class DirichletGroupFactory(UniqueFactory): :: - sage: r4 = CyclotomicField(4).ring_of_integers() + sage: K = CyclotomicField(4) + sage: r4 = K.ring_of_integers() sage: G = DirichletGroup(60, r4) sage: G.gens() (Dirichlet character modulo 60 of conductor 4 @@ -2401,8 +2394,7 @@ class DirichletGroupFactory(UniqueFactory): zeta4 sage: parent(val) Gaussian Integers generated by zeta4 in Cyclotomic Field of order 4 and degree 2 - sage: r4_29_0 = r4.residue_field(r4.ideal(29).factor()[0][0]); r4_29_0(val) - doctest:warning ... DeprecationWarning: ... + sage: r4_29_0 = r4.residue_field(K(29).factor()[0][0]); r4_29_0(val) 17 sage: r4_29_0(val) * GF(29)(3) 22 @@ -2465,7 +2457,6 @@ class DirichletGroupFactory(UniqueFactory): sage: DirichletGroup(60) is DirichletGroup(60) True - """ def create_key(self, N, base_ring=None, zeta=None, zeta_order=None, names=None, integral=False): @@ -2565,7 +2556,6 @@ def create_object(self, version, key, **extra_args): sage: DirichletGroup.create_object(None, (K, 60, K.gen(), 4)) Group of Dirichlet characters modulo 60 with values in the group of order 4 generated by zeta4 in Cyclotomic Field of order 4 and degree 2 - """ base_ring, modulus, zeta, zeta_order = key return DirichletGroup_class(base_ring, modulus, zeta, zeta_order) @@ -2626,7 +2616,6 @@ def __init__(self, base_ring, modulus, zeta, zeta_order): True sage: DirichletGroup(13) == DirichletGroup(13, QQ) False - """ from sage.categories.groups import Groups category = Groups().Commutative() @@ -2743,7 +2732,6 @@ def change_ring(self, R, zeta=None, zeta_order=None): sage: D.change_ring(f) Group of Dirichlet characters modulo 5 with values in Complex Field with 53 bits of precision - """ if zeta is None and self._zeta is not None: # A root of unity was explicitly given; we use it over the @@ -2822,7 +2810,6 @@ def base_extend(self, R): 14 sage: g.parent().zeta() 14 - """ if not (isinstance(R, Map) or R.has_coerce_map_from(self.base_ring())): @@ -3039,17 +3026,17 @@ def galois_orbits(self, v=None, reps_only=False, sort=True, check=True): INPUT: - - ``v`` -- (optional) list of elements of ``self`` + - ``v`` -- (optional) list of elements of ``self`` - - ``reps_only`` -- (optional: default ``False``) if ``True`` - only returns representatives for the orbits. + - ``reps_only`` -- (optional: default ``False``) if ``True`` + only returns representatives for the orbits - - ``sort`` -- (optional: default ``True``) whether to sort - the list of orbits and the orbits themselves (slightly faster if - ``False``). + - ``sort`` -- (optional: default ``True``) whether to sort + the list of orbits and the orbits themselves (slightly faster if + ``False``). - - ``check`` -- (default: ``True``) whether or not - to explicitly coerce each element of ``v`` into ``self``. + - ``check`` -- boolean (default: ``True``); whether or not + to explicitly coerce each element of ``v`` into ``self`` The Galois group is the absolute Galois group of the prime subfield of Frac(R). If R is not a domain, an error will be raised. @@ -3098,7 +3085,7 @@ def galois_orbits(self, v=None, reps_only=False, sort=True, check=True): def gen(self, n=0): """ - Return the n-th generator of ``self``. + Return the `n`-th generator of ``self``. EXAMPLES:: diff --git a/src/sage/modular/drinfeld_modform/element.py b/src/sage/modular/drinfeld_modform/element.py index 8af86f25118..59d7a9e23ff 100644 --- a/src/sage/modular/drinfeld_modform/element.py +++ b/src/sage/modular/drinfeld_modform/element.py @@ -25,6 +25,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.polynomial.multi_polynomial import MPolynomial + class DrinfeldModularFormsElement(ModuleElement): r""" Element class of rings of Drinfeld modular forms. @@ -84,7 +85,7 @@ class DrinfeldModularFormsElement(ModuleElement): sage: M(T*f1 + f2^3 + T^2 + 1) g2^3 + T*g1 + (T^2 + 1) - .. note:: + .. NOTE:: This class should not be directly instanciated, instead create an instance of the parent @@ -341,9 +342,7 @@ def polynomial(self): Return this graded Drinfeld forms as a multivariate polynomial over the generators of the ring. - OUTPUT: - - A multivariate polynomial over the base ring. + OUTPUT: a multivariate polynomial over the base ring EXAMPLES:: diff --git a/src/sage/modular/drinfeld_modform/ring.py b/src/sage/modular/drinfeld_modform/ring.py index bb638e339ab..c383cf94266 100644 --- a/src/sage/modular/drinfeld_modform/ring.py +++ b/src/sage/modular/drinfeld_modform/ring.py @@ -44,6 +44,7 @@ from .element import DrinfeldModularFormsElement + class DrinfeldModularForms(Parent, UniqueRepresentation): r""" Base class for the graded ring of Drinfeld modular forms. @@ -76,20 +77,20 @@ class DrinfeldModularForms(Parent, UniqueRepresentation): INPUT: - ``base_ring`` -- the fraction field of a univariate polynomial - ring over `\mathbb{F}_q`. + ring over `\mathbb{F}_q` - - ``rank`` integer (default: ``None``) -- the rank of the ring. If + - ``rank`` integer (default: ``None``); the rank of the ring. If the rank is ``None``, then the names of the generators must be specified. - - ``group`` (not implemented, default: ``None``) -- the group of the + - ``group`` -- (not implemented, default: ``None``) the group of the ring. The current implementation only supports the full modular group `\mathrm{GL}_r(A)`. - - ``has_type`` boolean (default: ``False``) -- if set to ``True``, - returns the graded ring of arbitrary type. + - ``has_type`` -- boolean (default: ``False``); if set to ``True``, + returns the graded ring of arbitrary type - - ``names`` string, tuple or list (default: ``None``) -- a single + - ``names`` -- string, tuple or list (default: ``None``); a single character, a tuple or list of character, or comma separated string of character representing the names of the generators. If this parameter is set to ``None`` and the rank is specified, then the @@ -341,7 +342,7 @@ def __init__(self, base_ring, rank, group, has_type, names): def _an_element_(self): r""" - Return an element of self. + Return an element of ``self``. TESTS:: @@ -356,7 +357,7 @@ def _an_element_(self): def _repr_(self): r""" - Return the string representation of self. + Return the string representation of ``self``. TESTS:: @@ -371,7 +372,7 @@ def _repr_(self): def _generator_coefficient_form(self, i): r""" - Return the i-th coefficient form at `T`. + Return the `i`-th coefficient form at `T`. For internal use only, the user should use :meth:`coefficient_form` instead. @@ -415,9 +416,9 @@ def _coefficient_forms(self, a): INPUT: - - ``a`` -- an element in the ring of regular functions. + - ``a`` -- an element in the ring of regular functions - OUTPUT: a list of Drinfeld modular forms. The `i`-th element of + OUTPUT: list of Drinfeld modular forms. The `i`-th element of that list corresponds to the `(i+1)`-th coefficient form at `a`. TESTS:: @@ -430,13 +431,11 @@ def _coefficient_forms(self, a): [(T^2 + T)*g1, g1^3 + (T^4 + T)*g2, g1^4*g2 + g1*g2^2, g2^5] """ a = a.numerator() - d = a.degree() poly_ring = PolynomialRing(self._base_ring, self.rank(), 'g') poly_ring_gens = poly_ring.gens() Frob = poly_ring.frobenius_endomorphism() gen = [self._base_ring.gen()] - for g in poly_ring_gens: - gen.append(g) + gen.extend(poly_ring_gens) ore_pol_ring = OrePolynomialRing(poly_ring, Frob, 't') gen = ore_pol_ring(gen) f = sum(c*(gen**idx) for idx, c in enumerate(a.coefficients(sparse=False))) @@ -460,7 +459,7 @@ def coefficient_form(self, i, a=None): INPUT: - - ``i`` -- an integer between 1 and `r d_a`; + - ``i`` -- integer between 1 and `r d_a` - ``a`` -- (default: ``None``) an element in the ring of regular functions. If `a` is ``None``, then the method returns the @@ -546,7 +545,7 @@ def coefficient_forms(self, a=None): functions. If `a` is ``None``, then the method returns the coefficients forms at `a = T`. - OUTPUT: a list of Drinfeld modular forms. The `i`-th element of + OUTPUT: list of Drinfeld modular forms. The `i`-th element of that list corresponds to the `(i+1)`-th coefficient form at `a`. EXAMPLES:: @@ -728,7 +727,7 @@ def basis_of_weight(self, k): INPUT: - - ``k`` -- an integer. + - ``k`` -- integer EXAMPLES:: diff --git a/src/sage/modular/drinfeld_modform/tutorial.py b/src/sage/modular/drinfeld_modform/tutorial.py index 01e0f80db5c..e4f64f10daf 100644 --- a/src/sage/modular/drinfeld_modform/tutorial.py +++ b/src/sage/modular/drinfeld_modform/tutorial.py @@ -21,7 +21,7 @@ completion of an algebraic closure of `K_{\infty}`. Lastly, we denote by `\tau : x\mapsto x^q` the `q`-Frobenius. -.. note:: +.. NOTE:: The above construction of `\mathbb{C}_{\infty}` is the same as the construction of `\mathbb{C}_p` in the case of `p`-adic numbers diff --git a/src/sage/modular/etaproducts.py b/src/sage/modular/etaproducts.py index b794d0cf2d6..a063255c6a6 100644 --- a/src/sage/modular/etaproducts.py +++ b/src/sage/modular/etaproducts.py @@ -276,13 +276,12 @@ def q_expansion(self, n): INPUT: - - ``n`` (integer): number of terms to calculate + - ``n`` -- integer; number of terms to calculate OUTPUT: - - a power series over `\ZZ` in - the variable `q`, with a *relative* precision of - `1 + O(q^n)`. + A power series over `\ZZ` in the variable `q`, with a *relative* + precision of `1 + O(q^n)`. ALGORITHM: Calculates eta to (n/m) terms, where m is the smallest integer dividing self.level() such that self.r(m) != 0. Then @@ -329,11 +328,9 @@ def order_at_cusp(self, cusp: CuspFamily) -> Integer: INPUT: - - ``cusp`` -- a :class:`CuspFamily` object + - ``cusp`` -- a :class:`CuspFamily` object - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: @@ -470,7 +467,7 @@ def _element_constructor_(self, dic): INPUT: - - ``dic`` -- a dictionary + - ``dic`` -- dictionary See the docstring of :func:`EtaProduct` for how ``dic`` is used. @@ -500,8 +497,8 @@ def basis(self, reduce=True) -> list: INPUT: - - ``reduce`` -- a boolean (default: ``True``) indicating - whether or not to apply LLL-reduction to the calculated basis + - ``reduce`` -- boolean (default: ``True``); whether or not to apply + LLL-reduction to the calculated basis EXAMPLES:: @@ -576,7 +573,7 @@ def reduce_basis(self, long_etas) -> list: INPUT: - - ``long_etas`` -- a list of EtaGroupElement objects (which + - ``long_etas`` -- a list of EtaGroupElement objects (which should all be of the same level) OUTPUT: @@ -627,19 +624,18 @@ def EtaProduct(level, dic) -> EtaGroupElement: INPUT: - - ``level`` -- (integer): the N such that this eta - product is a function on X_0(N). + - ``level`` -- integer; the N such that this eta + product is a function on `X_0(N)` - - ``dic`` -- (dictionary): a dictionary indexed by - divisors of N such that the coefficient of `\eta(q^d)` is - r[d]. Only nonzero coefficients need be specified. If Ligozat's - criteria are not satisfied, a :class:`ValueError` will be raised. + - ``dic`` -- a dictionary indexed by divisors of N such that the + coefficient of `\eta(q^d)` is r[d]. Only nonzero coefficients need be + specified. If Ligozat's criteria are not satisfied, a :exc:`ValueError` + will be raised. OUTPUT: - - an EtaGroupElement object, whose parent is - the EtaGroup of level N and whose coefficients are the given - dictionary. + An EtaGroupElement object, whose parent is the EtaGroup of level N and + whose coefficients are the given dictionary. .. NOTE:: @@ -671,9 +667,9 @@ def num_cusps_of_width(N, d) -> Integer: INPUT: - - ``N`` -- (integer): the level + - ``N`` -- integer; the level - - ``d`` -- (integer): an integer dividing N, the cusp width + - ``d`` -- integer; an integer dividing `N`, the cusp width EXAMPLES:: @@ -700,7 +696,7 @@ def AllCusps(N) -> list: INPUT: - - ``N`` -- (integer): the level + - ``N`` -- integer; the level EXAMPLES:: @@ -859,7 +855,7 @@ def _repr_(self) -> str: def qexp_eta(ps_ring, prec): r""" - Return the q-expansion of `\eta(q) / q^{1/24}`. + Return the `q`-expansion of `\eta(q) / q^{1/24}`. Here `\eta(q)` is Dedekind's function @@ -871,11 +867,11 @@ def qexp_eta(ps_ring, prec): INPUT: - - ``ps_ring`` -- (PowerSeriesRing): a power series ring + - ``ps_ring`` -- PowerSeriesRing; a power series ring - - ``prec`` -- (integer): the number of terms to compute + - ``prec`` -- integer; the number of terms to compute - OUTPUT: An element of ps_ring which is the q-expansion of + OUTPUT: an element of ``ps_ring`` which is the `q`-expansion of `\eta(q)/q^{1/24}` truncated to prec terms. ALGORITHM: We use the Euler identity @@ -917,17 +913,17 @@ def eta_poly_relations(eta_elements, degree, labels=['x1', 'x2'], INPUT: - - ``eta_elements`` -- (list): a list of EtaGroupElement objects. + - ``eta_elements`` -- list; a list of EtaGroupElement objects. Not implemented unless this list has precisely two elements. degree - - ``degree`` -- (integer): the maximal degree of polynomial to look for. + - ``degree`` -- integer; the maximal degree of polynomial to look for - - ``labels`` -- (list of strings): labels to use for the polynomial returned. + - ``labels`` -- list of strings; labels to use for the polynomial returned - - ``verbose`` -- (boolean, default ``False``): if ``True``, prints information as - it goes. + - ``verbose`` -- boolean (default: ``False``); if ``True``, prints information as + it goes - OUTPUT: a list of polynomials which is a Groebner basis for the + OUTPUT: list of polynomials which is a Groebner basis for the part of the ideal of relations between eta_elements which is generated by elements up to the given degree; or None, if no relations were found. diff --git a/src/sage/modular/hecke/algebra.py b/src/sage/modular/hecke/algebra.py index 81611bd2780..383a4e0c035 100644 --- a/src/sage/modular/hecke/algebra.py +++ b/src/sage/modular/hecke/algebra.py @@ -26,7 +26,7 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** -from typing import Iterator +from collections.abc import Iterator from sage.rings.infinity import infinity from sage.categories.algebras import Algebras @@ -35,12 +35,12 @@ from sage.arith.misc import gcd from sage.misc.latex import latex from sage.matrix.matrix_space import MatrixSpace -from sage.rings.ring import CommutativeRing from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.structure.element import Element from sage.structure.unique_representation import CachedRepresentation from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent from sage.structure.richcmp import richcmp_method, richcmp @@ -73,9 +73,7 @@ def _heckebasis(M): - ``M`` -- a Hecke module - OUTPUT: - - a list of Hecke algebra elements represented as matrices + OUTPUT: list of Hecke algebra elements represented as matrices EXAMPLES:: @@ -113,19 +111,18 @@ def _heckebasis(M): @richcmp_method -class HeckeAlgebra_base(CachedRepresentation, CommutativeRing): +class HeckeAlgebra_base(CachedRepresentation, Parent): """ Base class for algebras of Hecke operators on a fixed Hecke module. INPUT: - - ``M`` -- a Hecke module + - ``M`` -- a Hecke module EXAMPLES:: sage: CuspForms(1, 12).hecke_algebra() # indirect doctest Full Hecke algebra acting on Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field - """ @staticmethod def __classcall__(cls, M): @@ -189,8 +186,7 @@ def __init__(self, M) -> None: raise TypeError(msg) self.__M = M cat = Algebras(M.base_ring()).Commutative() - CommutativeRing.__init__(self, base_ring=M.base_ring(), - category=cat) + Parent.__init__(self, base=M.base_ring(), category=cat) def _an_element_(self): r""" @@ -224,7 +220,7 @@ def _element_constructor_(self, x, check=True): In the last case, the parameter ``check`` controls whether or not to check that this element really does lie in the appropriate algebra. At present, setting ``check=True`` raises - a :class:`NotImplementedError` unless x is a scalar (or a diagonal + a :exc:`NotImplementedError` unless x is a scalar (or a diagonal matrix). EXAMPLES:: @@ -250,7 +246,6 @@ def _element_constructor_(self, x, check=True): Traceback (most recent call last): ... TypeError: Don't know how to construct an element of Anemic Hecke algebra acting on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field from Hecke operator T_11 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field - """ from .hecke_operator import HeckeAlgebraElement_matrix, HeckeOperator, HeckeAlgebraElement @@ -383,7 +378,7 @@ def matrix_space(self): def _latex_(self) -> str: r""" - LaTeX representation of self. + LaTeX representation of ``self``. EXAMPLES:: @@ -560,7 +555,7 @@ def hecke_operator(self, n): def hecke_matrix(self, n, *args, **kwds): """ - Return the matrix of the n-th Hecke operator `T_n`. + Return the matrix of the `n`-th Hecke operator `T_n`. EXAMPLES:: @@ -607,7 +602,7 @@ class HeckeAlgebra_full(HeckeAlgebra_base): """ def _repr_(self) -> str: r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -618,7 +613,7 @@ def _repr_(self) -> str: def __richcmp__(self, other, op) -> bool: r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -648,7 +643,7 @@ def is_anemic(self): def anemic_subalgebra(self): r""" - The subalgebra of self generated by the Hecke operators of + The subalgebra of ``self`` generated by the Hecke operators of index coprime to the level. EXAMPLES:: @@ -677,7 +672,7 @@ def _repr_(self) -> str: def __richcmp__(self, other, op) -> bool: r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: diff --git a/src/sage/modular/hecke/ambient_module.py b/src/sage/modular/hecke/ambient_module.py index b6044f35889..3ce44fa63ce 100644 --- a/src/sage/modular/hecke/ambient_module.py +++ b/src/sage/modular/hecke/ambient_module.py @@ -87,9 +87,7 @@ def rank(self): """ Return the rank of this ambient Hecke module. - OUTPUT: - - Integer + OUTPUT: integer EXAMPLES:: @@ -167,7 +165,7 @@ def _degeneracy_lowering_matrix(self, codomain, t): def _hecke_image_of_ith_basis_element(self, n, i): """ - Return the image under the Hecke operator T_n of the i-th basis + Return the image under the Hecke operator `T_n` of the `i`-th basis element. EXAMPLES:: @@ -286,14 +284,14 @@ def degeneracy_map(self, codomain, t=1): INPUT: - - ``codomain`` -- a Hecke module, which should be of the same type as - self, or a positive integer (in which case Sage will use - :meth:`~hecke_module_of_level` to find the "natural" module of the - corresponding level). - - ``t`` -- int, the parameter of the degeneracy map, i.e., the map is - related to `f(q)` - `f(q^t)`. + - ``codomain`` -- a Hecke module, which should be of the same type as + self, or a positive integer (in which case Sage will use + :meth:`~hecke_module_of_level` to find the "natural" module of the + corresponding level). + - ``t`` -- integer; the parameter of the degeneracy map, i.e., the map + is related to `f(q)` - `f(q^t)` - OUTPUT: A morphism from ``self`` to ``codomain``. + OUTPUT: a morphism from ``self`` to ``codomain`` EXAMPLES:: @@ -464,18 +462,18 @@ def fcp(self, n, var='x'): INPUT: - - ``self`` -- Hecke module invariant under the Hecke operator of index - `n`. + - ``self`` -- Hecke module invariant under the Hecke operator of index + `n` - - ``n`` --- a positive integer. + - ``n`` --- a positive integer. - - ``var`` --- variable of polynomial (default ``'x'``) + - ``var`` --- variable of polynomial (default: ``'x'``) OUTPUT: - - ``list`` -- list of the pairs `(g,e)`, where `g` is an - irreducible factor of the characteristic polynomial of `T_n`, and `e` - is its multiplicity. + - ``list`` -- list of the pairs `(g,e)`, where `g` is an + irreducible factor of the characteristic polynomial of `T_n`, and `e` + is its multiplicity. EXAMPLES:: @@ -543,7 +541,7 @@ def hecke_module_of_level(self, level): Return the Hecke module corresponding to ``self`` at the given level, which should be either a divisor or a multiple of the level of ``self``. - This raises :class:`NotImplementedError`, and should be overridden in + This raises :exc:`NotImplementedError`, and should be overridden in derived classes. EXAMPLES:: @@ -562,13 +560,11 @@ def hecke_images(self, i, v): INPUT: - - ``i`` -- nonnegative integer - - - ``v`` -- a list of positive integer + - ``i`` -- nonnegative integer - OUTPUT: + - ``v`` -- list of positive integer - - ``matrix`` -- whose rows are the Hecke images + OUTPUT: ``matrix`` -- whose rows are the Hecke images EXAMPLES:: @@ -713,13 +709,12 @@ def linear_combination_of_basis(self, v): r""" Given a list or vector of length equal to the dimension of ``self``, construct the appropriate linear combination of the basis vectors of - self. + ``self``. EXAMPLES:: sage: ModularForms(3, 12).linear_combination_of_basis([1,0,0,0,1]) 2*q + 2049*q^2 + 177147*q^3 + 4196177*q^4 + 48830556*q^5 + O(q^6) - """ return self(v) @@ -729,8 +724,8 @@ def new_submodule(self, p=None): INPUT: - - ``p`` -- (default: ``None``); if not ``None``, return only - the `p`-new submodule. + - ``p`` -- (default: ``None``) if not ``None``, return only + the `p`-new submodule OUTPUT: the new or `p`-new submodule of ``self``, i.e. the intersection of the kernel of the degeneracy lowering maps to level `N/p` (for the @@ -833,8 +828,8 @@ def old_submodule(self, p=None): INPUT: - - ``p`` -- (default: ``None``); if not ``None``, return only the `p`-old - submodule. + - ``p`` -- (default: ``None``) if not ``None``, return only the `p`-old + submodule OUTPUT: the old or `p`-old submodule of ``self`` @@ -866,7 +861,6 @@ def old_submodule(self, p=None): Modular Symbols subspace of dimension 0 of Modular Symbols space of dimension 40 and level 42, weight 6, character [-1, -1], sign 1, over Rational Field - """ try: if self.__is_old[p]: @@ -979,12 +973,12 @@ def submodule_from_nonembedded_module(self, V, Vdual=None, check=True): INPUT: - - ``V`` -- submodule of ambient free module of the same rank as the - rank of self. + - ``V`` -- submodule of ambient free module of the same rank as the + rank of ``self`` - - ``Vdual`` -- used to pass in dual submodule (may be ``None``) + - ``Vdual`` -- used to pass in dual submodule (may be ``None``) - - ``check`` -- whether to check that submodule is Hecke-equivariant + - ``check`` -- whether to check that submodule is Hecke-equivariant OUTPUT: Hecke submodule of ``self`` diff --git a/src/sage/modular/hecke/element.py b/src/sage/modular/hecke/element.py index df828ebca66..4a82899325a 100644 --- a/src/sage/modular/hecke/element.py +++ b/src/sage/modular/hecke/element.py @@ -282,9 +282,9 @@ def is_eisenstein(self) -> bool: def is_new(self, p=None) -> bool: r""" - Return ``True`` if this element is p-new. + Return ``True`` if this element is `p`-new. - If p is ``None``, return ``True`` if the element is new. + If `p` is ``None``, return ``True`` if the element is new. EXAMPLES:: @@ -299,9 +299,9 @@ def is_new(self, p=None) -> bool: def is_old(self, p=None) -> bool: r""" - Return ``True`` if this element is p-old. + Return ``True`` if this element is `p`-old. - If p is ``None``, return ``True`` if the element is old. + If `p` is ``None``, return ``True`` if the element is old. EXAMPLES:: diff --git a/src/sage/modular/hecke/hecke_operator.py b/src/sage/modular/hecke/hecke_operator.py index eb0edef0e74..c7d39270f63 100644 --- a/src/sage/modular/hecke/hecke_operator.py +++ b/src/sage/modular/hecke/hecke_operator.py @@ -163,7 +163,7 @@ def hecke_module_morphism(self): def _add_(self, other): """ - Add self to other. + Add ``self`` to ``other``. EXAMPLES:: @@ -230,8 +230,8 @@ def __rmul__(self, left): def _sub_(self, other): """ - Compute the difference of self and other, where other has already been - coerced into the parent of self. + Compute the difference of ``self`` and ``other``, where ``other`` has + already been coerced into the parent of ``self``. EXAMPLES:: @@ -273,11 +273,9 @@ def charpoly(self, var='x'): INPUT: + - ``var`` -- string (default: ``'x'``) - - ``var`` -- string (default: 'x') - - - OUTPUT: a monic polynomial in the given variable. + OUTPUT: a monic polynomial in the given variable EXAMPLES:: @@ -424,7 +422,7 @@ class HeckeAlgebraElement_matrix(HeckeAlgebraElement): def __init__(self, parent, A): r""" Initialise an element from a matrix. This *must* be over the base ring - of self and have the right size. + of ``self`` and have the right size. This is a bit overkill as similar checks will be performed by the call and coerce methods of the parent of self, but it can't hurt to be @@ -462,8 +460,8 @@ def __init__(self, parent, A): def _richcmp_(self, other, op): r""" - Compare self to other, where the coercion model has already ensured - that other has the same parent as self. + Compare ``self`` to ``other``, where the coercion model has already ensured + that ``other`` has the same parent as ``self``. EXAMPLES:: @@ -486,7 +484,7 @@ def _richcmp_(self, other, op): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -500,7 +498,7 @@ def _repr_(self): def _latex_(self): r""" - Latex representation of self (just prints the matrix) + Latex representation of ``self`` (just prints the matrix). EXAMPLES:: @@ -527,8 +525,8 @@ def matrix(self): def _mul_(self, other): r""" - Multiply self by other (which has already been coerced into an element - of the parent of self). + Multiply ``self`` by ``other`` (which has already been coerced into an element + of the parent of ``self``). EXAMPLES:: @@ -625,8 +623,8 @@ def __init__(self, parent, n): def _richcmp_(self, other, op): r""" - Compare self and other (where the coercion model has already ensured - that self and other have the same parent). Hecke operators on the same + Compare ``self`` and ``other`` (where the coercion model has already ensured + that ``self`` and ``other`` have the same parent). Hecke operators on the same space compare as equal if and only if their matrices are equal, so we check if the indices are the same and if not we compute the matrices (which is potentially expensive). @@ -661,7 +659,7 @@ def _richcmp_(self, other, op): def _repr_(self): r""" - String representation of self + String representation of ``self``. EXAMPLES:: @@ -672,7 +670,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation of self + LaTeX representation of ``self``. EXAMPLES:: diff --git a/src/sage/modular/hecke/module.py b/src/sage/modular/hecke/module.py index cd8a1c70373..e22ed609da6 100644 --- a/src/sage/modular/hecke/module.py +++ b/src/sage/modular/hecke/module.py @@ -233,7 +233,7 @@ def _compute_hecke_matrix(self, n, **kwds): def _compute_hecke_matrix_prime(self, p, **kwds): """ - Compute and return the matrix of the p-th Hecke operator for p prime. + Compute and return the matrix of the `p`-th Hecke operator for `p` prime. Derived classes should overload this function, and they will inherit the machinery for calculating general Hecke operators. @@ -444,11 +444,9 @@ def level(self): INPUT: - - ``ModularSymbols self`` -- an arbitrary space of modular symbols + - ``ModularSymbols self`` -- an arbitrary space of modular symbols - OUTPUT: - - - ``int`` -- the level + OUTPUT: integer; the level EXAMPLES:: @@ -462,7 +460,7 @@ def rank(self): r""" Return the rank of this module over its base ring. - This raises a :class:`NotImplementedError`, since this is an + This raises a :exc:`NotImplementedError`, since this is an abstract base class. EXAMPLES:: @@ -479,7 +477,7 @@ def submodule(self, X): Return the submodule of ``self`` corresponding to ``X``. As this is an abstract base class, this raises a - :class:`NotImplementedError`. + :exc:`NotImplementedError`. EXAMPLES:: @@ -535,7 +533,7 @@ def _repr_(self): def __getitem__(self, n): r""" - Return the nth term in the decomposition of ``self``. + Return the `n`-th term in the decomposition of ``self``. See the docstring for :meth:`decomposition` for further information. @@ -559,7 +557,6 @@ def __hash__(self): sage: MS = ModularSymbols(22) sage: hash(MS) == hash((MS.weight(), MS.level(), MS.base_ring())) True - """ return hash((self.__weight, self.level(), self.base_ring())) @@ -618,7 +615,7 @@ def _eigen_nonzero_element(self, n=1): Return `T_n(x)` where `x` is a sparse modular symbol such that the image of `x` is nonzero under the dual projection map associated to this space, and `T_n` is the - `n^{th}` Hecke operator. + `n`-th Hecke operator. Used in the :meth:`dual_eigenvector` and :meth:`eigenvalue` methods. @@ -745,7 +742,7 @@ def ambient_hecke_module(self): r""" Return the ambient module associated to this module. - As this is an abstract base class, raise :class:`NotImplementedError`. + As this is an abstract base class, raise :exc:`NotImplementedError`. EXAMPLES:: @@ -930,21 +927,19 @@ def decomposition(self, bound=None, anemic=True, height_guess=1, INPUT: - - ``anemic`` -- bool (default: ``True``), if True, use only - Hecke operators of index coprime to the level. + - ``anemic`` -- boolean (default: ``True``); if ``True``, use only + Hecke operators of index coprime to the level - - ``bound`` -- int or None, (default: None). If None, - use all Hecke operators up to the Sturm bound, and hence obtain the - same result as one would obtain by using every element of the Hecke - ring. If a fixed integer, decompose using only Hecke operators - `T_p`, with `p` prime, up to bound. - - ``sort_by_basis`` -- bool (default: ``False``); If True the resulting - decomposition will be sorted as if it was free modules, ignoring the - Hecke module structure. This will save a lot of time. + - ``bound`` -- integer or ``None`` (default: ``None``); if ``None``, + use all Hecke operators up to the Sturm bound, and hence obtain the + same result as one would obtain by using every element of the Hecke + ring. If a fixed integer, decompose using only Hecke operators + `T_p`, with `p` prime, up to bound. + - ``sort_by_basis`` -- boolean (default: ``False``); if ``True`` the + resulting decomposition will be sorted as if it was free modules, + ignoring the Hecke module structure. This will save a lot of time. - OUTPUT: - - - ``list`` -- a list of subspaces of ``self``. + OUTPUT: list of subspaces of ``self`` EXAMPLES:: @@ -1086,15 +1081,17 @@ def dual_eigenvector(self, names='alpha', lift=True, nz=None): INPUT: - - ``name`` -- print name of generator for eigenvalue - field. + - ``name`` -- print name of generator for eigenvalue + field - - ``lift`` -- bool (default: ``True``) + - ``lift`` -- boolean (default: ``True``) - - ``nz`` -- if not ``None``, then normalize vector so dot - product with this basis vector of ambient space is 1. + - ``nz`` -- if not ``None``, then normalize vector so dot + product with this basis vector of ambient space is 1 - OUTPUT: A vector with entries possibly in an extension of the base + OUTPUT: + + A vector with entries possibly in an extension of the base ring. This vector is an eigenvector for all Hecke operators acting via their transpose. @@ -1206,7 +1203,7 @@ def dual_eigenvector(self, names='alpha', lift=True, nz=None): def dual_hecke_matrix(self, n): """ - Return the matrix of the `n^{th}` Hecke operator acting on the dual + Return the matrix of the `n`-th Hecke operator acting on the dual embedded representation of ``self``. EXAMPLES:: @@ -1228,14 +1225,14 @@ def dual_hecke_matrix(self, n): def eigenvalue(self, n, name='alpha'): r""" Assuming that ``self`` is a simple space, return the eigenvalue of the - `n^{th}` Hecke operator on ``self``. + `n`-th Hecke operator on ``self``. INPUT: - - ``n`` -- index of Hecke operator + - ``n`` -- index of Hecke operator - - ``name`` -- print representation of generator of - eigenvalue field + - ``name`` -- print representation of generator of + eigenvalue field EXAMPLES:: @@ -1263,11 +1260,11 @@ def eigenvalue(self, n, name='alpha'): #. In fact there are `d` systems of eigenvalues associated to self, where `d` is the rank of - self. Each of the systems of eigenvalues is conjugate + ``self``. Each of the systems of eigenvalues is conjugate over the base field. This function chooses one of the systems and consistently returns eigenvalues from that system. Thus these are the coefficients `a_n` for - `n\geq 1` of a modular eigenform attached to self. + `n\geq 1` of a modular eigenform attached to ``self``. #. This function works even for Eisenstein subspaces, though it will not give the constant coefficient of one @@ -1370,7 +1367,7 @@ def gens(self): def gen(self, n): r""" - Return the nth basis vector of the space. + Return the `n`-th basis vector of the space. EXAMPLES:: @@ -1381,8 +1378,7 @@ def gen(self, n): def hecke_matrix(self, n): """ - Return the matrix of the `n^{th}` Hecke operator acting on given - basis. + Return the matrix of the `n`-th Hecke operator acting on given basis. EXAMPLES:: @@ -1405,10 +1401,7 @@ def hecke_operator(self, n): INPUT: - - ``ModularSymbols self`` -- Hecke equivariant space of - modular symbols - - - ``int n`` -- an integer at least 1. + - ``n`` -- integer at least 1 EXAMPLES:: @@ -1460,7 +1453,7 @@ def diamond_bracket_matrix(self, d): def diamond_bracket_operator(self, d): r""" - Return the diamond bracket operator `\langle d \rangle` on self. + Return the diamond bracket operator `\langle d \rangle` on ``self``. EXAMPLES:: @@ -1472,7 +1465,7 @@ def diamond_bracket_operator(self, d): def T(self, n): r""" - Return the `n^{th}` Hecke operator `T_n`. + Return the `n`-th Hecke operator `T_n`. This function is a synonym for :meth:`hecke_operator`. @@ -1486,12 +1479,12 @@ def T(self, n): def hecke_polynomial(self, n, var='x'): """ - Return the characteristic polynomial of the `n^{th}` Hecke operator + Return the characteristic polynomial of the `n`-th Hecke operator acting on this space. INPUT: - - ``n`` -- integer + - ``n`` -- integer OUTPUT: a polynomial @@ -1507,7 +1500,7 @@ def is_simple(self): Return ``True`` if this space is simple as a module for the corresponding Hecke algebra. - This raises :class:`NotImplementedError`, as this is an abstract base + This raises :exc:`NotImplementedError`, as this is an abstract base class. EXAMPLES:: @@ -1599,14 +1592,14 @@ def projection(self): ALGORITHM: Let `B` be the matrix whose columns are obtained by concatenating together a basis for the factors of the ambient - space. Then the projection matrix onto self is the submatrix of + space. Then the projection matrix onto ``self`` is the submatrix of `B^{-1}` obtained from the rows corresponding to self, - i.e., if the basis vectors for self appear as columns `n` + i.e., if the basis vectors for ``self`` appear as columns `n` through `m` of `B`, then the projection matrix is got from rows `n` through `m` of `B^{-1}`. This is because projection with respect to the B basis is just given by an `m-n+1` row slice `P` of a diagonal - matrix D with 1's in the `n` through `m` positions, + matrix D with 1s in the `n` through `m` positions, so projection with respect to the standard basis is given by `P\cdot B^{-1}`, which is just rows `n` through `m` of `B^{-1}`. @@ -1673,14 +1666,14 @@ def system_of_eigenvalues(self, n, name='alpha'): r""" Assuming that ``self`` is a simple space of modular symbols, return the eigenvalues `[a_1, \ldots, a_nmax]` of the Hecke - operators on self. See ``self.eigenvalue(n)`` for more + operators on ``self``. See ``self.eigenvalue(n)`` for more details. INPUT: - - ``n`` -- number of eigenvalues + - ``n`` -- number of eigenvalues - - ``alpha`` -- name of generate for eigenvalue field + - ``alpha`` -- name of generate for eigenvalue field EXAMPLES: @@ -1741,11 +1734,9 @@ def weight(self): INPUT: - - ``self`` -- an arbitrary Hecke module - - OUTPUT: + - ``self`` -- an arbitrary Hecke module - - ``int`` -- the weight + OUTPUT: integer; the weight EXAMPLES:: diff --git a/src/sage/modular/hecke/morphism.py b/src/sage/modular/hecke/morphism.py index 03da3dd77a9..d9dff926fbe 100644 --- a/src/sage/modular/hecke/morphism.py +++ b/src/sage/modular/hecke/morphism.py @@ -103,21 +103,23 @@ class HeckeModuleMorphism_matrix(MatrixMorphism, HeckeModuleMorphism): ... TypeError: Incompatible composition of morphisms: domain of left morphism must be codomain of right. """ - def __init__(self, parent, A, name='', side="left"): + def __init__(self, parent, A, name='', side='left'): """ INPUT: - ``parent`` -- ModularSymbolsHomspace - - ``A`` -- Matrix + - ``A`` -- matrix - - ``name`` -- str (defaults to '') name of the morphism + - ``name`` -- string (default: ``''``); name of the morphism (used for printing) + - ``side`` -- string (default: ``'left'``) + EXAMPLES:: sage: M = ModularSymbols(6) - sage: t = M.Hom(M)(matrix(QQ,3,3,srange(9)), name="spam"); t + sage: t = M.Hom(M)(matrix(QQ,3,3,srange(9)), name='spam'); t Hecke module morphism spam defined by the matrix [0 1 2] [3 4 5] @@ -139,7 +141,7 @@ def name(self, new=None): EXAMPLES:: sage: M = ModularSymbols(6) - sage: t = M.Hom(M)(matrix(QQ,3,3,srange(9)), name="spam"); t + sage: t = M.Hom(M)(matrix(QQ,3,3,srange(9)), name='spam'); t Hecke module morphism spam defined by ... sage: t.name() 'spam' @@ -152,7 +154,7 @@ def name(self, new=None): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: diff --git a/src/sage/modular/hecke/submodule.py b/src/sage/modular/hecke/submodule.py index 8fc412013c6..c542d095339 100644 --- a/src/sage/modular/hecke/submodule.py +++ b/src/sage/modular/hecke/submodule.py @@ -66,10 +66,10 @@ def __init__(self, ambient, submodule, dual_free_module=None, check=True): be invariant under all Hecke operators. - ``dual_free_module`` -- the submodule of the dual of the ambient - module corresponding to this submodule (or None). + module corresponding to this submodule (or ``None``) - ``check`` -- whether or not to explicitly check that the submodule is - Hecke equivariant. + Hecke equivariant EXAMPLES:: @@ -110,7 +110,7 @@ def __init__(self, ambient, submodule, dual_free_module=None, check=True): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -124,7 +124,7 @@ def _repr_(self): def __add__(self, other): r""" - Sum of self and other (as submodules of a common ambient + Sum of ``self`` and ``other`` (as submodules of a common ambient module). EXAMPLES:: @@ -170,7 +170,7 @@ def _element_constructor_(self, x, check=True): def __richcmp__(self, other, op): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -201,8 +201,8 @@ def __richcmp__(self, other, op): ################################ def _compute_dual_hecke_matrix(self, n): """ - Compute the matrix for the nth Hecke operator acting on - the dual of self. + Compute the matrix for the `n`-th Hecke operator acting on + the dual of ``self``. EXAMPLES:: @@ -223,9 +223,9 @@ def _compute_dual_hecke_matrix(self, n): def _compute_hecke_matrix(self, n): r""" - Compute the matrix of the nth Hecke operator acting on this space, by + Compute the matrix of the `n`-th Hecke operator acting on this space, by calling the corresponding function for the ambient space and - restricting. If n is not coprime to the level, we check that the + restricting. If `n` is not coprime to the level, we check that the restriction is well-defined. EXAMPLES:: @@ -262,7 +262,7 @@ def _compute_diamond_matrix(self, d): def _compute_atkin_lehner_matrix(self, d): """ Compute the Atkin-Lehner matrix corresponding to the - divisor d of the level of self. + divisor d of the level of ``self``. EXAMPLES:: @@ -283,9 +283,9 @@ def _compute_atkin_lehner_matrix(self, d): def _set_dual_free_module(self, V): """ - Set the dual free module of self to V. Here V must be a vector - space of the same dimension as self, embedded in a space of - the same dimension as the ambient space of self. + Set the dual free module of ``self`` to V. Here V must be a vector + space of the same dimension as ``self``, embedded in a space of + the same dimension as the ambient space of ``self``. EXAMPLES:: @@ -405,23 +405,22 @@ def complement(self, bound=None): def degeneracy_map(self, level, t=1): """ - The t-th degeneracy map from self to the space of ambient modular - symbols of the given level. The level of self must be a divisor or - multiple of level, and t must be a divisor of the quotient. + The `t`-th degeneracy map from ``self`` to the space of ambient modular + symbols of the given level. The level of ``self`` must be a divisor or + multiple of level, and `t` must be a divisor of the quotient. INPUT: + - ``level`` -- positive integer; the level of the codomain of the + map - - ``level`` -- int, the level of the codomain of the - map (positive int). + - ``t`` -- integer; the parameter of the degeneracy map, + i.e., the map is related to `f(q)` - `f(q^t)` - - ``t`` -- int, the parameter of the degeneracy map, - i.e., the map is related to `f(q)` - `f(q^t)`. + OUTPUT: - - OUTPUT: A linear function from self to the space of modular symbols - of given level with the same weight, character, sign, etc., as this - space. + A linear function from ``self`` to the space of modular symbols of given + level with the same weight, character, sign, etc., as this space. EXAMPLES:: @@ -459,12 +458,12 @@ def dual_free_module(self, bound=None, anemic=True, use_star=True): In general this will not be possible, e.g., if this space is not Hecke equivariant, possibly if it is not cuspidal, or if the characteristic is not 0. In all these cases we raise a - :class:`RuntimeError` exception. + :exc:`RuntimeError` exception. - If use_star is True (which is the default), we also use the +/- - eigenspaces for the star operator to find the dual free module of self. - If self does not have a star involution, use_star will automatically be - set to False. + If ``use_star`` is ``True`` (which is the default), we also use the +/- + eigenspaces for the star operator to find the dual free module of ``self``. + If ``self`` does not have a star involution, ``use_star`` will automatically be + set to ``False``. EXAMPLES:: @@ -516,7 +515,6 @@ def dual_free_module(self, bound=None, anemic=True, use_star=True): sage: EllipticCurve('128a').congruence_number() 32 - """ # if we know the complement we can read off the dual module @@ -601,7 +599,7 @@ def dual_free_module(self, bound=None, anemic=True, use_star=True): def free_module(self): """ - Return the free module corresponding to self. + Return the free module corresponding to ``self``. EXAMPLES:: @@ -633,7 +631,7 @@ def module(self): def intersection(self, other): """ - Returns the intersection of self and other, which must both lie in + Return the intersection of ``self`` and ``other``, which must both lie in a common ambient space of modular symbols. EXAMPLES:: @@ -678,8 +676,7 @@ def intersection(self, other): def is_ambient(self): r""" - Return ``True`` if self is an ambient space of modular - symbols. + Return ``True`` if ``self`` is an ambient space of modular symbols. EXAMPLES:: @@ -695,8 +692,8 @@ def is_ambient(self): def is_new(self, p=None): """ - Returns True if this Hecke module is p-new. If p is None, - returns True if it is new. + Return ``True`` if this Hecke module is `p`-new. If `p` is None, + returns ``True`` if it is new. EXAMPLES:: @@ -717,8 +714,8 @@ def is_new(self, p=None): def is_old(self, p=None): """ - Returns True if this Hecke module is p-old. If p is None, - returns True if it is old. + Return ``True`` if this Hecke module is `p`-old. If `p` is ``None``, + returns ``True`` if it is old. EXAMPLES:: @@ -742,7 +739,7 @@ def is_old(self, p=None): def is_submodule(self, V): """ - Returns True if and only if self is a submodule of V. + Return ``True`` if and only if ``self`` is a submodule of V. EXAMPLES:: @@ -785,14 +782,13 @@ def linear_combination_of_basis(self, v): ] sage: S.linear_combination_of_basis([3, 10]) 3*q + 10*q^2 + 756*q^3 - 6384*q^4 + 14490*q^5 + O(q^6) - """ x = self.free_module().linear_combination_of_basis(v) return self(x) def new_submodule(self, p=None): """ - Return the new or p-new submodule of this space of modular + Return the new or `p`-new submodule of this space of modular symbols. EXAMPLES:: @@ -834,7 +830,7 @@ def new_submodule(self, p=None): def nonembedded_free_module(self): """ - Return the free module corresponding to self as an abstract + Return the free module corresponding to ``self`` as an abstract free module, i.e. not as an embedded vector space. EXAMPLES:: @@ -850,7 +846,7 @@ def nonembedded_free_module(self): def old_submodule(self, p=None): r""" - Return the old or p-old submodule of this space of modular + Return the old or `p`-old submodule of this space of modular symbols. EXAMPLES: We compute the old and new submodules of @@ -893,7 +889,7 @@ def old_submodule(self, p=None): def rank(self): r""" - Return the rank of self as a free module over the base ring. + Return the rank of ``self`` as a free module over the base ring. EXAMPLES:: @@ -906,8 +902,8 @@ def rank(self): def submodule(self, M, Mdual=None, check=True): """ - Construct a submodule of self from the free module M, which - must be a subspace of self. + Construct a submodule of ``self`` from the free module M, which + must be a subspace of ``self``. EXAMPLES:: @@ -933,19 +929,17 @@ def submodule(self, M, Mdual=None, check=True): def submodule_from_nonembedded_module(self, V, Vdual=None, check=True): """ - Construct a submodule of self from V. Here V should be a + Construct a submodule of ``self`` from V. Here V should be a subspace of a vector space whose dimension is the same as that - of self. + of ``self``. INPUT: + - ``V`` -- submodule of ambient free module of the same + rank as the rank of ``self`` - - ``V`` -- submodule of ambient free module of the same - rank as the rank of self. - - - ``check`` -- whether to check that V is Hecke - equivariant. - + - ``check`` -- whether to check that V is Hecke + equivariant OUTPUT: Hecke submodule of self diff --git a/src/sage/modular/hypergeometric_misc.pxd b/src/sage/modular/hypergeometric_misc.pxd index 00bf9a97e9a..ccd013ca2ee 100644 --- a/src/sage/modular/hypergeometric_misc.pxd +++ b/src/sage/modular/hypergeometric_misc.pxd @@ -1,2 +1,3 @@ -cpdef hgm_coeffs(long long p, int f, int prec, gamma, m, int D, +cpdef hgm_coeffs(long long p, unsigned int f, + int prec, gamma, m, int D, gtable, int gtable_prec, bint use_longs) diff --git a/src/sage/modular/hypergeometric_misc.pyx b/src/sage/modular/hypergeometric_misc.pyx index 3be8e4dd545..f3e37b515d9 100644 --- a/src/sage/modular/hypergeometric_misc.pyx +++ b/src/sage/modular/hypergeometric_misc.pyx @@ -6,7 +6,8 @@ from cpython cimport array from cysignals.signals cimport sig_check from sage.rings.integer cimport Integer -cpdef hgm_coeffs(long long p, int f, int prec, gamma, m, int D, +cpdef hgm_coeffs(long long p, unsigned int f, + int prec, gamma, m, int D, gtable, int gtable_prec, bint use_longs): r""" Compute coefficients for the hypergeometric trace formula. @@ -35,8 +36,8 @@ cpdef hgm_coeffs(long long p, int f, int prec, gamma, m, int D, """ from sage.rings.padics.factory import Zp - cdef int gl, j, k, l, v, gv - cdef long long i, q1, w, w1, w2, q2, r, r1 + cdef int gl, j, k, v, gv + cdef long long i, l, q1, w, w1, w2, q2, r, r1 cdef bint flip, use_longlongs q1 = p ** f - 1 diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index 8e726fc877e..5418a1fff58 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -104,23 +104,21 @@ def characteristic_polynomial_from_traces(traces, d, q, i, sign, deg=None, use_f INPUT: - - ``traces`` -- a list of integers `t_1, \dots, t_k` + - ``traces`` -- list of integers `t_1, \dots, t_k` - ``d`` -- the degree of the characteristic polynomial - ``q`` -- power of a prime number - - ``i`` -- integer, the weight in the motivic sense + - ``i`` -- integer; the weight in the motivic sense - - ``sign`` -- integer, the sign + - ``sign`` -- integer; the sign - - ``deg`` -- an integer or ``None`` + - ``deg`` -- integer or ``None`` - - ``use_fe`` -- a boolean (default: ``True``) + - ``use_fe`` -- boolean (default: ``True``) - OUTPUT: - - a polynomial + OUTPUT: a polynomial If ``deg`` is specified, only the coefficients up to this degree (inclusive) are computed. @@ -189,6 +187,7 @@ def characteristic_polynomial_from_traces(traces, d, q, i, sign, deg=None, use_f data[k] = sign * coeffs[d - k] * q**(i * (k - d / 2)) return ring(data) + def enumerate_hypergeometric_data(d, weight=None): r""" Return an iterator over parameters of hypergeometric motives (up to swapping). @@ -197,7 +196,7 @@ def enumerate_hypergeometric_data(d, weight=None): - ``d`` -- the degree - - ``weight`` -- optional integer, to specify the motivic weight + - ``weight`` -- (optional) integer; specifies the motivic weight EXAMPLES:: @@ -231,7 +230,7 @@ def possible_hypergeometric_data(d, weight=None) -> list: - ``d`` -- the degree - - ``weight`` -- optional integer, to specify the motivic weight + - ``weight`` -- (optional) integer; specifies the motivic weight EXAMPLES:: @@ -281,7 +280,7 @@ def alpha_to_cyclotomic(alpha) -> list: The output represent a product of cyclotomic polynomials with exactly the given roots. Note that the multiplicity of `r/s` in the list - must be independent of `r`; otherwise, a :class:`ValueError` will be raised. + must be independent of `r`; otherwise, a :exc:`ValueError` will be raised. This is the inverse of :func:`cyclotomic_to_alpha`. @@ -321,11 +320,9 @@ def capital_M(n): INPUT: - - ``n`` -- an integer - - OUTPUT: + - ``n`` -- integer - a rational + OUTPUT: a rational EXAMPLES:: @@ -379,7 +376,7 @@ def gamma_list_to_cyclotomic(galist): INPUT: - - ``galist`` -- a list of integers, where an integer `n` represents + - ``galist`` -- list of integers, where an integer `n` represents the power `(x^{|n|} - 1)^{\operatorname{sgn}(n)}` OUTPUT: @@ -421,7 +418,7 @@ def __init__(self, cyclotomic=None, alpha_beta=None, gamma_list=None): INPUT: - three possibilities are offered, each describing a quotient + Three possibilities are offered, each describing a quotient of products of cyclotomic polynomials. - ``cyclotomic`` -- a pair of lists of nonnegative integers, @@ -704,7 +701,6 @@ def zigzag(self, x, flip_beta=False): sage: H = Hyp(cyclotomic=([5], [1,1,1,1])) sage: [H.zigzag(x) for x in [0,1/6,1/4,1/2,3/4,5/6]] [-4, -4, -3, -2, -1, 0] - """ alpha = self._alpha beta = self._beta @@ -931,7 +927,7 @@ def E_polynomial(self, vars=None): INPUT: - - ``vars`` -- optional pair of variables (default: `u,v`) + - ``vars`` -- (optional) pair of variables (default: `u,v`) REFERENCES: @@ -999,9 +995,7 @@ def M_value(self): """ Return the `M` coefficient that appears in the trace formula. - OUTPUT: - - a rational + OUTPUT: a rational .. SEEALSO:: :meth:`canonical_scheme` @@ -1331,17 +1325,15 @@ def padic_H_value(self, p, f, t, prec=None, cache_p=False): - ``p`` -- a prime number - - ``f`` -- an integer such that `q = p^f` + - ``f`` -- integer such that `q = p^f` - ``t`` -- a rational parameter - ``prec`` -- precision (optional) - - ``cache_p`` -- a boolean + - ``cache_p`` -- boolean - OUTPUT: - - an integer + OUTPUT: integer EXAMPLES: @@ -1476,17 +1468,15 @@ def H_value(self, p, f, t, ring=None): - ``p`` -- a prime number - - ``f`` -- an integer such that `q = p^f` + - ``f`` -- integer such that `q = p^f` - ``t`` -- a rational parameter - - ``ring`` -- optional (default: :class:`UniversalCyclotomicfield`) + - ``ring`` -- (default: :class:`UniversalCyclotomicfield`) The ring could be also ``ComplexField(n)`` or ``QQbar``. - OUTPUT: - - an integer + OUTPUT: integer .. WARNING:: @@ -1496,9 +1486,11 @@ def H_value(self, p, f, t, ring=None): Using instead :class:`UniversalCyclotomicfield`, this is much slower than the `p`-adic version :meth:`padic_H_value`. + Unlike in :meth:`padic_H_value`, tame and wild primes are not supported. + EXAMPLES: - With values in the UniversalCyclotomicField (slow):: + With values in the :class:`UniversalCyclotomicField` (slow):: sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp sage: H = Hyp(alpha_beta=([1/2]*4, [0]*4)) @@ -1513,7 +1505,7 @@ def H_value(self, p, f, t, ring=None): sage: [H.H_value(13,i,-1) for i in range(1,3)] # not tested [-84, -1420] - With values in ComplexField:: + With values in :class:`ComplexField`:: sage: [H.H_value(5,i,-1, ComplexField(60)) for i in range(1,3)] [-4, 276] @@ -1630,7 +1622,6 @@ def sign(self, t, p): sage: H = Hyp(cyclotomic=([1,1,1], [6,2])) sage: [H.sign(4,p) for p in [5,7,11,13,17,19]] [1, 1, -1, -1, 1, 1] - """ t = QQ(t) if 0 in self._alpha: @@ -1663,9 +1654,7 @@ def euler_factor_tame_contribution(self, t, p, mo, deg=None): - ``deg`` -- integer (optional) - OUTPUT: - - a polynomial + OUTPUT: a polynomial If ``deg`` is specified, the output is truncated to that degree (inclusive). @@ -1750,15 +1739,13 @@ def euler_factor(self, t, p, deg=None, cache_p=False): INPUT: - - ``t`` -- rational number, not 0 or 1 + - ``t`` -- rational number, not 0 - ``p`` -- prime number of good reduction - ``deg`` -- integer or ``None`` - OUTPUT: - - a polynomial + OUTPUT: a polynomial See [Benasque2009]_ for explicit examples of Euler factors. @@ -1837,6 +1824,15 @@ def euler_factor(self, t, p, deg=None, cache_p=False): sage: H.euler_factor(1/7^4, 7) 7*T^3 + 7*T^2 + T + 1 + This is an example with `t = 1`:: + + sage: H = Hyp(cyclotomic=[[4,2], [3,1]]) + sage: H.euler_factor(1, 7) + -T^2 + 1 + sage: H = Hyp(cyclotomic=[[5], [1,1,1,1]]) + sage: H.euler_factor(1, 7) + 343*T^2 - 6*T + 1 + TESTS:: sage: H1 = Hyp(alpha_beta=([1,1,1], [1/2,1/2,1/2])) @@ -1926,7 +1922,7 @@ def euler_factor(self, t, p, deg=None, cache_p=False): - [Watkins]_ """ t = QQ(t) - if t in [0, 1]: + if t == 0: raise ValueError('invalid t') if not is_prime(p): raise ValueError('p not prime') @@ -2003,7 +1999,7 @@ def euler_factor(self, t, p, deg=None, cache_p=False): ans = characteristic_polynomial_from_traces(traces, d, p, w, sign, deg=deg) # In the multiplicative case, we sometimes need to add extra factors. - if typ == "mult": + if typ == "mult" and t != 1: if self.degree() % 2 == 0: ans *= tmp if w % 2 == 0 and (t-1).valuation(p) % 2 == 0: diff --git a/src/sage/modular/local_comp/liftings.py b/src/sage/modular/local_comp/liftings.py index dcb901cc3a1..3cef125420d 100644 --- a/src/sage/modular/local_comp/liftings.py +++ b/src/sage/modular/local_comp/liftings.py @@ -87,7 +87,7 @@ def lift_matrix_to_sl2z(A, N): - ``A`` -- list of 4 integers defining a `2 \times 2` matrix - - `N` -- positive integer + - ``N`` -- positive integer EXAMPLES:: diff --git a/src/sage/modular/local_comp/local_comp.py b/src/sage/modular/local_comp/local_comp.py index 0fb990c17de..04d9123ab57 100644 --- a/src/sage/modular/local_comp/local_comp.py +++ b/src/sage/modular/local_comp/local_comp.py @@ -20,22 +20,23 @@ - Jared Weinstein """ -from sage.structure.sage_object import SageObject -from sage.rings.integer_ring import ZZ +from sage.structure.sage_object import SageObject +from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring import polygen from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.misc.abstract_method import abstract_method -from sage.misc.cachefunc import cached_method -from sage.misc.lazy_import import lazy_import -from sage.misc.verbose import verbose -from sage.misc.flatten import flatten -from sage.modular.modform.element import Newform -from sage.structure.sequence import Sequence +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import +from sage.misc.verbose import verbose +from sage.misc.flatten import flatten +from sage.modular.modform.element import Newform +from sage.structure.sequence import Sequence lazy_import('sage.rings.qqbar', 'QQbar') -from .type_space import TypeSpace -from .smoothchar import SmoothCharacterGroupQp, SmoothCharacterGroupUnramifiedQuadratic, SmoothCharacterGroupRamifiedQuadratic +from .type_space import TypeSpace +from .smoothchar import SmoothCharacterGroupQp, SmoothCharacterGroupUnramifiedQuadratic, SmoothCharacterGroupRamifiedQuadratic + def LocalComponent(f, p, twist_factor=None): r""" @@ -44,11 +45,11 @@ def LocalComponent(f, p, twist_factor=None): INPUT: - - ``f`` (:class:`~sage.modular.modform.element.Newform`) a newform of weight `k \ge 2` - - ``p`` (integer) a prime - - ``twist_factor`` (integer) an integer congruent to `k` modulo 2 (default: `k - 2`) + - ``f`` -- (:class:`~sage.modular.modform.element.Newform`) a newform of weight `k \ge 2` + - ``p`` -- integer; prime + - ``twist_factor`` -- integer congruent to `k` modulo 2 (default: `k - 2`) - .. note:: + .. NOTE:: The argument ``twist_factor`` determines the choice of normalisation: if it is set to `j \in \ZZ`, then the central character of `\pi_{f, \ell}` maps `\ell` @@ -115,6 +116,7 @@ def LocalComponent(f, p, twist_factor=None): mintwist = LocalComponent(g, p, twist_factor) return ImprimitiveLocalComponent(f, p, twist_factor, mintwist, chi) + class LocalComponentBase(SageObject): r""" Base class for local components of newforms. Not to be directly instantiated; use the :func:`~LocalComponent` constructor function. @@ -169,7 +171,7 @@ def check_tempered(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -298,7 +300,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Return True if ``self != other``. + Return ``True`` if ``self != other``. EXAMPLES:: @@ -316,6 +318,7 @@ def __ne__(self, other): """ return not (self == other) + class PrimitiveLocalComponent(LocalComponentBase): r""" Base class for primitive (twist-minimal) local components. @@ -323,7 +326,7 @@ class PrimitiveLocalComponent(LocalComponentBase): def is_primitive(self): r""" - Return True if this local component is primitive (has minimal level + Return ``True`` if this local component is primitive (has minimal level among its character twists). EXAMPLES:: @@ -346,6 +349,7 @@ def minimal_twist(self): """ return self + class PrincipalSeries(PrimitiveLocalComponent): r""" A principal series representation. This is an abstract base class, not to @@ -399,6 +403,7 @@ def characters(self): """ pass + class UnramifiedPrincipalSeries(PrincipalSeries): r""" An unramified principal series representation of `{\rm GL}_2(\QQ_p)` @@ -445,7 +450,7 @@ def characters(self): `\pi_{f, p}` is equal to the principal series `\pi(\chi_1, \chi_2)`. These are the unramified characters mapping `p` to the roots of the Satake polynomial, so in most cases (but not always) they will be defined over an - extension of the coefficient field of self. + extension of the coefficient field of ``self``. EXAMPLES:: @@ -469,6 +474,7 @@ def characters(self): G = SmoothCharacterGroupQp(self.prime(), d.parent()) return Sequence([G.character(0, [d]), G.character(0, [self.newform()[self.prime()] - d])], cr=True, universe=G) + class PrimitivePrincipalSeries(PrincipalSeries): r""" A ramified principal series of the form `\pi(\chi_1, \chi_2)` @@ -500,6 +506,7 @@ def characters(self): chi2 = G.character(0, [self.prime()]) * self.central_character() / chi1 return Sequence([chi1, chi2], cr=True, universe=G) + class PrimitiveSpecial(PrimitiveLocalComponent): r""" A primitive special representation: that is, the Steinberg representation @@ -586,6 +593,7 @@ def check_tempered(self): for sigma in K.embeddings(QQbar): assert sigma(c1(p)).abs() == w + class PrimitiveSupercuspidal(PrimitiveLocalComponent): r""" A primitive supercuspidal representation. @@ -971,6 +979,7 @@ def check_tempered(self): for sigma in K.embeddings(QQbar): assert sigma(c1(p)).abs() == sigma(c2(p)).abs() == w + class ImprimitiveLocalComponent(LocalComponentBase): r""" A smooth representation which is not of minimal level among its character @@ -991,7 +1000,7 @@ def __init__(self,newform, prime, twist_factor, min_twist, chi): def is_primitive(self): r""" - Return True if this local component is primitive (has minimal level + Return ``True`` if this local component is primitive (has minimal level among its character twists). EXAMPLES:: diff --git a/src/sage/modular/local_comp/smoothchar.py b/src/sage/modular/local_comp/smoothchar.py index cfce7550fda..e2cadd4219a 100644 --- a/src/sage/modular/local_comp/smoothchar.py +++ b/src/sage/modular/local_comp/smoothchar.py @@ -98,7 +98,7 @@ def __init__(self, parent, c, values_on_gens): def _check_level(self): r""" - Checks that this character has the level it claims to have, and if not, + Check that this character has the level it claims to have, and if not, decrement the level appropriately. This is called by :meth:`__init__`. EXAMPLES:: @@ -266,7 +266,7 @@ def _repr_(self): def _mul_(self, other): r""" - Product of self and other. + Product of ``self`` and ``other``. EXAMPLES:: @@ -287,7 +287,7 @@ def _mul_(self, other): def __invert__(self): r""" - Multiplicative inverse of self. + Multiplicative inverse of ``self``. EXAMPLES:: @@ -379,7 +379,7 @@ def _element_constructor_(self, x): r""" Construct an element of this group from ``x`` (possibly noncanonically). This only works if ``x`` is a character of a field containing the field of - self, whose values lie in a field that can be converted into self. + ``self``, whose values lie in a field that can be converted into ``self``. EXAMPLES:: @@ -495,7 +495,6 @@ def _coerce_map_from_(self, other): sage: G = SmoothCharacterGroupUnramifiedQuadratic(3, QQ) sage: G.character(0, [1]).base_extend(K) Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 0, mapping 3 |--> 1 - """ return (isinstance(other, SmoothCharacterGroupGeneric) and other.number_field() == self.number_field() @@ -547,7 +546,6 @@ def base_extend(self, ring): Traceback (most recent call last): ... TypeError: no canonical coercion from Rational Field to Ring of integers modulo 3 - """ if not ring.has_coerce_map_from(self.base_ring()): ring.coerce(self.base_ring().an_element()) @@ -558,7 +556,7 @@ def base_extend(self, ring): @abstract_method def _field_name(self): r""" - A string representing the name of the p-adic field of which this is the + A string representing the name of the `p`-adic field of which this is the character group. To be overridden by derived subclasses. EXAMPLES:: @@ -573,7 +571,7 @@ def _field_name(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -587,7 +585,7 @@ def _repr_(self): def ideal(self, level): r""" Return the ``level``-th power of the maximal ideal of the ring of - integers of the p-adic field. Since we approximate by using number + integers of the `p`-adic field. Since we approximate by using number field arithmetic, what is actually returned is an ideal in a number field. @@ -684,14 +682,14 @@ def character(self, level, values_on_gens): INPUT: - - ``level`` (integer) an integer `\ge 0` - - ``values_on_gens`` (sequence) a sequence of elements of length equal + - ``level`` -- integer an integer `\ge 0` + - ``values_on_gens`` -- sequence a sequence of elements of length equal to the length of ``self.unit_gens(level)``. The values should be convertible (that is, possibly noncanonically) into the base ring of self; they should all be units, and all but the last must be roots of unity (of the orders given by ``self.exponents(level)``. - .. note:: + .. NOTE:: The character returned may have level less than ``level`` in general. @@ -943,7 +941,7 @@ def change_ring(self, ring): Return the group of characters of the same field but with values in a different ring. This need not have anything to do with the original base ring, and in particular there won't generally be a coercion map - from self to the new group -- use + from ``self`` to the new group -- use :meth:`~SmoothCharacterGroupGeneric.base_extend` if you want this. EXAMPLES:: @@ -1024,7 +1022,7 @@ def subgroup_gens(self, level): INPUT: - - ``c`` (integer) an integer `\ge 1` + - ``c`` -- integer `\ge 1` EXAMPLES:: @@ -1105,6 +1103,7 @@ def quadratic_chars(self): nr = self.character(0, [-1]) return sorted([nr] + list(ram) + [f*nr for f in ram]) + class SmoothCharacterGroupQuadratic(SmoothCharacterGroupGeneric): r""" The group of smooth characters of `E^\times`, where `E` is a quadratic extension of `\QQ_p`. @@ -1305,16 +1304,16 @@ def extend_character(self, level, chi, vals, check=True): INPUT: - - ``chi``: a smooth character of `\QQ_p`, where `p` is the residue - characteristic of `F`, with values in the base ring of self (or some + - ``chi`` -- a smooth character of `\QQ_p`, where `p` is the residue + characteristic of `F`, with values in the base ring of ``self`` (or some other ring coercible to it) - - ``level``: the level of the new character (which should be at least + - ``level`` -- the level of the new character (which should be at least the level of ``chi``) - - ``vals``: a list of elements of the base ring of self (or some other + - ``vals`` -- a list of elements of the base ring of ``self`` (or some other ring coercible to it), specifying values on the quotients returned by - :meth:`quotient_gens`. + :meth:`quotient_gens` - A :class:`ValueError` will be raised if `x^t \ne \chi(\alpha^t)`, where `t` + A :exc:`ValueError` will be raised if `x^t \ne \chi(\alpha^t)`, where `t` is the smallest integer such that `\alpha^t` is congruent modulo `p^{\rm level}` to an element of `\QQ_p`. @@ -1393,6 +1392,7 @@ def extend_character(self, level, chi, vals, check=True): raise ValueError("Invalid values for extension") return chiE + class SmoothCharacterGroupUnramifiedQuadratic(SmoothCharacterGroupQuadratic): r""" The group of smooth characters of `\QQ_{p^2}^\times`, where `\QQ_{p^2}` is @@ -1432,7 +1432,7 @@ def change_ring(self, ring): Return the character group of the same field, but with values in a different coefficient ring. This need not have anything to do with the original base ring, and in particular there won't generally be a - coercion map from self to the new group -- use + coercion map from ``self`` to the new group -- use :meth:`~SmoothCharacterGroupGeneric.base_extend` if you want this. EXAMPLES:: @@ -1621,10 +1621,10 @@ def __init__(self, prime, flag, base_ring, names='s'): INPUT: - - ``prime`` -- a prime integer + - ``prime`` -- prime integer - ``flag`` -- either 0 or 1 - ``base_ring`` -- a ring - - ``names`` -- a variable name (default ``s``) + - ``names`` -- a variable name (default: ``'s'``) If ``flag`` is 0, return the group of characters of the multiplicative group of the field `\QQ_p(\sqrt{p})`. If ``flag`` is 1, use the @@ -1676,7 +1676,7 @@ def change_ring(self, ring): Return the character group of the same field, but with values in a different coefficient ring. This need not have anything to do with the original base ring, and in particular there won't generally be a - coercion map from self to the new group -- use + coercion map from ``self`` to the new group -- use :meth:`~SmoothCharacterGroupGeneric.base_extend` if you want this. EXAMPLES:: diff --git a/src/sage/modular/local_comp/type_space.py b/src/sage/modular/local_comp/type_space.py index 87c93d53477..ea43ec89ccf 100644 --- a/src/sage/modular/local_comp/type_space.py +++ b/src/sage/modular/local_comp/type_space.py @@ -62,6 +62,7 @@ def example_type_space(example_no=0): # a ramified (odd p-power level) case return TypeSpace(Newform_constructor('27a'), 3) + def find_in_space(f, A, base_extend=False): r""" Given a Newform object `f`, and a space `A` of modular symbols of the same @@ -147,6 +148,7 @@ def find_in_space(f, A, base_extend=False): return D + class TypeSpace(SageObject): r""" The modular symbol type space associated to a newform, at a prime dividing @@ -183,7 +185,7 @@ def __init__(self, f, p, base_extend=True): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -272,7 +274,7 @@ def free_module(self): def eigensymbol_subspace(self): r""" - Return the subspace of self corresponding to the plus eigensymbols of + Return the subspace of ``self`` corresponding to the plus eigensymbols of `f` and its Galois conjugates (as a subspace of the vector space returned by :meth:`~free_module`). @@ -331,7 +333,7 @@ def group(self): @cached_method def is_minimal(self): r""" - Return True if there exists a newform `g` of level strictly smaller + Return ``True`` if there exists a newform `g` of level strictly smaller than `N`, and a Dirichlet character `\chi` of `p`-power conductor, such that `f = g \otimes \chi` where `f` is the form of which this is the type space. To find such a form, use :meth:`~minimal_twist`. @@ -401,12 +403,11 @@ def minimal_twist(self): V = A.submodule(VV, check=False) D = V.decomposition()[0] - #if len(D.star_eigenvalues()) == 2: + # if len(D.star_eigenvalues()) == 2: # D = D.sign_submodule(1) D1 = D.modular_symbols_of_sign(1) M = ModularForms(D1.group(), D1.weight(), D1.base_ring()) - ff = Newform(M, D1, names='a') - return ff + return Newform(M, D1, names='a') ##################################### # The group action on the type space. @@ -634,7 +635,7 @@ def _discover_torus_action(self): mats = self._intertwining_basis(a) V = self.t_space.nonembedded_free_module() v = self.eigensymbol_subspace().gen(0) - w = V.submodule_with_basis([m * v for m in mats]).coordinates(v) #v * self.e_space.diamond_eigenvalue(crt(a, 1, f, self.tame_level()))) + w = V.submodule_with_basis([m * v for m in mats]).coordinates(v) # v * self.e_space.diamond_eigenvalue(crt(a, 1, f, self.tame_level()))) self._a = a self._amat = sum([mats[i] * w[i] for i in range(len(mats))]) @@ -735,7 +736,6 @@ def _unif_ramified(self): sage: T._unif_ramified() [-1 0] [ 0 -1] - """ p = self.prime() k = self.form().weight() diff --git a/src/sage/modular/meson.build b/src/sage/modular/meson.build new file mode 100644 index 00000000000..d334cf975c8 --- /dev/null +++ b/src/sage/modular/meson.build @@ -0,0 +1,47 @@ +py.install_sources( + 'all.py', + 'buzzard.py', + 'congroup.py', + 'congroup_element.py', + 'cusps.py', + 'cusps_nf.py', + 'dims.py', + 'dirichlet.py', + 'etaproducts.py', + 'hypergeometric_misc.pxd', + 'hypergeometric_motive.py', + 'multiple_zeta.py', + 'multiple_zeta_F_algebra.py', + subdir: 'sage/modular', +) + +extension_data = {'hypergeometric_misc' : files('hypergeometric_misc.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modular', + install: true, + include_directories: [inc_cpython], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +install_subdir('abvar', install_dir: sage_install_dir / 'modular') +subdir('arithgroup') +install_subdir('btquotients', install_dir: sage_install_dir / 'modular') +install_subdir('drinfeld_modform', install_dir: sage_install_dir / 'modular') +install_subdir('hecke', install_dir: sage_install_dir / 'modular') +install_subdir('local_comp', install_dir: sage_install_dir / 'modular') +subdir('modform') +install_subdir( + 'modform_hecketriangle', + install_dir: sage_install_dir / 'modular', +) +subdir('modsym') +install_subdir('overconvergent', install_dir: sage_install_dir / 'modular') +subdir('pollack_stevens') +install_subdir('quasimodform', install_dir: sage_install_dir / 'modular') +install_subdir('quatalg', install_dir: sage_install_dir / 'modular') +install_subdir('ssmod', install_dir: sage_install_dir / 'modular') diff --git a/src/sage/modular/modform/ambient.py b/src/sage/modular/modform/ambient.py index b218e5e649f..bf67263db8c 100644 --- a/src/sage/modular/modform/ambient.py +++ b/src/sage/modular/modform/ambient.py @@ -119,7 +119,7 @@ def __init__(self, group, weight, base_ring, character=None, eis_only=False): def _repr_(self): """ - Return string representation of self. + Return string representation of ``self``. EXAMPLES:: @@ -159,9 +159,7 @@ def change_ring(self, base_ring): INPUT: - - - ``R`` -- ring - + - ``R`` -- ring EXAMPLES:: @@ -208,8 +206,8 @@ def dimension(self): def hecke_module_of_level(self, N): r""" Return the Hecke module of level N corresponding to self, which is the - domain or codomain of a degeneracy map from self. Here N must be either - a divisor or a multiple of the level of self. + domain or codomain of a degeneracy map from ``self``. Here N must be either + a divisor or a multiple of the level of ``self``. EXAMPLES:: @@ -229,7 +227,7 @@ def hecke_module_of_level(self, N): def _degeneracy_raising_matrix(self, M, t): r""" - Calculate the matrix of the degeneracy map from self to M corresponding + Calculate the matrix of the degeneracy map from ``self`` to M corresponding to `f(q) \mapsto f(q^t)`. Here the level of M should be a multiple of the level of self, and t should divide the quotient. @@ -288,9 +286,9 @@ def ambient_space(self): def is_ambient(self): """ - Return True if this an ambient space of modular forms. + Return ``True`` if this an ambient space of modular forms. - This is an ambient space, so this function always returns True. + This is an ambient space, so this function always returns ``True``. EXAMPLES:: @@ -365,11 +363,9 @@ def prec(self, new_prec=None): INPUT: + - ``new_prec`` -- positive integer (default: ``None``) - - ``new_prec`` -- positive integer (default: None) - - - OUTPUT: if new_prec is None, returns the current precision. + OUTPUT: if ``new_prec`` is ``None``, returns the current precision EXAMPLES:: @@ -468,10 +464,8 @@ def new_submodule(self, p=None): INPUT: - - - ``p`` -- (default: None), if specified return only - the `p`-new submodule. - + - ``p`` -- (default: ``None``), if specified return only + the `p`-new submodule EXAMPLES:: @@ -518,7 +512,7 @@ def new_submodule(self, p=None): def _q_expansion(self, element, prec): r""" - Return the q-expansion of a particular element of this space of + Return the `q`-expansion of a particular element of this space of modular forms, where the element should be a vector, list, or tuple (not a ModularFormElement). Here element should have length = self.dimension(). If element = [ a_i ] and self.basis() = [ v_i @@ -526,11 +520,9 @@ def _q_expansion(self, element, prec): INPUT: + - ``element`` -- vector, list or tuple - - ``element`` -- vector, list or tuple - - - ``prec`` -- desired precision of q-expansion - + - ``prec`` -- desired precision of `q`-expansion EXAMPLES:: @@ -679,7 +671,7 @@ def _dim_new_eisenstein(self): @cached_method def eisenstein_params(self): """ - Return parameters that define all Eisenstein series in self. + Return parameters that define all Eisenstein series in ``self``. OUTPUT: an immutable Sequence @@ -752,12 +744,12 @@ def _compute_q_expansion_basis(self, prec): def _compute_hecke_matrix(self, n): """ - Compute the matrix of the Hecke operator T_n acting on self. + Compute the matrix of the Hecke operator `T_n` acting on ``self``. - NOTE: + .. NOTE:: - If self is a level 1 space, the much faster Victor Miller basis - is used for this computation. + If ``self`` is a level 1 space, the much faster Victor Miller basis + is used for this computation. EXAMPLES:: @@ -830,7 +822,7 @@ def _compute_hecke_matrix_prime_power(self, p, r): def hecke_polynomial(self, n, var='x'): r""" - Compute the characteristic polynomial of the Hecke operator T_n acting + Compute the characteristic polynomial of the Hecke operator `T_n` acting on this space. Except in level 1, this is computed via modular symbols, and in particular is faster to compute than the matrix itself. diff --git a/src/sage/modular/modform/ambient_R.py b/src/sage/modular/modform/ambient_R.py index 0d19eb36cd3..c07597e25dc 100644 --- a/src/sage/modular/modform/ambient_R.py +++ b/src/sage/modular/modform/ambient_R.py @@ -16,6 +16,7 @@ from sage.rings.integer_ring import ZZ from sage.misc.cachefunc import cached_method + class ModularFormsAmbient_R(ambient.ModularFormsAmbient): def __init__(self, M, base_ring): """ @@ -82,7 +83,7 @@ def _repr_(self): def _compute_q_expansion_basis(self, prec=None): """ - Compute q-expansions for a basis of self to precision prec. + Compute `q`-expansions for a basis of ``self`` to precision ``prec``. EXAMPLES:: diff --git a/src/sage/modular/modform/ambient_eps.py b/src/sage/modular/modform/ambient_eps.py index 81527a72aa8..ddd4ed467bc 100644 --- a/src/sage/modular/modform/ambient_eps.py +++ b/src/sage/modular/modform/ambient_eps.py @@ -94,6 +94,7 @@ from . import cuspidal_submodule from . import eisenstein_submodule + class ModularFormsAmbient_eps(ModularFormsAmbient): """ A space of modular forms with character. @@ -102,7 +103,7 @@ def __init__(self, character, weight=2, base_ring=None, eis_only=False): """ Create an ambient modular forms space with character. - .. note:: + .. NOTE:: The base ring must be of characteristic 0. The ambient_R Python module is used for computing in characteristic p, @@ -110,7 +111,7 @@ def __init__(self, character, weight=2, base_ring=None, eis_only=False): INPUT: - - ``weight`` -- int + - ``weight`` -- integer - ``character`` -- dirichlet.DirichletCharacter @@ -260,10 +261,10 @@ def eisenstein_submodule(self): def hecke_module_of_level(self, N): r""" - Return the Hecke module of level N corresponding to self, which is the - domain or codomain of a degeneracy map from self. Here N must be either - a divisor or a multiple of the level of self, and a multiple of the - conductor of the character of self. + Return the Hecke module of level N corresponding to ``self``, which is the + domain or codomain of a degeneracy map from ``self``. Here N must be either + a divisor or a multiple of the level of ``self``, and a multiple of the + conductor of the character of ``self``. EXAMPLES:: diff --git a/src/sage/modular/modform/ambient_g1.py b/src/sage/modular/modform/ambient_g1.py index 2771a9a1623..31db01bd081 100644 --- a/src/sage/modular/modform/ambient_g1.py +++ b/src/sage/modular/modform/ambient_g1.py @@ -135,7 +135,7 @@ def _compute_diamond_matrix(self, d): def _compute_hecke_matrix(self, n): r""" - Compute the matrix of the Hecke operator T_n acting on this space. + Compute the matrix of the Hecke operator `T_n` acting on this space. EXAMPLES:: diff --git a/src/sage/modular/modform/constructor.py b/src/sage/modular/modform/constructor.py index 746b10472bc..ffe19d3d708 100644 --- a/src/sage/modular/modform/constructor.py +++ b/src/sage/modular/modform/constructor.py @@ -19,15 +19,15 @@ ] """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2004-2006 William Stein # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import weakref import re @@ -56,28 +56,23 @@ def canonical_parameters(group, level, weight, base_ring): INPUT: + - ``group`` -- integer, group, or Dirichlet character - - ``group`` -- int, long, Sage integer, group, - Dirichlet character, or + - ``level`` -- integer or group - - ``level`` -- int, long, Sage integer, or group - - - ``weight`` -- coercible to Sage integer - - - ``base_ring`` -- commutative Sage ring + - ``weight`` -- coercible to integer + - ``base_ring`` -- commutative ring OUTPUT: + - ``level`` -- integer - - ``level`` -- Sage integer - - - ``group`` -- congruence subgroup + - ``group`` -- congruence subgroup - - ``weight`` -- Sage integer - - - ``ring`` -- commutative Sage ring + - ``weight`` -- integer + - ``ring`` -- commutative ring EXAMPLES:: @@ -99,13 +94,13 @@ def canonical_parameters(group, level, weight, base_ring): raise NotImplementedError("weight must be at least 1") if isinstance(group, dirichlet.DirichletCharacter): - if ( group.level() != Integer(level) ): + if group.level() != Integer(level): raise ValueError("group.level() and level do not match.") group = group.minimize_base_ring() level = Integer(level) elif isinstance(group, arithgroup.CongruenceSubgroupBase): - if ( Integer(level) != group.level() ): + if Integer(level) != group.level(): raise ValueError("group.level() and level do not match.") # normalize the case of SL2Z if isinstance(group, arithgroup.SL2Z_class) or \ @@ -137,6 +132,7 @@ def canonical_parameters(group, level, weight, base_ring): _cache = {} + def ModularForms_clear_cache(): """ Clear the cache of modular forms. @@ -168,13 +164,13 @@ def ModularForms(group=1, INPUT: - - ``group`` -- A congruence subgroup or a Dirichlet character eps. + - ``group`` -- a congruence subgroup or a Dirichlet character eps - - ``weight`` -- int, the weight, which must be an integer >= 1. + - ``weight`` -- integer; the weight (`\geq 1`) - ``base_ring`` -- the base ring (ignored if group is a Dirichlet character) - - ``eis_only`` -- if True, compute only the Eisenstein part of the space. + - ``eis_only`` -- if ``True``, compute only the Eisenstein part of the space. Only permitted (and only useful) in weight 1, where computing dimensions of cusp form spaces is expensive. @@ -307,7 +303,6 @@ def ModularForms(group=1, Congruence Subgroup Gamma1(59) of weight 1 over Rational Field sage: (E.0 + E.2).q_expansion(40) 1 + q^2 + 196*q^29 - 197*q^30 - q^31 + q^33 + q^34 + q^37 + q^38 - q^39 + O(q^40) - """ if isinstance(group, dirichlet.DirichletCharacter): if base_ring is None: @@ -423,25 +418,23 @@ def EisensteinForms(group=1, def Newforms(group, weight=2, base_ring=None, names=None): r""" - Returns a list of the newforms of the given weight and level (or weight, + Return a list of the newforms of the given weight and level (or weight, level and character). These are calculated as `\operatorname{Gal}(\overline{F} / F)`-orbits, where `F` is the given base field. INPUT: + - ``group`` -- the congruence subgroup of the newform, or a Nebentypus + character - - ``group`` -- the congruence subgroup of the newform, or a Nebentypus - character + - ``weight`` -- the weight of the newform (default: 2) - - ``weight`` -- the weight of the newform (default 2) - - - ``base_ring`` -- the base ring (defaults to `\QQ` for spaces without - character, or the base ring of the character otherwise) - - - ``names`` -- if the newform has coefficients in a - number field, a generator name must be specified + - ``base_ring`` -- the base ring (defaults to `\QQ` for spaces without + character, or the base ring of the character otherwise) + - ``names`` -- if the newform has coefficients in a number field, a + generator name must be specified EXAMPLES:: @@ -478,7 +471,6 @@ def Newforms(group, weight=2, base_ring=None, names=None): sage: N = Newforms(719, names='a'); len(N) # long time (3 s) 3 - """ return CuspForms(group, weight, base_ring).newforms(names) @@ -487,19 +479,17 @@ def Newform(identifier, group=None, weight=2, base_ring=QQ, names=None): """ INPUT: + - ``identifier`` -- a canonical label, or the index of + the specific newform desired - - ``identifier`` -- a canonical label, or the index of - the specific newform desired - - - ``group`` -- the congruence subgroup of the newform - - - ``weight`` -- the weight of the newform (default 2) + - ``group`` -- the congruence subgroup of the newform - - ``base_ring`` -- the base ring + - ``weight`` -- the weight of the newform (default: 2) - - ``names`` -- if the newform has coefficients in a - number field, a generator name must be specified + - ``base_ring`` -- the base ring + - ``names`` -- if the newform has coefficients in a + number field, a generator name must be specified EXAMPLES:: diff --git a/src/sage/modular/modform/cuspidal_submodule.py b/src/sage/modular/modform/cuspidal_submodule.py index 0bf53873ed3..5de0805b386 100644 --- a/src/sage/modular/modform/cuspidal_submodule.py +++ b/src/sage/modular/modform/cuspidal_submodule.py @@ -43,7 +43,7 @@ from sage.matrix.special import identity_matrix from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import -from sage.misc.verbose import verbose +from sage.misc.verbose import verbose from sage.rings.integer import Integer from sage.rings.rational_field import QQ @@ -52,6 +52,7 @@ from .submodule import ModularFormsSubmodule from . import weight1 + class CuspidalSubmodule(ModularFormsSubmodule): """ Base class for cuspidal submodules of ambient spaces of modular forms. @@ -100,7 +101,7 @@ def __init__(self, ambient_space): def _compute_q_expansion_basis(self, prec): r""" - Compute a basis of q-expansions of self to the given precision. Not + Compute a basis of `q`-expansions of ``self`` to the given precision. Not implemented in this abstract base class. EXAMPLES:: @@ -115,7 +116,7 @@ def _compute_q_expansion_basis(self, prec): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -126,7 +127,7 @@ def _repr_(self): def is_cuspidal(self): """ - Return True since spaces of cusp forms are cuspidal. + Return ``True`` since spaces of cusp forms are cuspidal. EXAMPLES:: @@ -211,6 +212,7 @@ def change_ring(self, R): """ return self.ambient_module().change_ring(R).cuspidal_submodule() + class CuspidalSubmodule_R(CuspidalSubmodule): """ Cuspidal submodule over a non-minimal base ring. @@ -231,11 +233,11 @@ def _compute_q_expansion_basis(self, prec): class CuspidalSubmodule_modsym_qexp(CuspidalSubmodule): """ - Cuspidal submodule with q-expansions calculated via modular symbols. + Cuspidal submodule with `q`-expansions calculated via modular symbols. """ def _compute_q_expansion_basis(self, prec=None): """ - Compute q-expansions of a basis for self (via modular symbols). + Compute `q`-expansions of a basis for ``self`` (via modular symbols). EXAMPLES:: @@ -272,7 +274,7 @@ def _compute_hecke_matrix_prime(self, p): def hecke_polynomial(self, n, var='x'): r""" - Return the characteristic polynomial of the Hecke operator T_n on this + Return the characteristic polynomial of the Hecke operator `T_n` on this space. This is computed via modular symbols, and in particular is faster to compute than the matrix itself. @@ -320,7 +322,7 @@ class CuspidalSubmodule_level1_Q(CuspidalSubmodule): """ def _compute_q_expansion_basis(self, prec=None): """ - Compute q-expansions of a basis for self. + Compute `q`-expansions of a basis for ``self``. EXAMPLES:: @@ -358,7 +360,7 @@ class CuspidalSubmodule_wt1_eps(CuspidalSubmodule): def _compute_q_expansion_basis(self, prec=None): r""" - Compute q-expansion basis using Schaeffer's algorithm. + Compute `q`-expansion basis using Schaeffer's algorithm. EXAMPLES:: @@ -383,7 +385,7 @@ class CuspidalSubmodule_wt1_gH(CuspidalSubmodule): def _compute_q_expansion_basis(self, prec=None): r""" - Compute q-expansion basis using Schaeffer's algorithm. + Compute `q`-expansion basis using Schaeffer's algorithm. EXAMPLES:: @@ -540,7 +542,6 @@ def _compute_hecke_matrix(self, n): [ 0 1 0 0 1 0 0] sage: C.hecke_matrix(23) == 0 True - """ chars = self.group().characters_mod_H(sign=-1, galois_orbits=True) A = Matrix(QQ, 0, 0) @@ -590,9 +591,9 @@ class CuspidalSubmodule_gH_Q(CuspidalSubmodule_modsym_qexp): def _compute_hecke_matrix(self, n): r""" - Compute the matrix of the Hecke operator T_n acting on this space. + Compute the matrix of the Hecke operator `T_n` acting on this space. This is done directly using modular symbols, rather than using - q-expansions as for spaces with fixed character. + `q`-expansions as for spaces with fixed character. EXAMPLES:: @@ -627,11 +628,13 @@ def _compute_diamond_matrix(self, d): symbs = self.modular_symbols(sign=1) return _convert_matrix_from_modsyms(symbs, symbs.diamond_bracket_matrix(d))[0] + class CuspidalSubmodule_g1_Q(CuspidalSubmodule_gH_Q): r""" Space of cusp forms for `\Gamma_1(N)` over `\QQ`. """ + class CuspidalSubmodule_eps(CuspidalSubmodule_modsym_qexp): """ Space of cusp forms with given Dirichlet character. @@ -660,6 +663,7 @@ class CuspidalSubmodule_eps(CuspidalSubmodule_modsym_qexp): """ pass + def _convert_matrix_from_modsyms(symbs, T): r""" Given a space of modular symbols and a matrix T acting on it, calculate the @@ -671,8 +675,9 @@ def _convert_matrix_from_modsyms(symbs, T): the Atkin-Lehner operators, for instance, when there are oldforms present. OUTPUT: - A pair `(T_e, ps)` with `T_e` the converted matrix and `ps` a list - of pivot elements of the echelon basis. + + A pair `(T_e, ps)` with `T_e` the converted matrix and `ps` a list + of pivot elements of the echelon basis. EXAMPLES:: @@ -694,17 +699,19 @@ def _convert_matrix_from_modsyms(symbs, T): # we repeatedly use these matrices below, so we store them # once as lists to save time. - hecke_matrix_ls = [ symbs.hecke_matrix(m).list() for m in range(1,r+1) ] - hecke_image_ls = [ (T*symbs.hecke_matrix(m)).list() for m in range(1,r+1) ] + hecke_matrix_ls = [symbs.hecke_matrix(m).list() + for m in range(1, r + 1)] + hecke_image_ls = [(T * symbs.hecke_matrix(m)).list() + for m in range(1, r + 1)] # compute the q-expansions of some cusp forms and their # images under T_n for i in range(d**2): - v = X([ hecke_matrix_ls[m][i] for m in range(r) ]) + v = X([hecke_matrix_ls[m][i] for m in range(r)]) Ynew = Y.span(Y.basis() + [v]) if Ynew.rank() > Y.rank(): basis.append(v) - basis_images.append(X([ hecke_image_ls[m][i] for m in range(r) ])) + basis_images.append(X([hecke_image_ls[m][i] for m in range(r)])) Y = Ynew if len(basis) == d: break diff --git a/src/sage/modular/modform/eis_series.py b/src/sage/modular/modform/eis_series.py index f01c28fd0f2..73ea6dcaf1c 100644 --- a/src/sage/modular/modform/eis_series.py +++ b/src/sage/modular/modform/eis_series.py @@ -30,7 +30,7 @@ def eisenstein_series_qexp(k, prec=10, K=QQ, var='q', normalization='linear'): r""" Return the `q`-expansion of the normalized weight `k` Eisenstein series on - `\SL_2(\ZZ)` to precision prec in the ring `K`. Three normalizations + `\SL_2(\ZZ)` to precision ``prec`` in the ring `K`. Three normalizations are available, depending on the parameter ``normalization``; the default normalization is the one for which the linear coefficient is 1. @@ -42,7 +42,7 @@ def eisenstein_series_qexp(k, prec=10, K=QQ, var='q', normalization='linear'): - ``K`` -- (default: `\QQ`) a ring - - ``var`` -- (default: ``'q'``) variable name to use for q-expansion + - ``var`` -- (default: ``'q'``) variable name to use for `q`-expansion - ``normalization`` -- (default: ``'linear'``) normalization to use. If this is ``'linear'``, then the series will be normalized so that the linear @@ -78,7 +78,7 @@ def eisenstein_series_qexp(k, prec=10, K=QQ, var='q', normalization='linear'): 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + O(q^5) sage: eisenstein_series_qexp(12, 5, normalization='linear') 691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + O(q^5) - sage: eisenstein_series_qexp(12, 50, K=GF(13), normalization="constant") + sage: eisenstein_series_qexp(12, 50, K=GF(13), normalization='constant') 1 + O(q^50) TESTS: @@ -95,20 +95,20 @@ def eisenstein_series_qexp(k, prec=10, K=QQ, var='q', normalization='linear'): We check that the function behaves properly over finite-characteristic base rings:: - sage: eisenstein_series_qexp(12, 5, K = Zmod(691), normalization="integral") + sage: eisenstein_series_qexp(12, 5, K = Zmod(691), normalization='integral') 566*q + 236*q^2 + 286*q^3 + 194*q^4 + O(q^5) - sage: eisenstein_series_qexp(12, 5, K = Zmod(691), normalization="constant") + sage: eisenstein_series_qexp(12, 5, K = Zmod(691), normalization='constant') Traceback (most recent call last): ... ValueError: The numerator of -B_k/(2*k) (=691) must be invertible in the ring Ring of integers modulo 691 - sage: eisenstein_series_qexp(12, 5, K = Zmod(691), normalization="linear") + sage: eisenstein_series_qexp(12, 5, K = Zmod(691), normalization='linear') q + 667*q^2 + 252*q^3 + 601*q^4 + O(q^5) - sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="integral") + sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization='integral') 1 + O(q^5) - sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="constant") + sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization='constant') 1 + O(q^5) - sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization="linear") + sage: eisenstein_series_qexp(12, 5, K = Zmod(2), normalization='linear') Traceback (most recent call last): ... ValueError: The denominator of -B_k/(2*k) (=65520) must be invertible in the ring Ring of integers modulo 2 @@ -159,7 +159,7 @@ def eisenstein_series_qexp(k, prec=10, K=QQ, var='q', normalization='linear'): E._unsafe_mutate(0, a0) return R(E, prec) # The following is an older slower alternative to the above three lines: - #return a0fac*R(eisenstein_series_poly(k, prec).list(), prec=prec, check=False) + # return a0fac*R(eisenstein_series_poly(k, prec).list(), prec=prec, check=False) else: # This used to work with check=False, but that can only be regarded as # an improbable lucky miracle. Enabling checking is a noticeable speed @@ -170,6 +170,7 @@ def eisenstein_series_qexp(k, prec=10, K=QQ, var='q', normalization='linear'): else: return R(eisenstein_series_poly(k, prec).list(), prec=prec, check=True) + def __common_minimal_basering(chi, psi): """ Find the smallest basering over which chi and psi are valued, and @@ -279,7 +280,7 @@ def __find_eisen_chars(character, k): if L not in C: continue GL = C[L] - for R in divisors(N/L): + for R in divisors(N // L): if R not in C: continue GR = C[R] @@ -288,8 +289,8 @@ def __find_eisen_chars(character, k): if chi*psi == eps: chi0, psi0 = __common_minimal_basering(chi, psi) for t in divisors(N//(R*L)): - if k != 1 or ((psi0, chi0, t) not in params): - params.append( (chi0,psi0,t) ) + if k != 1 or (psi0, chi0, t) not in params: + params.append((chi0, psi0, t)) return params @@ -365,8 +366,6 @@ def __find_eisen_chars_gamma1(N, k): pairs.append((psi, chi)) else: pairs.append((chi, psi)) - #end fors - #end if triples = [] for chi, psi in pairs: @@ -376,20 +375,20 @@ def __find_eisen_chars_gamma1(N, k): if k == 2 and chi.is_trivial() and psi.is_trivial(): D.remove(1) chi, psi = __common_minimal_basering(chi, psi) - for t in D: - triples.append((chi, psi, t)) + triples.extend((chi, psi, t) for t in D) + return triples def eisenstein_series_lseries(weight, prec=53, - max_imaginary_part=0, - max_asymp_coeffs=40): + max_imaginary_part=0, + max_asymp_coeffs=40): r""" - Return the L-series of the weight `2k` Eisenstein series + Return the `L`-series of the weight `2k` Eisenstein series on `\SL_2(\ZZ)`. This actually returns an interface to Tim Dokchitser's program - for computing with the L-series of the Eisenstein series + for computing with the `L`-series of the Eisenstein series INPUT: @@ -401,18 +400,16 @@ def eisenstein_series_lseries(weight, prec=53, - ``max_asymp_coeffs`` -- integer - OUTPUT: - - The L-series of the Eisenstein series. + OUTPUT: the `L`-series of the Eisenstein series EXAMPLES: - We compute with the L-series of `E_{16}` and then `E_{20}`:: + We compute with the `L`-series of `E_{16}` and then `E_{20}`:: sage: L = eisenstein_series_lseries(16) sage: L(1) -0.291657724743874 - sage: L = eisenstein_series_lseries(20) + sage: L = eisenstein_series_lseries(20) sage: L(2) -5.02355351645998 diff --git a/src/sage/modular/modform/eis_series_cython.pyx b/src/sage/modular/modform/eis_series_cython.pyx index 70271d3f80b..60df3add6f0 100644 --- a/src/sage/modular/modform/eis_series_cython.pyx +++ b/src/sage/modular/modform/eis_series_cython.pyx @@ -23,12 +23,10 @@ cpdef Ek_ZZ(int k, int prec=10): INPUT: - - `k` -- int - - ``prec`` -- int + - ``k`` -- integer + - ``prec`` -- integer - OUTPUT: - - - list of Sage Integers. + OUTPUT: list of integers EXAMPLES:: @@ -109,12 +107,12 @@ cpdef Ek_ZZ(int k, int prec=10): # compute the valuation of n at p additional_p_powers = 0 - temp_index = ind / p + temp_index = ind // p remainder = 0 while not remainder: additional_p_powers += 1 prev_index = temp_index - temp_index = temp_index / p + temp_index = temp_index // p remainder = prev_index - p*temp_index # if we need a new sum, it has to be the next uncomputed one. @@ -142,7 +140,7 @@ cpdef Ek_ZZ(int k, int prec=10): cpdef eisenstein_series_poly(int k, int prec=10): r""" - Return the q-expansion up to precision ``prec`` of the weight `k` + Return the `q`-expansion up to precision ``prec`` of the weight `k` Eisenstein series, as a FLINT :class:`~sage.libs.flint.fmpz_poly.Fmpz_poly` object, normalised so the coefficients are integers with no common factor. @@ -186,7 +184,7 @@ cpdef eisenstein_series_poly(int k, int prec=10): a0 = -bernoulli(k) / (2*k) cdef long p, ppow - for p in primes(1, prec) : + for p in primes(1, prec): ppow = p mpz_set_si(mult, p) diff --git a/src/sage/modular/modform/eisenstein_submodule.py b/src/sage/modular/modform/eisenstein_submodule.py index 034d94479d5..fbbe2e06da3 100644 --- a/src/sage/modular/modform/eisenstein_submodule.py +++ b/src/sage/modular/modform/eisenstein_submodule.py @@ -60,7 +60,7 @@ def _repr_(self): def eisenstein_submodule(self): """ - Return the Eisenstein submodule of self. + Return the Eisenstein submodule of ``self``. (Yes, this is just self.) EXAMPLES:: @@ -119,13 +119,14 @@ def modular_symbols(self, sign=0): A = self.ambient_module() return A.modular_symbols(sign).eisenstein_submodule() + class EisensteinSubmodule_params(EisensteinSubmodule): @cached_method def parameters(self): r""" Return a list of parameters for each Eisenstein series - spanning self. That is, for each such series, return a triple + spanning ``self``. That is, for each such series, return a triple of the form (`\psi`, `\chi`, level), where `\psi` and `\chi` are the characters defining the Eisenstein series, and level is the smallest level at which this series occurs. @@ -169,7 +170,7 @@ def parameters(self): def new_submodule(self, p=None): r""" - Return the new submodule of self. + Return the new submodule of ``self``. EXAMPLES:: @@ -190,7 +191,7 @@ def new_submodule(self, p=None): def _parameters_character(self): """ - Return the character defining self. + Return the character defining ``self``. EXAMPLES:: @@ -201,7 +202,7 @@ def _parameters_character(self): def change_ring(self, base_ring): """ - Return self as a module over base_ring. + Return ``self`` as a module over ``base_ring``. EXAMPLES:: @@ -332,7 +333,7 @@ def new_eisenstein_series(self): def _compute_q_expansion_basis(self, prec=None, new=False): """ - Compute a q-expansion basis for self to precision prec. + Compute a `q`-expansion basis for ``self`` to precision ``prec``. EXAMPLES:: @@ -382,9 +383,9 @@ def _compute_q_expansion_basis(self, prec=None, new=False): def _q_expansion(self, element, prec): """ - Compute a q-expansion for a given element of self, expressed + Compute a `q`-expansion for a given element of self, expressed as a vector of coefficients for the basis vectors of self, - viewing self as a subspace of the corresponding space of + viewing ``self`` as a subspace of the corresponding space of modular forms. EXAMPLES:: @@ -429,7 +430,7 @@ class EisensteinSubmodule_gH_Q(EisensteinSubmodule_params): """ def _parameters_character(self): """ - Return the character defining self. Since self is + Return the character defining ``self``. Since ``self`` is a space of Eisenstein forms on GammaH(N) rather than a space with fixed character, we return the group GammaH(N) itself. @@ -475,24 +476,22 @@ def _compute_hecke_matrix(self, n, bound=None): INPUT: - - n: a positive integer + - ``n`` -- positive integer - - bound: an integer such that any element of this space with + - ``bound`` -- integer such that any element of this space with coefficients a_1, ..., a_b all zero must be the zero element. If this turns out not to be true, the code will increase the bound and try again. Setting bound = None is equivalent to setting bound = self.dimension(). - OUTPUT: - - - a matrix (over `\QQ`) + OUTPUT: matrix (over `\QQ`) ALGORITHM: This uses the usual pairing between modular symbols and modular forms, but in a slightly non-standard way. As for cusp forms, we can find a basis for this space made up of - forms with q-expansions `c_m(f) = a_{i,j}(T_m)`, where + forms with `q`-expansions `c_m(f) = a_{i,j}(T_m)`, where `T_m` denotes the matrix of the Hecke operator on the corresponding modular symbols space. Then `c_m(T_n f) = a_{i,j}(T_n* T_m)`. But we can't find the constant terms @@ -537,9 +536,9 @@ class EisensteinSubmodule_g1_Q(EisensteinSubmodule_gH_Q): """ def _parameters_character(self): r""" - Return the character defining self. + Return the character defining ``self``. - Since self is a space of Eisenstein + Since ``self`` is a space of Eisenstein forms on `\Gamma_1(N)`, all characters modulo the level are possible, so we return the level. @@ -586,29 +585,24 @@ class EisensteinSubmodule_eps(EisensteinSubmodule_params): q^4 - 2*zeta3*q^7 + O(q^10), q^5 + (zeta3 + 1)*q^8 + O(q^10) ] - """ # TODO - #def _compute_q_expansion_basis(self, prec): - #B = EisensteinSubmodule_params._compute_q_expansion_basis(self, prec) - #raise NotImplementedError, "must restrict scalars down correctly." + # def _compute_q_expansion_basis(self, prec): + # B = EisensteinSubmodule_params._compute_q_expansion_basis(self, prec) + # raise NotImplementedError("must restrict scalars down correctly.") -def cyclotomic_restriction(L,K): +def cyclotomic_restriction(L, K): r""" - Given two cyclotomic fields L and K, compute the compositum - M of K and L, and return a function and the index [M:K]. The - function is a map that acts as follows (here `M = Q(\zeta_m)`): - - INPUT: - - element alpha in L + Given two cyclotomic fields `L` and `K`, compute the compositum + `M` of `K` and `L`, and return a function `f` and the index `[M:K]`. - OUTPUT: + The function `f` is a map that acts as follows (here `M =\QQ(\zeta_m)`): - a polynomial `f(x)` in `K[x]` such that `f(\zeta_m) = \alpha`, - where we view alpha as living in `M`. (Note that `\zeta_m` - generates `M`, not `L`.) + INPUT: element alpha in `L` + OUTPUT: a polynomial `f(x)` in `K[x]` such that `f(\zeta_m) = \alpha`, + where we view alpha as living in `M`. (Note that `\zeta_m` generates + `M`, not `L`.) EXAMPLES:: @@ -637,16 +631,6 @@ def g(x): r""" Function returned by cyclotomic restriction. - INPUT: - - element alpha in L - - OUTPUT: - - a polynomial `f(x)` in `K[x]` such that `f(\zeta_m) = \alpha`, - where we view alpha as living in `M`. (Note that `\zeta_m` - generates `M`, not `L`.) - EXAMPLES:: sage: L = CyclotomicField(12) @@ -662,19 +646,13 @@ def g(x): euler_phi(L.zeta_order())//euler_phi(K.zeta_order()) -def cyclotomic_restriction_tower(L,K): - """ - Suppose L/K is an extension of cyclotomic fields and L=Q(zeta_m). +def cyclotomic_restriction_tower(L, K): + r""" + Suppose `L/K` is an extension of cyclotomic fields and `L=Q(\zeta_m)`. This function computes a map with the following property: - - INPUT: - - an element alpha in L - - OUTPUT: - - a polynomial `f(x)` in `K[x]` such that `f(zeta_m) = alpha`. + INPUT: element alpha in `L` + OUTPUT: a polynomial `f(x)` in `K[x]` such that `f(\zeta_m) = alpha` EXAMPLES:: @@ -690,8 +668,8 @@ def cyclotomic_restriction_tower(L,K): f = L.defining_polynomial() R = K['x'] g = R(f) - h_ls = [ t[0] for t in g.factor() if t[0](L.gen(0)) == 0 ] - if len(h_ls) == 0: + h_ls = [t[0] for t in g.factor() if t[0](L.gen(0)) == 0] + if not h_ls: raise ValueError(r"K (= Q(\zeta_%s)) is not contained in L (= Q(\zeta_%s))" % (K._n(), L._n())) h = h_ls[0] @@ -699,14 +677,6 @@ def z(a): """ Function returned by cyclotomic_restriction_tower. - INPUT: - - an element alpha in L - - OUTPUT: - - a polynomial `f(x)` in `K[x]` such that `f(zeta_m) = alpha`. - EXAMPLES:: sage: L = CyclotomicField(121); K = CyclotomicField(11) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 72880952610..6ce83f0372e 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -90,14 +90,14 @@ def is_ModularFormElement(x): def delta_lseries(prec=53, max_imaginary_part=0, max_asymp_coeffs=40, algorithm=None): r""" - Return the L-series of the modular form `\Delta`. + Return the `L`-series of the modular form `\Delta`. - If algorithm is "gp", this returns an interface to Tim - Dokchitser's program for computing with the L-series of the + If algorithm is ``'gp'``, this returns an interface to Tim + Dokchitser's program for computing with the `L`-series of the modular form `\Delta`. - If algorithm is "pari", this returns instead an interface to Pari's - own general implementation of L-functions. + If algorithm is ``'pari'``, this returns instead an interface to Pari's + own general implementation of `L`-functions. INPUT: @@ -107,11 +107,11 @@ def delta_lseries(prec=53, max_imaginary_part=0, - ``max_asymp_coeffs`` -- integer - - ``algorithm`` -- optional string: 'gp' (default), 'pari' + - ``algorithm`` -- string; ``'gp'`` (default), ``'pari'`` OUTPUT: - The L-series of `\Delta`. + The `L`-series of `\Delta`. EXAMPLES:: @@ -175,7 +175,7 @@ def weight(self): def level(self): """ - Return the level of self. + Return the level of ``self``. EXAMPLES:: @@ -221,7 +221,7 @@ def _repr_(self): def __call__(self, x, prec=None): """ - Evaluate the q-expansion of this modular form at x. + Evaluate the `q`-expansion of this modular form at x. EXAMPLES:: @@ -239,7 +239,7 @@ def __call__(self, x, prec=None): @cached_method def valuation(self): """ - Return the valuation of self (i.e. as an element of the power + Return the valuation of ``self`` (i.e. as an element of the power series ring in q). EXAMPLES:: @@ -273,7 +273,7 @@ def qexp(self, prec=None): def __eq__(self, other): """ - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -294,7 +294,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Return True if ``self != other``. + Return ``True`` if ``self != other``. EXAMPLES:: @@ -382,7 +382,7 @@ def coefficients(self, X): def __getitem__(self, n): """ - Returns the `q^n` coefficient of the `q`-expansion of self or + Return the `q^n` coefficient of the `q`-expansion of ``self`` or returns a list containing the `q^i` coefficients of self where `i` is in slice `n`. @@ -410,11 +410,11 @@ def __getitem__(self, n): def coefficient(self, n): r""" - Return the `n`-th coefficient of the `q`-expansion of self. + Return the `n`-th coefficient of the `q`-expansion of ``self``. INPUT: - - ``n`` -- non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -437,7 +437,7 @@ def coefficient(self, n): def padded_list(self, n): """ Return a list of length n whose entries are the first n - coefficients of the q-expansion of self. + coefficients of the `q`-expansion of ``self``. EXAMPLES:: @@ -450,7 +450,7 @@ def padded_list(self, n): def _latex_(self): """ - Return the LaTeX expression of self. + Return the LaTeX expression of ``self``. EXAMPLES:: @@ -464,7 +464,7 @@ def _latex_(self): def character(self, compute=True): """ - Return the character of self. If ``compute=False``, then this will + Return the character of ``self``. If ``compute=False``, then this will return None unless the form was explicitly created as an element of a space of forms with character, skipping the (potentially expensive) computation of the matrices of the diamond operators. @@ -562,7 +562,7 @@ def q_expansion(self, prec=None): sage: f.q_expansion(-1) Traceback (most recent call last): ... - ValueError: prec (= -1) must be non-negative + ValueError: prec (= -1) must be nonnegative """ if prec is None: prec = self.parent().prec() @@ -652,7 +652,7 @@ def atkin_lehner_eigenvalue(self, d=None, embedding=None): INPUT: - - ``d`` -- a positive integer exactly dividing the level `N` + - ``d`` -- positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d` (default: `d = N`) @@ -666,7 +666,7 @@ def atkin_lehner_eigenvalue(self, d=None, embedding=None): specified, and in (a suitable extension of) the base field of ``self`` otherwise. - If ``self`` is not an eigenform for `W_d`, a :class:`ValueError` is + If ``self`` is not an eigenform for `W_d`, a :exc:`ValueError` is raised. .. SEEALSO:: @@ -751,7 +751,7 @@ def period(self, M, prec=53): linear combinations of the real and the imaginary period of `E`:: sage: s = E.modular_symbol(sign=+1) - sage: t = E.modular_symbol(sign=-1, implementation="sage") + sage: t = E.modular_symbol(sign=-1, implementation='sage') sage: s(3/11), t(3/11) (1/10, 1/2) sage: s(3/11)*omega1 + t(3/11)*2*omega2.imag()*I @@ -804,7 +804,6 @@ def period(self, M, prec=53): sage: M = Gamma0(19)([10, 1, 19, 2]) sage: E.newform().period(M) # abs tol 1e-14 -1.35975973348831 + 1.09365931898146e-16*I - """ R = RealField(prec) @@ -853,29 +852,29 @@ def period(self, M, prec=53): def lseries(self, embedding=0, prec=53, max_imaginary_part=0, max_asymp_coeffs=40): r""" - Return the L-series of the weight k cusp form + Return the `L`-series of the weight k cusp form `f` on `\Gamma_0(N)`. This actually returns an interface to Tim Dokchitser's program for - computing with the L-series of the cusp form. + computing with the `L`-series of the cusp form. INPUT: - ``embedding`` -- either an embedding of the coefficient field of self into `\CC`, or an integer `i` between 0 and D-1 where D is the degree of the coefficient field (meaning to pick the `i`-th embedding). - (Default: 0) + (default: 0) - - ``prec`` -- integer (bits precision). Default: 53. + - ``prec`` -- integer (default: 53); bits precision - - ``max_imaginary_part`` -- real number. Default: 0. + - ``max_imaginary_part`` -- real number (default: 0) - - ``max_asymp_coeffs`` -- integer. Default: 40. + - ``max_asymp_coeffs`` -- integer (default: 40) For more information on the significance of the last three arguments, see :mod:`~sage.lfunctions.dokchitser`. - .. note:: + .. NOTE:: If an explicit embedding is given, but this embedding is specified to smaller precision than ``prec``, it will be automatically @@ -883,7 +882,7 @@ def lseries(self, embedding=0, prec=53, max_imaginary_part=0, OUTPUT: - The L-series of the cusp form, as a + The `L`-series of the cusp form, as a :class:`sage.lfunctions.dokchitser.Dokchitser` object. EXAMPLES:: @@ -925,7 +924,7 @@ def lseries(self, embedding=0, prec=53, max_imaginary_part=0, sage: f.lseries(embedding=1)(1) 0.298115272465799 + 0.0402203326076732*I - We compute with the L-series of the Eisenstein series `E_4`:: + We compute with the `L`-series of the Eisenstein series `E_4`:: sage: f = ModularForms(1,4).0 sage: L = f.lseries() @@ -1037,18 +1036,18 @@ def lseries(self, embedding=0, prec=53, max_imaginary_part=0, def symsquare_lseries(self, chi=None, embedding=0, prec=53): r""" - Compute the symmetric square L-series of this modular form, twisted by + Compute the symmetric square `L`-series of this modular form, twisted by the character `\chi`. INPUT: - - ``chi`` -- Dirichlet character to twist by, or None (default None, - interpreted as the trivial character). + - ``chi`` -- Dirichlet character to twist by, or ``None`` (default: + ``None``), interpreted as the trivial character) - ``embedding`` -- embedding of the coefficient field into `\RR` or `\CC`, or an integer `i` (in which case take the `i`-th embedding) - - ``prec`` -- The desired precision in bits (default 53). + - ``prec`` -- the desired precision in bits (default: 53) - OUTPUT: The symmetric square L-series of the cusp form, as a + OUTPUT: the symmetric square `L`-series of the cusp form, as a :class:`sage.lfunctions.dokchitser.Dokchitser` object. EXAMPLES:: @@ -1170,7 +1169,7 @@ def petersson_norm(self, embedding=0, prec=53): Only implemented for N = 1 at present. It is assumed that `f` has real coefficients. The norm is computed as a special value of the symmetric - square L-function, using the identity + square `L`-function, using the identity .. MATH:: @@ -1178,10 +1177,10 @@ def petersson_norm(self, embedding=0, prec=53): INPUT: - - ``embedding``: embedding of the coefficient field into `\RR` or + - ``embedding`` -- embedding of the coefficient field into `\RR` or `\CC`, or an integer `i` (interpreted as the `i`-th embedding) (default: 0) - - ``prec`` (integer, default 53): precision in bits + - ``prec`` -- integer (default: 53); precision in bits EXAMPLES:: @@ -1217,7 +1216,7 @@ def _q_expansion_bound(self, eps): This function takes as input a modular form, ``self`` and a Dirichlet character ``eps`` and returns an integer bound such that if ``self`` and its twist by ``eps`` have the same - q-expansion up to this bound, then they are equal. + `q`-expansion up to this bound, then they are equal. The bound is taken from [Mu1997]_. See also [Shi1971]_, Proposition 3.64. @@ -1226,9 +1225,7 @@ def _q_expansion_bound(self, eps): - ``eps`` -- a Dirichlet character - OUTPUT: - - A positive integer. + OUTPUT: a positive integer EXAMPLES: @@ -1268,9 +1265,7 @@ def has_cm(self): r""" Return whether the modular form ``self`` has complex multiplication. - OUTPUT: - - Boolean + OUTPUT: boolean .. SEEALSO:: @@ -1386,13 +1381,13 @@ def __init__(self, parent, component, names, check=True): INPUT: - - ``parent`` -- An ambient cuspidal space of modular forms for - which self is a newform. + - ``parent`` -- an ambient cuspidal space of modular forms for + which ``self`` is a newform - - ``component`` -- A simple component of a cuspidal modular - symbols space of any sign corresponding to this newform. + - ``component`` -- a simple component of a cuspidal modular + symbols space of any sign corresponding to this newform - - ``check`` -- If check is ``True``, check that parent and + - ``check`` -- if check is ``True``, check that parent and component have the same weight, level, and character, that component has sign 1 and is simple, and that the types are correct on all inputs. @@ -1429,9 +1424,9 @@ def __init__(self, parent, component, names, check=True): self.__hecke_eigenvalue_field = extension_field def _name(self): - """ + r""" Return the name of the generator of the Hecke eigenvalue field - of self. Note that a name exists even when this field is QQ. + of ``self``. Note that a name exists even when this field is `\QQ`. EXAMPLES:: @@ -1442,7 +1437,7 @@ def _name(self): def _compute_q_expansion(self, prec): """ - Return the q-expansion of self to precision prec. + Return the `q`-expansion of ``self`` to precision ``prec``. EXAMPLES:: @@ -1456,7 +1451,7 @@ def _compute_q_expansion(self, prec): def __eq__(self, other): """ - Return True if self equals other, and False otherwise. + Return ``True`` if ``self`` equals ``other``, and ``False`` otherwise. EXAMPLES:: @@ -1482,7 +1477,6 @@ def __eq__(self, other): q - 4*q^2 + 16*q^4 - 14*q^5 + O(q^6) sage: f == g True - """ if (not isinstance(other, ModularForm_abstract) or self.weight() != other.weight()): return False @@ -1504,7 +1498,7 @@ def __eq__(self, other): @cached_method def abelian_variety(self): """ - Return the abelian variety associated to self. + Return the abelian variety associated to ``self``. EXAMPLES:: @@ -1516,7 +1510,6 @@ def abelian_variety(self): Traceback (most recent call last): ... TypeError: f must have weight 2 - """ from sage.modular.abvar.abvar_newform import ModularAbelianVariety_newform return ModularAbelianVariety_newform(self) @@ -1540,15 +1533,13 @@ def hecke_eigenvalue_field(self): def coefficient(self, n): """ - Return the coefficient of `q^n` in the power series of self. + Return the coefficient of `q^n` in the power series of ``self``. INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - OUTPUT: - - - the coefficient of `q^n` in the power series of self. + OUTPUT: the coefficient of `q^n` in the power series of ``self`` EXAMPLES:: @@ -1598,7 +1589,7 @@ def element(self): Find an element of the ambient space of modular forms which represents this newform. - .. note:: + .. NOTE:: This can be quite expensive. Also, the polynomial defining the field of Hecke eigenvalues should be considered random, @@ -1710,7 +1701,7 @@ def modsym_eigenspace(self, sign=0): def _defining_modular_symbols(self): """ - Return the modular symbols space corresponding to self. + Return the modular symbols space corresponding to ``self``. EXAMPLES:: @@ -1780,12 +1771,12 @@ def _atkin_lehner_eigenvalue_from_qexp(self, Q): - ``self`` -- a newform `f` - - ``Q`` -- an integer exactly dividing the level of ``self`` + - ``Q`` -- integer exactly dividing the level of ``self`` .. NOTE:: This method assumes that the `Q`-th coefficient in the - `q`-expansion of ``self`` is non-zero. + `q`-expansion of ``self`` is nonzero. TESTS:: @@ -1829,7 +1820,7 @@ def _atkin_lehner_eigenvalue_from_modsym(self, Q): - ``self`` -- a newform `f` - - ``Q`` -- a positive integer exactly dividing the level of ``self`` + - ``Q`` -- positive integer exactly dividing the level of ``self`` .. NOTE:: @@ -1986,8 +1977,8 @@ def atkin_lehner_eigenvalue(self, d=None, normalization='analytic', embedding=No INPUT: - - ``d`` -- a positive integer exactly dividing the level `N` of `f`, - i.e. `d` divides `N` and is coprime to `N/d`. The default is `d = N`. + - ``d`` -- positive integer exactly dividing the level `N` of `f`, + i.e., `d` divides `N` and is coprime to `N/d`; the default is `d = N` If `d` does not divide `N` exactly, then it will be replaced with a multiple `D` of `d` such that `D` exactly divides `N` and `D` has the @@ -1995,10 +1986,10 @@ def atkin_lehner_eigenvalue(self, d=None, normalization='analytic', embedding=No divide `N`. - ``normalization`` -- either ``'analytic'`` (the default) or - ``'arithmetic'``; see below. + ``'arithmetic'``; see below - ``embedding`` -- (optional) embedding of the coefficient field of `f` - into another ring. Ignored if `'normalization='arithmetic'``. + into another ring; ignored if ``'normalization='arithmetic'`` OUTPUT: @@ -2257,7 +2248,6 @@ def twist(self, chi, level=None, check=True): AUTHORS: - Peter Bruin (April 2015) - """ from sage.modular.all import CuspForms R = coercion_model.common_parent(self.base_ring(), chi.base_ring()) @@ -2432,16 +2422,15 @@ def __init__(self, parent, x, check=True): INPUT: - - ``parent`` -- ModularForms (an ambient space of modular forms) + - ``parent`` -- :class:`ModularFormsSpace` (an ambient space of modular + forms) - ``x`` -- a vector on the basis for parent - ``check`` -- if check is ``True``, check the types of the - inputs. - - OUTPUT: + inputs - - ``ModularFormElement`` -- a modular form + OUTPUT: ``ModularFormElement`` -- a modular form EXAMPLES:: @@ -2457,7 +2446,7 @@ def __init__(self, parent, x, check=True): def _compute_q_expansion(self, prec): """ - Computes the q-expansion of self to precision prec. + Compute the `q`-expansion of ``self`` to precision ``prec``. EXAMPLES:: @@ -2472,7 +2461,7 @@ def _compute_q_expansion(self, prec): def _add_(self, other): """ - Add self to other. + Add ``self`` to ``other``. EXAMPLES:: @@ -2491,10 +2480,10 @@ def _add_(self, other): def __mul__(self, other): r""" - Calculate the product self * other. + Calculate the product ``self * other``. This tries to determine the - characters of self and other, in order to avoid having to compute a + characters of ``self`` and ``other``, in order to avoid having to compute a (potentially very large) Gamma1 space. Note that this might lead to a modular form that is defined with respect to a larger subgroup than the factors are. @@ -2586,8 +2575,8 @@ def atkin_lehner_eigenvalue(self, d=None, embedding=None): INPUT: - - ``d`` -- a positive integer exactly dividing the level `N` of - ``self``, i.e. `d` divides `N` and is coprime to `N/d`. (Default: `d + - ``d`` -- positive integer exactly dividing the level `N` of + ``self``, i.e. `d` divides `N` and is coprime to `N/d`. (default: `d = N`) - ``embedding`` -- ignored (but accepted for compatibility with @@ -2596,7 +2585,7 @@ def atkin_lehner_eigenvalue(self, d=None, embedding=None): OUTPUT: The Atkin-Lehner eigenvalue of `W_d` on ``self``. If ``self`` is not an - eigenform for `W_d`, a :class:`ValueError` is raised. + eigenform for `W_d`, a :exc:`ValueError` is raised. .. SEEALSO:: @@ -2707,7 +2696,6 @@ def twist(self, chi, level=None): - \L. J. P. Kilford (2009-08-28) - Peter Bruin (2015-03-30) - """ from sage.modular.all import CuspForms, ModularForms R = coercion_model.common_parent(self.base_ring(), chi.base_ring()) @@ -2767,7 +2755,7 @@ def __init__(self, parent, E): def elliptic_curve(self): """ - Return elliptic curve associated to self. + Return elliptic curve associated to ``self``. EXAMPLES:: @@ -2824,7 +2812,7 @@ def atkin_lehner_eigenvalue(self, d=None, embedding=None): INPUT: - - ``d`` -- a positive integer exactly dividing the level `N` of + - ``d`` -- positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d`. (Defaults to `d = N` if not given.) @@ -2924,7 +2912,7 @@ def __init__(self, parent, vector, t, chi, psi): def _compute_q_expansion(self, prec=None): """ - Compute the q-expansion of self to precision prec. + Compute the `q`-expansion of ``self`` to precision ``prec``. EXAMPLES:: @@ -2951,7 +2939,6 @@ def _compute(self, X): [-9*zeta10^3 + 1, 16*zeta10^2 + 4*zeta10 + 1, 25*zeta10^3 - 25*zeta10^2 + 25*zeta10 - 24] - """ if self.weight() == 2 and (self.__chi.is_trivial() and self.__psi.is_trivial()): return self.__compute_weight2_trivial_character(X) @@ -2960,7 +2947,7 @@ def _compute(self, X): def __compute_weight2_trivial_character(self, X): r""" - Compute coefficients for self an Eisenstein series of the form + Compute coefficients for ``self`` an Eisenstein series of the form `E_2 - t*E_2(q^t)`. Computes `a_n` for each `n \in X`. EXAMPLES:: @@ -3057,7 +3044,7 @@ def __defining_parameters(self): def chi(self): """ - Return the parameter chi associated to self. + Return the parameter chi associated to ``self``. EXAMPLES:: @@ -3068,7 +3055,7 @@ def chi(self): def psi(self): """ - Return the parameter psi associated to self. + Return the parameter psi associated to ``self``. EXAMPLES:: @@ -3079,7 +3066,7 @@ def psi(self): def t(self): """ - Return the parameter t associated to self. + Return the parameter t associated to ``self``. EXAMPLES:: @@ -3090,7 +3077,7 @@ def t(self): def parameters(self): """ - Return chi, psi, and t, which are the defining parameters of self. + Return chi, psi, and t, which are the defining parameters of ``self``. EXAMPLES:: @@ -3124,7 +3111,7 @@ def M(self): @cached_method def character(self): """ - Return the character associated to self. + Return the character associated to ``self``. EXAMPLES:: @@ -3154,7 +3141,7 @@ def character(self): def new_level(self): """ - Return level at which self is new. + Return level at which ``self`` is new. EXAMPLES:: @@ -3217,13 +3204,11 @@ def __init__(self, parent, forms_datum): INPUT: - ``parent`` -- an object of the class ``ModularFormsRing`` - - ``forms_datum`` -- a dictionary ``{k_1:f_1, k_2:f_2, ..., k_n:f_n}`` + - ``forms_datum`` -- dictionary ``{k_1:f_1, k_2:f_2, ..., k_n:f_n}`` or a list ``[f_1, f_2,..., f_n]`` where `f_i` is a modular form of weight `k_i` - OUTPUT: - - A ``GradedModularFormElement`` corresponding to `f_1 + f_2 + ... + f_n` + OUTPUT: a ``GradedModularFormElement`` corresponding to `f_1 + f_2 + ... + f_n` TESTS:: @@ -3306,7 +3291,7 @@ def __init__(self, parent, forms_datum): def __bool__(self): r""" - Return "True" if ``self`` is non-zero and "False" otherwise. + Return "True" if ``self`` is nonzero and "False" otherwise. EXAMPLES:: @@ -3317,13 +3302,12 @@ def __bool__(self): True sage: bool(M(ModularForms(1,6).0)) True - """ return bool(self._forms_dictionary) def is_zero(self): r""" - Return "True" if the graded form is 0 and "False" otherwise + Return "True" if the graded form is 0 and "False" otherwise. EXAMPLES:: @@ -3340,7 +3324,7 @@ def is_zero(self): def is_one(self): r""" - Return "True" if the graded form is 1 and "False" otherwise + Return "True" if the graded form is 1 and "False" otherwise. EXAMPLES:: @@ -3405,7 +3389,7 @@ def q_expansion(self, prec=None): def _repr_(self): r""" - The string representation of self. + The string representation of ``self``. EXAMPLES:: @@ -3436,8 +3420,8 @@ def __getitem__(self, weight): INPUT: - - ``weight`` -- An integer corresponding to the weight of the - homogeneous component of the given graded modular form. + - ``weight`` -- integer corresponding to the weight of the + homogeneous component of the given graded modular form EXAMPLES:: @@ -3466,18 +3450,18 @@ def __getitem__(self, weight): sage: f[-1] Traceback (most recent call last): ... - ValueError: the weight must be non-negative + ValueError: the weight must be nonnegative """ if not isinstance(weight, (int, Integer)): raise KeyError("the weight must be an integer") if weight < 0: - raise ValueError("the weight must be non-negative") + raise ValueError("the weight must be nonnegative") return self._forms_dictionary.get(weight, self.parent().zero()) homogeneous_component = __getitem__ # alias def __call__(self, x, prec=None): r""" - Evaluate the q-expansion of this graded modular form at x. + Evaluate the `q`-expansion of this graded modular form at x. EXAMPLES:: @@ -3525,7 +3509,7 @@ def _add_(self, other): def __neg__(self): r""" - The negation of self. + The negation of ``self``. TESTS:: @@ -3579,13 +3563,13 @@ def _mul_(self, other): def _lmul_(self, c): r""" - The left action of the base ring on self. + The left action of the base ring on ``self``. INPUT: - ``c`` -- an element of the base ring of self - OUTPUT: A ``GradedModularFormElement``. + OUTPUT: a ``GradedModularFormElement`` TESTS:: @@ -3608,7 +3592,7 @@ def _lmul_(self, c): def _richcmp_(self, other, op): r""" - Compare self with other. + Compare ``self`` with ``other``. TESTS:: @@ -3688,7 +3672,8 @@ def weights_list(self): def is_homogeneous(self): r""" - Return True if the graded modular form is homogeneous, i.e. if it is a modular forms of a certain weight. + Return ``True`` if the graded modular form is homogeneous, i.e. if it + is a modular forms of a certain weight. An alias of this method is ``is_modular_form`` @@ -3714,10 +3699,11 @@ def _homogeneous_to_polynomial(self, names, gens): INPUT: - - ``names`` -- a list or tuple of names (strings), or a comma separated string; - - ``gens`` -- (list) a list of generator of ``self``. + - ``names`` -- list or tuple of names (strings), or a comma separated + string + - ``gens`` -- (list) a list of generator of ``self`` - OUTPUT: A polynomial in the variables ``names`` + OUTPUT: a polynomial in the variables ``names`` TESTS:: @@ -3794,13 +3780,14 @@ def to_polynomial(self, names='x', gens=None): INPUT: - - ``names`` -- a list or tuple of names (strings), or a comma separated string. Correspond - to the names of the variables; - - ``gens`` -- (default: None) a list of generator of the parent of ``self``. If set to ``None``, - the list returned by :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms` + - ``names`` -- list or tuple of names (strings), or a comma separated + string; corresponds to the names of the variables + - ``gens`` -- (default: ``None``) a list of generator of the parent of + ``self``. If set to ``None``, the list returned by + :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms` is used instead - OUTPUT: A polynomial in the variables ``names`` + OUTPUT: a polynomial in the variables ``names`` EXAMPLES:: @@ -3867,9 +3854,9 @@ def derivative(self, name='E2'): INPUT: - - ``name`` (str, default: 'E2') -- the name of the weight 2 Eisenstein - series generating the graded algebra of quasimodular forms over the - ring of modular forms. + - ``name``-- string (default: ``'E2'``); the name of the weight 2 + Eisenstein series generating the graded algebra of quasimodular forms + over the ring of modular forms OUTPUT: a :class:`sage.modular.quasimodform.element.QuasiModularFormsElement` diff --git a/src/sage/modular/modform/half_integral.py b/src/sage/modular/modform/half_integral.py index bf6c33e73a1..49e205cafab 100644 --- a/src/sage/modular/modform/half_integral.py +++ b/src/sage/modular/modform/half_integral.py @@ -16,6 +16,7 @@ from .theta import theta2_qexp, theta_qexp from copy import copy + def half_integral_weight_modform_basis(chi, k, prec): r""" A basis for the space of weight `k/2` forms with character @@ -28,9 +29,9 @@ def half_integral_weight_modform_basis(chi, k, prec): - ``k`` -- an odd integer > 1 - - ``prec`` -- a positive integer + - ``prec`` -- positive integer - OUTPUT: a list of power series + OUTPUT: list of power series .. warning:: diff --git a/src/sage/modular/modform/hecke_operator_on_qexp.py b/src/sage/modular/modform/hecke_operator_on_qexp.py index daf4c3bfbec..346a073f20a 100644 --- a/src/sage/modular/modform/hecke_operator_on_qexp.py +++ b/src/sage/modular/modform/hecke_operator_on_qexp.py @@ -19,13 +19,14 @@ from sage.rings.infinity import Infinity from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.rings.power_series_ring_element import is_PowerSeries +from sage.rings.power_series_ring_element import PowerSeries lazy_import('sage.rings.number_field.number_field', 'CyclotomicField') from sage.modular.dirichlet import DirichletGroup, DirichletCharacter from .element import ModularFormElement + def hecke_operator_on_qexp(f, n, k, eps=None, prec=None, check=True, _return_list=False): r""" @@ -87,7 +88,7 @@ def hecke_operator_on_qexp(f, n, k, eps=None, # ZZ can coerce to GF(p), but QQ can't. eps = DirichletGroup(1, base_ring=ZZ)[0] if check: - if not (is_PowerSeries(f) or isinstance(f, ModularFormElement)): + if not (isinstance(f, PowerSeries) or isinstance(f, ModularFormElement)): raise TypeError("f (=%s) must be a power series or modular form" % f) if not isinstance(eps, DirichletCharacter): raise TypeError("eps (=%s) must be a Dirichlet character" % eps) @@ -132,7 +133,7 @@ def hecke_operator_on_qexp(f, n, k, eps=None, def _hecke_operator_on_basis(B, V, n, k, eps): """ - Does the work for hecke_operator_on_basis once the input + Do the work for hecke_operator_on_basis once the input is normalized. EXAMPLES:: @@ -163,7 +164,7 @@ def hecke_operator_on_basis(B, n, k, eps=None, already_echelonized=False): with character `\varepsilon` to precision at least `\#B\cdot n+1`, this function computes the matrix of `T_n` relative to `B`. - .. note:: + .. NOTE:: If the elements of B are not known to sufficient precision, this function will report that the vectors are linearly @@ -171,16 +172,16 @@ def hecke_operator_on_basis(B, n, k, eps=None, already_echelonized=False): INPUT: - - ``B`` -- list of q-expansions + - ``B`` -- list of `q`-expansions - - ``n`` -- an integer >= 1 + - ``n`` -- integer >= 1 - - ``k`` -- an integer + - ``k`` -- integer - ``eps`` -- Dirichlet character - - ``already_echelonized`` -- bool (default: ``False``); if True, use that the - basis is already in Echelon form, which saves a lot of time. + - ``already_echelonized`` -- boolean (default: ``False``); if ``True``, use + that the basis is already in Echelon form, which saves a lot of time EXAMPLES:: @@ -235,7 +236,7 @@ def hecke_operator_on_basis(B, n, k, eps=None, already_echelonized=False): eps = DirichletGroup(1, R)[0] all_powerseries = True for x in B: - if not is_PowerSeries(x): + if not isinstance(x, PowerSeries): all_powerseries = False if not all_powerseries: raise TypeError("each element of B must be a power series") diff --git a/src/sage/modular/modform/j_invariant.py b/src/sage/modular/modform/j_invariant.py index 48b7c91fcb0..a74d42b91b2 100644 --- a/src/sage/modular/modform/j_invariant.py +++ b/src/sage/modular/modform/j_invariant.py @@ -6,6 +6,7 @@ from .vm_basis import delta_qexp from sage.rings.rational_field import QQ + def j_invariant_qexp(prec=10, K=QQ): r""" Return the `q`-expansion of the `j`-invariant to diff --git a/src/sage/modular/modform/l_series_gross_zagier.py b/src/sage/modular/modform/l_series_gross_zagier.py index 28acdeeb978..7959c346a2e 100644 --- a/src/sage/modular/modform/l_series_gross_zagier.py +++ b/src/sage/modular/modform/l_series_gross_zagier.py @@ -9,7 +9,7 @@ class GrossZagierLseries(SageObject): def __init__(self, E, A, prec=53): r""" - Class for the Gross-Zagier L-series. + Class for the Gross-Zagier `L`-series. This is attached to a pair `(E,A)` where `E` is an elliptic curve over `\QQ` and `A` is an ideal class in an imaginary quadratic number field. @@ -23,7 +23,7 @@ def __init__(self, E, A, prec=53): - ``A`` -- an ideal class in an imaginary quadratic number field - - ``prec`` -- an integer (default 53) giving the required precision + - ``prec`` -- integer (default: 53); giving the required precision EXAMPLES:: @@ -71,9 +71,9 @@ def __call__(self, s, der=0): INPUT: - - `s` -- complex number + - ``s`` -- complex number - - ``der`` -- ? (default 0) + - ``der`` -- (default: 0) EXAMPLES:: @@ -93,9 +93,9 @@ def taylor_series(self, s=1, series_prec=6, var='z'): INPUT: - - `s` -- complex number (default 1) - - ``series_prec`` -- number of terms (default 6) in the Taylor series - - ``var`` -- variable (default 'z') + - ``s`` -- complex number (default: 1) + - ``series_prec`` -- number of terms (default: 6) in the Taylor series + - ``var`` -- variable (default: ``'z'``) EXAMPLES:: diff --git a/src/sage/modular/modform/l_series_gross_zagier_coeffs.pyx b/src/sage/modular/modform/l_series_gross_zagier_coeffs.pyx index f91a3e256f0..b3dc41e1750 100644 --- a/src/sage/modular/modform/l_series_gross_zagier_coeffs.pyx +++ b/src/sage/modular/modform/l_series_gross_zagier_coeffs.pyx @@ -52,9 +52,7 @@ def bqf_theta_series(Q, long bound, var=None): - ``bound`` -- how many terms to compute - ``var`` -- (optional) the variable in which to express this power series - OUTPUT: - - A power series in ``var``, or list of ints if ``var`` is unspecified. + OUTPUT: a power series in ``var``, or list of ints if ``var`` is unspecified EXAMPLES:: @@ -99,19 +97,17 @@ cdef long* bqf_theta_series_c(long* terms, long bound, long a, long b, long c) e def gross_zagier_L_series(an_list, Q, long N, long u, var=None): """ - Compute the coefficients of the Gross-Zagier L-series. + Compute the coefficients of the Gross-Zagier `L`-series. INPUT: - - ``an_list`` -- list of coefficients of the L-series of an elliptic curve + - ``an_list`` -- list of coefficients of the `L`-series of an elliptic curve - ``Q`` -- a positive definite quadratic form - ``N`` -- conductor of the elliptic curve - ``u`` -- number of roots of unity in the field associated with ``Q`` - ``var`` -- (optional) the variable in which to express this power series - OUTPUT: - - A power series in ``var``, or list of ints if ``var`` is unspecified. + OUTPUT: a power series in ``var``, or list of ints if ``var`` is unspecified The number of terms is the length of the input ``an_list``. diff --git a/src/sage/modular/modform/meson.build b/src/sage/modular/modform/meson.build new file mode 100644 index 00000000000..7276059448d --- /dev/null +++ b/src/sage/modular/modform/meson.build @@ -0,0 +1,47 @@ +py.install_sources( + 'all.py', + 'ambient.py', + 'ambient_R.py', + 'ambient_eps.py', + 'ambient_g0.py', + 'ambient_g1.py', + 'constructor.py', + 'cuspidal_submodule.py', + 'defaults.py', + 'eis_series.py', + 'eisenstein_submodule.py', + 'element.py', + 'find_generators.py', + 'half_integral.py', + 'hecke_operator_on_qexp.py', + 'j_invariant.py', + 'l_series_gross_zagier.py', + 'notes.py', + 'numerical.py', + 'periods.py', + 'ring.py', + 'space.py', + 'submodule.py', + 'tests.py', + 'theta.py', + 'vm_basis.py', + 'weight1.py', + subdir: 'sage/modular/modform', +) + +extension_data = { + 'eis_series_cython' : files('eis_series_cython.pyx'), + 'l_series_gross_zagier_coeffs' : files('l_series_gross_zagier_coeffs.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modular/modform', + install: true, + include_directories: [inc_cpython, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + diff --git a/src/sage/modular/modform/numerical.py b/src/sage/modular/modform/numerical.py index 847859a70fb..dd14ff15995 100644 --- a/src/sage/modular/modform/numerical.py +++ b/src/sage/modular/modform/numerical.py @@ -3,58 +3,57 @@ Numerical computation of newforms """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2004-2006 William Stein # # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** - -from sage.rings.fast_arith import prime_range -from sage.matrix.constructor import matrix -from sage.misc.verbose import verbose -from sage.misc.cachefunc import cached_method -from sage.misc.prandom import randint +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.rings.fast_arith import prime_range +from sage.matrix.constructor import matrix +from sage.misc.verbose import verbose +from sage.misc.cachefunc import cached_method +from sage.misc.prandom import randint from sage.modular.arithgroup.all import Gamma0 -from sage.modular.modsym.all import ModularSymbols +from sage.modular.modsym.all import ModularSymbols from sage.modules.free_module_element import free_module_element as vector -from sage.rings.complex_double import CDF -from sage.rings.integer import Integer -from sage.rings.rational_field import QQ -from sage.structure.richcmp import richcmp_method, richcmp -from sage.structure.sage_object import SageObject -from sage.structure.sequence import Sequence +from sage.rings.complex_double import CDF +from sage.rings.integer import Integer +from sage.rings.rational_field import QQ +from sage.structure.richcmp import richcmp_method, richcmp +from sage.structure.sage_object import SageObject +from sage.structure.sequence import Sequence # This variable controls importing the SciPy library sparingly scipy = None + @richcmp_method class NumericalEigenforms(SageObject): """ - numerical_eigenforms(group, weight=2, eps=1e-20, delta=1e-2, tp=[2,3,5]) + numerical_eigenforms(group, weight=2, eps=1e-20, delta=1e-2, tp=[2,3,5]). INPUT: - ``group`` -- a congruence subgroup of a Dirichlet character of order 1 or 2 - - ``weight`` -- an integer >= 2 + - ``weight`` -- integer >= 2 - ``eps`` -- a small float; abs( ) < eps is what "equal to zero" is - interpreted as for floating point numbers. + interpreted as for floating point numbers - ``delta`` -- a small-ish float; eigenvalues are considered distinct if their difference has absolute value at least delta - ``tp`` -- use the Hecke operators T_p for p in tp when searching - for a random Hecke operator with distinct Hecke eigenvalues. - - OUTPUT: + for a random Hecke operator with distinct Hecke eigenvalues - A numerical eigenforms object, with the following useful methods: + OUTPUT: a numerical eigenforms object, with the following useful methods: - :meth:`ap` -- return all eigenvalues of `T_p` @@ -65,7 +64,7 @@ class NumericalEigenforms(SageObject): [eigenvalues of T_3], [eigenvalues of T_5], ...] - - :meth:`systems_of_eigenvalues` -- a list of the systems of + - :meth:`systems_of_eigenvalues` -- list of the systems of eigenvalues of eigenforms such that the chosen random linear combination of Hecke operators has multiplicity 1 eigenvalues. @@ -154,7 +153,7 @@ def weight(self): def _repr_(self): """ - Print string representation of self. + Print string representation of ``self``. EXAMPLES:: @@ -367,11 +366,9 @@ def ap(self, p): INPUT: - - ``p`` -- integer, a prime number - - OUTPUT: + - ``p`` -- integer; a prime number - - ``list`` -- a list of double precision complex numbers + OUTPUT: list of double precision complex numbers EXAMPLES:: @@ -400,11 +397,9 @@ def eigenvalues(self, primes): INPUT: - - ``primes`` -- a list of primes + - ``primes`` -- list of primes - OUTPUT: - - list of lists of eigenvalues. + OUTPUT: list of lists of eigenvalues EXAMPLES:: @@ -442,7 +437,7 @@ def phi(y): def systems_of_eigenvalues(self, bound): """ - Return all systems of eigenvalues for self for primes + Return all systems of eigenvalues for ``self`` for primes up to bound. EXAMPLES:: @@ -470,7 +465,7 @@ def systems_of_eigenvalues(self, bound): def systems_of_abs(self, bound): """ Return the absolute values of all systems of eigenvalues for - self for primes up to bound. + ``self`` for primes up to bound. EXAMPLES:: @@ -494,6 +489,7 @@ def systems_of_abs(self, bound): v.set_immutable() return v + def support(v, eps): """ Given a vector `v` and a threshold eps, return all @@ -506,6 +502,5 @@ def support(v, eps): sage: sage.modular.modform.numerical.support( numerical_eigenforms(61)._easy_vector(), 0.5 ) [0, 4] - """ return [i for i in range(v.degree()) if abs(v[i]) > eps] diff --git a/src/sage/modular/modform/ring.py b/src/sage/modular/modform/ring.py index bf7b10dc025..dacfda54bae 100644 --- a/src/sage/modular/modform/ring.py +++ b/src/sage/modular/modform/ring.py @@ -10,7 +10,7 @@ - William Stein (2007-08-24): first version - David Ayotte (2021-06): implemented category and Parent/Element frameworks """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # 2021 David Ayotte # @@ -18,8 +18,8 @@ # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from random import shuffle @@ -54,15 +54,15 @@ def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=Fals - ``forms`` -- list of pairs `(k, f)` with k an integer and f a power series (all over the same base ring) - - ``weight`` -- an integer - - ``prec`` -- an integer (less than or equal to the precision of all the - forms in ``forms``) -- precision to use in power series computations. - - ``stop_dim`` -- an integer: stop as soon as we have enough forms to span + - ``weight`` -- integer + - ``prec`` -- integer (less than or equal to the precision of all the + forms in ``forms``); precision to use in power series computations + - ``stop_dim`` -- integer; stop as soon as we have enough forms to span a submodule of this rank (a saturated one if the base ring is `\ZZ`). - Ignored if ``use_random`` is False. - - ``use_random`` -- which algorithm to use. If True, tries random products + Ignored if ``use_random`` is ``False``. + - ``use_random`` -- which algorithm to use. If ``True``, tries random products of the generators of the appropriate weight until a large enough - submodule is found (determined by ``stop_dim``). If False, just tries + submodule is found (determined by ``stop_dim``). If ``False``, just tries everything. Note that if the given forms do generate the whole space, then @@ -143,6 +143,7 @@ def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=Fals verbose('span has dimension %s' % W.rank(), t) return W + @richcmp_method class ModularFormsRing(Parent): r""" @@ -189,7 +190,6 @@ class ModularFormsRing(Parent): 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) sage: M((E4^3 - E6^2)/1728) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - """ Element = GradedModularFormElement @@ -201,8 +201,9 @@ def __init__(self, group, base_ring=QQ): - ``group`` -- a congruence subgroup of `\SL_2(\ZZ)`, or a positive integer `N` (interpreted as `\Gamma_0(N)`) - - ``base_ring`` (ring, default: `\QQ`) -- a base ring, which should be - `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p` + - ``base_ring`` -- ring (default: `\QQ`); a base ring, which + should be `\QQ`, `\ZZ`, or the integers mod `p` for some prime + `p` TESTS: @@ -242,17 +243,18 @@ def __init__(self, group, base_ring=QQ): self.__cached_gens = [] self.__cached_cusp_maxweight = ZZ(-1) self.__cached_cusp_gens = [] - Parent.__init__(self, base=base_ring, category=GradedAlgebras(base_ring)) + cat = GradedAlgebras(base_ring).Commutative() + Parent.__init__(self, base=base_ring, category=cat) def change_ring(self, base_ring): r""" - Return the ring of modular forms over the given base ring and the same - group as ``self``. + Return a ring of modular forms over a new base ring of the same + congruence subgroup. INPUT: - - ``base_ring`` -- a base ring, which should be `\QQ`, `\ZZ`, or the - integers mod `p` for some prime `p`. + - ``base_ring`` -- a base ring, which should be `\QQ`, `\ZZ`, or + the integers mod `p` for some prime `p` EXAMPLES:: @@ -267,7 +269,7 @@ def change_ring(self, base_ring): def some_elements(self): r""" - Return a list of generators of ``self``. + Return some elements of this ring. EXAMPLES:: @@ -279,7 +281,7 @@ def some_elements(self): def group(self): r""" - Return the congruence subgroup for which this is the ring of modular forms. + Return the congruence subgroup of this ring of modular forms. EXAMPLES:: @@ -291,14 +293,13 @@ def group(self): def gen(self, i): r""" - Return the `i`-th generator of ``self``. + Return the `i`-th generator of this ring. INPUT: - - ``i`` (Integer) -- correspond to the `i`-th modular form generating - the ring of modular forms. + - ``i`` -- integer - OUTPUT: A ``GradedModularFormElement`` + OUTPUT: an instance of :class:`~sage.modular.modform.GradedModularFormElement` EXAMPLES:: @@ -314,7 +315,7 @@ def gen(self, i): def ngens(self): r""" - Return the number of generators of ``self`` + Return the number of generators of this ring. EXAMPLES:: @@ -334,17 +335,25 @@ def ngens(self): def polynomial_ring(self, names, gens=None): r""" - Return a polynomial ring of which ``self`` is a quotient. + Return a polynomial ring of which this ring of modular forms is + a quotient. INPUT: - - ``names`` -- a list or tuple of names (strings), or a comma separated string - - ``gens`` (default: None) -- (list) a list of generator of ``self``. If ``gens`` is - ``None`` then the generators returned by :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms` - is used instead. - - OUTPUT: A multivariate polynomial ring in the variable ``names``. Each variable of the - polynomial ring correspond to a generator given in gens (following the ordering of the list). + - ``names`` -- a list or tuple of names (strings), or a comma + separated string; consists in the names of the polynomial + ring variables + - ``gens`` -- list of modular forms generating this ring + (default: ``None``); if ``gens`` is ``None`` then the list of + generators returned by the method + :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms` + is used instead. Note that we do not check if the list is + indeed a generating set. + + OUTPUT: a multivariate polynomial ring in the variable + ``names``. Each variable of the polynomial ring correspond to a + generator given in the list ``gens`` (following the ordering of + the list). EXAMPLES:: @@ -357,7 +366,8 @@ def polynomial_ring(self, names, gens=None): sage: M.polynomial_ring('g', gens) Multivariate Polynomial Ring in g0, g1, g2 over Rational Field - The degrees of the variables are the weights of the corresponding forms:: + The degrees of the variables are the weights of the + corresponding forms:: sage: M = ModularFormsRing(1) sage: P. = M.polynomial_ring() @@ -371,16 +381,17 @@ def polynomial_ring(self, names, gens=None): if gens is None: gens = self.gen_forms() degs = [f.weight() for f in gens] - return PolynomialRing(self.base_ring(), len(gens), names, order=TermOrder('wdeglex', degs)) # Should we remove the deg lexicographic ordering here? + return PolynomialRing(self.base_ring(), len(gens), names, + order=TermOrder('wdeglex', degs)) def _generators_variables_dictionnary(self, poly_parent, gens): r""" - Utility function that returns a dictionary giving an association between - polynomial ring generators and generators of modular forms ring. + Return a dictionary giving an association between polynomial + ring generators and generators of modular forms ring. INPUT: - - ``poly_parent`` -- A polynomial ring + - ``poly_parent`` -- a polynomial ring - ``gen`` -- list of generators of the modular forms ring TESTS:: @@ -397,26 +408,31 @@ def _generators_variables_dictionnary(self, poly_parent, gens): nb_var = poly_parent.ngens() nb_gens = self.ngens() if nb_var != nb_gens: - raise ValueError('the number of variables (%s) must be equal to the number of generators of the modular forms ring (%s)' % (nb_var, self.ngens())) + raise ValueError('the number of variables (%s) must be equal to' + ' the number of generators of the modular forms' + ' ring (%s)' % (nb_var, self.ngens())) return {poly_parent.gen(i): self(gens[i]) for i in range(0, nb_var)} def from_polynomial(self, polynomial, gens=None): r""" - Convert the given polynomial to a graded form living in ``self``. If - ``gens`` is ``None`` then the list of generators given by the method - :meth:`gen_forms` will be used. Otherwise, ``gens`` should be a list of - generators. + Return a graded modular form constructed by evaluating a given + multivariate polynomial at a set of generators. INPUT: - - ``polynomial`` -- A multivariate polynomial. The variables names of - the polynomial should be different from ``'q'``. The number of - variable of this polynomial should equal the number of generators - - ``gens`` -- list (default: ``None``) of generators of the modular - forms ring + - ``polynomial`` -- a multivariate polynomial. The variables + names of the polynomial should be different from ``'q'``. The + number of variable of this polynomial should equal the number + of given generators. + - ``gens`` -- list of modular forms generating this ring + (default: ``None``); if ``gens`` is ``None`` then the list of + generators returned by the method + :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms` + is used instead. Note that we do not check if the list is + indeed a generating set. - OUTPUT: A ``GradedModularFormElement`` given by the polynomial - relation ``polynomial``. + OUTPUT: a ``GradedModularFormElement`` given by the polynomial + relation ``polynomial`` EXAMPLES:: @@ -436,7 +452,8 @@ def from_polynomial(self, polynomial, gens=None): sage: M.from_polynomial(P(1/2)) 1/2 - Note that the number of variables must be equal to the number of generators:: + Note that the number of variables must be equal to the number of + generators:: sage: x, y = polygens(QQ, 'x, y') sage: M(x + y) @@ -469,13 +486,13 @@ def from_polynomial(self, polynomial, gens=None): def _element_constructor_(self, forms_datum): r""" - The call method of self. + Return the graded modular form corresponding to the given data. INPUT: - - ``forms_datum`` (dict, list, ModularFormElement, - GradedModularFormElement, RingElement, Multivariate polynomial) -- Try - to coerce ``forms_datum`` into self. + - ``forms_datum`` -- dictionary, list, ModularFormElement, + GradedModularFormElement, RingElement, or Multivariate polynomial; try + to coerce ``forms_datum`` into ``self`` TESTS:: @@ -523,7 +540,7 @@ def _element_constructor_(self, forms_datum): else: raise ValueError('the group (%s) and/or the base ring (%s) of the given modular form is not consistant with the base space: %s' % (forms_datum.group(), forms_datum.base_ring(), self)) elif forms_datum in self.base_ring(): - forms_dictionary = {0:forms_datum} + forms_dictionary = {0: forms_datum} elif isinstance(forms_datum, MPolynomial): return self.from_polynomial(forms_datum) elif isinstance(forms_datum, PowerSeries_poly): @@ -576,7 +593,8 @@ def one(self): def _coerce_map_from_(self, M): r""" - Code to make ModularFormRing work well with coercion framework. + Return ``True`` if there is a coercion map from ``M`` to this + ring. TESTS:: @@ -601,7 +619,7 @@ def _coerce_map_from_(self, M): def __richcmp__(self, other, op): r""" - Compare self to other. + Compare ``self`` to ``other``. Rings are equal if and only if their groups and base rings are. @@ -622,7 +640,7 @@ def __richcmp__(self, other, op): def _repr_(self): r""" - String representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -635,7 +653,8 @@ def _repr_(self): def modular_forms_of_weight(self, weight): """ - Return the space of modular forms on this group of the given weight. + Return the space of modular forms of the given weight and the + same congruence subgroup. EXAMPLES:: @@ -649,23 +668,30 @@ def modular_forms_of_weight(self, weight): def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2): r""" - If `R` is the base ring of self, then this function calculates a set of - modular forms which generate the `R`-algebra of all modular forms of - weight up to ``maxweight`` with coefficients in `R`. + Return a list of generator of this ring as a list of pairs + `(k, f)` where `k` is an integer and `f` is a univariate power + series in `q` corresponding to the `q`-expansion of a modular + form of weight `k`. + + More precisely, if `R` is the base ring of self, then this + function calculates a set of modular forms which generate the + `R`-algebra of all modular forms of weight up to ``maxweight`` + with coefficients in `R`. INPUT: - - ``maxweight`` (integer, default: 8) -- check up to this weight for - generators + - ``maxweight`` -- integer (default: 8); check up to this weight + for generators - - ``prec`` (integer, default: 10) -- return `q`-expansions to this - precision + - ``prec`` -- integer (default: 10); return `q`-expansions to + this precision - - ``start_gens`` (list, default: ``[]``) -- list of pairs `(k, f)`, or - triples `(k, f, F)`, where: + - ``start_gens`` -- list (default: ``[]``); list of pairs + `(k, f)`, or triples `(k, f, F)`, where: - `k` is an integer, - - `f` is the `q`-expansion of a modular form of weight `k`, as a power series over the base ring of self, + - `f` is the `q`-expansion of a modular form of weight `k`, + as a power series over the base ring of self, - `F` (if provided) is a modular form object corresponding to F. If this list is nonempty, we find a minimal generating set containing @@ -674,12 +700,12 @@ def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2): the case); otherwise, more terms will be calculated from the modular form object `F`. - - ``start_weight`` (integer, default: 2) -- calculate the graded - subalgebra of forms of weight at least ``start_weight``. + - ``start_weight`` -- integer (default: 2); calculate the graded + subalgebra of forms of weight at least ``start_weight`` OUTPUT: - a list of pairs (k, f), where f is the q-expansion to precision + a list of pairs (k, f), where f is the `q`-expansion to precision ``prec`` of a modular form of weight k. .. SEEALSO:: @@ -786,7 +812,8 @@ def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2): for x in start_gens: if len(x) == 2: if x[1].prec() < prec: - raise ValueError("Requested precision cannot be higher than precision of approximate starting generators!") + raise ValueError("Requested precision cannot be higher" + " than precision of approximate starting generators!") sgs.append((x[0], x[1], None)) else: sgs.append(x) @@ -806,22 +833,22 @@ def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2): def gen_forms(self, maxweight=8, start_gens=[], start_weight=2): r""" - Return a list of modular forms generating this ring (as an algebra over - the appropriate base ring). + Return a list of modular forms generating this ring (as an algebra + over the appropriate base ring). This method differs from :meth:`generators` only in that it returns graded modular form objects, rather than bare `q`-expansions. INPUT: - - ``maxweight`` (integer, default: 8) -- calculate forms generating all - forms up to this weight + - ``maxweight`` -- integer (default: 8); calculate forms + generating all forms up to this weight - - ``start_gens`` (list, default: ``[]``) -- a list of modular forms. If - this list is nonempty, we find a minimal generating set containing - these forms + - ``start_gens`` -- list (default: ``[]``); a list of + modular forms. If this list is nonempty, we find a minimal + generating set containing these forms. - - ``start_weight`` (integer, default: 2) -- calculate the graded + - ``start_weight`` -- integer (default: 2); calculate the graded subalgebra of forms of weight at least ``start_weight`` .. NOTE:: @@ -840,20 +867,21 @@ def gen_forms(self, maxweight=8, start_gens=[], start_weight=2): q - 9*q^4 - 10*q^5 + O(q^6)] sage: A[0].parent() Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field - """ - sgs = tuple( (F.weight(), None, F) for F in start_gens ) + sgs = tuple((F.weight(), None, F) for F in start_gens) G = self._find_generators(maxweight, sgs, start_weight) - return [F for k,f,F in G] + return [F for k, f, F in G] gens = gen_forms def _find_generators(self, maxweight, start_gens, start_weight): r""" - For internal use. This function is called by :meth:`generators` and - :meth:`gen_forms`: it returns a list of triples `(k, f, F)` where `F` - is a modular form of weight `k` and `f` is its `q`-expansion coerced - into the base ring of self. + Returns a list of triples `(k, f, F)` where `F` is a modular + form of weight `k` and `f` is its `q`-expansion coerced into the + base ring of self. + + For internal use. This function is called by :meth:`generators` + and :meth:`gen_forms`. INPUT: @@ -861,12 +889,10 @@ def _find_generators(self, maxweight, start_gens, start_weight): - ``start_weight`` -- minimum weight to try - ``start_gens`` -- a sequence of tuples of the form `(k, f, F)`, where `F` is a modular form of weight `k` and `f` is its `q`-expansion - coerced into ``self.base_ring()`. Either (but not both) of `f` and `F` + coerced into ``self.base_ring()``. Either (but not both) of `f` and `F` may be ``None``. - OUTPUT: - - a list of tuples, formatted as with ``start_gens``. + OUTPUT: list of tuples, formatted as with ``start_gens`` EXAMPLES:: @@ -975,19 +1001,19 @@ def _find_generators(self, maxweight, start_gens, start_weight): @cached_method def q_expansion_basis(self, weight, prec=None, use_random=True): r""" - Calculate a basis of q-expansions for the space of modular forms of the - given weight for this group, calculated using the ring generators given - by ``find_generators``. + Return a basis of `q`-expansions for the space of modular forms + of the given weight for this group, calculated using the ring + generators given by ``find_generators``. INPUT: - - ``weight`` (integer) -- the weight - - ``prec`` (integer or ``None``, default: ``None``) -- power series - precision. If ``None``, the precision defaults to the Sturm bound for - the requested level and weight. - - ``use_random`` (boolean, default: ``True``) -- whether or not to use a - randomized algorithm when building up the space of forms at the given - weight from known generators of small weight. + - ``weight`` -- the weight + - ``prec`` -- integer (default: ``None``); power series + precision. If ``None``, the precision defaults to the Sturm + bound for the requested level and weight. + - ``use_random`` -- boolean (default: ``True``); whether or not to + use a randomized algorithm when building up the space of forms + at the given weight from known generators of small weight. EXAMPLES:: @@ -1043,8 +1069,8 @@ def q_expansion_basis(self, weight, prec=None, use_random=True): def cuspidal_ideal_generators(self, maxweight=8, prec=None): r""" - Calculate generators for the ideal of cuspidal forms in this ring, as a - module over the whole ring. + Return a set of generators for the ideal of cuspidal forms in + this ring, as a module over the whole ring. EXAMPLES:: @@ -1065,7 +1091,7 @@ def cuspidal_ideal_generators(self, maxweight=8, prec=None): for j,f,F in self.__cached_cusp_gens: if f.prec() >= working_prec: f = F.qexp(working_prec).change_ring(self.base_ring()) - G.append( (j,f,F) ) + G.append((j, f, F)) else: k = 2 G = [] @@ -1116,22 +1142,23 @@ def cuspidal_ideal_generators(self, maxweight=8, prec=None): if prec is None: return G elif prec <= working_prec: - return [ (k, f.truncate_powerseries(prec), F) for k,f,F in G] + return [(k, f.truncate_powerseries(prec), F) for k,f,F in G] else: # user wants increased precision, so we may as well cache that - Gnew = [ (k, F.qexp(prec).change_ring(self.base_ring()), F) for k,f,F in G] + Gnew = [(k, F.qexp(prec).change_ring(self.base_ring()), F) for k, f, F in G] self.__cached_cusp_gens = Gnew return Gnew def cuspidal_submodule_q_expansion_basis(self, weight, prec=None): r""" - Calculate a basis of `q`-expansions for the space of cusp forms of + Return a basis of `q`-expansions for the space of cusp forms of weight ``weight`` for this group. INPUT: - - ``weight`` (integer) -- the weight - - ``prec`` (integer or None) -- precision of `q`-expansions to return + - ``weight`` -- the weight + - ``prec`` -- integer (default: ``None``) precision of + `q`-expansions to return ALGORITHM: Uses the method :meth:`cuspidal_ideal_generators` to calculate generators of the ideal of cusp forms inside this ring. Then diff --git a/src/sage/modular/modform/space.py b/src/sage/modular/modform/space.py index 7dba1ae3a0f..202ea687953 100644 --- a/src/sage/modular/modform/space.py +++ b/src/sage/modular/modform/space.py @@ -70,7 +70,7 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.power_series_ring import PowerSeriesRing -from sage.rings.power_series_ring_element import is_PowerSeries +from sage.rings.power_series_ring_element import PowerSeries from sage.rings.rational_field import QQ from sage.categories.rings import Rings @@ -87,7 +87,7 @@ def is_ModularFormsSpace(x): r""" - Return True if x is a ```ModularFormsSpace```. + Return ``True`` if x is a ``ModularFormsSpace``. EXAMPLES:: @@ -163,11 +163,9 @@ def prec(self, new_prec=None): INPUT: + - ``new_prec`` -- positive integer (default: ``None``) - - ``new_prec`` -- positive integer (default: None) - - - OUTPUT: if new_prec is None, returns the current precision. + OUTPUT: if new_prec is None, returns the current precision EXAMPLES:: @@ -195,9 +193,7 @@ def set_precision(self, new_prec): INPUT: - - - ``new_prec`` -- positive integer - + - ``new_prec`` -- positive integer EXAMPLES:: @@ -346,11 +342,11 @@ def character(self): def has_character(self): r""" - Return True if this space of modular forms has a specific + Return ``True`` if this space of modular forms has a specific character. - This is True exactly when the character() function does not return - None. + This is ``True`` exactly when the ``character()`` function does not + return ``None``. EXAMPLES: A space for `\Gamma_0(N)` has trivial character, hence has a character. @@ -374,7 +370,7 @@ def has_character(self): def is_ambient(self): """ - Return True if this an ambient space of modular forms. + Return ``True`` if this an ambient space of modular forms. EXAMPLES:: @@ -417,7 +413,7 @@ def __normalize_prec(self, prec): @cached_method def echelon_form(self): r""" - Return a space of modular forms isomorphic to self but with basis + Return a space of modular forms isomorphic to ``self`` but with basis of `q`-expansions in reduced echelon form. This is useful, e.g., the default basis for spaces of modular forms @@ -490,7 +486,7 @@ def echelon_form(self): @cached_method def echelon_basis(self): """ - Return a basis for self in reduced echelon form. This means that if + Return a basis for ``self`` in reduced echelon form. This means that if we view the `q`-expansions of the basis as defining rows of a matrix (with infinitely many columns), then this matrix is in reduced echelon form. @@ -619,7 +615,7 @@ def integral_basis(self): @cached_method def _q_expansion_module(self): """ - Return module spanned by coefficients of q-expansions to sufficient + Return module spanned by coefficients of `q`-expansions to sufficient precision to determine elements of this space. EXAMPLES:: @@ -642,7 +638,7 @@ def _q_expansion_module(self): def q_expansion_basis(self, prec=None): """ - Return a sequence of q-expansions for the basis of this space + Return a sequence of `q`-expansions for the basis of this space computed to the given input precision. INPUT: @@ -650,12 +646,12 @@ def q_expansion_basis(self, prec=None): - ``prec`` -- integer (>=0) or None If prec is None, the prec is computed to be *at least* large - enough so that each q-expansion determines the form as an element + enough so that each `q`-expansion determines the form as an element of this space. - .. note:: + .. NOTE:: - In fact, the q-expansion basis is always computed to + In fact, the `q`-expansion basis is always computed to *at least* ``self.prec()``. EXAMPLES:: @@ -749,7 +745,7 @@ def _compute_q_expansion_basis(self, prec): def q_echelon_basis(self, prec=None): r""" Return the echelon form of the basis of `q`-expansions of - self up to precision prec. + ``self`` up to precision ``prec``. The `q`-expansions are power series (not actual modular forms). The number of `q`-expansions returned equals the @@ -802,12 +798,12 @@ def q_echelon_basis(self, prec=None): def q_integral_basis(self, prec=None): r""" Return a `\ZZ`-reduced echelon basis of - `q`-expansions for self. + `q`-expansions for ``self``. The `q`-expansions are power series with coefficients in `\ZZ`; they are *not* actual modular forms. - The base ring of self must be `\QQ`. The number of + The base ring of ``self`` must be `\QQ`. The number of `q`-expansions returned equals the dimension. EXAMPLES:: @@ -852,7 +848,7 @@ def q_integral_basis(self, prec=None): @cached_method def _q_expansion_ring(self): """ - Returns the parent for q-expansions of modular forms in self. + Return the parent for `q`-expansions of modular forms in ``self``. EXAMPLES:: @@ -865,7 +861,7 @@ def _q_expansion_ring(self): @cached_method def _q_expansion_zero(self): """ - Returns the q-expansion of the modular form 0. + Return the `q`-expansion of the modular form 0. EXAMPLES:: @@ -879,8 +875,8 @@ def _q_expansion_zero(self): def _q_expansion(self, element, prec): """ - Take an element of self (specified as a list, tuple, or vector), - and return the corresponding q-expansion. + Take an element of ``self`` (specified as a list, tuple, or vector), + and return the corresponding `q`-expansion. EXAMPLES:: @@ -899,7 +895,7 @@ def _q_expansion(self, element, prec): def __add__(self, right): """ - If self and right live inside the same ambient module, return the + If ``self`` and ``right`` live inside the same ambient module, return the sum of the two spaces (as modules). EXAMPLES:: @@ -929,15 +925,13 @@ def __add__(self, right): def _has_natural_inclusion_map_to(self, right): """ Return true if there is a natural inclusion map from modular forms - in self to modular forms in right. + in ``self`` to modular forms in right. INPUT: + - ``self``, ``right`` -- spaces of modular forms - - ``self, right`` -- spaces of modular forms - - - OUTPUT: True if self embeds in right, and False otherwise. + OUTPUT: ``True`` if ``self`` embeds in ``right``, ``False`` otherwise TODO: Barring a few trivial cases, this only works in the case that right.is_ambient() returns True. @@ -997,11 +991,11 @@ def _coerce_map_from_(self, from_par): def _element_constructor_(self, x, check=True): """ - Try to coerce x into self. If x is a vector of length - self.dimension(), interpret it as a list of coefficients for - self.basis() and return that linear combination. If x is a power - series, it tries to determine whether or not x lives in self. If - so, it returns x as an element of M, and throws an error if not. + Try to coerce ``x`` into ``self``. If ``x`` is a vector of length + ``self.dimension()``, interpret it as a list of coefficients for + ``self.basis()`` and return that linear combination. If ``x`` is a power + series, it tries to determine whether or not ``x`` lives in ``self``. If + so, it returns ``x`` as an element of M, and throws an error if not. EXAMPLES:: @@ -1066,7 +1060,7 @@ def _element_constructor_(self, x, check=True): sage: ModularForms(1, 12)(R(1)) Traceback (most recent call last): ... - TypeError: unable to create modular form from exact non-zero polynomial + TypeError: unable to create modular form from exact nonzero polynomial sage: E = ModularForms(3,12).cuspidal_subspace() sage: f = E.gens()[0] @@ -1121,12 +1115,12 @@ def _element_constructor_(self, x, check=True): return self(x.q_expansion(self._q_expansion_module().degree())) - elif is_PowerSeries(x): + elif isinstance(x, PowerSeries): if x.prec() == PlusInfinity(): if x == 0: return self.element_class(self, self.free_module().zero()) else: - raise TypeError("unable to create modular form from exact non-zero polynomial") + raise TypeError("unable to create modular form from exact nonzero polynomial") W = self._q_expansion_module() if W.degree() <= x.prec(): try: @@ -1152,7 +1146,7 @@ def _pushout_(self, other): - ``other`` -- ``ModularFormSpace`` or a ``ModularFormRing`` - OUTPUT: If ``self`` and ``other`` have the same groups and base rings, then this method returns + OUTPUT: if ``self`` and ``other`` have the same groups and base rings, then this method returns ``self`` if the weights of the two spaces are equal, otherwise it returns a ``ModularFormsRing``. @@ -1184,7 +1178,7 @@ def _pushout_(self, other): def __richcmp__(self, x, op): """ - Compare self and x. + Compare ``self`` and ``x``. For spaces of modular forms, we order first by signature, then by dimension, and then by the ordering on the underlying free @@ -1227,7 +1221,7 @@ def __richcmp__(self, x, op): def span_of_basis(self, B): """ - Take a set B of forms, and return the subspace of self with B as a + Take a set B of forms, and return the subspace of ``self`` with B as a basis. EXAMPLES:: @@ -1262,7 +1256,7 @@ def span_of_basis(self, B): def __submodule_from_subset_of_basis(self, x): """ - Return the submodule of self generated by the elements of x. + Return the submodule of ``self`` generated by the elements of x. EXAMPLES:: @@ -1278,7 +1272,7 @@ def __submodule_from_subset_of_basis(self, x): def _compute_hecke_matrix_prime(self, p, prec=None): """ - Compute the matrix of the Hecke operator T_p acting on self. + Compute the matrix of the Hecke operator `T_p` acting on ``self``. EXAMPLES:: @@ -1306,8 +1300,7 @@ def _compute_hecke_matrix_prime(self, p, prec=None): except AttributeError: pass else: - if prec < cur: - prec = cur + prec = max(prec, cur) B = self.q_expansion_basis(prec) eps = self.character() if eps is None: @@ -1321,7 +1314,7 @@ def _compute_hecke_matrix_prime(self, p, prec=None): def _compute_hecke_matrix(self, n): """ - Compute the matrix of the Hecke operator T_n acting on self. + Compute the matrix of the Hecke operator `T_n` acting on ``self``. EXAMPLES:: @@ -1378,7 +1371,7 @@ def _compute_hecke_matrix(self, n): @cached_method def basis(self): """ - Return a basis for self. + Return a basis for ``self``. EXAMPLES:: @@ -1395,7 +1388,7 @@ def basis(self): def gen(self, n): """ - Return the nth generator of self. + Return the `n`-th generator of ``self``. EXAMPLES:: @@ -1433,7 +1426,7 @@ def gen(self, n): def gens(self): """ - Return a complete set of generators for self. + Return a complete set of generators for ``self``. EXAMPLES:: @@ -1452,10 +1445,10 @@ def gens(self): def sturm_bound(self, M=None): r""" For a space M of modular forms, this function returns an integer B - such that two modular forms in either self or M are equal if and - only if their q-expansions are equal to precision B (note that this + such that two modular forms in either ``self`` or M are equal if and + only if their `q`-expansions are equal to precision B (note that this is 1+ the usual Sturm bound, since `O(q^\mathrm{prec})` has - precision prec). If M is none, then M is set equal to self. + precision ``prec``). If M is none, then M is set equal to ``self``. EXAMPLES:: @@ -1518,7 +1511,7 @@ def sturm_bound(self, M=None): def cuspidal_submodule(self): """ - Return the cuspidal submodule of self. + Return the cuspidal submodule of ``self``. EXAMPLES:: @@ -1587,7 +1580,7 @@ def cuspidal_subspace(self): def is_cuspidal(self): r""" - Return True if this space is cuspidal. + Return ``True`` if this space is cuspidal. EXAMPLES:: @@ -1601,7 +1594,7 @@ def is_cuspidal(self): def is_eisenstein(self): r""" - Return True if this space is Eisenstein. + Return ``True`` if this space is Eisenstein. EXAMPLES:: @@ -1615,11 +1608,11 @@ def is_eisenstein(self): def new_submodule(self, p=None): """ - Return the new submodule of self. + Return the new submodule of ``self``. - If p is specified, return the p-new submodule of self. + If `p` is specified, return the `p`-new submodule of ``self``. - .. note:: + .. NOTE:: This function should be overridden by all derived classes. @@ -1651,7 +1644,7 @@ def eisenstein_series(self): """ Compute the Eisenstein series associated to this space. - .. note:: + .. NOTE:: This function should be overridden by all derived classes. @@ -1673,7 +1666,7 @@ def decomposition(self): self, if possible. The space `V(f_i,t)` is the image under `g(q)` maps to `g(q^t)` of the intersection with `R[[q]]` of the space spanned by the conjugates of - `f_i`, where `R` is the base ring of self. + `f_i`, where `R` is the base ring of ``self``. TODO: Implement this function. @@ -1688,7 +1681,7 @@ def decomposition(self): def newforms(self, names=None): """ - Return all newforms in the cuspidal subspace of self. + Return all newforms in the cuspidal subspace of ``self``. EXAMPLES:: @@ -1705,15 +1698,15 @@ def newforms(self, names=None): """ M = self.modular_symbols(sign=1) factors = M.cuspidal_subspace().new_subspace().decomposition() - large_dims = [ X.dimension() for X in factors if X.dimension() != 1 ] - if len(large_dims) > 0 and names is None: + large_dims = [X.dimension() for X in factors if X.dimension() != 1] + if large_dims and names is None: raise ValueError("Please specify a name to be used when generating names for generators of Hecke eigenvalue fields corresponding to the newforms.") elif names is None: # In this case, we don't need a variable name, so insert # something to get passed along below names = 'a' - return [ Newform(self, factors[i], names=(names+str(i)) ) - for i in range(len(factors)) ] + return [Newform(self, factors[i], names=names + str(i)) + for i in range(len(factors))] @cached_method def eisenstein_submodule(self): @@ -1766,7 +1759,7 @@ def eisenstein_subspace(self): def embedded_submodule(self): """ - Return the underlying module of self. + Return the underlying module of ``self``. EXAMPLES:: @@ -1823,7 +1816,7 @@ def embedded_submodule(self): def level(self): """ - Return the level of self. + Return the level of ``self``. EXAMPLES:: @@ -1835,7 +1828,7 @@ def level(self): def modular_symbols(self, sign=0): """ - Return the space of modular symbols corresponding to self with the + Return the space of modular symbols corresponding to ``self`` with the given sign. .. NOTE:: @@ -1856,27 +1849,25 @@ def find_in_space(self, f, forms=None, prec=None, indep=True): """ INPUT: + - ``f`` -- a modular form or power series - - ``f`` -- a modular form or power series + - ``forms`` -- (default: ``None``) a specific list of + modular forms or `q`-expansions - - ``forms`` -- (default: None) a specific list of - modular forms or q-expansions. + - ``prec`` -- if forms are given, compute with them to + the given precision - - ``prec`` -- if forms are given, compute with them to - the given precision + - ``indep`` -- boolean (default: ``True``); whether the given list + of forms are assumed to form a basis - - ``indep`` -- (default: ``True``) whether the given list - of forms are assumed to form a basis. - - - OUTPUT: A list of numbers that give f as a linear combination of + OUTPUT: list of numbers that give f as a linear combination of the basis for this space or of the given forms if independent=True. - .. note:: + .. NOTE:: If the list of forms is given, they do *not* have to be in - self. + ``self``. EXAMPLES:: @@ -1914,7 +1905,7 @@ def find_in_space(self, f, forms=None, prec=None, indep=True): B = V.span_of_basis(w) else: B = V.span(w) - if is_PowerSeries(f) and f.prec() < n: + if isinstance(f, PowerSeries) and f.prec() < n: raise ValueError("you need at least %s terms of precision" % n) x = V(f.padded_list(n)) return B.coordinates(x) diff --git a/src/sage/modular/modform/submodule.py b/src/sage/modular/modform/submodule.py index 15a45b80069..992b7ed6231 100644 --- a/src/sage/modular/modform/submodule.py +++ b/src/sage/modular/modform/submodule.py @@ -39,11 +39,11 @@ def __init__(self, ambient_module, submodule, dual=None, check=False): """ INPUT: - - ambient_module -- ModularFormsSpace - - submodule -- a submodule of the ambient space. - - dual_module -- (default: None) ignored - - check -- (default: ``False``) whether to check that the - submodule is Hecke equivariant + - ``ambient_module`` -- ModularFormsSpace + - ``submodule`` -- a submodule of the ambient space + - ``dual_module`` -- (default: ``None``) ignored + - ``check`` -- boolean (default: ``False``); whether to check that the + submodule is Hecke equivariant EXAMPLES:: @@ -51,7 +51,6 @@ def __init__(self, ambient_module, submodule, dual=None, check=False): Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field sage: M.eisenstein_subspace() Eisenstein subspace of dimension 11 of Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field - """ A = ambient_module sage.modular.hecke.submodule.HeckeSubmodule.__init__(self, A, submodule, check=check) @@ -69,7 +68,7 @@ def _repr_(self): def _compute_coefficients(self, element, X): """ - Compute all coefficients of the modular form element in self for + Compute all coefficients of the modular form element in ``self`` for indices in X. TODO: Implement this function. @@ -86,7 +85,8 @@ def _compute_coefficients(self, element, X): def _compute_q_expansion_basis(self, prec): """ - Compute q_expansions to precision prec for each element in self.basis(). + Compute ``q_expansions`` to precision ``prec`` for each element in + ``self.basis()``. EXAMPLES:: diff --git a/src/sage/modular/modform/theta.py b/src/sage/modular/modform/theta.py index ea0a88c81ba..fbe34473f98 100644 --- a/src/sage/modular/modform/theta.py +++ b/src/sage/modular/modform/theta.py @@ -11,19 +11,18 @@ from math import sqrt + def theta2_qexp(prec=10, var='q', K=ZZ, sparse=False): r""" Return the `q`-expansion of the series `\theta_2 = \sum_{n \text{ odd}} q^{n^2}`. INPUT: - - prec -- integer; the absolute precision of the output - - var -- (default: 'q') variable name - - K -- (default: ZZ) base ring of answer - - OUTPUT: + - ``prec`` -- integer; the absolute precision of the output + - ``var`` -- (default: ``'q'``) variable name + - ``K`` -- (default: ZZ) base ring of answer - a power series over K + OUTPUT: a power series over K EXAMPLES:: @@ -60,6 +59,7 @@ def theta2_qexp(prec=10, var='q', K=ZZ, sparse=False): R = PowerSeriesRing(K, sparse=sparse, names=var) return R(v, prec=prec) + def theta_qexp(prec=10, var='q', K=ZZ, sparse=False): r""" Return the `q`-expansion of the standard `\theta` series @@ -67,13 +67,11 @@ def theta_qexp(prec=10, var='q', K=ZZ, sparse=False): INPUT: - - prec -- integer; the absolute precision of the output - - var -- (default: 'q') variable name - - K -- (default: ZZ) base ring of answer + - ``prec`` -- integer; the absolute precision of the output + - ``var`` -- (default: ``'q'``) variable name + - ``K`` -- (default: ZZ) base ring of answer - OUTPUT: - - a power series over K + OUTPUT: a power series over K EXAMPLES:: @@ -91,7 +89,6 @@ def theta_qexp(prec=10, var='q', K=ZZ, sparse=False): 1 + 2*q + 2*q^4 + 2*q^9 + 2*q^16 + O(q^20) sage: parent(f) Sparse Power Series Ring in q over Integer Ring - """ prec = Integer(prec) if prec <= 0: diff --git a/src/sage/modular/modform/vm_basis.py b/src/sage/modular/modform/vm_basis.py index 6e04ad12156..58f36fd0f1a 100644 --- a/src/sage/modular/modform/vm_basis.py +++ b/src/sage/modular/modform/vm_basis.py @@ -19,14 +19,14 @@ True """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 William Stein # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import math @@ -53,17 +53,15 @@ def victor_miller_basis(k, prec=10, cusp_only=False, var='q'): INPUT: - - ``k`` -- an integer + - ``k`` -- integer - ``prec`` -- (default: 10) a positive integer - - ``cusp_only`` -- bool (default: ``False``) + - ``cusp_only`` -- boolean (default: ``False``) - - ``var`` -- string (default: 'q') + - ``var`` -- string (default: ``'q'``) - OUTPUT: - - A sequence whose entries are power series in ``ZZ[[var]]``. + OUTPUT: a sequence whose entries are power series in ``ZZ[[var]]`` EXAMPLES:: @@ -132,7 +130,7 @@ def victor_miller_basis(k, prec=10, cusp_only=False, var='q'): if k % 2 == 1 or k == 2: return Sequence([]) elif k < 0: - raise ValueError("k must be non-negative") + raise ValueError("k must be nonnegative") elif k == 0: return Sequence([PowerSeriesRing(ZZ,var)(1).add_bigoh(prec)], cr=True) e = k.mod(12) @@ -158,22 +156,22 @@ def victor_miller_basis(k, prec=10, cusp_only=False, var='q'): ls[i] = err return Sequence(ls, cr=True) - F6 = eisenstein_series_poly(6,prec) + F6 = eisenstein_series_poly(6, prec) if e == 0: A = Fmpz_poly(1) elif e == 4: - A = eisenstein_series_poly(4,prec) + A = eisenstein_series_poly(4, prec) elif e == 6: A = F6 elif e == 8: - A = eisenstein_series_poly(8,prec) + A = eisenstein_series_poly(8, prec) elif e == 10: - A = eisenstein_series_poly(10,prec) - else: # e == 14 - A = eisenstein_series_poly(14,prec) + A = eisenstein_series_poly(10, prec) + else: # e == 14 + A = eisenstein_series_poly(14, prec) - if A[0] == -1 : + if A[0] == -1: A = -A if n == 0: @@ -188,9 +186,9 @@ def victor_miller_basis(k, prec=10, cusp_only=False, var='q'): if cusp_only: ls = [Fmpz_poly(0)] + [A] * n else: - ls = [A] * (n+1) + ls = [A] * (n + 1) - for i in range(1,n+1): + for i in range(1, n + 1): ls[n-i] *= Fprod ls[i] *= Dprod ls[n-i]._unsafe_mutate_truncate(prec) @@ -203,22 +201,22 @@ def victor_miller_basis(k, prec=10, cusp_only=False, var='q'): P = PowerSeriesRing(ZZ, var) if cusp_only: - for i in range(1,n+1) : - for j in range(1, i) : + for i in range(1, n + 1): + for j in range(1, i): ls[j] = ls[j] - ls[j][i]*ls[i] - return Sequence([P(l.list()).add_bigoh(prec) for l in ls[1:]],cr=True) - else : - for i in range(1,n+1): - for j in range(i): - ls[j] = ls[j] - ls[j][i]*ls[i] + return Sequence([P(l.list()).add_bigoh(prec) for l in ls[1:]], cr=True) + + for i in range(1, n + 1): + for j in range(i): + ls[j] = ls[j] - ls[j][i] * ls[i] - return Sequence([P(l.list()).add_bigoh(prec) for l in ls], cr=True) + return Sequence([P(l.list()).add_bigoh(prec) for l in ls], cr=True) def _delta_poly(prec=10): """ - Return the q-expansion of Delta as a FLINT polynomial. Used internally by + Return the `q`-expansion of Delta as a FLINT polynomial. Used internally by the :func:`~delta_qexp` function. See the docstring of :func:`~delta_qexp` for more information. @@ -228,7 +226,7 @@ def _delta_poly(prec=10): OUTPUT: - the q-expansion of Delta to precision ``prec``, as a FLINT + the `q`-expansion of Delta to precision ``prec``, as a FLINT :class:`~sage.libs.flint.fmpz_poly.Fmpz_poly` object. EXAMPLES:: @@ -274,21 +272,21 @@ def _delta_poly(prec=10): def _delta_poly_modulo(N, prec=10): r""" - Return the q-expansion of `\Delta` modulo `N`. Used internally by + Return the `q`-expansion of `\Delta` modulo `N`. Used internally by the :func:`~delta_qexp` function. See the docstring of :func:`~delta_qexp` for more information. INPUT: - - `N` -- positive integer modulo which we want to compute `\Delta` + - ``N`` -- positive integer modulo which we want to compute `\Delta` - ``prec`` -- integer; the absolute precision of the output OUTPUT: - the polynomial of degree ``prec``-1 which is the truncation - of `\Delta` modulo `N`, as an element of the polynomial - ring in `q` over the integers modulo `N`. + the polynomial of degree ``prec``-1 which is the truncation + of `\Delta` modulo `N`, as an element of the polynomial + ring in `q` over the integers modulo `N`. EXAMPLES:: @@ -299,7 +297,7 @@ def _delta_poly_modulo(N, prec=10): 2*q^11 + 7*q^9 + 6*q^7 + 2*q^6 + 8*q^4 + 2*q^3 + 6*q^2 + q """ if prec <= 0: - raise ValueError( "prec must be positive" ) + raise ValueError("prec must be positive") v = [0] * prec # Let F = \sum_{n >= 0} (-1)^n (2n+1) q^(floor(n(n+1)/2)). @@ -326,23 +324,21 @@ def _delta_poly_modulo(N, prec=10): return f -def delta_qexp(prec=10, var='q', K=ZZ) : +def delta_qexp(prec=10, var='q', K=ZZ): r""" Return the `q`-expansion of the weight 12 cusp form `\Delta` as a power series with coefficients in the ring K (`= \ZZ` by default). INPUT: - - ``prec`` -- integer (default 10), the absolute precision of the output + - ``prec`` -- integer (default: 10); the absolute precision of the output (must be positive) - - ``var`` -- string (default: 'q'), variable name - - - ``K`` -- ring (default: `\ZZ`), base ring of answer + - ``var`` -- string (default: ``'q'``); variable name - OUTPUT: + - ``K`` -- ring (default: `\ZZ`); base ring of answer - a power series over K in the variable ``var`` + OUTPUT: a power series over K in the variable ``var`` ALGORITHM: diff --git a/src/sage/modular/modform/weight1.py b/src/sage/modular/modform/weight1.py index c2ce006decb..9aa75074676 100644 --- a/src/sage/modular/modform/weight1.py +++ b/src/sage/modular/modform/weight1.py @@ -20,6 +20,7 @@ from sage.modular.arithgroup.all import Gamma0, GammaH from sage.modular.arithgroup.arithgroup_generic import ArithmeticSubgroup + @cached_function def modular_ratio_space(chi): r""" @@ -27,7 +28,7 @@ def modular_ratio_space(chi): level N and character chi such that f * E is a holomorphic cusp form for every Eisenstein series E of weight 1 and character 1/chi. - Elements are returned as q-expansions up to precision R, where R is one + Elements are returned as `q`-expansions up to precision R, where R is one greater than the weight 3 Sturm bound. EXAMPLES:: @@ -80,7 +81,7 @@ def modular_ratio_space(chi): def modular_ratio_to_prec(chi, qexp, prec): r""" - Given a q-expansion of a modular ratio up to sufficient precision to + Given a `q`-expansion of a modular ratio up to sufficient precision to determine it uniquely, compute it to greater precision. EXAMPLES:: @@ -100,12 +101,13 @@ def modular_ratio_to_prec(chi, qexp, prec): fB_elt = C(fB, check=False) return fB_elt.qexp(prec) / B + @cached_function def hecke_stable_subspace(chi, aux_prime=ZZ(2)): r""" - Compute a q-expansion basis for S_1(chi). + Compute a `q`-expansion basis for `S_1(\chi)`. - Results are returned as q-expansions to a certain fixed (and fairly high) + Results are returned as `q`-expansions to a certain fixed (and fairly high) precision. If more precision is required this can be obtained with :func:`modular_ratio_to_prec`. @@ -187,6 +189,7 @@ def hecke_stable_subspace(chi, aux_prime=ZZ(2)): qexps = Sequence(A(x.list()).add_bigoh(R) for x in J.gens()) return qexps + @cached_function def dimension_wt1_cusp_forms(chi): r""" @@ -200,6 +203,7 @@ def dimension_wt1_cusp_forms(chi): """ return len(hecke_stable_subspace(chi)) + @cached_function def dimension_wt1_cusp_forms_gH(group): r""" diff --git a/src/sage/modular/modform_hecketriangle/abstract_ring.py b/src/sage/modular/modform_hecketriangle/abstract_ring.py index f1f0efad596..e62cdcb47af 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_ring.py +++ b/src/sage/modular/modform_hecketriangle/abstract_ring.py @@ -50,17 +50,15 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: `\Z`). + - ``base_ring`` -- the base_ring (default: `\Z`) - - ``red_hom`` -- If ``True`` then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the (Hecke) forms. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the (Hecke) forms. - OUTPUT: - - The corresponding abstract (Hecke) forms ring. + OUTPUT: the corresponding abstract (Hecke) forms ring EXAMPLES:: @@ -260,16 +258,17 @@ def _an_element_(self): def default_prec(self, prec=None): r""" Set the default precision ``prec`` for the Fourier expansion. - If ``prec=None`` (default) then the current default precision is returned instead. + If ``prec=None`` (default) then the current default precision is + returned instead. INPUT: - - ``prec`` -- An integer. + - ``prec`` -- integer - NOTE: + .. NOTE:: - This is also used as the default precision for the Fourier - expansion when evaluating forms. + This is also used as the default precision for the Fourier + expansion when evaluating forms. EXAMPLES:: @@ -408,14 +407,12 @@ def extend_type(self, analytic_type=None, ring=False): INPUT: - - ``analytic_type`` -- An ``AnalyticType`` or something which - coerces into it (default: ``None``). + - ``analytic_type`` -- an ``AnalyticType`` or something which + coerces into it (default: ``None``) - - ``ring`` -- Whether to extend to a graded ring (default: ``False``). - - OUTPUT: + - ``ring`` -- whether to extend to a graded ring (default: ``False``) - The new extended space. + OUTPUT: the new extended space EXAMPLES:: @@ -454,14 +451,13 @@ def reduce_type(self, analytic_type=None, degree=None): INPUT: - - ``analytic_type`` -- An ``AnalyticType`` or something which coerces into it (default: ``None``). + - ``analytic_type`` -- an ``AnalyticType`` or something which coerces + into it (default: ``None``) - - ``degree`` -- ``None`` (default) or the degree of the homogeneous component to which - ``self`` should be reduced. + - ``degree`` -- ``None`` (default) or the degree of the homogeneous + component to which ``self`` should be reduced - OUTPUT: - - The new reduced space. + OUTPUT: the new reduced space EXAMPLES:: @@ -645,7 +641,7 @@ def rat_field(self): def get_d(self, fix_d=False, d_num_prec=None): r""" - Return the parameter ``d`` of self either as a formal + Return the parameter ``d`` of ``self`` either as a formal parameter or as a numerical approximation with the specified precision (resp. an exact value in the arithmetic cases). @@ -654,18 +650,14 @@ def get_d(self, fix_d=False, d_num_prec=None): INPUT: - - ``fix_d`` -- If ``False`` (default) a formal parameter is - used for ``d``. - - If ``True`` then the numerical value of - ``d`` is used (or an exact value if the - group is arithmetic). Otherwise, the given - value is used for ``d``. + - ``fix_d`` -- if ``False`` (default) a formal parameter is + used for ``d``. If ``True`` then the numerical value of ``d`` is used + (or an exact value if the group is arithmetic). Otherwise, the given + value is used for ``d``. - - ``d_num_prec`` -- An integer. The numerical precision of - ``d``. Default: ``None``, in which case - the default numerical precision of - ``self.parent()`` is used. + - ``d_num_prec`` -- integer (default: ``None``); the numerical + precision of ``d``. By default, the default numerical precision of + ``self.parent()`` is used. OUTPUT: @@ -717,18 +709,18 @@ def get_q(self, prec=None, fix_d=False, d_num_prec=None): INPUT: - - ``prec`` -- An integer or ``None`` (default), namely the desired default - precision of the space of power series. If nothing is specified - the default precision of ``self`` is used. + - ``prec`` -- an integer or ``None`` (default), namely the desired + default precision of the space of power series. If nothing is + specified the default precision of ``self`` is used. - - ``fix_d`` -- If ``False`` (default) a formal parameter is used for ``d``. - If ``True`` then the numerical value of ``d`` is used - (resp. an exact value if the group is arithmetic). - Otherwise the given value is used for ``d``. + - ``fix_d`` -- if ``False`` (default) a formal parameter is used for + ``d``. If ``True`` then the numerical value of ``d`` is used (resp. + an exact value if the group is arithmetic). Otherwise the given value + is used for ``d``. - - ``d_num_prec`` -- The precision to be used if a numerical value for ``d`` is substituted. - Default: ``None`` in which case the default - numerical precision of ``self.parent()`` is used. + - ``d_num_prec`` -- the precision to be used if a numerical value for + ``d`` is substituted (default: ``None``), otherwise the default + numerical precision of ``self.parent()`` is used OUTPUT: @@ -1019,9 +1011,9 @@ def homogeneous_part(self, k, ep): INPUT: - - ``k`` -- An integer. + - ``k`` -- integer - - ``ep`` -- `+1` or `-1`. + - ``ep`` -- `+1` or `-1` EXAMPLES:: @@ -1726,7 +1718,6 @@ def E2(self): It is in particular also a generator of the graded ring of ``self`` and the polynomial variable ``z`` exactly corresponds to ``E2``. - EXAMPLES:: sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, QuasiModularFormsRing, CuspFormsRing @@ -1790,11 +1781,10 @@ def EisensteinSeries(self, k=None): INPUT: - - ``k`` -- A non-negative even integer, namely the weight. - - If ``k=None`` (default) then the weight of ``self`` - is choosen if ``self`` is homogeneous and the - weight is possible, otherwise ``k=0`` is set. + - ``k`` -- a nonnegative even integer, namely the weight. + If ``k`` is ``None`` (default) then the weight of ``self`` is chosen if + ``self`` is homogeneous and the weight is possible, otherwise ``k`` + is set to `0`. OUTPUT: @@ -1893,7 +1883,7 @@ def EisensteinSeries(self, k=None): raise TypeError(None) k = 2*ZZ(k/2) except TypeError: - raise TypeError("k={} must be a non-negative even integer!".format(k)) + raise TypeError("k={} must be a nonnegative even integer!".format(k)) # The case n=infinity is special (there are 2 cusps) # Until we/I get confirmation what is what sort of Eisenstein series diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index 719d8847f31..89c86ca41c2 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -22,15 +22,16 @@ from sage.rings.infinity import infinity from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.rings.laurent_series_ring import is_LaurentSeriesRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing -from sage.rings.power_series_ring import is_PowerSeriesRing +from sage.rings.laurent_series_ring import LaurentSeriesRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general +from sage.rings.power_series_ring import PowerSeriesRing_generic from sage.rings.rational_field import QQ from sage.structure.element import parent from .abstract_ring import FormsRing_abstract lazy_import('sage.rings.imaginary_unit', 'I') +lazy_import('sage.rings.lazy_series_ring', ('LazyLaurentSeriesRing', 'LazyPowerSeriesRing')) lazy_import('sage.rings.qqbar', 'QQbar') @@ -51,19 +52,16 @@ def __init__(self, group, base_ring, k, ep, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``k`` -- The weight (default: `0`) + - ``k`` -- the weight (default: `0`) - - ``ep`` -- The epsilon (default: ``None``). - If ``None``, then k*(n-2) has to be divisible by `2` and - ``ep=(-1)^(k*(n-2)/2)`` is used. + - ``ep`` -- the epsilon (default: ``None``); if ``None``, then `k(n-2)` + has to be divisible by `2` and ``ep=(-1)^(k*(n-2)/2)`` is used - - ``base_ring`` -- The base_ring (default: `\Z`). + - ``base_ring`` -- the base_ring (default: `\Z`) - OUTPUT: - - The corresponding abstract (Hecke) forms space. + OUTPUT: the corresponding abstract (Hecke) forms space EXAMPLES:: @@ -257,8 +255,9 @@ def _element_constructor_(self, el): # can be changed in construct_form # resp. construct_quasi_form)) P = parent(el) - if is_LaurentSeriesRing(P) or is_PowerSeriesRing(P): - if (self.is_modular()): + if isinstance(P, (LaurentSeriesRing, PowerSeriesRing_generic, + LazyLaurentSeriesRing, LazyPowerSeriesRing)): + if self.is_modular(): return self.construct_form(el) else: return self.construct_quasi_form(el) @@ -380,7 +379,7 @@ def is_ambient(self): def ambient_space(self): r""" - Return the ambient space of self. + Return the ambient space of ``self``. EXAMPLES:: @@ -401,7 +400,7 @@ def ambient_space(self): def module(self): r""" - Return the module associated to self. + Return the module associated to ``self``. EXAMPLES:: @@ -420,7 +419,7 @@ def module(self): def ambient_module(self): r""" - Return the module associated to the ambient space of self. + Return the module associated to the ambient space of ``self``. EXAMPLES:: @@ -544,11 +543,9 @@ def element_from_coordinates(self, vec): INPUT: - - ``vec`` -- A coordinate vector with respect to ``self.gens()``. - - OUTPUT: + - ``vec`` -- a coordinate vector with respect to ``self.gens()`` - An element of ``self`` corresponding to the coordinate vector ``vec``. + OUTPUT: an element of ``self`` corresponding to the coordinate vector ``vec`` EXAMPLES:: @@ -588,11 +585,9 @@ def element_from_ambient_coordinates(self, vec): INPUT: - - ``vec`` -- An element of ``self.module()`` or ``self.ambient_module()``. + - ``vec`` -- an element of ``self.module()`` or ``self.ambient_module()`` - OUTPUT: - - An element of ``self`` corresponding to ``vec``. + OUTPUT: an element of ``self`` corresponding to ``vec`` EXAMPLES:: @@ -619,7 +614,7 @@ def element_from_ambient_coordinates(self, vec): def homogeneous_part(self, k, ep): r""" Since ``self`` already is a homogeneous component return ``self`` - unless the degree differs in which case a :class:`ValueError` is raised. + unless the degree differs in which case a :exc:`ValueError` is raised. EXAMPLES:: @@ -697,7 +692,7 @@ def weight_parameters(self): # l2 = num % ZZ(2) # l1 = ((num-l2)/ZZ(2)).numerator() # TODO: The correct generalization seems (l1,l2) = (0,num) - l2 = ZZ(0) + l2 = ZZ.zero() l1 = num else: l2 = num % n @@ -714,9 +709,9 @@ def aut_factor(self, gamma, t): INPUT: - - ``gamma`` -- An element of the group of ``self``. + - ``gamma`` -- an element of the group of ``self`` - - ``t`` -- An element of the upper half plane. + - ``t`` -- an element of the upper half plane EXAMPLES:: @@ -769,7 +764,7 @@ def aut_factor(self, gamma, t): return aut_f @cached_method - def F_simple(self, order_1=ZZ(0)): + def F_simple(self, order_1=ZZ.zero()): r""" Return a (the most) simple normalized element of ``self`` corresponding to the weight parameters ``l1=self._l1`` and @@ -781,9 +776,9 @@ def F_simple(self, order_1=ZZ(0)): INPUT: - - ``order_1`` -- An integer (default: 0) denoting the desired order at - ``-1`` in the case ``n = infinity``. - If ``n != infinity`` the parameter is ignored. + - ``order_1`` -- an integer (default: 0) denoting the desired order at + ``-1`` in the case ``n = infinity``. If ``n != infinity`` the + parameter is ignored. EXAMPLES:: @@ -836,9 +831,9 @@ def F_simple(self, order_1=ZZ(0)): return new_space(rat) - def Faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): + def Faber_pol(self, m, order_1=ZZ.zero(), fix_d=False, d_num_prec=None): r""" - Return the ``m``'th Faber polynomial of ``self``. + Return the ``m``-th Faber polynomial of ``self``. Namely a polynomial ``P(q)`` such that ``P(J_inv)*F_simple(order_1)`` has a Fourier expansion of the form ``q^m + O(q^(order_inf + 1))``. @@ -853,23 +848,21 @@ def Faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): INPUT: - - ``m`` -- An integer ``m <= order_inf = self._l1 - order_1``. + - ``m`` -- an integer ``m <= order_inf = self._l1 - order_1`` - - ``order_1`` -- The order at ``-1`` of F_simple (default: 0). - This parameter is ignored if ``n != infinity``. + - ``order_1`` -- the order at ``-1`` of F_simple (default: 0); + this parameter is ignored if ``n != infinity`` - - ``fix_d`` -- If ``False`` (default) a formal parameter is used for ``d``. - If ``True`` then the numerical value of ``d`` is used - (resp. an exact value if the group is arithmetic). - Otherwise the given value is used for ``d``. + - ``fix_d`` -- if ``False`` (default) a formal parameter is used for + ``d``. If ``True`` then the numerical value of ``d`` is used (resp. + an exact value if the group is arithmetic). Otherwise the given + value is used for ``d``. - - ``d_num_prec`` -- The precision to be used if a numerical value for ``d`` is substituted. - Default: ``None`` in which case the default - numerical precision of ``self.parent()`` is used. - - OUTPUT: + - ``d_num_prec`` -- the precision to be used if a numerical value for + ``d`` is substituted (default: ``None``), otherwise the default + numerical precision of ``self.parent()`` is used - The corresponding Faber polynomial ``P(q)``. + OUTPUT: the corresponding Faber polynomial ``P(q)`` EXAMPLES:: @@ -986,11 +979,11 @@ def Faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): return fab_pol.polynomial() # very similar to Faber_pol: faber_pol(q)=Faber_pol(d*q) - def faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): + def faber_pol(self, m, order_1=ZZ.zero(), fix_d=False, d_num_prec=None): r""" If ``n=infinity`` a non-trivial order of ``-1`` can be specified through the parameter ``order_1`` (default: 0). Otherwise it is ignored. - Return the `m`'th Faber polynomial of ``self`` + Return the `m`-th Faber polynomial of ``self`` with a different normalization based on ``j_inv`` instead of ``J_inv``. @@ -1006,23 +999,21 @@ def faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): INPUT: - - ``m`` -- An integer ``m <= self._l1 - order_1``. + - ``m`` -- integer; ``m <= self._l1 - order_1`` - - ``order_1`` -- The order at ``-1`` of ``F_simple`` (default: 0). - This parameter is ignored if ``n != infinity``. + - ``order_1`` -- the order at ``-1`` of ``F_simple`` (default: 0); + this parameter is ignored if ``n != infinity`` - - ``fix_d`` -- If ``False`` (default) a formal parameter is used for ``d``. - If ``True`` then the numerical value of ``d`` is used - (resp. an exact value if the group is arithmetic). - Otherwise the given value is used for ``d``. + - ``fix_d`` -- if ``False`` (default) a formal parameter is used for + ``d``. If ``True`` then the numerical value of ``d`` is used (resp. + an exact value if the group is arithmetic). Otherwise the given value + is used for ``d``. - - ``d_num_prec`` -- The precision to be used if a numerical value for ``d`` is substituted. - Default: ``None`` in which case the default - numerical precision of ``self.parent()`` is used. + - ``d_num_prec`` -- the precision to be used if a numerical value for + ``d`` is substituted (default: ``None``), otherwise the default + numerical precision of ``self.parent()`` is used - OUTPUT: - - The corresponding Faber polynomial ``p(q)``. + OUTPUT: the corresponding Faber polynomial ``p(q)`` EXAMPLES:: @@ -1127,9 +1118,9 @@ def faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): return fab_pol.polynomial() - def F_basis_pol(self, m, order_1=ZZ(0)): + def F_basis_pol(self, m, order_1=ZZ.zero()): r""" - Returns a polynomial corresponding to the basis element of + Return a polynomial corresponding to the basis element of the corresponding space of weakly holomorphic forms of the same degree as ``self``. The basis element is determined by the property that the Fourier expansion is of the form @@ -1140,10 +1131,10 @@ def F_basis_pol(self, m, order_1=ZZ(0)): INPUT: - - ``m`` -- An integer ``m <= self._l1``. + - ``m`` -- integer; ``m <= self._l1`` - - ``order_1`` -- The order at ``-1`` of ``F_simple`` (default: 0). - This parameter is ignored if ``n != infinity``. + - ``order_1`` -- the order at ``-1`` of ``F_simple`` (default: 0); + this parameter is ignored if ``n != infinity`` OUTPUT: @@ -1229,9 +1220,9 @@ def F_basis_pol(self, m, order_1=ZZ(0)): return rat - def F_basis(self, m, order_1=ZZ(0)): + def F_basis(self, m, order_1=ZZ.zero()): r""" - Returns a weakly holomorphic element of ``self`` + Return a weakly holomorphic element of ``self`` (extended if necessarily) determined by the property that the Fourier expansion is of the form is of the form ``q^m + O(q^(order_inf + 1))``, where ``order_inf = self._l1 - order_1``. @@ -1245,10 +1236,10 @@ def F_basis(self, m, order_1=ZZ(0)): INPUT: - - ``m`` -- An integer ``m <= self._l1``. + - ``m`` -- integer; ``m <= self._l1`` - - ``order_1`` -- The order at ``-1`` of ``F_simple`` (default: 0). - This parameter is ignored if ``n != infinity``. + - ``order_1`` -- the order at ``-1`` of ``F_simple`` (default: 0); + this parameter is ignored if ``n != infinity`` OUTPUT: @@ -1357,11 +1348,11 @@ def _canonical_min_exp(self, min_exp, order_1): order_1 = max(order_1, 0) if (self.hecke_n() != infinity): - order_1 = ZZ(0) + order_1 = ZZ.zero() return (min_exp, order_1) - def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0)): + def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()): r""" Return a basis in ``self`` of the subspace of (quasi) weakly holomorphic forms which satisfy the specified properties on @@ -1369,25 +1360,20 @@ def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0)): INPUT: - - ``r`` -- An integer or ``None`` (default), indicating - the desired power of ``E2`` If ``r=None`` - then all possible powers (``r``) are - choosen. + - ``r`` -- an integer or ``None`` (default), indicating the desired + power of ``E2``; if ``r`` is ``None`` then all possible powers + (``r``) are chosen - - ``min_exp`` -- An integer giving a lower bound for the - first non-trivial Fourier coefficient of the - generators (default: 0). + - ``min_exp`` -- integer (default: 0); a lower bound for the first + non-trivial Fourier coefficient of the generators - - ``max_exp`` -- An integer or ``infinity`` (default) giving - an upper bound for the first non-trivial - Fourier coefficient of the generators. If - ``max_exp==infinity`` then no upper bound is - assumed. + - ``max_exp`` -- integer or ``infinity`` (default) giving an upper + bound for the first non-trivial Fourier coefficient of the + generators. If ``max_exp==infinity`` then no upper bound is assumed. - - ``order_1`` -- A lower bound for the order at ``-1`` of all - quasi parts of the basis elements (default: - 0). If ``n!=infinity`` this parameter is - ignored. + - ``order_1`` -- a lower bound for the order at ``-1`` of all quasi + parts of the basis elements (default: 0). If ``n!=infinity`` this + parameter is ignored. OUTPUT: @@ -1499,14 +1485,14 @@ def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0)): max_numerator_weight = self._weight - 4*n/(n-2)*min_exp + 4 # If r is not specified we gather all generators for all possible r's - if (r is None): + if r is None: gens = [] - for rnew in range(ZZ(0), QQ(max_numerator_weight/ZZ(2)).floor() + 1): + for rnew in range(QQ(max_numerator_weight/ZZ(2)).floor() + 1): gens += self.quasi_part_gens(r=rnew, min_exp=min_exp, max_exp=max_exp, order_1=order_1) return gens r = ZZ(r) - if (r < 0 or 2*r > max_numerator_weight): + if r < 0 or 2*r > max_numerator_weight: return [] E2 = self.E2() @@ -1526,7 +1512,7 @@ def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0)): return gens - def quasi_part_dimension(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0)): + def quasi_part_dimension(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()): r""" Return the dimension of the subspace of ``self`` generated by ``self.quasi_part_gens(r, min_exp, max_exp, order_1)``. @@ -1590,10 +1576,10 @@ def quasi_part_dimension(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0 (min_exp, order_1) = self._canonical_min_exp(min_exp, order_1) # For modular forms spaces the quasi parts are all zero except for r=0 - if (self.is_modular()): - r = ZZ(0) - if (r != 0): - return ZZ(0) + if self.is_modular(): + r = ZZ.zero() + if r != 0: + return ZZ.zero() # The lower bounds on the powers of f_inf and E4 determine # how large powers of E2 we can fit in... @@ -1604,12 +1590,12 @@ def quasi_part_dimension(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0 max_numerator_weight = self._weight - 4*n/(n-2)*min_exp + 4 # If r is not specified we calculate the total dimension over all possible r's - if (r is None): - return sum([self.quasi_part_dimension(r=rnew, min_exp=min_exp, max_exp=max_exp, order_1=order_1) for rnew in range(ZZ(0), QQ(max_numerator_weight/ZZ(2)).floor() + 1)]) + if r is None: + return sum([self.quasi_part_dimension(r=rnew, min_exp=min_exp, max_exp=max_exp, order_1=order_1) for rnew in range(QQ(max_numerator_weight/ZZ(2)).floor() + 1)]) r = ZZ(r) if (r < 0 or 2*r > max_numerator_weight): - return ZZ(0) + return ZZ.zero() k = self._weight - QQ(2*r) ep = self._ep * (-1)**r @@ -1625,15 +1611,15 @@ def quasi_part_dimension(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ(0 if (max_exp == infinity): max_exp = order_inf elif (max_exp < min_exp): - return ZZ(0) + return ZZ.zero() else: max_exp = min(ZZ(max_exp), order_inf) - return max(ZZ(0), max_exp - min_exp + 1) + return max(ZZ.zero(), max_exp - min_exp + 1) - def construct_form(self, laurent_series, order_1=ZZ(0), check=True, rationalize=False): + def construct_form(self, laurent_series, order_1=ZZ.zero(), check=True, rationalize=False): r""" - Tries to construct an element of self with the given Fourier + Try to construct an element of ``self`` with the given Fourier expansion. The assumption is made that the specified Fourier expansion corresponds to a weakly holomorphic modular form. @@ -1642,21 +1628,21 @@ def construct_form(self, laurent_series, order_1=ZZ(0), check=True, rationalize= INPUT: - - ``laurent_series`` -- A Laurent or Power series. + - ``laurent_series`` -- a Laurent or Power series - - ``order_1`` -- A lower bound for the order at ``-1`` of the form (default: 0). - If ``n!=infinity`` this parameter is ignored. + - ``order_1`` -- a lower bound for the order at ``-1`` of the form + (default: 0). If ``n!=infinity`` this parameter is ignored. - - ``check`` -- If ``True`` (default) then the series expansion of the constructed - form is compared against the given series. + - ``check`` -- if ``True`` (default) then the series expansion of the + constructed form is compared against the given series - - ``rationalize`` -- If ``True`` (default: ``False``) then the series is - `rationalized` beforehand. Note that in non-exact or non-arithmetic - cases this is experimental and extremely unreliable! + - ``rationalize`` -- if ``True`` (default: ``False``) then the series + is "rationalized" beforehand. Note that in non-exact or + non-arithmetic cases this is experimental and extremely unreliable! OUTPUT: - If possible: An element of self with the same initial + If possible: An element of ``self`` with the same initial Fourier expansion as ``laurent_series``. Note: For modular spaces it is also possible to call @@ -1721,7 +1707,7 @@ def construct_form(self, laurent_series, order_1=ZZ(0), check=True, rationalize= """ base_ring = laurent_series.base_ring() - if is_PolynomialRing(base_ring.base()): + if isinstance(base_ring.base(), PolynomialRing_general): if not (self.coeff_ring().has_coerce_map_from(base_ring)): raise ValueError("The Laurent coefficients don't coerce into the coefficient ring of self!") elif rationalize: @@ -1755,7 +1741,7 @@ def construct_form(self, laurent_series, order_1=ZZ(0), check=True, rationalize= return el @cached_method - def _quasi_form_matrix(self, min_exp=0, order_1=ZZ(0), incr_prec_by=0): + def _quasi_form_matrix(self, min_exp=0, order_1=ZZ.zero(), incr_prec_by=0): r""" Return a base change matrix which transforms coordinate vectors with respect to a certain basis into a vector corresponding to @@ -1767,19 +1753,18 @@ def _quasi_form_matrix(self, min_exp=0, order_1=ZZ(0), incr_prec_by=0): INPUT: - - ``min_exp`` -- An integer (default: 0), namely the lower bound for the - order at infinity resp. the exponent of the Laurent series. - - - ``order_1`` -- A lower bound for the order at ``-1`` of all quasi parts of the - subspace (default: 0). If ``n!=infinity`` this parameter is ignored. + - ``min_exp`` -- integer (default: 0), namely the lower bound for the + order at infinity resp. the exponent of the Laurent series - - ``incr_prec_by`` -- An integer (default: 0) which specifies how - much the precision should be increased compared to - the size of the corresponding basis. + - ``order_1`` -- a lower bound for the order at ``-1`` of all quasi + parts of the subspace (default: 0). If ``n!=infinity`` this parameter + is ignored. - OUTPUT: + - ``incr_prec_by`` -- integer (default: 0) which specifies how much the + precision should be increased compared to the size of the + corresponding basis - The corresponding base change matrix. + OUTPUT: the corresponding base change matrix EXAMPLES:: @@ -1866,7 +1851,7 @@ def _quasi_form_matrix(self, min_exp=0, order_1=ZZ(0), incr_prec_by=0): return A - def required_laurent_prec(self, min_exp=0, order_1=ZZ(0)): + def required_laurent_prec(self, min_exp=0, order_1=ZZ.zero()): r""" Return an upper bound for the required precision for Laurent series to uniquely determine a corresponding (quasi) form in ``self`` with the given @@ -1875,15 +1860,15 @@ def required_laurent_prec(self, min_exp=0, order_1=ZZ(0)): .. NOTE:: For ``n=infinity`` only the holomorphic case (``min_exp >= 0``) - is supported (in particular a non-negative order at ``-1`` is assumed). + is supported (in particular a nonnegative order at ``-1`` is assumed). INPUT: - - ``min_exp`` -- An integer (default: 0), namely the lower bound for the - order at infinity resp. the exponent of the Laurent series. + - ``min_exp`` -- integer (default: 0); namely the lower bound for the + order at infinity resp. the exponent of the Laurent series - - ``order_1`` -- A lower bound for the order at ``-1`` for all quasi parts - (default: 0). If ``n!=infinity`` this parameter is ignored. + - ``order_1`` -- a lower bound for the order at ``-1`` for all quasi + parts (default: 0). If ``n!=infinity`` this parameter is ignored. OUTPUT: @@ -1913,9 +1898,9 @@ def required_laurent_prec(self, min_exp=0, order_1=ZZ(0)): return self._quasi_form_matrix(min_exp=min_exp, order_1=order_1).dimensions()[0] + min_exp - def construct_quasi_form(self, laurent_series, order_1=ZZ(0), check=True, rationalize=False): + def construct_quasi_form(self, laurent_series, order_1=ZZ.zero(), check=True, rationalize=False): r""" - Try to construct an element of self with the given Fourier + Try to construct an element of ``self`` with the given Fourier expansion. The assumption is made that the specified Fourier expansion corresponds to a weakly holomorphic quasi modular form. @@ -1924,21 +1909,22 @@ def construct_quasi_form(self, laurent_series, order_1=ZZ(0), check=True, ration INPUT: - - ``laurent_series`` -- A Laurent or Power series. + - ``laurent_series`` -- a Laurent or Power series - - ``order_1`` -- A lower bound for the order at ``-1`` for all quasi parts of the - form (default: 0). If ``n!=infinity`` this parameter is ignored. + - ``order_1`` -- a lower bound for the order at ``-1`` for all quasi + parts of the form (default: 0). If ``n!=infinity`` this parameter is + ignored. - - ``check`` -- If ``True`` (default) then the series expansion of the constructed - form is compared against the given (rationalized) series. + - ``check`` -- if ``True`` (default) then the series expansion of the + constructed form is compared against the given (rationalized) series. - - ``rationalize`` -- If ``True`` (default: ``False``) then the series is - `rationalized` beforehand. Note that in non-exact or non-arithmetic - cases this is experimental and extremely unreliable! + - ``rationalize`` -- if ``True`` (default: ``False``) then the series + is "rationalized" beforehand. Note that in non-exact or + non-arithmetic cases this is experimental and extremely unreliable! OUTPUT: - If possible: An element of self with the same initial + If possible: An element of ``self`` with the same initial Fourier expansion as ``laurent_series``. Note: For non modular spaces it is also possible to call @@ -2015,7 +2001,7 @@ def construct_quasi_form(self, laurent_series, order_1=ZZ(0), check=True, ration """ base_ring = laurent_series.base_ring() - if is_PolynomialRing(base_ring.base()): + if isinstance(base_ring.base(), PolynomialRing_general): if not (self.coeff_ring().has_coerce_map_from(base_ring)): raise ValueError("The Laurent coefficients don't coerce into the coefficient ring of self!") elif rationalize: @@ -2072,7 +2058,7 @@ def construct_quasi_form(self, laurent_series, order_1=ZZ(0), check=True, ration return el @cached_method - def q_basis(self, m=None, min_exp=0, order_1=ZZ(0)): + def q_basis(self, m=None, min_exp=0, order_1=ZZ.zero()): r""" Try to return a (basis) element of ``self`` with a Laurent series of the form ``q^m + O(q^N)``, where ``N=self.required_laurent_prec(min_exp)``. @@ -2081,14 +2067,17 @@ def q_basis(self, m=None, min_exp=0, order_1=ZZ(0)): INPUT: - - ``m`` -- An integer, indicating the desired initial Laurent exponent of the element. - If ``m==None`` (default) then the whole basis is returned. + - ``m`` -- integer, indicating the desired initial Laurent exponent + of the element. If ``m==None`` (default) then the whole basis is + returned. - - ``min_exp`` -- An integer, indicating the minimal Laurent exponent (for each quasi part) - of the subspace of ``self`` which should be considered (default: 0). + - ``min_exp`` -- integer (default: 0); the minimal Laurent exponent + (for each quasi part) of the subspace of ``self`` which should be + considered - - ``order_1`` -- A lower bound for the order at ``-1`` of all quasi parts of the subspace - (default: 0). If ``n!=infinity`` this parameter is ignored. + - ``order_1`` -- a lower bound for the order at ``-1`` of all quasi + parts of the subspace (default: 0). If ``n!=infinity`` this parameter + is ignored. OUTPUT: @@ -2190,35 +2179,33 @@ def rationalize_series(self, laurent_series, coeff_bound=1e-10, denom_factor=ZZ( INPUT: - - ``laurent_series`` -- A Laurent series. If the Laurent coefficients already - coerce into ``self.coeff_ring()`` with a formal parameter - then the Laurent series is returned as is. + - ``laurent_series`` -- a Laurent series. If the Laurent coefficients + already coerce into ``self.coeff_ring()`` with a formal parameter + then the Laurent series is returned as is. - Otherwise it is assumed that the series is normalized - in the sense that the first non-trivial coefficient - is a power of ``d`` (e.g. ``1``). + Otherwise it is assumed that the series is normalized in the sense + that the first non-trivial coefficient is a power of ``d`` (e.g. + ``1``). - - ``coeff_bound`` -- Either ``None`` resp. ``0`` or a positive real number - (default: ``1e-10``). If specified ``coeff_bound`` - gives a lower bound for the size of the initial Laurent - coefficients. If a coefficient is smaller it is - assumed to be zero. + - ``coeff_bound`` -- either ``None`` resp. ``0`` or a positive real + number (default: ``1e-10``). If specified ``coeff_bound`` gives a + lower bound for the size of the initial Laurent coefficients. If a + coefficient is smaller it is assumed to be zero. - For calculations with very small coefficients (less than - ``1e-10``) ``coeff_bound`` should be set to something - even smaller or just ``0``. + For calculations with very small coefficients (less than ``1e-10``) + ``coeff_bound`` should be set to something even smaller or just ``0``. - Non-exact calculations often produce non-zero - coefficients which are supposed to be zero. In those - cases this parameter helps a lot. + Non-exact calculations often produce nonzero coefficients which are + supposed to be zero. In those cases this parameter helps a lot. - - ``denom_factor`` -- An integer (default: 1) whose factor might occur in - the denominator of the given Laurent coefficients - (in addition to naturally occurring factors). + - ``denom_factor`` -- integer (default: 1) whose factor might occur in + the denominator of the given Laurent coefficients (in addition to + naturally occurring factors). OUTPUT: - A Laurent series over ``self.coeff_ring()`` corresponding to the given Laurent series. + A Laurent series over ``self.coeff_ring()`` corresponding to the given + Laurent series. EXAMPLES:: @@ -2282,7 +2269,7 @@ def rationalize_series(self, laurent_series, coeff_bound=1e-10, denom_factor=ZZ( # If the coefficients already coerce to our coefficient ring # and are in polynomial form we simply return the Laurent series - if (is_PolynomialRing(base_ring.base())): + if (isinstance(base_ring.base(), PolynomialRing_general)): if (self.coeff_ring().has_coerce_map_from(base_ring)): return laurent_series else: @@ -2380,10 +2367,9 @@ def _an_element_(self): sage: el O(q^5) """ - # this seems ok, so might as well leave it as is for everything - return self(ZZ(0)) - #return self.F_simple() + return self(ZZ.zero()) + # return self.F_simple() @cached_method def dimension(self): @@ -2449,7 +2435,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` EXAMPLES:: @@ -2482,7 +2468,7 @@ def ambient_coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` EXAMPLES:: @@ -2525,7 +2511,7 @@ def gens(self): def gen(self, k=0): r""" - Return the ``k``'th basis element of ``self`` + Return the ``k``-th basis element of ``self`` if possible (default: ``k=0``). EXAMPLES:: diff --git a/src/sage/modular/modform_hecketriangle/analytic_type.py b/src/sage/modular/modform_hecketriangle/analytic_type.py index d04d42c91f1..32a2123d974 100644 --- a/src/sage/modular/modform_hecketriangle/analytic_type.py +++ b/src/sage/modular/modform_hecketriangle/analytic_type.py @@ -205,12 +205,10 @@ def reduce_to(self, reduce_type): INPUT: - - ``reduce_type`` -- an analytic type or something which is + - ``reduce_type`` -- an analytic type or something which is convertible to an analytic type - OUTPUT: - - The new reduced analytic type. + OUTPUT: the new reduced analytic type EXAMPLES:: @@ -235,12 +233,10 @@ def extend_by(self, extend_type): INPUT: - - ``extend_type`` -- an analytic type or something which is + - ``extend_type`` -- an analytic type or something which is convertible to an analytic type - OUTPUT: - - The new extended analytic type. + OUTPUT: the new extended analytic type EXAMPLES:: @@ -293,16 +289,16 @@ class AnalyticType(FiniteLatticePoset): The basic ``analytic properties`` are: - - ``quasi`` -- Whether the element is quasi modular (and not modular) - or modular. - - ``mero`` -- ``meromorphic``: If the element is meromorphic - and meromorphic at infinity. - - ``weak`` -- ``weakly holomorphic``: If the element is holomorphic - and meromorphic at infinity. - - ``holo`` -- ``holomorphic``: If the element is holomorphic and - holomorphic at infinity. - - ``cusp`` -- ``cuspidal``: If the element additionally has a positive - order at infinity. + - ``quasi`` -- whether the element is quasi modular (and not modular) + or modular. + - ``mero`` -- ``meromorphic`` -- if the element is meromorphic + and meromorphic at infinity + - ``weak`` -- ``weakly holomorphic`` -- if the element is holomorphic + and meromorphic at infinity + - ``holo`` -- ``holomorphic`` -- if the element is holomorphic and + holomorphic at infinity + - ``cusp`` -- ``cuspidal`` -- if the element additionally has a positive + order at infinity The ``zero`` elements/property have no analytic properties (or only ``quasi``). @@ -494,12 +490,9 @@ def _element_constructor_(self, element): INPUT: - - ``element`` -- Either something which coerces in the - ``FiniteLatticePoset`` of ``self`` or - a string or a list of strings of basic - properties that should be contained in - the new element. - + - ``element`` -- either something which coerces in the + ``FiniteLatticePoset`` of ``self`` or a string or a list of strings + of basic properties that should be contained in the new element OUTPUT: diff --git a/src/sage/modular/modform_hecketriangle/constructor.py b/src/sage/modular/modform_hecketriangle/constructor.py index 309a024c43a..e3525879e6e 100644 --- a/src/sage/modular/modform_hecketriangle/constructor.py +++ b/src/sage/modular/modform_hecketriangle/constructor.py @@ -42,37 +42,36 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): INPUT: - - ``f`` -- A rational function in ``x,y,z,d`` over ``base_ring``. + - ``f`` -- a rational function in ``x,y,z,d`` over ``base_ring`` - - ``n`` -- An integer greater or equal to `3` corresponding - to the ``HeckeTriangleGroup`` with that parameter (default: `3`). + - ``n`` -- integer greater or equal to `3` corresponding + to the ``HeckeTriangleGroup`` with that parameter (default: `3`) - - ``base_ring`` -- The base ring of the corresponding forms ring, resp. - polynomial ring (default: ``ZZ``). + - ``base_ring`` -- the base ring of the corresponding forms ring, resp. + polynomial ring (default: ``ZZ``) OUTPUT: A tuple ``(elem, homo, k, ep, analytic_type)`` describing the basic analytic properties of `f` (with the interpretation indicated above). - - ``elem`` -- ``True`` if `f` has a homogeneous denominator. + - ``elem`` -- ``True`` if `f` has a homogeneous denominator - - ``homo`` -- ``True`` if `f` also has a homogeneous numerator. + - ``homo`` -- ``True`` if `f` also has a homogeneous numerator - ``k`` -- ``None`` if `f` is not homogeneous, otherwise - the weight of `f` (which is the first component of its degree). + the weight of `f` (which is the first component of its degree) - ``ep`` -- ``None`` if `f` is not homogeneous, otherwise the multiplier of `f` (which is the second component of its degree) - - ``analytic_type`` -- The :class:`AnalyticType` of `f`. + - ``analytic_type`` -- the :class:`AnalyticType` of `f` - For the zero function the degree `(0, 1)` is choosen. + For the zero function the degree `(0, 1)` is chosen. This function is (heavily) used to determine the type of elements and to check if the element really is contained in its parent. - EXAMPLES:: sage: from sage.modular.modform_hecketriangle.constructor import rational_type @@ -118,11 +117,11 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): analytic_type = AT(["quasi", "mero"]) - R = PolynomialRing(base_ring,'x,y,z,d') + R = PolynomialRing(base_ring, 'x,y,z,d') F = FractionField(R) - (x,y,z,d) = R.gens() + x, y, z, d = R.gens() R2 = PolynomialRing(PolynomialRing(base_ring, 'd'), 'x,y,z') - dhom = R.hom( R2.gens() + (R2.base().gen(),), R2) + dhom = R.hom(R2.gens() + (R2.base().gen(),), R2) f = F(f) @@ -132,12 +131,12 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): ep_denom = {ZZ.one() - 2*((sum([g.exponents()[0][m] for m in [1, 2]])) % 2) for g in dhom(denom).monomials()} if (n == infinity): - hom_num = R( num.subs(x=x**4, y=y**2, z=z**2) ) - hom_denom = R( denom.subs(x=x**4, y=y**2, z=z**2) ) + hom_num = R(num.subs(x=x**4, y=y**2, z=z**2)) + hom_denom = R(denom.subs(x=x**4, y=y**2, z=z**2)) else: n = ZZ(n) - hom_num = R( num.subs(x=x**4, y=y**(2*n), z=z**(2*(n-2))) ) - hom_denom = R( denom.subs(x=x**4, y=y**(2*n), z=z**(2*(n-2))) ) + hom_num = R(num.subs(x=x**4, y=y**(2*n), z=z**(2*(n-2)))) + hom_denom = R(denom.subs(x=x**4, y=y**(2*n), z=z**(2*(n-2)))) # Determine whether the denominator of f is homogeneous if (len(ep_denom) == 1 and dhom(hom_denom).is_homogeneous()): @@ -147,9 +146,9 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): return (False, False, None, None, None) # Determine whether f is homogeneous - if (len(ep_num) == 1 and dhom(hom_num).is_homogeneous()): + if len(ep_num) == 1 and dhom(hom_num).is_homogeneous(): homo = True - if (n == infinity): + if n == infinity: weight = (dhom(hom_num).degree() - dhom(hom_denom).degree()) else: weight = (dhom(hom_num).degree() - dhom(hom_denom).degree()) / (n-2) @@ -161,17 +160,17 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): ep = None # Note that we intentionally leave out the d-factor! - if (n == infinity): + if n == infinity: finf_pol = (x-y**2) else: finf_pol = x**n-y**2 # Determine whether f is modular - if not ( (num.degree(z) > 0) or (denom.degree(z) > 0) ): + if not (num.degree(z) > 0 or denom.degree(z) > 0): analytic_type = analytic_type.reduce_to("mero") # Determine whether f is holomorphic - if (dhom(denom).is_constant()): + if dhom(denom).is_constant(): analytic_type = analytic_type.reduce_to(["quasi", "holo"]) # Determine whether f is cuspidal in the sense that finf divides it... # Bug in singular: finf_pol.divides(1.0) fails over RR @@ -181,7 +180,7 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): else: # -> Because of a bug with singular in some cases try: - while (finf_pol.divides(denom)): + while finf_pol.divides(denom): # a simple "denom /= finf_pol" is strangely not enough for non-exact rings # and dividing would/may result with an element of the quotient ring of the polynomial ring denom = denom.quo_rem(finf_pol)[0] @@ -209,16 +208,16 @@ def FormsSpace(analytic_type, group=3, base_ring=ZZ, k=QQ(0), ep=None): INPUT: - - ``analytic_type`` -- An element of ``AnalyticType()`` describing - the analytic type of the space. + - ``analytic_type`` -- an element of ``AnalyticType()`` describing + the analytic type of the space - - ``group`` -- The index of the (Hecke triangle) group of the space (default: `3`). + - ``group`` -- the index of the (Hecke triangle) group of the space (default: `3`) - - ``base_ring`` -- The base ring of the space (default: ``ZZ``). + - ``base_ring`` -- the base ring of the space (default: ``ZZ``) - - ``k`` -- The weight of the space, a rational number (default: ``0``). + - ``k`` -- the weight of the space, a rational number (default: ``0``) - - ``ep`` -- The multiplier of the space, `1`, `-1` or ``None`` + - ``ep`` -- the multiplier of the space, `1`, `-1` or ``None`` (in which case ``ep`` should be determined from ``k``). Default: ``None``. For the variables ``group``, ``base_ring``, ``k``, ``ep`` @@ -227,9 +226,7 @@ def FormsSpace(analytic_type, group=3, base_ring=ZZ, k=QQ(0), ep=None): In particular the multiplier ``ep`` is calculated as usual from ``k`` if ``ep == None``. - OUTPUT: - - The FormsSpace with the given properties. + OUTPUT: the FormsSpace with the given properties EXAMPLES:: @@ -323,24 +320,22 @@ def FormsRing(analytic_type, group=3, base_ring=ZZ, red_hom=False): INPUT: - - ``analytic_type`` -- An element of ``AnalyticType()`` describing - the analytic type of the space. + - ``analytic_type`` -- an element of ``AnalyticType()`` describing + the analytic type of the space - - ``group`` -- The index of the (Hecke triangle) group of the space - (default: 3`). + - ``group`` -- the index of the (Hecke triangle) group of the space + (default: 3`) - - ``base_ring`` -- The base ring of the space (default: ``ZZ``). + - ``base_ring`` -- the base ring of the space (default: ``ZZ``) - - ``red_hom`` -- The (boolean) variable ``red_hom`` of the space - (default: ``False``). + - ``red_hom`` -- the (boolean) variable ``red_hom`` of the space + (default: ``False``) For the variables ``group``, ``base_ring``, ``red_hom`` the same arguments as for the class :class:`FormsRing_abstract` can be used. The variables will then be put in canonical form. - OUTPUT: - - The FormsRing with the given properties. + OUTPUT: the FormsRing with the given properties EXAMPLES:: diff --git a/src/sage/modular/modform_hecketriangle/element.py b/src/sage/modular/modform_hecketriangle/element.py index 308d3c6a7c0..8d8575537e3 100644 --- a/src/sage/modular/modform_hecketriangle/element.py +++ b/src/sage/modular/modform_hecketriangle/element.py @@ -182,24 +182,24 @@ def ambient_coordinate_vector(self): def lseries(self, num_prec=None, max_imaginary_part=0, max_asymp_coeffs=40): r""" - Return the L-series of ``self`` if ``self`` is modular and holomorphic. + Return the `L`-series of ``self`` if ``self`` is modular and holomorphic. This relies on the (pari) based function ``Dokchitser``. INPUT: - - ``num_prec`` -- An integer denoting the to-be-used numerical precision. + - ``num_prec`` -- integer denoting the to-be-used numerical precision. If integer ``num_prec=None`` (default) the default numerical precision of the parent of ``self`` is used. - - ``max_imaginary_part`` -- A real number (default: 0), indicating up to which - imaginary part the L-series is going to be studied. + - ``max_imaginary_part`` -- a real number (default: 0), indicating up + to which imaginary part the `L`-series is going to be studied - - ``max_asymp_coeffs`` -- An integer (default: 40). + - ``max_asymp_coeffs`` -- integer (default: 40) OUTPUT: - An interface to Tim Dokchitser's program for computing L-series, namely + An interface to Tim Dokchitser's program for computing `L`-series, namely the series given by the Fourier coefficients of ``self``. EXAMPLES:: diff --git a/src/sage/modular/modform_hecketriangle/functors.py b/src/sage/modular/modform_hecketriangle/functors.py index b0fdfcf5ac7..b50d618c3c4 100644 --- a/src/sage/modular/modform_hecketriangle/functors.py +++ b/src/sage/modular/modform_hecketriangle/functors.py @@ -33,7 +33,7 @@ from .subspace import SubSpaceForms -def _get_base_ring(ring, var_name="d"): +def _get_base_ring(ring, var_name='d'): r""" Return the base ring of the given ``ring``: @@ -56,7 +56,7 @@ def _get_base_ring(ring, var_name="d"): whose construction should be based on the returned base ring (and not on ``ring``!). - If ``var_name`` (default: "d") is specified then this variable + If ``var_name`` (default: ``'d'``) is specified then this variable name is used for the polynomial ring. EXAMPLES:: @@ -79,7 +79,7 @@ def _get_base_ring(ring, var_name="d"): """ # from sage.rings.fraction_field import FractionField_generic - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.categories.pushout import FractionField as FractionFieldFunctor base_ring = ring @@ -87,7 +87,7 @@ def _get_base_ring(ring, var_name="d"): # base_ring = base_ring.base() if (base_ring.construction() and base_ring.construction()[0] == FractionFieldFunctor()): base_ring = base_ring.construction()[1] - if (is_PolynomialRing(base_ring) and base_ring.ngens() == 1 and base_ring.variable_name() == var_name): + if (isinstance(base_ring, PolynomialRing_general) and base_ring.ngens() == 1 and base_ring.variable_name() == var_name): base_ring = base_ring.base() if (base_ring.construction() and base_ring.construction()[0] == FractionFieldFunctor()): base_ring = base_ring.construction()[1] @@ -164,14 +164,12 @@ def __init__(self, ambient_space_functor, generators): INPUT: - - ``ambient_space_functor`` -- A FormsSpaceFunctor + - ``ambient_space_functor`` -- a FormsSpaceFunctor - - ``generators`` -- A list of elements of some ambient space - over some base ring. + - ``generators`` -- a list of elements of some ambient space + over some base ring - OUTPUT: - - The construction functor for the corresponding forms sub space. + OUTPUT: the construction functor for the corresponding forms sub space EXAMPLES:: @@ -268,7 +266,6 @@ def merge(self, other): If ``other`` is not a ``FormsSubSpaceFunctor`` then ``self`` is merged as if it was its ambient space functor. - EXAMPLES:: sage: from sage.modular.modform_hecketriangle.functors import (FormsSpaceFunctor, FormsSubSpaceFunctor) @@ -359,17 +356,15 @@ def __init__(self, analytic_type, group, k, ep): INPUT: - - ``analytic_type`` -- An element of ``AnalyticType()``. - - - ``group`` -- The index of a Hecke Triangle group. + - ``analytic_type`` -- an element of ``AnalyticType()`` - - ``k`` -- A rational number, the weight of the space. + - ``group`` -- the index of a Hecke Triangle group - - ``ep`` -- `1` or `-1`, the multiplier of the space. + - ``k`` -- a rational number, the weight of the space - OUTPUT: + - ``ep`` -- `1` or `-1`, the multiplier of the space - The construction functor for the corresponding forms space/ring. + OUTPUT: the construction functor for the corresponding forms space/ring EXAMPLES:: @@ -454,7 +449,6 @@ def merge(self, other): Two ``FormsRingFunctors`` are merged to the corresponding (extended) ``FormsRingFunctor``. - EXAMPLES:: sage: from sage.modular.modform_hecketriangle.functors import (FormsSpaceFunctor, FormsRingFunctor) @@ -545,16 +539,14 @@ def __init__(self, analytic_type, group, red_hom): INPUT: - - ``analytic_type`` -- An element of ``AnalyticType()``. - - - ``group`` -- The index of a Hecke Triangle group. + - ``analytic_type`` -- an element of ``AnalyticType()`` - - ``red_hom`` -- A boolean variable for the parameter ``red_hom`` - (also see ``FormsRing_abstract``). + - ``group`` -- the index of a Hecke Triangle group - OUTPUT: + - ``red_hom`` -- a boolean variable for the parameter ``red_hom`` + (also see ``FormsRing_abstract``) - The construction functor for the corresponding forms ring. + OUTPUT: the construction functor for the corresponding forms ring EXAMPLES:: @@ -644,7 +636,6 @@ def merge(self, other): Two ``FormsRingFunctors`` are merged to the corresponding (extended) ``FormsRingFunctor``. - EXAMPLES:: sage: from sage.modular.modform_hecketriangle.functors import (FormsSpaceFunctor, FormsRingFunctor) diff --git a/src/sage/modular/modform_hecketriangle/graded_ring.py b/src/sage/modular/modform_hecketriangle/graded_ring.py index 87251973e18..1cb832bbef3 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring.py @@ -83,13 +83,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -146,13 +146,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -206,13 +206,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -266,13 +266,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -326,13 +326,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -386,13 +386,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -445,13 +445,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: @@ -505,13 +505,13 @@ def __init__(self, group, base_ring, red_hom, n): INPUT: - - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) + - ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: ``ZZ``). + - ``base_ring`` -- the base_ring (default: ``ZZ``) - - ``red_hom`` -- If True then results of binary operations are considered - homogeneous whenever it makes sense (default: ``False``). - This is mainly used by the spaces of homogeneous elements. + - ``red_hom`` -- if ``True`` then results of binary operations are + considered homogeneous whenever it makes sense (default: ``False``). + This is mainly used by the spaces of homogeneous elements. OUTPUT: diff --git a/src/sage/modular/modform_hecketriangle/graded_ring_element.py b/src/sage/modular/modform_hecketriangle/graded_ring_element.py index f097db5e44e..b1510c662a6 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring_element.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring_element.py @@ -88,11 +88,11 @@ def __init__(self, parent, rat): INPUT: - - ``parent`` -- An (non abstract) instance of ``FormsRing_abstract``. + - ``parent`` -- (non abstract) instance of ``FormsRing_abstract`` - - ``rat`` -- A rational function in ``parent.rat_field()``, the - fraction field of the polynomial ring in ``x,y,z,d`` - over the base ring of ``parent``. + - ``rat`` -- a rational function in ``parent.rat_field()``, the + fraction field of the polynomial ring in ``x,y,z,d`` over the base + ring of ``parent`` OUTPUT: @@ -1014,7 +1014,7 @@ def diff_op(self, op, new_parent=None): INPUT: - - ``op`` -- An element of ``self.parent().diff_alg()``. + - ``op`` -- an element of ``self.parent().diff_alg()``. I.e. an element of the algebra over ``QQ`` of differential operators generated by ``X, Y, Z, dX, dY, DZ``, where e.g. ``X`` @@ -1026,13 +1026,11 @@ def diff_op(self, op, new_parent=None): should be homogeneous operator (with respect to the usual, special grading). - - ``new_parent`` -- Try to convert the result to the specified + - ``new_parent`` -- try to convert the result to the specified ``new_parent``. If ``new_parent == None`` (default) then the parent is extended to a "quasi meromorphic" ring. - OUTPUT: - - The new element. + OUTPUT: the new element EXAMPLES:: @@ -1522,7 +1520,7 @@ def full_reduce(self): @cached_method def _q_expansion_cached(self, prec, fix_d, subs_d, d_num_prec, fix_prec=False): """ - Returns the Fourier expansion of self (cached). + Return the Fourier expansion of ``self`` (cached). Don't call this function, instead use :meth:`q_expansion`. Also see :meth:`q_expansion` for a description of the arguments. @@ -1593,27 +1591,25 @@ def q_expansion(self, prec=None, fix_d=False, d_num_prec=None, fix_prec=False): INPUT: - - ``prec`` -- An integer, the desired output precision O(q^prec). + - ``prec`` -- integer, the desired output precision O(q^prec). Default: ``None`` in which case the default precision of ``self.parent()`` is used. - - ``fix_d`` -- If ``False`` (default) a formal parameter is used for ``d``. - If ``True`` then the numerical value of ``d`` is used + - ``fix_d`` -- if ``False`` (default) a formal parameter is used for + ``d``. If ``True`` then the numerical value of ``d`` is used (resp. an exact value if the group is arithmetic). Otherwise the given value is used for ``d``. - - ``d_num_prec`` -- The precision to be used if a numerical value for ``d`` is substituted. - Default: ``None`` in which case the default - numerical precision of ``self.parent()`` is used. + - ``d_num_prec`` -- the precision to be used if a numerical value for + ``d`` is substituted (default: ``None``), otherwise the default + numerical precision of ``self.parent()`` is used - - ``fix_prec`` -- If ``fix_prec`` is not ``False`` (default) + - ``fix_prec`` -- if ``fix_prec`` is not ``False`` (default) then the precision of the ``MFSeriesConstructor`` is increased such that the output has exactly the specified precision O(q^prec). - OUTPUT: - - The Fourier expansion of ``self`` as a ``FormalPowerSeries`` or ``FormalLaurentSeries``. + OUTPUT: the Fourier expansion of ``self`` as a ``FormalPowerSeries`` or ``FormalLaurentSeries`` EXAMPLES:: @@ -1700,21 +1696,21 @@ def q_expansion_fixed_d(self, prec=None, d_num_prec=None, fix_prec=False): INPUT: - - ``prec`` -- An integer, the desired output precision O(q^prec). - Default: ``None`` in which case the default precision of ``self.parent()`` is used. + - ``prec`` -- integer; the desired output precision O(q^prec). + Default: ``None``, in which case the default precision of + ``self.parent()`` is used. - - ``d_num_prec`` -- The precision to be used if a numerical value for ``d`` is substituted. - Default: ``None`` in which case the default - numerical precision of ``self.parent()`` is used. + - ``d_num_prec`` -- the precision to be used if a numerical value for + ``d`` is substituted (default: ``None``), otherwise the default + numerical precision of ``self.parent()`` is used - - ``fix_prec`` -- If ``fix_prec`` is not ``False`` (default) + - ``fix_prec`` -- if ``fix_prec`` is not ``False`` (default) then the precision of the ``MFSeriesConstructor`` is increased such that the output has exactly the specified precision O(q^prec). - OUTPUT: - - The Fourier expansion of self as a ``FormalPowerSeries`` or ``FormalLaurentSeries``. + OUTPUT: the Fourier expansion of ``self`` as a ``FormalPowerSeries`` or + ``FormalLaurentSeries`` EXAMPLES:: @@ -1759,16 +1755,17 @@ def q_expansion_vector(self, min_exp=None, max_exp=None, prec=None, **kwargs): INPUT: - - ``min_exp`` -- An integer, specifying the first coefficient to be + - ``min_exp`` -- integer specifying the first coefficient to be used for the vector. Default: ``None``, meaning that the first non-trivial coefficient is used. - - ``max_exp`` -- An integer, specifying the last coefficient to be + - ``max_exp`` -- integer specifying the last coefficient to be used for the vector. Default: ``None``, meaning that the default precision + 1 is used. - - ``prec`` -- An integer, specifying the precision of the underlying - Laurent series. Default: ``None``, meaning that ``max_exp + 1`` is used. + - ``prec`` -- integer specifying the precision of the underlying + Laurent series. Default: ``None``, meaning that ``max_exp + 1`` is + used. OUTPUT: @@ -1845,16 +1842,16 @@ def evaluate(self, tau, prec=None, num_prec=None, check=False): - ``tau`` -- ``infinity`` or an element of the upper half plane. E.g. with parent ``AA`` or ``CC``. - - ``prec`` -- An integer, namely the precision used for the + - ``prec`` -- integer, namely the precision used for the Fourier expansion. If ``prec == None`` (default) - then the default precision of ``self.parent()`` is used. + then the default precision of ``self.parent()`` is used - - ``num_prec`` -- An integer, namely the minimal numerical precision + - ``num_prec`` -- integer, namely the minimal numerical precision used for ``tau`` and ``d``. If ``num_prec == None`` (default) then the default numerical precision of ``self.parent()`` is used. - - ``check`` -- If ``True`` then the order of ``tau`` is checked. + - ``check`` -- if ``True`` then the order of ``tau`` is checked. Otherwise the order is only considered for ``tau = infinity, i, rho, -1/rho``. Default: ``False``. @@ -1879,7 +1876,7 @@ def evaluate(self, tau, prec=None, num_prec=None, check=False): #. The evaluation at ``w`` is calculated by evaluating the truncated Fourier expansion of - self at ``q(w)``. + ``self`` at ``q(w)``. Note that this is much faster and more precise than a direct evaluation at ``tau``. diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py index c2938e444a0..e7c56fd0e94 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py @@ -25,11 +25,11 @@ from sage.rings.infinity import infinity from sage.rings.cc import CC -lazy_import('sage.rings.qqbar', 'AA') - from sage.groups.matrix_gps.group_element import MatrixGroupElement_generic from sage.geometry.hyperbolic_space.hyperbolic_interface import HyperbolicPlane +lazy_import('sage.rings.qqbar', 'AA') + # We want to simplify p after the coercion (pari bug for AA) def coerce_AA(p): @@ -51,7 +51,7 @@ def coerce_AA(p): """ el = AA(p) el.simplify() - #el.exactify() + # el.exactify() return el @@ -63,7 +63,7 @@ def cyclic_representative(L): INPUT: - - ``L`` -- A list or tuple. + - ``L`` -- list or tuple OUTPUT: @@ -103,13 +103,13 @@ def __init__(self, parent, M, check=True, **kwargs): INPUT: - - ``parent`` -- A ``HeckeTriangleGroup``. + - ``parent`` -- a ``HeckeTriangleGroup`` - - ``M`` -- A matrix which coerces into the matrix space + - ``M`` -- a matrix which coerces into the matrix space of ``parent``. For example with entries in a polynomial ring over ``ZZ`` with parameter ``lam``. - - ``check`` -- ``True`` (default) or ``False``. If ``True`` + - ``check`` -- boolean (default: ``True``); if ``True`` then a (possibly long) check is performed to see whether ``M`` really corresponds to a group element of ``parent``. @@ -182,7 +182,7 @@ def _word_S_T_data(self): of ``self`` as a product of the generators ``S`` and ``T`` together with a sign correction ``sgn``. - If this decomposition is not possible a :class:`TypeError` + If this decomposition is not possible a :exc:`TypeError` is raised. In particular this function can be used to check the membership in ``parent`` of an arbitrary matrix over the base ring. @@ -221,13 +221,13 @@ def _word_S_T_data(self): half = one / ZZ(2) while True: - a,b,c,d = M.list() + a, b, c, d = M.list() mshift = coerce_AA((4*a*c + b*d) / (4*c*c + d*d)) m = (mshift / lam + half).floor() if m != zero: res.append((one, m),) M = T**(-m) * M - a,b,c,d = M.list() + a, b, c, d = M.list() abs_t = coerce_AA((4*a*a + b*b) / (4*c*c + d*d)) if coerce_AA(abs_t) < 1: @@ -256,7 +256,7 @@ def word_S_T(self): of ``L`` are either the generator ``S`` or a non-trivial integer power of the generator ``T``. ``sgn`` is +- the identity. - If this decomposition is not possible a :class:`TypeError` is raised. + If this decomposition is not possible a :exc:`TypeError` is raised. EXAMPLES:: @@ -337,7 +337,7 @@ def _repr_(self): """ return self.string_repr(self.parent().element_repr_method()) - def string_repr(self, method="default"): + def string_repr(self, method='default'): r""" Return a string representation of ``self`` using the specified ``method``. This method is used to represent ``self``. @@ -346,21 +346,23 @@ def string_repr(self, method="default"): INPUT: - - ``method`` -- one of + - ``method`` -- one of - - ``default``: Use the usual representation method for matrix group elements. + - ``'default'`` -- use the usual representation method for matrix + group elements - - ``basic``: The representation is given as a word in ``S`` and powers of ``T``. - Note: If ``S, T`` are defined accordingly the output can - be used/evaluated directly to recover ``self``. + - ``'basic'`` -- the representation is given as a word in ``S`` and + powers of ``T``. Note: If ``S, T`` are defined accordingly the + output can be used/evaluated directly to recover ``self``. - - ``conj``: The conjugacy representative of the element is represented - as a word in powers of the basic blocks, together with - an unspecified conjugation matrix. + - ``'conj'`` -- the conjugacy representative of the element is + represented as a word in powers of the basic blocks, together with + an unspecified conjugation matrix - - ``block``: Same as ``conj`` but the conjugation matrix is specified as well. - Note: Assuming ``S, T, U, V`` are defined accordingly the output - can directly be used/evaluated to recover ``self``. + - ``'block'`` -- same as ``conj`` but the conjugation matrix is + specified as well. Note: Assuming ``S, T, U, V`` are defined + accordingly the output can directly be used/evaluated to recover + ``self``. Warning: For ``n=infinity`` the methods ``conj`` and ``block`` are not verified at all and are probably wrong! @@ -375,10 +377,10 @@ def string_repr(self, method="default"): sage: el4 = G.U()^4 sage: el5 = (G.V(2)*G.T()).acton(-G.S()) - sage: el4.string_repr(method="basic") + sage: el4.string_repr(method='basic') 'S*T^(-1)' - sage: G.element_repr_method("default") + sage: G.element_repr_method('default') sage: el1 [-1 0] [ 0 -1] @@ -395,7 +397,7 @@ def string_repr(self, method="default"): [-7*lam - 4 9*lam + 6] [-4*lam - 5 7*lam + 4] - sage: G.element_repr_method("basic") + sage: G.element_repr_method('basic') sage: el1 -1 sage: el2 @@ -407,7 +409,7 @@ def string_repr(self, method="default"): sage: el5 T*S*T^2*S*T^(-2)*S*T^(-1) - sage: G.element_repr_method("conj") + sage: G.element_repr_method('conj') sage: el1 [-1] sage: el2 @@ -419,7 +421,7 @@ def string_repr(self, method="default"): sage: el5 [-S] - sage: G.element_repr_method("block") + sage: G.element_repr_method('block') sage: el1 -1 sage: el2 @@ -431,14 +433,14 @@ def string_repr(self, method="default"): sage: el5 -(T*S*T^2) * (S) * (T*S*T^2)^(-1) - sage: G.element_repr_method("default") + sage: G.element_repr_method('default') sage: G = HeckeTriangleGroup(n=infinity) sage: el = G.S()*G.T(3)*G.S()*G.T(-2) sage: print(el.string_repr()) [ -1 4] [ 6 -25] - sage: print(el.string_repr(method="basic")) + sage: print(el.string_repr(method='basic')) S*T^3*S*T^(-2) """ if method == "default": @@ -450,7 +452,7 @@ def string_repr(self, method="default"): return "-1" if sgn < 0 else "1" Lstr = list(L) - for i,(v0,v1) in enumerate(Lstr): + for i, (v0, v1) in enumerate(Lstr): if v0 == 0: Lstr[i] = "S" elif v1 == 1: @@ -472,16 +474,16 @@ def string_repr(self, method="default"): (L, R, sgn) = self._block_decomposition_data() - repr_str = self.string_repr(method="conj") + repr_str = self.string_repr(method='conj') repr_str = repr_str[1:-1] if sgn < 0: repr_str = repr_str[1:] - #if self != R.inverse().acton(self): + # if self != R.inverse().acton(self): if R.is_identity(): repr_str = "{}{}".format("-" if sgn < 0 else "", repr_str) else: - R_str = "({})".format(R.string_repr(method="basic")) + R_str = "({})".format(R.string_repr(method='basic')) repr_str = "{}{} * ({}) * {}^(-1)".format("-" if sgn < 0 else "", R_str, repr_str, R_str) return repr_str @@ -494,7 +496,7 @@ def string_repr(self, method="default"): (L, R, sgn) = self._block_decomposition_data() if self.is_elliptic(): - L = [ L ] + L = [L] repr_str = "" begin = True @@ -631,7 +633,7 @@ def continued_fraction(self): if p == infinity: # TODO: The choice of r doesn't matter? r = ZZ.zero() - #elif self.is_elliptic(): + # elif self.is_elliptic(): # r = ZZ(emb(p/lam).real().floor() + 1) else: emb_res = emb(p/lam) @@ -643,7 +645,7 @@ def continued_fraction(self): cf_index += one preperiod_len = cf_dict[p] - #period_len = cf_index - preperiod_len + # period_len = cf_index - preperiod_len return (tuple(L[:preperiod_len]), tuple(L[preperiod_len:])) @@ -660,7 +662,7 @@ def _primitive_block_decomposition_data(self): decomposition is further described by the tuple ``L``, and the corresponding conjugation matrix ``R``. - Together they describe the primitive part of self. + Together they describe the primitive part of ``self``. I.e. an element which is equal to ``self`` up to a sign after taking the appropriate power and which itself cannot be written as a non-trivial @@ -680,7 +682,7 @@ def _primitive_block_decomposition_data(self): The number of such factors is called ``block length`` (see :meth:`block_length`). Each block (and also their product) has a positive sign and - non-negative entries. + nonnegative entries. In the elliptic case the primitive representative is either ``S`` or ``U``. @@ -805,7 +807,7 @@ def _primitive_block_decomposition_data(self): L = (one, one) else: raise RuntimeError("There is something wrong in the method " - "_primitive_block_decomposition_data. Please contact sage-devel@googlegroups.com") + "_primitive_block_decomposition_data. Please contact sage-devel@googlegroups.com") return (L, R) @@ -833,11 +835,11 @@ def _primitive_block_decomposition_data(self): initial_ones = number_of_ones.pop(0) if not list_larger: - list_v1 = [-ZZ(1)] - list_vlarger = [ initial_ones + 2 ] + list_v1 = [-ZZ.one()] + list_vlarger = [initial_ones + 2] else: - list_v1 = [ v-2 for v in list_larger ] - list_vlarger = [ v+2 for v in number_of_ones ] + list_v1 = [v - 2 for v in list_larger] + list_vlarger = [v + 2 for v in number_of_ones] list_vlarger[-1] += initial_ones L = [] @@ -878,7 +880,7 @@ def _primitive_block_decomposition_data(self): return (L, R) - def primitive_representative(self, method="block"): + def primitive_representative(self, method='block'): r""" Return a tuple ``(P, R)`` which gives the decomposition of the primitive part of ``self``, @@ -887,7 +889,7 @@ def primitive_representative(self, method="block"): conjugation matrix ``R`` (the result depends on the method used). - Together they describe the primitive part of self. + Together they describe the primitive part of ``self``. I.e. an element which is equal to ``self`` up to a sign after taking the appropriate power. @@ -901,20 +903,17 @@ def primitive_representative(self, method="block"): INPUT: - - ``method`` -- ``block`` (default) or ``cf``. The method - used to determine ``P`` and ``R``. If - ``self`` is elliptic, this parameter is - ignored, and if ``self`` is +- the identity - then the ``block`` method is used. + - ``method`` -- ``'block'`` (default) or ``'cf'``. The method used to + determine ``P`` and ``R``. If ``self`` is elliptic, this parameter is + ignored, and if ``self`` is +- the identity then the ``block`` method + is used. - With ``block`` the decomposition described - in :meth:`_primitive_block_decomposition_data` is used. + With ``'block'`` the decomposition described in + :meth:`_primitive_block_decomposition_data` is used. - With ``cf`` a reduced representative from - the lambda-CF of ``self`` is used (see - :meth:`continued_fraction`). In that case - ``P`` corresponds to the period and ``R`` - to the preperiod. + With ``'cf'`` a reduced representative from the lambda-CF of ``self`` + is used (see :meth:`continued_fraction`). In that case ``P`` + corresponds to the period and ``R`` to the preperiod. OUTPUT: @@ -926,37 +925,37 @@ def primitive_representative(self, method="block"): sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.element_repr_method("basic") - sage: el = G.T().primitive_representative(method="cf") + sage: el = G.T().primitive_representative(method='cf') sage: el (S*T^(-1)*S*T^(-1)*S*T*S, S*T*S) sage: (el[0]).is_primitive() True - sage: el = G.V(2).acton(G.T(-3)).primitive_representative(method="cf") + sage: el = G.V(2).acton(G.T(-3)).primitive_representative(method='cf') sage: el (-T*S*T^(-1)*S*T^(-1), 1) sage: (el[0]).is_primitive() True - sage: el = (-G.V(2)).primitive_representative(method="cf") + sage: el = (-G.V(2)).primitive_representative(method='cf') sage: el (T^2*S, T*S) sage: (el[0]).is_primitive() True - sage: el = (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method="cf") + sage: el = (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method='cf') sage: el (-T^2*S*T^2*S*T*S*T^(-2)*S*T*S*T*S*T^2*S, T*S) sage: (el[0]).is_primitive() True - sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method="cf") + sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method='cf') sage: el (-T^2*S*T^2*S*T^2*S*T*S*T^(-2)*S*T*S*T*S, T*S*T*S*T*S*T^2*S) sage: (el[0]).is_primitive() True - sage: el = (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_representative(method="cf") + sage: el = (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_representative(method='cf') sage: el (T^2*S*T*S*T^2*S*T*S*T^2*S*T*S*T^7*S, T^6*S) sage: (el[0]).is_primitive() True - sage: el = (G.V(2)*G.V(3)).acton(G.U()^6).primitive_representative(method="cf") + sage: el = (G.V(2)*G.V(3)).acton(G.U()^6).primitive_representative(method='cf') sage: el (T*S, -T*S*T^2*S*T*S*T) sage: (el[0]).is_primitive() @@ -1066,15 +1065,15 @@ def primitive_representative(self, method="block"): raise ValueError("if the element is not elliptic, then method must " "be either be 'cf' or 'block'") - def primitive_part(self, method="cf"): + def primitive_part(self, method='cf'): r""" Return the primitive part of ``self``. I.e. a group element - ``A`` with non-negative trace such that + ``A`` with nonnegative trace such that ``self = sign * A^power``, where ``sign = self.sign()`` is +- the identity (to correct the sign) and ``power = self.primitive_power()``. - The primitive part itself is choosen such that it cannot be + The primitive part itself is chosen such that it cannot be written as a non-trivial power of another element. It is a generator of the stabilizer of the corresponding (attracting) fixed point. @@ -1087,16 +1086,14 @@ def primitive_part(self, method="cf"): INPUT: - - ``method`` -- The method used to determine the primitive + - ``method`` -- the method used to determine the primitive part (see :meth:`primitive_representative`), - default: "cf". The parameter is ignored + default: ``'cf'``. The parameter is ignored for elliptic elements or +- the identity. The result should not depend on the method. - OUTPUT: - - The primitive part as a group element of ``self``. + OUTPUT: the primitive part as a group element of ``self`` EXAMPLES:: @@ -1128,25 +1125,25 @@ def primitive_part(self, method="cf"): sage: el = (G.V(2)*G.V(3)).acton(G.U()^6) sage: el.primitive_part() (-T*S*T^2*S*T*S*T) * (U) * (-T*S*T^2*S*T*S*T)^(-1) - sage: el.primitive_part() == el.primitive_part(method="block") + sage: el.primitive_part() == el.primitive_part(method='block') True sage: G.T().primitive_part() (T^(-1)*S) * (V(6)) * (T^(-1)*S)^(-1) - sage: G.T().primitive_part(method="block") + sage: G.T().primitive_part(method='block') (T^(-1)) * (V(1)) * (T^(-1))^(-1) - sage: G.V(2).acton(G.T(-3)).primitive_part() == G.V(2).acton(G.T(-3)).primitive_part(method="block") + sage: G.V(2).acton(G.T(-3)).primitive_part() == G.V(2).acton(G.T(-3)).primitive_part(method='block') True - sage: (-G.V(2)).primitive_part() == (-G.V(2)).primitive_part(method="block") + sage: (-G.V(2)).primitive_part() == (-G.V(2)).primitive_part(method='block') True sage: el = -G.V(2)^3*G.V(6)^2*G.V(3) - sage: el.primitive_part() == el.primitive_part(method="block") + sage: el.primitive_part() == el.primitive_part(method='block') True sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)) - sage: el.primitive_part() == el.primitive_part(method="block") + sage: el.primitive_part() == el.primitive_part(method='block') True sage: el=G.V(1)^5*G.V(2)*G.V(3)^3 - sage: el.primitive_part() == el.primitive_part(method="block") + sage: el.primitive_part() == el.primitive_part(method='block') True sage: G.element_repr_method("default") @@ -1167,15 +1164,15 @@ def reduce(self, primitive=True): If ``self`` is elliptic (or +- the identity) the result is never reduced (by definition). Instead a more canonical conjugation representative of ``self`` (resp. it's - primitive part) is choosen. + primitive part) is chosen. Warning: The case ``n=infinity`` is not verified at all and probably wrong! INPUT: - - ``primitive`` -- If ``True`` (default) then a primitive - representative for ``self`` is returned. + - ``primitive`` -- if ``True`` (default) then a primitive + representative for ``self`` is returned EXAMPLES:: @@ -1213,7 +1210,7 @@ def reduce(self, primitive=True): from warnings import warn warn("The case n=infinity here is not verified at all and probably wrong!") - (P, R) = self.primitive_representative(method="cf") + (P, R) = self.primitive_representative(method='cf') if primitive: return P @@ -1270,7 +1267,7 @@ def sign(self): raise AssertionError("This shouldn't happen!") @cached_method - def primitive_power(self, method="cf"): + def primitive_power(self, method='cf'): r""" Return the primitive power of ``self``. I.e. an integer ``power`` such that ``self = sign * primitive_part^power``, @@ -1286,16 +1283,16 @@ def primitive_power(self, method="cf"): INPUT: - - ``method`` -- The method used to determine the primitive + - ``method`` -- the method used to determine the primitive power (see :meth:`primitive_representative`), - default: "cf". The parameter is ignored + default: ``'cf'``. The parameter is ignored for elliptic elements or +- the identity. OUTPUT: An integer. For +- the identity element ``0`` is returned, for parabolic and hyperbolic elements a positive integer. - And for elliptic elements a (non-zero) integer with minimal + And for elliptic elements a (nonzero) integer with minimal absolute value such that ``primitive_part^power`` still has a positive sign. @@ -1316,7 +1313,7 @@ def primitive_power(self, method="cf"): 2 sage: (G.V(2)*G.V(3)).acton(G.U()^6).primitive_power() -1 - sage: G.V(2).acton(G.T(-3)).primitive_power() == G.V(2).acton(G.T(-3)).primitive_power(method="block") + sage: G.V(2).acton(G.T(-3)).primitive_power() == G.V(2).acton(G.T(-3)).primitive_power(method='block') True sage: (-G.I()).primitive_power() @@ -1366,20 +1363,21 @@ def primitive_power(self, method="cf"): for j in range(1, G.n()): Uj *= U if U_power == Uj: - #L = [one, ZZ(j)] + # L = [one, ZZ(j)] break elif U_power == -Uj: - #L = [one, ZZ(-j)] + # L = [one, ZZ(-j)] break else: raise RuntimeError("There is a problem in the method " - "'primitive_power'. Please contact sage-devel@googlegroups.com") + "'primitive_power'. Please contact sage-devel@googlegroups.com") if abs(j) < G.n()/two: return j elif two*j == G.n(): return j - # for the cases fom here on the sign has to be adjusted to the + # for the cases from here on the sign has to be adjusted + # to the # sign of self (in self._block_decomposition_data()) elif two*j == -G.n(): return -j @@ -1424,16 +1422,15 @@ def block_length(self, primitive=False): INPUT: - - ``primitive`` -- If ``True`` then the conjugacy - representative of the primitive part is - used instead, default: ``False``. + - ``primitive`` -- boolean (default: ``False``); if ``True`` then the + conjugacy representative of the primitive part is used instead OUTPUT: - An integer. For hyperbolic elements a non-negative integer. + An integer. For hyperbolic elements a nonnegative integer. For parabolic elements a negative sign corresponds to taking the inverse. For elliptic elements a (non-trivial) integer - with minimal absolute value is choosen. For +- the identity + with minimal absolute value is chosen. For +- the identity element ``0`` is returned. EXAMPLES:: @@ -1517,7 +1514,7 @@ def block_length(self, primitive=False): else: return sum(abs(v[1]) for v in L) - #@cached_method + # @cached_method def _block_decomposition_data(self): r""" Return a tuple ``(L, R, sgn)`` which describes the @@ -1774,7 +1771,7 @@ def block_decomposition(self): P = G.U() return ((P**L[1],), R, sgn) else: - return (tuple(G.V(v[0])**v[1] for v in L ), R, sgn) + return (tuple(G.V(v[0])**v[1] for v in L), R, sgn) def conjugacy_type(self, ignore_sign=True, primitive=False): r""" @@ -1786,12 +1783,12 @@ def conjugacy_type(self, ignore_sign=True, primitive=False): INPUT: - - ``ignore_sign`` -- If ``True`` (default) then the conjugacy - classes are only considered up to a sign. + - ``ignore_sign`` -- if ``True`` (default) then the conjugacy + classes are only considered up to a sign - - ``primitive`` -- If ``True`` then the conjugacy class of - the primitive part is considered instead - and the sign is ignored, default: ``False``. + - ``primitive`` -- boolean (default: ``False``); if ``True`` then the + conjugacy class of the primitive part is considered instead and the + sign is ignored OUTPUT: @@ -2012,7 +2009,7 @@ def simple_fixed_point_set(self, extended=True): This is a so called `irreducible system of poles` for rational period functions for the parent group. I.e. the fixed points occur as a irreducible part - of the non-zero pole set of some rational period + of the nonzero pole set of some rational period function and all pole sets are given as a union of such irreducible systems of poles. @@ -2209,7 +2206,7 @@ def is_translation(self, exclude_one=False): sage: (-HeckeTriangleGroup(n=7).I()).is_translation(exclude_one=True) False """ - a,b,c,d = self._matrix.list() + a, b, c, d = self._matrix.list() if not (c.is_zero() and a == d and (a.is_one() or (-a).is_one())): return False @@ -2307,7 +2304,7 @@ def is_elliptic(self): def is_primitive(self): r""" - Returns whether ``self`` is primitive. We call an element + Return whether ``self`` is primitive. We call an element primitive if (up to a sign and taking inverses) it generates the full stabilizer subgroup of the corresponding fixed point. In the non-elliptic case this means that primitive elements @@ -2366,7 +2363,7 @@ def is_primitive(self): def is_reduced(self, require_primitive=True, require_hyperbolic=True): r""" - Returns whether ``self`` is reduced. We call an element + Return whether ``self`` is reduced. We call an element reduced if the associated lambda-CF is purely periodic. I.e. (in the hyperbolic case) if the associated hyperbolic @@ -2386,11 +2383,11 @@ def is_reduced(self, require_primitive=True, require_hyperbolic=True): INPUT: - - ``require_primitive`` -- If ``True`` (default) then non-primitive elements - are not considered reduced. + - ``require_primitive`` -- if ``True`` (default) then non-primitive + elements are not considered reduced - - ``require_hyperbolic`` -- If ``True`` (default) then non-hyperbolic elements - are not considered reduced. + - ``require_hyperbolic`` -- if ``True`` (default) then non-hyperbolic + elements are not considered reduced EXAMPLES:: @@ -2491,7 +2488,7 @@ def is_simple(self): return False # The last condition is/should be equivalent to: - a,b,c,d = self._matrix.list() + a, b, c, d = self._matrix.list() return (coerce_AA(a) > 0 and coerce_AA(b) > 0 and coerce_AA(c) > 0 and coerce_AA(d) > 0) def is_hecke_symmetric(self): @@ -2678,7 +2675,7 @@ def rational_period_function(self, k): if k % 2: raise TypeError except TypeError: - raise ValueError("k={} must be an even integer!".format(k)) + raise ValueError(f"k={k} must be an even integer!") from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing P = PolynomialRing(self.parent().base_ring(), 'z') @@ -2686,14 +2683,14 @@ def rational_period_function(self, k): s = P.zero() - #L1 = [] + # L1 = [] for v in self.simple_elements(): - a,b,c,d = v._matrix.list() + a, b, c, d = v._matrix.list() Q = c*z**2 + (d - a)*z - b s += Q**(-k/ZZ(2)) for v in self.inverse().simple_elements(): - a,b,c,d = v._matrix.list() + a, b, c, d = v._matrix.list() Q = c*z**2 + (d - a)*z - b s -= ZZ(-1)**(k/ZZ(2)) * Q**(-k/ZZ(2)) @@ -2885,7 +2882,7 @@ def root_extension_embedding(self, K=None): INPUT: - - ``K`` -- A field to which we want the (correct) embedding. + - ``K`` -- a field to which we want the (correct) embedding. If ``K=None`` (default), then ``AlgebraicField()`` is used for elliptic elements and ``AlgebraicRealField()`` otherwise. @@ -2946,28 +2943,29 @@ def root_extension_embedding(self, K=None): """ return self.parent().root_extension_embedding(self.discriminant(), K) - def fixed_points(self, embedded=False, order="default"): + def fixed_points(self, embedded=False, order='default'): r""" Return a pair of (mutually conjugate) fixed points of ``self`` in a possible quadratic extension of the base field. INPUT: - - ``embedded`` -- If ``True``, the fixed points are embedded into - ``AlgebraicRealField`` resp. ``AlgebraicField``. Default: ``False``. + - ``embedded`` -- boolean (default: ``False``); if ``True``, the fixed + points are embedded into ``AlgebraicRealField`` resp. + ``AlgebraicField`` - - ``order`` -- If ``order="none"`` the fixed points are choosen - and ordered according to a fixed formula. + - ``order`` -- if ``order='none'`` the fixed points are chosen + and ordered according to a fixed formula - If ``order="sign"`` the fixed points are always ordered + If ``order='sign'`` the fixed points are always ordered according to the sign in front of the square root. - If ``order="default"`` (default) then in case the fixed + If ``order='default'`` (default) then in case the fixed points are hyperbolic they are ordered according to the sign of the trace of ``self`` instead, such that the attracting fixed point comes first. - If ``order="trace"`` the fixed points are always ordered + If ``order='trace'`` the fixed points are always ordered according to the sign of the trace of ``self``. If the trace is zero they are ordered by the sign in front of the square root. In particular the fixed_points @@ -2979,9 +2977,9 @@ def fixed_points(self, embedded=False, order="default"): ``AlgebraicField`` is returned. Otherwise an element of a relative field extension over the base field of (the parent of) ``self`` is returned. - Warning: Relative field extensions don't support default embeddings. + Warning: Relative field extensions do not support default embeddings. So the correct embedding (which is the positive resp. imaginary positive - one) has to be choosen. + one) has to be chosen. EXAMPLES:: @@ -3016,16 +3014,16 @@ def fixed_points(self, embedded=False, order="default"): True sage: (G.U()^4).fixed_points() ((1/2*lam^2 - 1/2*lam - 1/2)*e + 1/2*lam, (-1/2*lam^2 + 1/2*lam + 1/2)*e + 1/2*lam) - sage: pts = (G.U()^4).fixed_points(order="trace") + sage: pts = (G.U()^4).fixed_points(order='trace') sage: (G.U()^4).fixed_points() == [pts[1], pts[0]] False - sage: (G.U()^4).fixed_points(order="trace") == (-G.U()^4).fixed_points(order="trace") + sage: (G.U()^4).fixed_points(order='trace') == (-G.U()^4).fixed_points(order='trace') True - sage: (G.U()^4).fixed_points() == (G.U()^4).fixed_points(order="none") + sage: (G.U()^4).fixed_points() == (G.U()^4).fixed_points(order='none') True sage: (-G.U()^4).fixed_points() == (G.U()^4).fixed_points() True - sage: (-G.U()^4).fixed_points(order="none") == pts + sage: (-G.U()^4).fixed_points(order='none') == pts True sage: p = (G.U()^4).fixed_points(embedded=True)[1] sage: p @@ -3051,7 +3049,7 @@ def fixed_points(self, embedded=False, order="default"): else: e = self.root_extension_field().gen() - a,b,c,d = self._matrix.list() + a, b, c, d = self._matrix.list() if order == "none": sgn = ZZ(1) @@ -3105,7 +3103,7 @@ def acton(self, tau): INPUT: - - ``tau`` -- Either an element of ``self`` or any + - ``tau`` -- either an element of ``self`` or any element to which a linear fractional transformation can be applied in the usual way. @@ -3172,7 +3170,7 @@ def acton(self, tau): model = tau.model() tau = tau.to_model('UHP').coordinates() - a,b,c,d = self._matrix.list() + a, b, c, d = self._matrix.list() if tau == infinity: if c.is_zero(): @@ -3237,10 +3235,10 @@ def slash(self, f, tau=None, k=None): INPUT: - - ``f`` -- A function in ``tau`` (or an object for which - evaluation at ``self.acton(tau)`` makes sense. + - ``f`` -- a function in ``tau`` (or an object for which + evaluation at ``self.acton(tau)`` makes sense - - ``tau`` -- Where to evaluate the result. + - ``tau`` -- where to evaluate the result. This should be a valid argument for :meth:`acton`. If ``tau`` is a point of ``HyperbolicPlane()`` then @@ -3251,7 +3249,7 @@ def slash(self, f, tau=None, k=None): the generator of the polynomial ring is used for ``tau``. That way ``slash`` acts on rational functions / polynomials. - - ``k`` -- An even integer. + - ``k`` -- even integer Default: ``None`` in which case ``f`` either has to be a rational function / polynomial in one @@ -3319,9 +3317,10 @@ def slash(self, f, tau=None, k=None): return (self.c()*tau + self.d())**(-k) * f(self.acton(tau)) - def as_hyperbolic_plane_isometry(self, model="UHP"): + def as_hyperbolic_plane_isometry(self, model='UHP'): r""" - Return ``self`` as an isometry of ``HyperbolicPlane()`` (in the upper half plane model). + Return ``self`` as an isometry of ``HyperbolicPlane()`` (in the upper + half plane model). EXAMPLES:: diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index 17ee69ec123..6aedcba881c 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -77,11 +77,9 @@ def __init__(self, n): INPUT: - - ``n`` -- ``infinity`` or an integer greater or equal to ``3``. + - ``n`` -- ``infinity`` or an integer greater or equal to `3` - OUTPUT: - - The Hecke triangle group for the given parameter ``n``. + OUTPUT: the Hecke triangle group for the given parameter `n` EXAMPLES:: @@ -122,7 +120,7 @@ def _repr_(self): sage: HeckeTriangleGroup(10) Hecke triangle group for n = 10 """ - return "Hecke triangle group for n = {}".format(self._n) + return f"Hecke triangle group for n = {self._n}" def _latex_(self): r""" @@ -143,19 +141,23 @@ def element_repr_method(self, method=None): INPUT: - - ``method`` -- If ``method=None`` (default) the current default representation - method is returned. Otherwise the default method is set to ``method``. - If ``method`` is not available a :class:`ValueError` is raised. Possible methods are: + - ``method`` -- if ``method=None`` (default) the current default + representation method is returned. Otherwise the default method is + set to ``method``. If ``method`` is not available a + :exc:`ValueError` is raised. Possible methods are: - ``default``: Use the usual representation method for matrix group elements. + - ``default``: use the usual representation method for matrix group + elements - ``basic``: The representation is given as a word in ``S`` and powers of ``T``. + - ``basic``: the representation is given as a word in ``S`` and + powers of ``T`` - ``conj``: The conjugacy representative of the element is represented - as a word in powers of the basic blocks, together with - an unspecified conjugation matrix. + - ``conj``: the conjugacy representative of the element is + represented as a word in powers of the basic blocks, together with + an unspecified conjugation matrix - ``block``: Same as ``conj`` but the conjugation matrix is specified as well. + - ``block``: same as ``conj`` but the conjugation matrix is + specified as well EXAMPLES:: @@ -390,11 +392,13 @@ def I(self): @cached_method def T(self, m=1): r""" - Return the element in ``self`` corresponding to the translation by ``m*self.lam()``. + Return the element in ``self`` corresponding to the translation by + ``m*self.lam()``. INPUT: - - ``m`` -- An integer, default: ``1``, namely the second generator of ``self``. + - ``m`` -- integer (default: 1); namely the second generator of + ``self`` EXAMPLES:: @@ -479,12 +483,10 @@ def V(self, j): INPUT: - - ``j`` -- Any integer. To get the usual representatives - ``j`` should range from ``1`` to ``self.n()-1``. - - OUTPUT: + - ``j`` --integer; to get the usual representatives + ``j`` should range from ``1`` to ``self.n()-1`` - The corresponding matrix/element. + OUTPUT: the corresponding matrix/element The matrix is parabolic if ``j`` is congruent to `\pm 1` modulo ``self.n()``. It is elliptic if ``j`` is congruent to 0 modulo ``self.n()``. @@ -589,19 +591,19 @@ def get_FD(self, z): INPUT: - - ``z`` -- a complex number or an element of AlgebraicField(). + - ``z`` -- a complex number or an element of AlgebraicField() OUTPUT: A tuple ``(A, w)``. - ``A`` -- a matrix in ``self`` such that ``A.acton(w)==z`` - (if ``z`` is exact at least). + (if ``z`` is exact at least) - ``w`` -- a complex number or an element of AlgebraicField() (depending on the type ``z``) which lies inside the (strict) fundamental domain of ``self`` (``self.in_FD(w)==True``) and - which is equivalent to ``z`` (by the above property). + which is equivalent to ``z`` (by the above property) EXAMPLES:: @@ -678,13 +680,13 @@ def root_extension_field(self, D): INPUT: - - ``D`` -- An element of the base ring of ``self`` - corresponding to a discriminant. + - ``D`` -- an element of the base ring of ``self`` + corresponding to a discriminant OUTPUT: A relative (at most quadratic) extension to the base field - of self in the variable ``e`` which corresponds to ``sqrt(D)``. + of ``self`` in the variable ``e`` which corresponds to ``sqrt(D)``. If the extension degree is ``1`` then the base field is returned. The correct embedding is the positive resp. positive imaginary one. @@ -745,18 +747,18 @@ def root_extension_embedding(self, D, K=None): INPUT: - - ``D`` -- An element of the base ring of ``self`` - corresponding to a discriminant. + - ``D`` -- an element of the base ring of ``self`` + corresponding to a discriminant - - ``K`` -- A field to which we want the (correct) embedding. - If ``K=None`` (default) then ``AlgebraicField()`` is + - ``K`` -- a field to which we want the (correct) embedding; + if ``K=None`` (default) then ``AlgebraicField()`` is used for positive ``D`` and ``AlgebraicRealField()`` - otherwise. + otherwise OUTPUT: The corresponding embedding if it was found. - Otherwise a :class:`ValueError` is raised. + Otherwise a :exc:`ValueError` is raised. EXAMPLES:: @@ -893,7 +895,7 @@ def _elliptic_conj_reps(self): def _conjugacy_representatives(self, max_block_length=0, D=None): r""" Store conjugacy representatives up to block length - ``max_block_length`` (a non-negative integer, default: 0) + ``max_block_length`` (a nonnegative integer, default: 0) in the internal dictionary. Previously calculated data is reused. This is a helper function for e.g. :meth:`class_number`. @@ -904,18 +906,17 @@ def _conjugacy_representatives(self, max_block_length=0, D=None): The set of all non-primitive representatives (so far) with discriminant ``D`` is stored in ``self._conj_nonprim[D]``. - The case of non-positive discriminants is done manually. + The case of nonpositive discriminants is done manually. INPUT: - - ``max_block_length`` -- A non-negative integer (default: ``0``), - the maximal block length. + - ``max_block_length`` -- nonnegative integer (default: `0`); the + maximal block length - - ``D`` -- An element/discriminant of the base ring or - more generally an upper bound for the - involved discriminants. If ``D != None`` - then an upper bound for ``max_block_length`` - is deduced from ``D`` (default: ``None``). + - ``D`` -- an element/discriminant of the base ring or more generally + an upper bound for the involved discriminants. If ``D != None`` then + an upper bound for ``max_block_length`` is deduced from ``D`` + (default: ``None``). EXAMPLES:: @@ -969,7 +970,7 @@ def _conjugacy_representatives(self, max_block_length=0, D=None): if max_block_length < 0: raise TypeError except TypeError: - raise ValueError("max_block_length must be a non-negative integer!") + raise ValueError("max_block_length must be a nonnegative integer!") if not hasattr(self, "_max_block_length"): self._max_block_length = ZZ.zero() @@ -1068,11 +1069,11 @@ def class_representatives(self, D, primitive=True): INPUT: - - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + - ``D`` -- an element of the base ring corresponding + to a valid discriminant - - ``primitive`` -- If ``True`` (default) then only primitive - representatives are considered. + - ``primitive`` -- if ``True`` (default) then only primitive + representatives are considered EXAMPLES:: @@ -1153,11 +1154,11 @@ def class_number(self, D, primitive=True): INPUT: - - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + - ``D`` -- an element of the base ring corresponding + to a valid discriminant - - ``primitive`` -- If ``True`` (default) then only primitive - elements are considered. + - ``primitive`` -- if ``True`` (default) then only primitive + elements are considered EXAMPLES:: @@ -1203,10 +1204,10 @@ def is_discriminant(self, D, primitive=True) -> bool: INPUT: - - ``D`` -- An element of the base ring. + - ``D`` -- an element of the base ring - - ``primitive`` -- If ``True`` (default) then only primitive - elements are considered. + - ``primitive`` -- if ``True`` (default) then only primitive + elements are considered OUTPUT: @@ -1250,22 +1251,20 @@ def list_discriminants(self, D, primitive=True, hyperbolic=True, incomplete=Fals INPUT: - - ``D`` -- An element/discriminant of the base ring or - more generally an upper bound for the discriminant. + - ``D`` -- an element/discriminant of the base ring or + more generally an upper bound for the discriminant - - ``primitive`` -- If ``True`` (default) then only primitive - discriminants are listed. + - ``primitive`` -- if ``True`` (default) then only primitive + discriminants are listed - - ``hyperbolic`` -- If ``True`` (default) then only positive - discriminants are listed. + - ``hyperbolic`` -- if ``True`` (default) then only positive + discriminants are listed - - ``incomplete`` -- If ``True`` (default: ``False``) then all + - ``incomplete`` -- if ``True`` (default: ``False``) then all (also higher) discriminants which were gathered so far are listed - (however there might be missing discriminants inbetween). - - OUTPUT: + (however there might be missing discriminants in between). - A list of discriminants less than or equal to ``D``. + OUTPUT: list of discriminants less than or equal to ``D`` EXAMPLES:: @@ -1312,8 +1311,8 @@ def reduced_elements(self, D): Also see the element method :meth:`is_reduced` for more information. - - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + - ``D`` -- an element of the base ring corresponding + to a valid discriminant EXAMPLES:: @@ -1349,8 +1348,8 @@ def simple_elements(self, D): Also see the element method ``is_simple()`` for more information. - - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + - ``D`` -- an element of the base ring corresponding to a valid + discriminant EXAMPLES:: @@ -1376,7 +1375,8 @@ def simple_elements(self, D): def rational_period_functions(self, k, D): r""" - Return a list of basic rational period functions of weight ``k`` for discriminant ``D``. + Return a list of basic rational period functions of weight ``k`` for + discriminant ``D``. The list is expected to be a generating set for all rational period functions of the given weight and discriminant (unknown). @@ -1385,11 +1385,11 @@ def rational_period_functions(self, k, D): Also see the element method `rational_period_function` for more information. - - ``k`` -- An even integer, the desired weight - of the rational period functions. + - ``k`` -- even integer, the desired weight of the rational period + functions - - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + - ``D`` -- an element of the base ring corresponding to a valid + discriminant EXAMPLES:: @@ -1412,7 +1412,7 @@ def rational_period_functions(self, k, D): if not ZZ(2).divides(k): raise TypeError except TypeError: - raise ValueError("k={} has to be an even integer!".format(k)) + raise ValueError(f"k={k} has to be an even integer!") z = PolynomialRing(self.base_ring(), 'z').gen() diff --git a/src/sage/modular/modform_hecketriangle/readme.py b/src/sage/modular/modform_hecketriangle/readme.py index 799f68dc814..60747e9578a 100644 --- a/src/sage/modular/modform_hecketriangle/readme.py +++ b/src/sage/modular/modform_hecketriangle/readme.py @@ -464,7 +464,7 @@ For each group element a very specific conjugacy representative can be obtained. For hyperbolic and parabolic elements the representative is a product ``V(j)``-matrices. They all - have non-negative trace and the number of factors is called + have nonnegative trace and the number of factors is called the block length of the element (which is implemented). Note: For this decomposition special care is given to the diff --git a/src/sage/modular/modform_hecketriangle/series_constructor.py b/src/sage/modular/modform_hecketriangle/series_constructor.py index b44f41a09a0..4705846217b 100644 --- a/src/sage/modular/modform_hecketriangle/series_constructor.py +++ b/src/sage/modular/modform_hecketriangle/series_constructor.py @@ -86,14 +86,12 @@ def __init__(self, group, prec): INPUT: - - ``group`` -- A Hecke triangle group (default: HeckeTriangleGroup(3)). + - ``group`` -- a Hecke triangle group (default: HeckeTriangleGroup(3)) - - ``prec`` -- An integer (default: 10), the default precision used - in calculations in the LaurentSeriesRing or PowerSeriesRing. + - ``prec`` -- integer (default: 10), the default precision used in + calculations in the LaurentSeriesRing or PowerSeriesRing - OUTPUT: - - The constructor for Fourier expansion with the specified settings. + OUTPUT: the constructor for Fourier expansion with the specified settings EXAMPLES:: @@ -115,10 +113,9 @@ def __init__(self, group, prec): sage: MFSeriesConstructor(group=infinity) Power series constructor for Hecke modular forms for n=+Infinity with (basic series) precision 10 """ - self._group = group self._prec = prec - self._series_ring = PowerSeriesRing(QQ,'q',default_prec=self._prec) + self._series_ring = PowerSeriesRing(QQ, 'q', default_prec=self._prec) def _repr_(self): r""" @@ -147,7 +144,6 @@ def group(self): sage: MFSeriesConstructor(group=4).group() Hecke triangle group for n = 4 """ - return self._group def hecke_n(self): @@ -160,7 +156,6 @@ def hecke_n(self): sage: MFSeriesConstructor(group=4).hecke_n() 4 """ - return self._group.n() def prec(self): @@ -175,7 +170,6 @@ def prec(self): sage: MFSeriesConstructor(group=5, prec=20).prec() 20 """ - return self._prec @cached_method @@ -193,9 +187,9 @@ def J_inv_ZZ(self): .. TODO:: - The functions that are used in this implementation are - products of hypergeometric series with other, elementary, - functions. Implement them and clean up this representation. + The functions that are used in this implementation are + products of hypergeometric series with other, elementary, + functions. Implement them and clean up this representation. EXAMPLES:: @@ -210,29 +204,27 @@ def J_inv_ZZ(self): sage: MFSeriesConstructor(group=infinity, prec=3).J_inv_ZZ() q^-1 + 3/8 + 69/1024*q + O(q^2) """ + def F1(a, b): + return self._series_ring( + [ZZ.zero()] + + [rising_factorial(a, k) * rising_factorial(b, k) / (ZZ(k).factorial())**2 + * sum(ZZ.one()/(a+j) + ZZ.one()/(b+j) - ZZ(2)/ZZ(1+j) + for j in range(k)) + for k in range(1, self._prec + 1) + ], + ZZ(self._prec + 1) + ) + + def F(a, b, c): + return self._series_ring( + [rising_factorial(a, k) * rising_factorial(b, k) / rising_factorial(c, k) / ZZ(k).factorial() + for k in range(self._prec + 1)], + ZZ(self._prec + 1) + ) - F1 = lambda a,b: self._series_ring( - [ ZZ(0) ] - + [ - rising_factorial(a,k) * rising_factorial(b,k) / (ZZ(k).factorial())**2 - * sum(ZZ(1)/(a+j) + ZZ(1)/(b+j) - ZZ(2)/ZZ(1+j) - for j in range(ZZ(0),ZZ(k)) - ) - for k in range(ZZ(1), ZZ(self._prec+1)) - ], - ZZ(self._prec+1) - ) - - F = lambda a,b,c: self._series_ring( - [ - rising_factorial(a,k) * rising_factorial(b,k) / rising_factorial(c,k) / ZZ(k).factorial() - for k in range(ZZ(0), ZZ(self._prec+1)) - ], - ZZ(self._prec+1) - ) a = self._group.alpha() b = self._group.beta() - Phi = F1(a,b) / F(a,b,ZZ(1)) + Phi = F1(a, b) / F(a, b, ZZ.one()) q = self._series_ring.gen() # the current implementation of power series reversion is slow @@ -240,7 +232,7 @@ def J_inv_ZZ(self): temp_f = (q*Phi.exp()).polynomial() new_f = temp_f.revert_series(temp_f.degree()+1) - J_inv_ZZ = ZZ(1) / (new_f + O(q**(temp_f.degree()+1))) + J_inv_ZZ = ZZ.one() / (new_f + O(q**(temp_f.degree()+1))) return J_inv_ZZ @@ -509,7 +501,7 @@ def EisensteinSeries_ZZ(self, k): INPUT: - - ``k`` -- A non-negative even integer, namely the weight. + - ``k`` -- a nonnegative even integer, namely the weight EXAMPLES:: @@ -552,7 +544,7 @@ def EisensteinSeries_ZZ(self, k): raise TypeError(None) k = 2*ZZ(k/2) except TypeError: - raise TypeError("k={} has to be a non-negative even integer!".format(k)) + raise TypeError("k={} has to be a nonnegative even integer!".format(k)) if (not self.group().is_arithmetic() or self.group().n() == infinity): # Exceptional cases should be called manually (see in FormsRing_abstract) diff --git a/src/sage/modular/modform_hecketriangle/space.py b/src/sage/modular/modform_hecketriangle/space.py index 9530d5f07fe..3a55142a63d 100644 --- a/src/sage/modular/modform_hecketriangle/space.py +++ b/src/sage/modular/modform_hecketriangle/space.py @@ -266,7 +266,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` OUTPUT: @@ -440,7 +440,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` OUTPUT: @@ -708,7 +708,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` OUTPUT: @@ -853,7 +853,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` OUTPUT: @@ -961,9 +961,9 @@ def _change_degree(self, k, ep): INPUT: - - ``k`` -- A rational number, the weight. + - ``k`` -- a rational number; the weight - - ``ep`` -- ``1`` or ``-1``, the multiplier. + - ``ep`` -- ``1`` or ``-1``; the multiplier EXAMPLES:: @@ -1017,7 +1017,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``, i.e. in this case the zero vector. + - ``v`` -- an element of ``self``, i.e. in this case the zero vector EXAMPLES:: diff --git a/src/sage/modular/modform_hecketriangle/subspace.py b/src/sage/modular/modform_hecketriangle/subspace.py index aa16edabc04..b22840338dd 100644 --- a/src/sage/modular/modform_hecketriangle/subspace.py +++ b/src/sage/modular/modform_hecketriangle/subspace.py @@ -59,7 +59,7 @@ def ModularFormsSubSpace(*args, **kwargs): r""" Create a modular forms subspace generated by the supplied arguments if possible. Instead of a list of generators also multiple input arguments can be used. - If ``reduce=True`` then the corresponding ambient space is choosen as small as possible. + If ``reduce=True`` then the corresponding ambient space is chosen as small as possible. If no subspace is available then the ambient space is returned. EXAMPLES:: @@ -137,22 +137,21 @@ def __classcall__(cls, ambient_space, basis=(), check=True): def __init__(self, ambient_space, basis, check): r""" - Return the Submodule of (Hecke) forms in ``ambient_space`` for the given ``basis``. + Return the Submodule of (Hecke) forms in ``ambient_space`` for the + given ``basis``. INPUT: - - ``ambient_space`` -- An ambient forms space. + - ``ambient_space`` -- an ambient forms space - - ``basis`` -- A tuple of (not necessarily linearly independent) - elements of ``ambient_space``. + - ``basis`` -- a tuple of (not necessarily linearly independent) + elements of ``ambient_space`` - - ``check`` -- If ``True`` (default) then a maximal linearly - independent subset of ``basis`` is choosen. Otherwise - it is assumed that ``basis`` is linearly independent. + - ``check`` -- if ``True`` (default) then a maximal linearly + independent subset of ``basis`` is chosen. Otherwise it is assumed + that ``basis`` is linearly independent. - OUTPUT: - - The corresponding submodule. + OUTPUT: the corresponding submodule EXAMPLES:: @@ -230,7 +229,7 @@ def _repr_(self): # If we list the basis the representation usually gets too long... # return "Subspace with basis {} of {}".format([v.as_ring_element() for v in self.basis()], self._ambient_space) - return "Subspace of dimension {} of {}".format(len(self._basis), self._ambient_space) + return f"Subspace of dimension {len(self._basis)} of {self._ambient_space}" def change_ring(self, new_base_ring): r""" @@ -383,7 +382,7 @@ def coordinate_vector(self, v): INPUT: - - ``v`` -- An element of ``self``. + - ``v`` -- an element of ``self`` OUTPUT: diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index 02e1bc3cb9e..beb8509af0f 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -119,13 +119,13 @@ class ModularSymbolsAmbient(ModularSymbolsSpace, AmbientHeckeModule): INPUT: - - ``weight`` -- an integer - - ``group`` -- a congruence subgroup. - - ``sign`` -- an integer, either -1, 0, or 1 + - ``weight`` -- integer + - ``group`` -- a congruence subgroup + - ``sign`` -- integer; either -1, 0, or 1 - ``base_ring`` -- a commutative ring - - ``custom_init`` -- a function that is called with self as input + - ``custom_init`` -- a function that is called with ``self`` as input before any computations are done using self; this could be used - to set a custom modular symbols presentation. + to set a custom modular symbols presentation TESTS:: @@ -147,19 +147,18 @@ def __init__(self, group, weight, sign, base_ring, INPUT: - - ``weight`` -- an integer + - ``weight`` -- integer - - ``group`` -- a congruence subgroup. + - ``group`` -- a congruence subgroup - - ``sign`` -- an integer, either -1, 0, or 1 + - ``sign`` -- integer, either -1, 0, or 1 - - ``base_ring`` -- a commutative ring + - ``base_ring`` -- a commutative ring EXAMPLES:: sage: ModularSymbols(2,2) Modular Symbols space of dimension 1 for Gamma_0(2) of weight 2 with sign 0 over Rational Field - """ weight = int(weight) if weight <= 1: @@ -201,14 +200,10 @@ def new_submodule(self, p=None): INPUT: + - ``p`` -- (default: ``None``) if not ``None``, return only + the `p`-new submodule - - ``p`` -- (default: None); if not None, return only - the `p`-new submodule. - - - OUTPUT: - - The new or `p`-new submodule of this modular symbols ambient space. + OUTPUT: the new or `p`-new submodule of this modular symbols ambient space EXAMPLES:: @@ -306,7 +301,6 @@ def compute_presentation(self): EXAMPLES:: sage: ModularSymbols(11,2).compute_presentation() # no output - """ B, basis, mod = relation_matrix.compute_presentation( self.manin_symbols(), self.sign(), @@ -348,50 +342,49 @@ def manin_gens_to_basis(self): def _element_constructor_(self, x, computed_with_hecke=False): r""" Coerce `x` into this modular symbols space. The result is - either an element of self or a subspace of self. + either an element of ``self`` or a subspace of ``self``. INPUT: The allowed input types for `x` are as follows: + - ``Vector`` -- a vector of the same degree. This + defines the corresponding linear combination of the basis of ``self`` - - ``Vector`` -- a vector of the same degree. This - defines the corresponding linear combination of the basis of self. + - ``ManinSymbol`` -- a Manin symbol of the same weight + as the space - - ``ManinSymbol`` -- a Manin symbol of the same weight - as the space + - ``ModularSymbolsElement`` -- a modular symbol whose + ambient parent is this space of modular symbols. (TODO: make more + sophisticated) - - ``ModularSymbolsElement`` -- a modular symbol whose - ambient parent is this space of modular symbols. (TODO: make more - sophisticated) + - 0 -- the integer 0; results in the 0 modular symbol - - 0 -- the integer 0; results in the 0 modular symbol. + - 3-tuple -- given a 3-tuple (i,u,v), returns the modular symbol + element defined by the Manin symbol + `[X^{i}\cdot Y^{k-2-i}, (u,v)]`, where k is the weight. + Note that we must have `0\leq i \leq k-2`. - - 3-tuple -- Given a 3-tuple (i,u,v), returns the modular symbol - element defined by the Manin symbol - `[X^{i}\cdot Y^{k-2-i}, (u,v)]`, where k is the weight. - Note that we must have `0\leq i \leq k-2`. + - 2-tuple -- given a 2-tuple (u,v), returns the element defined by + the Manin symbol `[X^0 \cdot Y^{2-k}, (u,v)]` - - 2-tuple -- Given a 2-tuple (u,v), returns the element defined by - the Manin symbol `[X^0 \cdot Y^{2-k}, (u,v)]`. + - 2-elements list -- given a list ``[alpha, beta]``, + where `\alpha` and `\beta` are (coercible to) + cusps, return the modular symbol `\{\alpha, \beta\}`. When + the weight `k > 2` return + `Y^{k-2} \{\alpha, \beta\}`. - - 2-elements list -- Given a list ``[alpha, beta]``, - where `\alpha` and `\beta` are (coercible to) - cusps, return the modular symbol `\{\alpha, \beta\}`. When - the weight `k > 2` return - `Y^{k-2} \{\alpha, \beta\}`. + - 3-element list -- given a list ``[i, alpha, beta]``, + where `i` is an integer, and `\alpha`, + `\beta` are (coercible to) cusps, return the modular symbol + `X^i Y^{k-2-i} \{\alpha, \beta\}`. - - 3-element list -- Given a list ``[i, alpha, beta]``, - where `i` is an integer, and `\alpha`, - `\beta` are (coercible to) cusps, return the modular symbol - `X^i Y^{k-2-i} \{\alpha, \beta\}`. - - If our list is ``[f, alpha, beta]``, where `f` - is a homogeneous polynomial in two variables of degree k-2 with - integer coefficients, and alpha and beta are cusps, return the - corresponding sum of modular symbols as an element of self. So if - `f = \sum_{i=0}^{k-2} a_i X^i Y^{k-2-i}`, return - `\sum_{i=0}^{k-2} a_i * [ i, alpha, beta ]`. + If our list is ``[f, alpha, beta]``, where `f` + is a homogeneous polynomial in two variables of degree k-2 with + integer coefficients, and alpha and beta are cusps, return the + corresponding sum of modular symbols as an element of ``self``. So if + `f = \sum_{i=0}^{k-2} a_i X^i Y^{k-2-i}`, return + `\sum_{i=0}^{k-2} a_i * [ i, alpha, beta ]`. EXAMPLES:: @@ -509,8 +502,8 @@ def _action_on_modular_symbols(self, g): INPUT: - `g` (list) -- `g=[a,b,c,d]` where `a,b,c,d` are integers - defining a `2\times2` integer matrix. + - ``g`` -- list; `g=[a,b,c,d]` where `a,b,c,d` are integers + defining a `2\times2` integer matrix OUTPUT: @@ -543,10 +536,10 @@ def manin_symbol(self, x, check=True): INPUT: - - ``x`` (list) -- either `[u,v]` or `[i,u,v]`, where `0\le + - ``x`` -- list; either `[u,v]` or `[i,u,v]`, where `0\le i\le k-2` where `k` is the weight, and `u`,`v` are integers defining a valid element of `\mathbb{P}^1(N)`, where `N` is - the level. + the level OUTPUT: @@ -592,9 +585,9 @@ def _modular_symbol_0_to_alpha(self, alpha, i=0): INPUT: - - ``alpha`` (rational or Infinity) -- a cusp + - ``alpha`` -- rational or Infinity a cusp - - ``i`` (int, default 0) -- the degree of the symbol + - ``i`` -- integer (default: 0); the degree of the symbol OUTPUT: @@ -687,7 +680,7 @@ def modular_symbol(self, x, check=True): INPUT: - - ``x`` (list) -- a list of either 2 or 3 entries: + - ``x`` -- list of either 2 or 3 entries: - 2 entries: `[\alpha, \beta]` where `\alpha` and `\beta` are cusps; @@ -695,7 +688,7 @@ def modular_symbol(self, x, check=True): - 3 entries: `[i, \alpha, \beta]` where `0\le i\le k-2` and `\alpha` and `\beta` are cusps; - - ``check`` (bool, default: ``True``) -- flag that determines + - ``check`` -- boolean (default: ``True``); flag that determines whether the input ``x`` needs processing: use check=False for efficiency if the input ``x`` is a list of length 3 whose first entry is an Integer, and whose second and third @@ -772,13 +765,13 @@ def modular_symbol_sum(self, x, check=True): INPUT: - - ``x`` (list) -- `[f, \alpha, \beta]` where `f = + - ``x`` -- list; `[f, \alpha, \beta]` where `f = \sum_{i=0}^{k-2} a_i X^i Y^{k-2-i}` is a homogeneous polynomial over `\ZZ` of degree `k` and `\alpha` and `\beta` are cusps. - - ``check`` (bool, default: ``True``) -- if True check the validity - of the input tuple ``x`` + - ``check`` -- boolean (default: ``True``); if ``True`` check the + validity of the input tuple ``x`` OUTPUT: @@ -830,7 +823,7 @@ def _compute_dual_hecke_matrix(self, n): INPUT: - - ``n`` (int) -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -853,15 +846,15 @@ def _compute_hecke_matrix_prime(self, p, rows=None): INPUT: - - ``p`` (int) -- a prime number. + - ``p`` -- integer; a prime number - - ``rows`` (list or None (default)) -- if not None, a list of - the rows which should be computed; otherwise the complete - matrix will be computed, + - ``rows`` -- list or ``None`` (default); if not ``None``, a list of + the rows which should be computed, otherwise the complete + matrix will be computed - .. note:: + .. NOTE:: - `p` does not have to be, prime despite the function name. + `p` does not have to be prime despite the function name. OUTPUT: @@ -1013,21 +1006,18 @@ def __heilbronn_operator(self, M, H, t=1): r""" Return the matrix function to the space `M` defined by `H`, `t`. - .. note:: + .. NOTE:: Users will instead use the simpler interface defined, for example, by ``hecke_matrix()`` (see examples). INPUT: + - ``M`` -- ModularSymbols; codomain (a space of modular symbols) - - ``M`` (ModularSymbols) -- codomain (a space of modular - symbols); - - - ``H`` (list) -- a list of matrices in `M_2(\ZZ)`; - - - ``t`` (int, default 1) -- an integer. + - ``H`` -- list of matrices in `M_2(\ZZ)` + - ``t`` -- integer (default: 1) OUTPUT: @@ -1054,8 +1044,6 @@ def __heilbronn_operator(self, M, H, t=1): [ 0 2 -1 2 0] [ 0 0 0 -3 2] [ 0 0 0 0 1] - - """ MS = MatrixSpace(self.base_ring(), self.dimension(), M.dimension()) @@ -1143,7 +1131,7 @@ def _matrix_of_operator_on_modular_symbols(self, codomain, R): r""" Return the matrix of a modular symbols operator. - .. note:: + .. NOTE:: Users will usually instead use the simpler interface defined, for example, by ``hecke_matrix()`` (see examples), @@ -1152,19 +1140,18 @@ def _matrix_of_operator_on_modular_symbols(self, codomain, R): INPUT: - - ``codomain`` -- space of modular symbols - - - ``R`` (list) -- a list of lists `[a,b,c,d]` of length 4, - which we view as elements of `GL_2(`QQ)`. + - ``codomain`` -- space of modular symbols + - ``R`` -- list of lists `[a,b,c,d]` of length 4, + which we view as elements of `GL_2(`QQ)` OUTPUT: - -- (matrix) The matrix of the operator + The matrix of the operator .. MATH:: - x \mapsto \sum_{g in R} g.x, + x \mapsto \sum_{g in R} g.x, where `g.x` is the formal linear fractional transformation on modular @@ -1179,7 +1166,6 @@ def _matrix_of_operator_on_modular_symbols(self, codomain, R): [ 0 3 0 5 -2] [ 0 -3 1 -5 3] [ 0 0 2 3 -3] - """ rows = [] for b in self.basis(): @@ -1199,12 +1185,10 @@ def _compute_atkin_lehner_matrix(self, d): INPUT: - - ``d`` (int) -- an integer that divides the level. + - ``d`` -- integer that divides the level - OUTPUT: - - (matrix) The matrix of the operator `W_d` with respect to - the standard basis. + OUTPUT: the matrix of the operator `W_d` with respect to the standard + basis EXAMPLES: An example at level 29:: @@ -1409,17 +1393,16 @@ def cuspidal_submodule(self): def _degeneracy_raising_matrix(self, M, t): r""" - Return the matrix of the level-raising degeneracy map from self to M, + Return the matrix of the level-raising degeneracy map from ``self`` to M, of index t. This is calculated by composing the level-raising matrix for `t = 1` with a Hecke operator. INPUT: - - ``M`` (int) -- a space of modular symbols whose level is an integer - multiple of the level of self + - ``M`` -- integer; a space of modular symbols whose level is an + integer multiple of the level of ``self`` - - ``t`` (int) -- a positive integer dividing the quotient of the two - levels. + - ``t`` -- positive integer dividing the quotient of the two levels OUTPUT: @@ -1465,7 +1448,7 @@ def _degeneracy_raising_matrix_1(self, M): Return the matrix of the degeneracy map to the given level (which must be a multiple of the level of self). - .. note:: + .. NOTE:: Not implemented in the base class, only in the derived classes. @@ -1479,21 +1462,21 @@ def _degeneracy_raising_matrix_1(self, M): def _degeneracy_lowering_matrix(self, M, t): r""" - Return the matrix of the level-lowering degeneracy map from self to M. + Return the matrix of the level-lowering degeneracy map from ``self`` to M. INPUT: - ``M`` -- a modular symbols space whose level divides the level of - self + ``self`` - - ``t`` (int) -- a positive integer dividing the quotient of the - levels. + - ``t`` -- integer; a positive integer dividing the quotient of the + levels OUTPUT: - (matrix) The matrix of the degeneracy map from this space to the space + The matrix of the degeneracy map from this space to the space `M` of index `t`, where `t` is a divisor of the quotient of the levels - of self and `M`. + of ``self`` and `M`. EXAMPLES:: @@ -1516,9 +1499,7 @@ def rank(self): """ Return the rank of this modular symbols ambient space. - OUTPUT: - - (int) The rank of this space of modular symbols. + OUTPUT: integer; the rank of this space of modular symbols EXAMPLES:: @@ -1564,19 +1545,15 @@ def eisenstein_submodule(self): def element(self, x): """ - Creates and returns an element of self from a modular symbol, if + Create and return an element of ``self`` from a modular symbol, if possible. INPUT: + - ``x`` -- an object of one of the following types: + ModularSymbol, ManinSymbol - - ``x`` -- an object of one of the following types: - ModularSymbol, ManinSymbol. - - - OUTPUT: - - ModularSymbol - a modular symbol with parent self. + OUTPUT: ModularSymbol - a modular symbol with parent self EXAMPLES:: @@ -1637,7 +1614,7 @@ def dual_star_involution_matrix(self): def factorization(self): r""" Return a list of pairs `(S,e)` where `S` is spaces - of modular symbols and self is isomorphic to the direct sum of the + of modular symbols and ``self`` is isomorphic to the direct sum of the `S^e` as a module over the *anemic* Hecke algebra adjoin the star involution. The cuspidal `S` are all simple, but the Eisenstein factors need not be simple. @@ -1800,7 +1777,7 @@ def factorization(self): def is_cuspidal(self): r""" - Return True if this space is cuspidal, else False. + Return ``True`` if this space is cuspidal, else ``False``. EXAMPLES:: @@ -1823,7 +1800,7 @@ def is_cuspidal(self): def is_eisenstein(self): r""" - Return True if this space is Eisenstein, else False. + Return ``True`` if this space is Eisenstein, else ``False``. EXAMPLES:: @@ -1849,11 +1826,8 @@ def manin_symbols_basis(self): A list of Manin symbols that form a basis for the ambient space ``self``. - OUTPUT: - - - ``list`` -- a list of 2-tuples (if the weight is 2) - or 3-tuples, which represent the Manin symbols basis for self. - + OUTPUT: list of 2-tuples (if the weight is 2) or 3-tuples, which + represent the Manin symbols basis for ``self`` EXAMPLES:: @@ -1927,7 +1901,7 @@ def modular_symbols_of_sign(self, sign): INPUT: - - ``sign`` (int) -- A sign (`+1`, `-1` or `0`). + - ``sign`` -- integer; a sign (`+1`, `-1` or `0`) OUTPUT: @@ -1958,7 +1932,7 @@ def modular_symbols_of_weight(self, k): INPUT: - - ``k`` (int) -- A positive integer. + - ``k`` -- positive integer OUTPUT: @@ -1978,21 +1952,17 @@ def modular_symbols_of_weight(self, k): def _compute_sign_submodule(self, sign, compute_dual=True): r""" - Return the subspace of self that is fixed under the star + Return the subspace of ``self`` that is fixed under the star involution. INPUT: + - ``sign`` -- integer (either -1 or +1) - - ``sign`` -- int (either -1 or +1) - - - ``compute_dual`` -- bool (default: ``True``) also - compute dual subspace. This are useful for many algorithms. - + - ``compute_dual`` -- boolean (default: ``True``); also + compute dual subspace. This is useful for many algorithms. - OUTPUT: - - A subspace of modular symbols + OUTPUT: a subspace of modular symbols EXAMPLES:: @@ -2048,12 +2018,9 @@ def _compute_diamond_matrix(self, d): INPUT: - - `d` -- integer + - ``d`` -- integer - OUTPUT: - - - ``matrix`` -- the matrix of the diamond bracket operator - on this space. + OUTPUT: the matrix of the diamond bracket operator on this space EXAMPLES:: @@ -2093,20 +2060,17 @@ def submodule(self, M, dual_free_module=None, check=True): INPUT: + - ``M`` -- either a submodule of this ambient free module, or + generators for a submodule - - ``M`` -- either a submodule of this ambient free module, or - generators for a submodule; - - - ``dual_free_module`` (bool, default None) -- this may be - useful to speed up certain calculations; it is the - corresponding submodule of the ambient dual module; + - ``dual_free_module`` -- boolean (default: ``None``); this may be + useful to speed up certain calculations; it is the corresponding + submodule of the ambient dual module; - - ``check`` (bool, default: ``True``) -- if True, check that `M` is - a submodule, i.e. is invariant under all Hecke operators. + - ``check`` -- boolean (default: ``True``); if ``True``, check that `M` + is a submodule, i.e. is invariant under all Hecke operators - OUTPUT: - - A subspace of this modular symbol space. + OUTPUT: a subspace of this modular symbol space EXAMPLES:: @@ -2122,7 +2086,7 @@ def submodule(self, M, dual_free_module=None, check=True): sage: M.submodule([M.0 - 1/5*M.2]) Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field - .. note:: + .. NOTE:: It would make more sense to only check that `M` is invariant under the Hecke operators with index coprime to the level. @@ -2146,9 +2110,9 @@ def twisted_winding_element(self, i, eps): INPUT: - - ``i`` (int) -- an integer, `0\le i\le k-2` where `k` is the weight. + - ``i`` -- integer; `0\le i\le k-2` where `k` is the weight - - ``eps`` (character) -- a Dirichlet character + - ``eps`` -- character; a Dirichlet character OUTPUT: @@ -2158,7 +2122,7 @@ def twisted_winding_element(self, i, eps): \sum_{a \in (\ZZ/m\ZZ)^\times} \varepsilon(a) * [ i, 0, a/m ]. - .. note:: + .. NOTE:: This will only work if the base ring of the modular symbol space contains the character values. @@ -2190,13 +2154,12 @@ def integral_structure(self, algorithm='default'): INPUT: + - ``algorithm`` -- string (default: ``'default'``, choose + heuristically) - - ``algorithm`` -- string (default: 'default', choose - heuristically) - - - ``'pari'`` -- use pari for the HNF computation + - ``'pari'`` -- use pari for the HNF computation - - ``'padic'`` -- use p-adic algorithm (only good for + - ``'padic'`` -- use `p`-adic algorithm (only good for dense case) @@ -2306,17 +2269,12 @@ class of cuspidal newforms in this ambient space. INPUT: - - - ``v`` -- list of positive integers - + - ``v`` -- list of positive integers OUTPUT: - - - ``list`` -- of pairs (E, x), where E\*x is a vector - with entries the eigenvalues `a_n` for - `n \in v`. - + List of pairs (E, x), where ``E*x`` is a vector with entries the + eigenvalues `a_n` for `n \in v`. EXAMPLES:: @@ -2430,7 +2388,7 @@ def _pari_pairing(self): E\colon M \times P \to K. - OUTPUT: The matrix of the bilinear map `E`. + OUTPUT: the matrix of the bilinear map `E` This is currently only implemented for spaces of modular symbols of trivial character. @@ -2489,7 +2447,7 @@ def _pari_tensor(self): T \in P \otimes_K M. - OUTPUT: The matrix of the element `T \in P \otimes_K M`. + OUTPUT: the matrix of the element `T \in P \otimes_K M`. This is the inverse of the matrix returned by :meth:`_pari_pairing`. @@ -2534,15 +2492,13 @@ class ModularSymbolsAmbient_wtk_g0(ModularSymbolsAmbient): INPUT: + - ``N`` -- integer; the level - - ``N`` -- int, the level - - - ``k`` -- integer weight = 2. - - - ``sign`` -- int, either -1, 0, or 1 + - ``k`` -- integer; weight = 2 - - ``F`` -- field + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- field EXAMPLES:: @@ -2567,15 +2523,13 @@ def __init__(self, N, k, sign, F, custom_init=None, category=None): INPUT: + - ``N`` -- integer; the level - - ``N`` -- int, the level + - ``k`` -- integer; weight = 2 - - ``k`` -- integer weight = 2. - - - ``sign`` -- int, either -1, 0, or 1 - - - ``F`` -- field + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- field EXAMPLES:: @@ -2668,12 +2622,10 @@ def _degeneracy_raising_matrix_1(self, M): INPUT: - - ``M`` -- A space of Gamma0 modular symbols of the same weight as - self, with level an integer multiple of the level of self. + - ``M`` -- a space of Gamma0 modular symbols of the same weight as + ``self``, with level an integer multiple of the level of ``self`` - OUTPUT: - - (matrix) The matrix of the degeneracy raising map to `M`. + OUTPUT: the matrix of the degeneracy raising map to `M` EXAMPLES:: @@ -2789,15 +2741,11 @@ def _hecke_images(self, i, v): INPUT: + - ``i`` -- nonnegative integer - - ``i`` -- nonnegative integer - - - ``v`` -- a list of positive integer - + - ``v`` -- list of positive integer - OUTPUT: - - - ``matrix`` -- whose rows are the Hecke images + OUTPUT: ``matrix`` -- whose rows are the Hecke images EXAMPLES:: @@ -2865,10 +2813,9 @@ class ModularSymbolsAmbient_wt2_g0(ModularSymbolsAmbient_wtk_g0): INPUT: - - ``N`` -- int, the level - - - ``sign`` -- int, either -1, 0, or 1 + - ``N`` -- integer; the level + - ``sign`` -- integer; either -1, 0, or 1 OUTPUT: @@ -2882,14 +2829,13 @@ class ModularSymbolsAmbient_wt2_g0(ModularSymbolsAmbient_wtk_g0): """ def __init__(self, N, sign, F, custom_init=None, category=None): """ - Initialize a space of modular symbols. INPUT: + Initialize a space of modular symbols. INPUT: - - ``N`` -- int, the level - - - ``sign`` -- int, either -1, 0, or 1 + - ``N`` -- integer; the level + - ``sign`` -- integer; either -1, 0, or 1 OUTPUT: @@ -3060,11 +3006,9 @@ def _hecke_image_of_ith_basis_vector(self, n, i): INPUT: - - ``n`` -- an integer which should be prime. + - ``n`` -- integer which should be prime - OUTPUT: - - - ``modular symbol`` -- element of this ambient space + OUTPUT: ``modular symbol`` -- element of this ambient space EXAMPLES:: @@ -3091,17 +3035,11 @@ def _hecke_images(self, i, v): INPUT: + - ``i`` -- nonnegative integer - - ``i`` -- nonnegative integer - - - ``v`` -- a list of positive integer - - - OUTPUT: - - - - ``matrix`` -- whose rows are the Hecke images + - ``v`` -- list of positive integer + OUTPUT: matrix whose rows are the Hecke images EXAMPLES:: @@ -3129,15 +3067,13 @@ class ModularSymbolsAmbient_wtk_g1(ModularSymbolsAmbient): r""" INPUT: + - ``level`` -- integer; the level - - ``level`` -- int, the level - - - ``weight`` -- int, the weight = 2 - - - ``sign`` -- int, either -1, 0, or 1 + - ``weight`` -- integer; the weight = 2 - - ``F`` -- field + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- field EXAMPLES:: @@ -3158,15 +3094,13 @@ def __init__(self, level, weight, sign, F, custom_init=None, category=None): INPUT: + - ``level`` -- integer; the level - - ``level`` -- int, the level - - - ``weight`` -- int, the weight = 2 - - - ``sign`` -- int, either -1, 0, or 1 + - ``weight`` -- integer; the weight = 2 - - ``F`` -- field + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- field EXAMPLES:: @@ -3375,16 +3309,13 @@ def __init__(self, group, weight, sign, F, custom_init=None, category=None): INPUT: + - ``group`` -- a congruence subgroup `\Gamma_H(N)` - - ``group`` -- a congruence subgroup - `\Gamma_H(N)`. + - ``weight`` -- integer; the weight = 2 - - ``weight`` -- int, the weight = 2 - - - ``sign`` -- int, either -1, 0, or 1 - - - ``F`` -- field + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- field EXAMPLES:: @@ -3431,7 +3362,6 @@ def _cuspidal_submodule_dimension_formula(self): sage: ModularSymbols(GammaH(15,[4]),2)._cuspidal_submodule_dimension_formula() is None True - """ return None @@ -3527,17 +3457,15 @@ def __init__(self, eps, weight, sign, base_ring, custom_init=None, category=None INPUT: + - ``eps`` -- dirichlet.DirichletCharacter, the + "Nebentypus" character - - ``eps`` -- dirichlet.DirichletCharacter, the - "Nebentypus" character. - - - ``weight`` -- int, the weight = 2 - - - ``sign`` -- int, either -1, 0, or 1 + - ``weight`` -- integer; the weight = 2 - - ``base_ring`` -- the base ring. It must be possible to change the ring - of the character to this base ring (not always canonically). + - ``sign`` -- integer; either -1, 0, or 1 + - ``base_ring`` -- the base ring; it must be possible to change the ring + of the character to this base ring (not always canonically) EXAMPLES:: @@ -3640,20 +3568,18 @@ def _matrix_of_operator_on_modular_symbols(self, codomain, R, character_twist=Fa r""" INPUT: + - ``self`` -- this space of modular symbols - - ``self`` -- this space of modular symbols - - - ``codomain`` -- space of modular symbols - - - ``R`` -- list of lists [a,b,c,d] of length 4, which - we view as elements of GL_2(Q). + - ``codomain`` -- space of modular symbols + - ``R`` -- list of lists [a,b,c,d] of length 4, which + we view as elements of GL_2(Q) OUTPUT: a matrix, which represents the operator .. MATH:: - x \mapsto \sum_{g in R} g.x + x \mapsto \sum_{g in R} g.x, where g.x is the formal linear fractional transformation on modular @@ -3689,14 +3615,14 @@ def _degeneracy_raising_matrix_1(self, M): r""" Return the matrix of the degeneracy raising map to ``M``, which should be a space of modular symbols with level a multiple of the level of - self and with compatible character. + ``self`` and with compatible character. INPUT: - ``M`` -- a space of modular symbols with character, whose level - should be an integer multiple of the level of self, and whose + should be an integer multiple of the level of ``self``, and whose character should be the Dirichlet character at that level obtained by - extending the character of self. + extending the character of ``self``. The input is *not* sanity-checked in any way -- use with care! @@ -3805,7 +3731,7 @@ def modular_symbols_of_level(self, N): INPUT: - - ``N`` (int) -- a positive integer. + - ``N`` -- positive integer OUTPUT: @@ -3837,7 +3763,7 @@ def modular_symbols_of_sign(self, sign): INPUT: - - ``sign`` (int) -- A sign (`+1`, `-1` or `0`). + - ``sign`` -- integer; a sign (`+1`, `-1` or `0`) OUTPUT: @@ -3856,7 +3782,6 @@ def modular_symbols_of_sign(self, sign): Modular Symbols space of dimension 0 and level 5, weight 2, character [zeta4], sign 1, over Cyclotomic Field of order 4 and degree 2 sage: M.modular_symbols_of_sign(-1) Modular Symbols space of dimension 0 and level 5, weight 2, character [zeta4], sign -1, over Cyclotomic Field of order 4 and degree 2 - """ return modsym.ModularSymbols(self.character(), self.weight(), sign, self.base_ring()) @@ -3868,7 +3793,7 @@ def modular_symbols_of_weight(self, k): INPUT: - - ``k`` (int) -- A positive integer. + - ``k`` -- positive integer OUTPUT: @@ -3897,11 +3822,9 @@ def _hecke_images(self, i, v): - ``i`` -- nonnegative integer - - ``v`` -- a list of positive integer - - OUTPUT: + - ``v`` -- list of positive integer - - ``matrix`` -- whose rows are the Hecke images + OUTPUT: ``matrix`` -- whose rows are the Hecke images EXAMPLES:: diff --git a/src/sage/modular/modsym/boundary.py b/src/sage/modular/modsym/boundary.py index 093ba6a594f..16241c843aa 100644 --- a/src/sage/modular/modsym/boundary.py +++ b/src/sage/modular/modsym/boundary.py @@ -49,7 +49,7 @@ which means this class must vanish. Notice that this cannot be used to show that `[(1,0)]` or `[(0,1)]` is 0. -.. note:: +.. NOTE:: Special care must be taken when working with the images of the cusps 0 and `\infty` in `B_k(G)`. For all cusps *except* 0 and `\infty`, multiplying the @@ -64,7 +64,7 @@ - `[(1,0)] = \sigma \cdot [(-1,0)]` and `[(1,0)] = (-1)^k [(-1,0)]`, so `[(1,0)] = 0` whenever `\sigma \ne (-1)^k`. -.. note:: +.. NOTE:: For all the spaces of boundary symbols below, no work is done to determine the cusps for G at creation time. Instead, cusps are added as they are @@ -114,13 +114,11 @@ def __init__(self, parent, x): INPUT: + - ``parent`` -- BoundarySpace; a space of boundary + modular symbols - - ``parent`` -- BoundarySpace; a space of boundary - modular symbols - - - ``x`` -- a dict with integer keys and values in the - base field of parent. - + - ``x`` -- dictionary with integer keys and values in the + base field of parent EXAMPLES:: @@ -138,8 +136,8 @@ def __init__(self, parent, x): def coordinate_vector(self): r""" - Return self as a vector on the QQ-vector space with basis - self.parent()._known_cusps(). + Return ``self`` as a vector on the `\QQ`-vector space with basis + ``self.parent()._known_cusps()``. EXAMPLES:: @@ -180,7 +178,7 @@ def _repr_(self): def _add_(self, other): """ - Return self + other. Assumes that other is a BoundarySpaceElement. + Return ``self + other``. Assumes that other is a BoundarySpaceElement. EXAMPLES:: @@ -201,7 +199,7 @@ def _add_(self, other): def _sub_(self, other): """ - Return self - other. Assumes that other is a BoundarySpaceElement. + Return ``self - other``. Assumes that other is a BoundarySpaceElement. EXAMPLES:: @@ -222,10 +220,10 @@ def _sub_(self, other): def _rmul_(self, other): r""" - Return self \* other. + Return ``self * other``. Assumes that other can be coerced into - self.parent().base_ring(). + ``self.parent().base_ring()``. EXAMPLES:: @@ -243,10 +241,10 @@ def _rmul_(self, other): def _lmul_(self, other): r""" - Return other \* self. + Return ``other * self``. Assumes that other can be coerced into - self.parent().base_ring(). + ``self.parent().base_ring()``. EXAMPLES:: @@ -294,17 +292,14 @@ def __init__(self, INPUT: + - ``weight`` -- integer; the weight - - ``weight`` -- int, the weight - - - ``group`` -- arithgroup.congroup_generic.CongruenceSubgroup, a congruence - subgroup. + - ``group`` -- arithgroup.congroup_generic.CongruenceSubgroup, a + congruence subgroup - - ``sign`` -- int, either -1, 0, or 1 - - - ``base_ring`` -- rings.Ring (defaults to the - rational numbers) + - ``sign`` -- integer; either -1, 0, or 1 + - ``base_ring`` -- rings.Ring (defaults to the rational numbers) EXAMPLES:: @@ -596,7 +591,6 @@ def _cusp_index(self, cusp): - ``-2`` if ``cusp`` is equivalent to a cusp that's known to vanish from the relations in this space. - EXAMPLES:: sage: B = ModularSymbols(Gamma0(21), 4).boundary_space() @@ -624,15 +618,13 @@ def __init__(self, level, weight, sign, F): INPUT: + - ``level`` -- integer; the level - - ``level`` -- int, the level - - - ``weight`` -- integer weight = 2. + - ``weight`` -- integer; weight = 2 - - ``sign`` -- int, either -1, 0, or 1 - - - ``F`` -- field + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- field EXAMPLES:: @@ -768,14 +760,13 @@ def __init__(self, level, weight, sign, F): INPUT: + - ``level`` -- integer; the level - - ``level`` -- int, the level - - - ``weight`` -- int, the weight = 2 + - ``weight`` -- integer; the weight = 2 - - ``sign`` -- int, either -1, 0, or 1 + - ``sign`` -- integer; either -1, 0, or 1 - - ``F`` -- base ring + - ``F`` -- base ring EXAMPLES:: @@ -969,15 +960,13 @@ def __init__(self, group, weight, sign, F): INPUT: + - ``group`` -- congruence subgroup Gamma_H(N) - - ``group`` -- congruence subgroup Gamma_H(N). - - - ``weight`` -- int, the weight = 2 + - ``weight`` -- integer; the weight = 2 - - ``sign`` -- int, either -1, 0, or 1 - - - ``F`` -- base ring + - ``sign`` -- integer; either -1, 0, or 1 + - ``F`` -- base ring EXAMPLES:: @@ -1022,8 +1011,8 @@ def _repr_(self): def _is_equiv(self, c1, c2): """ - Return a pair of the form (b, t), where b is True if c1 and c2 are - equivalent cusps for self, and False otherwise, and t gives extra + Return a pair of the form (b, t), where b is ``True`` if c1 and c2 are + equivalent cusps for ``self``, and ``False`` otherwise, and t gives extra information about the equivalence between c1 and c2. EXAMPLES:: @@ -1223,14 +1212,12 @@ def __init__(self, eps, weight, sign=0): INPUT: + - ``eps`` -- dirichlet.DirichletCharacter, the + "Nebentypus" character - - ``eps`` -- dirichlet.DirichletCharacter, the - "Nebentypus" character. - - - ``weight`` -- int, the weight = 2 - - - ``sign`` -- int, either -1, 0, or 1 + - ``weight`` -- integer; the weight = 2 + - ``sign`` -- integer; either -1, 0, or 1 EXAMPLES:: @@ -1272,9 +1259,9 @@ def _repr_(self): def _is_equiv(self, c1, c2): """ - Return a pair (b, t), where b is True if c1 and c2 are equivalent - cusps for self, and False otherwise, and t gives extra information - about the equivalence of c1 and c2. + Return a pair (b, t), where b is ``True`` if c1 and c2 are equivalent + cusps for ``self``, and ``False`` otherwise, and t gives extra + information about the equivalence of c1 and c2. EXAMPLES:: diff --git a/src/sage/modular/modsym/element.py b/src/sage/modular/modsym/element.py index 21b1ecb181b..9386ebd0d11 100644 --- a/src/sage/modular/modsym/element.py +++ b/src/sage/modular/modsym/element.py @@ -31,7 +31,7 @@ def is_ModularSymbolsElement(x) -> bool: r""" - Return True if x is an element of a modular symbols space. + Return ``True`` if x is an element of a modular symbols space. EXAMPLES:: @@ -51,23 +51,22 @@ def is_ModularSymbolsElement(x) -> bool: return isinstance(x, ModularSymbolsElement) -def set_modsym_print_mode(mode="manin"): +def set_modsym_print_mode(mode='manin'): r""" Set the mode for printing of elements of modular symbols spaces. INPUT: - - ``mode`` -- a string. The possibilities are as - follows: + - ``mode`` -- string; the possibilities are as follows: - - ``'manin'`` -- (the default) formal sums of Manin - symbols [P(X,Y),(u,v)] + - ``'manin'`` -- (the default) formal sums of Manin + symbols [P(X,Y),(u,v)] - - ``'modular'`` -- formal sums of Modular symbols - P(X,Y)\*alpha,beta, where alpha and beta are cusps + - ``'modular'`` -- formal sums of Modular symbols + P(X,Y)\*alpha,beta, where alpha and beta are cusps - - ``'vector'`` -- as vectors on the basis for the - ambient space + - ``'vector'`` -- as vectors on the basis for the + ambient space OUTPUT: none @@ -107,8 +106,8 @@ def __init__(self, parent, x, check=True): - ``parent`` -- a space of modular symbols - ``x`` -- a free module element that represents the modular - symbol in terms of a basis for the ambient space (not in - terms of a basis for parent!) + symbol in terms of a basis for the ambient space (not in + terms of a basis for parent!) EXAMPLES:: @@ -132,7 +131,7 @@ def __init__(self, parent, x, check=True): def _repr_(self): r""" - String representation of self. The output will depend on the global + String representation of ``self``. The output will depend on the global modular symbols print mode setting controlled by the function ``set_modsym_print_mode``. @@ -157,7 +156,8 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation of self. The output will be determined by the print mode setting set using ``set_modsym_print_mode``. + LaTeX representation of ``self``. The output will be determined by the + print mode setting set using ``set_modsym_print_mode``. EXAMPLES:: @@ -186,7 +186,7 @@ def _latex_(self): def _add_(self, right): r""" - Sum of self and other. + Sum of ``self`` and ``other``. EXAMPLES:: @@ -200,7 +200,7 @@ def _add_(self, right): def _rmul_(self, other): r""" - Right-multiply self by other. + Right-multiply ``self`` by ``other``. EXAMPLES:: @@ -219,7 +219,7 @@ def _rmul_(self, other): def _lmul_(self, left): r""" - Left-multiply self by other. + Left-multiply ``self`` by ``other``. EXAMPLES:: @@ -252,7 +252,7 @@ def _neg_(self): def _sub_(self, other): r""" - Subtract other from self. + Subtract ``other`` from ``self``. EXAMPLES:: @@ -272,7 +272,8 @@ def _sub_(self, other): def list(self): r""" - Return a list of the coordinates of self in terms of a basis for the ambient space. + Return a list of the coordinates of ``self`` in terms of a basis for + the ambient space. EXAMPLES:: @@ -283,7 +284,7 @@ def list(self): def manin_symbol_rep(self): """ - Return a representation of self as a formal sum of Manin symbols. + Return a representation of ``self`` as a formal sum of Manin symbols. EXAMPLES:: diff --git a/src/sage/modular/modsym/g1list.py b/src/sage/modular/modsym/g1list.py index 4485a52814a..23ad499f3ad 100644 --- a/src/sage/modular/modsym/g1list.py +++ b/src/sage/modular/modsym/g1list.py @@ -51,7 +51,7 @@ def __init__(self, N): def __richcmp__(self, other, op): r""" - Compare self to other. + Compare ``self`` to ``other``. EXAMPLES:: @@ -120,7 +120,7 @@ def normalize(self, u, v): `\Gamma_0` (where the problem is rather harder). This will only make sense if `{\rm gcd}(u, v, N) = 1`; otherwise the - output will not be an element of self. + output will not be an element of ``self``. EXAMPLES:: diff --git a/src/sage/modular/modsym/ghlist.py b/src/sage/modular/modsym/ghlist.py index 62989e22105..916374a97b2 100644 --- a/src/sage/modular/modsym/ghlist.py +++ b/src/sage/modular/modsym/ghlist.py @@ -93,7 +93,7 @@ def __len__(self): def __repr__(self): """ - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -122,7 +122,7 @@ def normalize(self, u, v): is equivalent to `(u', v')`. This will only make sense if `{\rm gcd}(u, v, N) = 1`; otherwise the - output will not be an element of self. + output will not be an element of ``self``. EXAMPLES:: diff --git a/src/sage/modular/modsym/hecke_operator.py b/src/sage/modular/modsym/hecke_operator.py index 818de55e97e..b12c5020df7 100644 --- a/src/sage/modular/modsym/hecke_operator.py +++ b/src/sage/modular/modsym/hecke_operator.py @@ -23,7 +23,7 @@ def apply_sparse(self, x): """ Return the image of ``x`` under ``self``. - If ``x`` is not in ``self.domain()``, raise a :class:`TypeError`. + If ``x`` is not in ``self.domain()``, raise a :exc:`TypeError`. EXAMPLES:: diff --git a/src/sage/modular/modsym/heilbronn.pyx b/src/sage/modular/modsym/heilbronn.pyx index c9c7a93b8a0..82adf9efa20 100644 --- a/src/sage/modular/modsym/heilbronn.pyx +++ b/src/sage/modular/modsym/heilbronn.pyx @@ -104,7 +104,7 @@ cdef class Heilbronn: (This function is automatically called during initialization.) - .. note:: + .. NOTE:: This function must be overridden by all derived classes! @@ -173,9 +173,9 @@ cdef class Heilbronn: r""" INPUT: - - ``u``, ``v``, ``N`` -- integers + - ``u``, ``v``, ``N`` -- integers - - ``a``, ``b`` -- preallocated int arrays of the length of ``self`` + - ``a``, ``b`` -- preallocated integer arrays of the length of ``self`` OUTPUT: sets the entries of `a`, `b` @@ -210,10 +210,10 @@ cdef class Heilbronn: r""" INPUT: - - ``ans`` -- ``fmpz_poly_t*``; pre-allocated an - initialized array of ``self.length`` ``fmpz_poly_t``s - - ``i`` -- integer - - ``k`` -- integer + - ``ans`` -- ``fmpz_poly_t*``; pre-allocated an + initialized array of ``self.length`` ``fmpz_poly_t``s + - ``i`` -- integer + - ``k`` -- integer OUTPUT: sets entries of ``ans`` """ @@ -230,7 +230,7 @@ cdef class Heilbronn: Return a list of pairs `((c,d),m)`, which is obtained as follows: 1) Compute the images `(a,b)` of the vector `(u,v) \pmod N` acted on by - each of the HeilbronnCremona matrices in self. + each of the HeilbronnCremona matrices in ``self``. 2) Reduce each `(a,b)` to canonical form `(c,d)` using ``p1normalize``. @@ -383,7 +383,7 @@ cdef class HeilbronnCremona(Heilbronn): # NOTE: In C, -p/2 means "round toward 0", but in Python it # means "round down." sig_on() - for r in range(-p/2, p/2+1): + for r in range(-p // 2, p // 2 + 1): x1 = p x2 = -r y1 = 0 @@ -394,7 +394,7 @@ cdef class HeilbronnCremona(Heilbronn): x3 = 0 y3 = 0 q = 0 - list_append4(L, x1,x2,y1,y2) + list_append4(L, x1, x2, y1, y2) while b: q = roundf(a / b) c = a - b*q @@ -406,8 +406,8 @@ cdef class HeilbronnCremona(Heilbronn): y3 = q*y2 - y1 y1 = y2 y2 = y3 - list_append4(L, x1,x2, y1,y2) - self.length = L.i/4 + list_append4(L, x1, x2, y1, y2) + self.length = L.i // 4 sig_off() @@ -491,7 +491,7 @@ cdef class HeilbronnMerel(Heilbronn): for a in range(1, n+1): ## We have ad-bc=n so c=0 and ad=n, or b=(ad-n)/c ## Must have ad - n >= 0, so d must be >= Ceiling(n/a). - q = n/a + q = n // a if q*a == n: d = q for b in range(a): @@ -503,10 +503,10 @@ cdef class HeilbronnMerel(Heilbronn): ## Divisor c of bc must satisfy Floor(bc/c) lt a and c lt d. ## c ge (bc div a + 1) <=> Floor(bc/c) lt a (for integers) ## c le d - 1 <=> c lt d - for c in range(bc/a + 1, d): + for c in range(bc // a + 1, d): if bc % c == 0: - list_append4(L,a,bc/c,c,d) - self.length = L.i/4 + list_append4(L, a, bc // c, c, d) + self.length = L.i // 4 sig_off() @@ -522,11 +522,10 @@ def hecke_images_gamma0_weight2(int u, int v, int N, indices, R): INPUT: - ``u``, ``v``, ``N`` -- integers so that `\gcd(u,v,N) = 1` - - ``indices`` -- a list of positive integers + - ``indices`` -- list of positive integers - ``R`` -- matrix over `\QQ` that writes each elements of `\textnormal{P1} = \textnormal{P1List}(N)` in terms of a - subset of `\textnormal{P1}`. - + subset of `\textnormal{P1}` OUTPUT: a dense matrix whose columns are the images `T_n(x)` for `n` in indices and `x` the Manin symbol `(u,v)`, expressed @@ -549,7 +548,6 @@ def hecke_images_gamma0_weight2(int u, int v, int N, indices, R): sage: D = N.decomposition() sage: D[1].q_eigenform(10, 'a') # indirect doctest q + 4*q^2 + 2*q^3 + 6*q^5 + q^6 + 5*q^7 + 6*q^8 + q^9 + O(q^10) - """ cdef p1list.P1List P1 = p1list.P1List(N) @@ -648,13 +646,12 @@ def hecke_images_nonquad_character_weight2(int u, int v, int N, indices, chi, R) INPUT: - ``u``, ``v``, ``N`` -- integers so that `\gcd(u,v,N) = 1` - - ``indices`` -- a list of positive integers + - ``indices`` -- list of positive integers - ``chi`` -- a Dirichlet character that takes values - in a nontrivial extension of `\QQ`. + in a nontrivial extension of `\QQ` - ``R`` -- matrix over `\QQ` that writes each elements of `\textnormal{P1} = \textnormal{P1List}(N)` in terms of a - subset of `\textnormal{P1}`. - + subset of `\textnormal{P1}` OUTPUT: a dense matrix with entries in the field `\QQ(\chi)` (the values of `\chi`) whose columns are the images `T_n(x)` for `n` in @@ -754,12 +751,11 @@ def hecke_images_quad_character_weight2(int u, int v, int N, indices, chi, R): INPUT: - ``u``, ``v``, ``N`` -- integers so that `\gcd(u,v,N) = 1` - - ``indices`` -- a list of positive integers + - ``indices`` -- list of positive integers - ``chi`` -- a Dirichlet character that takes values in `\QQ` - ``R`` -- matrix over `\QQ(\chi)` that writes each elements of `\textnormal{P1} = \textnormal{P1List}(N)` in terms of a subset - of `\textnormal{P1}`. - + of `\textnormal{P1}` OUTPUT: a dense matrix with entries in the rational field `\QQ` (the values of `\chi`) whose columns are the images `T_n(x)` for `n` in @@ -852,13 +848,13 @@ def hecke_images_gamma0_weight_k(int u, int v, int i, int N, int k, indices, R): r""" INPUT: - - ``u``, ``v``, ``N`` -- integers so that `\gcd(u,v,N) = 1` - - ``i`` -- integer with `0 \le i \le k-2` - - ``k`` -- weight - - ``indices`` -- a list of positive integers - - ``R`` -- matrix over `\QQ` that writes each elements of - `\textnormal{P1} = \textnormal{P1List}(N)` in terms of a - subset of `\textnormal{P1}`. + - ``u``, ``v``, ``N`` -- integers so that `\gcd(u,v,N) = 1` + - ``i`` -- integer with `0 \le i \le k-2` + - ``k`` -- weight + - ``indices`` -- list of positive integers + - ``R`` -- matrix over `\QQ` that writes each elements of + `\textnormal{P1} = \textnormal{P1List}(N)` in terms of a + subset of `\textnormal{P1}` OUTPUT: a dense matrix with rational entries whose columns are the images `T_n(x)` for `n` in indices and `x` the Manin symbol diff --git a/src/sage/modular/modsym/manin_symbol.pyx b/src/sage/modular/modsym/manin_symbol.pyx index 434aa370e18..7a98b5d1a40 100644 --- a/src/sage/modular/modsym/manin_symbol.pyx +++ b/src/sage/modular/modsym/manin_symbol.pyx @@ -92,7 +92,6 @@ cdef class ManinSymbol(Element): sage: s = ManinSymbol(m,(2,2,3)) sage: s.parent() Manin Symbol List of weight 8 for Gamma0(5) - """ def __init__(self, parent, t): r""" @@ -118,7 +117,6 @@ cdef class ManinSymbol(Element): sage: m = ManinSymbolList_gamma0(5,8) sage: s = ManinSymbol(m,(2,2,3)); s [X^2*Y^4,(2,3)] - """ Element.__init__(self, parent) (i, u, v) = t @@ -138,7 +136,6 @@ cdef class ManinSymbol(Element): sage: s = ManinSymbol(m, (2, 2, 3)) sage: loads(dumps(s)) (2,3) - """ return ManinSymbol, (self.parent(), self.tuple()) @@ -154,7 +151,6 @@ cdef class ManinSymbol(Element): sage: s = ManinSymbol(m,(2,2,3)) sage: loads(dumps(s)) (2,3) - """ self._parent = state['_ManinSymbol__parent'] (self.i, self.u, self.v) = state['_ManinSymbol__t'] @@ -293,7 +289,7 @@ cdef class ManinSymbol(Element): def apply(self, a,b,c,d): """ - Return the image of self under the matrix `[a,b;c,d]`. + Return the image of ``self`` under the matrix `[a,b;c,d]`. Not implemented for raw ManinSymbol objects, only for members of ManinSymbolLists. @@ -342,7 +338,6 @@ cdef class ManinSymbol(Element): [X^2*Y^4,(2,3)] sage: s.lift_to_sl2z() [1, 1, 2, 3] - """ if N is None: N = self.level() @@ -421,7 +416,6 @@ cdef class ManinSymbol(Element): sage: s = ManinSymbol(m,(2,2,3)) sage: s.weight() 8 - """ return self.parent().weight() @@ -437,7 +431,6 @@ cdef class ManinSymbol(Element): sage: s = ManinSymbol(m,(2,2,3)) sage: s.level() 5 - """ return self.parent().level() @@ -456,8 +449,6 @@ cdef class ManinSymbol(Element): sage: s = ManinSymbol(m,(2,2,3)) sage: s.modular_symbol_rep() 144*X^6*{1/3, 1/2} - 384*X^5*Y*{1/3, 1/2} + 424*X^4*Y^2*{1/3, 1/2} - 248*X^3*Y^3*{1/3, 1/2} + 81*X^2*Y^4*{1/3, 1/2} - 14*X*Y^5*{1/3, 1/2} + Y^6*{1/3, 1/2} - - """ # TODO: It would likely be much better to do this slightly more directly from sage.modular.modsym.modular_symbols import ModularSymbol diff --git a/src/sage/modular/modsym/manin_symbol_list.py b/src/sage/modular/modsym/manin_symbol_list.py index f2a26c68303..ebc40022031 100644 --- a/src/sage/modular/modsym/manin_symbol_list.py +++ b/src/sage/modular/modsym/manin_symbol_list.py @@ -165,7 +165,7 @@ def apply(self, j, X): def _apply_S_only_0pm1(self) -> bool: """ - Return True if the coefficient when applying the S relation is + Return ``True`` if the coefficient when applying the S relation is always 0, 1, or -1. This is useful for optimizing code in relation_matrix.py. @@ -311,7 +311,6 @@ def manin_symbol_list(self): ... [X^2,(3,1)], [X^2,(3,2)]] - """ import copy try: @@ -329,11 +328,11 @@ def manin_symbol(self, i): INPUT: - - ``i`` -- integer, a valid index of a symbol in this list + - ``i`` -- integer; a valid index of a symbol in this list OUTPUT: - :class:`ManinSymbol` -- the `i`'th Manin symbol in the list. + :class:`ManinSymbol` -- the `i`-th Manin symbol in the list. EXAMPLES:: @@ -363,7 +362,6 @@ def normalize(self, x): sage: from sage.modular.modsym.manin_symbol_list import ManinSymbolList sage: m = ManinSymbolList(6,P1List(11)) sage: m.normalize((0,6,7)) # not implemented in base class - """ raise NotImplementedError("Only implemented in derived classes") @@ -371,9 +369,7 @@ def weight(self): """ Return the weight of the Manin symbols in this :class:`ManinSymbolList`. - OUTPUT: - - integer -- the weight of the Manin symbols in the list. + OUTPUT: integer; the weight of the Manin symbols in the list EXAMPLES:: @@ -396,7 +392,7 @@ class ManinSymbolList_group(ManinSymbolList): - ``weight`` -- integer weight - ``syms`` -- something with ``normalize`` and ``list`` methods, - e.g. :class:`~sage.modular.modsym.p1list.P1List`. + e.g. :class:`~sage.modular.modsym.p1list.P1List` EXAMPLES:: @@ -415,7 +411,7 @@ def __init__(self, level, weight, syms): - ``weight`` -- integer weight - ``syms`` -- something with ``normalize`` and ``list`` - methods, e.g. :class:`~sage.modular.modsym.p1list.P1List`. + methods, e.g. :class:`~sage.modular.modsym.p1list.P1List` EXAMPLES:: @@ -463,12 +459,12 @@ def apply_S(self, j): INPUT: - - ``j`` -- (int) a symbol index + - ``j`` -- integer; a symbol index OUTPUT: ``(k, s)`` where k is the index of the symbol obtained by acting on the - `j`'th symbol with `S`, and `s` is the parity of the `j`'th symbol + `j`-th symbol with `S`, and `s` is the parity of the `j`-th symbol (a Python ``int``, either 1 or -1). EXAMPLES:: @@ -500,7 +496,7 @@ def apply_S(self, j): def _apply_S_only_0pm1(self): """ - Return True if the coefficient when applying the S relation is + Return ``True`` if the coefficient when applying the S relation is always 0, 1, or -1. This is useful for optimizing code in relation_matrix.py. @@ -518,12 +514,12 @@ def apply_I(self, j): INPUT: - - ``j`` -- (int) a symbol index + - ``j`` -- integer; a symbol index OUTPUT: ``(k, s)`` where k is the index of the symbol obtained by acting on the - `j`'th symbol with `I`, and `s` is the parity of the `j`'th symbol + `j`-th symbol with `I`, and `s` is the parity of the `j`-th symbol (a Python ``int``, either 1 or -1) EXAMPLES:: @@ -557,7 +553,7 @@ def apply_T(self, j): INPUT: - - ``j`` -- (int) a symbol index + - ``j`` -- integer; a symbol index OUTPUT: see documentation for apply() @@ -600,7 +596,7 @@ def apply_TT(self, j): INPUT: - - ``j`` -- (int) a symbol index + - ``j`` -- integer; a symbol index OUTPUT: see documentation for apply() @@ -643,7 +639,7 @@ def apply(self, j, m): INPUT: - - ``j`` -- (int) a symbol index + - ``j`` -- integer; a symbol index - ``m = [a, b, c, d]`` a list of 4 integers, which defines a 2x2 matrix @@ -651,7 +647,7 @@ def apply(self, j, m): a list of pairs `(j_i, \alpha_i)`, where each `\alpha_i` is a nonzero integer, `j_i` is an integer (index of the `j_i`-th Manin symbol), and - `\sum_i \alpha_i\*x_{j_i}` is the image of the j-th Manin symbol under + `\sum_i \alpha_i\*x_{j_i}` is the image of the `j`-th Manin symbol under the right action of the matrix [a,b;c,d]. Here the right action of `g = [a, b; c, d]` on a Manin symbol `[P(X,Y),(u,v)]` is `[P(aX+bY,cX+dY),(u,v)\*g]`. @@ -714,9 +710,9 @@ class ManinSymbolList_gamma0(ManinSymbolList_group): INPUT: - - ``level`` -- (integer): the level. + - ``level`` -- integer; the level - - ``weight`` -- (integer): the weight. + - ``weight`` -- integer; the weight EXAMPLES:: @@ -732,7 +728,7 @@ class ManinSymbolList_gamma0(ManinSymbolList_group): """ def __init__(self, level, weight): """ - Constructor for a ModularSymbolList for Gamma_0(N) + Constructor for a ModularSymbolList for Gamma_0(N). EXAMPLES:: @@ -766,9 +762,9 @@ class ManinSymbolList_gamma1(ManinSymbolList_group): INPUT: - - ``level`` -- (integer): the level. + - ``level`` -- integer; the level - - ``weight`` -- (integer): the weight. + - ``weight`` -- integer; the weight EXAMPLES:: @@ -823,9 +819,9 @@ class ManinSymbolList_gamma_h(ManinSymbolList_group): INPUT: - - ``group`` -- (integer): the congruence subgroup. + - ``group`` -- integer; the congruence subgroup - - ``weight`` -- (integer): the weight. + - ``weight`` -- integer; the weight EXAMPLES:: @@ -865,7 +861,7 @@ def __init__(self, group, weight): def group(self): """ - Return the group associated to self. + Return the group associated to ``self``. EXAMPLES:: @@ -876,7 +872,7 @@ def group(self): def __repr__(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -895,7 +891,7 @@ class ManinSymbolList_character(ManinSymbolList): - ``character`` -- (DirichletCharacter) the Dirichlet character - - ``weight`` -- (integer) the weight + - ``weight`` -- integer; the weight EXAMPLES:: @@ -915,9 +911,9 @@ def __init__(self, character, weight): INPUT: - - ``character`` -- (DirichletCharacter) the Dirichlet character + - ``character`` -- (DirichletCharacter) the Dirichlet character - - ``weight`` -- (integer) the weight + - ``weight`` -- integer; the weight EXAMPLES:: @@ -970,9 +966,7 @@ def level(self): """ Return the level of this :class:`ManinSymbolList`. - OUTPUT: - - ``integer`` -- the level of the symbols in this list. + OUTPUT: integer; the level of the symbols in this list EXAMPLES:: @@ -990,17 +984,16 @@ def apply(self, j, m): INPUT: + - ``j`` -- integer; the index of the symbol to act on - - ``j`` (integer): the index of the symbol to act on. - - - ``m`` (list of ints): `[a,b,c,d]` where `m = [a, b; c, d]` is the matrix to be applied. - + - ``m`` -- list of integers `[a,b,c,d]` where `m = [a, b; c, d]` is the + matrix to be applied OUTPUT: A list of pairs `(j, c_i)`, where each `c_i` is an integer, `j` is an integer (the `j`-th Manin symbol), and the - sum `c_i*x_i` is the image of self under the right action + sum `c_i*x_i` is the image of ``self`` under the right action of the matrix `[a,b;c,d]`. Here the right action of `g = [a,b;c,d]` on a Manin symbol `[P(X,Y),(u,v)]` is by definition `[P(aX+bY,cX+dY),(u,v)*g]`. @@ -1034,13 +1027,13 @@ def apply_S(self, j): INPUT: - - ``j`` -- (integer) a symbol index. + - ``j`` -- integer; a symbol index OUTPUT: ``(k, s)`` where `k` is the index of the symbol obtained by acting - on the `j`'th symbol with `S`, and `s` is the parity of the - `j`'th symbol. + on the `j`-th symbol with `S`, and `s` is the parity of the + `j`-th symbol. EXAMPLES:: @@ -1063,7 +1056,7 @@ def apply_S(self, j): def _apply_S_only_0pm1(self): """ - Return True if the coefficient when applying the S relation is + Return ``True`` if the coefficient when applying the S relation is always 0, 1, or -1. This is useful for optimizing code in relation_matrix.py. @@ -1085,13 +1078,13 @@ def apply_I(self, j): INPUT: - - ``j`` -- (integer) a symbol index + - ``j`` -- integer; a symbol index OUTPUT: ``(k, s)`` where `k` is the index of the symbol obtained by acting - on the `j`'th symbol with `I`, and `s` is the parity of the - `j`'th symbol. + on the `j`-th symbol with `I`, and `s` is the parity of the + `j`-th symbol. EXAMPLES:: @@ -1114,17 +1107,17 @@ def apply_I(self, j): def apply_T(self, j): """ - Apply the matrix `T=[0,1,-1,-1]` to the j-th Manin symbol. + Apply the matrix `T=[0,1,-1,-1]` to the `j`-th Manin symbol. INPUT: - - ``j`` -- (integer) a symbol index. + - ``j`` -- integer; a symbol index OUTPUT: A list of pairs `(j, c_i)`, where each `c_i` is an integer, `j` is an integer (the `j`-th Manin symbol), and the - sum `c_i*x_i` is the image of self under the right action + sum `c_i*x_i` is the image of ``self`` under the right action of the matrix `T`. EXAMPLES:: @@ -1161,13 +1154,13 @@ def apply_TT(self, j): INPUT: - - ``j`` -- (integer) a symbol index + - ``j`` -- integer; a symbol index OUTPUT: A list of pairs `(j, c_i)`, where each `c_i` is an integer, `j` is an integer (the `j`-th Manin symbol), and the - sum `c_i*x_i` is the image of self under the right action + sum `c_i*x_i` is the image of ``self`` under the right action of the matrix `T^2`. EXAMPLES:: @@ -1202,9 +1195,7 @@ def character(self): """ Return the character of this :class:`ManinSymbolList_character` object. - OUTPUT: - - The Dirichlet character of this Manin symbol list. + OUTPUT: the Dirichlet character of this Manin symbol list EXAMPLES:: @@ -1215,7 +1206,6 @@ def character(self): Manin Symbol List of weight 2 for Gamma1(4) with character [-1] sage: m.character() Dirichlet character modulo 4 of conductor 4 mapping 3 |--> -1 - """ return self.__character @@ -1268,7 +1258,7 @@ def normalize(self, x): INPUT: - ``x`` -- 3-tuple of integers ``(i,u,v)``, defining an element of this - list of Manin symbols, which need not be normalized. + list of Manin symbols, which need not be normalized OUTPUT: diff --git a/src/sage/modular/modsym/meson.build b/src/sage/modular/modsym/meson.build new file mode 100644 index 00000000000..f05d0776246 --- /dev/null +++ b/src/sage/modular/modsym/meson.build @@ -0,0 +1,41 @@ +py.install_sources( + 'all.py', + 'ambient.py', + 'apply.pxd', + 'boundary.py', + 'element.py', + 'g1list.py', + 'ghlist.py', + 'hecke_operator.py', + 'manin_symbol.pxd', + 'manin_symbol_list.py', + 'modsym.py', + 'modular_symbols.py', + 'p1list.pxd', + 'p1list_nf.py', + 'relation_matrix.py', + 'space.py', + 'subspace.py', + 'tests.py', + subdir: 'sage/modular/modsym', +) + +extension_data = { + 'apply' : files('apply.pyx'), + 'heilbronn' : files('heilbronn.pyx'), + 'manin_symbol' : files('manin_symbol.pyx'), + 'p1list' : files('p1list.pyx'), + 'relation_matrix_pyx' : files('relation_matrix_pyx.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modular/modsym', + install: true, + include_directories: [inc_cpython, inc_ext, inc_flint, inc_rings], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + diff --git a/src/sage/modular/modsym/modsym.py b/src/sage/modular/modsym/modsym.py index 6cb40dae8c0..fb46d0edafa 100644 --- a/src/sage/modular/modsym/modsym.py +++ b/src/sage/modular/modsym/modsym.py @@ -212,17 +212,17 @@ def ModularSymbols(group=1, INPUT: - - ``group`` -- A congruence subgroup or a Dirichlet character eps. - - ``weight`` -- int, the weight, which must be >= 2. - - ``sign`` -- int, The sign of the involution on modular symbols + - ``group`` -- a congruence subgroup or a Dirichlet character eps + - ``weight`` -- integer; the weight, which must be >= 2 + - ``sign`` -- integer; the sign of the involution on modular symbols induced by complex conjugation. The default is 0, which means "no sign", i.e., take the whole space. - ``base_ring`` -- the base ring. Defaults to `\QQ` if no character is given, or to the minimal extension of `\QQ` containing the values of the character. - - ``custom_init`` -- a function that is called with self as input + - ``custom_init`` -- a function that is called with ``self`` as input before any computations are done using self; this could be used - to set a custom modular symbols presentation. If self is + to set a custom modular symbols presentation. If ``self`` is already in the cache and use_cache=True, then this function is not called. diff --git a/src/sage/modular/modsym/modular_symbols.py b/src/sage/modular/modsym/modular_symbols.py index 57dc8f23a2b..3e8a8be156c 100644 --- a/src/sage/modular/modsym/modular_symbols.py +++ b/src/sage/modular/modsym/modular_symbols.py @@ -269,8 +269,8 @@ def apply(self, g): INPUT: - - ``g`` -- a list ``[a,b,c,d]``, corresponding to the 2x2 matrix - `\begin{pmatrix} a & b \\ c & d \end{pmatrix} \in {\rm GL}_2(\QQ)`. + - ``g`` -- list ``[a,b,c,d]``, corresponding to the 2x2 matrix + `\begin{pmatrix} a & b \\ c & d \end{pmatrix} \in {\rm GL}_2(\QQ)` OUTPUT: diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index 188e79e6c01..7ceda12d5c8 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -31,28 +31,29 @@ cdef int c_p1_normalize_int(int N, int u, int v, int* uu, int* vv, int* ss, int compute_s) except -1: r""" - Computes the canonical representative of + Compute the canonical representative of `\mathbb{P}^1(\ZZ/N\ZZ)` equivalent to `(u,v)` along with a transforming scalar. INPUT: - - ``N`` -- an integer + - ``N`` -- integer + + - ``u`` -- integer - - ``u`` -- an integer + - ``v`` -- integer - - ``v`` -- an integer + OUTPUT: - OUTPUT: If gcd(u,v,N) = 1, then returns + If `\gcd(u,v,N) = 1`, then returns - - ``uu`` -- an integer + - ``uu`` -- integer - - ``vv`` -- an integer + - ``vv`` -- integer - - ``ss`` -- an integer such that `(ss*uu, ss*vv)` is congruent to - `(u,v)` (mod `N`); + - ``ss`` -- integer such that `(ss*uu, ss*vv)` is congruent to `(u,v)` (mod `N`); - if `\gcd(u,v,N) \not= 1`, returns 0, 0, 0. + If `\gcd(u,v,N) \not= 1`, returns ``0, 0, 0``. If ``compute_s`` is 0, ``s`` is not computed. """ @@ -93,8 +94,8 @@ cdef int c_p1_normalize_int(int N, int u, int v, # Now g = s*u + t*N, so s is a "pseudo-inverse" of u mod N # Adjust s modulo N/g so it is coprime to N. - if g!=1: - d = N/g + if g != 1: + d = N // g while arith_int.c_gcd_int(s,N) != 1: s = (s+d) % N @@ -104,8 +105,8 @@ cdef int c_p1_normalize_int(int N, int u, int v, min_v = v min_t = 1 - if g!=1: - Ng = N/g + if g != 1: + Ng = N // g vNg = (v*Ng) % N t = 1 for k in range(2, g + 1): @@ -128,30 +129,29 @@ cdef int c_p1_normalize_int(int N, int u, int v, def p1_normalize_int(N, u, v): r""" - Computes the canonical representative of + Compute the canonical representative of `\mathbb{P}^1(\ZZ/N\ZZ)` equivalent to `(u,v)` along with a transforming scalar. INPUT: + - ``N`` -- integer - - ``N`` -- an integer - - - ``u`` -- an integer + - ``u`` -- integer - - ``v`` -- an integer + - ``v`` -- integer + OUTPUT: - OUTPUT: If gcd(u,v,N) = 1, then returns - + If `\gcd(u,v,N) = 1`, then returns - - ``uu`` -- an integer + - ``uu`` -- integer - - ``vv`` -- an integer + - ``vv`` -- integer - - ``ss`` -- an integer such that `(ss*uu, ss*vv)` is congruent to `(u,v)` (mod `N`); + - ``ss`` -- integer such that `(ss*uu, ss*vv)` is congruent to `(u,v)` (mod `N`); - if `\gcd(u,v,N) \not= 1`, returns 0, 0, 0. + If `\gcd(u,v,N) \not= 1`, returns ``0, 0, 0``. EXAMPLES:: @@ -177,8 +177,7 @@ def p1list_int(int N): INPUT: - - - ``N`` -- integer (the level or modulus). + - ``N`` -- integer (the level or modulus) EXAMPLES:: @@ -270,26 +269,25 @@ cdef int c_p1_normalize_llong(int N, int u, int v, INPUT: + - ``N`` -- integer (the modulus or level) - - ``N`` -- an integer (the modulus or level) + - ``u`` -- integer (the first coordinate of (u:v)) - - ``u`` -- an integer (the first coordinate of (u:v)) + - ``v`` -- integer (the second coordinate of (u:v)) - - ``v`` -- an integer (the second coordinate of (u:v)) + - ``compute_s`` -- boolean (int) - - ``compute_s`` -- a boolean (int) - - - OUTPUT: If gcd(u,v,N) = 1, then returns + OUTPUT: + If `\gcd(u,v,N) = 1`, then returns - - ``uu`` -- an integer + - ``uu`` -- integer - - ``vv`` -- an integer + - ``vv`` -- integer - - ``ss`` -- an integer such that `(ss*uu, ss*vv)` is equivalent to `(u,v)` mod `N`; + - ``ss`` -- integer such that `(ss*uu, ss*vv)` is equivalent to `(u,v)` mod `N` - if `\gcd(u,v,N) \not= 1`, returns 0, 0, 0. + If `\gcd(u,v,N) \not= 1`, returns ``0, 0, 0``. EXAMPLES:: @@ -357,8 +355,8 @@ cdef int c_p1_normalize_llong(int N, int u, int v, # Now g = s*u + t*N, so s is a "pseudo-inverse" of u mod N # Adjust s modulo N/g so it is coprime to N. - if g!=1: - d = N/g + if g != 1: + d = N // g while arith_int.c_gcd_int(s,N) != 1: s = (s+d) % N @@ -369,8 +367,8 @@ cdef int c_p1_normalize_llong(int N, int u, int v, min_v = v min_t = 1 - if g!=1: - Ng = N/g + if g != 1: + Ng = N // g vNg = ((v * Ng) % ll_N) t = 1 for k in range(2, g + 1): @@ -393,30 +391,29 @@ cdef int c_p1_normalize_llong(int N, int u, int v, def p1_normalize_llong(N, u, v): r""" - Computes the canonical representative of + Compute the canonical representative of `\mathbb{P}^1(\ZZ/N\ZZ)` equivalent to `(u,v)` along with a transforming scalar. INPUT: + - ``N`` -- integer - - ``N`` -- an integer - - - ``u`` -- an integer + - ``u`` -- integer - - ``v`` -- an integer + - ``v`` -- integer + OUTPUT: - OUTPUT: If gcd(u,v,N) = 1, then returns - + If `\gcd(u,v,N) = 1`, then returns - - ``uu`` -- an integer + - ``uu`` -- integer - - ``vv`` -- an integer + - ``vv`` -- integer - - ``ss`` -- an integer such that `(ss*uu, ss*vv)` is equivalent to `(u,v)` mod `N`; + - ``ss`` -- integer such that `(ss*uu, ss*vv)` is equivalent to `(u,v)` mod `N` - if `\gcd(u,v,N) \not= 1`, returns 0, 0, 0. + If `\gcd(u,v,N) \not= 1`, returns ``0, 0, 0``. EXAMPLES:: @@ -443,8 +440,7 @@ def p1list_llong(int N): INPUT: - - - ``N`` -- integer (the level or modulus). + - ``N`` -- integer (the level or modulus) EXAMPLES:: @@ -505,7 +501,7 @@ def p1list(N): INPUT: - - N (integer) -- a positive integer (less than 2^31). + - ``N`` -- integer; a positive integer (less than 2^31) OUTPUT: @@ -532,30 +528,29 @@ def p1list(N): def p1_normalize(int N, int u, int v): r""" - Computes the canonical representative of + Compute the canonical representative of `\mathbb{P}^1(\ZZ/N\ZZ)` equivalent to `(u,v)` along with a transforming scalar. INPUT: + - ``N`` -- integer - - ``N`` -- an integer - - - ``u`` -- an integer - - - ``v`` -- an integer + - ``u`` -- integer + - ``v`` -- integer - OUTPUT: If gcd(u,v,N) = 1, then returns + OUTPUT: + If `\gcd(u,v,N) = 1`, then returns - - ``uu`` -- an integer + - ``uu`` -- integer - - ``vv`` -- an integer + - ``vv`` -- integer - - ``ss`` -- an integer such that `(ss*uu, ss*vv)` is equivalent to `(u,v)` mod `N`; + - ``ss`` -- integer such that `(ss*uu, ss*vv)` is equivalent to `(u,v)` mod `N` - if `\gcd(u,v,N) \not= 1`, returns 0, 0, 0. + If `\gcd(u,v,N) \not= 1`, returns ``0, 0, 0``. EXAMPLES:: @@ -596,17 +591,14 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, """ INPUT: + - ``N``, ``u``, ``v`` -- integers - - ``N, u, v`` -- integers - - - ``compute_s`` -- do not compute s if compute_s == 0. - - - ``t_g, t_a, t_b`` -- int arrays of + - ``compute_s`` -- do not compute s if ``compute_s == 0`` + - ``t_g``, ``t_a``, ``t_b`` -- integer arrays - OUTPUT: - - - ``uu, vv, ss`` -- reduced representative and normalizing scalar. + OUTPUT: ``uu, vv, ss`` -- reduced representative and normalizing + scalar """ cdef int d, k, g, s, t, min_v, min_t, Ng, vNg if N == 1: @@ -648,8 +640,8 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, # Now g = s*u + t*N, so s is a "pseudo-inverse" of u mod N # Adjust s modulo N/g so it is coprime to N. - if g!=1: - d = N/g + if g != 1: + d = N // g while t_g[s] != 1: # while arith_int.c_gcd_int(s,N) != 1: s = (s+d) % N @@ -659,8 +651,8 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, min_v = v min_t = 1 - if g!=1: - Ng = N/g + if g != 1: + Ng = N // g vNg = (v*Ng) % N t = 1 for k in range(2, g + 1): @@ -706,11 +698,9 @@ cdef class P1List(): INPUT: - - ``N`` -- positive integer (the modulus or level). + - ``N`` -- positive integer (the modulus or level) - OUTPUT: - - A P1List object representing `\mathbb{P}^1(\ZZ/N\ZZ)`. + OUTPUT: a P1List object representing `\mathbb{P}^1(\ZZ/N\ZZ)` EXAMPLES:: @@ -754,7 +744,7 @@ cdef class P1List(): def __dealloc__(self): """ - Deallocates memory for an object of the class P1List. + Deallocate memory for an object of the class P1List. """ sig_free(self.g) sig_free(self.s) @@ -847,23 +837,22 @@ cdef class P1List(): sage: L = P1List(8) sage: str(L) # indirect doctest 'The projective line over the integers modulo 8' - """ return "The projective line over the integers modulo %s" % self.__N def lift_to_sl2z(self, int i): r""" - Lift the `i`'th element of this P1list to an element of + Lift the `i`-th element of this P1list to an element of `SL(2,\ZZ)`. - If the `i`'th element is `(c,d)`, this function computes and + If the `i`-th element is `(c,d)`, this function computes and returns a list `[a,b, c',d']` that defines a 2x2 matrix with determinant 1 and integer entries, such that `c=c'` (mod `N`) and `d=d'` (mod `N`). INPUT: - - ``i`` -- integer (the index of the element to lift). + - ``i`` -- integer (the index of the element to lift) EXAMPLES:: @@ -896,11 +885,11 @@ cdef class P1List(): def apply_I(self, int i): r""" Return the index of the result of applying the matrix - `I=[-1,0;0,1]` to the `i`'th element of this P1List. + `I=[-1,0;0,1]` to the `i`-th element of this P1List. INPUT: - - ``i`` -- integer (the index of the element to act on). + - ``i`` -- integer (the index of the element to act on) EXAMPLES:: @@ -928,12 +917,11 @@ cdef class P1List(): def apply_S(self, int i): r""" Return the index of the result of applying the matrix - `S=[0,-1;1,0]` to the `i`'th element of this P1List. + `S=[0,-1;1,0]` to the `i`-th element of this P1List. INPUT: - - - ``i`` -- integer (the index of the element to act on). + - ``i`` -- integer (the index of the element to act on) EXAMPLES:: @@ -961,12 +949,11 @@ cdef class P1List(): def apply_T(self, int i): r""" Return the index of the result of applying the matrix - `T=[0,1;-1,-1]` to the `i`'th element of this P1List. + `T=[0,1;-1,-1]` to the `i`-th element of this P1List. INPUT: - - - ``i`` -- integer (the index of the element to act on). + - ``i`` -- integer (the index of the element to act on) EXAMPLES:: @@ -999,14 +986,11 @@ cdef class P1List(): INPUT: - - - ``u, v`` -- integers, with `\gcd(u,v,N)=1`. - + - ``u``, ``v`` -- integers with `\gcd(u,v,N)=1` OUTPUT: - - - ``i`` -- the index of `u`, `v`, in the P1list. + - ``i`` -- the index of `u`, `v`, in the P1list EXAMPLES:: @@ -1043,16 +1027,13 @@ cdef class P1List(): INPUT: - - - ``u, v`` -- integers, with `\gcd(u,v,N)=1`. - + - ``u``, ``v`` -- integers with `\gcd(u,v,N)=1` OUTPUT: + - ``i`` -- the index of `u`, `v`, in the P1list - - ``i`` -- the index of `u`, `v`, in the P1list. - - - ``s`` -- normalizing scalar. + - ``s`` -- normalizing scalar. """ if self.__N == 1: # there is exactly 1 class [(0,0)]. @@ -1086,14 +1067,12 @@ cdef class P1List(): INPUT: - - - ``u``, ``v`` -- integers, with `\gcd(u,v,N)=1`, normalized so they lie in the list. - + - ``u``, ``v`` -- integers with `\gcd(u,v,N)=1`, normalized so they lie + in the list OUTPUT: - - - ``i`` -- the index of `(u:v)`, in the P1list. + - ``i`` -- the index of `(u:v)`, in the P1list EXAMPLES:: @@ -1130,14 +1109,10 @@ cdef class P1List(): INPUT: + - ``u``, ``v`` -- integers with `\gcd(u,v,N)=1` - - ``u, v`` -- integers, with `\gcd(u,v,N)=1`. - - - OUTPUT: - - - a 2-tuple ``(uu,vv)`` where `(uu:vv)` is a *normalized* - representative of `(u:v)`. + OUTPUT: a 2-tuple ``(uu,vv)`` where `(uu:vv)` is a *normalized* + representative of `(u:v)` NOTE: See also normalize_with_scalar() which also returns the normalizing scalar. @@ -1163,9 +1138,7 @@ cdef class P1List(): INPUT: - - - ``u, v`` -- integers, with `\gcd(u,v,N)=1`. - + - ``u``, ``v`` -- integers with `\gcd(u,v,N)=1` OUTPUT: @@ -1226,7 +1199,7 @@ def lift_to_sl2z_int(int c, int d, int N): INPUT: - - ``c,d,N`` -- integers such that `\gcd(c,d,N)=1`. + - ``c``, ``d``, ``N`` -- integers such that `\gcd(c,d,N)=1` EXAMPLES:: @@ -1264,17 +1237,17 @@ def lift_to_sl2z_int(int c, int d, int N): # compute prime-to-d part of m. while True: - g = arith_int.c_gcd_int(m,d) + g = arith_int.c_gcd_int(m, d) if g == 1: break - m = m / g + m = m // g # compute prime-to-N part of m. while True: - g = arith_int.c_gcd_int(m,N) + g = arith_int.c_gcd_int(m, N) if g == 1: break - m = m / g + m = m // g d += N * m g = arith_int.c_xgcd_int(c, d, &z1, &z2) @@ -1296,7 +1269,7 @@ def lift_to_sl2z_llong(llong c, llong d, int N): INPUT: - - ``c,d,N`` -- integers such that `\gcd(c,d,N)=1`. + - ``c``, ``d``, ``N`` -- integers such that `\gcd(c,d,N)=1` EXAMPLES:: @@ -1326,7 +1299,7 @@ def lift_to_sl2z_llong(llong c, llong d, int N): g = arith_llong.c_xgcd_longlong(c, d, &z1, &z2) # We're lucky: z1*c + z2*d = 1. - if g==1: + if g == 1: return [z2, -z1, c, d] # Have to try harder. @@ -1334,17 +1307,17 @@ def lift_to_sl2z_llong(llong c, llong d, int N): # compute prime-to-d part of m. while True: - g = arith_llong.c_gcd_longlong(m,d) + g = arith_llong.c_gcd_longlong(m, d) if g == 1: break - m = m / g + m = m // g # compute prime-to-N part of m. while True: - g = arith_llong.c_gcd_longlong(m,N) + g = arith_llong.c_gcd_longlong(m, N) if g == 1: break - m = m / g + m = m // g d += N * m g = arith_llong.c_xgcd_longlong(c, d, &z1, &z2) @@ -1362,7 +1335,7 @@ def lift_to_sl2z(c, d, N): INPUT: - - ``c,d,N`` -- Python ints or longs such that `\gcd(c,d,N)=1`. + - ``c``, ``d``, ``N`` -- python ints or longs such that `\gcd(c,d,N)=1` EXAMPLES:: @@ -1371,7 +1344,7 @@ def lift_to_sl2z(c, d, N): sage: lift_to_sl2z(2,3,6000000) [1, 1, 2, 3] - You will get a :class:`ValueError` exception if the input is invalid. + You will get a :exc:`ValueError` exception if the input is invalid. Note that here gcd(15,6,24)=3:: sage: lift_to_sl2z(15,6,24) diff --git a/src/sage/modular/modsym/p1list_nf.py b/src/sage/modular/modsym/p1list_nf.py index 2c9ed6516ad..86d33071974 100644 --- a/src/sage/modular/modsym/p1list_nf.py +++ b/src/sage/modular/modsym/p1list_nf.py @@ -122,16 +122,18 @@ class MSymbol(SageObject): INPUT: - - ``N`` -- integral ideal (the modulus or level). + - ``N`` -- integral ideal (the modulus or level) - ``c`` -- integral element of the underlying number field or an MSymbol of - level N. + level N - ``d`` -- (optional) when present, it must be an integral element such - that `\langle c\rangle + \langle d\rangle + N = R`, where `R` is the corresponding ring of integers. + that `\langle c\rangle + \langle d\rangle + N = R`, where `R` is the + corresponding ring of integers - - ``check`` -- bool (default ``True``). If ``check=False`` the constructor does - not check the condition `\langle c\rangle + \langle d\rangle + N = R`. + - ``check`` -- boolean (default: ``True``); if ``check=False`` the + constructor does not check the condition + `\langle c\rangle + \langle d\rangle + N = R` OUTPUT: @@ -232,7 +234,7 @@ def __repr__(self): def _latex_(self): r""" - Return latex representation of self. + Return latex representation of ``self``. EXAMPLES:: @@ -384,7 +386,7 @@ def normalize(self, with_scalar=False): INPUT: - - ``with_scalar`` -- bool (default ``False``) + - ``with_scalar`` -- boolean (default: ``False``) OUTPUT: @@ -484,7 +486,7 @@ class P1NFList(SageObject): INPUT: - - ``N`` -- integral ideal (the modulus or level). + - ``N`` -- integral ideal (the modulus or level) OUTPUT: @@ -618,12 +620,12 @@ def normalize(self, c, d=None, with_scalar=False): INPUT: - ``c`` -- integral element of the underlying number field, or an - MSymbol. + MSymbol - ``d`` -- (optional) when present, it must be an integral element of - the number field such that `(c, d)` defines an M-symbol of level `N`. + the number field such that `(c, d)` defines an M-symbol of level `N` - - ``with_scalar`` -- bool (default ``False``) + - ``with_scalar`` -- boolean (default: ``False``) OUTPUT: @@ -690,18 +692,18 @@ def index(self, c, d=None, with_scalar=False): INPUT: - ``c`` -- integral element of the corresponding number field, or an - :class:`MSymbol`. + :class:`MSymbol` - ``d`` -- (optional) when present, it must be an integral element of - the number field such that `(c, d)` defines an M-symbol of level `N`. + the number field such that `(c, d)` defines an M-symbol of level `N` - - ``with_scalar`` -- bool (default ``False``) + - ``with_scalar`` -- boolean (default: ``False``) OUTPUT: - ``u`` -- the normalizing scalar (only if ``with_scalar=True``) - - ``i`` -- the index of `(c, d)` in the list. + - ``i`` -- the index of `(c, d)` in the list EXAMPLES:: @@ -774,15 +776,13 @@ def index_of_normalized_pair(self, c, d=None): INPUT: - ``c`` -- integral element of the corresponding number field, or a - normalized :class:`MSymbol`. + normalized :class:`MSymbol` - ``d`` -- (optional) when present, it must be an integral element of the number field such that `(c, d)` defines a normalized M-symbol of - level `N`. + level `N` - OUTPUT: - - - ``i`` -- the index of `(c, d)` in the list. + OUTPUT: ``i`` -- the index of `(c, d)` in the list EXAMPLES:: @@ -916,19 +916,19 @@ def apply_TS(self, i): def apply_T_alpha(self, i, alpha=1): r""" - Applies the matrix `T_{alpha}` = [1, `alpha`, 0, 1] to the `i`-th M-Symbol of - the list. + Applies the matrix `T_{alpha}` = [1, `alpha`, 0, 1] to the `i`-th + M-Symbol of the list. INPUT: - ``i`` -- integer - - ``alpha`` -- (default 1) element of the corresponding ring of integers + - ``alpha`` -- (default: 1) element of the corresponding ring of integers OUTPUT: integer -- the index of the M-Symbol obtained by the right action of - the matrix `T_{alpha}` = [1, `alpha`, 0, 1] on the i-th M-Symbol. + the matrix `T_{alpha}` = [1, `alpha`, 0, 1] on the `i`-th M-Symbol. EXAMPLES:: @@ -963,7 +963,7 @@ def apply_J_epsilon(self, i, e1, e2=1): - ``e1`` -- unit - - ``e2`` -- unit (default 1) + - ``e2`` -- unit (default: 1) OUTPUT: @@ -1013,7 +1013,7 @@ def p1NFlist(N): INPUT: - - ``N`` -- integral ideal (the level or modulus). + - ``N`` -- integral ideal (the level or modulus) EXAMPLES:: @@ -1073,7 +1073,6 @@ def lift_to_sl2_Ok(N, c, d): a `2\times 2` matrix with determinant 1. The lower two entries are congruent to `c`, `d` modulo the ideal `N`. - EXAMPLES:: sage: from sage.modular.modsym.p1list_nf import lift_to_sl2_Ok diff --git a/src/sage/modular/modsym/relation_matrix.py b/src/sage/modular/modsym/relation_matrix.py index 7d58bb62a48..0562cfdf899 100644 --- a/src/sage/modular/modsym/relation_matrix.py +++ b/src/sage/modular/modsym/relation_matrix.py @@ -69,10 +69,8 @@ def modS_relations(syms): OUTPUT: - - - ``rels`` -- set of pairs of pairs (j, s), where if - mod[i] = (j,s), then x_i = s\*x_j (mod S relations) - + - ``rels`` -- set of pairs of pairs (j, s), where if + mod[i] = (j,s), then x_i = s\*x_j (mod S relations) EXAMPLES:: @@ -138,12 +136,12 @@ def modI_relations(syms, sign): - ``syms`` -- :class:`ManinSymbolList` - - ``sign`` -- int (either -1, 0, or 1) + - ``sign`` -- integer (either -1, 0, or 1) OUTPUT: - - ``rels`` -- set of pairs of pairs (j, s), where if - mod[i] = (j,s), then x_i = s\*x_j (mod S relations) + - ``rels`` -- set of pairs of pairs (j, s), where if + mod[i] = (j,s), then x_i = s\*x_j (mod S relations) EXAMPLES:: @@ -204,16 +202,16 @@ def T_relation_matrix_wtk_g0(syms, mod, field, sparse): - ``syms`` -- :class:`ManinSymbolList` - - ``mod`` -- list that gives quotient modulo some two-term relations, i.e., - the S relations, and if sign is nonzero, the I relations. + - ``mod`` -- list that gives quotient modulo some two-term relations, i.e., + the S relations, and if sign is nonzero, the I relations - - ``field`` -- base_ring + - ``field`` -- ``base_ring`` - - ``sparse`` -- (True or False) whether to use sparse rather than dense - linear algebra + - ``sparse`` -- boolean; whether to use sparse rather than dense + linear algebra - OUTPUT: A sparse matrix whose rows correspond to the reduction of - the T relations modulo the S and I relations. + OUTPUT: a sparse matrix whose rows correspond to the reduction of + the `T` relations modulo the `S` and `I` relations. EXAMPLES:: @@ -266,25 +264,23 @@ def gens_to_basis_matrix(syms, relation_matrix, mod, field, sparse): - ``syms`` -- :class:`ManinSymbolList` - - ``relation_matrix`` -- as output by - ``__compute_T_relation_matrix(self, mod)`` + - ``relation_matrix`` -- as output by + ``__compute_T_relation_matrix(self, mod)`` - - ``mod`` -- quotient of modular symbols modulo the - 2-term S (and possibly I) relations + - ``mod`` -- quotient of modular symbols modulo the + 2-term S (and possibly I) relations - - ``field`` -- base field + - ``field`` -- base field - - ``sparse`` -- (bool): whether or not matrix should be - sparse + - ``sparse`` -- boolean; whether or not matrix should be sparse OUTPUT: - - ``matrix`` -- a matrix whose ith row expresses the - Manin symbol generators in terms of a basis of Manin symbols - (modulo the S, (possibly I,) and T rels) Note that the entries of - the matrix need not be integers. + ``matrix`` -- a matrix whose `i`-th row expresses the Manin symbol + generators in terms of a basis of Manin symbols (modulo the S, (possibly + I,) and T rels). Note that the entries of the matrix need not be integers. - - ``list`` -- integers i, such that the Manin symbols `x_i` are a basis. + - ``list`` -- integers `i`, such that the Manin symbols `x_i` are a basis EXAMPLES:: @@ -370,21 +366,20 @@ def compute_presentation(syms, sign, field, sparse=None): - ``syms`` -- :class:`ManinSymbolList` - - ``sign`` -- integer (-1, 0, 1) - - - ``field`` -- a field + - ``sign`` -- integer (-1, 0, 1) + - ``field`` -- a field OUTPUT: - - sparse matrix whose rows give each generator - in terms of a basis for the quotient + - sparse matrix whose rows give each generator + in terms of a basis for the quotient - - list of integers that give the basis for the - quotient + - list of integers that give the basis for the + quotient - - mod: list where mod[i]=(j,s) means that x_i - = s\*x_j modulo the 2-term S (and possibly I) relations. + - mod: list where mod[i]=(j,s) means that x_i + = s\*x_j modulo the 2-term S (and possibly I) relations. ALGORITHM: @@ -422,7 +417,6 @@ def compute_presentation(syms, sign, field, sparse=None): of Manin symbols, modulo the relations. This subset of Manin symbols is a basis for the quotient by the relations. - EXAMPLES:: sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma0(8,2) @@ -462,11 +456,11 @@ def relation_matrix_wtk_g0(syms, sign, field, sparse): - ``syms`` -- :class:`ManinSymbolList` - - ``sign``: integer (0, 1 or -1) + - ``sign`` -- integer (0, 1 or -1) - - ``field``: the base field (non-field base rings not supported at present) + - ``field`` -- the base field (non-field base rings not supported at present) - - ``sparse``: (True or False) whether to use sparse arithmetic. + - ``sparse`` -- boolean; whether to use sparse arithmetic Note that ManinSymbolList objects already have a specific weight, so there is no need for an extra ``weight`` parameter. @@ -519,30 +513,26 @@ def sparse_2term_quotient(rels, n, F): INPUT: - - ``rels`` -- iterable made of pairs ((i,s), (j,t)). The pair - represents the relation s\*x_i + t\*x_j = 0, where the i, j must - be Python int's. + - ``rels`` -- iterable made of pairs ((i,s), (j,t)). The pair + represents the relation `s x_i + t x_j = 0`, where the `i, j` must + be Python int's. - - ``n`` -- int, the x_i are x_0, ..., x_n-1. + - ``n`` -- integer, the `x_i` are `x_0, \ldots, x_{n-1}` - - ``F`` -- base field + - ``F`` -- base field OUTPUT: - - ``mod`` -- list such that mod[i] = (j,s), which means - that x_i is equivalent to s\*x_j, where the x_j are a basis for - the quotient. + ``mod`` -- list such that ``mod[i] = (j,s)``, which means that `x_i` is + equivalent to `s x_j`, where the `x_j` are a basis for the quotient. EXAMPLES: We quotient out by the relations .. MATH:: - 3*x0 - x1 = 0,\qquad x1 + x3 = 0,\qquad x2 + x3 = 0,\qquad x4 - x5 = 0 + 3*x0 - x1 = 0,\qquad x1 + x3 = 0,\qquad x2 + x3 = 0,\qquad x4 - x5 = 0 - - to get - - :: + to get:: sage: rels = [((int(0),3), (int(1),-1)), ((int(1),1), (int(3),1)), ((int(2),1),(int(3),1)), ((int(4),1),(int(5),-1))] sage: n = 6 diff --git a/src/sage/modular/modsym/relation_matrix_pyx.pyx b/src/sage/modular/modsym/relation_matrix_pyx.pyx index 46d8d716e62..0079133b610 100644 --- a/src/sage/modular/modsym/relation_matrix_pyx.pyx +++ b/src/sage/modular/modsym/relation_matrix_pyx.pyx @@ -31,10 +31,10 @@ def sparse_2term_quotient_only_pm1(rels, n): INPUT: - ``rels`` -- iterable made of pairs ((i,s), (j,t)). The pair - represents the relation s*x_i + t*x_j = 0, where the i, j must - be Python int's, and the s,t must all be 1 or -1. + represents the relation `s x_i + t x_j = 0`, where the `i, j` must + be Python int's, and the `s, t` must all be 1 or -1. - - ``n`` -- int, the x_i are x_0, ..., x_n-1. + - ``n`` -- integer; the `x_i` are `x_0, \ldots, x_{n-1}` OUTPUT: diff --git a/src/sage/modular/modsym/space.py b/src/sage/modular/modsym/space.py index 8dba0412a60..a77d9279a6b 100644 --- a/src/sage/modular/modsym/space.py +++ b/src/sage/modular/modsym/space.py @@ -196,14 +196,14 @@ def compact_system_of_eigenvalues(self, v, names='alpha', nz=None): INPUT: - - ``v`` -- a list of positive integers - - ``nz`` -- (default: ``None``); if given specifies a column index - such that the dual module has that column nonzero. + - ``v`` -- list of positive integers + - ``nz`` -- (default: ``None``) if given specifies a column index + such that the dual module has that column nonzero OUTPUT: - ``E`` -- matrix such that E\*v is a vector with components - the eigenvalues `a_n` for `n \in v`. + the eigenvalues `a_n` for `n \in v` - ``v`` -- a vector over a number field EXAMPLES:: @@ -388,13 +388,13 @@ def group(self): INPUT: - - ``ModularSymbols self`` -- an arbitrary space of - modular symbols + - ``ModularSymbols self`` -- an arbitrary space of + modular symbols OUTPUT: - - ``CongruenceSubgroup`` -- the congruence subgroup - that this is a space of modular symbols for. + - ``CongruenceSubgroup`` -- the congruence subgroup + that this is a space of modular symbols for ALGORITHM: The group is recorded when this space is created. @@ -473,9 +473,9 @@ def is_simple(self): def multiplicity(self, S, check_simple=True): """ Return the multiplicity of the simple modular symbols space S in - self. S must be a simple anemic Hecke module. + ``self``. S must be a simple anemic Hecke module. - ASSUMPTION: self is an anemic Hecke module with the same weight and + ASSUMPTION: ``self`` is an anemic Hecke module with the same weight and group as S, and S is simple. EXAMPLES:: @@ -507,12 +507,12 @@ def ngens(self): INPUT: - - ``ModularSymbols self`` -- arbitrary space of modular symbols. + - ``ModularSymbols self`` -- arbitrary space of modular symbols OUTPUT: - ``int`` -- the number of generators, which is the same as the - dimension of self. + dimension of ``self`` ALGORITHM: Call the dimension function. @@ -612,31 +612,31 @@ def set_precision(self, prec): def q_expansion_basis(self, prec=None, algorithm='default'): r""" - Return a basis of q-expansions (as power series) to precision prec + Return a basis of `q`-expansions (as power series) to precision ``prec`` of the space of modular forms associated to ``self``. - The q-expansions are defined over the same base ring as ``self``, + The `q`-expansions are defined over the same base ring as ``self``, and a put in echelon form. INPUT: - - ``self`` -- a space of CUSPIDAL modular symbols + - ``self`` -- a space of CUSPIDAL modular symbols - - ``prec`` -- an integer + - ``prec`` -- integer - - ``algorithm`` -- string: + - ``algorithm`` -- string; one of - - ``'default' (default)`` -- decide which algorithm to - use based on heuristics + - ``'default'`` -- (default) decide which algorithm to + use based on heuristics - - ``'hecke'`` -- compute basis by computing - homomorphisms T - K, where T is the Hecke algebra + - ``'hecke'`` -- compute basis by computing + homomorphisms T - K, where T is the Hecke algebra - - ``'eigen'`` -- compute basis using eigenvectors for - the Hecke action and Atkin-Lehner-Li theory to patch them together + - ``'eigen'`` -- compute basis using eigenvectors for + the Hecke action and Atkin-Lehner-Li theory to patch them together - - ``'all'`` -- compute using hecke_dual and eigen - algorithms and verify that the results are the same. + - ``'all'`` -- compute using hecke_dual and eigen + algorithms and verify that the results are the same The computed basis is *not* cached, though of course Hecke @@ -753,20 +753,19 @@ def q_expansion_module(self, prec=None, R=None): vectors of the `q`-expansions corresponding to ``self``. If R is not the base ring of ``self``, this returns the - restriction of scalars down to R (for this, self must have + restriction of scalars down to R (for this, ``self`` must have base ring `\QQ` or a number field). INPUT: - - ``self`` -- must be cuspidal + - ``self`` -- must be cuspidal - - ``prec`` -- an integer (default: - self.default_prec()) + - ``prec`` -- integer (default: ``self.default_prec()``) - - ``R`` -- either ZZ, QQ, or the base_ring of self + - ``R`` -- either `\ZZ`, `\QQ`, or the ``base_ring`` of ``self`` (which is the default) - OUTPUT: A free module over R. + OUTPUT: a free module over `R` .. TODO:: @@ -940,12 +939,12 @@ def _q_eigenform_images(self, A, prec, names): INPUT: - - ``self`` -- space of modular symbols + - ``self`` -- space of modular symbols - - ``A`` -- cuspidal simple space of level dividing the - level of self and the same weight + - ``A`` -- cuspidal simple space of level dividing the + level of ``self`` and the same weight - - ``prec`` -- a positive integer + - ``prec`` -- positive integer EXAMPLES:: @@ -972,11 +971,11 @@ def _q_expansion_module(self, prec, algorithm='hecke'): EXAMPLES:: - sage: ModularSymbols(11, 2, base_ring=GF(4,'a')).cuspidal_submodule()._q_expansion_module(prec=4, algorithm="hecke") + sage: ModularSymbols(11, 2, base_ring=GF(4,'a')).cuspidal_submodule()._q_expansion_module(prec=4, algorithm='hecke') Vector space of degree 4 and dimension 1 over Finite Field in a of size 2^2 Basis matrix: [0 1 0 1] - sage: ModularSymbols(11, 2, base_ring=QuadraticField(-7,'b'), sign=1).cuspidal_submodule()._q_expansion_module(prec=4, algorithm="eigen") + sage: ModularSymbols(11, 2, base_ring=QuadraticField(-7,'b'), sign=1).cuspidal_submodule()._q_expansion_module(prec=4, algorithm='eigen') Vector space of degree 4 and dimension 1 over Number Field in b with defining polynomial x^2 + 7 with b = 2.645751311064591?*I Basis matrix: [ 0 1 -2 -1] @@ -1002,7 +1001,7 @@ def q_eigen_gens(d, f): EXAMPLES:: - sage: ModularSymbols(11, 4, base_ring=QuadraticField(-7,'b'),sign=1).cuspidal_submodule()._q_expansion_module(prec=5, algorithm="eigen") # indirect doctest + sage: ModularSymbols(11, 4, base_ring=QuadraticField(-7,'b'),sign=1).cuspidal_submodule()._q_expansion_module(prec=5, algorithm='eigen') # indirect doctest Vector space of degree 5 and dimension 2 over Number Field in b with defining polynomial x^2 + 7 with b = 2.645751311064591?*I Basis matrix: [ 0 1 0 3 -6] @@ -1039,7 +1038,7 @@ def _q_expansion_module_rational(self, prec): INPUT: - - ``prec`` (integer) -- number of q-expansion terms to calculate. + - ``prec`` -- integer; number of `q`-expansion terms to calculate EXAMPLES:: @@ -1102,7 +1101,7 @@ def _q_expansion_module_integral(self, prec): the `q`-expansions corresponding to ``self``. The base ring of ``self`` must be `\QQ` or a number field, and - self must be cuspidal. The returned space is a `\ZZ`-module, + ``self`` must be cuspidal. The returned space is a `\ZZ`-module, where the coordinates are the coefficients of `q`-expansions. EXAMPLES:: @@ -1127,9 +1126,9 @@ def congruence_number(self, other, prec=None): congruence number, using ``prec`` terms of the `q`-expansions. The congruence number is defined as follows. If `V` is the - submodule of integral cusp forms corresponding to self (saturated in + submodule of integral cusp forms corresponding to ``self`` (saturated in `\ZZ[[q]]`, by definition) and `W` is the - submodule corresponding to other, each computed to precision prec, + submodule corresponding to other, each computed to precision ``prec``, the congruence number is the index of `V+W` in its saturation in `\ZZ[[q]]`. @@ -1170,7 +1169,7 @@ def q_eigenform_character(self, names=None): INPUT: - - ``names`` -- string, name of the variable. + - ``names`` -- string; name of the variable OUTPUT: @@ -1236,7 +1235,7 @@ def q_eigenform_character(self, names=None): def q_eigenform(self, prec, names=None): """ - Return the q-expansion to precision ``prec`` of a new eigenform + Return the `q`-expansion to precision ``prec`` of a new eigenform associated to ``self``. Here ``self`` must be new, cuspidal, and simple. @@ -1309,7 +1308,7 @@ def _q_expansion_basis_eigen(self, prec, names): def q_expansion_cuspforms(self, prec=None): r""" Return a function f(i,j) such that each value f(i,j) is the - q-expansion, to the given precision, of an element of the + `q`-expansion, to the given precision, of an element of the corresponding space `S` of cusp forms. Together these functions span `S`. Here `i,j` are integers @@ -1367,7 +1366,7 @@ def q_expansion_cuspforms(self, prec=None): def _q_expansion_basis_hecke_dual(self, prec): r""" - Compute a basis of q-expansions for the associated space of cusp forms + Compute a basis of `q`-expansions for the associated space of cusp forms to the given precision, by using linear functionals on the Hecke algebra as described in William Stein's book (Algorithm 3.26, page 56) @@ -1384,8 +1383,7 @@ def _q_expansion_basis_hecke_dual(self, prec): prec = Integer(prec) if prec < 1: raise ValueError("prec (=%s) must be >= 1" % prec) - if d >= prec - 1: - d = prec - 1 + d = min(prec - 1, d) K = self.base_ring() A = VectorSpace(K, prec - 1) @@ -1452,21 +1450,15 @@ def sign(self): INPUT: - - ``ModularSymbols self`` -- arbitrary space of modular - symbols. + - ``ModularSymbols self`` -- arbitrary space of modular symbols OUTPUT: - - ``int`` -- the sign of ``self``, either -1, 0, or 1. + - ``-1`` -- if this is factor of quotient where \* acts as -1, - - ``-1`` -- if this is factor of quotient where \* acts - as -1, + - ``+1`` -- if this is factor of quotient where \* acts as +1, - - ``+1`` -- if this is factor of quotient where \* acts - as +1, - - - ``0`` -- if this is full space of modular symbols (no - quotient). + - ``0`` -- if this is full space of modular symbols (no quotient) EXAMPLES:: @@ -1696,7 +1688,7 @@ def integral_basis(self): def integral_hecke_matrix(self, n): r""" - Return the matrix of the `n`th Hecke operator acting on the integral + Return the matrix of the `n`-th Hecke operator acting on the integral structure on ``self`` (as returned by ``self.integral_structure()``). This is often (but not always) different from the matrix @@ -1771,8 +1763,8 @@ def plus_submodule(self, compute_dual=True): INPUT: - - ``compute_dual`` -- bool (default: ``True``) also - compute dual subspace. This are useful for many algorithms. + - ``compute_dual`` -- boolean (default: ``True``); also + compute dual subspace. This is useful for many algorithms. OUTPUT: subspace of modular symbols @@ -1791,8 +1783,8 @@ def minus_submodule(self, compute_dual=True): INPUT: - - ``compute_dual`` -- bool (default: ``True``) also - compute dual subspace. This are useful for many algorithms. + - ``compute_dual`` -- boolean (default: ``True``); also + compute dual subspace. This is useful for many algorithms. OUTPUT: subspace of modular symbols @@ -1811,10 +1803,10 @@ def _compute_sign_submodule(self, sign, compute_dual=True): INPUT: - - sign (integer): 1 or -1 + - ``sign`` -- integer; 1 or -1 - - compute_dual (boolean, default ``True``): also compute the dual - submodule (useful for some algorithms) + - ``compute_dual`` -- boolean (default: ``True``); also compute the + dual submodule (useful for some algorithms) OUTPUT: a submodule of ``self`` @@ -1870,10 +1862,10 @@ def sign_submodule(self, sign, compute_dual=True): INPUT: - - ``sign`` -- int (either -1, 0 or +1) + - ``sign`` -- integer (either -1, 0 or +1) - - ``compute_dual`` -- bool (default: ``True``) also - compute dual subspace. This are useful for many algorithms. + - ``compute_dual`` -- boolean (default: ``True``); also + compute dual subspace. This is useful for many algorithms. OUTPUT: subspace of modular symbols @@ -1931,8 +1923,8 @@ def abelian_variety(self): INPUT: - - ``self`` -- modular symbols space of weight 2 for a - congruence subgroup such as Gamma0, Gamma1 or GammaH. + - ``self`` -- modular symbols space of weight 2 for a + congruence subgroup such as Gamma0, Gamma1 or GammaH EXAMPLES:: @@ -1972,7 +1964,7 @@ def rational_period_mapping(self): This is a homomorphism to a vector space whose kernel is the same as the kernel of the period mapping associated to - ``self``. For this to exist, self must be Hecke equivariant. + ``self``. For this to exist, ``self`` must be Hecke equivariant. Use :meth:`integral_period_mapping` to obtain a homomorphism to a `\ZZ`-module, normalized so the image of integral modular symbols is @@ -2092,12 +2084,12 @@ def modular_symbols_of_sign(self, sign, bound=None): INPUT: - - ``self`` -- a cuspidal space of modular symbols + - ``self`` -- a cuspidal space of modular symbols - - ``sign`` -- an integer, one of -1, 0, or 1 + - ``sign`` -- integer, one of -1, 0, or 1 - - ``bound`` -- integer (default: None); if specified - only use Hecke operators up to the given bound. + - ``bound`` -- integer (default: ``None``); if specified + only use Hecke operators up to the given bound EXAMPLES:: @@ -2354,9 +2346,9 @@ def _matrix_of_galois_action(self, t, P): INPUT: - - `t` -- integer + - ``t`` -- integer - - `P` -- list of cusps + - ``P`` -- list of cusps EXAMPLES: diff --git a/src/sage/modular/modsym/subspace.py b/src/sage/modular/modsym/subspace.py index a4892a71a80..e814602226a 100644 --- a/src/sage/modular/modsym/subspace.py +++ b/src/sage/modular/modsym/subspace.py @@ -36,19 +36,17 @@ def __init__(self, ambient_hecke_module, submodule, """ INPUT: + - ``ambient_hecke_module`` -- the ambient space of + modular symbols in which we're constructing a submodule - - ``ambient_hecke_module`` -- the ambient space of - modular symbols in which we're constructing a submodule + - ``submodule`` -- the underlying free module of the + submodule - - ``submodule`` -- the underlying free module of the - submodule - - - ``dual_free_module`` -- underlying free module of - the dual of the submodule (optional) - - - ``check`` -- (default: ``False``) whether to check that - the submodule is invariant under all Hecke operators T_p. + - ``dual_free_module`` -- underlying free module of + the dual of the submodule (optional) + - ``check`` -- boolean (default: ``False``); whether to check that + the submodule is invariant under all Hecke operators `T_p` EXAMPLES:: @@ -77,7 +75,7 @@ def __init__(self, ambient_hecke_module, submodule, def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: @@ -228,7 +226,7 @@ def eisenstein_subspace(self): def factorization(self): """ Return a list of pairs `(S,e)` where `S` is simple - spaces of modular symbols and self is isomorphic to the direct sum + spaces of modular symbols and ``self`` is isomorphic to the direct sum of the `S^e` as a module over the *anemic* Hecke algebra adjoin the star involution. @@ -238,7 +236,7 @@ def factorization(self): The factors are sorted by dimension - don't depend on much more for now. - ASSUMPTION: self is a module over the anemic Hecke algebra. + ASSUMPTION: ``self`` is a module over the anemic Hecke algebra. EXAMPLES: Note that if the sign is 1 then the cuspidal factors occur twice, one with each star eigenvalue. @@ -325,7 +323,7 @@ def factorization(self): def is_cuspidal(self) -> bool: """ - Return True if self is cuspidal. + Return ``True`` if ``self`` is cuspidal. EXAMPLES:: @@ -357,7 +355,7 @@ def _set_is_cuspidal(self, t): def is_eisenstein(self): """ - Return True if self is an Eisenstein subspace. + Return ``True`` if ``self`` is an Eisenstein subspace. EXAMPLES:: @@ -380,10 +378,10 @@ def _compute_sign_subspace(self, sign, compute_dual=True): INPUT: - - ``sign`` -- int (either -1 or +1) + - ``sign`` -- integer (either -1 or +1) - - ``compute_dual`` -- bool (default: ``True``) also - compute dual subspace. This are useful for many algorithms. + - ``compute_dual`` -- boolean (default: ``True``); also + compute dual subspace. This is useful for many algorithms. OUTPUT: subspace of modular symbols diff --git a/src/sage/modular/modsym/tests.py b/src/sage/modular/modsym/tests.py index 3af2ffb1d87..8157b4e9e6b 100644 --- a/src/sage/modular/modsym/tests.py +++ b/src/sage/modular/modsym/tests.py @@ -45,11 +45,11 @@ def __init__(self, levels=20, weights=4, onlyg0=False, onlyg1=False, INPUT: - - levels -- list or int - - weights -- list or int - - onlyg0 -- bool, if True only select Gamma0 spaces for testing - - onlyg1 -- bool, if True only select Gamma1 spaces for testing - - onlychar -- bool, if True only selects spaces with character for testing + - ``levels`` -- list or integer + - ``weights`` -- list or integer + - ``onlyg0`` -- boolean; if ``True`` only select Gamma0 spaces for testing + - ``onlyg1`` -- boolean; if ``True`` only select Gamma1 spaces for testing + - ``onlychar`` -- boolean; if ``True`` only selects spaces with character for testing EXAMPLES:: @@ -92,7 +92,7 @@ def __repr__(self): def _modular_symbols_space(self): """ Generate a random space of modular symbols subject to - the conditions of self. + the conditions of ``self``. EXAMPLES:: diff --git a/src/sage/modular/multiple_zeta.py b/src/sage/modular/multiple_zeta.py index 92a61876307..8bcbb1101de 100644 --- a/src/sage/modular/multiple_zeta.py +++ b/src/sage/modular/multiple_zeta.py @@ -167,7 +167,7 @@ # **************************************************************************** from __future__ import annotations import numbers -from typing import Iterator +from collections.abc import Iterator from itertools import product from sage.misc.fast_methods import Singleton @@ -223,9 +223,7 @@ def coproduct_iterator(paire) -> Iterator[list]: - ``paire`` -- a pair (list of indices, end of word) - OUTPUT: - - iterator for terms in the motivic coproduct + OUTPUT: iterator for terms in the motivic coproduct Each term is seen as a list of positions. @@ -329,9 +327,7 @@ def dual_composition(c) -> tuple[int, ...]: - ``c`` -- a composition - OUTPUT: - - a composition + OUTPUT: a composition EXAMPLES:: @@ -560,11 +556,9 @@ def extend_multiplicative_basis(B, n) -> Iterator: - ``B`` -- function mapping integer to list of tuples of compositions - - ``n`` -- an integer - - OUTPUT: + - ``n`` -- integer - Each term is a tuple of tuples of compositions. + OUTPUT: each term is a tuple of tuples of compositions EXAMPLES:: @@ -665,7 +659,7 @@ def __init__(self, R): if R in Domains(): cat = cat & Domains() W = Words(PositiveIntegers(), infinite=False) - CombinatorialFreeModule.__init__(self, R, W, prefix="Z", category=cat) + CombinatorialFreeModule.__init__(self, R, W, prefix='Z', category=cat) def _repr_(self) -> str: r""" @@ -951,7 +945,7 @@ def algebra_generators(self, n) -> list: INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -972,7 +966,7 @@ def basis_data(self, basering, n) -> Iterator: INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -996,7 +990,7 @@ def basis_brown(self, n) -> list: INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -1022,9 +1016,9 @@ def basis_filtration(self, d, reverse=False): INPUT: - - ``d`` -- (non-negative integer) the weight + - ``d`` -- nonnegative integer; the weight - - ``reverse`` -- (boolean, default ``False``) change the ordering of compositions + - ``reverse`` -- boolean (default: ``False``); change the ordering of compositions EXAMPLES:: @@ -1045,7 +1039,7 @@ def basis_filtration(self, d, reverse=False): [] """ if d < 0: - raise ValueError('d must be a non-negative integer') + raise ValueError('d must be a nonnegative integer') if d == 0: return [self([])] if d == 1: @@ -1148,7 +1142,7 @@ def simplify_full(self, basis=None): INPUT: - - ``basis`` (optional) -- either ``None`` or a function such that + - ``basis`` -- either ``None`` (default) or a function such that ``basis(d)`` is a basis of the weight ``d`` multiple zeta values. If ``None``, the Hoffman basis is used. @@ -1422,7 +1416,7 @@ def __init__(self, R): cat = GradedAlgebrasWithBasis(R).Commutative() if R in Domains(): cat = cat & Domains() - CombinatorialFreeModule.__init__(self, R, Words10, prefix="I", + CombinatorialFreeModule.__init__(self, R, Words10, prefix='I', category=cat) def _repr_(self) -> str: @@ -1624,7 +1618,7 @@ def composition_on_basis(self, w, basering=None): INPUT: - - ``basering`` -- optional choice of the coefficient ring + - ``basering`` -- (optional) choice of the coefficient ring EXAMPLES:: @@ -1754,9 +1748,7 @@ def phi_extended(self, w): - ``w`` -- a word in 0 and 1 - OUTPUT: - - an element in the auxiliary F-algebra + OUTPUT: an element in the auxiliary F-algebra The coefficients are in the base ring. @@ -2034,7 +2026,7 @@ def _richcmp_(self, other, op) -> bool: sage: M = Multizetas(QQ) sage: a = 28*M((3,9))+150*M((5,7))+168*M((7,5)) sage: b = 5197/691*M((12,)) - sage: a.iterated() == b.iterated() # not tested, long time 20s + sage: a.iterated() == b.iterated() # not tested, long time (20s) True """ if op not in [op_EQ, op_NE]: @@ -2081,7 +2073,7 @@ def __init__(self, R): """ if R not in Rings(): raise TypeError("argument R must be a ring") - CombinatorialFreeModule.__init__(self, R, Words10, prefix="I") + CombinatorialFreeModule.__init__(self, R, Words10, prefix='I') def _repr_(self) -> str: """ @@ -2379,9 +2371,7 @@ def coeff_phi(w): - ``w`` -- a word in 0 and 1 with `k` letters (where `k` is odd) - OUTPUT: - - a rational number + OUTPUT: a rational number EXAMPLES:: @@ -2414,9 +2404,7 @@ def phi_on_multiplicative_basis(compo): - ``compo`` -- a composition (in the hardcoded multiplicative base) - OUTPUT: - - an element in :func:`F_ring` with rational coefficients + OUTPUT: an element in :func:`F_ring` with rational coefficients EXAMPLES:: @@ -2444,13 +2432,11 @@ def phi_on_basis(L): INPUT: - a list of compositions, each composition in the hardcoded basis + - ``L`` -- list of compositions; each composition in the hardcoded basis This encodes a product of multiple zeta values. - OUTPUT: - - an element in :func:`F_ring` + OUTPUT: an element in :func:`F_ring` EXAMPLES:: @@ -2518,9 +2504,7 @@ def compute_u_on_compo(compo): - ``compo`` -- a composition - OUTPUT: - - an element of :func:`F_ring` over `\QQ` + OUTPUT: an element of :func:`F_ring` over `\QQ` EXAMPLES:: @@ -2544,9 +2528,7 @@ def compute_u_on_basis(w): - ``w`` -- a word in 0,1 - OUTPUT: - - an element of :func:`F_ring` over `\QQ` + OUTPUT: an element of :func:`F_ring` over `\QQ` EXAMPLES:: @@ -2587,7 +2569,7 @@ def rho_matrix_inverse(n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2617,9 +2599,7 @@ def rho_inverse(elt): - ``elt`` -- an homogeneous element of the F ring - OUTPUT: - - a linear combination of multiple zeta values + OUTPUT: a linear combination of multiple zeta values EXAMPLES:: diff --git a/src/sage/modular/multiple_zeta_F_algebra.py b/src/sage/modular/multiple_zeta_F_algebra.py index 1d7c8a79ddf..fca676694ee 100644 --- a/src/sage/modular/multiple_zeta_F_algebra.py +++ b/src/sage/modular/multiple_zeta_F_algebra.py @@ -26,7 +26,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from __future__ import annotations -from typing import Iterator +from collections.abc import Iterator from sage.arith.misc import bernoulli from sage.categories.rings import Rings @@ -69,10 +69,10 @@ def str_to_index(x: str) -> tuple: r""" Convert a string to an index. - Every letter ``"2"`` contributes to the power of `f_2`. Other letters + Every letter ``'2'`` contributes to the power of `f_2`. Other letters are odd and define a word in `f_1, f_3, f_5, \ldots` - Usually the letters ``"2"`` form a prefix of the input. + Usually the letters ``'2'`` form a prefix of the input. EXAMPLES:: @@ -90,7 +90,7 @@ def str_to_index(x: str) -> tuple: def basis_f_odd_iterator(n, start=3) -> Iterator[tuple]: r""" - Return an iterator over compositions of ``n`` with odd parts. + Return an iterator over compositions of `n` with odd parts. Let `s` be the chosen odd start index. The allowed parts are the odd integers at least equal to `s`, in the set `s,s+2,s+4,s+6,\ldots`. @@ -99,9 +99,9 @@ def basis_f_odd_iterator(n, start=3) -> Iterator[tuple]: INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``start`` -- (default: ``3``) odd integer, start index for odd generators + - ``start`` -- odd integer (default: `3`); start index for odd generators EXAMPLES:: @@ -131,7 +131,7 @@ def basis_f_odd_iterator(n, start=3) -> Iterator[tuple]: def basis_f_iterator(n, start=3) -> Iterator[tuple]: r""" - Return an iterator for decompositions of ``n`` using ``2`` and odd integers. + Return an iterator for decompositions of `n` using `2` and odd integers. Let `s` be the chosen odd start index. The allowed odd parts are the odd integers at least equal to `s`, in the set `s,s+2,s+4,s+6,\ldots`. @@ -143,9 +143,9 @@ def basis_f_iterator(n, start=3) -> Iterator[tuple]: INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``start`` -- (default: ``3``) odd start index for odd generators + - ``start`` -- (default: `3`) odd start index for odd generators Each term is returned as a pair (integer, word) where the integer is the exponent of 2. @@ -193,14 +193,12 @@ def morphism_constructor(data: dict, start=3): INPUT: - - ``data`` -- a dictionary with integer keys containing the images of + - ``data`` -- dictionary with integer keys containing the images of `f_2, f_s, f_{s+2}, f_{s+4}, \ldots` - ``start`` -- (default: 3) start index for odd generators - OUTPUT: - - the unique morphism defined by the dictionary ``data`` + OUTPUT: the unique morphism defined by the dictionary ``data`` The codomain must be a zinbiel algebra, namely have both a commutative associative product ``*`` and a zinbiel product @@ -299,7 +297,7 @@ def __init__(self, R, start=3): Indices = NonNegativeIntegers().cartesian_product(W_Odds(start)) cat = BialgebrasWithBasis(R).Commutative().Graded() CombinatorialFreeModule.__init__(self, R, Indices, - latex_prefix="", prefix='f', + latex_prefix='', prefix='f', category=cat) def _repr_term(self, pw) -> str: @@ -388,7 +386,7 @@ def half_product_on_basis(self, pw1, pw2): INPUT: - - ``pw1``, ``pw2`` -- Basis elements + - ``pw1``, ``pw2`` -- basis elements EXAMPLES:: @@ -436,7 +434,7 @@ def gen(self, i): INPUT: - - ``i`` -- a nonnegative integer (at least 2) + - ``i`` -- nonnegative integer (at least 2) If ``i`` is odd, this returns a single generator `f_i` of the free shuffle algebra. @@ -558,11 +556,9 @@ def homogeneous_from_vector(self, vec, N): - ``vec`` -- a vector with coefficients in some base ring - - ``N`` -- integer, the homogeneous weight + - ``N`` -- integer; the homogeneous weight - OUTPUT: - - a homogeneous element of :func:`F_ring` over this base ring + OUTPUT: a homogeneous element of :func:`F_ring` over this base ring .. SEEALSO:: :meth:`F_algebra.homogeneous_to_vector` @@ -723,9 +719,7 @@ def homogeneous_to_vector(self): This is using a fixed enumeration of the basis. - OUTPUT: - - a vector with coefficients in the base ring + OUTPUT: a vector with coefficients in the base ring .. SEEALSO:: :meth:`F_algebra.homogeneous_from_vector` diff --git a/src/sage/modular/overconvergent/genus0.py b/src/sage/modular/overconvergent/genus0.py index 4cfdb603bd2..2576c9ddc18 100644 --- a/src/sage/modular/overconvergent/genus0.py +++ b/src/sage/modular/overconvergent/genus0.py @@ -243,23 +243,23 @@ def OverconvergentModularForms(prime, weight, radius, base_ring=QQ, prec=20, cha INPUT: - ``prime`` -- a prime number `p`, which must be one of the primes `\{2, 3, - 5, 7, 13\}`, or the congruence subgroup `\Gamma_0(p)` where `p` is one of these - primes. + 5, 7, 13\}`, or the congruence subgroup `\Gamma_0(p)` where `p` is one of + these primes - - ``weight`` -- an integer (which at present must be 0 or `\ge 2`), the - weight. + - ``weight`` -- integer (which at present must be 0 or `\ge 2`), the + weight - ``radius`` -- a rational number in the interval `\left( 0, \frac{p}{p+1} - \right)`, the radius of overconvergence. + \right)`, the radius of overconvergence - - ``base_ring`` -- (default: `\QQ`), a ring over which to compute. This - need not be a `p`-adic ring. + - ``base_ring`` -- (default: `\QQ`), a ring over which to compute; this + need not be a `p`-adic ring - - ``prec`` -- an integer (default: 20), the number of `q`-expansion terms to - compute. + - ``prec`` -- integer (default: 20); the number of `q`-expansion terms to + compute - - ``char`` -- a Dirichlet character modulo `p` or ``None`` (the default). - Here ``None`` is interpreted as the trivial character modulo `p`. + - ``char`` -- a Dirichlet character modulo `p` or ``None`` (the default); + here ``None`` is interpreted as the trivial character modulo `p` The character `\chi` and weight `k` must satisfy `(-1)^k = \chi(-1)`, and the base ring must contain an element `v` such that @@ -461,13 +461,13 @@ def base_extend(self, ring): Return the base extension of ``self`` to the given base ring. There must be a canonical map to this ring from the current - base ring, otherwise a :class:`TypeError` will be raised. + base ring, otherwise a :exc:`TypeError` will be raised. EXAMPLES:: sage: M = OverconvergentModularForms(2, 0, 1/2, base_ring=Qp(2)) sage: x = polygen(ZZ, 'x') - sage: M.base_extend(Qp(2).extension(x^2 - 2, names="w")) + sage: M.base_extend(Qp(2).extension(x^2 - 2, names='w')) Space of 2-adic 1/2-overconvergent modular forms of weight-character 0 over 2-adic Eisenstein Extension ... sage: M.base_extend(QQ) @@ -616,7 +616,6 @@ def _params(self): 7-adic Eisenstein Extension Field in w defined by x^2 - 7, 20, Dirichlet character modulo 7 of conductor 1 mapping 3 |--> 1) - """ return (self.prime(), self.weight().k(), self.radius(), self.base_ring(), self.prec(), self.weight().chi()) @@ -636,7 +635,6 @@ def __reduce__(self): 7-adic Eisenstein Extension Field in w defined by x^2 - 7, 20, Dirichlet character modulo 7 of conductor 1 mapping 3 |--> 1)) - """ return (OverconvergentModularForms, self._params()) @@ -1133,13 +1131,13 @@ def eigenfunctions(self, n, F=None, exact_arith=True): INPUT: - - ``n`` -- integer. The size of the matrix to use. + - ``n`` -- integer; the size of the matrix to use - ``F`` -- either ``None`` or a field over which to calculate eigenvalues. If the field is ``None``, the current base ring is used. If the base ring is not a `p`-adic ring, an error will be raised. - - ``exact_arith`` -- ``True`` or ``False`` (default ``True``). If ``True``, use exact + - ``exact_arith`` -- boolean (default: ``True``); if ``True``, use exact rational arithmetic to calculate the matrix of the `U` operator and its characteristic power series, even when the base ring is an inexact `p`-adic ring. This is typically slower, but more numerically stable. @@ -1313,7 +1311,8 @@ def recurrence_matrix(self, use_smithline=True): def _discover_recurrence_matrix(self, use_smithline=True): r""" - Does hard work of calculating recurrence matrix, which is cached to avoid doing this every time. + Do the hard work of calculating the recurrence matrix, which is cached + to avoid doing this every time. EXAMPLES:: @@ -1388,7 +1387,7 @@ def cps_u(self, n, use_recurrence=False): Uses the Hessenberg form of the Hecke matrix to compute the characteristic polynomial. Because of the use of relative precision here this tends to give better - precision in the p-adic coefficients. + precision in the `p`-adic coefficients. """ m = self.hecke_matrix(self.prime(), n, use_recurrence) A = PowerSeriesRing(self.base_ring(), 'T') @@ -1472,7 +1471,6 @@ def _lmul_(self, x): sage: f = M.0 sage: 2*f # indirect doctest 2-adic overconvergent modular form of weight-character 12 with q-expansion 2 - 131040/1414477*q ... - """ return OverconvergentModularFormElement(self.parent(), gexp=x * self.gexp()) @@ -1486,7 +1484,6 @@ def _rmul_(self, x): sage: f = M.0 sage: f * 3 # indirect doctest 2-adic overconvergent modular form of weight-character 12 with q-expansion 3 - 196560/1414477*q ... - """ return OverconvergentModularFormElement(self.parent(), gexp=x * self.gexp()) diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index 924ebaf5a60..0b1502d2d9a 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -87,6 +87,7 @@ # AUXILIARY CODE: SPACES OF MODULAR FORMS AND LINEAR ALGEBRA + def compute_G(p, F): r""" Given a power series `F \in R[[q]]^\times`, for some ring `R`, and an @@ -110,7 +111,7 @@ def compute_G(p, F): EXAMPLES:: - sage: E = sage.modular.overconvergent.hecke_series.eisenstein_series_qexp(2, 12, Zmod(9),normalization="constant") + sage: E = sage.modular.overconvergent.hecke_series.eisenstein_series_qexp(2, 12, Zmod(9),normalization='constant') sage: sage.modular.overconvergent.hecke_series.compute_G(3, E) 1 + 3*q + 3*q^4 + 6*q^7 + O(q^12) """ @@ -129,14 +130,12 @@ def low_weight_bases(N, p, m, NN, weightbound): INPUT: - - ``N`` -- positive integer (level). - - ``p`` -- prime. - - ``m``, ``NN`` -- positive integers. - - ``weightbound`` -- (even) positive integer. - - OUTPUT: + - ``N`` -- positive integer (level) + - ``p`` -- prime + - ``m``, ``NN`` -- positive integers + - ``weightbound`` -- (even) positive integer - - list of lists of `q`-expansions modulo `(p^m,q^{NN})`. + OUTPUT: list of lists of `q`-expansions modulo `(p^m,q^{NN})` EXAMPLES:: @@ -145,7 +144,6 @@ def low_weight_bases(N, p, m, NN, weightbound): [[1 + 24*q + 24*q^2 + 96*q^3 + 24*q^4 + O(q^5)], [1 + 115*q^2 + 35*q^4 + O(q^5), q + 8*q^2 + 28*q^3 + 64*q^4 + O(q^5)], [1 + 121*q^2 + 118*q^4 + O(q^5), q + 32*q^2 + 119*q^3 + 24*q^4 + O(q^5)]] - """ generators = [] @@ -154,22 +152,21 @@ def low_weight_bases(N, p, m, NN, weightbound): generators.append(list(b)) return generators + def random_low_weight_bases(N,p,m,NN,weightbound): r""" - Returns list of random integral bases of modular forms of level `N` and + Return list of random integral bases of modular forms of level `N` and (even) weight at most weightbound with coefficients reduced modulo `(p^m,q^{NN})`. INPUT: - - ``N`` -- positive integer (level). - - ``p`` -- prime. - - ``m``, ``NN`` -- positive integers. - - ``weightbound`` -- (even) positive integer. + - ``N`` -- positive integer (level) + - ``p`` -- prime + - ``m``, ``NN`` -- positive integers + - ``weightbound`` -- (even) positive integer - OUTPUT: - - - list of lists of `q`-expansions modulo `(p^m,q^{NN})`. + OUTPUT: list of lists of `q`-expansions modulo `(p^m,q^{NN})` EXAMPLES:: @@ -185,7 +182,6 @@ def random_low_weight_bases(N,p,m,NN,weightbound): Power Series Ring in q over Ring of integers modulo 49 sage: S[0][0].prec() 5 - """ LWB = low_weight_bases(N,p,m,NN,weightbound) # this is "approximately" row reduced (it's the mod p^n reduction of a @@ -200,9 +196,10 @@ def random_low_weight_bases(N,p,m,NN,weightbound): return RandomLWB + def low_weight_generators(N,p,m,NN): r""" - Returns a list of lists of modular forms, and an even natural number. + Return a list of lists of modular forms, and an even natural number. The first output is a list of lists of modular forms reduced modulo `(p^m,q^{NN})` which generate the `(\ZZ / p^m \ZZ)`-algebra of mod `p^m` @@ -217,13 +214,11 @@ def low_weight_generators(N,p,m,NN): INPUT: - - ``N`` -- positive integer (level). - - ``p`` -- prime. - - ``m``, ``NN`` -- positive integers. + - ``N`` -- positive integer (level) + - ``p`` -- prime + - ``m``, ``NN`` -- positive integers - OUTPUT: - - a tuple consisting of: + OUTPUT: a tuple consisting of: - a list of lists of `q`-expansions modulo `(p^m,q^{NN})`, - an even natural number (twice the length of the list). @@ -252,9 +247,10 @@ def low_weight_generators(N,p,m,NN): return generators, weightbound + def random_solution(B,K): r""" - Returns a random solution in non-negative integers to the equation `a_1 + 2 + Return a random solution in nonnegative integers to the equation `a_1 + 2 a_2 + 3 a_3 + ... + B a_B = K`, using a greedy algorithm. Note that this is *much* faster than using @@ -262,11 +258,9 @@ def random_solution(B,K): INPUT: - - ``B``, ``K`` -- non-negative integers. + - ``B``, ``K`` -- nonnegative integers - OUTPUT: - - - list. + OUTPUT: list EXAMPLES:: @@ -344,27 +338,23 @@ def ech_form(A, p): def random_new_basis_modp(N, p, k, LWBModp, TotalBasisModp, elldash, bound): r""" - Returns a list of lists of lists ``[j, a]`` encoding a choice of basis for - the ith complementary space `W_i`, as explained in the documentation for the + Return a list of lists of lists ``[j, a]`` encoding a choice of basis for + the `i`-th complementary space `W_i`, as explained in the documentation for the function :func:`complementary_spaces_modp`. INPUT: - - ``N`` -- positive integer at least 2 and not divisible by `p` (level). - - ``p`` -- prime at least 5. - - ``k`` -- non-negative integer. - - ``LWBModp`` -- list of list of `q`-expansions modulo - `(p,q^\text{elldash})`. - - ``TotalBasisModp`` -- matrix over `\mathrm{GF}(p)`. - - ``elldash`` -- positive integer. - - ``bound`` -- positive even integer (twice the length of the list - ``LWBModp``). + - ``N`` -- positive integer at least 2 and not divisible by `p` (level) + - ``p`` -- prime at least 5 + - ``k`` -- nonnegative integer + - ``LWBModp`` -- list of list of `q`-expansions modulo `(p,q^\text{elldash})` + - ``TotalBasisModp`` -- matrix over `\mathrm{GF}(p)` + - ``elldash`` -- positive integer + - ``bound`` -- positive even integer (twice the length of the list ``LWBModp``) - OUTPUT: + OUTPUT: list of lists of lists ``[j, a]`` - - A list of lists of lists ``[j, a]``. - - .. note:: + .. NOTE:: As well as having a non-trivial return value, this function also modifies the input matrix ``TotalBasisModp``. @@ -376,7 +366,6 @@ def random_new_basis_modp(N, p, k, LWBModp, TotalBasisModp, elldash, bound): sage: LWBModp = [ [f.change_ring(GF(5)) for f in x] for x in LWB] sage: complementary_spaces_modp(2, 5, 2, 3, 4, LWBModp, 4) # random, indirect doctest [[[[0, 0]]], [[[0, 0], [1, 1]]], [[[0, 0], [1, 0], [1, 1]]], [[[0, 0], [1, 0], [1, 1], [1, 1]]]] - """ R = LWBModp[0][0].parent() @@ -413,17 +402,18 @@ def random_new_basis_modp(N, p, k, LWBModp, TotalBasisModp, elldash, bound): return NewBasisCode + def complementary_spaces_modp(N, p, k0, n, elldash, LWBModp, bound): r""" - Returns a list of lists of lists of lists ``[j, a]``. The pairs ``[j, a]`` + Return a list of lists of lists of lists ``[j, a]``. The pairs ``[j, a]`` encode the choice of the `a`-th element in the `j`-th list of the input ``LWBModp``, i.e., the `a`-th element in a particular basis modulo `(p,q^\text{elldash})` for the space of modular forms of level `\Gamma_0(N)` and weight `2(j+1)`. The list ``[[j_1, a_1], ...,[j_r, a_r]]`` then encodes the product of the r modular forms associated to each ``[j_i, a_i]``; this has weight `k + (p-1)i` for some `0 \le i \le n`; here - the `i` is such that this *list of lists* occurs in the ith list of the - output. The ith list of the output thus encodes a choice of basis for the + the `i` is such that this *list of lists* occurs in the `i`-th list of the + output. The `i`-th list of the output thus encodes a choice of basis for the complementary space `W_i` which occurs in Step 2 of Algorithm 2 in [Lau2011]_. The idea is that one searches for this space `W_i` first modulo `(p,q^\text{elldash})` and then, having found the correct products of @@ -433,16 +423,14 @@ def complementary_spaces_modp(N, p, k0, n, elldash, LWBModp, bound): INPUT: - - ``N`` -- positive integer at least 2 and not divisible by `p` (level). - - ``p`` -- prime at least 5. - - ``k0`` -- integer in range 0 to `p-1`. - - ``n``, ``elldash`` -- positive integers. - - ``LWBModp`` -- list of lists of `q`-expansions over `GF(p)`. - - ``bound`` -- positive even integer (twice the length of the list ``LWBModp``). - - OUTPUT: + - ``N`` -- positive integer at least 2 and not divisible by `p` (level) + - ``p`` -- prime at least 5 + - ``k0`` -- integer in range 0 to `p-1` + - ``n``, ``elldash`` -- positive integers + - ``LWBModp`` -- list of lists of `q`-expansions over `GF(p)` + - ``bound`` -- positive even integer (twice the length of the list ``LWBModp``) - - list of list of list of lists. + OUTPUT: list of list of list of lists EXAMPLES:: @@ -463,10 +451,11 @@ def complementary_spaces_modp(N, p, k0, n, elldash, LWBModp, bound): return CompSpacesCode + def complementary_spaces(N, p, k0, n, mdash, elldashp, elldash, modformsring, bound): r""" - Returns a list ``Ws``, each element in which is a list ``Wi`` of - q-expansions modulo `(p^\text{mdash},q^\text{elldashp})`. The list ``Wi`` is + Return a list ``Ws``, each element in which is a list ``Wi`` of + `q`-expansions modulo `(p^\text{mdash},q^\text{elldashp})`. The list ``Wi`` is a basis for a choice of complementary space in level `\Gamma_0(N)` and weight `k` to the image of weight `k - (p-1)` forms under multiplication by the Eisenstein series `E_{p-1}`. @@ -486,16 +475,16 @@ def complementary_spaces(N, p, k0, n, mdash, elldashp, elldash, modformsring, bo INPUT: - - ``N`` -- positive integer at least 2 and not divisible by p (level). - - ``p`` -- prime at least 5. - - ``k0`` -- integer in range 0 to `p - 1`. - - ``n``, ``mdash``, ``elldashp``, ``elldash`` -- positive integers. - - ``modformsring`` -- ``True`` or ``False``. - - ``bound`` -- positive (even) integer (ignored if ``modformsring`` is True). + - ``N`` -- positive integer at least 2 and not divisible by p (level) + - ``p`` -- prime at least 5 + - ``k0`` -- integer in range 0 to `p - 1` + - ``n``, ``mdash``, ``elldashp``, ``elldash`` -- positive integers + - ``modformsring`` -- boolean + - ``bound`` -- positive (even) integer (ignored if ``modformsring`` is True) OUTPUT: - - list of lists of q-expansions modulo + - list of lists of `q`-expansions modulo `(p^\text{mdash},q^\text{elldashp})`. EXAMPLES:: @@ -522,7 +511,7 @@ def complementary_spaces(N, p, k0, n, mdash, elldashp, elldash, modformsring, bo CompSpacesCode = complementary_spaces_modp(N, p, k0, n, elldash, LWBModp, bound) Ws = [] - Epm1 = eisenstein_series_qexp(p - 1, prec=elldashp, K=Zmod(p**mdash), normalization="constant") + Epm1 = eisenstein_series_qexp(p - 1, prec=elldashp, K=Zmod(p**mdash), normalization='constant') for i in range(n + 1): CompSpacesCodemi = CompSpacesCode[i] Wi = [] @@ -540,9 +529,10 @@ def complementary_spaces(N, p, k0, n, mdash, elldashp, elldash, modformsring, bo # AUXILIARY CODE: KATZ EXPANSIONS + def higher_level_katz_exp(p, N, k0, m, mdash, elldash, elldashp, modformsring, bound): r""" - Returns a matrix `e` of size ``ell x elldashp`` over the integers modulo + Return a matrix `e` of size ``ell x elldashp`` over the integers modulo `p^\text{mdash}`, and the Eisenstein series `E_{p-1} = 1 + .\dots \bmod (p^\text{mdash},q^\text{elldashp})`. The matrix `e` contains the coefficients of the elements `e_{i,s}` in the Katz expansions basis in Step 3 of @@ -552,16 +542,14 @@ def higher_level_katz_exp(p, N, k0, m, mdash, elldash, elldashp, modformsring, b INPUT: - - ``p`` -- prime at least 5. - - ``N`` -- positive integer at least 2 and not divisible by `p` (level). - - ``k0`` -- integer in range 0 to `p-1`. - - ``m``, ``mdash, ``elldash``, ``elldashp`` -- positive integers. - - ``modformsring`` -- ``True`` or ``False``. - - ``bound`` -- positive (even) integer. - - OUTPUT: + - ``p`` -- prime at least 5 + - ``N`` -- positive integer at least 2 and not divisible by `p` (level) + - ``k0`` -- integer in range 0 to `p-1` + - ``m``, ``mdash, ``elldash``, ``elldashp`` -- positive integers + - ``modformsring`` -- boolean + - ``bound`` -- positive (even) integer - - matrix and `q`-expansion. + OUTPUT: matrix and `q`-expansion EXAMPLES:: @@ -579,7 +567,7 @@ def higher_level_katz_exp(p, N, k0, m, mdash, elldash, elldashp, modformsring, b """ ordr = 1 / (p + 1) S = Zmod(p ** mdash) - Ep1 = eisenstein_series_qexp(p - 1, prec=elldashp, K=S, normalization="constant") + Ep1 = eisenstein_series_qexp(p - 1, prec=elldashp, K=S, normalization='constant') n = floor(((p + 1) / (p - 1)) * (m + 1)) Wjs = complementary_spaces(N, p, k0, n, mdash, elldashp, elldash, modformsring, bound) @@ -606,9 +594,10 @@ def higher_level_katz_exp(p, N, k0, m, mdash, elldash, elldashp, modformsring, b return M, Ep1 + def compute_elldash(p, N, k0, n): r""" - Returns the "Sturm bound" for the space of modular forms of level + Return the "Sturm bound" for the space of modular forms of level `\Gamma_0(N)` and weight `k_0 + n(p-1)`. .. SEEALSO:: @@ -617,13 +606,11 @@ def compute_elldash(p, N, k0, n): INPUT: - - ``p`` -- prime. - - ``N`` -- positive integer (level). - - ``k0``, ``n`` -- non-negative integers not both zero. - - OUTPUT: + - ``p`` -- prime + - ``N`` -- positive integer (level) + - ``k0``, ``n`` -- nonnegative integers not both zero - - positive integer. + OUTPUT: positive integer EXAMPLES:: @@ -636,10 +623,11 @@ def compute_elldash(p, N, k0, n): # *** DEGREE BOUND ON HECKE SERIES *** + def hecke_series_degree_bound(p, N, k, m): r""" - Returns the ``Wan bound`` on the degree of the characteristic series of the - Atkin operator on p-adic overconvergent modular forms of level + Return the ``Wan bound`` on the degree of the characteristic series of the + Atkin operator on `p`-adic overconvergent modular forms of level `\Gamma_0(N)` and weight `k` when reduced modulo `p^m`. This bound depends only upon `p, k \pmod{p-1}`, and `N`. It uses Lemma 3.1 in @@ -647,14 +635,12 @@ def hecke_series_degree_bound(p, N, k, m): INPUT: - - ``p`` -- prime at least 5. - - ``N`` -- positive integer not divisible by `p`. - - ``k`` -- even integer. - - ``m`` -- positive integer. + - ``p`` -- prime at least 5 + - ``N`` -- positive integer not divisible by `p` + - ``k`` -- even integer + - ``m`` -- positive integer - OUTPUT: - - A non-negative integer. + OUTPUT: nonnegative integer EXAMPLES:: @@ -682,6 +668,7 @@ def hecke_series_degree_bound(p, N, k, m): # Returns matrix A modulo p^m from Step 6 of Algorithm 2. + def higher_level_UpGj(p, N, klist, m, modformsring, bound, extra_data=False): r""" Return a list ``[A_k]`` of square matrices over ``IntegerRing(p^m)`` @@ -696,13 +683,13 @@ def higher_level_UpGj(p, N, klist, m, modformsring, bound, extra_data=False): INPUT: - - ``p`` -- prime at least 5. - - ``N`` -- integer at least 2 and not divisible by `p` (level). - - ``klist`` -- list of integers all congruent modulo `(p-1)` (the weights). - - ``m`` -- positive integer. - - ``modformsring`` -- ``True`` or ``False``. - - ``bound`` -- (even) positive integer. - - ``extra_data`` -- (default: ``False``) boolean. + - ``p`` -- prime at least 5 + - ``N`` -- integer at least 2 and not divisible by `p` (level) + - ``klist`` -- list of integers all congruent modulo `(p-1)` (the weights) + - ``m`` -- positive integer + - ``modformsring`` -- boolean + - ``bound`` -- (even) positive integer + - ``extra_data`` -- boolean (default: ``False``) OUTPUT: @@ -809,12 +796,12 @@ def higher_level_UpGj(p, N, klist, m, modformsring, bound, extra_data=False): def compute_Wi(k, p, h, hj, E4, E6): r""" - This function computes a list `W_i` of q-expansions, together with an + This function computes a list `W_i` of `q`-expansions, together with an auxiliary quantity `h^j` (see below) which is to be used on the next - call of this function. (The precision is that of input q-expansions.) + call of this function. (The precision is that of input `q`-expansions.) The list `W_i` is a certain subset of a basis of the modular forms of - weight `k` and level 1. Suppose `(a, b)` is the pair of non-negative + weight `k` and level 1. Suppose `(a, b)` is the pair of nonnegative integers with `4a + 6b = k` and `a` minimal among such pairs. Then this space has a basis given by @@ -836,16 +823,16 @@ def compute_Wi(k, p, h, hj, E4, E6): INPUT: - - ``k`` -- non-negative integer. - - ``p`` -- prime at least 5. - - ``h`` -- q-expansion of `h` (to some finite precision). - - ``hj`` -- q-expansion of `h^j` where `j` is the dimension of the space of + - ``k`` -- nonnegative integer + - ``p`` -- prime at least 5 + - ``h`` -- `q`-expansion of `h` (to some finite precision) + - ``hj`` -- `q`-expansion of `h^j` where `j` is the dimension of the space of modular forms of level 1 and weight `k - (p-1)` (to same finite - precision). - - ``E4`` -- `q`-expansion of `E_4` (to same finite precision). - - ``E6`` -- `q`-expansion of `E_6` (to same finite precision). + precision) + - ``E4`` -- `q`-expansion of `E_4` (to same finite precision) + - ``E6`` -- `q`-expansion of `E_6` (to same finite precision) - The Eisenstein series q-expansions should be normalized to have constant + The Eisenstein series `q`-expansions should be normalized to have constant term 1. OUTPUT: @@ -859,8 +846,8 @@ def compute_Wi(k, p, h, hj, E4, E6): sage: prec = 10 sage: k = 24 sage: S = Zmod(17^3) - sage: E4 = eisenstein_series_qexp(4, prec, K=S, normalization="constant") - sage: E6 = eisenstein_series_qexp(6, prec, K=S, normalization="constant") + sage: E4 = eisenstein_series_qexp(4, prec, K=S, normalization='constant') + sage: E6 = eisenstein_series_qexp(6, prec, K=S, normalization='constant') sage: h = delta_qexp(prec, K=S) / E6^2 sage: from sage.modular.dims import dimension_modular_forms sage: j = dimension_modular_forms(1, k - (p - 1)) @@ -897,9 +884,10 @@ def compute_Wi(k, p, h, hj, E4, E6): return Wi, hj + def katz_expansions(k0, p, ellp, mdash, n): r""" - Returns a list `e` of `q`-expansions, and the Eisenstein series `E_{p-1} = 1 + + Return a list `e` of `q`-expansions, and the Eisenstein series `E_{p-1} = 1 + \dots`, all modulo `(p^\text{mdash},q^\text{ellp})`. The list `e` contains the elements `e_{i,s}` in the Katz expansions basis in Step 3 of Algorithm 1 in [Lau2011]_ when one takes as input to that algorithm `p,m` and `k` and define @@ -907,9 +895,9 @@ def katz_expansions(k0, p, ellp, mdash, n): INPUT: - - ``k0`` -- integer in range 0 to `p - 1`. - - ``p`` -- prime at least 5. - - ``ellp``, ``mdash``, ``n`` -- positive integers. + - ``k0`` -- integer in range 0 to `p - 1` + - ``p`` -- prime at least 5 + - ``ellp``, ``mdash``, ``n`` -- positive integers OUTPUT: @@ -925,9 +913,9 @@ def katz_expansions(k0, p, ellp, mdash, n): """ S = Zmod(p ** mdash) - Ep1 = eisenstein_series_qexp(p - 1, ellp, K=S, normalization="constant") - E4 = eisenstein_series_qexp(4, ellp, K=S, normalization="constant") - E6 = eisenstein_series_qexp(6, ellp, K=S, normalization="constant") + Ep1 = eisenstein_series_qexp(p - 1, ellp, K=S, normalization='constant') + E4 = eisenstein_series_qexp(4, ellp, K=S, normalization='constant') + E6 = eisenstein_series_qexp(6, ellp, K=S, normalization='constant') delta = delta_qexp(ellp, K=S) h = delta / E6 ** 2 @@ -949,6 +937,7 @@ def katz_expansions(k0, p, ellp, mdash, n): # *** MAIN FUNCTION FOR LEVEL 1 *** + def level1_UpGj(p, klist, m, extra_data=False): r""" Return a list `[A_k]` of square matrices over ``IntegerRing(p^m)`` @@ -963,10 +952,10 @@ def level1_UpGj(p, klist, m, extra_data=False): INPUT: - - ``p`` -- prime at least 5. - - ``klist`` -- list of integers congruent modulo `(p-1)` (the weights). - - ``m`` -- positive integer. - - ``extra_data`` -- (default: ``False``) boolean + - ``p`` -- prime at least 5 + - ``klist`` -- list of integers congruent modulo `(p-1)` (the weights) + - ``m`` -- positive integer + - ``extra_data`` -- boolean (default: ``False``) OUTPUT: @@ -987,7 +976,6 @@ def level1_UpGj(p, klist, m, extra_data=False): ] sage: len(level1_UpGj(7, [100], 5, extra_data=True)) 4 - """ # Step 1 t = cputime() @@ -1062,15 +1050,17 @@ def level1_UpGj(p, klist, m, extra_data=False): # *** CODE FOR GENERAL LEVEL *** + def is_valid_weight_list(klist, p): r""" This function checks that ``klist`` is a nonempty list of integers all of - which are congruent modulo `(p-1)`. Otherwise, it will raise a ValueError. + which are congruent modulo `(p-1)`. Otherwise, it will raise a + :exc:`ValueError`. INPUT: - - ``klist`` -- list of integers. - - ``p`` -- prime. + - ``klist`` -- list of integers + - ``p`` -- prime EXAMPLES:: @@ -1093,10 +1083,11 @@ def is_valid_weight_list(klist, p): if (klist[i] % (p-1)) != k0: raise ValueError("List of weights must be all congruent modulo p-1 = %s, but given list contains %s and %s which are not congruent" % (p - 1, klist[0], klist[i])) + def hecke_series(p, N, klist, m, modformsring=False, weightbound=6): r""" - Returns the characteristic series modulo `p^m` of the Atkin operator `U_p` - acting upon the space of p-adic overconvergent modular forms of level + Return the characteristic series modulo `p^m` of the Atkin operator `U_p` + acting upon the space of `p`-adic overconvergent modular forms of level `\Gamma_0(N)` and weight ``klist``. The input ``klist`` may also be a list of weights congruent modulo `(p-1)`, @@ -1108,7 +1099,7 @@ def hecke_series(p, N, klist, m, modformsring=False, weightbound=6): If ``modformsring`` is ``True``, then for `N > 1` the algorithm computes at one step ``ModularFormsRing(N).generators()``. This will often be faster but the algorithm will default to ``modformsring=False`` if the generators - found are not p-adically integral. Note that ``modformsring`` is ignored + found are not `p`-adically integral. Note that ``modformsring`` is ignored for `N = 1` and the ring structure of modular forms is *always* used in this case. @@ -1122,18 +1113,15 @@ def hecke_series(p, N, klist, m, modformsring=False, weightbound=6): INPUT: - - ``p`` -- a prime greater than or equal to 5. - - ``N`` -- a positive integer not divisible by `p`. - - ``klist`` -- either a list of integers congruent modulo `(p-1)`, or a single integer. - - ``m`` -- a positive integer. - - ``modformsring`` -- ``True`` or ``False`` (default: ``False``). - Ignored if `N = 1`. + - ``p`` -- a prime greater than or equal to 5 + - ``N`` -- positive integer not divisible by `p` + - ``klist`` -- either a list of integers congruent modulo `(p-1)`, or a single integer + - ``m`` -- positive integer + - ``modformsring`` -- boolean (default: ``False``); ignored if `N = 1` - ``weightbound`` -- a positive even integer (default: 6). Ignored - if `N = 1` or ``modformsring`` is ``True``. - - OUTPUT: + if `N = 1` or ``modformsring`` is ``True`` - Either a list of polynomials or a single polynomial over the integers modulo `p^m`. + OUTPUT: either a list of polynomials or a single polynomial over the integers modulo `p^m` EXAMPLES:: diff --git a/src/sage/modular/overconvergent/weightspace.py b/src/sage/modular/overconvergent/weightspace.py index e9478c40a90..40110016c52 100644 --- a/src/sage/modular/overconvergent/weightspace.py +++ b/src/sage/modular/overconvergent/weightspace.py @@ -85,9 +85,11 @@ _wscache = {} + + def WeightSpace_constructor(p, base_ring=None): r""" - Construct the p-adic weight space for the given prime p. + Construct the `p`-adic weight space for the given prime p. A `p`-adic weight is a continuous character `\ZZ_p^\times \to \CC_p^\times`. @@ -281,8 +283,8 @@ def _coerce_map_from_(self, other): def _coerce_in_wtchar(self, x): r""" - Convert in a weight-character whose parent is different from self (with - has the prime, but possibly different base ring). + Convert in a weight-character whose parent is different from ``self`` + (with has the prime, but possibly different base ring). EXAMPLES:: @@ -300,7 +302,7 @@ def _coerce_in_wtchar(self, x): class WeightCharacter(Element): r""" - Abstract base class representing an element of the p-adic weight space + Abstract base class representing an element of the `p`-adic weight space `Hom(\ZZ_p^\times, \CC_p^\times)`. """ @@ -336,7 +338,7 @@ def base_extend(self, R): def is_even(self) -> bool: r""" - Return True if this weight-character sends -1 to +1. + Return ``True`` if this weight-character sends -1 to +1. EXAMPLES:: @@ -353,7 +355,7 @@ def is_even(self) -> bool: def pAdicEisensteinSeries(self, ring, prec=20): r""" - Calculate the q-expansion of the p-adic Eisenstein series of given + Calculate the `q`-expansion of the `p`-adic Eisenstein series of given weight-character, normalised so the constant term is 1. EXAMPLES:: @@ -393,7 +395,7 @@ def values_on_gens(self): def is_trivial(self) -> bool: r""" - Return True if and only if this is the trivial character. + Return ``True`` if and only if this is the trivial character. EXAMPLES:: @@ -424,7 +426,7 @@ def _richcmp_(self, other, op) -> bool: def Lvalue(self): r""" - Return the value of the p-adic L-function of `\QQ`, which can be + Return the value of the `p`-adic `L`-function of `\QQ`, which can be regarded as a rigid-analytic function on weight space, evaluated at this character. @@ -440,10 +442,10 @@ def Lvalue(self): def one_over_Lvalue(self): r""" - Return the reciprocal of the p-adic L-function evaluated at this + Return the reciprocal of the `p`-adic `L`-function evaluated at this weight-character. - If the weight-character is odd, then the L-function + If the weight-character is odd, then the `L`-function is zero, so an error will be raised. EXAMPLES:: @@ -526,7 +528,7 @@ def __call__(self, x): sage: kappa(13 + 4*29 + 11*29^2 + O(29^3)) 9 + 21*29 + 27*29^2 + O(29^3) - When the character chi is defined over a p-adic field, the results returned are inexact:: + When the character chi is defined over a `p`-adic field, the results returned are inexact:: sage: kappa = pAdicWeightSpace(29)(13, DirichletGroup(29, Qp(29)).0^14) sage: kappa(1) @@ -648,13 +650,13 @@ def teichmuller_type(self): def Lvalue(self): r""" - Return the value of the p-adic L-function of `\QQ` evaluated at + Return the value of the `p`-adic `L`-function of `\QQ` evaluated at this weight-character. If the character is `x \mapsto x^k \chi(x)` where `k > 0` and `\chi` has conductor a power of `p`, this is an element of the number field generated by the values of `\chi`, equal to - the value of the complex L-function `L(1-k, \chi)`. If `\chi` is + the value of the complex `L`-function `L(1-k, \chi)`. If `\chi` is trivial, it is equal to `(1 - p^{k-1})\zeta(1-k)`. At present this is not implemented in any other cases, except the @@ -689,10 +691,10 @@ class ArbitraryWeight(WeightCharacter): def __init__(self, parent, w, t): r""" - Create the element of p-adic weight space in the given component + Create the element of `p`-adic weight space in the given component mapping 1 + p to w. - Here w must be an element of a p-adic field, with finite + Here w must be an element of a `p`-adic field, with finite precision. EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/dist.pyx b/src/sage/modular/pollack_stevens/dist.pyx index 9a05c4ad758..85cccd3bb11 100644 --- a/src/sage/modular/pollack_stevens/dist.pyx +++ b/src/sage/modular/pollack_stevens/dist.pyx @@ -3,7 +3,7 @@ """ `p`-adic distributions spaces -This module implements p-adic distributions, a `p`-adic Banach +This module implements `p`-adic distributions, a `p`-adic Banach space dual to locally analytic functions on a disc. EXAMPLES:: @@ -56,17 +56,17 @@ def get_dist_classes(p, prec_cap, base, symk, implementation): INPUT: - - ``p`` -- prime + - ``p`` -- prime - - ``prec_cap`` -- The `p`-adic precision cap + - ``prec_cap`` -- the `p`-adic precision cap - - ``base`` -- The base ring + - ``base`` -- the base ring - - ``symk`` -- An element of Symk + - ``symk`` -- an element of Symk - - ``implementation`` -- string; If not None, override the + - ``implementation`` -- string; if not ``None``, override the automatic choice of implementation. May be 'long' or 'vector', - otherwise raise a :class:`NotImplementedError` + otherwise raise a :exc:`NotImplementedError`. OUTPUT: @@ -99,7 +99,7 @@ cdef class Dist(ModuleElement): INPUT: - - ``n`` -- an integer or slice, to be passed on to moments. + - ``n`` -- integer or slice, to be passed on to moments OUTPUT: @@ -121,9 +121,7 @@ cdef class Dist(ModuleElement): r""" Return the vector of moments. - OUTPUT: - - - the vector of moments + OUTPUT: the vector of moments EXAMPLES:: @@ -142,9 +140,7 @@ cdef class Dist(ModuleElement): Normalize so that the precision of the `i`-th moment is `n-i`, where `n` is the number of moments. - OUTPUT: - - - Normalized entries of the distribution + OUTPUT: normalized entries of the distribution EXAMPLES:: @@ -184,15 +180,13 @@ cdef class Dist(ModuleElement): def scale(self, left): r""" - Scale the moments of the distribution by ``left`` + Scale the moments of the distribution by ``left``. INPUT: - ``left`` -- scalar - OUTPUT: - - - Scales the moments by ``left`` + OUTPUT: scales the moments by ``left`` EXAMPLES:: @@ -219,8 +213,9 @@ cdef class Dist(ModuleElement): def is_zero(self, p=None, M=None): r""" - Return True if the `i`-th moment is zero for all `i` (case ``M`` is None) - or zero modulo `p^{M-i}` for all `i` (when ``M`` is not None). + Return ``True`` if the `i`-th moment is zero for all `i` (case ``M`` is + ``None``) or zero modulo `p^{M-i}` for all `i` (when ``M`` is not + ``None``). Note that some moments are not known to precision ``M``, in which case they are only checked to be equal to zero modulo the @@ -232,9 +227,7 @@ cdef class Dist(ModuleElement): - ``M`` -- precision - OUTPUT: - - - True/False + OUTPUT: boolean EXAMPLES:: @@ -292,9 +285,9 @@ cdef class Dist(ModuleElement): def find_scalar(self, _other, p, M=None, check=True): r""" Return an ``alpha`` with ``other = self * alpha``, or raises - a :class:`ValueError`. + a :exc:`ValueError`. - It will also raise a :class:`ValueError` if this distribution is zero. + It will also raise a :exc:`ValueError` if this distribution is zero. INPUT: @@ -302,15 +295,13 @@ cdef class Dist(ModuleElement): - ``p`` -- an integral prime (only used if the parent is not a Symk) - - ``M`` -- (default: None) an integer, the relative precision + - ``M`` -- (default: ``None``) an integer, the relative precision to which the scalar must be determined - - ``check`` -- (default: ``True``) boolean, whether to validate - that ``other`` is actually a multiple of this element. - - OUTPUT: + - ``check`` -- boolean (default: ``True``); whether to validate + that ``other`` is actually a multiple of this element - - A scalar ``alpha`` with ``other = self * alpha``. + OUTPUT: a scalar ``alpha`` with ``other = self * alpha`` EXAMPLES:: @@ -416,9 +407,9 @@ cdef class Dist(ModuleElement): def find_scalar_from_zeroth_moment(self, _other, p, M=None, check=True): r""" Return an ``alpha`` with ``other = self * alpha`` using only - the zeroth moment, or raises a :class:`ValueError`. + the zeroth moment, or raises a :exc:`ValueError`. - It will also raise a :class:`ValueError` if the zeroth moment of the + It will also raise a :exc:`ValueError` if the zeroth moment of the distribution is zero. INPUT: @@ -427,15 +418,13 @@ cdef class Dist(ModuleElement): - ``p`` -- an integral prime (only used if the parent is not a Symk) - - ``M`` -- (default: None) an integer, the relative precision + - ``M`` -- (default: ``None``) an integer, the relative precision to which the scalar must be determined - - ``check`` -- (default: ``True``) boolean, whether to validate - that ``other`` is actually a multiple of this element. - - OUTPUT: + - ``check`` -- boolean (default: ``True``); whether to validate + that ``other`` is actually a multiple of this element - - A scalar ``alpha`` with ``other = self * alpha``. + OUTPUT: a scalar ``alpha`` with ``other = self * alpha`` EXAMPLES:: @@ -538,12 +527,12 @@ cdef class Dist(ModuleElement): INPUT: - - ``p`` -- (default: None) a positive integral prime + - ``p`` -- (default: ``None``) a positive integral prime OUTPUT: - - the largest integer `m` so that `p^m` divides the `0`-th - moment, `p^{m-1}` divides the first moment, etc. + The largest integer `m` so that `p^m` divides the `0`-th + moment, `p^{m-1}` divides the first moment, etc. EXAMPLES:: @@ -565,11 +554,9 @@ cdef class Dist(ModuleElement): INPUT: - - ``p`` -- (default: None) a positive integral prime + - ``p`` -- (default: ``None``) a positive integral prime - OUTPUT: - - - an integer + OUTPUT: integer .. WARNING:: @@ -603,12 +590,12 @@ cdef class Dist(ModuleElement): INPUT: - - ``new_base_ring`` -- (default: None) a ring giving the - desired base ring of the result. + - ``new_base_ring`` -- (default: ``None``) a ring giving the + desired base ring of the result OUTPUT: - - An element of `Sym^k(K)`, where `K` is the specified base ring. + An element of `Sym^k(K)`, where `K` is the specified base ring. EXAMPLES:: @@ -635,15 +622,15 @@ cdef class Dist(ModuleElement): INPUT: - - ``p`` -- (default: None) a positive integral prime. If None - then ``p`` must be available in the parent. + - ``p`` -- (default: ``None``) a positive integral prime. If ``None`` + then ``p`` must be available in the parent - - ``M`` -- (default: None) a positive integer giving the - desired number of moments. If None, returns a distribution having one + - ``M`` -- (default: ``None``) a positive integer giving the + desired number of moments. If ``None``, returns a distribution having one more moment than this one. - - ``new_base_ring`` -- (default: None) a ring giving the desired base - ring of the result. If None, a base ring is chosen automatically. + - ``new_base_ring`` -- (default: ``None``) a ring giving the desired base + ring of the result. If ``None``, a base ring is chosen automatically. OUTPUT: @@ -738,10 +725,10 @@ cdef class Dist_vector(Dist): - ``parent`` -- a :class:`distributions.OverconvergentDistributions_class` or :class:`distributions.Symk_class` instance - - ``ordp`` -- an integer. This MUST be zero in the case of Symk - of an exact ring. + - ``ordp`` -- integer; this *must* be zero in the case of Symk + of an exact ring - - ``check`` -- (default: ``True``) boolean, whether to validate input + - ``check`` -- boolean (default: ``True``); whether to validate input EXAMPLES:: @@ -756,7 +743,6 @@ cdef class Dist_vector(Dist): sage: Symk(4)(0) (0, 0, 0, 0, 0) - """ # if not hasattr(parent,'Element'): # parent, moments = moments, parent @@ -801,7 +787,7 @@ cdef class Dist_vector(Dist): cdef Dist_vector _new_c(self): r""" - Creates an empty distribution. + Create an empty distribution. Note that you MUST fill in the ordp attribute on the resulting distribution. @@ -852,7 +838,7 @@ cdef class Dist_vector(Dist): sage: QQ(d) 4/3 - We get a :class:`TypeError` if there is more than 1 moment:: + We get a :exc:`TypeError` if there is more than 1 moment:: sage: D = Symk(1); d = D([1,2]); d (1, 2) @@ -875,7 +861,6 @@ cdef class Dist_vector(Dist): sage: d = D([1,2,3,4,5]); e = D([2,3,4,5,6]) sage: d == e # indirect doctest False - """ return len(self._moments) @@ -895,7 +880,7 @@ cdef class Dist_vector(Dist): cdef Dist_vector _addsub(self, Dist_vector right, bint negate): r""" - Common code for the sum and the difference of two distributions + Common code for the sum and the difference of two distributions. EXAMPLES:: @@ -905,7 +890,6 @@ cdef class Dist_vector(Dist): (5, 7, 9) sage: u - v # indirect doctest (-3, -3, -3) - """ cdef Dist_vector ans = self._new_c() cdef long aprec = min(self.ordp + len(self._moments), right.ordp + len(right._moments)) @@ -1002,9 +986,7 @@ cdef class Dist_vector(Dist): distributions, the precision is the integer `m` so that the sequence of moments is known modulo `Fil^m`. - OUTPUT: - - - An integer giving the number of moments. + OUTPUT: integer giving the number of moments EXAMPLES:: @@ -1051,9 +1033,7 @@ cdef class Dist_vector(Dist): parent is a space of distributions, then normalize reduces the `i`-th moment modulo `p^{N-i}`. - OUTPUT: - - - this distribution, after normalizing. + OUTPUT: this distribution, after normalizing .. WARNING:: @@ -1099,8 +1079,8 @@ cdef class Dist_vector(Dist): INPUT: - - ``M`` -- a positive integer less than the precision of this - distribution. + - ``M`` -- positive integer less than the precision of this + distribution OUTPUT: @@ -1209,10 +1189,10 @@ cdef class WeightKAction(Action): See the documentation of :class:`sage.modular.pollack_stevens.distributions.OverconvergentDistributions_factory` for more details. - - ``adjuster`` -- a callable object that turns matrices into 4-tuples. - - ``on_left`` -- whether this action should be on the left. + - ``adjuster`` -- a callable object that turns matrices into 4-tuples + - ``on_left`` -- whether this action should be on the left - ``dettwist`` -- a power of the determinant to twist by - - ``padic`` -- if True, define an action of `p`-adic matrices (not just integer ones) + - ``padic`` -- if ``True``, define an action of `p`-adic matrices (not just integer ones) EXAMPLES:: @@ -1278,8 +1258,8 @@ cdef class WeightKAction(Action): - ``g`` -- an instance of :class:`sage.matrix.matrix_generic_dense.Matrix_generic_dense` - - ``M`` -- a positive integer giving the precision at which - ``g`` should act. + - ``M`` -- positive integer giving the precision at which + ``g`` should act OUTPUT: @@ -1336,8 +1316,8 @@ cdef class WeightKAction(Action): - ``g`` -- a `2 \times 2` instance of :class:`sage.matrices.matrix_integer_dense.Matrix_integer_dense` - - ``M`` -- a positive integer giving the precision at which - ``g`` should act. + - ``M`` -- positive integer giving the precision at which + ``g`` should act OUTPUT: @@ -1365,8 +1345,8 @@ cdef class WeightKAction_vector(WeightKAction): - ``g`` -- a `2 \times 2` instance of :class:`sage.matrix.matrix_generic_dense.Matrix_generic_dense` - - ``M`` -- a positive integer giving the precision at which - ``g`` should act. + - ``M`` -- positive integer giving the precision at which + ``g`` should act OUTPUT: @@ -1425,14 +1405,12 @@ cdef class WeightKAction_vector(WeightKAction): INPUT: - ``_v`` -- a :class:`Dist_vector` instance, the distribution - on which to act. + on which to act - ``g`` -- a `2 \times 2` instance of - :class:`sage.matrix.matrix_integer_dense.Matrix_integer_dense`. + :class:`sage.matrix.matrix_integer_dense.Matrix_integer_dense` - OUTPUT: - - - the distribution ``_v * g``. + OUTPUT: the distribution ``_v * g`` EXAMPLES:: @@ -1441,7 +1419,6 @@ cdef class WeightKAction_vector(WeightKAction): sage: g = Matrix(ZZ,2,2,[3,-1,1,0]) sage: v * D._act.actor()(g) # indirect doctest (40, -9, 2) - """ # if g is a matrix it needs to be immutable # hashing on arithmetic_subgroup_elements is by str diff --git a/src/sage/modular/pollack_stevens/distributions.py b/src/sage/modular/pollack_stevens/distributions.py index a11240613fb..80bc25b22d9 100644 --- a/src/sage/modular/pollack_stevens/distributions.py +++ b/src/sage/modular/pollack_stevens/distributions.py @@ -63,16 +63,16 @@ class OverconvergentDistributions_factory(UniqueFactory): INPUT: - ``k`` -- nonnegative integer - - ``p`` -- prime number or None - - ``prec_cap`` -- positive integer or None - - ``base`` -- ring or None - - ``character`` -- a Dirichlet character or None - - ``adjuster`` -- None or callable that turns 2 x 2 matrices into a 4-tuple - - ``act_on_left`` -- bool (default: ``False``) - - ``dettwist`` -- integer or None (interpreted as 0) + - ``p`` -- prime number or ``None`` + - ``prec_cap`` -- positive integer or ``None`` + - ``base`` -- ring or ``None`` + - ``character`` -- a Dirichlet character or ``None`` + - ``adjuster`` -- ``None`` or callable that turns 2 x 2 matrices into a 4-tuple + - ``act_on_left`` -- boolean (default: ``False``) + - ``dettwist`` -- integer or ``None`` (interpreted as 0) - ``act_padic`` -- whether monoid should allow `p`-adic coefficients - - ``implementation`` -- string (default: None). - Either None (for automatic), 'long', or 'vector' + - ``implementation`` -- string (default: ``None``); either ``None`` (for + automatic), ``'long'``, or ``'vector'`` EXAMPLES:: @@ -152,14 +152,16 @@ class Symk_factory(UniqueFactory): INPUT: - - ``k`` -- (integer): the degree (degree `k` corresponds to weight `k + 2` modular forms) - - ``base`` -- (ring, default None): the base ring (None is interpreted as `\QQ`) - - ``character`` -- (Dirichlet character or None, default None) the character - - ``adjuster`` -- (None or a callable that turns - `2 \times 2` matrices into a 4-tuple, default None) - - ``act_on_left`` -- (boolean, default: ``False``) whether to have the group acting - on the left rather than the right. - - ``dettwist`` (integer or None) -- power of determinant to twist by + - ``k`` -- integer; the degree (degree `k` corresponds to weight `k + 2` + modular forms) + - ``base`` -- ring (default: ``None``); the base ring (``None`` is + interpreted as `\QQ`) + - ``character`` -- Dirichlet character or ``None`` (default: ``None``) + - ``adjuster`` -- ``None`` or a callable that turns `2 \times 2` matrices + into a 4-tuple (default: ``None``) + - ``act_on_left`` -- boolean (default: ``False``); whether to have the + group acting on the left rather than the right + - ``dettwist`` -- integer or ``None``; power of determinant to twist by EXAMPLES:: @@ -234,18 +236,18 @@ class OverconvergentDistributions_abstract(Module): INPUT: - - ``k`` -- integer; `k` is the usual modular forms weight minus 2 - - ``p`` -- None or prime - - ``prec_cap`` -- None or positive integer - - ``base`` -- None or the base ring over which to construct the distributions - - ``character`` -- None or Dirichlet character - - ``adjuster`` -- None or a way to specify the action among different conventions - - ``act_on_left`` -- bool (default: ``False``) - - ``dettwist`` -- None or integer (twist by determinant). Ignored for Symk spaces - - ``act_padic`` -- bool (default: ``False``) If true, will allow - action by `p`-adic matrices. - - ``implementation`` -- string (default: None) Either automatic (if None), - 'vector' or 'long'. + - ``k`` -- integer; `k` is the usual modular forms weight minus 2 + - ``p`` -- ``None`` or prime + - ``prec_cap`` -- ``None`` or positive integer + - ``base`` -- ``None`` or the base ring over which to construct the distributions + - ``character`` -- ``None`` or Dirichlet character + - ``adjuster`` -- ``None`` or a way to specify the action among different conventions + - ``act_on_left`` -- boolean (default: ``False``) + - ``dettwist`` -- ``None`` or integer (twist by determinant); ignored for Symk spaces + - ``act_padic`` -- boolean (default: ``False``); if ``True``, will allow + action by `p`-adic matrices + - ``implementation`` -- string (default: ``None``); either automatic (if ``None``), + ``'vector'`` or ``'long'`` EXAMPLES:: @@ -307,7 +309,7 @@ def __init__(self, k, p=None, prec_cap=None, base=None, character=None, def _element_constructor_(self, val, **kwargs): """ - Construct a distribution from data in ``val`` + Construct a distribution from data in ``val``. EXAMPLES:: @@ -378,9 +380,7 @@ def prime(self): In case this space is Symk of a non-padic field, we return 0. - OUTPUT: - - - a prime or 0 + OUTPUT: a prime or 0 EXAMPLES:: @@ -412,9 +412,7 @@ def weight(self): The standard caveat applies, namely that the weight of `Sym^k` is defined to be `k`, not `k+2`. - OUTPUT: - - nonnegative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -453,9 +451,9 @@ def lift(self, p=None, M=None, new_base_ring=None): INPUT: - - ``p`` -- prime or None - - ``M`` -- nonnegative integer or None - - ``new_base_ring`` -- ring or None + - ``p`` -- prime or ``None`` + - ``M`` -- nonnegative integer or ``None`` + - ``new_base_ring`` -- ring or ``None`` EXAMPLES:: @@ -502,7 +500,8 @@ def approx_module(self, M=None): INPUT: - - ``M`` -- None or nonnegative integer that is at most the precision cap + - ``M`` -- ``None`` or nonnegative integer that is at most the + precision cap EXAMPLES:: @@ -540,11 +539,11 @@ def approx_module(self, M=None): def random_element(self, M=None, **args): """ Return a random element of the `M`-th approximation module with - non-negative valuation. + nonnegative valuation. INPUT: - - ``M`` -- None or a nonnegative integer + - ``M`` -- ``None`` or a nonnegative integer EXAMPLES:: @@ -591,8 +590,8 @@ def basis(self, M=None): INPUT: - - ``M`` -- (Default: None) If not None, specifies the ``M``-th approximation module, - in case that this makes sense. + - ``M`` -- (default: ``None``) if not ``None``, specifies the ``M``-th + approximation module, in case that this makes sense EXAMPLES:: @@ -620,7 +619,7 @@ def basis(self, M=None): def _an_element_(self): """ - Return a typical element of self. + Return a typical element of ``self``. EXAMPLES:: @@ -681,7 +680,6 @@ def _repr_(self): Sym^6 Q^2 twisted by Dirichlet character modulo 7 of conductor 7 mapping 3 |--> -1 sage: Symk(6,character=DirichletGroup(7,QQ).0,dettwist=3) Sym^6 Q^2 * det^3 twisted by Dirichlet character modulo 7 of conductor 7 mapping 3 |--> -1 - """ if self.base_ring() is QQ: V = 'Q^2' @@ -757,7 +755,7 @@ def base_extend(self, new_base_ring): class OverconvergentDistributions_class(OverconvergentDistributions_abstract): r""" - The class of overconvergent distributions + The class of overconvergent distributions. This class represents the module of finite approximation modules, which are finite-dimensional spaces with a `\Sigma_0(N)` action which approximate the module of overconvergent distributions. @@ -827,7 +825,9 @@ def change_ring(self, new_base_ring): """ Return space of distributions like this one, but with the base ring changed. - INPUT: a ring over which the distribution can be coerced. + INPUT: + + - ``new_base_ring`` -- a ring over which the distribution can be coerced EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/fund_domain.py b/src/sage/modular/pollack_stevens/fund_domain.py index 40ebcc84fc1..c9b61b36546 100644 --- a/src/sage/modular/pollack_stevens/fund_domain.py +++ b/src/sage/modular/pollack_stevens/fund_domain.py @@ -38,7 +38,9 @@ def M2Z(x): r""" Create an immutable `2 \times 2` integer matrix from ``x``. - INPUT: anything that can be converted into a `2 \times 2` matrix. + INPUT: + + - ``x`` -- anything that can be converted into a `2 \times 2` matrix EXAMPLES:: @@ -73,21 +75,21 @@ class PollackStevensModularDomain(SageObject): INPUT: - - ``N`` -- a positive integer, the level of the congruence subgroup + - ``N`` -- positive integer, the level of the congruence subgroup `\Gamma_0(N)` - - ``reps`` -- a list of `2 \times 2` matrices, the coset + - ``reps`` -- list of `2 \times 2` matrices, the coset representatives of `Div^0(P^1(\QQ))` - - ``indices`` -- a list of integers; indices of elements in + - ``indices`` -- list of integers; indices of elements in ``reps`` which are generators - - ``rels`` -- a list of list of triples ``(d, A, i)``, one for each + - ``rels`` -- list of list of triples ``(d, A, i)``, one for each coset representative of ``reps`` which describes how to express the elements of ``reps`` in terms of generators specified by ``indices``. See :meth:`relations` for a detailed explanations of these triples. - - ``equiv_ind`` -- a dictionary which maps normalized coordinates on + - ``equiv_ind`` -- dictionary which maps normalized coordinates on `P^1(\ZZ/N\ZZ)` to an integer such that a matrix whose bottom row is equivalent to `[a:b]` in `P^1(\ZZ/N\ZZ)` is in the coset of ``reps[equiv_ind[(a,b)]]`` @@ -110,13 +112,12 @@ class PollackStevensModularDomain(SageObject): Traceback (most recent call last): ... TypeError: unable to coerce to an integer - """ def __init__(self, N, reps, indices, rels, equiv_ind): r""" INPUT: - See :class:`PollackStevensModularDomain`. + See :class:`PollackStevensModularDomain`. EXAMPLES:: @@ -220,11 +221,11 @@ def gens(self): def gen(self, n=0): r""" - Return the ``n``-th generator. + Return the `n`-th generator. INPUT: - - ``n`` -- integer (default: 0), which generator is desired + - ``n`` -- integer (default: 0); which generator is desired EXAMPLES:: @@ -283,7 +284,7 @@ def indices(self, n=None): INPUT: - - ``n`` -- integer (default: None) + - ``n`` -- integer (default: ``None``) OUTPUT: @@ -320,7 +321,7 @@ def reps(self, n=None): INPUT: - - ``n`` -- integer (default: None) + - ``n`` -- integer (default: ``None``) OUTPUT: @@ -368,7 +369,7 @@ def relations(self, A=None): A `\ZZ[\Gamma_0(N)]`-relation expressing the divisor attached to ``A`` in terms of the generating set. The relation is given as a list of - triples ``(d, B, i)`` such that the divisor attached to `A`` is the sum + triples ``(d, B, i)`` such that the divisor attached to ``A`` is the sum of ``d`` times the divisor attached to ``B^{-1} * self.reps(i)``. If ``A`` is an integer, then return this data for the ``A``-th @@ -535,7 +536,6 @@ def P1(self): sage: A = ManinRelations(11) sage: A.P1() The projective line over the integers modulo 11 - """ return self._P @@ -547,7 +547,7 @@ class ManinRelations(PollackStevensModularDomain): INPUT: - - ``N`` -- a positive integer, the level of `\Gamma_0(N)` to work with + - ``N`` -- positive integer, the level of `\Gamma_0(N)` to work with EXAMPLES:: @@ -576,7 +576,6 @@ class ManinRelations(PollackStevensModularDomain): Traceback (most recent call last): ... ValueError: N must be a positive integer - """ def __init__(self, N): r""" @@ -584,7 +583,7 @@ def __init__(self, N): INPUT: - - ``N`` -- a positive integer, the level of `\Gamma_0(N)` to work with + - ``N`` -- positive integer; the level of `\Gamma_0(N)` to work with EXAMPLES:: @@ -895,9 +894,7 @@ def indices_with_two_torsion(self): contains a point fixed by a `\Gamma_0(N)` element of order 2 (where the order is computed in `PSL_2(\ZZ)`). - OUTPUT: - - A list of integers. + OUTPUT: list of integers EXAMPLES:: @@ -940,9 +937,7 @@ def reps_with_two_torsion(self): point fixed by a `\Gamma_0(N)` element of order 2 (where the order is computed in `PSL_2(\ZZ)`). - OUTPUT: - - A list of matrices. + OUTPUT: list of matrices EXAMPLES:: @@ -1310,9 +1305,7 @@ def unimod_to_matrices(self, r1, r2): - ``r1``, ``r2`` -- rational numbers (that are assumed to be connected by a unimodular path) - OUTPUT: - - A pair of `2 \times 2` matrices of determinant 1 + OUTPUT: a pair of `2 \times 2` matrices of determinant 1 EXAMPLES:: @@ -1346,7 +1339,7 @@ def fd_boundary(self, C): INPUT: - - ``C`` -- a list of rational numbers coming from + - ``C`` -- list of rational numbers coming from ``self.form_list_of_cusps()`` OUTPUT: @@ -1549,12 +1542,10 @@ def basic_hecke_matrix(a, l): INPUT: - - `a` -- an integer or Infinity + - ``a`` -- integer or Infinity - ``l`` -- a prime - OUTPUT: - - A `2 \times 2` matrix of determinant l + OUTPUT: a `2 \times 2` matrix of determinant l EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/manin_map.py b/src/sage/modular/pollack_stevens/manin_map.py index b90d95c27f7..04120ba5d7d 100644 --- a/src/sage/modular/pollack_stevens/manin_map.py +++ b/src/sage/modular/pollack_stevens/manin_map.py @@ -85,7 +85,6 @@ def unimod_matrices_to_infty(r, s): This is Manin's continued fraction trick, which gives an expression `\{0,r/s\} = \{0,\infty\} + ... + \{a,b\} + ... + \{*,r/s\}`, where each `\{a,b\}` is the image of `\{0,\infty\}` under a matrix in `SL_2(\ZZ)`. - """ if s == 0: return [] @@ -140,7 +139,6 @@ def unimod_matrices_from_infty(r, s): This is Manin's continued fraction trick, which gives an expression `\{\infty,r/s\} = \{\infty,0\} + ... + \{a,b\} + ... + \{*,r/s\}`, where each `\{a,b\}` is the image of `\{0,\infty\}` under a matrix in `SL_2(\ZZ)`. - """ if s != 0: L = convergents(r / s) @@ -161,7 +159,7 @@ def unimod_matrices_from_infty(r, s): return [] -class ManinMap(): +class ManinMap: r""" Map from a set of right coset representatives of `\Gamma_0(N)` in `SL_2(\ZZ)` to a coefficient module that satisfies the Manin @@ -170,12 +168,13 @@ class ManinMap(): INPUT: - ``codomain`` -- coefficient module - - ``manin_relations`` -- a :class:`sage.modular.pollack_stevens.fund_domain.ManinRelations` object - - ``defining_data`` -- a dictionary whose keys are a superset of + - ``manin_relations`` -- a :class:`sage.modular.pollack_stevens.fund_domain.ManinRelations` + object + - ``defining_data`` -- dictionary whose keys are a superset of ``manin_relations.gens()`` and a subset of ``manin_relations.reps()``, - and whose values are in the codomain. + and whose values are in the codomain - ``check`` -- do numerous (slow) checks and transformations to - ensure that the input data is perfect. + ensure that the input data is perfect EXAMPLES:: @@ -194,11 +193,11 @@ def __init__(self, codomain, manin_relations, defining_data, check=True): - ``codomain`` -- coefficient module - ``manin_relations`` -- a :class:`ManinRelations` object - - ``defining_data`` -- a dictionary whose keys are a superset of + - ``defining_data`` -- dictionary whose keys are a superset of :meth:`manin_relations.gens()` and a subset of manin_relations.reps(), - and whose values are in the codomain. + and whose values are in the codomain - ``check`` -- do numerous (slow) checks and transformations to - ensure that the input data is perfect. + ensure that the input data is perfect TESTS: @@ -243,7 +242,9 @@ def __init__(self, codomain, manin_relations, defining_data, check=True): def extend_codomain(self, new_codomain, check=True): r""" - Extend the codomain of self to new_codomain. There must be a valid conversion operation from the old to the new codomain. This is most often used for extension of scalars from `\QQ` to `\QQ_p`. + Extend the codomain of ``self`` to ``new_codomain``. There must be a + valid conversion operation from the old to the new codomain. This is + most often used for extension of scalars from `\QQ` to `\QQ_p`. EXAMPLES:: @@ -268,11 +269,12 @@ def _compute_image_from_gens(self, B): INPUT: - - ``B`` -- generator of Manin relations. + - ``B`` -- generator of Manin relations OUTPUT: - - an element in the codomain of self (e.g. a distribution), the image of ``B`` under ``self``. + An element in the codomain of ``self`` (e.g. a distribution), the image + of ``B`` under ``self``. EXAMPLES:: @@ -300,11 +302,12 @@ def __getitem__(self, B): INPUT: - - ``B`` -- coset representative of Manin relations. + - ``B`` -- coset representative of Manin relations OUTPUT: - - an element in the codomain of self (e.g. a distribution), the image of ``B`` under ``self``. + An element in the codomain of ``self`` (e.g. a distribution), the image + of ``B`` under ``self``. EXAMPLES:: @@ -342,7 +345,8 @@ def __getitem__(self, B): def compute_full_data(self): r""" - Compute the values of self on all coset reps from its values on our generating set. + Compute the values of ``self`` on all coset reps from its values on our + generating set. EXAMPLES:: @@ -372,16 +376,15 @@ def compute_full_data(self): def __add__(self, right): r""" - Return sum self + right, where self and right are + Return sum ``self + right``, where ``self`` and ``right`` are assumed to have identical codomains and Manin relations. INPUT: - - ``self`` and ``right`` -- two Manin maps with the same codomain and Manin relations. - - OUTPUT: + - ``self``, ``right`` -- two Manin maps with the same codomain and + Manin relations - - the sum of ``self`` and ``right`` -- a Manin map + OUTPUT: the sum of ``self`` and ``right`` -- a Manin map EXAMPLES:: @@ -409,16 +412,15 @@ def __add__(self, right): def __sub__(self, right): """ - Return difference self - right, where self and right are + Return difference ``self`` - right, where ``self`` and ``right`` are assumed to have identical codomains and Manin relations. INPUT: - - ``self`` and ``right`` -- two Manin maps with the same codomain and Manin relations. + - ``self``, ``right`` -- two Manin maps with the same codomain and + Manin relations - OUTPUT: - - - the difference of ``self`` and ``right`` -- a Manin map + OUTPUT: the difference of ``self`` and ``right`` -- a Manin map EXAMPLES:: @@ -446,17 +448,15 @@ def __sub__(self, right): def __mul__(self, right): """ - Return scalar multiplication self * right, where right is in the - base ring of the codomain. + Return scalar multiplication ``self * right``, where ``right`` is in + the base ring of the codomain. INPUT: - - ``self`` -- a Manin map. - - ``right`` -- an element of the base ring of the codomain of self. - - OUTPUT: + - ``self`` -- a Manin map + - ``right`` -- an element of the base ring of the codomain of self - - the sum ``self`` and ``right`` -- a Manin map + OUTPUT: the sum ``self`` and ``right`` -- a Manin map EXAMPLES:: @@ -483,7 +483,7 @@ def __mul__(self, right): def __repr__(self): """ - Return string representation of self. + Return string representation of ``self``. EXAMPLES:: @@ -499,7 +499,7 @@ def __repr__(self): def _eval_sl2(self, A): r""" - Return the value of self on the unimodular divisor corresponding to `A`. + Return the value of ``self`` on the unimodular divisor corresponding to `A`. Note that `A` must be in `SL_2(Z)` for this to work. @@ -509,7 +509,8 @@ def _eval_sl2(self, A): OUTPUT: - The value of self on the divisor corresponding to `A` -- i.e. on the divisor `\{A(0)\} - \{A(\infty)\}`. + The value of ``self`` on the divisor corresponding to `A` -- i.e. on + the divisor `\{A(0)\} - \{A(\infty)\}`. EXAMPLES:: @@ -531,15 +532,14 @@ def _eval_sl2(self, A): def __call__(self, A): """ - Evaluate self at A. + Evaluate ``self`` at A. INPUT: - ``A`` -- a `2 \times 2` matrix - OUTPUT: - - The value of self on the divisor corresponding to ``A`` -- an element of the codomain of self. + OUTPUT: the value of ``self`` on the divisor corresponding to ``A`` -- + an element of the codomain of self EXAMPLES:: @@ -592,9 +592,11 @@ def apply(self, f, codomain=None, to_moments=False): INPUT: - - ``f`` -- anything that can be called with elements of the coefficient module - - ``codomain`` -- (default: None) the codomain of the return map - - ``to_moments`` -- (default: ``False``) if True, will apply ``f`` to each of the moments instead + - ``f`` -- anything that can be called with elements of the coefficient + module + - ``codomain`` -- (default: ``None``) the codomain of the return map + - ``to_moments`` -- boolean (default: ``False``); if ``True``, will + apply ``f`` to each of the moments instead EXAMPLES:: @@ -657,9 +659,7 @@ def _right_action(self, gamma): - ``gamma`` -- `2 \times 2` integer matrix of nonzero determinant, with a well-defined action on the coefficient module - OUTPUT: - - - the image of self under the action of `\gamma` -- a Manin map. + OUTPUT: the image of ``self`` under the action of `\gamma` -- a Manin map EXAMPLES:: @@ -692,8 +692,8 @@ def _right_action(self, gamma): def normalize(self): r""" - Normalize every value of self -- e.g., reduces each value's - `j`-th moment modulo `p^{N-j}` + Normalize every value of ``self`` -- e.g., reduce each value's + `j`-th moment modulo `p^{N-j}`. EXAMPLES:: @@ -719,7 +719,7 @@ def reduce_precision(self, M): INPUT: - - ``M`` -- an integer, the new precision. + - ``M`` -- integer; the new precision EXAMPLES:: @@ -770,13 +770,9 @@ def hecke(self, ell, algorithm='prep'): - ``ell`` -- a prime - - ``algorithm`` -- a string, either 'prep' (default) or - 'naive' + - ``algorithm`` -- string; either ``'prep'`` (default) or ``'naive'`` - OUTPUT: - - - The image of this ManinMap under the Hecke operator - `T_{\ell}` + OUTPUT: the image of this ManinMap under the Hecke operator `T_{\ell}` EXAMPLES:: @@ -817,20 +813,18 @@ def hecke(self, ell, algorithm='prep'): def p_stabilize(self, p, alpha, V): r""" - Return the `p`-stabilization of self to level `N*p` on which + Return the `p`-stabilization of ``self`` to level `N*p` on which `U_p` acts by `\alpha`. INPUT: - - ``p`` -- a prime. + - ``p`` -- a prime - - ``alpha`` -- a `U_p`-eigenvalue. + - ``alpha`` -- a `U_p`-eigenvalue - - ``V`` -- a space of modular symbols. - - OUTPUT: + - ``V`` -- a space of modular symbols - - The image of this ManinMap under the Hecke operator `T_{\ell}` + OUTPUT: the image of this ManinMap under the Hecke operator `T_{\ell}` EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/meson.build b/src/sage/modular/pollack_stevens/meson.build new file mode 100644 index 00000000000..d22947db12c --- /dev/null +++ b/src/sage/modular/pollack_stevens/meson.build @@ -0,0 +1,26 @@ +py.install_sources( + 'all.py', + 'dist.pxd', + 'distributions.py', + 'fund_domain.py', + 'manin_map.py', + 'modsym.py', + 'padic_lseries.py', + 'sigma0.py', + 'space.py', + subdir: 'sage/modular/pollack_stevens', +) + +extension_data = {'dist' : files('dist.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modular/pollack_stevens', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/modular/pollack_stevens/modsym.py b/src/sage/modular/pollack_stevens/modsym.py index 9217c186156..8df8655e5e9 100644 --- a/src/sage/modular/pollack_stevens/modsym.py +++ b/src/sage/modular/pollack_stevens/modsym.py @@ -62,8 +62,8 @@ def _iterate_Up(Phi, p, M, ap, q, aq, check): r""" - Return an overconvergent Hecke-eigensymbol lifting self -- self must be a - `p`-ordinary eigensymbol + Return an overconvergent Hecke-eigensymbol lifting ``self`` -- ``self`` + must be a `p`-ordinary eigensymbol. INPUT: @@ -77,9 +77,7 @@ def _iterate_Up(Phi, p, M, ap, q, aq, check): - ``aq`` -- Hecke eigenvalue at `q` - OUTPUT: - - - Hecke-eigenvalue overconvergent modular symbol lifting self. + OUTPUT: Hecke-eigenvalue overconvergent modular symbol lifting ``self`` EXAMPLES:: @@ -116,10 +114,11 @@ def _iterate_Up(Phi, p, M, ap, q, aq, check): Phi = ~(q ** (k + 1) + 1 - aq) * Phi return Phi + class PSModSymAction(Action): def __init__(self, actor, MSspace): r""" - Create the action + Create the action. EXAMPLES:: @@ -134,7 +133,7 @@ def __init__(self, actor, MSspace): def _act_(self, g, sym): r""" - Return the result of sym * g + Return the result of ``sym * g``. EXAMPLES:: @@ -151,7 +150,7 @@ def _act_(self, g, sym): class PSModularSymbolElement(ModuleElement): def __init__(self, map_data, parent, construct=False): r""" - Initialize a modular symbol + Initialize a modular symbol. EXAMPLES:: @@ -179,7 +178,9 @@ def _repr_(self): def dict(self): r""" - Return dictionary on the modular symbol self, where keys are generators and values are the corresponding values of self on generators + Return dictionary on the modular symbol ``self``, where keys are + generators and values are the corresponding values of ``self`` on + generators. EXAMPLES:: @@ -250,9 +251,9 @@ def _normalize(self, **kwds): def _richcmp_(self, other, op): """ - Check if self == other. + Check if ``self == other``. - Here self and other have the same parent. + Here ``self`` and ``other`` have the same parent. EXAMPLES:: @@ -276,7 +277,7 @@ def _richcmp_(self, other, op): def _add_(self, right): """ - Return self + right + Return ``self + right``. EXAMPLES:: @@ -293,7 +294,7 @@ def _add_(self, right): def _lmul_(self, right): """ - Return self * right + Return ``self * right``. EXAMPLES:: @@ -310,7 +311,7 @@ def _lmul_(self, right): def _rmul_(self, right): """ - Return self * right + Return ``self * right``. EXAMPLES:: @@ -327,7 +328,7 @@ def _rmul_(self, right): def _sub_(self, right): """ - Return self - right + Return ``self - right``. EXAMPLES:: @@ -348,19 +349,19 @@ def _get_prime(self, p=None, alpha=None, allow_none=False): INPUT: - - ``p`` -- an integer or None (default None); if specified - needs to match the prime of the parent. + - ``p`` -- integer or ``None`` (default: ``None``); if specified + needs to match the prime of the parent - - ``alpha`` -- an element or None (default None); if p-adic - can contribute a prime. + - ``alpha`` -- an element or None (default: ``None``); if `p`-adic + can contribute a prime - ``allow_none`` -- boolean (default: ``False``); whether to allow - no prime to be specified. + no prime to be specified OUTPUT: - a prime or ``None``. If ``allow_none`` is ``False`` then a - :class:`ValueError` will be raised rather than returning ``None`` + :exc:`ValueError` will be raised rather than returning ``None`` if no prime can be determined. EXAMPLES:: @@ -404,14 +405,11 @@ def _get_prime(self, p=None, alpha=None, allow_none=False): def plus_part(self): r""" - Return the plus part of self -- i.e. ``self + self | [1,0,0,-1]``. + Return the plus part of ``self`` -- i.e. + ``self + self | [1,0,0,-1]``. Note that we haven't divided by 2. Is this a problem? - OUTPUT: - - - self + self | [1,0,0,-1] - EXAMPLES:: sage: E = EllipticCurve('11a') @@ -446,16 +444,16 @@ def minus_part(self): S0N = Sigma0(self.parent().level()) return self - self * S0N(minusproj) - def hecke(self, ell, algorithm="prep"): + def hecke(self, ell, algorithm='prep'): r""" - Return self | `T_{\ell}` by making use of the precomputations in - self.prep_hecke() + Return ``self`` | `T_{\ell}` by making use of the precomputations in + ``self.prep_hecke()``. INPUT: - ``ell`` -- a prime - - ``algorithm`` -- a string, either 'prep' (default) or + - ``algorithm`` -- string, either 'prep' (default) or 'naive' OUTPUT: @@ -506,9 +504,7 @@ def valuation(self, p=None): - ``p`` -- prime - OUTPUT: - - - The valuation of ``self`` at `p` + OUTPUT: the valuation of ``self`` at `p` EXAMPLES:: @@ -544,7 +540,7 @@ def valuation(self, p=None): def diagonal_valuation(self, p): """ - Return the minimum of the diagonal valuation on the values of self + Return the minimum of the diagonal valuation on the values of ``self``. INPUT: @@ -570,7 +566,7 @@ def diagonal_valuation(self, p): @cached_method def is_Tq_eigensymbol(self, q, p=None, M=None): r""" - Determine if self is an eigenvector for `T_q` modulo `p^M` + Determine if ``self`` is an eigenvector for `T_q` modulo `p^M`. INPUT: @@ -580,9 +576,7 @@ def is_Tq_eigensymbol(self, q, p=None, M=None): - ``M`` -- degree of accuracy of approximation - OUTPUT: - - - True/False + OUTPUT: boolean EXAMPLES:: @@ -613,15 +607,15 @@ def is_Tq_eigensymbol(self, q, p=None, M=None): @cached_method def Tq_eigenvalue(self, q, p=None, M=None, check=True): r""" - Eigenvalue of `T_q` modulo `p^M` + Eigenvalue of `T_q` modulo `p^M`. INPUT: - ``q`` -- prime of the Hecke operator - - ``p`` -- prime we are working modulo (default: None) + - ``p`` -- prime we are working modulo (default: ``None``) - - ``M`` -- degree of accuracy of approximation (default: None) + - ``M`` -- degree of accuracy of approximation (default: ``None``) - ``check`` -- check that ``self`` is an eigensymbol @@ -691,13 +685,11 @@ def is_ordinary(self, p=None, P=None): INPUT: - - ``p`` -- a positive integral prime, or None (default None) + - ``p`` -- a positive integral prime, or None (default: ``None``) - ``P`` -- a prime of the base ring above `p`, or None. This is ignored - unless the base ring is a number field. - - OUTPUT: + unless the base ring is a number field - - True/False + OUTPUT: boolean EXAMPLES:: @@ -753,7 +745,7 @@ def evaluate_twisted(self, a, chi): INPUT: - ``a`` -- integer in the range range(p) - - ``chi`` -- the modulus of a quadratic character. + - ``chi`` -- the modulus of a quadratic character OUTPUT: @@ -762,13 +754,13 @@ def evaluate_twisted(self, a, chi): EXAMPLES:: sage: E = EllipticCurve('17a1') - sage: L = E.padic_lseries(5, implementation="pollackstevens", precision=4) #long time + sage: L = E.padic_lseries(5, implementation='pollackstevens', precision=4) #long time sage: D = L.quadratic_twist() # long time sage: L.symbol().evaluate_twisted(1,D) # long time (1 + 5 + 3*5^2 + 5^3 + O(5^4), 5^2 + O(5^3), 1 + O(5^2), 2 + O(5)) sage: E = EllipticCurve('40a4') - sage: L = E.padic_lseries(7, implementation="pollackstevens", precision=4) #long time + sage: L = E.padic_lseries(7, implementation='pollackstevens', precision=4) #long time sage: D = L.quadratic_twist() # long time sage: L.symbol().evaluate_twisted(1,D) # long time (4 + 6*7 + 3*7^2 + O(7^4), 6*7 + 6*7^2 + O(7^3), 6 + O(7^2), 1 + O(7)) @@ -778,7 +770,7 @@ def evaluate_twisted(self, a, chi): Check for :issue:`32878`:: sage: E = EllipticCurve('11a1') - sage: L = E.padic_lseries(3, implementation="pollackstevens", precision=4) + sage: L = E.padic_lseries(3, implementation='pollackstevens', precision=4) sage: D = 5 sage: L.symbol().evaluate_twisted(1, D) (2 + 3 + 2*3^2 + O(3^4), 2 + 3 + O(3^3), 2 + 3 + O(3^2), 2 + O(3)) @@ -860,24 +852,25 @@ def _find_alpha(self, p, k, M=None, ap=None, new_base_ring=None, ordinary=True, - ``k`` -- Pollack-Stevens weight - - ``M`` -- precision (default: None) of `\QQ_p` + - ``M`` -- precision (default: ``None``); of `\QQ_p` - - ``ap`` -- Hecke eigenvalue at `p` (default: None) + - ``ap`` -- Hecke eigenvalue at `p` (default: ``None``) - - ``new_base_ring`` -- field of definition of `\alpha` (default: None) + - ``new_base_ring`` -- field of definition of `\alpha` (default: ``None``) - - ``ordinary`` -- True if the prime is ordinary (default: ``True``) + - ``ordinary`` -- ``True`` if the prime is ordinary (default: ``True``) - ``check`` -- check to see if the prime is ordinary (default: ``True``) - - ``find_extraprec`` -- setting this to True finds extra precision (default: ``True``) + - ``find_extraprec`` -- setting this to ``True`` finds extra precision + (default: ``True``) OUTPUT: - The output is a tuple (``alpha``, ``new_base_ring``, - ``newM``, ``eisenloss``,``q``,``aq``), with + The output is a tuple (``alpha``, ``new_base_ring``, ``newM``, + ``eisenloss``, ``q``,``aq``), with - - ``alpha`` -- `U_p` eigenvalue + - ``alpha`` -- `U_p` eigenvalue - ``new_base_ring`` -- field of definition of `\alpha` with precision at least ``newM`` @@ -962,7 +955,8 @@ def _find_alpha(self, p, k, M=None, ap=None, new_base_ring=None, ordinary=True, def p_stabilize(self, p=None, M=20, alpha=None, ap=None, new_base_ring=None, ordinary=True, check=True): r""" - Return the `p`-stabilization of self to level `N p` on which `U_p` acts by `\alpha`. + Return the `p`-stabilization of ``self`` to level `N p` on which `U_p` + acts by `\alpha`. Note that since `\alpha` is `p`-adic, the resulting symbol is just an approximation to the true `p`-stabilization @@ -980,22 +974,23 @@ def p_stabilize(self, p=None, M=20, alpha=None, ap=None, new_base_ring=None, ord - ``new_base_ring`` -- change of base ring - - ``ordinary`` -- (default: ``True``) whether to return the ordinary - (at ``p``) eigensymbol. + - ``ordinary`` -- boolean (default: ``True``); whether to return the + ordinary (at ``p``) eigensymbol - - ``check`` -- (default: ``True``) whether to perform extra sanity checks + - ``check`` -- boolean (default: ``True``); whether to perform extra + sanity checks OUTPUT: A modular symbol with the same Hecke eigenvalues as - self away from `p` and eigenvalue `\alpha` at `p`. + ``self`` away from `p` and eigenvalue `\alpha` at `p`. The eigenvalue `\alpha` depends on the parameter ``ordinary``. If ``ordinary`` == True: the unique modular symbol of level - `N p` with the same Hecke eigenvalues as self away from + `N p` with the same Hecke eigenvalues as ``self`` away from `p` and unit eigenvalue at `p`; else the unique modular symbol of level `N p` with the same Hecke eigenvalues as - self away from `p` and non-unit eigenvalue at `p`. + ``self`` away from `p` and non-unit eigenvalue at `p`. EXAMPLES:: @@ -1058,7 +1053,7 @@ def p_stabilize(self, p=None, M=20, alpha=None, ap=None, new_base_ring=None, ord def completions(self, p, M): r""" If `K` is the base_ring of self, this function takes all maps - `K\to \QQ_p` and applies them to self return a list of + `K\to \QQ_p` and applies them to ``self`` return a list of (modular symbol,map: `K\to \QQ_p`) as map varies over all such maps. .. NOTE:: @@ -1122,7 +1117,7 @@ def lift(self, p=None, M=None, alpha=None, new_base_ring=None, algorithm=None, eigensymbol=False, check=True): r""" Return a (`p`-adic) overconvergent modular symbol with - `M` moments which lifts self up to an Eisenstein error + `M` moments which lifts ``self`` up to an Eisenstein error. Here the Eisenstein error is a symbol whose system of Hecke eigenvalues equals `\ell+1` for `T_\ell` when `\ell` @@ -1138,13 +1133,14 @@ def lift(self, p=None, M=None, alpha=None, new_base_ring=None, - ``new_base_ring`` -- change of base ring - - ``algorithm`` -- 'stevens' or 'greenberg' (default 'stevens') + - ``algorithm`` -- ``'stevens'`` or ``'greenberg'`` (default: + ``'stevens'``) - - ``eigensymbol`` -- if True, lifts to Hecke eigensymbol (self must + - ``eigensymbol`` -- if ``True``, lifts to Hecke eigensymbol (self must be a `p`-ordinary eigensymbol) (Note: ``eigensymbol = True`` does *not* just indicate to the code that - self is an eigensymbol; it solves a wholly different problem, lifting + ``self`` is an eigensymbol; it solves a wholly different problem, lifting an eigensymbol to an eigensymbol.) OUTPUT: @@ -1263,7 +1259,7 @@ def lift(self, p=None, M=None, alpha=None, new_base_ring=None, def _lift_to_OMS(self, p, M, new_base_ring, algorithm='greenberg'): r""" Return a (`p`-adic) overconvergent modular symbol with - `M` moments which lifts self up to an Eisenstein error + `M` moments which lifts ``self`` up to an Eisenstein error. Here the Eisenstein error is a symbol whose system of Hecke eigenvalues equals `\ell+1` for `T_\ell` when `\ell` @@ -1277,16 +1273,16 @@ def _lift_to_OMS(self, p, M, new_base_ring, algorithm='greenberg'): - ``new_base_ring`` -- new base ring - - ``algorithm`` -- (default: 'greenberg') a string, either 'greenberg' - or 'stevens', specifying whether to use + - ``algorithm`` -- string (default: ``'greenberg'``); either + ``'greenberg'`` or ``'stevens'``, specifying whether to use the lifting algorithm of M.Greenberg or that of Pollack--Stevens. The latter one solves the difference equation, which is not needed. The option to use Pollack--Stevens' algorithm here is just for historical reasons. OUTPUT: - - An overconvergent modular symbol whose specialization - equals self up to some Eisenstein error. + An overconvergent modular symbol whose specialization + equals ``self`` up to some Eisenstein error. EXAMPLES:: @@ -1444,7 +1440,7 @@ def p_stabilize_and_lift(self, p, M, alpha=None, ap=None, ordinary=True, algorithm='greenberg', eigensymbol=False, check=True): """ - `p`-stabilize and lift self + `p`-stabilize and lift ``self``. INPUT: @@ -1452,28 +1448,31 @@ def p_stabilize_and_lift(self, p, M, alpha=None, ap=None, - ``M`` -- precision - - ``alpha`` -- (default: None) the `U_p` eigenvalue, if known + - ``alpha`` -- (default: ``None``) the `U_p` eigenvalue, if known - - ``ap`` -- (default: None) the Hecke eigenvalue at p (before stabilizing), if known + - ``ap`` -- (default: ``None``) the Hecke eigenvalue at p (before + stabilizing), if known - - ``new_base_ring`` -- (default: None) if specified, force the resulting eigensymbol to take values in the given ring + - ``new_base_ring`` -- (default: ``None``) if specified, force the + resulting eigensymbol to take values in the given ring - - ``ordinary`` -- (default: ``True``) whether to return the ordinary - (at ``p``) eigensymbol. + - ``ordinary`` -- boolean (default: ``True``); whether to return the + ordinary (at ``p``) eigensymbol - - ``algorithm`` -- (default: 'greenberg') a string, either 'greenberg' - or 'stevens', specifying whether to use + - ``algorithm`` -- string (default: ``'greenberg'``); either + ``'greenberg'`` or ``'stevens'``, specifying whether to use the lifting algorithm of M.Greenberg or that of Pollack--Stevens. - The latter one solves the difference equation, which is not needed. The - option to use Pollack--Stevens' algorithm here is just for historical reasons. + The latter one solves the difference equation, which is not needed. + The option to use Pollack--Stevens' algorithm here is just for + historical reasons. - - ``eigensymbol`` -- (default: ``False``) if True, return an overconvergent eigensymbol. Otherwise just perform a naive lift + - ``eigensymbol`` -- boolean (default: ``False``); if ``True``, return + an overconvergent eigensymbol. Otherwise just perform a naive lift - - ``check`` -- (default: ``True``) whether to perform extra sanity checks - - OUTPUT: + - ``check`` -- boolean (default: ``True``); whether to perform extra + sanity checks - `p`-stabilized and lifted version of self. + OUTPUT: `p`-stabilized and lifted version of ``self`` EXAMPLES:: @@ -1515,7 +1514,7 @@ class PSModularSymbolElement_dist(PSModularSymbolElement): def reduce_precision(self, M): r""" - Only hold on to `M` moments of each value of self + Only hold on to `M` moments of each value of ``self``. EXAMPLES:: @@ -1577,7 +1576,7 @@ def specialize(self, new_base_ring=None): def padic_lseries(self,*args, **kwds): """ - Return the `p`-adic L-series of this modular symbol. + Return the `p`-adic `L`-series of this modular symbol. EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/padic_lseries.py b/src/sage/modular/pollack_stevens/padic_lseries.py index 1869e8ed047..613ceef65b8 100644 --- a/src/sage/modular/pollack_stevens/padic_lseries.py +++ b/src/sage/modular/pollack_stevens/padic_lseries.py @@ -49,7 +49,7 @@ class pAdicLseries(SageObject): sage: E = EllipticCurve('37a') sage: p = 5 sage: prec = 4 - sage: L = E.padic_lseries(p, implementation="pollackstevens", precision=prec) # long time + sage: L = E.padic_lseries(p, implementation='pollackstevens', precision=prec) # long time sage: L[1] # long time 1 + 4*5 + 2*5^2 + O(5^3) sage: L.series(3) # long time @@ -88,7 +88,7 @@ class pAdicLseries(SageObject): def __init__(self, symb, gamma=None, quadratic_twist=1, precision=None): r""" - Initialize the class + Initialize the class. EXAMPLES:: @@ -125,12 +125,12 @@ def __init__(self, symb, gamma=None, quadratic_twist=1, precision=None): def __getitem__(self, n): r""" - Return the `n`-th coefficient of the `p`-adic `L`-series + Return the `n`-th coefficient of the `p`-adic `L`-series. EXAMPLES:: sage: E = EllipticCurve('14a5') - sage: L = E.padic_lseries(7,implementation="pollackstevens",precision=5) # long time + sage: L = E.padic_lseries(7,implementation='pollackstevens',precision=5) # long time sage: L[0] # long time O(7^5) sage: L[1] # long time @@ -173,7 +173,7 @@ def __eq__(self, other): EXAMPLES:: sage: E = EllipticCurve('11a') - sage: L = E.padic_lseries(11,implementation="pollackstevens",precision=6) # long time + sage: L = E.padic_lseries(11,implementation='pollackstevens',precision=6) # long time sage: L == loads(dumps(L)) # indirect doctest, long time True """ @@ -192,7 +192,7 @@ def __ne__(self, other): EXAMPLES:: sage: E = EllipticCurve('11a') - sage: L = E.padic_lseries(11,implementation="pollackstevens",precision=6) # long time + sage: L = E.padic_lseries(11,implementation='pollackstevens',precision=6) # long time sage: L != L # long time False """ @@ -224,7 +224,7 @@ def prime(self): EXAMPLES:: sage: E = EllipticCurve('19a') - sage: L = E.padic_lseries(19, implementation="pollackstevens",precision=6) # long time + sage: L = E.padic_lseries(19, implementation='pollackstevens',precision=6) # long time sage: L.prime() # long time 19 """ @@ -253,7 +253,7 @@ def _repr_(self): EXAMPLES:: sage: E = EllipticCurve('14a2') - sage: L = E.padic_lseries(3, implementation="pollackstevens", precision=4) # long time + sage: L = E.padic_lseries(3, implementation='pollackstevens', precision=4) # long time sage: L._repr_() # long time '3-adic L-series of Modular symbol of level 42 with values in Space of 3-adic distributions with k=0 action and precision cap 8' @@ -268,24 +268,24 @@ def series(self, prec=5): INPUT: - - ``prec`` -- (default 5) is the precision of the power series + - ``prec`` -- (default: 5) the precision of the power series EXAMPLES:: sage: E = EllipticCurve('14a2') sage: p = 3 sage: prec = 6 - sage: L = E.padic_lseries(p,implementation="pollackstevens",precision=prec) # long time + sage: L = E.padic_lseries(p,implementation='pollackstevens',precision=prec) # long time sage: L.series(4) # long time 2*3 + 3^4 + 3^5 + O(3^6) + (2*3 + 3^2 + O(3^4))*T + (2*3 + O(3^2))*T^2 + (3 + O(3^2))*T^3 + O(T^4) sage: E = EllipticCurve("15a3") - sage: L = E.padic_lseries(5,implementation="pollackstevens",precision=15) # long time + sage: L = E.padic_lseries(5,implementation='pollackstevens',precision=15) # long time sage: L.series(3) # long time O(5^15) + (2 + 4*5^2 + 3*5^3 + 5^5 + 2*5^6 + 3*5^7 + 3*5^8 + 2*5^9 + 2*5^10 + 3*5^11 + 5^12 + O(5^13))*T + (4*5 + 4*5^3 + 3*5^4 + 4*5^5 + 3*5^6 + 2*5^7 + 5^8 + 4*5^9 + 3*5^10 + O(5^11))*T^2 + O(T^3) sage: E = EllipticCurve("79a1") - sage: L = E.padic_lseries(2,implementation="pollackstevens",precision=10) # not tested + sage: L = E.padic_lseries(2,implementation='pollackstevens',precision=10) # not tested sage: L.series(4) # not tested O(2^9) + (2^3 + O(2^4))*T + O(2^0)*T^2 + (O(2^-3))*T^3 + O(T^4) """ @@ -297,7 +297,7 @@ def series(self, prec=5): def interpolation_factor(self, ap, chip=1, psi=None): r""" - Return the interpolation factor associated to self. + Return the interpolation factor associated to ``self``. This is the `p`-adic multiplier that which appears in the interpolation formula of the `p`-adic `L`-function. It has the form `(1-\alpha_p^{-1})^2`, where `\alpha_p` is the @@ -307,16 +307,16 @@ def interpolation_factor(self, ap, chip=1, psi=None): - ``ap`` -- the eigenvalue of the Up operator - - ``chip`` -- the value of the nebentype at p (default: 1) + - ``chip`` -- the value of the nebentype at `p` (default: 1) - - ``psi`` -- a twisting character (default: None) + - ``psi`` -- a twisting character (default: ``None``) OUTPUT: a `p`-adic number EXAMPLES:: sage: E = EllipticCurve('19a2') - sage: L = E.padic_lseries(3,implementation="pollackstevens",precision=6) # long time + sage: L = E.padic_lseries(3,implementation='pollackstevens',precision=6) # long time sage: ap = E.ap(3) # long time sage: L.interpolation_factor(ap) # long time 3^2 + 3^3 + 2*3^5 + 2*3^6 + O(3^7) @@ -359,7 +359,7 @@ def _basic_integral(self, a, j): sage: from sage.modular.pollack_stevens.padic_lseries import pAdicLseries sage: E = EllipticCurve('11a3') - sage: L = E.padic_lseries(5, implementation="pollackstevens", precision=4) #long time + sage: L = E.padic_lseries(5, implementation='pollackstevens', precision=4) #long time sage: L._basic_integral(1,2) # long time 2*5^2 + 5^3 + O(5^4) """ diff --git a/src/sage/modular/pollack_stevens/sigma0.py b/src/sage/modular/pollack_stevens/sigma0.py index 501ef54c8ad..2659f12cfa3 100644 --- a/src/sage/modular/pollack_stevens/sigma0.py +++ b/src/sage/modular/pollack_stevens/sigma0.py @@ -2,7 +2,7 @@ The matrix monoid `\Sigma_0(N)`. This stands for a monoid of matrices over `\ZZ`, `\QQ`, `\ZZ_p`, or `\QQ_p`, -depending on an integer `N \ge 1`. This class exists in order to act on p-adic +depending on an integer `N \ge 1`. This class exists in order to act on `p`-adic distribution spaces. Over `\QQ` or `\ZZ`, it is the monoid of matrices `2\times2` matrices @@ -88,9 +88,7 @@ class _default_adjuster(Sigma0ActionAdjuster): - ``g`` -- a `2 \times 2` matrix - OUTPUT: - - - a 4-tuple consisting of the entries of the matrix + OUTPUT: a 4-tuple consisting of the entries of the matrix EXAMPLES:: @@ -108,18 +106,20 @@ def __call__(self, g): """ return tuple(g.list()) + class Sigma0_factory(UniqueFactory): r""" Create the monoid of non-singular matrices, upper triangular mod `N`. INPUT: - - ``N`` (integer) -- the level (should be strictly positive) + - ``N`` -- integer; the level (should be strictly positive) - ``base_ring`` (commutative ring, default `\ZZ`) -- the base ring (normally `\ZZ` or a `p`-adic ring) - - ``adjuster`` -- None, or a callable which takes a `2 \times 2` matrix and returns - a 4-tuple of integers. This is supplied in order to support differing - conventions for the action of `2 \times 2` matrices on distributions. + - ``adjuster`` -- ``None``, or a callable which takes a `2 \times 2` matrix + and returns a 4-tuple of integers. This is supplied in order to support + differing conventions for the action of `2 \times 2` matrices on + distributions. EXAMPLES:: @@ -213,7 +213,7 @@ def __hash__(self): def det(self): r""" - Return the determinant of this matrix, which is (by assumption) non-zero. + Return the determinant of this matrix, which is (by assumption) nonzero. EXAMPLES:: @@ -266,7 +266,7 @@ def _richcmp_(self, other, op): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -279,7 +279,8 @@ def _repr_(self): def matrix(self): r""" - Return self as a matrix (forgetting the additional data that it is in Sigma0(N)). + Return ``self`` as a matrix (forgetting the additional data that it is + in ``Sigma0(N)``). EXAMPLES:: @@ -412,7 +413,7 @@ def __init__(self, N, base_ring, adjuster): def _an_element_(self): r""" - Return an element of self. This is implemented in a rather dumb way. + Return an element of ``self``. This is implemented in a rather dumb way. EXAMPLES:: @@ -478,14 +479,14 @@ def _coerce_map_from_(self, other): def _element_constructor_(self, x, check=True): r""" - Construct an element of self from x. + Construct an element of ``self`` from x. INPUT: - ``x`` -- something that one can make into a matrix over the appropriate base ring - - ``check`` (boolean, default: ``True``) -- if True, then check that this - matrix actually satisfies the conditions. + - ``check`` -- boolean (default: ``True``); if ``True``, then check + that this matrix actually satisfies the conditions EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/space.py b/src/sage/modular/pollack_stevens/space.py index 4bb25a086c7..862418412ca 100644 --- a/src/sage/modular/pollack_stevens/space.py +++ b/src/sage/modular/pollack_stevens/space.py @@ -93,7 +93,7 @@ class PollackStevensModularSymbols_factory(UniqueFactory): - ``sign`` -- integer; -1, 0, 1 - - ``base_ring`` -- ring or ``None`` + - ``base_ring`` -- ring or ``None`` - ``p`` -- prime or ``None`` @@ -107,7 +107,7 @@ class PollackStevensModularSymbols_factory(UniqueFactory): They are only relevant if ``coefficients`` is ``None``, in which case the coefficient module is inferred from the other data. - .. note:: + .. NOTE:: We emphasize that in the Pollack-Stevens notation, the ``weight`` is the usual weight minus 2, so a classical weight @@ -177,7 +177,7 @@ def create_object(self, version, key): - ``version`` -- the version of the object to create - - ``key`` -- a tuple of parameters, as created by :meth:`create_key` + - ``key`` -- tuple of parameters, as created by :meth:`create_key` EXAMPLES:: @@ -205,7 +205,7 @@ class PollackStevensModularSymbolspace(Module): - ``coefficients`` -- a coefficient module - - ``sign`` -- (default: 0); 0, -1, or 1 + - ``sign`` -- (default: 0) 0, -1, or 1 EXAMPLES:: @@ -256,7 +256,7 @@ def __init__(self, group, coefficients, sign=0): def _element_constructor_(self, data): r""" - Construct an element of self from data. + Construct an element of ``self`` from data. EXAMPLES:: @@ -270,7 +270,7 @@ def _element_constructor_(self, data): elif isinstance(data, ManinMap): pass else: - # a dict, or a single distribution specifying a constant symbol, etc + # a dict, or a single distribution specifying a constant symbol, etc. data = ManinMap(self._coefficients, self._source, data) if data._codomain != self._coefficients: @@ -328,9 +328,7 @@ def source(self): r""" Return the domain of the modular symbols in this space. - OUTPUT: - - A :class:`sage.modular.pollack_stevens.fund_domain.PollackStevensModularDomain` + OUTPUT: a :class:`sage.modular.pollack_stevens.fund_domain.PollackStevensModularDomain` EXAMPLES:: @@ -394,7 +392,7 @@ def sign(self): def ngens(self): r""" - Returns the number of generators defining this space. + Return the number of generators defining this space. EXAMPLES:: @@ -577,9 +575,7 @@ def _specialize_parent_space(self, new_base_ring): - ``new_base_ring`` -- a ring - OUTPUT: - - A space of modular symbols to which our space specializes. + OUTPUT: a space of modular symbols to which our space specializes EXAMPLES:: @@ -592,7 +588,6 @@ def _specialize_parent_space(self, new_base_ring): 5-adic Ring with capped absolute precision 20 sage: M._specialize_parent_space(QQ).base_ring() Rational Field - """ return PollackStevensModularSymbols(self.group(), coefficients=self.coefficient_module().specialize(new_base_ring), sign=self.sign()) @@ -607,9 +602,7 @@ def _lift_parent_space(self, p, M, new_base_ring): - ``M`` -- precision cap - ``new_base_ring`` -- ring - OUTPUT: - - A space of distribution valued modular symbols. + OUTPUT: a space of distribution valued modular symbols EXAMPLES:: @@ -622,7 +615,6 @@ def _lift_parent_space(self, p, M, new_base_ring): TypeError: Coefficient module must be a Symk sage: PollackStevensModularSymbols(Gamma1(3), weight=1)._lift_parent_space(17,10,Qp(17)) Space of overconvergent modular symbols for Congruence Subgroup Gamma1(3) with sign 0 and values in Space of 17-adic distributions with k=1 action and precision cap 10 - """ if self.coefficient_module().is_symk(): return PollackStevensModularSymbols(self.group(), coefficients=self.coefficient_module().lift(p, M, new_base_ring), sign=self.sign()) @@ -637,9 +629,7 @@ def change_ring(self, new_base_ring): - ``new_base_ring`` -- a ring - OUTPUT: - - A space of modular symbols over the specified base. + OUTPUT: a space of modular symbols over the specified base EXAMPLES:: @@ -649,7 +639,6 @@ def change_ring(self, new_base_ring): Space of modular symbols for Congruence Subgroup Gamma(6) with sign 0 and values in Sym^4 Q^2 sage: M.change_ring(Qp(5,8)) Space of modular symbols for Congruence Subgroup Gamma(6) with sign 0 and values in Sym^4 Q_5^2 - """ return PollackStevensModularSymbols(self.group(), coefficients=self.coefficient_module().change_ring(new_base_ring), sign=self.sign()) @@ -657,9 +646,7 @@ def _an_element_(self): r""" Return the cusps associated to an element of a congruence subgroup. - OUTPUT: - - an element of the modular symbol space + OUTPUT: an element of the modular symbol space This returns a "typical" element of this space; in this case the constant map sending every element to an element of the @@ -688,15 +675,13 @@ def _an_element_(self): def random_element(self, M=None): r""" - Return a random overconvergent modular symbol in this space with `M` moments + Return a random overconvergent modular symbol in this space with `M` moments. INPUT: - ``M`` -- positive integer - OUTPUT: - - An element of the modular symbol space with `M` moments + OUTPUT: an element of the modular symbol space with `M` moments Returns a random element in this space by randomly choosing values of distributions on all but one divisor, and solves the @@ -811,9 +796,7 @@ def cusps_from_mat(g): - ``g`` -- an element of a congruence subgroup or a matrix - OUTPUT: - - A tuple of cusps associated to ``g``. + OUTPUT: a tuple of cusps associated to ``g`` EXAMPLES:: @@ -865,13 +848,11 @@ def ps_modsym_from_elliptic_curve(E, sign=0, implementation='eclib'): the plus (if ``sign`` == 1) or the minus (if ``sign`` == -1) modular symbol. The default of 0 returns the sum of the plus and minus symbols. - - ``implementation`` -- either 'eclib' (default) or 'sage'. This + - ``implementation`` -- either ``'eclib'`` (default) or ``'sage'``. This determines which implementation of the underlying classical modular symbols is used. - OUTPUT: - - The overconvergent modular symbol associated to ``E`` + OUTPUT: the overconvergent modular symbol associated to ``E`` EXAMPLES:: @@ -914,14 +895,15 @@ def ps_modsym_from_elliptic_curve(E, sign=0, implementation='eclib'): return V(val) -def ps_modsym_from_simple_modsym_space(A, name="alpha"): +def ps_modsym_from_simple_modsym_space(A, name='alpha'): r""" - Returns some choice -- only well defined up a nonzero scalar (!) -- of an overconvergent modular symbol that corresponds to ``A``. + Return some choice -- only well defined up a nonzero scalar (!) -- of an + overconvergent modular symbol that corresponds to ``A``. INPUT: - ``A`` -- nonzero simple Hecke equivariant new space of modular symbols, - which need not be cuspidal. + which need not be cuspidal OUTPUT: diff --git a/src/sage/modular/quasimodform/element.py b/src/sage/modular/quasimodform/element.py index 12d441809c4..c8bbdd1a9a3 100644 --- a/src/sage/modular/quasimodform/element.py +++ b/src/sage/modular/quasimodform/element.py @@ -31,6 +31,7 @@ from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.integer_ring import ZZ + class QuasiModularFormsElement(ModuleElement): r""" A quasimodular forms ring element. Such an element is described by @@ -103,9 +104,7 @@ def __init__(self, parent, polynomial): each `f_i` are modular forms ring elements and `E_2` correspond to the weight 2 Eisenstein series - OUTPUT: - - ``QuasiModularFormsElement`` + OUTPUT: ``QuasiModularFormsElement`` TESTS:: @@ -144,15 +143,15 @@ def q_expansion(self, prec=6): sage: E2.q_expansion(prec=10) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10) """ - E2 = eisenstein_series_qexp(2, prec=prec, K=self.base_ring(), normalization='constant') #normalization -> to force integer coefficients + E2 = eisenstein_series_qexp(2, prec=prec, K=self.base_ring(), normalization='constant') # normalization -> to force integer coefficients coefficients = self._polynomial.coefficients(sparse=False) - return sum(f.q_expansion(prec=prec)*E2**idx for idx, f in enumerate(coefficients)) + return sum(f.q_expansion(prec=prec) * E2**idx for idx, f in enumerate(coefficients)) - qexp = q_expansion # alias + qexp = q_expansion # alias def _repr_(self): r""" - String representation of self. + String representation of ``self``. TESTS:: @@ -180,7 +179,7 @@ def _latex_(self): def _richcmp_(self, other, op): r""" - Compare self with other. + Compare ``self`` with ``other``. TESTS:: @@ -227,7 +226,7 @@ def _add_(self, other): def __neg__(self): r""" - The negation of ``self``` + The negation of ``self``. TESTS:: @@ -242,7 +241,7 @@ def __neg__(self): def _mul_(self, other): r""" - The multiplication of two ``QuasiModularFormElement`` + The multiplication of two ``QuasiModularFormElement``. INPUT: @@ -265,7 +264,7 @@ def _mul_(self, other): def _lmul_(self, c): r""" - The left action of the base ring on self. + The left action of the base ring on ``self``. INPUT: @@ -287,7 +286,7 @@ def _lmul_(self, c): def __bool__(self): r""" - Return whether ``self`` is non-zero. + Return whether ``self`` is nonzero. EXAMPLES:: @@ -454,13 +453,13 @@ def polynomial(self, names=None): INPUT: - - ``names`` (str, default: ``None``) -- a list or tuple of names + - ``names``-- string (default: ``None``); list or tuple of names (strings), or a comma separated string. Defines the names for the generators of the multivariate polynomial ring. The default names are of the form ``ABCk`` where ``k`` is a number corresponding to the weight of the form ``ABC``. - OUTPUT: A multivariate polynomial in the variables ``names`` + OUTPUT: a multivariate polynomial in the variables ``names`` EXAMPLES:: @@ -477,7 +476,6 @@ def polynomial(self, names=None): 5 sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).polynomial() E3_1*E4_0 + E2_0*E3_0 + E2 + E2_0 - """ P = self.parent().polynomial_ring(names) poly_gens = P.gens() @@ -777,7 +775,7 @@ def derivative(self): def _compute(self, X): r""" - Compute the coefficients of `q^n` of the q-expansion of this, + Compute the coefficients of `q^n` of the `q`-expansion of this, graded quasimodular form for `n` in the list `X`. The results are not cached. (Use coefficients for cached results). @@ -800,7 +798,7 @@ def _compute(self, X): def coefficients(self, X): r""" - Return the coefficients of `q^n` of the q-expansion of this, + Return the coefficients of `q^n` of the `q`-expansion of this, graded quasimodular form for `n` in the list `X`. If X is an integer, return coefficients for indices from 1 diff --git a/src/sage/modular/quasimodform/ring.py b/src/sage/modular/quasimodform/ring.py index 14f099be987..29df3bfcde0 100644 --- a/src/sage/modular/quasimodform/ring.py +++ b/src/sage/modular/quasimodform/ring.py @@ -222,15 +222,15 @@ def __init__(self, group=1, base_ring=QQ, name='E2'): r""" INPUT: - - ``group`` (default: `\SL_2(\ZZ)`) -- a congruence subgroup of + - ``group`` -- (default: `\SL_2(\ZZ)`) a congruence subgroup of `\SL_2(\ZZ)`, or a positive integer `N` (interpreted as - `\Gamma_0(N)`). + `\Gamma_0(N)`) - - ``base_ring`` (ring, default: `\QQ`) -- a base ring, which should be - `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p`. + - ``base_ring`` -- a base ring (default: `\QQ`); should be + `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p` - - ``name`` (str, default: ``'E2'``) -- a variable name corresponding to - the weight 2 Eisenstein series. + - ``name`` -- string (default: ``'E2'``); a variable name corresponding to + the weight 2 Eisenstein series TESTS: @@ -321,9 +321,9 @@ def quasimodular_forms_of_weight(self, weight): INPUT: - - ``weight`` (int, Integer) + - ``weight`` -- integer - OUTPUT: A quasimodular forms space of the given weight. + OUTPUT: a quasimodular forms space of the given weight EXAMPLES:: @@ -331,13 +331,12 @@ def quasimodular_forms_of_weight(self, weight): Traceback (most recent call last): ... NotImplementedError: spaces of quasimodular forms of fixed weight not yet implemented - """ raise NotImplementedError("spaces of quasimodular forms of fixed weight not yet implemented") def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -377,11 +376,11 @@ def _coerce_map_from_(self, M): def _element_constructor_(self, datum): r""" - The call method of self. + The call method of ``self``. INPUT: - - ``datum`` -- list, GradedModularFormElement, ModularFormElement, + - ``datum`` -- list; GradedModularFormElement, ModularFormElement, Polynomial, base ring element OUTPUT: QuasiModularFormElement @@ -605,7 +604,7 @@ def polynomial_ring(self, names=None): INPUT: - - ``names`` (str, default: ``None``) -- a list or tuple of names + - ``names``-- string (default: ``None``); list or tuple of names (strings), or a comma separated string. Defines the names for the generators of the multivariate polynomial ring. The default names are of the following form: @@ -621,7 +620,7 @@ def polynomial_ring(self, names=None): - In any other cases, we use the letters ``Fk``, ``Gk``, ``Hk``, ..., ``FFk``, ``FGk``, ... to denote any generator of weight `k`. - OUTPUT: A multivariate polynomial ring in the variables ``names`` + OUTPUT: a multivariate polynomial ring in the variables ``names`` EXAMPLES:: @@ -728,7 +727,7 @@ def from_polynomial(self, polynomial): INPUT: - - ``polynomial`` -- A multivariate polynomial + - ``polynomial`` -- a multivariate polynomial OUTPUT: the graded quasimodular forms `P(g_0, \ldots, g_n)` @@ -789,11 +788,9 @@ def basis_of_weight(self, weight): INPUT: - - ``weight`` (integer) -- the weight of the subspace - - OUTPUT: + - ``weight`` -- integer; the weight of the subspace - A list of quasimodular forms of the given weight. + OUTPUT: list of quasimodular forms of the given weight EXAMPLES:: diff --git a/src/sage/modular/quatalg/brandt.py b/src/sage/modular/quatalg/brandt.py index 5a6714fbdde..e91e6950e76 100644 --- a/src/sage/modular/quatalg/brandt.py +++ b/src/sage/modular/quatalg/brandt.py @@ -96,7 +96,7 @@ ``is_right_equivalent(I,J)`` returns true if `I` and `J` are equivalent. This method first compares the theta series of `I` and `J`. If they are the same, it computes the theta series of the lattice `I\overline(J)`. It -returns true if the `n^{th}` coefficient of this series is nonzero +returns true if the `n`-th coefficient of this series is nonzero where `n=N(J)N(I)`. The theta series of a lattice `L` over the quaternion algebra `A` is @@ -117,19 +117,19 @@ Brandt matrices which can be computed using the definition of the Hecke operators given earlier. -``hecke_matrix_from_defn(self,n)`` returns the matrix of the n-th Hecke +``hecke_matrix_from_defn(self,n)`` returns the matrix of the `n`-th Hecke operator `B_{0}(n)` acting on self, computed directly from the definition. However, one can efficiently compute Brandt matrices using theta series. In fact, let `\{I_{1},.....,I_{h}\}` be a set of right `\mathcal{O}`-ideal class representatives. The (i,j) entry in the -Brandt matrix `B_{0}(n)` is the product of the `n^{th}` coefficient in +Brandt matrix `B_{0}(n)` is the product of the `n`-th coefficient in the theta series of the lattice `I_{i}\overline{I_{j}}` and the first coefficient in the theta series of the lattice `I_{i}\overline{I_{i}}`. -``compute_hecke_matrix_brandt(self,n)`` returns the n-th Hecke matrix, +``compute_hecke_matrix_brandt(self,n)`` returns the `n`-th Hecke matrix, computed using theta series. EXAMPLES:: @@ -140,7 +140,9 @@ Order of Quaternion Algebra (-1, -23) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) sage: B.right_ideals() - (Fractional ideal (2 + 2*j, 2*i + 2*k, 4*j, 4*k), Fractional ideal (2 + 2*j, 2*i + 6*k, 8*j, 8*k), Fractional ideal (2 + 10*j + 8*k, 2*i + 8*j + 6*k, 16*j, 16*k)) + (Fractional ideal (4, 4*i, 2 + 2*j, 2*i + 2*k), + Fractional ideal (8, 8*i, 2 + 2*j, 6*i + 2*k), + Fractional ideal (16, 16*i, 10 + 8*i + 2*j, 8 + 6*i + 2*k)) sage: B.hecke_matrix(2) [1 2 0] @@ -235,15 +237,13 @@ def BrandtModule(N, M=1, weight=2, base_ring=QQ, use_cache=True): INPUT: - - `N` -- a product of primes with odd exponents - - `M` -- an integer coprime to `q` (default: 1) - - ``weight`` -- an integer that is at least 2 (default: 2) + - ``N`` -- a product of primes with odd exponents + - ``M`` -- integer coprime to `q` (default: 1) + - ``weight`` -- integer that is at least 2 (default: 2) - ``base_ring`` -- the base ring (default: ``QQ``) - ``use_cache`` -- whether to use the cache (default: ``True``) - OUTPUT: - - a Brandt module + OUTPUT: a Brandt module EXAMPLES:: @@ -322,13 +322,11 @@ def class_number(p, r, M): INPUT: - - `p` -- a prime - - `r` -- an odd positive integer (default: 1) - - `M` -- an integer coprime to `q` (default: 1) + - ``p`` -- a prime + - ``r`` -- an odd positive integer (default: 1) + - ``M`` -- integer coprime to `q` (default: 1) - OUTPUT: - - Integer + OUTPUT: integer EXAMPLES:: @@ -360,11 +358,9 @@ def maximal_order(A): INPUT: - - `A` -- quaternion algebra ramified precisely at `p` and infinity - - OUTPUT: + - ``A`` -- quaternion algebra ramified precisely at `p` and infinity - a maximal order in `A` + OUTPUT: a maximal order in `A` EXAMPLES:: @@ -390,12 +386,10 @@ def basis_for_left_ideal(R, gens): INPUT: - - `R` -- quaternion order + - ``R`` -- quaternion order - ``gens`` -- list of elements of `R` - OUTPUT: - - list of four elements of `R` + OUTPUT: list of four elements of `R` EXAMPLES:: @@ -403,9 +397,9 @@ def basis_for_left_ideal(R, gens): sage: sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [i+j,i-j,2*k,A(3)]) doctest:...: DeprecationWarning: The function basis_for_left_ideal() is deprecated, use the _left_ideal_basis() method of quaternion algebras See https://github.com/sagemath/sage/issues/37090 for details. - [1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k] + [1, 1/2 + 1/2*i, j, 1/3*i + 1/2*j + 1/6*k] sage: sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [3*(i+j),3*(i-j),6*k,A(3)]) - [3/2 + 1/2*i + k, i + 2*k, 3/2*j + 3/2*k, 3*k] + [3, 3/2 + 3/2*i, 3*j, i + 3/2*j + 1/2*k] """ from sage.misc.superseded import deprecation deprecation(37090, "The function basis_for_left_ideal() is deprecated, use the _left_ideal_basis() method of quaternion algebras") @@ -419,12 +413,10 @@ def right_order(R, basis): INPUT: - - `R` -- order in quaternion algebra + - ``R`` -- order in quaternion algebra - ``basis`` -- basis for an ideal `I` - OUTPUT: - - order in quaternion algebra + OUTPUT: order in quaternion algebra EXAMPLES: @@ -436,7 +428,7 @@ def right_order(R, basis): See https://github.com/sagemath/sage/issues/37090 for details. Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k) sage: basis - [1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k] + [1, 1/2 + 1/2*i, j, 1/3*i + 1/2*j + 1/6*k] sage: B = BrandtModule(17); A = B.quaternion_algebra(); i,j,k = A.gens() sage: basis = B.maximal_order()._left_ideal_basis([i*j - j]) @@ -456,7 +448,7 @@ def quaternion_order_with_given_level(A, level): INPUT: - - ``level`` -- The level of the order to be returned. Currently this + - ``level`` -- the level of the order to be returned. Currently this is only implemented when the level is divisible by at most one power of a prime that ramifies in this quaternion algebra. @@ -624,10 +616,10 @@ def __init__(self, N, M, weight, base_ring): """ INPUT: - - N -- ramification number (coprime to M) - - M -- auxiliary level - - weight -- integer 2 - - base_ring -- the base ring + - ``N`` -- ramification number (coprime to M) + - ``M`` -- auxiliary level + - ``weight`` -- integer 2 + - ``base_ring`` -- the base ring EXAMPLES:: @@ -800,8 +792,8 @@ def cyclic_submodules(self, I, p): INPUT: - - `I` -- ideal I in R = self.order_of_level_N() - - `p` -- prime `p` coprime to self.level() + - ``I`` -- ideal `I` in ``R = self.order_of_level_N()`` + - ``p`` -- prime `p` coprime to ``self.level()`` OUTPUT: @@ -813,14 +805,14 @@ def cyclic_submodules(self, I, p): sage: B = BrandtModule(11) sage: I = B.order_of_level_N().unit_ideal() sage: B.cyclic_submodules(I, 2) - [Fractional ideal (1/2 + 3/2*j + k, 1/2*i + j + 1/2*k, 2*j, 2*k), - Fractional ideal (1/2 + 1/2*i + 1/2*j + 1/2*k, i + k, j + k, 2*k), - Fractional ideal (1/2 + 1/2*j + k, 1/2*i + j + 3/2*k, 2*j, 2*k)] + [Fractional ideal (2, 2*i, 3/2 + i + 1/2*j, 1 + 1/2*i + 1/2*k), + Fractional ideal (2, 1 + i, 1 + j, 1/2 + 1/2*i + 1/2*j + 1/2*k), + Fractional ideal (2, 2*i, 1/2 + i + 1/2*j, 1 + 3/2*i + 1/2*k)] sage: B.cyclic_submodules(I, 3) - [Fractional ideal (1/2 + 1/2*j, 1/2*i + 5/2*k, 3*j, 3*k), - Fractional ideal (1/2 + 3/2*j + 2*k, 1/2*i + 2*j + 3/2*k, 3*j, 3*k), - Fractional ideal (1/2 + 3/2*j + k, 1/2*i + j + 3/2*k, 3*j, 3*k), - Fractional ideal (1/2 + 5/2*j, 1/2*i + 1/2*k, 3*j, 3*k)] + [Fractional ideal (3, 3*i, 1/2 + 1/2*j, 5/2*i + 1/2*k), + Fractional ideal (3, 3*i, 3/2 + 2*i + 1/2*j, 2 + 3/2*i + 1/2*k), + Fractional ideal (3, 3*i, 3/2 + i + 1/2*j, 1 + 3/2*i + 1/2*k), + Fractional ideal (3, 3*i, 5/2 + 1/2*j, 1/2*i + 1/2*k)] sage: B.cyclic_submodules(I, 11) Traceback (most recent call last): ... @@ -883,16 +875,17 @@ def cyclic_submodules(self, I, p): # right multiplication by X changes something to be written # in terms of the basis for I. - Y = I.basis_matrix() - X = Y**(-1) + basis = basis_for_quaternion_lattice(I.basis(), reverse=False) + Y = matrix(map(list, basis)) + X = ~Y # Compute the matrix of right multiplication by alpha acting on # our fixed choice of basis for this ideal. M_alpha = (matrix([(i * alpha).coefficient_tuple() - for i in I.basis()]) * X).change_ring(GF(p)) + for i in basis]) * X).change_ring(GF(p)) M_beta = (matrix([(i * beta).coefficient_tuple() - for i in I.basis()]) * X).change_ring(GF(p)) + for i in basis]) * X).change_ring(GF(p)) # step 2: Find j such that if f=I[j], then mod 2 we have span(I[0],alpha*I[i]) # has trivial intersection with span(I[j],alpha*I[j]). @@ -946,25 +939,25 @@ def hecke_matrix(self, n, algorithm='default', sparse=False, B=None): INPUT: - - `n` -- integer + - ``n`` -- integer - - ``algorithm`` -- string (default: 'default') + - ``algorithm`` -- string (default: ``'default'``) - - 'default' -- let Sage guess which algorithm is best + - ``'default'`` -- let Sage guess which algorithm is best - - 'direct' -- use cyclic subideals (generally much + - ``'direct'`` -- use cyclic subideals (generally much better when you want few Hecke operators and the dimension is very large); uses 'theta' if n divides the level. - - 'brandt' -- use Brandt matrices (generally much + - ``'brandt'`` -- use Brandt matrices (generally much better when you want many Hecke operators and the dimension is very small; bad when the dimension is large) - - ``sparse`` -- bool (default: ``False``) + - ``sparse`` -- boolean (default: ``False``) - - `B` -- integer or ``None`` (default: ``None``); in direct + - ``B`` -- integer or ``None`` (default: ``None``); in direct algorithm, use theta series to this precision as an initial check for equality of ideal classes. @@ -1015,18 +1008,18 @@ def hecke_matrix(self, n, algorithm='default', sparse=False, B=None): def _compute_hecke_matrix_prime(self, p, sparse=False, B=None): """ - Return matrix of the `p`-th Hecke operator on self. The matrix + Return matrix of the `p`-th Hecke operator on ``self``. The matrix is always computed using the direct algorithm. INPUT: - - `p` -- prime number + - ``p`` -- prime number - - `B` -- integer or None (default: None); in direct algorithm, + - ``B`` -- integer or ``None`` (default: ``None``); in direct algorithm, use theta series to this precision as an initial check for equality of ideal classes. - - ``sparse`` -- bool (default: ``False``); whether matrix should be sparse + - ``sparse`` -- boolean (default: ``False``); whether matrix should be sparse EXAMPLES:: @@ -1045,15 +1038,15 @@ def _compute_hecke_matrix_prime(self, p, sparse=False, B=None): def _compute_hecke_matrix_directly(self, n, B=None, sparse=False): """ Given an integer `n` coprime to the level, return the matrix of - the n-th Hecke operator on self, computed on our fixed basis + the `n`-th Hecke operator on ``self``, computed on our fixed basis by directly using the definition of the Hecke action in terms of fractional ideals. INPUT: - - `n` -- integer, coprime to level + - ``n`` -- integer, coprime to level - - ``sparse`` -- bool (default: ``False``); whether matrix should be sparse + - ``sparse`` -- boolean (default: ``False``); whether matrix should be sparse EXAMPLES:: @@ -1153,16 +1146,14 @@ def _theta_dict(self, B): """ Return a dictionary from theta series vectors of degree `B` to list of integers `i`, where the key is the vector of - coefficients of the normalized theta series of the `i`th right + coefficients of the normalized theta series of the `i`-th right ideal, as indexed by ``self.right_ideals()``. INPUT: - - `B` -- positive integer, precision of theta series vectors + - ``B`` -- positive integer, precision of theta series vectors - OUTPUT: - - dictionary + OUTPUT: dictionary EXAMPLES: @@ -1193,18 +1184,18 @@ def _theta_dict(self, B): def _compute_hecke_matrix_brandt(self, n, sparse=False): """ - Return the n-th Hecke matrix, computed using Brandt matrices + Return the `n`-th Hecke matrix, computed using Brandt matrices (theta series). - When the n-th Hecke operator is requested, we computed theta + When the `n`-th Hecke operator is requested, we computed theta series to precision `2n+20`, since it only takes slightly longer, and this means that any Hecke operator `T_m` can quickly be computed, for `m<2n+20`. INPUT: - - n -- integer, coprime to level - - sparse -- bool (default: ``False``); whether matrix should be sparse + - ``n`` -- integer, coprime to level + - ``sparse`` -- boolean (default: ``False``); whether matrix should be sparse EXAMPLES:: @@ -1221,7 +1212,6 @@ def _compute_hecke_matrix_brandt(self, n, sparse=False): [0 2 2 2] sage: B._compute_hecke_matrix_brandt(5).fcp() (x - 6) * (x - 3) * (x^2 - 3*x - 2) - """ # we go out to 2*n+20 for efficiency, since it takes only a # little longer, but saves a lot of time if one computes @@ -1258,17 +1248,15 @@ def right_ideals(self, B=None): Return sorted tuple of representatives for the equivalence classes of right ideals in ``self``. - OUTPUT: - - sorted tuple of fractional ideals + OUTPUT: sorted tuple of fractional ideals EXAMPLES:: sage: B = BrandtModule(23) sage: B.right_ideals() - (Fractional ideal (2 + 2*j, 2*i + 2*k, 4*j, 4*k), - Fractional ideal (2 + 2*j, 2*i + 6*k, 8*j, 8*k), - Fractional ideal (2 + 10*j + 8*k, 2*i + 8*j + 6*k, 16*j, 16*k)) + (Fractional ideal (4, 4*i, 2 + 2*j, 2*i + 2*k), + Fractional ideal (8, 8*i, 2 + 2*j, 6*i + 2*k), + Fractional ideal (16, 16*i, 10 + 8*i + 2*j, 8 + 6*i + 2*k)) TESTS:: @@ -1338,27 +1326,25 @@ def _ideal_products(self, diagonal_only=False): INPUT: - - ``diagonal_only`` -- bool (default: ``False``) if ``True`` returns + - ``diagonal_only`` -- boolean (default: ``False``); if ``True`` returns only the diagonal ideal products - OUTPUT: - - list of ideals + OUTPUT: list of ideals EXAMPLES:: sage: B = BrandtModule(37) sage: B._ideal_products() - [[Fractional ideal (8 + 8*j + 8*k, 4*i + 8*j + 4*k, 16*j, 16*k)], - [Fractional ideal (8 + 24*j + 8*k, 4*i + 8*j + 4*k, 32*j, 32*k), - Fractional ideal (16 + 16*j + 48*k, 4*i + 8*j + 36*k, 32*j + 32*k, 64*k)], - [Fractional ideal (8 + 24*j + 24*k, 4*i + 24*j + 4*k, 32*j, 32*k), - Fractional ideal (8 + 4*i + 16*j + 28*k, 8*i + 16*j + 8*k, 32*j, 64*k), - Fractional ideal (16 + 16*j + 16*k, 4*i + 24*j + 4*k, 32*j + 32*k, 64*k)]] + [[Fractional ideal (16, 16*i, 8 + 8*i + 8*j, 8 + 12*i + 4*k)], + [Fractional ideal (32, 32*i, 8 + 24*i + 8*j, 24 + 12*i + 4*k), + Fractional ideal (32, 64*i, 16 + 48*i + 16*j, 36*i + 8*j + 4*k)], + [Fractional ideal (32, 32*i, 8 + 8*i + 8*j, 8 + 12*i + 4*k), + Fractional ideal (64, 32 + 32*i, 16 + 16*i + 16*j, 40 + 12*i + 4*k), + Fractional ideal (32, 64*i, 16 + 16*i + 16*j, 16 + 52*i + 8*j + 4*k)]] sage: B._ideal_products(diagonal_only=True) - [Fractional ideal (8 + 8*j + 8*k, 4*i + 8*j + 4*k, 16*j, 16*k), - Fractional ideal (16 + 16*j + 48*k, 4*i + 8*j + 36*k, 32*j + 32*k, 64*k), - Fractional ideal (16 + 16*j + 16*k, 4*i + 24*j + 4*k, 32*j + 32*k, 64*k)] + [Fractional ideal (16, 16*i, 8 + 8*i + 8*j, 8 + 12*i + 4*k), + Fractional ideal (32, 64*i, 16 + 48*i + 16*j, 36*i + 8*j + 4*k), + Fractional ideal (32, 64*i, 16 + 16*i + 16*j, 16 + 52*i + 8*j + 4*k)] """ L = self.right_ideals() n = len(L) @@ -1449,9 +1435,7 @@ def brandt_series(self, prec, var='q'): - ``prec`` -- positive integer - ``var`` -- string (default: `q`) - OUTPUT: - - matrix of power series with coefficients in `\QQ` + OUTPUT: matrix of power series with coefficients in `\QQ` EXAMPLES:: @@ -1585,7 +1569,7 @@ def benchmark_magma(levels, silent=False): - ``levels`` -- list of pairs `(p,M)` where `p` is a prime not dividing `M` - - ``silent`` -- bool, default ``False``; if ``True`` suppress + - ``silent`` -- boolean (default: ``False``); if ``True`` suppress printing during computation OUTPUT: @@ -1625,7 +1609,7 @@ def benchmark_sage(levels, silent=False): - ``levels`` -- list of pairs `(p,M)` where `p` is a prime not dividing `M` - - ``silent`` -- bool, default ``False``; if ``True`` suppress + - ``silent`` -- boolean (default: ``False``); if ``True`` suppress printing during computation OUTPUT: diff --git a/src/sage/modular/ssmod/ssmod.py b/src/sage/modular/ssmod/ssmod.py index 49eb6fe1a08..9913e554a02 100644 --- a/src/sage/modular/ssmod/ssmod.py +++ b/src/sage/modular/ssmod/ssmod.py @@ -100,9 +100,7 @@ def Phi2_quad(J3, ssJ1, ssJ2): - ``ssJ2``, ``ssJ2`` -- supersingular j-invariants over the finite field - OUTPUT: - - - polynomial -- defined over the finite field + OUTPUT: polynomial; defined over the finite field EXAMPLES: @@ -119,7 +117,7 @@ def Phi2_quad(J3, ssJ1, ssJ2): sage: sage.modular.ssmod.ssmod.Phi2_quad(X, F(8), j_in) x^2 + 31*x + 31 - .. note:: + .. NOTE:: Given a root (j1,j2) to the polynomial `Phi_2(J1,J2)`, the pairs (j2,j3) not equal to (j2,j1) which solve `Phi_2(j2,j3)` are roots of @@ -164,9 +162,7 @@ def Phi_polys(L, x, j): - ``j`` -- supersingular j-invariant over the finite field - OUTPUT: - - - polynomial -- defined over the finite field + OUTPUT: polynomial; defined over the finite field EXAMPLES: @@ -204,13 +200,11 @@ def dimension_supersingular_module(prime, level=1): INPUT: - - ``prime`` -- integer, prime - - - ``level`` -- integer, positive + - ``prime`` -- integer; prime - OUTPUT: + - ``level`` -- integer; positive - - dimension -- integer, nonnegative + OUTPUT: dimension; integer, nonnegative EXAMPLES: @@ -259,11 +253,9 @@ def supersingular_D(prime): INPUT: - - prime -- integer, prime - - OUTPUT: + - ``prime`` -- integer, prime - - D -- integer, negative + OUTPUT: d; integer, negative EXAMPLES: @@ -304,7 +296,7 @@ def supersingular_j(FF): INPUT: - - ``FF`` -- finite field with p^2 elements, where p is a prime number + - ``FF`` -- finite field with p^2 elements, where p is a prime number OUTPUT: @@ -419,7 +411,7 @@ def __init__(self, prime=2, level=1, base_ring=ZZ): def _repr_(self) -> str: """ - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -504,9 +496,7 @@ def dimension(self): - ``self`` -- SupersingularModule object - OUTPUT: - - - integer -- dimension, nonnegative + OUTPUT: integer; dimension, nonnegative EXAMPLES:: @@ -553,9 +543,7 @@ def level(self): - ``self`` -- SupersingularModule object - OUTPUT: - - - integer -- the level, positive + OUTPUT: integer; the level, positive EXAMPLES:: @@ -579,9 +567,7 @@ def prime(self): - ``self`` -- SupersingularModule object - OUTPUT: - - - integer -- characteristic, positive + OUTPUT: integer; characteristic, positive EXAMPLES:: @@ -605,9 +591,7 @@ def weight(self): - ``self`` -- SupersingularModule object - OUTPUT: - - - integer -- weight, positive + OUTPUT: integer; weight, positive EXAMPLES:: @@ -630,7 +614,7 @@ def supersingular_points(self): INPUT: - - ``self`` -- SupersingularModule object + - ``self`` -- SupersingularModule object OUTPUT: @@ -783,11 +767,9 @@ def hecke_matrix(self, L): - ``self`` -- SupersingularModule object - - ``L`` -- integer, positive + - ``L`` -- integer; positive - OUTPUT: - - - matrix -- sparse integer matrix + OUTPUT: matrix; sparse integer matrix EXAMPLES: @@ -814,7 +796,7 @@ def hecke_matrix(self, L): [1 1 0 1 0 1] [1 1 1 0 1 0] - .. note:: + .. NOTE:: The first list --- list_j --- returned by the supersingular_points function are the rows *and* column indexes of the above hecke diff --git a/src/sage/modules/diamond_cutting.py b/src/sage/modules/diamond_cutting.py index 14adddd4b54..f470c7f72eb 100644 --- a/src/sage/modules/diamond_cutting.py +++ b/src/sage/modules/diamond_cutting.py @@ -137,11 +137,9 @@ def diamond_cut(V, GM, C, verbose=False): - ``C`` -- radius to use in cutting algorithm - - ``verbose`` -- (default: ``False``) whether to print debug information + - ``verbose`` -- boolean (default: ``False``); whether to print debug information - OUTPUT: - - A :class:`Polyhedron` instance. + OUTPUT: a :class:`Polyhedron` instance EXAMPLES:: @@ -234,7 +232,7 @@ def diamond_cut(V, GM, C, verbose=False): def calculate_voronoi_cell(basis, radius=None, verbose=False): """ - Calculate the Voronoi cell of the lattice defined by basis + Calculate the Voronoi cell of the lattice defined by basis. INPUT: @@ -244,9 +242,7 @@ def calculate_voronoi_cell(basis, radius=None, verbose=False): - ``verbose`` -- whether to print debug information - OUTPUT: - - A :class:`Polyhedron` instance. + OUTPUT: a :class:`Polyhedron` instance EXAMPLES:: diff --git a/src/sage/modules/fg_pid/fgp_element.py b/src/sage/modules/fg_pid/fgp_element.py index 5139506637e..ed63c1d2053 100644 --- a/src/sage/modules/fg_pid/fgp_element.py +++ b/src/sage/modules/fg_pid/fgp_element.py @@ -59,11 +59,12 @@ def __init__(self, parent, x, check=DEBUG): """ INPUT: - - ``parent`` -- parent module M + - ``parent`` -- parent module ``M`` - - ``x`` -- element of M.V() + - ``x`` -- element of ``M.V()`` - - ``check`` -- (default: ``True``) if True, verify that x in M.V() + - ``check`` -- boolean (default: ``True``); if ``True``, verify that x + in ``M.V()`` EXAMPLES:: @@ -83,7 +84,8 @@ def __init__(self, parent, x, check=DEBUG): def lift(self): """ - Lift self to an element of V, where the parent of self is the quotient module V/W. + Lift ``self`` to an element of V, where the parent of ``self`` is the + quotient module V/W. EXAMPLES:: @@ -193,7 +195,7 @@ def _rmul_(self, c): INPUT: - - ``c`` -- an element of ``self.parent().base_ring()``. + - ``c`` -- an element of ``self.parent().base_ring()`` OUTPUT: @@ -238,7 +240,7 @@ def _lmul_(self, s): INPUT: - - ``c`` -- an element of ``self.parent().base_ring()``. + - ``c`` -- an element of ``self.parent().base_ring()`` OUTPUT: @@ -355,11 +357,9 @@ def _vector_(self, base_ring=None): INPUT: - - ``base_ring`` -- the desired base ring of the vector. + - ``base_ring`` -- the desired base ring of the vector - OUTPUT: - - A vector over the base ring. + OUTPUT: a vector over the base ring EXAMPLES:: @@ -391,7 +391,7 @@ def _vector_(self, base_ring=None): def _richcmp_(self, right, op): """ - Compare self and right. + Compare ``self`` and ``right``. EXAMPLES:: diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index 64a6e085eb7..435796d83e5 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -238,14 +238,12 @@ def FGP_Module(V, W, check=True): - ``W`` -- a free `R`-submodule of `V` - - ``check`` -- bool (default: ``True``); if ``True``, more checks - on correctness are performed; in particular, we check the data + - ``check`` -- boolean (default: ``True``); if ``True``, more checks + on correctness are performed. In particular, we check the data types of ``V`` and ``W``, and that `W` is a submodule of `V` with the same base ring. - OUTPUT: - - - the quotient `V/W` as a finitely generated `R`-module + OUTPUT: the quotient `V/W` as a finitely generated `R`-module EXAMPLES:: @@ -302,7 +300,7 @@ class FGP_Module_class(Module): - ``W`` -- an `R`-submodule of `V` - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) EXAMPLES:: @@ -346,8 +344,8 @@ def __init__(self, V, W, check=True): - ``W`` -- an `R`-submodule of `V` - - ``check`` -- bool (default: ``True``); if ``True``, more checks on - correctness are performed; in particular, we check the data types of + - ``check`` -- boolean (default: ``True``); if ``True``, more checks on + correctness are performed. In particular, we check the data types of ``V`` and ``W``, and that `W` is a submodule of `V` with the same base ring `R`. @@ -391,11 +389,9 @@ def _module_constructor(self, V, W, check=True): - ``W`` -- an `R`-submodule of `V` - - ``check`` -- bool (default: ``True``) - - OUTPUT: + - ``check`` -- boolean (default: ``True``) - The quotient `V/W`. + OUTPUT: the quotient `V/W` EXAMPLES:: @@ -416,9 +412,7 @@ def _coerce_map_from_(self, S): - ``S`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -457,7 +451,8 @@ def _mul_(self, other, switch_sides=False): INPUT: - ``other`` -- an element of the base ring - - ``switch_sides`` -- (default: ``False``) left or right multiplication + - ``switch_sides`` -- boolean (default: ``False``); left or right + multiplication EXAMPLES:: @@ -536,7 +531,7 @@ def __eq__(self, other): def __ne__(self, other): """ - True iff ``self`` is not equal to ``other``. + Return ``True`` iff ``self`` is not equal to ``other``. This may not be needed for modules created using the function :func:`FGP_Module`, since those have uniqueness built into @@ -576,7 +571,7 @@ def __ne__(self, other): def __lt__(self, other): """ - True iff ``self`` is a proper submodule of ``other``. + Return ``True`` iff ``self`` is a proper submodule of ``other``. EXAMPLES:: @@ -594,7 +589,7 @@ def __lt__(self, other): def __gt__(self, other): """ - True iff ``other`` is a proper submodule of ``self``. + Return ``True`` iff ``other`` is a proper submodule of ``self``. EXAMPLES:: @@ -612,7 +607,7 @@ def __gt__(self, other): def __ge__(self, other): """ - True iff ``other`` is a submodule of ``self``. + Return ``True`` iff ``other`` is a submodule of ``self``. EXAMPLES:: @@ -641,7 +636,7 @@ def _element_constructor_(self, x, check=True): space and try to put into `V`. If ``x`` is in ``self`` already, just return ``x``. - - `check` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) .. SEEALSO:: :meth:`linear_combination_of_smith_form_gens` @@ -673,7 +668,6 @@ def linear_combination_of_smith_form_gens(self, x): sage: X = ZZ**2 / span([[3,0], [0,2]], ZZ) sage: X.linear_combination_of_smith_form_gens([1]) (1) - """ try: x = self.optimized()[0].V().linear_combination_of_basis(x) @@ -794,7 +788,6 @@ def has_canonical_map_to(self, A): True sage: Q.has_canonical_map_to(A) False - """ if not isinstance(A, FGP_Module_class): return False @@ -856,7 +849,6 @@ def V(self): [1/2 0 0] [ 0 1 0] [ 0 0 1] - """ return self._V @@ -949,7 +941,7 @@ def _smith_form(self): """ Return matrices `S`, `U`, and `V` such that `S = U*R*V`, and `S` is in Smith normal form, and `R` is the relative matrix that defines - self. + ``self``. See :meth:`_relative_matrix`. @@ -986,14 +978,14 @@ def invariants(self, include_ones=False): r""" Return the diagonal entries of the Smith form of the relative matrix that defines ``self`` (see :meth:`._relative_matrix`) - padded with zeros, excluding 1's by default. Thus if ``v`` is the - list of integers returned, then self is abstractly isomorphic to + padded with zeros, excluding 1s by default. Thus if ``v`` is the + list of integers returned, then ``self`` is abstractly isomorphic to the product of cyclic groups `\ZZ/n\ZZ` where `n` is in ``v``. INPUT: - - ``include_ones`` -- bool (default: ``False``); if ``True``, also - include 1's in the output list. + - ``include_ones`` -- boolean (default: ``False``); if ``True``, also + include 1s in the output list EXAMPLES:: @@ -1011,7 +1003,6 @@ def invariants(self, include_ones=False): (0,) sage: Q.invariants(include_ones=True) (1, 1, 0) - """ D, _, _ = self._smith_form() @@ -1083,9 +1074,7 @@ def gens_to_smith(self): To go in the other direction, use :meth:`smith_to_gens`. - OUTPUT: - - - a matrix over the base ring + OUTPUT: a matrix over the base ring EXAMPLES:: @@ -1134,9 +1123,7 @@ def smith_to_gens(self): To go in the other direction, use :meth:`gens_to_smith`. - OUTPUT: - - - a matrix over the base ring + OUTPUT: a matrix over the base ring EXAMPLES:: @@ -1203,7 +1190,7 @@ def gens_vector(self, x, reduce=False): - ``x`` -- element of ``self`` - - ``reduce`` -- (default: ``False``); if ``True``, + - ``reduce`` -- (default: ``False``) if ``True``, reduce coefficients modulo invariants; this is ignored if the base ring is not `\ZZ` @@ -1266,9 +1253,9 @@ def coordinate_vector(self, x, reduce=False): - ``x`` -- element of ``self`` - - ``reduce`` -- (default: ``False``); if ``True``, reduce + - ``reduce`` -- (default: ``False``) if ``True``, reduce coefficients modulo invariants; this is - ignored if the base ring is not ``ZZ``. + ignored if the base ring is not ``ZZ`` OUTPUT: @@ -1503,10 +1490,9 @@ def hom(self, im_gens, codomain=None, check=True): INPUT: - - ``im_gens`` -- a list of the images of ``self.gens()`` in some + - ``im_gens`` -- list of the images of ``self.gens()`` in some `R`-module - EXAMPLES:: sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ) @@ -1650,7 +1636,6 @@ def _hom_general(self, im_gens, check=True): Morphism from module over Integer Ring with invariants (3,) to module with invariants (3,) that sends the generators to [(1), (1)] - """ m = self.ngens() A = ZZ**m @@ -1740,7 +1725,6 @@ def _Hom_(self, N, category=None): in Category of commutative additive groups sage: type(H) - """ if isinstance(N, FGP_Module_class): return FGP_Homset(self, N) @@ -2000,7 +1984,8 @@ def random_fgp_module(n, R=ZZ, finite=False): - ``R`` -- base ring (default: ``ZZ``) - - ``finite`` -- bool (default: ``True``); if True, make the random module finite + - ``finite`` -- boolean (default: ``True``); if ``True``, make the random + module finite EXAMPLES:: diff --git a/src/sage/modules/fg_pid/fgp_morphism.py b/src/sage/modules/fg_pid/fgp_morphism.py index 4be28f43be1..df08f7ceb0f 100644 --- a/src/sage/modules/fg_pid/fgp_morphism.py +++ b/src/sage/modules/fg_pid/fgp_morphism.py @@ -391,7 +391,7 @@ def lift(self, x): INPUT: - - ``x`` -- element of the codomain of self. + - ``x`` -- element of the codomain of self EXAMPLES:: @@ -410,7 +410,6 @@ def lift(self, x): sage: V = span([[5, -1/2]],ZZ); W = span([[20,-2]],ZZ); Q = V/W; phi=Q.hom([2*Q.0]) sage: x = phi.image().0; phi(phi.lift(x)) == x True - """ x = self.codomain()(x) @@ -485,7 +484,7 @@ def FGP_Homset(X, Y): class FGP_Homset_class(Homset): """ - Homsets of :class:`~sage.modules.fg_pid.fgp_module.FGP_Module` + Homsets of :class:`~sage.modules.fg_pid.fgp_module.FGP_Module`. TESTS:: diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index 1b0bb892b7f..ecea38e8365 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -133,11 +133,9 @@ def is_FilteredVectorSpace(X): INPUT: - - ``X`` -- anything. + - ``X`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -220,14 +218,11 @@ def FilteredVectorSpace(arg1, arg2=None, base_ring=QQ, check=True): def normalize_degree(deg): """ - Normalized the degree - - - ``deg`` -- something that defines the degree (either integer or - infinity). + Normalize the degree. - OUTPUT: + - ``deg`` -- something that defines the degree (either integer or infinity) - Plus/minus infinity or a Sage integer. + OUTPUT: plus/minus infinity or a Sage integer EXAMPLES:: @@ -255,10 +250,10 @@ def construct_from_dim_degree(dim, max_degree, base_ring, check): INPUT: - - ``dim`` -- integer. The dimension. + - ``dim`` -- integer; the dimension - - ``max_degree`` -- integer or infinity. The maximal degree where - the vector subspace of the filtration is still the entire space. + - ``max_degree`` -- integer or infinity; the maximal degree where + the vector subspace of the filtration is still the entire space EXAMPLES:: @@ -303,7 +298,7 @@ def construct_from_generators(filtration, base_ring, check): INPUT: - - ``filtration`` -- a dictionary of filtration steps. Each + - ``filtration`` -- dictionary of filtration steps. Each filtration step is a pair consisting of an integer degree and a list/tuple/iterable of vector space generators. The integer ``degree`` stipulates that all filtration steps of degree higher @@ -342,11 +337,11 @@ def construct_from_generators_indices(generators, filtration, base_ring, check): INPUT: - - ``generators`` -- a list/tuple/iterable of vectors, or something + - ``generators`` -- list/tuple/iterable of vectors, or something convertible to them. The generators spanning various subspaces. - - ``filtration`` -- a list or iterable of filtration steps. Each + - ``filtration`` -- list or iterable of filtration steps. Each filtration step is a pair ``(degree, ray_indices)``. The ``ray_indices`` are a list or iterable of ray indices, which span a subspace of the vector space. The integer ``degree`` @@ -408,24 +403,24 @@ class FilteredVectorSpace_class(FreeModule_ambient_field): def __init__(self, base_ring, dim, generators, filtration, check=True): r""" - A descending filtration of a vector space + A descending filtration of a vector space. INPUT: - - ``base_ring`` -- a field. The base field of the ambient vector space. + - ``base_ring`` -- a field; the base field of the ambient vector space - - ``dim`` -- integer. The dimension of the ambient vector space. + - ``dim`` -- integer; the dimension of the ambient vector space - ``generators`` -- tuple of generators for the ambient vector space. These will be used to span the subspaces of the filtration. - - ``filtration`` -- a dictionary of filtration steps in ray + - ``filtration`` -- dictionary of filtration steps in ray index notation. See :func:`construct_from_generators_indices` for details. - - ``check`` -- boolean (optional; default: ``True``). Whether - to perform consistency checks. + - ``check`` -- boolean (default: ``True``); whether + to perform consistency checks TESTS:: @@ -489,7 +484,7 @@ def change_ring(self, base_ring): INPUT: - - ``base_ring`` -- a ring. The new base ring. + - ``base_ring`` -- the new base ring OUTPUT: @@ -511,9 +506,7 @@ def ambient_vector_space(self): """ Return the ambient (unfiltered) vector space. - OUTPUT: - - A vector space. + OUTPUT: a vector space EXAMPLES:: @@ -528,10 +521,8 @@ def is_constant(self): """ Return whether the filtration is constant. - OUTPUT: - - Boolean. Whether the filtered vector spaces are identical in - all degrees. + OUTPUT: boolean; whether the filtered vector spaces are identical in + all degrees EXAMPLES:: @@ -560,9 +551,7 @@ def is_exhaustive(self): A filtration `\{F_d\}` in an ambient vector space `V` is exhaustive if `\cup F_d = V`. See also :meth:`is_separating`. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -585,9 +574,7 @@ def is_separating(self): A filtration `\{F_d\}` in an ambient vector space `V` is exhaustive if `\cap F_d = 0`. See also :meth:`is_exhaustive`. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -690,7 +677,7 @@ def get_degree(self, d): INPUT: - - ``d`` -- Integer. The desired degree of the filtration. + - ``d`` -- integer; the desired degree of the filtration OUTPUT: @@ -727,11 +714,9 @@ def graded(self, d): INPUT: - - ``d`` -- integer. The degree. - - OUTPUT: + - ``d`` -- integer; the degree - The quotient `G_d = F_d / F_{d+1}`. + OUTPUT: the quotient `G_d = F_d / F_{d+1}` EXAMPLES:: @@ -787,7 +772,7 @@ def _repr_field_name(self): RAISES: - :class:`NotImplementedError`: The field does not have an + :exc:`NotImplementedError`: The field does not have an abbreviated name defined. EXAMPLES:: @@ -818,15 +803,13 @@ def _repr_field_name(self): def _repr_vector_space(self, dim): """ - Return a string representation of the vector space of given dimension + Return a string representation of the vector space of given dimension. INPUT: - - ``dim`` -- integer. - - OUTPUT: + - ``dim`` -- integer - String representation of the vector space of dimension ``dim``. + OUTPUT: string representation of the vector space of dimension ``dim`` EXAMPLES:: @@ -849,14 +832,14 @@ def _repr_vector_space(self, dim): def _repr_degrees(self, min_deg, max_deg): """ - Return a string representation + Return a string representation. This method is like :meth:`_repr_` except that the user can select the range of degrees to be shown in the output. INPUT: - - ``min_deg``, ``max_deg`` -- two integers. + - ``min_deg``, ``max_deg`` -- two integers EXAMPLES:: @@ -876,9 +859,7 @@ def _repr_(self): r""" Return as string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -982,11 +963,9 @@ def direct_sum(self, other): INPUT: - - ``other`` -- a filtered vector space. - - OUTPUT: + - ``other`` -- a filtered vector space - The direct sum as a filtered vector space. + OUTPUT: the direct sum as a filtered vector space EXAMPLES:: @@ -1044,7 +1023,7 @@ def tensor_product(self, other): INPUT: - - ``other`` -- a filtered vector space. + - ``other`` -- a filtered vector space OUTPUT: @@ -1107,7 +1086,7 @@ def _power_operation(self, n, operation): INPUT: - - ``n`` -- integer. the number of factors of ``self``. + - ``n`` -- integer; the number of factors of ``self`` - ``operation`` -- string. See :class:`~sage.modules.tensor_operations.TensorOperation` for @@ -1145,8 +1124,7 @@ def exterior_power(self, n): INPUT: - - ``n`` -- integer. Exterior product of how many copies of - ``self``. + - ``n`` -- integer; exterior product of how many copies of ``self`` OUTPUT: @@ -1178,8 +1156,8 @@ def symmetric_power(self, n): INPUT: - - ``n`` -- integer. Symmetric product of how many copies of - ``self``. + - ``n`` -- integer; symmetric product of how many copies of + ``self`` OUTPUT: @@ -1248,11 +1226,11 @@ def shift(self, deg): def random_deformation(self, epsilon=None): """ - Return a random deformation + Return a random deformation. INPUT: - - ``epsilon`` -- a number in the base ring. + - ``epsilon`` -- a number in the base ring OUTPUT: diff --git a/src/sage/modules/finite_submodule_iter.pyx b/src/sage/modules/finite_submodule_iter.pyx index 188ff9d879a..6b4992c8f33 100644 --- a/src/sage/modules/finite_submodule_iter.pyx +++ b/src/sage/modules/finite_submodule_iter.pyx @@ -83,11 +83,11 @@ cdef class FiniteZZsubmodule_iterator: INPUT: - - ``basis`` -- the elements `(g_0, \ldots, g_n)` - - ``order`` (optional) -- the additive_orders `m_i` of `g_i`. - - ``coset_rep`` (optional) -- an element of g, - if one aims to compute a coset of the `\ZZ`-submodule `M`. - - ``immutable`` (optional; default: ``False``) -- set it to + - ``basis`` -- the elements `(g_0, \ldots, g_n)` + - ``order`` -- (optional) the additive_orders `m_i` of `g_i` + - ``coset_rep`` -- (optional) an element of `g`, + if one aims to compute a coset of the `\ZZ`-submodule `M` + - ``immutable`` -- boolean (default: ``False``); set it to ``True`` to return immutable elements. Setting this to ``True`` makes sense if the elements are vectors. See :class:`FiniteFieldsubspace_iterator` for examples. @@ -106,7 +106,7 @@ cdef class FiniteZZsubmodule_iterator: def __init__(self, basis, order=None, coset_rep=None, immutable=False): """ - see :class:`FiniteZZsubmodule_iterator` + See :class:`FiniteZZsubmodule_iterator`. EXAMPLES:: @@ -227,17 +227,17 @@ cdef class FiniteFieldsubspace_iterator(FiniteZZsubmodule_iterator): INPUT: - - ``basis`` -- a list of vectors or a matrix with elements over + - ``basis`` -- list of vectors or a matrix with elements over a finite field. If a matrix is provided then it is not checked whether the matrix is full ranked. Similarly, if a list of vectors is provided, then the linear independence of the vectors is not checked. - - ``coset_rep`` (optional) -- a vector in the same ambient space, - if one aims to compute a coset of the vector space given by ``basis``. + - ``coset_rep`` -- (optional) a vector in the same ambient space, + if one aims to compute a coset of the vector space given by ``basis`` - - ``immutable`` (optional; default: ``False``) -- set it to - ``True`` to return immutable vectors. + - ``immutable`` -- boolean (default: ``False``); set it to + ``True`` to return immutable vectors EXAMPLES:: @@ -260,12 +260,11 @@ cdef class FiniteFieldsubspace_iterator(FiniteZZsubmodule_iterator): sage: c = next(iter) sage: c.is_immutable() True - """ def __init__(self, basis, coset_rep=None, immutable=False): """ - see :class:`FiniteFieldsubspace_iterator` + See :class:`FiniteFieldsubspace_iterator`. EXAMPLES:: @@ -311,18 +310,18 @@ cdef class FiniteFieldsubspace_projPoint_iterator: INPUT: - - ``basis`` -- a list of vectors or a matrix with elements over + - ``basis`` -- list of vectors or a matrix with elements over a finite field. If a matrix is provided then it is not checked whether the matrix is full ranked. Similarly, if a list of vectors is provided, then the linear independence of the vectors is not checked. - - ``normalize`` (optional; default: ``False``) -- boolean which - indicates if the returned vectors should be normalized, i.e. the - first nonzero coordinate is equal to 1. + - ``normalize`` -- boolean (default: ``False``); whether the returned + vectors should be normalized, i.e. the first nonzero coordinate is + equal to 1 - - ``immutable`` (optional; default: ``False``) -- set it to - ``True`` to return immutable vectors. + - ``immutable`` -- boolean (default: ``False``); set it to + ``True`` to return immutable vectors EXAMPLES:: @@ -355,7 +354,7 @@ cdef class FiniteFieldsubspace_projPoint_iterator: def __init__(self, basis, normalize=False, immutable=False): """ - see :class:`FiniteFieldsubspace_projPoint_iterator` + See :class:`FiniteFieldsubspace_projPoint_iterator`. EXAMPLES:: diff --git a/src/sage/modules/fp_graded/element.py b/src/sage/modules/fp_graded/element.py index 5e348276c33..273dea1f60b 100755 --- a/src/sage/modules/fp_graded/element.py +++ b/src/sage/modules/fp_graded/element.py @@ -65,9 +65,7 @@ def degree(self): r""" The degree of ``self``. - OUTPUT: - - The integer degree of ``self`` or raise an error if the zero element. + OUTPUT: the integer degree of ``self`` or raise an error if the zero element EXAMPLES:: @@ -147,9 +145,7 @@ def _lmul_(self, a): - ``a`` -- an element of the algebra the parent module is defined over - OUTPUT: - - The module element `a \cdot x` where `x` is ``self``. + OUTPUT: the module element `a \cdot x` where `x` is ``self`` EXAMPLES:: @@ -180,7 +176,7 @@ def _lmul_(self, a): def vector_presentation(self): r""" - A coordinate vector representing ``self`` when it is non-zero. + A coordinate vector representing ``self`` when it is nonzero. These are coordinates with respect to the basis chosen by :meth:`~sage.modules.fp_graded.module.FPModule.basis_elements`. @@ -190,7 +186,7 @@ def vector_presentation(self): OUTPUT: A vector of elements in the ground ring of the algebra for - this module when this element is non-zero. Otherwise, the + this module when this element is nonzero. Otherwise, the value ``None``. .. SEEALSO:: @@ -250,11 +246,11 @@ def vector_presentation(self): def __bool__(self): r""" - Determine if this element is non-zero. + Determine if this element is nonzero. OUTPUT: - The boolean value ``True`` if this element is non-zero + The boolean value ``True`` if this element is nonzero and ``False`` otherwise. EXAMPLES:: @@ -281,7 +277,7 @@ def __bool__(self): def __eq__(self, other): r""" - True iff ``self`` and ``other`` are equal. + ``True`` iff ``self`` and ``other`` are equal. EXAMPLES:: diff --git a/src/sage/modules/fp_graded/free_element.py b/src/sage/modules/fp_graded/free_element.py index 8dc11e7764a..c37eed11566 100755 --- a/src/sage/modules/fp_graded/free_element.py +++ b/src/sage/modules/fp_graded/free_element.py @@ -164,9 +164,7 @@ def _lmul_(self, a): - ``a`` -- an element of the algebra the parent module is defined over - OUTPUT: - - The module element `a \cdot x` where `x` is this module element. + OUTPUT: the module element `a \cdot x` where `x` is this module element EXAMPLES:: @@ -198,7 +196,7 @@ def _lmul_(self, a): @cached_method def vector_presentation(self): r""" - A coordinate vector representing ``self`` when it is a non-zero + A coordinate vector representing ``self`` when it is a nonzero homogeneous element. These are coordinates with respect to the basis chosen by @@ -209,7 +207,7 @@ def vector_presentation(self): OUTPUT: A vector of elements in the ground ring of the algebra for - this module when this element is non-zero. Otherwise, the value + this module when this element is nonzero. Otherwise, the value ``None``. .. SEEALSO:: diff --git a/src/sage/modules/fp_graded/free_module.py b/src/sage/modules/fp_graded/free_module.py index ea736cc54ea..3f5ec2a9284 100755 --- a/src/sage/modules/fp_graded/free_module.py +++ b/src/sage/modules/fp_graded/free_module.py @@ -79,7 +79,7 @@ sage: Sq(2) * x (Sq(4,1)+Sq(7))*g[0] + Sq(3,1)*g[1] -Each non-zero element has a well-defined degree:: +Each nonzero element has a well-defined degree:: sage: x.degree() 5 @@ -306,7 +306,7 @@ class FreeGradedModule(CombinatorialFreeModule): - ``generator_degrees`` -- tuple of integers defining the number of generators of the module, and their degrees - - ``names`` -- optional, the names of the generators. If ``names`` + - ``names`` -- (optional) the names of the generators. If ``names`` is a comma-separated string like ``'a, b, c'``, then those will be the names. Otherwise, for example if ``names`` is ``abc``, then the names will be ``abc(d,i)``. @@ -549,7 +549,7 @@ def _element_constructor_(self, coefficients): INPUT: - - ``coefficients`` -- a tuple of coefficient (i.e. elements of the + - ``coefficients`` -- tuple of coefficient (i.e. elements of the algebra for this module), an element of FreeGradedModule, or the zero integer constant @@ -646,7 +646,7 @@ def basis_elements(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: @@ -733,11 +733,9 @@ def element_from_coordinates(self, coordinates, n): INPUT: - ``coordinates`` -- a sequence of elements of the ground ring - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: - - A module element of degree ``n``. + OUTPUT: a module element of degree ``n`` .. SEEALSO:: @@ -811,7 +809,7 @@ def vector_presentation(self, n): INPUT: - - ``n`` -- an integer degree + - ``n`` -- integer degree OUTPUT: @@ -921,7 +919,7 @@ def suspension(self, t): INPUT: - - ``t`` -- an integer + - ``t`` -- integer OUTPUT: @@ -985,12 +983,12 @@ def resolution(self, k, top_dim=None, verbose=False): INPUT: - - ``k`` -- a non-negative integer + - ``k`` -- nonnegative integer - ``top_dim`` -- stop the computation at this degree. Ignored, for compatibility with :meth:`sage.modules.fp_graded.module.FPModule.resolution`. - - ``verbose`` -- (default: ``False``) a boolean to control if - log messages should be emitted + - ``verbose`` -- boolean (default: ``False``); controls whether log + messages should be emitted OUTPUT: @@ -1026,7 +1024,7 @@ def resolution(self, k, top_dim=None, verbose=False): Module endomorphism of Free graded left module on 0 generators over The exterior algebra of rank 3 over Rational Field] """ if k < 0: - raise ValueError('the length of the resolution must be non-negative') + raise ValueError('the length of the resolution must be nonnegative') # The first map \epsilon is the identity map ret_complex = [Hom(self, self).identity()] @@ -1047,9 +1045,7 @@ def minimal_presentation(self, top_dim=None, verbose=False): r""" Return a minimal presentation of ``self``. - OUTPUT: - - The identity morphism as ``self`` is free. + OUTPUT: the identity morphism as ``self`` is free EXAMPLES:: diff --git a/src/sage/modules/fp_graded/free_morphism.py b/src/sage/modules/fp_graded/free_morphism.py index 8044fb3883b..68560eaf9e3 100755 --- a/src/sage/modules/fp_graded/free_morphism.py +++ b/src/sage/modules/fp_graded/free_morphism.py @@ -34,7 +34,7 @@ class FreeGradedModuleMorphism(FPModuleMorphism): - ``parent`` -- a homspace in the category of finitely generated free modules - - ``values`` -- a list of elements in the codomain; each element + - ``values`` -- list of elements in the codomain; each element corresponds (by their ordering) to a module generator in the domain EXAMPLES:: @@ -178,9 +178,7 @@ def fp_module(self): r""" Create a finitely presented module from ``self``. - OUTPUT: - - The finitely presented module with presentation equal to ``self``. + OUTPUT: the finitely presented module with presentation equal to ``self`` EXAMPLES:: diff --git a/src/sage/modules/fp_graded/homspace.py b/src/sage/modules/fp_graded/homspace.py index 6edb4bb7dd6..0e3fe9be73e 100755 --- a/src/sage/modules/fp_graded/homspace.py +++ b/src/sage/modules/fp_graded/homspace.py @@ -143,9 +143,7 @@ def an_element(self, n=0): - ``n`` -- (default: 0) an integer degree - OUTPUT: - - A module homomorphism of degree ``n``. + OUTPUT: a module homomorphism of degree ``n`` EXAMPLES:: @@ -192,11 +190,9 @@ def basis_elements(self, n): INPUT: - - ``n`` -- an integer degree + - ``n`` -- integer degree - OUTPUT: - - A basis for the set of all module homomorphisms of degree ``n``. + OUTPUT: a basis for the set of all module homomorphisms of degree ``n`` EXAMPLES:: @@ -241,7 +237,6 @@ def zero(self): To: Free graded left module on 2 generators over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1] Defn: g[1] |--> 0 g[3] |--> 0 - """ ngens = len(self.domain().generator_degrees()) return self.element_class(self, [self.codomain().zero()] * ngens) @@ -310,7 +305,7 @@ def _basis_elements(self, n, basis): INPUT: - - ``n`` -- an integer degree + - ``n`` -- integer degree - ``basis`` -- boolean; decide if a basis should be returned or just a single homomorphism diff --git a/src/sage/modules/fp_graded/module.py b/src/sage/modules/fp_graded/module.py index 62536fabc20..992fe25b8ae 100755 --- a/src/sage/modules/fp_graded/module.py +++ b/src/sage/modules/fp_graded/module.py @@ -319,7 +319,7 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): INPUT: - - ``d`` -- a dictionary + - ``d`` -- dictionary This code is taken from the method of the same name for ``sage.combinat.free_module.FreeModule``. @@ -402,7 +402,7 @@ def _element_constructor_(self, x): INPUT: - - ``x`` -- a tuple of coefficients, an element of FPModule, or the + - ``x`` -- tuple of coefficients, an element of FPModule, or the zero integer constant OUTPUT: @@ -644,11 +644,9 @@ def an_element(self, n=None): INPUT: - - ``n`` -- (optional) the degree of the element to construct + - ``n`` -- (optional) the degree of the element to construct - OUTPUT: - - A module element of the given degree. + OUTPUT: a module element of the given degree EXAMPLES:: @@ -683,8 +681,8 @@ def basis_elements(self, n, verbose=False): INPUT: - - ``n`` -- an integer - - ``verbose`` -- (default: ``False``) a boolean to control if log + - ``n`` -- integer + - ``verbose`` -- boolean (default: ``False``); controls whether log messages should be emitted OUTPUT: @@ -798,9 +796,7 @@ def vector_presentation(self, n, verbose=False): - ``n`` -- the degree of the presentation - OUTPUT: - - A vector space. + OUTPUT: a vector space .. SEEALSO:: @@ -1068,7 +1064,7 @@ def suspension(self, t): INPUT: - - ``t`` -- an integer degree by which the module is suspended + - ``t`` -- integer degree by which the module is suspended OUTPUT: @@ -1113,11 +1109,9 @@ def submodule_inclusion(self, spanning_elements): INPUT: - - ``spanning_elements`` -- an iterable of elements + - ``spanning_elements`` -- an iterable of elements - OUTPUT: - - The inclusion of the submodule into this module. + OUTPUT: the inclusion of the submodule into this module Because a submodule of a finitely presented module need not be finitely presented, this method will only work if the @@ -1155,16 +1149,14 @@ def resolution(self, k, top_dim=None, verbose=False): INPUT: - - ``k`` -- a non-negative integer + - ``k`` -- nonnegative integer - ``top_dim`` -- stop the computation at this degree (default: ``None``, but required if the algebra is not finite-dimensional) - - ``verbose`` -- (default: ``False``) a boolean to control if + - ``verbose`` -- boolean (default: ``False``); control if log messages should be emitted - OUTPUT: - - A list of homomorphisms `[\epsilon, f_1, \ldots, f_k]` such that + OUTPUT: list of homomorphisms `[\epsilon, f_1, \ldots, f_k]` such that .. MATH:: @@ -1315,7 +1307,7 @@ def _print_progress(i, k): print('Computing f_%d (%d/%d)' % (i, i, k)) if k < 0: - raise ValueError('the length of the resolution must be non-negative') + raise ValueError('the length of the resolution must be nonnegative') ret_complex = [] diff --git a/src/sage/modules/fp_graded/morphism.py b/src/sage/modules/fp_graded/morphism.py index 219058b4af8..890178110a6 100755 --- a/src/sage/modules/fp_graded/morphism.py +++ b/src/sage/modules/fp_graded/morphism.py @@ -45,11 +45,11 @@ def _create_relations_matrix(module, relations, source_degs, target_degs): INPUT: - ``module`` -- the module where the relations acts - - ``relations`` -- a list of lists of algebra coefficients defining the + - ``relations`` -- list of lists of algebra coefficients defining the matrix `R` - - ``source_degs`` -- a list of integer degrees; its length should be + - ``source_degs`` -- list of integer degrees; its length should be equal to the number of columns of `R` - - ``target_degs`` -- a list of integer degrees; its length should be + - ``target_degs`` -- list of integer degrees; its length should be equal to the number of rows of `R` Furthermore must the degrees given by the input satisfy the following:: @@ -60,12 +60,12 @@ def _create_relations_matrix(module, relations, source_degs, target_degs): OUTPUT: - - ``block_matrix`` -- A list of lists representing a matrix of linear + - ``block_matrix`` -- list of lists representing a matrix of linear transformations `(T_{ij})`. Each transformtion `T_{ij}` is the linear map representing multiplication by the coefficient `r_{ij}` restricted to the module elements of degree ``source_degs[j]``. - - ``R`` -- A matrix representing ``block_matrix`` as a single linear - transformation. + - ``R`` -- a matrix representing ``block_matrix`` as a single linear + transformation TESTS:: @@ -151,7 +151,7 @@ class FPModuleMorphism(Morphism): INPUT: - ``parent`` -- a homspace of finitely presented graded modules - - ``values`` -- a list of elements in the codomain; each element + - ``values`` -- list of elements in the codomain; each element corresponds to a module generator in the domain - ``check`` -- boolean (default: ``True``); if ``True``, check that the morphism is well-defined @@ -301,9 +301,7 @@ def degree(self): r""" The degree of ``self``. - OUTPUT: - - The integer degree of ``self``. + OUTPUT: the integer degree of ``self`` EXAMPLES:: @@ -346,9 +344,7 @@ def values(self): r""" The values under ``self`` of the module generators of the domain module. - OUTPUT: - - A sequence of module elements of the codomain. + OUTPUT: a sequence of module elements of the codomain EXAMPLES:: @@ -619,9 +615,7 @@ def is_zero(self): r""" Decide if ``self`` is the zero homomorphism. - OUTPUT: - - The boolean value ``True`` if ``self`` is trivial and ``False`` otherwise. + OUTPUT: the boolean value ``True`` if ``self`` is trivial and ``False`` otherwise EXAMPLES:: @@ -700,7 +694,7 @@ def __call__(self, x): INPUT: - - ``x`` -- an element of the domain of the homomorphism + - ``x`` -- an element of the domain of the homomorphism OUTPUT: @@ -775,7 +769,7 @@ def vector_presentation(self, n): Return the restriction of ``self`` to the domain module elements of degree ``n``. - The restriction of a non-zero module homomorphism to the free module + The restriction of a nonzero module homomorphism to the free module of module elements of degree `n` is a linear function into the free module of elements of degree `n+d` belonging to the codomain. Here `d` is the degree of this homomorphism. @@ -786,7 +780,7 @@ def vector_presentation(self, n): INPUT: - - ``n`` -- an integer degree + - ``n`` -- integer degree OUTPUT: @@ -1250,7 +1244,7 @@ def split(self, verbose=False): INPUT: - - ``verbose`` -- boolean (default: ``False``); enable progress messages + - ``verbose`` -- boolean (default: ``False``); enable progress messages OUTPUT: @@ -1350,11 +1344,9 @@ def suspension(self, t): INPUT: - - ``t`` -- an integer by which the morphism is suspended - - OUTPUT: + - ``t`` -- integer by which the morphism is suspended - The morphism which is the suspension of ``self`` by the degree ``t``. + OUTPUT: the morphism which is the suspension of ``self`` by the degree ``t`` EXAMPLES:: @@ -1967,7 +1959,7 @@ def fp_module(self): @cached_function def _top_dim(algebra): r""" - The top dimension of ``algebra`` + The top dimension of ``algebra``. This returns infinity if the algebra is infinite-dimensional. If the algebra has a ``top_class`` method, then it is used in the diff --git a/src/sage/modules/fp_graded/steenrod/module.py b/src/sage/modules/fp_graded/steenrod/module.py index 90160d18a19..e799fadf389 100755 --- a/src/sage/modules/fp_graded/steenrod/module.py +++ b/src/sage/modules/fp_graded/steenrod/module.py @@ -249,7 +249,7 @@ def export_module_definition(self, powers_of_two_only=True): # A private function which transforms a vector in a given dimension # to a vector of global indices for the basis elements corresponding - # to the non-zero entries in the vector. E.g. + # to the nonzero entries in the vector. E.g. # _GetIndices(dim=2, vec=(1,0,1)) will return a vector of length two, # (a, b), where a is the index of the first vector in the basis for # the 2-dimensional part of the module, and b is the index of the @@ -357,13 +357,12 @@ def resolution(self, k, top_dim=None, verbose=False): INPUT: - - ``k`` -- non-negative integer + - ``k`` -- nonnegative integer - ``top_dim`` -- (optional) stop the computation at this degree - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed - OUTPUT: - - A list of homomorphisms `[\epsilon, f_1, \ldots, f_k]` such that + OUTPUT: list of homomorphisms `[\epsilon, f_1, \ldots, f_k]` such that .. MATH:: diff --git a/src/sage/modules/fp_graded/steenrod/morphism.py b/src/sage/modules/fp_graded/steenrod/morphism.py index 595db1a33aa..2a57af86866 100755 --- a/src/sage/modules/fp_graded/steenrod/morphism.py +++ b/src/sage/modules/fp_graded/steenrod/morphism.py @@ -98,7 +98,8 @@ def is_injective(self, top_dim=None, verbose=False): - ``top_dim`` -- (optional) stop the computation at this degree; if not specified, this is determined using :meth:`profile` - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed EXAMPLES:: @@ -131,9 +132,10 @@ def kernel_inclusion(self, top_dim=None, verbose=False): - ``top_dim`` -- (optional) stop the computation at this degree; if not specified, this is determined using :meth:`profile` - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed - OUTPUT: An injective homomorphism into the domain ``self`` which is + OUTPUT: an injective homomorphism into the domain ``self`` which is onto the kernel of this homomorphism. EXAMPLES:: @@ -176,7 +178,8 @@ def cokernel_projection(self, verbose=False): INPUT: - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed OUTPUT: @@ -221,7 +224,8 @@ def image(self, top_dim=None, verbose=False): - ``top_dim`` -- integer (optional); used by this function to stop the computation at the given degree - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed OUTPUT: @@ -263,7 +267,6 @@ def image(self, top_dim=None, verbose=False): sage: g.is_zero() True - """ return self._action(FPModuleMorphism.image, top_dim=top_dim, verbose=verbose) @@ -275,9 +278,10 @@ def _resolve_kernel(self, top_dim=None, verbose=False): - ``top_dim`` -- (optional) stop the computation at this degree; if not specified, this is determined using :meth:`profile` - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed - OUTPUT: A homomorphism `j: F \rightarrow D` where `D` is the domain of + OUTPUT: a homomorphism `j: F \rightarrow D` where `D` is the domain of this homomorphism, `F` is free and such that `\ker(self) = \operatorname{im}(j)`. TESTS:: @@ -322,9 +326,10 @@ def _resolve_image(self, top_dim=None, verbose=False): - ``top_dim`` -- (optional) stop the computation at this degree; if not specified, this is determined using :meth:`profile` - - ``verbose`` -- (default: ``False``) whether log messages are printed + - ``verbose`` -- boolean (default: ``False``); whether log messages are + printed - OUTPUT: A homomorphism `j: F \rightarrow C` where `C` is the codomain + OUTPUT: a homomorphism `j: F \rightarrow C` where `C` is the codomain of this homomorphism, `F` is free, and `\operatorname{im}(self) = \operatorname{im}(j)`. diff --git a/src/sage/modules/fp_graded/steenrod/profile.py b/src/sage/modules/fp_graded/steenrod/profile.py index 13c5171b7b1..7326eb37eaf 100755 --- a/src/sage/modules/fp_graded/steenrod/profile.py +++ b/src/sage/modules/fp_graded/steenrod/profile.py @@ -41,15 +41,15 @@ def profile_elt(elt, char=2): - ``elt`` -- element of the Steenrod algebra (or a sub-Hopf algebra of it) or list(s) representing it - - ``char`` (default: 2) -- the characteristic + - ``char`` -- (default: 2) the characteristic ``elt`` could also be a list (when ``char=2``) or a pair of lists (otherwise), in which case it is treated as corresponding to an element of the Steenrod algebra: ``(a, b, c) <-> Sq(a, b, c)`` or ``((a, b, c), (x, y, z)) <-> Q_a Q_b Q_c P(x, y, z)``. - OUTPUT: The profile function corresponding to the smallest - sub-Hopf algebra containing the element passed. + OUTPUT: the profile function corresponding to the smallest + sub-Hopf algebra containing the element passed EXAMPLES:: @@ -102,13 +102,13 @@ def enveloping_profile_elements(alist, char=2): INPUT: - ``alist`` -- list of Steenrod algebra elements - - ``char`` (default: 2) -- the characteristic + - ``char`` -- (default: 2) the characteristic As with :func:`profile_elt`, the entries of ``alist`` could also be iterables or pairs of iterables. - OUTPUT: The profile function for the minimum sub-algebra - containing all the elements of ``alist``. + OUTPUT: the profile function for the minimum sub-algebra + containing all the elements of ``alist`` EXAMPLES:: @@ -155,16 +155,14 @@ def enveloping_profile_elements(alist, char=2): def find_min_profile(prof, char=2): r""" Return the smallest valid profile function containing a tuple of - non-negative integers, + nonnegative integers. INPUT: - - ``prof`` -- a list or tuple of nonnegative integers - - ``char`` (default: 2) -- the characteristic + - ``prof`` -- list or tuple of nonnegative integers + - ``char`` -- (default: 2) the characteristic - OUTPUT: - - - a valid profile containing ``prof`` + OUTPUT: a valid profile containing ``prof`` A profile function `e` must satisfy `e(r) \geq \min( e(r-i) - i, e(i))` for all `0 < i < r`, and at odd primes, if `k(i+j) = 1`, diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 6bf1b79bd7d..6b407414030 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -308,7 +308,7 @@ def create_object(self, version, key): def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_matrix=None, *, with_basis='standard', rank=None, basis_keys=None, **args): r""" - Create a free module over the given commutative ``base_ring`` + Create a free module over the given commutative ``base_ring``. ``FreeModule`` can be called with the following positional arguments: @@ -318,22 +318,22 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m INPUT: - - ``base_ring`` -- a commutative ring + - ``base_ring`` -- a commutative ring - - ``rank`` -- a nonnegative integer + - ``rank`` -- nonnegative integer - - ``basis_keys`` -- a finite or enumerated family of arbitrary objects + - ``basis_keys`` -- a finite or enumerated family of arbitrary objects - - ``sparse`` -- boolean (default ``False``) + - ``sparse`` -- boolean (default: ``False``) - - ``inner_product_matrix`` -- the inner product matrix (default ``None``) + - ``inner_product_matrix`` -- the inner product matrix (default: ``None``) - - ``with_basis`` -- either ``"standard"`` (the default), in which case - a free module with the standard basis as the distinguished basis is created; - or ``None``, in which case a free module without distinguished basis is - created. + - ``with_basis`` -- either ``'standard'`` (the default), in which case + a free module with the standard basis as the distinguished basis is created; + or ``None``, in which case a free module without distinguished basis is + created. - - further options may be accepted by various implementation classes + - further options may be accepted by various implementation classes OUTPUT: a free module @@ -341,9 +341,9 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m depending on the input. Not all combinations of options are implemented. - - If the parameter ``basis_keys`` is provided, it must be a finite - or enumerated family of objects, and an instance of - :class:`CombinatorialFreeModule` is created. + - If the parameter ``basis_keys`` is provided, it must be a finite + or enumerated family of objects, and an instance of + :class:`CombinatorialFreeModule` is created. EXAMPLES:: @@ -355,9 +355,9 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m for more examples and details, including its :class:`UniqueRepresentation` semantics. - - If the parameter ``with_basis`` is set to ``None``, then a free module - of the given ``rank`` without distinguished basis is created. It is - represented by an instance of :class:`FiniteRankFreeModule`. + - If the parameter ``with_basis`` is set to ``None``, then a free module + of the given ``rank`` without distinguished basis is created. It is + represented by an instance of :class:`FiniteRankFreeModule`. EXAMPLES:: @@ -367,20 +367,19 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m See the documentation of :class:`FiniteRankFreeModule` for more options, examples, and details. - - If ``rank`` is provided and the option ``with_basis`` is left at its - default value, ``"standard"``, then a free ambient module with - distinguished standard basis indexed by ``range(rank)`` is created. - There is only one dense and one sparse free ambient module of - given ``rank`` over ``base_ring``. - - EXAMPLES:: + - If ``rank`` is provided and the option ``with_basis`` is left at its + default value, ``'standard'``, then a free ambient module with + distinguished standard basis indexed by ``range(rank)`` is created. + There is only one dense and one sparse free ambient module of + given ``rank`` over ``base_ring``. - sage: FreeModule(Integers(8), 10) - Ambient free module of rank 10 over Ring of integers modulo 8 + EXAMPLES:: - The remainder of this documentation discusses this case of - free ambient modules. + sage: FreeModule(Integers(8), 10) + Ambient free module of rank 10 over Ring of integers modulo 8 + The remainder of this documentation discusses this case of + free ambient modules. EXAMPLES: @@ -485,7 +484,6 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m Refactor modules such that it only counts what category the base ring belongs to, but not what is its Python class. - EXAMPLES:: sage: FreeModule(QQ, ['a', 'b', 'c']) @@ -598,7 +596,7 @@ def VectorSpace(K, dimension_or_basis_keys=None, sparse=False, inner_product_mat (0, 0, 1) ] - The base must be a field or a :class:`TypeError` is raised. + The base must be a field or a :exc:`TypeError` is raised. :: @@ -622,16 +620,16 @@ def span(gens, base_ring=None, check=True, already_echelonized=False): INPUT: - - ``gens`` -- a list of either vectors or lists of ring elements + - ``gens`` -- list of either vectors or lists of ring elements used to generate the span - - ``base_ring`` -- (default: ``None``); a principal ideal domain + - ``base_ring`` -- (default: ``None``) a principal ideal domain for the ring of scalars - - ``check`` -- (default: ``True``); passed to the ``span()`` method + - ``check`` -- (default: ``True``) passed to the ``span()`` method of the ambient module - - ``already_echelonized`` -- (default: ``False``); set to ``True`` + - ``already_echelonized`` -- (default: ``False``) set to ``True`` if the vectors form the rows of a matrix in echelon form, in order to skip the computation of an echelonized basis for the span. @@ -845,7 +843,7 @@ def basis_seq(V, vecs): def is_FreeModule(M): """ - Return True if M inherits from FreeModule_generic. + Return ``True`` if M inherits from ``FreeModule_generic``. EXAMPLES:: @@ -882,7 +880,7 @@ class Module_free_ambient(Module): - ``base_ring`` -- a commutative ring - - ``degree`` -- a non-negative integer; degree of the ambient free module + - ``degree`` -- nonnegative integer; degree of the ambient free module - ``sparse`` -- boolean (default: ``False``) @@ -1038,9 +1036,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -1610,11 +1606,11 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): INPUT: - - ``gens`` -- a list of vectors + - ``gens`` -- list of vectors - ``base_ring`` -- (optional) a ring - - ``check`` -- boolean (default: ``True``): whether or not to + - ``check`` -- boolean (default: ``True``); whether or not to coerce entries of gens into base field - ``already_echelonized`` -- boolean (default: ``False``); @@ -1738,9 +1734,9 @@ def submodule(self, gens, check=True, already_echelonized=False): INPUT: - - ``gens`` -- a list of free module elements or a free module + - ``gens`` -- list of free module elements or a free module - - ``check`` -- (default: ``True``) whether or not to verify + - ``check`` -- boolean (default: ``True``); whether or not to verify that the gens are in ``self`` OUTPUT: @@ -1769,7 +1765,7 @@ def submodule(self, gens, check=True, already_echelonized=False): [3 3 0] We try to create a submodule that is not really a submodule, - which results in an :class:`ArithmeticError` exception:: + which results in an :exc:`ArithmeticError` exception:: sage: W.submodule([B[0] - B[1]]) Traceback (most recent call last): @@ -1821,7 +1817,7 @@ def quotient_module(self, sub, check=True): - ``sub`` -- a submodule of ``self`` or something that can be turned into one via ``self.submodule(sub)`` - - ``check`` -- (default: ``True``) whether or not to check that + - ``check`` -- boolean (default: ``True``); whether or not to check that ``sub`` is a submodule EXAMPLES:: @@ -1942,9 +1938,9 @@ class FreeModule_generic(Module_free_ambient): - ``base_ring`` -- a commutative ring - - ``rank`` -- a non-negative integer + - ``rank`` -- nonnegative integer - - ``degree`` -- a non-negative integer + - ``degree`` -- nonnegative integer - ``sparse`` -- boolean (default: ``False``) @@ -2014,7 +2010,6 @@ def __init__(self, base_ring, rank, degree, sparse=False, sage: N.element_class - """ if base_ring not in CommutativeRings(): warn("You are constructing a free module\n" @@ -2041,7 +2036,7 @@ def __init__(self, base_ring, rank, degree, sparse=False, def construction(self): """ - The construction functor and base ring for self. + The construction functor and base ring for ``self``. EXAMPLES:: @@ -2104,9 +2099,9 @@ def dense_module(self): def _dense_module(self): """ - Creates a dense module with the same defining data as self. + Create a dense module with the same defining data as ``self``. - N.B. This function is for internal use only! See dense_module for + N.B. This function is for internal use only! See ``dense_module`` for use. EXAMPLES:: @@ -2161,9 +2156,9 @@ def sparse_module(self): def _sparse_module(self): """ - Creates a sparse module with the same defining data as self. + Create a sparse module with the same defining data as ``self``. - N.B. This function is for internal use only! See sparse_module for + N.B. This function is for internal use only! See ``sparse_module`` for use. EXAMPLES:: @@ -2183,9 +2178,9 @@ def _element_constructor_(self, x, coerce=True, copy=True, check=True): The ``coerce`` and ``copy`` arguments are passed on to the underlying element constructor. If ``check`` is ``True``, confirm that the - element specified by x does in fact lie in self. + element specified by x does in fact lie in ``self``. - .. note:: + .. NOTE:: In the case of an inexact base ring (i.e. RDF), we don't verify that the element is in the subspace, even when @@ -2482,7 +2477,7 @@ def __iter__(self): if R in InfiniteEnumeratedSets(): # This makes iter(ZZ^n) produce vectors in a "natural" order, - # rather than only vectors with the first component non-zero. + # rather than only vectors with the first component nonzero. # Algorithm: Initial version which ordered by max-norm due to # Aleksei Udovenko, adapted by Lorenz Panny to order by 1-norm # primarily and by max-norm secondarily. @@ -2532,9 +2527,7 @@ def cardinality(self): r""" Return the cardinality of the free module. - OUTPUT: - - Either an integer or ``+Infinity``. + OUTPUT: either an integer or ``+Infinity`` EXAMPLES:: @@ -2758,25 +2751,24 @@ def direct_sum(self, other): def coordinates(self, v, check=True): """ - Write `v` in terms of the basis for self. + Write `v` in terms of the basis for ``self``. INPUT: - ``v`` -- vector - - ``check`` -- boolean (default: ``True``); if ``True``, also verify that - `v` is really in ``self``. + - ``check`` -- boolean (default: ``True``); if ``True``, also verify + that `v` is really in ``self`` OUTPUT: list - Returns a list `c` such that if `B` is the basis - for self, then + Returns a list `c` such that if `B` is the basis for ``self``, then .. MATH:: \\sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -2790,14 +2782,14 @@ def coordinates(self, v, check=True): def coordinate_vector(self, v, check=True): """ Return the vector whose coefficients give `v` as a linear - combination of the basis for self. + combination of the basis for ``self``. INPUT: - ``v`` -- vector - ``check`` -- boolean (default: ``True``); if ``True``, also verify that - `v` is really in ``self``. + `v` is really in ``self`` OUTPUT: list @@ -3012,9 +3004,9 @@ def gen(self, i=0): INPUT: - - `i` -- an integer (default 0) + - ``i`` -- integer (default: 0) - OUTPUT: `i`-th basis vector for ``self``. + OUTPUT: `i`-th basis vector for ``self`` EXAMPLES:: @@ -3097,12 +3089,12 @@ def hom(self, im_gens, codomain=None, **kwds): EXAMPLES:: - sage: W = ZZ^2; W.hom(matrix(1, [1, 2]), side="right") + sage: W = ZZ^2; W.hom(matrix(1, [1, 2]), side='right') Free module morphism defined as left-multiplication by the matrix [1 2] Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 1 over the principal ideal domain Integer Ring - sage: V = QQ^2; V.hom(identity_matrix(2), side="right") + sage: V = QQ^2; V.hom(identity_matrix(2), side='right') Vector space morphism represented as left-multiplication by the matrix: [1 0] [0 1] @@ -3167,7 +3159,7 @@ def _inner_product_is_dot_product(self): def is_ambient(self): """ - Returns False since this is not an ambient free module. + Return ``False`` since this is not an ambient free module. EXAMPLES:: @@ -3193,7 +3185,7 @@ def is_ambient(self): def is_dense(self): """ Return ``True`` if the underlying representation of - this module uses dense vectors, and False otherwise. + this module uses dense vectors, and ``False`` otherwise. EXAMPLES:: @@ -3221,7 +3213,7 @@ def is_full(self): def is_finite(self): """ - Returns True if the underlying set of this free module is finite. + Return ``True`` if the underlying set of this free module is finite. EXAMPLES:: @@ -3236,7 +3228,7 @@ def is_finite(self): def ngens(self): """ - Returns the number of basis elements of this free module. + Return the number of basis elements of this free module. EXAMPLES:: @@ -3255,7 +3247,7 @@ def ngens(self): def nonembedded_free_module(self): """ - Returns an ambient free module that is isomorphic to this free + Return an ambient free module that is isomorphic to this free module. Thus if this free module is of rank `n` over a ring @@ -3271,16 +3263,16 @@ def nonembedded_free_module(self): def random_element(self, prob=1.0, *args, **kwds): """ - Returns a random element of self. + Return a random element of ``self``. INPUT: - ``prob`` -- float. Each coefficient will be set to zero with - probability `1-prob`. Otherwise coefficients will be chosen - randomly from base ring (and may be zero). + probability `1-prob`. Otherwise coefficients will be chosen + randomly from base ring (and may be zero). - ``*args``, ``**kwds`` -- passed on to the :func:`random_element` - function of the base ring. + function of the base ring EXAMPLES:: @@ -3329,7 +3321,7 @@ def rank(self): def __bool__(self): """ Return ``True`` if and only if the rank of this module is - non-zero. In other words, this returns ``False`` for the zero + nonzero. In other words, this returns ``False`` for the zero module and ``True`` otherwise (apart from the exceptional case where the base ring is the zero ring). @@ -3621,7 +3613,6 @@ def _mul_(self, other, switch_sides=False): over Finite Field of size 2 Basis matrix: [1 1] - """ B = self.basis_matrix() B = other * B if switch_sides else B * other @@ -3669,8 +3660,8 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, def __add__(self, other): r""" - Return the sum of ``self`` and other, where both ``self`` and ``other`` must be - submodules of the ambient vector space. + Return the sum of ``self`` and ``other``, where both ``self`` and + ``other`` must be submodules of the ambient vector space. EXAMPLES: @@ -4038,7 +4029,7 @@ def index_in_saturation(self): def saturation(self): r""" Return the saturated submodule of `R^n` that spans the same - vector space as self. + vector space as ``self``. EXAMPLES: @@ -4181,19 +4172,17 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F def submodule_with_basis(self, basis, check=True, already_echelonized=False): r""" - Create the R-submodule of the ambient vector space with given - basis, where R is the base ring of self. + Create the `R`-submodule of the ambient vector space with given + basis, where `R` is the base ring of ``self``. INPUT: - - ``basis`` -- a list of linearly independent vectors + - ``basis`` -- list of linearly independent vectors - ``check`` -- whether or not to verify that each gen is in - the ambient vector space + the ambient vector space - OUTPUT: - - - ``FreeModule`` -- the `R`-submodule with given basis + OUTPUT: ``FreeModule``; the `R`-submodule with given basis EXAMPLES: @@ -4260,12 +4249,10 @@ def vector_space_span(self, gens, check=True): INPUT: + - ``gens`` -- list of vector in ``self`` - - ``gens`` -- a list of vector in self - - - ``check`` -- whether or not to verify that each gen - is in the ambient vector space - + - ``check`` -- whether or not to verify that each gen + is in the ambient vector space OUTPUT: a vector subspace @@ -4322,10 +4309,10 @@ def vector_space_span_of_basis(self, basis, check=True): INPUT: - - ``basis`` -- a list of linearly independent vectors + - ``basis`` -- list of linearly independent vectors - ``check`` -- whether or not to verify that each gen is in - the ambient vector space + the ambient vector space OUTPUT: a vector subspace with user-specified basis @@ -4351,7 +4338,7 @@ def quotient_module(self, sub, check=True, **kwds): - ``sub`` -- a submodule of ``self``, or something that can be turned into one via ``self.submodule(sub)`` - - ``check`` -- (default: ``True``) whether or not to check + - ``check`` -- boolean (default: ``True``); whether or not to check that ``sub`` is a submodule - further named arguments, that are passed to the constructor @@ -4383,7 +4370,7 @@ class FreeModule_generic_field(FreeModule_generic_pid): """ def __init__(self, base_field, dimension, degree, sparse=False, category=None): """ - Creates a vector space over a field. + Create a vector space over a field. EXAMPLES:: @@ -4406,7 +4393,7 @@ def __init__(self, base_field, dimension, degree, sparse=False, category=None): def _Hom_(self, Y, category): r""" - Returns a homspace whose morphisms have this vector space as domain. + Return a homspace whose morphisms have this vector space as domain. This is called by the general methods such as :meth:`sage.structure.parent.Parent.Hom`. @@ -4501,7 +4488,7 @@ def scale(self, other): def __add__(self, other): """ - Return the sum of ``self`` and other. + Return the sum of ``self`` and ``other``. EXAMPLES:: @@ -4543,8 +4530,8 @@ def echelonized_basis_matrix(self): def intersection(self, other): """ - Return the intersection of ``self`` and other, which must be - R-submodules of a common ambient vector space. + Return the intersection of ``self`` and ``other``, which must be + `R`-submodules of a common ambient vector space. EXAMPLES:: @@ -4641,7 +4628,7 @@ def intersection(self, other): def is_subspace(self, other): """ - True if this vector space is a subspace of other. + ``True`` if this vector space is a subspace of ``other``. EXAMPLES:: @@ -4665,19 +4652,17 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F field of ``self`` or user specified base_ring. Note that this span is a subspace of the ambient vector space, but - need not be a subspace of self. + need not be a subspace of ``self``. INPUT: + - ``basis`` -- list of vectors - - ``basis`` -- list of vectors - - - ``check`` -- boolean (default: ``True``): whether or not to - coerce entries of gens into base field - - - ``already_echelonized`` -- boolean (default: ``False``): - set this if you know the gens are already in echelon form + - ``check`` -- boolean (default: ``True``); whether or not to + coerce entries of gens into base field + - ``already_echelonized`` -- boolean (default: ``False``); + set this if you know the gens are already in echelon form EXAMPLES:: @@ -4693,7 +4678,7 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F [3 3 0] The basis vectors must be linearly independent or a - :class:`ValueError` exception is raised:: + :exc:`ValueError` exception is raised:: sage: W.span_of_basis([[2,2,2], [3,3,3]]) Traceback (most recent call last): @@ -4722,13 +4707,13 @@ def subspace(self, gens, check=True, already_echelonized=False): INPUT: - - ``gens`` -- list of vectors + - ``gens`` -- list of vectors - - ``check`` -- boolean (default: ``True``) verify that gens - are all in ``self``. + - ``check`` -- boolean (default: ``True``); verify that gens + are all in ``self`` - - ``already_echelonized`` -- boolean (default: ``False``) set - to True if you know the gens are in Echelon form. + - ``already_echelonized`` -- boolean (default: ``False``); set + to ``True`` if you know the gens are in Echelon form EXAMPLES: @@ -4752,7 +4737,7 @@ def subspace(self, gens, check=True, already_echelonized=False): [1 1 0] With ``check=True`` (the default) the mistake is correctly - detected and reported with an :class:`ArithmeticError` exception:: + detected and reported with an :exc:`ArithmeticError` exception:: sage: W.subspace([[1,1,0]], check=True) Traceback (most recent call last): @@ -4767,7 +4752,7 @@ def subspaces(self, dim): INPUT: - - ``dim`` -- int, dimension of subspaces to be generated + - ``dim`` -- integer; dimension of subspaces to be generated EXAMPLES:: @@ -4924,8 +4909,8 @@ def complement(self): def vector_space(self, base_field=None): """ - Return the vector space associated to self. Since ``self`` is a vector - space this function simply returns self, unless the base field is + Return the vector space associated to ``self``. Since ``self`` is a vector + space this function simply returns ``self``, unless the base field is different. EXAMPLES:: @@ -4945,7 +4930,7 @@ def vector_space(self, base_field=None): def zero_submodule(self): """ - Return the zero submodule of self. + Return the zero submodule of ``self``. EXAMPLES:: @@ -4958,7 +4943,7 @@ def zero_submodule(self): def zero_subspace(self): """ - Return the zero subspace of self. + Return the zero subspace of ``self``. EXAMPLES:: @@ -4971,19 +4956,21 @@ def zero_subspace(self): def linear_dependence(self, vectors, zeros='left', check=True): r""" - Returns a list of vectors giving relations of linear dependence for the input list of vectors. + Return a list of vectors giving relations of linear dependence for the + input list of vectors. + Can be used to check linear independence of a set of vectors. INPUT: - - ``vectors`` -- A list of vectors, all from the same vector - space. + - ``vectors`` -- list of vectors; all from the same vector + space - - ``zeros`` -- (default: ``'left'``); ``'left'`` or ``'right'`` + - ``zeros`` -- (default: ``'left'``) ``'left'`` or ``'right'`` as a general preference for where zeros are located in the returned coefficients - - ``check`` -- (default: ``True``); if ``True`` each item in + - ``check`` -- (default: ``True``) if ``True`` each item in the list ``vectors`` is checked for membership in ``self``. Set to ``False`` if you can be certain the vectors come from the vector space. @@ -5000,7 +4987,7 @@ def linear_dependence(self, vectors, zeros='left', check=True): list being empty, so this provides a test - see the examples below. The returned vectors are always independent, and with ``zeros`` set to - ``'left'`` they have 1's in their first non-zero entries and a qualitative + ``'left'`` they have 1s in their first nonzero entries and a qualitative disposition to having zeros in the low-index entries. With ``zeros`` set to ``'right'`` the situation is reversed with a qualitative disposition for zeros in the high-index entries. @@ -5167,7 +5154,7 @@ def quotient_module(self, sub, check=True): - ``sub`` -- a submodule of ``self``, or something that can be turned into one via ``self.submodule(sub)`` - - ``check`` -- (default: ``True``) whether or not to check + - ``check`` -- boolean (default: ``True``); whether or not to check that ``sub`` is a submodule EXAMPLES:: @@ -5305,22 +5292,21 @@ def quotient_abstract(self, sub, check=True, **kwds): INPUT: - - ``sub`` -- a submodule of ``self`` or something that can - be turned into one via ``self.submodule(sub)`` + - ``sub`` -- a submodule of ``self`` or something that can + be turned into one via ``self.submodule(sub)`` - - ``check`` -- (default: ``True``) whether or not to check - that sub is a submodule + - ``check`` -- boolean (default: ``True``); whether or not to check + that sub is a submodule - further named arguments, that are currently ignored. OUTPUT: - - ``U`` -- the quotient as an abstract *ambient* free module - - - ``pi`` -- projection map to the quotient + - ``U``; the quotient as an abstract *ambient* free module - - ``lift`` -- lifting map back from quotient + - ``pi``; projection map to the quotient + - ``lift``; lifting map back from quotient EXAMPLES:: @@ -5377,11 +5363,11 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category INPUT: - - ``base_ring`` -- a commutative ring + - ``base_ring`` -- a commutative ring - - ``rank`` -- a non-negative integer + - ``rank`` -- nonnegative integer - - ``sparse`` -- boolean (default: ``False``) + - ``sparse`` -- boolean (default: ``False``) - ``coordinate_ring`` -- a ring containing ``base_ring`` (default: equal to ``base_ring``) @@ -5468,7 +5454,7 @@ def _coerce_map_from_(self, M): def _dense_module(self): """ - Creates a dense module with the same defining data as self. + Create a dense module with the same defining data as ``self``. N.B. This function is for internal use only! See dense_module for use. @@ -5484,7 +5470,7 @@ def _dense_module(self): def _sparse_module(self): """ - Creates a sparse module with the same defining data as self. + Create a sparse module with the same defining data as ``self``. N.B. This function is for internal use only! See sparse_module for use. @@ -5500,7 +5486,7 @@ def _sparse_module(self): def echelonized_basis_matrix(self): """ - The echelonized basis matrix of self. + The echelonized basis matrix of ``self``. EXAMPLES:: @@ -5635,7 +5621,7 @@ def _echelon_matrix_richcmp(self, other, op): def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -5737,10 +5723,8 @@ def basis(self): OUTPUT: - - - ``Sequence`` -- an immutable sequence with universe - this ambient free module - + - ``Sequence`` -- an immutable sequence with universe + this ambient free module EXAMPLES:: @@ -5858,7 +5842,7 @@ def coordinate_vector(self, v, check=True): \\sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -5877,10 +5861,10 @@ def echelon_coordinate_vector(self, v, check=True): INPUT: - - ``v`` -- vector + - ``v`` -- vector - - ``check`` -- boolean (default: ``True``); if True, also - verify that `v` is really in ``self``. + - ``check`` -- boolean (default: ``True``); if ``True``, also + verify that `v` is really in ``self`` OUTPUT: list @@ -5904,8 +5888,8 @@ def echelon_coordinate_vector(self, v, check=True): def echelon_coordinates(self, v, check=True): """ - Returns the coordinate vector of v in terms of the echelon basis - for self. + Return the coordinate vector of v in terms of the echelon basis + for ``self``. EXAMPLES:: @@ -5939,18 +5923,16 @@ def echelon_coordinates(self, v, check=True): def random_element(self, prob=1.0, *args, **kwds): """ - Returns a random element of self. + Return a random element of ``self``. INPUT: - - ``prob`` -- float. Each coefficient will be set to zero with - probability `1-prob`. Otherwise coefficients will be chosen - randomly from base ring (and may be zero). + probability `1-prob`. Otherwise coefficients will be chosen + randomly from base ring (and may be zero). - ``*args``, ``**kwds`` -- passed on to random_element function of base - ring. - + ring EXAMPLES:: @@ -6013,9 +5995,9 @@ def gen(self, i=0): INPUT: - - `i` -- an integer (default 0) + - ``i`` -- integer (default: 0) - OUTPUT: `i`-th basis vector for ``self``. + OUTPUT: `i`-th basis vector for ``self`` EXAMPLES:: @@ -6197,8 +6179,8 @@ def coordinate_vector(self, v, check=True): - ``v`` -- vector - - ``check`` -- boolean (default: ``True``); if ``True``, also verify that - `v` is really in ``self``. + - ``check`` -- boolean (default: ``True``); if ``True``, also verify + that `v` is really in ``self`` OUTPUT: list @@ -6209,7 +6191,7 @@ def coordinate_vector(self, v, check=True): \\sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -6232,7 +6214,7 @@ def coordinate_vector(self, v, check=True): def vector_space(self, base_field=None): """ - Returns the vector space obtained from ``self`` by tensoring with the + Return the vector space obtained from ``self`` by tensoring with the fraction field of the base ring and extending to the field. EXAMPLES:: @@ -6266,7 +6248,7 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category - ``base_ring`` -- a principal ideal domain - - ``rank`` -- a non-negative integer + - ``rank`` -- nonnegative integer - ``sparse`` -- boolean (default: ``False``) @@ -6296,7 +6278,7 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category def _repr_(self) -> str: """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -6348,9 +6330,6 @@ def _repr_(self) -> str: ############################################################################### class FreeModule_ambient_field(FreeModule_generic_field, FreeModule_ambient_pid): - """ - - """ def __init__(self, base_field, dimension, sparse=False, category=None): """ Create the ambient vector space of given dimension over the given @@ -6358,11 +6337,11 @@ def __init__(self, base_field, dimension, sparse=False, category=None): INPUT: - - ``base_field`` -- a field + - ``base_field`` -- a field - - ``dimension`` -- a non-negative integer + - ``dimension`` -- nonnegative integer - - ``sparse`` -- boolean (default: ``False``) + - ``sparse`` -- boolean (default: ``False``) EXAMPLES:: @@ -6373,7 +6352,7 @@ def __init__(self, base_field, dimension, sparse=False, category=None): def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -6417,7 +6396,7 @@ def _repr_(self): def ambient_vector_space(self): """ - Returns ``self`` as the ambient vector space. + Return ``self`` as the ambient vector space. EXAMPLES:: @@ -6429,7 +6408,7 @@ def ambient_vector_space(self): def base_field(self): """ - Returns the base field of this vector space. + Return the base field of this vector space. EXAMPLES:: @@ -6488,28 +6467,27 @@ class FreeModule_submodule_with_basis_pid(FreeModule_generic_pid): INPUT: - ``ambient`` -- ambient free module over a principal ideal domain `R`, - i.e. `R^n`; + i.e. `R^n` - ``basis`` -- list of elements of `K^n`, where `K` is the fraction field - of `R`. These elements must be linearly independent and will be used as - the default basis of the constructed submodule; + of `R`; these elements must be linearly independent and will be used as + the default basis of the constructed submodule - - ``check`` -- (default: ``True``) if ``False``, correctness of the input - will not be checked and type conversion may be omitted, use with care; + - ``check`` -- boolean (default: ``True``); if ``False``, correctness of + the input will not be checked and type conversion may be omitted, use + with care - - ``echelonize`` -- (default:``False``) if ``True``, ``basis`` will be + - ``echelonize`` -- (default: ``False``) if ``True``, ``basis`` will be echelonized and the result will be used as the default basis of the constructed submodule; - - `` echelonized_basis`` -- (default: ``None``) if not ``None``, must be - the echelonized basis spanning the same submodule as ``basis``; - - - ``already_echelonized`` -- (default: ``False``) if ``True``, ``basis`` - must be already given in the echelonized form. + - ``echelonized_basis`` -- (default: ``None``) if not ``None``, must be + the echelonized basis spanning the same submodule as ``basis`` - OUTPUT: + - ``already_echelonized`` -- boolean (default: ``False``); if ``True``, + ``basis`` must be already given in the echelonized form - - `R`-submodule of `K^n` with the user-specified ``basis``. + OUTPUT: `R`-submodule of `K^n` with the user-specified ``basis`` EXAMPLES:: @@ -6649,7 +6627,7 @@ def __hash__(self): def _echelon_matrix_richcmp(self, other, op): r""" - Compare the free module ``self`` with other. + Compare the free module ``self`` with ``other``. Modules are ordered by their ambient spaces, then by dimension, then in order by their echelon matrices. @@ -6724,7 +6702,7 @@ def _echelon_matrix_richcmp(self, other, op): def construction(self): """ - Returns the functorial construction of self, namely, the subspace + Return the functorial construction of ``self``, namely, the subspace of the ambient module spanned by the given basis. EXAMPLES:: @@ -6818,7 +6796,6 @@ def _denominator(self, B): [ 0 23/6 46/3] sage: L._denominator(L.echelonized_basis_matrix().list()) 30 - """ if not B: return 1 @@ -6830,7 +6807,7 @@ def _denominator(self, B): def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -6949,7 +6926,6 @@ def ambient(self): [5 7 9] sage: U.ambient() Ambient free module of rank 3 over the principal ideal domain Integer Ring - """ if self.base_ring() == self.coordinate_ring(): return self.ambient_module() @@ -7049,10 +7025,10 @@ def echelon_coordinates(self, v, check=True): INPUT: - - ``v`` -- vector + - ``v`` -- vector - - ``check`` -- boolean (default: ``True``); if ``True``, also - verify that `v` is really in ``self``. + - ``check`` -- boolean (default: ``True``); if ``True``, also + verify that `v` is really in ``self`` OUTPUT: list @@ -7063,7 +7039,7 @@ def echelon_coordinates(self, v, check=True): \sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -7164,10 +7140,10 @@ def user_to_echelon_matrix(self): def echelon_to_user_matrix(self): """ Return matrix that transforms the echelon basis to the user basis - of self. This is a matrix `A` such that if `v` is a + of ``self``. This is a matrix `A` such that if `v` is a vector written with respect to the echelon basis for ``self`` then `vA` is that vector written with respect to the user basis - of self. + of ``self``. EXAMPLES:: @@ -7183,7 +7159,7 @@ def echelon_to_user_matrix(self): [ 4/3 -1/3] The vector `(1,1,1)` has coordinates `v=(1,1)` with - respect to the echelonized basis for self. Multiplying `vA` + respect to the echelonized basis for ``self``. Multiplying `vA` we find the coordinates of this vector with respect to the user basis. @@ -7205,10 +7181,10 @@ def echelon_to_user_matrix(self): def _user_to_rref_matrix(self): """ - Returns a transformation matrix from the user specified basis to row + Return a transformation matrix from the user specified basis to row reduced echelon form, for this module over a PID. - Note: For internal use only! See user_to_echelon_matrix. + Note: For internal use only! See ``user_to_echelon_matrix``. EXAMPLES:: @@ -7237,10 +7213,10 @@ def _user_to_rref_matrix(self): def _rref_to_user_matrix(self): """ - Returns a transformation matrix from row reduced echelon form to + Return a transformation matrix from row reduced echelon form to the user specified basis, for this module over a PID. - Note: For internal use only! See user_to_echelon_matrix. + Note: For internal use only! See ``user_to_echelon_matrix``. EXAMPLES:: @@ -7266,7 +7242,7 @@ def _rref_to_user_matrix(self): def _echelon_to_rref_matrix(self): """ - Returns a transformation matrix from the some matrix to the row + Return a transformation matrix from the some matrix to the row reduced echelon form for this module over a PID. Note: For internal use only! and not used! @@ -7301,7 +7277,7 @@ def _echelon_to_rref_matrix(self): def _rref_to_echelon_matrix(self): """ - Returns a transformation matrix from row reduced echelon form to + Return a transformation matrix from row reduced echelon form to some matrix for this module over a PID. Note: For internal use only! @@ -7434,7 +7410,7 @@ def change_ring(self, R): INPUT: - - ``R`` -- a principal ideal domain + - ``R`` -- a principal ideal domain EXAMPLES:: @@ -7495,7 +7471,7 @@ def coordinate_vector(self, v, check=True): - ``v`` -- vector - ``check`` -- boolean (default: ``True``); if ``True``, also verify that - `v` is really in ``self``. + `v` is really in ``self`` OUTPUT: list @@ -7506,7 +7482,7 @@ def coordinate_vector(self, v, check=True): \\sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -7551,19 +7527,19 @@ def echelon_coordinate_vector(self, v, check=True): INPUT: - - ``v`` -- vector + - ``v`` -- vector - - ``check`` -- boolean (default: ``True``); if ``True``, also - verify that `v` is really in ``self``. + - ``check`` -- boolean (default: ``True``); if ``True``, also + verify that `v` is really in ``self`` Returns a list `c` such that if `B` is the echelonized basis - for self, then + for ``self``, then .. MATH:: \\sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -7671,7 +7647,7 @@ def __init__(self, ambient, gens, check=True, already_echelonized=False, def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -7707,7 +7683,7 @@ def coordinate_vector(self, v, check=True): - ``v`` -- vector - ``check`` -- boolean (default: ``True``); if ``True``, also verify that - `v` is really in ``self``. + `v` is really in ``self`` OUTPUT: list @@ -7718,7 +7694,7 @@ def coordinate_vector(self, v, check=True): \\sum c_i B_i = v. - If `v` is not in self, raise an :class:`ArithmeticError` exception. + If `v` is not in self, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -7829,7 +7805,7 @@ def __init__(self, ambient, basis, check=True, def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -8030,7 +8006,7 @@ def __init__(self, ambient, gens, check=True, already_echelonized=False, categor def _repr_(self) -> str: """ - The default printing representation of self. + The default printing representation of ``self``. EXAMPLES:: @@ -8109,10 +8085,10 @@ def echelon_coordinates(self, v, check=True): INPUT: - - ``v`` -- vector + - ``v`` -- vector - - ``check`` -- boolean (default: ``True``); if ``True``, also - verify that `v` is really in ``self`` + - ``check`` -- boolean (default: ``True``); if ``True``, also + verify that `v` is really in ``self`` OUTPUT: list @@ -8123,7 +8099,7 @@ def echelon_coordinates(self, v, check=True): \\sum c_i B_i = v. - If `v` is not in ``self``, raise an :class:`ArithmeticError` exception. + If `v` is not in ``self``, raise an :exc:`ArithmeticError` exception. EXAMPLES:: @@ -8186,7 +8162,7 @@ def coordinate_vector(self, v, check=True): \\sum c_i B_i = v. - If `v` is not in ``self``, raise an :class:`ArithmeticError` exception. + If `v` is not in ``self``, raise an :exc:`ArithmeticError` exception. EXAMPLES:: diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index d71d22ac1f7..3f397404988 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -178,14 +178,14 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): INPUT: - - ``object`` -- a list, dictionary, or other + - ``object`` -- list, dictionary, or other iterable containing the entries of the vector, including any object that is palatable to the ``Sequence`` constructor - ``ring`` -- a base ring (or field) for the vector space or free module, which contains all of the elements - - ``degree`` -- an integer specifying the number of + - ``degree`` -- integer specifying the number of entries in the vector or free module element - ``sparse`` -- boolean, whether the result should be a sparse vector @@ -486,6 +486,16 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: vector(S, 3) # needs sage.rings.finite_rings ... (0, 0, 0) + + We check that ``sparse`` is respected for numpy arrays:: + + sage: # needs numpy + sage: import numpy + sage: a = numpy.array([1,2,3], dtype=numpy.float64) + sage: v = vector(a, sparse=True); v + (1.0, 2.0, 3.0) + sage: v.is_sparse() + True """ from sage.modules.free_module import FreeModule # We first efficiently handle the important special case of the zero vector @@ -555,11 +565,15 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): R = None try: + import numpy from numpy import ndarray + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") + except ImportError: pass else: - if isinstance(v, ndarray): + if isinstance(v, ndarray) and not sparse: if len(v.shape) != 1: raise TypeError("cannot convert %r-dimensional array to a vector" % len(v.shape)) from sage.modules.free_module import VectorSpace @@ -606,20 +620,18 @@ free_module_element = vector def prepare(v, R, degree=None): r""" - Converts an object describing elements of a vector into a list of entries in a common ring. + Convert an object describing elements of a vector into a list of entries in a common ring. INPUT: - - ``v`` -- a dictionary with non-negative integers as keys, + - ``v`` -- dictionary with nonnegative integers as keys, or a list or other object that can be converted by the ``Sequence`` constructor - ``R`` -- a ring containing all the entries, possibly given as ``None`` - - ``degree`` -- a requested size for the list when the input is a dictionary, + - ``degree`` -- a requested size for the list when the input is a dictionary, otherwise ignored - OUTPUT: - - A pair. + OUTPUT: a pair The first item is a list of the values specified in the object ``v``. If the object is a dictionary , entries are placed in the list @@ -637,7 +649,6 @@ def prepare(v, R, degree=None): has no elements and ``R`` is ``None``, the ring returned is the integers. - EXAMPLES:: sage: from sage.modules.free_module_element import prepare @@ -702,7 +713,7 @@ def prepare(v, R, degree=None): def zero_vector(arg0, arg1=None): r""" - Returns a vector or free module element with a specified number of zeros. + Return a vector or free module element with a specified number of zeros. CALL FORMATS: @@ -715,7 +726,7 @@ def zero_vector(arg0, arg1=None): - ``degree`` -- the number of zero entries in the vector or free module element - - ``ring`` -- (default: ``ZZ``); the base ring of the vector + - ``ring`` -- (default: ``ZZ``) the base ring of the vector space or module containing the constructed zero vector OUTPUT: @@ -780,14 +791,14 @@ def zero_vector(arg0, arg1=None): def random_vector(ring, degree=None, *args, **kwds): r""" - Returns a vector (or module element) with random entries. + Return a vector (or module element) with random entries. INPUT: - - ring -- (default: ``ZZ``); the base ring for the entries - - degree -- a non-negative integer for the number of entries in the vector - - sparse -- (default: ``False``); whether to use a sparse implementation - - args, kwds -- additional arguments and keywords are passed + - ``ring`` -- (default: ``ZZ``) the base ring for the entries + - ``degree`` -- nonnegative integer for the number of entries in the vector + - ``sparse`` -- (default: ``False``) whether to use a sparse implementation + - ``*args``, ``**kwds`` -- additional arguments and keywords are passed to the ``random_element()`` method of the ring OUTPUT: @@ -886,13 +897,13 @@ def random_vector(ring, degree=None, *args, **kwds): sage: from sage.misc.randstate import current_randstate sage: seed = current_randstate().seed() sage: set_random_seed(seed) - sage: v1 = random_vector(ZZ, 20, distribution="1/n") + sage: v1 = random_vector(ZZ, 20, distribution='1/n') sage: v2 = random_vector(ZZ, 15, x=-1000, y=1000) sage: v3 = random_vector(QQ, 10) sage: v4 = random_vector(FiniteField(17), 10) sage: v5 = random_vector(RR, 10) sage: set_random_seed(seed) - sage: w1 = vector(ZZ.random_element(distribution="1/n") for _ in range(20)) + sage: w1 = vector(ZZ.random_element(distribution='1/n') for _ in range(20)) sage: w2 = vector(ZZ.random_element(x=-1000, y=1000) for _ in range(15)) sage: w3 = vector(QQ.random_element() for _ in range(10)) sage: [v1, v2, v3] == [w1, w2, w3] @@ -919,7 +930,7 @@ def random_vector(ring, degree=None, *args, **kwds): sage: random_vector(ZZ, -9) Traceback (most recent call last): ... - ValueError: degree of a random vector must be non-negative, not -9 + ValueError: degree of a random vector must be nonnegative, not -9 """ if isinstance(ring, (Integer, int)): if degree is not None: @@ -931,7 +942,7 @@ def random_vector(ring, degree=None, *args, **kwds): if not isinstance(degree, (Integer, int)): raise TypeError("degree of a random vector must be an integer, not %s" % degree) if degree < 0: - raise ValueError("degree of a random vector must be non-negative, not %s" % degree) + raise ValueError("degree of a random vector must be nonnegative, not %s" % degree) if ring not in Rings(): raise TypeError("elements of a vector, or module element, must come from a ring, not %s" % ring) if not hasattr(ring, "random_element"): @@ -966,10 +977,10 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally - represented by a dictionary ``d``, then make a copy of ``d``; - if ``False``, then this can cause undesired behavior by - mutating ``d`` + - ``copy`` -- boolean (default: ``True``); if ``self`` is internally + represented by a dictionary ``d``, then make a copy of ``d``. + If ``False``, then this can cause undesired behavior by + mutating ``d``. EXAMPLES:: @@ -1006,20 +1017,20 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(ZZ, 4, range(4)) - sage: giac(v) + v # needs sage.libs.giac + sage: giac(v) + v # needs giac [0,2,4,6] :: sage: v = vector(QQ, 3, [2/3, 0, 5/4]) - sage: giac(v) # needs sage.libs.giac + sage: giac(v) # needs giac [2/3,0,5/4] :: sage: P. = ZZ[] sage: v = vector(P, 3, [x^2 + 2, 2*x + 1, -2*x^2 + 4*x]) - sage: giac(v) # needs sage.libs.giac + sage: giac(v) # needs giac [sageVARx^2+2,2*sageVARx+1,-2*sageVARx^2+4*sageVARx] """ return self.list() @@ -1028,9 +1039,7 @@ cdef class FreeModuleElement(Vector): # abstract base class """ Convert ``self`` to a PARI vector. - OUTPUT: - - A PARI ``gen`` of type ``t_VEC``. + OUTPUT: a PARI ``gen`` of type ``t_VEC`` EXAMPLES:: @@ -1054,9 +1063,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Give a string which, when evaluated in GP, gives a PARI representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1067,7 +1074,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Create the multiplication table of `GF(4)` using GP:: sage: # needs sage.libs.pari - sage: k. = GF(4, impl="pari_ffelt") + sage: k. = GF(4, impl='pari_ffelt') sage: v = gp(vector(list(k))) sage: v [0, 1, a, a + 1] @@ -1081,7 +1088,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def _magma_init_(self, magma): r""" - Convert self to Magma. + Convert ``self`` to Magma. EXAMPLES:: @@ -1127,7 +1134,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def numpy(self, dtype=object): """ - Convert self to a numpy array. + Convert ``self`` to a numpy array. INPUT: @@ -1188,7 +1195,11 @@ cdef class FreeModuleElement(Vector): # abstract base class over Rational Field to numpy array of type <... 'float'>: setting an array element with a sequence. """ + import numpy from numpy import array + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") + try: return array(self, dtype=dtype) except ValueError as e: @@ -1216,7 +1227,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def _vector_(self, R=None): r""" - Return self as a vector. + Return ``self`` as a vector. EXAMPLES:: @@ -1647,7 +1658,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def additive_order(self): """ - Return the additive order of self. + Return the additive order of ``self``. EXAMPLES:: @@ -1724,8 +1735,8 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - - ``p`` -- default: 2 -- ``p`` can be a real number greater than 1, - infinity (``oo`` or ``Infinity``), or a symbolic expression. + - ``p`` -- (default: 2) ``p`` can be a real number greater than 1, + infinity (``oo`` or ``Infinity``), or a symbolic expression: - `p=1`: the taxicab (Manhattan) norm - `p=2`: the usual Euclidean norm (the default) @@ -1866,7 +1877,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def __getitem__(self, i): """ - Return `i`-th entry or slice of self. + Return `i`-th entry or slice of ``self``. EXAMPLES:: @@ -1898,7 +1909,7 @@ cdef class FreeModuleElement(Vector): # abstract base class cdef get_unsafe(self, Py_ssize_t i): """ - Cython function to get the `i`'th entry of this vector. + Cython function to get the `i`-th entry of this vector. Used as building block for a generic ``__getitem__``. """ @@ -1918,7 +1929,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def __setitem__(self, i, value): """ - Set the `i`-th entry or slice of self to ``value``. + Set the `i`-th entry or slice of ``self`` to ``value``. EXAMPLES:: @@ -1959,7 +1970,7 @@ cdef class FreeModuleElement(Vector): # abstract base class cdef int set_unsafe(self, Py_ssize_t i, value) except -1: """ - Cython function to set the `i`'th entry of this vector to + Cython function to set the `i`-th entry of this vector to ``value``. Used as building block for a generic ``__setitem__``. @@ -2030,12 +2041,12 @@ cdef class FreeModuleElement(Vector): # abstract base class def list(self, copy=True): """ - Return list of elements of self. + Return list of elements of ``self``. INPUT: - - copy -- bool, whether returned list is a copy that is - safe to change, is ignored. + - ``copy`` -- boolean (default: ``True``); whether returned list is a + copy that is safe to change (ignored) EXAMPLES:: @@ -2065,8 +2076,7 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - - positions -- iterable of ints - + - ``positions`` -- iterable of integers EXAMPLES:: @@ -2083,7 +2093,7 @@ cdef class FreeModuleElement(Vector): # abstract base class OUTPUT: - Return a lift of self to the covering ring of the base ring `R`, + Return a lift of ``self`` to the covering ring of the base ring `R`, which is by definition the ring returned by calling :meth:`~sage.rings.quotient_ring.QuotientRing_nc.cover_ring` on `R`, or just `R` itself if the @@ -2143,7 +2153,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def __pos__(self): """ - Always returns self, since +self == self. + Always returns ``self``, since ``+self == self``. EXAMPLES:: @@ -2157,7 +2167,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def __pow__(self, n, dummy): """ - Raises a NotImplementedError, since powering doesn't make + Raises a :exc:`NotImplementedError`, since powering doesn't make sense for vectors. EXAMPLES:: @@ -2250,7 +2260,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def denominator(self): """ Return the least common multiple of the denominators of the - entries of self. + entries of ``self``. EXAMPLES:: @@ -2296,14 +2306,12 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally - represented by a dictionary ``d``, then make a copy of ``d``; - if ``False``, then this can cause undesired behavior by - mutating ``d`` + - ``copy`` -- boolean (default: ``True``); if ``self`` is internally + represented by a dictionary ``d``, then make a copy of ``d``. + If ``False``, then this can cause undesired behavior by + mutating ``d``. - OUTPUT: - - - Python dictionary + OUTPUT: Python dictionary EXAMPLES:: @@ -2353,7 +2361,7 @@ cdef class FreeModuleElement(Vector): # abstract base class more than 3 dimensions. - ``start`` -- (default: origin in correct dimension) may be a tuple, - list, or vector. + list, or vector EXAMPLES: @@ -2490,22 +2498,21 @@ cdef class FreeModuleElement(Vector): # abstract base class r""" INPUT: - - ``xmin`` -- (default: 0) start x position to start - plotting - - - ``xmax`` -- (default: 1) stop x position to stop - plotting + - ``xmin`` -- (default: 0) start x position to start + plotting - - ``eps`` -- (default: determined by xmax) we view this - vector as defining a function at the points xmin, xmin + eps, xmin - + 2\*eps, ..., + - ``xmax`` -- (default: 1) stop x position to stop + plotting - - ``res`` -- (default: all points) total number of - points to include in the graph + - ``eps`` -- (default: determined by xmax) we view this + vector as defining a function at the points xmin, xmin + eps, xmin + + 2\*eps, ..., - - ``connect`` -- (default: ``True``) if True draws a line; - otherwise draw a list of points. + - ``res`` -- (default: all points) total number of + points to include in the graph + - ``connect`` -- boolean (default: ``True``); if ``True`` draws a line, + otherwise draw a list of points EXAMPLES:: @@ -2694,13 +2701,13 @@ cdef class FreeModuleElement(Vector): # abstract base class def cross_product(self, right): """ - Return the cross product of self and right, which is only defined + Return the cross product of ``self`` and ``right``, which is only defined for vectors of length 3 or 7. INPUT: - - ``right`` -- A vector of the same size as ``self``, either - degree three or degree seven. + - ``right`` -- a vector of the same size as ``self``, either + degree three or degree seven OUTPUT: @@ -2815,9 +2822,7 @@ cdef class FreeModuleElement(Vector): # abstract base class and also `w \cdot \hat{v} = w \times v` for all vectors `w`. The basis vectors are assumed to be orthonormal. - OUTPUT: - - The cross product matrix of this vector. + OUTPUT: the cross product matrix of this vector EXAMPLES:: @@ -2889,16 +2894,14 @@ cdef class FreeModuleElement(Vector): # abstract base class def pairwise_product(self, right): """ - Return the pairwise product of self and right, which is a vector of + Return the pairwise product of ``self`` and ``right``, which is a vector of the products of the corresponding entries. INPUT: - - - ``right`` -- vector of the same degree as self. It - need not be in the same vector space as self, as long as the - coefficients can be multiplied. - + - ``right`` -- vector of the same degree as ``self``. It + need not be in the same vector space as ``self``, as long as the + coefficients can be multiplied. EXAMPLES:: @@ -3073,7 +3076,6 @@ cdef class FreeModuleElement(Vector): # abstract base class of vector fields on Euclidean spaces (and more generally pseudo-Riemannian manifolds), in particular for computing the divergence in curvilinear coordinates. - """ if variables is None: variables = self._variables() @@ -3127,7 +3129,6 @@ cdef class FreeModuleElement(Vector): # abstract base class of vector fields on Euclidean spaces (and more generally pseudo-Riemannian manifolds), in particular for computing the curl in curvilinear coordinates. - """ if len(self) == 3: if variables is None: @@ -3153,8 +3154,8 @@ cdef class FreeModuleElement(Vector): # abstract base class def element(self): """ - Simply returns self. This is useful, since for many objects, - self.element() returns a vector corresponding to self. + Simply return ``self``. This is useful, since for many objects, + ``self.element()`` returns a vector corresponding to ``self``. EXAMPLES:: @@ -3191,7 +3192,7 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - * "p" - default: 2 - p value for the norm + - ``p`` -- (default: 2) p value for the norm EXAMPLES:: @@ -3213,7 +3214,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def conjugate(self): r""" - Returns a vector where every entry has been replaced by its complex conjugate. + Return a vector where every entry has been replaced by its complex conjugate. OUTPUT: @@ -3302,7 +3303,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def inner_product(self, right): r""" - Returns the inner product of ``self`` and ``right``, + Return the inner product of ``self`` and ``right``, possibly using an inner product matrix from the parent of ``self``. INPUT: @@ -3407,7 +3408,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def outer_product(self, right): r""" - Returns a matrix, the outer product of two vectors ``self`` and ``right``. + Return a matrix, the outer product of two vectors ``self`` and ``right``. INPUT: @@ -3525,7 +3526,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def hermitian_inner_product(self, right): r""" - Returns the dot product, but with the entries of the first vector + Return the dot product, but with the entries of the first vector conjugated beforehand. INPUT: @@ -3832,7 +3833,7 @@ cdef class FreeModuleElement(Vector): # abstract base class OUTPUT: - If self is the free module element (1,2,3,4), + If ``self`` is the free module element (1,2,3,4), then a string with the following latex is returned: "\left(1,\,2,\,3,\,4\right)" (without the quotes). The vector is enclosed in parentheses by default, @@ -3863,8 +3864,8 @@ cdef class FreeModuleElement(Vector): # abstract base class def dense_vector(self): """ - Return dense version of self. If self is dense, just return - self; otherwise, create and return correspond dense vector. + Return dense version of ``self``. If ``self`` is dense, just return + ``self``; otherwise, create and return correspond dense vector. EXAMPLES:: @@ -3882,7 +3883,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def sparse_vector(self): """ - Return sparse version of self. If self is sparse, just return + Return sparse version of ``self``. If ``self`` is sparse, just return self; otherwise, create and return correspond sparse vector. EXAMPLES:: @@ -3906,16 +3907,13 @@ cdef class FreeModuleElement(Vector): # abstract base class automatically determine the base ring of the resulting element. INPUT: - sparse -- True or False will control whether the result - is sparse. By default, the result is sparse iff self - is sparse. + - ``sparse`` -- boolean; will control whether the result is sparse. + By default, the result is sparse iff self is sparse. - - ``phi`` -- arbitrary Python function or callable - object - - - ``R`` -- (optional) ring + - ``phi`` -- arbitrary Python function or callable object + - ``R`` -- (optional) ring OUTPUT: a free module element over R @@ -3945,7 +3943,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: n.parent() # needs sage.rings.finite_rings Vector space of dimension 9 over Finite Field in a of size 3^2 - If your map sends 0 to a non-zero value, then your resulting + If your map sends 0 to a nonzero value, then your resulting vector is not mathematically sparse:: sage: v = vector([0] * 6 + [1], sparse=True); v @@ -4025,7 +4023,7 @@ cdef class FreeModuleElement(Vector): # abstract base class # OK, we have some zero entries. zero_res = phi(self.base_ring()(0)) if not zero_res.is_zero(): - # And phi maps 0 to a non-zero value. + # And phi maps 0 to a nonzero value. v = [zero_res] * self._degree for i,z in self.dict(copy=False).items(): v[i] = phi(z) @@ -4126,7 +4124,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def integral(self, *args, **kwds): """ - Returns a symbolic integral of the vector, component-wise. + Return a symbolic integral of the vector, component-wise. :meth:`integrate` is an alias of the function. @@ -4141,7 +4139,6 @@ cdef class FreeModuleElement(Vector): # abstract base class (1/2*t^2, 1/3*t^3, -cos(t)) sage: r.integrate(t, 0, 1) (1/2, 1/3, -cos(1) + 1) - """ from sage.misc.functional import integral return self.apply_map(lambda x: integral(x,*args, **kwds)) @@ -4150,7 +4147,7 @@ cdef class FreeModuleElement(Vector): # abstract base class def nintegral(self, *args, **kwds): """ - Returns a numeric integral of the vector, component-wise, and + Return a numeric integral of the vector, component-wise, and the result of the nintegral command on each component of the input. @@ -4177,7 +4174,6 @@ cdef class FreeModuleElement(Vector): # abstract base class ((0.5, 0.0, 1.0), {0: (0.5, 5.55111512312578...e-15, 21, 0), 2: (1.0, 1.11022302462515...e-14, 21, 0)}) - """ # If Cython supported lambda functions, we would just do # return self.apply_map(lambda x: x.nintegral(*args, **kwds) for x in self) @@ -4365,8 +4361,7 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): INPUT: - - ``v`` -- a list which is used as the new entries (without - copying) + - ``v`` -- list which is used as the new entries (without copying) """ cdef type t = type(self) cdef FreeModuleElement_generic_dense x = t.__new__(t) @@ -4651,11 +4646,11 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): def list(self, copy=True): """ - Return list of elements of self. + Return list of elements of ``self``. INPUT: - - copy -- bool, return list of underlying entries + - ``copy`` -- boolean; return list of underlying entries EXAMPLES:: @@ -4816,7 +4811,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): INPUT: - - ``v`` -- a dict which is used as the new entries (without + - ``v`` -- dictionary which is used as the new entries (without copying) """ cdef type t = type(self) @@ -5301,7 +5296,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): def denominator(self): """ Return the least common multiple of the denominators of the - entries of self. + entries of ``self``. EXAMPLES:: @@ -5330,14 +5325,12 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally - represented by a dictionary ``d``, then make a copy of ``d``; - if ``False``, then this can cause undesired behavior by - mutating ``d`` - - OUTPUT: + - ``copy`` -- boolean (default: ``True``); if ``self`` is internally + represented by a dictionary ``d``, then make a copy of ``d``. + If ``False``, then this can cause undesired behavior by + mutating ``d``. - - Python dictionary + OUTPUT: Python dictionary EXAMPLES:: @@ -5383,7 +5376,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): def nonzero_positions(self): """ - Returns the list of numbers ``i`` such that ``self[i] != 0``. + Return the list of numbers ``i`` such that ``self[i] != 0``. EXAMPLES:: @@ -5398,7 +5391,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): cpdef int hamming_weight(self) noexcept: """ - Returns the number of positions ``i`` such that ``self[i] != 0``. + Return the number of positions ``i`` such that ``self[i] != 0``. EXAMPLES:: diff --git a/src/sage/modules/free_module_homspace.py b/src/sage/modules/free_module_homspace.py index 8fb97a48e5a..fc87d7f83f6 100644 --- a/src/sage/modules/free_module_homspace.py +++ b/src/sage/modules/free_module_homspace.py @@ -134,11 +134,11 @@ def __call__(self, A, **kwds): r""" INPUT: - - A -- either a matrix or a list/tuple of images of generators, - or a function returning elements of the codomain for elements of the domain. - - check -- bool (default: ``True``) - - the keyword ``side`` can be assigned the values ``"left"`` or - ``"right"``. It corresponds to the side of vectors relative to the matrix. + - ``A`` -- either a matrix or a list/tuple of images of generators, + or a function returning elements of the codomain for elements of the domain + - ``check`` -- boolean (default: ``True``) + - the keyword ``side`` can be assigned the values ``'left'`` or + ``'right'``. It corresponds to the side of vectors relative to the matrix. If A is a matrix, then it is the matrix of this linear transformation, with respect to the basis for the domain and @@ -227,11 +227,12 @@ def __call__(self, A, **kwds): return free_module_morphism.FreeModuleMorphism(self, A, side) @cached_method - def zero(self, side="left"): + def zero(self, side='left'): """ INPUT: - - side -- side of the vectors acted on by the matrix (default: ``left``) + - ``side`` -- side of the vectors acted on by the matrix + (default: ``'left'``) EXAMPLES:: @@ -272,18 +273,17 @@ def zero(self, side="left"): return self(lambda x: self.codomain().zero(), side=side) @cached_method - def _matrix_space(self, side="left"): + def _matrix_space(self, side='left'): """ INPUT: - - side -- side of the vectors acted on by the matrix (default: ``left``) + - ``side`` -- side of the vectors acted on by the matrix + (default: ``'left'``) Return underlying matrix space that contains the matrices that define the homomorphisms in this free module homspace. - OUTPUT: - - - matrix space + OUTPUT: matrix space EXAMPLES:: @@ -300,17 +300,16 @@ def _matrix_space(self, side="left"): return MatrixSpace(R, self.codomain().rank(), self.domain().rank()) @cached_method - def basis(self, side="left"): + def basis(self, side='left'): """ Return a basis for this space of free module homomorphisms. INPUT: - - side -- side of the vectors acted on by the matrix (default: ``left``) - - OUTPUT: + - ``side`` -- side of the vectors acted on by the matrix + (default: ``'left'``) - - tuple + OUTPUT: tuple EXAMPLES:: @@ -340,13 +339,14 @@ def basis(self, side="left"): B = M.basis() return tuple([self(x, side=side) for x in B]) - def identity(self, side="left"): + def identity(self, side='left'): r""" Return identity morphism in an endomorphism ring. INPUT: - - side -- side of the vectors acted on by the matrix (default: ``left``) + - ``side`` -- side of the vectors acted on by the matrix + (default: ``'left'``) EXAMPLES:: diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 5bc9f1a3836..6e4171113e5 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -32,6 +32,7 @@ ############################################################################## from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.modules.free_module import FreeModule_submodule_with_basis_pid, FreeModule_ambient_pid @@ -57,8 +58,8 @@ def IntegerLattice(basis, lll_reduce=True): - an element of an absolute order - - ``lll_reduce`` -- (default: ``True``) run LLL reduction on the basis - on construction. + - ``lll_reduce`` -- boolean (default: ``True``); run LLL reduction on the basis + on construction EXAMPLES: @@ -171,7 +172,6 @@ def IntegerLattice(basis, lll_reduce=True): [ 0 0 0 0 0 1048576 0 0] [ 0 0 0 0 0 0 1048576 0] [ 0 0 0 0 0 0 0 1048576] - """ if isinstance(basis, OrderElement_absolute): @@ -218,7 +218,6 @@ class FreeModule_submodule_with_basis_integer(FreeModule_submodule_with_basis_pi [ 2 -1 1 2 -3 2 2 1 0 1] sage: L.shortest_vector() (-1, 1, 2, -2, 0, 1, 0, -1, 2, 1) - """ def __init__(self, ambient, basis, check=True, echelonize=False, echelonized_basis=None, already_echelonized=False, @@ -233,21 +232,21 @@ def __init__(self, ambient, basis, check=True, echelonize=False, - ``basis`` -- either a list of vectors or a matrix over the integers - - ``check`` -- (default: ``True``) if ``False``, correctness of - the input will not be checked and type conversion may be omitted, + - ``check`` -- boolean (default: ``True``); if ``False``, correctness + of the input will not be checked and type conversion may be omitted, use with care - - ``echelonize`` -- (default:``False``) if ``True``, ``basis`` will be + - ``echelonize`` -- (default: ``False``) if ``True``, ``basis`` will be echelonized and the result will be used as the default basis of the constructed submodule - - `` echelonized_basis`` -- (default: ``None``) if not ``None``, must + - ``echelonized_basis`` -- (default: ``None``) if not ``None``, must be the echelonized basis spanning the same submodule as ``basis`` - - ``already_echelonized`` -- (default: ``False``) if ``True``, + - ``already_echelonized`` -- boolean (default: ``False``); if ``True``, ``basis`` must be already given in the echelonized form - - ``lll_reduce`` -- (default: ``True``) run LLL reduction on the basis + - ``lll_reduce`` -- boolean (default: ``True``); run LLL reduction on the basis on construction EXAMPLES:: @@ -281,7 +280,6 @@ def __init__(self, ambient, basis, check=True, echelonize=False, [ 0 -1 1 -4 1 -1 1 0] [ 2 0 -3 -1 0 -3 0 0] [-1 0 -1 0 -3 -3 0 0] - """ basis = matrix(ZZ, basis) self._basis_is_LLL_reduced = False @@ -357,9 +355,7 @@ def LLL(self, *args, **kwds): - ``**kwds`` -- passed through to :meth:`sage.matrix.matrix_integer_dense.Matrix_integer_dense.LLL` - OUTPUT: - - An integer matrix which is an LLL-reduced basis for this lattice. + OUTPUT: integer matrix which is an LLL-reduced basis for this lattice EXAMPLES:: @@ -384,7 +380,10 @@ def LLL(self, *args, **kwds): basis = matrix(ZZ, len(basis), len(basis[0]), basis) basis.set_immutable() - if self.reduced_basis[0].norm() > basis[0].norm(): + b0 = basis[0] + rb0 = self.reduced_basis[0] + + if rb0.dot_product(rb0) > b0.dot_product(b0): self._reduced_basis = basis return basis @@ -400,9 +399,7 @@ def BKZ(self, *args, **kwds): - ``*kwds`` -- passed through to :meth:`sage.matrix.matrix_integer_dense.Matrix_integer_dense.BKZ` - OUTPUT: - - An integer matrix which is a BKZ-reduced basis for this lattice. + OUTPUT: integer matrix which is a BKZ-reduced basis for this lattice EXAMPLES:: @@ -463,9 +460,7 @@ def HKZ(self, *args, **kwds): - ``*kwds`` -- passed through to :meth:`BKZ` - OUTPUT: - - An integer matrix which is a HKZ-reduced basis for this lattice. + OUTPUT: integer matrix which is a HKZ-reduced basis for this lattice EXAMPLES:: @@ -484,9 +479,7 @@ def volume(self): r""" Return `vol(L)` which is `\sqrt{\det(B \cdot B^T)}` for any basis `B`. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -505,9 +498,7 @@ def discriminant(self): Return `|\det(G)|`, i.e. the absolute value of the determinant of the Gram matrix `B \cdot B^T` for any basis `B`. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -522,9 +513,7 @@ def is_unimodular(self): """ Return ``True`` if this lattice is unimodular. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -538,25 +527,23 @@ def is_unimodular(self): return self.volume() == 1 @cached_method - def shortest_vector(self, update_reduced_basis=True, algorithm="fplll", *args, **kwds): + def shortest_vector(self, update_reduced_basis=True, algorithm='fplll', *args, **kwds): r""" Return a shortest vector. INPUT: - - ``update_reduced_basis`` -- (default: ``True``) set this flag if - the found vector should be used to improve the basis + - ``update_reduced_basis`` -- boolean (default: ``True``); set this + flag if the found vector should be used to improve the basis - - ``algorithm`` -- (default: ``"fplll"``) either ``"fplll"`` or - ``"pari"`` + - ``algorithm`` -- (default: ``'fplll'``) either ``'fplll'`` or + ``'pari'`` - ``*args`` -- passed through to underlying implementation - ``**kwds`` -- passed through to underlying implementation - OUTPUT: - - A shortest non-zero vector for this lattice. + OUTPUT: a shortest nonzero vector for this lattice EXAMPLES:: @@ -573,11 +560,11 @@ def shortest_vector(self, update_reduced_basis=True, algorithm="fplll", *args, * sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.symbolic 6.03890756700000e10 - sage: L.shortest_vector(algorithm="pari").norm().n() # needs sage.symbolic + sage: L.shortest_vector(algorithm='pari').norm().n() # needs sage.symbolic 3.74165738677394 sage: L = IntegerLattice(A, lll_reduce=True) - sage: L.shortest_vector(algorithm="pari").norm().n() # needs sage.symbolic + sage: L.shortest_vector(algorithm='pari').norm().n() # needs sage.symbolic 3.74165738677394 """ if algorithm == "pari": @@ -611,9 +598,7 @@ def update_reduced_basis(self, w): - ``w`` -- a vector - OUTPUT: - - Nothing is returned but the internal state is modified. + OUTPUT: nothing is returned but the internal state is modified EXAMPLES:: @@ -641,9 +626,7 @@ def voronoi_cell(self, radius=None): - ``radius`` -- (default: automatic determination) radius of ball containing considered vertices - OUTPUT: - - The Voronoi cell as a Polyhedron instance. + OUTPUT: the Voronoi cell as a Polyhedron instance The result is cached so that subsequent calls to this function return instantly. @@ -702,9 +685,7 @@ def voronoi_relevant_vectors(self): """ Compute the embedded vectors inducing the Voronoi cell. - OUTPUT: - - The list of Voronoi relevant vectors. + OUTPUT: the list of Voronoi relevant vectors EXAMPLES:: @@ -744,9 +725,7 @@ def closest_vector(self, t): - ``t`` -- the target vector to compute the closest vector to - OUTPUT: - - The vector in the lattice closest to ``t``. + OUTPUT: the vector in the lattice closest to ``t`` EXAMPLES:: @@ -806,16 +785,11 @@ def CVPP_2V(t, V, voronoi_cell): i -= 1 return t - t_new - def approximate_closest_vector(self, t, delta=None, *args, **kwargs): + def approximate_closest_vector(self, t, delta=None, algorithm='embedding', *args, **kwargs): r""" - Compute a vector `w` such that - - .. MATH:: - - |t-w|<(\frac{1}{\delta-\frac{1}{4}})^{d/2}|t-u| - - where `u` is the closest lattice point to `t`, `\delta` is the LLL - reduction parameter, and `d` is the dimension of the lattice. + Compute a vector `w` in this lattice which is close to the target vector `t`. + The ratio `\frac{|t-w|}{|t-u|}`, where `u` is the closest lattice vector to `t`, + is exponential in the dimension of the lattice. This will check whether the basis is already `\delta`-LLL-reduced and otherwise it will run LLL to make sure that it is. For more @@ -827,13 +801,23 @@ def approximate_closest_vector(self, t, delta=None, *args, **kwargs): - ``delta`` -- (default: ``0.99``) the LLL reduction parameter + - ``algorithm`` -- string (default: 'embedding'): + + - ``'embedding'`` -- embeds the lattice in a d+1 dimensional space + and seeks short vectors using LLL. This calls LLL twice but is + usually still quick. + + - ``'nearest_plane'`` -- uses the "NEAREST PLANE" algorithm from [Bab86]_ + + - ``'rounding_off'`` -- uses the "ROUNDING OFF" algorithm from [Bab86]_. + This yields slightly worse results than the other algorithms but is + at least faster than ``'nearest_plane'``. + - ``*args`` -- passed through to :meth:`LLL` - ``**kwds`` -- passed through to :meth:`LLL` - OUTPUT: - - The vector `w` described above. + OUTPUT: the vector `w` described above EXAMPLES:: @@ -849,30 +833,62 @@ def approximate_closest_vector(self, t, delta=None, *args, **kwargs): ....: [0, 0, 101, 0], [-28, 39, 45, 1]], lll_reduce=False) sage: t = vector([1337]*4) sage: L.approximate_closest_vector(t, delta=0.26) - (1348, 1340, 1383, 1337) + (1331, 1324, 1349, 1334) sage: L.approximate_closest_vector(t, delta=0.99) (1326, 1349, 1339, 1345) sage: L.closest_vector(t) (1326, 1349, 1339, 1345) - ALGORITHM: - - Uses the algorithm from [Bab86]_. + sage: # Checking that the other algorithms work + sage: L.approximate_closest_vector(t, algorithm='nearest_plane') + (1326, 1349, 1339, 1345) + sage: L.approximate_closest_vector(t, algorithm='rounding_off') + (1331, 1324, 1349, 1334) """ if delta is None: delta = ZZ(99)/ZZ(100) - # bound checks on delta are performed in is_LLL_reduced + # Bound checks on delta are performed in is_LLL_reduced if not self._reduced_basis.is_LLL_reduced(delta=delta): self.LLL(*args, delta=delta, **kwargs) B = self._reduced_basis - G = B.gram_schmidt()[0] t = vector(t) - b = t - for i in reversed(range(G.nrows())): - b -= B[i] * ((b * G[i]) / (G[i] * G[i])).round("even") - return (t - b).change_ring(ZZ) + if algorithm == 'embedding': + L = matrix(QQ, B.nrows()+1, B.ncols()+1) + L.set_block(0, 0, B) + L.set_block(B.nrows(), 0, matrix(t)) + weight = (B[-1]*B[-1]).isqrt()+1 # Norm of the largest vector + L[-1, -1] = weight + + # The vector should be the last row but we iterate just in case + for v in reversed(L.LLL(delta=delta, *args, **kwargs).rows()): + if abs(v[-1]) == weight: + return t - v[:-1]*v[-1].sign() + raise ValueError('No suitable vector found in basis.' + 'This is a bug, please report it.') + + elif algorithm == 'nearest_plane': + G = B.gram_schmidt()[0] + + b = t + for i in reversed(range(G.nrows())): + b -= B[i] * ((b * G[i]) / (G[i] * G[i])).round("even") + return (t - b).change_ring(ZZ) + + elif algorithm == 'rounding_off': + # t = x*B might not have a solution over QQ so we instead solve + # the system x*B*B^T = t*B^T which will be the "closest" solution + # if it does not exist, same effect as using the psuedo-inverse + sol = (B*B.T).solve_left(t*B.T) + return vector(ZZ, [QQ(x).round('even') for x in sol])*B - babai = approximate_closest_vector \ No newline at end of file + else: + raise ValueError("algorithm must be one of 'embedding', 'nearest_plane' or 'rounding_off'") + + def babai(self, *args, **kwargs): + """ + Alias for :meth:`approximate_closest_vector`. + """ + return self.approximate_closest_vector(*args, **kwargs) diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index 7cbfe0f7281..efdbc607c09 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -73,15 +73,15 @@ def is_FreeModuleMorphism(x): class FreeModuleMorphism(matrix_morphism.MatrixMorphism): - def __init__(self, parent, A, side="left"): + def __init__(self, parent, A, side='left'): """ INPUT: - - ``parent`` -- a homspace in a (sub) category of free modules + - ``parent`` -- a homspace in a (sub) category of free modules - - ``A`` -- matrix + - ``A`` -- matrix - - side -- side of the vectors acted on by the matrix (default: ``"left"``) + - ``side`` -- side of the vectors acted on by the matrix (default: ``'left'``) EXAMPLES:: @@ -181,7 +181,7 @@ def _repr_(self): [1 0 0] Domain: Ambient free module of rank 3 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring - sage: h2 = V.hom([V.1, V.2, V.0], side="right"); h2 + sage: h2 = V.hom([V.1, V.2, V.0], side='right'); h2 Free module morphism defined as left-multiplication by the matrix [0 0 1] [1 0 0] @@ -248,7 +248,7 @@ def inverse_image(self, V): """ Given a submodule V of the codomain of self, return the inverse image of V under self, i.e., the biggest submodule of - the domain of self that maps into V. + the domain of ``self`` that maps into V. EXAMPLES: @@ -320,7 +320,7 @@ def inverse_image(self, V): sage: V = ZZ^2 sage: m = matrix(2, [1, 1, 0, 1]) - sage: h = V.hom(m, side="right") + sage: h = V.hom(m, side='right') sage: h Free module morphism defined as left-multiplication by the matrix [1 1] @@ -453,7 +453,7 @@ def lift(self, x): :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").lift(V.0 + V.1) + sage: V.hom(m, side='right').lift(V.0 + V.1) (0, 1) sage: V.hom(m).lift(V.0 + V.1) (1, 0) @@ -488,12 +488,12 @@ def lift(self, x): def eigenvalues(self, extend=True): r""" - Returns a list with the eigenvalues of the endomorphism of vector spaces. + Return a list with the eigenvalues of the endomorphism of vector spaces. INPUT: - - ``extend`` -- boolean (default: ``True``) decides if base field - extensions should be considered or not. + - ``extend`` -- boolean (default: ``True``); decides if base field + extensions should be considered or not EXAMPLES: @@ -523,12 +523,12 @@ def eigenvalues(self, extend=True): def eigenvectors(self, extend=True): """ - Computes the subspace of eigenvectors of a given eigenvalue. + Compute the subspace of eigenvectors of a given eigenvalue. INPUT: - - ``extend`` -- boolean (default: ``True``) decides if base field - extensions should be considered or not. + - ``extend`` -- boolean (default: ``True``); decides if base field + extensions should be considered or not OUTPUT: @@ -559,7 +559,7 @@ def eigenvectors(self, extend=True): sage: V = QQ^2 sage: m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenvectors() # needs sage.rings.number_field + sage: V.hom(m, side='right').eigenvectors() # needs sage.rings.number_field [(1, [ (1, 0) ], 2)] sage: V.hom(m).eigenvectors() # needs sage.rings.number_field [(1, [ (0, 1) ], 2)] @@ -587,12 +587,10 @@ def eigenspaces(self, extend=True): INPUT: - - ``extend`` -- (default: ``True``) determines if field + - ``extend`` -- boolean (default: ``True``); determines if field extensions should be considered - OUTPUT: - - - a list of pairs ``(eigenvalue, eigenspace)`` + OUTPUT: a list of pairs ``(eigenvalue, eigenspace)`` EXAMPLES:: @@ -634,7 +632,7 @@ def eigenspaces(self, extend=True): :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenspaces() # needs sage.rings.number_field + sage: V.hom(m, side='right').eigenspaces() # needs sage.rings.number_field [(1, Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [1 0])] @@ -712,12 +710,12 @@ def _richcmp_(self, other, op): class BaseIsomorphism1D_to_FM(BaseIsomorphism1D): """ - An isomorphism from a ring to its 1-dimensional free module + An isomorphism from a ring to its 1-dimensional free module. INPUT: - ``parent`` -- the homset - - ``basis`` -- (default 1) an invertible element of the ring + - ``basis`` -- (default: 1) an invertible element of the ring EXAMPLES:: @@ -769,12 +767,12 @@ def _call_(self, x): class BaseIsomorphism1D_from_FM(BaseIsomorphism1D): """ - An isomorphism to a ring from its 1-dimensional free module + An isomorphism to a ring from its 1-dimensional free module. INPUT: - ``parent`` -- the homset - - ``basis`` -- (default 1) an invertible element of the ring + - ``basis`` -- (default: 1) an invertible element of the ring EXAMPLES:: diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index da54426e9c9..a209ae79ee4 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -91,13 +91,13 @@ def FreeQuadraticModule(base_ring, rank, inner_product_matrix, - ``base_ring`` -- a commutative ring - - ``rank`` -- a nonnegative integer + - ``rank`` -- nonnegative integer - ``inner_product_matrix`` -- the inner product matrix - - ``sparse`` -- bool; (default ``False``) + - ``sparse`` -- boolean (default: ``False``) - - ``inner_product_ring`` -- the inner product codomain ring; (default ``None``) + - ``inner_product_ring`` -- the inner product codomain ring (default: ``None``) OUTPUT: @@ -209,7 +209,7 @@ def QuadraticSpace(K, dimension, inner_product_matrix, sparse=False): (0, 0, 1) ] - The base must be a field or a :class:`TypeError` is raised:: + The base must be a field or a :exc:`TypeError` is raised:: sage: QuadraticSpace(ZZ, 5, identity_matrix(ZZ,2)) Traceback (most recent call last): @@ -318,7 +318,7 @@ def __init__(self, base_ring, rank, degree, inner_product_matrix, sparse=False): - ``base_ring`` -- a commutative ring - - ``rank`` -- a non-negative integer + - ``rank`` -- nonnegative integer EXAMPLES:: @@ -739,10 +739,10 @@ def span(self, gens, check=True, already_echelonized=False): - ``gens`` -- list of vectors - - ``check`` -- bool (default: ``True``): whether or not to coerce + - ``check`` -- boolean (default: ``True``); whether or not to coerce entries of gens into base field - - ``already_echelonized`` -- bool (default: ``False``): set this if + - ``already_echelonized`` -- boolean (default: ``False``); set this if you know the gens are already in echelon form EXAMPLES:: @@ -779,10 +779,10 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): - ``basis`` -- list of vectors - - ``check`` -- bool (default: ``True``): whether or not to coerce + - ``check`` -- boolean (default: ``True``); whether or not to coerce entries of gens into base field - - ``already_echelonized`` -- bool (default: ``False``): set this if + - ``already_echelonized`` -- boolean (default: ``False``); set this if you know the gens are already in echelon form EXAMPLES:: @@ -799,7 +799,7 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): [3 3 0] The basis vectors must be linearly independent or a - :class:`ValueError` exception is raised:: + :exc:`ValueError` exception is raised:: sage: W.span_of_basis([[2,2,2], [3,3,3]]) Traceback (most recent call last): @@ -831,7 +831,7 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): - ``base_ring`` -- a commutative ring - - ``rank`` -- a non-negative integer + - ``rank`` -- nonnegative integer EXAMPLES:: @@ -1047,11 +1047,11 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): - ``base_ring`` -- a principal ideal domain - - ``rank`` -- a non-negative integer + - ``rank`` -- nonnegative integer - - ``sparse`` -- bool (default: ``False``) + - ``sparse`` -- boolean (default: ``False``) - - ``inner_product_matrix`` -- bool (default: ``None``) + - ``inner_product_matrix`` -- boolean (default: ``None``) EXAMPLES:: @@ -1131,9 +1131,9 @@ def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): - ``base_field`` -- a field - - ``dimension`` -- a non-negative integer + - ``dimension`` -- nonnegative integer - - ``sparse`` -- bool (default: ``False``) + - ``sparse`` -- boolean (default: ``False``) EXAMPLES:: @@ -1349,7 +1349,7 @@ def change_ring(self, R): element of ``self`` into a vector over the fraction field of `R`, then taking the resulting `R`-module. - This raises a :class:`TypeError` if coercion is not possible. + This raises a :exc:`TypeError` if coercion is not possible. INPUT: diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index f7343dfc484..c58f0f3ea1e 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -39,6 +39,7 @@ - Simon Brandhorst (2017-09): First created - Paolo Menegatti (2018-03): Added IntegralLatticeDirectSum, IntegralLatticeGluing +- Lorenz Panny (2024): enumeration routines for short and close vectors """ # **************************************************************************** @@ -50,8 +51,9 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - +from pathlib import Path from copy import copy + from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from sage.rings.rational_field import QQ @@ -83,12 +85,12 @@ def IntegralLattice(data, basis=None): - ``data`` -- can be one of the following: * a symmetric matrix over the rationals -- the inner product matrix - * an integer -- the dimension for an Euclidean lattice + * an integer -- the dimension for a Euclidean lattice * a symmetric Cartan type or anything recognized by :class:`CartanMatrix` (see also :mod:`Cartan types `) -- for a root lattice - * the string ``"U"`` or ``"H"`` -- for hyperbolic lattices + * the string ``'U'`` or ``'H'`` -- for hyperbolic lattices - ``basis`` -- (optional) a matrix whose rows form a basis of the lattice, or a list of module elements forming a basis @@ -118,7 +120,7 @@ def IntegralLattice(data, basis=None): [ 2 1] [ 1 -2] - We can define an Euclidean lattice just by its dimension:: + We can define a Euclidean lattice just by its dimension:: sage: IntegralLattice(3) Lattice of degree 3 and rank 3 over Integer Ring @@ -140,16 +142,16 @@ def IntegralLattice(data, basis=None): [ 2 -1] [-1 2] - We use ``"U"`` or ``"H"`` for defining a hyperbolic lattice:: + We use ``'U'`` or ``'H'`` for defining a hyperbolic lattice:: - sage: L1 = IntegralLattice("U") + sage: L1 = IntegralLattice('U') sage: L1 Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: [0 1] [1 0] - sage: L1 == IntegralLattice("H") + sage: L1 == IntegralLattice('H') True We can construct root lattices by specifying their type @@ -263,8 +265,8 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): INPUT: - - ``Lattices`` -- a list of lattices ``[L_1,...,L_n]`` - - ``return_embeddings`` -- (default: ``False``) a boolean + - ``Lattices`` -- list of lattices ``[L_1,...,L_n]`` + - ``return_embeddings`` -- boolean (default: ``False``) OUTPUT: @@ -373,12 +375,11 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): INPUT: - - ``Lattices`` -- a list of lattices `[L_1,...,L_n]` - - ``glue`` -- a list where the elements are lists in the form `[g_1,...,g_n]`; + - ``Lattices`` -- list of lattices `[L_1,...,L_n]` + - ``glue`` -- list where the elements are lists in the form `[g_1,...,g_n]`; here `g_i` is an element of the discriminant group of `L_i`and the overlattice is spanned by the additional ``[sum(g) for g in glue]`` - - ``return_embeddings`` -- (default: ``False``) a boolean - + - ``return_embeddings`` -- boolean (default: ``False``) OUTPUT: @@ -629,7 +630,7 @@ class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_b INPUT: - ``ambient`` -- an ambient free quadratic module - - ``basis`` -- a list of elements of ambient or a matrix + - ``basis`` -- list of elements of ambient or a matrix - ``inner_product_matrix`` -- a symmetric matrix over the rationals EXAMPLES:: @@ -751,7 +752,7 @@ def is_even(self): @cached_method def dual_lattice(self): r""" - Return the dual lattice as a :class:`FreeQuadraticModule` + Return the dual lattice as a :class:`FreeQuadraticModule`. Let `L` be a lattice. Its dual lattice is @@ -781,7 +782,7 @@ def discriminant_group(self, s=0): INPUT: - - ``s`` -- an integer (default: 0) + - ``s`` -- integer (default: 0) OUTPUT: @@ -974,7 +975,7 @@ def sublattice(self, basis): INPUT: - - ``basis`` -- A list of elements of this lattice. + - ``basis`` -- list of elements of this lattice EXAMPLES:: @@ -1010,7 +1011,7 @@ def overlattice(self, gens): INPUT: - - ``gens`` -- a list of elements or a rational matrix + - ``gens`` -- list of elements or a rational matrix EXAMPLES:: @@ -1032,9 +1033,9 @@ def maximal_overlattice(self, p=None): INPUT: - - ``p`` -- (default:``None``) if given return an overlattice + - ``p`` -- (default: ``None``) if given return an overlattice `M` of this lattice `L` that is maximal at `p` and the - completions `M_q = L_q` are equal for all primes `q \neq p`. + completions `M_q = L_q` are equal for all primes `q \neq p` If `p` is `2` or ``None``, then the lattice must be even. @@ -1055,7 +1056,6 @@ def maximal_overlattice(self, p=None): sage: L = IntegralLattice(matrix.diagonal([2,4,4,8])) sage: L.maximal_overlattice().is_even() True - """ # this code is somewhat slow but it works # it might speed up things to use the algorithms given in @@ -1162,9 +1162,10 @@ def orthogonal_group(self, gens=None, is_finite=None): INPUT: - - ``gens`` -- a list of matrices (default:``None``) - - ``is_finite`` -- bool (default: ``None``) If set to ``True``, - then the group is placed in the category of finite groups. Sage does not check this. + - ``gens`` -- list of matrices (default: ``None``) + - ``is_finite`` -- boolean (default: ``None``); if set to ``True``, + then the group is placed in the category of finite groups. Sage does + not check this. OUTPUT: @@ -1335,8 +1336,8 @@ def tensor_product(self, other, discard_basis=False): INPUT: - ``other`` -- an integral lattice - - ``discard_basis`` -- a boolean (default: ``False``). If ``True``, then the lattice - returned is equipped with the standard basis. + - ``discard_basis`` -- boolean (default: ``False``); if ``True``, then + the lattice returned is equipped with the standard basis EXAMPLES:: @@ -1480,13 +1481,12 @@ def LLL(self): p, n = self.signature_pair() if p * n != 0: from sage.env import SAGE_EXTCODE - from sage.interfaces.gp import gp from sage.libs.pari import pari - m = self.gram_matrix().__pari__() - gp.read(SAGE_EXTCODE + "/pari/simon/qfsolve.gp") - m = gp.eval('qflllgram_indefgoon(%s)' % m) - # convert the output string to sage - G, U = pari(m).sage() + m = self.gram_matrix() + pari.read(Path(SAGE_EXTCODE) / "pari" / "simon" / "qfsolve.gp") + m = pari('qflllgram_indefgoon')(m) + # convert the output to sage + G, U = m.sage() U = U.T else: e = 1 @@ -1503,13 +1503,11 @@ def short_vectors(self, n, **kwargs): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - further keyword arguments are passed on to - :meth:`sage.quadratic_forms.short_vector_list_up_to_length`. + :meth:`sage.quadratic_forms.short_vector_list_up_to_length` - OUTPUT: - - - a list `L` where ``L[k]`` is the list of vectors of lengths `k` + OUTPUT: list `L` where ``L[k]`` is the list of vectors of lengths `k` EXAMPLES:: @@ -1530,16 +1528,130 @@ def short_vectors(self, n, **kwargs): short = q.short_vector_list_up_to_length(n, *kwargs) return [[self(v * self.basis_matrix()) for v in L] for L in short] + def _fplll_enumerate(self, target=None): + r""" + Internal helper method to invoke the fplll enumeration routines. + + EXAMPLES:: + + sage: L = IntegralLattice('A4') + sage: t = vector([1.2, -3/11, 5.5, -9.1]) + sage: short = L.enumerate_short_vectors() # implicit doctest + sage: vecs = [next(short) for _ in range(10)] + sage: sorted(vecs, key=lambda v: (L(v).inner_product(L(v)), v)) + [(0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 1, 1), (0, 1, 0, 0), (0, 1, 1, 0), + (0, 1, 1, 1), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0), (1, 1, 1, 1)] + sage: close = L.enumerate_close_vectors(t) # implicit doctest + sage: vecs = [next(close) for _ in range(10)] + sage: sorted(vecs, key=lambda v: (L(v).inner_product(L(v)), v)) + [(1, 0, 6, -8), (1, 0, 5, -9), (2, 0, 5, -9), (1, -1, 5, -9), (2, 1, 6, -9), + (1, 0, 6, -9), (2, 0, 6, -9), (1, 0, 5, -10), (1, -1, 6, -9), (1, -1, 5, -10)] + """ + L = self.LLL() + dim = L.dimension() + gram = L.gram_matrix() + basis = L.basis_matrix() + + import fpylll + gmat = fpylll.IntegerMatrix(dim, dim) + for i in range(dim): + for j in range(dim): + gmat[i,j] = gram[i,j] + gso = fpylll.GSO.Mat(gmat, gram=True) + ok = gso.update_gso() + assert ok + + coord = None + if target is not None: + coord = basis.solve_left(target) + Mu = 1 + matrix([gso.get_mu(i,j) for j in range(dim)] for i in range(dim)) + coord *= Mu + + count = 8 + bound = gso.get_r(dim-1, dim-1) + seen = set() + while True: + enum = fpylll.Enumeration(gso, count, fpylll.EvaluatorStrategy.BEST_N_SOLUTIONS) + try: + combs = enum.enumerate(0, dim, bound, 0, coord) + except fpylll.EnumerationError: + combs = [] + if len(combs) < count: + bound *= 2 + continue + for length,comb in combs: + vec = sum(ZZ(c)*b for c,b in zip(comb,basis)) + if tuple(vec) not in seen: + yield vec + seen.add(tuple(vec)) + count *= 2 + + def enumerate_short_vectors(self): + r""" + Return an iterator over all the vectors in this lattice (modulo sign), + starting from shorter vectors. + + .. WARNING:: + + The returned vectors are not necessarily ordered strictly + by length. + + EXAMPLES:: + + sage: L = IntegralLattice(4, [[1,2,3,4], [7,7,8,8], [1,-1,1,0]]) + sage: short = L.enumerate_short_vectors() + sage: vecs = [next(short) for _ in range(20)] + sage: sorted(vecs, key=lambda v: (L(v).inner_product(L(v)), v)) + [(1, -1, 1, 0), (2, -2, 2, 0), (3, -3, 3, 0), (0, 3, 2, 4), (1, 2, 3, 4), + (3, 2, -2, -4), (4, 4, 1, 0), (-1, 4, 1, 4), (3, 5, 0, 0), (4, 1, -1, -4), + (2, 1, 4, 4), (2, 3, -3, -4), (5, 3, 2, 0), (2, 6, -1, 0), (5, 0, 0, -4), + (-2, 5, 0, 4), (4, -4, 4, 0), (1, 4, -4, -4), (6, 2, 3, 0), (3, 0, 5, 4)] + + This example demonstrates that the lattice inner product is used for the norm:: + + sage: Q = Matrix(QQ, [[1000, 0], [0, 1]]) + sage: B = [[1, 1], [1, -1]] + sage: L = IntegralLattice(Q, basis=B) + sage: short = L.enumerate_short_vectors() + sage: vecs = [next(short) for _ in range(20)] + sage: sorted(vecs, key=lambda v: (L(v).inner_product(L(v)), v)) + [(0, -2), (0, -4), (0, -6), (0, -8), (0, -10), (0, -12), (0, -14), (0, -16), + (0, -18), (0, -20), (0, -22), (0, -24), (0, -26), (0, -28), (0, -30), (-1, -1), + (-1, 1), (-1, -3), (-1, 3), (0, -32)] + """ + yield from self._fplll_enumerate() + + def enumerate_close_vectors(self, target): + r""" + Return an iterator over all the vectors in this lattice, starting + from vectors relatively close to the given ``target`` vector. + + .. WARNING:: + + The returned vectors are not necessarily ordered strictly + by their distance to the target. + + EXAMPLES:: + + sage: L = IntegralLattice(4, [[1,2,3,4], [7,7,8,8], [1,-1,1,0]]) + sage: t = vector([1/2, -133/7, 123.44, -11]) + sage: close = L.enumerate_close_vectors(t) + sage: vecs = [next(close) for _ in range(10)] + sage: sorted(vecs, key=lambda v: (L(v).inner_product(L(v)), v)) + [(-1, -16, 121, 148), (0, -17, 122, 148), (-3, -22, 122, 148), (1, -18, 123, 148), (-2, -23, 123, 148), + (2, -19, 124, 148), (3, -20, 125, 148), (4, -21, 126, 148), (-3, -19, 124, 152), (-2, -20, 125, 152)] + """ + yield from self._fplll_enumerate(target) + def twist(self, s, discard_basis=False): r""" Return the lattice with inner product matrix scaled by ``s``. INPUT: - - ``s`` -- a nonzero integer - - ``discard_basis`` -- a boolean (default: ``False``). - If ``True``, then the lattice returned is equipped - with the standard basis. + - ``s`` -- nonzero integer + - ``discard_basis`` -- boolean (default: ``False``); if ``True``, then + the lattice returned is equipped with the standard basis EXAMPLES:: @@ -1576,7 +1688,7 @@ def twist(self, s, discard_basis=False): except TypeError: raise ValueError("the scaling factor must be an element of the base ring.") if s == 0: - raise ValueError("the scaling factor must be non zero") + raise ValueError("the scaling factor must be nonzero") if discard_basis: return IntegralLattice(s * self.gram_matrix()) else: diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index fcce12a0788..175d152f364 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -58,7 +58,7 @@ def is_MatrixMorphism(x): """ - Return True if x is a Matrix morphism of free modules. + Return ``True`` if x is a Matrix morphism of free modules. This function is deprecated. @@ -97,10 +97,9 @@ def __init__(self, parent, side='left'): """ INPUT: - - ``parent`` -- a homspace - - - ``A`` -- matrix + - ``parent`` -- a homspace + - ``A`` -- matrix EXAMPLES:: @@ -244,7 +243,6 @@ def _call_with_args(self, x, args=(), kwds={}): to coefficients in Real Field with 53 bits of precision sage: f((1, 0), coerce=False) (1.00000000000000*I, 0.000000000000000) - """ if self.domain().is_ambient(): x = x.element() @@ -299,7 +297,7 @@ def side(self): sage: m = matrix(2, [1, 1, 0, 1]) sage: V = ZZ^2 - sage: h1 = V.hom(m); h2 = V.hom(m, side="right") + sage: h1 = V.hom(m); h2 = V.hom(m, side='right') sage: h1.side() 'left' sage: h1([1, 0]) @@ -313,7 +311,7 @@ def side(self): def side_switch(self): """ - Return the same morphism, acting on vectors on the opposite side + Return the same morphism, acting on vectors on the opposite side. EXAMPLES:: @@ -342,7 +340,7 @@ def inverse(self): r""" Return the inverse of this matrix morphism, if the inverse exists. - This raises a :class:`ZeroDivisionError` if the inverse does not exist. + This raises a :exc:`ZeroDivisionError` if the inverse does not exist. EXAMPLES: @@ -565,7 +563,7 @@ def __mul__(self, right): Codomain: Vector space of dimension 2 over Rational Field sage: f(a) (1, 1) - sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV + sage: V.hom([V.0 - V.1, V.0 + V.1], side='right')*KtoV Composite map: From: Number Field in a with defining polynomial x^2 + 23 To: Vector space of dimension 2 over Rational Field @@ -580,12 +578,12 @@ def __mul__(self, right): Codomain: Vector space of dimension 2 over Rational Field - We can test interraction between morphisms with different ``side``:: + We can test interaction between morphisms with different ``side``:: sage: V = ZZ^2 sage: m = matrix(2, [1,1,0,1]) sage: hl = V.hom(m) - sage: hr = V.hom(m, side="right") + sage: hr = V.hom(m, side='right') sage: hl * hl Free module morphism defined by the matrix [1 2] @@ -650,7 +648,7 @@ def __mul__(self, right): if right.side() == "right": return H(self.matrix() * right.matrix(), side=self.side()) else: - return H(right.matrix() * self.matrix().transpose(), side="left") + return H(right.matrix() * self.matrix().transpose(), side='left') def __add__(self, right): """ @@ -694,7 +692,7 @@ def __add__(self, right): sage: V = ZZ^2 sage: m = matrix(2, [1,1,0,1]) sage: hl = V.hom(m) - sage: hr = V.hom(m, side="right") + sage: hr = V.hom(m, side='right') sage: hl + hl Free module morphism defined by the matrix [2 2] @@ -727,12 +725,12 @@ def __add__(self, right): if right.side() == "left": return self.parent()(self.matrix() + right.matrix(), side=self.side()) elif right.side() == "right": - return self.parent()(self.matrix() + right.matrix().transpose(), side="left") + return self.parent()(self.matrix() + right.matrix().transpose(), side='left') if self.side() == "right": if right.side() == "right": return self.parent()(self.matrix() + right.matrix(), side=self.side()) elif right.side() == "left": - return self.parent()(self.matrix().transpose() + right.matrix(), side="left") + return self.parent()(self.matrix().transpose() + right.matrix(), side='left') def __neg__(self): """ @@ -765,7 +763,7 @@ def __sub__(self, other): sage: V = ZZ^2 sage: m = matrix(2, [1,1,0,1]) sage: hl = V.hom(m) - sage: hr = V.hom(m, side="right") + sage: hr = V.hom(m, side='right') sage: hl - hr Free module morphism defined by the matrix [ 0 1] @@ -798,17 +796,17 @@ def __sub__(self, other): if other.side() == "left": return self.parent()(self.matrix() - other.matrix(), side=self.side()) elif other.side() == "right": - return self.parent()(self.matrix() - other.matrix().transpose(), side="left") + return self.parent()(self.matrix() - other.matrix().transpose(), side='left') if self.side() == "right": if other.side() == "right": return self.parent()(self.matrix() - other.matrix(), side=self.side()) elif other.side() == "left": - return self.parent()(self.matrix().transpose() - other.matrix(), side="left") + return self.parent()(self.matrix().transpose() - other.matrix(), side='left') def base_ring(self): """ - Return the base ring of self, that is, the ring over which self is - given by a matrix. + Return the base ring of ``self``, that is, the ring over which ``self`` + is given by a matrix. EXAMPLES:: @@ -820,9 +818,9 @@ def base_ring(self): def decomposition(self, *args, **kwds): """ Return decomposition of this endomorphism, i.e., sequence of - subspaces obtained by finding invariant subspaces of self. + subspaces obtained by finding invariant subspaces of ``self``. - See the documentation for self.matrix().decomposition for more + See the documentation for ``self.matrix().decomposition`` for more details. All inputs to this function are passed onto the matrix one. @@ -838,7 +836,7 @@ def decomposition(self, *args, **kwds): Echelon basis matrix: [ 1 -1] ] - sage: phi2 = V.hom(phi.matrix(), side="right") + sage: phi2 = V.hom(phi.matrix(), side='right') sage: phi2.decomposition() # needs sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring @@ -893,7 +891,7 @@ def kernel(self): [1 0 0] [0 0 1] sage: f1 = V.hom(m) - sage: f2 = V.hom(m, side="right") + sage: f2 = V.hom(m, side='right') sage: f1.kernel() Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: @@ -938,7 +936,7 @@ def image(self): [1 0 0] [0 0 1] sage: f1 = V.hom(m) - sage: f2 = V.hom(m, side="right") + sage: f2 = V.hom(m, side='right') sage: f1.image() Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: @@ -1030,7 +1028,7 @@ def _matrix_(self): def rank(self): r""" - Returns the rank of the matrix representing this morphism. + Return the rank of the matrix representing this morphism. EXAMPLES:: @@ -1045,7 +1043,7 @@ def rank(self): def nullity(self): r""" - Returns the nullity of the matrix representing this morphism, which is the + Return the nullity of the matrix representing this morphism, which is the dimension of its kernel. EXAMPLES:: @@ -1065,7 +1063,7 @@ def nullity(self): sage: h1.nullity() 1 sage: W = ZZ^1 - sage: h2 = W.hom(m, side="right") + sage: h2 = W.hom(m, side='right') sage: h2.nullity() 0 """ @@ -1207,7 +1205,7 @@ def is_zero(self): sage: phi.is_zero() True - An image list that just barely makes a non-zero morphism. :: + An image list that just barely makes a nonzero morphism. :: sage: V = ZZ^4 sage: W = ZZ^6 @@ -1347,7 +1345,7 @@ def restrict_domain(self, sub): Free module morphism defined by the matrix [0 2]... sage: m = matrix(2, range(1,5)) - sage: f1 = V.hom(m); f2 = V.hom(m, side="right") + sage: f1 = V.hom(m); f2 = V.hom(m, side='right') sage: SV = V.span([V.0]) sage: f1.restrict_domain(SV) Free module morphism defined by the matrix @@ -1451,7 +1449,7 @@ def restrict_codomain(self, sub): V = sub.free_module() try: if self.side() == "right": - return H(self.matrix().transpose().restrict_codomain(V).transpose(), side="right") + return H(self.matrix().transpose().restrict_codomain(V).transpose(), side='right') else: return H(self.matrix().restrict_codomain(V)) except Exception: @@ -1555,13 +1553,13 @@ class MatrixMorphism(MatrixMorphism_abstract): INPUT: - - ``parent`` -- a homspace + - ``parent`` -- a homspace - - ``A`` -- matrix or a :class:`MatrixMorphism_abstract` instance + - ``A`` -- matrix or a :class:`MatrixMorphism_abstract` instance - - ``copy_matrix`` -- (default: ``True``) make an immutable copy of - the matrix ``A`` if it is mutable; if ``False``, then this makes - ``A`` immutable + - ``copy_matrix`` -- boolean (default: ``True``); make an immutable copy of + the matrix ``A`` if it is mutable. If ``False``, then this makes + ``A`` immutable. """ def __init__(self, parent, A, copy_matrix=True, side='left'): """ diff --git a/src/sage/modules/meson.build b/src/sage/modules/meson.build new file mode 100644 index 00000000000..bc505da9372 --- /dev/null +++ b/src/sage/modules/meson.build @@ -0,0 +1,101 @@ +py.install_sources( + 'all.py', + 'complex_double_vector.py', + 'diamond_cutting.py', + 'filtered_vector_space.py', + 'finite_submodule_iter.pxd', + 'free_module.py', + 'free_module_element.pxd', + 'free_module_homspace.py', + 'free_module_integer.py', + 'free_module_morphism.py', + 'free_quadratic_module.py', + 'free_quadratic_module_integer_symmetric.py', + 'matrix_morphism.py', + 'misc.py', + 'module.pxd', + 'module_functors.py', + 'multi_filtered_vector_space.py', + 'quotient_module.py', + 'real_double_vector.py', + 'submodule.py', + 'tensor_operations.py', + 'torsion_quadratic_module.py', + 'tutorial_free_modules.py', + 'vector_callable_symbolic_dense.py', + 'vector_complex_double_dense.pxd', + 'vector_double_dense.pxd', + 'vector_integer_dense.pxd', + 'vector_integer_sparse.pxd', + 'vector_mod2_dense.pxd', + 'vector_modn_dense.pxd', + 'vector_modn_sparse.pxd', + 'vector_numpy_dense.pxd', + 'vector_numpy_integer_dense.pxd', + 'vector_rational_dense.pxd', + 'vector_rational_sparse.pxd', + 'vector_real_double_dense.pxd', + 'vector_space_homspace.py', + 'vector_space_morphism.py', + 'vector_symbolic_dense.py', + 'vector_symbolic_sparse.py', + subdir: 'sage/modules', +) + +extension_data = { + 'finite_submodule_iter' : files('finite_submodule_iter.pyx'), + 'free_module_element' : files('free_module_element.pyx'), + 'module' : files('module.pyx'), + 'vector_complex_double_dense' : files('vector_complex_double_dense.pyx'), + 'vector_double_dense' : files('vector_double_dense.pyx'), + 'vector_integer_dense' : files('vector_integer_dense.pyx'), + 'vector_integer_sparse' : files('vector_integer_sparse.pyx'), + 'vector_modn_dense' : files('vector_modn_dense.pyx'), + 'vector_modn_sparse' : files('vector_modn_sparse.pyx'), + 'vector_numpy_dense' : files('vector_numpy_dense.pyx'), + 'vector_numpy_integer_dense' : files('vector_numpy_integer_dense.pyx'), + 'vector_rational_dense' : files('vector_rational_dense.pyx'), + 'vector_rational_sparse' : files('vector_rational_sparse.pyx'), + 'vector_real_double_dense' : files('vector_real_double_dense.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modules', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_numpy, + inc_rings, + inc_rings_finite, + ], + dependencies: [py_dep, cysignals, gd, gmp, m4ri, png], + ) +endforeach + +extension_data_cpp = {'vector_mod2_dense': files('vector_mod2_dense.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modules', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_numpy, + inc_rings, + inc_rings_finite, + ], + dependencies: [py_dep, cysignals, gd, gmp, m4ri, png], + ) +endforeach + +install_subdir('fg_pid', install_dir: sage_install_dir / 'modules') +install_subdir('fp_graded', install_dir: sage_install_dir / 'modules') +subdir('with_basis') diff --git a/src/sage/modules/module.pyx b/src/sage/modules/module.pyx index 845c4b239d8..1ca79818c26 100644 --- a/src/sage/modules/module.pyx +++ b/src/sage/modules/module.pyx @@ -71,7 +71,7 @@ cdef class Module(Parent): INPUT: - - ``base`` -- a ring. The base ring of the module. + - ``base`` -- a ring; the base ring of the module - ``category`` -- a category (default: ``None``), the category for this module. If ``None``, then this is set to the category of modules/vector @@ -112,7 +112,6 @@ cdef class Module(Parent): sage: M.rename('toto') sage: h == M.__hash__() True - """ def __init__(self, base, category=None, names=None): """ @@ -124,7 +123,6 @@ cdef class Module(Parent): sage: M = Module(ZZ) sage: type(M) - """ from sage.categories.modules import Modules if category is None: @@ -170,7 +168,6 @@ cdef class Module(Parent): - Simon King (2010-12) - Peter Bruin (June 2014) - """ try: if (isinstance(M, Module) @@ -193,7 +190,6 @@ cdef class Module(Parent): Traceback (most recent call last): ... NotImplementedError: the method change_ring() has not yet been implemented - """ if R is self.base_ring(): return self @@ -204,7 +200,7 @@ cdef class Module(Parent): Return the base extension of ``self`` to `R`. This is the same as ``self.change_ring(R)`` except that a - :class:`TypeError` is raised if there is no canonical coerce map + :exc:`TypeError` is raised if there is no canonical coerce map from the base ring of ``self`` to `R`. INPUT: @@ -245,7 +241,6 @@ cdef class Module(Parent): ... TypeError: Base extension of self (over 'Cyclotomic Field of order 9 and degree 6') to ring 'Cyclotomic Field of order 3 and degree 2' not defined. - """ if R.has_coerce_map_from(self.base_ring()): return self.change_ring(R) @@ -276,7 +271,7 @@ def is_Module(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything EXAMPLES:: @@ -302,7 +297,7 @@ def is_VectorSpace(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything EXAMPLES:: @@ -324,7 +319,6 @@ def is_VectorSpace(x): True sage: is_VectorSpace(M) False - """ from sage.misc.superseded import deprecation_cython deprecation_cython(37924, "the function is_VectorSpace is deprecated; use 'isinstance(..., Module)' and check the base ring instead") diff --git a/src/sage/modules/multi_filtered_vector_space.py b/src/sage/modules/multi_filtered_vector_space.py index 36bf483ee60..ece6d2af6c7 100644 --- a/src/sage/modules/multi_filtered_vector_space.py +++ b/src/sage/modules/multi_filtered_vector_space.py @@ -63,8 +63,8 @@ def MultiFilteredVectorSpace(arg, base_ring=None, check=True): base field of the vector space. Must be a field. If not specified, the base field is derived from the filtrations. - - ``check`` -- boolean (optional; default: ``True``). Whether - to perform consistency checks. + - ``check`` -- boolean (default: ``True``); whether + to perform consistency checks EXAMPLES:: @@ -110,15 +110,14 @@ def __init__(self, base_ring, dim, filtrations, check=True): INPUT: - - ``base_ring`` -- a ring. the base ring. + - ``base_ring`` -- the base ring - - ``dim`` -- integer. The dimension of the ambient vector space. + - ``dim`` -- integer; the dimension of the ambient vector space - - ``filtrations`` -- a dictionary whose values are - filtrations. + - ``filtrations`` -- dictionary whose values are filtrations - - ``check`` -- boolean (optional). Whether to perform - additional consistency checks. + - ``check`` -- boolean (default: ``True``); whether to perform + additional consistency checks EXAMPLES:: @@ -142,9 +141,7 @@ def index_set(self): """ Return the allowed indices for the different filtrations. - OUTPUT: - - Set. + OUTPUT: set EXAMPLES:: @@ -163,7 +160,7 @@ def change_ring(self, base_ring): INPUT: - - ``base_ring`` -- a ring. The new base ring. + - ``base_ring`` -- the new base ring OUTPUT: @@ -199,9 +196,7 @@ def ambient_vector_space(self): """ Return the ambient (unfiltered) vector space. - OUTPUT: - - A vector space. + OUTPUT: a vector space EXAMPLES:: @@ -218,10 +213,8 @@ def is_constant(self): """ Return whether the multi-filtration is constant. - OUTPUT: - - Boolean. Whether the each filtration is constant, see - :meth:`~sage.modules.filtered_vector_space.FilteredVectorSpace_class.is_constant`. + OUTPUT: boolean; whether the each filtration is constant, see + :meth:`~sage.modules.filtered_vector_space.FilteredVectorSpace_class.is_constant` EXAMPLES:: @@ -243,10 +236,8 @@ def is_exhaustive(self): A filtration `\{F_d\}` in an ambient vector space `V` is exhaustive if `\cup F_d = V`. See also :meth:`is_separating`. - OUTPUT: - - Boolean. Whether each filtration is constant, see - :meth:`~sage.modules.filtered_vector_space.FilteredVectorSpace_class.is_exhaustive`. + OUTPUT: boolean; whether each filtration is constant, see + :meth:`~sage.modules.filtered_vector_space.FilteredVectorSpace_class.is_exhaustive` EXAMPLES:: @@ -265,10 +256,8 @@ def is_separating(self): A filtration `\{F_d\}` in an ambient vector space `V` is exhaustive if `\cap F_d = 0`. See also :meth:`is_exhaustive`. - OUTPUT: - - Boolean. Whether each filtration is separating, see - :meth:`~sage.modules.filtered_vector_space.FilteredVectorSpace_class.is_separating`. + OUTPUT: boolean; whether each filtration is separating, see + :meth:`~sage.modules.filtered_vector_space.FilteredVectorSpace_class.is_separating` EXAMPLES:: @@ -355,9 +344,7 @@ def get_filtration(self, key): """ Return the filtration indexed by ``key``. - OUTPUT: - - A filtered vector space. + OUTPUT: a filtered vector space EXAMPLES:: @@ -375,10 +362,10 @@ def get_degree(self, key, deg): INPUT: - - ``key`` -- an element of the :meth:`index_set`. Specifies - which filtration. + - ``key`` -- an element of the :meth:`index_set`; specifies + which filtration - - ``d`` -- Integer. The desired degree of the filtration. + - ``d`` -- integer; the desired degree of the filtration OUTPUT: @@ -404,10 +391,10 @@ def graded(self, key, deg): INPUT: - - ``key`` -- an element of the :meth:`index_set`. Specifies - which filtration. + - ``key`` -- an element of the :meth:`index_set`; specifies + which filtration - - ``d`` -- Integer. The desired degree of the filtration. + - ``d`` -- integer; the desired degree of the filtration OUTPUT: @@ -434,9 +421,7 @@ def _repr_(self): r""" Return as string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -517,7 +502,7 @@ def direct_sum(self, other): INPUT: - ``other`` -- a multi-filtered vector space with the same - :meth:`index_set`. + :meth:`index_set` OUTPUT: @@ -558,7 +543,7 @@ def tensor_product(self, other): INPUT: - ``other`` -- a multi-filtered vector space with the same - :meth:`index_set`. + :meth:`index_set` OUTPUT: @@ -599,8 +584,7 @@ def exterior_power(self, n): INPUT: - - ``n`` -- integer. Exterior product of how many copies of - ``self``. + - ``n`` -- integer; exterior product of how many copies of ``self`` OUTPUT: @@ -629,8 +613,7 @@ def symmetric_power(self, n): INPUT: - - ``n`` -- integer. Symmetric product of how many copies of - ``self``. + - ``n`` -- integer; symmetric product of how many copies of ``self`` OUTPUT: @@ -699,11 +682,11 @@ def shift(self, deg): def random_deformation(self, epsilon=None): """ - Return a random deformation + Return a random deformation. INPUT: - - ``epsilon`` -- a number in the base ring. + - ``epsilon`` -- a number in the base ring OUTPUT: diff --git a/src/sage/modules/quotient_module.py b/src/sage/modules/quotient_module.py index a59273cc407..26c9c7629c0 100644 --- a/src/sage/modules/quotient_module.py +++ b/src/sage/modules/quotient_module.py @@ -219,7 +219,7 @@ def cover(self): def relations(self): r""" - Given this quotient space `Q = V/W`, return `W` + Given this quotient space `Q = V/W`, return `W`. EXAMPLES:: @@ -489,9 +489,9 @@ def _element_constructor_(self, x): Convert an element into this quotient space `V/W` if there is a way to make sense of it. - An element converts into self if it can be converted into `V`, + An element converts into ``self`` if it can be converted into `V`, or if not at least if it can be made sense of as a list of - length the dimension of self. + length the dimension of ``self``. EXAMPLES: @@ -534,7 +534,6 @@ def _element_constructor_(self, x): sage: Q((ZZ^3)([1,2,3])) (2, 3) - """ if isinstance(x, self.element_class) and x.parent() is self: return x @@ -576,7 +575,6 @@ def _coerce_map_from_(self, M): sage: V = QQ^3 / [[1,2,3]] sage: V.coerce_map_from(QQ^2) - """ from sage.modules.free_module import FreeModule_ambient if (isinstance(M, FreeModule_ambient) diff --git a/src/sage/modules/tensor_operations.py b/src/sage/modules/tensor_operations.py index 8ca968133a2..2f17640d89e 100644 --- a/src/sage/modules/tensor_operations.py +++ b/src/sage/modules/tensor_operations.py @@ -71,13 +71,13 @@ def symmetrized_coordinate_sums(dim, n): """ - Return formal symmetrized sum of multi-indices + Return formal symmetrized sum of multi-indices. INPUT: - - ``dim`` -- integer. The dimension (range of each index). + - ``dim`` -- integer; the dimension (range of each index) - - ``n`` -- integer. The total number of indices. + - ``n`` -- integer; the total number of indices OUTPUT: @@ -103,13 +103,13 @@ def symmetrized_coordinate_sums(dim, n): def antisymmetrized_coordinate_sums(dim, n): """ - Return formal anti-symmetrized sum of multi-indices + Return formal anti-symmetrized sum of multi-indices. INPUT: - - ``dim`` -- integer. The dimension (range of each index). + - ``dim`` -- integer; the dimension (range of each index) - - ``n`` -- integer. The total number of indices. + - ``n`` -- integer; the total number of indices OUTPUT: @@ -143,9 +143,9 @@ class VectorCollection(FreeModule_ambient_field): INPUT: - - ``dim`` -- integer. The dimension of the ambient vector space. + - ``dim`` -- integer; the dimension of the ambient vector space - - ``base_ring`` -- a field. The base field of the ambient vector space. + - ``base_ring`` -- a field; the base field of the ambient vector space - ``rays`` -- any list/iterable of things than can be converted into vectors of the ambient vector space. These will be used to @@ -189,7 +189,7 @@ def __init__(self, vector_collection, base_ring, dim): def vectors(self): """ - Return the collection of vectors + Return the collection of vectors. OUTPUT: @@ -207,11 +207,9 @@ def vectors(self): def n_vectors(self): """ - Return the number of vectors + Return the number of vectors. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -236,10 +234,10 @@ class TensorOperation(VectorCollection): INPUT: - ``vector_collections`` -- a nonempty list/tuple/iterable of - :class:`VectorCollection` objects. + :class:`VectorCollection` objects - - ``operation`` -- string. The tensor operation. Currently allowed - values are ``product``, ``symmetric``, and ``antisymmetric``. + - ``operation`` -- string; the tensor operation. Currently allowed + values are ``'product'``, ``'symmetric'``, and ``'antisymmetric'``. .. TODO:: @@ -300,7 +298,7 @@ def _init_product_vectors(self, i): INPUT: - - `i` -- list/tuple of integers. Multi-index of length equal + - ``i`` -- list/tuple of integers. Multi-index of length equal to the number of constituent vector collections. The `j`-th entry `i[j]` indexes a ray in the `j`-th vector collection. Hence, `i` specifies one element in each vector @@ -353,12 +351,12 @@ def _init_power_operation_vectors(self, i, linear_combinations): INPUT: - - `i` -- list/tuple of integers. Specifies one element + - ``i`` -- list/tuple of integers. Specifies one element (vector) in each vector collection as in - :meth:`_init_product_vector`. + :meth:`_init_product_vector` - ``linear_combination`` -- formal linear combination of - vector indices in the vectors specified by `i`. + vector indices in the vectors specified by `i` EXAMPLES:: @@ -391,7 +389,7 @@ def _init_power_operation_vectors(self, i, linear_combinations): def _init_product(self): """ - Initialization for the tensor product + Initialization for the tensor product. EXAMPLES:: @@ -433,7 +431,7 @@ def _init_symmetric(self): def _init_antisymmetric(self): """ - Initialization for the antisymmetric product + Initialization for the antisymmetric product. EXAMPLES:: @@ -552,9 +550,7 @@ def codomain(self): """ The codomain of the index map. - OUTPUT: - - A list of integers. The image of :meth:`index_map`. + OUTPUT: list of integers; the image of :meth:`index_map` EXAMPLES:: diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 45f1450c3cb..d6d8431ff2f 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -97,7 +97,7 @@ class TorsionQuadraticModuleElement(FGP_Element): - ``x`` -- element of ``parent.V()`` - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) TESTS:: @@ -205,7 +205,7 @@ class TorsionQuadraticModule(FGP_Module_class, CachedRepresentation): - ``W`` -- a submodule of ``V`` of the same rank as ``V`` - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - ``modulus`` -- a rational number dividing `m` (default: `m`); the inner product `b` is defined in `\QQ /` ``modulus`` `\ZZ` @@ -328,14 +328,12 @@ def _module_constructor(self, V, W, check=False): - ``W`` -- a submodule of ``V`` over the same base ring - - ``check`` -- bool (default: ``False``); + - ``check`` -- boolean (default: ``False``) * if ``False``, then the value modulus is inherited from ``self`` * if ``True``, it figures it out on its own. But that is expensive - OUTPUT: - - The quotient ``V / W`` as a :class:`TorsionQuadraticModule`. + OUTPUT: the quotient ``V / W`` as a :class:`TorsionQuadraticModule` EXAMPLES:: @@ -423,9 +421,7 @@ def brown_invariant(self): The Brown invariant is additive with respect to direct sums of torsion quadratic modules. - OUTPUT: - - - an element of `\Zmod{8}` + OUTPUT: an element of `\Zmod{8}` EXAMPLES:: @@ -544,7 +540,7 @@ def genus(self, signature_pair): r""" Return the genus defined by ``self`` and the ``signature_pair``. - If no such genus exists, raise a :class:`ValueError`. + If no such genus exists, raise a :exc:`ValueError`. REFERENCES: @@ -754,8 +750,8 @@ def is_genus(self, signature_pair, even=True): INPUT: - - ``signature_pair`` -- a tuple of non negative integers ``(s_plus, s_minus)`` - - ``even`` -- bool (default: ``True``) + - ``signature_pair`` -- tuple of nonnegative integers ``(s_plus, s_minus)`` + - ``even`` -- boolean (default: ``True``) EXAMPLES:: @@ -776,7 +772,7 @@ def is_genus(self, signature_pair, even=True): s_plus = ZZ(signature_pair[0]) s_minus = ZZ(signature_pair[1]) if s_plus < 0 or s_minus < 0: - raise ValueError("signature invariants must be non negative") + raise ValueError("signature invariants must be nonnegative") rank = s_plus + s_minus signature = s_plus - s_minus D = self.cardinality() @@ -829,7 +825,7 @@ def orthogonal_group(self, gens=None, check=False): INPUT: - - ``gens`` -- a list of generators, for instance square matrices, + - ``gens`` -- a list of generators, for instance square matrices, something that acts on ``self``, or an automorphism of the underlying abelian group - ``check`` -- perform additional checks on the generators @@ -985,12 +981,10 @@ def normal_form(self, partial=False): INPUT: - - ``partial`` -- bool (default: ``False``) return only a partial normal form; - it is not unique but still useful to extract invariants - - OUTPUT: + - ``partial`` -- boolean (default: ``False``); return only a partial + normal form. It is not unique but still useful to extract invariants. - - a torsion quadratic module + OUTPUT: a torsion quadratic module EXAMPLES:: @@ -1125,11 +1119,9 @@ def primary_part(self, m): INPUT: - - ``m`` -- an integer - - OUTPUT: + - ``m`` -- integer - - a submodule + OUTPUT: a submodule EXAMPLES:: @@ -1162,11 +1154,9 @@ def submodule_with_gens(self, gens): INPUT: - - ``gens`` -- a list of generators that convert into ``self`` - - OUTPUT: + - ``gens`` -- list of generators that convert into ``self`` - - a submodule with the specified generators + OUTPUT: a submodule with the specified generators EXAMPLES:: diff --git a/src/sage/modules/tutorial_free_modules.py b/src/sage/modules/tutorial_free_modules.py index 8fe8cd8c7df..3af1ba78f54 100644 --- a/src/sage/modules/tutorial_free_modules.py +++ b/src/sage/modules/tutorial_free_modules.py @@ -137,12 +137,12 @@ Some definitions: * A *monomial* is an element of the basis `B_i`; - * A *term* is an element of the basis multiplied by a non zero + * A *term* is an element of the basis multiplied by a nonzero *coefficient*: `c B_i`; * The support of that term is `i`. * The corresponding *item* is the :class:`tuple` ``(i, c)``. * The *support* of an element `f` is the collection of indices `i` - such that `B_i` appears in `f` with non zero coefficient. + such that `B_i` appears in `f` with nonzero coefficient. * The *monomials*, *terms*, *items*, and *coefficients* of an element `f` are defined accordingly. * *Leading*/*trailing* refers to the *greatest*/*least* index. diff --git a/src/sage/modules/vector_callable_symbolic_dense.py b/src/sage/modules/vector_callable_symbolic_dense.py index eb2cf2eedfd..8f23e78114f 100644 --- a/src/sage/modules/vector_callable_symbolic_dense.py +++ b/src/sage/modules/vector_callable_symbolic_dense.py @@ -55,7 +55,7 @@ class Vector_callable_symbolic_dense(free_module_element.FreeModuleElement_generic_dense): def _repr_(self): """ - Returns the string representation of the vector + Return the string representation of the vector. EXAMPLES:: diff --git a/src/sage/modules/vector_complex_double_dense.pyx b/src/sage/modules/vector_complex_double_dense.pyx index 59b585f912c..c8aaedce365 100644 --- a/src/sage/modules/vector_complex_double_dense.pyx +++ b/src/sage/modules/vector_complex_double_dense.pyx @@ -71,7 +71,7 @@ cdef class Vector_complex_double_dense(Vector_double_dense): def __reduce__(self): """ - Pickling + Pickling. EXAMPLES:: diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index 79f42205439..5c184c96967 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -103,7 +103,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): cpdef _sub_(self, right): """ - Return self - right + Return ``self - right``. EXAMPLES:: @@ -123,7 +123,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): cpdef _dot_product_(self, Vector right): """ - Dot product of self and right. + Dot product of ``self`` and ``right``. EXAMPLES:: @@ -147,7 +147,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): cpdef _pairwise_product_(self, Vector right): """ - Return the component-wise product of self and right. + Return the component-wise product of ``self`` and ``right``. EXAMPLES:: @@ -170,7 +170,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): cpdef _rmul_(self, Element left): """ - Multiply a scalar and vector + Multiply a scalar and vector. EXAMPLES:: @@ -186,7 +186,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): cpdef _lmul_(self, Element right): """ - Multiply a scalar and vector + Multiply a scalar and vector. EXAMPLES:: @@ -200,7 +200,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): return self._new(self._vector_numpy*self._python_dtype(right)) - def inv_fft(self,algorithm="radix2", inplace=False): + def inv_fft(self, algorithm='radix2', inplace=False): """ This performs the inverse fast Fourier transform on the vector. @@ -217,15 +217,15 @@ cdef class Vector_double_dense(Vector_numpy_dense): sage: max(v - w.inv_fft()) < 1e-12 True """ - return self.fft(direction="backward",algorithm=algorithm,inplace=inplace) + return self.fft(direction='backward', algorithm=algorithm, inplace=inplace) - def fft(self, direction = "forward", algorithm = "radix2", inplace=False): + def fft(self, direction='forward', algorithm='radix2', inplace=False): """ This performs a fast Fourier transform on the vector. INPUT: - - direction -- 'forward' (default) or 'backward' + - ``direction`` -- string; ``'forward'`` (default) or ``'backward'`` The algorithm and inplace arguments are ignored. @@ -311,7 +311,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): def zero_at(self, eps): r""" - Returns a copy with small entries replaced by zeros. + Return a copy with small entries replaced by zeros. This is useful for modifying output from algorithms which have large relative errors when producing zero @@ -328,7 +328,6 @@ cdef class Vector_double_dense(Vector_numpy_dense): complex vectors, the real and imaginary parts are considered individually. - EXAMPLES:: sage: v = vector(RDF, [1.0, 2.0, 10^-10, 3.0]) @@ -360,11 +359,11 @@ cdef class Vector_double_dense(Vector_numpy_dense): def norm(self, p=2): r""" - Returns the norm (or related computations) of the vector. + Return the norm (or related computations) of the vector. INPUT: - - ``p`` -- (default: 2); controls which norm is computed, + - ``p`` -- (default: 2) controls which norm is computed, allowable values are any real number and positive and negative infinity. See output discussion for specifics. @@ -376,12 +375,11 @@ cdef class Vector_double_dense(Vector_numpy_dense): - ``p = Infinity`` or ``p = oo``: the maximum of the absolute values of the entries, where the absolute value - of the complex number `a+bi` is `\sqrt{a^2+b^2}`. + of the complex number `a+bi` is `\sqrt{a^2+b^2}` - ``p = -Infinity`` or ``p = -oo``: the minimum of the - absolute values of the entries. - - ``p = 0`` : the number of nonzero entries in the vector. - - ``p`` is any other real number: for a vector `\vec{x}` - this method computes + absolute values of the entries + - ``p = 0``: the number of nonzero entries in the vector + - ``p`` any other real number: for a vector `\vec{x}` this method computes .. MATH:: @@ -470,7 +468,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): except Exception: raise ValueError("vector norm 'p' must be +/- infinity or a real number, not %s" % p) n = numpy.linalg.norm(self._vector_numpy, ord=p) - # p = 0 returns integer *count* of non-zero entries + # p = 0 returns integer *count* of nonzero entries return RDF(n) ############################# @@ -498,7 +496,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): INPUT: - - ``population`` -- If False, calculate the sample variance. + - ``population`` -- if ``False``, calculate the sample variance EXAMPLES:: @@ -523,7 +521,9 @@ cdef class Vector_double_dense(Vector_numpy_dense): Calculate the standard deviation of entries of the vector. INPUT: - population -- If False, calculate the sample standard deviation. + + - ``population`` -- If ``False``, calculate the sample standard + deviation EXAMPLES:: @@ -567,7 +567,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): def prod(self): """ - Return the product of the entries of self. + Return the product of the entries of ``self``. EXAMPLES:: @@ -582,7 +582,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): def sum(self): """ - Return the sum of the entries of self. + Return the sum of the entries of ``self``. EXAMPLES:: diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 274f1c0dbff..3605f4cf865 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -196,7 +196,7 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): INPUT: - - ``copy``, ignored optional argument. + - ``copy`` -- ignored optional argument EXAMPLES:: @@ -307,7 +307,7 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): INPUT: - - singular -- \Singular interface instance (default: None) + - ``singular`` -- \Singular interface instance (default: ``None``) EXAMPLES:: diff --git a/src/sage/modules/vector_integer_sparse.pyx b/src/sage/modules/vector_integer_sparse.pyx index b647c22fb23..8484c0a6a93 100644 --- a/src/sage/modules/vector_integer_sparse.pyx +++ b/src/sage/modules/vector_integer_sparse.pyx @@ -87,12 +87,15 @@ cdef Py_ssize_t mpz_binary_search(mpz_t* v, Py_ssize_t n, mpz_t x, Py_ssize_t* i obtain an ordered array. INPUT: - v -- array of mpz_t (integer) - n -- integer (length of array v) - x -- mpz_t (integer) + + - ``v`` -- array of mpz_t (integer) + - ``n`` -- integer (length of array v) + - ``x`` -- mpz_t (integer) + OUTPUT: - position of x (as a Py_ssize_t) - ins -- (call be pointer), the insertion point if x is not found. + + position of x (as a Py_ssize_t) + ins -- (call be pointer), the insertion point if x is not found. """ cdef Py_ssize_t i, j, k, c if n == 0: @@ -127,7 +130,7 @@ cdef Py_ssize_t mpz_binary_search(mpz_t* v, Py_ssize_t n, mpz_t x, Py_ssize_t* i cdef int mpz_vector_get_entry(mpz_t ans, mpz_vector* v, Py_ssize_t n) except -1: """ Returns the n-th entry of the sparse vector v. This - would be v[n] in Python syntax. + would be ``v[n]`` in Python syntax. The return is done using the pointer ans, which is to an mpz_t that *must* have been initialized using mpz_init. @@ -153,7 +156,7 @@ cdef bint mpz_vector_is_entry_zero_unsafe(mpz_vector* v, Py_ssize_t n) noexcept: cdef object mpz_vector_to_list(mpz_vector* v): """ - Returns a Python list of 2-tuples (i,x), where x=v[i] runs + Return a Python list of 2-tuples (i,x), where ``x=v[i]`` runs through the nonzero elements of x, in order. """ cdef object X @@ -170,7 +173,7 @@ cdef object mpz_vector_to_list(mpz_vector* v): cdef int mpz_vector_set_entry(mpz_vector* v, Py_ssize_t n, mpz_t x) except -1: """ Set the n-th component of the sparse vector v equal to x. - This would be v[n] = x in Python syntax. + This would be ``v[n] = x`` in Python syntax. """ if n >= v.degree or n < 0: raise IndexError("Index (=%s) must be between 0 and %s." % (n, v.degree - 1)) diff --git a/src/sage/modules/vector_numpy_dense.pyx b/src/sage/modules/vector_numpy_dense.pyx index 9b16a6c354d..b6e6d37473f 100644 --- a/src/sage/modules/vector_numpy_dense.pyx +++ b/src/sage/modules/vector_numpy_dense.pyx @@ -53,7 +53,7 @@ cdef class Vector_numpy_dense(FreeModuleElement): def __cinit__(self, parent, entries, coerce=True, copy=True): """ - Set up a new vector + Set up a new vector. EXAMPLES:: @@ -70,7 +70,7 @@ cdef class Vector_numpy_dense(FreeModuleElement): cdef Vector_numpy_dense _new(self, numpy.ndarray vector_numpy): """ - Return a new vector with same parent as self. + Return a new vector with same parent as ``self``. """ cdef Vector_numpy_dense v v = self.__class__.__new__(self.__class__,self._parent,None,None,None) @@ -103,19 +103,19 @@ cdef class Vector_numpy_dense(FreeModuleElement): cdef bint is_dense_c(self) noexcept: """ - Return True (i.e., 1) if self is dense. + Return ``True`` (i.e., 1) if ``self`` is dense. """ return 1 cdef bint is_sparse_c(self) noexcept: """ - Return True (i.e., 1) if self is sparse. + Return ``True`` (i.e., 1) if ``self`` is sparse. """ return 0 def __copy__(self, copy=True): """ - Return a copy of the vector + Return a copy of the vector. EXAMPLES:: @@ -266,8 +266,9 @@ cdef class Vector_numpy_dense(FreeModuleElement): INPUT: - - ``dtype`` -- if specified, the `numpy dtype `_ - of the returned array. + - ``dtype`` -- if specified, the `numpy dtype + `_ of + the returned array EXAMPLES:: diff --git a/src/sage/modules/vector_rational_dense.pyx b/src/sage/modules/vector_rational_dense.pyx index 864628f10c7..22e3c67fcc3 100644 --- a/src/sage/modules/vector_rational_dense.pyx +++ b/src/sage/modules/vector_rational_dense.pyx @@ -234,7 +234,7 @@ cdef class Vector_rational_dense(free_module_element.FreeModuleElement): INPUT: - - ``copy``, ignored optional argument. + - ``copy`` -- ignored optional argument EXAMPLES:: diff --git a/src/sage/modules/vector_rational_sparse.pyx b/src/sage/modules/vector_rational_sparse.pyx index 2c661f34bab..fcdaf2b7cf8 100644 --- a/src/sage/modules/vector_rational_sparse.pyx +++ b/src/sage/modules/vector_rational_sparse.pyx @@ -94,12 +94,15 @@ cdef Py_ssize_t mpq_binary_search(mpq_t* v, Py_ssize_t n, mpq_t x, Py_ssize_t* i obtain an ordered array. INPUT: - v -- array of mpq_t (rational) - n -- integer (length of array v) - x -- mpq_t (rational) + + - ``v`` -- array of mpq_t (rational) + - ``n`` -- integer (length of array v) + - ``x`` -- mpq_t (rational) + OUTPUT: - position of x (as an Py_ssize_t) - ins -- (call be pointer), the insertion point if x is not found. + + position of x (as an Py_ssize_t) + ins -- (call be pointer), the insertion point if x is not found. """ cdef Py_ssize_t i, j, k, c if n == 0: @@ -133,11 +136,11 @@ cdef Py_ssize_t mpq_binary_search(mpq_t* v, Py_ssize_t n, mpq_t x, Py_ssize_t* i cdef int mpq_vector_get_entry(mpq_t ans, mpq_vector* v, Py_ssize_t n) except -1: """ - Returns the n-th entry of the sparse vector v. This - would be v[n] in Python syntax. + Return the n-th entry of the sparse vector v. This + would be ``v[n]`` in Python syntax. - The return is done using the pointer ans, which is to an mpq_t - that *must* have been initialized using mpq_init. + The return is done using the pointer ``ans``, which is to an ``mpq_t`` + that *must* have been initialized using ``mpq_init``. """ if n >= v.degree: raise IndexError("Index must be between 0 and %s." % (v.degree - 1)) @@ -160,7 +163,7 @@ cdef bint mpq_vector_is_entry_zero_unsafe(mpq_vector* v, Py_ssize_t n) noexcept: cdef object mpq_vector_to_list(mpq_vector* v): """ - Returns a Python list of 2-tuples (i,x), where x=v[i] runs + Return a Python list of 2-tuples (i,x), where ``x=v[i]`` runs through the nonzero elements of x, in order. """ cdef object X @@ -177,7 +180,7 @@ cdef object mpq_vector_to_list(mpq_vector* v): cdef int mpq_vector_set_entry(mpq_vector* v, Py_ssize_t n, mpq_t x) except -1: """ Set the n-th component of the sparse vector v equal to x. - This would be v[n] = x in Python syntax. + This would be ``v[n] = x`` in Python syntax. """ if n >= v.degree or n < 0: raise IndexError("Index must be between 0 and the degree minus 1.") @@ -250,7 +253,7 @@ mpq_init(mpq_set_tmp) cdef int mpq_vector_set_entry_str(mpq_vector* v, Py_ssize_t n, char *x_str) except -1: """ Set the n-th component of the sparse vector v equal to x. - This would be v[n] = x in Python syntax. + This would be ``v[n] = x`` in Python syntax. """ mpq_set_str(mpq_set_tmp, x_str, 0) mpq_vector_set_entry(v, n, mpq_set_tmp) diff --git a/src/sage/modules/vector_real_double_dense.pyx b/src/sage/modules/vector_real_double_dense.pyx index 0bedec59d58..8ed7210422b 100644 --- a/src/sage/modules/vector_real_double_dense.pyx +++ b/src/sage/modules/vector_real_double_dense.pyx @@ -62,7 +62,7 @@ cdef class Vector_real_double_dense(Vector_double_dense): def stats_skew(self): """ - Computes the skewness of a data set. + Compute the skewness of a data set. For normally distributed data, the skewness should be about 0. A skewness value > 0 means that there is more weight in the @@ -80,7 +80,7 @@ cdef class Vector_real_double_dense(Vector_double_dense): def __reduce__(self): """ - Pickling + Pickling. EXAMPLES:: diff --git a/src/sage/modules/vector_space_homspace.py b/src/sage/modules/vector_space_homspace.py index 1589e66d640..d18bfd769b4 100644 --- a/src/sage/modules/vector_space_homspace.py +++ b/src/sage/modules/vector_space_homspace.py @@ -254,7 +254,7 @@ def __call__(self, A, check=True, **kwds): INPUT: - ``A`` -- one of several possible inputs representing - a morphism from this vector space homspace. + a morphism from this vector space homspace: - a vector space morphism in this homspace - a matrix representation relative to the bases of the vector spaces, @@ -262,13 +262,12 @@ def __call__(self, A, check=True, **kwds): - a list or tuple containing images of the domain's basis vectors - a function from the domain to the codomain - - ``check`` (default: ``True``) -- ``True`` or ``False``, required for - compatibility with calls from - :meth:`sage.structure.parent.Parent.hom`. + - ``check`` -- boolean (default: ``True``); required for compatibility + with calls from :meth:`sage.structure.parent.Parent.hom` - - the keyword ``side`` can be assigned the values ``"left"`` or - ``"right"``. It corresponds to the side of vectors relative to the - matrix. + - the keyword ``side`` can be assigned the values ``'left'`` or + ``'right'``; it corresponds to the side of vectors relative to the + matrix EXAMPLES:: @@ -371,7 +370,7 @@ def __call__(self, A, check=True, **kwds): sage: H.zero().is_zero() True - Previously the above code resulted in a :class:`TypeError` because the + Previously the above code resulted in a :exc:`TypeError` because the dimensions of the matrix were incorrect. """ from .vector_space_morphism import VectorSpaceMorphism diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 460e8fba728..9eee6152585 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -345,7 +345,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): the same field that are the domain and codomain (respectively) of the linear transformation. - ``side`` is a keyword that is either 'left' or 'right'. + ``side`` is a keyword that is either ``'left'`` or ``'right'``. When a matrix is used to specify a linear transformation, as in the first two call formats below, you may specify if the function is given by matrix multiplication with @@ -781,7 +781,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): def is_VectorSpaceMorphism(x) -> bool: r""" - Returns ``True`` if ``x`` is a vector space morphism (a linear transformation). + Return ``True`` if ``x`` is a vector space morphism (a linear transformation). This function is deprecated. @@ -815,17 +815,17 @@ def is_VectorSpaceMorphism(x) -> bool: class VectorSpaceMorphism(free_module_morphism.FreeModuleMorphism): - def __init__(self, homspace, A, side="left"): + def __init__(self, homspace, A, side='left'): r""" Create a linear transformation, a morphism between vector spaces. INPUT: - - ``homspace`` -- a homspace (of vector spaces) to serve - as a parent for the linear transformation and a home for - the domain and codomain of the morphism - - ``A`` -- a matrix representing the linear transformation, - which will act on vectors placed to the left of the matrix + - ``homspace`` -- a homspace (of vector spaces) to serve + as a parent for the linear transformation and a home for + the domain and codomain of the morphism + - ``A`` -- a matrix representing the linear transformation, + which will act on vectors placed to the left of the matrix EXAMPLES: diff --git a/src/sage/modules/vector_symbolic_dense.py b/src/sage/modules/vector_symbolic_dense.py index b1d47f32966..e3d6524a921 100644 --- a/src/sage/modules/vector_symbolic_dense.py +++ b/src/sage/modules/vector_symbolic_dense.py @@ -59,7 +59,7 @@ def apply_map(phi): """ - Returns a function that applies phi to its argument. + Return a function that applies ``phi`` to its argument. EXAMPLES:: @@ -68,7 +68,6 @@ def apply_map(phi): sage: f = apply_map(lambda x: x+1) sage: f(v) (2, 3, 4) - """ def apply(self, *args, **kwds): """ diff --git a/src/sage/modules/vector_symbolic_sparse.py b/src/sage/modules/vector_symbolic_sparse.py index c0e7fc209b6..290aa282a85 100644 --- a/src/sage/modules/vector_symbolic_sparse.py +++ b/src/sage/modules/vector_symbolic_sparse.py @@ -61,7 +61,7 @@ def apply_map(phi): """ - Returns a function that applies phi to its argument. + Return a function that applies ``phi`` to its argument. EXAMPLES:: @@ -70,7 +70,6 @@ def apply_map(phi): sage: f = apply_map(lambda x: x+1) sage: f(v) (2, 3, 4) - """ def apply(self, *args, **kwds): """ diff --git a/src/sage/modules/with_basis/cell_module.py b/src/sage/modules/with_basis/cell_module.py index 2c5f54de21b..7c61057737c 100644 --- a/src/sage/modules/with_basis/cell_module.py +++ b/src/sage/modules/with_basis/cell_module.py @@ -234,7 +234,7 @@ def bilinear_form_matrix(self, ordering=None): @cached_method def nonzero_bilinear_form(self): """ - Return ``True`` if the bilinear form of ``self`` is non-zero. + Return ``True`` if the bilinear form of ``self`` is nonzero. EXAMPLES:: diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index 85428fc1f55..47e2fe1cc6f 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -31,7 +31,7 @@ from sage.categories.modules import _Fields cdef class IndexedFreeModuleElement(ModuleElement): r""" - Element class for :class:`~sage.combinat.free_module.CombinatorialFreeModule` + Element class for :class:`~sage.combinat.free_module.CombinatorialFreeModule`. TESTS:: @@ -235,10 +235,10 @@ cdef class IndexedFreeModuleElement(ModuleElement): INPUT: - - ``copy`` -- (default: ``True``) if ``self`` is internally - represented by a dictionary ``d``, then make a copy of ``d``; - if ``False``, then this can cause undesired behavior by - mutating ``d`` + - ``copy`` -- boolean (default: ``True``); if ``self`` is internally + represented by a dictionary ``d``, then make a copy of ``d``. + If ``False``, then this can cause undesired behavior by + mutating ``d``. EXAMPLES:: @@ -786,7 +786,7 @@ cdef class IndexedFreeModuleElement(ModuleElement): - ``new_base_ring`` -- a ring (default: ``None``) - ``order`` -- (optional) an ordering of the support of ``self`` - - ``sparse`` -- (default: ``False``) whether to return a sparse + - ``sparse`` -- boolean (default: ``False``); whether to return a sparse vector or a dense vector OUTPUT: a :func:`FreeModule` vector diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 7e7600f3069..5c4202419a5 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -257,7 +257,7 @@ def _invariant_map(g, x): # Give the intersection of kernels of the map `s*x-x` to determine when # `s*x = x` for all generators `s` of `S` - basis = M.annihilator_basis(S.gens(), action=_invariant_map, side="left") + basis = M.annihilator_basis(S.gens(), action=_invariant_map, side='left') super().__init__(Family(basis), support_order=M._compute_support_order(basis), @@ -310,9 +310,9 @@ def _repr_(self): M = M._module return f"({self._semigroup})-invariant submodule of {M}" - def _latex_(self): + def _latex_(self) -> str: r""" - Return a latex representaion of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -800,7 +800,7 @@ def __classcall_private__(cls, M, G, chi, sage: type(T) - Check the :class:`ValueError`:: + Check the :exc:`ValueError`:: sage: T = M.twisted_invariant_module(G, "ichigo", action_on_basis=action) Traceback (most recent call last): @@ -905,7 +905,7 @@ def proj_difference(g, x): basis = M.annihilator_basis(M.basis(), action=proj_difference, - side="left") + side='left') super().__init__(Family(basis), support_order=M._compute_support_order(basis), diff --git a/src/sage/modules/with_basis/meson.build b/src/sage/modules/with_basis/meson.build new file mode 100644 index 00000000000..1956c6ac99c --- /dev/null +++ b/src/sage/modules/with_basis/meson.build @@ -0,0 +1,24 @@ +py.install_sources( + 'all.py', + 'cell_module.py', + 'indexed_element.pxd', + 'invariant.py', + 'morphism.py', + 'representation.py', + 'subquotient.py', + subdir: 'sage/modules/with_basis', +) + +extension_data = {'indexed_element' : files('indexed_element.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/modules/with_basis', + install: true, + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 1e2e169b147..68ad2521493 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -133,10 +133,10 @@ class ModuleMorphism(Morphism): INPUT: - ``domain`` -- a parent in ``ModulesWithBasis(...)`` - - ``codomain`` -- a parent in ``Modules(...)``; - - ``category`` -- a category or ``None`` (default: `None``) + - ``codomain`` -- a parent in ``Modules(...)`` + - ``category`` -- a category or ``None`` (default: ``None``) - ``affine`` -- whether we define an affine module morphism - (default: ``False``). + (default: ``False``) Construct a module morphism from ``domain`` to ``codomain`` in the category ``category``. By default, the category is the first of @@ -164,7 +164,7 @@ class of ``self`` upon construction. """ def __init__(self, domain, codomain=None, category=None, affine=False): """ - Initialization of module morphisms + Initialization of module morphisms. TESTS:: @@ -252,7 +252,7 @@ def __init__(self, domain, function, codomain=None, category=None): """ TESTS:: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X'); x = X.basis() sage: from sage.modules.with_basis.morphism import ModuleMorphismFromFunction sage: def f(x): return 3*x sage: import __main__; __main__.f = f # Fake f being defined in a python module @@ -277,7 +277,7 @@ class ModuleMorphismByLinearity(ModuleMorphism): ``domain`` as ``position``-th argument - ``codomain`` -- a parent in ``Modules(...)`` (default: ``on_basis.codomain()``) - - ``position`` -- a non-negative integer (default: 0) + - ``position`` -- nonnegative integer (default: 0) - ``zero`` -- the zero of the codomain (defaults: ``codomain.zero()``) .. SEEALSO:: @@ -341,7 +341,6 @@ def _richcmp_(self, other, op): sage: h3 = X.module_morphism(on_basis=Y.monomial * abs, category=Modules(ZZ)) sage: f == g, f == h1, f == h2, f == h3, f == 1, 1 == f (True, False, False, False, False, False) - """ if op == op_EQ: return (self.__class__ is other.__class__ @@ -418,7 +417,7 @@ def __call__(self, *args): class TriangularModuleMorphism(ModuleMorphism): r""" - An abstract class for triangular module morphisms + An abstract class for triangular module morphisms. Let `X` and `Y` be modules over the same base ring, with distinguished bases `F` indexed by `I` and `G` indexed by `J`, @@ -446,10 +445,10 @@ class TriangularModuleMorphism(ModuleMorphism): - ``codomain`` -- a module with basis `Y` (default: `X`) - ``category`` -- a category, as for :class:`ModuleMorphism` - - ``triangular`` -- ``"upper"`` or ``"lower"`` (default: ``"upper"``) + - ``triangular`` -- ``'upper'`` or ``'lower'`` (default: ``'upper'``) - ``unitriangular`` -- boolean (default: ``False``) - As a shorthand, one may use ``unitriangular="lower"`` - for ``triangular="lower", unitriangular=True``. + As a shorthand, one may use ``unitriangular='lower'`` + for ``triangular='lower', unitriangular=True``. - ``key`` -- a comparison key on `J` (default: the usual comparison of elements of `J`) @@ -461,7 +460,7 @@ class TriangularModuleMorphism(ModuleMorphism): domain. This of course requires the domain to be finite dimensional. - - ``invertible`` -- a boolean or ``None`` (default: ``None``); can + - ``invertible`` -- boolean or ``None`` (default: ``None``); can be set to specify that `\phi` is known to be (or not to be) invertible. If the domain and codomain share the same indexing set, this is by default automatically set to ``True`` if @@ -477,9 +476,7 @@ class TriangularModuleMorphism(ModuleMorphism): - :class:`ModuleMorphismFromFunction` and :class:`TriangularModuleMorphism`. - OUTPUT: - - A morphism from `X` to `Y`. + OUTPUT: a morphism from `X` to `Y` .. WARNING:: @@ -496,10 +493,10 @@ class TriangularModuleMorphism(ModuleMorphism): two free `\QQ`-modules:: sage: I = range(1,200) - sage: X = CombinatorialFreeModule(QQ, I); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(QQ, I); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(QQ, I); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(QQ, I); Y.rename('Y'); y = Y.basis() sage: ut = Y.sum_of_monomials * divisors # This * is map composition. - sage: phi = X.module_morphism(ut, unitriangular="upper", codomain=Y) + sage: phi = X.module_morphism(ut, unitriangular='upper', codomain=Y) sage: phi(x[2]) B[1] + B[2] sage: phi(x[6]) @@ -517,9 +514,9 @@ class TriangularModuleMorphism(ModuleMorphism): A lower triangular (but not unitriangular) morphism:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() sage: def lt(i): return sum(j*x[j] for j in range(i,4)) - sage: phi = X.module_morphism(lt, triangular="lower", codomain=X) + sage: phi = X.module_morphism(lt, triangular='lower', codomain=X) sage: phi(x[2]) 2*B[2] + 3*B[3] sage: phi.preimage(x[2]) @@ -530,10 +527,10 @@ class TriangularModuleMorphism(ModuleMorphism): Using the ``key`` keyword, we can use triangularity even if the map becomes triangular only after a permutation of the basis:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) sage: perm = [0, 2, 1, 3] - sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, + sage: phi = X.module_morphism(ut, triangular='upper', codomain=X, ....: key=lambda a: perm[a]) sage: [phi(x[i]) for i in range(1, 4)] [B[1] + B[2], B[2], B[2] + B[3]] @@ -543,7 +540,7 @@ class TriangularModuleMorphism(ModuleMorphism): The same works in the lower-triangular case:: sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i]) - sage: phi = X.module_morphism(lt, triangular="lower", codomain=X, + sage: phi = X.module_morphism(lt, triangular='lower', codomain=X, ....: key=lambda a: perm[a]) sage: [phi(x[i]) for i in range(1, 4)] [B[1], B[1] + B[2] + B[3], B[3]] @@ -557,7 +554,7 @@ class TriangularModuleMorphism(ModuleMorphism): sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis() sage: ult = lambda i: sum( y[j] for j in range(i+1,6) ) - sage: phi = X.module_morphism(ult, unitriangular="lower", codomain=Y, + sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi(x[2]) B[3] + B[4] + B[5] @@ -569,13 +566,13 @@ class TriangularModuleMorphism(ModuleMorphism): them has to be permuted in order to render the morphism triangular. For example:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() sage: def ut(i): ....: return (x[3] if i == 1 else x[1] if i == 2 ....: else x[1] + x[2]) sage: def perm(i): ....: return (2 if i == 1 else 3 if i == 2 else 1) - sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, + sage: phi = X.module_morphism(ut, triangular='upper', codomain=X, ....: inverse_on_support=perm) sage: [phi(x[i]) for i in range(1, 4)] [B[3], B[1], B[1] + B[2]] @@ -584,13 +581,13 @@ class TriangularModuleMorphism(ModuleMorphism): The same works if the permutation induces lower triangularity:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() sage: def lt(i): ....: return (x[3] if i == 1 else x[2] if i == 2 ....: else x[1] + x[2]) sage: def perm(i): ....: return 4 - i - sage: phi = X.module_morphism(lt, triangular="lower", codomain=X, + sage: phi = X.module_morphism(lt, triangular='lower', codomain=X, ....: inverse_on_support=perm) sage: [phi(x[i]) for i in range(1, 4)] [B[3], B[2], B[1] + B[2]] @@ -603,8 +600,8 @@ class TriangularModuleMorphism(ModuleMorphism): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3, 4]); y = Y.basis() sage: ut = lambda i: sum( y[j] for j in range(1,i+2) ) - sage: phi = X.module_morphism(ut, triangular="upper", codomain=Y, - ....: inverse_on_support="compute") + sage: phi = X.module_morphism(ut, triangular='upper', codomain=Y, + ....: inverse_on_support='compute') sage: tx = "{} {} {}" sage: for j in Y.basis().keys(): ....: i = phi._inverse_on_support(j) @@ -616,7 +613,7 @@ class TriangularModuleMorphism(ModuleMorphism): The ``inverse_on_basis`` and ``key`` keywords can be combined:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: x = X.basis() sage: def ut(i): ....: return (2*x[2] + 3*x[3] if i == 1 @@ -625,22 +622,22 @@ class TriangularModuleMorphism(ModuleMorphism): sage: def perm(i): ....: return (2 if i == 1 else 3 if i == 2 else 1) sage: perverse_key = lambda a: (a - 2) % 3 - sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, + sage: phi = X.module_morphism(ut, triangular='upper', codomain=X, ....: inverse_on_support=perm, key=perverse_key) sage: [phi(x[i]) for i in range(1, 4)] [2*B[2] + 3*B[3], B[1] + B[2] + B[3], 4*B[2]] sage: [phi.preimage(x[i]) for i in range(1, 4)] [-1/3*B[1] + B[2] - 1/12*B[3], 1/4*B[3], 1/3*B[1] - 1/6*B[3]] """ - def __init__(self, triangular="upper", unitriangular=False, + def __init__(self, triangular='upper', unitriangular=False, key=None, inverse=None, inverse_on_support=identity, invertible=None): """ TESTS:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() sage: def lt(i): return sum(j*x[j] for j in range(i,4)) sage: import __main__; __main__.lt = lt # Fake lt being defined in a python module - sage: phi = X.module_morphism(lt, triangular="lower", codomain=X) + sage: phi = X.module_morphism(lt, triangular='lower', codomain=X) sage: phi.__class__ sage: phi._invertible @@ -649,14 +646,14 @@ def __init__(self, triangular="upper", unitriangular=False, With the option ``compute``:: - sage: phi = X.module_morphism(lt, triangular="lower", codomain=X, - ....: inverse_on_support="compute") + sage: phi = X.module_morphism(lt, triangular='lower', codomain=X, + ....: inverse_on_support='compute') sage: TestSuite(phi).run(skip=["_test_pickling"]) Pickling works in Python3 (:issue:`17957`):: - sage: phi = X.module_morphism(lt, triangular="lower", codomain=X, - ....: inverse_on_support="compute") + sage: phi = X.module_morphism(lt, triangular='lower', codomain=X, + ....: inverse_on_support='compute') sage: loads(dumps(phi)) Generic endomorphism of X sage: phi._inverse_on_support @@ -701,22 +698,21 @@ def _richcmp_(self, other, op): TESTS:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) sage: perm = [0, 2, 1, 3] sage: our_key = lambda a: perm[a] - sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, key=our_key) + sage: phi = X.module_morphism(ut, triangular='upper', codomain=X, key=our_key) sage: def ut2(i): return (x[1] + 7*x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) - sage: phi2 = X.module_morphism(ut2, triangular="upper", codomain=X, key=our_key) + sage: phi2 = X.module_morphism(ut2, triangular='upper', codomain=X, key=our_key) sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i]) - sage: psi = X.module_morphism(lt, triangular="lower", codomain=X, key=our_key) + sage: psi = X.module_morphism(lt, triangular='lower', codomain=X, key=our_key) sage: phi == phi True sage: phi == phi2 False sage: phi == psi False - """ if op == op_EQ: return (self.__class__ is other.__class__ @@ -731,7 +727,7 @@ def _richcmp_(self, other, op): def _test_triangular(self, **options): """ - Test that ``self`` is actually triangular + Test that ``self`` is actually triangular. See also: :class:`sage.misc.sage_unittest.TestSuite`. @@ -740,11 +736,11 @@ def _test_triangular(self, **options): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis() sage: lt = lambda i: sum( y[j] for j in range(i,4) ) - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y) + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y) sage: phi._test_triangular() sage: lt = lambda i: sum( y[j] for j in range(i+1,4) ) - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y) + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y) sage: phi._test_triangular() Traceback (most recent call last): ... @@ -753,12 +749,12 @@ def _test_triangular(self, **options): sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis() sage: ult = lambda i: sum( y[j] for j in range(i+1,6) ) - sage: phi = X.module_morphism(ult, unitriangular="lower", codomain=Y, + sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi._test_triangular() sage: ult = lambda i: sum( 2*y[j] for j in range(i+1,6) ) - sage: phi = X.module_morphism(ult, unitriangular="lower", codomain=Y, + sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi._test_triangular() Traceback (most recent call last): @@ -793,11 +789,11 @@ def __invert__(self): sage: ut = lambda i: sum(j*y[j] for j in range(1,i+1)) # upper sage: lt = lambda i: sum(j*y[j] for j in range(i,4 )) # lower sage: f_uut = X.module_morphism(uut, codomain=Y, - ....: unitriangular="upper") + ....: unitriangular='upper') sage: f_ult = X.module_morphism(ult, codomain=Y, - ....: unitriangular="lower") - sage: f_ut = X.module_morphism(ut, codomain=Y, triangular="upper") - sage: f_lt = X.module_morphism(lt, codomain=Y, triangular="lower") + ....: unitriangular='lower') + sage: f_ut = X.module_morphism(ut, codomain=Y, triangular='upper') + sage: f_lt = X.module_morphism(lt, codomain=Y, triangular='lower') sage: (~f_uut)(y[2]) -B[1] + B[2] sage: (~f_ult)(y[2]) @@ -819,7 +815,7 @@ def section(self): Return the section (partial inverse) of ``self``. This returns a partial triangular morphism which is a section of - ``self``. The section morphism raises a :class:`ValueError` if + ``self``. The section morphism raises a :exc:`ValueError` if asked to apply on an element which is not in the image of ``self``. EXAMPLES:: @@ -828,7 +824,7 @@ def section(self): sage: X.rename('X') sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis() sage: ult = lambda i: sum( y[j] for j in range(i+1,6) ) # uni-lower - sage: phi = X.module_morphism(ult, triangular="lower", codomain=Y, + sage: phi = X.module_morphism(ult, triangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: ~phi Traceback (most recent call last): @@ -879,7 +875,7 @@ def _invert_on_basis(self, i): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis() sage: ult = lambda i: sum( y[j] for j in range(i,4) ) # uni-lower - sage: phi = X.module_morphism(ult, triangular="lower", codomain=Y) + sage: phi = X.module_morphism(ult, triangular='lower', codomain=Y) sage: phi._invert_on_basis(2) B[2] - B[3] """ @@ -894,7 +890,7 @@ def preimage(self, f): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis() sage: ult = lambda i: sum( y[j] for j in range(i,4) ) # uni-lower - sage: phi = X.module_morphism(ult, triangular="lower", codomain=Y) + sage: phi = X.module_morphism(ult, triangular='lower', codomain=Y) sage: phi.preimage(y[1] + y[2]) B[1] - B[3] @@ -904,7 +900,7 @@ def preimage(self, f): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3, 4]); y = Y.basis() sage: lt = lambda i: sum( y[j] for j in range(i,5) ) - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y) + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y) sage: phi.preimage(y[1] + y[2]) B[1] - B[3] @@ -914,7 +910,7 @@ def preimage(self, f): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3, 4, 5]); y = Y.basis() sage: lt = lambda i: sum( y[j] for j in range(i+1,6) ) # lower - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y, + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi(x[1]) B[2] + B[3] + B[4] + B[5] @@ -943,7 +939,7 @@ def preimage(self, f): sage: X = CombinatorialFreeModule(ZZ, [1, 2, 3]); x = X.basis() sage: Y = CombinatorialFreeModule(ZZ, [1, 2, 3]); y = Y.basis() sage: lt = lambda i: sum( 2* y[j] for j in range(i,4) ) # lower - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y) + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y) sage: phi.preimage(2*y[1] + 2*y[2]) B[1] - B[3] @@ -1006,7 +1002,7 @@ def coreduced(self, y): sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis() sage: ult = lambda i: sum( y[j] for j in range(i+1,6) ) - sage: phi = X.module_morphism(ult, unitriangular="lower", codomain=Y, + sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: [phi(v) for v in X.basis()] [B[2] + B[3] + B[4] + B[5], @@ -1020,7 +1016,7 @@ def coreduced(self, y): Now with a non unitriangular morphism:: sage: lt = lambda i: sum( j*y[j] for j in range(i+1,6) ) - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y, + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: [phi(v) for v in X.basis()] [2*B[2] + 3*B[3] + 4*B[4] + 5*B[5], @@ -1036,14 +1032,14 @@ def coreduced(self, y): sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); x = X.basis() sage: Y = CombinatorialFreeModule(ZZ, [1,2,3,4,5]); y = Y.basis() - sage: phi = X.module_morphism(ult, unitriangular="lower", codomain=Y, + sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: [phi.coreduced(y[1]-2*y[4])] [B[1] + 2*B[5]] sage: [phi.coreduced(v) for v in y] [B[1], 0, 0, -B[5], B[5]] - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y, + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: [phi.coreduced(v) for v in y] Traceback (most recent call last): @@ -1105,12 +1101,12 @@ def cokernel_basis_indices(self): sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); x = X.basis() sage: Y = CombinatorialFreeModule(ZZ, [1,2,3,4,5]); y = Y.basis() sage: uut = lambda i: sum( y[j] for j in range(i+1,6) ) # uni-upper - sage: phi = X.module_morphism(uut, unitriangular="upper", codomain=Y, + sage: phi = X.module_morphism(uut, unitriangular='upper', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi.cokernel_basis_indices() [1, 5] - sage: phi = X.module_morphism(uut, triangular="upper", codomain=Y, + sage: phi = X.module_morphism(uut, triangular='upper', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi.cokernel_basis_indices() Traceback (most recent call last): @@ -1118,7 +1114,7 @@ def cokernel_basis_indices(self): NotImplementedError: cokernel_basis_indices for a triangular but not unitriangular morphism over a ring sage: Y = CombinatorialFreeModule(ZZ, NN); y = Y.basis() - sage: phi = X.module_morphism(uut, unitriangular="upper", codomain=Y, + sage: phi = X.module_morphism(uut, unitriangular='upper', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phi.cokernel_basis_indices() Traceback (most recent call last): @@ -1145,7 +1141,7 @@ def cokernel_projection(self, category=None): sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis() sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis() sage: lt = lambda i: sum( y[j] for j in range(i+1,6) ) # lower - sage: phi = X.module_morphism(lt, triangular="lower", codomain=Y, + sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y, ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None) sage: phipro = phi.cokernel_projection() sage: phipro(y[1] + y[2]) @@ -1265,7 +1261,7 @@ class ModuleMorphismFromMatrix(ModuleMorphismByLinearity): - ``matrix`` -- a matrix with base ring `R` and dimensions matching that of `F` and `G`, respectively - - ``side`` -- "left" or "right" (default: "left") + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``) If ``side`` is "left", this morphism is considered as acting on the left; i.e. each column of the matrix @@ -1276,8 +1272,8 @@ class ModuleMorphismFromMatrix(ModuleMorphismByLinearity): EXAMPLES:: - sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y'); y = Y.basis() sage: m = matrix([[1,2],[3,5]]) sage: phi = X.module_morphism(matrix=m, codomain=Y) sage: phi.parent() @@ -1290,7 +1286,7 @@ class ModuleMorphismFromMatrix(ModuleMorphismByLinearity): 2*B[3] + 5*B[4] sage: m = matrix([[1,2],[3,5]]) - sage: phi = X.module_morphism(matrix=m, codomain=Y, side="right", + sage: phi = X.module_morphism(matrix=m, codomain=Y, side='right', ....: category=Modules(ZZ).WithBasis()) sage: phi.parent() Set of Morphisms from X to Y @@ -1305,20 +1301,20 @@ class ModuleMorphismFromMatrix(ModuleMorphismByLinearity): Possibly implement rank, addition, multiplication, matrix, etc, from the stored matrix. """ - def __init__(self, domain, matrix, codomain=None, category=None, side="left"): + def __init__(self, domain, matrix, codomain=None, category=None, side='left'): r""" Initialize ``self``. TESTS:: sage: from sage.modules.with_basis.morphism import ModuleMorphismFromMatrix - sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y'); y = Y.basis() sage: m = matrix([[1,2],[3,5]]) - sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side="right") + sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side='right') sage: phi.__class__ - sage: phi.matrix(side="right") == m + sage: phi.matrix(side='right') == m True sage: TestSuite(phi).run(skip=["_test_pickling"]) @@ -1336,7 +1332,7 @@ def __init__(self, domain, matrix, codomain=None, category=None, side="left"): [1 2] [3 5] - sage: phi = ModuleMorphismFromMatrix(matrix=m, side="left", + sage: phi = ModuleMorphismFromMatrix(matrix=m, side='left', ....: domain=X, codomain=Y) sage: phi._matrix [1 3] @@ -1377,17 +1373,17 @@ def _richcmp_(self, other, op): TESTS:: sage: from sage.modules.with_basis.morphism import ModuleMorphismFromMatrix - sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y'); y = Y.basis() sage: m = matrix([[1,2],[3,5]]) - sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side="right") - sage: phi2 = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side="right") + sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side='right') + sage: phi2 = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side='right') sage: phi == phi2 True sage: phi is phi2 False sage: m2 = matrix([[1,2],[4,5]]) - sage: phi2 = ModuleMorphismFromMatrix(matrix=m2, domain=X, codomain=Y, side="right") + sage: phi2 = ModuleMorphismFromMatrix(matrix=m2, domain=X, codomain=Y, side='right') sage: phi == phi2 False """ @@ -1435,7 +1431,7 @@ class DiagonalModuleMorphism(ModuleMorphismByLinearity): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: phi = X.module_morphism(diagonal=factorial, codomain=X) sage: x = X.basis() sage: phi(x[1]), phi(x[2]), phi(x[3]) @@ -1447,7 +1443,7 @@ def __init__(self, domain, diagonal, codomain=None, category=None): TESTS:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: phi = X.module_morphism(diagonal=factorial, codomain=X) sage: phi.__class__ @@ -1474,14 +1470,13 @@ def _richcmp_(self, other, op): TESTS:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') sage: phi = X.module_morphism(diagonal=factorial, codomain=X) sage: psi = X.module_morphism(diagonal=factorial, codomain=X) sage: phi == psi True sage: phi is psi False - """ if op == op_EQ: return (self.__class__ is other.__class__ @@ -1496,8 +1491,8 @@ def _on_basis(self, i): TESTS:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); Y.rename('Y'); y = Y.basis() sage: phi = X.module_morphism(diagonal=factorial, codomain=X) sage: phi._on_basis(3) 6*B[3] @@ -1510,8 +1505,8 @@ def __invert__(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); Y.rename("Y"); y = Y.basis() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() + sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); Y.rename('Y'); y = Y.basis() sage: phi = X.module_morphism(diagonal=factorial, codomain=X) sage: phi_inv = ~phi sage: phi_inv diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index b7d09675a05..7e67d3ec750 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -34,8 +34,8 @@ class Representation_abstract: INPUT: - ``semigroup`` -- a semigroup - - ``side`` -- (default: ``"left"``) whether this is a - ``"left"`` or ``"right"`` representation + - ``side`` -- (default: ``'left'``) whether this is a + ``'left'`` or ``'right'`` representation - ``algebra`` -- (default: ``semigroup.algebra(self.base_ring())``) the semigroup algebra @@ -125,9 +125,7 @@ def side(self): """ Return whether ``self`` is a left, right, or two-sided representation. - OUTPUT: - - - the string ``"left"``, ``"right"``, or ``"twosided"`` + OUTPUT: the string ``'left'``, ``'right'``, or ``'twosided'`` EXAMPLES:: @@ -135,7 +133,7 @@ def side(self): sage: R = G.regular_representation() sage: R.side() 'left' - sage: S = G.regular_representation(side="right") + sage: S = G.regular_representation(side='right') sage: S.side() 'right' sage: R = G.sign_representation() @@ -171,9 +169,7 @@ def invariant_module(self, S=None, **kwargs): Two sided actions are considered as left actions for the invariant module. - OUTPUT: - - - :class:`~sage.modules.with_basis.invariant.FiniteDimensionalInvariantModule` + OUTPUT: :class:`~sage.modules.with_basis.invariant.FiniteDimensionalInvariantModule` EXAMPLES:: @@ -214,16 +210,14 @@ def twisted_invariant_module(self, chi, G=None, **kwargs): INPUT: - - ``chi`` -- a list/tuple of character values or an instance + - ``chi`` -- list/tuple of character values or an instance of :class:`~sage.groups.class_function.ClassFunction_gap` - ``G`` -- a finitely-generated semigroup (default: the semigroup this is a representation of) This also accepts the first argument to be the group. - OUTPUT: - - - :class:`~sage.modules.with_basis.invariant.FiniteDimensionalTwistedInvariantModule` + OUTPUT: :class:`~sage.modules.with_basis.invariant.FiniteDimensionalTwistedInvariantModule` EXAMPLES:: @@ -262,8 +256,8 @@ def representation_matrix(self, g, side=None, sparse=False): sage: S3 = SymmetricGroup(3) sage: g = S3.an_element(); g (2,3) - sage: L = S3.regular_representation(side="left") - sage: R = S3.regular_representation(side="right") + sage: L = S3.regular_representation(side='left') + sage: R = S3.regular_representation(side='right') sage: R.representation_matrix(g) [0 0 0 1 0 0] [0 0 0 0 0 1] @@ -431,7 +425,7 @@ def brauer_character(self): sage: T.brauer_character() (0, 0, 0) - sage: W = CoxeterGroup(['D', 4], implementation="permutation") + sage: W = CoxeterGroup(['D', 4], implementation='permutation') sage: R = W.reflection_representation(GF(2)) sage: R.brauer_character() (4, 1) @@ -676,8 +670,8 @@ def subrepresentation(self, gens, check=True, already_echelonized=False, - ``gens`` -- the generators of the submodule - ``check`` -- ignored - ``already_echelonized`` -- (default: ``False``) whether - the elements of ``gens`` are already in (not necessarily - reduced) echelon form + the elements of ``gens`` are already in (not necessarily + reduced) echelon form - ``is_closed`` -- (keyword only; default: ``False``) whether ``gens`` already spans the subspace closed under the semigroup action @@ -841,10 +835,10 @@ def _composition_series_data(self): data = {i: lift(prev._basis[i]) for i in prev._basis.keys()} lift = prev.module_morphism(data.__getitem__, codomain=self, - triangular="lower", + triangular='lower', unitriangular=False, key=W._support_key, - inverse_on_support="compute") + inverse_on_support='compute') retract = lift.section() ret.append(ret[-1].subrepresentation([], is_closed=True)) @@ -960,7 +954,7 @@ def _acted_upon_(self, scalar, self_on_left=False): s2*s1*s2 + 2*s1*s2 + s2 + 3 sage: G = groups.misc.WeylGroup(['B',2], prefix='s') - sage: R = G.regular_representation(side="right") + sage: R = G.regular_representation(side='right') sage: s1,s2 = G.gens() sage: x = R.an_element(); x 2*s2*s1*s2 + s1*s2 + 3*s2 + 1 @@ -1052,8 +1046,8 @@ class Representation(Representation_abstract, CombinatorialFreeModule): ``g`` is an element of the semigroup and ``m`` is an element of the indexing set for the basis, and returns the result of ``g`` acting on ``m`` - - ``side`` -- (default: ``"left"``) whether this is a - ``"left"`` or ``"right"`` representation + - ``side`` -- (default: ``'left'``) whether this is a + ``'left'`` or ``'right'`` representation EXAMPLES: @@ -1098,7 +1092,7 @@ class Representation(Representation_abstract, CombinatorialFreeModule): - :wikipedia:`Group_representation` """ - def __init__(self, semigroup, module, on_basis, side="left", **kwargs): + def __init__(self, semigroup, module, on_basis, side='left', **kwargs): """ Initialize ``self``. @@ -1184,7 +1178,7 @@ def _test_representation(self, **options): sage: M = CombinatorialFreeModule(QQ, ['v']) sage: def on_basis(g, m): ....: return M.term(m, (-1)**g.length()) - sage: R = G.representation(M, on_basis, side="right") + sage: R = G.representation(M, on_basis, side='right') sage: R._test_representation(max_runs=500) """ from sage.misc.functional import sqrt @@ -1495,7 +1489,7 @@ def __classcall_private__(cls, reps, **options): reps = sum((module._sets if isinstance(module, Representation_Tensor) else (module,) for module in reps), ()) if all('FiniteDimensional' in M.category().axioms() for M in reps): options['category'] = options['category'].FiniteDimensional() - return super(Representation_Tensor, cls).__classcall__(cls, reps, **options) + return super().__classcall__(cls, reps, **options) def __init__(self, reps, **options): r""" @@ -1527,8 +1521,8 @@ def _semigroup_action(self, g, vec, vec_on_left): EXAMPLES:: sage: S3 = SymmetricGroup(3) - sage: L = S3.regular_representation(side="left") - sage: R = S3.regular_representation(side="right") + sage: L = S3.regular_representation(side='left') + sage: R = S3.regular_representation(side='right') sage: T = tensor([R, L]) sage: g = S3.an_element(); g (2,3) @@ -1564,14 +1558,14 @@ def __init__(self, rep, degree=None, category=None, **options): EXAMPLES:: sage: G = groups.matrix.GL(3, 2) - sage: R = G.regular_representation(side="right") + sage: R = G.regular_representation(side='right') sage: E2 = R.exterior_power(2) sage: E2.category() Category of finite dimensional modules with basis over Integer Ring sage: TestSuite(E2).run() sage: G = groups.matrix.GL(2, 3) - sage: L = G.regular_representation(side="left") + sage: L = G.regular_representation(side='left') sage: E48 = L.exterior_power(48) sage: TestSuite(E48).run() @@ -1732,7 +1726,7 @@ def _from_repr_to_ext(self, elt): EXAMPLES:: sage: G = groups.matrix.GL(2, 2) - sage: L = G.regular_representation(side="left") + sage: L = G.regular_representation(side='left') sage: E = L.exterior_power() sage: E._from_repr_to_ext(sum(i*b for i,b in enumerate(L.basis(), start=1))) e0 + 2*e1 + 3*e2 + 4*e3 + 5*e4 + 6*e5 @@ -1751,7 +1745,7 @@ def _semigroup_action(self, g, vec, vec_on_left): sage: DC3 = groups.permutation.DiCyclic(3) sage: g = DC3.an_element(); g (1,4,2,3)(5,6) - sage: R = DC3.regular_representation(side="right") + sage: R = DC3.regular_representation(side='right') sage: E2 = R.exterior_power(2) sage: vec = E2.an_element(); vec 2*()*(5,6,7) + 2*()*(5,7,6) + 3*()*(1,2)(3,4) @@ -1774,7 +1768,7 @@ def _action_on_basis(self, g, b, vec_on_left): sage: S3 = SymmetricGroup(3) sage: g = S3.an_element(); g (2,3) - sage: L = S3.regular_representation(side="left") + sage: L = S3.regular_representation(side='left') sage: E2 = L.exterior_power(2) sage: vec = E2.an_element(); vec 2*()*(1,3,2) + 2*()*(1,2,3) + 3*()*(2,3) @@ -1810,14 +1804,14 @@ def __init__(self, rep, degree=None, category=None, **options): EXAMPLES:: sage: G = groups.matrix.GL(3, 2) - sage: R = G.regular_representation(side="right") + sage: R = G.regular_representation(side='right') sage: E0 = R.exterior_power(0) sage: E0.category() Category of finite dimensional algebras with basis over Integer Ring sage: TestSuite(E0).run() sage: G = groups.matrix.GL(2, 3) - sage: L = G.regular_representation(side="left") + sage: L = G.regular_representation(side='left') sage: E = L.exterior_power() sage: E.category() Category of finite dimensional algebras with basis over Integer Ring @@ -1836,7 +1830,7 @@ def one_basis(self): EXAMPLES:: sage: S3 = SymmetricGroup(3) - sage: L = S3.regular_representation(side="left") + sage: L = S3.regular_representation(side='left') sage: E = L.exterior_power() sage: E.one_basis() 0 @@ -1853,7 +1847,7 @@ def product_on_basis(self, x, y): EXAMPLES:: sage: S3 = SymmetricGroup(3) - sage: L = S3.regular_representation(side="left") + sage: L = S3.regular_representation(side='left') sage: E = L.exterior_power() sage: B = list(E.basis()) sage: B[:7] @@ -1877,7 +1871,7 @@ def __init__(self, rep, degree, **options): EXAMPLES:: sage: G = groups.matrix.GL(3, 2) - sage: R = G.regular_representation(side="right") + sage: R = G.regular_representation(side='right') sage: S2 = R.symmetric_power(2) sage: TestSuite(S2).run() sage: S0 = R.symmetric_power(0) @@ -2063,7 +2057,7 @@ def _from_repr_to_sym(self, elt): EXAMPLES:: sage: G = groups.matrix.GL(2, 2) - sage: L = G.regular_representation(side="left") + sage: L = G.regular_representation(side='left') sage: S3L = L.symmetric_power(3) sage: S3L._from_repr_to_sym(sum(i*b for i,b in enumerate(L.basis(), start=1))) e0 + 2*e1 + 3*e2 + 4*e3 + 5*e4 + 6*e5 @@ -2081,7 +2075,7 @@ def _semigroup_action(self, g, vec, vec_on_left): sage: DC3 = groups.permutation.DiCyclic(3) sage: g = DC3.an_element(); g (1,4,2,3)(5,6) - sage: R = DC3.regular_representation(side="right") + sage: R = DC3.regular_representation(side='right') sage: S2L = R.symmetric_power(2) sage: vec = S2L.an_element(); vec 3*()*(5,7,6) + 2*()*(5,6,7) + 2*()^2 @@ -2104,7 +2098,7 @@ def _action_on_basis(self, g, b, vec_on_left): sage: S3 = SymmetricGroup(3) sage: g = S3.an_element(); g (2,3) - sage: L = S3.regular_representation(side="left") + sage: L = S3.regular_representation(side='left') sage: S2L = L.symmetric_power(2) sage: vec = S2L.an_element(); vec 3*()*(1,2,3) + 2*()*(1,3,2) + 2*()^2 @@ -2144,14 +2138,14 @@ class RegularRepresentation(Representation): - ``semigroup`` -- a semigroup - ``base_ring`` -- the base ring for the representation - - ``side`` -- (default: ``"left"``) whether this is a - ``"left"`` or ``"right"`` representation + - ``side`` -- (default: ``'left'``) whether this is a + ``'left'`` or ``'right'`` representation REFERENCES: - :wikipedia:`Regular_representation` """ - def __init__(self, semigroup, base_ring, side="left"): + def __init__(self, semigroup, base_ring, side='left'): """ Initialize ``self``. @@ -2178,7 +2172,7 @@ def _repr_(self): sage: G.regular_representation() Left Regular Representation of Dihedral group of order 8 as a permutation group over Integer Ring - sage: G.regular_representation(side="right") + sage: G.regular_representation(side='right') Right Regular Representation of Dihedral group of order 8 as a permutation group over Integer Ring """ @@ -2207,7 +2201,7 @@ def _right_on_basis(self, g, m): EXAMPLES:: sage: G = groups.permutation.Dihedral(4) - sage: R = G.regular_representation(side="right") + sage: R = G.regular_representation(side='right') sage: R._test_representation() # indirect doctest """ return self.monomial(m * g) diff --git a/src/sage/modules/with_basis/subquotient.py b/src/sage/modules/with_basis/subquotient.py index 48a235b4ab9..d914ba88f0c 100644 --- a/src/sage/modules/with_basis/subquotient.py +++ b/src/sage/modules/with_basis/subquotient.py @@ -89,7 +89,7 @@ def __init__(self, submodule, category, *args, **opts): TESTS:: sage: from sage.modules.with_basis.subquotient import QuotientModuleWithBasis - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: I = X.submodule( (x[0]-x[1], x[1]-x[2]) ) sage: Y = QuotientModuleWithBasis(I) sage: Y.print_options(prefix='y') @@ -115,7 +115,7 @@ def ambient(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])) sage: Y.ambient() is X True @@ -132,7 +132,7 @@ def lift(self, x): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])); y = Y.basis() sage: Y.lift(y[2]) x[2] @@ -150,7 +150,7 @@ def retract(self, x): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])); y = Y.basis() sage: Y.print_options(prefix='y') sage: Y.retract(x[0]) @@ -231,7 +231,7 @@ def __init__(self, basis, support_order, ambient, unitriangular, category, TESTS:: sage: from sage.modules.with_basis.subquotient import SubmoduleWithBasis - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: ybas = (x[0]-x[1], x[1]-x[2]) sage: Y = SubmoduleWithBasis(ybas, [0, 1, 2], X) sage: Y.print_options(prefix='y') @@ -287,7 +287,7 @@ def lift(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: Y = X.submodule((x[0]-x[1], x[1]-x[2]), already_echelonized=True); y = Y.basis() sage: Y.lift Generic morphism: @@ -300,10 +300,10 @@ def lift(self): """ return self.module_morphism(self.lift_on_basis, codomain=self._ambient, - triangular="lower", + triangular='lower', unitriangular=self._unitriangular, key=self._support_key, - inverse_on_support="compute") + inverse_on_support='compute') @lazy_attribute def reduce(self): @@ -315,7 +315,7 @@ def reduce(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: Y = X.submodule((x[0]-x[1], x[1]-x[2]), already_echelonized=True) sage: Y.reduce Generic endomorphism of Free module generated by {0, 1, 2} over Rational Field @@ -338,7 +338,7 @@ def retract(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis() + sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x'); x = X.basis() sage: Y = X.submodule((x[0]-x[1], x[1]-x[2]), already_echelonized=True) sage: Y.print_options(prefix='y') sage: Y.retract @@ -661,7 +661,7 @@ def subspace(self, gens, *args, **opts): INPUT: - - ``gens`` -- a list or family of elements of ``self`` + - ``gens`` -- list or family of elements of ``self`` For additional optional arguments, see :meth:`ModulesWithBasis.ParentMethods.submodule`. diff --git a/src/sage/monoids/automatic_semigroup.py b/src/sage/monoids/automatic_semigroup.py index 4f351d372ef..c4926239f8d 100644 --- a/src/sage/monoids/automatic_semigroup.py +++ b/src/sage/monoids/automatic_semigroup.py @@ -117,7 +117,7 @@ class AutomaticSemigroup(UniqueRepresentation, Parent): [1, 3, 5, 9] sage: # needs sage.graphs - sage: G = M.cayley_graph(side="twosided"); G + sage: G = M.cayley_graph(side='twosided'); G Looped multi-digraph on 4 vertices sage: G.edges(sort=True, key=str) [([1, 1], [1, 1], (2, 'left')), @@ -184,8 +184,8 @@ class AutomaticSemigroup(UniqueRepresentation, Parent): Let us construct and play with the 0-Hecke Monoid:: sage: # needs sage.graphs sage.modules - sage: W = WeylGroup(['A',4]); W.rename("W") - sage: ambient_monoid = FiniteSetMaps(W, action="right") + sage: W = WeylGroup(['A',4]); W.rename('W') + sage: ambient_monoid = FiniteSetMaps(W, action='right') sage: pi = W.simple_projections(length_increasing=True).map(ambient_monoid) sage: M = AutomaticSemigroup(pi, one=ambient_monoid.one()); M A submonoid of (Maps from W to itself) with 4 generators @@ -351,7 +351,7 @@ def __classcall_private__(cls, generators, ambient=None, one=None, mul=operator. def __init__(self, generators, ambient, one, mul, category): """ - Initializes this semigroup. + Initialize this semigroup. TESTS:: @@ -409,7 +409,7 @@ def _repr_(self): sage: AutomaticSemigroup(Family({1: R(3), 2: R(5)}), mul=operator.add, one=R.zero()) A semigroup with 2 generators - sage: S5 = SymmetricGroup(5); S5.rename("S5") # needs sage.groups + sage: S5 = SymmetricGroup(5); S5.rename('S5') # needs sage.groups sage: AutomaticSemigroup(Family({1: S5((1,2))}), # needs sage.groups ....: category=Groups().Finite().Subobjects()) A subgroup of (S5) with 1 generators @@ -429,9 +429,9 @@ def _repr_(self): return f"{typ}{of} with {len(self._generators)} generators" - def repr_element_method(self, style="ambient"): + def repr_element_method(self, style='ambient'): """ - Sets the representation of the elements of the monoid. + Set the representation of the elements of the monoid. INPUT: @@ -501,7 +501,7 @@ def retract(self, ambient_element, check=True): sage: # needs sage.groups sage: from sage.monoids.automatic_semigroup import AutomaticSemigroup - sage: S5 = SymmetricGroup(5); S5.rename("S5") + sage: S5 = SymmetricGroup(5); S5.rename('S5') sage: M = AutomaticSemigroup(Family({1:S5((1,2)), 2:S5((1,2,3,4))}), ....: one=S5.one()) sage: m = M.retract(S5((3,1))); m @@ -773,7 +773,7 @@ def from_reduced_word(self, l): INPUT: - - ``l`` -- a list of indices of the generators + - ``l`` -- list of indices of the generators .. NOTE:: @@ -804,9 +804,9 @@ def construct(self, up_to=None, n=None): INPUT: - - ``up_to`` -- an element of ``self`` or of the ambient semigroup. + - ``up_to`` -- an element of ``self`` or of the ambient semigroup - - ``n`` -- an integer or ``None`` (default: ``None``) + - ``n`` -- integer or ``None`` (default: ``None``) This construct all the elements of this semigroup, their reduced words, and the right Cayley graph. If `n` is @@ -818,8 +818,8 @@ def construct(self, up_to=None, n=None): sage: # needs sage.groups sage.modules sage: from sage.monoids.automatic_semigroup import AutomaticSemigroup - sage: W = WeylGroup(['A',3]); W.rename("W") - sage: ambient_monoid = FiniteSetMaps(W, action="right") + sage: W = WeylGroup(['A',3]); W.rename('W') + sage: ambient_monoid = FiniteSetMaps(W, action='right') sage: pi = W.simple_projections(length_increasing=True).map(ambient_monoid) sage: M = AutomaticSemigroup(pi, one=ambient_monoid.one()); M A submonoid of (Maps from W to itself) with 3 generators @@ -876,7 +876,7 @@ def reduced_word(self): r""" Return the length-lexicographic shortest word of ``self``. - OUTPUT: a list of indexes of the generators + OUTPUT: list of indexes of the generators Obtaining the reduced word requires having constructed the Cayley graph of the semigroup up to ``self``. If this is diff --git a/src/sage/monoids/free_abelian_monoid.py b/src/sage/monoids/free_abelian_monoid.py index 37564eb5c5e..3b8fe3f0e07 100644 --- a/src/sage/monoids/free_abelian_monoid.py +++ b/src/sage/monoids/free_abelian_monoid.py @@ -71,11 +71,9 @@ class FreeAbelianMonoidFactory(UniqueFactory): INPUT: + - ``n`` -- integer - - ``n`` -- integer - - - ``names`` -- names of generators - + - ``names`` -- names of generators OUTPUT: free abelian monoid @@ -116,7 +114,7 @@ def FreeAbelianMonoid(index_set=None, names=None, **kwds): Return a free abelian monoid on `n` generators or with the generators indexed by a set `I`. - We construct free abelian monoids by specifing either: + We construct free abelian monoids by specifying either: - the number of generators and/or the names of the generators - the indexing set for the generators (this ignores the other two inputs) @@ -126,11 +124,9 @@ def FreeAbelianMonoid(index_set=None, names=None, **kwds): - ``index_set`` -- an indexing set for the generators; if an integer, then this becomes `\{0, 1, \ldots, n-1\}` - - ``names`` -- names of generators - - OUTPUT: + - ``names`` -- names of generators - A free abelian monoid. + OUTPUT: a free abelian monoid EXAMPLES:: @@ -163,7 +159,7 @@ def FreeAbelianMonoid(index_set=None, names=None, **kwds): def is_FreeAbelianMonoid(x): """ - Return True if `x` is a free abelian monoid. + Return ``True`` if `x` is a free abelian monoid. EXAMPLES:: @@ -231,7 +227,7 @@ def __call__(self, x): def __contains__(self, x): """ - Return True if `x` is an element of this abelian monoid. + Return ``True`` if `x` is an element of this abelian monoid. EXAMPLES:: diff --git a/src/sage/monoids/free_abelian_monoid_element.pyx b/src/sage/monoids/free_abelian_monoid_element.pyx index 9f66e83942d..1cd087584cf 100644 --- a/src/sage/monoids/free_abelian_monoid_element.pyx +++ b/src/sage/monoids/free_abelian_monoid_element.pyx @@ -47,7 +47,7 @@ def is_FreeAbelianMonoidElement(x): INPUT: - - ``x`` -- an object. + - ``x`` -- an object OUTPUT: diff --git a/src/sage/monoids/free_monoid.py b/src/sage/monoids/free_monoid.py index 3e8ed837cf8..e7a2a9f6532 100644 --- a/src/sage/monoids/free_monoid.py +++ b/src/sage/monoids/free_monoid.py @@ -73,7 +73,7 @@ class FreeMonoid(Monoid_class, UniqueRepresentation): Return a free monoid on `n` generators or with the generators indexed by a set `I`. - We construct free monoids by specifing either: + We construct free monoids by specifying either: - the number of generators and/or the names of the generators - the indexing set for the generators @@ -85,12 +85,10 @@ class FreeMonoid(Monoid_class, UniqueRepresentation): - ``names`` -- names of generators - - ``commutative`` -- (default: ``False``) whether the free + - ``commutative`` -- boolean (default: ``False``); whether the free monoid is commutative or not - OUTPUT: - - A free monoid. + OUTPUT: a free monoid EXAMPLES:: diff --git a/src/sage/monoids/free_monoid_element.py b/src/sage/monoids/free_monoid_element.py index 993fef9c72d..f378270fcfd 100644 --- a/src/sage/monoids/free_monoid_element.py +++ b/src/sage/monoids/free_monoid_element.py @@ -27,6 +27,7 @@ from sage.rings.integer import Integer from sage.structure.element import MonoidElement from sage.structure.richcmp import richcmp, richcmp_not_equal +from sage.rings.semirings.non_negative_integer_semiring import NN def is_FreeMonoidElement(x): @@ -134,7 +135,7 @@ def _repr_(self): def _latex_(self) -> str: r""" - Return latex representation of self. + Return latex representation of ``self``. EXAMPLES:: @@ -176,23 +177,44 @@ def __call__(self, *x, **kwds): """ EXAMPLES:: + sage: M. = FreeMonoid(2) + sage: (x*y).substitute(x=1) + y + + sage: M. = FreeMonoid(1) + sage: a.substitute(a=5) + 5 + sage: M. = FreeMonoid(3) sage: (x*y).subs(x=1,y=2,z=14) 2 sage: (x*y).subs({x:z,y:z}) z^2 + + It is still possible to substitute elements + that have no common parent:: + sage: M1 = MatrixSpace(ZZ,1,2) # needs sage.modules sage: M2 = MatrixSpace(ZZ,2,1) # needs sage.modules sage: (x*y).subs({x: M1([1,2]), y: M2([3,4])}) # needs sage.modules [11] + TESTS:: + sage: M. = FreeMonoid(2) - sage: (x*y).substitute(x=1) - y + sage: (x*y)(QQ(4),QQ(5)).parent() + Rational Field - sage: M. = FreeMonoid(1) - sage: a.substitute(a=5) - 5 + The codomain is by default the first parent:: + + sage: M.one()(QQ(4),QQ(5)).parent() + Rational Field + + unless there is no variable and no substitution:: + + sage: M = FreeMonoid(0, []) + sage: M.one()().parent() + Free monoid on 0 generators () AUTHORS: @@ -210,34 +232,28 @@ def __call__(self, *x, **kwds): if key in gens_dict: x[gens_dict[key]] = value - if isinstance(x[0], tuple): + if x and isinstance(x[0], tuple): x = x[0] if len(x) != self.parent().ngens(): raise ValueError("must specify as many values as generators in parent") - # I don't start with 0, because I don't want to preclude evaluation with - # arbitrary objects (e.g. matrices) because of funny coercion. - one = P.one() - result = None + # if no substitution, do nothing + if not x: + return self + + try: + # This will land in the parent of the first element + result = x[0].parent().one() + except (AttributeError, TypeError): + # unless the parent has no unit + result = NN.one() for var_index, exponent in self._element_list: - # Take further pains to ensure that non-square matrices are not exponentiated. replacement = x[var_index] if exponent > 1: - c = replacement ** exponent + result *= replacement ** exponent elif exponent == 1: - c = replacement - else: - c = one - - if result is None: - result = c - else: - result *= c - - if result is None: - return one - + result *= replacement return result def _mul_(self, y): diff --git a/src/sage/monoids/hecke_monoid.py b/src/sage/monoids/hecke_monoid.py index b76867d6e0d..bc25f9769a7 100644 --- a/src/sage/monoids/hecke_monoid.py +++ b/src/sage/monoids/hecke_monoid.py @@ -19,7 +19,7 @@ def HeckeMonoid(W): INPUT: - - `W` -- a finite Coxeter group + - ``W`` -- a finite Coxeter group Let `s_1,\ldots,s_n` be the simple reflections of `W`. The 0-Hecke monoid is the monoid generated by projections `\pi_1,\ldots,\pi_n` @@ -57,7 +57,7 @@ def HeckeMonoid(W): sage: H.cardinality() 24 """ - ambient_monoid = FiniteSetMaps(W, action="right") + ambient_monoid = FiniteSetMaps(W, action='right') pi = W.simple_projections(length_increasing=True).map(ambient_monoid) H = ambient_monoid.submonoid(pi) H.rename("0-Hecke monoid of the %s" % W) diff --git a/src/sage/monoids/indexed_free_monoid.py b/src/sage/monoids/indexed_free_monoid.py index 66af0a2fb5c..69b67e260f7 100644 --- a/src/sage/monoids/indexed_free_monoid.py +++ b/src/sage/monoids/indexed_free_monoid.py @@ -205,7 +205,7 @@ def __iter__(self): def _richcmp_(self, other, op): r""" - Comparisons + Comparisons. TESTS:: @@ -271,7 +271,7 @@ def _richcmp_(self, other, op): def support(self): """ Return a list of the objects indexing ``self`` with - non-zero exponents. + nonzero exponents. EXAMPLES:: @@ -288,7 +288,11 @@ def support(self): [0, 2] """ supp = {key for key, exp in self._sorted_items() if exp != 0} - return sorted(supp) + try: + return sorted(supp, key=print_options['sorting_key'], + reverse=print_options['sorting_reverse']) + except Exception: # Sorting the output is a plus, but if we can't, no big deal + return list(supp) def leading_support(self): """ @@ -523,7 +527,7 @@ def _sorted_items(self): try: v.sort(key=print_options['sorting_key'], reverse=print_options['sorting_reverse']) - except Exception: # Sorting the output is a plus, but if we can't, no big deal + except Exception: # Sorting the output is a plus, but if we can't, no big deal pass return v @@ -773,14 +777,12 @@ def _element_constructor_(self, x=None): sage: F([[1, 3], [-2, 12]]) F[-2]^12*F[1]^3 sage: F(-5) - Traceback (most recent call last): - ... - TypeError: unable to convert -5, use gen() instead + F[-5] """ if x is None: return self.one() if x in self._indices: - raise TypeError(f"unable to convert {x!r}, use gen() instead") + return self.gen(x) return self.element_class(self, x) def _an_element_(self): @@ -933,9 +935,9 @@ def gen(self, x): if x not in self._indices: raise IndexError(f"{x} is not in the index set") try: - return self.element_class(self, ((self._indices(x),1),)) - except (TypeError, NotImplementedError): # Backup (e.g., if it is a string) - return self.element_class(self, ((x,1),)) + return self.element_class(self, ((self._indices(x), ZZ.one()),)) + except (ValueError, TypeError, NotImplementedError): # Backup (e.g., if it is a string) + return self.element_class(self, ((x, ZZ.one()),)) class IndexedFreeAbelianMonoid(IndexedMonoid): """ @@ -961,6 +963,11 @@ class IndexedFreeAbelianMonoid(IndexedMonoid): sage: F = FreeAbelianMonoid(index_set=Partitions(), prefix='A', bracket=False, scalar_mult='%') sage: F.gen([3,1,1]) * F.gen([2,2]) A[2, 2]%A[3, 1, 1] + + .. TODO:: + + Implement a subclass when the index sets is finite that utilizes + vectors or the polydict monomials with the index order fixed. """ def _repr_(self): """ @@ -1045,10 +1052,15 @@ def gen(self, x): Traceback (most recent call last): ... IndexError: 0 is not in the index set + + sage: F = lie_algebras.VirasoroAlgebra(QQ).pbw_basis().indices(); F + Free abelian monoid indexed by Disjoint union of Family ({'c'}, Integer Ring) + sage: F.gen('c') + PBW['c'] """ if x not in self._indices: raise IndexError(f"{x} is not in the index set") try: - return self.element_class(self, {self._indices(x): 1}) - except (TypeError, NotImplementedError): # Backup (e.g., if it is a string) - return self.element_class(self, {x: 1}) + return self.element_class(self, {self._indices(x): ZZ.one()}) + except (ValueError, TypeError, NotImplementedError): # Backup (e.g., if it is a string) + return self.element_class(self, {x: ZZ.one()}) diff --git a/src/sage/monoids/meson.build b/src/sage/monoids/meson.build new file mode 100644 index 00000000000..df2a4ae36be --- /dev/null +++ b/src/sage/monoids/meson.build @@ -0,0 +1,32 @@ +py.install_sources( + 'all.py', + 'automatic_semigroup.py', + 'free_abelian_monoid.py', + 'free_abelian_monoid_element.pxd', + 'free_monoid.py', + 'free_monoid_element.py', + 'hecke_monoid.py', + 'indexed_free_monoid.py', + 'monoid.py', + 'string_monoid.py', + 'string_monoid_element.py', + 'string_ops.py', + 'trace_monoid.py', + subdir: 'sage/monoids', +) + +extension_data = { + 'free_abelian_monoid_element' : files('free_abelian_monoid_element.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/monoids', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/monoids/string_monoid.py b/src/sage/monoids/string_monoid.py index 7aa51ad9776..61814c421c5 100644 --- a/src/sage/monoids/string_monoid.py +++ b/src/sage/monoids/string_monoid.py @@ -35,10 +35,10 @@ def __init__(self, n, alphabet=()): INPUT: - - ``n`` -- Integer + - ``n`` -- integer - - ``alphabet`` -- String or tuple whose characters or elements denote - the generators. + - ``alphabet`` -- string or tuple whose characters or elements denote + the generators EXAMPLES:: @@ -168,7 +168,7 @@ def __call__(self, x, check=True): Return ``x`` coerced into this free monoid. One can create a free binary string monoid element from a - Python string of 0's and 1's or list of integers. + Python string of 0s and 1s or list of integers. NOTE: Due to the ambiguity of the second generator '1' with the identity element '' of the monoid, the syntax S(1) is not @@ -288,7 +288,7 @@ def __call__(self, x, check=True): Return ``x`` coerced into this free monoid. One can create a free octal string monoid element from a - Python string of 0's to 7's or list of integers. + Python string of 0s to 7s or list of integers. EXAMPLES:: @@ -596,7 +596,7 @@ def __call__(self, x, check=True): else: raise TypeError("Argument x (= %s) is of the wrong type." % x) - def characteristic_frequency(self, table_name="beker_piper"): + def characteristic_frequency(self, table_name='beker_piper'): r""" Return a table of the characteristic frequency probability distribution of the English alphabet. In written English, various @@ -630,15 +630,15 @@ def characteristic_frequency(self, table_name="beker_piper"): INPUT: - - ``table_name`` -- (default ``"beker_piper"``) the table of + - ``table_name`` -- (default: ``'beker_piper'``) the table of characteristic frequency probability distribution to use. The following tables are supported: - - ``"beker_piper"`` -- the table of characteristic frequency + - ``'beker_piper'`` -- the table of characteristic frequency probability distribution by Beker and Piper [BP1982]_. This is the default table to use. - - ``"lewand"`` -- the table of characteristic frequency + - ``'lewand'`` -- the table of characteristic frequency probability distribution by Lewand as described on page 36 of [Lew2000]_. @@ -654,7 +654,7 @@ def characteristic_frequency(self, table_name="beker_piper"): Beker and Piper [BP1982]_:: sage: A = AlphabeticStrings() - sage: table = A.characteristic_frequency(table_name="beker_piper") + sage: table = A.characteristic_frequency(table_name='beker_piper') sage: sorted(table.items()) [('A', 0.0820000000000000), @@ -687,7 +687,7 @@ def characteristic_frequency(self, table_name="beker_piper"): The characteristic frequency probability distribution table of Lewand [Lew2000]_:: - sage: table = A.characteristic_frequency(table_name="lewand") + sage: table = A.characteristic_frequency(table_name='lewand') sage: sorted(table.items()) [('A', 0.0816700000000000), @@ -767,7 +767,7 @@ def characteristic_frequency(self, table_name="beker_piper"): Traceback (most recent call last): ... ValueError: Table name must be either 'beker_piper' or 'lewand'. - sage: table = A.characteristic_frequency(table_name="none") + sage: table = A.characteristic_frequency(table_name='none') Traceback (most recent call last): ... ValueError: Table name must be either 'beker_piper' or 'lewand'. diff --git a/src/sage/monoids/string_monoid_element.py b/src/sage/monoids/string_monoid_element.py index 6a7719c9d7c..d7e06428e0f 100644 --- a/src/sage/monoids/string_monoid_element.py +++ b/src/sage/monoids/string_monoid_element.py @@ -30,46 +30,58 @@ def is_StringMonoidElement(x): - r""" - """ + from sage.misc.superseded import deprecation + deprecation(38280, + "The function is_StringMonoidElement is deprecated; " + "use 'isinstance(..., StringMonoidElement)' instead.") return isinstance(x, StringMonoidElement) def is_AlphabeticStringMonoidElement(x): - r""" - """ + from sage.misc.superseded import deprecation + deprecation(38280, + "The function is_AlphabeticStringMonoidElement is deprecated; " + "use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), AlphabeticStringMonoid)' instead.") from .string_monoid import AlphabeticStringMonoid return isinstance(x, StringMonoidElement) and \ isinstance(x.parent(), AlphabeticStringMonoid) def is_BinaryStringMonoidElement(x): - r""" - """ + from sage.misc.superseded import deprecation + deprecation(38280, + "The function is_BinaryStringMonoidElement is deprecated; " + "use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), BinaryStringMonoid)' instead.") from .string_monoid import BinaryStringMonoid return isinstance(x, StringMonoidElement) and \ isinstance(x.parent(), BinaryStringMonoid) def is_OctalStringMonoidElement(x): - r""" - """ + from sage.misc.superseded import deprecation + deprecation(38280, + "The function is_OctalStringMonoidElement is deprecated; " + "use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), OctalStringMonoid)' instead.") from .string_monoid import OctalStringMonoid return isinstance(x, StringMonoidElement) and \ isinstance(x.parent(), OctalStringMonoid) def is_HexadecimalStringMonoidElement(x): - r""" - """ + from sage.misc.superseded import deprecation + deprecation(38280, + "The function is_HexadecimalStringMonoidElement is deprecated; " + "use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), HexadecimalStringMonoid)' instead.") from .string_monoid import HexadecimalStringMonoid return isinstance(x, StringMonoidElement) and \ isinstance(x.parent(), HexadecimalStringMonoid) def is_Radix64StringMonoidElement(x): - r""" - """ + from sage.misc.superseded import deprecation + deprecation(38280, + "The function is_Radix64StringMonoidElement is deprecated; " + "use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), Radix64StringMonoid)' instead.") from .string_monoid import Radix64StringMonoid return isinstance(x, StringMonoidElement) and \ isinstance(x.parent(), Radix64StringMonoid) @@ -140,7 +152,7 @@ def _repr_(self): def _latex_(self): """ - Return latex representation of self. + Return latex representation of ``self``. EXAMPLES:: @@ -191,12 +203,12 @@ def __pow__(self, n): sage: x**(-1) Traceback (most recent call last): ... - IndexError: Argument n (= -1) must be non-negative. + IndexError: Argument n (= -1) must be nonnegative. """ if not isinstance(n, (int, Integer)): raise TypeError("Argument n (= %s) must be an integer." % n) if n < 0: - raise IndexError("Argument n (= %s) must be non-negative." % n) + raise IndexError("Argument n (= %s) must be nonnegative." % n) elif n == 0: return self.parent()('') elif n == 1: @@ -444,7 +456,7 @@ def frequency_distribution(self, length=1, prec=0): INPUT: - - ``length`` -- (default ``1``) if ``length=1`` then consider the + - ``length`` -- (default: ``1``) if ``length=1`` then consider the probability space of monogram frequency, i.e. probability distribution of single characters. If ``length=2`` then consider the probability space of digram frequency, i.e. probability @@ -452,7 +464,7 @@ def frequency_distribution(self, length=1, prec=0): supports the generation of probability spaces for monogram frequency (``length=1``) and digram frequency (``length=2``). - - ``prec`` -- (default ``0``) a non-negative integer representing + - ``prec`` -- (default: ``0``) a nonnegative integer representing the precision (in number of bits) of a floating-point number. The default value ``prec=0`` means that we use 53 bits to represent the mantissa of a floating-point number. For more information on diff --git a/src/sage/monoids/string_ops.py b/src/sage/monoids/string_ops.py index 500762cb3e5..304e908c16b 100644 --- a/src/sage/monoids/string_ops.py +++ b/src/sage/monoids/string_ops.py @@ -95,8 +95,8 @@ def coincidence_discriminant(S, n=2): """ INPUT: - A tuple of strings, e.g. produced as decimation of transposition - ciphertext, or a sample plaintext. + - ``S`` --tuple of strings; e.g. produced as decimation of transposition + ciphertext, or a sample plaintext OUTPUT: diff --git a/src/sage/monoids/trace_monoid.py b/src/sage/monoids/trace_monoid.py index df5a7d4bce9..cb1c036e039 100644 --- a/src/sage/monoids/trace_monoid.py +++ b/src/sage/monoids/trace_monoid.py @@ -109,7 +109,7 @@ def _repr_(self) -> str: return "1" return f"[{self.value}]" - def _richcmp_(self, other, op): + def _richcmp_(self, other, op) -> bool: r""" Compare two traces by their lexicographic normal forms. @@ -131,9 +131,7 @@ def lex_normal_form(self): r""" Return the lexicographic normal form of ``self``. - OUTPUT: - - A free monoid element. + OUTPUT: a free monoid element EXAMPLES:: @@ -149,13 +147,11 @@ def lex_normal_form(self): """ return self.value - def foata_normal_form(self): + def foata_normal_form(self) -> tuple: r""" Return the Foata normal form of ``self``. - OUTPUT: - - Tuple of free monoid elements. + OUTPUT: tuple of free monoid elements EXAMPLES:: @@ -186,9 +182,7 @@ def _flat_elements(self): r""" Return flatten list of generator numbers representing the trace. - OUTPUT: - - A list of generator indexes. + OUTPUT: list of generator indexes TESTS:: @@ -210,9 +204,7 @@ def dependence_graph(self): generators are connected by edges which direction depend on the generator position in the trace. - OUTPUT: - - Directed graph of generator indexes. + OUTPUT: directed graph of generator indexes EXAMPLES:: @@ -237,7 +229,7 @@ def dependence_graph(self): return DiGraph(graph) @cached_method - def hasse_diagram(self, algorithm="naive"): + def hasse_diagram(self, algorithm='naive'): r""" Return Hasse diagram of the trace. @@ -249,9 +241,7 @@ def hasse_diagram(self, algorithm="naive"): that will be used to compute Hasse diagram; there are two variants: ``'naive'`` and ``'min'``. - OUTPUT: - - Directed graph of generator indexes. + OUTPUT: directed graph of generator indexes .. SEEALSO:: @@ -290,9 +280,7 @@ def min_hasse_diagram(self): r""" Return Hasse diagram of the trace. - OUTPUT: - - Directed graph of generator indexes. + OUTPUT: directed graph of generator indexes .. SEEALSO:: @@ -312,12 +300,12 @@ def min_hasse_diagram(self): elements.reverse() independence = self.parent()._independence reachable = {} - min = set() + mini = set() graph = DiGraph({}) for i, x in enumerate(elements): reachable[i] = set() - front = min.copy() + front = mini.copy() while front: used = set() for j in list(front): @@ -326,14 +314,14 @@ def min_hasse_diagram(self): graph.add_edge(i, j) reachable[i].add(j) reachable[i].update(reachable[j]) - if j in min: - min.remove(j) + if j in mini: + mini.remove(j) used.add(j) forbidden = set(chain.from_iterable(reachable[v] for v in used)) front = {dest for _, dest in graph.outgoing_edges(front, labels=False)} front = front - forbidden - min.add(i) + mini.add(i) length = len(elements) graph.relabel(length - 1 - i for i in range(length)) @@ -348,9 +336,7 @@ def naive_hasse_diagram(self): In loop check for every two pair of edges if they have common vertex, remove their transitive edge. - OUTPUT: - - Directed graph of generator indexes. + OUTPUT: directed graph of generator indexes .. SEEALSO:: @@ -381,9 +367,7 @@ def alphabet(self): r""" Return alphabet of ``self``. - OUTPUT: - - A set of free monoid generators. + OUTPUT: a set of free monoid generators EXAMPLES:: @@ -405,9 +389,7 @@ def projection(self, letters): - ``letters`` -- set of generators; defines set of letters that will be used to filter the trace - OUTPUT: - - A trace + OUTPUT: a trace EXAMPLES:: @@ -450,7 +432,7 @@ class TraceMonoid(UniqueRepresentation, Monoid_class): Return a free partially commuting monoid (trace monoid) on `n` generators over independence relation `I`. - We construct a trace monoid by specifing: + We construct a trace monoid by specifying: - a free monoid and independence relation - or generator names and independence relation, @@ -513,7 +495,7 @@ def __classcall_private__(cls, M=None, I=frozenset(), names=None): rels = set() gen_from_str = {names[i]: gen for i, gen in enumerate(M.gens())} - for (x, y) in I: + for x, y in I: try: if isinstance(x, str): x = gen_from_str[x] @@ -531,7 +513,7 @@ def __classcall_private__(cls, M=None, I=frozenset(), names=None): return super().__classcall__(cls, M, I, names) - def __init__(self, M, I, names): + def __init__(self, M, I, names) -> None: r""" Initialize ``self``. @@ -611,9 +593,7 @@ def _compute_dependence_stack(self, x): Return generator stacks formed from trace subelements with respect to non-commutativity. - OUTPUT: - - Used generators and list of stacks as tuple. + OUTPUT: used generators and list of stacks as tuple ALGORITHM: @@ -654,9 +634,7 @@ def _compute_lex_normal_form(self, x): Return lexicographic normal form of the free monoid element in free monoid terms. - OUTPUT: - - Trace monoid element. + OUTPUT: trace monoid element ALGORITHM: @@ -695,7 +673,7 @@ def _compute_lex_normal_form(self, x): return prod(elements) @cached_method - def _compute_foata_normal_form(self, x): + def _compute_foata_normal_form(self, x) -> tuple: r""" Return Foata normal form of the monoid element. @@ -770,7 +748,7 @@ def independence(self): r""" Return independence relation over the monoid. - OUTPUT: set of commuting generator pairs. + OUTPUT: set of commuting generator pairs EXAMPLES:: @@ -788,9 +766,7 @@ def dependence(self): r""" Return dependence relation over the monoid. - OUTPUT: - - Set of non-commuting generator pairs. + OUTPUT: set of non-commuting generator pairs EXAMPLES:: @@ -819,7 +795,7 @@ def dependence_graph(self): """ return Graph({frozenset((e1, e2)) if e1 != e2 else (e1, e2) for e1, e2 in self.dependence()}, loops=True, - format="list_of_edges", + format='list_of_edges', immutable=True) @cached_method @@ -827,9 +803,7 @@ def independence_graph(self): r""" Return the digraph of independence relations. - OUTPUT: - - Independence graph with generators as vertices. + OUTPUT: independence graph with generators as vertices TESTS:: @@ -852,9 +826,7 @@ def dependence_polynomial(self, t=None): where `c_i` equals to number of full subgraphs of size `i` in the independence graph. - OUTPUT: - - A rational function in ``t`` with coefficients in the integer ring. + OUTPUT: a rational function in ``t`` with coefficients in the integer ring EXAMPLES:: @@ -944,11 +916,11 @@ def words(self, length): if not ((list(word.value)[-1][0], suffix.value) in self._independence and list(word.value)[-1][0] > suffix.value)]) - def _sorted_independence(self): + def _sorted_independence(self) -> list: r""" Return independence relation over the monoid. - OUTPUT: sorted list of sorted commuting generator pairs. + OUTPUT: sorted list of sorted commuting generator pairs EXAMPLES:: @@ -979,7 +951,7 @@ def _repr_(self) -> str: ", ".join(f"{{{x}, {y}}}" for (x, y) in self._sorted_independence())) - def _latex_(self): + def _latex_(self) -> str: r""" LaTeX representation of trace monoids. diff --git a/src/sage/numerical/backends/cvxopt_backend.pyx b/src/sage/numerical/backends/cvxopt_backend.pyx index 23a3fcb014c..14c60dc3167 100644 --- a/src/sage/numerical/backends/cvxopt_backend.pyx +++ b/src/sage/numerical/backends/cvxopt_backend.pyx @@ -30,7 +30,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="CVXOPT") + sage: p = MixedIntegerLinearProgram(solver='CVXOPT') TESTS: @@ -40,7 +40,7 @@ cdef class CVXOPTBackend(GenericBackend): Mixed Integer Program (no objective, 0 variables, 0 constraints) """ - cdef list objective_function #c_matrix + cdef list objective_function # c_matrix cdef list G_matrix cdef str prob_name cdef bint is_maximize @@ -57,16 +57,15 @@ cdef class CVXOPTBackend(GenericBackend): def __cinit__(self, maximization = True): """ - Cython constructor + Cython constructor. EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") - + sage: p = get_solver(solver='CVXOPT') """ - self.objective_function = [] #c_matrix in the example for cvxopt + self.objective_function = [] # c_matrix in the example for cvxopt self.G_matrix = [] self.prob_name = '' self.obj_constant_term = 0 @@ -80,12 +79,12 @@ cdef class CVXOPTBackend(GenericBackend): self.row_name_var = [] self.col_name_var = [] - self.param = {"show_progress":False, - "maxiters":100, - "abstol":1e-7, - "reltol":1e-6, - "feastol":1e-7, - "refinement":0 } + self.param = {"show_progress": False, + "maxiters": 100, + "abstol": 1e-7, + "reltol": 1e-6, + "feastol": 1e-7, + "refinement": 0} self.answer = {} if maximization: self.set_sense(+1) @@ -96,12 +95,12 @@ cdef class CVXOPTBackend(GenericBackend): # Added a second inequality to this doctest, # because otherwise CVXOPT complains: ValueError: Rank(A) < p or Rank([G; A]) < n """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = MixedIntegerLinearProgram(solver="CVXOPT") + sage: p = MixedIntegerLinearProgram(solver='CVXOPT') sage: b = p.new_variable() sage: p.add_constraint(b[1] + b[2] <= 6) sage: p.add_constraint(b[2] <= 5) @@ -145,22 +144,22 @@ cdef class CVXOPTBackend(GenericBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integer (default: ``False``). + - ``integer`` -- ``True`` if the variable is integer (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.ncols() 0 sage: p.add_variable() @@ -211,7 +210,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="cvxopt") + sage: p = get_solver(solver='cvxopt') sage: p.add_variables(5) 4 sage: p.set_variable_type(3, -1) @@ -229,7 +228,7 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``sense`` (integer): + - ``sense`` -- integer: * `+1` => Maximization * `-1` => Minimization @@ -237,7 +236,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.is_maximization() True sage: p.set_sense(-1) @@ -256,14 +255,14 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient + - ``coeff`` -- double; its coefficient EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variable() 0 sage: p.objective_coefficient(0) @@ -283,15 +282,16 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variables(5) 4 sage: p.set_objective([1, 1, 2, 1, 3]) @@ -304,7 +304,7 @@ cdef class CVXOPTBackend(GenericBackend): cpdef set_verbosity(self, int level): """ - Does not apply for the cvxopt solver + Do not apply for the cvxopt solver. """ pass @@ -314,15 +314,15 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it - appears. Namely, the ith entry of ``coeffs`` corresponds to + appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint - represented by the ith entry in ``indices``. + represented by the i-th entry in ``indices``. .. NOTE:: @@ -332,7 +332,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.ncols() 0 sage: p.nrows() @@ -375,7 +375,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variables(5) 4 sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) @@ -412,7 +412,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="cvxopt", maximization=False) + sage: p = MixedIntegerLinearProgram(solver='cvxopt', maximization=False) sage: x = p.new_variable(nonnegative=True) sage: p.set_objective(-4*x[0] - 5*x[1]) sage: p.add_constraint(2*x[0] + x[1] <= 3) @@ -420,7 +420,7 @@ cdef class CVXOPTBackend(GenericBackend): sage: N(p.solve(), digits=2) -9.0 - sage: p = MixedIntegerLinearProgram(solver="cvxopt", maximization=False) + sage: p = MixedIntegerLinearProgram(solver='cvxopt', maximization=False) sage: x = p.new_variable(nonnegative=True) sage: p.set_objective(x[0] + 2*x[1]) sage: p.add_constraint(-5*x[0] + x[1] <= 7) @@ -431,7 +431,7 @@ cdef class CVXOPTBackend(GenericBackend): sage: N(p.solve(), digits=4) 48.83 - sage: p = MixedIntegerLinearProgram(solver="cvxopt") + sage: p = MixedIntegerLinearProgram(solver='cvxopt') sage: x = p.new_variable(nonnegative=True) sage: p.set_objective(x[0] + x[1] + 3*x[2]) sage: p.solver_parameter("show_progress",True) @@ -450,8 +450,8 @@ cdef class CVXOPTBackend(GenericBackend): gives the center point of the top face, whereas the other tested solvers return a vertex:: - sage: c = MixedIntegerLinearProgram(solver="cvxopt") - sage: p = MixedIntegerLinearProgram(solver="ppl") + sage: c = MixedIntegerLinearProgram(solver='cvxopt') + sage: p = MixedIntegerLinearProgram(solver='ppl') sage: g = MixedIntegerLinearProgram() sage: xc = c.new_variable(nonnegative=True) sage: xp = p.new_variable(nonnegative=True) @@ -571,7 +571,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="cvxopt") + sage: p = get_solver(solver='cvxopt') sage: p.add_variables(2) 1 sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) @@ -603,7 +603,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variables(2) 1 sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) @@ -626,7 +626,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.ncols() 0 sage: p.add_variables(2) @@ -644,7 +644,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.nrows() 0 sage: p.add_variables(5) @@ -662,7 +662,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.is_maximization() True sage: p.set_sense(-1) @@ -676,17 +676,17 @@ cdef class CVXOPTBackend(GenericBackend): cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.problem_name() '' sage: p.problem_name("There once was a french fry") @@ -699,11 +699,11 @@ cdef class CVXOPTBackend(GenericBackend): cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -715,7 +715,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variables(5) 4 sage: p.add_linear_constraint(list(zip(range(5), range(5))), 2, 2) @@ -740,7 +740,7 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -751,7 +751,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variables(5) 4 sage: p.add_linear_constraint(list(zip(range(5), range(5))), 2, 2) @@ -768,7 +768,7 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -779,7 +779,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variable() 0 sage: p.col_bounds(0) @@ -797,12 +797,12 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.ncols() 0 sage: p.add_variable() @@ -813,7 +813,6 @@ cdef class CVXOPTBackend(GenericBackend): ValueError: ... sage: p.is_variable_binary(0) False - """ return False @@ -824,12 +823,12 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.ncols() 0 sage: p.add_variable() @@ -851,12 +850,12 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.ncols() 0 sage: p.add_variable() @@ -869,22 +868,21 @@ cdef class CVXOPTBackend(GenericBackend): ValueError: ... sage: p.is_variable_continuous(0) True - """ return True cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_linear_constraints(1, 2, None, names=["Empty constraint 1"]) sage: p.row_name(0) 'Empty constraint 1' @@ -895,19 +893,19 @@ cdef class CVXOPTBackend(GenericBackend): cpdef col_name(self, int index): """ - Return the ``index`` th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variable(name="I am a variable") 0 sage: p.col_name(0) @@ -919,11 +917,11 @@ cdef class CVXOPTBackend(GenericBackend): cpdef variable_upper_bound(self, int index, value = False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``False`` @@ -932,7 +930,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variable() 0 sage: p.col_bounds(0) @@ -948,11 +946,11 @@ cdef class CVXOPTBackend(GenericBackend): cpdef variable_lower_bound(self, int index, value = False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not lower bound. When set to ``False`` @@ -961,7 +959,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.add_variable() 0 sage: p.col_bounds(0) @@ -977,14 +975,14 @@ cdef class CVXOPTBackend(GenericBackend): cpdef solver_parameter(self, name, value = None): """ - Return or define a solver parameter + Return or define a solver parameter. INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value .. NOTE:: @@ -994,7 +992,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.solver_parameter("show_progress") False sage: p.solver_parameter("show_progress", True) diff --git a/src/sage/numerical/backends/cvxopt_sdp_backend.pyx b/src/sage/numerical/backends/cvxopt_sdp_backend.pyx index 1aec0b3c502..c6addca8996 100644 --- a/src/sage/numerical/backends/cvxopt_sdp_backend.pyx +++ b/src/sage/numerical/backends/cvxopt_sdp_backend.pyx @@ -31,13 +31,12 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): def __init__(self, maximization=True, base_ring=None): """ - Cython constructor + Cython constructor. EXAMPLES:: sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver="CVXOPT") - + sage: p = get_solver(solver='CVXOPT') """ from sage.rings.real_double import RDF @@ -67,7 +66,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: p = SemidefiniteProgram(solver='cvxopt', maximization=False) sage: x = p.new_variable() sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) @@ -82,7 +81,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) sage: N(p.solve(), digits=4) -3.225 - sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: p = SemidefiniteProgram(solver='cvxopt', maximization=False) sage: x = p.new_variable() sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) @@ -97,7 +96,6 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) sage: N(p.solve(), digits=4) -3.154 - """ from cvxopt import matrix as c_matrix, solvers from sage.rings.real_double import RDF @@ -169,7 +167,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: p = SemidefiniteProgram(solver='cvxopt', maximization=False) sage: x = p.new_variable() sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) @@ -196,7 +194,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): cpdef _get_answer(self): """ - return the complete output dict of the solver + Return the complete output dict of the solver. Mainly for testing purposes @@ -230,7 +228,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: p = SemidefiniteProgram(solver='cvxopt', maximization=False) sage: x = p.new_variable() sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) @@ -256,15 +254,14 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): cpdef dual_variable(self, int i, sparse=False): """ - The `i`-th dual variable - - Available after self.solve() is called, otherwise the result is undefined + The `i`-th dual variable. - - ``index`` (integer) -- the constraint's id. + Available after ``self.solve()`` is called, otherwise the result is + undefined. - OUTPUT: + - ``index`` -- integer; the constraint's id - The matrix of the `i`-th dual variable + OUTPUT: the matrix of the `i`-th dual variable EXAMPLES:: @@ -297,7 +294,6 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): IndexError: list index out of range sage: abs(g - B._get_answer()['gap']) # tol 1e-22 0.0 - """ cdef int n n = self.answer['zs'][i].size[0] @@ -306,15 +302,14 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): cpdef slack(self, int i, sparse=False): """ - Slack of the `i`-th constraint - - Available after self.solve() is called, otherwise the result is undefined + Slack of the `i`-th constraint. - - ``index`` (integer) -- the constraint's id. + Available after ``self.solve()`` is called, otherwise the result is + undefined. - OUTPUT: + - ``index`` -- integer; the constraint's id - The matrix of the slack of the `i`-th constraint + OUTPUT: the matrix of the slack of the `i`-th constraint EXAMPLES:: @@ -348,7 +343,6 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): Traceback (most recent call last): ... IndexError: list index out of range - """ cdef int n n = self.answer['ss'][i].size[0] @@ -357,14 +351,14 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): cpdef solver_parameter(self, name, value=None): """ - Return or define a solver parameter + Return or define a solver parameter. INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value .. NOTE:: @@ -374,7 +368,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver="CVXOPT") + sage: p = get_solver(solver='CVXOPT') sage: p.solver_parameter("show_progress") False sage: p.solver_parameter("show_progress", True) diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index 175b727a8a5..6a758e35bfb 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -41,46 +41,46 @@ cdef class CVXPYBackend: Using the default solver determined by CVXPY:: - sage: p = MixedIntegerLinearProgram(solver="CVXPY"); p.solve() + sage: p = MixedIntegerLinearProgram(solver='CVXPY'); p.solve() 0.0 Using a specific solver:: - sage: p = MixedIntegerLinearProgram(solver="CVXPY/OSQP"); p.solve() + sage: p = MixedIntegerLinearProgram(solver='CVXPY/OSQP'); p.solve() 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/ECOS"); p.solve() + sage: p = MixedIntegerLinearProgram(solver='CVXPY/ECOS'); p.solve() 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/SCS"); p.solve() + sage: p = MixedIntegerLinearProgram(solver='CVXPY/SCS'); p.solve() 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/SciPy/HiGHS"); p.solve() + sage: p = MixedIntegerLinearProgram(solver='CVXPY/SciPy/HiGHS'); p.solve() 0.0 Open-source solvers provided by optional packages:: - sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLPK"); p.solve() # needs cvxopt + sage: p = MixedIntegerLinearProgram(solver='CVXPY/GLPK'); p.solve() # needs cvxopt 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLPK_MI"); p.solve() # needs cvxopt + sage: p = MixedIntegerLinearProgram(solver='CVXPY/GLPK_MI'); p.solve() # needs cvxopt 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/CVXOPT"); p.solve() # needs cvxopt + sage: p = MixedIntegerLinearProgram(solver='CVXPY/CVXOPT'); p.solve() # needs cvxopt 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLOP"); p.solve() # optional - ortools + sage: p = MixedIntegerLinearProgram(solver='CVXPY/GLOP'); p.solve() # optional - ortools 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/PDLP"); p.solve() # optional - ortools + sage: p = MixedIntegerLinearProgram(solver='CVXPY/PDLP'); p.solve() # optional - ortools 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/CBC"); p.solve() # optional - cylp + sage: p = MixedIntegerLinearProgram(solver='CVXPY/CBC'); p.solve() # optional - cylp 0.0 Non-free solvers:: - sage: p = MixedIntegerLinearProgram(solver="CVXPY/Gurobi"); p.solve() # optional - gurobi + sage: p = MixedIntegerLinearProgram(solver='CVXPY/Gurobi'); p.solve() # optional - gurobi 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/CPLEX"); p.solve() # optional - cplex + sage: p = MixedIntegerLinearProgram(solver='CVXPY/CPLEX'); p.solve() # optional - cplex 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/MOSEK"); p.solve() # optional - mosek + sage: p = MixedIntegerLinearProgram(solver='CVXPY/MOSEK'); p.solve() # optional - mosek 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/SCIP"); p.solve() # optional - pyscipopt + sage: p = MixedIntegerLinearProgram(solver='CVXPY/SCIP'); p.solve() # optional - pyscipopt 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/XPRESS"); p.solve() # optional - xpress + sage: p = MixedIntegerLinearProgram(solver='CVXPY/XPRESS'); p.solve() # optional - xpress 0.0 sage: p = MixedIntegerLinearProgram(solver="CVXPY/NAG"); p.solve() # optional - naginterfaces 0.0 @@ -88,25 +88,25 @@ cdef class CVXPYBackend: def __cinit__(self, maximization=True, base_ring=None, cvxpy_solver=None, cvxpy_solver_args=None): """ - Cython constructor + Cython constructor. INPUT: - - ``maximization`` (boolean, default: ``True``) -- Whether this is a - maximization or minimization problem. + - ``maximization``-- boolean (default: ``True``); whether this is a + maximization or minimization problem - - ``base_ring`` (optional): Must be ``RDF`` if provided. + - ``base_ring`` -- (optional) must be ``RDF`` if provided - - ``cvxpy_solver (optional): Passed to :meth:`cvxpy.Problem.solve` as the - parameter ``solver``. + - ``cvxpy_solver`` -- (optional) passed to :meth:`cvxpy.Problem.solve` + as the parameter ``solver`` - - ``cvxpy_solver_args`` (optional dict): Passed to :meth:`cvxpy.Problem.solve` - as additional keyword arguments. + - ``cvxpy_solver_args`` -- dictionary (optional); passed to + :meth:`cvxpy.Problem.solve` as additional keyword arguments EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') """ if base_ring is None: base_ring = RDF @@ -143,12 +143,12 @@ cdef class CVXPYBackend: cpdef __copy__(self): """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = MixedIntegerLinearProgram(solver="CVXPY") + sage: p = MixedIntegerLinearProgram(solver='CVXPY') sage: b = p.new_variable() sage: p.add_constraint(b[1] + b[2] <= 6) sage: p.set_objective(b[1] + b[2]) @@ -196,26 +196,25 @@ cdef class CVXPYBackend: - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integral (default: ``False``). + - ``integer`` -- ``True`` if the variable is integral (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - - ``coefficients`` -- (optional) an iterable of pairs ``(i, v)``. In each - pair, ``i`` is a row index (integer) and ``v`` is a - value (element of :meth:`base_ring`). + - ``coefficients`` -- (optional) an iterable of pairs ``(i, v)``; in each + pair, ``i`` is a row index (integer) and ``v`` is a value (element of :meth:`base_ring`) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.ncols() 0 sage: p.add_variable() @@ -287,18 +286,18 @@ cdef class CVXPYBackend: cpdef set_verbosity(self, int level): """ - Set the log (verbosity) level + Set the log (verbosity) level. This is currently ignored. INPUT: - - ``level`` (integer) -- From 0 (no verbosity) to 3. + - ``level`` -- integer; from 0 (no verbosity) to 3 EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.set_verbosity(2) """ pass @@ -314,17 +313,17 @@ cdef class CVXPYBackend: value (element of :meth:`base_ring`). - ``lower_bound`` -- element of :meth:`base_ring` or - ``None``. The lower bound. + ``None``; the lower bound - ``upper_bound`` -- element of :meth:`base_ring` or - ``None``. The upper bound. + ``None``; the upper bound - - ``name`` -- string or ``None``. Optional name for this row. + - ``name`` -- string or ``None``; optional name for this row EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variables(5) 4 sage: index = p.nrows() @@ -368,11 +367,11 @@ cdef class CVXPYBackend: INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint @@ -386,7 +385,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.ncols() 0 sage: p.nrows() @@ -415,15 +414,16 @@ cdef class CVXPYBackend: INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variables(5) 4 sage: p.set_objective([1, 1, 2, 1, 3]) @@ -447,7 +447,7 @@ cdef class CVXPYBackend: INPUT: - - ``sense`` (integer) : + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -455,7 +455,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.is_maximization() True sage: p.set_sense(-1) @@ -471,19 +471,19 @@ cdef class CVXPYBackend: cpdef objective_coefficient(self, int variable, coeff=None): """ - Set or get the coefficient of a variable in the objective function + Set or get the coefficient of a variable in the objective function. INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient or ``None`` for + - ``coeff`` -- double; its coefficient or ``None`` for reading (default: ``None``) EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variable() 0 sage: p.objective_coefficient(0) @@ -517,7 +517,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_linear_constraints(5, 0, None) sage: p.add_col(list(range(5)), list(range(5))) Traceback (most recent call last): @@ -555,7 +555,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variables(2) 1 sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) @@ -582,7 +582,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variables(2) 1 sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) @@ -605,7 +605,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.ncols() 0 sage: p.add_variables(2) @@ -622,7 +622,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.nrows() 0 sage: p.add_linear_constraints(2, 0, None) @@ -638,7 +638,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.is_maximization() True sage: p.set_sense(-1) @@ -649,17 +649,17 @@ cdef class CVXPYBackend: cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.problem_name("There_once_was_a_french_fry") sage: print(p.problem_name()) There_once_was_a_french_fry @@ -674,11 +674,11 @@ cdef class CVXPYBackend: cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -690,7 +690,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variables(5) 4 sage: index = p.nrows() @@ -714,7 +714,7 @@ cdef class CVXPYBackend: INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -725,7 +725,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variables(5) 4 sage: index = p.nrows() @@ -743,7 +743,7 @@ cdef class CVXPYBackend: INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -754,7 +754,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variable() 0 sage: p.col_bounds(0) @@ -771,12 +771,12 @@ cdef class CVXPYBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.ncols() 0 sage: p.add_variable() @@ -792,12 +792,12 @@ cdef class CVXPYBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.ncols() 0 sage: p.add_variable() @@ -813,12 +813,12 @@ cdef class CVXPYBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.ncols() 0 sage: p.add_variable() @@ -830,16 +830,16 @@ cdef class CVXPYBackend: cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_linear_constraint([], 2, 2) sage: p.row_name(0) 'constraint_0' @@ -848,19 +848,19 @@ cdef class CVXPYBackend: cpdef col_name(self, int index): """ - Return the ``index`` th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variable() 0 sage: p.col_name(0) @@ -870,11 +870,11 @@ cdef class CVXPYBackend: cpdef variable_upper_bound(self, int index, value=False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``None`` @@ -883,7 +883,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variable() 0 sage: p.col_bounds(0) @@ -902,11 +902,11 @@ cdef class CVXPYBackend: cpdef variable_lower_bound(self, int index, value=False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not lower bound. When set to ``None`` @@ -915,7 +915,7 @@ cdef class CVXPYBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXPY") + sage: p = get_solver(solver='CVXPY') sage: p.add_variable() 0 sage: p.col_bounds(0) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 4ebfa58f839..b7962c3c877 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -3,7 +3,7 @@ Generic Backend for LP solvers This class only lists the methods that should be defined by any interface with a LP Solver. All these methods immediately raise -:class:`NotImplementedError` exceptions when called, and are obviously +:exc:`NotImplementedError` exceptions when called, and are obviously meant to be replaced by the solver-specific method. This file can also be used as a template to create a new interface : one would only need to replace the occurrences of ``"Nonexistent_LP_solver"`` by the @@ -54,17 +54,17 @@ cdef class GenericBackend: - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integral (default: ``False``). + - ``integer`` -- ``True`` if the variable is integral (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -109,17 +109,17 @@ cdef class GenericBackend: - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is binary (default: ``True``). + - ``continuous`` -- ``True`` if the variable is binary (default: ``True``) - - ``integer`` -- ``True`` if the variable is binary (default: ``False``). + - ``integer`` -- ``True`` if the variable is binary (default: ``False``) - - ``obj`` -- (optional) coefficient of all variables in the objective function (default: 0.0) + - ``obj`` -- coefficient of all variables in the objective function (default: 0.0) - - ``names`` -- optional list of names (default: ``None``) + - ``names`` -- list of names (default: ``None``) - OUTPUT: The index of the variable created last. + OUTPUT: the index of the variable created last EXAMPLES:: @@ -168,7 +168,7 @@ cdef class GenericBackend: @classmethod def _test_add_variables(cls, tester=None, **options): """ - Run tests on the method :meth:`.add_linear_constraints`. + Run tests on the method :meth:`add_linear_constraints`. TESTS:: @@ -211,13 +211,13 @@ cdef class GenericBackend: cpdef set_variable_type(self, int variable, int vtype): """ - Set the type of a variable + Set the type of a variable. INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``vtype`` (integer): + - ``vtype`` -- integer: * `1` Integer * `0` Binary @@ -244,7 +244,7 @@ cdef class GenericBackend: INPUT: - - ``sense`` (integer) : + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -273,7 +273,6 @@ cdef class GenericBackend: sage: p = GenericBackend() sage: p._test_sense() # optional - Nonexistent_LP_solver Exception NotImplementedError ... - """ p = cls() # fresh instance of the backend if tester is None: @@ -291,9 +290,9 @@ cdef class GenericBackend: INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient + - ``coeff`` -- double; its coefficient EXAMPLES:: @@ -312,11 +311,12 @@ cdef class GenericBackend: cpdef objective_constant_term(self, d=None): """ - Set or get the constant term in the objective function + Set or get the constant term in the objective function. INPUT: - - ``d`` (double) -- its coefficient. If `None` (default), return the current value. + - ``d`` -- double; its coefficient. If ``None`` (default), return the + current value. EXAMPLES:: @@ -340,10 +340,11 @@ cdef class GenericBackend: INPUT: - - ``coeff`` -- a list of real values, whose i-th element is the - coefficient of the i-th variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: @@ -372,11 +373,11 @@ cdef class GenericBackend: cpdef set_verbosity(self, int level): """ - Set the log (verbosity) level + Set the log (verbosity) level. INPUT: - - ``level`` (integer) -- From 0 (no verbosity) to 3. + - ``level`` -- integer; from 0 (no verbosity) to 3 EXAMPLES:: @@ -392,7 +393,7 @@ cdef class GenericBackend: INPUT: - - ``i`` -- index of the constraint to remove. + - ``i`` -- index of the constraint to remove EXAMPLES:: @@ -420,7 +421,7 @@ cdef class GenericBackend: INPUT: - - ``constraints`` -- an iterable containing the indices of the rows to remove. + - ``constraints`` -- an iterable containing the indices of the rows to remove EXAMPLES:: @@ -455,12 +456,12 @@ cdef class GenericBackend: value (element of :meth:`base_ring`). - ``lower_bound`` -- element of :meth:`base_ring` or - ``None``. The lower bound. + ``None``; the lower bound - ``upper_bound`` -- element of :meth:`base_ring` or - ``None``. The upper bound. + ``None``; the upper bound - - ``name`` -- string or ``None``. Optional name for this row. + - ``name`` -- string or ``None``; optional name for this row EXAMPLES:: @@ -493,21 +494,21 @@ cdef class GenericBackend: INPUT: - - ``degree`` -- integer. The vector degree, that is, the - number of new scalar constraints. + - ``degree`` -- integer; the vector degree, that is, the + number of new scalar constraints - ``coefficients`` -- an iterable of pairs ``(i, v)``. In each pair, ``i`` is a variable index (integer) and ``v`` is a vector (real and of length ``degree``). - - ``lower_bound`` -- either a vector or ``None``. The - component-wise lower bound. + - ``lower_bound`` -- either a vector or ``None``; the + component-wise lower bound - - ``upper_bound`` -- either a vector or ``None``. The - component-wise upper bound. + - ``upper_bound`` -- either a vector or ``None``; the + component-wise upper bound - - ``name`` -- string or ``None``. An optional name for all new - rows. + - ``name`` -- string or ``None``; an optional name for all new + rows EXAMPLES:: @@ -532,7 +533,7 @@ cdef class GenericBackend: @classmethod def _test_add_linear_constraint_vector(cls, tester=None, **options): """ - Run tests on the method :meth:`.add_linear_constraint_vector`. + Run tests on the method :meth:`add_linear_constraint_vector`. TESTS:: @@ -566,11 +567,11 @@ cdef class GenericBackend: INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint @@ -600,7 +601,7 @@ cdef class GenericBackend: @classmethod def _test_add_col(cls, tester=None, **options): """ - Run tests on the method :meth:`.add_col` + Run tests on the method :meth:`add_col`. TESTS:: @@ -610,7 +611,6 @@ cdef class GenericBackend: Traceback (most recent call last): ... NotImplementedError: ... - """ p = cls() # fresh instance of the backend if tester is None: @@ -627,7 +627,7 @@ cdef class GenericBackend: INPUT: - - ``number`` (integer) -- the number of constraints to add. + - ``number`` -- integer; the number of constraints to add - ``lower_bound`` -- a lower bound, either a real value or ``None`` @@ -655,7 +655,7 @@ cdef class GenericBackend: @classmethod def _test_add_linear_constraints(cls, tester=None, **options): """ - Run tests on the method :meth:`.add_linear_constraints`. + Run tests on the method :meth:`add_linear_constraints`. TESTS:: @@ -936,11 +936,11 @@ cdef class GenericBackend: cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: @@ -956,11 +956,11 @@ cdef class GenericBackend: cpdef write_lp(self, name): """ - Write the problem to a ``.lp`` file + Write the problem to a ``.lp`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -972,18 +972,18 @@ cdef class GenericBackend: sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3) sage: p.set_objective([2, 5]) sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".lp") as f: + sage: with NamedTemporaryFile(suffix='.lp') as f: ....: p.write_lp(f.name) """ raise NotImplementedError() cpdef write_mps(self, name, int modern): """ - Write the problem to a ``.mps`` file + Write the problem to a ``.mps`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -995,15 +995,14 @@ cdef class GenericBackend: sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) sage: p.set_objective([2, 5]) sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".lp") as f: + sage: with NamedTemporaryFile(suffix='.lp') as f: ....: p.write_lp(f.name) - """ raise NotImplementedError() cpdef copy(self): """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -1021,7 +1020,7 @@ cdef class GenericBackend: # Override this method in backends. cpdef __copy__(self): """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -1061,11 +1060,11 @@ cdef class GenericBackend: cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -1095,7 +1094,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -1124,7 +1123,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -1153,7 +1152,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1167,7 +1166,6 @@ cdef class GenericBackend: sage: p.set_variable_type(0,0) sage: p.is_variable_binary(0) True - """ raise NotImplementedError() @@ -1177,7 +1175,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1200,7 +1198,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1216,17 +1214,16 @@ cdef class GenericBackend: sage: p.set_variable_type(0,1) sage: p.is_variable_continuous(0) False - """ raise NotImplementedError() cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: @@ -1236,20 +1233,19 @@ cdef class GenericBackend: sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) sage: p.row_name(0) 'Empty constraint 1' - """ raise NotImplementedError() cpdef col_name(self, int index): """ - Return the ``index``-th column name + Return the ``index``-th column name. INPUT: - - ``index`` (integer) -- the column id + - ``index`` -- integer; the column id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: @@ -1345,11 +1341,11 @@ cdef class GenericBackend: cpdef variable_upper_bound(self, int index, value=False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``False`` @@ -1372,11 +1368,11 @@ cdef class GenericBackend: cpdef variable_lower_bound(self, int index, value=False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not lower bound. When set to ``False`` @@ -1399,14 +1395,14 @@ cdef class GenericBackend: cpdef solver_parameter(self, name, value=None): """ - Return or define a solver parameter + Return or define a solver parameter. INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value .. NOTE:: @@ -1433,7 +1429,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1464,7 +1460,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1495,7 +1491,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1526,7 +1522,7 @@ cdef class GenericBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1561,7 +1557,6 @@ cdef class GenericBackend: Traceback (most recent call last): ... NotImplementedError - """ p = cls() # fresh instance of the backend if tester is None: @@ -1589,7 +1584,7 @@ default_solver = None def default_mip_solver(solver=None): """ - Returns/sets the default MILP solver used by Sage + Return/set the default MILP solver used by Sage. INPUT: @@ -1601,14 +1596,14 @@ def default_mip_solver(solver=None): - a callable (typically a subclass of :class:`sage.numerical.backends.generic_backend.GenericBackend`); - - ``None`` (default), in which case the current default solver - is returned; this is either a string or a callable. + - ``None`` -- (default) in which case the current default solver + is returned; this is either a string or a callable OUTPUT: This function returns the current default solver's name if ``solver = None`` (default). Otherwise, it sets the default solver to the one given. If this - solver does not exist, or is not available, a :class:`ValueError` exception is + solver does not exist, or is not available, a :exc:`ValueError` exception is raised. EXAMPLES:: @@ -1723,7 +1718,7 @@ def default_mip_solver(solver=None): cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_ring=None): """ - Return a solver according to the given preferences + Return a solver according to the given preferences. INPUT: @@ -1732,13 +1727,13 @@ cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_r - a string indicating one of the available solvers (see :class:`MixedIntegerLinearProgram`); - - ``None`` (default), in which case the default solver is used + - ``None`` -- (default) in which case the default solver is used (see :func:`default_mip_solver`); - or a callable (such as a class), in which case it is called, and its result is returned. - - ``base_ring`` -- If not ``None``, request a solver that works over this + - ``base_ring`` -- if not ``None``, request a solver that works over this (ordered) field. If ``base_ring`` is not a field, its fraction field is used. @@ -1746,7 +1741,7 @@ cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_r the rational numbers. This is unrelated to whether variables are constrained to be integers or not. - - ``constraint_generation`` -- Only used when ``solver=None``. + - ``constraint_generation`` -- only used when ``solver=None``: - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, it is possible to add a constraint, and then solve it again. @@ -1757,7 +1752,7 @@ cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_r .. SEEALSO:: - - :func:`default_mip_solver` -- Returns/Sets the default MIP solver. + - :func:`default_mip_solver` -- returns/sets the default MIP solver EXAMPLES:: @@ -1798,8 +1793,8 @@ cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_r sage: def glpk_exact_solver(): ....: from sage.numerical.backends.generic_backend import get_solver - ....: b = get_solver(solver="GLPK") - ....: b.solver_parameter("simplex_or_intopt", "exact_simplex_only") + ....: b = get_solver(solver='GLPK') + ....: b.solver_parameter('simplex_or_intopt', 'exact_simplex_only') ....: return b sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4,solver=glpk_exact_solver) # long time 8 @@ -1815,7 +1810,6 @@ cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_r sage: M.get_backend() <...GLPKBackend...> sage: default_mip_solver(old_default) - """ if solver is None: diff --git a/src/sage/numerical/backends/generic_backend_test.py b/src/sage/numerical/backends/generic_backend_test.py index 3c5416eb63c..2b5411fb64e 100644 --- a/src/sage/numerical/backends/generic_backend_test.py +++ b/src/sage/numerical/backends/generic_backend_test.py @@ -19,4 +19,4 @@ def test_ncols_nonnegative(self, backend: GenericBackend): def test_sage_unittest_testsuite(self, sage_object: SageObject): # TODO: Remove this test as soon as all old test methods are migrated from sage.misc.sage_unittest import TestSuite - TestSuite(sage_object).run(verbose=True, raise_on_failure=True, skip="_test_pickling") + TestSuite(sage_object).run(verbose=True, raise_on_failure=True, skip='_test_pickling') diff --git a/src/sage/numerical/backends/generic_sdp_backend.pyx b/src/sage/numerical/backends/generic_sdp_backend.pyx index 7124afd14ab..e1ad583f41c 100644 --- a/src/sage/numerical/backends/generic_sdp_backend.pyx +++ b/src/sage/numerical/backends/generic_sdp_backend.pyx @@ -3,7 +3,7 @@ Generic Backend for SDP solvers This class only lists the methods that should be defined by any interface with a SDP Solver. All these methods immediately raise -``NotImplementedError`` exceptions when called, and are obviously +:exc:`NotImplementedError` exceptions when called, and are obviously meant to be replaced by the solver-specific method. This file can also be used as a template to create a new interface : one would only need to replace the occurrences of ``"Nonexistent_SDP_solver"`` by the @@ -30,7 +30,7 @@ cdef class GenericSDPBackend: cpdef base_ring(self): """ - The base ring + The base ring. TESTS:: @@ -43,7 +43,7 @@ cdef class GenericSDPBackend: cpdef zero(self): """ - Zero of the base ring + Zero of the base ring. TESTS:: @@ -62,11 +62,13 @@ cdef class GenericSDPBackend: INPUT: - - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) + - ``obj`` -- (optional) coefficient of this variable in the objective + function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: + ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -99,11 +101,11 @@ cdef class GenericSDPBackend: - ``n`` -- the number of new variables (must be > 0) - - ``obj`` -- (optional) coefficient of all variables in the objective function (default: 0.0) + - ``obj`` -- coefficient of all variables in the objective function (default: 0.0) - - ``names`` -- optional list of names (default: ``None``) + - ``names`` -- list of names (default: ``None``) - OUTPUT: The index of the variable created last. + OUTPUT: the index of the variable created last EXAMPLES:: @@ -127,7 +129,7 @@ cdef class GenericSDPBackend: INPUT: - - ``sense`` (integer): + - ``sense`` -- integer: * `+1` => Maximization * `-1` => Minimization @@ -152,9 +154,9 @@ cdef class GenericSDPBackend: INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient + - ``coeff`` -- double; its coefficient EXAMPLES:: @@ -177,10 +179,11 @@ cdef class GenericSDPBackend: INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: @@ -237,7 +240,7 @@ cdef class GenericSDPBackend: INPUT: - - ``number`` (integer) -- the number of constraints to add. + - ``number`` -- integer; the number of constraints to add - ``lower_bound`` -- a lower bound, either a real value or ``None`` @@ -399,11 +402,11 @@ cdef class GenericSDPBackend: cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``NULL`` (default), the method returns the problem's name. EXAMPLES:: @@ -420,11 +423,11 @@ cdef class GenericSDPBackend: cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -450,11 +453,11 @@ cdef class GenericSDPBackend: cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: @@ -464,20 +467,19 @@ cdef class GenericSDPBackend: sage: p.add_linear_constraints(1, 2, None, name="Empty constraint 1") sage: p.row_name(0) 'Empty constraint 1' - """ raise NotImplementedError() cpdef col_name(self, int index): """ - Return the ``index`` th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: @@ -493,15 +495,13 @@ cdef class GenericSDPBackend: cpdef dual_variable(self, int i, sparse=False): """ - The `i`-th dual variable - - Available after self.solve() is called, otherwise the result is undefined + The `i`-th dual variable. - - ``index`` (integer) -- the constraint's id. + Available after ``self.solve()`` is called, otherwise the result is undefined - OUTPUT: + - ``index`` -- integer; the constraint's id - The matrix of the `i`-th dual variable + OUTPUT: the matrix of the `i`-th dual variable EXAMPLES:: @@ -540,15 +540,14 @@ cdef class GenericSDPBackend: cpdef slack(self, int i, sparse=False): """ - Slack of the `i`-th constraint + Slack of the `i`-th constraint. - Available after self.solve() is called, otherwise the result is undefined + Available after ``self.solve()`` is called, otherwise the result is + undefined. - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id - OUTPUT: - - The matrix of the slack of the `i`-th constraint + OUTPUT: the matrix of the slack of the `i`-th constraint EXAMPLES:: @@ -589,14 +588,14 @@ cdef class GenericSDPBackend: cpdef solver_parameter(self, name, value=None): """ - Return or define a solver parameter + Return or define a solver parameter. INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value .. NOTE:: @@ -620,28 +619,28 @@ default_solver = None def default_sdp_solver(solver=None): """ - Return/set the default SDP solver used by Sage + Return/set the default SDP solver used by Sage. INPUT: - ``solver`` -- one of the following: - - the string ``"CVXOPT"``, to make the use of the CVXOPT solver + - the string ``'CVXOPT'``, to make the use of the CVXOPT solver (see the `CVXOPT `_ web site) the default; - a subclass of :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend`, to make it the default; or - - ``None`` (default), in which case the current default solver - (a string or a class) is returned. + - ``None`` -- (default) in which case the current default solver + (a string or a class) is returned OUTPUT: This function returns the current default solver (a string or a class) if ``solver = None`` (default). Otherwise, it sets the default solver to the one given. If this solver does not exist, or - is not available, a ``ValueError`` exception is raised. + is not available, a :exc:`ValueError` exception is raised. EXAMPLES:: @@ -659,7 +658,6 @@ def default_sdp_solver(solver=None): sage: default_sdp_solver(my_sdp_solver) sage: default_sdp_solver() is my_sdp_solver True - """ global default_solver @@ -707,18 +705,18 @@ cpdef GenericSDPBackend get_solver(solver=None, base_ring=None): - ``solver`` -- one of the following: - - the string ``"CVXOPT"``, designating the use of the CVXOPT solver + - the string ``'CVXOPT'``, designating the use of the CVXOPT solver (see the `CVXOPT `_ web site); - a subclass of - :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend`; + :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend` - - ``None`` (default), in which case the default solver is used (see - :func:`default_sdp_solver`); + - ``None`` -- (default) in which case the default solver is used (see + :func:`default_sdp_solver`) .. SEEALSO:: - - :func:`default_sdp_solver` -- Returns/Sets the default SDP solver. + - :func:`default_sdp_solver` -- returns/sets the default SDP solver EXAMPLES:: diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index f1253f461b6..dddde9a07b6 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -33,18 +33,17 @@ from sage.libs.glpk.lp cimport * cdef class GLPKBackend(GenericBackend): - """ MIP Backend that uses the GLPK solver. """ def __cinit__(self, maximization = True): """ - Constructor + Constructor. EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') """ self.lp = glp_create_prob() self.simplex_or_intopt = glp_simplex_then_intopt @@ -78,17 +77,17 @@ cdef class GLPKBackend(GenericBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integral (default: ``False``). + - ``integer`` -- ``True`` if the variable is integral (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -158,17 +157,17 @@ cdef class GLPKBackend(GenericBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is binary (default: ``True``). + - ``continuous`` -- ``True`` if the variable is binary (default: ``True``) - - ``integer`` -- ``True`` if the variable is binary (default: ``False``). + - ``integer`` -- ``True`` if the variable is binary (default: ``False``) - - ``obj`` -- (optional) coefficient of all variables in the objective function (default: 0.0) + - ``obj`` -- coefficient of all variables in the objective function (default: 0.0) - - ``names`` -- optional list of names (default: ``None``) + - ``names`` -- list of names (default: ``None``) - OUTPUT: The index of the variable created last. + OUTPUT: the index of the variable created last EXAMPLES:: @@ -230,13 +229,13 @@ cdef class GLPKBackend(GenericBackend): cpdef set_variable_type(self, int variable, int vtype): """ - Set the type of a variable + Set the type of a variable. INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``vtype`` (integer) : + - ``vtype`` -- integer: * 1 Integer * 0 Binary @@ -259,12 +258,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.set_variable_type(2,0) Traceback (most recent call last): ... ValueError: invalid variable index 2 - """ if variable < 0 or variable > (self.ncols() - 1): raise ValueError("invalid variable index %d" % variable) @@ -284,7 +282,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``sense`` (integer) : + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -306,13 +304,13 @@ cdef class GLPKBackend(GenericBackend): cpdef objective_coefficient(self, int variable, coeff=None): """ - Set or get the coefficient of a variable in the objective function + Set or get the coefficient of a variable in the objective function. INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient or ``None`` for + - ``coeff`` -- double; its coefficient or ``None`` for reading (default: ``None``) EXAMPLES:: @@ -332,12 +330,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.objective_coefficient(2) Traceback (most recent call last): ... ValueError: invalid variable index 2 - """ if variable < 0 or variable > (self.ncols() - 1): raise ValueError("invalid variable index %d" % variable) @@ -349,11 +346,11 @@ cdef class GLPKBackend(GenericBackend): cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: @@ -385,10 +382,11 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: @@ -411,15 +409,15 @@ cdef class GLPKBackend(GenericBackend): cpdef set_verbosity(self, int level): """ - Set the verbosity level + Set the verbosity level. INPUT: - - ``level`` (integer) -- From 0 (no verbosity) to 3. + - ``level`` -- integer; from 0 (no verbosity) to 3 EXAMPLES:: - sage: p. = MixedIntegerLinearProgram(solver="GLPK") + sage: p. = MixedIntegerLinearProgram(solver='GLPK') sage: p.add_constraint(10 * x[0] <= 1) sage: p.add_constraint(5 * x[1] <= 1) sage: p.set_objective(x[0] + x[1]) @@ -438,7 +436,7 @@ cdef class GLPKBackend(GenericBackend): :: - sage: p. = MixedIntegerLinearProgram(solver="GLPK/exact") + sage: p. = MixedIntegerLinearProgram(solver='GLPK/exact') sage: p.add_constraint(10 * x[0] <= 1) sage: p.add_constraint(5 * x[1] <= 1) sage: p.set_objective(x[0] + x[1]) @@ -473,7 +471,7 @@ cdef class GLPKBackend(GenericBackend): cpdef remove_constraint(self, int i): r""" - Remove a constraint from self. + Remove a constraint from ``self``. INPUT: @@ -516,7 +514,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``constraints`` -- an iterable containing the indices of the rows to remove. + - ``constraints`` -- an iterable containing the indices of the rows to remove EXAMPLES:: @@ -597,13 +595,12 @@ cdef class GLPKBackend(GenericBackend): This used to crash Sage, but was fixed in :issue:`19525`:: - sage: p = MixedIntegerLinearProgram(solver="glpk") - sage: q = MixedIntegerLinearProgram(solver="glpk") + sage: p = MixedIntegerLinearProgram(solver='glpk') + sage: q = MixedIntegerLinearProgram(solver='glpk') sage: q.add_constraint(p.new_variable()[0] <= 1) Traceback (most recent call last): ... ValueError: invalid variable index 0 - """ if lower_bound is None and upper_bound is None: raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.") @@ -655,7 +652,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``number`` (integer) -- the number of constraints to add. + - ``number`` -- integer; the number of constraints to add - ``lower_bound`` -- a lower bound, either a real value or ``None`` @@ -699,11 +696,11 @@ cdef class GLPKBackend(GenericBackend): cpdef row(self, int index): r""" - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -729,12 +726,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.row(2) Traceback (most recent call last): ... ValueError: invalid row index 2 - """ if index < 0 or index > (self.nrows() - 1): raise ValueError("invalid row index %d" % index) @@ -760,7 +756,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -785,12 +781,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.row_bounds(2) Traceback (most recent call last): ... ValueError: invalid row index 2 - """ cdef double ub cdef double lb @@ -812,7 +807,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -837,12 +832,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.col_bounds(2) Traceback (most recent call last): ... ValueError: invalid column index 2 - """ cdef double ub @@ -865,15 +859,15 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it - appears. Namely, the ith entry of ``coeffs`` corresponds to + appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint - represented by the ith entry in ``indices``. + represented by the i-th entry in ``indices``. .. NOTE:: @@ -1098,7 +1092,7 @@ cdef class GLPKBackend(GenericBackend): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("mip_gap_tolerance",100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -1152,7 +1146,7 @@ cdef class GLPKBackend(GenericBackend): cpdef get_objective_value(self): """ - Returns the value of the objective function. + Return the value of the objective function. .. NOTE:: @@ -1200,7 +1194,7 @@ cdef class GLPKBackend(GenericBackend): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("mip_gap_tolerance",100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -1235,7 +1229,7 @@ cdef class GLPKBackend(GenericBackend): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("mip_gap_tolerance",100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -1260,7 +1254,7 @@ cdef class GLPKBackend(GenericBackend): cpdef get_variable_value(self, int variable): """ - Returns the value of a variable given by the solver. + Return the value of a variable given by the solver. .. NOTE:: @@ -1288,12 +1282,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.get_variable_value(2) Traceback (most recent call last): ... ValueError: invalid variable index 2 - """ if variable < 0 or variable > (self.ncols() - 1): raise ValueError("invalid variable index %d" % variable) @@ -1306,7 +1299,7 @@ cdef class GLPKBackend(GenericBackend): cpdef get_row_prim(self, int i): r""" - Returns the value of the auxiliary variable associated with i-th row. + Return the value of the auxiliary variable associated with i-th row. .. NOTE:: @@ -1340,12 +1333,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.get_row_prim(2) Traceback (most recent call last): ... ValueError: invalid row index 2 - """ if i < 0 or i > (self.nrows() - 1): raise ValueError("invalid row index %d" % i) @@ -1388,11 +1380,11 @@ cdef class GLPKBackend(GenericBackend): cpdef col_name(self, int index): """ - Return the ``index`` th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id EXAMPLES:: @@ -1408,12 +1400,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.col_name(2) Traceback (most recent call last): ... ValueError: invalid column index 2 - """ cdef char * s @@ -1430,11 +1421,11 @@ cdef class GLPKBackend(GenericBackend): cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: @@ -1449,12 +1440,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.row_name(2) Traceback (most recent call last): ... ValueError: invalid row index 2 - """ cdef char * s @@ -1475,7 +1465,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1494,10 +1484,9 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.is_variable_binary(2) False - """ if index < 0 or index > (self.ncols() - 1): # This is how the other backends behave, and this method is @@ -1512,7 +1501,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1531,10 +1520,9 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.is_variable_integer(2) False - """ if index < 0 or index > (self.ncols() - 1): # This is how the other backends behave, and this method is @@ -1549,7 +1537,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1570,10 +1558,9 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.is_variable_continuous(2) False - """ if index < 0 or index > (self.ncols() - 1): # This is how the other backends behave, and this method is @@ -1601,11 +1588,11 @@ cdef class GLPKBackend(GenericBackend): cpdef variable_upper_bound(self, int index, value=False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``False`` @@ -1627,7 +1614,7 @@ cdef class GLPKBackend(GenericBackend): :issue:`14581`:: - sage: P = MixedIntegerLinearProgram(solver="GLPK") + sage: P = MixedIntegerLinearProgram(solver='GLPK') sage: x = P["x"] sage: P.set_max(x, 0) sage: P.get_max(x) @@ -1635,7 +1622,7 @@ cdef class GLPKBackend(GenericBackend): Check that :issue:`10232` is fixed:: - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.variable_upper_bound(2) Traceback (most recent call last): ... @@ -1700,11 +1687,11 @@ cdef class GLPKBackend(GenericBackend): cpdef variable_lower_bound(self, int index, value=False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not lower bound. When set to ``False`` @@ -1726,7 +1713,7 @@ cdef class GLPKBackend(GenericBackend): :issue:`14581`:: - sage: P = MixedIntegerLinearProgram(solver="GLPK") + sage: P = MixedIntegerLinearProgram(solver='GLPK') sage: x = P["x"] sage: P.set_min(x, 5) sage: P.set_min(x, 0) @@ -1735,7 +1722,7 @@ cdef class GLPKBackend(GenericBackend): Check that :issue:`10232` is fixed:: - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.variable_lower_bound(2) Traceback (most recent call last): ... @@ -1800,11 +1787,11 @@ cdef class GLPKBackend(GenericBackend): cpdef write_lp(self, filename): """ - Write the problem to a .lp file + Write the problem to a ``.lp`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -1815,7 +1802,7 @@ cdef class GLPKBackend(GenericBackend): sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3) sage: p.set_objective([2, 5]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".lp") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.lp') as f: ....: _ = p.write_lp(f.name) ....: len(f.readlines()) ... @@ -1827,11 +1814,11 @@ cdef class GLPKBackend(GenericBackend): cpdef write_mps(self, filename, int modern): """ - Write the problem to a .mps file + Write the problem to a ``.mps`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -1842,7 +1829,7 @@ cdef class GLPKBackend(GenericBackend): sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3) sage: p.set_objective([2, 5]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix="mps") as f: + sage: with tempfile.NamedTemporaryFile(suffix='mps') as f: ....: _ = p.write_mps(f.name, 2) ....: len(f.readlines()) ... @@ -1854,7 +1841,7 @@ cdef class GLPKBackend(GenericBackend): cpdef __copy__(self): """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -1874,14 +1861,14 @@ cdef class GLPKBackend(GenericBackend): cpdef solver_parameter(self, name, value=None): """ - Return or define a solver parameter + Return or define a solver parameter. INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value You can supply the name of a parameter and its value using either a string or a ``glp_`` constant (which are defined as Cython variables of @@ -1898,7 +1885,7 @@ cdef class GLPKBackend(GenericBackend): Parameter **names** are specified in lower case. To use a constant instead of a string, prepend ``glp_`` to the name. - For example, both ``glp_gmi_cuts`` or ``"gmi_cuts"`` control whether + For example, both ``glp_gmi_cuts`` or ``'gmi_cuts'`` control whether to solve using Gomory cuts. Parameter **values** are specified as strings in upper case, @@ -2014,7 +2001,7 @@ cdef class GLPKBackend(GenericBackend): * - ``presolve_intopt`` - - ``GLP_ON`` (default) or ``GLP_OFF``. + - ``GLP_ON`` (default) or ``GLP_OFF`` * - ``binarize`` @@ -2330,12 +2317,12 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="GLPK") + solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -2360,12 +2347,12 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="GLPK") + solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -2391,12 +2378,12 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="GLPK") + solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -2422,12 +2409,12 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="GLPK") + solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -2456,9 +2443,7 @@ cdef class GLPKBackend(GenericBackend): - ``filename`` -- (optional) name of the file - OUTPUT: - - Zero if the operations was successful otherwise nonzero. + OUTPUT: zero if the operations was successful otherwise nonzero .. NOTE:: @@ -2482,7 +2467,7 @@ cdef class GLPKBackend(GenericBackend): sage: p.solve() 0 sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(mode="r+t", suffix=".tmp") as f: + sage: with NamedTemporaryFile(mode='r+t', suffix='.tmp') as f: ....: p.print_ranges(f.name) ....: for ll in f.readlines(): ....: if ll: print(ll) @@ -2529,9 +2514,9 @@ cdef class GLPKBackend(GenericBackend): cpdef double get_row_dual(self, int variable) noexcept: r""" - Returns the dual value of a constraint. + Return the dual value of a constraint. - The dual value of the ith row is also the value of the ith variable + The dual value of the i-th row is also the value of the i-th variable of the dual problem. The dual value of a constraint is the shadow price of the constraint. @@ -2541,7 +2526,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``variable`` -- The number of the constraint + - ``variable`` -- the number of the constraint .. NOTE:: @@ -2567,8 +2552,6 @@ cdef class GLPKBackend(GenericBackend): 0.0 sage: lp.get_row_dual(1) # tolerance 0.00001 10.0 - - """ if self.simplex_or_intopt == simplex_only: @@ -2578,7 +2561,7 @@ cdef class GLPKBackend(GenericBackend): cpdef double get_col_dual(self, int variable) except? -1: """ - Returns the dual value (reduced cost) of a variable + Return the dual value (reduced cost) of a variable The dual value is the reduced cost of a variable. The reduced cost is the amount by which the objective coefficient @@ -2586,7 +2569,7 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``variable`` -- The number of the variable + - ``variable`` -- the number of the variable .. NOTE:: @@ -2594,7 +2577,6 @@ cdef class GLPKBackend(GenericBackend): If the simplex algorithm has not been used for solving just a 0.0 will be returned. - EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver @@ -2617,12 +2599,11 @@ cdef class GLPKBackend(GenericBackend): We sanity check the input that will be passed to GLPK:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="GLPK") + sage: p = get_solver(solver='GLPK') sage: p.get_col_dual(2) Traceback (most recent call last): ... ValueError: invalid column index 2 - """ if variable < 0 or variable > (self.ncols() - 1): raise ValueError("invalid column index %d" % variable) @@ -2638,11 +2619,12 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``i`` -- The index of the constraint + - ``i`` -- the index of the constraint OUTPUT: - - Returns current status assigned to the auxiliary variable associated with i-th row: + Current status assigned to the auxiliary variable associated with i-th + row: * GLP_BS = 1 basic variable * GLP_NL = 2 non-basic variable on lower bound @@ -2683,11 +2665,12 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``j`` -- The index of the variable + - ``j`` -- the index of the variable OUTPUT: - - Returns current status assigned to the structural variable associated with j-th column: + Current status assigned to the structural variable associated + with j-th column: * GLP_BS = 1 basic variable * GLP_NL = 2 non-basic variable on lower bound @@ -2729,9 +2712,9 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``i`` -- The index of the constraint + - ``i`` -- the index of the constraint - - ``stat`` -- The status to set to + - ``stat`` -- the status to set to EXAMPLES:: @@ -2764,9 +2747,9 @@ cdef class GLPKBackend(GenericBackend): INPUT: - - ``j`` -- The index of the constraint + - ``j`` -- the index of the constraint - - ``stat`` -- The status to set to + - ``stat`` -- the status to set to EXAMPLES:: @@ -2797,9 +2780,7 @@ cdef class GLPKBackend(GenericBackend): r""" Warm up the basis using current statuses assigned to rows and cols. - OUTPUT: - - - Returns the warming up status + OUTPUT: the warming up status * 0 The operation has been successfully performed. * GLP_EBADB The basis matrix is invalid. @@ -2831,7 +2812,7 @@ cdef class GLPKBackend(GenericBackend): cpdef eval_tab_row(self, int k): r""" - Computes a row of the current simplex tableau. + Compute a row of the current simplex tableau. A row corresponds to some basic variable specified by the parameter ``k`` as follows: @@ -2848,12 +2829,12 @@ cdef class GLPKBackend(GenericBackend): .. NOTE:: The basis factorization must exist and the variable with - index ``k`` must be basic. Otherwise, a ``ValueError`` is + index ``k`` must be basic. Otherwise, a :exc:`ValueError` is be raised. INPUT: - - ``k`` (integer) -- the id of the basic variable. + - ``k`` -- integer; the id of the basic variable OUTPUT: @@ -2899,7 +2880,6 @@ cdef class GLPKBackend(GenericBackend): Traceback (most recent call last): ... ValueError: ... - """ cdef int m = self.nrows() cdef int n = self.ncols() @@ -2930,7 +2910,7 @@ cdef class GLPKBackend(GenericBackend): cpdef eval_tab_col(self, int k): r""" - Computes a column of the current simplex tableau. + Compute a column of the current simplex tableau. A (column) corresponds to some non-basic variable specified by the parameter ``k`` as follows: @@ -2947,12 +2927,12 @@ cdef class GLPKBackend(GenericBackend): .. NOTE:: The basis factorization must exist and the variable with - index ``k`` must not be basic. Otherwise, a ``ValueError`` is + index ``k`` must not be basic. Otherwise, a :exc:`ValueError` is be raised. INPUT: - - ``k`` (integer) -- the id of the non-basic variable. + - ``k`` -- integer; the id of the non-basic variable OUTPUT: @@ -2998,7 +2978,6 @@ cdef class GLPKBackend(GenericBackend): Traceback (most recent call last): ... ValueError: ... - """ cdef int m = self.nrows() cdef int n = self.ncols() @@ -3050,7 +3029,6 @@ cdef void glp_callback(glp_tree* tree, void* info) noexcept: - ``info`` -- a ``void *`` to let the function know *where* it should store the data we need. The value of ``info`` is equal to the one stored in iocp.cb_info. - """ cdef search_tree_data_t * data = info data.mip_gap = glp_ios_mip_gap(tree) diff --git a/src/sage/numerical/backends/glpk_backend_test.py b/src/sage/numerical/backends/glpk_backend_test.py index b41b1ae80c8..5204b66e73d 100644 --- a/src/sage/numerical/backends/glpk_backend_test.py +++ b/src/sage/numerical/backends/glpk_backend_test.py @@ -9,4 +9,4 @@ class TestGLPKBackend(GenericBackendTests): @pytest.fixture def backend(self) -> GenericBackend: - return MixedIntegerLinearProgram(solver="GLPK").get_backend() + return MixedIntegerLinearProgram(solver='GLPK').get_backend() diff --git a/src/sage/numerical/backends/glpk_exact_backend.pyx b/src/sage/numerical/backends/glpk_exact_backend.pyx index 8030e1710d3..a9289264a42 100644 --- a/src/sage/numerical/backends/glpk_exact_backend.pyx +++ b/src/sage/numerical/backends/glpk_exact_backend.pyx @@ -15,7 +15,6 @@ AUTHORS: ############################################################################## cdef class GLPKExactBackend(GLPKBackend): - """ MIP Backend that runs the GLPK solver in exact rational simplex mode. @@ -31,11 +30,11 @@ cdef class GLPKExactBackend(GLPKBackend): """ def __cinit__(self, maximization = True): """ - Constructor + Constructor. EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="GLPK/exact") + sage: p = MixedIntegerLinearProgram(solver='GLPK/exact') """ # inherited __cinit__ is called automatically import sage.numerical.backends.glpk_backend as glpk_backend @@ -58,17 +57,17 @@ cdef class GLPKExactBackend(GLPKBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integer (default: ``False``). + - ``integer`` -- ``True`` if the variable is integer (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -126,17 +125,17 @@ cdef class GLPKExactBackend(GLPKBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is binary (default: ``True``). + - ``continuous`` -- ``True`` if the variable is binary (default: ``True``) - - ``integer`` -- ``True`` if the variable is binary (default: ``False``). + - ``integer`` -- ``True`` if the variable is binary (default: ``False``) - - ``obj`` -- (optional) coefficient of all variables in the objective function (default: 0.0) + - ``obj`` -- coefficient of all variables in the objective function (default: 0.0) - - ``names`` -- optional list of names (default: ``None``) + - ``names`` -- list of names (default: ``None``) - OUTPUT: The index of the variable created last. + OUTPUT: the index of the variable created last EXAMPLES:: @@ -166,9 +165,9 @@ cdef class GLPKExactBackend(GLPKBackend): INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``vtype`` (integer) : + - ``vtype`` -- integer: * 1 Integer * 0 Binary diff --git a/src/sage/numerical/backends/glpk_exact_backend_test.py b/src/sage/numerical/backends/glpk_exact_backend_test.py index cffc87e3844..125e041f29e 100644 --- a/src/sage/numerical/backends/glpk_exact_backend_test.py +++ b/src/sage/numerical/backends/glpk_exact_backend_test.py @@ -7,4 +7,4 @@ class TestGLPKExactBackend(GenericBackendTests): @pytest.fixture def backend(self) -> GenericBackend: - return MixedIntegerLinearProgram(solver="GLPK/exact").get_backend() + return MixedIntegerLinearProgram(solver='GLPK/exact').get_backend() diff --git a/src/sage/numerical/backends/glpk_graph_backend.pyx b/src/sage/numerical/backends/glpk_graph_backend.pyx index 63bc2a76305..2a89dfe0bd1 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pyx +++ b/src/sage/numerical/backends/glpk_graph_backend.pyx @@ -16,21 +16,21 @@ Methods index :widths: 30, 70 :delim: | - :meth:`~GLPKGraphBackend.add_vertex` | Adds an isolated vertex to the graph. - :meth:`~GLPKGraphBackend.add_vertices` | Adds vertices from an iterable container of vertices. - :meth:`~GLPKGraphBackend.set_vertex_demand` | Sets the vertex parameters. - :meth:`~GLPKGraphBackend.set_vertices_demand` | Sets the parameters of selected vertices. - :meth:`~GLPKGraphBackend.get_vertex` | Returns a specific vertex as a ``dict`` Object. - :meth:`~GLPKGraphBackend.get_vertices` | Returns a dictionary of the dictionaries associated to each vertex. - :meth:`~GLPKGraphBackend.vertices` | Returns a ``list`` of all vertices. - :meth:`~GLPKGraphBackend.delete_vertex` | Removes a vertex from the graph. - :meth:`~GLPKGraphBackend.delete_vertices` | Removes vertices from the graph. - :meth:`~GLPKGraphBackend.add_edge` | Adds an edge between vertices ``u`` and ``v``. - :meth:`~GLPKGraphBackend.add_edges` | Adds edges to the graph. - :meth:`~GLPKGraphBackend.get_edge` | Returns an edge connecting two vertices. - :meth:`~GLPKGraphBackend.edges` | Returns a ``list`` of all edges in the graph. - :meth:`~GLPKGraphBackend.delete_edge` | Deletes an edge from the graph. - :meth:`~GLPKGraphBackend.delete_edges` | Deletes edges from the graph. + :meth:`~GLPKGraphBackend.add_vertex` | Add an isolated vertex to the graph. + :meth:`~GLPKGraphBackend.add_vertices` | Add vertices from an iterable container of vertices. + :meth:`~GLPKGraphBackend.set_vertex_demand` | Set the vertex parameters. + :meth:`~GLPKGraphBackend.set_vertices_demand` | Set the parameters of selected vertices. + :meth:`~GLPKGraphBackend.get_vertex` | Return a specific vertex as a dictionary Object. + :meth:`~GLPKGraphBackend.get_vertices` | Return a dictionary of the dictionaries associated to each vertex. + :meth:`~GLPKGraphBackend.vertices` | Return a ``list`` of all vertices. + :meth:`~GLPKGraphBackend.delete_vertex` | Remove a vertex from the graph. + :meth:`~GLPKGraphBackend.delete_vertices` | Remove vertices from the graph. + :meth:`~GLPKGraphBackend.add_edge` | Add an edge between vertices ``u`` and ``v``. + :meth:`~GLPKGraphBackend.add_edges` | Add edges to the graph. + :meth:`~GLPKGraphBackend.get_edge` | Return an edge connecting two vertices. + :meth:`~GLPKGraphBackend.edges` | Return a ``list`` of all edges in the graph. + :meth:`~GLPKGraphBackend.delete_edge` | Delete an edge from the graph. + :meth:`~GLPKGraphBackend.delete_edges` | Delete edges from the graph. **Graph writing operations:** @@ -39,10 +39,10 @@ Methods index :widths: 30, 70 :delim: | - :meth:`~GLPKGraphBackend.write_graph` | Writes the graph to a plain text file. - :meth:`~GLPKGraphBackend.write_ccdata` | Writes the graph to a text file in DIMACS format. - :meth:`~GLPKGraphBackend.write_mincost` | Writes the mincost flow problem data to a text file in DIMACS format. - :meth:`~GLPKGraphBackend.write_maxflow` | Writes the maximum flow problem data to a text file in DIMACS format. + :meth:`~GLPKGraphBackend.write_graph` | Write the graph to a plain text file. + :meth:`~GLPKGraphBackend.write_ccdata` | Write the graph to a text file in DIMACS format. + :meth:`~GLPKGraphBackend.write_mincost` | Write the mincost flow problem data to a text file in DIMACS format. + :meth:`~GLPKGraphBackend.write_maxflow` | Write the maximum flow problem data to a text file in DIMACS format. **Network optimization operations:** @@ -51,9 +51,9 @@ Methods index :widths: 30, 70 :delim: | - :meth:`~GLPKGraphBackend.mincost_okalg` | Finds solution to the mincost problem with the out-of-kilter algorithm. - :meth:`~GLPKGraphBackend.maxflow_ffalg` | Finds solution to the maxflow problem with Ford-Fulkerson algorithm. - :meth:`~GLPKGraphBackend.cpp` | Solves the critical path problem of a project network. + :meth:`~GLPKGraphBackend.mincost_okalg` | Find solution to the mincost problem with the out-of-kilter algorithm. + :meth:`~GLPKGraphBackend.maxflow_ffalg` | Find solution to the maxflow problem with Ford-Fulkerson algorithm. + :meth:`~GLPKGraphBackend.cpp` | Solve the critical path problem of a project network. Classes and methods ------------------- @@ -79,14 +79,14 @@ from sage.numerical.mip import MIPSolverException cdef class GLPKGraphBackend(): """ - GLPK Backend for access to GLPK graph functions + GLPK Backend for access to GLPK graph functions. The constructor can either be called without arguments (which results in an empty graph) or with arguments to read graph data from a file. INPUT: - - ``data`` -- a filename or a :class:`Graph` object. + - ``data`` -- a filename or a :class:`Graph` object - ``format`` -- when ``data`` is a filename, specifies the format of the data read from a file. The ``format`` parameter is a string and can take @@ -143,7 +143,7 @@ cdef class GLPKGraphBackend(): * edges -- The edge values used in the algorithms are read from the edges labels (and left undefined if the edge labels are equal to - ``None``). To be defined, the labels must be ``dict`` objects with + ``None``). To be defined, the labels must be dictionary objects with keys "low", "cap" and "cost". See :meth:`get_edge` for details. EXAMPLES: @@ -185,7 +185,7 @@ cdef class GLPKGraphBackend(): def __cinit__(self, data = None, format = "plain"): """ - Constructor + Constructor. The constructor can either be called without arguments creating an empty graph or with arguments to read graph data from a file or a Sage @@ -233,17 +233,17 @@ cdef class GLPKGraphBackend(): cpdef add_vertex(self, name=None): """ - Adds an isolated vertex to the graph. + Add an isolated vertex to the graph. If the vertex already exists, nothing is done. INPUT: - - ``name`` -- ``str`` of max 255 chars length. If no name is - specified, then the vertex will be represented by the string - representation of the ID of the vertex or - if this already exists - - a string representation of the least integer not already representing - a vertex. + - ``name`` -- string of max 255 chars length. If no name is + specified, then the vertex will be represented by the string + representation of the ID of the vertex or - if this already exists - + a string representation of the least integer not already representing + a vertex. OUTPUT: @@ -287,7 +287,7 @@ cdef class GLPKGraphBackend(): cpdef __add_vertices_sage(self, g): """ - Adds vertices to the GLPK Graph. + Add vertices to the GLPK Graph. This function is only used when importing a :class:`~sage.graphs.generic_graph.GenericGraph` object. @@ -329,14 +329,14 @@ cdef class GLPKGraphBackend(): cpdef list add_vertices(self, vertices): """ - Adds vertices from an iterable container of vertices. + Add vertices from an iterable container of vertices. Vertices that already exist in the graph will not be added again. INPUT: - - ``vertices`` -- iterator of vertex labels (``str``). A label can be - ``None``. + - ``vertices`` -- iterator of vertex labels (string); a label can be + ``None`` OUTPUT: @@ -381,11 +381,11 @@ cdef class GLPKGraphBackend(): cpdef set_vertex_demand(self, vertex, demand): """ - Sets the demand of the vertex in a mincost flow algorithm. + Set the demand of the vertex in a mincost flow algorithm. INPUT: - - ``vertex`` -- Name of the vertex + - ``vertex`` -- name of the vertex - ``demand`` -- the numerical value representing demand of the vertex in a mincost flow algorithm (it could be for instance `-1` to represent a @@ -418,11 +418,11 @@ cdef class GLPKGraphBackend(): cpdef set_vertices_demand(self, list pairs): """ - Sets the parameters of selected vertices. + Set the parameters of selected vertices. INPUT: - - ``pairs`` -- A list of pairs ``(vertex, demand)`` associating a demand + - ``pairs`` -- list of pairs ``(vertex, demand)`` associating a demand to each vertex. For more information, see the documentation of :meth:`set_vertex_demand`. @@ -446,16 +446,16 @@ cdef class GLPKGraphBackend(): cpdef dict get_vertex(self, vertex): """ - Returns a specific vertex as a ``dict`` Object. + Return a specific vertex as a dictionary Object. INPUT: - - ``vertex`` -- The vertex label as ``str``. + - ``vertex`` -- the vertex label as string OUTPUT: - The vertex as a ``dict`` object or ``None`` if the vertex does not - exist. The ``dict`` contains the values used or created by the different + The vertex as a dictionary object or ``None`` if the vertex does not + exist. The dictionary contains the values used or created by the different algorithms. The values associated with the keys following keys contain: * "rhs" -- The supply / demand value the vertex (mincost alg) @@ -484,16 +484,16 @@ cdef class GLPKGraphBackend(): cdef c_v_data * vdata = vert.data return { - "rhs" : vdata.rhs, - "pi" : vdata.pi, - "cut" : vdata.cut, - "es" : vdata.es, - "ls" : vdata.ls + "rhs": vdata.rhs, + "pi": vdata.pi, + "cut": vdata.cut, + "es": vdata.es, + "ls": vdata.ls } cpdef dict get_vertices(self, verts): """ - Returns a dictionary of the dictionaries associated to each vertex. + Return a dictionary of the dictionaries associated to each vertex. INPUT: @@ -522,7 +522,7 @@ cdef class GLPKGraphBackend(): cpdef list vertices(self): """ - Returns the list of all vertices + Return the list of all vertices. .. NOTE:: @@ -554,25 +554,25 @@ cdef class GLPKGraphBackend(): cpdef add_edge(self, u, v, dict params=None): """ - Adds an edge between vertices ``u`` and ``v``. + Add an edge between vertices ``u`` and ``v``. Allows adding an edge and optionally providing parameters used by the algorithms. If a vertex does not exist it is created. INPUT: - - ``u`` -- The name (as ``str``) of the tail vertex + - ``u`` -- the name (as string) of the tail vertex - - ``v`` -- The name (as ``str``) of the head vertex + - ``v`` -- the name (as string) of the head vertex - - ``params`` -- An optional ``dict`` containing the edge parameters used + - ``params`` -- an optional dictionary containing the edge parameters used for the algorithms. The following keys are used: - * ``low`` -- The minimum flow through the edge + * ``low`` -- the minimum flow through the edge - * ``cap`` -- The maximum capacity of the edge + * ``cap`` -- the maximum capacity of the edge - * ``cost`` -- The cost of transporting one unit through the edge + * ``cost`` -- the cost of transporting one unit through the edge EXAMPLES:: @@ -618,14 +618,14 @@ cdef class GLPKGraphBackend(): cpdef list add_edges(self, edges): """ - Adds edges to the graph. + Add edges to the graph. INPUT: - - ``edges`` -- An iterable container of pairs of the form ``(u, v)``, - where ``u`` is name (as ``str``) of the tail vertex and ``v`` is the - name (as ``str``) of the head vertex or an iterable container of - triples of the form ``(u, v, params)`` where params is a ``dict`` as + - ``edges`` -- an iterable container of pairs of the form ``(u, v)``, + where ``u`` is name (as string) of the tail vertex and ``v`` is the + name (as string) of the head vertex or an iterable container of + triples of the form ``(u, v, params)`` where params is a dictionary as described in ``add_edge``. EXAMPLES:: @@ -656,7 +656,7 @@ cdef class GLPKGraphBackend(): cpdef __add_edges_sage(self, g): """ - Adds edges to the Graph. + Add edges to the Graph. This function is only used when importing a ``GenericGraph``. @@ -711,7 +711,7 @@ cdef class GLPKGraphBackend(): cpdef tuple get_edge(self, u, v): """ - Returns an edge connecting two vertices. + Return an edge connecting two vertices. .. NOTE:: @@ -720,19 +720,19 @@ cdef class GLPKGraphBackend(): INPUT: - - ``u`` -- Name (as ``str``) of the tail vertex - - ``v`` -- Name (as ``str``) of the head vertex + - ``u`` -- name (as string) of the tail vertex + - ``v`` -- name (as string) of the head vertex OUTPUT: A ``triple`` describing if edge was found or ``None`` if not. The third - value of the triple is a ``dict`` containing the following edge + value of the triple is a dictionary containing the following edge parameters: - * ``low`` -- The minimum flow through the edge - * ``cap`` -- The maximum capacity of the edge - * ``cost`` -- The cost of transporting one unit through the edge - * ``x`` -- The actual flow through the edge after solving + * ``low`` -- the minimum flow through the edge + * ``cap`` -- the maximum capacity of the edge + * ``cost`` -- the cost of transporting one unit through the edge + * ``x`` -- the actual flow through the edge after solving EXAMPLES:: @@ -767,11 +767,9 @@ cdef class GLPKGraphBackend(): cpdef list edges(self): """ - Returns a ``list`` of all edges in the graph + Return a ``list`` of all edges in the graph. - OUTPUT: - - A ``list`` of ``triples`` representing the edges of the graph. + OUTPUT: a ``list`` of ``triples`` representing the edges of the graph EXAMPLES:: @@ -822,7 +820,7 @@ cdef class GLPKGraphBackend(): INPUT: - - ``vert`` -- The name (as ``str``) of the vertex to delete. + - ``vert`` -- the name (as string) of the vertex to delete EXAMPLES:: @@ -858,7 +856,7 @@ cdef class GLPKGraphBackend(): INPUT: - - ``verts`` -- iterable container containing names (as ``str``) of the + - ``verts`` -- iterable container containing names (as string) of the vertices to delete EXAMPLES:: @@ -896,15 +894,15 @@ cdef class GLPKGraphBackend(): cpdef delete_edge(self, u, v, dict params=None): """ - Deletes an edge from the graph. + Delete an edge from the graph. If an edge does not exist it is ignored. INPUT: - - ``u`` -- The name (as ``str``) of the tail vertex of the edge - - ``v`` -- The name (as ``str``) of the tail vertex of the edge - - ``params`` -- ``params`` -- An optional ``dict`` containing the edge + - ``u`` -- the name (as string) of the tail vertex of the edge + - ``v`` -- the name (as string) of the tail vertex of the edge + - ``params`` -- an optional dictionary containing the edge parameters (see :meth:`add_edge`). If this parameter is not provided, all edges connecting ``u`` and ``v`` are deleted. Otherwise only edges with matching parameters are deleted. @@ -975,13 +973,13 @@ cdef class GLPKGraphBackend(): def delete_edges(self, edges): """ - Deletes edges from the graph. + Delete edges from the graph. Non existing edges are ignored. INPUT: - - ``edges`` -- An iterable container of edges. + - ``edges`` -- an iterable container of edges .. SEEALSO:: @@ -1008,15 +1006,13 @@ cdef class GLPKGraphBackend(): cpdef int _find_vertex(self, name) noexcept: """ - Returns the index of a vertex specified by a name + Return the index of a vertex specified by a name INPUT: - - ``name`` -- Name of the vertex - - OUTPUT: + - ``name`` -- name of the vertex - The index of the vertex or ``-1`` if the vertex is not found + OUTPUT: the index of the vertex or ``-1`` if the vertex is not found EXAMPLES:: @@ -1041,9 +1037,7 @@ cdef class GLPKGraphBackend(): - ``fname`` -- full name of the file - OUTPUT: - - Zero if the operations was successful otherwise nonzero + OUTPUT: zero if the operations was successful otherwise nonzero EXAMPLES:: @@ -1073,9 +1067,7 @@ cdef class GLPKGraphBackend(): - ``fname`` -- full name of the file - OUTPUT: - - Zero if the operations was successful otherwise nonzero + OUTPUT: zero if the operations was successful otherwise nonzero EXAMPLES:: @@ -1099,11 +1091,9 @@ cdef class GLPKGraphBackend(): INPUT: - - ``fname`` -- Full name of file + - ``fname`` -- full name of file - OUTPUT: - - Zero if successful, otherwise nonzero + OUTPUT: zero if successful, otherwise nonzero EXAMPLES:: @@ -1198,11 +1188,11 @@ cdef class GLPKGraphBackend(): INPUT: - - ``fname`` -- Full name of file + - ``fname`` -- full name of file OUTPUT: - ``Zero`` if successful, otherwise ``non-zero`` + ``Zero`` if successful, otherwise ``nonzero`` EXAMPLES:: @@ -1224,7 +1214,6 @@ cdef class GLPKGraphBackend(): Writing maximum flow problem data to ... 6 lines were written 0 - """ if self.graph.nv <= 0: @@ -1240,8 +1229,8 @@ cdef class GLPKGraphBackend(): INPUT: - - ``u`` -- Name (as ``str``) of the tail vertex. Default is ``None``. - - ``v`` -- Name (as ``str``) of the head vertex. Default is ``None``. + - ``u`` -- name (as string) of the tail vertex; default is ``None`` + - ``v`` -- name (as string) of the head vertex; default is ``None`` If ``u`` or ``v`` are ``None``, the currently stored values for the head or tail vertex are used. This behavior is useful when reading @@ -1249,16 +1238,14 @@ cdef class GLPKGraphBackend(): ``u`` and ``v``, the head and tail vertex are stored for later use. - OUTPUT: - - The solution to the maxflow problem, i.e. the maximum flow. + OUTPUT: the solution to the maxflow problem, i.e. the maximum flow .. NOTE:: - * If the source or sink vertex does not exist, an ``IndexError`` is + * If the source or sink vertex does not exist, an :exc:`IndexError` is raised. - * If the source and sink are identical, a ``ValueError`` is raised. + * If the source and sink are identical, a :exc:`ValueError` is raised. * This method raises ``MIPSolverException`` exceptions when the solution cannot be computed for any reason (none exists, or the @@ -1324,11 +1311,9 @@ cdef class GLPKGraphBackend(): cpdef double cpp(self) noexcept: r""" - Solves the critical path problem of a project network. - - OUTPUT: + Solve the critical path problem of a project network. - The length of the critical path of the network + OUTPUT: the length of the critical path of the network EXAMPLES:: diff --git a/src/sage/numerical/backends/interactivelp_backend.pyx b/src/sage/numerical/backends/interactivelp_backend.pyx index a61fac176fb..ea1a53aedce 100644 --- a/src/sage/numerical/backends/interactivelp_backend.pyx +++ b/src/sage/numerical/backends/interactivelp_backend.pyx @@ -43,7 +43,7 @@ cdef class InteractiveLPBackend: def __cinit__(self, maximization = True, base_ring = None): """ - Cython constructor + Cython constructor. EXAMPLES:: @@ -83,7 +83,7 @@ cdef class InteractiveLPBackend: cpdef __copy__(self): """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -108,9 +108,7 @@ cdef class InteractiveLPBackend: """ Return the base ring. - OUTPUT: - - A ring. The coefficients that the chosen solver supports. + OUTPUT: a ring; the coefficients that the chosen solver supports EXAMPLES:: @@ -131,9 +129,7 @@ cdef class InteractiveLPBackend: - ``upper_bound`` -- the upper bound of the variable - OUTPUT: - - - a string, one of "", "<=", ">=" + OUTPUT: string, one of ``''``, ``'<='``, ``'>='`` The function raises an error if this pair of bounds cannot be represented by an `InteractiveLPProblem` variable type. @@ -189,21 +185,21 @@ cdef class InteractiveLPBackend: - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integral (default: ``False``). + - ``integer`` -- ``True`` if the variable is integral (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - ``coefficients`` -- (optional) an iterable of pairs ``(i, v)``. In each pair, ``i`` is a variable index (integer) and ``v`` is a value (element of :meth:`base_ring`). - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -262,9 +258,9 @@ cdef class InteractiveLPBackend: INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``vtype`` (integer) : + - ``vtype`` -- integer: * 1 Integer * 0 Binary @@ -312,7 +308,7 @@ cdef class InteractiveLPBackend: INPUT: - - ``sense`` (integer) : + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -343,9 +339,9 @@ cdef class InteractiveLPBackend: INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient + - ``coeff`` -- double; its coefficient EXAMPLES:: @@ -371,11 +367,12 @@ cdef class InteractiveLPBackend: cpdef objective_constant_term(self, d=None): """ - Set or get the constant term in the objective function + Set or get the constant term in the objective function. INPUT: - - ``d`` (double) -- its coefficient. If `None` (default), return the current value. + - ``d`` -- double; its coefficient. If ``None`` (default), return the + current value. EXAMPLES:: @@ -401,10 +398,11 @@ cdef class InteractiveLPBackend: INPUT: - - ``coeff`` -- a list of real values, whose i-th element is the - coefficient of the i-th variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (real) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- real; the constant term in the linear function (set to `0` + by default) EXAMPLES:: @@ -437,7 +435,6 @@ cdef class InteractiveLPBackend: sage: p.set_objective(-x - y - 7) sage: p.solve() -47/5 - """ A, b, _, x, constraint_types, variable_types, problem_type, ring, _ = self._AbcxCVPRd() c = coeff @@ -447,11 +444,11 @@ cdef class InteractiveLPBackend: cpdef set_verbosity(self, int level): """ - Set the log (verbosity) level + Set the log (verbosity) level. INPUT: - - ``level`` (integer) -- From 0 (no verbosity) to 3. + - ``level`` -- integer; from 0 (no verbosity) to 3 EXAMPLES:: @@ -467,11 +464,11 @@ cdef class InteractiveLPBackend: INPUT: - - ``i`` -- index of the constraint to remove. + - ``i`` -- index of the constraint to remove EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="InteractiveLP") + sage: p = MixedIntegerLinearProgram(solver='InteractiveLP') sage: v = p.new_variable(nonnegative=True) sage: x,y = v[0], v[1] sage: p.add_constraint(2*x + 3*y, max = 6) @@ -506,12 +503,12 @@ cdef class InteractiveLPBackend: value (element of :meth:`base_ring`). - ``lower_bound`` -- element of :meth:`base_ring` or - ``None``. The lower bound. + ``None``; the lower bound - ``upper_bound`` -- element of :meth:`base_ring` or - ``None``. The upper bound. + ``None``; the upper bound - - ``name`` -- string or ``None``. Optional name for this row. + - ``name`` -- string or ``None``; optional name for this row EXAMPLES:: @@ -562,11 +559,11 @@ cdef class InteractiveLPBackend: INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint @@ -574,8 +571,7 @@ cdef class InteractiveLPBackend: .. NOTE:: - ``indices`` and ``coeffs`` are expected to be of the same - length. + ``indices`` and ``coeffs`` are expected to be of the same length. EXAMPLES:: @@ -741,11 +737,11 @@ cdef class InteractiveLPBackend: cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: @@ -766,11 +762,11 @@ cdef class InteractiveLPBackend: cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -804,7 +800,7 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -839,7 +835,7 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -875,7 +871,7 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -887,7 +883,6 @@ cdef class InteractiveLPBackend: 0 sage: p.is_variable_binary(0) False - """ return False @@ -897,7 +892,7 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -918,7 +913,7 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -930,17 +925,16 @@ cdef class InteractiveLPBackend: 0 sage: p.is_variable_continuous(0) True - """ return True cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: @@ -949,26 +943,25 @@ cdef class InteractiveLPBackend: sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) sage: p.row_name(0) 'Empty constraint 1' - """ return self.row_names[index] cpdef col_name(self, int index): """ - Return the ``index``-th column name + Return the ``index``-th column name. INPUT: - - ``index`` (integer) -- the column id + - ``index`` -- integer; the column id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") - sage: p.add_variable(name="I_am_a_variable") + sage: p.add_variable(name='I_am_a_variable') 0 sage: p.col_name(0) 'I_am_a_variable' @@ -977,11 +970,11 @@ cdef class InteractiveLPBackend: cpdef variable_upper_bound(self, int index, value=False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``False`` @@ -1021,11 +1014,11 @@ cdef class InteractiveLPBackend: cpdef variable_lower_bound(self, int index, value=False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has no lower bound. When set to ``False`` @@ -1072,12 +1065,12 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="InteractiveLP") + solver='InteractiveLP') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -1102,12 +1095,12 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="InteractiveLP") + solver='InteractiveLP') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -1132,12 +1125,12 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="InteractiveLP") + solver='InteractiveLP') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -1162,12 +1155,12 @@ cdef class InteractiveLPBackend: INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="InteractiveLP") + solver='InteractiveLP') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -1192,7 +1185,7 @@ cdef class InteractiveLPBackend: EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="InteractiveLP") + solver='InteractiveLP') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) @@ -1215,19 +1208,17 @@ cdef class InteractiveLPBackend: sage: lp, basis = p.interactive_lp_problem() sage: lp.dictionary(*basis).basic_solution() (17/8, 0) - """ return self.final_dictionary cpdef interactive_lp_problem(self): - """ Return the :class:`InteractiveLPProblem` object associated with this backend. EXAMPLES:: sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="InteractiveLP") + solver='InteractiveLP') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) diff --git a/src/sage/numerical/backends/interactivelp_backend_test.py b/src/sage/numerical/backends/interactivelp_backend_test.py index 0f0af51250d..5523c40ce1f 100644 --- a/src/sage/numerical/backends/interactivelp_backend_test.py +++ b/src/sage/numerical/backends/interactivelp_backend_test.py @@ -7,4 +7,4 @@ class TestInteractiveLPBackend(GenericBackendTests): @pytest.fixture def backend(self) -> GenericBackend: - return MixedIntegerLinearProgram(solver="InteractiveLP").get_backend() + return MixedIntegerLinearProgram(solver='InteractiveLP').get_backend() diff --git a/src/sage/numerical/backends/logging_backend.py b/src/sage/numerical/backends/logging_backend.py index 2efb77eaf08..d2d7bd98299 100644 --- a/src/sage/numerical/backends/logging_backend.py +++ b/src/sage/numerical/backends/logging_backend.py @@ -91,7 +91,6 @@ def m(self, *args, **kwdargs): return m class LoggingBackend(GenericBackend): - """ See :class:`LoggingBackendFactory` for documentation. @@ -225,7 +224,6 @@ def _test_{name}(cls, tester=None, **options): Traceback (most recent call last): ... NotImplementedError - """ p = cls() # fresh instance of the backend if tester is None: @@ -336,7 +334,6 @@ def LoggingBackendFactory(solver=None, printing=True, doctest_file=None, test_me | Traceback (most recent call last): | ... | NotImplementedError - | | ... | p = cls() # fresh instance of the backend | if tester is None: @@ -351,7 +348,6 @@ def LoggingBackendFactory(solver=None, printing=True, doctest_file=None, test_me If ``test_method_file`` is not provided, a default output file name will be computed from ``test_method``. - """ if test_method is not None: diff --git a/src/sage/numerical/backends/matrix_sdp_backend.pyx b/src/sage/numerical/backends/matrix_sdp_backend.pyx index 7e108018275..aad7fc4be68 100644 --- a/src/sage/numerical/backends/matrix_sdp_backend.pyx +++ b/src/sage/numerical/backends/matrix_sdp_backend.pyx @@ -26,13 +26,12 @@ cdef class MatrixSDPBackend(GenericSDPBackend): def __init__(self, maximization=True, base_ring=None): """ - Cython constructor + Cython constructor. EXAMPLES:: sage: from sage.numerical.backends.generic_sdp_backend import get_solver sage: p = get_solver(solver = "CVXOPT") - """ self.objective_function = [] self.name = "" @@ -56,7 +55,7 @@ cdef class MatrixSDPBackend(GenericSDPBackend): cpdef base_ring(self): """ - The base ring + The base ring. TESTS:: @@ -68,11 +67,11 @@ cdef class MatrixSDPBackend(GenericSDPBackend): def get_matrix(self): """ - Get a block of a matrix coefficient + Get a block of a matrix coefficient. EXAMPLES:: - sage: p = SemidefiniteProgram(solver="cvxopt") + sage: p = SemidefiniteProgram(solver='cvxopt') sage: x = p.new_variable() sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 5.]]) @@ -83,7 +82,6 @@ cdef class MatrixSDPBackend(GenericSDPBackend): [-1.0 -2.0] -1, [-2.0 -3.0] ) - """ return self.coeffs_matrix @@ -96,11 +94,13 @@ cdef class MatrixSDPBackend(GenericSDPBackend): INPUT: - - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) + - ``obj`` -- (optional) coefficient of this variable in the objective + function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: + ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -143,9 +143,9 @@ cdef class MatrixSDPBackend(GenericSDPBackend): - ``n`` -- the number of new variables (must be > 0) - - ``names`` -- optional list of names (default: ``None``) + - ``names`` -- list of names (default: ``None``) - OUTPUT: The index of the variable created last. + OUTPUT: the index of the variable created last EXAMPLES:: @@ -170,7 +170,7 @@ cdef class MatrixSDPBackend(GenericSDPBackend): INPUT: - - ``sense`` (integer) + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -197,9 +197,9 @@ cdef class MatrixSDPBackend(GenericSDPBackend): INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient + - ``coeff`` -- double; its coefficient EXAMPLES:: @@ -224,10 +224,11 @@ cdef class MatrixSDPBackend(GenericSDPBackend): INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: @@ -272,7 +273,7 @@ cdef class MatrixSDPBackend(GenericSDPBackend): [-7.00000000000000 -11.0000000000000] [-11.0000000000000 3.00000000000000] ]) - sage: p.add_linear_constraint( [(0, matrix([[33., -9.], [-9., 26.]])) , (1, matrix([[-7., -11.] ,[ -11., 3.]]) )],name="fun") + sage: p.add_linear_constraint( [(0, matrix([[33., -9.], [-9., 26.]])) , (1, matrix([[-7., -11.] ,[ -11., 3.]]) )],name='fun') sage: p.row_name(-1) 'fun' """ @@ -296,7 +297,7 @@ cdef class MatrixSDPBackend(GenericSDPBackend): INPUT: - - ``number`` (integer) -- the number of constraints to add. + - ``number`` -- integer; the number of constraints to add - ``names`` -- an optional list of names (default: ``None``) @@ -371,11 +372,11 @@ cdef class MatrixSDPBackend(GenericSDPBackend): cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``NULL`` (default), the method returns the problem's name. EXAMPLES:: @@ -393,11 +394,11 @@ cdef class MatrixSDPBackend(GenericSDPBackend): cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -433,20 +434,19 @@ cdef class MatrixSDPBackend(GenericSDPBackend): cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: sage: from sage.numerical.backends.generic_sdp_backend import get_solver sage: p = get_solver(solver = "CVXOPT") - sage: p.add_linear_constraints(1, names="A") + sage: p.add_linear_constraints(1, names='A') sage: p.row_name(0) 'A' - """ if self.row_name_var[index] is not None: return self.row_name_var[index] @@ -454,14 +454,14 @@ cdef class MatrixSDPBackend(GenericSDPBackend): cpdef col_name(self, int index): """ - Return the ``index`` th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: diff --git a/src/sage/numerical/backends/meson.build b/src/sage/numerical/backends/meson.build new file mode 100644 index 00000000000..a6a53e97033 --- /dev/null +++ b/src/sage/numerical/backends/meson.build @@ -0,0 +1,66 @@ +# Cannot be found via pkg-config +glpk = cc.find_library('glpk') + +py.install_sources( + 'all.py', + 'all__sagemath_polyhedra.py', + 'cvxopt_backend_test.py', + 'cvxpy_backend.pxd', + 'cvxpy_backend_test.py', + 'generic_backend.pxd', + 'generic_backend_test.py', + 'generic_sdp_backend.pxd', + 'glpk_backend.pxd', + 'glpk_backend_test.py', + 'glpk_exact_backend.pxd', + 'glpk_exact_backend_test.py', + 'glpk_graph_backend.pxd', + 'interactivelp_backend.pxd', + 'interactivelp_backend_test.py', + 'logging_backend.py', + 'matrix_sdp_backend.pxd', + 'ppl_backend_test.py', + 'scip_backend.pxd', + 'scip_backend_test.py', + subdir: 'sage/numerical/backends', +) + +extension_data = { + 'cvxopt_backend' : files('cvxopt_backend.pyx'), + 'cvxopt_sdp_backend' : files('cvxopt_sdp_backend.pyx'), + 'cvxpy_backend' : files('cvxpy_backend.pyx'), + 'generic_backend' : files('generic_backend.pyx'), + 'generic_sdp_backend' : files('generic_sdp_backend.pyx'), + 'glpk_backend' : files('glpk_backend.pyx'), + 'glpk_exact_backend' : files('glpk_exact_backend.pyx'), + 'glpk_graph_backend' : files('glpk_graph_backend.pyx'), + 'interactivelp_backend' : files('interactivelp_backend.pyx'), + 'matrix_sdp_backend' : files('matrix_sdp_backend.pyx'), + 'ppl_backend' : files('ppl_backend.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/numerical/backends', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, glpk, gmp], + ) +endforeach + +extension_data_cpp = {'scip_backend': files('scip_backend.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/numerical/backends', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/numerical/backends/ppl_backend.pyx b/src/sage/numerical/backends/ppl_backend.pyx index 1e53c947c95..24b0c8e80ac 100644 --- a/src/sage/numerical/backends/ppl_backend.pyx +++ b/src/sage/numerical/backends/ppl_backend.pyx @@ -29,7 +29,6 @@ from copy import copy cdef class PPLBackend(GenericBackend): - """ MIP Backend that uses the exact MIP solver from the Parma Polyhedra Library. """ @@ -52,7 +51,7 @@ cdef class PPLBackend(GenericBackend): def __cinit__(self, maximization = True, base_ring = None): """ - Constructor + Constructor. EXAMPLES:: @@ -62,7 +61,7 @@ cdef class PPLBackend(GenericBackend): Raise an error if a ``base_ring`` is requested that is not supported:: - sage: p = MixedIntegerLinearProgram(solver="PPL", base_ring=AA) # needs sage.rings.number_field + sage: p = MixedIntegerLinearProgram(solver='PPL', base_ring=AA) # needs sage.rings.number_field Traceback (most recent call last): ... TypeError: The PPL backend only supports rational data. @@ -100,7 +99,7 @@ cdef class PPLBackend(GenericBackend): cpdef __copy__(self): """ - Returns a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -138,7 +137,7 @@ cdef class PPLBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="PPL") + sage: p = get_solver(solver='PPL') sage: p.base_ring() Rational Field sage: type(p.zero()) @@ -208,7 +207,7 @@ cdef class PPLBackend(GenericBackend): - ``e`` -- a linear expression (type ``Linear_Expression``) - - ``denom`` -- a positive integer + - ``denom`` -- positive integer - ``lower``, ``upper`` -- a rational number or ``None``, where ``None`` means that there is no constraint @@ -217,7 +216,7 @@ cdef class PPLBackend(GenericBackend): Create a linear system with only equalities as constraints:: - sage: p = MixedIntegerLinearProgram(solver="PPL") + sage: p = MixedIntegerLinearProgram(solver='PPL') sage: x = p.new_variable(nonnegative=False) sage: n = 40 sage: v = random_vector(QQ, n) @@ -228,7 +227,6 @@ cdef class PPLBackend(GenericBackend): ....: p.add_constraint(lhs == rhs) sage: p.solve() # long time 0 - """ if lower == upper: if lower is not None: @@ -257,17 +255,17 @@ cdef class PPLBackend(GenericBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integral (default: ``False``). + - ``integer`` -- ``True`` if the variable is integral (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -328,17 +326,17 @@ cdef class PPLBackend(GenericBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``). + - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``) - - ``integer`` -- ``True`` if the variable is integral (default: ``False``). + - ``integer`` -- ``True`` if the variable is integral (default: ``False``) - - ``obj`` -- (optional) coefficient of all variables in the objective function (default: 0) + - ``obj`` -- coefficient of all variables in the objective function (default: 0) - - ``names`` -- optional list of names (default: ``None``) + - ``names`` -- list of names (default: ``None``) - OUTPUT: The index of the variable created last. + OUTPUT: the index of the variable created last EXAMPLES:: @@ -384,9 +382,9 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``vtype`` (integer) : + - ``vtype`` -- integer: * 1 Integer * 0 Binary @@ -437,7 +435,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``sense`` (integer) : + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -464,9 +462,9 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (integer) -- its coefficient + - ``coeff`` -- integer; its coefficient EXAMPLES:: @@ -491,12 +489,12 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="PPL") + sage: p = MixedIntegerLinearProgram(solver='PPL') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(x[0]*5 + x[1]/11 <= 6) sage: p.set_objective(x[0]) @@ -556,7 +554,7 @@ cdef class PPLBackend(GenericBackend): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="PPL") + sage: p = MixedIntegerLinearProgram(solver='PPL') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(x[0]/2 + x[1]/3 <= 2/5) sage: p.set_objective(x[1]) @@ -600,15 +598,15 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it - appears. Namely, the ith entry of ``coeffs`` corresponds to + appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint - represented by the ith entry in ``indices``. + represented by the i-th entry in ``indices``. .. NOTE:: @@ -644,7 +642,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``number`` (integer) -- the number of constraints to add. + - ``number`` -- integer; the number of constraints to add - ``lower_bound`` -- a lower bound, either a real value or ``None`` @@ -738,7 +736,7 @@ cdef class PPLBackend(GenericBackend): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="PPL") + sage: p = MixedIntegerLinearProgram(solver='PPL') sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(5/13*x[0] + x[1]/2 == 8/7) sage: p.set_objective(5/13*x[0] + x[1]/2) @@ -845,11 +843,11 @@ cdef class PPLBackend(GenericBackend): cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: @@ -866,11 +864,11 @@ cdef class PPLBackend(GenericBackend): cpdef row(self, int i): """ - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -905,7 +903,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -933,7 +931,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -961,7 +959,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -982,7 +980,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1003,7 +1001,7 @@ cdef class PPLBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1020,11 +1018,11 @@ cdef class PPLBackend(GenericBackend): cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: @@ -1040,14 +1038,14 @@ cdef class PPLBackend(GenericBackend): cpdef col_name(self, int index): """ - Return the ``index`` th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id - - ``name`` (``char *``) -- its name. When set to ``NULL`` - (default), the method returns the current name. + - ``name`` -- (``char *``) its name; when set to ``NULL`` + (default), the method returns the current name EXAMPLES:: @@ -1064,11 +1062,11 @@ cdef class PPLBackend(GenericBackend): cpdef variable_upper_bound(self, int index, value=False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``False`` @@ -1096,11 +1094,11 @@ cdef class PPLBackend(GenericBackend): cpdef variable_lower_bound(self, int index, value=False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not lower bound. When set to ``False`` diff --git a/src/sage/numerical/backends/ppl_backend_test.py b/src/sage/numerical/backends/ppl_backend_test.py index 852c3be82c1..13ef46e1a3d 100644 --- a/src/sage/numerical/backends/ppl_backend_test.py +++ b/src/sage/numerical/backends/ppl_backend_test.py @@ -9,4 +9,4 @@ class TestPPLBackend(GenericBackendTests): @pytest.fixture def backend(self) -> GenericBackend: - return MixedIntegerLinearProgram(solver="PPL").get_backend() + return MixedIntegerLinearProgram(solver='PPL').get_backend() diff --git a/src/sage/numerical/backends/scip_backend.pyx b/src/sage/numerical/backends/scip_backend.pyx index 7fdedc6a334..4cac8e171e0 100644 --- a/src/sage/numerical/backends/scip_backend.pyx +++ b/src/sage/numerical/backends/scip_backend.pyx @@ -27,7 +27,6 @@ from pyscipopt import Model cdef class SCIPBackend(GenericBackend): - """ MIP Backend that uses the SCIP solver. @@ -35,17 +34,17 @@ cdef class SCIPBackend(GenericBackend): General backend testsuite:: - sage: p = MixedIntegerLinearProgram(solver="SCIP") - sage: TestSuite(p.get_backend()).run(skip="_test_pickling") + sage: p = MixedIntegerLinearProgram(solver='SCIP') + sage: TestSuite(p.get_backend()).run(skip='_test_pickling') """ def __cinit__(self, maximization=True): """ - Constructor + Constructor. EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="SCIP") + sage: p = MixedIntegerLinearProgram(solver='SCIP') """ self.model = Model('') if maximization: @@ -65,7 +64,7 @@ cdef class SCIPBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: lp = get_solver(solver="SCIP") + sage: lp = get_solver(solver='SCIP') sage: lp.add_variables(3) 2 sage: lp.add_linear_constraint(zip([0, 1, 2], [8, 6, 1]), None, 48) @@ -109,17 +108,17 @@ cdef class SCIPBackend(GenericBackend): - ``upper_bound`` -- the upper bound of the variable (default: ``None``) - - ``binary`` -- ``True`` if the variable is binary (default: ``False``). + - ``binary`` -- ``True`` if the variable is binary (default: ``False``) - - ``continuous`` -- ``True`` if the variable is binary (default: ``True``). + - ``continuous`` -- ``True`` if the variable is binary (default: ``True``) - - ``integer`` -- ``True`` if the variable is binary (default: ``False``). + - ``integer`` -- ``True`` if the variable is binary (default: ``False``) - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0) - - ``name`` -- an optional name for the newly added variable (default: ``None``). + - ``name`` -- an optional name for the newly added variable (default: ``None``) - OUTPUT: The index of the newly created variable + OUTPUT: the index of the newly created variable EXAMPLES:: @@ -178,13 +177,13 @@ cdef class SCIPBackend(GenericBackend): cpdef set_variable_type(self, int variable, int vtype): """ - Set the type of a variable + Set the type of a variable. INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``vtype`` (integer): + - ``vtype`` -- integer: * 1 Integer * 0 Binary @@ -213,7 +212,7 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``sense`` (integer): + - ``sense`` -- integer: * +1 => Maximization * -1 => Minimization @@ -239,13 +238,13 @@ cdef class SCIPBackend(GenericBackend): cpdef objective_coefficient(self, int variable, coeff=None): """ - Set or get the coefficient of a variable in the objective function + Set or get the coefficient of a variable in the objective function. INPUT: - - ``variable`` (integer) -- the variable's id + - ``variable`` -- integer; the variable's id - - ``coeff`` (double) -- its coefficient or ``None`` for + - ``coeff`` -- double; its coefficient or ``None`` for reading (default: ``None``) EXAMPLES:: @@ -272,11 +271,11 @@ cdef class SCIPBackend(GenericBackend): cpdef problem_name(self, name=None): """ - Return or define the problem's name + Return or define the problem's name. INPUT: - - ``name`` (``str``) -- the problem's name. When set to + - ``name`` -- string; the problem's name. When set to ``None`` (default), the method returns the problem's name. EXAMPLES:: @@ -298,10 +297,11 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``coeff`` -- a list of real values, whose ith element is the - coefficient of the ith variable in the objective function. + - ``coeff`` -- list of real values, whose i-th element is the + coefficient of the i-th variable in the objective function - - ``d`` (double) -- the constant term in the linear function (set to `0` by default) + - ``d`` -- double; the constant term in the linear function (set to `0` + by default) EXAMPLES:: @@ -320,11 +320,11 @@ cdef class SCIPBackend(GenericBackend): cpdef set_verbosity(self, int level): """ - Set the verbosity level + Set the verbosity level. INPUT: - - ``level`` (integer) -- From 0 (no verbosity) to 1. + - ``level`` -- integer; from 0 (no verbosity) to 1 EXAMPLES:: @@ -348,7 +348,7 @@ cdef class SCIPBackend(GenericBackend): cpdef remove_constraint(self, int i): r""" - Remove a constraint from self. + Remove a constraint from ``self``. INPUT: @@ -371,7 +371,7 @@ cdef class SCIPBackend(GenericBackend): Removing fancy constraints does not make Sage crash:: - sage: MixedIntegerLinearProgram(solver="SCIP").remove_constraint(-2) + sage: MixedIntegerLinearProgram(solver='SCIP').remove_constraint(-2) Traceback (most recent call last): ... ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints @@ -470,11 +470,11 @@ cdef class SCIPBackend(GenericBackend): cpdef row(self, int index): r""" - Return a row + Return a row. INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -511,7 +511,7 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the constraint's id. + - ``index`` -- integer; the constraint's id OUTPUT: @@ -544,7 +544,7 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id. + - ``index`` -- integer; the variable's id OUTPUT: @@ -579,15 +579,15 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``indices`` (list of integers) -- this list contains the + - ``indices`` -- list of integers; this list contains the indices of the constraints in which the variable's coefficient is nonzero - - ``coeffs`` (list of real values) -- associates a coefficient + - ``coeffs`` -- list of real values; associates a coefficient to the variable in each of the constraints in which it - appears. Namely, the ith entry of ``coeffs`` corresponds to + appears. Namely, the i-th entry of ``coeffs`` corresponds to the coefficient of the variable in the constraint - represented by the ith entry in ``indices``. + represented by the i-th entry in ``indices``. .. NOTE:: @@ -745,7 +745,7 @@ cdef class SCIPBackend(GenericBackend): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="SCIP") + sage: p = MixedIntegerLinearProgram(solver='SCIP') sage: p.solver_parameter("limits/gap", 100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -780,7 +780,7 @@ cdef class SCIPBackend(GenericBackend): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="SCIP") + sage: p = MixedIntegerLinearProgram(solver='SCIP') sage: p.solver_parameter("limits/gap", 100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -916,11 +916,11 @@ cdef class SCIPBackend(GenericBackend): cpdef col_name(self, int index): """ - Return the ``index``th col name + Return the ``index``-th col name. INPUT: - - ``index`` (integer) -- the col's id + - ``index`` -- integer; the col's id EXAMPLES:: @@ -935,11 +935,11 @@ cdef class SCIPBackend(GenericBackend): cpdef row_name(self, int index): """ - Return the ``index`` th row name + Return the ``index``-th row name. INPUT: - - ``index`` (integer) -- the row's id + - ``index`` -- integer; the row's id EXAMPLES:: @@ -957,7 +957,7 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -979,7 +979,7 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1001,7 +1001,7 @@ cdef class SCIPBackend(GenericBackend): INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id EXAMPLES:: @@ -1037,11 +1037,11 @@ cdef class SCIPBackend(GenericBackend): cpdef variable_upper_bound(self, int index, value=False): """ - Return or define the upper bound on a variable + Return or define the upper bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not upper bound. When set to ``False`` @@ -1063,7 +1063,7 @@ cdef class SCIPBackend(GenericBackend): :issue:`14581`:: - sage: P = MixedIntegerLinearProgram(solver="SCIP") + sage: P = MixedIntegerLinearProgram(solver='SCIP') sage: x = P["x"] sage: P.set_max(x, 0) sage: P.get_max(x) @@ -1071,7 +1071,7 @@ cdef class SCIPBackend(GenericBackend): Check that :issue:`10232` is fixed:: - sage: p = get_solver(solver="SCIP") + sage: p = get_solver(solver='SCIP') sage: p.variable_upper_bound(2) Traceback (most recent call last): ... @@ -1098,11 +1098,11 @@ cdef class SCIPBackend(GenericBackend): cpdef variable_lower_bound(self, int index, value=False): """ - Return or define the lower bound on a variable + Return or define the lower bound on a variable. INPUT: - - ``index`` (integer) -- the variable's id + - ``index`` -- integer; the variable's id - ``value`` -- real value, or ``None`` to mean that the variable has not lower bound. When set to ``False`` @@ -1124,7 +1124,7 @@ cdef class SCIPBackend(GenericBackend): :issue:`14581`:: - sage: P = MixedIntegerLinearProgram(solver="SCIP") + sage: P = MixedIntegerLinearProgram(solver='SCIP') sage: x = P["x"] sage: P.set_min(x, 5) sage: P.set_min(x, 0) @@ -1133,7 +1133,7 @@ cdef class SCIPBackend(GenericBackend): Check that :issue:`10232` is fixed:: - sage: p = get_solver(solver="SCIP") + sage: p = get_solver(solver='SCIP') sage: p.variable_lower_bound(2) Traceback (most recent call last): ... @@ -1160,11 +1160,11 @@ cdef class SCIPBackend(GenericBackend): cpdef write_cip(self, filename): """ - Write the problem to a .cip file + Write the problem to a ``.cip`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -1175,7 +1175,7 @@ cdef class SCIPBackend(GenericBackend): sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3) sage: p.set_objective([2, 5]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".cip") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.cip') as f: ....: p.write_cip(f.name) wrote problem to file ... """ @@ -1183,11 +1183,11 @@ cdef class SCIPBackend(GenericBackend): cpdef write_lp(self, filename): """ - Write the problem to a .lp file + Write the problem to a ``.lp`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -1198,7 +1198,7 @@ cdef class SCIPBackend(GenericBackend): sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3) sage: p.set_objective([2, 5]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".lp") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.lp') as f: ....: p.write_lp(f.name) wrote problem to file ... """ @@ -1212,11 +1212,11 @@ cdef class SCIPBackend(GenericBackend): cpdef write_mps(self, filename, int modern): """ - Write the problem to a .mps file + Write the problem to a ``.mps`` file. INPUT: - - ``filename`` (string) + - ``filename`` -- string EXAMPLES:: @@ -1227,7 +1227,7 @@ cdef class SCIPBackend(GenericBackend): sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3) sage: p.set_objective([2, 5]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".mps") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.mps') as f: ....: p.write_mps(f.name, 2) wrote problem to file ... """ @@ -1241,7 +1241,7 @@ cdef class SCIPBackend(GenericBackend): cpdef __copy__(self): """ - Return a copy of self. + Return a copy of ``self``. EXAMPLES:: @@ -1262,19 +1262,19 @@ cdef class SCIPBackend(GenericBackend): cpdef solver_parameter(self, name, value=None): """ - Return or define a solver parameter + Return or define a solver parameter. INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value EXAMPLES: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="SCIP") + sage: p = get_solver(solver='SCIP') sage: p.solver_parameter("limits/time", 1) sage: p.solver_parameter("limits/time") 1.0 diff --git a/src/sage/numerical/gauss_legendre.pyx b/src/sage/numerical/gauss_legendre.pyx index 57d9050057e..4a422e9c6d6 100644 --- a/src/sage/numerical/gauss_legendre.pyx +++ b/src/sage/numerical/gauss_legendre.pyx @@ -62,14 +62,12 @@ def nodes_uncached(degree, prec): INPUT: - - ``degree`` -- integer. The number of nodes. Must be 3 or even. + - ``degree`` -- integer; the number of nodes (must be 3 or even) - - ``prec`` -- integer (minimal value 53). Binary precision with which the - nodes and weights are computed. + - ``prec`` -- integer (minimal value 53); binary precision with which the + nodes and weights are computed - OUTPUT: - - A list of (node, weight) pairs. + OUTPUT: list of (node, weight) pairs EXAMPLES: @@ -172,14 +170,12 @@ def nodes(degree, prec): INPUT: - - ``degree`` -- integer. The number of nodes. Must be 3 or even. - - - ``prec`` -- integer (minimal value 53). Binary precision with which the - nodes and weights are computed. + - ``degree`` -- integer; the number of nodes (must be 3 or even) - OUTPUT: + - ``prec`` -- integer (minimal value 53); binary precision with which the + nodes and weights are computed - A list of (node, weight) pairs. + OUTPUT: list of (node, weight) pairs. EXAMPLES: @@ -211,7 +207,6 @@ def nodes(degree, prec): [(0.11270166537925831148207346002, 0.27777777777777777777777777778), (0.50000000000000000000000000000, 0.44444444444444444444444444444), (0.88729833462074168851792653998, 0.27777777777777777777777777778)] - """ return nodes_uncached(degree, prec) @@ -230,15 +225,15 @@ def estimate_error(results, prec, epsilon): INPUT: - - ``results`` -- list. List of approximations to estimate the error from. Should be at least length 2. + - ``results`` -- list of approximations to estimate the error from; should + be at least length 2 - - ``prec`` -- integer. Binary precision at which computations are happening. + - ``prec`` -- integer; binary precision at which computations are happening - - ``epsilon`` -- multiprecision float. Default error estimate in case of insufficient data. + - ``epsilon`` -- multiprecision float; default error estimate in case of + insufficient data - OUTPUT: - - An estimate of the error. + OUTPUT: an estimate of the error EXAMPLES:: @@ -283,15 +278,13 @@ def integrate_vector_N(f, prec, N=3): INPUT: - - ``f`` -- callable. Vector-valued integrand. - - - ``prec`` -- integer. Binary precision to be used. + - ``f`` -- callable; vector-valued integrand - - ``N`` -- integer (default: 3). Number of nodes to use. + - ``prec`` -- integer; binary precision to be used - OUTPUT: + - ``N`` -- integer (default: 3); number of nodes to use - Vector approximating value of the integral. + OUTPUT: vector approximating value of the integral EXAMPLES:: @@ -308,7 +301,7 @@ def integrate_vector_N(f, prec, N=3): The nodes and weights are calculated in the real field with ``prec`` bits of precision. If the vector space in which ``f`` takes values is over a field which is incompatible with this field (e.g. a finite - field) then a :class:`TypeError` occurs. + field) then a :exc:`TypeError` occurs. """ # We use nodes_uncached, because caching takes up memory, and numerics in # Bruin-DisneyHogg-Gao suggest that caching provides little benefit in the @@ -329,15 +322,14 @@ def integrate_vector(f, prec, epsilon=None): INPUT: - - ``f`` -- callable. Vector-valued integrand. - - - ``prec`` -- integer. Binary precision to be used. + - ``f`` -- callable; vector-valued integrand - - ``epsilon`` -- multiprecision float (default: `2^{(-\text{prec}+3)}`). Target error bound. + - ``prec`` -- integer; binary precision to be used - OUTPUT: + - ``epsilon`` -- multiprecision float (default: `2^{(-\text{prec}+3)}`); + target error bound - Vector approximating value of the integral. + OUTPUT: vector approximating value of the integral EXAMPLES:: diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index 9a9e12eb9a0..a89da826c77 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -44,7 +44,7 @@ sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P LP problem (use 'view(...)' or '%display typeset' for details) @@ -219,14 +219,12 @@ def _assemble_arrayl(lines, stretch=None): INPUT: - - ``lines`` -- a list of strings suitable for math mode typesetting + - ``lines`` -- list of strings suitable for math mode typesetting - - ``stretch`` -- (default: None) if given, a command setting + - ``stretch`` -- (default: ``None``) if given, a command setting ``\arraystretch`` to this value will be added before the array - OUTPUT: - - - a :class:`LatexExpr` + OUTPUT: a :class:`LatexExpr` EXAMPLES:: @@ -268,11 +266,11 @@ def _latex_product(coefficients, variables, INPUT: - - ``coefficients`` -- a list of coefficients + - ``coefficients`` -- list of coefficients - - ``variables`` -- a list of variables + - ``variables`` -- list of variables - - ``separator`` -- (default: ``"&"`` with some extra space adjustment) a + - ``separator`` -- (default: ``'&'`` with some extra space adjustment) a string to be inserted between elements of the generated expression - ``head`` -- either ``None`` (default) or a list of entries to be @@ -281,10 +279,10 @@ def _latex_product(coefficients, variables, - ``tail`` -- either ``None`` (default) or a list of entries to be added to the end of the output - - ``drop_plus`` -- (default: ``True``) whether to drop the leading plus + - ``drop_plus`` -- boolean (default: ``True``); whether to drop the leading plus sign or not - - ``allow_empty`` -- (default: ``False``) whether to allow empty output or + - ``allow_empty`` -- boolean (default: ``False``); whether to allow empty output or produce at least "0" OUTPUT: @@ -366,9 +364,7 @@ def variable(R, v): - ``v`` -- a variable of ``R`` or convertible into ``R``, a string with the name of a variable of ``R`` or an index of a variable in ``R`` - OUTPUT: - - - a variable of ``R`` + OUTPUT: a variable of ``R`` EXAMPLES:: @@ -452,11 +448,9 @@ def default_variable_name(variable): INPUT: - - ``variable`` -- a string describing requested name - - OUTPUT: + - ``variable`` -- string describing requested name - - a string with the requested name for current style + OUTPUT: string with the requested name for current style EXAMPLES:: @@ -477,13 +471,13 @@ def style(new_style=None): INPUT: - - ``new_style`` -- a string or ``None`` (default) + - ``new_style`` -- string or ``None`` (default) OUTPUT: - a string with current style (same as ``new_style`` if it was given) - If the input is not recognized as a valid style, a ``ValueError`` exception + If the input is not recognized as a valid style, a :exc:`ValueError` exception is raised. Currently supported styles are: @@ -573,25 +567,25 @@ class InteractiveLPProblem(SageObject): - ``c`` -- a vector of objective coefficients - - ``x`` -- (default: ``"x"``) a vector of decision variables or a + - ``x`` -- (default: ``'x'``) a vector of decision variables or a string giving the base name - - ``constraint_type`` -- (default: ``"<="``) a string specifying constraint - type(s): either ``"<="``, ``">="``, ``"=="``, or a list of them + - ``constraint_type`` -- (default: ``'<='``) a string specifying constraint + type(s): either ``'<='``, ``'>='``, ``'=='``, or a list of them - ``variable_type`` -- (default: ``""``) a string specifying variable - type(s): either ``">="``, ``"<="``, ``""`` (the empty string), or a - list of them, corresponding, respectively, to non-negative, - non-positive, and free variables + type(s): either ``'>='``, ``'<='``, ``""`` (the empty string), or a + list of them, corresponding, respectively, to nonnegative, + nonpositive, and free variables - - ``problem_type`` -- (default: ``"max"``) a string specifying the - problem type: ``"max"``, ``"min"``, ``"-max"``, or ``"-min"`` + - ``problem_type`` -- (default: ``'max'``) a string specifying the + problem type: ``'max'``, ``'min'``, ``'-max'``, or ``'-min'`` - ``base_ring`` -- (default: the fraction field of a common ring for all input coefficients) a field to which all input coefficients will be converted - - ``is_primal`` -- (default: ``True``) whether this problem is primal or + - ``is_primal`` -- boolean (default: ``True``); whether this problem is primal or dual: each problem is of course dual to its own dual, this flag is mostly for internal use and affects default variable names only @@ -618,16 +612,16 @@ class InteractiveLPProblem(SageObject): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') Same problem, but more explicitly:: sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], - ....: constraint_type="<=", variable_type=">=") + ....: constraint_type='<=', variable_type='>=') Even more explicitly:: - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], problem_type="max", + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], problem_type='max', ....: constraint_type=["<=", "<="], variable_type=[">=", ">="]) Using the last form you should be able to represent any LP problem, as long @@ -635,8 +629,8 @@ class InteractiveLPProblem(SageObject): are on different sides. """ - def __init__(self, A, b, c, x="x", - constraint_type="<=", variable_type="", problem_type="max", + def __init__(self, A, b, c, x='x', + constraint_type='<=', variable_type='', problem_type='max', base_ring=None, is_primal=True, objective_constant_term=0): r""" See :class:`InteractiveLPProblem` for documentation. @@ -646,7 +640,7 @@ def __init__(self, A, b, c, x="x", sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: TestSuite(P).run() """ super().__init__() @@ -673,7 +667,7 @@ def __init__(self, A, b, c, x="x", x = [str(_) for _ in x] if len(x) != n: raise ValueError("A and x have incompatible dimensions") - R = PolynomialRing(base_ring, x, order="neglex") + R = PolynomialRing(base_ring, x, order='neglex') x = vector(R, R.gens()) # All variables as a vector self._Abcx = A, b, c, x self._constant_term = objective_constant_term @@ -727,11 +721,11 @@ def __eq__(self, other): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: P2 = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') + sage: P2 = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P == P2 True - sage: P3 = InteractiveLPProblem(A, c, b, ["C", "B"], variable_type=">=") + sage: P3 = InteractiveLPProblem(A, c, b, ["C", "B"], variable_type='>=') sage: P == P3 False """ @@ -747,16 +741,14 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string TESTS:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: print(P._latex_()) \begin{array}{l} \begin{array}{lcrcrcl} @@ -799,16 +791,14 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string TESTS:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: print(P._repr_()) LP problem (use ...) """ @@ -824,16 +814,14 @@ def _solution(self, x): problem, e.g. a vector or a list of correct length or a single element list with such a vector - OUTPUT: - - - ``x`` as a vector + OUTPUT: ``x`` as a vector EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, variable_type='>=') sage: P._solution([100, 200]) (100, 200) sage: P._solution([[100, 200]]) @@ -875,7 +863,7 @@ def _solve(self): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P._solve() ((250, 750), 6250) """ @@ -910,16 +898,14 @@ def Abcx(self): r""" Return `A`, `b`, `c`, and `x` of ``self`` as a tuple. - OUTPUT: - - - a tuple + OUTPUT: a tuple EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.Abcx() ( [1 1] @@ -928,7 +914,7 @@ def Abcx(self): """ return self._Abcx - def add_constraint(self, coefficients, constant_term, constraint_type="<="): + def add_constraint(self, coefficients, constant_term, constraint_type='<='): r""" Return a new LP problem by adding a constraint to``self``. @@ -938,12 +924,10 @@ def add_constraint(self, coefficients, constant_term, constraint_type="<="): - ``constant_term`` -- a constant term of the new constraint - - ``constraint_type`` -- (default: ``"<="``) a string indicating + - ``constraint_type`` -- (default: ``'<='``) a string indicating the constraint type of the new constraint - OUTPUT: - - - an :class:`LP problem ` + OUTPUT: an :class:`LP problem ` EXAMPLES:: @@ -999,21 +983,19 @@ def base_ring(self): The base ring of LP problems is always a field. - OUTPUT: - - - a ring + OUTPUT: a ring EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.base_ring() Rational Field sage: c = (10, 5.) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.base_ring() Real Field with 53 bits of precision """ @@ -1023,16 +1005,14 @@ def constant_terms(self): r""" Return constant terms of constraints of ``self``, i.e. `b`. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.constant_terms() (1000, 1500) sage: P.b() @@ -1044,16 +1024,14 @@ def constraint_coefficients(self): r""" Return coefficients of constraints of ``self``, i.e. `A`. - OUTPUT: - - - a matrix + OUTPUT: a matrix EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.constraint_coefficients() [1 1] [3 1] @@ -1067,16 +1045,14 @@ def constraint_types(self): r""" Return a tuple listing the constraint types of all rows. - OUTPUT: - - - a tuple of strings + OUTPUT: a tuple of strings EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=", constraint_type=["<=", "=="]) + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=', constraint_type=["<=", "=="]) sage: P.constraint_types() ('<=', '==') """ @@ -1086,16 +1062,14 @@ def decision_variables(self): r""" Return decision variables of ``self``, i.e. `x`. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.decision_variables() (C, B) sage: P.x() @@ -1112,16 +1086,14 @@ def dual(self, y=None): - ``y`` -- (default: depends on :func:`style`) a vector of dual decision variables or a string giving the base name - OUTPUT: - - - an :class:`InteractiveLPProblem` + OUTPUT: an :class:`InteractiveLPProblem` EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: DP = P.dual() sage: DP.b() == P.c() True @@ -1179,16 +1151,14 @@ def feasible_set(self): r""" Return the feasible set of ``self``. - OUTPUT: - - - a :mod:`Polyhedron ` + OUTPUT: a :mod:`Polyhedron ` EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.feasible_set() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices @@ -1219,23 +1189,21 @@ def is_bounded(self): r""" Check if ``self`` is bounded. - OUTPUT: - - - ``True`` is ``self`` is bounded, ``False`` otherwise + OUTPUT: ``True`` if ``self`` is bounded, ``False`` otherwise EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.is_bounded() True Note that infeasible problems are always bounded:: sage: b = (-1000, 1500) - sage: P = InteractiveLPProblem(A, b, c, variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, variable_type='>=') sage: P.is_feasible() False sage: P.is_bounded() @@ -1262,7 +1230,7 @@ def is_feasible(self, *x): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, variable_type='>=') sage: P.is_feasible() True sage: P.is_feasible(100, 200) @@ -1282,17 +1250,17 @@ def is_feasible(self, *x): def is_negative(self): r""" - Return `True` when the problem is of type ``"-max"`` or ``"-min"``. + Return ``True`` when the problem is of type ``'-max'`` or ``'-min'``. EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.is_negative() False - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=", problem_type="-min") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=', problem_type='-min') sage: P.is_negative() True """ @@ -1304,16 +1272,14 @@ def is_primal(self): This distinction affects only some automatically chosen variable names. - OUTPUT: - - - boolean + OUTPUT: boolean EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.is_primal() True sage: P.dual().is_primal() @@ -1330,16 +1296,14 @@ def is_optimal(self, *x): - anything that can be interpreted as a valid solution for this problem, i.e. a sequence of values for all decision variables - OUTPUT: - - - ``True`` is the given solution is optimal, ``False`` otherwise + OUTPUT: ``True`` if the given solution is optimal, ``False`` otherwise EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (15, 5) - sage: P = InteractiveLPProblem(A, b, c, variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, variable_type='>=') sage: P.is_optimal(100, 200) False sage: P.is_optimal(500, 0) @@ -1356,16 +1320,14 @@ def n_constraints(self): r""" Return the number of constraints of ``self``, i.e. `m`. - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.n_constraints() 2 sage: P.m() @@ -1377,16 +1339,14 @@ def n_variables(self): r""" Return the number of decision variables of ``self``, i.e. `n`. - OUTPUT: - - - an integer + OUTPUT: integer EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.n_variables() 2 sage: P.n() @@ -1398,16 +1358,14 @@ def objective_coefficients(self): r""" Return coefficients of the objective of ``self``, i.e. `c`. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.objective_coefficients() (10, 5) sage: P.c() @@ -1419,22 +1377,20 @@ def objective_constant_term(self): r""" Return the constant term of the objective. - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.objective_constant_term() 0 sage: P.optimal_value() 6250 sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], - ....: variable_type=">=", objective_constant_term=-1250) + ....: variable_type='>=', objective_constant_term=-1250) sage: P.objective_constant_term() -1250 sage: P.optimal_value() @@ -1461,7 +1417,7 @@ def objective_value(self, *x): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, variable_type='>=') sage: P.objective_value(100, 200) 2000 """ @@ -1472,16 +1428,14 @@ def optimal_solution(self): r""" Return **an** optimal solution of ``self``. - OUTPUT: - - - a vector or ``None`` if there are no optimal solutions + OUTPUT: a vector or ``None`` if there are no optimal solutions EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.optimal_solution() (250, 750) """ @@ -1501,7 +1455,7 @@ def optimal_value(self): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.optimal_value() 6250 """ @@ -1518,9 +1472,7 @@ def plot(self, *args, **kwds): - ``alpha`` -- (default: 0.2) determines how opaque are shadows - OUTPUT: - - - a plot + OUTPUT: a plot This only works for problems with two decision variables. On the plot the black arrow indicates the direction of growth of the objective. The @@ -1536,7 +1488,7 @@ def plot(self, *args, **kwds): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: p = P.plot() # needs sage.plot sage: p.show() # needs sage.plot @@ -1549,7 +1501,7 @@ def plot(self, *args, **kwds): We check that zero objective can be dealt with:: - sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() # needs sage.plot + sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type='>=').plot() # needs sage.plot Graphics object consisting of 8 graphics primitives """ FP = self.plot_feasible_set(*args, **kwds) @@ -1566,8 +1518,8 @@ def plot(self, *args, **kwds): else [xmin + (xmax-xmin)/2, ymin + (ymax-ymin)/2]) length = min(xmax - xmin, ymax - ymin) / 5 end = start + (c * length / c.norm()).n().change_ring(QQ) - result = FP + point(start, color="black", size=50, zorder=10) - result += arrow(start, end, color="black", zorder=10) + result = FP + point(start, color='black', size=50, zorder=10) + result += arrow(start, end, color='black', zorder=10) ieqs = [(xmax, -1, 0), (- xmin, 1, 0), (ymax, 0, -1), (- ymin, 0, 1)] box = Polyhedron(ieqs=ieqs) @@ -1577,11 +1529,11 @@ def plot(self, *args, **kwds): level = box.intersection(level) if level.vertices(): if i == 0 and self.is_bounded(): - result += line(level.vertices(), color="black", + result += line(level.vertices(), color='black', thickness=2) else: - result += line(level.vertices(), color="black", - linestyle="--") + result += line(level.vertices(), color='black', + linestyle='--') result.set_axes_range(xmin, xmax, ymin, ymax) result.axes_labels(FP.axes_labels()) #FIXME: should be preserved! return result @@ -1598,9 +1550,7 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None, - ``alpha`` -- (default: 0.2) determines how opaque are shadows - OUTPUT: - - - a plot + OUTPUT: a plot This only works for a problem with two decision variables. The plot shows boundaries of constraints with a shadow on one side for @@ -1613,7 +1563,7 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None, sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: p = P.plot_feasible_set() # needs sage.plot sage: p.show() # needs sage.plot @@ -1679,9 +1629,9 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None, halfplane = box.intersection(Polyhedron(ieqs=ieqs)) result += halfplane.render_solid(alpha=alpha, color=color) if F.vertices(): - result += F.render_solid(alpha=alpha, color="gray") + result += F.render_solid(alpha=alpha, color='gray') result += text("$F$", F.center(), - fontsize=20, color="black", zorder=5) + fontsize=20, color='black', zorder=5) result.set_axes_range(xmin, xmax, ymin, ymax) result.axes_labels(["${}$".format(latex(xi)) for xi in x]) result.legend(True) @@ -1697,19 +1647,17 @@ def problem_type(self): Needs to be used together with ``is_negative``. - OUTPUT: - - - a string, one of ``"max"``, ``"min"``. + OUTPUT: string, one of ``'max'``, ``'min'`` EXAMPLES:: sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=') sage: P.problem_type() 'max' - sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=", problem_type="-min") + sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type='>=', problem_type='-min') sage: P.problem_type() 'min' """ @@ -1721,7 +1669,7 @@ def standard_form(self, transformation=False, **kwds): INPUT: - - ``transformation`` -- (default: ``False``) if ``True``, a map + - ``transformation`` -- boolean (default: ``False``); if ``True``, a map converting solutions of the problem in standard form to the original one will be returned as well @@ -1739,7 +1687,7 @@ def standard_form(self, transformation=False, **kwds): sage: A = ([1, 1], [3, 1]) sage: b = (1000, 1500) sage: c = (10, 5) - sage: P = InteractiveLPProblem(A, b, c, variable_type=">=") + sage: P = InteractiveLPProblem(A, b, c, variable_type='>=') sage: DP = P.dual() sage: DPSF = DP.standard_form() sage: DPSF.b() @@ -1791,7 +1739,7 @@ def standard_form(self, transformation=False, **kwds): sage: c = (-10, -5) sage: P = InteractiveLPProblem(A, b, c, variable_type=["<=", ""], ....: objective_constant_term=-42, - ....: problem_type="min") + ....: problem_type='min') sage: PSF, f = P.standard_form(True) sage: PSF.optimal_solution() (0, 1000, 0) @@ -1801,7 +1749,6 @@ def standard_form(self, transformation=False, **kwds): -5042 sage: P.optimal_value() -5042 - """ A, b, c, x = self.Abcx() f = identity_matrix(self.n()).columns() @@ -1864,9 +1811,7 @@ def variable_types(self): r""" Return a tuple listing the variable types of all decision variables. - OUTPUT: - - - a tuple of strings + OUTPUT: a tuple of strings EXAMPLES:: @@ -1916,17 +1861,17 @@ class InteractiveLPProblemStandardForm(InteractiveLPProblem): - ``c`` -- a vector of objective coefficients - - ``x`` -- (default: ``"x"``) a vector of decision variables or a string + - ``x`` -- (default: ``'x'``) a vector of decision variables or a string the base name giving - - ``problem_type`` -- (default: ``"max"``) a string specifying the - problem type: either ``"max"`` or ``"-max"`` + - ``problem_type`` -- (default: ``'max'``) a string specifying the + problem type: either ``'max'`` or ``'-max'`` - ``slack_variables`` -- (default: depends on :func:`style`) a vector of slack variables or a string giving the base name - ``auxiliary_variable`` -- (default: same as ``x`` parameter with adjoined - ``"0"`` if it was given as a string, otherwise ``"x0"``) the auxiliary + ``'0'`` if it was given as a string, otherwise ``'x0'``) the auxiliary name, expected to be the same as the first decision variable for auxiliary problems @@ -1934,12 +1879,12 @@ class InteractiveLPProblemStandardForm(InteractiveLPProblem): input coefficients) a field to which all input coefficients will be converted - - ``is_primal`` -- (default: ``True``) whether this problem is primal or + - ``is_primal`` -- boolean (default: ``True``); whether this problem is primal or dual: each problem is of course dual to its own dual, this flag is mostly for internal use and affects default variable names only - - ``objective_name`` -- a string or a symbolic expression for the - objective used in dictionaries, default depends on :func:`style` + - ``objective_name`` -- string or symbolic expression for the + objective used in dictionaries (default: depends on :func:`style`) - ``objective_constant_term`` -- (default: 0) a constant term of the objective @@ -1952,8 +1897,8 @@ class InteractiveLPProblemStandardForm(InteractiveLPProblem): sage: P = InteractiveLPProblemStandardForm(A, b, c) Unlike :class:`InteractiveLPProblem`, this class does not allow you to adjust types of - constraints (they are always ``"<="``) and variables (they are always - ``">="``), and the problem type may only be ``"max"`` or ``"-max"``. + constraints (they are always ``'<='``) and variables (they are always + ``'>='``), and the problem type may only be ``'max'`` or ``'-max'``. You may give custom names to slack and auxiliary variables, but in most cases defaults should work:: @@ -1963,7 +1908,7 @@ class InteractiveLPProblemStandardForm(InteractiveLPProblem): (x3, x4) """ - def __init__(self, A, b, c, x="x", problem_type="max", + def __init__(self, A, b, c, x='x', problem_type='max', slack_variables=None, auxiliary_variable=None, base_ring=None, is_primal=True, objective_name=None, objective_constant_term=0): @@ -1984,8 +1929,8 @@ def __init__(self, A, b, c, x="x", problem_type="max", super().__init__( A, b, c, x, problem_type=problem_type, - constraint_type="<=", - variable_type=">=", + constraint_type='<=', + variable_type='>=', base_ring=base_ring, is_primal=is_primal, objective_constant_term=objective_constant_term) @@ -2011,7 +1956,7 @@ def __init__(self, A, b, c, x="x", problem_type="max", names.extend(slack_variables) if names[0] == names[1]: names.pop(0) - R = PolynomialRing(self.base_ring(), names, order="neglex") + R = PolynomialRing(self.base_ring(), names, order='neglex') self._R = R x = vector(R.gens()[-n-m:-m]) x.set_immutable() @@ -2075,9 +2020,7 @@ def add_constraint(self, coefficients, constant_term, slack_variable=None): - ``slack_variable`` -- (default: depends on :func:`style`) a string giving the name of the slack variable of the new constraint - OUTPUT: - - - an :class:`LP problem in standard form ` + OUTPUT: an :class:`LP problem in standard form ` EXAMPLES:: @@ -2140,12 +2083,10 @@ def auxiliary_problem(self, objective_name=None): INPUT: - - ``objective_name`` -- a string or a symbolic expression for the - objective used in dictionaries, default depends on :func:`style` + - ``objective_name`` -- string or symbolic expression for the + objective used in dictionaries (default: depends on :func:`style`) - OUTPUT: - - - an :class:`LP problem in standard form ` + OUTPUT: an :class:`LP problem in standard form ` The auxiliary problem with the auxiliary variable `x_0` is @@ -2190,9 +2131,7 @@ def auxiliary_variable(self): Note that the auxiliary variable may or may not be among :meth:`~InteractiveLPProblem.decision_variables`. - OUTPUT: - - - a variable of the :meth:`coordinate_ring` of ``self`` + OUTPUT: a variable of the :meth:`coordinate_ring` of ``self`` EXAMPLES:: @@ -2250,9 +2189,7 @@ def dictionary(self, *x_B): - basic variables for the dictionary to be constructed - OUTPUT: - - - a :class:`dictionary ` + OUTPUT: a :class:`dictionary ` .. NOTE:: @@ -2283,9 +2220,7 @@ def feasible_dictionary(self, auxiliary_dictionary): :meth:`auxiliary_problem` of ``self`` with the optimal value `0` and a non-basic auxiliary variable - OUTPUT: - - - a feasible :class:`dictionary ` for ``self`` + OUTPUT: a feasible :class:`dictionary ` for ``self`` EXAMPLES:: @@ -2351,9 +2286,7 @@ def final_dictionary(self): See :meth:`run_simplex_method` for the description of possibilities. - OUTPUT: - - - a :class:`dictionary ` + OUTPUT: a :class:`dictionary ` EXAMPLES:: @@ -2387,9 +2320,7 @@ def final_revised_dictionary(self): See :meth:`run_revised_simplex_method` for the description of possibilities. - OUTPUT: - - - a :class:`revised dictionary ` + OUTPUT: a :class:`revised dictionary ` EXAMPLES:: @@ -2423,9 +2354,7 @@ def initial_dictionary(self): of the :meth:`~InteractiveLPProblem.decision_variables`, i.e. it has slack variables as basic ones. - OUTPUT: - - - a :class:`dictionary ` + OUTPUT: a :class:`dictionary ` EXAMPLES:: @@ -2452,9 +2381,7 @@ def inject_variables(self, scope=None, verbose=True): - ``verbose`` -- if ``True`` (default), names of injected variables will be printed - OUTPUT: - - - none + OUTPUT: none EXAMPLES:: @@ -2478,9 +2405,7 @@ def objective_name(self): r""" Return the objective name used in dictionaries for this problem. - OUTPUT: - - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -2497,7 +2422,7 @@ def objective_name(self): zeta sage: sage.numerical.interactive_simplex_method.style("UAlberta") 'UAlberta' - sage: P = InteractiveLPProblemStandardForm(A, b, c, objective_name="custom") + sage: P = InteractiveLPProblemStandardForm(A, b, c, objective_name='custom') sage: P.objective_name() custom """ @@ -2513,9 +2438,7 @@ def revised_dictionary(self, *x_B): :meth:`slack_variables` will be used, perhaps with the :meth:`auxiliary_variable` to give a feasible dictionary - OUTPUT: - - - a :class:`revised dictionary ` + OUTPUT: a :class:`revised dictionary ` EXAMPLES:: @@ -2568,7 +2491,7 @@ def run_revised_simplex_method(self): one of the following: - an optimal dictionary with the :meth:`auxiliary_variable` among - :meth:`~LPRevisedDictionary.basic_variables` and a non-zero + :meth:`~LPRevisedDictionary.basic_variables` and a nonzero optimal value indicating that ``self`` is infeasible; @@ -2632,7 +2555,7 @@ def run_simplex_method(self): of the following: - an optimal dictionary for the :meth:`auxiliary_problem` with a - non-zero optimal value indicating that ``self`` is infeasible; + nonzero optimal value indicating that ``self`` is infeasible; - a non-optimal dictionary for ``self`` that has marked entering variable for which there is no choice of the leaving variable, @@ -2704,9 +2627,7 @@ def slack_variables(self): If you want to give custom names to slack variables, you have to do so during construction of the problem. - OUTPUT: - - - a tuple + OUTPUT: a tuple EXAMPLES:: @@ -2752,9 +2673,7 @@ def _html_(self): r""" Return an HTML representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string TESTS:: @@ -2778,12 +2697,10 @@ def _preupdate_output(self, direction): INPUT: - - ``direction`` -- a string specifying the type of the simplex method + - ``direction`` -- string specifying the type of the simplex method used, either "primal" or "dual" - OUTPUT: - - - :class:`~sage.misc.html.HtmlFragment`. + OUTPUT: :class:`~sage.misc.html.HtmlFragment` TESTS:: @@ -2812,9 +2729,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string TESTS:: @@ -2838,18 +2753,16 @@ def add_row(self, nonbasic_coefficients, constant, basic_variable=None): INPUT: - - ``nonbasic_coefficients`` -- a list of the coefficients for the + - ``nonbasic_coefficients`` -- list of the coefficients for the new row (with which nonbasic variables are subtracted in the relation for the new basic variable) - - ``constant`` -- the constant term for the new row + - ``constant`` -- the constant term for the new row - ``basic_variable`` -- (default: depends on :func:`style`) a string giving the name of the basic variable of the new row - OUTPUT: - - - a new dictionary of the same class + OUTPUT: a new dictionary of the same class EXAMPLES:: @@ -2867,9 +2780,7 @@ def base_ring(self): r""" Return the base ring of ``self``, i.e. the ring of coefficients. - OUTPUT: - - - a ring + OUTPUT: a ring EXAMPLES:: @@ -2891,9 +2802,7 @@ def basic_variables(self): r""" Return the basic variables of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -2919,12 +2828,10 @@ def basic_solution(self, include_slack_variables=False): INPUT: - - ``include_slack_variables`` -- (default: ``False``) if ``True``, + - ``include_slack_variables`` -- boolean (default: ``False``); if ``True``, values of slack variables will be appended at the end - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -2961,9 +2868,7 @@ def column_coefficients(self, v): - ``v`` -- a nonbasic variable of ``self``, can be given as a string, an actual variable, or an integer interpreted as the index of a variable - OUTPUT: - - - a vector of coefficients of a nonbasic variable + OUTPUT: a vector of coefficients of a nonbasic variable EXAMPLES:: @@ -2981,9 +2886,7 @@ def constant_terms(self): r""" Return the constant terms of relations of ``self``. - OUTPUT: - - - a vector. + OUTPUT: a vector EXAMPLES:: @@ -3113,9 +3016,7 @@ def entering(self): r""" Return the currently chosen entering variable. - OUTPUT: - - - a variable if the entering one was chosen, otherwise ``None`` + OUTPUT: a variable if the entering one was chosen, otherwise ``None`` EXAMPLES:: @@ -3136,9 +3037,7 @@ def entering_coefficients(self): r""" Return coefficients of the entering variable. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -3163,7 +3062,7 @@ def is_dual_feasible(self): OUTPUT: - ``True`` if all :meth:`~LPDictionary.objective_coefficients` are - non-positive, ``False`` otherwise + nonpositive, ``False`` otherwise EXAMPLES:: @@ -3187,7 +3086,7 @@ def is_feasible(self): OUTPUT: - ``True`` if all :meth:`~LPDictionary.constant_terms` are - non-negative, ``False`` otherwise + nonnegative, ``False`` otherwise EXAMPLES:: @@ -3211,8 +3110,8 @@ def is_optimal(self): OUTPUT: - ``True`` if ``self`` :meth:`is_feasible` and :meth:`is_dual_feasible` - (i.e. all :meth:`~LPDictionary.constant_terms` are non-negative and - all :meth:`~LPDictionary.objective_coefficients` are non-positive), + (i.e. all :meth:`~LPDictionary.constant_terms` are nonnegative and + all :meth:`~LPDictionary.objective_coefficients` are nonpositive), ``False`` otherwise. EXAMPLES:: @@ -3283,9 +3182,7 @@ def leaving(self): r""" Return the currently chosen leaving variable. - OUTPUT: - - - a variable if the leaving one was chosen, otherwise ``None`` + OUTPUT: a variable if the leaving one was chosen, otherwise ``None`` EXAMPLES:: @@ -3306,9 +3203,7 @@ def leaving_coefficients(self): r""" Return coefficients of the leaving variable. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -3338,9 +3233,7 @@ def nonbasic_variables(self): r""" Return non-basic variables of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -3358,9 +3251,7 @@ def objective_coefficients(self): r""" Return coefficients of the objective of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -3378,9 +3269,7 @@ def objective_name(self): r""" Return the objective name of ``self``. - OUTPUT: - - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -3399,9 +3288,7 @@ def objective_value(self): Return the value of the objective at the :meth:`~LPAbstractDictionary.basic_solution` of ``self``. - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: @@ -3615,9 +3502,7 @@ def row_coefficients(self, v): - ``v`` -- a basic variable of ``self``, can be given as a string, an actual variable, or an integer interpreted as the index of a variable - OUTPUT: - - - a vector of coefficients of a basic variable + OUTPUT: a vector of coefficients of a basic variable EXAMPLES:: @@ -3845,15 +3730,13 @@ class LPDictionary(LPAbstractDictionary): - ``objective_value`` -- current value of the objective `z^*` - - ``basic_variables`` -- a list of basic variables `x_B` + - ``basic_variables`` -- list of basic variables `x_B` - - ``nonbasic_variables`` -- a list of non-basic variables `x_N` + - ``nonbasic_variables`` -- list of non-basic variables `x_N` - ``objective_name`` -- a "name" for the objective `z` - OUTPUT: - - - a :class:`dictionary for an LP problem ` + OUTPUT: a :class:`dictionary for an LP problem ` .. NOTE:: @@ -3878,7 +3761,7 @@ class LPDictionary(LPAbstractDictionary): sage: A = matrix(QQ, ([1, 1], [3, 1])) sage: b = vector(QQ, (1000, 1500)) sage: c = vector(QQ, (10, 5)) - sage: R = PolynomialRing(QQ, "x1, x2, x3, x4", order="neglex") + sage: R = PolynomialRing(QQ, "x1, x2, x3, x4", order='neglex') sage: from sage.numerical.interactive_simplex_method \ ....: import LPDictionary sage: D2 = LPDictionary(A, b, c, 0, R.gens()[2:], R.gens()[:2], "z") @@ -3897,7 +3780,7 @@ def __init__(self, A, b, c, objective_value, sage: A = matrix(QQ, ([1, 1], [3, 1])) sage: b = vector(QQ, (1000, 1500)) sage: c = vector(QQ, (10, 5)) - sage: R = PolynomialRing(QQ, "x1, x2, x3, x4", order="neglex") + sage: R = PolynomialRing(QQ, "x1, x2, x3, x4", order='neglex') sage: from sage.numerical.interactive_simplex_method \ ....: import LPDictionary sage: D = LPDictionary(A, b, c, 0, R.gens()[2:], R.gens()[:2], "z") @@ -3956,9 +3839,7 @@ def random_element(m, n, bound=5, special_probability=0.2): - ``special_probability`` -- (default: 0.2) probability of constructing a potentially infeasible or potentially optimal dictionary - OUTPUT: - - - an :class:`LP problem dictionary ` + OUTPUT: an :class:`LP problem dictionary ` EXAMPLES:: @@ -3976,7 +3857,7 @@ def random_element(m, n, bound=5, special_probability=0.2): c = random_vector(ZZ, n, x=-bound, y=bound).change_ring(QQ) else: # Make dual feasible dictionary c = random_vector(ZZ, n, x=-bound, y=0).change_ring(QQ) - x_N = list(PolynomialRing(QQ, "x", m + n + 1, order="neglex").gens()) + x_N = list(PolynomialRing(QQ, "x", m + n + 1, order='neglex').gens()) x_N.pop(0) x_B = [x_N.pop(randint(0, n + m - i - 1)) for i in range(m)] return LPDictionary(A, b, c, randint(-bound, bound), x_B, x_N, "z") @@ -4005,7 +3886,7 @@ def __eq__(self, other): sage: A = matrix(QQ, ([1, 1], [3, 1])) sage: b = vector(QQ, (1000, 1500)) sage: c = vector(QQ, (10, 5)) - sage: R = PolynomialRing(QQ, "x1, x2, x3, x4", order="neglex") + sage: R = PolynomialRing(QQ, "x1, x2, x3, x4", order='neglex') sage: from sage.numerical.interactive_simplex_method \ ....: import LPDictionary sage: D2 = LPDictionary(A, b, c, 0, R.gens()[2:], R.gens()[:2], "z") @@ -4023,9 +3904,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string TESTS:: @@ -4099,18 +3978,16 @@ def add_row(self, nonbasic_coefficients, constant, basic_variable=None): INPUT: - - ``nonbasic_coefficients`` -- a list of the coefficients for the + - ``nonbasic_coefficients`` -- list of the coefficients for the new row (with which nonbasic variables are subtracted in the relation for the new basic variable) - - ``constant`` -- the constant term for the new row + - ``constant`` -- the constant term for the new row - ``basic_variable`` -- (default: depends on :func:`style`) a string giving the name of the basic variable of the new row - OUTPUT: - - - a :class:`dictionary ` + OUTPUT: a :class:`dictionary ` EXAMPLES:: @@ -4145,7 +4022,7 @@ def add_row(self, nonbasic_coefficients, constant, basic_variable=None): basic_variable = str(basic_variable) R = PolynomialRing( - BR, list(B.base_ring().variable_names()) + [basic_variable], order="neglex") + BR, list(B.base_ring().variable_names()) + [basic_variable], order='neglex') B = list(B) + [basic_variable] B = map(R, B) N = map(R, N) @@ -4155,9 +4032,7 @@ def basic_variables(self): r""" Return the basic variables of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -4180,9 +4055,7 @@ def column_coefficients(self, v): - ``v`` -- a nonbasic variable of ``self``, can be given as a string, an actual variable, or an integer interpreted as the index of a variable - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -4205,9 +4078,7 @@ def constant_terms(self): r""" Return the constant terms of relations of ``self``. - OUTPUT: - - - a vector. + OUTPUT: a vector EXAMPLES:: @@ -4225,9 +4096,7 @@ def nonbasic_variables(self): r""" Return non-basic variables of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -4245,9 +4114,7 @@ def objective_coefficients(self): r""" Return coefficients of the objective of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -4265,9 +4132,7 @@ def objective_name(self): r""" Return the objective name of ``self``. - OUTPUT: - - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -4286,9 +4151,7 @@ def objective_value(self): Return the value of the objective at the :meth:`~LPAbstractDictionary.basic_solution` of ``self``. - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: @@ -4314,9 +4177,7 @@ def row_coefficients(self, v): - ``v`` -- a basic variable of ``self``, can be given as a string, an actual variable, or an integer interpreted as the index of a variable - OUTPUT: - - - a vector of coefficients of a basic variable + OUTPUT: a vector of coefficients of a basic variable EXAMPLES:: @@ -4413,11 +4274,9 @@ class LPRevisedDictionary(LPAbstractDictionary): - ``problem`` -- an :class:`LP problem in standard form ` - - ``basic_variables`` -- a list of basic variables or their indices + - ``basic_variables`` -- list of basic variables or their indices - OUTPUT: - - - a :class:`revised dictionary for an LP problem ` + OUTPUT: a :class:`revised dictionary for an LP problem ` A revised dictionary encodes the same relations as a :class:`regular dictionary `, but stores only what is @@ -4585,9 +4444,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - a string + OUTPUT: string TESTS:: @@ -4712,12 +4569,10 @@ def _preupdate_output(self, direction): INPUT: - - ``direction`` -- a string specifying the type of the simplex method + - ``direction`` -- string specifying the type of the simplex method used, either "primal" or "dual" - OUTPUT: - - - :class:`~sage.misc.html.HtmlFragment`. + OUTPUT: :class:`~sage.misc.html.HtmlFragment` TESTS:: @@ -4758,9 +4613,7 @@ def A(self, v): - ``v`` -- a variable, its name, or its index - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -4794,9 +4647,7 @@ def A_N(self): Return the `A_N` matrix, constraint coefficients of non-basic variables. - OUTPUT: - - - a matrix + OUTPUT: a matrix EXAMPLES:: @@ -4817,9 +4668,7 @@ def B(self): Return the `B` matrix, i.e. constraint coefficients of basic variables. - OUTPUT: - - - a matrix + OUTPUT: a matrix EXAMPLES:: @@ -4842,9 +4691,7 @@ def B_inverse(self): This inverse matrix is stored and computed during dictionary update in a more efficient way than generic inversion. - OUTPUT: - - - a matrix + OUTPUT: a matrix EXAMPLES:: @@ -4867,9 +4714,7 @@ def E(self): r""" Return the eta matrix between ``self`` and the next dictionary. - OUTPUT: - - - a matrix + OUTPUT: a matrix If `B_{\mathrm{old}}` is the current matrix `B` and `B_{\mathrm{new}}` is the `B` matrix of the next dictionary (after the update step), then @@ -4907,9 +4752,7 @@ def E_inverse(self): This inverse matrix is computed in a more efficient way than generic inversion. - OUTPUT: - - - a matrix + OUTPUT: a matrix EXAMPLES:: @@ -4946,18 +4789,16 @@ def add_row(self, nonbasic_coefficients, constant, basic_variable=None): INPUT: - - ``nonbasic_coefficients`` -- a list of the coefficients for the + - ``nonbasic_coefficients`` -- list of the coefficients for the new row (with which nonbasic variables are subtracted in the relation for the new basic variable) - - ``constant`` -- the constant term for the new row + - ``constant`` -- the constant term for the new row - ``basic_variable`` -- (default: depends on :func:`style`) a string giving the name of the basic variable of the new row - OUTPUT: - - - a :class:`revised dictionary ` + OUTPUT: a :class:`revised dictionary ` EXAMPLES:: @@ -5035,9 +4876,7 @@ def basic_indices(self): indices of variables which are parts of their names. (They will for the default indexed names.) - OUTPUT: - - - a list. + OUTPUT: list EXAMPLES:: @@ -5056,9 +4895,7 @@ def basic_variables(self): r""" Return the basic variables of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -5076,9 +4913,7 @@ def c_B(self): r""" Return the `c_B` vector, objective coefficients of basic variables. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -5106,9 +4941,7 @@ def c_N(self): r""" Return the `c_N` vector, objective coefficients of non-basic variables. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -5139,9 +4972,7 @@ def column_coefficients(self, v): - ``v`` -- a nonbasic variable of ``self``, can be given as a string, an actual variable, or an integer interpreted as the index of a variable - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -5163,9 +4994,7 @@ def constant_terms(self): r""" Return constant terms in the relations of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -5183,9 +5012,7 @@ def dictionary(self): r""" Return a regular LP dictionary matching ``self``. - OUTPUT: - - - an :class:`LP dictionary ` + OUTPUT: an :class:`LP dictionary ` EXAMPLES:: @@ -5221,9 +5048,7 @@ def nonbasic_indices(self): of variables which are parts of their names. (They will for the default indexed names.) - OUTPUT: - - - a list + OUTPUT: list EXAMPLES:: @@ -5242,9 +5067,7 @@ def nonbasic_variables(self): r""" Return non-basic variables of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: @@ -5263,9 +5086,7 @@ def objective_coefficients(self): r""" Return coefficients of the objective of ``self``. - OUTPUT: - - - a vector + OUTPUT: a vector These are coefficients of non-basic variables when basic variables are eliminated. @@ -5286,9 +5107,7 @@ def objective_name(self): r""" Return the objective name of ``self``. - OUTPUT: - - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -5306,9 +5125,7 @@ def objective_value(self): r""" Return the value of the objective at the basic solution of ``self``. - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: @@ -5327,9 +5144,7 @@ def problem(self): r""" Return the original problem. - OUTPUT: - - - an :class:`LP problem in standard form ` + OUTPUT: an :class:`LP problem in standard form ` EXAMPLES:: @@ -5355,9 +5170,7 @@ def row_coefficients(self, v): - ``v`` -- a basic variable of ``self``, can be given as a string, an actual variable, or an integer interpreted as the index of a variable - OUTPUT: - - - a vector of coefficients of a basic variable + OUTPUT: a vector of coefficients of a basic variable EXAMPLES:: @@ -5419,9 +5232,7 @@ def y(self): Return the `y` vector, the product of :meth:`c_B` and :meth:`B_inverse`. - OUTPUT: - - - a vector + OUTPUT: a vector EXAMPLES:: diff --git a/src/sage/numerical/knapsack.py b/src/sage/numerical/knapsack.py index 3f80f517998..9f9d06fcd3b 100644 --- a/src/sage/numerical/knapsack.py +++ b/src/sage/numerical/knapsack.py @@ -103,7 +103,7 @@ class Superincreasing(SageObject): A class for super-increasing sequences. Let `L = (a_1, a_2, a_3, \dots, a_n)` be a non-empty sequence of - non-negative integers. Then `L` is said to be super-increasing if + nonnegative integers. Then `L` is said to be super-increasing if each `a_i` is strictly greater than the sum of all previous values. That is, for each `a_i \in L` the sequence `L` must satisfy the property @@ -120,7 +120,7 @@ class Superincreasing(SageObject): INPUT: - - ``seq`` -- (default: ``None``) a non-empty sequence. + - ``seq`` -- (default: ``None``) a non-empty sequence EXAMPLES:: @@ -148,8 +148,7 @@ def __init__(self, seq=None): INPUT: - - ``seq`` -- (default: ``None``) a non-empty sequence. - + - ``seq`` -- (default: ``None``) a non-empty sequence EXAMPLES:: @@ -204,7 +203,6 @@ def __repr__(self): Return a string representation of this super-increasing sequence object. - EXAMPLES:: sage: from sage.numerical.knapsack import Superincreasing @@ -231,15 +229,13 @@ def largest_less_than(self, N): INPUT: - - ``N`` -- integer; the target value to search for. - + - ``N`` -- integer; the target value to search for OUTPUT: The largest integer in ``self`` that is less than or equal to ``N``. If no solution exists, then return ``None``. - EXAMPLES: When a solution is found, return it:: @@ -339,7 +335,7 @@ def is_superincreasing(self, seq=None): super-increasing. Let `L = (a_1, a_2, a_3, \dots, a_n)` be a non-empty sequence of - non-negative integers. Then `L` is said to be super-increasing if + nonnegative integers. Then `L` is said to be super-increasing if each `a_i` is strictly greater than the sum of all previous values. That is, for each `a_i \in L` the sequence `L` must satisfy the property @@ -352,12 +348,10 @@ def is_superincreasing(self, seq=None): If `L` has exactly one element, then it is also defined to be a super-increasing sequence. - INPUT: - ``seq`` -- (default: ``None``) a sequence to test - OUTPUT: - If ``seq`` is ``None``, then test ``self`` to determine whether or @@ -368,7 +362,6 @@ def is_superincreasing(self, seq=None): or not it is super-increasing. Return ``True`` if ``seq`` is super-increasing; ``False`` otherwise. - EXAMPLES: By definition, an empty sequence is not super-increasing:: @@ -414,12 +407,12 @@ def is_superincreasing(self, seq=None): sage: Superincreasing(L).is_superincreasing() Traceback (most recent call last): ... - TypeError: Element e (= 1.00000000000000) of seq must be a non-negative integer. + TypeError: Element e (= 1.00000000000000) of seq must be a nonnegative integer. sage: L = [1, 2.1, pi, 21, 69, 189, 376, 919] sage: Superincreasing(L).is_superincreasing() Traceback (most recent call last): ... - TypeError: Element e (= 2.10000000000000) of seq must be a non-negative integer. + TypeError: Element e (= 2.10000000000000) of seq must be a nonnegative integer. """ # argument seq is None, so test self for super-increasing if seq is None: @@ -448,15 +441,15 @@ def is_superincreasing(self, seq=None): return False # so now seq is known to represent a non-empty sequence if (not isinstance(seq[0], Integer)) and (not isinstance(seq[0], int)): - raise TypeError("Element e (= %s) of seq must be a non-negative integer." % seq[0]) + raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % seq[0]) if seq[0] < 0: - raise TypeError("Element e (= %s) of seq must be a non-negative integer." % seq[0]) + raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % seq[0]) cumSum = seq[0] # the cumulative sum of the sequence seq for e in seq[1:]: if (not isinstance(e, Integer)) and (not isinstance(e, int)): - raise TypeError("Element e (= %s) of seq must be a non-negative integer." % e) + raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % e) if e < 0: - raise TypeError("Element e (= %s) of seq must be a non-negative integer." % e) + raise TypeError("Element e (= %s) of seq must be a nonnegative integer." % e) if e <= cumSum: return False cumSum += e @@ -467,7 +460,7 @@ def subset_sum(self, N): Solving the subset sum problem for a super-increasing sequence. Let `S = (s_1, s_2, s_3, \dots, s_n)` be a non-empty sequence of - non-negative integers, and let `N \in \ZZ` be non-negative. The + nonnegative integers, and let `N \in \ZZ` be nonnegative. The subset sum problem asks for a subset `A \subseteq S` all of whose elements sum to `N`. This method specializes the subset sum problem to the case of super-increasing sequences. If a solution exists, then @@ -480,11 +473,9 @@ def subset_sum(self, N): problem for an arbitrary sequence is known to be computationally hard. - INPUT: - - ``N`` -- a non-negative integer. - + - ``N`` -- nonnegative integer OUTPUT: @@ -492,12 +483,10 @@ def subset_sum(self, N): subset is also a super-increasing sequence. If no such subset exists, then return the empty list. - - ALGORITHMS: + ALGORITHM: The algorithm used is adapted from page 355 of [HPS2008]_. - EXAMPLES: Solving the subset sum problem for a super-increasing sequence @@ -511,35 +500,35 @@ def subset_sum(self, N): TESTS: - The target ``N`` must be a non-negative integer:: + The target ``N`` must be a nonnegative integer:: sage: from sage.numerical.knapsack import Superincreasing sage: L = [0, 1, 2, 4] sage: Superincreasing(L).subset_sum(-6) Traceback (most recent call last): ... - TypeError: N (= -6) must be a non-negative integer. + TypeError: N (= -6) must be a nonnegative integer. sage: Superincreasing(L).subset_sum(-6.2) Traceback (most recent call last): ... - TypeError: N (= -6.20000000000000) must be a non-negative integer. + TypeError: N (= -6.20000000000000) must be a nonnegative integer. - The sequence that ``self`` represents must only contain non-negative + The sequence that ``self`` represents must only contain nonnegative integers:: sage: L = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1] sage: Superincreasing(L).subset_sum(1) Traceback (most recent call last): ... - TypeError: Element e (= -10) of seq must be a non-negative integer. + TypeError: Element e (= -10) of seq must be a nonnegative integer. """ # input error handling if not self.is_superincreasing(): raise TypeError("self is not super-increasing. Only super-increasing sequences are currently supported.") if (not isinstance(N, Integer)) and (not isinstance(N, int)): - raise TypeError("N (= %s) must be a non-negative integer." % N) + raise TypeError("N (= %s) must be a nonnegative integer." % N) if N < 0: - raise TypeError("N (= %s) must be a non-negative integer." % N) + raise TypeError("N (= %s) must be a nonnegative integer." % N) # solve subset sum problem for super-increasing sequence candidates = [] @@ -559,7 +548,7 @@ def subset_sum(self, N): def knapsack(seq, binary=True, max=1, value_only=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Solves the knapsack problem + Solve the knapsack problem. For more information on the knapsack problem, see the documentation of the :mod:`knapsack module ` or the @@ -567,7 +556,7 @@ def knapsack(seq, binary=True, max=1, value_only=False, solver=None, verbose=0, INPUT: - - ``seq`` -- Two different possible types: + - ``seq`` -- two different possible types: - A sequence of tuples ``(weight, value, something1, something2, ...)``. Note that only the first two coordinates (``weight`` and @@ -577,17 +566,17 @@ def knapsack(seq, binary=True, max=1, value_only=False, solver=None, verbose=0, - A sequence of reals (a value of 1 is assumed). - - ``binary`` -- When set to ``True``, an item can be taken 0 or 1 time. + - ``binary`` -- when set to ``True``, an item can be taken 0 or 1 time When set to ``False``, an item can be taken any amount of times (while staying integer and positive). - - ``max`` -- Maximum admissible weight. + - ``max`` -- maximum admissible weight - - ``value_only`` -- When set to ``True``, only the maximum useful value is + - ``value_only`` -- when set to ``True``, only the maximum useful value is returned. When set to ``False``, both the maximum useful value and an assignment are returned. - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -595,11 +584,11 @@ def knapsack(seq, binary=True, max=1, value_only=False, solver=None, verbose=0, of the class :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``). Sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` OUTPUT: diff --git a/src/sage/numerical/linear_functions.pyx b/src/sage/numerical/linear_functions.pyx index d1a038fd54b..3b0061960e1 100644 --- a/src/sage/numerical/linear_functions.pyx +++ b/src/sage/numerical/linear_functions.pyx @@ -116,15 +116,13 @@ from sage.misc.cachefunc import cached_function cpdef is_LinearFunction(x): """ - Test whether ``x`` is a linear function + Test whether ``x`` is a linear function. INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -149,15 +147,13 @@ cpdef is_LinearFunction(x): def is_LinearConstraint(x): """ - Test whether ``x`` is a linear constraint + Test whether ``x`` is a linear constraint. INPUT: - - ``x`` -- anything. - - OUTPUT: + - ``x`` -- anything - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -197,12 +193,10 @@ def LinearFunctionsParent(base_ring): INPUT: - - ``base_ring`` -- a ring. The coefficient ring for the linear - functions. + - ``base_ring`` -- a ring; the coefficient ring for the linear + functions - OUTPUT: - - The parent of the linear functions over ``base_ring``. + OUTPUT: the parent of the linear functions over ``base_ring`` EXAMPLES:: @@ -223,13 +217,11 @@ def LinearConstraintsParent(linear_functions_parent): INPUT: - - ``linear_functions_parent`` -- a - :class:`LinearFunctionsParent_class`. The type of linear - functions that the constraints are made out of. - - OUTPUT: + - ``linear_functions_parent`` -- a + :class:`LinearFunctionsParent_class`; the type of linear + functions that the constraints are made out of - The parent of the linear constraints with the given linear functions. + OUTPUT: the parent of the linear constraints with the given linear functions EXAMPLES:: @@ -539,9 +531,7 @@ cdef class LinearFunctionsParent_class(Parent): You should use :func:`LinearFunctionsParent` to construct instances of this class. - INPUT/OUTPUT: - - See :func:`LinearFunctionsParent` + INPUT/OUTPUT: see :func:`LinearFunctionsParent` EXAMPLES:: @@ -551,7 +541,7 @@ cdef class LinearFunctionsParent_class(Parent): """ def __cinit__(self): """ - Cython initializer + Cython initializer. TESTS:: @@ -566,7 +556,7 @@ cdef class LinearFunctionsParent_class(Parent): def __init__(self, base_ring): """ - The Python constructor + The Python constructor. TESTS:: @@ -583,8 +573,8 @@ cdef class LinearFunctionsParent_class(Parent): INPUT: - - ``symbol`` -- string, default: ``'*'``. The multiplication - symbol to be used. + - ``symbol`` -- string (default: ``'*'``); the multiplication + symbol to be used EXAMPLES:: @@ -609,9 +599,7 @@ cdef class LinearFunctionsParent_class(Parent): """ Return the multiplication symbol. - OUTPUT: - - String. By default, this is ``'*'``. + OUTPUT: string. By default, this is ``'*'`` EXAMPLES:: @@ -628,7 +616,7 @@ cdef class LinearFunctionsParent_class(Parent): INPUT: - ``free_module`` -- vector space or matrix space over the - same base ring. + same base ring OUTPUT: @@ -655,11 +643,9 @@ cdef class LinearFunctionsParent_class(Parent): INPUT: - - ``i`` -- non-negative integer. + - ``i`` -- nonnegative integer - OUTPUT: - - The linear function `x_i`. + OUTPUT: the linear function `x_i` EXAMPLES:: @@ -671,7 +657,7 @@ cdef class LinearFunctionsParent_class(Parent): def _repr_(self): """ - Return as string representation + Return as string representation. EXAMPLES:: @@ -716,11 +702,9 @@ cdef class LinearFunctionsParent_class(Parent): INPUT: - - ``R`` -- a ring. - - OUTPUT: + - ``R`` -- a ring - Boolean. Whether there is a coercion map. + OUTPUT: boolean; whether there is a coercion map EXAMPLES:: @@ -738,11 +722,9 @@ cdef class LinearFunctionsParent_class(Parent): def _an_element_(self): """ - Returns an element + Return an element. - OUTPUT: - - A linear function. + OUTPUT: a linear function EXAMPLES:: @@ -869,8 +851,8 @@ cdef class LinearFunction(LinearFunctionOrConstraint): INPUT: - - ``x`` -- a linear variable or an integer. If an integer `i` - is passed, then `x_i` is used as linear variable. + - ``x`` -- a linear variable or an integer; if an integer `i` + is passed, then `x_i` is used as linear variable OUTPUT: @@ -924,7 +906,7 @@ cdef class LinearFunction(LinearFunctionOrConstraint): cpdef _add_(self, b): r""" - Defining the + operator + Defining the ``+`` operator. EXAMPLES:: @@ -974,7 +956,7 @@ cdef class LinearFunction(LinearFunctionOrConstraint): cpdef _lmul_(self, Element b): r""" - Multiplication by scalars + Multiplication by scalars. EXAMPLES:: @@ -1045,11 +1027,11 @@ cdef class LinearFunction(LinearFunctionOrConstraint): def _coeff_formatter(self, coeff, constant_term=False): """ - Pretty-print multiplicative coefficient ``x`` + Pretty-print multiplicative coefficient ``x``. OUTPUT: - String, including a trailing space if the coefficient is not + string, including a trailing space if the coefficient is not one. Empty string otherwise. EXAMPLES:: @@ -1104,7 +1086,7 @@ cdef class LinearFunction(LinearFunctionOrConstraint): def _repr_(self): r""" - Returns a string version of the linear function. + Return a string version of the linear function. EXAMPLES:: @@ -1151,9 +1133,7 @@ cdef class LinearFunction(LinearFunctionOrConstraint): """ Test whether ``self`` is zero. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1171,9 +1151,7 @@ cdef class LinearFunction(LinearFunctionOrConstraint): """ Logically compare ``left`` and ``right``. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1193,7 +1171,7 @@ cdef class LinearFunction(LinearFunctionOrConstraint): cdef class LinearConstraintsParent_class(Parent): """ - Parent for :class:`LinearConstraint` + Parent for :class:`LinearConstraint`. .. warning:: @@ -1202,9 +1180,7 @@ cdef class LinearConstraintsParent_class(Parent): :class:`MixedIntegerLinearProgram`. Also, use the :func:`LinearConstraintsParent` factory function. - INPUT/OUTPUT: - - See :func:`LinearFunctionsParent` + INPUT/OUTPUT: see :func:`LinearFunctionsParent` EXAMPLES:: @@ -1217,7 +1193,7 @@ cdef class LinearConstraintsParent_class(Parent): """ def __cinit__(self, linear_functions_parent): """ - Cython initializer + Cython initializer. TESTS:: @@ -1237,11 +1213,9 @@ cdef class LinearConstraintsParent_class(Parent): def __init__(self, linear_functions_parent): """ - The Python constructor - - INPUT/OUTPUT: + The Python constructor. - See :func:`LinearFunctionsParent` + INPUT/OUTPUT: see :func:`LinearFunctionsParent` TESTS:: @@ -1259,7 +1233,7 @@ cdef class LinearConstraintsParent_class(Parent): def linear_functions_parent(self): """ - Return the parent for the linear functions + Return the parent for the linear functions. EXAMPLES:: @@ -1271,11 +1245,9 @@ cdef class LinearConstraintsParent_class(Parent): def _repr_(self): """ - Return a string representation + Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1296,14 +1268,12 @@ cdef class LinearConstraintsParent_class(Parent): :class:`LinearConstraint`. - ``right`` -- a :class:`LinearFunction` or ``None`` - (default). - - - ``equality`` -- boolean (default: ``True``). Whether to - construct an equation or an inequality. + (default) - OUTPUT: + - ``equality`` -- boolean (default: ``True``); whether to + construct an equation or an inequality - The :class:`LinearConstraint` constructed from the input data. + OUTPUT: the :class:`LinearConstraint` constructed from the input data EXAMPLES:: @@ -1366,7 +1336,7 @@ cdef class LinearConstraintsParent_class(Parent): def _an_element_(self): """ - Returns an element + Return an element. EXAMPLES:: @@ -1410,15 +1380,15 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): INPUT: - - ``parent`` -- the parent, a :class:`LinearConstraintsParent_class` + - ``parent`` -- the parent; a :class:`LinearConstraintsParent_class` - - ``terms`` -- a list/tuple/iterable of two or more linear + - ``terms`` -- list/tuple/iterable of two or more linear functions (or things that can be converted into linear - functions). + functions) - - ``equality`` -- boolean (default: ``False``). Whether the terms + - ``equality`` -- boolean (default: ``False``); whether the terms are the entries of a chained less-or-equal (``<=``) inequality - or a chained equality. + or a chained equality EXAMPLES:: @@ -1430,7 +1400,7 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def __init__(self, parent, terms, equality=False): r""" - Constructor for ``LinearConstraint`` + Constructor for ``LinearConstraint``. INPUT: @@ -1455,7 +1425,7 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): OUTPUT: - Boolean. Whether all terms of ``left`` and ``right`` are + boolean; whether all terms of ``left`` and ``right`` are equal. Note that this is stronger than mathematical equivalence of the relations. @@ -1482,11 +1452,9 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def is_equation(self): """ - Whether the constraint is a chained equation - - OUTPUT: + Whether the constraint is a chained equation. - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1501,11 +1469,9 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def is_less_or_equal(self): """ - Whether the constraint is a chained less-or_equal inequality + Whether the constraint is a chained less-or_equal inequality. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1540,7 +1506,7 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def __iter__(self): """ - Iterate over the terms of the chained (in)-equality + Iterate over the terms of the chained (in)-equality. OUTPUT: @@ -1568,7 +1534,7 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def equations(self): """ - Iterate over the unchained(!) equations + Iterate over the unchained(!) equations. OUTPUT: @@ -1603,7 +1569,7 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def inequalities(self): """ - Iterate over the unchained(!) inequalities + Iterate over the unchained(!) inequalities. OUTPUT: @@ -1639,11 +1605,9 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def _repr_(self): r""" - Returns a string representation of the constraint. - - OUTPUT: + Return a string representation of the constraint. - String. + OUTPUT: string EXAMPLES:: @@ -1666,7 +1630,7 @@ cdef class LinearConstraint(LinearFunctionOrConstraint): def __bool__(self): """ - Part of the hack to allow chained (in)equalities + Part of the hack to allow chained (in)equalities. EXAMPLES:: diff --git a/src/sage/numerical/linear_tensor.py b/src/sage/numerical/linear_tensor.py index c4c62066db5..e7eaedb2fe5 100644 --- a/src/sage/numerical/linear_tensor.py +++ b/src/sage/numerical/linear_tensor.py @@ -116,11 +116,9 @@ def is_LinearTensor(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -159,11 +157,10 @@ def LinearTensorParent(free_module_parent, linear_functions_parent): INPUT: - - ``free_module_parent`` -- module. A free module, like vector or - matrix space. + - ``free_module_parent`` -- a free module, like vector or matrix space - - ``linear_functions_parent`` -- linear functions. The linear - functions parent. + - ``linear_functions_parent`` -- linear functions; the linear functions + parent OUTPUT: @@ -204,9 +201,7 @@ class LinearTensorParent_class(Parent): You should use :func:`LinearTensorParent` to construct instances of this class. - INPUT/OUTPUT: - - See :func:`LinearTensorParent` + INPUT/OUTPUT: see :func:`LinearTensorParent` EXAMPLES:: @@ -218,11 +213,9 @@ class LinearTensorParent_class(Parent): def __init__(self, free_module, linear_functions): """ - The Python constructor - - INPUT/OUTPUT: + The Python constructor. - See :func:`LinearTensorParent` + INPUT/OUTPUT: see :func:`LinearTensorParent` TESTS:: @@ -263,10 +256,8 @@ def is_vector_space(self): """ Return whether the free module is a vector space. - OUTPUT: - - Boolean. Whether the :meth:`free_module` factor in the tensor - product is a vector space. + OUTPUT: boolean; whether the :meth:`free_module` factor in the tensor + product is a vector space EXAMPLES:: @@ -284,10 +275,8 @@ def is_matrix_space(self): """ Return whether the free module is a matrix space. - OUTPUT: - - Boolean. Whether the :meth:`free_module` factor in the tensor - product is a matrix space. + OUTPUT: boolean; whether the :meth:`free_module` factor in the tensor + product is a matrix space EXAMPLES:: @@ -325,11 +314,9 @@ def linear_functions(self): def _repr_(self): """ - Return a string representation + Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -342,9 +329,7 @@ def _convert_constant(self, m): """ Convert ``m`` to a constant free module element. - OUTPUT: - - A :meth:`free_module` element. + OUTPUT: a :meth:`free_module` element EXAMPLES:: @@ -441,11 +426,9 @@ def _coerce_map_from_(self, R): INPUT: - - ``R`` -- a ring. + - ``R`` -- a ring - OUTPUT: - - Boolean. Whether there is a coercion map. + OUTPUT: boolean; whether there is a coercion map EXAMPLES:: @@ -470,11 +453,9 @@ def _coerce_map_from_(self, R): def _an_element_(self): """ - Returns an element - - OUTPUT: + Return an element. - A linear function tensored with a free module. + OUTPUT: a linear function tensored with a free module EXAMPLES:: diff --git a/src/sage/numerical/linear_tensor_constraints.py b/src/sage/numerical/linear_tensor_constraints.py index 60578c2511d..68aa1178d00 100644 --- a/src/sage/numerical/linear_tensor_constraints.py +++ b/src/sage/numerical/linear_tensor_constraints.py @@ -45,11 +45,9 @@ def is_LinearTensorConstraint(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -92,9 +90,7 @@ def LinearTensorConstraintsParent(linear_functions_parent): :class:`~sage.numerical.linear_functions.LinearFunctionsParent_class`. The type of linear functions that the constraints are made out of. - OUTPUT: - - The parent of the linear constraints with the given linear functions. + OUTPUT: the parent of the linear constraints with the given linear functions EXAMPLES:: @@ -143,7 +139,7 @@ class LinearTensorConstraint(Element): :class:`sage.numerical.linear_tensor_element.LinearTensor`. The left and right hand side of the constraint (in)equality. - - ``equality`` -- boolean (default: ``False``). Whether the + - ``equality`` -- boolean (default: ``False``); whether the constraint is an equality. If ``False``, it is a ``<=`` inequality. @@ -156,7 +152,7 @@ class LinearTensorConstraint(Element): def __init__(self, parent, lhs, rhs, equality): r""" - Constructor for ``LinearTensorConstraint`` + Constructor for ``LinearTensorConstraint``. INPUT: @@ -175,11 +171,9 @@ def __init__(self, parent, lhs, rhs, equality): def is_equation(self): """ - Whether the constraint is a chained equation + Whether the constraint is a chained equation. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -193,11 +187,9 @@ def is_equation(self): def is_less_or_equal(self): """ - Whether the constraint is a chained less-or_equal inequality + Whether the constraint is a chained less-or_equal inequality. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -247,7 +239,7 @@ def rhs(self): def _ascii_art_(self): """ - Return Ascii Art + Return Ascii Art. OUTPUT: @@ -272,11 +264,9 @@ def matrix_art(m): def _repr_(self): r""" - Returns a string representation of the constraint. - - OUTPUT: + Return a string representation of the constraint. - String. + OUTPUT: string EXAMPLES:: @@ -304,7 +294,7 @@ def _repr_(self): class LinearTensorConstraintsParent_class(Parent): """ - Parent for :class:`LinearTensorConstraint` + Parent for :class:`LinearTensorConstraint`. .. warning:: @@ -313,9 +303,7 @@ class LinearTensorConstraintsParent_class(Parent): :class:`MixedIntegerLinearProgram`. Also, use the :func:`LinearTensorConstraintsParent` factory function. - INPUT/OUTPUT: - - See :func:`LinearTensorConstraintsParent` + INPUT/OUTPUT: see :func:`LinearTensorConstraintsParent` EXAMPLES:: @@ -335,12 +323,12 @@ class LinearTensorConstraintsParent_class(Parent): def __init__(self, linear_tensor_parent): """ - The Python constructor + The Python constructor. INPUT: - ``linear_tensor_parent`` -- instance of - :class:`LinearTensorParent_class`. + :class:`LinearTensorParent_class` TESTS:: @@ -360,11 +348,9 @@ def __init__(self, linear_tensor_parent): def linear_tensors(self): """ - Return the parent for the linear functions + Return the parent for the linear functions. - OUTPUT: - - Instance of :class:`sage.numerical.linear_tensor.LinearTensorParent_class`. + OUTPUT: instance of :class:`sage.numerical.linear_tensor.LinearTensorParent_class` EXAMPLES:: @@ -378,11 +364,9 @@ def linear_tensors(self): def linear_functions(self): """ - Return the parent for the linear functions - - OUTPUT: + Return the parent for the linear functions. - Instance of :class:`sage.numerical.linear_functions.LinearFunctionsParent_class`. + OUTPUT: instance of :class:`sage.numerical.linear_functions.LinearFunctionsParent_class` EXAMPLES:: @@ -395,11 +379,9 @@ def linear_functions(self): def _repr_(self): """ - Return a string representation + Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -425,14 +407,12 @@ def _element_constructor_(self, left, right, equality): :class:`LinearTensorConstraint`. - ``right`` -- a :class:`LinearTensor` or ``None`` - (default). + (default) - - ``equality`` -- boolean. Whether to - construct an equation or a less-or-equal inequality. - - OUTPUT: + - ``equality`` -- boolean; whether to + construct an equation or a less-or-equal inequality - The :class:`LinearTensorConstraint` constructed from the input data. + OUTPUT: the :class:`LinearTensorConstraint` constructed from the input data EXAMPLES:: diff --git a/src/sage/numerical/linear_tensor_element.pyx b/src/sage/numerical/linear_tensor_element.pyx index f7dd2b61deb..4c6ba3c20cc 100644 --- a/src/sage/numerical/linear_tensor_element.pyx +++ b/src/sage/numerical/linear_tensor_element.pyx @@ -34,7 +34,7 @@ from sage.numerical.linear_functions cimport LinearFunction, is_LinearFunction cdef class LinearTensor(ModuleElement): r""" - A linear function tensored with a free module + A linear function tensored with a free module. .. warning:: @@ -56,9 +56,9 @@ cdef class LinearTensor(ModuleElement): INPUT: - ``parent`` -- the parent - :class:`~sage.numerical.linear_tensor.LinearTensorParent_class`. + :class:`~sage.numerical.linear_tensor.LinearTensorParent_class` - - ``f`` -- A linear function tensored by a free module is + - ``f`` -- a linear function tensored by a free module is represented as a dictionary. The values are the coefficient (free module elements) of the variable represented by the keys. The key ``-1`` corresponds to the constant term. @@ -188,9 +188,7 @@ cdef class LinearTensor(ModuleElement): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -226,9 +224,7 @@ cdef class LinearTensor(ModuleElement): """ Return a matrix-like string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -267,11 +263,9 @@ cdef class LinearTensor(ModuleElement): INPUT: - - ``b`` -- a :class:`LinearTensor`. - - OUTPUT: + - ``b`` -- a :class:`LinearTensor` - A :class:`LinearTensor`. + OUTPUT: a :class:`LinearTensor` EXAMPLES:: @@ -289,9 +283,7 @@ cdef class LinearTensor(ModuleElement): r""" Return the negative. - OUTPUT: - - A :class:`LinearTensor`. + OUTPUT: a :class:`LinearTensor` EXAMPLES:: @@ -311,11 +303,9 @@ cdef class LinearTensor(ModuleElement): INPUT: - - ``b`` -- a :class:`LinearTensor`. - - OUTPUT: + - ``b`` -- a :class:`LinearTensor` - A :class:`LinearTensor`. + OUTPUT: a :class:`LinearTensor` EXAMPLES:: @@ -337,11 +327,9 @@ cdef class LinearTensor(ModuleElement): INPUT: - - ``b`` -- base ring element. The scalar to multiply by. - - OUTPUT: + - ``b`` -- base ring element; the scalar to multiply by - A :class:`LinearTensor`. + OUTPUT: a :class:`LinearTensor` EXAMPLES:: diff --git a/src/sage/numerical/meson.build b/src/sage/numerical/meson.build new file mode 100644 index 00000000000..222deff834e --- /dev/null +++ b/src/sage/numerical/meson.build @@ -0,0 +1,35 @@ +py.install_sources( + 'all.py', + 'all__sagemath_polyhedra.py', + 'interactive_simplex_method.py', + 'knapsack.py', + 'linear_functions.pxd', + 'linear_tensor.py', + 'linear_tensor_constraints.py', + 'linear_tensor_element.pxd', + 'mip.pxd', + 'optimize.py', + 'sdp.pxd', + subdir: 'sage/numerical', +) + +extension_data = { + 'gauss_legendre' : files('gauss_legendre.pyx'), + 'linear_functions' : files('linear_functions.pyx'), + 'linear_tensor_element' : files('linear_tensor_element.pyx'), + 'mip' : files('mip.pyx'), + 'sdp' : files('sdp.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/numerical', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cypari2, gmp, mpfr], + ) +endforeach + +subdir('backends') diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 7af017ebd17..2395868b43d 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -49,7 +49,7 @@ A mixed integer linear program can give you an answer: #. You have to create an instance of :class:`MixedIntegerLinearProgram` and -- in our case -- specify that it is a minimization. - #. Create a dictionary ``w`` of non-negative integer variables ``w`` via ``w = + #. Create a dictionary ``w`` of nonnegative integer variables ``w`` via ``w = p.new_variable(integer=True, nonnegative=True)``. #. Add those three equations as equality constraints via :meth:`add_constraint `. @@ -64,7 +64,7 @@ A mixed integer linear program can give you an answer: The following example shows all these steps:: - sage: p = MixedIntegerLinearProgram(maximization=False, solver="GLPK") + sage: p = MixedIntegerLinearProgram(maximization=False, solver='GLPK') sage: w = p.new_variable(integer=True, nonnegative=True) sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0) sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0) @@ -183,37 +183,37 @@ also implements the :class:`MIPSolverException` exception, as well as the :widths: 30, 70 :delim: | - :meth:`~MixedIntegerLinearProgram.add_constraint` | Adds a constraint to the ``MixedIntegerLinearProgram`` + :meth:`~MixedIntegerLinearProgram.add_constraint` | Add a constraint to the ``MixedIntegerLinearProgram`` :meth:`~MixedIntegerLinearProgram.base_ring` | Return the base ring :meth:`~MixedIntegerLinearProgram.best_known_objective_bound`| Return the value of the currently best known bound - :meth:`~MixedIntegerLinearProgram.constraints` | Returns a list of constraints, as 3-tuples - :meth:`~MixedIntegerLinearProgram.default_variable` | Return the default ``MIPVariable`` of `self`. - :meth:`~MixedIntegerLinearProgram.get_backend` | Returns the backend instance used - :meth:`~MixedIntegerLinearProgram.get_max` | Returns the maximum value of a variable - :meth:`~MixedIntegerLinearProgram.get_min` | Returns the minimum value of a variable + :meth:`~MixedIntegerLinearProgram.constraints` | Return a list of constraints, as 3-tuples + :meth:`~MixedIntegerLinearProgram.default_variable` | Return the default ``MIPVariable`` of ``self``. + :meth:`~MixedIntegerLinearProgram.get_backend` | Return the backend instance used + :meth:`~MixedIntegerLinearProgram.get_max` | Return the maximum value of a variable + :meth:`~MixedIntegerLinearProgram.get_min` | Return the minimum value of a variable :meth:`~MixedIntegerLinearProgram.get_objective_value` | Return the value of the objective function :meth:`~MixedIntegerLinearProgram.get_relative_objective_gap`| Return the relative objective gap of the best known solution :meth:`~MixedIntegerLinearProgram.get_values` | Return values found by the previous call to ``solve()`` - :meth:`~MixedIntegerLinearProgram.is_binary` | Tests whether the variable ``e`` is binary - :meth:`~MixedIntegerLinearProgram.is_integer` | Tests whether the variable is an integer - :meth:`~MixedIntegerLinearProgram.is_real` | Tests whether the variable is real + :meth:`~MixedIntegerLinearProgram.is_binary` | Test whether the variable ``e`` is binary + :meth:`~MixedIntegerLinearProgram.is_integer` | Test whether the variable is an integer + :meth:`~MixedIntegerLinearProgram.is_real` | Test whether the variable is real :meth:`~MixedIntegerLinearProgram.linear_constraints_parent` | Return the parent for all linear constraints :meth:`~MixedIntegerLinearProgram.linear_functions_parent` | Return the parent for all linear functions - :meth:`~MixedIntegerLinearProgram.new_variable` | Returns an instance of ``MIPVariable`` associated - :meth:`~MixedIntegerLinearProgram.number_of_constraints` | Returns the number of constraints assigned so far - :meth:`~MixedIntegerLinearProgram.number_of_variables` | Returns the number of variables used so far - :meth:`~MixedIntegerLinearProgram.polyhedron` | Returns the polyhedron defined by the Linear Program - :meth:`~MixedIntegerLinearProgram.remove_constraint` | Removes a constraint from self + :meth:`~MixedIntegerLinearProgram.new_variable` | Return an instance of ``MIPVariable`` associated + :meth:`~MixedIntegerLinearProgram.number_of_constraints` | Return the number of constraints assigned so far + :meth:`~MixedIntegerLinearProgram.number_of_variables` | Return the number of variables used so far + :meth:`~MixedIntegerLinearProgram.polyhedron` | Return the polyhedron defined by the Linear Program + :meth:`~MixedIntegerLinearProgram.remove_constraint` | Remove a constraint from self :meth:`~MixedIntegerLinearProgram.remove_constraints` | Remove several constraints - :meth:`~MixedIntegerLinearProgram.set_binary` | Sets a variable or a ``MIPVariable`` as binary - :meth:`~MixedIntegerLinearProgram.set_integer` | Sets a variable or a ``MIPVariable`` as integer - :meth:`~MixedIntegerLinearProgram.set_max` | Sets the maximum value of a variable - :meth:`~MixedIntegerLinearProgram.set_min` | Sets the minimum value of a variable - :meth:`~MixedIntegerLinearProgram.set_objective` | Sets the objective of the ``MixedIntegerLinearProgram`` - :meth:`~MixedIntegerLinearProgram.set_problem_name` | Sets the name of the ``MixedIntegerLinearProgram`` - :meth:`~MixedIntegerLinearProgram.set_real` | Sets a variable or a ``MIPVariable`` as real - :meth:`~MixedIntegerLinearProgram.show` | Displays the ``MixedIntegerLinearProgram`` in a human-readable - :meth:`~MixedIntegerLinearProgram.solve` | Solves the ``MixedIntegerLinearProgram`` + :meth:`~MixedIntegerLinearProgram.set_binary` | Set a variable or a ``MIPVariable`` as binary + :meth:`~MixedIntegerLinearProgram.set_integer` | Set a variable or a ``MIPVariable`` as integer + :meth:`~MixedIntegerLinearProgram.set_max` | Set the maximum value of a variable + :meth:`~MixedIntegerLinearProgram.set_min` | Set the minimum value of a variable + :meth:`~MixedIntegerLinearProgram.set_objective` | Set the objective of the ``MixedIntegerLinearProgram`` + :meth:`~MixedIntegerLinearProgram.set_problem_name` | Set the name of the ``MixedIntegerLinearProgram`` + :meth:`~MixedIntegerLinearProgram.set_real` | Set a variable or a ``MIPVariable`` as real + :meth:`~MixedIntegerLinearProgram.show` | Display the ``MixedIntegerLinearProgram`` in a human-readable + :meth:`~MixedIntegerLinearProgram.solve` | Solve the ``MixedIntegerLinearProgram`` :meth:`~MixedIntegerLinearProgram.solver_parameter` | Return or define a solver parameter :meth:`~MixedIntegerLinearProgram.sum` | Efficiently computes the sum of a sequence of LinearFunction elements :meth:`~MixedIntegerLinearProgram.write_lp` | Write the linear program as a LP file @@ -260,26 +260,26 @@ cdef class MixedIntegerLinearProgram(SageObject): for more information and installation instructions for optional solvers. - - ``solver="GLPK"``: The `GNU Linear Programming Kit + - ``solver="GLPK"``: the `GNU Linear Programming Kit `_. - ``solver="GLPK/exact"``: GLPK's implementation of an exact rational simplex method. - - ``solver="Coin"``: The `COIN-OR CBC (COIN Branch and Cut) solver + - ``solver="Coin"``: the `COIN-OR CBC (COIN Branch and Cut) solver `_. - - ``solver="CPLEX"``, provided by the proprietary `IBM ILOG CPLEX + - ``solver="CPLEX"``: provided by the proprietary `IBM ILOG CPLEX Optimization Studio `_. - - ``solver="Gurobi"``: The proprietary `Gurobi solver `_. + - ``solver="Gurobi"``: the proprietary `Gurobi solver `_. - - ``solver="CVXOPT"``: See the `CVXOPT `_ web site. + - ``solver="CVXOPT"``: see the `CVXOPT `_ web site. - - ``solver="PPL"``: An exact rational solver (for small scale instances) + - ``solver="PPL"``: an exact rational solver (for small scale instances) provided by the `Parma Polyhedra Library (PPL) `_. - - ``solver="InteractiveLP"``: A didactical + - ``solver="InteractiveLP"``: a didactical implementation of the revised simplex method in Sage. It works over any exact ordered field, the default is ``QQ``. @@ -298,7 +298,7 @@ cdef class MixedIntegerLinearProgram(SageObject): - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as a minimization. - - ``constraint_generation`` -- Only used when ``solver=None``. + - ``constraint_generation`` -- only used when ``solver=None`` - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, it is possible to add a constraint, and then solve it again. @@ -309,7 +309,7 @@ cdef class MixedIntegerLinearProgram(SageObject): .. SEEALSO:: - - :func:`default_mip_solver` -- Returns/Sets the default MIP solver. + - :func:`default_mip_solver` -- returns/sets the default MIP solver EXAMPLES: @@ -358,14 +358,14 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``solver`` -- one of the following: - a string indicating one of the available solvers - (see :class:`MixedIntegerLinearProgram`); + (see :class:`MixedIntegerLinearProgram`) - - ``None`` (default), the default solver is used, see - :func:`default_mip_solver`. + - ``None`` -- (default) the default solver is used, see + :func:`default_mip_solver` - or a callable (such as a class), see :func:`sage.numerical.backends.generic_backend.get_solver` - for examples. + for examples - ``maximization`` @@ -374,7 +374,7 @@ cdef class MixedIntegerLinearProgram(SageObject): - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as a minimization. - - ``constraint_generation`` -- Only used when ``solver=None``. + - ``constraint_generation`` -- only used when ``solver=None``: - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, it is possible to add a constraint, @@ -397,7 +397,7 @@ cdef class MixedIntegerLinearProgram(SageObject): .. SEEALSO:: - - :meth:`default_mip_solver` -- Returns/Sets the default MIP solver. + - :meth:`default_mip_solver` -- returns/sets the default MIP solver EXAMPLES:: @@ -452,7 +452,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def linear_functions_parent(self): """ - Return the parent for all linear functions + Return the parent for all linear functions. EXAMPLES:: @@ -468,7 +468,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def linear_constraints_parent(self): """ - Return the parent for all linear constraints + Return the parent for all linear constraints. See :mod:`~sage.numerical.linear_functions` for more details. @@ -551,7 +551,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def __copy__(self): r""" - Returns a copy of the current ``MixedIntegerLinearProgram`` instance. + Return a copy of the current ``MixedIntegerLinearProgram`` instance. EXAMPLES:: @@ -620,13 +620,12 @@ cdef class MixedIntegerLinearProgram(SageObject): False sage: dcll[0] is dcll[1] True - """ return self.__copy__() def __getitem__(self, v): r""" - Returns the symbolic variable corresponding to the key + Return the symbolic variable corresponding to the key from the default :class:`MIPVariable` instance. It returns the element asked, creating it if necessary. @@ -648,9 +647,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ Return the base ring. - OUTPUT: - - A ring. The coefficients that the chosen solver supports. + OUTPUT: a ring. The coefficients that the chosen solver supports EXAMPLES:: @@ -675,12 +672,12 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_problem_name(self,name): r""" - Sets the name of the ``MixedIntegerLinearProgram``. + Set the name of the ``MixedIntegerLinearProgram``. INPUT: - - ``name`` -- A string representing the name of the - ``MixedIntegerLinearProgram``. + - ``name`` -- string representing the name of the + ``MixedIntegerLinearProgram`` EXAMPLES:: @@ -691,7 +688,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ self._backend.problem_name(name) - def new_variable(self, real=False, binary=False, integer=False, nonnegative=False, name="", + def new_variable(self, real=False, binary=False, integer=False, nonnegative=False, name='', indices=None): r""" Return a new :class:`MIPVariable` instance. @@ -708,10 +705,10 @@ cdef class MixedIntegerLinearProgram(SageObject): .. SEEALSO:: - :meth:`set_min`, :meth:`get_min` -- set/get the lower bound of a - variable. + variable - :meth:`set_max`, :meth:`get_max` -- set/get the upper bound of a - variable. + variable INPUT: @@ -719,21 +716,21 @@ cdef class MixedIntegerLinearProgram(SageObject): arguments to ``True`` to ensure that the variable gets the corresponding type. - - ``nonnegative`` -- boolean, default ``False``. Whether the + - ``nonnegative`` -- boolean (default: ``False``); whether the variable should be assumed to be nonnegative. Rather useless - for the binary type. + for the binary type - - ``name`` -- string. Associates a name to the variable. This + - ``name`` -- string; associates a name to the variable. This is only useful when exporting the linear program to a file using ``write_mps`` or ``write_lp``, and has no other effect. - ``indices`` -- (optional) an iterable of keys; components - corresponding to these keys are created in order, - and access to components with other keys will raise an - error; otherwise components of this variable can be - indexed by arbitrary keys and are created dynamically - on access + corresponding to these keys are created in order, + and access to components with other keys will raise an + error; otherwise components of this variable can be + indexed by arbitrary keys and are created dynamically + on access OUTPUT: @@ -829,7 +826,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def default_variable(self): """ - Return the default :class:`MIPVariable` of `self`. + Return the default :class:`MIPVariable` of ``self``. EXAMPLES:: @@ -850,7 +847,7 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - - ``n`` -- integer. The number of variables to construct. + - ``n`` -- integer; the number of variables to construct OUTPUT: @@ -888,7 +885,7 @@ cdef class MixedIntegerLinearProgram(SageObject): cpdef int number_of_variables(self) noexcept: r""" - Returns the number of variables used so far. + Return the number of variables used so far. Note that this is backend-dependent, i.e. we count solver's variables rather than user's variables. An example of the latter @@ -906,11 +903,11 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: p.add_constraint(p[0] - 2*p[1], min=1) sage: p.number_of_variables() 3 - sage: p = MixedIntegerLinearProgram(solver="glpk") + sage: p = MixedIntegerLinearProgram(solver='glpk') sage: p.add_constraint(p[0] - p[2], min=1, max=4) sage: p.number_of_variables() 2 - sage: p = MixedIntegerLinearProgram(solver="gurobi") # optional - Gurobi + sage: p = MixedIntegerLinearProgram(solver='gurobi') # optional - Gurobi sage: p.add_constraint(p[0] - p[2], min=1, max=4) # optional - Gurobi sage: p.number_of_variables() # optional - Gurobi 3 @@ -919,7 +916,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def constraints(self, indices = None): r""" - Returns a list of constraints, as 3-tuples. + Return a list of constraints, as 3-tuples. INPUT: @@ -981,7 +978,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Running the examples from above, reordering applied:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.add_constraint(p[0] - p[2], min=1, max=4) sage: p.add_constraint(p[0] - 2*p[1], min=1) sage: sorted(reorder_constraint(*c) for c in p.constraints()) @@ -1021,7 +1018,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def polyhedron(self, **kwds): r""" - Returns the polyhedron defined by the Linear Program. + Return the polyhedron defined by the Linear Program. INPUT: @@ -1185,10 +1182,10 @@ cdef class MixedIntegerLinearProgram(SageObject): When constraints and variables have names :: - sage: p = MixedIntegerLinearProgram(solver="GLPK") - sage: x = p.new_variable(name="Hey") + sage: p = MixedIntegerLinearProgram(solver='GLPK') + sage: x = p.new_variable(name='Hey') sage: p.set_objective(x[1] + x[2]) - sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name="Constraint_1") + sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name='Constraint_1') sage: p.show() Maximization: Hey[1] + Hey[2] @@ -1200,7 +1197,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Without any names :: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.set_objective(x[1] + x[2]) sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) @@ -1321,22 +1318,22 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - - ``filename`` -- The file in which you want the problem - to be written. + - ``filename`` -- the file in which you want the problem + to be written - - ``modern`` -- Lets you choose between Fixed MPS and Free MPS + - ``modern`` -- lets you choose between Fixed MPS and Free MPS: - - ``True`` -- Outputs the problem in Free MPS - - ``False`` -- Outputs the problem in Fixed MPS + - ``True`` -- outputs the problem in Free MPS + - ``False`` -- outputs the problem in Fixed MPS EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.set_objective(x[1] + x[2]) - sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name="OneConstraint") + sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name='OneConstraint') sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".mps") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.mps') as f: ....: p.write_mps(f.name) Writing problem data to ... 17 records were written @@ -1354,17 +1351,17 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - - ``filename`` -- The file in which you want the problem - to be written. + - ``filename`` -- the file in which you want the problem + to be written EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: p.set_objective(x[1] + x[2]) sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".lp") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.lp') as f: ....: p.write_lp(f.name) Writing problem data to ... 9 lines were written @@ -1404,7 +1401,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Return the value of a variable component in the backend as an integer. The value is rounded to an integer, and if the difference to the - original value is greater than ``tolerance``, raise a ``RuntimeError``. + original value is greater than ``tolerance``, raise a :exc:`RuntimeError`. INPUT: @@ -1412,9 +1409,7 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``tolerance`` -- a nonnegative real number - OUTPUT: - - An element of ``ZZ``. + OUTPUT: an element of ``ZZ`` EXAMPLES:: @@ -1449,10 +1444,10 @@ cdef class MixedIntegerLinearProgram(SageObject): Return the value of a variable component in the backend as a boolean. The value is rounded to an integer, and if the difference to the - original value is greater than ``tolerance``, raise a ``RuntimeError``. + original value is greater than ``tolerance``, raise a :exc:`RuntimeError`. If the rounded value is anything other than 0 or 1, also a - ``RuntimeError`` is raised. + :exc:`RuntimeError` is raised. INPUT: @@ -1460,9 +1455,7 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``tolerance`` -- a nonnegative real number - OUTPUT: - - A ``bool``. + OUTPUT: a ``bool`` EXAMPLES:: @@ -1533,9 +1526,9 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - ``*lists`` -- any instance of ``MIPVariable`` (or one of its - elements), or lists of them. + elements), or lists of them - - ``convert`` -- ``None`` (default), ``ZZ``, ``bool``, or ``True``. + - ``convert`` -- (default: ``None``) ``ZZ``, ``bool``, or ``True``: - if ``convert=None`` (default), return all variable values as the backend provides them, i.e., as an element of :meth:`base_ring` or a @@ -1555,7 +1548,7 @@ cdef class MixedIntegerLinearProgram(SageObject): :meth:`base_ring` is an exact ring). Required if ``convert`` is not ``None`` and any integer conversion is to be done. If the variable value differs from the nearest integer by more than ``tolerance``, - raise a ``RuntimeError``. + raise a :exc:`RuntimeError`. OUTPUT: @@ -1761,7 +1754,7 @@ cdef class MixedIntegerLinearProgram(SageObject): elif convert is True: get_backend_variable_value = self._backend_variable_value_True else: - raise ValueError('convert should be one of None, ZZ, bool, True') + raise ValueError('convert should be one of None, ZZ, boolean, True') val = [] for l in lists: @@ -1791,11 +1784,11 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_objective(self,obj): r""" - Sets the objective of the ``MixedIntegerLinearProgram``. + Set the objective of the ``MixedIntegerLinearProgram``. INPUT: - - ``obj`` -- A linear function to be optimized. + - ``obj`` -- a linear function to be optimized ( can also be set to ``None`` or ``0`` or any number when just looking for a feasible solution ) @@ -1833,7 +1826,6 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: p.set_objective(42) sage: p.solve() # tol 1e-8 42 - """ cdef list values = [] @@ -1844,7 +1836,7 @@ cdef class MixedIntegerLinearProgram(SageObject): cdef int i if obj is None: - f = {-1 : 0} + f = {-1: 0} else: # See if it is a constant R = self.base_ring() @@ -1862,11 +1854,11 @@ cdef class MixedIntegerLinearProgram(SageObject): def add_constraint(self, linear_function, max=None, min=None, name=None, return_indices=False): r""" - Adds a constraint to the ``MixedIntegerLinearProgram``. + Add a constraint to the ``MixedIntegerLinearProgram``. INPUT: - - ``linear_function`` -- Four different types of arguments are + - ``linear_function`` -- four different types of arguments are admissible: - A linear function. In this case, one of the arguments @@ -1897,10 +1889,10 @@ cdef class MixedIntegerLinearProgram(SageObject): linear functions. Not allowed if the ``linear_function`` argument is a symbolic (in)-equality. - - ``name`` -- A name for the constraint. + - ``name`` -- a name for the constraint - ``return_indices`` -- boolean (default: ``False``), - whether to return the indices of the added constraints. + whether to return the indices of the added constraints OUTPUT: @@ -2007,7 +1999,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Complex constraints:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: b = p.new_variable(nonnegative=True) sage: p.add_constraint(b[8] - b[15] <= 3*b[8] + 9) sage: p.show() @@ -2049,7 +2041,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Do not add redundant elements (notice only one copy of each constraint is added):: - sage: lp = MixedIntegerLinearProgram(solver="GLPK", check_redundant=True) + sage: lp = MixedIntegerLinearProgram(solver='GLPK', check_redundant=True) sage: for each in range(10): ....: lp.add_constraint(lp[0]-lp[1], min=1) sage: lp.show() @@ -2225,15 +2217,13 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - - ``constraint`` -- dictionary of a non-zero linear function - without constant term. + - ``constraint`` -- dictionary of a nonzero linear function + without constant term - ``min_bound``, ``max_bound`` -- base ring elements or - ``None``. The lower and upper bound. - - OUTPUT: + ``None``; the lower and upper bound - Boolean. Whether the (normalized) constraint has already been added. + OUTPUT: boolean; whether the (normalized) constraint has already been added EXAMPLES:: @@ -2266,11 +2256,11 @@ cdef class MixedIntegerLinearProgram(SageObject): def remove_constraint(self, int i): r""" - Removes a constraint from self. + Removes a constraint from ``self``. INPUT: - - ``i`` -- Index of the constraint to remove. + - ``i`` -- index of the constraint to remove EXAMPLES:: @@ -2308,7 +2298,7 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - - ``constraints`` -- an iterable containing the indices of the rows to remove. + - ``constraints`` -- an iterable containing the indices of the rows to remove EXAMPLES:: @@ -2371,7 +2361,6 @@ cdef class MixedIntegerLinearProgram(SageObject): :issue:`34881`:: sage: MixedIntegerLinearProgram().remove_constraints([]) - """ if self._check_redundant: for i in sorted(constraints, reverse=True): @@ -2381,12 +2370,12 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_binary(self, ee): r""" - Sets a variable or a ``MIPVariable`` as binary. + Set a variable or a ``MIPVariable`` as binary. INPUT: - - ``ee`` -- An instance of ``MIPVariable`` or one of - its elements. + - ``ee`` -- an instance of ``MIPVariable`` or one of + its elements EXAMPLES:: @@ -2404,7 +2393,6 @@ cdef class MixedIntegerLinearProgram(SageObject): variables as integer while keeping the others as they are:: sage: p.set_integer(x[3]) - """ cdef MIPVariable e e = ee @@ -2420,16 +2408,14 @@ cdef class MixedIntegerLinearProgram(SageObject): def is_binary(self, e): r""" - Tests whether the variable ``e`` is binary. Variables are real by + Test whether the variable ``e`` is binary. Variables are real by default. INPUT: - - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.) - - OUTPUT: + - ``e`` -- a variable (not a ``MIPVariable``, but one of its elements) - ``True`` if the variable ``e`` is binary; ``False`` otherwise. + OUTPUT: ``True`` if the variable ``e`` is binary; ``False`` otherwise EXAMPLES:: @@ -2446,12 +2432,12 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_integer(self, ee): r""" - Sets a variable or a ``MIPVariable`` as integer. + Set a variable or a ``MIPVariable`` as integer. INPUT: - - ``ee`` -- An instance of ``MIPVariable`` or one of - its elements. + - ``ee`` -- an instance of ``MIPVariable`` or one of + its elements EXAMPLES:: @@ -2484,16 +2470,14 @@ cdef class MixedIntegerLinearProgram(SageObject): def is_integer(self, e): r""" - Tests whether the variable is an integer. Variables are real by + Test whether the variable is an integer. Variables are real by default. INPUT: - - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.) + - ``e`` -- a variable (not a ``MIPVariable``, but one of its elements) - OUTPUT: - - ``True`` if the variable ``e`` is an integer; ``False`` otherwise. + OUTPUT: ``True`` if the variable ``e`` is an integer; ``False`` otherwise EXAMPLES:: @@ -2510,12 +2494,12 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_real(self,ee): r""" - Sets a variable or a ``MIPVariable`` as real. + Set a variable or a ``MIPVariable`` as real. INPUT: - - ``ee`` -- An instance of ``MIPVariable`` or one of - its elements. + - ``ee`` -- an instance of ``MIPVariable`` or one of + its elements EXAMPLES:: @@ -2533,7 +2517,6 @@ cdef class MixedIntegerLinearProgram(SageObject): variables as binary while keeping the others as they are:: sage: p.set_binary(x[3]) - """ cdef MIPVariable e e = ee @@ -2551,15 +2534,13 @@ cdef class MixedIntegerLinearProgram(SageObject): def is_real(self, e): r""" - Tests whether the variable is real. + Test whether the variable is real. INPUT: - - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.) - - OUTPUT: + - ``e`` -- a variable (not a ``MIPVariable``, but one of its elements) - ``True`` if the variable is real; ``False`` otherwise. + OUTPUT: ``True`` if the variable is real; ``False`` otherwise EXAMPLES:: @@ -2579,23 +2560,21 @@ cdef class MixedIntegerLinearProgram(SageObject): def solve(self, log=None, objective_only=False): r""" - Solves the ``MixedIntegerLinearProgram``. + Solve the ``MixedIntegerLinearProgram``. INPUT: - - ``log`` -- integer (default: ``None``) The verbosity level. Indicates + - ``log`` -- integer (default: ``None``); the verbosity level. Indicates whether progress should be printed during computation. The solver is initialized to report no progress. - - ``objective_only`` -- Boolean variable. + - ``objective_only`` -- boolean: - When set to ``True``, only the objective function is returned. - When set to ``False`` (default), the optimal numerical values are stored (takes computational time). - OUTPUT: - - The optimal value taken by the objective function. + OUTPUT: the optimal value taken by the objective function .. WARNING:: @@ -2661,18 +2640,18 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_min(self, v, min): r""" - Sets the minimum value of a variable. + Set the minimum value of a variable. INPUT: - - ``v`` -- a variable. + - ``v`` -- a variable - - ``min`` -- the minimum value the variable can take. When - ``min=None``, the variable has no lower bound. + - ``min`` -- the minimum value the variable can take; when + ``min=None``, the variable has no lower bound .. SEEALSO:: - - :meth:`get_min` -- get the minimum value of a variable. + - :meth:`get_min` -- get the minimum value of a variable EXAMPLES:: @@ -2705,14 +2684,14 @@ cdef class MixedIntegerLinearProgram(SageObject): def set_max(self, v, max): r""" - Sets the maximum value of a variable. + Set the maximum value of a variable. INPUT: - - ``v`` -- a variable. + - ``v`` -- a variable - - ``max`` -- the maximum value the variable can take. When - ``max=None``, the variable has no upper bound. + - ``max`` -- the maximum value the variable can take; when + ``max=None``, the variable has no upper bound EXAMPLES:: @@ -2742,7 +2721,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def get_min(self, v): r""" - Returns the minimum value of a variable. + Return the minimum value of a variable. INPUT: @@ -2773,11 +2752,11 @@ cdef class MixedIntegerLinearProgram(SageObject): def get_max(self, v): r""" - Returns the maximum value of a variable. + Return the maximum value of a variable. INPUT: - - ``v`` -- a variable. + - ``v`` -- a variable OUTPUT: @@ -2801,7 +2780,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def solver_parameter(self, name, value = None): """ - Return or define a solver parameter + Return or define a solver parameter. The solver parameters are by essence solver-specific, which means their meaning heavily depends on the solver used. @@ -2813,22 +2792,22 @@ cdef class MixedIntegerLinearProgram(SageObject): Very common parameters have aliases making them solver-independent. For example, the following:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("timelimit", 60) Sets the solver to stop its computations after 60 seconds, and works with GLPK, CPLEX , SCIP, and Gurobi. - - ``"timelimit"`` -- defines the maximum time spent on a - computation. Measured in seconds. + - ``'timelimit'`` -- defines the maximum time spent on a + computation (measured in seconds) - Another example is the ``"logfile"`` parameter, which is used to specify + Another example is the ``'logfile'`` parameter, which is used to specify the file in which computation logs are recorded. By default, the logs are not recorded, and we can disable this feature providing an empty filename. This is currently working with CPLEX and Gurobi:: sage: # optional - cplex - sage: p = MixedIntegerLinearProgram(solver="CPLEX") + sage: p = MixedIntegerLinearProgram(solver='CPLEX') sage: p.solver_parameter("logfile") '' sage: p.solver_parameter("logfile", "/dev/null") @@ -2852,7 +2831,7 @@ cdef class MixedIntegerLinearProgram(SageObject): The command :: - sage: p = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX + sage: p = MixedIntegerLinearProgram(solver='CPLEX') # optional - CPLEX sage: p.solver_parameter("CPX_PARAM_TILIM", 60) # optional - CPLEX works as intended. @@ -2866,14 +2845,14 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("timelimit", 60) sage: p.solver_parameter("timelimit") 60.0 @@ -2885,15 +2864,15 @@ cdef class MixedIntegerLinearProgram(SageObject): cpdef sum(self, L): r""" - Efficiently computes the sum of a sequence of + Efficiently compute the sum of a sequence of :class:`~sage.numerical.linear_functions.LinearFunction` elements INPUT: - - ``mip`` -- the :class:`MixedIntegerLinearProgram` parent. + - ``mip`` -- the :class:`MixedIntegerLinearProgram` parent - ``L`` -- list of - :class:`~sage.numerical.linear_functions.LinearFunction` instances. + :class:`~sage.numerical.linear_functions.LinearFunction` instances .. NOTE:: @@ -2921,7 +2900,7 @@ cdef class MixedIntegerLinearProgram(SageObject): def get_backend(self): r""" - Returns the backend instance used. + Return the backend instance used. This might be useful when access to additional functions provided by the backend is needed. @@ -2930,7 +2909,7 @@ cdef class MixedIntegerLinearProgram(SageObject): This example uses the simplex algorithm and prints information:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: x, y = p[0], p[1] sage: p.add_constraint(2*x + 3*y, max=6) sage: p.add_constraint(3*x + 2*y, max=6) @@ -2959,7 +2938,7 @@ cdef class MixedIntegerLinearProgram(SageObject): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: x, y = p[0], p[1] sage: p.add_constraint(2*x + 3*y, max=6) sage: p.add_constraint(3*x + 2*y, max=6) @@ -2990,7 +2969,7 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("mip_gap_tolerance",100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -3025,7 +3004,7 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.solver_parameter("mip_gap_tolerance",100) sage: b = p.new_variable(binary=True) sage: p.set_objective(p.sum(b[v] for v in g)) @@ -3049,12 +3028,12 @@ cdef class MixedIntegerLinearProgram(SageObject): def interactive_lp_problem(self,form='standard'): r""" - Returns an InteractiveLPProblem and, if available, a basis. + Return an InteractiveLPProblem and, if available, a basis. INPUT: - - ``form`` -- (default: ``"standard"``) a string specifying return type: either - ``None``, or ``"std"`` or ``"standard"``, respectively returns an instance of + - ``form`` -- (default: ``'standard'``) a string specifying return type: either + ``None``, or ``'std'`` or ``'standard'``, respectively returns an instance of :class:`InteractiveLPProblem` or of :class:`InteractiveLPProblemStandardForm` OUTPUT: @@ -3068,7 +3047,7 @@ cdef class MixedIntegerLinearProgram(SageObject): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(names=['m'], solver="GLPK") + sage: p = MixedIntegerLinearProgram(names=['m'], solver='GLPK') sage: x = p.new_variable(nonnegative=True) sage: y = p.new_variable(nonnegative=True, name='n') sage: v = p.new_variable(nonnegative=True) @@ -3205,7 +3184,7 @@ class MIPSolverException(RuntimeError): No continuous solution:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: v = p.new_variable(nonnegative=True) sage: p.add_constraint(v[0], max=5.5) sage: p.add_constraint(v[0], min=7.6) @@ -3220,7 +3199,7 @@ class MIPSolverException(RuntimeError): No integer solution:: - sage: p = MixedIntegerLinearProgram(solver="GLPK") + sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: v = p.new_variable(nonnegative=True) sage: p.add_constraint(v[0], max=5.6) sage: p.add_constraint(v[0], min=5.2) @@ -3247,34 +3226,34 @@ cdef class MIPVariable(FiniteFamily): You should not instantiate this class directly. Instead, use :meth:`MixedIntegerLinearProgram.new_variable`. """ - def __init__(self, mip, vtype, name="", lower_bound=0, upper_bound=None, + def __init__(self, mip, vtype, name='', lower_bound=0, upper_bound=None, indices=None): r""" Constructor for ``MIPVariable``. INPUT: - - ``parent`` -- :class:`MIPVariableParent`. The parent of the - MIP variable. + - ``parent`` -- :class:`MIPVariableParent`; the parent of the + MIP variable - - ``mip`` -- :class:`MixedIntegerLinearProgram`. The - underlying linear program. + - ``mip`` -- :class:`MixedIntegerLinearProgram`; the + underlying linear program - - ``vtype`` (integer) -- Defines the type of the variables - (default is ``REAL``, i.e., ``vtype=-1``). + - ``vtype`` -- integer; defines the type of the variables + (default: ``REAL``, i.e., ``vtype=-1``) - - ``name`` -- A name for the ``MIPVariable``. + - ``name`` -- a name for the ``MIPVariable`` - ``lower_bound``, ``upper_bound`` -- lower bound and upper bound on the variable. Set to ``None`` to indicate that the variable is unbounded. - ``indices`` -- (optional) an iterable of keys; components - corresponding to these keys are created in order, - and access to components with other keys will raise an - error; otherwise components of this variable can be - indexed by arbitrary keys and are created dynamically - on access + corresponding to these keys are created in order, + and access to components with other keys will raise an + error; otherwise components of this variable can be + indexed by arbitrary keys and are created dynamically + on access For more information, see the method ``MixedIntegerLinearProgram.new_variable``. @@ -3284,7 +3263,6 @@ cdef class MIPVariable(FiniteFamily): sage: p = MixedIntegerLinearProgram(solver='GLPK') sage: p.new_variable(nonnegative=True) MIPVariable with 0 real components, >= 0 - """ super().__init__({}) self._p = mip @@ -3299,7 +3277,7 @@ cdef class MIPVariable(FiniteFamily): def __copy__(self): r""" - Returns a copy of ``self``. + Return a copy of ``self``. EXAMPLES:: @@ -3321,7 +3299,7 @@ cdef class MIPVariable(FiniteFamily): def __deepcopy__(self, memo={}): r""" - Returns a copy of ``self``. + Return a copy of ``self``. EXAMPLES:: @@ -3343,7 +3321,7 @@ cdef class MIPVariable(FiniteFamily): def __getitem__(self, i): r""" - Returns the variable component corresponding to the key. + Return the variable component corresponding to the key. Returns the component asked. @@ -3394,7 +3372,6 @@ cdef class MIPVariable(FiniteFamily): Traceback (most recent call last): ... IndexError: 0 does not index a component of MIPVariable with 0 real components - """ cdef int j if i in self._dictionary: @@ -3412,14 +3389,14 @@ cdef class MIPVariable(FiniteFamily): integer=(self._vtype == self._p.__INTEGER), obj=zero, name=name) - v = self._p.linear_functions_parent()({j : 1}) + v = self._p.linear_functions_parent()({j: 1}) self._p._variables[v] = j self._dictionary[i] = v return v def copy_for_mip(self, mip): r""" - Returns a copy of ``self`` suitable for a new :class:`MixedIntegerLinearProgram` + Return a copy of ``self`` suitable for a new :class:`MixedIntegerLinearProgram` instance ``mip``. For this to make sense, ``mip`` should have been obtained as a copy of @@ -3456,7 +3433,6 @@ cdef class MIPVariable(FiniteFamily): Traceback (most recent call last): ... IndexError: 5 does not index a component of MIPVariable with 2 real components - """ cdef MIPVariable cp = type(self)(mip, self._vtype, self._name, self._lower_bound, self._upper_bound) @@ -3466,12 +3442,12 @@ cdef class MIPVariable(FiniteFamily): def set_min(self, min): r""" - Sets a lower bound on the variable. + Set a lower bound on the variable. INPUT: - ``min`` -- a lower bound, or ``None`` to mean that the variable is - unbounded. + unbounded EXAMPLES:: @@ -3497,7 +3473,6 @@ cdef class MIPVariable(FiniteFamily): sage: x.set_min(42) sage: p.get_min(y[0]) is None True - """ self._lower_bound = min for v in self._dictionary.values(): @@ -3505,12 +3480,12 @@ cdef class MIPVariable(FiniteFamily): def set_max(self, max): r""" - Sets an upper bound on the variable. + Set an upper bound on the variable. INPUT: - ``max`` -- an upper bound, or ``None`` to mean that the variable is - unbounded. + unbounded EXAMPLES:: @@ -3541,7 +3516,7 @@ cdef class MIPVariable(FiniteFamily): def _repr_(self): r""" - Returns a representation of self. + Return a representation of ``self``. EXAMPLES:: @@ -3549,7 +3524,7 @@ cdef class MIPVariable(FiniteFamily): sage: v = p.new_variable() sage: v MIPVariable with 0 real components - sage: x = p.new_variable(integer=True, nonnegative=True, name="x") + sage: x = p.new_variable(integer=True, nonnegative=True, name='x') sage: x[0] x_0 sage: x @@ -3558,12 +3533,12 @@ cdef class MIPVariable(FiniteFamily): x_1 sage: x MIPVariable x with 2 integer components, >= 0 - sage: y = p.new_variable(real=True, name="y", indices=range(5)) + sage: y = p.new_variable(real=True, name='y', indices=range(5)) sage: y.set_min(0) sage: y.set_max(17) sage: y MIPVariable y with 5 real components, >= 0, <= 17 - sage: z = p.new_variable(binary=True, name="z", indices=range(7)) + sage: z = p.new_variable(binary=True, name='z', indices=range(7)) sage: z MIPVariable z with 7 binary components """ @@ -3622,7 +3597,7 @@ cdef class MIPVariable(FiniteFamily): def mip(self): r""" - Returns the :class:`MixedIntegerLinearProgram` in which ``self`` is a variable. + Return the :class:`MixedIntegerLinearProgram` in which ``self`` is a variable. EXAMPLES:: diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index e3d94d1746e..7b3d0456147 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -40,9 +40,8 @@ def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=Fals - ``maxiter`` -- integer; if convergence is not achieved in ``maxiter`` iterations, an error is raised. Must be `\geq 0`. - - ``full_output`` -- bool (default: ``False``), if ``True``, also return - object that contains information about convergence. - + - ``full_output`` -- boolean (default: ``False``); if ``True``, also return + object that contains information about convergence EXAMPLES: @@ -100,7 +99,6 @@ def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=Fals Traceback (most recent call last): ... RuntimeError: f appears to have no zero on the interval - """ try: return f.find_root(a=a,b=b,xtol=xtol,rtol=rtol,maxiter=maxiter,full_output=full_output) @@ -155,6 +153,10 @@ def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=Fals b = max(s_1, s_2) import scipy.optimize + import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") + g = lambda x: float(f(x)) brentqRes = scipy.optimize.brentq(g, a, b, full_output=full_output, xtol=xtol, rtol=rtol, maxiter=maxiter) @@ -215,15 +217,14 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): INPUT: - - ``f`` -- a function of at most one variable. + - ``f`` -- a function of at most one variable - - ``a``, ``b`` -- endpoints of interval on which to minimize `f`. + - ``a``, ``b`` -- endpoints of interval on which to minimize `f` - ``tol`` -- the convergence tolerance - ``maxfun`` -- maximum function evaluations - OUTPUT: - ``minval`` -- (float) the minimum value that `f` takes on in the @@ -231,7 +232,6 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): - ``x`` -- (float) the point at which `f` takes on the minimum value - EXAMPLES:: sage: f = lambda x: x*cos(x) @@ -288,11 +288,15 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): a = float(a) b = float(b) import scipy.optimize + import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") + xmin, fval, iter, funcalls = scipy.optimize.fminbound(f, a, b, full_output=1, xtol=tol, maxfun=maxfun) return fval, xmin -def minimize(func, x0, gradient=None, hessian=None, algorithm="default", +def minimize(func, x0, gradient=None, hessian=None, algorithm='default', verbose=False, **args): r""" This function is an interface to a variety of algorithms for computing @@ -300,24 +304,24 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", INPUT: - - ``func`` -- Either a symbolic function or a Python function whose + - ``func`` -- either a symbolic function or a Python function whose argument is a tuple with `n` components - - ``x0`` -- Initial point for finding minimum. + - ``x0`` -- initial point for finding minimum - - ``gradient`` -- Optional gradient function. This will be computed + - ``gradient`` -- (optional) gradient function. This will be computed automatically for symbolic functions. For Python functions, it allows the use of algorithms requiring derivatives. It should accept a tuple of arguments and return a NumPy array containing the partial derivatives at that point. - - ``hessian`` -- Optional hessian function. This will be computed + - ``hessian`` -- (optional) hessian function. This will be computed automatically for symbolic functions. For Python functions, it allows the use of algorithms requiring derivatives. It should accept a tuple of arguments and return a NumPy array containing the second partial derivatives of the function. - - ``algorithm`` -- String specifying algorithm to use. Options are + - ``algorithm`` -- string specifying algorithm to use. Options are ``'default'`` (for Python functions, the simplex method is the default) (for symbolic functions bfgs is the default): @@ -331,7 +335,7 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", - ``'ncg'`` -- (newton-conjugate gradient) requires gradient and hessian - - ``verbose`` -- (default: ``False``) print convergence message + - ``verbose`` -- boolean (default: ``False``); print convergence message .. NOTE:: @@ -352,12 +356,12 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", Try the newton-conjugate gradient method; the gradient and hessian are computed automatically:: - sage: minimize(f, [.1, .3, .4], algorithm="ncg") # abs tol 1e-6 # needs sage.symbolic + sage: minimize(f, [.1, .3, .4], algorithm='ncg') # abs tol 1e-6 # needs sage.symbolic (1.0, 1.0, 1.0) We get additional convergence information with the `verbose` option:: - sage: minimize(f, [.1, .3, .4], algorithm="ncg", verbose=True) # needs sage.symbolic + sage: minimize(f, [.1, .3, .4], algorithm='ncg', verbose=True) # needs sage.symbolic Optimization terminated successfully. ... (0.9999999..., 0.999999..., 0.999999...) @@ -376,6 +380,8 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", sage: def rosen(x): # The Rosenbrock function ....: return sum(100.0r*(x[1r:]-x[:-1r]**2.0r)**2.0r + (1r-x[:-1r])**2.0r) sage: import numpy + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") sage: from numpy import zeros sage: def rosen_der(x): ....: xm = x[1r:-1r] @@ -387,12 +393,15 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", ....: der[-1] = 200r*(x[-1r]-x[-2r]**2r) ....: return der sage: minimize(rosen, [.1,.3,.4], gradient=rosen_der, # abs tol 1e-6 - ....: algorithm="bfgs") + ....: algorithm='bfgs') (1.0, 1.0, 1.0) """ from sage.structure.element import Expression from sage.ext.fast_callable import fast_callable import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") + from scipy import optimize if isinstance(func, Expression): var_list = func.variables() @@ -400,7 +409,9 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", fast_f = fast_callable(func, vars=var_names, domain=float) f = lambda p: fast_f(*p) gradient_list = func.gradient() - fast_gradient_functions = [fast_callable(gradient_list[i], vars=var_names, domain=float) for i in range(len(gradient_list))] + fast_gradient_functions = [fast_callable(gradient_list[i], + vars=var_names, domain=float) + for i in range(len(gradient_list))] gradient = lambda p: numpy.array([ a(*p) for a in fast_gradient_functions]) else: f = func @@ -435,10 +446,9 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) r""" Minimize a function with constraints. - INPUT: - - ``func`` -- Either a symbolic function, or a Python function whose + - ``func`` -- either a symbolic function, or a Python function whose argument is a tuple with `n` components - ``cons`` -- constraints. This should be either a function or list of @@ -450,20 +460,19 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) of intervals and there are no constraints for a given variable, that component can be (``None``, ``None``). - - ``x0`` -- Initial point for finding minimum + - ``x0`` -- initial point for finding minimum - - ``algorithm`` -- Optional, specify the algorithm to use: + - ``algorithm`` -- (optional) specify the algorithm to use: - - ``'default'`` -- default choices + - ``'default'`` -- default choices - - ``'l-bfgs-b'`` -- only effective if you specify bound constraints. - See [ZBN1997]_. + - ``'l-bfgs-b'`` -- only effective if you specify bound constraints; + see [ZBN1997]_ - - ``gradient`` -- Optional gradient function. This will be computed + - ``gradient`` -- (optional) gradient function. This will be computed automatically for symbolic functions. This is only used when the constraints are specified as a list of intervals. - EXAMPLES: Let us maximize `x + y - 50` subject to the following constraints: @@ -525,11 +534,12 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) sage: c2(y,x) = 1-y sage: minimize_constrained(f, [c1, c2], (0,0)) (1.0, 0.0) - """ from sage.structure.element import Expression from sage.ext.fast_callable import fast_callable import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") from scipy import optimize function_type = type(lambda x,y: x+y) @@ -580,34 +590,33 @@ def find_fit(data, model, initial_guess=None, parameters=None, variables=None, s INPUT: - - ``data`` -- A two dimensional table of floating point numbers of the + - ``data`` -- a two dimensional table of floating point numbers of the form `[[x_{1,1}, x_{1,2}, \ldots, x_{1,k}, f_1], [x_{2,1}, x_{2,2}, \ldots, x_{2,k}, f_2], \ldots, [x_{n,1}, x_{n,2}, \ldots, x_{n,k}, f_n]]` given as either a list of lists, matrix, or numpy array. - - ``model`` -- Either a symbolic expression, symbolic function, or a + - ``model`` -- either a symbolic expression, symbolic function, or a Python function. ``model`` has to be a function of the variables `(x_1, x_2, \ldots, x_k)` and free parameters `(a_1, a_2, \ldots, a_l)`. - - ``initial_guess`` -- (default: ``None``) Initial estimate for the + - ``initial_guess`` -- (default: ``None``) initial estimate for the parameters `(a_1, a_2, \ldots, a_l)`, given as either a list, tuple, vector or numpy array. If ``None``, the default estimate for each parameter is `1`. - - ``parameters`` -- (default: ``None``) A list of the parameters + - ``parameters`` -- (default: ``None``) a list of the parameters `(a_1, a_2, \ldots, a_l)`. If model is a symbolic function it is ignored, and the free parameters of the symbolic function are used. - - ``variables`` -- (default: ``None``) A list of the variables + - ``variables`` -- (default: ``None``) a list of the variables `(x_1, x_2, \ldots, x_k)`. If model is a symbolic function it is ignored, and the variables of the symbolic function are used. - - ``solution_dict`` -- (default: ``False``) if ``True``, return the - solution as a dictionary rather than an equation. - + - ``solution_dict`` -- boolean (default: ``False``); if ``True``, return the + solution as a dictionary rather than an equation EXAMPLES: @@ -652,6 +661,8 @@ def find_fit(data, model, initial_guess=None, parameters=None, variables=None, s ``lmdif`` and ``lmder`` algorithms. """ import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") if not isinstance(data, numpy.ndarray): try: @@ -729,7 +740,7 @@ def error_function(params, x_data, y_data): estimated_params = estimated_params.tolist() if solution_dict: - return {i0: i1 for i0, i1 in zip(parameters, estimated_params)} + return dict(zip(parameters, estimated_params)) return [item[0] == item[1] for item in zip(parameters, estimated_params)] @@ -757,11 +768,11 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, INPUT: - ``items`` -- list or dict; either a list of real values (the items' - weight), or a dictionary associating to each item its weight. + weight), or a dictionary associating to each item its weight - - ``maximum`` -- (default: 1); the maximal size of a bin + - ``maximum`` -- (default: 1) the maximal size of a bin - - ``k`` -- integer (default: ``None``); Number of bins + - ``k`` -- integer (default: ``None``); number of bins: - When set to an integer value, the function returns a partition of the items into `k` bins if possible, and raises an exception otherwise. @@ -769,7 +780,7 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, - When set to ``None``, the function returns a partition of the items using the least possible number of bins. - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -777,11 +788,11 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, of the class :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` OUTPUT: @@ -848,7 +859,7 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, TypeError: parameter items must be a list or a dictionary. """ if isinstance(items, list): - weight = {i:w for i,w in enumerate(items)} + weight = dict(enumerate(items)) elif isinstance(items, dict): weight = items else: diff --git a/src/sage/numerical/sdp.pyx b/src/sage/numerical/sdp.pyx index 7e214ad5023..7c08ed08e10 100644 --- a/src/sage/numerical/sdp.pyx +++ b/src/sage/numerical/sdp.pyx @@ -196,7 +196,7 @@ also implements the :class:`SDPSolverException` exception, as well as the :widths: 30, 70 :delim: | - :meth:`~SemidefiniteProgram.add_constraint` | Adds a constraint to the ``SemidefiniteProgram`` + :meth:`~SemidefiniteProgram.add_constraint` | Add a constraint to the ``SemidefiniteProgram`` :meth:`~SemidefiniteProgram.base_ring` | Return the base ring :meth:`~SemidefiniteProgram.dual_variable` | Return optimal dual variable block :meth:`~SemidefiniteProgram.get_backend` | Return the backend instance used @@ -272,7 +272,7 @@ cdef class SemidefiniteProgram(SageObject): .. SEEALSO:: - - :func:`default_sdp_solver` -- Returns/Sets the default SDP solver. + - :func:`default_sdp_solver` -- returns/sets the default SDP solver EXAMPLES: @@ -323,12 +323,11 @@ cdef class SemidefiniteProgram(SageObject): .. SEEALSO:: - - :meth:`default_sdp_solver` -- Returns/Sets the default SDP solver. + - :meth:`default_sdp_solver` -- returns/Sets the default SDP solver EXAMPLES:: sage: p = SemidefiniteProgram(maximization=True) - """ self._first_variable_names = list(names) from sage.numerical.backends.generic_sdp_backend import get_solver @@ -423,7 +422,7 @@ cdef class SemidefiniteProgram(SageObject): def __getitem__(self, v): r""" - Returns the symbolic variable corresponding to the key + Return the symbolic variable corresponding to the key from a default dictionary. It returns the element asked, and otherwise creates it. @@ -450,9 +449,7 @@ cdef class SemidefiniteProgram(SageObject): """ Return the base ring. - OUTPUT: - - A ring. The coefficients that the chosen solver supports. + OUTPUT: a ring. The coefficients that the chosen solver supports EXAMPLES:: @@ -464,12 +461,12 @@ cdef class SemidefiniteProgram(SageObject): def set_problem_name(self,name): r""" - Sets the name of the ``SemidefiniteProgram``. + Set the name of the ``SemidefiniteProgram``. INPUT: - - ``name`` -- A string representing the name of the - ``SemidefiniteProgram``. + - ``name`` -- string representing the name of the + ``SemidefiniteProgram`` EXAMPLES:: @@ -482,7 +479,7 @@ cdef class SemidefiniteProgram(SageObject): def new_variable(self, name=""): r""" - Returns an instance of :class:`SDPVariable` associated + Return an instance of :class:`SDPVariable` associated to the current instance of :class:`SemidefiniteProgram`. A new variable ``x`` is defined by:: @@ -496,11 +493,11 @@ cdef class SemidefiniteProgram(SageObject): INPUT: - - ``dim`` -- integer. Defines the dimension of the dictionary. + - ``dim`` -- integer; defines the dimension of the dictionary If ``x`` has dimension `2`, its fields will be of the form ``x[key1][key2]``. Deprecated. - - ``name`` -- string. Associates a name to the variable. + - ``name`` -- string; associates a name to the variable EXAMPLES:: @@ -531,7 +528,7 @@ cdef class SemidefiniteProgram(SageObject): INPUT: - - ``n`` -- integer. The number of variables to construct. + - ``n`` -- integer; the number of variables to construct OUTPUT: @@ -592,7 +589,6 @@ cdef class SemidefiniteProgram(SageObject): r""" Return the number of variables used so far. - EXAMPLES:: sage: p = SemidefiniteProgram() @@ -612,7 +608,7 @@ cdef class SemidefiniteProgram(SageObject): When constraints and variables have names :: sage: p = SemidefiniteProgram() - sage: x = p.new_variable(name="hihi") + sage: x = p.new_variable(name='hihi') sage: a1 = matrix([[1,2],[2,3]]) sage: a2 = matrix([[2,3],[3,4]]) sage: a3 = matrix([[3,4],[4,5]]) @@ -735,7 +731,6 @@ cdef class SemidefiniteProgram(SageObject): sage: x_sol = p.get_values(x) # needs cvxopt sage: sorted(x_sol) # needs cvxopt [3, 5] - """ val = [] for l in lists: @@ -762,11 +757,11 @@ cdef class SemidefiniteProgram(SageObject): def set_objective(self, obj): r""" - Sets the objective of the :class:`SemidefiniteProgram`. + Set the objective of the :class:`SemidefiniteProgram`. INPUT: - - ``obj`` -- A semidefinite function to be optimized. + - ``obj`` -- a semidefinite function to be optimized (can also be set to ``None`` or ``0`` when just looking for a feasible solution) @@ -808,8 +803,8 @@ cdef class SemidefiniteProgram(SageObject): if obj is not None: f = obj.dict() else: - f = {-1 : 0} - d = f.pop(-1,self._backend.zero()) + f = {-1: 0} + d = f.pop(-1, self._backend.zero()) for i in range(self._backend.ncols()): values.append(f.get(i,self._backend.zero())) @@ -817,11 +812,11 @@ cdef class SemidefiniteProgram(SageObject): def add_constraint(self, linear_function, name=None): r""" - Adds a constraint to the ``SemidefiniteProgram``. + Add a constraint to the ``SemidefiniteProgram``. INPUT: - - ``linear_function`` -- Two different types of arguments are possible: + - ``linear_function`` -- two different types of arguments are possible: - A linear function. In this case, arguments ``min`` or ``max`` have to be specified. @@ -829,7 +824,7 @@ cdef class SemidefiniteProgram(SageObject): ``A <= B <= C``, ``A >= B >= C`` or ``A == B``. In this case, arguments ``min`` and ``max`` will be ignored. - - ``name`` -- A name for the constraint. + - ``name`` -- a name for the constraint EXAMPLES: @@ -890,7 +885,6 @@ cdef class SemidefiniteProgram(SageObject): sage: p = SemidefiniteProgram() sage: p.add_constraint(sum([])) - """ if linear_function is 0: return @@ -919,15 +913,13 @@ cdef class SemidefiniteProgram(SageObject): INPUT: - - ``objective_only`` -- Boolean variable. - - - When set to ``True``, only the objective function is returned. - - When set to ``False`` (default), the optimal numerical values - are stored (takes computational time). + - ``objective_only`` -- boolean: - OUTPUT: + - when set to ``True``, only the objective function is returned + - when set to ``False`` (default), the optimal numerical values + are stored (takes computational time) - The optimal value taken by the objective function. + OUTPUT: the optimal value taken by the objective function TESTS: @@ -961,15 +953,14 @@ cdef class SemidefiniteProgram(SageObject): """ The `i`-th dual variable. - Available after self.solve() is called, otherwise the result is undefined. + Available after ``self.solve()`` is called, otherwise the result is + undefined. INPUT: - - ``index`` (integer) -- the constraint's id + - ``index`` -- integer; the constraint's id - OUTPUT: - - The matrix of the `i`-th dual variable. + OUTPUT: the matrix of the `i`-th dual variable EXAMPLES: @@ -1011,17 +1002,16 @@ cdef class SemidefiniteProgram(SageObject): cpdef slack(self, int i, sparse=False): """ - Slack of the `i`-th constraint + Slack of the `i`-th constraint. - Available after self.solve() is called, otherwise the result is undefined + Available after ``self.solve()`` is called, otherwise the result is + undefined. INPUT: - - ``index`` (integer) -- the constraint's id. - - OUTPUT: + - ``index`` -- integer; the constraint's id - The matrix of the slack of the `i`-th constraint + OUTPUT: the matrix of the slack of the `i`-th constraint EXAMPLES:: @@ -1071,15 +1061,15 @@ cdef class SemidefiniteProgram(SageObject): INPUT: - - ``name`` (string) -- the parameter + - ``name`` -- string; the parameter - ``value`` -- the parameter's value if it is to be defined, - or ``None`` (default) to obtain its current value. + or ``None`` (default) to obtain its current value EXAMPLES:: sage: # needs cvxopt - sage: p. = SemidefiniteProgram(solver="cvxopt", + sage: p. = SemidefiniteProgram(solver='cvxopt', ....: maximization=False) sage: p.solver_parameter("show_progress", True) sage: p.solver_parameter("show_progress") @@ -1107,13 +1097,13 @@ cdef class SemidefiniteProgram(SageObject): cpdef sum(self, L): r""" - Efficiently computes the sum of a sequence of + Efficiently compute the sum of a sequence of :class:`~sage.numerical.linear_functions.LinearFunction` elements. INPUT: - ``L`` -- list of - :class:`~sage.numerical.linear_functions.LinearFunction` instances. + :class:`~sage.numerical.linear_functions.LinearFunction` instances .. NOTE:: @@ -1150,7 +1140,7 @@ cdef class SemidefiniteProgram(SageObject): This example prints a matrix coefficient:: - sage: p = SemidefiniteProgram(solver="cvxopt") + sage: p = SemidefiniteProgram(solver='cvxopt') sage: x = p.new_variable() sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 5.]]) @@ -1182,7 +1172,7 @@ class SDPSolverException(RuntimeError): No solution:: sage: # needs cvxopt - sage: p = SemidefiniteProgram(solver="cvxopt") + sage: p = SemidefiniteProgram(solver='cvxopt') sage: x = p.new_variable() sage: p.set_objective(x[0]) sage: a = matrix([[1,2],[2,4]]) @@ -1220,13 +1210,13 @@ cdef class SDPVariable(Element): INPUT: - - ``parent`` -- :class:`SDPVariableParent`. The parent of the - SDP variable. + - ``parent`` -- :class:`SDPVariableParent`; the parent of the + SDP variable - - ``sdp`` -- :class:`SemidefiniteProgram`. The - underlying linear program. + - ``sdp`` -- :class:`SemidefiniteProgram`; the + underlying linear program - - ``name`` -- A name for the ``SDPVariable``. + - ``name`` -- a name for the ``SDPVariable`` - ``lower_bound``, ``upper_bound`` -- lower bound and upper bound on the variable. Set to ``None`` to indicate that the @@ -1259,7 +1249,6 @@ cdef class SDPVariable(Element): sage: p.set_objective(v[0] + v[1]) sage: v[0] x_0 - """ cdef int j if i in self._dict: @@ -1267,7 +1256,7 @@ cdef class SDPVariable(Element): zero = self._p._backend.zero() name = self._name + "[" + str(i) + "]" if self._name else None j = self._p._backend.add_variable( obj=zero, name=name) - v = self._p.linear_function({j : 1}) + v = self._p.linear_function({j: 1}) self._p._variables[v] = j self._dict[i] = v return v @@ -1389,11 +1378,9 @@ cdef class SDPVariableParent(Parent): def _repr_(self): r""" - Return representation of self. - - OUTPUT: + Return representation of ``self``. - String. + OUTPUT: string EXAMPLES:: @@ -1410,7 +1397,7 @@ cdef class SDPVariableParent(Parent): OUTPUT: This is required for the coercion framework. We raise a - ``TypeError`` to abort search for any coercion to another + :exc:`TypeError` to abort search for any coercion to another parent for binary operations. The only interesting operations involving :class:`SDPVariable` elements are actions by matrices. @@ -1428,11 +1415,9 @@ cdef class SDPVariableParent(Parent): def _element_constructor_(self, sdp, name=""): """ - The Element constructor - - INPUT/OUTPUT: + The Element constructor. - See :meth:`SDPVariable.__init__`. + INPUT/OUTPUT: see :meth:`SDPVariable.__init__` EXAMPLES:: diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index b8ea5e75bb3..a01d680bdcc 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -51,7 +51,7 @@ def normalize_input(a): return ((a,), {}) -class Parallel(): +class Parallel: r""" Create a ``parallel``-decorated function. This is the object created by :func:`parallel`. @@ -99,9 +99,7 @@ def __call__(self, f): - ``f`` -- Python callable object or function - OUTPUT: - - - Decorated version of ``f`` + OUTPUT: decorated version of ``f`` EXAMPLES:: @@ -121,7 +119,7 @@ def __call__(self, f): @instancedoc -class ParallelFunction(): +class ParallelFunction: """ Class which parallelizes a function or class method. This is typically accessed indirectly through @@ -129,7 +127,7 @@ class ParallelFunction(): """ def __init__(self, parallel, func): """ - .. note:: + .. NOTE:: This is typically accessed indirectly through :meth:`Parallel.__call__`. @@ -137,10 +135,9 @@ def __init__(self, parallel, func): INPUT: - ``parallel`` -- a :class:`Parallel` object which controls - how the parallel execution will be done. + how the parallel execution will be done - ``func`` -- Python callable object or function - """ self.parallel = parallel self.func = func @@ -170,7 +167,7 @@ def __get__(self, instance, owner): Implement part of the descriptor protocol for :class:`ParallelFunction` objects. - .. note:: + .. NOTE:: This is the key to fixing :issue:`11461`. @@ -228,7 +225,7 @@ def __get__(self, instance, owner): def _sage_argspec_(self): """ - Returns the argument specification for this object, which is + Return the argument specification for this object, which is just the argument specification for the underlying function. See :mod:`sage.misc.sageinspect` for more information on this convention. @@ -249,7 +246,7 @@ def _sage_argspec_(self): def _sage_src_(self): """ - Returns the source code for this object, which is just the + Return the source code for this object, which is just the source code for the underlying function. See :mod:`sage.misc.sageinspect` for more information on this convention. @@ -269,7 +266,7 @@ def _sage_src_(self): def _instancedoc_(self): r""" - Returns the docstring for this object, which is just the + Return the docstring for this object, which is just the docstring for the underlying function. See :mod:`sage.misc.sageinspect` for more information on this convention. @@ -304,13 +301,13 @@ def parallel(p_iter='fork', ncpus=None, **kwds): INPUT: - - ``p_iter`` -- parallel iterator function or string: - - ``'fork'`` -- (default) use a new forked subprocess for each input - - ``'multiprocessing'`` -- use multiprocessing library - - ``'reference'`` -- use a fake serial reference implementation - - ``ncpus`` -- integer, maximal number of subprocesses to use at the same time - - ``timeout`` -- number of seconds until each subprocess is killed (only supported - by 'fork'; zero means not at all) + - ``p_iter`` -- parallel iterator function or string: + - ``'fork'`` -- (default) use a new forked subprocess for each input + - ``'multiprocessing'`` -- use multiprocessing library + - ``'reference'`` -- use a fake serial reference implementation + - ``ncpus`` -- integer; maximal number of subprocesses to use at the same time + - ``timeout`` -- number of seconds until each subprocess is killed (only supported + by ``'fork'``; zero means not at all) .. warning:: @@ -318,7 +315,6 @@ def parallel(p_iter='fork', ncpus=None, **kwds): subprocess is spawned, so none of your local state (variables, certain functions, etc.) is available. - EXAMPLES: We create a simple decoration for a simple function. The number @@ -426,7 +422,7 @@ def parallel(p_iter='fork', ncpus=None, **kwds): # def f(...): ... ################################################################### -class Fork(): +class Fork: """ A ``fork`` decorator class. """ @@ -436,7 +432,7 @@ def __init__(self, timeout=0, verbose=False): - ``timeout`` -- (default: 0) kill the subprocess after it has run this many seconds (wall time), or if ``timeout`` is zero, do not kill it. - - ``verbose`` -- (default: ``False``) whether to print anything about + - ``verbose`` -- boolean (default: ``False``); whether to print anything about what the decorator does (e.g., killing the subprocess) EXAMPLES:: @@ -455,9 +451,7 @@ def __call__(self, f): - ``f`` -- a function - OUTPUT: - - - A decorated function. + OUTPUT: a decorated function EXAMPLES:: @@ -488,7 +482,7 @@ def fork(f=None, timeout=0, verbose=False): - ``f`` -- a function - ``timeout`` -- (default: 0) if positive, kill the subprocess after this many seconds (wall time) - - ``verbose`` -- (default: ``False``) whether to print anything + - ``verbose`` -- boolean (default: ``False``); whether to print anything about what the decorator does (e.g., killing the subprocess) .. warning:: @@ -522,8 +516,6 @@ def fork(f=None, timeout=0, verbose=False): sage: @fork(timeout=0.1, verbose=True) ....: def g(n, m): return factorial(n).ndigits() + m - sage: g(5, m=5) - 8 sage: g(10^7, m=5) Killing subprocess ... with input ((10000000,), {'m': 5}) which took too long 'NO DATA (timed out)' diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 460f91242c8..303f7405416 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -293,7 +293,7 @@ should be a prefix (including a possible directory) for the profile dump:: sage: import tempfile - sage: d = tempfile.TemporaryDirectory(prefix="RESetMR_profile") + sage: d = tempfile.TemporaryDirectory(prefix='RESetMR_profile') sage: res = S.run(profile=d.name) # random [RESetMapReduceWorker-1:58] (20:00:41.444) Profiling in /home/user/.sage/temp/.../32414/RESetMR_profilewRCRAx/profcomp1 @@ -346,7 +346,7 @@ `Logging facility for Python `_ for more detail on logging and log system configuration. -.. note:: +.. NOTE:: Calls to logger which involve printing the node are commented out in the code, because the printing (to a string) of the node can be very time @@ -393,16 +393,16 @@ map-reduce protocol: - ``_results`` -- a :class:`~multiprocessing.queues.SimpleQueue` where - the master gathers the results sent by the workers. + the master gathers the results sent by the workers - ``_active_tasks`` -- a :class:`~multiprocessing.Semaphore` recording - the number of active tasks. The work is complete when it reaches 0. + the number of active tasks; the work is complete when it reaches 0 - ``_done`` -- a :class:`~multiprocessing.Lock` which ensures that - shutdown is done only once. + shutdown is done only once - ``_aborted`` -- a :func:`~multiprocessing.Value` storing a shared :class:`ctypes.c_bool` which is ``True`` if the computation was aborted - before all workers ran out of work. -- ``_workers`` -- a list of :class:`RESetMapReduceWorker` objects. - Each worker is identified by its position in this list. + before all workers ran out of work +- ``_workers`` -- list of :class:`RESetMapReduceWorker` objects + Each worker is identified by its position in this list Each **worker** is a process (:class:`RESetMapReduceWorker` inherits from :class:`~multiprocessing.Process`) which contains: @@ -413,11 +413,11 @@ worker. It is used as a stack by the worker. Thiefs steal from the bottom of this queue. - ``worker._request`` -- a :class:`~multiprocessing.queues.SimpleQueue` storing - steal request submitted to ``worker``. + steal request submitted to ``worker`` - ``worker._read_task``, ``worker._write_task`` -- a - :class:`~multiprocessing.queues.Pipe` used to transfer node during steal. + :class:`~multiprocessing.queues.Pipe` used to transfer node during steal - ``worker._thief`` -- a :class:`~threading.Thread` which is in charge of - stealing from ``worker._todo``. + stealing from ``worker._todo`` Here is a schematic of the architecture: @@ -515,7 +515,7 @@ - :class:`RESetMPExample` -- a simple basic example - :class:`RESetParallelIterator` -- a more advanced example using non standard - communication configuration. + communication configuration Tests ----- @@ -591,8 +591,7 @@ def proc_number(max_proc=None): INPUT: - - ``max_proc`` -- an upper bound on the number of processes or - ``None``. + - ``max_proc`` -- an upper bound on the number of processes or ``None`` EXAMPLES:: @@ -629,7 +628,7 @@ class AbortError(Exception): pass -class ActiveTaskCounterDarwin(): +class ActiveTaskCounterDarwin: r""" Handling the number of active tasks. @@ -644,7 +643,7 @@ def __init__(self, task_number): sage: from sage.parallel.map_reduce import ActiveTaskCounterDarwin as ATC sage: t = ATC(4) - sage: TestSuite(t).run(skip="_test_pickling", verbose=True) + sage: TestSuite(t).run(skip='_test_pickling', verbose=True) running ._test_new() . . . pass """ self._active_tasks = mp.Value(ctypes.c_int, task_number) @@ -742,7 +741,7 @@ def abort(self): self._active_tasks.value = 0 -class ActiveTaskCounterPosix(): +class ActiveTaskCounterPosix: r""" Handling the number of active tasks. @@ -750,7 +749,7 @@ class ActiveTaskCounterPosix(): computation process. This is the standard implementation on POSIX compliant OSes. We essentially wrap a semaphore. - .. note:: + .. NOTE:: A legitimate question is whether there is a need in keeping the two implementations. I ran the following experiment on my machine:: @@ -778,7 +777,7 @@ def __init__(self, task_number): sage: from sage.parallel.map_reduce import ActiveTaskCounter as ATC sage: t = ATC(4) - sage: TestSuite(t).run(skip="_test_pickling", verbose=True) + sage: TestSuite(t).run(skip='_test_pickling', verbose=True) running ._test_new() . . . pass """ self._active_tasks = mp.Semaphore(task_number) @@ -885,7 +884,7 @@ def abort(self): # ActiveTaskCounter = ActiveTaskCounterDarwin # to debug Darwin implementation -class RESetMapReduce(): +class RESetMapReduce: r""" Map-Reduce on recursively enumerated sets. @@ -897,7 +896,7 @@ class RESetMapReduce(): - or a triple ``roots, children, post_process`` as follows - - ``roots=r`` -- The root of the enumeration + - ``roots=r`` -- the root of the enumeration - ``children=c`` -- a function iterating through children nodes, given a parent node - ``post_process=p`` -- a post-processing function @@ -908,9 +907,9 @@ class RESetMapReduce(): Description of the map/reduce operation: - - ``map_function=f`` -- (default to ``None``) - - ``reduce_function=red`` -- (default to ``None``) - - ``reduce_init=init`` -- (default to ``None``) + - ``map_function=f`` -- (default: ``None``) + - ``reduce_function=red`` -- (default: ``None``) + - ``reduce_init=init`` -- (default: ``None``) .. SEEALSO:: @@ -985,11 +984,9 @@ def roots(self): r""" Return the roots of ``self``. - OUTPUT: - - An iterable of nodes. + OUTPUT: an iterable of nodes - .. note:: This should be overloaded in applications. + .. NOTE:: This should be overloaded in applications. EXAMPLES:: @@ -1008,11 +1005,9 @@ def map_function(self, o): - ``o`` -- a node - OUTPUT: - - By default ``1``. + OUTPUT: by default ``1`` - .. note:: This should be overloaded in applications. + .. NOTE:: This should be overloaded in applications. EXAMPLES:: @@ -1034,11 +1029,9 @@ def reduce_function(self, a, b): - ``a``, ``b`` -- two values to be reduced - OUTPUT: - - By default the sum of ``a`` and ``b``. + OUTPUT: by default the sum of ``a`` and ``b`` - .. note:: This should be overloaded in applications. + .. NOTE:: This should be overloaded in applications. EXAMPLES:: @@ -1063,7 +1056,7 @@ def post_process(self, a): With the default post-processing function, which is the identity function, this returns ``a`` itself. - .. note:: This should be overloaded in applications. + .. NOTE:: This should be overloaded in applications. EXAMPLES:: @@ -1083,7 +1076,7 @@ def reduce_init(self): r""" Return the initial element for a reduction. - .. note:: This should be overloaded in applications. + .. NOTE:: This should be overloaded in applications. TESTS:: @@ -1103,8 +1096,8 @@ def setup_workers(self, max_proc=None, reduce_locally=True): INPUT: - - ``max_proc`` -- (integer) an upper bound on the number of - worker processes. + - ``max_proc`` -- integer; an upper bound on the number of + worker processes - ``reduce_locally`` -- whether the workers should reduce locally their work or sends results to the master as soon as possible. @@ -1143,21 +1136,12 @@ def start_workers(self): sage: from sage.parallel.map_reduce import RESetMapReduce sage: def children(x): ....: print(f"Starting: {x}", flush=True) - ....: sleep(float(0.5)) - ....: print(f"Finished: {x}", flush=True) ....: return [] sage: S = RESetMapReduce(roots=[1, 2], children=children) sage: S.setup_workers(2) - sage: S.start_workers(); sleep(float(0.4)) + sage: S.start_workers(); sleep(float(5)) # long time Starting: ... Starting: ... - sage: [w.is_alive() for w in S._workers] - [True, True] - sage: sleep(float(1.5)) - Finished: ... - Finished: ... - sage: [not w.is_alive() for w in S._workers] - [True, True] Cleanup:: @@ -1397,9 +1381,7 @@ def random_worker(self): r""" Return a random worker. - OUTPUT: - - A worker for ``self`` chosen at random. + OUTPUT: a worker for ``self`` chosen at random EXAMPLES:: @@ -1433,7 +1415,7 @@ def run(self, maximum number of worker processors to use. The actual number is also bounded by the value of the environment variable ``SAGE_NUM_THREADS`` (the number of cores by default). - - ``reduce_locally`` -- See :class:`RESetMapReduceWorker` (default: ``True``) + - ``reduce_locally`` -- see :class:`RESetMapReduceWorker` (default: ``True``) - ``timeout`` -- a timeout on the computation (default: ``None``) - ``profile`` -- directory/filename prefix for profiling, or ``None`` for no profiling (default: ``None``) @@ -1570,9 +1552,9 @@ class RESetMapReduceWorker(mp.Process): INPUT: - ``mapred`` -- the instance of :class:`RESetMapReduce` for which - this process is working. + this process is working - - ``iproc`` -- the id of this worker. + - ``iproc`` -- the id of this worker - ``reduce_locally`` -- when reducing the results. Three possible values are supported: @@ -1645,9 +1627,7 @@ def steal(self): r""" Steal some node from another worker. - OUTPUT: - - A node stolen from another worker chosen at random. + OUTPUT: a node stolen from another worker chosen at random EXAMPLES:: @@ -1659,7 +1639,7 @@ def steal(self): sage: # known bug (Issue #27537) sage: w0, w1 = EX._workers sage: w0._todo.append(42) - sage: thief0 = Thread(target = w0._thief, name="Thief") + sage: thief0 = Thread(target = w0._thief, name='Thief') sage: thief0.start() sage: w1.steal() 42 @@ -1753,7 +1733,7 @@ def run_myself(self): self._stats[0] = 0 self._stats[3] = 0 logger.debug("Launching thief") - self._thief = Thread(target=self._thief, name="Thief") + self._thief = Thread(target=self._thief, name='Thief') self._thief.start() self._res = reduce_init() @@ -1810,11 +1790,9 @@ def walk_branch_locally(self, node): INPUT: - - ``node`` -- the root of the subtree explored. + - ``node`` -- the root of the subtree explored - OUTPUT: - - Nothing, the result are stored in ``self._res``. + OUTPUT: nothing, the result are stored in ``self._res`` This is where the actual work is performed. @@ -1867,7 +1845,7 @@ class RESetMPExample(RESetMapReduce): INPUT: - - ``maxl`` -- the maximum size of permutations generated (default to `9`). + - ``maxl`` -- the maximum size of permutations generated (default: `9`) This computes the generating series of permutations counted by their size up to size ``maxl``. @@ -1881,7 +1859,6 @@ class RESetMPExample(RESetMapReduce): + 24*x^4 + 6*x^3 + 2*x^2 + x + 1 .. SEEALSO:: This is an example of :class:`RESetMapReduce` - """ def __init__(self, maxl=9): r""" @@ -1915,7 +1892,7 @@ def children(self, l): INPUT: - - ``l`` -- a list containing a permutation + - ``l`` -- list containing a permutation OUTPUT: @@ -1936,7 +1913,7 @@ def map_function(self, l): INPUT: - - ``l`` -- a list containing a permutation + - ``l`` -- list containing a permutation OUTPUT: diff --git a/src/sage/parallel/multiprocessing_sage.py b/src/sage/parallel/multiprocessing_sage.py index 2ccab49ac0f..ab2ee3f95ee 100644 --- a/src/sage/parallel/multiprocessing_sage.py +++ b/src/sage/parallel/multiprocessing_sage.py @@ -25,11 +25,9 @@ def pyprocessing(processes=0): INPUT: - ``processes`` -- integer (default: 0); if 0, set to the number - of processors on the computer. + of processors on the computer - OUTPUT: - - - a (partially evaluated) function + OUTPUT: a (partially evaluated) function EXAMPLES:: @@ -55,9 +53,7 @@ def parallel_iter(processes, f, inputs): - ``f`` -- function - ``inputs`` -- an iterable of pairs (args, kwds) - OUTPUT: - - - iterator over values of ``f`` at ``args,kwds`` in some random order. + OUTPUT: iterator over values of ``f`` at ``args, kwds`` in some random order EXAMPLES:: diff --git a/src/sage/parallel/parallelism.py b/src/sage/parallel/parallelism.py index 010372467d9..6df09f58fad 100644 --- a/src/sage/parallel/parallelism.py +++ b/src/sage/parallel/parallelism.py @@ -82,7 +82,6 @@ class Parallelism(Singleton, SageObject): Switching off all parallelizations:: sage: Parallelism().set(nproc=1) - """ def __init__(self): r""" @@ -104,7 +103,6 @@ def __init__(self): The test suite is passed:: sage: TestSuite(par).run() - """ self._default = ncpus() # default number of proc. used in parallelizations @@ -121,7 +119,6 @@ def _repr_(self): sage: Parallelism()._repr_() 'Number of processes for parallelization:\n - linbox computations: 1\n - tensor computations: 1' - """ resu = "Number of processes for parallelization:\n" for field in sorted(self._nproc): @@ -164,7 +161,6 @@ def reset(self): - tensor computations: 1 sage: Parallelism().get_default() # random (depends on the computer) 8 - """ self._default = ncpus() for field in self._nproc: @@ -233,7 +229,6 @@ def set(self, field=None, nproc=None): Number of processes for parallelization: - linbox computations: 1 - tensor computations: 1 - """ if field is None: for fi in self._nproc: @@ -277,7 +272,6 @@ def get(self, field): sage: Parallelism().set('tensor', nproc=4) sage: Parallelism().get('tensor') 4 - """ if field not in self._nproc: raise KeyError("entry for field {} is not ".format(field) + @@ -305,7 +299,6 @@ def get_all(self): sage: Parallelism().set(nproc=4) sage: Parallelism().get_all() {'linbox': 4, 'tensor': 4} - """ return self._nproc @@ -339,7 +332,6 @@ def set_default(self, nproc=None): sage: Parallelism().set_default() sage: Parallelism().get_default() # random (depends on the computer) 8 - """ if nproc is None: self._default = ncpus() @@ -367,6 +359,5 @@ def get_default(self): sage: Parallelism().set_default(nproc=4) sage: Parallelism().get_default() 4 - """ return self._default diff --git a/src/sage/parallel/reference.py b/src/sage/parallel/reference.py index 36dd7a8bb76..6a855874330 100644 --- a/src/sage/parallel/reference.py +++ b/src/sage/parallel/reference.py @@ -16,15 +16,13 @@ def parallel_iter(f, inputs): INPUT: - ``f`` -- a Python function that can be pickled using - the pickle_function command. + the ``pickle_function`` command - - ``inputs`` -- a list of pickleable pairs (args, kwds), where - args is a tuple and kwds is a dictionary. + - ``inputs`` -- list of pickleable pairs (args, kwds), where + args is a tuple and kwds is a dictionary - OUTPUT: - - - iterator over 2-tuples ``(inputs[i], f(inputs[i]))``, where the - order may be completely random + OUTPUT: iterator over 2-tuples ``(inputs[i], f(inputs[i]))``, where the + order may be completely random EXAMPLES:: diff --git a/src/sage/parallel/use_fork.py b/src/sage/parallel/use_fork.py index 24341dfb2de..36269127b80 100644 --- a/src/sage/parallel/use_fork.py +++ b/src/sage/parallel/use_fork.py @@ -20,18 +20,18 @@ from sage.misc.timing import walltime -class WorkerData(): +class WorkerData: """ Simple class which stores data about a running ``p_iter_fork`` worker. This just stores three attributes: - - ``input``: the input value used by this worker + - ``input`` -- the input value used by this worker - - ``starttime``: the walltime when this worker started + - ``starttime`` -- the walltime when this worker started - - ``failure``: an optional message indicating the kind of failure + - ``failure`` -- an optional message indicating the kind of failure EXAMPLES:: @@ -55,21 +55,19 @@ def __init__(self, input_value, starttime=None, failure=""): self.failure = failure -class p_iter_fork(): +class p_iter_fork: """ A parallel iterator implemented using ``fork()``. INPUT: - - ``ncpus`` -- the maximal number of simultaneous - subprocesses to spawn - - ``timeout`` -- (float, default: 0) wall time in seconds until - a subprocess is automatically killed - - ``verbose`` -- (default: ``False``) whether to print - anything about what the iterator does (e.g., killing - subprocesses) - - ``reset_interfaces`` -- (default: ``True``) whether to reset - all pexpect interfaces + - ``ncpus`` -- the maximal number of simultaneous subprocesses to spawn + - ``timeout`` -- float (default: 0); wall time in seconds until a + subprocess is automatically killed + - ``verbose`` -- boolean (default: ``False``); whether to print anything + about what the iterator does (e.g., killing subprocesses) + - ``reset_interfaces`` -- boolean (default: ``True``); whether to reset all + pexpect interfaces EXAMPLES:: @@ -114,11 +112,9 @@ def __call__(self, f, inputs): - ``f`` -- a function (or more general, any callable) - - ``inputs`` -- a list of pairs ``(args, kwds)`` to be used as + - ``inputs`` -- list of pairs ``(args, kwds)`` to be used as arguments to ``f``, where ``args`` is a tuple and ``kwds`` is - a dictionary. - - OUTPUT: + a dictionary EXAMPLES:: @@ -263,7 +259,7 @@ def _subprocess(self, f, dir, args, kwds={}): - ``dir`` -- name of a directory - - ``args`` -- a tuple with positional arguments for ``f`` + - ``args`` -- tuple with positional arguments for ``f`` - ``kwds`` -- (optional) a dict with keyword arguments for ``f`` diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index b5aae572283..16672405c8e 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -160,17 +160,16 @@ class Animation(WithEqualityById, SageObject): INPUT: - - ``v`` -- iterable of Sage objects. These should preferably be + - ``v`` -- iterable of Sage objects; these should preferably be graphics objects, but if they aren't, then :meth:`make_image` is called on them. - - ``xmin``, ``xmax``, ``ymin``, ``ymax`` -- the ranges of the x and y axes. + - ``xmin``, ``xmax``, ``ymin``, ``ymax`` -- the ranges of the x and y axes - ``**kwds`` -- all additional inputs are passed onto the rendering command. E.g., use ``figsize`` to adjust the resolution and aspect ratio. - EXAMPLES:: sage: x = SR.var("x") @@ -185,7 +184,7 @@ class Animation(WithEqualityById, SageObject): The :meth:`show` method takes arguments to specify the delay between frames (measured in hundredths of a second, default - value 20) and the number of iterations (default value 0, which + value 20) and the number of iterations (default: 0, which means to iterate forever). To iterate 4 times with half a second between each frame:: @@ -256,7 +255,7 @@ def __init__(self, v=None, **kwds): def _combine_kwds(self, *kwds_tuple): """ - Returns a dictionary which is a combination of the all the + Return a dictionary which is a combination of the all the dictionaries in kwds_tuple. This also does the appropriate thing for taking the mins and maxes of all of the x/y mins/maxes. @@ -406,7 +405,7 @@ def __mul__(self, other): def __len__(self): """ - Length of self + Length of ``self``. EXAMPLES:: @@ -459,7 +458,6 @@ def make_image(self, frame, filename, **kwds): sage: v = os.listdir(d); v.sort(); v ['00000000.png', '00000001.png', '00000002.png', '00000003.png'] sage: B.show() # not tested - """ p = plot.plot(frame, **kwds) p.save_image(filename) @@ -476,13 +474,10 @@ def png(self, dir=None): INPUT: - - ``dir`` -- Directory in which to store frames. Default - ``None``; in this case, a temporary directory will be - created for storing the frames. + - ``dir`` -- (default: ``None``) directory in which to store frames; in + this case, a temporary directory will be created for storing the frames - OUTPUT: - - Absolute path to the directory containing the PNG images + OUTPUT: absolute path to the directory containing the PNG images EXAMPLES:: @@ -518,7 +513,6 @@ def graphics_array(self, ncols=3): The frames must be acceptable inputs for :class:`sage.plot.multigraphics.GraphicsArray`. - EXAMPLES:: sage: # needs sage.schemes @@ -558,13 +552,13 @@ def graphics_array(self, ncols=3): nrows, rem = divmod(n,ncols) if rem > 0: nrows += 1 - return plot.graphics_array(frame_list, nrows, ncols) + return plot.graphics_array(frame_list, nrows, ncols) def gif(self, delay=20, savefile=None, iterations=0, show_path=False, use_ffmpeg=False): r""" - Returns an animated gif composed from rendering the graphics - objects in self. + Return an animated gif composed from rendering the graphics + objects in ``self``. This method will only work if either (a) the ImageMagick software suite is installed, i.e., you have the ``magick/convert`` @@ -576,19 +570,19 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, INPUT: - - ``delay`` -- (default: 20) delay in hundredths of a - second between frames + - ``delay`` -- (default: 20) delay in hundredths of a + second between frames - - ``savefile`` -- file that the animated gif gets saved - to + - ``savefile`` -- file that the animated gif gets saved + to - - ``iterations`` -- integer (default: 0); number of - iterations of animation. If 0, loop forever. + - ``iterations`` -- integer (default: 0); number of + iterations of animation. If 0, loop forever. - - ``show_path`` -- boolean (default: ``False``); if True, - print the path to the saved file + - ``show_path`` -- boolean (default: ``False``); if True, + print the path to the saved file - - ``use_ffmpeg`` -- boolean (default: ``False``); if True, use + - ``use_ffmpeg`` -- boolean (default: ``False``); if ``True``, use 'ffmpeg' by default instead of ImageMagick If ``savefile`` is not specified: in notebook mode, display the @@ -656,7 +650,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, INPUT: - - ``savefile`` -- file that the mpeg gets saved to. + - ``savefile`` -- file that the mpeg gets saved to .. warning:: @@ -666,7 +660,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, print the path to the saved file - ``delay`` -- (default: 20) delay in hundredths of a - second between frames + second between frames - ``iterations`` -- integer (default: 0); number of iterations of animation. If 0, loop forever. @@ -693,7 +687,6 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, Executable 'magick' not found on PATH. Further installation instructions might be available at https://www.imagemagick.org/. - """ from sage.features.imagemagick import ImageMagick, Magick ImageMagick().require() @@ -715,7 +708,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, # If a problem with the command occurs, print the log before # raising an error (more verbose than result.check_returncode()) if result.returncode: - print('Command "{}" returned non-zero exit status "{}" ' + print('Command "{}" returned nonzero exit status "{}" ' '(with stderr "{}" and stdout "{}").'.format(result.args, result.returncode, result.stderr.strip(), @@ -732,7 +725,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -805,11 +798,11 @@ def show(self, delay=None, iterations=None, **kwds): INPUT: - - ``delay`` -- (default: 20) delay in hundredths of a - second between frames. + - ``delay`` -- (default: 20) delay in hundredths of a + second between frames - - ``iterations`` -- integer (default: 0); number of - iterations of animation. If 0, loop forever. + - ``iterations`` -- integer (default: 0); number of + iterations of animation. If 0, loop forever. - ``format`` -- (default: gif) format to use for output. Currently supported formats are: gif, @@ -849,19 +842,19 @@ def show(self, delay=None, iterations=None, **kwds): You can also make use of the HTML5 video element in the Sage Notebook:: sage: # long time, optional -- FFmpeg - sage: a.show(format="ogg") - sage: a.show(format="webm") - sage: a.show(format="mp4") - sage: a.show(format="webm", iterations=1) + sage: a.show(format='ogg') + sage: a.show(format='webm') + sage: a.show(format='mp4') + sage: a.show(format='webm', iterations=1) Other backends may support other file formats as well:: sage: # long time, optional -- FFmpeg - sage: a.show(format="flash") - sage: a.show(format="matroska") - sage: a.show(format="avi") - sage: a.show(format="wmv") - sage: a.show(format="quicktime") + sage: a.show(format='flash') + sage: a.show(format='matroska') + sage: a.show(format='avi') + sage: a.show(format='wmv') + sage: a.show(format='quicktime') TESTS: @@ -903,7 +896,7 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, INPUT: - - ``savefile`` -- file that the mpeg gets saved to. + - ``savefile`` -- file that the mpeg gets saved to .. warning:: @@ -922,7 +915,7 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, used. - ``ffmpeg_options`` -- string (default: ``''``); this string is - passed directly to ffmpeg. + passed directly to ffmpeg - ``delay`` -- integer (default: ``None``); delay in hundredths of a second between frames. The framerate is 100/delay. @@ -934,7 +927,7 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, for animated gif output and requires ``ffmpeg`` version 0.9 or later. For older versions, set ``iterations=None``. - - ``pix_fmt`` -- string (default: 'rgb24'); used only for gif + - ``pix_fmt`` -- string (default: ``'rgb24'``); used only for gif output. Different values such as 'rgb8' or 'pal8' may be necessary depending on how ffmpeg was installed. Set ``pix_fmt=None`` to disable this option. @@ -1043,8 +1036,8 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, def apng(self, savefile=None, show_path=False, delay=20, iterations=0): r""" - Creates an animated PNG composed from rendering the graphics - objects in self. Return the absolute path to that file. + Create an animated PNG composed from rendering the graphics + objects in ``self``. Return the absolute path to that file. Notice that not all web browsers are capable of displaying APNG files, though they should still present the first frame of the @@ -1054,17 +1047,17 @@ def apng(self, savefile=None, show_path=False, delay=20, iterations=0): Input: - - ``delay`` -- (default: 20) delay in hundredths of a - second between frames + - ``delay`` -- (default: 20) delay in hundredths of a + second between frames - - ``savefile`` -- file that the animated gif gets saved - to + - ``savefile`` -- file that the animated gif gets saved + to - - ``iterations`` -- integer (default: 0); number of - iterations of animation. If 0, loop forever. + - ``iterations`` -- integer (default: 0); number of + iterations of animation. If 0, loop forever. - - ``show_path`` -- boolean (default: ``False``); if True, - print the path to the saved file + - ``show_path`` -- boolean (default: ``False``); if True, + print the path to the saved file EXAMPLES:: @@ -1094,7 +1087,6 @@ def apng(self, savefile=None, show_path=False, delay=20, iterations=0): sage: a = animate([]) sage: a.apng(show_path=True) Animation saved to file ....png. - """ pngdir = self.png() if savefile is None: @@ -1115,16 +1107,15 @@ def save(self, filename=None, show_path=False, use_ffmpeg=False, **kwds): INPUT: - - ``filename`` -- (default: None) name of save file + - ``filename`` -- (default: ``None``) name of save file - - ``show_path`` -- boolean (default: ``False``); if True, - print the path to the saved file + - ``show_path`` -- boolean (default: ``False``); if True, + print the path to the saved file - - ``use_ffmpeg`` -- boolean (default: ``False``); if True, use - 'ffmpeg' by default instead of ImageMagick when creating GIF - files. + - ``use_ffmpeg`` -- boolean (default: ``False``); if ``True``, use + 'ffmpeg' by default instead of ImageMagick when creating GIF files - If filename is None, then in notebook mode, display the + If filename is ``None``, then in notebook mode, display the animation; otherwise, save the animation to a GIF file. If filename ends in '.html', save an :meth:`interactive` version of the animation to an HTML file that uses the Three.js viewer. If @@ -1218,9 +1209,7 @@ def interactive(self, **kwds): viewer are: ``animate``, ``animation_controls``, ``auto_play``, ``delay``, and ``loop``. - OUTPUT: - - A 3D graphics object which, by default, will use the Three.js viewer. + OUTPUT: a 3D graphics object which, by default, will use the Three.js viewer EXAMPLES:: @@ -1240,7 +1229,6 @@ def interactive(self, **kwds): .. SEEALSO:: :ref:`threejs_viewer` - """ from sage.plot.plot3d.base import Graphics3d, KeyframeAnimationGroup # Attempt to convert frames to Graphics3d objects. @@ -1268,7 +1256,7 @@ def interactive(self, **kwds): class APngAssembler: r""" - Builds an APNG_ (Animated PNG) from a sequence of PNG files. + Build an APNG_ (Animated PNG) from a sequence of PNG files. This is used by the :meth:`sage.plot.animate.Animation.apng` method. This code is quite simple; it does little more than copying chunks @@ -1328,7 +1316,7 @@ def __init__(self, out, num_frames, def add_frame(self, pngfile, delay=None, delay_denominator=None): r""" - Adds a single frame to the APNG file. + Add a single frame to the APNG file. INPUT: @@ -1359,7 +1347,6 @@ def add_frame(self, pngfile, delay=None, delay_denominator=None): Traceback (most recent call last): ... RuntimeError: Already reached the declared number of frames - """ if self._idx == self.num_frames: raise RuntimeError("Already reached the declared number of frames") @@ -1378,7 +1365,7 @@ def add_frame(self, pngfile, delay=None, delay_denominator=None): def set_default(self, pngfile): r""" - Adds a default image for the APNG file. + Add a default image for the APNG file. This image is used as a fallback in case some application does not understand the APNG format. This method must be called @@ -1409,7 +1396,6 @@ def set_default(self, pngfile): Traceback (most recent call last): ... RuntimeError: Already reached the declared number of frames - """ if self._idx != 0: raise RuntimeError("Default image must precede all animation frames") @@ -1649,7 +1635,7 @@ def _fctl(self): def _chunk(self, ctype, cdata): r""" - Write a new (or modified) chunk of data + Write a new (or modified) chunk of data. TESTS:: @@ -1716,10 +1702,10 @@ def _testData(cls, name, asFile): INPUT: - - ``name``: The name of the file content. + - ``name`` -- the name of the file content. - - ``asFile``: Whether to return a binary string of the named data - or the path of a file containing that data. + - ``asFile`` -- whether to return a binary string of the named data + or the path of a file containing that data EXAMPLES:: @@ -1777,7 +1763,7 @@ def _testData(cls, name, asFile): d = cls._hex2bin(data[name]) if asFile: from sage.misc.temporary_file import tmp_filename - fn = tmp_filename(ext=".png") + fn = tmp_filename(ext='.png') with open(fn, 'wb') as f: f.write(d) return fn diff --git a/src/sage/plot/arc.py b/src/sage/plot/arc.py index 79dedb5762e..77f09c4a485 100644 --- a/src/sage/plot/arc.py +++ b/src/sage/plot/arc.py @@ -39,7 +39,7 @@ class Arc(GraphicPrimitive): - ``sector`` -- sector of angle - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -52,7 +52,7 @@ class Arc(GraphicPrimitive): """ def __init__(self, x, y, r1, r2, angle, s1, s2, options): """ - Initializes base class ``Arc``. + Initialize base class ``Arc``. EXAMPLES:: @@ -150,7 +150,7 @@ def get_minmax_data(self): if angle < 0: angle += twopi - epsilon = float(0.0000001) + epsilon = 0.0000001 cos_angle = cos(angle) sin_angle = sin(angle) @@ -297,7 +297,7 @@ def bezier_path(self): Graphics object consisting of 1 graphics primitive sage: from math import pi - sage: a = arc((0,0),2,1,0,(pi/5,pi/2+pi/12), linestyle="--", color="red") + sage: a = arc((0,0),2,1,0,(pi/5,pi/2+pi/12), linestyle='--', color='red') sage: b = a[0].bezier_path() sage: b[0] Bezier path from (1.133..., 0.8237...) to (-0.2655..., 0.9911...) @@ -390,23 +390,23 @@ def plot3d(self): aspect_ratio=1.0) def arc(center, r1, r2=None, angle=0.0, sector=(0.0, 2 * pi), **options): r""" - An arc (that is a portion of a circle or an ellipse) + An arc (that is a portion of a circle or an ellipse). Type ``arc.options`` to see all options. INPUT: - - ``center`` -- 2-tuple of real numbers; position of the center. + - ``center`` -- 2-tuple of real numbers; position of the center - ``r1``, ``r2`` -- positive real numbers; radii of the ellipse. If only ``r1`` is set, then the two radii are supposed to be equal and this function returns an arc of circle. - ``angle`` -- real number; angle between the horizontal and the axis that - corresponds to ``r1``. + corresponds to ``r1`` - - ``sector`` -- 2-tuple (default: (0,2*pi))- angles sector in which the arc will - be drawn. + - ``sector`` -- 2-tuple (default: (0,2*pi)); angles sector in which the arc will + be drawn OPTIONS: @@ -414,12 +414,12 @@ def arc(center, r1, r2=None, angle=0.0, sector=(0.0, 2 * pi), **options): - ``thickness`` -- float (default: 1) -- thickness of the arc - - ``color``, ``rgbcolor``; string or 2-tuple (default: 'blue') -- the color - of the arc + - ``color``, ``rgbcolor`` -- string or 2-tuple (default: ``'blue'``); the + color of the arc - - ``linestyle`` -- string (default: ``'solid'``) -- The style of the line, + - ``linestyle`` -- string (default: ``'solid'``); the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, - or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively. + or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively EXAMPLES: @@ -454,14 +454,14 @@ def arc(center, r1, r2=None, angle=0.0, sector=(0.0, 2 * pi), **options): Plot an arc of an ellipse in red with a dashed linestyle:: - sage: arc((0,0), 2, 1, 0, (0,pi/2), linestyle="dashed", color="red") + sage: arc((0,0), 2, 1, 0, (0,pi/2), linestyle='dashed', color='red') Graphics object consisting of 1 graphics primitive - sage: arc((0,0), 2, 1, 0, (0,pi/2), linestyle="--", color="red") + sage: arc((0,0), 2, 1, 0, (0,pi/2), linestyle='--', color='red') Graphics object consisting of 1 graphics primitive .. PLOT:: - sphinx_plot(arc((0,0), 2, 1, 0, (0,pi/2), linestyle="dashed", color="red")) + sphinx_plot(arc((0,0), 2, 1, 0, (0,pi/2), linestyle='dashed', color='red')) The default aspect ratio for arcs is 1.0:: diff --git a/src/sage/plot/arrow.py b/src/sage/plot/arrow.py index ac1dc79d802..02442f90ba4 100644 --- a/src/sage/plot/arrow.py +++ b/src/sage/plot/arrow.py @@ -26,7 +26,7 @@ class CurveArrow(GraphicPrimitive): def __init__(self, path, options): """ - Returns an arrow graphics primitive along the provided path (bezier curve). + Return an arrow graphics primitive along the provided path (bezier curve). EXAMPLES:: @@ -49,10 +49,13 @@ def __init__(self, path, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: + sage: import numpy # to ensure numpy 2.0 compatibility + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") sage: from sage.plot.arrow import CurveArrow sage: b = CurveArrow(path=[[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]], ....: options={}) @@ -163,7 +166,7 @@ def _render_on_subplot(self, subplot): class Arrow(GraphicPrimitive): """ - Primitive class that initializes the (line) arrow graphics type + Primitive class that initializes the (line) arrow graphics type. EXAMPLES: @@ -194,7 +197,7 @@ def __init__(self, xtail, ytail, xhead, yhead, options): def get_minmax_data(self): """ - Returns a bounding box for this arrow. + Return a bounding box for this arrow. EXAMPLES:: @@ -280,7 +283,7 @@ def _plot3d_options(self, options=None): def plot3d(self, ztail=0, zhead=0, **kwds): """ - Takes 2D plot and places it in 3D. + Take 2D plot and places it in 3D. EXAMPLES:: @@ -398,7 +401,7 @@ def _render_on_subplot(self, subplot): class CheckNthSubPath: def __init__(self, patch, n): """ - creates a callable object that returns True if the + Creates a callable object that returns ``True`` if the provided path is the n-th path from the patch. """ self._patch = patch @@ -426,8 +429,8 @@ class ConditionalStroke(pe.RendererBase): def __init__(self, condition_func, pe_list): """ - path effect that is only applied when the condition_func - returns True. + Path effect that is only applied when the ``condition_func`` + returns ``True``. """ super().__init__() self._pe_list = pe_list @@ -449,7 +452,7 @@ def draw_path(self, renderer, gc, tpath, affine, rgbFace): def arrow(tailpoint=None, headpoint=None, **kwds): """ - Returns either a 2-dimensional or 3-dimensional arrow depending + Return either a 2-dimensional or 3-dimensional arrow depending on value of points. For information regarding additional arguments, see either arrow2d? @@ -479,7 +482,6 @@ def arrow(tailpoint=None, headpoint=None, **kwds): sage: arrow((0,0), (0,0), linestyle='dashed') Graphics object consisting of 1 graphics primitive - """ try: return arrow2d(tailpoint, headpoint, **kwds) @@ -511,9 +513,9 @@ def arrow2d(tailpoint=None, headpoint=None, path=None, **options): or both (2) of the path (using 0 will swap headpoint and tailpoint). This is ignored in 3D plotting. - - ``linestyle`` -- (default: ``'solid'``) The style of the line, which is + - ``linestyle`` -- (default: ``'solid'``) the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, - or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively. + or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively - ``width`` -- (default: 2) the width of the arrow shaft, in points @@ -532,7 +534,7 @@ def arrow2d(tailpoint=None, headpoint=None, path=None, **options): - ``legend_color`` -- the color for the legend label - ``zorder`` -- the layer level to draw the arrow-- note that this is - ignored in 3D plotting. + ignored in 3D plotting EXAMPLES: @@ -646,7 +648,7 @@ def arrow2d(tailpoint=None, headpoint=None, path=None, **options): Verify that :issue:`36153` is fixed:: - sage: A = arrow2d((-1,-1), (2,3), legend_label="test") + sage: A = arrow2d((-1,-1), (2,3), legend_label='test') """ from sage.plot.all import Graphics g = Graphics() diff --git a/src/sage/plot/bar_chart.py b/src/sage/plot/bar_chart.py index 34ed242af4c..f03ea65ab12 100644 --- a/src/sage/plot/bar_chart.py +++ b/src/sage/plot/bar_chart.py @@ -54,7 +54,7 @@ def __init__(self, ind, datalist, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: diff --git a/src/sage/plot/bezier_path.py b/src/sage/plot/bezier_path.py index abd171bbdb6..1b81c6fe6d5 100644 --- a/src/sage/plot/bezier_path.py +++ b/src/sage/plot/bezier_path.py @@ -38,18 +38,17 @@ class BezierPath(GraphicPrimitive_xydata): We use :func:`bezier_path` to actually plot Bezier curves:: - sage: bezier_path([[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]], linestyle="dashed") + sage: bezier_path([[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]], linestyle='dashed') Graphics object consisting of 1 graphics primitive .. PLOT:: - P = bezier_path([[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]], linestyle="dashed") + P = bezier_path([[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]], linestyle='dashed') sphinx_plot(P) - """ def __init__(self, path, options): """ - Returns a graphics primitive of a path of Bezier curves. + Return a graphics primitive of a path of Bezier curves. EXAMPLES:: @@ -97,7 +96,7 @@ def __init__(self, path, options): def _allowed_options(self): """ - Returns a dict of allowed options for ``bezier_path``. + Return a dict of allowed options for ``bezier_path``. EXAMPLES:: @@ -111,7 +110,6 @@ def _allowed_options(self): ('rgbcolor', 'The color as an RGB tuple.'), ('thickness', 'How thick the border of the polygon is.'), ('zorder', 'The layer level in which to draw')] - """ return {'alpha': 'How transparent the line is.', 'fill': 'Whether or not to fill the polygon.', @@ -124,7 +122,7 @@ def _allowed_options(self): def _plot3d_options(self, options=None): """ - Updates ``BezierPath`` options to those allowed by 3D implementation. + Update ``BezierPath`` options to those allowed by 3D implementation. EXAMPLES:: @@ -158,9 +156,9 @@ def _plot3d_options(self, options=None): def plot3d(self, z=0, **kwds): """ - Returns a 3D plot (Jmol) of the Bezier path. Since a ``BezierPath`` + Return a 3D plot (Jmol) of the Bezier path. Since a ``BezierPath`` primitive contains only `x,y` coordinates, the path will be drawn in - some plane (default is `z=0`). To create a Bezier path with nonzero + some plane (default: `z=0`). To create a Bezier path with nonzero (and nonidentical) `z` coordinates in the path and control points, use the function :func:`~sage.plot.plot3d.shapes2.bezier3d` instead of :func:`bezier_path`. @@ -188,7 +186,6 @@ def plot3d(self, z=0, **kwds): .. PLOT:: sphinx_plot(bezier3d([[(0,0,0),(1,0,0),(0,1,0),(0,1,1)]])) - """ from sage.plot.plot3d.shapes2 import bezier3d options = self._plot3d_options() @@ -255,7 +252,7 @@ def _render_on_subplot(self, subplot): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: @@ -276,7 +273,7 @@ def get_minmax_data(self): @options(alpha=1, fill=False, thickness=1, rgbcolor=(0,0,0), zorder=2, linestyle='solid') def bezier_path(path, **options): """ - Returns a Graphics object of a Bezier path corresponding to the + Return a Graphics object of a Bezier path corresponding to the path parameter. The path is a list of curves, and each curve is a list of points. Each point is a tuple ``(x,y)``. @@ -312,11 +309,11 @@ def bezier_path(path, **options): p5 = (0,4) path = [[p1, c1, c2, p2], [c3, c4, p3], [c5, p4], [p5]] P = bezier_path(path) - P += line([p1,c1], color="red", linestyle="dashed") - P += line([p2,c2], color="red", linestyle="dashed") - P += line([p2,c3], color="red", linestyle="dashed") - P += line([p3,c4], color="red", linestyle="dashed") - P += line([p3,c5], color="red", linestyle="dashed") + P += line([p1,c1], color='red', linestyle='dashed') + P += line([p2,c2], color='red', linestyle='dashed') + P += line([p2,c3], color='red', linestyle='dashed') + P += line([p3,c4], color='red', linestyle='dashed') + P += line([p3,c5], color='red', linestyle='dashed') P += text("c1", c1, horizontal_alignment='left') P += text("c2", c2, horizontal_alignment='right') P += text("c3", c3, horizontal_alignment='left', vertical_alignment='bottom') @@ -339,14 +336,14 @@ def bezier_path(path, **options): INPUT: - - ``path`` -- a list of lists of tuples (see above) - - ``alpha`` -- default: 1 - - ``fill`` -- default: ``False`` - - ``thickness`` -- default: 1 - - ``linestyle`` -- default: ``'solid'``, The style of the line, which is one - of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or ``'--'``, - ``':'``, ``'-'``, ``'-.'``, respectively. - - ``rgbcolor`` -- default: (0,0,0) + - ``path`` -- list of lists of tuples (see above) + - ``alpha`` -- (default: 1) + - ``fill`` -- (default: ``False``) + - ``thickness`` -- (default: 1) + - ``linestyle`` -- (default: ``'solid'``) the style of the line, which is one + of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or ``'--'``, + ``':'``, ``'-'``, ``'-.'``, respectively + - ``rgbcolor`` -- (default: (0,0,0)) - ``zorder`` -- the layer in which to draw EXAMPLES:: diff --git a/src/sage/plot/circle.py b/src/sage/plot/circle.py index 3ee8d9e3e91..f9c864d602a 100644 --- a/src/sage/plot/circle.py +++ b/src/sage/plot/circle.py @@ -36,7 +36,7 @@ class Circle(GraphicPrimitive): - ``r`` -- radius of Circle object - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -59,7 +59,7 @@ class Circle(GraphicPrimitive): """ def __init__(self, x, y, r, options): """ - Initializes base class Circle. + Initialize base class Circle. EXAMPLES:: @@ -172,8 +172,7 @@ def plot3d(self, z=0, **kwds): INPUT: - - - ``z`` -- optional 3D height above `xy`-plane. + - ``z`` -- (optional) 3D height above `xy`-plane EXAMPLES:: @@ -240,23 +239,23 @@ def circle(center, radius, **options): OPTIONS: - - ``alpha`` -- default: 1 + - ``alpha`` -- (default: 1) - - ``fill`` -- default: ``False`` + - ``fill`` -- (default: ``False``) - - ``thickness`` -- default: 1 + - ``thickness`` -- (default: 1) - - ``linestyle`` -- default: ``'solid'`` (2D plotting only) The style of the + - ``linestyle`` -- (default: ``'solid'``) (2D plotting only) the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, - or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively. + or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively - - ``edgecolor`` -- default: 'blue' (2D plotting only) + - ``edgecolor`` -- (default: ``'blue'``) 2D plotting only - - ``facecolor`` -- default: 'blue' (2D plotting only, useful only - if ``fill=True``) + - ``facecolor`` -- (default: ``'blue'``) 2D plotting only, useful only + if ``fill=True`` - ``rgbcolor`` -- 2D or 3D plotting. This option overrides - ``edgecolor`` and ``facecolor`` for 2D plotting. + ``edgecolor`` and ``facecolor`` for 2D plotting - ``legend_label`` -- the label for this item in the legend @@ -409,7 +408,7 @@ def circle(center, radius, **options): Verify that :issue:`36153` does not arise:: - sage: C = circle((1,1), 1, legend_label="test") + sage: C = circle((1,1), 1, legend_label='test') """ from sage.plot.all import Graphics diff --git a/src/sage/plot/colors.py b/src/sage/plot/colors.py index 8d95d2725fb..a9792c2e374 100644 --- a/src/sage/plot/colors.py +++ b/src/sage/plot/colors.py @@ -202,9 +202,7 @@ def mod_one(x): - ``x`` -- an instance of Integer, int, RealNumber, etc.; the number to reduce - OUTPUT: - - - a float + OUTPUT: float EXAMPLES:: @@ -232,11 +230,9 @@ def html_to_float(c): INPUT: - - ``c`` -- a string; a valid HTML hex color + - ``c`` -- string; a valid HTML hex color - OUTPUT: - - - a RGB 3-tuple of floats in the interval [0.0, 1.0] + OUTPUT: a RGB 3-tuple of floats in the interval [0.0, 1.0] EXAMPLES:: @@ -271,13 +267,11 @@ def rgbcolor(c, space='rgb'): - ``c`` -- a :class:`Color` instance, string (name or HTML hex), 3-tuple, or 3-list; the color to convert - - ``space`` -- a string (default: 'rgb'); the color space - coordinate system (other choices are 'hsl', 'hls', and 'hsv') in - which to interpret a 3-tuple or 3-list - - OUTPUT: + - ``space`` -- string (default: ``'rgb'``); the color space + coordinate system (other choices are ``'hsl'``, ``'hls'``, and ``'hsv'``) + in which to interpret a 3-tuple or 3-list - - a RGB 3-tuple of floats in the interval [0.0, 1.0] + OUTPUT: a RGB 3-tuple of floats in the interval [0.0, 1.0] EXAMPLES:: @@ -370,17 +364,17 @@ def __init__(self, r='#0000ff', g=None, b=None, space='rgb'): transformations, of this space. Coordinates in all of these spaces are floating point values in the interval [0.0, 1.0]. - .. note:: All instantiations of :class:`Color` are converted + .. NOTE:: All instantiations of :class:`Color` are converted to an internal RGB floating point 3-tuple. This is likely to degrade precision. INPUT: - - ``r,g,b`` -- either a triple of floats between 0 and 1, - OR ``r`` - a color name string or HTML color hex string + - ``r``, ``g``, ``b`` -- either a triple of floats between 0 and 1, + OR ``r`` - a color name string or HTML color hex string - - ``space`` -- a string (default: 'rgb'); the coordinate system - (other choices are 'hsl', 'hls', and 'hsv') in which to + - ``space`` -- string (default: ``'rgb'``); the coordinate system + (other choices are ``'hsl'``, ``'hls'``, and ``'hsv'``) in which to interpret a triple of floats EXAMPLES:: @@ -410,9 +404,7 @@ def __repr__(self): """ Return a string representation of this color. - OUTPUT: - - - a string + OUTPUT: string EXAMPLES:: @@ -433,9 +425,7 @@ def __lt__(self, right): - ``right`` -- an object - OUTPUT: - - - boolean -- False + OUTPUT: boolean; ``False`` EXAMPLES:: @@ -459,9 +449,7 @@ def __le__(self, right): - ``right`` -- an object - OUTPUT: - - - boolean -- False + OUTPUT: boolean; ``False`` EXAMPLES:: @@ -483,9 +471,8 @@ def __eq__(self, right): - ``right`` -- a :class:`Color` instance - OUTPUT: - - - boolean -- True if the two colors are the same, False if different + OUTPUT: boolean; ``True`` if the two colors are the same, ``False`` + if different EXAMPLES:: @@ -513,8 +500,8 @@ def __ne__(self, right): OUTPUT: - - boolean -- True if the two colors are different, - False if they're the same + boolean; ``True`` if the two colors are different, ``False`` if they're + the same. EXAMPLES:: @@ -539,9 +526,7 @@ def __gt__(self, right): - ``right`` -- an object - OUTPUT: - - - boolean -- False + OUTPUT: boolean; ``False`` EXAMPLES:: @@ -565,9 +550,7 @@ def __ge__(self, right): - ``right`` -- an object - OUTPUT: - - - boolean -- False + OUTPUT: boolean; ``False`` EXAMPLES:: @@ -585,9 +568,7 @@ def __hash__(self): Return the hash value of a color. Equal colors return equal hash values. - OUTPUT: - - - a hash value + OUTPUT: a hash value EXAMPLES:: @@ -612,9 +593,7 @@ def blend(self, color, fraction=0.5): - ``fraction`` -- a float-convertible number; the fraction of ``color`` to blend with this color - OUTPUT: - - - a **new** :class:`Color` instance + OUTPUT: a **new** :class:`Color` instance EXAMPLES:: @@ -657,9 +636,7 @@ def __add__(self, right): - ``right`` -- a :class:`Color` instance or float-convertible 3-tuple/list - OUTPUT: - - - a **new** :class:`Color` instance + OUTPUT: a **new** :class:`Color` instance EXAMPLES:: @@ -693,9 +670,7 @@ def __radd__(self, left): - ``left`` -- a :class:`Color` instance or float-convertible 3-tuple/list - OUTPUT: - - - a **new** :class:`Color` instance + OUTPUT: a **new** :class:`Color` instance EXAMPLES:: @@ -723,9 +698,7 @@ def __mul__(self, right): - ``right`` -- a float-convertible number - OUTPUT: - - - a **new** :class:`Color` instance + OUTPUT: a **new** :class:`Color` instance EXAMPLES:: @@ -751,9 +724,7 @@ def __rmul__(self, left): - ``left`` -- a float-convertible number - OUTPUT: - - - a **new** :class:`Color` instance + OUTPUT: a **new** :class:`Color` instance EXAMPLES:: @@ -772,11 +743,9 @@ def __truediv__(self, right): INPUT: - - ``right`` -- a float-convertible, non-zero number - - OUTPUT: + - ``right`` -- a float-convertible, nonzero number - - a **new** instance of :class:`Color` + OUTPUT: a **new** instance of :class:`Color` EXAMPLES:: @@ -812,9 +781,9 @@ def __int__(self): OUTPUT: - - the integer `256^2 r_int + 256 g_int + b_int`, where `r_int`, `g_int`, and `b_int` - are obtained from `r`, `g`, and `b` by converting from the real interval [0.0, 1.0] - to the integer range 0, 1, ..., 255. + The integer 256^2 r_int + 256 g_int + b_int, where r_int, g_int, + and b_int are obtained from r, g, and b by converting from the + real interval [0.0, 1.0] to the integer range 0, 1, ..., 255. EXAMPLES:: @@ -828,9 +797,7 @@ def __iter__(self): """ Return an iterator over the RGB coordinates of this color. - OUTPUT: - - - a tupleiterator + OUTPUT: a tupleiterator EXAMPLES:: @@ -854,11 +821,9 @@ def __getitem__(self, i): INPUT: - - ``i`` -- an integer; the 0-based coordinate to retrieve + - ``i`` -- integer; the 0-based coordinate to retrieve - OUTPUT: - - - a float + OUTPUT: float EXAMPLES:: @@ -881,9 +846,7 @@ def rgb(self): Return the underlying Red-Green-Blue (RGB) coordinates of this color. - OUTPUT: - - - a 3-tuple of floats + OUTPUT: a 3-tuple of floats EXAMPLES:: @@ -906,9 +869,7 @@ def hls(self): Return the Hue-Lightness-Saturation (HLS) coordinates of this color. - OUTPUT: - - - a 3-tuple of floats + OUTPUT: a 3-tuple of floats EXAMPLES:: @@ -929,9 +890,7 @@ def hsl(self): Return the Hue-Saturation-Lightness (HSL) coordinates of this color. - OUTPUT: - - - a 3-tuple of floats + OUTPUT: a 3-tuple of floats EXAMPLES:: @@ -951,9 +910,7 @@ def hsv(self): Return the Hue-Saturation-Value (HSV) coordinates of this color. - OUTPUT: - - - a 3-tuple of floats + OUTPUT: a 3-tuple of floats EXAMPLES:: @@ -971,9 +928,7 @@ def html_color(self): """ Return a HTML hex representation for this color. - OUTPUT: - - - a string of length 7. + OUTPUT: string of length 7 EXAMPLES:: @@ -1000,9 +955,7 @@ def lighter(self, fraction=1/3): - ``fraction`` -- a float (default: 1/3); blending fraction to apply - OUTPUT: - - - a **new** instance of :class:`Color` + OUTPUT: a **new** instance of :class:`Color` EXAMPLES:: @@ -1028,9 +981,7 @@ def darker(self, fraction=1/3): - ``fraction`` -- a float (default: 1/3); blending fraction to apply - OUTPUT: - - - a new instance of :class:`Color` + OUTPUT: a new instance of :class:`Color` EXAMPLES:: @@ -1055,7 +1006,7 @@ class ColorsDict(dict): """ def __init__(self): """ - Constructs a dict-like collection of colors. The keys are the + Construct a dict-like collection of colors. The keys are the color names (i.e., strings) and the values are RGB 3-tuples of floats. @@ -1076,15 +1027,13 @@ def __init__(self): def __getattr__(self, name): """ - Gets a color via attribute access. + Get a color via attribute access. INPUT: - - ``name`` -- a string; the name of the color to return + - ``name`` -- string; the name of the color to return - OUTPUT: - - - a RGB 3-tuple of floats + OUTPUT: a RGB 3-tuple of floats EXAMPLES:: @@ -1108,12 +1057,10 @@ def __getattr__(self, name): def __dir__(self): """ - Returns an approximate list of attribute names, including the + Return an approximate list of attribute names, including the color names. - OUTPUT: - - - a list of strings + OUTPUT: list of strings EXAMPLES:: @@ -1161,9 +1108,7 @@ def hue(h, s=1, v=1): - ``v`` -- a number (default: 1); the color's value - OUTPUT: - - - a RGB 3-tuple of floats in the interval [0.0, 1.0] + OUTPUT: a RGB 3-tuple of floats in the interval [0.0, 1.0] EXAMPLES:: @@ -1204,9 +1149,7 @@ def float_to_html(r, g, b): - ``b`` -- a real number; the RGB color's "blue" intensity - OUTPUT: - - - a string of length 7, starting with '#' + OUTPUT: string of length 7, starting with ``'#'`` EXAMPLES:: @@ -1245,9 +1188,9 @@ def float_to_integer(r, g, b): OUTPUT: - - the integer `256^2 r_int + 256 g_int + b_int`, where `r_int`, `g_int`, and `b_int` - are obtained from `r`, `g`, and `b` by converting from the real interval [0.0, 1.0] - to the integer range 0, 1, ..., 255. + The integer 256^2 r_int + 256 g_int + b_int, where r_int, g_int, and + b_int are obtained from r, g, and b by converting from the real + interval [0.0, 1.0] to the integer range 0, 1, ..., 255. EXAMPLES:: @@ -1272,7 +1215,7 @@ def float_to_integer(r, g, b): def rainbow(n, format='hex'): """ - Returns a list of colors sampled at equal intervals over the + Return a list of colors sampled at equal intervals over the spectrum, from Hue-Saturation-Value (HSV) coordinates (0, 1, 1) to (1, 1, 1). This range is red at the extremes, but it covers orange, yellow, green, cyan, blue, violet, and many other hues in @@ -1283,13 +1226,11 @@ def rainbow(n, format='hex'): - ``n`` -- a number; the length of the list - - ``format`` -- a string (default: 'hex'); the output format for - each color in the list; the other choice is 'rgbtuple' - - OUTPUT: + - ``format`` -- string (default: ``'hex'``); the output format for + each color in the list. The other choice is ``'rgbtuple'``. - - a list of strings or RGB 3-tuples of floats in the interval - [0.0, 1.0] + OUTPUT: a list of strings or RGB 3-tuples of floats in the interval + [0.0, 1.0] EXAMPLES:: @@ -1321,7 +1262,7 @@ def rainbow(n, format='hex'): # about cmap where it is used and to test these classes. def get_cmap(cmap): r""" - Returns a color map (actually, a matplotlib :class:`Colormap` + Return a color map (actually, a matplotlib :class:`Colormap` object), given its name or a [mixed] list/tuple of RGB list/tuples and color names. For a list of map names, evaluate:: @@ -1332,13 +1273,10 @@ def get_cmap(cmap): INPUT: - - ``cmap`` -- a string, list, tuple, or - :class:`matplotlib.colors.Colormap`; a string must be a valid - color map name - - OUTPUT: + - ``cmap`` -- string, list, tuple, or :class:`matplotlib.colors.Colormap`; + a string must be a valid color map name - - a :class:`matplotlib.colors.Colormap` instance + OUTPUT: a :class:`matplotlib.colors.Colormap` instance EXAMPLES:: @@ -1428,7 +1366,7 @@ class Colormaps(MutableMapping): """ def __init__(self): """ - Constructs an empty mutable collection of color maps. + Construct an empty mutable collection of color maps. EXAMPLES:: @@ -1462,12 +1400,10 @@ def load_maps(self): def __dir__(self): """ - Returns an approximate list of attribute names, including the + Return an approximate list of attribute names, including the color map names. - OUTPUT: - - - a list of strings + OUTPUT: list of strings EXAMPLES:: @@ -1484,11 +1420,9 @@ def __dir__(self): def __len__(self): """ - Returns the number of color maps. + Return the number of color maps. - OUTPUT: - - - an int + OUTPUT: integer EXAMPLES:: @@ -1502,11 +1436,9 @@ def __len__(self): def __iter__(self): """ - Returns an iterator over the color map collection. + Return an iterator over the color map collection. - OUTPUT: - - - a dictionary key iterator instance + OUTPUT: a dictionary key iterator instance EXAMPLES:: @@ -1522,15 +1454,13 @@ def __iter__(self): def __contains__(self, name): """ - Returns whether a map is in the color maps collection. + Return whether a map is in the color maps collection. INPUT: - - ``name`` -- a string; the name of the map to query - - OUTPUT: + - ``name`` -- string; the name of the map to query - - a boolean + OUTPUT: boolean EXAMPLES:: @@ -1546,15 +1476,13 @@ def __contains__(self, name): def __getitem__(self, name): """ - Gets a color map from the collection via key access. + Get a color map from the collection via key access. INPUT: - - ``name`` -- a string; the name of the map return - - OUTPUT: + - ``name`` -- string; the name of the map return - - an instance of :class:`matplotlib.colors.Colormap` + OUTPUT: an instance of :class:`matplotlib.colors.Colormap` EXAMPLES:: @@ -1578,15 +1506,13 @@ def __getitem__(self, name): def __getattr__(self, name): """ - Gets a color map from the collection via attribute access. + Get a color map from the collection via attribute access. INPUT: - - ``name`` -- a string; the name of the map to return + - ``name`` -- string; the name of the map to return - OUTPUT: - - - an instance of :class:`matplotlib.colors.Colormap` + OUTPUT: an instance of :class:`matplotlib.colors.Colormap` EXAMPLES:: @@ -1612,11 +1538,9 @@ def __getattr__(self, name): def __repr__(self): """ - Returns a string representation of the color map collection. - - OUTPUT: + Return a string representation of the color map collection. - - a string + OUTPUT: string EXAMPLES:: @@ -1632,11 +1556,11 @@ def __repr__(self): def __setitem__(self, name, colormap): """ - Adds a color map to the collection. + Add a color map to the collection. INPUT: - - ``name`` -- a string; the name of the map to add + - ``name`` -- string; the name of the map to add - ``colormap`` -- an instance of :class:`matplotlib.colors.Colormap`; the color map to add @@ -1662,7 +1586,7 @@ def __delitem__(self, name): INPUT: - - ``name`` -- a string; the name of the map to remove + - ``name`` -- string; the name of the map to remove EXAMPLES:: diff --git a/src/sage/plot/complex_plot.pyx b/src/sage/plot/complex_plot.pyx index f1f2671a803..124209f257e 100644 --- a/src/sage/plot/complex_plot.pyx +++ b/src/sage/plot/complex_plot.pyx @@ -64,7 +64,7 @@ cdef inline double mag_to_lightness(double r, double rate=0.5) noexcept: INPUT: - - ``r`` -- a non-negative real number; the magnitude + - ``r`` -- a nonnegative real number; the magnitude - ``rate`` -- a positive real number; how quickly changes in magnitude affect changes in output lightness @@ -110,7 +110,7 @@ cdef inline double cyclic_logarithmic_mag_to_lightness(double r, double base=2) INPUT: - - ``r`` -- a non-negative real number; the magnitude + - ``r`` -- a nonnegative real number; the magnitude - ``base`` -- a real number (default: `2`); contours will appear at integer powers of ``base``. This should be greater than `1`. @@ -131,7 +131,7 @@ cdef inline double cyclic_logarithmic_mag_to_lightness(double r, double base=2) sage: from sage.plot.complex_plot import complex_to_rgb sage: complex_to_rgb([[0, 1, 10]], contoured=True, # abs tol 1e-4 - ....: contour_type="logarithmic") + ....: contour_type='logarithmic') array([[[1. , 0. , 0. ], [1. , 0.15 , 0.15 ], [0.98903595, 0. , 0. ]]]) @@ -139,7 +139,7 @@ cdef inline double cyclic_logarithmic_mag_to_lightness(double r, double base=2) We set contours to be multiples of `5` apart:: sage: complex_to_rgb([[0, 1, 10]], contoured=True, # abs tol 1e-4 - ....: contour_type="logarithmic", contour_base=5) + ....: contour_type='logarithmic', contour_base=5) array([[[1. , 0. , 0. ], [1. , 0.15 , 0.15 ], [0.93466172, 0. , 0. ]]]) @@ -161,7 +161,7 @@ cdef inline double cyclic_linear_mag_to_lightness(double r, double base=10) noex INPUT: - - ``r`` -- a non-negative real number; the magnitude + - ``r`` -- a nonnegative real number; the magnitude - ``base`` -- a positive real number (default: `10`); contours will appear at integer multiples of ``base`` @@ -182,7 +182,7 @@ cdef inline double cyclic_linear_mag_to_lightness(double r, double base=10) noex sage: from sage.plot.complex_plot import complex_to_rgb sage: complex_to_rgb([[1, 5, 11]], contoured=True, # abs tol 1e-4 - ....: contour_type="linear") + ....: contour_type='linear') array([[[1. , 0.1, 0.1], [0.9, 0. , 0. ], [1. , 0.1, 0.1]]]) @@ -193,7 +193,7 @@ cdef inline double cyclic_linear_mag_to_lightness(double r, double base=10) noex same, but the values for `5` and `11` should be:: sage: complex_to_rgb([[1, 5, 11]], contoured=True, # abs tol 1e-4 - ....: contour_type="linear", contour_base=3) + ....: contour_type='linear', contour_base=3) array([[[0.98333333, 0. , 0. ], [0.81666667, 0. , 0. ], [0.81666667, 0. , 0. ]]]) @@ -217,15 +217,15 @@ cdef inline double mag_and_arg_to_lightness(double r, double arg, INPUT: - - ``r`` -- a non-negative real number + - ``r`` -- a nonnegative real number - ``arg`` -- a real number - ``base`` -- a positive real number (default: ``2``); contours will appear at integer powers of ``base``. This should be greater than `1`. - - ``nphases`` -- a positive integer (default: ``10``); how many phase - contours to represent a change of argument by `2 \pi`. + - ``nphases`` -- positive integer (default: `10`); how many phase + contours to represent a change of argument by `2 \pi` OUTPUT: @@ -285,28 +285,28 @@ def complex_to_rgb(z_values, contoured=False, tiled=False, INPUT: - - ``z_values`` -- A grid of complex numbers, as a list of lists + - ``z_values`` -- a grid of complex numbers, as a list of lists - ``contoured`` -- boolean (default: ``False``); causes magnitude to be - indicated through contour-like adjustments to lightness. + indicated through contour-like adjustments to lightness - ``tiled`` -- boolean (default: ``False``); causes magnitude and argument to - be indicated through contour-like adjustments to lightness. + be indicated through contour-like adjustments to lightness - - ``nphases`` -- a positive integer (default: `10`); when ``tiled=True``, - this is the number of divisions the phase is divided into. + - ``nphases`` -- positive integer (default: 10); when ``tiled=True``, + this is the number of divisions the phase is divided into - ``contour_type`` -- either ``'logarithmic'``, or ``'linear'`` (default: ``'logarithmic'``); causes added contours to be of given type when ``contoured=True``. - - ``contour_base`` -- a positive integer; when ``contour_type`` is + - ``contour_base`` -- positive integer; when ``contour_type`` is ``'logarithmic'``, this sets logarithmic contours at multiples of ``contour_base`` apart. When ``contour_type`` is ``'linear'``, this sets contours at distances of ``contour_base`` apart. If ``None``, then a default is chosen depending on ``contour_type``. - - ``dark_rate`` -- a positive number (default: `0.5`); affects how quickly + - ``dark_rate`` -- a positive number (default: 0.5); affects how quickly magnitudes affect how light/dark the image is. When there are contours, this affects how visible each contour is. Large values (near `1.0`) have very strong, immediate effects, while small values (near `0.0`) have @@ -346,12 +346,12 @@ def complex_to_rgb(z_values, contoured=False, tiled=False, We can change contour types and the distances between contours:: sage: complex_to_rgb([[0, 1 + 1j, 3 + 4j]], # abs tol 1e-4 - ....: contoured=True, contour_type="logarithmic", contour_base=3) + ....: contoured=True, contour_type='logarithmic', contour_base=3) array([[[1. , 0. , 0. ], [0.99226756, 0.74420067, 0. ], [0.91751324, 0.81245954, 0. ]]]) sage: complex_to_rgb([[0, 1 + 1j, 3 + 4j]], # abs tol 1e-4 - ....: contoured=True, contour_type="linear", contour_base=3) + ....: contoured=True, contour_type='linear', contour_base=3) array([[[1. , 0.15 , 0.15 ], [0.91429774, 0.6857233 , 0. ], [0.81666667, 0.72315973, 0. ]]]) @@ -475,34 +475,34 @@ def complex_to_cmap_rgb(z_values, cmap='turbo', contoured=False, tiled=False, INPUT: - - ``z_values`` -- A grid of complex numbers, as a list of lists + - ``z_values`` -- a grid of complex numbers, as a list of lists - - ``cmap`` -- the string name of a matplotlib colormap, or an instance - of a matplotlib Colormap (default: ``'turbo'``). + - ``cmap`` -- the string name of a matplotlib colormap, or an instance + of a matplotlib Colormap (default: ``'turbo'``) - ``contoured`` -- boolean (default: ``False``); causes magnitude to be - indicated through contour-like adjustments to lightness. + indicated through contour-like adjustments to lightness - ``tiled`` -- boolean (default: ``False``); causes magnitude and argument to - be indicated through contour-like adjustments to lightness. + be indicated through contour-like adjustments to lightness - - ``nphases`` -- a positive integer (default: `10`); when ``tiled=True``, - this is the number of divisions the phase is divided into. + - ``nphases`` -- positive integer (default: 10); when ``tiled=True``, + this is the number of divisions the phase is divided into - ``contour_type`` -- either ``'logarithmic'``, or ``'linear'`` (default: ``'logarithmic'``); causes added contours to be of given type when ``contoured=True``. - - ``contour_base`` -- a positive integer; when ``contour_type`` is + - ``contour_base`` -- positive integer; when ``contour_type`` is ``'logarithmic'``, this sets logarithmic contours at multiples of ``contour_base`` apart. When ``contour_type`` is ``'linear'``, this sets contours at distances of ``contour_base`` apart. If ``None``, then a default is chosen depending on ``contour_type``. - - ``dark_rate`` -- a positive number (default: `0.5`); affects how quickly + - ``dark_rate`` -- a positive number (default: 0.5); affects how quickly magnitudes affect how light/dark the image is. When there are contours, - this affects how visible each contour is. Large values (near `1.0`) have - very strong, immediate effects, while small values (near `0.0`) have + this affects how visible each contour is. Large values (near 1.0) have + very strong, immediate effects, while small values (near 0.0) have gradual effects. OUTPUT: @@ -532,12 +532,12 @@ def complex_to_cmap_rgb(z_values, cmap='turbo', contoured=False, tiled=False, We can change contour types and the distances between contours:: sage: complex_to_cmap_rgb([[0, 1 + 1j, 3 + 4j]], contoured=True, # abs tol 1e-4 - ....: contour_type="logarithmic", contour_base=3) + ....: contour_type='logarithmic', contour_base=3) array([[[0.64362 , 0.98999 , 0.23356 ], [0.93239357, 0.81063338, 0.21955399], [0.95647342, 0.74861225, 0.14963982]]]) sage: complex_to_cmap_rgb([[0, 1 + 1j, 3 + 4j]], cmap='turbo', # abs tol 1e-4 - ....: contoured=True, contour_type="linear", contour_base=3) + ....: contoured=True, contour_type='linear', contour_base=3) array([[[0.71246796, 0.9919238 , 0.3816262 ], [0.92617785, 0.79322304, 0.14779989], [0.95156284, 0.72025117, 0.05370383]]]) @@ -649,7 +649,7 @@ def add_lightness_smoothing_to_rgb(rgb, delta): INPUT: - ``rgb`` -- a grid of length 3 tuples `(r, g, b)`, as an - `N \times M \times 3` numpy array. + `N \times M \times 3` numpy array - ``delta`` -- a grid of values as an `N \times M` numpy array; these represent how much to change the lightness of each `(r, g, b)`. Values @@ -702,14 +702,14 @@ def add_contours_to_rgb(rgb, delta, dark_rate=0.5): INPUT: - ``rgb`` -- a grid of length 3 tuples `(r, g, b)`, as an `N \times M - \times 3` numpy array. + \times 3` numpy array - ``delta`` -- a grid of values as an `N \times M` numpy array; these represent how much to change the lightness of each `(r, g, b)`. Values should be in `[-1, 1]`. - - ``dark_rate`` -- a positive number (default: `0.5`); affects how - strongly visible the contours appear. + - ``dark_rate`` -- a positive number (default: 0.5); affects how + strongly visible the contours appear OUTPUT: @@ -731,7 +731,6 @@ def add_contours_to_rgb(rgb, delta, dark_rate=0.5): Finally map `(h, l', s) \mapsto (r, g, b)` using the standard HLS-to-RGB formula. - EXAMPLES:: sage: # needs numpy @@ -771,11 +770,11 @@ class ComplexPlot(GraphicPrimitive): INPUT: - - ``rgb_data`` -- An array of colored points to be plotted. + - ``rgb_data`` -- an array of colored points to be plotted - - ``x_range`` -- A minimum and maximum x value for the plot. + - ``x_range`` -- a minimum and maximum x value for the plot - - ``y_range`` -- A minimum and maximum y value for the plot. + - ``y_range`` -- a minimum and maximum y value for the plot TESTS:: @@ -868,9 +867,9 @@ def complex_plot(f, x_range, y_range, contoured=False, tiled=False, cmap=None, - ``(ymin, ymax)`` -- 2-tuple, the range of ``y`` values - - ``cmap`` -- ``None``, or the string name of a matplotlib colormap, or an + - ``cmap`` -- ``None``, or the string name of a matplotlib colormap, or an instance of a matplotlib Colormap, or the special string ``'matplotlib'`` - (default: ``None``); If ``None``, then hues are chosen from a standard + (default: ``None``); if ``None``, then hues are chosen from a standard color wheel, cycling from red to yellow to blue. If ``matplotlib``, then hues are chosen from a preset matplotlib colormap. @@ -882,10 +881,10 @@ def complex_plot(f, x_range, y_range, contoured=False, tiled=False, cmap=None, magnitude along one contour is either twice or half the magnitude along adjacent contours. - - ``dark_rate`` -- a positive number (default: `0.5`); affects how quickly + - ``dark_rate`` -- a positive number (default: 0.5); affects how quickly magnitudes affect how light/dark the image is. When there are contours, - this affects how visible each contour is. Large values (near `1.0`) have - very strong, immediate effects, while small values (near `0.0`) have + this affects how visible each contour is. Large values (near 1.0) have + very strong, immediate effects, while small values (near 0.0) have gradual effects. - ``tiled`` -- boolean (default: ``False``); causes the magnitude to @@ -893,14 +892,14 @@ def complex_plot(f, x_range, y_range, contoured=False, tiled=False, cmap=None, ``contoured``, and in addition for there to be `10` evenly spaced phase contours. - - ``nphases`` -- a positive integer (default: `10`); when ``tiled=True``, - this is the number of divisions the phase is divided into. + - ``nphases`` -- positive integer (default: 10); when ``tiled=True``, + this is the number of divisions the phase is divided into - ``contour_type`` -- either ``'logarithmic'``, or ``'linear'`` (default: ``'logarithmic'``); causes added contours to be of given type when ``contoured=True``. - - ``contour_base`` -- a positive integer; when ``contour_type`` is + - ``contour_base`` -- positive integer; when ``contour_type`` is ``'logarithmic'``, this sets logarithmic contours at multiples of ``contour_base`` apart. When ``contour_type`` is ``'linear'``, this sets contours at distances of ``contour_base`` apart. If ``None``, then a @@ -908,7 +907,7 @@ def complex_plot(f, x_range, y_range, contoured=False, tiled=False, cmap=None, The following inputs may also be passed in as named parameters: - - ``plot_points`` -- integer (default: ``100``); number of points to + - ``plot_points`` -- integer (default: 100); number of points to plot in each direction of the grid - ``interpolation`` -- string (default: ``'catrom'``); the interpolation @@ -929,7 +928,6 @@ def complex_plot(f, x_range, y_range, contoured=False, tiled=False, cmap=None, See [NAR2018]_ for more information about colormap choice for scientific visualization. - EXAMPLES: Here we plot a couple of simple functions:: @@ -1237,7 +1235,7 @@ def rgb_to_hls(rgb): INPUT: - - ``rgb`` -- an `N \times 3` array of floats with values + - ``rgb`` -- an `N \times 3` array of floats with values in the range `[0, 1]`; the rgb values at each point. (Note that the input can actually be of any dimension, such as `N \times M \times 3`, as long as the last dimension has length `3`). @@ -1282,15 +1280,13 @@ def rgb_to_hls(rgb): raise ValueError("Last dimension of input array must be 3; " "shape {} was found.".format(rgb.shape)) in_shape = rgb.shape - rgb = np.array( - rgb, copy=False, dtype=np.dtype(float), ndmin=2 - ) + rgb = np.asarray(rgb, dtype=np.dtype(float)) rgb_max = rgb.max(-1) rgb_min = rgb.min(-1) l = (rgb_max + rgb_min)/2.0 # lightness hls = np.zeros_like(rgb) - delta = rgb.ptp(-1) + delta = np.ptp(rgb, -1) s = np.zeros_like(delta) ipos = delta > 0 @@ -1407,13 +1403,13 @@ def _v(m1, m2, hue): INPUT: - - ``m1`` -- An array of floats with values in the range `[0, 1]`. + - ``m1`` -- an array of floats with values in the range `[0, 1]` - - ``m2`` -- An array of floats with values in the range `[0, 1]` with - the same dimensions as ``m1``. + - ``m2`` -- an array of floats with values in the range `[0, 1]` with + the same dimensions as ``m1`` - - ``hue`` -- An array of floats with values in the range `[0, 1]` with - the same dimensions as ``m1``. + - ``hue`` -- an array of floats with values in the range `[0, 1]` with + the same dimensions as ``m1`` OUTPUT: diff --git a/src/sage/plot/contour_plot.py b/src/sage/plot/contour_plot.py index 2d94deaa6ff..26874790ec5 100644 --- a/src/sage/plot/contour_plot.py +++ b/src/sage/plot/contour_plot.py @@ -40,7 +40,7 @@ class ContourPlot(GraphicPrimitive): - ``yrange`` -- tuple of 2 floats indicating range for vertical direction - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -250,11 +250,11 @@ def contour_plot(f, xrange, yrange, **options): The following inputs must all be passed in as named parameters: - - ``plot_points`` -- integer (default: 100); number of points to plot + - ``plot_points`` -- integer (default: 100); number of points to plot in each direction of the grid. For old computers, 25 is fine, but should not be used to verify specific intersection points. - - ``fill`` -- bool (default: ``True``), whether to color in the area + - ``fill`` -- boolean (default: ``True``); whether to color in the area between contour lines - ``cmap`` -- a colormap (default: ``'gray'``), the name of @@ -269,25 +269,25 @@ def contour_plot(f, xrange, yrange, **options): is passed (or the option is not given), then the number of contour lines is determined automatically, and is usually about 5. - - ``linewidths`` -- integer or list of integer (default: None), if + - ``linewidths`` -- integer or list of integer (default: ``None``), if a single integer all levels will be of the width given, otherwise the levels will be plotted with the width in the order given. If the list is shorter than the number of contours, then the widths will be repeated cyclically. - - ``linestyles`` -- string or list of strings (default: None), the - style of the lines to be plotted, one of: ``"solid"``, ``"dashed"``, - ``"dashdot"``, ``"dotted"``, respectively ``"-"``, ``"--"``, - ``"-."``, ``":"``. If the list is shorter than the number of + - ``linestyles`` -- string or list of strings (default: ``None``), the + style of the lines to be plotted, one of: ``'solid'``, ``'dashed'``, + ``'dashdot'``, ``'dotted'``, respectively ``'-'``, ``'--'``, + ``'-.'``, ``':'``. If the list is shorter than the number of contours, then the styles will be repeated cyclically. - - ``labels`` -- boolean (default: ``False``) Show level labels or not. + - ``labels`` -- boolean (default: ``False``); show level labels or not The following options are to adjust the style and placement of labels, they have no effect if no labels are shown. - - ``label_fontsize`` -- integer (default: 9), the font size of - the labels. + - ``label_fontsize`` -- integer (default: 9); the font size of + the labels - ``label_colors`` -- string or sequence of colors (default: None) If a string, gives the name of a single color with which @@ -299,36 +299,36 @@ def contour_plot(f, xrange, yrange, **options): otherwise True), controls whether the underlying contour is removed or not. - - ``label_inline_spacing`` -- integer (default: 3), When inline, + - ``label_inline_spacing`` -- integer (default: 3); when inline, this is the amount of contour that is removed from each side, in pixels. - - ``label_fmt`` -- a format string (default: "%1.2f"), this is + - ``label_fmt`` -- a format string (default: ``"%1.2f"``), this is used to get the label text from the level. This can also be a dictionary with the contour levels as keys and corresponding text string labels as values. It can also be any callable which returns a string when called with a numeric contour level. - - ``colorbar`` -- boolean (default: ``False``) Show a colorbar or not. + - ``colorbar`` -- boolean (default: ``False``); show a colorbar or not The following options are to adjust the style and placement of colorbars. They have no effect if a colorbar is not shown. - - ``colorbar_orientation`` -- string (default: 'vertical'), + - ``colorbar_orientation`` -- string (default: ``'vertical'``), controls placement of the colorbar, can be either 'vertical' or 'horizontal' - ``colorbar_format`` -- a format string, this is used to format - the colorbar labels. + the colorbar labels - - ``colorbar_spacing`` -- string (default: 'proportional'). If + - ``colorbar_spacing`` -- string (default: ``'proportional'``); if 'proportional', make the contour divisions proportional to values. If 'uniform', space the colorbar divisions uniformly, without regard for numeric values. - ``legend_label`` -- the label for this item in the legend - - ``region`` -- (default: None) If region is given, it must be a function + - ``region`` -- (default: ``None``) if region is given, it must be a function of two variables. Only segments of the surface where region(x,y) returns a number >0 will be included in the plot. @@ -880,7 +880,6 @@ def f(x,y): return cos(x) + sin(y) sage: x,y = SR.var('x,y', domain='real') sage: contour_plot(log(x) + log(y), (-1, 5), (-1, 5)) Graphics object consisting of 1 graphics primitive - """ from sage.plot.all import Graphics from sage.plot.misc import setup_for_eval_on_grid @@ -950,7 +949,7 @@ def f(x,y): return cos(x) + sin(y) # ...make it actually the const_z0 function. xy_data_array.fill(z0) - # We're going to set fill=True in a momemt, so we need to + # We're going to set fill=True in a moment, so we need to # prepend an entry to the cmap so that the user's original # cmap winds up in the right place. if "cmap" in options: @@ -1058,21 +1057,21 @@ def implicit_plot(f, xrange, yrange, **options): in each direction of the grid - ``fill`` -- boolean (default: ``False``); if ``True``, fill the region - `f(x, y) < 0`. + `f(x, y) < 0` - - ``fillcolor`` -- string (default: ``'blue'``), the color of the region + - ``fillcolor`` -- string (default: ``'blue'``); the color of the region where `f(x,y) < 0` if ``fill = True``. Colors are defined in :mod:`sage.plot.colors`; try ``colors?`` to see them all. - - ``linewidth`` -- integer (default: None), if a single integer all levels + - ``linewidth`` -- integer (default: ``None``); if a single integer all levels will be of the width given, otherwise the levels will be plotted with the widths in the order given. - - ``linestyle`` -- string (default: None), the style of the line to be - plotted, one of: ``"solid"``, ``"dashed"``, ``"dashdot"`` or - ``"dotted"``, respectively ``"-"``, ``"--"``, ``"-."``, or ``":"``. + - ``linestyle`` -- string (default: ``None``); the style of the line to be + plotted, one of: ``'solid'``, ``'dashed'``, ``'dashdot'`` or + ``'dotted'``, respectively ``'-'``, ``'--'``, ``'-.'``, or ``':'``. - - ``color`` -- string (default: ``'blue'``), the color of the plot. Colors + - ``color`` -- string (default: ``'blue'``); the color of the plot. Colors are defined in :mod:`sage.plot.colors`; try ``colors?`` to see them all. If ``fill = True``, then this sets only the color of the border of the plot. See ``fillcolor`` for setting the color of the fill region. @@ -1085,17 +1084,17 @@ def implicit_plot(f, xrange, yrange, **options): ``basex`` sets the base of the logarithm along the horizontal axis and ``basey`` sets the base along the vertical axis. - - ``scale`` -- (default: ``"linear"``) string. The scale of the axes. - Possible values are ``"linear"``, ``"loglog"``, ``"semilogx"``, - ``"semilogy"``. + - ``scale`` -- (default: ``'linear'``) string. The scale of the axes. + Possible values are ``'linear'``, ``'loglog'``, ``'semilogx'``, + ``'semilogy'``. The scale can be also be given as single argument that is a list or tuple ``(scale, base)`` or ``(scale, basex, basey)``. - The ``"loglog"`` scale sets both the horizontal and vertical axes to - logarithmic scale. The ``"semilogx"`` scale sets the horizontal axis - to logarithmic scale. The ``"semilogy"`` scale sets the vertical axis - to logarithmic scale. The ``"linear"`` scale is the default value + The ``'loglog'`` scale sets both the horizontal and vertical axes to + logarithmic scale. The ``'semilogx'`` scale sets the horizontal axis + to logarithmic scale. The ``'semilogy'`` scale sets the vertical axis + to logarithmic scale. The ``'linear'`` scale is the default value when :class:`~sage.plot.graphics.Graphics` is initialized. .. WARNING:: @@ -1189,13 +1188,13 @@ def f(x,y): return x**2 + y**2 - 2 You can even change the color of the plot:: - sage: implicit_plot(x^2 + y^2 == 2, (x,-3,3), (y,-3,3), color="red") + sage: implicit_plot(x^2 + y^2 == 2, (x,-3,3), (y,-3,3), color='red') Graphics object consisting of 1 graphics primitive .. PLOT:: x, y =var("x y") - g = implicit_plot(x**2 + y**2 == 2, (x,-3,3), (y,-3,3), color="red") + g = implicit_plot(x**2 + y**2 == 2, (x,-3,3), (y,-3,3), color='red') sphinx_plot(g) The color of the fill region can be changed:: @@ -1206,7 +1205,7 @@ def f(x,y): return x**2 + y**2 - 2 .. PLOT:: x, y =var("x y") - g = implicit_plot(x**2 + y**2 == 2, (x,-3,3), (y,-3,3), fill=True, fillcolor="red") + g = implicit_plot(x**2 + y**2 == 2, (x,-3,3), (y,-3,3), fill=True, fillcolor='red') sphinx_plot(g) Here is a beautiful (and long) example which also tests that all @@ -1397,14 +1396,14 @@ def f(x,y): def region_plot(f, xrange, yrange, **options): r""" ``region_plot`` takes a boolean function of two variables, `f(x, y)` - and plots the region where f is True over the specified + and plots the region where f is ``True`` over the specified ``xrange`` and ``yrange`` as demonstrated below. ``region_plot(f, (xmin,xmax), (ymin,ymax), ...)`` INPUT: - - ``f`` -- a boolean function or a list of boolean functions of + - ``f`` -- boolean function or a list of boolean functions of two variables - ``(xmin, xmax)`` -- 2-tuple, the range of ``x`` values OR 3-tuple @@ -1413,7 +1412,7 @@ def region_plot(f, xrange, yrange, **options): - ``(ymin, ymax)`` -- 2-tuple, the range of ``y`` values OR 3-tuple ``(y,ymin,ymax)`` - - ``plot_points`` -- integer (default: 100); number of points to plot + - ``plot_points`` -- integer (default: 100); number of points to plot in each direction of the grid - ``incol`` -- a color (default: ``'blue'``), the color inside the region @@ -1429,11 +1428,11 @@ def region_plot(f, xrange, yrange, **options): (``'black'`` if ``borderwidth`` or ``borderstyle`` is specified but not ``bordercol``) - - ``borderstyle`` -- string (default: ``'solid'``), one of ``'solid'``, + - ``borderstyle`` -- string (default: ``'solid'``); one of ``'solid'``, ``'dashed'``, ``'dotted'``, ``'dashdot'``, respectively ``'-'``, - ``'--'``, ``':'``, ``'-.'``. + ``'--'``, ``':'``, ``'-.'`` - - ``borderwidth`` -- integer (default: ``None``), the width of the + - ``borderwidth`` -- integer (default: ``None``); the width of the border in pixels - ``alpha`` -- (default: 1) how transparent the fill is; a number @@ -1447,20 +1446,19 @@ def region_plot(f, xrange, yrange, **options): ``basex`` sets the base of the logarithm along the horizontal axis and ``basey`` sets the base along the vertical axis. - - ``scale`` -- (default: ``"linear"``) string. The scale of the axes. - Possible values are ``"linear"``, ``"loglog"``, ``"semilogx"``, - ``"semilogy"``. + - ``scale`` -- string (default: ``'linear'``); the scale of the axes. + Possible values are ``'linear'``, ``'loglog'``, ``'semilogx'``, + ``'semilogy'``. The scale can be also be given as single argument that is a list or tuple ``(scale, base)`` or ``(scale, basex, basey)``. - The ``"loglog"`` scale sets both the horizontal and vertical axes to - logarithmic scale. The ``"semilogx"`` scale sets the horizontal axis - to logarithmic scale. The ``"semilogy"`` scale sets the vertical axis - to logarithmic scale. The ``"linear"`` scale is the default value + The ``'loglog'`` scale sets both the horizontal and vertical axes to + logarithmic scale. The ``'semilogx'`` scale sets the horizontal axis + to logarithmic scale. The ``'semilogy'`` scale sets the vertical axis + to logarithmic scale. The ``'linear'`` scale is the default value when :class:`~sage.plot.graphics.Graphics` is initialized. - EXAMPLES: Here we plot a simple function of two variables:: diff --git a/src/sage/plot/density_plot.py b/src/sage/plot/density_plot.py index a22394ad2c1..84d08518a0b 100644 --- a/src/sage/plot/density_plot.py +++ b/src/sage/plot/density_plot.py @@ -40,7 +40,7 @@ class DensityPlot(GraphicPrimitive): - ``yrange`` -- tuple of 2 floats indicating range for vertical direction - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -65,7 +65,7 @@ class DensityPlot(GraphicPrimitive): """ def __init__(self, xy_data_array, xrange, yrange, options): """ - Initializes base class DensityPlot. + Initialize base class ``DensityPlot``. EXAMPLES:: @@ -85,7 +85,7 @@ def __init__(self, xy_data_array, xrange, yrange, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: @@ -179,13 +179,12 @@ def density_plot(f, xrange, yrange, **options): Colormap. Type: ``import matplotlib.cm; matplotlib.cm.datad.keys()`` for available colormap names. - - ``interpolation`` -- string (default: ``'catrom'``), the interpolation + - ``interpolation`` -- string (default: ``'catrom'``); the interpolation method to use: ``'bilinear'``, ``'bicubic'``, ``'spline16'``, ``'spline36'``, ``'quadric'``, ``'gaussian'``, ``'sinc'``, ``'bessel'``, ``'mitchell'``, ``'lanczos'``, ``'catrom'``, ``'hermite'``, ``'hanning'``, ``'hamming'``, ``'kaiser'`` - EXAMPLES: Here we plot a simple function of two variables. Note that @@ -290,7 +289,7 @@ def f(x,y): return x**2 * cos(x*y) sage: density_plot((x*y)^(1/2), (x,0,3), (y,0,500), aspect_ratio=.01) Graphics object consisting of 1 graphics primitive - Default ``aspect_ratio`` is ``"automatic"``, and that should work too:: + Default ``aspect_ratio`` is ``'automatic'``, and that should work too:: sage: density_plot((x*y)^(1/2), (x,0,3), (y,0,500)) Graphics object consisting of 1 graphics primitive diff --git a/src/sage/plot/disk.py b/src/sage/plot/disk.py index e7f3f4475cf..862ba12afc9 100644 --- a/src/sage/plot/disk.py +++ b/src/sage/plot/disk.py @@ -40,7 +40,7 @@ class Disk(GraphicPrimitive): - ``angle`` -- beginning and ending angles of disk (i.e. angle extent of sector/wedge) - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -66,7 +66,7 @@ class Disk(GraphicPrimitive): """ def __init__(self, point, r, angle, options): """ - Initializes base class ``Disk``. + Initialize base class ``Disk``. EXAMPLES:: @@ -94,7 +94,7 @@ def __init__(self, point, r, angle, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: @@ -109,7 +109,6 @@ def get_minmax_data(self): 6.0 sage: d['ymax'] 5.0 - """ from sage.plot.plot import minmax_data return minmax_data([self.x - self.r, self.x + self.r], @@ -164,7 +163,6 @@ def _render_on_subplot(self, subplot): sage: f = tmp_filename(ext='.pdf') sage: p = disk((0,0), 5, (0, pi/4), alpha=0.5) sage: p.save(f) - """ import matplotlib.patches as patches options = self.options() @@ -190,8 +188,7 @@ def plot3d(self, z=0, **kwds): INPUT: - - - ``z`` -- optional 3D height above `xy`-plane. + - ``z`` -- (optional) 3D height above `xy`-plane AUTHORS: @@ -349,7 +346,7 @@ def disk(point, radius, angle, **options): Verify that :issue:`36153` is fixed:: - sage: D = disk((0, 0), 5, (0, pi/2), legend_label="test") + sage: D = disk((0, 0), 5, (0, pi/2), legend_label='test') """ from sage.plot.all import Graphics g = Graphics() diff --git a/src/sage/plot/ellipse.py b/src/sage/plot/ellipse.py index 02c598c793f..8722d6fdb83 100644 --- a/src/sage/plot/ellipse.py +++ b/src/sage/plot/ellipse.py @@ -48,7 +48,7 @@ class Ellipse(GraphicPrimitive): """ def __init__(self, x, y, r1, r2, angle, options): """ - Initializes base class ``Ellipse``. + Initialize base class ``Ellipse``. TESTS:: @@ -248,22 +248,22 @@ def ellipse(center, r1, r2, angle=0, **options): OPTIONS: - - ``alpha`` -- (default: 1); transparency + - ``alpha`` -- (default: 1) transparency - - ``fill`` -- (default: ``False``); whether to fill the ellipse or not + - ``fill`` -- (default: ``False``) whether to fill the ellipse or not - - ``thickness`` -- (default: 1); thickness of the line + - ``thickness`` -- (default: 1) thickness of the line - - ``linestyle`` -- (default: ``'solid'``); The style of the line, which is one + - ``linestyle`` -- (default: ``'solid'``) the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or ``'--'``, - ``':'``, ``'-'``, ``'-.'``, respectively. + ``':'``, ``'-'``, ``'-.'``, respectively - - ``edgecolor`` -- (default: 'black'); color of the contour + - ``edgecolor`` -- (default: ``'black'``) color of the contour - - ``facecolor`` -- (default: 'red'); color of the filling + - ``facecolor`` -- (default: ``'red'``) color of the filling - ``rgbcolor`` -- 2D or 3D plotting. This option overrides - ``edgecolor`` and ``facecolor`` for 2D plotting. + ``edgecolor`` and ``facecolor`` for 2D plotting - ``legend_label`` -- the label for this item in the legend @@ -285,17 +285,17 @@ def ellipse(center, r1, r2, angle=0, **options): More complicated examples with tilted axes and drawing options:: sage: from math import pi - sage: ellipse((0,0), 3, 1, pi/6, fill=True, alpha=0.3, linestyle="dashed") + sage: ellipse((0,0), 3, 1, pi/6, fill=True, alpha=0.3, linestyle='dashed') Graphics object consisting of 1 graphics primitive .. PLOT:: - E = ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3,linestyle="dashed") + E = ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3,linestyle='dashed') sphinx_plot(E) other way to indicate dashed linestyle:: - sage: ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3,linestyle="--") + sage: ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3,linestyle='--') Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -350,7 +350,7 @@ def ellipse(center, r1, r2, angle=0, **options): Verify that :issue:`36153` does not arise:: - sage: E = ellipse((0,0), 2, 1, legend_label="test") + sage: E = ellipse((0,0), 2, 1, legend_label='test') """ from sage.plot.all import Graphics g = Graphics() diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index a84d162cb56..1ade8565660 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -55,7 +55,7 @@ def is_Graphics(x): """ - Return True if `x` is a Graphics object. + Return ``True`` if `x` is a Graphics object. EXAMPLES:: @@ -99,7 +99,6 @@ def _parse_figsize(figsize): sage: _parse_figsize(5) # tol 1.0e-13 (5.0, 3.75) - """ from matplotlib import rcParams if isinstance(figsize, (list, tuple)): @@ -212,9 +211,7 @@ def set_aspect_ratio(self, ratio): INPUT: - - - ``ratio`` -- a positive real number or 'automatic' - + - ``ratio`` -- a positive real number or 'automatic' EXAMPLES: We create a plot of the upper half of a circle, but it doesn't look round because the aspect ratio is off:: @@ -292,7 +289,7 @@ def legend(self, show=None): INPUT: - - ``show`` -- (default: ``None``) a boolean + - ``show`` -- (default: ``None``) a boolean If called with no input, return the current legend setting. @@ -317,7 +314,7 @@ def legend(self, show=None): sage: P.legend() False sage: P.legend(True) - sage: P # show with the legend + sage: P # show with the legend Graphics object consisting of 1 graphics primitive """ if show is None: @@ -331,15 +328,15 @@ def set_legend_options(self, **kwds): INPUT: - - ``title`` -- (default: None) string, the legend title + - ``title`` -- (default: ``None``) string, the legend title - ``ncol`` -- (default: 1) positive integer, the number of columns - - ``columnspacing`` -- (default: None) the spacing between columns + - ``columnspacing`` -- (default: ``None``) the spacing between columns - - ``borderaxespad`` -- (default: None) float, length between the axes and the legend + - ``borderaxespad`` -- (default: ``None``) float, length between the axes and the legend - - ``back_color`` -- (default: 'white') This parameter can be a string + - ``back_color`` -- (default: ``'white'``) this parameter can be a string denoting a color or an RGB tuple. The string can be a color name as in ('red', 'green', 'yellow', ...) or a floating point number like '0.8' which gets expanded to (0.8, 0.8, 0.8). The @@ -352,7 +349,7 @@ def set_legend_options(self, **kwds): - ``labelspacing`` -- (default: 0.02) float, vertical space between legend entries - - ``loc`` -- (default: 'best') May be a string, an integer or a tuple. String or + - ``loc`` -- (default: ``'best'``) may be a string, an integer or a tuple. String or integer inputs must be one of the following: - 0, 'best' @@ -380,30 +377,36 @@ def set_legend_options(self, **kwds): - Tuple arguments represent an absolute (x, y) position on the plot in axes coordinates (meaning from 0 to 1 in each direction). - - ``markerscale`` -- (default: 0.6) float, how much to scale the markers in the legend. + - ``markerscale`` -- (default: 0.6) float, how much to scale the markers in the legend - ``numpoints`` -- (default: 2) integer, the number of points in the legend for line - ``borderpad`` -- (default: 0.6) float, the fractional whitespace inside the legend border (between 0 and 1) - - ``font_family`` -- (default: 'sans-serif') string, one of 'serif', 'sans-serif', - 'cursive', 'fantasy', 'monospace' + - ``font_family`` -- (default: ``'sans-serif'``) string, one of + ``'serif'``, ``'sans-serif'``, ``'cursive'``, ``'fantasy'``, + ``'monospace'`` - - ``font_style`` -- (default: 'normal') string, one of 'normal', 'italic', 'oblique' + - ``font_style`` -- (default: ``'normal'``) string, one of + ``'normal'``, ``'italic'``, ``'oblique'`` - - ``font_variant`` -- (default: 'normal') string, one of 'normal', 'small-caps' + - ``font_variant`` -- (default: ``'normal'``) string, one of + ``'normal'``, ``'small-caps'`` - - ``font_weight`` -- (default: 'medium') string, one of 'black', 'extra bold', 'bold', - 'semibold', 'medium', 'normal', 'light' + - ``font_weight`` -- (default: ``'medium'``) string, one of + ``'black'``, ``'extra bold'``, ``'bold'``, ``'semibold'``, + ``'medium'``, ``'normal'``, ``'light'`` - - ``font_size`` -- (default: 'medium') string, one of 'xx-small', 'x-small', 'small', - 'medium', 'large', 'x-large', 'xx-large' or an absolute font size (e.g. 12) + - ``font_size`` -- (default: ``'medium'``) string, one of + ``'xx-small'``, ``'x-small'``, ``'small'``, ``'medium'``, + ``'large'``, ``'x-large'``, ``'xx-large'``, or an absolute font size + (e.g. 12) - - ``shadow`` -- (default: ``True``) boolean -- draw a shadow behind the legend + - ``shadow`` -- boolean (default: ``True``); draw a shadow behind the legend - - ``fancybox`` -- (default: ``False``) a boolean. If True, draws a frame with a round - fancybox. + - ``fancybox`` -- boolean (default: ``False``); if + ``True``, draws a frame with a round fancybox These are all keyword arguments. @@ -436,7 +439,17 @@ def set_legend_options(self, **kwds): :: - sage: p.set_legend_options(loc=(0.5,0.5)); p # aligns the bottom of the box to the center # needs sage.symbolic + sage: p.set_legend_options(loc=(0.5,0.5)); p # aligns the bottom of the box to the center # needs sage.symbolic + Graphics object consisting of 1 graphics primitive + + The parameters ``loc`` and ``borderaxespad`` can be altered + in order to place the legend below the x-axis label or to + the left of the y-axis label:: + + sage: p = line([(0, 0), (1, 1)], legend_label='test') + sage: p.axes_labels(['X-Label', 'Y-Label']) # adding labels for axes + sage: p.set_legend_options(loc=8, borderaxespad=-7.5-0.01*p.fontsize()) + sage: p Graphics object consisting of 1 graphics primitive """ if len(kwds) == 0: @@ -446,8 +459,8 @@ def set_legend_options(self, **kwds): def get_axes_range(self): """ - Returns a dictionary of the range of the axes for this graphics - object. This is fall back to the ranges in get_minmax_data() for + Return a dictionary of the range of the axes for this graphics + object. This is fall back to the ranges in ``get_minmax_data()`` for any value which the user has not explicitly set. .. warning:: @@ -475,9 +488,7 @@ def set_axes_range(self, xmin=None, xmax=None, ymin=None, ymax=None): INPUT: - - - ``xmin, xmax, ymin, ymax`` -- floats - + - ``xmin``, ``xmax``, ``ymin``, ``ymax`` -- floats EXAMPLES:: @@ -497,7 +508,7 @@ def set_axes_range(self, xmin=None, xmax=None, ymin=None, ymax=None): def _get_axes_range_dict(self): """ - Returns the underlying dictionary used to store the user's + Return the underlying dictionary used to store the user's custom ranges for the axes on this object. EXAMPLES:: @@ -590,8 +601,7 @@ def fontsize(self, s=None): INPUT: - - - ``s`` -- integer, a font size in points. + - ``s`` -- integer, a font size in points If called with no input, return the current fontsize. @@ -625,7 +635,7 @@ def axes_labels_size(self, s=None): INPUT: - ``s`` -- float, relative size of axes labels w.r.t. to the tick marks, - the size of the tick marks being set by :meth:`fontsize`. + the size of the tick marks being set by :meth:`fontsize` If called with no input, return the current relative size. @@ -643,7 +653,6 @@ def axes_labels_size(self, s=None): sage: p # needs sage.symbolic Graphics object consisting of 1 graphics primitive - """ if s is None: try: @@ -660,9 +669,7 @@ def axes(self, show=None): INPUT: - - - ``show`` -- bool - + - ``show`` -- boolean If called with no input, return the current axes setting. @@ -708,10 +715,8 @@ def axes_color(self, c=None): INPUT: - - - ``c`` -- an RGB color 3-tuple, where each tuple entry - is a float between 0 and 1 - + - ``c`` -- an RGB color 3-tuple, where each tuple entry + is a float between 0 and 1 EXAMPLES: We create a line, which has like everything a default axes color of black. @@ -753,15 +758,13 @@ def axes_labels(self, l=None): INPUT: - - - ``l`` -- (default: None) a list of two strings or - None - + - ``l`` -- (default: ``None``) a list of two strings or + ``None`` OUTPUT: a 2-tuple of strings - If l is None, returns the current ``axes_labels``, - which is itself by default None. The default labels are both + If l is ``None``, returns the current ``axes_labels``, + which is itself by default ``None``. The default labels are both empty. EXAMPLES: We create a plot and put x and y axes labels on it. @@ -820,8 +823,7 @@ def axes_label_color(self, c=None): INPUT: - - - ``c`` -- an RGB 3-tuple of numbers between 0 and 1 + - ``c`` -- an RGB 3-tuple of numbers between 0 and 1 If called with no input, return the current axes_label_color @@ -868,8 +870,7 @@ def axes_width(self, w=None): INPUT: - - - ``w`` -- a float + - ``w`` -- a float If called with no input, return the current @@ -909,11 +910,10 @@ def tick_label_color(self, c=None): INPUT: - - - ``c`` -- an RGB 3-tuple of numbers between 0 and 1 + - ``c`` -- an RGB 3-tuple of numbers between 0 and 1 - If called with no input, return the current tick_label_color + If called with no input, return the current ``tick_label_color`` setting. EXAMPLES:: @@ -940,9 +940,7 @@ def _repr_(self): r""" Return a string representation of the graphics objects. - OUTPUT: - - String. + OUTPUT: string EXAMPLES: @@ -976,7 +974,7 @@ def _repr_(self): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -1016,9 +1014,7 @@ def __str__(self): r""" Return string representation of this plot. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1036,7 +1032,7 @@ def __str__(self): def __getitem__(self, i): """ - Returns the ith graphics primitive object: + Return the i-th graphics primitive object: EXAMPLES:: @@ -1063,7 +1059,7 @@ def __len__(self): def __delitem__(self, i): """ - If G is of type Graphics, then del(G[i]) removes the ith distinct + If G is of type Graphics, then del(G[i]) removes the i-th distinct graphic primitive making up that object. EXAMPLES:: @@ -1111,7 +1107,7 @@ def __radd__(self, other): Compute and return other + this graphics object. This only works when other is a Python int equal to 0. In all other - cases a :class:`TypeError` is raised. The main reason for this + cases a :exc:`TypeError` is raised. The main reason for this function is to make summing a list of graphics objects easier. EXAMPLES:: @@ -1232,7 +1228,7 @@ def __add__(self, other): def add_primitive(self, primitive): """ - Adds a primitive to this graphics object. + Add a primitive to this graphics object. EXAMPLES: @@ -1273,7 +1269,7 @@ def plot(self): ... TypeError: ...plot() takes 1 positional argument but 2 were given - sage: S.plot(hey="hou") + sage: S.plot(hey='hou') Traceback (most recent call last): ... TypeError: ...plot() got an unexpected keyword argument 'hey' @@ -1353,14 +1349,15 @@ def _set_scale(self, subplot, scale=None, base=None): INPUT: - - ``subplot`` -- matplotlib Axes instance. + - ``subplot`` -- matplotlib Axes instance - ``scale`` -- the scale of the figure. Values it can take are - ``"linear"``, ``"loglog"``, ``"semilogx"``, ``"semilogy"``. See + ``'linear'``, ``'loglog'``, ``'semilogx'``, ``'semilogy'``. See :meth:`show` for other options it can take. - ``base`` -- the base of the logarithm if a logarithmic scale is - set. See :meth:`show` for the options it can take. + set. See :meth:`show` for the options it can take OUTPUT: + The scale in the form of a tuple: (xscale, yscale, basex, basey) EXAMPLES:: @@ -1495,10 +1492,10 @@ def show(self, **kwds): inches, at the default ``dpi`` of 100 dpi, which is just shy of the maximum allowed value of 32768 dots (pixels). - - ``fig_tight`` -- (default: ``True``) whether to clip the drawing - tightly around drawn objects. If True, then the resulting + - ``fig_tight`` -- boolean (default: ``True``); whether to clip the drawing + tightly around drawn objects. If ``True``, then the resulting image will usually not have dimensions corresponding to - ``figsize``. If False, the resulting image will have + ``figsize``. If ``False``, the resulting image will have dimensions corresponding to ``figsize``. - ``aspect_ratio`` -- the perceived height divided by the @@ -1511,7 +1508,7 @@ def show(self, **kwds): - ``axes`` -- (default: ``True``) - - ``axes_labels`` -- (default: None) list (or tuple) of two + - ``axes_labels`` -- (default: ``None``) list (or tuple) of two strings; the first is used as the label for the horizontal axis, and the second for the vertical axis. @@ -1523,9 +1520,9 @@ def show(self, **kwds): integer; used for axes labels; if you make this very large, you may have to increase figsize to see all labels. - - ``frame`` -- (default: ``False``) draw a frame around the image + - ``frame`` -- boolean (default: ``False``); draw a frame around the image - - ``gridlines`` -- (default: None) can be any of the following: + - ``gridlines`` -- (default: ``None``) can be any of the following: - None, False: do not add grid lines. @@ -1552,33 +1549,34 @@ def show(self, **kwds): - ``gridlinesstyle, hgridlinesstyle, vgridlinesstyle`` - - (default: None) a dictionary of MATPLOTLIB options for the + (default: ``None``); a dictionary of MATPLOTLIB options for the rendering of the grid lines, the horizontal grid lines or the vertical grid lines, respectively. - - ``transparent`` -- (default: ``False``) If True, make the background transparent. + - ``transparent`` -- boolean (default: ``False``); if True, make the + background transparent - - ``axes_pad`` -- (default: 0.02 on ``"linear"`` scale, 1 on - ``"log"`` scale). + - ``axes_pad`` -- (default: 0.02 on ``'linear'`` scale, 1 on + ``'log'`` scale) - - In the ``"linear"`` scale, it determines the percentage of the + - In the ``'linear'`` scale, it determines the percentage of the axis range that is added to each end of each axis. This helps avoid problems like clipping lines because of line-width, etc. To get axes that are exactly the specified limits, set ``axes_pad`` to zero. - - On the ``"log"`` scale, it determines the exponent of the + - On the ``'log'`` scale, it determines the exponent of the fraction of the minimum (resp. maximum) that is subtracted from the minimum (resp. added to the maximum) value of the axis. For instance if the minimum is `m` and the base of the axis is `b` then the new minimum after padding the axis will be `m - m/b^{\mathrm{axes\_pad}}`. - - ``ticks_integer`` -- (default: ``False``) guarantee that the ticks + - ``ticks_integer`` -- boolean (default: ``False``); guarantee that the ticks are integers (the ``ticks`` option, if specified, will override this) - - ``ticks`` -- A matplotlib locator for the major ticks, or + - ``ticks`` -- a matplotlib locator for the major ticks, or a number. There are several options. For more information about locators, type ``from matplotlib import ticker`` and then ``ticker?``. @@ -1603,14 +1601,14 @@ def show(self, **kwds): ticks at the locations specified. This includes the case of of the empty list, which will give no ticks. See examples. - - ``tick_formatter`` -- A matplotlib formatter for the major + - ``tick_formatter`` -- a matplotlib formatter for the major ticks. There are several options. For more information about formatters, type ``from matplotlib import ticker`` and then ``ticker?``. If the value of this keyword is a single item, then this will give the formatting for the horizontal axis *only* (except for - the ``"latex"`` option). If it is a list or tuple, the first + the ``'latex'`` option). If it is a list or tuple, the first is for the horizontal axis, the second for the vertical axis. The options are below: @@ -1628,7 +1626,7 @@ def show(self, **kwds): This should only be used with the ``ticks`` option using nice rational multiples of that constant! - - If one of the entries is the string ``"latex"``, then the + - If one of the entries is the string ``'latex'``, then the formatting will be nice typesetting of the ticks. This is intended to be used when the tick locator for at least one of the axes is a list including some symbolic elements. This uses @@ -1636,9 +1634,9 @@ def show(self, **kwds): use an external LaTeX compiler, then set the keyword option ``typeset``. See examples. - - ``title`` -- (default: None) The title for the plot + - ``title`` -- (default: ``None``) the title for the plot - - ``title_pos`` -- (default: None) The position of the title for the + - ``title_pos`` -- (default: ``None``) the position of the title for the plot. It must be a tuple or a list of two real numbers ``(x_pos, y_pos)`` which indicate the relative position of the title within the plot. The plot itself can be considered to @@ -1656,13 +1654,13 @@ def show(self, **kwds): present in the list. Each entry of the list of strings must be provided with a corresponding number in the first entry of ``ticks`` to indicate its position on the axis. To typeset the - strings with ``"latex"`` enclose them within ``"$"`` symbols. To + strings with ``'latex'`` enclose them within ``'$'`` symbols. To have similar custom formatting of the labels along the vertical axis, the second entry must be a list of strings and the second entry of ``ticks`` must also be a list of numbers which give the positions of the labels. See the examples below. - - ``show_legend`` -- (default: None) If True, show the legend + - ``show_legend`` -- (default: ``None``) if ``True``, show the legend - ``legend_*`` -- all the options valid for :meth:`set_legend_options` prefixed with ``legend_`` @@ -1673,53 +1671,53 @@ def show(self, **kwds): ``basex`` sets the base of the logarithm along the horizontal axis and ``basey`` sets the base along the vertical axis. - - ``scale`` -- (default: ``"linear"``) string. The scale of the axes. + - ``scale`` -- (default: ``'linear'``) string. The scale of the axes. Possible values are - - ``"linear"`` -- linear scaling of both the axes - - ``"loglog"`` -- sets both the horizontal and vertical axes to + - ``'linear'`` -- linear scaling of both the axes + - ``'loglog'`` -- sets both the horizontal and vertical axes to logarithmic scale - - ``"semilogx"`` -- sets only the horizontal axis to logarithmic - scale. - - ``"semilogy"`` -- sets only the vertical axis to logarithmic - scale. + - ``'semilogx'`` -- sets only the horizontal axis to logarithmic + scale + - ``'semilogy'`` -- sets only the vertical axis to logarithmic + scale The scale can be also be given as single argument that is a list or tuple ``(scale, base)`` or ``(scale, basex, basey)``. - .. note:: + .. NOTE:: - - If the ``scale`` is ``"linear"``, then irrespective of what + - If the ``scale`` is ``'linear'``, then irrespective of what ``base`` is set to, it will default to 10 and will remain unused. - - ``xmin`` -- starting x value in the rendered figure. + - ``xmin`` -- starting x value in the rendered figure - - ``xmax`` -- ending x value in the rendered figure. + - ``xmax`` -- ending x value in the rendered figure - - ``ymin`` -- starting y value in the rendered figure. + - ``ymin`` -- starting y value in the rendered figure - - ``ymax`` -- ending y value in the rendered figure. + - ``ymax`` -- ending y value in the rendered figure - - ``flip_x`` -- (default: ``False``) boolean. If True, flip the horizontal - axis. + - ``flip_x`` -- boolean (default: ``False``); if ``True``, flip the horizontal + axis - - ``flip_y`` -- (default: ``False``) boolean. If True, flip the vertical - axis. + - ``flip_y`` -- boolean (default: ``False``); if ``True``, flip the vertical + axis - - ``typeset`` -- (default: ``"default"``) string. The type of + - ``typeset`` -- (default: ``'default'``) string. The type of font rendering that should be used for the text. The possible values are - - ``"default"`` -- Uses matplotlib's internal text rendering + - ``'default'`` -- uses matplotlib's internal text rendering engine called Mathtext ( see https://matplotlib.org/users/mathtext.html ). If you have modified the default matplotlib settings, for instance via a matplotlibrc file, then this option will not change any of those settings. - - ``"latex"`` -- LaTeX is used for rendering the fonts. This - requires LaTeX, dvipng and Ghostscript to be installed. - - ``"type1"`` -- Type 1 fonts are used by matplotlib in the text + - ``'latex'`` -- laTeX is used for rendering the fonts. This + requires LaTeX, dvipng and Ghostscript to be installed + - ``'type1'`` -- type 1 fonts are used by matplotlib in the text in the figure. This requires LaTeX, dvipng and Ghostscript to be installed. @@ -1760,14 +1758,14 @@ def show(self, **kwds): Graphics object consisting of 1 graphics primitive If you want all the text to be rendered by using an external LaTeX - installation then set the ``typeset`` to ``"latex"``. This + installation then set the ``typeset`` to ``'latex'``. This requires that LaTeX, dvipng and Ghostscript be installed:: sage: plot(x, typeset='latex') # optional - latex, needs sage.symbolic Graphics object consisting of 1 graphics primitive If you want all the text in your plot to use Type 1 fonts, then - set the ``typeset`` option to ``"type1"``. This requires that + set the ``typeset`` option to ``'type1'``. This requires that LaTeX, dvipng and Ghostscript be installed:: sage: plot(x, typeset='type1') # optional - latex, needs sage.symbolic @@ -1855,8 +1853,8 @@ def show(self, **kwds): sage: c = circle((0,0), 1) sage: c.show(gridlines=True) - sage: c.show(gridlines="automatic") - sage: c.show(gridlines="major") + sage: c.show(gridlines='automatic') + sage: c.show(gridlines='major') Add grid lines at the major and minor ticks of the axes. @@ -1866,7 +1864,7 @@ def show(self, **kwds): sage: u,v = var('u v') sage: f = exp(-(u^2+v^2)) sage: p = plot_vector_field(f.gradient(), (u,-2,2), (v,-2,2)) - sage: p.show(gridlines="minor") + sage: p.show(gridlines='minor') Add only horizontal or vertical grid lines. @@ -1892,7 +1890,7 @@ def show(self, **kwds): sage: def maple_leaf(t): ....: return (100/(100+(t-pi/2)^8))*(2-sin(7*t)-cos(30*t)/2) sage: p = polar_plot(maple_leaf, -pi/4, 3*pi/2, # long time, needs sage.symbolic - ....: color="red",plot_points=1000) + ....: color='red',plot_points=1000) sage: p.show(gridlines=([-3,-2.75,..,3], range(-1,5,2))) # long time, needs sage.symbolic Add grid lines at specific positions (using functions). @@ -1911,7 +1909,7 @@ def show(self, **kwds): sage: b = bar_chart([-3,5,-6,11], color='red') sage: b.show(gridlines=([-1,-0.5,..,4], True), - ....: gridlinesstyle=dict(color="blue", linestyle=":")) + ....: gridlinesstyle=dict(color='blue', linestyle=':')) Change the style of the horizontal or vertical grid lines separately. @@ -1920,8 +1918,8 @@ def show(self, **kwds): sage: p = polar_plot(2 + 2*cos(x), 0, 2*pi, color=hue(0.3)) # needs sage.symbolic sage: p.show(gridlines=True, # needs sage.symbolic - ....: hgridlinesstyle=dict(color="orange", linewidth=1.0), - ....: vgridlinesstyle=dict(color="blue", linestyle=":")) + ....: hgridlinesstyle=dict(color='orange', linewidth=1.0), + ....: vgridlinesstyle=dict(color='blue', linestyle=':')) Change the style of each grid line individually. @@ -1941,7 +1939,7 @@ def show(self, **kwds): ....: (1,{"color":"red","linestyle":":"}), ....: ] ....: ), - ....: gridlinesstyle=dict(marker='x',color="black")) + ....: gridlinesstyle=dict(marker='x',color='black')) Grid lines can be added to contour plots. @@ -1977,7 +1975,7 @@ def show(self, **kwds): Graphics object consisting of 2 graphics primitives The behavior of the ``axes_pad`` parameter is different if the axis - is in the ``"log"`` scale. If `b` is the base of the axis, the + is in the ``'log'`` scale. If `b` is the base of the axis, the minimum value of the axis, is decreased by the factor `1/b^{\mathrm{axes\_pad}}` of the minimum and the maximum value of the axis is increased by the same factor of the maximum value. Compare the @@ -2039,7 +2037,7 @@ def show(self, **kwds): sage: plot(2*x + 1, (x,0,5), # not tested (broken with matplotlib 3.6), needs sage.symbolic ....: ticks=[[0,1,e,pi,sqrt(20)], 2], - ....: tick_formatter="latex") + ....: tick_formatter='latex') Graphics object consisting of 1 graphics primitive This is particularly useful when setting custom ticks in multiples @@ -2241,7 +2239,7 @@ def ymax(self, ymax=None): def get_minmax_data(self): r""" - Return the x and y coordinate minimum and maximum + Return the x and y coordinate minimum and maximum. .. warning:: @@ -2316,12 +2314,12 @@ def get_minmax_data(self): def _limit_output_aspect_ratio(self, xmin, xmax, ymin, ymax): r""" - Private helper function for :meth:`get_minmax_data` + Private helper function for :meth:`get_minmax_data`. INPUT: - ``xmin``, ``xmax``, ``ymin``, ``ymax`` -- bounding box for - the graphics. + the graphics OUTPUT: @@ -2375,7 +2373,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), INPUT: - - ``subplot`` -- the subplot instance. + - ``subplot`` -- the subplot instance EXAMPLES:: @@ -2552,11 +2550,11 @@ def _get_vmin_vmax(self, vmin, vmax, basev, axes_pad): INPUT: - - ``vmin`` -- the current min for this variable (e.g. xmin or ymin) + - ``vmin`` -- the current min for this variable (e.g. xmin or ymin) - - ``vmax`` -- the current max for this variable (e.g. xmax or ymax) + - ``vmax`` -- the current max for this variable (e.g. xmax or ymax) - - ``basev`` -- the base of the logarithmic scale for this variable + - ``basev`` -- the base of the logarithmic scale for this variable - ``axes_pad`` -- the padding for the axis. It determines the exponent of the fraction of the minimum (resp. maximum) that is @@ -2607,7 +2605,6 @@ def _get_vmin_vmax(self, vmin, vmax, basev, axes_pad): Traceback (most recent call last): ... ValueError: vmin must be less than vmax - """ if vmin <= 0: raise ValueError('vmin must be positive') @@ -2754,7 +2751,7 @@ def matplotlib(self, filename=None, sage: xmin, xmax = sub.get_xlim() sage: ymin, ymax = sub.get_ylim() sage: xmin > xmax, ymin > ymax - (True, True) + (...True..., ...True...) """ if not isinstance(ticks, (list, tuple)): ticks = (ticks, None) @@ -3232,7 +3229,7 @@ def matplotlib(self, filename=None, def save_image(self, filename=None, *args, **kwds): r""" - Save an image representation of self. + Save an image representation of ``self``. The image type is determined by the extension of the filename. For example, this could be ``.png``, ``.jpg``, ``.gif``, @@ -3249,7 +3246,7 @@ def save_image(self, filename=None, *args, **kwds): sage: import tempfile sage: c = circle((1,1), 1, color='red') - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: ....: c.save_image(f.name, xmin=-1, xmax=3, ....: ymin=-1, ymax=3) """ @@ -3286,15 +3283,13 @@ def save(self, filename, **kwds): All other keyword arguments will be passed to the plotter. - OUTPUT: - - - none. + OUTPUT: none EXAMPLES:: sage: c = circle((1,1), 1, color='red') sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".png") as f: + sage: with NamedTemporaryFile(suffix='.png') as f: ....: c.save(f.name, xmin=-1, xmax=3, ymin=-1, ymax=3) To make a figure bigger or smaller, use ``figsize``:: @@ -3330,7 +3325,7 @@ def save(self, filename, **kwds): sage: P.set_legend_options(back_color=(1,0,0)) sage: P.set_legend_options(loc=7) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: ....: P.save(f.name) This plot should save with the frame shown, showing :issue:`7524` @@ -3340,14 +3335,13 @@ def save(self, filename, **kwds): (x, y) sage: a = plot_vector_field((x,-y),(x,-1,1),(y,-1,1)) # needs sage.symbolic sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # needs sage.symbolic + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: # needs sage.symbolic ....: a.save(f.name) The following plot should show the axes; fixes :issue:`14782` :: sage: plot(x^2, (x, 1, 2), ticks=[[], []]) # needs sage.symbolic Graphics object consisting of 1 graphics primitive - """ options = {} options.update(self.SHOW_OPTIONS) @@ -3432,11 +3426,9 @@ def _latex_(self, **kwds): INPUT: - All keyword arguments will be passed to the plotter. - - OUTPUT: + - ``**kwds`` -- all keyword arguments will be passed to the plotter - A string of PGF commands to plot ``self`` + OUTPUT: string of PGF commands to plot ``self`` EXAMPLES:: @@ -3499,9 +3491,7 @@ def inset(self, graphics, pos=None, fontsize=None): ``fontsize`` has been explicitly set in the construction of ``graphics`` (in this case, it is not overwritten here) - OUTPUT: - - - instance of :class:`~sage.plot.multigraphics.MultiGraphics` + OUTPUT: instance of :class:`~sage.plot.multigraphics.MultiGraphics` EXAMPLES:: @@ -3552,7 +3542,6 @@ def inset(self, graphics, pos=None, fontsize=None): g3 = plot(f(x), (x, -0.05, 0.05), axes_labels=['$x$', '$y$'], \ frame=True) sphinx_plot(g1g2.inset(g3, pos=(0.65, 0.12, 0.25, 0.25))) - """ from .multigraphics import MultiGraphics if pos is None: @@ -3581,7 +3570,6 @@ def GraphicsArray(*args, **kwargs): See https://github.com/sagemath/sage/issues/28675 for details. sage: G Graphics Array of size 1 x 2 - """ from .multigraphics import GraphicsArray as NewGraphicsArray from sage.misc.superseded import deprecation diff --git a/src/sage/plot/histogram.py b/src/sage/plot/histogram.py index fa86a44bd0a..d2514b9ef29 100644 --- a/src/sage/plot/histogram.py +++ b/src/sage/plot/histogram.py @@ -92,6 +92,8 @@ def get_minmax_data(self): {'xmax': 10.0, 'xmin': 3.0, 'ymax': 0.476190476190..., 'ymin': 0} """ import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") # Extract these options (if they are not None) and pass them to # histogram() @@ -208,49 +210,49 @@ def _render_on_subplot(self, subplot): @options(aspect_ratio='automatic', align='mid', weights=None, range=None, bins=10, edgecolor='black') def histogram(datalist, **options): """ - Computes and draws the histogram for list(s) of numerical data. + Compute and draw the histogram for list(s) of numerical data. See examples for the many options; even more customization is available using matplotlib directly. INPUT: - - ``datalist`` -- A list, or a list of lists, of numerical data - - ``align`` -- (default: "mid") How the bars align inside of each bin. - Acceptable values are "left", "right" or "mid" + - ``datalist`` -- list, or a list of lists, of numerical data + - ``align`` -- (default: ``'mid'``) how the bars align inside of each bin. + Acceptable values are ``'left'`` ``'right'`` or ``'mid'`` - ``alpha`` -- (float in [0,1], default: 1) The transparency of the plot - - ``bins`` -- The number of sections in which to divide the range. Also + - ``bins`` -- the number of sections in which to divide the range. Also can be a sequence of points within the range that create the partition - - ``color`` -- The color of the face of the bars or list of colors if + - ``color`` -- the color of the face of the bars or list of colors if multiple data sets are given - - ``cumulative`` -- (default: ``False``) If True, then + - ``cumulative`` -- boolean (default: ``False``); if True, then a histogram is computed in which each bin gives the counts in that bin plus all bins for smaller values. Negative values give a reversed direction of accumulation - - ``edgecolor`` -- The color of the border of each bar - - ``fill`` -- (default: ``True``) Whether to fill the bars - - ``hatch`` -- (default: None) symbol to fill the bars with; one of + - ``edgecolor`` -- the color of the border of each bar + - ``fill`` -- boolean (default: ``True``); whether to fill the bars + - ``hatch`` -- (default: ``None``) symbol to fill the bars with; one of "/", "\\", "|", "-", "+", "x", "o", "O", ".", "*", "" (or None) - - ``hue`` -- The color of the bars given as a hue. See + - ``hue`` -- the color of the bars given as a hue. See :mod:`~sage.plot.colors.hue` for more information on the hue - - ``label`` -- A string label for each data list given + - ``label`` -- string label for each data list given - ``linewidth`` -- (float) width of the lines defining the bars - - ``linestyle`` -- (default: 'solid') Style of the line. One of 'solid' + - ``linestyle`` -- (default: ``'solid'``) style of the line. One of 'solid' or '-', 'dashed' or '--', 'dotted' or ':', 'dashdot' or '-.' - - ``density`` -- (default: ``False``) If True, the result is the + - ``density`` -- boolean (default: ``False``); if True, the result is the value of the probability density function at the bin, normalized such that the integral over the range is 1. - - ``range`` -- A list [min, max] which define the range of the + - ``range`` -- list [min, max] which define the range of the histogram. Values outside of this range are treated as outliers and omitted from counts - ``rwidth`` -- (float in [0,1], default: 1) The relative width of the bars as a fraction of the bin width - - ``stacked`` -- (default: ``False``) If True, multiple data are + - ``stacked`` -- boolean (default: ``False``); if True, multiple data are stacked on top of each other - ``weights`` -- (list) A sequence of weights the same length as the data list. If supplied, then each value contributes its associated weight to the bin count - - ``zorder`` -- (integer) the layer level at which to draw the histogram + - ``zorder`` -- integer; the layer level at which to draw the histogram .. NOTE:: @@ -288,12 +290,12 @@ def histogram(datalist, **options): There are many options one can use with histograms. Some of these control the presentation of the data, even if it is boring:: - sage: histogram(list(range(100)), color=(1,0,0), label='mydata', rwidth=.5, align="right") + sage: histogram(list(range(100)), color=(1,0,0), label='mydata', rwidth=.5, align='right') Graphics object consisting of 1 graphics primitive .. PLOT:: - sphinx_plot(histogram(list(range(100)), color=(1,0,0), label='mydata', rwidth=.5, align="right")) + sphinx_plot(histogram(list(range(100)), color=(1,0,0), label='mydata', rwidth=.5, align='right')) This includes many usual matplotlib styling options:: diff --git a/src/sage/plot/hyperbolic_arc.py b/src/sage/plot/hyperbolic_arc.py index ef75f805348..904576f79b2 100644 --- a/src/sage/plot/hyperbolic_arc.py +++ b/src/sage/plot/hyperbolic_arc.py @@ -200,7 +200,7 @@ def __init__(self, A, B, model, options): sage: from sage.plot.hyperbolic_arc import HyperbolicArc sage: arc = HyperbolicArc(0, 1/2+I*sqrt(3)/2, "UHP", {}) - sage: TestSuite(arc).run(skip="_test_pickling") # no equality implemented + sage: TestSuite(arc).run(skip='_test_pickling') # no equality implemented """ if model == "HM": raise ValueError("the hyperboloid model is not supported") @@ -230,8 +230,8 @@ def _repr_(self): @rename_keyword(color='rgbcolor') -@options(alpha=1, fill=False, thickness=1, rgbcolor="blue", zorder=2, linestyle='solid') -def hyperbolic_arc(a, b, model="UHP", **options): +@options(alpha=1, fill=False, thickness=1, rgbcolor='blue', zorder=2, linestyle='solid') +def hyperbolic_arc(a, b, model='UHP', **options): r""" Plot an arc from ``a`` to ``b`` in hyperbolic plane. @@ -249,11 +249,11 @@ def hyperbolic_arc(a, b, model="UHP", **options): OPTIONS: - - ``alpha`` -- default: 1 + - ``alpha`` -- (default: 1) - - ``thickness`` -- default: 1 + - ``thickness`` -- (default: 1) - - ``rgbcolor`` -- default: ``'blue'`` + - ``rgbcolor`` -- (default: ``'blue'``) - ``linestyle`` -- (default: ``'solid'``) the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, @@ -320,9 +320,9 @@ def hyperbolic_arc(a, b, model="UHP", **options): sage: z4 = CC((0.6*cos(3*pi/4),0.6*sin(3*pi/4))) sage: z5 = CC(-0.5,0.5) sage: z6 = CC(0.5,-0.5) - sage: a1 = hyperbolic_arc(z1, z2, model="PD", color="red") - sage: a2 = hyperbolic_arc(z3, z4, model="PD", color="green") - sage: a3 = hyperbolic_arc(z5, z6, model="PD", linestyle="--") + sage: a1 = hyperbolic_arc(z1, z2, model='PD', color='red') + sage: a2 = hyperbolic_arc(z3, z4, model='PD', color='green') + sage: a3 = hyperbolic_arc(z5, z6, model='PD', linestyle='--') sage: a1 + a2 + a3 Graphics object consisting of 6 graphics primitives @@ -334,9 +334,9 @@ def hyperbolic_arc(a, b, model="UHP", **options): z4 = CC((0.6*cos(3*pi/4),0.6*sin(3*pi/4))) z5 = CC(-0.5,0.5) z6 = CC(0.5,-0.5) - a1 = hyperbolic_arc(z1, z2, model="PD", color="red") - a2 = hyperbolic_arc(z3, z4, model="PD", color="green") - a3 = hyperbolic_arc(z5, z6, model="PD", linestyle="--") + a1 = hyperbolic_arc(z1, z2, model='PD', color='red') + a2 = hyperbolic_arc(z3, z4, model='PD', color='green') + a3 = hyperbolic_arc(z5, z6, model='PD', linestyle='--') P = a1 + a2 + a3 sphinx_plot(P) @@ -344,9 +344,9 @@ def hyperbolic_arc(a, b, model="UHP", **options): model (note that these are *not* the image of those arcs when changing between the models):: - sage: a1 = hyperbolic_arc(z1, z2, model="KM", color="red") - sage: a2 = hyperbolic_arc(z3, z4, model="KM", color="green") - sage: a3 = hyperbolic_arc(z5, z6, model="KM", linestyle="--") + sage: a1 = hyperbolic_arc(z1, z2, model='KM', color='red') + sage: a2 = hyperbolic_arc(z3, z4, model='KM', color='green') + sage: a3 = hyperbolic_arc(z5, z6, model='KM', linestyle='--') sage: a1 + a2 + a3 Graphics object consisting of 6 graphics primitives @@ -358,9 +358,9 @@ def hyperbolic_arc(a, b, model="UHP", **options): z4 = CC((0.6*cos(3*pi/4),0.6*sin(3*pi/4))) z5 = CC(-0.5,0.5) z6 = CC(0.5,-0.5) - a1 = hyperbolic_arc(z1, z2, model="KM", color="red") - a2 = hyperbolic_arc(z3, z4, model="KM", color="green") - a3 = hyperbolic_arc(z5, z6, model="KM", linestyle="--") + a1 = hyperbolic_arc(z1, z2, model='KM', color='red') + a2 = hyperbolic_arc(z3, z4, model='KM', color='green') + a3 = hyperbolic_arc(z5, z6, model='KM', linestyle='--') P = a1 + a2 + a3 sphinx_plot(P) @@ -369,14 +369,14 @@ def hyperbolic_arc(a, b, model="UHP", **options): sage: a = (1,2,sqrt(6)) sage: b = (-2,-3,sqrt(14)) - sage: hyperbolic_arc(a, b, model="HM") + sage: hyperbolic_arc(a, b, model='HM') Graphics3d Object .. PLOT:: a = (1,2,sqrt(6)) b = (-2,-3,sqrt(14)) - sphinx_plot(hyperbolic_arc(a, b, model="HM")) + sphinx_plot(hyperbolic_arc(a, b, model='HM')) """ from sage.plot.graphics import Graphics diff --git a/src/sage/plot/hyperbolic_polygon.py b/src/sage/plot/hyperbolic_polygon.py index 57b2bbe971b..f74c35fef6f 100644 --- a/src/sage/plot/hyperbolic_polygon.py +++ b/src/sage/plot/hyperbolic_polygon.py @@ -43,7 +43,7 @@ class HyperbolicPolygon(HyperbolicArcCore): - ``pts`` -- coordinates of the polygon (as complex numbers) - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -62,7 +62,7 @@ def __init__(self, pts, model, options): sage: from sage.plot.hyperbolic_polygon import HyperbolicPolygon sage: HP = HyperbolicPolygon([0, 1/2, I], "UHP", {}) - sage: TestSuite(HP).run(skip ="_test_pickling") + sage: TestSuite(HP).run(skip ='_test_pickling') """ if model == "HM": raise ValueError("the hyperboloid model is not supported") @@ -152,8 +152,8 @@ def _is_left(point, edge): @rename_keyword(color='rgbcolor') -@options(alpha=1, fill=False, thickness=1, rgbcolor="blue", zorder=2, linestyle='solid') -def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): +@options(alpha=1, fill=False, thickness=1, rgbcolor='blue', zorder=2, linestyle='solid') +def hyperbolic_polygon(pts, model='UHP', resolution=200, **options): r""" Return a hyperbolic polygon in the hyperbolic plane with vertices ``pts``. @@ -161,19 +161,19 @@ def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): INPUT: - - ``pts`` -- a list or tuple of complex numbers + - ``pts`` -- list or tuple of complex numbers OPTIONS: - - ``model`` -- default: ``UHP`` Model used for hyperbolic plane + - ``model`` -- (default: ``UHP``) Model used for hyperbolic plane - - ``alpha`` -- default: 1 + - ``alpha`` -- (default: 1) - - ``fill`` -- default: ``False`` + - ``fill`` -- (default: ``False``) - - ``thickness`` -- default: 1 + - ``thickness`` -- (default: 1) - - ``rgbcolor`` -- default: ``'blue'`` + - ``rgbcolor`` -- (default: ``'blue'``) - ``linestyle`` -- (default: ``'solid'``) the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or @@ -214,21 +214,21 @@ def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): Show a hyperbolic polygon in the Poincare disc model with coordinates `1`, `i`, `-1`, `-i`:: - sage: hyperbolic_polygon([1,I,-1,-I], model="PD", color='green') + sage: hyperbolic_polygon([1,I,-1,-I], model='PD', color='green') Graphics object consisting of 2 graphics primitives .. PLOT:: - sphinx_plot(hyperbolic_polygon([1,I,-1,-I], model="PD", color='green')) + sphinx_plot(hyperbolic_polygon([1,I,-1,-I], model='PD', color='green')) With more options:: - sage: hyperbolic_polygon([1,I,-1,-I], model="PD", color='green', fill=True, linestyle="-") + sage: hyperbolic_polygon([1,I,-1,-I], model='PD', color='green', fill=True, linestyle='-') Graphics object consisting of 2 graphics primitives .. PLOT:: - P = hyperbolic_polygon([1,I,-1,-I], model="PD", color='green', fill=True, linestyle="-") + P = hyperbolic_polygon([1,I,-1,-I], model='PD', color='green', fill=True, linestyle='-') sphinx_plot(P) Klein model is also supported via the parameter ``model``. @@ -241,7 +241,7 @@ def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): sage: p4 = -1 sage: p5 = (cos(4*pi/3), sin(4*pi/3)) sage: p6 = (cos(5*pi/3), sin(5*pi/3)) - sage: hyperbolic_polygon([p1,p2,p3,p4,p5,p6], model="KM", fill=True, color='purple') + sage: hyperbolic_polygon([p1,p2,p3,p4,p5,p6], model='KM', fill=True, color='purple') Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -252,7 +252,7 @@ def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): p4=-1 p5=(cos(4*pi/3),sin(4*pi/3)) p6=(cos(5*pi/3),sin(5*pi/3)) - P = hyperbolic_polygon([p1,p2,p3,p4,p5,p6], model="KM", fill=True, color='purple') + P = hyperbolic_polygon([p1,p2,p3,p4,p5,p6], model='KM', fill=True, color='purple') sphinx_plot(P) Hyperboloid model is supported partially, via the parameter ``model``. @@ -261,13 +261,13 @@ def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): `(-3,3,\sqrt(19))`:: sage: pts = [(3,3,sqrt(19)),(3,-3,sqrt(19)),(-3,-3,sqrt(19)),(-3,3,sqrt(19))] - sage: hyperbolic_polygon(pts, model="HM") + sage: hyperbolic_polygon(pts, model='HM') Graphics3d Object .. PLOT:: pts = [(3,3,sqrt(19)),(3,-3,sqrt(19)),(-3,-3,sqrt(19)),(-3,3,sqrt(19))] - P = hyperbolic_polygon(pts, model="HM") + P = hyperbolic_polygon(pts, model='HM') sphinx_plot(P) Filling a hyperbolic_polygon in hyperboloid model is possible although @@ -277,16 +277,15 @@ def hyperbolic_polygon(pts, model="UHP", resolution=200, **options): give a faster result.) :: sage: pts = [(1,1,sqrt(3)), (0,2,sqrt(5)), (2,0,sqrt(5))] - sage: hyperbolic_polygon(pts, model="HM", resolution=50, + sage: hyperbolic_polygon(pts, model='HM', resolution=50, ....: color='yellow', fill=True) Graphics3d Object .. PLOT:: pts = [(1,1,sqrt(3)),(0,2,sqrt(5)),(2,0,sqrt(5))] - P = hyperbolic_polygon(pts, model="HM", color='yellow', fill=True) + P = hyperbolic_polygon(pts, model='HM', color='yellow', fill=True) sphinx_plot(P) - """ from sage.plot.all import Graphics g = Graphics() @@ -329,7 +328,7 @@ def region(x, y, z): return g -def hyperbolic_triangle(a, b, c, model="UHP", **options): +def hyperbolic_triangle(a, b, c, model='UHP', **options): r""" Return a hyperbolic triangle in the hyperbolic plane with vertices ``(a,b,c)``. @@ -342,17 +341,17 @@ def hyperbolic_triangle(a, b, c, model="UHP", **options): OPTIONS: - - ``alpha`` -- default: 1 + - ``alpha`` -- (default: 1) - - ``fill`` -- default: ``False`` + - ``fill`` -- (default: ``False``) - - ``thickness`` -- default: 1 + - ``thickness`` -- (default: 1) - - ``rgbcolor`` -- default: ``'blue'`` + - ``rgbcolor`` -- (default: ``'blue'``) - ``linestyle`` -- (default: ``'solid'``) the style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or - ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively. + ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively EXAMPLES: @@ -392,7 +391,7 @@ def hyperbolic_triangle(a, b, c, model="UHP", **options): sage: z1 = CC((cos(pi/3),sin(pi/3))) sage: z2 = CC((0.6*cos(3*pi/4),0.6*sin(3*pi/4))) sage: z3 = 1 - sage: hyperbolic_triangle(z1, z2, z3, model="PD", color="red") + sage: hyperbolic_triangle(z1, z2, z3, model='PD', color='red') Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -400,18 +399,17 @@ def hyperbolic_triangle(a, b, c, model="UHP", **options): z1 = CC((cos(pi/3),sin(pi/3))) z2 = CC((0.6*cos(3*pi/4),0.6*sin(3*pi/4))) z3 = 1 - P = hyperbolic_triangle(z1, z2, z3, model="PD", color="red") + P = hyperbolic_triangle(z1, z2, z3, model='PD', color='red') sphinx_plot(P) :: - sage: hyperbolic_triangle(0.3+0.3*I, 0.8*I, -0.5-0.5*I, model="PD", color='magenta') + sage: hyperbolic_triangle(0.3+0.3*I, 0.8*I, -0.5-0.5*I, model='PD', color='magenta') Graphics object consisting of 2 graphics primitives .. PLOT:: - P = hyperbolic_triangle(0.3+0.3*I, 0.8*I, -0.5-0.5*I, model="PD", color='magenta') + P = hyperbolic_triangle(0.3+0.3*I, 0.8*I, -0.5-0.5*I, model='PD', color='magenta') sphinx_plot(P) - """ return hyperbolic_polygon((a, b, c), model, **options) diff --git a/src/sage/plot/hyperbolic_regular_polygon.py b/src/sage/plot/hyperbolic_regular_polygon.py index 96df49b2271..14e8bdcaf68 100644 --- a/src/sage/plot/hyperbolic_regular_polygon.py +++ b/src/sage/plot/hyperbolic_regular_polygon.py @@ -61,7 +61,7 @@ class HyperbolicRegularPolygon(HyperbolicPolygon): A(\mathcal{P}) = \pi(s-2) - s \cdot \alpha > 0, - where `s` is ``sides`` and `\alpha` is ``i_angle`. This raises an error if + where `s` is ``sides`` and `\alpha` is ``i_angle``. This raises an error if the ``i_angle`` is less than the minimum to generate a compact polygon:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon @@ -184,9 +184,7 @@ def _i_rotation(self, z, alpha): - ``alpha`` -- angle of rotation (radians, counterclockwise) - OUTPUT: - - - rotated point in the upper complex halfplane + OUTPUT: rotated point in the upper complex halfplane TESTS:: @@ -203,7 +201,7 @@ def _i_rotation(self, z, alpha): @rename_keyword(color='rgbcolor') -@options(alpha=1, fill=False, thickness=1, rgbcolor="blue", zorder=2, +@options(alpha=1, fill=False, thickness=1, rgbcolor='blue', zorder=2, linestyle='solid') def hyperbolic_regular_polygon(sides, i_angle, center=CC(0,1), **options): r""" @@ -219,18 +217,18 @@ def hyperbolic_regular_polygon(sides, i_angle, center=CC(0,1), **options): - ``i_angle`` -- interior angle of the polygon - - ``center`` -- (default: `i`) hyperbolic center point + - ``center`` -- (default: `i`) hyperbolic center point (complex number) of the polygon OPTIONS: - - ``alpha`` -- default: 1 + - ``alpha`` -- (default: 1) - - ``fill`` -- default: ``False`` + - ``fill`` -- (default: ``False``) - - ``thickness`` -- default: 1 + - ``thickness`` -- (default: 1) - - ``rgbcolor`` -- default: ``'blue'`` + - ``rgbcolor`` -- (default: ``'blue'``) - ``linestyle`` -- (default: ``'solid'``) the style of the line, which can be one of the following: @@ -271,7 +269,7 @@ def hyperbolic_regular_polygon(sides, i_angle, center=CC(0,1), **options): A(\mathcal{P}) = \pi(s-2) - s \cdot \alpha > 0, - where `s` is ``sides`` and `\alpha` is ``i_angle`. This raises an error if + where `s` is ``sides`` and `\alpha` is ``i_angle``. This raises an error if the ``i_angle`` is less than the minimum to generate a compact polygon:: sage: hyperbolic_regular_polygon(4, pi/2) diff --git a/src/sage/plot/line.py b/src/sage/plot/line.py index 92db1abf424..241b2b4c1f1 100644 --- a/src/sage/plot/line.py +++ b/src/sage/plot/line.py @@ -103,7 +103,7 @@ def _plot3d_options(self, options=None): 0.5 sage: m.thickness 10 - sage: L = line([(1,1), (1,2), (2,2), (2,1)], linestyle=":") + sage: L = line([(1,1), (1,2), (2,2), (2,1)], linestyle=':') sage: L.plot3d() Traceback (most recent call last): ... @@ -141,7 +141,6 @@ def plot3d(self, z=0, **kwds): E = EllipticCurve('37a').plot(thickness=5).plot3d() F = EllipticCurve('37a').plot(thickness=5).plot3d(z=2) sphinx_plot(E+F) - """ from sage.plot.plot3d.shapes2 import line3d options = self._plot3d_options() @@ -166,11 +165,9 @@ def __getitem__(self, i): INPUT: - - ``i`` -- an integer between 0 and the number of points minus 1 - - OUTPUT: + - ``i`` -- integer between 0 and the number of points minus 1 - A 2-tuple of floats. + OUTPUT: 2-tuple of floats EXAMPLES:: @@ -193,7 +190,7 @@ def __setitem__(self, i, point): INPUT: - - ``i`` -- an integer between 0 and the number of points on the + - ``i`` -- integer between 0 and the number of points on the line minus 1 - ``point`` -- a 2-tuple of floats @@ -276,13 +273,13 @@ def _render_on_subplot(self, subplot): def line(points, **kwds): """ - Returns either a 2-dimensional or 3-dimensional line depending + Return either a 2-dimensional or 3-dimensional line depending on value of points. INPUT: - - ``points`` -- either a single point (as a tuple), a list of - points, a single complex number, or a list of complex numbers. + - ``points`` -- either a single point (as a tuple), a list of + points, a single complex number, or a list of complex numbers For information regarding additional arguments, see either line2d? or line3d?. @@ -323,8 +320,8 @@ def line2d(points, **options): INPUT: - - ``points`` -- either a single point (as a tuple), a list of - points, a single complex number, or a list of complex numbers. + - ``points`` -- either a single point (as a tuple), a list of + points, a single complex number, or a list of complex numbers Type ``line2d.options`` for a dictionary of the default options for lines. You can change this to change the defaults for all future @@ -332,39 +329,39 @@ def line2d(points, **options): INPUT: - - ``alpha`` -- How transparent the line is + - ``alpha`` -- how transparent the line is - - ``thickness`` -- How thick the line is + - ``thickness`` -- how thick the line is - - ``rgbcolor`` -- The color as an RGB tuple + - ``rgbcolor`` -- the color as an RGB tuple - - ``hue`` -- The color given as a hue + - ``hue`` -- the color given as a hue - - ``legend_color`` -- The color of the text in the legend + - ``legend_color`` -- the color of the text in the legend - ``legend_label`` -- the label for this item in the legend Any MATPLOTLIB line option may also be passed in. E.g., - - ``linestyle`` -- (default: "-") The style of the line, which is one of - - ``"-"`` or ``"solid"`` - - ``"--"`` or ``"dashed"`` - - ``"-."`` or ``"dash dot"`` - - ``":"`` or ``"dotted"`` + - ``linestyle`` -- (default: ``'-'``) the style of the line, which is one of + - ``'-'`` or ``'solid'`` + - ``'--'`` or ``'dashed'`` + - ``'-.'`` or ``'dash dot'`` + - ``':'`` or ``'dotted'`` - ``"None"`` or ``" "`` or ``""`` (nothing) - The linestyle can also be prefixed with a drawing style (e.g., ``"steps--"``) + The linestyle can also be prefixed with a drawing style (e.g., ``'steps--'``) - - ``"default"`` (connect the points with straight lines) - - ``"steps"`` or ``"steps-pre"`` (step function; horizontal + - ``'default'`` (connect the points with straight lines) + - ``'steps'`` or ``'steps-pre'`` (step function; horizontal line is to the left of point) - - ``"steps-mid"`` (step function; points are in the middle of + - ``'steps-mid'`` (step function; points are in the middle of horizontal lines) - - ``"steps-post"`` (step function; horizontal line is to the + - ``'steps-post'`` (step function; horizontal line is to the right of point) - - ``marker`` -- The style of the markers, which is one of + - ``marker`` -- the style of the markers, which is one of - ``"None"`` or ``" "`` or ``""`` (nothing) -- default - ``","`` (pixel), ``"."`` (point) - ``"_"`` (horizontal line), ``"|"`` (vertical line) diff --git a/src/sage/plot/matrix_plot.py b/src/sage/plot/matrix_plot.py index 5e505957e8f..900ac9989e0 100644 --- a/src/sage/plot/matrix_plot.py +++ b/src/sage/plot/matrix_plot.py @@ -41,7 +41,7 @@ class MatrixPlot(GraphicPrimitive): (number of rows in the matrix). If ``None``, the defaults are used as indicated in :func:`matrix_plot`. - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -73,7 +73,7 @@ class MatrixPlot(GraphicPrimitive): """ def __init__(self, xy_data_array, xrange, yrange, options): """ - Initializes base class MatrixPlot. + Initialize base class MatrixPlot. EXAMPLES:: @@ -98,7 +98,7 @@ def __init__(self, xy_data_array, xrange, yrange, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: @@ -273,26 +273,26 @@ def matrix_plot(mat, xrange=None, yrange=None, **options): - ``mat`` -- a 2D matrix or array - - ``xrange`` -- (default: None) tuple of the horizontal extent + - ``xrange`` -- (default: ``None``) tuple of the horizontal extent ``(xmin, xmax)`` of the bounding box in which to draw the matrix. The image is stretched individually along x and y to fill the box. - If None, the extent is determined by the following conditions. Matrix + If ``None``, the extent is determined by the following conditions. Matrix entries have unit size in data coordinates. Their centers are on integer coordinates, and their center coordinates range from 0 to columns-1 horizontally and from 0 to rows-1 vertically. If the matrix is sparse, this keyword is ignored. - - ``yrange`` -- (default: None) tuple of the vertical extent + - ``yrange`` -- (default: ``None``) tuple of the vertical extent ``(ymin, ymax)`` of the bounding box in which to draw the matrix. See ``xrange`` for details. The following input must all be passed in as named parameters, if default not used: - - ``cmap`` -- a colormap (default: 'Greys'), the name of a predefined - colormap, a list of colors, or an instance of a matplotlib Colormap. + - ``cmap`` -- a colormap (default: ``'Greys'``); the name of a predefined + colormap, a list of colors, or an instance of a matplotlib Colormap The list of predefined color maps can be visualized in `matplotlib's documentation @@ -300,43 +300,44 @@ def matrix_plot(mat, xrange=None, yrange=None, **options): can also type ``import matplotlib.cm; matplotlib.cm.datad.keys()`` to list their names. - - ``colorbar`` -- boolean (default: ``False``) Show a colorbar or not (dense matrices only). + - ``colorbar`` -- boolean (default: ``False``); show a colorbar or not + (dense matrices only) The following options are used to adjust the style and placement of colorbars. They have no effect if a colorbar is not shown. - - ``colorbar_orientation`` -- string (default: 'vertical'), + - ``colorbar_orientation`` -- string (default: ``'vertical'``); controls placement of the colorbar, can be either 'vertical' or 'horizontal' - ``colorbar_format`` -- a format string, this is used to format - the colorbar labels. + the colorbar labels - - ``colorbar_options`` -- a dictionary of options for the matplotlib + - ``colorbar_options`` -- dictionary of options for the matplotlib colorbar API. Documentation for the :mod:`matplotlib.colorbar` module has details. - - ``norm`` -- If None (default), the value range is scaled to the interval + - ``norm`` -- if ``None`` (default), the value range is scaled to the interval [0,1]. If 'value', then the actual value is used with no scaling. A :class:`matplotlib.colors.Normalize` instance may also passed. - - ``vmin`` -- The minimum value (values below this are set to this value) + - ``vmin`` -- the minimum value (values below this are set to this value) - - ``vmax`` -- The maximum value (values above this are set to this value) + - ``vmax`` -- the maximum value (values above this are set to this value) - - ``flip_y`` -- (default: ``True``) boolean. If False, the first row of the + - ``flip_y`` -- boolean (default: ``True``); if ``False``, the first row of the matrix is on the bottom of the graph. Otherwise, the first row is on the top of the graph. - - ``subdivisions`` -- If True, plot the subdivisions of the matrix as lines. + - ``subdivisions`` -- if ``True``, plot the subdivisions of the matrix as lines - - ``subdivision_boundaries`` -- a list of lists in the form + - ``subdivision_boundaries`` -- list of lists in the form ``[row_subdivisions, column_subdivisions]``, which specifies the row and column subdivisions to use. If not specified, defaults to the matrix subdivisions - - ``subdivision_style`` -- a dictionary of properties passed + - ``subdivision_style`` -- dictionary of properties passed on to the :func:`~sage.plot.line.line2d` command for plotting subdivisions. If this is a two-element list or tuple, then it specifies the styles of row and column divisions, respectively. @@ -511,7 +512,7 @@ def matrix_plot(mat, xrange=None, yrange=None, **options): Graphics object consisting of 1 graphics primitive The title position is adjusted upwards if the ``flip_y`` keyword is set - to True (this is the default).:: + to ``True`` (this is the default).:: sage: matrix_plot(identity_matrix(50), title='identity') Graphics object consisting of 1 graphics primitive diff --git a/src/sage/plot/meson.build b/src/sage/plot/meson.build new file mode 100644 index 00000000000..96a337faf78 --- /dev/null +++ b/src/sage/plot/meson.build @@ -0,0 +1,48 @@ +py.install_sources( + 'all.py', + 'animate.py', + 'arc.py', + 'arrow.py', + 'bar_chart.py', + 'bezier_path.py', + 'circle.py', + 'colors.py', + 'contour_plot.py', + 'density_plot.py', + 'disk.py', + 'ellipse.py', + 'graphics.py', + 'histogram.py', + 'hyperbolic_arc.py', + 'hyperbolic_polygon.py', + 'hyperbolic_regular_polygon.py', + 'line.py', + 'matrix_plot.py', + 'misc.py', + 'multigraphics.py', + 'plot.py', + 'plot_field.py', + 'point.py', + 'polygon.py', + 'primitive.py', + 'scatter_plot.py', + 'step.py', + 'streamline_plot.py', + 'text.py', + subdir: 'sage/plot', +) + +extension_data = {'complex_plot' : files('complex_plot.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/plot', + install: true, + include_directories: [inc_cpython, inc_gsl, inc_numpy, inc_rings], + dependencies: [py_dep, cysignals, gmp, gsl], + ) +endforeach + +subdir('plot3d') diff --git a/src/sage/plot/misc.py b/src/sage/plot/misc.py index 5ebe845fe16..b86b52b05f6 100644 --- a/src/sage/plot/misc.py +++ b/src/sage/plot/misc.py @@ -32,18 +32,18 @@ def setup_for_eval_on_grid(funcs, - ``funcs`` -- a function, or a list, tuple, or vector of functions - - ``ranges`` -- a list of ranges. A range can be a 2-tuple of + - ``ranges`` -- list of ranges. A range can be a 2-tuple of numbers specifying the minimum and maximum, or a 3-tuple giving the variable explicitly. - - ``plot_points`` -- a tuple of integers specifying the number of + - ``plot_points`` -- tuple of integers specifying the number of plot points for each range. If a single number is specified, it will be the value for all ranges. This defaults to 2. - - ``return_vars`` -- (default ``False``) If ``True``, return the variables, - in order. + - ``return_vars`` -- (default: ``False``) if ``True``, return the variables, + in order - - ``imaginary_tolerance`` -- (default: ``1e-8``); if an imaginary + - ``imaginary_tolerance`` -- (default: ``1e-8``) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than @@ -51,12 +51,11 @@ def setup_for_eval_on_grid(funcs, OUTPUT: - - ``fast_funcs`` -- if only one function passed, then a fast callable function. If funcs is a list or tuple, then a tuple of fast callable functions is returned. - - ``range_specs`` -- a list of range_specs: for each range, a + - ``range_specs`` -- list of range_specs: for each range, a tuple is returned of the form (range_min, range_max, range_step) such that ``srange(range_min, range_max, range_step, include_endpoint=True)`` gives the correct points @@ -125,7 +124,6 @@ def setup_for_eval_on_grid(funcs, Graphics3d Object sage: streamline_plot(abs(x+i*y), (x,-1,1),(y,-1,1)) Graphics object consisting of 1 graphics primitive - """ if max(map(len, ranges)) > 3: raise ValueError("At least one variable range has more than 3 entries: each should either have 2 or 3 entries, with one of the forms (xmin, xmax) or (x, xmin, xmax)") @@ -233,8 +231,8 @@ def unify_arguments(funcs): INPUT: - - ``funcs`` -- a list of functions; these can be symbolic - expressions, polynomials, etc + - ``funcs`` -- list of functions; these can be symbolic + expressions, polynomials, etc. OUTPUT: functions, expected arguments @@ -327,32 +325,32 @@ def get_matplotlib_linestyle(linestyle, return_type): 'dotted', 'dashdot' ). If linestyle is none of these allowed options, the function raises - a ValueError. + a :exc:`ValueError`. INPUT: - - ``linestyle`` -- The style of the line, which is one of - - ``"-"`` or ``"solid"`` - - ``"--"`` or ``"dashed"`` - - ``"-."`` or ``"dash dot"`` - - ``":"`` or ``"dotted"`` + - ``linestyle`` -- the style of the line, which is one of + - ``'-'`` or ``'solid'`` + - ``'--'`` or ``'dashed'`` + - ``'-.'`` or ``'dash dot'`` + - ``':'`` or ``'dotted'`` - ``"None"`` or ``" "`` or ``""`` (nothing) - The linestyle can also be prefixed with a drawing style (e.g., ``"steps--"``) + The linestyle can also be prefixed with a drawing style (e.g., ``'steps--'``) - - ``"default"`` (connect the points with straight lines) - - ``"steps"`` or ``"steps-pre"`` (step function; horizontal + - ``'default'`` (connect the points with straight lines) + - ``'steps'`` or ``'steps-pre'`` (step function; horizontal line is to the left of point) - - ``"steps-mid"`` (step function; points are in the middle of + - ``'steps-mid'`` (step function; points are in the middle of horizontal lines) - - ``"steps-post"`` (step function; horizontal line is to the + - ``'steps-post'`` (step function; horizontal line is to the right of point) If ``linestyle`` is ``None`` (of type NoneType), then we return it back unmodified. - - ``return_type`` -- The type of linestyle that should be output. This - argument takes only two values - ``"long"`` or ``"short"``. + - ``return_type`` -- the type of linestyle that should be output. This + argument takes only two values - ``'long'`` or ``'short'`` EXAMPLES: @@ -382,9 +380,9 @@ def get_matplotlib_linestyle(linestyle, return_type): sage: get_matplotlib_linestyle(None, 'short') is None True - Linestyles with ``"default"`` or ``"steps"`` in them should also be + Linestyles with ``'default'`` or ``'steps'`` in them should also be properly handled. For instance, matplotlib understands only the short - version when ``"steps"`` is used:: + version when ``'steps'`` is used:: sage: get_matplotlib_linestyle("default", "short") '' @@ -402,7 +400,6 @@ def get_matplotlib_linestyle(linestyle, return_type): linestyle options are: {'solid', 'dashed', 'dotted', dashdot', 'None'}, respectively {'-', '--', ':', '-.', ''} - """ long_to_short_dict = {'solid' : '-','dashed' : '--', 'dotted' : ':', 'dashdot':'-.'} @@ -496,7 +493,6 @@ def __call__(self, *args): sage: fff = FastCallablePlotWrapper(ff, imag_tol=0.1) sage: type(fff(CDF.random_element())) is float True - """ try: return super().__call__(*args) diff --git a/src/sage/plot/multigraphics.py b/src/sage/plot/multigraphics.py index b583be32317..6ed26974c49 100644 --- a/src/sage/plot/multigraphics.py +++ b/src/sage/plot/multigraphics.py @@ -37,7 +37,7 @@ class MultiGraphics(WithEqualityById, SageObject): INPUT: - - ``graphics_list`` -- a list of graphics along with their positions on the + - ``graphics_list`` -- list of graphics along with their positions on the common canvas; each element of ``graphics_list`` is either - a pair ``(graphics, position)``, where ``graphics`` is a @@ -123,7 +123,6 @@ class MultiGraphics(WithEqualityById, SageObject): Graphics object consisting of 1 graphics primitive] sage: len(G) 3 - """ def __init__(self, graphics_list): r""" @@ -164,7 +163,6 @@ def _repr_(self): 'Graphics Array of size 1 x 3' sage: G Graphics Array of size 1 x 3 - """ return str(self) @@ -186,7 +184,6 @@ def _rich_repr_(self, display_manager, **kwds): sage: G = graphics_array([Graphics(), Graphics()], 1, 2) sage: G._rich_repr_(dm) OutputImagePng container - """ types = display_manager.types prefer_raster = ( @@ -214,7 +211,7 @@ def _rich_repr_(self, display_manager, **kwds): def __getitem__(self, i): r""" - Return the ``i``th element of the list of graphics composing ``self``. + Return the ``i``-th element of the list of graphics composing ``self``. EXAMPLES: @@ -232,13 +229,12 @@ def __getitem__(self, i): sage: G = graphics_array(L, 5, 2) sage: G[3] Graphics object consisting of 2 graphics primitives - """ return self._glist[i] def __setitem__(self, i, g): r""" - Set the ``i``th element of the list of graphics composing ``self``. + Set the ``i``-th element of the list of graphics composing ``self``. EXAMPLES:: @@ -253,7 +249,6 @@ def __setitem__(self, i, g): ....: color='purple') sage: G[1] # a circle and some purple points Graphics object consisting of 2 graphics primitives - """ self._glist[i] = g @@ -267,7 +262,6 @@ def __len__(self): sage: G = graphics_array(L, 2, 3) sage: len(G) 6 - """ return len(self._glist) @@ -355,7 +349,6 @@ def matplotlib(self, figure=None, figsize=None, **kwds):
sage: fig2
- """ from matplotlib.figure import Figure glist = self._glist @@ -394,7 +387,7 @@ def save(self, filename, figsize=None, **kwds): INPUT: - - ``filename`` -- (string) the file name; the image format is given by + - ``filename`` -- string; the file name. The image format is given by the extension, which can be one of the following: * ``.eps``, @@ -429,7 +422,6 @@ def save(self, filename, figsize=None, **kwds): sage: graphics_array([]).save(F) sage: graphics_array([[]]).save(F) - """ from matplotlib import rcParams ext = os.path.splitext(filename)[1].lower() @@ -516,7 +508,6 @@ def save_image(self, filename=None, *args, **kwds): ....: for n in range(3)] for m in range(1,3)] sage: G = graphics_array(plots) sage: G.save_image(tmp_filename(ext='.png')) - """ self.save(filename, *args, **kwds) @@ -526,11 +517,9 @@ def _latex_(self, **kwds): INPUT: - All keyword arguments will be passed to the plotter. - - OUTPUT: + - ``**kwds`` -- all keyword arguments will be passed to the plotter - A string of PGF commands to plot ``self`` + OUTPUT: string of PGF commands to plot ``self`` EXAMPLES:: @@ -539,7 +528,6 @@ def _latex_(self, **kwds): '%% Creator: Matplotlib, PGF backend\n%%\n%' The above doctest fails on macOS due to the following Matplotlib issue: https://github.com/matplotlib/matplotlib/issues/10307 - """ tmpfilename = tmp_filename(ext='.pgf') self.save(filename=tmpfilename, **kwds) @@ -617,7 +605,6 @@ def show(self, **kwds): [plot(tan), plot(sec)]]) sphinx_plot(G, axes=False, frame=True, figsize=4, fontsize=8, \ gridlines='major') - """ from sage.repl.rich_output import get_display_manager dm = get_display_manager() @@ -634,7 +621,6 @@ def plot(self): sage: G = multi_graphics([g1, g2]) sage: G.plot() is G True - """ return self @@ -658,9 +644,7 @@ def inset(self, graphics, pos=None, fontsize=None): ``fontsize`` has been explicitly set in the construction of ``graphics`` (in this case, it is not overwritten here) - OUTPUT: - - - instance of :class:`~sage.plot.multigraphics.MultiGraphics` + OUTPUT: instance of :class:`~sage.plot.multigraphics.MultiGraphics` EXAMPLES: @@ -698,7 +682,6 @@ def inset(self, graphics, pos=None, fontsize=None): G = graphics_array([plot(sin, (0, 2*pi)), plot(cos, (0, 2*pi))]) c = circle((0,0), 1, color='red', thickness=2, frame=True) sphinx_plot(G.inset(c, pos=(0.3, 0.7, 0.2, 0.2), fontsize=8)) - """ if pos is None: pos = (0.7, 0.7, 0.2, 0.2) @@ -718,7 +701,7 @@ def inset(self, graphics, pos=None, fontsize=None): # def __str__(self): r""" - String representation of ``self`` + String representation of ``self``. EXAMPLES:: @@ -735,7 +718,6 @@ def __str__(self): sage: G = MultiGraphics([c, c, c]) sage: str(G) 'Multigraphics with 3 elements' - """ n = len(self._glist) if n <= 1: @@ -753,12 +735,10 @@ def _add_subplot(self, figure, index, **options): INPUT: - ``figure`` -- a Matplotlib ``Figure`` object - - ``index`` -- integer specifiying the element of ``self`` + - ``index`` -- integer specifying the element of ``self`` - ``options`` -- extra options to be passed to ``Figure.add_axes`` - OUTPUT: - - - a Matplotlib ``Axes`` object + OUTPUT: a Matplotlib ``Axes`` object EXAMPLES:: @@ -784,9 +764,11 @@ def _add_subplot(self, figure, index, **options): True sage: G.position(1) (0.2, 0.3, 0.4, 0.1) + sage: import numpy # to ensure numpy 2.0 compatibility + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") sage: ax1.get_position().bounds # tol 1.0e-13 (0.2, 0.3, 0.4000000000000001, 0.10000000000000003) - """ # Note: using label=str(index) ensures that a new Axes is generated # for each element of ``self``, even if some elements share the same @@ -801,7 +783,7 @@ def position(self, index): INPUT: - - ``index`` -- integer specifiying which element of ``self`` + - ``index`` -- integer specifying which element of ``self`` OUTPUT: @@ -818,7 +800,6 @@ def position(self, index): (0.125, 0.11, 0.775, 0.77) sage: G.position(1) # tol 1.0e-13 (0.15, 0.2, 0.1, 0.15) - """ return self._positions[index] @@ -903,7 +884,6 @@ def append(self, graphics, pos=None): .. SEEALSO:: :meth:`inset` - """ from matplotlib import rcParams if not isinstance(graphics, Graphics): @@ -1081,7 +1061,6 @@ class GraphicsArray(MultiGraphics): G = graphics_array([[g1, g2], [g3, g4]]) G[0] = g4 sphinx_plot(G) - """ def __init__(self, array): r""" @@ -1135,7 +1114,6 @@ def __init__(self, array): Traceback (most recent call last): ... TypeError: every element of array must be a Graphics object - """ MultiGraphics.__init__(self, []) if not isinstance(array, (list, tuple)): @@ -1175,7 +1153,6 @@ def __str__(self): 'Graphics Array of size 2 x 3' sage: str(G) 'Graphics Array of size 2 x 3' - """ return f"Graphics Array of size {self._rows} x {self._cols}" @@ -1190,12 +1167,10 @@ def _add_subplot(self, figure, index, **options): INPUT: - ``figure`` -- a Matplotlib ``Figure`` object - - ``index`` -- integer specifiying the element of ``self`` + - ``index`` -- integer specifying the element of ``self`` - ``options`` -- extra options to be passed to ``Figure.add_subplot`` - OUTPUT: - - - a Matplotlib ``Axes`` object + OUTPUT: a Matplotlib ``Axes`` object EXAMPLES:: @@ -1209,7 +1184,6 @@ def _add_subplot(self, figure, index, **options): sage: ax2 = G._add_subplot(fig, 1) sage: fig.get_axes() == [ax1, ax2] True - """ if self._rows == 0 or self._cols == 0: rows = 1 @@ -1233,7 +1207,6 @@ def nrows(self): 2 sage: graphics_array(L).nrows() 1 - """ return self._rows @@ -1269,7 +1242,6 @@ def append(self, g): ... NotImplementedError: Appending to a graphics array is not yet implemented - """ # Not clear if there is a way to do this raise NotImplementedError('Appending to a graphics array is not ' @@ -1282,7 +1254,7 @@ def position(self, index): INPUT: - - ``index`` -- integer specifiying which element of ``self`` + - ``index`` -- integer specifying which element of ``self`` OUTPUT: @@ -1295,6 +1267,9 @@ def position(self, index): sage: g1 = plot(sin(x), (x, -pi, pi)) sage: g2 = circle((0,1), 1.) sage: G = graphics_array([g1, g2]) + sage: import numpy # to ensure numpy 2.0 compatibility + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") sage: G.position(0) # tol 5.0e-3 (0.025045451349937315, 0.03415488992713045, @@ -1305,7 +1280,6 @@ def position(self, index): 0.20212705964722733, 0.4489880779745068, 0.5986507706326758) - """ if not self._positions: # self._positions must be generated, by invoking get_position() on diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index 5184374756e..d1e21abe20a 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -7,7 +7,7 @@ The following graphics primitives are supported: -- :func:`~sage.plot.arrow.arrow` -- an arrow from a min point to a max point. +- :func:`~sage.plot.arrow.arrow` -- an arrow from a min point to a max point - :func:`~sage.plot.circle.circle` -- a circle with given radius @@ -30,7 +30,7 @@ The following plotting functions are supported: - :func:`plot` -- plot of a function or other Sage object (e.g., elliptic - curve). + curve) - :func:`parametric_plot` @@ -419,14 +419,14 @@ def y(x): return x*sin(x**2) Pi Axis:: sage: g1 = plot(sin(x), 0, 2*pi) - sage: g2 = plot(cos(x), 0, 2*pi, linestyle="--") + sage: g2 = plot(cos(x), 0, 2*pi, linestyle='--') sage: (g1 + g2).show(ticks=pi/6, # show their sum, nicely formatted # long time ....: tick_formatter=pi) .. PLOT:: g1 = plot(sin(x), 0, 2*pi, ticks=pi/6, tick_formatter=pi) - g2 = plot(cos(x), 0, 2*pi, linestyle="--", ticks=pi/6, tick_formatter=pi) + g2 = plot(cos(x), 0, 2*pi, linestyle='--', ticks=pi/6, tick_formatter=pi) sphinx_plot(g1+g2) An illustration of integration:: @@ -477,10 +477,10 @@ def f(x): return (x-3)*(x-5)*(x-7)+40 sage: t = plt.title('About as simple as it gets, folks') sage: plt.grid(True) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f1: + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f1: ....: plt.savefig(f1.name) sage: plt.clf() - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f2: + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f2: ....: plt.savefig(f2.name) sage: plt.close() sage: plt.imshow([[1,2],[0,1]]) @@ -494,7 +494,7 @@ def f(x): return (x-3)*(x-5)*(x-7)+40 sage: plt.imshow([[(0.0,0.0,0.0)]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: ....: plt.savefig(f.name) Since the above overwrites many Sage plotting functions, we reset @@ -698,9 +698,8 @@ def SelectiveFormatter(formatter, skip_values): ....: skip_values=[0,1]) sage: ax.xaxis.set_major_formatter(formatter) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.png') as f: ....: fig.savefig(f.name) - """ global _SelectiveFormatterClass if _SelectiveFormatterClass is None: @@ -714,9 +713,9 @@ def __init__(self, formatter, skip_values): INPUT: - - formatter -- the formatter object to which we should pass labels + - ``formatter`` -- the formatter object to which we should pass labels - - skip_values -- a list of values that we should skip when + - ``skip_values`` -- list of values that we should skip when formatting the tick labels EXAMPLES:: @@ -734,7 +733,7 @@ def __init__(self, formatter, skip_values): ....: skip_values=[0,1]) sage: ax.xaxis.set_major_formatter(formatter) sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".png") as f: + sage: with NamedTemporaryFile(suffix='.png') as f: ....: fig.savefig(f.name) """ self.formatter = formatter @@ -756,7 +755,7 @@ def set_locs(self, locs): def __call__(self, x, *args, **kwds): """ - Return the format for tick val *x* at position *pos* + Return the format for tick val *x* at position *pos*. EXAMPLES:: @@ -847,7 +846,7 @@ def xydata_from_point_list(points): aspect_ratio='automatic', imaginary_tolerance=1e-8) def plot(funcs, *args, **kwds): r""" - Use plot by writing + Use plot by writing. ``plot(X, ...)`` @@ -868,40 +867,40 @@ def plot(funcs, *args, **kwds): PLOT OPTIONS: - - ``plot_points`` -- (default: `200`); the minimal number of plot points. + - ``plot_points`` -- (default: 200) the minimal number of plot points - - ``adaptive_recursion`` -- (default: `5`); how many levels of recursion to go + - ``adaptive_recursion`` -- (default: 5) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement. - - ``adaptive_tolerance`` -- (default: `0.01`); how large a difference should be + - ``adaptive_tolerance`` -- (default: 0.01) how large a difference should be before the adaptive refinement code considers it significant. See the documentation further below for more information, starting at "the algorithm used to insert". - - ``imaginary_tolerance`` -- (default: ``1e-8``); if an imaginary + - ``imaginary_tolerance`` -- (default: ``1e-8``) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than this are ignored in your plot points. - - ``base`` -- (default: `10`); the base of the logarithm if + - ``base`` -- (default: `10`) the base of the logarithm if a logarithmic scale is set. This must be greater than 1. The base can be also given as a list or tuple ``(basex, basey)``. ``basex`` sets the base of the logarithm along the horizontal axis and ``basey`` sets the base along the vertical axis. - - ``scale`` -- string (default: ``"linear"``); scale of the axes. - Possible values are ``"linear"``, ``"loglog"``, ``"semilogx"``, - ``"semilogy"``. + - ``scale`` -- string (default: ``'linear'``); scale of the axes. + Possible values are ``'linear'``, ``'loglog'``, ``'semilogx'``, + ``'semilogy'``. The scale can be also be given as single argument that is a list or tuple ``(scale, base)`` or ``(scale, basex, basey)``. - The ``"loglog"`` scale sets both the horizontal and vertical axes to - logarithmic scale. The ``"semilogx"`` scale sets the horizontal axis - to logarithmic scale. The ``"semilogy"`` scale sets the vertical axis - to logarithmic scale. The ``"linear"`` scale is the default value + The ``'loglog'`` scale sets both the horizontal and vertical axes to + logarithmic scale. The ``'semilogx'`` scale sets the horizontal axis + to logarithmic scale. The ``'semilogy'`` scale sets the vertical axis + to logarithmic scale. The ``'linear'`` scale is the default value when :class:`~sage.plot.graphics.Graphics` is initialized. - ``xmin`` -- starting x value in the rendered figure. This parameter is @@ -916,7 +915,7 @@ def plot(funcs, *args, **kwds): - ``ymax`` -- ending y value in the rendered figure. This parameter is passed directly to the ``show`` procedure and it could be overwritten. - - ``detect_poles`` -- (default: ``False``) If set to ``True`` poles are detected. + - ``detect_poles`` -- boolean (default: ``False``); if set to ``True`` poles are detected. If set to "show" vertical asymptotes are drawn. - ``legend_label`` -- a (TeX) string serving as the label for `X` in the legend. @@ -925,7 +924,7 @@ def plot(funcs, *args, **kwds): .. NOTE:: - - If the ``scale`` is ``"linear"``, then irrespective of what + - If the ``scale`` is ``'linear'``, then irrespective of what ``base`` is set to, it will default to 10 and will remain unused. - If you want to limit the plot along the horizontal axis in the @@ -951,11 +950,11 @@ def plot(funcs, *args, **kwds): COLOR OPTIONS: - - ``color`` -- (Default: 'blue') One of: + - ``color`` -- (default: ``'blue'``) one of: - an RGB tuple (r,g,b) with each of r,g,b between 0 and 1. - - a color name as a string (e.g., 'purple'). + - a color name as a string (e.g., ``'purple'``). - an HTML color such as '#aaff0b'. @@ -963,14 +962,14 @@ def plot(funcs, *args, **kwds): if a dictionary, keys are taken from ``range(len(X))``; the entries/values of the list/dictionary may be any of the options above. - - 'automatic' -- maps to default ('blue') if `X` is a single Sage object; and - maps to a fixed sequence of regularly spaced colors if `X` is a list. + - ``'automatic'`` -- maps to default ('blue') if `X` is a single Sage object; and + maps to a fixed sequence of regularly spaced colors if `X` is a list - ``legend_color`` -- the color of the text for `X` (or each item in `X`) in the legend. - Default color is 'black'. Options are as in ``color`` above, except that the choice 'automatic' maps to 'black' if `X` is a single Sage object. + Default color is 'black'. Options are as in ``color`` above, except that the choice 'automatic' maps to 'black' if `X` is a single Sage object - - ``fillcolor`` -- The color of the fill for the plot of `X` (or each item in `X`). - Default color is 'gray' if `X` is a single Sage object or if ``color`` is a single color. Otherwise, options are as in ``color`` above. + - ``fillcolor`` -- the color of the fill for the plot of `X` (or each item in `X`). + Default color is 'gray' if `X` is a single Sage object or if ``color`` is a single color. Otherwise, options are as in ``color`` above APPEARANCE OPTIONS: @@ -992,30 +991,30 @@ def plot(funcs, *args, **kwds): Any MATPLOTLIB line option may also be passed in. E.g., - - ``linestyle`` -- (default: "-") The style of the line, which is one of + - ``linestyle`` -- (default: ``'-'``) the style of the line, which is one of - - ``"-"`` or ``"solid"`` - - ``"--"`` or ``"dashed"`` - - ``"-."`` or ``"dash dot"`` - - ``":"`` or ``"dotted"`` + - ``'-'`` or ``'solid'`` + - ``'--'`` or ``'dashed'`` + - ``'-.'`` or ``'dash dot'`` + - ``':'`` or ``'dotted'`` - ``"None"`` or ``" "`` or ``""`` (nothing) - a list or dictionary (see below) - The linestyle can also be prefixed with a drawing style (e.g., ``"steps--"``) + The linestyle can also be prefixed with a drawing style (e.g., ``'steps--'``) - - ``"default"`` (connect the points with straight lines) - - ``"steps"`` or ``"steps-pre"`` (step function; horizontal + - ``'default'`` (connect the points with straight lines) + - ``'steps'`` or ``'steps-pre'`` (step function; horizontal line is to the left of point) - - ``"steps-mid"`` (step function; points are in the middle of + - ``'steps-mid'`` (step function; points are in the middle of horizontal lines) - - ``"steps-post"`` (step function; horizontal line is to the + - ``'steps-post'`` (step function; horizontal line is to the right of point) If `X` is a list, then ``linestyle`` may be a list (with entries taken from the strings above) or a dictionary (with keys in ``range(len(X))`` and values taken from the strings above). - - ``marker`` -- The style of the markers, which is one of + - ``marker`` -- the style of the markers, which is one of - ``"None"`` or ``" "`` or ``""`` (nothing) -- default - ``","`` (pixel), ``"."`` (point) @@ -1042,12 +1041,12 @@ def plot(funcs, *args, **kwds): - ``markeredgewidth`` -- the size of the marker edge in points - - ``exclude`` -- (Default: None) values which are excluded from the plot range. + - ``exclude`` -- (default: ``None``) values which are excluded from the plot range. Either a list of real numbers, or an equation in one variable. FILLING OPTIONS: - - ``fill`` -- (default: ``False``) One of: + - ``fill`` -- boolean (default: ``False``); one of: - "axis" or ``True``: Fill the area between the function and the x-axis. @@ -1066,12 +1065,12 @@ def plot(funcs, *args, **kwds): the j-th function in the list. (But if ``d[i] == j``: Fill the area between the i-th function in the list and the horizontal line y = j.) - - ``fillalpha`` -- (default: `0.5`) How transparent the fill is. - A number between 0 and 1. + - ``fillalpha`` -- (default: 0.5) how transparent the fill is; + a number between 0 and 1 MATPLOTLIB STYLE SHEET OPTION: - - ``stylesheet`` -- (Default: classic) Support for loading a full matplotlib style sheet. + - ``stylesheet`` -- (default: classic) support for loading a full matplotlib style sheet. Any style sheet listed in ``matplotlib.pyplot.style.available`` is acceptable. If a non-existing style is provided the default classic is applied. @@ -1774,12 +1773,12 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) sage: plot(2*x + 1, (x, 0, 5), ....: ticks=[[0, 1, e, pi, sqrt(20)], ....: [1, 3, 2*e + 1, 2*pi + 1, 2*sqrt(20) + 1]], - ....: tick_formatter="latex") + ....: tick_formatter='latex') Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot(2*x + 1, (x, 0, 5), ticks=[[0, 1, e, pi, sqrt(20)], [1, 3, 2*e + 1, 2*pi + 1, 2*sqrt(20) + 1]], tick_formatter="latex") + g = plot(2*x + 1, (x, 0, 5), ticks=[[0, 1, e, pi, sqrt(20)], [1, 3, 2*e + 1, 2*pi + 1, 2*sqrt(20) + 1]], tick_formatter='latex') sphinx_plot(g) This is particularly useful when setting custom ticks in multiples of `\pi`. @@ -2097,7 +2096,7 @@ def _plot(funcs, xrange, parametric=False, The following option is deprecated in favor of ``legend_label``: - - ``label`` -- (default: '') a string for the label + - ``label`` -- (default: ``''``) a string for the label All other usual plot options are also accepted, and a number are required (see the example below) which are normally passed @@ -2150,7 +2149,7 @@ def _plot(funcs, xrange, parametric=False, Make sure that we don't get multiple legend labels for plot segments (:issue:`11998`):: - sage: p1 = plot(1/(x^2-1),(x,-2,2),legend_label="foo",detect_poles=True) + sage: p1 = plot(1/(x^2-1),(x,-2,2),legend_label='foo',detect_poles=True) sage: len(p1.matplotlib().axes[0].legend().texts) 1 sage: p1.show(ymin=-10,ymax=10) # should be one legend @@ -2165,7 +2164,6 @@ def _plot(funcs, xrange, parametric=False, sage: plot(x, -1, 1, detect_poles=True) Graphics object consisting of 1 graphics primitive - """ from sage.plot.colors import Color from sage.plot.misc import setup_for_eval_on_grid @@ -2569,9 +2567,9 @@ def parametric_plot(funcs, *args, **kwargs): INPUT: - - ``funcs`` -- 2 or 3-tuple of functions, or a vector of dimension 2 or 3. + - ``funcs`` -- 2 or 3-tuple of functions, or a vector of dimension 2 or 3 - - ``other options`` -- passed to :func:`plot` or :func:`~sage.plot.plot3d.parametric_plot3d.parametric_plot3d` + - ``other options`` -- passed to :func:`plot` or :func:`~sage.plot.plot3d.parametric_plot3d.parametric_plot3d` EXAMPLES: We draw some 2d parametric plots. Note that the default aspect ratio is 1, so that circles look like circles. :: @@ -2635,13 +2633,13 @@ def parametric_plot(funcs, *args, **kwargs): :: sage: parametric_plot((5*cos(x), 5*sin(x), x), (x, -12, 12), # long time - ....: plot_points=150, color="red") + ....: plot_points=150, color='red') Graphics3d Object .. PLOT:: #AttributeError: 'Line' object has no attribute 'plot' - #g = parametric_plot( (5*cos(x), 5*sin(x), x), (x,-12, 12), plot_points=150, color="red") # long time + #g = parametric_plot( (5*cos(x), 5*sin(x), x), (x,-12, 12), plot_points=150, color='red') # long time #sphinx_plot(g) :: @@ -2865,7 +2863,6 @@ def polar_plot(funcs, *args, **kwds): g = polar_plot(log(floor(x)), (x, 1, 4*pi), exclude=list(range(1,13))) sphinx_plot(g) - """ kwds['polar'] = True return plot(funcs, *args, **kwds) @@ -3170,12 +3167,12 @@ def plot_loglog(funcs, *args, **kwds): INPUT: - - ``base`` -- (default: `10`); the base of the logarithm. This must be + - ``base`` -- (default: `10`) the base of the logarithm; this must be greater than 1. The base can be also given as a list or tuple ``(basex, basey)``. ``basex`` sets the base of the logarithm along the horizontal axis and ``basey`` sets the base along the vertical axis. - - ``funcs`` -- any Sage object which is acceptable to the :func:`plot`. + - ``funcs`` -- any Sage object which is acceptable to the :func:`plot` For all other inputs, look at the documentation of :func:`plot`. @@ -3208,7 +3205,6 @@ def plot_loglog(funcs, *args, **kwds): g = plot_loglog(exp, (1,10), base=(2,3)) sphinx_plot(g) - """ return plot(funcs, *args, scale='loglog', **kwds) @@ -3221,10 +3217,10 @@ def plot_semilogx(funcs, *args, **kwds): INPUT: - - ``base`` -- (default: `10`); the base of the logarithm. This must be - greater than 1. + - ``base`` -- (default: `10`) the base of the logarithm; this must be + greater than 1 - - ``funcs`` -- any Sage object which is acceptable to the :func:`plot`. + - ``funcs`` -- any Sage object which is acceptable to the :func:`plot` For all other inputs, look at the documentation of :func:`plot`. @@ -3261,7 +3257,6 @@ def plot_semilogx(funcs, *args, **kwds): f = 4000000/(4000000 + 4000*s*i - s*s) g = plot_semilogx(20*log(abs(f), 10), (s, 1, 1e6)) sphinx_plot(g) - """ return plot(funcs, *args, scale='semilogx', **kwds) @@ -3274,10 +3269,10 @@ def plot_semilogy(funcs, *args, **kwds): INPUT: - - ``base`` -- (default: `10`); the base of the logarithm. This must be - greater than 1. + - ``base`` -- (default: `10`) the base of the logarithm; this must be + greater than 1 - - ``funcs`` -- any Sage object which is acceptable to the :func:`plot`. + - ``funcs`` -- any Sage object which is acceptable to the :func:`plot` For all other inputs, look at the documentation of :func:`plot`. @@ -3300,7 +3295,6 @@ def plot_semilogy(funcs, *args, **kwds): g = plot_semilogy(exp, (1,10), base=2) # long time # with base 2 sphinx_plot(g) - """ return plot(funcs, *args, scale='semilogy', **kwds) @@ -3313,7 +3307,7 @@ def list_plot_loglog(data, plotjoined=False, **kwds): INPUT: - - ``base`` -- (default: `10`); the base of the logarithm. This must be + - ``base`` -- (default: `10`) the base of the logarithm; this must be greater than 1. The base can be also given as a list or tuple ``(basex, basey)``. ``basex`` sets the base of the logarithm along the horizontal axis and ``basey`` sets the base along the vertical axis. @@ -3368,7 +3362,6 @@ def list_plot_loglog(data, plotjoined=False, **kwds): sage: list_plot_loglog(list(zip(range(1,len(yl)), yl[1:]))) Graphics object consisting of 1 graphics primitive - """ return list_plot(data, plotjoined=plotjoined, scale='loglog', **kwds) @@ -3381,8 +3374,8 @@ def list_plot_semilogx(data, plotjoined=False, **kwds): INPUT: - - ``base`` -- (default: `10`); the base of the logarithm. This must be - greater than 1. + - ``base`` -- (default: `10`) the base of the logarithm; this must be + greater than 1 For all other inputs, look at the documentation of :func:`list_plot`. @@ -3424,7 +3417,6 @@ def list_plot_semilogx(data, plotjoined=False, **kwds): g = list_plot_semilogx([(1,2),(3,4),(3,-1),(25,3)], base=2) sphinx_plot(g) - """ return list_plot(data, plotjoined=plotjoined, scale='semilogx', **kwds) @@ -3437,8 +3429,8 @@ def list_plot_semilogy(data, plotjoined=False, **kwds): INPUT: - - ``base`` -- (default: `10`); the base of the logarithm. This must be - greater than 1. + - ``base`` -- (default: `10`) the base of the logarithm; this must be + greater than 1 For all other inputs, look at the documentation of :func:`list_plot`. @@ -3483,7 +3475,6 @@ def list_plot_semilogy(data, plotjoined=False, **kwds): g = list_plot_semilogy([2, 4, 6, 8, 16, 31], base=2) sphinx_plot(g) - """ return list_plot(data, plotjoined=plotjoined, scale='semilogy', **kwds) @@ -3512,11 +3503,11 @@ def reshape(v, n, m): INPUT: - - ``v`` -- a list of lists or tuples + - ``v`` -- list of lists or tuples - - ``n, m`` -- integers + - ``n``, ``m`` -- integers - OUTPUT: a list of lists of graphics objects + OUTPUT: list of lists of graphics objects EXAMPLES:: @@ -3709,7 +3700,6 @@ def h(x): return sin(4*x) .. SEEALSO:: :class:`~sage.plot.multigraphics.GraphicsArray` for more examples - """ # TODO: refactor the whole array flattening and reshaping into a class if nrows is None and ncols is None: @@ -3749,7 +3739,7 @@ def multi_graphics(graphics_list): INPUT: - - ``graphics_list`` -- a list of graphics along with their + - ``graphics_list`` -- list of graphics along with their positions on the canvas; each element of ``graphics_list`` is either - a pair ``(graphics, position)``, where ``graphics`` is a @@ -3810,7 +3800,6 @@ def multi_graphics(graphics_list): .. SEEALSO:: :class:`~sage.plot.multigraphics.MultiGraphics` for more examples - """ return MultiGraphics(graphics_list) @@ -3863,17 +3852,17 @@ def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, - ``p1``, ``p2`` -- two points to refine between - - ``adaptive_recursion`` -- (default: `5`); how many + - ``adaptive_recursion`` -- (default: `5`) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement. - - ``adaptive_tolerance`` -- (default: `0.01`); how large + - ``adaptive_tolerance`` -- (default: `0.01`) how large a relative difference should be before the adaptive refinement code considers it significant; see documentation for generate_plot_points for more information. See the documentation for :func:`plot` for more information on how the adaptive refinement algorithm works. - - ``excluded`` -- (default: ``False``); also return locations where it has been + - ``excluded`` -- (default: ``False``) also return locations where it has been discovered that the function is not defined (y-value will be ``'NaN'`` in this case) @@ -3977,26 +3966,26 @@ def generate_plot_points(f, xrange, plot_points=5, adaptive_tolerance=0.01, - ``p1``, ``p2`` -- two points to refine between - - ``plot_points`` -- (default: `5`); the minimal number of plot points. (Note + - ``plot_points`` -- (default: 5) the minimal number of plot points. (Note however that in any actual plot a number is passed to this, with default value 200.) - - ``adaptive_recursion`` -- (default: `5`); how many levels of recursion to go + - ``adaptive_recursion`` -- (default: 5) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement. - - ``adaptive_tolerance`` -- (default: `0.01`); how large the relative difference + - ``adaptive_tolerance`` -- (default: 0.01) how large the relative difference should be before the adaptive refinement code considers it significant. If the actual difference is greater than adaptive_tolerance*delta, where delta is the initial subinterval size for the given xrange and plot_points, then the algorithm will consider it significant. - - ``initial_points`` -- (default: ``None``); a list of x-values that should be evaluated. + - ``initial_points`` -- (default: ``None``) a list of x-values that should be evaluated - - ``excluded`` -- (default: ``False``); add a list of discovered x-values, for + - ``excluded`` -- (default: ``False``) add a list of discovered x-values, for which ``f`` is not defined - - ``imaginary_tolerance`` -- (default: ``1e-8``); if an imaginary + - ``imaginary_tolerance`` -- (default: ``1e-8``) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 4c09ea7e7c7..0f3cca16607 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -84,7 +84,7 @@ cdef class Graphics3d(SageObject): """ def __cinit__(self): """ - The Cython constructor + The Cython constructor. EXAMPLES:: @@ -108,9 +108,7 @@ cdef class Graphics3d(SageObject): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -122,7 +120,7 @@ cdef class Graphics3d(SageObject): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -133,7 +131,6 @@ cdef class Graphics3d(SageObject): sage: g = sphere() sage: g._rich_repr_(dm) # OutputSceneThreejs container outside doctest mode OutputSceneJmol container - """ ### First, figure out the best graphics format types = display_manager.types @@ -191,8 +188,8 @@ cdef class Graphics3d(SageObject): the rendered image (can be png, gif, or jpg). Determines the type of the output. - - ``**kwds`` -- Optional keyword arguments are passed to the - Tachyon raytracer. + - ``**kwds`` -- optional keyword arguments are passed to the + Tachyon raytracer OUTPUT: @@ -245,11 +242,11 @@ cdef class Graphics3d(SageObject): def _rich_repr_jmol(self, **kwds): """ - Rich Representation as JMol scene + Rich Representation as JMol scene. INPUT: - Optional keyword arguments are passed to JMol. + - ``**kwds`` -- optional keyword arguments are passed to JMol OUTPUT: @@ -288,7 +285,7 @@ cdef class Graphics3d(SageObject): script = '''set defaultdirectory "{0}"\nscript SCRIPT\n'''.format(scene_native) jdata.export_image(targetfile=preview_png, datafile=script, - image_type="PNG", + image_type='PNG', figsize=opts['figsize'][0]) from sage.repl.rich_output.output_graphics3d import OutputSceneJmol from sage.repl.rich_output.buffer import OutputBuffer @@ -298,11 +295,11 @@ cdef class Graphics3d(SageObject): def _rich_repr_wavefront(self, **kwds): r""" - Rich Representation as Wavefront (obj + mtl) Scene + Rich Representation as Wavefront (obj + mtl) Scene. INPUT: - Optional keyword arguments are ignored. + - ``**kwds`` -- optional keyword arguments are ignored OUTPUT: @@ -327,11 +324,11 @@ cdef class Graphics3d(SageObject): def _rich_repr_canvas3d(self, **kwds): r""" - Rich Representation as Canvas3D Scene + Rich Representation as Canvas3D Scene. INPUT: - Optional keyword arguments. + - ``**kwds`` -- optional keyword arguments OUTPUT: @@ -360,11 +357,11 @@ cdef class Graphics3d(SageObject): def _rich_repr_threejs(self, **kwds): r""" - Rich Representation as Three.js Scene + Rich Representation as Three.js Scene. INPUT: - Optional keyword arguments. + - ``**kwds`` -- optional keyword arguments OUTPUT: @@ -440,7 +437,6 @@ cdef class Graphics3d(SageObject): sage: str = d._rich_repr_threejs(online=True).html.get_str() sage: '"Page" & <Title>' in str True - """ options = self._process_viewing_options(kwds) options.setdefault('online', False) @@ -927,7 +923,7 @@ cdef class Graphics3d(SageObject): """ params = RenderParams(ds=.075) - fn = tmp_filename(ext=".zip") + fn = tmp_filename(ext='.zip') params.output_archive = zipfile.ZipFile(fn, 'w', zipfile.ZIP_STORED, True) return params @@ -968,7 +964,6 @@ cdef class Graphics3d(SageObject): - """ return """ @@ -1006,7 +1001,7 @@ cdef class Graphics3d(SageObject): # Instead, the tachyon aspectratio is set to match nonsquare # drawing area in "figsize". - # Parameters are mostly taken from tachyion.py, + # Parameters are mostly taken from tachyon.py, # but camera_center is renamed camera_position. # Apparently reST strips () from default parameters in the automatic documentation. # Thus, I replaced () by [] as default values. @@ -1162,7 +1157,7 @@ end_scene""".format( @staticmethod def _tostring(s): r""" - Converts vector information to a space-separated string. + Convert vector information to a space-separated string. EXAMPLES:: @@ -1184,7 +1179,7 @@ end_scene""".format( EXAMPLES:: - sage: out_file = tmp_filename(ext=".jmol") + sage: out_file = tmp_filename(ext='.jmol') sage: G = sphere((1, 2, 3), 5) + cube() + sage.plot.plot3d.shapes.Text("hi") sage: G.export_jmol(out_file) sage: import zipfile @@ -1389,7 +1384,6 @@ end_scene""".format( sage: G = sage.plot.plot3d.base.Graphics3d() sage: G.threejs_repr(G.default_render_params()) [] - """ return [] @@ -1556,11 +1550,11 @@ end_scene""".format( # draw axes from sage.plot.plot3d.shapes import arrow3d A = (arrow3d((min(0,a_min[0]),0, 0), (max(0,a_max[0]), 0,0), - thickness, color="blue"), + thickness, color='blue'), arrow3d((0,min(0,a_min[1]), 0), (0, max(0,a_max[1]), 0), - thickness, color="blue"), + thickness, color='blue'), arrow3d((0, 0, min(0,a_min[2])), (0, 0, max(0,a_max[2])), - thickness, color="blue")) + thickness, color='blue')) X += sum(A).translate([-z for z in T]) return X @@ -1626,7 +1620,7 @@ end_scene""".format( def show(self, **kwds): r""" - Display graphics immediately + Display graphics immediately. This method attempts to display the graphics immediately, without waiting for the currently running code (if any) to @@ -1636,8 +1630,8 @@ end_scene""".format( INPUT: - - ``viewer`` -- string (default: ``'threejs'``), how to view the plot; - admissible values are + - ``viewer`` -- string (default: ``'threejs'``); how to view the plot. + Admissible values are * ``'threejs'``: interactive web-based 3D viewer using JavaScript and a WebGL renderer @@ -1651,52 +1645,52 @@ end_scene""".format( * ``'canvas3d'``: web-based 3D viewer using JavaScript and a canvas renderer (Sage notebook only) - - ``verbosity`` -- display information about rendering - the figure + - ``verbosity`` -- display information about rendering + the figure - - ``figsize`` -- (default: 5); x or pair [x,y] for - numbers, e.g., [5,5]; controls the size of the output figure. - With 'tachyon', the resolution (in number of pixels) is 100 times - ``figsize``. This is ignored for the jmol embedded renderer. + - ``figsize`` -- (default: 5) x or pair [x,y] for + numbers, e.g., [5,5]; controls the size of the output figure. + With 'tachyon', the resolution (in number of pixels) is 100 times + ``figsize``. This is ignored for the jmol embedded renderer. - - ``aspect_ratio`` -- (default: ``'automatic'``) -- aspect - ratio of the coordinate system itself. Give [1,1,1] or 1 to make spheres - look round. + - ``aspect_ratio`` -- (default: ``'automatic'``) aspect + ratio of the coordinate system itself; give [1,1,1] or 1 to make + spheres look round - - ``frame_aspect_ratio`` -- (default: ``'automatic'``) - aspect ratio of frame that contains the 3d scene. + - ``frame_aspect_ratio`` -- (default: ``'automatic'``) + aspect ratio of frame that contains the 3d scene - - ``zoom`` -- (default: 1) how zoomed in + - ``zoom`` -- (default: 1) how zoomed in - - ``frame`` -- (default: ``True``) if True, draw a - bounding frame with labels + - ``frame`` -- boolean (default: ``True``); if ``True``, draw a + bounding frame with labels - - ``axes`` -- (default: ``False``) if True, draw coordinate - axes + - ``axes`` -- boolean (default: ``False``); if ``True``, draw coordinate + axes - - ``camera_position`` (for tachyon) -- (default: (2.3, 2.4, 2.0)) - the viewpoint, with respect to the cube - $[-1,1]\\times[-1,1]\\times[-1,1]$, - into which the bounding box of the scene - is scaled and centered. - The default viewing direction is towards the origin. + - ``camera_position`` -- (for tachyon) (default: (2.3, 2.4, 2.0)) + the viewpoint, with respect to the cube + $[-1,1]\\times[-1,1]\\times[-1,1]$, + into which the bounding box of the scene + is scaled and centered. + The default viewing direction is towards the origin. - - ``viewdir`` (for tachyon) -- (default: None) three coordinates - specifying the viewing direction. + - ``viewdir`` -- (for tachyon) (default: ``None``) three coordinates + specifying the viewing direction - - ``updir`` (for tachyon) -- (default: (0,0,1)) the "upward" - direction of the camera + - ``updir`` -- (for tachyon) (default: (0,0,1)) the "upward" + direction of the camera - - ``light_position`` (for tachyon) -- (default: (4,3,2)) the position - of the single light source in the scene (in addition to ambient light) + - ``light_position`` -- (for tachyon) (default: (4,3,2)) the position + of the single light source in the scene (in addition to ambient light) - - ``antialiasing`` (for tachyon) -- (default: ``False``) + - ``antialiasing`` -- (for tachyon) (default: ``False``) - - ``raydepth`` (for tachyon) -- (default: 8) - see the :class:`sage.plot.plot3d.tachyon.Tachyon` class + - ``raydepth`` -- (for tachyon) (default: 8) + see the :class:`sage.plot.plot3d.tachyon.Tachyon` class - - ``shade`` (for tachyon) -- string (default: ``'full'``); - shading options. Admissible values are + - ``shade`` -- (for tachyon) string (default: ``'full'``); + shading options. Admissible values are * ``'full'``: best quality rendering (and slowest). Sets tachyon command line flag ``-fullshade``. @@ -1710,11 +1704,11 @@ end_scene""".format( * ``'lowest'``: worst quality rendering, preview (and fastest). Sets tachyon command line flag ``-lowestshade``. - - ``extra_opts`` (for tachyon) -- string (default: empty string); - extra options that will be appended to the tachyon command line. + - ``extra_opts`` -- (for tachyon) string (default: empty string); + extra options that will be appended to the tachyon command line - - ``**kwds`` -- other options, which make sense for particular - rendering engines + - ``**kwds`` -- other options, which make sense for particular + rendering engines OUTPUT: @@ -1729,11 +1723,11 @@ end_scene""".format( If this is not desired, one can set ``aspect_ratio=1``:: sage: p = plot3d(lambda u,v:(cos(u)-cos(v)), (-0.2,0.2),(-0.2,0.2)) - sage: p.show(viewer="threejs") - sage: p.show(viewer="jmol") - sage: p.show(viewer="jmol",aspect_ratio=1) - sage: p.show(viewer="tachyon",camera_position=(4,0,0)) - sage: p.show(viewer="tachyon",camera_position=(2,2,0.3),aspect_ratio=1) + sage: p.show(viewer='threejs') + sage: p.show(viewer='jmol') + sage: p.show(viewer='jmol',aspect_ratio=1) + sage: p.show(viewer='tachyon',camera_position=(4,0,0)) + sage: p.show(viewer='tachyon',camera_position=(2,2,0.3),aspect_ratio=1) CHANGING DEFAULTS: Defaults can be uniformly changed by importing a dictionary and changing it. For example, here we change the default @@ -1784,12 +1778,12 @@ end_scene""".format( Sometimes shadows in Tachyon-produced images can lead to confusing plots. To remove them:: - sage: p.show(viewer="tachyon", shade="medium") # needs sage.symbolic + sage: p.show(viewer='tachyon', shade='medium') # needs sage.symbolic One can also pass Tachyon command line flags directly. For example, the following line produces the same result as the previous one:: - sage: p.show(viewer="tachyon", extra_opts="-mediumshade") # needs sage.symbolic + sage: p.show(viewer='tachyon', extra_opts='-mediumshade') # needs sage.symbolic """ from sage.repl.rich_output import get_display_manager dm = get_display_manager() @@ -1840,8 +1834,8 @@ end_scene""".format( INPUT: - - ``filename`` -- string. The file name under which to save - the image. + - ``filename`` -- string; the file name under which to save + the image Any further keyword arguments are passed to the renderer. @@ -1893,9 +1887,9 @@ end_scene""".format( INPUT: - - ``filename`` -- string. Where to save the image or object. + - ``filename`` -- string; where to save the image or object - - ``**kwds`` -- When specifying an image file to be rendered by Tachyon + - ``**kwds`` -- when specifying an image file to be rendered by Tachyon or Jmol, any of the viewing options accepted by :meth:`show` are valid as keyword arguments to this function and they will behave in the same way. Accepted keywords include: ``viewer``, ``verbosity``, @@ -1935,7 +1929,6 @@ end_scene""".format( sage: f = tmp_filename(ext='.html') sage: G.save(f, frame=False, online=True) - """ ext = os.path.splitext(filename)[1].lower() if ext == '' or ext == '.sobj': @@ -1973,9 +1966,7 @@ end_scene""".format( This only works for surfaces, transforms and unions of surfaces, but not for general plot objects! - OUTPUT: - - A binary string that represents the surface in the binary STL format. + OUTPUT: a binary string that represents the surface in the binary STL format See :wikipedia:`STL_(file_format)` @@ -2010,7 +2001,7 @@ end_scene""".format( N_triangles = len(data) return b''.join([header, struct.pack('I', N_triangles)] + data) - def stl_ascii_string(self, name="surface"): + def stl_ascii_string(self, name='surface'): """ Return an STL (STereoLithography) representation of the surface. @@ -2020,11 +2011,9 @@ end_scene""".format( INPUT: - - ``name`` (string, default: "surface") -- name of the surface. - - OUTPUT: + - ``name`` -- string (default: ``'surface'``); name of the surface - A string that represents the surface in the STL format. + OUTPUT: string that represents the surface in the STL format See :wikipedia:`STL_(file_format)` @@ -2113,19 +2102,17 @@ end_scene""".format( string_list += ["endsolid {}".format(name)] return "".join(string_list) - def ply_ascii_string(self, name="surface"): + def ply_ascii_string(self, name='surface'): """ Return a PLY (Polygon File Format) representation of the surface. INPUT: - - ``name`` (string, default: "surface") -- name of the surface. - - OUTPUT: + - ``name`` -- string (default: ``'surface'``); name of the surface - A string that represents the surface in the PLY format. + OUTPUT: string that represents the surface in the PLY format - See :wikipedia:`PLY_(file_format)` + See :wikipedia:`PLY_(file_format)`. EXAMPLES:: @@ -2179,7 +2166,7 @@ end_scene""".format( return "".join(string_list) - def amf_ascii_string(self, name="surface"): + def amf_ascii_string(self, name='surface'): """ Return an AMF (Additive Manufacturing File Format) representation of the surface. @@ -2190,13 +2177,11 @@ end_scene""".format( INPUT: - - ``name`` (string, default: "surface") -- name of the surface. + - ``name`` -- string (default: ``'surface'``); name of the surface - OUTPUT: - - A string that represents the surface in the AMF format. + OUTPUT: string that represents the surface in the AMF format - See :wikipedia:`Additive_Manufacturing_File_Format` + See :wikipedia:`Additive_Manufacturing_File_Format`. .. TODO:: @@ -2249,7 +2234,6 @@ end_scene""".format( sage: S = sphere((0,0,0), 2) sage: S.plot() is S True - """ return self @@ -2476,7 +2460,6 @@ class Graphics3dGroup(Graphics3d): 'linewidth': 1.0, 'opacity': 1.0, 'points': [(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)]})] - """ reprs = [] for g in self.all: @@ -2756,7 +2739,6 @@ class TransformGroup(Graphics3dGroup): 'opacity': 1.0, 'point': (30.0, 30.0, 30.0), 'size': 5.0})] - """ render_params.push_transform(self.get_transformation()) rep = Graphics3dGroup.threejs_repr(self, render_params) @@ -2843,14 +2825,13 @@ class KeyframeAnimationGroup(Graphics3dGroup): sage: type(animate(frames).interactive()) - """ Graphics3dGroup.__init__(self, all) self._extra_kwds.update(kwds) def threejs_repr(self, render_params): r""" - Adds keyframe information to the representations of the group's contents. + Add keyframe information to the representations of the group's contents. EXAMPLES:: @@ -2871,7 +2852,6 @@ class KeyframeAnimationGroup(Graphics3dGroup): [('point', {..., 'keyframe': 0, ..., 'point': (0.0, 0.0, 1.0), ...}), ('point', {..., 'keyframe': 0, ..., 'point': (0.0, 1.0, 0.0), ...}), ('point', {..., 'keyframe': 1, ..., 'point': (1.0, 0.0, 0.0), ...})] - """ reprs = [] for i, g in enumerate(self.all): @@ -3029,7 +3009,6 @@ cdef class PrimitiveObject(Graphics3d): 'vertices': [{'x': 0.0, 'y': 0.0, 'z': 0.0}, {'x': 1.0, 'y': 0.0, 'z': 0.0}, {'x': 0.0, 'y': 1.0, 'z': 0.0}]})] - """ return self.triangulation().threejs_repr(render_params) @@ -3080,7 +3059,6 @@ class BoundingSphere(SageObject): sage: BoundingSphere((1,2,3), 10) + None + 0 Center (1.0, 2.0, 3.0) radius 10 - """ if other == 0 or other is None: return self @@ -3209,17 +3187,16 @@ class RenderParams(SageObject): [ 0.0 1.0 0.0 500.0] [ 0.0 0.0 1.0 0.0] [ 0.0 0.0 0.0 1.0] - """ self.transform = self.transform_list.pop() - def unique_name(self, desc="name"): + def unique_name(self, desc='name'): """ Return a unique identifier starting with ``desc``. INPUT: - - ``desc`` (string) -- the prefix of the names (default 'name') + - ``desc`` -- string (default: ``'name'``); the prefix of the names EXAMPLES:: @@ -3340,11 +3317,11 @@ def optimal_aspect_ratios(ratios): Average the aspect ratios. compute the elementwise maximum of triples. - TESTS:: + TESTS:: - sage: from sage.plot.plot3d.base import optimal_aspect_ratios - sage: optimal_aspect_ratios([(2,4,6), (5,4,4), (1,2,7)]) - [5, 4, 7] + sage: from sage.plot.plot3d.base import optimal_aspect_ratios + sage: optimal_aspect_ratios([(2,4,6), (5,4,4), (1,2,7)]) + [5, 4, 7] """ n = len(ratios) if n > 0: @@ -3357,11 +3334,11 @@ def optimal_extra_kwds(v): Merge a list v of dictionaries such that later dictionaries have precedence. - TESTS:: + TESTS:: - sage: from sage.plot.plot3d.base import optimal_extra_kwds - sage: optimal_extra_kwds([{1:2, 2:3}, {2:4, 3:5}]) - {1: 2, 2: 4, 3: 5} + sage: from sage.plot.plot3d.base import optimal_extra_kwds + sage: optimal_extra_kwds([{1:2, 2:3}, {2:4, 3:5}]) + {1: 2, 2: 4, 3: 5} """ a = {} for b in v: @@ -3371,12 +3348,12 @@ def optimal_extra_kwds(v): def _flip_orientation(v): """ - Switch from LH to RH coords to be consistent with Java rendition + Switch from LH to RH coords to be consistent with Java rendition. - TESTS:: + TESTS:: - sage: from sage.plot.plot3d.base import _flip_orientation - sage: _flip_orientation((1, 2, 3)) - (1, -2, 3) + sage: from sage.plot.plot3d.base import _flip_orientation + sage: _flip_orientation((1, 2, 3)) + (1, -2, 3) """ return (v[0], -v[1], v[2]) diff --git a/src/sage/plot/plot3d/bugs.txt b/src/sage/plot/plot3d/bugs.txt index 7355e3ad63f..60a084c22c0 100644 --- a/src/sage/plot/plot3d/bugs.txt +++ b/src/sage/plot/plot3d/bugs.txt @@ -65,13 +65,13 @@ Jmol bugs: other things break. Probably need to save the javascript and execute it each time we reload. -* Sphere(0.3,color="red").translate([1,1,-1]) has *holes* in it!! +* Sphere(0.3,color='red').translate([1,1,-1]) has *holes* in it!! * (done) Default zoom is useless -- we will have to rescale the whole scene I think. Basically we have to figure out the true range of the 3d plot in each direction, then rescale everything into a 10x10x10 square. We should draw axis and allow for aspect ratios. - * Invalid color doesn't yield an error message, e.g., Icosahedron(texture="yello") + * Invalid color doesn't yield an error message, e.g., Icosahedron(texture='yello') * color --> rgbcolor * Observation: jmol embedded applets *crash* when more than 10 or so appear in diff --git a/src/sage/plot/plot3d/implicit_plot3d.py b/src/sage/plot/plot3d/implicit_plot3d.py index 1d8cf813e95..6fe1d4de6a0 100644 --- a/src/sage/plot/plot3d/implicit_plot3d.py +++ b/src/sage/plot/plot3d/implicit_plot3d.py @@ -11,26 +11,26 @@ def implicit_plot3d(f, xrange, yrange, zrange, **kwds): INPUT: - - ``f`` -- function + - ``f`` -- function - - ``xrange`` -- a 2-tuple (x_min, x_max) or a 3-tuple (x, x_min, x_max) + - ``xrange`` -- a 2-tuple (x_min, x_max) or a 3-tuple (x, x_min, x_max) - - ``yrange`` -- a 2-tuple (y_min, y_max) or a 3-tuple (y, y_min, y_max) + - ``yrange`` -- a 2-tuple (y_min, y_max) or a 3-tuple (y, y_min, y_max) - - ``zrange`` -- a 2-tuple (z_min, z_max) or a 3-tuple (z, z_min, z_max) + - ``zrange`` -- a 2-tuple (z_min, z_max) or a 3-tuple (z, z_min, z_max) - - ``plot_points`` -- (default: "automatic", which is 40) the number of - function evaluations in each direction. (The number of cubes in the - marching cubes algorithm will be one less than this). Can be a triple of - integers, to specify a different resolution in each of x,y,z. + - ``plot_points`` -- (default: "automatic", which is 40) the number of + function evaluations in each direction. (The number of cubes in the + marching cubes algorithm will be one less than this). Can be a triple of + integers, to specify a different resolution in each of x,y,z. - - ``contour`` -- (default: 0) plot the isosurface ``f(x,y,z) == contour``. - Can be a list, in which case multiple contours are plotted. + - ``contour`` -- (default: 0) plot the isosurface ``f(x,y,z) == contour``. + Can be a list, in which case multiple contours are plotted - - ``region`` -- (default: None) If region is given, it must be a Python - callable. Only segments of the surface where ``region(x,y,z)`` returns a - number `>0` will be included in the plot. (Note that returning a Python - boolean is acceptable, since ``True == 1`` and ``False == 0``). + - ``region`` -- (default: ``None``) if region is given, it must be a Python + callable. Only segments of the surface where ``region(x,y,z)`` returns a + number `>0` will be included in the plot. (Note that returning a Python + boolean is acceptable, since ``True == 1`` and ``False == 0``). EXAMPLES:: diff --git a/src/sage/plot/plot3d/implicit_surface.pyx b/src/sage/plot/plot3d/implicit_surface.pyx index ce0da48a4e0..0a6e03354e6 100644 --- a/src/sage/plot/plot3d/implicit_surface.pyx +++ b/src/sage/plot/plot3d/implicit_surface.pyx @@ -468,6 +468,7 @@ cdef class MarchingCubesTriangles(MarchingCubes): sage: cube_marcher.y_vertices.tolist() [[[<1.0, 0.5, 0.0>, None]], [[None, None]]] sage: cube_marcher.x_vertices.any() # This shouldn't affect the X vertices. + ... """ (self.y_vertices, self.y_vertices_swapped) = \ (self.y_vertices_swapped, self.y_vertices) @@ -574,6 +575,7 @@ cdef class MarchingCubesTriangles(MarchingCubes): sage: cube_marcher.x_vertices.tolist() [[None, None], [None, <1.5, 1.0, 1.0>]] sage: cube_marcher.y_vertices.any() or cube_marcher.z_vertices.any() # This shouldn't affect the Y or Z vertices. + ... """ cdef bint has_prev = (_prev is not None) cdef bint has_next = (_next is not None) @@ -849,18 +851,18 @@ cpdef render_implicit(f, xrange, yrange, zrange, plot_points, cube_marchers): """ INPUT: - - ``f`` -- a (fast!) callable function + - ``f`` -- a (fast!) callable function - - ``xrange`` -- a 2-tuple (x_min, x_max) + - ``xrange`` -- a 2-tuple (x_min, x_max) - - ``yrange`` -- a 2-tuple (y_min, y_may) + - ``yrange`` -- a 2-tuple (y_min, y_may) - - ``zrange`` -- a 2-tuple (z_min, z_maz) + - ``zrange`` -- a 2-tuple (z_min, z_maz) - - ``plot_points`` -- a triple of integers indicating the number of - function evaluations in each direction. + - ``plot_points`` -- a triple of integers indicating the number of + function evaluations in each direction - - ``cube_marchers`` -- a list of cube marchers, one for each contour. + - ``cube_marchers`` -- list of cube marchers, one for each contour OUTPUT: @@ -945,7 +947,7 @@ cdef class ImplicitSurface(IndexFaceSet): cdef readonly tuple plot_points def __init__(self, f, xrange, yrange, zrange, - contour=0, plot_points="automatic", + contour=0, plot_points='automatic', region=None, smooth=True, gradient=None, **kwds): """ @@ -1197,7 +1199,6 @@ cdef class ImplicitSurface(IndexFaceSet): sage: len(G.vertex_list()) > 0, len(G.face_list()) > 0 (True, True) sage: G.show() # This should be fast, since the mesh is already triangulated. - """ if self.fcount != 0 and not force: # The mesh is already triangulated diff --git a/src/sage/plot/plot3d/index_face_set.pyx b/src/sage/plot/plot3d/index_face_set.pyx index 4a98bfba774..04cd6866f8d 100644 --- a/src/sage/plot/plot3d/index_face_set.pyx +++ b/src/sage/plot/plot3d/index_face_set.pyx @@ -205,7 +205,7 @@ def midpoint(pointa, pointb, w): - ``pointa``, ``pointb`` -- two points in 3-dimensional space - - ``w`` -- a real weight between 0 and 1. + - ``w`` -- a real weight between 0 and 1 If the weight is zero, the result is ``pointb``. If the weight is one, the result is ``pointa``. @@ -393,7 +393,7 @@ cdef class IndexFaceSet(PrimitiveObject): cdef int realloc(self, Py_ssize_t vcount, Py_ssize_t fcount, Py_ssize_t icount) except -1: r""" - Allocates memory for vertices, faces, and face indices. Can + Allocate memory for vertices, faces, and face indices. Can only be called from Cython, so the doctests must be indirect. EXAMPLES:: @@ -930,7 +930,7 @@ cdef class IndexFaceSet(PrimitiveObject): INPUT: - - `f` -- a function from `\RR^3` to `\ZZ` + - ``f`` -- a function from `\RR^3` to `\ZZ` EXAMPLES:: @@ -1003,9 +1003,7 @@ cdef class IndexFaceSet(PrimitiveObject): - ``eps`` -- target accuracy in the intersection (default: 1.0e-6) - OUTPUT: - - an ``IndexFaceSet`` + OUTPUT: an ``IndexFaceSet`` This will contain both triangular and quadrilateral faces. @@ -1409,7 +1407,6 @@ cdef class IndexFaceSet(PrimitiveObject): {'x': 0.0, 'y': 1.0, 'z': 1.0}, {'x': 1.0, 'y': 0.0, 'z': 1.0}, {'x': 1.0, 'y': 1.0, 'z': 0.0}]})] - """ surface = {} @@ -1711,9 +1708,7 @@ cdef class IndexFaceSet(PrimitiveObject): the original surface so it shows, typically this value is very small compared to the actual object - OUTPUT: - - Graphics3dGroup of stickers + OUTPUT: Graphics3dGroup of stickers EXAMPLES:: @@ -1757,8 +1752,6 @@ cdef class FaceIter: True """ def __init__(self, face_set): - """ - """ self.set = face_set self.i = 0 diff --git a/src/sage/plot/plot3d/list_plot3d.py b/src/sage/plot/plot3d/list_plot3d.py index ed79ff12c7f..8bfa47ab5c6 100644 --- a/src/sage/plot/plot3d/list_plot3d.py +++ b/src/sage/plot/plot3d/list_plot3d.py @@ -22,7 +22,7 @@ def list_plot3d(v, interpolation_type='default', point_list=None, **kwds): - a list of 3-tuples - a list of lists (all of the same length) -- this is treated the same as - a matrix. + a matrix OPTIONAL KEYWORDS: @@ -35,22 +35,22 @@ def list_plot3d(v, interpolation_type='default', point_list=None, **kwds): Clough-Tocher scheme. The interpolant is guaranteed to be continuously differentiable. The gradients of the interpolant are chosen so that the curvature of the interpolating surface is - approximatively minimized. + approximately minimized. The option 'spline' interpolates using a bivariate B-spline. When v is a matrix the default is to use linear interpolation, when v is a list of points the default is 'clough'. - - ``degree`` -- an integer between 1 and 5, controls the degree of spline + - ``degree`` -- integer between 1 and 5, controls the degree of spline used for spline interpolation. For data that is highly oscillatory use higher values - - ``point_list`` -- If point_list=True is passed, then if the array + - ``point_list`` -- if ``point_list=True`` is passed, then if the array is a list of lists of length three, it will be treated as an array of points rather than a 3xn array. - - ``num_points`` -- Number of points to sample interpolating + - ``num_points`` -- number of points to sample interpolating function in each direction, when ``interpolation_type`` is not ``default``. By default for an `n\times n` array this is `n`. @@ -392,8 +392,8 @@ def list_plot3d_array_of_arrays(v, interpolation_type, **kwds): INPUT: - - ``v`` -- a list of lists, all the same length - - ``interpolation_type`` -- (default: 'linear') + - ``v`` -- list of lists, all the same length + - ``interpolation_type`` -- (default: ``'linear'``) OPTIONAL KEYWORDS: @@ -474,15 +474,15 @@ def list_plot3d_tuples(v, interpolation_type, **kwds): When ``v`` is a matrix the default is to use linear interpolation, when ``v`` is a list of points the default is ``'clough'``. - - ``degree`` -- an integer between 1 and 5, controls the degree of spline + - ``degree`` -- integer between 1 and 5, controls the degree of spline used for spline interpolation. For data that is highly oscillatory use higher values - - ``point_list`` -- If ``point_list=True`` is passed, then if the array + - ``point_list`` -- if ``point_list=True`` is passed, then if the array is a list of lists of length three, it will be treated as an array of points rather than a `3\times n` array. - - ``num_points`` -- Number of points to sample interpolating + - ``num_points`` -- number of points to sample interpolating function in each direction. By default for an `n\times n` array this is `n`. diff --git a/src/sage/plot/plot3d/meson.build b/src/sage/plot/plot3d/meson.build new file mode 100644 index 00000000000..46cc4a25ffc --- /dev/null +++ b/src/sage/plot/plot3d/meson.build @@ -0,0 +1,45 @@ +py.install_sources( + 'all.py', + 'base.pxd', + 'implicit_plot3d.py', + 'index_face_set.pxd', + 'introduction.py', + 'list_plot3d.py', + 'parametric_plot3d.py', + 'parametric_surface.pxd', + 'platonic.py', + 'plot3d.py', + 'plot_field3d.py', + 'revolution_plot3d.py', + 'shapes.pxd', + 'shapes2.py', + 'tachyon.py', + 'texture.py', + 'transform.pxd', + 'tri_plot.py', + subdir: 'sage/plot/plot3d', +) + +extension_data = { + 'base' : files('base.pyx'), + 'implicit_surface' : files('implicit_surface.pyx'), + 'index_face_set' : files('index_face_set.pyx'), + 'shapes' : files('shapes.pyx'), + 'transform' : files('transform.pyx'), + 'parametric_surface' : files('parametric_surface.pyx'), +} + +foreach name, pyx : extension_data + dependencies = [py_dep, cysignals, gmp] + if name == 'parametric_surface' + dependencies += [interpreters_dep] + endif + py.extension_module( + name, + sources: pyx, + subdir: 'sage/plot/plot3d', + install: true, + include_directories: [inc_cpython, inc_ext, inc_numpy], + dependencies: dependencies, + ) +endforeach diff --git a/src/sage/plot/plot3d/parametric_plot3d.py b/src/sage/plot/plot3d/parametric_plot3d.py index 201894eac42..fa8a69a805e 100644 --- a/src/sage/plot/plot3d/parametric_plot3d.py +++ b/src/sage/plot/plot3d/parametric_plot3d.py @@ -11,7 +11,7 @@ @rename_keyword(alpha='opacity') -def parametric_plot3d(f, urange, vrange=None, plot_points="automatic", +def parametric_plot3d(f, urange, vrange=None, plot_points='automatic', boundary_style=None, **kwds): r""" Return a parametric three-dimensional space curve or surface. @@ -54,13 +54,13 @@ def parametric_plot3d(f, urange, vrange=None, plot_points="automatic", how to draw the boundaries of regions by giving options that are passed to the line3d command. - - ``mesh`` -- bool (default: ``False``) whether to display + - ``mesh`` -- boolean (default: ``False``); whether to display mesh grid lines - - ``dots`` -- bool (default: ``False``) whether to display + - ``dots`` -- boolean (default: ``False``); whether to display dots at mesh grid points - .. note:: + .. NOTE:: #. By default for a curve any points where `f_x`, `f_y`, or `f_z` do not evaluate to a real number @@ -72,7 +72,6 @@ def parametric_plot3d(f, urange, vrange=None, plot_points="automatic", #. mesh and dots are not supported when using the Tachyon ray tracer renderer. - EXAMPLES: We demonstrate each of the four ways to call this function. @@ -302,8 +301,8 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: u, v = var('u,v') sage: f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v)) sage: f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u)) - sage: p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture="red") - sage: p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture="blue") + sage: p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture='red') + sage: p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture='blue') sage: p1 + p2 Graphics3d Object @@ -312,8 +311,8 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 u, v = var('u,v') f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v)) f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u)) - p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture="red") - p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture="blue") + p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture='red') + p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture='blue') sphinx_plot(p1 + p2) A cylindrical Star of David:: @@ -363,7 +362,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = cos(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u)) sage: f_y = sin(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u)) sage: f_z = v - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-1,1), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-1,1), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -372,7 +371,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = cos(u)*(4*sqrt(1-v**2)*sin(abs(u))**abs(u)) f_y = sin(u) *(4*sqrt(1-v**2)*sin(abs(u))**abs(u)) f_z = v - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-1,1), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-1,1), frame=False, color='red')) A Trefoil knot (:wikipedia:`Trefoil_knot`):: @@ -380,7 +379,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (4*(1+0.25*sin(3*v))+cos(u))*cos(2*v) sage: f_y = (4*(1+0.25*sin(3*v))+cos(u))*sin(2*v) sage: f_z = sin(u)+2*cos(3*v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color="blue") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='blue') Graphics3d Object .. PLOT:: @@ -389,7 +388,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (4*(1+0.25*sin(3*v))+cos(u))*cos(2*v) f_y = (4*(1+0.25*sin(3*v))+cos(u))*sin(2*v) f_z = sin(u)+2*cos(3*v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color="blue")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='blue')) Green bowtie:: @@ -397,7 +396,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = sin(u) / (sqrt(2) + sin(v)) sage: f_y = sin(u) / (sqrt(2) + cos(v)) sage: f_z = cos(u) / (1 + sqrt(2)) - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='green') Graphics3d Object .. PLOT:: @@ -406,7 +405,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = sin(u) / (sqrt(2) + sin(v)) f_y = sin(u) / (sqrt(2) + cos(v)) f_z = cos(u) / (1 + sqrt(2)) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='green')) Boy's surface (:wikipedia:`Boy%27s_surface` and https://mathcurve.com/surfaces/boy/boy.shtml):: @@ -420,7 +419,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 ....: (v,0,pi), ....: plot_points=[90,90], ....: frame=False, - ....: color="orange") + ....: color='orange') Graphics3d Object .. PLOT:: @@ -431,7 +430,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_y = K * (cos(u)*sin(2*v)-sqrt(2)*sin(u)*sin(v)) f_z = 3 * K * cos(u) P = parametric_plot3d([f_x, f_y, f_z], (u,-2*pi,2*pi), (v,0,pi), - plot_points=[90,90], frame=False, color="orange") # long time -- about 30 seconds + plot_points=[90,90], frame=False, color='orange') # long time -- about 30 seconds sphinx_plot(P) Maeder's Owl also known as Bour's minimal surface (:wikipedia:`Bour%27s_minimal_surface`):: @@ -441,7 +440,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_y = -v*sin(u) - 0.5*v^2*sin(2*u) sage: f_z = 4 * v^1.5 * cos(3*u/2) / 3 sage: parametric_plot3d([f_x, f_y, f_z], (u,-2*pi,2*pi), (v,0,1), - ....: plot_points=[90,90], frame=False, color="purple") + ....: plot_points=[90,90], frame=False, color='purple') Graphics3d Object .. PLOT:: @@ -451,7 +450,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_y = -v*sin(u) - 0.5*v**2*sin(2*u) f_z = 4 * v**1.5 * cos(3*u/2) / 3 P = parametric_plot3d([f_x, f_y, f_z], (u,-2*pi,2*pi), (v,0,1), - plot_points=[90,90], frame=False, color="purple") + plot_points=[90,90], frame=False, color='purple') sphinx_plot(P) Bracelet:: @@ -460,7 +459,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (2 + 0.2*sin(2*pi*u))*sin(pi*v) sage: f_y = 0.2 * cos(2*pi*u) * 3 * cos(2*pi*v) sage: f_z = (2 + 0.2*sin(2*pi*u))*cos(pi*v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,pi/2), (v,0,3*pi/4), frame=False, color="gray") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,pi/2), (v,0,3*pi/4), frame=False, color='gray') Graphics3d Object .. PLOT:: @@ -469,7 +468,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (2 + 0.2*sin(2*pi*u))*sin(pi*v) f_y = 0.2 * cos(2*pi*u) * 3* cos(2*pi*v) f_z = (2 + 0.2*sin(2*pi*u))*cos(pi*v) - P = parametric_plot3d([f_x, f_y, f_z], (u,0,pi/2), (v,0,3*pi/4), frame=False, color="gray") + P = parametric_plot3d([f_x, f_y, f_z], (u,0,pi/2), (v,0,3*pi/4), frame=False, color='gray') sphinx_plot(P) @@ -479,7 +478,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = cos(u) * cos(2*v) sage: f_y = sin(u) * cos(2*v) sage: f_z = sin(v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,pi), frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,pi), frame=False, color='green') Graphics3d Object .. PLOT:: @@ -488,7 +487,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = cos(u) * cos(2*v) f_y = sin(u) * cos(2*v) f_z = sin(v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,pi), frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,pi), frame=False, color='green')) Funny folded surface - with square projection:: @@ -497,7 +496,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = cos(u) * sin(2*v) sage: f_y = sin(u) * cos(2*v) sage: f_z = sin(v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green') Graphics3d Object .. PLOT:: @@ -506,7 +505,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = cos(u) * sin(2*v) f_y = sin(u) * cos(2*v) f_z = sin(v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green')) Surface of revolution of figure 8:: @@ -514,7 +513,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = cos(u) * sin(2*v) sage: f_y = sin(u) * sin(2*v) sage: f_z = sin(v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green') Graphics3d Object .. PLOT:: @@ -523,7 +522,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = cos(u) * sin(2*v) f_y = sin(u) * sin(2*v) f_z = sin(v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green')) Yellow Whitney's umbrella (:wikipedia:`Whitney_umbrella`):: @@ -531,7 +530,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = u*v sage: f_y = u sage: f_z = v^2 - sage: parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-1,1), frame=False, color="yellow") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-1,1), frame=False, color='yellow') Graphics3d Object .. PLOT:: @@ -540,7 +539,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = u*v f_y = u f_z = v**2 - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-1,1), frame=False, color="yellow")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-1,1), frame=False, color='yellow')) Cross cap (:wikipedia:`Cross-cap`):: @@ -548,7 +547,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (1+cos(v)) * cos(u) sage: f_y = (1+cos(v)) * sin(u) sage: f_z = -tanh((2/3)*(u-pi)) * sin(v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -557,7 +556,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (1+cos(v)) * cos(u) f_y = (1+cos(v)) * sin(u) f_z = -tanh((2.0/3.0)*(u-pi)) * sin(v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red')) Twisted torus:: @@ -565,7 +564,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (3+sin(v)+cos(u)) * cos(2*v) sage: f_y = (3+sin(v)+cos(u)) * sin(2*v) sage: f_z = sin(u) + 2*cos(v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -574,7 +573,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (3+sin(v)+cos(u)) * cos(2*v) f_y = (3+sin(v)+cos(u)) * sin(2*v) f_z = sin(u) + 2*cos(v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red')) Four intersecting discs:: @@ -582,7 +581,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = v*cos(u) - 0.5*v^2*cos(2*u) sage: f_y = -v*sin(u) - 0.5*v^2*sin(2*u) sage: f_z = 4 * v^1.5 * cos(3*u/2) / 3 - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,4*pi), (v,0,2*pi), frame=False, color="red", opacity=0.7) + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,4*pi), (v,0,2*pi), frame=False, color='red', opacity=0.7) Graphics3d Object .. PLOT:: @@ -591,7 +590,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = v*cos(u) - 0.5*v**2*cos(2*u) f_y = -v*sin(u) - 0.5*v**2*sin(2*u) f_z = 4 * v**1.5 * cos(3.0*u/2.0) /3 - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,4*pi), (v,0,2*pi), frame=False, color="red", opacity=0.7)) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,4*pi), (v,0,2*pi), frame=False, color='red', opacity=0.7)) Steiner surface/Roman's surface (see :wikipedia:`Roman_surface` and @@ -601,7 +600,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (sin(2*u) * cos(v) * cos(v)) sage: f_y = (sin(u) * sin(2*v)) sage: f_z = (cos(u) * sin(2*v)) - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,-pi/2,pi/2), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,-pi/2,pi/2), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -610,7 +609,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (sin(2*u) * cos(v) * cos(v)) f_y = (sin(u) * sin(2*v)) f_z = (cos(u) * sin(2*v)) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,-pi/2,pi/2), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,-pi/2,pi/2), frame=False, color='red')) Klein bottle? (see :wikipedia:`Klein_bottle`):: @@ -618,7 +617,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (3*(1+sin(v)) + 2*(1-cos(v)/2)*cos(u)) * cos(v) sage: f_y = (4+2*(1-cos(v)/2)*cos(u)) * sin(v) sage: f_z = -2 * (1-cos(v)/2) * sin(u) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green') Graphics3d Object .. PLOT:: @@ -627,7 +626,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (3*(1+sin(v)) + 2*(1-cos(v)/2)*cos(u)) * cos(v) f_y = (4+2*(1-cos(v)/2)*cos(u)) * sin(v) f_z = -2 * (1-cos(v)/2) * sin(u) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green')) A Figure 8 embedding of the Klein bottle (see :wikipedia:`Klein_bottle`):: @@ -636,7 +635,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (2+cos(v/2)*sin(u)-sin(v/2)*sin(2*u)) * cos(v) sage: f_y = (2+cos(v/2)*sin(u)-sin(v/2)*sin(2*u)) * sin(v) sage: f_z = sin(v/2)*sin(u) + cos(v/2)*sin(2*u) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -645,7 +644,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (2+cos(0.5*v)*sin(u)-sin(0.5*v)*sin(2*u)) * cos(v) f_y = (2+cos(0.5*v)*sin(u)-sin(0.5*v)*sin(2*u)) * sin(v) f_z = sin(v*0.5)*sin(u) + cos(v*0.5)*sin(2*u) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red')) Enneper's surface (see :wikipedia:`Enneper_surface`):: @@ -654,7 +653,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = u - u^3/3 + u*v^2 sage: f_y = v - v^3/3 + v*u^2 sage: f_z = u^2 - v^2 - sage: parametric_plot3d([f_x, f_y, f_z], (u,-2,2), (v,-2,2), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-2,2), (v,-2,2), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -663,7 +662,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = u - u**3/3 + u*v**2 f_y = v - v**3/3 + v*u**2 f_z = u**2 - v**2 - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-2,2), (v,-2,2), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-2,2), (v,-2,2), frame=False, color='red')) Henneberg's surface (see http://xahlee.org/surface/gallery_m.html):: @@ -672,7 +671,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = 2*sinh(u)*cos(v) - (2/3)*sinh(3*u)*cos(3*v) sage: f_y = 2*sinh(u)*sin(v) + (2/3)*sinh(3*u)*sin(3*v) sage: f_z = 2 * cosh(2*u) * cos(2*v) - sage: parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-pi/2,pi/2), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-pi/2,pi/2), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -681,7 +680,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = 2.0*sinh(u)*cos(v) - (2.0/3.0)*sinh(3*u)*cos(3*v) f_y = 2.0*sinh(u)*sin(v) + (2.0/3.0)*sinh(3*u)*sin(3*v) f_z = 2.0 * cosh(2*u) * cos(2*v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-pi/2,pi/2), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-pi/2,pi/2), frame=False, color='red')) Dini's spiral:: @@ -689,7 +688,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = cos(u) * sin(v) sage: f_y = sin(u) * sin(v) sage: f_z = (cos(v)+log(tan(v/2))) + 0.2*u - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,12.4), (v,0.1,2), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,12.4), (v,0.1,2), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -698,7 +697,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = cos(u) * sin(v) f_y = sin(u) * sin(v) f_z = (cos(v)+log(tan(v*0.5))) + 0.2*u - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,12.4), (v,0.1,2), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,12.4), (v,0.1,2), frame=False, color='red')) Catalan's surface (see http://xahlee.org/surface/catalan/catalan.html):: @@ -707,7 +706,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = u - sin(u)*cosh(v) sage: f_y = 1 - cos(u)*cosh(v) sage: f_z = 4 * sin(1/2*u) * sinh(v/2) - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,3*pi), (v,-2,2), frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,3*pi), (v,-2,2), frame=False, color='red') Graphics3d Object .. PLOT:: @@ -716,7 +715,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = u - sin(u)*cosh(v) f_y = 1.0 - cos(u)*cosh(v) f_z = 4.0 * sin(0.5*u) * sinh(0.5*v) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,3*pi), (v,-2,2), frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,3*pi), (v,-2,2), frame=False, color='red')) A Conchoid:: @@ -845,7 +844,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (sinh(v)*cos(3*u)) / (1+cosh(u)*cosh(v)) sage: f_y = (sinh(v)*sin(3*u)) / (1+cosh(u)*cosh(v)) sage: f_z = (cosh(v)*sinh(u)) / (1+cosh(u)*cosh(v)) - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red') Graphics3d Object .. PLOT:: @@ -855,7 +854,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (sinh(v)*cos(3*u)) / (1+cosh(u)*cosh(v)) f_y = (sinh(v)*sin(3*u)) / (1+cosh(u)*cosh(v)) f_z = (cosh(v)*sinh(u)) / (1+cosh(u)*cosh(v)) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red')) A Helicoid (lines through a helix, :wikipedia:`Helix`):: @@ -864,7 +863,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = sinh(v) * sin(u) sage: f_y = -sinh(v) * cos(u) sage: f_z = 3 * u - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color="red") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red') Graphics3d Object .. PLOT:: @@ -873,7 +872,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = sinh(v) * sin(u) f_y = -sinh(v) * cos(u) f_z = 3 * u - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color="red")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red')) Kuen's surface (http://virtualmathmuseum.org/Surface/kuen/kuen.html):: @@ -881,7 +880,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (2*(cos(u) + u*sin(u))*sin(v))/(1+ u^2*sin(v)^2) sage: f_y = (2*(sin(u) - u*cos(u))*sin(v))/(1+ u^2*sin(v)^2) sage: f_z = log(tan(1/2 *v)) + (2*cos(v))/(1+ u^2*sin(v)^2) - sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0.01,pi-0.01), plot_points=[50,50], frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0.01,pi-0.01), plot_points=[50,50], frame=False, color='green') Graphics3d Object .. PLOT:: @@ -890,7 +889,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (2.0*(cos(u)+u*sin(u))*sin(v)) / (1.0+u**2*sin(v)**2) f_y = (2.0*(sin(u)-u*cos(u))*sin(v)) / (1.0+u**2*sin(v)**2) f_z = log(tan(0.5 *v)) + (2*cos(v))/(1.0+u**2*sin(v)**2) - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0.01,pi-0.01), plot_points=[50,50], frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0.01,pi-0.01), plot_points=[50,50], frame=False, color='green')) A 5-pointed star:: @@ -899,7 +898,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = cos(u) * cos(v) * G1 * G2 sage: f_y = cos(u) * sin(v) * G1 * G2 sage: f_z = sin(u) * G1 - sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,0,2*pi), plot_points=[50,50], frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,0,2*pi), plot_points=[50,50], frame=False, color='green') Graphics3d Object .. PLOT:: @@ -910,14 +909,14 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = cos(u) * cos(v) * G1 * G2 f_y = cos(u) * sin(v) * G1 * G2 f_z = sin(u) * G1 - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,0,2*pi), plot_points=[50,50], frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,0,2*pi), plot_points=[50,50], frame=False, color='green')) A cool self-intersecting surface (Eppener surface?):: sage: f_x = u - u^3/3 + u*v^2 sage: f_y = v - v^3/3 + v*u^2 sage: f_z = u^2 - v^2 - sage: parametric_plot3d([f_x, f_y, f_z], (u,-25,25), (v,-25,25), plot_points=[50,50], frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-25,25), (v,-25,25), plot_points=[50,50], frame=False, color='green') Graphics3d Object .. PLOT:: @@ -926,7 +925,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = u - u**3/3 + u*v**2 f_y = v - v**3/3 + v*u**2 f_z = u**2 - v**2 - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-25,25), (v,-25,25), plot_points=[50,50], frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-25,25), (v,-25,25), plot_points=[50,50], frame=False, color='green')) The breather surface (:wikipedia:`Breather_surface`):: @@ -936,7 +935,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: f_x = (2*K*cosh(0.4*u)*(-(K*cos(v)*cos(K*v)) - sin(v)*sin(K*v)))/G sage: f_y = (2*K*cosh(0.4*u)*(-(K*sin(v)*cos(K*v)) + cos(v)*sin(K*v)))/G sage: f_z = -u + (2*0.84*cosh(0.4*u)*sinh(0.4*u))/G - sage: parametric_plot3d([f_x, f_y, f_z], (u,-13.2,13.2), (v,-37.4,37.4), plot_points=[90,90], frame=False, color="green") + sage: parametric_plot3d([f_x, f_y, f_z], (u,-13.2,13.2), (v,-37.4,37.4), plot_points=[90,90], frame=False, color='green') Graphics3d Object .. PLOT:: @@ -947,7 +946,7 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 f_x = (2*K*cosh(0.4*u)*(-(K*cos(v)*cos(K*v)) - sin(v)*sin(K*v)))/G f_y = (2*K*cosh(0.4*u)*(-(K*sin(v)*cos(K*v)) + cos(v)*sin(K*v)))/G f_z = -u + (2*0.84*cosh(0.4*u)*sinh(0.4*u))/G - sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-13.2,13.2), (v,-37.4,37.4), plot_points=[90,90], frame=False, color="green")) + sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-13.2,13.2), (v,-37.4,37.4), plot_points=[90,90], frame=False, color='green')) TESTS:: @@ -970,23 +969,22 @@ def g(x,y): return x, y+sin(y), x**2 + y**2 sage: x, y = var('x,y') sage: plot3d(x*y^2 - sin(x), (x,-1,1), (y,-1,1)) Graphics3d Object - """ # TODO: # * Surface -- behavior of functions not defined everywhere -- see note above # * Iterative refinement - # color_function -- (default: "automatic") how to determine the color of curves and surfaces - # color_function_scaling -- (default: ``True``) whether to scale the input to color_function - # exclusions -- (default: "automatic") u points or (u,v) conditions to exclude. + # color_function -- (default: ``'automatic'``) how to determine the color of curves and surfaces + # color_function_scaling -- boolean (default: ``True``); whether to scale the input to color_function + # exclusions -- (default: ``'automatic'``) u points or (u,v) conditions to exclude. # (E.g., exclusions could be a function e = lambda u, v: False if u < v else True - # exclusions_style -- (default: None) what to draw at excluded points - # max_recursion -- (default: "automatic") maximum number of recursive subdivisions, + # exclusions_style -- (default: ``None``) what to draw at excluded points + # max_recursion -- (default: ``'automatic'``) maximum number of recursive subdivisions, # when ... - # mesh -- (default: "automatic") how many mesh divisions in each direction to draw - # mesh_functions -- (default: "automatic") how to determine the placement of mesh divisions - # mesh_shading -- (default: None) how to shade regions between mesh divisions - # plot_range -- (default: "automatic") range of values to include + # mesh -- (default: ``'automatic'``) how many mesh divisions in each direction to draw + # mesh_functions -- (default: ``'automatic'``) how to determine the placement of mesh divisions + # mesh_shading -- (default: ``None``) how to shade regions between mesh divisions + # plot_range -- (default: ``'automatic'``) range of values to include if isinstance(f, Vector): f = tuple(f) @@ -1035,8 +1033,8 @@ def _parametric_plot3d_curve(f, urange, plot_points, **kwds): - ``urange`` -- a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) - - ``plot_points`` -- (default: "automatic", which is 75) initial - number of sample points in each parameter; an integer. + - ``plot_points`` -- integer (default: 75, "automatic"); initial + number of sample points in each parameter EXAMPLES: @@ -1054,7 +1052,6 @@ def _parametric_plot3d_curve(f, urange, plot_points, **kwds): sage: u = var('u') sage: parametric_plot3d((sin(u), cos(u), u/10), (u,0,20)) Graphics3d Object - """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange], plot_points) diff --git a/src/sage/plot/plot3d/parametric_surface.pyx b/src/sage/plot/plot3d/parametric_surface.pyx index 85e01276228..dab78e762a5 100644 --- a/src/sage/plot/plot3d/parametric_surface.pyx +++ b/src/sage/plot/plot3d/parametric_surface.pyx @@ -44,14 +44,14 @@ EXAMPLES:: By default, the surface is colored with one single color. :: sage: P = ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1)), - ....: color="red") + ....: color='red') sage: P.show() .. PLOT:: from sage.plot.plot3d.parametric_surface import ParametricSurface def f(x,y): return x+y, sin(x)*sin(y), x*y - sphinx_plot(ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1)), color="red")) + sphinx_plot(ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1)), color='red')) One can instead provide a coloring function and a colormap:: @@ -145,15 +145,15 @@ cdef class ParametricSurface(IndexFaceSet): INPUT: - - ``f`` -- (default: ``None``) The defining function. Either a tuple of + - ``f`` -- (default: ``None``) the defining function. Either a tuple of three functions, or a single function which returns a tuple, taking two python floats as input. To subclass, pass ``None`` for ``f`` and override ``eval_c`` or ``eval`` instead. - - ``domain`` -- (default: ``None``) A tuple of two lists, defining the + - ``domain`` -- (default: ``None``) a tuple of two lists, defining the grid of `u,v` values. If ``None``, this will be calculated automatically. - - ``color`` -- (default: ``None``) A pair `(h,c)` where `h` is + - ``color`` -- (default: ``None``) a pair `(h,c)` where `h` is a function with values in `[0,1]` and `c` is a colormap. The color of a point `p` is then defined as the composition `c(h(p))` @@ -189,7 +189,7 @@ cdef class ParametricSurface(IndexFaceSet): ....: return (x,y,z) sage: v = srange(float(0),float((3/2)*pi),float(0.1)) sage: S = ParametricSurface(f, (srange(float(0),float(pi),float(0.1)), - ....: srange(float(-1),float(1),float(0.1))), color="blue") + ....: srange(float(-1),float(1),float(0.1))), color='blue') sage: show(S) .. PLOT:: @@ -203,7 +203,7 @@ cdef class ParametricSurface(IndexFaceSet): return (x,y,z) from sage.plot.plot3d.parametric_surface import ParametricSurface v = srange(float(0),float((3/2)*pi),float(0.1)) - sphinx_plot(ParametricSurface(f, (srange(float(0),float(pi),float(0.1)),srange(float(-1),float(1),float(0.1))), color="blue")) + sphinx_plot(ParametricSurface(f, (srange(float(0),float(pi),float(0.1)),srange(float(-1),float(1),float(0.1))), color='blue')) A colored example using the ``color`` keyword:: @@ -383,7 +383,6 @@ cdef class ParametricSurface(IndexFaceSet): 'vertices': [{'x': -2.0, 'y': -2.0, 'z': 0.0}, ... {'x': 2.0, 'y': 2.0, 'z': 0.0}]})] - """ self.triangulate(render_params) return IndexFaceSet.threejs_repr(self, render_params) @@ -658,10 +657,10 @@ cdef class ParametricSurface(IndexFaceSet): We branch outside the loops for efficiency. The options for self.f are: - - ``None`` -- call self.eval_c() or self.eval() - (One of these is presumably overridden.) - - tuple -- split into fx, fy, fz and call each separately - - callable -- call f(u,v) + - ``None`` -- call ``self.eval_c()`` or ``self.eval()`` + (One of these is presumably overridden.) + - ``tuple`` -- split into fx, fy, fz and call each separately + - ``callable`` -- call f(u,v) In addition, branches are taken for efficient calling of fast callables """ @@ -784,7 +783,6 @@ cdef class ParametricSurface(IndexFaceSet): sage: S = parametric_plot3d( (sin, cos, lambda u: u/10), (0, 20)) sage: S.plot() is S True - """ return self @@ -833,7 +831,6 @@ class MoebiusStrip(ParametricSurface): Graphics3d Object sage: O = MoebiusStrip(5,1,plot_points=200,color='red'); O # keywords get passed to plot3d Graphics3d Object - """ ParametricSurface.__init__(self, **kwds) self.r = float(r) @@ -848,9 +845,9 @@ class MoebiusStrip(ParametricSurface): INPUT: - - ``ds`` -- A number, typically coming from a RenderParams object, - which helps determine the increment for the `v` range for the - MoebiusStrip object. + - ``ds`` -- a number, typically coming from a RenderParams object, + which helps determine the increment for the `v` range for the + MoebiusStrip object EXAMPLES:: diff --git a/src/sage/plot/plot3d/platonic.py b/src/sage/plot/plot3d/platonic.py index 491179ede81..3f8587968e2 100644 --- a/src/sage/plot/plot3d/platonic.py +++ b/src/sage/plot/plot3d/platonic.py @@ -86,8 +86,7 @@ def index_face_set(face_list, point_list, enclosed, **kwds): - ``point_list`` -- list of points, given explicitly from the solid invocation - - ``enclosed`` -- boolean (default passed is always ``True`` - for these solids) + - ``enclosed`` -- boolean (default: ``True`` for these solids) TESTS: @@ -127,13 +126,13 @@ def prep(G, center, size, kwds): INPUT: - - ``center`` -- 3-tuple indicating the center (default passed - from :func:`index_face_set` is the origin `(0,0,0)`) + - ``center`` -- 3-tuple indicating the center (default: the origin + `(0,0,0)`, passed from :func:`index_face_set`) - - ``size`` -- number indicating amount to scale by (default - passed from :func:`index_face_set` is 1) + - ``size`` -- number indicating amount to scale by (default: 1, + passed from :func:`index_face_set`) - - ``kwds`` -- a dictionary of keywords, passed from solid + - ``kwds`` -- dictionary of keywords, passed from solid invocation by :func:`index_face_set` TESTS: @@ -164,7 +163,7 @@ def tetrahedron(center=(0, 0, 0), size=1, **kwds): - ``size`` -- (default: 1) - - ``color`` -- a string (``"red"``, ``"green"``, etc) + - ``color`` -- string (``'red'``, ``'green'``, etc) or a tuple (r, g, b) with r, g, b numbers between 0 and 1 - ``opacity`` -- (default: 1) if less than 1 then is @@ -276,21 +275,19 @@ def cube(center=(0, 0, 0), size=1, color=None, frame_thickness=0, - ``center`` -- (default: (0,0,0)) - - ``size`` -- (default: 1) the side lengths of the - cube + - ``size`` -- (default: 1) the side lengths of the cube - - ``color`` -- a string that describes a color; this + - ``color`` -- string that describes a color; this can also be a list of 3-tuples or strings length 6 or 3, in which - case the faces (and oppositive faces) are colored. + case the faces (and oppositive faces) are colored - ``frame_thickness`` -- (default: 0) if positive, then thickness of the frame - - ``frame_color`` -- (default: None) if given, gives + - ``frame_color`` -- (default: ``None``) if given, gives the color of the frame - - ``opacity`` -- (default: 1) if less than 1 then it's - transparent + - ``opacity`` -- (default: 1) if less than 1 then it's transparent EXAMPLES: @@ -305,12 +302,12 @@ def cube(center=(0, 0, 0), size=1, color=None, frame_thickness=0, A red cube:: - sage: cube(color="red") + sage: cube(color='red') Graphics3d Object .. PLOT:: - sphinx_plot(cube(color="red")) + sphinx_plot(cube(color='red')) A transparent grey cube that contains a red cube:: @@ -419,12 +416,11 @@ def octahedron(center=(0, 0, 0), size=1, **kwds): - ``size`` -- (default: 1) - - ``color`` -- a string that describes a color; this + - ``color`` -- string that describes a color; this can also be a list of 3-tuples or strings length 6 or 3, in which - case the faces (and oppositive faces) are colored. + case the faces (and oppositive faces) are colored - - ``opacity`` -- (default: 1) if less than 1 then is - transparent + - ``opacity`` -- (default: 1) if less than 1 then is transparent EXAMPLES:: @@ -438,7 +434,6 @@ def octahedron(center=(0, 0, 0), size=1, **kwds): G = octahedron((1,4,3), color='orange') G += octahedron((0,2,1), size=2, opacity=0.6) sphinx_plot(G) - """ kwds['enclosed'] = True if 'aspect_ratio' not in kwds: @@ -457,9 +452,9 @@ def dodecahedron(center=(0, 0, 0), size=1, **kwds): - ``size`` -- (default: 1) - - ``color`` -- a string that describes a color; this + - ``color`` -- string that describes a color; this can also be a list of 3-tuples or strings length 6 or 3, in which - case the faces (and oppositive faces) are colored. + case the faces (and oppositive faces) are colored - ``opacity`` -- (default: 1) if less than 1 then is transparent @@ -571,9 +566,9 @@ def icosahedron(center=(0, 0, 0), size=1, **kwds): - ``size`` -- (default: 1) - - ``color`` -- a string that describes a color; this + - ``color`` -- string that describes a color; this can also be a list of 3-tuples or strings length 6 or 3, in which - case the faces (and oppositive faces) are colored. + case the faces (and oppositive faces) are colored - ``opacity`` -- (default: 1) if less than 1 then is transparent @@ -598,7 +593,6 @@ def icosahedron(center=(0, 0, 0), size=1, **kwds): p = icosahedron((-1/2,0,1), color='orange') p += icosahedron((2,0,1), size = 0.5, color='red', aspect_ratio=[1,1,1]) sphinx_plot(p) - """ kwds['enclosed'] = True if 'aspect_ratio' not in kwds: diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index c34830d35d6..3b583082a9a 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -169,11 +169,10 @@ class _Coordinates: INPUT: - - ``dep_var`` -- the dependent variable (the function value will be - - - ``indep_vars`` -- a list of independent variables (the parameters will be - substituted for these) + - ``dep_var`` -- the dependent variable (the function value will be + - ``indep_vars`` -- list of independent variables (the parameters will be + substituted for these) """ def __init__(self, dep_var, indep_vars): """ @@ -234,11 +233,11 @@ def to_cartesian(self, func, params=None): INPUT: - - ``func`` -- function in this coordinate space; corresponds - to the independent variable + - ``func`` -- function in this coordinate space; corresponds + to the independent variable - - ``params`` -- the parameters of ``func``; corresponds to - the dependent variables + - ``params`` -- the parameters of ``func``; corresponds to + the dependent variables EXAMPLES:: @@ -316,7 +315,6 @@ def to_cartesian(self, func, params=None): sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r).ev sage: spherical_plot3d(f,(0,2*pi),(0,pi)) Graphics3d Object - """ from sage.structure.element import Expression from sage.rings.real_mpfr import RealNumber @@ -435,13 +433,13 @@ def __init__(self, custom_trans, dep_var, indep_vars): INPUT: - - ``custom_trans`` -- A 3-tuple of transformation - functions. + - ``custom_trans`` -- a 3-tuple of transformation + functions - - ``dep_var`` -- The dependent (function) variable. + - ``dep_var`` -- the dependent (function) variable - - ``indep_vars`` -- a list of the two other independent - variables. + - ``indep_vars`` -- list of the two other independent + variables EXAMPLES:: @@ -753,9 +751,7 @@ def triangle(self, a, b, c, color=None): - ``color`` -- ignored - OUTPUT: - - - the list ``[a,b,c]`` + OUTPUT: the list ``[a,b,c]`` TESTS:: @@ -782,9 +778,7 @@ def smooth_triangle(self, a, b, c, da, db, dc, color=None): - ``color`` -- ignored - OUTPUT: - - - the list ``[a,b,c]`` + OUTPUT: the list ``[a,b,c]`` TESTS:: @@ -806,30 +800,30 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): INPUT: - - ``f`` -- a symbolic expression or function of 2 - variables + - ``f`` -- a symbolic expression or function of 2 + variables - - ``urange`` -- a 2-tuple (u_min, u_max) or a 3-tuple - (u, u_min, u_max) + - ``urange`` -- a 2-tuple (u_min, u_max) or a 3-tuple + (u, u_min, u_max) - - ``vrange`` -- a 2-tuple (v_min, v_max) or a 3-tuple - (v, v_min, v_max) + - ``vrange`` -- a 2-tuple (v_min, v_max) or a 3-tuple + (v, v_min, v_max) - - ``adaptive`` -- (default: ``False``) whether to use - adaptive refinement to draw the plot (slower, but may look better). - This option does NOT work in conjunction with a transformation - (see below). + - ``adaptive`` -- boolean (default: ``False``); whether to use + adaptive refinement to draw the plot (slower, but may look better). + This option does NOT work in conjunction with a transformation + (see below). - - ``mesh`` -- bool (default: ``False``) whether to display - mesh grid lines + - ``mesh`` -- boolean (default: ``False``); whether to display + mesh grid lines - - ``dots`` -- bool (default: ``False``) whether to display - dots at mesh grid points + - ``dots`` -- boolean (default: ``False``); whether to display + dots at mesh grid points - - ``plot_points`` -- (default: "automatic") initial number of sample - points in each direction; an integer or a pair of integers + - ``plot_points`` -- (default: ``'automatic'``) initial number of sample + points in each direction; an integer or a pair of integers - - ``transformation`` -- (default: None) a transformation to + - ``transformation`` -- (default: ``None``) a transformation to apply. May be a 3 or 4-tuple (x_func, y_func, z_func, independent_vars) where the first 3 items indicate a transformation to Cartesian coordinates (from your coordinate @@ -956,7 +950,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): We draw two parametric surfaces and a transparent plane:: - sage: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8) + sage: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color='lightblue', opacity=0.8) sage: P = plot3d(lambda x,y: 4 - x^3 - y^2, (-2,2), (-2,2), color='green') sage: Q = plot3d(lambda x,y: x^3 + y^2 - 4, (-2,2), (-2,2), color='orange') sage: L + P + Q @@ -964,7 +958,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): .. PLOT:: - L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8) + L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color='lightblue', opacity=0.8) P = plot3d(lambda x,y: 4 - x**3 - y**2, (-2,2), (-2,2), color='green') Q = plot3d(lambda x,y: x**3 + y**2 - 4, (-2,2), (-2,2), color='orange') sphinx_plot(L + P + Q) @@ -1125,7 +1119,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): return P -def plot3d_adaptive(f, x_range, y_range, color="automatic", +def plot3d_adaptive(f, x_range, y_range, color='automatic', grad_f=None, max_bend=.5, max_depth=5, initial_depth=4, num_colors=128, **kwds): r""" @@ -1136,21 +1130,20 @@ def plot3d_adaptive(f, x_range, y_range, color="automatic", INPUT: - - ``f`` -- a symbolic function or a Python function of 3 variables - ``x_range`` -- x range of values: 2-tuple (xmin, - xmax) or 3-tuple (x,xmin,xmax) + xmax) or 3-tuple (x,xmin,xmax) - ``y_range`` -- y range of values: 2-tuple (ymin, ymax) or 3-tuple - (y,ymin,ymax) + (y,ymin,ymax) - ``grad_f`` -- gradient of f as a Python function - ``color`` -- "automatic"; a rainbow of num_colors colors - ``num_colors`` -- (default: 128) number of colors to use with default - color + color - ``max_bend`` -- (default: 0.5) @@ -1174,10 +1167,8 @@ def plot3d_adaptive(f, x_range, y_range, color="automatic", from sage.plot.plot3d.plot3d import plot3d_adaptive x, y = var('x,y') sphinx_plot(plot3d_adaptive(sin(x*y), (x,-pi,pi), (y,-pi,pi), initial_depth=5)) - """ - if initial_depth >= max_depth: - max_depth = initial_depth + max_depth = max(max_depth, initial_depth) from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [x_range,y_range], plot_points=2) @@ -1326,7 +1317,6 @@ def spherical_plot3d(f, urange, vrange, **kwds): x, y = var('x,y') sphinx_plot(spherical_plot3d(1 + 2*cos(2*y), (x, 0, 3*pi/2), (y, 0, pi))) - """ return plot3d(f, urange, vrange, transformation=Spherical('radius', ['azimuth', 'inclination']), **kwds) @@ -1408,7 +1398,7 @@ def cylindrical_plot3d(f, urange, vrange, **kwds): def axes(scale=1, radius=None, **kwds): """ - Creates basic axes in three dimensions. Each axis is a three + Create basic axes in three dimensions. Each axis is a three dimensional arrow object. INPUT: diff --git a/src/sage/plot/plot3d/plot_field3d.py b/src/sage/plot/plot3d/plot_field3d.py index a18c49215be..99f9449e2f8 100644 --- a/src/sage/plot/plot3d/plot_field3d.py +++ b/src/sage/plot/plot3d/plot_field3d.py @@ -26,25 +26,25 @@ def plot_vector_field3d(functions, xrange, yrange, zrange, plot_points=5, colors='jet', center_arrows=False, **kwds): r""" - Plot a 3d vector field + Plot a 3d vector field. INPUT: - - ``functions`` -- a list of three functions, representing the x-, + - ``functions`` -- list of three functions, representing the x-, y-, and z-coordinates of a vector - ``xrange``, ``yrange``, and ``zrange`` -- three tuples of the form (var, start, stop), giving the variables and ranges for each axis - - ``plot_points`` -- (default 5) either a number or list of three + - ``plot_points`` -- (default: 5) either a number or list of three numbers, specifying how many points to plot for each axis - - ``colors`` -- (default ``'jet'``) a color, list of colors (which are + - ``colors`` -- (default: ``'jet'``) a color, list of colors (which are interpolated between), or matplotlib colormap name, giving the coloring of the arrows. If a list of colors or a colormap is given, coloring is done as a function of length of the vector - - ``center_arrows`` -- (default ``False``) If ``True``, draw the arrows + - ``center_arrows`` -- (default: ``False``) if ``True``, draw the arrows centered on the points; otherwise, draw the arrows with the tail at the point diff --git a/src/sage/plot/plot3d/point_c.pxi b/src/sage/plot/plot3d/point_c.pxi index ba9561ab18c..f282c3e9f63 100644 --- a/src/sage/plot/plot3d/point_c.pxi +++ b/src/sage/plot/plot3d/point_c.pxi @@ -110,7 +110,7 @@ cdef inline void point_c_middle(point_c* res, point_c P, point_c Q, double a) no cdef inline void point_c_transform(point_c* res, double* M, point_c P) noexcept: """ - M is a flattened 4x4 matrix, row major, representing an Euclidean Transformation. + M is a flattened 4x4 matrix, row major, representing a Euclidean Transformation. Operate on P as a point. """ res.x = M[0]*P.x + M[1]*P.y + M[2]*P.z + M[3] @@ -119,7 +119,7 @@ cdef inline void point_c_transform(point_c* res, double* M, point_c P) noexcept: cdef inline void point_c_stretch(point_c* res, double* M, point_c P) noexcept: """ - M is a flattened 4x4 matrix, row major, representing an Euclidean Transformation. + M is a flattened 4x4 matrix, row major, representing a Euclidean Transformation. Operate on P as a vector (i.e. ignore the translation component) """ res.x = M[0]*P.x + M[1]*P.y + M[2]*P.z diff --git a/src/sage/plot/plot3d/revolution_plot3d.py b/src/sage/plot/plot3d/revolution_plot3d.py index 6349fabbdd5..6c16263d971 100644 --- a/src/sage/plot/plot3d/revolution_plot3d.py +++ b/src/sage/plot/plot3d/revolution_plot3d.py @@ -33,34 +33,46 @@ def revolution_plot3d(curve,trange,phirange=None,parallel_axis='z',axis=(0,0),pr There are three ways to call this function: - - ``revolution_plot3d(f,trange)`` where `f` is a function located in the `x z` plane. + - ``revolution_plot3d(f,trange)`` where `f` is a function located in the + `x z` plane. - - ``revolution_plot3d((f_x,f_z),trange)`` where `(f_x,f_z)` is a parametric curve on the `x z` plane. + - ``revolution_plot3d((f_x,f_z),trange)`` where `(f_x,f_z)` is a parametric + curve on the `x z` plane. - - ``revolution_plot3d((f_x,f_y,f_z),trange)`` where `(f_x,f_y,f_z)` can be any parametric curve. + - ``revolution_plot3d((f_x,f_y,f_z),trange)`` where `(f_x,f_y,f_z)` can be + any parametric curve. INPUT: - - ``curve`` -- A curve to be revolved, specified as a function, a 2-tuple or a 3-tuple. + - ``curve`` -- a curve to be revolved, specified as a function, a 2-tuple + or a 3-tuple - - ``trange`` -- A 3-tuple `(t,t_{\min},t_{\max})` where t is the independent variable of the curve. + - ``trange`` -- a 3-tuple `(t,t_{\min},t_{\max})` where t is the + independent variable of the curve - - ``phirange`` -- A 2-tuple of the form `(\phi_{\min},\phi_{\max})`, (default `(0,\pi)`) that specifies the angle in which the curve is to be revolved. + - ``phirange`` -- a 2-tuple of the form `(\phi_{\min},\phi_{\max})` + (default: `(0,\pi)`) that specifies the angle in which the curve is to be + revolved - - ``parallel_axis`` -- A string (one of ``'x'``, ``'y'``, ``'z'``) that specifies the coordinate axis parallel to the revolution axis. + - ``parallel_axis`` -- string (one of ``'x'``, ``'y'``, ``'z'``) that + specifies the coordinate axis parallel to the revolution axis - - ``axis`` -- A 2-tuple that specifies the position of the revolution axis. If ``parallel_axis`` is: + - ``axis`` -- a 2-tuple that specifies the position of the revolution axis. + If ``parallel_axis`` is: - - ``'z'`` -- then ``axis`` is the point in which the revolution axis intersects the `x` `y` plane. + - ``'z'`` -- then ``axis`` is the point in which the revolution axis + intersects the `x` `y` plane - - ``'x'`` -- then ``axis`` is the point in which the revolution axis intersects the `y` `z` plane. + - ``'x'`` -- then ``axis`` is the point in which the revolution axis + intersects the `y` `z` plane - - ``'y'`` -- then ``axis`` is the point in which the revolution axis intersects the `x` `z` plane. + - ``'y'`` -- then ``axis`` is the point in which the revolution axis + intersects the `x` `z` plane - - ``print_vector`` -- If ``True``, the parametrization of the surface of revolution will be printed. - - - ``show_curve`` -- If ``True``, the curve will be displayed. + - ``print_vector`` -- if ``True``, the parametrization of the surface of + revolution will be printed + - ``show_curve`` -- if ``True``, the curve will be displayed EXAMPLES: diff --git a/src/sage/plot/plot3d/shapes.pyx b/src/sage/plot/plot3d/shapes.pyx index 393fa10d7bc..48369a64a07 100644 --- a/src/sage/plot/plot3d/shapes.pyx +++ b/src/sage/plot/plot3d/shapes.pyx @@ -117,22 +117,22 @@ class Box(IndexFaceSet): A red rectangular box:: - sage: show(Box([2,3,4], color="red")) + sage: show(Box([2,3,4], color='red')) .. PLOT:: from sage.plot.plot3d.shapes import Box - sphinx_plot(Box([2,3,4], color="red")) + sphinx_plot(Box([2,3,4], color='red')) A stack of boxes:: - sage: show(sum(Box([2,3,1], color="red").translate((0,0,6*i)) + sage: show(sum(Box([2,3,1], color='red').translate((0,0,6*i)) ....: for i in [0..3])) .. PLOT:: from sage.plot.plot3d.shapes import Box - P = sum([Box([2,3,1], color="red").translate((0,0,6*i)) for i in range(0,4)]) + P = sum([Box([2,3,1], color='red').translate((0,0,6*i)) for i in range(0,4)]) sphinx_plot(P) A sinusoidal stack of multicolored boxes:: @@ -147,7 +147,6 @@ class Box(IndexFaceSet): from sage.plot.plot3d.shapes import Box B = sum([Box([2,4,1/4], color=(i/4.0,i/5.0,1)).translate((sin(i),0,5-i)) for i in range(0,21)]) sphinx_plot(B) - """ def __init__(self, *size, **kwds): """ @@ -196,13 +195,11 @@ def ColorCube(size, colors, opacity=1, **kwds): INPUT: - ``size`` -- 3-tuple of sizes (same as for box and frame) - - ``colors`` -- a list of either 3 or 6 colors + - ``colors`` -- list of either 3 or 6 colors - ``opacity`` -- (default: 1) opacity of cube sides - ``**kwds`` -- passed to the face constructor - OUTPUT: - - a 3d graphics object + OUTPUT: a 3d graphics object EXAMPLES: @@ -233,7 +230,6 @@ def ColorCube(size, colors, opacity=1, **kwds): from sage.plot.plot3d.shapes import ColorCube c = ColorCube([0.5,0.5,0.5], ['red', 'blue', 'green']) sphinx_plot(c) - """ if not isinstance(size, (tuple, list)): size = (size, size, size) @@ -262,7 +258,7 @@ cdef class Cone(ParametricSurface): - ``height`` -- positive real number - - ``closed`` -- whether or not to include the base (default ``True``) + - ``closed`` -- whether or not to include the base (default: ``True``) - ``**kwds`` -- passed to the ParametricSurface constructor @@ -314,7 +310,6 @@ cdef class Cone(ParametricSurface): T = sum(Cone(exp(-n/5.0), 4/3*exp(-n/5.0), color=(0, .5, 0)).translate(0, 0, -3*exp(-n/5.0)) for n in range(8)) T += Cone(1/8, 1, color='brown').translate(0, 0, -3) sphinx_plot(T) - """ def __init__(self, radius, height, closed=True, **kwds): """ @@ -382,7 +377,7 @@ cdef class Cylinder(ParametricSurface): - ``height`` -- positive real number - - ``closed`` -- whether or not to include the ends (default ``True``) + - ``closed`` -- whether or not to include the ends (default: ``True``) - ``**kwds`` -- passed to the :class:`ParametricSurface` constructor @@ -427,7 +422,6 @@ cdef class Cylinder(ParametricSurface): G += G.translate(2.3, 0, -.5) G += G.translate(3.5, 2, -1) sphinx_plot(G) - """ def __init__(self, radius, height, closed=True, **kwds): """ @@ -684,10 +678,10 @@ def arrow3d(start, end, width=1, radius=None, head_radius=None, head_len=None, * - ``start`` -- (x,y,z) point; the starting point of the arrow - ``end`` -- (x,y,z) point; the end point - - ``width`` -- (default: 1); how wide the arrow is + - ``width`` -- (default: 1) how wide the arrow is - ``radius`` -- (default: ``width/50.0``) the radius of the arrow - - ``head_radius`` -- (default: ``3*radius``); radius of arrow head - - ``head_len`` -- (default: ``3*head_radius``); len of arrow head + - ``head_radius`` -- (default: ``3*radius``) radius of arrow head + - ``head_len`` -- (default: ``3*head_radius``) len of arrow head EXAMPLES: @@ -839,7 +833,6 @@ cdef class Sphere(ParametricSurface): from sage.plot.plot3d.shapes import Sphere S = Sphere(1).scale(1,2,1/2) sphinx_plot(S) - """ def __init__(self, radius, **kwds): """ @@ -987,9 +980,7 @@ cdef class Torus(ParametricSurface): - ``R`` -- (default: ``1``) outer radius - ``r`` -- (default: ``.3``) inner radius - OUTPUT: - - a 3d torus + OUTPUT: a 3d torus EXAMPLES:: @@ -1036,7 +1027,6 @@ cdef class Torus(ParametricSurface): D = Torus(1, .4, color=(.5, .3, .2)) + Torus(1, .3, color='yellow').translate(0, 0, .15) G = sum(D.translate(RDF.random_element(-.2, .2), RDF.random_element(-.2, .2), .8*t) for t in range(10)) sphinx_plot(G) - """ def __init__(self, R=1, r=.3, **kwds): """ @@ -1101,7 +1091,6 @@ class Text(PrimitiveObject): from sage.plot.plot3d.shapes import Text pts = [(RealField(10)**3).random_element() for k in range(20)] sphinx_plot(sum(Text(str(P)).translate(P) for P in pts)) - """ def __init__(self, string, **kwds): """ @@ -1173,14 +1162,14 @@ class Text(PrimitiveObject): [[['select atomno = 1', 'color atom [102,102,255]', 'label "Hi"']], [['select atomno = 2', 'color atom [102,102,255]', 'label "Bye"']]] """ - cen = (0,0,0) + cen = (0, 0, 0) if render_params.transform is not None: cen = render_params.transform.transform_point(cen) render_params.atom_list.append(cen) atom_no = len(render_params.atom_list) return ['select atomno = %s' % atom_no, self.get_texture().jmol_str("atom"), - 'label "%s"' % self.string] #.replace('\n', '|')] + 'label "%s"' % self.string] # .replace('\n', '|')] def threejs_repr(self, render_params): r""" @@ -1223,7 +1212,6 @@ class Text(PrimitiveObject): 'x': 0.0, 'y': 0.0, 'z': 0.0})] - """ center = (float(0), float(0), float(0)) if render_params.transform is not None: @@ -1251,7 +1239,7 @@ def _validate_threejs_text_style(style): INPUT: - - ``style`` -- a dict optionally containing keys: 'color', 'fontSize', + - ``style`` -- dictionary optionally containing keys: 'color', 'fontSize', 'fontFamily', 'fontStyle', 'fontWeight', and 'opacity' OUTPUT: @@ -1325,7 +1313,6 @@ def _validate_threejs_text_style(style): sage: validate(dict(opacity=0.5)) {...'opacity': 0.5} - """ default_color = '#000000' # black color = style.get('color', default_color) diff --git a/src/sage/plot/plot3d/shapes2.py b/src/sage/plot/plot3d/shapes2.py index d188abad674..05d6bb6e583 100644 --- a/src/sage/plot/plot3d/shapes2.py +++ b/src/sage/plot/plot3d/shapes2.py @@ -52,15 +52,15 @@ def line3d(points, thickness=1, radius=None, arrow_head=False, **kwds): INPUT: - - ``points`` -- a list of at least 2 points + - ``points`` -- list of at least 2 points - ``thickness`` -- (default: 1) - - ``radius`` -- (default: None) + - ``radius`` -- (default: ``None``) - ``arrow_head`` -- (default: ``False``) - - ``color`` -- a string (``"red"``, ``"green"`` etc) + - ``color`` -- string (``'red'``, ``'green'`` etc) or a tuple (r, g, b) with r, g, b numbers between 0 and 1 - ``opacity`` -- (default: 1) if less than 1 then is @@ -195,7 +195,7 @@ def tetra(col): @rename_keyword(alpha='opacity') -@options(opacity=1, color="blue", aspect_ratio=[1, 1, 1], thickness=2) +@options(opacity=1, color='blue', aspect_ratio=[1, 1, 1], thickness=2) def bezier3d(path, **options): """ Draw a 3-dimensional bezier path. @@ -205,18 +205,18 @@ def bezier3d(path, **options): INPUT: - - ``path`` -- a list of curves, which each is a list of points. See further - detail below. + - ``path`` -- list of curves, which each is a list of points. See further + detail below - - ``thickness`` -- (default: 2) + - ``thickness`` -- (default: 2) - - ``color`` -- a string (``"red"``, ``"green"`` etc) - or a tuple (r, g, b) with r, g, b numbers between 0 and 1 + - ``color`` -- string (``'red'``, ``'green'`` etc) + or a tuple (r, g, b) with r, g, b numbers between 0 and 1 - - ``opacity`` -- (default: 1) if less than 1 then is - transparent + - ``opacity`` -- (default: 1) if less than 1 then is + transparent - - ``aspect_ratio`` -- (default: [1,1,1]) + - ``aspect_ratio`` -- (default: [1,1,1]) The path is a list of curves, and each curve is a list of points. Each point is a tuple (x,y,z). @@ -416,10 +416,10 @@ def frame3d(lower_left, upper_right, **kwds): INPUT: - ``lower_left`` -- the lower left corner of the frame, as a - list, tuple, or vector. + list, tuple, or vector - ``upper_right`` -- the upper right corner of the frame, as a - list, tuple, or vector. + list, tuple, or vector EXAMPLES: @@ -437,8 +437,10 @@ def frame3d(lower_left, upper_right, **kwds): """ x0, y0, z0 = lower_left x1, y1, z1 = upper_right - L1 = line3d([(x0, y0, z0), (x0, y1, z0), (x1, y1, z0), (x1, y0, z0), (x0, y0, z0), # top square - (x0, y0, z1), (x0, y1, z1), (x1, y1, z1), (x1, y0, z1), (x0, y0, z1)], # bottom square + L1 = line3d([(x0, y0, z0), (x0, y1, z0), (x1, y1, z0), + (x1, y0, z0), (x0, y0, z0), # top square + (x0, y0, z1), (x0, y1, z1), (x1, y1, z1), + (x1, y0, z1), (x0, y0, z1)], # bottom square **kwds) # 3 additional lines joining top to bottom v2 = line3d([(x0, y1, z0), (x0, y1, z1)], **kwds) @@ -462,10 +464,10 @@ def frame_labels(lower_left, upper_right, INPUT: - ``lower_left`` -- the lower left corner of the frame, as a - list, tuple, or vector. + list, tuple, or vector - ``upper_right`` -- the upper right corner of the frame, as a - list, tuple, or vector. + list, tuple, or vector - ``label_lower_left`` -- the label for the lower left corner of the frame, as a list, tuple, or vector. This label must actually @@ -476,7 +478,7 @@ def frame_labels(lower_left, upper_right, have all coordinates greater than the coordinates of the other label. - ``eps`` -- (default: 1) a parameter for how far away from the frame - to put the labels. + to put the labels EXAMPLES: @@ -553,22 +555,22 @@ def ruler(start, end, ticks=4, sub_ticks=4, absolute=False, snap=False, **kwds): INPUT: - ``start`` -- the beginning of the ruler, as a list, - tuple, or vector. + tuple, or vector - ``end`` -- the end of the ruler, as a list, tuple, - or vector. + or vector - ``ticks`` -- (default: 4) the number of major ticks - shown on the ruler. + shown on the ruler - ``sub_ticks`` -- (default: 4) the number of shown - subdivisions between each major tick. + subdivisions between each major tick - - ``absolute`` -- (default: ``False``) if ``True``, makes a huge ruler - in the direction of an axis. + - ``absolute`` -- boolean (default: ``False``); if ``True``, makes a huge ruler + in the direction of an axis - - ``snap`` -- (default: ``False``) if ``True``, snaps to an implied - grid. + - ``snap`` -- boolean (default: ``False``); if ``True``, snaps to an implied + grid EXAMPLES: @@ -685,16 +687,16 @@ def ruler_frame(lower_left, upper_right, ticks=4, sub_ticks=4, **kwds): INPUT: - ``lower_left`` -- the lower left corner of the frame, as a - list, tuple, or vector. + list, tuple, or vector - ``upper_right`` -- the upper right corner of the frame, as a - list, tuple, or vector. + list, tuple, or vector - ``ticks`` -- (default: 4) the number of major ticks - shown on each ruler. + shown on each ruler - ``sub_ticks`` -- (default: 4) the number of shown - subdivisions between each major tick. + subdivisions between each major tick EXAMPLES: @@ -736,7 +738,7 @@ def sphere(center=(0, 0, 0), size=1, **kwds): - `(x,y,z)` -- center (default: (0,0,0)) - - ``size`` -- the radius (default: 1) + - ``size`` -- the radius (default: 1) EXAMPLES: A simple sphere:: @@ -795,11 +797,11 @@ def text3d(txt, x_y_z, **kwds): INPUT: - - ``txt`` -- some text + - ``txt`` -- some text - - ``(x,y,z)`` -- position tuple `(x,y,z)` + - ``x_y_z`` -- position tuple `(x,y,z)` - - ``**kwds`` -- standard 3d graphics options + - ``**kwds`` -- standard 3d graphics options EXAMPLES: @@ -859,7 +861,6 @@ def text3d(txt, x_y_z, **kwds): sage: def echo(o): ....: return text3d("Echo!", (0, 0, o), opacity=o) sage: show(sum([echo(o) for o in (0.1, 0.2, .., 1)]), viewer='threejs') - """ (x, y, z) = x_y_z if 'color' not in kwds and 'rgbcolor' not in kwds: @@ -877,9 +878,9 @@ class Point(PrimitiveObject): INPUT: - - ``center`` -- point (3-tuple) + - ``center`` -- point (3-tuple) - - ``size`` -- (default: 1) + - ``size`` -- (default: 1) EXAMPLES: @@ -909,7 +910,7 @@ def __init__(self, center, size=1, **kwds): def bounding_box(self): """ - Returns the lower and upper corners of a 3-D bounding box for ``self``. + Return the lower and upper corners of a 3-D bounding box for ``self``. This is used for rendering and ``self`` should fit entirely within this box. In this case, we simply return the center of the point. @@ -999,7 +1000,6 @@ def threejs_repr(self, render_params): sage: P.threejs_repr(P.default_render_params()) [('point', {'color': '#6666ff', 'opacity': 1.0, 'point': (0.0, 0.0, 0.0), 'size': 5.0})] - """ transform = render_params.transform center = tuple(float(coord) for coord in self.loc) @@ -1038,9 +1038,9 @@ class Line(PrimitiveObject): - ``thickness`` -- (default: 5) diameter of the line - ``corner_cutoff`` -- (default: 0.5) threshold for - smoothing (see :meth:`corners`). + smoothing (see :meth:`corners`) - - ``arrow_head`` -- (default: ``False``) if ``True`` make + - ``arrow_head`` -- boolean (default: ``False``); if ``True`` make this curve into an arrow The parameter ``corner_cutoff`` is a bound for the cosine of the @@ -1214,13 +1214,13 @@ def corners(self, corner_cutoff=None, max_len=None): INPUT: - - ``corner_cutoff`` -- (default: ``None``) If the + - ``corner_cutoff`` -- (default: ``None``) if the cosine of the angle between adjacent line segments is smaller than this bound, then there will be a sharp corner in the path. Otherwise, the path is smoothed. If ``None``, then the default value 0.5 is used. - - ``max_len`` -- (default: ``None``) Maximum number + - ``max_len`` -- (default: ``None``) maximum number of points allowed in a single path. If this is set, this creates corners at smooth points in order to break the path into smaller pieces. @@ -1373,7 +1373,6 @@ def threejs_repr(self, render_params): sage: A_repr = A.threejs_repr(A.default_render_params()) sage: A_repr == L_repr True - """ reprs = [] points = [tuple(float(coord) for coord in p) for p in self.points] @@ -1414,16 +1413,16 @@ def point3d(v, size=5, **kwds): INPUT: - - ``v`` -- a point or list of points + - ``v`` -- a point or list of points - - ``size`` -- (default: 5) size of the point (or - points) + - ``size`` -- (default: 5) size of the point (or + points) - - ``color`` -- a string (``"red"``, ``"green"`` etc) - or a tuple (r, g, b) with r, g, b numbers between 0 and 1 + - ``color`` -- string (``'red'``, ``'green'`` etc) + or a tuple (r, g, b) with r, g, b numbers between 0 and 1 - - ``opacity`` -- (default: 1) if less than 1 then is - transparent + - ``opacity`` -- (default: 1) if less than 1 then is + transparent EXAMPLES:: diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py index c4f136ec157..83315e33368 100644 --- a/src/sage/plot/plot3d/tachyon.py +++ b/src/sage/plot/plot3d/tachyon.py @@ -179,26 +179,26 @@ class Tachyon(WithEqualityById, SageObject): INPUT: - - ``xres`` -- (default 350) - - ``yres`` -- (default 350) - - ``zoom`` -- (default 1.0) - - ``antialiasing`` -- (default ``False``) - - ``aspectratio`` -- (default 1.0) - - ``raydepth`` -- (default 8) - - ``camera_position`` -- (default (-3, 0, 0)) - - ``updir`` -- (default (0, 0, 1)) - - ``look_at`` -- (default (0,0,0)) - - ``viewdir`` -- (default ``None``), otherwise list of three numbers - - ``projection`` -- ``'PERSPECTIVE'`` (default), ``'perspective_dof'`` - or ``'fisheye'``. - - ``frustum`` -- (default ``''``), otherwise list of four numbers. Only + - ``xres`` -- (default: 350) + - ``yres`` -- (default: 350) + - ``zoom`` -- (default: 1.0) + - ``antialiasing`` -- (default: ``False``) + - ``aspectratio`` -- (default: 1.0) + - ``raydepth`` -- (default: 8) + - ``camera_position`` -- (default: (-3, 0, 0)) + - ``updir`` -- (default: (0, 0, 1)) + - ``look_at`` -- (default: (0,0,0)) + - ``viewdir`` -- (default: ``None``) otherwise list of three numbers + - ``projection`` -- ``'PERSPECTIVE'`` (default) ``'perspective_dof'`` + or ``'fisheye'`` + - ``frustum`` -- (default: ``''``) otherwise list of four numbers. Only used with ``projection='fisheye'``. - - ``focallength`` -- (default ''), otherwise a number. Only used + - ``focallength`` -- (default: ``''``) otherwise a number. Only used with ``projection='perspective_dof'``. - - ``aperture`` -- (default ''), otherwise a number. Only used + - ``aperture`` -- (default: ``''``) otherwise a number. Only used with ``projection='perspective_dof'``. - OUTPUT: A Tachyon 3d scene. + OUTPUT: a Tachyon 3d scene Note that the coordinates are by default such that `z` is up, positive `y` is to the {left} and `x` is toward @@ -462,36 +462,36 @@ def save_image(self, filename=None, *args, **kwds): def save(self, filename='sage.png', verbose=None, extra_opts=''): r""" - Save rendering of the tachyon scene + Save rendering of the tachyon scene. INPUT: - - ``filename`` -- (default: 'sage.png') output - filename; the extension of the filename determines the type. - Supported types include: + - ``filename`` -- (default: ``'sage.png'``) output + filename; the extension of the filename determines the type. + Supported types include: - - ``tga`` -- 24-bit (uncompressed) + - ``tga`` -- 24-bit (uncompressed) - - ``bmp`` -- 24-bit Windows BMP (uncompressed) + - ``bmp`` -- 24-bit Windows BMP (uncompressed) - - ``ppm`` -- 24-bit PPM (uncompressed) + - ``ppm`` -- 24-bit PPM (uncompressed) - - ``rgb`` -- 24-bit SGI RGB (uncompressed) + - ``rgb`` -- 24-bit SGI RGB (uncompressed) - - ``png`` -- 24-bit PNG (compressed, lossless) + - ``png`` -- 24-bit PNG (compressed, lossless) - - ``verbose`` -- integer (default: ``None``); if no verbosity setting - is supplied, the verbosity level set by - ``sage.misc.verbose.set_verbose`` is used. + - ``verbose`` -- integer (default: ``None``); if no verbosity setting + is supplied, the verbosity level set by + ``sage.misc.verbose.set_verbose`` is used. - - ``0`` -- silent + - ``0`` -- silent - - ``1`` -- some output + - ``1`` -- some output - - ``2`` -- very verbose output + - ``2`` -- very verbose output - - ``extra_opts`` -- passed directly to tachyon command - line. Use tachyon_rt.usage() to see some of the possibilities. + - ``extra_opts`` -- passed directly to tachyon command + line. Use ``tachyon_rt.usage()`` to see some of the possibilities. EXAMPLES:: @@ -508,7 +508,7 @@ def save(self, filename='sage.png', verbose=None, extra_opts=''): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -711,7 +711,7 @@ def texfunc(self, type=0, center=(0, 0, 0), rotate=(0, 0, 0), r""" INPUT: - - ``type`` -- (default: 0) + - ``type`` -- (default: 0) 0. No special texture, plain shading 1. 3D checkerboard function, like a rubik's cube @@ -725,10 +725,9 @@ def texfunc(self, type=0, center=(0, 0, 0), rotate=(0, 0, 0), 8. Spherical Image Map, requires ppm filename (with path) 9. Planar Image Map, requires ppm filename (with path) - - ``center`` -- (default: (0,0,0)) - - ``rotate`` -- (default: (0,0,0)) - - ``scale`` -- (default: (1,1,1)) - + - ``center`` -- (default: (0,0,0)) + - ``rotate`` -- (default: (0,0,0)) + - ``scale`` -- (default: (1,1,1)) EXAMPLES: We draw an infinite checkerboard:: @@ -745,32 +744,32 @@ def texfunc(self, type=0, center=(0, 0, 0), rotate=(0, 0, 0), def texture(self, name, ambient=0.2, diffuse=0.8, specular=0.0, opacity=1.0, color=(1.0, 0.0, 0.5), texfunc=0, phong=0, phongsize=.5, - phongtype="PLASTIC", imagefile=''): + phongtype='PLASTIC', imagefile=''): r""" INPUT: - - ``name`` -- string; the name of the texture (to be - used later) + - ``name`` -- string; the name of the texture (to be + used later) - - ``ambient`` -- (default: 0.2) + - ``ambient`` -- (default: 0.2) - - ``diffuse`` -- (default: 0.8) + - ``diffuse`` -- (default: 0.8) - - ``specular`` -- (default: 0.0) + - ``specular`` -- (default: 0.0) - - ``opacity`` -- (default: 1.0) + - ``opacity`` -- (default: 1.0) - - ``color`` -- (default: (1.0,0.0,0.5)) + - ``color`` -- (default: (1.0,0.0,0.5)) - - ``texfunc`` -- (default: 0); a texture function; this - is either the output of self.texfunc, or a number between 0 and 9, - inclusive. See the docs for self.texfunc. + - ``texfunc`` -- (default: 0) a texture function; this + is either the output of self.texfunc, or a number between 0 and 9, + inclusive. See the docs for self.texfunc. - - ``phong`` -- (default: 0) + - ``phong`` -- (default: 0) - - ``phongsize`` -- (default: 0.5) + - ``phongsize`` -- (default: 0.5) - - ``phongtype`` -- (default: "PLASTIC") + - ``phongtype`` -- (default: ``'PLASTIC'``) EXAMPLES: @@ -925,7 +924,6 @@ def triangle(self, vertex_1, vertex_2, vertex_3, texture): sage: t.triangle([1,2,3],[4,5,6],[7,8,10],'s') sage: t._objects[1].get_vertices() ([1, 2, 3], [4, 5, 6], [7, 8, 10]) - """ self._objects.append(TachyonTriangle(vertex_1, vertex_2, vertex_3, texture)) @@ -968,29 +966,29 @@ def plot(self, f, xmin_xmax, ymin_ymax, texture, grad_f=None, r""" INPUT: - - ``f`` -- Function of two variables, which returns a - float (or coercible to a float) (xmin,xmax) + - ``f`` -- function of two variables, which returns a + float (or coercible to a float) (xmin,xmax) - - ``(ymin,ymax)`` -- defines the rectangle to plot over - texture: Name of texture to be used Optional arguments: + - ``(ymin,ymax)`` -- defines the rectangle to plot over + texture: Name of texture to be used Optional arguments: - - ``grad_f`` -- gradient function. If specified, - smooth triangles will be used. + - ``grad_f`` -- gradient function. If specified, + smooth triangles will be used - - ``max_bend`` -- Cosine of the threshold angle - between triangles used to determine whether or not to recurse after - the minimum depth + - ``max_bend`` -- cosine of the threshold angle + between triangles used to determine whether or not to recurse after + the minimum depth - - ``max_depth`` -- maximum recursion depth. Maximum - triangles plotted = `2^{2*max_depth}` + - ``max_depth`` -- maximum recursion depth. Maximum + triangles plotted = `2^{2*max_depth}` - - ``initial_depth`` -- minimum recursion depth. No - error-tolerance checking is performed below this depth. Minimum - triangles plotted: `2^{2*min_depth}` + - ``initial_depth`` -- minimum recursion depth. No + error-tolerance checking is performed below this depth. Minimum + triangles plotted: `2^{2*min_depth}` - - ``num_colors`` -- Number of rainbow bands to color - the plot with. Texture supplied will be cloned (with different - colors) using the texture_recolor method of the Tachyon object. + - ``num_colors`` -- number of rainbow bands to color + the plot with. Texture supplied will be cloned (with different + colors) using the texture_recolor method of the Tachyon object. Plots a function by constructing a mesh with nonstandard sampling @@ -1117,7 +1115,6 @@ def str(self): light center 1.0 1.0 1.0 rad 1.0 color 1.0 1.0 1.0 - """ return fr""" light center {tostr(self._center)} @@ -1193,7 +1190,7 @@ class Texture: def __init__(self, name, ambient=0.2, diffuse=0.8, specular=0.0, opacity=1.0, color=(1.0, 0.0, 0.5), texfunc=0, - phong=0, phongsize=0, phongtype="PLASTIC", imagefile=''): + phong=0, phongsize=0, phongtype='PLASTIC', imagefile=''): r""" Store texture information. diff --git a/src/sage/plot/plot3d/texture.py b/src/sage/plot/plot3d/texture.py index c34d0bdd207..561b8efbc3a 100644 --- a/src/sage/plot/plot3d/texture.py +++ b/src/sage/plot/plot3d/texture.py @@ -91,9 +91,7 @@ def parse_color(info, base=None): - ``info`` -- color, valid color str or number - ``base`` -- tuple of length 3 (default: ``None``) - OUTPUT: - - A tuple or color. + OUTPUT: a tuple or color EXAMPLES: @@ -183,22 +181,20 @@ def __classcall__(cls, id=None, **kwds): INPUT: - - ``id`` -- a texture (default: None), a dict, a color, a - str, a tuple, None or any other type acting as an ID. If ``id`` is - None and keyword ``texture`` is empty, then it returns a unique texture object. + - ``id`` -- a texture (default: ``None``), a dictionary, a color, a + string, a tuple, ``None`` or any other type acting as an ID. If ``id`` is + ``None`` and keyword ``texture`` is empty, then it returns a unique texture object. - ``texture`` -- a texture - - ``color`` -- tuple or str, (default: (.4, .4, 1)) + - ``color`` -- tuple or string (default: (.4, .4, 1)) - ``opacity`` -- number between 0 and 1 (default: 1) - ``ambient`` -- number (default: 0.5) - ``diffuse`` -- number (default: 1) - ``specular`` -- number (default: 0) - ``shininess`` -- number (default: 1) - - ``name`` -- str (default: None) + - ``name`` -- string (default: ``None``) - ``**kwds`` -- other valid keywords - OUTPUT: - - A texture object. + OUTPUT: a texture object EXAMPLES: diff --git a/src/sage/plot/plot3d/tri_plot.py b/src/sage/plot/plot3d/tri_plot.py index 5eb15299fe5..4453d8c574c 100644 --- a/src/sage/plot/plot3d/tri_plot.py +++ b/src/sage/plot/plot3d/tri_plot.py @@ -51,7 +51,7 @@ def __init__(self,a,b,c,color=0): def str(self): """ - Returns a string representation of an instance of the Triangle + Return a string representation of an instance of the Triangle class of the form a b c color @@ -85,7 +85,7 @@ def set_color(self, color): def get_vertices(self): """ - Returns a tuple of vertex coordinates of the triangle. + Return a tuple of vertex coordinates of the triangle. TESTS:: @@ -123,7 +123,7 @@ def __init__(self,a,b,c,da,db,dc,color=0): def str(self): """ - Returns a string representation of the SmoothTriangle of the form + Return a string representation of the SmoothTriangle of the form. a b c color da db dc @@ -141,7 +141,7 @@ def str(self): def get_normals(self): """ - Returns the normals to vertices a, b, and c. + Return the normals to vertices a, b, and c. TESTS:: @@ -221,7 +221,7 @@ def get_colors(self, list): class TrianglePlot: """ - Recursively plots a function of two variables by building squares of 4 triangles, checking at + Recursively plot a function of two variables by building squares of 4 triangles, checking at every stage whether or not each square should be split into four more squares. This way, more planar areas get fewer triangles, and areas with higher curvature get more triangles. """ @@ -452,7 +452,7 @@ def plot_block(self, min_x, mid_x, max_x, min_y, mid_y, max_y, sw_z, nw_z, se_z, def interface(self, n, p, p_c, q, q_c): """ - Takes a pair of lists of points, and compares the (n)th coordinate, and + Take a pair of lists of points, and compares the (n)th coordinate, and "zips" the lists together into one. The "centers", supplied in p_c and q_c are matched up such that the lists describe triangles whose sides are "perfectly" aligned. This algorithm assumes that p and q start and diff --git a/src/sage/plot/plot_field.py b/src/sage/plot/plot_field.py index b1a9505eb81..4a884cf4662 100644 --- a/src/sage/plot/plot_field.py +++ b/src/sage/plot/plot_field.py @@ -62,7 +62,6 @@ def __init__(self, xpos_array, ypos_array, xvec_array, yvec_array, options): sage: x,y = var('x,y') sage: P = plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3)) sage: Q = loads(dumps(P)) - """ self.xpos_array = xpos_array self.ypos_array = ypos_array @@ -72,7 +71,7 @@ def __init__(self, xpos_array, ypos_array, xvec_array, yvec_array, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: @@ -88,7 +87,7 @@ def get_minmax_data(self): def _allowed_options(self): """ - Returns a dictionary with allowed options for PlotField. + Return a dictionary with allowed options for PlotField. EXAMPLES:: @@ -137,7 +136,6 @@ def _repr_(self): zorder The layer level in which to draw 20 - """ return "PlotField defined by a {} x {} vector grid".format( self._options['plot_points'], self._options['plot_points']) diff --git a/src/sage/plot/point.py b/src/sage/plot/point.py index 2f393fe211c..7c2d6bb1ae3 100644 --- a/src/sage/plot/point.py +++ b/src/sage/plot/point.py @@ -45,7 +45,7 @@ class Point(GraphicPrimitive_xydata): - ``ydata`` -- list of y values for points in Point object - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -69,7 +69,7 @@ class Point(GraphicPrimitive_xydata): """ def __init__(self, xdata, ydata, options): """ - Initializes base class Point. + Initialize base class Point. EXAMPLES:: @@ -141,9 +141,8 @@ def plot3d(self, z=0, **kwds): INPUT: - - - ``z`` -- optional 3D height above `xy`-plane. May be a list - if self is a list of points. + - ``z`` -- (optional) 3D height above `xy`-plane; may be a list + if ``self`` is a list of points EXAMPLES: @@ -266,7 +265,7 @@ def _repr_(self): def __getitem__(self, i): """ - Returns tuple of coordinates of point. + Return tuple of coordinates of point. EXAMPLES:: @@ -322,8 +321,8 @@ def point(points, **kwds): INPUT: - - ``points`` -- either a single point (as a tuple), a list of - points, a single complex number, or a list of complex numbers. + - ``points`` -- either a single point (as a tuple), a list of + points, a single complex number, or a list of complex numbers For information regarding additional arguments, see either point2d? or point3d?. @@ -405,8 +404,8 @@ def point2d(points, **options): INPUT: - - ``points`` -- either a single point (as a tuple), a list of - points, a single complex number, or a list of complex numbers + - ``points`` -- either a single point (as a tuple), a list of + points, a single complex number, or a list of complex numbers - ``alpha`` -- how transparent the point is @@ -581,7 +580,7 @@ def point2d(points, **options): Verify that :issue:`36153` does not arise:: - sage: P = point((0.5, 0.5), legend_label="test") + sage: P = point((0.5, 0.5), legend_label='test') """ from sage.plot.plot import xydata_from_point_list from sage.plot.all import Graphics diff --git a/src/sage/plot/polygon.py b/src/sage/plot/polygon.py index 2914240e761..8f2fa424725 100644 --- a/src/sage/plot/polygon.py +++ b/src/sage/plot/polygon.py @@ -35,7 +35,7 @@ class Polygon(GraphicPrimitive_xydata): - ``ydata`` -- list of `y`-coordinates of points defining Polygon - - ``options`` -- dict of valid plot options to pass to constructor + - ``options`` -- dictionary of valid plot options to pass to constructor EXAMPLES: @@ -64,12 +64,12 @@ class Polygon(GraphicPrimitive_xydata): :: - sage: polygon2d([(1, 1), (0, 1), (1, 0)], fill=False, linestyle="dashed") + sage: polygon2d([(1, 1), (0, 1), (1, 0)], fill=False, linestyle='dashed') Graphics object consisting of 1 graphics primitive """ def __init__(self, xdata, ydata, options): """ - Initializes base class Polygon. + Initialize base class Polygon. EXAMPLES:: @@ -97,7 +97,7 @@ def _repr_(self): def __getitem__(self, i): """ - Return `i`-th vertex of Polygon primitive + Return `i`-th vertex of Polygon primitive. It is starting count from 0th vertex. @@ -112,7 +112,7 @@ def __getitem__(self, i): def __setitem__(self, i, point): """ - Change `i`-th vertex of Polygon primitive + Change `i`-th vertex of Polygon primitive. It is starting count from 0th vertex. @@ -191,8 +191,8 @@ def plot3d(self, z=0, **kwds): INPUT: - - ``z`` -- optional 3D height above `xy`-plane, or a list of - heights corresponding to the list of 2D polygon points. + - ``z`` -- (optional) 3D height above `xy`-plane, or a list of + heights corresponding to the list of 2D polygon points EXAMPLES: @@ -366,13 +366,13 @@ def polygon2d(points, **options): and the interior as follows:: sage: L = [[0,0]]+[[i/100, 1.1+cos(i/20)] for i in range(100)]+[[1,0]] # needs sage.symbolic - sage: polygon2d(L, color="limegreen", edgecolor="black", axes=False) # needs sage.symbolic + sage: polygon2d(L, color='limegreen', edgecolor='black', axes=False) # needs sage.symbolic Graphics object consisting of 1 graphics primitive .. PLOT:: L = [[0,0]]+[[i*0.01, 1.1+cos(i*0.05)] for i in range(100)]+[[1,0]] - P = polygon2d(L, color="limegreen", edgecolor="black", axes=False) + P = polygon2d(L, color='limegreen', edgecolor='black', axes=False) sphinx_plot(P) Some modern art -- a random polygon, with legend:: @@ -528,7 +528,7 @@ def polygon2d(points, **options): Verify that :issue:`36153` does not arise:: - sage: P = polygon2d([[1,2], [5,6], [5,0]], legend_label="test") + sage: P = polygon2d([[1,2], [5,6], [5,0]], legend_label='test') AUTHORS: diff --git a/src/sage/plot/primitive.py b/src/sage/plot/primitive.py index ee9966846b1..ef69f7f4344 100644 --- a/src/sage/plot/primitive.py +++ b/src/sage/plot/primitive.py @@ -61,9 +61,7 @@ def _allowed_options(self): """ Return the allowed options for a graphics primitive. - OUTPUT: - - - a reference to a dictionary. + OUTPUT: a reference to a dictionary EXAMPLES:: @@ -219,7 +217,7 @@ def _repr_(self): class GraphicPrimitive_xydata(GraphicPrimitive): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: diff --git a/src/sage/plot/scatter_plot.py b/src/sage/plot/scatter_plot.py index 4ad418f040b..3b07349cb9c 100644 --- a/src/sage/plot/scatter_plot.py +++ b/src/sage/plot/scatter_plot.py @@ -56,16 +56,16 @@ def __init__(self, xdata, ydata, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: sage: s = scatter_plot([[0,1],[2,4],[3.2,6]]) sage: d = s.get_minmax_data() sage: d['xmin'] - 0.0 + ...0.0... sage: d['ymin'] - 1.0 + ...1.0... """ return {'xmin': self.xdata.min(), 'xmax': self.xdata.max(), @@ -142,26 +142,26 @@ def _render_on_subplot(self, subplot): @options(alpha=1, markersize=50, marker='o', zorder=5, facecolor='#fec7b8', edgecolor='black', clip=True, aspect_ratio='automatic') def scatter_plot(datalist, **options): """ - Returns a Graphics object of a scatter plot containing all points in + Return a Graphics object of a scatter plot containing all points in the datalist. Type ``scatter_plot.options`` to see all available plotting options. INPUT: - - ``datalist`` -- a list of tuples ``(x,y)`` + - ``datalist`` -- list of tuples ``(x,y)`` - - ``alpha`` -- default: 1 + - ``alpha`` -- (default: 1) - - ``markersize`` -- default: 50 + - ``markersize`` -- (default: 50) - - ``marker`` -- The style of the markers (default ``"o"``). See the - documentation of :func:`plot` for the full list of markers. + - ``marker`` -- the style of the markers (default: ``'o'``); see the + documentation of :func:`plot` for the full list of markers - - ``facecolor`` -- default: ``'#fec7b8'`` + - ``facecolor`` -- (default: ``'#fec7b8'``) - - ``edgecolor`` -- default: ``'black'`` + - ``edgecolor`` -- (default: ``'black'``) - - ``zorder`` -- default: 5 + - ``zorder`` -- (default: 5) EXAMPLES:: diff --git a/src/sage/plot/step.py b/src/sage/plot/step.py index 4023686f9bd..85d4bd83c01 100644 --- a/src/sage/plot/step.py +++ b/src/sage/plot/step.py @@ -31,11 +31,11 @@ def plot_step_function(v, vertical_lines=True, **kwds): - ``v`` -- list of pairs (a,b) - - ``vertical_lines`` -- bool (default: ``True``) if ``True``, draw + - ``vertical_lines`` -- boolean (default: ``True``); if ``True``, draw vertical risers at each step of this step function. Technically these vertical lines are not part of the graph of this function, but they look very nice in the plot, so we - include them by default + include them by default. EXAMPLES: diff --git a/src/sage/plot/streamline_plot.py b/src/sage/plot/streamline_plot.py index 663d3aee70b..2801446433a 100644 --- a/src/sage/plot/streamline_plot.py +++ b/src/sage/plot/streamline_plot.py @@ -56,7 +56,6 @@ def __init__(self, xpos_array, ypos_array, xvec_array, yvec_array, options): sage: x, y = var('x y') sage: P = streamline_plot((sin(x), cos(y)), (x,-3,3), (y,-3,3)) sage: Q = loads(dumps(P)) - """ self.xpos_array = xpos_array self.ypos_array = ypos_array @@ -66,11 +65,14 @@ def __init__(self, xpos_array, ypos_array, xvec_array, yvec_array, options): def get_minmax_data(self): """ - Returns a dictionary with the bounding box data. + Return a dictionary with the bounding box data. EXAMPLES:: sage: x, y = var('x y') + sage: import numpy # to ensure numpy 2.0 compatibility + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") sage: d = streamline_plot((.01*x, x+y), (x,10,20), (y,10,20))[0].get_minmax_data() sage: d['xmin'] 10.0 @@ -82,7 +84,7 @@ def get_minmax_data(self): def _allowed_options(self): """ - Returns a dictionary with allowed options for StreamlinePlot. + Return a dictionary with allowed options for ``StreamlinePlot``. EXAMPLES:: @@ -124,7 +126,6 @@ def _repr_(self): zorder The layer level in which to draw 20 - """ return "StreamlinePlot defined by a {} x {} vector grid".format( self._options['plot_points'], self._options['plot_points']) @@ -270,7 +271,6 @@ def streamline_plot(f_g, xrange, yrange, **options): Streamlines currently pass close to ``start_points`` but do not necessarily pass directly through them. That is part of the behavior of matplotlib, not an error on your part. - """ # Parse the function input if isinstance(f_g, (list, tuple)): @@ -296,9 +296,8 @@ def streamline_plot(f_g, xrange, yrange, **options): else: options['density'] = float(options['density']) - xpos_array, ypos_array, xvec_array, yvec_array = [], [], [], [] - for x in xsrange(*ranges[0], include_endpoint=True): - xpos_array.append(x) + ypos_array, xvec_array, yvec_array = [], [], [] + xpos_array = list(xsrange(*ranges[0], include_endpoint=True)) for y in xsrange(*ranges[1], include_endpoint=True): ypos_array.append(y) xvec_row, yvec_row = [], [] diff --git a/src/sage/plot/text.py b/src/sage/plot/text.py index c641528be87..32b0cc712c4 100644 --- a/src/sage/plot/text.py +++ b/src/sage/plot/text.py @@ -36,7 +36,6 @@ class Text(GraphicPrimitive): .. PLOT:: sphinx_plot(text("I like Fibonacci",(3,5))) - """ def __init__(self, string, point, options): """ @@ -100,7 +99,6 @@ def _allowed_options(self): 'The layer level in which to draw' sage: T[0]._allowed_options()['rotation'] 'How to rotate the text: angle in degrees, vertical, horizontal' - """ return {'fontsize': 'How big the text is. Either the size in points or a relative size, e.g. \'smaller\', \'x-large\', etc', 'fontstyle': 'A string either \'normal\', \'italic\' or \'oblique\'', @@ -133,7 +131,6 @@ def _plot3d_options(self, options=None): sage: s=t.plot3d() sage: s.jmol_repr(s.testing_render_params())[0][1] 'color atom [0,0,255]' - """ if options is None: options = dict(self.options()) @@ -162,7 +159,6 @@ def plot3d(self, **kwds): 'label "ABC"' sage: s._trans (1.0, 1.0, 0) - """ from sage.plot.plot3d.shapes2 import text3d options = self._plot3d_options() @@ -173,11 +169,10 @@ def _render_on_subplot(self, subplot): """ TESTS:: - sage: t1 = text("Hello",(1,1), vertical_alignment="top", fontsize=30, rgbcolor='black') - sage: t2 = text("World", (1,1), horizontal_alignment="left", fontsize=20, zorder=-1) + sage: t1 = text("Hello", (1,1), vertical_alignment='top', fontsize=30, rgbcolor='black') + sage: t2 = text("World", (1,1), horizontal_alignment='left', fontsize=20, zorder=-1) sage: t1 + t2 # render the sum Graphics object consisting of 2 graphics primitives - """ options = self.options() opts = {} @@ -227,39 +222,42 @@ def text(string, xy, **options): 2D OPTIONS: - - ``fontsize`` -- How big the text is. Either an integer that + - ``fontsize`` -- how big the text is. Either an integer that specifies the size in points or a string which specifies a size (one of - 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large') + ``'xx-small'``, ``'x-small'``, ``'small'``, ``'medium'``, ``'large'``, + ``'x-large'``, ``'xx-large'``). - - ``fontstyle`` -- A string either 'normal', 'italic' or 'oblique' + - ``fontstyle`` -- string either ``'normal'``, ``'italic'`` or ``'oblique'`` - - ``fontweight`` -- A numeric value in the range 0-1000 or a string (one of - 'ultralight', 'light', 'normal', 'regular', 'book',' 'medium', 'roman', - 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black') + - ``fontweight`` -- a numeric value in the range 0-1000 or a string (one of + ``'ultralight'``, ``'light'``, ``'normal'``, ``'regular'``, ``'book'``, + ``'medium'``, ``'roman'``, ``'semibold'``, ``'demibold'``, ``'demi'``, + ``'bold'``, ``'heavy'``, ``'extra bold'``, ``'black'``) - - ``rgbcolor`` -- The color as an RGB tuple + - ``rgbcolor`` -- the color as an RGB tuple - - ``hue`` -- The color given as a hue + - ``hue`` -- the color given as a hue - - ``alpha`` -- A float (0.0 transparent through 1.0 opaque) + - ``alpha`` -- a float (0.0 transparent through 1.0 opaque) - - ``background_color`` -- The background color + - ``background_color`` -- the background color - - ``rotation`` -- How to rotate the text: angle in degrees, vertical, horizontal + - ``rotation`` -- how to rotate the text: angle in degrees, vertical, horizontal - - ``vertical_alignment`` -- How to align vertically: top, center, bottom + - ``vertical_alignment`` -- how to align vertically: top, center, bottom - - ``horizontal_alignment`` -- How to align horizontally: left, center, right + - ``horizontal_alignment`` -- how to align horizontally: left, center, right - - ``zorder`` -- The layer level in which to draw + - ``zorder`` -- the layer level in which to draw - - ``clip`` -- (default: ``False``) Whether to clip or not + - ``clip`` -- boolean (default: ``False``); whether to clip or not - - ``axis_coords`` -- (default: ``False``) If True, use axis coordinates, so that - (0,0) is the lower left and (1,1) upper right, regardless of the x and y - range of plotted values. + - ``axis_coords`` -- boolean (default: ``False``); if ``True``, use axis + coordinates, so that (0,0) is the lower left and (1,1) upper right, + regardless of the x and y range of plotted values - - ``bounding_box`` -- A dictionary specifying a bounding box. Currently the text location. + - ``bounding_box`` -- dictionary specifying a bounding box; currently the + text location EXAMPLES:: @@ -305,30 +303,30 @@ def text(string, xy, **options): :: - sage: text("Sage is really neat!!",(0,0), rotation="vertical") + sage: text("Sage is really neat!!", (0,0), rotation='vertical') Graphics object consisting of 1 graphics primitive .. PLOT:: - sphinx_plot(text("Sage is really neat!!",(0,0), rotation="vertical")) + sphinx_plot(text("Sage is really neat!!", (0,0), rotation='vertical')) You can also align text differently:: - sage: t1 = text("Hello", (1,1), vertical_alignment="top") - sage: t2 = text("World", (1,0.5), horizontal_alignment="left") + sage: t1 = text("Hello", (1,1), vertical_alignment='top') + sage: t2 = text("World", (1,0.5), horizontal_alignment='left') sage: t1 + t2 # render the sum Graphics object consisting of 2 graphics primitives .. PLOT:: - t1 = text("Hello",(1,1), vertical_alignment="top") - t2 = text("World", (1,0.5), horizontal_alignment="left") + t1 = text("Hello", (1,1), vertical_alignment='top') + t2 = text("World", (1,0.5), horizontal_alignment='left') sphinx_plot(t1 + t2) You can save text as part of PDF output:: sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".pdf") as f: + sage: with tempfile.NamedTemporaryFile(suffix='.pdf') as f: ....: text("sage", (0,0), rgbcolor=(0,0,0)).save(f.name) Some examples of bounding box:: diff --git a/src/sage/probability/meson.build b/src/sage/probability/meson.build new file mode 100644 index 00000000000..83b6a7e091e --- /dev/null +++ b/src/sage/probability/meson.build @@ -0,0 +1,17 @@ +py.install_sources('all.py', 'random_variable.py', subdir: 'sage/probability') + +extension_data = { + 'probability_distribution' : files('probability_distribution.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/probability', + install: true, + include_directories: [], + dependencies: [py_dep, cysignals, gmp, gsl], + ) +endforeach + diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index e2c71af9c25..fab94479291 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -101,7 +101,7 @@ cdef class ProbabilityDistribution: the probability distribution - ``bins`` -- (optional) number of bins to divide the samples - into. + into OUTPUT: @@ -140,6 +140,9 @@ cdef class ProbabilityDistribution: 1.8, 2.0] """ + import numpy as np + if int(np.version.short_version[0]) > 1: + np.set_printoptions(legacy="1.25") import pylab ell = [float(self.get_random_element()) for _ in range(num_samples)] S = pylab.hist(ell, bins, density=True) @@ -152,13 +155,13 @@ cdef class ProbabilityDistribution: INPUT: - - ``name`` -- file to save the histogram plot (as a PNG). + - ``name`` -- file to save the histogram plot (as a PNG) - ``num_samples`` -- (optional) number of times to sample from the probability distribution - ``bins`` -- (optional) number of bins to divide the samples - into. + into EXAMPLES: @@ -566,7 +569,6 @@ cdef class RealDistribution(ProbabilityDistribution): sage: Xs = [RealDistribution('gaussian', 1).get_random_element() for _ in range(1000)] sage: len(set(Xs)) > 2^^32 True - """ cdef gsl_rng_type *T cdef gsl_rng *r @@ -682,7 +684,6 @@ cdef class RealDistribution(ProbabilityDistribution): sage: T = RealDistribution('gaussian', 1, seed=0) sage: T.get_random_element() # rel tol 4e-16 0.13391860811867587 - """ cdef double result if self.distribution_type == uniform: @@ -1035,19 +1036,17 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): INPUT: - - ``P`` -- list of probabilities. The list will automatically be - normalised if ``sum(P)`` is not equal to 1. + - ``P`` -- list of probabilities; the list will automatically be + normalised if ``sum(P)`` is not equal to 1 - - ``rng`` -- (optional) random number generator to use. May be - one of ``'default'``, ``'luxury'``, or ``'taus'``. + - ``rng`` -- (optional) random number generator to use; may be + one of ``'default'``, ``'luxury'``, or ``'taus'`` - ``seed`` -- (optional) seed to use with the random number - generator. - - OUTPUT: + generator - - a probability distribution where the probability of selecting - ``x`` is ``P[x]``. + OUTPUT: a probability distribution where the probability of selecting + ``x`` is ``P[x]``. EXAMPLES: @@ -1090,12 +1089,12 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sage: len(set(Xs)) > 2^^32 True - The distribution probabilities must be non-negative:: + The distribution probabilities must be nonnegative:: sage: GeneralDiscreteDistribution([0.1, -0.1]) Traceback (most recent call last): ... - ValueError: The distribution probabilities must be non-negative + ValueError: The distribution probabilities must be nonnegative """ cdef gsl_rng_type * T cdef gsl_rng * r @@ -1160,7 +1159,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): for i in range(n): if P[i] < 0: raise ValueError("The distribution probabilities must " - "be non-negative") + "be nonnegative") P_vec[i] = P[i] self.dist = gsl_ran_discrete_preproc(n, P_vec) diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index 1a779aba083..cb5c0426c5a 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -93,8 +93,8 @@ def __init__(self, X, f, codomain=None, check=False): INPUT: - - X -- a probability space - - f -- a dictionary such that X[x] = value for x in X + - ``X`` -- a probability space + - ``f`` -- dictionary such that X[x] = value for x in X is the discrete function on X """ if not isinstance(X, DiscreteProbabilitySpace): @@ -134,7 +134,7 @@ def function(self): def expectation(self): r""" The expectation of the discrete random variable, namely - `\sum_{x \in S} p(x) X[x]`, where `X` = self and + `\sum_{x \in S} p(x) X[x]`, where `X` = ``self`` and `S` is the probability space of `X`. """ E = 0 @@ -197,8 +197,8 @@ def translation_variance(self, map): def covariance(self, other): r""" - The covariance of the discrete random variable X = self with Y = - other. + The covariance of the discrete random variable X = ``self`` with Y = + ``other``. Let `S` be the probability space of `X` = self, with probability function `p`, and `E(X)` be the @@ -220,8 +220,8 @@ def covariance(self, other): def translation_covariance(self, other, map): r""" - The covariance of the probability space X = self with image of Y = - other under the given map of the probability space. + The covariance of the probability space X = ``self`` with image of Y = + ``other`` under the given map of the probability space. Let `S` be the probability space of `X` = self, with probability function `p`, and `E(X)` be the @@ -259,23 +259,23 @@ def standard_deviation(self): def translation_standard_deviation(self, map): r""" The standard deviation of the translated discrete random variable - `X \circ e`, where `X` = self and `e` = + `X \circ e`, where `X` = ``self`` and `e` = map. - Let `S` be the probability space of `X` = self, + Let `S` be the probability space of `X` = ``self``, with probability function `p`, and `E(X)` be the expectation of `X`. Then the standard deviation of `X` is defined to be .. MATH:: - \sigma(X) = \sqrt{ \sum_{x \in S} p(x) (X(x) - E(x))^2} + \sigma(X) = \sqrt{ \sum_{x \in S} p(x) (X(x) - E(x))^2} """ return sqrt(self.translation_variance(map)) def correlation(self, other): """ - The correlation of the probability space X = self with Y = other. + The correlation of the probability space X = ``self`` with Y = ``other``. """ cov = self.covariance(other) sigX = self.standard_deviation() @@ -286,8 +286,8 @@ def correlation(self, other): def translation_correlation(self, other, map): """ - The correlation of the probability space X = self with image of Y = - other under map. + The correlation of the probability space X = ``self`` with image of Y = + ``other`` under map. """ cov = self.translation_covariance(other, map) sigX = self.standard_deviation() diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 37b0beabed5..1a75f415b64 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -80,9 +80,7 @@ class BinaryQF(SageObject): - ``a``, ``b``, ``c`` -- three integers - OUTPUT: - - The binary quadratic form `a x^2 + b xy + c y^2`. + OUTPUT: the binary quadratic form `a x^2 + b xy + c y^2` EXAMPLES:: @@ -300,7 +298,7 @@ def __call__(self, *args): INPUT: - - args -- x and y values, as a pair x, y or a list, tuple, or + - ``args`` -- x and y values, as a pair x, y or a list, tuple, or vector EXAMPLES:: @@ -611,9 +609,7 @@ def determinant(self): whom an integral quadratic form has coefficients `(a, 2b, c)` with `a`, `b`, `c` integers. - OUTPUT: - - The determinant of the matrix:: + OUTPUT: the determinant of the matrix:: [ a b/2] [b/2 c] @@ -773,9 +769,9 @@ def _reduce_indef(self, transformation=False): INPUT: - - ``transformation`` -- bool (default: ``False``); if ``True``, - return both the reduced form and a matrix transforming - ``self`` into the reduced form. + - ``transformation`` -- boolean (default: ``False``); if ``True``, + return both the reduced form and a matrix transforming ``self`` into + the reduced form TESTS:: @@ -835,7 +831,7 @@ def _reduce_indef(self, transformation=False): return Q @cached_method - def reduced_form(self, transformation=False, algorithm="default"): + def reduced_form(self, transformation=False, algorithm='default'): """ Return a reduced form equivalent to ``self``. @@ -843,9 +839,9 @@ def reduced_form(self, transformation=False, algorithm="default"): - ``self`` -- binary quadratic form of non-square discriminant - - ``transformation`` -- boolean (default: ``False``): if ``True``, return + - ``transformation`` -- boolean (default: ``False``); if ``True``, return both the reduced form and a matrix whose :meth:`matrix_action_right` - transforms ``self`` into the reduced form. + transforms ``self`` into the reduced form - ``algorithm`` -- string; the algorithm to use. Valid options are: @@ -1283,7 +1279,7 @@ def is_singular(self): def is_nonsingular(self): """ - Return whether this form is nonsingular, i.e., has non-zero discriminant. + Return whether this form is nonsingular, i.e., has nonzero discriminant. EXAMPLES:: @@ -1302,7 +1298,7 @@ def is_equivalent(self, other, proper=True): INPUT: - - ``proper`` -- bool (default: ``True``); if ``True`` use proper + - ``proper`` -- boolean (default: ``True``); if ``True`` use proper equivalence - ``other`` -- a binary quadratic form @@ -1608,17 +1604,17 @@ def small_prime_value(self, Bmax=1000): raise ValueError("Unable to find a prime value of %s" % self) B += 10 - def solve_integer(self, n, *, algorithm="general", _flag=2): + def solve_integer(self, n, *, algorithm='general', _flag=2): r""" Solve `Q(x, y) = n` in integers `x` and `y` where `Q` is this quadratic form. INPUT: - - ``n`` -- a positive integer or a + - ``n`` -- positive integer or a `:sage:`~sage.structure.factorization.Factorization` object - - ``algorithm`` -- ``"general"`` (default) or ``"cornacchia"`` + - ``algorithm`` -- ``'general'`` (default) or ``'cornacchia'`` - ``_flag`` -- ``1``, ``2`` (default) or ``3``; passed onto the pari function``qfbsolve``. For internal use only. @@ -1689,7 +1685,7 @@ def solve_integer(self, n, *, algorithm="general", _flag=2): sage: xy is None or Q(*xy) == n # needs sage.libs.pari True - Also when using the ``"cornacchia"`` algorithm:: + Also when using the ``'cornacchia'`` algorithm:: sage: # needs sage.libs.pari sage: n = random_prime(10^9) @@ -1833,12 +1829,12 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): INPUT: - - ``D`` -- (integer) a discriminant + - ``D`` -- integer; a discriminant - - ``primitive_only`` -- (boolean; default: ``True``): if ``True``, only - return primitive forms. + - ``primitive_only`` -- boolean (default: ``True``); if ``True``, only + return primitive forms - - ``proper`` -- (boolean; default: ``True``) + - ``proper`` -- boolean (default: ``True``) OUTPUT: diff --git a/src/sage/quadratic_forms/constructions.py b/src/sage/quadratic_forms/constructions.py index da51beb1c2e..95bd131215e 100644 --- a/src/sage/quadratic_forms/constructions.py +++ b/src/sage/quadratic_forms/constructions.py @@ -40,7 +40,6 @@ def BezoutianQuadraticForm(f, g): AUTHORS: - Fernando Rodriguez-Villegas, Jonathan Hanke -- added on 11/9/2008 - """ # Check that f and g are polynomials with a common base ring if not isinstance(f, Polynomial) or not isinstance(g, Polynomial): @@ -69,13 +68,13 @@ def BezoutianQuadraticForm(f, g): def HyperbolicPlane_quadratic_form(R, r=1): """ - Constructs the direct sum of `r` copies of the quadratic form `xy` + Construct the direct sum of `r` copies of the quadratic form `xy` representing a hyperbolic plane defined over the base ring `R`. INPUT: - - ``R``: a ring - - ``n`` (integer, default 1) number of copies + - ``R`` -- a ring + - ``n`` -- integer (default: 1); number of copies EXAMPLES:: diff --git a/src/sage/quadratic_forms/count_local_2.pyx b/src/sage/quadratic_forms/count_local_2.pyx index 3ce05a3a413..2cf39e037a3 100644 --- a/src/sage/quadratic_forms/count_local_2.pyx +++ b/src/sage/quadratic_forms/count_local_2.pyx @@ -18,12 +18,12 @@ def count_modp__by_gauss_sum(n, p, m, Qdet): INPUT: - - ``n`` -- an integer `\geq 1` + - ``n`` -- integer `\geq 1` - ``p`` -- a prime number > 2 - - ``m`` -- an integer - - ``Qdet`` -- a integer which is non-zero mod `p` + - ``m`` -- integer + - ``Qdet`` -- a integer which is nonzero mod `p` - OUTPUT: an integer `\geq 0` + OUTPUT: integer `\geq 0` EXAMPLES:: @@ -55,12 +55,10 @@ def count_modp__by_gauss_sum(n, p, m, Qdet): ....: == count_modp__by_gauss_sum(3, 3, m, 2) ....: for m in range(3)] [True, True, True] - - """ # Check that Qdet is non-degenerate if Qdet % p == 0: - raise RuntimeError("Qdet must be non-zero.") + raise RuntimeError("Qdet must be nonzero.") # Check that p is prime > 2 if not is_prime(p) or p == 2: @@ -74,14 +72,14 @@ def count_modp__by_gauss_sum(n, p, m, Qdet): neg1 = -1 if not m % p: if n % 2: - count = p**(n-1) + count = p**(n - 1) else: - count = p**(n-1) + (p-1) * (p**((n-2)//2)) * kronecker_symbol(((neg1**(n//2)) * Qdet) % p, p) + count = p**(n - 1) + (p - 1) * (p**((n - 2) // 2)) * kronecker_symbol(((neg1**(n // 2)) * Qdet) % p, p) else: if n % 2: - count = p**(n-1) + p**((n-1)//2) * kronecker_symbol(((neg1**((n-1)//2)) * Qdet * m) % p, p) + count = p**(n - 1) + p**((n - 1) // 2) * kronecker_symbol(((neg1**((n - 1) // 2)) * Qdet * m) % p, p) else: - count = p**(n-1) - p**((n-2)//2) * kronecker_symbol(((neg1**(n//2)) * Qdet) % p, p) + count = p**(n - 1) - p**((n - 2) // 2) * kronecker_symbol(((neg1**(n // 2)) * Qdet) % p, p) # Return the result return count @@ -117,13 +115,13 @@ cdef CountAllLocalTypesNaive_cdef(Q, p, k, m, zvec, nzvec): # Perform a carry (when value = R-1) until we can increment freely ptr = len(v) - while ((ptr > 0) and (v[ptr-1] == R-1)): - v[ptr-1] += 1 + while ((ptr > 0) and (v[ptr - 1] == R - 1)): + v[ptr - 1] += 1 ptr += -1 # Only increment if we're not already at the zero vector =) if ptr > 0: - v[ptr-1] += 1 + v[ptr - 1] += 1 # Evaluate Q(v) quickly tmp_val = Mod(0, R) @@ -157,9 +155,9 @@ def CountAllLocalTypesNaive(Q, p, k, m, zvec, nzvec): - ``Q`` -- quadratic form over `\ZZ` - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) - - ``zvec``, ``nzvec`` -- a list of integers in ``range(Q.dim())``, or ``None`` + - ``k`` -- integer > 0 + - ``m`` -- integer (depending only on mod `p^k`) + - ``zvec``, ``nzvec`` -- list of integers in ``range(Q.dim())``, or ``None`` OUTPUT: @@ -176,7 +174,6 @@ def CountAllLocalTypesNaive(Q, p, k, m, zvec, nzvec): [6, 6, 0, 0, 0, 0] sage: CountAllLocalTypesNaive(Q, 3, 1, 0, None, None) [15, 12, 1, 2, 0, 2] - """ return CountAllLocalTypesNaive_cdef(Q, p, k, m, zvec, nzvec) @@ -189,7 +186,6 @@ cdef local_solution_type_cdef(Q, p, w, zvec, nzvec): NOTE: No internal checking is done to test if `p` is a prime >=2, or that Q has the same size as `w`. - """ cdef long i cdef long n @@ -218,7 +214,7 @@ cdef local_solution_type_cdef(Q, p, w, zvec, nzvec): # print("IsLocalSolutionType: Passed the Zero congruence condition test \n") # Check if the solution satisfies the nzvec "nonzero" congruence conditions - # (nzvec is non-empty and its components index a non-zero vector mod p) + # (nzvec is non-empty and its components index a nonzero vector mod p) if nzvec is None: nonzero_flag = True elif len(nzvec) == 0: @@ -228,7 +224,7 @@ cdef local_solution_type_cdef(Q, p, w, zvec, nzvec): i = 0 while not nonzero_flag and i < len(nzvec): if w[nzvec[i]] % p: - nonzero_flag = True # The non-zero condition is satisfied when we find one non-zero entry + nonzero_flag = True # The nonzero condition is satisfied when we find one nonzero entry i += 1 if not nonzero_flag: @@ -243,7 +239,7 @@ cdef local_solution_type_cdef(Q, p, w, zvec, nzvec): return 1 if p == 2: for i in range(n - 1): - if Q[i, i+1] % p and (w[i] % p or w[i+1] % p): + if Q[i, i + 1] % p and (w[i] % p or w[i + 1] % p): return 1 # 2: Check Zero-type @@ -261,11 +257,11 @@ cdef local_solution_type_cdef(Q, p, w, zvec, nzvec): # Compute the valuation of each index, allowing for off-diagonal terms if Q[i, i] == 0: if i == 0: - val = valuation(Q[i, i+1], p) # Look at the term to the right + val = valuation(Q[i, i + 1], p) # Look at the term to the right elif i == n - 1: - val = valuation(Q[i-1, i], p) # Look at the term above + val = valuation(Q[i - 1, i], p) # Look at the term above else: - val = valuation(Q[i, i+1] + Q[i-1, i], p) # Finds the valuation of the off-diagonal term since only one isn't zero + val = valuation(Q[i, i + 1] + Q[i - 1, i], p) # Finds the valuation of the off-diagonal term since only one isn't zero else: val = valuation(Q[i, i], p) @@ -285,3 +281,83 @@ cdef local_solution_type_cdef(Q, p, w, zvec, nzvec): print(" Solution vector is " + str(w)) print(" and Q is \n" + str(Q) + "\n") raise RuntimeError("Error in IsLocalSolutionType: Should not execute this line... =( \n") + + +def count_all_local_good_types_normal_form(Q, p, k, m, zvec, nzvec): + r""" + This is an internal routine, which is called by + :meth:`sage.quadratic_forms.quadratic_form.QuadraticForm.local_good_density_congruence_even + QuadraticForm.local_good_density_congruence_even`. See the documentation of + that method for more details. + + INPUT: + + - ``Q`` -- quadratic form over `\ZZ` in local normal form at p with no zero blocks mod `p^k` + - ``p`` -- prime number > 0 + - ``k`` -- integer > 0 + - ``m`` -- non-negative integer (depending only on mod `p^k`) + - ``zvec``, ``nzvec`` -- list of integers in ``range(Q.dim())``, or ``None`` + + OUTPUT: + + a non-negative integer giving the number of solutions of Good type. + + EXAMPLES:: + + sage: from sage.quadratic_forms.count_local_2 import count_all_local_good_types_normal_form + sage: Q = DiagonalQuadraticForm(ZZ, [1,2,3]) + sage: Q_local_at2 = Q.local_normal_form(2) + sage: Q_local_at3 = Q.local_normal_form(3) + sage: count_all_local_good_types_normal_form(Q_local_at2, 2, 3, 3, None, None) + 64 + sage: count_all_local_good_types_normal_form(Q_local_at2, 2, 3, 3, [0], None) + 32 + sage: count_all_local_good_types_normal_form(Q_local_at3, 3, 2, 1, None, None) + 54 + """ + n = Q.dim() + if n == 0: + return 0 + + m_range = p**k + if zvec is None: + zvec = [] + if nzvec is None: + nzvec = [] + + # determine local blocks + blocks = [] + i = 0 + while i < n - 1: + if Q[i, i + 1] != 0: + blocks += [(i, i + 1)] + i += 2 + else: + blocks += [(i,)] + i += 1 + if i < n: + blocks += [(i,)] + + solutions = [[0, 0] for _ in range(m_range)] # [good, not good] + solutions[0][1] = 1 + for b in blocks: + Q_part = Q.extract_variables(b) + zvec_local = range(len(b)) if (b[0] in zvec) else None + nzvec_local = range(len(b)) if (b[0] in nzvec) else None + + solutions_part = [[0, 0] for _ in range(m_range)] + for m_part in range(m_range): + cnt = CountAllLocalTypesNaive(Q_part, p, k, m_part, zvec_local, nzvec_local) + solutions_part[m_part][0] = cnt[1] + solutions_part[m_part][1] = cnt[0] - cnt[1] + + # compute convolution of counts + solutions_new = [[0, 0] for _ in range(m_range)] + for m1 in range(m_range): + for m2 in range(m_range): + total = (solutions[m1][0] + solutions[m1][1]) * (solutions_part[m2][0] + solutions_part[m2][1]) + good = total - solutions[m1][1] * solutions_part[m2][1] + solutions_new[(m1 + m2) % m_range][0] += good + solutions_new[(m1 + m2) % m_range][1] += total - good + solutions = solutions_new + return solutions[m % m_range][0] diff --git a/src/sage/quadratic_forms/extras.py b/src/sage/quadratic_forms/extras.py index edb738ac561..38ab9c498d9 100644 --- a/src/sage/quadratic_forms/extras.py +++ b/src/sage/quadratic_forms/extras.py @@ -13,7 +13,7 @@ def is_triangular_number(n, return_value=False): Return whether ``n`` is a triangular number. A *triangular number* is a number of the form `k(k+1)/2` for some - non-negative integer `n`. See :wikipedia:`Triangular_number`. The sequence + nonnegative integer `n`. See :wikipedia:`Triangular_number`. The sequence of triangular number is references as A000217 in the Online encyclopedia of integer sequences (OEIS). @@ -22,11 +22,11 @@ def is_triangular_number(n, return_value=False): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``return_value`` -- a boolean set to ``False`` by default. If set to + - ``return_value`` -- boolean (default: ``False``); if set to ``True`` the function returns a pair made of a boolean and the value `v` - such that `v(v+1)/2 = n`. + such that `v(v+1)/2 = n` EXAMPLES:: @@ -85,11 +85,9 @@ def extend_to_primitive(A_input): INPUT: - a matrix, or a list of length n vectors (in the same space) + - ``A_input`` -- a matrix or a list of length n vectors (in the same space) - OUTPUT: - - a square matrix, or a list of n vectors (resp.) + OUTPUT: a square matrix or a list of n vectors (resp.) EXAMPLES:: diff --git a/src/sage/quadratic_forms/genera/genus.py b/src/sage/quadratic_forms/genera/genus.py index d98b2416c3d..0227fa8319a 100644 --- a/src/sage/quadratic_forms/genera/genus.py +++ b/src/sage/quadratic_forms/genera/genus.py @@ -18,7 +18,7 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** - +from pathlib import Path from copy import copy, deepcopy from sage.misc.lazy_import import lazy_import @@ -45,9 +45,9 @@ def genera(sig_pair, determinant, max_scale=None, even=False): INPUT: - - ``sig_pair`` -- a pair of non-negative integers giving the signature + - ``sig_pair`` -- a pair of nonnegative integers giving the signature - - ``determinant`` -- an integer; the sign is ignored + - ``determinant`` -- integer; the sign is ignored - ``max_scale`` -- (default: ``None``) an integer; the maximum scale of a jordan block @@ -85,7 +85,7 @@ def genera(sig_pair, determinant, max_scale=None, even=False): sig_pair = (ZZ(sig_pair[0]), ZZ(sig_pair[1])) even = bool(even) if not all(s >= 0 for s in sig_pair): - raise ValueError("the signature vector must be a pair of non negative integers.") + raise ValueError("the signature vector must be a pair of nonnegative integers.") if max_scale is None: max_scale = determinant else: @@ -139,9 +139,9 @@ def _local_genera(p, rank, det_val, max_scale, even): - ``det_val`` -- valuation of the determinant at `p` - - ``max_scale`` -- an integer the maximal scale of a jordan block + - ``max_scale`` -- integer the maximal scale of a jordan block - - ``even`` -- ``bool``; is ignored if `p` is not `2` + - ``even`` -- boolean; ignored if `p` is not `2` EXAMPLES:: @@ -225,17 +225,17 @@ def _local_genera(p, rank, det_val, max_scale, even): def _blocks(b, even_only=False): r""" - Return all viable `2`-adic jordan blocks with rank and scale given by ``b`` + Return all viable `2`-adic jordan blocks with rank and scale given by ``b``. This is a helper function for :meth:`_local_genera`. It is based on the existence conditions for a modular `2`-adic genus symbol. INPUT: - - ``b`` -- a list of `5` non-negative integers the first two are kept + - ``b`` -- list of `5` nonnegative integers the first two are kept and all possibilities for the remaining `3` are enumerated - - ``even_only`` -- bool (default: ``True``) if set, the blocks are even + - ``even_only`` -- boolean (default: ``True``); if set, the blocks are even EXAMPLES:: @@ -469,7 +469,7 @@ def is_2_adic_genus(genus_symbol_quintuple_list) -> bool: INPUT: - ``genus_symbol_quintuple_list`` -- a quintuple of integers (with certain - restrictions). + restrictions) OUTPUT: boolean @@ -509,12 +509,12 @@ def is_2_adic_genus(genus_symbol_quintuple_list) -> bool: return False if s[1] == 2 and s[3] == 1: if s[2] % 8 in (1, 7): - if not s[4] in (0, 2, 6): + if s[4] not in (0, 2, 6): return False if s[2] % 8 in (3, 5): - if not s[4] in (2, 4, 6): + if s[4] not in (2, 4, 6): return False - if (s[1] - s[4]) % 2 == 1: + if (s[1] - s[4]) % 2: return False if s[3] == 0 and s[4] != 0: return False @@ -534,7 +534,7 @@ def canonical_2_adic_compartments(genus_symbol_quintuple_list): - ``genus_symbol_quintuple_list`` -- a quintuple of integers (with certain restrictions) - OUTPUT: a list of lists of integers + OUTPUT: list of lists of integers EXAMPLES:: @@ -607,7 +607,7 @@ def canonical_2_adic_trains(genus_symbol_quintuple_list, compartments=None): restrictions). - ``compartments`` -- this argument is deprecated - OUTPUT: a list of lists of distinct integers + OUTPUT: list of lists of distinct integers EXAMPLES:: @@ -705,9 +705,9 @@ def canonical_2_adic_reduction(genus_symbol_quintuple_list): - ``genus_symbol_quintuple_list`` -- a quintuple of integers (with certain restrictions) - - ``compartments`` -- a list of lists of distinct integers (optional) + - ``compartments`` -- list of lists of distinct integers (optional) - OUTPUT: a list of lists of distinct integers. + OUTPUT: list of lists of distinct integers EXAMPLES:: @@ -824,7 +824,7 @@ def basis_complement(B): def signature_pair_of_matrix(A): r""" - Computes the signature pair `(p, n)` of a non-degenerate symmetric + Compute the signature pair `(p, n)` of a non-degenerate symmetric matrix, where - `p` is the number of positive eigenvalues of `A` @@ -886,11 +886,11 @@ def p_adic_symbol(A, p, val): - ``A`` -- symmetric matrix with integer coefficients - ``p`` -- prime number - - ``val`` -- non-negative integer; valuation of the maximal elementary + - ``val`` -- nonnegative integer; valuation of the maximal elementary divisor of `A` needed to obtain enough precision. Calculation is modulo `p` to the ``val+3``. - OUTPUT: a list of lists of integers + OUTPUT: list of lists of integers EXAMPLES:: @@ -902,7 +902,6 @@ def p_adic_symbol(A, p, val): sage: p_adic_symbol(A, 3, 1) [[0, 3, 1], [1, 1, -1]] - """ if p % 2 == 0: return two_adic_symbol(A, val) @@ -982,7 +981,7 @@ def split_odd(A): INPUT: - ``A`` -- an odd symmetric matrix with integer coefficients (which admits a - splitting as above). + splitting as above) OUTPUT: @@ -1073,9 +1072,9 @@ def trace_diag_mod_8(A): INPUT: - ``A`` -- symmetric matrix with coefficients in `\ZZ` which is odd in - `\ZZ/2\ZZ` and has determinant not divisible by `8`. + `\ZZ/2\ZZ` and has determinant not divisible by `8` - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1120,7 +1119,7 @@ def two_adic_symbol(A, val): INPUT: - ``A`` -- symmetric matrix with integer coefficients, non-degenerate - - ``val`` -- non-negative integer; valuation of maximal `2`-elementary divisor + - ``val`` -- nonnegative integer; valuation of maximal `2`-elementary divisor OUTPUT: @@ -1133,7 +1132,6 @@ def two_adic_symbol(A, val): sage: A = diagonal_matrix(ZZ, [1, 2, 3, 4]) sage: two_adic_symbol(A, 2) [[0, 2, 3, 1, 4], [1, 1, 1, 1, 1], [2, 1, 1, 1, 1]] - """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1266,7 +1264,6 @@ def __init__(self, prime, symbol, check=True): r""" Create the local genus symbol of given prime and local invariants. - EXAMPLES:: sage: from sage.quadratic_forms.genera.genus import p_adic_symbol @@ -1297,9 +1294,9 @@ def __init__(self, prime, symbol, check=True): def __repr__(self): r""" - String representation for the `p`-adic genus symbol + String representation for the `p`-adic genus symbol. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -1457,7 +1454,6 @@ def __eq__(self, other): True sage: G3 == G3 True - """ p = self._prime if p != other._prime: @@ -1669,13 +1665,11 @@ def automorphous_numbers(self): def canonical_symbol(self): r""" - Return (and cache) the canonical p-adic genus symbol. This is + Return (and cache) the canonical `p`-adic genus symbol. This is only really affects the `2`-adic symbol, since when `p > 2` the symbol is already canonical. - OUTPUT: - - a list of lists of integers + OUTPUT: list of lists of integers EXAMPLES:: @@ -1741,7 +1735,7 @@ def gram_matrix(self, check=True): INPUT: - - ``check`` (default: ``True``) -- double check the result + - ``check`` -- boolean (default: ``True``); double check the result EXAMPLES:: @@ -1907,7 +1901,7 @@ def prime(self): r""" Return the prime number `p` of this `p`-adic local symbol. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1951,7 +1945,7 @@ def symbol_tuple_list(self): Return a copy of the underlying list of lists of integers defining the genus symbol. - OUTPUT: a list of lists of integers + OUTPUT: list of lists of integers EXAMPLES:: @@ -1982,7 +1976,7 @@ def number_of_blocks(self): r""" Return the number of positive dimensional symbols/Jordan blocks. - OUTPUT: a non-negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -2009,12 +2003,12 @@ def number_of_blocks(self): def determinant(self): r""" - Returns the (`p`-part of the) determinant (square-class) of the + Return the (`p`-part of the) determinant (square-class) of the Hessian matrix of the quadratic form (given by regarding the integral symmetric matrix which generated this genus symbol as the Gram matrix of `Q`) associated to this local genus symbol. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -2044,7 +2038,7 @@ def dimension(self): r""" Return the dimension of a quadratic form associated to this genus symbol. - OUTPUT: a non-negative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -2143,7 +2137,7 @@ def excess(self): [CS1999]_ Conway and Sloane Book, 3rd edition, pp 370-371. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -2185,7 +2179,6 @@ def excess(self): 0 sage: p = 11; Genus_Symbol_p_adic_ring(p, p_adic_symbol(A, p, 2)).excess() 0 - """ p = self._prime if self._prime == 2: @@ -2209,7 +2202,7 @@ def scale(self): The scale of `(L,b)` is defined as the ideal `b(L,L)`. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -2269,7 +2262,7 @@ def trains(self) -> list: symbol if it is associated to the prime `p=2` (and raise an error for all other primes). - OUTPUT: a list of non-negative integers + OUTPUT: list of nonnegative integers EXAMPLES:: @@ -2282,7 +2275,6 @@ def trains(self) -> list: Genus symbol at 2: [2^-2 4^1 8^1]_6 sage: G2.trains() [[0, 1, 2]] - """ # Check that p = 2 if self._prime != 2: @@ -2296,7 +2288,7 @@ def compartments(self) -> list: symbol if it is associated to the prime `p=2` (and raise an error for all other primes). - OUTPUT: a list of non-negative integers + OUTPUT: list of nonnegative integers EXAMPLES:: @@ -2309,7 +2301,6 @@ def compartments(self) -> list: Genus symbol at 2: [2^-2 4^1 8^1]_6 sage: G2.compartments() [[0, 1, 2]] - """ # Check that p = 2 if self._prime != 2: @@ -2326,15 +2317,15 @@ class GenusSymbol_global_ring: INPUT: - - ``signature_pair`` -- a tuple of two non-negative integers + - ``signature_pair`` -- tuple of two nonnegative integers - - ``local_symbols`` -- a list of :class:`Genus_Symbol_p_adic_ring` instances + - ``local_symbols`` -- list of :class:`Genus_Symbol_p_adic_ring` instances sorted by their primes - ``representative`` -- (default: ``None``) integer symmetric matrix; the Gram matrix of a representative of this genus - - ``check`` -- (default: ``True``) a boolean; checks the input + - ``check`` -- boolean (default: ``True``); checks the input EXAMPLES:: @@ -2394,7 +2385,7 @@ def __repr__(self) -> str: r""" Return a string representing the global genus symbol. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -2418,7 +2409,6 @@ def __repr__(self) -> str: Signature: (2, 0) Genus symbol at 2: 1^-2 Genus symbol at 3: 1^-1 3^-1 - """ rep = "Genus" if self.dimension() <= 20: @@ -2460,7 +2450,7 @@ def __eq__(self, other) -> bool: INPUT: - a :class:`GenusSymbol_global_ring` object + - ``other`` -- a :class:`GenusSymbol_global_ring` object OUTPUT: boolean @@ -2510,7 +2500,7 @@ def __ne__(self, other) -> bool: INPUT: - a ``GenusSymbol_global_ring`` object + - ``other`` -- a ``GenusSymbol_global_ring`` object OUTPUT: boolean @@ -2532,7 +2522,6 @@ def __ne__(self, other) -> bool: sage: GS2 != GS2 False - """ return not self == other @@ -2655,7 +2644,7 @@ def spinor_generators(self, proper) -> list: - ``proper`` -- boolean - OUTPUT: a list of primes not dividing the determinant + OUTPUT: list of primes not dividing the determinant EXAMPLES:: @@ -2760,7 +2749,7 @@ def determinant(self): form whose Gram matrix is the Gram matrix giving rise to this global genus symbol. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -2813,7 +2802,8 @@ def direct_sum(self, other): signature_pair = (p1 + p2, n1 + n2) primes = [s.prime() for s in self.local_symbols()] - primes += [s.prime() for s in other.local_symbols() if not s.prime() in primes] + primes.extend(s.prime() for s in other.local_symbols() + if s.prime() not in primes) primes.sort() local_symbols = [] for p in primes: @@ -2941,13 +2931,11 @@ def _compute_representative(self, LLL=True): sig = self.signature_pair_of_matrix() if sig[0] * sig[1] != 0: from sage.env import SAGE_EXTCODE - from sage.interfaces.gp import gp - m = pari(L) - gp.read(SAGE_EXTCODE + "/pari/simon/qfsolve.gp") - m = gp.eval('qflllgram_indefgoon(%s)' % m) + pari.read(Path(SAGE_EXTCODE) / "pari" / "simon" / "qfsolve.gp") + m = pari('qflllgram_indefgoon')(m) # convert the output string to sage - L = pari(m).sage()[0] + L = m.sage()[0] elif sig[1] != 0: U = -(-L).LLL_gram() L = U.T * L * U @@ -2991,14 +2979,14 @@ def representative(self): def representatives(self, backend=None, algorithm=None): r""" - Return a list of representatives for the classes in this genus + Return a list of representatives for the classes in this genus. INPUT: - ``backend`` -- (default: ``None``) - ``algorithm`` -- (default: ``None``) - OUTPUT: a list of Gram matrices + OUTPUT: list of Gram matrices EXAMPLES:: @@ -3024,7 +3012,7 @@ def representatives(self, backend=None, algorithm=None): For positive definite forms the magma backend is available:: sage: G = Genus(matrix.diagonal([1, 1, 7])) - sage: G.representatives(backend="magma") # optional - magma + sage: G.representatives(backend='magma') # optional - magma ( [1 0 0] [ 1 0 0] [0 1 0] [ 0 2 -1] @@ -3163,7 +3151,6 @@ def _standard_mass(self): sage: GS = Genus(A) sage: GS._standard_mass() # needs sage.symbolic 1/48 - """ from sage.symbolic.constants import pi from sage.symbolic.ring import SR @@ -3206,7 +3193,7 @@ def mass(self, backend='sage'): INPUT: - - ``backend`` -- default: ``'sage'``, or ``'magma'`` + - ``backend`` -- ``'sage'`` (default) or ``'magma'`` OUTPUT: a rational number @@ -3293,7 +3280,7 @@ def scale(self): The scale of `(L,b)` is defined as the ideal `b(L,L)`. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -3334,10 +3321,10 @@ def _gram_from_jordan_block(p, block, discr_form=False): - ``p`` -- a prime number - - ``block`` -- a list of 3 integers or 5 integers if `p` is `2` + - ``block`` -- list of 3 integers or 5 integers if `p` is `2` - - ``discr_form`` -- bool (default: ``False``); if ``True`` invert the scales - to obtain a Gram matrix for the discriminant form instead. + - ``discr_form`` -- boolean (default: ``False``); if ``True`` invert the scales + to obtain a Gram matrix for the discriminant form instead EXAMPLES:: diff --git a/src/sage/quadratic_forms/genera/normal_form.py b/src/sage/quadratic_forms/genera/normal_form.py index 1dcf13d18e3..d0081636e61 100644 --- a/src/sage/quadratic_forms/genera/normal_form.py +++ b/src/sage/quadratic_forms/genera/normal_form.py @@ -101,12 +101,10 @@ def collect_small_blocks(G): INPUT: - - ``G`` -- a block_diagonal matrix consisting of + - ``G`` -- a ``block_diagonal`` matrix consisting of `1` by `1` and `2` by `2` blocks - OUTPUT: - - - a list of `1` by `1` and `2` by `2` matrices -- the blocks + OUTPUT: list of `1` by `1` and `2` by `2` matrices; the blocks EXAMPLES:: @@ -132,7 +130,7 @@ def p_adic_normal_form(G, p, precision=None, partial=False, debug=False): r""" Return the transformation to the `p`-adic normal form of a symmetric matrix. - Two ``p-adic`` quadratic forms are integrally equivalent if and only if + Two ```p`-adic`` quadratic forms are integrally equivalent if and only if their Gram matrices have the same normal form. Let `p` be odd and `u` be the smallest non-square modulo `p`. @@ -173,8 +171,8 @@ def p_adic_normal_form(G, p, precision=None, partial=False, debug=False): - ``G`` -- a symmetric `n` by `n` matrix in `\QQ` - ``p`` -- a prime number -- it is not checked whether it is prime - ``precision`` -- if not set, the minimal possible is taken - - ``partial`` -- boolean (default: ``False``) if set, only the - partial normal form is returned. + - ``partial`` -- boolean (default: ``False``); if set, only the + partial normal form is returned OUTPUT: @@ -300,7 +298,7 @@ def _find_min_p(G, cnt, lower_bound=0): - ``G`` -- a symmetric `n` by `n` matrix in `\QQ_p` - ``cnt`` -- start search from this index - - ``lower_bound`` -- an integer (default: ``0``) + - ``lower_bound`` -- integer (default: 0) a lower bound for the valuations used for optimization OUTPUT: @@ -363,7 +361,7 @@ def _get_small_block_indices(G): - ``G`` -- a block_diagonal matrix consisting of `1` by `1` and `2` by `2` blocks - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -398,9 +396,9 @@ def _get_homogeneous_block_indices(G): INPUT: - ``G`` -- a block diagonal matrix over the `p`-adics - with blocks of size at most `2`. + with blocks of size at most `2` - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -559,7 +557,7 @@ def _jordan_odd_adic(G): INPUT: - - a symmetric matrix over `\ZZ_p` of type ``'fixed-mod'`` + - ``G`` -- a symmetric matrix over `\ZZ_p` of type ``'fixed-mod'`` OUTPUT: @@ -741,10 +739,6 @@ def _min_nonsquare(p): - ``p`` -- a prime number - OUTPUT: - - - ``a`` -- the minimal nonsquare mod `p` - EXAMPLES:: sage: from sage.quadratic_forms.genera.normal_form import _min_nonsquare @@ -771,8 +765,8 @@ def _normalize(G, normal_odd=True): - ``G`` -- a symmetric matrix over `\ZZ_p` in jordan form -- the output of :meth:`p_adic_normal_form` or :meth:`_jordan_2_adic` - - ``normal_odd`` -- bool (default: ``True``) if true and `p` is odd, - compute a normal form. + - ``normal_odd`` -- boolean (default: ``True``); if ``True`` and `p` is odd, + compute a normal form OUTPUT: @@ -988,12 +982,12 @@ def _normalize_odd_2x2(G): INPUT: - ``G`` -- a multiple of the `2` by `2` identity_matrix - over the `p`-adics for `p` odd. + over the `p`-adics for `p` odd OUTPUT: - - A transformation matrix ``B`` such that - ``B * G * B.T`` is the identity matrix + A transformation matrix ``B`` such that ``B * G * B.T`` is the identity + matrix. EXAMPLES:: @@ -1121,15 +1115,15 @@ def _relations(G, n): INPUT: - - ``n`` -- an integer between 1 and 10 -- the number of the relation + - ``n`` -- integer between 1 and 10 -- the number of the relation - ``G`` -- a block diagonal matrix consisting of blocks of types `U, V, W` the left side of the relation. If ``G`` does not match `n` then the results are unpredictable. OUTPUT: - - square matrix ``B`` such that ``B * G * B.T`` is the right side of the - relation which consists of blocks of types `U`, `V`, `W` again + Square matrix ``B`` such that ``B * G * B.T`` is the right side of the + relation which consists of blocks of types `U`, `V`, `W` again. EXAMPLES:: @@ -1385,11 +1379,9 @@ def _two_adic_normal_forms(G, partial=False): INPUT: - ``G`` -- block diagonal matrix with blocks of type `U`, `V`, `W` - - ``partial`` -- bool (default: ``False``) - - OUTPUT: + - ``partial`` -- boolean (default: ``False``) - - ``D``, ``B`` -- such that ``D = B * G * B.T`` + OUTPUT: ``D``, ``B``; such that ``D = B * G * B.T`` EXAMPLES:: diff --git a/src/sage/quadratic_forms/genera/spinor_genus.py b/src/sage/quadratic_forms/genera/spinor_genus.py index ee6453b1fd5..4da6f0a2fbd 100644 --- a/src/sage/quadratic_forms/genera/spinor_genus.py +++ b/src/sage/quadratic_forms/genera/spinor_genus.py @@ -37,7 +37,7 @@ class SpinorOperator(AbelianGroupElement_gap): A spinor operator seen as a tuple of square classes. For `2` the square class is represented as one of `1,3,5,7` and for - `p` odd it is `1` for a p-adic unit square and `-1` for a non-square. + `p` odd it is `1` for a `p`-adic unit square and `-1` for a non-square. EXAMPLES:: @@ -149,7 +149,7 @@ def to_square_class(self, x, p): - ``p`` -- a prime - - ``x``` -- a non zero rational number + - ``x`` -- nonzero rational number EXAMPLES:: @@ -166,7 +166,7 @@ def to_square_class(self, x, p): """ x = QQ(x) if x == 0: - raise ValueError("x must be non zero") + raise ValueError("x must be nonzero") if p not in self._primes: raise ValueError("not a coordinate prime") v, u = x.val_unit(p) @@ -194,11 +194,10 @@ def delta(self, r, prime=None): INPUT: - - ``r`` -- a non zero integer; - if ``prime`` is ``None``, ``r`` must not be divisible - by the defining primes of ``self`` + - ``r`` -- a nonzero integer; if ``prime`` is ``None``, ``r`` must not + be divisible by the defining primes of ``self`` - - ``prime`` -- (default:``None``) a prime or `-1` + - ``prime`` -- (default: ``None``) a prime or `-1` OUTPUT: diff --git a/src/sage/quadratic_forms/meson.build b/src/sage/quadratic_forms/meson.build new file mode 100644 index 00000000000..0e352ed72be --- /dev/null +++ b/src/sage/quadratic_forms/meson.build @@ -0,0 +1,51 @@ +py.install_sources( + 'all.py', + 'binary_qf.py', + 'bqf_class_group.py', + 'constructions.py', + 'extras.py', + 'qfsolve.py', + 'quadratic_form.py', + 'quadratic_form__automorphisms.py', + 'quadratic_form__count_local_2.py', + 'quadratic_form__equivalence_testing.py', + 'quadratic_form__genus.py', + 'quadratic_form__local_density_congruence.py', + 'quadratic_form__local_density_interfaces.py', + 'quadratic_form__local_field_invariants.py', + 'quadratic_form__local_normal_form.py', + 'quadratic_form__local_representation_conditions.py', + 'quadratic_form__mass.py', + 'quadratic_form__mass__Conway_Sloane_masses.py', + 'quadratic_form__mass__Siegel_densities.py', + 'quadratic_form__neighbors.py', + 'quadratic_form__reduction_theory.py', + 'quadratic_form__siegel_product.py', + 'quadratic_form__split_local_covering.py', + 'quadratic_form__ternary_Tornaria.py', + 'quadratic_form__theta.py', + 'quadratic_form__variable_substitutions.py', + 'random_quadraticform.py', + 'special_values.py', + 'ternary_qf.py', + subdir: 'sage/quadratic_forms', +) + +extension_data = { + 'count_local_2' : files('count_local_2.pyx'), + 'quadratic_form__evaluate' : files('quadratic_form__evaluate.pyx'), + 'ternary' : files('ternary.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/quadratic_forms', + install: true, + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + +install_subdir('genera', install_dir: sage_install_dir / 'quadratic_forms') diff --git a/src/sage/quadratic_forms/qfsolve.py b/src/sage/quadratic_forms/qfsolve.py index 83720128bfc..55fd9a4b3b2 100644 --- a/src/sage/quadratic_forms/qfsolve.py +++ b/src/sage/quadratic_forms/qfsolve.py @@ -129,7 +129,7 @@ def solve(self, c=0): - ``c`` -- (default: 0) a rational number - OUTPUT: A non-zero vector `x` satisfying ``self(x) == c``. + OUTPUT: a nonzero vector `x` satisfying ``self(x) == c`` ALGORITHM: diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index b28bca0fb39..88df6dfcb9c 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -76,14 +76,12 @@ def quadratic_form_from_invariants(F, rk, det, P, sminus): - ``F`` -- the base field; currently only ``QQ`` is allowed - ``rk`` -- integer; the rank - ``det`` -- rational; the determinant - - ``P`` -- a list of primes where Cassel's Hasse invariant + - ``P`` -- list of primes where Cassel's Hasse invariant is negative - ``sminus`` -- integer; the number of negative eigenvalues of any Gram matrix - OUTPUT: - - - a quadratic form with the specified invariants + OUTPUT: a quadratic form with the specified invariants Let `(a_1, \ldots, a_n)` be the gram marix of a regular quadratic space. Then Cassel's Hasse invariant is defined as @@ -194,8 +192,8 @@ class QuadraticForm(SageObject): #. ``QuadraticForm(R, n, entries)``, where - ``R`` -- ring for which the quadratic form is defined - - ``n`` -- an integer `\geq 0` - - ``entries`` -- a list of `n(n+1)/2` coefficients of the quadratic form + - ``n`` -- integer `\geq 0` + - ``entries`` -- list of `n(n+1)/2` coefficients of the quadratic form in `R` (given lexicographically, or equivalently, by rows of the matrix) @@ -221,7 +219,6 @@ class QuadraticForm(SageObject): - ``number_of_automorphisms`` - ``determinant`` - OUTPUT: quadratic form EXAMPLES:: @@ -365,9 +362,9 @@ class QuadraticForm(SageObject): count_congruence_solutions__bad_type_II # Routines to be called by the user to compute local densities - lazy_import("sage.quadratic_forms.quadratic_form__local_density_interfaces", [ - "local_density", - "local_primitive_density" + lazy_import('sage.quadratic_forms.quadratic_form__local_density_interfaces', [ + 'local_density', + 'local_primitive_density' ]) # Routines for computing with ternary forms @@ -404,8 +401,8 @@ class QuadraticForm(SageObject): theta_by_cholesky # Routines to compute the product of all local densities - lazy_import("sage.quadratic_forms.quadratic_form__siegel_product", [ - "siegel_product" + lazy_import('sage.quadratic_forms.quadratic_form__siegel_product', [ + 'siegel_product' ]) # Routines to compute p-neighbors @@ -424,50 +421,50 @@ class QuadraticForm(SageObject): minkowski_reduction, \ minkowski_reduction_for_4vars__SP # Wrappers for Conway-Sloane genus routines (in ./genera/) - lazy_import("sage.quadratic_forms.quadratic_form__genus", [ - "global_genus_symbol", - "local_genus_symbol", - "CS_genus_symbol_list" + lazy_import('sage.quadratic_forms.quadratic_form__genus', [ + 'global_genus_symbol', + 'local_genus_symbol', + 'CS_genus_symbol_list' ]) # Routines to compute local masses for ZZ. - lazy_import("sage.quadratic_forms.quadratic_form__mass", [ - "shimura_mass__maximal", - "GHY_mass__maximal" + lazy_import('sage.quadratic_forms.quadratic_form__mass', [ + 'shimura_mass__maximal', + 'GHY_mass__maximal' ]) - lazy_import("sage.quadratic_forms.quadratic_form__mass__Siegel_densities", [ - "mass__by_Siegel_densities", - "Pall_mass_density_at_odd_prime", - "Watson_mass_at_2", - "Kitaoka_mass_at_2", - "mass_at_two_by_counting_mod_power" + lazy_import('sage.quadratic_forms.quadratic_form__mass__Siegel_densities', [ + 'mass__by_Siegel_densities', + 'Pall_mass_density_at_odd_prime', + 'Watson_mass_at_2', + 'Kitaoka_mass_at_2', + 'mass_at_two_by_counting_mod_power' ]) - lazy_import("sage.quadratic_forms.quadratic_form__mass__Conway_Sloane_masses", [ - "parity", - "is_even", - "is_odd", - "conway_species_list_at_odd_prime", - "conway_species_list_at_2", - "conway_octane_of_this_unimodular_Jordan_block_at_2", - "conway_diagonal_factor", - "conway_cross_product_doubled_power", - "conway_type_factor", - "conway_p_mass", - "conway_standard_p_mass", - "conway_standard_mass", - "conway_mass" + lazy_import('sage.quadratic_forms.quadratic_form__mass__Conway_Sloane_masses', [ + 'parity', + 'is_even', + 'is_odd', + 'conway_species_list_at_odd_prime', + 'conway_species_list_at_2', + 'conway_octane_of_this_unimodular_Jordan_block_at_2', + 'conway_diagonal_factor', + 'conway_cross_product_doubled_power', + 'conway_type_factor', + 'conway_p_mass', + 'conway_standard_p_mass', + 'conway_standard_mass', + 'conway_mass' # conway_generic_mass, \ # conway_p_mass_adjustment ]) # Routines to check local representability of numbers - lazy_import("sage.quadratic_forms.quadratic_form__local_representation_conditions", [ - "local_representation_conditions", - "is_locally_universal_at_prime", - "is_locally_universal_at_all_primes", - "is_locally_universal_at_all_places", - "is_locally_represented_number_at_place", - "is_locally_represented_number" + lazy_import('sage.quadratic_forms.quadratic_form__local_representation_conditions', [ + 'local_representation_conditions', + 'is_locally_universal_at_prime', + 'is_locally_universal_at_all_primes', + 'is_locally_universal_at_all_places', + 'is_locally_represented_number_at_place', + 'is_locally_represented_number' ]) # Routines to make a split local covering of the given quadratic form. @@ -478,15 +475,15 @@ class QuadraticForm(SageObject): split_local_cover # Routines to make automorphisms of the given quadratic form. - lazy_import("sage.quadratic_forms.quadratic_form__automorphisms", [ - "basis_of_short_vectors", - "short_vector_list_up_to_length", - "short_primitive_vector_list_up_to_length", - "_compute_automorphisms", - "automorphism_group", - "automorphisms", - "number_of_automorphisms", - "set_number_of_automorphisms" + lazy_import('sage.quadratic_forms.quadratic_form__automorphisms', [ + 'basis_of_short_vectors', + 'short_vector_list_up_to_length', + 'short_primitive_vector_list_up_to_length', + '_compute_automorphisms', + 'automorphism_group', + 'automorphisms', + 'number_of_automorphisms', + 'set_number_of_automorphisms' ]) # Routines to test the local and global equivalence/isometry of two quadratic forms. @@ -497,13 +494,13 @@ class QuadraticForm(SageObject): is_rationally_isometric # Routines for solving equations of the form Q(x) = c. - lazy_import("sage.quadratic_forms.qfsolve", [ - "solve" + lazy_import('sage.quadratic_forms.qfsolve', [ + 'solve' ]) # Genus - lazy_import("sage.quadratic_forms.genera.genus", - "_genera_staticmethod", as_="genera") + lazy_import('sage.quadratic_forms.genera.genus', + '_genera_staticmethod', as_='genera') def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_of_automorphisms=None, determinant=None): """ @@ -539,7 +536,7 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ sage: QuadraticForm(ZZ, -1) Traceback (most recent call last): ... - ValueError: the size must be a non-negative integer, not -1 + ValueError: the size must be a nonnegative integer, not -1 sage: x = polygen(ZZ, 'x') sage: QuadraticForm(x**2) @@ -618,7 +615,7 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ # Verify the size of the matrix is an integer >= 0 n = ZZ(n) if n < 0: - raise ValueError(f"the size must be a non-negative integer, not {n}") + raise ValueError(f"the size must be a nonnegative integer, not {n}") # Store the relevant variables N = n * (n + 1) // 2 @@ -702,7 +699,6 @@ def __pari__(self): sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) sage: Q.__pari__() # needs sage.libs.pari [2, 0; 0, 10] - """ return self.matrix().__pari__() @@ -780,7 +776,6 @@ def __getitem__(self, ij): [1 2 3] [2 4 5] [3 5 6] - """ # Unpack the list of indices i, j = ij @@ -813,7 +808,6 @@ def __setitem__(self, ij, coeff): [ 1 2 3 ] [ * 4 17 ] [ * * 6 ] - """ # Unpack the list of indices i, j = ij @@ -869,7 +863,6 @@ def __eq__(self, right): False sage: Q1 == Q2 False - """ if not isinstance(right, QuadraticForm): return False @@ -1043,7 +1036,6 @@ def __call__(self, v): sage: Q(M) Quadratic form in 1 variables over Integer Ring with coefficients: [ 14 ] - """ # If we are passed a matrix A, return the quadratic form Q(A(x)) # (In matrix notation: A^t * Q * A) @@ -1081,7 +1073,7 @@ def __call__(self, v): def _is_even_symmetric_matrix_(self, A, R=None): """ - Tests if a matrix is symmetric, defined over `R`, and has even diagonal in `R`. + Test if a matrix is symmetric, defined over `R`, and has even diagonal in `R`. INPUT: @@ -1101,7 +1093,6 @@ def _is_even_symmetric_matrix_(self, A, R=None): sage: A[0,0] = 1 sage: Q._is_even_symmetric_matrix_(A) False - """ if not isinstance(A, Matrix): raise TypeError("A is not a matrix.") @@ -1148,7 +1139,6 @@ def matrix(self): [ 0 1 2] [ 1 6 4] [ 2 4 10] - """ return self.Hessian_matrix() @@ -1167,7 +1157,6 @@ def Hessian_matrix(self): [2 6] sage: Q.matrix().base_ring() Rational Field - """ mat_entries = [] for i in range(self.dim()): @@ -1200,7 +1189,6 @@ def Gram_matrix_rational(self): [0 0 0 7] sage: A.base_ring() Rational Field - """ return (ZZ(1) / ZZ(2)) * self.matrix() @@ -1214,7 +1202,7 @@ def Gram_matrix(self): Q(x) = x^t\cdot A\cdot x, defined over the base ring of `Q`. If this is not possible, - then a :class:`TypeError` is raised. + then a :exc:`TypeError` is raised. EXAMPLES:: @@ -1258,7 +1246,6 @@ def has_integral_Gram_matrix(self): sage: Q = QuadraticForm(ZZ, 2, [4,5,6]) sage: Q.has_integral_Gram_matrix() False - """ # Warning over fields if self.base_ring() in Fields(): @@ -1301,7 +1288,7 @@ def polynomial(self, names='x'): - ``names`` -- specification of the names of the variables; see :func:`PolynomialRing` - OUTPUT: The polynomial form of the quadratic form. + OUTPUT: the polynomial form of the quadratic form EXAMPLES:: @@ -1436,7 +1423,6 @@ def adjoint_primitive(self): Quadratic form in 2 variables over Integer Ring with coefficients: [ 3 -2 ] [ * 1 ] - """ return QuadraticForm(self.Hessian_matrix().adjoint_classical()).primitive() @@ -1489,7 +1475,7 @@ def det(self): Return the determinant of the Gram matrix of `2\cdot Q`, or equivalently the determinant of the Hessian matrix of `Q`. - .. NOTE: + .. NOTE:: This is always defined over the same ring as the quadratic form. @@ -1581,7 +1567,7 @@ def level(self): generator for the smallest ideal `N` of `R` such that `N\cdot (` the matrix of `2*Q` `)^{(-1)}` is in `R` with diagonal in `2R`. - Over `\ZZ` this returns a non-negative number. + Over `\ZZ` this returns a nonnegative number. (Caveat: This always returns the unit ideal when working over a field!) @@ -1680,7 +1666,7 @@ def level_ideal(self): def bilinear_map(self, v, w): r""" - Return the value of the associated bilinear map on two vectors + Return the value of the associated bilinear map on two vectors. Given a quadratic form `Q` over some base ring `R` with characteristic not equal to 2, this gives the image of two @@ -1691,7 +1677,7 @@ def bilinear_map(self, v, w): - ``v``, ``w`` -- two vectors - OUTPUT: an element of the base ring `R`. + OUTPUT: an element of the base ring `R` EXAMPLES: diff --git a/src/sage/quadratic_forms/quadratic_form__automorphisms.py b/src/sage/quadratic_forms/quadratic_form__automorphisms.py index 4b6e3594f83..4fa4d4fe1ff 100644 --- a/src/sage/quadratic_forms/quadratic_form__automorphisms.py +++ b/src/sage/quadratic_forms/quadratic_form__automorphisms.py @@ -22,9 +22,7 @@ def basis_of_short_vectors(self, show_lengths=False): r""" Return a basis for `\ZZ^n` made of vectors with minimal lengths `Q(v)`. - OUTPUT: - - a tuple of vectors, and optionally a tuple of values for each vector. + OUTPUT: a tuple of vectors, and optionally a tuple of values for each vector This uses :pari:`qfminim`. @@ -105,8 +103,8 @@ def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): - ``len_bound`` -- bound for the length of the vectors - - ``up_to_sign_flag`` -- (default: ``False``) if set to True, then - only one of the vectors of the pair `[v, -v]` is listed. + - ``up_to_sign_flag`` -- boolean (default: ``False``); if set to ``True``, + then only one of the vectors of the pair `[v, -v]` is listed OUTPUT: @@ -231,7 +229,7 @@ def short_primitive_vector_list_up_to_length(self, len_bound, up_to_sign_flag=Fa This processes the PARI/GP output to always give elements of type `\ZZ`. - OUTPUT: a list of lists of vectors. + OUTPUT: list of lists of vectors EXAMPLES:: @@ -262,7 +260,7 @@ def _compute_automorphisms(self): This uses :pari:`qfauto`. - OUTPUT: None, this just caches the result. + OUTPUT: none, this just caches the result TESTS:: @@ -338,7 +336,7 @@ def automorphisms(self): """ Return the list of the automorphisms of the quadratic form. - OUTPUT: a list of matrices + OUTPUT: list of matrices EXAMPLES:: @@ -377,7 +375,7 @@ def number_of_automorphisms(self): Return the number of automorphisms (of det `1` and `-1`) of the quadratic form. - OUTPUT: an integer `\geq 2`. + OUTPUT: integer `\geq 2` EXAMPLES:: @@ -409,7 +407,7 @@ def set_number_of_automorphisms(self, num_autos): internal list of external initializations, accessible by the method :meth:`list_external_initializations`. - OUTPUT: None + OUTPUT: none EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__count_local_2.py b/src/sage/quadratic_forms/quadratic_form__count_local_2.py index b125d8d6840..3805945d0f7 100644 --- a/src/sage/quadratic_forms/quadratic_form__count_local_2.py +++ b/src/sage/quadratic_forms/quadratic_form__count_local_2.py @@ -38,8 +38,8 @@ def count_congruence_solutions_as_vector(self, p, k, m, zvec, nzvec): INPUT: - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``k`` -- integer > 0 + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers in ``range(self.dim())``, or ``None`` OUTPUT: @@ -47,7 +47,6 @@ def count_congruence_solutions_as_vector(self, p, k, m, zvec, nzvec): a list of six integers `\geq 0` representing the solution types: [All, Good, Zero, Bad, BadI, BadII] - EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,2,3]) @@ -63,7 +62,6 @@ def count_congruence_solutions_as_vector(self, p, k, m, zvec, nzvec): [6, 6, 0, 0, 0, 0] sage: Q.count_congruence_solutions_as_vector(3, 1, 0, None, None) [15, 12, 1, 2, 0, 2] - """ return CountAllLocalTypesNaive(self, p, k, m, zvec, nzvec) @@ -82,9 +80,9 @@ def count_congruence_solutions(self, p, k, m, zvec, nzvec): - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 + - ``k`` -- integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers in ``range(self.dim())``, or ``None`` @@ -107,9 +105,9 @@ def count_congruence_solutions__good_type(self, p, k, m, zvec, nzvec): - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 + - ``k`` -- integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers up to dim(`Q`) @@ -132,9 +130,9 @@ def count_congruence_solutions__zero_type(self, p, k, m, zvec, nzvec): - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 + - ``k`` -- integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers up to dim(`Q`) @@ -157,9 +155,9 @@ def count_congruence_solutions__bad_type(self, p, k, m, zvec, nzvec): - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 + - ``k`` -- integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers up to dim(`Q`) @@ -182,9 +180,9 @@ def count_congruence_solutions__bad_type_I(self, p, k, m, zvec, nzvec): - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 + - ``k`` -- integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers up to dim(`Q`) @@ -207,9 +205,9 @@ def count_congruence_solutions__bad_type_II(self, p, k, m, zvec, nzvec): - ``p`` -- prime number > 0 - - ``k`` -- an integer > 0 + - ``k`` -- integer > 0 - - ``m`` -- an integer (depending only on mod `p^k`) + - ``m`` -- integer (depending only on mod `p^k`) - ``zvec``, ``nzvec`` -- lists of integers up to dim(`Q`) diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 32f8bb62b4e..f688a08a546 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -32,7 +32,7 @@ def is_globally_equivalent_to(self, other, return_matrix=False): - ``self``, ``other`` -- positive definite integral quadratic forms - - ``return_matrix`` -- (boolean, default ``False``) return + - ``return_matrix`` -- boolean (default: ``False``); return the transformation matrix instead of a boolean OUTPUT: @@ -281,8 +281,7 @@ def has_equivalent_Jordan_decomposition_at_prime(self, other, p): # Condition (i): Check that their (unit) ratio is a square (but it suffices to check at most mod 8). modulus = norm_list[i] * norm_list[i+1] / (scale_list[i] ** 2) - if modulus > 8: - modulus = 8 + modulus = min(modulus, 8) if (modulus > 1) and (((self_chain_det_list[i] / other_chain_det_list[i]) % modulus) != 1): return False @@ -307,8 +306,9 @@ def is_rationally_isometric(self, other, return_matrix=False): - ``other`` -- a quadratic form over a number field - - ``return_matrix`` -- (boolean, default ``False``) return - the transformation matrix instead of a boolean; this is currently only implemented for forms over ``QQ`` + - ``return_matrix`` -- boolean (default: ``False``); return + the transformation matrix instead of a boolean; this is currently + only implemented for forms over ``QQ`` OUTPUT: @@ -444,7 +444,7 @@ def is_rationally_isometric(self, other, return_matrix=False): ... NotImplementedError: this only tests regular forms - Forms must have the same base ring otherwise a :class:`TypeError` is raised:: + Forms must have the same base ring otherwise a :exc:`TypeError` is raised:: sage: # needs sage.rings.number_field sage: K1. = QuadraticField(5) @@ -659,11 +659,9 @@ def _gram_schmidt(m, fixed_vector_index, inner_product): - ``fixed_vector_index`` -- any vectors preceding the vector (i.e. to its left) at this index are not changed. - ``inner_product`` -- a function that takes two vector arguments and returns a scalar, - representing an inner product. + representing an inner product - OUTPUT: - - - A matrix consisting of orthogonal columns with respect to the given inner product + OUTPUT: a matrix consisting of orthogonal columns with respect to the given inner product EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__evaluate.pyx b/src/sage/quadratic_forms/quadratic_form__evaluate.pyx index 95e82e669dc..b0c374e5381 100644 --- a/src/sage/quadratic_forms/quadratic_form__evaluate.pyx +++ b/src/sage/quadratic_forms/quadratic_form__evaluate.pyx @@ -23,7 +23,7 @@ def QFEvaluateVector(Q, v): INPUT: - ``Q`` -- :class:`QuadraticForm` over a base ring `R` - - ``v`` -- a tuple or list (or column matrix) of ``Q.dim()`` elements of `R` + - ``v`` -- tuple or list (or column matrix) of ``Q.dim()`` elements of `R` OUTPUT: an element of `R` @@ -48,7 +48,6 @@ cdef QFEvaluateVector_cdef(Q, v): r""" Routine to quickly evaluate a quadratic form `Q` on a vector `v`. See the Python wrapper function :meth:`QFEvaluate` above for details. - """ # If we are passed a matrix A, return the quadratic form Q(A(x)) # (In matrix notation: A^t * Q * A) @@ -115,7 +114,6 @@ cdef QFEvaluateMatrix_cdef(Q, M, Q2): r""" Routine to quickly evaluate a quadratic form `Q` on a matrix `M`. See the Python wrapper function :func:`QFEvaluateMatrix` above for details. - """ # Create the new quadratic form n = Q.dim() diff --git a/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py b/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py index a39637df8f0..dc9b30aa763 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py +++ b/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py @@ -13,7 +13,7 @@ from sage.arith.misc import valuation from sage.misc.verbose import verbose -from sage.quadratic_forms.count_local_2 import count_modp__by_gauss_sum +from sage.quadratic_forms.count_local_2 import count_modp__by_gauss_sum, count_all_local_good_types_normal_form def count_modp_solutions__by_Gauss_sum(self, p, m): @@ -34,9 +34,9 @@ def count_modp_solutions__by_Gauss_sum(self, p, m): - ``p`` -- a prime number > 2 - - ``m`` -- an integer + - ``m`` -- integer - OUTPUT: an integer `\geq 0` + OUTPUT: integer `\geq 0` EXAMPLES:: @@ -75,7 +75,7 @@ def local_good_density_congruence_odd(self, p, m, Zvec, NZvec): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -111,7 +111,7 @@ def local_good_density_congruence_odd(self, p, m, Zvec, NZvec): UnitVec = Set(i for i in range(n) if self[i, i] % p) NonUnitVec = Set(range(n)) - UnitVec - # Take cases on the existence of additional non-zero congruence conditions (mod p) + # Take cases on the existence of additional nonzero congruence conditions (mod p) UnitVec_minus_Zvec = list(UnitVec - Set(Zvec)) NonUnitVec_minus_Zvec = list(NonUnitVec - Set(Zvec)) Q_Unit_minus_Zvec = self.extract_variables(UnitVec_minus_Zvec) @@ -171,7 +171,7 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -210,17 +210,12 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): [ * * * 20 ] sage: Q.theta_series(20) # needs sage.libs.pari 1 + 2*q^5 + 2*q^10 + 2*q^14 + 2*q^15 + 2*q^16 + 2*q^18 + O(q^20) - sage: Q.local_normal_form(2) # needs sage.libs.pari sage.rings.padics - Quadratic form in 4 variables over Integer Ring with coefficients: - [ 0 1 0 0 ] - [ * 0 0 0 ] - [ * * 0 1 ] - [ * * * 0 ] - sage: Q.local_good_density_congruence_even(1, None, None) + sage: Q_local = Q.local_normal_form(2) # needs sage.libs.pari sage.rings.padics + sage: Q_local.local_good_density_congruence_even(1, None, None) # needs sage.libs.pari sage.rings.padics 3/4 - sage: Q.local_good_density_congruence_even(2, None, None) - 1 - sage: Q.local_good_density_congruence_even(5, None, None) + sage: Q_local.local_good_density_congruence_even(2, None, None) # needs sage.libs.pari sage.rings.padics + 9/8 + sage: Q_local.local_good_density_congruence_even(5, None, None) # needs sage.libs.pari sage.rings.padics 3/4 """ n = self.dim() @@ -237,7 +232,7 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): if (NZvec is not None) and (len(Set(NZvec) + Sn) > n): raise RuntimeError("NZvec must be a subset of {0, ..., n-1}.") - # Find the indices of x for which the associated Jordan blocks are non-zero mod 8 TODO: Move this to special Jordan block code separately! + # Find the indices of x for which the associated Jordan blocks are nonzero mod 8 TODO: Move this to special Jordan block code separately! # ------------------------------------------------------------------------------- Not8vec = [] for i in range(n): @@ -293,10 +288,10 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): verbose("Z_Is8 = " + str(Z_Is8)) verbose("Is8_minus_Z = " + str(Is8_minus_Z)) - # Take cases on the existence of additional non-zero congruence conditions (mod 2) + # Take cases on the existence of additional nonzero congruence conditions (mod 2) if NZvec is None: total = (4 ** len(Z_Is8)) * (8 ** len(Is8_minus_Z)) \ - * Q_Not8.count_congruence_solutions__good_type(2, 3, m, list(Z_Not8), None) + * count_all_local_good_types_normal_form(Q_Not8,2, 3, m, list(Z_Not8), None) else: ZNZ = Z + Set(NZvec) ZNZ_Not8 = Not8.intersection(ZNZ) @@ -310,9 +305,9 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): verbose("Is8_minus_ZNZ = " + str(Is8_minus_ZNZ)) total = (4 ** len(Z_Is8)) * (8 ** len(Is8_minus_Z)) \ - * Q_Not8.count_congruence_solutions__good_type(2, 3, m, list(Z_Not8), None) \ + * count_all_local_good_types_normal_form(Q_Not8, 2, 3, m, list(Z_Not8), None) \ - (4 ** len(ZNZ_Is8)) * (8 ** len(Is8_minus_ZNZ)) \ - * Q_Not8.count_congruence_solutions__good_type(2, 3, m, list(ZNZ_Not8), None) + * count_all_local_good_types_normal_form(Q_Not8, 2, 3, m, list(ZNZ_Not8), None) # DIAGNOSTIC verbose("total = " + str(total)) @@ -337,7 +332,7 @@ def local_good_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -358,7 +353,6 @@ def local_good_density_congruence(self, p, m, Zvec=None, NZvec=None): 1 sage: Q.local_good_density_congruence(3, 1, None, None) 8/9 - """ # DIAGNOSTIC verbose(" In local_good_density_congruence with ") @@ -408,7 +402,7 @@ def local_zero_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -481,7 +475,7 @@ def local_badI_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -560,7 +554,7 @@ def local_badI_density_congruence(self, p, m, Zvec=None, NZvec=None): S0 = [] S1_empty_flag = True # This is used to check if we should be computing BI solutions at all! - # (We should really to this earlier, but S1 must be non-zero to proceed.) + # (We should really to this earlier, but S1 must be nonzero to proceed.) # Find the valuation of each variable (which will be the same over 2x2 blocks), # remembering those of valuation 0 and if an entry of valuation 1 exists. @@ -644,7 +638,7 @@ def local_badII_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -790,7 +784,7 @@ def local_bad_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -848,7 +842,7 @@ def local_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` @@ -920,7 +914,7 @@ def local_primitive_density_congruence(self, p, m, Zvec=None, NZvec=None): - ``p`` -- a prime number - - ``m`` -- an integer + - ``m`` -- integer - ``Zvec``, ``NZvec`` -- non-repeating lists of integers in ``range(self.dim())`` or ``None`` diff --git a/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py b/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py index 2e5be4f59de..2643620e712 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py +++ b/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py @@ -21,7 +21,7 @@ def local_density(self, p, m): INPUT: - ``p`` -- a prime number > 0 - - ``m`` -- an integer + - ``m`` -- integer OUTPUT: a rational number @@ -67,7 +67,7 @@ def local_density(self, p, m): def local_primitive_density(self, p, m): """ - Return the local primitive density -- should be called by the user. =) + Return the local primitive density -- should be called by the user. NOTE: This screens for imprimitive forms, and puts the quadratic form in local normal form, which is a *requirement* of @@ -76,7 +76,7 @@ def local_primitive_density(self, p, m): INPUT: - ``p`` -- a prime number > 0 - - ``m`` -- an integer + - ``m`` -- integer OUTPUT: a rational number diff --git a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py index b9a8758be1d..aa2478af088 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py +++ b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py @@ -1,7 +1,7 @@ """ Local Field Invariants -This contains routines to compute local (p-adic) invariants of +This contains routines to compute local (`p`-adic) invariants of quadratic forms over the rationals. """ @@ -17,7 +17,7 @@ # **************************************************************************** ########################################################################### -# TO DO: Add routines for hasse invariants at all places, anisotropic +# TO DO: Add routines for Hasse invariants at all places, anisotropic # places, is_semi_definite, and support for number fields. ########################################################################### @@ -37,16 +37,16 @@ def rational_diagonal_form(self, return_matrix=False): INPUT: - - ``return_matrix`` -- (boolean, default: ``False``) also return the + - ``return_matrix`` -- boolean (default: ``False``); also return the transformation matrix OUTPUT: either the diagonal quadratic form `D` (if ``return_matrix`` is false) or the pair `(D, T)` (if ``return_matrix`` is true) where - - `D` -- the diagonalized form of this quadratic form + - ``D`` -- the diagonalized form of this quadratic form - - `T` -- transformation matrix. This is such that - ``T.transpose() * self.matrix() * T`` gives ``D.matrix()``. + - ``T`` -- transformation matrix. This is such that + ``T.transpose() * self.matrix() * T`` gives ``D.matrix()`` Both `D` and `T` are defined over the fraction field of the base ring of the given form. @@ -165,7 +165,19 @@ def rational_diagonal_form(self, return_matrix=False): sage: T[0,0] = 13 Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). + + Test for a singular form:: + + sage: m = matrix(GF(11), [[1,5,0,0], [5,1,9,0], [0,9,1,5], [0,0,5,1]]) + sage: qf = QuadraticForm(m) + sage: Q, T = qf.rational_diagonal_form(return_matrix=True) + sage: T + [ 1 6 5 10] + [ 0 1 10 9] + [ 0 0 1 2] + [ 0 0 0 1] """ Q, T = self._rational_diagonal_form_and_transformation() T.set_immutable() @@ -173,26 +185,24 @@ def rational_diagonal_form(self, return_matrix=False): # Quadratic forms do not support immutability, so we need to make # a copy to be safe. Q = deepcopy(Q) - - if return_matrix: - return Q, T - else: - return Q + return (Q, T) if return_matrix else Q @cached_method def _rational_diagonal_form_and_transformation(self): """ Return a diagonal form equivalent to the given quadratic from and - the corresponding transformation matrix. This is over the fraction - field of the base ring of the given quadratic form. + the corresponding transformation matrix. + + This is over the fraction field of the base ring of the given + quadratic form. OUTPUT: a tuple `(D,T)` where - - `D` -- the diagonalized form of this quadratic form + - ``D`` -- the diagonalized form of this quadratic form - - `T` -- transformation matrix. This is such that - ``T.transpose() * self.matrix() * T`` gives ``D.matrix()``. + - ``T`` -- transformation matrix. This is such that + ``T.transpose() * self.matrix() * T`` gives ``D.matrix()`` Both `D` and `T` are defined over the fraction field of the base ring of the given form. @@ -238,13 +248,13 @@ def _rational_diagonal_form_and_transformation(self): D = MS() for i in range(n): D[i, i] = R[i, i] - Q = Q.parent()(D) + newQ = Q.parent()(D) # Transformation matrix (inverted) T = MS(R.sage()) for i in range(n): T[i, i] = K.one() try: - return Q, ~T + return newQ, ~T except ZeroDivisionError: # Singular case is not fully supported by PARI pass @@ -258,7 +268,7 @@ def _rational_diagonal_form_and_transformation(self): # Deal with rows where the diagonal entry is zero. if Q[i, i] == 0: - # Look for a non-zero entry and use it to make the diagonal non-zero (if it exists) + # Look for a nonzero entry and use it to make the diagonal nonzero (if it exists) for j in range(i + 1, n): if Q[i, j] != 0: temp = MS(1) @@ -276,7 +286,8 @@ def _rational_diagonal_form_and_transformation(self): temp = MS(1) for j in range(i + 1, n): if Q[i, j] != 0: - temp[i, j] = -Q[i, j] / (Q[i, i] * 2) # This should only occur when Q[i,i] != 0, which the above step guarantees. + temp[i, j] = -Q[i, j] / (Q[i, i] * 2) + # This should only occur when Q[i,i] != 0, which the above step guarantees. Q = Q(temp) T = T * temp @@ -318,7 +329,6 @@ def signature_vector(self): [ * * * 9 ] sage: Q.signature_vector() (3, 1, 0) - """ diag = self.rational_diagonal_form() p = 0 @@ -343,7 +353,7 @@ def signature(self): of the matrix of the quadratic form. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -677,7 +687,7 @@ def is_anisotropic(self, p): def is_isotropic(self, p): r""" - Checks if `Q` is isotropic over the `p`-adic numbers `\QQ_p` or `\RR`. + Check if `Q` is isotropic over the `p`-adic numbers `\QQ_p` or `\RR`. INPUT: @@ -718,7 +728,6 @@ def is_isotropic(self, p): ....: p, -p*least_quadratic_nonresidue(p)]).is_isotropic(p) ....: for p in prime_range(3, 30)] [False, False, False, False, False, False, False, False, False] - """ return not self.is_anisotropic(p) @@ -763,7 +772,7 @@ def compute_definiteness(self): A degenerate form is considered neither definite nor indefinite. - .. NOTE: + .. NOTE:: The zero-dimensional form is considered both positive definite and negative definite. @@ -807,7 +816,6 @@ def compute_definiteness(self): False sage: Q.is_definite() False - """ # Sanity Check from sage.rings.real_mpfr import RR @@ -928,7 +936,7 @@ def is_positive_definite(self): The zero-dimensional form is considered both positive definite and negative definite. - OUTPUT: boolean -- True or False + OUTPUT: boolean EXAMPLES:: @@ -965,7 +973,7 @@ def is_negative_definite(self): The zero-dimensional form is considered both positive definite and negative definite. - OUTPUT: boolean -- True or False + OUTPUT: boolean EXAMPLES:: @@ -1002,7 +1010,7 @@ def is_indefinite(self): The zero-dimensional form is not considered indefinite. - OUTPUT: boolean -- True or False + OUTPUT: boolean EXAMPLES:: @@ -1015,7 +1023,6 @@ def is_indefinite(self): sage: Q = DiagonalQuadraticForm(ZZ, [1,-3,5]) sage: Q.is_indefinite() True - """ # Try to use the cached value try: @@ -1040,7 +1047,7 @@ def is_definite(self): The zero-dimensional form is considered indefinite. - OUTPUT: boolean -- True or False + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__local_normal_form.py b/src/sage/quadratic_forms/quadratic_form__local_normal_form.py index 5770a3c22f0..f70ce4f2bb3 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_normal_form.py +++ b/src/sage/quadratic_forms/quadratic_form__local_normal_form.py @@ -143,7 +143,7 @@ def local_normal_form(self, p): else: min_val = valuation(Q[min_i, min_j], p) - # Error if we still haven't seen non-zero coefficients! + # Error if we still haven't seen nonzero coefficients! if min_val == Infinity: raise RuntimeError("the original matrix is degenerate") @@ -261,7 +261,7 @@ def jordan_blocks_by_scale_and_unimodular(self, p, safe_flag=True): - `s_i` is an integer, - `L_i` is a block-diagonal unimodular quadratic form over `\ZZ_p`. - .. note:: + .. NOTE:: These forms `L_i` are defined over the `p`-adic integers, but by a matrix over `\ZZ` (or `\QQ`?). @@ -368,7 +368,7 @@ def jordan_blocks_in_unimodular_list_by_scale_power(self, p): - ``self`` -- a quadratic form over `\ZZ`, which has integer Gram matrix if `p = 2` - ``p`` -- a prime number > 0 - OUTPUT: a list of `p`-unimodular quadratic forms + OUTPUT: list of `p`-unimodular quadratic forms EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py index c337d2994a0..4cc9f18c152 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py +++ b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py @@ -96,7 +96,7 @@ class QuadraticFormLocalRepresentationConditions: """ def __init__(self, Q): r""" - Takes a :class:`QuadraticForm` and computes its local conditions (if + Take a :class:`QuadraticForm` and computes its local conditions (if they do not already exist). The ``recompute_flag`` overrides the previously computed conditions if they exist, and stores the new conditions. @@ -105,9 +105,7 @@ def __init__(self, Q): - ``Q`` -- Quadratic form over `\ZZ` - OUTPUT: - - a :class:`QuadraticFormLocalRepresentationConditions` object + OUTPUT: a :class:`QuadraticFormLocalRepresentationConditions` object EXAMPLES:: @@ -124,7 +122,7 @@ def __init__(self, Q): # Basic structure initialization self.local_repn_array = [] # List of all local conditions - self.dim = Q.dim() # We allow this to be any non-negative integer. + self.dim = Q.dim() # We allow this to be any nonnegative integer. self.exceptional_primes = [infinity] # Deal with the special cases of 0 and 1-dimensional forms @@ -293,7 +291,7 @@ def squareclass_vector(self, p) -> list: - ``p`` -- a positive prime number or "infinity" - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -318,7 +316,7 @@ def local_conditions_vector_for_prime(self, p) -> list: - ``p`` -- a positive prime number. (Is 'infinity' allowed here?) - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -362,7 +360,7 @@ def local_conditions_vector_for_prime(self, p) -> list: return [2, infinity, infinity, infinity, infinity, infinity, infinity, infinity, infinity] return [p, infinity, infinity, infinity, infinity, None, None, None, None] - raise RuntimeError("the stored dimension should be a non-negative integer") + raise RuntimeError("the stored dimension should be a nonnegative integer") def is_universal_at_prime(self, p) -> bool: r""" @@ -487,7 +485,7 @@ def is_locally_represented_at_place(self, m, p) -> bool: INPUT: - - ``m`` -- an integer + - ``m`` -- integer - ``p`` -- a positive prime number or "infinity" @@ -556,7 +554,7 @@ def is_locally_represented(self, m) -> bool: INPUT: - - ``m`` -- an integer + - ``m`` -- integer OUTPUT: boolean @@ -823,7 +821,7 @@ def is_locally_represented_number_at_place(self, m, p) -> bool: INPUT: - - ``m`` -- an integer + - ``m`` -- integer - ``p`` -- a prime number > 0 or 'infinity' @@ -868,7 +866,7 @@ def is_locally_represented_number(self, m) -> bool: INPUT: - - ``m`` -- an integer + - ``m`` -- integer OUTPUT: boolean diff --git a/src/sage/quadratic_forms/quadratic_form__mass.py b/src/sage/quadratic_forms/quadratic_form__mass.py index 67bf06d888a..96aa23610cd 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass.py +++ b/src/sage/quadratic_forms/quadratic_form__mass.py @@ -38,9 +38,7 @@ def shimura_mass__maximal(self): quadratic lattice. This works for any totally real number field, but has a small technical restriction when `n` is odd. - OUTPUT: - - a rational number + OUTPUT: a rational number EXAMPLES:: @@ -59,9 +57,7 @@ def GHY_mass__maximal(self): See [GHY, Prop 7.4 and 7.5, p121] and [GY, Thrm 10.20, p25]. - OUTPUT: - - a rational number + OUTPUT: a rational number EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py index 894ee68cec9..89460d08713 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py @@ -31,11 +31,9 @@ def parity(self, allow_rescaling_flag=True): INPUT: - ``self`` -- a quadratic form with base ring `\ZZ`, which we may - require to have integer Gram matrix. + require to have integer Gram matrix - OUTPUT: - - One of the strings: "even" or "odd" + OUTPUT: one of the strings: ``'even'`` or ``'odd'`` EXAMPLES:: @@ -143,7 +141,6 @@ def is_odd(self, allow_rescaling_flag=True): sage: Q = QuadraticForm(ZZ, 2, [1, 1, 1]) sage: Q.is_odd() False - """ return self.parity(allow_rescaling_flag) == "odd" @@ -158,7 +155,7 @@ def conway_species_list_at_odd_prime(self, p): number is always positive, otherwise it may be positive or negative (or zero, but that is considered positive by convention). - .. NOTE: + .. NOTE:: The species of a zero dimensional form is always 0+, so we interpret the return value of zero as positive here! =) @@ -167,7 +164,7 @@ def conway_species_list_at_odd_prime(self, p): - ``p`` -- a positive prime number - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -182,7 +179,6 @@ def conway_species_list_at_odd_prime(self, p): [5, 2] sage: Q.conway_species_list_at_odd_prime(5) [-6, 1] - """ # Sanity Check: if not (p > 2 and is_prime(p)): @@ -233,7 +229,7 @@ def conway_species_list_at_2(self): The species of a zero dimensional form is always 0+, so we interpret the return value of zero as positive here! =) - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -246,7 +242,6 @@ def conway_species_list_at_2(self): sage: Q = DiagonalQuadraticForm(ZZ, range(1,8)) sage: Q.conway_species_list_at_2() [1, 3, 1, 1, 1] - """ # Some useful variables n = self.dim() @@ -312,7 +307,7 @@ def conway_octane_of_this_unimodular_Jordan_block_at_2(self): unimodular blocks of size `\leq 2` and the `1 \times 1` blocks are all in the upper leftmost position. - OUTPUT: an integer `0 \leq x \leq 7` + OUTPUT: integer `0 \leq x \leq 7` EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py index 9133a84b76f..e1b7c897032 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py @@ -23,7 +23,7 @@ from sage.rings.rational_field import QQ -def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson"): +def mass__by_Siegel_densities(self, odd_algorithm='Pall', even_algorithm='Watson'): """ Return the mass of transformations (det 1 and -1). @@ -33,9 +33,10 @@ def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson INPUT: - - ``odd_algorithm`` -- algorithm to be used when `p>2`; ``"Pall"`` (only one choice for now) - - ``even_algorithm`` -- algorithm to be used when `p=2`; - either ``"Kitaoka"`` or ``"Watson"`` (the default) + - ``odd_algorithm`` -- algorithm to be used when `p>2`; ``'Pall'`` (only + one choice for now) + - ``even_algorithm`` -- algorithm to be used when `p=2`; either + ``'Kitaoka'`` or ``'Watson'`` (the default) REFERENCES: @@ -126,7 +127,7 @@ def Pall_mass_density_at_odd_prime(self, p): - ``p`` -- a prime number > 2 - OUTPUT: a rational number. + OUTPUT: a rational number EXAMPLES:: @@ -267,7 +268,6 @@ def Kitaoka_mass_at_2(self): sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.Kitaoka_mass_at_2() # WARNING: WE NEED TO CHECK THIS CAREFULLY! 1/2 - """ # Make a 0-dim'l quadratic form (for initialization purposes) Null_Form = deepcopy(self) @@ -352,7 +352,7 @@ def mass_at_two_by_counting_mod_power(self, k): INPUT: - - ``k`` -- an integer `\geq 1` + - ``k`` -- integer `\geq 1` OUTPUT: a rational number diff --git a/src/sage/quadratic_forms/quadratic_form__neighbors.py b/src/sage/quadratic_forms/quadratic_form__neighbors.py index 25566313812..d4d579409d3 100644 --- a/src/sage/quadratic_forms/quadratic_form__neighbors.py +++ b/src/sage/quadratic_forms/quadratic_form__neighbors.py @@ -18,7 +18,7 @@ def find_primitive_p_divisible_vector__random(self, p): """ Find a random `p`-primitive vector in `L/pL` whose value is `p`-divisible. - .. note:: + .. NOTE:: Since there are about `p^{(n-2)}` of these lines, we have a `1/p` chance of randomly finding an appropriate vector. @@ -59,7 +59,7 @@ def find_primitive_p_divisible_vector__next(self, p, v=None): value is `p`-divisible, where the last vector returned was `v`. For an initial call, no `v` needs to be passed. - Return vectors whose last non-zero entry is normalized to 0 or 1 (so no + Return vectors whose last nonzero entry is normalized to 0 or 1 (so no lines are counted repeatedly). The ordering is by increasing the first non-normalized entry. If we have tested all (lines of) vectors, then return None. @@ -97,12 +97,12 @@ def find_primitive_p_divisible_vector__next(self, p, v=None): if n <= 1: raise NotImplementedError("Sorry -- Not implemented yet!") - # Look for the last non-zero entry (which must be 1) + # Look for the last nonzero entry (which must be 1) nz = n - 1 while w[nz] == 0: nz += -1 - # Test that the last non-zero entry is 1 (to detect tampering). + # Test that the last nonzero entry is 1 (to detect tampering). if w[nz] != 1: print("Warning: The input vector to QuadraticForm.find_primitive_p_divisible_vector__next() is not normalized properly.") @@ -124,7 +124,7 @@ def find_primitive_p_divisible_vector__next(self, p, v=None): w[j] = 0 if nz != 0: - # Move the non-zero normalized index over by one, or + # Move the nonzero normalized index over by one, or # return the zero vector w[nz - 1] = 1 nz += -1 @@ -153,8 +153,8 @@ def find_p_neighbor_from_vec(self, p, y, return_matrix=False): - ``p`` -- a prime number - ``y`` -- a vector with `q(y) \in p \ZZ` - - ``odd`` -- (default: ``False``) if `p=2`, return also odd neighbors - - ``return_matrix`` -- (boolean, default ``False``) return + - ``odd`` -- boolean (default: ``False``); if `p=2`, return also odd neighbors + - ``return_matrix`` -- boolean (default: ``False``); return the transformation matrix instead of the quadratic form EXAMPLES:: @@ -259,7 +259,7 @@ def neighbor_iteration(seeds, p, mass=None, max_classes=None, INPUT: - - ``seeds`` -- a list of quadratic forms in the same genus + - ``seeds`` -- list of quadratic forms in the same genus - ``p`` -- a prime number @@ -272,7 +272,7 @@ def neighbor_iteration(seeds, p, mass=None, max_classes=None, - ``max_random_trys`` -- (default: ``1000``) the maximum number of neighbors computed for a single lattice - OUTPUT: a list of quadratic forms + OUTPUT: list of quadratic forms EXAMPLES:: @@ -386,7 +386,7 @@ def orbits_lines_mod_p(self, p): - ``p`` -- a prime number - OUTPUT: a list of vectors over ``GF(p)`` + OUTPUT: list of vectors over ``GF(p)`` EXAMPLES:: diff --git a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py index 4db788e5e44..14c7bdfb279 100644 --- a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py +++ b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py @@ -36,9 +36,9 @@ def cholesky_decomposition(self, bit_prec=53): INPUT: - - ``bit_prec`` -- a natural number (default 53) + - ``bit_prec`` -- a natural number (default: 53) - OUTPUT: an upper triangular real matrix of precision ``bit_prec``. + OUTPUT: an upper triangular real matrix of precision ``bit_prec`` .. TODO:: @@ -46,7 +46,7 @@ def cholesky_decomposition(self, bit_prec=53): If we only care about working over the real double field (``RDF``), then we can use the method :meth:`cholesky` present for square matrices over that. - .. note:: + .. NOTE:: There is a note in the original code reading @@ -55,7 +55,6 @@ def cholesky_decomposition(self, bit_prec=53): Finds the Cholesky decomposition of a quadratic form -- as an upper-triangular matrix! (It's assumed to be global, hence twice the form it refers to.) <-- Python revision asks: Is this true?!? =| - EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) @@ -118,7 +117,7 @@ def vectors_by_length(self, bound): INPUT: - - ``bound`` -- an integer `\geq 0` + - ``bound`` -- integer `\geq 0` OUTPUT: @@ -278,7 +277,7 @@ def complementary_subform_to_vector(self, v): INPUT: - - ``v`` -- a list of ``self.dim()`` integers + - ``v`` -- list of ``self.dim()`` integers OUTPUT: a :class:`QuadraticForm` over `\ZZ` @@ -312,7 +311,7 @@ def complementary_subform_to_vector(self, v): # Copy the quadratic form Q = deepcopy(self) - # Find the first non-zero component of v, and call it nz (Note: 0 <= nz < n) + # Find the first nonzero component of v, and call it nz (Note: 0 <= nz < n) nz = 0 while nz < n and v[nz] == 0: nz += 1 @@ -356,7 +355,7 @@ def complementary_subform_to_vector(self, v): def split_local_cover(self): r""" - Tries to find subform of the given (positive definite quaternary) + Try to find subform of the given (positive definite quaternary) quadratic form `Q` of the form .. MATH:: diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index cc7a6549312..0e447f982dd 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -53,7 +53,6 @@ def disc(self): 4 sage: DiagonalQuadraticForm(ZZ, [1,1,1,1]).disc() 16 - """ if is_odd(self.dim()): # This is not so good for characteristic 2. @@ -129,7 +128,6 @@ def adjoint(self): [ 39 2 8 ] [ * 19 4 ] [ * * 8 ] - """ from sage.quadratic_forms.quadratic_form import QuadraticForm as QuadraticForm diff --git a/src/sage/quadratic_forms/quadratic_form__theta.py b/src/sage/quadratic_forms/quadratic_form__theta.py index c4f0606df4c..12cffc8fbc1 100644 --- a/src/sage/quadratic_forms/quadratic_form__theta.py +++ b/src/sage/quadratic_forms/quadratic_form__theta.py @@ -50,7 +50,6 @@ def theta_series(self, Max=10, var_str='q', safe_flag=True): 1 + 2*q + 2*q^3 + 6*q^4 + 2*q^5 + 4*q^6 + 6*q^7 + 8*q^8 + 14*q^9 + 4*q^10 + 12*q^11 + 18*q^12 + 12*q^13 + 12*q^14 + 8*q^15 + 34*q^16 + 12*q^17 + 8*q^18 + 32*q^19 + 10*q^20 + 28*q^21 + 16*q^23 + 44*q^24 + O(q^25) - """ # Sanity Check: Max is an integer or an allowed string: try: @@ -83,14 +82,14 @@ def theta_by_pari(self, Max, var_str='q', safe_flag=True): output, or the original output. It is only meaningful when a vector is returned, otherwise a copy is automatically made in creating the power series. By default ``safe_flag=True``, so we - return a copy of the cached information. If this is set to False, + return a copy of the cached information. If this is set to ``False``, then the routine is much faster but the return values are vulnerable to being corrupted by the user. INPUT: - - ``Max`` -- an integer `\geq 0` - - ``var_str`` -- a string + - ``Max`` -- integer `\geq 0` + - ``var_str`` -- string OUTPUT: a power series or a vector @@ -103,7 +102,6 @@ def theta_by_pari(self, Max, var_str='q', safe_flag=True): ....: for i in range(1, Prec)] sage: compute == exact # needs sage.libs.pari True - """ # Try to use the cached result if it's enough precision if hasattr(self, '__theta_vec') and len(self.__theta_vec) >= Max: @@ -114,7 +112,7 @@ def theta_by_pari(self, Max, var_str='q', safe_flag=True): self.__theta_vec = theta_vec # Return the answer - if var_str == '': + if not var_str: if safe_flag: return deepcopy(theta_vec) # We must make a copy here to insure the integrity of the cached version! else: @@ -123,16 +121,16 @@ def theta_by_pari(self, Max, var_str='q', safe_flag=True): return PowerSeriesRing(ZZ, var_str)(theta_vec, Max) -# ------------- Compute the theta function by using an explicit Cholesky decomposition ------------ +# -- Compute the theta function by using an explicit Cholesky decomposition -- -########################################################################## -# Routines to compute the Fourier expansion of the theta function of Q ## -# (to a given precision) via a Cholesky decomposition over RR. ## -# ## -# The Cholesky code was taken from: ## -# ~/Documents/290_Project/C/Ver13.2__3-5-2007/Matrix_mpz/Matrix_mpz.cc ## -########################################################################## +######################################################################## +# Routines to compute the Fourier expansion of the theta function of Q # +# (to a given precision) via a Cholesky decomposition over RR. # +# # +# The Cholesky code was taken from: # +# ~/Documents/290_Project/C/Ver13.2__3-5-2007/Matrix_mpz/Matrix_mpz.cc # +######################################################################## def theta_by_cholesky(self, q_prec): @@ -146,24 +144,24 @@ def theta_by_cholesky(self, q_prec): Cohen's "A Course in Computational Algebraic Number Theory" book, p 102. - EXAMPLES:: + EXAMPLES: + + Check the sum of 4 squares form against Jacobi's formula:: - # Check the sum of 4 squares form against Jacobi's formula sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: Theta = Q.theta_by_cholesky(10) sage: Theta 1 + 8*q + 24*q^2 + 32*q^3 + 24*q^4 + 48*q^5 + 96*q^6 + 64*q^7 + 24*q^8 + 104*q^9 + 144*q^10 - sage: Expected = [1] + [8*sum([d for d in divisors(n) if d%4 != 0]) + sage: Expected = [1] + [8*sum(d for d in divisors(n) if d%4) ....: for n in range(1, 11)] sage: Expected [1, 8, 24, 32, 24, 48, 96, 64, 24, 104, 144] sage: Theta.list() == Expected True - :: + Check the form `x^2 + 3y^2 + 5z^2 + 7w^2` represents everything except 2 and 22.:: - # Check the form x^2 + 3y^2 + 5z^2 + 7w^2 represents everything except 2 and 22. sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7]) sage: Theta = Q.theta_by_cholesky(50) sage: Theta_list = Theta.list() @@ -178,10 +176,10 @@ def theta_by_cholesky(self, q_prec): from sage.rings.real_mpfr import RealField n = self.dim() - theta = [0 for i in range(q_prec + 1)] + theta = [0] * (q_prec + 1) PS = PowerSeriesRing(ZZ, 'q') - bit_prec = 53 # TO DO: Set this precision to reflect the appropriate roundoff + bit_prec = 53 # TO DO: Set this precision to reflect the appropriate roundoff Cholesky = self.cholesky_decomposition(bit_prec) # error estimate, to be confident through our desired q-precision. Q = Cholesky # <---- REDUNDANT!!! R = RealField(bit_prec) @@ -189,8 +187,8 @@ def theta_by_cholesky(self, q_prec): # 1. Initialize i = n - 1 - T = [R(0) for j in range(n)] - U = [R(0) for j in range(n)] + T = [R.zero()] * n + U = [R.zero()] * n T[i] = R(q_prec) U[i] = 0 L = [0] * n @@ -253,10 +251,7 @@ def theta_by_cholesky(self, q_prec): theta[Q_val] += 2 # 5. Check if x = 0, for exit condition. =) - done_flag = True - for j in range(n): - if x[j] != 0: - done_flag = False + done_flag = all(x[j] == 0 for j in range(n)) # Set the value: theta[0] = 1 theta[0] = 1 @@ -265,17 +260,15 @@ def theta_by_cholesky(self, q_prec): return PS(theta) -def theta_series_degree_2(Q, prec): +def theta_series_degree_2(Q, prec) -> dict: r""" Compute the theta series of degree 2 for the quadratic form `Q`. INPUT: - - ``prec`` -- an integer - - OUTPUT: + - ``prec`` -- integer - dictionary, where: + OUTPUT: dictionary, where: - keys are `{\rm GL}_2(\ZZ)`-reduced binary quadratic forms (given as triples of coefficients) @@ -326,14 +319,14 @@ def theta_series_degree_2(Q, prec): H = Q.Hessian_matrix() t = cputime() - max = (X + 1) // 4 - v_list = (Q.vectors_by_length(max)) # assume a>0 - v_list = [[V(_) for _ in vs] for vs in v_list] # coerce vectors into V + maxi = (X + 1) // 4 + v_list = (Q.vectors_by_length(maxi)) # assume a>0 + v_list = [[V(c) for c in vs] for vs in v_list] # coerce vectors into V verbose("Computed vectors_by_length", t) # Deal with the singular part coeffs = {(0, 0, 0): ZZ.one()} - for i in range(1, max + 1): + for i in range(1, maxi + 1): coeffs[(0, 0, i)] = ZZ(2) * len(v_list[i]) # Now deal with the non-singular part diff --git a/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py b/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py index aa72053793b..ba3b26bacaa 100644 --- a/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py +++ b/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py @@ -84,7 +84,7 @@ def multiply_variable(self, c, i, in_place=False): - ``c`` -- an element of ``self.base_ring()`` - - ``i`` -- an integer `\geq 0` + - ``i`` -- integer `\geq 0` OUTPUT: a :class:`QuadraticForm` (by default, otherwise none) @@ -127,7 +127,7 @@ def divide_variable(self, c, i, in_place=False): - ``c`` -- an element of ``self.base_ring()`` - - ``i`` -- an integer `\geq 0` + - ``i`` -- integer `\geq 0` OUTPUT: @@ -218,7 +218,7 @@ def extract_variables(QF, var_indices): INPUT: - - ``var_indices`` -- a list of integers `\geq 0` + - ``var_indices`` -- list of integers `\geq 0` OUTPUT: a :class:`QuadraticForm` diff --git a/src/sage/quadratic_forms/random_quadraticform.py b/src/sage/quadratic_forms/random_quadraticform.py index 0d751e1f584..fb36812bcbd 100644 --- a/src/sage/quadratic_forms/random_quadraticform.py +++ b/src/sage/quadratic_forms/random_quadraticform.py @@ -24,11 +24,11 @@ def random_quadraticform(R, n, rand_arg_list=None): INPUT: - ``R`` -- a ring - - ``n`` -- an integer `\ge 0` - - ``rand_arg_list`` -- a list of at most 3 arguments which can be taken by - ``R.random_element()``. + - ``n`` -- integer `\ge 0` + - ``rand_arg_list`` -- list of at most 3 arguments which can be taken by + ``R.random_element()`` - OUTPUT: A quadratic form over the ring `R`. + OUTPUT: a quadratic form over the ring `R` EXAMPLES:: @@ -134,10 +134,10 @@ def random_ternaryqf(rand_arg_list=None): INPUT: - - ``rand_arg_list`` -- a list of at most 3 arguments which can be taken by - ``R.random_element()``. + - ``rand_arg_list`` -- list of at most 3 arguments which can be taken by + ``R.random_element()`` - OUTPUT: A ternary quadratic form. + OUTPUT: a ternary quadratic form EXAMPLES:: diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index 2ee775e053d..0b865877525 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -1,10 +1,10 @@ r""" Routines for computing special values of `L`-functions -- :func:`gamma__exact` -- Exact values of the `\Gamma` function at integers and half-integers -- :func:`zeta__exact` -- Exact values of the Riemann `\zeta` function at critical values -- :func:`quadratic_L_function__exact` -- Exact values of the Dirichlet L-functions of quadratic characters at critical values -- :func:`quadratic_L_function__numerical` -- Numerical values of the Dirichlet L-functions of quadratic characters in the domain of convergence +- :func:`gamma__exact` -- exact values of the `\Gamma` function at integers and half-integers +- :func:`zeta__exact` -- exact values of the Riemann `\zeta` function at critical values +- :func:`quadratic_L_function__exact` -- exact values of the Dirichlet `L`-functions of quadratic characters at critical values +- :func:`quadratic_L_function__numerical` -- numerical values of the Dirichlet `L`-functions of quadratic characters in the domain of convergence """ import sage.rings.abc @@ -96,7 +96,7 @@ def gamma__exact(n): def zeta__exact(n): r""" - Return the exact value of the Riemann Zeta function + Return the exact value of the Riemann Zeta function. The argument must be a critical value, namely either positive even or negative odd. @@ -268,7 +268,7 @@ def quadratic_L_function__exact(n, d): def quadratic_L_function__numerical(n, d, num_terms=1000): """ - Evaluate the Dirichlet L-function (for quadratic character) numerically + Evaluate the Dirichlet `L`-function (for quadratic character) numerically (in a very naive way). EXAMPLES: diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index 4ed6d76ed3d..345d6b962b3 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -27,7 +27,7 @@ def red_mfact(a, b): - ``a``, ``b`` -- integers - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -594,7 +594,6 @@ def _find_zeros_mod_p_odd(long long a, long long b, long long c, long long r, lo (0, 32, 1) sage: Q((0, 32, 1)) 2018 - """ cdef long long a_i diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index 5debc32e846..79436ff4f77 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -52,11 +52,9 @@ class TernaryQF(SageObject): INPUT: - - ``v`` -- a list or tuple of 6 entries: ``[a,b,c,r,s,t]`` + - ``v`` -- list or tuple of 6 entries: ``[a,b,c,r,s,t]`` - OUTPUT: - - - the ternary quadratic form `a\cdot x^2 + b\cdot y^2 + c\cdot z^2 + r\cdot y\cdot z + s\cdot x\cdot z + t\cdot x\cdot y`. + OUTPUT: the ternary quadratic form `a\cdot x^2 + b\cdot y^2 + c\cdot z^2 + r\cdot y\cdot z + s\cdot x\cdot z + t\cdot x\cdot y` EXAMPLES:: @@ -117,7 +115,7 @@ def coefficients(self): def __hash__(self): """ - Returns a hash for self. + Return a hash for ``self``. EXAMPLES:: @@ -135,7 +133,7 @@ def coefficient(self, n): INPUT: - - ``n`` -- integer with `0 \leq n \leq 5`. + - ``n`` -- integer with `0 \leq n \leq 5` EXAMPLES:: @@ -426,7 +424,7 @@ def is_negative_definite(self) -> bool: def __neg__(self): """ - Return the ternary quadratic form with coefficients negatives of self. + Return the ternary quadratic form with coefficients negatives of ``self``. EXAMPLES:: @@ -951,7 +949,6 @@ def find_p_neighbors(self, p, mat=False): 1 sage: neig.count(Q2) 3 - """ z = self.find_zeros_mod_p(p) @@ -1309,8 +1306,6 @@ def _automorphisms_reduced_fast(self): sage: Q = TernaryQF([3, 4, 5, 3, 3, 2]) sage: Q._automorphisms_reduced_fast() [(1, 0, 0, 0, 1, 0, 0, 0, 1)] - - """ if self._border(1): diff --git a/src/sage/quivers/algebra.py b/src/sage/quivers/algebra.py index 90def69304a..9e867cadc7c 100644 --- a/src/sage/quivers/algebra.py +++ b/src/sage/quivers/algebra.py @@ -41,13 +41,11 @@ class PathAlgebra(CombinatorialFreeModule): - ``P`` -- the path semigroup of a quiver `Q` - - ``order`` -- optional string, one of "negdegrevlex" (default), - "degrevlex", "negdeglex" or "deglex", defining the monomial order to be - used. + - ``order`` -- string; one of ``'negdegrevlex'`` (default), + ``'degrevlex'``, ``'negdeglex'`` or ``'deglex'``, defining the monomial + order to be used - OUTPUT: - - - the path algebra `kP` with the given monomial order + OUTPUT: the path algebra `kP` with the given monomial order .. NOTE:: @@ -67,7 +65,7 @@ class PathAlgebra(CombinatorialFreeModule): sage: A is P.algebra(GF(7)) True - sage: A is P.algebra(GF(7), order="degrevlex") + sage: A is P.algebra(GF(7), order='degrevlex') False sage: A is P.algebra(RR) False @@ -132,7 +130,7 @@ class PathAlgebra(CombinatorialFreeModule): # # ########################################################################### - def __init__(self, k, P, order="negdegrevlex"): + def __init__(self, k, P, order='negdegrevlex'): """ Create a :class:`PathAlgebra` object. @@ -179,9 +177,9 @@ def order_string(self) -> str: EXAMPLES:: sage: P1 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t')) - sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") - sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="negdeglex") - sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="deglex") + sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') + sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='negdeglex') + sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='deglex') sage: P1.order_string() 'negdegrevlex' sage: P2.order_string() @@ -190,7 +188,6 @@ def order_string(self) -> str: 'negdeglex' sage: P4.order_string() 'deglex' - """ return self._ordstr @@ -277,7 +274,6 @@ def ngens(self): sage: A = P.algebra(GF(5)) sage: A.ngens() 7 - """ return self._semigroup.ngens() @@ -300,7 +296,6 @@ def _element_constructor_(self, x): 2*e_0 + 2*e_1 + 2*e_2 + 2*e_3 sage: B([(0,1,'a'),(1,2,'c')]) # indirect doctest a*c - """ from sage.quivers.paths import QuiverPath # If it's an element of another path algebra, do a linear combination @@ -399,7 +394,6 @@ def _coerce_map_from_(self, other): 2*e_0 + 2*e_1 + 2*e_2 + 2*e_3 sage: B(2)*x*B(3) # indirect doctest e_2 + b + e_3 - """ if isinstance(other, PathAlgebra) and self._base.has_coerce_map_from(other._base): OQ = other._quiver @@ -430,8 +424,8 @@ def _repr_monomial(self, data): INPUT: - A list providing the indices of the path algebra generators occurring - in the monomial. + - ``data`` -- list providing the indices of the path algebra + generators occurring in the monomial EXAMPLES:: @@ -439,7 +433,6 @@ def _repr_monomial(self, data): sage: X = sage_eval('a+2*b+3*c+5*e_0+3*e_2', A.gens_dict()) sage: X # indirect doctest 5*e_0 + a + 2*b + 3*c + 3*e_2 - """ # m is [list, pos, mid], where the list gives the nb of arrows, pos # gives the component in the module, and mid gives the length of the @@ -453,8 +446,8 @@ def _latex_monomial(self, data): INPUT: - A list providing the indices of the path algebra generators occurring - in the monomial. + - ``data`` -- list providing the indices of the path algebra + generators occurring in the monomial EXAMPLES:: @@ -462,7 +455,6 @@ def _latex_monomial(self, data): sage: X = sage_eval('a+2*b+3*c+5*e_0+3*e_2', A.gens_dict()) sage: latex(X) # indirect doctest 5 e_0 + a + 2 b + 3 c + 3 e_2 - """ arrows = self.variable_names() return '\\cdot '.join(arrows[n] for n in data) @@ -496,9 +488,7 @@ def quiver(self): """ Return the quiver from which the algebra ``self`` was formed. - OUTPUT: - - - :class:`DiGraph`, the quiver of the algebra + OUTPUT: :class:`DiGraph`; the quiver of the algebra EXAMPLES:: @@ -563,11 +553,11 @@ def degree_on_basis(self, x): def sum(self, iter_of_elements): """ - Return the sum of all elements in ``iter_of_elements`` + Return the sum of all elements in ``iter_of_elements``. INPUT: - - ``iter_of_elements``: iterator of elements of ``self`` + - ``iter_of_elements`` -- iterator of elements of ``self`` .. NOTE:: @@ -654,7 +644,6 @@ def homogeneous_component(self, n): sage: A = P.algebra(ZZ) sage: A.homogeneous_component(3) Free module spanned by [a*b*c, b*c*a, c*a*b] over Integer Ring - """ basis = [] for v in self._semigroup._quiver: @@ -667,7 +656,7 @@ def homogeneous_component(self, n): def homogeneous_components(self): r""" - Return the non-zero homogeneous components of ``self``. + Return the nonzero homogeneous components of ``self``. EXAMPLES:: diff --git a/src/sage/quivers/algebra_elements.pyx b/src/sage/quivers/algebra_elements.pyx index 63d187b05f6..a8f7778b202 100644 --- a/src/sage/quivers/algebra_elements.pyx +++ b/src/sage/quivers/algebra_elements.pyx @@ -106,7 +106,6 @@ cdef class PathAlgebraElement(RingElement): computations are not available for path algebras, yet. Hence, to implement computations in graded quotients of free algebras, the letterplace implementation currently is the only option. - """ def __cinit__(self): """ @@ -139,11 +138,11 @@ cdef class PathAlgebraElement(RingElement): INPUT: - - ``S``, a path algebra. + - ``S`` -- path algebra - - ``data``, a dictionary. Most of its keys are + - ``data`` -- dictionary; most of its keys are :class:`~sage.quivers.paths.QuiverPath`, the value giving its - coefficient. + coefficient .. NOTE:: @@ -156,17 +155,17 @@ cdef class PathAlgebraElement(RingElement): Defining e_1, x, y, z sage: (x+2*z+1)^2 e_1 + 4*z + 2*x + 4*z*z + 2*x*z + 2*z*x + x*x - sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P2.inject_variables() Defining e_1, x, y, z sage: (x+2*z+1)^2 4*z*z + 2*x*z + 2*z*x + x*x + 4*z + 2*x + e_1 - sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="negdeglex") + sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='negdeglex') sage: P3.inject_variables() Defining e_1, x, y, z sage: (x+2*z+1)^2 e_1 + 4*z + 2*x + 4*z*z + 2*z*x + 2*x*z + x*x - sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="deglex") + sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='deglex') sage: P4.inject_variables() Defining e_1, x, y, z sage: (x+2*z+1)^2 @@ -408,7 +407,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -464,7 +463,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -503,7 +502,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -560,7 +559,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -615,7 +614,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -690,7 +689,7 @@ cdef class PathAlgebraElement(RingElement): INPUT: - An element of the underlying partial semigroup. + - ``P`` -- an element of the underlying partial semigroup OUTPUT: @@ -699,7 +698,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -737,7 +736,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -789,7 +788,7 @@ cdef class PathAlgebraElement(RingElement): """ EXAMPLES:: - sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") + sage: P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') sage: P.inject_variables() Defining e_1, x, y, z sage: p = (x+2*z+1)^3 @@ -921,7 +920,7 @@ cdef class PathAlgebraElement(RingElement): EXAMPLES:: sage: P1 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(3,'t')) - sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(3,'t'), order="deglex") + sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(3,'t'), order='deglex') sage: P1.inject_variables() Defining e_1, x, y, z sage: p = x+y diff --git a/src/sage/quivers/ar_quiver.py b/src/sage/quivers/ar_quiver.py index daa1e755fa5..f13c67dfa32 100644 --- a/src/sage/quivers/ar_quiver.py +++ b/src/sage/quivers/ar_quiver.py @@ -213,7 +213,7 @@ def _repr_(self): # add options to class class options(GlobalOptions): r""" - Sets and displays the global options for Auslander-Reiten quivers. + Set and display the global options for Auslander-Reiten quivers. If no parameters are set, then the function returns a copy of the options dictionary. @@ -240,7 +240,7 @@ class options(GlobalOptions): """ NAME = 'AuslanderReitenQuiver' module = 'sage.quivers.ar_quiver' - latex = dict(default="node", + latex = dict(default='node', description='Specifies how nodes of the AR quiver should be latexed', values=dict(node='latex as the node description', dimension_vector='latex as the dimension vector', @@ -356,7 +356,7 @@ def edge_options(data): edge_opts["label"] = LatexExpr(r"\tau") return edge_opts - G.set_latex_options(format="dot2tex", edge_options=edge_options) + G.set_latex_options(format='dot2tex', edge_options=edge_options) return G def digraph_preprojectives(self, max_depth, with_translations=False): @@ -395,7 +395,7 @@ def digraph_preprojectives(self, max_depth, with_translations=False): prev = cur cur = self._dim_vecs_level(k) - G = DiGraph([verts, edges], format="vertices_and_edges", multiedges=True, immutable=True) + G = DiGraph([verts, edges], format='vertices_and_edges', multiedges=True, immutable=True) return self._digraph_set_latex_options(G) def digraph_postinjectives(self, max_depth, with_translations=False): @@ -434,7 +434,7 @@ def digraph_postinjectives(self, max_depth, with_translations=False): prev = cur cur = self._dim_vecs_level(-k) - G = DiGraph([verts, edges], format="vertices_and_edges", multiedges=True, immutable=True) + G = DiGraph([verts, edges], format='vertices_and_edges', multiedges=True, immutable=True) return self._digraph_set_latex_options(G) @cached_method @@ -444,8 +444,8 @@ def digraph(self, with_translations=False): INPUT: - - ``with_translations`` -- (default: ``False``) if ``True``, then - include the arrows corresponding to the translations. + - ``with_translations`` -- boolean (default: ``False``); if ``True``, then + include the arrows corresponding to the translations EXAMPLES:: @@ -491,7 +491,7 @@ def digraph(self, with_translations=False): cur = self._dim_vecs_level(k) self._injectives = Family(injectives) - G = DiGraph([verts, edges], format="vertices_and_edges", immutable=True) + G = DiGraph([verts, edges], format='vertices_and_edges', immutable=True) return self._digraph_set_latex_options(G) diff --git a/src/sage/quivers/homspace.py b/src/sage/quivers/homspace.py index 6a987c339ec..e500d7fac43 100644 --- a/src/sage/quivers/homspace.py +++ b/src/sage/quivers/homspace.py @@ -45,7 +45,7 @@ class QuiverHomSpace(Homset): .. NOTE:: The quivers of the domain and codomain must be equal or a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. EXAMPLES:: @@ -272,9 +272,7 @@ def __call__(self, *data, **kwds): default call method of :class:`~sage.categories.homset.Homset` is called instead. - OUTPUT: - - - :class:`QuiverRepHom` + OUTPUT: :class:`QuiverRepHom` EXAMPLES:: @@ -383,9 +381,7 @@ def _identity(self): """ Return the identity map. - OUTPUT: - - - :class:`QuiverRepHom` + OUTPUT: :class:`QuiverRepHom` EXAMPLES:: @@ -427,9 +423,7 @@ def quiver(self): """ Return the quiver of the representations. - OUTPUT: - - - :class:`DiGraph`, the quiver of the representations + OUTPUT: :class:`DiGraph`; the quiver of the representations EXAMPLES:: @@ -444,9 +438,7 @@ def domain(self): """ Return the domain of the hom space. - OUTPUT: - - - :class:`QuiverRep`, the domain of the Hom space + OUTPUT: :class:`QuiverRep`; the domain of the Hom space EXAMPLES:: @@ -462,9 +454,7 @@ def codomain(self): """ Return the codomain of the hom space. - OUTPUT: - - - :class:`QuiverRep`, the codomain of the Hom space + OUTPUT: :class:`QuiverRep`; the codomain of the Hom space EXAMPLES:: @@ -487,9 +477,7 @@ def dimension(self): """ Return the dimension of the hom space. - OUTPUT: - - - integer, the dimension + OUTPUT: integer; the dimension EXAMPLES:: @@ -505,9 +493,7 @@ def gens(self) -> tuple: Return a tuple of generators of the hom space (as a `k`-vector space). - OUTPUT: - - - tuple of :class:`QuiverRepHom` objects, the generators + OUTPUT: tuple of :class:`QuiverRepHom` objects; the generators EXAMPLES:: @@ -577,16 +563,14 @@ def left_module(self, basis=False): INPUT: - - ``basis`` -- bool. If ``False``, then only the module is + - ``basis`` -- boolean; if ``False``, then only the module is returned. If ``True``, then a tuple is returned. The first element is the QuiverRep and the second element is a dictionary which associates to each vertex a list. The elements of this list are the homomorphisms which correspond to the basis elements of that vertex in the module. - OUTPUT: - - - :class:`QuiverRep` or tuple + OUTPUT: :class:`QuiverRep` or tuple .. WARNING:: diff --git a/src/sage/quivers/meson.build b/src/sage/quivers/meson.build new file mode 100644 index 00000000000..cdefdce952b --- /dev/null +++ b/src/sage/quivers/meson.build @@ -0,0 +1,29 @@ +py.install_sources( + 'algebra.py', + 'algebra_elements.pxd', + 'all.py', + 'ar_quiver.py', + 'homspace.py', + 'morphism.py', + 'path_semigroup.py', + 'paths.pxd', + 'representation.py', + subdir: 'sage/quivers', +) + +extension_data = { + 'algebra_elements' : files('algebra_elements.pyx'), + 'paths' : files('paths.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/quivers', + install: true, + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/quivers/morphism.py b/src/sage/quivers/morphism.py index f6c2ca180a6..b35941eb05d 100644 --- a/src/sage/quivers/morphism.py +++ b/src/sage/quivers/morphism.py @@ -66,9 +66,7 @@ class QuiverRepHom(CallMorphism): and from ``C`` to the codomain of ``self``. The composition of these maps is the result. - OUTPUT: - - - :class:`QuiverRepHom` + OUTPUT: :class:`QuiverRepHom` EXAMPLES:: @@ -446,7 +444,7 @@ def __isub__(self, other): def __neg__(self): """ - This function overrides the unary ``-`` operator + This function overrides the unary ``-`` operator. TESTS:: @@ -469,7 +467,7 @@ def __neg__(self): def __pos__(self): """ - This function overrides the unary ``+`` operator + This function overrides the unary ``+`` operator. TESTS:: @@ -490,7 +488,7 @@ def __pos__(self): def __eq__(self, other): """ - This function overrides the ``==`` operator + This function overrides the ``==`` operator. TESTS:: @@ -536,7 +534,7 @@ def __hash__(self): def __ne__(self, other): """ - This function overrides the ``!=`` operator + This function overrides the ``!=`` operator. TESTS:: @@ -588,7 +586,7 @@ def __bool__(self) -> bool: def __mul__(self, other): """ - This function overrides the ``*`` operator + This function overrides the ``*`` operator. TESTS:: @@ -616,7 +614,7 @@ def __mul__(self, other): def _assert_valid_hom(self): """ - Raise a :class:`ValueError` if the homomorphism is not well defined. + Raise a :exc:`ValueError` if the homomorphism is not well defined. Specifically it checks that the domain and codomains of the maps are correct and that the edge diagrams commute. @@ -659,9 +657,7 @@ def domain(self): """ Return the domain of the homomorphism. - OUTPUT: - - - :class:`QuiverRep`, the domain + OUTPUT: :class:`QuiverRep`; the domain EXAMPLES:: @@ -680,9 +676,7 @@ def codomain(self): """ Return the codomain of the homomorphism. - OUTPUT: - - - :class:`QuiverRep`, the codomain + OUTPUT: :class:`QuiverRep`; the codomain EXAMPLES:: @@ -704,12 +698,10 @@ def get_matrix(self, vertex): INPUT: - - ``vertex`` -- integer, a vertex of the quiver + - ``vertex`` -- integer; a vertex of the quiver - OUTPUT: - - - matrix, the matrix representing the homomorphism associated to - the given vertex + OUTPUT: the matrix representing the homomorphism associated to + the given vertex EXAMPLES:: @@ -741,11 +733,9 @@ def get_map(self, vertex): INPUT: - - ``vertex`` -- integer, a vertex of the quiver + - ``vertex`` -- integer; a vertex of the quiver - OUTPUT: - - - homomorphism, the homomorphism associated to the given vertex + OUTPUT: the homomorphism associated to the given vertex EXAMPLES:: @@ -781,9 +771,7 @@ def base_ring(self): """ Return the base ring of the representation in the codomain. - OUTPUT: - - - ring, the base ring of the codomain + OUTPUT: the base ring of the codomain EXAMPLES:: @@ -806,9 +794,8 @@ def is_injective(self): """ Test whether the homomorphism is injective. - OUTPUT: - - - bool, ``True`` if the homomorphism is injective, ``False`` otherwise + OUTPUT: boolean; ``True`` if the homomorphism is injective, ``False`` + otherwise EXAMPLES:: @@ -829,9 +816,8 @@ def is_surjective(self): """ Test whether the homomorphism is surjective. - OUTPUT: - - - bool, ``True`` if the homomorphism is surjective, ``False`` otherwise + OUTPUT: boolean; ``True`` if the homomorphism is surjective, ``False`` + otherwise EXAMPLES:: @@ -857,10 +843,8 @@ def is_isomorphism(self): """ Test whether the homomorphism is an isomorphism. - OUTPUT: - - - bool, ``True`` if the homomorphism is bijective, ``False`` - otherwise + OUTPUT: boolean; ``True`` if the homomorphism is bijective, ``False`` + otherwise EXAMPLES:: @@ -880,9 +864,8 @@ def is_zero(self): """ Test whether the homomorphism is the zero homomorphism. - OUTPUT: - - - bool, ``True`` if the homomorphism is zero, ``False`` otherwise + OUTPUT: boolean; ``True`` if the homomorphism is zero, ``False`` + otherwise EXAMPLES:: @@ -902,10 +885,8 @@ def is_endomorphism(self): """ Test whether the homomorphism is an endomorphism. - OUTPUT: - - - bool, ``True`` if the domain equals the codomain, ``False`` - otherwise + OUTPUT: boolean; ``True`` if the domain equals the codomain, ``False`` + otherwise EXAMPLES:: @@ -926,9 +907,7 @@ def rank(self): Return the rank of the homomorphism ``self`` (as a `k`-linear map). - OUTPUT: - - - integer, the rank + OUTPUT: integer; the rank EXAMPLES:: @@ -953,9 +932,7 @@ def kernel(self): """ Return the kernel of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the kernel + OUTPUT: :class:`QuiverRep`; the kernel .. NOTE:: @@ -982,9 +959,7 @@ def image(self): """ Return the image of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the image + OUTPUT: :class:`QuiverRep`; the image .. NOTE:: @@ -1011,9 +986,7 @@ def cokernel(self): """ Return the cokernel of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the cokernel + OUTPUT: :class:`QuiverRep`; the cokernel .. NOTE:: @@ -1040,9 +1013,7 @@ def linear_dual(self): Compute the linear dual `Df : DN \to DM` of ``self`` = `f : M \to N` where `D(-) = Hom_k(-, k)`. - OUTPUT: - - - :class:`QuiverRepHom`, the map `Df : DN \to DM` + OUTPUT: :class:`QuiverRepHom`; the map `Df : DN \to DM` .. NOTE:: @@ -1088,9 +1059,7 @@ def algebraic_dual(self): Compute the algebraic dual `f^t : N^t \to M^t` of ``self`` = `f : M \to N` where `(-)^t = Hom_Q(-, kQ)`. - OUTPUT: - - - :class:`QuiverRepHom`, the map `f^t : N^t \to M^t` + OUTPUT: :class:`QuiverRepHom`; the map `f^t : N^t \to M^t` .. NOTE:: @@ -1131,7 +1100,7 @@ def direct_sum(self, maps, return_maps=False, pinch=None): - ``maps`` -- :class:`QuiverRepHom` or list of :class:`QuiverRepHom`'s - - ``return_maps`` -- bool (default: ``False``). If ``False``, then + - ``return_maps`` -- boolean (default: ``False``); if ``False``, then the return value is a :class:`QuiverRepHom` which is the direct sum of ``self`` with the :class:`QuiverRepHoms` in ``maps``. If ``True``, then the return value is a tuple of length either 3 @@ -1147,7 +1116,7 @@ def direct_sum(self, maps, return_maps=False, pinch=None): If ``pinch`` is either ``'domain'`` or ``'codomain'`` then the tuple will have length 3. - - ``pinch`` -- string or ``None`` (default: ``None``). If this is + - ``pinch`` -- string or ``None`` (default: ``None``); if this is equal to ``'domain'``, then the domains of ``self`` and the given maps must be equal. The direct sum of `f: A \to B` and `g: A \to C` returned is then the map `A \to B \oplus C` defined @@ -1161,9 +1130,7 @@ def direct_sum(self, maps, return_maps=False, pinch=None): `A \oplus C \to B \oplus D` defined by sending `(x, y)` to `(f(x), g(y))`. - OUTPUT: - - - :class:`QuiverRepHom` or tuple + OUTPUT: :class:`QuiverRepHom` or tuple EXAMPLES:: @@ -1246,9 +1213,7 @@ def lift(self, x): - ``x`` -- :class:`QuiverRepElement` - OUTPUT: - - - :class:`QuiverRepElement` + OUTPUT: :class:`QuiverRepElement` EXAMPLES:: diff --git a/src/sage/quivers/path_semigroup.py b/src/sage/quivers/path_semigroup.py index 860242334ba..1b9fe359fba 100644 --- a/src/sage/quivers/path_semigroup.py +++ b/src/sage/quivers/path_semigroup.py @@ -95,7 +95,7 @@ def __classcall__(cls, Q): INPUT: - - a :class:`~sage.graphs.digraph.DiGraph`. + - ``Q`` -- a :class:`~sage.graphs.digraph.DiGraph` TESTS:: @@ -121,7 +121,7 @@ def __init__(self, Q): INPUT: - - a :class:`~sage.graphs.digraph.DiGraph`. + - ``Q`` -- a :class:`~sage.graphs.digraph.DiGraph` EXAMPLES: @@ -268,7 +268,7 @@ def _coerce_map_from_(self, other): def _element_constructor_(self, data, check=True): """ - The accepted data are + The accepted data are: - the integer ``1``, which returns the first idempotent, - a list, whose only item is a tuple ``(v,v)`` for a vertex ``v``, @@ -294,7 +294,7 @@ def _element_constructor_(self, data, check=True): sage: Q(P(['c','d'])) c*d - A :class:`TypeError` or a :class:`ValueError` is raised appropriately + A :exc:`TypeError` or a :exc:`ValueError` is raised appropriately if the input is wrong:: sage: G = DiGraph([(0,0,'a'), (0,1,'b'), (1,0,'c')], loops=True) @@ -362,7 +362,7 @@ def _element_constructor_(self, data, check=True): path = [] else: # a list of edges if any(len(x) != 3 for x in data): - x = next((x for x in data if len(x) != 3)) + x = next(x for x in data if len(x) != 3) raise ValueError("each edge must be a triple, got {}".format(x)) start = data[0][0] end = data[-1][1] @@ -599,7 +599,6 @@ def __iter__(self): c*b*d a*d*c*a a*d*c*b - """ d = 0 length_d_available = True @@ -617,8 +616,8 @@ def iter_paths_by_length_and_startpoint(self, d, v): INPUT: - - ``d`` -- an integer, the path length - - ``v`` -- a vertex, start point of the paths + - ``d`` -- integer; the path length + - ``v`` -- a vertex; start point of the paths EXAMPLES:: @@ -659,7 +658,7 @@ def iter_paths_by_length_and_startpoint(self, d, v): """ # iterate over length d paths starting at vertex v if not d >= 0: - raise ValueError("path length must be a non-negative integer") + raise ValueError("path length must be a nonnegative integer") if v not in self._quiver: raise ValueError("the starting point {} is not a vertex of the underlying quiver".format(v)) if not d: @@ -675,8 +674,8 @@ def iter_paths_by_length_and_endpoint(self, d, v): INPUT: - - ``d`` -- an integer, the path length - - ``v`` -- a vertex, end point of the paths + - ``d`` -- integer; the path length + - ``v`` -- a vertex; end point of the paths EXAMPLES:: @@ -693,7 +692,7 @@ def iter_paths_by_length_and_endpoint(self, d, v): """ # iterate over length d paths ending at vertex v if not d >= 0: - raise ValueError("path length must be a non-negative integer") + raise ValueError("path length must be a nonnegative integer") if v not in self._quiver: raise ValueError("the starting point {} is not a vertex of the underlying quiver".format(v)) if not d: @@ -739,7 +738,7 @@ def reverse(self): """ return self._quiver.reverse().path_semigroup() - def algebra(self, k, order="negdegrevlex"): + def algebra(self, k, order='negdegrevlex'): """ Return the path algebra of the underlying quiver. @@ -747,9 +746,9 @@ def algebra(self, k, order="negdegrevlex"): - ``k`` -- a commutative ring - - ``order`` -- optional string, one of "negdegrevlex" (default), - "degrevlex", "negdeglex" or "deglex", defining the monomial order to - be used. + - ``order`` -- (optional) string, one of ``'negdegrevlex'`` (default), + ``'degrevlex'``, ``'negdeglex'`` or ``'deglex'``, defining the + monomial order to be used .. NOTE:: @@ -765,9 +764,9 @@ def algebra(self, k, order="negdegrevlex"): Now some example with different monomial orderings:: sage: P1 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t')) - sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="degrevlex") - sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="negdeglex") - sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order="deglex") + sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex') + sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='negdeglex') + sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='deglex') sage: P1.order_string() 'negdegrevlex' sage: sage_eval('(x+2*z+1)^3', P1.gens_dict()) @@ -778,7 +777,6 @@ def algebra(self, k, order="negdegrevlex"): e_1 + z + 3*x + 2*z*z + z*x + x*z + 3*x*x + 3*z*z*z + 4*z*z*x + 4*z*x*z + 2*z*x*x + 4*x*z*z + 2*x*z*x + 2*x*x*z + x*x*x sage: sage_eval('(x+2*z+1)^3', P4.gens_dict()) 3*z*z*z + 4*z*z*x + 4*z*x*z + 2*z*x*x + 4*x*z*z + 2*x*z*x + 2*x*x*z + x*x*x + 2*z*z + z*x + x*z + 3*x*x + z + 3*x + e_1 - """ from sage.quivers.algebra import PathAlgebra return PathAlgebra(k, self, order) @@ -817,14 +815,12 @@ def S(self, k, vertex): INPUT: - - `k` -- ring, the base ring of the representation + - ``k`` -- the base ring of the representation - - ``vertex`` -- integer, a vertex of the quiver + - ``vertex`` -- integer; a vertex of the quiver - OUTPUT: - - - :class:`~sage.quivers.representation.QuiverRep`, the simple module - at ``vertex`` with base ring `k` + OUTPUT: :class:`~sage.quivers.representation.QuiverRep`; the simple + module at ``vertex`` with base ring `k` EXAMPLES:: @@ -861,14 +857,12 @@ def P(self, k, vertex): INPUT: - - `k` -- ring, the base ring of the representation + - ``k`` -- the base ring of the representation - - ``vertex`` -- integer, a vertex of the quiver + - ``vertex`` -- integer; a vertex of the quiver - OUTPUT: - - - :class:`~sage.quivers.representation.QuiverRep`, the indecomposable - projective module at ``vertex`` with base ring `k` + OUTPUT: :class:`~sage.quivers.representation.QuiverRep`, the + indecomposable projective module at ``vertex`` with base ring `k` EXAMPLES:: @@ -901,9 +895,9 @@ def I(self, k, vertex): INPUT: - - `k` -- ring, the base ring of the representation + - ``k`` -- the base ring of the representation - - ``vertex`` -- integer, a vertex of the quiver + - ``vertex`` -- integer; a vertex of the quiver OUTPUT: @@ -939,7 +933,7 @@ def free_module(self, k): INPUT: - - ``k`` -- ring, the base ring of the representation. + - ``k`` -- ring; the base ring of the representation OUTPUT: @@ -1016,9 +1010,7 @@ def all_paths(self, start=None, end=None): vertex of the paths in the output; if ``None`` is given then the terminal vertex is arbitrary - OUTPUT: - - - list of paths, excluding the invalid path + OUTPUT: list of paths, excluding the invalid path .. TODO:: @@ -1078,7 +1070,7 @@ def all_paths(self, start=None, end=None): ... ValueError: the end vertex 4 is not a vertex of the quiver - If the underlying quiver is cyclic, a :class:`ValueError` + If the underlying quiver is cyclic, a :exc:`ValueError` is raised:: sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}) diff --git a/src/sage/quivers/paths.pyx b/src/sage/quivers/paths.pyx index 2f6dfc061b1..c3552c09294 100644 --- a/src/sage/quivers/paths.pyx +++ b/src/sage/quivers/paths.pyx @@ -105,7 +105,6 @@ cdef class QuiverPath(MonoidElement): sage: Q = DiGraph({1:{2:['a']}, 2:{3:['b']}}).path_semigroup() sage: p = Q([(1, 1)]) * Q([(1, 1)]) sage: del p # indirect doctest - """ biseq_dealloc(self._path) @@ -125,17 +124,17 @@ cdef class QuiverPath(MonoidElement): def __init__(self, parent, start, end, path): """ - Creates a path object. Type ``QuiverPath?`` for more information. + Create a path object. Type ``QuiverPath?`` for more information. INPUT: - - ``parent``, a path semigroup. - - ``start``, integer, the label of the initial vertex. - - ``end``, integer, the label of the terminal vertex. - - ``path``, list of integers, providing the list of arrows + - ``parent`` -- a path semigroup + - ``start`` -- integer; the label of the initial vertex + - ``end`` -- integer; the label of the terminal vertex + - ``path`` -- list of integers, providing the list of arrows occurring in the path, labelled according to the position in the list of all arrows (resp. the list of outgoing arrows at - each vertex). + each vertex) TESTS:: @@ -322,7 +321,6 @@ cdef class QuiverPath(MonoidElement): False sage: a < a False - """ # Since QuiverPath inherits from Element, it is guaranteed that # both arguments are elements of the same path semigroup @@ -404,7 +402,6 @@ cdef class QuiverPath(MonoidElement): e_4 sage: p[20:40].initial_vertex() == p.terminal_vertex() True - """ cdef tuple E cdef Py_ssize_t start, stop, step, slicelength @@ -527,7 +524,6 @@ cdef class QuiverPath(MonoidElement): a*b sage: print(p % e2) None - """ cdef QuiverPath right = other # Handle trivial case @@ -555,7 +551,7 @@ cdef class QuiverPath(MonoidElement): INPUT: - A :class:`QuiverPath` ``P`` + - ``P`` -- a :class:`QuiverPath` OUTPUT: @@ -594,7 +590,6 @@ cdef class QuiverPath(MonoidElement): b*a*c*d*a*c*d*a*b sage: print(p2[2:-1].gcd(p2[1:])) (None, None, None) - """ if self._parent is not P._parent: return (None, None, None) @@ -624,7 +619,6 @@ cdef class QuiverPath(MonoidElement): (b*c, b*a*d*d) sage: (b*c*a*d*b).complement(a*c) (None, None) - """ cdef mp_size_t i = biseq_contains(self._path, subpath._path, 0) if i == -1: @@ -637,8 +631,8 @@ cdef class QuiverPath(MonoidElement): INPUT: - ``subpath``, a path of positive length in the same path semigroup as - this path. + - ``subpath`` -- a path of positive length in the same path semigroup + as this path EXAMPLES:: @@ -676,11 +670,9 @@ cdef class QuiverPath(MonoidElement): INPUT: - ``subpath``, a path in the same path semigroup as this path. - - OUTPUT: + - ``subpath`` -- a path in the same path semigroup as this path - ``0`` or ``1``, which stands for ``False`` resp. ``True``. + OUTPUT: ``0`` or ``1``, which stands for ``False`` resp. ``True`` EXAMPLES:: @@ -695,7 +687,6 @@ cdef class QuiverPath(MonoidElement): 1 sage: (c*b*e*a).has_prefix(e_2) 0 - """ if subpath._parent is not self._parent: raise ValueError("the two paths belong to different quivers") @@ -711,9 +702,7 @@ cdef class QuiverPath(MonoidElement): """ Return the initial vertex of the path. - OUTPUT: - - - integer, the label of the initial vertex + OUTPUT: integer; the label of the initial vertex EXAMPLES:: @@ -728,9 +717,7 @@ cdef class QuiverPath(MonoidElement): """ Return the terminal vertex of the path. - OUTPUT: - - - integer, the label of the terminal vertex + OUTPUT: integer; the label of the terminal vertex EXAMPLES:: @@ -759,7 +746,6 @@ cdef class QuiverPath(MonoidElement): e_1 sage: e.reversal() e_1 - """ Q = self._parent.reverse() # Handle trivial paths @@ -788,16 +774,16 @@ def NewQuiverPath(Q, start, end, biseq_data): INPUT: - - ``Q``, the path semigroup of a quiver - - ``start``, an integer, the label of the startpoint - - ``end``, an integer, the label of the endpoint - - ``biseq_data``, a tuple formed by + - ``Q`` -- the path semigroup of a quiver + - ``start`` -- integer; the label of the startpoint + - ``end`` -- integer; the label of the endpoint + - ``biseq_data`` -- tuple formed by - - A string, encoding a bitmap representing the path as integer - at base `32`, - - the number of bits used to store the path, + - a string, encoding a bitmap representing the path as integer + at base `32` + - the number of bits used to store the path - the number of bits used to store a single item - - the number of items in the path. + - the number of items in the path TESTS:: diff --git a/src/sage/quivers/representation.py b/src/sage/quivers/representation.py index be58c37fd70..57d2e09a8bd 100644 --- a/src/sage/quivers/representation.py +++ b/src/sage/quivers/representation.py @@ -480,16 +480,16 @@ class QuiverRepFactory(UniqueFactory): are ignored; the keywords are only checked in the event that the argument list does not have enough entries after ``P``. - - ``spaces`` -- dict (default: empty); a dictionary associating to each - vertex a free module over the base ring `k`. Not all vertices must be - specified; unspecified vertices are automatically set to `k^0`. Keys - of the dictionary that don't correspond to vertices are ignored. + - ``spaces`` -- dictionary (default: empty) associating to each vertex a + free module over the base ring `k`. Not all vertices must be specified; + unspecified vertices are automatically set to `k^0`. Keys of the + dictionary that don't correspond to vertices are ignored. - - ``maps`` -- dict (default: empty); a dictionary associating to each edge - a map whose domain and codomain are the spaces associated to the initial - and terminal vertex of the edge respectively. Not all edges must be - specified; unspecified edges are automatically set to the zero map. - Keys of the dictionary that don't correspond to edges are ignored. + - ``maps`` -- dictionary (default: empty) associating to each edge a map + whose domain and codomain are the spaces associated to the initial and + terminal vertex of the edge respectively. Not all edges must be + specified; unspecified edges are automatically set to the zero map. Keys + of the dictionary that don't correspond to edges are ignored. The second option is the ``paths`` option which creates a module by generating a right ideal from a list of paths. Thus the basis elements @@ -502,7 +502,7 @@ class QuiverRepFactory(UniqueFactory): - ``basis`` -- list; a nonempty list of paths in the quiver ``Q``. Entries that do not represent valid paths are ignored and duplicate paths are deleted. There must be at least one valid path in the list - or a :class:`ValueError` is raised. The closure of this list under right + or a :exc:`ValueError` is raised. The closure of this list under right multiplication forms the basis of the resulting representation. The third option is the ``dual paths`` option which creates the dual of @@ -516,18 +516,16 @@ class QuiverRepFactory(UniqueFactory): - ``basis`` -- list; a nonempty list of paths in the quiver ``Q``. Entries that do not represent valid paths are ignored and duplicate paths are deleted. There must be at least one valid path in the list - or a :class:`ValueError` is raised. The closure of this list under left + or a :exc:`ValueError` is raised. The closure of this list under left multiplication of edges forms the basis of the resulting representation. Using the second and third options requires that the following keyword be passed to the constructor. This must be passed as a keyword. - - ``option`` -- string (default: ``None``), either ``'values'`` or - ``'paths'`` or ``'dual paths'``. ``None`` is equivalent to ``'values'``. + - ``option`` -- string (default: ``None``); either ``'values'`` or + ``'paths'`` or ``'dual paths'``. ``None`` is equivalent to ``'values'`` - OUTPUT: - - - :class:`QuiverRep` + OUTPUT: :class:`QuiverRep` EXAMPLES:: @@ -573,7 +571,8 @@ class QuiverRepFactory(UniqueFactory): In the following example, the 3rd and 4th paths are actually the same, so the duplicate is removed:: - sage: N = Q1.representation(QQ, [[(1, 1)], [(2, 2)], [(1, 2, 'a')], [(1, 2, 'a')]], option='paths') + sage: N = Q1.representation(QQ, [[(1, 1)], [(2, 2)], [(1, 2, 'a')], + ....: [(1, 2, 'a')]], option='paths') sage: N.dimension() 3 @@ -607,9 +606,7 @@ def create_key(self, k, P, *args, **kwds): See the class documentation. - OUTPUT: - - - tuple + OUTPUT: tuple EXAMPLES:: @@ -763,9 +760,7 @@ def create_object(self, version, key, **extra_args): - ``version`` -- the version of sage, this is currently ignored - ``key`` -- tuple - OUTPUT: - - - :class:`QuiverRep_generic` or :class:`QuiverRep_with_path_basis` + OUTPUT: :class:`QuiverRep_generic` or :class:`QuiverRep_with_path_basis` EXAMPLES:: @@ -825,20 +820,18 @@ class QuiverRepElement(ModuleElement): INPUT: - - ``module`` -- :class:`QuiverRep` (default: ``None``), the module to + - ``module`` -- :class:`QuiverRep` (default: ``None``); the module to which the element belongs - - ``elements`` -- dict (default: empty), a dictionary associating to each - vertex a vector or an object from which sage can create a vector. - Not all vertices must be specified, unspecified vertices will be - assigned the zero vector of the space associated to that vertex in - the given module. Keys that do not correspond to a vertex are ignored. - - - ``name`` -- string (default: ``None``), the name of the element + - ``elements`` -- dictionary (default: empty) associating to each vertex a + vector or an object from which sage can create a vector. Not all vertices + must be specified, unspecified vertices will be assigned the zero vector + of the space associated to that vertex in the given module. Keys that do + not correspond to a vertex are ignored. - OUTPUT: + - ``name`` -- string (default: ``None``); the name of the element - - :class:`QuiverRepElement` + OUTPUT: :class:`QuiverRepElement` .. NOTE:: @@ -986,7 +979,7 @@ def _neg_(self): def __mul__(self, other): """ - Implements ``*`` for right multiplication by quiver algebra elements. + Implement ``*`` for right multiplication by quiver algebra elements. TESTS:: @@ -1126,9 +1119,7 @@ def quiver(self): """ Return the quiver of the representation. - OUTPUT: - - - :class:`DiGraph`, the quiver of the representation + OUTPUT: :class:`DiGraph`, the quiver of the representation EXAMPLES:: @@ -1146,11 +1137,9 @@ def get_element(self, vertex): INPUT: - - ``vertex`` -- integer, a vertex of the quiver - - OUTPUT: + - ``vertex`` -- integer; a vertex of the quiver - - vector, the vector assigned to the given vertex + OUTPUT: the vector assigned to the given vertex EXAMPLES:: @@ -1178,7 +1167,7 @@ def _set_element(self, vector, vertex): - ``vector`` -- a vector or an object from which the space associated to the given vertex in the parent can create a vector - - ``vertex`` -- integer, a vertex of the quiver + - ``vertex`` -- integer; a vertex of the quiver .. WARNING:: @@ -1212,10 +1201,8 @@ def is_zero(self): """ Test whether ``self`` is zero. - OUTPUT: - - - bool, ``True`` if the element is the zero element, ``False`` - otherwise + OUTPUT: boolean, ``True`` if the element is the zero element, ``False`` + otherwise EXAMPLES:: @@ -1249,9 +1236,7 @@ def support(self): The support is the set of vertices to which a nonzero vector is associated. - OUTPUT: - - - list, the support + OUTPUT: list; the support EXAMPLES:: @@ -1319,22 +1304,18 @@ class QuiverRep_generic(WithEqualityById, Module): - ``P`` -- the path semigroup of the quiver `Q` of the representation - - ``spaces`` -- dict (default: empty), a dictionary associating to each - vertex a free module over the base ring `k`. Not all vertices need - to be specified, unspecified vertices are automatically set to - `k^0`. Keys of the dictionary that don't correspond to vertices are - ignored. - - - ``maps`` -- dict (default: empty), a dictionary associating to each - edge a map whose domain and codomain are the spaces associated to - the initial and terminal vertex of the edge respectively. Not all - edges need to be specified, unspecified edges are automatically set - to the zero map. Keys of the dictionary that don't correspond to - edges are ignored. + - ``spaces`` -- dictionary (default: empty) associating to each vertex a + free module over the base ring `k`. Not all vertices need to be + specified, unspecified vertices are automatically set to `k^0`. Keys of + the dictionary that don't correspond to vertices are ignored. - OUTPUT: + - ``maps`` -- dictionary (default: empty) associating to each edge a map + whose domain and codomain are the spaces associated to the initial and + terminal vertex of the edge respectively. Not all edges need to be + specified, unspecified edges are automatically set to the zero map. Keys + of the dictionary that don't correspond to edges are ignored. - - :class:`QuiverRep` + OUTPUT: :class:`QuiverRep` EXAMPLES:: @@ -1576,11 +1557,9 @@ def _coerce_map_from_(self, domain): INPUT: - - ``domain`` -= a Sage object - - OUTPUT: + - ``domain`` -- a Sage object - - :class:`QuiverRepHom` or bool + OUTPUT: :class:`QuiverRepHom` or boolean TESTS:: @@ -1658,7 +1637,7 @@ def get_space(self, vertex): INPUT: - - ``vertex`` -- integer, a vertex of the quiver of the module + - ``vertex`` -- integer; a vertex of the quiver of the module EXAMPLES:: @@ -1694,9 +1673,7 @@ def quiver(self): """ Return the quiver of the representation. - OUTPUT: - - - :class:`DiGraph` + OUTPUT: :class:`DiGraph` EXAMPLES:: @@ -1711,9 +1688,7 @@ def actor(self): r""" Return the quiver path algebra acting on this representation. - OUTPUT: - - - a quiver path algebra + OUTPUT: a quiver path algebra EXAMPLES:: @@ -1778,9 +1753,7 @@ def dimension_vector(self): """ Return the dimension vector of the representation. - OUTPUT: - - - tuple + OUTPUT: tuple .. NOTE:: @@ -1806,9 +1779,7 @@ def is_zero(self): """ Test whether the representation is zero. - OUTPUT: - - - bool + OUTPUT: boolean EXAMPLES:: @@ -1830,9 +1801,7 @@ def is_simple(self): """ Test whether the representation is simple. - OUTPUT: - - - bool + OUTPUT: boolean EXAMPLES:: @@ -1850,9 +1819,7 @@ def is_semisimple(self): """ Test whether the representation is semisimple. - OUTPUT: - - - bool + OUTPUT: boolean EXAMPLES:: @@ -1872,9 +1839,7 @@ def an_element(self): """ Return an element of ``self``. - OUTPUT: - - - :class:`QuiverRepElement` + OUTPUT: :class:`QuiverRepElement` EXAMPLES:: @@ -2030,9 +1995,7 @@ def linear_combination_of_basis(self, coordinates): coefficient of the `i`-th basis vector in the linear combination. - OUTPUT: - - - :class:`QuiverRepElement` + OUTPUT: :class:`QuiverRepElement` EXAMPLES:: @@ -2071,10 +2034,9 @@ def submodule(self, elements=[], spaces=None): - ``elements`` -- a collection of QuiverRepElements (default: empty list), each should be an element of ``self`` - - ``spaces`` -- dictionary (default: empty), this dictionary - should contain entries of the form ``{v: S}`` where `v` is a - vertex of the quiver and `S` is a subspace of the vector space - associated to `v` + - ``spaces`` -- dictionary (default: empty); should contain entries of + the form ``{v: S}`` where `v` is a vertex of the quiver and `S` is a + subspace of the vector space associated to `v` OUTPUT: @@ -2183,13 +2145,11 @@ def quotient(self, sub, check=True): associated to each edge `e` of ``sub`` is the restriction of the map associated to `e` in ``self`` - - ``check`` -- bool; if ``True`` then ``sub`` is checked to verify + - ``check`` -- boolean; if ``True`` then ``sub`` is checked to verify that it is indeed a submodule of ``self`` and an error is raised if it is not - OUTPUT: - - - :class:`QuiverRep`, the quotient module ``self / sub`` + OUTPUT: :class:`QuiverRep`, the quotient module ``self / sub`` .. NOTE:: @@ -2256,9 +2216,7 @@ def socle(self): """ The socle of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the socle + OUTPUT: :class:`QuiverRep`; the socle EXAMPLES:: @@ -2280,9 +2238,7 @@ def radical(self): """ Return the Jacobson radical of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the Jacobson radical + OUTPUT: :class:`QuiverRep`; the Jacobson radical EXAMPLES:: @@ -2304,9 +2260,7 @@ def top(self): """ Return the top of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the quotient of ``self`` by its radical + OUTPUT: :class:`QuiverRep`; the quotient of ``self`` by its radical EXAMPLES:: @@ -2323,9 +2277,7 @@ def zero_submodule(self): """ Return the zero submodule of ``self``. - OUTPUT: - - - :class:`QuiverRep`, the zero submodule of ``self``. + OUTPUT: :class:`QuiverRep`; the zero submodule of ``self`` EXAMPLES:: @@ -2345,9 +2297,7 @@ def linear_dual(self): Compute the linear dual `Hom_k(M, k)` of the module `M =` ``self`` over the base ring `k`. - OUTPUT: - - - :class:`QuiverRep`, the dual representation + OUTPUT: :class:`QuiverRep`; the dual representation .. NOTE:: @@ -2399,16 +2349,14 @@ def algebraic_dual(self, basis=False): INPUT: - - ``basis`` -- bool; if ``False``, then only the module is + - ``basis`` -- boolean; if ``False``, then only the module is returned. If ``True``, then a tuple is returned. The first element is the :class:`QuiverRep` and the second element is a dictionary which associates to each vertex a list. The elements of this list are the homomorphisms which correspond to the basis elements of that vertex in the module. - OUTPUT: - - - :class:`QuiverRep` or tuple + OUTPUT: :class:`QuiverRep` or tuple .. NOTE:: @@ -2452,7 +2400,7 @@ def direct_sum(self, modules, return_maps=False): - ``modules`` -- :class:`QuiverRep` or list of :class:`QuiverRep`'s - - ``return_maps`` -- Boolean (default: ``False``); if ``False``, then + - ``return_maps`` -- boolean (default: ``False``); if ``False``, then the output is a single QuiverRep object which is the direct sum of ``self`` with the given module or modules. If ``True``, then the output is a list ``[sum, iota, pi]``. The first entry @@ -2463,9 +2411,7 @@ def direct_sum(self, modules, return_maps=False): The summands are ordered as given with ``self`` being the zeroth summand. - OUTPUT: - - - :class:`QuiverRep` or tuple + OUTPUT: :class:`QuiverRep` or tuple EXAMPLES:: @@ -2618,9 +2564,7 @@ def transpose(self): If `p^t` is the algebraic dual of `p` then define `\mbox{Tr} M = \mbox{coker} p^t`. - OUTPUT: - - - :class:`QuiverRep` + OUTPUT: :class:`QuiverRep` EXAMPLES:: @@ -2860,7 +2804,7 @@ def _left_edge_action(self, edge, element): - ``element`` -- :class:`QuiverRepElement`; an element of ``self`` - - ``edge`` -- An edge of the quiver (a tuple) or a list of edges in + - ``edge`` -- an edge of the quiver (a tuple) or a list of edges in the quiver. Such a list can be empty (in which case no action is performed) and can contain trivial paths (tuples of the form `(v, v)` where `v` is a vertex of the quiver) diff --git a/src/sage/repl/attach.py b/src/sage/repl/attach.py index 4efc94f5cac..89b6a789fc4 100644 --- a/src/sage/repl/attach.py +++ b/src/sage/repl/attach.py @@ -109,10 +109,10 @@ def load_attach_mode(load_debug=None, attach_debug=None): - ``load_debug`` -- boolean or ``None`` (default); if not ``None``, then set a new value for the debug mode for loading - files. + files - ``attach_debug`` -- boolean or ``None`` (default); same as - ``load_debug``, but for attaching files. + ``load_debug``, but for attaching files OUTPUT: @@ -151,15 +151,13 @@ def load_attach_path(path=None, replace=False): INPUT: - ``path`` -- string or list of strings (default: ``None``); - path(s) to append to or replace the current path. + path(s) to append to or replace the current path - ``replace`` -- boolean (default: ``False``); if ``path`` is not ``None``, whether to *replace* the search path instead of - *appending* to it. + *appending* to it - OUTPUT: - - ``None`` or a *reference* to the current search paths. + OUTPUT: none or a *reference* to the current search paths EXAMPLES: @@ -296,20 +294,20 @@ def attach(*files): INPUT: - - ``files`` -- a list of filenames (strings) to attach. + - ``files`` -- list of filenames (strings) to attach OUTPUT: Each file is read in and added to an internal list of watched files. The meaning of reading in a file depends on the file type: - - ``.py`` files are read in with no preparsing (so, e.g., ``2^3`` is 2 - bit-xor 3); + - ``.py`` files are read in with no preparsing (so, e.g., ``2^3`` is 2 + bit-xor 3); - - ``.sage`` files are preparsed, then the result is read in; + - ``.sage`` files are preparsed, then the result is read in; - ``.pyx`` files are *not* preparsed, but rather are compiled to a - module ``m`` and then ``from m import *`` is executed. + module ``m`` and then ``from m import *`` is executed. The contents of the file are then loaded, which means they are read into the running Sage session. For example, if ``foo.sage`` contains @@ -372,7 +370,7 @@ def attach(*files): def add_attached_file(filename): """ - Add to the list of attached files + Add to the list of attached files. This is a callback to be used from :func:`~sage.repl.load.load` after evaluating the attached @@ -405,9 +403,7 @@ def attached_files() -> list: Return a list of all files attached to the current session with :meth:`attach`. - OUTPUT: - - The filenames in a sorted list of strings. + OUTPUT: the filenames in a sorted list of strings EXAMPLES:: @@ -433,7 +429,7 @@ def detach(filename): INPUT: - - ``filename`` -- a string, a list of strings or a tuple of strings + - ``filename`` -- string, a list of strings or a tuple of strings or a :class:`Path`, a list of :class:`Path` or a tuple of :class:`Path` EXAMPLES:: diff --git a/src/sage/repl/configuration.py b/src/sage/repl/configuration.py index ad0870cca2e..68b2fbb9f8b 100644 --- a/src/sage/repl/configuration.py +++ b/src/sage/repl/configuration.py @@ -37,11 +37,11 @@ SAGE_EXTENSION = 'sage' -class SageIpythonConfiguration(): +class SageIpythonConfiguration: def _doctest_mode(self): """ - Whether we are in doctest mode + Whether we are in doctest mode. This returns ``True`` during doctests. @@ -56,7 +56,7 @@ def _doctest_mode(self): def _allow_ansi(self): """ - Whether to allow ANSI escape sequences + Whether to allow ANSI escape sequences. This returns ``False`` during doctests to avoid ANSI escape sequences. @@ -71,7 +71,7 @@ def _allow_ansi(self): def colors(self): """ - Return the IPython color palette + Return the IPython color palette. This returns ``'NoColor'`` during doctests to avoid ANSI escape sequences. @@ -89,7 +89,7 @@ def colors(self): def simple_prompt(self): """ - Return whether to use the simple prompt + Return whether to use the simple prompt. This returns ``True`` during doctests to avoid ANSI escape sequences. @@ -103,7 +103,7 @@ def simple_prompt(self): def term_title(self): """ - Return whether to set the terminal title + Return whether to set the terminal title. This returns false during doctests to avoid ANSI escape sequences. @@ -117,7 +117,7 @@ def term_title(self): def default(self): """ - Return a new default configuration object + Return a new default configuration object. EXAMPLES:: @@ -166,7 +166,7 @@ def default(self): def copy(self): """ - Return a copy of the current configuration + Return a copy of the current configuration. EXAMPLES:: diff --git a/src/sage/repl/display/fancy_repr.py b/src/sage/repl/display/fancy_repr.py index c2e88af33f0..044f8e3f6b2 100644 --- a/src/sage/repl/display/fancy_repr.py +++ b/src/sage/repl/display/fancy_repr.py @@ -24,7 +24,7 @@ _baseclass_reprs = (object.__repr__,) -class ObjectReprABC(): +class ObjectReprABC: """ The abstract base class of an object representer. @@ -35,9 +35,7 @@ def __repr__(self): """ Return string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -53,15 +51,15 @@ def __call__(self, obj, p, cycle): INPUT: - - ``obj`` -- anything. Object to format. + - ``obj`` -- anything; object to format - - ``p`` -- PrettyPrinter instance. + - ``p`` -- PrettyPrinter instance - - ``cycle`` -- boolean. Whether there is a cycle. + - ``cycle`` -- boolean; whether there is a cycle OUTPUT: - Boolean. Whether the representer is applicable to ``obj``. If + boolean; whether the representer is applicable to ``obj``. If ``True``, the string representation is appended to ``p``. EXAMPLES:: @@ -79,11 +77,9 @@ def format_string(self, obj): INPUT: - - ``obj`` -- anything. Object to format. - - OUTPUT: + - ``obj`` -- anything; object to format - String. + OUTPUT: string EXAMPLES:: @@ -106,7 +102,7 @@ class SomeIPythonRepr(ObjectReprABC): def __init__(self): """ - Some selected representers from IPython + Some selected representers from IPython. EXAMPLES:: @@ -129,15 +125,15 @@ def __call__(self, obj, p, cycle): INPUT: - - ``obj`` -- anything. Object to format. + - ``obj`` -- anything; object to format - - ``p`` -- PrettyPrinter instance. + - ``p`` -- PrettyPrinter instance - - ``cycle`` -- boolean. Whether there is a cycle. + - ``cycle`` -- boolean; whether there is a cycle OUTPUT: - Boolean. Whether the representer is applicable to ``obj``. If + boolean; whether the representer is applicable to ``obj``. If ``True``, the string representation is appended to ``p``. EXAMPLES:: @@ -157,7 +153,7 @@ def __call__(self, obj, p, cycle): class LargeMatrixHelpRepr(ObjectReprABC): """ - Representation including help for large Sage matrices + Representation including help for large Sage matrices. .. automethod:: __call__ """ @@ -168,15 +164,15 @@ def __call__(self, obj, p, cycle): INPUT: - - ``obj`` -- anything. Object to format. + - ``obj`` -- anything; object to format - - ``p`` -- PrettyPrinter instance. + - ``p`` -- PrettyPrinter instance - - ``cycle`` -- boolean. Whether there is a cycle. + - ``cycle`` -- boolean; whether there is a cycle OUTPUT: - Boolean. Whether the representer is applicable to ``obj``. If + boolean; whether the representer is applicable to ``obj``. If ``True``, the string representation is appended to ``p``. EXAMPLES:: @@ -215,7 +211,7 @@ def __call__(self, obj, p, cycle): class PlainPythonRepr(ObjectReprABC): """ - The ordinary Python representation + The ordinary Python representation. .. automethod:: __call__ """ @@ -226,15 +222,15 @@ def __call__(self, obj, p, cycle): INPUT: - - ``obj`` -- anything. Object to format. + - ``obj`` -- anything; object to format - - ``p`` -- PrettyPrinter instance. + - ``p`` -- PrettyPrinter instance - - ``cycle`` -- boolean. Whether there is a cycle. + - ``cycle`` -- boolean; whether there is a cycle OUTPUT: - Boolean. Whether the representer is applicable to ``obj``. If + boolean; whether the representer is applicable to ``obj``. If ``True``, the string representation is appended to ``p``. EXAMPLES:: @@ -287,7 +283,7 @@ def __call__(self, obj, p, cycle): class TallListRepr(ObjectReprABC): """ - Special representation for lists with tall entries (e.g. matrices) + Special representation for lists with tall entries (e.g. matrices). .. automethod:: __call__ """ @@ -298,15 +294,15 @@ def __call__(self, obj, p, cycle): INPUT: - - ``obj`` -- anything. Object to format. + - ``obj`` -- anything; object to format - - ``p`` -- PrettyPrinter instance. + - ``p`` -- PrettyPrinter instance - - ``cycle`` -- boolean. Whether there is a cycle. + - ``cycle`` -- boolean; whether there is a cycle OUTPUT: - Boolean. Whether the representer is applicable to ``obj``. If + boolean; whether the representer is applicable to ``obj``. If ``True``, the string representation is appended to ``p``. EXAMPLES:: diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py index b76457669cb..bae9705d57c 100644 --- a/src/sage/repl/display/formatter.py +++ b/src/sage/repl/display/formatter.py @@ -84,11 +84,9 @@ class SageDisplayFormatter(DisplayFormatter): def __init__(self, *args, **kwds): """ - This is where the Sage rich objects are translated to IPython + This is where the Sage rich objects are translated to IPython. - INPUT/OUTPUT: - - See the IPython documentation. + INPUT/OUTPUT: see the IPython documentation EXAMPLES: @@ -113,11 +111,9 @@ def __init__(self, *args, **kwds): def format(self, obj, include=None, exclude=None): r""" - Use the Sage rich output instead of IPython - - INPUT/OUTPUT: + Use the Sage rich output instead of IPython. - See the IPython documentation. + INPUT/OUTPUT: see the IPython documentation EXAMPLES:: @@ -272,9 +268,7 @@ def __init__(self, *args, **kwds): rich output system that is more flexible and supports different backends. - INPUT/OUTPUT: - - See the IPython documentation. + INPUT/OUTPUT: see the IPython documentation EXAMPLES:: @@ -294,11 +288,9 @@ def __call__(self, obj): INPUT: - - ``obj`` -- anything. - - OUTPUT: + - ``obj`` -- anything - String. The plain text representation. + OUTPUT: string; the plain text representation EXAMPLES:: diff --git a/src/sage/repl/display/jsmol_iframe.py b/src/sage/repl/display/jsmol_iframe.py index b50822b875b..abe0e052c08 100644 --- a/src/sage/repl/display/jsmol_iframe.py +++ b/src/sage/repl/display/jsmol_iframe.py @@ -136,9 +136,7 @@ def script(self): This method extracts the Jmol script from the Jmol spt file (a zip archive) and inlines meshes. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -200,11 +198,9 @@ def js_script(self): def _repr_(self): """ - Return as string representation - - OUTPUT: + Return as string representation. - String. + OUTPUT: string EXAMPLES:: @@ -217,7 +213,7 @@ def _repr_(self): def inner_html(self): """ - Return a HTML document containing a JSmol applet + Return a HTML document containing a JSmol applet. EXAMPLES:: @@ -243,11 +239,9 @@ def inner_html(self): def iframe(self): """ - Return HTML iframe + Return HTML iframe. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -266,11 +260,9 @@ def iframe(self): def outer_html(self): """ - Return a HTML document containing an iframe with a JSmol applet - - OUTPUT: + Return a HTML document containing an iframe with a JSmol applet. - String + OUTPUT: string EXAMPLES:: diff --git a/src/sage/repl/display/pretty_print.py b/src/sage/repl/display/pretty_print.py index 99bbe5013d0..0e4c1aec150 100644 --- a/src/sage/repl/display/pretty_print.py +++ b/src/sage/repl/display/pretty_print.py @@ -50,7 +50,7 @@ def toplevel(self): OUTPUT: - Boolean. Whether we are currently pretty-printing an object at + boolean; whether we are currently pretty-printing an object at the outermost level (``True``), or whether the object is inside a container (``False``). @@ -67,7 +67,7 @@ def toplevel(self): def __init__(self, output, max_width, newline, max_seq_length=None): """ - Pretty print Sage objects for the commandline + Pretty print Sage objects for the commandline. INPUT: @@ -111,17 +111,15 @@ def __init__(self, output, max_width, newline, max_seq_length=None): def pretty(self, obj): r""" - Pretty print ``obj`` + Pretty print ``obj``. This is the only method that outside code should invoke. INPUT: - - ``obj`` -- anything. + - ``obj`` -- anything - OUTPUT: - - String representation for object. + OUTPUT: string representation for object EXAMPLES:: diff --git a/src/sage/repl/display/util.py b/src/sage/repl/display/util.py index e222351a74e..5b931a67673 100644 --- a/src/sage/repl/display/util.py +++ b/src/sage/repl/display/util.py @@ -16,9 +16,9 @@ # **************************************************************************** -class TallListFormatter(): +class TallListFormatter: """ - Special representation for lists with tall entries (e.g. matrices) + Special representation for lists with tall entries (e.g. matrices). .. automethod:: __call__ """ @@ -28,7 +28,7 @@ class TallListFormatter(): def _tall_list_row(self, running_lines, last_row=False): """ - Helper for :meth:`_check_tall_list_and_format` + Helper for :meth:`_check_tall_list_and_format`. This helper function processes and outputs the contents of the running_lines array. @@ -64,7 +64,7 @@ def try_format(self, the_list): INPUT: - - ``the_list`` -- The list (or a tuple). + - ``the_list`` -- the list (or a tuple) OUTPUT: @@ -144,11 +144,9 @@ def __call__(self, the_list): INPUT: - - ``the_list`` -- list or tuple. + - ``the_list`` -- list or tuple - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: diff --git a/src/sage/repl/image.py b/src/sage/repl/image.py index 2170d216caa..06a6f6a671a 100644 --- a/src/sage/repl/image.py +++ b/src/sage/repl/image.py @@ -43,7 +43,7 @@ class Image(SageObject): def __init__(self, mode, size, color='white'): """ - Creates a new image with the given mode and size. + Create a new image with the given mode and size. INPUT: @@ -76,7 +76,7 @@ def __init__(self, mode, size, color='white'): * ``'F'`` (32-bit floating point pixels) - - ``size`` -- 2-tuple, containing (width, height) in pixels. + - ``size`` -- 2-tuple, containing (width, height) in pixels - ``color`` -- string, numeric or tuple of numeric. What colour to use for the image. Default is black. If given, this should be a @@ -85,9 +85,7 @@ def __init__(self, mode, size, color='white'): ImageColor module. If the colour is None, the image is not initialised. - OUTPUT: - - A new :class:`Image` object. + OUTPUT: a new :class:`Image` object EXAMPLES:: @@ -106,11 +104,9 @@ def __init__(self, mode, size, color='white'): @property def pil(self): """ - Access the wrapped PIL(low) Image - - OUTPUT: + Access the wrapped PIL(low) Image. - The underlying ``PIL.Image.Image object``. + OUTPUT: the underlying ``PIL.Image.Image object`` EXAMPLES:: @@ -123,7 +119,7 @@ def pil(self): def pixels(self): """ - Return the pixel map + Return the pixel map. OUTPUT: @@ -139,13 +135,11 @@ def pixels(self): """ return self._pil.load() - def _repr_(self): + def _repr_(self) -> str: """ Return string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -154,17 +148,17 @@ def _repr_(self): 16x16px 24-bit RGB image """ modestr = { - '1': '{0}x{1}px BW image', - 'L': '{0}x{1}px 8-bit BW image', - 'P': '{0}x{1}px 8-bit Color image', - 'RGB': '{0}x{1}px 24-bit RGB image', - 'RGBA': '{0}x{1}px 32-bit RGBA image', - 'CMYK': '{0}x{1}px 24-bit CMYK image', + '1': '{0}x{1}px BW image', + 'L': '{0}x{1}px 8-bit BW image', + 'P': '{0}x{1}px 8-bit Color image', + 'RGB': '{0}x{1}px 24-bit RGB image', + 'RGBA': '{0}x{1}px 32-bit RGBA image', + 'CMYK': '{0}x{1}px 24-bit CMYK image', 'YCbCr': '{0}x{1}px 24-bit YCbCr mage', - 'LAB': '{0}x{1}px 24-bit LAB image', - 'HSV': '{0}x{1}px 24-bit HSV image', - 'I': '{0}x{1}px 32-bit signed integer image', - 'F': '{0}x{1}px 32-bit float image', + 'LAB': '{0}x{1}px 24-bit LAB image', + 'HSV': '{0}x{1}px 24-bit HSV image', + 'I': '{0}x{1}px 32-bit signed integer image', + 'F': '{0}x{1}px 32-bit float image', } try: mode = modestr[self.pil.mode] @@ -175,11 +169,9 @@ def _repr_(self): def mode(self): """ - Return the color mode + Return the color mode. - OUTPUT: - - String. As given when constructing the image. + OUTPUT: string; as given when constructing the image EXAMPLES:: @@ -192,11 +184,9 @@ def mode(self): def width(self): """ - Return the horizontal dimension in pixels - - OUTPUT: + Return the horizontal dimension in pixels. - Integer. + OUTPUT: integer EXAMPLES:: @@ -211,11 +201,9 @@ def width(self): def height(self): """ - Return the vertical dimension in pixels - - OUTPUT: + Return the vertical dimension in pixels. - Integer. + OUTPUT: integer EXAMPLES:: @@ -230,12 +218,12 @@ def height(self): def save(self, filename): r""" - Save the bitmap image + Save the bitmap image. INPUT: - - ``filename`` -- string. The filename to save as. The given - extension automatically determines the image file type. + - ``filename`` -- string; the filename to save as. The given + extension automatically determines the image file type EXAMPLES:: @@ -276,7 +264,7 @@ def show(self): def _rich_repr_(self, display_manager, **kwds): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -297,9 +285,9 @@ def _rich_repr_(self, display_manager, **kwds): return types = display_manager.types preferred = ( - ('PNG', types.OutputImagePng), + ('PNG', types.OutputImagePng), ('JPEG', types.OutputImageJpg), - ('GIF', types.OutputImageGif), + ('GIF', types.OutputImageGif), ) from sage.repl.rich_output.buffer import OutputBuffer for format, output_container in preferred: diff --git a/src/sage/repl/inputhook.py b/src/sage/repl/inputhook.py index 99fb4a0c871..ad87af73ea1 100644 --- a/src/sage/repl/inputhook.py +++ b/src/sage/repl/inputhook.py @@ -48,7 +48,7 @@ def sage_inputhook(context): def install(): """ - Install the Sage input hook + Install the Sage input hook. EXAMPLES: @@ -75,7 +75,7 @@ def install(): def uninstall(): """ - Uninstall the Sage input hook + Uninstall the Sage input hook. EXAMPLES:: diff --git a/src/sage/repl/interface_magic.py b/src/sage/repl/interface_magic.py index b60355f5cae..d4c28dc49ac 100644 --- a/src/sage/repl/interface_magic.py +++ b/src/sage/repl/interface_magic.py @@ -80,12 +80,12 @@ """ -class InterfaceMagic(): +class InterfaceMagic: @classmethod def all_iter(cls): """ - Iterate over the available interfaces + Iterate over the available interfaces. EXAMPLES:: @@ -104,7 +104,7 @@ def all_iter(cls): @classmethod def register_all(cls, shell=None): """ - Register all available interfaces + Register all available interfaces. EXAMPLES:: @@ -144,18 +144,15 @@ def register_all(cls, shell=None): @classmethod def find(cls, name): """ - Find a particular magic by name + Find a particular magic by name. This method is for doctesting purposes only. INPUT: - - ``name`` -- string. The name of the interface magic to - search for. + - ``name`` -- string; the name of the interface magic to search for - OUTPUT: - - The corresponding :class:`InterfaceMagic` instance. + OUTPUT: the corresponding :class:`InterfaceMagic` instance EXAMPLES:: @@ -169,17 +166,17 @@ def find(cls, name): def __init__(self, name, interface): """ - Interface Magic + Interface Magic. This class is a wrapper around interface objects to provide them with magics. INPUT: - - ``name`` -- string. The interface name + - ``name`` -- string; the interface name - - ``interface`` -- :class:`sage.interfaces.expect.Expect`. The - interface to wrap. + - ``interface`` -- :class:`sage.interfaces.expect.Expect`; the + interface to wrap EXAMPLES:: @@ -192,11 +189,9 @@ def __init__(self, name, interface): def line_magic_factory(self): """ - Factory for line magic - - OUTPUT: + Factory for line magic. - A function suitable to be used as line magic. + OUTPUT: a function suitable to be used as line magic EXAMPLES:: @@ -237,11 +232,9 @@ def line_magic(line): def cell_magic_factory(self): r""" - Factory for cell magic + Factory for cell magic. - OUTPUT: - - A function suitable to be used as cell magic. + OUTPUT: a function suitable to be used as cell magic EXAMPLES:: @@ -278,23 +271,21 @@ def cell_magic_factory(self): """ def cell_magic(line, cell): """ - Evaluate cell magic + Evaluate cell magic. - Docstring is overwritten in the instance + Docstring is overwritten in the instance. INPUT: - - ``line`` -- string. The option part of the cell magic. - - - ``cell`` -- string. The lines of the cell magic. + - ``line`` -- string; the option part of the cell magic - OUTPUT: + - ``cell`` -- string; the lines of the cell magic - Prints the interface output. + OUTPUT: prints the interface output RAISES: - ``SyntaxError`` if a line is specified; Interfaces have no + :exc:`SyntaxError` if a line is specified; Interfaces have no options. """ if line: diff --git a/src/sage/repl/interpreter.py b/src/sage/repl/interpreter.py index 84af28f8cf7..3a269592917 100644 --- a/src/sage/repl/interpreter.py +++ b/src/sage/repl/interpreter.py @@ -75,13 +75,14 @@ sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() - sage: print("dummy line"); shell.run_cell('1/0') # see #25320 for the reason of the `...` and the dummy line in this test + sage: print("dummy line"); shell.run_cell('1/0') # known bug (meson doesn't include the Cython source code) # see #25320 for the reason of the `...` and the dummy line in this test dummy line ... ZeroDivisionError...Traceback (most recent call last) ... ----> 1 Integer(1)/Integer(0) - .../sage/rings/integer.pyx... in sage.rings.integer.Integer...div... + ... + ...integer.pyx... in sage.rings.integer.Integer...div... ... -> ... raise ZeroDivisionError("rational division by zero") ....: x = Rational.__new__(Rational) @@ -177,8 +178,7 @@ def preparser(on=True): """ Turn on or off the Sage preparser. - :keyword on: if True turn on preparsing; if False, turn it off. - :type on: bool + - ``on`` -- boolean; whether to turn on preparsing EXAMPLES:: @@ -198,7 +198,7 @@ def preparser(on=True): ############################## # Sage[Terminal]InteractiveShell ############################## -class SageShellOverride(): +class SageShellOverride: """ Mixin to override methods in IPython's [Terminal]InteractiveShell classes. @@ -247,7 +247,7 @@ def system_raw(self, cmd): class SageNotebookInteractiveShell(SageShellOverride, InteractiveShell): """ - IPython Shell for the Sage IPython Notebook + IPython Shell for the Sage IPython Notebook. The doctests are not tested since they would change the current rich output backend away from the doctest rich output backend. @@ -261,7 +261,7 @@ class SageNotebookInteractiveShell(SageShellOverride, InteractiveShell): def init_display_formatter(self): """ - Switch to the Sage IPython notebook rich output backend + Switch to the Sage IPython notebook rich output backend. EXAMPLES:: @@ -275,7 +275,7 @@ def init_display_formatter(self): class SageTerminalInteractiveShell(SageShellOverride, TerminalInteractiveShell): """ - IPython Shell for the Sage IPython Commandline Interface + IPython Shell for the Sage IPython Commandline Interface. The doctests are not tested since they would change the current rich output backend away from the doctest rich output backend. @@ -289,7 +289,7 @@ class SageTerminalInteractiveShell(SageShellOverride, TerminalInteractiveShell): def init_display_formatter(self): """ - Switch to the Sage IPython commandline rich output backend + Switch to the Sage IPython commandline rich output backend. EXAMPLES:: @@ -313,9 +313,10 @@ def prompt_for_code(self): pythonapi.PyOS_setsig(signal.SIGINT, sigint_os) return text + class SageTestShell(SageShellOverride, TerminalInteractiveShell): """ - Test Shell + Test Shell. Care must be taken in these doctests to quit the test shell in order to switch back the rich output display backend to the @@ -331,7 +332,7 @@ class SageTestShell(SageShellOverride, TerminalInteractiveShell): def init_display_formatter(self): """ - Switch to the Sage IPython commandline rich output backend + Switch to the Sage IPython commandline rich output backend. EXAMPLES:: @@ -395,13 +396,12 @@ def _restart(self): def run_cell(self, *args, **kwds): """ - Run IPython cell + Run IPython cell. Starting with IPython-3.0, this returns an success/failure information. Since it is more convenient for doctests, we ignore it. - EXAMPLES:: sage: from sage.repl.interpreter import get_test_shell @@ -464,7 +464,6 @@ def SagePreparseTransformer(lines): So when debugging the preparser, print outs may be duplicated. If using IPython >= 7.17, try: ``sage.repl.interpreter.SagePreparseTransformer.has_side_effects = True`` - """ if _do_preparse: # IPython ensures the input lines end with a newline, and it expects @@ -556,8 +555,7 @@ def preparse_imports_from_sage(self, line): ``maxima(object)`` if :attr:`shell.interface` is ``maxima``. - :param line: the line to transform - :type line: string + - ``line`` -- string; the line to transform EXAMPLES:: @@ -610,10 +608,9 @@ def transform(self, line, continue_prompt): Evaluates *line* in :attr:`shell.interface` and returns a string representing the result of that evaluation. - :param line: the line to be transformed *and evaluated* - :type line: string - :param continue_prompt: is this line a continuation in a sequence of multiline input? - :type continue_prompt: bool + - ``line`` -- string; the line to be transformed *and evaluated* + - ``continue_prompt`` -- boolean; whether this line is a continuation in a + sequence of multiline input EXAMPLES:: @@ -668,14 +665,14 @@ def transform(self, line, continue_prompt): def interface_shell_embed(interface): """ - Returns an IPython shell which uses a Sage interface on the + Return an IPython shell which uses a Sage interface on the backend to perform the evaluations. It uses :class:`InterfaceShellTransformer` to transform the input into the appropriate ``interface.eval(...)`` input. INPUT: - - ``interface`` -- A Sage ``PExpect`` interface instance. + - ``interface`` -- a Sage ``PExpect`` interface instance EXAMPLES:: @@ -709,9 +706,7 @@ def get_test_shell(): Return a IPython shell that can be used in testing the functions in this module. - OUTPUT: - - An IPython shell + OUTPUT: an IPython shell EXAMPLES:: @@ -794,7 +789,7 @@ def load_config_file(self, *args, **kwds): r""" Merges a config file with the default sage config. - .. note:: + .. NOTE:: This code is based on :meth:`Application.update_config`. @@ -821,7 +816,7 @@ def init_shell(self): r""" Initialize the :class:`SageInteractiveShell` instance. - .. note:: + .. NOTE:: This code is based on :meth:`TerminalIPythonApp.init_shell`. diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index a7fccf9aa99..b6fc42bbb37 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -71,17 +71,18 @@ from sage.misc.lazy_import import LazyImport from sage.misc.misc import run_once + @magics_class class SageMagics(Magics): @line_magic def crun(self, s): r""" - Profile C function calls + Profile C function calls. INPUT: - - ``s`` -- string. Sage command to profile. + - ``s`` -- string; Sage command to profile EXAMPLES:: @@ -104,7 +105,7 @@ def runfile(self, s): This is designed to be used from the command line as ``%runfile /path/to/file``. - - ``s`` -- string. The file to be loaded. + - ``s`` -- string; the file to be loaded EXAMPLES:: @@ -137,7 +138,7 @@ def attach(self, s): sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: from tempfile import NamedTemporaryFile as NTF - sage: with NTF(mode="w+t", suffix=".py", delete=False) as f: + sage: with NTF(mode='w+t', suffix='.py', delete=False) as f: ....: _ = f.write('a = 2\n') sage: shell.run_cell('%attach ' + f.name) sage: shell.run_cell('a') @@ -169,7 +170,7 @@ def iload(self, args): - ``args`` -- string. The file to be interactively loaded - .. note:: + .. NOTE:: Currently, this cannot be completely doctested as it relies on :func:`raw_input`. @@ -334,20 +335,18 @@ def display(self, args): @cell_magic def cython(self, line, cell): """ - Cython cell magic + Cython cell magic. This is syntactic sugar on the :func:`~sage.misc.cython.cython_compile` function. INPUT: - - ``line`` -- ignored. - - - ``cell`` -- string. The Cython source code to process. + - ``line`` -- ignored - OUTPUT: + - ``cell`` -- string; the Cython source code to process - None. The Cython code is compiled and loaded. + OUTPUT: none; the Cython code is compiled and loaded EXAMPLES:: @@ -375,13 +374,11 @@ def fortran(self, line, cell): INPUT: - - ``line`` -- ignored. - - - ``cell`` -- string. The Cython source code to process. + - ``line`` -- ignored - OUTPUT: + - ``cell`` -- string; the Cython source code to process - None. The Fortran code is compiled and loaded. + OUTPUT: none; the Fortran code is compiled and loaded EXAMPLES:: @@ -421,7 +418,7 @@ def fortran(self, line, cell): return fortran(cell) -class SageCustomizations(): +class SageCustomizations: def __init__(self, shell=None): """ @@ -488,7 +485,7 @@ def run_init(self): Run Sage's initial startup file. """ try: - with open(SAGE_STARTUP_FILE, 'r') as f: + with open(SAGE_STARTUP_FILE) as f: self.shell.run_cell(f.read(), store_history=False) except OSError: pass diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py index e476efe22b9..0b340e86238 100644 --- a/src/sage/repl/ipython_kernel/install.py +++ b/src/sage/repl/ipython_kernel/install.py @@ -26,11 +26,11 @@ ) -class SageKernelSpec(): +class SageKernelSpec: def __init__(self, prefix=None): """ - Utility to manage SageMath kernels and extensions + Utility to manage SageMath kernels and extensions. INPUT: @@ -57,7 +57,7 @@ def __init__(self, prefix=None): def _mkdirs(self): """ - Create necessary parent directories + Create necessary parent directories. EXAMPLES:: @@ -79,9 +79,9 @@ def mkdir_p(path): @classmethod def identifier(cls): """ - Internal identifier for the SageMath kernel + Internal identifier for the SageMath kernel. - OUTPUT: the string ``"sagemath"``. + OUTPUT: the string ``'sagemath'`` EXAMPLES:: @@ -93,7 +93,7 @@ def identifier(cls): def symlink(self, src, dst): """ - Symlink ``src`` to ``dst`` + Symlink ``src`` to ``dst``. This is not an atomic operation. @@ -141,9 +141,7 @@ def _kernel_cmd(self): """ Helper to construct the SageMath kernel command. - OUTPUT: - - List of strings. The command to start a new SageMath kernel. + OUTPUT: list of strings; the command to start a new SageMath kernel EXAMPLES:: @@ -166,11 +164,9 @@ def _kernel_cmd(self): def kernel_spec(self): """ - Return the kernel spec as Python dictionary - - OUTPUT: + Return the kernel spec as Python dictionary. - A dictionary. See the Jupyter documentation for details. + OUTPUT: a dictionary; see the Jupyter documentation for details EXAMPLES:: @@ -187,14 +183,13 @@ def kernel_spec(self): def _install_spec(self): """ - Install the SageMath Jupyter kernel + Install the SageMath Jupyter kernel. EXAMPLES:: sage: from sage.repl.ipython_kernel.install import SageKernelSpec sage: spec = SageKernelSpec(prefix=tmp_dir()) sage: spec._install_spec() - """ jsonfile = os.path.join(self.kernel_dir, "kernel.json") import json @@ -203,7 +198,7 @@ def _install_spec(self): def _symlink_resources(self): """ - Symlink miscellaneous resources + Symlink miscellaneous resources. This method symlinks additional resources (like the SageMath documentation) into the SageMath kernel directory. This is @@ -215,7 +210,6 @@ def _symlink_resources(self): sage: spec = SageKernelSpec(prefix=tmp_dir()) sage: spec._install_spec() sage: spec._symlink_resources() - """ path = os.path.join(SAGE_EXTCODE, 'notebook-ipython') for filename in os.listdir(path): @@ -231,7 +225,7 @@ def _symlink_resources(self): @classmethod def update(cls, *args, **kwds): """ - Configure the Jupyter notebook for the SageMath kernel + Configure the Jupyter notebook for the SageMath kernel. This method does everything necessary to use the SageMath kernel, you should never need to call any of the other methods @@ -241,7 +235,6 @@ def update(cls, *args, **kwds): sage: from sage.repl.ipython_kernel.install import SageKernelSpec sage: SageKernelSpec.update(prefix=tmp_dir()) - """ instance = cls(*args, **kwds) instance.use_local_threejs() @@ -287,12 +280,10 @@ def have_prerequisites(debug=True): INPUT: - - ``debug`` -- boolean (default: ``True``). Whether to print debug - information in case that prerequisites are missing. - - OUTPUT: + - ``debug`` -- boolean (default: ``True``); whether to print debug + information in case that prerequisites are missing - Boolean. + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index a8167dcabd8..86e53412bc2 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -57,7 +57,7 @@ class sage_interactive(interactive): EXAMPLES:: sage: from sage.repl.ipython_kernel.interact import sage_interactive - sage: def myfunc(x=10, y="hello", z=None): pass + sage: def myfunc(x=10, y='hello', z=None): pass sage: sage_interactive(myfunc, x=(0,100), z=["one", "two", "three"]) ...Interactive function with 3 widgets x: IntSlider(value=10, description='x') @@ -66,7 +66,7 @@ class sage_interactive(interactive): """ def __init__(self, *args, **kwds): """ - See :class:`ipywidgets.widgets.interaction.interactive` + See :class:`ipywidgets.widgets.interaction.interactive`. TESTS:: diff --git a/src/sage/repl/ipython_kernel/kernel.py b/src/sage/repl/ipython_kernel/kernel.py index a9931f8b9cf..dc414ea2aab 100644 --- a/src/sage/repl/ipython_kernel/kernel.py +++ b/src/sage/repl/ipython_kernel/kernel.py @@ -48,11 +48,11 @@ class SageKernel(IPythonKernel): def __init__(self, **kwds): """ - The Sage Jupyter Kernel + The Sage Jupyter Kernel. INPUT: - See the Jupyter documentation + See the Jupyter documentation. EXAMPLES:: @@ -66,14 +66,12 @@ def __init__(self, **kwds): @property def banner(self): r""" - The Sage Banner + The Sage Banner. The value of this property is displayed in the Jupyter notebook. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -88,11 +86,9 @@ def banner(self): @property def help_links(self): r""" - Help in the Jupyter Notebook + Help in the Jupyter Notebook. - OUTPUT: - - See the Jupyter documentation. + OUTPUT: see the Jupyter documentation EXAMPLES:: diff --git a/src/sage/repl/ipython_kernel/widgets.py b/src/sage/repl/ipython_kernel/widgets.py index f3ac6a35ccb..42d674b7c9a 100644 --- a/src/sage/repl/ipython_kernel/widgets.py +++ b/src/sage/repl/ipython_kernel/widgets.py @@ -84,7 +84,7 @@ def description(self, value): pass -class TransformWidget(): +class TransformWidget: """ A mixin class for a widget to transform the bare widget value for use in interactive functions. @@ -92,7 +92,7 @@ class TransformWidget(): INPUT: - ``transform`` -- a one-argument function which transforms the - value of the widget for use by an interactive function. + value of the widget for use by an interactive function - other arguments are passed to the base class @@ -133,7 +133,7 @@ def get_value(self): sage: from ipywidgets import ColorPicker sage: from sage.repl.ipython_kernel.widgets import TransformWidget sage: class TransformColorPicker(TransformWidget, ColorPicker): pass - sage: TransformColorPicker(value="red").get_value() + sage: TransformColorPicker(value='red').get_value() 'red' """ return self.value @@ -276,7 +276,7 @@ class TransformText(TransformWidget, Text): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import TransformText - sage: w = TransformText(value="hello", transform=lambda x: x + x) + sage: w = TransformText(value='hello', transform=lambda x: x + x) sage: w TransformText(value='hello') sage: w.get_interact_value() @@ -293,7 +293,7 @@ class TransformTextarea(TransformWidget, Textarea): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import TransformTextarea - sage: w = TransformTextarea(value="hello", transform=lambda x: x + x) + sage: w = TransformTextarea(value='hello', transform=lambda x: x + x) sage: w TransformTextarea(value='hello') sage: w.get_interact_value() @@ -310,7 +310,7 @@ class EvalText(EvalWidget, Text): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import EvalText - sage: w = EvalText(value="pi", transform=lambda x: x^2) + sage: w = EvalText(value='pi', transform=lambda x: x^2) sage: w EvalText(value='pi') sage: w.get_interact_value() # needs sage.symbolic @@ -327,7 +327,7 @@ class EvalTextarea(EvalWidget, Textarea): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import EvalTextarea - sage: w = EvalTextarea(value="pi", transform=lambda x: x^2) + sage: w = EvalTextarea(value='pi', transform=lambda x: x^2) sage: w EvalTextarea(value='pi') sage: w.get_interact_value() # needs sage.symbolic @@ -383,7 +383,7 @@ class Grid(TransformWidget, HBox, ValueWidget): value = List() description = Unicode() - def __init__(self, nrows, ncols, make_widget, description=u"", transform=None): + def __init__(self, nrows, ncols, make_widget, description="", transform=None): """ Create a :class:`Grid` widget. @@ -392,11 +392,11 @@ def __init__(self, nrows, ncols, make_widget, description=u"", transform=None): - ``nrows``, ``ncols`` -- number of rows and columns in the grid - ``make_widget`` -- a function of two arguments ``(i,j)`` - returning the widget to be placed at position ``(i,j)``. + returning the widget to be placed at position ``(i,j)`` - - ``description`` -- an optional label. + - ``description`` -- an optional label - - ``transform`` -- an optional transformation, see :class:`TransformWidget`. + - ``transform`` -- an optional transformation, see :class:`TransformWidget` EXAMPLES:: @@ -431,7 +431,7 @@ def __init__(self, nrows, ncols, make_widget, description=u"", transform=None): widgets = [] for i in range(nrows): w = make_widget(i, j) - w.observe(self._update, names="value") + w.observe(self._update, names='value') widgets.append(w) col.children = widgets self.cols.append(col) diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py index 4d3b1dbdedc..aa146aa438a 100644 --- a/src/sage/repl/ipython_kernel/widgets_sagenb.py +++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py @@ -56,7 +56,7 @@ def input_box(default=None, label=None, type=None, width=80, height=1): - ``default`` -- initial value - - ``label`` -- optional label + - ``label`` -- (optional) - ``type`` -- function of one variable or ``None``. if ``type`` is ``str``, the value of this widget for interactive functions is @@ -68,7 +68,7 @@ def input_box(default=None, label=None, type=None, width=80, height=1): - ``width`` -- width of the box - ``height`` -- if ``height > 1``, create a textarea instead of a - single-line textbox. + single-line textbox EXAMPLES:: @@ -171,16 +171,15 @@ def slider(vmin, vmax=None, step_size=None, default=None, label=None, display_va For a selection slider (select a value from a list of values): - - ``vmin`` -- a list of possible values for the slider + - ``vmin`` -- list of possible values for the slider For all sliders: - ``default`` -- initial value - - ``label`` -- optional label + - ``label`` -- (optional) - - ``display_value`` -- (boolean) if ``True``, display the current - value. + - ``display_value`` -- boolean; if ``True``, display the current value EXAMPLES:: @@ -361,10 +360,9 @@ def range_slider(*args, **kwds): - ``default`` -- initial value, given as a 2-tuple - - ``label`` -- optional label + - ``label`` -- (optional) - - ``display_value`` -- (boolean) if ``True``, display the current - value. + - ``display_value`` -- boolean; if ``True``, display the current value EXAMPLES:: @@ -417,9 +415,9 @@ def checkbox(default=True, label=None): INPUT: - - ``default`` -- (boolean) initial value + - ``default`` -- boolean; initial value - - ``label`` -- optional label + - ``label`` -- (optional) EXAMPLES:: @@ -444,14 +442,14 @@ def selector(values, label=None, default=None, nrows=None, ncols=None, width=Non INPUT: - - ``values`` -- a list of values to choose from (see examples below + - ``values`` -- list of values to choose from (see examples below for the accepted formats for this) - - ``label`` -- optional label + - ``label`` -- (optional) - ``default`` -- initial value - - ``buttons`` -- (boolean) if True, display buttons instead of a + - ``buttons`` -- boolean; if ``True``, display buttons instead of a dropdown box EXAMPLES:: @@ -515,7 +513,7 @@ def input_grid(nrows, ncols, default=None, label=None, to_value=None, width=4): - ``default`` -- initial value (given as a list of lists, a single constant value or a flat list) - - ``label`` -- optional label + - ``label`` -- (optional) - ``to_value`` -- function to be called to get the value for interactive functions @@ -525,7 +523,7 @@ def input_grid(nrows, ncols, default=None, label=None, to_value=None, width=4): EXAMPLES:: sage: from sage.repl.ipython_kernel.all_jupyter import input_grid - sage: input_grid(2, 2, default=42, label="answers") + sage: input_grid(2, 2, default=42, label='answers') Grid(value=[[42, 42], [42, 42]], children=(Label(value='answers'), VBox(children=(EvalText(value='42', layout=Layout(max_width='5em')), EvalText(value='42', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='42', layout=Layout(max_width='5em')), EvalText(value='42', layout=Layout(max_width='5em')))))) sage: w = input_grid(2, 2, default=[[cos(x), sin(x)], [-sin(x), cos(x)]], to_value=matrix); w Grid(value=[[cos(x), sin(x)], [-sin(x), cos(x)]], children=(Label(value=''), VBox(children=(EvalText(value='cos(x)', layout=Layout(max_width='5em')), EvalText(value='-sin(x)', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='sin(x)', layout=Layout(max_width='5em')), EvalText(value='cos(x)', layout=Layout(max_width='5em')))))) @@ -567,9 +565,9 @@ def color_selector(default=(0, 0, 1), label=None, widget=None, hide_box=False): - ``default`` -- initial value - - ``label`` -- optional label + - ``label`` -- (optional) - - ``hide_box`` -- (boolean) if True, do not show the textbox + - ``hide_box`` -- boolean; if ``True``, do not show the textbox EXAMPLES:: diff --git a/src/sage/repl/ipython_tests.py b/src/sage/repl/ipython_tests.py index 12f03c20d7e..1e26d47717c 100644 --- a/src/sage/repl/ipython_tests.py +++ b/src/sage/repl/ipython_tests.py @@ -11,15 +11,15 @@ sage: shell.run_cell(u'%pinfo dummy') Signature: dummy(argument, optional=None) Docstring: - Dummy Docstring Title + Dummy Docstring Title. Dummy docstring explanation. INPUT: - ... "argument" -- anything. Dummy argument. + ... "argument" -- anything; dummy argument - ... "optional" -- anything (optional). Dummy optional. + ... "optional" -- anything (optional); dummy optional EXAMPLES... @@ -35,7 +35,7 @@ sage: shell.run_cell(u'from sage.tests.stl_vector import stl_int_vector') sage: shell.run_cell(u'%pinfo stl_int_vector') ... - Example class wrapping an STL vector + Example class wrapping an STL vector. EXAMPLES... @@ -73,15 +73,15 @@ Source: def dummy(argument, optional=None): """ - Dummy Docstring Title + Dummy Docstring Title. Dummy docstring explanation. INPUT: - - ``argument`` -- anything. Dummy argument. + - ``argument`` -- anything; dummy argument - - ``optional`` -- anything (optional). Dummy optional. + - ``optional`` -- anything (optional); dummy optional EXAMPLES:: @@ -100,7 +100,7 @@ def dummy(argument, optional=None): ... cdef class stl_int_vector(SageObject): """ - Example class wrapping an STL vector + Example class wrapping an STL vector. EXAMPLES:: @@ -144,15 +144,15 @@ def __cinit__(self): def dummy(argument, optional=None): """ - Dummy Docstring Title + Dummy Docstring Title. Dummy docstring explanation. INPUT: - - ``argument`` -- anything. Dummy argument. + - ``argument`` -- anything; dummy argument - - ``optional`` -- anything (optional). Dummy optional. + - ``optional`` -- anything (optional); dummy optional EXAMPLES:: diff --git a/src/sage/repl/load.py b/src/sage/repl/load.py index c7c014d2f8b..a1a1451f1c2 100644 --- a/src/sage/repl/load.py +++ b/src/sage/repl/load.py @@ -29,11 +29,9 @@ def is_loadable_filename(filename): INPUT: - - ``filename`` -- a string or :class:`Path` object + - ``filename`` -- string or :class:`Path` object - OUTPUT: - - - a boolean + OUTPUT: boolean EXAMPLES:: @@ -91,13 +89,13 @@ def load(filename, globals, attach=False): INPUT: - - ``filename`` -- a string (denoting a filename or URL) or a :class:`Path` object + - ``filename`` -- string (denoting a filename or URL) or a :class:`Path` object - - ``globals`` -- a string:object dictionary; the context in which - to execute the file contents. + - ``globals`` -- string:object dictionary; the context in which + to execute the file contents - - ``attach`` -- a boolean (default: ``False``); whether to add the - file to the list of attached files. + - ``attach`` -- boolean (default: ``False``); whether to add the + file to the list of attached files Loading an executable Sage script from the command prompt will run whatever code is inside an @@ -143,10 +141,10 @@ def load(filename, globals, attach=False): sage: z -7 - If the file is not a Cython, Python, or Sage file, a :class:`ValueError` + If the file is not a Cython, Python, or Sage file, a :exc:`ValueError` is raised:: - sage: sage.repl.load.load(tmp_filename(ext=".foo"), globals()) + sage: sage.repl.load.load(tmp_filename(ext='.foo'), globals()) Traceback (most recent call last): ... ValueError: unknown file extension '.foo' for load or attach (supported extensions: .py, .pyx, .sage, .spyx, .f, .f90, .m) @@ -301,13 +299,13 @@ def load_wrap(filename, attach=False): INPUT: - - ``filename`` -- a string or :class:`Path` object; the argument + - ``filename`` -- string or :class:`Path` object; the argument to the load or attach command - - ``attach`` -- a boolean (default: ``False``); whether to attach + - ``attach`` -- boolean (default: ``False``); whether to attach ``filename``, instead of loading it - OUTPUT: a string + OUTPUT: string EXAMPLES:: diff --git a/src/sage/repl/preparse.py b/src/sage/repl/preparse.py index 9b5dde719ce..02a6a51edf5 100644 --- a/src/sage/repl/preparse.py +++ b/src/sage/repl/preparse.py @@ -254,7 +254,7 @@ def implicit_multiplication(level=None): INPUT: - - ``level`` -- a boolean or integer (default: 5); how aggressive to be in + - ``level`` -- boolean or integer (default: 5); how aggressive to be in placing \*'s - 0 -- Do nothing @@ -263,9 +263,7 @@ def implicit_multiplication(level=None): - 3 -- Spaces between alphanumeric - 10 -- Adjacent parentheses (may mangle call statements) - OUTPUT: - - The current ``level`` if no argument is given. + OUTPUT: the current ``level`` if no argument is given EXAMPLES:: @@ -398,7 +396,7 @@ def pop(self): """ Remove and return the frame that was most recently added to the stack. - Raise an IndexError if the stack is empty. + Raise an :exc:`IndexError` if the stack is empty. EXAMPLES:: @@ -491,11 +489,11 @@ def __init__(self, delim, raw=False, f_string=False, braces=0, parens=0, bracket - ``delim`` -- string; the quote character(s) used: ``'``, ``"``, ``'''``, or ``\"\"\"`` - ``raw`` -- boolean (default: ``False``); whether we are in a raw string - ``f_string`` -- boolean (default: ``False``); whether we are in an F-string - - ``braces`` -- integer (default: ``0``); in an F-string, + - ``braces`` -- integer (default: 0); in an F-string, how many unclosed ``{``'s have we encountered? - - ``parens`` -- integer (default: ``0``); in a replacement section of an F-string + - ``parens`` -- integer (default: 0); in a replacement section of an F-string (``braces > 0``), how many unclosed ``(``'s have we encountered? - - ``brackets`` -- integer (default: ``0``); in a replacement section of an F-string + - ``brackets`` -- integer (default: 0); in a replacement section of an F-string (``braces > 0``), how many unclosed ``[``'s have we encountered? - ``fmt_spec`` -- boolean (default: ``False``); in the format specifier portion of a replacement section? @@ -530,7 +528,7 @@ def strip_string_literals(code, state=None): INPUT: - - ``code`` -- a string; the input + - ``code`` -- string; the input - ``state`` -- a :class:`QuoteStack` (default: ``None``); state with which to continue processing, e.g., across multiple calls to this function @@ -876,17 +874,17 @@ def containing_block(code, idx, delimiters=['()', '[]', '{}'], require_delim=Tru INPUT: - - ``code`` -- a string + - ``code`` -- string - - ``idx`` -- an integer; a starting position + - ``idx`` -- integer; a starting position - - ``delimiters`` -- a list of strings (default: ['()', '[]', + - ``delimiters`` -- list of strings (default: ['()', '[]', '{}']); the delimiters to balance. A delimiter must be a single character and no character can at the same time be opening and closing delimiter. - - ``require_delim`` -- a boolean (default: ``True``); whether to raise - a ``SyntaxError`` if delimiters are present. If the delimiters are + - ``require_delim`` -- boolean (default: ``True``); whether to raise + a :exc:`SyntaxError` if delimiters are present. If the delimiters are unbalanced, an error will be raised in any case. OUTPUT: @@ -894,7 +892,7 @@ def containing_block(code, idx, delimiters=['()', '[]', '{}'], require_delim=Tru - a 2-tuple ``(a,b)`` of integers, such that ``code[a:b]`` is delimited by balanced delimiters, ``a<=idx(?P\\\[|\\\()(?P.*)(?P\\\]|\\\))', flags=re.DOTALL) + class OutputHtml(OutputBase): def __init__(self, html): """ - HTML Output + HTML Output. INPUT: @@ -52,14 +53,12 @@ def __init__(self, html): @classmethod def example(cls): r""" - Construct a sample Html output container + Construct a sample Html output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputHtml`. + OUTPUT: an instance of :class:`OutputHtml` EXAMPLES:: @@ -88,7 +87,7 @@ def print_to_stdout(self): def with_html_tag(self): r""" - Return the HTML code surrounded by ```` tag + Return the HTML code surrounded by ```` tag. This is just a convenience method. diff --git a/src/sage/repl/rich_output/output_graphics.py b/src/sage/repl/rich_output/output_graphics.py index d8c29c553a7..dfef3a78696 100644 --- a/src/sage/repl/rich_output/output_graphics.py +++ b/src/sage/repl/rich_output/output_graphics.py @@ -26,7 +26,7 @@ class OutputImagePng(OutputBase): def __init__(self, png): """ - PNG Image + PNG Image. .. NOTE:: @@ -53,14 +53,12 @@ def __init__(self, png): @classmethod def example(cls): r""" - Construct a sample PNG output container + Construct a sample PNG output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputImagePng`. + OUTPUT: an instance of :class:`OutputImagePng` EXAMPLES:: @@ -79,7 +77,7 @@ class OutputImageGif(OutputBase): def __init__(self, gif): """ - GIF Image (possibly animated) + GIF Image (possibly animated). INPUT: @@ -101,14 +99,12 @@ def __init__(self, gif): @classmethod def example(cls): r""" - Construct a sample GIF output container + Construct a sample GIF output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputImageGif`. + OUTPUT: an instance of :class:`OutputImageGif` EXAMPLES:: @@ -124,13 +120,11 @@ def example(cls): def html_fragment(self): """ - Return a self-contained HTML fragment displaying the image + Return a self-contained HTML fragment displaying the image. This is a workaround for the Jupyter notebook which doesn't support GIF directly. - OUTPUT: - - String. HTML fragment for displaying the GIF image. + OUTPUT: string. HTML fragment for displaying the GIF image EXAMPLES:: @@ -146,7 +140,7 @@ class OutputImageJpg(OutputBase): def __init__(self, jpg): """ - JPEG Image + JPEG Image. INPUT: @@ -168,14 +162,12 @@ def __init__(self, jpg): @classmethod def example(cls): r""" - Construct a sample JPEG output container + Construct a sample JPEG output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputImageJpg`. + OUTPUT: an instance of :class:`OutputImageJpg` EXAMPLES:: @@ -194,7 +186,7 @@ class OutputImageSvg(OutputBase): def __init__(self, svg): """ - SVG Image + SVG Image. INPUT: @@ -216,14 +208,12 @@ def __init__(self, svg): @classmethod def example(cls): r""" - Construct a sample SVG output container + Construct a sample SVG output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputImageSvg`. + OUTPUT: an instance of :class:`OutputImageSvg` EXAMPLES:: @@ -242,7 +232,7 @@ class OutputImagePdf(OutputBase): def __init__(self, pdf): """ - PDF Image + PDF Image. INPUT: @@ -264,14 +254,12 @@ def __init__(self, pdf): @classmethod def example(cls): r""" - Construct a sample PDF output container + Construct a sample PDF output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputImagePdf`. + OUTPUT: an instance of :class:`OutputImagePdf` EXAMPLES:: @@ -290,7 +278,7 @@ class OutputImageDvi(OutputBase): def __init__(self, dvi): """ - DVI Image + DVI Image. INPUT: @@ -312,14 +300,12 @@ def __init__(self, dvi): @classmethod def example(cls): r""" - Construct a sample DVI output container + Construct a sample DVI output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputImageDvi`. + OUTPUT: an instance of :class:`OutputImageDvi` EXAMPLES:: diff --git a/src/sage/repl/rich_output/output_graphics3d.py b/src/sage/repl/rich_output/output_graphics3d.py index 3cf42fafb4a..5e3da996293 100644 --- a/src/sage/repl/rich_output/output_graphics3d.py +++ b/src/sage/repl/rich_output/output_graphics3d.py @@ -24,16 +24,16 @@ class OutputSceneJmol(OutputBase): def __init__(self, scene_zip, preview_png): """ - JMol Scene + JMol Scene. By our (Sage) convention, the actual scene is called ``SCENE`` inside the zip archive. INPUT: - - ``scene_zip`` -- string/bytes. The jmol scene (a zip archive). + - ``scene_zip`` -- string/bytes; the jmol scene (a zip archive) - - ``preview_png`` -- string/bytes. Preview as png file. + - ``preview_png`` -- string/bytes; preview as png file EXAMPLES:: @@ -53,9 +53,7 @@ def launch_script_filename(self): file. The launch script is often necessary to make jmol render the 3d scene. - OUTPUT: - - String. The file name of a suitable launch script. + OUTPUT: string; the file name of a suitable launch script EXAMPLES:: @@ -82,14 +80,12 @@ def launch_script_filename(self): @classmethod def example(cls): r""" - Construct a sample Jmol output container + Construct a sample Jmol output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputSceneJmol`. + OUTPUT: an instance of :class:`OutputSceneJmol` EXAMPLES:: @@ -116,11 +112,11 @@ class OutputSceneCanvas3d(OutputBase): def __init__(self, canvas3d): """ - Canvas3d Scene + Canvas3d Scene. INPUT: - - ``canvas3d`` -- string/bytes. The canvas3d data. + - ``canvas3d`` -- string/bytes; the canvas3d data EXAMPLES:: @@ -133,14 +129,12 @@ def __init__(self, canvas3d): @classmethod def example(cls): r""" - Construct a sample Canvas3D output container + Construct a sample Canvas3D output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputSceneCanvas3d`. + OUTPUT: an instance of :class:`OutputSceneCanvas3d` EXAMPLES:: @@ -161,11 +155,11 @@ class OutputSceneThreejs(OutputBase): def __init__(self, html): """ - Three.js Scene + Three.js Scene. INPUT: - - ``html`` -- string/bytes. The Three.js HTML data. + - ``html`` -- string/bytes; the Three.js HTML data EXAMPLES:: @@ -180,7 +174,7 @@ class OutputSceneWavefront(OutputBase): def __init__(self, obj, mtl): """ - Wavefront `*.obj` Scene + Wavefront `*.obj` Scene. The Wavefront format consists of two files, an ``.obj`` file defining the geometry data (mesh points, normal vectors, ...) @@ -188,11 +182,11 @@ def __init__(self, obj, mtl): INPUT: - - ``obj`` -- bytes. The Wavefront obj file format describing - the mesh shape. + - ``obj`` -- bytes; the Wavefront obj file format describing + the mesh shape - - ``mtl`` -- bytes. The Wavefront mtl file format describing - textures. + - ``mtl`` -- bytes; the Wavefront mtl file format describing + textures EXAMPLES:: @@ -214,11 +208,11 @@ def _check_no_directory(self, filename): INPUT: - - ``filename`` -- string. A filename. + - ``filename`` -- string; a filename OUTPUT: - This method returns nothing. A ``ValueError`` is raised if + This method returns nothing. A :exc:`ValueError` is raised if ``filename`` is not just a plain filename but contains a directory (relative or absolute). @@ -246,7 +240,7 @@ def _check_no_directory(self, filename): def mtllib(self): """ - Return the ``mtllib`` filename + Return the ``mtllib`` filename. The ``mtllib`` line in the Wavefront file format (``*.obj``) is the name of the separate texture file. @@ -272,7 +266,7 @@ def mtllib(self): def obj_filename(self): """ - Return the file name of the ``.obj`` file + Return the file name of the ``.obj`` file. This method saves the object and texture to separate files in a temporary directory and returns the object file name. This @@ -321,14 +315,12 @@ def obj_filename(self): @classmethod def example(cls): r""" - Construct a sample Canvas3D output container + Construct a sample Canvas3D output container. This static method is meant for doctests, so they can easily construct an example. - OUTPUT: - - An instance of :class:`OutputSceneCanvas3d`. + OUTPUT: an instance of :class:`OutputSceneCanvas3d` EXAMPLES:: diff --git a/src/sage/repl/rich_output/output_video.py b/src/sage/repl/rich_output/output_video.py index 5171ac058ae..e1c25a3fca5 100644 --- a/src/sage/repl/rich_output/output_video.py +++ b/src/sage/repl/rich_output/output_video.py @@ -22,14 +22,13 @@ class OutputVideoBase(OutputBase): def __init__(self, video, loop=True): """ - Abstract base class for rich video output + Abstract base class for rich video output. INPUT: - - ``video`` -- - :class:`~sage.repl.rich_output.buffer.OutputBuffer`. - The video data. - - ``loop`` -- boolean. Whether to repeat the video in an endless loop. + - ``video`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`; + the video data + - ``loop`` -- boolean; whether to repeat the video in an endless loop EXAMPLES:: @@ -44,16 +43,14 @@ def __init__(self, video, loop=True): @classmethod def example(cls): r""" - Construct a sample video output container + Construct a sample video output container. This static method is meant for doctests, so they can easily construct an example. The method is implemented in the abstract :class:`OutputVideoBase` class, but should get invoked on a concrete subclass for which an actual example can exist. - OUTPUT: - - An instance of the class on which this method is called. + OUTPUT: an instance of the class on which this method is called EXAMPLES:: @@ -73,14 +70,14 @@ def example(cls): def html_fragment(self, url, link_attrs=''): r""" - Construct a HTML fragment for embedding this video + Construct a HTML fragment for embedding this video. INPUT: - - ``url`` -- string. The URL where the data of this video can be found. + - ``url`` -- string; the URL where the data of this video can be found - - ``link_attrs`` -- string. Can be used to style the fallback link - which is presented to the user if the video is not supported. + - ``link_attrs`` -- string; can be used to style the fallback link + which is presented to the user if the video is not supported EXAMPLES:: @@ -114,7 +111,7 @@ def html_fragment(self, url, link_attrs=''): class OutputVideoOgg(OutputVideoBase): """ - Ogg video, Ogg Theora in particular + Ogg video, Ogg Theora in particular. EXAMPLES:: @@ -129,7 +126,7 @@ class OutputVideoOgg(OutputVideoBase): class OutputVideoWebM(OutputVideoBase): """ - WebM video + WebM video. The video can be encoded using VP8, VP9 or an even more recent codec. @@ -146,7 +143,7 @@ class OutputVideoWebM(OutputVideoBase): class OutputVideoMp4(OutputVideoBase): """ - MPEG 4 video + MPEG 4 video. EXAMPLES:: @@ -161,7 +158,7 @@ class OutputVideoMp4(OutputVideoBase): class OutputVideoFlash(OutputVideoBase): """ - Flash video + Flash video. EXAMPLES:: @@ -176,7 +173,7 @@ class OutputVideoFlash(OutputVideoBase): class OutputVideoMatroska(OutputVideoBase): """ - Matroska Video + Matroska Video. EXAMPLES:: @@ -191,7 +188,7 @@ class OutputVideoMatroska(OutputVideoBase): class OutputVideoAvi(OutputVideoBase): """ - AVI video + AVI video. EXAMPLES:: @@ -206,7 +203,7 @@ class OutputVideoAvi(OutputVideoBase): class OutputVideoWmv(OutputVideoBase): """ - Windows Media Video + Windows Media Video. EXAMPLES:: @@ -221,7 +218,7 @@ class OutputVideoWmv(OutputVideoBase): class OutputVideoQuicktime(OutputVideoBase): """ - Quicktime video + Quicktime video. EXAMPLES:: diff --git a/src/sage/repl/rich_output/preferences.py b/src/sage/repl/rich_output/preferences.py index 00cb5ec2ab6..24b35499a8b 100644 --- a/src/sage/repl/rich_output/preferences.py +++ b/src/sage/repl/rich_output/preferences.py @@ -83,15 +83,15 @@ class Property(property): def __init__(self, name, allowed_values, doc=None): r""" - Preference item + Preference item. INPUT: - - ``name`` -- string. The name of the property. + - ``name`` -- string; the name of the property - - ``allowed_values`` -- list/tuple/iterable of allowed values. + - ``allowed_values`` -- list/tuple/iterable of allowed values - - ``doc`` -- string (optional). The docstring of the property. + - ``doc`` -- string (optional); the docstring of the property EXAMPLES:: @@ -115,12 +115,12 @@ def _make_doc(self, doc): INPUT: - - ``doc`` -- the title line of the documentation. + - ``doc`` -- the title line of the documentation OUTPUT: - String. The docstring with auto-generated documentation about - the allowed values added. + string; the docstring with auto-generated documentation about + the allowed values added EXAMPLES:: @@ -149,11 +149,9 @@ def _make_doc(self, doc): def __repr__(self): """ - Return a string representation + Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -166,16 +164,14 @@ def __repr__(self): def getter(self, prefs): """ - Get the current value of the property + Get the current value of the property. INPUT: - ``prefs`` -- the :class:`PreferencesABC` instance that the - property is bound to. - - OUTPUT: + property is bound to - One of the allowed values or ``None`` if not set. + OUTPUT: one of the allowed values or ``None`` if not set EXAMPLES:: @@ -195,12 +191,12 @@ def getter(self, prefs): def setter(self, prefs, value): """ - Get the current value of the property + Get the current value of the property. INPUT: - ``prefs`` -- the :class:`PreferencesABC` instance that the - property is bound to. + property is bound to - ``value`` -- anything. The new value of the property. Setting a property to ``None`` is equivalent to @@ -208,7 +204,7 @@ def setter(self, prefs, value): OUTPUT: - This method does not return anything. A ``ValueError`` is + This method does not return anything. A :exc:`ValueError` is raised if the given ``value`` is not one of the allowed values. @@ -237,12 +233,12 @@ def setter(self, prefs, value): def deleter(self, prefs): """ - Delete the current value of the property + Delete the current value of the property. INPUT: - ``prefs`` -- the :class:`PreferencesABC` instance that the - property is bound to. + property is bound to EXAMPLES:: @@ -267,7 +263,7 @@ class PreferencesABC(SageObject): def __init__(self, *args, **kwds): """ - Preferences for displaying graphics + Preferences for displaying graphics. These can be preferences expressed by the user or by the display backend. They are specified as keyword arguments. @@ -279,8 +275,8 @@ def __init__(self, *args, **kwds): to right, that is, later parents override values from earlier parents. - - ``**kwds`` -- keyword arguments. Will be used to initialize - properties, and override inherited values if necessary. + - ``**kwds`` -- keyword arguments; will be used to initialize + properties, and override inherited values if necessary EXAMPLES:: @@ -331,11 +327,11 @@ def _add_option(cls, name, values, doc): INPUT: - - ``name`` -- the name of the option. + - ``name`` -- the name of the option - - ``values`` -- the allowed values. + - ``values`` -- the allowed values - - ``doc`` -- docstring. + - ``doc`` -- docstring EXAMPLES:: @@ -354,12 +350,11 @@ def _add_option(cls, name, values, doc): def available_options(self): """ - Return the available options + Return the available options. OUTPUT: - Tuple of the preference items as instances of - :class:`Property`. + tuple of the preference items as instances of :class:`Property` EXAMPLES:: @@ -368,18 +363,16 @@ def available_options(self): (align_latex, graphics, supplemental_plot, text) """ options = [] - for key, value in self.__class__.__dict__.items(): + for value in self.__class__.__dict__.values(): if isinstance(value, Property): options.append(value) return tuple(sorted(options, key=str)) def _repr_(self): r""" - Return a string representation - - OUTPUT: + Return a string representation. - String. + OUTPUT: string EXAMPLES:: diff --git a/src/sage/repl/rich_output/pretty_print.py b/src/sage/repl/rich_output/pretty_print.py index 2cb113b230a..93833e01cd8 100644 --- a/src/sage/repl/rich_output/pretty_print.py +++ b/src/sage/repl/rich_output/pretty_print.py @@ -84,15 +84,15 @@ def __init__(self, *args, **kwds): def is_homogeneous(self, common_type): """ - Return whether the pretty print items are homogeneous + Return whether the pretty print items are homogeneous. INPUT: - - ``common_type`` -- a type. + - ``common_type`` -- a type OUTPUT: - Boolean. Whether all items to be pretty printed are of said + boolean; whether all items to be pretty printed are of said type. EXAMPLES:: @@ -108,11 +108,9 @@ def is_homogeneous(self, common_type): def _concatenate_graphs(self): """ - Plot multiple graphs into a single plot + Plot multiple graphs into a single plot. - OUTPUT: - - A graphics object. + OUTPUT: a graphics object EXAMPLES:: @@ -128,11 +126,9 @@ def _concatenate_graphs(self): def _concatenate_graphics(self): """ - Combine multiple graphics objects into one graphics array - - OUTPUT: + Combine multiple graphics objects into one graphics array. - A graphics array. + OUTPUT: a graphics array EXAMPLES:: @@ -210,8 +206,8 @@ def pretty_print(*args, **kwds): INPUT: - - ``*args`` -- any number of positional arguments. The objects to - pretty print. + - ``*args`` -- any number of positional arguments; the objects to + pretty print - ``**kwds`` -- optional keyword arguments that are passed to the rich representation. Examples include: @@ -224,7 +220,7 @@ def pretty_print(*args, **kwds): - ``fontsize`` -- positive integer - - ``frame`` -- (default: ``False``) draw a MATLAB-like frame around + - ``frame`` -- boolean (default: ``False``); draw a MATLAB-like frame around the image EXAMPLES:: diff --git a/src/sage/repl/rich_output/test_backend.py b/src/sage/repl/rich_output/test_backend.py index a08d75624e1..133fb35ae5d 100644 --- a/src/sage/repl/rich_output/test_backend.py +++ b/src/sage/repl/rich_output/test_backend.py @@ -95,11 +95,9 @@ class TestObject(SageObject): def _repr_(self): """ - Return string representation + Return string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -112,7 +110,7 @@ def _repr_(self): def _rich_repr_(self, display_manager): """ - Rich Output Magic Method + Rich Output Magic Method. See :mod:`sage.repl.rich_output` for details. @@ -135,11 +133,9 @@ class BackendTest(BackendBase): def _repr_(self): """ - Return the string representation - - OUTPUT: + Return the string representation. - String. + OUTPUT: string EXAMPLES:: diff --git a/src/sage/repl/user_globals.py b/src/sage/repl/user_globals.py index dfbdc7f72ef..444c0af1405 100644 --- a/src/sage/repl/user_globals.py +++ b/src/sage/repl/user_globals.py @@ -68,7 +68,7 @@ def _check(): """ - Raise ``RuntimeError`` if ``user_globals`` has not been initialized. + Raise :exc:`RuntimeError` if ``user_globals`` has not been initialized. EXAMPLES:: @@ -108,8 +108,8 @@ def set_globals(g): INPUT: - - ``g`` -- a dictionary. Typically, this will be some dictionary - given by the user interface or just ``globals()``. + - ``g`` -- dictionary; typically, this will be some dictionary + given by the user interface or just ``globals()`` EXAMPLES:: @@ -132,7 +132,7 @@ def initialize_globals(all, g=None): - ``all`` -- a module whose globals will be injected - - ``g`` -- a dictionary, see :func:`set_globals`. If this is + - ``g`` -- dictionary; see :func:`set_globals`. If this is ``None``, keep the current globals dictionary. EXAMPLES:: @@ -166,11 +166,11 @@ def get_global(name): """ Return the value of global variable ``name``. - Raise :class:`NameError` if there is no such global variable. + Raise :exc:`NameError` if there is no such global variable. INPUT: - - ``name`` -- a string representing a variable name + - ``name`` -- string representing a variable name OUTPUT: the value of variable ``name`` @@ -199,7 +199,7 @@ def set_global(name, value): INPUT: - - ``name`` -- a string representing a variable name + - ``name`` -- string representing a variable name - ``value`` -- a value to assign to the variable diff --git a/src/sage/rings/algebraic_closure_finite_field.py b/src/sage/rings/algebraic_closure_finite_field.py index 430037f7b31..b5e76c676d3 100644 --- a/src/sage/rings/algebraic_closure_finite_field.py +++ b/src/sage/rings/algebraic_closure_finite_field.py @@ -74,7 +74,6 @@ class AlgebraicClosureFiniteFieldElement(FieldElement): z2 sage: type(F.gen(2)) - """ def __init__(self, parent, value): """ @@ -88,7 +87,6 @@ def __init__(self, parent, value): The ``_test_pickling`` test has to be skipped because there is no coercion map between the parents of ``x`` and ``loads(dumps(x))``. - """ if isinstance(value, Element) and isinstance(value.parent(), FiniteField): n = value.parent().degree() @@ -162,7 +160,6 @@ def _repr_(self): sage: F = GF(3).algebraic_closure() sage: F._repr_() 'Algebraic closure of Finite Field of size 3' - """ return self._value._repr_() @@ -201,7 +198,6 @@ def _add_(self, right): sage: F = GF(3).algebraic_closure() sage: F.gen(2) + F.gen(3) z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 1 - """ F = self.parent() x, y = F._to_common_subfield(self, right) @@ -216,7 +212,6 @@ def _sub_(self, right): sage: F = GF(3).algebraic_closure() sage: F.gen(2) - F.gen(3) z6^4 + 2*z6^3 + z6^2 + 2*z6 - """ F = self.parent() x, y = F._to_common_subfield(self, right) @@ -231,7 +226,6 @@ def _mul_(self, right): sage: F = GF(3).algebraic_closure() sage: F.gen(2) * F.gen(3) z6^5 + 2*z6^4 + z6^2 + 2 - """ F = self.parent() x, y = F._to_common_subfield(self, right) @@ -246,7 +240,6 @@ def _div_(self, right): sage: F = GF(3).algebraic_closure() sage: F.gen(2) / F.gen(3) z6^5 + 2*z6^4 + z6^3 + 1 - """ F = self.parent() x, y = F._to_common_subfield(self, right) @@ -282,7 +275,6 @@ def change_level(self, n): From: Finite Field of size 3 To: Finite Field in z3 of size 3^3 Defn: 1 |--> 1 - """ F = self.parent() l = self._level @@ -304,7 +296,6 @@ def _latex_(self): z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 2 sage: latex(s) z_{6}^{5} + 2 z_{6}^{4} + 2 z_{6}^{3} + z_{6}^{2} + 2 z_{6} + 2 - """ return self._value._latex_() @@ -318,7 +309,6 @@ def minpoly(self): sage: F = GF(11).algebraic_closure() sage: F.gen(3).minpoly() x^3 + 2*x + 9 - """ return self._value.minpoly() @@ -335,7 +325,6 @@ def is_square(self): sage: F = GF(3).algebraic_closure() sage: F.gen(2).is_square() True - """ return True @@ -384,7 +373,6 @@ def nth_root(self, n): .. TODO:: This function could probably be made faster. - """ from sage.rings.integer import Integer F = self.parent() @@ -414,7 +402,6 @@ def multiplicative_order(self): 16806 sage: (K.gen(1) + K.gen(2) + K.gen(3)).multiplicative_order() 7353 - """ return self._value.multiplicative_order() @@ -436,7 +423,6 @@ def pth_power(self, k=1): t3^2 + t3 + 1 sage: s.pth_power(3).parent() is K True - """ return self.__class__(self.parent(), self._value.pth_power(k)) @@ -458,7 +444,6 @@ def pth_root(self, k=1): t3^2 + t3 + 1 sage: s.pth_root(2).parent() is K True - """ return self.__class__(self.parent(), self._value.pth_root(k)) @@ -468,8 +453,8 @@ def as_finite_field_element(self, minimal=False): INPUT: - - ``minimal`` -- boolean (default: ``False``). If ``True``, - always return the smallest subfield containing ``self``. + - ``minimal`` -- boolean (default: ``False``); if ``True``, + always return the smallest subfield containing ``self`` OUTPUT: @@ -533,7 +518,6 @@ def as_finite_field_element(self, minimal=False): Defn: z2 |--> z4^3 + z4^2 + z4 + 3 sage: f(b) z4^3 + z4^2 + z4 + 4 - """ Fbar = self.parent() x = self._value @@ -621,7 +605,6 @@ def characteristic(self): sage: F = AlgebraicClosureFiniteField(GF(p), 'z') sage: F.characteristic() == p True - """ return self.base_ring().characteristic() @@ -644,7 +627,6 @@ def _element_constructor_(self, x): Traceback (most recent call last): ... ValueError: no conversion defined between different algebraic closures - """ if isinstance(x, self.element_class): if x.parent() is not self: @@ -663,7 +645,6 @@ def _coerce_map_from_(self, other): sage: F = GF(7).algebraic_closure() sage: F.has_coerce_map_from(Integers()) True - """ if other is self: return True @@ -682,7 +663,6 @@ def _repr_(self): sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: F._repr_() 'Algebraic closure of Finite Field of size 5' - """ return 'Algebraic closure of %s' % self.base_ring() @@ -710,7 +690,6 @@ def _to_common_subfield(self, x, y): Finite Field in z6 of size 3^6 sage: y.parent() Finite Field in z6 of size 3^6 - """ if x._level == y._level: return x._value, y._value @@ -753,7 +732,6 @@ def _get_im_gen(self, m, n): Traceback (most recent call last): ... NotImplementedError: - """ def _subfield(self, n): @@ -765,7 +743,6 @@ def _subfield(self, n): sage: F = GF(3).algebraic_closure() sage: F._subfield(4) Finite Field in z4 of size 3^4 - """ if n == 1: return self.base_ring() @@ -797,7 +774,6 @@ def subfield(self, n): From: Finite Field in z4 of size 3^4 To: Algebraic closure of Finite Field of size 3 Defn: z4 |--> z4) - """ Fn = self._subfield(n) return Fn, Fn.hom( (self.gen(n),), check=False) @@ -820,7 +796,6 @@ def inclusion(self, m, n): From: Finite Field in z2 of size 3^2 To: Finite Field in z4 of size 3^4 Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1 - """ if m.divides(n): # check=False is required to avoid "coercion hell": an @@ -840,7 +815,6 @@ def ngens(self): sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: AlgebraicClosureFiniteField(GF(5), 'z').ngens() +Infinity - """ from sage.rings.infinity import Infinity return Infinity @@ -855,7 +829,6 @@ def gen(self, n): sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: F.gen(2) z2 - """ F = self._subfield(n) return self(F.gen()) @@ -892,7 +865,6 @@ def _first_ngens(self, n): sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: F._first_ngens(3) (1, z2, z3) - """ return tuple(self.gen(i + 1) for i in range(n)) @@ -908,7 +880,6 @@ def algebraic_closure(self): sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: F.algebraic_closure() is F True - """ return self @@ -920,7 +891,6 @@ def _an_element_(self): sage: F = AlgebraicClosureFiniteField(GF(5), 'w') sage: F.an_element() # indirect doctest w2 - """ return self.gen(2) @@ -933,7 +903,6 @@ def some_elements(self): sage: F = GF(7).algebraic_closure() sage: F.some_elements() (1, z2, z3 + 1) - """ return (self(1), self.gen(2), 1+self.gen(3)) @@ -962,7 +931,6 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=None, algori ....: p = R.random_element(degree=randint(2,8)) ....: for r in p.roots(K, multiplicities=False): ....: assert p(r).is_zero(), "r={} is not a root of p={}".format(r,p) - """ from sage.arith.functions import lcm from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1013,7 +981,6 @@ def _factor_univariate_polynomial(self, p, **kwds): sage: for d in range(10): ....: p = R.random_element(degree=randint(2,8)) ....: assert p.factor().prod() == p, "error in the factorization of p={}".format(p) - """ from sage.structure.factorization import Factorization R = p.parent() @@ -1045,7 +1012,6 @@ class AlgebraicClosureFiniteField_pseudo_conway(WithEqualityById, AlgebraicClosu sage: F5 = GF(5).algebraic_closure() sage: F3 == F5 False - """ def __init__(self, base_ring, name, category=None, lattice=None, use_database=True): """ @@ -1056,18 +1022,18 @@ def __init__(self, base_ring, name, category=None, lattice=None, use_database=Tr accepted. - ``name`` -- prefix to use for generators of the finite - subfields. + subfields - ``category`` -- if provided, specifies the category in which - this algebraic closure will be placed. + this algebraic closure will be placed - ``lattice`` -- :class:`~sage.rings.finite_rings.conway_polynomials.PseudoConwayPolynomialLattice` - (default: None). If provided, use this pseudo-Conway + (default: ``None``); if provided, use this pseudo-Conway polynomial lattice to construct an algebraic closure. - - ``use_database`` -- boolean. If True (default), use actual + - ``use_database`` -- boolean. If ``True`` (default), use actual Conway polynomials whenever they are available in the - database. If False, always compute pseudo-Conway + database. If ``False``, always compute pseudo-Conway polynomials from scratch. TESTS:: @@ -1098,7 +1064,6 @@ def __init__(self, base_ring, name, category=None, lattice=None, use_database=Tr be made to compare equal, and ``_test_elements`` has to be skipped for the reason described in :meth:`AlgebraicClosureFiniteFieldElement.__init__`. - """ if not (isinstance(base_ring, FiniteField) and base_ring.is_prime_field()): raise NotImplementedError('algebraic closures of finite fields are only implemented for prime fields') @@ -1122,7 +1087,6 @@ def _get_polynomial(self, n): sage: F = AlgebraicClosureFiniteField_pseudo_conway(GF(5), 'z') sage: F._get_polynomial(1) x + 3 - """ return self._pseudo_conway_lattice.polynomial(n) @@ -1137,7 +1101,6 @@ def _get_im_gen(self, m, n): sage: F = AlgebraicClosureFiniteField_pseudo_conway(GF(5), 'z') sage: F._get_im_gen(2, 4) z4^3 + z4^2 + z4 + 3 - """ p = self.characteristic() if m == 1: @@ -1177,7 +1140,6 @@ def AlgebraicClosureFiniteField(base_ring, name, category=None, implementation=N This is to ensure that the result of comparing two instances cannot change with time. - """ if category is None: from sage.categories.fields import Fields diff --git a/src/sage/rings/asymptotic/asymptotic_expansion_generators.py b/src/sage/rings/asymptotic/asymptotic_expansion_generators.py index 2d0569cce1e..481b83c2415 100644 --- a/src/sage/rings/asymptotic/asymptotic_expansion_generators.py +++ b/src/sage/rings/asymptotic/asymptotic_expansion_generators.py @@ -59,18 +59,16 @@ - Clemens Heuberger (2016) - Benjamin Hackl (2016) - ACKNOWLEDGEMENT: - Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P 24644-N26. - Classes and Methods =================== """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Daniel Krenn # Copyright (C) 2016 Clemens Heuberger # @@ -78,8 +76,8 @@ # 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. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.superseded import experimental from sage.structure.sage_object import SageObject @@ -113,20 +111,18 @@ def Stirling(var, precision=None, skip_constant_factor=False): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``precision`` -- (default: ``None``) an integer `\ge 3`. If ``None``, then + - ``precision`` -- (default: ``None``) integer `\ge 3`. If ``None``, then the default precision of the asymptotic ring is used. - - ``skip_constant_factor`` -- (default: ``False``) a - boolean. If set, then the constant factor `\sqrt{2\pi}` is left out. + - ``skip_constant_factor`` -- boolean (default: ``False``); if set, + then the constant factor `\sqrt{2\pi}` is left out. As a consequence, the coefficient ring of the output changes from ``Symbolic Constants Subring`` (if ``False``) to ``Rational Field`` (if ``True``). - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -205,20 +201,18 @@ def log_Stirling(var, precision=None, skip_constant_summand=False): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - ``skip_constant_summand`` -- (default: ``False``) a - boolean. If set, then the constant summand `\log(2\pi)/2` is left out. + - ``skip_constant_summand`` -- boolean (default: ``False``); if set, + then the constant summand `\log(2\pi)/2` is left out. As a consequence, the coefficient ring of the output changes from ``Symbolic Constants Subring`` (if ``False``) to ``Rational Field`` (if ``True``). - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -329,14 +323,12 @@ def _log_StirlingNegativePowers_(var, precision): INPUT: - - ``var`` -- a string for the variable name. - - - ``precision`` -- an integer specifying the number of exact summands. - If this is negative, then the result is `0`. + - ``var`` -- string for the variable name - OUTPUT: + - ``precision`` -- integer specifying the number of exact summands; + if this is negative, then the result is `0` - An asymptotic expansion. + OUTPUT: an asymptotic expansion TESTS:: @@ -376,20 +368,18 @@ def HarmonicNumber(var, precision=None, skip_constant_summand=False): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - ``skip_constant_summand`` -- (default: ``False``) a - boolean. If set, then the constant summand ``euler_gamma`` is left out. + - ``skip_constant_summand`` -- boolean (default: ``False``); if set, + then the constant summand ``euler_gamma`` is left out. As a consequence, the coefficient ring of the output changes from ``Symbolic Constants Subring`` (if ``False``) to ``Rational Field`` (if ``True``). - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -482,23 +472,20 @@ def Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``k`` -- a number or symbolic constant. + - ``k`` -- a number or symbolic constant - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - ``skip_constant_factor`` -- (default: ``False``) a - boolean. If set, then the constant factor `\sqrt{k/(2\pi(k-1))}` - is left out. + - ``skip_constant_factor`` -- boolean (default: ``False``); if set, + then the constant factor `\sqrt{k/(2\pi(k-1))}` is left out. As a consequence, the coefficient ring of the output changes from ``Symbolic Constants Subring`` (if ``False``) to ``Rational Field`` (if ``True``). - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -593,7 +580,7 @@ def Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False): if b.parent() is SR: b = SCR(b).canonicalize_radical() result *= n.rpow(b) - result *= n**(-QQ(1)/QQ(2)) + result *= n**(-QQ((1, 2))) if not skip_constant_factor: result *= (k/((k-1)*2*SCR('pi'))).sqrt() @@ -628,25 +615,23 @@ def SingularityAnalysis(var, zeta=1, alpha=0, beta=0, delta=0, INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``zeta`` -- (default: `1`) the location of the singularity. + - ``zeta`` -- (default: `1`) the location of the singularity - - ``alpha`` -- (default: `0`) the pole order of the singularity. + - ``alpha`` -- (default: `0`) the pole order of the singularity - - ``beta`` -- (default: `0`) the order of the logarithmic singularity. + - ``beta`` -- (default: `0`) the order of the logarithmic singularity - - ``delta`` -- (default: `0`) the order of the log-log singularity. - Not yet implemented for ``delta != 0``. + - ``delta`` -- (default: `0`) the order of the log-log singularity; + not yet implemented for ``delta != 0`` - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - ``normalized`` -- (default: ``True``) a boolean, see above. - - OUTPUT: + - ``normalized`` -- boolean (default: ``True``); see above - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -918,7 +903,7 @@ def SingularityAnalysis(var, zeta=1, alpha=0, beta=0, delta=0, from sage.symbolic.ring import SR SCR = SR.subring(no_variables=True) - s = SR('s') + s = SR.var('s') iga = 1/gamma(alpha) if iga.parent() is SR: try: @@ -1012,7 +997,7 @@ def inverse_gamma_derivative(shift, r): else: beta_denominator = 0 L = _sa_coefficients_lambda_(max(1, k_max), beta=beta_denominator) - (k, r) = next(it) + k, r = next(it) result = (n**(-k) * log_n**(-r)).O() if alpha in ZZ and beta == 0: @@ -1022,7 +1007,7 @@ def inverse_gamma_derivative(shift, r): from .misc import NotImplementedOZero raise NotImplementedOZero(A, exact_part=A.zero()) - for (k, r) in it: + for k, r in it: result += binomial(beta, r) * \ sum(L[(k, ell)] * (-1)**ell * inverse_gamma_derivative(ell, r) @@ -1052,22 +1037,19 @@ def ImplicitExpansion(var, phi, tau=None, precision=None): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``phi`` -- the function `\Phi`. See the extended description for - assumptions on `\Phi`. + - ``phi`` -- the function `\Phi`; see the extended description for + assumptions on `\Phi` - ``tau`` -- (default: ``None``) the fundamental constant described in the extended description. If ``None``, then `\tau` is determined automatically if possible. - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -1078,7 +1060,6 @@ def ImplicitExpansion(var, phi, tau=None, precision=None): represents a singular element of the form `(1 - z/\rho)^{-1}`, for the variable `z\to\rho`. - EXAMPLES: We can, for example, determine the singular expansion of the well-known @@ -1142,27 +1123,26 @@ def ImplicitExpansion(var, phi, tau=None, precision=None): sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + 42*u, precision=5) Traceback (most recent call last): ... - ValueError: The function phi does not satisfy the requirements + ValueError: the function phi does not satisfy the requirements sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 42*u + u^2, precision=5) Traceback (most recent call last): ... - ValueError: The function phi does not satisfy the requirements + ValueError: the function phi does not satisfy the requirements sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + u^2 + u^42, precision=5) Traceback (most recent call last): ... - ValueError: Fundamental constant tau could not be determined - + ValueError: fundamental constant tau could not be determined """ from sage.symbolic.ring import SR from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ from sage.rings.asymptotic.asymptotic_ring import AsymptoticRing from sage.arith.srange import srange - y, u = SR('y'), SR('u') - one_half = QQ(1)/2 + y, u = SR.var('y'), SR.var('u') + one_half = QQ((1, 2)) - if phi(QQ(0)).is_zero() or phi(u) == phi(0) + u*phi(u).diff(u)(u=0): - raise ValueError('The function phi does not satisfy the requirements') + if phi(QQ.zero()).is_zero() or phi(u) == phi(0) + u*phi(u).diff(u)(u=0): + raise ValueError('the function phi does not satisfy the requirements') if tau is None: tau = _fundamental_constant_implicit_function_(phi=phi) @@ -1179,7 +1159,7 @@ def H(y): def ansatz(prec=precision): if prec < 1: - return A(1).O() + return A.one().O() if prec == 1: return ((1/Z)**one_half).O() return (-(2*tau/phi(tau)/H(y).diff(y, 2)(y=tau)).sqrt() * (1/Z)**one_half @@ -1188,7 +1168,7 @@ def ansatz(prec=precision): # we compare coefficients between a "single" Z and the # following expansion, this allows us to compute the constants d_j - z = SR('z') + z = SR.var('z') z_expansion = sum(H(z).diff(z, k)(z=tau)/k.factorial() * ansatz(prec=precision+2-k)**k for k in srange(2, precision)) + ((1/Z)**(precision * one_half)).O() @@ -1196,7 +1176,7 @@ def ansatz(prec=precision): solution_dict = dict() for k in srange(2, precision-1): coef = z_expansion.monomial_coefficient((1/Z)**((k+1) * one_half)) - current_var = SR('d{k}'.format(k=k)) + current_var = SR.var('d{k}'.format(k=k)) solution_dict[current_var] = coef.subs(solution_dict).simplify_rational().solve(current_var)[0].rhs() return A(tau) + ansatz(prec=precision-1).map_coefficients(lambda term: term.subs(solution_dict).simplify_rational()) @@ -1222,25 +1202,22 @@ def ImplicitExpansionPeriodicPart(var, phi, period, tau=None, precision=None): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``phi`` -- the function `\Phi`. See the extended description for - assumptions on `\Phi`. + - ``phi`` -- the function `\Phi`; see the extended description for + assumptions on `\Phi` - - ``period`` -- the period of the function `\Phi`. See the - extended description for details. + - ``period`` -- the period of the function `\Phi`; see the + extended description for details - ``tau`` -- (default: ``None``) the fundamental constant described in the extended description. If ``None``, then `\tau` is determined automatically if possible. - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -1276,7 +1253,6 @@ def ImplicitExpansionPeriodicPart(var, phi, period, tau=None, precision=None): sage: A. = AsymptoticRing('Z^QQ', QQ, default_prec=3) sage: g((1 - 1/Z)/4) 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3)) - """ if tau is None: tau = _fundamental_constant_implicit_function_(phi=phi) @@ -1286,7 +1262,7 @@ def ImplicitExpansionPeriodicPart(var, phi, period, tau=None, precision=None): phi=lambda u: phi(u**(1/period))**period, tau=tau_p, precision=precision) - rho = tau/phi(tau) + rho = tau / phi(tau) Z = aperiodic_expansion.parent().gen() return 1/rho * (aperiodic_expansion/(1 - 1/Z))**(1/period) @@ -1307,25 +1283,22 @@ def InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None): INPUT: - - ``var`` -- a string for the variable name. + - ``var`` -- string for the variable name - - ``phi`` -- the function `\Phi`. See the extended description for - assumptions on `\Phi`. + - ``phi`` -- the function `\Phi`; see the extended description for + assumptions on `\Phi` - ``tau`` -- (default: ``None``) the fundamental constant described in the extended description. If ``None``, then `\tau` is determined automatically if possible. - ``period`` -- (default: `1`) the period of the function `\Phi`. See - the extended description for details. + the extended description for details - - ``precision`` -- (default: ``None``) an integer. If ``None``, then + - ``precision`` -- (default: ``None``) integer. If ``None``, then the default precision of the asymptotic ring is used. - - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -1337,7 +1310,6 @@ def InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None): for `n \equiv 1 \mod p`, where `p` is the period. All other coefficients are `0`. - EXAMPLES: There are `C_n` (the `n`-th Catalan number) different binary trees @@ -1395,7 +1367,7 @@ def InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None): if tau is None: tau = _fundamental_constant_implicit_function_(phi=phi) - rho = tau/phi(tau) + rho = tau / phi(tau) if period == 1: expansion = asymptotic_expansions.ImplicitExpansion(var=var, phi=phi, @@ -1407,6 +1379,7 @@ def InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None): n = growth.parent().gen() return growth.subs({n: (n-1)/period}) + def _fundamental_constant_implicit_function_(phi): r""" Return the fundamental constant `\tau` occurring in the analysis of @@ -1418,7 +1391,7 @@ def _fundamental_constant_implicit_function_(phi): INPUT: - - ``phi`` -- the function `\Phi`. + - ``phi`` -- the function `\Phi` .. SEEALSO:: @@ -1435,15 +1408,15 @@ def _fundamental_constant_implicit_function_(phi): 1 sage: _fundamental_constant_implicit_function_(phi=lambda u: 1 + 2*u + 2*u^2) 1/2*sqrt(2) - """ from sage.symbolic.ring import SR - u = SR('u') + u = SR.var('u') positive_solution = [s for s in (phi(u) - u*phi(u).diff(u)).solve(u) if s.rhs() > 0] if len(positive_solution) == 1: return positive_solution[0].rhs() - raise ValueError('Fundamental constant tau could not be determined') + raise ValueError('fundamental constant tau could not be determined') + def _sa_coefficients_lambda_(K, beta=0): r""" @@ -1451,14 +1424,11 @@ def _sa_coefficients_lambda_(K, beta=0): INPUT: - - ``K`` -- an integer. - - - ``beta`` -- (default: `0`) the order of the logarithmic - singularity. + - ``K`` -- integer - OUTPUT: + - ``beta`` -- (default: `0`) the order of the logarithmic singularity - A dictionary mapping pairs of indices to rationals. + OUTPUT: a dictionary mapping pairs of indices to rationals .. SEEALSO:: @@ -1490,18 +1460,17 @@ def _sa_coefficients_lambda_(K, beta=0): (4, 4): 5} """ from sage.rings.laurent_series_ring import LaurentSeriesRing - from sage.rings.power_series_ring import PowerSeriesRing + from sage.rings.lazy_series_ring import LazyPowerSeriesRing from sage.rings.rational_field import QQ V = LaurentSeriesRing(QQ, names='v', default_prec=K) v = V.gen() - T = PowerSeriesRing(V, names='t', default_prec=2*K-1) - t = T.gen() + t = LazyPowerSeriesRing(V, names='t').gen() - S = (t - (1+1/v+beta) * (1+v*t).log()).exp() - return dict(((k + L.valuation(), ell), c) - for ell, L in enumerate(S.list()) - for k, c in enumerate(L.list())) + S = (t - (1 + 1/v + beta) * (1 + v*t).log()).exp() + return {(k + L.valuation(), ell): c + for ell, L in enumerate(S[:2 * K - 1]) + for k, c in enumerate(L.list())} # Easy access to the asymptotic expansions generators from the command line: diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index d85f407872f..48caffa1b6a 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -414,15 +414,24 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** +import sage.rings.abc + +from sage.categories.pushout import ConstructionFunctor +from sage.misc.defaults import series_precision +from sage.misc.lazy_import import lazy_import +from sage.rings.real_mpfi import RIF from sage.structure.element import CommutativeAlgebraElement from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.misc.defaults import series_precision -from sage.categories.pushout import ConstructionFunctor -import sage.rings.abc -from sage.rings.real_mpfi import RIF + from .misc import WithLocals +lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') +lazy_import('sage.rings.polynomial.multi_polynomial_ring_base', 'MPolynomialRing_base') +lazy_import('sage.rings.polynomial.polynomial_ring', 'PolynomialRing_general') +lazy_import('sage.rings.power_series_ring', 'PowerSeriesRing_generic') +lazy_import('sage.symbolic.ring', 'SymbolicRing') + class NoConvergenceError(RuntimeError): r""" @@ -438,16 +447,16 @@ class AsymptoticExpansion(CommutativeAlgebraElement): INPUT: - - ``parent`` -- the parent of the asymptotic expansion. + - ``parent`` -- the parent of the asymptotic expansion - ``summands`` -- the summands as a :class:`~sage.data_structures.mutable_poset.MutablePoset`, which - represents the underlying structure. + represents the underlying structure - - ``simplify`` -- a boolean (default: ``True``). It controls - automatic simplification (absorption) of the asymptotic expansion. + - ``simplify`` -- boolean (default: ``True``); it controls + automatic simplification (absorption) of the asymptotic expansion - - ``convert`` -- a boolean (default: ``True``). If set, then the + - ``convert`` -- boolean (default: ``True``); if set, then the ``summands`` are converted to the asymptotic ring (the parent of this expansion). If not, then the summands are taken as they are. In that case, the caller must ensure that the parent of the terms is @@ -739,9 +748,7 @@ def __bool__(self) -> bool: r""" Return whether this asymptotic expansion is not identically zero. - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -761,11 +768,9 @@ def __eq__(self, other) -> bool: INPUT: - - ``other`` -- an object. - - OUTPUT: + - ``other`` -- an object - A boolean. + OUTPUT: boolean .. NOTE:: @@ -803,11 +808,9 @@ def __ne__(self, other) -> bool: INPUT: - - ``other`` -- an object. - - OUTPUT: + - ``other`` -- an object - A boolean. + OUTPUT: boolean .. NOTE:: @@ -836,11 +839,9 @@ def has_same_summands(self, other) -> bool: INPUT: - - ``other`` -- an asymptotic expansion. - - OUTPUT: + - ``other`` -- an asymptotic expansion - A boolean. + OUTPUT: boolean .. NOTE:: @@ -884,11 +885,9 @@ def _has_same_summands_(self, other) -> bool: INPUT: - - ``other`` -- an :class:`AsymptoticExpansion`. - - OUTPUT: + - ``other`` -- an :class:`AsymptoticExpansion` - A boolean. + OUTPUT: boolean .. NOTE:: @@ -913,9 +912,7 @@ def _simplify_(self): r""" Simplify this asymptotic expansion. - OUTPUT: - - Nothing, but modifies this asymptotic expansion. + OUTPUT: nothing, but modifies this asymptotic expansion .. NOTE:: @@ -951,12 +948,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. - - OUTPUT: + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - A string. + OUTPUT: string EXAMPLES:: @@ -983,9 +978,7 @@ def _latex_(self): r""" A LaTeX-representation string for this asymptotic expansion. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -1031,9 +1024,7 @@ def monomial_coefficient(self, monomial): - ``monomial`` -- a monomial element which can be converted into the asymptotic ring of this element - OUTPUT: - - An element of the coefficient ring. + OUTPUT: an element of the coefficient ring EXAMPLES:: @@ -1091,7 +1082,6 @@ def monomial_coefficient(self, monomial): Traceback (most recent call last): ... ValueError: non-exact monomial O(n) - """ monomial = self.parent()(monomial) if not monomial.is_exact(): @@ -1112,11 +1102,9 @@ def _add_(self, other): INPUT: - - ``other`` -- an :class:`AsymptoticExpansion`. - - OUTPUT: + - ``other`` -- an :class:`AsymptoticExpansion` - The sum as an :class:`AsymptoticExpansion`. + OUTPUT: the sum as an :class:`AsymptoticExpansion` EXAMPLES:: @@ -1149,11 +1137,9 @@ def _sub_(self, other): INPUT: - - ``other`` -- an :class:`AsymptoticExpansion`. + - ``other`` -- an :class:`AsymptoticExpansion` - OUTPUT: - - The difference as an :class:`AsymptoticExpansion`. + OUTPUT: the difference as an :class:`AsymptoticExpansion` .. NOTE:: @@ -1178,12 +1164,9 @@ def _mul_term_(self, term): INPUT: - - ``term`` -- an asymptotic term (see - :doc:`term_monoid`). - - OUTPUT: + - ``term`` -- an asymptotic term (see :doc:`term_monoid`) - The product as an :class:`AsymptoticExpansion`. + OUTPUT: the product as an :class:`AsymptoticExpansion` TESTS:: @@ -1207,11 +1190,9 @@ def _mul_(self, other): INPUT: - - ``other`` -- an :class:`AsymptoticExpansion`. + - ``other`` -- an :class:`AsymptoticExpansion` - OUTPUT: - - The product as an :class:`AsymptoticExpansion`. + OUTPUT: the product as an :class:`AsymptoticExpansion` EXAMPLES:: @@ -1247,11 +1228,9 @@ def _lmul_(self, other): INPUT: - - ``other`` -- an element of the coefficient ring. - - OUTPUT: + - ``other`` -- an element of the coefficient ring - An :class:`AsymptoticExpansion`. + OUTPUT: an :class:`AsymptoticExpansion` TESTS:: @@ -1272,11 +1251,9 @@ def _div_(self, other): INPUT: - - ``other`` -- an asymptotic expansion. + - ``other`` -- an asymptotic expansion - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -1310,9 +1287,7 @@ def __invert__(self, precision=None): expansion. If ``None`` (default value) is used, the default precision of the parent is used. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. WARNING:: @@ -1393,13 +1368,11 @@ def truncate(self, precision=None): INPUT: - - ``precision`` -- a positive integer or ``None``. Number of + - ``precision`` -- positive integer or ``None``. Number of summands that are kept. If ``None`` (default value) is given, then ``default_prec`` from the parent is used. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -1444,9 +1417,7 @@ def exact_part(self): Return the expansion consisting of all exact terms of this expansion. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -1476,9 +1447,7 @@ def error_part(self): Return the expansion consisting of all error terms of this expansion. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -1498,15 +1467,13 @@ def __pow__(self, exponent, precision=None): INPUT: - - ``exponent`` -- an element. + - ``exponent`` -- an element - ``precision`` -- the precision used for truncating the expansion. If ``None`` (default value) is used, the default precision of the parent is used. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -1719,17 +1686,15 @@ def __pow_number__(self, exponent, precision=None, check_convergence=False): INPUT: - ``exponent`` -- a numerical value (e.g. integer, rational) - or other constant. + or other constant - - ``precision`` -- a non-negative integer. + - ``precision`` -- nonnegative integer - - ``check_convergence`` -- (default: ``False``) a boolean. If set, + - ``check_convergence`` -- boolean (default: ``False``); if set, then an additional check on the input is performed to ensure - that the calculated sum converges. + that the calculated sum converges - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. SEEALSO:: @@ -1861,9 +1826,7 @@ def sqrt(self, precision=None): expansion. If ``None`` (default value) is used, the default precision of the parent is used. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -1892,9 +1855,7 @@ def O(self): r""" Convert all terms in this asymptotic expansion to `O`-terms. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -1942,14 +1903,12 @@ def log(self, base=None, precision=None, locals=None): expansion. If ``None`` (default value) is used, the default precision of the parent is used. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -2066,9 +2025,7 @@ def is_exact(self) -> bool: r""" Return whether all terms of this expansion are exact. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -2091,9 +2048,7 @@ def is_little_o_of_one(self) -> bool: r""" Return whether this expansion is of order `o(1)`. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -2129,20 +2084,18 @@ def rpow(self, base, precision=None, locals=None): INPUT: - - ``base`` -- an element or ``'e'``. + - ``base`` -- an element or ``'e'`` - ``precision`` -- the precision used for truncating the expansion. If ``None`` (default value) is used, the default precision of the parent is used. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -2244,8 +2197,8 @@ def _main_term_relative_error_(self, return_inverse_main_term=False): INPUT: - - ``return_inverse_main_term`` -- (default: ``False``) a boolean. - If set, then the pair `(m^{-1},x)` is returned instead of `(m,x)`. + - ``return_inverse_main_term`` -- boolean (default: ``False``); + if set, then the pair `(m^{-1},x)` is returned instead of `(m,x)` OUTPUT: @@ -2332,20 +2285,18 @@ def _power_series_(coefficients, start, ratio, ratio_start, precision): INPUT: - - ``coefficients`` -- an iterator. + - ``coefficients`` -- an iterator - - ``start`` -- an asymptotic expansion. + - ``start`` -- an asymptotic expansion - - ``ratio`` -- an asymptotic expansion. + - ``ratio`` -- an asymptotic expansion - - ``ratio_start`` -- an asymptotic expansion. + - ``ratio_start`` -- an asymptotic expansion - - ``precision`` -- a non-negative integer. All intermediate - results are truncated to this precision. - - OUTPUT: + - ``precision`` -- nonnegative integer; all intermediate + results are truncated to this precision - An asymptotic expansion. + OUTPUT: an asymptotic expansion TESTS:: @@ -2394,9 +2345,7 @@ def exp(self, precision=None): expansion. If ``None`` (default value) is used, the default precision of the parent is used. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -2459,19 +2408,17 @@ def subs(self, rules=None, domain=None, **kwds): INPUT: - - ``rules`` -- a dictionary. + - ``rules`` -- dictionary - ``kwds`` -- keyword arguments will be added to the - substitution ``rules``. + substitution ``rules`` - ``domain`` -- (default: ``None``) a parent. The neutral elements `0` and `1` (rules for the keys ``'_zero_'`` and ``'_one_'``, see note box below) are taken out of this domain. If ``None``, then this is determined automatically. - OUTPUT: - - An object. + OUTPUT: an object .. NOTE:: @@ -2683,13 +2630,10 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. - The neutral element of the asymptotic ring is replaced by the value - to key ``'_zero_'``. + - ``rules`` -- dictionary. The neutral element of the asymptotic ring + is replaced by the value to key ``'_zero_'``. - OUTPUT: - - An object. + OUTPUT: an object TESTS:: @@ -2734,20 +2678,20 @@ def compare_with_values(self, variable, function, values, INPUT: - - ``variable`` -- an asymptotic expansion or a string. + - ``variable`` -- an asymptotic expansion or a string - ``function`` -- a callable or symbolic expression giving the - comparison values. + comparison values - - ``values`` -- a list or iterable of values where the comparison - shall be carried out. + - ``values`` -- list or iterable of values where the comparison + shall be carried out - - ``rescaled`` -- (default: ``True``) determines whether + - ``rescaled`` -- boolean (default: ``True``); determines whether the difference is divided by the error term of the asymptotic - expansion. + expansion - ``ring`` -- (default: ``RIF``) the parent into which the - difference is converted. + difference is converted OUTPUT: @@ -2893,29 +2837,27 @@ def plot_comparison(self, variable, function, values, rescaled=True, INPUT: - - ``variable`` -- an asymptotic expansion or a string. + - ``variable`` -- an asymptotic expansion or a string - ``function`` -- a callable or symbolic expression giving the - comparison values. + comparison values - - ``values`` -- a list or iterable of values where the comparison - shall be carried out. + - ``values`` -- list or iterable of values where the comparison + shall be carried out - - ``rescaled`` -- (default: ``True``) determines whether + - ``rescaled`` -- boolean (default: ``True``); determines whether the difference is divided by the error term of the asymptotic - expansion. + expansion - ``ring`` -- (default: ``RIF``) the parent into which the - difference is converted. + difference is converted - - ``relative_tolerance`` -- (default: ``0.025``). Raise error - when relative error exceeds this tolerance. + - ``relative_tolerance`` -- (default: ``0.025``) raise error + when relative error exceeds this tolerance Other keyword arguments are passed to :func:`list_plot`. - OUTPUT: - - A graphics object. + OUTPUT: a graphics object .. NOTE:: @@ -2991,9 +2933,7 @@ def symbolic_expression(self, R=None): The output will be an element of ``R``. If ``None``, then the symbolic ring is used. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -3044,13 +2984,11 @@ def map_coefficients(self, f, new_coefficient_ring=None): INPUT: - - ``f`` -- a callable. A coefficient `c` will be mapped to `f(c)`. + - ``f`` -- a callable; a coefficient `c` will be mapped to `f(c)` - - ``new_coefficient_ring`` -- (default: ``None``) a ring. - - OUTPUT: + - ``new_coefficient_ring`` -- (default: ``None``) a ring - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -3095,9 +3033,7 @@ def factorial(self): r""" Return the factorial of this asymptotic expansion. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -3196,9 +3132,7 @@ def variable_names(self): r""" Return the names of the variables of this asymptotic expansion. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -3233,17 +3167,15 @@ def _singularity_analysis_(self, var, zeta, precision=None): INPUT: - - ``var`` -- a string, the variable for the growth of the coefficients, - or the generator of an asymptotic ring. + - ``var`` -- string; the variable for the growth of the coefficients, + or the generator of an asymptotic ring - ``zeta`` -- location of the singularity - - ``precision`` -- (default: ``None``) an integer. If ``None``, then - the default precision of the parent of this expansion is used. + - ``precision`` -- (default: ``None``) integer; if ``None``, then + the default precision of the parent of this expansion is used - OUTPUT: - - An asymptotic expansion in ``var``. + OUTPUT: an asymptotic expansion in ``var`` EXAMPLES:: @@ -3316,9 +3248,7 @@ def limit(self): """ Compute the limit of this asymptotic expansion. - OUTPUT: - - An element of the coefficient ring. + OUTPUT: an element of the coefficient ring EXAMPLES:: @@ -3369,9 +3299,7 @@ def B(self, valid_from=0): is passed to ``valid_from``, then the lower bounds for all variables of the asymptotic expansion are set to this number - OUTPUT: - - An asymptotic expansion + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -3417,10 +3345,10 @@ class AsymptoticRing(Parent, UniqueRepresentation, WithLocals): :class:`~sage.rings.asymptotic.growth_group.GrowthGroupFactory`). - ``coefficient_ring`` -- the ring which contains the - coefficients of the expansions. + coefficients of the expansions - - ``default_prec`` -- a positive integer. This is the number of - summands that are kept before truncating an infinite series. + - ``default_prec`` -- positive integer; this is the number of + summands that are kept before truncating an infinite series - ``category`` -- the category of the parent can be specified in order to broaden the base structure. It has to be a @@ -3431,7 +3359,7 @@ class AsymptoticRing(Parent, UniqueRepresentation, WithLocals): If ``None``, then :class:`~sage.rings.asymptotic.term_monoid.DefaultTermMonoidFactory` is used. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not given, then the usual :class:`log ` is taken. @@ -3537,7 +3465,7 @@ def __classcall__(cls, growth_group=None, coefficient_ring=None, term_monoid_factory=None, locals=None): r""" - Normalizes the input in order to ensure a unique + Normalize the input in order to ensure a unique representation of the parent. For more information see :class:`AsymptoticRing`. @@ -3778,7 +3706,7 @@ def term_monoid(self, type): INPUT: - - ``type`` -- 'O' or 'exact', or an instance of an existing + - ``type`` -- ``'O'`` or ``'exact'``, or an instance of an existing term monoid. See :class:`~sage.rings.asymptotic.term_monoid.TermMonoidFactory` for more details. @@ -3807,17 +3735,15 @@ def change_parameter(self, **kwds): INPUT: - - ``growth_group`` -- (default: ``None``) the new growth group. + - ``growth_group`` -- (default: ``None``) the new growth group - - ``coefficient_ring`` -- (default: ``None``) the new coefficient ring. + - ``coefficient_ring`` -- (default: ``None``) the new coefficient ring - - ``category`` -- (default: ``None``) the new category. + - ``category`` -- (default: ``None``) the new category - - ``default_prec`` -- (default: ``None``) the new default precision. - - OUTPUT: + - ``default_prec`` -- (default: ``None``) the new default precision - An asymptotic ring. + OUTPUT: an asymptotic ring EXAMPLES:: @@ -3858,9 +3784,7 @@ def _create_empty_summands_(): Create an empty data structure suitable for storing and working with summands. - OUTPUT: - - A :class:`~sage.data_structures.mutable_poset.MutablePoset`. + OUTPUT: a :class:`~sage.data_structures.mutable_poset.MutablePoset` TESTS:: @@ -3880,15 +3804,13 @@ def _create_element_in_extension_(self, term, old_term_parent=None): INPUT: - - ``term`` -- the element data. + - ``term`` -- the element data - ``old_term_parent`` -- the parent of ``term`` is compared to this parent. If both are the same or ``old_parent`` is ``None``, then the result is an expansion in this (``self``) asymptotic ring. - OUTPUT: - - An element. + OUTPUT: an element EXAMPLES:: @@ -3926,21 +3848,19 @@ def _element_constructor_(self, data, simplify=True, convert=True): INPUT: - ``data`` -- an object representing the element to be - initialized. + initialized - - ``simplify`` -- (default: ``True``) if set, then the constructed - element is simplified (terms are absorbed) automatically. + - ``simplify`` -- boolean (default: ``True``); if set, then the constructed + element is simplified (terms are absorbed) automatically - - ``convert`` -- (default: ``True``) passed on to the element + - ``convert`` -- boolean (default: ``True``); passed on to the element constructor. If set, then the ``summands`` are converted to the asymptotic ring (the parent of this expansion). If not, then the summands are taken as they are. In that case, the caller must ensure that the parent of the terms is set correctly. - OUTPUT: - - An element of this asymptotic ring. + OUTPUT: an element of this asymptotic ring TESTS:: @@ -4077,10 +3997,6 @@ def _element_constructor_(self, data, simplify=True, convert=True): return self.create_summand('exact', data) from .misc import combine_exceptions - from sage.symbolic.ring import SymbolicRing - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing - from sage.rings.power_series_ring import is_PowerSeriesRing if isinstance(P, SymbolicRing): from sage.symbolic.operators import add_vararg @@ -4097,7 +4013,7 @@ def _element_constructor_(self, data, simplify=True, convert=True): (data, self)), e) return sum(summands, self.zero()) - elif is_PolynomialRing(P): + elif isinstance(P, PolynomialRing_general): p = P.gen() try: return sum(iter(self.create_summand('exact', growth=p**i, @@ -4108,7 +4024,7 @@ def _element_constructor_(self, data, simplify=True, convert=True): raise combine_exceptions( ValueError('Polynomial %s is not in %s' % (data, self)), e) - elif is_MPolynomialRing(P): + elif isinstance(P, MPolynomialRing_base): try: return sum(iter(self.create_summand('exact', growth=g, coefficient=c) for c, g in iter(data)), @@ -4117,7 +4033,7 @@ def _element_constructor_(self, data, simplify=True, convert=True): raise combine_exceptions( ValueError('Polynomial %s is not in %s' % (data, self)), e) - elif is_PowerSeriesRing(P): + elif isinstance(P, (PowerSeriesRing_generic, LazyPowerSeriesRing)): raise NotImplementedError( 'cannot convert %s from the %s to an asymptotic expansion ' 'in %s, since growths at other points than +oo are not yet ' @@ -4149,11 +4065,9 @@ def _coerce_map_from_(self, R): INPUT: - - ``R`` -- a parent. - - OUTPUT: + - ``R`` -- a parent - A boolean. + OUTPUT: boolean .. NOTE:: @@ -4200,9 +4114,7 @@ def _repr_(self) -> str: r""" A representation string of this asymptotic ring. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -4221,9 +4133,7 @@ def _an_element_(self): r""" Return an element of this asymptotic ring. - OUTPUT: - - An :class:`AsymptoticExpansion`. + OUTPUT: an :class:`AsymptoticExpansion` EXAMPLES:: @@ -4245,9 +4155,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -4277,9 +4185,7 @@ def gens(self) -> tuple: r""" Return a tuple with generators of this asymptotic ring. - OUTPUT: - - A tuple of asymptotic expansions. + OUTPUT: a tuple of asymptotic expansions .. NOTE:: @@ -4309,11 +4215,9 @@ def gen(self, n=0): INPUT: - - ``n`` -- (default: `0`) a non-negative integer. + - ``n`` -- (default: `0`) a nonnegative integer - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion EXAMPLES:: @@ -4327,9 +4231,7 @@ def ngens(self): r""" Return the number of generators of this asymptotic ring. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -4348,15 +4250,15 @@ def coefficients_of_generating_function(self, function, singularities, precision INPUT: - - ``function`` -- a callable function in one variable. + - ``function`` -- a callable function in one variable - - ``singularities`` -- list of dominant singularities of the function. + - ``singularities`` -- list of dominant singularities of the function - - ``precision`` -- (default: ``None``) an integer. If ``None``, then - the default precision of the asymptotic ring is used. + - ``precision`` -- integer (default: ``None``); if ``None``, then + the default precision of the asymptotic ring is used - - ``return_singular_expansions`` -- (default: ``False``) a boolean. - If set, the singular expansions are also returned. + - ``return_singular_expansions`` -- boolean (default: ``False``); + if set, the singular expansions are also returned - ``error_term`` -- (default: ``None``) an asymptotic expansion. If ``None``, then this is interpreted as zero. @@ -4491,22 +4393,20 @@ def create_summand(self, type, data=None, **kwds): INPUT: - - ``type`` -- 'O' or 'exact'. + - ``type`` -- 'O' or 'exact' - - ``data`` -- the element out of which a summand has to be created. + - ``data`` -- the element out of which a summand has to be created - - ``growth`` -- an element of the :meth:`growth_group`. + - ``growth`` -- an element of the :meth:`growth_group` - - ``coefficient`` -- an element of the :meth:`coefficient_ring`. + - ``coefficient`` -- an element of the :meth:`coefficient_ring` .. NOTE:: Either ``growth`` and ``coefficient`` or ``data`` have to be specified. - OUTPUT: - - An asymptotic expansion. + OUTPUT: an asymptotic expansion .. NOTE:: @@ -4581,9 +4481,7 @@ def variable_names(self): r""" Return the names of the variables. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -4645,9 +4543,7 @@ def B(expression, valid_from=0): is passed to ``valid_from``, then the lower bounds for all variables of the asymptotic expansion are set to this number - OUTPUT: - - A B-term + OUTPUT: a B-term EXAMPLES:: @@ -4669,11 +4565,11 @@ class AsymptoticRingFunctor(ConstructionFunctor): :class:`AsymptoticRing` or :doc:`growth_group` for details). - - ``default_prec`` -- ``None`` (default) or an integer. + - ``default_prec`` -- ``None`` (default) or integer - - ``category`` -- ``None`` (default) or a category. + - ``category`` -- ``None`` (default) or a category - - ``cls`` -- :class:`AsymptoticRing` (default) or a derived class. + - ``cls`` -- :class:`AsymptoticRing` (default) or a derived class EXAMPLES:: @@ -4739,9 +4635,7 @@ def _repr_(self) -> str: r""" Return a representation string of this functor. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -4766,11 +4660,9 @@ def _apply_functor(self, coefficient_ring): INPUT: - - ``base`` -- anything :class:`~sage.rings.asymptotic.growth_group.MonomialGrowthGroup` accepts. + - ``base`` -- anything :class:`~sage.rings.asymptotic.growth_group.MonomialGrowthGroup` accepts - OUTPUT: - - An :class:`AsymptoticRing`. + OUTPUT: an :class:`AsymptoticRing` EXAMPLES:: @@ -4818,11 +4710,9 @@ def merge(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A functor or ``None``. + OUTPUT: a functor or ``None`` EXAMPLES:: @@ -4914,11 +4804,9 @@ def __eq__(self, other) -> bool: INPUT: - - ``other`` -- a functor. + - ``other`` -- a functor - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -4943,11 +4831,9 @@ def __ne__(self, other) -> bool: INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A boolean. + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index f5163d394a5..9eaf85376ca 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -235,7 +235,7 @@ class FractionWithFactoredDenominator(RingElement): - ``numerator`` -- an element `p`; this can be of any ring from which parent's base has coercion in - - ``denominator_factored`` -- a list of the form + - ``denominator_factored`` -- list of the form `[(q_1, e_1), \ldots, (q_n, e_n)]`, where the `q_1, \ldots, q_n` are distinct irreducible elements of `R` and the `e_i` are positive integers @@ -369,9 +369,7 @@ def numerator(self): r""" Return the numerator of ``self``. - OUTPUT: - - The numerator. + OUTPUT: the numerator EXAMPLES:: @@ -439,9 +437,7 @@ def denominator_ring(self): r""" Return the ring of the denominator. - OUTPUT: - - A ring. + OUTPUT: a ring EXAMPLES:: @@ -467,9 +463,7 @@ def numerator_ring(self): r""" Return the ring of the numerator. - OUTPUT: - - A ring. + OUTPUT: a ring EXAMPLES:: @@ -494,9 +488,7 @@ def dimension(self): r""" Return the number of indeterminates of ``self.denominator_ring``. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -510,10 +502,10 @@ def dimension(self): sage: F.dimension() 2 """ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base R = self.denominator_ring - if is_PolynomialRing(R) or is_MPolynomialRing(R): + if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base): return R.ngens() raise NotImplementedError('only polynomial rings are supported as base') @@ -521,9 +513,7 @@ def quotient(self): r""" Convert ``self`` into a quotient. - OUTPUT: - - An element. + OUTPUT: an element EXAMPLES:: @@ -546,9 +536,7 @@ def _repr_(self) -> str: r""" Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -575,9 +563,7 @@ def _eq_(self, other): - ``other`` -- an instance of :class:`FractionWithFactoredDenominator` - OUTPUT: - - ``True`` or ``False``. + OUTPUT: boolean It can be assumed that ``self`` and ``other`` have the same parent. @@ -660,9 +646,7 @@ def _total_order_key_(self): denominators are equal and the numerator of ``A`` is less than that of ``B`` in their ring). - OUTPUT: - - A tuple. + OUTPUT: a tuple EXAMPLES:: @@ -720,9 +704,7 @@ def univariate_decomposition(self): factorization of the denominator. This gives a speed up for non-small instances. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` EXAMPLES:: @@ -910,9 +892,7 @@ def nullstellensatz_decomposition(self): Recursive. Only works for multivariate ``self``. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` EXAMPLES:: @@ -976,9 +956,7 @@ def algebraic_dependence_certificate(self): ``self.denominator_ring.base_ring()`` that has ``m = len(self.denominator_factored())`` indeterminates. - OUTPUT: - - An ideal. + OUTPUT: an ideal EXAMPLES:: @@ -1088,9 +1066,7 @@ def algebraic_dependence_decomposition(self, whole_and_parts=True): The algorithm used comes from [Rai2012]_. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` EXAMPLES:: @@ -1211,9 +1187,7 @@ def leinartas_decomposition(self): The algorithm used comes from [Rai2012]_. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` EXAMPLES:: @@ -1317,9 +1291,7 @@ def cohomology_decomposition(self): The algorithm used here comes from the proof of Theorem 17.4 of [AY1983]_. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` EXAMPLES:: @@ -1444,9 +1416,7 @@ def asymptotic_decomposition(self, alpha, asy_var=None): respect to which to compute asymptotics; if ``None`` is given, we set ``asy_var = var('r')`` - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` The output results from a Leinartas decomposition followed by a cohomology decomposition. @@ -1542,20 +1512,19 @@ def asymptotics(self, p, alpha, N, asy_var=None, numerical=0, INPUT: - - ``p`` -- a dictionary with keys that can be coerced to equal + - ``p`` -- dictionary with keys that can be coerced to equal ``self.denominator_ring.gens()`` - - ``alpha`` -- a tuple of length ``self.dimension()`` of - positive integers or, if `p` is a smooth point, - possibly of symbolic variables - - ``N`` -- a positive integer + - ``alpha`` -- tuple of length ``self.dimension()`` of positive + integers or, if `p` is a smooth point, possibly of symbolic variables + - ``N`` -- positive integer - ``asy_var`` -- (default: ``None``) a symbolic variable for the - asymptotic expansion; if ``none`` is given, then - ``var('r')`` will be assigned - - ``numerical`` -- (default: 0) a natural number; - if ``numerical`` is greater than 0, then return a numerical - approximation of `F_{r \alpha}` with ``numerical`` digits of - precision; otherwise return exact values - - ``verbose`` -- (default: ``False``) print the current state of + asymptotic expansion; if ``none`` is given, then ``var('r')`` will be + assigned + - ``numerical`` -- (default: 0) a natural number; if ``numerical`` is + greater than 0, then return a numerical approximation of + `F_{r \alpha}` with ``numerical`` digits of precision; otherwise + return exact values + - ``verbose`` -- boolean (default: ``False``); print the current state of the algorithm OUTPUT: @@ -1677,29 +1646,26 @@ def asymptotics_smooth(self, p, alpha, N, asy_var, coordinate=None, INPUT: - - ``p`` -- a dictionary with keys that can be coerced to equal + - ``p`` -- dictionary with keys that can be coerced to equal ``self.denominator_ring.gens()`` - - ``alpha`` -- a tuple of length ``d = self.dimension()`` of - positive integers or, if `p` is a smooth point, - possibly of symbolic variables - - ``N`` -- a positive integer - - ``asy_var`` -- (optional; default: ``None``) a symbolic variable; - the variable of the asymptotic expansion, - if none is given, ``var('r')`` will be assigned - - ``coordinate`` -- (optional; default: ``None``) an integer in - `\{0, \ldots, d-1\}` indicating a convenient coordinate to base - the asymptotic calculations on; if ``None`` is assigned, then - choose ``coordinate=d-1`` - - ``numerical`` -- (optional; default: 0) a natural number; - if numerical is greater than 0, then return a numerical approximation - of the Maclaurin ray coefficients of ``self`` with ``numerical`` - digits of precision; otherwise return exact values - - ``verbose`` -- (default: ``False``) print the current state of - the algorithm - - OUTPUT: + - ``alpha`` -- tuple of length ``d = self.dimension()`` of positive + integers or, if `p` is a smooth point, possibly of symbolic variables + - ``N`` -- positive integer + - ``asy_var`` -- (default: ``None``) a symbolic variable; the variable + of the asymptotic expansion, if none is given, ``var('r')`` will be + assigned + - ``coordinate`` -- (default: ``None``) an integer in + `\{0, \ldots, d-1\}` indicating a convenient coordinate to base the + asymptotic calculations on; if ``None`` is assigned, then choose + ``coordinate=d-1`` + - ``numerical`` -- (default: 0) a natural number; if numerical is + greater than 0, then return a numerical approximation of the + Maclaurin ray coefficients of ``self`` with ``numerical`` digits of + precision; otherwise return exact values + - ``verbose`` -- boolean (default: ``False``); print the current state + of the algorithm - The asymptotic expansion. + OUTPUT: the asymptotic expansion EXAMPLES:: @@ -2055,29 +2021,26 @@ def asymptotics_multiple(self, p, alpha, N, asy_var, coordinate=None, INPUT: - - ``p`` -- a dictionary with keys that can be coerced to equal + - ``p`` -- dictionary with keys that can be coerced to equal ``self.denominator_ring.gens()`` - - ``alpha`` -- a tuple of length ``d = self.dimension()`` of - positive integers or, if `p` is a smooth point, - possibly of symbolic variables - - ``N`` -- a positive integer - - ``asy_var`` -- (optional; default: ``None``) a symbolic variable; - the variable of the asymptotic expansion, - if none is given, ``var('r')`` will be assigned - - ``coordinate`` -- (optional; default: ``None``) an integer in - `\{0, \ldots, d-1\}` indicating a convenient coordinate to base - the asymptotic calculations on; if ``None`` is assigned, then - choose ``coordinate=d-1`` - - ``numerical`` -- (optional; default: 0) a natural number; - if numerical is greater than 0, then return a numerical approximation - of the Maclaurin ray coefficients of ``self`` with ``numerical`` - digits of precision; otherwise return exact values - - ``verbose`` -- (default: ``False``) print the current state of + - ``alpha`` -- tuple of length ``d = self.dimension()`` of positive + integers or, if `p` is a smooth point, possibly of symbolic variables + - ``N`` -- positive integer + - ``asy_var`` -- (default: ``None``) a symbolic variable; the variable + of the asymptotic expansion, if none is given, ``var('r')`` will be + assigned + - ``coordinate`` -- (default: ``None``) an integer in + `\{0, \ldots, d-1\}` indicating a convenient coordinate to base the + asymptotic calculations on; if ``None`` is assigned, then choose + ``coordinate=d-1`` + - ``numerical`` -- (default: 0) a natural number; if numerical is + greater than 0, then return a numerical approximation of the + Maclaurin ray coefficients of ``self`` with ``numerical`` digits of + precision. Otherwise return exact values. + - ``verbose`` -- boolean (default: ``False``); print the current state of the algorithm - OUTPUT: - - The asymptotic expansion. + OUTPUT: the asymptotic expansion EXAMPLES:: @@ -2357,9 +2320,9 @@ def _crit_cone_combo(self, p, alpha, coordinate=None): INPUT: - - ``p`` -- a dictionary with keys that can be coerced to equal + - ``p`` -- dictionary with keys that can be coerced to equal ``self.denominator_ring.gens()`` - - ``alpha`` -- a list of rationals + - ``alpha`` -- list of rationals OUTPUT: @@ -2426,12 +2389,10 @@ def grads(self, p): INPUT: - - ``p`` -- (optional; default: ``None``) a dictionary whose keys are + - ``p`` -- (default: ``None``) a dictionary whose keys are the generators of ``self.denominator_ring`` - OUTPUT: - - A list. + OUTPUT: list EXAMPLES:: @@ -2476,12 +2437,10 @@ def log_grads(self, p): INPUT: - - ``p`` -- (optional; default: ``None``) a dictionary whose keys + - ``p`` -- (default: ``None``) a dictionary whose keys are the generators of ``self.denominator_ring`` - OUTPUT: - - A list. + OUTPUT: list EXAMPLES:: @@ -2521,13 +2480,11 @@ def critical_cone(self, p, coordinate=None): INPUT: - - ``p`` -- a dictionary with keys that can be coerced to equal + - ``p`` -- dictionary with keys that can be coerced to equal ``self.denominator_ring.gens()`` and values in a field - - ``coordinate`` -- (optional; default: ``None``) a natural number + - ``coordinate`` -- (default: ``None``) a natural number - OUTPUT: - - A list of vectors. + OUTPUT: list of vectors This list of vectors generate the critical cone of ``p`` and the cone itself, which is ``None`` if the values of ``p`` don't lie in @@ -2578,7 +2535,7 @@ def critical_cone(self, p, coordinate=None): def is_convenient_multiple_point(self, p): r""" - Tests if ``p`` is a convenient multiple point of ``self``. + Test if ``p`` is a convenient multiple point of ``self``. In case ``p`` is a convenient multiple point, ``verdict = True`` and ``comment`` is a string stating which variables it's convenient to use. @@ -2589,7 +2546,7 @@ def is_convenient_multiple_point(self, p): INPUT: - - ``p`` -- a dictionary with keys that can be coerced to equal + - ``p`` -- dictionary with keys that can be coerced to equal ``self.denominator_ring.gens()`` OUTPUT: @@ -2671,9 +2628,7 @@ def singular_ideal(self): then the output is the ideal of the singular locus (which is a variety) of the variety of `H`. - OUTPUT: - - An ideal. + OUTPUT: an ideal EXAMPLES:: @@ -2708,12 +2663,10 @@ def smooth_critical_ideal(self, alpha): INPUT: - - ``alpha`` -- a tuple of positive integers and/or symbolic entries + - ``alpha`` -- tuple of positive integers and/or symbolic entries of length ``self.denominator_ring.ngens()`` - OUTPUT: - - An ideal. + OUTPUT: an ideal EXAMPLES:: @@ -2773,11 +2726,11 @@ def maclaurin_coefficients(self, multi_indices, numerical=0): INPUT: - - ``multi_indices`` -- a list of tuples of positive integers, where + - ``multi_indices`` -- list of tuples of positive integers, where each tuple has length ``self.dimension()`` - - ``numerical`` -- (optional; default: 0) a natural number; if - positive, return numerical approximations of coefficients with - ``numerical`` digits of accuracy + - ``numerical`` -- (default: 0) a natural number; if positive, return + numerical approximations of coefficients with ``numerical`` digits of + accuracy OUTPUT: @@ -2876,14 +2829,12 @@ def relative_error(self, approx, alpha, interval, exp_scale=Integer(1), - ``approx`` -- an individual or list of symbolic expressions in one variable - - ``alpha`` -- a list of positive integers of length + - ``alpha`` -- list of positive integers of length ``self.denominator_ring.ngens()`` - - ``interval`` -- a list of positive integers - - ``exp_scale`` -- (optional; default: 1) a number + - ``interval`` -- list of positive integers + - ``exp_scale`` -- (default: 1) a number - OUTPUT: - - A list of tuples with properties described below. + OUTPUT: list of tuples with properties described below This outputs a list whose entries are a tuple ``(r*alpha, a_r, b_r, err_r)`` for ``r`` in ``interval``. @@ -2953,7 +2904,7 @@ def relative_error(self, approx, alpha, interval, exp_scale=Integer(1), def _add_(left, right): r""" - Returns the sum of ``left`` with ``right``. + Return the sum of ``left`` with ``right``. INPUT: @@ -2961,9 +2912,7 @@ def _add_(left, right): - ``right`` -- the right summand - OUTPUT: - - The sum as a new element. + OUTPUT: the sum as a new element EXAMPLES:: @@ -2980,7 +2929,7 @@ def _add_(left, right): def _mul_(left, right): r""" - Returns the product of ``left`` with ``right``. + Return the product of ``left`` with ``right``. INPUT: @@ -2988,9 +2937,7 @@ def _mul_(left, right): - ``right`` -- the right factor - OUTPUT: - - The product as a new element. + OUTPUT: the product as a new element EXAMPLES:: @@ -3085,9 +3032,7 @@ def _repr_(self) -> str: r""" Return a representation. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -3102,11 +3047,9 @@ def _repr_(self) -> str: def base_ring(self): r""" - Returns the base ring. - - OUTPUT: + Return the base ring. - A ring. + OUTPUT: a ring EXAMPLES:: @@ -3124,7 +3067,7 @@ def base_ring(self): def _element_constructor_(self, *args, **kwargs): r""" - Returns an element of this ring. + Return an element of this ring. See :class:`FractionWithFactoredDenominator` for details. @@ -3222,9 +3165,9 @@ def _element_constructor_(self, *args, **kwargs): p = numerator q = R(denominator) - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing - if is_PolynomialRing(R) or is_MPolynomialRing(R): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base + if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base): if not R(q).is_unit(): # Factor denominator try: @@ -3247,15 +3190,13 @@ def _element_constructor_(self, *args, **kwargs): def _coerce_map_from_(self, P): r""" - Checks if there is a coercion from the given parent. + Check if there is a coercion from the given parent. INPUT: - ``P`` -- a parent - OUTPUT: - - ``True`` if there is a coercion, otherwise ``False`` or ``None``. + OUTPUT: ``True`` if there is a coercion, otherwise ``False`` or ``None`` TESTS:: @@ -3292,9 +3233,9 @@ def _coerce_map_from_(self, P): from sage.rings.fraction_field import FractionField_generic if isinstance(P, FractionField_generic): B = P.base() - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing - if is_PolynomialRing(B) or is_MPolynomialRing(B): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base + if isinstance(B, PolynomialRing_general) or isinstance(B, MPolynomialRing_base): if self.base().has_coerce_map_from(B): return True @@ -3303,11 +3244,7 @@ def _coerce_map_from_(self, P): def _an_element_(self): r""" - Returns an element. - - OUTPUT: - - An element. + Return an element. TESTS:: @@ -3339,9 +3276,7 @@ def __repr__(self) -> str: r""" Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3359,9 +3294,7 @@ def __eq__(self, other) -> bool: r""" Return ``True`` if ``self`` is equal to ``other``. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -3385,9 +3318,7 @@ def __ne__(self, other) -> bool: r""" Return ``True`` if ``self`` is not equal to ``other``. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -3410,9 +3341,7 @@ def denominator_ring(self): r""" Return the polynomial ring of the denominators of ``self``. - OUTPUT: - - A ring or ``None`` if the list is empty. + OUTPUT: a ring or ``None`` if the list is empty EXAMPLES:: @@ -3437,9 +3366,7 @@ def whole_and_parts(self): Rewrite ``self`` as a sum of a (possibly zero) polynomial followed by reduced rational expressions. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` Only useful for multivariate decompositions. @@ -3494,9 +3421,7 @@ def _combine_like_terms_(self): Combine terms in ``self`` with the same denominator. Only useful for multivariate decompositions. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominatorSum`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominatorSum` EXAMPLES:: @@ -3549,9 +3474,7 @@ def sum(self): r""" Return the sum of the elements in ``self``. - OUTPUT: - - An instance of :class:`FractionWithFactoredDenominator`. + OUTPUT: an instance of :class:`FractionWithFactoredDenominator` EXAMPLES:: @@ -3578,7 +3501,7 @@ def sum(self): # Compute the sum's numerator and denominator. R = self.denominator_ring - summy = sum((f.quotient() for f in self)) + summy = sum(f.quotient() for f in self) numer = summy.numerator() denom = R(summy.denominator()) @@ -3622,21 +3545,21 @@ def diff_prod(f_derivs, u, g, X, interval, end, uderivs, atc): INPUT: - - ``f_derivs`` -- a dictionary whose keys are all tuples of the form + - ``f_derivs`` -- dictionary whose keys are all tuples of the form ``s + end``, where ``s`` is a sequence of variables from ``X`` whose length lies in ``interval``, and whose values are the derivatives of a function `f` evaluated at `c` - ``u`` -- a callable symbolic function - ``g`` -- an expression or callable symbolic function - - ``X`` -- a list of symbolic variables - - ``interval`` -- a list of positive integers + - ``X`` -- list of symbolic variables + - ``interval`` -- list of positive integers Call the first and last values `n` and `nn`, respectively - ``end`` -- a possibly empty list of repetitions of the variable ``z``, where ``z`` is the last element of ``X`` - - ``uderivs`` -- a dictionary whose keys are the symbolic + - ``uderivs`` -- dictionary whose keys are the symbolic derivatives of order 0 to order `n-1` of ``u`` evaluated at `c` and whose values are the corresponding derivatives evaluated at `c` - - ``atc`` -- a dictionary whose keys are the keys of `c` and all + - ``atc`` -- dictionary whose keys are the keys of `c` and all the symbolic derivatives of order 0 to order `nn` of ``g`` evaluated `c` and whose values are the corresponding derivatives evaluated at `c` @@ -3712,7 +3635,7 @@ def permutation_sign(s, u): INPUT: - ``s`` -- a sublist of ``u`` - - ``u`` -- a list + - ``u`` -- list OUTPUT: @@ -3756,7 +3679,7 @@ def subs_all(f, sub, simplify=False): - ``f`` -- an individual or list of symbolic expressions or dictionaries - ``sub`` -- an individual or list of dictionaries - - ``simplify`` -- (default: ``False``) boolean; set to ``True`` to + - ``simplify`` -- boolean (default: ``False``); set to ``True`` to simplify the result OUTPUT: @@ -3839,17 +3762,15 @@ def diff_all(f, V, n, ending=[], sub=None, sub_final=None, INPUT: - ``f`` -- an individual or list of `\mathcal{C}^{n+1}` functions - - ``V`` -- a list of variables occurring in `f` + - ``V`` -- list of variables occurring in `f` - ``n`` -- a natural number - - ``ending`` -- a list of variables in `V` + - ``ending`` -- list of variables in `V` - ``sub`` -- an individual or list of dictionaries - ``sub_final`` -- an individual or list of dictionaries - ``rekey`` -- a callable symbolic function in `V` or list thereof - ``zero_order`` -- a natural number - OUTPUT: - - The dictionary ``{s_1:deriv_1, ..., sr:deriv_r}``. + OUTPUT: the dictionary ``{s_1:deriv_1, ..., sr:deriv_r}`` Here ``s_1, ..., s_r`` is a listing of all nondecreasing sequences of length 1 up to length `n` over the @@ -3987,8 +3908,8 @@ def diff_op(A, B, AB_derivs, V, M, r, N): - ``A`` -- a single or length ``r`` list of symbolic functions in the variables ``V`` - - ``B`` -- a symbolic function in the variables ``V``. - - ``AB_derivs`` -- a dictionary whose keys are the (symbolic) + - ``B`` -- a symbolic function in the variables ``V`` + - ``AB_derivs`` -- dictionary whose keys are the (symbolic) derivatives of ``A[0], ..., A[r-1]`` up to order ``2 * N-2`` and the (symbolic) derivatives of ``B`` up to order ``2 * N``; the values of the dictionary are complex numbers that are @@ -3998,9 +3919,7 @@ def diff_op(A, B, AB_derivs, V, M, r, N): length of ``V`` - ``r``, ``N`` -- natural numbers - OUTPUT: - - A dictionary. + OUTPUT: a dictionary The output is a dictionary whose keys are natural number tuples of the form @@ -4081,8 +4000,8 @@ def diff_seq(V, s): INPUT: - - ``V`` -- a list - - ``s`` -- a list of tuples of natural numbers in the interval + - ``V`` -- list + - ``s`` -- list of tuples of natural numbers in the interval ``range(len(V))`` OUTPUT: @@ -4124,8 +4043,8 @@ def diff_op_simple(A, B, AB_derivs, x, v, a, N): INPUT: - - ``A``, ``B`` -- Symbolic functions in the variable ``x`` - - ``AB_derivs`` -- a dictionary whose keys are the (symbolic) + - ``A``, ``B`` -- symbolic functions in the variable ``x`` + - ``AB_derivs`` -- dictionary whose keys are the (symbolic) derivatives of ``A`` up to order ``2 * N`` if ``v`` is even or ``N`` if ``v`` is odd and the (symbolic) derivatives of ``B`` up to order ``2 * N + v`` if ``v`` is even or ``N + v`` @@ -4135,9 +4054,7 @@ def diff_op_simple(A, B, AB_derivs, x, v, a, N): - ``a`` -- a complex number - ``v``, ``N`` -- natural numbers - OUTPUT: - - A dictionary. + OUTPUT: a dictionary The output is a dictionary whose keys are natural number pairs of the form `(k, l)`, @@ -4188,7 +4105,7 @@ def direction(v, coordinate=None): INPUT: - ``v`` -- a vector - - ``coordinate`` -- (optional; default: ``None``) an index for ``v`` + - ``coordinate`` -- (default: ``None``) an index for ``v`` EXAMPLES:: diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py index 1d7d3049405..cf9cf74ca70 100644 --- a/src/sage/rings/asymptotic/growth_group.py +++ b/src/sage/rings/asymptotic/growth_group.py @@ -259,10 +259,10 @@ class Variable(CachedRepresentation, SageObject): e.g. ``log(x)^ZZ``: ``var`` is then used to specify the variable `x`. - ``latex_name`` -- (default: ``None``) if specified, then this string - will be used as LaTeX-representation of ``var``. + will be used as LaTeX-representation of ``var`` - ``ignore`` -- (default: ``None``) a tuple (or other iterable) - of strings which are not variables. + of strings which are not variables TESTS:: @@ -404,11 +404,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- another variable. + - ``other`` -- another variable - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -426,11 +424,9 @@ def __ne__(self, other): INPUT: - - ``other`` -- another variable. - - OUTPUT: + - ``other`` -- another variable - A boolean. + OUTPUT: boolean TESTS:: @@ -446,9 +442,7 @@ def _repr_(self): r""" Return a representation string of this variable. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -462,9 +456,7 @@ def _latex_(self): r""" Return a LaTeX-representation string of this variable. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -482,9 +474,7 @@ def variable_names(self): r""" Return the names of the variables. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -500,9 +490,7 @@ def is_monomial(self): r""" Return whether this is a monomial variable. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -521,11 +509,9 @@ def extract_variable_names(s): INPUT: - - ``s`` -- a string. - - OUTPUT: + - ``s`` -- string - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -601,11 +587,9 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. + - ``rules`` -- dictionary - OUTPUT: - - An object. + OUTPUT: an object TESTS:: @@ -653,7 +637,7 @@ class PartialConversionValueError(ValueError): """ def __init__(self, element, *args, **kwds): r""" - See :class:`PartialConversionValueError` for more information. + See :exc:`PartialConversionValueError` for more information. TESTS:: @@ -679,9 +663,9 @@ class PartialConversionElement(SageObject): - ``raw_element`` -- an object A :class:`PartialConversionElement` is an element ``growth_group(raw_element)`` - which usually appears in conjunction with :class:`PartialConversionValueError`. + which usually appears in conjunction with :exc:`PartialConversionValueError`. In this case, it was to possible to create that element, although - the conversion went partially well in the sense that a `raw_element`` + the conversion went partially well in the sense that a ``raw_element`` (e.g. an exponent for :class:`MonomialGrowthElement` or a base for :class:`ExponentialGrowthElement`) could be extracted. @@ -777,13 +761,7 @@ def _is_lt_one_(self): r""" Return whether this element is less than `1`. - INPUT: - - Nothing. - - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -809,9 +787,7 @@ def _log_(self, base=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - OUTPUT: - - A growth element. + OUTPUT: a growth element EXAMPLES:: @@ -926,7 +902,7 @@ def _log_factor_(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. @@ -1000,11 +976,9 @@ def _rpow_(self, base): INPUT: - - ``base`` -- an element. - - OUTPUT: + - ``base`` -- an element - A growth element. + OUTPUT: a growth element EXAMPLES:: @@ -1122,9 +1096,9 @@ class GenericGrowthElement(MultiplicativeGroupElement): INPUT: - - ``parent`` -- a :class:`GenericGrowthGroup`. + - ``parent`` -- a :class:`GenericGrowthGroup` - - ``raw_element`` -- an element from the base of the parent. + - ``raw_element`` -- an element from the base of the parent EXAMPLES:: @@ -1207,13 +1181,7 @@ def _repr_(self): r""" A representation string for this generic element. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1234,13 +1202,7 @@ def __hash__(self): r""" Return the hash of this element. - INPUT: - - Nothing. - - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -1257,7 +1219,7 @@ def _mul_(self, other): INPUT: - - ``other`` -- a :class:`GenericGrowthElement`. + - ``other`` -- a :class:`GenericGrowthElement` OUTPUT: @@ -1284,9 +1246,7 @@ def __invert__(self): r""" Return the inverse of this growth element. - OUTPUT: - - An instance of :class:`GenericGrowthElement`. + OUTPUT: an instance of :class:`GenericGrowthElement` TESTS:: @@ -1319,9 +1279,7 @@ def _eq_(self, other): - ``other`` -- a :class:`GenericGrowthElement` - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -1390,9 +1348,7 @@ def _lt_(self, other): - ``other`` -- a :class:`GenericGrowthElement` - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -1434,7 +1390,7 @@ def _log_factor_(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. @@ -1467,11 +1423,9 @@ def _rpow_element_(self, base): INPUT: - - ``base`` -- an element. - - OUTPUT: + - ``base`` -- an element - Nothing since a ``ValueError`` is raised in this generic method. + OUTPUT: nothing since a :exc:`ValueError` is raised in this generic method TESTS:: @@ -1491,13 +1445,7 @@ def factors(self): Return the atomic factors of this growth element. An atomic factor cannot be split further. - INPUT: - - Nothing. - - OUTPUT: - - A tuple of growth elements. + OUTPUT: a tuple of growth elements EXAMPLES:: @@ -1516,11 +1464,9 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. - - OUTPUT: + - ``rules`` -- dictionary - An object. + OUTPUT: an object TESTS:: @@ -1543,9 +1489,7 @@ def variable_names(self): r""" Return the names of the variables of this growth element. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -1585,11 +1529,11 @@ def _singularity_analysis_(self, var, zeta, precision): INPUT: - - ``var`` -- a string denoting the variable + - ``var`` -- string denoting the variable - ``zeta`` -- a number - - ``precision`` -- an integer + - ``precision`` -- integer OUTPUT: @@ -1617,14 +1561,12 @@ def _find_minimum_(self, valid_from): INPUT: - - ``valid_from`` -- a dictionary describing the range of the minimization: + - ``valid_from`` -- dictionary describing the range of the minimization: the keys are names of variables and the range is the intersection over the ranges where the absolute value of the variable designated by the key is at least the corresponding value - OUTPUT: - - A number + OUTPUT: a number TESTS:: @@ -1646,7 +1588,7 @@ class GenericGrowthGroup(UniqueRepresentation, Parent, WithLocals): INPUT: - ``base`` -- one of SageMath's parents, out of which the elements - get their data (``raw_element``). + get their data (``raw_element``) - ``category`` -- (default: ``None``) the category of the newly created growth group. It has to be a subcategory of ``Join of @@ -1693,7 +1635,7 @@ class GenericGrowthGroup(UniqueRepresentation, Parent, WithLocals): @staticmethod def __classcall__(cls, base, var=None, category=None, ignore_variables=None): r""" - Normalizes the input in order to ensure a unique + Normalize the input in order to ensure a unique representation. For more information see :class:`GenericGrowthGroup`. @@ -1787,9 +1729,7 @@ def _initial_category_(base): - ``base`` -- a SageMath parent - OUTPUT: - - A category or ``None``. + OUTPUT: a category or ``None`` TESTS:: @@ -1805,9 +1745,9 @@ def _initial_category_(base): # The following block can be removed once #19269 is fixed. from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general if base is ZZ or base is QQ or \ - is_PolynomialRing(base) and \ + isinstance(base, PolynomialRing_general) and \ (base.base_ring() is ZZ or base.base_ring() is QQ): return Posets() else: @@ -1882,7 +1822,6 @@ def __init__(self, base, var, category): Traceback (most recent call last): ... TypeError: x is not a valid base. - """ self._var_ = var super().__init__(category=category, base=base) @@ -1891,13 +1830,7 @@ def _repr_short_(self): r""" A short representation string of this abstract growth group. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1921,13 +1854,11 @@ def _repr_(self, condense=False): INPUT: - - ``condense`` -- (default: ``False``) if set, then a shorter - output is returned, e.g. the prefix-string ``Growth Group`` - is not show in this case. + - ``condense`` -- boolean (default: ``False``); if set, then a shorter + output is returned, e.g. the prefix-string ``Growth Group`` is not + shown in this case - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1949,13 +1880,7 @@ def __hash__(self): r""" Return the hash of this group. - INPUT: - - Nothing. - - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -2005,13 +1930,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -2035,11 +1954,9 @@ def _create_element_in_extension_(self, raw_element): INPUT: - - ``raw_element`` -- the element data. - - OUTPUT: + - ``raw_element`` -- the element data - An element. + OUTPUT: an element EXAMPLES:: @@ -2064,13 +1981,11 @@ def le(self, left, right): INPUT: - - ``left`` -- an element. - - - ``right`` -- an element. + - ``left`` -- an element - OUTPUT: + - ``right`` -- an element - A boolean. + OUTPUT: boolean .. NOTE:: @@ -2097,16 +2012,13 @@ def _element_constructor_(self, data, raw_element=None): INPUT: - - ``data`` -- an object representing the element to be - initialized. + - ``data`` -- an object representing the element to be initialized - ``raw_element`` -- (default: ``None``) if given, then this is directly passed to the element constructor (i.e., no conversion is performed). - OUTPUT: - - An element of this growth group. + OUTPUT: an element of this growth group .. NOTE:: @@ -2249,7 +2161,7 @@ def _convert_(self, data): INPUT: - - ``data`` -- an object. + - ``data`` -- an object OUTPUT: @@ -2313,9 +2225,7 @@ def _split_raw_element_(raw_element): - ``raw_element`` -- an object - OUTPUT: - - A pair of objects. + OUTPUT: a pair of objects .. NOTE:: @@ -2339,11 +2249,9 @@ def _coerce_map_from_(self, S): INPUT: - - ``S`` -- a parent. + - ``S`` -- a parent - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -2467,13 +2375,7 @@ def gens_monomial(self): Return a tuple containing monomial generators of this growth group. - INPUT: - - Nothing. - - OUTPUT: - - An empty tuple. + OUTPUT: an empty tuple .. NOTE:: @@ -2503,13 +2405,7 @@ def gens(self): r""" Return a tuple of all generators of this growth group. - INPUT: - - Nothing. - - OUTPUT: - - A tuple whose entries are growth elements. + OUTPUT: a tuple whose entries are growth elements EXAMPLES:: @@ -2528,11 +2424,9 @@ def gen(self, n=0): INPUT: - - ``n`` -- default: `0`. + - ``n`` -- (default: `0`) - OUTPUT: - - A :class:`MonomialGrowthElement`. + OUTPUT: a :class:`MonomialGrowthElement` EXAMPLES:: @@ -2555,13 +2449,7 @@ def ngens(self): r""" Return the number of generators (as a group) of this growth group. - INPUT: - - Nothing. - - OUTPUT: - - A Python integer. + OUTPUT: a Python integer EXAMPLES:: @@ -2584,9 +2472,7 @@ def variable_names(self): r""" Return the names of the variables of this growth group. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -2618,9 +2504,7 @@ def extended_by_non_growth_group(self): Extend to a cartesian product of this growth group and a suitable non growth group. - OUTPUT: - - A group group. + OUTPUT: a group group EXAMPLES:: @@ -2647,9 +2531,7 @@ def non_growth_group(self): r""" Return a non-growth group compatible with this growth group. - OUTPUT: - - A group group. + OUTPUT: a group group EXAMPLES:: @@ -2668,10 +2550,10 @@ class AbstractGrowthGroupFunctor(ConstructionFunctor): INPUT: - - ``var`` -- a string or list of strings (or anything else - :class:`Variable` accepts). + - ``var`` -- string or list of strings (or anything else :class:`Variable` + accepts) - - ``domain`` -- a category. + - ``domain`` -- a category EXAMPLES:: @@ -2716,9 +2598,7 @@ def _repr_(self): r""" Return a representation string of this functor. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -2734,11 +2614,9 @@ def merge(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A functor or ``None``. + OUTPUT: a functor or ``None`` EXAMPLES:: @@ -2759,11 +2637,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- a functor. + - ``other`` -- a functor - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -2783,11 +2659,9 @@ def __ne__(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -2816,7 +2690,7 @@ class DecreasingGrowthElementError(ValueError): """ def __init__(self, element, *args, **kwds): r""" - See :class:`DecreasingGrowthElementError` for more information. + See :exc:`DecreasingGrowthElementError` for more information. TESTS:: @@ -2837,9 +2711,9 @@ class MonomialGrowthElement(GenericGrowthElement): INPUT: - - ``parent`` -- a :class:`MonomialGrowthGroup`. + - ``parent`` -- a :class:`MonomialGrowthGroup` - - ``raw_element`` -- an element from the base ring of the parent. + - ``raw_element`` -- an element from the base ring of the parent This ``raw_element`` is the exponent of the created monomial growth element. @@ -2884,12 +2758,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. + - ``latex`` -- boolean (default: ``False``); if set, then LaTeX-output + is returned - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -2945,9 +2817,7 @@ def _latex_(self): r""" A LaTeX-representation string for this monomial growth element. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -2977,9 +2847,7 @@ def _mul_(self, other): - ``other`` -- a :class:`MonomialGrowthElement` - OUTPUT: - - The product as a :class:`MonomialGrowthElement`. + OUTPUT: the product as a :class:`MonomialGrowthElement` .. NOTE:: @@ -3005,13 +2873,7 @@ def __invert__(self): r""" Return the multiplicative inverse of this monomial growth element. - INPUT: - - Nothing. - - OUTPUT: - - The multiplicative inverse as a :class:`MonomialGrowthElement`. + OUTPUT: the multiplicative inverse as a :class:`MonomialGrowthElement` EXAMPLES:: @@ -3041,9 +2903,7 @@ def __pow__(self, exponent): valid right hand side of ``*`` with elements of the parent's base. - OUTPUT: - - The result of this exponentiation, a :class:`MonomialGrowthElement`. + OUTPUT: the result of this exponentiation, a :class:`MonomialGrowthElement` EXAMPLES:: @@ -3077,10 +2937,10 @@ def _log_factor_(self, base=None, locals=None): INPUT: - - ``base`` -- the base of the logarithm. If ``None`` - (default value) is used, the natural logarithm is taken. + - ``base`` -- the base of the logarithm. If ``None`` (default value) is + used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. @@ -3154,23 +3014,21 @@ def _rpow_element_(self, base, locals=None): INPUT: - - ``base`` -- an element. + - ``base`` -- an element - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - A growth element. + OUTPUT: a growth element .. NOTE:: The parent of the result can be different from the parent of this element. - A ``ValueError`` is raised if the calculation is not possible + A :exc:`ValueError` is raised if the calculation is not possible within this method. (Then the calling method should take care of the calculation.) @@ -3229,9 +3087,7 @@ def _lt_(self, other): - ``other`` -- a :class:`MonomialGrowthElement` - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -3254,13 +3110,10 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. - The neutral element of the group is replaced by the value - to key ``'_one_'``. + - ``rules`` -- dictionary; the neutral element of the group is replaced + by the value to key ``'_one_'`` - OUTPUT: - - An object. + OUTPUT: an object TESTS:: @@ -3296,11 +3149,11 @@ def _singularity_analysis_(self, var, zeta, precision): INPUT: - - ``var`` -- a string denoting the variable + - ``var`` -- string denoting the variable - ``zeta`` -- a number - - ``precision`` -- an integer + - ``precision`` -- integer OUTPUT: @@ -3366,14 +3219,12 @@ def _find_minimum_(self, valid_from): INPUT: - - ``valid_from`` -- a dictionary describing the range of the minimization: + - ``valid_from`` -- dictionary describing the range of the minimization: the keys are names of variables and the range is the intersection over the ranges where the absolute value of the variable designated by the key is at least the corresponding value - OUTPUT: - - A number + OUTPUT: a number TESTS:: @@ -3424,12 +3275,12 @@ class MonomialGrowthGroup(GenericGrowthGroup): INPUT: - ``base`` -- one of SageMath's parents, out of which the elements - get their data (``raw_element``). + get their data (``raw_element``) As monomials are represented by this group, the elements in ``base`` are the exponents of these monomials. - - ``var`` -- an object. + - ``var`` -- an object The string representation of ``var`` acts as a base of the monomials represented by this group. @@ -3483,13 +3334,7 @@ def _repr_short_(self): r""" A short representation string of this monomial growth group. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3517,7 +3362,7 @@ def _convert_(self, data): INPUT: - - ``data`` -- an object. + - ``data`` -- an object OUTPUT: @@ -3657,9 +3502,7 @@ def _split_raw_element_(raw_element): - ``raw_element`` -- an object - OUTPUT: - - A pair of objects. + OUTPUT: a pair of objects .. NOTE:: @@ -3681,13 +3524,7 @@ def gens_monomial(self): Return a tuple containing monomial generators of this growth group. - INPUT: - - Nothing. - - OUTPUT: - - A tuple containing elements of this growth group. + OUTPUT: a tuple containing elements of this growth group .. NOTE:: @@ -3714,13 +3551,7 @@ def gens_logarithmic(self): Return a tuple containing logarithmic generators of this growth group. - INPUT: - - Nothing. - - OUTPUT: - - A tuple containing elements of this growth group. + OUTPUT: a tuple containing elements of this growth group .. NOTE:: @@ -3777,17 +3608,15 @@ def factory(cls, exponential growth group; see :class:`MonomialGrowthGroup` for details. - - ``extend_by_non_growth_group`` -- a boolean (default ``False``). If set, then - the growth group consists of two parts, one part dealing with - the absolute values of the bases and one for their arguments. + - ``extend_by_non_growth_group`` -- boolean (default: ``False``); if + set, then the growth group consists of two parts, one part dealing + with the absolute values of the bases and one for their arguments. - - ``return_factors`` -- a boolean (default: ``False``). If set, + - ``return_factors`` -- boolean (default: ``False``); if set, then a tuple of the (cartesian) factors of this growth group - is returned. - - OUTPUT: + is returned - A growth group or tuple of growth groups. + OUTPUT: a growth group or tuple of growth groups EXAMPLES:: @@ -3830,9 +3659,7 @@ def non_growth_group(self): (with an imaginary group as base) compatible with this monomial growth group. - OUTPUT: - - A group group. + OUTPUT: a group group EXAMPLES:: @@ -3851,8 +3678,8 @@ class MonomialGrowthGroupFunctor(AbstractGrowthGroupFunctor): INPUT: - - ``var`` -- a string or list of strings (or anything else - :class:`Variable` accepts). + - ``var`` -- string or list of strings (or anything else + :class:`Variable` accepts) EXAMPLES:: @@ -3899,11 +3726,9 @@ def _apply_functor(self, base): INPUT: - - ``base`` -- anything :class:`MonomialGrowthGroup` accepts. - - OUTPUT: + - ``base`` -- anything :class:`MonomialGrowthGroup` accepts - A monomial growth group. + OUTPUT: a monomial growth group EXAMPLES:: @@ -3921,9 +3746,9 @@ class ExponentialGrowthElement(GenericGrowthElement): INPUT: - - ``parent`` -- an :class:`ExponentialGrowthGroup`. + - ``parent`` -- an :class:`ExponentialGrowthGroup` - - ``raw_element`` -- an element from the base ring of the parent. + - ``raw_element`` -- an element from the base ring of the parent This ``raw_element`` is the base of the created exponential growth element. @@ -3992,12 +3817,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -4049,9 +3872,7 @@ def _latex_(self): r""" A LaTeX-representation string for this exponential growth element. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -4092,9 +3913,7 @@ def _mul_(self, other): - ``other`` -- a :class:`ExponentialGrowthElement` - OUTPUT: - - The product as a :class:`ExponentialGrowthElement`. + OUTPUT: the product as a :class:`ExponentialGrowthElement` .. NOTE:: @@ -4120,13 +3939,7 @@ def __invert__(self): r""" Return the multiplicative inverse of this exponential growth element. - INPUT: - - Nothing. - - OUTPUT: - - The multiplicative inverse as a :class:`ExponentialGrowthElement`. + OUTPUT: the multiplicative inverse as a :class:`ExponentialGrowthElement` EXAMPLES:: @@ -4165,9 +3978,7 @@ def __pow__(self, exponent): on the right hand side of ``*`` with an elements of the parent's base. - OUTPUT: - - The result of this exponentiation as an :class:`ExponentialGrowthElement`. + OUTPUT: the result of this exponentiation as an :class:`ExponentialGrowthElement` EXAMPLES:: @@ -4209,7 +4020,7 @@ def _log_factor_(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. @@ -4264,9 +4075,7 @@ def _lt_(self, other): - ``other`` -- a :class:`ExponentialGrowthElement` - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -4297,13 +4106,10 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. - The neutral element of the group is replaced by the value - to key ``'_one_'``. + - ``rules`` -- dictionary; the neutral element of the group is replaced + by the value to key ``'_one_'`` - OUTPUT: - - An object. + OUTPUT: an object TESTS:: @@ -4341,12 +4147,12 @@ class ExponentialGrowthGroup(GenericGrowthGroup): INPUT: - ``base`` -- one of SageMath's parents, out of which the elements - get their data (``raw_element``). + get their data (``raw_element``) As exponential expressions are represented by this group, the elements in ``base`` are the bases of these exponentials. - - ``var`` -- an object. + - ``var`` -- an object The string representation of ``var`` acts as an exponent of the elements represented by this group. @@ -4426,13 +4232,7 @@ def _repr_short_(self): r""" A short representation string of this exponential growth group. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -4453,12 +4253,12 @@ def _repr_short_(self): def _convert_(self, data): r""" - Converts given ``data`` to something the constructor of the + Convert given ``data`` to something the constructor of the element class accepts (``raw_element``). INPUT: - - ``data`` -- an object. + - ``data`` -- an object OUTPUT: @@ -4578,9 +4378,7 @@ def _split_raw_element_(base): - ``raw_element`` -- an object - OUTPUT: - - A pair of objects. + OUTPUT: a pair of objects .. NOTE:: @@ -4719,13 +4517,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -4741,13 +4533,7 @@ def gens(self): Return a tuple of all generators of this exponential growth group. - INPUT: - - Nothing. - - OUTPUT: - - An empty tuple. + OUTPUT: an empty tuple EXAMPLES:: @@ -4794,17 +4580,15 @@ def factory(cls, exponential growth group; see :class:`ExponentialGrowthGroup` for details. - - ``extend_by_non_growth_group`` -- a boolean (default ``True``). If set, then - the growth group consists of two parts, one part dealing with - the absolute values of the bases and one for their arguments. + - ``extend_by_non_growth_group`` -- boolean (default: ``True``); if + set, then the growth group consists of two parts, one part dealing + with the absolute values of the bases and one for their arguments. - - ``return_factors`` -- a boolean (default: ``False``). If set, + - ``return_factors`` -- boolean (default: ``False``); if set, then a tuple of the (cartesian) factors of this growth group - is returned. - - OUTPUT: + is returned - A growth group or tuple of growth groups. + OUTPUT: a growth group or tuple of growth groups EXAMPLES:: @@ -4866,9 +4650,7 @@ def non_growth_group(self): (with an argument group, e.g. roots of unity, as base) compatible with this exponential growth group. - OUTPUT: - - A group group. + OUTPUT: a group group EXAMPLES:: @@ -4900,8 +4682,8 @@ class ExponentialGrowthGroupFunctor(AbstractGrowthGroupFunctor): INPUT: - - ``var`` -- a string or list of strings (or anything else - :class:`Variable` accepts). + - ``var`` -- string or list of strings (or anything else + :class:`Variable` accepts) EXAMPLES:: @@ -4948,11 +4730,9 @@ def _apply_functor(self, base): INPUT: - - ``base`` -- anything :class:`ExponentialGrowthGroup` accepts. + - ``base`` -- anything :class:`ExponentialGrowthGroup` accepts - OUTPUT: - - An exponential growth group. + OUTPUT: an exponential growth group EXAMPLES:: @@ -5011,9 +4791,7 @@ def _initial_category_(base): - ``base`` -- a SageMath parent - OUTPUT: - - Always the category of posets. + OUTPUT: always the category of posets TESTS:: @@ -5129,11 +4907,9 @@ def _apply_functor(self, base): INPUT: - - ``base`` -- anything :class:`ExponentialNonGrowthGroup` accepts. + - ``base`` -- anything :class:`ExponentialNonGrowthGroup` accepts - OUTPUT: - - An exponential argument growth group. + OUTPUT: an exponential argument growth group EXAMPLES:: @@ -5211,11 +4987,9 @@ def _apply_functor(self, base): INPUT: - - ``base`` -- anything :class:`MonomialNonGrowthGroup` accepts. - - OUTPUT: + - ``base`` -- anything :class:`MonomialNonGrowthGroup` accepts - An exponential argument growth group. + OUTPUT: an exponential argument growth group EXAMPLES:: @@ -5238,7 +5012,7 @@ class GrowthGroupFactory(UniqueFactory): INPUT: - - ``specification`` -- a string. + - ``specification`` -- string - keyword arguments are passed on to the growth group constructor. @@ -5246,9 +5020,7 @@ class GrowthGroupFactory(UniqueFactory): ``ignore_variables=('e',)`` (to ignore ``e`` as a variable name) is used. - OUTPUT: - - An asymptotic growth group. + OUTPUT: an asymptotic growth group .. NOTE:: diff --git a/src/sage/rings/asymptotic/growth_group_cartesian.py b/src/sage/rings/asymptotic/growth_group_cartesian.py index 27a934e69a5..0bdb3d4a1eb 100644 --- a/src/sage/rings/asymptotic/growth_group_cartesian.py +++ b/src/sage/rings/asymptotic/growth_group_cartesian.py @@ -100,7 +100,7 @@ class CartesianProductFactory(UniqueFactory): INPUT: - - ``growth_groups`` -- a tuple (or other iterable) of growth groups. + - ``growth_groups`` -- tuple (or other iterable) of growth groups - ``order`` -- (default: ``None``) if specified, then this order is taken for comparing two Cartesian product elements. If ``order`` is @@ -325,9 +325,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -357,11 +355,9 @@ def _create_element_in_extension_(self, element): INPUT: - - ``element`` -- a tuple. - - OUTPUT: + - ``element`` -- tuple - An element. + OUTPUT: an element EXAMPLES:: @@ -396,8 +392,7 @@ def _create_element_in_extension_(self, element): def _element_constructor_(self, data): r""" - Converts the given object to an element of this Cartesian - product. + Convert the given object to an element of this Cartesian product. EXAMPLES:: @@ -521,13 +516,7 @@ def _repr_short_(self): A short (shorter than :meth:`._repr_`) representation string for this Cartesian product of growth groups. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -547,11 +536,9 @@ def _convert_factors_(self, factors): INPUT: - - ``factors`` -- a tuple or other iterable. - - OUTPUT: + - ``factors`` -- tuple or other iterable - An element of this Cartesian product. + OUTPUT: an element of this Cartesian product EXAMPLES:: @@ -614,13 +601,11 @@ def cartesian_injection(self, factor, element): INPUT: - - ``factor`` -- a growth group (a factor of this Cartesian product). - - - ``element`` -- an element of ``factor``. + - ``factor`` -- a growth group (a factor of this Cartesian product) - OUTPUT: + - ``element`` -- an element of ``factor`` - An element of this Cartesian product. + OUTPUT: an element of this Cartesian product TESTS:: @@ -638,11 +623,9 @@ def _coerce_map_from_(self, S): INPUT: - - ``S`` -- a parent. + - ``S`` -- a parent - OUTPUT: - - A boolean. + OUTPUT: boolean TESTS:: @@ -855,13 +838,7 @@ def gens_monomial(self): r""" Return a tuple containing monomial generators of this growth group. - INPUT: - - Nothing. - - OUTPUT: - - A tuple containing elements of this growth group. + OUTPUT: a tuple containing elements of this growth group .. NOTE:: @@ -890,9 +867,7 @@ def variable_names(self): r""" Return the names of the variables. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -917,12 +892,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -948,9 +921,7 @@ def _latex_(self): r""" A representation string for this Cartesian product element. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -971,11 +942,9 @@ def __pow__(self, exponent): INPUT: - - ``exponent`` -- a number. - - OUTPUT: + - ``exponent`` -- a number - A growth element. + OUTPUT: a growth element EXAMPLES:: @@ -999,13 +968,7 @@ def factors(self): Return the atomic factors of this growth element. An atomic factor cannot be split further and is not the identity (`1`). - INPUT: - - Nothing. - - OUTPUT: - - A tuple of growth elements. + OUTPUT: a tuple of growth elements EXAMPLES:: @@ -1053,13 +1016,14 @@ def _log_factor_(self, base=None, locals=None): INPUT: - - ``base`` -- the base of the logarithm. If ``None`` - (default value) is used, the natural logarithm is taken. + - ``base`` -- the base of the logarithm; if ``None`` + (default value) is used, the natural logarithm is taken - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and + values: - - ``'log'`` -- value: a function. If not used, then the usual - :class:`log ` is taken. + - ``'log'`` -- value: a function; if not used, then the usual + :class:`log ` is taken OUTPUT: @@ -1103,23 +1067,20 @@ def try_create_growth(g): def _rpow_element_(self, base): r""" - Return an element which is the power of ``base`` to this - element. + Return an element which is the power of ``base`` to this element. INPUT: - - ``base`` -- an element. - - OUTPUT: + - ``base`` -- an element - A growth element. + OUTPUT: a growth element .. NOTE:: The parent of the result can be different from the parent of this element. - A ``ValueError`` is raised if the calculation is not possible + A :exc:`ValueError` is raised if the calculation is not possible within this method. (Then the calling method should take care of the calculation.) @@ -1146,13 +1107,7 @@ def exp(self): r""" The exponential of this element. - INPUT: - - Nothing. - - OUTPUT: - - A growth element. + OUTPUT: a growth element EXAMPLES:: @@ -1190,9 +1145,7 @@ def __invert__(self): r""" Return the multiplicative inverse of this Cartesian product. - OUTPUT: - - A growth element. + OUTPUT: a growth element .. NOTE:: @@ -1216,13 +1169,10 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. - The neutral element of the group is replaced by the value - to key ``'_one_'``. + - ``rules`` -- dictionary; the neutral element of the group is + replaced by the value to key ``'_one_'`` - OUTPUT: - - An object. + OUTPUT: an object TESTS:: @@ -1264,11 +1214,11 @@ def _singularity_analysis_(self, var, zeta, precision): INPUT: - - ``var`` -- a string denoting the variable + - ``var`` -- string denoting the variable - ``zeta`` -- a number - - ``precision`` -- an integer + - ``precision`` -- integer OUTPUT: @@ -1355,9 +1305,7 @@ def variable_names(self): r""" Return the names of the variables of this growth element. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: diff --git a/src/sage/rings/asymptotic/misc.py b/src/sage/rings/asymptotic/misc.py index c33ea3e5a94..e3d7a013285 100644 --- a/src/sage/rings/asymptotic/misc.py +++ b/src/sage/rings/asymptotic/misc.py @@ -28,8 +28,15 @@ # **************************************************************************** from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.structure.sage_object import SageObject +lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') +lazy_import('sage.rings.multi_power_series_ring', 'MPowerSeriesRing_generic') +lazy_import('sage.rings.polynomial.multi_polynomial_ring_base', 'MPolynomialRing_base') +lazy_import('sage.rings.polynomial.polynomial_ring', 'PolynomialRing_general') +lazy_import('sage.rings.power_series_ring', 'PowerSeriesRing_generic') + def repr_short_to_parent(s): r""" @@ -38,11 +45,9 @@ def repr_short_to_parent(s): INPUT: - - ``s`` -- a string, short representation of a parent. - - OUTPUT: + - ``s`` -- string; short representation of a parent - A parent. + OUTPUT: a parent The possible short representations are shown in the examples below. @@ -108,11 +113,9 @@ def parent_to_repr_short(P): INPUT: - - ``P`` -- a parent. + - ``P`` -- a parent - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -149,9 +152,6 @@ def parent_to_repr_short(P): from sage.rings.real_mpfi import RIF from sage.rings.real_mpfr import RR from sage.symbolic.ring import SR - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing - from sage.rings.power_series_ring import is_PowerSeriesRing def abbreviate(P): try: @@ -168,10 +168,8 @@ def abbreviate(P): pass raise ValueError('Cannot abbreviate %s.' % (P,)) - poly = is_PolynomialRing(P) or is_MPolynomialRing(P) - from sage.rings import multi_power_series_ring - power = is_PowerSeriesRing(P) or \ - multi_power_series_ring.is_MPowerSeriesRing(P) + poly = isinstance(P, (PolynomialRing_general, MPolynomialRing_base)) + power = isinstance(P, (PowerSeriesRing_generic, MPowerSeriesRing_generic, LazyPowerSeriesRing)) if poly or power: if poly: @@ -198,18 +196,16 @@ def split_str_by_op(string, op, strip_parentheses=True): INPUT: - - ``string`` -- a string. + - ``string`` -- string - - ``op`` -- a string. This is used by + - ``op`` -- string; this is used by :python:`str.split `. Thus, if this is ``None``, then any whitespace string is a separator and empty strings are removed from the result. - - ``strip_parentheses`` -- (default: ``True``) a boolean. + - ``strip_parentheses`` -- boolean (default: ``True``) - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings TESTS:: @@ -309,18 +305,16 @@ def repr_op(left, op, right=None, latex=False): INPUT: - - ``left`` -- an element. - - - ``op`` -- a string. + - ``left`` -- an element - - ``right`` -- an element. + - ``op`` -- string - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. + - ``right`` -- an element - OUTPUT: + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - A string. + OUTPUT: string EXAMPLES:: @@ -368,13 +362,11 @@ def combine_exceptions(e, *f): INPUT: - - ``e`` -- an exception. + - ``e`` -- an exception - - ``*f`` -- exceptions. - - OUTPUT: + - ``*f`` -- exceptions - An exception. + OUTPUT: an exception EXAMPLES:: @@ -416,14 +408,11 @@ def substitute_raise_exception(element, e): INPUT: - - ``element`` -- an element. + - ``element`` -- an element - - ``e`` -- an exception which is included in the raised error - message. + - ``e`` -- an exception which is included in the raised error message - OUTPUT: - - Raise an exception of the same type as ``e``. + OUTPUT: raise an exception of the same type as ``e`` TESTS:: @@ -445,9 +434,9 @@ def bidirectional_merge_overlapping(A, B, key=None): INPUT: - - ``A`` -- a list or tuple (type has to coincide with type of ``B``). + - ``A`` -- list or tuple (type has to coincide with type of ``B``) - - ``B`` -- a list or tuple (type has to coincide with type of ``A``). + - ``B`` -- list or tuple (type has to coincide with type of ``A``) - ``key`` -- (default: ``None``) a function. If ``None``, then the identity is used. This ``key``-function applied on an element @@ -578,9 +567,9 @@ def bidirectional_merge_sorted(A, B, key=None): INPUT: - - ``A`` -- a list or tuple (type has to coincide with type of ``B``). + - ``A`` -- list or tuple (type has to coincide with type of ``B``) - - ``B`` -- a list or tuple (type has to coincide with type of ``A``). + - ``B`` -- list or tuple (type has to coincide with type of ``A``) - ``key`` -- (default: ``None``) a function. If ``None``, then the identity is used. This ``key``-function applied on an element @@ -715,13 +704,11 @@ def log_string(element, base=None): INPUT: - - ``element`` -- an object. + - ``element`` -- an object - - ``base`` -- an object or ``None``. + - ``base`` -- an object or ``None`` - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -746,9 +733,7 @@ def strip_symbolic(expression): - ``expression`` -- an object - OUTPUT: - - An object. + OUTPUT: an object EXAMPLES:: @@ -790,9 +775,10 @@ def __init__(self, asymptotic_ring=None, var=None, exact_part=0): r""" INPUT: - - ``asymptotic_ring`` -- (default: ``None``) an :class:`AsymptoticRing` or ``None``. + - ``asymptotic_ring`` -- (default: ``None``) an :class:`AsymptoticRing` + or ``None`` - - ``var`` -- (default: ``None``) a string. + - ``var`` -- (default: ``None``) a string Either ``asymptotic_ring`` or ``var`` has to be specified. @@ -853,9 +839,10 @@ def __init__(self, asymptotic_ring=None, var=None, exact_part=0): r""" INPUT: - - ``asymptotic_ring`` -- (default: ``None``) an :class:`AsymptoticRing` or ``None``. + - ``asymptotic_ring`` -- (default: ``None``) an :class:`AsymptoticRing` + or ``None`` - - ``var`` -- (default: ``None``) a string. + - ``var`` -- (default: ``None``) string Either ``asymptotic_ring`` or ``var`` has to be specified. @@ -922,15 +909,15 @@ def transform_category(category, INPUT: - - ``category`` -- a category. + - ``category`` -- a category - - ``subcategory_mapping`` -- a list (or other iterable) of triples + - ``subcategory_mapping`` -- list (or other iterable) of triples ``(from, to, mandatory)``, where - ``from`` and ``to`` are categories and - ``mandatory`` is a boolean. - - ``axiom_mapping`` -- a list (or other iterable) of triples + - ``axiom_mapping`` -- list (or other iterable) of triples ``(from, to, mandatory)``, where - ``from`` and ``to`` are strings describing axioms and @@ -944,9 +931,7 @@ def transform_category(category, :class:`category of objects ` is used. - OUTPUT: - - A category. + OUTPUT: a category .. NOTE:: @@ -1136,9 +1121,7 @@ def default_locals(self): Return the default locals used in the :class:`~sage.rings.asymptotic.asymptotic_ring.AsymptoticRing`. - OUTPUT: - - A dictionary. + OUTPUT: a dictionary EXAMPLES:: @@ -1202,9 +1185,7 @@ def locals(self, locals=None): the default values) :class:`Locals` object is created and returned. - OUTPUT: - - A :class:`Locals` object. + OUTPUT: a :class:`Locals` object TESTS:: diff --git a/src/sage/rings/asymptotic/term_monoid.py b/src/sage/rings/asymptotic/term_monoid.py index e50b1e7409c..588580c3e13 100644 --- a/src/sage/rings/asymptotic/term_monoid.py +++ b/src/sage/rings/asymptotic/term_monoid.py @@ -17,11 +17,11 @@ implements the following types of terms: - :class:`OTerm` -- `O`-terms at infinity, see - :wikipedia:`Big_O_notation`. + :wikipedia:`Big_O_notation` - :class:`TermWithCoefficient` -- abstract base class for - asymptotic terms with coefficients. + asymptotic terms with coefficients - :class:`ExactTerm` -- this class represents a growth element - multiplied with some non-zero coefficient from a coefficient ring. + multiplied with some nonzero coefficient from a coefficient ring A characteristic property of asymptotic terms is that some terms are able to "absorb" other terms (see @@ -252,13 +252,11 @@ def absorption(left, right): INPUT: - - ``left`` -- an asymptotic term. + - ``left`` -- an asymptotic term - - ``right`` -- an asymptotic term. + - ``right`` -- an asymptotic term - OUTPUT: - - An asymptotic term or ``None``. + OUTPUT: an asymptotic term or ``None`` EXAMPLES:: @@ -298,13 +296,11 @@ def can_absorb(left, right): INPUT: - - ``left`` -- an asymptotic term. - - - ``right`` -- an asymptotic term. + - ``left`` -- an asymptotic term - OUTPUT: + - ``right`` -- an asymptotic term - A boolean. + OUTPUT: boolean .. NOTE:: @@ -332,9 +328,9 @@ class GenericTerm(MultiplicativeGroupElement): INPUT: - - ``parent`` -- the parent of the asymptotic term. + - ``parent`` -- the parent of the asymptotic term - - ``growth`` -- an asymptotic growth element. + - ``growth`` -- an asymptotic growth element EXAMPLES:: @@ -395,10 +391,6 @@ def construction(self): r""" Return a construction of this term. - INPUT: - - Nothing. - OUTPUT: A pair ``(cls, kwds)`` such that ``cls(**kwds)`` equals this term. @@ -432,11 +424,9 @@ def _mul_(self, other): INPUT: - - ``other`` -- an asymptotic term. - - OUTPUT: + - ``other`` -- an asymptotic term - A :class:`GenericTerm`. + OUTPUT: a :class:`GenericTerm` .. NOTE:: @@ -464,9 +454,7 @@ def __invert__(self): r""" Invert this term. - OUTPUT: - - A :class:`GenericTerm`. + OUTPUT: a :class:`GenericTerm` TESTS:: @@ -500,7 +488,7 @@ def __pow__(self, exponent): INPUT: - - ``exponent`` -- an element. + - ``exponent`` -- an element OUTPUT: @@ -532,11 +520,9 @@ def _calculate_pow_test_zero_(self, exponent): INPUT: - - ``exponent`` -- an element. - - OUTPUT: + - ``exponent`` -- an element - A term. + OUTPUT: a term TESTS:: @@ -586,14 +572,12 @@ def _calculate_pow_(self, exponent, new_coefficient=None): INPUT: - - ``exponent`` -- an element. + - ``exponent`` -- an element - ``new_coefficient`` -- if not ``None`` this is passed on to the - construction of the element (in particular, not taken to any power). - - OUTPUT: + construction of the element (in particular, not taken to any power) - A term. + OUTPUT: a term TESTS:: @@ -635,11 +619,9 @@ def can_absorb(self, other): INPUT: - - ``other`` -- an asymptotic term. - - OUTPUT: + - ``other`` -- an asymptotic term - A boolean. + OUTPUT: boolean .. NOTE:: @@ -672,10 +654,10 @@ def absorb(self, other, check=True): INPUT: - - ``other`` -- an asymptotic term. + - ``other`` -- an asymptotic term - - ``check`` -- a boolean. If ``check`` is ``True`` (default), - then ``can_absorb`` is called before absorption. + - ``check`` -- boolean; if ``True`` (default), then ``can_absorb`` + is called before absorption OUTPUT: @@ -769,11 +751,9 @@ def _absorb_(self, other): INPUT: - ``other`` -- an asymptotic term from the same parent as - this element. - - OUTPUT: + this element - An asymptotic term or ``None``. + OUTPUT: an asymptotic term or ``None`` .. NOTE:: @@ -823,14 +803,12 @@ def log_term(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - A tuple of terms. + OUTPUT: a tuple of terms .. NOTE:: @@ -879,14 +857,12 @@ def _log_growth_(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - A tuple of terms. + OUTPUT: a tuple of terms EXAMPLES:: @@ -918,9 +894,7 @@ def _lt_(self, other): - ``other`` -- an asymptotic term - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -1022,11 +996,9 @@ def _eq_(self, other): INPUT: - - ``other`` -- an asymptotic term. - - OUTPUT: + - ``other`` -- an asymptotic term - A boolean. + OUTPUT: boolean .. NOTE:: @@ -1077,13 +1049,7 @@ def is_constant(self): r""" Return whether this term is an (exact) constant. - INPUT: - - Nothing. - - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -1115,9 +1081,7 @@ def is_exact(self): r""" Return whether this term is an exact term. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1134,13 +1098,7 @@ def is_little_o_of_one(self): r""" Return whether this generic term is of order `o(1)`. - INPUT: - - Nothing. - - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1173,11 +1131,9 @@ def rpow(self, base): INPUT: - - ``base`` -- an element or ``'e'``. - - OUTPUT: + - ``base`` -- an element or ``'e'`` - A term. + OUTPUT: a term EXAMPLES:: @@ -1200,13 +1156,7 @@ def _repr_(self): r""" A representation string for this generic term. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1227,9 +1177,7 @@ def _latex_(self): r""" A LaTeX-representation string for this generic term. - OUTPUT: - - A NotImplementedError is raised. + OUTPUT: a :exc:`NotImplementedError` is raised TESTS:: @@ -1252,7 +1200,7 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. + - ``rules`` -- dictionary OUTPUT: @@ -1284,9 +1232,7 @@ def variable_names(self): r""" Return the names of the variables of this term. - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -1309,9 +1255,7 @@ def _factorial_(self): r""" Return the factorial of this generic term. - OUTPUT: - - A term. + OUTPUT: a term TESTS:: @@ -1335,11 +1279,11 @@ def _singularity_analysis_(self, var, zeta, precision): INPUT: - - ``var`` -- a string denoting the variable + - ``var`` -- string denoting the variable - ``zeta`` -- a number - - ``precision`` -- an integer + - ``precision`` -- integer OUTPUT: @@ -1372,12 +1316,12 @@ class GenericTermMonoid(UniqueRepresentation, Parent, WithLocals): INPUT: - ``growth_group`` -- a growth group (i.e. an instance of - :class:`~sage.rings.asymptotic.growth_group.GenericGrowthGroup`). + :class:`~sage.rings.asymptotic.growth_group.GenericGrowthGroup`) - ``coefficient_ring`` -- a ring which contains the (maybe implicit) - coefficients of the elements. + coefficients of the elements - - ``category`` -- The category of the parent can be specified + - ``category`` -- the category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of ``Join of Category of Monoids and Category of posets``. This is also the default category if ``None`` is specified. @@ -1542,10 +1486,9 @@ def term_monoid(self, type): INPUT: - - ``type`` -- 'O' or 'exact', or an instance of an existing - term monoid. - See :class:`~sage.rings.asymptotic.term_monoid.TermMonoidFactory` - for more details. + - ``type`` -- 'O' or 'exact', or an instance of an existing term monoid. + See :class:`~sage.rings.asymptotic.term_monoid.TermMonoidFactory` for + more details. OUTPUT: @@ -1609,13 +1552,11 @@ def change_parameter(self, growth_group=None, coefficient_ring=None): INPUT: - - ``growth_group`` -- (default: ``None``) the new growth group. + - ``growth_group`` -- (default: ``None``) the new growth group - - ``coefficient_ring`` -- (default: ``None``) the new coefficient ring. + - ``coefficient_ring`` -- (default: ``None``) the new coefficient ring - OUTPUT: - - A term monoid. + OUTPUT: a term monoid EXAMPLES:: @@ -1651,13 +1592,7 @@ def _repr_(self): r""" A representation string for this generic term monoid. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1679,11 +1614,9 @@ def _coerce_map_from_(self, S): INPUT: - - ``S`` -- a parent. - - OUTPUT: + - ``S`` -- a parent - A boolean. + OUTPUT: boolean .. NOTE:: @@ -1738,16 +1671,14 @@ def _element_constructor_(self, data, *args, **kwds): INPUT: - ``data`` -- a growth element or an object representing the - element to be initialized. + element to be initialized - - ``coefficient`` -- (default: ``None``) - an element of the coefficient ring. + - ``coefficient`` -- (default: ``None``) an element of the coefficient + ring - - ``**kwds`` -- keyword arguments passed on to the term. - - OUTPUT: + - ``**kwds`` -- keyword arguments passed on to the term - An element of this term monoid. + OUTPUT: an element of this term monoid EXAMPLES:: @@ -1913,7 +1844,7 @@ def _validate_growth_or_error_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) @@ -1973,7 +1904,7 @@ def _validate_coefficient_or_error_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) @@ -2035,13 +1966,7 @@ def _default_kwds_construction_(self): r""" Return the default keyword arguments for the construction of a term. - INPUT: - - Nothing. - - OUTPUT: - - A dictionary. + OUTPUT: a dictionary TESTS:: @@ -2065,14 +1990,12 @@ def _convert_construction_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) - OUTPUT: - - Nothing, but ``kwds_construction`` might be changed. + OUTPUT: nothing, but ``kwds_construction`` might be changed TESTS:: @@ -2115,11 +2038,9 @@ def from_construction(self, construction, **kwds_overrides): - ``construction`` -- a pair ``(cls, kwds_construction)`` - - ``kwds_overrides`` -- a dictionary - - OUTPUT: + - ``kwds_overrides`` -- dictionary - A term. + OUTPUT: a term EXAMPLES:: @@ -2193,11 +2114,9 @@ def _create_element_in_extension_(self, growth, coefficient): INPUT: - - ``growth`` and ``coefficient`` -- the element data. - - OUTPUT: + - ``growth`` and ``coefficient`` -- the element data - An element. + OUTPUT: an element EXAMPLES:: @@ -2228,7 +2147,7 @@ def _split_growth_and_coefficient_(self, data): INPUT: - - ``data`` -- an element. + - ``data`` -- an element OUTPUT: @@ -2309,11 +2228,9 @@ def _get_factors_(self, data): INPUT: - - ``data`` -- an object. - - OUTPUT: + - ``data`` -- an object - A tuple. + OUTPUT: a tuple TESTS:: @@ -2345,13 +2262,7 @@ def _an_element_(self): r""" Return an element of this term monoid. - INPUT: - - Nothing. - - OUTPUT: - - An element of this term monoid. + OUTPUT: an element of this term monoid EXAMPLES:: @@ -2372,13 +2283,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -2397,13 +2302,11 @@ def le(self, left, right): INPUT: - - ``left`` -- an element. - - - ``right`` -- an element. + - ``left`` -- an element - OUTPUT: + - ``right`` -- an element - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -2430,9 +2333,9 @@ class OTerm(GenericTerm): INPUT: - - ``parent`` -- the parent of the asymptotic term. + - ``parent`` -- the parent of the asymptotic term - - ``growth`` -- a growth element. + - ``growth`` -- a growth element EXAMPLES:: @@ -2471,12 +2374,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. - - OUTPUT: + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - A string. + OUTPUT: string EXAMPLES:: @@ -2507,9 +2408,7 @@ def _latex_(self): r""" A LaTeX-representation string for this `O`-term. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -2532,7 +2431,7 @@ def __invert__(self): OUTPUT: - A :class:`ZeroDivisionError` since `O`-terms cannot be inverted. + A :exc:`ZeroDivisionError` since `O`-terms cannot be inverted. TESTS:: @@ -2553,11 +2452,9 @@ def __pow__(self, exponent): INPUT: - - ``exponent`` -- an element. - - OUTPUT: + - ``exponent`` -- an element - An :class:`OTerm`. + OUTPUT: an :class:`OTerm` TESTS:: @@ -2585,11 +2482,9 @@ def can_absorb(self, other): INPUT: - - ``other`` -- an asymptotic term. - - OUTPUT: + - ``other`` -- an asymptotic term - A boolean. + OUTPUT: boolean .. NOTE:: @@ -2618,11 +2513,9 @@ def _absorb_(self, other): INPUT: - - ``other`` -- an asymptotic `O`-term. - - OUTPUT: + - ``other`` -- an asymptotic `O`-term - An asymptotic `O`-term. + OUTPUT: an asymptotic `O`-term .. NOTE:: @@ -2664,14 +2557,12 @@ def log_term(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - A tuple of terms. + OUTPUT: a tuple of terms .. NOTE:: @@ -2705,13 +2596,7 @@ def is_little_o_of_one(self): r""" Return whether this O-term is of order `o(1)`. - INPUT: - - Nothing. - - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -2755,11 +2640,9 @@ def rpow(self, base): INPUT: - - ``base`` -- an element or ``'e'``. + - ``base`` -- an element or ``'e'`` - OUTPUT: - - A term. + OUTPUT: a term .. NOTE:: @@ -2812,11 +2695,9 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. - - OUTPUT: + - ``rules`` -- dictionary - An object. + OUTPUT: an object TESTS:: @@ -2886,9 +2767,7 @@ def _factorial_(self): Return the factorial of this O-term if it is constant (i.e., has growth `1`). - OUTPUT: - - A term. + OUTPUT: a term TESTS:: @@ -2915,11 +2794,11 @@ def _singularity_analysis_(self, var, zeta, precision): INPUT: - - ``var`` -- a string denoting the variable + - ``var`` -- string denoting the variable - ``zeta`` -- a number - - ``precision`` -- an integer + - ``precision`` -- integer OUTPUT: @@ -2948,9 +2827,9 @@ class OTermMonoid(GenericTermMonoid): INPUT: - - ``growth_group`` -- a growth group. + - ``growth_group`` -- a growth group - - ``category`` -- The category of the parent can be specified + - ``category`` -- the category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of ``Join of Category of monoids and Category of posets``. This is also the default category if ``None`` is specified. @@ -2988,14 +2867,12 @@ def _convert_construction_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) - OUTPUT: - - Nothing, but ``kwds_construction`` might be changed. + OUTPUT: nothing, but ``kwds_construction`` might be changed TESTS:: @@ -3042,11 +2919,9 @@ def _coerce_map_from_(self, S): INPUT: - - ``S`` -- a parent. - - OUTPUT: + - ``S`` -- a parent - ``True`` or ``None``. + OUTPUT: ``True`` or ``None`` .. NOTE:: @@ -3098,13 +2973,7 @@ def _repr_(self): r""" A representation string for this `O`-term monoid. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3125,12 +2994,11 @@ class TermWithCoefficient(GenericTerm): INPUT: - - ``parent`` -- the parent of the asymptotic term. + - ``parent`` -- the parent of the asymptotic term - - ``growth`` -- an asymptotic growth element of - the parent's growth group. + - ``growth`` -- an asymptotic growth element of the parent's growth group - - ``coefficient`` -- an element of the parent's coefficient ring. + - ``coefficient`` -- an element of the parent's coefficient ring EXAMPLES:: @@ -3208,10 +3076,6 @@ def construction(self): r""" Return a construction of this term. - INPUT: - - Nothing. - OUTPUT: A pair ``(cls, kwds)`` such that ``cls(**kwds)`` equals this term. @@ -3245,13 +3109,7 @@ def _repr_(self): r""" A representation string for this term with coefficient. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3273,12 +3131,10 @@ def _repr_product_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. - - OUTPUT: + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - A string + OUTPUT: string EXAMPLES:: @@ -3326,7 +3182,7 @@ def _mul_(self, other): INPUT: - - ``other`` -- an asymptotic term. + - ``other`` -- an asymptotic term OUTPUT: @@ -3373,11 +3229,9 @@ def _calculate_pow_(self, exponent): INPUT: - - ``exponent`` -- an element. + - ``exponent`` -- an element - OUTPUT: - - A term. + OUTPUT: a term TESTS:: @@ -3427,14 +3281,12 @@ def _log_coefficient_(self, base=None, locals=None): - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - A tuple of terms. + OUTPUT: a tuple of terms EXAMPLES:: @@ -3481,9 +3333,7 @@ def _eq_(self, other): - ``other`` -- an :class:`TermWithCoefficient` - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -3519,15 +3369,15 @@ class TermWithCoefficientMonoid(GenericTermMonoid): INPUT: - - ``growth_group`` -- a growth group. + - ``growth_group`` -- a growth group - - ``category`` -- The category of the parent can be specified + - ``category`` -- the category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of ``Join of Category of monoids and Category of posets``. This is also the default category if ``None`` is specified. - ``coefficient_ring`` -- the ring which contains the - coefficients of the elements. + coefficients of the elements EXAMPLES:: @@ -3556,13 +3406,7 @@ def _repr_(self): r""" A representation string for this TermWithCoefficient Monoid. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3585,7 +3429,7 @@ def _validate_coefficient_or_error_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) @@ -3640,13 +3484,7 @@ def _default_kwds_construction_(self): r""" Return the default keyword arguments for the construction of a term. - INPUT: - - Nothing. - - OUTPUT: - - A dictionary. + OUTPUT: a dictionary TESTS:: @@ -3673,14 +3511,12 @@ def _convert_construction_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) - OUTPUT: - - Nothing, but ``kwds_construction`` might be changed. + OUTPUT: nothing, but ``kwds_construction`` might be changed TESTS:: @@ -3710,13 +3546,7 @@ def _an_element_(self): r""" Return an element of this term with coefficient monoid. - INPUT: - - Nothing. - - OUTPUT: - - An element of this term monoid. + OUTPUT: an element of this term monoid EXAMPLES:: @@ -3740,13 +3570,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -3772,12 +3596,11 @@ class ExactTerm(TermWithCoefficient): INPUT: - - ``parent`` -- the parent of the asymptotic term. + - ``parent`` -- the parent of the asymptotic term - - ``growth`` -- an asymptotic growth element from - ``parent.growth_group``. + - ``growth`` -- an asymptotic growth element from ``parent.growth_group`` - - ``coefficient`` -- an element from ``parent.coefficient_ring``. + - ``coefficient`` -- an element from ``parent.coefficient_ring`` EXAMPLES:: @@ -3836,12 +3659,10 @@ def _repr_(self, latex=False): INPUT: - - ``latex`` -- (default: ``False``) a boolean. If set, then - LaTeX-output is returned. - - OUTPUT: + - ``latex`` -- boolean (default: ``False``); if set, then + LaTeX-output is returned - A string. + OUTPUT: string EXAMPLES:: @@ -3877,9 +3698,7 @@ def _latex_(self): r""" A LaTeX-representation string for this exact term. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -3921,9 +3740,7 @@ def __invert__(self): r""" Invert this term. - OUTPUT: - - A term. + OUTPUT: a term TESTS:: @@ -3950,11 +3767,9 @@ def __pow__(self, exponent): INPUT: - - ``exponent`` -- an element. - - OUTPUT: + - ``exponent`` -- an element - An :class:`ExactTerm`. + OUTPUT: an :class:`ExactTerm` TESTS:: @@ -3978,11 +3793,9 @@ def can_absorb(self, other): INPUT: - - ``other`` -- an asymptotic term. - - OUTPUT: + - ``other`` -- an asymptotic term - A boolean. + OUTPUT: boolean .. NOTE:: @@ -4014,11 +3827,9 @@ def _absorb_(self, other): INPUT: - - ``other`` -- an exact term. - - OUTPUT: + - ``other`` -- an exact term - An exact term or ``None``. + OUTPUT: an exact term or ``None`` .. NOTE:: @@ -4068,14 +3879,12 @@ def log_term(self, base=None, locals=None): (default value) is used, the natural logarithm is taken. - - ``locals`` -- a dictionary which may contain the following keys and values: + - ``locals`` -- dictionary which may contain the following keys and values: - ``'log'`` -- value: a function. If not used, then the usual :class:`log ` is taken. - OUTPUT: - - A tuple of terms. + OUTPUT: a tuple of terms .. NOTE:: @@ -4113,13 +3922,7 @@ def is_constant(self): r""" Return whether this term is an (exact) constant. - INPUT: - - Nothing. - - OUTPUT: - - A boolean. + OUTPUT: boolean .. NOTE:: @@ -4146,13 +3949,7 @@ def is_little_o_of_one(self): r""" Return whether this exact term is of order `o(1)`. - INPUT: - - Nothing. - - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -4194,9 +3991,7 @@ def is_exact(self): r""" Return whether this term is an exact term. - OUTPUT: - - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -4222,11 +4017,9 @@ def rpow(self, base): INPUT: - - ``base`` -- an element or ``'e'``. - - OUTPUT: + - ``base`` -- an element or ``'e'`` - A term. + OUTPUT: a term EXAMPLES:: @@ -4280,11 +4073,9 @@ def _substitute_(self, rules): INPUT: - - ``rules`` -- a dictionary. + - ``rules`` -- dictionary - OUTPUT: - - An object. + OUTPUT: an object TESTS:: @@ -4330,9 +4121,7 @@ def _factorial_(self): Return the factorial of this exact term if it is constant (i.e., has growth `1`). - OUTPUT: - - A term. + OUTPUT: a term TESTS:: @@ -4363,11 +4152,11 @@ def _singularity_analysis_(self, var, zeta, precision): INPUT: - - ``var`` -- a string denoting the variable + - ``var`` -- string denoting the variable - ``zeta`` -- a number - - ``precision`` -- an integer + - ``precision`` -- integer OUTPUT: @@ -4402,15 +4191,15 @@ class ExactTermMonoid(TermWithCoefficientMonoid): INPUT: - - ``growth_group`` -- a growth group. + - ``growth_group`` -- a growth group - - ``category`` -- The category of the parent can be specified + - ``category`` -- the category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of ``Join of Category of monoids and Category of posets``. This is also the default category if ``None`` is specified. - ``coefficient_ring`` -- the ring which contains the coefficients of - the elements. + the elements EXAMPLES:: @@ -4450,14 +4239,12 @@ def _convert_construction_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) - OUTPUT: - - Nothing, but ``kwds_construction`` might be changed. + OUTPUT: nothing, but ``kwds_construction`` might be changed TESTS:: @@ -4497,13 +4284,7 @@ def _repr_(self): r""" A representation string for this exact term monoid. - INPUT: - - Nothing. - - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -4571,7 +4352,6 @@ class BTerm(TermWithCoefficient): sage: T(x^3*y^2, coefficient=42, valid_from={'x': 10, 'y': 20}) B(42*x^3*y^2, x >= 10, y >= 20) - """ def __init__(self, parent, growth, valid_from, **kwds): r""" @@ -4619,7 +4399,7 @@ def __init__(self, parent, growth, valid_from, **kwds): ... ValueError: B-Term has valid_from variables defined which do not occur in the term. """ - # BTerms must have positive cofficients + # BTerms must have positive coefficients coefficient = abs(kwds['coefficient']) super().__init__(parent=parent, growth=growth, coefficient=coefficient) @@ -4644,10 +4424,6 @@ def construction(self): r""" Return a construction of this term. - INPUT: - - Nothing. - OUTPUT: A pair ``(cls, kwds)`` such that ``cls(**kwds)`` equals this term. @@ -4684,13 +4460,7 @@ def _repr_(self, latex=False): r""" A representation string for this B-term. - INPUT: - - Nothing - - OUTPUT: - - A string + OUTPUT: string EXAMPLES:: @@ -4720,9 +4490,7 @@ def _latex_(self): r""" A LaTeX-representation string for this B-term. - OUTPUT: - - A string + OUTPUT: string TESTS:: @@ -4788,9 +4556,7 @@ def can_absorb(self, other): - ``other`` -- an asymptotic term - OUTPUT: - - A boolean + OUTPUT: boolean .. NOTE:: @@ -4900,10 +4666,10 @@ class BTermMonoid(TermWithCoefficientMonoid): - ``coefficient_ring`` -- the ring which contains the coefficients of the elements - - ``category`` -- The category of the parent can be specified + - ``category`` -- the category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of ``Join of Category of monoids and Category of posets``. This - is also the default category if ``None`` is specified + is also the default category if ``None`` is specified. EXAMPLES:: @@ -4927,13 +4693,7 @@ def _repr_(self): r""" A representation string for this B term monoid. - INPUT: - - Nothing - - OUTPUT: - - A string + OUTPUT: string EXAMPLES:: @@ -4950,13 +4710,7 @@ def _default_kwds_construction_(self): r""" Return the default keyword arguments for the construction of a term. - INPUT: - - Nothing. - - OUTPUT: - - A dictionary. + OUTPUT: a dictionary TESTS:: @@ -4991,14 +4745,12 @@ def _convert_construction_(self, kwds_construction): INPUT: - - ``kwds_construction`` -- a dictionary representing + - ``kwds_construction`` -- dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and :meth:`TermWithCoefficient.construction`) - OUTPUT: - - Nothing, but ``kwds_construction`` might be changed. + OUTPUT: nothing, but ``kwds_construction`` might be changed TESTS:: @@ -5058,9 +4810,7 @@ def _coerce_map_from_(self, S): - ``S`` -- a parent - OUTPUT: - - ``True`` or ``None`` + OUTPUT: ``True`` or ``None`` .. NOTE:: @@ -5114,13 +4864,7 @@ def _an_element_(self): r""" Return an element of this B-term monoid. - INPUT: - - Nothing. - - OUTPUT: - - An element of this term monoid. + OUTPUT: an element of this term monoid EXAMPLES:: @@ -5143,13 +4887,7 @@ def some_elements(self): See :class:`TestSuite` for a typical use case. - INPUT: - - Nothing. - - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -5200,22 +4938,19 @@ class TermMonoidFactory(UniqueRepresentation, UniqueFactory): INPUT: - - ``term_monoid`` -- the kind of terms held in the new term monoid. + - ``term_monoid`` -- the kind of terms held in the new term monoid Either a string ``'exact'``, ``'O'`` (capital letter ``O``) or ``'B'`` or an existing instance of a term monoid. - - ``growth_group`` -- a growth group or - a string describing a growth group. + - ``growth_group`` -- a growth group or a string describing a growth group - - ``coefficient_ring`` -- a ring. + - ``coefficient_ring`` -- a ring - ``asymptotic_ring`` -- if specified, then ``growth_group`` and - ``coefficient_ring`` are taken from this asymptotic ring. - - OUTPUT: + ``coefficient_ring`` are taken from this asymptotic ring - An asymptotic term monoid. + OUTPUT: an asymptotic term monoid EXAMPLES:: diff --git a/src/sage/rings/bernmm.pyx b/src/sage/rings/bernmm.pyx index 82b1646a72f..492181f1f22 100644 --- a/src/sage/rings/bernmm.pyx +++ b/src/sage/rings/bernmm.pyx @@ -46,7 +46,7 @@ def bernmm_bern_rat(long k, int num_threads = 1): INPUT: - - ``k`` -- non-negative integer + - ``k`` -- nonnegative integer - ``num_threads`` -- integer `\geq 1`, number of threads to use COMPLEXITY: @@ -85,7 +85,7 @@ def bernmm_bern_rat(long k, int num_threads = 1): cdef Rational x if k < 0: - raise ValueError("k must be non-negative") + raise ValueError("k must be nonnegative") x = Rational() sig_on() @@ -104,7 +104,7 @@ def bernmm_bern_modp(long p, long k): INPUT: - ``p`` -- a prime - - ``k`` -- non-negative integer + - ``k`` -- nonnegative integer COMPLEXITY: @@ -147,7 +147,7 @@ def bernmm_bern_modp(long p, long k): cdef long x if k < 0: - raise ValueError("k must be non-negative") + raise ValueError("k must be nonnegative") sig_on() x = bern_modp(p, k) diff --git a/src/sage/rings/bernmm/bern_rat.cpp b/src/sage/rings/bernmm/bern_rat.cpp index 963cb173524..1a1ad87b6c2 100644 --- a/src/sage/rings/bernmm/bern_rat.cpp +++ b/src/sage/rings/bernmm/bern_rat.cpp @@ -87,7 +87,7 @@ struct Item */ struct Item_cmp { - bool operator()(const Item* x, const Item* y) + bool operator()(const Item* x, const Item* y) const { return mpz_cmp(x->modulus, y->modulus) < 0; } @@ -331,9 +331,9 @@ void bern_rat(mpq_t res, long k, int num_threads) #ifdef USE_THREADS for (long i = 0; i < num_threads - 1; i++) pthread_join(threads[i], NULL); -#endif pthread_attr_destroy (&attr); +#endif // reconstruct B_k as a rational number Item* item = *(state.items.begin()); diff --git a/src/sage/rings/bernoulli_mod_p.pyx b/src/sage/rings/bernoulli_mod_p.pyx index ff2948eec56..1783c712aaf 100644 --- a/src/sage/rings/bernoulli_mod_p.pyx +++ b/src/sage/rings/bernoulli_mod_p.pyx @@ -53,9 +53,9 @@ def verify_bernoulli_mod_p(data): INPUT: - - ``data`` -- list, same format as output of :func:`bernoulli_mod_p` function + - ``data`` -- list; same format as output of :func:`bernoulli_mod_p` function - OUTPUT: bool -- True if checksum passed + OUTPUT: boolean; ``True`` if checksum passed EXAMPLES:: @@ -100,7 +100,7 @@ def bernoulli_mod_p(int p): INPUT: - - ``p`` -- integer, a prime + - ``p`` -- integer; a prime OUTPUT: @@ -228,16 +228,14 @@ def bernoulli_mod_p_single(long p, long k): r""" Return the Bernoulli number `B_k` mod `p`. - If `B_k` is not `p`-integral, an :class:`ArithmeticError` is raised. + If `B_k` is not `p`-integral, an :exc:`ArithmeticError` is raised. INPUT: - - ``p`` -- integer, a prime - - ``k`` -- non-negative integer + - ``p`` -- integer; a prime + - ``k`` -- nonnegative integer - OUTPUT: - - The `k`-th Bernoulli number mod `p`. + OUTPUT: the `k`-th Bernoulli number mod `p` EXAMPLES:: @@ -267,7 +265,7 @@ def bernoulli_mod_p_single(long p, long k): sage: bernoulli_mod_p_single(19, -4) Traceback (most recent call last): ... - ValueError: k must be non-negative + ValueError: k must be nonnegative Check results against :class:`bernoulli_mod_p`:: diff --git a/src/sage/rings/big_oh.py b/src/sage/rings/big_oh.py index 917c81e0a3d..54513722d03 100644 --- a/src/sage/rings/big_oh.py +++ b/src/sage/rings/big_oh.py @@ -1,5 +1,5 @@ """ -Big O for various types (power series, p-adics, etc.) +Big O for various types (power series, `p`-adics, etc.) .. SEEALSO:: diff --git a/src/sage/rings/cfinite_sequence.py b/src/sage/rings/cfinite_sequence.py index f34f4514186..4166083de4a 100644 --- a/src/sage/rings/cfinite_sequence.py +++ b/src/sage/rings/cfinite_sequence.py @@ -90,6 +90,7 @@ from numbers import Integral from sage.categories.rings import Rings +from sage.libs.pari import pari from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -102,11 +103,6 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.interfaces.gp import Gp -from sage.misc.sage_eval import sage_eval - -_gp = None - def CFiniteSequences(base_ring, names=None, category=None): r""" @@ -120,7 +116,7 @@ def CFiniteSequences(base_ring, names=None, category=None): - ``base_ring`` -- the base ring to construct the fraction field representing the C-Finite sequences - - ``names`` -- (optional) the list of variables. + - ``names`` -- (optional) the list of variables EXAMPLES:: @@ -172,9 +168,7 @@ class CFiniteSequence(FieldElement, (can be an element from the symbolic ring, fraction field or polynomial ring) - OUTPUT: - - A CFiniteSequence object + OUTPUT: a CFiniteSequence object EXAMPLES:: @@ -329,12 +323,12 @@ def __init__(self, parent, ogf): INPUT: - - ``ogf`` -- the ordinary generating function, a fraction of polynomials over the rationals - - ``parent`` -- the parent of the C-Finite sequence, an occurrence of :class:`CFiniteSequences` + - ``ogf`` -- the ordinary generating function, a fraction of + polynomials over the rationals + - ``parent`` -- the parent of the C-Finite sequence, an occurrence of + :class:`CFiniteSequences` - OUTPUT: - - - A CFiniteSequence object + OUTPUT: a CFiniteSequence object TESTS:: @@ -511,9 +505,7 @@ def coefficients(self): Return the coefficients of the recurrence representation of the C-finite sequence. - OUTPUT: - - - A list of values + OUTPUT: list of values EXAMPLES:: @@ -728,9 +720,7 @@ def recurrence_repr(self) -> str: Return a string with the recurrence representation of the C-finite sequence. - OUTPUT: - - A string + OUTPUT: string EXAMPLES:: @@ -784,7 +774,7 @@ def series(self, n): INPUT: - - `n` -- a nonnegative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -891,7 +881,7 @@ def closed_form(self, n='n'): class CFiniteSequences_generic(Parent, UniqueRepresentation): r""" - The class representing the ring of C-Finite Sequences + The class representing the ring of C-Finite Sequences. TESTS:: @@ -960,7 +950,8 @@ def _element_constructor_(self, ogf): INPUT: - - ``ogf`` -- the ordinary generating function, a fraction of polynomials over the rationals + - ``ogf`` -- the ordinary generating function, a fraction of + polynomials over the rationals TESTS:: @@ -1005,7 +996,7 @@ def gen(self, i=0): INPUT: - - ``i`` -- an integer (default:0) + - ``i`` -- integer (default: 0) EXAMPLES:: @@ -1042,9 +1033,7 @@ def an_element(self): r""" Return an element of C-Finite Sequences. - OUTPUT: - - The Lucas sequence. + OUTPUT: the Lucas sequence EXAMPLES:: @@ -1134,12 +1123,10 @@ def from_recurrence(self, coefficients, values): INPUT: - - ``coefficients`` -- a list of rationals + - ``coefficients`` -- list of rationals - ``values`` -- start values, a list of rationals - OUTPUT: - - - A CFiniteSequence object + OUTPUT: a CFiniteSequence object EXAMPLES:: @@ -1185,14 +1172,12 @@ def guess(self, sequence, algorithm='sage'): INPUT: - ``sequence`` -- list of integers - - ``algorithm`` -- string - - 'sage' -- the default is to use Sage's matrix kernel function - - 'pari' -- use Pari's implementation of LLL - - 'bm' -- use Sage's Berlekamp-Massey algorithm - - OUTPUT: + - ``algorithm`` -- string; one of + - ``'sage'`` -- the default is to use Sage's matrix kernel function + - ``'pari'`` -- use Pari's implementation of LLL + - ``'bm'`` -- use Sage's Berlekamp-Massey algorithm - - a CFiniteSequence, or 0 if none could be found + OUTPUT: a CFiniteSequence, or 0 if none could be found With the default kernel method, trailing zeroes are chopped off before a guessing attempt. This may reduce the data @@ -1215,6 +1200,13 @@ def guess(self, sequence, algorithm='sage'): C-finite sequence, generated by -1/2/(x - 1/2) sage: r[0:5] [1, 2, 4, 8, 16] + + Using pari:: + + sage: r = C.guess([1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28], algorithm='pari'); r + C-finite sequence, generated by (-x - 1)/(x^3 + x^2 - 1) + sage: r[0:5] + [1, 1, 1, 2, 2] """ S = self.polynomial_ring() @@ -1232,22 +1224,18 @@ def guess(self, sequence, algorithm='sage'): return CFiniteSequence(numerator / denominator) if algorithm == 'pari': - global _gp if len(sequence) < 6: raise ValueError('sequence too short for guessing') - if _gp is None: - _gp = Gp() - _gp("ggf(v)=local(l,m,p,q,B);l=length(v);B=floor(l/2);\ + pari("ggf(v)=local(l,m,p,q,B);l=length(v);B=l\\2;\ if(B<3,return(0));m=matrix(B,B,x,y,v[x-y+B+1]);\ q=qflll(m,4)[1];if(length(q)==0,return(0));\ p=sum(k=1,B,x^(k-1)*q[k,1]);\ q=Pol(Pol(vector(l,n,v[l-n+1]))*p+O(x^(B+1)));\ if(polcoeff(p,0)<0,q=-q;p=-p);q=q/p;p=Ser(q+O(x^(l+1)));\ for(m=1,l,if(polcoeff(p,m-1)!=v[m],return(0)));q") - _gp.set('gf', sequence) - _gp("gf=ggf(gf)") - num = S(sage_eval(_gp.eval("Vec(numerator(gf))"))[::-1]) - den = S(sage_eval(_gp.eval("Vec(denominator(gf))"))[::-1]) + pari_guess = pari("ggf")(sequence) + num = S(pari_guess.numerator().Vec().sage()[::-1]) + den = S(pari_guess.denominator().Vec().sage()[::-1]) if num == 0: return 0 return CFiniteSequence(num / den) diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index 095de7b6774..fb9d821a413 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -75,7 +75,7 @@ above warning, inexact balls are not considered equal to themselves):: sage: a == b False -A ball is non-zero in the sense of usual comparison if and only if it does not +A ball is nonzero in the sense of usual comparison if and only if it does not contain zero:: sage: a = CBF(RIF(-0.5, 0.5)) @@ -314,7 +314,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): INPUT: - - ``precision`` -- an integer `\ge 2`. + - ``precision`` -- integer `\ge 2` EXAMPLES:: @@ -365,7 +365,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): INPUT: - - ``precision`` -- an integer `\ge 2`. + - ``precision`` -- integer `\ge 2` EXAMPLES:: @@ -454,7 +454,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): def complex_field(self): """ - Return the complex ball field with the same precision, i.e. ``self`` + Return the complex ball field with the same precision, i.e. ``self``. EXAMPLES:: @@ -587,7 +587,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): INPUT: - - ``x``, ``y`` (optional) -- either a complex number, interval or ball, + - ``x``, ``y`` -- (optional) either a complex number, interval or ball, or two real ones (see examples below for more information on accepted number types). @@ -765,7 +765,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): self('nan'), self('nan', 'nan'), self('inf', 'nan')] def _roots_univariate_polynomial(self, pol, ring, multiplicities, - algorithm, proof=True): + algorithm, proof=True, warn=True): r""" Compute the roots of ``pol``. @@ -890,8 +890,8 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): try: sig_on() while ((isolated < deg or any(acb_rel_accuracy_bits(&roots[i]) < tgtprec - for i in range(deg))) - and prec < maxprec): + for i in range(deg))) + and prec < maxprec): acb_poly_set_round(rounded_poly, poly._poly, prec) maxiter = min(max(deg, 32), prec) if (prec == initial_prec): @@ -905,7 +905,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): if proof: raise ValueError("unable to isolate the roots (try using " "proof=False or increasing the precision)") - else: + elif warn: warnings.warn("roots may have been lost") _acb_vec_sort_pretty(roots, deg) @@ -1029,11 +1029,11 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): balls, or elements of any parent that coerces into this ball field, e.g. rational or algebraic numbers. - - ``rel_tol`` (default: `2^{-p}` where `p` is the precision of - the ball field) -- relative accuracy goal + - ``rel_tol`` -- relative accuracy goal (default: `2^{-p}` where `p` is + the precision of the ball field) - - ``abs_tol`` (default: `2^{-p}` where `p` is the precision of - the ball field) -- absolute accuracy goal + - ``abs_tol`` -- absolute accuracy goal (default: `2^{-p}` where `p` is + the precision of the ball field) Additionally, the following optional parameters can be used to control the integration algorithm. See the `FLINT documentation `_ @@ -1048,12 +1048,12 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): - ``depth_limit`` -- maximum search depth for adaptive subdivision - - ``use_heap`` (boolean, default ``False``) -- if ``True``, use a + - ``use_heap`` -- boolean (default: ``False``); if ``True``, use a priority queue instead of a stack to manage subintervals. This sometimes gives better results for integrals with slow convergence but may require more memory and increasing ``depth_limit``. - - ``verbose`` (integer, default 0) -- If set to 1, some information + - ``verbose`` -- integer (default: 0); if set to 1, some information about the overall integration process is printed to standard output. If set to 2, information about each subinterval is printed. @@ -1306,7 +1306,7 @@ cdef inline real_ball_field(ComplexBall ball): cdef class ComplexBall(RingElement): """ - Hold one ``acb_t`` of the `FLINT library `_ + Hold one ``acb_t`` of the `FLINT library `_. EXAMPLES:: @@ -1342,10 +1342,10 @@ cdef class ComplexBall(RingElement): INPUT: - - ``parent`` -- a :class:`ComplexBallField`. + - ``parent`` -- a :class:`ComplexBallField` - - ``x``, ``y`` (optional) -- either a complex number, interval or ball, - or two real ones. + - ``x``, ``y`` -- (optional) either a complex number, interval or ball, + or two real ones .. SEEALSO:: :meth:`ComplexBallField._element_constructor_` @@ -1408,7 +1408,6 @@ cdef class ComplexBall(RingElement): Traceback (most recent call last): ... TypeError: unsupported initializer - """ cdef fmpz_t tmpz cdef fmpq_t tmpq @@ -1485,9 +1484,7 @@ cdef class ComplexBall(RingElement): """ Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1619,7 +1616,7 @@ cdef class ComplexBall(RingElement): INPUT: - ``parent`` -- :class:`~sage.rings.complex_mpfr.ComplexField_class`, - target parent. + target parent EXAMPLES:: @@ -1647,7 +1644,7 @@ cdef class ComplexBall(RingElement): INPUT: - ``parent`` -- :class:`~sage.rings.real_mpfi.RealIntervalField_class`, - target parent. + target parent EXAMPLES:: @@ -1672,7 +1669,7 @@ cdef class ComplexBall(RingElement): INPUT: - ``parent`` -- :class:`~sage.rings.real_mpfr.RealField_class`, - target parent. + target parent EXAMPLES:: @@ -1816,9 +1813,7 @@ cdef class ComplexBall(RingElement): """ Return the real part of this ball. - OUTPUT: - - A :class:`~sage.rings.real_arb.RealBall`. + OUTPUT: a :class:`~sage.rings.real_arb.RealBall` EXAMPLES:: @@ -1837,9 +1832,7 @@ cdef class ComplexBall(RingElement): """ Return the imaginary part of this ball. - OUTPUT: - - A :class:`~sage.rings.real_arb.RealBall`. + OUTPUT: a :class:`~sage.rings.real_arb.RealBall` EXAMPLES:: @@ -1878,13 +1871,11 @@ cdef class ComplexBall(RingElement): INPUT: - - ``test_zero`` (boolean, default ``False``) -- if ``True``, + - ``test_zero`` -- boolean (default: ``False``); if ``True``, make sure that the returned lower bound is positive, raising an error if the ball contains zero. - OUTPUT: - - A ball with zero radius + OUTPUT: a ball with zero radius EXAMPLES:: @@ -1915,9 +1906,7 @@ cdef class ComplexBall(RingElement): """ Return an upper bound for the absolute value of this complex ball. - OUTPUT: - - A ball with zero radius + OUTPUT: a ball with zero radius EXAMPLES:: @@ -1990,9 +1979,7 @@ cdef class ComplexBall(RingElement): """ Return an exact ball with the same midpoint as this ball. - OUTPUT: - - A :class:`ComplexBall`. + OUTPUT: a :class:`ComplexBall` EXAMPLES:: @@ -2205,12 +2192,10 @@ cdef class ComplexBall(RingElement): INPUT: - - ``ampl`` -- A **real** ball (or an object that can be coerced to a - real ball). - - OUTPUT: + - ``ampl`` -- a **real** ball (or an object that can be coerced to a + real ball) - A new complex ball. + OUTPUT: a new complex ball EXAMPLES:: @@ -2451,7 +2436,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``other`` -- a :class:`ComplexBall`. + - ``other`` -- a :class:`ComplexBall` OUTPUT: @@ -2480,7 +2465,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``other`` -- a :class:`ComplexBall`. + - ``other`` -- a :class:`ComplexBall` EXAMPLES:: @@ -2711,7 +2696,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``shift`` -- integer, may be negative. + - ``shift`` -- integer; may be negative EXAMPLES:: @@ -2762,7 +2747,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``shift`` -- integer, may be negative. + - ``shift`` -- integer; may be negative EXAMPLES:: @@ -2857,7 +2842,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the exponent is not an integer and the base ball touches the branch cut of the logarithm @@ -2924,7 +2909,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -2954,7 +2939,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3020,7 +3005,6 @@ cdef class ComplexBall(RingElement): [2.34369112679686134...e+347382171305201285713 +/- ...] sage: CBF(1/2).rising_factorial(CBF(2,3)) # abs tol 1e-15 [-0.123060451458124 +/- 3.06e-16] + [0.0406412631676552 +/- 7.57e-17]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_n = self._parent.coerce(n) @@ -3037,11 +3021,11 @@ cdef class ComplexBall(RingElement): INPUT: - - ``base`` (optional, complex ball or number) -- if ``None``, return + - ``base`` -- (optional) complex ball or number; if ``None``, return the principal branch of the natural logarithm ``ln(self)``, otherwise, return the general logarithm ``ln(self)/ln(base)`` - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut (with respect to ``self``) @@ -3092,7 +3076,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3351,7 +3335,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3380,7 +3364,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3409,7 +3393,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3440,7 +3424,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3469,7 +3453,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3498,7 +3482,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3567,7 +3551,7 @@ cdef class ComplexBall(RingElement): INPUT: - - ``analytic`` (optional, boolean) -- if ``True``, return an + - ``analytic`` -- boolean (default: ``False``); if ``True``, return an indeterminate (not-a-number) value when the input ball touches the branch cut @@ -3626,7 +3610,6 @@ cdef class ComplexBall(RingElement): nan sage: CBF(1,1).psi(10) [56514.8269344249 +/- ...e-11] + [56215.1218005823 +/- ...e-11]*I - """ cdef ComplexBall my_n cdef ComplexBall result = self._new() @@ -3675,7 +3658,7 @@ cdef class ComplexBall(RingElement): def zetaderiv(self, k): r""" - Return the image of this ball by the k-th derivative of the Riemann + Return the image of this ball by the `k`-th derivative of the Riemann zeta function. For a more flexible interface, see the low-level method @@ -3814,18 +3797,16 @@ cdef class ComplexBall(RingElement): INPUT: - - ``a`` -- upper parameters, list of complex numbers that coerce into - this ball's parent; + - ``a`` -- upper parameters; list of complex numbers that coerce into + this ball's parent - - ``b`` -- lower parameters, list of complex numbers that coerce into - this ball's parent. + - ``b`` -- lower parameters; list of complex numbers that coerce into + this ball's parent - - ``regularized`` -- if True, the regularized generalized hypergeometric - function is computed. + - ``regularized`` -- if ``True``, the regularized generalized + hypergeometric function is computed - OUTPUT: - - The generalized hypergeometric function defined by + OUTPUT: the generalized hypergeometric function defined by .. MATH:: @@ -3891,7 +3872,6 @@ cdef class ComplexBall(RingElement): sage: CBF(0, 1).hypergeometric([QQbar(sqrt(2)), RLF(pi)], [1r, 1/2]) # needs sage.symbolic [-8.7029449215408 +/- ...e-14] + [-0.8499070546106 +/- ...e-14]*I - """ cdef ComplexBall tmp, my_a, my_b, my_c cdef ComplexBall res = self._new() @@ -4024,7 +4004,6 @@ cdef class ComplexBall(RingElement): sage: ai, aip, bi, bip = CBF(1,2).airy() sage: (ai * bip - bi * aip) * CBF(pi) # needs sage.symbolic [1.0000000000000 +/- ...e-15] + [+/- ...e-16]*I - """ cdef ComplexBall ai = self._new() cdef ComplexBall aip = self._new() @@ -4126,7 +4105,6 @@ cdef class ComplexBall(RingElement): [+/- ...e-16] + [+/- ...e-16]*I sage: Y - CBF(1, 1).bessel_Y(1) [+/- ...e-14] + [+/- ...e-14]*I - """ cdef ComplexBall result1 = self._new() cdef ComplexBall result2 = self._new() @@ -4425,7 +4403,6 @@ cdef class ComplexBall(RingElement): [0.913579138156117 +/- ...e-16], [1.086434811213308 +/- ...e-16], [0.913579138156117 +/- ...e-16]) - """ cdef ComplexBall res1 = self._new() @@ -4447,7 +4424,6 @@ cdef class ComplexBall(RingElement): sage: CBF(0,1).modular_j() [1728.0000000000 +/- ...e-11] - """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4465,7 +4441,6 @@ cdef class ComplexBall(RingElement): [0.768225422326057 +/- ...e-16] sage: CBF(12,1).modular_eta() [-0.768225422326057 +/- ...e-16] - """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4487,7 +4462,6 @@ cdef class ComplexBall(RingElement): [-0.00022005123884157 +/- ...e-18] + [-0.00079787346459944 +/- ...e-18]*I sage: (tau / (1 - 2*tau)).modular_lambda() [-0.00022005123884 +/- ...e-15] + [-0.00079787346460 +/- ...e-15]*I - """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4509,7 +4483,6 @@ cdef class ComplexBall(RingElement): [0.20921376655 +/- ...e-12] + [1.57611925523 +/- ...e-12]*I sage: (c*tau+d)^12 * tau.modular_delta() [0.20921376654986 +/- ...e-15] + [1.5761192552253 +/- ...e-14]*I - """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4536,7 +4509,6 @@ cdef class ComplexBall(RingElement): [331011.2004330 +/- ...e-8] + [-711178.1655746 +/- ...e-8]*I sage: (c*tau+d)^8 * tau.eisenstein(3)[2] [331011.20043304 +/- ...e-9] + [-711178.1655746 +/- ...e-8]*I - """ if n < 0: raise ValueError("n must be nonnegative") @@ -4581,7 +4553,6 @@ cdef class ComplexBall(RingElement): [[-3.28920996772709 +/- ...e-15] + [-0.00036737673029 +/- ...e-15]*I, [0.0024730557943 +/- ...e-14] + [0.0038595540403 +/- ...e-14]*I, [-0.01299087562 +/- ...e-12] + [0.00725027522 +/- ...e-12]*I] - """ cdef ComplexBall my_tau = self._parent.coerce(tau) cdef ComplexBall result @@ -4659,7 +4630,6 @@ cdef class ComplexBall(RingElement): sage: CBF(2,3).elliptic_k() [1.04291329192852 +/- ...e-15] + [0.62968247230864 +/- ...e-15]*I - """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4676,7 +4646,6 @@ cdef class ComplexBall(RingElement): sage: CBF(2,3).elliptic_e() [1.472797144959 +/- ...e-13] + [-1.231604783936 +/- ...e-14]*I - """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4693,7 +4662,6 @@ cdef class ComplexBall(RingElement): sage: CBF(2,3).elliptic_pi(CBF(1,1)) [0.2702999736198...] + [0.715676058329...]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_m = self._parent.coerce(m) @@ -4731,7 +4699,6 @@ cdef class ComplexBall(RingElement): [1.3393589639094 +/- ...e-14] + [1.1104369690719 +/- ...e-14]*I sage: phi.elliptic_k() [1.33935896390938 +/- ...e-15] + [1.11043696907194 +/- ...e-15]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_m = self._parent.coerce(m) @@ -4769,7 +4736,6 @@ cdef class ComplexBall(RingElement): [0.787564350925 +/- ...e-13] + [-0.686896129145 +/- ...e-13]*I sage: phi.elliptic_e() [0.7875643509254 +/- ...e-14] + [-0.686896129145 +/- ...e-13]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_m = self._parent.coerce(m) @@ -4834,7 +4800,6 @@ cdef class ComplexBall(RingElement): sage: CBF(0,1).elliptic_rf(CBF(-1/2,1), CBF(-1,-1)) [1.469800396738515 +/- ...e-16] + [-0.2358791199824196 +/- ...e-17]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_y = self._parent.coerce(y) @@ -4859,7 +4824,6 @@ cdef class ComplexBall(RingElement): sage: CBF(0,1).elliptic_rg(CBF(-1/2,1), CBF(-1,-1)) [0.1586786770922370 +/- ...e-17] + [0.2239733128130531 +/- ...e-17]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_y = self._parent.coerce(y) @@ -4886,7 +4850,6 @@ cdef class ComplexBall(RingElement): sage: CBF(0,1).elliptic_rj(CBF(-1/2,1), CBF(-1,-1), CBF(2)) [1.00438675628573...] + [-0.24516268343916...]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_y = self._parent.coerce(y) @@ -4899,7 +4862,7 @@ cdef class ComplexBall(RingElement): def elliptic_zeta(self, tau): r""" - Return the value of the Weierstrass zeta function at ``(self, tau)`` + Return the value of the Weierstrass zeta function at ``(self, tau)``. EXAMPLES:: @@ -4919,7 +4882,7 @@ cdef class ComplexBall(RingElement): def elliptic_sigma(self, tau): r""" - Return the value of the Weierstrass sigma function at ``(self, tau)`` + Return the value of the Weierstrass sigma function at ``(self, tau)``. EXAMPLES:: @@ -4929,7 +4892,6 @@ cdef class ComplexBall(RingElement): sage: CBF(1,1).elliptic_sigma(CBF(1,3)) [-0.543073363596 +/- ...e-13] + [3.6357291186244 +/- ...e-14]*I - """ cdef ComplexBall result = self._new() cdef ComplexBall my_tau = self._parent.coerce(tau) @@ -4949,7 +4911,6 @@ cdef class ComplexBall(RingElement): [0.8710045668809 +/- ...e-14] sage: CBF(1/3).chebyshev_T(CBF(5,1)) [1.84296854518763 +/- ...e-15] + [0.20053614301799 +/- ...e-15]*I - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall result = self._new() @@ -4969,7 +4930,6 @@ cdef class ComplexBall(RingElement): [0.6973126541184 +/- ...e-14] sage: CBF(1/3).chebyshev_U(CBF(5,1)) [1.75884964893425 +/- ...e-15] + [0.7497317165104 +/- ...e-14]*I - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall result = self._new() @@ -4987,7 +4947,6 @@ cdef class ComplexBall(RingElement): sage: CBF(5,-6).jacobi_P(8, CBF(1,2), CBF(2,3)) [-920983000.45982 +/- ...e-6] + [6069919969.92857 +/- ...e-6]*I - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall my_a = self._parent.coerce(a) @@ -5008,7 +4967,6 @@ cdef class ComplexBall(RingElement): sage: CBF(-10).gegenbauer_C(7, 1/2) [-263813415.6250000 +/- ...e-8] - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall my_m = self._parent.coerce(m) @@ -5053,7 +5011,6 @@ cdef class ComplexBall(RingElement): 20.00000000000000 sage: CBF(10).hermite_H(30) [8.0574670961707e+37 +/- ...e+23] - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall result = self._new() @@ -5082,7 +5039,6 @@ cdef class ComplexBall(RingElement): [-22104403.487377 +/- ...e-7] + [53364750.687392 +/- ...e-7]*I sage: CBF(-10).legendre_P(5, 325/100, type=3) [-57761589.914581 +/- ...e-7] + [+/- ...e-7]*I - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall my_m = self._parent.coerce(m) @@ -5116,7 +5072,6 @@ cdef class ComplexBall(RingElement): [-83825154.36008 +/- ...e-6] + [-34721515.80396 +/- ...e-6]*I sage: CBF(-10).legendre_Q(5, 325/100, type=3) [-4.797306921692e-6 +/- ...e-19] + [-4.797306921692e-6 +/- ...e-19]*I - """ cdef ComplexBall my_n = self._parent.coerce(n) cdef ComplexBall my_m = self._parent.coerce(m) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index c59a2b46d6f..d6e5a7d05b1 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -164,7 +164,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): cpdef bint is_exact(self) except -2: """ - Returns whether or not this field is exact, which is always ``False``. + Return whether or not this field is exact, which is always ``False``. EXAMPLES:: @@ -260,9 +260,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - a string. + OUTPUT: string TESTS:: @@ -302,7 +300,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): sage: CDF(mpc('2.0+1.0j')) 2.0 + 1.0*I - A ``TypeError`` is raised if the coercion doesn't make sense:: + A :exc:`TypeError` is raised if the coercion doesn't make sense:: sage: CDF(QQ['x'].0) Traceback (most recent call last): @@ -379,7 +377,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): cpdef _coerce_map_from_(self, S): """ Return the canonical coerce of `x` into the complex double field, if - it is defined, otherwise raise a ``TypeError``. + it is defined, otherwise raise a :exc:`TypeError`. The rings that canonically coerce to the complex double field are: @@ -487,7 +485,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): def to_prec(self, prec): """ - Returns the complex field to the specified precision. As doubles + Return the complex field to the specified precision. As doubles have fixed precision, this will only return a complex double field if prec is exactly 53. @@ -534,7 +532,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): def algebraic_closure(self): r""" - Returns the algebraic closure of ``self``, i.e., the complex double + Return the algebraic closure of ``self``, i.e., the complex double field. EXAMPLES:: @@ -558,7 +556,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): def pi(self): r""" - Returns `\pi` as a double precision complex number. + Return `\pi` as a double precision complex number. EXAMPLES:: @@ -569,7 +567,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): def construction(self): """ - Returns the functorial construction of ``self``, namely, algebraic + Return the functorial construction of ``self``, namely, algebraic closure of the real double field. EXAMPLES:: @@ -589,9 +587,9 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): INPUT: - - ``n`` -- a positive integer (default: 2) + - ``n`` -- positive integer (default: 2) - OUTPUT: a complex `n`-th root of unity. + OUTPUT: a complex `n`-th root of unity EXAMPLES:: @@ -677,7 +675,6 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): sage: F = f.factor() sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-9 [1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14, 3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14] - """ unit = f.leading_coefficient() f *= ~unit @@ -691,7 +688,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): cdef ComplexDoubleElement new_ComplexDoubleElement(): """ - Creates a new (empty) :class:`ComplexDoubleElement`. + Create a new (empty) :class:`ComplexDoubleElement`. """ cdef ComplexDoubleElement z z = ComplexDoubleElement.__new__(ComplexDoubleElement) @@ -745,7 +742,7 @@ cdef class ComplexDoubleElement(FieldElement): def __init__(self, real, imag): """ - Constructs an element of a complex double field with specified real + Construct an element of a complex double field with specified real and imaginary values. EXAMPLES:: @@ -779,7 +776,7 @@ cdef class ComplexDoubleElement(FieldElement): def __hash__(self): """ - Returns the hash of ``self``, which coincides with the python ``float`` + Return the hash of ``self``, which coincides with the python ``float`` and ``complex`` (and often ``int``) types for ``self``. EXAMPLES:: @@ -843,13 +840,13 @@ cdef class ComplexDoubleElement(FieldElement): def __getitem__(self, n): """ - Returns the real or imaginary part of ``self``. + Return the real or imaginary part of ``self``. INPUT: - - ``n`` -- integer (either 0 or 1) + - ``n`` -- integer (either 0 or 1) - Raises an ``IndexError`` if ``n`` is not 0 or 1. + Raises an :exc:`IndexError` if ``n`` is not 0 or 1. EXAMPLES:: @@ -889,7 +886,7 @@ cdef class ComplexDoubleElement(FieldElement): def prec(self): """ - Returns the precision of this number (to be more similar to + Return the precision of this number (to be more similar to :class:`ComplexNumber`). Always returns 53. EXAMPLES:: @@ -961,7 +958,7 @@ cdef class ComplexDoubleElement(FieldElement): def _interface_init_(self, I=None): """ - Returns ``self`` formatted as a string, suitable as input to another + Return ``self`` formatted as a string, suitable as input to another computer algebra system. (This is the default function used for exporting to other computer algebra systems.) @@ -1470,8 +1467,8 @@ cdef class ComplexDoubleElement(FieldElement): INPUT: - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots If all is ``False``, the branch cut is the negative real axis. The result always lies in the right half of the complex plane. @@ -1512,8 +1509,8 @@ cdef class ComplexDoubleElement(FieldElement): INPUT: - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all ``n``-th roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all ``n``-th roots EXAMPLES:: @@ -1550,7 +1547,7 @@ cdef class ComplexDoubleElement(FieldElement): def is_integer(self): """ - Return ``True`` if this number is a integer + Return ``True`` if this number is a integer. EXAMPLES:: @@ -1740,7 +1737,7 @@ cdef class ComplexDoubleElement(FieldElement): INPUT: - - ``base`` -- default: `e`, the base of the natural logarithm + - ``base`` -- (default: `e`) the base of the natural logarithm EXAMPLES:: @@ -2155,15 +2152,15 @@ cdef class ComplexDoubleElement(FieldElement): ####################################################################### def eta(self, int omit_frac=0): r""" - Return the value of the Dedekind `\eta` function on self. + Return the value of the Dedekind `\eta` function on ``self``. INPUT: - - ``self`` -- element of the upper half plane (if not, - raises a ValueError). + - ``self`` -- element of the upper half plane (if not, + raises a ValueError) - - ``omit_frac`` -- (bool, default: ``False``), if ``True``, - omit the `e^{\pi i z / 12}` factor. + - ``omit_frac`` -- boolean (default: ``False``); if ``True``, + omit the `e^{\pi i z / 12}` factor OUTPUT: a complex double number @@ -2247,20 +2244,20 @@ cdef class ComplexDoubleElement(FieldElement): cdef int flag = 0 if omit_frac else 1 return complex_double_element_eta(self, flag) - def agm(self, right, algorithm="optimal"): + def agm(self, right, algorithm='optimal'): r""" Return the Arithmetic-Geometric Mean (AGM) of ``self`` and ``right``. INPUT: - - ``right`` (complex) -- another complex number + - ``right`` -- complex; another complex number - - ``algorithm`` (string, default ``"optimal"``) -- the algorithm to use - (see below). + - ``algorithm`` -- string (default: ``'optimal'``); the algorithm to + use (see below) OUTPUT: - (complex) A value of the AGM of self and right. Note that + (complex) A value of the AGM of ``self`` and ``right``. Note that this is a multi-valued function, and the algorithm used affects the value returned, as follows: @@ -2349,7 +2346,7 @@ cdef class ComplexDoubleElement(FieldElement): def dilog(self): r""" - Returns the principal branch of the dilogarithm of `x`, i.e., analytic + Return the principal branch of the dilogarithm of `x`, i.e., analytic continuation of the power series .. MATH:: @@ -2444,7 +2441,7 @@ cdef class ComplexDoubleElement(FieldElement): def algdep(self, long n): """ - Returns a polynomial of degree at most `n` which is + Return a polynomial of degree at most `n` which is approximately satisfied by this complex number. Note that the returned polynomial need not be irreducible, and indeed usually won't be if `z` is a good approximation to an algebraic @@ -2501,7 +2498,6 @@ cdef class FloatToCDF(Morphism): To: Complex Double Field sage: f(3.5) 3.5 - """ def __init__(self, R): """ @@ -2558,10 +2554,10 @@ cdef class ComplexToCDF(Morphism): sage: # needs numpy sage: import numpy - sage: f = CDF.coerce_map_from(numpy.complex_) - sage: f(numpy.complex_(I)) + sage: f = CDF.coerce_map_from(numpy.complex128) + sage: f(numpy.complex128(I)) 1.0*I - sage: f(numpy.complex_(I)).parent() + sage: f(numpy.complex128(I)).parent() Complex Double Field """ def __init__(self, R): @@ -2578,7 +2574,7 @@ cdef class ComplexToCDF(Morphism): EXAMPLES:: sage: import numpy # needs numpy - sage: CDF(numpy.complex_(I)) # indirect doctest # needs numpy + sage: CDF(numpy.complex128(I)) # indirect doctest # needs numpy 1.0*I """ cdef ComplexDoubleElement z = ComplexDoubleElement.__new__(ComplexDoubleElement) @@ -2592,7 +2588,7 @@ cdef class ComplexToCDF(Morphism): EXAMPLES:: sage: import numpy # needs numpy - sage: f = sage.rings.complex_double.ComplexToCDF(numpy.complex_) # needs numpy + sage: f = sage.rings.complex_double.ComplexToCDF(numpy.complex128) # needs numpy sage: f._repr_type() # needs numpy 'Native' """ @@ -2610,7 +2606,7 @@ cdef ComplexDoubleElement I = ComplexDoubleElement(0,1) def ComplexDoubleField(): """ - Returns the field of double precision complex numbers. + Return the field of double precision complex numbers. EXAMPLES:: @@ -2623,7 +2619,7 @@ def ComplexDoubleField(): from sage.misc.parser import Parser -cdef cdf_parser = Parser(float, float, {"I" : _CDF.gen(), "i" : _CDF.gen()}) +cdef cdf_parser = Parser(float, float, {"I": _CDF.gen(), "i": _CDF.gen()}) cdef inline double complex extract_double_complex(ComplexDoubleElement x) noexcept: """ diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index 5b3064688b0..c9273384788 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -208,7 +208,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): return self.imag() raise IndexError("i must be between 0 and 1.") - def __reduce__( self ): + def __reduce__(self): """ Pickling support. @@ -271,7 +271,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): INPUT: - ``parent`` -- :class:`~sage.rings.real_mpfr.RealField_class`, - target parent. + target parent EXAMPLES:: @@ -532,7 +532,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): def overlaps(self, ComplexIntervalFieldElement other): """ - Return ``True`` if ``self`` and other are intervals with at least + Return ``True`` if ``self`` and ``other`` are intervals with at least one value in common. EXAMPLES:: @@ -799,16 +799,16 @@ cdef class ComplexIntervalFieldElement(FieldElement): sage: b = CIF(-1, (2, 3)) sage: c = a/b sage: c.endpoints() - (0.200000000000000 - 2.00000000000000*I, - 2.30000000000000 - 0.500000000000000*I, - 0.200000000000000 - 0.500000000000000*I, - 2.30000000000000 - 2.00000000000000*I) + (0.500000000000000 - 1.60000000000000*I, + 1.50000000000000 - 0.600000000000000*I, + 0.500000000000000 - 0.600000000000000*I, + 1.50000000000000 - 1.60000000000000*I) sage: c = b/a sage: c.endpoints() - (0.100000000000000 + 0.250000000000000*I, - 1.15000000000000 + 1.00000000000000*I, - 0.100000000000000 + 1.00000000000000*I, - 1.15000000000000 + 0.250000000000000*I) + (0.246153846153846 + 0.317647058823529*I, + 0.841176470588236 + 0.761538461538462*I, + 0.246153846153846 + 0.761538461538462*I, + 0.841176470588236 + 0.317647058823529*I) """ return self * right.__invert__() @@ -854,19 +854,19 @@ cdef class ComplexIntervalFieldElement(FieldElement): Note that ``x^2`` is not the same as ``x*x``:: sage: a = CIF(RIF(-1,1)) - sage: print((a^2).str(style="brackets")) + sage: print((a^2).str(style='brackets')) [0.0000000000000000 .. 1.0000000000000000] - sage: print((a*a).str(style="brackets")) + sage: print((a*a).str(style='brackets')) [-1.0000000000000000 .. 1.0000000000000000] sage: a = CIF(0, RIF(-1,1)) - sage: print((a^2).str(style="brackets")) + sage: print((a^2).str(style='brackets')) [-1.0000000000000000 .. -0.0000000000000000] - sage: print((a*a).str(style="brackets")) + sage: print((a*a).str(style='brackets')) [-1.0000000000000000 .. 1.0000000000000000] sage: a = CIF(RIF(-1,1), RIF(-1,1)) - sage: print((a^2).str(style="brackets")) + sage: print((a^2).str(style='brackets')) [-1.0000000000000000 .. 1.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I - sage: print((a*a).str(style="brackets")) + sage: print((a*a).str(style='brackets')) [-2.0000000000000000 .. 2.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I We can take very high powers:: @@ -876,7 +876,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): sage: s = RealField(27, rnd="RNDZ")(1/2)^(1/3) sage: a = CIF(RIF(-s/2,s/2), RIF(-s, s)) sage: r = a^(10^10000) - sage: print(r.str(style="brackets")) + sage: print(r.str(style='brackets')) [-2.107553304e1028 .. 2.107553304e1028] + [-2.107553304e1028 .. 2.107553304e1028]*I TESTS:: @@ -973,13 +973,13 @@ cdef class ComplexIntervalFieldElement(FieldElement): def _interface_init_(self, I=None): """ - Raise a ``TypeError``. + Raise a :exc:`TypeError`. This function would return the string representation of ``self`` that makes sense as a default representation of a complex interval in other computer algebra systems. But, most other computer algebra systems do not support interval arithmetic, - so instead we just raise a ``TypeError``. + so instead we just raise a :exc:`TypeError`. Define the appropriate ``_cas_init_`` function if there is a computer algebra system you would like to support. @@ -992,7 +992,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): ... TypeError - Here a conversion to Maxima happens, which results in a ``TypeError``:: + Here a conversion to Maxima happens, which results in a :exc:`TypeError`:: sage: a = CIF(2.3) sage: maxima(a) # needs sage.symbolic @@ -1002,7 +1002,6 @@ cdef class ComplexIntervalFieldElement(FieldElement): """ raise TypeError - def _sage_input_(self, sib, coerce): r""" Produce an expression which will reproduce this value when evaluated. @@ -1135,10 +1134,10 @@ cdef class ComplexIntervalFieldElement(FieldElement): sage: a = CIF((1, 2), (3, 4)) sage: c = a.__invert__() sage: c.endpoints() - (0.0500000000000000 - 0.400000000000000*I, - 0.200000000000000 - 0.150000000000000*I, - 0.0500000000000000 - 0.150000000000000*I, - 0.200000000000000 - 0.400000000000000*I) + (0.0588235294117647 - 0.300000000000000*I, + 0.153846153846154 - 0.200000000000000*I, + 0.0588235294117647 - 0.200000000000000*I, + 0.153846153846154 - 0.300000000000000*I) TESTS: @@ -1155,7 +1154,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): Test that the bug reported in :issue:`25414` has been fixed:: sage: 1 / CIF(RIF(-1 ,1), 0) - [-infinity .. +infinity] + [0.0000000000000000 .. +infinity]*I + [.. NaN ..] + [.. NaN ..]*I Test that the bug reported in :issue:`37927` is fixed:: @@ -1166,24 +1165,161 @@ cdef class ComplexIntervalFieldElement(FieldElement): - [RL1971]_ """ - cdef ComplexIntervalFieldElement x + cdef ComplexIntervalFieldElement result x = self._new() - cdef mpfi_t t0, t1 - mpfi_init2(t0, self._prec) - mpfi_init2(t1, self._prec) - - mpfi_sqr(t0, self.__re) - mpfi_sqr(t1, self.__im) - - mpfi_add(t0, t0, t1) # now t0 is the norm - mpfi_div(x.__re, self.__re, t0) # x.__re = self.__re/norm + if mpfi_nan_p(self.__re) or mpfi_nan_p(self.__im): + # Return NaN if any input is NaN + return x - mpfi_neg(t1, self.__im) - mpfi_div(x.__im, t1, t0) # x.__im = -self.__im/norm + if mpfi_has_zero(self.__re) and mpfi_has_zero(self.__im): + # Return NaN when dividing by (a complex interval containing) zero. + return x - mpfi_clear(t0) - mpfi_clear(t1) + # The algorithm roughly follows [RL1971]. + # + # However, we deviate from [RL1971] significantly and the + # documentation here is self-contained and hopefully easier + # to follow than [RL1971]. There is a visualization at: + # https://www.shadertoy.com/view/M3VXWG + # + # Note that [RL1971] has several mistakes. For example, when analyzing + # the second case where y1 < 0 and y2 > 0 (and x1 >= 0 from earlier + # assumptions), they have a subcase "y_1 >= x_1". That inequality can + # never be true given the earlier assumptions and should be + # "-y_1 >= x_1". + + # To maximize symmetry considerations, we actually compute the + # circle inversion (z |-> conjugate(1/z)) and conjugate at the end. + + # Let the input be the complex interval [xmin, xmax] + [ymin, ymax] * I. + # + # We say that the complex interval is in standard form if either: + # (I) It is contained within the first quadrant. Furthermore its + # left bottom corner is on or below the north east diagonal. + # That is 0 <= ymin <= xmin. Or: + # (II) It is contained within the first and fourth quadrant crossing + # the (positive) x-Axis. Furthermore, its midpoint is above the + # x-Axis. + # That is 0 < xmin; ymin < 0 < ymax and |ymin| <= |ymax|. + # + # Since we already guarded against the input containing zero, we always + # can and will bring it into standard form by negating or swapping the + # real and imaginary part. + + cdef mpfr_t xmin, xmax, ymin, ymax + mpfr_init2(xmin, self._prec) + mpfr_init2(xmax, self._prec) + mpfr_init2(ymin, self._prec) + mpfr_init2(ymax, self._prec) + + mpfi_get_left(xmin, self.__re) + mpfi_get_right(xmax, self.__re) + mpfi_get_left(ymin, self.__im) + mpfi_get_right(ymax, self.__im) + + # Record what mirror symmetries we applied to undo them later. + # + # We assume that we flip about the coordinate axes before flipping + # about the north east diagonal. + cdef bint negated_x = False + cdef bint negated_y = False + cdef bint swapped_xy = False + + # Record whether we are in case (II). + cdef bint crosses_x_axis = False + + ######################################################################## + # Now bring the input into standard form. + + if mpfr_sgn(ymax) <= 0: + # Interval below (and possibly touching) x-Axis, flip about it. + _negate_interval(ymin, ymax) + negated_y = True + elif mpfr_sgn(ymin) < 0: + # Interval crosses x-Axis + crosses_x_axis = True + # else: Interval is above x-Axis + + # Negating interval for y and swapping do not commute, so + # order of the above and below if-block is important. + + if mpfr_sgn(xmax) <= 0: + # Interval left of (and possibly touching) y-Axis, flip about it. + _negate_interval(xmin, xmax) + negated_x = True + elif mpfr_sgn(xmin) < 0: + # Interval crosses y-Axis, swap to make it cross x-Axis instead. + mpfr_swap(xmin, ymin) + mpfr_swap(xmax, ymax) + swapped_xy = True + crosses_x_axis = True + # else: Interval is right of y-Axis + + if crosses_x_axis: + # Case (II). Ensure standard condition |ymax| >= |ymin| + if mpfr_cmpabs(ymin, ymax) > 0: + _negate_interval(ymin, ymax) + # Note that we negate after potentially swapping. + # Determine what we should have negated before swapping instead. + if swapped_xy: + # negated_x cannot be True already. + negated_x = True + else: + # negated_y cannot be True already. + negated_y = True + else: + # Case (I). Ensure standard condition |ymin| <= |xmin|. + if mpfr_cmp(xmin, ymin) < 0: + mpfr_swap(xmin, ymin) + mpfr_swap(xmax, ymax) + swapped_xy = True + + ######################################################################## + # Apply circle inversion + + # Result will be [amin, amax] + [bmin, bmax] * I. + cdef mpfr_t amin, amax, bmin, bmax + + mpfr_init2(amin, self._prec) + mpfr_init2(amax, self._prec) + mpfr_init2(bmin, self._prec) + mpfr_init2(bmax, self._prec) + + _circle_invert_standard( + amin, amax, bmin, bmax, + xmin, xmax, ymin, ymax, + crosses_x_axis, self._prec) + + ######################################################################## + # Undo symmetries applied above. + + if swapped_xy: + mpfr_swap(amin, bmin) + mpfr_swap(amax, bmax) + + if negated_x: + _negate_interval(amin, amax) + + # We sneak in the promised conjugation by + # inverting negated_y. + if not negated_y: + _negate_interval(bmin, bmax) + + ######################################################################## + # Write out result and free memory + + mpfi_interv_fr(x.__re, amin, amax) + mpfi_interv_fr(x.__im, bmin, bmax) + + mpfr_clear(xmin) + mpfr_clear(xmax) + mpfr_clear(ymin) + mpfr_clear(ymax) + mpfr_clear(amin) + mpfr_clear(amax) + mpfr_clear(bmin) + mpfr_clear(bmax) return x @@ -1435,7 +1571,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): def multiplicative_order(self): """ Return the multiplicative order of this complex number, if known, - or raise a ``NotImplementedError``. + or raise a :exc:`NotImplementedError`. EXAMPLES:: @@ -1478,7 +1614,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): The argument (angle) of the complex number, normalized so that `-\pi < \theta.lower() \leq \pi`. - We raise a ``ValueError`` if the interval strictly contains 0, + We raise a :exc:`ValueError` if the interval strictly contains 0, or if the interval contains only 0. .. WARNING:: @@ -1718,8 +1854,8 @@ cdef class ComplexIntervalFieldElement(FieldElement): INPUT: - - ``all`` -- bool (default: ``False``); if ``True``, return a list - of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a list + of all square roots EXAMPLES:: @@ -1876,7 +2012,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): sage: CIF(1,1).tan() 0.27175258531952? + 1.08392332733870?*I sage: CIF(2).tan() - -2.18503986326152? + -2.185039863261519? sage: CIF(0,2).tan() 0.964027580075817?*I """ @@ -1965,7 +2101,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): sage: CIF(2).tanh() 0.964027580075817? sage: CIF(0,2).tanh() - -2.18503986326152?*I + -2.185039863261519?*I """ return self.sinh() / self.cosh() @@ -1988,6 +2124,271 @@ cdef class ComplexIntervalFieldElement(FieldElement): return ComplexBallField(self.prec())(self).zeta(a).\ _complex_mpfi_(self._parent) +cdef _negate_interval(mpfr_ptr xmin, mpfr_ptr xmax): + """ + Negate interval with endpoints xmin and xmax in place. + """ + mpfr_swap(xmin, xmax) + mpfr_neg(xmin, xmin, MPFR_RNDD) + mpfr_neg(xmax, xmax, MPFR_RNDU) + +cdef _inversion_coordinate( + mpfr_ptr result, mpfr_ptr tmp, + mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_denom, mpfr_rnd_t rnd): + """ + Compute the x-coordinate of the image of the point (x,y) under inversion. + That is compute x / (x^2 + y^2). + + rnd_denom determines how to round when computing the denominator. + rnd determines how to round when doing the division. + + This function expects the callee to allocate and pass an mpfr number tmp + that will be used for intermediate computations. This way, an allocated + mpfr number can be used in multiple calculations. + """ + + mpfr_sqr(tmp, x, rnd_denom) + mpfr_sqr(result, y, rnd_denom) + mpfr_add(tmp, tmp, result, rnd_denom) + mpfr_div(result, x, tmp, rnd) + +cdef _inversion_coordinate_pos_down( + mpfr_ptr result, mpfr_ptr tmp, + mpfr_srcptr x, mpfr_srcptr y): + """ + Computes a lower bound for x / (x^2 + y^2) assuming that x is non-negative. + + Note that the result will not be NaN as long as x or y is positive. + """ + + # Let us check that we do not get NaN. + # We need to check mpfr_div since it could return NaN if we divide by zero + # (it currently returns +/-inf, but the documentation says this might be + # subject to change). + # We round up when computing the denominator and thus should get something + # positive if x or y is positive. Even if, say, x is so small that squaring + # produces something smaller than the smallest positive mpfr floating point + # number, we get something non-zero because we round up. + + _inversion_coordinate( + result, tmp, x, y, + MPFR_RNDU, # denominator rounding + MPFR_RNDD) # division rounding + +cdef _inversion_coordinate_pos_up( + mpfr_ptr result, mpfr_ptr tmp, + mpfr_srcptr x, mpfr_srcptr y): + """ + Computes an upper bound for x / (x^2 + y^2) assuming that x is non-negative. + """ + _inversion_coordinate( + result, tmp, x, y, + MPFR_RNDD, # denominator rounding + MPFR_RNDU) # division rounding + +cdef _inversion_coordinate_neg_down( + mpfr_ptr result, mpfr_ptr tmp, + mpfr_srcptr x, mpfr_srcptr y): + """ + Computes a lower bound for x / (x^2 + y^2) assuming that x is non-positive. + """ + _inversion_coordinate( + result, tmp, x, y, + MPFR_RNDD, # denominator rounding + MPFR_RNDD) # division rounding + +cdef _circle_invert_standard( + mpfr_ptr amin, mpfr_ptr amax, mpfr_ptr bmin, mpfr_ptr bmax, + mpfr_srcptr xmin, mpfr_srcptr xmax, mpfr_srcptr ymin, mpfr_srcptr ymax, + bint crosses_x_axis, mpfr_prec_t prec): + """ + Assumes that the input [xmin, xmax] + [ymin, ymax] * I is in standard form + as described above in ComplexIntervalFieldElement.__invert__ with + crosses_x_axis saying whether case (II) applies. + + Computes a complex interval [amin, amax] + [bmin, bmax] * I containing + the image of the input under circle inversion f(z) = conjugate(1/z). + """ + + # Note that, by the maximum principle, it is sufficient to consider the + # image of the boundary of the input rect which will be formed by four + # arcs or line segments. + + # It is useful to do a case analysis by considering whether the input + # crosses the x-Axis, the north east or south east diagonal, respectively. + # + # Given standard form, the input also has to cross the north east + # diagonal and x-Axis if it crosses the south east diagonal. + # + # Thus, we are left with five cases: + # + # NE diagonal x-Axis SE diagonal. + # 1. + # 2. crosses + # 3. crosses + # 4. crosses crosses + # 5. crosses crosses crosses + + # The reader can go to https://www.shadertoy.com/view/M3VXWG to explore + # the different cases visually. + + # Case 1 is the easiest (and the generic case for small intervals). + # + # Consider the images + # f(xmin + ymin * I), ..., f(xmax + ymax * I) + # of the four corners of the input rect under inversion f. + # Now consider the the axis-parallel rectangle R that these images span. + # In general, the image of the input rect might not be contained in R. + # In case 1, however, (and only in case 1) it is and we furthermore know + # which image is mapped to which edge of R. Thus, we have: + # + # amin = Re(f(xmax + ymax * I)) # Image of right top corner + # amax = Re(f(xmin + ymin * I)) # left bottom corner + # bmin = Im(f(xmax + ymin * I)) # right bottom corner + # = Re(f(ymin + xmax * I)) + # bmax = Im(f(xmin + ymax * I)) # left top corner + # = Re(f(ymax + xmin * I)) + # + # Re(f(...)) can be computed with the correct rounding using one of the + # helper functions such as _inversion_coordinate_pos_down. + + # For the other cases, we might need to consider the images of two corners + # and take the minimum to compute, say amin. + + # Furthermore, we also need to consider the image of t + xmin * I which is + # a circle touching the y-Axis at the origin. Depending on which of the + # diagonals and x-Axis the input rect crosses, we need to expand R to + # include the lowest, highest or rightmost point on this circle for the + # correct result. + # + # For example, we have + # amax = 1 / xmin for case 2 and bmax = 1 / (2 * ymin) for case 3. + # + + cdef bint crosses_NE_diagonal = mpfr_cmp(ymax, xmin) > 0 + cdef bint crosses_both_diagonals = False + # Using that input can only cross south east diagonal if it crosses + # x-Axis and north east diagonal. + if crosses_x_axis and crosses_NE_diagonal: + crosses_both_diagonals = mpfr_cmpabs(ymin, xmin) > 0 + + # Some temporary variables + cdef mpfr_t tmp, min2 + + mpfr_init2(tmp, prec) + if crosses_NE_diagonal: + # Temporary variable needed only in some cases. + mpfr_init2(min2, prec) + + ######################################################################## + # Compute amin + + # Use image of right top corner + _inversion_coordinate_pos_down(amin, tmp, xmax, ymax) + + if crosses_NE_diagonal: + # Also use image of left top corner. + + # This is because in this case, the image of the left top corner + # can be left of the image of the right top corner. + + _inversion_coordinate_pos_down(min2, tmp, xmin, ymax) + + # Note that mpfr_min does not return NaN if one (but not the other) + # input is NaN. This could be a problem. Luckily, + # _inversion_coordinate_pos_down never produces NaN. + mpfr_min(amin, amin, min2, MPFR_RNDD) + + # Note that we do not need to consider the images of the left or right + # bottom corner here. Not even in case 5. + # This is because in standard form, the top edge is further aways from + # the x-Axis than the bottom edge. Thus, the images of the left and + # right corner of the top edge is left of those of the bottom edge, + # respectively. + + # Potential optimization: if bmax >= amax, we only need to use the + # image of the left top corner and skip computing the image of the + # right top corner. + + ######################################################################## + # Compute amax + + if crosses_x_axis: + # Use rightmost point on the circle that is the image of + # image of t + xmin * I + mpfr_ui_div(amax, 1, xmin, MPFR_RNDU) + else: + # Use image of left bottom corner + _inversion_coordinate_pos_up(amax, tmp, xmin, ymin) + + ######################################################################## + # Compute bmax + + # In case 5, bmin can reuse bmax (up to sign), so we compute bmax first. + + if crosses_NE_diagonal: + # Use highest point on the circle that is the image of + # t + xmin * I. That is bmax = 1 / (2 * xmin). + if crosses_x_axis: + # Re-use amax = 1 / xmin. + # We can just copy the mantissa and decrease the exponent by 1. + mpfr_div_2ui(bmax, amax, 1, MPFR_RNDU) + else: + # Compute bmax from scratch. + mpfr_ui_div(bmax, 1, xmin, MPFR_RNDU) + mpfr_div_2ui(bmax, bmax, 1, MPFR_RNDU) + else: + # Use image of of left top corner + _inversion_coordinate_pos_up(bmax, tmp, ymax, xmin) + + ######################################################################## + # Compute bmin + + # bmin is probably the hardest to compute. + + cdef bint right_edge_crosses_NE_diagonal + + if crosses_x_axis: + # ymin and thus bmin will be negative. + if crosses_both_diagonals: + # We are in case 5. + # + # Use lowest point on the circle that is the image of + # t + xmin * I. That is bmin = -1 / (2 * xmin). + # + # We can reuse bmax = 1 / (2 * xmin). + mpfr_neg(bmin, bmax, MPFR_RNDD) + else: + # Use image of left bottom corner. + _inversion_coordinate_neg_down(bmin, tmp, ymin, xmin) + else: + # ymin and thus bmin will be non-negative. + + # Use image of right bottom corner. + _inversion_coordinate_pos_down(bmin, tmp, ymin, xmax) + + if crosses_NE_diagonal: + right_edge_crosses_NE_diagonal = mpfr_cmp(ymax, xmax) > 0 + if right_edge_crosses_NE_diagonal: + # Also use image of right top corner. + # + # This is similar to the computation of amin which also + # considered a second corner when crosses_NE_diagonal. + # + # In particular, the same comment about NaN applies. + # + _inversion_coordinate_pos_down(min2, tmp, ymax, xmax) + + # See comment about NaN above. + mpfr_min(bmin, bmin, min2, MPFR_RNDD) + + ######################################################################## + # Free memory + + mpfr_clear(tmp) + if crosses_NE_diagonal: + mpfr_clear(min2) + def make_ComplexIntervalFieldElement0( fld, re, im ): """ @@ -2010,16 +2411,16 @@ def create_ComplexIntervalFieldElement(s_real, s_imag=None, int pad=0, min_prec= INPUT: - - ``s_real`` -- a string that defines a real number (or something whose + - ``s_real`` -- string that defines a real number (or something whose string representation defines a number) - - ``s_imag`` -- a string that defines a real number (or something whose + - ``s_imag`` -- string that defines a real number (or something whose string representation defines a number) - - ``pad`` -- an integer at least 0. + - ``pad`` -- integer at least 0 - ``min_prec`` -- number will have at least this many bits of precision, - no matter what. + no matter what EXAMPLES:: @@ -2054,7 +2455,6 @@ def create_ComplexIntervalFieldElement(s_real, s_imag=None, int pad=0, min_prec= ....: assert c_CIFE(0,s).imag()-1 != 0 ....: except TypeError: ....: pass - """ if s_imag is None: s_imag = 0 diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index 372d84abca8..0b6981cf07b 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -148,7 +148,7 @@ class ComplexIntervalField_class(sage.rings.abc.ComplexIntervalField): sage: CIF.category() Category of infinite fields - sage: TestSuite(CIF).run(skip="_test_gcd_vs_xgcd") + sage: TestSuite(CIF).run(skip='_test_gcd_vs_xgcd') TESTS: @@ -195,7 +195,7 @@ def __init__(self, prec=53): from sage.categories.fields import Fields Field.__init__(self, self.real_field(), ("I",), False, category=Fields().Infinite()) - self._populate_coercion_lists_(convert_method_name="_complex_mpfi_") + self._populate_coercion_lists_(convert_method_name='_complex_mpfi_') def __reduce__(self): """ @@ -210,7 +210,7 @@ def __reduce__(self): def construction(self): """ - Returns the functorial construction of this complex interval field, + Return the functorial construction of this complex interval field, namely as the algebraic closure of the real interval field with the same precision. @@ -254,7 +254,7 @@ def is_exact(self): def prec(self): """ - Returns the precision of ``self`` (in bits). + Return the precision of ``self`` (in bits). EXAMPLES:: @@ -267,7 +267,7 @@ def prec(self): def to_prec(self, prec): """ - Returns a complex interval field with the given precision. + Return a complex interval field with the given precision. EXAMPLES:: @@ -625,7 +625,7 @@ def is_field(self, proof=True): def pi(self): r""" - Returns `\pi` as an element in the complex (interval) field. + Return `\pi` as an element in the complex (interval) field. EXAMPLES:: @@ -659,11 +659,9 @@ def zeta(self, n=2): INPUT: - - ``n`` -- an integer (default: 2) + - ``n`` -- integer (default: 2) - OUTPUT: - - A complex `n`-th root of unity. + OUTPUT: a complex `n`-th root of unity EXAMPLES:: diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index eda06a9fc2c..d6bcb664a49 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -237,7 +237,7 @@ cpdef inline split_complex_string(string, int base=10): cache = {} -def MPComplexField(prec=53, rnd="RNDNN", names=None): +def MPComplexField(prec=53, rnd='RNDNN', names=None): """ Return the complex field with real and imaginary parts having prec *bits* of precision. @@ -273,12 +273,12 @@ cdef class MPComplexField_class(Field): INPUT: - - ``prec`` -- (integer) precision; default = 53 + - ``prec`` -- integer (default: 53); precision prec is the number of bits used to represent the mantissa of both the real and imaginary part of complex floating-point number. - - ``rnd`` -- (string) the rounding mode; default = ``'RNDNN'`` + - ``rnd`` -- string (default: ``'RNDNN'``); the rounding mode Rounding mode is of the form ``'RNDxy'`` where ``x`` and ``y`` are the rounding mode for respectively the real and imaginary parts and @@ -333,7 +333,7 @@ cdef class MPComplexField_class(Field): cdef MPComplexNumber _new(self): """ - Return a new complex number with parent ``self`. + Return a new complex number with parent ``self``. """ cdef MPComplexNumber z z = MPComplexNumber.__new__(MPComplexNumber) @@ -582,7 +582,7 @@ cdef class MPComplexField_class(Field): cpdef bint is_exact(self) except -2: """ - Returns whether or not this field is exact, which is always ``False``. + Return whether or not this field is exact, which is always ``False``. EXAMPLES:: @@ -958,7 +958,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): def __hash__(self): """ - Returns the hash of ``self``, which coincides with the python + Return the hash of ``self``, which coincides with the python complex and float (and often int) types. This has the drawback that two very close high precision @@ -974,7 +974,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): def __getitem__(self, i): r""" - Returns either the real or imaginary component of ``self`` + Return either the real or imaginary component of ``self`` depending on the choice of ``i``: real (``i``=0), imaginary (``i``=1). INPUT: @@ -1064,7 +1064,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): - ``base`` -- (default: 10) base for output - ``**kwds`` -- other arguments to pass to the ``str()`` - method of the real numbers in the real and imaginary parts. + method of the real numbers in the real and imaginary parts EXAMPLES:: @@ -1561,7 +1561,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): EXAMPLES: This indeed acts as the square function when the imaginary - component of self is equal to zero:: + component of ``self`` is equal to zero:: sage: MPC = MPComplexField() sage: a = MPC(2,1) @@ -2103,7 +2103,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): cdef MPComplexNumber z, x x = self z = x._new() - mpc_mul_2si(z.value , x.value, n, (x._parent).__rnd) + mpc_mul_2si(z.value, x.value, n, (x._parent).__rnd) return z def __rshift__(self, n): @@ -2122,7 +2122,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): cdef MPComplexNumber z, x x = self z = x._new() - mpc_div_2si(z.value , x.value, n, (x._parent).__rnd) + mpc_div_2si(z.value, x.value, n, (x._parent).__rnd) return z def nth_root(self, n, all=False): @@ -2131,8 +2131,8 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all `n`-th roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all `n`-th roots EXAMPLES:: @@ -2227,11 +2227,11 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``self`` -- element of the upper half plane (if not, - raises a ``ValueError``). + - ``self`` -- element of the upper half plane (if not, + raises a :exc:`ValueError`) - - ``omit_frac`` -- (bool, default: ``False``), if ``True``, - omit the `e^{\pi i z / 12}` factor. + - ``omit_frac`` -- -- boolean (default: ``False``); if ``True``, + omit the `e^{\pi i z / 12}` factor OUTPUT: a complex number @@ -2289,7 +2289,6 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): -0.0013781309 + 0.0065198200*I sage: C(2).gamma_inc(1 + i) 0.70709210 - 0.42035364*I - """ return self._parent(self.__pari__().incgam(t, precision=self.prec())) @@ -2306,7 +2305,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): """ return self._parent(self.__pari__().zeta()) - def agm(self, right, algorithm="optimal"): + def agm(self, right, algorithm='optimal'): """ Return the algebro-geometric mean of ``self`` and ``right``. @@ -2315,11 +2314,11 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: MPC = MPComplexField() sage: u = MPC(1, 4) sage: v = MPC(-2,5) - sage: u.agm(v, algorithm="pari") + sage: u.agm(v, algorithm='pari') -0.410522769709397 + 4.60061063922097*I - sage: u.agm(v, algorithm="principal") + sage: u.agm(v, algorithm='principal') 1.24010691168158 - 0.472193567796433*I - sage: u.agm(v, algorithm="optimal") + sage: u.agm(v, algorithm='optimal') -0.410522769709397 + 4.60061063922097*I """ if algorithm == "pari": @@ -2425,7 +2424,6 @@ def __create__MPComplexField_version0 (prec, rnd): sage: sage.rings.complex_mpc.__create__MPComplexField_version0(200, 'RNDDZ') Complex Field with 200 bits of precision and rounding RNDDZ - """ return MPComplexField(prec, rnd) diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index 79c06af06d5..bec9978401e 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -29,7 +29,7 @@ AUTHORS: # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - +import re import weakref import sage.misc.misc @@ -41,8 +41,6 @@ from sage.structure.element cimport RingElement, Element from sage.structure.richcmp cimport rich_to_bool from sage.categories.map cimport Map -from sage.misc.sage_eval import sage_eval - import sage.rings.abc from sage.arith.constants cimport LOG_TEN_TWO_PLUS_EPSILON from sage.rings import infinity @@ -70,6 +68,10 @@ AA = None QQbar = None CDF = CLF = RLF = None +# useful for parsing +NUMBERS = re.compile("[0-9]") +BLOCK = re.compile(r'[+-]?(?:I\*|)[0-9\.]*(?:e[+-]?[0-9]*|)\*?I?') + def late_import(): """ @@ -496,10 +498,26 @@ class ComplexField_class(sage.rings.abc.ComplexField): sage: CC('1.2+3.4*j') 1.20000000000000 + 3.40000000000000*I + sage: CC("+4-13.59658451496887*I") + 4.00000000000000 - 13.5965845149689*I + sage: CC('1.2*I+3.4') + 3.40000000000000 + 1.20000000000000*I + sage: CC('1.2*I') + 1.20000000000000*I + sage: CC('9-I*1.2') + 9.00000000000000 - 1.20000000000000*I + sage: CC('3.4') + 3.40000000000000 + sage: CC('3.4e-6+7.8e11*I') + 3.40000000000000e-6 + 7.80000000000000e11*I sage: CC('hello') Traceback (most recent call last): ... ValueError: given string 'hello' is not a complex number + sage: CC('1+2+3*I') + Traceback (most recent call last): + ... + ValueError: given string '1+2+3*I' is not a complex number """ if not isinstance(x, (RealNumber, tuple)): if isinstance(x, ComplexDoubleElement): @@ -512,24 +530,35 @@ class ComplexField_class(sage.rings.abc.ComplexField): allowed = '+-.*0123456789Ie' if len(x) == 0 or not all(letter in allowed for letter in x): raise ValueError(f'given string {x!r} is not a complex number') - # This should rather use a proper parser to validate input. - # TODO: this is probably not the best and most - # efficient way to do this. -- Martin Albrecht - return ComplexNumber(self, - sage_eval(x, locals={"I": self.gen()})) + split = [group for group in BLOCK.findall(x) if group] + N = len(split) + if N == 1: + split = split[0] + real, imag = ('0', split) if 'I' in split else (split, '0') + elif N == 2: + real, imag = split + if 'I' in real: + real, imag = imag, real + else: + raise ValueError(f'given string {x!r} is not a complex number') + if not NUMBERS.search(imag): + imag = imag.replace('I', '1') + else: + imag = imag.replace('*', '').replace('I', '') + return ComplexNumber(self, real, imag) late_import() if isinstance(x, NumberFieldElement_quadratic): if isinstance(x.parent(), sage.rings.abc.NumberField_quadratic) and list(x.parent().polynomial()) == [1, 0, 1]: - (re, im) = list(x) - return ComplexNumber(self, re, im) + real, imag = list(x) + return ComplexNumber(self, real, imag) try: return self(x.sage()) except (AttributeError, TypeError): pass try: - return x._complex_mpfr_field_( self ) + return x._complex_mpfr_field_(self) except AttributeError: pass return ComplexNumber(self, x) @@ -718,9 +747,9 @@ class ComplexField_class(sage.rings.abc.ComplexField): True """ size = self._real_field()(component_max) - re = self._real_field().random_element(-size, size, *args, **kwds) - im = self._real_field().random_element(-size, size, *args, **kwds) - return self(re, im) + real = self._real_field().random_element(-size, size, *args, **kwds) + imag = self._real_field().random_element(-size, size, *args, **kwds) + return self(real, imag) def pi(self): r""" @@ -754,9 +783,9 @@ class ComplexField_class(sage.rings.abc.ComplexField): INPUT: - - ``n`` -- an integer (default: 2) + - ``n`` -- integer (default: 2) - OUTPUT: a complex `n`-th root of unity. + OUTPUT: a complex `n`-th root of unity EXAMPLES:: @@ -855,7 +884,6 @@ class ComplexField_class(sage.rings.abc.ComplexField): (x - I) * (x + I) sage: k._factor_univariate_polynomial(k(I) * (x^2 + 1)) (1.0000000000000000000000000000*I) * (x - I) * (x + I) - """ R = f.parent() @@ -890,7 +918,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): cdef ComplexNumber _new(self): """ - Quickly creates a new initialized complex number with the same + Quickly create a new initialized complex number with the same parent as ``self``. """ cdef ComplexNumber x @@ -953,8 +981,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): elif isinstance(real, pari_gen): real, imag = real.real(), real.imag() elif isinstance(real, (list, tuple)): - re, imag = real - real = re + real, imag = real elif isinstance(real, complex): real, imag = real.real, real.imag elif type(real) is gmpy2.mpc: @@ -1172,8 +1199,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def __getitem__(self, i): r""" - Return either the real or imaginary component of self depending on - the choice of i: real (i=0), imaginary (i=1) + Return either the real or imaginary component of ``self`` depending on + the choice of ``i``: real (``i=0``), imaginary (``i=1``). INPUT: @@ -1205,7 +1232,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def __reduce__(self): """ - Pickling support + Pickling support. EXAMPLES:: @@ -1230,7 +1257,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``n`` -- an integer which will define the multiplicative order + - ``n`` -- integer which will define the multiplicative order EXAMPLES:: @@ -1253,10 +1280,10 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): - ``base`` -- (default: 10) base for output - - ``istr`` -- (default: ``I``) String representation of the complex unit + - ``istr`` -- (default: ``I``) string representation of the complex unit - ``**kwds`` -- other arguments to pass to the ``str()`` - method of the real numbers in the real and imaginary parts. + method of the real numbers in the real and imaginary parts EXAMPLES:: @@ -1373,7 +1400,6 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: ComplexNumber(0).log()._latex_() '-\\infty' """ - import re s = repr(self).replace('*I', 'i').replace('infinity','\\infty') return re.sub(r"e(-?\d+)", r" \\times 10^{\1}", s) @@ -1460,9 +1486,9 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): if prec is not None: return ComplexField(prec)(self)._mpmath_() from sage.libs.mpmath.all import make_mpc - re = mpfr_to_mpfval(self.__re) - im = mpfr_to_mpfval(self.__im) - return make_mpc((re, im)) + real = mpfr_to_mpfval(self.__re) + imag = mpfr_to_mpfval(self.__im) + return make_mpc((real, imag)) def _sympy_(self): """ @@ -1836,7 +1862,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def __abs__(self): r""" - Method for computing the absolute value or modulus of ``self`` + Method for computing the absolute value or modulus of ``self``. .. MATH:: @@ -1891,10 +1917,10 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): mpfr_mul(t1, self.__im, self.__im, rnd) mpfr_add(t0, t0, t1, rnd) # now t0 is the norm - mpfr_div(x.__re, self.__re, t0, rnd) # x.__re = self.__re/norm + mpfr_div(x.__re, self.__re, t0, rnd) # x.__re = self.__re/norm mpfr_neg(t1, self.__im, rnd) - mpfr_div(x.__im, t1, t0, rnd) # x.__im = -self.__im/norm + mpfr_div(x.__im, t1, t0, rnd) # x.__im = -self.__im/norm mpfr_clear(t0) mpfr_clear(t1) @@ -2004,7 +2030,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def multiplicative_order(self): """ Return the multiplicative order of this complex number, if known, - or raise a :class:`NotImplementedError`. + or raise a :exc:`NotImplementedError`. EXAMPLES:: @@ -2050,7 +2076,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def plot(self, **kargs): """ - Plots this complex number as a point in the plane + Plots this complex number as a point in the plane. The accepted options are the ones of :meth:`~sage.plot.point.point2d`. Type ``point2d.options`` to see all options. @@ -2328,11 +2354,11 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``self`` -- element of the upper half plane (if not, - raises a :class:`ValueError`). + - ``self`` -- element of the upper half plane (if not, + raises a :exc:`ValueError`) - - ``omit_frac`` -- (bool, default: ``False``), if ``True``, - omit the `e^{\pi i z / 12}` factor. + - ``omit_frac`` -- -- boolean (default: ``False``); if ``True``, + omit the `e^{\pi i z / 12}` factor OUTPUT: a complex number @@ -2512,16 +2538,16 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): return z # Other special functions - def agm(self, right, algorithm="optimal"): + def agm(self, right, algorithm='optimal'): r""" Return the Arithmetic-Geometric Mean (AGM) of ``self`` and ``right``. INPUT: - - ``right`` (complex) -- another complex number + - ``right`` -- complex; another complex number - - ``algorithm`` (string, default ``"optimal"``) -- the algorithm to use - (see below). + - ``algorithm`` -- string (default: ``'optimal'``); the algorithm to use + (see below) OUTPUT: @@ -2529,15 +2555,15 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): this is a multi-valued function, and the algorithm used affects the value returned, as follows: - - ``"pari"``: Call the :pari:`agm` function from the PARI library. + - ``'pari'``: Call the :pari:`agm` function from the PARI library. - - ``"optimal"``: Use the AGM sequence such that at each stage + - ``'optimal'``: Use the AGM sequence such that at each stage `(a,b)` is replaced by `(a_1,b_1)=((a+b)/2,\pm\sqrt{ab})` where the sign is chosen so that `|a_1-b_1|\le|a_1+b_1|`, or equivalently `\Re(b_1/a_1)\ge 0`. The resulting limit is maximal among all possible values. - - ``"principal"``: Use the AGM sequence such that at each stage + - ``'principal'``: Use the AGM sequence such that at each stage `(a,b)` is replaced by `(a_1,b_1)=((a+b)/2,\pm\sqrt{ab})` where the sign is chosen so that `\Re(b_1)\ge 0` (the so-called principal branch of the square root). @@ -2550,11 +2576,11 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: b = CC(2,-1) sage: a.agm(b) 1.62780548487271 + 0.136827548397369*I - sage: a.agm(b, algorithm="optimal") + sage: a.agm(b, algorithm='optimal') 1.62780548487271 + 0.136827548397369*I - sage: a.agm(b, algorithm="principal") + sage: a.agm(b, algorithm='principal') 1.62780548487271 + 0.136827548397369*I - sage: a.agm(b, algorithm="pari") # needs sage.libs.pari + sage: a.agm(b, algorithm='pari') # needs sage.libs.pari 1.62780548487271 + 0.136827548397369*I An example to show that the returned value depends on the algorithm @@ -2562,17 +2588,17 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: a = CC(-0.95,-0.65) sage: b = CC(0.683,0.747) - sage: a.agm(b, algorithm="optimal") + sage: a.agm(b, algorithm='optimal') -0.371591652351761 + 0.319894660206830*I - sage: a.agm(b, algorithm="principal") + sage: a.agm(b, algorithm='principal') 0.338175462986180 - 0.0135326969565405*I - sage: a.agm(b, algorithm="pari") # needs sage.libs.pari + sage: a.agm(b, algorithm='pari') # needs sage.libs.pari -0.371591652351761 + 0.319894660206830*I - sage: a.agm(b, algorithm="optimal").abs() + sage: a.agm(b, algorithm='optimal').abs() 0.490319232466314 - sage: a.agm(b, algorithm="principal").abs() + sage: a.agm(b, algorithm='principal').abs() 0.338446122230459 - sage: a.agm(b, algorithm="pari").abs() # needs sage.libs.pari + sage: a.agm(b, algorithm='pari').abs() # needs sage.libs.pari 0.490319232466314 TESTS: @@ -2882,7 +2908,6 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: C = ComplexField(400) sage: C(2 + I).gamma_inc(C(3 + I)) # abs tol 1e-120 # needs sage.libs.pari 0.121515644664508695525971545977439666159749344176962379708992904126499444842886620664991650378432544392118359044438541515 + 0.101533909079826033296475736021224621546966200987295663190553587086145836461236284668967411665020429964946098113930918850*I - """ return self._parent(self.__pari__().incgam(t, precision=self.prec())) @@ -2967,8 +2992,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots EXAMPLES:: @@ -3036,8 +3061,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all `n`-th roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all `n`-th roots EXAMPLES:: @@ -3252,7 +3277,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): algdep = algebraic_dependency -def make_ComplexNumber0(fld, mult_order, re, im): +def make_ComplexNumber0(fld, mult_order, real, imag): """ Create a complex number for pickling. @@ -3262,7 +3287,7 @@ def make_ComplexNumber0(fld, mult_order, re, im): sage: loads(dumps(a)) == a # indirect doctest True """ - x = ComplexNumber(fld, re, im) + x = ComplexNumber(fld, real, imag) x._set_multiplicative_order(mult_order) return x @@ -3276,16 +3301,16 @@ def create_ComplexNumber(s_real, s_imag=None, int pad=0, min_prec=53): INPUT: - - ``s_real`` -- a string that defines a real number + - ``s_real`` -- string that defines a real number (or something whose string representation defines a number) - - ``s_imag`` -- a string that defines a real number + - ``s_imag`` -- string that defines a real number (or something whose string representation defines a number) - - ``pad`` -- an integer at least 0. + - ``pad`` -- integer at least 0 - ``min_prec`` -- number will have at least this many bits of precision, - no matter what. + no matter what EXAMPLES:: @@ -3317,7 +3342,6 @@ def create_ComplexNumber(s_real, s_imag=None, int pad=0, min_prec=53): False sage: sage.rings.complex_mpfr.create_ComplexNumber(0,s).imag()-1 == 0 False - """ if s_imag is None: s_imag = 0 @@ -3360,11 +3384,9 @@ cdef class RRtoCC(Map): INPUT: - - ``_slots`` -- a dictionary - - OUTPUT: + - ``_slots`` -- dictionary - The given dictionary, with zero added. + OUTPUT: the given dictionary, with zero added EXAMPLES:: @@ -3386,7 +3408,7 @@ cdef class RRtoCC(Map): INPUT: - - ``_slots`` -- a dictionary providing values for the c(p)def slots of self. + - ``_slots`` -- dictionary providing values for the c(p)def slots of ``self`` EXAMPLES:: @@ -3537,7 +3559,6 @@ def _format_complex_number(real, imag, format_spec): ... ValueError: '=' alignment not allowed in complex format specifier """ - import re match = re.match(r'^(.?[><=^])?' # 1: fill and align r'([ +-]?)' # 2: sign r'[^\d\.]*?0?(\d*)' # 3: width diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index c51b64261ab..e4825bf3b7e 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -265,7 +265,7 @@ def rat_interval_cf_list(r1, r2): Return the common prefix of the rationals ``r1`` and ``r2`` seen as continued fractions. - OUTPUT: a list of Sage integers. + OUTPUT: list of Sage integers EXAMPLES:: @@ -362,9 +362,9 @@ def str(self, nterms=10, unicode=False, join=True): - ``nterms`` -- the maximum number of terms to use - - ``unicode`` -- (default ``False``) whether to use unicode character + - ``unicode`` -- (default: ``False``) whether to use unicode character - - ``join`` -- (default ``True``) if ``False`` instead of returning a + - ``join`` -- (default: ``True``) if ``False`` instead of returning a string return a list of string, each of them representing a line EXAMPLES:: @@ -663,7 +663,7 @@ def _mpfr_(self, R): ....: fields.append(RealField(prec=prec, rnd=rnd)) sage: for n in range(3000): # long time, not tested, known bug (see :issue:`29957`) ....: a = QQ.random_element(num_bound=2^(n%100)) - ....: if a.denominator() % 8 == 0: # not precices enough # :issue:`29957` + ....: if a.denominator() % 8 == 0: # not precise enough # :issue:`29957` ....: continue ....: cf = continued_fraction(a) ....: for R in fields: @@ -823,7 +823,7 @@ def denominator(self, n): def convergent(self, n): """ - Return the ``n``-th partial convergent to self. + Return the ``n``-th partial convergent to ``self``. EXAMPLES:: @@ -1174,9 +1174,10 @@ def apply_homography(self, a, b, c, d, forward_value=False): - ``a``, ``b``, ``c``, ``d`` -- integers - - ``forward_value`` -- boolean (default: ``False``) whether the returned continued - fraction is given the symbolic value of `(a x + b)/(cx + d)` and not only the - list of partial quotients obtained from Gosper's algorithm. + - ``forward_value`` -- boolean (default: ``False``); whether the + returned continued fraction is given the symbolic value of + `(a x + b)/(cx + d)` and not only the list of partial quotients + obtained from Gosper's algorithm EXAMPLES:: @@ -1312,9 +1313,9 @@ def __init__(self, x1, x2=None, check=True): r""" INPUT: - - ``x1`` -- a tuple of integers + - ``x1`` -- tuple of integers - - ``x2`` -- a tuple of integers + - ``x2`` -- tuple of integers TESTS:: @@ -1840,7 +1841,7 @@ def __init__(self, x): def length(self): r""" - Return infinity + Return infinity. EXAMPLES:: @@ -2065,8 +2066,7 @@ def __init__(self, w, value=None, check=True): - ``value`` -- an optional known value - - ``check`` -- whether the constructor checks the input (default is - ``True``) + - ``check`` -- whether the constructor checks the input (default: ``True``) TESTS:: @@ -2077,11 +2077,11 @@ def __init__(self, w, value=None, check=True): ValueError: the sequence must consist of integers sage: from itertools import count - sage: w = Word(count(), length="infinite") # needs sage.combinat + sage: w = Word(count(), length='infinite') # needs sage.combinat sage: continued_fraction(w) # needs sage.combinat [0; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19...] - sage: w = Word(count(), length="unknown") # needs sage.combinat + sage: w = Word(count(), length='unknown') # needs sage.combinat sage: continued_fraction(w) # needs sage.combinat Traceback (most recent call last): ... @@ -2157,7 +2157,7 @@ def quotient(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2192,7 +2192,7 @@ def _Integer_quotient(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2333,7 +2333,7 @@ def check_and_reduce_pair(x1, x2=None): return tuple(y1), tuple(y2) -def continued_fraction_list(x, type="std", partial_convergents=False, +def continued_fraction_list(x, type='std', partial_convergents=False, bits=None, nterms=None): r""" Return the (finite) continued fraction of ``x`` as a list. @@ -2358,20 +2358,20 @@ def continued_fraction_list(x, type="std", partial_convergents=False, INPUT: - - ``x`` -- exact rational or floating-point number. The number to - compute the continued fraction of. + - ``x`` -- exact rational or floating-point number; the number to + compute the continued fraction of - - ``type`` -- either "std" (default) for standard continued fractions or - "hj" for Hirzebruch-Jung ones. + - ``type`` -- either ``'std'`` (default) for standard continued fractions or + ``'hj'`` for Hirzebruch-Jung ones - - ``partial_convergents`` -- boolean. Whether to return the - partial convergents. + - ``partial_convergents`` -- boolean; whether to return the + partial convergents - ``bits`` -- an optional integer that specify a precision for the real - interval field that is used internally. + interval field that is used internally - - ``nterms`` -- integer. The upper bound on the number of terms in - the continued fraction expansion to return. + - ``nterms`` -- integer; the upper bound on the number of terms in + the continued fraction expansion to return OUTPUT: @@ -2387,7 +2387,7 @@ def continued_fraction_list(x, type="std", partial_convergents=False, sage: 2 + 1/(2 + 1/(1 + 1/(2 + 1/2))) 45/19 - sage: continued_fraction_list(45/19, type="hj") + sage: continued_fraction_list(45/19, type='hj') [3, 2, 3, 2, 3] sage: 3 - 1/(2 - 1/(3 - 1/(2 - 1/3))) 45/19 diff --git a/src/sage/rings/continued_fraction_gosper.py b/src/sage/rings/continued_fraction_gosper.py index bb1a31178e5..619008df426 100644 --- a/src/sage/rings/continued_fraction_gosper.py +++ b/src/sage/rings/continued_fraction_gosper.py @@ -35,7 +35,8 @@ from sage.rings.infinity import Infinity from sage.rings.integer import Integer -class gosper_iterator(): + +class gosper_iterator: r""" Iterable for the partial quotients of `(a*x+b)/(c*x+d)`, where `a, b, c, d` are integers, and `x` is a continued fraction. diff --git a/src/sage/rings/convert/meson.build b/src/sage/rings/convert/meson.build new file mode 100644 index 00000000000..0b485247bf1 --- /dev/null +++ b/src/sage/rings/convert/meson.build @@ -0,0 +1,15 @@ +py.install_sources('all.py', 'mpfi.pxd', subdir: 'sage/rings/convert') + +extension_data = {'mpfi' : files('mpfi.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/convert', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cypari2, gmp, gsl, mpfi, mpfr, pari], + ) +endforeach + diff --git a/src/sage/rings/convert/mpfi.pyx b/src/sage/rings/convert/mpfi.pyx index 0d42927740a..803eed59146 100644 --- a/src/sage/rings/convert/mpfi.pyx +++ b/src/sage/rings/convert/mpfi.pyx @@ -52,16 +52,16 @@ cdef int mpfi_set_sage(mpfi_ptr re, mpfi_ptr im, x, field, int base) except -1: INPUT: - - ``re`` -- a pre-initialized MPFI interval. + - ``re`` -- a pre-initialized MPFI interval - - ``im`` -- a pre-initialized MPFI interval or NULL. + - ``im`` -- a pre-initialized MPFI interval or NULL - - ``x`` -- any Sage or Python object to be converted to an interval. + - ``x`` -- any Sage or Python object to be converted to an interval - ``field`` -- a ``RealIntervalField`` or ``ComplexIntervalField`` - of the right precision (real or complex doesn't matter). + of the right precision (real or complex doesn't matter) - - ``base`` -- base to use for string conversion. + - ``base`` -- base to use for string conversion OUTPUT: diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index 2702f497d66..b824e16e0d1 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -260,7 +260,6 @@ def __init__(self, domain, codomain, twist=None): Traceback (most recent call last): ... TypeError: the domain of the derivation must coerce to the domain of the twisting homomorphism - """ if domain not in Rings().Commutative(): raise TypeError("the domain must be a commutative ring") @@ -457,7 +456,6 @@ def __hash__(self): sage: M = R.derivation_module() sage: hash(M) == hash((M.domain(), M.codomain(), M.twisting_morphism())) True - """ return hash((self._domain, self._codomain, self._twist)) @@ -546,7 +544,6 @@ def domain(self): Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.domain() Multivariate Polynomial Ring in x, y over Integer Ring - """ return self._domain @@ -561,7 +558,6 @@ def codomain(self): Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.codomain() Multivariate Polynomial Ring in x, y over Integer Ring - """ return self._codomain @@ -592,7 +588,6 @@ def defining_morphism(self): From: Univariate Polynomial Ring in x over Rational Field To: Rational Field Defn: x |--> 0 - """ return self._defining_morphism @@ -616,7 +611,6 @@ def twisting_morphism(self): sage: M = R.derivation_module() sage: M.twisting_morphism() - """ return self._twist @@ -650,7 +644,6 @@ def ngens(self): 1 sage: M.gen() [x |--> y, y |--> x] - id - """ if self._gens is None: raise NotImplementedError("generators are not implemented for this derivation module") @@ -679,7 +672,6 @@ def gens(self): Ring in x, y over Integer Ring (twisting morphism: x |--> y, y |--> x) sage: M.gens() ([x |--> y, y |--> x] - id,) - """ if self._gens is None: raise NotImplementedError("generators are not implemented for this derivation module") @@ -687,11 +679,11 @@ def gens(self): def gen(self, n=0): r""" - Return the ``n``-th generator of this module of derivations. + Return the `n`-th generator of this module of derivations. INPUT: - - ``n`` -- an integer (default: ``0``) + - ``n`` -- integer (default: `0`) EXAMPLES:: @@ -720,7 +712,6 @@ def basis(self): sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy) - """ if self._basis is None: raise NotImplementedError("basis is not implemented for this derivation module") @@ -745,7 +736,6 @@ def dual_basis(self): Family (d/dx, d/dy) sage: M.dual_basis() Family (x, y) - """ if self._dual_basis is None: raise NotImplementedError("basis is not implemented for this derivation module") @@ -764,7 +754,6 @@ def ring_of_constants(self): Family (d/dx, d/dy) sage: M.ring_of_constants() Rational Field - """ if not self._constants[1]: raise NotImplementedError("the computation of the ring of constants" @@ -781,7 +770,6 @@ def random_element(self, *args, **kwds): sage: M = R.derivation_module() sage: M.random_element() # random (x^2 + x*y - 3*y^2 + x + 1)*d/dx + (-2*x^2 + 3*x*y + 10*y^2 + 2*x + 8)*d/dy - """ if self._gens is None: raise NotImplementedError("generators are not implemented for this derivation module") @@ -797,7 +785,6 @@ def some_elements(self): sage: M = R.derivation_module() sage: M.some_elements() [d/dx, d/dy, x*d/dx, x*d/dy, y*d/dx, y*d/dy] - """ if self._gens is None: return self.an_element() @@ -821,7 +808,6 @@ class RingDerivation(ModuleElement): d/dx + 2*d/dy sage: f(x*y) 2*x + y - """ def __call__(self, x): """ @@ -850,7 +836,6 @@ def domain(self): Multivariate Polynomial Ring in x, y over Rational Field sage: f.domain() is R True - """ return self.parent().domain() @@ -877,7 +862,6 @@ def codomain(self): Univariate Polynomial Ring in x over Rational Field sage: M.random_element().codomain() is S True - """ return self.parent().codomain() @@ -1008,7 +992,6 @@ def list(self): x*d/dx + y*d/dy sage: f.list() [x, y] - """ parent = self.parent() return [self(x) for x in parent.dual_basis()] @@ -1037,7 +1020,6 @@ def monomial_coefficients(self): x*d/dx + y*d/dy sage: f.monomial_coefficients() {0: x, 1: y} - """ dual_basis = self.parent().dual_basis() dict = { } @@ -1079,7 +1061,6 @@ def _richcmp_(self, other, op): x*d/dx + y*d/dy + z*d/dz sage: D.pth_power() == D True - """ if op == op_EQ: if isinstance(other, RingDerivationWithoutTwist): @@ -1128,7 +1109,6 @@ def _bracket_(self, other): sage: f = R.random_element() sage: X.bracket(f*Y) == X(f)*Y + f*X.bracket(Y) True - """ parent = self.parent() if parent.domain() is not parent.codomain(): @@ -1191,7 +1171,6 @@ def pth_power(self): sage: D.bracket(Dp) # needs sage.rings.finite_rings 0 - """ parent = self.parent() if parent.domain() is not parent.codomain(): @@ -1255,7 +1234,6 @@ def precompose(self, morphism): Traceback (most recent call last): ... TypeError: the given ring does not coerce to the domain of the derivation - """ parent = self.parent() if morphism in Rings().Commutative(): @@ -1313,7 +1291,6 @@ def postcompose(self, morphism): Traceback (most recent call last): ... TypeError: you must give a homomorphism of rings - """ parent = self.parent() if morphism in Rings().Commutative(): @@ -1380,7 +1357,6 @@ def __init__(self, parent, arg=None): True sage: TestSuite(der).run() - """ if isinstance(arg, list) and len(arg) == 1 and isinstance(arg[0], RingDerivation): arg = arg[0] @@ -1422,7 +1398,6 @@ def __hash__(self): sage: f = R.derivation(x) sage: hash(f) # random 3713081631936575706 - """ return hash(tuple(self.list())) @@ -1437,7 +1412,6 @@ def _add_(self, other): sage: Dy = R.derivation(y) sage: Dx + Dy d/dx + d/dy - """ return other @@ -1452,7 +1426,6 @@ def _sub_(self, other): sage: Dy = R.derivation(y) sage: Dx - Dy d/dx - d/dy - """ return -other @@ -1466,7 +1439,6 @@ def _neg_(self): sage: Dx = R.derivation(x) sage: -Dx -d/dx - """ return self @@ -1482,7 +1454,6 @@ def _lmul_(self, factor): 2*d/dx sage: Dx * x^2 x^2*d/dx - """ return self @@ -1498,7 +1469,6 @@ def _rmul_(self, left): 2*d/dx sage: x^2 * Dx x^2*d/dx - """ return self @@ -1512,7 +1482,6 @@ def _call_(self, x): sage: f = x*R.derivation(x) + y*R.derivation(y) sage: f(x^2 + 3*x*y - y^2) 2*x^2 + 6*x*y - 2*y^2 - """ return self.parent().codomain().zero() @@ -1528,7 +1497,6 @@ def _bracket_(self, other): sage: Dy = R.derivation(y) sage: Dx._bracket_(Dy) 0 - """ return self @@ -1541,7 +1509,6 @@ def is_zero(self): sage: M = QQ.derivation_module() sage: M().is_zero() True - """ return True @@ -1555,7 +1522,6 @@ def list(self): sage: M = QQ.derivation_module() sage: M().list() [] - """ return [] @@ -1583,7 +1549,6 @@ def __init__(self, parent, arg=None): sage: isinstance(der, RingDerivationWithoutTwist_wrapper) True sage: TestSuite(der).run() - """ if isinstance(arg, list) and len(arg) == 1 and isinstance(arg[0], RingDerivation): arg = arg[0] @@ -1603,7 +1568,6 @@ def __hash__(self): sage: f = R.derivation(x) sage: hash(f) # random 3713081631936575706 - """ return hash(tuple(self.list())) @@ -1620,7 +1584,6 @@ def _add_(self, other): sage: Dy = S.derivation(y) sage: Dx + Dy d/dx + d/dy - """ return type(self)(self.parent(), self._base_derivation + other._base_derivation) @@ -1637,7 +1600,6 @@ def _sub_(self, other): sage: Dy = S.derivation(y) sage: Dx - Dy d/dx - d/dy - """ return type(self)(self.parent(), self._base_derivation - other._base_derivation) @@ -1653,7 +1615,6 @@ def _neg_(self): sage: Dx = S.derivation(x) sage: -Dx -d/dx - """ return type(self)(self.parent(), -self._base_derivation) @@ -1671,7 +1632,6 @@ def _lmul_(self, factor): 2*d/dx sage: Dx * x^2 x^2*d/dx - """ return type(self)(self.parent(), self._base_derivation * factor) @@ -1689,7 +1649,6 @@ def _rmul_(self, factor): 2*d/dx sage: x^2 * Dx x^2*d/dx - """ return type(self)(self.parent(), factor * self._base_derivation) @@ -1714,7 +1673,6 @@ def list(self): x*d/dx + y*d/dy sage: f.list() [x, y] - """ return self._base_derivation.list() @@ -1739,7 +1697,6 @@ def __init__(self, parent, arg=None): d/dx + 2*d/dy sage: TestSuite(der).run() - """ domain = parent.domain() codomain = parent.codomain() @@ -1781,7 +1738,6 @@ def __hash__(self): sage: f = R.derivation(x) sage: hash(f) # random 3713081631936575706 - """ return hash(tuple(self.list())) @@ -1796,7 +1752,6 @@ def _add_(self, other): sage: Dy = R.derivation(y) sage: Dx + Dy d/dx + d/dy - """ base_derivation = self._base_derivation + other._base_derivation im = [ self._images[i] + other._images[i] for i in range(self.parent().domain().ngens()) ] @@ -1920,7 +1875,6 @@ def list(self): x*d/dx + y*d/dy sage: f.list() [x, y] - """ return self._base_derivation.list() + self._images @@ -1939,7 +1893,6 @@ def __hash__(self): sage: f = R.derivation(x) sage: hash(f) # random 3713081631936575706 - """ return hash(tuple(self.list())) @@ -1955,7 +1908,6 @@ def _call_(self, x): d/dx sage: f(1/x) (-1)/x^2 - """ defining_morphism = self.parent().defining_morphism() num = x.numerator() @@ -1981,7 +1933,6 @@ def __hash__(self): sage: f = R.derivation(x) sage: hash(f) # random 3713081631936575706 - """ return hash(tuple(self.list())) @@ -1998,7 +1949,6 @@ def _call_(self, x): x^3*d/dx sage: f(x^3) 0 - """ return self._base_derivation(x.lift()) @@ -2025,7 +1975,6 @@ def __init__(self, parent, scalar=0): sage: der = R.derivation(x, twist=theta) sage: TestSuite(der).run() - """ codomain = parent.codomain() self._scalar = codomain(scalar) @@ -2042,7 +1991,6 @@ def __hash__(self): sage: f = R.derivation(1, twist=theta) sage: hash(f) # random -6511057926760520014 - """ return hash(self._scalar) @@ -2233,7 +2181,6 @@ def list(self): (x + y)*(twisting_morphism - id) sage: f.list() [x + y] - """ return [ self._scalar ] @@ -2266,7 +2213,6 @@ def precompose(self, morphism): Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> y^3 y |--> x^2 - """ parent = self.parent() if morphism in Rings().Commutative(): @@ -2309,7 +2255,6 @@ def postcompose(self, morphism): Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> y^2 y |--> x^3 - """ parent = self.parent() if morphism in Rings().Commutative(): diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index 87f8d0c1072..f85d6c5f3da 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -41,9 +41,7 @@ cpdef aurifeuillian(n, m, F=None, bint check=True): - ``F`` -- integer (default: ``None``) - ``check`` -- boolean (default: ``True``) - OUTPUT: - - A list of factors. + OUTPUT: list of factors EXAMPLES:: @@ -127,9 +125,7 @@ cpdef factor_aurifeuillian(n, check=True): - ``n`` -- integer - OUTPUT: - - List of factors of `n` found by Aurifeuillian factorization. + OUTPUT: list of factors of `n` found by Aurifeuillian factorization EXAMPLES:: @@ -221,7 +217,7 @@ def factor_cunningham(m, proof=None): INPUT: - - ``proof`` -- bool (default: ``None``); whether or not to + - ``proof`` -- boolean (default: ``None``); whether or not to prove primality of each factor, this is only for factors not in the Cunningham table @@ -232,7 +228,6 @@ def factor_cunningham(m, proof=None): 535006138814359 * 1155685395246619182673033 * 374550598501810936581776630096313181393 sage: factor_cunningham((3^101+1)*(2^60).next_prime(), proof=False) # optional - cunningham_tables 2^2 * 379963 * 1152921504606847009 * 1017291527198723292208309354658785077827527 - """ from sage.databases import cunningham_tables cunningham_prime_factors = cunningham_tables.cunningham_prime_factors() @@ -259,7 +254,7 @@ cpdef factor_trial_division(m, long limit=LONG_MAX): INPUT: - - ``limit`` -- integer (default: ``LONG_MAX``) that fits in a C ``signed long`` + - ``limit`` -- integer (default: ``LONG_MAX``); that fits in a C ``signed long`` EXAMPLES:: @@ -277,7 +272,6 @@ cpdef factor_trial_division(m, long limit=LONG_MAX): sage: from sage.rings.factorint import factor_trial_division sage: list(factor_trial_division(8)) [(2, 3)] - """ cdef Integer n = PY_NEW(Integer), unit = PY_NEW(Integer), p = Integer(2) cdef long e diff --git a/src/sage/rings/factorint_flint.pyx b/src/sage/rings/factorint_flint.pyx index cc50af04a1c..69cd6ae8456 100644 --- a/src/sage/rings/factorint_flint.pyx +++ b/src/sage/rings/factorint_flint.pyx @@ -34,7 +34,7 @@ def factor_using_flint(Integer n): INPUT: - - ``n`` -- a nonzero sage Integer; the number to factor. + - ``n`` -- a nonzero sage Integer; the number to factor OUTPUT: diff --git a/src/sage/rings/factorint_pari.pyx b/src/sage/rings/factorint_pari.pyx index 8dae96b047f..a8d748c5845 100644 --- a/src/sage/rings/factorint_pari.pyx +++ b/src/sage/rings/factorint_pari.pyx @@ -41,9 +41,7 @@ def factor_using_pari(n, int_=False, debug_level=0, proof=None): required to be proven prime; if ``None``, the global default is used - OUTPUT: - - A list of pairs. + OUTPUT: list of pairs EXAMPLES:: diff --git a/src/sage/rings/fast_arith.pyx b/src/sage/rings/fast_arith.pyx index 4796122c1b6..2dafcbd701f 100644 --- a/src/sage/rings/fast_arith.pyx +++ b/src/sage/rings/fast_arith.pyx @@ -53,25 +53,25 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): INPUT: - - ``start`` -- integer, lower bound (default: 1) + - ``start`` -- integer; lower bound (default: 1) - - ``stop`` -- integer, upper bound + - ``stop`` -- integer; upper bound - - ``algorithm`` -- optional string (default: ``None``), one of: + - ``algorithm`` -- string (default: ``None``), one of: - - ``None``: Use algorithm ``"pari_primes"`` if ``stop`` <= 436273009 - (approximately 4.36E8). Otherwise use algorithm ``"pari_isprime"``. + - ``None``: Use algorithm ``'pari_primes'`` if ``stop`` <= 436273009 + (approximately 4.36E8). Otherwise use algorithm ``'pari_isprime'``. - - ``"pari_primes"``: Use PARI's :pari:`primes` function to generate all + - ``'pari_primes'``: Use PARI's :pari:`primes` function to generate all primes from 2 to stop. This is fast but may crash if there is insufficient memory. Raises an error if ``stop`` > 436273009. - - ``"pari_isprime"``: Wrapper for ``list(primes(start, stop))``. Each (odd) + - ``'pari_isprime'``: Wrapper for ``list(primes(start, stop))``. Each (odd) integer in the specified range is tested for primality by applying PARI's :pari:`isprime` function. This is slower but will work for much larger input. - - ``py_ints`` -- optional boolean (default ``False``), return Python ints rather - than Sage Integers (faster). Ignored unless algorithm ``"pari_primes"`` is being + - ``py_ints`` -- boolean (default: ``False``); return Python ints rather + than Sage Integers (faster). Ignored unless algorithm ``'pari_primes'`` is being used. EXAMPLES:: @@ -90,7 +90,7 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): [5, 7] sage: prime_range(-100,10,"pari_isprime") [2, 3, 5, 7] - sage: prime_range(2,2,algorithm="pari_isprime") + sage: prime_range(2,2,algorithm='pari_isprime') [] sage: prime_range(10**16,10**16+100,"pari_isprime") [10000000000000061, 10000000000000069, 10000000000000079, 10000000000000099] @@ -98,7 +98,7 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): [1000000000000000000000000000057, 1000000000000000000000000000099] sage: type(prime_range(8)[0]) - sage: type(prime_range(8,algorithm="pari_isprime")[0]) + sage: type(prime_range(8,algorithm='pari_isprime')[0]) .. NOTE:: @@ -134,7 +134,7 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): sage: prime_range(436273009, 436273010) [436273009] - sage: prime_range(436273009, 436273010, algorithm="pari_primes") + sage: prime_range(436273009, 436273010, algorithm='pari_primes') Traceback (most recent call last): ... ValueError: algorithm "pari_primes" is limited to primes larger than 436273008 diff --git a/src/sage/rings/finite_rings/conway_polynomials.py b/src/sage/rings/finite_rings/conway_polynomials.py index 7d6e558f030..ff5873ee14b 100644 --- a/src/sage/rings/finite_rings/conway_polynomials.py +++ b/src/sage/rings/finite_rings/conway_polynomials.py @@ -24,7 +24,7 @@ def conway_polynomial(p, n): Return the Conway polynomial of degree `n` over ``GF(p)``. If the requested polynomial is not known, this function raises a - ``RuntimeError`` exception. + :exc:`RuntimeError` exception. INPUT: @@ -199,9 +199,7 @@ def polynomial(self, n): - ``n`` -- positive integer - OUTPUT: - - - a pseudo-Conway polynomial of degree `n` for the prime `p`. + OUTPUT: a pseudo-Conway polynomial of degree `n` for the prime `p` ALGORITHM: @@ -305,14 +303,11 @@ def _find_pow_of_frobenius(p, n, x, y): - ``n`` -- positive integer - ``x`` -- an element of a field `K` of `p^n` elements so that - the multiplicative order of `x` is `p^n - 1`. - - - ``y`` -- an element of `K` with the same minimal polynomial as - `x`. + the multiplicative order of `x` is `p^n - 1` - OUTPUT: + - ``y`` -- an element of `K` with the same minimal polynomial as `x` - - an element `i` of the integers modulo `n` such that `x = y^{p^i}`. + OUTPUT: an element `i` of the integers modulo `n` such that `x = y^{p^i}` EXAMPLES:: @@ -323,7 +318,6 @@ def _find_pow_of_frobenius(p, n, x, y): sage: y = x^27 sage: _find_pow_of_frobenius(3, 14, x, y) 11 - """ from .integer_mod import mod for i in range(n): @@ -350,7 +344,6 @@ def _crt_non_coprime(running, a): Traceback (most recent call last): ... AssertionError - """ g = running.modulus().gcd(a.modulus()) if g == 1: @@ -387,12 +380,12 @@ def _frobenius_shift(K, generators, check_only=False): - ``K`` -- a finite field of degree `n` over its prime field - - ``generators`` -- a dictionary, indexed by prime divisors `q` of + - ``generators`` -- dictionary, indexed by prime divisors `q` of `n`, whose entries are elements of `K` satisfying the `n/q` - pseudo-Conway polynomial. + pseudo-Conway polynomial - ``check_only`` -- if ``True``, just check that the given - generators form a compatible system. + generators form a compatible system EXAMPLES:: @@ -414,7 +407,6 @@ def _frobenius_shift(K, generators, check_only=False): 13 sage: _find_pow_of_frobenius(2, 12, x12, generators[5]) 8 - """ if len(generators) == 1: return generators @@ -433,7 +425,7 @@ def _frobenius_shift(K, generators, check_only=False): q, x = compatible[m].popitem() except KeyError: break - for qq, xx in compatible[m].items(): + for xx in compatible[m].values(): assert x == xx return crt = {} diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index 18b0db173b5..aa0a66b4748 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -24,6 +24,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from sage.misc.superseded import deprecated_function_alias + def is_FiniteFieldElement(x): """ Return ``True`` if ``x`` is a finite field element. @@ -53,8 +54,8 @@ cdef class FiniteRingElement(CommutativeRingElement): def _nth_root_common(self, n, all, algorithm, cunningham): """ This function exists to reduce code duplication between finite field - nth roots and integer_mod nth roots. It assumes that `self` is a field - element. + `n`-th roots and ``integer_mod`` `n`-th roots. It assumes that ``self`` + is a field element. The inputs are described there. @@ -142,7 +143,7 @@ cdef class FiniteRingElement(CommutativeRingElement): else: raise ValueError("unknown algorithm") - def to_bytes(self, byteorder="big"): + def to_bytes(self, byteorder='big'): r""" Return an array of bytes representing an integer. @@ -151,8 +152,8 @@ cdef class FiniteRingElement(CommutativeRingElement): INPUT: - - ``byteorder`` -- str (default: ``"big"``); determines the byte order of - ``input_bytes``; can only be ``"big"`` or ``"little"`` + - ``byteorder`` -- string (default: ``'big'``); determines the byte order of + ``input_bytes``; can only be ``'big'`` or ``'little'`` EXAMPLES:: @@ -160,7 +161,7 @@ cdef class FiniteRingElement(CommutativeRingElement): sage: a = F(8726) sage: a.to_bytes() b'\x00"\x16' - sage: a.to_bytes(byteorder="little") + sage: a.to_bytes(byteorder='little') b'\x16"\x00' """ length = (self.parent().order().nbits() + 7) // 8 @@ -203,18 +204,18 @@ cdef class FinitePolyExtElement(FiniteRingElement): def minpoly(self,var='x',algorithm='pari'): """ - Returns the minimal polynomial of this element + Return the minimal polynomial of this element (over the corresponding prime subfield). INPUT: - - ``var`` -- string (default: 'x') + - ``var`` -- string (default: ``'x'``) - - ``algorithm`` -- string (default: 'pari') + - ``algorithm`` -- string (default: ``'pari'``): - - 'pari' -- use pari's minpoly + - ``'pari'`` -- use pari's minpoly - - 'matrix' -- return the minpoly computed from the matrix of + - ``'matrix'`` -- return the minpoly computed from the matrix of left multiplication by self EXAMPLES:: @@ -224,8 +225,8 @@ cdef class FinitePolyExtElement(FiniteRingElement): sage: parent(a) Finite Field in a of size 19^2 sage: b=a**20 - sage: p=FinitePolyExtElement.minpoly(b,"x", algorithm="pari") - sage: q=FinitePolyExtElement.minpoly(b,"x", algorithm="matrix") + sage: p=FinitePolyExtElement.minpoly(b,"x", algorithm='pari') + sage: q=FinitePolyExtElement.minpoly(b,"x", algorithm='matrix') sage: q == p True sage: p @@ -249,7 +250,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): # for compatibility with sage.matrix def minimal_polynomial(self, var='x'): """ - Returns the minimal polynomial of this element + Return the minimal polynomial of this element (over the corresponding prime subfield). EXAMPLES:: @@ -268,7 +269,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): def __getitem__(self, n): r""" - Return the `n`\th coefficient of this finite field element when + Return the `n`-th coefficient of this finite field element when written as a polynomial in the generator. EXAMPLES:: @@ -408,7 +409,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): INPUT: - ``reverse`` -- reverse the order of the bits - from little endian to big endian. + from little endian to big endian EXAMPLES:: @@ -455,7 +456,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): INPUT: - - ``reverse`` -- if True, act on vectors in reversed order + - ``reverse`` -- if ``True``, act on vectors in reversed order EXAMPLES:: @@ -488,8 +489,8 @@ cdef class FinitePolyExtElement(FiniteRingElement): def _latex_(self): r""" - Return the latex representation of self, which is just the - latex representation of the polynomial representation of self. + Return the latex representation of ``self``, which is just the + latex representation of the polynomial representation of ``self``. EXAMPLES:: @@ -545,7 +546,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): INPUT: - - ``var`` -- (default: ``None``); a string for a new variable name to use. + - ``var`` -- (default: ``None``) a string for a new variable name to use EXAMPLES:: @@ -590,9 +591,9 @@ cdef class FinitePolyExtElement(FiniteRingElement): INPUT: - - ``var`` -- string (default: 'x') + - ``var`` -- string (default: ``'x'``) - - ``algorithm`` -- string (default: ``'pari'``) + - ``algorithm`` -- string (default: ``'pari'``): - ``'pari'`` -- use pari's charpoly @@ -608,8 +609,8 @@ cdef class FinitePolyExtElement(FiniteRingElement): sage: parent(a) Finite Field in a of size 19^2 sage: b = a**20 - sage: p = FinitePolyExtElement.charpoly(b, "x", algorithm="pari") - sage: q = FinitePolyExtElement.charpoly(b, "x", algorithm="matrix") # needs sage.modules + sage: p = FinitePolyExtElement.charpoly(b, "x", algorithm='pari') + sage: q = FinitePolyExtElement.charpoly(b, "x", algorithm='matrix') # needs sage.modules sage: q == p # needs sage.modules True sage: p @@ -630,9 +631,9 @@ cdef class FinitePolyExtElement(FiniteRingElement): def norm(self): """ - Return the norm of self down to the prime subfield. + Return the norm of ``self`` down to the prime subfield. - This is the product of the Galois conjugates of self. + This is the product of the Galois conjugates of ``self``. EXAMPLES:: @@ -736,7 +737,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): def is_square(self): """ - Returns ``True`` if and only if this element is a perfect square. + Return ``True`` if and only if this element is a perfect square. EXAMPLES:: @@ -772,17 +773,16 @@ cdef class FinitePolyExtElement(FiniteRingElement): INPUT: - - - ``extend`` -- bool (default: ``True``); if ``True``, return a - square root in an extension ring, if necessary. Otherwise, raise a - ValueError if the root is not in the base ring. + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the root is not in the base ring. .. WARNING:: This option is not implemented! - - ``all`` -- bool (default: ``False``); if ``True``, return all - square roots of ``self``, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of ``self``, instead of just one .. WARNING:: @@ -824,31 +824,31 @@ cdef class FinitePolyExtElement(FiniteRingElement): def nth_root(self, n, extend = False, all = False, algorithm=None, cunningham=False): r""" - Returns an `n`\th root of ``self``. + Return an `n`-th root of ``self``. INPUT: - ``n`` -- integer `\geq 1` - - ``extend`` -- bool (default: ``False``); if ``True``, return an `n`\th - root in an extension ring, if necessary. Otherwise, raise a - ValueError if the root is not in the base ring. Warning: + - ``extend`` -- boolean (default: ``False``); if ``True``, return an + `n`-th root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the root is not in the base ring. Warning: this option is not implemented! - - ``all`` -- bool (default: ``False``); if ``True``, return all `n`\th - roots of ``self``, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all `n`-th + roots of ``self``, instead of just one - - ``algorithm`` -- string (default: ``None``); 'Johnston' is the only - currently supported option. For IntegerMod elements, the problem + - ``algorithm`` -- string (default: ``None``); ``'Johnston'`` is the + only currently supported option. For IntegerMod elements, the problem is reduced to the prime modulus case using CRT and `p`-adic logs, and then this algorithm used. OUTPUT: - If self has an `n`\th root, returns one (if ``all`` is ``False``) or a + If ``self`` has an `n`-th root, returns one (if ``all`` is ``False``) or a list of all of them (if ``all`` is ``True``). - Otherwise, raises a ``ValueError`` (if ``extend`` is ``False``) - or a ``NotImplementedError`` (if ``extend`` is ``True``). + Otherwise, raises a :exc:`ValueError` (if ``extend`` is ``False``) + or a :exc:`NotImplementedError` (if ``extend`` is ``True``). .. warning:: @@ -943,7 +943,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): def pth_power(self, int k = 1): """ - Return the `(p^k)^{th}` power of self, where `p` is the + Return the `(p^k)`-th power of self, where `p` is the characteristic of the field. INPUT: @@ -977,7 +977,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): def pth_root(self, int k = 1): """ - Return the `(p^k)^{th}` root of self, where `p` is the characteristic + Return the `(p^k)`-th root of self, where `p` is the characteristic of the field. INPUT: @@ -1106,7 +1106,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): integer_representation = deprecated_function_alias(33941, to_integer) - def to_bytes(self, byteorder="big"): + def to_bytes(self, byteorder='big'): r""" Return an array of bytes representing an integer. @@ -1115,8 +1115,8 @@ cdef class FinitePolyExtElement(FiniteRingElement): INPUT: - - ``byteorder`` -- str (default: ``"big"``); determines the byte order of - the output; can only be ``"big"`` or ``"little"`` + - ``byteorder`` -- string (default: ``'big'``); determines the byte order of + the output; can only be ``'big'`` or ``'little'`` EXAMPLES:: diff --git a/src/sage/rings/finite_rings/element_givaro.pyx b/src/sage/rings/finite_rings/element_givaro.pyx index 401f398ddee..bb5a9f6b376 100644 --- a/src/sage/rings/finite_rings/element_givaro.pyx +++ b/src/sage/rings/finite_rings/element_givaro.pyx @@ -106,7 +106,7 @@ cdef void late_import() noexcept: cdef class Cache_givaro(Cache_base): - def __init__(self, parent, unsigned int p, unsigned int k, modulus, repr="poly", cache=False): + def __init__(self, parent, unsigned int p, unsigned int k, modulus, repr='poly', cache=False): """ Finite Field. @@ -120,24 +120,22 @@ cdef class Cache_givaro(Cache_base): - ``name`` -- variable used for poly_repr (default: ``'a'``) - - ``modulus`` -- a polynomial to use as modulus. + - ``modulus`` -- a polynomial to use as modulus - - ``repr`` -- (default: 'poly') controls the way elements are printed + - ``repr`` -- (default: ``'poly'``) controls the way elements are printed to the user: - 'log': repr is :meth:`~FiniteField_givaroElement.log_repr()` - 'int': repr is :meth:`~FiniteField_givaroElement.int_repr()` - 'poly': repr is :meth:`~FiniteField_givaroElement.poly_repr()` - - ``cache`` -- (default: ``False``) if ``True`` a cache of all + - ``cache`` -- boolean (default: ``False``); if ``True`` a cache of all elements of this field is created. Thus, arithmetic does not create new elements which speeds calculations up. Also, if many elements are needed during a calculation this cache reduces the memory requirement as at most :meth:`order()` elements are created. - OUTPUT: - - Givaro finite field with characteristic `p` and cardinality `p^n`. + OUTPUT: Givaro finite field with characteristic `p` and cardinality `p^n` EXAMPLES: @@ -301,7 +299,7 @@ cdef class Cache_givaro(Cache_base): INPUT: - - ``e`` -- data to coerce in. + - ``e`` -- data to coerce in EXAMPLES:: @@ -497,9 +495,7 @@ cdef class Cache_givaro(Cache_base): - ``n`` -- log representation of a finite field element - OUTPUT: - - integer representation of a finite field element. + OUTPUT: integer representation of a finite field element EXAMPLES:: @@ -530,9 +526,7 @@ cdef class Cache_givaro(Cache_base): - ``n`` -- integer representation of a finite field element - OUTPUT: - - log representation of ``n`` + OUTPUT: log representation of ``n`` EXAMPLES:: @@ -847,7 +841,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def __init__(FiniteField_givaroElement self, parent): """ - Initializes an element in parent. It's much better to use + Initialize an element in parent. It's much better to use parent() or any specialized method of parent like gen() instead. In general do not call this constructor directly. @@ -860,9 +854,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): - ``parent`` -- base field - OUTPUT: - - A finite field element. + OUTPUT: a finite field element EXAMPLES:: @@ -870,7 +862,6 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: from sage.rings.finite_rings.element_givaro import FiniteField_givaroElement sage: FiniteField_givaroElement(k) 0 - """ FinitePolyExtElement.__init__(self, parent) self._cache = parent._cache @@ -944,7 +935,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def is_unit(FiniteField_givaroElement self): """ - Return ``True`` if self is nonzero, so it is a unit as an element of + Return ``True`` if ``self`` is nonzero, so it is a unit as an element of the finite field. EXAMPLES:: @@ -964,7 +955,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def is_square(FiniteField_givaroElement self): """ - Return ``True`` if ``self`` is a square in ``self.parent()`` + Return ``True`` if ``self`` is a square in ``self.parent()``. ALGORITHM: @@ -1006,20 +997,20 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def sqrt(FiniteField_givaroElement self, extend=False, all=False): """ Return a square root of this finite field element in its - parent, if there is one. Otherwise, raise a ``ValueError``. + parent, if there is one. Otherwise, raise a :exc:`ValueError`. INPUT: - - ``extend`` -- bool (default: ``True``); if ``True``, return a + - ``extend`` -- boolean (default: ``True``); if ``True``, return a square root in an extension ring, if necessary. Otherwise, - raise a ``ValueError`` if the root is not in the base ring. + raise a :exc:`ValueError` if the root is not in the base ring. .. WARNING:: this option is not implemented! - - ``all`` -- bool (default: ``False``); if ``True``, return all square - roots of ``self``, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of ``self``, instead of just one .. WARNING:: @@ -1061,7 +1052,6 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: K. = FiniteField(9) sage: a.sqrt(extend = False, all = True) [] - """ if all: if self.is_square(): @@ -1114,7 +1104,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): cpdef _div_(self, right): """ - Divide two elements + Divide two elements. EXAMPLES:: @@ -1191,7 +1181,6 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): Traceback (most recent call last): ... ZeroDivisionError: division by zero in finite field - """ cdef int r = 0 if self.element == 0: @@ -1333,7 +1322,6 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): Traceback (most recent call last): ... TypeError: Cannot coerce element to an integer. - """ cdef int self_int = self._cache.log_to_int(self.element) if self_int % self._cache.characteristic() != self_int: @@ -1350,7 +1338,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): `e = a_0 + a_1 x + a_2 x^2 + \cdots`, the integer representation is `a_0 + a_1 p + a_2 p^2 + \cdots`. - OUTPUT: A Python ``int``. + OUTPUT: a Python ``int`` .. SEEALSO:: @@ -1411,11 +1399,18 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): """ return Integer(self._cache.log_to_int(self.element)) - def log(FiniteField_givaroElement self, base): + def log(FiniteField_givaroElement self, base, order=None, *, check=False): """ Return the log to the base `b` of ``self``, i.e., an integer `n` such that `b^n =` ``self``. + INPUT: + + - ``base`` -- non-zero field element + - ``order`` -- integer (optional), multiple of order of ``base`` + - ``check`` -- boolean (default: ``False``): If set, + test whether the given ``order`` is correct. + .. WARNING:: TODO -- This is currently implemented by solving the discrete @@ -1429,9 +1424,22 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: a = b^7 sage: a.log(b) 7 + + TESTS: + + An example for ``check=True``:: + + sage: F. = GF(3^5, impl='givaro') + sage: t.log(t, 3^4, check=True) + Traceback (most recent call last): + ... + ValueError: 81 is not a multiple of the order of the base """ b = self.parent()(base) - return sage.groups.generic.discrete_log(self, b) + if (order is not None) and check and not (b**order).is_one(): + raise ValueError(f"{order} is not a multiple of the order of the base") + + return sage.groups.generic.discrete_log(self, b, ord=order) def _int_repr(FiniteField_givaroElement self): r""" @@ -1478,7 +1486,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def polynomial(FiniteField_givaroElement self, name=None): """ - Return self viewed as a polynomial over + Return ``self`` viewed as a polynomial over ``self.parent().prime_subfield()``. EXAMPLES:: @@ -1509,7 +1517,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def _magma_init_(self, magma): """ - Return a string representation of self that MAGMA can + Return a string representation of ``self`` that MAGMA can understand. EXAMPLES:: @@ -1618,8 +1626,8 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): Return a string that evaluates to the GAP representation of this element. - A ``NotImplementedError`` is raised if ``self.parent().modulus()`` is - not a Conway polynomial, as the isomorphism of finite fields is + A :exc:`NotImplementedError` is raised if ``self.parent().modulus()`` + is not a Conway polynomial, as the isomorphism of finite fields is not implemented yet. EXAMPLES:: @@ -1674,7 +1682,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): INPUT: - ``reverse`` -- reverse the order of the bits from little endian to - big endian. + big endian EXAMPLES:: @@ -1729,6 +1737,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): """ return unpickle_FiniteField_givaroElement,(self.parent(),self.element) + def unpickle_FiniteField_givaroElement(parent, int x): """ TESTS:: diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index 32ffd192353..2c1c25254c4 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -144,7 +144,7 @@ cdef class Cache_ntl_gf2e(Cache_base): TESTS:: - sage: k. = GF(2^8, impl="ntl") + sage: k. = GF(2^8, impl='ntl') """ self._parent = parent self._zero_element = self._new() @@ -262,10 +262,10 @@ cdef class Cache_ntl_gf2e(Cache_base): We can coerce from PARI finite field implementations:: - sage: K. = GF(2^19, impl="ntl") + sage: K. = GF(2^19, impl='ntl') sage: a^20 a^6 + a^3 + a^2 + a - sage: M. = GF(2^19, impl="pari_ffelt") + sage: M. = GF(2^19, impl='pari_ffelt') sage: K(c^20) a^6 + a^3 + a^2 + a """ @@ -386,7 +386,7 @@ cdef class Cache_ntl_gf2e(Cache_base): INPUT: - - ``number`` -- an integer, of size less than the cardinality + - ``number`` -- integer; of size less than the cardinality EXAMPLES:: @@ -436,12 +436,12 @@ cdef class Cache_ntl_gf2e(Cache_base): def polynomial(self): """ - Returns the list of 0's and 1's giving the defining polynomial of the + Return the list of 0s and 1s giving the defining polynomial of the field. EXAMPLES:: - sage: k. = GF(2^20,modulus="minimal_weight") + sage: k. = GF(2^20,modulus='minimal_weight') sage: k._cache.polynomial() [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] """ @@ -471,7 +471,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): def __init__(FiniteField_ntl_gf2eElement self, parent=None ): """ - Initializes an element in parent. It's much better to use + Initialize an element in parent. It's much better to use parent() or any specialized method of parent (one,zero,gen) instead. Do not call this constructor directly, it doesn't make much sense. @@ -480,9 +480,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): - ``parent`` -- base field - OUTPUT: - - A finite field element. + OUTPUT: a finite field element EXAMPLES:: @@ -499,11 +497,11 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): def __cinit__(FiniteField_ntl_gf2eElement self, parent=None ): """ - Restores the cache and constructs the underlying NTL element. + Restore the cache and construct the underlying NTL element. EXAMPLES:: - sage: k. = GF(2^8, impl="ntl") # indirect doctest + sage: k. = GF(2^8, impl='ntl') # indirect doctest """ if parent is None: return @@ -588,7 +586,6 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): False sage: k(1).is_one() True - """ (self._parent._cache).F.restore() return self.x == self._cache._one_element.x @@ -647,7 +644,6 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): sage: GF(2^16,'a')(1).sqrt() 1 - """ # this really should be handled special, its gf2 linear after # all @@ -898,7 +894,6 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): Traceback (most recent call last): ... TypeError: Cannot coerce element to an integer. - """ if self == 0: return int(0) @@ -999,13 +994,11 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): - ``var`` -- string (default: ``'x'``) - OUTPUT: - - polynomial + OUTPUT: polynomial EXAMPLES:: - sage: k. = GF(2^8, impl="ntl") + sage: k. = GF(2^8, impl='ntl') sage: b = a^3 + a sage: b.minpoly() x^4 + x^3 + x^2 + x + 1 @@ -1021,7 +1014,6 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): cdef int pow = n/d return f if pow == 1 else f**pow - def minpoly(self, var='x'): r""" Return the minimal polynomial of ``self``, which is the smallest @@ -1031,9 +1023,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): - ``var`` -- string (default: ``'x'``) - OUTPUT: - - polynomial + OUTPUT: polynomial EXAMPLES:: @@ -1081,7 +1071,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): def weight(self): """ - Returns the number of non-zero coefficients in the polynomial + Return the number of nonzero coefficients in the polynomial representation of ``self``. EXAMPLES:: @@ -1146,7 +1136,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): Return a string that evaluates to the GAP representation of this element. - A ``NotImplementedError`` is raised if + A :exc:`NotImplementedError` is raised if ``self.parent().modulus()`` is not a Conway polynomial, as the isomorphism of finite fields is not implemented yet. @@ -1194,7 +1184,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): INPUT: - ``reverse`` -- reverse the order of the bits from little endian to - big endian. + big endian EXAMPLES:: @@ -1234,7 +1224,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): """ return unpickleFiniteField_ntl_gf2eElement, (self._parent, str(self)) - def log(self, base): + def log(self, base, order=None, *, check=False): """ Compute an integer `x` such that `b^x = a`, where `a` is ``self`` and `b` is ``base``. @@ -1242,11 +1232,14 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): INPUT: - ``base`` -- finite field element + - ``order`` -- integer (optional), the order of the base + - ``check`` -- boolean (default: ``False``): If set, + test whether the given ``order`` is correct. OUTPUT: Integer `x` such that `a^x = b`, if it exists. - Raises a ``ValueError`` exception if no such `x` exists. + Raises a :exc:`ValueError` exception if no such `x` exists. ALGORITHM: :pari:`fflog` @@ -1279,16 +1272,34 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): ... ValueError: no logarithm of z50 exists to base z50^49 + z50^46 + z50^45 + z50^44 + z50^41 + z50^34 + z50^33 + z50^32 + z50^27 + z50^25 + z50^24 + z50^21 + z50^18 + z50^17 + z50^16 + z50^15 + z50^12 + z50^11 + z50^10 + z50^8 + z50^7 + z50^3 + z50^2 + An example for ``check=True``:: + + sage: F. = GF(2^5, impl='ntl') + sage: t.log(t, 3^4, check=True) + Traceback (most recent call last): + ... + ValueError: base does not have the provided order + AUTHORS: - David Joyner and William Stein (2005-11) - Lorenz Panny (2021-11): use PARI's :pari:`fflog` instead of :func:`sage.groups.generic.discrete_log` """ + cdef Integer base_order + base = self.parent()(base) # The result is undefined if the input to fflog() is invalid. # Since the unit group is cyclic, it suffices to check orders. - cdef Integer base_order = base.multiplicative_order() + if order is None: + base_order = base.multiplicative_order() + else: + if check: + from sage.groups.generic import has_order + if not has_order(base, order, '*'): + raise ValueError('base does not have the provided order') + base_order = order + cdef Integer self_order = self.multiplicative_order() if not self_order.divides(base_order): raise ValueError(f'no logarithm of {self} exists to base {base}') @@ -1302,6 +1313,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): x = pari.fflog(self, base, (base_order, fac)) return Integer(x) + def unpickleFiniteField_ntl_gf2eElement(parent, elem): """ EXAMPLES:: diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index c7f286bcbeb..3c92e26d679 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -54,7 +54,6 @@ cdef GEN _INT_to_FFELT(GEN g, GEN x) except NULL: sage: F. = GF(p^2) sage: x * 2^63 9223372036854775808*x - """ cdef GEN f, p = gel(g, 4), result cdef long t @@ -381,7 +380,6 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): sage: R = [r[0] for r in pol.roots()] sage: prod(Fq_X.gen() - r for r in R) == pol True - """ cdef GEN f, g, result, x_GEN cdef long i, n, t @@ -756,7 +754,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): def is_unit(self): """ - Return ``True`` if ``self`` is non-zero. + Return ``True`` if ``self`` is nonzero. EXAMPLES:: @@ -849,7 +847,6 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): exponent to an integer. This means that ``a^Mod(1, n)`` returns `a` even if `n` is not a multiple of the multiplicative order of `a`. - """ if exp == 0: return self._parent.one() @@ -863,7 +860,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): def pth_power(FiniteFieldElement_pari_ffelt self, int k=1): r""" - Return the `(p^k)^{th}` power of ``self``, where `p` is the + Return the `(p^k)`-th power of ``self``, where `p` is the characteristic of the field. INPUT: @@ -960,7 +957,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): INPUT: - - ``var`` -- string (default: 'x'): variable name to use. + - ``var`` -- string (default: ``'x'``); variable name to use EXAMPLES:: @@ -979,7 +976,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): INPUT: - - ``var`` -- string (default: 'x'): variable name to use. + - ``var`` -- string (default: ``'x'``); variable name to use EXAMPLES:: @@ -1029,13 +1026,13 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): INPUT: - - ``extend`` -- bool (default: ``False``) + - ``extend`` -- boolean (default: ``False``) .. WARNING:: This option is not implemented. - - ``all`` -- bool (default: ``False``) + - ``all`` -- boolean (default: ``False``) OUTPUT: @@ -1045,7 +1042,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): If ``extend`` is ``True``, a square root is chosen in an extension field if necessary. If ``extend`` is ``False``, a - :class:`ValueError` is raised if the element is not a square in the + :exc:`ValueError` is raised if the element is not a square in the base field. .. WARNING:: @@ -1107,15 +1104,15 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): INPUT: - - ``base`` -- non-zero field element + - ``base`` -- nonzero field element - ``order`` -- integer (optional), the order of the base - - ``check`` -- boolean (default: ``False``): If set, - test whether the given ``order`` is correct. + - ``check`` -- boolean (default: ``False``); if set, + test whether the given ``order`` is correct OUTPUT: An integer `x` such that ``self`` equals ``base`` raised to - the power `x`. If no such `x` exists, a ``ValueError`` is + the power `x`. If no such `x` exists, a :exc:`ValueError` is raised. EXAMPLES:: @@ -1211,7 +1208,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): def multiplicative_order(self): """ - Returns the order of ``self`` in the multiplicative group. + Return the order of ``self`` in the multiplicative group. EXAMPLES:: diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index d10ac31cf96..085ce14ce87 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -91,7 +91,6 @@ cdef class FiniteField(Field): True sage: hash(F) == object.__hash__(F) True - """ # This is the default hash function in Python's object.c: cdef long x @@ -150,7 +149,6 @@ cdef class FiniteField(Field): sage: GF(2).is_perfect() True - """ return True @@ -183,7 +181,7 @@ cdef class FiniteField(Field): def _latex_(self): r""" - Returns a string denoting the name of the field in LaTeX. + Return a string denoting the name of the field in LaTeX. The :func:`~sage.misc.latex.latex` function calls the ``_latex_`` attribute when available. @@ -318,14 +316,14 @@ cdef class FiniteField(Field): EXAMPLES:: - sage: k. = FiniteField(9, impl="pari") + sage: k. = FiniteField(9, impl='pari') sage: list(k) [0, 1, 2, a, a + 1, a + 2, 2*a, 2*a + 1, 2*a + 2] Partial iteration of a very large finite field:: sage: p = next_prime(2^64) - sage: k. = FiniteField(p^2, impl="pari") + sage: k. = FiniteField(p^2, impl='pari') sage: it = iter(k); it <...generator object at ...> sage: [next(it) for i in range(10)] @@ -337,11 +335,11 @@ cdef class FiniteField(Field): sage: L = [] sage: from sage.rings.finite_rings.finite_field_base import FiniteField - sage: print(list(FiniteField.__iter__(GF(8, impl="givaro", names="z")))) # needs sage.libs.linbox + sage: print(list(FiniteField.__iter__(GF(8, impl='givaro', names='z')))) # needs sage.libs.linbox [0, 1, z, z + 1, z^2, z^2 + 1, z^2 + z, z^2 + z + 1] - sage: print(list(FiniteField.__iter__(GF(8, impl="pari", names="z")))) + sage: print(list(FiniteField.__iter__(GF(8, impl='pari', names='z')))) [0, 1, z, z + 1, z^2, z^2 + 1, z^2 + z, z^2 + z + 1] - sage: print(list(FiniteField.__iter__(GF(8, impl="ntl", names="z")))) # needs sage.libs.ntl + sage: print(list(FiniteField.__iter__(GF(8, impl='ntl', names='z')))) # needs sage.libs.ntl [0, 1, z, z + 1, z^2, z^2 + 1, z^2 + z, z^2 + z + 1] """ cdef Py_ssize_t n = self.degree() @@ -419,7 +417,7 @@ cdef class FiniteField(Field): INPUT: - - `n` -- integer between `0` and the cardinality of this field minus `1`. + - ``n`` -- integer between `0` and the cardinality of this field minus `1` EXAMPLES:: @@ -463,7 +461,7 @@ cdef class FiniteField(Field): def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): """ - Return ``True`` if the map from self to codomain sending + Return ``True`` if the map from ``self`` to codomain sending ``self.0`` to the unique element of ``im_gens`` is a valid field homomorphism. Otherwise, return ``False``. @@ -546,7 +544,7 @@ cdef class FiniteField(Field): INPUT: - - ``f`` -- a univariate non-zero polynomial over this field + - ``f`` -- a univariate nonzero polynomial over this field ALGORITHM: [Coh1993]_, Algorithm 3.4.2 which is basically the algorithm in [Yun1976]_ with special treatment for powers divisible by `p`. @@ -586,7 +584,6 @@ cdef class FiniteField(Field): sage: R. = PolynomialRing(GF(65537), sparse=True) sage: (x^65537 + 2).squarefree_decomposition() (x + 2)^65537 - """ from sage.structure.factorization import Factorization if f.degree() == 0: @@ -647,7 +644,7 @@ cdef class FiniteField(Field): def gen(self): r""" Return a generator of this field (over its prime field). As this is an - abstract base class, this just raises a ``NotImplementedError``. + abstract base class, this just raises a :exc:`NotImplementedError`. EXAMPLES:: @@ -677,7 +674,7 @@ cdef class FiniteField(Field): def zeta(self, n=None): """ Return an element of multiplicative order ``n`` in this finite - field. If there is no such element, raise ``ValueError``. + field. If there is no such element, raise :exc:`ValueError`. .. WARNING:: @@ -851,7 +848,7 @@ cdef class FiniteField(Field): def is_field(self, proof = True): """ - Returns whether or not the finite field is a field, i.e., + Return whether or not the finite field is a field, i.e., always returns ``True``. EXAMPLES:: @@ -878,7 +875,7 @@ cdef class FiniteField(Field): @cached_method def factored_order(self): """ - Returns the factored order of this field. For compatibility with + Return the factored order of this field. For compatibility with :mod:`~sage.rings.finite_rings.integer_mod_ring`. EXAMPLES:: @@ -892,7 +889,7 @@ cdef class FiniteField(Field): @cached_method def factored_unit_order(self): """ - Returns the factorization of ``self.order()-1``, as a 1-tuple. + Return the factorization of ``self.order()-1``, as a 1-tuple. The format is for compatibility with :mod:`~sage.rings.finite_rings.integer_mod_ring`. @@ -960,9 +957,7 @@ cdef class FiniteField(Field): coefficients in the base field that has `a` as a root. In finite field extensions, `\GF{p^n}`, the base field is `\GF{p}`. - OUTPUT: - - - a monic polynomial over `\GF{p}` in the variable `x`. + OUTPUT: a monic polynomial over `\GF{p}` in the variable `x` EXAMPLES:: @@ -1011,7 +1006,7 @@ cdef class FiniteField(Field): The given modulus is always made monic:: - sage: k. = GF(7^2, modulus=2*x^2 - 3, impl="pari_ffelt") + sage: k. = GF(7^2, modulus=2*x^2 - 3, impl='pari_ffelt') sage: k.modulus() x^2 + 2 @@ -1019,21 +1014,21 @@ cdef class FiniteField(Field): We test the various finite field implementations:: - sage: GF(2, impl="modn").modulus() + sage: GF(2, impl='modn').modulus() x + 1 - sage: GF(2, impl="givaro").modulus() # needs sage.libs.linbox + sage: GF(2, impl='givaro').modulus() # needs sage.libs.linbox x + 1 - sage: GF(2, impl="ntl").modulus() # needs sage.libs.ntl + sage: GF(2, impl='ntl').modulus() # needs sage.libs.ntl x + 1 - sage: GF(2, impl="modn", modulus=x).modulus() + sage: GF(2, impl='modn', modulus=x).modulus() x - sage: GF(2, impl="givaro", modulus=x).modulus() # needs sage.libs.linbox + sage: GF(2, impl='givaro', modulus=x).modulus() # needs sage.libs.linbox x - sage: GF(2, impl="ntl", modulus=x).modulus() # needs sage.libs.ntl + sage: GF(2, impl='ntl', modulus=x).modulus() # needs sage.libs.ntl x - sage: GF(13^2, 'a', impl="givaro", modulus=x^2 + 2).modulus() # needs sage.libs.linbox + sage: GF(13^2, 'a', impl='givaro', modulus=x^2 + 2).modulus() # needs sage.libs.linbox x^2 + 2 - sage: GF(13^2, 'a', impl="pari_ffelt", modulus=x^2 + 2).modulus() # needs sage.libs.pari + sage: GF(13^2, 'a', impl='pari_ffelt', modulus=x^2 + 2).modulus() # needs sage.libs.pari x^2 + 2 """ # Normally, this is set by the constructor of the implementation @@ -1058,9 +1053,7 @@ cdef class FiniteField(Field): - ``name`` -- a variable name to use for the polynomial. By default, use the name given when constructing this field. - OUTPUT: - - - a monic polynomial over `\GF{p}` in the variable ``name``. + OUTPUT: a monic polynomial over `\GF{p}` in the variable ``name`` .. SEEALSO:: @@ -1128,7 +1121,6 @@ cdef class FiniteField(Field): sage: k.random_element(prob=0) # needs sage.modules 0 - """ if self.degree() == 1: return self(randrange(self.order())) @@ -1137,7 +1129,7 @@ cdef class FiniteField(Field): def some_elements(self): """ - Returns a collection of elements of this finite field for use in unit + Return a collection of elements of this finite field for use in unit testing. EXAMPLES:: @@ -1150,7 +1142,7 @@ cdef class FiniteField(Field): def polynomial_ring(self, variable_name=None): """ - Returns the polynomial ring over the prime subfield in the + Return the polynomial ring over the prime subfield in the same variable as this finite field. EXAMPLES:: @@ -1186,7 +1178,7 @@ cdef class FiniteField(Field): over the subfield. If not given, one is chosen automatically. - ``map`` -- boolean (default: ``True``); if ``True``, isomorphisms - from and to the vector space are also returned. + from and to the vector space are also returned The ``basis`` maps to the standard basis of the vector space by the isomorphisms. @@ -1388,7 +1380,7 @@ cdef class FiniteField(Field): cpdef _convert_map_from_(self, R): """ - Conversion from p-adic fields. + Conversion from `p`-adic fields. EXAMPLES:: @@ -1430,7 +1422,6 @@ cdef class FiniteField(Field): sage: F, R = k.construction() sage: F(R) is k True - """ from sage.categories.pushout import AlgebraicExtensionFunctor try: @@ -1459,22 +1450,22 @@ cdef class FiniteField(Field): INPUT: - ``modulus`` -- a polynomial with coefficients in ``self``, - or an integer. + or an integer - - ``name`` or ``names`` -- string: the name of the generator + - ``name`` or ``names`` -- string; the name of the generator in the new extension - - ``latex_name`` or ``latex_names`` -- string: latex name of + - ``latex_name`` or ``latex_names`` -- string; latex name of the generator in the new extension - - ``map`` -- boolean (default: ``False``): if ``False``, - return just the extension `E`; if ``True``, return a pair + - ``map`` -- boolean (default: ``False``); if ``False``, + return just the extension `E`. If ``True``, return a pair `(E, f)`, where `f` is an embedding of ``self`` into `E`. - ``embedding`` -- currently not used; for compatibility with - other ``AlgebraicExtensionFunctor`` calls. + other ``AlgebraicExtensionFunctor`` calls - - ``**kwds``: further keywords, passed to the finite field + - ``**kwds`` -- further keywords, passed to the finite field constructor. OUTPUT: @@ -1654,7 +1645,7 @@ cdef class FiniteField(Field): - ``name`` -- string; name of the generator of the subfield - - ``map`` -- boolean (default ``False``); whether to also return the inclusion map + - ``map`` -- boolean (default: ``False``); whether to also return the inclusion map EXAMPLES:: @@ -1764,9 +1755,9 @@ cdef class FiniteField(Field): INPUT: - - ``degree`` -- (default: `0`) an integer + - ``degree`` -- integer (default: `0`) - - ``name`` -- a string, a dictionary or ``None``: + - ``name`` -- string; a dictionary or ``None``: - If ``degree`` is nonzero, then ``name`` must be a string (or ``None``, if this is a pseudo-Conway extension), @@ -1841,10 +1832,10 @@ cdef class FiniteField(Field): INPUT: - - ``name`` -- string (default: 'z'): prefix to use for + - ``name`` -- string (default: ``'z'``); prefix to use for variable names of subfields - - ``implementation`` -- string (optional): specifies how to + - ``implementation`` -- string (optional); specifies how to construct the algebraic closure. The only value supported at the moment is ``'pseudo_conway'``. For more details, see :mod:`~sage.rings.algebraic_closure_finite_field`. @@ -1880,6 +1871,12 @@ cdef class FiniteField(Field): sage: F.gen(3) z3 + For finite fields, the algebraic closure is always (isomorphic + to) the algebraic closure of the prime field:: + + sage: GF(5^2).algebraic_closure() == F + True + The default name is 'z' but you can change it through the option ``name``:: @@ -1899,20 +1896,25 @@ cdef class FiniteField(Field): .. NOTE:: - This is currently only implemented for prime fields. + For non-prime finite fields, this method currently simply + returns the algebraic closure of the prime field. This may + or may not change in the future when extension towers are + supported properly. TESTS:: sage: GF(5).algebraic_closure() is GF(5).algebraic_closure() True """ + if not self.is_prime_field(): + return self.prime_subfield().algebraic_closure() from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField return AlgebraicClosureFiniteField(self, name, **kwds) @cached_method def is_conway(self): """ - Return ``True`` if self is defined by a Conway polynomial. + Return ``True`` if ``self`` is defined by a Conway polynomial. EXAMPLES:: @@ -1929,11 +1931,81 @@ cdef class FiniteField(Field): return (exists_conway_polynomial(p, n) and self.polynomial() == self.polynomial_ring()(conway_polynomial(p, n))) + def an_embedding(self, K): + r""" + Return some embedding of this field into another field `K`, + and raise a :class:`ValueError` if none exists. + + .. SEEALSO:: + + :meth:`sage.rings.ring.Field.an_embedding` + + EXAMPLES:: + + sage: GF(4,'a').an_embedding(GF(2).algebraic_closure()) + Ring morphism: + From: Finite Field in a of size 2^2 + To: Algebraic closure of Finite Field of size 2 + Defn: a |--> ... + """ + if self.characteristic() != K.characteristic(): + raise ValueError(f'no embedding from {self} to {K}: incompatible characteristics') + try: + return super().an_embedding(K) + except (NotImplementedError, ValueError): + pass + if K not in FiniteFields(): + from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic + if not isinstance(K, AlgebraicClosureFiniteField_generic): + raise NotImplementedError('computing embeddings into this ring not implemented') + g = self.gen() + if (emb := K.coerce_map_from(self)) is not None: + return self.hom([emb(g)]) + try: + r = g.minpoly().change_ring(K).any_root() + except ValueError: + raise ValueError(f'no embedding from {self} to {K}') + return self.hom([r]) + + def embeddings(self, K): + r""" + Return a list of all embeddings of this field in another field `K`. + + EXAMPLES:: + + sage: GF(2).embeddings(GF(4)) + [Ring morphism: + From: Finite Field of size 2 + To: Finite Field in z2 of size 2^2 + Defn: 1 |--> 1] + sage: GF(4).embeddings(GF(2).algebraic_closure()) + [Ring morphism: + From: Finite Field in z2 of size 2^2 + To: Algebraic closure of Finite Field of size 2 + Defn: z2 |--> z2, + Ring morphism: + From: Finite Field in z2 of size 2^2 + To: Algebraic closure of Finite Field of size 2 + Defn: z2 |--> z2 + 1] + """ + if self.characteristic() != K.characteristic(): + return [] + if K not in FiniteFields(): + from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic + if not isinstance(K, AlgebraicClosureFiniteField_generic): + raise NotImplementedError('computing embeddings into this ring not implemented') + g = self.gen() + rs = [] + if (emb := K.coerce_map_from(self)) is not None: + rs.append(emb(g)) + rs += [r for r,_ in g.minpoly().roots(ring=K) if r not in rs] + return [self.hom([r]) for r in rs] + def frobenius_endomorphism(self, n=1): """ INPUT: - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) OUTPUT: @@ -2008,14 +2080,14 @@ cdef class FiniteField(Field): INPUT: - - ``basis`` -- (default: ``None``): a basis of the finite field + - ``basis`` -- (default: ``None``); a basis of the finite field ``self``, `\GF{p^n}`, as a vector space over the base field `\GF{p}`. Uses the power basis `\{x^i : 0 \leq i \leq n-1\}` as input if no basis is supplied, where `x` is the generator of ``self``. - - ``check`` -- (default: ``True``): verifies that ``basis`` is - a valid basis of ``self``. + - ``check`` -- (default: ``True``); verifies that ``basis`` is + a valid basis of ``self`` ALGORITHM: @@ -2114,7 +2186,7 @@ cdef class FiniteField(Field): return [sum(x * y for x, y in zip(col, basis)) for col in B.columns()] - def from_bytes(self, input_bytes, byteorder="big"): + def from_bytes(self, input_bytes, byteorder='big'): r""" Return the integer represented by the given array of bytes. @@ -2123,8 +2195,8 @@ cdef class FiniteField(Field): INPUT: - ``input_bytes`` -- a bytes-like object or iterable producing bytes - - ``byteorder`` -- str (default: ``"big"``); determines the byte order of - ``input_bytes``; can only be ``"big"`` or ``"little"`` + - ``byteorder`` -- string (default: ``'big'``); determines the byte order of + ``input_bytes`` (can only be ``'big'`` or ``'little'``) EXAMPLES:: @@ -2132,7 +2204,7 @@ cdef class FiniteField(Field): sage: F = GF(2**127 - 1) sage: F.from_bytes(input_bytes) 545127616933790290830707 - sage: a = F.from_bytes(input_bytes, byteorder="little"); a + sage: a = F.from_bytes(input_bytes, byteorder='little'); a 544943659528996309004147 sage: type(a) @@ -2143,7 +2215,7 @@ cdef class FiniteField(Field): sage: F_ext = GF(65537**5) sage: F_ext.from_bytes(input_bytes) 29549*z5^4 + 40876*z5^3 + 52171*z5^2 + 13604*z5 + 20843 - sage: F_ext.from_bytes(input_bytes, byteorder="little") + sage: F_ext.from_bytes(input_bytes, byteorder='little') 29539*z5^4 + 42728*z5^3 + 47440*z5^2 + 12423*z5 + 27473 TESTS:: diff --git a/src/sage/rings/finite_rings/finite_field_constructor.py b/src/sage/rings/finite_rings/finite_field_constructor.py index 78acc0a8873..bd29fdb1a95 100644 --- a/src/sage/rings/finite_rings/finite_field_constructor.py +++ b/src/sage/rings/finite_rings/finite_field_constructor.py @@ -8,11 +8,11 @@ are -- ``sage.rings.finite_rings.integer_mod.IntegerMod_int``, +- ``sage.rings.finite_rings.integer_mod.IntegerMod_int``, -- ``sage.rings.finite_rings.integer_mod.IntegerMod_int64``, and +- ``sage.rings.finite_rings.integer_mod.IntegerMod_int64``, and -- ``sage.rings.finite_rings.integer_mod.IntegerMod_gmp``. +- ``sage.rings.finite_rings.integer_mod.IntegerMod_gmp``. Small extension fields of cardinality `< 2^{16}` are @@ -229,16 +229,15 @@ class FiniteFieldFactory(UniqueFactory): - ``impl`` -- (optional) a string specifying the implementation of the finite field. Possible values are: - - ``'modn'`` -- ring of integers modulo `p` (only for prime - fields). + - ``'modn'`` -- ring of integers modulo `p` (only for prime fields) - ``'givaro'`` -- Givaro, which uses Zech logs (only for fields - of at most 65521 elements). + of at most 65521 elements) - - ``'ntl'`` -- NTL using GF2X (only in characteristic 2). + - ``'ntl'`` -- NTL using GF2X (only in characteristic 2) - ``'pari'`` or ``'pari_ffelt'`` -- PARI's ``FFELT`` type (only - for extension fields). + for extension fields) - ``elem_cache`` -- (default: order < 500) cache all elements to avoid creation time; ignored unless ``impl='givaro'`` @@ -258,8 +257,8 @@ class FiniteFieldFactory(UniqueFactory): - ``check_irreducible`` -- verify that the polynomial modulus is irreducible - - ``proof`` -- bool (default: ``True``): if ``True``, use provable - primality test; otherwise only use pseudoprimality test. + - ``proof`` -- boolean (default: ``True``); if ``True``, use provable + primality test; otherwise only use pseudoprimality test ALIAS: You can also use ``GF`` instead of ``FiniteField`` -- they are identical. @@ -304,7 +303,7 @@ class FiniteFieldFactory(UniqueFactory): 7105427357601001858711242675781 sage: a.is_square() True - sage: K. = GF(5^45, modulus="primitive") + sage: K. = GF(5^45, modulus='primitive') sage: b.multiplicative_order() 28421709430404007434844970703124 @@ -358,7 +357,7 @@ class FiniteFieldFactory(UniqueFactory): change how Sage computes in this field, but it will change the result of the :meth:`modulus` and :meth:`gen` methods:: - sage: k. = GF(5, modulus="primitive") + sage: k. = GF(5, modulus='primitive') sage: k.modulus() x + 3 sage: a @@ -465,9 +464,9 @@ class FiniteFieldFactory(UniqueFactory): Check that :issue:`16934` has been fixed:: - sage: k1. = GF(17^14, impl="pari") + sage: k1. = GF(17^14, impl='pari') sage: _ = a/2 - sage: k2. = GF(17^14, impl="pari") + sage: k2. = GF(17^14, impl='pari') sage: k1 is k2 True diff --git a/src/sage/rings/finite_rings/finite_field_givaro.py b/src/sage/rings/finite_rings/finite_field_givaro.py index a393535a1fd..ce61efb8edd 100644 --- a/src/sage/rings/finite_rings/finite_field_givaro.py +++ b/src/sage/rings/finite_rings/finite_field_givaro.py @@ -39,7 +39,7 @@ class FiniteField_givaro(FiniteField): - ``name`` -- (default: ``'a'``) variable used for :meth:`~sage.rings.finite_rings.element_givaro.FiniteField_givaroElement.poly_repr()` - - ``modulus`` -- A minimal polynomial to use for reduction. + - ``modulus`` -- a minimal polynomial to use for reduction - ``repr`` -- (default: ``'poly'``) controls the way elements are printed to the user: @@ -51,15 +51,13 @@ class FiniteField_givaro(FiniteField): - 'poly': repr is :meth:`~sage.rings.finite_rings.element_givaro.FiniteField_givaroElement.poly_repr()` - - cache -- (default: ``False``) if ``True`` a cache of all elements of - this field is created. Thus, arithmetic does not create new elements - which speeds calculations up. Also, if many elements are needed during a - calculation this cache reduces the memory requirement as at most + - ``cache`` -- boolean (default: ``False``); if ``True`` a cache of all + elements of this field is created. Thus, arithmetic does not create new + elements which speeds calculations up. Also, if many elements are needed + during a calculation this cache reduces the memory requirement as at most :meth:`order` elements are created. - OUTPUT: - - Givaro finite field with characteristic `p` and cardinality `p^n`. + OUTPUT: Givaro finite field with characteristic `p` and cardinality `p^n` EXAMPLES: @@ -104,7 +102,7 @@ class FiniteField_givaro(FiniteField): sage: GF(1009, impl='givaro', modulus='conway').modulus() x + 998 """ - def __init__(self, q, name="a", modulus=None, repr="poly", cache=False): + def __init__(self, q, name='a', modulus=None, repr='poly', cache=False): """ Initialize ``self``. @@ -161,9 +159,7 @@ def order(self): """ Return the cardinality of this field. - OUTPUT: - - Integer -- the number of elements in ``self``. + OUTPUT: integer; the number of elements in ``self`` EXAMPLES:: @@ -178,9 +174,7 @@ def degree(self): r""" If the cardinality of ``self`` is `p^n`, then this returns `n`. - OUTPUT: - - Integer -- the degree + OUTPUT: integer; the degree EXAMPLES:: @@ -334,10 +328,10 @@ def _element_constructor_(self, e): We can coerce from PARI finite field implementations:: - sage: K. = GF(3^10, impl="givaro") + sage: K. = GF(3^10, impl='givaro') sage: a^20 2*a^9 + 2*a^8 + a^7 + 2*a^5 + 2*a^4 + 2*a^3 + 1 - sage: M. = GF(3^10, impl="pari_ffelt") + sage: M. = GF(3^10, impl='pari_ffelt') sage: K(c^20) 2*a^9 + 2*a^8 + a^7 + 2*a^5 + 2*a^4 + 2*a^3 + 1 @@ -409,7 +403,7 @@ def gen(self, n=0): def prime_subfield(self): r""" - Return the prime subfield `\GF{p}` of self if ``self`` is `\GF{p^n}`. + Return the prime subfield `\GF{p}` of ``self`` if ``self`` is `\GF{p^n}`. EXAMPLES:: @@ -440,9 +434,7 @@ def log_to_int(self, n): - ``n`` -- log representation of a finite field element - OUTPUT: - - integer representation of a finite field element. + OUTPUT: integer representation of a finite field element EXAMPLES:: @@ -464,9 +456,7 @@ def int_to_log(self, n): - ``n`` -- integer representation of a finite field element - OUTPUT: - - log representation of ``n`` + OUTPUT: log representation of ``n`` EXAMPLES:: @@ -577,7 +567,7 @@ def frobenius_endomorphism(self, n=1): """ INPUT: - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) OUTPUT: diff --git a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py index 654f7a2b54b..2bfda7690d3 100644 --- a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py +++ b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py @@ -53,16 +53,14 @@ class FiniteField_ntl_gf2e(FiniteField): - ``names`` -- variable used for poly_repr (default: ``'a'``) - - ``modulus`` -- A minimal polynomial to use for reduction. + - ``modulus`` -- a minimal polynomial to use for reduction - ``repr`` -- controls the way elements are printed to the user: (default: ``'poly'``) - - ``'poly'``: polynomial representation + - ``'poly'`` -- polynomial representation - OUTPUT: - - Finite field with characteristic 2 and cardinality `2^n`. + OUTPUT: finite field with characteristic 2 and cardinality `2^n` EXAMPLES:: @@ -89,7 +87,7 @@ class FiniteField_ntl_gf2e(FiniteField): True """ - def __init__(self, q, names="a", modulus=None, repr="poly"): + def __init__(self, q, names='a', modulus=None, repr='poly'): """ Initialize ``self``. @@ -107,7 +105,7 @@ def __init__(self, q, names="a", modulus=None, repr="poly"): sage: k2. = GF(2^17) sage: k1 == k2 False - sage: k3. = GF(2^16, impl="pari_ffelt") + sage: k3. = GF(2^16, impl='pari_ffelt') sage: k1 == k3 False @@ -277,7 +275,7 @@ def from_integer(self, number): INPUT: - - ``number`` -- an integer + - ``number`` -- integer EXAMPLES:: diff --git a/src/sage/rings/finite_rings/finite_field_pari_ffelt.py b/src/sage/rings/finite_rings/finite_field_pari_ffelt.py index c60a7a563a7..9549dbc94b4 100644 --- a/src/sage/rings/finite_rings/finite_field_pari_ffelt.py +++ b/src/sage/rings/finite_rings/finite_field_pari_ffelt.py @@ -195,7 +195,7 @@ def characteristic(self): def degree(self): """ - Returns the degree of ``self`` over its prime field. + Return the degree of ``self`` over its prime field. EXAMPLES:: @@ -222,7 +222,7 @@ def _pari_frobenius(self, k=1): """ k = k % self.degree() if k == 0: - raise ValueError("_pari_frobenius requires a non-zero exponent") + raise ValueError("_pari_frobenius requires a nonzero exponent") g = self.gen() i = len(self.__pari_frobenius_powers) if i == 0: diff --git a/src/sage/rings/finite_rings/finite_field_prime_modn.py b/src/sage/rings/finite_rings/finite_field_prime_modn.py index b51cf9fe7d5..d94b0a4335a 100644 --- a/src/sage/rings/finite_rings/finite_field_prime_modn.py +++ b/src/sage/rings/finite_rings/finite_field_prime_modn.py @@ -56,9 +56,9 @@ def __init__(self, p, check=True, modulus=None): INPUT: - - ``p`` -- an integer at least 2 + - ``p`` -- integer at least 2 - - ``check`` -- bool (default: ``True``); if ``False``, do not + - ``check`` -- boolean (default: ``True``); if ``False``, do not check ``p`` for primality EXAMPLES:: @@ -154,7 +154,7 @@ def _coerce_map_from_(self, S): def _convert_map_from_(self, R): """ - Conversion from p-adic fields. + Conversion from `p`-adic fields. EXAMPLES:: @@ -174,7 +174,8 @@ def _convert_map_from_(self, R): def construction(self): """ - Returns the construction of this finite field (for use by sage.categories.pushout) + Return the construction of this finite field (for use by + ``sage.categories.pushout``). EXAMPLES:: @@ -214,7 +215,7 @@ def is_prime_field(self): def polynomial(self, name=None): """ - Returns the polynomial ``name``. + Return the polynomial ``name``. EXAMPLES:: @@ -278,7 +279,7 @@ def gen(self, n=0): 1 sage: # needs sage.rings.finite_rings - sage: k = GF(1009, modulus="primitive") + sage: k = GF(1009, modulus='primitive') sage: k.gen() # this gives a primitive element 11 sage: k.gen(1) diff --git a/src/sage/rings/finite_rings/galois_group.py b/src/sage/rings/finite_rings/galois_group.py index f11b72bc681..32e23a40c44 100644 --- a/src/sage/rings/finite_rings/galois_group.py +++ b/src/sage/rings/finite_rings/galois_group.py @@ -66,11 +66,11 @@ def __init__(self, field): sage: TestSuite(GF(9).galois_group()).run() """ - GaloisGroup_cyc.__init__(self, field, (field.degree(),), gen_names="Frob") + GaloisGroup_cyc.__init__(self, field, (field.degree(),), gen_names='Frob') def _repr_(self): r""" - String representation of this Galois group + String representation of this Galois group. EXAMPLES:: diff --git a/src/sage/rings/finite_rings/hom_finite_field.pyx b/src/sage/rings/finite_rings/hom_finite_field.pyx index 9aa5db8ea86..9e825650fca 100644 --- a/src/sage/rings/finite_rings/hom_finite_field.pyx +++ b/src/sage/rings/finite_rings/hom_finite_field.pyx @@ -150,7 +150,6 @@ cdef class SectionFiniteFieldHomomorphism_generic(Section): return root raise ValueError("%s is not in the image of %s" % (x, self._inverse)) - def _repr_(self): """ Return a string representation of this section. @@ -167,7 +166,6 @@ cdef class SectionFiniteFieldHomomorphism_generic(Section): """ return "Section of %s" % self._inverse - def _latex_(self): r""" Return a latex representation of this section. @@ -196,7 +194,6 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): sage: K. = GF(3^21) sage: f = FiniteFieldHomomorphism_generic(Hom(k, K)) sage: TestSuite(f).run() - """ def __init__(self, parent, im_gens=None, base_map=None, check=True, section_class=None): """ @@ -322,7 +319,6 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): f = f.map_coefficients(bm) return f(self.im_gens()[0]) - def is_injective(self): """ Return ``True`` since a embedding between finite fields is @@ -339,7 +335,6 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): """ return True - def is_surjective(self): """ Return ``True`` if this embedding is surjective (and hence an @@ -359,7 +354,6 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): """ return self.domain().cardinality() == self.codomain().cardinality() - @cached_method def section(self): """ @@ -423,7 +417,7 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): def __hash__(self): r""" - Return a hash of this morphism + Return a hash of this morphism. TESTS:: @@ -437,7 +431,7 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): cdef dict _extra_slots(self): r""" - Helper function for copying and pickling + Helper function for copying and pickling. TESTS:: @@ -465,7 +459,7 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): cdef _update_slots(self, dict slots): r""" - Helper function for copying and pickling + Helper function for copying and pickling. TESTS:: @@ -494,15 +488,14 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): sage: k. = GF(7^11) sage: Frob = k.frobenius_endomorphism(5) sage: TestSuite(Frob).run() - """ def __init__(self, domain, n=1): """ INPUT: - - ``domain`` -- a finite field + - ``domain`` -- a finite field - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) .. NOTE:: @@ -546,7 +539,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): self._q = domain.characteristic() ** self._power RingHomomorphism.__init__(self, Hom(domain, domain)) - def _repr_(self): """ Return a string representation of this endomorphism. @@ -570,7 +562,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): s += " %s" % self.domain() return s - def _repr_short(self): """ Return a short string representation of this endomorphism. @@ -593,7 +584,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): s = "%s |--> %s^(%s^%s)" % (name, name, self.domain().characteristic(), self._power) return s - def _latex_(self): r""" Return a latex representation of this endomorphism. @@ -617,7 +607,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): s = "%s \\mapsto %s^{%s^{%s}}" % (name, name, self.domain().characteristic(), self._power) return s - cpdef Element _call_(self, x): """ TESTS:: @@ -634,7 +623,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): else: return x.pth_power(self._power) - def order(self): """ Return the order of this endomorphism. @@ -675,7 +663,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): """ return self._power - def __pow__(self, n, modulus): """ Return the `n`-th iterate of this endomorphism. @@ -713,7 +700,7 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): def _composition(self, right): """ - Return self o right. + Return ``self`` o ``right``. EXAMPLES:: @@ -737,7 +724,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): else: return RingHomomorphism._composition(self, right) - def fixed_field(self): """ Return the fixed field of ``self``. @@ -782,7 +768,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): f = FiniteFieldHomomorphism_generic(Hom(k, self.domain())) return k, f - def is_injective(self): """ Return ``True`` since any power of the Frobenius endomorphism @@ -797,7 +782,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): """ return True - def is_surjective(self): """ Return ``True`` since any power of the Frobenius endomorphism @@ -812,7 +796,6 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): """ return True - def is_identity(self): """ Return ``True`` if this morphism is the identity morphism. @@ -830,7 +813,7 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): def __hash__(self): r""" - Return a hash of this morphism + Return a hash of this morphism. EXAMPLES:: @@ -843,7 +826,7 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): cdef _update_slots(self, dict slots): r""" - Helper function for copying and pickling + Helper function for copying and pickling. TESTS:: diff --git a/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx b/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx index bf3e69f56a7..81b7045b8f6 100644 --- a/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx +++ b/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx @@ -99,7 +99,6 @@ cdef class SectionFiniteFieldHomomorphism_givaro(SectionFiniteFieldHomomorphism_ self._codomain_cache = ((self._codomain.gen()))._cache - cpdef Element _call_(self, x): """ TESTS:: @@ -181,7 +180,6 @@ cdef class FiniteFieldHomomorphism_givaro(FiniteFieldHomomorphism_generic): self._order_domain = domain.cardinality() - 1 self._order_codomain = codomain.cardinality() - 1 - cpdef Element _call_(self, x): """ TESTS:: @@ -228,7 +226,6 @@ cdef class FrobeniusEndomorphism_givaro(FrobeniusEndomorphism_finite_field): raise TypeError("The domain is not an instance of FiniteField_givaro") FrobeniusEndomorphism_finite_field.__init__(self, domain, power) - def fixed_field(self): """ Return the fixed field of ``self``. diff --git a/src/sage/rings/finite_rings/hom_prime_finite_field.pyx b/src/sage/rings/finite_rings/hom_prime_finite_field.pyx index e45de1d83f9..c53a87ddca0 100644 --- a/src/sage/rings/finite_rings/hom_prime_finite_field.pyx +++ b/src/sage/rings/finite_rings/hom_prime_finite_field.pyx @@ -117,9 +117,9 @@ cdef class FrobeniusEndomorphism_prime(FrobeniusEndomorphism_finite_field): def _composition(self, right): """ - Return self o right. + Return ``self`` o ``right``. - It is always right, since self is always identity because + It is always ``right``, since ``self`` is always identity because the domain is a prime field. """ return right diff --git a/src/sage/rings/finite_rings/homset.py b/src/sage/rings/finite_rings/homset.py index ef72f35a1a5..6c15d725f43 100644 --- a/src/sage/rings/finite_rings/homset.py +++ b/src/sage/rings/finite_rings/homset.py @@ -159,7 +159,7 @@ def _repr_(self): def is_aut(self): """ - Check if ``self`` is an automorphism + Check if ``self`` is an automorphism. EXAMPLES:: @@ -233,7 +233,7 @@ def list(self): Between isomorphic fields with different moduli:: sage: k1 = GF(1009) - sage: k2 = GF(1009, modulus="primitive") + sage: k2 = GF(1009, modulus='primitive') sage: Hom(k1, k2).list() [ Ring morphism: @@ -249,8 +249,8 @@ def list(self): Defn: 11 |--> 11 ] - sage: k1. = GF(1009^2, modulus="first_lexicographic") - sage: k2. = GF(1009^2, modulus="conway") + sage: k1. = GF(1009^2, modulus='first_lexicographic') + sage: k2. = GF(1009^2, modulus='conway') sage: Hom(k1, k2).list() [ Ring morphism: @@ -348,7 +348,6 @@ def _an_element_(self): .. TODO:: Use a more sophisticated algorithm; see also :issue:`8751`. - """ K = self.domain() L = self.codomain() diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index b2238689afb..0b220e81a1e 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -7,20 +7,20 @@ There are three types of integer_mod classes, depending on the size of the modulus. -- ``IntegerMod_int`` stores its value in a - ``int_fast32_t`` (typically an ``int``); - this is used if the modulus is less than - `\sqrt{2^{31}-1}`. +- ``IntegerMod_int`` stores its value in a + ``int_fast32_t`` (typically an ``int``); + this is used if the modulus is less than + `\sqrt{2^{31}-1}`. -- ``IntegerMod_int64`` stores its value in a - ``int_fast64_t`` (typically a ``long - long``); this is used if the modulus is less than - `2^{31}-1`. In many places, we assume that the values and the modulus - actually fit inside an ``unsigned long``. +- ``IntegerMod_int64`` stores its value in a + ``int_fast64_t`` (typically a ``long + long``); this is used if the modulus is less than + `2^{31}-1`. In many places, we assume that the values and the modulus + actually fit inside an ``unsigned long``. -- ``IntegerMod_gmp`` stores its value in a - ``mpz_t``; this can be used for an arbitrarily large - modulus. +- ``IntegerMod_gmp`` stores its value in a + ``mpz_t``; this can be used for an arbitrarily large + modulus. All extend ``IntegerMod_abstract``. @@ -151,7 +151,7 @@ def Mod(n, m, parent=None): if m == 0: return n - # m is non-zero, so return n mod m + # m is nonzero, so return n mod m if parent is None: from sage.rings.finite_rings.integer_mod_ring import IntegerModRing parent = IntegerModRing(m) @@ -479,7 +479,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): Coerce this element to the ring `Z/(modulus)`. If the new ``modulus`` does not divide the current modulus, - an ``ArithmeticError`` is raised. + an :exc:`ArithmeticError` is raised. EXAMPLES:: @@ -605,7 +605,6 @@ cdef class IntegerMod_abstract(FiniteRingElement): 4 sage: aa.typeOf() # optional - fricas IntegerMod(15) - """ return '%s :: %s'%(self, self.parent()._axiom_init_()) @@ -638,7 +637,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): else: return sib(self.parent())(v) - def log(self, b=None): + def log(self, b=None, order=None, check=False): r""" Compute the discrete logarithm of this element to base `b`, that is, @@ -647,17 +646,22 @@ cdef class IntegerMod_abstract(FiniteRingElement): INPUT: + - ``self`` -- unit modulo `n` - - ``self`` -- unit modulo `n` + - ``b`` -- a unit modulo `n`. If ``b`` is not given, + ``R.multiplicative_generator()`` is used, where + ``R`` is the parent of ``self``. - - ``b`` -- a unit modulo `n`. If ``b`` is not given, - ``R.multiplicative_generator()`` is used, where - ``R`` is the parent of ``self``. + - ``order`` -- integer (unused), the order of ``b``. + This argument is normally unused, only there for + coherence of apis with finite field elements. + - ``check`` -- boolean (default: ``False``); if set, + test whether the given ``order`` is correct OUTPUT: - Integer `x` such that `b^x = a`, if this exists; a :class:`ValueError` + Integer `x` such that `b^x = a`, if this exists; a :exc:`ValueError` otherwise. .. NOTE:: @@ -760,6 +764,15 @@ cdef class IntegerMod_abstract(FiniteRingElement): sage: R(1).factor() 1 + An example for ``check=True``:: + + sage: F = GF(127, impl='modn') + sage: t = F.primitive_element() + sage: t.log(t, 57, check=True) + Traceback (most recent call last): + ... + ValueError: base does not have the provided order + AUTHORS: - David Joyner and William Stein (2005-11) @@ -781,6 +794,11 @@ cdef class IntegerMod_abstract(FiniteRingElement): if not b.is_unit(): raise ValueError(f"logarithm with base {b} is not defined since it is not a unit modulo {b.modulus()}") + if check: + from sage.groups.generic import has_order + if not has_order(b, order, '*'): + raise ValueError('base does not have the provided order') + cdef Integer n = Integer() cdef Integer m = one_Z cdef Integer q, na, nb @@ -821,7 +839,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def generalised_log(self): r""" - Return integers `[n_1, \ldots, n_d]` such that + Return integers `[n_1, \ldots, n_d]` such that. .. MATH:: @@ -851,7 +869,6 @@ cdef class IntegerMod_abstract(FiniteRingElement): of the parent (which is the default). Specifying ``algorithm='pari'`` usually yields a different set of generators that is incompatible with this method. - """ if not self.is_unit(): raise ZeroDivisionError @@ -881,7 +898,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def charpoly(self, var='x'): """ - Returns the characteristic polynomial of this element. + Return the characteristic polynomial of this element. EXAMPLES:: @@ -901,7 +918,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def minpoly(self, var='x'): """ - Returns the minimal polynomial of this element. + Return the minimal polynomial of this element. EXAMPLES:: @@ -912,7 +929,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def minimal_polynomial(self, var='x'): """ - Returns the minimal polynomial of this element. + Return the minimal polynomial of this element. EXAMPLES:: @@ -923,7 +940,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def polynomial(self, var='x'): """ - Returns a constant polynomial representing this value. + Return a constant polynomial representing this value. EXAMPLES:: @@ -940,7 +957,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def norm(self): """ - Returns the norm of this element, which is itself. (This is here + Return the norm of this element, which is itself. (This is here for compatibility with higher order finite fields.) EXAMPLES:: @@ -958,7 +975,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def trace(self): """ - Returns the trace of this element, which is itself. (This is here + Return the trace of this element, which is itself. (This is here for compatibility with higher order finite fields.) EXAMPLES:: @@ -1119,14 +1136,12 @@ cdef class IntegerMod_abstract(FiniteRingElement): INPUT: - - ``extend`` -- bool (default: ``True``); - if ``True``, return a square root in an extension ring, - if necessary. Otherwise, raise a ``ValueError`` if the - square root is not in the base ring. + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the square root is not in the base ring. - - ``all`` -- bool (default: ``False``); if - ``True``, return {all} square roots of self, instead of - just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return {all} + square roots of self, instead of just one ALGORITHM: Calculates the square roots mod `p` for each of the primes `p` dividing the order of the ring, then lifts @@ -1337,38 +1352,38 @@ cdef class IntegerMod_abstract(FiniteRingElement): def nth_root(self, n, extend = False, all = False, algorithm = None, cunningham = False): r""" - Returns an `n`\th root of ``self``. + Return an `n`-th root of ``self``. INPUT: - ``n`` -- integer `\geq 1` - - ``extend`` -- bool (default: ``True``); if True, return an nth - root in an extension ring, if necessary. Otherwise, raise a - ValueError if the root is not in the base ring. Warning: + - ``extend`` -- boolean (default: ``True``); if ``True``, return an + `n`-th root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the root is not in the base ring. Warning: this option is not implemented! - - ``all`` -- bool (default: ``False``); if ``True``, return all `n`\th - roots of ``self``, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all + `n`-th roots of ``self``, instead of just one - - ``algorithm`` -- string (default: None); The algorithm for the prime modulus case. - CRT and p-adic log techniques are used to reduce to this case. - 'Johnston' is the only currently supported option. + - ``algorithm`` -- string (default: ``None``); the algorithm for the + prime modulus case. CRT and `p`-adic log techniques are used to reduce + to this case. ``'Johnston'`` is the only currently supported option. - - ``cunningham`` -- bool (default: ``False``); In some cases, - factorization of ``n`` is computed. If cunningham is set to ``True``, - the factorization of ``n`` is computed using trial division for all + - ``cunningham`` -- boolean (default: ``False``); in some cases, + factorization of `n` is computed. If cunningham is set to ``True``, + the factorization of `n` is computed using trial division for all primes in the so called Cunningham table. Refer to - sage.rings.factorint.factor_cunningham for more information. You need - to install an optional package to use this method, this can be done - with the following command line ``sage -i cunningham_tables`` + ``sage.rings.factorint.factor_cunningham`` for more information. You + need to install an optional package to use this method, this can be + done with the following command line: ``sage -i cunningham_tables``. OUTPUT: - If self has an `n`\th root, returns one (if ``all`` is ``False``) or a + If ``self`` has an `n`-th root, returns one (if ``all`` is ``False``) or a list of all of them (if ``all`` is ``True``). Otherwise, raises a - ``ValueError`` (if ``extend`` is ``False``) or a ``NotImplementedError`` (if - ``extend`` is ``True``). + :exc:`ValueError` (if ``extend`` is ``False``) or a + :exc:`NotImplementedError` (if ``extend`` is ``True``). .. warning:: @@ -1390,13 +1405,13 @@ cdef class IntegerMod_abstract(FiniteRingElement): - if ``self=1``: ``self`` is returned - - otherwise; a ``ValueError`` is raised + - otherwise; a :exc:`ValueError` is raised - If `n < 0`: - - if self is invertible, the `(-n)`\th root of the inverse of self is returned + - if ``self`` is invertible, the `(-n)`\th root of the inverse of ``self`` is returned - - otherwise a ``ValueError`` is raised or empty list returned. + - otherwise a :exc:`ValueError` is raised or empty list returned. EXAMPLES:: @@ -1599,7 +1614,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def _nth_root_naive(self, n): """ - Computes all nth roots using brute force, for doc-testing. + Compute all `n`-th roots using brute force, for doc-testing. TESTS:: @@ -1737,7 +1752,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def additive_order(self): r""" - Returns the additive order of self. + Return the additive order of ``self``. This is the same as ``self.order()``. @@ -1846,7 +1861,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def multiplicative_order(self): """ - Returns the multiplicative order of self. + Return the multiplicative order of ``self``. EXAMPLES:: @@ -1911,7 +1926,6 @@ cdef class IntegerMod_abstract(FiniteRingElement): +Infinity sage: ZZ.quo(1024)(16).valuation(4) 2 - """ p=self._modulus.sageInteger.gcd(p) if p==1: @@ -1951,7 +1965,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def _vector_(self): """ - Return self as a vector of its parent viewed as a one-dimensional + Return ``self`` as a vector of its parent viewed as a one-dimensional vector space. This is to support prime finite fields, which are implemented as @@ -2016,7 +2030,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): def __lshift__(IntegerMod_gmp self, k): r""" - Performs a left shift by ``k`` bits. + Perform a left shift by ``k`` bits. For details, see :meth:`shift`. @@ -2030,7 +2044,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): def __rshift__(IntegerMod_gmp self, k): r""" - Performs a right shift by ``k`` bits. + Perform a right shift by ``k`` bits. For details, see :meth:`shift`. @@ -2044,7 +2058,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): cdef shift(IntegerMod_gmp self, long k): r""" - Performs a bit-shift specified by ``k`` on ``self``. + Perform a bit-shift specified by ``k`` on ``self``. Suppose that ``self`` represents an integer `x` modulo `n`. If `k` is `k = 0`, returns `x`. If `k > 0`, shifts `x` to the left, that is, @@ -2056,11 +2070,9 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): INPUT: - - ``k`` -- Integer of type ``long`` + - ``k`` -- integer of type ``long`` - OUTPUT: - - - Result of type ``IntegerMod_gmp`` + OUTPUT: result of type ``IntegerMod_gmp`` EXAMPLES:: @@ -2101,8 +2113,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): cpdef bint is_one(IntegerMod_gmp self) noexcept: """ - Returns ``True`` if this is `1`, otherwise - ``False``. + Return ``True`` if this is `1`, otherwise ``False``. EXAMPLES:: @@ -2115,8 +2126,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): def __bool__(IntegerMod_gmp self): """ - Returns ``True`` if this is not `0`, otherwise - ``False``. + Return ``True`` if this is not `0`, otherwise ``False``. EXAMPLES:: @@ -2313,7 +2323,6 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): sage: zero^0 0 - """ cdef IntegerMod_gmp x = self._new_c() sig_on() @@ -2325,7 +2334,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): def __invert__(IntegerMod_gmp self): """ - Return the multiplicative inverse of self. + Return the multiplicative inverse of ``self``. EXAMPLES:: @@ -2381,14 +2390,14 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): @coerce_binop def gcd(self, IntegerMod_gmp other): r""" - Greatest common divisor + Greatest common divisor. Returns the "smallest" generator in `\ZZ / N\ZZ` of the ideal generated by ``self`` and ``other``. INPUT: - - ``other`` -- an element of the same ring as this one. + - ``other`` -- an element of the same ring as this one EXAMPLES:: @@ -2484,8 +2493,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): cpdef bint is_one(IntegerMod_int self) noexcept: """ - Returns ``True`` if this is `1`, otherwise - ``False``. + Return ``True`` if this is `1`, otherwise ``False``. EXAMPLES:: @@ -2502,8 +2510,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): def __bool__(IntegerMod_int self): """ - Returns ``True`` if this is not `0`, otherwise - ``False``. + Return ``True`` if this is not `0`, otherwise ``False``. EXAMPLES:: @@ -2532,9 +2539,9 @@ cdef class IntegerMod_int(IntegerMod_abstract): def _crt(IntegerMod_int self, IntegerMod_int other): """ Use the Chinese Remainder Theorem to find an element of the - integers modulo the product of the moduli that reduces to self and - to other. The modulus of other must be coprime to the modulus of - self. + integers modulo the product of the moduli that reduces to ``self`` and + to ``other``. The modulus of ``other`` must be coprime to the modulus + of ``self``. EXAMPLES:: @@ -2678,7 +2685,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): def __lshift__(IntegerMod_int self, k): r""" - Performs a left shift by ``k`` bits. + Perform a left shift by ``k`` bits. For details, see :meth:`shift`. @@ -2694,7 +2701,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): def __rshift__(IntegerMod_int self, k): r""" - Performs a right shift by ``k`` bits. + Perform a right shift by ``k`` bits. For details, see :meth:`shift`. @@ -2710,7 +2717,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): cdef shift(IntegerMod_int self, int k): """ - Performs a bit-shift specified by ``k`` on ``self``. + Perform a bit-shift specified by ``k`` on ``self``. Suppose that ``self`` represents an integer `x` modulo `n`. If `k` is `k = 0`, returns `x`. If `k > 0`, shifts `x` to the left, that is, @@ -2722,11 +2729,9 @@ cdef class IntegerMod_int(IntegerMod_abstract): INPUT: - - ``k`` -- Integer of type ``int`` + - ``k`` -- integer of type ``int`` - OUTPUT: - - - Result of type ``IntegerMod_int`` + OUTPUT: result of type ``IntegerMod_int`` WARNING: @@ -2796,7 +2801,6 @@ cdef class IntegerMod_int(IntegerMod_abstract): sage: R = Integers(1) sage: R(0)^0 0 - """ cdef long long_exp cdef int_fast32_t res @@ -2832,7 +2836,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): def __invert__(IntegerMod_int self): """ - Return the multiplicative inverse of self. + Return the multiplicative inverse of ``self``. EXAMPLES:: @@ -2910,14 +2914,14 @@ cdef class IntegerMod_int(IntegerMod_abstract): INPUT: - - ``extend`` -- bool (default: ``True``); - if ``True``, return a square root in an extension ring, - if necessary. Otherwise, raise a ``ValueError`` if the - square root is not in the base ring. + - ``extend`` -- boolean (default: ``True``); + if ``True``, return a square root in an extension ring, + if necessary. Otherwise, raise a :exc:`ValueError` if the + square root is not in the base ring. - - ``all`` -- bool (default: ``False``); if - ``True``, return {all} square roots of self, instead of - just one. + - ``all`` -- boolean (default: ``False``); if + ``True``, return {all} square roots of self, instead of + just one. ALGORITHM: Calculates the square roots mod `p` for each of the primes `p` dividing the order of the ring, then lifts @@ -3021,7 +3025,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): # easy case of n prime, n = 3 mod 4. if n > 100 and n % 4 == 3 and len(moduli) == 1 and moduli[0][1] == 1: if jacobi_int(self.ivalue, self._modulus.int32) == 1: - # it's a non-zero square, sqrt(a) = a^(p+1)/4 + # it's a nonzero square, sqrt(a) = a^(p+1)/4 i = mod_pow_int(self.ivalue, (self._modulus.int32+1)/4, n) if i > n / 2: i = n - i @@ -3064,14 +3068,14 @@ cdef class IntegerMod_int(IntegerMod_abstract): @coerce_binop def gcd(self, IntegerMod_int other): r""" - Greatest common divisor + Greatest common divisor. Returns the "smallest" generator in `\ZZ / N\ZZ` of the ideal generated by ``self`` and ``other``. INPUT: - - ``other`` -- an element of the same ring as this one. + - ``other`` -- an element of the same ring as this one EXAMPLES:: @@ -3101,9 +3105,9 @@ cdef class IntegerMod_int(IntegerMod_abstract): cdef int_fast32_t gcd_int(int_fast32_t a, int_fast32_t b) noexcept: """ - Returns the gcd of a and b + Return the gcd of ``a`` and ``b``. - For use with IntegerMod_int + For use with ``IntegerMod_int``. AUTHORS: @@ -3123,9 +3127,9 @@ cdef int_fast32_t gcd_int(int_fast32_t a, int_fast32_t b) noexcept: cdef int_fast32_t mod_inverse_int(int_fast32_t x, int_fast32_t n) except 0: """ - Returns y such that xy=1 mod n + Return y such that xy=1 mod n. - For use in IntegerMod_int + For use in ``IntegerMod_int``. AUTHORS: @@ -3157,9 +3161,9 @@ cdef int_fast32_t mod_inverse_int(int_fast32_t x, int_fast32_t n) except 0: cdef int_fast32_t mod_pow_int(int_fast32_t base, int_fast32_t exp, int_fast32_t n) noexcept: """ - Returns base^exp mod n + Return base^exp mod n. - For use in IntegerMod_int + For use in ``IntegerMod_int``. EXAMPLES:: @@ -3199,9 +3203,9 @@ cdef int_fast32_t mod_pow_int(int_fast32_t base, int_fast32_t exp, int_fast32_t cdef int jacobi_int(int_fast32_t a, int_fast32_t m) except -2: """ - Calculates the jacobi symbol (a/n) + Calculate the jacobi symbol (a/n). - For use in IntegerMod_int + For use in ``IntegerMod_int``. AUTHORS: @@ -3315,8 +3319,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): cpdef bint is_one(IntegerMod_int64 self) noexcept: """ - Returns ``True`` if this is `1`, otherwise - ``False``. + Return ``True`` if this is `1`, otherwise ``False``. EXAMPLES:: @@ -3329,8 +3332,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def __bool__(IntegerMod_int64 self): """ - Returns ``True`` if this is not `0`, otherwise - ``False``. + Return ``True`` if this is not `0`, otherwise ``False``. EXAMPLES:: @@ -3357,9 +3359,9 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def _crt(IntegerMod_int64 self, IntegerMod_int64 other): """ Use the Chinese Remainder Theorem to find an element of the - integers modulo the product of the moduli that reduces to self and - to other. The modulus of other must be coprime to the modulus of - self. + integers modulo the product of the moduli that reduces to ``self`` and + to ``other``. The modulus of ``other`` must be coprime to the modulus + of ``self``. EXAMPLES:: @@ -3499,7 +3501,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def __lshift__(IntegerMod_int64 self, k): r""" - Performs a left shift by ``k`` bits. + Perform a left shift by ``k`` bits. For details, see :meth:`shift`. @@ -3515,7 +3517,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def __rshift__(IntegerMod_int64 self, k): r""" - Performs a right shift by ``k`` bits. + Perform a right shift by ``k`` bits. For details, see :meth:`shift`. @@ -3529,7 +3531,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): cdef shift(IntegerMod_int64 self, int k): """ - Performs a bit-shift specified by ``k`` on ``self``. + Perform a bit-shift specified by ``k`` on ``self``. Suppose that ``self`` represents an integer `x` modulo `n`. If `k` is `k = 0`, returns `x`. If `k > 0`, shifts `x` to the left, that is, @@ -3541,11 +3543,9 @@ cdef class IntegerMod_int64(IntegerMod_abstract): INPUT: - - ``k`` -- Integer of type ``int`` + - ``k`` -- integer of type ``int`` - OUTPUT: - - - Result of type ``IntegerMod_int64`` + OUTPUT: result of type ``IntegerMod_int64`` WARNING: @@ -3626,7 +3626,6 @@ cdef class IntegerMod_int64(IntegerMod_abstract): sage: zero^0 0 - """ cdef long long_exp cdef int_fast64_t res @@ -3662,7 +3661,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def __invert__(IntegerMod_int64 self): """ - Return the multiplicative inverse of self. + Return the multiplicative inverse of ``self``. EXAMPLES:: @@ -3695,7 +3694,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def __float__(IntegerMod_int64 self): """ - Coerce self to a float. + Coerce ``self`` to a float. EXAMPLES:: @@ -3707,7 +3706,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): def __hash__(self): """ - Compute hash of self. + Compute hash of ``self``. EXAMPLES:: @@ -3729,14 +3728,14 @@ cdef class IntegerMod_int64(IntegerMod_abstract): @coerce_binop def gcd(self, IntegerMod_int64 other): r""" - Greatest common divisor + Greatest common divisor. Returns the "smallest" generator in `\ZZ / N\ZZ` of the ideal generated by ``self`` and ``other``. INPUT: - - ``other`` -- an element of the same ring as this one. + - ``other`` -- an element of the same ring as this one EXAMPLES:: @@ -3776,9 +3775,9 @@ cdef int mpz_pow_helper(mpz_t res, mpz_t base, object exp, mpz_t modulus) except cdef int_fast64_t gcd_int64(int_fast64_t a, int_fast64_t b) noexcept: """ - Returns the gcd of a and b + Return the gcd of ``a`` and ``b``. - For use with IntegerMod_int64 + For use with IntegerMod_int64. AUTHORS: @@ -3798,9 +3797,9 @@ cdef int_fast64_t gcd_int64(int_fast64_t a, int_fast64_t b) noexcept: cdef int_fast64_t mod_inverse_int64(int_fast64_t x, int_fast64_t n) except 0: """ - Returns y such that xy=1 mod n + Return y such that xy=1 mod n. - For use in IntegerMod_int64 + For use in ``IntegerMod_int64``. AUTHORS: @@ -3830,9 +3829,9 @@ cdef int_fast64_t mod_inverse_int64(int_fast64_t x, int_fast64_t n) except 0: cdef int_fast64_t mod_pow_int64(int_fast64_t base, int_fast64_t exp, int_fast64_t n) noexcept: """ - Returns base^exp mod n + Return base^exp mod n. - For use in IntegerMod_int64 + For use in ``IntegerMod_int64``. AUTHORS: @@ -3866,9 +3865,9 @@ cdef int_fast64_t mod_pow_int64(int_fast64_t base, int_fast64_t exp, int_fast64_ cdef int jacobi_int64(int_fast64_t a, int_fast64_t m) except -2: """ - Calculates the jacobi symbol (a/n) + Calculate the jacobi symbol (a/n). - For use in IntegerMod_int64 + For use in ``IntegerMod_int64``. AUTHORS: @@ -3910,7 +3909,7 @@ cdef int jacobi_int64(int_fast64_t a, int_fast64_t m) except -2: def square_root_mod_prime_power(IntegerMod_abstract a, p, e): r""" - Calculates the square root of `a`, where `a` is an + Calculate the square root of `a`, where `a` is an integer mod `p^e`. ALGORITHM: Compute `p`-adically by stripping off even powers of `p` @@ -4006,7 +4005,7 @@ def square_root_mod_prime_power(IntegerMod_abstract a, p, e): cpdef square_root_mod_prime(IntegerMod_abstract a, p=None): r""" - Calculates the square root of `a`, where `a` is an + Calculate the square root of `a`, where `a` is an integer mod `p`; if `a` is not a perfect square, this returns an (incorrect) answer without checking. @@ -4014,19 +4013,17 @@ cpdef square_root_mod_prime(IntegerMod_abstract a, p=None): `p \bmod 16`. - - `p \bmod 2 = 0`: `p = 2` so - `\sqrt{a} = a`. + - `p \bmod 2 = 0`: `p = 2` so `\sqrt{a} = a`. - - `p \bmod 4 = 3`: `\sqrt{a} = a^{(p+1)/4}`. + - `p \bmod 4 = 3`: `\sqrt{a} = a^{(p+1)/4}`. - - `p \bmod 8 = 5`: `\sqrt{a} = \zeta i a` where - `\zeta = (2a)^{(p-5)/8}`, `i=\sqrt{-1}`. + - `p \bmod 8 = 5`: `\sqrt{a} = \zeta i a` where `\zeta = (2a)^{(p-5)/8}`, + `i=\sqrt{-1}`. - - `p \bmod 16 = 9`: Similar, work in a bi-quadratic - extension of `\GF{p}` for small `p`, Tonelli - and Shanks for large `p`. + - `p \bmod 16 = 9`: Similar, work in a bi-quadratic extension of `\GF{p}` + for small `p`, Tonelli and Shanks for large `p`. - - `p \bmod 16 = 1`: Tonelli and Shanks. + - `p \bmod 16 = 1`: Tonelli and Shanks. REFERENCES: @@ -4114,7 +4111,7 @@ cpdef square_root_mod_prime(IntegerMod_abstract a, p=None): def lucas_q1(mm, IntegerMod_abstract P): """ Return `V_k(P, 1)` where `V_k` is the Lucas - function defined by the recursive relation + function defined by the recursive relation. `V_k(P, Q) = PV_{k-1}(P, Q) - QV_{k-2}(P, Q)` @@ -4328,7 +4325,6 @@ cdef class IntegerMod_hom(Morphism): To: Ring of integers modulo 5 sage: psi(R15(7)) 2 - """ Morphism._update_slots(self, _slots) self.zero = _slots['zero'] @@ -4392,7 +4388,6 @@ cdef class IntegerMod_to_IntegerMod(IntegerMod_hom): sage: Zmod(4).hom(Zmod(2)).is_surjective() True - """ return True @@ -4404,14 +4399,12 @@ cdef class IntegerMod_to_IntegerMod(IntegerMod_hom): sage: Zmod(4).hom(Zmod(2)).is_injective() False - """ return self.domain().order() == self.codomain().order() cdef class Integer_to_IntegerMod(IntegerMod_hom): r""" - Fast `\ZZ \rightarrow \ZZ/n\ZZ` - morphism. + Fast `\ZZ \rightarrow \ZZ/n\ZZ` morphism. EXAMPLES: @@ -4463,7 +4456,6 @@ cdef class Integer_to_IntegerMod(IntegerMod_hom): sage: ZZ.hom(Zmod(2)).is_surjective() True - """ return True @@ -4475,7 +4467,6 @@ cdef class Integer_to_IntegerMod(IntegerMod_hom): sage: ZZ.hom(Zmod(2)).is_injective() False - """ return False diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 6876d569e4c..5117119dbf4 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -93,10 +93,9 @@ class IntegerModFactory(UniqueFactory): INPUT: - ``order`` -- integer (default: 0); positive or negative - - ``is_field`` -- bool (default: ``False``); assert that - the order is prime and hence the quotient ring belongs to - the category of fields - - ``category`` (optional) -- the category that the quotient ring belongs to. + - ``is_field`` -- boolean (default: ``False``); assert that the order is + prime and hence the quotient ring belongs to the category of fields + - ``category`` -- (optional) the category that the quotient ring belongs to .. NOTE:: @@ -199,7 +198,6 @@ class IntegerModFactory(UniqueFactory): the ring factory:: sage: IntegerModRing._cache.clear() - """ def get_object(self, version, key, extra_args): out = super().get_object(version, key, extra_args) @@ -289,13 +287,11 @@ class IntegerModRing_generic(quotient_ring.QuotientRing_generic, sage.rings.abc. INPUT: - - ``order`` -- an integer + - ``order`` -- integer - ``category`` -- a subcategory of ``CommutativeRings()`` (the default) - OUTPUT: - - The ring of integers modulo `N`. + OUTPUT: the ring of integers modulo `N` EXAMPLES: @@ -500,7 +496,7 @@ def _macaulay2_init_(self, macaulay2=None): def _axiom_init_(self): """ - Returns a string representation of self in (Pan)Axiom. + Return a string representation of ``self`` in (Pan)Axiom. EXAMPLES:: @@ -575,7 +571,7 @@ def is_prime_field(self): def _precompute_table(self): """ - Computes a table of elements so that elements are unique. + Compute a table of elements so that elements are unique. EXAMPLES:: @@ -680,12 +676,12 @@ def is_field(self, proof=None): INPUT: - - ``proof`` (optional bool or None, default None): - If ``False``, then test whether the category of the quotient - is a subcategory of ``Fields()``, or do a probabilistic - primality test. If ``None``, then test the category and then - do a primality test according to the global arithmetic proof - settings. If True, do a deterministic primality test. + - ``proof`` -- boolean or ``None`` (default). If ``False``, then test + whether the category of the quotient is a subcategory of + ``Fields()``, or do a probabilistic primality test. If ``None``, then + test the category and then do a primality test according to the + global arithmetic proof settings. If ``True``, do a deterministic + primality test. If it is found (perhaps probabilistically) that the ring is a field, then the category of the ring is refined to include the category @@ -717,8 +713,8 @@ def is_field(self, proof=None): and Category of quotients of semigroups It is possible to mistakenly put `\ZZ/n\ZZ` into the category of fields. - In this case, :meth:`is_field` will return True without performing a - primality check. However, if the optional argument `proof=True` is + In this case, :meth:`is_field` will return ``True`` without performing a + primality check. However, if the optional argument ``proof=True`` is provided, primality is tested and the mistake is uncovered in a warning message:: @@ -739,7 +735,6 @@ def is_field(self, proof=None): of the ring factory:: sage: IntegerModRing._cache.clear() - """ from sage.categories.fields import Fields if not proof: @@ -764,7 +759,7 @@ def field(self): """ If this ring is a field, return the corresponding field as a finite field, which may have extra functionality and structure. Otherwise, - raise a ``ValueError``. + raise a :exc:`ValueError`. EXAMPLES:: @@ -926,9 +921,7 @@ def square_roots_of_one(self): Return all square roots of 1 in self, i.e., all solutions to `x^2 - 1 = 0`. - OUTPUT: - - The square roots of 1 in ``self`` as a tuple. + OUTPUT: the square roots of 1 in ``self`` as a tuple EXAMPLES:: @@ -1274,7 +1267,7 @@ def _coerce_map_from_(self, S): def _convert_map_from_(self, other): """ - Conversion from p-adic fields. + Conversion from `p`-adic fields. EXAMPLES:: @@ -1316,7 +1309,6 @@ def __richcmp__(self, other, op): True sage: R2 == GF(5) False - """ # We want that GF(p) and IntegerModRing(p) evaluate unequal. # However, we cannot just compare the types, since the @@ -1333,7 +1325,7 @@ def __richcmp__(self, other, op): def unit_gens(self, **kwds): r""" - Returns generators for the unit group `(\ZZ/N\ZZ)^*`. + Return generators for the unit group `(\ZZ/N\ZZ)^*`. We compute the list of generators using a deterministic algorithm, so the generators list will always be the same. For each odd prime divisor @@ -1341,9 +1333,7 @@ def unit_gens(self, **kwds): even there will be 0, 1 or 2 generators according to whether 2 divides `N` to order 1, 2 or `\geq 3`. - OUTPUT: - - A tuple containing the units of ``self``. + OUTPUT: a tuple containing the units of ``self`` EXAMPLES:: @@ -1374,7 +1364,6 @@ def unit_gens(self, **kwds): (3,) sage: IntegerModRing(8).unit_gens() # needs sage.groups (7, 5) - """ return self.unit_group(**kwds).gens_values() @@ -1509,7 +1498,6 @@ def unit_group(self, algorithm='sage'): Traceback (most recent call last): ... ValueError: unknown algorithm 'bogus' for computing the unit group - """ from sage.groups.abelian_gps.values import AbelianGroupWithValues if algorithm == 'sage': @@ -1536,9 +1524,9 @@ def random_element(self, bound=None): INPUT: - - ``bound``, a positive integer or ``None`` (the default). Is given, + - ``bound`` -- positive integer or ``None`` (the default); if given, return the coercion of an integer in the interval - ``[-bound, bound]`` into this ring. + ``[-bound, bound]`` into this ring EXAMPLES:: diff --git a/src/sage/rings/finite_rings/maps_finite_field.py b/src/sage/rings/finite_rings/maps_finite_field.py index 9c8713f1a61..e68bd5c7b94 100644 --- a/src/sage/rings/finite_rings/maps_finite_field.py +++ b/src/sage/rings/finite_rings/maps_finite_field.py @@ -40,7 +40,6 @@ def _repr_(self): Isomorphism: From: Vector space of dimension 1 over Finite Field in z4 of size 2^4 To: Finite Field in z4 of size 2^4 - """ s = "Isomorphism:" s += "\n From: {}".format(self.domain()) diff --git a/src/sage/rings/finite_rings/meson.build b/src/sage/rings/finite_rings/meson.build new file mode 100644 index 00000000000..896d69651cf --- /dev/null +++ b/src/sage/rings/finite_rings/meson.build @@ -0,0 +1,81 @@ +py.install_sources( + 'all.py', + 'conway_polynomials.py', + 'element_base.pxd', + 'element_givaro.pxd', + 'element_ntl_gf2e.pxd', + 'element_pari_ffelt.pxd', + 'finite_field_base.pxd', + 'finite_field_constructor.py', + 'finite_field_givaro.py', + 'finite_field_ntl_gf2e.py', + 'finite_field_pari_ffelt.py', + 'finite_field_prime_modn.py', + 'galois_group.py', + 'hom_finite_field.pxd', + 'hom_finite_field_givaro.pxd', + 'hom_prime_finite_field.pxd', + 'homset.py', + 'integer_mod.pxd', + 'integer_mod_limits.h', + 'integer_mod_ring.py', + 'maps_finite_field.py', + 'residue_field.pxd', + 'stdint.pxd', + subdir: 'sage/rings/finite_rings', +) + +extension_data = { + 'element_base' : files('element_base.pyx'), + 'element_pari_ffelt' : files('element_pari_ffelt.pyx'), + 'finite_field_base' : files('finite_field_base.pyx'), + 'hom_finite_field' : files('hom_finite_field.pyx'), + 'hom_prime_finite_field' : files('hom_prime_finite_field.pyx'), + 'integer_mod' : files('integer_mod.pyx'), + 'residue_field' : files('residue_field.pyx'), + 'residue_field_givaro' : files('residue_field_givaro.pyx'), + 'residue_field_ntl_gf2e' : files('residue_field_ntl_gf2e.pyx'), + 'residue_field_pari_ffelt' : files('residue_field_pari_ffelt.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/finite_rings', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_ntl, + inc_rings, + inc_rings_finite, + ], + dependencies: [py_dep, cypari2, cysignals, givaro, gmp, m, ntl, pari], + ) +endforeach + +extension_data_cpp = { + 'element_givaro': files('element_givaro.pyx'), + 'element_ntl_gf2e': files('element_ntl_gf2e.pyx'), + 'hom_finite_field_givaro': files('hom_finite_field_givaro.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/finite_rings', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_ntl, + inc_rings, + inc_rings_finite, + ], + dependencies: [py_dep, cypari2, cysignals, givaro, gmp, m, ntl, pari], + ) +endforeach + diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index 7a7fa6dfc23..3146f7fd764 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -182,14 +182,14 @@ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.finite_rings.finite_field_constructor import zech_log_bound, FiniteField as GF from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn -from sage.rings.ideal import is_Ideal +from sage.rings.ideal import Ideal_generic from sage.rings.number_field.number_field_element_base import NumberFieldElement_base from sage.rings.number_field.number_field_ideal import NumberFieldIdeal from sage.rings.fraction_field import FractionField_generic from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.polynomial_element import Polynomial from sage.structure.element cimport Element, parent, Vector @@ -205,17 +205,15 @@ class ResidueFieldFactory(UniqueFactory): INPUT: - - ``p`` -- a prime ideal of an order in a number field. + - ``p`` -- a prime ideal of an order in a number field - - ``names`` -- the variable name for the finite field created. - Defaults to the name of the number field variable but with - bar placed after it. + - ``names`` -- the variable name for the finite field created; + defaults to the name of the number field variable but with + bar placed after it - - ``check`` -- whether or not to check if `p` is prime. + - ``check`` -- whether or not to check if `p` is prime - OUTPUT: - - The residue field at the prime `p`. + OUTPUT: the residue field at the prime `p` EXAMPLES:: @@ -322,7 +320,7 @@ class ResidueFieldFactory(UniqueFactory): Residue field in abar of Fractional ideal (2*a^2 + 3*a - 10) """ if check: - if not is_Ideal(p): + if not isinstance(p, Ideal_generic): if isinstance(p, (int, Integer, Rational)): p = ZZ.ideal(p) elif isinstance(p, NumberFieldElement_base): @@ -339,7 +337,7 @@ class ResidueFieldFactory(UniqueFactory): raise ValueError("p must be an ideal or element of a number field or function field.") if not p.is_prime(): raise ValueError("p (%s) must be prime" % p) - if is_PolynomialRing(p.ring()): + if isinstance(p.ring(), PolynomialRing_general): if not p.ring().base_ring().is_finite(): raise ValueError("residue fields only supported for polynomial rings over finite fields") if not p.ring().base_ring().is_prime_field(): @@ -375,7 +373,7 @@ class ResidueFieldFactory(UniqueFactory): if pring is ZZ: return ResidueFiniteField_prime_modn(p, names, p.gen(), None, None, None) - if is_PolynomialRing(pring): + if isinstance(pring, PolynomialRing_general): K = pring.fraction_field() Kbase = pring.base_ring() f = p.gen() @@ -588,7 +586,6 @@ class ResidueField_generic(Field): Residue field of Integers modulo 17 sage: F(CyclotomicField(49)) Residue field in zbar of Fractional ideal (17) - """ return AlgebraicExtensionFunctor([self.polynomial()], [self.variable_name()], [None], residue=self.p), self.p.ring() @@ -683,7 +680,7 @@ class ResidueField_generic(Field): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coercion map from ``R`` to ``self``. + Return ``True`` if there is a coercion map from ``R`` to ``self``. EXAMPLES:: @@ -716,7 +713,7 @@ class ResidueField_generic(Field): def __repr__(self): """ - Returns a string describing this residue field. + Return a string describing this residue field. EXAMPLES:: @@ -742,7 +739,7 @@ class ResidueField_generic(Field): def lift(self, x): """ - Returns a lift of ``x`` to the Order, returning a "polynomial" in the + Return a lift of ``x`` to the Order, returning a "polynomial" in the generator with coefficients between 0 and `p-1`. EXAMPLES:: @@ -822,7 +819,7 @@ class ResidueField_generic(Field): def lift_map(self): """ - Returns the standard map from this residue field up to the ring of + Return the standard map from this residue field up to the ring of integers lifting the canonical projection. EXAMPLES:: @@ -864,7 +861,7 @@ class ResidueField_generic(Field): def _richcmp_(self, x, op): """ - Compares two residue fields: they are equal iff the primes + Compare two residue fields: they are equal iff the primes defining them are equal and they have the same variable name. EXAMPLES:: @@ -925,7 +922,7 @@ cdef class ReductionMap(Map): A reduction map from a (subset) of a number field or function field to this residue class field. - It will be defined on those elements of the field with non-negative + It will be defined on those elements of the field with nonnegative valuation at the specified prime. EXAMPLES:: @@ -1063,7 +1060,7 @@ cdef class ReductionMap(Map): field. If ``x`` doesn't map because it has negative valuation, then a - ``ZeroDivisionError`` exception is raised. + :exc:`ZeroDivisionError` exception is raised. EXAMPLES:: @@ -1178,7 +1175,7 @@ cdef class ReductionMap(Map): def section(self): """ - Computes a section of the map, namely a map that lifts elements of the + Compute a section of the map, namely a map that lifts elements of the residue field to elements of the field. EXAMPLES:: @@ -1267,11 +1264,11 @@ cdef class ResidueFieldHomomorphism_global(RingHomomorphism): INPUT: - - ``k`` -- The residue field that is the codomain of this morphism + - ``k`` -- the residue field that is the codomain of this morphism - - ``p`` -- The prime ideal defining this residue field + - ``p`` -- the prime ideal defining this residue field - - ``im_gen`` -- The image of the generator of the number field + - ``im_gen`` -- the image of the generator of the number field EXAMPLES: @@ -1403,7 +1400,7 @@ cdef class ResidueFieldHomomorphism_global(RingHomomorphism): # No special code for residue fields of Z, since we just use the normal reduction map to GF(p) if self._K is ZZ: return self._F(x) - if is_PolynomialRing(self._K): + if isinstance(self._K, PolynomialRing_general): p = self._F.p.gen() if p.degree() == 1: return self._F((x % p)[0]) @@ -1414,7 +1411,7 @@ cdef class ResidueFieldHomomorphism_global(RingHomomorphism): def section(self): """ - Computes a section of the map, namely a map that lifts elements of + Compute a section of the map, namely a map that lifts elements of the residue field to elements of the ring of integers. EXAMPLES:: @@ -1461,7 +1458,7 @@ cdef class ResidueFieldHomomorphism_global(RingHomomorphism): def lift(self, x): """ - Returns a lift of ``x`` to the Order, returning a "polynomial" in + Return a lift of ``x`` to the Order, returning a "polynomial" in the generator with coefficients between 0 and `p-1`. EXAMPLES:: @@ -1661,7 +1658,7 @@ cdef class LiftingMap(Section): return self._K(self._K.ring_of_integers()(x)) else: return self._K(self._K.ring_of_integers()(x.polynomial().list())) - elif is_PolynomialRing(self._K): + elif isinstance(self._K, PolynomialRing_general): return self._K(x.polynomial().list()) # Else the lifting map is just x |--> to_order(x * PB) x = self._F(x) @@ -1730,7 +1727,7 @@ class ResidueFiniteField_prime_modn(ResidueField_generic, FiniteField_prime_modn INPUT: - - ``p`` -- A prime ideal of a number field + - ``p`` -- a prime ideal of a number field - ``name`` -- the name of the generator of this extension @@ -1780,7 +1777,7 @@ class ResidueFiniteField_prime_modn(ResidueField_generic, FiniteField_prime_modn INPUT: - - ``x`` -- something to cast in to ``self``. + - ``x`` -- something to cast in to ``self`` EXAMPLES:: diff --git a/src/sage/rings/finite_rings/residue_field_givaro.pyx b/src/sage/rings/finite_rings/residue_field_givaro.pyx index a00bc5138fd..84e78622760 100644 --- a/src/sage/rings/finite_rings/residue_field_givaro.pyx +++ b/src/sage/rings/finite_rings/residue_field_givaro.pyx @@ -71,7 +71,7 @@ class ResidueFiniteField_givaro(ResidueField_generic, FiniteField_givaro): - ``to_order`` -- the map from a lattice in that vector space to the maximal order - - ``PB`` -- a matrix used in defining the reduction and lifting maps. + - ``PB`` -- a matrix used in defining the reduction and lifting maps EXAMPLES:: @@ -104,7 +104,7 @@ class ResidueFiniteField_givaro(ResidueField_generic, FiniteField_givaro): """ INPUT: - - ``x`` -- Something to cast into ``self``. + - ``x`` -- something to cast into ``self`` EXAMPLES:: diff --git a/src/sage/rings/finite_rings/residue_field_ntl_gf2e.pyx b/src/sage/rings/finite_rings/residue_field_ntl_gf2e.pyx index 5071bc87137..eb0620e3ba1 100644 --- a/src/sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/residue_field_ntl_gf2e.pyx @@ -110,7 +110,7 @@ class ResidueFiniteField_ntl_gf2e(ResidueField_generic, FiniteField_ntl_gf2e): """ INPUT: - - ``x`` -- Something to cast into ``self``. + - ``x`` -- something to cast into ``self`` EXAMPLES:: diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index 756cbbc9efc..4e3e923c263 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -101,9 +101,9 @@ def FractionField(R, names=None): INPUT: - - ``R`` -- an integral domain + - ``R`` -- an integral domain - - ``names`` -- ignored + - ``names`` -- ignored EXAMPLES: @@ -178,7 +178,7 @@ def __init__(self, R, INPUT: - - ``R`` -- an integral domain + - ``R`` -- an integral domain EXAMPLES:: @@ -187,14 +187,20 @@ def __init__(self, R, sage: Frac(QQ['x,y']).variable_names() ('x', 'y') sage: category(Frac(QQ['x'])) - Category of quotient fields + Category of infinite quotient fields + + TESTS:: + + sage: F = FractionField(QQ['x']) + sage: F.cardinality() + +Infinity """ self._R = R self._element_class = element_class cat = category - if self in Rings().Infinite(): + if R in Rings().Infinite(): cat = cat.Infinite() - elif self in Rings().Finite(): + elif R in Rings().Finite(): cat = cat.Finite() Parent.__init__(self, base=R, names=R._names, category=cat) @@ -392,11 +398,9 @@ def _number_field_to_frac_of_ring_of_integers(self, x): INPUT: - - ``x`` -- Number field element + - ``x`` -- number field element - OUTPUT: - - - Element of ``self`` + OUTPUT: Element of ``self`` TESTS: @@ -440,7 +444,6 @@ def is_finite(self): sage: Frac(QQ['a','b','c']).is_finite() False - """ return self._R.is_finite() @@ -1043,7 +1046,6 @@ def _factor_univariate_polynomial(self, f): sage: f = x^3 + a sage: f.factor() (x + 2*a + 1)^3 - """ # The default implementation would try to convert this element to singular and factor there. # This fails silently over some base fields, see #23642, so we convert @@ -1064,7 +1066,6 @@ def function_field(self): .. SEEALSO:: :meth:`sage.rings.function_field.RationalFunctionField.field` - """ from sage.rings.function_field.constructor import FunctionField return FunctionField(self.base_ring(), names=self.variable_name()) @@ -1086,7 +1087,6 @@ def _coerce_map_from_(self, R): over Finite Field of size 5 sage: f(~L.gen()) 1/t - """ from sage.rings.function_field.function_field_rational import ( RationalFunctionField, @@ -1127,7 +1127,6 @@ class FractionFieldEmbedding(DefaultConvertMap_unique): True sage: R.is_subring(R.fraction_field()) True - """ def is_surjective(self): r""" @@ -1138,7 +1137,6 @@ def is_surjective(self): sage: R. = QQ[] sage: R.fraction_field().coerce_map_from(R).is_surjective() False - """ return self.domain().is_field() @@ -1154,7 +1152,6 @@ def is_injective(self): sage: R. = QQ[] sage: R.fraction_field().coerce_map_from(R).is_injective() True - """ return True @@ -1169,7 +1166,6 @@ def section(self): Section map: From: Fraction Field of Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in x over Rational Field - """ from sage.categories.homset import Hom from sage.categories.sets_with_partial_maps import SetsWithPartialMaps @@ -1191,7 +1187,6 @@ def _richcmp_(self, other, op): False sage: f == f True - """ if type(self) is not type(other): return NotImplemented @@ -1206,7 +1201,6 @@ def __hash__(self): sage: R. = QQ[] sage: hash(R.fraction_field().coerce_map_from(R)) == hash(R.fraction_field().coerce_map_from(R)) True - """ return hash((type(self), self.domain())) @@ -1230,7 +1224,6 @@ class FractionFieldEmbeddingSection(Section): sage: isinstance(f, FractionFieldEmbeddingSection) True sage: TestSuite(f).run() - """ def _call_(self, x, check=True): r""" @@ -1324,7 +1317,6 @@ def _richcmp_(self, other, op): False sage: f == f True - """ if type(self) is not type(other): return NotImplemented @@ -1339,6 +1331,5 @@ def __hash__(self): sage: R. = QQ[] sage: hash(R.fraction_field().coerce_map_from(R).section()) == hash(R.fraction_field().coerce_map_from(R).section()) True - """ return hash((type(self), self.codomain())) diff --git a/src/sage/rings/fraction_field_FpT.pyx b/src/sage/rings/fraction_field_FpT.pyx index b3ae363d9ae..5317c1551fb 100644 --- a/src/sage/rings/fraction_field_FpT.pyx +++ b/src/sage/rings/fraction_field_FpT.pyx @@ -115,9 +115,11 @@ cdef class FpTElement(FieldElement): """ INPUT: - - parent -- the Fraction field containing this element - - numer -- something that can be converted into the polynomial ring, giving the numerator - - denom -- something that can be converted into the polynomial ring, giving the numerator (default 1) + - ``parent`` -- the Fraction field containing this element + - ``numer`` -- something that can be converted into the polynomial + ring, giving the numerator + - ``denom`` -- something that can be converted into the polynomial + ring, giving the numerator (default: 1) EXAMPLES:: @@ -173,7 +175,8 @@ cdef class FpTElement(FieldElement): cdef FpTElement _new_c(self): """ - Creates a new FpTElement in the same field, leaving the value to be initialized. + Create a new FpTElement in the same field, leaving the value to be + initialized. """ cdef FpTElement x = FpTElement.__new__(FpTElement) x._parent = self._parent @@ -185,7 +188,8 @@ cdef class FpTElement(FieldElement): cdef FpTElement _copy_c(self): """ - Creates a new FpTElement in the same field, with the same value as self. + Create a new FpTElement in the same field, with the same value as + ``self``. """ cdef FpTElement x = FpTElement.__new__(FpTElement) x._parent = self._parent @@ -295,7 +299,7 @@ cdef class FpTElement(FieldElement): def valuation(self, v): """ - Return the valuation of self at `v`. + Return the valuation of ``self`` at `v`. EXAMPLES:: @@ -444,7 +448,7 @@ cdef class FpTElement(FieldElement): def __neg__(self): """ - Negates this element. + Negate this element. EXAMPLES:: @@ -768,12 +772,12 @@ cdef class FpTElement(FieldElement): INPUT: - - ``extend`` -- bool (default: ``True``); if True, return a - square root in an extension ring, if necessary. Otherwise, raise a - ValueError if the square is not in the base ring. + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the square is not in the base ring. - - ``all`` -- bool (default: ``False``); if True, return all - square roots of self, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of self, instead of just one EXAMPLES:: @@ -802,7 +806,7 @@ cdef class FpTElement(FieldElement): def __pow__(FpTElement self, Py_ssize_t e, dummy): r""" - Return the ``e``th power of this element. + Return the `e`-th power of this element. EXAMPLES:: @@ -886,11 +890,12 @@ cdef class FpT_iter: """ INPUT: - - parent -- The FpT that we're iterating over. + - ``parent`` -- the FpT that we're iterating over - - degree -- The maximum degree of the numerator and denominator of the elements over which we iterate. + - ``degree`` -- the maximum degree of the numerator and denominator of + the elements over which we iterate - - start -- (default 0) The element on which to start. + - ``start`` -- (default: 0) the element on which to start EXAMPLES:: @@ -1029,7 +1034,7 @@ cdef class FpT_iter: cdef class Polyring_FpT_coerce(RingHomomorphism): """ - This class represents the coercion map from GF(p)[t] to GF(p)(t) + This class represents the coercion map from GF(p)[t] to GF(p)(t). EXAMPLES:: @@ -1045,7 +1050,6 @@ cdef class Polyring_FpT_coerce(RingHomomorphism): TESTS:: TestSuite(f).run() - """ cdef long p @@ -1053,7 +1057,7 @@ cdef class Polyring_FpT_coerce(RingHomomorphism): """ INPUT: - - R -- An FpT + - ``R`` -- an FpT EXAMPLES:: @@ -1218,7 +1222,7 @@ cdef class Polyring_FpT_coerce(RingHomomorphism): cdef class FpT_Polyring_section(Section): """ - This class represents the section from GF(p)(t) back to GF(p)[t] + This class represents the section from GF(p)(t) back to GF(p)[t]. EXAMPLES:: @@ -1246,7 +1250,6 @@ cdef class FpT_Polyring_section(Section): TESTS:: sage: TestSuite(f).run(skip='_test_pickling') - """ cdef long p @@ -1254,7 +1257,7 @@ cdef class FpT_Polyring_section(Section): """ INPUT: - - f -- A Polyring_FpT_coerce homomorphism + - ``f`` -- a Polyring_FpT_coerce homomorphism EXAMPLES:: @@ -1347,7 +1350,7 @@ cdef class FpT_Polyring_section(Section): cdef class Fp_FpT_coerce(RingHomomorphism): """ - This class represents the coercion map from GF(p) to GF(p)(t) + This class represents the coercion map from GF(p) to GF(p)(t). EXAMPLES:: @@ -1363,7 +1366,6 @@ cdef class Fp_FpT_coerce(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ cdef long p @@ -1371,7 +1373,7 @@ cdef class Fp_FpT_coerce(RingHomomorphism): """ INPUT: - - R -- An FpT + - ``R`` -- an FpT EXAMPLES:: @@ -1520,7 +1522,7 @@ cdef class Fp_FpT_coerce(RingHomomorphism): cdef class FpT_Fp_section(Section): """ - This class represents the section from GF(p)(t) back to GF(p)[t] + This class represents the section from GF(p)(t) back to GF(p)[t]. EXAMPLES:: @@ -1548,8 +1550,6 @@ cdef class FpT_Fp_section(Section): TESTS:: sage: TestSuite(f).run(skip='_test_pickling') - - """ cdef long p @@ -1557,7 +1557,7 @@ cdef class FpT_Fp_section(Section): """ INPUT: - - f -- An Fp_FpT_coerce homomorphism + - ``f`` -- an ``Fp_FpT_coerce`` homomorphism EXAMPLES:: @@ -1669,7 +1669,7 @@ cdef class FpT_Fp_section(Section): cdef class ZZ_FpT_coerce(RingHomomorphism): """ - This class represents the coercion map from ZZ to GF(p)(t) + This class represents the coercion map from ZZ to GF(p)(t). EXAMPLES:: @@ -1685,7 +1685,6 @@ cdef class ZZ_FpT_coerce(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ cdef long p @@ -1693,7 +1692,7 @@ cdef class ZZ_FpT_coerce(RingHomomorphism): """ INPUT: - - R -- An FpT + - ``R`` -- an FpT EXAMPLES:: @@ -1909,7 +1908,7 @@ cdef inline void nmod_poly_inc(nmod_poly_t poly, bint monic) noexcept: """ Set poly to the "next" polynomial: this is just counting in base p. - If monic is True then will only iterate through monic polynomials. + If monic is ``True`` then will only iterate through monic polynomials. """ cdef long n cdef long a diff --git a/src/sage/rings/fraction_field_element.pyx b/src/sage/rings/fraction_field_element.pyx index e651a0bf560..3d14ab66134 100644 --- a/src/sage/rings/fraction_field_element.pyx +++ b/src/sage/rings/fraction_field_element.pyx @@ -113,7 +113,6 @@ cdef class FractionFieldElement(FieldElement): (x + 1)/(x^2 + x + 1) sage: K(355/113) 355/113 - """ FieldElement.__init__(self, parent) if coerce: @@ -264,7 +263,6 @@ cdef class FractionFieldElement(FieldElement): """ return self._denominator - def is_square(self,root=False): """ Return whether or not ``self`` is a perfect square. @@ -275,15 +273,15 @@ cdef class FractionFieldElement(FieldElement): INPUT: - - ``root`` -- whether or not to also return a square - root (default: ``False``) + - ``root`` -- whether or not to also return a square + root (default: ``False``) OUTPUT: - - ``bool`` -- whether or not a square + - boolean; whether or not a square - - ``object`` -- (optional) an actual square root if - found, and None otherwise. + - object (optional); an actual square root if found, and ``None`` + otherwise EXAMPLES:: @@ -600,9 +598,7 @@ cdef class FractionFieldElement(FieldElement): - ``right`` -- ``ModuleElement`` to add to ``self`` - OUTPUT: - - - Sum of ``self`` and ``right`` + OUTPUT: sum of ``self`` and ``right`` EXAMPLES:: @@ -679,15 +675,13 @@ cdef class FractionFieldElement(FieldElement): cpdef _mul_(self, right): """ - Computes the product of ``self`` and ``right``. + Compute the product of ``self`` and ``right``. INPUT: - ``right`` -- ``RingElement`` to multiply with ``self`` - OUTPUT: - - - Product of ``self`` and ``right`` + OUTPUT: product of ``self`` and ``right`` EXAMPLES:: @@ -745,15 +739,13 @@ cdef class FractionFieldElement(FieldElement): cpdef _div_(self, right): """ - Computes the quotient of ``self`` and ``right``. + Compute the quotient of ``self`` and ``right``. INPUT: - ``right`` -- ``RingElement`` that is the divisor - OUTPUT: - - Quotient of ``self`` and ``right`` + OUTPUT: quotient of ``self`` and ``right`` EXAMPLES:: @@ -828,7 +820,7 @@ cdef class FractionFieldElement(FieldElement): def _conversion(self, R): r""" - Generic conversion + Generic conversion. TESTS:: @@ -891,7 +883,7 @@ cdef class FractionFieldElement(FieldElement): def __pow__(self, right, dummy): r""" - Returns self raised to the `right^{th}` power. + Return ``self`` raised to the ``right``-th power. Note that we need to check whether or not right is negative so we don't set ``_numerator`` or ``_denominator`` to an element of the @@ -1184,7 +1176,7 @@ cdef class FractionFieldElement(FieldElement): def specialization(self, D=None, phi=None): """ - Returns the specialization of a fraction element of a polynomial ring + Return the specialization of a fraction element of a polynomial ring. """ numerator = self.numerator().specialization(D, phi) denominator = self.denominator().specialization(D, phi) @@ -1225,7 +1217,7 @@ cdef class FractionFieldElement_1poly_field(FractionFieldElement): def is_integral(self): """ - Returns whether this element is actually a polynomial. + Return whether this element is actually a polynomial. EXAMPLES:: @@ -1245,7 +1237,7 @@ cdef class FractionFieldElement_1poly_field(FractionFieldElement): def support(self): """ - Returns a sorted list of primes dividing either the numerator or + Return a sorted list of primes dividing either the numerator or denominator of this element. EXAMPLES:: @@ -1262,7 +1254,7 @@ cdef class FractionFieldElement_1poly_field(FractionFieldElement): cpdef reduce(self): """ - Pick a normalized representation of self. + Pick a normalized representation of ``self``. In particular, for any a == b, after normalization they will have the same numerator and denominator. @@ -1286,6 +1278,7 @@ cdef class FractionFieldElement_1poly_field(FractionFieldElement): super(self.__class__, self).reduce() self.normalize_leading_coefficients() + def make_element(parent, numerator, denominator): """ Used for unpickling :class:`FractionFieldElement` objects (and subclasses). diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index 8eb407d1552..a316c384bd1 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -167,7 +167,6 @@ def create_key(self,polynomial,names): sage: N. = K.extension(z - 1) sage: M is N False - """ if names is None: names = polynomial.variable_name() diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index 2e0fe91a968..952d5813dd6 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -229,7 +229,6 @@ def _call_(self, x): 1 sage: d(y^2) 0 - """ if x.is_zero(): return self.codomain().zero() diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index 4442a63bd22..8f841180532 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -247,7 +247,7 @@ def _add_(self, other): def _div_(self, other): """ - Return the quotient of ``self`` and ``other`` + Return the quotient of ``self`` and ``other``. INPUT: @@ -427,9 +427,7 @@ def residue(self, place): - ``place`` -- a place of the function field - OUTPUT: - - - an element of the residue field of the place + OUTPUT: an element of the residue field of the place EXAMPLES: @@ -472,7 +470,6 @@ def residue(self, place): sage: d = w.divisor() sage: sum([QQ(w.residue(p)) for p in d.support()]) 0 - """ R,fr_R,to_R = place._residue_field() diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 30d99d920d4..13247abe3b0 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -132,7 +132,7 @@ class FunctionFieldDivisor(ModuleElement): - ``parent`` -- divisor group - - ``data`` -- dict of place and multiplicity pairs + - ``data`` -- dictionary of place and multiplicity pairs EXAMPLES:: @@ -467,7 +467,7 @@ def multiplicity(self, place): def is_effective(self): """ - Return ``True`` if this divisor has non-negative multiplicity at all + Return ``True`` if this divisor has nonnegative multiplicity at all places. EXAMPLES:: diff --git a/src/sage/rings/function_field/drinfeld_modules/action.py b/src/sage/rings/function_field/drinfeld_modules/action.py index 6fca6225d60..4962162424e 100644 --- a/src/sage/rings/function_field/drinfeld_modules/action.py +++ b/src/sage/rings/function_field/drinfeld_modules/action.py @@ -85,7 +85,9 @@ def __init__(self, drinfeld_module): """ Initialize ``self``. - INPUT: the Drinfeld module + INPUT: + + - ``drinfeld_module`` -- the Drinfeld module TESTS:: @@ -142,7 +144,7 @@ def _latex_(self): r""" Return a LaTeX representation of the action. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -162,7 +164,7 @@ def _repr_(self): r""" Return a string representation of the action. - OUTPUT: a string + OUTPUT: string EXAMPLES:: diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 34644aef4a4..d183848f296 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -121,7 +121,7 @@ def _compute_coefficient_exp(self, k): INPUT: - - ``k`` (integer) -- the index of the coefficient + - ``k`` -- integer; the index of the coefficient TESTS:: @@ -157,12 +157,10 @@ def exponential(self, name='z'): INPUT: - - ``name`` (string, default: ``'z'``) -- the name of the - generator of the lazy power series ring. + - ``name`` -- string (default: ``'z'``); the name of the + generator of the lazy power series ring - OUTPUT: - - A lazy power series over the base field. + OUTPUT: a lazy power series over the base field EXAMPLES:: @@ -276,12 +274,10 @@ def logarithm(self, name='z'): INPUT: - - ``name`` (string, default: ``'z'``) -- the name of the - generator of the lazy power series ring. - - OUTPUT: + - ``name`` -- string (default: ``'z'``); the name of the + generator of the lazy power series ring - A lazy power series over the base field. + OUTPUT: a lazy power series over the base field EXAMPLES:: @@ -319,7 +315,6 @@ def logarithm(self, name='z'): True sage: log[2**3] == -1/((T**q - T)*(T**(q**2) - T)*(T**(q**3) - T)) # expected value True - """ L = LazyPowerSeriesRing(self._base, name) zero = self._base.zero() @@ -358,7 +353,6 @@ def _compute_goss_polynomial(self, n, q, poly_ring, X): X^12 sage: phi._compute_goss_polynomial(9, 2^2, poly_ring, X) X^9 + (1/(T^3 + T^2 + T))*X^6 + (1/(T^6 + T^4 + T^2))*X^3 - """ # Trivial cases if n.is_zero(): @@ -386,14 +380,12 @@ def goss_polynomial(self, n, var='X'): INPUT: - - ``n`` (integer) -- the index of the Goss polynomial - - - ``var`` (str, default: ``'X'``) -- the name of polynomial - variable. + - ``n`` -- integer; the index of the Goss polynomial - OUTPUT: + - ``var``-- string (default: ``'X'``); the name of polynomial + variable - - a univariate polynomial in ``var`` over the base `A`-field. + OUTPUT: a univariate polynomial in ``var`` over the base `A`-field EXAMPLES:: diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 55b4cfab326..d225820ab18 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -125,7 +125,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` (default: ``'t'``) -- the name of the Ore polynomial ring + - ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring generator .. RUBRIC:: Construction @@ -533,12 +533,10 @@ def __classcall_private__(cls, function_ring, gen, name='t'): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` (default: ``'t'``) -- the name of the Ore polynomial + - ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring gen - OUTPUT: - - A DrinfeldModule or DrinfeldModule_finite. + OUTPUT: a DrinfeldModule or DrinfeldModule_finite TESTS:: @@ -645,7 +643,7 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` (default: ``'t'``) -- the name of the Ore polynomial + - ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring gen TESTS:: @@ -759,27 +757,6 @@ def _Hom_(self, other, category): from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset return DrinfeldModuleHomset(self, other, category) - def _check_rank_two(self): - r""" - Raise ``NotImplementedError`` if the rank is not two. - - TESTS:: - - sage: Fq = GF(25) - sage: A. = Fq[] - sage: K. = Fq.extension(6) - sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 - sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) - sage: phi._check_rank_two() - sage: phi = DrinfeldModule(A, [p_root, 1]) - sage: phi._check_rank_two() - Traceback (most recent call last): - ... - NotImplementedError: rank must be 2 - """ - if self.rank() != 2: - raise NotImplementedError('rank must be 2') - def _latex_(self): r""" Return a LaTeX representation of the Drinfeld module. @@ -914,15 +891,15 @@ def basic_j_invariant_parameters(self, coeff_indices=None, nonzero=False): INPUT: - - ``coeff_indices`` (list or tuple, or NoneType; default: - ``None``) -- indices of the Drinfeld module generator + - ``coeff_indices`` -- list or tuple, or NoneType (default: + ``None``); indices of the Drinfeld module generator coefficients to be considered in the computation. If the parameter is ``None`` (default), all the coefficients are involved. - - ``nonzero`` (boolean, default: ``False``) -- if this flag + - ``nonzero``-- boolean (default: ``False``); if this flag is set to ``True``, then only the parameters for which the - corresponding basic `j`-invariant is nonzero are returned. + corresponding basic `j`-invariant is nonzero are returned .. WARNING:: @@ -1091,9 +1068,9 @@ def basic_j_invariants(self, nonzero=False): INPUT: - - ``nonzero`` (boolean, default: ``False``) -- if this flag + - ``nonzero``-- boolean (default: ``False``); if this flag is set to ``True``, then only the parameters for which the - corresponding basic `j`-invariant is nonzero are returned. + corresponding basic `j`-invariant is nonzero are returned .. WARNING:: @@ -1145,7 +1122,7 @@ def coefficient(self, n): INPUT: - - ``n`` -- a nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: an element in the base codomain @@ -1184,7 +1161,7 @@ def coefficients(self, sparse=True): INPUT: - - ``sparse`` -- a boolean + - ``sparse`` -- boolean EXAMPLES:: @@ -1236,7 +1213,7 @@ def gen(self): def height(self): r""" Return the height of the Drinfeld module if the function field - characteristic is a prime ideal; raise ValueError otherwise. + characteristic is a prime ideal; raise :exc:`ValueError` otherwise. The height of a Drinfeld module is defined when the function field characteristic is a prime ideal. In our case, this ideal @@ -1294,7 +1271,6 @@ def height(self): Traceback (most recent call last): ... NotImplementedError: height not implemented in this case - """ try: if self.characteristic().is_zero(): @@ -1313,9 +1289,9 @@ def is_isomorphic(self, other, absolutely=False): INPUT: - - ``absolutely`` -- a boolean (default: ``False``); if ``True``, + - ``absolutely`` -- a boolean (default: ``False``); if ``False``, check the existence of an isomorphism defined on the base - field; if ``False``, check over an algebraic closure. + field. If ``True``, check over an algebraic closure. EXAMPLES:: @@ -1349,6 +1325,18 @@ def is_isomorphic(self, other, absolutely=False): sage: phi.is_isomorphic(psi, absolutely=True) True + In particular, two Drinfeld modules may have the same + `j`-invariant, while not being isomorphic on the base field:: + + sage: phi = DrinfeldModule(A, [z, 0, 1]) + sage: psi = DrinfeldModule(A, [z, 0, z]) + sage: phi.j_invariant() == psi.j_invariant() + True + sage: phi.is_isomorphic(psi) + False + sage: phi.is_isomorphic(psi, absolutely=True) + True + On certain fields, testing isomorphisms over the base field may fail:: @@ -1532,8 +1520,8 @@ def j_invariant(self, parameter=None, check=True): INPUT: - - ``parameter`` (tuple or list, integer or NoneType; default: - ``None``) -- the `j`-invariant parameter: + - ``parameter`` -- tuple or list, integer or NoneType (default: + ``None``); the `j`-invariant parameter: - If ``parameter`` is a list or a tuple, then it must be of the form: @@ -1550,11 +1538,11 @@ def j_invariant(self, parameter=None, check=True): `j`-invariant, that is the `j`-invariant for the parameter `((1,), (q+1, 1))`. - - ``check`` (bool, default: ``True``) -- if this flag is set to + - ``check`` -- boolean (default: ``True``); if this flag is set to ``False`` then the code will not check if the given parameter is valid and satisfy the weight-0 condition. - OUTPUT: the `j`-invariant of ``self`` for the given parameter. + OUTPUT: the `j`-invariant of ``self`` for the given parameter EXAMPLES:: @@ -1743,13 +1731,13 @@ def jk_invariants(self): `1 \leqslant k \leqslant r-1` and the values are the corresponding `j_k`-invariants - Recall that the `j_k`-invariant of self is defined by: + Recall that the `j_k`-invariant of ``self`` is defined by: .. MATH:: j_k := \frac{g_k^{(q^r - 1)/(\mathrm{gcd}(k, r) - 1)}}{g_r^{(q^k - 1)/(\mathrm{gcd}(k, r) - 1)}} - where `g_i` is the `i`-th coefficient of the generator of self. + where `g_i` is the `i`-th coefficient of the generator of ``self``. EXAMPLES:: @@ -1832,7 +1820,7 @@ def rank(self): In our case, the rank is the degree of the generator. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -2029,7 +2017,6 @@ def hom(self, x, codomain=None): Traceback (most recent call last): ... ValueError: Ore polynomial does not define a morphism - """ # When `x` is in the function ring (or something that coerces to it): if self.function_ring().has_coerce_map_from(x.parent()): @@ -2075,7 +2062,6 @@ def scalar_multiplication(self, x): sage: phi.hom(T^2 + 1) Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1 - """ if not self.function_ring().has_coerce_map_from(x.parent()): raise ValueError("%s is not element of the function ring" % x) diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 470dfc495d7..2269085539d 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -125,7 +125,7 @@ class DrinfeldModule_finite(DrinfeldModule): def __init__(self, gen, category): """ - Initialize `self`. + Initialize ``self``. Validity of the input is checked in `__classcall_private__`. The `__init__` just saves attributes. @@ -138,7 +138,7 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module as a list of coefficients or an Ore polynomial - - ``name`` (default: `'t'`) -- the name of the Ore polynomial + - ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring gen TESTS:: @@ -162,7 +162,7 @@ def __init__(self, gen, category): self._frobenius_trace = None self._frobenius_charpoly = None - def _frobenius_crystalline_matrix(self): + def _frobenius_matrix_crystalline(self): r""" Return the matrix representing the Frobenius endomorphism on the crystalline cohomology of the Drinfeld module. This is done up to @@ -180,7 +180,7 @@ def _frobenius_crystalline_matrix(self): sage: K. = Fq.extension(6) sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) - sage: phi._frobenius_crystalline_matrix() + sage: phi._frobenius_matrix_crystalline() [...((z2 + 3) + z12 + (4*z2 + 1)*z12^2 + (z2 + 4)*z12^3 + (z2 + 4)*z12^4 + (2*z2 + 3)*z12^5)*T^3 + (2*z2 + 2*z2*z12 + (2*z2 + 3)*z12^2 + ... + (3*z2 + 4)*z12^3 + (2*z2 + 3)*z12^4 + 3*z2*z12^5] ALGORITHM: @@ -257,7 +257,7 @@ def frobenius_endomorphism(self): deg = self.base_over_constants_field().degree_over() return self._Hom_(self, category=self.category())(t**deg) - def frobenius_charpoly(self, var='X', algorithm='crystalline'): + def frobenius_charpoly(self, var='X', algorithm=None): r""" Return the characteristic polynomial of the Frobenius endomorphism. @@ -291,9 +291,29 @@ def frobenius_charpoly(self, var='X', algorithm='crystalline'): INPUT: - ``var`` (default: ``'X'``) -- the name of the second variable - - ``algorithm`` (default: ``'crystalline'``) -- the algorithm + - ``algorithm`` (default: ``None``) -- the algorithm used to compute the characteristic polynomial + .. NOTE: + + Available algorithms are: + + - ``'CSA'`` -- it exploits the fact that `K\{\tau\}` is a + central simple algebra (CSA) over `\mathbb + F_q[\text{Frob}_\phi]` (see Chapter 4 of [CL2023]_). + - ``'crystalline'`` -- it uses the action of the Frobenius + on the crystalline cohomology (see [MS2023]_). + - ``'gekeler'`` -- it tries to identify coefficients by + writing that the characteristic polynomial annihilates the + Frobenius endomorphism; this algorithm may fail is some + cases (see [Gek2008]_). + - ``'motive'`` -- it uses the action of the Frobenius on the + Anderson motive (see Chapter 2 of [CL2023]_). + + The method raises an exception if the user asks for an + unimplemented algorithm, even if the characteristic polynomial + has already been computed. + EXAMPLES:: sage: Fq = GF(25) @@ -310,7 +330,7 @@ def frobenius_charpoly(self, var='X', algorithm='crystalline'): sage: A. = Fq[] sage: K. = Fq.extension(2) sage: phi = DrinfeldModule(A, [1, 0, z6]) - sage: chi = phi.frobenius_charpoly() + sage: chi = phi.frobenius_charpoly(algorithm='crystalline') sage: chi X^2 + ((3*z3^2 + z3 + 4)*T + 4*z3^2 + 6*z3 + 3)*X + (5*z3^2 + 2*z3)*T^2 + (4*z3^2 + 3*z3)*T + 5*z3^2 + 2*z3 @@ -319,6 +339,9 @@ def frobenius_charpoly(self, var='X', algorithm='crystalline'): sage: frob_pol = phi.frobenius_endomorphism().ore_polynomial() sage: chi(frob_pol, phi(T)) 0 + sage: phi.frobenius_charpoly(algorithm='motive')(phi.frobenius_endomorphism()) + Endomorphism of Drinfeld module defined by T |--> z6*t^2 + 1 + Defn: 0 :: @@ -329,33 +352,99 @@ def frobenius_charpoly(self, var='X', algorithm='crystalline'): ALGORITHM: - By default, this method uses the so-called *crystalline* - algorithm which computes the characteristic polynomial of the - Frobenius acting on the crystalline cohomology of the Drinfeld - module. For further details, see [Ang1997]_. + If the user specifies an algorithm, then the characteristic + polynomial is computed according to the user's input (see + the note above), even if it had already been computed. + + If no algorithm is given, then the function either returns a + cached value, or if no cached value is available, the + function computes the Frobenius characteristic polynomial + from scratch. In that case, if the rank `r` is less than the + extension degree `n`, then the ``crystalline`` algorithm is + used, while the ``CSA`` algorithm is used otherwise. + + TESTS:: + + sage: Fq = GF(9) + sage: A. = Fq[] + sage: k. = Fq.extension(2) + sage: K. = k.extension(3) + + :: + + sage: phi = DrinfeldModule(A, [K(zk), z^8, z^7]) + sage: phi.frobenius_charpoly(algorithm='CSA') + X^2 + (2*T^3 + (2*z2 + 2)*T^2 + (z2 + 1)*T + 2*z2)*X + z2*T^6 + (2*z2 + 2)*T^3 + 2 + sage: phi.frobenius_charpoly(algorithm='crystalline') + X^2 + (2*T^3 + (2*z2 + 2)*T^2 + (z2 + 1)*T + 2*z2)*X + z2*T^6 + (2*z2 + 2)*T^3 + 2 + sage: phi.frobenius_charpoly(algorithm='gekeler') + X^2 + (2*T^3 + (2*z2 + 2)*T^2 + (z2 + 1)*T + 2*z2)*X + z2*T^6 + (2*z2 + 2)*T^3 + 2 + sage: phi.frobenius_charpoly(algorithm='motive') + X^2 + (2*T^3 + (2*z2 + 2)*T^2 + (z2 + 1)*T + 2*z2)*X + z2*T^6 + (2*z2 + 2)*T^3 + 2 + sage: phi.frobenius_charpoly()(phi.frobenius_endomorphism()).ore_polynomial() + 0 + + :: + + sage: phi = DrinfeldModule(A, [K(zk), z^2, z^3, z^4]) + sage: phi.frobenius_charpoly(algorithm='CSA') + X^3 + ((z2 + 1)*T^2 + (z2 + 1)*T + z2 + 2)*X^2 + ((z2 + 2)*T^4 + 2*T^3 + z2*T^2 + T + 2*z2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly(algorithm='crystalline') + X^3 + ((z2 + 1)*T^2 + (z2 + 1)*T + z2 + 2)*X^2 + ((z2 + 2)*T^4 + 2*T^3 + z2*T^2 + T + 2*z2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly(algorithm='gekeler') + X^3 + ((z2 + 1)*T^2 + (z2 + 1)*T + z2 + 2)*X^2 + ((z2 + 2)*T^4 + 2*T^3 + z2*T^2 + T + 2*z2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly(algorithm='motive') + X^3 + ((z2 + 1)*T^2 + (z2 + 1)*T + z2 + 2)*X^2 + ((z2 + 2)*T^4 + 2*T^3 + z2*T^2 + T + 2*z2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly()(phi.frobenius_endomorphism()).ore_polynomial() + 0 + + :: - The available options for 'algorithm' are: + sage: phi = DrinfeldModule(A, [K(zk), z^8, z^7, z^20]) + sage: phi.frobenius_charpoly(algorithm='CSA') + X^3 + (z2*T^2 + z2*T + z2 + 1)*X^2 + (T^4 + (2*z2 + 1)*T^3 + (z2 + 2)*T^2 + (2*z2 + 1)*T + z2 + 2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly(algorithm='crystalline') + X^3 + (z2*T^2 + z2*T + z2 + 1)*X^2 + (T^4 + (2*z2 + 1)*T^3 + (z2 + 2)*T^2 + (2*z2 + 1)*T + z2 + 2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly(algorithm='gekeler') + X^3 + (z2*T^2 + z2*T + z2 + 1)*X^2 + (T^4 + (2*z2 + 1)*T^3 + (z2 + 2)*T^2 + (2*z2 + 1)*T + z2 + 2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly(algorithm='motive') + X^3 + (z2*T^2 + z2*T + z2 + 1)*X^2 + (T^4 + (2*z2 + 1)*T^3 + (z2 + 2)*T^2 + (2*z2 + 1)*T + z2 + 2)*X + T^6 + 2*z2*T^3 + 2*z2 + 1 + sage: phi.frobenius_charpoly()(phi.frobenius_endomorphism()).ore_polynomial() + 0 - - ``'crystalline'`` -- Computes the characteristic polynomial of the - Frobenius endomorphism on the crystalline cohomology of a Drinfeld - module. + Check that ``var`` inputs are taken into account for cached + characteristic polynomials:: - - ``'motive'`` -- Based on computing the characteristic polynomial of - the Frobenius endomorphism on the motive of a Drinfeld module. This - instantiates the Frobenius as a morphism object and calls its - ``'characteristic_polynomial'`` method. + sage: Fq = GF(2) + sage: A. = Fq[] + sage: K. = Fq.extension(2) + sage: phi = DrinfeldModule(A, [z, 0, 1]) + sage: phi.frobenius_charpoly() + X^2 + X + T^2 + T + 1 + sage: phi.frobenius_charpoly(var='Foo') + Foo^2 + Foo + T^2 + T + 1 + sage: phi.frobenius_charpoly(var='Bar') + Bar^2 + Bar + T^2 + T + 1 """ - # Throw an error if the user asks for an unimplemented algorithm - # even if the char poly has already been computed - method_name = f'_frobenius_charpoly_{algorithm}' - if hasattr(self, method_name): + # If no algorithm is specified, return cached data (if it + # exists), or pick an algorithm: + if algorithm is None: if self._frobenius_charpoly is not None: - return self._frobenius_charpoly - self._frobenius_charpoly = getattr(self, method_name)(var) - return self._frobenius_charpoly - raise NotImplementedError(f'algorithm \"{algorithm}\" not implemented') + return self._frobenius_charpoly.change_variable_name(var) + else: + if self.rank() < self._base_degree_over_constants: + algorithm = 'crystalline' + else: + algorithm = 'CSA' + # If an algorithm is specified, do not use cached data, even + # if it is possible: + method_name = f'_frobenius_charpoly_{algorithm}' + if not hasattr(self, method_name): + raise NotImplementedError(f'algorithm "{algorithm}" not implemented') + self._frobenius_charpoly = getattr(self, method_name)() + return self._frobenius_charpoly.change_variable_name(var) - def _frobenius_charpoly_crystalline(self, var): + def _frobenius_charpoly_CSA(self): r""" Return the characteristic polynomial of the Frobenius endomorphism using Crystalline cohomology. @@ -365,11 +454,59 @@ def _frobenius_charpoly_crystalline(self, var): This method is private and should not be directly called. Instead, use :meth:`frobenius_charpoly` with the option - `algorithm='crystalline'`. + `algorithm='CSA'`. - INPUT: + EXAMPLES:: - - ``var`` -- the name of the second variable + sage: Fq = GF(5) + sage: A. = Fq[] + sage: K. = Fq.extension(3) + sage: phi = DrinfeldModule(A, [z^i for i in range(1, 50)]) + sage: phi.frobenius_charpoly(algorithm="CSA") # indirect doctest + X^48 + 4*X^47 + 4*X^46 + X^45 + 3*X^44 + X^42 + 4*X^41 + 4*X^39 + 2*X^37 + 4*X^36 + 3*X^35 + 2*X^33 + (4*T + 2)*X^32 + (4*T + 1)*X^31 + (3*T + 1)*X^30 + 4*T*X^29 + 4*T*X^28 + 2*X^27 + X^26 + (3*T + 4)*X^25 + (4*T + 4)*X^24 + (T + 1)*X^23 + (T + 3)*X^22 + 4*T*X^21 + (2*T + 1)*X^20 + 4*X^19 + 4*T*X^18 + (T + 4)*X^17 + 4*T^2*X^16 + (T^2 + 3*T + 3)*X^15 + (4*T^2 + 3*T + 3)*X^14 + (3*T^2 + 3*T + 3)*X^13 + (3*T^2 + 4*T + 4)*X^12 + (T^2 + 2*T + 2)*X^11 + (3*T^2 + 4*T + 4)*X^10 + (3*T^2 + T + 1)*X^9 + (4*T + 4)*X^8 + (3*T + 3)*X^7 + (T^2 + 3*T + 3)*X^6 + (3*T^2 + T + 1)*X^5 + (2*T^2 + 3*T + 3)*X^4 + (2*T^2 + 3*T + 3)*X^3 + 3*T^2*X^2 + 4*T^2*X + 2*T^3 + T + 1 + + ALGORITHM: + + Compute the characteristic polynomial of the Frobenius from + the reduced characteristic polynomial of the Ore polynomial + `phi_T`. This algorithm is particularly interesting when the + rank of the Drinfeld module is large compared to the degree + of the extension `K/\mathbb F_q`. See [CL2023]_. + """ + E = self._base + EZ = PolynomialRing(E, name='Z') + n = self._base_degree_over_constants + f = self.gen() # phi_T, which is updated in the subsequent loop + t = self.ore_variable() + rows = [] + for i in range(n): + m = f.degree() + 1 + row = [EZ([f[jj] for jj in range(j, m, n)]) for j in range(n)] + rows.append(row) + f = t * f + chi = Matrix(rows).charpoly() + # Format the result + K = self.base_over_constants_field() + A = self.function_ring() + n = self._base_degree_over_constants + r = self.rank() + lc = chi[0][r] + coeffs = [A([K(chi[i][j]/lc).in_base() + for i in range((r-j)*n // r + 1)]) + for j in range(r+1)] + return PolynomialRing(A, name='X')(coeffs) + + def _frobenius_charpoly_crystalline(self): + r""" + Return the characteristic polynomial of the Frobenius + endomorphism using Crystalline cohomology. + + The algorithm works for Drinfeld `\mathbb{F}_q[T]`-modules of + any rank. + + This method is private and should not be directly called. + Instead, use :meth:`frobenius_charpoly` with the option + `algorithm='crystalline'`. OUTPUT: a univariate polynomial with coefficients in the function ring @@ -413,17 +550,96 @@ def _frobenius_charpoly_crystalline(self, var): of section 6.3 in [MS2023]_. """ A = self.function_ring() - K = self.base_over_constants_field() - charpoly_K = self._frobenius_crystalline_matrix() \ - .charpoly(var).coefficients(sparse=False) + charpoly_K = self._frobenius_matrix_crystalline().charpoly().list() # The above line obtains the char poly with coefficients in K[T] # This maps them into A = Fq[T] coeffs_A = [A([x.in_base() for x in coeff]) for coeff in charpoly_K] - return PolynomialRing(A, name=var)(coeffs_A) + return PolynomialRing(A, name='X')(coeffs_A) - def _frobenius_charpoly_motive(self, var): + def _frobenius_charpoly_gekeler(self): + r""" + Return the characteristic polynomial of the Frobenius + endomorphism using Gekeler's algorithm. + + The algorithm works for Drinfeld `\mathbb{F}_q[T]`-modules of + any rank, provided that the constant coefficient is a generator + of the base field. + + This method is private and should not be directly called. + Instead, use :meth:`frobenius_charpoly` with the option + `algorithm='gekeler'`. + + .. WARNING: + + This algorithm only works in the generic case when the + corresponding linear system is invertible. Notable cases + where this fails include Drinfeld modules whose minimal + polynomial is not equal to the characteristic polynomial, + and rank 2 Drinfeld modules where the degree 1 coefficient + of `\phi_T` is 0. In that case, an exception is raised. + + EXAMPLES:: + + sage: Fq = GF(25) + sage: A. = Fq[] + sage: K. = Fq.extension(6) + sage: phi = DrinfeldModule(A, [z, 4, 1, z]) + sage: phi.frobenius_charpoly(algorithm='gekeler') # indirect doctest + X^3 + ((z2 + 2)*T^2 + (z2 + 2)*T + 4*z2 + 4)*X^2 + ... + (3*z2 + 2)*T^2 + (3*z2 + 3)*T + 4 + + :: + + sage: Fq = GF(125) + sage: A. = Fq[] + sage: K. = Fq.extension(2) + sage: phi = DrinfeldModule(A, [z, 0, z]) + sage: phi.frobenius_charpoly(algorithm='gekeler') # indirect doctest + Traceback (most recent call last): + NotImplementedError: 'gekeler' algorithm failed + + ALGORITHM: + + Construct a linear system based on the requirement that the + Frobenius satisfies a degree r polynomial with coefficients in + the function ring. This generalizes the procedure from + [Gek2008]_ for the rank 2 case. + """ + K = self.base_over_constants_field() + A = self.function_ring() + r, n = self.rank(), self._base_degree_over_constants + # Compute constants that determine the block structure of the + # linear system. The system is prepared such that the solution + # vector has the form [a_0, a_1, ... a_{r-1}]^T with each a_i + # corresponding to a block of length (n*(r - i))//r + 1 + shifts = [(n*(r - i))//r + 1 for i in range(r)] + rows, cols = n*r + 1, sum(shifts) + block_shifts = [0] + for i in range(r-1): + block_shifts.append(block_shifts[-1] + shifts[i]) + # Compute the images \phi_T^i for i = 0 .. n. + gen_powers = [self(A.gen()**i).coefficients(sparse=False) + for i in range(0, n + 1)] + sys, vec = Matrix(K, rows, cols), vector(K, rows) + vec[rows - 1] = -1 + for j in range(r): + for k in range(shifts[j]): + for i in range(len(gen_powers[k])): + sys[i + n*j, block_shifts[j] + k] = gen_powers[k][i] + if sys.right_nullity() != 0: + raise NotImplementedError("'gekeler' algorithm failed") + sol = list(sys.solve_right(vec)) + # The system is solved over K, but the coefficients should all + # be in Fq We project back into Fq here. + sol_Fq = [K(x).vector()[0] for x in sol] + char_poly = [] + for i in range(r): + char_poly.append([sol_Fq[block_shifts[i] + j] + for j in range(shifts[i])]) + return PolynomialRing(A, name='X')(char_poly + [1]) + + def _frobenius_charpoly_motive(self): r""" Return the characteristic polynomial of the Frobenius endomorphism using Motivic cohomology. @@ -435,10 +651,6 @@ def _frobenius_charpoly_motive(self, var): Instead, use :meth:`frobenius_charpoly` with the option `algorithm='motive'`. - INPUT: - - - ``var`` -- the name of the second variable - OUTPUT: a univariate polynomial with coefficients in the function ring @@ -470,7 +682,7 @@ def _frobenius_charpoly_motive(self, var): sage: phi.frobenius_charpoly(algorithm='motive') # indirect doctest X^11 + (z3^2 + 2*z3)*X^10 + ((z3 + 1)*T + z3)*X^9 + ((2*z3^2 + z3 + 2)*T^2 + ... + (2*z3^2 + 2*z3 + 2)*T + z3^2 """ - return self.frobenius_endomorphism().characteristic_polynomial(var) + return self.frobenius_endomorphism().characteristic_polynomial('X') def frobenius_norm(self): r""" @@ -478,9 +690,25 @@ def frobenius_norm(self): Let `C(X) = \sum_{i=0}^r a_iX^{i}` denote the characteristic polynomial of the Frobenius endomorphism. The Frobenius norm - is `(-1)^r a_{0}`. This is an element of the regular function ring - and if `n` is the degree of the base field over `\mathbb{F}_q`, - then the Frobenius norm has degree `n`. + is `a_{0}`, and given by the formula + + .. MATH:: + + a_0 = (-1)^{nr - n -r} + \mathrm{Norm}_{K/\mathbb F_q}(\Delta)^{-1} + p^{n / \mathrm{deg}(p)}, + + where `K` is the ground field, which as degree `n` over + `\mathbb F_q`, `r` is the rank of the Drinfeld module, + and `\Delta` is the leading coefficient of the generator. + This formula is given in Theorem~4.2.7 of [Pap2023]_. + + Note that the Frobenius norm computed by this method may be + different than what is computed as the isogeny norm of the + Frobenius endomorphism (see :meth:`norm` on the Frobenius + endomorphism), which is an ideal defined of the function ring + given by its monic generator; the Frobenius norm may not be + monic. EXAMPLES:: @@ -488,19 +716,28 @@ def frobenius_norm(self): sage: A. = Fq[] sage: K. = Fq.extension(2) sage: phi = DrinfeldModule(A, [1, 0, z6]) - sage: B = phi.frobenius_norm() - sage: B + sage: frobenius_norm = phi.frobenius_norm() + sage: frobenius_norm (5*z3^2 + 2*z3)*T^2 + (4*z3^2 + 3*z3)*T + 5*z3^2 + 2*z3 :: sage: n = 2 # Degree of the base field over Fq - sage: B.degree() == n + sage: frobenius_norm.degree() == n True :: - sage: B == phi.frobenius_charpoly()[0] + sage: frobenius_norm == phi.frobenius_charpoly()[0] + True + + :: + + sage: lc = frobenius_norm.leading_coefficient() + sage: isogeny_norm = phi.frobenius_endomorphism().norm() + sage: isogeny_norm.gen() == frobenius_norm / lc + True + sage: A.ideal(frobenius_norm) == isogeny_norm True ALGORITHM: @@ -512,12 +749,15 @@ def frobenius_norm(self): return self._frobenius_norm K = self.base_over_constants_field() n = K.degree(self._Fq) - char = self.characteristic() + r = self.rank() + p = self.characteristic() norm = K(self.coefficients()[-1]).norm() - self._frobenius_norm = ((-1)**n)*(char**(n/char.degree())) / norm + self._frobenius_norm = (-1) ** (n*r - n - r) \ + * norm**(-1) \ + * p ** (n//p.degree()) return self._frobenius_norm - def frobenius_trace(self): + def frobenius_trace(self, algorithm=None): r""" Return the Frobenius trace of the Drinfeld module. @@ -527,44 +767,145 @@ def frobenius_trace(self): and if `n` is the degree of the base field over `\mathbb{F}_q`, then the Frobenius trace has degree at most `\frac{n}{r}`. + INPUT: + + - ``algorithm`` (default: ``None``) -- the algorithm + used to compute the characteristic polynomial + + .. NOTE: + + Available algorithms are: + + - ``'CSA'`` -- it exploits the fact that `K\{\tau\}` is a + central simple algebra (CSA) over `\mathbb + F_q[\text{Frob}_\phi]` (see Chapter 4 of [CL2023]_). + - ``'crystalline'`` -- it uses the action of the Frobenius + on the crystalline cohomology (see [MS2023]_). + + The method raises an exception if the user asks for an + unimplemented algorithm, even if the characteristic has already + been computed. See :meth:`frobenius_charpoly` for more details. + EXAMPLES:: sage: Fq = GF(343) sage: A. = Fq[] sage: K. = Fq.extension(2) sage: phi = DrinfeldModule(A, [1, 0, z6]) - sage: A = phi.frobenius_trace() - sage: A + sage: frobenius_trace = phi.frobenius_trace() + sage: frobenius_trace (4*z3^2 + 6*z3 + 3)*T + 3*z3^2 + z3 + 4 :: sage: n = 2 # Degree over Fq of the base codomain - sage: A.degree() <= n/2 + sage: frobenius_trace.degree() <= n/2 True :: - sage: A == -phi.frobenius_charpoly()[1] + sage: frobenius_trace == -phi.frobenius_charpoly()[1] True + One can specify an algorithm:: + + sage: psi = DrinfeldModule(A, [z6, 1, z6^3, z6 + 1]) + sage: psi.frobenius_trace(algorithm='crystalline') + z3^2 + 6*z3 + 2 + sage: psi.frobenius_trace(algorithm='CSA') + z3^2 + 6*z3 + 2 + ALGORITHM: - We extract the coefficient of `X^{r-1}` from the characteristic - polynomial if it has been previously computed, otherwise we compute - the trace of the matrix of the Frobenius acting on the crystalline - cohomology. + If the user specifies an algorithm, then the trace is + computed according to the user's input (see the note above), + even if the Frobenius trace or the Frobenius characteristic + polynomial had already been computed. + + If no algorithm is given, then the function either returns a + cached value, or if no cached value is available, the + function computes the Frobenius trace from scratch. In that + case, if the rank `r` is less than the extension degree `n`, + then the ``crystalline`` algorithm is used, while the + ``CSA`` algorithm is used otherwise. + + TESTS: + + These test values are taken from :meth:`frobenius_charpoly`:: + + sage: Fq = GF(9) + sage: A. = Fq[] + sage: k. = Fq.extension(2) + sage: K. = k.extension(3) + + :: + + sage: phi = DrinfeldModule(A, [K(zk), z^8, z^7]) + sage: phi.frobenius_trace(algorithm='CSA') + T^3 + (z2 + 1)*T^2 + (2*z2 + 2)*T + z2 + sage: phi.frobenius_trace(algorithm='crystalline') + T^3 + (z2 + 1)*T^2 + (2*z2 + 2)*T + z2 + sage: charpoly = phi.frobenius_charpoly() + sage: trace = phi.frobenius_trace() + sage: trace == -charpoly[1] + True + + :: + + sage: phi = DrinfeldModule(A, [K(zk), z^2, z^3, z^4]) + sage: phi.frobenius_trace(algorithm='CSA') + (2*z2 + 2)*T^2 + (2*z2 + 2)*T + 2*z2 + 1 + sage: phi.frobenius_trace(algorithm='crystalline') + (2*z2 + 2)*T^2 + (2*z2 + 2)*T + 2*z2 + 1 + sage: charpoly = phi.frobenius_charpoly() + sage: trace = phi.frobenius_trace() + sage: trace == -charpoly[2] + True + + :: + + sage: phi = DrinfeldModule(A, [K(zk), z^8, z^7, z^20]) + sage: phi.frobenius_trace(algorithm='CSA') + 2*z2*T^2 + 2*z2*T + 2*z2 + 2 + sage: phi.frobenius_trace(algorithm='crystalline') + 2*z2*T^2 + 2*z2*T + 2*z2 + 2 + sage: charpoly = phi.frobenius_charpoly() + sage: trace = phi.frobenius_trace() + sage: trace == -charpoly[2] + True """ - K = self.base_over_constants_field() - A = self.function_ring() - if self._frobenius_trace is not None: + if algorithm is None: + # If no algorithm is specified, return cached data (if it + # exists), or pick an algorithm: + # However, if an algorithm is specified, do not use cached + # data, even if it is possible + if self._frobenius_trace is not None: + return self._frobenius_trace + if self._frobenius_charpoly is not None: + self._frobenius_trace = -self._frobenius_charpoly \ + .coefficients(sparse=False)[-2] + return self._frobenius_trace + else: + if self.rank() < self._base_degree_over_constants: + algorithm = 'crystalline' + else: + algorithm = 'CSA' + # We first check if a matrix method is available + matrix_method_name = f'_frobenius_matrix_{algorithm}' + if hasattr(self, matrix_method_name): + matrix = getattr(self, matrix_method_name)() + trace = matrix.trace() + A = self.function_ring() + self._frobenius_trace = A([x.in_base() for x in trace]) + return self._frobenius_trace + # If it is not, we look for a charpoly method + charpoly_method_name = f'_frobenius_charpoly_{algorithm}' + if hasattr(self, charpoly_method_name): + charpoly = getattr(self, charpoly_method_name)() + self._frobenius_trace = -charpoly.list()[-2] return self._frobenius_trace - if self._frobenius_charpoly is not None: - self._frobenius_trace = -self._frobenius_charpoly \ - .coefficients(sparse=False)[-2] - self._frobenius_trace = self._frobenius_crystalline_matrix().trace() - self._frobenius_trace = A([x.in_base() for x in self._frobenius_trace]) - return self._frobenius_trace + # If all fail, we raise an error + raise NotImplementedError(f'algorithm "{algorithm}" not implemented') def invert(self, ore_pol): r""" @@ -639,7 +980,6 @@ def invert(self, ore_pol): Traceback (most recent call last): ... TypeError: input must be an Ore polynomial - """ deg = ore_pol.degree() r = self.rank() @@ -658,7 +998,6 @@ def invert(self, ore_pol): # Write the system and solve it k = deg // r A = self._function_ring - T = A.gen() mat_rows = [[E.zero() for _ in range(k+1)] for _ in range(k+1)] mat_rows[0][0] = E.one() phiT = self.gen() @@ -763,7 +1102,6 @@ def is_supersingular(self): False sage: psi.is_supersingular() False - """ return self.height() == self.rank() @@ -788,6 +1126,5 @@ def is_ordinary(self): sage: phi = DrinfeldModule(A, [1, z6, 0, z6]) sage: phi.is_ordinary() True - """ return self.height() == 1 diff --git a/src/sage/rings/function_field/drinfeld_modules/homset.py b/src/sage/rings/function_field/drinfeld_modules/homset.py index d50e943686b..41a79e7fe6a 100644 --- a/src/sage/rings/function_field/drinfeld_modules/homset.py +++ b/src/sage/rings/function_field/drinfeld_modules/homset.py @@ -64,7 +64,6 @@ class DrinfeldModuleMorphismAction(Action): From: Drinfeld module defined by T |--> z*t^2 + t + z To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^2 + (z^2 + 4*z + 3)*t + z Defn: t + 2 - """ def __init__(self, A, H, is_left, op): r""" @@ -76,7 +75,7 @@ def __init__(self, A, H, is_left, op): - ``H`` -- a homset between Drinfeld modules - - ``is_left`` -- a boolean + - ``is_left`` -- boolean - ``op`` -- an operator @@ -95,7 +94,6 @@ def __init__(self, A, H, is_left, op): sage: right_action = DrinfeldModuleMorphismAction(A, H, False, operator.mul) sage: TestSuite(right_action).run(skip='_test_pickling') - """ Action.__init__(self, A, H, is_left, op) if is_left: @@ -120,7 +118,6 @@ def _act_(self, a, f): From: Drinfeld module defined by T |--> z*t^3 + t^2 + z To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z Defn: (2*z^2 + 4*z + 4)*t^4 + (z + 1)*t^3 + t^2 + (2*z^2 + 4*z + 4)*t + z - """ u = f.ore_polynomial() if self._is_left: @@ -234,7 +231,6 @@ class DrinfeldModuleHomset(Homset): False sage: frobenius_endomorphism in H False - """ Element = DrinfeldModuleMorphism @@ -248,10 +244,11 @@ def __init__(self, X, Y, category=None, check=True): - ``Y`` -- the codomain of the homset - - ``category`` (default: ``None``) -- the Drinfeld modules category of + - ``category`` -- (default: ``None``) the Drinfeld modules category of the domain and codomain - - ``check`` (default: ``True``) -- check the validity of the category + - ``check`` -- boolean (default: ``True``); check the validity of the + category TESTS:: diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index c7e1f6c3bfe..82c1d7a0da1 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -122,7 +122,6 @@ class DrinfeldModuleMorphism(Morphism, UniqueRepresentation, Defn: t + z^5 + z^3 + z + 1 sage: DrinfeldModuleMorphism(Hom(phi, psi), ore_pol) is morphism True - """ @staticmethod def __classcall_private__(cls, parent, x): @@ -459,7 +458,6 @@ def __add__(self, other): sage: F + T Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z Defn: (z + 1)*t^3 + t^2 + z - """ return self.parent()(self.ore_polynomial() + other.ore_polynomial()) @@ -480,7 +478,6 @@ def _composition_(self, other, H): sage: f * f # indirect doctest Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: t^6 - """ return H(self.ore_polynomial() * other.ore_polynomial()) @@ -525,7 +522,6 @@ def inverse(self): Traceback (most recent call last): ... ZeroDivisionError: this morphism is not invertible - """ return self.__invert__() @@ -547,7 +543,6 @@ def __invert__(self): True sage: (g*f).is_identity() True - """ if not self.is_isomorphism(): raise ZeroDivisionError("this morphism is not invertible") @@ -573,7 +568,6 @@ def _motive_matrix(self): sage: f._motive_matrix() [ T + 3 + z 3 + 3*z + 2*z^2] [(1 + z + z^2)*T + 3 + 2*z - z^2 T + 2 - z + 2*z^2] - """ phi = self.domain() phiT = phi.gen() @@ -614,10 +608,10 @@ def norm(self, ideal=True): INPUT: - - ``ideal`` -- a boolean (default: ``True``); if ``True``, - return the norm as an ideal in the function ring of the Drinfeld - modules; if ``False``, return the norm as an element in this - function ring (only relevant for endomorphisms) + - ``ideal`` -- boolean (default: ``True``); if ``True``, return the + norm as an ideal in the function ring of the Drinfeld modules; if + ``False``, return the norm as an element in this function ring (only + relevant for endomorphisms) EXAMPLES:: @@ -660,7 +654,6 @@ def norm(self, ideal=True): Traceback (most recent call last): ... ValueError: norm is defined as an actual element only for endomorphisms - """ nu = self._motive_matrix().det() # We cast to A @@ -720,7 +713,6 @@ def dual_isogeny(self): Traceback (most recent call last): ... ValueError: the dual isogeny of the zero morphism is not defined - """ if not self.is_isogeny(): raise ValueError("the dual isogeny of the zero morphism is not defined") @@ -736,7 +728,7 @@ def characteristic_polynomial(self, var='X'): INPUT: - - ``var`` -- a string (default: ``X``), the name of the + - ``var`` -- string (default: ``X``), the name of the variable of the characteristic polynomial EXAMPLES:: @@ -772,7 +764,6 @@ def characteristic_polynomial(self, var='X'): Traceback (most recent call last): ... ValueError: characteristic polynomial is only defined for endomorphisms - """ if self.domain() is not self.codomain(): raise ValueError("characteristic polynomial is only defined for endomorphisms") @@ -788,7 +779,7 @@ def charpoly(self, var='X'): INPUT: - - ``var`` -- a string (default: ``X``), the name of the + - ``var`` -- string (default: ``'X'``); the name of the variable of the characteristic polynomial EXAMPLES:: @@ -822,6 +813,5 @@ def charpoly(self, var='X'): sage: f.charpoly(var='Y') Y^3 + (T + 1)*Y^2 + (2*T + 3)*Y + 2*T^3 + T + 1 - """ return self.characteristic_polynomial(var) diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 5e8254e8294..2863732cf3b 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -45,6 +45,8 @@ AUTHORS: - Maarten Derickx (2011-09-11): added doctests, fixed pickling - Kwankyu Lee (2017-04-30): added elements for global function fields + +- Vincent Macri (2024-09-03): added subs method """ # ***************************************************************************** # Copyright (C) 2010 William Stein @@ -57,6 +59,7 @@ AUTHORS: # 2018-2020 Travis Scrimshaw # 2019 Brent Baccala # 2021 Saher Amasha +# 2024 Vincent Macri # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of @@ -64,8 +67,9 @@ AUTHORS: # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.structure.element cimport FieldElement +from sage.categories.function_fields import FunctionFields from sage.misc.cachefunc import cached_method +from sage.structure.element cimport FieldElement def is_FunctionFieldElement(x): @@ -76,14 +80,24 @@ def is_FunctionFieldElement(x): sage: t = FunctionField(QQ,'t').gen() sage: sage.rings.function_field.element.is_FunctionFieldElement(t) + doctest:warning... + DeprecationWarning: The function is_FunctionFieldElement is deprecated; + use '....parent() in FunctionFields()' instead. + See https://github.com/sagemath/sage/issues/38289 for details. True sage: sage.rings.function_field.element.is_FunctionFieldElement(0) False """ + from sage.misc.superseded import deprecation_cython + deprecation_cython(38289, + "The function is_FunctionFieldElement is deprecated; " + "use '....parent() in FunctionFields()' instead.") if isinstance(x, FunctionFieldElement): return True - from sage.rings.function_field.function_field import is_FunctionField - return is_FunctionField(x.parent()) + from sage.rings.function_field.function_field import FunctionField + if isinstance(x.parent(), FunctionField): + return True + return x.parent() in FunctionFields() def make_FunctionFieldElement(parent, element_class, representing_element): @@ -146,7 +160,6 @@ cdef class FunctionFieldElement(FieldElement): Traceback (most recent call last): ... NotImplementedError: PARI does not support general function field elements. - """ raise NotImplementedError("PARI does not support general function field elements.") @@ -164,6 +177,269 @@ cdef class FunctionFieldElement(FieldElement): """ return self._x._latex_() + def subs(self, in_dict=None, **kwds): + r""" + Substitute the given generators with given values while not touching + other generators. + + INPUT: + + - ``in_dict`` -- (optional) dictionary of inputs + + - ``**kwds`` -- named parameters + + OUTPUT: new object if substitution is possible, otherwise ``self`` + + EXAMPLES: + + Basic substitution:: + + sage: K = GF(7) + sage: Kx. = FunctionField(K) + sage: y = polygen(Kx) + sage: f = x^6 + 3; f + x^6 + 3 + + We also substitute the generators in any base fields:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: S. = L[] + sage: M. = L.extension(t^2 - x*y) + sage: f = 7 * t + 3*x*y + sage: f.subs(t=9) + 3*x*y + 63 + sage: f.subs(x=2, y=4) + 7*t + 24 + sage: f.subs(t=1, x=2, y=3) + 25 + + Because of the possibility of extension fields, a generator to + substitute must be specified:: + + sage: K. = FunctionField(QQ) + sage: f = x + sage: f.subs(2) + Traceback (most recent call last): + ... + TypeError: in_dict must be a dict + + sage: # needs sage.rings.function_field + sage: R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: f = x + y + sage: f.subs(0) + Traceback (most recent call last): + ... + TypeError: in_dict must be a dict + + We can also substitute using dictionary syntax:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: S. = L[] + sage: M. = L.extension(t^2 - x*y) + sage: f = x + y + t + sage: f.subs({x: 1, y: 3, t: 4}) + 8 + sage: f.subs({x: 1, t: 4}) + y + 5 + + TESTS: + + Check that we correctly handle extension fields:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: S. = L[] + sage: M. = L.extension(t^2 - x*y) + sage: f = t + x*y + sage: f.subs(x=1, y=3, t=5) + 8 + sage: f_sub = f.subs(x=1); f_sub + t + y + sage: f_sub.parent() == f.parent() + True + sage: f.subs(y=2) + t + 2*x + sage: f_sub = f.subs(x=1, y=1, t=1); f_sub + 2 + sage: f_sub.parent() == M + True + + Test that substitution works for rational functions:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^4 - 3) + sage: f = x / y + sage: f.subs(x=2) == 2 / y + True + sage: f.subs(y=3) + 9*x + sage: f.subs(t=-1) is f + True + sage: f.subs({x: 2, y: 4}) + 128/3 + + Make sure that we return the same object when there is no + substitution:: + + sage: K = GF(7) + sage: Kx. = FunctionField(K) + sage: y = polygen(Kx) + sage: f = x^6 + 3 + sage: g = f.subs(z=2) + sage: g == f + True + sage: g is f + True + + Same purpose as above but over an extension field over the rationals:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: S. = L[] + sage: M. = L.extension(t^2 - x*y) + sage: f = t + x*y + sage: f.subs() is f + True + sage: f.subs(w=7) is f + True + sage: f.subs(w=7) is f.subs(w=7) + True + sage: f.subs(y=y) is f + True + sage: f.subs({y: y}) is f + True + sage: f.subs(x=x, y=y, t=t) is f + True + + Test proper handling of not making substitutions:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: f = x + sage: f.subs() is f + True + sage: f.subs(dict()) is f + True + sage: f.subs(w=0) is f + True + sage: R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: f = 3*y + sage: f.subs(x=0) + 3*y + sage: f = 3*y + sage: f.subs(x=0, y=y) + 3*y + + Test error handling for wrong argument type:: + + sage: K. = FunctionField(QQ) + sage: f = x + sage: f.subs(0) + Traceback (most recent call last): + ... + TypeError: in_dict must be a dict + + Test error handling for dictionary with keys that don't match + generators:: + + sage: K. = FunctionField(QQ) + sage: f = x + sage: f.subs({1: 1}) + Traceback (most recent call last): + ... + TypeError: key does not match any field generators + + Test error handling with ambiguously named generators:: + + sage: # needs sage.rings.function_field + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(x^3 - x) + sage: str(L.gen()) == str(K.gen()) + True + sage: f = K.gen() - L.gen() + sage: f.subs(x=2) + Traceback (most recent call last): + ... + TypeError: multiple generators have the same name, making substitution ambiguous. Rename generators or pass substitution values in using dictionary format + sage: f.subs({K.gen(): 1}) + -x + 1 + sage: f.subs({L.gen(): 2}) + x - 2 + sage: f.subs({K.gen(): 1, L.gen(): 2}) + -1 + sage: f.subs({K.gen(): 2, L.gen(): 1}) + 1 + """ + def sub_recurse(ff_element, sub_dict): + # Helper method to recurse through base fields. + ff = ff_element.parent() + if ff.base_field() == ff: + return ff(ff_element._x.subs({ff.gen(): sub_dict[ff.gen()]})) + total = ff.zero() + for i, v in enumerate(list(ff_element._x)): + total += sub_recurse(v, sub_dict) * sub_dict[ff.gen()]**i + return ff(total) + + if in_dict is None and kwds is None: + return self + + if in_dict is not None and not isinstance(in_dict, dict): + raise TypeError('in_dict must be a dict') + + field_tower = [self.parent()] + ff = self.parent() + + while ff.base_field() != ff: + ff = ff.base_field() + field_tower.append(ff) + sub_dict = {f.gen(): f.gen() for f in field_tower} + + made_substitution = False + if in_dict is not None: + for k, v in in_dict.items(): + if k not in sub_dict: + raise TypeError('key does not match any field generators') + sub_dict[k] = v + if v != k: + made_substitution = True + else: + used_kwds = {k: False for k in kwds} + for g in sub_dict: + strg = str(g) + if strg not in kwds: + continue + v = kwds[strg] + sub_dict[g] = v + + if used_kwds[strg]: + raise TypeError('multiple generators have the ' + 'same name, making substitution ' + 'ambiguous. Rename generators ' + 'or pass substitution values in ' + 'using dictionary format') + used_kwds[strg] = True + if g != v: + made_substitution = True + + if made_substitution: + return sub_recurse(self, sub_dict) + return self + @cached_method def matrix(self, base=None): r""" @@ -172,8 +448,8 @@ cdef class FunctionFieldElement(FieldElement): INPUT: - - ``base`` -- a function field (default: ``None``), if ``None``, then - the matrix is formed over the base field of this function field. + - ``base`` -- a function field (default: ``None``); if ``None``, then + the matrix is formed over the base field of this function field EXAMPLES: @@ -238,7 +514,7 @@ cdef class FunctionFieldElement(FieldElement): # with this element; make matrix whose rows are the coefficients of the # result, and transpose V, f, t = self.parent().vector_space(base) - rows = [ t(self*f(b)) for b in V.basis() ] + rows = [t(self*f(b)) for b in V.basis()] from sage.matrix.matrix_space import MatrixSpace MS = MatrixSpace(V.base_field(), V.dimension()) ret = MS(rows) @@ -316,7 +592,7 @@ cdef class FunctionFieldElement(FieldElement): sage: f.degree() 1 """ - return max(self._x.denominator().degree(),self._x.numerator().degree()) + return max(self._x.denominator().degree(), self._x.numerator().degree()) def characteristic_polynomial(self, *args, **kwds): """ @@ -641,8 +917,8 @@ cdef class FunctionFieldElement(FieldElement): OUTPUT: If the element is in the valuation ring at the place, then an element - in the residue field at the place is returned. Otherwise, ``ValueError`` - is raised. + in the residue field at the place is returned. Otherwise, a + :exc:`ValueError` is raised. EXAMPLES:: @@ -671,7 +947,7 @@ cdef class FunctionFieldElement(FieldElement): v = self.valuation(place) if v > 0: return R.zero() - if v == 0: + if v == 0: return to_R(self) # v < 0 raise ValueError('has a pole at the place') @@ -683,7 +959,7 @@ cdef class FunctionFieldElement(FieldElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: @@ -709,7 +985,7 @@ cdef class FunctionFieldElement(FieldElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index 55e887ea491..2d92da20bfe 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -114,7 +114,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): cpdef _richcmp_(self, other, int op): """ - Do rich comparison with the other element with respect to ``op`` + Do rich comparison with the other element with respect to ``op``. EXAMPLES:: @@ -257,7 +257,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: @@ -293,7 +293,6 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): x sage: L(x^9).nth_root(-27)^-27 x^9 - """ if n == 1: return self @@ -323,7 +322,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer ALGORITHM: @@ -345,7 +344,6 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): False sage: L(x).is_nth_power(2) True - """ if n == 0: return self.is_one() diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx index 5ad0d81341d..19a63d9ef90 100644 --- a/src/sage/rings/function_field/element_rational.pyx +++ b/src/sage/rings/function_field/element_rational.pyx @@ -61,7 +61,6 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: K. = FunctionField(QQ) sage: ((a+1)/(a-1)).__pari__() # needs sage.libs.pari (a + 1)/(a - 1) - """ return self.element().__pari__() @@ -146,7 +145,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): cpdef _richcmp_(self, other, int op): """ - Compare the element with the other element with respect to ``op`` + Compare the element with the other element with respect to ``op``. INPUT: @@ -213,7 +212,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): cpdef _mul_(self, right): """ - Multiply the element with the other element + Multiply the element with the other element. INPUT: @@ -231,7 +230,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): cpdef _div_(self, right): """ - Divide the element with the other element + Divide the element with the other element. INPUT: @@ -367,7 +366,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: @@ -419,7 +418,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: diff --git a/src/sage/rings/function_field/extensions.py b/src/sage/rings/function_field/extensions.py index e65532db39e..94e810a9f87 100644 --- a/src/sage/rings/function_field/extensions.py +++ b/src/sage/rings/function_field/extensions.py @@ -82,7 +82,6 @@ class ConstantFieldExtension(FunctionFieldExtension): - ``F`` -- a function field whose constant field is `k` - ``k_ext`` -- an extension of `k` - """ def __init__(self, F, k_ext): """ diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 315f58cdc39..401b2144be9 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -263,10 +263,17 @@ def is_FunctionField(x): sage: from sage.rings.function_field.function_field import is_FunctionField sage: is_FunctionField(QQ) + doctest:warning... + DeprecationWarning: The function is_FunctionField is deprecated; use '... in FunctionFields()' instead. + See https://github.com/sagemath/sage/issues/38289 for details. False sage: is_FunctionField(FunctionField(QQ, 't')) True """ + from sage.misc.superseded import deprecation + deprecation(38289, + "The function is_FunctionField is deprecated; " + "use '... in FunctionFields()' instead.") if isinstance(x, FunctionField): return True return x in FunctionFields() @@ -438,9 +445,7 @@ def extension(self, f, names=None): - ``names`` -- string or tuple of length 1 that names the variable `y` - OUTPUT: - - - a function field + OUTPUT: a function field EXAMPLES:: @@ -475,9 +480,7 @@ def order_with_basis(self, basis, check=True): basis is really linearly independent and that the module it spans is closed under multiplication, and contains the identity element. - OUTPUT: - - - an order in the function field + OUTPUT: an order in the function field EXAMPLES:: @@ -800,17 +803,15 @@ def _convert_map_from_(self, R): def _intermediate_fields(self, base): """ - Return the fields which lie in between base and the function field in the - tower of function fields. + Return the fields which lie in between base and the function field in + the tower of function fields. INPUT: - ``base`` -- function field, either this field or a field from which this field has been created as an extension - OUTPUT: - - - a list of fields; the first entry is this field, the last entry is ``base`` + OUTPUT: list of fields; the first entry is this field, the last entry is ``base`` EXAMPLES:: @@ -846,7 +847,7 @@ def _intermediate_fields(self, base): ... TypeError: base must be a function field """ - if not is_FunctionField(base): + if base not in FunctionFields(): raise TypeError("base must be a function field") ret = [self] @@ -999,7 +1000,6 @@ def valuation(self, prime): sage: v = L.valuation(x); v # needs sage.rings.function_field (x)-adic valuation - """ from sage.rings.function_field.valuation import FunctionFieldValuation return FunctionFieldValuation(self, prime) @@ -1235,7 +1235,7 @@ def hilbert_symbol(self, a, b, P): INPUT: - - ``a`` and ``b`` -- elements of this function field + - ``a``, ``b`` -- elements of this function field - ``P`` -- a place of this function field diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index fd8c975e682..de6cbf47a6c 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -247,8 +247,7 @@ def _to_base_field(self, f): INPUT: - - ``f`` -- element of the function field which lies in the base - field. + - ``f`` -- element of the function field which lies in the base field EXAMPLES:: @@ -323,10 +322,10 @@ def monic_integral_model(self, names=None): INPUT: - - ``names`` -- a string or a tuple of up to two strings (default: - ``None``), the name of the generator of the field, and the name of - the generator of the underlying rational function field (if a tuple); - if not given, then the names are chosen automatically. + - ``names`` -- string or tuple of up to two strings (default: + ``None``); the name of the generator of the field, and the name of + the generator of the underlying rational function field (if a tuple). + If not given, then the names are chosen automatically. OUTPUT: @@ -410,7 +409,6 @@ def monic_integral_model(self, names=None): To: Function field in yy defined by yy^2 - xx Defn: y |--> yy x |--> xx) - """ if names: if not isinstance(names, tuple): @@ -528,7 +526,7 @@ def degree(self, base=None): INPUT: - ``base`` -- a function field (default: ``None``), a function field - from which this field has been constructed as a finite extension. + from which this field has been constructed as a finite extension EXAMPLES:: @@ -554,7 +552,6 @@ def degree(self, base=None): Traceback (most recent call last): ... ValueError: base must be the rational function field itself - """ if base is None: base = self.base_field() @@ -659,7 +656,6 @@ def is_separable(self, base=None): sage: L. = K.extension(y^5 - 1) sage: L.is_separable() False - """ if base is None: base = self.base_field() @@ -701,10 +697,10 @@ def free_module(self, base=None, basis=None, map=True): space is over this subfield `R`, which defaults to the base field of this function field. - - ``basis`` -- a basis for this field over the base. + - ``basis`` -- a basis for this field over the base - - ``maps`` -- boolean (default ``True``), whether to return - `R`-linear maps to and from `V`. + - ``maps`` -- boolean (default: ``True``); whether to return + `R`-linear maps to and from `V` OUTPUT: @@ -785,7 +781,6 @@ def free_module(self, base=None, basis=None, map=True): Isomorphism: From: Function field in z defined by z^2 - y To: Vector space of dimension 10 over Rational function field in x over Rational Field) - """ if basis is not None: raise NotImplementedError @@ -891,7 +886,7 @@ def hom(self, im_gens, base_morphism=None): INPUT: - ``im_gens`` -- list of images of the generators of the function field - and of successive base rings. + and of successive base rings - ``base_morphism`` -- homomorphism of the base ring, after the ``im_gens`` are used. Thus if ``im_gens`` has length 2, then @@ -986,7 +981,6 @@ def hom(self, im_gens, base_morphism=None): To: Function field in y defined by y^2 - x^3 - 1 Defn: xx |--> x yy |--> y - """ if not isinstance(im_gens, (list, tuple)): im_gens = [im_gens] @@ -1051,7 +1045,7 @@ def _simple_model(self, name='v'): INPUT: - - ``name`` -- a string, the name of the generator of `N` + - ``name`` -- string; the name of the generator of `N` ALGORITHM: @@ -1127,7 +1121,6 @@ def _simple_model(self, name='v'): To: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 Defn: z |--> v^4 + x^2 y |--> v^4 + v + x^2) - """ M = self L = M.base_field() @@ -1188,7 +1181,7 @@ def simple_model(self, name=None): INPUT: - - ``name`` -- a string (default: ``None``), the name of generator of + - ``name`` -- string (default: ``None``); the name of generator of the simple extension. If ``None``, then the name of the generator will be the same as the name of the generator of this function field. @@ -1366,7 +1359,7 @@ def separable_model(self, names=None): INPUT: - - ``names`` -- a tuple of two strings or ``None`` (default: ``None``); + - ``names`` -- tuple of two strings or ``None`` (default: ``None``); the second entry will be used as the variable name of the rational function field, the first entry will be used as the variable name of its separable extension. If ``None``, then the variable names will be @@ -1512,7 +1505,6 @@ def separable_model(self, names=None): Defn: z |--> x_ y |--> x_^3 x |--> x_^6) - """ if names is None: pass @@ -1582,9 +1574,9 @@ def change_variable_name(self, name): INPUT: - - ``name`` -- a string or a tuple consisting of a strings, the names of + - ``name`` -- string or tuple consisting of a strings; the names of the new variables starting with a generator of this field and going - down to the rational function field. + down to the rational function field OUTPUT: @@ -1642,7 +1634,6 @@ def change_variable_name(self, name): Defn: z |--> zz y |--> yy x |--> xx) - """ if not isinstance(name, tuple): name = (name,) @@ -1736,7 +1727,7 @@ def places_above(self, p): INPUT: - - ``p`` -- place of the base rational function field. + - ``p`` -- place of the base rational function field EXAMPLES:: @@ -1898,7 +1889,7 @@ def residue_field(self, place, name=None): ideal. If an element not in the valuation ring is applied to the map, an - exception ``TypeError`` is raised. + exception :exc:`TypeError` is raised. EXAMPLES:: @@ -2096,7 +2087,7 @@ def get_place(self, degree): INPUT: - - ``degree`` -- a positive integer + - ``degree`` -- positive integer OUTPUT: a place of ``degree`` if any exists; otherwise ``None`` @@ -2122,7 +2113,6 @@ def get_place(self, degree): sage: L.get_place(7) Place (x^7 + x + 1, y + x^6 + x^5 + x^4 + x^3 + x) sage: L.get_place(8) - """ for p in self._places_finite(degree): return p @@ -2390,22 +2380,17 @@ def _singular_normal(ideal): sage: _singular_normal(ideal(f)) [[1]] """ - from sage.libs.singular.function import singular_function, lib - lib('normal.lib') + from sage.libs.singular.function import (singular_function, + lib as singular_lib, + get_printlevel, set_printlevel) + singular_lib('normal.lib') normal = singular_function('normal') - execute = singular_function('execute') - - try: - get_printlevel = singular_function('get_printlevel') - except NameError: - execute('proc get_printlevel {return (printlevel);}') - get_printlevel = singular_function('get_printlevel') - # It's fairly verbose unless printlevel is -1. + # verbose unless printlevel is -1. saved_printlevel = get_printlevel() - execute('printlevel=-1') + set_printlevel(-1) nor = normal(ideal) - execute('printlevel={}'.format(saved_printlevel)) + set_printlevel(saved_printlevel) return nor[1] diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index bb2075b1ecf..192b6e0deb6 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -123,7 +123,6 @@ class RationalFunctionField(FunctionField): + Place (x, y - 1) + Place (x, y + 1) - Place (x + i, y) - """ Element = FunctionFieldElement_rational @@ -204,7 +203,6 @@ def __hash__(self): sage: K. = FunctionField(QQ) sage: hash(K) == hash((K.constant_base_field(), K.variable_names())) True - """ return self._hash @@ -253,7 +251,6 @@ def _element_constructor_(self, x): sage: I = S * [x^2 - y^2, y - t] sage: I.groebner_basis() # needs sage.rings.function_field [x^2 - t^2, y - t] - """ if isinstance(x, FunctionFieldElement): return self.element_class(self, self._field(x._x)) @@ -275,7 +272,7 @@ def _to_constant_base_field(self, f): INPUT: - ``f`` -- element of the rational function field which is a - constant of the underlying rational function field. + constant of the underlying rational function field EXAMPLES:: @@ -295,7 +292,6 @@ def _to_constant_base_field(self, f): True sage: x in QQ False - """ K = self.constant_base_field() if f.denominator() in K and f.numerator() in K: @@ -310,7 +306,8 @@ def _to_polynomial(self, f): INPUT: - - ``f`` -- an element of this rational function field whose denominator is a constant. + - ``f`` -- an element of this rational function field whose denominator + is a constant EXAMPLES:: @@ -332,9 +329,7 @@ def _to_bivariate_polynomial(self, f): - ``f`` -- univariate polynomial over the function field - OUTPUT: - - - bivariate polynomial, denominator + OUTPUT: bivariate polynomial, denominator EXAMPLES:: @@ -405,7 +400,6 @@ def _factor_univariate_polynomial(self, f, proof=None): sage: F = t*x sage: F.factor(proof=False) (x) * t - """ old_variable_name = f.variable_name() # the variables of the bivariate polynomial must be distinct @@ -445,9 +439,7 @@ def extension(self, f, names=None): - ``names`` -- string or length-1 tuple - OUTPUT: - - - a function field + OUTPUT: a function field EXAMPLES:: @@ -506,7 +498,8 @@ def free_module(self, base=None, basis=None, map=True): - ``basis`` -- (ignored) a basis for the vector space - - ``map`` -- (default ``True``), whether to return maps to and from the vector space + - ``map`` -- (default: ``True``) whether to return maps to and from the + vector space OUTPUT: @@ -538,7 +531,6 @@ def free_module(self, base=None, basis=None, map=True): Isomorphism: From: Rational function field in x over Rational Field To: Vector space of dimension 1 over Rational function field in x over Rational Field) - """ if basis is not None: raise NotImplementedError @@ -648,11 +640,9 @@ def hom(self, im_gens, base_morphism=None): ``base_morphism``; this is not checked. - ``base_morphism`` -- a homomorphism from the base field into the - other ring. If ``None``, try to use a coercion map. - - OUTPUT: + other ring; if ``None``, try to use a coercion map - - a map between function fields + OUTPUT: a map between function fields EXAMPLES: @@ -706,7 +696,6 @@ def field(self): .. SEEALSO:: :meth:`sage.rings.fraction_field.FractionField_1poly_field.function_field` - """ return self._field @@ -800,7 +789,7 @@ def change_variable_name(self, name): INPUT: - - ``name`` -- a string or a tuple consisting of a single string, the + - ``name`` -- string or tuple consisting of a single string; the name of the new variable OUTPUT: @@ -825,7 +814,6 @@ def change_variable_name(self, name): Defn: x |--> y) sage: L.change_variable_name('x')[0] is K True - """ if isinstance(name, tuple): if len(name) != 1: @@ -974,7 +962,7 @@ def get_place(self, degree): INPUT: - - ``degree`` -- a positive integer + - ``degree`` -- positive integer EXAMPLES:: @@ -990,7 +978,6 @@ def get_place(self, degree): Place (x^4 + x + 1) sage: K.get_place(5) # needs sage.libs.pari Place (x^5 + x^2 + 1) - """ for p in self._places_finite(degree): return p diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 00450c60533..2ef9d20d132 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -445,7 +445,6 @@ def factor(self): sage: I = O.ideal(y) sage: I == I.factor().prod() True - """ return Factorization(self._factor(), cr=True) @@ -700,9 +699,7 @@ def module(self): The formation of the module is compatible with the vector space corresponding to the function field. - OUTPUT: - - - a module over the maximal order of the base field of the ideal + OUTPUT: a module over the maximal order of the base field of the ideal EXAMPLES:: @@ -967,7 +964,7 @@ def __contains__(self, x): def __hash__(self): """ - Return the hash of this ideal + Return the hash of this ideal. EXAMPLES:: diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index 83a1370e493..829598231cb 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -30,7 +30,7 @@ class FunctionFieldIdeal_polymod(FunctionFieldIdeal): """ - Fractional ideals of algebraic function fields + Fractional ideals of algebraic function fields. INPUT: @@ -468,7 +468,6 @@ def intersect(self, other): sage: J = O.ideal(x) sage: I.intersect(J) == I * J * (I + J)^-1 True - """ from sage.matrix.special import block_matrix from .hermite_form_polynomial import reversed_hermite_form @@ -1025,7 +1024,7 @@ def _factor(self): class FunctionFieldIdeal_global(FunctionFieldIdeal_polymod): """ - Fractional ideals of canonical function fields + Fractional ideals of canonical function fields. INPUT: diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 2ef3a6beba4..59c63cc9782 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -29,9 +29,9 @@ class FunctionFieldIdeal_rational(FunctionFieldIdeal): INPUT: - - ``ring`` -- the maximal order of the rational function field. + - ``ring`` -- the maximal order of the rational function field - - ``gen`` -- generator of the ideal, an element of the function field. + - ``gen`` -- generator of the ideal, an element of the function field EXAMPLES:: diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index 7954a842f13..405d90bfc3f 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -238,7 +238,7 @@ def _apply_functor(self, jacobian): def merge(self, other): """ - Return the functor merging ``self`` and ``other`` + Return the functor merging ``self`` and ``other``. INPUT: @@ -549,7 +549,7 @@ def get_points(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -633,7 +633,7 @@ def _an_element_(self): def __call__(self, x): """ - Return the point of ``self`` constructed from ``x`` + Return the point of ``self`` constructed from ``x``. It is assumed that ``self`` and ``x`` are points of the Jacobians attached to the same function field. @@ -776,7 +776,7 @@ def set_base_place(self, place): INPUT: - - ``place`` -- a rational place of the function field. + - ``place`` -- a rational place of the function field The base place `B` is used to map a rational place `P` of the function field to the point of the Jacobian defined by the divisor `P - B`. diff --git a/src/sage/rings/function_field/jacobian_hess.py b/src/sage/rings/function_field/jacobian_hess.py index 13e930fd620..a85bc10e256 100644 --- a/src/sage/rings/function_field/jacobian_hess.py +++ b/src/sage/rings/function_field/jacobian_hess.py @@ -832,7 +832,7 @@ def zero(self): class JacobianGroup_finite_field(JacobianGroup, JacobianGroup_finite_field_base): """ - Jacobian groups of function fields over finite fields + Jacobian groups of function fields over finite fields. INPUT: diff --git a/src/sage/rings/function_field/jacobian_khuri_makdisi.py b/src/sage/rings/function_field/jacobian_khuri_makdisi.py index 012dc983355..2c9a2e5da97 100644 --- a/src/sage/rings/function_field/jacobian_khuri_makdisi.py +++ b/src/sage/rings/function_field/jacobian_khuri_makdisi.py @@ -66,7 +66,6 @@ allows representing points of Jacobian as matrices once we fix a basis of the Riemann-Roch space. - EXAMPLES:: sage: P2. = ProjectiveSpace(GF(17), 2) @@ -170,7 +169,6 @@ class JacobianPoint(JacobianPoint_base): [0 0 0 1 0 0 0 0 5] [0 0 0 0 0 1 0 0 5] [0 0 0 0 0 0 1 0 4] - """ def __init__(self, parent, w): """ @@ -338,7 +336,7 @@ def _rmul_(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -361,7 +359,7 @@ def multiple(self, n): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: diff --git a/src/sage/rings/function_field/khuri_makdisi.pyx b/src/sage/rings/function_field/khuri_makdisi.pyx index 266a83a5c54..5933abcd1ce 100644 --- a/src/sage/rings/function_field/khuri_makdisi.pyx +++ b/src/sage/rings/function_field/khuri_makdisi.pyx @@ -472,7 +472,7 @@ cdef class KhuriMakdisi_large(KhuriMakdisi_base): cpdef Matrix addflip(self, Matrix wd1, Matrix wd2): """ - Theorem 4.3 (addflip) + Theorem 4.3 (addflip). TESTS:: diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 2863a953f20..6b37456c64c 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -157,7 +157,6 @@ def _richcmp_(self, other, op): sage: g = K.coerce_map_from(L) sage: f == g False - """ if type(self) is not type(other): return NotImplemented @@ -245,7 +244,6 @@ def _call_(self, v): ....: for i in range(100): ....: a = F.random_element() ....: assert(f(t(a)) == a) - """ fields = self._K._intermediate_fields(self._V.base_field()) fields.pop() @@ -325,7 +323,7 @@ def __init__(self, K, V): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) sage: V, f, t = L.vector_space() - sage: TestSuite(t).run(skip="_test_category") + sage: TestSuite(t).run(skip='_test_category') """ self._V = V self._K = K @@ -359,7 +357,6 @@ def _call_(self, x): ....: for i in range(100): ....: a = V.random_element() ....: assert(t(f(a)) == a) - """ ret = [x] fields = self._K._intermediate_fields(self._V.base_field()) @@ -393,7 +390,7 @@ def __init__(self, parent, im_gen, base_morphism): sage: f = K.hom(1/x); f Function Field endomorphism of Rational function field in x over Rational Field Defn: x |--> 1/x - sage: TestSuite(f).run(skip="_test_category") + sage: TestSuite(f).run(skip='_test_category') """ RingHomomorphism.__init__(self, parent) @@ -461,7 +458,7 @@ def __init__(self, parent, im_gen, base_morphism): sage: K. = FunctionField(GF(7)); R. = K[] sage: L. = K.extension(y^3 + 6*x^3 + x) sage: f = L.hom(y*2) - sage: TestSuite(f).run(skip="_test_category") + sage: TestSuite(f).run(skip='_test_category') """ FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism) # Verify that the morphism is valid: @@ -579,7 +576,8 @@ def __init__(self, parent): def _repr_type(self) -> str: r""" - Return the type of this map (a conversion), for the purposes of printing out self. + Return the type of this map (a conversion), for the purposes of + printing out ``self``. EXAMPLES:: @@ -588,7 +586,6 @@ def _repr_type(self) -> str: Conversion map: From: Rational function field in x over Rational Field To: Rational Field - """ return "Conversion" @@ -599,7 +596,6 @@ def _call_(self, x): sage: K. = FunctionField(QQ) sage: QQ(K(1)) # indirect doctest 1 - """ return x.parent()._to_constant_base_field(x) @@ -628,7 +624,6 @@ class FunctionFieldToFractionField(FunctionFieldVectorSpaceIsomorphism): sage: isinstance(f, FunctionFieldToFractionField) True sage: TestSuite(f).run() - """ def _call_(self, f): r""" @@ -641,7 +636,6 @@ def _call_(self, f): sage: f = K.coerce_map_from(L) sage: f(~L.gen()) 1/x - """ return self.codomain()(f.numerator(), f.denominator()) @@ -832,7 +826,7 @@ def _repr_type(self) -> str: def _call_(self, f): """ - Call the completion for f + Call the completion for f. EXAMPLES:: diff --git a/src/sage/rings/function_field/meson.build b/src/sage/rings/function_field/meson.build new file mode 100644 index 00000000000..16e5fa6fa6f --- /dev/null +++ b/src/sage/rings/function_field/meson.build @@ -0,0 +1,55 @@ +py.install_sources( + 'all.py', + 'constructor.py', + 'derivations.py', + 'derivations_polymod.py', + 'derivations_rational.py', + 'differential.py', + 'divisor.py', + 'element.pxd', + 'extensions.py', + 'function_field.py', + 'function_field_polymod.py', + 'function_field_rational.py', + 'ideal.py', + 'ideal_polymod.py', + 'ideal_rational.py', + 'jacobian_base.py', + 'jacobian_hess.py', + 'jacobian_khuri_makdisi.py', + 'maps.py', + 'order.py', + 'order_basis.py', + 'order_polymod.py', + 'order_rational.py', + 'place.py', + 'place_polymod.py', + 'place_rational.py', + 'valuation.py', + 'valuation_ring.py', + subdir: 'sage/rings/function_field', +) + +extension_data = { + 'element' : files('element.pyx'), + 'element_polymod' : files('element_polymod.pyx'), + 'element_rational' : files('element_rational.pyx'), + 'hermite_form_polynomial' : files('hermite_form_polynomial.pyx'), + 'khuri_makdisi' : files('khuri_makdisi.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/function_field', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp], + ) +endforeach + +install_subdir( + 'drinfeld_modules', + install_dir: sage_install_dir / 'rings/function_field', +) diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index eebaeab97d1..1cf89e3f966 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -28,8 +28,8 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): - ``basis`` -- list of elements of the function field - - ``check`` -- (default: ``True``) if ``True``, check whether the module - that ``basis`` generates forms an order + - ``check`` -- boolean (default: ``True``); if ``True``, check whether the + module that ``basis`` generates forms an order EXAMPLES:: @@ -102,7 +102,7 @@ def __init__(self, basis, check=True): if check: if self._module.rank() != field.degree(): raise ValueError("basis {} is not linearly independent".format(basis)) - if not to_V(field(1)) in self._module: + if to_V(field(1)) not in self._module: raise ValueError("the identity element must be in the module spanned by basis {}".format(basis)) if not all(to_V(a*b) in self._module for a in basis for b in basis): raise ValueError("the module generated by basis {} must be closed under multiplication".format(basis)) @@ -399,7 +399,7 @@ def __init__(self, basis, check=True): if check: if self._module.rank() != field.degree(): raise ValueError("basis {} is not linearly independent".format(basis)) - if not W.coordinate_vector(to(field(1))) in self._module: + if W.coordinate_vector(to(field(1))) not in self._module: raise ValueError("the identity element must be in the module spanned by basis {}".format(basis)) if not all(W.coordinate_vector(to(a*b)) in self._module for a in basis for b in basis): raise ValueError("the module generated by basis {} must be closed under multiplication".format(basis)) @@ -431,7 +431,7 @@ def _element_constructor_(self, f): V, fr_V, to_V = F.vector_space() W = self._ambient_space - if not W.coordinate_vector(to_V(f)) in self._module: + if W.coordinate_vector(to_V(f)) not in self._module: raise TypeError("{} is not an element of {}".format(f, self)) return f diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index ad760aad0b6..16ff2d8f2ae 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -17,6 +17,7 @@ # **************************************************************************** from sage.arith.functions import lcm +from sage.categories.commutative_algebras import CommutativeAlgebras from sage.misc.cachefunc import cached_method from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -73,9 +74,8 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): n = len(basis) self._mtable = [] for i in range(n): - row = [] - for j in range(n): - row.append(self._coordinate_vector(basis[i] * basis[j])) + row = [self._coordinate_vector(basis[i] * basis[j]) + for j in range(n)] self._mtable.append(row) zero = vector(R._ring, n * [0]) @@ -248,8 +248,8 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): - ``d`` -- (default: 1) a nonzero element of the polynomial ring - - ``check`` -- boolean (default: ``True``); if ``True``, compute the real - denominator of the vectors, possibly different from ``d``. + - ``check`` -- boolean (default: ``True``); if ``True``, compute the + real denominator of the vectors, possibly different from ``d`` EXAMPLES:: @@ -617,7 +617,6 @@ def decomposition(self, ideal): Use Kummer's theorem to shortcut this code if possible, like as done in :meth:`FunctionFieldMaximalOrder_global.decomposition()` - """ from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra from sage.matrix.constructor import matrix @@ -643,13 +642,16 @@ def decomposition(self, ideal): # the basis of this order, construct the n n-by-n matrices that show # how to multiply by each of the basis elements. matrices = [matrix(o, [self.coordinate_vector(b1*b2) for b1 in self.basis()]) - for b2 in self.basis()] + for b2 in self.basis()] # Let O denote the maximal order self. When reduced modulo p, # matrices_reduced give the multiplication matrices used to form the # algebra O mod pO. - matrices_reduced = list(map(lambda M: M.mod(p), matrices)) - A = FiniteDimensionalAlgebra(k, matrices_reduced) + matrices_reduced = [M.mod(p) for M in matrices] + cat = CommutativeAlgebras(k).FiniteDimensional().WithBasis() + A = FiniteDimensionalAlgebra(k, matrices_reduced, + assume_associative=True, + category=cat) # Each prime ideal of the algebra A corresponds to a prime ideal of O, # and since the algebra is an Artinian ring, all of its prime ideals @@ -680,7 +682,7 @@ def decomposition(self, ideal): # not be in pO. To ensure that beta*P is in pO, multiplying # beta by each of P's generators must produce a vector whose # elements are multiples of p. We can ensure that all this - # occurs by constructing a matrix in k, and finding a non-zero + # occurs by constructing a matrix in k, and finding a nonzero # vector in the kernel of the matrix. m = [] @@ -886,7 +888,7 @@ def ideal(self, *gens): """ if len(gens) == 1: gens = gens[0] - if not type(gens) in (list,tuple): + if type(gens) not in (list,tuple): gens = (gens,) mgens = [g * b for g in gens for b in self._basis] return self.ideal_with_gens_over_base(mgens) @@ -1313,7 +1315,7 @@ def decomposition(self, ideal): Ip = self.p_radical(ideal) Ob = matrix.identity(Fp, n) - def bar(I): # transfer to O/pO + def bar(I): # transfer to O/pO m = [] for v in I._hnf: m.append([to(e) for e in v]) @@ -1322,8 +1324,8 @@ def bar(I): # transfer to O/pO def liftb(Ib): m = [vector([fr(e) for e in v]) for v in Ib] - m += [v for v in pO._hnf] - return self._ideal_from_vectors_and_denominator(m,1) + m.extend(pO._hnf) + return self._ideal_from_vectors_and_denominator(m, 1) def cut_last_zero_rows(h): i = h.nrows() @@ -1331,17 +1333,17 @@ def cut_last_zero_rows(h): i -= 1 return h[:i] - def mul_vec(v1,v2): + def mul_vec(v1, v2): s = 0 for i in range(n): for j in range(n): s += v1[i] * v2[j] * mtable[i][j] return s - def pow(v, r): # r > 0 + def pow(v, r): # r > 0 m = v while r > 1: - m = mul_vec(m,v) + m = mul_vec(m, v) r -= 1 return m diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py index b21712bcf2c..d90124c6800 100644 --- a/src/sage/rings/function_field/order_rational.py +++ b/src/sage/rings/function_field/order_rational.py @@ -83,7 +83,7 @@ def _element_constructor_(self, f): except TypeError: raise TypeError("unable to convert to an element of {}".format(F)) - if not f.denominator() in self.function_field().constant_base_field(): + if f.denominator() not in self.function_field().constant_base_field(): raise TypeError("%r is not an element of %r" % (f,self)) return f @@ -287,7 +287,6 @@ def _residue_field_global(self, q, name=None): sage: K, fr_K, to_K = O._residue_field_global(_f) # needs sage.modules sage: all(to_K(fr_K(e)) == e for e in K) # needs sage.modules True - """ # polynomial ring over the base field R = self._ring @@ -494,7 +493,8 @@ def basis(self): def gen(self, n=0): """ - Return the ``n``-th generator of self. Since there is only one generator ``n`` must be 0. + Return the `n`-th generator of ``self``. Since there is only one + generator `n` must be `0`. EXAMPLES:: diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index ee9e8de5874..7a5f2b90cad 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -387,7 +387,7 @@ def _residue_field(self, name=None): INPUT: - - ``name`` -- string (default: `None`); name of the generator + - ``name`` -- string (default: ``None``); name of the generator of the residue field EXAMPLES:: diff --git a/src/sage/rings/function_field/valuation.py b/src/sage/rings/function_field/valuation.py index 5bd32b7901e..a192a76beb6 100644 --- a/src/sage/rings/function_field/valuation.py +++ b/src/sage/rings/function_field/valuation.py @@ -180,7 +180,6 @@ class FunctionFieldValuationFactory(UniqueFactory): 1 See :meth:`sage.rings.function_field.function_field.FunctionField.valuation` for further examples. - """ def create_key_and_extra_args(self, domain, prime): r""" @@ -207,7 +206,6 @@ def create_key_and_extra_args(self, domain, prime): sage: w = K.valuation(w) sage: w is K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) False - """ from sage.categories.function_fields import FunctionFields if domain not in FunctionFields(): @@ -242,8 +240,8 @@ def create_key_and_extra_args(self, domain, prime): # unique extension to domain base_valuation = domain.base_field().valuation(prime) return self.create_key_and_extra_args_from_valuation(domain, base_valuation) - from sage.rings.ideal import is_Ideal - if is_Ideal(prime): + from sage.rings.ideal import Ideal_generic + if isinstance(prime, Ideal_generic): raise NotImplementedError("a place cannot be given by an ideal yet") raise NotImplementedError("argument must be a place or a pseudo-valuation on a supported subring but %r does not satisfy this for the domain %r" % (prime, domain)) @@ -257,7 +255,6 @@ def create_key_and_extra_args_from_place(self, domain, generator): sage: K. = FunctionField(QQ) sage: v = K.valuation(1/x) # indirect doctest - """ if generator not in domain.base_field(): raise NotImplementedError("a place must be defined over a rational function field") @@ -313,7 +310,6 @@ def create_key_and_extra_args_from_valuation(self, domain, valuation): (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y), [ (x)-adic valuation, v(y) = 1/2 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y)] - """ # this should have been handled by create_key already assert valuation.domain() is not domain @@ -358,7 +354,6 @@ def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, v sage: L. = K.extension(y^2 + y + x^3) # needs sage.rings.function_field sage: v = K.valuation(1/x) # needs sage.rings.function_field sage: w = v.extension(L) # indirect doctest # needs sage.rings.function_field - """ from sage.categories.function_fields import FunctionFields if valuation.domain() not in FunctionFields(): @@ -404,7 +399,6 @@ def create_object(self, version, key, **extra_args): sage: w = valuations.GaussValuation(R, QQ.valuation(2)) sage: v = K.valuation(w); v # indirect doctest 2-adic valuation - """ domain, valuation = key from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace @@ -469,7 +463,6 @@ class FunctionFieldValuation_base(DiscretePseudoValuation): sage: from sage.rings.function_field.valuation import FunctionFieldValuation_base sage: isinstance(v, FunctionFieldValuation_base) True - """ @@ -484,7 +477,6 @@ class DiscreteFunctionFieldValuation_base(DiscreteValuation): sage: from sage.rings.function_field.valuation import DiscreteFunctionFieldValuation_base sage: isinstance(v, DiscreteFunctionFieldValuation_base) True - """ def extensions(self, L): r""" @@ -597,7 +589,6 @@ class RationalFunctionFieldValuation_base(FunctionFieldValuation_base): sage: from sage.rings.function_field.valuation import RationalFunctionFieldValuation_base sage: isinstance(v, RationalFunctionFieldValuation_base) True - """ @cached_method def element_with_valuation(self, s): @@ -618,7 +609,6 @@ def element_with_valuation(self, s): 2/x sage: w.element_with_valuation(1) 2 - """ constant_valuation = self.restriction(self.domain().constant_base_field()) if constant_valuation.is_trivial(): @@ -642,7 +632,6 @@ class ClassicalFunctionFieldValuation_base(DiscreteFunctionFieldValuation_base): sage: from sage.rings.function_field.valuation import ClassicalFunctionFieldValuation_base sage: isinstance(v, ClassicalFunctionFieldValuation_base) True - """ def _test_classical_residue_field(self, **options): r""" @@ -654,7 +643,6 @@ def _test_classical_residue_field(self, **options): sage: K. = FunctionField(QQ) sage: v = K.valuation(x^2 + 1) sage: v._test_classical_residue_field() # needs sage.rings.number_field - """ tester = self._tester(**options) @@ -673,7 +661,6 @@ def _ge_(self, other): False sage: w >= v False - """ if other.is_trivial(): return other.is_discrete_valuation() @@ -691,7 +678,6 @@ class InducedRationalFunctionFieldValuation_base(FunctionFieldValuation_base): sage: K. = FunctionField(QQ) sage: v = K.valuation(x^2 + 1) # indirect doctest - """ def __init__(self, parent, base_valuation): r""" @@ -702,7 +688,6 @@ def __init__(self, parent, base_valuation): sage: from sage.rings.function_field.valuation import InducedRationalFunctionFieldValuation_base sage: isinstance(v, InducedRationalFunctionFieldValuation_base) True - """ FunctionFieldValuation_base.__init__(self, parent) @@ -721,7 +706,6 @@ def uniformizer(self): sage: K. = FunctionField(QQ) sage: K.valuation(x).uniformizer() x - """ return self.domain()(self._base_valuation.uniformizer()) @@ -738,7 +722,6 @@ def lift(self, F): 0 sage: v.lift(1) 1 - """ F = self.residue_ring().coerce(F) if F in self._base_valuation.residue_ring(): @@ -761,7 +744,6 @@ def value_group(self): sage: K. = FunctionField(QQ) sage: K.valuation(x).value_group() Additive Abelian Group generated by 1 - """ return self._base_valuation.value_group() @@ -775,7 +757,6 @@ def reduce(self, f): sage: v = K.valuation(x^2 + 1) sage: v.reduce(x) # needs sage.rings.number_field u1 - """ f = self.domain().coerce(f) @@ -806,7 +787,6 @@ def _repr_(self): sage: K. = FunctionField(QQ) sage: K.valuation(x^2 + 1) # indirect doctest (x^2 + 1)-adic valuation - """ from sage.rings.valuation.augmented_valuation import AugmentedValuation_base from sage.rings.valuation.gauss_valuation import GaussValuation @@ -832,7 +812,6 @@ def extensions(self, L): sage: L. = FunctionField(GaussianIntegers().fraction_field()) sage: v.extensions(L) # indirect doctest [(x - I)-adic valuation, (x + I)-adic valuation] - """ K = self.domain() if L is K: @@ -865,7 +844,6 @@ def _call_(self, f): sage: v = K.valuation(x) # indirect doctest sage: v((x+1)/x^2) -2 - """ return self._base_valuation(f.numerator()) - self._base_valuation(f.denominator()) @@ -878,7 +856,6 @@ def residue_ring(self): sage: K. = FunctionField(QQ) sage: K.valuation(x).residue_ring() Rational Field - """ return self._base_valuation.residue_ring().fraction_field() @@ -891,7 +868,6 @@ def restriction(self, ring): sage: K. = FunctionField(QQ) sage: K.valuation(x).restriction(QQ) Trivial valuation on Rational Field - """ if ring.is_subring(self._base_valuation.domain()): return self._base_valuation.restriction(ring) @@ -923,7 +899,6 @@ def simplify(self, f, error=None, force=False): sage: v.simplify(f, force=True) 3 - """ f = self.domain().coerce(f) @@ -984,7 +959,6 @@ def _relative_size(self, f): sage: v.simplify(f, force=True) -1 - """ return max(self._base_valuation._relative_size(f.numerator()), self._base_valuation._relative_size(f.denominator())) @@ -1015,7 +989,6 @@ class FiniteRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation sage: q = L.valuation(x^6 - t); q (x^6 + 2*t)-adic valuation - """ def __init__(self, parent, base_valuation): r""" @@ -1026,7 +999,6 @@ def __init__(self, parent, base_valuation): sage: from sage.rings.function_field.valuation import FiniteRationalFunctionFieldValuation sage: isinstance(v, FiniteRationalFunctionFieldValuation) True - """ InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation) ClassicalFunctionFieldValuation_base.__init__(self, parent) @@ -1044,7 +1016,6 @@ class NonClassicalRationalFunctionFieldValuation(InducedRationalFunctionFieldVal sage: v = GaussValuation(QQ['x'], QQ.valuation(2)) sage: w = K.valuation(v); w # indirect doctest 2-adic valuation - """ def __init__(self, parent, base_valuation): r""" @@ -1061,7 +1032,6 @@ def __init__(self, parent, base_valuation): sage: from sage.rings.function_field.valuation import NonClassicalRationalFunctionFieldValuation sage: isinstance(w, NonClassicalRationalFunctionFieldValuation) True - """ InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation) RationalFunctionFieldValuation_base.__init__(self, parent) @@ -1100,7 +1070,6 @@ def residue_ring(self): sage: w = K.valuation(vv) sage: w.residue_ring() Finite Field of size 2 - """ if not self.is_discrete_valuation(): # A pseudo valuation attaining negative infinity does typically not have a function field as its residue ring @@ -1121,7 +1090,6 @@ class FunctionFieldFromLimitValuation(FiniteExtensionFromLimitValuation, Discret sage: v = K.valuation(x - 1) # indirect doctest # needs sage.rings.function_field sage: w = v.extension(L); w # needs sage.rings.function_field (x - 1)-adic valuation - """ def __init__(self, parent, approximant, G, approximants): r""" @@ -1136,7 +1104,6 @@ def __init__(self, parent, approximant, G, approximants): sage: from sage.rings.function_field.valuation import FunctionFieldFromLimitValuation sage: isinstance(w, FunctionFieldFromLimitValuation) True - """ FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants) DiscreteFunctionFieldValuation_base.__init__(self, parent) @@ -1155,7 +1122,6 @@ def _to_base_domain(self, f): sage: w = v.extension(L) sage: w._to_base_domain(y).parent() Univariate Polynomial Ring in y over Rational function field in x over Rational Field - """ return f.element() @@ -1173,7 +1139,6 @@ def scale(self, scalar): sage: w = v.extension(L) sage: 3*w 3 * (x - 1)-adic valuation - """ if scalar in QQ and scalar > 0 and scalar != 1: return self.domain().valuation(self._base_valuation._initial_approximation.scale(scalar)) @@ -1190,7 +1155,6 @@ class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValua sage: K. = FunctionField(GF(2)) sage: v = K.valuation(1/x); v Valuation at the infinite place - """ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain): r""" @@ -1201,7 +1165,6 @@ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_v sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuation_base sage: isinstance(v, FunctionFieldMappedValuation_base) True - """ FunctionFieldValuation_base.__init__(self, parent) MappedValuation_base.__init__(self, parent, base_valuation) @@ -1222,7 +1185,6 @@ def _to_base_domain(self, f): sage: w = v.extension(L) # needs sage.rings.function_field sage: w._to_base_domain(y) # needs sage.rings.function_field x^2*y - """ return self._to_base(f) @@ -1256,7 +1218,6 @@ def scale(self, scalar): sage: w = v.extension(L) # needs sage.rings.function_field sage: 3*w # needs sage.rings.function_field 3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x) - """ from sage.rings.rational_field import QQ if scalar in QQ and scalar > 0 and scalar != 1: @@ -1275,7 +1236,6 @@ def _repr_(self): sage: v = K.valuation(1/x) sage: v.extension(L) # indirect doctest # needs sage.rings.function_field Valuation at the infinite place - """ to_base = repr(self._to_base) if hasattr(self._to_base, '_repr_defn'): @@ -1296,7 +1256,6 @@ def is_discrete_valuation(self): sage: w0,w1 = v.extensions(L) sage: w0.is_discrete_valuation() True - """ return self._base_valuation.is_discrete_valuation() @@ -1312,7 +1271,6 @@ class FunctionFieldMappedValuationRelative_base(FunctionFieldMappedValuation_bas sage: K. = FunctionField(GF(2)) sage: v = K.valuation(1/x); v Valuation at the infinite place - """ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain): r""" @@ -1323,7 +1281,6 @@ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_v sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuationRelative_base sage: isinstance(v, FunctionFieldMappedValuationRelative_base) True - """ FunctionFieldMappedValuation_base.__init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain) if self.domain().constant_base_field() is not base_valuation.domain().constant_base_field(): @@ -1338,7 +1295,6 @@ def restriction(self, ring): sage: K. = FunctionField(GF(2)) sage: K.valuation(1/x).restriction(GF(2)) Trivial valuation on Finite Field of size 2 - """ if ring.is_subring(self.domain().constant_base_field()): return self._base_valuation.restriction(ring) @@ -1360,7 +1316,6 @@ class RationalFunctionFieldMappedValuation(FunctionFieldMappedValuationRelative_ Valuation on rational function field induced by [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] (in Rational function field in x over Rational Field after x |--> 1/x) - """ def __init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain): r""" @@ -1374,7 +1329,6 @@ def __init__(self, parent, base_valuation, to_base_valuation_doain, from_base_va sage: from sage.rings.function_field.valuation import RationalFunctionFieldMappedValuation sage: isinstance(v, RationalFunctionFieldMappedValuation) True - """ FunctionFieldMappedValuationRelative_base.__init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain) RationalFunctionFieldValuation_base.__init__(self, parent) @@ -1388,7 +1342,6 @@ class InfiniteRationalFunctionFieldValuation(FunctionFieldMappedValuationRelativ sage: K. = FunctionField(QQ) sage: v = K.valuation(1/x) # indirect doctest - """ def __init__(self, parent): r""" @@ -1399,7 +1352,6 @@ def __init__(self, parent): sage: from sage.rings.function_field.valuation import InfiniteRationalFunctionFieldValuation sage: isinstance(v, InfiniteRationalFunctionFieldValuation) True - """ x = parent.domain().gen() FunctionFieldMappedValuationRelative_base.__init__(self, parent, FunctionFieldValuation(parent.domain(), x), parent.domain().hom([1/x]), parent.domain().hom([1/x])) @@ -1415,7 +1367,6 @@ def _repr_(self): sage: K. = FunctionField(QQ) sage: K.valuation(1/x) # indirect doctest Valuation at the infinite place - """ return "Valuation at the infinite place" @@ -1448,7 +1399,6 @@ class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative sage: from sage.rings.function_field.valuation import FunctionFieldExtensionMappedValuation sage: isinstance(w, FunctionFieldExtensionMappedValuation) # needs sage.rings.function_field True - """ def _repr_(self): r""" @@ -1472,7 +1422,6 @@ def _repr_(self): sage: w = v.extensions(L); w [[ Valuation at the infinite place, v(y + 1) = 2 ]-adic valuation, [ Valuation at the infinite place, v(y - 1) = 2 ]-adic valuation] - """ assert (self.domain().base() is not self.domain()) if repr(self._base_valuation) == repr(self.restriction(self.domain().base())): diff --git a/src/sage/rings/homset.py b/src/sage/rings/homset.py index 6e3126d7ebd..94781b87396 100644 --- a/src/sage/rings/homset.py +++ b/src/sage/rings/homset.py @@ -53,11 +53,10 @@ def RingHomset(R, S, category=None): sage: Hom(ZZ, QQ) # indirect doctest Set of Homomorphisms from Integer Ring to Rational Field - """ - if quotient_ring.is_QuotientRing(R): - from .polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing - if not is_PolynomialQuotientRing(R): # backwards compatibility + if isinstance(R, quotient_ring.QuotientRing_nc): + from .polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic + if not isinstance(R, PolynomialQuotientRing_generic): # backwards compatibility return RingHomset_quo_ring(R, S, category=category) return RingHomset_generic(R, S, category=category) @@ -204,7 +203,7 @@ def _element_constructor_(self, x, check=True, base_map=None): def natural_map(self): """ - Returns the natural map from the domain to the codomain. + Return the natural map from the domain to the codomain. The natural map is the coercion map from the domain ring to the codomain ring. @@ -240,7 +239,6 @@ def zero(self): Traceback (most recent call last): ... ValueError: homset has no zero element - """ if not self.codomain().is_zero(): raise ValueError("homset has no zero element") @@ -324,7 +322,6 @@ def _element_constructor_(self, x, base_map=None, check=True): Coercion map: From: Multivariate Polynomial Ring in x, y over Rational Field To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) - """ if isinstance(x, morphism.RingHomomorphism_from_quotient): phi = x._phi() diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index ccb9128a540..4208c63c55c 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -48,22 +48,20 @@ def Ideal(*args, **kwds): There are some shorthand notations for creating an ideal, in addition to using the :func:`Ideal` function: - - ``R.ideal(gens, coerce=True)`` - - ``gens*R`` - - ``R*gens`` + - ``R.ideal(gens, coerce=True)`` + - ``gens*R`` + - ``R*gens`` INPUT: - - ``R`` -- A ring (optional; if not given, will try to infer it from - ``gens``) + - ``R`` -- a ring (optional; if not given, will try to infer it from ``gens``) - - ``gens`` -- list of elements generating the ideal + - ``gens`` -- list of elements generating the ideal - - ``coerce`` -- bool (default: ``True``); - whether ``gens`` need to be coerced into the ring. + - ``coerce`` -- boolean (default: ``True``); whether ``gens`` need to be + coerced into the ring - - OUTPUT: The ideal of ring generated by ``gens``. + OUTPUT: the ideal of ring generated by ``gens`` EXAMPLES:: @@ -222,6 +220,9 @@ def is_Ideal(x): sage: from sage.rings.ideal import is_Ideal sage: R = ZZ sage: is_Ideal(R) + doctest:warning... + DeprecationWarning: The function is_Ideal is deprecated; use 'isinstance(..., Ideal_generic)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. False sage: 1*R; is_Ideal(1*R) Principal ideal (1) of Integer Ring @@ -240,6 +241,10 @@ def is_Ideal(x): sage: is_Ideal((x^2 + 1)*R) True """ + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_Ideal is deprecated; " + "use 'isinstance(..., Ideal_generic)' instead.") return isinstance(x, Ideal_generic) @@ -255,12 +260,12 @@ def __init__(self, ring, gens, coerce=True, **kwds): INPUT: - - ``ring`` -- A ring + - ``ring`` -- a ring - - ``gens`` -- The generators for this ideal + - ``gens`` -- the generators for this ideal - - ``coerce`` -- (default: ``True``) If ``gens`` needs to be coerced - into ``ring``. + - ``coerce`` -- boolean (default: ``True``); if ``gens`` needs to be coerced + into ``ring`` EXAMPLES:: @@ -320,7 +325,7 @@ def _repr_short(self): return '\n(\n %s\n)\n' % (',\n\n '.join(L)) return '(%s)' % (', '.join(L)) - def __repr__(self): + def _repr_(self): """ Return a string representation of ``self``. @@ -342,21 +347,18 @@ def random_element(self, *args, **kwds): sage: I = P.ideal([a^2, a*b + c, c^3]) sage: I.random_element() # random 2*a^5*c + a^2*b*c^4 + ... + O(a, b, c)^13 - """ return sum(self.__ring.random_element(*args, **kwds) * g for g in self.__gens) def _richcmp_(self, other, op): """ - Compares the generators of two ideals. + Compare the generators of two ideals. INPUT: - ``other`` -- an ideal - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -449,7 +451,7 @@ def __bool__(self): def base_ring(self): r""" - Returns the base ring of this ideal. + Return the base ring of this ideal. EXAMPLES:: @@ -733,7 +735,7 @@ def is_maximal(self): def is_primary(self, P=None): r""" - Returns ``True`` if this ideal is primary (or `P`-primary, if + Return ``True`` if this ideal is primary (or `P`-primary, if a prime ideal `P` is specified). Recall that an ideal `I` is primary if and only if `I` has a @@ -915,7 +917,7 @@ def embedded_primes(self): def is_principal(self): r""" - Returns ``True`` if the ideal is principal in the ring containing the + Return ``True`` if the ideal is principal in the ring containing the ideal. .. TODO:: @@ -1045,7 +1047,7 @@ def __radd__(self, other): def __mul__(self, other): """ - This method just makes sure that ``self`` and other are ideals in the + This method just makes sure that ``self`` and ``other`` are ideals in the same ring and then calls :meth:`_mul_`. If you want to change the behaviour of ideal multiplication in a subclass of :class:`Ideal_generic` please overwrite :meth:`_mul_` and not @@ -1074,7 +1076,7 @@ def _mul_(self, other): This method assumes that ``self`` and ``other`` are Ideals of the same ring. - The number of generators of ```self * other` will be + The number of generators of ``self * other`` will be ``self.ngens() * other.ngens()``. So if used repeatedly this method will create an ideal with a uselessly large amount of generators. Therefore it is advisable to overwrite this method with a method that @@ -1100,7 +1102,6 @@ def __rmul__(self, other): sage: I = [x*y+y*z,x^2+x*y-y*x-y^2]*P sage: [2]*I # indirect doctest Ideal (2*x*y + 2*y*z, 2*x^2 - 2*y^2) of Multivariate Polynomial Ring in x, y, z over Rational Field - """ if not isinstance(other, Ideal_generic): try: @@ -1113,7 +1114,7 @@ def __rmul__(self, other): def norm(self): """ - Returns the norm of this ideal. + Return the norm of this ideal. In the general case, this is just the ideal itself, since the ring it lies in can't be implicitly assumed to be an extension of anything. @@ -1133,7 +1134,7 @@ def norm(self): def absolute_norm(self): """ - Returns the absolute norm of this ideal. + Return the absolute norm of this ideal. In the general case, this is just the ideal itself, since the ring it lies in can't be implicitly assumed to be an extension of anything. @@ -1210,7 +1211,6 @@ def _macaulay2_init_(self, macaulay2=None): sage: R2 = macaulay2(R.ideal(y^2 - x)).ring() # optional - macaulay2 sage: R1._operator('===', R2) # optional - macaulay2 true - """ if macaulay2 is None: from sage.interfaces.macaulay2 import macaulay2 as m2_default @@ -1270,7 +1270,7 @@ class Ideal_principal(Ideal_generic): #def __init__(self, ring, gen): # Ideal_generic.__init__(self, ring, [gen]) - def __repr__(self): + def _repr_(self): """ Return a string representation of ``self``. @@ -1285,7 +1285,7 @@ def __repr__(self): def is_principal(self): r""" - Returns ``True`` if the ideal is principal in the ring containing the + Return ``True`` if the ideal is principal in the ring containing the ideal. When the ideal construction is explicitly principal (i.e. when we define an ideal with one element) this is always the case. @@ -1504,7 +1504,7 @@ def reduce(self, f): def gcd(self, other): r""" - Returns the greatest common divisor of the principal ideal with the + Return the greatest common divisor of the principal ideal with the ideal ``other``; that is, the largest principal ideal contained in both the ideal and ``other`` @@ -1607,7 +1607,7 @@ def is_prime(self): def is_maximal(self): """ - Returns whether this ideal is maximal. + Return whether this ideal is maximal. Principal ideal domains have Krull dimension 1 (or 0), so an ideal is maximal if and only if it's prime (and nonzero if the ring is not a @@ -1700,7 +1700,7 @@ class Ideal_fractional(Ideal_generic): See :func:`Ideal()`. """ - def __repr__(self): + def _repr_(self): """ Return a string representation of ``self``. @@ -1724,15 +1724,15 @@ def Cyclic(R, n=None, homog=False, singular=None): INPUT: - - ``R`` -- base ring to construct ideal for + - ``R`` -- base ring to construct ideal for - - ``n`` -- number of cyclic roots (default: ``None``). If ``None``, then - ``n`` is set to ``R.ngens()``. + - ``n`` -- number of cyclic roots (default: ``None``); if ``None``, then + ``n`` is set to ``R.ngens()`` - - ``homog`` -- (default: ``False``) if ``True`` a homogeneous ideal is - returned using the last variable in the ideal + - ``homog`` -- boolean (default: ``False``); if ``True`` a homogeneous + ideal is returned using the last variable in the ideal - - ``singular`` -- singular instance to use + - ``singular`` -- Singular instance to use .. NOTE:: @@ -1783,22 +1783,21 @@ def Cyclic(R, n=None, homog=False, singular=None): return R2.ideal(I).change_ring(R) def Katsura(R, n=None, homog=False, singular=None): - """ - ``n``-th katsura ideal of ``R`` if ``R`` is coercible to + r""" + `n`-th katsura ideal of `R` if `R` is coercible to :class:`Singular `. INPUT: - ``R`` -- base ring to construct ideal for - - ``n`` -- (default: ``None``) which katsura ideal of ``R``. If ``None``, - then ``n`` is set to ``R.ngens()``. - - - ``homog`` -- if ``True`` a homogeneous ideal is returned - using the last variable in the ideal (default: ``False``) + - ``n`` -- (default: ``None``) which katsura ideal of `R`. If ``None``, + then ``n`` is set to ``R.ngens()`` - - ``singular`` -- singular instance to use + - ``homog`` -- boolean (default: ``False``); if ``True`` a homogeneous + ideal is returned using the last variable in the ideal + - ``singular`` -- Singular instance to use EXAMPLES:: @@ -1809,7 +1808,7 @@ def Katsura(R, n=None, homog=False, singular=None): :: - sage: Q. = PolynomialRing(QQ, implementation="singular") # needs sage.libs.singular + sage: Q. = PolynomialRing(QQ, implementation='singular') # needs sage.libs.singular sage: J = sage.rings.ideal.Katsura(Q,1); J # needs sage.libs.singular Ideal (x - 1) of Multivariate Polynomial Ring in x over Rational Field """ diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index 182b2dd8b8d..986b32cb5d5 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -666,7 +666,7 @@ def _repr_(self) -> str: def _element_constructor_(self, x): """ - The element constructor + The element constructor. TESTS:: @@ -935,7 +935,7 @@ def _mul_(self, other): def _sympy_(self): """ - Converts ``unsigned_infinity`` to sympy ``zoo``. + Convert ``unsigned_infinity`` to sympy ``zoo``. EXAMPLES:: @@ -976,6 +976,10 @@ def is_Infinite(x) -> bool: EXAMPLES:: sage: sage.rings.infinity.is_Infinite(oo) + doctest:warning... + DeprecationWarning: The function is_Infinite is deprecated; + use 'isinstance(..., InfinityElement)' instead. + See https://github.com/sagemath/sage/issues/38022 for details. True sage: sage.rings.infinity.is_Infinite(-oo) True @@ -988,6 +992,9 @@ def is_Infinite(x) -> bool: sage: sage.rings.infinity.is_Infinite(ZZ) False """ + from sage.misc.superseded import deprecation + deprecation(38022, "The function is_Infinite is deprecated; use 'isinstance(..., InfinityElement)' instead.") + return isinstance(x, InfinityElement) @@ -1119,7 +1126,7 @@ def _repr_(self) -> str: def _element_constructor_(self, x): """ - The element constructor + The element constructor. TESTS:: @@ -1622,7 +1629,7 @@ def sqrt(self): def _sympy_(self): """ - Converts ``-oo`` to sympy ``-oo``. + Convert ``-oo`` to sympy ``-oo``. Then you don't have to worry which ``oo`` you use, like in these examples: @@ -1637,7 +1644,6 @@ def _sympy_(self): True sage: bool((-oo)._sympy_() == -sympy.oo) True - """ import sympy return -sympy.oo @@ -1724,7 +1730,7 @@ def sqrt(self): def _sympy_(self): """ - Converts ``oo`` to sympy ``oo``. + Convert ``oo`` to sympy ``oo``. Then you don't have to worry which ``oo`` you use, like in these examples: @@ -1762,7 +1768,7 @@ def _gap_init_(self) -> str: def test_comparison(ring): """ - Check comparison with infinity + Check comparison with infinity. INPUT: @@ -1841,7 +1847,7 @@ def test_signed_infinity(pos_inf): INPUT: - - ``pos_inf`` -- a representation of positive infinity. + - ``pos_inf`` -- a representation of positive infinity OUTPUT: diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index b4a1fa5039b..9616e7946bc 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -276,7 +276,7 @@ cdef _digits_internal(mpz_t v,l,int offset,int power_index,power_list,digits): - ``power_index`` -- a measure of size to fill and index to power_list we're filling ``1 << (power_index+1)`` digits - - ``power_list`` -- a list of powers of the base, precomputed in + - ``power_list`` -- list of powers of the base, precomputed in method digits digits - a python sequence type with objects to use for digits note that python negative index semantics are relied upon @@ -377,7 +377,7 @@ cdef class IntegerWrapper(Integer): def __init__(self, parent=None, x=None, unsigned int base=0): """ We illustrate how to create integers with parents different - from :class:`IntegerRing``:: + from :class:`IntegerRing`:: sage: from sage.rings.integer import IntegerWrapper @@ -574,7 +574,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ... TypeError: Unable to coerce PARI x to an Integer - Test coercion of p-adic with negative valuation:: + Test coercion of `p`-adic with negative valuation:: sage: ZZ(pari(Qp(11)(11^-7))) # needs sage.libs.pari sage.rings.padics Traceback (most recent call last): @@ -592,10 +592,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Test comparisons with numpy types (see :issue:`13386` and :issue:`18076`):: - sage: import numpy # needs numpy - sage: numpy.int8('12') == 12 # needs numpy + sage: # needs numpy + sage: import numpy + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") + sage: numpy.int8('12') == 12 True - sage: 12 == numpy.int8('12') # needs numpy + sage: 12 == numpy.int8('12') True sage: float('15') == 15 @@ -803,7 +806,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def __richcmp__(left, right, int op): """ - cmp for integers + ``cmp`` for integers. EXAMPLES:: @@ -1049,7 +1052,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def __mpz__(self): """ - Return a gmpy2 integer + Return a gmpy2 integer. EXAMPLES:: @@ -1127,7 +1130,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: "{0:#x}; {0:#b}; {0:+05d}".format(ZZ(17)) '0x11; 0b10001; +0017' - """ return int(self).__format__(*args,**kwargs) @@ -1344,7 +1346,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def trailing_zero_bits(self): """ Return the number of trailing zero bits in ``self``, i.e. - the exponent of the largest power of 2 dividing self. + the exponent of the largest power of 2 dividing ``self``. EXAMPLES:: @@ -1358,7 +1360,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 5 sage: 0.trailing_zero_bits() 0 - """ if mpz_sgn(self.value) == 0: return int(0) @@ -1374,14 +1375,14 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``base`` -- integer (default: 10) + - ``base`` -- integer (default: 10) - - ``digits`` -- optional indexable object as source for - the digits + - ``digits`` -- (optional) indexable object as source for + the digits - - ``padto`` -- the minimal length of the returned list, - sufficient number of zeros are added to make the list minimum that - length (default: 0) + - ``padto`` -- the minimal length of the returned list, sufficient + number of zeros are added to make the list minimum that length + (default: 0) As a shorthand for ``digits(2)``, you can use :meth:`.bits`. @@ -1706,7 +1707,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``base`` -- integer (default: 10) + - ``base`` -- integer (default: 10) EXAMPLES:: @@ -2042,7 +2043,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cpdef _div_(self, right): r""" - Computes `\frac{a}{b}` + Compute `\frac{a}{b}`. EXAMPLES:: @@ -2059,7 +2060,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cpdef _floordiv_(self, right): r""" - Computes the whole part of `\frac{x}{y}`. + Compute the whole part of `\frac{x}{y}`. EXAMPLES:: @@ -2328,22 +2329,22 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``n`` -- integer `\geq 1` (must fit in the C ``int`` type). + - ``n`` -- integer `\geq 1` (must fit in the C ``int`` type) - - ``truncate_mode`` -- boolean, whether to allow truncation if - ``self`` is not an ``n``-th power. + - ``truncate_mode`` -- boolean, whether to allow truncation if + ``self`` is not an ``n``-th power OUTPUT: If ``truncate_mode`` is 0 (default), then returns the exact n'th root - if ``self`` is an n'th power, or raises a :class:`ValueError` + if ``self`` is an n'th power, or raises a :exc:`ValueError` if it is not. If ``truncate_mode`` is 1, then if either ``n`` is odd or ``self`` is positive, returns a pair ``(root, exact_flag)`` where ``root`` is the truncated ``n``-th root (rounded towards zero) and ``exact_flag`` is a boolean indicating whether the root extraction was exact; - otherwise raises a :class:`ValueError`. + otherwise raises a :exc:`ValueError`. AUTHORS: @@ -2417,7 +2418,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: ZZ(2^20).nth_root(21, truncate_mode=1) (1, False) - """ if n < 1: raise ValueError("n (=%s) must be positive" % n) @@ -2619,7 +2619,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``m`` -- integer `\geq 2` + - ``m`` -- integer `\geq 2` AUTHORS: @@ -2771,10 +2771,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``m`` -- default: natural log base e + - ``m`` -- (default: natural) log base e - - ``prec`` -- integer (default: ``None``): if ``None``, returns - symbolic, else to given bits of precision as in :class:`RealField` + - ``prec`` -- integer (default: ``None``); if ``None``, returns + symbolic, else to given bits of precision as in :class:`RealField` EXAMPLES:: @@ -2889,10 +2889,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - - ``prec`` -- integer (default: None): if None, returns - symbolic, else to given bits of precision as in :class:`RealField` - + - ``prec`` -- integer (default: ``None``); if ``None``, returns + symbolic, else to given bits of precision as in :class:`RealField` EXAMPLES:: @@ -2926,9 +2924,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``m`` -- Integer + - ``m`` -- integer - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -3093,7 +3091,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): If one first computes all the divisors and then sorts it, the sorting step can easily dominate the runtime. Note, - however, that (non-negative) multiplication on the left + however, that (nonnegative) multiplication on the left preserves relative order. One can leverage this fact to keep the list in order as one computes it using a process similar to that of the merge sort algorithm. @@ -3264,7 +3262,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def __abs__(self): """ - Computes `|self|` + Compute ``|self|``. EXAMPLES:: @@ -3280,7 +3278,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def euclidean_degree(self): r""" - Return the degree of this element as an element of an Euclidean domain. + Return the degree of this element as an element of a Euclidean domain. If this is an element in the ring of integers, this is simply its absolute value. @@ -3289,7 +3287,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: ZZ(1).euclidean_degree() 1 - """ from sage.rings.integer_ring import ZZ if self.parent() is ZZ: @@ -3302,7 +3299,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): depending on whether this number is negative, zero, or positive respectively. - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -3403,19 +3400,19 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def quo_rem(Integer self, other): """ - Return the quotient and the remainder of ``self`` divided by other. + Return the quotient and the remainder of ``self`` divided by ``other``. Note that the remainder returned is always either zero or of the - same sign as other. + same sign as ``other``. INPUT: - - ``other`` -- the divisor + - ``other`` -- the divisor OUTPUT: - - ``q`` -- the quotient of self/other + - ``q`` -- the quotient of ``self/other`` - - ``r`` -- the remainder of self/other + - ``r`` -- the remainder of ``self/other`` EXAMPLES:: @@ -3537,13 +3534,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``self`` -- Integer - - - ``m`` -- Integer + - ``self`` -- integer - OUTPUT: + - ``m`` -- integer - - a :class:`Rational` + OUTPUT: a :class:`Rational` EXAMPLES:: @@ -3704,10 +3699,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``bound`` -- a positive integer that fits in a C ``signed long`` - - ``start`` -- a positive integer that fits in a C ``signed long`` + - ``bound`` -- positive integer that fits in a C ``signed long`` + - ``start`` -- positive integer that fits in a C ``signed long`` - OUTPUT: A positive integer + OUTPUT: a positive integer EXAMPLES:: @@ -3866,37 +3861,34 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``algorithm`` -- string + - ``algorithm`` -- string; one of - - ``'pari'`` -- (default) use the PARI library + - ``'pari'`` -- (default) use the PARI library - - ``'flint'`` -- use the FLINT library + - ``'flint'`` -- use the FLINT library - - ``'kash'`` -- use the KASH computer algebra system (requires - kash) + - ``'kash'`` -- use the KASH computer algebra system (requires + kash) - - ``'magma'`` -- use the MAGMA computer algebra system (requires - an installation of MAGMA) + - ``'magma'`` -- use the MAGMA computer algebra system (requires + an installation of MAGMA) - - ``'qsieve'`` -- use Bill Hart's quadratic sieve code; - WARNING: this may not work as expected, see qsieve? for - more information + - ``'qsieve'`` -- use Bill Hart's quadratic sieve code; + WARNING: this may not work as expected, see qsieve? for + more information - - ``'ecm'`` -- use ECM-GMP, an implementation of Hendrik - Lenstra's elliptic curve method. + - ``'ecm'`` -- use ECM-GMP, an implementation of Hendrik + Lenstra's elliptic curve method - - ``proof`` -- bool (default: ``True``) whether or not to prove - primality of each factor (only applicable for ``'pari'`` - and ``'ecm'``). + - ``proof`` -- boolean (default: ``True``); whether or not to prove + primality of each factor (only applicable for ``'pari'`` and ``'ecm'``) - - ``limit`` -- int or None (default: None) if limit is + - ``limit`` -- integer or ``None`` (default: ``None``); if limit is given it must fit in a ``signed int``, and the factorization is done - using trial division and primes up to limit. - - OUTPUT: + using trial division and primes up to limit - - a Factorization object containing the prime factors and - their multiplicities + OUTPUT: a Factorization object containing the prime factors and + their multiplicities EXAMPLES:: @@ -4065,8 +4057,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): """ Return a sorted list of the primes dividing this integer. - OUTPUT: The sorted list of primes appearing in the factorization of - this rational with positive exponent. + OUTPUT: the sorted list of primes appearing in the factorization of + this rational with positive exponent EXAMPLES:: @@ -4075,7 +4067,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-999).support() [3, 37] - Trying to find the support of 0 raises an :class:`ArithmeticError`:: + Trying to find the support of 0 raises an :exc:`ArithmeticError`:: sage: 0.support() Traceback (most recent call last): @@ -4090,7 +4082,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def coprime_integers(self, m): """ - Return the non-negative integers `< m` that are coprime to + Return the nonnegative integers `< m` that are coprime to this integer. EXAMPLES:: @@ -4209,7 +4201,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cpdef RingElement _valuation(Integer self, Integer p): r""" - Return the p-adic valuation of ``self``. + Return the `p`-adic valuation of ``self``. We do not require that p be prime, but it must be at least 2. For more documentation see ``valuation`` @@ -4234,7 +4226,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef object _val_unit(Integer self, Integer p): r""" - Return a pair: the p-adic valuation of ``self``, and the p-adic unit + Return a pair: the `p`-adic valuation of ``self``, and the `p`-adic unit of ``self``. We do not require the p be prime, but it must be at least 2. For @@ -4259,11 +4251,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def valuation(self, p): """ - Return the p-adic valuation of ``self``. + Return the `p`-adic valuation of ``self``. INPUT: - - ``p`` -- an integer at least 2. + - ``p`` -- integer at least 2 EXAMPLES:: @@ -4295,9 +4287,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``p`` -- a prime integer. + - ``p`` -- prime integer - OUTPUT: Largest power of ``p`` dividing ``self``. + OUTPUT: largest power of ``p`` dividing ``self`` EXAMPLES:: @@ -4320,18 +4312,18 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def val_unit(self, p): r""" - Return a pair: the p-adic valuation of ``self``, and the p-adic unit + Return a pair: the `p`-adic valuation of ``self``, and th`p`-adicic unit of ``self``. INPUT: - - ``p`` -- an integer at least 2. + - ``p`` -- integer at least 2 OUTPUT: - - ``v_p(self)`` -- the p-adic valuation of ``self`` + - ``v_p(self)`` -- the `p`-adic valuation of ``self`` - - ``u_p(self)`` -- ``self`` / `p^{v_p(\mathrm{self})}` + - ``u_p(self)`` -- ``self`` / `p^{v_p(\mathrm{self})}` EXAMPLES:: @@ -4358,7 +4350,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Currently returns 0 when ``self`` is 0. This behaviour is fairly arbitrary, and in Sage 4.6 this special case was not handled at all, eventually - propagating a TypeError. The caller should not rely on the behaviour + propagating a :exc:`TypeError`. The caller should not rely on the behaviour in case ``self`` is 0. EXAMPLES:: @@ -4527,7 +4519,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): r""" Return the factorial `n! = 1 \cdot 2 \cdot 3 \cdots n`. - If the input does not fit in an ``unsigned long int``, an :class:`OverflowError` + If the input does not fit in an ``unsigned long int``, an :exc:`OverflowError` is raised. EXAMPLES:: @@ -4542,22 +4534,22 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 5 120 6 720 - Large integers raise an :class:`OverflowError`:: + Large integers raise an :exc:`OverflowError`:: sage: (2**64).factorial() Traceback (most recent call last): ... OverflowError: argument too large for factorial - And negative ones a :class:`ValueError`:: + And negative ones a :exc:`ValueError`:: sage: (-1).factorial() Traceback (most recent call last): ... - ValueError: factorial only defined for non-negative integers + ValueError: factorial only defined for nonnegative integers """ if mpz_sgn(self.value) < 0: - raise ValueError("factorial only defined for non-negative integers") + raise ValueError("factorial only defined for nonnegative integers") if not mpz_fits_ulong_p(self.value): raise OverflowError("argument too large for factorial") @@ -4572,15 +4564,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def multifactorial(self, long k): r""" - Compute the k-th factorial `n!^{(k)}` of ``self``. + Compute the `k`-th factorial `n!^{(k)}` of ``self``. - The multifactorial number `n!^{(k)}` is defined for non-negative + The multifactorial number `n!^{(k)}` is defined for nonnegative integers `n` as follows. For `k=1` this is the standard factorial, and for `k` greater than `1` it is the product of every `k`-th terms down from `n` to `1`. The recursive definition is used to extend this function to the negative integers `n`. - This function uses direct call to GMP if `k` and `n` are non-negative + This function uses direct call to GMP if `k` and `n` are nonnegative and uses simple transformation for other cases. EXAMPLES:: @@ -4606,7 +4598,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ... ValueError: multifactorial undefined - When entries are too large an :class:`OverflowError` is raised:: + When entries are too large an :exc:`OverflowError` is raised:: sage: (2**64).multifactorial(2) Traceback (most recent call last): @@ -4614,7 +4606,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): OverflowError: argument too large for multifactorial """ if k <= 0: - raise ValueError("multifactorial only defined for non-positive k") + raise ValueError("multifactorial only defined for nonpositive k") if not mpz_fits_slong_p(self.value): raise OverflowError("argument too large for multifactorial") @@ -4624,7 +4616,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef Integer z if n >= 0: - # non-negative n: call native GMP functions + # nonnegative n: call native GMP functions z = PY_NEW(Integer) if k == 1: mpz_fac_ui(z.value, n) @@ -4654,7 +4646,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def gamma(self): r""" The gamma function on integers is the factorial function (shifted by - one) on positive integers, and `\pm \infty` on non-positive integers. + one) on positive integers, and `\pm \infty` on nonpositive integers. EXAMPLES:: @@ -4675,7 +4667,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def floor(self): """ - Return the floor of ``self``, which is just self since ``self`` is an + Return the floor of ``self``, which is just ``self`` since ``self`` is an integer. EXAMPLES:: @@ -4712,7 +4704,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): """ return self - def round(Integer self, mode="away"): + def round(Integer self, mode='away'): """ Return the nearest integer to ``self``, which is ``self`` since ``self`` is an integer. @@ -4800,7 +4792,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_integer(self): """ - Return ``True`` as they are integers + Return ``True`` as they are integers. EXAMPLES:: @@ -4904,8 +4896,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + - ``prec`` -- integer; desired floating point precision (default: + default RealField precision) OUTPUT: @@ -4936,7 +4928,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef bint _is_power_of(Integer self, Integer n) noexcept: r""" - Return a non-zero int if there is an integer b with + Return a nonzero int if there is an integer b with `\mathtt{self} = n^b`. For more documentation see :meth:`is_power_of`. @@ -5161,12 +5153,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``proof`` -- Boolean or ``None`` (default). If ``False``, use a strong + - ``proof`` -- boolean or ``None`` (default). If ``False``, use a strong pseudo-primality test (see :meth:`is_pseudoprime`). If ``True``, use a provable primality test. If unset, use the default arithmetic proof flag. - - ``get_data`` -- (default ``False``), if ``True`` return a pair + - ``get_data`` -- (default: ``False``), if ``True`` return a pair ``(p,k)`` such that this integer equals ``p^k`` with ``p`` a prime and ``k`` a positive integer or the pair ``(self,0)`` otherwise. @@ -5311,7 +5303,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``proof`` -- Boolean or ``None`` (default). If ``False``, use a + - ``proof`` -- boolean or ``None`` (default). If ``False``, use a strong pseudo-primality test (see :meth:`is_pseudoprime`). If ``True``, use a provable primality test. If unset, use the :mod:`default arithmetic proof flag `. @@ -5412,9 +5404,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``self`` -- A PARI pseudoprime + - ``self`` -- a PARI pseudoprime - - ``proof`` -- Mandatory proof flag (``True``, ``False`` or ``None``) + - ``proof`` -- mandatory proof flag (``True``, ``False`` or ``None``) OUTPUT: @@ -5484,9 +5476,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``get_data`` -- (default ``False``) if ``True`` return a pair `(p,k)` + - ``get_data`` -- (default: ``False``) if ``True`` return a pair `(p,k)` such that this number equals `p^k` with `p` a pseudoprime and `k` a - positive integer or the pair ``(self,0)`` otherwise. + positive integer or the pair ``(self,0)`` otherwise EXAMPLES:: @@ -5687,10 +5679,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``self`` -- an integer congruent to `0` or `1` mod `4` which is + - ``self`` -- integer congruent to `0` or `1` mod `4` which is not a square - - ``proof`` (boolean, default ``True``) -- if ``False``, then + - ``proof`` -- boolean (default: ``True``); if ``False``, then for negative discriminants a faster algorithm is used by the PARI library which is known to give incorrect results when the class group has many cyclic factors. However, the @@ -5761,10 +5753,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def squarefree_part(self, long bound=-1): r""" - Return the square free part of `x` (=self), i.e., the unique integer + Return the square free part of `x` (=``self``), i.e., the unique integer `z` that `x = z y^2`, with `y^2` a perfect square and `z` square-free. - Use ``self.radical()`` for the product of the primes that divide self. + Use ``self.radical()`` for the product of the primes that divide ``self``. If ``self`` is 0, just returns 0. @@ -5870,9 +5862,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``proof`` -- bool or None (default: None, see - ``proof.arithmetic`` or :mod:`sage.structure.proof`) Note that the global Sage - default is ``proof=True`` + - ``proof`` -- boolean or ``None`` (default: ``None``, see + ``proof.arithmetic`` or :mod:`sage.structure.proof`); note that the + global Sage default is ``proof=True`` EXAMPLES:: @@ -6226,7 +6218,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: m = n.__pari__() # crash from trac 875 # needs sage.libs.pari sage: m % 1234567 # needs sage.libs.pari 1041334 - """ global new_gen_from_integer if new_gen_from_integer is None: @@ -6352,7 +6343,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): r""" Return `(s, r)` where `s` is the integer square root of ``self`` and `r` is the remainder such that `\text{self} = s^2 + r`. - Raises :class:`ValueError` if ``self`` is negative. + Raises :exc:`ValueError` if ``self`` is negative. EXAMPLES:: @@ -6369,7 +6360,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Traceback (most recent call last): ... ValueError: square root of negative integer not defined - """ if mpz_sgn(self.value) < 0: raise ValueError("square root of negative integer not defined") @@ -6381,7 +6371,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def isqrt(self): r""" Return the integer floor of the square root of ``self``, or raises an - :class:`ValueError` if ``self`` is negative. + :exc:`ValueError` if ``self`` is negative. EXAMPLES:: @@ -6413,17 +6403,17 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``prec`` -- integer (default: ``None``): if ``None``, return an exact - square root; otherwise return a numerical square root, to the - given bits of precision. + - ``prec`` -- integer (default: ``None``); if ``None``, return an exact + square root; otherwise return a numerical square root, to the + given bits of precision. - - ``extend`` -- bool (default: ``True``); if ``True``, return a - square root in an extension ring, if necessary. Otherwise, raise a - :class:`ValueError` if the square is not in the base ring. Ignored if ``prec`` - is not ``None``. + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the square is not in the base ring. Ignored if + ``prec`` is not ``None``. - - ``all`` -- bool (default: ``False``); if ``True``, return all - square roots of ``self`` (a list of length 0, 1, or 2). + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of ``self`` (a list of length 0, 1, or 2) EXAMPLES:: @@ -6516,11 +6506,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: - A triple ``(g, s, t)`` such that ``g`` is the non-negative gcd of + A triple ``(g, s, t)`` such that ``g`` is the nonnegative gcd of ``self`` and ``n``, and ``s`` and ``t`` are cofactors satisfying the Bezout identity @@ -6539,7 +6529,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 6.xgcd(4) (2, 1, -1) - """ return self._xgcd(n) @@ -6549,15 +6538,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``n`` -- an integer - - ``minimal`` -- a boolean (default: ``False``), whether to compute + - ``n`` -- integer + - ``minimal`` -- boolean (default: ``False``); whether to compute minimal cofactors (see below) OUTPUT: - A triple ``(g, s, t)`` such that ``g`` is the non-negative gcd of + A triple ``(g, s, t)`` such that ``g`` is the nonnegative gcd of ``self`` and ``n``, and ``s`` and ``t`` are cofactors satisfying the - Bezout identity + Bezout identity. .. MATH:: @@ -6638,7 +6627,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # Note: the GMP documentation for mpz_gcdext (or mpn_gcdext for that # matter) makes absolutely no claims about any minimality conditions - # satisfied by the returned cofactors. They guarantee a non-negative + # satisfied by the returned cofactors. They guarantee a nonnegative # gcd, but that's it. So we have to do some work ourselves. if not minimal: @@ -6887,7 +6876,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def inverse_of_unit(self): """ Return inverse of ``self`` if ``self`` is a unit in the integers, i.e., - ``self`` is `-1` or `1`. Otherwise, raise a :class:`ZeroDivisionError`. + ``self`` is `-1` or `1`. Otherwise, raise a :exc:`ZeroDivisionError`. EXAMPLES:: @@ -6913,18 +6902,18 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): r""" Return the inverse of ``self`` modulo `n`, if this inverse exists. - Otherwise, raise a :class:`ZeroDivisionError` exception. + Otherwise, raise a :exc:`ZeroDivisionError` exception. INPUT: - - ``self`` -- Integer + - ``self`` -- integer - - ``n`` -- Integer, or ideal of integer ring + - ``n`` -- integer or ideal of integer ring OUTPUT: - - ``x`` -- Integer such that x\*self = 1 (mod m), or - raises ZeroDivisionError. + - ``x`` -- integer such that x * ``self`` = 1 (mod m), or + raises :exc:`ZeroDivisionError` IMPLEMENTATION: @@ -7074,7 +7063,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``m`` -- an integer + - ``m`` -- integer - ``algorithm`` -- ``'gmp'`` (default), ``'mpir'`` (an alias for ``gmp``), or ``'pari'``; ``'gmp'`` is faster for small ``m``, @@ -7171,7 +7160,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): else: raise ValueError("algorithm must be one of: 'pari' or 'gmp' (alias: 'mpir')") - def to_bytes(self, length=1, byteorder="big", is_signed=False): + def to_bytes(self, length=1, byteorder='big', is_signed=False): r""" Return an array of bytes representing an integer. @@ -7179,10 +7168,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``length`` -- positive integer (default: ``1``); integer is represented in - ``length`` bytes - - ``byteorder`` -- str (default: ``"big"``); determines the byte order of - the output; can only be ``"big"`` or ``"little"`` + - ``length`` -- positive integer (default: 1); integer represented + in ``length`` bytes + - ``byteorder`` -- string (default: ``'big'``); determines the byte + order of the output (can only be ``'big'`` or ``'little'``) - ``is_signed`` -- boolean (default: ``False``); determines whether to use two's compliment to represent the integer @@ -7211,17 +7200,16 @@ cdef int mpz_set_str_python(mpz_ptr z, char* s, int base) except -1: Wrapper around ``mpz_set_str()`` which supports :pep:`3127` literals. - If the string is invalid, a ``TypeError`` will be raised. + If the string is invalid, a :exc:`TypeError` will be raised. INPUT: - - ``z`` -- A pre-allocated ``mpz_t`` where the result will be - stored. + - ``z`` -- a pre-allocated ``mpz_t`` where the result will be stored - - ``s`` -- A string to be converted to an ``mpz_t``. + - ``s`` -- string to be converted to an ``mpz_t`` - - ``base`` -- Either 0 or a base between 2 and 36: a base to use - for the string conversion. 0 means auto-detect using prefixes. + - ``base`` -- either 0 or a base between 2 and 36: a base to use + for the string conversion. 0 means auto-detect using prefixes EXAMPLES:: @@ -7807,7 +7795,7 @@ cdef double mpz_get_d_nearest(mpz_t x) except? -648555075988944.5: pass else: if not remainder_is_zero: - # Remainder is non-zero: round away from zero + # Remainder is nonzero: round away from zero q64 += 1 else: # Halfway case: round to even diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index a1574d00756..2b2ec33294c 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -614,18 +614,16 @@ cdef class IntegerRing_class(CommutativeRing): INPUT: - - ``x``, ``y`` integers -- bounds for the result. + - ``x``, ``y`` integers -- bounds for the result - - ``distribution`` -- a string: + - ``distribution`` -- string: - ``'uniform'`` - ``'mpz_rrandomb'`` - ``'1/n'`` - ``'gaussian'`` - OUTPUT: - - - With no input, return a random integer. + OUTPUT: with no input, return a random integer If only one integer `x` is given, return an integer between 0 and `x-1`. @@ -687,9 +685,9 @@ cdef class IntegerRing_class(CommutativeRing): ....: return 1/5 sage: dic = defaultdict(Integer) sage: counter = 0.0 - sage: add_samples(distribution="uniform") + sage: add_samples(distribution='uniform') sage: while any(abs(dic[i]/counter - prob(i)) > 0.01 for i in dic): - ....: add_samples(distribution="uniform") + ....: add_samples(distribution='uniform') Here we use the distribution ``'1/n'``:: @@ -699,9 +697,9 @@ cdef class IntegerRing_class(CommutativeRing): ....: return 2/(5*abs(n)*(abs(n) + 1)) sage: dic = defaultdict(Integer) sage: counter = 0.0 - sage: add_samples(distribution="1/n") + sage: add_samples(distribution='1/n') sage: while any(abs(dic[i]/counter - prob(i)) > 0.01 for i in dic): - ....: add_samples(distribution="1/n") + ....: add_samples(distribution='1/n') If a range is given, the default distribution is uniform in that range:: @@ -736,25 +734,25 @@ cdef class IntegerRing_class(CommutativeRing): We return a sample from a discrete Gaussian distribution:: - sage: ZZ.random_element(11.0, distribution="gaussian").parent() is ZZ # needs sage.modules + sage: ZZ.random_element(11.0, distribution='gaussian').parent() is ZZ # needs sage.modules True TESTS: Check that :issue:`32124` is fixed:: - sage: ZZ.random_element(5, -5, distribution="1/n").parent() is ZZ + sage: ZZ.random_element(5, -5, distribution='1/n').parent() is ZZ True - sage: ZZ.random_element(5, -5, distribution="gaussian").parent() is ZZ # needs sage.modules + sage: ZZ.random_element(5, -5, distribution='gaussian').parent() is ZZ # needs sage.modules True - sage: ZZ.random_element(5, -5, distribution="mpz_rrandomb").parent() is ZZ + sage: ZZ.random_element(5, -5, distribution='mpz_rrandomb').parent() is ZZ True - sage: ZZ.random_element(-10, -5, distribution="mpz_rrandomb") + sage: ZZ.random_element(-10, -5, distribution='mpz_rrandomb') Traceback (most recent call last): ... TypeError: x must be > 0 - sage: ZZ.random_element(-10, -5, distribution="gaussian") + sage: ZZ.random_element(-10, -5, distribution='gaussian') Traceback (most recent call last): ... TypeError: x must be > 0 @@ -832,7 +830,7 @@ cdef class IntegerRing_class(CommutativeRing): r = _prev_discrete_gaussian_integer_sampler[1]() else: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler - D = DiscreteGaussianDistributionIntegerSampler(sigma=x, algorithm="uniform+logtable") + D = DiscreteGaussianDistributionIntegerSampler(sigma=x, algorithm='uniform+logtable') r = D() _prev_discrete_gaussian_integer_sampler = (x, D) mpz_set(value, r.value) @@ -841,7 +839,7 @@ cdef class IntegerRing_class(CommutativeRing): def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): r""" - Tests whether the map from `\ZZ` to codomain, which takes the + Test whether the map from `\ZZ` to codomain, which takes the generator of `\ZZ` to ``im_gens[0]``, is a ring homomorphism. (This amounts to checking that 1 goes to 1.) @@ -909,13 +907,13 @@ cdef class IntegerRing_class(CommutativeRing): INPUT: - - ``poly`` -- a list of one or more polynomials + - ``poly`` -- list of one or more polynomials - ``names`` -- a parameter which will be passed to - :func:`EquationOrder`. + :func:`EquationOrder` - ``embedding`` -- a parameter which will be passed to - :func:`EquationOrder`. + :func:`EquationOrder` OUTPUT: @@ -958,7 +956,7 @@ cdef class IntegerRing_class(CommutativeRing): """ if isinstance(I, sage.rings.integer.Integer): n = I - elif sage.rings.ideal.is_Ideal(I): + elif isinstance(I, sage.rings.ideal.Ideal_generic): if not (I.ring() is self): raise TypeError("I must be an ideal of ZZ") n = I.gens()[0] @@ -977,12 +975,12 @@ cdef class IntegerRing_class(CommutativeRing): - ``prime`` -- a prime number - - ``check`` -- (boolean, default ``True``) whether or not + - ``check`` -- boolean (default: ``True``); whether or not to check the primality of prime - ``names`` -- ignored (for compatibility with number fields) - OUTPUT: The residue field at this prime. + OUTPUT: the residue field at this prime EXAMPLES:: @@ -1027,7 +1025,7 @@ cdef class IntegerRing_class(CommutativeRing): """ if isinstance(prime, sage.rings.integer.Integer): p = self.ideal(prime) - elif sage.rings.ideal.is_Ideal(prime): + elif isinstance(prime, sage.rings.ideal.Ideal_generic): if not (prime.ring() is self): raise TypeError("%s is not an ideal of ZZ" % prime) p = prime @@ -1059,10 +1057,10 @@ cdef class IntegerRing_class(CommutativeRing): INPUT: - - ``n`` (default: 0) -- In a ring with more than one generator, the + - ``n`` -- (default: 0) in a ring with more than one generator, the optional parameter `n` indicates which generator to return; since there is only one generator in this case, the only valid value for - `n` is 0. + `n` is 0 EXAMPLES:: @@ -1171,11 +1169,9 @@ cdef class IntegerRing_class(CommutativeRing): - ``prec`` -- the desired precision - ``extras`` -- any further parameters to pass to the method used to - create the completion. - - OUTPUT: + create the completion - - The completion of `\ZZ` at `p`. + OUTPUT: the completion of `\ZZ` at `p` EXAMPLES:: @@ -1209,7 +1205,7 @@ cdef class IntegerRing_class(CommutativeRing): INPUT: - - ``n`` -- (default 2) a positive integer + - ``n`` -- (default: 2) a positive integer OUTPUT: @@ -1265,7 +1261,7 @@ cdef class IntegerRing_class(CommutativeRing): - ``multiplicities`` -- boolean (default: ``True``); whether to compute the multiplicities - - ``algorithm`` -- ``"dense"``, ``"sparse"`` or ``None`` (default: + - ``algorithm`` -- ``'dense'``, ``'sparse'`` or ``None`` (default: ``None``); the algorithm to use OUTPUT: @@ -1278,14 +1274,14 @@ cdef class IntegerRing_class(CommutativeRing): ALGORITHM: - If ``algorithm`` is ``"dense"`, the roots are computed using + If ``algorithm`` is ``'dense'``, the roots are computed using :meth:`_roots_from_factorization`. - If ``algorithm`` is ``"sparse"``, the roots are computed using the + If ``algorithm`` is ``'sparse'``, the roots are computed using the algorithm described in [CKS1999]_. - If ``algorithm`` is ``None``, use the ``"dense"`` algorithm for - polynomials of degree at most `100`, and ``"sparse"`` otherwise. + If ``algorithm`` is ``None``, use the ``'dense'`` algorithm for + polynomials of degree at most `100`, and ``'sparse'`` otherwise. .. NOTE:: @@ -1319,19 +1315,19 @@ cdef class IntegerRing_class(CommutativeRing): [(100, 1), (-5445, 5), (1, 23), (-1, 23)] sage: ZZ._roots_univariate_polynomial(p, multiplicities=False) [100, -5445, 1, -1] - sage: ZZ._roots_univariate_polynomial(p, algorithm="sparse") + sage: ZZ._roots_univariate_polynomial(p, algorithm='sparse') [(100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, algorithm="dense") + sage: ZZ._roots_univariate_polynomial(p, algorithm='dense') [(100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, algorithm="foobar") + sage: ZZ._roots_univariate_polynomial(p, algorithm='foobar') Traceback (most recent call last): ... ValueError: unknown algorithm 'foobar' sage: p = x^20 * p # needs sage.libs.pari - sage: ZZ._roots_univariate_polynomial(p, algorithm="sparse") # needs sage.libs.pari + sage: ZZ._roots_univariate_polynomial(p, algorithm='sparse') # needs sage.libs.pari [(0, 20), (100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, algorithm="dense") # needs sage.libs.pari + sage: ZZ._roots_univariate_polynomial(p, algorithm='dense') # needs sage.libs.pari [(100, 1), (-5445, 5), (0, 20), (1, 23), (-1, 23)] """ deg = p.degree() @@ -1529,7 +1525,6 @@ cdef class IntegerRing_class(CommutativeRing): sage: polymake(ZZ) # optional - jupymake # indirect doctest Integer - """ return '"Integer"' @@ -1578,12 +1573,11 @@ cdef class IntegerRing_class(CommutativeRing): :meth:`Order.valuation() `, :meth:`RationalField.valuation() ` - """ from sage.rings.padics.padic_valuation import pAdicValuation return pAdicValuation(self, p) - def from_bytes(self, input_bytes, byteorder="big", is_signed=False): + def from_bytes(self, input_bytes, byteorder='big', is_signed=False): r""" Return the integer represented by the given array of bytes. @@ -1592,8 +1586,8 @@ cdef class IntegerRing_class(CommutativeRing): INPUT: - ``input_bytes`` -- a bytes-like object or iterable producing bytes - - ``byteorder`` -- str (default: ``"big"``); determines the byte order of - ``input_bytes``; can only be ``"big"`` or ``"little"`` + - ``byteorder`` -- string (default: ``'big'``); determines the byte order of + ``input_bytes`` (can only be ``'big'`` or ``'little'``) - ``is_signed`` -- boolean (default: ``False``); determines whether to use two's compliment to represent the integer @@ -1640,14 +1634,14 @@ def crt_basis(X, xgcd=None): INPUT: - - ``X`` -- a list of Integers that are coprime in pairs. + - ``X`` -- list of Integers that are coprime in pairs - - ``xgcd`` -- an optional parameter which is ignored. + - ``xgcd`` -- an optional parameter which is ignored OUTPUT: - - ``E`` -- a list of Integers such that ``E[i] = 1`` (mod ``X[i]``) and - ``E[i] = 0`` (mod ``X[j]``) for all `j \neq i`. + - ``E`` -- list of Integers such that ``E[i] = 1`` (mod ``X[i]``) and + ``E[i] = 0`` (mod ``X[j]``) for all `j \neq i` For this explanation, let ``E[i]`` be denoted by `E_i`. diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index cda4138d5e4..fb953f98813 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -125,7 +125,7 @@ def _guess_variables(polynomial, *args): INPUT: - ``polynomial`` -- a polynomial, or a list/tuple of polynomials - in the same polynomial ring. + in the same polynomial ring - ``*args`` -- the variables. If none are specified, all variables in ``polynomial`` are returned. If a list or tuple is passed, @@ -177,10 +177,10 @@ def transvectant(f, g, h=1, scale='default'): INPUT: - - ``f``, ``g`` -- two homogeneous binary forms in the same polynomial ring. + - ``f``, ``g`` -- two homogeneous binary forms in the same polynomial ring - - ``h`` -- the order of the transvectant. If it is not specified, - the first transvectant is returned. + - ``h`` -- the order of the transvectant; if it is not specified, + the first transvectant is returned - ``scale`` -- the scaling factor applied to the result. Possible values are ``'default'`` and ``'none'``. The ``'default'`` scaling factor is @@ -336,9 +336,7 @@ def _jacobian_determinant(self, *args): homogeneous degree. Must be a covariant, that is, polynomial in the given :meth:`variables` - OUTPUT: - - The Jacobian determinant with respect to the variables. + OUTPUT: the Jacobian determinant with respect to the variables EXAMPLES:: @@ -424,10 +422,8 @@ def is_homogeneous(self): """ Return whether the forms were defined by homogeneous polynomials. - OUTPUT: - - Boolean. Whether the user originally defined the form via - homogeneous variables. + OUTPUT: boolean; whether the user originally defined the form via + homogeneous variables EXAMPLES:: @@ -462,14 +458,14 @@ class AlgebraicForm(FormsBase): INPUT: - - ``n`` -- The number of variables. + - ``n`` -- the number of variables - - ``d`` -- The degree of the polynomial. + - ``d`` -- the degree of the polynomial - - ``polynomial`` -- The polynomial. + - ``polynomial`` -- the polynomial - - ``*args`` -- The variables, as a single list/tuple, multiple - arguments, or ``None`` to use all variables of the polynomial. + - ``*args`` -- the variables, as a single list/tuple, multiple + arguments, or ``None`` to use all variables of the polynomial Derived classes must implement the same arguments for the constructor. @@ -578,8 +574,8 @@ def _check_covariant(self, method_name, g=None, invariant=False): INPUT: - - ``method_name`` -- string. The name of the method that - returns the invariant / covariant to test. + - ``method_name`` -- string; the name of the method that + returns the invariant / covariant to test - ``g`` -- an `SL(n,\CC)` matrix or ``None`` (default). The test will be to check that the covariant transforms @@ -587,8 +583,8 @@ def _check_covariant(self, method_name, g=None, invariant=False): the homogeneous variables. If ``None``, a random matrix will be picked. - - ``invariant`` -- boolean. Whether to additionally test that - it is an invariant. + - ``invariant`` -- boolean; whether to additionally test that + it is an invariant EXAMPLES:: @@ -644,9 +640,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -688,9 +682,7 @@ def form(self): """ Return the defining polynomial. - OUTPUT: - - The polynomial used to define the algebraic form. + OUTPUT: the polynomial used to define the algebraic form EXAMPLES:: @@ -712,7 +704,7 @@ def homogenized(self, var='h'): INPUT: - ``var`` -- either a variable name, variable index or a - variable (default: ``'h'``). + variable (default: ``'h'``) OUTPUT: @@ -768,8 +760,8 @@ def _extract_coefficients(self, monomials): - ``polynomial`` -- the input polynomial - - ``monomials`` -- a list of all the monomials in the polynomial - ring. If less monomials are passed, an exception is thrown. + - ``monomials`` -- list of all the monomials in the polynomial + ring; if less monomials are passed, an exception is thrown OUTPUT: @@ -892,9 +884,9 @@ def transformed(self, g): INPUT: - ``g`` -- a `GL(n,\CC)` matrix or a dictionary with the - variables as keys. A matrix is used to define the linear - transformation of homogeneous variables, a dictionary acts - by substitution of the variables. + variables as keys. A matrix is used to define the linear + transformation of homogeneous variables, a dictionary acts + by substitution of the variables. OUTPUT: @@ -994,12 +986,10 @@ def from_invariants(cls, discriminant, x, z, *args, **kwargs): INPUT: - - ``discriminant`` -- Value of the discriminant used to reconstruct - the binary quadratic. - - OUTPUT: + - ``discriminant`` -- value of the discriminant used to reconstruct + the binary quadratic - A QuadraticForm with 2 variables. + OUTPUT: a QuadraticForm with 2 variables EXAMPLES:: @@ -1108,7 +1098,7 @@ def scaled_coeffs(self): @cached_method def matrix(self): r""" - Return the quadratic form as a symmetric matrix + Return the quadratic form as a symmetric matrix. OUTPUT: @@ -1181,12 +1171,10 @@ def invariants(self, type='discriminant'): INPUT: - - ``type`` -- The type of invariants to return. The default choice - is to return the discriminant. + - ``type`` -- the type of invariants to return; the default choice + is to return the discriminant - OUTPUT: - - The invariants of the binary quadratic. + OUTPUT: the invariants of the binary quadratic EXAMPLES:: @@ -1199,7 +1187,6 @@ def invariants(self, type='discriminant'): Traceback (most recent call last): ... ValueError: unknown type of invariants unknown for a binary quadratic - """ if type == 'discriminant': return (self.discriminant(),) @@ -1439,9 +1426,7 @@ def EisensteinD(self): r""" One of the Eisenstein invariants of a binary quartic. - OUTPUT: - - The Eisenstein D-invariant of the quartic. + OUTPUT: the Eisenstein D-invariant of the quartic .. MATH:: @@ -1468,9 +1453,7 @@ def EisensteinE(self): r""" One of the Eisenstein invariants of a binary quartic. - OUTPUT: - - The Eisenstein E-invariant of the quartic. + OUTPUT: the Eisenstein E-invariant of the quartic .. MATH:: @@ -1497,9 +1480,7 @@ def g_covariant(self): r""" The g-covariant of a binary quartic. - OUTPUT: - - The g-covariant of the quartic. + OUTPUT: the g-covariant of the quartic .. MATH:: @@ -1548,9 +1529,7 @@ def h_covariant(self): r""" The h-covariant of a binary quartic. - OUTPUT: - - The h-covariant of the quartic. + OUTPUT: the h-covariant of the quartic .. MATH:: @@ -1680,12 +1659,10 @@ def from_invariants(cls, invariants, x, z, *args, **kwargs): INPUT: - - ``invariants`` -- A list or tuple of invariants that are used to - reconstruct the binary quintic. - - OUTPUT: + - ``invariants`` -- list or tuple of invariants that are used to + reconstruct the binary quintic - A BinaryQuintic. + OUTPUT: a BinaryQuintic EXAMPLES:: @@ -1797,9 +1774,7 @@ def H_covariant(self, as_form=False): as polynomial (default). If it is ``True`` the result is returned as an object of the class :class:`AlgebraicForm`. - OUTPUT: - - The `H`-covariant of the binary quintic as polynomial or as binary form. + OUTPUT: the `H`-covariant of the binary quintic as polynomial or as binary form EXAMPLES:: @@ -1834,9 +1809,7 @@ def i_covariant(self, as_form=False): as polynomial (default). If it is ``True`` the result is returned as an object of the class :class:`AlgebraicForm`. - OUTPUT: - - The `i`-covariant of the binary quintic as polynomial or as binary form. + OUTPUT: the `i`-covariant of the binary quintic as polynomial or as binary form EXAMPLES:: @@ -1868,9 +1841,7 @@ def T_covariant(self, as_form=False): as polynomial (default). If it is ``True`` the result is returned as an object of the class :class:`AlgebraicForm`. - OUTPUT: - - The `T`-covariant of the binary quintic as polynomial or as binary form. + OUTPUT: the `T`-covariant of the binary quintic as polynomial or as binary form EXAMPLES:: @@ -1907,9 +1878,7 @@ def j_covariant(self, as_form=False): as polynomial (default). If it is ``True`` the result is returned as an object of the class :class:`AlgebraicForm`. - OUTPUT: - - The `j`-covariant of the binary quintic as polynomial or as binary form. + OUTPUT: the `j`-covariant of the binary quintic as polynomial or as binary form EXAMPLES:: @@ -2185,9 +2154,7 @@ def A_invariant(self): """ Return the invariant `A` of a binary quintic. - OUTPUT: - - The `A`-invariant of the binary quintic. + OUTPUT: the `A`-invariant of the binary quintic EXAMPLES:: @@ -2213,9 +2180,7 @@ def B_invariant(self): """ Return the invariant `B` of a binary quintic. - OUTPUT: - - The `B`-invariant of the binary quintic. + OUTPUT: the `B`-invariant of the binary quintic EXAMPLES:: @@ -2245,9 +2210,7 @@ def C_invariant(self): """ Return the invariant `C` of a binary quintic. - OUTPUT: - - The `C`-invariant of the binary quintic. + OUTPUT: the `C`-invariant of the binary quintic EXAMPLES:: @@ -2276,9 +2239,7 @@ def R_invariant(self): """ Return the invariant `R` of a binary quintic. - OUTPUT: - - The `R`-invariant of the binary quintic. + OUTPUT: the `R`-invariant of the binary quintic EXAMPLES:: @@ -2310,12 +2271,10 @@ def invariants(self, type='clebsch'): INPUT: - - ``type`` -- The type of invariants to return. The default choice - is to return the Clebsch invariants. - - OUTPUT: + - ``type`` -- the type of invariants to return; the default choice + is to return the Clebsch invariants - The invariants of the binary quintic. + OUTPUT: the invariants of the binary quintic EXAMPLES:: @@ -2331,7 +2290,6 @@ def invariants(self, type='clebsch'): Traceback (most recent call last): ... ValueError: unknown type of invariants unknown for a binary quintic - """ if type == 'clebsch': return self.clebsch_invariants(as_tuple=True) @@ -2348,9 +2306,7 @@ def clebsch_invariants(self, as_tuple=False): The following invariants are returned: `A`, `B`, `C` and `R`. - OUTPUT: - - The Clebsch invariants of the binary quintic. + OUTPUT: the Clebsch invariants of the binary quintic EXAMPLES:: @@ -2368,7 +2324,6 @@ def clebsch_invariants(self, as_tuple=False): 4983526016/390625, -247056495846408/244140625, -148978972828696847376/30517578125) - """ if self._ring.characteristic() in [2, 3, 5]: raise NotImplementedError('no invariants implemented for fields ' @@ -2396,9 +2351,7 @@ def arithmetic_invariants(self): of the Clebsch invariants, such that they still generate the ring of invariants. - OUTPUT: - - The arithmetic invariants of the binary quintic. They are given by + OUTPUT: the arithmetic invariants of the binary quintic. They are given by .. MATH:: @@ -2433,7 +2386,6 @@ def arithmetic_invariants(self): sage: invs = quintic.arithmetic_invariants() sage: [invs[x].content() for x in invs] [1, 1, 1, 1] - """ R = self._ring clebsch = self.clebsch_invariants() @@ -2459,10 +2411,10 @@ def canonical_form(self, reduce_gcd=False): INPUT: - - ``reduce_gcd`` -- If set to ``True``, then a variant of this canonical + - ``reduce_gcd`` -- if set to ``True``, then a variant of this canonical form is computed where the coefficients are coprime integers. The - obtained form is then unique up to multiplication by a unit. - See also :meth:`~sage.rings.invariants.reconstruction.binary_quintic_from_invariants`'. + obtained form is then unique up to multiplication by a unit. See also + :meth:`~sage.rings.invariants.reconstruction.binary_quintic_from_invariants`'. OUTPUT: @@ -2495,14 +2447,14 @@ def canonical_form(self, reduce_gcd=False): def _covariant_conic(A_scaled_coeffs, B_scaled_coeffs, monomials): """ - Helper function for :meth:`TernaryQuadratic.covariant_conic` + Helper function for :meth:`TernaryQuadratic.covariant_conic`. INPUT: - - ``A_scaled_coeffs``, ``B_scaled_coeffs`` -- The scaled - coefficients of the two ternary quadratics. + - ``A_scaled_coeffs``, ``B_scaled_coeffs`` -- the scaled + coefficients of the two ternary quadratics - - ``monomials`` -- The monomials :meth:`~TernaryQuadratic.monomials`. + - ``monomials`` -- the monomials :meth:`~TernaryQuadratic.monomials` OUTPUT: @@ -2656,7 +2608,7 @@ def covariant_conic(self, other): INPUT: - - ``other`` -- Another ternary quadratic. + - ``other`` -- another ternary quadratic OUTPUT: @@ -3102,7 +3054,7 @@ class SeveralAlgebraicForms(FormsBase): INPUT: - - ``forms`` -- a list/tuple/iterable of at least one + - ``forms`` -- list/tuple/iterable of at least one :class:`AlgebraicForm` object, all with the same number of variables. Interpreted as multiple homogeneous polynomials in a common polynomial ring. @@ -3244,7 +3196,7 @@ def homogenized(self, var='h'): INPUT: - ``var`` -- either a variable name, variable index or a - variable (default: ``'h'``). + variable (default: ``'h'``) OUTPUT: @@ -3275,8 +3227,8 @@ def _check_covariant(self, method_name, g=None, invariant=False): INPUT: - - ``method_name`` -- string. The name of the method that - returns the invariant / covariant to test. + - ``method_name`` -- string; the name of the method that + returns the invariant / covariant to test - ``g`` -- a `SL(n,\CC)` matrix or ``None`` (default). The test will be to check that the covariant transforms @@ -3284,8 +3236,8 @@ def _check_covariant(self, method_name, g=None, invariant=False): the homogeneous variables. If ``None``, a random matrix will be picked. - - ``invariant`` -- boolean. Whether to additionally test that - it is an invariant. + - ``invariant`` -- boolean; whether to additionally test that + it is an invariant EXAMPLES:: @@ -3327,9 +3279,7 @@ def first(self): """ Return the first of the two forms. - OUTPUT: - - The first algebraic form used in the definition. + OUTPUT: the first algebraic form used in the definition EXAMPLES:: @@ -3351,9 +3301,7 @@ def second(self): """ Return the second of the two forms. - OUTPUT: - - The second form used in the definition. + OUTPUT: the second form used in the definition EXAMPLES:: @@ -3564,7 +3512,7 @@ def syzygy(self, Delta, Theta, Theta_prime, Delta_prime, S, S_prime, F, J): 0 If the arguments are not the invariants and covariants then - the output is some (generically non-zero) polynomial:: + the output is some (generically nonzero) polynomial:: sage: biquadratic.syzygy(1, 1, 1, 1, 1, 1, 1, x) 1/64*x^2 + 1 @@ -3600,8 +3548,8 @@ class TwoQuaternaryQuadratics(TwoAlgebraicForms): REFERENCES: - - section on "Invariants and Covariants of - Systems of Quadrics" in [Sal1958]_, [Sal1965]_ + - section on "Invariants and Covariants of + Systems of Quadrics" in [Sal1958]_, [Sal1965]_ TESTS:: @@ -3948,7 +3896,7 @@ def syzygy(self, Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T, T_prime, 0 If the arguments are not the invariants and covariants then - the output is some (generically non-zero) polynomial:: + the output is some (generically nonzero) polynomial:: sage: biquadratic.syzygy(1, 1, 1, 1, 1, 1, 1, 1, 1, x) -x^2 + 1 @@ -4011,7 +3959,7 @@ def syzygy(self, Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T, T_prime, ###################################################################### -class InvariantTheoryFactory(): +class InvariantTheoryFactory: """ Factory object for invariants of multilinear forms. @@ -4032,9 +3980,7 @@ def __repr__(self): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -4049,7 +3995,7 @@ def quadratic_form(self, polynomial, *args): INPUT: - - ``polynomial`` -- a homogeneous or inhomogeneous quadratic form. + - ``polynomial`` -- a homogeneous or inhomogeneous quadratic form - ``*args`` -- the variables as multiple arguments, or as a single list/tuple. If the last argument is ``None``, the @@ -4094,10 +4040,10 @@ def inhomogeneous_quadratic_form(self, polynomial, *args): INPUT: - - ``polynomial`` -- an inhomogeneous quadratic form. + - ``polynomial`` -- an inhomogeneous quadratic form - ``*args`` -- the variables as multiple arguments, or as a - single list/tuple. + single list/tuple EXAMPLES:: @@ -4123,7 +4069,7 @@ def binary_quadratic(self, quadratic, *args): INPUT: - - ``quadratic`` -- a quadratic form. + - ``quadratic`` -- a quadratic form - ``x``, ``y`` -- the homogeneous variables. If ``y`` is ``None``, the quadratic is assumed to be inhomogeneous. @@ -4150,11 +4096,10 @@ def quaternary_quadratic(self, quadratic, *args): INPUT: - - ``quadratic`` -- a quadratic form. + - ``quadratic`` -- a quadratic form - ``w``, ``x``, ``y``, ``z`` -- the homogeneous variables. If - ``z`` is ``None``, the quadratic is assumed to be - inhomogeneous. + ``z`` is ``None``, the quadratic is assumed to be inhomogeneous. REFERENCES: @@ -4199,7 +4144,7 @@ def binary_quartic(self, quartic, *args, **kwds): INPUT: - - ``quartic`` -- a quartic. + - ``quartic`` -- a quartic - ``x``, ``y`` -- the homogeneous variables. If ``y`` is ``None``, the quartic is assumed to be inhomogeneous. @@ -4286,17 +4231,17 @@ def binary_form_from_invariants(self, degree, invariants, variables=None, as_for INPUT: - - ``degree`` -- The degree of the binary form. + - ``degree`` -- the degree of the binary form - - ``invariants`` -- A list or tuple of values of the invariants of the - binary form. + - ``invariants`` -- list or tuple of values of the invariants of the + binary form - - ``variables`` -- A list or tuple of two variables that are used for + - ``variables`` -- list or tuple of two variables that are used for the resulting form (only if ``as_form`` is ``True``). If no variables are provided, two abstract variables ``x`` and ``z`` will be used. - - ``as_form`` -- boolean. If ``False``, the function will return a tuple - of coefficients of a binary form. + - ``as_form`` -- boolean; if ``False``, the function will return a tuple + of coefficients of a binary form OUTPUT: @@ -4309,7 +4254,7 @@ def binary_form_from_invariants(self, degree, invariants, variables=None, as_for based on the value of the discriminant. See also :meth:`binary_quadratic_coefficients_from_invariants` and :meth:`binary_cubic_coefficients_from_invariants`. These methods will always return the - same result if the discriminant is non-zero:: + same result if the discriminant is nonzero:: sage: discriminant = 1 sage: invariant_theory.binary_form_from_invariants(2, [discriminant]) @@ -4318,7 +4263,7 @@ def binary_form_from_invariants(self, degree, invariants, variables=None, as_for (0, 1, -1, 0) For binary cubics, there is no class implemented yet, so ``as_form=True`` - will yield an ``NotImplementedError``:: + will yield a :exc:`NotImplementedError`:: sage: invariant_theory.binary_form_from_invariants(3, [discriminant]) Traceback (most recent call last): @@ -4457,7 +4402,7 @@ def ternary_quadratic(self, quadratic, *args, **kwds): INPUT: - ``quadratic`` -- a homogeneous quadratic in 3 homogeneous - variables, or an inhomogeneous quadratic in 2 variables. + variables, or an inhomogeneous quadratic in 2 variables - ``x``, ``y``, ``z`` -- the variables. If ``z`` is ``None``, the quadratic is assumed to be inhomogeneous. @@ -4533,7 +4478,7 @@ def ternary_cubic(self, cubic, *args, **kwds): INPUT: - ``cubic`` -- a homogeneous cubic in 3 homogeneous variables, - or an inhomogeneous cubic in 2 variables. + or an inhomogeneous cubic in 2 variables - ``x``, ``y``, ``z`` -- the variables. If ``z`` is ``None``, the cubic is assumed to be inhomogeneous. diff --git a/src/sage/rings/invariants/reconstruction.py b/src/sage/rings/invariants/reconstruction.py index 8e98ad3f20f..907538889ad 100644 --- a/src/sage/rings/invariants/reconstruction.py +++ b/src/sage/rings/invariants/reconstruction.py @@ -26,10 +26,10 @@ def binary_quadratic_coefficients_from_invariants(discriminant, invariant_choice INPUT: - - ``discriminant`` -- The value of the discriminant of the - binary quadratic. + - ``discriminant`` -- the value of the discriminant of the + binary quadratic - - ``invariant_choice`` -- The type of invariants provided. The accepted + - ``invariant_choice`` -- the type of invariants provided. The accepted options are ``'discriminant'`` and ``'default'``, which are the same. No other options are implemented. @@ -67,10 +67,10 @@ def binary_cubic_coefficients_from_invariants(discriminant, invariant_choice='de INPUT: - - ``discriminant`` -- The value of the discriminant of the - binary cubic. + - ``discriminant`` -- the value of the discriminant of the + binary cubic - - ``invariant_choice`` -- The type of invariants provided. The accepted + - ``invariant_choice`` -- the type of invariants provided. The accepted options are ``'discriminant'`` and ``'default'``, which are the same. No other options are implemented. @@ -113,17 +113,17 @@ def binary_quintic_coefficients_from_invariants(invariants, K=None, invariant_ch INPUT: - - ``invariants`` -- A list or tuple of values of the three or four + - ``invariants`` -- list or tuple of values of the three or four invariants. The default option requires the Clebsch invariants `A`, `B`, `C` and `R` of the binary quintic. - - ``K`` -- The field over which the quintic is defined. + - ``K`` -- the field over which the quintic is defined - - ``invariant_choice`` -- The type of invariants provided. The accepted + - ``invariant_choice`` -- the type of invariants provided. The accepted options are ``'clebsch'`` and ``'default'``, which are the same. No other options are implemented. - - ``scaling`` -- How the coefficients should be scaled. The accepted + - ``scaling`` -- how the coefficients should be scaled. The accepted values are ``'none'`` for no scaling, ``'normalized'`` to scale in such a way that the resulting coefficients are independent of the scaling of the input invariants and ``'coprime'`` which scales the input invariants @@ -136,7 +136,7 @@ def binary_quintic_coefficients_from_invariants(invariants, K=None, invariant_ch EXAMPLES: - First we check the general case, where the invariant `M` is non-zero:: + First we check the general case, where the invariant `M` is nonzero:: sage: R. = QQ[] sage: p = 3*x1^5 + 6*x1^4*x0 + 3*x1^3*x0^2 + 4*x1^2*x0^3 - 5*x1*x0^4 + 4*x0^5 @@ -363,9 +363,9 @@ def _reduce_invariants(invariants, weights): INPUT: - - ``invariants`` -- The values of the invariants. + - ``invariants`` -- the values of the invariants - - ``weights`` -- The respective weights of the invariants. + - ``weights`` -- the respective weights of the invariants OUTPUT: diff --git a/src/sage/rings/laurent_series_ring.py b/src/sage/rings/laurent_series_ring.py index e2b03bcca58..2142f717460 100644 --- a/src/sage/rings/laurent_series_ring.py +++ b/src/sage/rings/laurent_series_ring.py @@ -38,6 +38,7 @@ from sage.categories.integral_domains import IntegralDomains from sage.categories.rings import Rings from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import infinity from sage.rings.integer_ring import ZZ from sage.rings.laurent_series_ring_element import LaurentSeries @@ -49,6 +50,11 @@ except ImportError: pari_gen = () +lazy_import('sage.rings.polynomial.laurent_polynomial_ring_base', 'LaurentPolynomialRing_generic') +lazy_import('sage.rings.lazy_series_ring', ('LazyPowerSeriesRing', 'LazyLaurentSeriesRing')) +lazy_import('sage.rings.polynomial.polynomial_ring', 'PolynomialRing_general') +lazy_import('sage.rings.power_series_ring', 'PowerSeriesRing_generic') + def is_LaurentSeriesRing(x): """ @@ -62,12 +68,19 @@ def is_LaurentSeriesRing(x): sage: from sage.rings.laurent_series_ring import is_LaurentSeriesRing sage: K. = LaurentSeriesRing(QQ) sage: is_LaurentSeriesRing(K) + doctest:warning... + DeprecationWarning: The function is_LaurentSeriesRing is deprecated; + use 'isinstance(..., (LaurentSeriesRing, LazyLaurentSeriesRing))' instead. + See https://github.com/sagemath/sage/issues/38290 for details. True sage: L. = LazyLaurentSeriesRing(QQ) sage: is_LaurentSeriesRing(L) True """ - from sage.rings.lazy_series_ring import LazyLaurentSeriesRing + from sage.misc.superseded import deprecation + deprecation(38290, + "The function is_LaurentSeriesRing is deprecated; " + "use 'isinstance(..., (LaurentSeriesRing, LazyLaurentSeriesRing))' instead.") return isinstance(x, (LaurentSeriesRing, LazyLaurentSeriesRing)) @@ -207,9 +220,9 @@ def __classcall__(cls, *args, **kwds): sage: L.variable_name() 'q' """ - from .power_series_ring import PowerSeriesRing, is_PowerSeriesRing + from .power_series_ring import PowerSeriesRing - if not kwds and len(args) == 1 and is_PowerSeriesRing(args[0]): + if not kwds and len(args) == 1 and isinstance(args[0], (PowerSeriesRing_generic, LazyPowerSeriesRing)): power_series = args[0] else: power_series = PowerSeriesRing(*args, **kwds) @@ -218,7 +231,7 @@ def __classcall__(cls, *args, **kwds): def __init__(self, power_series): """ - Initialization + Initialization. EXAMPLES:: @@ -284,8 +297,8 @@ def __init__(self, power_series): def base_extend(self, R): """ Return the Laurent series ring over R in the same variable as - self, assuming there is a canonical coerce map from the base ring - of self to R. + ``self``, assuming there is a canonical coerce map from the base ring + of ``self`` to R. EXAMPLES:: @@ -304,7 +317,7 @@ def fraction_field(self): If the base ring is a field, then Laurent series are already a field. If the base ring is a domain, then the Laurent series over its fraction - field is returned. Otherwise, raise a ``ValueError``. + field is returned. Otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -405,7 +418,7 @@ def _element_constructor_(self, x, n=0, prec=infinity): - ``n`` -- (default: 0) multiply the result by `t^n` - ``prec`` -- (default: ``infinity``) the precision of the series - as an integer. + as an integer EXAMPLES:: @@ -675,18 +688,12 @@ def _coerce_map_from_(self, P): True """ A = self.base_ring() - from sage.rings.polynomial.laurent_polynomial_ring_base import ( - LaurentPolynomialRing_generic, - ) - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.power_series_ring import is_PowerSeriesRing - - if ((is_LaurentSeriesRing(P) or - isinstance(P, LaurentPolynomialRing_generic) or - is_PowerSeriesRing(P) or - is_PolynomialRing(P)) - and P.variable_name() == self.variable_name() - and A.has_coerce_map_from(P.base_ring())): + if (isinstance(P, (LaurentSeriesRing, LazyLaurentSeriesRing, + LaurentPolynomialRing_generic, + PowerSeriesRing_generic, LazyPowerSeriesRing, + PolynomialRing_general)) + and P.variable_name() == self.variable_name() + and A.has_coerce_map_from(P.base_ring())): return True def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): @@ -712,7 +719,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): False """ # NOTE: There are no ring homomorphisms from the ring of - # all formal power series to most rings, e.g, the p-adic + # all formal power series to most rings, e.g, the `p`-adic # field, since you can always (mathematically!) construct # some power series that does not converge. # NOTE: The above claim is wrong when the base ring is Z. @@ -721,7 +728,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): if base_map is None and not codomain.has_coerce_map_from(self.base_ring()): return False # Note that 0 is not a *ring* homomorphism, and you cannot map to a power series ring - if is_LaurentSeriesRing(codomain): + if isinstance(codomain, (LaurentSeriesRing, LazyLaurentSeriesRing)): return im_gens[0].valuation() > 0 and im_gens[0].is_unit() return False diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index 62c244d1669..405752c6191 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -78,6 +78,10 @@ from sage.misc.derivative import multi_derivative def is_LaurentSeries(x): + from sage.misc.superseded import deprecation_cython + deprecation_cython(38266, + "The function is_LaurentSeries is deprecated; " + "use 'isinstance(..., LaurentSeries)' instead.") return isinstance(x, LaurentSeries) @@ -149,7 +153,6 @@ cdef class LaurentSeries(AlgebraElement): elif parent is not f.parent(): f = parent._power_series_ring(f) - # self is that t^n * u: if not f: if n is infinity: @@ -232,7 +235,7 @@ cdef class LaurentSeries(AlgebraElement): def is_monomial(self): """ - Return ``True`` if this element is a monomial. That is, if self is + Return ``True`` if this element is a monomial. That is, if ``self`` is `x^n` for some integer `n`. EXAMPLES:: @@ -404,7 +407,7 @@ cdef class LaurentSeries(AlgebraElement): 5*x^-1 + 3 + 2*x """ if n == 0: - raise ValueError('n must be non zero') + raise ValueError('n must be nonzero') if n < 0: if not self.prec() is infinity: @@ -627,7 +630,7 @@ cdef class LaurentSeries(AlgebraElement): def exponents(self): """ - Return the exponents appearing in self with nonzero coefficients. + Return the exponents appearing in ``self`` with nonzero coefficients. EXAMPLES:: @@ -663,7 +666,7 @@ cdef class LaurentSeries(AlgebraElement): INPUT: - - ``absprec`` -- an integer or ``None`` (default: ``None``), the + - ``absprec`` -- integer or ``None`` (default: ``None``); the absolute precision of the result. If ``None``, lifts to an exact element. @@ -822,7 +825,6 @@ cdef class LaurentSeries(AlgebraElement): # 3. Subtract return type(self)(self._parent, f1 - f2, m) - def add_bigoh(self, prec): """ Return the truncated series at chosen precision ``prec``. @@ -956,7 +958,6 @@ cdef class LaurentSeries(AlgebraElement): sage: h = x^2 + 2*x^4 + x^6 sage: h^(1/2) x + x^3 - """ cdef LaurentSeries self = _self @@ -988,7 +989,7 @@ cdef class LaurentSeries(AlgebraElement): def shift(self, k): r""" - Returns this Laurent series multiplied by the power `t^n`. + Return this Laurent series multiplied by the power `t^n`. Does not change this series. .. NOTE:: @@ -1028,7 +1029,7 @@ cdef class LaurentSeries(AlgebraElement): def truncate(self, long n): r""" Return the Laurent series of degree ` < n` which is - equivalent to self modulo `x^n`. + equivalent to ``self`` modulo `x^n`. EXAMPLES:: @@ -1071,7 +1072,7 @@ cdef class LaurentSeries(AlgebraElement): This is equivalent to:: - self - self.truncate(n) + ``self - self.truncate(n)`` EXAMPLES:: @@ -1404,7 +1405,7 @@ cdef class LaurentSeries(AlgebraElement): ``precision`` is not given, then the precision of the reverse defaults to the default precision of ``f.parent()``. - Note that this is only possible if the valuation of self is exactly + Note that this is only possible if the valuation of ``self`` is exactly 1. The implementation depends on the underlying power series element @@ -1564,7 +1565,6 @@ cdef class LaurentSeries(AlgebraElement): """ return multi_derivative(self, args) - def _derivative(self, var=None): """ The formal derivative of this Laurent series with respect to var. @@ -1624,7 +1624,6 @@ cdef class LaurentSeries(AlgebraElement): u = self._parent._power_series_ring(v, self.__u.prec()) return type(self)(self._parent, u, n-1) - def integral(self): r""" The formal integral of this Laurent series with 0 constant term. @@ -1682,7 +1681,6 @@ cdef class LaurentSeries(AlgebraElement): raise ArithmeticError("Coefficients of integral cannot be coerced into the base ring") return type(self)(self._parent, u, n+1) - def nth_root(self, long n, prec=None): r""" Return the ``n``-th root of this Laurent power series. diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 74744c311da..8520ad33f68 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -411,22 +411,22 @@ def __getitem__(self, n): def coefficients(self, n=None): r""" - Return the first `n` non-zero coefficients of ``self``. + Return the first `n` nonzero coefficients of ``self``. INPUT: - - ``n`` -- (optional) the number of non-zero coefficients to return + - ``n`` -- (optional) the number of nonzero coefficients to return - If the series has fewer than `n` non-zero coefficients, only + If the series has fewer than `n` nonzero coefficients, only these are returned. If ``n`` is ``None``, a :class:`~sage.misc.lazy_list.lazy_list_generic` with all - non-zero coefficients is returned instead. + nonzero coefficients is returned instead. .. WARNING:: - If there are fewer than `n` non-zero coefficients, but + If there are fewer than `n` nonzero coefficients, but this cannot be detected, this method will not return. EXAMPLES:: @@ -434,7 +434,7 @@ def coefficients(self, n=None): sage: L. = LazyPowerSeriesRing(QQ) sage: f = L([1,2,3]) sage: f.coefficients(5) - doctest:...: DeprecationWarning: the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead. + doctest:...: DeprecationWarning: the method coefficients now only returns the nonzero coefficients. Use __getitem__ instead. See https://github.com/sagemath/sage/issues/32367 for details. [1, 2, 3] @@ -460,7 +460,7 @@ def coefficients(self, n=None): return [] from itertools import repeat, chain, islice from sage.misc.lazy_list import lazy_list - # prepare a generator of the non-zero coefficients + # prepare a generator of the nonzero coefficients P = self.parent() if isinstance(coeff_stream, Stream_exact): if coeff_stream._constant: @@ -476,17 +476,17 @@ def coefficients(self, n=None): return lazy_list(coeffs) # flatten out the generator in the multivariate case - return lazy_list(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs))) + return lazy_list(chain.from_iterable(coeff.coefficients() for coeff in coeffs)) if isinstance(self, LazyPowerSeries) and self.parent()._arity == 1: from sage.misc.superseded import deprecation - deprecation(32367, 'the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead.') + deprecation(32367, 'the method coefficients now only returns the nonzero coefficients. Use __getitem__ instead.') if P._internal_poly_ring.base_ring() is not P._laurent_poly_ring: return list(islice(coeffs, n)) # flatten out the generator in the multivariate case - return list(islice(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs)), n)) + return list(islice(chain.from_iterable(coeff.coefficients() for coeff in coeffs), n)) def map_coefficients(self, f): r""" @@ -574,7 +574,6 @@ def map_coefficients(self, f): sage: f = z + z^2 + z^3 sage: f.map_coefficients(lambda c: c + 1) 2*z + 2*z^2 + 2*z^3 - """ P = self.parent() coeff_stream = self._coeff_stream @@ -1025,7 +1024,7 @@ def _richcmp_(self, other, op): def __hash__(self): """ - Return the hash of ``self`` + Return the hash of ``self``. TESTS:: @@ -1179,8 +1178,8 @@ def is_nonzero(self, proof=False): INPUT: - - ``proof`` -- (default: ``False``) if ``True``, this will also return - an index such that ``self`` has a nonzero coefficient + - ``proof`` -- boolean (default: ``False``); if ``True``, this will + also return an index such that ``self`` has a nonzero coefficient .. WARNING:: @@ -2697,7 +2696,6 @@ def arcsinh(self): sage: L. = LazyLaurentSeriesRing(SR); x = var("x") # needs sage.symbolic sage: asinh(z)[0:6] == asinh(x).series(x, 6).coefficients(sparse=False) # needs sage.symbolic True - """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) @@ -2735,7 +2733,6 @@ def arctanh(self): sage: L. = LazyLaurentSeriesRing(SR); x = var("x") # needs sage.symbolic sage: atanh(z)[0:6] == atanh(x).series(x, 6).coefficients(sparse=False) # needs sage.symbolic True - """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) @@ -2770,7 +2767,6 @@ def hypergeometric(self, a, b): sage: L. = LazyLaurentSeriesRing(SR); x = var("x") # needs sage.symbolic sage: z.hypergeometric([1,1],[1])[0:6] == hypergeometric([1,1],[1], x).series(x, 6).coefficients(sparse=False) # needs sage.symbolic True - """ from .lazy_series_ring import LazyLaurentSeriesRing from sage.arith.misc import rising_factorial @@ -3834,8 +3830,8 @@ def __call__(self, g): composition `(f \circ g)(z) = f(g(z))` is defined if and only if: - `g = 0` and `\mathrm{val}(f) \geq 0`, - - `g` is non-zero and `f` has only finitely many non-zero coefficients, - - `g` is non-zero and `\mathrm{val}(g) > 0`. + - `g` is nonzero and `f` has only finitely many nonzero coefficients, + - `g` is nonzero and `\mathrm{val}(g) > 0`. INPUT: @@ -4031,7 +4027,7 @@ def __call__(self, g): ZeroDivisionError: the valuation of the series must be nonnegative `g \neq 0` and `\mathrm{val}(g) \leq 0` and `f` has infinitely many - non-zero coefficients:: + nonzero coefficients:: sage: g = z^-1 + z^-2 sage: g.valuation() <= 0 @@ -4122,7 +4118,6 @@ def __call__(self, g): sage: g = L([2]) sage: f(g) 0 - """ # Find a good parent for the result from sage.structure.element import get_coercion_model @@ -4139,7 +4134,7 @@ def __call__(self, g): and isinstance(g._coeff_stream, Stream_zero))): if self._coeff_stream._approximate_order >= 0: return P(self[0]) - # Perhaps we just don't yet know if the valuation is non-negative + # Perhaps we just don't yet know if the valuation is nonnegative if any(self._coeff_stream[i] for i in range(self._coeff_stream._approximate_order, 0)): raise ZeroDivisionError("the valuation of the series must be nonnegative") self._coeff_stream._approximate_order = 0 @@ -4705,7 +4700,7 @@ def approximate_series(self, prec, name=None): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer - ``name`` -- name of the variable; if it is ``None``, the name of the variable of the series is used @@ -4765,7 +4760,7 @@ def polynomial(self, degree=None, name=None): If ``degree`` is not ``None``, the terms of the series of degree greater than ``degree`` are first truncated. If ``degree`` is ``None`` and the series is not a polynomial or - a Laurent polynomial, a ``ValueError`` is raised. + a Laurent polynomial, a :exc:`ValueError` is raised. EXAMPLES:: @@ -4806,7 +4801,6 @@ def polynomial(self, degree=None, name=None): sage: L.zero().polynomial() 0 - """ S = self.parent() @@ -4937,7 +4931,7 @@ def exponential(self): def compute_coefficients(self, i): r""" - Computes all the coefficients of ``self`` up to ``i``. + Compute all the coefficients of ``self`` up to ``i``. This method is deprecated, it has no effect anymore. @@ -4976,7 +4970,6 @@ def _im_gens_(self, codomain, im_gens, base_map=None): sage: f = 1/(1+x*q-t) sage: f._im_gens_(S, [s, x*s], base_map=cc) 1 + 2*x*s + 4*x^2*s^2 + 8*x^3*s^3 + 16*x^4*s^4 + 32*x^5*s^5 + 64*x^6*s^6 + O(s^7) - """ if base_map is None: return codomain(self(*im_gens)) @@ -5628,7 +5621,7 @@ def adams_operator(self, p): INPUT: - - ``p`` -- a positive integer + - ``p`` -- positive integer EXAMPLES: @@ -6012,7 +6005,7 @@ def polynomial(self, degree=None, names=None): If ``degree`` is not ``None``, the terms of the series of degree greater than ``degree`` are first truncated. If ``degree`` is ``None`` and the series is not a polynomial - polynomial, a ``ValueError`` is raised. + polynomial, a :exc:`ValueError` is raised. EXAMPLES:: @@ -6401,16 +6394,16 @@ def __call__(self, *args): - `g_i = 0`, or - setting all alphabets except the `i`-th in `f` to zero yields a symmetric function with only finitely many - non-zero coefficients, or + nonzero coefficients, or - `\mathrm{val}(g) > 0`. If `f` is a univariate 'exact' lazy symmetric function, we - can check whether `f` has only finitely many non-zero + can check whether `f` has only finitely many nonzero coefficients. However, if `f` has larger arity, we have no way to test whether setting all but one alphabets of `f` to zero yields a polynomial, except if `f` itself is 'exact' and therefore a symmetric function with only finitely many - non-zero coefficients. + nonzero coefficients. INPUT: @@ -6669,7 +6662,6 @@ def revert(self): - Andrew Gainer-Dewar - Martin Rubey - """ P = self.parent() if P._arity != 1: @@ -6833,7 +6825,7 @@ def derivative_with_respect_to_p1(self, n=1): def suspension(self): r""" - Return the suspension of `self``. + Return the suspension of ``self``. This is an involution, that maps the homogeneous component `f_n` of degree `n` to `(-1)^{n - 1} \omega(f_n)`, where @@ -6919,7 +6911,7 @@ def functorial_composition(self, *args): sage: P.functorial_composition(P2)[4].coefficient([2,2])[3] # needs sage.libs.pari sage.modules 8 - labellings of their vertices with two 1's and two 2's. + labellings of their vertices with two 1s and two 2s. The symmetric function `h_1 \sum_n h_n` is the neutral element with respect to functorial composition:: @@ -6981,9 +6973,8 @@ def functorial_composition(self, *args): """ if len(args) != self.parent()._arity: raise ValueError("arity must be equal to the number of arguments provided") - from sage.combinat.sf.sfa import is_SymmetricFunction - if not all(isinstance(g, LazySymmetricFunction) - or is_SymmetricFunction(g) + from sage.combinat.sf.sfa import SymmetricFunctionAlgebra_generic + if not all(isinstance(g, (LazySymmetricFunction, SymmetricFunctionAlgebra_generic.Element)) or not g for g in args): raise ValueError("all arguments must be (possibly lazy) symmetric functions") @@ -7104,9 +7095,7 @@ def arithmetic_product(self, *args): - ``g`` -- a cycle index series having the same parent as ``self`` - OUTPUT: - - The arithmetic product of ``self`` with ``g``. + OUTPUT: the arithmetic product of ``self`` with ``g`` .. SEEALSO:: @@ -7196,13 +7185,11 @@ def arithmetic_product(self, *args): sage: L = LazySymmetricFunctions(s) # needs sage.modules sage: L(s([2])).arithmetic_product(s([1,1,1])) # needs sage.modules s[2, 2, 1, 1] + s[3, 1, 1, 1] + s[3, 2, 1] + s[3, 3] - """ if len(args) != self.parent()._arity: raise ValueError("arity must be equal to the number of arguments provided") - from sage.combinat.sf.sfa import is_SymmetricFunction - if not all(isinstance(g, LazySymmetricFunction) - or is_SymmetricFunction(g) + from sage.combinat.sf.sfa import SymmetricFunctionAlgebra_generic + if not all(isinstance(g, (LazySymmetricFunction, SymmetricFunctionAlgebra_generic.Element)) or not g for g in args): raise ValueError("all arguments must be (possibly lazy) symmetric functions") @@ -7283,7 +7270,7 @@ def symmetric_function(self, degree=None): If ``degree`` is not ``None``, the terms of the series of degree greater than ``degree`` are first truncated. If ``degree`` is ``None`` and the series is not a polynomial - polynomial, a ``ValueError`` is raised. + polynomial, a :exc:`ValueError` is raised. EXAMPLES:: @@ -7321,7 +7308,6 @@ def symmetric_function(self, degree=None): 0 sage: f4.symmetric_function(0) # needs lrcalc_python s[] - """ S = self.parent() R = S._laurent_poly_ring @@ -7508,13 +7494,13 @@ def __invert__(self): O(1/(8^z)) Trying to invert a non-invertible 'exact' series raises a - ``ZeroDivisionError``:: + :exc:`ZeroDivisionError`:: sage: f = ~L([0,1], constant=1) sage: f[1] Traceback (most recent call last): ... - ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero + ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is nonzero sage: f = ~L(lambda n: n-1) sage: f[1] diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 6f96ffc839d..ee3e463e988 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -122,8 +122,8 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No INPUT: - ``x`` -- data used to the define a series - - ``valuation`` -- integer (optional); integer; a lower bound for - the valuation of the series + - ``valuation`` -- integer (optional); a lower bound for the valuation + of the series - ``degree`` -- (optional) the degree when the series is ``constant`` - ``constant`` -- (optional) the eventual constant of the series - ``coefficients`` -- (optional) a callable that defines the @@ -738,7 +738,6 @@ def one(self): sage: L = LazySymmetricFunctions(m) # needs sage.modules sage: L.one() # needs sage.modules m[] - """ R = self.base_ring() coeff_stream = Stream_exact([R.one()], constant=R.zero(), order=0) @@ -919,9 +918,9 @@ def prod(self, f, a=None, b=infinity, add_one=False): INPUT: - - ``f`` -- a list (or iterable) of elements of ``self`` + - ``f`` -- list (or iterable) of elements of ``self`` - ``a``, ``b`` -- optional arguments - - ``add_one`` -- (default: ``False``); if ``True``, then converts a + - ``add_one`` -- (default: ``False``) if ``True``, then converts a lazy series `p_i` from ``args`` into `1 + p_i` for the product If ``a`` and ``b`` are both integers, then this returns the product @@ -1019,7 +1018,7 @@ def sum(self, f, a=None, b=infinity): INPUT: - - ``f`` -- a list (or iterable or function) of elements of ``self`` + - ``f`` -- list (or iterable or function) of elements of ``self`` - ``a``, ``b`` -- optional arguments If ``a`` and ``b`` are both integers, then this returns the sum @@ -1245,7 +1244,7 @@ class LazyLaurentSeriesRing(LazySeriesRing): - ``base_ring`` -- base ring - ``names`` -- name of the generator - - ``sparse`` -- (default: ``True``) whether the implementation of + - ``sparse`` -- boolean (default: ``True``); whether the implementation of the series is sparse or not EXAMPLES:: @@ -1392,7 +1391,7 @@ class LazyLaurentSeriesRing(LazySeriesRing): False We additionally provide two other methods of performing comparisons. - The first is raising a ``ValueError`` and the second uses a check + The first is raising a :exc:`ValueError` and the second uses a check up to a (user set) finite precision. These behaviors are set using the options ``secure`` and ``halting_precision``. In particular, this applies to series that are not specified by a finite number @@ -1400,7 +1399,7 @@ class LazyLaurentSeriesRing(LazySeriesRing): Equality checking will depend on the coefficients which have already been computed. If this information is not enough to check that two series are different, then if ``L.options.secure`` - is set to ``True``, then we raise a ``ValueError``:: + is set to ``True``, then we raise a :exc:`ValueError`:: sage: L.options.secure = True sage: f = 1 / (z + z^2); f @@ -1489,10 +1488,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() # needs sage.libs.singular sage: L.category() Category of infinite commutative no zero divisors algebras over - (unique factorization domains and commutative algebras over + (unique factorization domains and algebras with basis over (Dedekind domains and euclidean domains - and noetherian rings - and infinite enumerated sets and metric spaces) + and noetherian rings + and infinite enumerated sets and metric spaces) + and commutative algebras over + (Dedekind domains and euclidean domains + and noetherian rings + and infinite enumerated sets and metric spaces) and infinite sets) sage: L = LazyLaurentSeriesRing(GF(5), 't') @@ -1963,7 +1966,7 @@ class LazyPowerSeriesRing(LazySeriesRing): - ``base_ring`` -- base ring of this Taylor series ring - ``names`` -- name(s) of the generator of this Taylor series ring - - ``sparse`` -- (default: ``True``) whether this series is sparse or not + - ``sparse`` -- boolean (default: ``True``); whether this series is sparse or not EXAMPLES:: @@ -1987,14 +1990,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: LazyPowerSeriesRing.options.halting_precision(12) sage: L = LazyPowerSeriesRing(ZZ, 't') - sage: TestSuite(L).run(skip="_test_fraction_field") + sage: TestSuite(L).run(skip='_test_fraction_field') sage: L = LazyPowerSeriesRing(ZZ, 's, t') - sage: TestSuite(L).run(skip="_test_fraction_field") + sage: TestSuite(L).run(skip='_test_fraction_field') sage: L = LazyPowerSeriesRing(QQ, 't') - sage: TestSuite(L).run(skip="_test_fraction_field") + sage: TestSuite(L).run(skip='_test_fraction_field') sage: L = LazyPowerSeriesRing(QQ, 's, t') - sage: TestSuite(L).run(skip="_test_fraction_field") + sage: TestSuite(L).run(skip='_test_fraction_field') sage: L = LazyPowerSeriesRing(GF(5), 't') sage: TestSuite(L).run() @@ -2008,14 +2011,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run(skip=['_test_revert']) sage: L = LazyPowerSeriesRing(QQ['q'], 't') - sage: TestSuite(L).run(skip="_test_fraction_field") + sage: TestSuite(L).run(skip='_test_fraction_field') sage: L = LazyPowerSeriesRing(QQ['q'], 's, t') - sage: TestSuite(L).run(skip="_test_fraction_field") # long time + sage: TestSuite(L).run(skip='_test_fraction_field') # long time sage: L = LazyPowerSeriesRing(ZZ['q'], 't') - sage: TestSuite(L).run(skip="_test_fraction_field") + sage: TestSuite(L).run(skip='_test_fraction_field') sage: L = LazyPowerSeriesRing(ZZ['q'], 's, t') - sage: TestSuite(L).run(skip="_test_fraction_field") # long time + sage: TestSuite(L).run(skip='_test_fraction_field') # long time sage: LazyPowerSeriesRing.options._reset() # reset the options @@ -2182,15 +2185,17 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No INPUT: - ``x`` -- data used to the define a Taylor series - - ``valuation`` -- integer (optional); integer; a lower bound for the valuation of the series + - ``valuation`` -- integer (optional); a lower bound for the valuation + of the series - ``constant`` -- (optional) the eventual constant of the series - ``degree`` -- (optional) the degree when the series is ``constant`` - - ``check`` -- (optional) check that coefficients are homogeneous of the correct degree when they are retrieved + - ``check`` -- (optional) check that coefficients are homogeneous of + the correct degree when they are retrieved .. WARNING:: The behaviour of ``LazyPowerSeries(c)`` for a list ``c`` - with non-zero last element `e` changed with + with nonzero last element `e` changed with :issue:`32367`. To obtain the old behaviour, use ``LazyPowerSeries(c, constant=e)``. @@ -2297,11 +2302,10 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No Traceback (most recent call last): ... ValueError: coefficients must be homogeneous polynomials of the correct degree - """ if valuation is not None: if valuation < 0: - raise ValueError("the valuation of a Taylor series must be non-negative") + raise ValueError("the valuation of a Taylor series must be nonnegative") # TODO: the following is nonsense, think of an iterator if self._arity > 1: raise ValueError("valuation must not be specified for multivariate Taylor series") @@ -2641,7 +2645,7 @@ class LazyCompletionGradedAlgebra(LazySeriesRing): - ``basis`` -- a graded algebra - ``names`` -- name(s) of the alphabets - - ``sparse`` -- (default: ``True``) whether we use a sparse or + - ``sparse`` -- boolean (default: ``True``); whether we use a sparse or a dense representation EXAMPLES:: @@ -2798,8 +2802,8 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No INPUT: - ``x`` -- data used to the define a lazy element - - ``valuation`` -- integer (optional); integer; a lower bound for - the valuation of the series + - ``valuation`` -- integer (optional); a lower bound for the valuation + of the series - ``degree`` -- (optional) the degree when the lazy element has finite support - ``check`` -- (optional) check that coefficients are homogeneous of @@ -3012,7 +3016,6 @@ def some_elements(self): sage: L = S.formal_series_ring() sage: L.some_elements()[:4] [0, S[], 2*S[] + 2*S[1] + (3*S[1,1]), 2*S[1] + (3*S[1,1])] - """ elt = self.an_element() elts = [self.zero(), self.one(), elt] @@ -3045,7 +3048,8 @@ class LazySymmetricFunctions(LazyCompletionGradedAlgebra): - ``basis`` -- the ring of symmetric functions - ``names`` -- name(s) of the alphabets - - ``sparse`` -- (default: ``True``) whether we use a sparse or a dense representation + - ``sparse`` -- boolean (default: ``True``); whether we use a sparse or a + dense representation EXAMPLES:: @@ -3072,7 +3076,7 @@ class LazyDirichletSeriesRing(LazySeriesRing): - ``base_ring`` -- base ring of this Dirichlet series ring - ``names`` -- name of the generator of this Dirichlet series ring - - ``sparse`` -- (default: ``True``) whether this series is sparse or not + - ``sparse`` -- boolean (default: ``True``); whether this series is sparse or not Unlike formal univariate Laurent/power series (over a field), the ring of formal Dirichlet series is not a @@ -3164,7 +3168,6 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() # needs sage.symbolic sage: LazyDirichletSeriesRing.options._reset() # reset the options - """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") @@ -3234,8 +3237,8 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No INPUT: - ``x`` -- data used to the define a Dirichlet series - - ``valuation`` -- integer (optional); integer; a lower bound for - the exp of the valuation of the series + - ``valuation`` -- integer (optional); a lower bound for the exp of the + valuation of the series - ``degree`` -- (optional) the degree when the series is ``constant`` - ``constant`` -- (optional) the eventual constant of the series diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index e19d814b55d..be1fc217a8d 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -195,11 +195,10 @@ def normalize_extra_units(base_ring, add_units, warning=True): - ``base_ring`` -- an instance of :class:`IntegralDomain` - ``add_units`` -- list of elements from base ring - - ``warning`` -- (default: ``True``) to suppress a warning which is thrown if no normalization was possible + - ``warning`` -- boolean (default: ``True``); to suppress a warning which + is thrown if no normalization was possible - OUTPUT: - - List of all prime factors of the elements of the given list. + OUTPUT: list of all prime factors of the elements of the given list EXAMPLES:: @@ -251,13 +250,13 @@ def normalize_extra_units(base_ring, add_units, warning=True): class LocalizationElement(IntegralDomainElement): """ - Element class for localizations of integral domains + Element class for localizations of integral domains. INPUT: - ``parent`` -- instance of :class:`Localization` - - ``x`` -- instance of :class:`FractionFieldElement` whose parent is the fraction - field of the parent's base ring + - ``x`` -- instance of :class:`FractionFieldElement` whose parent is the + fraction field of the parent's base ring EXAMPLES:: @@ -527,9 +526,7 @@ def _rational_(self): This is only possible if its base ring is the ring of integers. - OUTPUT: - - A rational. + OUTPUT: a rational TESTS:: @@ -550,9 +547,7 @@ def _integer_(self, Z=None): This is only possible if its base ring is the ring of integers and the denominator of ``self`` is one. - OUTPUT: - - An integer. + OUTPUT: integer TESTS:: @@ -568,32 +563,40 @@ def _integer_(self, Z=None): class Localization(IntegralDomain, UniqueRepresentation): r""" - The localization generalizes the construction of the field of fractions of an integral domain to - an arbitrary ring. Given a (not necessarily commutative) ring `R` and a subset `S` of `R`, - there exists a ring `R[S^{-1}]` together with the ring homomorphism `R \longrightarrow R[S^{-1}]` - that "inverts" `S`; that is, the homomorphism maps elements in `S` to unit elements in `R[S^{-1}]` - and, moreover, any ring homomorphism from `R` that "inverts" `S` uniquely factors through `R[S^{-1}]`. - - The ring `R[S^{-1}]` is called the *localization* of `R` with respect to `S`. For example, if `R` is - a commutative ring and `f` an element in `R`, then the localization consists of elements of the form - `r/f, r\in R, n \geq 0` (to be precise, `R[f^{-1}] = R[t]/(ft-1)`. - - The above text is taken from `Wikipedia`. The construction here used for this class relies on the - construction of the field of fraction and is therefore restricted to integral domains. - - Accordingly, this class is inherited from :class:`IntegralDomain` and can only be used in that context. - Furthermore, the base ring should support :meth:`sage.structure.element.CommutativeRingElement.divides` and - the exact division operator `//` (:meth:`sage.structure.element.Element.__floordiv__`) in order to guarantee - a successful application. + The localization generalizes the construction of the field of fractions of + an integral domain to an arbitrary ring. Given a (not necessarily + commutative) ring `R` and a subset `S` of `R`, there exists a ring + `R[S^{-1}]` together with the ring homomorphism `R \longrightarrow R[S^{-1}]` + that "inverts" `S`; that is, the homomorphism maps elements in `S` to unit + elements in `R[S^{-1}]` and, moreover, any ring homomorphism from `R` that + "inverts" `S` uniquely factors through `R[S^{-1}]`. + + The ring `R[S^{-1}]` is called the *localization* of `R` with respect to + `S`. For example, if `R` is a commutative ring and `f` an element in `R`, + then the localization consists of elements of the form + `r/f, r\in R, n \geq 0` (to be precise, `R[f^{-1}] = R[t]/(ft-1)`). + + The above text is taken from `Wikipedia`. The construction here used for + this class relies on the construction of the field of fraction and is + therefore restricted to integral domains. + + Accordingly, this class is inherited from :class:`IntegralDomain` and can + only be used in that context. Furthermore, the base ring should support + :meth:`sage.structure.element.CommutativeRingElement.divides` and the exact + division operator ``//`` (:meth:`sage.structure.element.Element.__floordiv__`) + in order to guarantee a successful application. INPUT: - - ``base_ring`` -- an instance of :class:`Ring` allowing the construction of :meth:`fraction_field` (that is an integral domain) - - ``extra_units`` -- tuple of elements of ``base_ring`` which should be turned into units + - ``base_ring`` -- an instance of :class:`Ring` allowing the construction + of :meth:`fraction_field` (that is an integral domain) + - ``extra_units`` -- tuple of elements of ``base_ring`` which should be + turned into units - ``names`` -- passed to :class:`IntegralDomain` - - ``normalize`` -- (default: ``True``) passed to :class:`IntegralDomain` - - ``category`` -- (default: None) passed to :class:`IntegralDomain` - - ``warning`` -- (default: ``True``) to suppress a warning which is thrown if self cannot be represented uniquely + - ``normalize`` -- boolean (default: ``True``); passed to :class:`IntegralDomain` + - ``category`` -- (default: ``None``) passed to :class:`IntegralDomain` + - ``warning`` -- boolean (default: ``True``); to suppress a warning which + is thrown if ``self`` cannot be represented uniquely REFERENCES: @@ -899,16 +902,14 @@ def _cut_off_extra_units_from_base_ring_element(self, x): def _fraction_to_element(self, x): """ - Checks if the given element of the fraction field is contained in ``self`` - and construct it as an element of self in case the answer is true. + Check if the given element of the fraction field is contained in ``self`` + and construct it as an element of ``self`` in case the answer is true. INPUT: - ``x`` -- an element of the fraction field of the base ring - OUTPUT: - - An instance of the element class of self representing `x`. + OUTPUT: an instance of the element class of ``self`` representing `x` EXAMPLES:: @@ -1019,15 +1020,15 @@ def is_field(self, proof=True): INPUT: - - ``proof`` -- (default: ``True``) Determines what to do in unknown - cases + - ``proof`` -- boolean (default: ``True``); determines what to do in + unknown cases ALGORITHM: If the parameter ``proof`` is set to ``True``, the returned value is correct but the method might throw an error. Otherwise, if it is set - to ``False``, the method returns True if it can establish that self is - a field and False otherwise. + to ``False``, the method returns ``True`` if it can establish that + ``self`` is a field and ``False`` otherwise. EXAMPLES:: diff --git a/src/sage/rings/meson.build b/src/sage/rings/meson.build new file mode 100644 index 00000000000..9aff2d7c8f3 --- /dev/null +++ b/src/sage/rings/meson.build @@ -0,0 +1,217 @@ +pthread = cc.find_library('pthread') + +py.install_sources( + 'abc.pxd', + 'algebraic_closure_finite_field.py', + 'all.py', + 'all__sagemath_categories.py', + 'all__sagemath_objects.py', + 'big_oh.py', + 'cc.py', + 'cfinite_sequence.py', + 'cif.py', + 'commutative_algebra.py', + 'complex_arb.pxd', + 'complex_conversion.pxd', + 'complex_double.pxd', + 'complex_interval.pxd', + 'complex_interval_field.py', + 'complex_mpc.pxd', + 'complex_mpfr.pxd', + 'continued_fraction.py', + 'continued_fraction_gosper.py', + 'derivation.py', + 'fast_arith.pxd', + 'fraction_field.py', + 'fraction_field_FpT.pxd', + 'generic.py', + 'homset.py', + 'ideal.py', + 'ideal_monoid.py', + 'imaginary_unit.py', + 'infinity.py', + 'integer.pxd', + 'integer.pyx', + 'integer_fake.h', + 'integer_fake.pxd', + 'integer_ring.pxd', + 'integer_ring.pyx', + 'laurent_series_ring.py', + 'laurent_series_ring_element.pxd', + 'lazy_series.py', + 'lazy_series_ring.py', + 'localization.py', + 'monomials.py', + 'morphism.pxd', + 'multi_power_series_ring.py', + 'multi_power_series_ring_element.py', + 'numbers_abc.py', + 'pari_ring.py', + 'power_series_mpoly.pxd', + 'power_series_pari.pxd', + 'power_series_poly.pxd', + 'power_series_ring.py', + 'power_series_ring_element.pxd', + 'puiseux_series_ring.py', + 'puiseux_series_ring_element.pxd', + 'qqbar.py', + 'qqbar_decorators.py', + 'quotient_ring.py', + 'quotient_ring_element.py', + 'rational.pxd', + 'rational.pyx', + 'rational_field.py', + 'real_arb.pxd', + 'real_double.pxd', + 'real_double_element_gsl.pxd', + 'real_field.py', + 'real_lazy.pxd', + 'real_mpfi.pxd', + 'real_mpfr.pxd', + 'ring.pxd', + 'ring_extension.pxd', + 'ring_extension_conversion.pxd', + 'ring_extension_element.pxd', + 'ring_extension_homset.py', + 'ring_extension_morphism.pxd', + 'sum_of_squares.pxd', + 'tate_algebra.py', + 'tate_algebra_element.pxd', + 'tate_algebra_ideal.pxd', + 'tests.py', + 'universal_cyclotomic_field.py', + subdir: 'sage/rings', +) + +extension_data = { + 'abc' : files('abc.pyx'), + 'complex_arb' : files('complex_arb.pyx'), + 'complex_conversion' : files('complex_conversion.pyx'), + 'complex_double' : files('complex_double.pyx'), + 'complex_interval' : files('complex_interval.pyx'), + 'complex_mpc' : files('complex_mpc.pyx'), + 'complex_mpfr' : files('complex_mpfr.pyx'), + 'factorint' : files('factorint.pyx'), + 'factorint_flint' : files('factorint_flint.pyx'), + 'factorint_pari' : files('factorint_pari.pyx'), + 'fast_arith' : files('fast_arith.pyx'), + 'fraction_field_element' : files('fraction_field_element.pyx'), + 'integer' : files('integer.pyx'), + 'integer_ring' : files('integer_ring.pyx'), + 'laurent_series_ring_element' : files('laurent_series_ring_element.pyx'), + 'morphism' : files('morphism.pyx'), + 'noncommutative_ideals' : files('noncommutative_ideals.pyx'), + 'power_series_mpoly' : files('power_series_mpoly.pyx'), + 'power_series_pari' : files('power_series_pari.pyx'), + 'power_series_poly' : files('power_series_poly.pyx'), + 'power_series_ring_element' : files('power_series_ring_element.pyx'), + 'puiseux_series_ring_element' : files('puiseux_series_ring_element.pyx'), + 'real_arb' : files('real_arb.pyx'), + 'real_double' : files('real_double.pyx'), + 'real_double_element_gsl' : files('real_double_element_gsl.pyx'), + 'real_interval_absolute' : files('real_interval_absolute.pyx'), + 'real_lazy' : files('real_lazy.pyx'), + 'real_mpfi' : files('real_mpfi.pyx'), + 'real_mpfr' : files('real_mpfr.pyx'), + 'ring' : files('ring.pyx'), + 'ring_extension' : files('ring_extension.pyx'), + 'ring_extension_conversion' : files('ring_extension_conversion.pyx'), + 'ring_extension_element' : files('ring_extension_element.pyx'), + 'ring_extension_morphism' : files('ring_extension_morphism.pyx'), + 'sum_of_squares' : files('sum_of_squares.pyx'), + 'tate_algebra_element' : files('tate_algebra_element.pyx'), + 'tate_algebra_ideal' : files('tate_algebra_ideal.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_gsl, + inc_ntl, + inc_rings, + inc_rings_finite, + ], + dependencies: [ + py_dep, + cypari2, + cysignals, + flint, + gmp, + gmpy2, + gsl, + m, + mpc, + mpfi, + mpfr, + ntl, + pari, + pthread, + ], + ) +endforeach + +extension_data_cpp = { + 'bernmm': files( + 'bernmm.pyx', + 'bernmm/bern_modp.cpp', + 'bernmm/bern_modp_util.cpp', + 'bernmm/bern_rat.cpp', + ), + 'bernoulli_mod_p': files('bernoulli_mod_p.pyx'), + 'fraction_field_FpT': files('fraction_field_FpT.pyx'), + 'rational': files('rational.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings', + install: true, + cpp_args: ['-DUSE_THREADS=1', '-DTHREAD_STACK_SIZE=4096'], + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_gsl, + inc_ntl, + inc_rings, + inc_rings_finite, + ], + dependencies: [ + py_dep, + cypari2, + cysignals, + flint, + gmp, + gmpy2, + gsl, + m, + mpc, + mpfi, + mpfr, + ntl, + pari, + pthread, + ], + ) +endforeach + +install_subdir('asymptotic', install_dir: sage_install_dir / 'rings') +subdir('convert') +subdir('finite_rings') +subdir('function_field') +install_subdir('invariants', install_dir: sage_install_dir / 'rings') +subdir('number_field') +subdir('padics') +subdir('polynomial') +subdir('semirings') +install_subdir('valuation', install_dir: sage_install_dir / 'rings') diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index bad89829a70..594e2ff0a3e 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -648,7 +648,6 @@ cdef class RingHomomorphism(RingMap): sage: isinstance(f, sage.rings.morphism.RingHomomorphism) # needs sage.rings.padics True - """ from sage.rings.homset import RingHomset_generic if not isinstance(parent, RingHomset_generic): @@ -663,7 +662,6 @@ cdef class RingHomomorphism(RingMap): sage: ZZ.hom(Zp(3))._repr_type() # needs sage.rings.padics 'Ring' - """ return "Ring" @@ -678,9 +676,7 @@ cdef class RingHomomorphism(RingMap): - ``lift`` -- a ring map - OUTPUT: - - Changes the state of ``self``. + OUTPUT: changes the state of ``self`` EXAMPLES:: @@ -691,7 +687,6 @@ cdef class RingHomomorphism(RingMap): From: Ring of integers modulo 3 To: Integer Ring Defn: Choice of lifting map - """ if lift.domain() != self.codomain(): raise TypeError("lift must have correct domain") @@ -888,7 +883,7 @@ cdef class RingHomomorphism(RingMap): def pushforward(self, I): """ - Returns the pushforward of the ideal `I` under this ring + Return the pushforward of the ideal `I` under this ring homomorphism. EXAMPLES:: @@ -898,7 +893,7 @@ cdef class RingHomomorphism(RingMap): Ideal (xx, xx*yy + 3*xx) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) """ - if not ideal.is_Ideal(I): + if not isinstance(I, ideal.Ideal_generic): raise TypeError("I must be an ideal") R = self.codomain() return R.ideal([self(y) for y in I.gens()]) @@ -1038,10 +1033,10 @@ cdef class RingHomomorphism(RingMap): sage: f.kernel() # needs sage.libs.singular Ideal (0) of Multivariate Polynomial Ring in t, u over Rational Field """ - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing - from sage.rings.quotient_ring import is_QuotientRing - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic + from sage.rings.quotient_ring import QuotientRing_nc + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general B = self.codomain() graph, from_B, to_A = self._graph_ideal() Q = graph.ring() @@ -1050,14 +1045,14 @@ cdef class RingHomomorphism(RingMap): # avoid adding the 0-ideal to the graph ideal in order to benefit # from a cached Gröbner basis graph_I = graph - elif (is_MPolynomialRing(B) or is_PolynomialRing(B) - or is_QuotientRing(B) or is_PolynomialQuotientRing(B)): + elif (isinstance(B, MPolynomialRing_base) or isinstance(B, PolynomialRing_general) + or isinstance(B, QuotientRing_nc) or isinstance(B, PolynomialQuotientRing_generic)): graph_I = graph + from_B(I) else: - # non-zero fractional ideals of number fields not yet supported + # nonzero fractional ideals of number fields not yet supported raise NotImplementedError("inverse image not implemented " "for ideals in %s" % B) - if is_QuotientRing(Q): + if isinstance(Q, QuotientRing_nc): # elimination_ideal does not work with quotient rings, so # switch to the cover ring gens_B_lifted = Q.cover_ring().gens()[:B.ngens()] @@ -1287,7 +1282,7 @@ cdef class RingHomomorphism(RingMap): ... NotImplementedError: rings are not commutative """ - from sage.rings.quotient_ring import is_QuotientRing + from sage.rings.quotient_ring import QuotientRing_nc from sage.rings.ideal import Ideal_generic A = self.domain() B = self.codomain() @@ -1306,7 +1301,7 @@ cdef class RingHomomorphism(RingMap): A_to_Q = A.hom(Q.gens()[B.ngens():], Q, check=False) B_to_Q = B.hom(Q.gens()[:B.ngens()], Q, check=False) graph = Q.ideal([B_to_Q(self(x)) - A_to_Q(x) for x in A.gens()]) - R = Q.cover_ring() if is_QuotientRing(Q) else Q + R = Q.cover_ring() if isinstance(Q, QuotientRing_nc) else Q R_to_A = R.hom(tuple([0] * B.ngens()) + A.gens(), A, check=False) Q_to_A = R_to_A if R is Q else R_to_A * Q.lifting_map() @@ -1328,7 +1323,7 @@ cdef class RingHomomorphism(RingMap): """ Return the inverse of this ring homomorphism if it exists. - Raises a ``ZeroDivisionError`` if the inverse does not exist. + Raises a :exc:`ZeroDivisionError` if the inverse does not exist. ALGORITHM: @@ -2282,7 +2277,7 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): """ P = self.codomain() try: - return P(dict([(a, self._underlying(b)) for a,b in x.dict().items()])) + return P({a: self._underlying(b) for a, b in x.monomial_coefficients().items()}) except Exception: pass try: @@ -2495,7 +2490,7 @@ cdef class RingHomomorphism_cover(RingHomomorphism): We verify that calling directly raises the expected error (just coercing into the codomain), but calling with __call__ - (the second call below) gives a :class:`TypeError` since 1/2 cannot be + (the second call below) gives a :exc:`TypeError` since 1/2 cannot be coerced into the domain. :: sage: f._call_(1/2) @@ -2621,10 +2616,10 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): INPUT: - - ``parent`` -- a ring homset ``Hom(R,S)`` + - ``parent`` -- a ring homset ``Hom(R,S)`` - - ``phi`` -- a ring homomorphism ``C --> S``, where ``C`` is the - domain of ``R.cover()`` + - ``phi`` -- a ring homomorphism ``C --> S``, where ``C`` is the + domain of ``R.cover()`` OUTPUT: a ring homomorphism @@ -2652,7 +2647,7 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): True Validity of the homomorphism is determined, when possible, and a - ``TypeError`` is raised if there is no homomorphism sending the + :exc:`TypeError` is raised if there is no homomorphism sending the generators to the given images:: sage: S.hom([b^2, c^2, a^2]) # needs sage.libs.singular @@ -2712,7 +2707,6 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): False sage: psi(a) == phi(a) True - """ self.phi = _slots['phi'] RingHomomorphism._update_slots(self, _slots) @@ -2864,9 +2858,9 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): """ INPUT: - - ``domain`` -- a ring + - ``domain`` -- a ring - - ``n`` -- a nonnegative integer (default: 1) + - ``n`` -- nonnegative integer (default: 1) OUTPUT: @@ -3061,7 +3055,7 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): def _composition(self, right): """ - Return self o right. + Return ``self`` o ``right``. EXAMPLES:: @@ -3139,12 +3133,12 @@ def _tensor_product_ring(B, A): """ from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.number_field.number_field_base import NumberField - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.term_order import TermOrder - from sage.rings.quotient_ring import is_QuotientRing + from sage.rings.quotient_ring import QuotientRing_nc if set(B.variable_names()).isdisjoint(A.variable_names()): names = B.variable_names() + A.variable_names() @@ -3154,7 +3148,7 @@ def _tensor_product_ring(B, A): def term_order(A): # univariate rings do not have a term order - if (is_PolynomialRing(A) or is_PolynomialQuotientRing(A) + if (isinstance(A, PolynomialRing_general) or isinstance(A, PolynomialQuotientRing_generic) or (isinstance(A, (NumberField, FiniteField)) and not A.is_prime_field())): return TermOrder('lex', 1) @@ -3170,12 +3164,12 @@ def _tensor_product_ring(B, A): order=term_order(B) + term_order(A)) def relations(A, R_gens_A): - if is_MPolynomialRing(A) or is_PolynomialRing(A): + if isinstance(A, MPolynomialRing_base) or isinstance(A, PolynomialRing_general): return [] - elif is_PolynomialQuotientRing(A): + elif isinstance(A, PolynomialQuotientRing_generic): to_R = A.ambient().hom(R_gens_A, R, check=False) return [to_R(A.modulus())] - elif is_QuotientRing(A): + elif isinstance(A, QuotientRing_nc): to_R = A.ambient().hom(R_gens_A, R, check=False) return list(to_R(A.defining_ideal()).gens()) elif (isinstance(A, (NumberField, FiniteField)) diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index d399fdb6c0b..35c4d4beb32 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -205,15 +205,16 @@ import sage.misc.latex as latex +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import infinity from sage.rings.multi_power_series_ring_element import MPowerSeries -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.polynomial.term_order import TermOrder -from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic, is_PowerSeriesRing -from sage.rings.ring import CommutativeRing +from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic from sage.structure.nonexact import Nonexact +from sage.structure.parent import Parent from sage.categories.commutative_rings import CommutativeRings _CommutativeRings = CommutativeRings() @@ -226,6 +227,8 @@ except ImportError: LaurentSeriesRing = () +lazy_import('sage.rings.lazy_series_ring', ('LazyPowerSeriesRing', 'LazyLaurentSeriesRing')) + def is_MPowerSeriesRing(x): """ @@ -237,8 +240,16 @@ def is_MPowerSeriesRing(x): sage: from sage.rings.multi_power_series_ring import is_MPowerSeriesRing sage: M = PowerSeriesRing(ZZ, 4, 'v') sage: is_PowerSeriesRing(M) + doctest:warning... + DeprecationWarning: The function is_PowerSeriesRing is deprecated; + use 'isinstance(..., (PowerSeriesRing_generic, LazyPowerSeriesRing) and ....ngens() == 1)' instead. + See https://github.com/sagemath/sage/issues/38290 for details. False sage: is_MPowerSeriesRing(M) + doctest:warning... + DeprecationWarning: The function is_MPowerSeriesRing is deprecated; + use 'isinstance(..., (MPowerSeriesRing_generic, LazyPowerSeriesRing))' instead. + See https://github.com/sagemath/sage/issues/38290 for details. True sage: T = PowerSeriesRing(RR, 'v') sage: is_PowerSeriesRing(T) @@ -252,7 +263,10 @@ def is_MPowerSeriesRing(x): sage: is_MPowerSeriesRing(L) True """ - from sage.rings.lazy_series_ring import LazyPowerSeriesRing + from sage.misc.superseded import deprecation + deprecation(38290, + "The function is_MPowerSeriesRing is deprecated; " + "use 'isinstance(..., (MPowerSeriesRing_generic, LazyPowerSeriesRing))' instead.") return isinstance(x, (MPowerSeriesRing_generic, LazyPowerSeriesRing)) @@ -306,7 +320,6 @@ def __classcall__(cls, base_ring, num_gens, name_list, sage: P2 = PowerSeriesRing(QQ,4,'f', order='degrevlex') sage: P1 is P2 # indirect doctest True - """ order = TermOrder(order, num_gens) return super().__classcall__(cls, base_ring, num_gens, name_list, @@ -315,7 +328,7 @@ def __classcall__(cls, base_ring, num_gens, name_list, def __init__(self, base_ring, num_gens, name_list, order='negdeglex', default_prec=10, sparse=False): """ - Initializes a multivariate power series ring. See PowerSeriesRing + Initialize a multivariate power series ring. See PowerSeriesRing for complete documentation. INPUT: @@ -324,7 +337,7 @@ def __init__(self, base_ring, num_gens, name_list, - ``num_gens`` -- number of generators - - ``name_list`` -- List of indeterminate names or a single name. + - ``name_list`` -- list of indeterminate names or a single name If a single name is given, indeterminates will be this name followed by a number from 0 to num_gens - 1. If a list is given, these will be the indeterminate names and the length @@ -333,11 +346,11 @@ def __init__(self, base_ring, num_gens, name_list, - ``order`` -- ordering of variables; default is negative degree lexicographic - - ``default_prec`` -- The default total-degree precision for - elements. The default value of default_prec is 10. + - ``default_prec`` -- (default: 10) the default total-degree precision + for elements - - ``sparse`` -- whether or not the power series are sparse. - The underlying polynomial ring is always sparse. + - ``sparse`` -- whether or not the power series are sparse; the + underlying polynomial ring is always sparse EXAMPLES:: @@ -364,7 +377,6 @@ def __init__(self, base_ring, num_gens, name_list, sage: P.category() Category of commutative rings sage: TestSuite(P).run() - """ self._term_order = order if not base_ring.is_commutative(): @@ -377,8 +389,9 @@ def __init__(self, base_ring, num_gens, name_list, # Multivariate power series rings inherit from power series rings. But # apparently we can not call their initialisation. Instead, initialise # CommutativeRing and Nonexact: - CommutativeRing.__init__(self, base_ring, name_list, category=_IntegralDomains if base_ring in - _IntegralDomains else _CommutativeRings) + Parent.__init__(self, base=base_ring, names=name_list, + category=_IntegralDomains if base_ring in + _IntegralDomains else _CommutativeRings) Nonexact.__init__(self, default_prec) # underlying polynomial ring in which to represent elements @@ -397,7 +410,7 @@ def __init__(self, base_ring, num_gens, name_list, def _repr_(self): """ - Prints out a multivariate power series ring. + Print out a multivariate power series ring. EXAMPLES:: @@ -420,7 +433,7 @@ def _repr_(self): def _latex_(self): """ - Returns latex representation of power series ring + Return latex representation of power series ring. EXAMPLES:: @@ -465,7 +478,7 @@ def is_noetherian(self, proof=False): def term_order(self): """ - Print term ordering of self. Term orderings are implemented by the + Print term ordering of ``self``. Term orderings are implemented by the TermOrder class. EXAMPLES:: @@ -476,7 +489,7 @@ def term_order(self): sage: m = y*z^12 - y^6*z^8 - x^7*y^5*z^2 + x*y^2*z + M.O(15); m x*y^2*z + y*z^12 - x^7*y^5*z^2 - y^6*z^8 + O(x, y, z)^15 - sage: N = PowerSeriesRing(ZZ,3,'x,y,z', order="deglex") + sage: N = PowerSeriesRing(ZZ,3,'x,y,z', order='deglex') sage: N.term_order() Degree lexicographic term order sage: N(m) @@ -486,7 +499,7 @@ def term_order(self): def characteristic(self): """ - Return characteristic of base ring, which is characteristic of self. + Return characteristic of base ring, which is characteristic of ``self``. EXAMPLES:: @@ -499,8 +512,8 @@ def characteristic(self): return self.base_ring().characteristic() def construction(self): - """ - Returns a functor F and base ring R such that F(R) == self. + r""" + Return a functor `F` and base ring `R` such that ``F(R) == self``. EXAMPLES:: @@ -533,7 +546,6 @@ def construction(self): sage: c,R = M3.construction() sage: c(R)==M3 True - """ from sage.categories.pushout import CompletionFunctor extras = {'order':self.term_order(), 'num_gens':self.ngens()} @@ -545,10 +557,10 @@ def construction(self): def change_ring(self, R): """ - Returns the power series ring over R in the same variable as self. + Return the power series ring over `R` in the same variable as ``self``. This function ignores the question of whether the base ring of self - is or can extend to the base ring of R; for the latter, use - base_extend. + is or can extend to the base ring of `R`; for the latter, use + ``base_extend``. EXAMPLES:: @@ -576,7 +588,7 @@ def change_ring(self, R): def remove_var(self, *var): """ - Remove given variable or sequence of variables from self. + Remove given variable or sequence of variables from ``self``. EXAMPLES:: @@ -598,7 +610,6 @@ def remove_var(self, *var): sage: M.remove_var(*M.gens()) Finite Field of size 5 - """ vars = list(self.variable_names()) for v in var: @@ -617,7 +628,7 @@ def remove_var(self, *var): def _coerce_impl(self, f): """ Return the canonical coercion of ``f`` into this multivariate power - series ring, if one is defined, or raise a TypeError. + series ring, if one is defined, or raise a :exc:`TypeError`. The rings that canonically coerce to this multivariate power series ring are: @@ -663,8 +674,9 @@ def _coerce_impl(self, f): True """ P = f.parent() - if is_MPolynomialRing(P) or is_MPowerSeriesRing(P) \ - or is_PolynomialRing(P) or is_PowerSeriesRing(P): + if isinstance(P, (PolynomialRing_general, MPolynomialRing_base, + PowerSeriesRing_generic, MPowerSeriesRing_generic, + LazyPowerSeriesRing)): if set(P.variable_names()).issubset(set(self.variable_names())): if self.has_coerce_map_from(P.base_ring()): return self(f) @@ -742,7 +754,8 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): if all(v == 0 for v in im_gens): return True - if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain) or isinstance(codomain, LaurentSeriesRing): + if isinstance(codomain, (PowerSeriesRing_generic, MPowerSeriesRing_generic, LazyPowerSeriesRing, + LaurentSeriesRing, LazyLaurentSeriesRing)): try: B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens) except NotImplementedError: @@ -827,8 +840,8 @@ def _coerce_map_from_(self, P): sage: R.has_coerce_map_from(L) True """ - if is_MPolynomialRing(P) or is_MPowerSeriesRing(P) \ - or is_PolynomialRing(P) or is_PowerSeriesRing(P): + if isinstance(P, (MPolynomialRing_base, MPowerSeriesRing_generic, LazyPowerSeriesRing, + PolynomialRing_general, PowerSeriesRing_generic)): if set(P.variable_names()).issubset(set(self.variable_names())): if self.has_coerce_map_from(P.base_ring()): return True @@ -881,7 +894,7 @@ def _element_constructor_(self, f, prec=None): def laurent_series_ring(self): """ - Laurent series not yet implemented for multivariate power series rings + Laurent series not yet implemented for multivariate power series rings. TESTS:: @@ -915,7 +928,7 @@ def _poly_ring(self, x=None): def _mpoly_ring(self, x=None): """ - Same as _poly_ring + Same as ``_poly_ring``. TESTS:: @@ -940,7 +953,6 @@ def _bg_ps_ring(self, x=None): t, u over Rational Field sage: R._bg_ps_ring(4).parent() == R False - """ if x is None: return self._bg_power_series_ring @@ -949,7 +961,7 @@ def _bg_ps_ring(self, x=None): def is_sparse(self): """ - Is self sparse? + Check whether ``self`` is sparse. EXAMPLES:: @@ -966,7 +978,7 @@ def is_sparse(self): def is_dense(self): """ - Is self dense? (opposite of sparse) + Is ``self`` dense? (opposite of sparse) EXAMPLES:: @@ -983,7 +995,7 @@ def is_dense(self): def gen(self, n=0): """ - Return the nth generator of self. + Return the `n`-th generator of ``self``. EXAMPLES:: @@ -994,11 +1006,11 @@ def gen(self, n=0): if n < 0 or n >= self._ngens: raise ValueError("Generator not defined.") #return self(self._poly_ring().gens()[int(n)]) - return self.element_class(parent=self,x=self._poly_ring().gens()[int(n)], is_gen=True) + return self.element_class(parent=self, x=self._poly_ring().gens()[int(n)], is_gen=True) def ngens(self): """ - Return number of generators of self. + Return number of generators of ``self``. EXAMPLES:: @@ -1008,6 +1020,18 @@ def ngens(self): """ return self._ngens + def gens(self) -> tuple: + """ + Return the generators of this ring. + + EXAMPLES:: + + sage: M = PowerSeriesRing(ZZ, 3, 'v') + sage: M.gens() + (v0, v1, v2) + """ + return tuple(self.gen(i) for i in range(self._ngens)) + def prec_ideal(self): """ Return the ideal which determines precision; this is the ideal diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 32e16def317..8e1789d5672 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -154,14 +154,17 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.structure.richcmp import richcmp - +from sage.misc.lazy_import import lazy_import from sage.rings.finite_rings.integer_mod_ring import Zmod -from sage.rings.infinity import infinity, is_Infinite +from sage.rings.infinity import infinity, InfinityElement from sage.rings.integer import Integer -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing -from sage.rings.power_series_ring import is_PowerSeriesRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.power_series_ring_element import PowerSeries +from sage.structure.richcmp import richcmp + +lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') +lazy_import('sage.rings.multi_power_series_ring', 'MPowerSeriesRing_generic') +lazy_import('sage.rings.power_series_ring', 'PowerSeriesRing_generic') def is_MPowerSeries(f): @@ -174,8 +177,14 @@ def is_MPowerSeries(f): sage: from sage.rings.multi_power_series_ring_element import is_MPowerSeries sage: M = PowerSeriesRing(ZZ,4,'v') sage: is_PowerSeries(M.random_element(10)) + doctest:warning... + DeprecationWarning: The function is_PowerSeries is deprecated; use 'isinstance(..., PowerSeries)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. True sage: is_MPowerSeries(M.random_element(10)) + doctest:warning... + DeprecationWarning: The function is_MPowerSeries is deprecated; use 'isinstance(..., MPowerSeries)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. True sage: T. = PowerSeriesRing(RR) sage: is_MPowerSeries(1 - v + v^2 +O(v^3)) @@ -183,6 +192,10 @@ def is_MPowerSeries(f): sage: is_PowerSeries(1 - v + v^2 +O(v^3)) True """ + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_MPowerSeries is deprecated; " + "use 'isinstance(..., MPowerSeries)' instead.") return isinstance(f, MPowerSeries) @@ -223,20 +236,22 @@ class MPowerSeries(PowerSeries): INPUT: - - ``parent`` -- A multivariate power series. + - ``parent`` -- a multivariate power series - - ``x`` -- The element (default: 0). This can be another + - ``x`` -- the element (default: 0). This can be another :class:`MPowerSeries` object, or an element of one of the following: - the background univariate power series ring - the foreground polynomial ring - a ring that coerces to one of the above two - - ``prec`` -- (default: ``infinity``) The precision + - ``prec`` -- (default: ``infinity``) the precision - - ``is_gen`` -- (default: ``False``) Is this element one of the generators? + - ``is_gen`` -- boolean (default: ``False``); whether this element is one + of the generators - - ``check`` -- (default: ``False``) Needed by univariate power series class + - ``check`` -- boolean (default: ``False``); needed by univariate power + series class EXAMPLES: @@ -346,7 +361,6 @@ def __init__(self, parent, x=0, prec=infinity, is_gen=False, check=False): sage: b = B(d) # test coercion from univariate power series ring sage: b in B True - """ PowerSeries.__init__(self, parent, prec, is_gen=is_gen) self._PowerSeries__is_gen = is_gen @@ -364,12 +378,11 @@ def __init__(self, parent, x=0, prec=infinity, is_gen=False, check=False): # test whether x coerces to background univariate # power series ring of parent - from sage.rings.multi_power_series_ring import is_MPowerSeriesRing - if is_PowerSeriesRing(xparent) or is_MPowerSeriesRing(xparent): + if isinstance(xparent, (PowerSeriesRing_generic, MPowerSeriesRing_generic, LazyPowerSeriesRing)): # x is either a multivariate or univariate power series # # test whether x coerces directly to designated parent - if is_MPowerSeries(x): + if isinstance(x, MPowerSeries): try: self._bg_value = parent._bg_ps_ring(x._bg_value) except TypeError: @@ -393,7 +406,7 @@ def __init__(self, parent, x=0, prec=infinity, is_gen=False, check=False): self._bg_value = parent._send_to_bg(x).add_bigoh(prec) # test whether x coerces to underlying polynomial ring of parent - elif is_PolynomialRing(xparent): + elif isinstance(xparent, PolynomialRing_general): self._bg_value = parent._send_to_bg(x).add_bigoh(prec) else: @@ -554,7 +567,7 @@ def _subs_formal(self, *x, **kwds): base_map = kwds.get('base_map') if base_map is None: base_map = lambda t: t - for m, c in self.dict().items(): + for m, c in self.monomial_coefficients().items(): y += base_map(c)*prod([x[i]**m[i] for i in range(n) if m[i] != 0]) if self.prec() == infinity: return y @@ -634,7 +647,7 @@ def _latex_(self): def _im_gens_(self, codomain, im_gens, base_map=None): """ - Returns the image of this series under the map that sends the + Return the image of this series under the map that sends the generators to ``im_gens``. This is used internally for computing homomorphisms. @@ -1086,7 +1099,7 @@ def __mod__(self, other): return self.change_ring(Zmod(other)) raise NotImplementedError("Mod on multivariate power series ring elements not defined except modulo an integer.") - def dict(self): + def monomial_coefficients(self): """ Return underlying dictionary with keys the exponents and values the coefficients of this power series. @@ -1103,6 +1116,14 @@ def dict(self): sage: m = 2/3*t0*t1^15*t3^48 - t0^15*t1^21*t2^28*t3^5 sage: m2 = 1/2*t0^12*t1^29*t2^46*t3^6 - 1/4*t0^39*t1^5*t2^23*t3^30 + M.O(100) sage: s = m + m2 + sage: s.monomial_coefficients() + {(1, 15, 0, 48): 2/3, + (12, 29, 46, 6): 1/2, + (15, 21, 28, 5): -1, + (39, 5, 23, 30): -1/4} + + ``dict`` is an alias:: + sage: s.dict() {(1, 15, 0, 48): 2/3, (12, 29, 46, 6): 1/2, @@ -1111,9 +1132,11 @@ def dict(self): """ out_dict = {} for j in self._bg_value.coefficients(): - out_dict.update(j.dict()) + out_dict.update(j.monomial_coefficients()) return out_dict + dict = monomial_coefficients + def polynomial(self): """ Return the underlying polynomial of ``self`` as an element of @@ -1211,7 +1234,7 @@ def coefficients(self): True """ if self.is_sparse(): - return self.dict() + return self.monomial_coefficients() tmp = {} for j in self._bg_value.coefficients(): for m in j.monomials(): @@ -1410,7 +1433,7 @@ def valuation(self): if self._bg_value == 0: return infinity - # at this stage, self is probably a non-zero + # at this stage, self is probably a nonzero # element of the base ring for a in range(len(self._bg_value.list())): if self._bg_value.list()[a] != 0: @@ -1620,7 +1643,7 @@ def integral(self, *args): .. warning:: Coefficient division. If the base ring is not a field (e.g. `ZZ`), or if it has a - non-zero characteristic, (e.g. `ZZ/3ZZ`), integration is not + nonzero characteristic, (e.g. `ZZ/3ZZ`), integration is not always possible while staying with the same base ring. In the first case, Sage will report that it has not been able to coerce some coefficient to the base ring:: @@ -1644,7 +1667,7 @@ def integral(self, *args): sage: f.integral(b) b^2 + O(a, b)^6 - In non-zero characteristic, Sage will report that a zero division + In nonzero characteristic, Sage will report that a zero division occurred :: sage: T. = PowerSeriesRing(Zmod(3), 2) @@ -1714,12 +1737,12 @@ def _integral(self, xx): xxe = xx.exponents()[0] pos = [i for i, c in enumerate(xxe) if c != 0][0] # get the position of the variable res = {mon.eadd(xxe): R(co / (mon[pos]+1)) - for mon, co in self.dict().items()} + for mon, co in self.monomial_coefficients().items()} return P( res ).add_bigoh(self.prec()+1) def ogf(self): """ - Method from univariate power series not yet implemented + Method from univariate power series not yet implemented. TESTS:: @@ -1734,7 +1757,7 @@ def ogf(self): def egf(self): """ - Method from univariate power series not yet implemented + Method from univariate power series not yet implemented. TESTS:: @@ -1749,7 +1772,7 @@ def egf(self): def __pari__(self): """ - Method from univariate power series not yet implemented + Method from univariate power series not yet implemented. TESTS:: @@ -1882,8 +1905,8 @@ def exp(self, prec=infinity): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to OUTPUT: @@ -1956,7 +1979,7 @@ def exp(self, prec=infinity): assert (val >= 1) prec = min(prec, self.prec()) - if is_Infinite(prec): + if isinstance(prec, InfinityElement): prec = R.default_prec() n_inv_factorial = R.base_ring().one() x_pow_n = Rbg.one() @@ -1977,8 +2000,8 @@ def log(self, prec=infinity): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to OUTPUT: @@ -2033,14 +2056,14 @@ def log(self, prec=infinity): sage: a.log(prec=10) Traceback (most recent call last): ... - ValueError: Can only take formal power series for non-zero constant term. + ValueError: Can only take formal power series for nonzero constant term. """ R = self.parent() Rbg = R._bg_power_series_ring c = self.constant_coefficient() if c.is_zero(): - raise ValueError('Can only take formal power series for non-zero constant term.') + raise ValueError('Can only take formal power series for nonzero constant term.') if c.is_one(): log_c = self.base_ring().zero() else: @@ -2053,7 +2076,7 @@ def log(self, prec=infinity): assert (val >= 1) prec = min(prec, self.prec()) - if is_Infinite(prec): + if isinstance(prec, InfinityElement): prec = R.default_prec() x_pow_n = Rbg.one() log_x = Rbg.zero().add_bigoh(prec) @@ -2082,7 +2105,7 @@ def laurent_series(self): raise NotImplementedError("laurent_series not defined for multivariate power series.") -class MO(): +class MO: """ Object representing a zero element with given precision. diff --git a/src/sage/rings/noncommutative_ideals.pyx b/src/sage/rings/noncommutative_ideals.pyx index 62484c9326b..48f19dd4596 100644 --- a/src/sage/rings/noncommutative_ideals.pyx +++ b/src/sage/rings/noncommutative_ideals.pyx @@ -83,7 +83,6 @@ class IdealMonoid_nc(IdealMonoid_c): sage: MS = MatrixSpace(ZZ,2,2) sage: MS.ideal_monoid() Monoid of ideals of Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - """ def __init__(self, R): """ @@ -91,7 +90,7 @@ class IdealMonoid_nc(IdealMonoid_c): INPUT: - - ``R`` -- A ring. + - ``R`` -- a ring TESTS:: @@ -99,7 +98,6 @@ class IdealMonoid_nc(IdealMonoid_c): sage: MS = MatrixSpace(ZZ,2,2) sage: IdealMonoid_nc(MS) Monoid of ideals of Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - """ self._IdealMonoid_c__R = R Parent.__init__(self, base=ZZ, @@ -112,7 +110,7 @@ class IdealMonoid_nc(IdealMonoid_c): INPUT: - - ``x`` -- An ideal, or a list of elements. + - ``x`` -- an ideal or a list of elements TESTS:: @@ -137,7 +135,6 @@ class IdealMonoid_nc(IdealMonoid_c): True sage: IT == loads(dumps(IT)) True - """ side = "twosided" if isinstance(x, Ideal_nc): @@ -191,23 +188,22 @@ class Ideal_nc(Ideal_generic): [1 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - """ - def __init__(self, ring, gens, coerce=True, side="twosided"): + def __init__(self, ring, gens, coerce=True, side='twosided'): """ Initialize ``self``. INPUT: - - ``ring`` -- A ring. + - ``ring`` -- a ring - - ``gens`` -- A list or tuple of elements. + - ``gens`` -- list or tuple of elements - - ``coerce`` (optional bool, default ``True``): First coerce the given - list of elements into the given ring. + - ``coerce`` -- boolean (default: ``True``); first coerce the given + list of elements into the given ring - - ``side`` (option string, default ``"twosided"``): Must be ``"left"``, - ``"right"`` or ``"twosided"``. Determines whether the ideal is a + - ``side`` -- string (default ``'twosided'``); must be ``'left'``, + ``'right'`` or ``'twosided'``. Determines whether the ideal is a left, right or twosided ideal. TESTS:: @@ -234,7 +230,6 @@ class Ideal_nc(Ideal_generic): [1 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - """ if side not in ['left', 'right', 'twosided']: raise ValueError("Ideals are left, right or twosided, but not %s" % side) @@ -255,7 +250,6 @@ class Ideal_nc(Ideal_generic): Right Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis sage: A*[A.1+A.2,A.1^2]*A Twosided Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis - """ return "%s Ideal %s of %s" % (self.__side.capitalize(), self._repr_short(), self.ring()) @@ -341,7 +335,6 @@ class Ideal_nc(Ideal_generic): 'right' sage: IT.side() 'twosided' - """ return self.__side diff --git a/src/sage/rings/number_field/S_unit_solver.py b/src/sage/rings/number_field/S_unit_solver.py index 759d6b8da74..0ffac369720 100644 --- a/src/sage/rings/number_field/S_unit_solver.py +++ b/src/sage/rings/number_field/S_unit_solver.py @@ -88,12 +88,10 @@ def column_Log(SUK, iota, U, prec=106): - ``SUK`` -- a group of `S`-units - ``iota`` -- an element of ``K`` - - ``U`` -- a list of places (finite or infinite) of ``K`` + - ``U`` -- list of places (finite or infinite) of ``K`` - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The log vector as a list of real numbers + OUTPUT: the log vector as a list of real numbers EXAMPLES:: @@ -126,9 +124,7 @@ def c3_func(SUK, prec=106): - ``SUK`` -- a group of `S`-units - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The constant `c_3`, as a real number + OUTPUT: the constant `c_3`, as a real number EXAMPLES:: @@ -147,7 +143,6 @@ def c3_func(SUK, prec=106): REFERENCES: - [AKMRVW]_ :arxiv:`1903.00977` - """ R = RealField(prec) @@ -177,9 +172,7 @@ def c4_func(SUK, v, A, prec=106): - ``A`` -- the set of the product of the coefficients of the ``S``-unit equation with each root of unity of ``K`` - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The constant `c_4`, as a real number + OUTPUT: the constant `c_4`, as a real number EXAMPLES:: @@ -210,15 +203,18 @@ def c4_func(SUK, v, A, prec=106): def beta_k(betas_and_ns): r""" - Return a pair `[\beta_k,|beta_k|_v]`, where `\beta_k` has the smallest nonzero valuation in absolute value of the list ``betas_and_ns``. + Return a pair `[\beta_k,|beta_k|_v]`, where `\beta_k` has the smallest + nonzero valuation in absolute value of the list ``betas_and_ns``. INPUT: - - ``betas_and_ns`` -- a list of pairs ``[beta,val_v(beta)]`` outputted from the function where ``beta`` is an element of ``SUK.fundamental_units()`` + - ``betas_and_ns`` -- list of pairs ``[beta,val_v(beta)]`` outputted from + the function where ``beta`` is an element of ``SUK.fundamental_units()`` OUTPUT: - The pair ``[beta_k,v(beta_k)]``, where ``beta_k`` is an element of ``K`` and ``val_v(beta_k)`` is a integer + The pair ``[beta_k,v(beta_k)]``, where ``beta_k`` is an element of ``K`` + and ``val_v(beta_k)`` is a integer. EXAMPLES:: @@ -255,9 +251,7 @@ def mus(SUK, v): - ``SUK`` -- a group of `S`-units - ``v`` -- a finite place of ``K`` - OUTPUT: - - A list ``[mus]`` where each ``mu`` is an element of ``K`` + OUTPUT: list ``[mus]`` where each ``mu`` is an element of ``K`` EXAMPLES:: @@ -273,7 +267,6 @@ def mus(SUK, v): REFERENCES: - [AKMRVW]_ - """ betas = SUK.fundamental_units() beta_and_ns = [[beta,beta.valuation(v)] for beta in betas] @@ -295,9 +288,7 @@ def possible_mu0s(SUK, v): - ``SUK`` -- a group of `S`-units - ``v`` -- a finite place of ``K`` - OUTPUT: - - A list ``[mu0s]`` where each ``mu0`` is an element of ``K`` + OUTPUT: list ``[mu0s]`` where each ``mu0`` is an element of ``K`` EXAMPLES:: @@ -321,7 +312,6 @@ def possible_mu0s(SUK, v): - [AKMRVW]_ - [Sma1995]_ pp. 824-825, but we modify the definition of ``sigma`` (``sigma_tilde``) to make it easier to code - """ beta_and_ns = [[beta,beta.valuation(v)] for beta in SUK.fundamental_units()] betak, nk = beta_k(beta_and_ns) @@ -476,7 +466,7 @@ def Yu_modified_height(mu, n, v, prec=106): INPUT: - ``mu`` -- an element of a field K - - ``n`` -- number of mu_j to be considered in Yu's Theorem. + - ``n`` -- number of mu_j to be considered in Yu's Theorem - ``v`` -- a place of K - ``prec`` -- the precision of the real field @@ -529,12 +519,11 @@ def Omega_prime(dK, v, mu_list, prec=106): - ``dK`` -- the degree of a number field `K` - ``v`` -- a finite place of `K` - - ``mu_list`` -- a list of nonzero elements of `K`. It is assumed that the sublist ``mu_list[1:]`` is multiplicatively independent. + - ``mu_list`` -- list of nonzero elements of `K`. It is assumed that the + sublist ``mu_list[1:]`` is multiplicatively independent - ``prec`` -- the precision of the real field - OUTPUT: - - The constant `\Omega'`. + OUTPUT: the constant `\Omega'` EXAMPLES:: @@ -576,9 +565,7 @@ def Yu_C1_star(n, v, prec=106): - ``v`` -- a finite place of `K` (a fractional ideal) - ``prec`` -- the precision of the real field - OUTPUT: - - The constant `C_1^*` as a real number. + OUTPUT: the constant `C_1^*` as a real number EXAMPLES:: @@ -638,9 +625,7 @@ def Yu_bound(SUK, v, prec=106): - ``v`` -- a finite place of `K` (a fractional ideal) - ``prec`` -- the precision of the real field - OUTPUT: - - The constant `c_8` as a real number. + OUTPUT: the constant `c_8` as a real number EXAMPLES:: @@ -721,9 +706,7 @@ def K0_func(SUK, A, prec=106): - ``A`` -- the set of the products of the coefficients of the `S`-unit equation with each root of unity of `K` - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The constant `K_0`, a real number. + OUTPUT: the constant `K_0`, a real number EXAMPLES:: @@ -772,9 +755,7 @@ def c11_func(SUK, v, A, prec=106): - ``A`` -- the set of the product of the coefficients of the `S`-unit equation with each root of unity of `K` - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The constant `c_{11}`, a real number + OUTPUT: the constant `c_{11}`, a real number EXAMPLES:: @@ -813,9 +794,7 @@ def c13_func(SUK, v, prec=106): - ``v`` -- an infinite place of ``K`` (element of ``SUK.number_field().places(prec)``) - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The constant `c_{13}`, as a real number + OUTPUT: the constant `c_{13}`, as a real number EXAMPLES:: @@ -863,12 +842,11 @@ def K1_func(SUK, v, A, prec=106): - ``SUK`` -- a group of `S`-units - ``v`` -- an infinite place of `K` (element of ``SUK.number_field().places(prec)``) - - ``A`` -- a list of all products of each potential `a`, `b` in the `S`-unit equation `ax + by + 1 = 0` with each root of unity of `K` + - ``A`` -- list of all products of each potential `a`, `b` in the `S`-unit + equation `ax + by + 1 = 0` with each root of unity of `K` - ``prec`` -- the precision of the real field (default: 106) - OUTPUT: - - The constant `K_1`, a real number + OUTPUT: the constant `K_1`, a real number EXAMPLES:: @@ -889,7 +867,6 @@ def K1_func(SUK, v, A, prec=106): REFERENCES: - [Sma1995]_ p. 825 - """ R = RealField(prec) @@ -933,9 +910,7 @@ def minimal_vector(A, y, prec=106): - ``y`` -- a row (1 by `n`) vector with integer coordinates - ``prec`` -- precision of real field (default: 106) - OUTPUT: - - A lower bound for the square of + OUTPUT: a lower bound for the square of .. MATH:: @@ -995,13 +970,11 @@ def reduction_step_complex_case(place, B0, list_of_gens, torsion_gen, c13): - ``place`` -- (ring morphism) an infinite place of a number field `K` - ``B0`` -- the initial bound - - ``list_of_gens`` -- a set of generators of the free part of the group + - ``list_of_gens`` -- set of generators of the free part of the group - ``torsion_gen`` -- an element of the torsion part of the group - ``c13`` -- a positive real number - OUTPUT: - - A tuple consisting of: + OUTPUT: a tuple consisting of: 1. a new upper bound, an integer 2. a boolean value, ``True`` if we have to increase precision, otherwise ``False`` @@ -1068,7 +1041,7 @@ def reduction_step_complex_case(place, B0, list_of_gens, torsion_gen, c13): A = A.transpose() - # Note that l is the lower bound on the square of the magnitude of the shortest non-zero vector in the lattice generated by A + # Note that l is the lower bound on the square of the magnitude of the shortest nonzero vector in the lattice generated by A l = minimal_vector(A, zero_vector(ZZ,n+1)) # Checking hypotheses of Lemma 5.3 in our paper: @@ -1107,7 +1080,7 @@ def reduction_step_complex_case(place, B0, list_of_gens, torsion_gen, c13): # We apply Lemma 5.3 from [AKMRVW] A = A.transpose() l = minimal_vector(A, zero_vector(ZZ,n+1)) - # Note that l is the a lower bound on the square of the magnitude of the shortest non-zero vector in the lattice generated by A + # Note that l is the a lower bound on the square of the magnitude of the shortest nonzero vector in the lattice generated by A # Checking hypothesis of lemma 5.3 in [AKMRVW] if l <= T**2 + S: C *= 2 @@ -1154,7 +1127,7 @@ def reduction_step_complex_case(place, B0, list_of_gens, torsion_gen, c13): # We apply Lemma 5.2 from [AKMRVW] A = A.transpose() l = minimal_vector(A, zero_vector(ZZ,n+1)) - # Note that l is the a lower bound on the square of the magnitude of the shortest non-zero vector in the lattice generated by A + # Note that l is the a lower bound on the square of the magnitude of the shortest nonzero vector in the lattice generated by A # Checking hypothesis of lemma 5.2 in [AKMRVW] if l <= T**2 + S: C *= 2 @@ -1178,12 +1151,11 @@ def cx_LLL_bound(SUK, A, prec=106): INPUT: - ``SUK`` -- a group of `S`-units - - ``A`` -- a list of all products of each potential `a`, `b` in the `S`-unit equation `ax + by + 1 = 0` with each root of unity of `K` + - ``A`` -- list of all products of each potential `a`, `b` in the `S`-unit + equation `ax + by + 1 = 0` with each root of unity of `K` - ``prec`` -- precision of real field (default: 106) - OUTPUT: - - A bound for the exponents at the infinite place, as a real number + OUTPUT: a bound for the exponents at the infinite place, as a real number EXAMPLES:: @@ -1234,15 +1206,18 @@ def log_p(a, prime, prec): - ``a`` -- an element of a number field `K` - ``prime`` -- a prime ideal of the number field `K` - - ``prec`` -- a positive integer + - ``prec`` -- positive integer OUTPUT: - An element of `K` which is congruent to the ``prime``-adic logarithm of `a` with respect to ``prime`` modulo ``p^prec``, where `p` is the rational prime below ``prime`` + An element of `K` which is congruent to the ``prime``-adic logarithm of `a` + with respect to ``prime`` modulo ``p^prec``, where `p` is the rational + prime below ``prime``. .. NOTE:: - Here we take into account the other primes in `K` above `p` in order to get coefficients with small values + Here we take into account the other primes in `K` above `p` in order to + get coefficients with small values. EXAMPLES:: @@ -1299,15 +1274,16 @@ def log_p_series_part(a, prime, prec): - ``a`` -- an element of a number field `K` - ``prime`` -- a prime ideal of the number field `K` - - ``prec`` -- a positive integer + - ``prec`` -- positive integer OUTPUT: - The ``prime``-adic logarithm of `a` and accuracy ``p^prec``, where `p` is the rational prime below ``prime`` + The ``prime``-adic logarithm of `a` and accuracy ``p^prec``, where `p` is + the rational prime below ``prime``. ALGORITHM: - The algorithm is based on the algorithm on page 30 of [Sma1998]_ + The algorithm is based on the algorithm on page 30 of [Sma1998]_. EXAMPLES:: @@ -1394,9 +1370,7 @@ def defining_polynomial_for_Kp(prime, prec=106): - ``prime`` -- a prime ideal of a number field `K` - ``prec`` -- a positive natural number (default: 106) - OUTPUT: - - A polynomial with integer coefficients that is equivalent ``mod p^prec`` to a defining polynomial for the completion of `K` associated to the specified prime. + OUTPUT: a polynomial with integer coefficients that is equivalent ``mod p^prec`` to a defining polynomial for the completion of `K` associated to the specified prime .. NOTE:: @@ -1504,15 +1478,14 @@ def p_adic_LLL_bound_one_prime(prime, B0, M, M_logp, m0, c3, prec=106): - ``prime`` -- a prime ideal of a number field `K` - ``B0`` -- the initial bound - - ``M`` -- a list of elements of `K`, the `\mu_i`'s from Lemma IX.3 of [Sma1998]_ - - ``M_logp`` -- the p-adic logarithm of elements in `M` + - ``M`` -- list of elements of `K`, the `\mu_i`'s from Lemma IX.3 of [Sma1998]_ + - ``M_logp`` -- the `p`-adic logarithm of elements in `M` - ``m0`` -- an element of `K`, this is `\mu_0` from Lemma IX.3 of [Sma1998]_ - ``c3`` -- a positive real constant - - ``prec`` -- the precision of the calculations (default: 106), i.e., values are known to ``O(p^prec)`` - - OUTPUT: + - ``prec`` -- the precision of the calculations (default: 106), i.e., + values are known to ``O(p^prec)`` - A pair consisting of: + OUTPUT: a pair consisting of: 1. a new upper bound, an integer 2. a boolean value, ``True`` if we have to increase precision, otherwise ``False`` @@ -1562,7 +1535,7 @@ def p_adic_LLL_bound_one_prime(prime, B0, M, M_logp, m0, c3, prec=106): False """ if any(g.valuation(prime) != 0 for g in M+[m0]): - raise ValueError('There is an element with non zero valuation') + raise ValueError('There is an element with nonzero valuation') K = prime.ring() w = K.number_of_roots_of_unity() @@ -1651,13 +1624,15 @@ def p_adic_LLL_bound_one_prime(prime, B0, M, M_logp, m0, c3, prec=106): def p_adic_LLL_bound(SUK, A, prec=106): r""" - Return the maximum of all of the `K_0`'s as they are LLL-optimized for each finite place `v`. + Return the maximum of all of the `K_0`'s as they are LLL-optimized for each + finite place `v`. INPUT: - ``SUK`` -- a group of `S`-units - - ``A`` -- a list of all products of each potential `a`, `b` in the `S`-unit equation `ax + by + 1 = 0` with each root of unity of `K` - - ``prec`` -- precision for p-adic LLL calculations (default: 106) + - ``A`` -- list of all products of each potential `a`, `b` in the `S`-unit + equation `ax + by + 1 = 0` with each root of unity of `K` + - ``prec`` -- precision for `p`-adic LLL calculations (default: 106) OUTPUT: @@ -1702,8 +1677,7 @@ def p_adic_LLL_bound(SUK, A, prec=106): Log_p_Mus = [embedding_to_Kp(a, v, local_prec) for a in Log_p_Mus] m0_Kv_new,increase_precision = p_adic_LLL_bound_one_prime(v, m0_Kv_old, Mus, Log_p_Mus, m0, c3_func(SUK, local_prec), local_prec) - if m0_Kv_old > val: - val = m0_Kv_old + val = max(m0_Kv_old, val) LLL_K0_by_finite_place.append(val) return max(LLL_K0_by_finite_place) @@ -1711,16 +1685,15 @@ def p_adic_LLL_bound(SUK, A, prec=106): def split_primes_large_lcm(SUK, bound): r""" - Return a list `L` of rational primes `q` which split completely in `K` and which have desirable properties (see NOTE). + Return a list `L` of rational primes `q` which split completely in `K` and + which have desirable properties (see NOTE). INPUT: - - ``SUK`` -- the `S`-unit group of an absolute number field `K`. - - ``bound`` -- a positive integer + - ``SUK`` -- the `S`-unit group of an absolute number field `K` + - ``bound`` -- positive integer - OUTPUT: - - A list `L` of rational primes `q`, with the following properties: + OUTPUT: list `L` of rational primes `q`, with the following properties: - each prime `q` in `L` splits completely in `K` - if `Q` is a prime in `S` and `q` is the rational @@ -1757,7 +1730,6 @@ def split_primes_large_lcm(SUK, bound): Traceback (most recent call last): ... ValueError: Not enough split primes found. Increase bound. - """ K = SUK.number_field() @@ -1786,11 +1758,10 @@ def sieve_ordering(SUK, q): INPUT: - ``SUK`` -- the `S`-unit group of a number field `K` - - ``q`` -- a rational prime number which splits completely in `K` + - ``q`` -- a rational prime number which splits completely in `K` - OUTPUT: - - A list of tuples, ``[ideals_over_q, residue_fields, rho_images, product_rho_orders]``, where + OUTPUT: list of tuples; + ``[ideals_over_q, residue_fields, rho_images, product_rho_orders]``, where: 1. ``ideals_over_q`` is a list of the `d = [K:\QQ]` ideals in `K` over `q` 2. ``residue_fields[i]`` is the residue field of ``ideals_over_q[i]`` @@ -1855,11 +1826,10 @@ def clean_rfv_dict(rfv_dictionary): INPUT: - - ``rfv_dictionary`` -- a dictionary whose keys are exponent vectors and whose values are residue field vectors - - OUTPUT: + - ``rfv_dictionary`` -- dictionary whose keys are exponent vectors and + whose values are residue field vectors - ``None``. But it removes some keys from the input dictionary. + OUTPUT: none, but it removes some keys from the input dictionary .. NOTE:: @@ -1891,14 +1861,17 @@ def clean_rfv_dict(rfv_dictionary): def construct_rfv_to_ev(rfv_dictionary, q, d, verbose=False): r""" - Return a reverse lookup dictionary, to find the exponent vectors associated to a given residue field vector. + Return a reverse lookup dictionary, to find the exponent vectors associated + to a given residue field vector. INPUT: - - ``rfv_dictionary`` -- a dictionary whose keys are exponent vectors and whose values are the associated residue field vectors + - ``rfv_dictionary`` -- dictionary whose keys are exponent vectors and + whose values are the associated residue field vectors - ``q`` -- a prime (assumed to split completely in the relevant number field) - ``d`` -- the number of primes in `K` above the rational prime `q` - - ``verbose`` -- a boolean flag to indicate more detailed output is desired (default: ``False``) + - ``verbose`` -- boolean (default: ``False``); flag to indicate more + detailed output is desired OUTPUT: @@ -2026,16 +1999,17 @@ def construct_rfv_to_ev(rfv_dictionary, q, d, verbose=False): def construct_comp_exp_vec(rfv_to_ev_dict, q): r""" - Constructs a dictionary associating complement vectors to residue field vectors. + Construct a dictionary associating complement vectors to residue field vectors. INPUT: - - ``rfv_to_ev_dict`` -- a dictionary whose keys are residue field vectors and whose values are lists of exponent vectors with the associated residue field vector. + - ``rfv_to_ev_dict`` -- dictionary whose keys are residue field vectors and + whose values are lists of exponent vectors with the associated residue + field vector - ``q`` -- the characteristic of the residue field - OUTPUT: - - A dictionary whose typical key is an exponent vector ``a``, and whose associated value is a list of complementary exponent vectors to ``a``. + OUTPUT: a dictionary whose typical key is an exponent vector ``a``, and + whose associated value is a list of complementary exponent vectors to ``a`` EXAMPLES: @@ -2102,13 +2076,12 @@ def drop_vector(ev, p, q, complement_ev_dict): - ``ev`` -- an exponent vector modulo `p-1` - ``p`` -- the prime such that ``ev`` is an exponent vector modulo `p-1` - ``q`` -- a prime, distinct from `p`, that is a key in the ``complement_ev_dict`` - - ``complement_ev_dict`` -- a dictionary of dictionaries, whose keys are primes. + - ``complement_ev_dict`` -- dictionary of dictionaries, whose keys are primes ``complement_ev_dict[q]`` is a dictionary whose keys are exponent vectors modulo `q-1` and whose values are lists of complementary exponent vectors modulo `q-1` - OUTPUT: - - Returns ``True`` if ``ev`` may be dropped from the complement exponent vector dictionary, and ``False`` if not. + OUTPUT: ``True`` if ``ev`` may be dropped from the complement exponent + vector dictionary, and ``False`` if not .. NOTE:: @@ -2165,15 +2138,17 @@ def construct_complement_dictionaries(split_primes_list, SUK, verbose=False): INPUT: - - ``split_primes_list`` -- a list of rational primes which split completely in the number field `K` + - ``split_primes_list`` -- list of rational primes which split completely + in the number field `K` - ``SUK`` -- the `S`-unit group for a number field `K` - - ``verbose`` -- a boolean to provide additional feedback (default: ``False``) + - ``verbose`` -- boolean to provide additional feedback (default: ``False``) OUTPUT: - A dictionary of dictionaries. The keys coincide with the primes in ``split_primes_list`` - For each `q`, ``comp_exp_vec[q]`` is a dictionary whose keys are exponent vectors modulo `q-1`, - and whose values are lists of exponent vectors modulo `q-1` + A dictionary of dictionaries. The keys coincide with the primes in + ``split_primes_list``. For each `q`, ``comp_exp_vec[q]`` is a dictionary + whose keys are exponent vectors modulo `q-1`, and whose values are lists of + exponent vectors modulo `q-1`. If `w` is an exponent vector in ``comp_exp_vec[q][v]``, then the residue field vectors modulo `q` for `v` and `w` sum to ``[1,1,...,1]`` @@ -2385,9 +2360,7 @@ def compatible_vectors_check(a0, a1, g, l): - ``g`` -- the gcd of ``m0`` and ``m1`` - ``l`` -- the length of ``a0`` and of ``a1`` - OUTPUT: - - ``True`` if there is an integer exponent vector a satisfying + OUTPUT: ``True`` if there is an integer exponent vector a satisfying .. MATH:: @@ -2425,18 +2398,17 @@ def compatible_vectors(a, m0, m1, g): INPUT: - - ``a`` -- an exponent vector for the modulus ``m0`` - - ``m0`` -- a positive integer (specifying the modulus for ``a``) - - ``m1`` -- a positive integer (specifying the alternate modulus) + - ``a`` -- an exponent vector for the modulus ``m0`` + - ``m0`` -- positive integer (specifying the modulus for ``a``) + - ``m1`` -- positive integer (specifying the alternate modulus) - ``g`` -- the gcd of ``m0`` and ``m1`` - OUTPUT: - - A list of exponent vectors modulo ``m1`` which are compatible with ``a``. + OUTPUT: list of exponent vectors modulo ``m1`` which are compatible with ``a`` .. NOTE:: - - Exponent vectors must agree exactly in the 0th position in order to be compatible. + Exponent vectors must agree exactly in the 0th position in order to be + compatible. EXAMPLES:: @@ -2466,16 +2438,16 @@ def compatible_vectors(a, m0, m1, g): def compatible_systems(split_prime_list, complement_exp_vec_dict): r""" - Given dictionaries of complement exponent vectors for various primes that split in `K`, compute all possible compatible systems. + Given dictionaries of complement exponent vectors for various primes that + split in `K`, compute all possible compatible systems. INPUT: - - ``split_prime_list`` -- a list of rational primes that split completely in `K` - - ``complement_exp_vec_dict`` -- a dictionary of dictionaries. The keys are primes from ``split_prime_list``. - - OUTPUT: + - ``split_prime_list`` -- list of rational primes that split completely in `K` + - ``complement_exp_vec_dict`` -- dictionary of dictionaries; the keys are + primes from ``split_prime_list`` - A list of compatible systems of exponent vectors. + OUTPUT: list of compatible systems of exponent vectors .. NOTE:: @@ -2532,17 +2504,17 @@ def compatible_systems(split_prime_list, complement_exp_vec_dict): def compatible_system_lift(compatible_system, split_primes_list): r""" - Given a compatible system of exponent vectors and complementary exponent vectors, return a lift to the integers. + Given a compatible system of exponent vectors and complementary exponent + vectors, return a lift to the integers. INPUT: - - ``compatible_system`` -- a list of pairs ``[ [v0, w0], [v1, w1], .., [vk, wk] ]`` - where [vi, wi] is a pair of complementary exponent vectors modulo ``qi - 1``, and all pairs are compatible. - - ``split_primes_list`` -- a list of primes ``[ q0, q1, .., qk ]`` + - ``compatible_system`` -- list of pairs ``[ [v0, w0], [v1, w1], .., [vk, wk] ]`` + where [vi, wi] is a pair of complementary exponent vectors modulo ``qi - 1``, + and all pairs are compatible + - ``split_primes_list`` -- list of primes ``[ q0, q1, .., qk ]`` - OUTPUT: - - A pair of vectors ``[v, w]`` satisfying: + OUTPUT: a pair of vectors ``[v, w]`` satisfying: 1. ``v[0] == vi[0]`` for all ``i`` 2. ``w[0] == wi[0]`` for all ``i`` @@ -2593,15 +2565,17 @@ def compatible_system_lift(compatible_system, split_primes_list): def solutions_from_systems(SUK, bound, cs_list, split_primes_list): r""" - Lift compatible systems to the integers and return the `S`-unit equation solutions that the lifts yield. + Lift compatible systems to the integers and return the `S`-unit equation + solutions that the lifts yield. INPUT: - ``SUK`` -- the group of `S`-units where we search for solutions - ``bound`` -- a bound for the entries of all entries of all lifts - - ``cs_list`` -- a list of compatible systems of exponent vectors modulo `q-1` for - various primes `q` - - ``split_primes_list`` -- a list of primes giving the moduli of the exponent vectors in ``cs_list`` + - ``cs_list`` -- list of compatible systems of exponent vectors modulo + `q-1` for various primes `q` + - ``split_primes_list`` -- list of primes giving the moduli of the exponent + vectors in ``cs_list`` OUTPUT: @@ -2654,11 +2628,9 @@ def clean_sfs(sfs_list): INPUT: - - ``sfs_list`` -- a list of solutions to the `S`-unit equation - - OUTPUT: + - ``sfs_list`` -- list of solutions to the `S`-unit equation - A list of solutions to the `S`-unit equation + OUTPUT: list of solutions to the `S`-unit equation .. NOTE:: @@ -2686,17 +2658,23 @@ def clean_sfs(sfs_list): def sieve_below_bound(K, S, bound=10, bump=10, split_primes_list=[], verbose=False): r""" - Return all solutions to the `S`-unit equation `x + y = 1` over `K` with exponents below the given bound. + Return all solutions to the `S`-unit equation `x + y = 1` over `K` with + exponents below the given bound. INPUT: - ``K`` -- a number field (an absolute extension of the rationals) - - ``S`` -- a list of finite primes of `K` - - ``bound`` -- a positive integer upper bound for exponents, solutions with exponents having absolute value below this bound will be found (default: 10) - - ``bump`` -- a positive integer by which the minimum LCM will be increased if not enough split primes are found in sieving step (default: 10) - - ``split_primes_list`` -- a list of rational primes that split completely in the extension `K/\QQ`, used for sieving. - For complete list of solutions should have lcm of `\{(p_i-1)\} for primes `p_i` greater than bound (default: ``[]``) - - ``verbose`` -- an optional parameter allowing the user to print information during the sieving process (default: ``False``) + - ``S`` -- list of finite primes of `K` + - ``bound`` -- positive integer upper bound for exponents, solutions with + exponents having absolute value below this bound will be found (default: 10) + - ``bump`` -- positive integer by which the minimum LCM will be increased + if not enough split primes are found in sieving step (default: 10) + - ``split_primes_list`` -- list of rational primes that split completely in + the extension `K/\QQ`, used for sieving. For complete list of solutions + should have lcm of `\{(p_i-1)\} for primes `p_i` greater than bound + (default: ``[]``). + - ``verbose`` -- an optional parameter allowing the user to print + information during the sieving process (default: ``False``) OUTPUT: @@ -2753,11 +2731,15 @@ def solve_S_unit_equation(K, S, prec=106, include_exponents=True, include_bound= INPUT: - ``K`` -- a number field (an absolute extension of the rationals) - - ``S`` -- a list of finite primes of `K` - - ``prec`` -- precision used for computations in real, complex, and p-adic fields (default: 106) - - ``include_exponents`` -- whether to include the exponent vectors in the returned value (default: ``True``). - - ``include_bound`` -- whether to return the final computed bound (default: ``False``) - - ``verbose`` -- whether to print information during the sieving step (default: ``False``) + - ``S`` -- list of finite primes of `K` + - ``prec`` -- precision used for computations in real, complex, and `p`-adic + fields (default: 106) + - ``include_exponents`` -- whether to include the exponent vectors in the + returned value (default: ``True``) + - ``include_bound`` -- whether to return the final computed bound + (default: ``False``) + - ``verbose`` -- whether to print information during the sieving step + (default: ``False``) OUTPUT: diff --git a/src/sage/rings/number_field/bdd_height.py b/src/sage/rings/number_field/bdd_height.py index 7419361579f..45f08aa4711 100644 --- a/src/sage/rings/number_field/bdd_height.py +++ b/src/sage/rings/number_field/bdd_height.py @@ -50,13 +50,11 @@ def bdd_norm_pr_gens_iq(K, norm_list): INPUT: - - `K` -- an imaginary quadratic number field + - ``K`` -- an imaginary quadratic number field - - ``norm_list`` -- a list of positive integers + - ``norm_list`` -- list of positive integers - OUTPUT: - - - a dictionary of number field elements, keyed by norm + OUTPUT: dictionary of number field elements, keyed by norm EXAMPLES: @@ -114,13 +112,11 @@ def bdd_height_iq(K, height_bound): INPUT: - - `K` -- an imaginary quadratic number field + - ``K`` -- an imaginary quadratic number field - ``height_bound`` -- a real number - OUTPUT: - - - an iterator of number field elements + OUTPUT: an iterator of number field elements EXAMPLES:: @@ -219,13 +215,11 @@ def bdd_norm_pr_ideal_gens(K, norm_list): INPUT: - - `K` -- a number field - - - ``norm_list`` -- a list of positive integers + - ``K`` -- a number field - OUTPUT: + - ``norm_list`` -- list of positive integers - - a dictionary of number field elements, keyed by norm + OUTPUT: dictionary of number field elements, keyed by norm EXAMPLES: @@ -253,7 +247,6 @@ def bdd_norm_pr_ideal_gens(K, norm_list): sage: key = ZZ(28) sage: b[key] [157*g^4 - 139*g^3 - 369*g^2 + 848*g + 158, g^4 + g^3 - g - 7] - """ negative_norm_units = K.elements_of_norm(-1) gens = {} @@ -285,9 +278,7 @@ def integer_points_in_polytope(matrix, interval_radius): - ``interval_radius`` -- a real number - OUTPUT: - - - a list of tuples of integers + OUTPUT: list of tuples of integers EXAMPLES: @@ -370,9 +361,7 @@ def bdd_height(K, height_bound, tolerance=1e-2, precision=53): - ``precision`` -- (default: 53) positive integer - OUTPUT: - - an iterator of number field elements + OUTPUT: an iterator of number field elements EXAMPLES: diff --git a/src/sage/rings/number_field/class_group.py b/src/sage/rings/number_field/class_group.py index f514bd49b26..34a48931f8e 100644 --- a/src/sage/rings/number_field/class_group.py +++ b/src/sage/rings/number_field/class_group.py @@ -261,7 +261,8 @@ def representative_prime(self, norm_bound=1000): INPUT: - - ``norm_bound`` -- (positive integer) upper bound on the norm of primes tested. + - ``norm_bound`` -- (positive integer) upper bound on the norm of + primes tested EXAMPLES:: @@ -510,9 +511,7 @@ def gens_ideals(self): This is an alias for :meth:`gens_values`. - OUTPUT: - - A tuple of ideals, one for each abstract Abelian group generator. + OUTPUT: a tuple of ideals, one for each abstract Abelian group generator EXAMPLES:: diff --git a/src/sage/rings/number_field/galois_group.py b/src/sage/rings/number_field/galois_group.py index 364abc0f706..c974c3df6ff 100644 --- a/src/sage/rings/number_field/galois_group.py +++ b/src/sage/rings/number_field/galois_group.py @@ -277,7 +277,7 @@ def __init__(self, number_field, algorithm='pari', names=None, gc_numbering=None You can specify the variable name for the Galois closure:: sage: x = polygen(ZZ, 'x') - sage: G = NumberField(x^3 - 2, 'b').galois_group(names="c"); G + sage: G = NumberField(x^3 - 2, 'b').galois_group(names='c'); G Galois group 3T2 (S3) with order 6 of x^3 - 2 sage: G._galois_closure Number Field in c with defining polynomial x^6 + 108 @@ -324,7 +324,7 @@ def _pol_galgp(self, algorithm=None): sage: G = K.galois_group() sage: G._pol_galgp() PARI group [6, -1, 2, "S3"] of degree 3 - sage: G._pol_galgp(algorithm="gap") # optional - gap_packages + sage: G._pol_galgp(algorithm='gap') # optional - gap_packages Transitive group number 2 of degree 3 """ algorithm = self._get_algorithm(algorithm) @@ -342,7 +342,7 @@ def group(self): sage: R. = ZZ[] sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^3 + 2*x + 2) - sage: G = K.galois_group(type="pari") + sage: G = K.galois_group(type='pari') ...DeprecationWarning: the different Galois types have been merged into one class See https://github.com/sagemath/sage/issues/28782 for details. sage: G.group() @@ -357,7 +357,7 @@ def group(self): @cached_method(key=_alg_key) def order(self, algorithm=None, recompute=False): """ - Return the order of this Galois group + Return the order of this Galois group. EXAMPLES:: @@ -423,7 +423,7 @@ def transitive_number(self, algorithm=None, recompute=False): 2 sage: x = polygen(ZZ, 'x') sage: L. = NumberField(x^13 + 2*x + 2) - sage: H = L.galois_group(algorithm="gap") + sage: H = L.galois_group(algorithm='gap') sage: H.transitive_number() # optional - gap_packages 9 """ @@ -484,7 +484,7 @@ def signature(self): @lazy_attribute def _gcdata(self): """ - Return the Galois closure, together with the embedding of the top field into it + Return the Galois closure, together with the embedding of the top field into it. EXAMPLES:: @@ -573,9 +573,8 @@ def _elts(self): """ if self._gc_numbering: # PARI computes all the elements of self anyway, so we might as well store them - return sorted([self(x, check=False) for x in self._pari_data[5]]) - else: - return sorted(list(self.iteration())) + return sorted(self(x, check=False) for x in self._pari_data[5]) + return sorted(self.iteration()) @lazy_attribute def _gens(self): @@ -693,7 +692,7 @@ def is_galois(self): def _repr_(self): r""" - String representation of this Galois group + String representation of this Galois group. EXAMPLES:: @@ -1026,26 +1025,30 @@ def artin_symbol(self, P): raise ValueError("%s is ramified" % P) return t[0] + class GaloisGroup_subgroup(GaloisSubgroup_perm): r""" - A subgroup of a Galois group, as returned by functions such as ``decomposition_group``. + A subgroup of a Galois group, as returned by functions such as + ``decomposition_group``. INPUT: - ``ambient`` -- the ambient Galois group - - ``gens`` -- a list of generators for the group + - ``gens`` -- list of generators for the group - ``gap_group`` -- a gap or libgap permutation group, or a string defining one (default: ``None``) - - ``domain`` -- a set on which this permutation group acts; extracted from ``ambient`` if not specified + - ``domain`` -- set on which this permutation group acts; extracted from + ``ambient`` if not specified - ``category`` -- the category for this object - ``canonicalize`` -- if ``True``, sorts and removes duplicates - - ``check`` -- whether to check that generators actually lie in the ambient group + - ``check`` -- whether to check that generators actually lie in the + ambient group EXAMPLES:: @@ -1106,7 +1109,7 @@ def fixed_field(self, name=None, polred=None, threshold=None): INPUT: - - ``name`` -- a variable name for the new field. + - ``name`` -- a variable name for the new field - ``polred`` -- whether to optimize the generator of the newly created field for a simpler polynomial, using PARI's :pari:`polredbest`. @@ -1186,6 +1189,7 @@ def fixed_field(self, name=None, polred=None, threshold=None): name = G._field.variable_name() + '0' return L.subfield(x, name=name) + class GaloisGroupElement(PermutationGroupElement): r""" An element of a Galois group. This is stored as a permutation, but may also @@ -1254,8 +1258,8 @@ def as_hom(self): def __call__(self, x): r""" - Return the action of self on an element x in the number field of self - (or its Galois closure). + Return the action of ``self`` on an element x in the number field of + ``self`` (or its Galois closure). EXAMPLES:: diff --git a/src/sage/rings/number_field/homset.py b/src/sage/rings/number_field/homset.py index 4e4a12a9c6f..62ca214754d 100644 --- a/src/sage/rings/number_field/homset.py +++ b/src/sage/rings/number_field/homset.py @@ -240,7 +240,7 @@ def list(self): def __getitem__(self, n): r""" - Return the ``n``th element of ``self.list()``. + Return the `n`-th element of ``self.list()``. EXAMPLES:: diff --git a/src/sage/rings/number_field/maps.py b/src/sage/rings/number_field/maps.py index b14c4ca48f3..8d8eb1b69ef 100644 --- a/src/sage/rings/number_field/maps.py +++ b/src/sage/rings/number_field/maps.py @@ -52,6 +52,7 @@ IdentityMap = IdentityMorphism + class NumberFieldIsomorphism(Map): r""" A base class for various isomorphisms between number fields and @@ -101,6 +102,7 @@ def is_surjective(self): """ return True + class MapVectorSpaceToNumberField(NumberFieldIsomorphism): r""" The map to an absolute number field from its underlying `\QQ`-vector space. @@ -191,6 +193,7 @@ def _call_(self, v): f = K.polynomial_ring()(v.list()) return K._element_class(K, f) + class MapNumberFieldToVectorSpace(Map): r""" A class for the isomorphism from an absolute number field to its underlying @@ -249,6 +252,7 @@ def _call_(self, x): v = v + [QQ.zero()] * k return self.codomain()(v) + class MapRelativeVectorSpaceToRelativeNumberField(NumberFieldIsomorphism): r""" EXAMPLES:: @@ -314,6 +318,7 @@ def _call_(self, v): g = K._pari_rnfeq()._eltreltoabs(h) return K._element_class(K, g) + class MapRelativeNumberFieldToRelativeVectorSpace(NumberFieldIsomorphism): r""" EXAMPLES:: @@ -456,6 +461,7 @@ def _call_(self, x): y = x._copy_for_parent(self.codomain()) return y + class MapRelativeToAbsoluteNumberField(NumberFieldIsomorphism): r""" EXAMPLES:: @@ -533,6 +539,7 @@ def _call_(self, x): f = x.polynomial() return A._element_class(A, f) + class MapAbsoluteToRelativeNumberField(NumberFieldIsomorphism): r""" See :class:`~MapRelativeToAbsoluteNumberField` for examples. @@ -565,6 +572,7 @@ def _call_(self, x): f = x.polynomial() return R._element_class(R, f) + class MapVectorSpaceToRelativeNumberField(NumberFieldIsomorphism): r""" The isomorphism to a relative number field from its underlying `\QQ`-vector @@ -609,6 +617,7 @@ def _call_(self, x): """ return self._from_K(self._from_V(x)) + class MapRelativeNumberFieldToVectorSpace(NumberFieldIsomorphism): r""" The isomorphism from a relative number field to its underlying `\QQ`-vector diff --git a/src/sage/rings/number_field/meson.build b/src/sage/rings/number_field/meson.build new file mode 100644 index 00000000000..077c1d918e6 --- /dev/null +++ b/src/sage/rings/number_field/meson.build @@ -0,0 +1,66 @@ +py.install_sources( + 'S_unit_solver.py', + 'all.py', + 'bdd_height.py', + 'class_group.py', + 'galois_group.py', + 'homset.py', + 'maps.py', + 'morphism.py', + 'number_field.py', + 'number_field_base.pxd', + 'number_field_element.pxd', + 'number_field_element_base.pxd', + 'number_field_element_quadratic.pxd', + 'number_field_ideal.py', + 'number_field_ideal_rel.py', + 'number_field_rel.py', + 'order.py', + 'order_ideal.py', + 'selmer_group.py', + 'small_primes_of_degree_one.py', + 'splitting_field.py', + 'structure.py', + 'totallyreal_data.pxd', + 'totallyreal_phc.py', + 'totallyreal_rel.py', + 'unit_group.py', + subdir: 'sage/rings/number_field', +) + +extension_data = { + 'number_field_base' : files('number_field_base.pyx'), + 'number_field_element_base' : files('number_field_element_base.pyx'), + 'number_field_morphisms' : files('number_field_morphisms.pyx'), + 'totallyreal' : files('totallyreal.pyx'), + 'totallyreal_data' : files('totallyreal_data.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/number_field', + install: true, + include_directories: [inc_cpython, inc_ext, inc_flint, inc_ntl, inc_rings], + dependencies: [py_dep, cypari2, cysignals, flint, gmp, mpfi, mpfr, ntl], + ) +endforeach + +extension_data_cpp = { + 'number_field_element': files('number_field_element.pyx'), + 'number_field_element_quadratic': files('number_field_element_quadratic.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/number_field', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ext, inc_flint, inc_ntl, inc_rings], + dependencies: [py_dep, cypari2, cysignals, flint, gmp, mpfi, mpfr, ntl], + ) +endforeach + diff --git a/src/sage/rings/number_field/morphism.py b/src/sage/rings/number_field/morphism.py index a16ccd2bbc6..579c925ed01 100644 --- a/src/sage/rings/number_field/morphism.py +++ b/src/sage/rings/number_field/morphism.py @@ -26,7 +26,7 @@ class NumberFieldHomomorphism_im_gens(RingHomomorphism_im_gens): def __invert__(self): r""" - Return the inverse of an isomorphism of absolute number fields + Return the inverse of an isomorphism of absolute number fields. EXAMPLES:: @@ -88,16 +88,16 @@ def __invert__(self): def preimage(self, y): r""" Compute a preimage of `y` in the domain, provided one exists. - Raises a :class:`ValueError` if `y` has no preimage. + Raises a :exc:`ValueError` if `y` has no preimage. INPUT: - - ``y`` -- an element of the codomain of ``self``. + - ``y`` -- an element of the codomain of ``self`` OUTPUT: Returns the preimage of `y` in the domain, if one exists. - Raises a :class:`ValueError` if `y` has no preimage. + Raises a :exc:`ValueError` if `y` has no preimage. EXAMPLES:: @@ -221,7 +221,7 @@ def im_gens(self): def _richcmp_(self, other, op): """ - Compare + Compare. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index c1e9c12a711..767acd8ebc5 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -234,19 +234,19 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, INPUT: - ``polynomial`` -- a polynomial over `\QQ` or a number field, or a list - of such polynomials. - - ``names`` (or ``name``) -- a string or a list of strings, the names of + of such polynomials + - ``names`` (or ``name``) -- string or list of strings, the names of the generators - - ``check`` -- a boolean (default: ``True``); do type checking and - irreducibility checking. + - ``check`` -- boolean (default: ``True``); do type checking and + irreducibility checking - ``embedding`` -- ``None``, an element, or a list of elements, the images of the generators in an ambient field (default: ``None``) - ``latex_names`` (or ``latex_name``) -- ``None``, a string, or a - list of strings (default: ``None``), how the generators are printed + list of strings (default: ``None``); how the generators are printed for latex output - - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, + - ``assume_disc_small`` -- boolean (default: ``False``); if ``True``, assume that no square of a prime greater than PARI's primelimit - (which should be 500000); only applies for absolute fields at + (which should be 500000). Only applies for absolute fields at present. - ``maximize_at_primes`` -- ``None`` or a list of primes (default: ``None``); if not ``None``, then the maximal order is computed by @@ -565,17 +565,17 @@ class NumberFieldFactory(UniqueFactory): INPUT: - - ``polynomial`` -- a polynomial over `\QQ` or a number field. - - ``name`` -- a string (default: ``'a'``), the name of the generator - - ``check`` -- a boolean (default: ``True``); do type checking and - irreducibility checking. + - ``polynomial`` -- a polynomial over `\QQ` or a number field + - ``name`` -- string (default: ``'a'``); the name of the generator + - ``check`` -- boolean (default: ``True``); do type checking and + irreducibility checking - ``embedding`` -- ``None`` or an element, the images of the generator in an ambient field (default: ``None``) - - ``latex_name`` -- ``None`` or a string (default: ``None``), how the + - ``latex_name`` -- ``None`` or string (default: ``None``); how the generator is printed for latex output - - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, + - ``assume_disc_small`` -- boolean (default: ``False``); if ``True``, assume that no square of a prime greater than PARI's primelimit - (which should be 500000); only applies for absolute fields at + (which should be 500000). Only applies for absolute fields at present. - ``maximize_at_primes`` -- ``None`` or a list of primes (default: ``None``); if not ``None``, then the maximal order is computed by @@ -608,7 +608,6 @@ class NumberFieldFactory(UniqueFactory): Isomorphism given by variable name change map: From: Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? To: Number Field in b with defining polynomial x^2 - 2) - """ def create_key_and_extra_args(self, polynomial, name, check, embedding, latex_name, assume_disc_small, maximize_at_primes, structure): r""" @@ -623,7 +622,6 @@ def create_key_and_extra_args(self, polynomial, name, check, embedding, latex_na ....: latex_name=None, assume_disc_small=False, maximize_at_primes=None, structure=None) ((Rational Field, x^2 + 1, ('a',), None, 'a', None, False, None), {'check': False}) - """ if name is None: raise TypeError("You must specify the name of the generator.") @@ -678,7 +676,6 @@ def create_object(self, version, key, check): sage: R. = QQ[] sage: nff.create_object(None, (QQ, x^2 + 1, ('a',), None, None, None, False, None), check=False) Number Field in a with defining polynomial x^2 + 1 - """ base, polynomial, name, embedding, latex_name, maximize_at_primes, assume_disc_small, structure = key @@ -704,21 +701,21 @@ def NumberFieldTower(polynomials, names, check=True, embeddings=None, latex_name INPUT: - - ``polynomials`` -- a list of polynomials. Each entry must be polynomial + - ``polynomials`` -- list of polynomials. Each entry must be polynomial which is irreducible over the number field generated by the roots of the following entries. - - ``names`` -- a list of strings or a string, the names of the generators of + - ``names`` -- list of strings or a string, the names of the generators of the relative number fields. If a single string, then names are generated from that string. - - ``check`` -- a boolean (default: ``True``), whether to check that the + - ``check`` -- boolean (default: ``True``); whether to check that the polynomials are irreducible - - ``embeddings`` -- a list of elements or ``None`` (default: ``None``), - embeddings of the relative number fields in an ambient field. - - ``latex_names`` -- a list of strings or ``None`` (default: ``None``), names - used to print the generators for latex output. - - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, + - ``embeddings`` -- list of elements or ``None`` (default: ``None``); + embeddings of the relative number fields in an ambient field + - ``latex_names`` -- list of strings or ``None`` (default: ``None``); names + used to print the generators for latex output + - ``assume_disc_small`` -- boolean (default: ``False``); if ``True``, assume that no square of a prime greater than PARI's ``primelimit`` - (which should be 500000); only applies for absolute fields at + (which should be 500000). Only applies for absolute fields at present. - ``maximize_at_primes`` -- ``None`` or a list of primes (default: ``None``); if not ``None``, then the maximal order is computed by @@ -868,15 +865,14 @@ def QuadraticField(D, name='a', check=True, embedding=True, latex_name='sqrt', * - ``name`` -- variable name (default: ``'a'``) - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - - ``embedding`` -- bool or square root of `D` in an - ambient field (default: ``True``) + - ``embedding`` -- boolean or square root of `D` in an ambient field + (default: ``True``) - ``latex_name`` -- latex variable name (default: `\sqrt{D}`) - - OUTPUT: A number field defined by a quadratic polynomial. Unless + OUTPUT: a number field defined by a quadratic polynomial. Unless otherwise specified, it has an embedding into `\RR` or `\CC` by sending the generator to the positive or upper-half-plane root. @@ -1041,23 +1037,24 @@ def is_AbsoluteNumberField(x): class CyclotomicFieldFactory(UniqueFactory): r""" - Return the `n`-th cyclotomic field, where n is a positive integer, - or the universal cyclotomic field if ``n==0``. + Return the `n`-th cyclotomic field, where `n` is a positive integer, + or the universal cyclotomic field if `n=0`. For the documentation of the universal cyclotomic field, see :class:`~sage.rings.universal_cyclotomic_field.UniversalCyclotomicField`. INPUT: - - ``n`` -- a nonnegative integer, default: ``0`` + - ``n`` -- nonnegative integer (default: `0`) - - ``names`` -- name of generator (default: ``zetan``) + - ``names`` -- name of generator (default: ``zetan``) - - ``bracket`` -- Defines the brackets in the case of ``n==0``, and - is ignored otherwise. Can be any even length string, with ``"()"`` being the default. + - ``bracket`` -- defines the brackets in the case of `n=0`, and + is ignored otherwise. Can be any even length string, with ``'()'`` being + the default. - - ``embedding`` -- bool or `n`-th root of unity in an - ambient field (default: ``True``) + - ``embedding`` -- boolean or `n`-th root of unity in an ambient field + (default: ``True``) EXAMPLES: @@ -1078,7 +1075,7 @@ class CyclotomicFieldFactory(UniqueFactory): zeta7 The default embedding sends the generator to the complex primitive - `n^{th}` root of unity of least argument. + `n`-th root of unity of least argument. :: @@ -1318,7 +1315,6 @@ class NumberField_generic(WithEqualityById, number_field_base.NumberField): ....: for f in D: ....: elt = f.q_eigenform(10, 'alpha')[3] ....: assert elt.is_integral() - """ def __init__(self, polynomial, name, latex_name, check=True, embedding=None, category=None, @@ -1442,7 +1438,6 @@ def _convert_map_from_(self, other): 1/6*b^3 + 1/6*b sage: L(b) i - a - """ from sage.categories.map import Map if self._structure is not None: @@ -1576,7 +1571,6 @@ def construction(self): sage: F, R = K.construction() sage: F(R) == K True - """ from sage.categories.pushout import AlgebraicExtensionFunctor from sage.rings.rational_field import QQ @@ -2102,21 +2096,20 @@ def random_element(self, num_bound=None, den_bound=None, INPUT: - - ``num_bound`` -- Bound on numerator of the coefficients of + - ``num_bound`` -- bound on numerator of the coefficients of the resulting element - - ``den_bound`` -- Bound on denominators of the coefficients + - ``den_bound`` -- bound on denominators of the coefficients of the resulting element - - ``integral_coefficients`` -- (default: ``False``) If ``True``, then - the resulting element will have integral - coefficients. This option overrides any - value of ``den_bound``. + - ``integral_coefficients`` -- boolean (default: ``False``); if + ``True``, then the resulting element will have integral coefficients. + This option overrides any value of ``den_bound``. - - ``distribution`` -- Distribution to use for the coefficients + - ``distribution`` -- distribution to use for the coefficients of the resulting element - OUTPUT: Element of this number field + OUTPUT: element of this number field EXAMPLES:: @@ -2182,14 +2175,14 @@ def subfield(self, alpha, name=None, names=None): INPUT: - - ``alpha`` -- an element of ``self``, or something that - coerces to an element of ``self``. + - ``alpha`` -- an element of ``self``, or something that + coerces to an element of ``self`` OUTPUT: - ``K`` -- a number field - ``from_K`` -- a homomorphism from `K` to ``self`` that - sends the generator of `K` to ``alpha``. + sends the generator of `K` to ``alpha`` EXAMPLES:: @@ -2358,17 +2351,17 @@ def subfield_from_elements(self, alpha, name=None, polred=True, threshold=None): - ``name`` -- a name for the generator of the new number field - - ``polred`` -- (boolean, default ``True``); whether to optimize the generator of - the newly created field + - ``polred`` -- boolean (default: ``True``); whether to optimize the + generator of the newly created field - - ``threshold`` -- (positive number, default ``None``) threshold to be passed to - the ``do_polred`` function + - ``threshold`` -- positive number (default: ``None``) threshold to be + passed to the ``do_polred`` function OUTPUT: a triple ``(field, beta, hom)`` where - ``field`` -- a subfield of this number field - - ``beta`` -- a list of elements of ``field`` corresponding to ``alpha`` + - ``beta`` -- list of elements of ``field`` corresponding to ``alpha`` - ``hom`` -- inclusion homomorphism from ``field`` to ``self`` @@ -2551,11 +2544,11 @@ def quadratic_defect(self, a, p, check=True): - ``p`` -- a prime ideal - - ``check`` -- (default: ``True``); check if `p` is prime + - ``check`` -- boolean (default: ``True``); check if `p` is prime ALGORITHM: - This is an implementation of Algorithm 3.1.3 from [Kir2016]_ + This is an implementation of Algorithm 3.1.3 from [Kir2016]_. EXAMPLES:: @@ -2572,6 +2565,16 @@ def quadratic_defect(self, a, p, check=True): sage: p = K.primes_above(2)[0] sage: K.quadratic_defect(5, p) +Infinity + + TESTS:: + + sage: x = polygen(QQ, 'x') + sage: K. = NumberField(x^10 - x^8 - 2*x^7 - x^6 + 2*x^5 + 2*x^4 - x^2 + 1) + sage: p = K.prime_factors(2)[0] + sage: pi = K.uniformizer(p) + sage: a = 1 + pi^3 + sage: K.quadratic_defect(a, p) + 3 """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing if a not in self: @@ -2584,13 +2587,9 @@ def quadratic_defect(self, a, p, check=True): if a.is_zero(): return Infinity v = self(a).valuation(p) - if v % 2 == 1: + if v % 2: return v - # compute uniformizer pi - for g in p.gens(): - if g.valuation(p) == 1: - pi = g - break + pi = self.uniformizer(p) a = self(a) / pi**v F = p.residue_field() q = F.reduction_map() @@ -2604,11 +2603,10 @@ def quadratic_defect(self, a, p, check=True): a = self(s**2) * a u = self(4).valuation(p) w = (a - 1).valuation(p) - R = PolynomialRing(F, 'x') - x = R.gen() - f = R(x**2 + x) - while w < u and w % 2 == 0: - s = self(q((a - 1) / pi**w)**(1/2)) + x = PolynomialRing(F, 'x').gen() + f = x**2 + x + while w < u and not w % 2: + s = F.lift(q((a - 1) / pi**w).sqrt()) a = a / (1 + s*(pi**(w/2)))**2 w = (a - 1).valuation(p) if w < u and w % 2: @@ -2684,7 +2682,6 @@ def is_isomorphic(self, other, isomorphism_maps=False) -> bool: sage: k. = NumberField(x) sage: k.is_isomorphic(k) True - """ if not isinstance(other, NumberField_generic): raise ValueError("other must be a generic number field.") @@ -2870,7 +2867,7 @@ def complex_conjugation(self): This is only well-defined for fields contained in CM fields (i.e. for totally real fields and CM fields). Recall that a CM field is a totally imaginary quadratic extension of a totally - real field. For other fields, a :class:`ValueError` is raised. + real field. For other fields, a :exc:`ValueError` is raised. EXAMPLES:: @@ -3039,7 +3036,6 @@ def maximal_totally_real_subfield(self): polynomial x^4 - 2*x^3 + x^2 + 6*x + 3 To: Number Field in z with defining polynomial x^2 - 1/2*a over its base field] - """ try: @@ -3179,7 +3175,6 @@ def real_embeddings(self, prec=53): 0 sage: len(K.embeddings(AA)) 0 - """ K = sage.rings.real_mpfr.RealField(prec) return self.embeddings(K) @@ -3306,18 +3301,16 @@ def algebraic_closure(self): @cached_method def conductor(self, check_abelian=True): r""" - Computes the conductor of the abelian field `K`. + Compute the conductor of the abelian field `K`. If ``check_abelian`` is set to ``False`` and the field is not an abelian extension of `\QQ`, the output is not meaningful. INPUT: - - ``check_abelian`` -- a boolean (default: ``True``); check to see + - ``check_abelian`` -- boolean (default: ``True``); check to see that this is an abelian extension of `\QQ` - OUTPUT: - - Integer which is the conductor of the field. + OUTPUT: integer which is the conductor of the field EXAMPLES:: @@ -3388,7 +3381,7 @@ def dirichlet_group(self): The output is random if the field is not abelian. - OUTPUT: a list of Dirichlet characters + OUTPUT: list of Dirichlet characters EXAMPLES:: @@ -3448,7 +3441,6 @@ def _repr_(self): sage: k. = NumberField(x^13 - (2/3)*x + 3, embedding=-1) sage: k._repr_() 'Number Field in a with defining polynomial x^13 - 2/3*x + 3 with a = -1.106745229567614?' - """ result = "Number Field in {} with defining polynomial {}".format(self.variable_name(), self.polynomial()) gen = self.gen_embedding() @@ -3553,9 +3545,9 @@ def idealchinese(self, ideals, residues): INPUT: - - ``ideals`` -- a list of ideals of the number field. + - ``ideals`` -- list of ideals of the number field - - ``residues`` -- a list of elements of the number field. + - ``residues`` -- list of elements of the number field OUTPUT: @@ -3615,10 +3607,7 @@ def fractional_ideal(self, *gens, **kwds): INPUT: - - - ``gens`` -- a list of generators, or a number field - ideal. - + - ``gens`` -- list of generators, or a number field ideal EXAMPLES:: @@ -3667,9 +3656,9 @@ def ideals_of_bdd_norm(self, bound): INPUT: - - ``bound`` -- a positive integer + - ``bound`` -- positive integer - OUTPUT: A dict of all integral ideals `I` such that Norm(`I`) `\leq` ``bound``, + OUTPUT: a dict of all integral ideals `I` such that Norm(`I`) `\leq` ``bound``, keyed by norm. EXAMPLES:: @@ -3723,15 +3712,15 @@ def primes_above(self, x, degree=None): INPUT: - - ``x`` -- usually an element or ideal of ``self``. It - should be such that ``self.ideal(x)`` is sensible. This excludes `x=0`. + - ``x`` -- usually an element or ideal of ``self``. It should be such + that ``self.ideal(x)`` is sensible. This excludes `x=0`. - - ``degree`` -- (default: ``None``) ``None`` or an integer. - If ``None``, find all primes above `x` of any degree. If an - integer, find all primes above `x` such that the resulting - residue field has exactly this degree. + - ``degree`` -- (default: ``None``) ``None`` or an integer. + If ``None``, find all primes above `x` of any degree. If an + integer, find all primes above `x` such that the resulting + residue field has exactly this degree. - OUTPUT: A list of prime ideals of ``self`` lying over `x`. If ``degree`` + OUTPUT: list of prime ideals of ``self`` lying over `x`. If ``degree`` is specified and no such ideal exists, returns the empty list. The output is sorted by residue degree first, then by underlying prime (or equivalently, by norm). @@ -3826,16 +3815,16 @@ def prime_above(self, x, degree=None): INPUT: - - ``x`` -- usually an element or ideal of ``self``. It - should be such that ``self.ideal(x)`` is sensible. This excludes `x=0`. + - ``x`` -- usually an element or ideal of ``self``. It should be such + that ``self.ideal(x)`` is sensible. This excludes `x=0`. - - ``degree`` -- (default: ``None``) ``None`` or an integer. - If one, find a prime above `x` of any degree. If an integer, find a - prime above `x` such that the resulting residue field has exactly - this degree. + - ``degree`` -- (default: ``None``) ``None`` or an integer. + If one, find a prime above `x` of any degree. If an integer, find a + prime above `x` such that the resulting residue field has exactly + this degree. - OUTPUT: A prime ideal of ``self`` lying over `x`. If ``degree`` is specified - and no such ideal exists, raises a :class:`ValueError`. + OUTPUT: a prime ideal of ``self`` lying over `x`. If ``degree`` is specified + and no such ideal exists, raises a :exc:`ValueError`. EXAMPLES:: @@ -3904,7 +3893,6 @@ def prime_above(self, x, degree=None): Traceback (most recent call last): ... AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors'... - """ ids = self.primes_above(x, degree) if not ids: @@ -3917,8 +3905,8 @@ def primes_of_bounded_norm(self, B): INPUT: - - ``B`` -- a positive integer or real; upper bound on the norms of the - primes generated. + - ``B`` -- positive integer or real; upper bound on the norms of the + primes generated OUTPUT: @@ -3927,7 +3915,7 @@ def primes_of_bounded_norm(self, B): using the comparison function for ideals, which is based on the Hermite Normal Form. - .. note:: + .. NOTE:: See also :meth:`primes_of_bounded_norm_iter` for an iterator version of this, but note that the iterator sorts @@ -3969,9 +3957,9 @@ def primes_of_bounded_norm(self, B): from sage.rings.fast_arith import prime_range if self is QQ: - return prime_range(B + 1, algorithm="pari_isprime") + return prime_range(B + 1, algorithm='pari_isprime') else: - P = (pp for p in prime_range(B + 1, algorithm="pari_isprime") + P = (pp for p in prime_range(B + 1, algorithm='pari_isprime') for pp in self.primes_above(p)) P = [p for p in P if p.norm() <= B] P.sort(key=lambda P: (P.norm(), P)) @@ -3983,15 +3971,15 @@ def primes_of_bounded_norm_iter(self, B): INPUT: - - ``B`` -- a positive integer or real; upper bound on the norms of the - primes generated. + - ``B`` -- positive integer or real; upper bound on the norms of the + primes generated OUTPUT: An iterator over all prime ideals of this number field of norm at most `B`. - .. note:: + .. NOTE:: The output is not sorted by norm, but by size of the underlying rational prime. @@ -4021,10 +4009,10 @@ def primes_of_bounded_norm_iter(self, B): from sage.rings.fast_arith import prime_range if self is QQ: - for p in prime_range(B + 1, algorithm="pari_isprime"): + for p in prime_range(B + 1, algorithm='pari_isprime'): yield p else: - for p in prime_range(B + 1, algorithm="pari_isprime"): + for p in prime_range(B + 1, algorithm='pari_isprime'): for pp in self.primes_above(p): if pp.norm() <= B: yield pp @@ -4088,15 +4076,13 @@ def primes_of_degree_one_list(self, n, num_integer_primes=10000, max_iterations= INPUT: - - ``num_integer_primes`` -- (default: 10000) an - integer. We try to find primes of absolute norm no greater than the - ``num_integer_primes``-th prime number. For example, if - ``num_integer_primes`` is 2, the largest norm found will be 3, since - the second prime is 3. + - ``num_integer_primes`` -- integer (default: 10000). We try to find + primes of absolute norm no greater than the ``num_integer_primes``-th + prime number. For example, if ``num_integer_primes`` is 2, the + largest norm found will be 3, since the second prime is 3. - - ``max_iterations`` -- (default: 100) an integer. We - test ``max_iterations`` integers to find small primes before raising - :class:`StopIteration`. + - ``max_iterations`` -- integer (default: 100). We test ``max_iterations`` + integers to find small primes before raising :class:`StopIteration`. EXAMPLES:: @@ -4120,11 +4106,9 @@ def completely_split_primes(self, B=200): INPUT: - - ``B`` -- a positive integer bound (default: 200) - - OUTPUT: + - ``B`` -- positive integer bound (default: 200) - A list of all primes `p < B` which split completely in ``K``. + OUTPUT: list of all primes `p < B` which split completely in ``K`` EXAMPLES:: @@ -4303,8 +4287,8 @@ def pari_nf(self, important=True): INPUT: - - ``important`` -- boolean (default: ``True``). If ``False``, - raise a :class:`RuntimeError` if we need to do a difficult + - ``important`` -- boolean (default: ``True``); if ``False``, + raise a :exc:`RuntimeError` if we need to do a difficult discriminant factorization. This is useful when an integral basis is not strictly required, such as for factoring polynomials over this number field. @@ -4425,16 +4409,13 @@ def pari_bnf(self, proof=None, units=True): INPUT: - - ``proof`` -- If ``False``, assume GRH. If ``True``, run PARI's - :pari:`bnfcertify` to make sure that the results are correct. - - - ``units`` -- (default: ``True) If ``True``, insist on having - fundamental units. If ``False``, the units may or may not be - computed. + - ``proof`` -- if ``False``, assume GRH; if ``True``, run PARI's + :pari:`bnfcertify` to make sure that the results are correct - OUTPUT: + - ``units`` -- (default: ``True) if ``True``, insist on having + fundamental units; if ``False``, the units may or may not be computed - The PARI ``bnf`` structure of this number field. + OUTPUT: the PARI ``bnf`` structure of this number field .. warning:: @@ -4563,14 +4544,13 @@ def class_group(self, proof=None, names='c'): INPUT: - - ``proof`` -- if ``True`` then compute the class group - provably correctly. Default is ``True``. Call :func:`number_field_proof` to - change this default globally. + - ``proof`` -- if ``True`` (default), then compute the class group + provably correctly; call :func:`number_field_proof` to change this + default globally - - ``names`` -- names of the generators of this class - group. + - ``names`` -- names of the generators of this class group - OUTPUT: The class group of this number field. + OUTPUT: the class group of this number field EXAMPLES:: @@ -4625,9 +4605,8 @@ def class_group(self, proof=None, names='c'): default assume the Generalized Riemann Hypothesis. To do class groups computations not provably correctly you must often pass the flag ``proof=False`` to functions or call the function - ``proof.number_field(False)``. It can easily take 1000's of times + ``proof.number_field(False)``. It can easily take 1000s of times longer to do computations with ``proof=True`` (the default). - """ proof = proof_flag(proof) try: @@ -4652,7 +4631,7 @@ def class_number(self, proof=None): INPUT: - - ``proof`` -- bool (default: ``True`` unless you called + - ``proof`` -- boolean (default: ``True``, unless you called ``number_field_proof``) EXAMPLES:: @@ -4674,15 +4653,15 @@ def S_class_group(self, S, proof=None, names='c'): INPUT: - - ``S`` -- a set of primes of the base field + - ``S`` -- set of primes of the base field - - ``proof`` -- if False, assume the GRH in computing the class group. - Default is ``True``. Call ``number_field_proof`` to change this - default globally. + - ``proof`` -- if ``False``, assume the GRH in computing the class + group. Default is ``True``. Call ``number_field_proof`` to change + this default globally. - - ``names`` -- names of the generators of this class group. + - ``names`` -- names of the generators of this class group - OUTPUT: The S-class group of this number field. + OUTPUT: the S-class group of this number field EXAMPLES: @@ -4731,13 +4710,13 @@ def S_units(self, S, proof=True): INPUT: - - ``S`` -- a set of primes of the base field + - ``S`` -- set of primes of the base field - ``proof`` -- if ``False``, assume the GRH in computing the class group - OUTPUT: A list of generators of the unit group. + OUTPUT: list of generators of the unit group - .. note:: + .. NOTE:: For more functionality see the function :func:`S_unit_group`. @@ -4780,7 +4759,6 @@ def S_units(self, S, proof=True): sage: J = K.ideal(-2) sage: K.S_units([I, J, I]) [2, -1] - """ return self._S_class_group_and_units(tuple(S), proof=proof)[0] @@ -4791,17 +4769,17 @@ def _S_class_group_and_units(self, S, proof=True): INPUT: - - ``S`` -- a tuple of prime ideals of ``self`` + - ``S`` -- tuple of prime ideals of ``self`` - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: - - ``units`` -- A list of generators of the unit group. + - ``units``: a list of generators of the unit group - - ``clgp_gens`` -- A list of generators of the `S`-class group. + - ``clgp_gens`` -- a list of generators of the `S`-class group. Each generator is represented as a pair ``(gen, order)``, - where ``gen`` is a fractional ideal of self and ``order`` is + where ``gen`` is a fractional ideal of ``self`` and ``order`` is its order in the `S`-class group. EXAMPLES:: @@ -4907,14 +4885,14 @@ def selmer_generators(self, S, m, proof=True, orders=False): INPUT: - - ``S`` -- a set of primes of ``self`` + - ``S`` -- set of primes of ``self`` - - ``m`` -- a positive integer + - ``m`` -- positive integer - ``proof`` -- if ``False``, assume the GRH in computing the class group - - ``orders`` -- (default: ``False``) if ``True``, output two lists, the - generators and their orders + - ``orders`` -- boolean (default: ``False``); if ``True``, output two + lists, the generators and their orders OUTPUT: @@ -5033,7 +5011,6 @@ def selmer_generators(self, S, m, proof=True, orders=False): sage: S = K.selmer_generators((), 4) sage: all(4.divides(x.valuation(p)) for x in S) True - """ units, clgp_gens = self._S_class_group_and_units(tuple(S), proof=proof) gens = [] @@ -5085,9 +5062,9 @@ def selmer_group_iterator(self, S, m, proof=True): INPUT: - - ``S`` -- a set of primes of ``self`` + - ``S`` -- set of primes of ``self`` - - ``m`` -- a positive integer + - ``m`` -- positive integer - ``proof`` -- if ``False``, assume the GRH in computing the class group @@ -5131,11 +5108,11 @@ def selmer_space(self, S, p, proof=None): INPUT: - - ``S`` -- a set of primes ideals of ``self`` + - ``S`` -- set of primes ideals of ``self`` - ``p`` -- a prime number - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: @@ -5225,7 +5202,6 @@ def selmer_space(self, S, p, proof=None): sage: K.hilbert_class_field('b') Number Field in b with defining polynomial x^2 + 1 over its base field - """ from sage.rings.number_field.selmer_group import pSelmerGroup return pSelmerGroup(self, S, p, proof) @@ -5245,9 +5221,7 @@ def composite_fields(self, other, names=None, both_maps=False, preserve_embeddin - ``preserve_embedding`` -- boolean (default: ``True``) - OUTPUT: - - A list of the composite fields, possibly with maps. + OUTPUT: list of the composite fields, possibly with maps If ``both_maps`` is ``True``, the list consists of quadruples ``(F, self_into_F, other_into_F, k)`` such that @@ -5703,9 +5677,7 @@ def discriminant(self, v=None): - ``v`` -- (optional) list of elements of this number field - OUTPUT: - - Integer if ``v`` is omitted, and Rational otherwise. + OUTPUT: integer if ``v`` is omitted, and Rational otherwise EXAMPLES:: @@ -5968,7 +5940,7 @@ def decomposition_type(self, p): INPUT: - - ``p`` -- a prime element or ideal of the base field. + - ``p`` -- a prime element or ideal of the base field OUTPUT: @@ -6071,10 +6043,7 @@ def gen(self, n=0): INPUT: - - - ``n`` -- must be 0 (the default), or an exception is - raised. - + - ``n`` -- must be 0 (the default), or an exception is raised EXAMPLES:: @@ -6213,15 +6182,15 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non INPUT: - - ``type`` -- Deprecated; the different versions of Galois groups have been - merged in :issue:`28782`. + - ``type`` -- deprecated; the different versions of Galois groups have been + merged in :issue:`28782` - - ``algorithm`` -- ``'pari'``, ``'gap'``, ``'kash'``, ``'magma'``. (default: ``'pari'``; - for degrees between 12 and 15 default is ``'gap'``, and - when the degree is >= 16 it is ``'kash'``.) + - ``algorithm`` -- ``'pari'``, ``'gap'``, ``'kash'``, or ``'magma'`` + (default: ``'pari'``); for degrees between 12 and 15 default is + ``'gap'``, and when the degree is >= 16 it is ``'kash'``) - - ``names`` -- a string giving a name for the generator of the Galois - closure of ``self``, when this field is not Galois. + - ``names`` -- string giving a name for the generator of the Galois + closure of ``self``, when this field is not Galois - ``gc_numbering`` -- if ``True``, permutations will be written in terms of the action on the roots of a defining polynomial @@ -6310,7 +6279,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non We check that the changes in :issue:`28782` won't break code that used v1 Galois groups:: sage: # needs sage.groups - sage: G = NumberField(x^3 - 2, 'a').galois_group(type="pari") + sage: G = NumberField(x^3 - 2, 'a').galois_group(type='pari') ...DeprecationWarning: the different Galois types have been merged into one class See https://github.com/sagemath/sage/issues/28782 for details. sage: G.group() @@ -6343,7 +6312,6 @@ def _normalize_prime_list(self, v): (3, 5) sage: K._normalize_prime_list([3, 5, -3]) (3, 5) - """ if v is None: v = [] @@ -6395,8 +6363,8 @@ def integral_basis(self, v=None): INPUT: - - ``v`` -- ``None``, a prime, or a list of primes. See the - documentation for :meth:`maximal_order`. + - ``v`` -- ``None``, a prime, or a list of primes; see the + documentation for :meth:`maximal_order` EXAMPLES:: @@ -6426,11 +6394,11 @@ def _pari_integral_basis(self, v=None, important=True): INPUT: - - ``v`` -- ``None``, a prime, or a list of primes. See the - documentation for :meth:``maximal_order``. + - ``v`` -- ``None``, a prime, or a list of primes; see the + documentation for :meth:``maximal_order`` - - ``important`` -- boolean (default: ``True``). If ``False``, - raise a :class:`RuntimeError` if we need to do a difficult + - ``important`` -- boolean (default: ``True``); if ``False``, + raise a :exc:`RuntimeError` if we need to do a difficult discriminant factorization. This is useful when an integral basis is not strictly required. @@ -6499,8 +6467,8 @@ def reduced_basis(self, prec=None): INPUT: - - ``prec`` (default: ``None``) -- the precision with which to - compute the Minkowski embedding. + - ``prec`` -- (default: ``None``) the precision with which to + compute the Minkowski embedding OUTPUT: @@ -6573,17 +6541,17 @@ def reduced_gram_matrix(self, prec=None): INPUT: - - ``prec`` (default: ``None``) -- the precision with which - to calculate the Minkowski embedding. (See NOTE below.) + - ``prec`` -- (default: ``None``) the precision with which + to calculate the Minkowski embedding (see NOTE below) - OUTPUT: The Gram matrix `[\langle x_i,x_j \rangle]` of an LLL reduced + OUTPUT: the Gram matrix `[\langle x_i,x_j \rangle]` of an LLL reduced basis for the maximal order of ``self``, where the integral basis for ``self`` is given by `\{x_0, \dots, x_{n-1}\}`. Here `\langle , \rangle` is the usual inner product on `\RR^n`, and ``self`` is embedded in `\RR^n` by the Minkowski embedding. See the docstring for :meth:`NumberField_absolute.minkowski_embedding` for more information. - .. note:: + .. NOTE:: In the non-totally-real case, the LLL routine we call is currently PARI's :pari:`qflll`, which works with floating point @@ -6671,7 +6639,7 @@ def _positive_integral_elements_with_trace(self, C): Find all totally positive integral elements in ``self`` whose trace is between C[0] and C[1], inclusive. - .. note:: + .. NOTE:: This is currently only implemented in the case that ``self`` is totally real, since it requires exact computation of @@ -6719,8 +6687,8 @@ def narrow_class_group(self, proof=None): INPUT: - - ``proof`` -- default: ``None`` (use the global proof - setting, which defaults to ``True``). + - ``proof`` -- (default: ``None``) use the global proof setting, which + defaults to ``True`` EXAMPLES:: @@ -6742,7 +6710,7 @@ def ngens(self): """ Return the number of generators of this number field (always 1). - OUTPUT: the python integer 1. + OUTPUT: the python integer 1 EXAMPLES:: @@ -6889,7 +6857,7 @@ def regulator(self, proof=None): INPUT: - - ``proof`` -- default: ``True``, unless you set it otherwise. + - ``proof`` -- (default: ``True``) unless you set it otherwise EXAMPLES:: @@ -6919,12 +6887,11 @@ def residue_field(self, prime, names=None, check=True): this number field, or an element of the field which generates a principal prime ideal. - - ``names`` -- the name of the variable in the residue - field + - ``names`` -- the name of the variable in the residue field - - ``check`` -- whether or not to check the primality of ``prime``. + - ``check`` -- whether or not to check the primality of ``prime`` - OUTPUT: The residue field at this prime. + OUTPUT: the residue field at this prime EXAMPLES:: @@ -7012,24 +6979,22 @@ def trace_pairing(self, v): A[j, i] = t return A - def uniformizer(self, P, others="positive"): + def uniformizer(self, P, others='positive'): """ Return an element of ``self`` with valuation 1 at the prime ideal `P`. INPUT: + - ``self`` -- a number field - - ``self`` -- a number field - - - ``P`` -- a prime ideal of ``self`` - - - ``others`` -- either ``"positive"`` (default), in which - case the element will have non-negative valuation at all other - primes of ``self``, or ``"negative"``, in which case the element will have - non-positive valuation at all other primes of ``self``. + - ``P`` -- a prime ideal of ``self`` + - ``others`` -- either ``'positive'`` (default), in which case the + element will have nonnegative valuation at all other primes of + ``self``, or ``'negative'``, in which case the element will have + nonpositive valuation at all other primes of ``self`` - .. note:: + .. NOTE:: When `P` is principal (e.g., always when ``self`` has class number one) the result may or may not be a generator of `P`! @@ -7113,9 +7078,9 @@ def units(self, proof=None): INPUT: - - ``proof`` (bool, default ``True``) flag passed to PARI. + - ``proof`` -- boolean (default: ``True``); flag passed to PARI - .. note:: + .. NOTE:: For more functionality see :meth:`unit_group`. @@ -7195,9 +7160,9 @@ def unit_group(self, proof=None): INPUT: - - ``proof`` (bool, default ``True``) flag passed to PARI. + - ``proof`` -- boolean (default: ``True``); flag passed to PARI - .. note:: + .. NOTE:: The group is cached. @@ -7277,7 +7242,7 @@ def S_unit_group(self, proof=None, S=None): INPUT: - - ``proof`` -- bool (default: ``True``); flag passed to PARI + - ``proof`` -- boolean (default: ``True``); flag passed to PARI - ``S`` -- list or tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in @@ -7285,7 +7250,7 @@ def S_unit_group(self, proof=None, S=None): group is constructed; otherwise, the `S`-unit group is constructed. - .. note:: + .. NOTE:: The group is cached. @@ -7364,7 +7329,6 @@ def S_unit_group(self, proof=None, S=None): -1 * 2^9 * 3^5 sage: U.log(u) (1, 1, 4, 1, 5) - """ proof = proof_flag(proof) @@ -7415,11 +7379,15 @@ def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_boun INPUT: - - ``S`` -- a list of finite primes in this number field - - ``prec`` -- precision used for computations in real, complex, and p-adic fields (default: 106) - - ``include_exponents`` -- whether to include the exponent vectors in the returned value (default: ``True``). - - ``include_bound`` -- whether to return the final computed bound (default: ``False``) - - ``proof`` -- if ``False``, assume the GRH in computing the class group. Default is ``True``. + - ``S`` -- list of finite primes in this number field + - ``prec`` -- precision used for computations in real, complex, and + `p`-adic fields (default: 106) + - ``include_exponents`` -- whether to include the exponent vectors in + the returned value (default: ``True``) + - ``include_bound`` -- whether to return the final computed bound + (default: ``False``) + - ``proof`` -- if ``False``, assume the GRH in computing the class group; + default is ``True`` OUTPUT: @@ -7472,11 +7440,10 @@ def zeta(self, n=2, all=False): - ``n`` -- positive integer - - ``all`` -- boolean. If ``False`` (default), return a primitive - `n`-th root of unity in this field, or raise a :class:`ValueError` - exception if there are none. If ``True``, return a list of - all primitive `n`-th roots of unity in this field - (possibly empty). + - ``all`` -- boolean; if ``False`` (default), return a primitive + `n`-th root of unity in this field, or raise a :exc:`ValueError` + exception if there are none. If ``True``, return a list of all + primitive `n`-th roots of unity in this field (possibly empty). .. NOTE:: @@ -7576,7 +7543,7 @@ def zeta_order(self): r""" Return the number of roots of unity in this field. - .. note:: + .. NOTE:: We do not create the full unit group since that can be expensive, but we do use it if it is already known. @@ -7622,7 +7589,7 @@ def primitive_root_of_unity(self): cyclotomic fields. Repeated calls of this function may return a different value. - .. note:: + .. NOTE:: We do not create the full unit group since that can be expensive, but we do use it if it is already known. @@ -7731,17 +7698,17 @@ def solve_CRT(self, reslist, Ilist, check=True): INPUT: - - ``reslist`` -- a list of residues, i.e. integral number field elements + - ``reslist`` -- list of residues, i.e. integral number field elements - - ``Ilist`` -- a list of integral ideals, assumed pairwise coprime + - ``Ilist`` -- list of integral ideals, assumed pairwise coprime - - ``check`` -- (boolean, default ``True``) if ``True``, result is checked + - ``check`` -- boolean (default: ``True``); if ``True``, result is checked OUTPUT: An integral element `x` such that ``x - reslist[i]`` is in ``Ilist[i]`` for all `i`. - .. note:: + .. NOTE:: The current implementation requires the ideals to be pairwise coprime. A more general version would be possible. @@ -7872,7 +7839,6 @@ def valuation(self, prime): :meth:`Order.valuation() `, :meth:`pAdicGeneric.valuation() ` - """ from sage.rings.padics.padic_valuation import pAdicValuation return pAdicValuation(self, prime) @@ -7904,7 +7870,6 @@ def some_elements(self): Number Field in a with defining polynomial t sage: K.some_elements() [0, 1, 2, -1, 1/2, -1/2, 1/4, -2, 4] - """ elements = [] @@ -7961,7 +7926,7 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): - if a list, return an order that is maximal at each prime of these primes - ``assume_maximal`` -- ``True``, ``False``, ``None``, or - ``"non-maximal-non-unique"`` (default: ``"non-maximal-non-unique"``) + ``'non-maximal-non-unique'`` (default: ``'non-maximal-non-unique'``) ignored when ``v`` is ``None``; otherwise, controls whether we assume that the order :meth:`order.is_maximal` outside of ``v``. @@ -7972,7 +7937,7 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): - if ``None``, no assumptions are made about primes not in ``v``. - - if ``"non-maximal-non-unique"`` (deprecated), like ``False``, + - if ``'non-maximal-non-unique'`` (deprecated), like ``False``, however, the order is not a unique parent, so creating the same order later does typically not poison caches with the information that the order is not maximal. @@ -8079,7 +8044,6 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): 400160824478095086350656915693814563600 sage: O3.is_maximal() False - """ v = self._normalize_prime_list(v) @@ -8126,7 +8090,7 @@ def _coerce_from_other_number_field(self, x): in a common field, or there is an embedding of ``x.parent()`` into ``self`` or the other way around. If no compatible embeddings are found and `x` is not in ``QQ``, then raise - ``TypeError``. This guarantees that these conversions respect + :exc:`TypeError`. This guarantees that these conversions respect the field operations and conversions between several fields commute. @@ -8139,9 +8103,7 @@ def _coerce_from_other_number_field(self, x): - ``x`` -- an element of some number field - OUTPUT: - - An element of ``self`` corresponding to ``x``. + OUTPUT: an element of ``self`` corresponding to ``x`` EXAMPLES:: @@ -8253,7 +8215,6 @@ def _coerce_from_other_number_field(self, x): AUTHORS: - Jeroen Demeyer (2011-09-30): :issue:`11869` - """ # Special case for x in QQ. This is common, so should be fast. xpol = x.polynomial() @@ -8324,8 +8285,7 @@ def _coerce_from_other_number_field(self, x): log_half_root_bound = log2abs(f[0]/2)/n for i in range(1, n): bd = log2abs(f[i])/(n-i) - if bd > log_half_root_bound: - log_half_root_bound = bd + log_half_root_bound = max(bd, log_half_root_bound) # Twice the bound on the roots of f, in other words an upper # bound for the distance between two roots. log_double_root_bound = log_half_root_bound + 2.0 # 2.0 = log2(4) @@ -8445,7 +8405,6 @@ def _coerce_map_from_(self, R): sage: K. = NumberField(polygen(QQ)^2 - 2) sage: type(K.coerce_map_from(QQ)) - """ if R is int: return self._generic_coerce_map(R) @@ -8747,7 +8706,7 @@ def change_names(self, names): INPUT: - - ``names`` -- should be exactly one variable name. + - ``names`` -- should be exactly one variable name Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an @@ -8881,7 +8840,6 @@ def _subfields_helper(self, degree=0, name=None, both_maps=True, optimize=False) sage: K = F.subfields(3)[0][0] sage: K Number Field in zeta7_0 with defining polynomial x^3 + x^2 - 2*x - 1 with zeta7_0 = 1.246979603717467? - """ if name is None: name = self.variable_names() @@ -8947,7 +8905,6 @@ def _maximal_order(self, v=(), assume_maximal=None): sage: k. = NumberField(x^3 + x^2 - 2*x+8) sage: k.maximal_order() is k.maximal_order() # indirect doctest True - """ B = [self(b, check=False) for b in self._pari_integral_basis(v=v)] @@ -8963,20 +8920,20 @@ def order(self, *args, **kwds): INPUT: - - ``gens`` -- list of elements in this number field; if no generators - are given, just returns the cardinality of this number field - (`\infty`) for consistency. + - ``gens`` -- list of elements in this number field; if no generators + are given, just returns the cardinality of this number field + (`\infty`) for consistency. - - ``check_is_integral`` -- bool (default: ``True``), whether to check - that each generator is integral. + - ``check_is_integral`` -- boolean (default: ``True``); whether to + check that each generator is integral - - ``check_rank`` -- bool (default: ``True``), whether to check that the - ring generated by ``gens`` is of full rank. + - ``check_rank`` -- boolean (default: ``True``); whether to check that + the ring generated by ``gens`` is of full rank - - ``allow_subfield`` -- bool (default: ``False``), if ``True`` and the - generators do not generate an order, i.e., they generate a subring - of smaller rank, instead of raising an error, return an order in a - smaller number field. + - ``allow_subfield`` -- boolean (default: ``False``); if ``True`` and + the generators do not generate an order, i.e., they generate a + subring of smaller rank, instead of raising an error, return an order + in a smaller number field EXAMPLES:: @@ -9057,7 +9014,6 @@ def _order(self, gens, **kwds): sage: K.order(a) is K.order(a,a^2) is K.order(a^2,a) True - """ from sage.rings.number_field.order import absolute_order_from_ring_generators return absolute_order_from_ring_generators(gens, **kwds) @@ -9075,12 +9031,12 @@ def free_module(self, base=None, basis=None, map=True): - ``basis`` -- a basis for this field over the base - - ``maps`` -- boolean (default ``True``), whether to return + - ``maps`` -- boolean (default: ``True``); whether to return `R`-linear maps to and from `V` OUTPUT: - - `V` -- a vector space over the rational numbers + - ``V`` -- a vector space over the rational numbers - ``from_V`` -- an isomorphism from `V` to ``self`` (if requested) @@ -9205,7 +9161,8 @@ def galois_closure(self, names=None, map=False): - ``names`` -- variable name for Galois closure - - ``map`` -- (default: ``False``) also return an embedding of ``self`` into `K` + - ``map`` -- boolean (default: ``False``); also return an embedding of + ``self`` into `K` EXAMPLES:: @@ -9388,6 +9345,41 @@ def embeddings(self, K): Defn: a |--> 1.25992104989487 ] + Some more (possible and impossible) embeddings of cyclotomic fields:: + + sage: CyclotomicField(5).embeddings(QQbar) + [ + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> 0.3090169943749474? + 0.9510565162951536?*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> -0.8090169943749474? + 0.5877852522924731?*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> -0.8090169943749474? - 0.5877852522924731?*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> 0.3090169943749474? - 0.9510565162951536?*I + ] + sage: CyclotomicField(3).embeddings(CyclotomicField(7)) + [ ] + sage: CyclotomicField(3).embeddings(CyclotomicField(6)) + [ + Ring morphism: + From: Cyclotomic Field of order 3 and degree 2 + To: Cyclotomic Field of order 6 and degree 2 + Defn: zeta3 |--> zeta6 - 1, + Ring morphism: + From: Cyclotomic Field of order 3 and degree 2 + To: Cyclotomic Field of order 6 and degree 2 + Defn: zeta3 |--> -zeta6 + ] + Test that :issue:`15053` is fixed:: sage: K = NumberField(x^3 - 2, 'a') @@ -9506,17 +9498,17 @@ def logarithmic_embedding(self, prec=53): Return the morphism of ``self`` under the logarithmic embedding in the category Set. - The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`. + The logarithmic embedding is defined as a map from the number field + ``self`` to `\RR^n`. It is defined under Definition 4.9.6 in [Coh1993]_. INPUT: - - ``prec`` -- desired floating point precision. - - OUTPUT: + - ``prec`` -- desired floating point precision - the morphism of ``self`` under the logarithmic embedding in the category Set. + OUTPUT: the morphism of ``self`` under the logarithmic embedding in the + category Set EXAMPLES:: @@ -9714,9 +9706,7 @@ def abs_val(self, v, iota, prec=None): - ``iota`` -- an element of ``K`` - ``prec`` -- (default: ``None``) the precision of the real field - OUTPUT: - - The absolute value as a real number + OUTPUT: the absolute value as a real number EXAMPLES:: @@ -9775,9 +9765,7 @@ def relativize(self, alpha, names, structure=None): will return isomorphisms from and to this field. Otherwise, the field will be equipped with ``structure``. - OUTPUT: - - `K` -- relative number field + OUTPUT: `K` -- relative number field Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an isomorphism @@ -9952,7 +9940,6 @@ def relativize(self, alpha, names, structure=None): sage: K. = L.subfield(z24^3)[0] sage: L.relativize(K.hom(L), L.variable_name()+'0' ) Number Field in z2400 with defining polynomial x^2 + z240^3*x - z240^2 over its base field - """ # step 1: construct the abstract field generated by alpha.w # step 2: make a relative extension of it. @@ -9992,7 +9979,7 @@ def relativize(self, alpha, names, structure=None): basis.append(a**extdeg) # this one makes the basis no longer a basis mat = matrix([b.vector() for b in basis]) soln_space = mat.left_kernel(mat.row_space()(0)) - # the solution space is one dimensional and the last entry is non-zero + # the solution space is one dimensional and the last entry is nonzero # because a satisfies no smaller linear relation assert soln_space.dimension() == 1 (reln, ) = soln_space.basis() @@ -10133,7 +10120,7 @@ def relative_different(self): def hilbert_symbol(self, a, b, P=None): r""" Return the Hilbert symbol `(a,b)_P` for a prime `P` of ``self`` - and non-zero elements `a` and `b` of ``self``. + and nonzero elements `a` and `b` of ``self``. If `P` is omitted, return the global Hilbert symbol `(a,b)` instead. @@ -10141,21 +10128,19 @@ def hilbert_symbol(self, a, b, P=None): - ``a``, ``b`` -- elements of ``self`` - - ``P`` -- (default: ``None``) If ``None``, compute the global + - ``P`` -- (default: ``None``) if ``None``, compute the global symbol. Otherwise, `P` should be either a prime ideal of ``self`` (which may also be given as a generator or set of generators) or a real or complex embedding. - OUTPUT: - - If `a` or `b` is zero, returns 0. + OUTPUT: if `a` or `b` is zero, returns 0 - If `a` and `b` are non-zero and `P` is specified, returns + If `a` and `b` are nonzero and `P` is specified, returns the Hilbert symbol `(a,b)_P`, which is `1` if the equation `a x^2 + b y^2 = 1` has a solution in the completion of ``self`` at `P`, and is `-1` otherwise. - If `a` and `b` are non-zero and `P` is unspecified, returns `1` + If `a` and `b` are nonzero and `P` is unspecified, returns `1` if the equation has a solution in ``self`` and `-1` otherwise. EXAMPLES: @@ -10366,11 +10351,11 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): INPUT: - - ``S`` -- a list of places (or prime ideals) of even cardinality - - ``b`` -- a non-zero rational number which is a non-square locally - at every place in `S`. - - ``check`` -- bool (default: ``True``) perform additional checks on - the input and confirm the output + - ``S`` -- list of places (or prime ideals) of even cardinality + - ``b`` -- a nonzero rational number which is a non-square locally + at every place in `S` + - ``check`` -- boolean (default: ``True``); perform additional checks + on the input and confirm the output OUTPUT: @@ -10543,9 +10528,7 @@ def hilbert_conductor(self, a, b): - ``a``, ``b`` -- elements of the number field ``self`` - OUTPUT: - - squarefree ideal of the ring of integers of ``self`` + OUTPUT: squarefree ideal of the ring of integers of ``self`` EXAMPLES:: @@ -10589,9 +10572,7 @@ def elements_of_bounded_height(self, **kwds): This is an implementation of the revised algorithm (Algorithm 4) in [DK2013]_. Algorithm 5 is used for imaginary quadratic fields. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- a real number @@ -10599,9 +10580,7 @@ def elements_of_bounded_height(self, **kwds): - ``precision`` -- (default: 53) a positive integer - OUTPUT: - - an iterator of number field elements + OUTPUT: an iterator of number field elements EXAMPLES: @@ -10959,7 +10938,7 @@ def _magma_init_(self, magma): Function returning a string to create this cyclotomic field in Magma. - .. note:: + .. NOTE:: The Magma generator name is also initialized to be the same as for the Sage field. @@ -11401,11 +11380,11 @@ def _coerce_from_other_cyclotomic_field(self, x, only_canonical=False): INPUT: - - ``x`` -- number field element + - ``x`` -- number field element - - ``only_canonical`` -- bool (default: ``False``); Attempt - to work, even in some cases when `x` is not in a subfield of the - cyclotomics (as long as `x` is a root of unity). + - ``only_canonical`` -- boolean (default: ``False``); attempt + to work, even in some cases when `x` is not in a subfield of the + cyclotomics (as long as `x` is a root of unity) EXAMPLES:: @@ -11780,9 +11759,9 @@ def discriminant(self, v=None): INPUT: - - ``v`` -- (optional) list of elements of this number field + - ``v`` -- (optional) list of elements of this number field - OUTPUT: Integer if ``v`` is omitted, and Rational otherwise. + OUTPUT: integer if ``v`` is omitted, and Rational otherwise EXAMPLES:: @@ -11910,15 +11889,15 @@ def zeta(self, n=None, all=False): Return an element of multiplicative order `n` in this cyclotomic field. - If there is no such element, raise a :class:`ValueError`. + If there is no such element, raise a :exc:`ValueError`. INPUT: - ``n`` -- integer (default: ``None``, returns element of maximal order) - - ``all`` -- bool (default: ``False``); whether to return - a list of all primitive `n`-th roots of unity. + - ``all`` -- boolean (default: ``False``); whether to return + a list of all primitive `n`-th roots of unity OUTPUT: root of unity or list @@ -12187,7 +12166,6 @@ def _polymake_init_(self): sage: Z = QuadraticField(7) sage: polymake(Z) # optional - jupymake # indirect doctest QuadraticExtension - """ return '"QuadraticExtension"' @@ -12199,11 +12177,9 @@ def discriminant(self, v=None): INPUT: + - ``v`` -- (optional) list of element of this number field - - ``v`` -- (optional) list of element of this number field - - - OUTPUT: Integer if ``v`` is omitted, and Rational otherwise. + OUTPUT: integer if ``v`` is omitted, and Rational otherwise EXAMPLES:: @@ -12293,7 +12269,6 @@ def class_number(self, proof=None): sage: type(CyclotomicField(10).class_number()) - """ proof = proof_flag(proof) try: @@ -12308,7 +12283,7 @@ def hilbert_class_field_defining_polynomial(self, name='x'): Hilbert class field of this quadratic field as an extension of this quadratic field. - .. note:: + .. NOTE:: Computed using PARI via Schertz's method. This implementation is quite fast. @@ -12343,7 +12318,7 @@ def hilbert_class_field(self, names): Return the Hilbert class field of this quadratic field as a relative extension of this field. - .. note:: + .. NOTE:: For the polynomial that defines this field as a relative extension, see the method :meth:`hilbert_class_field_defining_polynomial`, @@ -12517,13 +12492,11 @@ def put_natural_embedding_first(v): INPUT: - - ``v`` -- a list of embeddings of a number field + - ``v`` -- list of embeddings of a number field - OUTPUT: ``None``. The - list is altered in-place, so that, if possible, the first embedding - has been switched with one of the others, so that if there is an - embedding which preserves the generator names then it appears - first. + OUTPUT: none; the list is altered in-place, so that, if possible, the first + embedding has been switched with one of the others, so that if there is an + embedding which preserves the generator names then it appears first. EXAMPLES:: @@ -12563,12 +12536,12 @@ def refine_embedding(e, prec=None): INPUT: - - ``e`` -- an embedding of a number field into either - `\RR` or `\CC` (with some precision) + - ``e`` -- an embedding of a number field into either `\RR` or `\CC` + (with some precision) - - ``prec`` -- (default ``None``) the desired precision; if ``None``, - current precision is doubled; if ``Infinity``, the equivalent - embedding into either ``QQbar`` or ``AA`` is returned. + - ``prec`` -- (default: ``None``) the desired precision; if ``None``, + current precision is doubled; if ``Infinity``, the equivalent + embedding into either ``QQbar`` or ``AA`` is returned. EXAMPLES:: @@ -12700,7 +12673,7 @@ def refine_embedding(e, prec=None): def is_real_place(v): r""" - Return ``True`` if `v` is real, ``False`` if `v` is complex + Return ``True`` if `v` is real, ``False`` if `v` is complex. INPUT: @@ -12732,7 +12705,6 @@ def is_real_place(v): Traceback (most recent call last): ... AttributeError: 'NumberFieldFractionalIdeal' object has no attribute 'im_gens'... - """ RR = sage.rings.real_mpfr.RealField(53) try: @@ -12776,7 +12748,6 @@ def _splitting_classes_gens_(K, m, d): 11 sage: _splitting_classes_gens_(L,11,5) # needs sage.libs.gap # optional - gap_package_polycyclic [10] - """ from sage.groups.abelian_gps.abelian_group import AbelianGroup diff --git a/src/sage/rings/number_field/number_field_base.pyx b/src/sage/rings/number_field/number_field_base.pyx index 651ff62f7c1..910f6ff7904 100644 --- a/src/sage/rings/number_field/number_field_base.pyx +++ b/src/sage/rings/number_field/number_field_base.pyx @@ -256,9 +256,7 @@ cdef class NumberField(Field): :meth:`~bach_bound` - OUTPUT: - - symbolic expression or Rational + OUTPUT: symbolic expression or Rational EXAMPLES: @@ -336,9 +334,7 @@ cdef class NumberField(Field): :meth:`~minkowski_bound` - OUTPUT: - - symbolic expression or the Integer 1 + OUTPUT: symbolic expression or the Integer 1 EXAMPLES: @@ -416,9 +412,7 @@ cdef class NumberField(Field): r""" Return an interval approximation of the generator of this number field. - OUTPUT: - - A real interval element with precision `53 \times 2^i`. + OUTPUT: a real interval element with precision `53 \times 2^i` EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index 8a3e006ace6..27432813b2b 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -104,7 +104,7 @@ def is_NumberFieldElement(x): sage: is_NumberFieldElement(2) doctest:warning... DeprecationWarning: is_NumberFieldElement is deprecated; - use isinstance(..., sage.structure.element.NumberFieldElement) instead + use isinstance(..., sage.rings.number_field.number_field_element_base.NumberFieldElement_base) instead See https://github.com/sagemath/sage/issues/34931 for details. False sage: x = polygen(ZZ, 'x') @@ -115,7 +115,7 @@ def is_NumberFieldElement(x): from sage.misc.superseded import deprecation deprecation(34931, 'is_NumberFieldElement is deprecated; ' - 'use isinstance(..., sage.structure.element.NumberFieldElement) instead') + 'use isinstance(..., sage.rings.number_field.number_field_element_base.NumberFieldElement_base) instead') return isinstance(x, NumberFieldElement) @@ -172,8 +172,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): """ cdef _new(self): """ - Quickly creates a new initialized NumberFieldElement with the same - parent as self. + Quickly create a new initialized NumberFieldElement with the same + parent as ``self``. """ cdef type t = type(self) cdef NumberFieldElement x = t.__new__(t) @@ -184,8 +184,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): cdef number_field(self): r""" + Return the number field of ``self``. Only accessible from Cython. - Return the number field of self. Only accessible from Cython. EXAMPLES:: sage: x = polygen(ZZ, 'x') @@ -210,9 +210,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): """ INPUT: - - ``parent`` -- a number field + - ``parent`` -- a number field - - ``f`` -- defines an element of a number field. + - ``f`` -- defines an element of a number field EXAMPLES: @@ -308,7 +308,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _lift_cyclotomic_element(self, new_parent, bint check=True, int rel=0): """ - Creates an element of the passed field from this field. This is + Create an element of the passed field from this field. This is specific to creating elements in a cyclotomic field from elements in another cyclotomic field, in the case that self.number_field()._n() divides new_parent()._n(). This @@ -449,7 +449,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): b^2 + 1 sage: (a+1)._im_gens_(m, [b^2]) b^2 + 1 - """ # NOTE -- if you ever want to change this so relative number # fields are in terms of a root of a poly. The issue is that @@ -467,7 +466,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _latex_(self): r""" - Returns the latex representation for this element. + Return the latex representation for this element. EXAMPLES:: @@ -480,7 +479,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _gap_init_(self): """ - Return gap string representation of self. + Return gap string representation of ``self``. EXAMPLES:: @@ -599,7 +598,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def __pari__(self, name='y'): r""" - Return PARI representation of self. + Return PARI representation of ``self``. The returned element is a PARI ``POLMOD`` in the variable ``name``, which is by default 'y' - not the name of the generator @@ -607,7 +606,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``name`` -- (default: 'y') the PARI variable name used. + - ``name`` -- (default: ``'y'``) the PARI variable name used EXAMPLES:: @@ -698,7 +697,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _pari_init_(self, name='y'): """ - Return PARI/GP string representation of self. + Return PARI/GP string representation of ``self``. The returned string defines a PARI ``POLMOD`` in the variable ``name``, which is by default 'y' - not the name of the generator @@ -706,7 +705,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``name`` -- (default: 'y') the PARI variable name used. + - ``name`` -- (default: ``'y'``) the PARI variable name used EXAMPLES:: @@ -882,11 +881,11 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``num_bound`` -- Bound for the numerator of coefficients of result + - ``num_bound`` -- bound for the numerator of coefficients of result - - ``den_bound`` -- Bound for the denominator of coefficients of result + - ``den_bound`` -- bound for the denominator of coefficients of result - - ``distribution`` -- Distribution to use for coefficients of result + - ``distribution`` -- distribution to use for coefficients of result EXAMPLES:: @@ -1156,7 +1155,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): mpfi_set_prec(a, mpfi_get_prec(v.value)) ZZX_evaluation_mpfi(a, self._numerator, v.value) mpfi_div_z(a, a, den) - mpfr_floor(&a.left ,&a.left) + mpfr_floor(&a.left, &a.left) mpfr_floor(&a.right, &a.right) ans = PY_NEW(Integer) @@ -1293,12 +1292,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: + - ``prec`` -- integer (default: ``None``); bits of precision - - ``prec`` -- (default: None) integer bits of precision - - - ``i`` -- (default: None) integer, which embedding to - use - + - ``i`` -- integer (default: ``None``); which embedding to use EXAMPLES:: @@ -1357,7 +1353,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: b.abs(prec=53) 1.32471795724475 - """ if (i is None and prec is None and ( self._parent)._embedded_real): @@ -1380,10 +1375,10 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``P`` -- a prime ideal of the parent of ``self`` + - ``P`` -- a prime ideal of the parent of ``self`` - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -1392,7 +1387,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): normalised absolute value, so that the underlying prime number `p` has absolute value `1/p`. - EXAMPLES:: sage: x = polygen(ZZ, 'x') @@ -1489,9 +1483,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - - ``prec`` -- integer (default: 53) bits of precision - + - ``prec`` -- integer (default: 53); bits of precision EXAMPLES:: @@ -1571,11 +1563,11 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``L`` -- a number field containing `K` = ``self.parent()``. - - ``element`` -- ``True`` or ``False``, whether to also output an element - of which ``self`` is a norm. - - ``proof`` -- If ``True``, then the output is correct unconditionally. - If ``False``, then the output is correct under GRH. + - ``L`` -- a number field containing `K` = ``self.parent()`` + - ``element`` -- boolean; whether to also output an element + of which ``self`` is a norm + - ``proof`` -- if ``True``, then the output is correct unconditionally; + if ``False``, then the output is correct under GRH OUTPUT: @@ -1707,7 +1699,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): algorithm looks for a solution `x` that is an `S`-integer, with `S` a list of places of `L` containing at least the ramified primes, the generators of the class group of `L`, as well as those primes - dividing self. + dividing ``self``. If `L/K` is Galois, then this is enough; otherwise, ``extra_primes`` is used to add more primes to `S`: all the places @@ -1720,10 +1712,10 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - `L` -- a relative number field with base field ``self.parent()`` - - ``proof`` -- whether to certify outputs of PARI init functions. - If ``False``, truth of the output depends on GRH. - - ``extra_primes`` -- an integer as explained above. + - ``L`` -- a relative number field with base field ``self.parent()`` + - ``proof`` -- whether to certify outputs of PARI init functions; + if ``False``, truth of the output depends on GRH + - ``extra_primes`` -- integer; as explained above OUTPUT: @@ -1954,7 +1946,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): elements raised to appropriate powers, with an appropriate unit factor. - Raise :class:`ValueError` if the factorization of the + Raise :exc:`ValueError` if the factorization of the ideal (``self``) contains a non-principal prime ideal. EXAMPLES:: @@ -1982,7 +1974,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined - """ if self.is_zero(): raise ArithmeticError("factorization of 0 is not defined") @@ -2033,14 +2024,13 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``self``, ``other`` -- elements of a number field or maximal - order. + - ``self``, ``other`` -- elements of a number field or maximal order OUTPUT: - - A generator of the ideal ``(self, other)``. If the parent is - a number field, this always returns 0 or 1. For maximal orders, - this raises :class:`ArithmeticError` if the ideal is not principal. + A generator of the ideal ``(self, other)``. If the parent is + a number field, this always returns 0 or 1. For maximal orders, + this raises :exc:`ArithmeticError` if the ideal is not principal. EXAMPLES:: @@ -2149,10 +2139,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - - ``root`` -- if ``True``, also return a square root (or - ``None`` if ``self`` is not a perfect square) - + - ``root`` -- if ``True``, also return a square root (or ``None`` if + ``self`` is not a perfect square) EXAMPLES:: @@ -2204,7 +2192,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - ``P`` -- a prime ideal - - ``check`` -- (default: ``True``); check if `P` is prime + - ``check`` -- boolean (default: ``True``); check if `P` is prime EXAMPLES:: @@ -2222,10 +2210,10 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``all`` -- optional boolean (default ``False``); whether to return + - ``all`` -- boolean (default: ``False``); whether to return both square roots - - ``extend`` -- optional boolean (default ``True``); whether to extend + - ``extend`` -- boolean (default: ``True``); whether to extend the field by adding the square roots if needed EXAMPLES:: @@ -2304,7 +2292,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def nth_root(self, n, all=False): r""" - Return an `n`'th root of ``self`` in its parent `K`. + Return an `n`-th root of ``self`` in its parent `K`. EXAMPLES:: @@ -2330,7 +2318,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def is_nth_power(self, n): r""" - Return ``True`` if ``self`` is an `n`'th power in its parent `K`. + Return ``True`` if ``self`` is an `n`-th power in its parent `K`. EXAMPLES:: @@ -2494,7 +2482,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): cpdef _mul_(self, right): """ - Returns the product of self and other as elements of a number + Return the product of ``self`` and ``other`` as elements of a number field. EXAMPLES:: @@ -2542,7 +2530,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): cpdef _div_(self, other): """ - Returns the quotient of self and other as elements of a number + Return the quotient of ``self`` and ``other`` as elements of a number field. EXAMPLES:: @@ -2753,7 +2741,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def __invert__(self): """ - Return the multiplicative inverse of self in the number field. + Return the multiplicative inverse of ``self`` in the number field. EXAMPLES:: @@ -2792,7 +2780,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _integer_(self, Z=None): """ - Returns an integer if this element is actually an integer. + Return an integer if this element is actually an integer. EXAMPLES:: @@ -2810,7 +2798,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _rational_(self): """ - Returns a rational number if this element is actually a rational + Return a rational number if this element is actually a rational number. EXAMPLES:: @@ -2844,7 +2832,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: AA(alpha) Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real sage: NF. = NumberField(x^5 + 7*x + 3) @@ -2980,7 +2968,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: K. = NumberField(p, embedding=rt) sage: SR(a) # needs sage.symbolic -0.3056815681115094? - """ K = self._parent.fraction_field() @@ -3073,7 +3060,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): This is only well-defined for fields contained in CM fields (i.e. for totally real fields and CM fields). Recall that a CM field is a totally imaginary quadratic extension of a totally - real field. For other fields, a :class:`ValueError` is raised. + real field. For other fields, a :exc:`ValueError` is raised. EXAMPLES:: @@ -3096,7 +3083,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: j.conjugate() -j - Raise a :class:`ValueError` if the field is not contained in a CM field. + Raise a :exc:`ValueError` if the field is not contained in a CM field. :: @@ -3124,7 +3111,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): -1/2*a^3 - a - 1/2 sage: (2*a^2 - 1).conjugate() a^3 - 2*a^2 - 2 - """ nf = self.number_field() @@ -3171,7 +3157,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): 1/2*x^3 + 3*x - 1/2 sage: R(list(b)) y - """ from sage.rings.polynomial.polynomial_ring_constructor import _single_variate as Pol return Pol(QQ, var)(self._coefficients()) @@ -3235,10 +3220,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): Return the coefficients of the underlying polynomial corresponding to this number field element. - OUTPUT: - - - a list whose length corresponding to the degree of this - element written in terms of a generator + OUTPUT: list whose length corresponding to the degree of this element + written in terms of a generator EXAMPLES:: @@ -3740,9 +3723,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - - ``base`` -- field or morphism - + - ``base`` -- field or morphism EXAMPLES: @@ -3863,7 +3844,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``P`` -- a prime ideal of the parent of ``self`` + - ``P`` -- a prime ideal of the parent of ``self`` .. NOTE:: @@ -3930,18 +3911,17 @@ cdef class NumberFieldElement(NumberFieldElement_base): def local_height(self, P, prec=None, weighted=False): r""" - Returns the local height of ``self`` at a given prime ideal `P`. + Return the local height of ``self`` at a given prime ideal `P`. INPUT: - - ``P`` -- a prime ideal of the parent of ``self`` - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer; (default: default :class:`RealField` precision); + desired floating point precision - - ``weighted`` (bool, default ``False``) -- if ``True``, apply local - degree weighting. + - ``weighted`` -- boolean (default: ``False``); if ``True``, apply local + degree weighting OUTPUT: @@ -3987,23 +3967,23 @@ cdef class NumberFieldElement(NumberFieldElement_base): def local_height_arch(self, i, prec=None, weighted=False): r""" - Returns the local height of ``self`` at the `i`'th infinite place. + Return the local height of ``self`` at the `i`-th infinite place. INPUT: - - ``i`` (int) -- an integer in ``range(r+s)`` where `(r,s)` is the - signature of the parent field (so `n=r+2s` is the degree). + - ``i`` -- integer in ``range(r+s)`` where `(r,s)` is the signature of + the parent field (so `n=r+2s` is the degree) - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision - - ``weighted`` (bool, default ``False``) -- if ``True``, apply local - degree weighting, i.e. double the value for complex places. + - ``weighted`` -- boolean (default: ``False``); if ``True``, apply local + degree weighting, i.e. double the value for complex places OUTPUT: (real) The archimedean local height of this number field - element at the `i`'th infinite place. If ``weighted`` is + element at the `i`-th infinite place. If ``weighted`` is ``True``, this is multiplied by the local degree (as required for global heights), i.e. 1 for real places and 2 for complex places. @@ -4051,8 +4031,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + - ``prec`` -- integer (default: default RealField precision); desired + floating point precision OUTPUT: @@ -4101,12 +4081,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): def global_height_arch(self, prec=None): """ - Returns the total archimedean component of the height of ``self``. + Return the total archimedean component of the height of ``self``. INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -4128,12 +4108,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): def global_height(self, prec=None): """ - Returns the absolute logarithmic height of this number field element. + Return the absolute logarithmic height of this number field element. INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -4175,7 +4155,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): 0.346573590279973 sage: (1/s).global_height() #make sure that 11758 is fixed 0.346573590279973 - """ return (self.global_height_non_arch(prec)+self.global_height_arch(prec))/self.number_field().absolute_degree() @@ -4246,7 +4225,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): """ Return the support of this number field element. - OUTPUT: A sorted list of the prime ideals at which this number + OUTPUT: a sorted list of the prime ideals at which this number field element has nonzero valuation. An error is raised if the element is zero. @@ -4366,14 +4345,14 @@ cdef class NumberFieldElement(NumberFieldElement_base): def inverse_mod(self, I): r""" - Returns the inverse of ``self`` mod the integral ideal `I`. + Return the inverse of ``self`` mod the integral ideal `I`. INPUT: - - ``I`` -- may be an ideal of ``self.parent()``, or an element or list - of elements of ``self.parent()`` generating a nonzero ideal. A :class:`ValueError` - is raised if `I` is non-integral or zero. A :class:`ZeroDivisionError` is - raised if `I + (x) \neq (1)`. + - ``I`` -- may be an ideal of ``self.parent()``, or an element or list + of elements of ``self.parent()`` generating a nonzero ideal. A + :exc:`ValueError` is raised if `I` is non-integral or zero. A + :exc:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. .. NOTE:: @@ -4420,7 +4399,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): .. NOTE:: can also be called for an ideal from sage.rings.number_field_ideal.residue_symbol - .. NOTE:: self is coerced into the number field of the ideal P + .. NOTE:: ``self`` is coerced into the number field of the ideal P .. NOTE:: @@ -4433,9 +4412,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): - ``m`` -- positive integer - OUTPUT: - - - an `m`-th root of unity in the number field + OUTPUT: an `m`-th root of unity in the number field EXAMPLES: @@ -4463,35 +4440,34 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: (w^2 + 3).residue_symbol(K.ideal(17),3) -w - The field must contain the m-th roots of unity:: + The field must contain the `m`-th roots of unity:: sage: K. = NumberField(x^2 - x + 1) sage: (w^2 + 3).residue_symbol(K.ideal(17),5) Traceback (most recent call last): ... ValueError: The residue symbol to that power is not defined for the number field - """ return P.residue_symbol(self,m,check) def descend_mod_power(self, K=QQ, d=2): r""" Return a list of elements of the subfield `K` equal to - ``self`` modulo `d`'th powers. + ``self`` modulo `d`-th powers. INPUT: - - ``K`` (number field, default `\QQ`) -- a subfield of the + - ``K`` -- number field (default: `\QQ`); a subfield of the parent number field `L` of ``self`` - - ``d`` (positive integer, default 2) -- an integer at least 2 + - ``d`` -- positive integer (default: 2); an integer at least 2 OUTPUT: A list, possibly empty, of elements of `K` equal to ``self`` - modulo `d`'th powers, i.e. the preimages of ``self`` under the + modulo `d`-th powers, i.e. the preimages of ``self`` under the map `K^*/(K^*)^d \rightarrow L^*/(L^*)^d` where `L` is the - parent of ``self``. A :class:`ValueError` is raised if `K` does + parent of ``self``. A :exc:`ValueError` is raised if `K` does not embed into `L`. ALGORITHM: @@ -4650,12 +4626,10 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): INPUT: - - - ``magma`` -- a Magma interpreter - + - ``magma`` -- a Magma interpreter OUTPUT: MagmaElement that has parent the Magma object corresponding - to the parent number field. + to the parent number field EXAMPLES:: @@ -4860,7 +4834,6 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): sage: K. = QuadraticField(-3) sage: a.lift() x - """ R = self.number_field().base_field()[var] return R(self.list()) @@ -4924,7 +4897,7 @@ cdef class NumberFieldElement_relative(NumberFieldElement): The current relative number field element implementation does everything in terms of absolute polynomials. - All conversions from relative polynomials, lists, vectors, etc + All conversions from relative polynomials, lists, vectors, etc. should happen in the parent. """ def __init__(self, parent, f): @@ -5021,7 +4994,6 @@ cdef class NumberFieldElement_relative(NumberFieldElement): sage: u = L(1/2*a + 1/2 + b + (a-9)*b^5) sage: u.lift() (a - 9)*x^5 + x + 1/2*a + 1/2 - """ K = self.number_field() # Compute representation of self in terms of relative vector space. @@ -5191,7 +5163,8 @@ cdef class NumberFieldElement_relative(NumberFieldElement): INPUT: - - ``P`` -- a prime ideal of relative number field which is the parent of ``self`` + - ``P`` -- a prime ideal of relative number field which is the parent + of ``self`` EXAMPLES:: @@ -5247,7 +5220,7 @@ cdef class OrderElement_absolute(NumberFieldElement_absolute): cdef _new(self): """ - Quickly creates a new initialized NumberFieldElement with the same + Quickly create a new initialized NumberFieldElement with the same parent as ``self``. EXAMPLES: @@ -5288,10 +5261,10 @@ cdef class OrderElement_absolute(NumberFieldElement_absolute): INPUT: - - ``I`` -- may be an ideal of ``self.parent()``, or an - element or list of elements of ``self.parent()`` generating a nonzero - ideal. A :class:`ValueError` is raised if `I` is non-integral or is zero. - A :class:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. + - ``I`` -- may be an ideal of ``self.parent()``, or an element or list + of elements of ``self.parent()`` generating a nonzero ideal. A + :exc:`ValueError` is raised if `I` is non-integral or is zero. A + :exc:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. EXAMPLES:: @@ -5366,8 +5339,8 @@ cdef class OrderElement_relative(NumberFieldElement_relative): cdef _new(self): """ - Quickly creates a new initialized NumberFieldElement with the same - parent as self. + Quickly create a new initialized NumberFieldElement with the same + parent as ``self``. EXAMPLES: @@ -5420,12 +5393,10 @@ cdef class OrderElement_relative(NumberFieldElement_relative): INPUT: - - - ``I`` -- may be an ideal of ``self.parent()``, or an - element or list of elements of ``self.parent()`` generating a nonzero - ideal. A :class:`ValueError` is raised if `I` is non-integral or is zero. - A :class:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. - + - ``I`` -- may be an ideal of ``self.parent()``, or an + element or list of elements of ``self.parent()`` generating a nonzero + ideal. A :exc:`ValueError` is raised if `I` is non-integral or is zero. + A :exc:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. EXAMPLES:: @@ -5631,7 +5602,7 @@ class CoordinateFunction(): def __eq__(self, other): """ - Test equality + Test equality. EXAMPLES:: @@ -5657,7 +5628,7 @@ class CoordinateFunction(): def __ne__(self, other): """ - Test inequality + Test inequality. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_element_base.pyx b/src/sage/rings/number_field/number_field_element_base.pyx index 5fee5817cbc..759209f8bb3 100644 --- a/src/sage/rings/number_field/number_field_element_base.pyx +++ b/src/sage/rings/number_field/number_field_element_base.pyx @@ -13,10 +13,11 @@ Number field elements (abstract base class) cdef class NumberFieldElement_base(FieldElement): r""" - Abstract base class for :class:`~sage.rings.number_field.number_field_element.NumberFieldElement` + Abstract base class for + :class:`~sage.rings.number_field.number_field_element.NumberFieldElement`. - This class is defined for the purpose of :func:`isinstance` tests. It should not be - instantiated. + This class is defined for the purpose of :func:`isinstance` tests. + It should not be instantiated. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index ef924174a9e..a0e90d1d63d 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -227,8 +227,8 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): cdef _new(self): """ - Quickly creates a new initialized NumberFieldElement_quadratic with the - same parent as self. + Quickly create a new initialized NumberFieldElement_quadratic with the + same parent as ``self``. EXAMPLES:: @@ -472,7 +472,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def _lift_cyclotomic_element(self, new_parent, bint check=True, int rel=0): """ - Creates an element of the passed field from this field. This + Create an element of the passed field from this field. This is specific to creating elements in a cyclotomic field from elements in another cyclotomic field, in the case that self.number_field()._n() divides new_parent()._n(). This @@ -943,7 +943,8 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def sign(self): r""" - Returns the sign of ``self`` (`0` if zero, `+1` if positive, and `-1` if negative). + Return the sign of ``self`` (`0` if zero, `+1` if positive, and `-1` if + negative). EXAMPLES:: @@ -1296,7 +1297,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): r""" Reduces into canonical form. - WARNING: this mutates self. + WARNING: this mutates ``self``. """ cdef mpz_t gcd # cancel out common factors @@ -1470,7 +1471,6 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: K. = QuadraticField(5, embedding=AA(5).sqrt()) sage: sqrt5*vector([1,2]) (sqrt5, 2*sqrt5) - """ cdef NumberFieldElement_quadratic other = other_m cdef NumberFieldElement_quadratic res = self._new() @@ -2072,7 +2072,6 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): Traceback (most recent call last): ... ValueError: no way to embed L into parent's base ring K - """ cdef Rational res = Rational.__new__(Rational) @@ -2188,8 +2187,9 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified, this defaults to ``'x'`` - - ``algorithm`` -- for compatibility with general number field elements; ignored + in a variable with this name; if not specified, this defaults to ``'x'`` + - ``algorithm`` -- for compatibility with general number field + elements; ignored EXAMPLES:: @@ -2213,8 +2213,9 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified, this defaults to ``'x'`` - - ``algorithm`` -- for compatibility with general number field elements: and ignored + in a variable with this name; if not specified, this defaults to ``'x'`` + - ``algorithm`` -- for compatibility with general number field + elements; ignored EXAMPLES:: @@ -2262,7 +2263,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def floor(self): r""" - Returns the floor of ``self``. + Return the floor of ``self``. EXAMPLES:: @@ -2728,9 +2729,9 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified, this defaults to ``'x'`` - - ``algorithm`` -- for compatibility with general number field elements; ignored - + in a variable with this name; if not specified, this defaults to ``'x'`` + - ``algorithm`` -- for compatibility with general number field + elements; ignored EXAMPLES:: @@ -2755,8 +2756,9 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified, this defaults to ``'x'`` - - ``algorithm`` -- for compatibility with general number field elements; ignored + in a variable with this name; if not specified, this defaults to ``'x'`` + - ``algorithm`` -- for compatibility with general number field + elements; ignored EXAMPLES:: @@ -2849,10 +2851,10 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): INPUT: - - ``I`` -- may be an ideal of ``self.parent()``, or an - element or list of elements of ``self.parent()`` generating a nonzero - ideal. A :class:`ValueError` is raised if `I` is non-integral or is zero. - A :class:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. + - ``I`` -- may be an ideal of ``self.parent()``, or an + element or list of elements of ``self.parent()`` generating a nonzero + ideal. A :exc:`ValueError` is raised if `I` is non-integral or is zero. + A :exc:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. EXAMPLES:: @@ -2864,7 +2866,7 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): -13 sage: w.inverse_mod(13).parent() == OE True - sage: w.inverse_mod(2*OE) + sage: w.inverse_mod(2) Traceback (most recent call last): ... ZeroDivisionError: w is not invertible modulo Fractional ideal (2) @@ -2956,7 +2958,7 @@ cdef class Z_to_quadratic_field_element(Morphism): def __init__(self, K): """ - ``K`` is the target quadratic field + ``K`` is the target quadratic field. EXAMPLES:: @@ -3058,7 +3060,9 @@ cdef class Q_to_quadratic_field_element(Morphism): def __init__(self, K): """ - ``K`` is the target quadratic field + INPUT: + + - ``K`` -- the target quadratic field EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index b9d7e0ad781..3686840ccba 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -100,7 +100,8 @@ def __init__(self, field, gens, coerce=True): - ``field`` -- a number field - - ``gens`` -- a list of :class:`NumberFieldElement` objects belonging to the field + - ``gens`` -- list of :class:`NumberFieldElement` objects belonging to + the field TESTS: @@ -144,12 +145,9 @@ def _magma_init_(self, magma): INPUT: + - ``magma`` -- a Magma interpreter - - ``magma`` -- a Magma interpreter - - - OUTPUT: :class:`MagmaElement` corresponding to this ideal. - + OUTPUT: :class:`MagmaElement` corresponding to this ideal EXAMPLES:: @@ -302,7 +300,8 @@ def coordinates(self, x): INPUT: - - ``x`` -- an element of the number field (or ring of integers) of this ideal. + - ``x`` -- an element of the number field (or ring of integers) of this + ideal OUTPUT: @@ -427,11 +426,11 @@ def __elements_from_hnf(self, hnf): K = self.number_field() return [K(x, check=False) for x in K.pari_zk() * hnf] - def __repr__(self): + def _repr_(self): """ Return the string representation of this number field ideal. - .. note:: + .. NOTE:: Only the zero ideal actually has type NumberFieldIdeal; all others have type NumberFieldFractionalIdeal. So this function @@ -556,7 +555,7 @@ def __pari__(self): def _pari_init_(self): """ - Return self in PARI Hermite Normal Form as a string + Return ``self`` in PARI Hermite Normal Form as a string. EXAMPLES:: @@ -726,9 +725,9 @@ def free_module(self): def reduce_equiv(self): """ - Return a small ideal that is equivalent to self in the group + Return a small ideal that is equivalent to ``self`` in the group of fractional ideals modulo principal ideals. Very often (but - not always) if self is principal then this function returns + not always) if ``self`` is principal then this function returns the unit ideal. ALGORITHM: Calls :pari:`idealred` function. @@ -848,7 +847,6 @@ def gens_two(self): [12, [0, 12]~] sage: I.gens_two() (12, 0) - """ try: return self.__two_generators @@ -1065,7 +1063,7 @@ def pari_prime(self): INPUT: - - ``self`` -- a prime ideal. + - ``self`` -- a prime ideal OUTPUT: a PARI "prime ideal", i.e. a five-component vector `[p,a,e,f,b]` representing the prime ideal `p O_K + a O_K`, `e`, `f` as usual, `a` as @@ -1097,10 +1095,10 @@ def _cache_bnfisprincipal(self, proof=None, gens=False): - ``self`` -- an ideal - - ``proof`` -- proof flag. If ``proof=False``, assume GRH. + - ``proof`` -- proof flag. If ``proof=False``, assume GRH - - ``gens`` -- (default: ``False``) if True, also computes the reduced - generators of the ideal. + - ``gens`` -- boolean (default: ``False``); if ``True``, also computes + the reduced generators of the ideal OUTPUT: @@ -1271,7 +1269,7 @@ def S_ideal_class_log(self, S): def is_zero(self): """ - Return ``True`` iff ``self`` is the zero ideal + Return ``True`` iff ``self`` is the zero ideal. Note that `(0)` is a :class:`NumberFieldIdeal`, not a :class:`NumberFieldFractionalIdeal`. @@ -1386,7 +1384,7 @@ def number_field(self): def smallest_integer(self): r""" - Return the smallest non-negative integer in `I \cap \ZZ`, + Return the smallest nonnegative integer in `I \cap \ZZ`, where `I` is this ideal. If `I = 0`, returns 0. EXAMPLES:: @@ -1443,17 +1441,17 @@ def smallest_integer(self): def valuation(self, p): r""" - Return the valuation of self at ``p``. + Return the valuation of ``self`` at ``p``. INPUT: - - ``p`` -- a prime ideal `\mathfrak{p}` of this number field. + - ``p`` -- a prime ideal `\mathfrak{p}` of this number field OUTPUT: (integer) The valuation of this fractional ideal at the prime `\mathfrak{p}`. If `\mathfrak{p}` is not prime, raise a - :class:`ValueError`. + :exc:`ValueError`. EXAMPLES:: @@ -1503,10 +1501,10 @@ def decomposition_group(self): def ramification_group(self, v): r""" - Return the `v`'th ramification group of ``self``, i.e. the set of + Return the `v`-th ramification group of ``self``, i.e. the set of elements `s` of the Galois group of the number field of ``self`` (which we assume is Galois) such that `s` acts trivially - modulo the `(v+1)`'st power of self. See the + modulo the `(v+1)`'st power of ``self``. See the :meth:`GaloisGroup.ramification_group` method for further examples and doctests. @@ -1541,7 +1539,7 @@ def random_element(self, *args, **kwds): INPUT: - - ``*args``, ``*kwds`` -- Parameters passed to the random integer + - ``*args``, ``*kwds`` -- parameters passed to the random integer function. See the documentation of ``ZZ.random_element()`` for details. @@ -1557,7 +1555,7 @@ def random_element(self, *args, **kwds): sage: I = K.ideal(1 - a) sage: I.random_element() # random output -a^2 - a - 19 - sage: I.random_element(distribution="uniform") # random output + sage: I.random_element(distribution='uniform') # random output a^2 - 2*a - 8 sage: I.random_element(-30, 30) # random output -7*a^2 - 17*a - 75 @@ -1607,13 +1605,13 @@ def residue_symbol(self, e, m, check=True): .. MATH:: \left(\frac{\alpha}{\mathbf{P}}\right) \equiv \alpha^{\frac{N(\mathbf{P})-1}{m}} \operatorname{mod} \mathbf{P} - .. note:: accepts `m=1`, in which case returns 1 + .. NOTE:: accepts `m=1`, in which case returns 1 - .. note:: can also be called for an element from sage.rings.number_field_element.residue_symbol + .. NOTE:: can also be called for an element from sage.rings.number_field_element.residue_symbol - .. note:: `e` is coerced into the number field of ``self`` + .. NOTE:: `e` is coerced into the number field of ``self`` - .. note:: + .. NOTE:: if `m=2`, `e` is an integer, and ``self.number_field()`` has absolute degree 1 (i.e. it is a copy of the rationals), then this calls :func:`kronecker_symbol`, which is implemented using GMP. @@ -1624,9 +1622,7 @@ def residue_symbol(self, e, m, check=True): - ``m`` -- positive integer - OUTPUT: - - - an m-th root of unity in the number field + OUTPUT: an `m`-th root of unity in the number field EXAMPLES: @@ -1650,7 +1646,6 @@ def residue_symbol(self, e, m, check=True): Traceback (most recent call last): ... ValueError: The residue symbol to that power is not defined for the number field - """ K = self.ring() if m == 2 and K.absolute_degree() == 1: @@ -1780,6 +1775,7 @@ def basis_to_module(B, K): C = [to_V(K(b)) for b in B] return M.span_of_basis(C) + def is_NumberFieldIdeal(x): """ Return ``True`` if `x` is an ideal of a number field. @@ -1840,8 +1836,9 @@ class NumberFieldFractionalIdeal(MultiplicativeGroupElement, NumberFieldIdeal, I def __init__(self, field, gens, coerce=True): """ INPUT: - field -- a number field - x -- a list of NumberFieldElements of the field, not all zero + + - ``field`` -- a number field + - ``x`` -- list of NumberFieldElements of the field, not all zero EXAMPLES:: @@ -1862,11 +1859,11 @@ def __init__(self, field, gens, coerce=True): else: raise ValueError("gens must have a nonzero element (zero ideal is not a fractional ideal)") - def __repr__(self): + def _repr_(self): """ Return the string representation of this number field fractional ideal. - .. note:: + .. NOTE:: Only the zero ideal actually has type NumberFieldIdeal; all others have type NumberFieldFractionalIdeal. @@ -1884,7 +1881,7 @@ def __repr__(self): def divides(self, other): """ - Return ``True`` if this ideal divides other and False otherwise. + Return ``True`` if this ideal divides ``other`` and ``False`` otherwise. EXAMPLES:: @@ -2060,7 +2057,7 @@ def is_trivial(self, proof=None): def ramification_index(self): r""" Return the ramification index of this fractional ideal, - assuming it is prime. Otherwise, raise a :class:`ValueError`. + assuming it is prime. Otherwise, raise a :exc:`ValueError`. The ramification index is the power of this prime appearing in the factorization of the prime in `\ZZ` that this prime lies @@ -2108,7 +2105,7 @@ def reduce(self, f): - `d_i = b_i[i]`, with `\{b_0, b_1, \dots, b_n\}` HNF basis of the ideal ``self``. - .. note:: + .. NOTE:: The reduced element `g` is not necessarily small. To get a small `g` use the method :meth:`small_residue`. @@ -2164,7 +2161,7 @@ def reduce(self, f): R = self.number_field().maximal_order() - if not (f in R): + if f not in R: raise TypeError("reduce only defined for integral elements") Rbasis = R.basis() @@ -2194,7 +2191,7 @@ def residues(self): OUTPUT: An iterator through a complete list of residues modulo the integral - ideal self. This list is the set of canonical reduced representatives + ideal ``self``. This list is the set of canonical reduced representatives given by all integral elements with coordinates `(r_0, \dots,r_{n-1})`, where: @@ -2258,8 +2255,8 @@ def invertible_residues(self, reduce=True): INPUT: - - ``reduce`` -- bool. If ``True`` (default), use ``small_residue`` to get - small representatives of the residues. + - ``reduce`` -- boolean; if ``True`` (default), use ``small_residue`` to get + small representatives of the residues OUTPUT: @@ -2324,10 +2321,10 @@ def invertible_residues_mod(self, subgp_gens=[], reduce=True): an iterator through a list of representatives for the invertible residues modulo the integral ideal ``self``. - - ``reduce`` -- bool. If ``True`` (default), use ``small_residues`` to - get small representatives of the residues. + - ``reduce`` -- boolean; if ``True`` (default), use ``small_residues`` to + get small representatives of the residues - .. note:: + .. NOTE:: See also :meth:`invertible_residues` for a simpler version without the subgroup. @@ -2474,13 +2471,11 @@ def is_coprime(self, other): INPUT: - ``other`` -- another ideal of the same field, or generators - of an ideal. + of an ideal - OUTPUT: - - ``True`` if ``self`` and ``other`` are coprime, else ``False``. + OUTPUT: ``True`` if ``self`` and ``other`` are coprime, else ``False`` - .. note:: + .. NOTE:: This function works for fractional ideals as well as integral ideals. @@ -2540,11 +2535,10 @@ def idealcoprime(self, J): INPUT: - - ``J`` -- another integral ideal of the same field as ``self``, which must also be integral. - - OUTPUT: + - ``J`` -- another integral ideal of the same field as ``self``, which + must also be integral - an element `l` such that ``l*self`` is coprime to the ideal `J` + OUTPUT: an element `l` such that ``l*self`` is coprime to the ideal `J` .. TODO:: @@ -2593,7 +2587,7 @@ def small_residue(self, f): element `g` such that `f - g` belongs to the ideal ``self`` (which must be integral), and `g` is small. - .. note:: + .. NOTE:: The reduced representative returned is not uniquely determined. @@ -2615,7 +2609,6 @@ def small_residue(self, f): sage: I = K.ideal(5) sage: I.small_residue(a^2 -13) a^2 + 5*a - 3 - """ if not self.is_integral(): raise ValueError("The ideal must be integral") @@ -2632,9 +2625,7 @@ def _pari_bid_(self, flag=1): `(O_K/I)^*`, which takes more time. By default ``flag=1`` (no generators are computed). - OUTPUT: - - - The pari special structure ``bid``. + OUTPUT: the PARI special structure ``bid`` EXAMPLES:: @@ -2668,11 +2659,11 @@ def idealstar(self, flag=1): INPUT: - - ``flag`` (int default 1) -- when ``flag`` =2, it also + - ``flag`` -- integer (default: 1); when ``flag==2``, it also computes the generators of the group `(O_K/I)^*`, which - takes more time. By default ``flag`` =1 (no generators are + takes more time. By default ``flag`` is 1 (no generators are computed). In both cases the special PARI structure ``bid`` - is computed as well. If ``flag`` =0 (deprecated) it computes + is computed as well. If ``flag`` is 0 (deprecated) it computes only the group structure of `(O_K/I)^*` (with generators) and not the special ``bid`` structure. @@ -2680,7 +2671,7 @@ def idealstar(self, flag=1): The finite abelian group `(O_K/I)^*`. - .. note:: + .. NOTE:: Uses the PARI function :pari:`idealstar`. The PARI function outputs a special ``bid`` structure which is stored in the internal @@ -2738,26 +2729,26 @@ def ideallog(self, x, gens=None, check=True): INPUT: - - ``x`` -- a non-zero element of the number field of ``self``, + - ``x`` -- a nonzero element of the number field of ``self``, which must have valuation equal to 0 at all prime ideals in - the support of the ideal ``self``. - - ``gens`` -- a list of elements of the number field which generate `(R + the support of the ideal ``self`` + - ``gens`` -- list of elements of the number field which generate `(R / I)^*`, where `R` is the ring of integers of the field and `I` is this ideal, or ``None``. If ``None``, use the generators calculated by :meth:`~idealstar`. - - ``check`` -- if ``True``, do a consistency check on the results. Ignored - if ``gens`` is ``None``. + - ``check`` -- if ``True``, do a consistency check on the results. + Ignored if ``gens`` is ``None``. OUTPUT: - a list of non-negative integers `(x_i)` such that `x = + a list of nonnegative integers `(x_i)` such that `x = \prod_i g_i^{x_i}` in `(R/I)^*`, where `x_i` are the generators, and the list `(x_i)` is lexicographically minimal with respect to this requirement. If the `x_i` generate independent cyclic factors of order `d_i`, as is the case for the default generators calculated by :meth:`~idealstar`, this just means that `0 \le x_i < d_i`. - A :class:`ValueError` will be raised if the elements specified in ``gens`` + A :exc:`ValueError` will be raised if the elements specified in ``gens`` do not in fact generate the unit group (even if the element `x` is in the subgroup they generate). @@ -2857,7 +2848,7 @@ def ideallog(self, x, gens=None, check=True): def element_1_mod(self, other): r""" - Return an element `r` in this ideal such that `1-r` is in ``other`` + Return an element `r` in this ideal such that `1-r` is in ``other``. An error is raised if either ideal is not integral of if they are not coprime. @@ -2865,11 +2856,10 @@ def element_1_mod(self, other): INPUT: - ``other`` -- another ideal of the same field, or generators - of an ideal. - - OUTPUT: + of an ideal - An element `r` of the ideal self such that `1-r` is in the ideal ``other`` + OUTPUT: an element `r` of the ideal ``self`` such that `1-r` is in the + ideal ``other`` AUTHOR: Maite Aranes (modified to use PARI's :pari:`idealaddtoone` by Francis Clarke) @@ -2975,7 +2965,7 @@ def prime_to_S_part(self, S): INPUT: - - ``S`` -- a list of prime ideals + - ``S`` -- list of prime ideals OUTPUT: @@ -3015,10 +3005,10 @@ def is_S_unit(self, S): INPUT: - - ``S`` -- a list of prime ideals (not checked if they are - indeed prime). + - ``S`` -- list of prime ideals (not checked if they are + indeed prime) - .. note:: + .. NOTE:: This function assumes that `S` is a list of prime ideals, but does not check this. This function will fail if `S` is @@ -3046,10 +3036,9 @@ def is_S_integral(self, S): INPUT: - - `S` -- a list of prime ideals (not checked if they are indeed - prime). + - ``S`` -- list of prime ideals (not checked if they are indeed prime) - .. note:: + .. NOTE:: This function assumes that `S` is a list of prime ideals, but does not check this. This function will fail if `S` is @@ -3058,7 +3047,7 @@ def is_S_integral(self, S): OUTPUT: ``True``, if the ideal is `S`-integral: that is, if the valuations - of the ideal at all primes not in `S` are non-negative. ``False``, + of the ideal at all primes not in `S` are nonnegative. ``False``, otherwise. EXAMPLES:: @@ -3087,9 +3076,7 @@ def prime_to_idealM_part(self, M): - ``M`` -- an integral ideal of the same field, or generators of an ideal - OUTPUT: - - An ideal which is the largest divisor of ``self`` that is coprime to `M`. + OUTPUT: an ideal which is the largest divisor of ``self`` that is coprime to `M` AUTHOR: Maite Aranes @@ -3136,10 +3123,10 @@ def _p_quotient(self, p): OUTPUT: - - `V` -- a vector space of characteristic `p` + - ``V`` -- a vector space of characteristic `p` - ``quo`` -- a partially defined quotient homomorphism from the ambient number field to `V` - - ``lift`` -- a section of ``quo``. + - ``lift`` -- a section of ``quo`` EXAMPLES:: @@ -3219,11 +3206,10 @@ def residue_field(self, names=None): sage: FF(a) w - An example of reduction maps to the residue field: these are - defined on the whole valuation ring, i.e. the subring of the - number field consisting of elements with non-negative - valuation. This shows that the issue raised in :issue:`1951` - has been fixed:: + An example of reduction maps to the residue field: these are defined on + the whole valuation ring, i.e. the subring of the number field + consisting of elements with nonnegative valuation. This shows that the + issue raised in :issue:`1951` has been fixed:: sage: K. = NumberField(x^2 + 1) sage: P1, P2 = [g[0] for g in K.factor(5)]; P1, P2 @@ -3274,7 +3260,7 @@ def residue_field(self, names=None): def residue_class_degree(self): r""" Return the residue class degree of this fractional ideal, - assuming it is prime. Otherwise, raise a :class:`ValueError`. + assuming it is prime. Otherwise, raise a :exc:`ValueError`. The residue class degree of a prime ideal `I` is the degree of the extension `O_K/I` of its prime subfield. @@ -3382,7 +3368,7 @@ def __call__(self, x): INPUT: - x -- an element of the field + - ``x`` -- an element of the field EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_ideal_rel.py b/src/sage/rings/number_field/number_field_ideal_rel.py index 2f04cf27660..7f6cfd9b1b7 100644 --- a/src/sage/rings/number_field/number_field_ideal_rel.py +++ b/src/sage/rings/number_field/number_field_ideal_rel.py @@ -42,6 +42,7 @@ QQ = rational_field.RationalField() ZZ = integer_ring.IntegerRing() + class NumberFieldFractionalIdeal_rel(NumberFieldFractionalIdeal): """ An ideal of a relative number field. @@ -139,7 +140,8 @@ def absolute_ideal(self, names='a'): INPUT: - - ``names`` (optional) -- string; name of generator of the absolute field + - ``names`` -- (optional) string; name of generator of the absolute + field EXAMPLES:: @@ -249,7 +251,6 @@ def free_module(self): ... sage: I.free_module().is_submodule(K.maximal_order().free_module()) True - """ return self.absolute_ideal().free_module() @@ -659,7 +660,7 @@ def is_integral(self): def absolute_ramification_index(self): """ Return the absolute ramification index of this fractional ideal, - assuming it is prime. Otherwise, raise a :class:`ValueError`. + assuming it is prime. Otherwise, raise a :exc:`ValueError`. The absolute ramification index is the power of this prime appearing in the factorization of the rational prime that @@ -690,7 +691,7 @@ def absolute_ramification_index(self): def relative_ramification_index(self): """ Return the relative ramification index of this fractional ideal, - assuming it is prime. Otherwise, raise a :class:`ValueError`. + assuming it is prime. Otherwise, raise a :exc:`ValueError`. The relative ramification index is the power of this prime appearing in the factorization of the prime ideal of the @@ -760,7 +761,8 @@ def residue_class_degree(self): def residues(self): """ - Returns a iterator through a complete list of residues modulo this integral ideal. + Return a iterator through a complete list of residues modulo this + integral ideal. An error is raised if this fractional ideal is not integral. @@ -784,19 +786,20 @@ def residues(self): def element_1_mod(self, other): r""" - Returns an element `r` in this ideal such that `1-r` is in ``other``. + Return an element `r` in this ideal such that `1-r` is in ``other``. An error is raised if either ideal is not integral of if they are not coprime. INPUT: - - ``other`` -- another ideal of the same field, or generators of an ideal. + - ``other`` -- another ideal of the same field, or generators of an + ideal OUTPUT: - an element `r` of the ideal self such that `1-r` is in the - ideal ``other``. + an element `r` of the ideal ``self`` such that `1-r` is in the ideal + ``other``. EXAMPLES:: @@ -827,7 +830,7 @@ def element_1_mod(self, other): def smallest_integer(self): r""" - Return the smallest non-negative integer in `I \cap \ZZ`, where `I` is + Return the smallest nonnegative integer in `I \cap \ZZ`, where `I` is this ideal. If `I = 0`, returns `0`. EXAMPLES:: @@ -848,14 +851,13 @@ def valuation(self, p): INPUT: - - ``p`` -- a prime ideal `\mathfrak{p}` of this relative number field. + - ``p`` -- a prime ideal `\mathfrak{p}` of this relative number field OUTPUT: (integer) The valuation of this fractional ideal at the prime `\mathfrak{p}`. If `\mathfrak{p}` is not prime, raise a - :class:`ValueError`. - + :exc:`ValueError`. EXAMPLES:: @@ -881,6 +883,7 @@ def valuation(self, p): raise ValueError("p (= %s) must be an ideal in %s" % self.number_field()) return self.absolute_ideal().valuation(p.absolute_ideal()) + def is_NumberFieldFractionalIdeal_rel(x): """ Return ``True`` if `x` is a fractional ideal of a relative number field. diff --git a/src/sage/rings/number_field/number_field_morphisms.pyx b/src/sage/rings/number_field/number_field_morphisms.pyx index 9ef71586355..e71bad5db7c 100644 --- a/src/sage/rings/number_field/number_field_morphisms.pyx +++ b/src/sage/rings/number_field/number_field_morphisms.pyx @@ -68,11 +68,9 @@ cdef class NumberFieldEmbedding(Morphism): INPUT: - - ``_slots`` -- a dictionary + - ``_slots`` -- dictionary - OUTPUT: - - The given dictionary, with the generator image added. + OUTPUT: the given dictionary, with the generator image added EXAMPLES:: @@ -99,7 +97,7 @@ cdef class NumberFieldEmbedding(Morphism): INPUT: - - ``_slots`` -- a dictionary providing values for the c(p)def slots of self. + - ``_slots`` -- dictionary providing values for the c(p)def slots of ``self`` EXAMPLES:: @@ -191,7 +189,6 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): From: Number Field in i with defining polynomial x^2 + 1 with i = I To: Number Field in i with defining polynomial x^2 + 1 with i = -I Defn: i -> -i - """ cdef readonly ambient_field @@ -231,7 +228,7 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): 'Number Field in a with defining polynomial x^3 + 2 with a = -1.259921049894873?' and 'Number Field in a with defining polynomial x^3 + 2 with a = 0.6299605249474365? + 1.091123635971722?*I' - The following was fixed to raise a ``TypeError`` in :issue:`15331`:: + The following was fixed to raise a :exc:`TypeError` in :issue:`15331`:: sage: L. = NumberField(x^2 + 1) sage: K = NumberField(L(i/2+3).minpoly(), names=('i0',), embedding=L(i/2+3)) @@ -239,7 +236,6 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): Traceback (most recent call last): ... TypeError: No embedding available for Number Field in i with defining polynomial x^2 + 1 - """ if ambient_field is None: if K.coerce_embedding() is None: @@ -488,7 +484,6 @@ def root_from_approx(f, a): Traceback (most recent call last): ... ValueError: sqrt(3) is not a root of x^2 - 2 - """ P = a.parent() if P.is_exact() and not f(a): @@ -634,11 +629,9 @@ cdef class CyclotomicFieldEmbedding(NumberFieldEmbedding): INPUT: - - ``_slots`` -- a dictionary - - OUTPUT: + - ``_slots`` -- dictionary - The given dictionary, with _gen_image and ratio added. + OUTPUT: the given dictionary, with _gen_image and ratio added EXAMPLES:: @@ -665,7 +658,7 @@ cdef class CyclotomicFieldEmbedding(NumberFieldEmbedding): INPUT: - - ``_slots`` -- a dictionary providing values for the c(p)def slots of self. + - ``_slots`` -- dictionary providing values for the c(p)def slots of ``self`` EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index ba4b6c38ae0..7ea070b113e 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -149,14 +149,14 @@ class NumberField_relative(NumberField_generic): - ``base`` -- the base field - ``polynomial`` -- a polynomial which must be defined in the ring `K[x]`, - where `K` is the base field. + where `K` is the base field - - ``name`` -- a string, the variable name + - ``name`` -- string; the variable name - - ``latex_name`` -- a string or ``None`` (default: ``None``), variable name + - ``latex_name`` -- string or ``None`` (default: ``None``); variable name for latex printing - - ``check`` -- a boolean (default: ``True``), whether to check + - ``check`` -- boolean (default: ``True``); whether to check irreducibility of ``polynomial`` - ``embedding`` -- currently not supported, must be ``None`` @@ -349,7 +349,7 @@ def change_names(self, names): Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an - isomorphism from self to `K`. + isomorphism from ``self`` to `K`. EXAMPLES:: @@ -513,7 +513,6 @@ def gens(self): (a0, 0) sage: NumberField([x, x^2 - 3], 'a').gens() (0, a1) - """ return ((self._gen_relative(),) + tuple(map(self, self.base_field().gens()))) @@ -564,7 +563,7 @@ def ngens(self): def gen(self, n=0): """ - Return the `n`'th generator of this relative number field. + Return the `n`-th generator of this relative number field. EXAMPLES:: @@ -612,18 +611,17 @@ def composite_fields(self, other, names=None, both_maps=False, preserve_embeddin - ``names`` -- generator name for composite fields - - ``both_maps`` -- (default: ``False``) if ``True``, return quadruples - (`F`, ``self_into_F, ``other_into_F``, `k`) such that ``self_into_F`` maps ``self`` into - `F`, ``other_into_F`` maps ``other`` into `F`. For relative number fields, `k` is - always ``None``. - - - ``preserve_embedding`` -- (default: ``True``) has no effect, but is kept - for compatibility with the absolute version of this method. In every - case the list of all possible compositums is returned. + - ``both_maps`` -- boolean (default: ``False``); if ``True``, return + quadruples (`F`, ``self_into_F, ``other_into_F``, `k`) such that + ``self_into_F`` maps ``self`` into `F`, ``other_into_F`` maps + ``other`` into `F`. For relative number fields, `k` is always + ``None``. - OUTPUT: + - ``preserve_embedding`` -- boolean (default: ``True``); has no effect, + but is kept for compatibility with the absolute version of this, + method. In every case the list of all possible compositums is returned. - list of the composite fields, possibly with maps. + OUTPUT: list of the composite fields, possibly with maps EXAMPLES:: @@ -700,7 +698,7 @@ def absolute_degree(self): def relative_degree(self): r""" - Returns the relative degree of this relative number field. + Return the relative degree of this relative number field. EXAMPLES:: @@ -732,7 +730,7 @@ def degree(self): @cached_method def _maximal_order(self, v=(), assume_maximal='non-maximal-non-unique'): """ - Implements :meth:`NumberField_generic.maximal_order` for relative + Implement :meth:`NumberField_generic.maximal_order` for relative number fields. EXAMPLES:: @@ -741,7 +739,6 @@ def _maximal_order(self, v=(), assume_maximal='non-maximal-non-unique'): sage: K. = NumberFieldTower([x^2 - 17, x^3 - 2]) sage: K.maximal_order() is K.maximal_order() # indirect doctest True - """ absolute_order = self.absolute_field('z').maximal_order(v=v, assume_maximal=assume_maximal) @@ -847,7 +844,7 @@ def _convert_non_number_field_element(self, x): INPUT: - ``x`` -- a non number field element, e.g., a list, - integer, rational, or polynomial. + integer, rational, or polynomial EXAMPLES:: @@ -1156,8 +1153,8 @@ def _pari_base_bnf(self, proof=False, units=True): INPUT: - - ``proof`` (bool, default: ``True``) -- if True, certify - correctness of calculations (not assuming GRH). + - ``proof`` -- boolean (default: ``True``); if ``True``, certify + correctness of calculations (not assuming GRH) EXAMPLES:: @@ -1247,7 +1244,6 @@ def is_galois_absolute(self): sage: y = polygen(K); L. = K.extension(y^2 - a) sage: L.is_galois_absolute() # needs sage.groups False - """ f = self.absolute_polynomial() return f.galois_group(pari_group=True).order() == self.absolute_degree() @@ -1300,7 +1296,8 @@ def is_isomorphic_relative(self, other, base_isom=None): sage: L2.is_isomorphic_relative(L1cyc, base_isom=phi2) True - Omitting ``base_isom`` raises a :class:`ValueError` when the base fields are not identical:: + Omitting ``base_isom`` raises a :exc:`ValueError` when the base fields + are not identical:: sage: L1.is_isomorphic_relative(L1cyc) Traceback (most recent call last): @@ -1369,7 +1366,6 @@ def is_CM_extension(self): False sage: K.is_CM() True - """ try: @@ -1399,7 +1395,8 @@ def free_module(self, base=None, basis=None, map=True): - ``basis`` -- (optional) a list of elements giving a basis over the subfield - - ``map`` -- (default ``True``) whether to return isomorphisms to and from the vector space + - ``map`` -- (default: ``True``) whether to return isomorphisms to and + from the vector space EXAMPLES:: @@ -1517,7 +1514,6 @@ def vector_space(self, *args, **kwds): ... NotImplementedError: For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate - """ raise NotImplementedError("For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate") @@ -1611,7 +1607,7 @@ def _pari_relative_structure(self): field, and let `f` be the defining polynomial of `L` over `K`. This method returns a triple ``(g, alpha, beta)``, where - - ``g`` is the defining relative polynomial of the PARI + - ``g`` -- the defining relative polynomial of the PARI ``rnf`` structure (see :meth:`pari_rnf`); - ``alpha`` is the image of `x \bmod f` under some isomorphism @@ -1838,9 +1834,7 @@ def absolute_field(self, names): - ``names`` -- string; name of generator of the absolute field - OUTPUT: - - An absolute number field `K` that is isomorphic to this field. + OUTPUT: an absolute number field `K` that is isomorphic to this field Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` @@ -2046,7 +2040,7 @@ def embeddings(self, K): e.g., it could be the complex numbers). This will return an identical result when given `K` as input again. - If possible, the most natural embedding of self into `K` + If possible, the most natural embedding of ``self`` into `K` is put first in the list. INPUT: @@ -2078,6 +2072,9 @@ def embeddings(self, K): sage: f[0](a+b) -0.62996052494743693 - 0.091123635971721295*I """ + if K.characteristic(): + return Sequence([], immutable=True, check=False, universe=self.Hom(K)) + try: # this should be concordant with automorphisms return self.__embeddings[K] @@ -2190,11 +2187,9 @@ def logarithmic_embedding(self, prec=53): INPUT: - - ``prec`` -- desired floating point precision. - - OUTPUT: + - ``prec`` -- desired floating point precision - the morphism of ``self`` under the logarithmic embedding in the category Set. + OUTPUT: the morphism of ``self`` under the logarithmic embedding in the category Set EXAMPLES:: @@ -2358,9 +2353,9 @@ def absolute_discriminant(self, v=None): INPUT: - - ``v`` (optional) -- list of element of this relative number field. + - ``v`` -- (optional) list of element of this relative number field - OUTPUT: Integer if ``v`` is omitted, and Rational otherwise. + OUTPUT: integer if ``v`` is omitted, and Rational otherwise EXAMPLES:: @@ -2460,22 +2455,23 @@ def order(self, *gens, **kwds): - ``gens`` -- list of elements of ``self``; if no generators are given, just returns the cardinality of this number field (`\infty`) for consistency. - - ``check_is_integral`` -- bool (default: ``True``), whether to check that each - generator is integral. - - ``check_rank`` -- bool (default: ``True``), whether to check that the ring - generated by ``gens`` is of full rank. - - ``allow_subfield`` -- bool (default: ``False``), if ``True`` and the generators - do not generate an order, i.e., they generate a subring of smaller - rank, instead of raising an error, return an order in a smaller - number field. + - ``check_is_integral`` -- boolean (default: ``True``); whether to + check that each generator is integral + - ``check_rank`` -- boolean (default: ``True``); whether to check that + the ring generated by ``gens`` is of full rank + - ``allow_subfield`` -- boolean (default: ``False``); if ``True`` and + the generators do not generate an order, i.e., they generate a + subring of smaller rank, instead of raising an error, return an order + in a smaller number field. The ``check_is_integral`` and ``check_rank`` inputs must be given as explicit keyword arguments. EXAMPLES:: - sage: P. = QQ[2^(1/2), 2^(1/3), 3^(1/2)] # needs sage.symbolic - sage: R = P.order([a,b,c]); R # needs sage.symbolic + sage: # needs sage.symbolic + sage: P3. = QQ[2^(1/2), 2^(1/3), 3^(1/2)] + sage: R = P3.order([a,b,c]); R # not tested (83s, 2GB memory) Relative Order generated by [((-36372*sqrt3 + 371270)*a^2 + (-89082*sqrt3 + 384161)*a - 422504*sqrt3 - 46595)*sqrt2 + (303148*sqrt3 - 89080)*a^2 + (313664*sqrt3 - 218211)*a - 38053*sqrt3 - 1034933, ((-65954*sqrt3 + 323491)*a^2 + (-110591*sqrt3 + 350011)*a - 351557*sqrt3 + 77507)*sqrt2 + (264138*sqrt3 - 161552)*a^2 + (285784*sqrt3 - 270906)*a + 63287*sqrt3 - 861151, @@ -2484,7 +2480,12 @@ def order(self, *gens, **kwds): ((-73815*sqrt3 + 257278)*a^2 + (-102896*sqrt3 + 298046)*a - 277080*sqrt3 + 123726)*sqrt2 + (210072*sqrt3 - 180812)*a^2 + (243357*sqrt3 - 252052)*a + 101026*sqrt3 - 678718] in Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field - The base ring of an order in a relative extension is still `\ZZ`.:: + sage: P2. = QQ[2^(1/2), 2^(1/3)] # needs sage.symbolic + sage: R = P2.order([u,v]); R # needs sage.symbolic + Relative Order generated by [(6*a^2 - a - 1)*sqrt2 + 4*a^2 - 6*a - 9, sqrt2 - a] + in Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field + + The base ring of an order in a relative extension is still `\ZZ`:: sage: R.base_ring() # needs sage.symbolic Integer Ring @@ -2492,7 +2493,7 @@ def order(self, *gens, **kwds): One must give enough generators to generate a ring of finite index in the maximal order:: - sage: P.order([a, b]) # needs sage.symbolic + sage: P3.order([a, b]) # needs sage.symbolic Traceback (most recent call last): ... ValueError: the rank of the span of gens is wrong @@ -2512,7 +2513,7 @@ def is_free(self, proof=None): INPUT: - - ``proof`` -- default: ``True`` + - ``proof`` -- (default: ``True``) EXAMPLES:: @@ -2553,7 +2554,7 @@ def _factor_univariate_polynomial(self, poly, **kwargs): def lift_to_base(self, element): """ Lift an element of this extension into the base field if possible, - or raise a :class:`ValueError` if it is not possible. + or raise a :exc:`ValueError` if it is not possible. EXAMPLES:: @@ -2611,7 +2612,7 @@ def relativize(self, alpha, names): INPUT: - ``alpha`` -- an element of ``self``, or an embedding of a subfield into ``self`` - - ``names`` -- name of generator for output field `K`. + - ``names`` -- name of generator for output field `K` OUTPUT: `K` -- a relative number field @@ -2697,23 +2698,23 @@ def relativize(self, alpha, names): L = K.relativize(beta, names) return K.relativize(beta, names, structure=structure.RelativeFromRelative(L)) - def uniformizer(self, P, others="positive"): + def uniformizer(self, P, others='positive'): """ - Returns an element of ``self`` with valuation 1 at the prime ideal `P`. + Return an element of ``self`` with valuation 1 at the prime ideal `P`. INPUT: - - ``self`` -- a number field + - ``self`` -- a number field - - ``P`` -- a prime ideal of ``self`` + - ``P`` -- a prime ideal of ``self`` - - ``others`` -- either ``"positive"`` (default), in which - case the element will have non-negative valuation at all other - primes of ``self``, or ``"negative"``, in which case the element will have - non-positive valuation at all other primes of ``self``. + - ``others`` -- either ``'positive'`` (default), in which case the + element will have nonnegative valuation at all other primes of + ``self``, or ``'negative'``, in which case the element will have + nonpositive valuation at all other primes of ``self`` - .. note:: + .. NOTE:: When `P` is principal (e.g., always when ``self`` has class number one), the result may or may not be a generator of `P`! diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 11c4fea118d..55db3bbbcbf 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -126,7 +126,6 @@ class OrderFactory(UniqueFactory): sage: from sage.rings.number_field.order import AbsoluteOrder, OrderFactory sage: isinstance(AbsoluteOrder, OrderFactory) True - """ def get_object(self, version, key, extra_args): @@ -158,7 +157,6 @@ def get_object(self, version, key, extra_args): True sage: N._is_maximal_at(3) True - """ is_maximal = extra_args.pop("is_maximal", None) is_maximal_at = extra_args.pop("is_maximal_at", {}) @@ -210,7 +208,6 @@ def create_key_and_extra_args(self, K, module_rep, is_maximal=None, check=True, Note how the above is lacking the ``is_maximal`` and ``is_maximal_at`` keywords. These are stripped by :meth:`OrderFactory.get_object` and then put back in by :meth:`reduce_data`. - """ if check: if not K.is_absolute(): @@ -238,7 +235,6 @@ def create_object(self, version, key, is_maximal=None, is_maximal_at=()): sage: OK = K.order(i) sage: loads(dumps(OK)) is OK True - """ K, module_rep = key @@ -272,7 +268,6 @@ def reduce_data(self, order): sage: loads(dumps(N)) is O True - """ reduction = super().reduce_data(order) reduction[1][3]["is_maximal"] = order._is_maximal() @@ -322,7 +317,6 @@ def create_key_and_extra_args(self, K, absolute_order, is_maximal=None, check=Tr keywords. These are stripped by :meth:`OrderFactory.get_object`. Since they are applied to the underlying absolute order, they then get pickled when the underlying order is pickled. - """ return (K, absolute_order), {"is_maximal": is_maximal, "is_maximal_at": {p: True for p in is_maximal_at}} @@ -341,7 +335,6 @@ def create_object(self, version, key, is_maximal=None, is_maximal_at=()): sage: OK = L.order([i, j]) sage: loads(dumps(OK)) is OK True - """ K, absolute_order = key @@ -510,21 +503,21 @@ def ideal(self, *args, **kwds): """ Return the integral ideal with given generators. + .. NOTE:: + + This method constructs an ideal of this (not necessarily maximal) order. + To construct a fractional ideal in the ambient number field, use + :meth:`~sage.rings.number_field.number_field.NumberField_generic.fractional_ideal`. + EXAMPLES:: sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 7) sage: R = K.maximal_order() - sage: R.ideal(2/3 + 7*a, a) - Traceback (most recent call last): - ... - ValueError: ideal must be integral; - use fractional_ideal to create a non-integral ideal. - sage: R.ideal(7*a, 77 + 28*a) - Fractional ideal (7) + sage: R.ideal([7*a, 77 + 28*a]) + Ideal (7/2*a + 7/2, 7*a) of Maximal Order generated by 1/2*a + 1/2 in Number Field in a with defining polynomial x^2 + 7 sage: R = K.order(4*a) sage: R.ideal(8) - doctest:warning ... FutureWarning: ... Ideal (8, 32*a) of Order of conductor 8 generated by 4*a in Number Field in a with defining polynomial x^2 + 7 @@ -533,36 +526,22 @@ def ideal(self, *args, **kwds): sage: R = EquationOrder(x^2 + 2, 'a'); R Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 2 sage: (3,15)*R - doctest:warning ... DeprecationWarning: ... - Fractional ideal (3) + Ideal (3, 3*a) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 2 The zero ideal is handled properly:: sage: R.ideal(0) - Ideal (0) of Number Field in a with defining polynomial x^2 + 2 - """ - if kwds.get('future', False) or not self.is_maximal(): - if 'future' in kwds: - del kwds['future'] - from sage.rings.number_field.order_ideal import NumberFieldOrderIdeal - return NumberFieldOrderIdeal(self, *args, **kwds) - if kwds.get('warn', True): - if 'warn' in kwds: - del kwds['warn'] - from sage.misc.superseded import deprecation - deprecation(34198, 'In the future, constructing an ideal of the ring of ' - 'integers of a number field will use an implementation ' - 'compatible with ideals of other (non-maximal) orders, ' - 'rather than returning an integral fractional ideal of ' - 'its containing number field. Use .fractional_ideal(), ' - 'together with an .is_integral() check if desired, to ' - 'emulate the current behavior.\nSet warn=0 to silence ' - 'this warning, and future=1 to activate the upcoming ' - 'behavior already.') - I = self.number_field().ideal(*args, **kwds) - if not I.is_integral(): - raise ValueError("ideal must be integral; use fractional_ideal to create a non-integral ideal.") - return I + Ideal (0) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 2 + """ + # these keyword arguments are ignored since there used to be optional + # arguments with these names for controlling deprecated/future behavior; + # see #34806 and #35762 + if 'warn' in kwds: + del kwds['warn'] + if 'future' in kwds: + del kwds['future'] + from sage.rings.number_field.order_ideal import NumberFieldOrderIdeal + return NumberFieldOrderIdeal(self, *args, **kwds) def _coerce_map_from_(self, R): """ @@ -582,7 +561,7 @@ def _coerce_map_from_(self, R): def __mul__(self, right): """ - Create an ideal in this order using the syntax ``O * gens`` + Create an ideal in this order using the syntax ``O * gens``. EXAMPLES:: @@ -594,10 +573,9 @@ def __mul__(self, right): sage: Ok = k.maximal_order(); Ok Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077 sage: Ok * (11, a + 7) - doctest:warning ... DeprecationWarning: ... - Fractional ideal (11, a + 7) + Ideal (8*a + 1, 11*a) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077 sage: (11, a + 7) * Ok - Fractional ideal (11, a + 7) + Ideal (8*a + 1, 11*a) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077 """ return self.ideal(right) @@ -617,7 +595,7 @@ def __rmul__(self, left): sage: (6, 1/2*a + 11/2)*Ok # random output Fractional ideal (6, 1/2*a + 11/2) sage: 17*Ok - Fractional ideal (17) + Ideal (17/2*a + 17/2, 17*a) of Maximal Order generated by 1/2*a + 1/2 in Number Field in a with defining polynomial x^2 + 431 """ return self.ideal(left) @@ -638,7 +616,7 @@ def is_field(self, proof=True): def is_noetherian(self): r""" - Return ``True`` (because orders are always Noetherian) + Return ``True`` (because orders are always Noetherian). EXAMPLES:: @@ -713,7 +691,7 @@ def integral_closure(self): def gen(self, i): r""" - Return `i`'th module generator of this order. + Return `i`-th module generator of this order. EXAMPLES:: @@ -776,7 +754,7 @@ def coordinates(self, x): INPUT: - - ``x`` -- an element of the number field of this order. + - ``x`` -- an element of the number field of this order OUTPUT: @@ -817,7 +795,6 @@ def coordinates(self, x): (23, -14/3) sage: sum([O.basis()[j]*acoords[j] for j in range(2)]) == a True - """ K = self.number_field() V, from_V, to_V = K.absolute_vector_space() @@ -917,7 +894,7 @@ def ring_generators(self): gens.append(g) n.append(g.absolute_minpoly().degree()) W = A.span([to_V(x) for x in monomials(gens, n)]) - remaining = [x for x in remaining if not to_V(x) in W] + remaining = [x for x in remaining if to_V(x) not in W] return Sequence(gens, immutable=True) @cached_method @@ -1018,13 +995,11 @@ def residue_field(self, prime, names=None, check=False): INPUT: - - ``prime`` -- a prime ideal of the maximal order in this number field. - - ``names`` -- the name of the variable in the residue field. - - ``check`` -- whether or not to check the primality of prime. - - OUTPUT: + - ``prime`` -- a prime ideal of the maximal order in this number field + - ``names`` -- the name of the variable in the residue field + - ``check`` -- whether or not to check the primality of prime - The residue field at this prime. + OUTPUT: the residue field at this prime EXAMPLES:: @@ -1337,7 +1312,7 @@ def random_element(self, *args, **kwds): sage: OK = K.ring_of_integers() sage: OK.random_element() # random output -2*a^2 - a - 2 - sage: OK.random_element(distribution="uniform") # random output + sage: OK.random_element(distribution='uniform') # random output -a^2 - 1 sage: OK.random_element(-10,10) # random output -10*a^2 - 9*a - 2 @@ -1459,7 +1434,6 @@ def valuation(self, p): :meth:`NumberField_generic.valuation() `, :meth:`pAdicGeneric.valuation() ` - """ from sage.rings.padics.padic_valuation import pAdicValuation return pAdicValuation(self, p) @@ -1494,7 +1468,6 @@ def some_elements(self): Maximal Order generated by [] in Number Field in a with defining polynomial t sage: Z.some_elements() [1, 0, 2, -1, -2, 4] - """ elements = list(self.basis()) for a in self.fraction_field().some_elements(): @@ -1563,7 +1536,6 @@ def __init__(self, K, module_rep): sage: loads(dumps(O)) is O True sage: TestSuite(O).run() - """ if K.degree() == 2: self._element_type = OrderElement_quadratic @@ -1612,14 +1584,13 @@ def _element_constructor_(self, x): 10/3*a^2 + 7/3*a + 1/3 sage: K([1,2,3]) 3*a^2 + 2*a + 1 - """ if isinstance(x, (tuple, list)): x = sum(xi*gi for xi, gi in zip(x, self.gens())) if not isinstance(x, Element) or x.parent() is not self._K: x = self._K(x) V, _, embedding = self._K.vector_space() - if not embedding(x) in self._module_rep: + if embedding(x) not in self._module_rep: raise TypeError("Not an element of the order.") return self._element_type(self, x) @@ -1685,7 +1656,6 @@ def __and__(left, right): Maximal Order generated by [7/12*z^3 + 3/4*z^2 + 1/12*z + 1/4, 1/6*z^3 + 1/6*z, z^2] in Number Field in z with defining polynomial x^4 - 2*x^2 + 9 sage: L.maximal_order() & L.absolute_field('z').maximal_order() Maximal Order generated by [7/12*z^3 + 3/4*z^2 + 1/12*z + 1/4, 1/6*z^3 + 1/6*z, z^2] in Number Field in z with defining polynomial x^4 - 2*x^2 + 9 - """ if isinstance(right, Order_relative): return right & left @@ -1713,9 +1683,7 @@ def _magma_init_(self, magma): - ``magma`` -- a magma interpreter - OUTPUT: - - a :class:`MagmaElement`, the magma version of this absolute order + OUTPUT: a :class:`MagmaElement`, the magma version of this absolute order EXAMPLES:: @@ -1775,8 +1743,8 @@ def is_maximal(self, p=None): INPUT: - - ``p`` -- an integer prime or ``None`` (default: ``None``); if - set, return whether this order is maximal at the prime `p`. + - ``p`` -- integer prime or ``None`` (default: ``None``); if + set, return whether this order is maximal at the prime `p` EXAMPLES:: @@ -1809,7 +1777,6 @@ def is_maximal(self, p=None): sage: O = K.order([3*a, 2*b]) sage: O.is_maximal() False - """ if self._is_maximal() is True: return True @@ -1842,7 +1809,6 @@ def _is_maximal(self): False sage: K.order(1337*t)._is_maximal() False - """ return self.__is_maximal @@ -1877,7 +1843,6 @@ def _is_maximal_at(self, p=None): sage: O = K.maximal_order([13], assume_maximal=None) sage: O._is_maximal_at() {13: True} - """ if p is None: return dict(self.__is_maximal_at) @@ -1925,7 +1890,7 @@ def _assume_maximal(self, is_maximal=True, p=None): sage: O = K.order(1+i) sage: O.is_maximal() True - sage: N = O._assume_maximal(is_maximal="non-maximal-non-unique") + sage: N = O._assume_maximal(is_maximal='non-maximal-non-unique') sage: N._assume_maximal(p=2) is N True sage: N is O @@ -1936,7 +1901,6 @@ def _assume_maximal(self, is_maximal=True, p=None): False sage: N.is_maximal(p=2) True - """ if is_maximal is None: # No assumption made, return the object unchanged. @@ -2007,11 +1971,9 @@ def index_in(self, other): INPUT: - - ``other`` -- another absolute order with the same ambient number field. - - OUTPUT: + - ``other`` -- another absolute order with the same ambient number field - a rational number + OUTPUT: a rational number EXAMPLES:: @@ -2214,7 +2176,6 @@ def __init__(self, K, absolute_order): sage: loads(dumps(O)) is O True sage: TestSuite(O).run() - """ self._absolute_order = absolute_order self._module_rep = absolute_order._module_rep @@ -2293,9 +2254,10 @@ def absolute_order(self, names='z'): INPUT: - - ``names`` -- string (default: 'z'); name of generator of absolute extension. + - ``names`` -- string (default: ``'z'``); name of generator of absolute + extension - .. note:: + .. NOTE:: There *is* a default variable name, since this absolute order is frequently used for internal algorithms. @@ -2420,7 +2382,6 @@ def __and__(left, right): sage: (L.maximal_order() & L.maximal_order()).is_maximal() True - """ if isinstance(right, Order_absolute): return left._absolute_order & right @@ -2439,8 +2400,8 @@ def is_maximal(self, p=None): INPUT: - - ``p`` -- an integer prime or ``None`` (default: ``None``); if - set, return whether this order is maximal at the prime `p`. + - ``p`` -- integer prime or ``None`` (default: ``None``); if + set, return whether this order is maximal at the prime `p` EXAMPLES:: @@ -2466,7 +2427,6 @@ def is_maximal(self, p=None): sage: K.order(3*a, b).is_maximal(p=3) False - """ return self._absolute_order.is_maximal(p=p) @@ -2485,7 +2445,6 @@ def _is_maximal(self): False sage: O._is_maximal() False - """ return self._absolute_order._is_maximal() @@ -2510,7 +2469,6 @@ def _is_maximal_at(self, p=None): True sage: O._is_maximal_at() {2: True, 3: True, 5: True, 7: True} - """ return self._absolute_order._is_maximal_at(p=p) @@ -2554,7 +2512,7 @@ def _assume_maximal(self, is_maximal=True, p=None): sage: O = L.maximal_order([2, 3], assume_maximal=None) sage: O.is_maximal() True - sage: N = O._assume_maximal(is_maximal="non-maximal-non-unique") + sage: N = O._assume_maximal(is_maximal='non-maximal-non-unique') sage: N._assume_maximal(p=2) is N True sage: N is O @@ -2565,7 +2523,6 @@ def _assume_maximal(self, is_maximal=True, p=None): False sage: N.is_maximal(p=2) True - """ absolute_order = self._absolute_order._assume_maximal(is_maximal=is_maximal, p=p) if absolute_order is not self._absolute_order: @@ -2578,9 +2535,7 @@ def absolute_discriminant(self): Return the absolute discriminant of ``self``, which is the discriminant of the absolute order associated to ``self``. - OUTPUT: - - an integer + OUTPUT: integer EXAMPLES:: @@ -2628,11 +2583,9 @@ def index_in(self, other): INPUT: - - ``other`` -- another order with the same ambient absolute number field. + - ``other`` -- another order with the same ambient absolute number field - OUTPUT: - - a rational number + OUTPUT: a rational number EXAMPLES:: @@ -2674,16 +2627,17 @@ def absolute_order_from_ring_generators(gens, check_is_integral=True, """ INPUT: - - ``gens`` -- list of integral elements of an absolute order. - - ``check_is_integral`` -- bool (default: ``True``), whether to check that each - generator is integral. - - ``check_rank`` -- bool (default: ``True``), whether to check that the ring - generated by ``gens`` is of full rank. - - ``is_maximal`` -- bool (or ``None``); set if maximality of the generated order is - known - - ``allow_subfield`` -- bool (default: ``False``), if ``True`` and the generators do - not generate an order, i.e., they generate a subring of smaller rank, - instead of raising an error, return an order in a smaller number field. + - ``gens`` -- list of integral elements of an absolute order + - ``check_is_integral`` -- boolean (default: ``True``); whether to check + that each generator is integral + - ``check_rank`` -- boolean (default: ``True``); whether to check that the + ring generated by ``gens`` is of full rank + - ``is_maximal`` -- boolean (or ``None``); set if maximality of the + generated order is known + - ``allow_subfield`` -- boolean (default: ``False``); if ``True`` and the + generators do not generate an order, i.e., they generate a subring of + smaller rank, instead of raising an error, return an order in a smaller + number field EXAMPLES:: @@ -2746,17 +2700,18 @@ def absolute_order_from_module_generators(gens, INPUT: - ``gens`` -- list of elements of an absolute number field that generates an - order in that number field as a `\ZZ`-*module*. + order in that number field as a `\ZZ`-*module* - ``check_integral`` -- check that each generator is integral - - ``check_rank`` -- check that the ``gens`` span a module of the correct rank + - ``check_rank`` -- check that the ``gens`` span a module of the correct + rank - ``check_is_ring`` -- check that the module is closed under multiplication (this is very expensive) - - ``is_maximal`` -- bool (or ``None``); set if maximality of the generated order is known - - ``is_maximal_at`` -- a tuple of primes where this order is known to be maximal - - OUTPUT: + - ``is_maximal`` -- boolean (or ``None``); set if maximality of the + generated order is known + - ``is_maximal_at`` -- tuple of primes where this order is known to be + maximal - an absolute order + OUTPUT: an absolute order EXAMPLES: @@ -2898,13 +2853,13 @@ def relative_order_from_ring_generators(gens, """ INPUT: - - ``gens`` -- list of integral elements of an absolute order. - - ``check_is_integral`` -- bool (default: ``True``), whether to check that each - generator is integral. - - ``check_rank`` -- bool (default: ``True``), whether to check that the ring - generated by ``gens`` is of full rank. - - ``is_maximal`` -- bool (or ``None``); set if maximality of the generated order is - known. + - ``gens`` -- list of integral elements of an absolute order + - ``check_is_integral`` -- boolean (default: ``True``); whether to check + that each generator is integral + - ``check_rank`` -- boolean (default: ``True``); whether to check that the + ring generated by ``gens`` is of full rank + - ``is_maximal`` -- boolean (or ``None``); set if maximality of the + generated order is known EXAMPLES: @@ -2950,7 +2905,7 @@ def relative_order_from_ring_generators(gens, return RelativeOrder(K, abs_order, check=False) -def GaussianIntegers(names="I", latex_name="i"): +def GaussianIntegers(names='I', latex_name='i'): r""" Return the ring of Gaussian integers. @@ -2978,7 +2933,7 @@ def GaussianIntegers(names="I", latex_name="i"): return nf.ring_of_integers() -def EisensteinIntegers(names="omega"): +def EisensteinIntegers(names='omega'): r""" Return the ring of Eisenstein integers. diff --git a/src/sage/rings/number_field/order_ideal.py b/src/sage/rings/number_field/order_ideal.py index e1dc02e94cb..772c4ad3a9a 100644 --- a/src/sage/rings/number_field/order_ideal.py +++ b/src/sage/rings/number_field/order_ideal.py @@ -9,13 +9,6 @@ ideals of non-maximal orders (compared to the maximal case). This should hopefully change in the future. -TESTS: - -This module is currently experimental:: - - sage: import sage.rings.number_field.order_ideal - doctest:warning ... - EXAMPLES:: sage: O = QuadraticField(-1).order(5*i) @@ -75,13 +68,11 @@ from sage.rings.polynomial.polynomial_ring import polygens from sage.rings.ideal import Ideal_generic -from sage.misc.superseded import experimental_warning -experimental_warning(34198, 'Ideals of non-maximal orders are an experimental feature. Be wary of bugs.') - import sage.rings.number_field.order #TODO I*u works when u lies in I.ring().number_field(), but u*I doesn't + def NumberFieldOrderIdeal(O, *args, **kwds): r""" Construct either a :class:`NumberFieldOrderIdeal_generic` @@ -117,6 +108,7 @@ def NumberFieldOrderIdeal(O, *args, **kwds): cls = NumberFieldOrderIdeal_generic return cls(O, *args, **kwds) + class NumberFieldOrderIdeal_generic(Ideal_generic): r""" An ideal of a not necessarily maximal order in a number field. @@ -269,6 +261,7 @@ def norm(self): """ return self.free_module().index_in(self.ring().free_module()) + def _positive_sqrt(R, D): r""" Return the "positive" square root of `D` in `R`, which must be @@ -292,6 +285,7 @@ def _positive_sqrt(R, D): sqrtD, = (s for s in R(D).sqrt(all=True) if s.real() > 0 or s.imag() > 0) return sqrtD + def _gens_from_bqf(O, Q): r""" Helper function to compute generators of the ideal associated to @@ -354,6 +348,7 @@ def _gens_from_bqf(O, Q): t = sqrtD if a < 0 else 1 return a*t, g*t + class NumberFieldOrderIdeal_quadratic(NumberFieldOrderIdeal_generic): r""" An ideal of a not necessarily maximal order in a *quadratic* number field. @@ -567,7 +562,7 @@ def is_equivalent(self, other, narrow=False): If ``narrow`` is ``True``, test narrow equivalence instead. (Two ideals are equivalent if they differ by multiplication - by a non-zero element. They are narrowly equivalent if they + by a nonzero element. They are narrowly equivalent if they differ by multiplication by an element of positive norm.) EXAMPLES:: diff --git a/src/sage/rings/number_field/selmer_group.py b/src/sage/rings/number_field/selmer_group.py index 49b4030b2e9..5204cfc80b6 100644 --- a/src/sage/rings/number_field/selmer_group.py +++ b/src/sage/rings/number_field/selmer_group.py @@ -19,8 +19,8 @@ where `O^*_{K,S}` is the group of `S`-units of `K` and `Cl_{K,S}` the `S`-class group. When `m=p` is prime, `K(S,p)` is a finite-dimensional vector space over `GF(p)`. Its generators come -from three sources: units (modulo `p`'th powers); generators of the -`p`'th powers of ideals which are not principal but whose `p`'the +from three sources: units (modulo `p`-th powers); generators of the +`p`-th powers of ideals which are not principal but whose `p`-th powers are principal; and generators coming from the prime ideals in `S`. @@ -51,18 +51,17 @@ # A utility function to allow the same code to be used over QQ and # over number fields: + def _ideal_generator(I): r""" Return the generator of a principal ideal. INPUT: - - ``I`` (fractional ideal or integer) -- either a fractional ideal of a - number field, which must be principal, or a rational integer. - - OUTPUT: + - ``I`` -- either a fractional ideal of a number field, which must be + principal, or a rational integer - A generator of `I` when `I` is a principal ideal, else `I` itself. + OUTPUT: a generator of `I` when `I` is a principal ideal, else `I` itself EXAMPLES:: @@ -73,26 +72,26 @@ def _ideal_generator(I): sage: K. = QuadraticField(-11) sage: [_ideal_generator(K.prime_above(p)) for p in primes(25)] [2, 1/2*a - 1/2, -1/2*a - 3/2, 7, -a, 13, 17, 19, 1/2*a + 9/2] - """ try: return I.gens_reduced()[0] except AttributeError: return I.abs() + def _coords_in_C_p(I, C, p): r""" Return coordinates of the ideal ``I`` with respect to a basis of - the ``p``-torsion of the ideal class group ``C``. + the `p`-torsion of the ideal class group ``C``. INPUT: - - ``I`` (ideal) -- a fractional ideal of a number field ``K``, - whose ``p``'th power is principal. + - ``I`` -- ideal; a fractional ideal of a number field ``K``, whose + `p`-th power is principal - - ``C`` (class group) -- the ideal class group of ``K``. + - ``C`` -- (class group) the ideal class group of ``K`` - - ``p`` (prime) -- a prime number. + - ``p`` -- prime number OUTPUT: @@ -102,7 +101,7 @@ def _coords_in_C_p(I, C, p): ALGORITHM: Find the coordinates of `[I]` with respect to generators of `C` as - an abelian group, check that coordidates are 0 in cyclic factors + an abelian group, check that coordinates are 0 in cyclic factors of order prime to `p`, and return the list of `c/(n/p)` (mod `p`) for coordinates `c` for each cyclic factor of order `n` which is a multiple of `p`. @@ -123,7 +122,6 @@ def _coords_in_C_p(I, C, p): Traceback (most recent call last): ... ValueError: The 3rd power of Fractional ideal (2, a + 1) is not principal - """ cyclic_orders = C.gens_orders() non_p_indices = [i for i,n in enumerate(cyclic_orders) if not p.divides(n)] @@ -134,18 +132,19 @@ def _coords_in_C_p(I, C, p): return [(coords[i] // n) % p for i, n in p_indices] raise ValueError("The {} power of {} is not principal".format(p.ordinal_str(),I)) + def _coords_in_C_mod_p(I,C,p): r""" Return coordinates of the ideal ``I`` with respect to a basis of - the ``p``-cotorsion of the ideal class group ``C``. + the `p`-cotorsion of the ideal class group ``C``. INPUT: - - ``I`` (ideal) -- a fractional ideal of a number field ``K``. + - ``I`` -- ideal; a fractional ideal of a number field ``K`` - - ``C`` (class group) -- the ideal class group of ``K``. + - ``C`` -- (class group) the ideal class group of ``K`` - - ``p`` (prime) -- a prime number. + - ``p`` -- prime number OUTPUT: @@ -179,29 +178,27 @@ def _coords_in_C_mod_p(I,C,p): [[1, 0], [1, 1], [1, 1], [0, 1], [1, 0], [0, 1], [0, 0], [0, 1], [0, 0]] sage: [_coords_in_C_mod_p(K.prime_above(p), C, 3) for p in primes(25)] [[2], [0], [1], [0], [0], [1], [0], [2], [0]] - """ cyclic_orders = C.gens_orders() p_indices = [i for i, n in enumerate(cyclic_orders) if p.divides(n)] coords = C(I).exponents() return [coords[i] % p for i in p_indices] + def _root_ideal(I, C, p): r""" - Return a ``p``'th root of an ideal with respect to the class group. + Return a `p`-th root of an ideal with respect to the class group. INPUT: - - ``I`` (ideal) -- a fractional ideal of a number field ``K``, - whose ideal class is a ``p``'th power. - - - ``C`` (class group) -- the ideal class group of ``K``. + - ``I`` -- ideal; a fractional ideal of a number field ``K``, + whose ideal class is a `p`-th power - - ``p`` (prime) -- a prime number. + - ``C`` -- (class group) the ideal class group of ``K`` - OUTPUT: + - ``p`` -- prime number - An ideal `J` such that `J^p` is in the same ideal class as `I`. + OUTPUT: an ideal `J` such that `J^p` is in the same ideal class as `I` EXAMPLES:: @@ -222,7 +219,6 @@ def _root_ideal(I, C, p): sage: J = _root_ideal(I, C, 3) sage: C(J^3) == C(I) True - """ cyclic_orders = C.gens_orders() cyclic_gens = C.gens_ideals() @@ -238,18 +234,19 @@ def _root_ideal(I, C, p): return prod([gen ** wi for wi, gen in zip(w, cyclic_gens)], C.number_field().ideal(1)) + def coords_in_U_mod_p(u, U, p): r""" Return coordinates of a unit ``u`` with respect to a basis of the - ``p``-cotorsion `U/U^p` of the unit group ``U``. + `p`-cotorsion `U/U^p` of the unit group ``U``. INPUT: - - ``u`` (algebraic unit) -- a unit in a number field ``K``. + - ``u`` -- (algebraic unit) a unit in a number field ``K`` - - ``U`` (unit group) -- the unit group of ``K``. + - ``U`` -- (unit group) the unit group of ``K`` - - ``p`` (prime) -- a prime number. + - ``p`` -- prime number OUTPUT: @@ -280,34 +277,34 @@ def coords_in_U_mod_p(u, U, p): [1, 1, 0, 1] sage: coords_in_U_mod_p(u,U,3) [1, 2, 0] - """ coords = U.log(u) start = 1 - int(p.divides(U.zeta_order())) # 0 or 1 return [c % p for c in coords[start:]] + def basis_for_p_cokernel(S, C, p): r""" Return a basis for the group of ideals supported on ``S`` (mod - ``p``'th-powers) whose class in the class group ``C`` is a ``p``'th power, + `p`-th-powers) whose class in the class group ``C`` is a `p`-th power, together with a function which takes the ``S``-exponents of such an ideal and returns its coordinates on this basis. INPUT: - - ``S`` (list) -- a list of prime ideals in a number field ``K``. + - ``S`` -- list of prime ideals in a number field ``K`` - - ``C`` (class group) -- the ideal class group of ``K``. + - ``C`` -- (class group) the ideal class group of ``K`` - - ``p`` (prime) -- a prime number. + - ``p`` -- prime number OUTPUT: (tuple) (``b``, ``f``) where - ``b`` is a list of ideals which is a basis for the group of - ideals supported on ``S`` (modulo ``p``'th powers) whose ideal - class is a ``p``'th power; + ideals supported on ``S`` (modulo `p`-th powers) whose ideal + class is a `p`-th power; - ``f`` is a function which takes such an ideal and returns its coordinates with respect to this basis. @@ -341,7 +338,6 @@ class is a ``p``'th power; Fractional ideal (3, a + 1), Fractional ideal (5, a + 1), Fractional ideal (5, a + 3)] - """ from sage.matrix.constructor import Matrix M = Matrix(GF(p), [_coords_in_C_mod_p(P, C, p) for P in S]) @@ -360,18 +356,18 @@ def pSelmerGroup(K, S, p, proof=None, debug=False): INPUT: - - ``K`` -- a number field or `\QQ`. + - ``K`` -- a number field or `\QQ` - - ``S`` -- a list of prime ideals in `K`, or prime - numbers when `K` is `\QQ`. + - ``S`` -- list of prime ideals in `K`, or prime + numbers when `K` is `\QQ` - - ``p`` -- a prime number. + - ``p`` -- a prime number - ``proof`` -- if ``True``, compute the class group provably correctly. Default is ``True``. Call :meth:`proof.number_field` to change this default globally. - - ``debug`` -- (boolean, default ``False``) debug flag. + - ``debug`` -- boolean (default: ``False``); debug flag OUTPUT: @@ -401,14 +397,14 @@ def pSelmerGroup(K, S, p, proof=None, debug=False): of the group of roots of unity if its order is divisible by `p`. These have valuation `0` at all primes. - - ``betalist`` is a list of the generators of the `p`'th powers of + - ``betalist`` is a list of the generators of the `p`-th powers of ideals which generate the `p`-torsion in the class group (so is empty if the class number is prime to `p`). These have valuation divisible by `p` at all primes. - ``alphalist`` is a list of generators for each ideal `A` in a - basis of those ideals supported on `S` (modulo `p`'th powers of - ideals) which are `p`'th powers in the class group. We find `B` + basis of those ideals supported on `S` (modulo `p`-th powers of + ideals) which are `p`-th powers in the class group. We find `B` such that `A/B^p` is principal and take a generator of it, for each `A` in a generating set. As a special case, if all the ideals in `S` are principal then ``alphalist`` is a list of @@ -417,16 +413,16 @@ def pSelmerGroup(K, S, p, proof=None, debug=False): The map from the abstract space to `K^*` is easy: we just take the product of the generators to powers given by the coefficient vector. No attempt is made to reduce the resulting product modulo - `p`'th powers. + `p`-th powers. The reverse map is more complicated. Given `a\in K^*`: - write the principal ideal `(a)` in the form `AB^p` with `A` - supported by `S` and `p`'th power free. If this fails, then `a` + supported by `S` and `p`-th power free. If this fails, then `a` does not represent an element of `K(S,p)` and an error is raised. - - set `I_S` to be the group of ideals spanned by `S` mod `p`'th + - set `I_S` to be the group of ideals spanned by `S` mod `p`-th powers, and `I_{S,p}` the subgroup of `I_S` which maps to `0` in `C/C^p`. @@ -435,7 +431,7 @@ def pSelmerGroup(K, S, p, proof=None, debug=False): ``alphalist``. - after dividing out by `A`, now `(a)=B^p` (with a different `a` - and `B`). Write the ideal class `[B]`, whose `p`'th power is + and `B`). Write the ideal class `[B]`, whose `p`-th power is trivial, in terms of the generators of `C[p]`; then `B=(b)B_1`, where the coefficients of `B_1` with respect to generators of `C[p]` give the coordinates of the result with respect to the diff --git a/src/sage/rings/number_field/small_primes_of_degree_one.py b/src/sage/rings/number_field/small_primes_of_degree_one.py index fe456005fed..ff30a006bba 100644 --- a/src/sage/rings/number_field/small_primes_of_degree_one.py +++ b/src/sage/rings/number_field/small_primes_of_degree_one.py @@ -95,24 +95,23 @@ from sage.rings.integer_ring import ZZ -class Small_primes_of_degree_one_iter(): + +class Small_primes_of_degree_one_iter: r""" Iterator that finds primes of a number field of absolute degree one and bounded small prime norm. INPUT: - - ``field`` -- a :class:`NumberField`. + - ``field`` -- a :class:`NumberField` - - ``num_integer_primes`` -- (default: 10000) an integer. We try to find - primes of absolute norm no greater than the - ``num_integer_primes``-th prime number. For example, if - ``num_integer_primes`` is 2, the largest norm found will be 3, since - the second prime is 3. + - ``num_integer_primes`` -- integer (default: 10000); we try to find + primes of absolute norm no greater than the ``num_integer_primes``-th + prime number. For example, if ``num_integer_primes`` is 2, the largest + norm found will be 3, since the second prime is 3. - - ``max_iterations`` -- (default: 100) an integer. We test - ``max_iterations`` integers to find small primes before raising - :class:`StopIteration`. + - ``max_iterations`` -- integer (default: 100); we test ``max_iterations`` + integers to find small primes before raising :class:`StopIteration` AUTHOR: @@ -145,7 +144,7 @@ def __init__(self, field, num_integer_primes=10000, max_iterations=100): def __iter__(self): r""" - Return self as an iterator. + Return ``self`` as an iterator. EXAMPLES:: diff --git a/src/sage/rings/number_field/splitting_field.py b/src/sage/rings/number_field/splitting_field.py index 7fefcd02ce5..28c5486f171 100644 --- a/src/sage/rings/number_field/splitting_field.py +++ b/src/sage/rings/number_field/splitting_field.py @@ -90,7 +90,7 @@ def key(self): def poldegree(self): """ - Return the degree of ``self.pol`` + Return the degree of ``self.pol``. EXAMPLES:: @@ -132,7 +132,7 @@ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=No - ``name`` -- a variable name for the number field - - ``map`` -- (default: ``False``) also return an embedding of + - ``map`` -- boolean (default: ``False``); also return an embedding of ``poly`` into the resulting field. Note that computing this embedding might be expensive. @@ -144,14 +144,14 @@ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=No if it can be determined that the absolute degree of the splitting field is strictly larger than ``abort_degree``. - - ``simplify`` -- (default: ``True``) during the algorithm, try + - ``simplify`` -- boolean (default: ``True``); during the algorithm, try to find a simpler defining polynomial for the intermediate number fields using PARI's ``polredbest()``. This usually speeds up the computation but can also considerably slow it down. Try and see what works best in the given situation. - - ``simplify_all`` -- (default: ``False``) If ``True``, simplify - intermediate fields and also the resulting number field. + - ``simplify_all`` -- boolean (default: ``False``); if ``True``, simplify + intermediate fields and also the resulting number field OUTPUT: @@ -170,7 +170,7 @@ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=No The ``simplify`` and ``simplify_all`` flags usually yield fields defined by polynomials with smaller coefficients. - By default, ``simplify`` is True and ``simplify_all`` is False. + By default, ``simplify`` is ``True`` and ``simplify_all`` is ``False``. :: diff --git a/src/sage/rings/number_field/structure.py b/src/sage/rings/number_field/structure.py index b2b51997528..212d8e2a6f0 100644 --- a/src/sage/rings/number_field/structure.py +++ b/src/sage/rings/number_field/structure.py @@ -56,6 +56,7 @@ from sage.structure.unique_representation import UniqueRepresentation + class NumberFieldStructure(UniqueRepresentation): r""" Abstract base class encapsulating information about a number fields @@ -88,7 +89,6 @@ class NumberFieldStructure(UniqueRepresentation): sage: LL. = NumberField(x^2 + 1, structure=NameChange(L)) sage: KK is LL False - """ def __init__(self, other): """ @@ -99,7 +99,6 @@ def __init__(self, other): sage: from sage.rings.number_field.structure import NumberFieldStructure sage: type(NumberFieldStructure(QQ)) - """ self.other = other @@ -135,17 +134,17 @@ def create_structure(self, field): j sage: K(j) i - """ raise NotImplementedError + class NameChange(NumberFieldStructure): r""" Structure for a number field created by a change in variable name. INPUT: - - ``other`` -- the number field from which this field has been created. + - ``other`` -- the number field from which this field has been created TESTS:: @@ -163,7 +162,6 @@ class NameChange(NumberFieldStructure): 10 sage: [id(v) for v in gc.get_objects() if id(v) == u] [] - """ def create_structure(self, field): r""" @@ -179,11 +177,11 @@ def create_structure(self, field): Isomorphism given by variable name change map: From: Cyclotomic Field of order 5 and degree 4 To: Number Field in a with defining polynomial x^4 + x^3 + x^2 + x + 1) - """ from . import maps return maps.NameChangeMap(field, self.other), maps.NameChangeMap(self.other, field) + class AbsoluteFromRelative(NumberFieldStructure): r""" Structure for an absolute number field created from a relative number @@ -191,7 +189,7 @@ class AbsoluteFromRelative(NumberFieldStructure): INPUT: - - ``other`` -- the number field from which this field has been created. + - ``other`` -- the number field from which this field has been created TESTS:: @@ -201,7 +199,6 @@ class AbsoluteFromRelative(NumberFieldStructure): sage: L. = K.extension(x^2 - 3) sage: AbsoluteFromRelative(L) - """ def create_structure(self, field): r""" @@ -220,11 +217,11 @@ def create_structure(self, field): To: Number Field in b with defining polynomial x^2 - 3 over its base field, Isomorphism map: From: Number Field in b with defining polynomial x^2 - 3 over its base field To: Number Field in c with defining polynomial x^4 - 10*x^2 + 1) - """ from . import maps return maps.MapAbsoluteToRelativeNumberField(field, self.other), maps.MapRelativeToAbsoluteNumberField(self.other, field) + class RelativeFromAbsolute(NumberFieldStructure): r""" Structure for a relative number field created from an absolute number @@ -233,7 +230,7 @@ class RelativeFromAbsolute(NumberFieldStructure): INPUT: - ``other`` -- the (absolute) number field from which this field has been - created. + created - ``gen`` -- the generator of the intermediate field @@ -242,7 +239,6 @@ class RelativeFromAbsolute(NumberFieldStructure): sage: from sage.rings.number_field.structure import RelativeFromAbsolute sage: RelativeFromAbsolute(QQ, 1/2) - """ def __init__(self, other, gen): r""" @@ -253,7 +249,6 @@ def __init__(self, other, gen): sage: from sage.rings.number_field.structure import RelativeFromAbsolute sage: type(RelativeFromAbsolute(QQ, 1/2)) - """ NumberFieldStructure.__init__(self, other) self.gen = gen @@ -280,7 +275,6 @@ def create_structure(self, field): From: Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? To: Number Field in b with defining polynomial x + a_ over its base field Defn: a |--> -a_) - """ # other field # \ / @@ -302,6 +296,7 @@ def create_structure(self, field): return field_to_other, other_to_field + class RelativeFromRelative(NumberFieldStructure): r""" Structure for a relative number field created from another relative number @@ -310,7 +305,7 @@ class RelativeFromRelative(NumberFieldStructure): INPUT: - ``other`` -- the relative number field used in the construction, see - :meth:`create_structure`; there this field will be called ``field_``. + :meth:`create_structure`; there this field will be called ``field_`` TESTS:: @@ -320,7 +315,6 @@ class RelativeFromRelative(NumberFieldStructure): sage: L. = K.extension(x^2 - 2) sage: RelativeFromRelative(L) - """ def create_structure(self, field): r""" @@ -352,7 +346,6 @@ def create_structure(self, field): To: Number Field in b with defining polynomial x^2 - 2*a*x + 3 over its base field Defn: a |--> a i |--> -b + a) - """ # other and field_ are relative number fields which are isomorphic via # an absolute number field abs. diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 11d22c8672f..14e55237dd1 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -114,11 +114,9 @@ cpdef double odlyzko_bound_totallyreal(int n) noexcept: INPUT: - - ``n`` -- (integer) the degree + - ``n`` -- integer; the degree - OUTPUT: - - a lower bound on the root discriminant (as a real number) + OUTPUT: a lower bound on the root discriminant (as a real number) EXAMPLES:: @@ -172,28 +170,28 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False INPUT: - - ``n`` -- (integer) the degree - - ``B`` -- (integer) the discriminant bound - - ``a`` -- (list, default: ``[]``) the coefficient list to begin with + - ``n`` -- integer; the degree + - ``B`` -- integer; the discriminant bound + - ``a`` -- list (default: ``[]``); the coefficient list to begin with - ``verbose`` -- (integer or string, default: 0) if ``verbose == 1`` (or ``2``), then print to the screen (really) verbosely; if verbose is a string, then print verbosely to the file specified by verbose. - - ``return_seqs`` -- (boolean, default ``False``) If ``True``, then return - the polynomials as sequences (for easier exporting to a file). + - ``return_seqs`` -- boolean (default: ``False``); if ``True``, then return + the polynomials as sequences (for easier exporting to a file) - ``phc`` -- boolean or integer (default: ``False``) - - ``keep_fields`` -- (boolean or integer, default: ``False``) If + - ``keep_fields`` -- boolean or integer (default: ``False``); if ``keep_fields`` is ``True``, then keep fields up to ``B*log(B)``; if ``keep_fields`` is an integer, then keep fields up to that integer. - - ``t_2`` -- (boolean or integer, default: ``False``) If ``t_2 = T``, then - keep only polynomials with t_2 norm >= T. - - ``just_print`` -- (boolean, default: ``False``): if ``just_print`` is not + - ``t_2`` -- boolean or integer (default: ``False``); if ``t_2 = T``, then + keep only polynomials with ``t_2 norm >= T`` + - ``just_print`` -- boolean (default: ``False``); if ``just_print`` is not ``False``, instead of creating a sorted list of totally real number fields, we simply write each totally real field we find to the file whose filename is given by ``just_print``. In this case, we don't return anything. - - ``return_pari_objects`` -- (boolean, default: ``True``) if + - ``return_pari_objects`` -- boolean (default: ``True``); if both ``return_seqs`` and ``return_pari_objects`` are ``False`` then - it returns the elements as Sage objects; otherwise it returns PARI + it returns the elements as Sage objects. Otherwise it returns PARI objects. OUTPUT: @@ -236,7 +234,6 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False Univariate Polynomial Ring in x over Rational Field sage: enumerate_totallyreal_fields_prim(2, 10, return_seqs=True)[1][0][1][0].parent() Rational Field - """ cdef pari_gen B_pari, d, d_poly, keepB, nf, t2val, ngt2, ng diff --git a/src/sage/rings/number_field/totallyreal_data.pyx b/src/sage/rings/number_field/totallyreal_data.pyx index 9c31d5aa8e3..694e96235bc 100644 --- a/src/sage/rings/number_field/totallyreal_data.pyx +++ b/src/sage/rings/number_field/totallyreal_data.pyx @@ -457,10 +457,10 @@ cdef class tr_data: INPUT: - n -- integer, the degree - B -- integer, the discriminant bound - a -- list (default: ``[]``), the coefficient list to begin with, where - a[len(a)]*x^n + ... + a[0]x^(n-len(a)) + - ``n`` -- integer; the degree + - ``B`` -- integer; the discriminant bound + - ``a`` -- list (default: ``[]``); the coefficient list to begin with, + where ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))`` OUTPUT: @@ -593,14 +593,12 @@ cdef class tr_data: INPUT: - ``verbose`` -- boolean to print verbosely computational details - - ``haltk`` -- integer, the level at which to halt the inductive + - ``haltk`` -- integer; the level at which to halt the inductive coefficient bounds - ``phc`` -- boolean, if PHCPACK is available, use it when `k = n-5` to compute an improved Lagrange multiplier bound - OUTPUT: - - The next polynomial, as a sequence of integers + OUTPUT: the next polynomial, as a sequence of integers EXAMPLES:: @@ -648,13 +646,13 @@ cdef class tr_data: INPUT: - - f_out -- an integer sequence, to be written with the coefficients of + - ``f_out`` -- integer sequence, to be written with the coefficients of the next polynomial - - verbose -- boolean to print verbosely computational details - - haltk -- integer, the level at which to halt the inductive + - ``verbose`` -- boolean to print verbosely computational details + - ``haltk`` -- integer; the level at which to halt the inductive coefficient bounds - - phc -- boolean, if PHCPACK is available, use it when k == n-5 to - compute an improved Lagrange multiplier bound + - ``phc`` -- boolean; if PHCPACK is available, use it when ``k == n-5`` + to compute an improved Lagrange multiplier bound OUTPUT: @@ -915,7 +913,6 @@ cdef class tr_data: amax = [0, 0, 0, 1] beta = [...] gnk = [...] - """ print("k =", self.k) print("a =", [self.a[i] for i in range(self.n + 1)]) diff --git a/src/sage/rings/number_field/totallyreal_phc.py b/src/sage/rings/number_field/totallyreal_phc.py index e564d760320..db054708bb9 100644 --- a/src/sage/rings/number_field/totallyreal_phc.py +++ b/src/sage/rings/number_field/totallyreal_phc.py @@ -28,12 +28,10 @@ def coefficients_to_power_sums(n, m, a): INPUT: - - ``n`` -- integer, the degree - - ``a`` -- list of integers, the coefficients + - ``n`` -- integer; the degree + - ``a`` -- list of integers; the coefficients - OUTPUT: - - list of integers. + OUTPUT: list of integers .. NOTE:: @@ -64,12 +62,10 @@ def __lagrange_bounds_phc(n, m, a, tmpfile=None): INPUT: - - k -- integer, the index of the next coefficient - - a -- list of integers, the coefficients - - OUTPUT: + - ``k`` -- integer; the index of the next coefficient + - ``a`` -- list of integers; the coefficients - the lower and upper bounds as real numbers. + OUTPUT: the lower and upper bounds as real numbers .. NOTE:: @@ -128,7 +124,7 @@ def __lagrange_bounds_phc(n, m, a, tmpfile=None): os.remove(tmpfile + '.phc') os.popen('phc -b ' + tmpfile + ' ' + tmpfile + '.phc') - f = open(tmpfile + '.phc', 'r') + f = open(tmpfile + '.phc') f_str = f.read() pos = f_str.find('= real ') crits = [] diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 8ce8efb1c02..ac3f52a544c 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -118,7 +118,7 @@ def integral_elements_in_box(K, C): INPUT: - ``K`` -- a totally real number field - - ``C`` -- a list ``[[lower, upper], ...]`` of lower and upper bounds, + - ``C`` -- list ``[[lower, upper], ...]`` of lower and upper bounds, for each embedding EXAMPLES:: @@ -227,6 +227,7 @@ def integral_elements_in_box(K, C): eps_global = 10**(-6) + class tr_data_rel: r""" This class encodes the data used in the enumeration of totally real @@ -244,11 +245,11 @@ def __init__(self, F, m, B, a=None): INPUT: - - ``F`` -- number field, the base field - - ``m`` -- integer, the relative degree - - ``B`` -- integer, the discriminant bound - - ``a`` -- list (default: ``[]``), the coefficient list to begin with, - corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))``. + - ``F`` -- number field; the base field + - ``m`` -- integer; the relative degree + - ``B`` -- integer; the discriminant bound + - ``a`` -- list (default: ``[]``); the coefficient list to begin with, + corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))`` OUTPUT: @@ -371,17 +372,15 @@ def incr(self, f_out, verbose=False, haltk=0): INPUT: - - ``f_out`` -- an integer sequence, to be written with the - coefficients of the next polynomial - - ``verbose`` -- boolean or nonnegative integer (default: ``False``) - print verbosely computational details. It prints extra - information if ``verbose`` is set to ``2`` or more - - ``haltk`` -- integer, the level at which to halt the inductive + - ``f_out`` -- integer sequence; to be written with the coefficients of + the next polynomial + - ``verbose`` -- boolean or nonnegative integer (default: ``False``); + print verbosely computational details. It prints extra information if + ``verbose`` is set to ``2`` or more. + - ``haltk`` -- integer; the level at which to halt the inductive coefficient bounds - OUTPUT: - - the successor polynomial as a coefficient list. + OUTPUT: the successor polynomial as a coefficient list """ import numpy @@ -655,30 +654,29 @@ def enumerate_totallyreal_fields_rel(F, m, B, a=[], verbose=0, if ``length(a) = d+1``, so in particular always ``a[d] = 1``. - .. note:: + .. NOTE:: This is guaranteed to give all primitive such fields, and seems in practice to give many imprimitive ones. INPUT: - - ``F`` -- number field, the base field - - ``m`` -- integer, the degree - - ``B`` -- integer, the discriminant bound - - ``a`` -- list (default: ``[]``), the coefficient list to begin with - - ``verbose`` -- boolean or nonnegative integer or string (default: 0) + - ``F`` -- number field; the base field + - ``m`` -- integer; the degree + - ``B`` -- integer; the discriminant bound + - ``a`` -- list (default: ``[]``); the coefficient list to begin with + - ``verbose`` -- boolean or nonnegative integer or string (default: 0); give a verbose description of the computations being performed. If ``verbose`` is set to ``2`` or more then it outputs some extra information. If ``verbose`` is a string then it outputs to a file - specified by ``verbose`` - - ``return_seqs`` -- (boolean, default ``False``) If ``True``, then return + specified by ``verbose``. + - ``return_seqs`` -- boolean (default: ``False``); if ``True``, then return the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT section below. - - ``return_pari_objects`` -- (boolean, default: ``True``) if - both ``return_seqs`` and ``return_pari_objects`` are ``False`` then - it returns the elements as Sage objects; otherwise it returns PARI - objects. + - ``return_pari_objects`` -- boolean (default: ``True``); if both + ``return_seqs`` and ``return_pari_objects`` are ``False`` then it returns + the elements as Sage objects; otherwise it returns PARI objects. OUTPUT: @@ -910,21 +908,19 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, INPUT: - - ``n`` -- integer, the degree - - ``B`` -- integer, the discriminant bound - - ``verbose`` -- boolean or nonnegative integer or string (default: 0) + - ``n`` -- integer; the degree + - ``B`` -- integer; the discriminant bound + - ``verbose`` -- boolean or nonnegative integer or string (default: 0); give a verbose description of the computations being performed. If - ``verbose`` is set to ``2`` or more, it outputs some extra - information. If ``verbose`` is a string, it outputs to a file - specified by ``verbose`` - - ``return_seqs`` -- (boolean, default ``False``) If ``True``, then return + ``verbose`` is set to ``2`` or more, it outputs some extra information. + If ``verbose`` is a string, it outputs to a file specified by ``verbose``. + - ``return_seqs`` -- boolean (default: ``False``); if ``True``, then return the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT section below. - - ``return_pari_objects`` -- (boolean, default: ``True``) if both + - ``return_pari_objects`` -- boolean (default: ``True``); if both ``return_seqs`` and ``return_pari_objects`` are ``False`` then it - returns the elements as Sage objects; otherwise it returns PARI - objects. + returns the elements as Sage objects; otherwise it returns PARI objects. EXAMPLES:: diff --git a/src/sage/rings/number_field/unit_group.py b/src/sage/rings/number_field/unit_group.py index a98c1dd0907..eb6b46ed82e 100644 --- a/src/sage/rings/number_field/unit_group.py +++ b/src/sage/rings/number_field/unit_group.py @@ -235,7 +235,7 @@ def __init__(self, number_field, proof=True, S=None): INPUT: - ``number_field`` -- a number field - - ``proof`` -- boolean (default ``True``): proof flag + - ``proof`` -- boolean (default: ``True``); proof flag - ``S`` -- tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in which case the support is used. If ``None``, the global unit @@ -311,8 +311,6 @@ def __init__(self, number_field, proof=True, S=None): sage: K = QuadraticField(d) sage: K.unit_group(proof=False) Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 12936642 with a = 3596.754370262167? - - """ proof = get_flag(proof, "number_field") K = number_field @@ -369,14 +367,14 @@ def __init__(self, number_field, proof=True, S=None): def _element_constructor_(self, u): """ - Returns the abstract group element corresponding to the unit u. + Return the abstract group element corresponding to the unit u. INPUT: - - ``u`` -- Any object from which an element of the unit group's number + - ``u`` -- any object from which an element of the unit group's number field `K` may be constructed; an error is raised if an element of `K` cannot be constructed from u, or if the element constructed is not a - unit. + unit EXAMPLES:: @@ -515,7 +513,7 @@ def torsion_generator(self): def zeta_order(self): """ - Returns the order of the torsion part of the unit group. + Return the order of the torsion part of the unit group. EXAMPLES:: @@ -564,7 +562,6 @@ def zeta(self, n=2, all=False): ValueError: n (=3) does not divide order of generator sage: U.zeta(3, all=True) [] - """ N = self.__ntu K = self.number_field() @@ -631,13 +628,13 @@ def log(self, u): INPUT: - - ``u`` -- Any object from which an element of the unit group's number + - ``u`` -- any object from which an element of the unit group's number field `K` may be constructed; an error is raised if an element of `K` cannot be constructed from `u`, or if the element constructed is not a - unit. + unit - OUTPUT: a list of integers giving the exponents of `u` with - respect to the unit group's basis. + OUTPUT: list of integers giving the exponents of `u` with + respect to the unit group's basis EXAMPLES:: @@ -678,12 +675,12 @@ def exp(self, exponents): INPUT: - - ``u`` -- Any object from which an element of the unit + - ``u`` -- any object from which an element of the unit group's number field `K` may be constructed; an error is raised if an element of `K` cannot be constructed from `u`, or if the element constructed is not a unit. - OUTPUT: a list of integers giving the exponents of `u` with + OUTPUT: list of integers giving the exponents of `u` with respect to the unit group's basis. EXAMPLES:: diff --git a/src/sage/rings/padics/CA_template.pxi b/src/sage/rings/padics/CA_template.pxi index e8d906b01c8..0e6a10b67d9 100644 --- a/src/sage/rings/padics/CA_template.pxi +++ b/src/sage/rings/padics/CA_template.pxi @@ -48,7 +48,7 @@ from sage.categories.homset import Hom cdef class CAElement(pAdicTemplateElement): cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1: """ - Sets the value of this element from given defining data. + Set the value of this element from given defining data. This function is intended for use in conversion, and should not be called on an element created with :meth:`_new_c`. @@ -134,7 +134,7 @@ cdef class CAElement(pAdicTemplateElement): cdef int _get_unit(self, celement value) except -1: """ - Set ``value`` to the unit of this p-adic element. + Set ``value`` to the unit of this `p`-adic element. """ cremove(value, self.value, self.absprec, self.prime_pow, True) @@ -410,11 +410,9 @@ cdef class CAElement(pAdicTemplateElement): INPUT: - - ``_right`` -- currently integers and `p`-adic exponents are - supported. + - ``_right`` -- currently integers and `p`-adic exponents are supported - - ``dummy`` -- not used (Python's ``__pow__`` signature - includes it) + - ``dummy`` -- not used (Python's ``__pow__`` signature includes it) EXAMPLES:: @@ -536,7 +534,7 @@ cdef class CAElement(pAdicTemplateElement): cdef pAdicTemplateElement _lshift_c(self, long shift): r""" - Multiplies by `\pi^{\mbox{shift}}`. + Multiply by `\pi^{\mbox{shift}}`. Negative shifts may truncate the result. @@ -568,7 +566,7 @@ cdef class CAElement(pAdicTemplateElement): cdef pAdicTemplateElement _rshift_c(self, long shift): r""" - Divides by ``π^{\mbox{shift}}``. + Divide by ``π^{\mbox{shift}}``. Positive shifts may truncate the result. @@ -605,11 +603,10 @@ cdef class CAElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer or infinity + - ``absprec`` -- integer or infinity - OUTPUT: - - ``self`` with precision set to the minimum of ``self's`` precision and ``prec`` + OUTPUT: ``self`` with precision set to the minimum of ``self``'s + precision and ``prec`` EXAMPLES:: @@ -630,7 +627,6 @@ cdef class CAElement(pAdicTemplateElement): sage: k(3).add_bigoh(-1) O(3^-1) - """ cdef long aprec, newprec if absprec is infinity: @@ -698,7 +694,7 @@ cdef class CAElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer, infinity, or ``None`` + - ``absprec`` -- integer, infinity, or ``None`` EXAMPLES:: @@ -758,7 +754,7 @@ cdef class CAElement(pAdicTemplateElement): - ``right`` -- a `p`-adic element with the same parent - - ``absprec`` -- an integer, infinity, or ``None`` + - ``absprec`` -- integer, infinity, or ``None`` EXAMPLES:: @@ -824,8 +820,7 @@ cdef class CAElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer, at most the precision cap of the - parent + - ``absprec`` -- integer; at most the precision cap of the parent EXAMPLES:: @@ -1103,7 +1098,6 @@ cdef class pAdicCoercion_ZZ_CA(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, R): """ @@ -1242,11 +1236,11 @@ cdef class pAdicCoercion_ZZ_CA(RingHomomorphism): cdef class pAdicConvert_CA_ZZ(RingMap): """ The map from a capped absolute ring back to the ring of integers that - returns the smallest non-negative integer approximation to its input + returns the smallest nonnegative integer approximation to its input which is accurate up to the precision. - Raises a ``ValueError`` if the input is not in the closure of the image of - the ring of integers. + Raises a :exc:`ValueError` if the input is not in the closure of the image + of the ring of integers. EXAMPLES:: @@ -1291,7 +1285,7 @@ cdef class pAdicConvert_CA_ZZ(RingMap): cdef class pAdicConvert_QQ_CA(Morphism): """ The inclusion map from the rationals to a capped absolute ring that is - defined on all elements with non-negative `p`-adic valuation. + defined on all elements with nonnegative `p`-adic valuation. EXAMPLES:: @@ -1433,7 +1427,6 @@ cdef class pAdicCoercion_CA_frac_field(RingHomomorphism): TESTS:: sage: TestSuite(f).run() # needs sage.libs.flint - """ def __init__(self, R, K): """ @@ -1533,7 +1526,7 @@ cdef class pAdicCoercion_CA_frac_field(RingHomomorphism): def section(self): """ Return a map back to the ring that converts elements of - non-negative valuation. + nonnegative valuation. EXAMPLES:: @@ -1577,7 +1570,6 @@ cdef class pAdicCoercion_CA_frac_field(RingHomomorphism): a + O(3^20) sage: g(a) == f(a) True - """ _slots = RingHomomorphism._extra_slots(self) _slots['_zero'] = self._zero @@ -1607,7 +1599,6 @@ cdef class pAdicCoercion_CA_frac_field(RingHomomorphism): a + O(3^20) sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] self._section = _slots['_section'] @@ -1625,7 +1616,6 @@ cdef class pAdicCoercion_CA_frac_field(RingHomomorphism): sage: f = K.coerce_map_from(R) sage: f.is_injective() True - """ return True @@ -1641,7 +1631,6 @@ cdef class pAdicCoercion_CA_frac_field(RingHomomorphism): sage: f = K.coerce_map_from(R) sage: f.is_surjective() False - """ return False @@ -1816,7 +1805,6 @@ cdef class pAdicConvert_CA_frac_field(Morphism): a + O(3^20) sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] Morphism._update_slots(self, _slots) diff --git a/src/sage/rings/padics/CR_template.pxi b/src/sage/rings/padics/CR_template.pxi index acdc4803670..853a3c3df79 100644 --- a/src/sage/rings/padics/CR_template.pxi +++ b/src/sage/rings/padics/CR_template.pxi @@ -50,18 +50,18 @@ cdef inline bint exactzero(long ordp) noexcept: cdef inline int check_ordp_mpz(mpz_t ordp) except -1: """ - Checks for overflow after addition or subtraction of valuations. + Check for overflow after addition or subtraction of valuations. There is another variant, :meth:`check_ordp`, for long input. - If overflow is detected, raises an ``OverflowError``. + If overflow is detected, raises an :exc:`OverflowError`. """ if mpz_fits_slong_p(ordp) == 0 or mpz_cmp_si(ordp, maxordp) > 0 or mpz_cmp_si(ordp, minusmaxordp) < 0: raise OverflowError("valuation overflow") cdef inline int assert_nonzero(CRElement x) except -1: """ - Checks that ``x`` is distinguishable from zero. + Check that ``x`` is distinguishable from zero. Used in division and floor division. """ @@ -73,7 +73,7 @@ cdef inline int assert_nonzero(CRElement x) except -1: cdef class CRElement(pAdicTemplateElement): cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1: """ - Sets the value of this element from given defining data. + Set the value of this element from given defining data. This function is intended for use in conversion, and should not be called on an element created with :meth:`_new_c`. @@ -152,7 +152,7 @@ cdef class CRElement(pAdicTemplateElement): cdef int _set_exact_zero(self) except -1: """ - Sets ``self`` as an exact zero. + Set ``self`` as an exact zero. TESTS:: @@ -165,7 +165,7 @@ cdef class CRElement(pAdicTemplateElement): cdef int _set_inexact_zero(self, long absprec) except -1: """ - Sets ``self`` as an inexact zero with precision ``absprec``. + Set ``self`` as an inexact zero with precision ``absprec``. TESTS:: @@ -178,7 +178,7 @@ cdef class CRElement(pAdicTemplateElement): cdef CRElement _new_c(self): """ - Creates a new element with the same basic info. + Create a new element with the same basic info. TESTS:: @@ -206,7 +206,7 @@ cdef class CRElement(pAdicTemplateElement): cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec): """ - Creates a new element with a given value and absolute precision. + Create a new element with a given value and absolute precision. Used by code that doesn't know the precision type. """ @@ -219,13 +219,13 @@ cdef class CRElement(pAdicTemplateElement): cdef int _get_unit(self, celement value) except -1: """ - Sets ``value`` to the unit of this p-adic element. + Set ``value`` to the unit of this `p`-adic element. """ ccopy(value, self.unit, self.prime_pow) cdef int check_preccap(self) except -1: """ - Checks that this element doesn't have precision higher than + Check that this element doesn't have precision higher than allowed by the precision cap. TESTS:: @@ -258,7 +258,7 @@ cdef class CRElement(pAdicTemplateElement): cdef int _normalize(self) except -1: """ - Normalizes this element, so that ``self.ordp`` is correct. + Normalize this element, so that ``self.ordp`` is correct. TESTS:: @@ -619,7 +619,7 @@ cdef class CRElement(pAdicTemplateElement): INPUT: - ``_right`` -- currently integers and `p`-adic exponents are - supported. + supported - ``dummy`` -- not used (Python's ``__pow__`` signature includes it) @@ -736,7 +736,7 @@ cdef class CRElement(pAdicTemplateElement): cdef pAdicTemplateElement _lshift_c(self, long shift): r""" - Multiplies by `\pi^{\mbox{shift}}`. + Multiply by `\pi^{\mbox{shift}}`. Negative shifts may truncate the result if the parent is not a field. @@ -767,7 +767,7 @@ cdef class CRElement(pAdicTemplateElement): cdef pAdicTemplateElement _rshift_c(self, long shift): r""" - Divides by ``\pi^{\mbox{shift}}``. + Divide by ``\pi^{\mbox{shift}}``. Positive shifts may truncate the result if the parent is not a field. @@ -808,7 +808,7 @@ cdef class CRElement(pAdicTemplateElement): """ Quotient with remainder. - We choose the remainder to have the same p-adic expansion + We choose the remainder to have the same `p`-adic expansion as the numerator, but truncated at the valuation of the denominator. EXAMPLES:: @@ -889,7 +889,7 @@ cdef class CRElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer or infinity + - ``absprec`` -- integer or infinity OUTPUT: @@ -1002,7 +1002,7 @@ cdef class CRElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer, infinity, or ``None`` + - ``absprec`` -- integer, infinity, or ``None`` EXAMPLES:: @@ -1064,7 +1064,7 @@ cdef class CRElement(pAdicTemplateElement): INPUT: - ``right`` -- a `p`-adic element - - ``absprec`` -- an integer, infinity, or ``None`` + - ``absprec`` -- integer, infinity, or ``None`` EXAMPLES:: @@ -1261,7 +1261,7 @@ cdef class CRElement(pAdicTemplateElement): def _teichmuller_set_unsafe(self): """ - Sets this element to the Teichmuller representative with the + Set this element to the Teichmuller representative with the same residue. .. WARNING:: @@ -1369,7 +1369,7 @@ cdef class CRElement(pAdicTemplateElement): def precision_absolute(self): """ - Returns the absolute precision of this element. + Return the absolute precision of this element. This is the power of the maximal ideal modulo which this element is defined. @@ -1469,7 +1469,7 @@ cdef class CRElement(pAdicTemplateElement): """ Return the valuation of this element. - If self is an exact zero, returns ``maxordp``, which is defined as + If ``self`` is an exact zero, returns ``maxordp``, which is defined as ``(1L << (sizeof(long) * 8 - 2))-1``. EXAMPLES:: @@ -1490,7 +1490,8 @@ cdef class CRElement(pAdicTemplateElement): INPUT: - - ``p`` -- a prime (default: ``None``). If specified, will make sure that ``p == self.parent().prime()`` + - ``p`` -- a prime (default: ``None``); if specified, will make sure + that ``p == self.parent().prime()`` .. NOTE:: @@ -1559,7 +1560,6 @@ cdef class pAdicCoercion_ZZ_CR(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, R): """ @@ -1620,7 +1620,6 @@ cdef class pAdicCoercion_ZZ_CR(RingHomomorphism): 5 + O(5^21) sage: g(5) == f(5) True - """ self._zero = _slots['_zero'] self._section = _slots['_section'] @@ -1692,7 +1691,7 @@ cdef class pAdicCoercion_ZZ_CR(RingHomomorphism): def section(self): """ - Returns a map back to the ring of integers that approximates an element + Return a map back to the ring of integers that approximates an element by an integer. EXAMPLES:: @@ -1710,10 +1709,10 @@ cdef class pAdicCoercion_ZZ_CR(RingHomomorphism): cdef class pAdicConvert_CR_ZZ(RingMap): """ The map from a capped relative ring back to the ring of integers that - returns the smallest non-negative integer approximation to its input + returns the smallest nonnegative integer approximation to its input which is accurate up to the precision. - Raises a :class:`ValueError`, if the input is not in the closure of the image of + Raises a :exc:`ValueError`, if the input is not in the closure of the image of the integers. EXAMPLES:: @@ -1777,7 +1776,6 @@ cdef class pAdicCoercion_QQ_CR(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, R): """ @@ -1838,7 +1836,6 @@ cdef class pAdicCoercion_QQ_CR(RingHomomorphism): 1 + 5 + O(5^20) sage: g(6) == f(6) True - """ self._zero = _slots['_zero'] self._section = _slots['_section'] @@ -1914,7 +1911,7 @@ cdef class pAdicCoercion_QQ_CR(RingHomomorphism): def section(self): """ - Returns a map back to the rationals that approximates an element by + Return a map back to the rationals that approximates an element by a rational number. EXAMPLES:: @@ -1984,7 +1981,7 @@ cdef class pAdicConvert_CR_QQ(RingMap): cdef class pAdicConvert_QQ_CR(Morphism): """ The inclusion map from the rationals to a capped relative ring that is - defined on all elements with non-negative `p`-adic valuation. + defined on all elements with nonnegative `p`-adic valuation. EXAMPLES:: @@ -2120,7 +2117,7 @@ cdef class pAdicConvert_QQ_CR(Morphism): def section(self): """ Return the map back to the rationals that returns the smallest - non-negative integer approximation to its input which is accurate up to + nonnegative integer approximation to its input which is accurate up to the precision. EXAMPLES:: @@ -2152,7 +2149,6 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): TESTS:: sage: TestSuite(f).run() # needs sage.libs.flint - """ def __init__(self, R, K): """ @@ -2257,7 +2253,7 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): def section(self): """ Return a map back to the ring that converts elements of - non-negative valuation. + nonnegative valuation. EXAMPLES:: @@ -2301,7 +2297,6 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): a + O(3^20) sage: g(a) == f(a) True - """ _slots = RingHomomorphism._extra_slots(self) _slots['_zero'] = self._zero @@ -2331,7 +2326,6 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): a + O(3^20) sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] self._section = _slots['_section'] @@ -2349,7 +2343,6 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): sage: f = K.coerce_map_from(R) sage: f.is_injective() True - """ return True @@ -2365,7 +2358,6 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): sage: f = K.coerce_map_from(R) sage: f.is_surjective() False - """ return False @@ -2538,7 +2530,6 @@ cdef class pAdicConvert_CR_frac_field(Morphism): a + O(3^20) sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] Morphism._update_slots(self, _slots) diff --git a/src/sage/rings/padics/FM_template.pxi b/src/sage/rings/padics/FM_template.pxi index 8ce93d797a8..c05930fb0af 100644 --- a/src/sage/rings/padics/FM_template.pxi +++ b/src/sage/rings/padics/FM_template.pxi @@ -47,7 +47,7 @@ from sage.categories.homset import Hom cdef class FMElement(pAdicTemplateElement): cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1: """ - Sets the value of this element from given defining data. + Set the value of this element from given defining data. This function is intended for use in conversion, and should not be called on an element created with :meth:`_new_c`. @@ -91,7 +91,7 @@ cdef class FMElement(pAdicTemplateElement): cdef FMElement _new_c(self): """ - Creates a new element with the same basic info. + Create a new element with the same basic info. TESTS:: @@ -110,7 +110,7 @@ cdef class FMElement(pAdicTemplateElement): cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec): """ - Creates a new element with a given value and absolute precision. + Create a new element with a given value and absolute precision. Used by code that doesn't know the precision type. """ @@ -120,7 +120,7 @@ cdef class FMElement(pAdicTemplateElement): cdef int _get_unit(self, celement value) except -1: """ - Sets ``value`` to the unit of this p-adic element. + Set ``value`` to the unit of this `p`-adic element. """ cremove(value, self.value, self.prime_pow.ram_prec_cap, self.prime_pow) @@ -236,7 +236,7 @@ cdef class FMElement(pAdicTemplateElement): def __invert__(self): r""" - Returns multiplicative inverse of this element. The valuation + Return multiplicative inverse of this element. The valuation of ``self`` must be zero. EXAMPLES:: @@ -381,7 +381,7 @@ cdef class FMElement(pAdicTemplateElement): cdef pAdicTemplateElement _lshift_c(self, long shift): r""" - Multiplies self by `\pi^{shift}`. + Multiply ``self`` by `\pi^{shift}`. If shift < -self.valuation(), digits will be truncated. See :meth:`__rshift__` for details. @@ -428,7 +428,7 @@ cdef class FMElement(pAdicTemplateElement): cdef pAdicTemplateElement _rshift_c(self, long shift): r""" - Divides by `\pi^{shift}`, and truncates. + Divide by `\pi^{shift}`, and truncate. Note that this operation will insert arbitrary digits (in practice, currently all zero) in the least significant digits. @@ -466,11 +466,9 @@ cdef class FMElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer or infinity + - ``absprec`` -- integer or infinity - OUTPUT: - - a new element truncated modulo `\pi^{\mbox{absprec}}`. + OUTPUT: a new element truncated modulo `\pi^{\mbox{absprec}}` EXAMPLES:: @@ -486,7 +484,6 @@ cdef class FMElement(pAdicTemplateElement): 7 sage: a.add_bigoh(-2^1000) 0 - """ cdef long aprec if absprec is infinity: @@ -512,7 +509,7 @@ cdef class FMElement(pAdicTemplateElement): cpdef bint _is_exact_zero(self) except -1: """ - Tests whether this element is an exact zero, which is always + Test whether this element is an exact zero, which is always False for fixed modulus elements. EXAMPLES:: @@ -524,7 +521,7 @@ cdef class FMElement(pAdicTemplateElement): cpdef bint _is_inexact_zero(self) except -1: """ - Return ``True`` if self is indistinguishable from zero. + Return ``True`` if ``self`` is indistinguishable from zero. EXAMPLES:: @@ -538,11 +535,11 @@ cdef class FMElement(pAdicTemplateElement): def is_zero(self, absprec = None): r""" - Returns whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. + Return whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. INPUT: - - ``absprec`` -- an integer + - ``absprec`` -- integer EXAMPLES:: @@ -588,7 +585,7 @@ cdef class FMElement(pAdicTemplateElement): INPUT: - ``right`` -- a `p`-adic element with the same parent - - ``absprec`` -- a positive integer or ``None`` (default: ``None``) + - ``absprec`` -- positive integer or ``None`` (default: ``None``) EXAMPLES:: @@ -666,7 +663,7 @@ cdef class FMElement(pAdicTemplateElement): def _teichmuller_set_unsafe(self): """ - Sets this element to the Teichmuller representative with the + Set this element to the Teichmuller representative with the same residue. .. WARNING:: @@ -882,7 +879,6 @@ cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, R): """ @@ -963,7 +959,7 @@ cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): - ``x`` -- an Integer - ``absprec``, or the first positional argument -- the maximum - absolute precision (unused for fixed modulus elements). + absolute precision (unused for fixed modulus elements) - ``relprec``, or the second positional argument -- the maximum relative precision (unused for fixed modulus @@ -995,7 +991,7 @@ cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): def section(self): r""" - Returns a map back to `\ZZ` that approximates an element of this + Return a map back to `\ZZ` that approximates an element of this `p`-adic ring by an integer. EXAMPLES:: @@ -1013,9 +1009,9 @@ cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): cdef class pAdicConvert_FM_ZZ(RingMap): r""" The map from a fixed modulus ring back to `\ZZ` that returns the smallest - non-negative integer approximation to its input which is accurate up to the precision. + nonnegative integer approximation to its input which is accurate up to the precision. - If the input is not in the closure of the image of `\ZZ`, raises a :class:`ValueError`. + If the input is not in the closure of the image of `\ZZ`, raises a :exc:`ValueError`. EXAMPLES:: @@ -1060,7 +1056,7 @@ cdef class pAdicConvert_FM_ZZ(RingMap): cdef class pAdicConvert_QQ_FM(Morphism): r""" The inclusion map from `\QQ` to a fixed modulus ring that is defined - on all elements with non-negative `p`-adic valuation. + on all elements with nonnegative `p`-adic valuation. EXAMPLES:: @@ -1145,7 +1141,7 @@ cdef class pAdicConvert_QQ_FM(Morphism): - ``x`` -- a Rational - ``absprec``, or the first positional argument -- the maximum - absolute precision (unused for fixed modulus elements). + absolute precision (unused for fixed modulus elements) - ``relprec``, or the second positional argument -- the maximum relative precision (unused for fixed modulus @@ -1192,7 +1188,6 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): TESTS:: sage: TestSuite(f).run() # needs sage.libs.flint - """ def __init__(self, R, K): """ @@ -1288,7 +1283,7 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): def section(self): """ Return a map back to the ring that converts elements of - non-negative valuation. + nonnegative valuation. EXAMPLES:: @@ -1357,7 +1352,6 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): a sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] self._section = _slots['_section'] @@ -1375,7 +1369,6 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): sage: f = K.coerce_map_from(R) sage: f.is_injective() True - """ return True @@ -1391,7 +1384,6 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): sage: f = K.coerce_map_from(R) sage: f.is_surjective() False - """ return False @@ -1553,7 +1545,6 @@ cdef class pAdicConvert_FM_frac_field(Morphism): a sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] Morphism._update_slots(self, _slots) diff --git a/src/sage/rings/padics/FP_template.pxi b/src/sage/rings/padics/FP_template.pxi index 5c7f94051e7..654c3d6b6a3 100644 --- a/src/sage/rings/padics/FP_template.pxi +++ b/src/sage/rings/padics/FP_template.pxi @@ -87,7 +87,7 @@ cdef inline bint huge_val(long ordp) noexcept: cdef class FPElement(pAdicTemplateElement): cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1: """ - Sets the value of this element from given defining data. + Set the value of this element from given defining data. This function is intended for use in conversion, and should not be called on an element created with :meth:`_new_c`. @@ -100,10 +100,10 @@ cdef class FPElement(pAdicTemplateElement): - ``val`` -- the valuation of the resulting element - ``xprec -- an inherent precision of ``x``, if ``val`` - is larger then the result will be zero. + is larger then the result will be zero - ``absprec`` -- an absolute precision cap for this element, - if ``val`` is larger then the result will be zero. + if ``val`` is larger then the result will be zero - ``relprec`` -- a relative precision cap for this element (unused; for compatibility with other `p`-adic precision @@ -149,7 +149,7 @@ cdef class FPElement(pAdicTemplateElement): cdef int _set_exact_zero(self) except -1: """ - Sets this element to zero. + Set this element to zero. TESTS:: @@ -161,7 +161,7 @@ cdef class FPElement(pAdicTemplateElement): cdef int _set_infinity(self) except -1: """ - Sets this element to zero. + Set this element to zero. TESTS:: @@ -173,7 +173,7 @@ cdef class FPElement(pAdicTemplateElement): cdef FPElement _new_c(self): """ - Creates a new element with the same basic info. + Create a new element with the same basic info. TESTS:: @@ -199,7 +199,7 @@ cdef class FPElement(pAdicTemplateElement): cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec): """ - Creates a new element with a given value and absolute precision. + Create a new element with a given value and absolute precision. Used by code that doesn't know the precision type. """ @@ -211,7 +211,7 @@ cdef class FPElement(pAdicTemplateElement): cdef int _get_unit(self, celement value) except -1: """ - Sets ``value`` to the unit of this p-adic element. + Set ``value`` to the unit of this `p`-adic element. """ ccopy(value, self.unit, self.prime_pow) @@ -246,7 +246,7 @@ cdef class FPElement(pAdicTemplateElement): cdef int _normalize(self) except -1: """ - Normalizes this element, so that ``self.ordp`` is correct. + Normalize this element, so that ``self.ordp`` is correct. TESTS:: @@ -429,7 +429,7 @@ cdef class FPElement(pAdicTemplateElement): def __invert__(self): r""" - Returns multiplicative inverse of this element. + Return multiplicative inverse of this element. EXAMPLES:: @@ -530,7 +530,7 @@ cdef class FPElement(pAdicTemplateElement): """ Quotient with remainder. - We choose the remainder to have the same p-adic expansion + We choose the remainder to have the same `p`-adic expansion as the numerator, but truncated at the valuation of the denominator. EXAMPLES:: @@ -667,7 +667,7 @@ cdef class FPElement(pAdicTemplateElement): cdef pAdicTemplateElement _lshift_c(self, long shift): r""" - Multiplies self by `\pi^{shift}`. + Multiply ``self`` by `\pi^{shift}`. Negative shifts may truncate the result if the parent is not a field. @@ -720,7 +720,7 @@ cdef class FPElement(pAdicTemplateElement): cdef pAdicTemplateElement _rshift_c(self, long shift): r""" - Divides by `\pi^{shift}`. + Divide by `\pi^{shift}`. Positive shifts may truncate the result if the parent is not a field. @@ -778,10 +778,10 @@ cdef class FPElement(pAdicTemplateElement): INPUT: - ``mode`` -- allows one to override the default print mode of - the parent (default: ``None``). + the parent (default: ``None``) - ``do_latex`` -- whether to return a latex representation or - a normal one. + a normal one EXAMPLES:: @@ -800,11 +800,9 @@ cdef class FPElement(pAdicTemplateElement): INPUT: - - ``absprec`` -- an integer or infinity + - ``absprec`` -- integer or infinity - OUTPUT: - - a new element truncated modulo `\pi^{\mbox{absprec}}`. + OUTPUT: a new element truncated modulo `\pi^{\mbox{absprec}}` EXAMPLES:: @@ -839,7 +837,7 @@ cdef class FPElement(pAdicTemplateElement): cpdef bint _is_exact_zero(self) except -1: """ - Tests whether this element is exactly zero. + Test whether this element is exactly zero. EXAMPLES:: @@ -852,7 +850,7 @@ cdef class FPElement(pAdicTemplateElement): cpdef bint _is_inexact_zero(self) except -1: """ - Return ``True`` if self is indistinguishable from zero. + Return ``True`` if ``self`` is indistinguishable from zero. EXAMPLES:: @@ -866,11 +864,11 @@ cdef class FPElement(pAdicTemplateElement): def is_zero(self, absprec = None): r""" - Returns whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. + Return whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. INPUT: - - ``absprec`` -- an integer + - ``absprec`` -- integer EXAMPLES:: @@ -919,7 +917,7 @@ cdef class FPElement(pAdicTemplateElement): INPUT: - ``right`` -- a `p`-adic element with the same parent - - ``absprec`` -- a positive integer or ``None`` (default: ``None``) + - ``absprec`` -- positive integer or ``None`` (default: ``None``) EXAMPLES:: @@ -1006,7 +1004,7 @@ cdef class FPElement(pAdicTemplateElement): def _teichmuller_set_unsafe(self): """ - Sets this element to the Teichmuller representative with the + Set this element to the Teichmuller representative with the same residue. .. WARNING:: @@ -1264,7 +1262,6 @@ cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, R): """ @@ -1345,7 +1342,7 @@ cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): - ``x`` -- an Integer - ``absprec``, or the first positional argument -- the maximum - absolute precision (unused for floating point elements). + absolute precision (unused for floating point elements) - ``relprec``, or the second positional argument -- the maximum relative precision (unused for floating point @@ -1384,7 +1381,7 @@ cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): def section(self): r""" - Returns a map back to `\ZZ` that approximates an element of this + Return a map back to `\ZZ` that approximates an element of this `p`-adic ring by an integer. EXAMPLES:: @@ -1403,9 +1400,9 @@ cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): cdef class pAdicConvert_FP_ZZ(RingMap): r""" The map from a floating point ring back to `\ZZ` that returns the smallest - non-negative integer approximation to its input which is accurate up to the precision. + nonnegative integer approximation to its input which is accurate up to the precision. - If the input is not in the closure of the image of `\ZZ`, raises a :class:`ValueError`. + If the input is not in the closure of the image of `\ZZ`, raises a :exc:`ValueError`. EXAMPLES:: @@ -1476,7 +1473,6 @@ cdef class pAdicCoercion_QQ_FP(RingHomomorphism): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, R): """ @@ -1760,7 +1756,7 @@ cdef class pAdicConvert_QQ_FP(Morphism): - ``x`` -- a Rational - ``absprec``, or the first positional argument -- the maximum - absolute precision (unused for floating point elements). + absolute precision (unused for floating point elements) - ``relprec``, or the second positional argument -- the maximum relative precision (unused for floating point @@ -1815,7 +1811,6 @@ cdef class pAdicCoercion_FP_frac_field(RingHomomorphism): TESTS:: sage: TestSuite(f).run() # needs sage.libs.flint - """ def __init__(self, R, K): r""" @@ -1916,7 +1911,7 @@ cdef class pAdicCoercion_FP_frac_field(RingHomomorphism): def section(self): r""" Return a map back to the ring that converts elements of - non-negative valuation. + nonnegative valuation. EXAMPLES:: @@ -1981,7 +1976,6 @@ cdef class pAdicCoercion_FP_frac_field(RingHomomorphism): a sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] self._section = _slots['_section'] @@ -2151,7 +2145,6 @@ cdef class pAdicConvert_FP_frac_field(Morphism): a sage: g(a) == f(a) True - """ self._zero = _slots['_zero'] Morphism._update_slots(self, _slots) diff --git a/src/sage/rings/padics/README.txt b/src/sage/rings/padics/README.txt index b1204f9c63a..ed259a23f46 100644 --- a/src/sage/rings/padics/README.txt +++ b/src/sage/rings/padics/README.txt @@ -8,7 +8,7 @@ #***************************************************************************** This document aims at explaining the (somehow complicated) file structure and -class hierarchy for p-adics in Sage. +class hierarchy for `p`-adics in Sage. Below is a representation of the parent hierarchy. diff --git a/src/sage/rings/padics/common_conversion.pyx b/src/sage/rings/padics/common_conversion.pyx index 2a143e6d99e..a352cc74c18 100644 --- a/src/sage/rings/padics/common_conversion.pyx +++ b/src/sage/rings/padics/common_conversion.pyx @@ -1,9 +1,9 @@ r""" -The functions in this file are used in creating new p-adic elements. +The functions in this file are used in creating new `p`-adic elements. -When creating a p-adic element, the user can specify that the absolute +When creating a `p`-adic element, the user can specify that the absolute precision be bounded and/or that the relative precision be bounded. -Moreover, different p-adic parents impose their own bounds on the +Moreover, different `p`-adic parents impose their own bounds on the relative or absolute precision of their elements. The precision determines to what power of `p` the defining data will be reduced, but the valuation of the resulting element needs to be determined before @@ -65,9 +65,9 @@ cdef long get_ordp(x, PowComputer_class prime_pow) except? -10000: INPUT: - - ``x`` -- data defining a new p-adic element: a Python int, an + - ``x`` -- data defining a new `p`-adic element: a Python int, an Integer, Rational, an element of Zp or Qp with the same prime, a - PARI p-adic element, a list, a tuple, or an IntegerMod. + PARI `p`-adic element, a list, a tuple, or an IntegerMod. - a PowComputer associated to a `p`-adic ring, which determines the prime and the ramification degree. @@ -176,9 +176,9 @@ cdef long get_preccap(x, PowComputer_class prime_pow) except? -10000: INPUT: - - ``x`` -- data defining a new p-adic element: an Integer, + - ``x`` -- data defining a new `p`-adic element: an Integer, Rational, an element of Zp or Qp with the same prime, a PARI - p-adic element, a list, a tuple, or an IntegerMod. + `p`-adic element, a list, a tuple, or an IntegerMod. - ``prime_pow`` -- the PowComputer for the ring into which ``x`` is being converted. This is used to determine the prime and the ramification degree. @@ -235,10 +235,10 @@ cdef long comb_prec(iprec, long prec) except? -10000: INPUT: - - ``iprec`` -- either infinity, an Integer, a Python int or - something that can be converted to an Integer. + - ``iprec`` -- infinity, integer or something that can be converted to an + integer - - ``prec`` -- a long. + - ``prec`` -- a long """ if iprec is infinity: return prec cdef Integer intprec @@ -258,21 +258,21 @@ cdef int _process_args_and_kwds(long *aprec, long *rprec, args, kwds, bint absol This function obtains values for absprec and relprec from a combination of positional and keyword arguments. - When creating a p-adic element, the user can pass in two arguments: ``absprec`` and ``relprec``. + When creating a `p`-adic element, the user can pass in two arguments: ``absprec`` and ``relprec``. In implementing morphisms to speed up conversion from Integers and Rationals, we need to determine ``absprec`` and ``relprec`` from the ``args`` and ``kwds`` arguments of ``_call_with_args``. This function collects the code to do so. INPUT: - - ``args`` -- a tuple of positional arguments (at most two) + - ``args`` -- tuple of positional arguments (at most two) - - ``kwds`` -- a dictionary of keyword arguments (only + - ``kwds`` -- dictionary of keyword arguments (only ``'relprec'`` and ``'absprec'`` are used) - - ``absolute`` -- (boolean) True if the precision cap of the ring - is a cap on absolute precision, False if a cap on relative - precision. + - ``absolute`` -- boolean; ``True`` if the precision cap of the ring + is a cap on absolute precision, ``False`` if a cap on relative + precision - ``prime_pow`` -- a :class:`sage.rings.padics.pow_computer.PowComputer_class` @@ -281,10 +281,10 @@ cdef int _process_args_and_kwds(long *aprec, long *rprec, args, kwds, bint absol OUTPUT: - ``aprec`` -- (first argument) the maximum absolute precision of - the resulting element. + the resulting element - ``rprec`` -- (second argument) the maximum relative precision of - the resulting element. + the resulting element - error status """ @@ -321,14 +321,14 @@ cdef inline long cconv_mpq_t_shared(mpz_t out, mpq_t x, long prec, bint absolute INPUT: - - ``out`` -- an ``mpz_t`` to store the output. - - ``x`` -- an ``mpq_t`` giving the integer to be converted. - - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. - - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the output + - ``x`` -- an ``mpq_t`` giving the integer to be converted + - ``prec`` -- a long, giving the precision desired; absolute or + relative depending on the ``absolute`` input + - ``absolute`` -- if ``False`` then extracts the valuation and returns + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -362,10 +362,11 @@ cdef inline long cconv_mpq_t_shared(mpz_t out, mpq_t x, long prec, bint absolute cdef inline int cconv_mpq_t_out_shared(mpq_t out, mpz_t x, long valshift, long prec, PowComputer_class prime_pow) except -1: """ - Converts the underlying `p`-adic element into a rational + Convert the underlying `p`-adic element into a rational. - - ``out`` -- gives a rational approximating the input. Currently uses rational reconstruction but - may change in the future to use a more naive method + - ``out`` -- gives a rational approximating the input. Currently uses + rational reconstruction but may change in the future to use a more naive + method - ``x`` -- an ``mpz_t`` giving the underlying `p`-adic element - ``valshift`` -- a long giving the power of `p` to shift `x` by -` ``prec`` -- a long, the precision of ``x``, used in rational reconstruction @@ -392,18 +393,17 @@ cdef inline int cconv_shared(mpz_t out, x, long prec, long valshift, PowComputer INPUT: - - ``out`` -- an ``mpz_t`` to store the output. + - ``out`` -- an ``mpz_t`` to store the output - - ``x`` -- a Sage element that can be converted to a `p`-adic element. + - ``x`` -- a Sage element that can be converted to a `p`-adic element - - ``prec`` -- a long, giving the precision desired: absolute if - `valshift = 0`, relative if `valshift != 0`. + - ``prec`` -- a long, giving the precision desired; absolute if + `valshift = 0`, relative if `valshift != 0` - ``valshift`` -- the power of the uniformizer to divide by before - storing the result in ``out``. - - - ``prime_pow`` -- a PowComputer for the ring. + storing the result in ``out`` + - ``prime_pow`` -- a PowComputer for the ring """ if PyLong_Check(x): x = Integer(x) @@ -456,14 +456,14 @@ cdef inline long cconv_mpz_t_shared(mpz_t out, mpz_t x, long prec, bint absolute INPUT: - - ``out`` -- an ``mpz_t`` to store the output. - - ``x`` -- an ``mpz_t`` giving the integer to be converted. - - ``prec`` -- a long, giving the precision desired: absolute or - relative depending on the ``absolute`` input. - - ``absolute`` -- if False then extracts the valuation and returns - it, storing the unit in ``out``; if True then - just reduces ``x`` modulo the precision. - - ``prime_pow`` -- a PowComputer for the ring. + - ``out`` -- an ``mpz_t`` to store the output + - ``x`` -- an ``mpz_t`` giving the integer to be converted + - ``prec`` -- a long, giving the precision desired; absolute or + relative depending on the ``absolute`` input + - ``absolute`` -- if ``False`` then extracts the valuation and returns + it, storing the unit in ``out``; if ``True`` then just reduces ``x`` + modulo the precision + - ``prime_pow`` -- a PowComputer for the ring OUTPUT: @@ -483,15 +483,14 @@ cdef inline long cconv_mpz_t_shared(mpz_t out, mpz_t x, long prec, bint absolute cdef inline int cconv_mpz_t_out_shared(mpz_t out, mpz_t x, long valshift, long prec, PowComputer_class prime_pow) except -1: """ - Converts the underlying `p`-adic element into an integer if - possible. + Convert the underlying `p`-adic element into an integer if possible. - ``out`` -- stores the resulting integer as an integer between 0 - and `p^{prec + valshift}`. - - ``x`` -- an ``mpz_t`` giving the underlying `p`-adic element. - - ``valshift`` -- a long giving the power of `p` to shift `x` by. - -` ``prec`` -- a long, the precision of ``x``: currently not used. - - ``prime_pow`` -- a PowComputer for the ring. + and `p^{prec + valshift}` + - ``x`` -- an ``mpz_t`` giving the underlying `p`-adic element + - ``valshift`` -- a long giving the power of `p` to shift `x` by + -` ``prec`` -- a long, the precision of ``x``; currently not used + - ``prime_pow`` -- a PowComputer for the ring """ if valshift == 0: mpz_set(out, x) diff --git a/src/sage/rings/padics/eisenstein_extension_generic.py b/src/sage/rings/padics/eisenstein_extension_generic.py index 10e198abfb9..2e584291193 100644 --- a/src/sage/rings/padics/eisenstein_extension_generic.py +++ b/src/sage/rings/padics/eisenstein_extension_generic.py @@ -26,7 +26,7 @@ class EisensteinExtensionGeneric(pAdicExtensionGeneric): def __init__(self, poly, prec, print_mode, names, element_class): """ - Initializes ``self``. + Initialize ``self``. EXAMPLES:: @@ -59,7 +59,7 @@ def _extension_type(self): def absolute_e(self): """ - Return the absolute ramification index of this ring or field + Return the absolute ramification index of this ring or field. EXAMPLES:: @@ -97,11 +97,9 @@ def residue_class_field(self): INPUT: - - ``self`` -- a p-adic ring + - ``self`` -- a `p`-adic ring - OUTPUT: - - the residue field + OUTPUT: the residue field EXAMPLES:: @@ -147,7 +145,7 @@ def residue_ring(self, n): #def galois_group(self): # r""" - # Returns the Galois group of self's fraction field over Qp. + # Returns the Galois group of ``self``'s fraction field over Qp. # """ # ## # ## If K is a number field, then K.galois_group() can return diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index b3d7a232b7e..cee585d48a1 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -99,6 +99,7 @@ ext_table['re', pAdicRingFloatingPoint] = RelativeRamifiedExtensionRingFloatingPoint ext_table['re', pAdicFieldFloatingPoint] = RelativeRamifiedExtensionFieldFloatingPoint + def _canonicalize_show_prec(type, print_mode, show_prec=None): r""" Return a canonical string value for show_prec depending of the type, @@ -106,16 +107,15 @@ def _canonicalize_show_prec(type, print_mode, show_prec=None): INPUT: - - ``type`` -- a string: ``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'`` or ``'floating-point'``, - ``'lattice-cap'`` or ``'lattice-float'`` - - - ``print_mode`` -- a string: ``'series'``, ``'terse'``, ``'val-unit'``, ``'digits'``, ``'bars'`` + - ``type`` -- string; ``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'``, + ``'floating-point'``, ``'lattice-cap'`` or ``'lattice-float'`` - - ``show_prec`` -- a boolean, string or ``None`` + - ``print_mode`` -- string; ``'series'``, ``'terse'``, ``'val-unit'``, + ``'digits'``, ``'bars'`` - OUTPUT: + - ``show_prec`` -- boolean, string, or ``None`` - A string, either ``'bigoh'``, ``'dots'`` or ``'none'`` + OUTPUT: string; either ``'bigoh'``, ``'dots'`` or ``'none'`` EXAMPLES:: @@ -329,15 +329,16 @@ def get_key_base(p, prec, type, print_mode, names, ram_name, print_pos, print_se padic_field_cache = {} DEFAULT_PREC = Integer(20) + class Qp_class(UniqueFactory): r""" A creation function for `p`-adic fields. INPUT: - - ``p`` -- integer: the `p` in `\QQ_p` + - ``p`` -- integer; the `p` in `\QQ_p` - - ``prec`` -- integer (default: ``20``) the precision cap of the field. + - ``prec`` -- integer (default: 20); the precision cap of the field. In the lattice capped case, ``prec`` can either be a pair (``relative_cap``, ``absolute_cap``) or an integer (understood at relative cap). @@ -347,44 +348,43 @@ class Qp_class(UniqueFactory): Except in the floating point case, individual elements keep track of their own precision. See TYPES and PRECISION below. - - ``type`` -- string (default: ``'capped-rel'``) Valid types are - ``'capped-rel'``, ``'floating-point'``, ``'lattice-cap'``, ``'lattice-float'``. - See TYPES and PRECISION below + - ``type`` -- string (default: ``'capped-rel'``); valid types are + ``'capped-rel'``, ``'floating-point'``, ``'lattice-cap'``, + ``'lattice-float'``. See TYPES and PRECISION below. - - ``print_mode`` -- string (default: ``None``). Valid modes are 'series', - 'val-unit', 'terse', 'digits', and 'bars'. See PRINTING below + - ``print_mode`` -- string (default: ``None``); valid modes are + ``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'``, and ``'bars'``. + See PRINTING below. - ``names`` -- string or tuple (defaults to a string representation of - `p`). What to use whenever `p` is printed. + `p`); what to use whenever `p` is printed - - ``ram_name`` -- string. Another way to specify the name; for + - ``ram_name`` -- string; another way to specify the name. For consistency with the ``Qq`` and ``Zq`` and extension functions. - - ``print_pos`` -- bool (default ``None``) Whether to only use positive - integers in the representations of elements. See PRINTING below. + - ``print_pos`` -- boolean (default: ``None``); whether to only use + positive integers in the representations of elements. See PRINTING below. - - ``print_sep`` -- string (default ``None``) The separator character used + - ``print_sep`` -- string (default: ``None``); the separator character used in the ``'bars'`` mode. See PRINTING below. - - ``print_alphabet`` -- tuple (default ``None``) The encoding into digits + - ``print_alphabet`` -- tuple (default: ``None``); the encoding into digits for use in the 'digits' mode. See PRINTING below. - - ``print_max_terms`` -- integer (default ``None``) The maximum number of + - ``print_max_terms`` -- integer (default: ``None``); the maximum number of terms shown. See PRINTING below. - - ``show_prec`` -- a boolean or a string (default ``None``) Specify how + - ``show_prec`` -- boolean or a string (default: ``None``); specify how the precision is printed. See PRINTING below. - - ``check`` -- bool (default ``True``) whether to check if `p` is prime. + - ``check`` -- boolean (default: ``True``); whether to check if `p` is prime. Non-prime input may cause seg-faults (but can also be useful for - base n expansions for example) - - - ``label`` -- string (default ``None``) used for lattice precision to - create parents with different lattices. + base n expansions for example). - OUTPUT: + - ``label`` -- string (default: ``None``); used for lattice precision to + create parents with different lattices - - The corresponding `p`-adic field. + OUTPUT: the corresponding `p`-adic field TYPES AND PRECISION: @@ -606,7 +606,7 @@ class Qp_class(UniqueFactory): sage: d = R(-707/5^2); repr(d) '...444444444444444341.33' - Observe that the significant 0's are printed even if they are + Observe that the significant 0s are printed even if they are located in front of the number. On the contrary, unknown digits located after the comma appears as question marks. The precision can therefore be read in this mode as well. @@ -728,7 +728,7 @@ def create_key(self, p, prec=None, type='capped-rel', print_mode=None, print_sep=None, print_alphabet=None, print_max_terms=None, show_prec=None, check=True, label=None): # specific to Lattice precision r""" - Creates a key from input parameters for ``Qp``. + Create a key from input parameters for ``Qp``. See the documentation for ``Qp`` for more information. @@ -751,7 +751,7 @@ def create_key(self, p, prec=None, type='capped-rel', print_mode=None, def create_object(self, version, key): r""" - Creates an object using a given key. + Create an object using a given key. See the documentation for ``Qp`` for more information. @@ -839,57 +839,54 @@ def Qq(q, prec=None, type='capped-rel', modulus=None, names=None, As a tuple it is the pair ``(p, n)``, and as a list it is a single element list ``[(p, n)]``. - - ``prec`` -- integer (default: ``20``) the precision cap of the field. + - ``prec`` -- integer (default: 20); the precision cap of the field. Individual elements keep track of their own precision. See TYPES and PRECISION below. - - ``type`` -- string (default: ``'capped-rel'``) Valid types are + - ``type`` -- string (default: ``'capped-rel'``); valid types are ``'capped-rel'``, ``'floating-point'``, ``'lattice-cap'`` - and ``'lattice-float'``. See TYPES and PRECISION below + and ``'lattice-float'``. See TYPES and PRECISION below. - - ``modulus`` -- polynomial (default ``None``) A polynomial defining an + - ``modulus`` -- polynomial (default: ``None``); a polynomial defining an unramified extension of `\QQ_p`. See MODULUS below. - - ``names`` -- string or tuple (``None`` is only allowed when `q=p`). The - name of the generator, reducing to a generator of the residue - field. + - ``names`` -- string or tuple (``None`` is only allowed when `q=p`); the + name of the generator, reducing to a generator of the residue field. - - ``print_mode`` -- string (default: ``None``). Valid modes are ``'series'``, + - ``print_mode`` -- string (default: ``None``); valid modes are ``'series'``, ``'val-unit'``, ``'terse'``, and ``'bars'``. See PRINTING below. - ``ram_name`` -- string (defaults to string representation of `p` if - None). ``ram_name`` controls how the prime is printed. See PRINTING + ``None``). ``ram_name`` controls how the prime is printed. See PRINTING below. - ``res_name`` -- string (defaults to ``None``, which corresponds to adding a ``'0'`` to the end of the name). Controls how elements of the residue field print. - - ``print_pos`` -- bool (default ``None``) Whether to only use positive + - ``print_pos`` -- boolean (default: ``None``); whether to only use positive integers in the representations of elements. See PRINTING below. - - ``print_sep`` -- string (default ``None``) The separator character used + - ``print_sep`` -- string (default: ``None``); the separator character used in the ``'bars'`` mode. See PRINTING below. - - ``print_max_ram_terms`` -- integer (default ``None``) The maximum number + - ``print_max_ram_terms`` -- integer (default: ``None``) the maximum number of powers of `p` shown. See PRINTING below. - - ``print_max_unram_terms`` -- integer (default ``None``) The maximum + - ``print_max_unram_terms`` -- integer (default: ``None``); the maximum number of entries shown in a coefficient of `p`. See PRINTING below. - - ``print_max_terse_terms`` -- integer (default ``None``) The maximum + - ``print_max_terse_terms`` -- integer (default: ``None``); the maximum number of terms in the polynomial representation of an element (using ``'terse'``). See PRINTING below. - - ``show_prec`` -- bool (default ``None``) whether to show the precision + - ``show_prec`` -- boolean (default: ``None``); whether to show the precision for elements. See PRINTING below. - - ``check`` -- bool (default ``True``) whether to check inputs. + - ``check`` -- boolean (default: ``True``); whether to check inputs - OUTPUT: - - - The corresponding unramified `p`-adic field. + OUTPUT: the corresponding unramified `p`-adic field TYPES AND PRECISION: @@ -1306,11 +1303,11 @@ def Qq(q, prec=None, type='capped-rel', modulus=None, names=None, Check that :issue:`8162` is resolved:: - sage: R = Qq([(5,3)], names="alpha", check=False); R # needs sage.libs.ntl + sage: R = Qq([(5,3)], names='alpha', check=False); R # needs sage.libs.ntl 5-adic Unramified Extension Field in alpha defined by x^3 + 3*x + 3 - sage: Qq((5, 3), names="alpha") is R # needs sage.libs.ntl + sage: Qq((5, 3), names='alpha') is R # needs sage.libs.ntl True - sage: Qq(125.factor(), names="alpha") is R # needs sage.libs.ntl + sage: Qq(125.factor(), names='alpha') is R # needs sage.libs.ntl True Check that :issue:`18606` is resolved:: @@ -1387,6 +1384,7 @@ def Qq(q, prec=None, type='capped-rel', modulus=None, names=None, # Short constructor names for different types ###################################################### + def QpCR(p, prec=None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic fields. @@ -1401,6 +1399,7 @@ def QpCR(p, prec=None, *args, **kwds): """ return Qp(p, prec, 'capped-rel', *args, **kwds) + def QpFP(p, prec=None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic fields. @@ -1415,6 +1414,7 @@ def QpFP(p, prec=None, *args, **kwds): """ return Qp(p, prec, 'floating-point', *args, **kwds) + def QqCR(q, prec=None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic @@ -1430,6 +1430,7 @@ def QqCR(q, prec=None, *args, **kwds): """ return Qq(q, prec, 'capped-rel', *args, **kwds) + def QqFP(q, prec=None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic @@ -1445,6 +1446,7 @@ def QqFP(q, prec=None, *args, **kwds): """ return Qq(q, prec, 'floating-point', *args, **kwds) + @experimental(23505) def QpLC(p, prec=None, *args, **kwds): r""" @@ -1460,6 +1462,7 @@ def QpLC(p, prec=None, *args, **kwds): """ return Qp(p, prec, 'lattice-cap', *args, **kwds) + @experimental(23505) def QpLF(p, prec=None, *args, **kwds): r""" @@ -1475,6 +1478,7 @@ def QpLF(p, prec=None, *args, **kwds): """ return Qp(p, prec, 'lattice-float', *args, **kwds) + def QpER(p, prec=None, halt=None, secure=False, *args, **kwds): r""" A shortcut function to create relaxed `p`-adic fields. @@ -1497,15 +1501,16 @@ def QpER(p, prec=None, halt=None, secure=False, *args, **kwds): # ####################################################################################################### + class Zp_class(UniqueFactory): r""" A creation function for `p`-adic rings. INPUT: - - ``p`` -- integer: the `p` in `\ZZ_p` + - ``p`` -- integer; the `p` in `\ZZ_p` - - ``prec`` -- integer (default: ``20``) the precision cap of the + - ``prec`` -- integer (default: 20); the precision cap of the ring. In the lattice capped case, ``prec`` can either be a pair (``relative_cap``, ``absolute_cap``) or an integer (understood as relative cap). @@ -1516,44 +1521,42 @@ class Zp_class(UniqueFactory): keep track of their own precision. See TYPES and PRECISION below. - - ``type`` -- string (default: ``'capped-rel'``) Valid types are - ``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'``, - ``'floating-point'``, ``'lattice-cap'``, ``'lattice-float'``, ``'relaxed'``. + - ``type`` -- string (default: ``'capped-rel'``); valid types are + ``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'``, ``'floating-point'``, + ``'lattice-cap'``, ``'lattice-float'``, ``'relaxed'``. See TYPES and PRECISION below. - - ``print_mode`` -- string (default: ``None``). Valid modes are + - ``print_mode`` -- string (default: ``None``); valid modes are ``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'``, and ``'bars'``. See PRINTING below. - ``names`` -- string or tuple (defaults to a string - representation of `p`). What to use whenever `p` is printed. + representation of `p`); what to use whenever `p` is printed - - ``print_pos`` -- bool (default ``None``) Whether to only use + - ``print_pos`` -- boolean (default: ``None``); whether to only use positive integers in the representations of elements. See PRINTING below. - - ``print_sep`` -- string (default ``None``) The separator + - ``print_sep`` -- string (default: ``None``); the separator character used in the ``'bars'`` mode. See PRINTING below. - - ``print_alphabet`` -- tuple (default ``None``) The encoding into + - ``print_alphabet`` -- tuple (default: ``None``); the encoding into digits for use in the ``'digits'`` mode. See PRINTING below. - - ``print_max_terms`` -- integer (default ``None``) The maximum + - ``print_max_terms`` -- integer (default: ``None``); the maximum number of terms shown. See PRINTING below. - - ``show_prec`` -- bool (default ``None``) whether to show the precision + - ``show_prec`` -- boolean (default: ``None``) whether to show the precision for elements. See PRINTING below. - - ``check`` -- bool (default ``True``) whether to check if `p` is + - ``check`` -- boolean (default: ``True``) whether to check if `p` is prime. Non-prime input may cause seg-faults (but can also be useful for base `n` expansions for example) - - ``label`` -- string (default ``None``) used for lattice precision to - create parents with different lattices. - - OUTPUT: + - ``label`` -- string (default: ``None``); used for lattice precision to + create parents with different lattices - - The corresponding `p`-adic ring. + OUTPUT: the corresponding `p`-adic ring TYPES AND PRECISION: @@ -1941,7 +1944,7 @@ def create_key(self, p, prec=None, type='capped-rel', print_mode=None, print_max_terms=None, show_prec=None, check=True, label=None): r""" - Creates a key from input parameters for ``Zp``. + Create a key from input parameters for ``Zp``. See the documentation for :func:`Zp` for more information. @@ -1979,7 +1982,7 @@ def create_key(self, p, prec=None, type='capped-rel', print_mode=None, def create_object(self, version, key): r""" - Creates an object using a given key. + Create an object using a given key. See the documentation for :func:`Zp` for more information. @@ -2055,61 +2058,59 @@ def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, :class:`Factorization` object, single element list ``[(p, n)]`` where ``p`` is a prime and ``n`` a positive integer, or the pair ``(p, n)``. - - ``prec`` -- integer (default: ``20``) the precision cap of the + - ``prec`` -- integer (default: 20); the precision cap of the field. Individual elements keep track of their own precision. See TYPES and PRECISION below. - - ``type`` -- string (default: ``'capped-rel'``) Valid types are + - ``type`` -- string (default: ``'capped-rel'``); valid types are ``'capped-abs'``, ``'capped-rel'``, ``'fixed-mod'``, and ``'floating-point'``. See TYPES and PRECISION below. - - ``modulus`` -- polynomial (default None) A polynomial defining an + - ``modulus`` -- polynomial (default: ``None``); a polynomial defining an unramified extension of `\ZZ_p`. See MODULUS below. - ``names`` -- string or tuple (``None`` is only allowed when - `q=p`). The name of the generator, reducing to a generator of - the residue field. + `q=p`); the name of the generator, reducing to a generator of + the residue field - - ``print_mode`` -- string (default: ``None``). Valid modes are ``'series'``, + - ``print_mode`` -- string (default: ``None``); valid modes are ``'series'``, ``'val-unit'``, ``'terse'``, and ``'bars'``. See PRINTING below. - ``ram_name`` -- string (defaults to string representation of `p` if - ``None``). ``ram_name`` controls how the prime is printed. See PRINTING + ``None``); ``ram_name`` controls how the prime is printed. See PRINTING below. - ``res_name`` -- string (defaults to ``None``, which corresponds - to adding a ``'0'`` to the end of the name). Controls how + to adding a ``'0'`` to the end of the name); controls how elements of the residue field print. - - ``print_pos`` -- bool (default ``None``) Whether to only use + - ``print_pos`` -- boolean (default: ``None``); whether to only use positive integers in the representations of elements. See PRINTING below. - - ``print_sep`` -- string (default ``None``) The separator + - ``print_sep`` -- string (default: ``None``); the separator character used in the ``'bars'`` mode. See PRINTING below. - - ``print_max_ram_terms`` -- integer (default ``None``) The maximum + - ``print_max_ram_terms`` -- integer (default: ``None``); the maximum number of powers of `p` shown. See PRINTING below. - - ``print_max_unram_terms`` -- integer (default ``None``) The + - ``print_max_unram_terms`` -- integer (default: ``None``) the maximum number of entries shown in a coefficient of `p`. See PRINTING below. - - ``print_max_terse_terms`` -- integer (default ``None``) The maximum + - ``print_max_terse_terms`` -- integer (default: ``None``); the maximum number of terms in the polynomial representation of an element (using ``'terse'``). See PRINTING below. - - ``show_prec`` -- bool (default ``None``) Whether to show the precision - for elements. See PRINTING below. + - ``show_prec`` -- boolean (default: ``None``); whether to show the + precision for elements. See PRINTING below. - - ``check`` -- bool (default ``True``) whether to check inputs. + - ``check`` -- boolean (default: ``True``) whether to check inputs - - ``implementation`` -- string (default ``'FLINT'``) which + - ``implementation`` -- string (default: ``'FLINT'``); which implementation to use. ``'NTL'`` is the other option. - OUTPUT: - - The corresponding unramified `p`-adic ring. + OUTPUT: the corresponding unramified `p`-adic ring TYPES AND PRECISION: @@ -2561,13 +2562,12 @@ def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, TESTS:: sage: # needs sage.libs.ntl - sage: R = Zq([(5,3)], names="alpha"); R + sage: R = Zq([(5,3)], names='alpha'); R 5-adic Unramified Extension Ring in alpha defined by x^3 + 3*x + 3 - sage: Zq((5, 3), names="alpha") is R + sage: Zq((5, 3), names='alpha') is R True - sage: Zq(125.factor(), names="alpha") is R + sage: Zq(125.factor(), names='alpha') is R True - """ if check: if isinstance(q, Factorization) or isinstance(q, (list, tuple)): @@ -2629,6 +2629,7 @@ def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, # Short constructor names for different types ###################################################### + def ZpCR(p, prec=None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic rings. @@ -2643,6 +2644,7 @@ def ZpCR(p, prec=None, *args, **kwds): """ return Zp(p, prec, 'capped-rel', *args, **kwds) + def ZpCA(p, prec=None, *args, **kwds): r""" A shortcut function to create capped absolute `p`-adic rings. @@ -2656,6 +2658,7 @@ def ZpCA(p, prec=None, *args, **kwds): """ return Zp(p, prec, 'capped-abs', *args, **kwds) + def ZpFM(p, prec=None, *args, **kwds): r""" A shortcut function to create fixed modulus `p`-adic rings. @@ -2669,6 +2672,7 @@ def ZpFM(p, prec=None, *args, **kwds): """ return Zp(p, prec, 'fixed-mod', *args, **kwds) + def ZpFP(p, prec=None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic rings. @@ -2683,6 +2687,7 @@ def ZpFP(p, prec=None, *args, **kwds): """ return Zp(p, prec, 'floating-point', *args, **kwds) + def ZqCR(q, prec=None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic rings. @@ -2697,6 +2702,7 @@ def ZqCR(q, prec=None, *args, **kwds): """ return Zq(q, prec, 'capped-rel', *args, **kwds) + def ZqCA(q, prec=None, *args, **kwds): r""" A shortcut function to create capped absolute unramified `p`-adic rings. @@ -2710,6 +2716,7 @@ def ZqCA(q, prec=None, *args, **kwds): """ return Zq(q, prec, 'capped-abs', *args, **kwds) + def ZqFM(q, prec=None, *args, **kwds): r""" A shortcut function to create fixed modulus unramified `p`-adic rings. @@ -2723,6 +2730,7 @@ def ZqFM(q, prec=None, *args, **kwds): """ return Zq(q, prec, 'fixed-mod', *args, **kwds) + def ZqFP(q, prec=None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic rings. @@ -2737,6 +2745,7 @@ def ZqFP(q, prec=None, *args, **kwds): """ return Zq(q, prec, 'floating-point', *args, **kwds) + @experimental(23505) def ZpLC(p, prec=None, *args, **kwds): r""" @@ -2998,6 +3007,7 @@ def ZpLC(p, prec=None, *args, **kwds): """ return Zp(p, prec, 'lattice-cap', *args, **kwds) + @experimental(23505) def ZpLF(p, prec=None, *args, **kwds): r""" @@ -3025,21 +3035,20 @@ def ZpLF(p, prec=None, *args, **kwds): """ return Zp(p, prec, 'lattice-float', *args, **kwds) + def ZpER(p, prec=None, halt=None, secure=False, *args, **kwds): r""" A shortcut function to create relaxed `p`-adic rings. INPUT: - - ``prec`` -- an integer (default: ``20``), the default - precision + - ``prec`` -- integer (default: 20); the default precision - - ``halt`` -- an integer (default: twice ``prec``), the - halting precision + - ``halt`` -- integer (default: twice ``prec``); the halting precision - - ``secure`` -- a boolean (default: ``False``); if ``False``, + - ``secure`` -- boolean (default: ``False``); if ``False``, consider indistinguishable elements at the working precision - as equal; otherwise, raise an error. + as equal. Otherwise, raise an error. See documentation for :func:`Zp` for a description of the other input parameters. @@ -3053,7 +3062,7 @@ def ZpER(p, prec=None, halt=None, secure=False, *args, **kwds): Relaxed `p`-adic rings are created by the constructor :func:`ZpER`:: - sage: R = ZpER(5, print_mode="digits"); R # needs sage.libs.flint + sage: R = ZpER(5, print_mode='digits'); R # needs sage.libs.flint 5-adic Ring handled with relaxed arithmetics The precision is not capped in `R`:: @@ -3271,7 +3280,7 @@ def create_key_and_extra_args(self, base, modulus, prec=None, print_mode=None, print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, unram=False, implementation='FLINT'): r""" - Creates a key from input parameters for :class:`pAdicExtension`. + Create a key from input parameters for :class:`pAdicExtension`. See the documentation for :func:`Qq` for more information. @@ -3418,7 +3427,7 @@ def create_key_and_extra_args(self, base, modulus, prec=None, print_mode=None, def create_object(self, version, key, approx_modulus=None, shift_seed=None): r""" - Creates an object using a given key. + Create an object using a given key. See the documentation for :class:`pAdicExtension` for more information. @@ -3503,10 +3512,10 @@ def split(poly, prec): Traceback (most recent call last): ... NotImplementedError: Extensions by general polynomials not yet supported. Please use an unramified or Eisenstein polynomial. - """ raise NotImplementedError("Extensions by general polynomials not yet supported. Please use an unramified or Eisenstein polynomial.") + def truncate_to_prec(poly, R, absprec): r""" Truncates the unused precision off of a polynomial. @@ -3522,6 +3531,7 @@ def truncate_to_prec(poly, R, absprec): """ return R[poly.variable_name()]([R(a, absprec=absprec) for a in poly.list()]) # Is this quite right? We don't want flat necessarily... + def krasner_check(poly, prec): r""" Return ``True`` iff ``poly`` determines a unique isomorphism class of @@ -3539,6 +3549,7 @@ def krasner_check(poly, prec): """ return True #This needs to be implemented + def is_eisenstein(poly): r""" Return ``True`` iff this monic polynomial is Eisenstein. @@ -3568,6 +3579,7 @@ def is_eisenstein(poly): return False return True + def is_unramified(poly): r""" Return ``True`` iff this monic polynomial is unramified. diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index cb045b427fc..27ca55b274f 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -70,6 +70,7 @@ def _prec_type(self): """ return 'capped-abs' + class CappedRelativeGeneric(LocalGeneric): def is_capped_relative(self): """ @@ -107,6 +108,7 @@ def _prec_type(self): """ return 'capped-rel' + class FixedModGeneric(LocalGeneric): def is_fixed_mod(self): """ @@ -145,6 +147,7 @@ def _prec_type(self): """ return 'fixed-mod' + class FloatingPointGeneric(LocalGeneric): def is_floating_point(self): """ @@ -186,7 +189,7 @@ def _test_distributivity(self, **options): Test the distributivity of `*` on `+` on (not necessarily all) elements of this set. - p-adic floating point rings only satisfy distributivity + `p`-adic floating point rings only satisfy distributivity up to a precision that depends on the elements. INPUT: @@ -257,15 +260,23 @@ def _test_additive_associativity(self, **options): for x,y,z in some_tuples(S, 3, tester._max_runs): tester.assertTrue(((x + y) + z).is_equal_to(x + (y + z), min(x.precision_absolute(), y.precision_absolute(), z.precision_absolute()))) + class FloatingPointRingGeneric(FloatingPointGeneric): pass + + class FloatingPointFieldGeneric(FloatingPointGeneric):#, sage.rings.ring.Field): pass + + class CappedRelativeRingGeneric(CappedRelativeGeneric): pass + + class CappedRelativeFieldGeneric(CappedRelativeGeneric):#, sage.rings.ring.Field): pass + class pAdicLatticeGeneric(pAdicGeneric): r""" An implementation of the `p`-adic rationals with lattice precision. @@ -276,10 +287,10 @@ class pAdicLatticeGeneric(pAdicGeneric): - ``prec`` -- the precision - - ``subtype`` -- either ``"cap"`` or ``"float"``, + - ``subtype`` -- either ``'cap'`` or ``'float'``, specifying the precision model used for tracking precision - - ``label`` -- a string or ``None`` (default: ``None``) + - ``label`` -- string or ``None`` (default: ``None``) TESTS:: @@ -546,9 +557,9 @@ def _element_constructor_(self, x, prec=None): INPUT: - - ``x``: the datum from which the element is created + - ``x`` -- the datum from which the element is created - - ``prec`` -- an integer or ``None`` (the default); the + - ``prec`` -- integer or ``None`` (the default); the absolute precision of the created element NOTE: @@ -721,7 +732,7 @@ def _get_element_class(self, name=None): INPUT: - - ``name`` -- a string or ``None`` (default: ``None``); if ``None``, + - ``name`` -- string or ``None`` (default: ``None``); if ``None``, return the generic class from which all the others derive TESTS:: @@ -813,12 +824,12 @@ def default_prec(self): EXAMPLES:: sage: # needs sage.libs.flint - sage: R = ZpER(5, print_mode="digits") + sage: R = ZpER(5, print_mode='digits') sage: R.default_prec() 20 sage: R(1/17) ...34024323104201213403 - sage: S = ZpER(5, prec=10, print_mode="digits") + sage: S = ZpER(5, prec=10, print_mode='digits') sage: S.default_prec() 10 sage: S(1/17) @@ -837,7 +848,7 @@ def halting_prec(self): EXAMPLES:: - sage: R = ZpER(5, print_mode="digits") # needs sage.libs.flint + sage: R = ZpER(5, print_mode='digits') # needs sage.libs.flint sage: R.halting_prec() # needs sage.libs.flint 40 """ @@ -881,7 +892,7 @@ def _element_constructor_(self, x, prec=None): - ``x`` -- the datum from which the element is created - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); if given, bound the precision of the element to ``prec`` EXAMPLES:: @@ -1012,10 +1023,10 @@ def unknown(self, start_val=0, digits=None): INPUT: - - ``start_val`` -- an integer (default: 0); a lower bound on the + - ``start_val`` -- integer (default: 0); a lower bound on the valuation of the returned element - - ``digits`` -- an element, a list or ``None`` (default: ``None``); + - ``digits`` -- an element, a list, or ``None`` (default: ``None``); the first digit or the list of the digits of the returned element NOTE: @@ -1111,10 +1122,10 @@ def random_element(self, integral=False, prec=None): INPUT: - - ``integral`` -- a boolean (default: ``False``); if ``True``, + - ``integral`` -- boolean (default: ``False``); if ``True``, return a random element in the ring of integers of this ring - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); if given, bound the precision of the output to ``prec`` EXAMPLES:: @@ -1149,7 +1160,7 @@ def teichmuller(self, x): EXAMPLES:: - sage: R = ZpER(5, print_mode="digits") # needs sage.libs.flint + sage: R = ZpER(5, print_mode='digits') # needs sage.libs.flint sage: R.teichmuller(2) # needs sage.libs.flint ...40423140223032431212 """ @@ -1165,7 +1176,7 @@ def teichmuller_system(self): EXAMPLES:: - sage: R = ZpER(7, print_mode="digits") # needs sage.libs.flint + sage: R = ZpER(7, print_mode='digits') # needs sage.libs.flint sage: R.teichmuller_system() # needs sage.libs.flint [...00000000000000000001, ...16412125443426203642, @@ -1192,16 +1203,14 @@ def is_field(self, proof=True): def krull_dimension(self): r""" - Return the Krull dimension of self, i.e. 1 + Return the Krull dimension of self, i.e. 1. INPUT: - - self -- a `p`-adic ring + - ``self`` -- a `p`-adic ring - OUTPUT: - - - the Krull dimension of self. Since self is a `p`-adic ring, - this is 1. + OUTPUT: the Krull dimension of ``self``. Since ``self`` is a `p`-adic + ring, this is 1. EXAMPLES:: @@ -1218,12 +1227,12 @@ def _xgcd_univariate_polynomial(self, f, g): INPUT: - - ``f``, ``g`` -- the polynomials of which to take the xgcd + - ``f``, ``g`` -- the polynomials of which to take the xgcd OUTPUT: - - A tuple (a, b, c) which satisfies ``a = b*f + c*g``. There - is no guarantee that a, b, and c are minimal. + A tuple (a, b, c) which satisfies a = b*f + c*g. There + is no guarantee that a, b, and c are minimal. .. WARNING:: @@ -1291,9 +1300,9 @@ def _gcd_univariate_polynomial(self, f, g): INPUT: - - ``f``, ``g`` -- the polynomials of which to take the gcd + - ``f``, ``g`` -- the polynomials of which to take the gcd - OUTPUT: A polynomial + OUTPUT: a polynomial EXAMPLES:: @@ -1341,19 +1350,31 @@ class pAdicFieldGeneric(pAdicGeneric, sage.rings.abc.pAdicField): #def subfields_of_degree(self, n): # raise NotImplementedError + class pAdicFixedModRingGeneric(pAdicRingGeneric, FixedModGeneric): pass + + class pAdicCappedAbsoluteRingGeneric(pAdicRingGeneric, CappedAbsoluteGeneric): pass + + class pAdicCappedRelativeRingGeneric(pAdicRingGeneric, CappedRelativeRingGeneric): pass + + class pAdicCappedRelativeFieldGeneric(pAdicFieldGeneric, CappedRelativeFieldGeneric): pass + + class pAdicFloatingPointRingGeneric(pAdicRingGeneric, FloatingPointRingGeneric): pass + + class pAdicFloatingPointFieldGeneric(pAdicFieldGeneric, FloatingPointFieldGeneric): pass + class pAdicRingBaseGeneric(pAdicBaseGeneric, pAdicRingGeneric): def construction(self, forbid_frac_field=False): """ @@ -1365,7 +1386,7 @@ def construction(self, forbid_frac_field=False): INPUT: - - ``forbid_frac_field`` -- ignored, for compatibility with other p-adic types. + - ``forbid_frac_field`` -- ignored, for compatibility with other `p`-adic types EXAMPLES:: @@ -1445,6 +1466,7 @@ def random_element(self, algorithm='default'): #def principal_unit_group(self): # raise NotImplementedError + class pAdicFieldBaseGeneric(pAdicBaseGeneric, pAdicFieldGeneric): def composite(self, subfield1, subfield2): r""" @@ -1457,9 +1479,7 @@ def composite(self, subfield1, subfield2): - ``subfield1`` -- a subfield - ``subfield2`` -- a subfield - OUTPUT: - - the composite of ``subfield1`` and ``subfield2`` + OUTPUT: the composite of ``subfield1`` and ``subfield2`` EXAMPLES:: @@ -1473,12 +1493,12 @@ def composite(self, subfield1, subfield2): def subfields_of_degree(self, n): r""" - Return the number of subfields of ``self`` of degree `n` + Return the number of subfields of ``self`` of degree `n`. INPUT: - ``self`` -- a `p`-adic field - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: @@ -1497,16 +1517,14 @@ def subfields_of_degree(self, n): def subfield(self, list): r""" - Return the subfield generated by the elements in ``list`` + Return the subfield generated by the elements in ``list``. INPUT: - ``self`` -- a `p`-adic field - - ``list`` -- a list of elements of ``self`` - - OUTPUT: + - ``list`` -- list of elements of ``self`` - the subfield of ``self`` generated by the elements of ``list`` + OUTPUT: the subfield of ``self`` generated by the elements of ``list`` EXAMPLES:: diff --git a/src/sage/rings/padics/lattice_precision.py b/src/sage/rings/padics/lattice_precision.py index fda871c3052..f5a5ce09a76 100644 --- a/src/sage/rings/padics/lattice_precision.py +++ b/src/sage/rings/padics/lattice_precision.py @@ -56,6 +56,7 @@ # The number of additional digits used for internal computations STARTING_ADDITIONAL_PREC = 5 + class pRational: r""" This class implements rational numbers viewed as elements of ``Qp``. @@ -70,9 +71,9 @@ class pRational: - ``x`` -- a rational number - - ``exponent`` -- an integer (default: 0) + - ``exponent`` -- integer (default: 0) - - ``valuation`` -- an integer or ``None`` (default: ``None``), + - ``valuation`` -- integer or ``None`` (default: ``None``); the `p`-adic valuation of this element If not ``None``, this method trusts the given value to the @@ -108,7 +109,7 @@ class pRational: """ def __init__(self, p, x, exponent=0, valuation=None): r""" - Construct the element ``x * p^exponent`` + Construct the element ``x * p^exponent``. TESTS:: @@ -147,7 +148,7 @@ def reduce(self, prec): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer TESTS:: @@ -197,7 +198,7 @@ def reduce_relative(self, prec): INPUT: - - ``prec`` -- a nonnegative integer + - ``prec`` -- nonnegative integer TESTS:: @@ -402,7 +403,7 @@ def _quo_rem(self, other): """ Quotient with remainder. - Returns a pair `q`, `r` where `r` has the p-adic expansion of this element, + Returns a pair `q`, `r` where `r` has the `p`-adic expansion of this element, truncated at the valuation of other. EXAMPLES:: @@ -446,7 +447,7 @@ def __lshift__(self, n): INPUT: - - ``n`` -- a relative integer + - ``n`` -- relative integer TESTS:: @@ -468,7 +469,7 @@ def __rshift__(self, n): INPUT: - - ``n`` -- a relative integer + - ``n`` -- relative integer TESTS:: @@ -610,7 +611,7 @@ class DifferentialPrecisionGeneric(SageObject): - ``p`` -- a prime number - - ``label`` -- a string, the label of the parents to which the elements + - ``label`` -- string; the label of the parents to which the elements belong that are tracked by this precision module .. NOTE:: @@ -632,7 +633,6 @@ def __init__(self, p, label): sage: from sage.rings.padics.lattice_precision import DifferentialPrecisionGeneric sage: isinstance(prec, DifferentialPrecisionGeneric) True - """ self._p = p self._label = label @@ -672,7 +672,7 @@ def _repr_(self): If a label has been specified, it is included in the representation:: - sage: R = ZpLC(2, label="mylabel") + sage: R = ZpLC(2, label='mylabel') sage: R.precision() Precision lattice on 0 objects (label: mylabel) """ @@ -699,8 +699,8 @@ def threshold_deletion(self, threshold=None): INPUT: - - ``threshold`` -- a non-negative integer, ``Infinity`` or ``None`` - (default: ``None``): if not ``None`` set the threshold to the given + - ``threshold`` -- nonnegative integer, ``Infinity`` or ``None`` + (default: ``None``); if not ``None`` set the threshold to the given value. .. NOTE:: @@ -740,7 +740,7 @@ def prime(self): EXAMPLES:: - sage: R = ZpLC(2, label="mylabel") + sage: R = ZpLC(2, label='mylabel') sage: R.precision().prime() 2 """ @@ -756,7 +756,7 @@ def _index(self, ref): TESTS:: sage: from sage.rings.padics.lattice_precision import pAdicLatticeElementWeakProxy - sage: R = ZpLC(2, label="index") + sage: R = ZpLC(2, label='index') sage: prec = R.precision() sage: x = R(1, 10) sage: y = R(1, 5) @@ -884,10 +884,10 @@ def del_elements(self, threshold=None): INPUT: - - ``threshold`` -- an integer or ``None`` (default: ``None``): + - ``threshold`` -- integer or ``None`` (default: ``None``); a column whose distance to the right is greater than the - threshold is not erased but marked for deletion; - if ``None``, always erase (never mark for deletion). + threshold is not erased but marked for deletion. + If ``None``, always erase (never mark for deletion). EXAMPLES:: @@ -954,7 +954,7 @@ def precision_lattice(self, elements=None): INPUT: - - ``elements`` -- a list of elements or ``None`` (default: ``None``) + - ``elements`` -- list of elements or ``None`` (default: ``None``) EXAMPLES:: @@ -1058,11 +1058,11 @@ def tracked_elements(self, values=True, dead=True): INPUT: - - ``values`` -- a boolean (default: ``True``); if false, + - ``values`` -- boolean (default: ``True``); if ``False``, the method returns a list of weak references on tracked elements instead - - ``dead`` -- a boolean (default: ``True``); whether dead + - ``dead`` -- boolean (default: ``True``); whether dead elements for which the corresponding column is still not erased should be listed or not @@ -1258,17 +1258,17 @@ def history(self, compact=True, separate_reduce=False, timings=True, output_type INPUT: - - ``compact`` -- a boolean (default: ``True``); if true, all + - ``compact`` -- boolean (default: ``True``); if ``True``, all consecutive operations of the same type appear on a single row - - ``separate_reduce`` -- a boolean (default: ``False``); specify + - ``separate_reduce`` -- boolean (default: ``False``); specify whether partial/full Hermite reduction should be displayed separately - - ``timings`` -- a boolean (default: ``True``); specify whether + - ``timings`` -- boolean (default: ``True``); specify whether timings should be displayed - - ``output_type`` -- only ``asciiart`` is implemented for now. + - ``output_type`` -- only ``asciiart`` is implemented for now IMPORTANT NOTE: @@ -1483,7 +1483,7 @@ def timings(self, action=None): INPUT: - - ``action`` -- ``None`` (the default), ``'add'``, ``'mark'``, ``'del'``, + - ``action`` -- ``None`` (default), ``'add'``, ``'mark'``, ``'del'``, ``'partial reduce'`` or ``'full reduce'``; if not ``None``, return the cumulated timing corresponding to this action; otherwise, return a dictionary @@ -1543,8 +1543,8 @@ class PrecisionLattice(UniqueRepresentation, DifferentialPrecisionGeneric): - ``p`` -- a prime number - - ``label`` -- a string, the label of the parents to which the elements - tracked by this lattice belong. + - ``label`` -- string; the label of the parents to which the elements + tracked by this lattice belong .. NOTE:: @@ -1565,7 +1565,6 @@ def __init__(self, p, label): sage: R = ZpLC(2) sage: isinstance(R.precision(), PrecisionLattice) True - """ DifferentialPrecisionGeneric.__init__(self, p, label) self._repr_type = "Precision lattice" @@ -1593,7 +1592,7 @@ def _index(self, ref): TESTS:: sage: from sage.rings.padics.lattice_precision import pAdicLatticeElementWeakProxy - sage: R = ZpLC(2, label="index") + sage: R = ZpLC(2, label='index') sage: prec = R.precision() sage: x = R(1, 10) sage: y = R(1, 5) @@ -1633,10 +1632,10 @@ def reduce(self, index=0, partial=False): INPUT: - - ``index`` -- an integer, the starting row for which the reduction + - ``index`` -- integer; the starting row for which the reduction is performed - - ``partial`` -- a boolean (default: ``False``) specifying whether a + - ``partial`` -- boolean (default: ``False``); specifying whether a partial or a full Hermite reduction should be performed NOTE: @@ -1675,8 +1674,7 @@ def reduce(self, index=0, partial=False): col[i] = col[i].reduce(prec) col[i].normalize() dval = col[i].valuation() - prec - if dval < diffval[i-index]: - diffval[i-index] = dval + diffval[i-index] = min(dval, diffval[i-index]) # We update history if self._history is not None: self._history.append(('partial reduce', index, walltime(tme))) @@ -1715,16 +1713,16 @@ def _new_element(self, x, dx, bigoh, dx_mode='linear_combination', capped=False) - ``x`` -- the newly created element - - ``dx`` -- a dictionary representing the differential of ``x`` + - ``dx`` -- dictionary representing the differential of ``x`` - - ``bigoh`` -- an integer or ``None`` (default: ``None``): the + - ``bigoh`` -- integer or ``None`` (default: ``None``); the bigoh to be added to the precision of ``x``; if ``None``, the default cap is used. - - ``dx_mode`` -- a string, either ``linear_combination`` (the default) + - ``dx_mode`` -- string; either ``linear_combination`` (the default) or ``values`` - - ``capped`` -- a boolean, whether this element has been capped + - ``capped`` -- boolean; whether this element has been capped according to the parent's cap If ``dx_mode`` is ``linear_combination``, the dictionary ``dx`` @@ -1796,7 +1794,7 @@ def del_elements(self, threshold=None): INPUT: - - ``threshold`` -- an integer or ``None`` (default: ``None``): + - ``threshold`` -- integer or ``None`` (default: ``None``); a column whose distance to the right is greater than the threshold is not erased @@ -2064,9 +2062,9 @@ def precision_lattice(self, elements=None): INPUT: - - ``elements`` -- a list of elements or ``None`` (default: ``None``) + - ``elements`` -- list of elements or ``None`` (default: ``None``) - - ``echelon`` -- a boolean (default: ``True``); whether the result + - ``echelon`` -- boolean (default: ``True``); whether the result should be in echelon form EXAMPLES:: @@ -2125,8 +2123,7 @@ def precision_lattice(self, elements=None): col = self._matrix[ref] row = [ x.value() for x in col ] valcol = min([ x.valuation() for x in col ]) - if valcol < val: - val = valcol + val = min(valcol, val) row += (n-len(row)) * [ZZ(0)] rows.append(row) from sage.matrix.constructor import matrix @@ -2158,7 +2155,7 @@ def __init__(self, p, label, prec): - ``p`` -- a prime number - - ``label`` -- a string, the label of the parents to which belong + - ``label`` -- string; the label of the parents to which belong the elements tracked by this precision module NOTE: @@ -2301,16 +2298,16 @@ def _new_element(self, x, dx, bigoh, dx_mode='linear_combination'): - ``x`` -- the newly created element - - ``dx`` -- a dictionary representing the differential of ``x`` + - ``dx`` -- dictionary representing the differential of ``x`` - - ``bigoh`` -- an integer or ``None`` (default: ``None``): the - bigoh to be added to the precision of ``x``; if ``None``, the + - ``bigoh`` -- integer or ``None`` (default: ``None``); the + bigoh to be added to the precision of ``x``. If ``None``, the default cap is used. - - ``dx_mode`` -- a string, either ``"linear_combination"`` (the - default) or ``"values"`` + - ``dx_mode`` -- string; either ``'linear_combination'`` (the + default) or ``'values'`` - If ``dx_mode`` is ``"linear_combination"``, the dictionary ``dx`` + If ``dx_mode`` is ``'linear_combination'``, the dictionary ``dx`` encodes the expression of the differential of ``x``. For example, if ``x`` was defined as ``x = y*z`` then: @@ -2322,7 +2319,7 @@ def _new_element(self, x, dx, bigoh, dx_mode='linear_combination'): that the keys are not the elements themselves but weak references to them). - If ``dx_mode`` is ``"values"``, the dictionary ``dx`` directly + If ``dx_mode`` is ``'values'``, the dictionary ``dx`` directly specifies the entries that have to stored in the precision module. This mode is only used for multiple conversion between different parents (see :meth:`multiple_conversion`). @@ -2396,7 +2393,7 @@ def del_elements(self, threshold=None): INPUT: - - ``threshold`` -- an integer or ``None`` (default: ``None``): + - ``threshold`` -- integer or ``None`` (default: ``None``); a non-pivot column whose distance to the right is greater than the threshold is not erased but only marked for future deletion @@ -2669,7 +2666,7 @@ def precision_lattice(self, elements=None): INPUT: - - ``elements`` -- a list of elements or ``None`` (default: ``None``) + - ``elements`` -- list of elements or ``None`` (default: ``None``) EXAMPLES:: @@ -2720,8 +2717,7 @@ def precision_lattice(self, elements=None): col = self._matrix[ref] row = [ x.value() for x in col ] valcol = min([ x.valuation() for x in col ]) - if valcol < val: - val = valcol + val = min(valcol, val) row += (n-len(row)) * [ZZ(0)] rows.append(row) from sage.matrix.constructor import matrix @@ -2742,7 +2738,8 @@ def precision_lattice(self, elements=None): M *= self._p ** val return M -class pAdicLatticeElementWeakProxy(): + +class pAdicLatticeElementWeakProxy: r""" The implementations of :class:`DifferentialPrecisionGeneric` hold weak references to :class:`pAdicLatticeElement`. They are stored in @@ -2782,7 +2779,6 @@ def __init__(self, element, callback=None): True sage: pAdicLatticeElementWeakProxy(p) is pAdicLatticeElementWeakProxy(p) False - """ if not hasattr(element, '_proxy_id'): element._proxy_id = pAdicLatticeElementWeakProxy._next_id @@ -2805,7 +2801,6 @@ def __hash__(self): sage: p = R(2) sage: hash(pAdicLatticeElementWeakProxy(p)) == hash(pAdicLatticeElementWeakProxy(p)) True - """ return self._id @@ -2823,7 +2818,6 @@ def __eq__(self, other): True sage: pAdicLatticeElementWeakProxy(q) == pAdicLatticeElementWeakProxy(p) False - """ return isinstance(other, pAdicLatticeElementWeakProxy) and self._id == other._id @@ -2839,7 +2833,6 @@ def __call__(self): sage: p = R(2) sage: pAdicLatticeElementWeakProxy(p)() 2 + O(2^21) - """ return self._weakref() @@ -2854,10 +2847,10 @@ def __repr__(self): sage: p = R(2) sage: R.precision()._elements # indirect doctest [WeakProxy#...] - """ return "WeakProxy#%s" % (self._id,) + def list_of_padics(elements): r""" Convert a list of `p`-adic composed elements (such as polynomials, matrices) diff --git a/src/sage/rings/padics/local_generic.py b/src/sage/rings/padics/local_generic.py index 349a8ec17dc..58d83e40724 100644 --- a/src/sage/rings/padics/local_generic.py +++ b/src/sage/rings/padics/local_generic.py @@ -41,7 +41,7 @@ def __init__(self, base, prec, names, element_class, category=None): sage: R.precision_cap() 20 - In :issue:`14084`, the category framework has been implemented for p-adic rings:: + In :issue:`14084`, the category framework has been implemented for `p`-adic rings:: sage: TestSuite(R).run() # needs sage.geometry.polyhedron sage: K = Qp(7) @@ -244,14 +244,14 @@ def change(self, **kwds): The following arguments are applied to every ring in the tower: - ``type`` -- string, the precision type - - ``p`` -- the prime of the ground ring. Defining polynomials - will be converted to the new base rings. + - ``p`` -- the prime of the ground ring; defining polynomials + will be converted to the new base rings - ``print_mode`` -- string - - ``print_pos`` -- bool + - ``print_pos`` -- boolean - ``print_sep`` -- string - - ``print_alphabet`` -- dict - - ``show_prec`` -- bool - - ``check`` -- bool + - ``print_alphabet`` -- dictionary + - ``show_prec`` -- boolean + - ``check`` -- boolean - ``label`` -- string (only for lattice precision) The following arguments are only applied to the top ring in the tower: @@ -265,19 +265,19 @@ def change(self, **kwds): The following arguments have special behavior: - - ``prec`` -- integer. If the precision is increased on an extension ring, + - ``prec`` -- integer; if the precision is increased on an extension ring, the precision on the base is increased as necessary (respecting ramification). If the precision is decreased, the precision of the base is unchanged. - - ``field`` -- bool. If ``True``, switch to a tower of fields via the fraction field. - If False, switch to a tower of rings of integers. + - ``field`` -- boolean; if ``True``, switch to a tower of fields via the fraction field + If ``False``, switch to a tower of rings of integers - - ``q`` -- prime power. Replace the initial unramified extension of `\QQ_p` or `\ZZ_p` + - ``q`` -- prime power; replace the initial unramified extension of `\QQ_p` or `\ZZ_p` with an unramified extension of residue cardinality `q`. If the initial extension is ramified, add in an unramified extension. - - ``base`` -- ring or field. Use a specific base ring instead of recursively - calling :meth:`change` down the tower. + - ``base`` -- ring or field; use a specific base ring instead of recursively + calling :meth:`change` down the tower See the :mod:`constructors ` for more details on the meaning of these arguments. @@ -291,7 +291,7 @@ def change(self, **kwds): or the precision type:: - sage: Zp(5).change(type="capped-abs") + sage: Zp(5).change(type='capped-abs') 5-adic Ring with capped absolute precision 20 or even the prime:: @@ -617,11 +617,9 @@ def residue_characteristic(self): INPUT: - - ``self`` -- a p-adic ring. - - OUTPUT: + - ``self`` -- a `p`-adic ring - The characteristic of the residue field. + OUTPUT: the characteristic of the residue field EXAMPLES:: @@ -632,19 +630,17 @@ def residue_characteristic(self): def defining_polynomial(self, var='x', exact=False): r""" - Return the defining polynomial of this local ring + Return the defining polynomial of this local ring. INPUT: - - ``var`` -- string (default: ``'x'``), the name of the variable - - - ``exact`` -- a boolean (default: ``False``), whether to return the - underlying exact defining polynomial rather than the one with coefficients - in the base ring. + - ``var`` -- string (default: ``'x'``); the name of the variable - OUTPUT: + - ``exact`` -- boolean (default: ``False``); whether to return the + underlying exact defining polynomial rather than the one with coefficients + in the base ring - The defining polynomial of this ring as an extension over its ground ring + OUTPUT: the defining polynomial of this ring as an extension over its ground ring EXAMPLES:: @@ -675,9 +671,7 @@ def ground_ring(self): - ``self`` -- a local ring - OUTPUT: - - The ground ring of ``self``, i.e., itself. + OUTPUT: the ground ring of ``self``, i.e., itself EXAMPLES:: @@ -700,9 +694,7 @@ def ground_ring_of_tower(self): - ``self`` -- a `p`-adic ring - OUTPUT: - - The ground ring of the tower for ``self``, i.e., itself. + OUTPUT: the ground ring of the tower for ``self``, i.e., itself EXAMPLES:: @@ -714,7 +706,7 @@ def ground_ring_of_tower(self): def absolute_degree(self): r""" - Return the degree of this extension over the prime p-adic field/ring. + Return the degree of this extension over the prime `p`-adic field/ring. EXAMPLES:: @@ -1004,9 +996,7 @@ def inertia_subring(self): - ``self`` -- a local ring - OUTPUT: - - - the inertia subring of self, i.e., itself + OUTPUT: the inertia subring of ``self``, i.e., itself EXAMPLES:: @@ -1024,9 +1014,7 @@ def maximal_unramified_subextension(self): - ``self`` -- a local ring - OUTPUT: - - - the maximal unramified subextension of ``self`` + OUTPUT: the maximal unramified subextension of ``self`` EXAMPLES:: @@ -1061,7 +1049,8 @@ def uniformiser(self): def uniformiser_pow(self, n): r""" - Return the `n`th power of the uniformiser of ``self`` (as an element of ``self``). + Return the `n`-th power of the uniformiser of ``self`` (as an element + of ``self``). EXAMPLES:: @@ -1093,7 +1082,6 @@ def _test_add_bigoh(self, **options): sage: K = Qp(3) sage: K._test_add_bigoh() - """ tester = self._tester(**options) for x in tester.some_elements(): @@ -1131,7 +1119,6 @@ def _test_residue(self, **options): sage: R = Zp(2) sage: R._test_residue() - """ tester = self._tester(**options) tester.assertEqual(self.residue_field().characteristic(), self.residue_characteristic()) @@ -1222,14 +1209,14 @@ def _matrix_smith_form(self, M, transformation, integral, exact): :meth:`sage.matrix.matrix2.Matrix.smith_form` to compute the Smith normal form over local rings and fields. - The entries of the Smith normal form are normalized such that non-zero + The entries of the Smith normal form are normalized such that nonzero entries of the diagonal are powers of the distinguished uniformizer. INPUT: - ``M`` -- a matrix over this ring - - ``transformation`` -- a boolean; whether the transformation matrices + - ``transformation`` -- boolean; whether the transformation matrices are returned - ``integral`` -- a subring of the base ring or ``True``; the entries @@ -1237,13 +1224,13 @@ def _matrix_smith_form(self, M, transformation, integral, exact): entries are in the ring of integers of the base ring. - ``exact`` -- boolean. If ``True``, the diagonal smith form will - be exact, or raise a ``PrecisionError`` if this is not possible. + be exact, or raise a :exc:`PrecisionError` if this is not possible If ``False``, the diagonal entries will be inexact, but the transformation matrices will be exact. EXAMPLES:: - sage: A = Zp(5, prec=10, print_mode="digits") + sage: A = Zp(5, prec=10, print_mode='digits') sage: M = matrix(A, 2, 2, [2, 7, 1, 6]) sage: S, L, R = M.smith_form() # indirect doctest @@ -1494,7 +1481,6 @@ def _test_matrix_smith(self, **options): EXAMPLES:: sage: ZpCA(5, 15)._test_matrix_smith() # needs sage.geometry.polyhedron - """ tester = self._tester(**options) tester.assertEqual(self.residue_field().characteristic(), self.residue_characteristic()) @@ -1663,8 +1649,7 @@ def _matrix_determinant(self, M): for j in range(n): prec = min(prec, S[i,j].precision_absolute()) prec -= S[i,i].valuation() - if prec < relprec: - relprec = prec + relprec = min(prec, relprec) if prec < 0: relprec_neg += prec if relprec_neg < 0: diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index e0a03ea2450..84143902e86 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -34,14 +34,14 @@ cdef class LocalGenericElement(CommutativeRingElement): cpdef _div_(self, right): r""" - Returns the quotient of ``self`` by ``right``. + Return the quotient of ``self`` by ``right``. INPUT: - - ``self`` -- a `p`-adic element. + - ``self`` -- a `p`-adic element - - ``right`` -- a `p`-adic element distinguishable from zero. - In a fixed-modulus ring, this element must be a unit. + - ``right`` -- a `p`-adic element distinguishable from zero; + in a fixed-modulus ring, this element must be a unit EXAMPLES:: @@ -63,11 +63,9 @@ cdef class LocalGenericElement(CommutativeRingElement): def inverse_of_unit(self): r""" - Returns the inverse of ``self`` if ``self`` is a unit. + Return the inverse of ``self`` if ``self`` is a unit. - OUTPUT: - - - an element in the same ring as ``self`` + OUTPUT: an element in the same ring as ``self`` EXAMPLES:: @@ -77,7 +75,7 @@ cdef class LocalGenericElement(CommutativeRingElement): sage: b = a.inverse_of_unit(); b 2 + 3 + 3^2 + 3^3 + 3^4 + O(3^5) - A ``ZeroDivisionError`` is raised if an element has no inverse in the + A :exc:`ZeroDivisionError` is raised if an element has no inverse in the ring:: sage: R(3).inverse_of_unit() @@ -112,7 +110,7 @@ cdef class LocalGenericElement(CommutativeRingElement): TESTS: - Test that this works for all kinds of p-adic base elements:: + Test that this works for all kinds of `p`-adic base elements:: sage: ZpCA(3,5)(2).inverse_of_unit() 2 + 3 + 3^2 + 3^3 + 3^4 + O(3^5) @@ -163,7 +161,6 @@ cdef class LocalGenericElement(CommutativeRingElement): sage: R = QpCR(3,5); S. = R[]; W. = R.extension( t^2 - 3 ) sage: (t - 1).inverse_of_unit() 2 + 2*t + t^2 + t^3 + t^4 + t^5 + t^6 + t^7 + t^8 + t^9 + O(t^10) - """ if not self.is_unit(): raise ZeroDivisionError(f"inverse of {self} does not exist") @@ -172,7 +169,7 @@ cdef class LocalGenericElement(CommutativeRingElement): def __iter__(self): """ Local elements should not be iterable, so this method correspondingly - raises a ``TypeError``. + raises a :exc:`TypeError`. .. NOTE:: @@ -194,13 +191,12 @@ cdef class LocalGenericElement(CommutativeRingElement): Traceback (most recent call last): ... TypeError: this local element is not iterable - """ raise TypeError("this local element is not iterable") def slice(self, i, j, k = 1, lift_mode='simple'): r""" - Returns the sum of the `pi^{i + l \cdot k}` terms of the series + Return the sum of the `pi^{i + l \cdot k}` terms of the series expansion of this element, where pi is the uniformizer, for `i + l \cdot k` between ``i`` and ``j-1`` inclusive, and nonnegative integers `l`. Behaves analogously to the slice @@ -208,11 +204,11 @@ cdef class LocalGenericElement(CommutativeRingElement): INPUT: - - ``i`` -- an integer; if set to ``None``, the sum will start with the - first non-zero term of the series. + - ``i`` -- integer; if set to ``None``, the sum will start with the + first nonzero term of the series - - ``j`` -- an integer; if set to ``None`` or `\infty`, this method - behaves as if it was set to the absolute precision of this element. + - ``j`` -- integer; if set to ``None`` or `\infty`, this method + behaves as if it was set to the absolute precision of this element - ``k`` -- (default: 1) a positive integer @@ -357,7 +353,6 @@ cdef class LocalGenericElement(CommutativeRingElement): sage: a = F(0) sage: a.slice(0,None) 0 - """ if k is None: k = 1 @@ -380,7 +375,7 @@ cdef class LocalGenericElement(CommutativeRingElement): start -= self.valuation() stop -= self.valuation() - # make sure that start and stop are non-negative + # make sure that start and stop are nonnegative if start<0: i += -start # fix the value of ppow below start = 0 @@ -412,7 +407,7 @@ cdef class LocalGenericElement(CommutativeRingElement): def _latex_(self): r""" - Return a latex representation of self. + Return a latex representation of ``self``. EXAMPLES:: @@ -437,7 +432,7 @@ cdef class LocalGenericElement(CommutativeRingElement): cpdef _sub_(self, right): r""" - Returns the difference between ``self`` and ``right``. + Return the difference between ``self`` and ``right``. EXAMPLES:: @@ -456,7 +451,7 @@ cdef class LocalGenericElement(CommutativeRingElement): INPUT: - - ``absprec`` -- an integer or positive infinity + - ``absprec`` -- integer or positive infinity EXAMPLES:: @@ -514,7 +509,6 @@ cdef class LocalGenericElement(CommutativeRingElement): sage: R. = Qp(7).extension(x^3 - 7) # needs sage.libs.ntl sage: (pi^93).add_bigoh(-10) # needs sage.libs.ntl sage.symbolic O(pi^-10) - """ parent = self.parent() if absprec >= self.precision_absolute(): @@ -531,15 +525,13 @@ cdef class LocalGenericElement(CommutativeRingElement): def is_integral(self): """ - Returns whether self is an integral element. + Return whether ``self`` is an integral element. INPUT: - ``self`` -- a local ring element - OUTPUT: - - - boolean -- whether ``self`` is an integral element. + OUTPUT: boolean; whether ``self`` is an integral element EXAMPLES:: @@ -556,15 +548,14 @@ cdef class LocalGenericElement(CommutativeRingElement): def is_padic_unit(self): """ - Returns whether self is a `p`-adic unit. That is, whether it has zero valuation. + Return whether ``self`` is a `p`-adic unit. That is, whether it has + zero valuation. INPUT: - ``self`` -- a local ring element - OUTPUT: - - - boolean -- whether ``self`` is a unit + OUTPUT: boolean; whether ``self`` is a unit EXAMPLES:: @@ -613,15 +604,13 @@ cdef class LocalGenericElement(CommutativeRingElement): def is_unit(self): """ - Returns whether self is a unit + Return whether ``self`` is a unit. INPUT: - ``self`` -- a local ring element - OUTPUT: - - - boolean -- whether ``self`` is a unit + OUTPUT: boolean; whether ``self`` is a unit .. NOTE:: @@ -722,24 +711,22 @@ cdef class LocalGenericElement(CommutativeRingElement): INPUT: - - ``self`` -- a `p`-adic element. + - ``self`` -- a `p`-adic element - - ``extend`` -- a boolean (default: ``True``); if ``True``, return a + - ``extend`` -- boolean (default: ``True``); if ``True``, return a square root in an extension if necessary; if ``False`` and no root - exists in the given ring or field, raise a ValueError. + exists in the given ring or field, raise a :exc:`ValueError`. - - ``all`` -- a boolean (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots - - ``algorithm`` -- ``"pari"``, ``"sage"`` or ``None`` (default: + - ``algorithm`` -- ``'pari'``, ``'sage'`` or ``None`` (default: ``None``); Sage provides an implementation for any extension of `Q_p` whereas only square roots over `Q_p` is implemented in Pari; - the default is ``"pari"`` if the ground field is `Q_p`, ``"sage"`` + the default is ``'pari'`` if the ground field is `Q_p`, ``'sage'`` otherwise. - OUTPUT: - - The square root or the list of all square roots of this element. + OUTPUT: the square root or the list of all square roots of this element .. NOTE:: @@ -839,16 +826,14 @@ cdef class LocalGenericElement(CommutativeRingElement): def normalized_valuation(self): r""" - Returns the normalized valuation of this local ring element, + Return the normalized valuation of this local ring element, i.e., the valuation divided by the absolute ramification index. INPUT: - - ``self`` -- a local ring element. - - OUTPUT: + - ``self`` -- a local ring element - rational -- the normalized valuation of ``self``. + OUTPUT: rational; the normalized valuation of ``self`` EXAMPLES:: @@ -863,17 +848,15 @@ cdef class LocalGenericElement(CommutativeRingElement): def _min_valuation(self): r""" - Returns the valuation of this local ring element. + Return the valuation of this local ring element. This function only differs from valuation for relaxed elements. INPUT: - - ``self`` -- a local ring element. - - OUTPUT: + - ``self`` -- a local ring element - - integer -- the valuation of ``self``. + OUTPUT: integer; the valuation of ``self`` EXAMPLES:: @@ -887,7 +870,7 @@ cdef class LocalGenericElement(CommutativeRingElement): def euclidean_degree(self): r""" - Return the degree of this element as an element of an Euclidean domain. + Return the degree of this element as an element of a Euclidean domain. EXAMPLES: @@ -933,9 +916,9 @@ cdef class LocalGenericElement(CommutativeRingElement): INPUT: - ``other`` -- an element in the same ring - - ``integral`` -- if True, use integral-style remainders even when the parent is a field. - Namely, the remainder will have no terms in its p-adic expansion above - the valuation of ``other``. + - ``integral`` -- if ``True``, use integral-style remainders even when + the parent is a field. Namely, the remainder will have no terms in + its `p`-adic expansion above the valuation of ``other``. EXAMPLES:: @@ -976,7 +959,6 @@ cdef class LocalGenericElement(CommutativeRingElement): sage: x = Zp(3, 5).zero() sage: x._test_trivial_powers() - """ tester = self._tester(**options) @@ -997,7 +979,6 @@ cdef class LocalGenericElement(CommutativeRingElement): sage: x = Zp(3, 5).zero() sage: x._test_expansion() - """ tester = self._tester(**options) diff --git a/src/sage/rings/padics/meson.build b/src/sage/rings/padics/meson.build new file mode 100644 index 00000000000..9cb64492095 --- /dev/null +++ b/src/sage/rings/padics/meson.build @@ -0,0 +1,123 @@ +py.install_sources( + 'all.py', + 'common_conversion.pxd', + 'eisenstein_extension_generic.py', + 'factory.py', + 'generic_nodes.py', + 'lattice_precision.py', + 'local_generic.py', + 'local_generic_element.pxd', + 'misc.py', + 'morphism.pxd', + 'padic_ZZ_pX_CA_element.pxd', + 'padic_ZZ_pX_CR_element.pxd', + 'padic_ZZ_pX_FM_element.pxd', + 'padic_ZZ_pX_element.pxd', + 'padic_base_generic.py', + 'padic_base_leaves.py', + 'padic_capped_absolute_element.pxd', + 'padic_capped_relative_element.pxd', + 'padic_ext_element.pxd', + 'padic_extension_generic.py', + 'padic_extension_leaves.py', + 'padic_fixed_mod_element.pxd', + 'padic_floating_point_element.pxd', + 'padic_generic.py', + 'padic_generic_element.pxd', + 'padic_lattice_element.py', + 'padic_printing.pxd', + 'padic_relaxed_element.pxd', + 'padic_relaxed_errors.pxd', + 'padic_valuation.py', + 'pow_computer.pxd', + 'pow_computer_ext.pxd', + 'pow_computer_flint.pxd', + 'pow_computer_relative.pxd', + 'precision_error.py', + 'qadic_flint_CA.pxd', + 'qadic_flint_CR.pxd', + 'qadic_flint_FM.pxd', + 'qadic_flint_FP.pxd', + 'relative_extension_leaves.py', + 'relative_ramified_CA.pxd', + 'relative_ramified_CR.pxd', + 'relative_ramified_FM.pxd', + 'relative_ramified_FP.pxd', + 'tests.py', + 'tutorial.py', + 'unramified_extension_generic.py', + subdir: 'sage/rings/padics', +) + +extension_data = { + 'common_conversion' : files('common_conversion.pyx'), + 'local_generic_element' : files('local_generic_element.pyx'), + 'morphism' : files('morphism.pyx'), + 'padic_capped_absolute_element' : files('padic_capped_absolute_element.pyx'), + 'padic_capped_relative_element' : files('padic_capped_relative_element.pyx'), + 'padic_fixed_mod_element' : files('padic_fixed_mod_element.pyx'), + 'padic_floating_point_element' : files('padic_floating_point_element.pyx'), + 'padic_generic_element' : files('padic_generic_element.pyx'), + 'padic_relaxed_element' : files('padic_relaxed_element.pyx'), + 'padic_relaxed_errors' : files('padic_relaxed_errors.pyx'), + 'qadic_flint_CA' : files('qadic_flint_CA.pyx'), + 'qadic_flint_CR' : files('qadic_flint_CR.pyx'), + 'qadic_flint_FM' : files('qadic_flint_FM.pyx'), + 'qadic_flint_FP' : files('qadic_flint_FP.pyx'), + 'relative_ramified_CA' : files('relative_ramified_CA.pyx'), + 'relative_ramified_CR' : files('relative_ramified_CR.pyx'), + 'relative_ramified_FM' : files('relative_ramified_FM.pyx'), + 'relative_ramified_FP' : files('relative_ramified_FP.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/padics', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_ntl, + inc_rings, + inc_rings_finite, + inc_src, + ], + dependencies: [py_dep, cypari2, cysignals, flint, gmp, m, ntl], + ) +endforeach + +extension_data_cpp = { + 'padic_ZZ_pX_CA_element': files('padic_ZZ_pX_CA_element.pyx'), + 'padic_ZZ_pX_CR_element': files('padic_ZZ_pX_CR_element.pyx'), + 'padic_ZZ_pX_FM_element': files('padic_ZZ_pX_FM_element.pyx'), + 'padic_ZZ_pX_element': files('padic_ZZ_pX_element.pyx'), + 'padic_ext_element': files('padic_ext_element.pyx'), + 'padic_printing': files('padic_printing.pyx'), + 'pow_computer': files('pow_computer.pyx'), + 'pow_computer_ext': files('pow_computer_ext.pyx'), + 'pow_computer_flint': files('pow_computer_flint.pyx'), + 'pow_computer_relative': files('pow_computer_relative.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/padics', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_ntl, + inc_rings, + inc_rings_finite, + ], + dependencies: [py_dep, cypari2, cysignals, flint, gmp, m, ntl], + ) +endforeach + diff --git a/src/sage/rings/padics/misc.py b/src/sage/rings/padics/misc.py index dfe0feee162..d7ce570a732 100644 --- a/src/sage/rings/padics/misc.py +++ b/src/sage/rings/padics/misc.py @@ -30,6 +30,7 @@ python_min = min python_max = max + def gauss_sum(a, p, f, prec=20, factored=False, algorithm='pari', parent=None): r""" Return the Gauss sum `g_q(a)` as a `p`-adic number. @@ -68,11 +69,11 @@ def gauss_sum(a, p, f, prec=20, factored=False, algorithm='pari', parent=None): - ``f`` -- positive integer - - ``prec`` -- positive integer (optional, 20 by default) + - ``prec`` -- positive integer (default: 20) - - ``factored`` -- boolean (optional, ``False`` by default) + - ``factored`` -- boolean (default: ``False``) - - ``algorithm`` -- flag passed to p-adic Gamma function (optional, ``"pari"`` by default) + - ``algorithm`` -- flag passed to `p`-adic Gamma function (default: ``'pari'``) OUTPUT: @@ -184,9 +185,10 @@ def max(*L): except ValueError: return -infinity + def precprint(prec_type, prec_cap, p): """ - String describing the precision mode on a p-adic ring or field. + String describing the precision mode on a `p`-adic ring or field. EXAMPLES:: @@ -209,6 +211,7 @@ def precprint(prec_type, prec_cap, p): 'relaxed':'handled with relaxed arithmetics'} return precD[prec_type] + def trim_zeros(L): r""" Strips trailing zeros/empty lists from a list. diff --git a/src/sage/rings/padics/morphism.pyx b/src/sage/rings/padics/morphism.pyx index a9f041e1d70..d4684f9649d 100644 --- a/src/sage/rings/padics/morphism.pyx +++ b/src/sage/rings/padics/morphism.pyx @@ -1,6 +1,6 @@ # sage.doctest: needs sage.libs.ntl """ -Frobenius endomorphisms on p-adic fields +Frobenius endomorphisms on `p`-adic fields """ # **************************************************************************** # Copyright (C) 2013 Xavier Caruso @@ -26,15 +26,15 @@ from sage.rings.padics.padic_generic import pAdicGeneric cdef class FrobeniusEndomorphism_padics(RingHomomorphism): """ - A class implementing Frobenius endomorphisms on p-adic fields. + A class implementing Frobenius endomorphisms on `p`-adic fields. """ def __init__ (self,domain,n=1): """ INPUT: - - ``domain`` -- an unramified p-adic field + - ``domain`` -- an unramified `p`-adic field - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) .. NOTE:: @@ -240,7 +240,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): def _composition(self, right): """ - Return self o right. + Return ``self`` o ``right``. EXAMPLES:: @@ -267,7 +267,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): def is_injective(self): """ Return ``True`` since any power of the Frobenius endomorphism - over an unramified p-adic field is always injective. + over an unramified `p`-adic field is always injective. EXAMPLES:: @@ -281,7 +281,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): def is_surjective(self): """ Return ``True`` since any power of the Frobenius endomorphism - over an unramified p-adic field is always surjective. + over an unramified `p`-adic field is always surjective. EXAMPLES:: @@ -328,7 +328,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): cpdef _richcmp_(left, right, int op): """ - Compare ``left`` and ``right`` + Compare ``left`` and ``right``. EXAMPLES:: @@ -338,7 +338,6 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): sage: F == G True - """ if left is right: return rich_to_bool(op, 0) diff --git a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx index 09062475876..7efcfc5a047 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx @@ -16,12 +16,12 @@ For the parent class see padic_extension_leaves.pyx. The underlying implementation is through NTL's ``ZZ_pX`` class. Each element contains the following data: -- ``absprec`` (long) -- An integer giving the precision to which this +- ``absprec`` -- long; an integer giving the precision to which this element is defined. This is the power of the uniformizer modulo which the element is well defined. -- ``value`` (``ZZ_pX_c``) -- An ntl ``ZZ_pX`` storing the value. The - variable `x` is the uniformizer in the case of Eisenstein extensions. +- ``value`` -- ``ZZ_pX_c``; an ntl ``ZZ_pX`` storing the value. The + variable `x` is the uniformizer in the case of Eisenstein extensions This ZZ_pX is created with global ntl modulus determined by absprec. Let `a` be absprec and `e` be the ramification index over `\QQ_p` or `\ZZ_p`. Then the modulus is given by @@ -29,15 +29,15 @@ element contains the following data: to mix moduli. ``ZZ_pX_conv_modulus`` gives a semi-safe way to convert between different moduli without having to pass through ZZX. -- ``prime_pow`` (some subclass of ``PowComputer_ZZ_pX``) -- a class, +- ``prime_pow`` -- (some subclass of ``PowComputer_ZZ_pX``) a class, identical among all elements with the same parent, holding common data. - + ``prime_pow.deg`` -- The degree of the extension + + ``prime_pow.deg`` -- the degree of the extension - + ``prime_pow.e`` -- The ramification index + + ``prime_pow.e`` -- the ramification index - + ``prime_pow.f`` -- The inertia degree + + ``prime_pow.f`` -- the inertia degree + ``prime_pow.prec_cap`` -- the unramified precision cap. For Eisenstein extensions this is the smallest power of p that is @@ -64,7 +64,7 @@ element contains the following data: ``prime_pow.restore_top_context`` -- restores the given context. + ``prime_pow.get_modulus``, ``get_modulus_capdiv``, - ``get_top_modulus`` -- Returns a ``ZZ_pX_Modulus_c*`` pointing to + ``get_top_modulus`` -- returns a ``ZZ_pX_Modulus_c*`` pointing to a polynomial modulus defined modulo `p^n` (appropriately divided by ``prime_pow.e`` in the capdiv case). @@ -198,14 +198,15 @@ cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) -1 cdef class pAdicZZpXCAElement(pAdicZZpXElement): def __init__(self, parent, x, absprec = infinity, relprec = infinity, empty = False): """ - Creates an element of a capped absolute precision, unramified or Eisenstein extension of Zp or Qp. + Create an element of a capped absolute precision, unramified or + Eisenstein extension of Zp or Qp. INPUT: - ``parent`` -- either an ``EisensteinRingCappedAbsolute`` or ``UnramifiedRingCappedAbsolute`` - - `x` -- an integer, rational, `p`-adic element, polynomial, + - ``x`` -- integer, rational, `p`-adic element, polynomial, list, integer_mod, pari int/frac/poly_t/pol_mod, an ``ntl_ZZ_pX``, an ``ntl_ZZ``, an ``ntl_ZZ_p``, an ``ntl_ZZX``, or something convertible into parent.residue_field() @@ -216,7 +217,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): - ``relprec`` -- an upper bound on the relative precision of the element created - - ``empty`` -- whether to return after initializing to zero. + - ``empty`` -- whether to return after initializing to zero EXAMPLES:: @@ -259,7 +260,6 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): sage: W. = R.extension(a^2 + 1) sage: W(W.residue_field().zero()) O(3) - """ pAdicZZpXElement.__init__(self, parent) cdef long aprec, rprec, ctx_prec @@ -439,7 +439,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_inexact_zero(self, long absprec) except -1: """ - Sets ``self`` to be zero with valuation ``absprec``. + Set ``self`` to be zero with valuation ``absprec``. EXAMPLES:: @@ -463,7 +463,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef bint _is_inexact_zero(self) except -1: """ - Tests if ``self`` is an inexact zero. + Test if ``self`` is an inexact zero. EXAMPLES:: @@ -482,7 +482,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set(self, ZZ_pX_c* value, long absprec) except -1: """ - Sets ``value`` and ``absprec`` directly. + Set ``value`` and ``absprec`` directly. EXAMPLES:: @@ -504,7 +504,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_mpz_abs(self, mpz_t x, long absprec) except -1: """ - Sets ``self`` from an ``mpz_t`` with absolute precision + Set ``self`` from an ``mpz_t`` with absolute precision bounded by ``absprec``. EXAMPLES:: @@ -531,7 +531,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_mpz_both(self, mpz_t x, long absprec, long relprec) except -1: """ - Sets ``self`` from an ``mpz_t`` with relative precision + Set ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. @@ -567,7 +567,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_mpq_abs(self, mpq_t x, long absprec) except -1: """ - Sets ``self`` from an ``mpq_t`` with absolute precision bounded by + Set ``self`` from an ``mpq_t`` with absolute precision bounded by ``absprec``. EXAMPLES:: @@ -597,7 +597,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_mpq_both(self, mpq_t x, long absprec, long relprec) except -1: """ - Sets ``self`` from an ``mpq_t`` with relative precision bounded by + Set ``self`` from an ``mpq_t`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. EXAMPLES:: @@ -658,7 +658,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_ZZX_abs(self, ZZX_c poly, long absprec) except -1: """ - Sets ``self`` from a ``ZZX`` with absolute precision bounded by + Set ``self`` from a ``ZZX`` with absolute precision bounded by ``absprec``. EXAMPLES:: @@ -706,7 +706,8 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_ZZ_pX_abs(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec) except -1: """ - Sets ``self`` from a ``ZZ_pX`` with absolute precision bounded by ``absprec`` (and by ``ctx``). + Set ``self`` from a ``ZZ_pX`` with absolute precision bounded by + ``absprec`` (and by ``ctx``). EXAMPLES:: @@ -735,7 +736,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef int _set_from_ZZ_pX_both(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec, long relprec) except -1: """ - Sets ``self`` from a ``ZZ_pX`` with relative precision bounded by + Set ``self`` from a ``ZZ_pX`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. EXAMPLES:: @@ -770,7 +771,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef bint _set_prec_abs(self, long absprec) except -1: """ - Safely sets the absolute precision of self to ``absprec``. + Safely set the absolute precision of ``self`` to ``absprec``. Returns ``True`` iff ``self.absprec`` was reset. @@ -800,7 +801,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13) """ if absprec < 0: - raise ValueError("absprec must be non-negative") + raise ValueError("absprec must be nonnegative") if self.absprec == absprec: return False if absprec > 0: @@ -814,7 +815,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef bint _set_prec_both_with_ordp(self, long ordp, long absprec, long relprec) except -1: """ - Sets the absolute precision of ``self`` to the minimum of ``absprec`` + Set the absolute precision of ``self`` to the minimum of ``absprec`` and ``ordp + relprec``. Note that this will wipe out anything in ``self.value``. Be @@ -847,7 +848,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef pAdicZZpXCAElement _new_c(self, long absprec): """ - Returns a new element with the same parent as ``self`` and + Return a new element with the same parent as ``self`` and absolute precision ``absprec``. EXAMPLES:: @@ -924,7 +925,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def __invert__(self): """ - Returns the inverse of ``self``. + Return the inverse of ``self``. EXAMPLES:: @@ -945,7 +946,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef pAdicZZpXCRElement to_fraction_field(self): """ - Returns ``self`` cast into the fraction field of ``self.parent()``. + Return ``self`` cast into the fraction field of ``self.parent()``. EXAMPLES:: @@ -972,7 +973,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef pAdicZZpXCAElement _lshift_c(self, long n): """ - Multiplies ``self`` by the uniformizer raised to the power ``n``. If + Multiply ``self`` by the uniformizer raised to the power ``n``. If ``n`` is negative, right shifts by ``-n``. EXAMPLES:: @@ -993,7 +994,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def __lshift__(pAdicZZpXCAElement self, shift): """ - Multiplies ``self`` by the uniformizer raised to the power ``n``. If + Multiply ``self`` by the uniformizer raised to the power ``n``. If ``n`` is negative, right shifts by ``-n``. EXAMPLES:: @@ -1023,8 +1024,8 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef pAdicZZpXCAElement _rshift_c(self, long n): """ - Divides ``self`` by the uniformizer raised to the power ``n``. If - parent is not a field, throws away the non-positive part of + Divide ``self`` by the uniformizer raised to the power ``n``. If + parent is not a field, throws away the nonpositive part of the series expansion. If ``n`` is negative, left shifts by ``-n``. EXAMPLES:: @@ -1090,8 +1091,8 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def __rshift__(pAdicZZpXCAElement self, shift): """ - Divides ``self`` by the uniformizer raised to the power ``n``. If - parent is not a field, throws away the non-positive part of + Divide ``self`` by the uniformizer raised to the power ``n``. If + parent is not a field, throws away the nonpositive part of the series expansion. If ``n`` is negative, left shifts by ``-n``. EXAMPLES:: @@ -1121,7 +1122,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef _neg_(self): """ - Returns ``-self``. + Return ``-self``. EXAMPLES:: @@ -1150,7 +1151,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def __pow__(pAdicZZpXCAElement self, _right, m): # m ignored r""" - Computes ``self^right``. + Compute ``self^right``. Note: when right is divisible by `p` then one can get more precision than expected. @@ -1177,7 +1178,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): So if right is divisible by `p^k` we can multiply the relative precision by `p` until we exceed `e/(p-1)`, then add `e` until we have done a total of `k` things: the precision of the - result can therefore be greater than the precision of self. + result can therefore be greater than the precision of ``self``. There is also the issue of `p`-adic exponents, and determining how the precision of the exponent affects the precision of the @@ -1387,7 +1388,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef _add_(self, _right): """ - Computes the sum of ``self`` and ``right``. + Compute the sum of ``self`` and ``right``. EXAMPLES:: @@ -1425,7 +1426,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef _sub_(self, _right): """ - Returns the difference of ``self`` and ``right``. + Return the difference of ``self`` and ``right``. EXAMPLES:: @@ -1466,7 +1467,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef _mul_(self, _right): """ - Returns the product of ``self`` and ``right``. + Return the product of ``self`` and ``right``. EXAMPLES:: @@ -1519,7 +1520,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef _div_(self, right): """ - Returns the quotient of ``self`` by ``right``. + Return the quotient of ``self`` by ``right``. EXAMPLES:: @@ -1548,7 +1549,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def _integer_(self, Z=None): r""" - Returns an integer congruent to this element modulo + Return an integer congruent to this element modulo `\pi`^``self.absolute_precision()``, if possible. EXAMPLES:: @@ -1581,7 +1582,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def __copy__(self): """ - Returns a copy of ``self``. + Return a copy of ``self``. EXAMPLES:: @@ -1608,7 +1609,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): from zero. If ``self`` is an inexact zero of valuation less than ``absprec``, - raises a ``PrecisionError``. + raises a :exc:`PrecisionError`. EXAMPLES:: @@ -1754,7 +1755,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef ZZ_p_c _const_term(self) noexcept: """ - Returns the constant term of ``self.value``. + Return the constant term of ``self.value``. EXAMPLES:: @@ -1770,7 +1771,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def is_equal_to(self, right, absprec = None): """ - Returns whether ``self`` is equal to ``right`` modulo + Return whether ``self`` is equal to ``right`` modulo ``self.uniformizer()^absprec``. If ``absprec`` is ``None``, returns if ``self`` is equal to ``right`` modulo @@ -1793,12 +1794,12 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef pAdicZZpXCAElement lift_to_precision(self, absprec=None): """ - Returns a ``pAdicZZpXCAElement`` congruent to ``self`` but with + Return a ``pAdicZZpXCAElement`` congruent to ``self`` but with absolute precision at least ``absprec``. INPUT: - - ``absprec`` -- (default ``None``) the absolute precision of + - ``absprec`` -- (default: ``None``) the absolute precision of the result. If ``None``, lifts to the maximum precision allowed. @@ -1876,8 +1877,8 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): INPUT: - - ``n`` -- integer (default ``None``). If given, returns the - corresponding entry in the expansion. + - ``n`` -- integer (default: ``None``); if given, returns the + corresponding entry in the expansion EXAMPLES:: @@ -2009,15 +2010,15 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): # INPUT: -# - base -- field or morphism +# - ``base`` -- field or morphism # """ # raise NotImplementedError # def multiplicative_order(self, prec=None): # """ -# Returns the multiplicative order of self, ie the smallest -# positive n so that there is an exact p-adic element congruent -# to self modulo self's precision that is an nth root of unity. +# Returns the multiplicative order of ``self``, ie the smallest +# positive `n` so that there is an exact `p`-adic element congruent +# to ``self`` modulo ``self``'s precision that is an `n`-th root of unity. # Note: unlike the case for Qp and Zp, it is possible to have # non-teichmuller elements with finite orders. This can happen @@ -2026,18 +2027,16 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): # INPUT: -# - self -- a p-adic element -# - prec -- an integer - -# OUTPUT: +# - self -- a `p`-adic element +# - ``prec`` -- integer -# - integer -- the multiplicative order of self +# OUTPUT: integer; the multiplicative order of self # """ # raise NotImplementedError def teichmuller_expansion(self, n = None): r""" - Returns a list [`a_0`, `a_1`,..., `a_n`] such that + Return a list [`a_0`, `a_1`,..., `a_n`] such that: - `a_i^q = a_i` - ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a @@ -2047,8 +2046,8 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): INPUT: - - ``n`` -- integer (default ``None``). If given, returns the corresponding - entry in the expansion. + - ``n`` -- integer (default: ``None``); if given, returns the + corresponding entry in the expansion EXAMPLES:: @@ -2123,7 +2122,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def _teichmuller_set_unsafe(self): """ - Sets this element to the Teichmuller representative with the + Set this element to the Teichmuller representative with the same residue. .. WARNING:: @@ -2157,7 +2156,6 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): sage: R. = ZpCA(2).extension(x^2 - 2) sage: R.teichmuller(a) O(a^40) - """ if self.absprec == 0: raise ValueError("not enough precision known") @@ -2176,7 +2174,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def precision_absolute(self): """ - Returns the absolute precision of ``self``, ie the power of the + Return the absolute precision of ``self``, ie the power of the uniformizer modulo which this element is defined. EXAMPLES:: @@ -2202,7 +2200,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): def precision_relative(self): """ - Returns the relative precision of ``self``, ie the power of + Return the relative precision of ``self``, ie the power of the uniformizer modulo which the unit part of ``self`` is defined. @@ -2235,7 +2233,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef long valuation_c(self) noexcept: """ - Returns the valuation of ``self``. + Return the valuation of ``self``. EXAMPLES:: @@ -2272,7 +2270,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cpdef pAdicZZpXCAElement unit_part(self): """ - Returns the unit part of ``self``, ie ``self / uniformizer^(self.valuation())`` + Return the unit part of ``self``, ie ``self / uniformizer^(self.valuation())``. EXAMPLES:: @@ -2295,7 +2293,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): cdef ext_p_list(self, bint pos): """ - Returns a list of integers (in the Eisenstein case) or a list + Return a list of integers (in the Eisenstein case) or a list of lists of integers (in the unramified case). ``self`` can be reconstructed as a sum of elements of the list times powers of the uniformizer (in the Eisenstein case), or as a sum of diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index 8463d40ce26..82d04980363 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -16,12 +16,12 @@ For the parent class see :mod:`sage.rings.padics.padic_extension_leaves`. The underlying implementation is through NTL's ``ZZ_pX`` class. Each element contains the following data: -- ``ordp`` (``long``) -- A power of the uniformizer to scale the unit +- ``ordp`` -- ``long``; a power of the uniformizer to scale the unit by. For unramified extensions this uniformizer is `p`, for Eisenstein extensions it is not. A value equal to the maximum value of a ``long`` indicates that the element is an exact zero. -- ``relprec`` (``long``) -- A signed integer giving the precision to +- ``relprec`` -- ``long``; a signed integer giving the precision to which this element is defined. For nonzero ``relprec``, the absolute value gives the power of the uniformizer modulo which the unit is defined. A positive value indicates that the element is @@ -34,7 +34,7 @@ element contains the following data: ``ordp`` gives the absolute precision of the element. If ``ordp`` is greater than ``maxordp``, then the element is an exact zero. -- ``unit`` (``ZZ_pX_c``) -- An ntl ``ZZ_pX`` storing the unit part. +- ``unit`` -- ``ZZ_pX_c``; an ntl ``ZZ_pX`` storing the unit part The variable `x` is the uniformizer in the case of Eisenstein extensions. If the element is not normalized, the ``unit`` may or may not actually be a unit. This ``ZZ_pX`` is created with global @@ -51,11 +51,11 @@ element contains the following data: identical among all elements with the same parent, holding common data. - + ``prime_pow.deg`` -- The degree of the extension + + ``prime_pow.deg`` -- the degree of the extension - + ``prime_pow.e`` -- The ramification index + + ``prime_pow.e`` -- the ramification index - + ``prime_pow.f`` -- The inertia degree + + ``prime_pow.f`` -- the inertia degree + ``prime_pow.prec_cap`` -- the unramified precision cap. For Eisenstein extensions this is the smallest power of `p` that is @@ -82,7 +82,7 @@ element contains the following data: ``prime_pow.restore_top_context`` -- restores the given context. + ``prime_pow.get_modulus``, ``get_modulus_capdiv``, - ``get_top_modulus`` -- Returns a ``ZZ_pX_Modulus_c*`` pointing to + ``get_top_modulus`` -- returns a ``ZZ_pX_Modulus_c*`` pointing to a polynomial modulus defined modulo `p^n` (appropriately divided by ``prime_pow.e`` in the capdiv case). @@ -225,7 +225,7 @@ cdef inline int check_ordp(long a) except -1: cdef class pAdicZZpXCRElement(pAdicZZpXElement): def __init__(self, parent, x, absprec = infinity, relprec = infinity, empty = False): r""" - Creates an element of a capped relative precision, unramified + Create an element of a capped relative precision, unramified or Eisenstein extension of `\ZZ_p` or `\QQ_p`. INPUT: @@ -233,7 +233,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): - ``parent`` -- either an ``EisensteinRingCappedRelative`` or ``UnramifiedRingCappedRelative`` - - ``x`` -- an integer, rational, `p`-adic element, polynomial, + - ``x`` -- integer; rational, `p`-adic element, polynomial, list, integer_mod, pari int/frac/poly_t/pol_mod, an ``ntl_ZZ_pX``, an ``ntl_ZZ``, an ``ntl_ZZ_p``, an ``ntl_ZZX``, or something convertible into parent.residue_field() @@ -245,7 +245,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): the element created - ``empty`` -- whether to return after initializing to zero - (without setting the valuation). + (without setting the valuation) EXAMPLES:: @@ -286,7 +286,6 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: L. = K.extension(a^2 + 1) sage: L(L.residue_field().zero()) O(3) - """ pAdicZZpXElement.__init__(self, parent) self.relprec = 0 @@ -533,7 +532,6 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): (..., 0) sage: K(0,1)._cache_key() (..., 1, 0) - """ if self._is_exact_zero(): return (self.parent(), 0) @@ -547,7 +545,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_inexact_zero(self, long absprec) except -1: """ - Sets ``self`` to be zero with valuation absprec. + Set ``self`` to be zero with valuation absprec. EXAMPLES:: @@ -583,7 +581,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_exact_zero(self) except -1: """ - Sets ``self`` to be an exact zero. + Set ``self`` to be an exact zero. EXAMPLES:: @@ -619,7 +617,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef bint _is_exact_zero(self) except -1: """ - Tests if ``self`` is an exact zero. + Test if ``self`` is an exact zero. EXAMPLES:: @@ -645,7 +643,6 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: z = W(0,6) sage: z._is_exact_zero() False - """ if self.ordp == maxordp: return 1 @@ -654,7 +651,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef bint _is_inexact_zero(self) except -1: """ - Tests if ``self`` is an inexact zero. + Test if ``self`` is an inexact zero. EXAMPLES:: @@ -689,7 +686,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set(self, ZZ_pX_c* unit, long ordp, long relprec) except -1: """ - Sets ``unit``, ``ordp`` and ``relprec`` directly. + Set ``unit``, ``ordp`` and ``relprec`` directly. EXAMPLES:: @@ -815,7 +812,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_mpq_rel(self, mpq_t x, long relprec) except -1: """ - Sets ``self`` from an ``mpq_t`` with relative precision + Set ``self`` from an ``mpq_t`` with relative precision bounded by ``relprec``. EXAMPLES:: @@ -876,7 +873,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_mpq_both(self, mpq_t x, long absprec, long relprec) except -1: """ - Sets ``self`` from an ``mpq_t`` with relative precision + Set ``self`` from an ``mpq_t`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. @@ -914,7 +911,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_mpq_part1(self, mpz_t num_unit, mpz_t den_unit, mpq_t x) except -1: """ - Sets ``num_unit`` to be the unit of the numerator, ``den_unit`` to be the unit of the denominator and sets ``self.ordp`` correctly. + Set ``num_unit`` to be the unit of the numerator, ``den_unit`` to be + the unit of the denominator and sets ``self.ordp`` correctly. TESTS:: @@ -973,7 +971,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_ZZX_rel(self, ZZX_c poly, long relprec) except -1: """ - Sets ``self`` from a ``ZZX`` with relative precision bounded by + Set ``self`` from a ``ZZX`` with relative precision bounded by ``relprec``. EXAMPLES:: @@ -1011,7 +1009,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_ZZX_both(self, ZZX_c poly, long absprec, long relprec) except -1: """ - Sets ``self`` from a ``ZZX`` with relative precision bounded by + Set ``self`` from a ``ZZX`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. EXAMPLES:: @@ -1045,8 +1043,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_ZZX_part1(self, ZZX_c poly, long absprec, long relprec) except -1: """ - Sets ``self.ordp`` from ``poly`` and restores the context. ``poly`` must - have degree less than ``self.prime_pow.deg`` + Set ``self.ordp`` from ``poly`` and restores the context. ``poly`` must + have degree less than ``self.prime_pow.deg``. TESTS:: @@ -1088,11 +1086,11 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_ZZ_pX_rel(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long relprec) except -1: """ - Sets ``self`` from a ``ZZ_pX`` with relative precision bounded by + Set ``self`` from a ``ZZ_pX`` with relative precision bounded by ``relprec``. - If ``ctx`` is ``None`` and ``poly`` is 0 this function will raise an error - (a ``ZZ_pX`` cannot represent something with infinite absolute + If ``ctx`` is ``None`` and ``poly`` is 0 this function will raise an + error (a ``ZZ_pX`` cannot represent something with infinite absolute precision). EXAMPLES:: @@ -1131,7 +1129,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_ZZ_pX_both(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec, long relprec) except -1: """ - Sets ``self`` from a ``ZZ_pX`` with relative precision bounded by + Set ``self`` from a ``ZZ_pX`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. EXAMPLES:: @@ -1166,7 +1164,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_ZZ_pX_part1(self, ZZ_pX_c* poly) except -1: """ - Sets ``self.ordp`` based on ``poly``. ``poly`` must not be 0. + Set ``self.ordp`` based on ``poly``. ``poly`` must not be 0. TESTS:: @@ -1206,7 +1204,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef bint _set_prec_rel(self, long relprec) except -1: """ - Safely sets the relative precision of ``self`` to be the absolute + Safely set the relative precision of ``self`` to be the absolute value of ``relprec``. Returns ``True`` iff ``self.relprec`` was reset. @@ -1296,7 +1294,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _normalize(self) except -1: """ - Normalizes ``self``, adjusting ``self.ordp``, ``self.relprec``, and + Normalize ``self``, adjusting ``self.ordp``, ``self.relprec``, and ``self.unit`` so that ``self.unit`` actually represents a unit. EXAMPLES:: @@ -1353,7 +1351,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _internal_lshift(self, long shift) except -1: """ - Multiplies ``self.unit`` by ``x^shift``. + Multiply ``self.unit`` by ``x^shift``. Note that ``self.relprec`` must be set before calling this function and should not be 0, and self.unit must be defined to @@ -1397,7 +1395,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _pshift_self(self, long shift) except -1: """ - Multiplies ``self`` by ``p^shift``. + Multiply ``self`` by ``p^shift``. This function assumes that ``self.relprec``, ``self.ordp`` and ``self.unit`` are already set (in the case ``self.prime_pow.e @@ -1473,7 +1471,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): Return a new element with the same parent as ``self`` and relative precision ``relprec`` - Note that if ``relprec`` is non-positive, the convention is that + Note that if ``relprec`` is nonpositive, the convention is that ``relprec = 0`` indicates an exact or inexact zero, ``relprec < 0`` indicates an unnormalized element. @@ -1557,7 +1555,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def __invert__(self): """ - Return the inverse of this element + Return the inverse of this element. EXAMPLES:: @@ -1595,7 +1593,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef pAdicZZpXCRElement _lshift_c(self, long n): """ - Multiplies ``self`` by the uniformizer raised to the power ``n``. If + Multiply ``self`` by the uniformizer raised to the power ``n``. If ``n`` is negative, right shifts by ``-n``. EXAMPLES:: @@ -1629,7 +1627,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def __lshift__(pAdicZZpXCRElement self, shift): """ - Multiplies ``self`` by the uniformizer raised to the power ``n``. If + Multiply ``self`` by the uniformizer raised to the power ``n``. If ``n`` is negative, right shifts by ``-n``. EXAMPLES:: @@ -1662,8 +1660,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef pAdicZZpXCRElement _rshift_c(self, long n): """ - Divides self by the uniformizer raised to the power ``n``. If - parent is not a field, throws away the non-positive part of + Divide ``self`` by the uniformizer raised to the power ``n``. If + parent is not a field, throws away the nonpositive part of the series expansion. If ``n`` is negative, left shifts by ``-n``. EXAMPLES:: @@ -1727,8 +1725,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def __rshift__(pAdicZZpXCRElement self, shift): """ - Divides self by the uniformizer raised to the power ``n``. If - parent is not a field, throws away the non-positive part of + Divide ``self`` by the uniformizer raised to the power ``n``. If + parent is not a field, throws away the nonpositive part of the series expansion. If ``n`` is negative, left shifts by ``-n``. EXAMPLES:: @@ -1765,7 +1763,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef _neg_(self): """ - Negation + Negation. EXAMPLES:: @@ -1797,7 +1795,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def __pow__(pAdicZZpXCRElement self, _right, m): # m ignored r""" - Computes ``self^right``. + Compute ``self^right``. Note: when ``right`` is divisible by `p` then one can get more precision than expected. @@ -1908,7 +1906,6 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: W. = R.ext(f) sage: type(W(0)^0) == type(W(0)) True - """ self._normalize() cdef Integer right @@ -2161,7 +2158,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef _sub_(self, right): """ - Return the difference of two elements + Return the difference of two elements. EXAMPLES:: @@ -2187,7 +2184,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef _mul_(self, _right): """ - Return the product of two elements + Return the product of two elements. EXAMPLES:: @@ -2240,7 +2237,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef _div_(self, right): """ - Return the quotient of two elements + Return the quotient of two elements. EXAMPLES:: @@ -2270,7 +2267,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def __copy__(self): """ - Return a copy of this element + Return a copy of this element. EXAMPLES:: @@ -2337,7 +2334,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): is indistinguishable from zero. If this element is an inexact zero of valuation less than ``absprec``, - raises a :class:`PrecisionError`. + raises a :exc:`PrecisionError`. EXAMPLES:: @@ -2384,7 +2381,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef ntl_ZZ_pX _ntl_rep_unnormalized(self): """ - Return an ``ntl_ZZ_pX`` holding the current unit part of this element + Return an ``ntl_ZZ_pX`` holding the current unit part of this element. The element is not normalized before this operation, so the polynomial returned may not actually be a unit. @@ -2413,7 +2410,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef ntl_ZZ_pX _ntl_rep(self): """ - Return an ``ntl_ZZ_pX`` that holds the unit part of this element + Return an ``ntl_ZZ_pX`` that holds the unit part of this element. EXAMPLES:: @@ -2435,7 +2432,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef _ntl_rep_abs(self): """ Return a pair ``(f, k)`` where ``f`` is an ``ntl_ZZ_pX`` and ``k`` is a - non-positive integer such that ``self = f(self.parent.gen())*p^k`` + nonpositive integer such that ``self = f(self.parent.gen())*p^k``. EXAMPLES:: @@ -2612,7 +2609,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): # def lift(self): # """ -# Return an element of a number field defined by the same polynomial as self's parent that is congruent to self modulo an appropriate ideal. +# Return an element of a number field defined by the same polynomial as +# ``self``'s parent that is congruent to self modulo an appropriate ideal. # Not currently implemented. # """ @@ -2625,14 +2623,14 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): INPUT: - - ``absprec`` -- (default ``None``) the absolute precision of + - ``absprec`` -- (default: ``None``) the absolute precision of the result. If ``None``, lifts to the maximum precision allowed. .. NOTE:: If setting ``absprec`` that high would violate the - precision cap, raises a precision error. If self is an + precision cap, raises a precision error. If ``self`` is an inexact zero and ``absprec`` is greater than the maximum allowed valuation, raises an error. @@ -2734,8 +2732,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): INPUT: - - ``n`` -- integer (default ``None``). If given, returns the corresponding - entry in the expansion. + - ``n`` -- integer (default: ``None``); if given, returns the + corresponding entry in the expansion EXAMPLES:: @@ -2782,7 +2780,6 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: w = u - v^2 sage: w.expansion(4) 0 - """ self._normalize() if lift_mode == 'teichmuller': @@ -2857,7 +2854,6 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] - """ if self.valuation_c() < 0: raise ValueError("self must be integral") @@ -2901,9 +2897,9 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): # def multiplicative_order(self, prec=None): # """ -# Return the multiplicative order of self, ie the smallest -# positive n so that there is an exact p-adic element congruent -# to self modulo self's precision that is an nth root of unity. +# Return the multiplicative order of ``self``, ie the smallest +# positive `n` so that there is an exact `p`-adic element congruent +# to ``self`` modulo ``self``'s precision that is an `n`-th root of unity. # Note: unlike the case for Qp and Zp, it is possible to have # non-teichmuller elements with finite orders. This can happen @@ -2912,18 +2908,16 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): # INPUT: -# - self -- a p-adic element -# - prec -- an integer - -# OUTPUT: +# - self -- a `p`-adic element +# - ``prec`` -- integer -# - integer -- the multiplicative order of self +# OUTPUT: integer; the multiplicative order of ``self`` # """ # raise NotImplementedError def teichmuller_expansion(self, n = None): r""" - Return a list [`a_0`, `a_1`,..., `a_n`] such that + Return a list [`a_0`, `a_1`,..., `a_n`] such that: - `a_i^q = a_i` - ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a @@ -2933,8 +2927,8 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): INPUT: - - ``n`` -- integer (default ``None``). If given, returns the corresponding - entry in the expansion. + - ``n`` -- integer (default: ``None``); if given, returns the + corresponding entry in the expansion EXAMPLES:: @@ -3020,7 +3014,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def _teichmuller_set_unsafe(self): """ - Sets this element to the Teichmuller representative with the + Set this element to the Teichmuller representative with the same residue. .. WARNING:: diff --git a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx index f85c6b7f3b4..a3dcd42b3d6 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx @@ -16,7 +16,7 @@ For the parent class see ``padic_extension_leaves.pyx``. The underlying implementation is through NTL's ``ZZ_pX`` class. Each element contains the following data: -- ``value`` (``ZZ_pX_c``) -- An ntl ``ZZ_pX`` storing the value. The +- ``value`` (``ZZ_pX_c``) -- an ntl ``ZZ_pX`` storing the value. The variable `x` is the uniformizer in the case of Eisenstein extensions. This ``ZZ_pX`` is created with global ntl modulus determined by the parent's precision cap and shared among all elements. @@ -27,9 +27,9 @@ element contains the following data: * ``prime_pow.deg`` -- the degree of the extension - * ``prime_pow.e`` -- the ramification index + * ``prime_pow.e`` -- the ramification index - * ``prime_pow.f`` -- the inertia degree + * ``prime_pow.f`` -- the inertia degree * ``prime_pow.prec_cap`` -- the unramified precision cap: for Eisenstein extensions this is the smallest power of `p` that is @@ -56,7 +56,7 @@ element contains the following data: ``prime_pow.restore_top_context`` -- restores the given context * ``prime_pow.get_modulus``, ``get_modulus_capdiv``, - ``get_top_modulus`` -- Returns a ``ZZ_pX_Modulus_c*`` pointing to + ``get_top_modulus`` -- returns a ``ZZ_pX_Modulus_c*`` pointing to a polynomial modulus defined modulo `p^n` (appropriately divided by ``prime_pow.e`` in the capdiv case). @@ -152,7 +152,7 @@ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing cdef class pAdicZZpXFMElement(pAdicZZpXElement): def __init__(self, parent, x, absprec=None, relprec=None, empty=False): r""" - Creates an element of a fixed modulus, unramified or + Create an element of a fixed modulus, unramified or eisenstein extension of `\ZZ_p` or `\QQ_p`. INPUT: @@ -160,7 +160,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): - ``parent`` -- either an ``EisensteinRingFixedMod`` or ``UnramifiedRingFixedMod`` - - ``x`` -- an integer, rational, `p`-adic element, polynomial, + - ``x`` -- integer, rational, `p`-adic element, polynomial, list, integer_mod, pari int/frac/poly_t/pol_mod, an ``ntl_ZZ_pX``, an ``ntl_ZZX``, an ``ntl_ZZ``, or an ``ntl_ZZ_p`` @@ -196,7 +196,6 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): sage: W. = R.extension(a^2 + 1) sage: W(W.residue_field().zero()) 0 - """ pAdicZZpXElement.__init__(self, parent) if empty: @@ -283,7 +282,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cdef int _set_from_mpz(self, mpz_t x) except -1: """ - Sets ``self`` from an ``mpz_t``. + Set ``self`` from an ``mpz_t``. EXAMPLES:: @@ -307,7 +306,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cdef int _set_from_mpq(self, mpq_t x) except -1: """ - Sets ``self`` from an ``mpq_t``. + Set ``self`` from an ``mpq_t``. EXAMPLES:: @@ -341,7 +340,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cdef int _set_from_ZZ_pX(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx) except -1: """ - Sets ``self`` from a ``ZZ_pX_c``. + Set ``self`` from a ``ZZ_pX_c``. EXAMPLES:: @@ -361,7 +360,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cdef int _set_from_ZZX(self, ZZX_c poly) except -1: """ - Sets ``self`` from a ``ZZX`` with relative precision bounded + Set ``self`` from a ``ZZX`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. EXAMPLES:: @@ -381,7 +380,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cpdef bint _is_inexact_zero(self) except -1: """ - Tests if ``self`` is an inexact zero. + Test if ``self`` is an inexact zero. EXAMPLES:: @@ -477,7 +476,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): """ Return the inverse of ``self``, as long as ``self`` is a unit. - If ``self`` is not a unit, raises a ``ValueError``. + If ``self`` is not a unit, raises a :exc:`ValueError`. EXAMPLES:: @@ -573,7 +572,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): """ Divide ``self`` by the uniformizer raised to the power ``n``. - Throws away the non-positive part of the series expansion. + Throws away the nonpositive part of the series expansion. The top digits will be garbage. If ``n`` is negative, left shifts by ``-n``. @@ -631,7 +630,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): """ Divide ``self`` by the uniformizer raised to the power ``n``. - Throws away the non-positive part of the series expansion. + Throws away the nonpositive part of the series expansion. The top digits will be garbage. If ``n`` is negative, left shifts by ``-n``. @@ -662,7 +661,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cpdef _neg_(self): """ - Returns ``-self``. + Return ``-self``. EXAMPLES:: @@ -687,7 +686,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): def __pow__(pAdicZZpXFMElement self, right, m): # m ignored """ - Computes ``self`` ^ ``right``. + Compute ``self`` ^ ``right``. EXAMPLES:: @@ -725,7 +724,6 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): sage: W. = R.ext(f) sage: type(W(0)^0) == type(W(0)) True - """ if not isinstance(right, Integer): right = Integer(right) @@ -819,9 +817,9 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): cpdef _div_(self, _right): """ - Returns the quotient of ``self`` by ``right``. + Return the quotient of ``self`` by ``right``. - If ``right`` is not a unit, raises a ``ValueError``. + If ``right`` is not a unit, raises a :exc:`ValueError`. EXAMPLES:: @@ -843,7 +841,6 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): sage: R. = Zq(8,2,'fixed-mod') sage: 1/(t+t^2) (t + 1) + t^2*2 - """ cdef pAdicZZpXFMElement right = _right if right.valuation_c() > 0: @@ -930,11 +927,9 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): INPUT: - - ``absprec`` -- an integer + - ``absprec`` -- integer - OUTPUT: - - A new element truncated modulo `\pi^{\mbox{absprec}}`. + OUTPUT: a new element truncated modulo `\pi^{\mbox{absprec}}` EXAMPLES:: @@ -1255,7 +1250,8 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): # def lift(self): # """ -# Returns an element of a number field defined by the same polynomial as self's parent that is congruent to self modulo an appropriate ideal. +# Returns an element of a number field defined by the same polynomial as +# ``self``'s parent that is congruent to self modulo an appropriate ideal. # Not currently implemented. # """ @@ -1308,7 +1304,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): INPUT: - - ``n`` -- integer (default ``None``); if given, returns the + - ``n`` -- integer (default: ``None``); if given, returns the corresponding entry in the expansion EXAMPLES:: @@ -1351,7 +1347,6 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): sage: L. = K.extension(a^2 - 3) sage: a.residue() 0 - """ if lift_mode == 'teichmuller': zero = self.parent()(0) @@ -1387,7 +1382,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): def teichmuller_expansion(self, n = None): r""" - Return a list `[a_0, a_1, \ldots, a_n]` such that + Return a list `[a_0, a_1, \ldots, a_n]` such that. - `a_i^q = a_i` - ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a @@ -1395,7 +1390,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): INPUT: - - ``n`` -- integer (default ``None``); f given, returns the corresponding + - ``n`` -- integer (default: ``None``); if given, returns the corresponding entry in the expansion EXAMPLES:: @@ -1520,8 +1515,8 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): # def multiplicative_order(self): # """ # Returns the multiplicative order of self, ie the smallest -# positive n so that there is an exact p-adic element congruent -# to self modulo self's precision that is an nth root of unity. +# positive `n` so that there is an exact `p`-adic element congruent +# to self modulo ``self``'s precision that is an `n`-th root of unity. # Note: unlike the case for Qp and Zp, it is possible to have # non-teichmuller elements with finite orders. This can happen @@ -1530,12 +1525,10 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): # INPUT: -# - self -- a p-adic element -# - prec -- an integer - -# OUTPUT: +# - ``self`` -- a `p`-adic element +# - ``prec`` -- integer -# - integer -- the multiplicative order of self +# OUTPUT: integer; the multiplicative order of self # """ # raise NotImplementedError diff --git a/src/sage/rings/padics/padic_ZZ_pX_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_element.pyx index 9ef966c1764..b2d6267503e 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_element.pyx @@ -55,7 +55,7 @@ big = two**128 + one cdef class pAdicZZpXElement(pAdicExtElement): def __init__(self, parent): """ - Initialization + Initialization. EXAMPLES:: @@ -68,14 +68,14 @@ cdef class pAdicZZpXElement(pAdicExtElement): cdef int _set_from_list(self, L) except -1: """ - Sets ``self`` from a list. + Set ``self`` from a list. The list can contain integers, ``IntegerMods``, rationals, or `p`-adic base elements INPUT: - - `L` -- a list. + - ``L`` -- list EXAMPLES:: @@ -97,17 +97,16 @@ cdef class pAdicZZpXElement(pAdicExtElement): cdef int _set_from_list_rel(self, L, long relprec) except -1: """ - Sets ``self`` from a list. + Set ``self`` from a list. The list can contain integers, ``IntegerMods``, rationals, or `p`-adic base elements INPUT: - - ``L`` -- a list. + - ``L`` -- list - - ``relprec`` -- an integer, capping the relative precision of - ``self``. + - ``relprec`` -- integer; capping the relative precision of ``self`` EXAMPLES:: @@ -133,11 +132,11 @@ cdef class pAdicZZpXElement(pAdicExtElement): INPUT: - - ``L`` -- a list of integers, ``IntegerMod``s, rationals, or `p`-adic - base elements. + - ``L`` -- list of integers, ``IntegerMod``s, rationals, or `p`-adic + base elements - - ``absprec`` -- an integer at which the absolute precision of the - result will be capped. + - ``absprec`` -- integer at which the absolute precision of the + result will be capped EXAMPLES:: @@ -148,7 +147,6 @@ cdef class pAdicZZpXElement(pAdicExtElement): 1 + 2*w + 3*w^2 + 4*w^3 + O(w^25) sage: W([5,10,15,20], absprec=16) # indirect doctest w^5 + 4*w^6 + w^7 + w^8 + 2*w^9 + 4*w^10 + 2*w^11 + 3*w^13 + 2*w^15 + O(w^16) - """ cdef ntl_ZZ_pContext_class ctx L, min_val, ctx = preprocess_list(self, L) @@ -167,12 +165,12 @@ cdef class pAdicZZpXElement(pAdicExtElement): INPUT: - - ``L`` -- a list of integers, ``IntegerMod``s, rationals, or `p`-adic - base elements. + - ``L`` -- list of integers, ``IntegerMod``s, rationals, or `p`-adic + base elements - - ``absprec`` -- an integer at which the absolute precision of the result will be capped. + - ``absprec`` -- integer at which the absolute precision of the result will be capped - - ``relprec`` -- an integer at which the relative precision of the result will be capped. + - ``relprec`` -- integer at which the relative precision of the result will be capped EXAMPLES:: @@ -200,16 +198,16 @@ cdef class pAdicZZpXElement(pAdicExtElement): cdef long _check_ZZ_pContext(self, ntl_ZZ_pContext_class ctx) except -1: """ - Checks that the given ``ntl_ZZ_pContext`` is actually a power + Check that the given ``ntl_ZZ_pContext`` is actually a power of the relevant prime. If so, returns the exponent. INPUT: - - ``ctx`` -- An ``ntl_ZZ_pContext_class`` + - ``ctx`` -- an ``ntl_ZZ_pContext_class`` OUTPUT: - - ``val`` -- If ``ctx`` is a context for `p^n`, returns `n`. + - ``val`` -- if ``ctx`` is a context for `p^n`, returns `n`. Otherwise, raises an error. EXAMPLES:: @@ -230,7 +228,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): cdef ext_p_list_precs(self, bint pos, long prec): """ - Returns a list giving a series representation of ``self``. + Return a list giving a series representation of ``self``. - The returned list will consist of: @@ -247,23 +245,23 @@ cdef class pAdicZZpXElement(pAdicExtElement): generator (in the unramified case). Note that zeros are truncated from the returned list, so you - must use the valuation() function to completely recover self. + must use the valuation() function to completely recover ``self``. INPUT: - - ``pos`` -- ``bint``. If ``True``, all integers will be in + - ``pos`` -- bint; if ``True``, all integers will be in the range `[0,p-1]`, otherwise they will be in the range - `[(1-p)/2, p/2]`. + `[(1-p)/2, p/2]` - - ``prec`` -- How many terms to return in the list. This is + - ``prec`` -- how many terms to return in the list. This is important since shifting in the Eisenstein case can introduce random high order bits. Thus the process would not otherwise necessarily terminate at the right point. OUTPUT: - - ``L`` -- A list of integers or list of lists giving the - series expansion of ``self``. + - ``L`` -- list of integers or list of lists giving the + series expansion of ``self`` EXAMPLES:: @@ -494,7 +492,6 @@ cdef class pAdicZZpXElement(pAdicExtElement): sage: L. = F.ext(x^2 - 2) sage: L(0, 20).trace() O(2^10) - """ if base is not None: if base is self.parent(): @@ -531,7 +528,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): def _prime_pow(self): """ - Provides access to ``self's`` ``prime_pow``. + Provides access to ``self``'s ``prime_pow``. EXAMPLES:: @@ -546,7 +543,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): cdef int _pshift_self(self, long shift) except -1: """ - Multiplies this element by ``p^shift``. + Multiply this element by ``p^shift``. TESTS: @@ -578,7 +575,7 @@ def _test_preprocess_list(R, L): - ``R`` -- a `p`-adic extension ring - - ``L`` -- a list of rationals, integers, ints, longs, + - ``L`` -- list of rationals, integers, ints, longs, ``ntl_ZZ_ps``, ``ntl_ZZs``, ``IntegerMods`` or `p`-adic base elements @@ -650,7 +647,7 @@ cdef preprocess_list(pAdicZZpXElement elt, L): ctx = ntl_ZZ_pContext(py_tmp) else: # integers, rationals and things with finite precision - # note that min_val will be non-positive since things with finite precision return non-positive valuation from get_val_prec + # note that min_val will be nonpositive since things with finite precision return nonpositive valuation from get_val_prec py_tmp = ntl_ZZ.__new__(ntl_ZZ) py_tmp.x = elt.prime_pow.pow_ZZ_tmp(mpz_get_ui(((min_aprec - min_val)).value))[0] ctx = ntl_ZZ_pContext(py_tmp) @@ -707,11 +704,9 @@ def _find_val_aprec_test(R, L): INPUT: - ``R`` -- a `p`-adic extension - - ``L`` -- a list of integers, rationals, ``IntegerMods``, etc. - - OUTPUT: + - ``L`` -- list of integers, rationals, ``IntegerMods``, etc. - - ``min_val`` -- the minimum valuation of any element in the list + OUTPUT: ``min_val`` -- the minimum valuation of any element in the list - ``min_aprec`` -- the minimum absolute precision of any element in the list; if infinite, a predefined constant ``big`` is @@ -749,9 +744,9 @@ cdef find_val_aprec(PowComputer_ext pp, L): INPUT: - ``pp`` -- a PowComputer_ext for the element that this list is - being initialized into. + being initialized into - - ``L`` -- a list of integers, rationals, ``IntegerMods``, etc. + - ``L`` -- list of integers, rationals, ``IntegerMods``, etc. See the documentation for :func:`_find_val_aprec_test` for more details. """ @@ -784,7 +779,7 @@ def _test_get_val_prec(R, a): - ``R`` -- a `p`-adic extension ring to provide a ``PowComputer_ext`` - - ``a`` -- a rational, integer, int, long, ``ntl_ZZ_p``, + - ``a`` -- rational, integer, int, long, ``ntl_ZZ_p``, ``ntl_ZZ``, ``IntegerMod`` or `p`-adic base element OUTPUT: @@ -856,7 +851,7 @@ cdef get_val_prec(PowComputer_ext pp, a): - ``pp`` -- a ``PowComputer_ext`` - - ``a`` -- a rational, integer, int, long, ``ntl_ZZ_p``, + - ``a`` -- rational, integer, int, long, ``ntl_ZZ_p``, ``ntl_ZZ``, ``IntegerMod`` or `p`-adic base element See :func:`_test_get_val_prec` for more details. diff --git a/src/sage/rings/padics/padic_base_generic.py b/src/sage/rings/padics/padic_base_generic.py index 792e99996c5..8001d366b23 100644 --- a/src/sage/rings/padics/padic_base_generic.py +++ b/src/sage/rings/padics/padic_base_generic.py @@ -36,7 +36,7 @@ class pAdicBaseGeneric(pAdicGeneric): def __init__(self, p, prec, print_mode, names, element_class): """ - Initialization + Initialization. TESTS:: @@ -88,7 +88,7 @@ def __init__(self, p, prec, print_mode, names, element_class): def _repr_(self, do_latex=False): r""" - Returns a print representation of this p-adic ring or field. + Return a print representation of this `p`-adic ring or field. EXAMPLES:: @@ -143,9 +143,9 @@ def _repr_(self, do_latex=False): def exact_field(self): """ - Returns the rational field. + Return the rational field. - For compatibility with extensions of p-adics. + For compatibility with extensions of `p`-adics. EXAMPLES:: @@ -157,7 +157,7 @@ def exact_field(self): def exact_ring(self): """ - Returns the integer ring. + Return the integer ring. EXAMPLES:: @@ -169,7 +169,8 @@ def exact_ring(self): def is_isomorphic(self, ring): r""" - Returns whether ``self`` and ``ring`` are isomorphic, i.e. whether ``ring`` is an implementation of `\ZZ_p` for the same prime as ``self``. + Return whether ``self`` and ``ring`` are isomorphic, i.e. whether + ``ring`` is an implementation of `\ZZ_p` for the same prime as ``self``. INPUT: @@ -177,9 +178,8 @@ def is_isomorphic(self, ring): - ``ring`` -- a ring - OUTPUT: - - - ``boolean`` -- whether ``ring`` is an implementation of \ZZ_p` for the same prime as ``self``. + OUTPUT: ``boolean`` -- whether ``ring`` is an implementation of \ZZ_p` + for the same prime as ``self`` EXAMPLES:: @@ -190,7 +190,7 @@ def is_isomorphic(self, ring): def gen(self, n=0): """ - Returns the ``nth`` generator of this extension. For base + Return the `n`-th generator of this extension. For base rings/fields, we consider the generator to be the prime. EXAMPLES:: @@ -204,13 +204,14 @@ def gen(self, n=0): def modulus(self, exact=False): r""" - Returns the polynomial defining this extension. + Return the polynomial defining this extension. - For compatibility with extension fields; we define the modulus to be x-1. + For compatibility with extension fields; we define the modulus to be `x-1`. INPUT: - - ``exact`` -- boolean (default ``False``), whether to return a polynomial with integer entries. + - ``exact`` -- boolean (default: ``False``); whether to return a + polynomial with integer entries EXAMPLES:: @@ -221,7 +222,7 @@ def modulus(self, exact=False): def absolute_discriminant(self): """ - Returns the absolute discriminant of this `p`-adic ring + Return the absolute discriminant of this `p`-adic ring. EXAMPLES:: @@ -232,7 +233,7 @@ def absolute_discriminant(self): def discriminant(self, K=None): """ - Returns the discriminant of this `p`-adic ring over ``K`` + Return the discriminant of this `p`-adic ring over ``K``. INPUT: @@ -242,8 +243,8 @@ def discriminant(self, K=None): OUTPUT: - - integer -- the discriminant of this ring over ``K`` (or the - absolute discriminant if ``K`` is ``None``) + integer; the discriminant of this ring over ``K`` (or the absolute + discriminant if ``K`` is ``None``) EXAMPLES:: @@ -257,7 +258,7 @@ def discriminant(self, K=None): def is_abelian(self): """ - Returns whether the Galois group is abelian, i.e. ``True``. + Return whether the Galois group is abelian, i.e. ``True``. #should this be automorphism group? EXAMPLES:: @@ -269,7 +270,7 @@ def is_abelian(self): def is_normal(self): """ - Returns whether or not this is a normal extension, i.e. ``True``. + Return whether or not this is a normal extension, i.e. ``True``. EXAMPLES:: @@ -280,7 +281,7 @@ def is_normal(self): def uniformizer(self): """ - Returns a uniformizer for this ring. + Return a uniformizer for this ring. EXAMPLES:: @@ -292,7 +293,7 @@ def uniformizer(self): def uniformizer_pow(self, n): """ - Returns the ``nth`` power of the uniformizer of ``self`` (as + Return the `n`-th power of the uniformizer of ``self`` (as an element of ``self``). EXAMPLES:: @@ -307,7 +308,7 @@ def uniformizer_pow(self, n): def _uniformizer_print(self): """ - Returns how the uniformizer is supposed to print. + Return how the uniformizer is supposed to print. EXAMPLES:: @@ -318,7 +319,7 @@ def _uniformizer_print(self): def has_pth_root(self): r""" - Returns whether or not `\ZZ_p` has a primitive `p^{th}` + Return whether or not `\ZZ_p` has a primitive `p`-th root of unity. EXAMPLES:: @@ -332,19 +333,18 @@ def has_pth_root(self): def has_root_of_unity(self, n): r""" - Returns whether or not `\ZZ_p` has a primitive `n^{th}` + Return whether or not `\ZZ_p` has a primitive `n`-th root of unity. INPUT: - ``self`` -- a `p`-adic ring - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: - - ``boolean`` -- whether ``self`` has primitive `n^{th}` root - of unity + boolean; whether ``self`` has primitive `n`-th root of unity EXAMPLES:: @@ -361,19 +361,18 @@ def has_root_of_unity(self, n): def zeta(self, n=None): r""" - Returns a generator of the group of roots of unity. + Return a generator of the group of roots of unity. INPUT: - ``self`` -- a `p`-adic ring - - ``n`` -- an integer or ``None`` (default: ``None``) + - ``n`` -- integer or ``None`` (default: ``None``) OUTPUT: - - ``element`` -- a generator of the `n^{th}` roots of unity, - or a generator of the full group of roots of unity if ``n`` - is ``None`` + ``element``; a generator of the `n`-th roots of unity, or a generator + of the full group of roots of unity if ``n`` is ``None`` EXAMPLES:: @@ -394,7 +393,7 @@ def zeta(self, n=None): def zeta_order(self): """ - Returns the order of the group of roots of unity. + Return the order of the group of roots of unity. EXAMPLES:: @@ -420,7 +419,7 @@ def plot(self, max_points=2500, **args): INPUT: - ``max_points`` -- the maximum number or points to plot, - which controls the depth of recursion (default 2500) + which controls the depth of recursion (default: 2500) - ``**args`` -- color, size, etc. that are passed to the underlying point graphics objects diff --git a/src/sage/rings/padics/padic_base_leaves.py b/src/sage/rings/padics/padic_base_leaves.py index c89cb6a87ed..64be9291c49 100644 --- a/src/sage/rings/padics/padic_base_leaves.py +++ b/src/sage/rings/padics/padic_base_leaves.py @@ -98,7 +98,7 @@ sage: type((a * b) / 5^3) -The fixed modulus type is the leanest of the p-adic rings: it is +The fixed modulus type is the leanest of the `p`-adic rings: it is basically just a wrapper around `\ZZ / p^n \ZZ` providing a unified interface with the rest of the `p`-adics. This is the type you should use if your primary interest is in speed (though @@ -219,8 +219,8 @@ def __init__(self, p, prec, print_mode, names): - ``p`` -- prime - ``prec`` -- precision cap - - ``print_mode`` -- dictionary with print options. - - ``names`` -- how to print the prime. + - ``print_mode`` -- dictionary with print options + - ``names`` -- how to print the prime EXAMPLES:: @@ -317,8 +317,8 @@ def __init__(self, p, prec, print_mode, names): - ``p`` -- prime - ``prec`` -- precision cap - - ``print_mode`` -- dictionary with print options. - - ``names`` -- how to print the prime. + - ``print_mode`` -- dictionary with print options + - ``names`` -- how to print the prime EXAMPLES:: @@ -404,6 +404,7 @@ def _convert_map_from_(self, R): from sage.rings.padics.padic_generic import ResidueLiftingMap return ResidueLiftingMap._create_(R, self) + class pAdicRingFloatingPoint(pAdicRingBaseGeneric, pAdicFloatingPointRingGeneric): r""" An implementation of the `p`-adic integers with floating point @@ -417,8 +418,8 @@ def __init__(self, p, prec, print_mode, names): - ``p`` -- prime - ``prec`` -- precision cap - - ``print_mode`` -- dictionary with print options. - - ``names`` -- how to print the prime. + - ``print_mode`` -- dictionary with print options + - ``names`` -- how to print the prime EXAMPLES:: @@ -499,20 +500,21 @@ def _convert_map_from_(self, R): from sage.rings.padics.padic_generic import ResidueLiftingMap return ResidueLiftingMap._create_(R, self) + class pAdicRingFixedMod(pAdicRingBaseGeneric, pAdicFixedModRingGeneric): r""" An implementation of the `p`-adic integers using fixed modulus. """ def __init__(self, p, prec, print_mode, names): """ - Initialization + Initialization. INPUT: - ``p`` -- prime - ``prec`` -- precision cap - - ``print_mode`` -- dictionary with print options. - - ``names`` -- how to print the prime. + - ``print_mode`` -- dictionary with print options + - ``names`` -- how to print the prime EXAMPLES:: @@ -605,6 +607,7 @@ def _convert_map_from_(self, R): from sage.rings.padics.padic_generic import ResidueLiftingMap return ResidueLiftingMap._create_(R, self) + class pAdicFieldCappedRelative(pAdicFieldBaseGeneric, pAdicCappedRelativeFieldGeneric): r""" An implementation of `p`-adic fields with capped relative precision. @@ -613,7 +616,6 @@ class pAdicFieldCappedRelative(pAdicFieldBaseGeneric, pAdicCappedRelativeFieldGe sage: K = Qp(17, 1000000) # indirect doctest sage: K = Qp(101) # indirect doctest - """ def __init__(self, p, prec, print_mode, names): @@ -624,8 +626,8 @@ def __init__(self, p, prec, print_mode, names): - ``p`` -- prime - ``prec`` -- precision cap - - ``print_mode`` -- dictionary with print options. - - ``names`` -- how to print the prime. + - ``print_mode`` -- dictionary with print options + - ``names`` -- how to print the prime EXAMPLES:: @@ -649,7 +651,7 @@ def __init__(self, p, prec, print_mode, names): sage: R = Qp(3, 2) sage: TestSuite(R).run(elements=[R.random_element() for i in range(3^9)], # long time, needs sage.geometry.polyhedron - ....: skip="_test_metric_function") + ....: skip='_test_metric_function') sage: R._test_metric_function(elements=[R.random_element() for i in range(3^3)]) sage: R = Qp(next_prime(10^60)) @@ -685,7 +687,6 @@ def _coerce_map_from_(self, R): True sage: K.has_coerce_map_from(Zp(17,40)) True - """ #if isinstance(R, pAdicRingRelaxed) or isinstance(R, pAdicFieldRelaxed) and R.prime() == self.prime(): # return True @@ -742,6 +743,7 @@ def random_element(self, algorithm='default'): else: raise NotImplementedError("Don't know %s algorithm" % algorithm) + class pAdicFieldFloatingPoint(pAdicFieldBaseGeneric, pAdicFloatingPointFieldGeneric): r""" An implementation of the `p`-adic rationals with floating point @@ -755,8 +757,8 @@ def __init__(self, p, prec, print_mode, names): - ``p`` -- prime - ``prec`` -- precision cap - - ``print_mode`` -- dictionary with print options. - - ``names`` -- how to print the prime. + - ``print_mode`` -- dictionary with print options + - ``names`` -- how to print the prime EXAMPLES:: @@ -843,6 +845,7 @@ def _convert_map_from_(self, R): # Lattice precision ################### + class pAdicRingLattice(pAdicLatticeGeneric, pAdicRingBaseGeneric): """ An implementation of the `p`-adic integers with lattice precision. @@ -941,7 +944,7 @@ def random_element(self, prec=None): INPUT: - - ``prec`` -- an integer or ``None`` (the default): the + - ``prec`` -- integer or ``None`` (default); the absolute precision of the generated random element EXAMPLES:: @@ -960,8 +963,7 @@ def random_element(self, prec=None): prec = self._prec_cap_absolute x = ZZ.random_element(p**prec) relcap = x.valuation(p) + self._prec_cap_relative - if relcap < prec: - prec = relcap + prec = min(relcap, prec) return self._element_class(self, x, prec=prec) else: if prec is None: @@ -974,6 +976,7 @@ def random_element(self, prec=None): x += p**cap * ZZ.random_element(p**v) return self._element_class(self, x, prec=prec) + class pAdicFieldLattice(pAdicLatticeGeneric, pAdicFieldBaseGeneric): """ An implementation of the `p`-adic numbers with lattice precision. @@ -1072,10 +1075,10 @@ def random_element(self, prec=None, integral=False): INPUT: - - ``prec`` -- an integer or ``None`` (the default): the + - ``prec`` -- integer or ``None`` (default); the absolute precision of the generated random element - - ``integral`` -- a boolean (default: ``False``); if ``True``, + - ``integral`` -- boolean (default: ``False``); if ``True``, return an element in the ring of integers EXAMPLES:: @@ -1107,13 +1110,13 @@ def random_element(self, prec=None, integral=False): p = self.prime() x = ZZ.random_element(p**prec) relcap = x.valuation(p) + self._prec_cap_relative - if relcap < prec: - prec = relcap + prec = min(relcap, prec) return self._element_class(self, x*(p**val), prec=prec) # Relaxed ######### + class pAdicRingRelaxed(pAdicRelaxedGeneric, pAdicRingBaseGeneric): r""" An implementation of relaxed arithmetics over `\ZZ_p`. @@ -1152,6 +1155,7 @@ def __init__(self, p, prec, print_mode, names): self._element_class_module = padic_relaxed_element self._element_class_prefix = "pAdicRelaxedElement_" + class pAdicFieldRelaxed(pAdicRelaxedGeneric, pAdicFieldBaseGeneric): r""" An implementation of relaxed arithmetics over `\QQ_p`. diff --git a/src/sage/rings/padics/padic_capped_absolute_element.pyx b/src/sage/rings/padics/padic_capped_absolute_element.pyx index d21b2c18acb..84839c95388 100644 --- a/src/sage/rings/padics/padic_capped_absolute_element.pyx +++ b/src/sage/rings/padics/padic_capped_absolute_element.pyx @@ -32,7 +32,7 @@ cdef extern from "transcendantal.c": cdef class PowComputer_(PowComputer_base): """ - A PowComputer for a capped-absolute padic ring. + A PowComputer for a capped-absolute `p`-adic ring. """ def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field): """ @@ -51,7 +51,7 @@ cdef class PowComputer_(PowComputer_base): cdef class pAdicCappedAbsoluteElement(CAElement): """ - Constructs new element with given parent and value. + Construct new element with given parent and value. INPUT: @@ -126,7 +126,7 @@ cdef class pAdicCappedAbsoluteElement(CAElement): cdef pari_gen _to_gen(self): """ - Converts this element to an equivalent pari element. + Convert this element to an equivalent pari element. EXAMPLES:: @@ -156,7 +156,7 @@ cdef class pAdicCappedAbsoluteElement(CAElement): def _integer_(self, Z=None): r""" - Converts this element to an integer. + Convert this element to an integer. TESTS:: @@ -173,12 +173,14 @@ cdef class pAdicCappedAbsoluteElement(CAElement): INPUT: - - ``absprec`` -- a non-negative integer (default: 1) + - ``absprec`` -- nonnegative integer (default: 1) - - ``field`` -- boolean (default ``None``). Whether to return an element of GF(p) or Zmod(p). + - ``field`` -- boolean (default: ``None``); whether to return an + element of GF(p) or Zmod(p) - - ``check_prec`` -- boolean (default ``True``). Whether to raise an error if this - element has insufficient precision to determine the reduction. + - ``check_prec`` -- boolean (default: ``True``); whether to raise an + error if this element has insufficient precision to determine the + reduction OUTPUT: @@ -231,7 +233,6 @@ cdef class pAdicCappedAbsoluteElement(CAElement): .. SEEALSO:: :meth:`_mod_` - """ if not isinstance(absprec, Integer): absprec = Integer(absprec) @@ -260,7 +261,7 @@ cdef class pAdicCappedAbsoluteElement(CAElement): OUTPUT: - The multiplicative order of self. This is the minimum multiplicative + The multiplicative order of ``self``. This is the minimum multiplicative order of all elements of `\ZZ_p` lifting ``self`` to infinite precision. @@ -306,19 +307,19 @@ cdef class pAdicCappedAbsoluteElement(CAElement): def _log_binary_splitting(self, aprec, mina=0): r""" - Return ``\log(self)`` for ``self`` equal to 1 in the residue field + Return ``\log(self)`` for ``self`` equal to 1 in the residue field. This is a helper method for :meth:`log`. It uses a fast binary splitting algorithm. INPUT: - - ``aprec`` -- an integer, the precision to which the result is + - ``aprec`` -- integer; the precision to which the result is correct. ``aprec`` must not exceed the precision cap of the ring over which this element is defined. - - ``mina`` -- an integer (default: 0), the series will check `n` up to + - ``mina`` -- integer (default: 0); the series will check `n` up to this valuation (and beyond) to see if they can contribute to the - series. + series .. NOTE:: @@ -384,13 +385,13 @@ cdef class pAdicCappedAbsoluteElement(CAElement): def _exp_binary_splitting(self, aprec): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential .. NOTE:: @@ -422,9 +423,8 @@ cdef class pAdicCappedAbsoluteElement(CAElement): sage: R = Zp(7,5) sage: x = R(7) - sage: x.exp(algorithm="binary_splitting") # indirect doctest + sage: x.exp(algorithm='binary_splitting') # indirect doctest 1 + 7 + 4*7^2 + 2*7^3 + O(7^5) - """ cdef unsigned long p cdef unsigned long prec = aprec @@ -444,16 +444,16 @@ cdef class pAdicCappedAbsoluteElement(CAElement): def _exp_newton(self, aprec, log_algorithm=None): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential - - ``log_algorithm`` (default: None) -- the algorithm used for + - ``log_algorithm`` -- (default: ``None``) the algorithm used for computing the logarithm. This attribute is passed to the log method. See :meth:`log` for more details about the possible algorithms. @@ -480,7 +480,7 @@ cdef class pAdicCappedAbsoluteElement(CAElement): sage: # needs sage.libs.ntl sage: R. = Zq(7^2,5) sage: x = R(7*w) - sage: x.exp(algorithm="newton") # indirect doctest + sage: x.exp(algorithm='newton') # indirect doctest 1 + w*7 + (4*w + 2)*7^2 + (w + 6)*7^3 + 5*7^4 + O(7^5) """ cdef unsigned long p diff --git a/src/sage/rings/padics/padic_capped_relative_element.pyx b/src/sage/rings/padics/padic_capped_relative_element.pyx index 701c9575417..5c7e0091ffe 100644 --- a/src/sage/rings/padics/padic_capped_relative_element.pyx +++ b/src/sage/rings/padics/padic_capped_relative_element.pyx @@ -37,7 +37,7 @@ cdef extern from "transcendantal.c": cdef class PowComputer_(PowComputer_base): """ - A PowComputer for a capped-relative padic ring or field. + A PowComputer for a capped-relative `p`-adic ring or field. """ def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field): """ @@ -56,7 +56,7 @@ cdef class PowComputer_(PowComputer_base): cdef class pAdicCappedRelativeElement(CRElement): """ - Constructs new element with given parent and value. + Construct new element with given parent and value. INPUT: @@ -140,8 +140,7 @@ cdef class pAdicCappedRelativeElement(CRElement): sage: R(pari(R(0,5))) O(5^5) - .. TODO:: doctests for converting from other types of p-adic rings - + .. TODO:: doctests for converting from other types of `p`-adic rings """ def lift(self): r""" @@ -256,12 +255,12 @@ cdef class pAdicCappedRelativeElement(CRElement): INPUT: - - ``absprec`` -- a non-negative integer (default: ``1``) + - ``absprec`` -- nonnegative integer (default: 1) - - ``field`` -- boolean (default ``None``); whether to return an element + - ``field`` -- boolean (default: ``None``); whether to return an element of `\GF{p}` or `\ZZ / p\ZZ` - - ``check_prec`` -- boolean (default ``True``); whether to raise + - ``check_prec`` -- boolean (default: ``True``); whether to raise an error if this element has insufficient precision to determine the reduction @@ -303,7 +302,7 @@ cdef class pAdicCappedRelativeElement(CRElement): sage: b.residue() Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue TESTS:: @@ -328,7 +327,6 @@ cdef class pAdicCappedRelativeElement(CRElement): .. SEEALSO:: :meth:`_mod_` - """ cdef Integer selfvalue, modulus cdef long aprec @@ -339,7 +337,7 @@ cdef class pAdicCappedRelativeElement(CRElement): elif absprec < 0: raise ValueError("cannot reduce modulo a negative power of p") if self.ordp < 0: - raise ValueError("element must have non-negative valuation in order to compute residue") + raise ValueError("element must have nonnegative valuation in order to compute residue") if field is None: field = (absprec == 1) elif field and absprec != 1: @@ -368,10 +366,10 @@ cdef class pAdicCappedRelativeElement(CRElement): INPUT: - - ``aprec`` -- an integer, the precision to which the result is + - ``aprec`` -- integer; the precision to which the result is correct; ``aprec`` must not exceed the precision cap of the ring over which this element is defined - - ``mina`` -- an integer (default: 0), the series will check `n` up to + - ``mina`` -- integer (default: 0); the series will check `n` up to this valuation (and beyond) to see if they can contribute to the series @@ -440,13 +438,13 @@ cdef class pAdicCappedRelativeElement(CRElement): def _exp_binary_splitting(self, aprec): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential .. NOTE:: @@ -478,9 +476,8 @@ cdef class pAdicCappedRelativeElement(CRElement): sage: R = Zp(7,5) sage: x = R(7) - sage: x.exp(algorithm="binary_splitting") # indirect doctest + sage: x.exp(algorithm='binary_splitting') # indirect doctest 1 + 7 + 4*7^2 + 2*7^3 + O(7^5) - """ cdef unsigned long p cdef unsigned long prec = aprec @@ -508,13 +505,13 @@ cdef class pAdicCappedRelativeElement(CRElement): INPUT: - - ``aprec`` -- an integer; the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential - ``log_algorithm`` -- (default: ``None``) the algorithm used for computing the logarithm; this attribute is passed to the :meth:`log` - method; see :meth:`log` for more details about the possible - algorithms + method. See :meth:`log` for more details about the possible + algorithms. .. NOTE:: @@ -538,7 +535,7 @@ cdef class pAdicCappedRelativeElement(CRElement): sage: # needs sage.libs.ntl sage: R. = Zq(7^2,5) sage: x = R(7*w) - sage: x.exp(algorithm="newton") # indirect doctest + sage: x.exp(algorithm='newton') # indirect doctest 1 + w*7 + (4*w + 2)*7^2 + (w + 6)*7^3 + 5*7^4 + O(7^5) """ cdef unsigned long p @@ -586,8 +583,8 @@ def base_p_list(Integer n, bint pos, PowComputer_class prime_pow): - ``n`` -- a positive :class:`Integer` - - ``pos`` -- a boolean; if ``True``, then returns the standard base `p` - expansion, otherwise the digits lie in the range `-p/2` to `p/2`. + - ``pos`` -- boolean; if ``True``, then returns the standard base `p` + expansion, otherwise the digits lie in the range `-p/2` to `p/2` - ``prime_pow`` -- a :class:`PowComputer` giving the prime diff --git a/src/sage/rings/padics/padic_ext_element.pyx b/src/sage/rings/padics/padic_ext_element.pyx index 2327c8085a0..417ead46ad4 100644 --- a/src/sage/rings/padics/padic_ext_element.pyx +++ b/src/sage/rings/padics/padic_ext_element.pyx @@ -34,7 +34,7 @@ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p cdef class pAdicExtElement(pAdicGenericElement): cdef int _set_from_list(self, L) except -1: """ - Sets self from a list. + Set ``self`` from a list. The list should either be uniform in type, or all of the entries should be coercible to integers. If any of the entries in ``L`` @@ -42,7 +42,7 @@ cdef class pAdicExtElement(pAdicGenericElement): INPUT: - - ``L`` -- a list + - ``L`` -- list """ raise NotImplementedError @@ -57,8 +57,8 @@ cdef class pAdicExtElement(pAdicGenericElement): cdef int _set_from_ZZX(self, ZZX_c poly) except -1: """ - Sets from a ZZX_c, choosing how to handle based on the - precision type of self.parent(). + Set from a ZZX_c, choosing how to handle based on the + precision type of ``self.parent()``. Fixed modulus elements should override this function. @@ -109,7 +109,7 @@ cdef class pAdicExtElement(pAdicGenericElement): cdef int _set_from_ZZ_pX(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx) except -1: """ - Sets self from a ZZ_pX defined with context ctx. + Set ``self`` from a ZZ_pX defined with context ctx. This function should be overridden for fixed modulus elements. @@ -194,7 +194,7 @@ cdef class pAdicExtElement(pAdicGenericElement): cdef int _set_from_ZZ_pE_both(self, ZZ_pE_c* poly, ntl_ZZ_pEContext_class ctx, long absprec, long relprec) except -1: """ - Sets from a ZZ_pE_c with both absolute and relative precision bounded. + Set from a ZZ_pE_c with both absolute and relative precision bounded. Capped absolute and capped relative elements should override this function. @@ -208,7 +208,7 @@ cdef class pAdicExtElement(pAdicGenericElement): cdef int _set_from_ZZ_pEX(self, ZZ_pEX_c* poly, ntl_ZZ_pEContext_class ctx) except -1: """ - Sets self from a ZZ_pEX_c. + Set ``self`` from a ZZ_pEX_c. Fixed modulus elements should override this function. @@ -245,7 +245,7 @@ cdef class pAdicExtElement(pAdicGenericElement): cdef int _set_from_ZZ_pEX_both(self, ZZ_pEX_c* poly, ntl_ZZ_pEContext_class ctx, long absprec, long relprec) except -1: """ - Sets from a ZZ_pEX_c with both absolute and relative precision bounded. + Set from a ZZ_pEX_c with both absolute and relative precision bounded. Capped absolute and capped relative elements should override this function. @@ -274,7 +274,7 @@ cdef class pAdicExtElement(pAdicGenericElement): Return the constant term of a polynomial representing ``self``. This function is mainly for troubleshooting, and the meaning - of the return value will depend on whether self is capped + of the return value will depend on whether ``self`` is capped relative or otherwise. EXAMPLES:: @@ -365,7 +365,7 @@ cdef class pAdicExtElement(pAdicGenericElement): sage: c.frobenius().frobenius() (a + 1)*7^-1 + O(7^3) - An error will be raised if the parent of self is a ramified extension:: + An error will be raised if the parent of ``self`` is a ramified extension:: sage: x = polygen(ZZ, 'x') sage: K. = Qp(5).extension(x^2 - 5) @@ -397,14 +397,13 @@ cdef class pAdicExtElement(pAdicGenericElement): INPUT: - - ``p`` -- a prime, which is compared with the parent of this element. + - ``p`` -- a prime, which is compared with the parent of this element EXAMPLES:: sage: K. = Qq(7^3,4) sage: a._is_base_elt(5) False - """ return False @@ -414,18 +413,16 @@ cdef class pAdicExtElement(pAdicGenericElement): INPUT: - - ``absprec`` -- a non-negative integer (default: ``1``) + - ``absprec`` -- nonnegative integer (default: 1) - - ``field`` -- boolean (default ``None``). For precision 1, whether to return + - ``field`` -- boolean (default: ``None``); for precision 1, whether to return an element of the residue field or a residue ring. Currently unused. - - ``check_prec`` -- boolean (default ``True``). Whether to raise an error if this + - ``check_prec`` -- boolean (default: ``True``); whether to raise an error if this element has insufficient precision to determine the reduction. Errors are never raised for fixed-mod or floating-point types. - OUTPUT: - - This element reduced modulo `\pi^\mathrm{absprec}`. + OUTPUT: this element reduced modulo `\pi^\mathrm{absprec}` If ``absprec`` is zero, then as an element of `\ZZ/(1)`. @@ -475,7 +472,7 @@ cdef class pAdicExtElement(pAdicGenericElement): sage: (a/3).residue(0) Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue sage: # needs sage.libs.flint sage: R = ZpFM(3,5) @@ -495,7 +492,7 @@ cdef class pAdicExtElement(pAdicGenericElement): if absprec < 0: raise ValueError("cannot reduce modulo a negative power of the uniformizer") if self.valuation() < 0: - raise ValueError("element must have non-negative valuation in order to compute residue") + raise ValueError("element must have nonnegative valuation in order to compute residue") R = self.parent() if check_prec and (R.is_fixed_mod() or R.is_floating_point()): check_prec = False diff --git a/src/sage/rings/padics/padic_extension_generic.py b/src/sage/rings/padics/padic_extension_generic.py index 42d58e9d229..e3e97906be2 100644 --- a/src/sage/rings/padics/padic_extension_generic.py +++ b/src/sage/rings/padics/padic_extension_generic.py @@ -41,10 +41,11 @@ from sage.misc.cachefunc import cached_method from sage.structure.richcmp import rich_to_bool + class pAdicExtensionGeneric(pAdicGeneric): def __init__(self, poly, prec, print_mode, names, element_class): """ - Initialization + Initialization. EXAMPLES:: @@ -313,14 +314,14 @@ def __hash__(self): def defining_polynomial(self, var=None, exact=False): """ - Returns the polynomial defining this extension. + Return the polynomial defining this extension. INPUT: - - ``var`` -- string (default: ``'x'``), the name of the variable + - ``var`` -- string (default: ``'x'``); the name of the variable - - ``exact`` -- boolean (default ``False``), whether to return the underlying exact - defining polynomial rather than the one with coefficients in the base ring. + - ``exact`` -- boolean (default: ``False``); whether to return the underlying exact + defining polynomial rather than the one with coefficients in the base ring EXAMPLES:: @@ -377,7 +378,7 @@ def exact_ring(self): """ Return the order with the same defining polynomial. - Will raise a :class:`ValueError` if the coefficients of the defining + Will raise a :exc:`ValueError` if the coefficients of the defining polynomial are not integral. EXAMPLES:: @@ -402,12 +403,12 @@ def exact_ring(self): def modulus(self, exact=False): r""" - Returns the polynomial defining this extension. + Return the polynomial defining this extension. INPUT: - - ``exact`` -- boolean (default ``False``), whether to return the underlying exact - defining polynomial rather than the one with coefficients in the base ring. + - ``exact`` -- boolean (default: ``False``); whether to return the underlying exact + defining polynomial rather than the one with coefficients in the base ring EXAMPLES:: @@ -429,7 +430,7 @@ def modulus(self, exact=False): def ground_ring(self): """ - Returns the ring of which this ring is an extension. + Return the ring of which this ring is an extension. EXAMPLES:: @@ -444,10 +445,10 @@ def ground_ring(self): def ground_ring_of_tower(self): """ - Returns the p-adic base ring of which this is ultimately an + Return the `p`-adic base ring of which this is ultimately an extension. - Currently this function is identical to ground_ring(), since + Currently this function is identical to ``ground_ring()``, since relative extensions have not yet been implemented. EXAMPLES:: @@ -465,7 +466,7 @@ def ground_ring_of_tower(self): def polynomial_ring(self): """ - Returns the polynomial ring of which this is a quotient. + Return the polynomial ring of which this is a quotient. EXAMPLES:: @@ -492,7 +493,7 @@ def polynomial_ring(self): def construction(self, forbid_frac_field=False): """ - Returns the functorial construction of this ring, namely, + Return the functorial construction of this ring, namely, the algebraic extension of the base ring defined by the given polynomial. @@ -579,7 +580,7 @@ def free_module(self, base=None, basis=None, map=True): - ``basis`` -- a basis for this ring/field over the base - - ``map`` -- boolean (default ``True``), whether to return + - ``map`` -- boolean (default: ``True``); whether to return `R`-linear maps to and from `V` OUTPUT: @@ -668,9 +669,11 @@ def free_module(self, base=None, basis=None, map=True): # an object in two free module categories with # different base rings. So for now we # just stick with Map. + + class pAdicModuleIsomorphism(Map): r""" - A base class for various isomorphisms between p-adic rings/fields and free modules + A base class for various isomorphisms between `p`-adic rings/fields and free modules. EXAMPLES:: @@ -728,9 +731,10 @@ def _richcmp_(self, other, op): else: return rich_to_bool(op, 1) + class MapFreeModuleToOneStep(pAdicModuleIsomorphism): """ - The isomorphism from the underlying module of a one-step p-adic extension + The isomorphism from the underlying module of a one-step `p`-adic extension to the extension. EXAMPLES:: @@ -763,9 +767,10 @@ def _call_with_args(self, x, args=(), kwds={}): """ return self.codomain()(list(x), *args, **kwds) + class MapOneStepToFreeModule(pAdicModuleIsomorphism): """ - The isomorphism from a one-step p-adic extension to its underlying free module + The isomorphism from a one-step `p`-adic extension to its underlying free module. EXAMPLES:: @@ -787,9 +792,10 @@ def _call_(self, x): """ return self.codomain()(x._polynomial_list(pad=True)) + class MapFreeModuleToTwoStep(pAdicModuleIsomorphism): """ - The isomorphism from the underlying module of a two-step p-adic extension + The isomorphism from the underlying module of a two-step `p`-adic extension to the extension. EXAMPLES:: @@ -834,9 +840,10 @@ def _call_with_args(self, x, args=(), kwds={}): """ return self.codomain()(self._call_(x), *args, **kwds) + class MapTwoStepToFreeModule(pAdicModuleIsomorphism): """ - The isomorphism from a two-step p-adic extension to its underlying free module + The isomorphism from a two-step `p`-adic extension to its underlying free module. EXAMPLES:: @@ -861,14 +868,15 @@ def _call_(self, x): v = flatten([c._polynomial_list(pad=True) for c in x._polynomial_list(pad=True)]) return self.codomain()(v) + class DefPolyConversion(Morphism): """ - Conversion map between p-adic rings/fields with the same defining polynomial. + Conversion map between `p`-adic rings/fields with the same defining polynomial. INPUT: - - ``R`` -- a p-adic extension ring or field. - - ``S`` -- a p-adic extension ring or field with the same defining polynomial. + - ``R`` -- a `p`-adic extension ring or field + - ``S`` -- a `p`-adic extension ring or field with the same defining polynomial EXAMPLES:: @@ -919,7 +927,6 @@ def _call_(self, x): sage: R(K(0)) 0 - """ S = self.codomain() Sbase = S.base_ring() @@ -962,7 +969,6 @@ def _call_with_args(self, x, args=(), kwds={}): Traceback (most recent call last): ... TypeError: _call_with_args() got multiple values for keyword argument 'absprec' - """ S = self.codomain() Sbase = S.base_ring() diff --git a/src/sage/rings/padics/padic_extension_leaves.py b/src/sage/rings/padics/padic_extension_leaves.py index d6450039a82..d17563712fb 100644 --- a/src/sage/rings/padics/padic_extension_leaves.py +++ b/src/sage/rings/padics/padic_extension_leaves.py @@ -95,6 +95,7 @@ def _make_integral_poly(exact_modulus, p, prec): except TypeError: return exact_modulus.change_ring(Zmod(p**prec)).change_ring(ZZ) + class UnramifiedExtensionRingCappedRelative(UnramifiedExtensionGeneric, pAdicCappedRelativeRingGeneric): """ TESTS:: @@ -117,7 +118,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -153,6 +154,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp self.register_coercion(pAdicCoercion_ZZ_CR(self)) self.register_conversion(pAdicConvert_QQ_CR(self)) + class UnramifiedExtensionFieldCappedRelative(UnramifiedExtensionGeneric, pAdicCappedRelativeFieldGeneric): """ TESTS:: @@ -175,7 +177,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -261,7 +263,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -298,6 +300,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp self.register_coercion(pAdicCoercion_ZZ_CA(self)) self.register_conversion(pAdicConvert_QQ_CA(self)) + class UnramifiedExtensionRingFixedMod(UnramifiedExtensionGeneric, pAdicFixedModRingGeneric): """ TESTS:: @@ -320,7 +323,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -360,6 +363,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp # return Morphism_ZpFM_UnrFM(S, self) # return None + class UnramifiedExtensionRingFloatingPoint(UnramifiedExtensionGeneric, pAdicFloatingPointRingGeneric): """ TESTS:: @@ -382,7 +386,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -401,7 +405,6 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp sage: a % R.prime() # needs sage.libs.flint a - """ self._shift_seed = None self._exact_modulus = exact_modulus @@ -439,7 +442,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -485,6 +488,7 @@ def _coerce_map_from_(self, R): return super()._coerce_map_from_(R) + class EisensteinExtensionRingCappedRelative(EisensteinExtensionGeneric, pAdicCappedRelativeRingGeneric): """ TESTS:: @@ -508,7 +512,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -540,6 +544,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp self._implementation = implementation EisensteinExtensionGeneric.__init__(self, poly, prec, print_mode, names, pAdicZZpXCRElement) + class EisensteinExtensionFieldCappedRelative(EisensteinExtensionGeneric, pAdicCappedRelativeFieldGeneric): """ TESTS:: @@ -563,7 +568,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -596,6 +601,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp self._implementation = implementation EisensteinExtensionGeneric.__init__(self, poly, prec, print_mode, names, pAdicZZpXCRElement) + class EisensteinExtensionRingCappedAbsolute(EisensteinExtensionGeneric, pAdicCappedAbsoluteRingGeneric): """ TESTS:: @@ -619,7 +625,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused @@ -651,6 +657,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp self._implementation = implementation EisensteinExtensionGeneric.__init__(self, poly, prec, print_mode, names, pAdicZZpXCAElement) + class EisensteinExtensionRingFixedMod(EisensteinExtensionGeneric, pAdicFixedModRingGeneric): """ TESTS:: @@ -674,7 +681,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- a dictionary of print options + - ``print_mode`` -- dictionary of print options - ``shift_seed`` -- unused diff --git a/src/sage/rings/padics/padic_fixed_mod_element.pyx b/src/sage/rings/padics/padic_fixed_mod_element.pyx index bb4b8f3e0db..0dca538cbbd 100644 --- a/src/sage/rings/padics/padic_fixed_mod_element.pyx +++ b/src/sage/rings/padics/padic_fixed_mod_element.pyx @@ -1,7 +1,7 @@ """ `p`-adic Fixed-Mod Element -Elements of p-adic Rings with Fixed Modulus +Elements of `p`-adic Rings with Fixed Modulus AUTHORS: @@ -34,7 +34,7 @@ cdef extern from "transcendantal.c": cdef class PowComputer_(PowComputer_base): """ - A PowComputer for a fixed-modulus padic ring. + A PowComputer for a fixed-modulus `p`-adic ring. """ def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field): """ @@ -55,9 +55,9 @@ cdef class pAdicFixedModElement(FMElement): r""" INPUT: - - ``parent`` -- a ``pAdicRingFixedMod`` object. + - ``parent`` -- a ``pAdicRingFixedMod`` object - - ``x`` -- input data to be converted into the parent. + - ``x`` -- input data to be converted into the parent - ``absprec`` -- ignored; for compatibility with other `p`-adic rings @@ -158,7 +158,7 @@ cdef class pAdicFixedModElement(FMElement): cdef lift_c(self): r""" - Returns an integer congruent to this element modulo the precision. + Return an integer congruent to this element modulo the precision. .. WARNING:: @@ -250,11 +250,13 @@ cdef class pAdicFixedModElement(FMElement): INPUT: - - ``absprec`` -- an integer (default: ``1``) + - ``absprec`` -- integer (default: 1) - - ``field`` -- boolean (default ``None``). Whether to return an element of GF(p) or Zmod(p). + - ``field`` -- boolean (default: ``None``); whether to return an + element of GF(p) or Zmod(p) - - ``check_prec`` -- boolean (default ``False``). No effect (for compatibility with other types). + - ``check_prec`` -- boolean (default: ``False``); no effect (for + compatibility with other types) OUTPUT: @@ -299,7 +301,6 @@ cdef class pAdicFixedModElement(FMElement): .. SEEALSO:: :meth:`_mod_` - """ cdef Integer selfvalue, modulus cdef long aprec @@ -375,19 +376,19 @@ cdef class pAdicFixedModElement(FMElement): def _log_binary_splitting(self, aprec, mina=0): r""" - Return ``\log(self)`` for ``self`` equal to 1 in the residue field + Return ``\log(self)`` for ``self`` equal to 1 in the residue field. This is a helper method for :meth:`log`. It uses a fast binary splitting algorithm. INPUT: - - ``aprec`` -- an integer, the precision to which the result is + - ``aprec`` -- integer; the precision to which the result is correct. ``aprec`` must not exceed the precision cap of the ring over which this element is defined. - - ``mina`` -- an integer (default: 0), the series will check `n` up to + - ``mina`` -- integer (default: 0); the series will check `n` up to this valuation (and beyond) to see if they can contribute to the - series. + series .. NOTE:: @@ -450,13 +451,13 @@ cdef class pAdicFixedModElement(FMElement): def _exp_binary_splitting(self, aprec): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential .. NOTE:: @@ -488,9 +489,8 @@ cdef class pAdicFixedModElement(FMElement): sage: R = Zp(7,5) sage: x = R(7) - sage: x.exp(algorithm="binary_splitting") # indirect doctest + sage: x.exp(algorithm='binary_splitting') # indirect doctest 1 + 7 + 4*7^2 + 2*7^3 + O(7^5) - """ cdef unsigned long p cdef unsigned long prec = aprec @@ -509,16 +509,16 @@ cdef class pAdicFixedModElement(FMElement): def _exp_newton(self, aprec, log_algorithm=None): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential - - ``log_algorithm`` (default: None) -- the algorithm used for + - ``log_algorithm`` -- (default: ``None``) the algorithm used for computing the logarithm. This attribute is passed to the log method. See :meth:`log` for more details about the possible algorithms. @@ -545,7 +545,7 @@ cdef class pAdicFixedModElement(FMElement): sage: # needs sage.libs.ntl sage: R. = Zq(7^2,5) sage: x = R(7*w) - sage: x.exp(algorithm="newton") # indirect doctest + sage: x.exp(algorithm='newton') # indirect doctest 1 + w*7 + (4*w + 2)*7^2 + (w + 6)*7^3 + 5*7^4 + O(7^5) """ cdef unsigned long p diff --git a/src/sage/rings/padics/padic_floating_point_element.pyx b/src/sage/rings/padics/padic_floating_point_element.pyx index ed80e7c853d..ceae683a62c 100644 --- a/src/sage/rings/padics/padic_floating_point_element.pyx +++ b/src/sage/rings/padics/padic_floating_point_element.pyx @@ -32,7 +32,7 @@ cdef extern from "transcendantal.c": cdef class PowComputer_(PowComputer_base): """ - A PowComputer for a floating-point padic ring or field. + A PowComputer for a floating-point `p`-adic ring or field. """ def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field): """ @@ -51,7 +51,7 @@ cdef class PowComputer_(PowComputer_base): cdef class pAdicFloatingPointElement(FPElement): """ - Constructs new element with given parent and value. + Construct new element with given parent and value. INPUT: @@ -136,7 +136,6 @@ cdef class pAdicFloatingPointElement(FPElement): 0 # todo: doctests for converting from other types of p-adic rings - """ def lift(self): r""" @@ -144,7 +143,7 @@ cdef class pAdicFloatingPointElement(FPElement): precision. If a rational is returned, its denominator will equal ``p^ordp(self)``. - This method will raise a :class:`ValueError` when this element + This method will raise a :exc:`ValueError` when this element is infinity. EXAMPLES:: @@ -245,9 +244,9 @@ cdef class pAdicFloatingPointElement(FPElement): INPUT: - - ``absprec`` -- a non-negative integer (default: ``1``) + - ``absprec`` -- nonnegative integer (default: 1) - - ``field`` -- boolean (default ``None``); whether to return an + - ``field`` -- boolean (default: ``None``); whether to return an element of `\GF{p}` or `\ZZ / p\ZZ` - ``check_prec`` -- ignored (for compatibility with other types) @@ -276,7 +275,7 @@ cdef class pAdicFloatingPointElement(FPElement): sage: b.residue() Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue TESTS:: @@ -301,7 +300,7 @@ cdef class pAdicFloatingPointElement(FPElement): if mpz_sgn((absprec).value) < 0: raise ValueError("cannot reduce modulo a negative power of p") if self.ordp < 0: - raise ValueError("element must have non-negative valuation in order to compute residue") + raise ValueError("element must have nonnegative valuation in order to compute residue") if field is None: field = (absprec == 1) elif field and absprec != 1: @@ -325,13 +324,13 @@ cdef class pAdicFloatingPointElement(FPElement): def _exp_binary_splitting(self, aprec): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential .. NOTE:: @@ -363,9 +362,8 @@ cdef class pAdicFloatingPointElement(FPElement): sage: R = Zp(7,5) sage: x = R(7) - sage: x.exp(algorithm="binary_splitting") # indirect doctest + sage: x.exp(algorithm='binary_splitting') # indirect doctest 1 + 7 + 4*7^2 + 2*7^3 + O(7^5) - """ cdef unsigned long p cdef unsigned long prec = aprec @@ -386,13 +384,13 @@ cdef class pAdicFloatingPointElement(FPElement): def _exp_newton(self, aprec, log_algorithm=None): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer; the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential - ``log_algorithm`` -- (default: ``None``) the algorithm used for @@ -422,7 +420,7 @@ cdef class pAdicFloatingPointElement(FPElement): sage: # needs sage.libs.ntl sage: R. = Zq(7^2,5) sage: x = R(7*w) - sage: x.exp(algorithm="newton") # indirect doctest + sage: x.exp(algorithm='newton') # indirect doctest 1 + w*7 + (4*w + 2)*7^2 + (w + 6)*7^3 + 5*7^4 + O(7^5) """ cdef unsigned long p diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py index f9e4792fd3e..3f041a5e146 100644 --- a/src/sage/rings/padics/padic_generic.py +++ b/src/sage/rings/padics/padic_generic.py @@ -2,7 +2,7 @@ r""" `p`-adic Generic -A generic superclass for all p-adic parents. +A generic superclass for all `p`-adic parents. AUTHORS: @@ -164,7 +164,7 @@ def __richcmp__(self, other, op): r""" Rich comparison of ``self`` with ``other``. - We consider two p-adic rings or fields to be equal if they are + We consider two `p`-adic rings or fields to be equal if they are equal mathematically, and also have the same precision cap and printing parameters. @@ -230,9 +230,7 @@ def prime(self): r""" Return the prime, ie the characteristic of the residue field. - OUTPUT: - - The characteristic of the residue field. + OUTPUT: the characteristic of the residue field EXAMPLES:: @@ -275,9 +273,7 @@ def residue_characteristic(self): r""" Return the prime, i.e., the characteristic of the residue field. - OUTPUT: - - The characteristic of the residue field. + OUTPUT: the characteristic of the residue field EXAMPLES:: @@ -377,9 +373,7 @@ def fraction_field(self, print_mode=None): - ``print_mode`` -- (optional) a dictionary containing print options; defaults to the same options as this ring - OUTPUT: - - - the fraction field of this ring + OUTPUT: the fraction field of this ring EXAMPLES:: @@ -437,9 +431,7 @@ def integer_ring(self, print_mode=None): - ``print_mode`` -- (optional) a dictionary containing print options; defaults to the same options as this ring - OUTPUT: - - - the ring of elements of this field with nonnegative valuation + OUTPUT: the ring of elements of this field with nonnegative valuation EXAMPLES:: @@ -503,9 +495,7 @@ def teichmuller(self, x, prec=None): - ``x`` -- something that can be cast into ``self`` - OUTPUT: - - - the Teichmüller lift of ``x`` + OUTPUT: the Teichmüller lift of ``x`` EXAMPLES:: @@ -619,7 +609,7 @@ def teichmuller_system(self): def extension(self, modulus, prec=None, names=None, print_mode=None, implementation='FLINT', **kwds): r""" - Create an extension of this p-adic ring. + Create an extension of this `p`-adic ring. EXAMPLES:: @@ -1063,7 +1053,7 @@ def _test_convert_residue_field(self, **options): INPUT: - - ``options`` -- any keyword arguments accepted by :meth:`_tester` + - ``options`` -- any keyword arguments accepted by :meth:`_tester` EXAMPLES:: @@ -1120,7 +1110,7 @@ def frobenius_endomorphism(self, n=1): INPUT: - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) EXAMPLES:: @@ -1217,7 +1207,7 @@ def _primitive_qth_root_of_unity(self, exponent): INPUT: - - ``exponent`` -- an integer or ``Infinity`` + - ``exponent`` -- integer or ``Infinity`` OUTPUT: @@ -1292,9 +1282,9 @@ def primitive_root_of_unity(self, n=None, order=False): INPUT: - - ``n`` -- an integer or ``None`` (default: ``None``) + - ``n`` -- integer or ``None`` (default: ``None``) - - ``order`` -- a boolean (default: ``False``) + - ``order`` -- boolean (default: ``False``) OUTPUT: @@ -1372,7 +1362,7 @@ def roots_of_unity(self, n=None): INPUT: - - ``n`` -- an integer or ``None`` (default: ``None``); if + - ``n`` -- integer or ``None`` (default: ``None``); if ``None``, the full group of roots of unity is returned EXAMPLES:: @@ -1436,17 +1426,17 @@ def _roots_univariate_polynomial(self, P, ring, multiplicities, algorithm, secur - ``ring`` -- a ring into which this ring coerces - - ``multiplicities`` -- a boolean (default: ``True``); + - ``multiplicities`` -- boolean (default: ``True``); whether we have to return the multiplicities of each root or not - - ``algorithm`` -- ``"pari"``, ``"sage"`` or ``None`` (default: + - ``algorithm`` -- ``'pari'``, ``'sage'`` or ``None`` (default: ``None``); Sage provides an implementation for any extension of `\QQ_p` whereas only roots of polynomials over `\QQ_p` is implemented - in Pari; the default is ``"pari"`` if ``ring`` is `\ZZ_p` or `\QQ_p`, - ``"sage"`` otherwise. + in Pari; the default is ``'pari'`` if ``ring`` is `\ZZ_p` or `\QQ_p`, + ``'sage'`` otherwise. - - ``secure`` -- a boolean (default: ``False``) + - ``secure`` -- boolean (default: ``False``) .. NOTE:: @@ -1511,12 +1501,12 @@ def _roots_univariate_polynomial(self, P, ring, multiplicities, algorithm, secur 3 + O(3^9), O(3^9)] - This is due to the fact that we are using ``"pari"`` which does not + This is due to the fact that we are using ``'pari'`` which does not track precision (it can only compute `p`-adic roots of exact polynomials). - If we are switching to ``"sage"`` then the precision on the result + If we are switching to ``'sage'`` then the precision on the result becomes correct (but the computation is much slower):: - sage: P.roots(multiplicities=False, algorithm="sage") # needs sage.geometry.polyhedron sage.libs.ntl + sage: P.roots(multiplicities=False, algorithm='sage') # needs sage.geometry.polyhedron sage.libs.ntl [0, 3 + O(3^11), 1 + O(3^9), @@ -1526,9 +1516,9 @@ def _roots_univariate_polynomial(self, P, ring, multiplicities, algorithm, secur We check that the keyword ``secure`` works as explained above:: sage: P = x^2 + O(3^10)*x + O(3^10) # needs sage.libs.ntl - sage: P.roots(algorithm="sage") # needs sage.geometry.polyhedron sage.libs.ntl + sage: P.roots(algorithm='sage') # needs sage.geometry.polyhedron sage.libs.ntl [(O(3^5), 2)] - sage: P.roots(algorithm="sage", secure=True) # needs sage.libs.ntl + sage: P.roots(algorithm='sage', secure=True) # needs sage.libs.ntl Traceback (most recent call last): ... PrecisionError: not enough precision to determine the number of roots @@ -1611,7 +1601,7 @@ def _roots_univariate_polynomial(self, P, ring, multiplicities, algorithm, secur class ResidueReductionMap(Morphism): r""" - Reduction map from a p-adic ring or field to its residue field or ring. + Reduction map from a `p`-adic ring or field to its residue field or ring. These maps must be created using the :meth:`_create_` method in order to support categories correctly. @@ -1633,8 +1623,8 @@ def _create_(R, k): INPUT: - - ``R`` -- a `p`-adic ring or field. - - ``k`` -- the residue field of ``R``, or a residue ring of ``R``. + - ``R`` -- a `p`-adic ring or field + - ``k`` -- the residue field of ``R``, or a residue ring of ``R`` EXAMPLES:: @@ -1704,14 +1694,14 @@ def _call_(self, x): sage: Zmod(121).convert_map_from(Qp(11))(3/11) # needs sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue """ return x.residue(self._n, field=self._field, check_prec=self._field) def section(self): r""" Return the section from the residue ring or field - back to the p-adic ring or field. + back to the `p`-adic ring or field. EXAMPLES:: @@ -1753,9 +1743,10 @@ def _richcmp_(self, other, op): # A class for the Teichmüller lift would also be reasonable.... + class ResidueLiftingMap(Morphism): r""" - Lifting map to a p-adic ring or field from its residue field or ring. + Lifting map to a `p`-adic ring or field from its residue field or ring. These maps must be created using the :meth:`_create_` method in order to support categories correctly. @@ -1777,8 +1768,8 @@ def _create_(k, R): INPUT: - - ``k`` -- the residue field of ``R``, or a residue ring of ``R``. - - ``R`` -- a `p`-adic ring or field. + - ``k`` -- the residue field of ``R``, or a residue ring of ``R`` + - ``R`` -- a `p`-adic ring or field EXAMPLES:: @@ -1885,10 +1876,11 @@ def _richcmp_(self, other, op): return NotImplemented return richcmp((self.domain(), self.codomain()), (other.domain(), other.codomain()), op) + def local_print_mode(obj, print_options, pos=None, ram_name=None): r""" Context manager for safely temporarily changing the print_mode - of a p-adic ring/field. + of a `p`-adic ring/field. EXAMPLES:: diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 92fa0606de1..ec3b1848416 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -170,7 +170,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef bint _is_exact_zero(self) except -1: """ - Return ``True`` if self is exactly zero. Since + Return ``True`` if ``self`` is exactly zero. Since non-capped-relative elements cannot be exact, this function always returns False. @@ -183,7 +183,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef bint _is_inexact_zero(self) except -1: """ - Return ``True`` if self is indistinguishable from zero, but not + Return ``True`` if ``self`` is indistinguishable from zero, but not exactly zero. EXAMPLES:: @@ -195,7 +195,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef bint _is_zero_rep(self) except -1: """ - Return ``True`` is self is indistinguishable from zero. + Return ``True`` if ``self`` is indistinguishable from zero. EXAMPLES:: @@ -217,7 +217,7 @@ cdef class pAdicGenericElement(LocalGenericElement): """ Quotient with remainder. - We choose the remainder to have the same p-adic expansion + We choose the remainder to have the same `p`-adic expansion as the numerator, but truncated at the valuation of the denominator. EXAMPLES:: @@ -278,8 +278,8 @@ cdef class pAdicGenericElement(LocalGenericElement): def __floordiv__(self, right): """ - Divides self by right and throws away the nonintegral part if - self.parent() is not a field. + Divide ``self`` by ``right`` and throws away the nonintegral part if + ``self.parent()`` is not a field. There are a number of reasonable definitions for floor division. Any definition should satisfy the following @@ -292,7 +292,7 @@ cdef class pAdicGenericElement(LocalGenericElement): However, for elements of integer rings, there are many choices of definitions for a // b and a % b that satisfy this - equation. Since p-adic rings in Sage come equipped with a + equation. Since `p`-adic rings in Sage come equipped with a uniformizer pi, we can use the choice of uniformizer in our definitions. Here are some other criteria we might ask for: @@ -355,7 +355,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef _floordiv_(self, right): """ - Implements floor division. + Implement floor division. EXAMPLES:: @@ -367,7 +367,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def __getitem__(self, n): r""" - Returns the coefficient of `p^n` in the series expansion of this + Return the coefficient of `p^n` in the series expansion of this element, as an integer in the range `0` to `p-1`. EXAMPLES:: @@ -449,7 +449,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def __invert__(self): r""" - Returns the multiplicative inverse of self. + Return the multiplicative inverse of ``self``. EXAMPLES:: @@ -466,8 +466,8 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef _mod_(self, right): """ - If self is in a field, returns 0. If in a ring, returns a - p-adic integer such that + If ``self`` is in a field, returns 0. If in a ring, returns a + `p`-adic integer such that (1) a = (a // b) * b + a % b @@ -483,7 +483,7 @@ cdef class pAdicGenericElement(LocalGenericElement): However, for elements of integer rings, there are many choices of definitions for a // b and a % b that satisfy this - equation. Since p-adic rings in Sage come equipped with a + equation. Since `p`-adic rings in Sage come equipped with a uniformizer pi, we can use the choice of uniformizer in our definitions. Here are some other criteria we might ask for: @@ -548,10 +548,10 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - ``mode`` -- allows one to override the default print mode of - the parent (default: ``None``). + the parent (default: ``None``) - ``do_latex`` -- whether to return a latex representation or - a normal one. + a normal one EXAMPLES:: @@ -575,11 +575,9 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``) + - ``prec`` -- integer or ``None`` (default: ``None``) - OUTPUT: - - The additive order of this element + OUTPUT: the additive order of this element EXAMPLES:: @@ -601,7 +599,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``) + - ``prec`` -- integer or ``None`` (default: ``None``); the desired precision on the result; if ``None``, the precision is derived from the precision on the input @@ -636,9 +634,7 @@ cdef class pAdicGenericElement(LocalGenericElement): computing the logarithm is available. Otherwise we switch to the ``'series'`` algorithm. - OUTPUT: - - The Artin-Hasse exponential of this element. + OUTPUT: the Artin-Hasse exponential of this element See :wikipedia:`Artin-Hasse_exponential` for more information. @@ -714,7 +710,6 @@ cdef class pAdicGenericElement(LocalGenericElement): - Xavier Caruso (2018-08): extend to any p-adic rings and fields and implement several algorithms. - """ if self.valuation() < 1: raise ValueError("Artin-Hasse exponential does not converge on this input") @@ -757,10 +752,10 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- an integer, the precision at which the + - ``prec`` -- integer; the precision at which the result should be computed - - ``exp_algorithm`` -- a string, the algorithm called + - ``exp_algorithm`` -- string; the algorithm called for computing the exponential EXAMPLES:: @@ -853,7 +848,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- an integer, the precision at which the + - ``prec`` -- integer; the precision at which the result should be computed EXAMPLES:: @@ -904,7 +899,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- an integer, the precision at which the + - ``prec`` -- integer; the precision at which the result should be computed EXAMPLES:: @@ -969,13 +964,13 @@ cdef class pAdicGenericElement(LocalGenericElement): def minimal_polynomial(self, name='x', base=None): """ - Returns the minimal polynomial of this element over ``base`` + Return the minimal polynomial of this element over ``base``. INPUT: - - ``name`` -- string (default: ``'x'``): the name of the variable + - ``name`` -- string (default: ``'x'``); the name of the variable - - ``base`` -- a ring (default: the base ring of the parent): + - ``base`` -- a ring (default: the base ring of the parent); the base ring over which the minimal polynomial is computed EXAMPLES:: @@ -1048,9 +1043,7 @@ cdef class pAdicGenericElement(LocalGenericElement): - ``base`` -- a subring of the parent (default: base ring) - OUTPUT: - - The norm of this `p`-adic element over the given base. + OUTPUT: the norm of this `p`-adic element over the given base EXAMPLES:: @@ -1076,7 +1069,6 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: y = L.random_element() # needs sage.libs.ntl sage: (x*y).norm() == x.norm() * y.norm() # not tested, known bug (see :issue:`32085`) True - """ parent = self.parent() if base is None: @@ -1088,15 +1080,13 @@ cdef class pAdicGenericElement(LocalGenericElement): def trace(self, base=None): """ - Returns the trace of this `p`-adic element over the base ring + Return the trace of this `p`-adic element over the base ring. INPUT: - ``base`` -- a subring of the parent (default: base ring) - OUTPUT: - - The trace of this `p`-adic element over the given base. + OUTPUT: the trace of this `p`-adic element over the given base EXAMPLES:: @@ -1118,7 +1108,6 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: y = L.random_element() # needs sage.libs.ntl sage: (x+y).trace() == x.trace() + y.trace() # not tested, known bug (see :issue:`32085`) True - """ parent = self.parent() if base is None: @@ -1130,7 +1119,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def algdep(self, n): """ - Returns a polynomial of degree at most `n` which is approximately + Return a polynomial of degree at most `n` which is approximately satisfied by this number. Note that the returned polynomial need not be irreducible, and indeed usually won't be if this number is a good approximation to an algebraic number of degree less than `n`. @@ -1140,11 +1129,9 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - ``self`` -- a `p`-adic element - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: - - polynomial -- degree `n` polynomial approximately satisfied by ``self`` + OUTPUT: polynomial; degree `n` polynomial approximately satisfied by ``self`` EXAMPLES:: @@ -1178,7 +1165,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def algebraic_dependency(self, n): """ - Returns a polynomial of degree at most `n` which is approximately + Return a polynomial of degree at most `n` which is approximately satisfied by this number. Note that the returned polynomial need not be irreducible, and indeed usually won't be if this number is a good approximation to an algebraic number of degree less than `n`. @@ -1187,12 +1174,10 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``self`` -- a p-adic element - - ``n`` -- an integer - - OUTPUT: + - ``self`` -- a `p`-adic element + - ``n`` -- integer - polynomial -- degree `n` polynomial approximately satisfied by ``self`` + OUTPUT: polynomial; degree `n` polynomial approximately satisfied by ``self`` EXAMPLES:: @@ -1238,12 +1223,10 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``bd`` -- integer. Precision bound, defaults to 20 - - ``a`` -- integer. Offset parameter, defaults to 0 - - OUTPUT: + - ``bd`` -- integer (default: 20); precision bound + - ``a`` -- integer (default: 0); offset parameter - A `p`-adic integer. + OUTPUT: a `p`-adic integer .. NOTE:: @@ -1309,9 +1292,7 @@ cdef class pAdicGenericElement(LocalGenericElement): implemented in Sage. The default is ``'pari'`` since PARI is about 10 times faster than Sage. - OUTPUT: - - - a `p`-adic integer + OUTPUT: a `p`-adic integer .. NOTE:: @@ -1320,7 +1301,7 @@ cdef class pAdicGenericElement(LocalGenericElement): William Stein sped it up for GP (http://sage.math.washington.edu/home/wstein/www/home/wbhart/pari-2.4.2.alpha/src/basemath/trans2.c). The ``'sage'`` version uses dwork_expansion() to compute the - `p`-adic gamma function of self as in [RV2007]_ section 6.2. + `p`-adic gamma function of ``self`` as in [RV2007]_ section 6.2. EXAMPLES: @@ -1443,7 +1424,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R(3).gcd(9) 3 + O(3^21) - A non-zero result is always lifted to the maximal precision possible in + A nonzero result is always lifted to the maximal precision possible in the ring:: sage: a = R(3,2); a @@ -1538,7 +1519,6 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R = ZpCA(3) sage: R(3).gcd(9) 3 + O(3^20) - """ if self.is_zero() and other.is_zero(): if self.valuation() < other.valuation(): @@ -1701,7 +1681,6 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R = ZpCA(3) sage: R(3).xgcd(9) (3 + O(3^20), 1 + O(3^19), O(3^20)) - """ s,t = self.parent().zero(), self.parent().zero() if self.is_zero() and other.is_zero(): @@ -1729,7 +1708,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def is_square(self): """ - Returns whether this element is a square + Return whether this element is a square. INPUT: @@ -1881,7 +1860,6 @@ cdef class pAdicGenericElement(LocalGenericElement): K(0,0).is_squarefree() False - """ if self.parent().is_field(): if self.is_zero(): @@ -1901,17 +1879,15 @@ cdef class pAdicGenericElement(LocalGenericElement): def multiplicative_order(self, prec = None): r""" - Returns the multiplicative order of ``self``, where ``self`` is + Return the multiplicative order of ``self``, where ``self`` is considered to be one if it is one modulo `p^{\mbox{prec}}`. INPUT: - ``self`` -- a `p`-adic element - - ``prec`` -- an integer + - ``prec`` -- integer - OUTPUT: - - - integer -- the multiplicative order of ``self`` + OUTPUT: integer; the multiplicative order of ``self`` EXAMPLES:: @@ -2006,16 +1982,15 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - ``self`` -- a `p`-adic element - - ``p`` -- a prime (default: ``None``). If specified, will make sure that ``p == self.parent().prime()`` + - ``p`` -- a prime (default: ``None``); if specified, will make sure + that ``p == self.parent().prime()`` .. NOTE:: The optional argument `p` is used for consistency with the valuation methods on integers and rationals. - OUTPUT: - - integer -- the valuation of ``self`` + OUTPUT: integer; the valuation of ``self`` EXAMPLES:: @@ -2131,7 +2106,8 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - ``self`` -- a `p`-adic element - - ``p`` -- a prime (default: ``None``). If specified, will make sure that ``p == self.parent().prime()`` + - ``p`` -- a prime (default: ``None``); if specified, will make sure + that ``p == self.parent().prime()`` .. NOTE:: @@ -2198,9 +2174,9 @@ cdef class pAdicGenericElement(LocalGenericElement): def rational_reconstruction(self): r""" - Returns a rational approximation to this `p`-adic number. + Return a rational approximation to this `p`-adic number. - This will raise an :class:`ArithmeticError` if there are no valid + This will raise an :exc:`ArithmeticError` if there are no valid approximations to the unit part with numerator and denominator bounded by ``sqrt(p^absprec / 2)``. @@ -2208,9 +2184,7 @@ cdef class pAdicGenericElement(LocalGenericElement): :meth:`_rational_` - OUTPUT: - - rational -- an approximation to ``self`` + OUTPUT: rational; an approximation to ``self`` EXAMPLES:: @@ -2321,19 +2295,19 @@ cdef class pAdicGenericElement(LocalGenericElement): def _log_generic(self, aprec, mina=0): r""" - Return ``\log(self)`` for ``self`` equal to 1 in the residue field + Return ``\log(self)`` for ``self`` equal to 1 in the residue field. This is a helper method for :meth:`log`. INPUT: - - ``aprec`` -- an integer, the precision to which the result is + - ``aprec`` -- integer; the precision to which the result is correct. ``aprec`` must not exceed the precision cap of the ring over which this element is defined. - - ``mina`` -- an integer (default: 0), the series will check `n` up to + - ``mina`` -- integer (default: 0); the series will check `n` up to this valuation (and beyond) to see if they can contribute to the - series. + series ALGORITHM: @@ -2367,7 +2341,6 @@ cdef class pAdicGenericElement(LocalGenericElement): Traceback (most recent call last): ... ValueError: Input value (=2) must be 1 in the residue field - """ x = 1-self R = self.parent() @@ -2454,20 +2427,20 @@ cdef class pAdicGenericElement(LocalGenericElement): def _log_binary_splitting(self, aprec, mina=0): r""" - Return ``\log(self)`` for ``self`` equal to 1 in the residue field + Return ``\log(self)`` for ``self`` equal to 1 in the residue field. This is a helper method for :meth:`log`. It uses a fast binary splitting algorithm. INPUT: - - ``aprec`` -- an integer, the precision to which the result is + - ``aprec`` -- integer; the precision to which the result is correct. ``aprec`` must not exceed the precision cap of the ring over which this element is defined. - - ``mina`` -- an integer (default: 0), the series will check `n` up to + - ``mina`` -- integer (default: 0); the series will check `n` up to this valuation (and beyond) to see if they can contribute to the - series. + series .. NOTE:: @@ -2544,11 +2517,11 @@ cdef class pAdicGenericElement(LocalGenericElement): may specify at most one of ``p_branch`` and ``pi_branch``, and must specify one of them if this element is not a unit - - ``aprec`` -- an integer or ``None`` (default: ``None``); if not + - ``aprec`` -- integer or ``None`` (default: ``None``); if not ``None``, then the result will only be correct to precision ``aprec`` - - ``change_frac`` -- In general the codomain of the logarithm should be + - ``change_frac`` -- in general the codomain of the logarithm should be in the `p`-adic field, however, for most neighborhoods of 1, it lies in the ring of integers. This flag decides if the codomain should be the same as the input (default) or if it should change to the @@ -2630,7 +2603,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: c.log(p_branch=4) 4 + 2*5 + 3*5^2 + 2*5^3 + 4*5^4 + 2*5^6 + 2*5^7 + 4*5^8 + 2*5^9 + O(5^10) - The branch parameters are only relevant for elements of non-zero + The branch parameters are only relevant for elements of nonzero valuation:: sage: a.log(p_branch=0) @@ -2886,7 +2859,6 @@ cdef class pAdicGenericElement(LocalGenericElement): - Xavier Caruso (2017-06): Added binary splitting type algorithms over Qp - """ if self.is_zero(): raise ValueError('logarithm is not defined at zero') @@ -2977,14 +2949,14 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential EXAMPLES:: sage: R. = Zq(7^2,5) # needs sage.libs.ntl sage: x = R(7*w) # needs sage.libs.ntl - sage: x.exp(algorithm="generic") # indirect doctest # needs sage.libs.ntl + sage: x.exp(algorithm='generic') # indirect doctest # needs sage.libs.ntl 1 + w*7 + (4*w + 2)*7^2 + (w + 6)*7^3 + 5*7^4 + O(7^5) AUTHORS: @@ -2997,7 +2969,6 @@ cdef class pAdicGenericElement(LocalGenericElement): - Julian Rueth (2013-02-14): Rewrite to solve some precision problems in the capped-absolute case - """ R=self.parent() p=self.parent().prime() @@ -3052,13 +3023,13 @@ cdef class pAdicGenericElement(LocalGenericElement): def _exp_binary_splitting(self, aprec): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential .. NOTE:: @@ -3090,24 +3061,23 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R = Zp(7,5) sage: x = R(7) - sage: x.exp(algorithm="binary_splitting") # indirect doctest + sage: x.exp(algorithm='binary_splitting') # indirect doctest 1 + 7 + 4*7^2 + 2*7^3 + O(7^5) - """ raise NotImplementedError("the binary splitting algorithm is not implemented for the parent: %s" % self.parent()) def _exp_newton(self, aprec, log_algorithm=None): r""" - Compute the exponential power series of this element + Compute the exponential power series of this element. This is a helper method for :meth:`exp`. INPUT: - - ``aprec`` -- an integer, the precision to which to compute the + - ``aprec`` -- integer; the precision to which to compute the exponential - - ``log_algorithm`` (default: None) -- the algorithm used for + - ``log_algorithm`` -- (default: ``None``) the algorithm used for computing the logarithm. This attribute is passed to the log method. See :meth:`log` for more details about the possible algorithms. @@ -3133,7 +3103,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R. = Zq(7^2,5) # needs sage.libs.ntl sage: x = R(7*w) # needs sage.libs.ntl - sage: x.exp(algorithm="newton") # indirect doctest # needs sage.libs.ntl + sage: x.exp(algorithm='newton') # indirect doctest # needs sage.libs.ntl 1 + w*7 + (4*w + 2)*7^2 + (w + 6)*7^3 + 5*7^4 + O(7^5) """ R = self.parent() @@ -3163,7 +3133,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``aprec`` -- an integer or ``None`` (default: ``None``); if + - ``aprec`` -- integer or ``None`` (default: ``None``); if specified, computes only up to the indicated precision - ``algorithm`` -- ``'generic'``, ``'binary_splitting'``, ``'newton'`` @@ -3333,9 +3303,9 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R = Zp(5,50) sage: a = 5 * R.random_element() - sage: bg = a.exp(algorithm="generic") - sage: bbs = a.exp(algorithm="binary_splitting") - sage: bn = a.exp(algorithm="newton") + sage: bg = a.exp(algorithm='generic') + sage: bbs = a.exp(algorithm='binary_splitting') + sage: bn = a.exp(algorithm='newton') sage: bg == bbs True sage: bg == bn @@ -3356,7 +3326,6 @@ cdef class pAdicGenericElement(LocalGenericElement): - Julian Rueth (2013-02-14): Added doctests, fixed some corner cases - Xavier Caruso (2017-06): Added binary splitting and Newton algorithms - """ p = self.parent().prime() @@ -3393,20 +3362,20 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``self`` -- a `p`-adic element. + - ``self`` -- a `p`-adic element - - ``extend`` -- a boolean (default: ``True``); if ``True``, return a + - ``extend`` -- boolean (default: ``True``); if ``True``, return a square root in an extension if necessary; if ``False`` and no root - exists in the given ring or field, raise a :class:`ValueError`. + exists in the given ring or field, raise a :exc:`ValueError`. - - ``all`` -- a boolean (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots - - ``algorithm`` -- ``"pari"``, ``"sage"`` or ``None`` (default: + - ``algorithm`` -- ``'pari'``, ``'sage'`` or ``None`` (default: ``None``); Sage provides an implementation for any extension of - `\QQ_p`, whereas only square roots over `\QQ_p` are implemented in PARI; - the default is ``"pari"`` if the ground field is `\QQ_p`, ``"sage"`` - otherwise. + `\QQ_p`, whereas only square roots over `\QQ_p` are implemented in + PARI. The default is ``'pari'`` if the ground field is `\QQ_p`, + ``'sage'`` otherwise. OUTPUT: @@ -3595,10 +3564,10 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``all`` -- a boolean (default: ``False``): if ``True``, - return all `n`-th roots of this element, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, + return all `n`-th roots of this element, instead of just one EXAMPLES:: @@ -3733,7 +3702,6 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: elt = L.random_element() sage: elt in (elt^108).nth_root(108, all=True) True - """ n = ZZ(n) if n == 0: @@ -3785,7 +3753,7 @@ cdef class pAdicGenericElement(LocalGenericElement): root = root.lift_to_precision(min(minprec,prec,curprec)) root += invm * root * (1 - a*(root**m)) - # We now extract the (p^v)-th root + # We now extract the `(p^v)`-th root zeta, s, nextzeta = K._primitive_qth_root_of_unity(v) if v: nextzeta = (parent(nextzeta[0]), nextzeta[1]) # nextzeta[0] may have a wrong parent (with more precision) @@ -3831,7 +3799,7 @@ cdef class pAdicGenericElement(LocalGenericElement): - ``twist`` -- an element in the same parent or ``None`` (default: ``None``) - - ``hint`` -- a tuple or ``None`` (default: ``None``); if not + - ``hint`` -- tuple or ``None`` (default: ``None``); if not ``None``, it has to be the output of ``twist._inverse_pth_root()`` OUTPUT: @@ -3872,7 +3840,6 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: for n in [5, 10, 15]: # indirect doctest ....: z = y**n ....: assert z.nth_root(n)**n == z - """ ring = self.parent() p = ring.prime() @@ -4022,7 +3989,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- Integer. The precision of the real field in which + - ``prec`` -- integer; the precision of the real field in which the answer is returned. If ``None``, returns a rational for absolutely unramified fields, or a real with 53 bits of precision for ramified fields. @@ -4078,7 +4045,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``p`` -- a prime, which is compared with the parent of this element. + - ``p`` -- a prime, which is compared with the parent of this element EXAMPLES:: @@ -4090,18 +4057,17 @@ cdef class pAdicGenericElement(LocalGenericElement): raise NotImplementedError def _polylog_res_1(self, n, p_branch = 0): - """ - Return `Li_n(`self`)` , the `n`th `p`-adic polylogarithm of ``self``, assuming that self is congruent to 1 mod p. + r""" + Return `Li_n(`self`)`, the `n`-th `p`-adic polylogarithm of ``self``, + assuming that ``self`` is congruent to `1 \pmod p`. This is an internal function, used by :meth:`polylog`. INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - `Li_n(`self`)` + OUTPUT: `Li_n(`self`)` EXAMPLES:: @@ -4181,7 +4147,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - ``p_branch`` -- an element in the base ring or its fraction field; the implementation will choose the branch of the logarithm which sends `p` to ``p_branch`` @@ -4411,7 +4377,6 @@ def _AHE_coefficients(p, N, prec): sage: R = ZpFM(2, 10) sage: [ R(c) for c in L ] == [ R(c) for c in AH.list() ] # needs sage.rings.padics False - """ from sage.rings.padics.factory import ZpFM from sage.arith.misc import integer_floor as floor @@ -4461,7 +4426,7 @@ def _findprec(c_1, c_2, c_3, p): INPUT: - `c_1`, `c_2`, `c_3` -- positive integers - - `p` -- prime + - ``p`` -- prime OUTPUT: @@ -4520,11 +4485,9 @@ cpdef dwork_mahler_coeffs(R, int bd=20): INPUT: - ``R`` -- `p`-adic ring in which to compute - - ``bd`` -- integer. Number of terms in the expansion to use - - OUTPUT: + - ``bd`` -- integer; number of terms in the expansion to use - A list of `p`-adic integers. + OUTPUT: a list of `p`-adic integers EXAMPLES:: @@ -4606,7 +4569,7 @@ cpdef gauss_table(long long p, int f, int prec, bint use_longs): r""" Compute a table of Gauss sums using the Gross-Koblitz formula. - This is used in the computation of L-functions of hypergeometric motives. + This is used in the computation of `L`-functions of hypergeometric motives. The Gross-Koblitz formula is used as in `sage.rings.padics.misc.gauss_sum`, but further unpacked for efficiency. diff --git a/src/sage/rings/padics/padic_lattice_element.py b/src/sage/rings/padics/padic_lattice_element.py index d1b75efe6d6..46747174f43 100644 --- a/src/sage/rings/padics/padic_lattice_element.py +++ b/src/sage/rings/padics/padic_lattice_element.py @@ -59,7 +59,7 @@ def unpickle_le(parent, value, prec): - ``value`` -- a rational number - - ``prec`` -- an integer + - ``prec`` -- integer EXAMPLES:: @@ -75,7 +75,7 @@ def unpickle_le(parent, value, prec): class pAdicLatticeElement(pAdicGenericElement): r""" - Constructs new element with given parent and value. + Construct new element with given parent and value. INPUT: @@ -83,21 +83,21 @@ class pAdicLatticeElement(pAdicGenericElement): - ``x`` -- the newly created element - - ``prec`` -- an integer; the absolute precision at which this + - ``prec`` -- integer; the absolute precision at which this element has to be capped - - ``dx`` -- a dictionary representing the differential of ``x`` + - ``dx`` -- dictionary representing the differential of ``x`` - - ``dx_mode`` -- a string, either ``linear_combination`` (the default) - or ``values`` + - ``dx_mode`` -- string; either ``'linear_combination'`` (the default) + or ``'values'`` - - ``valuation`` -- an integer or ``None`` (default: ``None``), + - ``valuation`` -- integer or ``None`` (default: ``None``); the valuation of this element - - ``check`` -- a boolean (default: ``True``), whether the function + - ``check`` -- boolean (default: ``True``); whether the function should check that the given values are well formed and coherent - - ``reduce`` -- a boolean (default: ``True``), whether the given + - ``reduce`` -- boolean (default: ``True``); whether the given values need to be reduced TESTS:: @@ -204,7 +204,7 @@ def _is_base_elt(self, p): INPUT: - - ``p`` -- a prime, which is compared with the parent of this element. + - ``p`` -- a prime, which is compared with the parent of this element EXAMPLES:: @@ -264,12 +264,14 @@ def residue(self, absprec=1, field=None, check_prec=True): INPUT: - - ``absprec`` -- a non-negative integer (default: ``1``) + - ``absprec`` -- nonnegative integer (default: 1) - - ``field`` -- boolean (default ``None``). Whether to return an element of GF(p) or Zmod(p). + - ``field`` -- boolean (default: ``None``); whether to return an + element of GF(p) or Zmod(p) - - ``check_prec`` -- boolean (default ``True``). Whether to raise an error if this - element has insufficient precision to determine the reduction. + - ``check_prec`` -- boolean (default: ``True``); whether to raise an + error if this element has insufficient precision to determine the + reduction OUTPUT: @@ -310,7 +312,7 @@ def residue(self, absprec=1, field=None, check_prec=True): elif absprec < 0: raise ValueError("cannot reduce modulo a negative power of p") if self.valuation() < 0: - raise ValueError("element must have non-negative valuation in order to compute residue") + raise ValueError("element must have nonnegative valuation in order to compute residue") if field is None: field = (absprec == 1) elif field and absprec != 1: @@ -409,11 +411,11 @@ def valuation(self, secure=False): INPUT: - - ``secure`` -- a boolean (default: ``False``); when ``True``, + - ``secure`` -- boolean (default: ``False``); when ``True``, an error is raised if the precision on the element is not - enough to determine for sure its valuation; otherwise the + enough to determine for sure its valuation. Otherwise the absolute precision (which is the smallest possible valuation) - is returned + is returned. EXAMPLES:: @@ -449,7 +451,7 @@ def precision_relative(self, secure=False): INPUT: - - ``secure`` -- a boolean (default: ``False``); when ``True``, + - ``secure`` -- boolean (default: ``False``); when ``True``, an error is raised if the precision on the element is not enough to determine for sure its valuation @@ -727,7 +729,7 @@ def add_bigoh(self, prec): INPUT: - - ``prec`` -- an integer or infinity + - ``prec`` -- integer or infinity EXAMPLES:: @@ -768,16 +770,16 @@ def add_bigoh(self, prec): def lift_to_precision(self, prec=None, infer_precision=False): r""" Return another element of the same parent with absolute precision - at least ``prec``, congruent to this p-adic element modulo the + at least ``prec``, congruent to this `p`-adic element modulo the precision of this element. INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``), the + - ``prec`` -- integer or ``None`` (default: ``None``); the absolute precision of the result. If ``None``, lifts to the - maximum precision allowed + maximum precision allowed. - - ``infer_precision`` -- a boolean (default: ``False``) + - ``infer_precision`` -- boolean (default: ``False``) NOTE: @@ -878,7 +880,7 @@ def is_zero(self, prec=None): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``) + - ``prec`` -- integer or ``None`` (default: ``None``) EXAMPLES:: @@ -1162,13 +1164,13 @@ def expansion(self, n=None, lift_mode='simple', start_val=None): INPUT: - - ``n`` -- an integer or ``None`` (default ``None``); if given, - return the corresponding entry in the expansion. + - ``n`` -- integer or ``None`` (default: ``None``); if given, + return the corresponding entry in the expansion - - ``lift_mode`` -- a string (default: ``simple``); currently - only ``simple`` is implemented. + - ``lift_mode`` -- string (default: ``'simple'``); currently + only ``'simple'`` is implemented - - ``start_val`` -- an integer or ``None`` (default: ``None``); + - ``start_val`` -- integer or ``None`` (default: ``None``); start at this valuation rather than the default (`0` or the valuation of this element). diff --git a/src/sage/rings/padics/padic_printing.pyx b/src/sage/rings/padics/padic_printing.pyx index eb5904907ba..c0988388066 100644 --- a/src/sage/rings/padics/padic_printing.pyx +++ b/src/sage/rings/padics/padic_printing.pyx @@ -7,7 +7,7 @@ """ `p`-adic Printing -This file contains code for printing p-adic elements. +This file contains code for printing `p`-adic elements. It has been moved here to prevent code duplication and make finding the relevant code easier. @@ -52,9 +52,9 @@ def pAdicPrinter(ring, options={}): INPUT: - - ring -- a p-adic ring or field. + - ``ring`` -- a `p`-adic ring or field - - options -- a dictionary, with keys in ``'mode'``, ``'pos'``, + - ``options`` -- dictionary, with keys in ``'mode'``, ``'pos'``, ``'ram_name'``, ``'unram_name'``, ``'var_name'``, ``'max_ram_terms'``, ``'max_unram_terms'``, ``'max_terse_terms'``, ``'sep'``, ``'alphabet'``; see :class:`pAdicPrinter_class` for the meanings of these keywords. @@ -74,12 +74,12 @@ def pAdicPrinter(ring, options={}): class pAdicPrinterDefaults(SageObject): """ - This class stores global defaults for p-adic printing. + This class stores global defaults for `p`-adic printing. """ def __init__(self, mode = 'series', pos = True, max_ram_terms = -1, max_unram_terms = -1, max_terse_terms = -1, sep = "|", alphabet = None): r""" Instances of this class store global defaults used in - determining printing options during the creation of p-adic + determining printing options during the creation of `p`-adic rings and fields. One instance stored in padic_printing stores the globally relevant default values. @@ -273,7 +273,7 @@ class pAdicPrinterDefaults(SageObject): def alphabet(self, alphabet = None): r""" - Controls the alphabet used to translate p-adic digits into + Controls the alphabet used to translate `p`-adic digits into strings (so that no separator need be used in ``'digits'`` mode). ``alphabet`` should be passed in as a list or tuple. @@ -301,83 +301,72 @@ _printer_defaults = pAdicPrinterDefaults() cdef class pAdicPrinter_class(SageObject): """ - This class stores the printing options for a specific p-adic ring + This class stores the printing options for a specific `p`-adic ring or field, and uses these to compute the representations of elements. """ def __init__(self, ring, mode, pos, ram_name, unram_name, var_name, max_ram_terms, max_unram_terms, max_terse_terms, sep, alphabet, show_prec): """ - Initializes a :class:`pAdicPrinter`. + Initialize a :class:`pAdicPrinter`. INPUT: - - ring -- the ring or field to which this :class:`pAdicPrinter` is - attached. + - ``ring`` -- the ring or field to which this :class:`pAdicPrinter` is + attached - - mode -- The allowed values for mode are: 'val-unit', - 'series', 'terse', 'digits' and 'bars'. + - ``mode`` -- the allowed values for mode are: ``'val-unit'``, + ``'series'``, ``'terse'``, ``'digits'`` and ``'bars'``: - - 'val-unit' -- elements are displayed as a power of - the uniformizer times a unit, which is displayed in - terse mode. + - ``'val-unit'`` -- elements are displayed as a power of the + uniformizer times a unit, which is displayed in terse mode - - 'series' -- elements are displayed as power series - in the uniformizer. + - ``'series'`` -- elements are displayed as power series in the + uniformizer - - 'terse' -- for base rings and fields, elements are - just displayed as an integer lift. For extensions - rings and fields, elements are displayed as a - polynomial in the generator of the extension. + - ``'terse'`` -- for base rings and fields, elements are just + displayed as an integer lift. For extensions rings and fields, + elements are displayed as a polynomial in the generator of the + extension. - - 'digits' -- Used only for small primes and totally - ramified extensions (or trivial extensions), - elements are displayed as just a string of p-adic - digits, encoded using the 'alphabet' parameter. + - ``'digits'`` -- used only for small primes and totally ramified + extensions (or trivial extensions), elements are displayed as just + a string of `p`-adic digits, encoded using the 'alphabet' parameter - - 'bars' -- Like 'digits', but uses a separator in - order to print a more canonical representation for - each digit. This change allows the use of this - printing mode for unramified extensions and - extensions with larger primes. + - ``'bars'`` -- like ``'digits'``, but uses a separator in order to + print a more canonical representation for each digit. This change + allows the use of this printing mode for unramified extensions and + extensions with larger primes. - - pos -- if True then integers in the range [0,... p-1] - will be used; if False integers in the range - [(1-p)/2,..., p/2] will be used. + - ``pos`` -- if ``True`` then integers in the range [0,... p-1] will be + used; if ``False`` integers in the range [(1-p)/2,..., p/2] will be used - - ram_name -- The string used to represent the - uniformizer. + - ``ram_name`` -- the string used to represent the uniformizer - - unram_name -- The string used to represent the trivial - lift of a generator of the residue field over the prime - field. + - ``unram_name`` -- the string used to represent the trivial lift of a + generator of the residue field over the prime field - - var_name -- The string used to represent the - user-specified generator of this extension ring or - field. + - ``var_name`` -- the string used to represent the user-specified + generator of this extension ring or field - - max_ram_terms -- Controls the maximum number of terms - shown when printing in 'series', 'digits' or 'bars' - mode. + - ``max_ram_terms`` -- controls the maximum number of terms shown when + printing in ``'series'``, ``'digits'`` or ``'bars'`` mode - - max_unram_terms -- For rings with non-prime residue - fields, controls how many terms appear in the - coefficient of each pi^n when printing in 'series' or - 'bar' modes. + - ``max_unram_terms`` -- for rings with non-prime residue fields, + controls how many terms appear in the coefficient of each pi^n when + printing in ``'series'`` or ``'bar'`` modes - - max_terse_terms -- Controls the number of terms - appearing when printing polynomial representations in - 'terse' or 'val-unit' modes. + - ``max_terse_terms`` -- controls the number of terms appearing when + printing polynomial representations in ``'terse'`` or ``'val-unit'`` + modes - - sep -- Controls the separator used in 'bars' - mode. + - ``sep`` -- controls the separator used in ``'bars'`` mode - - alphabet -- Controls the alphabet used to translate - p-adic digits into strings (so that no separator need be - used in 'digits' mode). + - ``alphabet`` -- controls the alphabet used to translate `p`-adic digits + into strings (so that no separator need be used in ``'digits'`` mode) - - show_prec -- Specify how the precision is printed; it - can be 'none', 'bigoh' or 'dots' (the latter being not - available for all modes) + - ``show_prec`` -- Specify how the precision is printed; it can be + ``'none'``, ``'bigoh'`` or ``'dots'`` (the latter being not available + for all modes) TESTS:: @@ -522,7 +511,7 @@ cdef class pAdicPrinter_class(SageObject): (``max_unram_terms`` is irrelevant if the ring is totally ramified over the base, for example). This does not check if the rings are equal (to prevent infinite recursion in the comparison - functions of p-adic rings), but it does check if the primes + functions of `p`-adic rings), but it does check if the primes are the same (since the prime affects whether ``pos`` is relevant). @@ -665,7 +654,7 @@ cdef class pAdicPrinter_class(SageObject): def _pos(self): """ - Accesses self.pos. + Access ``self.pos``. EXAMPLES:: @@ -676,7 +665,7 @@ cdef class pAdicPrinter_class(SageObject): def _sep(self): """ - Accesses self.sep. + Access ``self.sep``. EXAMPLES:: @@ -687,7 +676,7 @@ cdef class pAdicPrinter_class(SageObject): def _alphabet(self): """ - Accesses self.pos. + Access ``self.pos``. EXAMPLES:: @@ -698,7 +687,7 @@ cdef class pAdicPrinter_class(SageObject): def _max_ram_terms(self): """ - Accesses self.max_ram_terms. + Access ``self.max_ram_terms``. EXAMPLES:: @@ -709,7 +698,7 @@ cdef class pAdicPrinter_class(SageObject): def _max_unram_terms(self): """ - Accesses self.max_unram_terms. + Access ``self.max_unram_terms``. EXAMPLES:: @@ -720,7 +709,7 @@ cdef class pAdicPrinter_class(SageObject): def _max_terse_terms(self): """ - Accesses self.max_terse_terms. + Access ``self.max_terse_terms``. EXAMPLES:: @@ -731,7 +720,7 @@ cdef class pAdicPrinter_class(SageObject): def _show_prec(self): """ - Accesses self.show_prec. + Access ``self.show_prec``. EXAMPLES:: @@ -742,7 +731,7 @@ cdef class pAdicPrinter_class(SageObject): def _ring(self): """ - Accesses self.ring. + Access ``self.ring``. EXAMPLES:: @@ -753,7 +742,7 @@ cdef class pAdicPrinter_class(SageObject): def _uniformizer_name(self): """ - Accesses self.ram_name. + Access ``self.ram_name``. EXAMPLES:: @@ -764,7 +753,7 @@ cdef class pAdicPrinter_class(SageObject): def _ram_name(self): """ - Accesses self.ram_name. + Access ``self.ram_name``. EXAMPLES:: @@ -775,7 +764,7 @@ cdef class pAdicPrinter_class(SageObject): def _print_mode(self): """ - Accesses self.mode. + Access ``self.mode``. EXAMPLES:: @@ -795,8 +784,7 @@ cdef class pAdicPrinter_class(SageObject): def _base_p_list(self, value, pos): """ - Returns a list of integers forming the base p expansion of - value. + Return a list of integers forming the base p expansion of value. If pos is True, these integers will be in the range [0,..., p-1]; if pos is False, they will be in the range @@ -820,8 +808,7 @@ cdef class pAdicPrinter_class(SageObject): cdef base_p_list(self, value, bint pos): """ - Returns a list of integers forming the base p expansion of - value. + Return a list of integers forming the base p expansion of value. If pos is True, these integers will be in the range [0,... p-1]; if po is False, they will be in the range @@ -851,10 +838,10 @@ cdef class pAdicPrinter_class(SageObject): INPUT: - - ``elt`` -- a p-adic element of the appropriate ring to print. + - ``elt`` -- a `p`-adic element of the appropriate ring to print - ``do_latex`` -- whether to return a latex representation or - a normal one. + a normal one EXAMPLES:: @@ -898,7 +885,8 @@ cdef class pAdicPrinter_class(SageObject): cdef _repr_gen(self, pAdicGenericElement elt, bint do_latex, bint pos, int mode, ram_name): r""" - Prints a string representation of the element. See __init__ for more details on print modes. + Print a string representation of the element. See ``__init__`` for + more details on print modes. EXAMPLES:: @@ -1275,7 +1263,7 @@ cdef class pAdicPrinter_class(SageObject): cdef _var(self, x, exp, do_latex): """ - Returns a representation of 'x^exp', latexed if necessary. + Return a representation of 'x^exp', latexed if necessary. """ if exp == 0: return "1" @@ -1288,7 +1276,7 @@ cdef class pAdicPrinter_class(SageObject): cdef _dot_var(self, x, exp, do_latex): """ - Returns a representation of '*x^exp', latexed if necessary. + Return a representation of '*x^exp', latexed if necessary. """ if exp == 0: return "" @@ -1304,7 +1292,7 @@ cdef class pAdicPrinter_class(SageObject): cdef _co_dot_var(self, co, x, exp, do_latex): """ - Returns a representation of 'co*x^exp', latexed if necessary. + Return a representation of 'co*x^exp', latexed if necessary. co should be greater than 0 """ @@ -1329,7 +1317,7 @@ cdef class pAdicPrinter_class(SageObject): cdef _plus_ellipsis(self, bint do_latex): """ - Returns a representation of '+ ...', latexed if necessary. + Return a representation of '+ ...', latexed if necessary. """ if do_latex: return " + \\cdots" @@ -1338,7 +1326,7 @@ cdef class pAdicPrinter_class(SageObject): cdef _ellipsis(self, bint do_latex): """ - Returns a representation of '...', latexed if necessary. + Return a representation of '...', latexed if necessary. """ if do_latex: return "\\cdots" @@ -1347,21 +1335,21 @@ cdef class pAdicPrinter_class(SageObject): cdef _truncate_list(self, L, max_terms, zero): """ - Takes a list L of coefficients and returns a list with at most max_terms nonzero terms. + Take a list L of coefficients and returns a list with at most max_terms nonzero terms. INPUT: - - L -- a list + - ``L`` -- list - - max_terms -- nonnegative integer (or -1, in which case + - ``max_terms`` -- nonnegative integer (or -1, in which case no truncation occurs) - - zero -- what should be considered zero, usually 0 or []. + - ``zero`` -- what should be considered zero, usually 0 or [] OUTPUT: - - Truncated list -- later terms are removed. - - Boolean -- whether any truncation occurred. + - truncated list; later terms are removed + - boolean; whether any truncation occurred """ if max_terms == -1 or len(L) == 0: return list(L), False @@ -1379,25 +1367,24 @@ cdef class pAdicPrinter_class(SageObject): cdef _print_unram_term(self, L, bint do_latex, polyname, long max_unram_terms, long expshift, bint increasing): """ - Returns a string representation of L when considered as a polynomial, truncating to at most max_unram_terms nonzero terms. + Return a string representation of L when considered as a polynomial, + truncating to at most ``max_unram_terms`` nonzero terms. INPUT: - - L -- A list of coefficients. + - ``L`` -- a list of coefficients - - do_latex -- whether to print latex-style. + - ``do_latex`` -- whether to print latex-style - - polyname -- the name for the variable. + - ``polyname`` -- the name for the variable - - max_unram_terms -- a maximum number of terms before + - ``max_unram_terms`` -- a maximum number of terms before truncation occurs and an ellipsis is added. -1 indicates no truncation should happen. - - expshift -- a shift for all the exponents of the - variable. + - ``expshift`` -- a shift for all the exponents of the variable - - increasing -- Whether to order the exponents in - increasing fashion. + - ``increasing`` -- whether to order the exponents in increasing fashion """ s = "" cdef Py_ssize_t j, newj @@ -1414,7 +1401,7 @@ cdef class pAdicPrinter_class(SageObject): return s else: count += 1 - if count == max_unram_terms: #this will never trigger if max_unram_terms == -1 + if count == max_unram_terms: # this will never trigger if max_unram_terms == -1 newj = len(L) - 1 while L[newj] == 0: newj -= 1 @@ -1437,7 +1424,7 @@ cdef class pAdicPrinter_class(SageObject): return s else: count += 1 - if count == max_unram_terms: #this will never trigger if max_unram_terms == -1 + if count == max_unram_terms: # this will never trigger if max_unram_terms == -1 newj = 0 while L[newj] == 0: newj += 1 @@ -1452,7 +1439,7 @@ cdef class pAdicPrinter_class(SageObject): cdef _terse_frac(self, a, v, u, ram_name, bint do_latex): """ - Returns a representation of a=u/ram_name^v, latexed if necessary. + Return a representation of 'a=u/ram_name^v', latexed if necessary. """ if do_latex: if v >= 0: @@ -1472,21 +1459,19 @@ cdef class pAdicPrinter_class(SageObject): cdef _print_list_as_poly(self, L, bint do_latex, polyname, long expshift, bint increasing): """ - Prints a list L as a polynomial. + Print a list ``L`` as a polynomial. INPUT: - - L -- A list of coefficients. + - ``L`` -- a list of coefficients - - do_latex -- whether to print latex-style. + - ``do_latex`` -- whether to print latex-style - - polyname -- the name for the variable. + - ``polyname`` -- the name for the variable - - expshift -- a shift for all the exponents of the - variable. + - ``expshift`` -- a shift for all the exponents of the variable - - increasing -- Whether to order the exponents in - increasing fashion. + - ``increasing`` -- whether to order the exponents in increasing fashion """ s = "" cdef Py_ssize_t j diff --git a/src/sage/rings/padics/padic_relaxed_errors.pyx b/src/sage/rings/padics/padic_relaxed_errors.pyx index 2157234f62b..5a7938db5f3 100644 --- a/src/sage/rings/padics/padic_relaxed_errors.pyx +++ b/src/sage/rings/padics/padic_relaxed_errors.pyx @@ -30,10 +30,10 @@ def raise_error(error, permissive=False): INPUT: - - ``error`` -- an integer; the error code + - ``error`` -- integer; the error code - - ``permissive`` -- a boolean (default: ``False``); if ``True``, - do not raise weak errors (precision, abandon). + - ``permissive`` -- boolean (default: ``False``); if ``True``, + do not raise weak errors (precision, abandon) TESTS:: @@ -50,7 +50,6 @@ def raise_error(error, permissive=False): PrecisionError: computation has been abandoned; try to increase precision sage: raise_error(1, permissive=True) - """ if error & ERROR_UNEXPECTED: raise RuntimeError("error code = %s" % error) diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi index a3b203845b5..c842d9934cd 100644 --- a/src/sage/rings/padics/padic_template_element.pxi +++ b/src/sage/rings/padics/padic_template_element.pxi @@ -46,11 +46,11 @@ cdef long minusmaxordp = -maxordp cdef inline int check_ordp(long ordp) except -1: """ - Checks for overflow after addition or subtraction of valuations. + Check for overflow after addition or subtraction of valuations. There is another variant, :meth:`check_ordp_mpz`, for ``mpz_t`` input. - If overflow is detected, raises a OverflowError. + If overflow is detected, raises a :exc:`OverflowError`. """ if ordp >= maxordp or ordp <= minusmaxordp: raise OverflowError("valuation overflow") @@ -64,8 +64,8 @@ cdef class pAdicTemplateElement(pAdicGenericElement): - ``parent`` -- a local ring or field - ``x`` -- data defining this element. Various types are supported, - including ints, Integers, Rationals, PARI p-adics, integers mod `p^k` - and other Sage p-adics. + including ints, Integers, Rationals, PARI `p`-adics, integers mod `p^k` + and other Sage `p`-adics. - ``absprec`` -- a cap on the absolute precision of this element @@ -75,7 +75,6 @@ cdef class pAdicTemplateElement(pAdicGenericElement): sage: Zp(17)(17^3, 8, 4) 17^3 + O(17^7) - """ def __init__(self, parent, x, absprec=infinity, relprec=infinity): """ @@ -117,7 +116,6 @@ cdef class pAdicTemplateElement(pAdicGenericElement): Traceback (most recent call last): ... TypeError: no conversion between padics when prime numbers differ - """ self.prime_pow = parent.prime_pow pAdicGenericElement.__init__(self, parent) @@ -171,26 +169,26 @@ cdef class pAdicTemplateElement(pAdicGenericElement): cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1: """ - Sets this element from given data computed in :meth:`__init__`. + Set this element from given data computed in :meth:`__init__`. INPUT: - - ``x`` -- an int, Integer, Rational, PARI p-adic, integer mod `p^k` or Sage p-adic + - ``x`` -- an int, Integer, Rational, PARI `p`-adic, integer mod `p^k` or + Sage `p`-adic - - ``val`` -- a long, the valuation of ``x`` + - ``val`` -- a long; the valuation of ``x`` - - ``xprec`` -- a long, the cap on the absolute precision imposed by ``x`` + - ``xprec`` -- a long; the cap on the absolute precision imposed by ``x`` - - ``absprec`` -- an integer or infinity, a bound on the absolute precision - - - ``relprec`` -- an integer or infinity, a bound on the relative precision + - ``absprec`` -- integer or infinity; a bound on the absolute precision + - ``relprec`` -- integer or infinity; a bound on the relative precision """ raise NotImplementedError cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec): """ - Creates a new element with a given value and absolute precision. + Create a new element with a given value and absolute precision. Used by code that doesn't know the precision type. """ @@ -198,13 +196,13 @@ cdef class pAdicTemplateElement(pAdicGenericElement): cdef int _get_unit(self, celement value) except -1: """ - Sets ``value`` to the unit of this p-adic element. + Set ``value`` to the unit of this `p`-adic element. """ raise NotImplementedError def __lshift__(pAdicTemplateElement self, shift): """ - Multiplies ``self`` by ``pi^shift``. + Multiply ``self`` by ``pi^shift``. If ``shift`` is negative and this element does not lie in a field, digits may be truncated. See ``__rshift__`` for details. @@ -269,7 +267,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): def __rshift__(pAdicTemplateElement self, shift): """ - Divides by ``p^shift``, and truncates (if the parent is not a field). + Divide by ``p^shift``, and truncate (if the parent is not a field). EXAMPLES:: @@ -314,13 +312,13 @@ cdef class pAdicTemplateElement(pAdicGenericElement): cdef pAdicTemplateElement _rshift_c(self, long shift): """ - Divides by ``p^shift`` and truncates (if the parent is not a field). + Divide by ``p^shift`` and truncate (if the parent is not a field). """ raise NotImplementedError cdef int check_preccap(self) except -1: """ - Checks that this element doesn't have precision higher than allowed by + Check that this element doesn't have precision higher than allowed by the precision cap. """ raise NotImplementedError @@ -333,9 +331,9 @@ cdef class pAdicTemplateElement(pAdicGenericElement): INPUT: - - ``absprec`` -- an integer or ``None`` (default: ``None``); the + - ``absprec`` -- integer or ``None`` (default: ``None``); the absolute precision of the result. If ``None``, lifts to the maximum - precision allowed + precision allowed. .. NOTE:: @@ -368,7 +366,6 @@ cdef class pAdicTemplateElement(pAdicGenericElement): 5 sage: a.lift_to_precision(10000) 5 - """ if absprec is None: absprec = maxordp @@ -404,7 +401,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): Different lift modes affect the choice of `a_i`. When ``lift_mode`` is ``'simple'``, the resulting `a_i` will be - non-negative: if the residue field is `\GF{p}` then they + nonnegative: if the residue field is `\GF{p}` then they will be integers with `0 \le a_i < p`; otherwise they will be a list of integers in the same range giving the coefficients of a polynomial in the indeterminant representing the maximal @@ -421,14 +418,15 @@ cdef class pAdicTemplateElement(pAdicGenericElement): INPUT: - - ``n`` -- integer (default ``None``). If given, returns the corresponding - entry in the expansion. Can also accept a slice (see :meth:`slice`) + - ``n`` -- integer (default: ``None``); if given, returns the + corresponding entry in the expansion. Can also accept a slice (see + :meth:`slice`). - ``lift_mode`` -- ``'simple'``, ``'smallest'`` or ``'teichmuller'`` (default: ``'simple'``) - ``start_val`` -- start at this valuation rather than the - default (`0` or the valuation of this element). + default (`0` or the valuation of this element) OUTPUT: @@ -564,7 +562,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): def teichmuller_expansion(self, n = None): r""" - Returns an iterator over coefficients `a_0, a_1, \dots, a_n` such that + Return an iterator over coefficients `a_0, a_1, \dots, a_n` such that - `a_i^q = a_i`, where `q` is the cardinality of the residue field, @@ -588,8 +586,8 @@ cdef class pAdicTemplateElement(pAdicGenericElement): INPUT: - - ``n`` -- integer (default ``None``). If given, returns the - coefficient of `\pi^n` in the expansion. + - ``n`` -- integer (default: ``None``); if given, returns the + coefficient of `\pi^n` in the expansion EXAMPLES: @@ -611,7 +609,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): def _ext_p_list(self, pos): """ - Returns the p-adic expansion of the unit part. Used in printing. + Return the `p`-adic expansion of the unit part. Used in printing. EXAMPLES:: @@ -628,7 +626,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): cpdef pAdicTemplateElement unit_part(self): r""" - Returns the unit part of this element. + Return the unit part of this element. This is the `p`-adic element `u` in the same ring so that this element is `\pi^v u`, where `\pi` is a uniformizer and `v` is @@ -650,7 +648,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): INPUT: - - ``p`` -- a prime, which is compared with the parent of this element. + - ``p`` -- a prime, which is compared with the parent of this element EXAMPLES:: @@ -658,7 +656,6 @@ cdef class pAdicTemplateElement(pAdicGenericElement): True sage: a._is_base_elt(17) False - """ return self.prime_pow.prime == p and self.prime_pow.deg == 1 @@ -680,12 +677,12 @@ cdef class pAdicTemplateElement(pAdicGenericElement): INPUT: - - ``absprec`` -- ``0`` or ``1``. + - ``absprec`` -- ``0`` or ``1`` - - ``field`` -- boolean (default ``None``). For precision 1, whether to return + - ``field`` -- boolean (default: ``None``); for precision 1, whether to return an element of the residue field or a residue ring. Currently unused. - - ``check_prec`` -- boolean (default ``True``). Whether to raise an error if this + - ``check_prec`` -- boolean (default: ``True``); whether to raise an error if this element has insufficient precision to determine the reduction. Errors are never raised for fixed-mod or floating-point types. @@ -737,12 +734,12 @@ cdef class pAdicTemplateElement(pAdicGenericElement): sage: (a/3).residue() Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue """ if absprec < 0: raise ValueError("cannot reduce modulo a negative power of the uniformizer") if self.valuation() < 0: - raise ValueError("element must have non-negative valuation in order to compute residue") + raise ValueError("element must have nonnegative valuation in order to compute residue") R = self.parent() if check_prec and (R.is_fixed_mod() or R.is_floating_point()): check_prec = False @@ -772,16 +769,13 @@ cdef Integer exact_pow_helper(long *ansrelprec, long relprec, _right, PowCompute - ``ansrelprec`` -- (return value) the relative precision of the answer - - ``relprec`` -- a positive integer: the relative precision of the base + - ``relprec`` -- positive integer: the relative precision of the base - ``_right`` -- the exponent, nonzero - - ``prime_pow`` -- the Powcomputer for the ring. - - OUTPUT: - - an Integer congruent to the given exponent + - ``prime_pow`` -- the Powcomputer for the ring + OUTPUT: an Integer congruent to the given exponent """ cdef Integer right, p = prime_pow.prime cdef long exp_val @@ -806,14 +800,14 @@ cdef long padic_pow_helper(celement result, celement base, long base_val, long b """ INPUT: - - ``result`` -- the result of exponentiation. + - ``result`` -- the result of exponentiation - - ``base`` -- a celement, the base of the exponentiation. + - ``base`` -- a celement; the base of the exponentiation - - ``base_val`` -- a long, used to check that the base is a unit + - ``base_val`` -- a long; used to check that the base is a unit - - ``base_relprec`` -- a positive integer: the relative precision - of the base. + - ``base_relprec`` -- positive integer; the relative precision + of the base - ``right_unit`` -- the unit part of the exponent @@ -821,11 +815,9 @@ cdef long padic_pow_helper(celement result, celement base, long base_val, long b - ``right_relprec`` -- the relative precision of the exponent - - ``prime_pow`` -- the Powcomputer for the ring. - - OUTPUT: + - ``prime_pow`` -- the Powcomputer for the ring - the precision of the result + OUTPUT: the precision of the result EXAMPLES:: @@ -920,7 +912,7 @@ cdef class ExpansionIter(): def __cinit__(self, pAdicTemplateElement elt, long prec, expansion_mode mode): """ - Allocates memory for the iterator. + Allocate memory for the iterator. TESTS:: @@ -946,7 +938,7 @@ cdef class ExpansionIter(): def __dealloc__(self): """ - Deallocates memory for the iterator. + Deallocate memory for the iterator. TESTS:: @@ -1052,7 +1044,7 @@ cdef class ExpansionIterable(): def __cinit__(self, pAdicTemplateElement elt, long prec, long val_shift, expansion_mode mode): """ - Allocates memory for the iteratable. + Allocate memory for the iteratable. TESTS:: diff --git a/src/sage/rings/padics/padic_template_element_header.pxi b/src/sage/rings/padics/padic_template_element_header.pxi index 11e1cc7fab7..8ddcefd672c 100644 --- a/src/sage/rings/padics/padic_template_element_header.pxi +++ b/src/sage/rings/padics/padic_template_element_header.pxi @@ -1,6 +1,6 @@ """ This file provides the declaration for the pAdicTemplateElement class, -which collects common functionality for the different p-adic template +which collects common functionality for the different `p`-adic template classes. It is included in CR_template_header.pxi, CA_template_header.pxi and diff --git a/src/sage/rings/padics/padic_valuation.py b/src/sage/rings/padics/padic_valuation.py index 1cf29093ba6..1050055e1fb 100644 --- a/src/sage/rings/padics/padic_valuation.py +++ b/src/sage/rings/padics/padic_valuation.py @@ -48,6 +48,7 @@ from sage.rings.infinity import infinity + class PadicValuationFactory(UniqueFactory): r""" Create a ``prime``-adic valuation on ``R``. @@ -105,7 +106,6 @@ class PadicValuationFactory(UniqueFactory): :meth:`pAdicGeneric.valuation() `, :meth:`RationalField.valuation() `, :meth:`IntegerRing_class.valuation() `. - """ def create_key_and_extra_args(self, R, prime=None, approximants=None): r""" @@ -116,13 +116,12 @@ def create_key_and_extra_args(self, R, prime=None, approximants=None): sage: QQ.valuation(2) # indirect doctest 2-adic valuation - """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.number_field.number_field_base import NumberField - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic if R.characteristic() != 0: # We do not support equal characteristic yet @@ -132,7 +131,7 @@ def create_key_and_extra_args(self, R, prime=None, approximants=None): return self.create_key_for_integers(R, prime), {} elif isinstance(R, pAdicGeneric): return self.create_key_for_local_ring(R, prime), {} - elif isinstance(R.fraction_field(), NumberField) or is_PolynomialQuotientRing(R): + elif isinstance(R.fraction_field(), NumberField) or isinstance(R, PolynomialQuotientRing_generic): return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants) else: raise NotImplementedError("p-adic valuations not implemented for %r" % (R,)) @@ -146,7 +145,6 @@ def create_key_for_integers(self, R, prime): sage: QQ.valuation(2) # indirect doctest 2-adic valuation - """ from sage.rings.integer_ring import ZZ if prime is None: @@ -167,7 +165,6 @@ def create_key_for_local_ring(self, R, prime): sage: Qp(2).valuation() # indirect doctest 2-adic valuation - """ # We do not care much about the value of prime since there is only one # reasonable p-adic valuation here @@ -189,7 +186,6 @@ def create_key_and_extra_args_for_number_field(self, R, prime, approximants): sage: GaussianIntegers().valuation(2) # indirect doctest # needs sage.rings.number_field 2-adic valuation - """ K, L, G = self._normalize_number_field_data(R) @@ -230,7 +226,6 @@ def create_key_and_extra_args_for_number_field_from_valuation(self, R, v, prime, sage: R. = QQ[] sage: S = R.quo(x^2 + 1) sage: v = valuations.pAdicValuation(S, v) # needs sage.geometry.polyhedron - """ K, L, G = self._normalize_number_field_data(R) @@ -306,7 +301,6 @@ def create_key_and_extra_args_for_number_field_from_ideal(self, R, I, prime): sage: K. = NumberField([x^2 - 2, x^2 + x + 1]) sage: K.valuation(2) 2-adic valuation - """ K, L, G = self._normalize_number_field_data(R) @@ -360,15 +354,14 @@ def _normalize_number_field_data(self, R): (Rational Field, Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1, x^2 + 1) - """ - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic from sage.rings.number_field.number_field_base import NumberField if isinstance(R.fraction_field(), NumberField): L = R.fraction_field() G = L.relative_polynomial() K = L.base_ring() - elif is_PolynomialQuotientRing(R): + elif isinstance(R, PolynomialQuotientRing_generic): from sage.categories.number_fields import NumberFields if R.base_ring().fraction_field() not in NumberFields(): raise NotImplementedError("cannot normalize quotients over %r" % (R.base_ring(),)) @@ -388,13 +381,12 @@ def create_object(self, version, key, **extra_args): sage: ZZ.valuation(5) # indirect doctest 5-adic valuation - """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic from sage.rings.number_field.number_field_base import NumberField R = key[0] parent = DiscretePseudoValuationSpace(R) @@ -412,7 +404,7 @@ def create_object(self, version, key, **extra_args): K = R.fraction_field() if isinstance(K, NumberField): G = K.relative_polynomial() - elif is_PolynomialQuotientRing(R): + elif isinstance(R, PolynomialQuotientRing_generic): G = R.modulus() else: raise NotImplementedError @@ -453,7 +445,6 @@ class pAdicValuation_base(DiscreteValuation): sage: TestSuite(ZZ.valuation(3)).run() # long time # needs sage.geometry.polyhedron sage: TestSuite(QQ.valuation(5)).run() # long time # needs sage.geometry.polyhedron sage: TestSuite(Zp(5).valuation()).run() # long time # needs sage.geometry.polyhedron - """ def __init__(self, parent, p): r""" @@ -462,7 +453,6 @@ def __init__(self, parent, p): sage: from sage.rings.padics.padic_valuation import pAdicValuation_base sage: isinstance(ZZ.valuation(3), pAdicValuation_base) True - """ DiscreteValuation.__init__(self, parent) @@ -477,7 +467,6 @@ def p(self): sage: GaussianIntegers().valuation(2).p() # needs sage.rings.number_field 2 - """ return self._p @@ -489,21 +478,18 @@ def reduce(self, x): - ``x`` -- an element in the domain of this valuation - OUTPUT: - - An element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`. + OUTPUT: an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field` EXAMPLES:: sage: v = ZZ.valuation(3) sage: v.reduce(4) 1 - """ x = self.domain().coerce(x) if self(x) < 0: - raise ValueError("reduction is only defined for elements of non-negative valuation") + raise ValueError("reduction is only defined for elements of nonnegative valuation") return self.residue_field()(x) @@ -521,7 +507,6 @@ def lift(self, x): sage: xbar = v.reduce(4) sage: v.lift(xbar) 1 - """ x = self.residue_field().coerce(x) @@ -536,11 +521,11 @@ def is_unramified(self, G, include_steps=False, assume_squarefree=False): - ``G`` -- a monic squarefree polynomial over the domain of this valuation - - ``include_steps`` -- a boolean (default: ``False``); whether to + - ``include_steps`` -- boolean (default: ``False``); whether to include the approximate valuations that were used to determine the - result in the return value. + result in the return value - - ``assume_squarefree`` -- a boolean (default: ``False``); whether to + - ``assume_squarefree`` -- boolean (default: ``False``); whether to assume that ``G`` is square-free over the completion of the domain of this valuation. Setting this to ``True`` can significantly improve the performance. @@ -566,12 +551,11 @@ def is_unramified(self, G, include_steps=False, assume_squarefree=False): sage: v.is_unramified(x^2 + 2*x + 4) # needs sage.geometry.polyhedron True - """ R = G.parent() - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if not is_PolynomialRing(R) or R.base_ring() is not self.domain() or not G.is_monic(): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if not isinstance(R, PolynomialRing_general) or R.base_ring() is not self.domain() or not G.is_monic(): raise ValueError("G must be a monic univariate polynomial over the domain of this valuation") if not assume_squarefree and not G.is_squarefree(): raise ValueError("G must be squarefree") @@ -613,11 +597,11 @@ def is_totally_ramified(self, G, include_steps=False, assume_squarefree=False): - ``G`` -- a monic squarefree polynomial over the domain of this valuation - - ``include_steps`` -- a boolean (default: ``False``); where to include + - ``include_steps`` -- boolean (default: ``False``); where to include the valuations produced during the process of checking whether ``G`` is totally ramified in the return value - - ``assume_squarefree`` -- a boolean (default: ``False``); whether to + - ``assume_squarefree`` -- boolean (default: ``False``); whether to assume that ``G`` is square-free over the completion of the domain of this valuation. Setting this to ``True`` can significantly improve the performance. @@ -664,12 +648,11 @@ def is_totally_ramified(self, G, include_steps=False, assume_squarefree=False): sage: f = x^9 + 9*x^2 + 3 sage: R.valuation().is_totally_ramified(f) # needs sage.geometry.polyhedron True - """ R = G.parent() - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if not is_PolynomialRing(R) or R.base_ring() is not self.domain() or not G.is_monic(): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if not isinstance(R, PolynomialRing_general) or R.base_ring() is not self.domain() or not G.is_monic(): raise ValueError("G must be a monic univariate polynomial over the domain of this valuation") if not assume_squarefree and not G.is_squarefree(): raise ValueError("G must be squarefree") @@ -711,7 +694,6 @@ def change_domain(self, ring): sage: v = ZZ.valuation(2) sage: v.change_domain(QQ).domain() Rational Field - """ return pAdicValuation(ring, self.p()) @@ -725,7 +707,6 @@ def _extensions_to_quotient(self, ring, approximants=None): sage: R. = QQ[] sage: QQ.valuation(2)._extensions_to_quotient(R.quo(x^2 + x + 1)) [2-adic valuation] - """ approximants = approximants or self.mac_lane_approximants(ring.modulus().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True) return [pAdicValuation(ring, approximant, approximants) for approximant in approximants] @@ -791,7 +772,6 @@ def extensions(self, ring): sage: v.extensions(L) [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation, [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation] - """ if self.domain() is ring: return [self] @@ -800,9 +780,9 @@ def extensions(self, ring): if domain_fraction_field.is_subring(ring): return pAdicValuation(domain_fraction_field, self).extensions(ring) if self.domain().is_subring(ring): - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing - if is_PolynomialQuotientRing(ring): - if is_PolynomialQuotientRing(self.domain()): + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic + if isinstance(ring, PolynomialQuotientRing_generic): + if isinstance(self.domain(), PolynomialQuotientRing_generic): if self.domain().modulus() == ring.modulus(): base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field())) return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions] @@ -830,7 +810,6 @@ def restriction(self, ring): sage: v = GaussianIntegers().valuation(2) # needs sage.rings.number_field sage: v.restriction(ZZ) # needs sage.rings.number_field 2-adic valuation - """ if ring is self.domain(): return self @@ -850,7 +829,6 @@ def value_semigroup(self): sage: v = GaussianIntegers().valuation(2) # needs sage.rings.number_field sage: v.value_semigroup() # needs sage.rings.number_field Additive Abelian Semigroup generated by 1/2 - """ from sage.categories.fields import Fields v = self(self.uniformizer()) @@ -876,7 +854,6 @@ class pAdicValuation_padic(pAdicValuation_base): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def __init__(self, parent): """ @@ -885,7 +862,6 @@ def __init__(self, parent): sage: from sage.rings.padics.padic_valuation import pAdicValuation_padic sage: isinstance(Qp(2).valuation(), pAdicValuation_padic) True - """ pAdicValuation_base.__init__(self, parent, parent.domain().prime()) @@ -897,16 +873,13 @@ def reduce(self, x): - ``x`` -- an element of the domain of this valuation - OUTPUT: - - An element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`. + OUTPUT: an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field` EXAMPLES:: sage: R = Zp(3) sage: Zp(3).valuation().reduce(R(4)) 1 - """ x = self.domain().coerce(x) return self.residue_field()(x.residue()) @@ -927,7 +900,6 @@ def lift(self, x): sage: xbar = v.reduce(R(4)) sage: v.lift(xbar) 1 + O(3^20) - """ x = self.residue_field().coerce(x) return self.domain()(x).lift_to_precision() @@ -941,7 +913,6 @@ def uniformizer(self): sage: v = Zp(3).valuation() sage: v.uniformizer() 3 + O(3^21) - """ return self.domain().uniformizer() @@ -966,7 +937,6 @@ def element_with_valuation(self, v): sage: L. = K.extension(y^2 + 3*y + 3) sage: L.valuation().element_with_valuation(3/2) y^3 + O(y^43) - """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -984,7 +954,6 @@ def _repr_(self): sage: ZZ.valuation(3)._repr_() '3-adic valuation' - """ return "%s-adic valuation" % (self.p()) @@ -999,7 +968,6 @@ def _call_(self, x): sage: L. = K.extension(y^2 - 3) # needs sage.libs.ntl sage: L.valuation()(3) # needs sage.libs.ntl 1 - """ return x.ordp() @@ -1011,7 +979,6 @@ def residue_ring(self): sage: Qq(9, names='a').valuation().residue_ring() # needs sage.libs.ntl Finite Field in a0 of size 3^2 - """ return self.domain().residue_field() @@ -1020,7 +987,7 @@ def shift(self, x, s): Shift ``x`` in its expansion with respect to :meth:`uniformizer` by ``s`` "digits". - For non-negative ``s``, this just returns ``x`` multiplied by a + For nonnegative ``s``, this just returns ``x`` multiplied by a power of the uniformizer `\pi`. For negative ``s``, it does the same but when not over a field, it @@ -1042,7 +1009,6 @@ def shift(self, x, s): sage: v = S.valuation() sage: v.shift(1, 5) y^5 + O(y^60) - """ x = self.domain().coerce(x) s = self.value_group()(s) @@ -1073,7 +1039,6 @@ def simplify(self, x, error=None, force=False): 2 + O(2^21) sage: v.simplify(6, error=0) 0 - """ x = self.domain().coerce(x) @@ -1100,7 +1065,6 @@ class pAdicValuation_int(pAdicValuation_base): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def _repr_(self): """ @@ -1110,7 +1074,6 @@ def _repr_(self): sage: ZZ.valuation(3)._repr_() '3-adic valuation' - """ return "%s-adic valuation" % (self.p()) @@ -1120,13 +1083,12 @@ def _call_(self, x): INPUT: - - ``x`` -- an element in the domain of this valuation + - ``x`` -- an element in the domain of this valuation EXAMPLES:: sage: ZZ.valuation(3)(9) 2 - """ if x.is_zero(): # x.valuation() is a factor 10 slower when computing the valuation @@ -1145,7 +1107,6 @@ def uniformizer(self): sage: v = ZZ.valuation(3) sage: v.uniformizer() 3 - """ return self.domain()(self.p()) @@ -1158,7 +1119,6 @@ def residue_ring(self): sage: v = ZZ.valuation(3) sage: v.residue_ring() Finite Field of size 3 - """ from sage.rings.finite_rings.finite_field_constructor import GF return GF(self.p()) @@ -1174,7 +1134,6 @@ def _ge_(self, other): sage: w = valuations.TrivialValuation(ZZ) sage: v >= w True - """ if other.is_trivial(): return other.is_discrete_valuation() @@ -1201,7 +1160,6 @@ def _relative_size(self, x): 1 sage: v._relative_size(2**20) 11 - """ x = self.domain().coerce(x) return (x.numerator().nbits() + x.denominator().nbits())//self.p().nbits() @@ -1246,7 +1204,6 @@ def simplify(self, x, error=None, force=False, size_heuristic_bound=32): Traceback (most recent call last): ... ArithmeticError: rational reconstruction of 55203 (mod 65536) does not exist - """ if not force and self._relative_size(x) <= size_heuristic_bound: return x @@ -1328,7 +1285,6 @@ def inverse(self, x, precision): sage: v.inverse(2, 0) 1 - """ if not x.is_zero(): y = ~x @@ -1365,7 +1321,6 @@ class pAdicFromLimitValuation(FiniteExtensionFromLimitValuation, pAdicValuation_ sage: v.shift(1, -1).parent() # needs sage.rings.number_field Number Field in I with defining polynomial x^2 + 1 with I = 1*I - """ def __init__(self, parent, approximant, G, approximants): r""" @@ -1375,7 +1330,6 @@ def __init__(self, parent, approximant, G, approximants): sage: from sage.rings.padics.padic_valuation import pAdicFromLimitValuation sage: isinstance(v, pAdicFromLimitValuation) # needs sage.rings.number_field True - """ FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants) pAdicValuation_base.__init__(self, parent, approximant.restriction(approximant.domain().base_ring()).p()) @@ -1404,7 +1358,6 @@ def _to_base_domain(self, f): sage: w = v.extension(L).extension(M) sage: w._to_base_domain(b) x - """ polynomial = f.lift() return polynomial(self._base_valuation.domain().gen()) @@ -1419,7 +1372,6 @@ def _from_base_domain(self, f): sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field sage: v._from_base_domain(v._base_valuation.domain().gen()) # needs sage.rings.number_field I - """ return self.domain()(f) @@ -1432,7 +1384,6 @@ def extensions(self, ring): sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field sage: v.extensions(v.domain().fraction_field()) # needs sage.rings.number_field [3-adic valuation] - """ if ring is self.domain().fraction_field(): if self.domain() is not self.domain().fraction_field(): @@ -1441,6 +1392,7 @@ def extensions(self, ring): return [pAdicValuation(ring, approximant)] return super().extensions(ring) + def _fraction_field(ring): r""" Return a fraction field of ``ring``. @@ -1457,14 +1409,13 @@ def _fraction_field(ring): sage: from sage.rings.padics.padic_valuation import _fraction_field sage: _fraction_field(S) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 - """ from sage.categories.fields import Fields if ring in Fields(): return ring - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing - if is_PolynomialQuotientRing(ring): + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic + if isinstance(ring, PolynomialQuotientRing_generic): from sage.categories.integral_domains import IntegralDomains if ring in IntegralDomains(): return ring.base().change_ring(ring.base_ring().fraction_field()).quo(ring.modulus()) diff --git a/src/sage/rings/padics/pow_computer.pyx b/src/sage/rings/padics/pow_computer.pyx index dda423f4a0f..9719dfa1efe 100644 --- a/src/sage/rings/padics/pow_computer.pyx +++ b/src/sage/rings/padics/pow_computer.pyx @@ -9,8 +9,8 @@ PowComputer A class for computing and caching powers of the same integer. -This class is designed to be used as a field of p-adic rings and -fields. Since elements of p-adic rings and fields need to use powers +This class is designed to be used as a field of `p`-adic rings and +fields. Since elements of `p`-adic rings and fields need to use powers of p over and over, this class precomputes and stores powers of p. There is no reason that the base has to be prime however. @@ -69,26 +69,26 @@ cdef class PowComputer_class(SageObject): def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly=None, shift_seed=None): """ - Initializes self. + Initialize ``self``. INPUT: - * prime -- the prime that is the base of the exponentials - stored in this pow_computer. + - ``prime`` -- the prime that is the base of the exponentials + stored in this ``pow_computer`` - * cache_limit -- how high to cache powers of prime. + - ``cache_limit`` -- how high to cache powers of prime - * prec_cap -- data stored for p-adic elements using this - pow_computer (so they have C-level access to fields - common to all elements of the same parent). + - ``prec_cap`` -- data stored for `p`-adic elements using this + ``pow_computer`` (so they have C-level access to fields + common to all elements of the same parent) - * ram_prec_cap -- prec_cap * e + - ``ram_prec_cap`` -- prec_cap * e - * in_field -- same idea as prec_cap + - ``in_field`` -- same idea as prec_cap - * poly -- same idea as prec_cap + - ``poly`` -- same idea as prec_cap - * shift_seed -- same idea as prec_cap + - ``shift_seed`` -- same idea as prec_cap EXAMPLES:: @@ -105,7 +105,7 @@ cdef class PowComputer_class(SageObject): def __richcmp__(self, other, int op): """ - Compares ``self`` to ``other``. + Compare ``self`` to ``other``. EXAMPLES:: @@ -148,7 +148,7 @@ cdef class PowComputer_class(SageObject): cdef Integer pow_Integer(self, long n): """ - Returns self.prime^n + Return ``self.prime^n``. EXAMPLES:: @@ -162,7 +162,7 @@ cdef class PowComputer_class(SageObject): def pow_Integer_Integer(self, n): """ - Tests the pow_Integer function. + Test the ``pow_Integer`` function. EXAMPLES:: @@ -247,14 +247,14 @@ cdef class PowComputer_class(SageObject): m = Integer(m) n = Integer(n) if m < 0 or n < 0: - raise ValueError("m, n must be non-negative") + raise ValueError("m, n must be nonnegative") cdef Integer ans = PY_NEW(Integer) mpz_mul(ans.value, self.pow_mpz_t_tmp(mpz_get_ui((m).value)), self.pow_mpz_t_tmp(mpz_get_ui((n).value))) return ans def _pow_mpz_t_tmp_test(self, n): """ - Tests the pow_mpz_t_tmp function. + Test the ``pow_mpz_t_tmp`` function. EXAMPLES:: @@ -286,7 +286,7 @@ cdef class PowComputer_class(SageObject): cdef mpz_srcptr pow_mpz_t_top(self) noexcept: """ - Returns a pointer to self.prime^self.prec_cap as an ``mpz_srcptr``. + Return a pointer to ``self.prime^self.prec_cap`` as an ``mpz_srcptr``. EXAMPLES:: @@ -298,7 +298,7 @@ cdef class PowComputer_class(SageObject): def _pow_mpz_t_top_test(self): """ - Tests the pow_mpz_t_top function. + Test the ``pow_mpz_t_top`` function. EXAMPLES:: @@ -317,7 +317,7 @@ cdef class PowComputer_class(SageObject): def _repr_(self): """ - Returns a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -328,7 +328,7 @@ cdef class PowComputer_class(SageObject): def _prime(self): """ - Returns the base that the PowComputer is exponentiating. + Return the base that the ``PowComputer`` is exponentiating. EXAMPLES:: @@ -340,7 +340,7 @@ cdef class PowComputer_class(SageObject): def _in_field(self): """ - Returns whether or not self is attached to a field. + Return whether or not ``self`` is attached to a field. EXAMPLES:: @@ -352,7 +352,7 @@ cdef class PowComputer_class(SageObject): def _cache_limit(self): """ - Returns the limit to which powers of prime are computed. + Return the limit to which powers of prime are computed. EXAMPLES:: @@ -367,8 +367,8 @@ cdef class PowComputer_class(SageObject): def _prec_cap(self): """ - Returns prec_cap, a single value that for which - ``self._prime()^prec_cap`` is stored + Return ``prec_cap``, a single value that for which + ``self._prime()^prec_cap`` is stored. EXAMPLES:: @@ -383,7 +383,7 @@ cdef class PowComputer_class(SageObject): def _top_power(self): """ - Returns ``self._prime()^self._prec_cap()`` + Return ``self._prime()^self._prec_cap()``. EXAMPLES:: @@ -398,7 +398,7 @@ cdef class PowComputer_class(SageObject): def __call__(self, n): """ - Returns ``self.prime^n``. + Return ``self.prime^n``. EXAMPLES:: @@ -434,14 +434,13 @@ cdef class PowComputer_class(SageObject): cdef class PowComputer_base(PowComputer_class): def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly=None, shift_seed=None): """ - Allocates a PowComputer_base. + Allocate a ``PowComputer_base``. EXAMPLES:: sage: PC = PowComputer(5, 7, 10) sage: PC(3) 125 - """ cdef Py_ssize_t i @@ -558,7 +557,7 @@ cdef class PowComputer_base(PowComputer_class): cdef mpz_srcptr pow_mpz_t_top(self) noexcept: """ - Returns a pointer to self.prime^self.prec_cap as an ``mpz_srcptr``. + Return a pointer to ``self.prime^self.prec_cap`` as an ``mpz_srcptr``. EXAMPLES:: @@ -570,7 +569,7 @@ cdef class PowComputer_base(PowComputer_class): cdef mpz_srcptr pow_mpz_t_tmp(self, long n) except NULL: """ - Computes self.prime^n. + Compute ``self.prime^n``. EXAMPLES:: @@ -580,11 +579,10 @@ cdef class PowComputer_base(PowComputer_class): sage: PC._pow_mpz_t_tmp_test(-1) Traceback (most recent call last): ... - ValueError: n must be non-negative - + ValueError: n must be nonnegative """ if n < 0: - raise ValueError("n must be non-negative") + raise ValueError("n must be nonnegative") if n <= self.cache_limit: return self.small_powers[n] if n == self.prec_cap: @@ -603,7 +601,7 @@ cdef class PowComputer_base(PowComputer_class): pow_comp_cache = {} cdef PowComputer_base PowComputer_c(Integer m, Integer cache_limit, Integer prec_cap, in_field, prec_type=None): """ - Returns a PowComputer. + Return a ``PowComputer``. EXAMPLES:: @@ -612,9 +610,9 @@ cdef PowComputer_base PowComputer_c(Integer m, Integer cache_limit, Integer prec 81 """ if cache_limit < 0: - raise ValueError("cache_limit must be non-negative") + raise ValueError("cache_limit must be nonnegative") if prec_cap < 0: - raise ValueError("prec_cap must be non-negative") + raise ValueError("prec_cap must be nonnegative") if mpz_cmp_si((prec_cap).value, maxpreccap) >= 0: raise ValueError("cannot create p-adic parents with precision cap larger than (1 << (sizeof(long)*8 - 2))") @@ -642,18 +640,17 @@ cdef PowComputer_base PowComputer_c(Integer m, Integer cache_limit, Integer prec def PowComputer(m, cache_limit, prec_cap, in_field = False, prec_type=None): r""" - Returns a PowComputer that caches the values `1, m, m^2, \ldots, m^{C}`, + Return a ``PowComputer`` that caches the values `1, m, m^2, \ldots, m^{C}`, where `C` is ``cache_limit``. - Once you create a PowComputer, merely call it to get values out. + Once you create a ``PowComputer``, merely call it to get values out. - You can input any integer, even if it's outside of the precomputed - range. + You can input any integer, even if it's outside of the precomputed range. INPUT: - * m -- An integer, the base that you want to exponentiate. - * cache_limit -- A positive integer that you want to cache powers up to. + - ``m`` -- integer; the base that you want to exponentiate + - ``cache_limit`` -- positive integer; that you want to cache powers up to EXAMPLES:: diff --git a/src/sage/rings/padics/pow_computer_ext.pyx b/src/sage/rings/padics/pow_computer_ext.pyx index 6978a9435b5..389bd0bb20d 100644 --- a/src/sage/rings/padics/pow_computer_ext.pyx +++ b/src/sage/rings/padics/pow_computer_ext.pyx @@ -8,7 +8,7 @@ """ PowComputer_ext -The classes in this file are designed to be attached to p-adic parents +The classes in this file are designed to be attached to `p`-adic parents and elements for Cython access to properties of the parent. In addition to storing the defining polynomial (as an NTL polynomial) @@ -86,7 +86,7 @@ cdef int ZZ_pX_Eis_init(PowComputer_ZZ_pX prime_pow, ntl_ZZ_pX shift_seed) excep INPUT: - ``prime_pow`` -- the PowComputer to be initialized - - ``shift_seed`` -- x^e/p as a polynomial of degree at most e-1 in x. + - ``shift_seed`` -- x^e/p as a polynomial of degree at most e-1 in x EXAMPLES:: @@ -269,7 +269,8 @@ cdef int ZZ_pX_Eis_init(PowComputer_ZZ_pX prime_pow, ntl_ZZ_pX shift_seed) excep def ZZ_pX_eis_shift_test(_shifter, _a, _n, _finalprec): """ - Shifts _a right _n x-adic digits, where x is considered modulo the polynomial in _shifter. + Shift ``_a`` right ``_n`` x-adic digits, where x is considered modulo the + polynomial in ``_shifter``. EXAMPLES:: @@ -463,7 +464,7 @@ cdef int ZZ_pX_eis_shift_p(PowComputer_ZZ_pX self, ZZ_pX_c* x, ZZ_pX_c* a, long cdef class PowComputer_ext(PowComputer_class): def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ - Constructs the storage for powers of prime as ZZ_c's. + Construct the storage for powers of prime as ZZ_c's. EXAMPLES:: @@ -509,7 +510,7 @@ cdef class PowComputer_ext(PowComputer_class): def __repr__(self): """ - Returns a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -576,7 +577,7 @@ cdef class PowComputer_ext(PowComputer_class): 625 """ if n < 0: - raise ValueError("n must be non-negative") + raise ValueError("n must be nonnegative") if n <= self.cache_limit: ZZ_to_mpz(self.temp_m, &(self.small_powers[n])) elif n == self.prec_cap: @@ -613,7 +614,7 @@ cdef class PowComputer_ext(PowComputer_class): 625 """ if n < 0: - raise ValueError("n must be non-negative") + raise ValueError("n must be nonnegative") if n <= self.cache_limit: return &(self.small_powers[n]) if n == self.prec_cap: @@ -623,7 +624,7 @@ cdef class PowComputer_ext(PowComputer_class): def _pow_ZZ_tmp_test(self, n): """ - Tests the pow_ZZ_tmp function + Test the ``pow_ZZ_tmp`` function. EXAMPLES:: @@ -670,14 +671,14 @@ cdef class PowComputer_ext(PowComputer_class): m = Integer(m) n = Integer(n) if m < 0 or n < 0: - raise ValueError("m, n must be non-negative") + raise ValueError("m, n must be nonnegative") cdef ntl_ZZ ans = ntl_ZZ.__new__(ntl_ZZ) ZZ_mul(ans.x, self.pow_ZZ_tmp(mpz_get_ui((m).value))[0], self.pow_ZZ_tmp(mpz_get_ui((n).value))[0]) return ans cdef mpz_srcptr pow_mpz_t_top(self) noexcept: """ - Returns self.prime^self.prec_cap as an ``mpz_srcptr``. + Return ``self.prime^self.prec_cap`` as an ``mpz_srcptr``. EXAMPLES:: @@ -690,7 +691,7 @@ cdef class PowComputer_ext(PowComputer_class): cdef ZZ_c* pow_ZZ_top(self) noexcept: """ - Returns self.prime^self.prec_cap as a ZZ_c. + Return ``self.prime^self.prec_cap`` as a ZZ_c. EXAMPLES:: @@ -702,7 +703,7 @@ cdef class PowComputer_ext(PowComputer_class): def _pow_ZZ_top_test(self): """ - Tests the pow_ZZ_top function. + Test the ``pow_ZZ_top`` function. EXAMPLES:: @@ -716,7 +717,7 @@ cdef class PowComputer_ext(PowComputer_class): def _ram_prec_cap(self): """ - Returns the precision cap of self, considered as a power of the uniformizer. + Return the precision cap of self, considered as a power of the uniformizer. EXAMPLES:: @@ -744,7 +745,8 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def polynomial(self): """ - Returns the polynomial (with coefficient precision prec_cap) associated to this PowComputer. + Return the polynomial (with coefficient precision prec_cap) associated + to this ``PowComputer``. The polynomial is output as an ntl_ZZ_pX. @@ -762,7 +764,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef ntl_ZZ_pContext_class get_context(self, long n): """ - Returns a ZZ_pContext for self.prime^(abs(n)). + Return a ``ZZ_pContext`` for ``self.prime^(abs(n))``. EXAMPLES:: @@ -782,7 +784,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _get_context_test(self, n): """ - Returns a ZZ_pContext for self.prime^n. + Return a ``ZZ_pContext`` for ``self.prime^n``. EXAMPLES:: @@ -795,7 +797,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef ntl_ZZ_pContext_class get_context_capdiv(self, long n): """ - Returns a ZZ_pContext for self.prime^((n-1) // self.e + 1) + Return a ``ZZ_pContext`` for ``self.prime^((n-1) // self.e + 1)``. For Eisenstein extensions this gives the context used for an element of relative precision n. @@ -810,7 +812,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _get_context_capdiv_test(self, n): """ - Returns a ZZ_pContext for self.prime^((n-1) // self.e + 1) + Return a ``ZZ_pContext`` for ``self.prime^((n-1) // self.e + 1)``. For Eisenstein extensions this gives the context used for an element of relative precision n. @@ -826,12 +828,13 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def speed_test(self, n, runs): """ - Runs a speed test. + Run a speed test. INPUT: - - ``n`` -- input to a function to be tested (the function needs to be set in the source code). - - ``runs`` -- The number of runs of that function + - ``n`` -- input to a function to be tested (the function needs to be + set in the source code) + - ``runs`` -- the number of runs of that function OUTPUT: @@ -855,7 +858,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef ntl_ZZ_pContext_class get_top_context(self): """ - Returns a ZZ_pContext for self.prime^self.prec_cap + Return a ``ZZ_pContext`` for ``self.prime^self.prec_cap``. TESTS:: @@ -867,7 +870,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _get_top_context_test(self): """ - Returns a ZZ_pContext for self.prime^self.prec_cap + Return a ``ZZ_pContext`` for ``self.prime^self.prec_cap``. TESTS:: @@ -879,7 +882,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef restore_context(self, long n): """ - Restores the contest corresponding to self.prime^n + Restore the contest corresponding to ``self.prime^n``. EXAMPLES:: @@ -890,7 +893,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _restore_context_test(self, n): """ - Restores the contest corresponding to self.prime^n + Restore the contest corresponding to ``self.prime^n``. EXAMPLES:: @@ -902,7 +905,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef restore_context_capdiv(self, long n): """ - Restores the context for self.prime^((n-1) // self.e + 1) + Restore the context for ``self.prime^((n-1) // self.e + 1)``. EXAMPLES:: @@ -913,7 +916,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _restore_context_capdiv_test(self, n): """ - Restores the context for self.prime^((n-1) // self.e + 1) + Restore the context for ``self.prime^((n-1) // self.e + 1)``. EXAMPLES:: @@ -925,7 +928,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef void restore_top_context(self) noexcept: """ - Restores the context corresponding to self.prime^self.prec_cap + Restore the context corresponding to ``self.prime^self.prec_cap``. EXAMPLES:: @@ -936,7 +939,7 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _restore_top_context_test(self): """ - Restores the context corresponding to self.prime^self.prec_cap + Restore the context corresponding to ``self.prime^self.prec_cap``. EXAMPLES:: @@ -947,7 +950,8 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef ZZ_pX_Modulus_c* get_modulus(self, long n) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod self.prime^n) + Return the modulus corresponding to ``self.polynomial()`` (mod + ``self.prime^n``). EXAMPLES:: @@ -962,7 +966,8 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _get_modulus_test(self, ntl_ZZ_pX a, ntl_ZZ_pX b, Integer n): """ - Multiplies a and b modulo the modulus corresponding to self.polynomial() (mod self.prime^n). + Multiply ``a`` and ``b`` modulo the modulus corresponding to + ``self.polynomial()`` (mod ``self.prime^n``). EXAMPLES:: @@ -990,15 +995,15 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef ZZ_pX_Modulus_c* get_modulus_capdiv(self, long n) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod - self.prime^((n-1) // self.e + 1) + Return the modulus corresponding to ``self.polynomial()`` (mod + ``self.prime^((n-1) // self.e + 1``). """ return self.get_modulus(self.capdiv(n)) cdef ZZ_pX_Modulus_c* get_top_modulus(self) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod - self.prime^self.prec_cap) + Return the modulus corresponding to ``self.polynomial()`` (mod + ``self.prime^self.prec_cap``). EXAMPLES:: @@ -1013,8 +1018,8 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _get_top_modulus_test(self, ntl_ZZ_pX a, ntl_ZZ_pX b): """ - Multiplies a and b modulo the modulus corresponding to - self.polynomial() (mod self.prime^self.prec_cap) + Multiply ``a`` and ``b`` modulo the modulus corresponding to + ``self.polynomial()`` (mod ``self.prime^self.prec_cap``). EXAMPLES:: @@ -1057,9 +1062,9 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): def _capdiv_test(self, n): """ - If n >= 0 returns ceil(n / self.e) + If n >= 0, return ceil(n / self.e). - If n < 0 returns ceil(-n / self.e) + If n < 0, return ceil(-n / self.e). EXAMPLES:: @@ -1082,30 +1087,30 @@ cdef class PowComputer_ZZ_pX(PowComputer_ext): cdef int teichmuller_set_c (self, ZZ_pX_c* x, ZZ_pX_c* a, long absprec) except -1: r""" - Sets x to the Teichmuller lift congruent to a modulo the + Set `x` to the Teichmuller lift congruent to a modulo the uniformizer, ie such that `x = a \mod \pi` and `x^q = x \mod \pi^{\mbox{absprec}}`. If `a = 0 \mod \pi` this function does nothing and returns 1. Otherwise returns 0. - x should be created with context p^absprec. + `x` should be created with context p^absprec. - Does not affect self. + Does not affect ``self``. INPUT: - - ``x`` -- The ``ZZ_pX_c`` to be set + - ``x`` -- the ``ZZ_pX_c`` to be set - - ``a`` -- A ``ZZ_pX_c`` ``currently holding an approximation to the + - ``a`` -- a ``ZZ_pX_c`` ``currently holding an approximation to the Teichmuller representative (this approximation can be any - integer). It will be set to the actual Teichmuller lift + integer). It will be set to the actual Teichmuller lift. - ``absprec`` -- the desired precision of the Teichmuller lift OUTPUT: - - 1 -- x should be set to zero + - 1 -- `x` should be set to zero - 0 -- normal EXAMPLES:: @@ -1212,13 +1217,13 @@ cdef class PowComputer_ZZ_pX_FM(PowComputer_ZZ_pX): r""" This class only caches a context and modulus for p^prec_cap. - Designed for use with fixed modulus p-adic rings, in Eisenstein + Designed for use with fixed modulus `p`-adic rings, in Eisenstein and unramified extensions of `\ZZ_p`. """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): """ - Caches a context and modulus for prime^prec_cap + Caches a context and modulus for ``prime^prec_cap``. EXAMPLES:: @@ -1250,7 +1255,7 @@ cdef class PowComputer_ZZ_pX_FM(PowComputer_ZZ_pX): cdef ntl_ZZ_pContext_class get_top_context(self): """ - Returns a ZZ_pContext for self.prime^self.prec_cap + Return a ``ZZ_pContext`` for ``self.prime^self.prec_cap``. EXAMPLES:: @@ -1262,7 +1267,7 @@ cdef class PowComputer_ZZ_pX_FM(PowComputer_ZZ_pX): cdef void restore_top_context(self) noexcept: """ - Restores the context corresponding to self.prime^self.prec_cap + Restore the context corresponding to ``self.prime^self.prec_cap``. EXAMPLES:: @@ -1273,7 +1278,8 @@ cdef class PowComputer_ZZ_pX_FM(PowComputer_ZZ_pX): cdef ZZ_pX_Modulus_c* get_top_modulus(self) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod self.prime^self.prec_cap) + Return the modulus corresponding to ``self.polynomial()`` + (mod ``self.prime^self.prec_cap``). EXAMPLES:: @@ -1307,12 +1313,13 @@ cdef class PowComputer_ZZ_pX_FM(PowComputer_ZZ_pX): cdef class PowComputer_ZZ_pX_FM_Eis(PowComputer_ZZ_pX_FM): """ - This class computes and stores low_shifter and high_shifter, which aid in right shifting elements. + This class computes and stores ``low_shifter`` and ``high_shifter``, which aid in right shifting elements. """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): """ - Calls Eis_init, which initializes high_shifter and low_shifter. + Call ``Eis_init``, which initializes ``high_shifter`` and + ``low_shifter``. TESTS:: @@ -1411,7 +1418,7 @@ cdef class PowComputer_ZZ_pX_FM_Eis(PowComputer_ZZ_pX_FM): def __dealloc__(self): """ - Deallocates low_shifter and high_shifter. + Deallocate ``low_shifter`` and ``high_shifter``. TESTS:: @@ -1423,8 +1430,8 @@ cdef class PowComputer_ZZ_pX_FM_Eis(PowComputer_ZZ_pX_FM): cdef void cleanup_ZZ_pX_FM_Eis(self) noexcept: """ - Does the actual work of deallocating low_shifter and - high_shifter. + Do the actual work of deallocating ``low_shifter`` and + ``high_shifter``. TESTS:: @@ -1436,9 +1443,10 @@ cdef class PowComputer_ZZ_pX_FM_Eis(PowComputer_ZZ_pX_FM): cdef int eis_shift(self, ZZ_pX_c* x, ZZ_pX_c* a, long n, long finalprec) except -1: """ - Shifts a right n pi-adic digits, where pi is considered modulo the polynomial in self. + Shift ``a`` right ``n`` pi-adic digits, where pi is considered modulo + the polynomial in ``self``. - Puts the result in x. + Puts the result in ``x``. EXAMPLES:: @@ -1534,7 +1542,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): This class caches contexts and moduli densely between 1 and cache_limit. It requires cache_limit == prec_cap. It is intended for use with capped relative and capped absolute rings and fields, in Eisenstein and unramified - extensions of the base p-adic fields. + extensions of the base `p`-adic fields. """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): @@ -1599,7 +1607,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): def __dealloc__(self): """ - Deallocates cache of contexts, moduli. + Deallocate cache of contexts, moduli. EXAMPLES:: @@ -1611,7 +1619,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): cdef void cleanup_ZZ_pX_small(self) noexcept: """ - Deallocates cache of contexts, moduli. + Deallocate cache of contexts, moduli. EXAMPLES:: @@ -1627,11 +1635,9 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): INPUT: - - ``n`` -- A nonzero long - - OUTPUT: + - ``n`` -- nonzero long - - A context for p^n + OUTPUT: a context for p^n EXAMPLES:: @@ -1653,7 +1659,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): INPUT: - - ``n`` -- A nonzero long + - ``n`` -- nonzero long EXAMPLES:: @@ -1669,7 +1675,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): cdef ntl_ZZ_pContext_class get_top_context(self): """ - Returns a ZZ_pContext for self.prime^self.prec_cap + Return a ``ZZ_pContext`` for ``self.prime^self.prec_cap``. EXAMPLES:: @@ -1681,7 +1687,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): cdef void restore_top_context(self) noexcept: """ - Restores the context corresponding to self.prime^self.prec_cap + Restore the context corresponding to ``self.prime^self.prec_cap``. EXAMPLES:: @@ -1692,11 +1698,12 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): cdef ZZ_pX_Modulus_c* get_modulus(self, long n) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod self.prime^n). + Return the modulus corresponding to ``self.polynomial()`` (mod + ``self.prime^n``). INPUT: - - ``n`` -- A long between 1 and ``self.cache_limit``, inclusive. + - ``n`` -- a long between 1 and ``self.cache_limit``, inclusive. If `n` is larger, this function will return ``self.mod[prec_cap]`` lifted to that precision. @@ -1720,7 +1727,8 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): cdef ZZ_pX_Modulus_c* get_top_modulus(self) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod self.prime^self.prec_cap) + Return the modulus corresponding to ``self.polynomial()`` + (mod ``self.prime^self.prec_cap``). EXAMPLES:: @@ -1734,7 +1742,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): cdef class PowComputer_ZZ_pX_small_Eis(PowComputer_ZZ_pX_small): """ - This class computes and stores low_shifter and high_shifter, which aid in right shifting elements. + This class computes and stores ``low_shifter`` and ``high_shifter``, which aid in right shifting elements. These are only stored at maximal precision: in order to get lower precision versions just reduce mod p^n. """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): @@ -1842,7 +1850,7 @@ cdef class PowComputer_ZZ_pX_small_Eis(PowComputer_ZZ_pX_small): def __dealloc__(self): """ - Deallocates low_shifter and high_shifter. + Deallocate ``low_shifter`` and ``high_shifter``. TESTS:: @@ -1854,8 +1862,8 @@ cdef class PowComputer_ZZ_pX_small_Eis(PowComputer_ZZ_pX_small): cdef void cleanup_ZZ_pX_small_Eis(self) noexcept: """ - Does the actual work of deallocating low_shifter and - high_shifter. + Do the actual work of deallocating ``low_shifter`` and + ``high_shifter``. TESTS:: @@ -1867,9 +1875,10 @@ cdef class PowComputer_ZZ_pX_small_Eis(PowComputer_ZZ_pX_small): cdef int eis_shift(self, ZZ_pX_c* x, ZZ_pX_c* a, long n, long finalprec) except -1: """ - Shifts a right n pi-adic digits, where pi is considered modulo the polynomial in self. + Shift ``a`` right ``n`` pi-adic digits, where pi is considered modulo + the polynomial in ``self``. - Puts the result in x. + Puts the result in ``x``. EXAMPLES:: @@ -1965,7 +1974,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): def __dealloc__(self): """ - Deallocates the stored moduli and contexts. + Deallocate the stored moduli and contexts. EXAMPLES:: @@ -1977,7 +1986,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef void cleanup_ZZ_pX_big(self) noexcept: """ - Deallocates the stored moduli and contexts. + Deallocate the stored moduli and contexts. EXAMPLES:: @@ -1988,7 +1997,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): def reset_dictionaries(self): """ - Resets the dictionaries. Note that if there are elements + Reset the dictionaries. Note that if there are elements lying around that need access to these dictionaries, calling this function and then doing arithmetic with those elements could cause trouble (if the context object gets garbage @@ -2012,7 +2021,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): def _context_dict(self): """ - Returns the context dictionary. + Return the context dictionary. EXAMPLES:: @@ -2025,7 +2034,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): def _modulus_dict(self): """ - Returns the context dictionary. + Return the context dictionary. EXAMPLES:: @@ -2044,15 +2053,13 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef ntl_ZZ_pContext_class get_context(self, long n): """ - Returns the context for p^n. + Return the context for p^n. INPUT: - - ``n`` -- A nonzero long + - ``n`` -- nonzero long - OUTPUT: - - - A context for p^n + OUTPUT: a context for p^n EXAMPLES:: @@ -2080,7 +2087,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef ntl_ZZ_pContext_class get_top_context(self): """ - Returns a ZZ_pContext for self.prime^self.prec_cap + Return a ``ZZ_pContext`` for ``self.prime^self.prec_cap``. EXAMPLES:: @@ -2092,7 +2099,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef void restore_top_context(self) noexcept: """ - Restores the context corresponding to self.prime^self.prec_cap + Restore the context corresponding to ``self.prime^self.prec_cap``. EXAMPLES:: @@ -2103,11 +2110,12 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef ZZ_pX_Modulus_c* get_modulus(self, long n) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod self.prime^n). + Return the modulus corresponding to ``self.polynomial()`` (mod + ``self.prime^n``). INPUT: - - ``n`` -- A nonzero long + - ``n`` -- nonzero long EXAMPLES:: @@ -2150,7 +2158,8 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef ZZ_pX_Modulus_c* get_top_modulus(self) noexcept: """ - Returns the modulus corresponding to self.polynomial() (mod self.prime^self.prec_cap) + Return the modulus corresponding to ``self.polynomial()`` + (mod ``self.prime^self.prec_cap``). EXAMPLES:: @@ -2164,8 +2173,10 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): """ - This class computes and stores low_shifter and high_shifter, which aid in right shifting elements. - These are only stored at maximal precision: in order to get lower precision versions just reduce mod p^n. + This class computes and stores ``low_shifter`` and ``high_shifter``, which + aid in right shifting elements. + These are only stored at maximal precision: in order to get lower precision + versions just reduce mod p^n. """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): """ @@ -2272,7 +2283,7 @@ cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): def __dealloc__(self): """ - Deallocates low_shifter and high_shifter. + Deallocate ``low_shifter`` and ``high_shifter``. TESTS:: @@ -2284,8 +2295,8 @@ cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): cdef void cleanup_ZZ_pX_big_Eis(self) noexcept: """ - Does the actual work of deallocating low_shifter and - high_shifter. + Do the actual work of deallocating ``low_shifter`` and + ``high_shifter``. TESTS:: @@ -2297,9 +2308,10 @@ cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): cdef int eis_shift(self, ZZ_pX_c* x, ZZ_pX_c* a, long n, long finalprec) except -1: """ - Shifts a right n pi-adic digits, where pi is considered modulo the polynomial in self. + Shift ``a`` right ``n`` pi-adic digits, where pi is considered modulo + the polynomial in ``self``. - Puts the result in x. + Puts the result in ``x``. EXAMPLES:: @@ -2325,37 +2337,37 @@ cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): def PowComputer_ext_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, prec_type = "small", ext_type = "u", shift_seed = None): r""" - Returns a PowComputer that caches the values `1, p, p^2, \ldots, p^C`, + Return a ``PowComputer`` that caches the values `1, p, p^2, \ldots, p^C`, where `C` is ``cache_limit``. - Once you create a PowComputer, merely call it to get values out. + Once you create a ``PowComputer``, merely call it to get values out. You can input any integer, even if it's outside of the precomputed range. INPUT: - - ``prime`` -- An integer, the base that you want to exponentiate. + - ``prime`` -- integer; the base that you want to exponentiate - - ``cache_limit`` -- A positive integer that you want to cache - powers up to. + - ``cache_limit`` -- positive integer that you want to cache + powers up to - - ``prec_cap`` -- The cap on precisions of elements. For ramified + - ``prec_cap`` -- the cap on precisions of elements. For ramified extensions, p^((prec_cap - 1) // e) will be the largest - power of p distinguishable from zero + power of p distinguishable from zero. - - ``in_field`` -- Boolean indicating whether this PowComputer is - attached to a field or not. + - ``in_field`` -- boolean indicating whether this PowComputer is + attached to a field or not - - ``poly`` -- An ``ntl_ZZ_pX`` or ``ntl_ZZ_pEX`` defining the extension. - It should be defined modulo p^((prec_cap - 1) // e + 1) + - ``poly`` -- an ``ntl_ZZ_pX`` or ``ntl_ZZ_pEX`` defining the extension. + It should be defined modulo ``p^((prec_cap - 1) // e + 1)``. - - ``prec_type`` -- 'FM', 'small', or 'big', defining how caching - is done. + - ``prec_type`` -- ``'FM'``, ``'small'``, or ``'big'``, defining how + caching is done - - ``ext_type`` -- 'u' = unramified, 'e' = Eisenstein, 't' = + - ``ext_type`` -- ``'u'`` = unramified, ``'e'`` = Eisenstein, ``'t'`` = two-step - ``shift_seed`` -- (required only for Eisenstein and two-step) - For Eisenstein and two-step extensions, if f = a_n x^n - p + for Eisenstein and two-step extensions, if f = a_n x^n - p a_{n-1} x^{n-1} - ... - p a_0 with a_n a unit, then shift_seed should be 1/a_n (a_{n-1} x^{n-1} + ... + a_0) diff --git a/src/sage/rings/padics/pow_computer_flint.pyx b/src/sage/rings/padics/pow_computer_flint.pyx index 79f5a971e55..cac2d70d758 100644 --- a/src/sage/rings/padics/pow_computer_flint.pyx +++ b/src/sage/rings/padics/pow_computer_flint.pyx @@ -42,7 +42,6 @@ cdef class PowComputer_flint(PowComputer_class): sage: from sage.rings.padics.pow_computer_flint import PowComputer_flint sage: type(PowComputer_flint(5, 20, 20, 20, False)) - """ # fmpz_init does not allocate memory fmpz_init(self.fprime) @@ -71,7 +70,6 @@ cdef class PowComputer_flint(PowComputer_class): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_maker(5, 20, 20, 20, False, f, 'capped-rel') # indirect doctest sage: TestSuite(A).run() - """ PowComputer_class.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed) @@ -105,7 +103,6 @@ cdef class PowComputer_flint(PowComputer_class): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_maker(5, 20, 20, 20, False, f, 'capped-rel') # indirect doctest sage: A._test_pickling() # indirect doctest - """ return PowComputer_flint_maker, (self.prime, self.cache_limit, self.prec_cap, self.ram_prec_cap, self.in_field, self.polynomial(), self._prec_type) @@ -123,7 +120,7 @@ cdef class PowComputer_flint(PowComputer_class): cdef fmpz_t* pow_fmpz_t_tmp(self, unsigned long n) except NULL: """ - Returns a pointer to a FLINT ``fmpz_t`` holding `p^n`. + Return a pointer to a FLINT ``fmpz_t`` holding `p^n`. Analogous to :meth:`sage.rings.padics.pow_computer.PowComputer_class.pow_mpz_t_tmp` @@ -140,7 +137,7 @@ cdef class PowComputer_flint(PowComputer_class): cdef mpz_srcptr pow_mpz_t_tmp(self, long n) except NULL: """ - Returns a pointer to an ``mpz_t`` holding `p^n`. + Return a pointer to an ``mpz_t`` holding `p^n`. See :meth:`sage.rings.padics.pow_computer.PowComputer_class.pow_mpz_t_tmp` @@ -151,14 +148,14 @@ cdef class PowComputer_flint(PowComputer_class): cdef mpz_srcptr pow_mpz_t_top(self) noexcept: """ - Returns a pointer to an ``mpz_t`` holding `p^N`, where `N` is + Return a pointer to an ``mpz_t`` holding `p^N`, where `N` is the precision cap. """ return self.top_power cdef unsigned long capdiv(self, unsigned long n) noexcept: """ - Returns ceil(n / e). + Return ceil(n / e). """ if self.e == 1: return n if n == 0: return 0 @@ -166,7 +163,7 @@ cdef class PowComputer_flint(PowComputer_class): def polynomial(self, n=None, var='x'): """ - Returns ``None``. + Return ``None``. For consistency with subclasses. @@ -176,7 +173,6 @@ cdef class PowComputer_flint(PowComputer_class): sage: A = PowComputer_flint(5, 20, 20, 20, False, None) sage: A.polynomial() is None True - """ return None @@ -192,7 +188,6 @@ cdef class PowComputer_flint_1step(PowComputer_flint): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_1step(5, 20, 20, 20, False, f); A FLINT PowComputer for 5 with polynomial x^3 - 8*x - 2 - """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, _poly): """ @@ -205,7 +200,6 @@ cdef class PowComputer_flint_1step(PowComputer_flint): sage: A = PowComputer_flint_1step(5, 20, 20, 20, False, f) sage: type(A) - """ cdef Polynomial_integer_dense_flint poly = _poly cdef long length = fmpz_poly_length(poly._poly) @@ -263,7 +257,6 @@ cdef class PowComputer_flint_1step(PowComputer_flint): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_maker(5, 20, 20, 20, False, f, 'capped-rel') sage: TestSuite(A).run() - """ PowComputer_flint.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, _poly, shift_seed) @@ -387,7 +380,7 @@ cdef class PowComputer_flint_1step(PowComputer_flint): cdef fmpz_poly_t* get_modulus_capdiv(self, unsigned long k) noexcept: """ - Returns the defining polynomial reduced modulo `p^a`, where + Return the defining polynomial reduced modulo `p^a`, where `a` is the ceiling of `k/e`. The same warnings apply as for @@ -397,14 +390,15 @@ cdef class PowComputer_flint_1step(PowComputer_flint): def polynomial(self, _n=None, var='x'): """ - Returns the polynomial attached to this ``PowComputer``, possibly reduced modulo a power of `p`. + Return the polynomial attached to this ``PowComputer``, possibly + reduced modulo a power of `p`. INPUT: - - ``_n`` -- (default ``None``) an integer, the power of `p` - modulo which to reduce. + - ``_n`` -- (default: ``None``) an integer, the power of `p` + modulo which to reduce - - ``var`` -- (default ``'x'``) the variable for the returned polynomial + - ``var`` -- (default: ``'x'``) the variable for the returned polynomial .. NOTE:: @@ -434,7 +428,7 @@ cdef class PowComputer_flint_1step(PowComputer_flint): cdef _new_fmpz_poly(self, fmpz_poly_t value, var='x'): """ - Returns a polynomial with the value stored in ``value`` and + Return a polynomial with the value stored in ``value`` and variable name ``var``. """ R = ZZ[var] @@ -455,7 +449,6 @@ cdef class PowComputer_flint_unram(PowComputer_flint_1step): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_unram(5, 20, 20, 20, False, f); A FLINT PowComputer for 5 with polynomial x^3 - 8*x - 2 - """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, _poly, shift_seed=None): """ @@ -468,7 +461,6 @@ cdef class PowComputer_flint_unram(PowComputer_flint_1step): sage: A = PowComputer_flint_unram(5, 20, 20, 20, False, f) sage: type(A) - """ # fmpz_init does not allocate memory fmpz_init(self.fmpz_ccmp) @@ -513,7 +505,6 @@ cdef class PowComputer_flint_unram(PowComputer_flint_1step): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_unram(5, 20, 20, 20, False, f) sage: del A - """ if self._allocated >= 16: fmpz_clear(self.fmpz_ccmp) @@ -548,7 +539,6 @@ cdef class PowComputer_flint_unram(PowComputer_flint_1step): sage: R. = ZZ[]; f = x^3 - 8*x - 2 sage: A = PowComputer_flint_maker(5, 20, 20, 20, False, f, 'capped-rel') sage: TestSuite(A).run() - """ PowComputer_flint_1step.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly) @@ -580,7 +570,6 @@ cdef class PowComputer_flint_eis(PowComputer_flint_1step): sage: A = PowComputer_flint_eis(5, 20, 20, 60, False, f) sage: type(A) - """ PowComputer_flint_1step.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly) @@ -597,16 +586,16 @@ def PowComputer_flint_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field - ``prime`` -- an integral prime - - ``cache_limit`` -- a non-negative integer, controlling the + - ``cache_limit`` -- nonnegative integer, controlling the caching. Powers of ``prime``, reductions of ``poly`` modulo different powers of ``prime`` and inverses of the leading coefficient modulo different powers of ``prime`` are cached. Additional data is cached for ramified extensions. - ``prec_cap`` -- the power of `p` modulo which elements of - largest precision are defined. + largest precision are defined - - ``ram_prec_cap`` -- Approximately ``e*prec_cap``, where ``e`` is + - ``ram_prec_cap`` -- approximately ``e*prec_cap``, where ``e`` is the ramification degree of the extension. For a ramified extension this is what Sage calls the precision cap of the ring. In fact, it's possible to have rings with precision cap not a @@ -615,12 +604,12 @@ def PowComputer_flint_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field ``prec_cap = ceil(n/e)`` - ``in_field`` -- (boolean) whether the associated ring is - actually a field. + actually a field - - ``poly`` -- the polynomial defining the extension. + - ``poly`` -- the polynomial defining the extension - - `prec_type`` -- one of ``"capped-rel"``, ``"capped-abs"`` or - ``"fixed-mod"``, the precision type of the ring. + - ``prec_type`` -- one of ``'capped-rel'``, ``'capped-abs'`` or + ``'fixed-mod'``; the precision type of the ring .. NOTE:: @@ -639,7 +628,6 @@ def PowComputer_flint_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field sage: A = PowComputer_flint_maker(3, 20, 20, 20, False, x^3 + 2*x + 1, 'fixed-mod'); type(A) - """ if prec_type == 'capped-rel': from sage.rings.padics.qadic_flint_CR import PowComputer_ diff --git a/src/sage/rings/padics/pow_computer_relative.pyx b/src/sage/rings/padics/pow_computer_relative.pyx index 2de1fa5688b..de2e85e6c85 100644 --- a/src/sage/rings/padics/pow_computer_relative.pyx +++ b/src/sage/rings/padics/pow_computer_relative.pyx @@ -53,7 +53,6 @@ cdef class PowComputer_relative(PowComputer_class): sage: from sage.rings.padics.pow_computer_relative import PowComputer_relative sage: isinstance(PC, PowComputer_relative) # needs sage.libs.flint True - """ def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed): r""" @@ -67,7 +66,6 @@ cdef class PowComputer_relative(PowComputer_class): sage: RFP = R.change(field=False, show_prec=False, type='floating-point') sage: shift_seed = (-f[:3] // 5).change_ring(RFP) sage: PC = PowComputer_relative_maker(3, 20, 20, 60, False, f, shift_seed, 'fixed-mod') - """ self._allocated = 4 @@ -83,7 +81,6 @@ cdef class PowComputer_relative(PowComputer_class): sage: shift_seed = (-f[:3] // 5).change_ring(RFP) sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, shift_seed, 'fixed-mod') # indirect doctest sage: TestSuite(PC).run() - """ PowComputer_class.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed) self.e = poly.degree() * poly.base_ring().absolute_e() @@ -115,7 +112,6 @@ cdef class PowComputer_relative(PowComputer_class): sage: shift_seed = (-f[:3] // 5).change_ring(RFP) sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, shift_seed, 'fixed-mod') sage: del PC - """ def __reduce__(self): @@ -152,7 +148,6 @@ cdef class PowComputer_relative(PowComputer_class): sage: shift_seed = (-f[:3] // 5).change_ring(RFP) sage: PowComputer_relative_maker(5, 20, 20, 60, False, f, shift_seed, 'fixed-mod') # indirect doctest Relative PowComputer for modulus x^3 + 5*x + a*5 - """ return "Relative PowComputer for modulus %s" % (self.modulus,) @@ -182,14 +177,13 @@ cdef class PowComputer_relative(PowComputer_class): sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, shift_seed, 'fixed-mod') # indirect doctest sage: PC.polynomial() is f True - """ return self.modulus cdef class PowComputer_relative_eis(PowComputer_relative): r""" - A ``PowComputer`` for a relative extension defined by an Eisenstein polynomial + A ``PowComputer`` for a relative extension defined by an Eisenstein polynomial. For a description of inputs see :func:`PowComputer_relative_maker`. @@ -207,7 +201,6 @@ cdef class PowComputer_relative_eis(PowComputer_relative): sage: isinstance(PC, PowComputer_relative_eis) # needs sage.libs.flint True - """ def __init__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed): r""" @@ -221,7 +214,6 @@ cdef class PowComputer_relative_eis(PowComputer_relative): sage: shift_seed = (-f[:3] // 5).change_ring(RFP) sage: PC = PowComputer_relative_maker(5, 20, 20, 60, False, f, shift_seed, 'fixed-mod') sage: TestSuite(PC).run() - """ PowComputer_relative.__init__(self, prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed) self._inv_shift_seed = self.invert(shift_seed, self.ram_prec_cap) @@ -235,11 +227,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): - ``a`` -- a `p`-adic element, represented as a reduced Polynomial in ``poly_ring`` - - ```prec`` -- a ``long``, the required precision + - ``prec`` -- a ``long``, the required precision - OUTPUT: - - A polynomial ``b`` such that ``a*b`` is one modulo `π^\mathrm{prec}` + OUTPUT: a polynomial ``b`` such that ``a*b`` is one modulo `π^\mathrm{prec}` EXAMPLES:: @@ -283,11 +273,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): INPUT: - - ``r`` -- an integer with 0 <= r < e - - OUTPUT: + - ``r`` -- integer with 0 <= r < e - A reduced polynomial in π + OUTPUT: a reduced polynomial in π EXAMPLES:: @@ -297,10 +285,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): sage: W. = R.ext(f) sage: elt = W.prime_pow.px_pow(2); elt ((4*a + 4) + (4*a + 1)*5 + (4*a + 2)*5^2)*x^2 + ((2*a + 3) + (2*a + 4)*5 + (2*a + 4)*5^2)*x + (a + 1)*5 + 3*5^2 + 2*5^3 - """ if r < 0: - raise ValueError("r must be non-negative") + raise ValueError("r must be nonnegative") elif r == 0: return self.poly_ring(self.base_ring.uniformizer()) elif r >= self.e: @@ -316,11 +303,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): INPUT: - - ``r`` -- a non-negative integer - - OUTPUT: + - ``r`` -- nonnegative integer - A reduced polynomial in π + OUTPUT: a reduced polynomial in π EXAMPLES:: @@ -330,10 +315,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): sage: W. = R.ext(f) sage: elt = W.prime_pow.pxe_pow(2); elt ((4*a + 2) + (a + 4)*5 + 2*a*5^2)*x^2 + ((a + 2) + (a + 2)*5 + (2*a + 4)*5^2)*x + (a + 1) + (3*a + 2)*5 + (2*a + 2)*5^2 - """ if r < 0: - raise ValueError("r must be non-negative") + raise ValueError("r must be nonnegative") elif r == 0: return self.poly_ring.one() elif r == 1: @@ -350,11 +334,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): INPUT: - - ``r`` -- a non-negative integer - - OUTPUT: + - ``r`` -- nonnegative integer - A reduced polynomial in π + OUTPUT: a reduced polynomial in π EXAMPLES:: @@ -364,10 +346,9 @@ cdef class PowComputer_relative_eis(PowComputer_relative): sage: W. = R.ext(f) sage: W.prime_pow.uniformizer_pow(2) x^2 - """ if r < 0: - raise ValueError("r must be non-negative") + raise ValueError("r must be nonnegative") elif r == 0: return self.poly_ring.one() elif r < self.e: @@ -386,8 +367,8 @@ def PowComputer_relative_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_fi - ``prime`` -- a uniformizer in the base ring - - ``cache_limit`` -- a non-negative integer, controlling the caching. The - ``PowComputer`` caches frequently used things like powers of ``prime``. + - ``cache_limit`` -- nonnegative integer, controlling the caching. The + ``PowComputer`` caches frequently used things like powers of ``prime`` This parameter, e.g., controls up to which power these are cached. - ``prec_cap`` -- the power of ``prime`` modulo which elements of largest @@ -400,13 +381,13 @@ def PowComputer_relative_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_fi `e`, in which case the actual relationship between ``ram_prec_cap`` and ``prec_cap`` is that ``prec_cap = ceil(n/e)`` - - ``in_field`` -- a boolean; whether the associated ring is actually a + - ``in_field`` -- boolean; whether the associated ring is actually a field - ``poly`` -- the polynomial defining the extension - - `prec_type`` -- one of ``"capped-rel"``, ``"capped-abs"`` or - ``"fixed-mod"``, ``"floating-point"``, the precision type of the ring + - ``prec_type`` -- one of ``'capped-rel'``, ``'capped-abs'`` or + ``'fixed-mod'``, ``'floating-point'``; the precision type of the ring .. NOTE:: @@ -426,7 +407,6 @@ def PowComputer_relative_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_fi sage: PC = W.prime_pow # indirect doctest sage: PC Relative PowComputer for modulus x^3 + (4*5 + 4*5^2)*x + 4*a*5 + 4*a*5^2 - """ PC = PowComputer_relative_eis(prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, shift_seed) # We have to set this here because the signature of __cinit__ in PowComputer_base doesn't allow for prec_type to be passed. diff --git a/src/sage/rings/padics/precision_error.py b/src/sage/rings/padics/precision_error.py index a536fa1a104..3dcf4b08d8e 100644 --- a/src/sage/rings/padics/precision_error.py +++ b/src/sage/rings/padics/precision_error.py @@ -2,7 +2,7 @@ Precision Error The errors in this file indicate various styles of precision problems -that can go wrong for p-adics and power series. +that can go wrong for `p`-adics and power series. AUTHORS: @@ -18,5 +18,6 @@ # http://www.gnu.org/licenses/ #***************************************************************************** + class PrecisionError(ArithmeticError): pass diff --git a/src/sage/rings/padics/qadic_flint_CA.pyx b/src/sage/rings/padics/qadic_flint_CA.pyx index a2a65359edc..36d3df419d0 100644 --- a/src/sage/rings/padics/qadic_flint_CA.pyx +++ b/src/sage/rings/padics/qadic_flint_CA.pyx @@ -83,13 +83,13 @@ cdef class qAdicCappedAbsoluteElement(CAElement): Return the element with the same reduction mod p that can be expressed with coefficients between 0 and p-1. The absolute precision will be maximal. - This method is used in printing and computing p-adic expansions. + This method is used in printing and computing `p`-adic expansions. INPUT: - - ``use_smallest_mode`` -- if True, use reps between -p/2 and p/2 instead. - - ``return_list`` -- if True, return a list of coefficients (as integers). - For use in printing. + - ``use_smallest_mode`` -- if ``True``, use reps between -p/2 and p/2 instead + - ``return_list`` -- if ``True``, return a list of coefficients (as integers); + for use in printing EXAMPLES:: @@ -110,8 +110,8 @@ cdef class qAdicCappedAbsoluteElement(CAElement): def __hash__(self): r""" - Raise a ``TypeError`` since this element is not hashable - (:issue:`11895`.) + Raise a :exc:`TypeError` since this element is not hashable + (:issue:`11895`). TESTS:: @@ -120,7 +120,6 @@ cdef class qAdicCappedAbsoluteElement(CAElement): Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CA.qAdicCappedAbsoluteElement' - """ # Eventually, hashing will be disabled for all (non-fixed-mod) p-adic # elements (#11895), until then, we only to this for types which did diff --git a/src/sage/rings/padics/qadic_flint_CR.pyx b/src/sage/rings/padics/qadic_flint_CR.pyx index 8f7f268b60e..a13d135ae18 100644 --- a/src/sage/rings/padics/qadic_flint_CR.pyx +++ b/src/sage/rings/padics/qadic_flint_CR.pyx @@ -118,13 +118,13 @@ cdef class qAdicCappedRelativeElement(CRElement): Return the element with the same reduction mod p that can be expressed with coefficients between 0 and p-1. The absolute precision will be maximal. - This method is used in printing and computing p-adic expansions. + This method is used in printing and computing `p`-adic expansions. INPUT: - - ``use_smallest_mode`` -- if True, use reps between -p/2 and p/2 instead. - - ``return_list`` -- if True, return a list of coefficients (as integers). - For use in printing. + - ``use_smallest_mode`` -- if ``True``, use reps between -p/2 and p/2 instead + - ``return_list`` -- if ``True``, return a list of coefficients (as integers); + for use in printing EXAMPLES:: @@ -152,8 +152,8 @@ cdef class qAdicCappedRelativeElement(CRElement): def __hash__(self): r""" - Raise a ``TypeError`` since this element is not hashable - (:issue:`11895`.) + Raise a :exc:`TypeError` since this element is not hashable + (:issue:`11895`). TESTS:: @@ -162,7 +162,6 @@ cdef class qAdicCappedRelativeElement(CRElement): Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' - """ # Eventually, hashing will be disabled for all (non-fixed-mod) p-adic # elements (#11895), until then, we only to this for types which did diff --git a/src/sage/rings/padics/qadic_flint_FM.pyx b/src/sage/rings/padics/qadic_flint_FM.pyx index 0a5e0563101..c0aebfb8bc6 100644 --- a/src/sage/rings/padics/qadic_flint_FM.pyx +++ b/src/sage/rings/padics/qadic_flint_FM.pyx @@ -83,13 +83,13 @@ cdef class qAdicFixedModElement(FMElement): Return the element with the same reduction mod p that can be expressed with coefficients between 0 and p-1. The absolute precision will be maximal. - This method is used in printing and computing p-adic expansions. + This method is used in printing and computing `p`-adic expansions. INPUT: - - ``use_smallest_mode`` -- if True, use reps between -p/2 and p/2 instead. - - ``return_list`` -- if True, return a list of coefficients (as integers). - For use in printing. + - ``use_smallest_mode`` -- if ``True``, use reps between -p/2 and p/2 instead + - ``return_list`` -- if ``True``, return a list of coefficients (as integers); + for use in printing EXAMPLES:: diff --git a/src/sage/rings/padics/qadic_flint_FP.pyx b/src/sage/rings/padics/qadic_flint_FP.pyx index 2d080dba429..0461e562a6b 100644 --- a/src/sage/rings/padics/qadic_flint_FP.pyx +++ b/src/sage/rings/padics/qadic_flint_FP.pyx @@ -113,13 +113,13 @@ cdef class qAdicFloatingPointElement(FPElement): Return the element with the same reduction mod p that can be expressed with coefficients between 0 and p-1. The absolute precision will be maximal. - This method is used in printing and computing p-adic expansions. + This method is used in printing and computing `p`-adic expansions. INPUT: - - ``use_smallest_mode`` -- if True, use reps between -p/2 and p/2 instead. - - ``return_list`` -- if True, return a list of coefficients (as integers). - For use in printing. + - ``use_smallest_mode`` -- if ``True``, use reps between -p/2 and p/2 instead + - ``return_list`` -- if ``True``, return a list of coefficients (as integers); + for use in printing EXAMPLES:: @@ -146,8 +146,8 @@ cdef class qAdicFloatingPointElement(FPElement): def __hash__(self): r""" - Raise a ``TypeError`` since this element is not hashable - (:issue:`11895`.) + Raise a :exc:`TypeError` since this element is not hashable + (:issue:`11895`). TESTS:: @@ -156,7 +156,6 @@ cdef class qAdicFloatingPointElement(FPElement): Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_FP.qAdicFloatingPointElement' - """ # Eventually, hashing will be disabled for all (non-fixed-mod) p-adic # elements (#11895), until then, we only to this for types which did diff --git a/src/sage/rings/padics/relative_extension_leaves.py b/src/sage/rings/padics/relative_extension_leaves.py index 0310f2b21c3..3005ae0825b 100644 --- a/src/sage/rings/padics/relative_extension_leaves.py +++ b/src/sage/rings/padics/relative_extension_leaves.py @@ -1,7 +1,7 @@ """ Relative extensions of `p`-adic rings -We represent general extensions of p-adic rings as a two-step extension: +We represent general extensions of `p`-adic rings as a two-step extension: first an unramified extension of Qp, followed by an Eisenstein extension of the result. @@ -28,6 +28,7 @@ from .relative_ramified_FP import RelativeRamifiedFloatingPointElement from .pow_computer_relative import PowComputer_relative_maker + class pAdicRelativeBaseringInjection(Morphism): """ The injection of the unramified base into the two-step extension. @@ -35,7 +36,7 @@ class pAdicRelativeBaseringInjection(Morphism): INPUT: - ``R`` -- an unramified `p`-adic ring or field - - ``S`` -- an eisenstein extension of ``R``. + - ``S`` -- an eisenstein extension of ``R`` EXAMPLES:: @@ -123,6 +124,7 @@ def section(self): """ return pAdicRelativeBaseringSection(self.codomain(), self.domain()) + class pAdicRelativeBaseringSection(Morphism): """ The map from a two-step extension back to its maximal unramified subextension. @@ -193,6 +195,7 @@ def _call_with_args(self, x, args=(), kwds={}): """ return self.codomain()(self._call_(x), *args, **kwds) + class RelativeRamifiedExtensionRingFixedMod(EisensteinExtensionGeneric, pAdicFixedModRingGeneric): """ Two-step extension ring with fixed-mod precision. @@ -230,6 +233,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, self.register_coercion(pAdicRelativeBaseringInjection(approx_modulus.base_ring(), self)) self.register_conversion(pAdicConvert_QQ_FM(self)) + class RelativeRamifiedExtensionRingCappedAbsolute(EisensteinExtensionGeneric, pAdicCappedAbsoluteRingGeneric): """ Two-step extension ring with capped absolute precision. @@ -267,6 +271,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, self.register_coercion(pAdicRelativeBaseringInjection(approx_modulus.base_ring(), self)) self.register_conversion(pAdicConvert_QQ_CA(self)) + class RelativeRamifiedExtensionRingCappedRelative(EisensteinExtensionGeneric, pAdicCappedRelativeRingGeneric): """ Two-step extension ring with capped relative precision. @@ -304,6 +309,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, self.register_coercion(pAdicRelativeBaseringInjection(approx_modulus.base_ring(), self)) self.register_conversion(pAdicConvert_QQ_CR(self)) + class RelativeRamifiedExtensionFieldCappedRelative(EisensteinExtensionGeneric, pAdicCappedRelativeFieldGeneric): """ Two-step extension field with capped relative precision. @@ -343,6 +349,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, self.register_coercion(pAdicRelativeBaseringInjection(approx_modulus.base_ring().integer_ring(), self)) self.register_coercion(pAdicCoercion_QQ_CR(self)) + class RelativeRamifiedExtensionRingFloatingPoint(EisensteinExtensionGeneric, pAdicFloatingPointRingGeneric): """ Two-step extension ring with floating point precision. @@ -380,6 +387,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, self.register_coercion(pAdicRelativeBaseringInjection(approx_modulus.base_ring(), self)) self.register_conversion(pAdicConvert_QQ_FP(self)) + class RelativeRamifiedExtensionFieldFloatingPoint(EisensteinExtensionGeneric, pAdicFloatingPointFieldGeneric): """ Two-step extension field with floating point precision. diff --git a/src/sage/rings/padics/relative_ramified_CA.pyx b/src/sage/rings/padics/relative_ramified_CA.pyx index 42337d04979..361c160cebe 100644 --- a/src/sage/rings/padics/relative_ramified_CA.pyx +++ b/src/sage/rings/padics/relative_ramified_CA.pyx @@ -20,7 +20,7 @@ cdef class RelativeRamifiedCappedAbsoluteElement(CAElement): sage: W(5)._poly_rep() 5 - The coefficients of P are floating point p-adics:: + The coefficients of P are floating point `p`-adics:: sage: P = W.random_element()._poly_rep() sage: ring = P.parent().base_ring() diff --git a/src/sage/rings/padics/relative_ramified_CR.pyx b/src/sage/rings/padics/relative_ramified_CR.pyx index 5263c190966..1bf0b815a3d 100644 --- a/src/sage/rings/padics/relative_ramified_CR.pyx +++ b/src/sage/rings/padics/relative_ramified_CR.pyx @@ -20,7 +20,7 @@ cdef class RelativeRamifiedCappedRelativeElement(CRElement): sage: W(5)._poly_rep() 5 - The coefficients of P are floating point p-adics:: + The coefficients of P are floating point `p`-adics:: sage: P = W.random_element()._poly_rep() sage: ring = P.parent().base_ring() diff --git a/src/sage/rings/padics/relative_ramified_FM.pyx b/src/sage/rings/padics/relative_ramified_FM.pyx index 27d18035ccb..7ec08b1af4e 100644 --- a/src/sage/rings/padics/relative_ramified_FM.pyx +++ b/src/sage/rings/padics/relative_ramified_FM.pyx @@ -20,7 +20,7 @@ cdef class RelativeRamifiedFixedModElement(FMElement): sage: W(5)._poly_rep() 5 - The coefficients of P are fixed-mod p-adics:: + The coefficients of P are fixed-mod `p`-adics:: sage: P = W.random_element()._poly_rep() sage: ring = P.parent().base_ring() diff --git a/src/sage/rings/padics/relative_ramified_FP.pyx b/src/sage/rings/padics/relative_ramified_FP.pyx index 3cbae5e55d3..2ac6656f753 100644 --- a/src/sage/rings/padics/relative_ramified_FP.pyx +++ b/src/sage/rings/padics/relative_ramified_FP.pyx @@ -20,7 +20,7 @@ cdef class RelativeRamifiedFloatingPointElement(FPElement): sage: W(5)._poly_rep() 5 - The coefficients of P are floating point p-adics:: + The coefficients of P are floating point `p`-adics:: sage: P = W.random_element()._poly_rep() sage: ring = P.parent().base_ring() diff --git a/src/sage/rings/padics/relaxed_template.pxi b/src/sage/rings/padics/relaxed_template.pxi index 7068a1425a2..1b6b4fb0833 100644 --- a/src/sage/rings/padics/relaxed_template.pxi +++ b/src/sage/rings/padics/relaxed_template.pxi @@ -112,7 +112,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``p`` -- a prime, which is compared with the parent of this element. + - ``p`` -- a prime, which is compared with the parent of this element EXAMPLES:: @@ -128,15 +128,14 @@ cdef class RelaxedElement(pAdicGenericElement): r""" Return a pointer on the `i`-th significant digit of this number. - .. NOTE: + .. NOTE:: This function does not check that the requested digit has been already computed. INPUT: - - ``i`` -- a positive integer - + - ``i`` -- positive integer """ pass @@ -145,15 +144,14 @@ cdef class RelaxedElement(pAdicGenericElement): Return a pointer on the digit in position `i` of this number. - .. NOTE: + .. NOTE:: This function do not check that the requested digit has been already computed. INPUT: - - ``i`` -- an integer - + - ``i`` -- integer """ pass @@ -165,10 +163,10 @@ cdef class RelaxedElement(pAdicGenericElement): - ``slice`` -- a ``celement`` to store the slice - - ``start`` -- a positive integer, the starting position of the slice + - ``start`` -- positive integer; the starting position of the slice in relative precision - - ``length`` -- a positive integer, the length of the slice + - ``length`` -- positive integer; the length of the slice .. NOTE:: @@ -182,9 +180,7 @@ cdef class RelaxedElement(pAdicGenericElement): r""" Compute the next digit of this number. - OUTPUT: - - An error code which is a superposition of the following: + OUTPUT: an error code which is a superposition of the following: - ``0`` -- no error - ``ERROR_ABANDON = 1`` -- computation has been abandoned @@ -204,7 +200,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -227,16 +223,15 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer - - ``halt`` -- an integer; the absolute precision after which the + - ``halt`` -- integer; the absolute precision after which the computation is abandoned if the first significant digit has not been found yet OUTPUT: An error code (see :meth:`_next_c` for details). - """ if self._valuation >= maxordp: return 0 @@ -276,7 +271,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -332,14 +327,14 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``n`` -- an integer or ``None`` (default ``None``); if - given, return the corresponding entries in the expansion. + - ``n`` -- integer or ``None`` (default: ``None``); if + given, return the corresponding entries in the expansion - ``lift_mode`` -- ``'simple'``, ``'smallest'`` or ``'teichmuller'`` (default: ``'simple'``) - ``start_val`` -- start at this valuation rather than the - default (`0` or the valuation of this element). + default (`0` or the valuation of this element) OUTPUT: @@ -351,7 +346,7 @@ cdef class RelaxedElement(pAdicGenericElement): EXAMPLES:: - sage: R = ZpER(7, print_mode="digits") + sage: R = ZpER(7, print_mode='digits') sage: a = R(1/2021); a ...23615224635636163463 @@ -443,7 +438,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``n`` -- an integer or a slice + - ``n`` -- integer or a slice EXAMPLES:: @@ -490,13 +485,13 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``start`` -- an integer or ``None`` (default: ``None``), + - ``start`` -- integer or ``None`` (default: ``None``); the first position of the slice - - ``stop`` -- an integer or ``None`` (default: ``None``), + - ``stop`` -- integer or ``None`` (default: ``None``); the first position not included in the slice - - ``bound`` -- a boolean (default: ``False``); whether the + - ``bound`` -- boolean (default: ``False``); whether the precision on the output should be bounded or unbounded EXAMPLES:: @@ -594,7 +589,6 @@ cdef class RelaxedElement(pAdicGenericElement): sage: b[:15] # indirect doctest 1 + 5 + 3*5^3 + 3*5^4 + 5^5 + 4*5^6 + 4*5^7 + 2*5^8 + 3*5^9 + 2*5^10 + 5^11 + 5^12 + 5^13 + O(5^15) - """ # This code should be integrated to the p-adic printer if self._valuation <= -maxordp: @@ -634,11 +628,10 @@ cdef class RelaxedElement(pAdicGenericElement): - ``right`` -- the second element involved in the comparison - - ``prec`` -- an integer, the precision at which the equality is checked - - - ``permissive`` -- a boolean; if ``True``, be silent if the precision - on one input is less than ``prec``; otherwise, raise an error + - ``prec`` -- integer; the precision at which the equality is checked + - ``permissive`` -- boolean; if ``True``, be silent if the precision + on one input is less than ``prec``. Otherwise, raise an error. """ cdef int error cdef long i @@ -670,7 +663,7 @@ cdef class RelaxedElement(pAdicGenericElement): - ``right`` -- a relaxed `p`-adic number - - ``prec`` -- an integer + - ``prec`` -- integer EXAMPLES:: @@ -698,11 +691,11 @@ cdef class RelaxedElement(pAdicGenericElement): - ``right`` -- a relaxed `p`-adic number - - ``prec`` -- an integer or ``None`` (default: ``None``); if - given, compare the two elements at this precision; otherwise - use the default halting precision of the parent + - ``prec`` -- integer or ``None`` (default: ``None``); if + given, compare the two elements at this precision. Otherwise + use the default halting precision of the parent. - - ``secure`` -- a boolean (default: ``False`` if ``prec`` is given, + - ``secure`` -- boolean (default: ``False`` if ``prec`` is given, ``True`` otherwise); when the elements cannot be distinguished at the given precision, raise an error if ``secure`` is ``True``, return ``True`` otherwise. @@ -858,7 +851,6 @@ cdef class RelaxedElement(pAdicGenericElement): O(5^20) sage: b._is_exact_zero() False - """ return self._valuation >= maxordp @@ -869,7 +861,7 @@ cdef class RelaxedElement(pAdicGenericElement): EXAMPLES:: - sage: R = ZpER(5, print_mode="digits") + sage: R = ZpER(5, print_mode='digits') sage: a = R(20/21) Computations have not started yet; hence we are not able @@ -1054,10 +1046,10 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); if ``None``, use the default precision of the parent - - ``permissive`` -- a boolean (default: ``False`` if ``prec`` + - ``permissive`` -- boolean (default: ``False`` if ``prec`` is given, ``True`` otherwise); if ``False``, raise an error if the precision of this element is not sufficient @@ -1123,7 +1115,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``absprec`` -- an integer or infinity + - ``absprec`` -- integer or infinity EXAMPLES:: @@ -1156,16 +1148,16 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); if ``None``, use the default precision of the parent - - ``halt`` -- an integer or a boolean (default: ``True``); + - ``halt`` -- integer or boolean (default: ``True``); the absolute precision after which the computation is abandoned - if the first significant digit has not been found yet; - if ``True``, the default halting precision of the parent is used; - if ``False``, the computation is never abandoned + if the first significant digit has not been found yet. + If ``True``, the default halting precision of the parent is used. + If ``False``, the computation is never abandoned. - - ``permissive`` -- a boolean (default: ``False`` if ``prec`` + - ``permissive`` -- boolean (default: ``False`` if ``prec`` is given, ``True`` otherwise); if ``False``, raise an error if the precision of this element is not sufficient @@ -1204,7 +1196,7 @@ cdef class RelaxedElement(pAdicGenericElement): sage: b.at_precision_relative(5, halt=21) # now, we're okay 5^20 + O(5^25) - .. NOTE: + .. NOTE:: It is also possible to pass in ``halt=False`` but it is not recommended because the computation can hang forever if this element is `0`. @@ -1254,7 +1246,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``absprec`` -- an integer or ``None`` (default: ``None``), the + - ``absprec`` -- integer or ``None`` (default: ``None``); the absolute precision of the result. If ``None``, the default precision of the parent is used. @@ -1325,9 +1317,9 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``halt`` -- an integer; if given, allow to increase the + - ``halt`` -- integer; if given, allow to increase the absolute precision on this element up to ``halt`` in order - to get a better lower bound. + to get a better lower bound """ cdef int error = 0 while not error and self._precrel == 0 and self._valuation < halt: @@ -1340,16 +1332,16 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``halt`` -- an integer or a boolean (default: ``True``); + - ``halt`` -- integer or boolean (default: ``True``); the absolute precision after which the computation is abandoned - if the first significant digit has not been found yet; - if ``True``, the default halting precision of the parent is used; - if ``False``, the computation is never abandoned + if the first significant digit has not been found yet. + If ``True``, the default halting precision of the parent is used. + If ``False``, the computation is never abandoned. - - ``secure`` -- a boolean (default: the value given at the creation + - ``secure`` -- boolean (default: the value given at the creation of the parent); when the valuation cannot be determined for sure, raise an error if ``secure`` is ``True``, return the best known - lower bound on the valuation otherwise. + lower bound on the valuation otherwise EXAMPLES:: @@ -1408,7 +1400,7 @@ cdef class RelaxedElement(pAdicGenericElement): sage: z.valuation(halt=21) # now, we're okay 20 - .. NOTE: + .. NOTE:: It is also possible to pass in ``halt=False`` but it is not recommended because the computation can hang forever if this element is `0`. @@ -1444,11 +1436,11 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``halt`` -- an integer or a boolean (default: ``True``); + - ``halt`` -- integer or boolean (default: ``True``); the absolute precision after which the computation is abandoned - if the first significant digit has not been found yet; - if ``True``, the default halting precision of the parent is used; - if ``False``, the computation is never abandoned + if the first significant digit has not been found yet. + If ``True``, the default halting precision of the parent is used. + If ``False``, the computation is never abandoned. EXAMPLES:: @@ -1476,7 +1468,6 @@ cdef class RelaxedElement(pAdicGenericElement): ValueError: unit part of 0 not defined See :meth:`valuation` for more details on the parameter ``halt``. - """ val = self.valuation(halt) if self._valuation >= self._precbound: @@ -1489,11 +1480,11 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``halt`` -- an integer or a boolean (default: ``True``); + - ``halt`` -- integer or boolean (default: ``True``); the absolute precision after which the computation is abandoned - if the first significant digit has not been found yet; - if ``True``, the default halting precision of the parent is used; - if ``False``, the computation is never abandoned + if the first significant digit has not been found yet. + If ``True``, the default halting precision of the parent is used. + If ``False``, the computation is never abandoned. EXAMPLES:: @@ -1522,7 +1513,6 @@ cdef class RelaxedElement(pAdicGenericElement): ValueError: unit part of 0 not defined See :meth:`valuation` for more details on the parameter ``halt``. - """ val = self.valuation(halt) if self._valuation >= self._precbound: @@ -1536,13 +1526,13 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``absprec`` -- a non-negative integer (default: ``1``) + - ``absprec`` -- nonnegative integer (default: 1) - - ``field`` -- boolean (default ``True``); when ``absprec`` is ``1``, - whether to return an element of GF(p) or Zmod(p). + - ``field`` -- boolean (default: ``True``); when ``absprec`` is ``1``, + whether to return an element of GF(p) or Zmod(p) - - ``check_prec`` -- boolean (default ``True``); whether to raise an error - if this element has insufficient precision to determine the reduction. + - ``check_prec`` -- boolean (default: ``True``); whether to raise an error + if this element has insufficient precision to determine the reduction EXAMPLES:: @@ -1561,7 +1551,7 @@ cdef class RelaxedElement(pAdicGenericElement): sage: b.residue() Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue """ if absprec >= maxordp: raise OverflowError @@ -1570,7 +1560,7 @@ cdef class RelaxedElement(pAdicGenericElement): error = self._jump_c(absprec) raise_error(error, not check_prec) if self._valuation < 0: - raise ValueError("element must have non-negative valuation in order to compute residue") + raise ValueError("element must have nonnegative valuation in order to compute residue") cdef celement digits cdef Integer ans if absprec <= self._valuation: @@ -1590,7 +1580,7 @@ cdef class RelaxedElement(pAdicGenericElement): INPUT: - - ``absprec`` -- an integer or ``None`` (default: ``None``); if ``None``, + - ``absprec`` -- integer or ``None`` (default: ``None``); if ``None``, the absolute precision of this element is used EXAMPLES:: @@ -1882,7 +1872,7 @@ cdef class RelaxedElement(pAdicGenericElement): sage: b 2 + 3 + 3^2 + 3^3 + 3^4 + ... - A ``ZeroDivisionError`` is raised if an element has no inverse in the + A :exc:`ZeroDivisionError` is raised if an element has no inverse in the ring:: sage: R(3).inverse_of_unit() @@ -1988,7 +1978,7 @@ cdef class RelaxedElement(pAdicGenericElement): def _test_pickling(self, **options): r""" - Checks that this object can be pickled and unpickled properly. + Check that this object can be pickled and unpickled properly. TESTS:: @@ -2030,7 +2020,7 @@ cdef class RelaxedElement(pAdicGenericElement): cdef class RelaxedElement_abandon(RelaxedElement): r""" - A special class for relaxed p-adic with all digits unknown. + A special class for relaxed `p`-adic with all digits unknown. This class is used for setting temporary definition of some self-referent numbers. @@ -2068,7 +2058,7 @@ cdef relaxedelement_abandon = RelaxedElement_abandon() cdef class RelaxedElementWithDigits(RelaxedElement): r""" - A generic class for relaxed p-adic elements that stores + A generic class for relaxed `p`-adic elements that stores the sequence of its digits. """ def __cinit__(self): @@ -2105,9 +2095,9 @@ cdef class RelaxedElementWithDigits(RelaxedElement): - ``slice`` -- a ``celement`` to store the slice - - ``start`` -- an integer, the start position of the slice + - ``start`` -- integer; the start position of the slice - - ``length`` -- an integer, the length of the slice + - ``length`` -- integer; the length of the slice .. NOTE:: @@ -2125,7 +2115,7 @@ cdef class RelaxedElementWithDigits(RelaxedElement): cdef class RelaxedElement_zero(RelaxedElement): r""" - A class for representation a relaxed p-adic number which is + A class for representation a relaxed `p`-adic number which is exactly zero. TESTS:: @@ -2133,7 +2123,6 @@ cdef class RelaxedElement_zero(RelaxedElement): sage: R = ZpER(7) sage: a = R.zero() sage: TestSuite(a).run() - """ def __init__(self, parent): r""" @@ -2193,9 +2182,9 @@ cdef class RelaxedElement_zero(RelaxedElement): - ``slice`` -- a ``celement`` to store the slice - - ``start`` -- an integer, the start position of the slice + - ``start`` -- integer; the start position of the slice - - ``length`` -- an integer, the length of the slice + - ``length`` -- integer; the length of the slice """ element_init(slice) @@ -2205,7 +2194,7 @@ cdef class RelaxedElement_zero(RelaxedElement): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -2228,7 +2217,7 @@ cdef class RelaxedElement_zero(RelaxedElement): cdef class RelaxedElement_one(RelaxedElementWithDigits): r""" - A class for representation a relaxed p-adic number which is + A class for representation a relaxed `p`-adic number which is exactly one. TESTS:: @@ -2236,7 +2225,6 @@ cdef class RelaxedElement_one(RelaxedElementWithDigits): sage: R = ZpER(7) sage: a = R.one() sage: TestSuite(a).run() - """ def __init__(self, parent): r""" @@ -2281,7 +2269,7 @@ cdef class RelaxedElement_one(RelaxedElementWithDigits): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -2307,8 +2295,8 @@ cdef class RelaxedElement_one(RelaxedElementWithDigits): cdef class RelaxedElement_bound(RelaxedElement): r""" - A class for p-adic relaxed elements which are defined by bounding the - precision of another p-adic relaxed element. + A class for `p`-adic relaxed elements which are defined by bounding the + precision of another `p`-adic relaxed element. TESTS:: @@ -2327,7 +2315,7 @@ cdef class RelaxedElement_bound(RelaxedElement): - ``x`` -- a relaxed `p`-adics, the element to bound - - ``precbound`` -- an integer or ``None`` (default: ``None``), + - ``precbound`` -- integer or ``None`` (default: ``None``); the bound on the precision .. NOTE:: @@ -2389,10 +2377,10 @@ cdef class RelaxedElement_bound(RelaxedElement): - ``slice`` -- a ``celement`` to store the slice - - ``start`` -- a positive integer, the starting position of the slice + - ``start`` -- positive integer; the starting position of the slice in relative precision - - ``length`` -- a positive integer, the length of the slice + - ``length`` -- positive integer; the length of the slice .. NOTE:: @@ -2408,7 +2396,7 @@ cdef class RelaxedElement_bound(RelaxedElement): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -2466,10 +2454,10 @@ cdef class RelaxedElement_value(RelaxedElementWithDigits): - ``value`` -- the value in the exact subring - - ``shift`` -- an integer (default: `0`), the position at which + - ``shift`` -- integer (default: `0`); the position at which the given value is written - - ``precbound`` -- an integer or ``None`` (default: ``None``), + - ``precbound`` -- integer or ``None`` (default: ``None``); the bound on the precision TESTS:: @@ -2514,7 +2502,7 @@ cdef class RelaxedElement_value(RelaxedElementWithDigits): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -2582,15 +2570,15 @@ cdef class RelaxedElement_random(RelaxedElementWithDigits): - ``parent`` -- the parent of this element - - ``valuation`` -- an integer or ``None``, the position from which + - ``valuation`` -- integer or ``None``; the position from which random digits are picked; if ``None``, it is randomly chosen if the parent is a field and set to `0` otherwise - - ``precbound`` -- an integer or ``None`` (default: ``None``), + - ``precbound`` -- integer or ``None`` (default: ``None``); the bound on the precision - - ``seed`` -- an integer or ``None`` (default: ``None``), the + - ``seed`` -- integer or ``None`` (default: ``None``); the seed of the random generator .. NOTE:: @@ -2628,7 +2616,7 @@ cdef class RelaxedElement_random(RelaxedElementWithDigits): TESTS:: - sage: R = ZpER(5, print_mode="digits") + sage: R = ZpER(5, print_mode='digits') sage: a = R.random_element() sage: a # random ...32220241412003314311 @@ -2696,13 +2684,13 @@ cdef class RelaxedElement_slice(RelaxedElement): - ``x`` -- a relaxed `p`-adic element, the element from which the slice is extracted - - ``start`` -- an integer, the position of the first digit of `x` + - ``start`` -- integer; the position of the first digit of `x` in the slice - - ``stop`` -- an integer, the position of the first digit of `x` + - ``stop`` -- integer; the position of the first digit of `x` after the slice - - ``shift`` -- an integer such that ``self[i] = x[i+shift]`` + - ``shift`` -- integer such that ``self[i] = x[i+shift]`` .. NOTE:: @@ -2739,7 +2727,7 @@ cdef class RelaxedElement_slice(RelaxedElement): TESTS:: - sage: R = ZpER(5, print_mode="digits") + sage: R = ZpER(5, print_mode='digits') sage: x = R(20/21) sage: y = x.slice(3, 6) sage: y == loads(dumps(y)) # indirect doctest @@ -2773,9 +2761,9 @@ cdef class RelaxedElement_slice(RelaxedElement): - ``slice`` -- a ``celement`` to store the slice - - ``start`` -- an integer, the start position of the slice + - ``start`` -- integer; the start position of the slice - - ``length`` -- an integer, the length of the slice + - ``length`` -- integer; the length of the slice .. NOTE:: @@ -2795,7 +2783,7 @@ cdef class RelaxedElement_slice(RelaxedElement): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -2902,7 +2890,7 @@ cdef class RelaxedElement_add(RelaxedElementWithDigits): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -3009,7 +2997,7 @@ cdef class RelaxedElement_sub(RelaxedElementWithDigits): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -3252,7 +3240,6 @@ cdef class RelaxedElement_muldigit(RelaxedElementWithDigits): digit is the first factor - ``y`` -- a relaxed `p`-adic element, the second factor - """ RelaxedElement.__init__(self, parent) self._x = x._inverse @@ -3325,9 +3312,9 @@ cdef class RelaxedElement_div(RelaxedElementWithDigits): - ``denom`` -- a relaxed `p`-adic element, the divisor - - ``minval`` -- an integer, the minimal valuation allowed for this element + - ``minval`` -- integer; the minimal valuation allowed for this element - - ``precbound`` -- an integer or ``None`` (default: ``None``), + - ``precbound`` -- integer or ``None`` (default: ``None``); the bound on the precision TESTS:: @@ -3540,7 +3527,6 @@ cdef class RelaxedElement_sqrt(RelaxedElementWithDigits): .. NOTE:: This code does not work for nontrivial extensions of `\QQ_2`. - """ cdef RelaxedElement x = self._x cdef long maxprec @@ -3654,7 +3640,7 @@ cdef class RelaxedElement_teichmuller(RelaxedElementWithDigits): - ``parent`` -- the parent of this element - ``xbar`` -- an element in the exact subring, which is congruent - to this Teichmüller modulo this uniformizer. + to this Teichmüller modulo this uniformizer TESTS:: @@ -3717,7 +3703,7 @@ cdef class RelaxedElement_teichmuller(RelaxedElementWithDigits): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -3781,10 +3767,10 @@ cdef class RelaxedElement_unknown(RelaxedElementWithDigits): - ``parent`` -- the parent of this element - - ``valuation`` -- an integer, a lower bound on the valuation of + - ``valuation`` -- integer; a lower bound on the valuation of this number - - ``digits`` -- a list or ``None`` (default: ``None``), the first + - ``digits`` -- list or ``None`` (default: ``None``); the first significant digits of this number TESTS:: @@ -3987,7 +3973,6 @@ cdef class RelaxedElement_zeroone(RelaxedElementWithDigits): - ``parent`` -- the parent of this element - ``valuation`` -- the valuation of this number - """ RelaxedElement.__init__(self, parent) self._valuation = valuation @@ -4011,7 +3996,7 @@ cdef class RelaxedElement_zeroone(RelaxedElementWithDigits): INPUT: - - ``prec`` -- an integer + - ``prec`` -- integer OUTPUT: @@ -4061,9 +4046,9 @@ cdef class ExpansionIter(): - ``mode`` -- either ``simple_mode``, ``smallest_mode`` or ``teichmuller_mode`` - - ``start`` -- an integer, the position where the expansion starts + - ``start`` -- integer; the position where the expansion starts - - ``stop`` -- an integer, the position where the expansion stops + - ``stop`` -- integer; the position where the expansion stops TESTS:: diff --git a/src/sage/rings/padics/relaxed_template_header.pxi b/src/sage/rings/padics/relaxed_template_header.pxi index 7a57141e922..044283ee7d0 100644 --- a/src/sage/rings/padics/relaxed_template_header.pxi +++ b/src/sage/rings/padics/relaxed_template_header.pxi @@ -1,6 +1,6 @@ """ This file provides the declaration for the RelaxedElement class, -which collects common functionality for the different relaxed p-adic +which collects common functionality for the different relaxed `p`-adic template classes. It is included in padic_relaxed_element.pxd and should be included diff --git a/src/sage/rings/padics/tutorial.py b/src/sage/rings/padics/tutorial.py index 45459711382..da0c80f021c 100644 --- a/src/sage/rings/padics/tutorial.py +++ b/src/sage/rings/padics/tutorial.py @@ -77,7 +77,7 @@ The *absolute precision* of a finite approximation `\bar{x} \in \ZZ/p^n\ZZ` to `x \in \ZZ_p` -is the non-negative integer `n`. +is the nonnegative integer `n`. In the second representation, we can achieve the same thing by truncating a series diff --git a/src/sage/rings/padics/unramified_extension_generic.py b/src/sage/rings/padics/unramified_extension_generic.py index 3ca4d07b2b0..7eb99efe585 100644 --- a/src/sage/rings/padics/unramified_extension_generic.py +++ b/src/sage/rings/padics/unramified_extension_generic.py @@ -31,16 +31,16 @@ class UnramifiedExtensionGeneric(pAdicExtensionGeneric): """ def __init__(self, poly, prec, print_mode, names, element_class): """ - Initializes ``self``. + Initialize ``self``. INPUT: - - ``poly`` -- Polynomial defining this extension. - - ``prec`` -- The precision cap - - ``print_mode`` -- a dictionary with print options + - ``poly`` -- polynomial defining this extension + - ``prec`` -- the precision cap + - ``print_mode`` -- dictionary with print options - ``names`` -- a 4-tuple, (``variable_name``, ``residue_name``, ``unramified_subextension_variable_name``, ``uniformizer_name``) - - ``element_class`` -- the class for elements of this unramified extension. + - ``element_class`` -- the class for elements of this unramified extension EXAMPLES:: @@ -100,7 +100,7 @@ def absolute_f(self): def residue_class_field(self): """ - Returns the residue class field. + Return the residue class field. EXAMPLES:: @@ -141,7 +141,7 @@ def discriminant(self, K=None): INPUT: - - ``K`` -- a subring/subfield (defaults to the base ring). + - ``K`` -- a subring/subfield (defaults to the base ring) EXAMPLES:: @@ -161,7 +161,7 @@ def discriminant(self, K=None): #def galois_group(self): # r""" - # Returns the Galois group of self's fraction field over Qp. + # Returns the Galois group of ``self``'s fraction field over Qp. # """ # ## # ## If K is a number field, then K.galois_group() can return @@ -182,7 +182,7 @@ def is_galois(self, K=None): INPUT: - - ``K`` -- a subring/subfield (defaults to the base ring). + - ``K`` -- a subring/subfield (defaults to the base ring) EXAMPLES:: @@ -213,7 +213,7 @@ def gen(self, n=0): @cached_method def _frob_gen(self, arithmetic=True): """ - Return frobenius of the generator for this unramified extension + Return frobenius of the generator for this unramified extension. EXAMPLES:: @@ -294,9 +294,7 @@ def has_pth_root(self): - ``self`` -- a `p`-adic ring - OUTPUT: - - boolean -- whether ``self`` has primitive `p`-th root of unity. + OUTPUT: boolean; whether ``self`` has primitive `p`-th root of unity EXAMPLES:: @@ -315,11 +313,9 @@ def has_root_of_unity(self, n): INPUT: - ``self`` -- a `p`-adic ring - - ``n`` -- an integer - - OUTPUT: + - ``n`` -- integer - - boolean + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/rings/pari_ring.py b/src/sage/rings/pari_ring.py index f34a45829a0..b8f2b62d5a7 100644 --- a/src/sage/rings/pari_ring.py +++ b/src/sage/rings/pari_ring.py @@ -124,7 +124,7 @@ def __pow__(self, other): sage: a^2 9 """ - if not (other in PariRing()): + if other not in PariRing(): other = Pari(other) return self.__class__(self.__x ** other.__x, parent=_inst) @@ -202,8 +202,8 @@ def random_element(self, x=None, y=None, distribution=None): between 0 and `x-1`, inclusive. If both are provided, then the result is between `x` and `y-1`, inclusive. - - `distribution` -- optional string, so that ``ZZ`` can make sense - of it as a probability distribution. + - ``distribution`` -- (optional) string, so that ``ZZ`` can make sense + of it as a probability distribution EXAMPLES:: @@ -212,9 +212,8 @@ def random_element(self, x=None, y=None, distribution=None): True sage: R(5) <= R.random_element(5,13) < R(13) True - sage: R.random_element(distribution="1/n").parent() is R + sage: R.random_element(distribution='1/n').parent() is R True - """ from sage.rings.integer_ring import ZZ return self(ZZ.random_element(x, y, distribution)) diff --git a/src/sage/rings/polynomial/binary_form_reduce.py b/src/sage/rings/polynomial/binary_form_reduce.py index 6afb11155cf..8d4c770072d 100644 --- a/src/sage/rings/polynomial/binary_form_reduce.py +++ b/src/sage/rings/polynomial/binary_form_reduce.py @@ -62,8 +62,7 @@ def covariant_z0(F, z0_cov=False, prec=53, emb=None, error_limit=0.000001): - ``emb`` -- embedding into CC - - ``error_limit`` -- sets the error tolerance (default:0.000001) - + - ``error_limit`` -- sets the error tolerance (default: 0.000001) OUTPUT: a complex number, a real number @@ -79,8 +78,8 @@ def covariant_z0(F, z0_cov=False, prec=53, emb=None, error_limit=0.000001): sage: F = -x^8 + 6*x^7*y - 7*x^6*y^2 - 12*x^5*y^3 + 27*x^4*y^4\ ....: - 4*x^3*y^5 - 19*x^2*y^6 + 10*x*y^7 - 5*y^8 sage: covariant_z0(F, prec=80) - (0.64189877107807122203369 + 1.1852516565091601348355*I, - 3134.5148284344627168275) + (0.64189877107807122203366 + 1.1852516565091601348355*I, + 3134.5148284344627168276) :: @@ -271,15 +270,15 @@ def epsinv(F, target, prec=53, target_tol=0.001, z=None, emb=None): - ``F`` -- binary form of degree at least 3 with no multiple roots - - ``target`` -- positive real number. The value we want to attain, i.e., + - ``target`` -- positive real number; the value we want to attain, i.e., the value we are taking the inverse of - - ``prec`` -- positive integer. precision to use in CC + - ``prec`` -- positive integer; precision to use in CC - - ``target_tol`` -- positive real number. The tolerance with which we - attain the target value. + - ``target_tol`` -- positive real number; the tolerance with which we + attain the target value - - ``z`` -- complex number. ``z_0`` covariant for F. + - ``z`` -- complex number; ``z_0`` covariant for F - ``emb`` -- embedding into CC @@ -435,7 +434,7 @@ def get_bound_poly(F, prec=53, norm_type='norm', emb=None): def smallest_poly(F, prec=53, norm_type='norm', emb=None): r""" - Determine the poly with smallest coefficients in `SL(2,\Z)` orbit of ``F`` + Determine the poly with smallest coefficients in `SL(2,\Z)` orbit of ``F``. Smallest can be in the sense of `L_2` norm or height. The method is the algorithm in Hutz-Stoll [HS2018]_. @@ -448,8 +447,8 @@ def smallest_poly(F, prec=53, norm_type='norm', emb=None): - ``F`` -- binary form of degree at least 3 with no multiple roots - - ``norm_type`` -- string; ``norm`` or ``height`` controlling what ``smallest`` - means for the coefficients. + - ``norm_type`` -- string; ``'norm'`` or ``'height'`` controlling what + ``smallest`` means for the coefficients OUTPUT: pair [poly, matrix] diff --git a/src/sage/rings/polynomial/commutative_polynomial.pyx b/src/sage/rings/polynomial/commutative_polynomial.pyx index dc9f2cab8b7..7e2e7be4fc8 100644 --- a/src/sage/rings/polynomial/commutative_polynomial.pyx +++ b/src/sage/rings/polynomial/commutative_polynomial.pyx @@ -1,6 +1,6 @@ cdef class CommutativePolynomial(CommutativeAlgebraElement): r""" - Abstract base class for commutative polynomials in any number of variables + Abstract base class for commutative polynomials in any number of variables. It is a common base for :class:`~sage.rings.polynomial.polynomial_element.Polynomial`, :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial`, and diff --git a/src/sage/rings/polynomial/complex_roots.py b/src/sage/rings/polynomial/complex_roots.py index 602ba9ffc27..0c94bac6035 100644 --- a/src/sage/rings/polynomial/complex_roots.py +++ b/src/sage/rings/polynomial/complex_roots.py @@ -54,9 +54,9 @@ def interval_roots(p, rts, prec): and a precision. We attempt to verify that the estimated roots are in fact distinct - roots of the polynomial, using interval arithmetic of precision prec. + roots of the polynomial, using interval arithmetic of precision ``prec``. If we succeed, we return a list of intervals bounding the roots; if we - fail, we return None. + fail, we return ``None``. EXAMPLES:: diff --git a/src/sage/rings/polynomial/convolution.py b/src/sage/rings/polynomial/convolution.py index 653bc37799c..0f7cc5fadfa 100644 --- a/src/sage/rings/polynomial/convolution.py +++ b/src/sage/rings/polynomial/convolution.py @@ -191,7 +191,7 @@ def _fft(L, K, start, depth, root): `S = R[y]/(y^K + 1)`. This function performs an inplace FFT, i.e. evaluates the - polynomial at x = each D-th root of unity in S (namely the powers + polynomial at x = each `D`-th root of unity in S (namely the powers of `y^{2K/D}`), with results in bit-reversed order. """ half = 1 << (depth - 1) diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index 84f85104cc3..8c9088434fa 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -40,6 +40,7 @@ try: except ImportError: pass + def cyclotomic_coeffs(nn, sparse=None): """ Return the coefficients of the `n`-th cyclotomic polynomial @@ -57,7 +58,7 @@ def cyclotomic_coeffs(nn, sparse=None): form `1-x^n` can be done very quickly in a single pass. If ``sparse`` is ``True``, the result is returned as a dictionary of - the non-zero entries, otherwise the result is returned as a list + the nonzero entries, otherwise the result is returned as a list of python ints. EXAMPLES:: @@ -208,9 +209,7 @@ def cyclotomic_value(n, x): - ``x`` -- an element of a ring - OUTPUT: - - - the value of the cyclotomic polynomial `\Phi_n` at `x` + OUTPUT: the value of the cyclotomic polynomial `\Phi_n` at `x` ALGORITHM: diff --git a/src/sage/rings/polynomial/flatten.py b/src/sage/rings/polynomial/flatten.py index ef71d2b13a6..6354bbcd382 100644 --- a/src/sage/rings/polynomial/flatten.py +++ b/src/sage/rings/polynomial/flatten.py @@ -38,8 +38,8 @@ from sage.categories.morphism import Morphism from sage.misc.cachefunc import cached_method from .polynomial_ring_constructor import PolynomialRing -from .polynomial_ring import is_PolynomialRing -from .multi_polynomial_ring_base import is_MPolynomialRing +from .polynomial_ring import PolynomialRing_general +from .multi_polynomial_ring_base import MPolynomialRing_base from sage.rings.fraction_field import FractionField_generic from sage.rings.fraction_field_element import FractionFieldElement from sage.rings.polynomial.polydict import ETuple @@ -79,7 +79,7 @@ class FlatteningMorphism(Morphism): """ def __init__(self, domain): """ - The Python constructor + The Python constructor. EXAMPLES:: @@ -160,14 +160,14 @@ def __init__(self, domain): sage: fl.section()(fl(p)) == p True """ - if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain): + if not isinstance(domain, PolynomialRing_general) and not isinstance(domain, MPolynomialRing_base): raise ValueError("domain should be a polynomial ring") ring = domain variables = [] intermediate_rings = [] - while is_PolynomialRing(ring) or is_MPolynomialRing(ring): + while isinstance(ring, PolynomialRing_general) or isinstance(ring, MPolynomialRing_base): intermediate_rings.append(ring) v = ring.variable_names() variables.extend(reversed(v)) @@ -181,7 +181,7 @@ def __init__(self, domain): if b not in variables: # not just variables[:i]! break variables[i] = b - if is_MPolynomialRing(domain): + if isinstance(domain, MPolynomialRing_base): codomain = PolynomialRing(ring, variables, len(variables)) else: codomain = PolynomialRing(ring, variables) @@ -221,16 +221,16 @@ def _call_(self, p): for ring in self._intermediate_rings: new_p = {} - if is_PolynomialRing(ring): + if isinstance(ring, PolynomialRing_general): for mon, pp in p.items(): assert pp.parent() is ring - for i, j in pp.dict().items(): - new_p[(i,)+(mon)] = j - elif is_MPolynomialRing(ring): + for i, j in pp.monomial_coefficients().items(): + new_p[(i,) + (mon)] = j + elif isinstance(ring, MPolynomialRing_base): for mon, pp in p.items(): assert pp.parent() is ring - for mmon, q in pp.dict().items(): - new_p[tuple(mmon)+mon] = q + for mmon, q in pp.monomial_coefficients().items(): + new_p[tuple(mmon) + mon] = q else: raise RuntimeError p = new_p @@ -285,7 +285,7 @@ def inverse(self): class UnflatteningMorphism(Morphism): r""" - Inverses for :class:`FlatteningMorphism` + Inverses for :class:`FlatteningMorphism`. EXAMPLES:: @@ -313,7 +313,7 @@ class UnflatteningMorphism(Morphism): def __init__(self, domain, codomain): """ - The Python constructor + The Python constructor. EXAMPLES:: @@ -345,17 +345,17 @@ def __init__(self, domain, codomain): ... ValueError: rings must have the same number of variables """ - if not is_MPolynomialRing(domain): + if not isinstance(domain, MPolynomialRing_base): raise ValueError("domain should be a multivariate polynomial ring") - if not is_PolynomialRing(codomain) and not is_MPolynomialRing(codomain): + if not isinstance(codomain, PolynomialRing_general) and not isinstance(codomain, MPolynomialRing_base): raise ValueError("codomain should be a polynomial ring") ring = codomain intermediate_rings = [] while True: - is_polynomial_ring = is_PolynomialRing(ring) - if not (is_polynomial_ring or is_MPolynomialRing(ring)): + is_polynomial_ring = isinstance(ring, PolynomialRing_general) + if not (is_polynomial_ring or isinstance(ring, MPolynomialRing_base)): break intermediate_rings.append((ring, is_polynomial_ring)) ring = ring.base_ring() @@ -416,7 +416,7 @@ def _call_(self, p): class SpecializationMorphism(Morphism): r""" - Morphisms to specialize parameters in (stacked) polynomial rings + Morphisms to specialize parameters in (stacked) polynomial rings. EXAMPLES:: @@ -463,7 +463,7 @@ class SpecializationMorphism(Morphism): def __init__(self, domain, D): """ - The Python constructor + The Python constructor. EXAMPLES:: @@ -499,7 +499,7 @@ def __init__(self, domain, D): Defn: Defined on coordinates by sending (z) to (z^2 + 1.00000000000000) """ - if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain): + if not isinstance(domain, PolynomialRing_general) and not isinstance(domain, MPolynomialRing_base): raise TypeError("domain should be a polynomial ring") # use only the generators that are in the stack somewhere, @@ -538,7 +538,7 @@ def __init__(self, domain, D): # Construct unflattened codomain R new_vars = [] R = domain - while is_PolynomialRing(R) or is_MPolynomialRing(R) or isinstance(R, FractionField_generic): + while isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base) or isinstance(R, FractionField_generic): if isinstance(R, FractionField_generic): # We've hit base_ring, so set _sub_specialization and exit the loop field_over = R.base() @@ -563,7 +563,7 @@ def __init__(self, domain, D): # We're still in the polynomials, so keep track of the tower old = R.gens() new = [t for t in old if t not in D] - force_multivariate = ((len(old) == 1) and is_MPolynomialRing(R)) + force_multivariate = ((len(old) == 1) and isinstance(R, MPolynomialRing_base)) new_vars.append((new, force_multivariate, old)) R = R.base_ring() @@ -642,7 +642,7 @@ def _call_(self, p): # apply _sub_specialization to each coefficient # in the flattened polynomial tmp = {} - for exponent, coefficient in flat.dict().items(): + for exponent, coefficient in flat.monomial_coefficients().items(): # Fix the type of exponent from (a,) to a # (necessary for R(tmp) later) if isinstance(exponent, ETuple) and len(exponent) == 1: @@ -664,7 +664,7 @@ class FractionSpecializationMorphism(Morphism): """ def __init__(self, domain, D): """ - Initialize the morphism with a domain and dictionary of specializations + Initialize the morphism with a domain and dictionary of specializations. EXAMPLES:: @@ -687,7 +687,7 @@ def __init__(self, domain, D): def _call_(self, p): """ - Evaluate a fraction specialization morphism + Evaluate a fraction specialization morphism. EXAMPLES:: @@ -700,7 +700,6 @@ def _call_(self, p): (3*x + 2*y)/(-2*z) sage: spec.parent() Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field - """ if not isinstance(p, FractionFieldElement): raise TypeError("p must be a fraction field element") diff --git a/src/sage/rings/polynomial/groebner_fan.py b/src/sage/rings/polynomial/groebner_fan.py index 83877f35072..d0a34b3cca8 100644 --- a/src/sage/rings/polynomial/groebner_fan.py +++ b/src/sage/rings/polynomial/groebner_fan.py @@ -58,14 +58,13 @@ """ import string +import re import pexpect from subprocess import PIPE, Popen -from sage.misc.sage_eval import sage_eval - from sage.structure.sage_object import SageObject from sage.interfaces.gfan import gfan -from .multi_polynomial_ideal import is_MPolynomialIdeal +from .multi_polynomial_ideal import MPolynomialIdeal from .polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ from sage.rings.integer import Integer @@ -104,7 +103,7 @@ def prefix_check(str_list): def max_degree(list_of_polys): """ - Compute the maximum degree of a list of polynomials + Compute the maximum degree of a list of polynomials. EXAMPLES:: @@ -124,8 +123,7 @@ def _cone_parse(fan_dict_cone): INPUT: - - ``fan_dict_cone`` -- the value of a fan_dict with - key 'CONES' + - ``fan_dict_cone`` -- the value of a ``fan_dict`` with key 'CONES' EXAMPLES:: @@ -290,8 +288,7 @@ def __init__(self, gfan_polyhedral_fan, parameter_indices=None): INPUT: - - ``gfan_polyhedral_fan`` -- output from gfan of a - polyhedral fan. + - ``gfan_polyhedral_fan`` -- output from gfan of a polyhedral fan EXAMPLES:: @@ -494,7 +491,7 @@ def is_simplicial(self): def to_RationalPolyhedralFan(self): """ - Converts to the RationalPolyhedralFan class, which is more actively + Convert to the RationalPolyhedralFan class, which is more actively maintained. While the information in each class is essentially the same, the methods and implementation are different. @@ -520,7 +517,6 @@ def to_RationalPolyhedralFan(self): [ 1 0 0 0 0 1 -2] [ 0 1 0 0 1 0 -2] [ 0 0 1 1 0 0 -2] - """ try: return self._fan @@ -656,12 +652,11 @@ def __init__(self, gfan_polyhedral_fan, polynomial_system, poly_ring, INPUT: - - ``gfan_polyhedral_fan`` -- output from ``gfan`` of a - polyhedral fan. - - ``polynomial_system`` -- a list of polynomials + - ``gfan_polyhedral_fan`` -- output from ``gfan`` of a polyhedral fan + - ``polynomial_system`` -- list of polynomials - ``poly_ring`` -- the polynomial ring of the list of polynomials - - ``parameters`` (optional) -- a list of variables to be considered - as parameters + - ``parameters`` -- (optional) list of variables to be considered + as parameters EXAMPLES:: @@ -725,7 +720,7 @@ def initial_form_systems(self): def ring_to_gfan_format(input_ring): """ - Converts a ring to gfan's format. + Convert a ring to gfan's format. EXAMPLES:: @@ -785,17 +780,17 @@ def __init__(self, I, is_groebner_basis=False, symmetry=None, verbose=False): INPUT: - - ``I`` -- ideal in a multivariate polynomial ring + - ``I`` -- ideal in a multivariate polynomial ring - - ``is_groebner_basis`` -- bool (default ``False``). if - ``True``, then I.gens() must be a Groebner basis with respect to the - standard degree lexicographic term order. + - ``is_groebner_basis`` -- boolean (default: ``False``); if + ``True``, then I.gens() must be a Groebner basis with respect to the + standard degree lexicographic term order - - ``symmetry`` -- default: ``None``; if not ``None``, describes - symmetries of the ideal + - ``symmetry`` -- (default: ``None``) if not ``None``, describes + symmetries of the ideal - - ``verbose`` -- default: ``False``; if ``True``, printout - useful info during computations + - ``verbose`` -- (default: ``False``) if ``True``, printout + useful info during computations EXAMPLES:: @@ -817,14 +812,13 @@ class to compute the Stanley-Reisner ideal of the tropical prevariety:: sage: RPF = PF.to_RationalPolyhedralFan() sage: RPF.Stanley_Reisner_ideal(PolynomialRing(QQ,4,'A, B, C, D')) Ideal (A*B, A*C, B*C*D) of Multivariate Polynomial Ring in A, B, C, D over Rational Field - """ self.__is_groebner_basis = is_groebner_basis self.__symmetry = symmetry if symmetry: print("WARNING! Symmetry option not yet implemented!!") self.__verbose = verbose - if not is_MPolynomialIdeal(I): + if not isinstance(I, MPolynomialIdeal): raise TypeError("I must be a multivariate polynomial ideal") if not prefix_check([str(R_gen) for R_gen in I.ring().gens()]): raise RuntimeError("Ring variables cannot contain each other as prefixes") @@ -844,7 +838,7 @@ class to compute the Stanley-Reisner ideal of the tropical prevariety:: def _repr_(self): """ - Describes the Groebner fan and its corresponding ideal. + Describe the Groebner fan and its corresponding ideal. EXAMPLES:: @@ -858,7 +852,7 @@ def _repr_(self): def __eq__(self, right): """ - Tests equality of Groebner fan objects. + Test equality of Groebner fan objects. EXAMPLES:: @@ -885,8 +879,6 @@ def ideal(self): def _gfan_maps(self): """ - INPUT: none - OUTPUT: - map from Sage ring to ``gfan`` ring @@ -983,8 +975,9 @@ def weight_vectors(self): stdin=PIPE, stdout=PIPE, stderr=PIPE) ans, err = gfan_processes.communicate(input=str_to_bytes(self.gfan())) ans = bytes_to_str(ans) - ans = sage_eval(ans.replace('{', '').replace('}', '').replace('\n', '')) - return [vector(QQ, x) for x in ans] + vect = re.compile(r"\([0-9,/\s]*\)") + ans = (tup[1:-1].split(',') for tup in vect.findall(ans)) + return [vector(QQ, [QQ(y) for y in x]) for x in ans] def ring(self): """ @@ -1114,9 +1107,9 @@ def gfan(self, cmd='bases', I=None, format=None): INPUT: - - ``cmd`` -- string (default:``'bases'``), GFan command - - ``I`` -- ideal (default:``None``) - - ``format`` -- bool (default:``None``), deprecated + - ``cmd`` -- string (default: ``'bases'``); GFan command + - ``I`` -- ideal (default: ``None``) + - ``format`` -- boolean (default: ``None``); deprecated EXAMPLES:: @@ -1157,7 +1150,7 @@ def __iter__(self): def __getitem__(self, i): """ - Get a reduced groebner basis + Get a reduced groebner basis. EXAMPLES:: @@ -1242,29 +1235,27 @@ def render(self, file=None, larger=False, shift=0, rgbcolor=(0, 0, 0), INPUT: - - ``file`` -- a filename if you prefer the output - saved to a file. This will be in xfig format. - - - ``shift`` -- shift the positions of the variables in - the drawing. For example, with shift=1, the corners will be b - (right), c (left), and d (top). The shifting is done modulo the - number of variables in the polynomial ring. The default is 0. + - ``file`` -- a filename if you prefer the output + saved to a file; this will be in xfig format - - ``larger`` -- bool (default: ``False``); if ``True``, make - the triangle larger so that the shape of the Groebner region - appears. Affects the xfig file but probably not the sage graphics - (?) + - ``shift`` -- shift the positions of the variables in + the drawing. For example, with shift=1, the corners will be b + (right), c (left), and d (top). The shifting is done modulo the + number of variables in the polynomial ring. The default is 0. - - ``rgbcolor`` -- This will not affect the saved xfig - file, only the sage graphics produced. + - ``larger`` -- boolean (default: ``False``); if ``True``, make + the triangle larger so that the shape of the Groebner region + appears. Affects the xfig file but probably not the sage graphics (?). - - ``polyfill`` -- Whether or not to fill the cones with - a color determined by the highest degree in each reduced Groebner - basis for that cone. + - ``rgbcolor`` -- this will not affect the saved xfig + file, only the sage graphics produced - - ``scale_colors`` -- if True, this will normalize - color values to try to maximize the range + - ``polyfill`` -- whether or not to fill the cones with + a color determined by the highest degree in each reduced Groebner + basis for that cone + - ``scale_colors`` -- if ``True``, this will normalize + color values to try to maximize the range EXAMPLES:: @@ -1281,7 +1272,7 @@ def render(self, file=None, larger=False, shift=0, rgbcolor=(0, 0, 0), TESTS: Testing the case where the number of generators is < 3. Currently, - this should raise a :class:`NotImplementedError`. + this should raise a :exc:`NotImplementedError`. :: @@ -1367,13 +1358,13 @@ def _cone_to_ieq(self, facet_list): def _embed_tetra(self, fpoint): """ - Takes a 4-d vector and projects it onto the plane perpendicular to + Take a 4-d vector and projects it onto the plane perpendicular to (1,1,1,1). Stretches by a factor of 2 as well, since this is only for graphical display purposes. INPUT: - - ``fpoint`` -- a list of four numbers + - ``fpoint`` -- list of four numbers EXAMPLES:: @@ -1402,7 +1393,7 @@ def _4d_to_3d(self, polyhedral_data): OUTPUT: - - ``edges`` -- a list of edges in 3d; each list item is a pair of + - ``edges`` -- list of edges in 3d; each list item is a pair of points EXAMPLES:: @@ -1457,11 +1448,11 @@ def render3d(self, verbose=False): TESTS: Now test the case where the number of generators is not 4. Currently, - this should raise a :class:`NotImplementedError` error. + this should raise a :exc:`NotImplementedError` error. :: - sage: P. = PolynomialRing(QQ, 3, order="lex") + sage: P. = PolynomialRing(QQ, 3, order='lex') sage: sage.rings.ideal.Katsura(P, 3).groebner_fan().render3d() # needs sage.plot Traceback (most recent call last): ... @@ -1608,10 +1599,10 @@ def tropical_basis(self, check=True, verbose=False): INPUT: - - ``check`` -- bool (default: ``True``); if True raises a - ValueError exception if this ideal does not define a tropical curve - (i.e., the condition that R/I has dimension equal to 1 + the - dimension of the homogeneity space is not satisfied). + - ``check`` -- boolean (default: ``True``); if ``True`` raises a + :exc:`ValueError` exception if this ideal does not define a tropical + curve (i.e., the condition that R/I has dimension equal to 1 + the + dimension of the homogeneity space is not satisfied) EXAMPLES:: @@ -1672,9 +1663,9 @@ def tropical_intersection(self, parameters=[], symmetry_generators=[], *args, ** INPUT: - - ``parameters`` (optional) -- a list of variables to be + - ``parameters`` -- (optional) list of variables to be considered as parameters - - ``symmetry_generators`` (optional) -- generators of the symmetry group + - ``symmetry_generators`` -- (optional) generators of the symmetry group OUTPUT: a TropicalPrevariety object @@ -1776,12 +1767,11 @@ def __init__(self, groebner_fan, gens, gfan_gens): INPUT: - - ``groebner_fan`` -- a GroebnerFan object from an - ideal + - ``groebner_fan`` -- a GroebnerFan object from an ideal - - ``gens`` -- the generators of the ideal + - ``gens`` -- the generators of the ideal - - ``gfan_gens`` -- the generators as a gfan string + - ``gfan_gens`` -- the generators as a gfan string EXAMPLES:: @@ -1888,9 +1878,9 @@ def groebner_cone(self, restrict=False): INPUT: - - ``restrict`` -- bool (default: ``False``); if True, add - an inequality for each coordinate, so that the cone is restricted - to the positive orthant. + - ``restrict`` -- boolean (default: ``False``); if ``True``, add + an inequality for each coordinate, so that the cone is restricted + to the positive orthant OUTPUT: tuple of integer vectors diff --git a/src/sage/rings/polynomial/hilbert.pyx b/src/sage/rings/polynomial/hilbert.pyx index 198a0940b95..24728bef328 100644 --- a/src/sage/rings/polynomial/hilbert.pyx +++ b/src/sage/rings/polynomial/hilbert.pyx @@ -93,7 +93,7 @@ cdef inline list interred(list L): INPUT: - - ``L`` -- a list of :class:`~sage.rings.polynomial.polydict.ETuple` + - ``L`` -- list of :class:`~sage.rings.polynomial.polydict.ETuple` OUTPUT: @@ -421,6 +421,7 @@ cdef make_children(Node D, tuple w): # It may be a good idea to form the product of some of the most # frequent variables. But this isn't implemented yet. TODO? + def first_hilbert_series(I, grading=None, return_grading=False): """ Return the first Hilbert series of the given monomial ideal. @@ -430,7 +431,8 @@ def first_hilbert_series(I, grading=None, return_grading=False): - ``I`` -- a monomial ideal (possibly defined in singular) - ``grading`` -- (optional) a list or tuple of integers used as degree weights - - ``return_grading`` -- (default: ``False``) whether to return the grading + - ``return_grading`` -- boolean (default: ``False``); whether to return the + grading OUTPUT: @@ -550,6 +552,7 @@ def first_hilbert_series(I, grading=None, return_grading=False): fmpz_poly_add(fhs._poly, AN.LMult, AN.RMult) got_result = True + def hilbert_poincare_series(I, grading=None): r""" Return the Hilbert Poincaré series of the given monomial ideal. diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index bb263b21a51..b7d10c05db1 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -54,8 +54,8 @@ Note that ``P(0)==0``, and thus variables of index zero are invariant under the permutation action. More generally, if ``P`` is any -callable object that accepts non-negative integers as input and -returns non-negative integers, then ``c^P`` means to apply ``P`` to +callable object that accepts nonnegative integers as input and +returns nonnegative integers, then ``c^P`` means to apply ``P`` to the variable indices occurring in ``c``. If you want to substitute variables you can use the standard polynomial @@ -121,8 +121,8 @@ class InfinitePolynomial(CommutativePolynomial, metaclass=InheritComparisonClass INPUT: - - ``A`` -- an Infinite Polynomial Ring. - - ``p`` -- a *classical* polynomial that can be interpreted in ``A``. + - ``A`` -- an Infinite Polynomial Ring + - ``p`` -- a *classical* polynomial that can be interpreted in ``A`` ASSUMPTIONS: @@ -175,7 +175,6 @@ class InfinitePolynomial(CommutativePolynomial, metaclass=InheritComparisonClass sage: Y(a) alpha_2^2 + alpha_1^2 - """ @staticmethod @@ -254,7 +253,6 @@ def __init__(self, A, p): sage: a = x[1] + x[2] sage: a == loads(dumps(a)) True - """ # Despite the above comment, it can still happen that p is in @@ -309,7 +307,6 @@ def polynomial(self): over Finite Field of size 7 sage: p.parent() Infinite polynomial ring in x, y over Finite Field of size 7 - """ return self._p @@ -384,7 +381,6 @@ def __getattr__(self, s): 'p.content_ideal'] sage: 'constant_coefficient' in dir(p) # indirect doctest True - """ if s == '__members__': return dir(self._p) @@ -405,9 +401,7 @@ def subs(self, fixed=None, **kwargs): - ``fixed`` -- (optional) ``dict`` with ``{variable: value}`` pairs - ``**kwargs`` -- named parameters - OUTPUT: - - the resulting substitution + OUTPUT: the resulting substitution EXAMPLES:: @@ -492,7 +486,6 @@ def ring(self): sage: p = x[100]*y[1]^3*x[1]^2 + 2*x[10]*y[30] sage: p.ring() Infinite polynomial ring in x, y over Integer Ring - """ return self.parent() @@ -559,6 +552,41 @@ def is_nilpotent(self): """ return self._p.is_nilpotent() + def numerator(self): + r""" + Return a numerator of ``self``, computed as ``self * self.denominator()``. + + .. WARNING:: + + This is not the numerator of the rational function + defined by ``self``, which would always be ``self`` since it is a + polynomial. + + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ) + sage: p = 2/3*x[1] + 4/9*x[2] - 2*x[1]*x[3] + sage: num = p.numerator(); num + -18*x_3*x_1 + 4*x_2 + 6*x_1 + + TESTS:: + + sage: num.parent() + Infinite polynomial ring in x over Rational Field + + Check that :issue:`37756` is fixed:: + + sage: R. = InfinitePolynomialRing(QQ) + sage: P. = QQ[] + sage: FF = P.fraction_field() + sage: FF(a[0]) + Traceback (most recent call last): + ... + TypeError: Could not find a mapping of the passed element to this ring. + """ + P = self.parent() + return InfinitePolynomial(P, self._p.numerator()) + @cached_method def variables(self): """ @@ -574,12 +602,71 @@ def variables(self): (x_1,) sage: X(1).variables() () - """ if hasattr(self._p, 'variables'): - return tuple(self._p.variables()) + P = self.parent() + return tuple(InfinitePolynomial(P, v) for v in self._p.variables()) return () + def monomials(self): + """ + Return the list of monomials in ``self``. + + The returned list is decreasingly ordered by the term ordering of + ``self.parent()``. + + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ) + sage: p = x[1]^3 + x[2] - 2*x[1]*x[3] + sage: p.monomials() + [x_3*x_1, x_2, x_1^3] + + sage: X. = InfinitePolynomialRing(QQ, order='deglex') + sage: p = x[1]^3 + x[2] - 2*x[1]*x[3] + sage: p.monomials() + [x_1^3, x_3*x_1, x_2] + """ + P = self.parent() + return [InfinitePolynomial(P, m) for m in self._p.monomials()] + + def monomial_coefficient(self, mon): + """ + Return the base ring element that is the coefficient of ``mon`` + in ``self``. + + This function contrasts with the function :meth:`coefficient`, + which returns the coefficient of a monomial viewing this + polynomial in a polynomial ring over a base ring having fewer + variables. + + INPUT: + + - ``mon`` -- a monomial in the parent of ``self`` + + OUTPUT: coefficient in base ring + + .. SEEALSO:: + + For coefficients in a base ring of fewer variables, + look at :meth:`coefficient`. + + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ) + sage: f = 2*x[0]*x[2] + 3*x[1]^2 + sage: c = f.monomial_coefficient(x[1]^2); c + 3 + sage: c.parent() + Rational Field + + sage: c = f.coefficient(x[2]); c + 2*x_0 + sage: c.parent() + Infinite polynomial ring in x over Rational Field + """ + return self._p.monomial_coefficient(mon._p) + @cached_method def max_index(self): r""" @@ -605,7 +692,6 @@ def _rmul_(self, left): sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') sage: R.from_base_ring(4) # indirect doctest 4 - """ return type(self)(self.parent(), left * self._p) @@ -616,7 +702,6 @@ def _lmul_(self, right): sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') sage: alpha[3]*4 # indirect doctest 4*alpha_3 - """ return type(self)(self.parent(), self._p * right) @@ -642,7 +727,7 @@ def _div_(self, x): sage: q.parent() Infinite polynomial ring in x over Rational Field - Division by a non-zero element:: + Division by a nonzero element:: sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') sage: 1/x[1] @@ -705,7 +790,6 @@ def lm(self): sage: p = 2*x[10]*y[30] + x[10]*y[1]^3*x[1]^2 sage: p.lm() x_10*x_1^2*y_1^3 - """ if hasattr(self._p, 'lm'): return InfinitePolynomial(self.parent(), self._p.lm()) @@ -727,7 +811,6 @@ def lc(self): sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2 sage: p.lc() 3 - """ if hasattr(self._p, 'lc'): return self._p.lc() @@ -747,7 +830,6 @@ def lt(self): sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2 sage: p.lt() 3*x_10*x_1^2*y_1^3 - """ if hasattr(self._p, 'lt'): return InfinitePolynomial(self.parent(), self._p.lt()) @@ -767,7 +849,6 @@ def tail(self): sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2 sage: p.tail() 2*x_10*y_30 - """ return self-self.lt() @@ -787,7 +868,6 @@ def squeezed(self): sage: p = x[1]*y[100] + x[50]*y[1000] sage: p.squeezed() x_2*y_4 + x_1*y_3 - """ Indices = set([0] + [Integer(str(Y).split('_')[1]) for Y in self.variables()]) @@ -802,9 +882,7 @@ def footprint(self): """ Leading exponents sorted by index and generator. - OUTPUT: - - ``D`` -- a dictionary whose keys are the occurring variable indices. + OUTPUT: ``D``; dictionary whose keys are the occurring variable indices ``D[s]`` is a list ``[i_1,...,i_n]``, where ``i_j`` gives the exponent of ``self.parent().gen(j)[s]`` in the leading @@ -832,7 +910,6 @@ def footprint(self): sage: p = a[12]^3*a[2]^7*a[4] + a[4]*a[2] sage: sorted(p.footprint().items()) [(2, [7]), (4, [1]), (12, [3])] - """ if not self._has_footprint: PARENT = self.parent() @@ -865,11 +942,11 @@ def symmetric_cancellation_order(self, other): INPUT: - ``self``, ``other`` -- two Infinite Polynomials + - ``self``, ``other`` -- two Infinite Polynomials ASSUMPTION: - Both Infinite Polynomials are non-zero. + Both Infinite Polynomials are nonzero. OUTPUT: @@ -903,7 +980,6 @@ def symmetric_cancellation_order(self, other): (None, 1, 1) sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2]) (-1, [2, 3, 1], 1) - """ PARENT = self.parent() other = PARENT(other) @@ -915,16 +991,14 @@ def symmetric_cancellation_order(self, other): return (0, 1, self.lc() / other.lc()) if self.lm() < other.lm(): rawcmp = -1 - Fsmall = dict([[k[0], [e for e in k[1]]] - for k in self.footprint().items()]) - Fbig = dict([[k[0], [e for e in k[1]]] - for k in other.footprint().items()]) + Fsmall = {k: list(v) for k, v in self.footprint().items()} + Fbig = {k: list(v) for k, v in other.footprint().items()} ltsmall = slt ltbig = olt else: rawcmp = 1 - Fbig = dict([[k[0], [e for e in k[1]]] for k in self.footprint().items()]) - Fsmall = dict([[k[0], [e for e in k[1]]] for k in other.footprint().items()]) + Fbig = {k: list(v) for k, v in self.footprint().items()} + Fsmall = {k: list(v) for k, v in other.footprint().items()} ltbig = slt ltsmall = olt # Case 1: one of the Infinite Polynomials is scalar. @@ -955,7 +1029,7 @@ def symmetric_cancellation_order(self, other): while j < lenBig: found = False if Lbig[j] >= i: - ExpoBigSave = [e for e in Fbig[Lbig[j]]] + ExpoBigSave = list(Fbig[Lbig[j]]) ExpoBig = Fbig[Lbig[j]] found = True for k in gens: @@ -987,7 +1061,7 @@ def symmetric_cancellation_order(self, other): def coefficient(self, monomial): """ - Returns the coefficient of a monomial in this polynomial. + Return the coefficient of a monomial in this polynomial. INPUT: @@ -1015,44 +1089,43 @@ def coefficient(self, monomial): sage: a.coefficient({x[0]:1, x[1]:1}) 2 - """ + P = self.parent() if self._p == 0: - res = 0 - elif isinstance(monomial, self.__class__): - if not (self.parent().has_coerce_map_from(monomial.parent())): - res = 0 + return P.zero() + if isinstance(monomial, self.__class__): + if not P.has_coerce_map_from(monomial.parent()): + return P.zero() + if hasattr(self._p, 'variables'): + VarList = [str(X) for X in self._p.variables()] else: - if hasattr(self._p, 'variables'): - VarList = [str(X) for X in self._p.variables()] - else: - VarList = [] - if hasattr(monomial._p, 'variables'): - VarList.extend([str(X) for X in monomial._p.variables()]) - VarList = list(set(VarList)) - VarList.sort(key=self.parent().varname_key, reverse=True) - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - if len(VarList) == 1: - # 'xx' is guaranteed to be no variable - # name of monomial, since coercions - # were tested before - R = PolynomialRing(self._p.base_ring(), VarList + ['xx'], order=self.parent()._order) - - res = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)(R(self._p).coefficient(R(monomial._p))) - else: - R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) - res = R(self._p).coefficient(R(monomial._p)) - elif isinstance(monomial, dict): + VarList = [] + if hasattr(monomial._p, 'variables'): + VarList.extend([str(X) for X in monomial._p.variables()]) + VarList = list(set(VarList)) + VarList.sort(key=P.varname_key, reverse=True) + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + if len(VarList) == 1: + # 'xx' is guaranteed to be no variable + # name of monomial, since coercions + # were tested before + R = PolynomialRing(self._p.base_ring(), VarList + ['xx'], order=P._order) + S = PolynomialRing(self._p.base_ring(), VarList, order=P._order) + res = S(R(self._p).coefficient(R(monomial._p))) + return InfinitePolynomial(P, res) + + R = PolynomialRing(self._p.base_ring(), VarList, order=P._order) + res = R(self._p).coefficient(R(monomial._p)) + return InfinitePolynomial(P, res) + + if isinstance(monomial, dict): if monomial: I = iter(monomial) K = next(I) del monomial[K] - res = self.coefficient(K).coefficient(monomial) - else: - return self - else: - raise TypeError("Objects of type %s have no coefficients in InfinitePolynomials" % (type(monomial))) - return self.parent()(res) + return self.coefficient(K).coefficient(monomial) + return self + raise TypeError("Objects of type %s have no coefficients in InfinitePolynomials" % (type(monomial))) # Essentials for Buchberger def reduce(self, I, tailreduce=False, report=None): @@ -1062,16 +1135,14 @@ def reduce(self, I, tailreduce=False, report=None): INPUT: - ``I`` -- a :class:`~sage.rings.polynomial.symmetric_ideal.SymmetricIdeal` or a list - of Infinite Polynomials. - - ``tailreduce`` -- (bool, default ``False``) *Tail reduction* is performed if this + of Infinite Polynomials + - ``tailreduce`` -- boolean (default: ``False``); *tail reduction* is performed if this parameter is ``True``. - - ``report`` -- (object, default ``None``) If not ``None``, some information on the + - ``report`` -- object (default: ``None``); if not ``None``, some information on the progress of computation is printed, since reduction of huge polynomials may take - a long time. - - OUTPUT: + a long time - Symmetrical reduction of ``self`` with respect to ``I``, possibly with tail reduction. + OUTPUT: symmetrical reduction of ``self`` with respect to ``I``, possibly with tail reduction THEORY: @@ -1125,7 +1196,6 @@ def reduce(self, I, tailreduce=False, report=None): the reduction process is finished (there could only be several non-trivial rounds if `I` was generated by more than one polynomial). - """ from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy if hasattr(I, 'gens'): @@ -1143,11 +1213,10 @@ def stretch(self, k): INPUT: - - ``k`` -- an integer. - - OUTPUT: + - ``k`` -- integer - Replace `v_n` with `v_{n\cdot k}` for all generators `v_\ast` occurring in self. + OUTPUT: replace `v_n` with `v_{n\cdot k}` for all generators `v_\ast` + occurring in ``self`` EXAMPLES:: @@ -1173,7 +1242,6 @@ def stretch(self, k): sage: a = x[2] + x[3] sage: a.stretch(2000) x_6000 + x_4000 - """ def P(n): return k*n @@ -1197,7 +1265,7 @@ def __iter__(self): def gcd(self, x): """ - computes the greatest common divisor + Compute the greatest common divisor. EXAMPLES:: @@ -1221,7 +1289,7 @@ class InfinitePolynomial_sparse(InfinitePolynomial): INPUT: - ``A`` -- an Infinite Polynomial Ring in sparse implementation - - ``p`` -- a *classical* polynomial that can be interpreted in ``A``. + - ``p`` -- a *classical* polynomial that can be interpreted in ``A`` Of course, one should not directly invoke this class, but rather construct elements of ``A`` in the usual way. @@ -1239,7 +1307,6 @@ class InfinitePolynomial_sparse(InfinitePolynomial): sage: p.polynomial().parent() Multivariate Polynomial Ring in b_100, b_0, c_4, c_0 over Univariate Polynomial Ring in a over Rational Field - """ def __call__(self, *args, **kwargs): @@ -1334,7 +1401,6 @@ def _mul_(self, x): sage: X. = InfinitePolynomialRing(ZZ) sage: x[2]*x[1] # indirect doctest x_2*x_1 - """ try: return InfinitePolynomial_sparse(self.parent(), self._p * x._p) @@ -1358,7 +1424,6 @@ def _sub_(self, x): sage: X. = InfinitePolynomialRing(QQ) sage: x[2] - x[1] # indirect doctest x_2 - x_1 - """ try: return InfinitePolynomial_sparse(self.parent(), self._p - x._p) @@ -1377,12 +1442,12 @@ def _sub_(self, x): def __pow__(self, n): """ - Exponentiation by an integer, or action by a callable object + Exponentiation by an integer, or action by a callable object. NOTE: - The callable object must accept non-negative integers as input - and return non-negative integers. Typical use case is a + The callable object must accept nonnegative integers as input + and return nonnegative integers. Typical use case is a permutation, that will result in the corresponding permutation of variables. @@ -1393,7 +1458,6 @@ def __pow__(self, n): sage: P = Permutation(((1,2),(3,4,5))) sage: p^P # indirect doctest x_10*y_1 + 2*x_2*y_4 - """ P = self.parent() if callable(n): @@ -1437,7 +1501,7 @@ def _richcmp_(self, x, op): NOTE: - Let x and y be generators of the parent of self. We only consider + Let x and y be generators of the parent of ``self``. We only consider monomial orderings in which x[m] > y[n] iff x appears earlier in the list of generators than y, or x==y and m>n @@ -1486,7 +1550,6 @@ def _richcmp_(self, x, op): sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') sage: p < q False - """ # We can assume that self.parent() is x.parent(), # but of course the underlying polynomial rings @@ -1522,11 +1585,10 @@ class InfinitePolynomial_dense(InfinitePolynomial): INPUT: - ``A`` -- an Infinite Polynomial Ring in dense implementation - - ``p`` -- a *classical* polynomial that can be interpreted in ``A``. + - ``p`` -- a *classical* polynomial that can be interpreted in ``A`` Of course, one should not directly invoke this class, but rather construct elements of ``A`` in the usual way. - """ def __call__(self, *args, **kwargs): @@ -1546,7 +1608,6 @@ def __call__(self, *args, **kwargs): sage: a(x_1=x[100]) x_100 + x_0 - """ # Replace any InfinitePolynomials by their underlying polynomials for kw in kwargs: @@ -1589,7 +1650,6 @@ def _richcmp_(self, x, op): sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') sage: p < q False - """ # We can assume that self and x belong to the same ring. # We can not assume yet that self._p and @@ -1614,7 +1674,6 @@ def _add_(self, x): sage: X. = InfinitePolynomialRing(QQ) sage: x[1] + x[2] # indirect doctest x_2 + x_1 - """ P = self.parent() self._p = P._P(self._p) @@ -1628,7 +1687,6 @@ def _mul_(self, x): sage: X. = InfinitePolynomialRing(QQ) sage: x[2]*x[1] # indirect doctest x_2*x_1 - """ P = self.parent() self._p = P._P(self._p) @@ -1642,7 +1700,6 @@ def _sub_(self, x): sage: X. = InfinitePolynomialRing(QQ) sage: x[2] - x[1] # indirect doctest x_2 - x_1 - """ P = self.parent() self._p = P._P(self._p) @@ -1651,12 +1708,12 @@ def _sub_(self, x): def __pow__(self, n): """ - Exponentiation by an integer, or action by a callable object + Exponentiation by an integer, or action by a callable object. NOTE: - The callable object must accept non-negative integers as input - and return non-negative integers. Typical use case is a + The callable object must accept nonnegative integers as input + and return nonnegative integers. Typical use case is a permutation, that will result in the corresponding permutation of variables. @@ -1669,7 +1726,6 @@ def __pow__(self, n): sage: P = Permutation(((1,2),(3,4,5))) sage: p^P x_10*y_1 + 2*x_2*y_4 - """ P = self.parent() if callable(n): diff --git a/src/sage/rings/polynomial/infinite_polynomial_ring.py b/src/sage/rings/polynomial/infinite_polynomial_ring.py index 75ca69f979a..05735a21cd2 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_ring.py +++ b/src/sage/rings/polynomial/infinite_polynomial_ring.py @@ -17,10 +17,10 @@ INPUT: -- ``R``, the base ring. It has to be a commutative ring, and in some +- ``R`` -- the base ring; it has to be a commutative ring, and in some applications it must even be a field -- ``names``, a finite list of generator names. Generator names must be alpha-numeric. -- ``order`` (optional string). The default order is ``'lex'`` (lexicographic). +- ``names`` -- a finite list of generator names; generator names must be alpha-numeric +- ``order`` -- (optional) string; the default order is ``'lex'`` (lexicographic). ``'deglex'`` is degree lexicographic, and ``'degrevlex'`` (degree reverse lexicographic) is possible but discouraged. @@ -279,8 +279,8 @@ class InfinitePolynomialRingFactory(UniqueFactory): """ A factory for creating infinite polynomial ring elements. It - handles making sure that they are unique as well as handling - pickling. For more details, see + makes sure that they are unique as well as handling pickling. + For more details, see :class:`~sage.structure.factory.UniqueFactory` and :mod:`~sage.rings.polynomial.infinite_polynomial_ring`. @@ -300,11 +300,10 @@ class InfinitePolynomialRingFactory(UniqueFactory): sage: X is loads(dumps(X)) True - """ def create_key(self, R, names=('x',), order='lex', implementation='dense'): """ - Creates a key which uniquely defines the infinite polynomial ring. + Create a key which uniquely defines the infinite polynomial ring. TESTS:: @@ -331,7 +330,7 @@ def create_key(self, R, names=('x',), order='lex', implementation='dense'): sage: _[0].all [FractionField, InfPoly{[x], "lex", "dense"}] - If it is attempted to use no generator, a :class:`ValueError` is raised:: + If it is attempted to use no generator, a :exc:`ValueError` is raised:: sage: InfinitePolynomialRing.create_key(ZZ, names=[]) Traceback (most recent call last): @@ -410,13 +409,12 @@ class InfiniteGenDict: sage: sage_eval('3*a_3*b_5-1/2*a_7', D._D[0]) -1/2*a_7 + 3*a_3*b_5 - """ def __init__(self, Gens): """ INPUT: - - ``Gens`` -- a list of generators of an infinite polynomial ring. + - ``Gens`` -- list of generators of an infinite polynomial ring EXAMPLES:: @@ -566,7 +564,7 @@ def __init__(self, parent, start): def __next__(self): """ - Return a dictionary that can be used to interprete strings in the base ring of ``self``. + Return a dictionary that can be used to interpret strings in the base ring of ``self``. EXAMPLES:: @@ -663,7 +661,6 @@ class InfinitePolynomialRing_sparse(CommutativeRing): See :mod:`~sage.rings.polynomial.infinite_polynomial_ring` for more details. - """ def __init__(self, R, names, order): """ @@ -704,7 +701,7 @@ def __init__(self, R, names, order): names = ['x'] for n in names: if not (isinstance(n, str) and n.isalnum() and (not n[0].isdigit())): - raise ValueError("generator names must be alpha-numeric strings not starting with a digit, but %s is not" % n) + raise ValueError("generator names must be alphanumeric strings not starting with a digit, but %s is not" % n) if len(names) != len(set(names)): raise ValueError("generator names must be pairwise different") self._names = tuple(names) @@ -813,7 +810,6 @@ def construction(self): sage: R. = InfinitePolynomialRing(GF(5)) sage: R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5] - """ return [InfinitePolynomialFunctor(self._names, self._order, 'sparse'), self._base] @@ -865,7 +861,7 @@ def _element_constructor_(self, x): INPUT: - - ``x`` -- any object that can be interpreted in ``self``. + - ``x`` -- any object that can be interpreted in ``self`` TESTS:: @@ -888,6 +884,17 @@ def _element_constructor_(self, x): Traceback (most recent call last): ... ValueError: cannot convert 1/3 into an element of Infinite polynomial ring in x over Integer Ring + + .. WARNING:: + + The :issue:`37756` is not yet fixed:: + + sage: L. = QQ[] + sage: R. = InfinitePolynomialRing(QQ) + sage: M = InfinitePolynomialRing(L, names=["a"]) + sage: c = a[0] + sage: M(c) # known bug + a_0 """ from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial # In many cases, the easiest solution is to "simply" evaluate @@ -1048,7 +1055,7 @@ def tensor_with_ring(self, R): INPUT: - - ``R`` -- a ring. + - ``R`` -- a ring OUTPUT: @@ -1057,7 +1064,7 @@ def tensor_with_ring(self, R): NOTE: - It is required that the underlying ring of self coerces into ``R``. + It is required that the underlying ring of ``self`` coerces into ``R``. Hence, the tensor product is in fact merely an extension of the base ring. @@ -1156,19 +1163,17 @@ def varname_key(self, x): INPUT: - - ``x`` -- a string of the form ``a+'_'+str(n)``, where a is the + - ``x`` -- string of the form ``a+'_'+str(n)``, where a is the name of a generator, and n is an integer - RETURN: - - a key used to sort the variables + OUTPUT: a key used to sort the variables THEORY: The order is defined as follows: x = InfinitePolynomialRing(QQ) sage: X.ngens() 2 - """ return len(self._names) @cached_method def gen(self, i=None): """ - Return the `i^{th}` 'generator' (see the description in :meth:`.ngens`) + Return the `i`-th 'generator' (see the description in :meth:`.ngens`) of this infinite polynomial ring. EXAMPLES:: @@ -1286,7 +1290,6 @@ def _ideal_class_(self, n=0): sage: R. = InfinitePolynomialRing(ZZ) sage: R._ideal_class_() - """ import sage.rings.polynomial.symmetric_ideal return sage.rings.polynomial.symmetric_ideal.SymmetricIdeal @@ -1302,7 +1305,6 @@ def characteristic(self): Infinite polynomial ring in x, y over Finite Field in a of size 5^2 sage: X.characteristic() # needs sage.rings.finite_rings 5 - """ return self._base.characteristic() @@ -1386,7 +1388,6 @@ class InfinitePolynomialGen(SageObject): x1_5 sage: x1 == loads(dumps(x1)) True - """ def __init__(self, parent, name): @@ -1396,7 +1397,6 @@ def __init__(self, parent, name): sage: X. = InfinitePolynomialRing(QQ) sage: loads(dumps(x)) x_* - """ self._name = name self._parent = parent @@ -1456,7 +1456,7 @@ def __getitem__(self, i): """ Return the variable ``x[i]`` where ``x`` is this :class:`sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialGen`, - and i is a non-negative integer. + and i is a nonnegative integer. EXAMPLES:: @@ -1468,7 +1468,7 @@ def __getitem__(self, i): raise ValueError("the index (= %s) must be an integer" % i) i = int(i) if i < 0: - raise ValueError("the index (= %s) must be non-negative" % i) + raise ValueError("the index (= %s) must be nonnegative" % i) P = self._parent from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial_dense, InfinitePolynomial_sparse from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1536,7 +1536,7 @@ def __str__(self): class InfinitePolynomialRing_dense(InfinitePolynomialRing_sparse): """ - Dense implementation of Infinite Polynomial Rings + Dense implementation of Infinite Polynomial Rings. Compared with :class:`~sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse`, from which this class inherits, it keeps a polynomial ring that comprises all elements that have @@ -1549,7 +1549,6 @@ def __init__(self, R, names, order): sage: X. = InfinitePolynomialRing(ZZ, implementation='dense') sage: X == loads(dumps(X)) True - """ if not names: names = ['x'] @@ -1585,7 +1584,7 @@ def tensor_with_ring(self, R): INPUT: - - ``R`` -- a ring. + - ``R`` -- a ring OUTPUT: @@ -1594,7 +1593,7 @@ def tensor_with_ring(self, R): NOTE: - It is required that the underlying ring of self coerces into ``R``. + It is required that the underlying ring of ``self`` coerces into ``R``. Hence, the tensor product is in fact merely an extension of the base ring. @@ -1611,7 +1610,6 @@ def tensor_with_ring(self, R): sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') sage: R.tensor_with_ring(QQ) is R True - """ if not R.has_coerce_map_from(self._underlying_ring): raise TypeError("we cannot tensor with " + repr(R)) @@ -1631,7 +1629,7 @@ def polynomial_ring(self): """ Return the underlying *finite* polynomial ring. - .. note:: + .. NOTE:: The ring returned can change over time as more variables are used. @@ -1649,6 +1647,5 @@ def polynomial_ring(self): sage: X.polynomial_ring() Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0 over Integer Ring - """ return self._P diff --git a/src/sage/rings/polynomial/integer_valued_polynomials.py b/src/sage/rings/polynomial/integer_valued_polynomials.py index 2197ac7f3d3..233c0cb800b 100644 --- a/src/sage/rings/polynomial/integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/integer_valued_polynomials.py @@ -36,7 +36,7 @@ class IntegerValuedPolynomialRing(UniqueRepresentation, Parent): The integer-valued polynomial ring over a base ring `R`. Integer-valued polynomial rings are commutative and associative - algebras, with a basis indexed by non-negative integers. + algebras, with a basis indexed by nonnegative integers. There are two natural bases, made of the sequence `\binom{x}{n}` for `n \geq 0` (the *binomial basis*) and of @@ -189,7 +189,7 @@ def from_polynomial(self, p): """ Convert a polynomial into the ring of integer-valued polynomials. - This raises a :class:`ValueError` if this is not possible. + This raises a :exc:`ValueError` if this is not possible. INPUT: @@ -331,7 +331,7 @@ def shift(self, j=1): INPUT: - - `j` -- integer (default: 1) + - ``j`` -- integer (default: 1) In the binomial basis, the shift by 1 corresponds to a summation operator from `0` to `x`. @@ -470,7 +470,7 @@ def __init__(self, A): CombinatorialFreeModule.__init__(self, A.base_ring(), NonNegativeIntegers(), category=A.Bases(), - prefix="S", + prefix='S', latex_prefix=r"\mathbb{S}") def _realization_name(self) -> str: @@ -514,7 +514,7 @@ def _from_binomial_basis(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -537,7 +537,7 @@ def from_h_vector(self, h): INPUT: - - ``h`` -- a tuple or vector + - ``h`` -- tuple or vector .. SEEALSO:: :meth:`Element.h_vector` @@ -692,7 +692,7 @@ def _poly(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -757,7 +757,7 @@ def variable_shift(self, k=1): INPUT: - - `k` -- integer (default: 1) + - ``k`` -- integer (default: 1) EXAMPLES:: @@ -981,7 +981,7 @@ def __init__(self, A) -> None: """ CombinatorialFreeModule.__init__(self, A.base_ring(), NonNegativeIntegers(), - latex_prefix="", + latex_prefix='', category=A.Bases()) def _realization_name(self) -> str: @@ -1026,7 +1026,7 @@ def _from_shifted_basis(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1174,7 +1174,7 @@ def _poly(self, i): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -1195,7 +1195,7 @@ def variable_shift(self, k=1): INPUT: - - `k` -- integer (default: 1) + - ``k`` -- integer (default: 1) EXAMPLES:: diff --git a/src/sage/rings/polynomial/laurent_polynomial.pxd b/src/sage/rings/polynomial/laurent_polynomial.pxd index 8e9107aeb47..1937490caac 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pxd +++ b/src/sage/rings/polynomial/laurent_polynomial.pxd @@ -7,11 +7,11 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): cpdef _mul_(self, other) cpdef _floordiv_(self, other) cpdef long number_of_terms(self) except -1 - cpdef dict dict(self) + cpdef dict monomial_coefficients(self) + cdef class LaurentPolynomial_univariate(LaurentPolynomial): cdef ModuleElement __u cdef long __n cpdef _normalize(self) cpdef _unsafe_mutate(self, i, value) - diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 650388e7f0f..0fed2467c05 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -13,7 +13,7 @@ from sage.structure.element import coerce_binop, parent from sage.structure.factorization import Factorization from sage.misc.derivative import multi_derivative from sage.rings.polynomial.polynomial_element import Polynomial -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.structure.richcmp cimport richcmp, rich_to_bool from sage.rings.infinity import minus_infinity @@ -40,7 +40,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): cpdef _add_(self, other): """ - Abstract addition method + Abstract addition method. EXAMPLES:: @@ -55,7 +55,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): cpdef _mul_(self, other): """ - Abstract multiplication method + Abstract multiplication method. EXAMPLES:: @@ -70,7 +70,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): cpdef _floordiv_(self, other): """ - Abstract floor division method + Abstract floor division method. EXAMPLES:: @@ -89,9 +89,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): This is only possible if the Laurent polynomial is constant. - OUTPUT: - - An integer. + OUTPUT: integer TESTS:: @@ -136,9 +134,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): This is only possible if the Laurent polynomial is constant. - OUTPUT: - - A rational. + OUTPUT: a rational TESTS:: @@ -210,7 +206,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): """ Return the hamming weight of ``self``. - The hamming weight is number of non-zero coefficients and + The hamming weight is number of nonzero coefficients and also known as the weight or sparsity. EXAMPLES:: @@ -222,7 +218,7 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): """ return self.number_of_terms() - cpdef dict dict(self): + cpdef dict monomial_coefficients(self): """ Abstract ``dict`` method. @@ -230,13 +226,15 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): sage: R. = LaurentPolynomialRing(ZZ) sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial - sage: LaurentPolynomial.dict(x) + sage: LaurentPolynomial.monomial_coefficients(x) Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError + dict = monomial_coefficients + def map_coefficients(self, f, new_base_ring=None): """ Apply ``f`` to the coefficients of ``self``. @@ -248,10 +246,10 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): INPUT: - - ``f`` -- a callable that will be applied to the coefficients of ``self``. + - ``f`` -- a callable that will be applied to the coefficients of ``self`` - - ``new_base_ring`` (optional) -- if given, the resulting polynomial - will be defined over this ring. + - ``new_base_ring`` -- (optional) if given, the resulting polynomial + will be defined over this ring EXAMPLES:: @@ -292,14 +290,14 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): X - Y sage: g.parent() Multivariate Laurent Polynomial Ring in X, Y over Finite Field of size 3 - """ R = self.parent() if new_base_ring is not None: R = R.change_ring(new_base_ring) elif isinstance(f, Map): R = R.change_ring(f.codomain()) - return R(dict([(k, f(v)) for (k, v) in self.dict().items()])) + return R(dict([(k, f(v)) + for k, v in self.monomial_coefficients().items()])) cdef class LaurentPolynomial_univariate(LaurentPolynomial): @@ -311,9 +309,9 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): - ``parent`` -- a Laurent polynomial ring - - ``f`` -- a polynomial (or something can be coerced to one) + - ``f`` -- a polynomial (or something that can be coerced to one) - - ``n`` -- (default: 0) an integer + - ``n`` -- integer (default: 0) AUTHORS: @@ -431,7 +429,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): if self.__n < 0: raise ValueError("Laurent polynomial with negative valuation cannot be converted to polynomial") - if is_PolynomialRing(R): + if isinstance(R, PolynomialRing_general): return R(self.__u) << self.__n elif self.__n == 0: return R(self.__u) @@ -486,7 +484,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): def __bool__(self): """ - Check if ``self`` is non-zero. + Check if ``self`` is nonzero. EXAMPLES:: @@ -773,7 +771,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): cpdef long number_of_terms(self) except -1: """ - Return the number of non-zero coefficients of ``self``. + Return the number of nonzero coefficients of ``self``. Also called weight, hamming weight or sparsity. @@ -843,7 +841,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): d = {repr(g): R.var(g) for g in self._parent.gens()} return self.subs(**d) - cpdef dict dict(self): + cpdef dict monomial_coefficients(self): """ Return a dictionary representing ``self``. @@ -853,11 +851,18 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: Q. = LaurentPolynomialRing(R) sage: f = (x^3 + y/t^3)^3 + t^2; f y^3*t^-9 + 3*x^3*y^2*t^-6 + 3*x^6*y*t^-3 + x^9 + t^2 + sage: f.monomial_coefficients() + {-9: y^3, -6: 3*x^3*y^2, -3: 3*x^6*y, 0: x^9, 2: 1} + + ``dict`` is an alias:: + sage: f.dict() {-9: y^3, -6: 3*x^3*y^2, -3: 3*x^6*y, 0: x^9, 2: 1} """ - cdef dict d = self.__u.dict() - return {k+self.__n: d[k] for k in d} + cdef dict d = self.__u.monomial_coefficients() + return {k + self.__n: d[k] for k in d} + + dict = monomial_coefficients def coefficients(self): """ @@ -1131,7 +1136,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ return self.__u.is_monomial() - def __pow__(_self, r, dummy): + def __pow__(_self, r, mod): """ EXAMPLES:: @@ -1150,9 +1155,21 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): x^-8 sage: (5*x^-4)^-3 5*x^12 + + Check that using third argument raises an error:: + + sage: L. = LaurentPolynomialRing(R) + sage: pow(x, 2, x) + Traceback (most recent call last): + ... + NotImplementedError: pow() with a modulus is not implemented for this ring """ cdef LaurentPolynomial_univariate self = _self cdef long right = r + if mod is not None: + raise NotImplementedError( + "pow() with a modulus is not implemented for this ring" + ) if right != r: raise ValueError("exponent must be an integer") try: @@ -1384,7 +1401,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): def inverse_mod(a, m): """ - Invert the polynomial ``a`` with respect to ``m``, or raise a :class:`ValueError` + Invert the polynomial ``a`` with respect to ``m``, or raise a :exc:`ValueError` if no such inverse exists. The parameter ``m`` may be either a single polynomial or an ideal @@ -1401,8 +1418,8 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: f * (t^-2 + 1) + (1/2*t^4 + 1/2*t^3) * (t^-3 + 1) 1 """ - from sage.rings.ideal import is_Ideal - if is_Ideal(m): + from sage.rings.ideal import Ideal_generic + if isinstance(m, Ideal_generic): v = m.gens_reduced() if len(v) > 1: raise NotImplementedError("only inversion modulo principal ideals implemented") @@ -2127,10 +2144,9 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): -tinv^2 + t sage: _.parent() Multivariate Polynomial Ring in t, tinv over Rational Field - """ dres = {} - for (e, c) in self.dict().items(): + for e, c in self.monomial_coefficients().items(): if e > 0: dres[(e, 0)] = c else: diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index db09032f7c5..ae21901fee1 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -48,7 +48,7 @@ def __init__(self, ring, gens, coerce=True, hint=None): INPUT: - ``ring`` -- the ring the ideal is defined in - - ``gens`` -- a list of generators for the ideal + - ``gens`` -- list of generators for the ideal - ``coerce`` -- whether or not to coerce elements into ``ring`` - ``hint`` -- an ideal in the associated polynomial ring (optional; see above) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 4d40075c619..17caf047da0 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -39,7 +39,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): - ``mon`` -- (default: ``None``) a tuple specifying the shift in the exponents - - ``reduce`` -- (default: ``True``) a boolean + - ``reduce`` -- boolean (default: ``True``) EXAMPLES:: @@ -108,7 +108,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): if isinstance(x, dict): self._mon = ETuple({}, int(parent.ngens())) D = {} - for k, x_k in x.iteritems(): # ETuple-ize keys, set _mon + for k, x_k in x.items(): # ETuple-ize keys, set _mon if not isinstance(k, (tuple, ETuple)) or len(k) != parent.ngens(): self._mon = ETuple({}, int(parent.ngens())) break @@ -119,7 +119,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): else: x = D if not self._mon.is_constant(): # factor out _mon - x = {k.esub(self._mon): x_k for k, x_k in x.iteritems()} + x = {k.esub(self._mon): x_k for k, x_k in x.items()} elif (isinstance(x, LaurentPolynomial_mpair) and parent.variable_names() == x.parent().variable_names()): self._mon = ( < LaurentPolynomial_mpair > x)._mon @@ -259,7 +259,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -281,7 +281,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): # self._parent.variable_names(), # self._parent.base_ring() # ) - cdef dict D = self._poly.dict() + cdef dict D = self._poly.monomial_coefficients() cdef ETuple e if i is None: @@ -309,12 +309,12 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: L. = LaurentPolynomialRing(QQ) sage: a = w^2*z^-1 +3 - sage: a.dict() # indirect doctest + sage: a.monomial_coefficients() # indirect doctest {(0, 0): 3, (2, -1): 1} """ # cdef dict D = self._poly._mpoly_dict_recursive(self._parent.variable_names(), # self._parent.base_ring()) - cdef dict D = self._poly.dict() + cdef dict D = self._poly.monomial_coefficients() cdef dict DD if self._mon.is_constant(): self._prod = PolyDict(D) @@ -401,7 +401,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): cpdef long number_of_terms(self) except -1: """ - Return the number of non-zero coefficients of ``self``. + Return the number of nonzero coefficients of ``self``. Also called weight, hamming weight or sparsity. @@ -448,7 +448,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): """ cdef ETuple e if self._poly.is_term(): - (e, c), = self.dict().items() + (e, c), = self.monomial_coefficients().items() e = e.emul(-1) P = self._parent try: @@ -460,7 +460,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): return P({e: c}) return super().__invert__() - def __pow__(LaurentPolynomial_mpair self, n, m): + def __pow__(LaurentPolynomial_mpair self, n, mod): """ EXAMPLES:: @@ -480,8 +480,20 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: f = (x+y+z^-1)^2 sage: f.substitute(z=1) x^2 + 2*x*y + y^2 + 2*x + 2*y + 1 + + Check that using third argument raises an error:: + + sage: L. = LaurentPolynomialRing(R) + sage: pow(x + y + z, 2, x) + Traceback (most recent call last): + ... + NotImplementedError: pow() with a modulus is not implemented for this ring """ cdef LaurentPolynomial_mpair ans + if mod is not None: + raise NotImplementedError( + "pow() with a modulus is not implemented for this ring" + ) if n < 0: return ~(self ** -n) ans = self._new_c() @@ -495,7 +507,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): `n` is a tuple of length `k` and `k` is the number of variables. If the number of inputs is not equal to the number of variables, this - raises a ``TypeError``. + raises a :exc:`TypeError`. EXAMPLES:: @@ -572,10 +584,9 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): -t2inv^2 + t1 sage: _.parent() Multivariate Polynomial Ring in t1, t1inv, t2, t2inv over Rational Field - """ dres = {} - for (e, c) in self.dict().items(): + for e, c in self.monomial_coefficients().items(): exps = [] for t in e: if t > 0: @@ -700,9 +711,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): - ``mon`` -- a monomial - OUTPUT: - - Element of the parent of ``self``. + OUTPUT: element of the parent of ``self`` .. NOTE:: @@ -745,7 +754,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): self._compute_polydict() if m._prod is None: m._compute_polydict() - return self._parent(self._prod.coefficient(m.dict())) + return self._parent(self._prod.coefficient(m.monomial_coefficients())) def coefficients(self): """ @@ -784,7 +793,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: f.variables(sort=False) #random (y, z, x) """ - cdef dict d = self.dict() + cdef dict d = self.monomial_coefficients() cdef tuple g = self._parent.gens() cdef Py_ssize_t nvars = len(g) cdef set vars = set() @@ -797,7 +806,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): v.sort() return tuple(v) - cpdef dict dict(self): + cpdef dict monomial_coefficients(self): """ Return ``self`` represented as a ``dict``. @@ -805,6 +814,11 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: L. = LaurentPolynomialRing(QQ) sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: sorted(f.monomial_coefficients().items()) + [((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)] + + ``dict`` is an alias:: + sage: sorted(f.dict().items()) [((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)] """ @@ -812,6 +826,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): self._compute_polydict() return < dict > self._prod.dict() + dict = monomial_coefficients + def _fraction_pair(self): """ Return one representation of ``self`` as a pair @@ -1059,9 +1075,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): - ``right`` -- a Laurent polynomial - OUTPUT: - - A pair of Laurent polynomials. + OUTPUT: a pair of Laurent polynomials EXAMPLES:: @@ -1151,7 +1165,6 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: e = a.exponents() sage: e.sort(); e [(0, 0), (2, -1)] - """ return [a.eadd(self._mon) for a in self._poly.exponents()] @@ -1284,7 +1297,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): """ INPUT: - - ``i`` -- The index of a generator of ``self.parent()`` + - ``i`` -- the index of a generator of ``self.parent()`` OUTPUT: @@ -1313,7 +1326,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): def has_any_inverse(self): """ - Return ``True`` if ``self`` contains any monomials with a negative exponent, False otherwise. + Return ``True`` if ``self`` contains any monomials with a negative + exponent, ``False`` otherwise. EXAMPLES:: @@ -1405,9 +1419,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): - ``**kwds`` -- keyword arguments - OUTPUT: - - A Laurent polynomial. + OUTPUT: a Laurent polynomial EXAMPLES:: @@ -1565,11 +1577,11 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): except ValueError: # call _derivative() recursively on coefficients return P({m: c._derivative(var) - for (m, c) in self.dict().iteritems()}) + for m, c in self.monomial_coefficients().items()}) # compute formal derivative with respect to generator cdef dict d = {} - for m, c in self.dict().iteritems(): + for m, c in self.monomial_coefficients().items(): if m[index] != 0: new_m = [u for u in m] new_m[index] += -1 @@ -1605,7 +1617,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): - ``R`` -- (default: ``None``) a univariate Laurent polynomial ring If this polynomial is not in at most one variable, then a - :class:`ValueError` exception is raised. The new polynomial is over + :exc:`ValueError` exception is raised. The new polynomial is over the same base ring as the given :class:`LaurentPolynomial` and in the variable ``x`` if no ring ``R`` is provided. @@ -1650,7 +1662,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): if R is None: R = LaurentPolynomialRing(self.base_ring(), x) - return R({m[i]: c for m, c in self.dict().iteritems()}) + return R({m[i]: c for m, c in self.monomial_coefficients().items()}) def monomial_reduction(self): """ @@ -1720,7 +1732,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): cdef list f = [] cdef dict d for t in pf: - d = (t[0].dict()) + d = (t[0].monomial_coefficients()) if len(d) == 1: # monomials are units u *= self.parent(d) ** t[1] else: @@ -1734,10 +1746,10 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): INPUT: - - ``root`` -- boolean (default ``False``); if set to ``True`` + - ``root`` -- boolean (default: ``False``); if set to ``True`` then return a pair ``(True, sqrt)`` with ``sqrt`` a square root of this Laurent polynomial when it exists or - ``(False, None)``. + ``(False, None)`` EXAMPLES:: @@ -1862,7 +1874,6 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]]), ....: new_ring=L.change_ring(F)) x^-2*y^2 + x^-3*y - """ cdef int n, i, j, x cdef dict d, dr diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index c10db4a39ca..40b09bbfb6e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -95,14 +95,14 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): INPUT: - ``base_ring`` -- a commutative ring - - ``name`` -- a string - - ``names`` -- a list or tuple of names, or a comma separated string - - ``n`` -- a positive integer - - ``sparse`` -- bool (default: ``False``), whether or not elements are sparse + - ``name`` -- string + - ``names`` -- list or tuple of names, or a comma separated string + - ``n`` -- positive integer + - ``sparse`` -- boolean (default: ``False``); whether or not elements are sparse - ``order`` -- string or :class:`~sage.rings.polynomial.term_order.TermOrder`, e.g., - - ``'degrevlex'`` (default) -- degree reverse lexicographic + - ``'degrevlex'`` -- default; degree reverse lexicographic - ``'lex'`` -- lexicographic - ``'deglex'`` -- degree lexicographic - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering @@ -136,7 +136,6 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): ... ValueError: variable names cannot be changed after object creation. - EXAMPLES: 1. ``LaurentPolynomialRing(base_ring, name, sparse=False)`` @@ -235,18 +234,18 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): sage: (w0 + 2*w8 + w13)^2 # needs sage.modules w0^2 + 4*w0*w8 + 4*w8^2 + 2*w0*w13 + 4*w8*w13 + w13^2 """ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base R = PolynomialRing(base_ring, *args, **kwds) if R in _cache: return _cache[R] # put () here to re-enable weakrefs - if is_PolynomialRing(R): + if isinstance(R, PolynomialRing_general): # univariate case P = LaurentPolynomialRing_univariate(R) else: - assert is_MPolynomialRing(R) + assert isinstance(R, MPolynomialRing_base) P = LaurentPolynomialRing_mpair(R) _cache[R] = P @@ -258,16 +257,14 @@ def _split_dict_(D, indices, group_by=None): INPUT: - - ``D`` -- a dictionary. - - - ``indices`` -- a tuple or list of nonnegative integers. + - ``D`` -- dictionary - - ``group_by`` -- a tuple or list of nonnegative integers. - If this is ``None`` (default), then no grouping is done. + - ``indices`` -- tuple or list of nonnegative integers - OUTPUT: + - ``group_by`` -- tuple or list of nonnegative integers; + if this is ``None`` (default), then no grouping is done - A dictionary. + OUTPUT: a dictionary TESTS:: @@ -341,17 +338,15 @@ def _split_laurent_polynomial_dict_(P, M, d): INPUT: - - ``P`` -- the parent to which we want to convert. + - ``P`` -- the parent to which we want to convert - - ``M`` -- the parent from which we want to convert. + - ``M`` -- the parent from which we want to convert - - ``d`` -- a dictionary mapping tuples (representing the exponents) + - ``d`` -- dictionary mapping tuples (representing the exponents) to their coefficients. This is the dictionary corresponding to an element of ``M``. - OUTPUT: - - A dictionary corresponding to an element of ``P``. + OUTPUT: a dictionary corresponding to an element of ``P`` TESTS:: @@ -393,7 +388,8 @@ def value(d, R): return {k: value(v, P.base_ring()) for k, v in D.items()} except (ValueError, TypeError): pass - return sum(P({k: 1}) * value(v, P) for k, v in D.items()).dict() + return sum(P({k: 1}) * value(v, P) + for k, v in D.items()).monomial_coefficients() def from_fraction_field(L, x): r""" @@ -449,6 +445,8 @@ def __init__(self, R): if R.ngens() != 1: raise ValueError("must be 1 generator") LaurentPolynomialRing_generic.__init__(self, R) + from sage.rings.integer_ring import IntegerRing + self._indices = IntegerRing() Element = LaurentPolynomial_univariate @@ -540,9 +538,9 @@ def _element_constructor_(self, x): P = x.parent() if set(self.variable_names()) & set(P.variable_names()): if isinstance(x, LaurentPolynomial_univariate): - d = {(k,): v for k, v in x.dict().items()} + d = {(k,): v for k, v in x.monomial_coefficients().items()} else: - d = x.dict() + d = x.monomial_coefficients() x = _split_laurent_polynomial_dict_(self, P, d) x = {k[0]: v for k, v in x.items()} elif P is self.base_ring(): @@ -550,7 +548,7 @@ def _element_constructor_(self, x): elif x.is_constant() and self.has_coerce_map_from(x.parent().base_ring()): return self(x.constant_coefficient()) elif len(self.variable_names()) == len(P.variable_names()): - x = x.dict() + x = x.monomial_coefficients() elif isinstance(x, FractionFieldElement): # since the field of fraction of self is defined corresponding to @@ -565,6 +563,12 @@ def _element_constructor_(self, x): return self.element_class(self, x) + def monomial(self, arg): + r""" + Return the monomial with the given exponent. + """ + return self.element_class(self, {arg: self.base_ring().one()}) + def __reduce__(self): """ Used in pickling. @@ -595,6 +599,9 @@ def __init__(self, R): if not R.base_ring().is_integral_domain(): raise ValueError("base ring must be an integral domain") LaurentPolynomialRing_generic.__init__(self, R) + from sage.modules.free_module import FreeModule + from sage.rings.integer_ring import IntegerRing + self._indices = FreeModule(IntegerRing(), R.ngens()) Element = LazyImport('sage.rings.polynomial.laurent_polynomial_mpair', 'LaurentPolynomial_mpair') @@ -609,7 +616,7 @@ def _repr_(self): """ return "Multivariate Laurent Polynomial Ring in %s over %s" % (", ".join(self._R.variable_names()), self._R.base_ring()) - def monomial(self, *args): + def monomial(self, *exponents): r""" Return the monomial whose exponents are given in argument. @@ -633,14 +640,27 @@ def monomial(self, *args): sage: L.monomial(1, 2, 3) # needs sage.modules Traceback (most recent call last): ... - TypeError: tuple key must have same length as ngens - """ - if len(args) != self.ngens(): - raise TypeError("tuple key must have same length as ngens") + TypeError: tuple key (1, 2, 3) must have same length as ngens (= 2) + + We also allow to specify the exponents in a single tuple:: + sage: L.monomial((-1, 2)) # needs sage.modules + x0^-1*x1^2 + + sage: L.monomial((-1, 2, 3)) # needs sage.modules + Traceback (most recent call last): + ... + TypeError: tuple key (-1, 2, 3) must have same length as ngens (= 2) + """ from sage.rings.polynomial.polydict import ETuple - m = ETuple(args, int(self.ngens())) - return self.element_class(self, self.polynomial_ring().one(), m) + if len(exponents) == 1 and isinstance((e := exponents[0]), (tuple, ETuple)): + exponents = e + + if len(exponents) != self.ngens(): + raise TypeError(f"tuple key {exponents} must have same length as ngens (= {self.ngens()})") + + m = ETuple(exponents, int(self.ngens())) + return self.element_class(self, self.polynomial_ring().base_ring().one(), m) def _element_constructor_(self, x, mon=None): """ @@ -767,9 +787,9 @@ def _element_constructor_(self, x, mon=None): pass elif set(self.variable_names()) & set(P.variable_names()): if isinstance(x, LaurentPolynomial_univariate): - d = {(k,): v for k, v in x.dict().items()} + d = {(k,): v for k, v in x.monomial_coefficients().items()} else: - d = x.dict() + d = x.monomial_coefficients() x = _split_laurent_polynomial_dict_(self, P, d) elif P is self.base_ring(): from sage.rings.polynomial.polydict import ETuple @@ -778,7 +798,7 @@ def _element_constructor_(self, x, mon=None): elif x.is_constant() and self.has_coerce_map_from(P.base_ring()): return self(x.constant_coefficient()) elif len(self.variable_names()) == len(P.variable_names()): - x = x.dict() + x = x.monomial_coefficients() elif isinstance(x, FractionFieldElement): # since the field of fraction of self is defined corresponding to diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 44654e1b076..b4f4f13289e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -42,11 +42,12 @@ class LaurentPolynomialRing_generic(CommutativeRing, Parent): sage: R. = LaurentPolynomialRing(QQ) sage: R.category() Join of Category of unique factorization domains + and Category of algebras with basis + over (number fields and quotient fields and metric spaces) and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets sage: TestSuite(R).run() - """ def __init__(self, R): """ @@ -85,7 +86,7 @@ def ngens(self): def gen(self, i=0): r""" - Returns the `i^{th}` generator of self. If i is not specified, then + Return the `i`-th generator of ``self``. If `i` is not specified, then the first generator will be returned. EXAMPLES:: @@ -119,11 +120,9 @@ def variable_names_recursive(self, depth=infinity): INPUT: - - ``depth`` -- an integer or :mod:`Infinity `. + - ``depth`` -- integer or :mod:`Infinity ` - OUTPUT: - - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -147,7 +146,7 @@ def variable_names_recursive(self, depth=infinity): def is_integral_domain(self, proof=True): """ - Return ``True`` if self is an integral domain. + Return ``True`` if ``self`` is an integral domain. EXAMPLES:: @@ -165,7 +164,7 @@ def is_integral_domain(self, proof=True): def is_noetherian(self): """ - Return ``True`` if self is Noetherian. + Return ``True`` if ``self`` is Noetherian. EXAMPLES:: @@ -183,7 +182,6 @@ def construction(self): sage: LaurentPolynomialRing(QQ, 2, 'x,y').construction() (LaurentPolynomialFunctor, Univariate Laurent Polynomial Ring in x over Rational Field) - """ from sage.categories.pushout import LaurentPolynomialFunctor from .laurent_polynomial_ring import LaurentPolynomialRing @@ -421,13 +419,12 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): def term_order(self): """ - Returns the term order of self. + Return the term order of ``self``. EXAMPLES:: sage: LaurentPolynomialRing(QQ, 2, 'x').term_order() Degree reverse lexicographic term order - """ return self._R.term_order() @@ -437,7 +434,6 @@ def is_finite(self): sage: LaurentPolynomialRing(QQ, 2, 'x').is_finite() False - """ return False @@ -452,7 +448,7 @@ def is_field(self, proof=True): def polynomial_ring(self): """ - Returns the polynomial ring associated with self. + Return the polynomial ring associated with ``self``. EXAMPLES:: @@ -465,7 +461,7 @@ def polynomial_ring(self): def characteristic(self): """ - Returns the characteristic of the base ring. + Return the characteristic of the base ring. EXAMPLES:: @@ -473,7 +469,6 @@ def characteristic(self): 0 sage: LaurentPolynomialRing(GF(3), 2, 'x').characteristic() 3 - """ return self.base_ring().characteristic() @@ -498,10 +493,10 @@ def random_element(self, min_valuation=-2, max_degree=2, *args, **kwds): INPUT: - - ``min_valuation`` -- integer (default: ``-2``); the + - ``min_valuation`` -- integer (default: `-2`); the minimal allowed valuation of the polynomial - - ``max_degree`` -- integer (default: ``2``); the + - ``max_degree`` -- integer (default: `2`); the maximal allowed degree of the polynomial - ``*args``, ``**kwds`` -- passed to the random element generator of the @@ -625,7 +620,7 @@ def random_element(self, min_valuation=-2, max_degree=2, *args, **kwds): abs_deg = (max_degree - min_valuation) f_rand = self._R.random_element(degree=abs_deg, *args, **kwds) - # Cast this polynomial back the `self`` + # Cast this polynomial back the ``self`` f = self(f_rand) # For the univariate case we simply shift by x**min_valuation diff --git a/src/sage/rings/polynomial/meson.build b/src/sage/rings/polynomial/meson.build new file mode 100644 index 00000000000..c1625c5eb94 --- /dev/null +++ b/src/sage/rings/polynomial/meson.build @@ -0,0 +1,174 @@ +py.install_sources( + 'all.py', + 'binary_form_reduce.py', + 'commutative_polynomial.pxd', + 'complex_roots.py', + 'convolution.py', + 'evaluation.pxd', + 'evaluation_flint.pxd', + 'evaluation_ntl.pxd', + 'flatten.py', + 'groebner_fan.py', + 'ideal.py', + 'infinite_polynomial_element.py', + 'infinite_polynomial_ring.py', + 'integer_valued_polynomials.py', + 'laurent_polynomial.pxd', + 'laurent_polynomial_ideal.py', + 'laurent_polynomial_mpair.pxd', + 'laurent_polynomial_ring.py', + 'laurent_polynomial_ring_base.py', + 'msolve.py', + 'multi_polynomial.pxd', + 'multi_polynomial_element.py', + 'multi_polynomial_ideal.py', + 'multi_polynomial_ideal_libsingular.pxd', + 'multi_polynomial_libsingular.pxd', + 'multi_polynomial_ring.py', + 'multi_polynomial_ring_base.pxd', + 'multi_polynomial_sequence.py', + 'omega.py', + 'ore_function_element.py', + 'ore_function_field.py', + 'ore_polynomial_element.pxd', + 'ore_polynomial_ring.py', + 'plural.pxd', + 'polydict.pxd', + 'polynomial_compiled.pxd', + 'polynomial_complex_arb.pxd', + 'polynomial_element.pxd', + 'polynomial_element_generic.py', + 'polynomial_fateman.py', + 'polynomial_gf2x.pxd', + 'polynomial_integer_dense_flint.pxd', + 'polynomial_integer_dense_ntl.pxd', + 'polynomial_modn_dense_ntl.pxd', + 'polynomial_quotient_ring.py', + 'polynomial_quotient_ring_element.py', + 'polynomial_rational_flint.pxd', + 'polynomial_ring.py', + 'polynomial_ring_constructor.py', + 'polynomial_ring_homomorphism.pxd', + 'polynomial_singular_interface.py', + 'polynomial_zmod_flint.pxd', + 'polynomial_zz_pex.pxd', + 'real_roots.pxd', + 'skew_polynomial_element.pxd', + 'skew_polynomial_finite_field.pxd', + 'skew_polynomial_finite_order.pxd', + 'skew_polynomial_ring.py', + 'symmetric_ideal.py', + 'symmetric_reduction.pxd', + 'term_order.py', + 'toy_buchberger.py', + 'toy_d_basis.py', + 'toy_variety.py', + subdir: 'sage/rings/polynomial', +) + +extension_data = { + 'commutative_polynomial' : files('commutative_polynomial.pyx'), + 'cyclotomic' : files('cyclotomic.pyx'), + 'evaluation_flint' : files('evaluation_flint.pyx'), + 'hilbert' : files('hilbert.pyx'), + 'laurent_polynomial' : files('laurent_polynomial.pyx'), + 'laurent_polynomial_mpair' : files('laurent_polynomial_mpair.pyx'), + 'multi_polynomial' : files('multi_polynomial.pyx'), + 'multi_polynomial_ring_base' : files('multi_polynomial_ring_base.pyx'), + 'ore_polynomial_element' : files('ore_polynomial_element.pyx'), + 'polydict' : files('polydict.pyx'), + 'polynomial_compiled' : files('polynomial_compiled.pyx'), + 'polynomial_complex_arb' : files('polynomial_complex_arb.pyx'), + 'polynomial_element' : files('polynomial_element.pyx'), + 'polynomial_number_field' : files('polynomial_number_field.pyx'), + 'polynomial_real_mpfr_dense' : files('polynomial_real_mpfr_dense.pyx'), + 'polynomial_ring_homomorphism' : files('polynomial_ring_homomorphism.pyx'), + 'real_roots' : files('real_roots.pyx'), + 'refine_root' : files('refine_root.pyx'), + 'skew_polynomial_element' : files('skew_polynomial_element.pyx'), + 'skew_polynomial_finite_field' : files('skew_polynomial_finite_field.pyx'), + 'skew_polynomial_finite_order' : files('skew_polynomial_finite_order.pyx'), + 'symmetric_reduction' : files('symmetric_reduction.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/polynomial', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_ntl, + inc_numpy, + inc_rings, + inc_rings_finite, + ], + dependencies: [ + py_dep, + cypari2, + cysignals, + flint, + givaro, + gmp, + mpfi, + mpfr, + ntl, + pari, + ], + ) +endforeach + +extension_data_cpp = { + 'evaluation_ntl': files('evaluation_ntl.pyx'), + 'multi_polynomial_ideal_libsingular': files( + 'multi_polynomial_ideal_libsingular.pyx', + ), + 'multi_polynomial_libsingular': files('multi_polynomial_libsingular.pyx'), + 'plural': files('plural.pyx'), + 'polynomial_gf2x': files('polynomial_gf2x.pyx'), + 'polynomial_integer_dense_flint': files('polynomial_integer_dense_flint.pyx'), + 'polynomial_integer_dense_ntl': files('polynomial_integer_dense_ntl.pyx'), + 'polynomial_modn_dense_ntl': files('polynomial_modn_dense_ntl.pyx'), + 'polynomial_rational_flint': files('polynomial_rational_flint.pyx'), + 'polynomial_zmod_flint': files('polynomial_zmod_flint.pyx'), + 'polynomial_zz_pex': files('polynomial_zz_pex.pyx'), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/polynomial', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_flint, + inc_ntl, + inc_numpy, + inc_rings, + inc_rings_finite, + ], + dependencies: [ + py_dep, + cypari2, + cysignals, + flint, + givaro, + gmp, + mpfi, + mpfr, + ntl, + pari, + singular, + ], + ) +endforeach + +install_subdir('padics', install_dir: sage_install_dir / 'rings/polynomial') +subdir('pbori') +subdir('weil') diff --git a/src/sage/rings/polynomial/msolve.py b/src/sage/rings/polynomial/msolve.py index d15d498c040..fb22236fba9 100644 --- a/src/sage/rings/polynomial/msolve.py +++ b/src/sage/rings/polynomial/msolve.py @@ -136,18 +136,18 @@ def variety(ideal, ring, *, proof=True): sage: R. = PolynomialRing(GF(p), 2, order='lex') sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) - sage: sorted(I.variety(algorithm="msolve", proof=False), key=str) # optional - msolve + sage: sorted(I.variety(algorithm='msolve', proof=False), key=str) # optional - msolve [{x: 1, y: 1}, {x: 267525699, y: 473946006}] sage: K. = GF(p^2) - sage: sorted(I.variety(K, algorithm="msolve", proof=False), key=str) # optional - msolve + sage: sorted(I.variety(K, algorithm='msolve', proof=False), key=str) # optional - msolve [{x: 1, y: 1}, {x: 118750849*a + 194048031, y: 510295713*a + 18174854}, {x: 267525699, y: 473946006}, {x: 418120060*a + 75297182, y: 26575196*a + 44750050}] sage: R. = PolynomialRing(GF(2147483659), 2, order='lex') - sage: ideal([x, y]).variety(algorithm="msolve", proof=False) + sage: ideal([x, y]).variety(algorithm='msolve', proof=False) Traceback (most recent call last): ... NotImplementedError: unsupported base field: Finite Field of size 2147483659 diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 2f4a33dc358..ca25adc23f0 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -243,12 +243,12 @@ cdef class MPolynomial(CommutativePolynomial): - Didier Deshommes """ - d = self.dict() + d = self.monomial_coefficients() return [d[i] for i in self.exponents()] def truncate(self, var, n): r""" - Returns a new multivariate polynomial obtained from ``self`` by + Return a new multivariate polynomial obtained from ``self`` by deleting all terms that involve the given variable to a power at least ``n``. """ @@ -260,8 +260,8 @@ cdef class MPolynomial(CommutativePolynomial): ind = Z.index(var) except ValueError: raise ValueError("var must be one of the generators of the parent polynomial ring.") - d = self.dict() - return R(dict([(k, c) for k, c in d.iteritems() if k[ind] < n])) + return R({k: c for k, c in self.monomial_coefficients().items() + if k[ind] < n}) def _fast_callable_(self, etb): r""" @@ -299,9 +299,9 @@ cdef class MPolynomial(CommutativePolynomial): n = len(x) expr = etb.constant(self.base_ring().zero()) - for (m, c) in self.dict().iteritems(): - monom = prod([ x[i]**m[i] for i in range(n) if m[i] != 0], - etb.constant(c)) + for m, c in self.monomial_coefficients().items(): + monom = prod([x[i] ** m[i] for i in range(n) if m[i] != 0], + etb.constant(c)) expr = expr + monom return expr @@ -426,12 +426,12 @@ cdef class MPolynomial(CommutativePolynomial): d = self.degree(var) B = ring.base_ring() w = {remove_from_tuple(e, ind): val - for e, val in self.dict().iteritems() if not e[ind]} + for e, val in self.monomial_coefficients().items() if not e[ind]} v = [B(w)] # coefficients that don't involve var z = var for i in range(1,d+1): - c = self.coefficient(z).dict() - w = {remove_from_tuple(e, ind): val for e, val in c.iteritems()} + c = self.coefficient(z).monomial_coefficients() + w = {remove_from_tuple(e, ind): val for e, val in c.items()} v.append(B(w)) z *= var return ring(v) @@ -483,7 +483,7 @@ cdef class MPolynomial(CommutativePolynomial): vars = self._parent.variable_names_recursive() cdef tuple my_vars = self._parent.variable_names() if vars == my_vars: - return self.dict() + return self.monomial_coefficients() elif my_vars[-1] not in vars: x = base_ring(self) if base_ring is not None else self const_ix = ETuple((0,)*len(vars)) @@ -511,13 +511,13 @@ cdef class MPolynomial(CommutativePolynomial): new_map[k] -= m tmp = [0] * (len(vars) - m) try: - for ix,a in self.dict().iteritems(): + for ix, a in self.monomial_coefficients().items(): for k in range(len(my_vars)): tmp[new_map[k]] = ix[k] postfix = ETuple(tmp) mpoly = a._mpoly_dict_recursive(prev_vars, base_ring) - for prefix,b in mpoly.iteritems(): - D[prefix+postfix] = b + for prefix, b in mpoly.items(): + D[prefix + postfix] = b return D except AttributeError: @@ -527,7 +527,7 @@ cdef class MPolynomial(CommutativePolynomial): base_ring = None tmp = [0] * len(vars) - for ix,a in self.dict().iteritems(): + for ix, a in self.monomial_coefficients().items(): for k in range(len(my_vars)): tmp[mapping[k]] = ix[k] if base_ring is not None: @@ -573,13 +573,12 @@ cdef class MPolynomial(CommutativePolynomial): Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' - """ cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap cdef long result_mon var_name_hash = [hash(v) for v in self._parent.variable_names()] cdef long c_hash - for m,c in self.dict().iteritems(): + for m, c in self.monomial_coefficients().items(): # I'm assuming (incorrectly) that hashes of zero indicate that the element is 0. # This assumption is not true, but I think it is true enough for the purposes and it # it allows us to write fast code that omits terms with 0 coefficients. This is @@ -605,7 +604,7 @@ cdef class MPolynomial(CommutativePolynomial): def args(self): r""" - Returns the names of the arguments of ``self``, in the + Return the names of the arguments of ``self``, in the order they are accepted from call. EXAMPLES:: @@ -710,7 +709,6 @@ cdef class MPolynomial(CommutativePolynomial): sage: q2 = p.homogenize() sage: q1.parent() is q2.parent() True - """ P = self.parent() @@ -784,9 +782,7 @@ cdef class MPolynomial(CommutativePolynomial): r""" Return the homogeneous components of this polynomial. - OUTPUT: - - A dictionary mapping degrees to homogeneous polynomials. + OUTPUT: a dictionary mapping degrees to homogeneous polynomials EXAMPLES:: @@ -850,7 +846,7 @@ cdef class MPolynomial(CommutativePolynomial): - ``R`` -- a ring or morphism; if a morphism, the coefficients are mapped to the codomain of ``R`` - OUTPUT: a new polynomial with the base ring changed to ``R``. + OUTPUT: a new polynomial with the base ring changed to ``R`` EXAMPLES:: @@ -917,7 +913,7 @@ cdef class MPolynomial(CommutativePolynomial): """ if isinstance(R, Map): return self.map_coefficients(R) - return self.parent().change_ring(R)(self.dict()) + return self.parent().change_ring(R)(self.monomial_coefficients()) def is_symmetric(self, group=None): r""" @@ -925,7 +921,7 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - - ``group`` (default: symmetric group) -- if set, test whether the + - ``group`` -- (default: symmetric group) if set, test whether the polynomial is invariant with respect to the given permutation group EXAMPLES:: @@ -1001,14 +997,14 @@ cdef class MPolynomial(CommutativePolynomial): raise ValueError("argument must be a permutation group") gens = [S(g) for g in gens] - cdef dict coeffs = self.dict() + cdef dict coeffs = self.monomial_coefficients() zero = self.base_ring().zero() return all(coeffs.get(g._act_on_etuple_on_position(e), zero) == coeff for e, coeff in coeffs.items() for g in gens) def _gap_(self, gap): r""" - Return a representation of ``self`` in the GAP interface + Return a representation of ``self`` in the GAP interface. INPUT: @@ -1076,7 +1072,7 @@ cdef class MPolynomial(CommutativePolynomial): def _magma_init_(self, magma): r""" - Returns a Magma string representation of ``self`` valid in the + Return a Magma string representation of ``self`` valid in the given magma session. EXAMPLES:: @@ -1118,7 +1114,7 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: # needs sage.libs.giac + sage: # needs giac sage: R. = GF(101)['e,i'][] sage: f = R('e*i') * x + y^2 sage: f._giac_init_() @@ -1150,7 +1146,7 @@ cdef class MPolynomial(CommutativePolynomial): def jacobian_ideal(self): r""" - Return the Jacobian ideal of the polynomial self. + Return the Jacobian ideal of the polynomial ``self``. EXAMPLES:: @@ -1194,7 +1190,7 @@ cdef class MPolynomial(CommutativePolynomial): r""" Facilitates iterating over the monomials of ``self``, returning tuples of the form ``(coeff, mon)`` for each - non-zero monomial. + nonzero monomial. EXAMPLES:: @@ -1215,7 +1211,7 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - - ``as_ETuples`` -- (default: ``True``) if ``True``, iterate over + - ``as_ETuples`` -- boolean (default: ``True``); if ``True``, iterate over pairs whose first element is an :class:`ETuple`, otherwise as a tuples EXAMPLES:: @@ -1262,7 +1258,6 @@ cdef class MPolynomial(CommutativePolynomial): sage: f.content(); f.content().parent() 2 Rational Field - """ from sage.arith.misc import GCD as gcd return gcd(self.coefficients()) @@ -1291,8 +1286,7 @@ cdef class MPolynomial(CommutativePolynomial): def is_generator(self): r""" - Returns ``True`` if this polynomial is a generator of its - parent. + Return ``True`` if this polynomial is a generator of its parent. EXAMPLES:: @@ -1315,7 +1309,7 @@ cdef class MPolynomial(CommutativePolynomial): def map_coefficients(self, f, new_base_ring=None): r""" - Returns the polynomial obtained by applying ``f`` to the non-zero + Return the polynomial obtained by applying ``f`` to the nonzero coefficients of ``self``. If ``f`` is a :class:`sage.categories.map.Map`, then the resulting @@ -1325,10 +1319,10 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - - ``f`` -- a callable that will be applied to the coefficients of ``self``. + - ``f`` -- a callable that will be applied to the coefficients of ``self`` - - ``new_base_ring`` (optional) -- if given, the resulting polynomial - will be defined over this ring. + - ``new_base_ring`` -- (optional) if given, the resulting polynomial + will be defined over this ring EXAMPLES:: @@ -1360,14 +1354,13 @@ cdef class MPolynomial(CommutativePolynomial): X - Y sage: g.parent() Multivariate Polynomial Ring in X, Y over Finite Field of size 3 - """ R = self.parent() if new_base_ring is not None: R = R.change_ring(new_base_ring) elif isinstance(f, Map): R = R.change_ring(f.codomain()) - return R(dict([(k,f(v)) for (k,v) in self.dict().items()])) + return R({k: f(v) for k, v in self.monomial_coefficients().items()}) def _norm_over_nonprime_finite_field(self): r""" @@ -1375,7 +1368,7 @@ cdef class MPolynomial(CommutativePolynomial): `\GF{p^e}`, compute the norm of the polynomial down to `\GF{p}`. This is the product of the conjugates by the Frobenius action - on coefficients, where Frobenius acts by p-th power. + on coefficients, where Frobenius acts by `p`-th power. This is (currently) an internal function used in factoring over finite fields. @@ -1409,13 +1402,11 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - ``self``, ``right`` -- multivariate polynomials - - ``variable`` -- optional, compute the Sylvester matrix with respect to this - variable. If ``variable`` is not provided, the first variable of the - polynomial ring is used. - - OUTPUT: + - ``variable`` -- (optional) compute the Sylvester matrix with respect + to this variable. If ``variable`` is not provided, the first variable + of the polynomial ring is used. - - The Sylvester matrix of ``self`` and ``right``. + OUTPUT: the Sylvester matrix of ``self`` and ``right`` EXAMPLES:: @@ -1508,7 +1499,6 @@ cdef class MPolynomial(CommutativePolynomial): [0 3] sage: K(3).sylvester_matrix(K(4)) [] - """ # This code is almost exactly the same as that of @@ -1557,14 +1547,14 @@ cdef class MPolynomial(CommutativePolynomial): def discriminant(self,variable): r""" - Returns the discriminant of ``self`` with respect to the given variable. + Return the discriminant of ``self`` with respect to the given variable. INPUT: - - ``variable`` -- The variable with respect to which we compute + - ``variable`` -- the variable with respect to which we compute the discriminant - OUTPUT: An element of the base ring of the polynomial ring. + OUTPUT: an element of the base ring of the polynomial ring EXAMPLES:: @@ -1622,7 +1612,7 @@ cdef class MPolynomial(CommutativePolynomial): - ``other`` -- a polynomial - OUTPUT: a list of polynomials in the same ring as ``self`` + OUTPUT: list of polynomials in the same ring as ``self`` EXAMPLES:: @@ -1635,7 +1625,6 @@ cdef class MPolynomial(CommutativePolynomial): sage: p.subresultants(q, x) [2*y^6 - 22*y^5 + 102*y^4 - 274*y^3 + 488*y^2 - 552*y + 288, x*y^2 + y^3 - 5*x*y - 6*y^2 + 6*x + 11*y - 6] - """ R = self.parent() if variable is None: @@ -1662,13 +1651,11 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - - ``args`` -- a list of `n-1` homogeneous polynomials in `n` variables. - works when ``args[0]`` is the list of polynomials, - or ``args`` is itself the list of polynomials - - OUTPUT: + - ``args`` -- list of `n-1` homogeneous polynomials in `n` variables; + works when ``args[0]`` is the list of polynomials, or ``args`` is + itself the list of polynomials - - the Macaulay resultant + OUTPUT: the Macaulay resultant EXAMPLES: @@ -1773,7 +1760,6 @@ cdef class MPolynomial(CommutativePolynomial): sage: RH = fh.parent() sage: f.resultant(g) == fh.macaulay_resultant(gh) # needs sage.modules True - """ if len(args) == 1 and isinstance(args[0],list): return self.parent().macaulay_resultant(self, *args[0]) @@ -1793,7 +1779,7 @@ cdef class MPolynomial(CommutativePolynomial): .. warning:: This is not the denominator of the rational function - defined by self, which would always be 1 since self is a + defined by ``self``, which would always be 1 since ``self`` is a polynomial. EXAMPLES: @@ -1870,7 +1856,7 @@ cdef class MPolynomial(CommutativePolynomial): .. warning:: This is not the numerator of the rational function - defined by ``self``, which would always be self since ``self`` is a + defined by ``self``, which would always be ``self`` since ``self`` is a polynomial. EXAMPLES: @@ -1948,7 +1934,7 @@ cdef class MPolynomial(CommutativePolynomial): def inverse_mod(self, I): r""" - Returns an inverse of ``self`` modulo the polynomial ideal `I`, + Return an inverse of ``self`` modulo the polynomial ideal `I`, namely a multivariate polynomial `f` such that ``self * f - 1`` belongs to `I`. @@ -1956,9 +1942,7 @@ cdef class MPolynomial(CommutativePolynomial): - ``I`` -- an ideal of the polynomial ring in which ``self`` lives - OUTPUT: - - a multivariate polynomial representing the inverse of ``f`` modulo `I` + OUTPUT: a multivariate polynomial representing the inverse of ``f`` modulo `I` EXAMPLES:: @@ -1999,11 +1983,11 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - - ``weights`` -- Either individual numbers, an iterable or a dictionary, + - ``weights`` -- either individual numbers, an iterable or a dictionary, specifying the weights of each variable. If it is a dictionary, it maps each variable of ``self`` to its weight. If it is a sequence of individual numbers or a tuple, the weights are specified in the order - of the generators as given by ``self.parent().gens()``: + of the generators as given by ``self.parent().gens()``. EXAMPLES:: @@ -2180,7 +2164,7 @@ cdef class MPolynomial(CommutativePolynomial): r""" Return a `n`-th root of this element. - If there is no such root, a ``ValueError`` is raised. + If there is no such root, a :exc:`ValueError` is raised. EXAMPLES:: @@ -2344,20 +2328,19 @@ cdef class MPolynomial(CommutativePolynomial): Implemented by Rebecca Lauren Miller as part of GSOC 2016. Smallest coefficients added by Ben Hutz July 2018. - INPUT: - - keywords: + INPUT: keyword arguments: - - ``prec`` -- integer, sets the precision (default: 300) + - ``prec`` -- integer (default: 300); sets the precision - - ``return_conjugation`` -- boolean. Returns element of `SL(2, \ZZ)` (default: ``True``) + - ``return_conjugation`` -- boolean (default: ``True``); whether to + return element of `SL(2, \ZZ)` - ``error_limit`` -- sets the error tolerance (default: 0.000001) - - ``smallest_coeffs`` -- (default: ``True``), boolean, whether to find the + - ``smallest_coeffs`` -- boolean (default: ``True``); whether to find the model with smallest coefficients - - ``norm_type`` -- either ``'norm'`` or ``'height'``. What type of norm + - ``norm_type`` -- either ``'norm'`` or ``'height'``; what type of norm to use for smallest coefficients - ``emb`` -- (optional) embedding of based field into ``CC`` @@ -2617,7 +2600,6 @@ cdef class MPolynomial(CommutativePolynomial): sage: _. = Zmod(36)[] sage: (7+ 6*x + 12*y - 18*x*y).is_unit() True - """ # EXERCISE (Atiyah-McDonald, Ch 1): Let `A[x]` be a polynomial # ring in one variable. Then `f=\sum a_i x^i \in A[x]` is a unit\ @@ -2629,7 +2611,7 @@ cdef class MPolynomial(CommutativePolynomial): # K[x,y,...] as K[x][y]... if not self.constant_coefficient().is_unit(): return False - cdef dict d = self.dict() + cdef dict d = self.monomial_coefficients() cdef ETuple zero_key = ETuple({}, int(self.parent().ngens())) d.pop(zero_key, None) return all(d[k].is_nilpotent() for k in d) @@ -2664,7 +2646,7 @@ cdef class MPolynomial(CommutativePolynomial): # Section 7.3 Exercise 33). # This generalizes easily to the multivariate case, by considering # K[x,y,...] as K[x][y]... - d = self.dict() + d = self.monomial_coefficients() return all(c.is_nilpotent() for c in d.values()) def _test_subs(self, tester=None, **options): @@ -2683,7 +2665,7 @@ cdef class MPolynomial(CommutativePolynomial): if gens: # substituting all variables (in a polynomial ring with variables) with 0 - d = {str(gen): 0 for gen in gens} + d = {str(gen): self.base_ring().zero() for gen in gens} tester.assertEqual(self.subs(**d).parent(), self.parent().base_ring()) # substituting all variables (in a polynomial ring with variables) @@ -2696,7 +2678,7 @@ cdef class MPolynomial(CommutativePolynomial): if len(gens) > 1: # substituting one variable (in a polynomial ring with variables) with 0 - d = {str(gens[0]): 0} + d = {str(gens[0]): self.base_ring().zero()} tester.assertEqual(self.subs(**d).parent(), self.parent()) # test error checking: partial substitution by elements @@ -2949,7 +2931,7 @@ cdef remove_from_tuple(e, int ind): cdef class MPolynomial_libsingular(MPolynomial): r""" - Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular` + Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular`. This class is defined for the purpose of :func:`isinstance` tests. It should not be instantiated. diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 91fcd38631b..6c4ec02c1b1 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -37,7 +37,7 @@ ....: + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2) True """ -#***************************************************************************** +# **************************************************************************** # # Sage: Open Source Mathematical Software # @@ -54,7 +54,7 @@ # The full text of the GPL is available at: # # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** import operator @@ -123,8 +123,7 @@ def __call__(self, *x, **kwds): Evaluate this multi-variate polynomial at `x`, where `x` is either the tuple of values to substitute in, or one can use functional notation `f(a_0,a_1,a_2, \ldots)` to - evaluate `f` with the ith variable replaced by - `a_i`. + evaluate `f` with the `i`-th variable replaced by `a_i`. EXAMPLES:: @@ -177,9 +176,14 @@ def __call__(self, *x, **kwds): K = x[0].parent() except AttributeError: K = self.parent().base_ring() - y = K(0) + try: + y = K.zero() + one = K.one() + except (AttributeError, RuntimeError): + y = K(0) + one = K(1) for m, c in self.element().dict().items(): - y += c * prod(v ** e for v, e in zip(x, m) if e) + y += c * prod((v ** e for v, e in zip(x, m) if e), one) return y def _richcmp_(self, right, op): @@ -246,7 +250,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None): def number_of_terms(self): """ - Return the number of non-zero coefficients of this polynomial. + Return the number of nonzero coefficients of this polynomial. This is also called weight, :meth:`hamming_weight` or sparsity. @@ -330,7 +334,7 @@ def _mul_(self, right): def _lmul_(self, a): """ - Left Scalar Multiplication + Left Scalar Multiplication. EXAMPLES: @@ -351,7 +355,7 @@ def _lmul_(self, a): def _rmul_(self, a): """ - Right Scalar Multiplication + Right Scalar Multiplication. EXAMPLES: @@ -447,7 +451,6 @@ def _new_constant_poly(self, x, P): sage: R. = QQ['t'][] sage: x._new_constant_poly(R.base_ring()(2),R) 2 - """ return MPolynomial_polydict(P, {P._zero_tuple:x}) @@ -537,7 +540,7 @@ def _macaulay2_(self, macaulay2=None): def degrees(self): r""" - Returns a tuple (precisely - an ``ETuple``) with the + Return a tuple (precisely - an ``ETuple``) with the degree of each variable in this polynomial. The list of degrees is, of course, ordered by the order of the generators. @@ -748,8 +751,7 @@ def monomial_coefficient(self, mon): INPUT: - - ``mon`` -- a monomial - + - ``mon`` -- a monomial OUTPUT: coefficient in base ring @@ -800,13 +802,28 @@ def monomial_coefficient(self, mon): zero = self.parent().base_ring().zero() return self.element().get(exp, zero) - def dict(self): + def monomial_coefficients(self): """ Return underlying dictionary with keys the exponents and values the coefficients of this polynomial. + + EXAMPLES:: + + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order='lex') + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) + sage: f.monomial_coefficients() + {(1, 5, 2): 1, (2, 0, 1): 1, (4, 1, 3): 1} + + ``dict`` is an alias:: + + sage: f.dict() # needs sage.rings.number_field + {(1, 5, 2): 1, (2, 0, 1): 1, (4, 1, 3): 1} """ return self.element().dict() + dict = monomial_coefficients + def __iter__(self): """ Iterate over ``self`` respecting the term order. @@ -855,8 +872,8 @@ def __getitem__(self, x): INPUT: - - ``x`` -- a tuple or, in case of a single-variable - MPolynomial ring x can also be an integer + - ``x`` -- tuple or, in case of a single-variable + MPolynomial ring, ``x`` can also be an integer EXAMPLES:: @@ -897,8 +914,8 @@ def iterator_exp_coeff(self, as_ETuples=True): INPUT: - - ``as_ETuples`` -- (default: ``True``) if ``True`` iterate over - pairs whose first element is an ETuple, otherwise as a tuples + - ``as_ETuples`` -- boolean (default: ``True``); if ``True`` iterate + over pairs whose first element is an ETuple, otherwise as a tuples EXAMPLES:: @@ -934,16 +951,14 @@ def coefficient(self, degrees): INPUT: + - ``degrees`` -- can be any of: - - ``degrees`` -- Can be any of: - - - a dictionary of degree restrictions + - a dictionary of degree restrictions - - a list of degree restrictions (with None in - the unrestricted variables) - - - a monomial (very fast, but not as flexible) + - a list of degree restrictions (with ``None`` in + the unrestricted variables) + - a monomial (very fast, but not as flexible) OUTPUT: element of the parent of ``self`` @@ -1022,9 +1037,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -1099,12 +1114,12 @@ def local_height(self, v, prec=None): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -1149,12 +1164,12 @@ def local_height_arch(self, i, prec=None): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -1214,12 +1229,10 @@ def exponents(self, as_ETuples=True): INPUT: - - ``as_ETuples`` -- (default: ``True``): return the list of + - ``as_ETuples`` -- (default: ``True``) return the list of exponents as a list of ETuples - OUTPUT: - - The list of exponents as a list of ETuples or tuples. + OUTPUT: the list of exponents as a list of ETuples or tuples EXAMPLES:: @@ -1292,8 +1305,17 @@ def is_homogeneous(self): False sage: (x^2*y + y^2*x).is_homogeneous() True + + The weight of the parent ring is respected:: + + sage: term_order = TermOrder("wdegrevlex", [1, 3]) + sage: R. = PolynomialRing(Qp(5), order=term_order) + sage: (x + y).is_homogeneous() + False + sage: (x^3 + y).is_homogeneous() + True """ - return self.element().is_homogeneous() + return self.element().is_homogeneous(self.parent().term_order().weights()) def _homogenize(self, var): r""" @@ -1303,10 +1325,8 @@ def _homogenize(self, var): INPUT: - - - ``var`` -- an integer indicating which variable to - use to homogenize (0 <= var < parent(self).ngens()) - + - ``var`` -- integer indicating which variable to + use to homogenize (``0 <= var < parent(self).ngens()``) OUTPUT: a multivariate polynomial @@ -1421,10 +1441,9 @@ def subs(self, fixed=None, **kwds): INPUT: - - ``fixed`` -- (optional) dictionary of inputs - - - ``**kwds`` -- named parameters + - ``fixed`` -- (optional) dictionary of inputs + - ``**kwds`` -- named parameters OUTPUT: new :class:`MPolynomial` @@ -1506,7 +1525,7 @@ def constant_coefficient(self): def is_univariate(self): """ Return ``True`` if this multivariate polynomial is univariate and - False otherwise. + ``False`` otherwise. EXAMPLES:: @@ -1537,17 +1556,16 @@ def is_univariate(self): def univariate_polynomial(self, R=None): """ - Returns a univariate polynomial associated to this multivariate + Return a univariate polynomial associated to this multivariate polynomial. INPUT: - - - ``R`` -- (default: None) :class:`PolynomialRing` + - ``R`` -- (default: ``None``) :class:`PolynomialRing` If this polynomial is not in at most one variable, then a - :class:`ValueError` exception is raised. This is checked using the + :exc:`ValueError` exception is raised. This is checked using the method :meth:`is_univariate`. The new :class:`Polynomial` is over the same base ring as the given :class:`MPolynomial`. @@ -1600,7 +1618,7 @@ def univariate_polynomial(self, R=None): return R(0) #construct list - lookup = [int(0),] * len(next(iter(monomial_coefficients))) + lookup = [0,] * len(next(iter(monomial_coefficients))) coefficients = [] for degree in range(max(m[var_idx] for m in monomial_coefficients.keys()) + 1): @@ -1615,7 +1633,7 @@ def univariate_polynomial(self, R=None): def variables(self): """ - Returns the tuple of variables occurring in this polynomial. + Return the tuple of variables occurring in this polynomial. EXAMPLES:: @@ -1728,7 +1746,6 @@ def lm(self): sage: f = x + y sage: f.lm() x - """ try: return self.__lm @@ -1743,8 +1760,8 @@ def lm(self): def lc(self): """ - Returns the leading coefficient of ``self``, i.e., - ``self.coefficient(self.lm())`` + Return the leading coefficient of ``self``, i.e., + ``self.coefficient(self.lm())``. EXAMPLES:: @@ -1776,7 +1793,7 @@ def lt(self): sage: f = 3*x^2 - y^2 - x*y sage: f.lt() 3*x^2 - sage: R. = PolynomialRing(QQbar, order="invlex") + sage: R. = PolynomialRing(QQbar, order='invlex') sage: f = 3*x^2 - y^2 - x*y sage: f.lt() -y^2 @@ -1821,9 +1838,9 @@ def __ne__(self, right): def __bool__(self): """ - Return ``True`` if self != 0 + Return ``True`` if ``self != 0``. - .. note:: + .. NOTE:: This is much faster than actually writing ``self == 0``. """ @@ -1831,9 +1848,9 @@ def __bool__(self): def _floordiv_(self, right): r""" - Quotient of division of ``self`` by other. This is denoted //. + Quotient of division of ``self`` by ``other``. This is denoted ``//``. - .. note:: + .. NOTE:: It's not clear to me that this is well-defined if ``self`` is not exactly divisible by other. @@ -1852,12 +1869,12 @@ def _floordiv_(self, right): """ # handle division by monomials without using Singular - if len(right.dict()) == 1: + if len(right.monomial_coefficients()) == 1: P = self.parent() ret = P(0) - denC,denM = next(iter(right)) - for c,m in self: - t = c*m + denC, denM = next(iter(right)) + for c, m in self: + t = c * m if denC.divides(c) and P.monomial_divides(denM, m): ret += P.monomial_quotient(t, right, coeff=True) return ret @@ -1913,7 +1930,8 @@ def _derivative(self, var=None): if index == -1: # var is not a generator; do term-by-term differentiation recursively # var may be, for example, a generator of the base ring - d = dict([(e, x._derivative(var)) for (e, x) in self.dict().items()]) + d = {e: x._derivative(var) + for e, x in self.monomial_coefficients().items()} d = polydict.PolyDict(d, check=False) d.remove_zeros() return MPolynomial_polydict(P, d) @@ -2010,7 +2028,7 @@ def integral(self, var=None): # var is not a generator; do term-by-term integration recursively # var may be, for example, a generator of the base ring d = {e: x.integral(var) - for e, x in self.dict().items()} + for e, x in self.monomial_coefficients().items()} d = polydict.PolyDict(d, check=False) d.remove_zeros() else: @@ -2025,7 +2043,7 @@ def factor(self, proof=None): INPUT: - ``proof`` -- insist on provably correct results (default: ``True`` - unless explicitly disabled for the ``"polynomial"`` subsystem with + unless explicitly disabled for the ``'polynomial'`` subsystem with :class:`sage.structure.proof.proof.WithProof`.) TESTS: @@ -2128,7 +2146,6 @@ def factor(self, proof=None): sage: f = y^3 + x^3 + (u + 1)*x sage: f.factor() x^3 + y^3 + (u + 1)*x - """ R = self.parent() @@ -2163,7 +2180,7 @@ def factor(self, proof=None): if proof is None: from sage.structure.proof.proof import get_flag - proof = get_flag(subsystem="polynomial") + proof = get_flag(subsystem='polynomial') if proof: raise NotImplementedError("Provably correct factorization not implemented. Disable this error by wrapping your code in a `with proof.WithProof('polynomial', False):` block.") @@ -2226,7 +2243,7 @@ def lift(self,I): @handle_AA_and_QQbar def quo_rem(self, right): """ - Returns quotient and remainder of ``self`` and ``right``. + Return quotient and remainder of ``self`` and ``right``. EXAMPLES:: @@ -2361,7 +2378,7 @@ def subresultants(self, other, variable=None): - ``other`` -- a polynomial - OUTPUT: a list of polynomials in the same ring as ``self`` + OUTPUT: list of polynomials in the same ring as ``self`` EXAMPLES:: @@ -2375,7 +2392,6 @@ def subresultants(self, other, variable=None): sage: p.subresultants(q, x) [2*y^6 + (-22)*y^5 + 102*y^4 + (-274)*y^3 + 488*y^2 + (-552)*y + 288, x*y^2 + y^3 + (-5)*x*y + (-6)*y^2 + 6*x + 11*y - 6] - """ R = self.parent() if variable is None: @@ -2392,7 +2408,7 @@ def reduce(self, I): INPUT: - - ``I`` -- a list of polynomials or an ideal + - ``I`` -- list of polynomials or an ideal EXAMPLES:: @@ -2480,6 +2496,7 @@ def reduce(self, I): p -= plt return r + ############################################################### # Useful for some geometry code. ############################################################### @@ -2494,7 +2511,7 @@ def degree_lowest_rational_function(r, x): - ``x`` -- a multivariate polynomial ring generator - OUTPUT: integer -- the difference `val_x(p) - val_x(q)` where `r = p/q` + OUTPUT: integer; the difference `val_x(p) - val_x(q)` where `r = p/q` .. NOTE:: diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index d5b7dce9866..222da435df2 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -176,7 +176,7 @@ The Groebner basis modulo any product of the prime factors is also non-trivial:: sage: I.change_ring(P.change_ring(IntegerModRing(2 * 7))).groebner_basis() - [x + 9*y + 13*z, y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10] + [x + ..., y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10] Modulo any other prime the Groebner basis is trivial so there are no other solutions. For example:: @@ -313,7 +313,7 @@ def is_MPolynomialIdeal(x) -> bool: INPUT: - - ``x`` -- an arbitrary object + - ``x`` -- an arbitrary object EXAMPLES:: @@ -326,6 +326,10 @@ def is_MPolynomialIdeal(x) -> bool: but matches Magma's behavior. :: sage: is_MPolynomialIdeal(I) + doctest:warning... + DeprecationWarning: The function is_MPolynomialIdeal is deprecated; + use 'isinstance(..., MPolynomialIdeal)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. False :: @@ -334,6 +338,10 @@ def is_MPolynomialIdeal(x) -> bool: sage: is_MPolynomialIdeal(I) True """ + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_MPolynomialIdeal is deprecated; " + "use 'isinstance(..., MPolynomialIdeal)' instead.") return isinstance(x, MPolynomialIdeal) @@ -345,7 +353,7 @@ def _magma_init_(self, magma): INPUT: - - ``magma`` -- Magma instance + - ``magma`` -- Magma instance EXAMPLES:: @@ -371,19 +379,17 @@ def _magma_init_(self, magma): @magma_gb_standard_options def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default): """ - Computes a Groebner Basis for this ideal using Magma if + Compute a Groebner Basis for this ideal using Magma if available. INPUT: - ``deg_bound`` -- only compute to degree ``deg_bound``, that - is, ignore all S-polynomials of higher degree. (default: - ``None``) + is, ignore all S-polynomials of higher degree (default: ``None``) - - ``prot`` -- if ``True`` Magma's protocol is printed to - stdout. + - ``prot`` -- if ``True`` Magma's protocol is printed to stdout - - ``magma`` -- Magma instance or None (default instance) (default: None) + - ``magma`` -- Magma instance or ``None`` (default instance) (default: ``None``) EXAMPLES:: @@ -448,7 +454,7 @@ class MPolynomialIdeal_singular_base_repr: @require_field def syzygy_module(self): r""" - Computes the first syzygy (i.e., the module of relations of the + Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal. EXAMPLES:: @@ -476,7 +482,7 @@ def syzygy_module(self): return matrix(self.ring(), S) @libsingular_gb_standard_options - def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds): + def _groebner_basis_libsingular(self, algorithm='groebner', *args, **kwds): """ Return the reduced Groebner basis of this ideal. @@ -487,8 +493,8 @@ def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds): INPUT: - ``algorithm`` -- see below for available algorithms - - ``redsb`` -- (default: ``True``) return a reduced Groebner basis - - ``red_tail`` -- (default: ``True``) perform tail reduction + - ``redsb`` -- boolean (default: ``True``); return a reduced Groebner basis + - ``red_tail`` -- boolean (default: ``True``); perform tail reduction ALGORITHMS: @@ -592,12 +598,11 @@ def _groebner_cover(self): [[1], [1], [[[(2*a + 3)], [[1]]]]]] """ from sage.rings.fraction_field import FractionField_generic - from sage.rings.polynomial.multi_polynomial_ring_base import \ - is_MPolynomialRing - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing + from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general F = self.base_ring() if (not isinstance(F, FractionField_generic) or - (not is_MPolynomialRing(F.ring()) and not is_PolynomialRing(F.ring()))): + not isinstance(F.ring(), (MPolynomialRing_base, PolynomialRing_general))): raise TypeError("the base ring must be a field with parameters") from sage.arith.functions import lcm from sage.libs.singular.function import lib, singular_function @@ -682,10 +687,7 @@ def plot(self, singular=None): INPUT: - - - ``self`` -- must be a principal ideal in 2 or 3 vars - over `\QQ`. - + - ``self`` -- must be a principal ideal in 2 or 3 vars over `\QQ` EXAMPLES: @@ -732,7 +734,7 @@ def plot(self, singular=None): @require_field @cached_method @libsingular_gb_standard_options - def complete_primary_decomposition(self, algorithm="sy"): + def complete_primary_decomposition(self, algorithm='sy'): r""" Return a list of primary ideals such that their intersection is ``self``, together with the associated prime ideals. @@ -759,7 +761,7 @@ def complete_primary_decomposition(self, algorithm="sy"): INPUT: - - ``algorithm`` -- string: + - ``algorithm`` -- string; one of - ``'sy'`` -- (default) use the Shimoyama-Yokoyama algorithm @@ -821,7 +823,6 @@ def complete_primary_decomposition(self, algorithm="sy"): [] sage: I.is_prime() False - """ # Avoid a bug in Singular (see #15745). @@ -872,7 +873,7 @@ def primary_decomposition(self, algorithm='sy'): INPUT: - - ``algorithm`` -- string: + - ``algorithm`` -- string; one of - ``'sy'`` -- (default) use the Shimoyama-Yokoyama algorithm @@ -933,28 +934,26 @@ def associated_primes(self, algorithm='sy'): If `I` is a proper ideal of the ring `R` then there exists a decomposition in primary ideals `Q_i` such that - - their intersection is `I` + - their intersection is `I` - - none of the `Q_i` contains the intersection of the - rest, and + - none of the `Q_i` contains the intersection of the + rest, and - - the associated prime ideals of `Q_i` are pairwise - different. + - the associated prime ideals of `Q_i` are pairwise + different. This method returns the associated primes of the `Q_i`. INPUT: - - - ``algorithm`` -- string: + - ``algorithm`` -- string; one of - ``'sy'`` -- (default) use the Shimoyama-Yokoyama algorithm - ``'gtz'`` -- use the Gianni-Trager-Zacharias algorithm - - OUTPUT: a list of associated primes + OUTPUT: list of associated primes EXAMPLES:: @@ -1041,22 +1040,22 @@ def triangular_decomposition(self, algorithm=None, singular=None): INPUT: - - ``algorithm`` -- string or None (default: None) + - ``algorithm`` -- string or ``None`` (default: ``None``) ALGORITHMS: - - ``"singular:triangL"`` -- decomposition of ``self`` into triangular - systems (Lazard). + - ``'singular:triangL'`` -- decomposition of ``self`` into triangular + systems (Lazard) - - ``"singular:triangLfak"`` -- decomposition of ``self`` into triangular systems - plus factorization. + - ``'singular:triangLfak'`` -- decomposition of ``self`` into triangular systems + plus factorization - - ``"singular:triangM"`` -- decomposition of ``self`` into - triangular systems (Moeller). + - ``'singular:triangM'`` -- decomposition of ``self`` into + triangular systems (Moeller) - OUTPUT: a list `T` of lists `t` such that the variety of + OUTPUT: list `T` of lists `t` such that the variety of ``self`` is the union of the varieties of `t` in `L` and each - `t` is in triangular form. + `t` is in triangular form EXAMPLES:: @@ -1178,10 +1177,16 @@ def dimension(self, singular=None): If the ideal is the total ring, the dimension is `-1` by convention. + ALGORITHM: + + For principal ideals, Theorem 3.5.1 of [Ger2008]_ is used. Otherwise + Singular is used, unless the characteristic is too large. This requires + computation of a Groebner basis, which can be very expensive. + For polynomials over a finite field of order too large for Singular, - this falls back on a toy implementation of Buchberger to compute - the Groebner basis, then uses the algorithm described in Chapter 9, - Section 1 of Cox, Little, and O'Shea's "Ideals, Varieties, and Algorithms". + this falls back on a toy implementation of Buchberger to compute the + Groebner basis, then uses the algorithm described in Chapter 9, Section + 1 of Cox, Little, and O'Shea's "Ideals, Varieties, and Algorithms". EXAMPLES:: @@ -1202,13 +1207,8 @@ def dimension(self, singular=None): sage: R. = PolynomialRing(GF(2147483659^2), order='lex') sage: I = R.ideal(0) sage: I.dimension() - verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. 2 - ALGORITHM: - - Uses Singular, unless the characteristic is too large. - TESTS: Check that this method works over QQbar (:issue:`25351`):: @@ -1217,16 +1217,21 @@ def dimension(self, singular=None): sage: I = ideal(x^2-y, x^3-QQbar(-1)) # needs sage.rings.number_field sage: I.dimension() # needs sage.rings.number_field 1 - - .. NOTE:: - - Requires computation of a Groebner basis, which can be a - very expensive operation. - """ try: return self.__dimension except AttributeError: + if not self.base_ring().is_field(): + raise NotImplementedError("implemented only over fields") + if self.ngens() == 1: + g = self.gen(0) + if g.is_unit(): + self.__dimension = Integer(-1) + elif g: + self.__dimension = Integer(self.ring().ngens() - 1) + else: + self.__dimension = Integer(self.ring().ngens()) + return self.__dimension try: from sage.libs.singular.function_factory import ff dim = ff.dim @@ -1237,57 +1242,55 @@ def dimension(self, singular=None): v = self._groebner_basis_singular_raw() self.__dimension = Integer(v.dim()) except TypeError: - if not self.base_ring().is_field(): - raise NotImplementedError("dimension() is implemented only over fields.") - if self.ring().term_order().is_global(): - verbose("Warning: falling back to very slow toy implementation.", level=0) - # See Chapter 9, Section 1 of Cox, Little, O'Shea's "Ideals, Varieties, - # and Algorithms". - from sage.sets.set import Set - gb = toy_buchberger.buchberger_improved(self) - if self.ring().one() in gb: - return Integer(-1) - ring_vars = self.ring().gens() - n = len(ring_vars) - lms = [each.lm() for each in gb] - # compute M_j, denoted by var_lms - var_lms = [Set([]) for _ in lms] - for j in range(len(ring_vars)): - for i in range(len(lms)): - if lms[i].degree(ring_vars[j]) > 0: - var_lms[i] += Set([j+1]) - # compute intersections of M_j and J - # we assume that the iterator starts with the empty set, - # then iterates through all subsets of order 1, - # then through all subsets of order 2, etc... - # the way Sage currently operates - all_J = Set([each + 1 for each in range(n)]).subsets() - min_dimension = -1 - all_J = iter(all_J) - while min_dimension == -1: - try: - J = next(all_J) - except StopIteration: - min_dimension = n - break - J_intersects_all = True - i = 0 - while J_intersects_all and i < len(var_lms): - J_intersects_all = J.intersection(var_lms[i]) != Set([]) - i += 1 - if J_intersects_all: - min_dimension = len(J) - return Integer(n - min_dimension) - else: - raise TypeError("Local/unknown orderings not supported by 'toy_buchberger' implementation.") - return self.__dimension + verbose("Warning: falling back to very slow toy implementation.", level=0) + if not self.ring().term_order().is_global(): + raise TypeError("local/unknown ordering is not supported by the toy implementation") + # See Chapter 9, Section 1 of Cox, Little, O'Shea's + # "Ideals, Varieties, and Algorithms" + from sage.sets.set import Set + gb = toy_buchberger.buchberger_improved(self) + if self.ring().one() in gb: + self.__dimension = Integer(-1) + return self.__dimension + ring_vars = self.ring().gens() + n = len(ring_vars) + lms = [each.lm() for each in gb] + # compute M_j, denoted by var_lms + var_lms = [Set([]) for _ in lms] + for j in range(len(ring_vars)): + for i in range(len(lms)): + if lms[i].degree(ring_vars[j]) > 0: + var_lms[i] += Set([j+1]) + # compute intersections of M_j and J + # we assume that the iterator starts with the empty set, + # then iterates through all subsets of order 1, + # then through all subsets of order 2, etc... + # the way Sage currently operates + all_J = Set([each + 1 for each in range(n)]).subsets() + min_dimension = -1 + all_J = iter(all_J) + while min_dimension == -1: + try: + J = next(all_J) + except StopIteration: + min_dimension = n + break + J_intersects_all = True + i = 0 + while J_intersects_all and i < len(var_lms): + J_intersects_all = J.intersection(var_lms[i]) != Set([]) + i += 1 + if J_intersects_all: + min_dimension = len(J) + self.__dimension = Integer(n - min_dimension) + return self.__dimension @require_field @handle_AA_and_QQbar def vector_space_dimension(self): """ Return the vector space dimension of the ring modulo this ideal. If - the ideal is not zero-dimensional, a :class:`TypeError` is raised. + the ideal is not zero-dimensional, a :exc:`TypeError` is raised. ALGORITHM: @@ -1329,7 +1332,6 @@ def vector_space_dimension(self): 0 sage: I.vector_space_dimension() 3 - """ R = self.ring() gb = R.ideal(self.groebner_basis()) @@ -1345,18 +1347,19 @@ def vector_space_dimension(self): return vd @require_field - def _groebner_basis_ginv(self, algorithm="TQ", criteria='CritPartially', division_interface="Janet"): + def _groebner_basis_ginv(self, algorithm='TQ', criteria='CritPartially', division_interface='Janet'): r""" Compute a Groebner basis using GINV. INPUT: - - ``algorithm`` -- "TQ", "TQBlockHigh", "TQBlockLow" or "TQDegree" - - ``criteria`` -- "Without" (without any criteria) - -- "C1", "CritPartially" (partial involutive criteria) - -- "C1C2C3", "C1C2C3C4" (full involutive criteria) + - ``algorithm`` -- ``'TQ'``, ``'TQBlockHigh'``, ``'TQBlockLow'``, or + ``'TQDegree'`` + - ``criteria`` -- ``'Without'`` (without any criteria), + ``'C1'``, ``'CritPartially'`` (partial involutive criteria), + ``'C1C2C3'``, ``'C1C2C3C4'`` (full involutive criteria) - - ``division_interface`` -- either "Janet" or "JanetLike" + - ``division_interface`` -- either ``'Janet'`` or ``'JanetLike'`` EXAMPLES: @@ -1413,7 +1416,7 @@ def _groebner_basis_ginv(self, algorithm="TQ", criteria='CritPartially', divisio return G @singular_gb_standard_options - def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds): + def _groebner_basis_singular(self, algorithm='groebner', *args, **kwds): """ Return the reduced Groebner basis of this ideal. If the Groebner basis for this ideal has been calculated before, the @@ -1422,8 +1425,7 @@ def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds): INPUT: - - ``algorithm`` -- see below for available algorithms - + - ``algorithm`` -- see below for available algorithms ALGORITHMS: @@ -1480,7 +1482,7 @@ def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds): return S @cached_method - def _groebner_basis_singular_raw(self, algorithm="groebner", singular=None, *args, **kwds): + def _groebner_basis_singular_raw(self, algorithm='groebner', singular=None, *args, **kwds): r""" Return a Groebner basis in Singular format. @@ -1710,9 +1712,7 @@ def intersection(self, *others): @libsingular_gb_standard_options def minimal_associated_primes(self): """ - OUTPUT: - - - ``list`` -- a list of prime ideals + OUTPUT: list of prime ideals EXAMPLES:: @@ -1837,7 +1837,7 @@ def integral_closure(self, p=0, r=True, singular=None): @handle_AA_and_QQbar def syzygy_module(self): r""" - Computes the first syzygy (i.e., the module of relations of the + Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal. EXAMPLES:: @@ -1980,7 +1980,6 @@ def interreduced_basis(self): - `LC(g_i) = 1` for all `i` if the coefficient ring is a field. - EXAMPLES:: sage: R. = PolynomialRing(QQ) @@ -2174,13 +2173,13 @@ def basis_is_groebner(self, singular=None): @handle_AA_and_QQbar @singular_gb_standard_options @libsingular_gb_standard_options - def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=None): + def transformed_basis(self, algorithm='gwalk', other_ring=None, singular=None): """ Return a lex or ``other_ring`` Groebner Basis for this ideal. INPUT: - - ``algorithm`` -- see below for options. + - ``algorithm`` -- see below for options - ``other_ring`` -- only valid for ``algorithm='fglm'``; if provided, conversion will be performed to this @@ -2189,18 +2188,18 @@ def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=None): ALGORITHMS: - - ``"fglm"`` -- FGLM algorithm. The input ideal must be given with a reduced + - ``'fglm'`` -- FGLM algorithm. The input ideal must be given with a reduced Groebner Basis of a zero-dimensional ideal - - ``"gwalk"`` -- Groebner Walk algorithm (*default*) + - ``'gwalk'`` -- Groebner Walk algorithm (*default*) - - ``"awalk1"`` -- 'first alternative' algorithm + - ``'awalk1'`` -- 'first alternative' algorithm - - ``"awalk2"`` -- 'second alternative' algorithm + - ``'awalk2'`` -- 'second alternative' algorithm - - ``"twalk"`` -- Tran algorithm + - ``'twalk'`` -- Tran algorithm - - ``"fwalk"`` -- Fractal Walk algorithm + - ``'fwalk'`` -- Fractal Walk algorithm EXAMPLES:: @@ -2287,10 +2286,10 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): INPUT: - - ``variables`` -- a list or tuple of variables in ``self.ring()`` + - ``variables`` -- list or tuple of variables in ``self.ring()`` - ``algorithm`` -- determines the algorithm to use, see below - for available algorithms. + for available algorithms ALGORITHMS: @@ -2312,7 +2311,8 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): You can use Giac to compute the elimination ideal:: - sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm="giac") == J + sage: # needs sage.libs.giac + sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm='giac') == J possible output... True @@ -2332,13 +2332,13 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): Check that this method works over QQbar (:issue:`25351`):: - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.libs.giac sage: R. = QQbar[] sage: I = R * [x - t, y - t^2, z - t^3, s - x + y^3] sage: J = I.elimination_ideal([t, s]); J Ideal (y^2 - x*z, x*y - z, x^2 - y) of Multivariate Polynomial Ring in x, y, t, s, z over Algebraic Field - sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm="giac") == J + sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm='giac') == J possible output... True @@ -2404,7 +2404,7 @@ def quotient(self, J): INPUT: - - ``J`` -- multivariate polynomial ideal + - ``J`` -- multivariate polynomial ideal EXAMPLES:: @@ -2467,7 +2467,8 @@ def quotient(self, J): @handle_AA_and_QQbar def saturation(self, other): r""" - Return the saturation (and saturation exponent) of the ideal ``self`` with respect to the ideal ``other`` + Return the saturation (and saturation exponent) of the ideal ``self`` + with respect to the ideal ``other``. INPUT: @@ -2506,7 +2507,7 @@ def saturation(self, other): return (R.ideal(ideal), ZZ(expo)) @require_field - def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True): + def variety(self, ring=None, *, algorithm='triangular_decomposition', proof=True): r""" Return the variety of this ideal. @@ -2690,11 +2691,11 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True ALGORITHM: - - With ``algorithm`` = ``"triangular_decomposition"`` (default), + - With ``algorithm`` = ``'triangular_decomposition'`` (default), uses triangular decomposition, via Singular if possible, falling back on a toy implementation otherwise. - - With ``algorithm`` = ``"msolve"``, uses the + - With ``algorithm`` = ``'msolve'``, uses the :ref:`optional package msolve `. Note that msolve uses heuristics and therefore requires setting the ``proof`` flag to ``False``. See @@ -2815,7 +2816,6 @@ def _variety_triangular_decomposition(self, ring): sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) sage: len(I.variety()) 4 - """ def _variety(T, V, v=None): @@ -2854,7 +2854,7 @@ def _variety(T, V, v=None): return [] if isinstance(self.base_ring(), sage.rings.abc.ComplexField): - verbose("Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.", level=0, caller_name="variety") + verbose("Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.", level=0, caller_name='variety') P = self.ring() if ring is not None: P = P.change_ring(ring) @@ -2863,7 +2863,7 @@ def _variety(T, V, v=None): T = [list(each.gens()) for each in TI] except TypeError: # conversion to Singular not supported if self.ring().term_order().is_global(): - verbose("Warning: falling back to very slow toy implementation.", level=0, caller_name="variety") + verbose("Warning: falling back to very slow toy implementation.", level=0, caller_name='variety') T = toy_variety.triangular_factorization(self.groebner_basis()) else: raise TypeError("Local/unknown orderings not supported by 'toy_buchberger' implementation.") @@ -3185,7 +3185,6 @@ def hilbert_numerator(self, grading=None, algorithm='sage'): sage: n2 = I.hilbert_numerator(algorithm='singular') sage: n1 == n2 True - """ if not self.is_homogeneous(): raise TypeError("Ideal must be homogeneous.") @@ -3295,12 +3294,12 @@ def normal_basis(self, degree=None, algorithm='libsingular', - ``degree`` -- integer (default: ``None``) - - ``algorithm`` -- string (default: ``"libsingular"``); if not the + - ``algorithm`` -- string (default: ``'libsingular'``); if not the default, this will use the ``kbase()`` or ``weightKB()`` command from Singular - ``singular`` -- the singular interpreter to use when ``algorithm`` is - not ``"libsingular"`` (default: the default instance) + not ``'libsingular'`` (default: the default instance) OUTPUT: @@ -3413,7 +3412,7 @@ def _groebner_basis_macaulay2(self, strategy=None): INPUT: - ``strategy`` -- (default: ``'gb'``) argument specifying the strategy - to be used by Macaulay2; possibilities: ``'f4'``, ``'gb'``, ``'mgb'``. + to be used by Macaulay2; possibilities: ``'f4'``, ``'gb'``, ``'mgb'`` EXAMPLES:: @@ -3495,19 +3494,18 @@ def _reduce_using_macaulay2(self, f): return R(k) class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc): - def __init__(self, ring, gens, coerce=True, side="left"): + def __init__(self, ring, gens, coerce=True, side='left'): r""" - Creates a non-commutative polynomial ideal. + Create a non-commutative polynomial ideal. INPUT: - - ``ring`` - the g-algebra to which this ideal belongs - - ``gens`` - the generators of this ideal - - ``coerce`` (optional - default: ``True``) - generators are + - ``ring`` -- the g-algebra to which this ideal belongs + - ``gens`` -- the generators of this ideal + - ``coerce`` -- boolean (default: ``True``); generators are coerced into the ring before creating the ideal - - ``side`` -- optional string, either ``"left"`` (default) - or ``"twosided"``; defines whether this ideal is left - of two-sided. + - ``side`` -- (optional) string; either ``'left'`` (default) + or ``'twosided'``. Defines whether this ideal is left or two-sided. EXAMPLES:: @@ -3524,18 +3522,17 @@ def __init__(self, ring, gens, coerce=True, side="left"): nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} sage: sorted(I.gens(), key=str) [x^2, y^2, z^2 - 1] - sage: H.ideal([y^2, x^2, z^2 - H.one()], side="twosided") # random + sage: H.ideal([y^2, x^2, z^2 - H.one()], side='twosided') # random Twosided Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(H.ideal([y^2, x^2, z^2 - H.one()], side="twosided").gens(), + sage: sorted(H.ideal([y^2, x^2, z^2 - H.one()], side='twosided').gens(), ....: key=str) [x^2, y^2, z^2 - 1] - sage: H.ideal([y^2, x^2, z^2 - H.one()], side="right") + sage: H.ideal([y^2, x^2, z^2 - H.one()], side='right') Traceback (most recent call last): ... ValueError: Only left and two-sided ideals are allowed. - """ if side == "right": raise ValueError("Only left and two-sided ideals are allowed.") @@ -3548,11 +3545,9 @@ def __call_singular(self, cmd, arg=None): INPUT: - ``cmd`` - string, representing a Singular function - - ``arg`` (Default: None) - arguments for which cmd is called + - ``arg`` -- (default: ``None``) arguments for which cmd is called - OUTPUT: - - - result of the Singular function call + OUTPUT: result of the Singular function call EXAMPLES:: @@ -3761,7 +3756,6 @@ def reduce(self,p): sage: I.reduce(z^2) # needs sage.combinat sage.modules 1 - """ return self._groebner_strategy().normal_form(p) @@ -3793,7 +3787,6 @@ def _contains_(self,p): False sage: x*y^2-y*z in JT # needs sage.combinat sage.modules True - """ return self.reduce(p).is_zero() @@ -3894,7 +3887,7 @@ def __init__(self, ring, gens, coerce=True): - ``ring`` -- the ring the ideal is defined in - - ``gens`` -- a list of generators for the ideal + - ``gens`` -- list of generators for the ideal - ``coerce`` -- whether to coerce elements to the ring ``ring`` @@ -3912,7 +3905,7 @@ def __init__(self, ring, gens, coerce=True): def __hash__(self): r""" - Stupid constant hash function! + Stupid constant hash function. TESTS:: @@ -3951,7 +3944,6 @@ def basis(self): sage: I = Ideal([x, y + 1]) sage: I.basis [x, y + 1] - """ return self.gens() @@ -3963,15 +3955,13 @@ def __richcmp__(self, other, op): - ``other`` -- a polynomial ideal - OUTPUT: - - boolean + OUTPUT: boolean ALGORITHM: Comparison for ``==`` and ``!=`` compares two Groebner bases. - Comparison for ``<=` and ``>=`` tests the inclusion of ideals + Comparison for ``<=`` and ``>=`` tests the inclusion of ideals using the usual ideal membership test, namely all generators of one ideal must reduce to zero in the other ideal's Groebner basis. @@ -4143,7 +4133,7 @@ def __richcmp__(self, other, op): o, r = next(iter(other_new._gb_by_ordering.items())) l = self.change_ring(R.change_ring(order=o)).gens() else: # use easy GB otherwise - newR = R.change_ring(order="degrevlex") + newR = R.change_ring(order='degrevlex') l = self.change_ring(newR).gens() r = other_new.change_ring(newR).groebner_basis() # remember this Groebner basis for future reference @@ -4162,7 +4152,7 @@ def __richcmp__(self, other, op): l = self.groebner_basis() r = other_new.groebner_basis() else: # use easy GB otherwise - newR = R.change_ring(order="degrevlex") + newR = R.change_ring(order='degrevlex') l = self.change_ring(newR).groebner_basis() r = other_new.change_ring(newR).groebner_basis() except AttributeError: # e.g. quotient rings @@ -4194,16 +4184,15 @@ def groebner_fan(self, is_groebner_basis=False, symmetry=None, verbose=False): INPUT: + - ``is_groebner_basis`` -- boolean (default: ``False``); if + ``True``, then ``I.gens()`` must be a Groebner basis with respect to + the standard degree lexicographic term order - - ``is_groebner_basis`` -- bool (default: ``False``). if - True, then I.gens() must be a Groebner basis with respect to the - standard degree lexicographic term order. - - - ``symmetry`` -- default: None; if not None, describes - symmetries of the ideal + - ``symmetry`` -- (default: ``None``) if not ``None``, describes + symmetries of the ideal - - ``verbose`` -- default: ``False``; if True, printout - useful info during computations + - ``verbose`` -- (default: ``False``) if ``True``, printout + useful info during computations """ import sage.rings.polynomial.groebner_fan as groebner_fan return groebner_fan.GroebnerFan(self, is_groebner_basis=is_groebner_basis, @@ -4229,7 +4218,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal INPUT: - ``algorithm`` -- determines the algorithm to use, see below - for available algorithms. + for available algorithms - ``deg_bound`` -- only compute to degree ``deg_bound``, that is, ignore all S-polynomials of higher degree. (default: @@ -4378,12 +4367,12 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal reverse lexicographical ordering here, in order to test against :issue:`21884`:: + sage: # needs sage.libs.giac sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: J = I.change_ring(P.change_ring(order='degrevlex')) sage: gb = J.groebner_basis('giac') # random sage: gb [c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1] - sage: J.groebner_basis.set_cache(gb) sage: ideal(J.transformed_basis()).change_ring(P).interreduced_basis() # testing issue #21884 ...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] @@ -4391,6 +4380,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Giac's gbasis over `\QQ` can benefit from a probabilistic lifting and multi threaded operations:: + sage: # needs sage.libs.giac sage: A9 = PolynomialRing(QQ, 9, 'x') sage: I9 = sage.rings.ideal.Katsura(A9) sage: print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=1e-7) # long time (3s) @@ -4642,7 +4632,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal sage: I.groebner_basis('libsingular:slimgb') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.libs.giac sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: J = I.change_ring(P.change_ring(order='degrevlex')) sage: gb = J.groebner_basis('giac') # random @@ -4832,15 +4822,12 @@ def groebner_cover(self): def change_ring(self, P): r""" - Return the ideal ``I`` in ``P`` spanned by - the generators `g_1, ..., g_n` of self as returned by - ``self.gens()``. + Return the ideal ``I`` in ``P`` spanned by the generators + `g_1, ..., g_n` of ``self`` as returned by ``self.gens()``. INPUT: - - - ``P`` -- a multivariate polynomial ring - + - ``P`` -- a multivariate polynomial ring EXAMPLES:: @@ -4892,7 +4879,7 @@ def subs(self, in_dict=None, **kwds): OUTPUT: A new ideal with modified generators. If possible, in the same - polynomial ring. Raises a :class:`TypeError` if no common + polynomial ring. Raises a :exc:`TypeError` if no common polynomial ring of the substituted generators can be found. EXAMPLES:: @@ -5016,10 +5003,7 @@ def homogenize(self, var='h'): INPUT: - - - ``h`` -- variable name or variable in cover ring - (default: 'h') - + - ``h`` -- variable name or variable in cover ring (default: ``'h'``) EXAMPLES:: @@ -5111,7 +5095,7 @@ def degree_of_semi_regularity(self): The degree of regularity of a semi-regular sequence `f_1, ...,f_m` of respective degrees `d_1,...,d_m` is given by the - index of the first non-positive coefficient of: + index of the first nonpositive coefficient of: `\sum c_k z^k = \frac{\prod (1 - z^{d_i})}{(1-z)^n}` @@ -5199,9 +5183,9 @@ def plot(self, *args, **kwds): - ``self`` -- a principal ideal in 2 variables - ``algorithm`` -- set this to 'surf' if you want 'surf' to - plot the ideal (default: None) + plot the ideal (default: ``None``) - - ``*args`` -- optional tuples ``(variable, minimum, maximum)`` + - ``*args`` -- (optional) tuples ``(variable, minimum, maximum)`` for plotting dimensions - ``**kwds`` -- optional keyword arguments passed on to @@ -5253,7 +5237,6 @@ def plot(self, *args, **kwds): sage: I = R.ideal([-x^2*y + 1]) sage: I.plot() # blow up # needs sage.plot Graphics object consisting of 1 graphics primitive - """ from sage.plot.all import implicit_plot from sage.rings.real_mpfr import RR @@ -5394,7 +5377,6 @@ def random_element(self, degree, compute_gb=False, *args, **kwds): sage: set_random_seed(5) sage: I.random_element(degree=2) -2*x^2 + 2*y^2 - """ if compute_gb: gens = self.groebner_basis() @@ -5684,9 +5666,7 @@ def __richcmp__(self, other, op): - ``other`` -- an ideal in a quotient of a polynomial ring - OUTPUT: - - boolean + OUTPUT: boolean TESTS:: diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx index 14820418454..70b1b3fdcf1 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx @@ -69,8 +69,8 @@ from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_ cdef object singular_ideal_to_sage_sequence(ideal *i, ring *r, object parent): """ - convert a SINGULAR ideal to a Sage Sequence (the format Sage - stores a Groebner basis in) + Convert a SINGULAR ideal to a Sage Sequence (the format Sage + stores a Groebner basis in). INPUT: @@ -102,7 +102,8 @@ cdef ideal *sage_ideal_to_singular_ideal(I) except NULL: INPUT: - ``I`` -- a Sage ideal in a ring of type - :class:`~sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular` or a list of generators. + :class:`~sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular` + or a list of generators TESTS: @@ -145,6 +146,7 @@ cdef ideal *sage_ideal_to_singular_ideal(I) except NULL: raise TypeError("All generators must be of type MPolynomial_libsingular.") return i + def kbase_libsingular(I, degree=None): """ SINGULAR's ``kbase()`` algorithm. @@ -201,6 +203,7 @@ def kbase_libsingular(I, degree=None): return res + def std_libsingular(I): """ SINGULAR's ``std()`` algorithm. @@ -224,7 +227,6 @@ def std_libsingular(I): idSkipZeroes(result) - id_Delete(&i,r) res = singular_ideal_to_sage_sequence(result,r,I.ring()) @@ -251,7 +253,7 @@ def slimgb_libsingular(I): i = sage_ideal_to_singular_ideal(I) r = currRing - if r.OrdSgn!=1 : + if r.OrdSgn != 1: id_Delete(&i, r) raise TypeError("ordering must be global for slimgb") @@ -265,13 +267,14 @@ def slimgb_libsingular(I): result = t_rep_gb(r, i, i.rank, 0) sig_off() - id_Delete(&i,r) + id_Delete(&i, r) - res = singular_ideal_to_sage_sequence(result,r,I.ring()) + res = singular_ideal_to_sage_sequence(result, r, I.ring()) - id_Delete(&result,r) + id_Delete(&result, r) return res + def interred_libsingular(I): """ SINGULAR's ``interred()`` command. @@ -318,21 +321,20 @@ def interred_libsingular(I): sig_off() singular_options = bck - # divide head by coefficients - if r.cf.type != n_Z and r.cf.type != n_Znm and r.cf.type != n_Zn and r.cf.type != n_Z2m : + if r.cf.type != n_Z and r.cf.type != n_Znm and r.cf.type != n_Zn and r.cf.type != n_Z2m: for j from 0 <= j < IDELEMS(result): p = result.m[j] if p: - n = p_GetCoeff(p,r) - n = r.cf.cfInvers(n,r.cf) + n = p_GetCoeff(p, r) + n = r.cf.cfInvers(n, r.cf) result.m[j] = pp_Mult_nn(p, n, r) - p_Delete(&p,r) - n_Delete(&n,r.cf) + p_Delete(&p, r) + n_Delete(&n, r.cf) - id_Delete(&i,r) + id_Delete(&i, r) res = sorted(singular_ideal_to_sage_sequence(result,r,I.ring()),reverse=True) - id_Delete(&result,r) + id_Delete(&result, r) return res diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 6b838190c52..d05760d84cd 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -109,7 +109,7 @@ TESTS:: sage: loads(dumps(x)) == x True - sage: Rt. = PolynomialRing(QQ, implementation="singular") + sage: Rt. = PolynomialRing(QQ, implementation='singular') sage: p = 1+t sage: R. = PolynomialRing(QQ, 2) sage: p(u/v) @@ -218,7 +218,7 @@ from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRi from sage.rings.polynomial.multi_polynomial_element import MPolynomial_polydict from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.rings.polynomial.polydict cimport ETuple -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general # base ring imports import sage.rings.abc @@ -390,7 +390,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): def __dealloc__(self): r""" - Deallocate the ring without changing ``currRing`` + Deallocate the ring without changing ``currRing``. TESTS: @@ -480,7 +480,6 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Coercion map: From: Univariate Polynomial Ring in x over Integer Ring To: Multivariate Polynomial Ring in x, y over Rational Field - """ base_ring = self.base_ring() if other is base_ring: @@ -509,7 +508,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): return True elif base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())): return True - elif is_PolynomialRing(other): + elif isinstance(other, PolynomialRing_general): if base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())): return True @@ -528,7 +527,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P. = QQ[] - We can coerce elements of self to self:: + We can coerce elements of ``self`` to ``self``:: sage: P.coerce(x*y + 1/2) x*y + 1/2 @@ -856,7 +855,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): if element.parent() == self: bucket = sBucketCreate(_ring) try: - for (m,c) in element.element().dict().iteritems(): + for m, c in element.element().dict().items(): mon = p_Init(_ring) p_SetCoeff(mon, sa2si(c, _ring), _ring) for pos in m.nonzero_positions(): @@ -894,13 +893,13 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): if element.parent().ngens() <= self.ngens(): bucket = sBucketCreate(_ring) try: - for (m,c) in element.element().dict().iteritems(): + for m, c in element.element().dict().items(): if check: c = base_ring(c) if not c: continue mon = p_Init(_ring) - p_SetCoeff(mon, sa2si(c , _ring), _ring) + p_SetCoeff(mon, sa2si(c, _ring), _ring) for pos in m.nonzero_positions(): overflow_check(m[pos], _ring) p_SetExp(mon, ind_map[pos], m[pos], _ring) @@ -924,13 +923,13 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): else: bucket = sBucketCreate(_ring) try: - for (m,c) in element.iteritems(): + for m, c in element.items(): if check: c = base_ring(c) if not c: continue mon = p_Init(_ring) - p_SetCoeff(mon, sa2si(c , _ring), _ring) + p_SetCoeff(mon, sa2si(c, _ring), _ring) if len(m) != self.ngens(): raise TypeError("tuple key must have same length as ngens") for pos from 0 <= pos < len(m): @@ -1022,7 +1021,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): def ngens(self): """ - Returns the number of variables in this multivariate polynomial ring. + Return the number of variables in this multivariate polynomial ring. EXAMPLES:: @@ -1039,12 +1038,12 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): def gen(self, int n=0): """ - Returns the ``n``-th generator of this multivariate polynomial + Return the ``n``-th generator of this multivariate polynomial ring. INPUT: - - ``n`` -- an integer ``>= 0`` + - ``n`` -- nonnegative integer EXAMPLES:: @@ -1081,7 +1080,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): - ``*gens`` -- list or tuple of generators (or several input arguments) - - ``coerce`` -- bool (default: ``True``); this must be a + - ``coerce`` -- boolean (default: ``True``); this must be a keyword argument. Only set it to ``False`` if you are certain that each generator is already in the ring. @@ -1099,8 +1098,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): coerce = kwds.get('coerce', True) if len(gens) == 1: gens = gens[0] - from sage.rings.ideal import is_Ideal - if is_Ideal(gens): + from sage.rings.ideal import Ideal_generic + if isinstance(gens, Ideal_generic): if gens.ring() is self: return gens gens = gens.gens() @@ -1370,7 +1369,6 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 1 : ordering lp // : names x // block 2 : ordering C - """ if singular is None: from sage.interfaces.singular import singular @@ -1461,7 +1459,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): def __reduce__(self): """ - Serializes self. + Serialize ``self``. EXAMPLES:: @@ -1618,7 +1616,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): res = pMDivide(f._poly, g._poly) if coeff: if r.cf.type == n_unknown or r.cf.cfDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r), r.cf): - n = r.cf.cfDiv( p_GetCoeff(f._poly, r) , p_GetCoeff(g._poly, r), r.cf) + n = r.cf.cfDiv(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r), r.cf) p_SetCoeff0(res, n, r) else: raise ArithmeticError("Cannot divide these coefficients.") @@ -1851,9 +1849,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): - ``t`` -- a monomial - OUTPUT: - a list of monomials - + OUTPUT: list of monomials EXAMPLES:: @@ -1877,9 +1873,10 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): M.append(new_MP(self, p_Copy(tempvector, _ring))) return M + def unpickle_MPolynomialRing_libsingular(base_ring, names, term_order): """ - inverse function for ``MPolynomialRing_libsingular.__reduce__`` + Inverse function for ``MPolynomialRing_libsingular.__reduce__``. EXAMPLES:: @@ -1926,9 +1923,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ Copy ``self``. - OUTPUT: - - A copy. + OUTPUT: a copy EXAMPLES:: @@ -1954,7 +1949,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def __deepcopy__(self, memo={}): """ - Deep copy ``self`` + Deep copy ``self``. TESTS:: @@ -1997,12 +1992,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Evaluate this multi-variate polynomial at ``x``, where ``x`` is either the tuple of values to substitute in, or one can use functional notation ``f(a_0,a_1,a_2, \ldots)`` to evaluate - ``f`` with the ith variable replaced by ``a_i``. + ``f`` with the ``i``-th variable replaced by ``a_i``. INPUT: - - ``x`` -- a list of elements in ``self.parent()`` - - or ``**kwds`` -- a dictionary of ``variable-name:value`` pairs. + - ``x`` -- list of elements in ``self.parent()`` + - or ``**kwds`` -- dictionary of ``variable-name:value`` pairs EXAMPLES:: @@ -2093,10 +2088,11 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): except TypeError: # give up, evaluate functional sage_res = parent.base_ring().zero() - for m, c in self.dict().iteritems(): + for m, c in self.monomial_coefficients().items(): sage_res += c * mul([x[i] ** m[i] for i in m.nonzero_positions()]) else: - singular_polynomial_call(&res, self._poly, _ring, coerced_x, MPolynomial_libsingular_get_element) + singular_polynomial_call(&res, self._poly, _ring, coerced_x, + MPolynomial_libsingular_get_element) if res == NULL: return res_parent(0) @@ -2226,7 +2222,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cpdef _lmul_(self, Element left): """ - Multiply self with a base ring element. + Multiply ``self`` with a base ring element. EXAMPLES:: @@ -2274,7 +2270,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cpdef _div_(left, right_ringelement): r""" - Divide left by right + Divide ``left`` by ``right``. EXAMPLES:: @@ -2336,7 +2332,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Ensure that :issue:`17638` is fixed:: - sage: R. = PolynomialRing(QQ, order="neglex") + sage: R. = PolynomialRing(QQ, order='neglex') sage: f = 1 + y sage: g = 1 + x sage: h = f/g @@ -2355,7 +2351,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): else: return (left._parent).fraction_field()(left,right_ringelement) - def __pow__(MPolynomial_libsingular self, exp, ignored): + def __pow__(MPolynomial_libsingular self, exp, mod): """ Return ``self**(exp)``. @@ -2418,7 +2414,20 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... TypeError: R is neither an integer nor a rational + + Check that using third argument raises an error:: + + sage: R. = PolynomialRing(ZZ) + sage: pow(x + y + z, 2, x) + Traceback (most recent call last): + ... + NotImplementedError: pow() with a modulus is not implemented for this ring """ + if mod is not None: + raise NotImplementedError( + "pow() with a modulus is not implemented for this ring" + ) + if type(exp) is not Integer: try: exp = Integer(exp) @@ -2678,7 +2687,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: type(f.degree(y)) - """ cdef ring *r = self._parent_ring cdef poly *p = self._poly @@ -2770,7 +2778,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def degrees(self): """ - Returns a tuple with the maximal degree of each variable in + Return a tuple with the maximal degree of each variable in this polynomial. The list of degrees is ordered by the order of the generators. @@ -2820,12 +2828,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``degrees`` -- Can be any of: + - ``degrees`` -- can be any of: - a dictionary of degree restrictions - a list of degree restrictions (with ``None`` in the unrestricted variables) - a monomial (very fast, but not as flexible) - OUTPUT: element of the parent of this element. + OUTPUT: element of the parent of this element .. NOTE:: @@ -2936,7 +2944,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def monomial_coefficient(self, MPolynomial_libsingular mon): """ Return the coefficient in the base ring of the monomial mon in - ``self``, where mon must have the same parent as self. + ``self``, where mon must have the same parent as ``self``. This function contrasts with the function ``coefficient`` which returns the coefficient of a monomial viewing this @@ -2947,9 +2955,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): - ``mon`` -- a monomial - OUTPUT: - - coefficient in base ring + OUTPUT: coefficient in base ring .. SEEALSO:: @@ -2991,16 +2997,21 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): return self._parent._base._zero_element - def dict(self): + def monomial_coefficients(self): """ - Return a dictionary representing self. This dictionary is in + Return a dictionary representing ``self``. This dictionary is in the same format as the generic MPolynomial: The dictionary consists of ``ETuple:coefficient`` pairs. EXAMPLES:: sage: R. = QQ[] - sage: f=2*x*y^3*z^2 + 1/7*x^2 + 2/3 + sage: f = 2*x*y^3*z^2 + 1/7*x^2 + 2/3 + sage: f.monomial_coefficients() + {(0, 0, 0): 2/3, (1, 3, 2): 2, (2, 0, 0): 1/7} + + ``dict`` is an alias:: + sage: f.dict() {(0, 0, 0): 2/3, (1, 3, 2): 2, (2, 0, 0): 1/7} """ @@ -3024,14 +3035,16 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): p = pNext(p) return pd + dict = monomial_coefficients + def iterator_exp_coeff(self, as_ETuples=True): """ Iterate over ``self`` as pairs of ((E)Tuple, coefficient). INPUT: - - ``as_ETuples`` -- (default: ``True``) if ``True`` iterate over - pairs whose first element is an ETuple, otherwise as a tuples + - ``as_ETuples`` -- boolean (default: ``True``); if ``True`` iterate + over pairs whose first element is an ETuple, otherwise as a tuples EXAMPLES:: @@ -3071,7 +3084,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cpdef long number_of_terms(self) noexcept: """ - Return the number of non-zero coefficients of this polynomial. + Return the number of nonzero coefficients of this polynomial. This is also called weight, :meth:`hamming_weight` or sparsity. @@ -3139,8 +3152,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``x`` -- a tuple or, in case of a single-variable MPolynomial - ring x can also be an integer. + - ``x`` -- tuple or, in case of a single-variable MPolynomial + ring x can also be an integer EXAMPLES:: @@ -3153,7 +3166,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f[0,1] 0 - sage: R. = PolynomialRing(GF(7), implementation="singular"); R + sage: R. = PolynomialRing(GF(7), implementation='singular'); R Multivariate Polynomial Ring in x over Finite Field of size 7 sage: f = 5*x^2 + 3; f -2*x^2 + 3 @@ -3197,7 +3210,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ Facilitates iterating over the monomials of self, returning tuples of the form ``(coeff, mon)`` for each - non-zero monomial. + nonzero monomial. EXAMPLES:: @@ -3236,8 +3249,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``as_ETuples`` -- (default: ``True``) if ``True`` returns the - result as a list of ETuples, otherwise returns a list of tuples + - ``as_ETuples`` -- boolean (default: ``True``); if ``True`` returns + the result as a list of ETuples, otherwise returns a list of tuples EXAMPLES:: @@ -3329,11 +3342,10 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``var`` -- an integer indicating which variable to use to + - ``var`` -- integer indicating which variable to use to homogenize (``0 <= var < parent(self).ngens()``) - OUTPUT: - a multivariate polynomial + OUTPUT: a multivariate polynomial EXAMPLES:: @@ -3554,7 +3566,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): (c + d)*z^2 sage: f.subs({z:x+1}) c*x^2*y + d*x^2 + (2*c)*x*y + (2*d)*x + c*y + d - """ cdef int mi, i cdef bint change_ring = False # indicates the need to change the parent ring @@ -3617,8 +3628,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): for m, v in items: gg[g.index(m)] = v y = parent.base_ring().zero() - for (m,c) in self.dict().items(): - y += c*mul([ gg[i]**m[i] for i in m.nonzero_positions()]) + for m, c in self.monomial_coefficients().items(): + y += c*mul([gg[i] ** m[i] for i in m.nonzero_positions()]) return y _f = ( v)._poly if p_IsConstant(_f, _ring): @@ -3675,9 +3686,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def monomials(self): """ - Return the list of monomials in self. The returned list is - decreasingly ordered by the term ordering of - ``self.parent()``. + Return the list of monomials in ``self``. The returned list is + decreasingly ordered by the term ordering of ``self.parent()``. EXAMPLES:: @@ -3764,7 +3774,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def univariate_polynomial(self, R=None): """ - Returns a univariate polynomial associated to this + Return a univariate polynomial associated to this multivariate polynomial. INPUT: @@ -3772,7 +3782,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): - ``R`` -- (default: ``None``) PolynomialRing If this polynomial is not in at most one variable, then a - ``ValueError`` exception is raised. This is checked using the + :exc:`ValueError` exception is raised. This is checked using the :meth:`is_univariate()` method. The new Polynomial is over the same base ring as the given ``MPolynomial`` and in the variable ``x`` if no ring ``R`` is provided. @@ -3873,7 +3883,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f = x*z^2 + z + 1 sage: f._variable_indices_() [0, 2] - """ cdef poly *p cdef ring *r = self._parent_ring @@ -3969,7 +3978,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def lm(MPolynomial_libsingular self): """ - Returns the lead monomial of ``self`` with respect to the term + Return the lead monomial of ``self`` with respect to the term order of ``self.parent()``. In Sage a monomial is a product of variables in some power without a coefficient. @@ -3998,7 +4007,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f = x^4*y^7*z^1 + x^4*y^2*z^3 sage: f.lm() x^4*y^7*z - """ cdef poly *_p cdef ring *_ring = self._parent_ring @@ -4171,7 +4179,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): quo = p_Add_q(quo, temp, r) p = pNext(p) return new_MP(parent, quo) - if r.cf.type == n_Znm or r.cf.type == n_Zn or r.cf.type == n_Z2m : + if r.cf.type == n_Znm or r.cf.type == n_Zn or r.cf.type == n_Z2m: raise NotImplementedError("Division of multivariate polynomials over non fields by non-monomials not implemented.") count = singular_polynomial_length_bounded(self._poly, 15) @@ -4201,7 +4209,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``proof`` -- ignored. + - ``proof`` -- ignored EXAMPLES:: @@ -4481,32 +4489,34 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") # I make a temporary copy of the poly in self because singclap_factorize appears to modify it's parameter - ptemp = p_Copy(self._poly,_ring) + ptemp = p_Copy(self._poly, _ring) iv = NULL sig_on() - if _ring!=currRing: rChangeCurrRing(_ring) # singclap_factorize - I = singclap_factorize ( ptemp, &iv , 0, _ring) + if _ring != currRing: + rChangeCurrRing(_ring) # singclap_factorize + I = singclap_factorize(ptemp, &iv, 0, _ring) sig_off() ivv = iv.ivGetVec() - v = [(new_MP(parent, p_Copy(I.m[i],_ring)) , ivv[i]) for i in range(1,I.ncols)] - v = [(f,m) for f,m in v if f!=0] # we might have zero in there - unit = new_MP(parent, p_Copy(I.m[0],_ring)) + v = [(new_MP(parent, p_Copy(I.m[i], _ring)), ivv[i]) + for i in range(1, I.ncols)] + v = [(f, m) for f, m in v if f != 0] # we might have zero in there + unit = new_MP(parent, p_Copy(I.m[0], _ring)) - F = Factorization(v,unit) + F = Factorization(v, unit) F.sort() del iv - id_Delete(&I,_ring) + id_Delete(&I, _ring) return F def lift(self, I): """ - given an ideal ``I = (f_1,...,f_r)`` and some ``g (== self)`` in ``I``, + Given an ideal ``I = (f_1,...,f_r)`` and some ``g (== self)`` in ``I``, find ``s_1,...,s_r`` such that ``g = s_1 f_1 + ... + s_r f_r``. - A ``ValueError`` exception is raised if ``g (== self)`` does not belong to ``I``. + A :exc:`ValueError` exception is raised if ``g (== self)`` does not belong to ``I``. EXAMPLES:: @@ -4563,7 +4573,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: foo = I.complete_primary_decomposition() # indirect doctest sage: foo[0][0] Ideal (x1 + 1, x2^2 - 3) of Multivariate Polynomial Ring in x1, x2 over Rational Field - """ global errorreported @@ -4586,20 +4595,21 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): try: f = parent.coerce(f) except TypeError as msg: - id_Delete(&fI,r) - id_Delete(&_I,r) + id_Delete(&fI, r) + id_Delete(&_I, r) raise TypeError(msg) _I.m[i] = p_Copy((f)._poly, r) - i+=1 + i += 1 - fI.m[0]= p_Copy(self._poly, r) + fI.m[0] = p_Copy(self._poly, r) - if r!=currRing: rChangeCurrRing(r) # idLift + if r != currRing: + rChangeCurrRing(r) # idLift sig_on() res = idLift(_I, fI, NULL, 0, 0, 0) sig_off() - if errorreported != 0 : + if errorreported != 0: errorcode = errorreported errorreported = 0 if errorcode == 1: @@ -4616,18 +4626,16 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): id_Delete(&res, r) return Sequence(l, check=False, immutable=True) - def reduce(self,I): + def reduce(self, I): r""" Return a remainder of this polynomial modulo the polynomials in ``I``. INPUT: - - ``I`` -- an ideal or a list/set/iterable of polynomials. + - ``I`` -- an ideal or a list/set/iterable of polynomials - OUTPUT: - - A polynomial ``r`` such that: + OUTPUT: a polynomial ``r`` such that: - ``self`` -- ``r`` is in the ideal generated by ``I``. @@ -4687,8 +4695,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): 2*y sage: (x+y).reduce([x-y, x+y]) 0 - - """ cdef ideal *_I cdef MPolynomialRing_libsingular parent = self._parent @@ -4779,7 +4785,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): @coerce_binop def gcd(self, right, algorithm=None, **kwds): """ - Return the greatest common divisor of self and right. + Return the greatest common divisor of ``self`` and ``right``. INPUT: @@ -4876,7 +4882,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): return right if _ring.cf.type != n_unknown: - if _ring.cf.type == n_Znm or _ring.cf.type == n_Zn or _ring.cf.type == n_Z2m : + if _ring.cf.type == n_Znm or _ring.cf.type == n_Zn or _ring.cf.type == n_Z2m: raise NotImplementedError("GCD over rings not implemented.") if n_GetChar(_ring.cf) > 1<<29: @@ -4947,7 +4953,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if _ring!=currRing: rChangeCurrRing(_ring) if _ring.cf.type != n_unknown: - if _ring.cf.type == n_Znm or _ring.cf.type == n_Zn or _ring.cf.type == n_Z2m : + if _ring.cf.type == n_Znm or _ring.cf.type == n_Zn or _ring.cf.type == n_Z2m: raise TypeError("LCM over non-integral domains not available.") if self._parent is not g._parent: @@ -4962,7 +4968,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): + singular_polynomial_length_bounded(_g._poly,20) if count >= 20: sig_on() - if _ring!=currRing: rChangeCurrRing(_ring) # singclap_gcd + if _ring != currRing: + rChangeCurrRing(_ring) # singclap_gcd gcd = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(_g._poly, _ring), _ring ) prod = pp_Mult_qq(self._poly, _g._poly, _ring) ret = p_Divide(prod, gcd, _ring) @@ -5019,7 +5026,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... ZeroDivisionError - """ cdef poly *quo cdef poly *rem @@ -5237,7 +5243,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: parent(h(R.0,0)) Univariate Polynomial Ring in x over Rational Field """ - return unpickle_MPolynomial_libsingular, (self._parent, self.dict()) + return unpickle_MPolynomial_libsingular, (self._parent, + self.monomial_coefficients()) def _im_gens_(self, codomain, im_gens, base_map=None): """ @@ -5278,8 +5285,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if base_map is None: # Just use conversion base_map = codomain - for (m,c) in self.dict().iteritems(): - y += base_map(c)*mul([ im_gens[i]**m[i] for i in range(n) if m[i]]) + for m, c in self.monomial_coefficients().items(): + y += base_map(c) * mul([im_gens[i] ** m[i] for i in range(n) if m[i]]) return y def _derivative(self, MPolynomial_libsingular var): @@ -5309,7 +5316,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f = x^3*y^2 + y^2 + x + 2 sage: f._derivative(x) # needs sage.rings.finite_rings x^2*y^2 + 1 - """ if var is None: raise ValueError("you must specify which variable with respect to which to differentiate") @@ -5407,7 +5413,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): v = ETuple({index: 1}, len(gens)) _p = p_ISet(0, _ring) - for (exp, coeff) in self.dict().iteritems(): + for exp, coeff in self.monomial_coefficients().items(): nexp = exp.eadd(v) # new exponent mon = p_Init(_ring) p_SetCoeff(mon, sa2si(coeff / (1 + exp[index]), _ring), _ring) @@ -5496,12 +5502,15 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): elif not self._parent._base.is_field(): raise ValueError("Resultants require base fields or integer base ring.") - cdef int count = singular_polynomial_length_bounded(self._poly,20) \ + cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ + singular_polynomial_length_bounded(other._poly,20) if count >= 20: sig_on() if _ring != currRing: rChangeCurrRing(_ring) # singclap_resultant - rt = singclap_resultant(p_Copy(self._poly, _ring), p_Copy(other._poly, _ring), p_Copy((variable)._poly , _ring ), _ring) + rt = singclap_resultant(p_Copy(self._poly, _ring), + p_Copy(other._poly, _ring), + p_Copy((variable)._poly, _ring ), + _ring) if count >= 20: sig_off() return new_MP(self._parent, rt) @@ -5549,9 +5558,9 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -5625,12 +5634,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -5673,12 +5682,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -5735,22 +5744,22 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def numerator(self): """ - Return a numerator of self computed as self * self.denominator() + Return a numerator of ``self`` computed as ``self * self.denominator()``. - If the base_field of self is the Rational Field then the + If the base_field of ``self`` is the Rational Field then the numerator is a polynomial whose base_ring is the Integer Ring, this is done for compatibility to the univariate case. - .. warning:: + .. WARNING:: - This is not the numerator of the rational function - defined by self, which would always be self since self is a + This is not the numerator of the rational function defined by + ``self``, which would always be ``self`` since ``self`` is a polynomial. EXAMPLES: First we compute the numerator of a polynomial with - integer coefficients, which is of course self. + integer coefficients, which is of course ``self``. :: @@ -5810,7 +5819,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): else: return self * self.denominator() - def in_subalgebra(self, J, algorithm="algebra_containment"): + def in_subalgebra(self, J, algorithm='algebra_containment'): """ Return whether this polynomial is contained in the subalgebra generated by ``J`` @@ -5819,19 +5828,19 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): - ``J`` -- list of elements of the parent polynomial ring - - ``algorithm`` -- can be ``"algebra_containment"`` (the default), - ``"inSubring"``, or ``"groebner"``. + - ``algorithm`` -- can be ``'algebra_containment'`` (the default), + ``'inSubring'``, or ``'groebner'`` - - ``"algebra_containment"``: use Singular's + - ``'algebra_containment'``: use Singular's ``algebra_containment`` function, https://www.singular.uni-kl.de/Manual/4-2-1/sing_1247.htm#SEC1328. The Singular documentation suggests that this is frequently faster than the next option. - - ``"inSubring"``: use Singular's ``inSubring`` function, + - ``'inSubring'``: use Singular's ``inSubring`` function, https://www.singular.uni-kl.de/Manual/4-2-0/sing_1240.htm#SEC1321. - - ``"groebner"``: use the algorithm described in Singular's + - ``'groebner'``: use the algorithm described in Singular's documentation, but within Sage: if the subalgebra generators are `y_1`, ..., `y_m`, then create a new polynomial algebra with the old generators along with new @@ -5857,20 +5866,17 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ R = self.parent() algorithm = algorithm.lower() - from sage.libs.singular.function import singular_function, lib as singular_lib + from sage.libs.singular.function import (singular_function, + get_printlevel, + set_printlevel, + lib as singular_lib) singular_lib('algebra.lib') if algorithm == "algebra_containment": - execute = singular_function('execute') - try: - get_printlevel = singular_function('get_printlevel') - except NameError: - execute('proc get_printlevel {return (printlevel);}') - get_printlevel = singular_function('get_printlevel') - # It's fairly verbose unless printlevel is -1. + # verbose unless printlevel is -1. saved_printlevel = get_printlevel() - execute('printlevel=-1') + set_printlevel(-1) contains = singular_function('algebra_containment')(self, R.ideal(J)) == 1 - execute('printlevel={}'.format(saved_printlevel)) + set_printlevel(saved_printlevel) return contains elif algorithm == "insubring": return singular_function('inSubring')(self, R.ideal(J))[0] == 1 @@ -5890,7 +5896,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def unpickle_MPolynomial_libsingular(MPolynomialRing_libsingular R, d): """ - Deserialize an ``MPolynomial_libsingular`` object + Deserialize an ``MPolynomial_libsingular`` object. INPUT: @@ -5913,9 +5919,9 @@ def unpickle_MPolynomial_libsingular(MPolynomialRing_libsingular R, d): rChangeCurrRing(r) bucket = sBucketCreate(r) try: - for mon,c in d.iteritems(): + for mon, c in d.items(): m = p_Init(r) - for i,e in mon.sparse_iter(): + for i, e in mon.sparse_iter(): _i = i if _i >= r.N: p_Delete(&m, r) @@ -5954,14 +5960,12 @@ cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, p INPUT: - - ``parent`` -- a :class:`MPolynomialRing_libsingular`` - instance. The parent of the polynomial to create. - - - ``juice`` -- a pointer to a Singular ``poly`` C struct. + - ``parent`` -- a :class:`MPolynomialRing_libsingular` + instance; the parent of the polynomial to create - OUTPUT: + - ``juice`` -- a pointer to a Singular ``poly`` C struct - A Python object :class:`MPolynomial_libsingular`. + OUTPUT: a Python object :class:`MPolynomial_libsingular` The ownership of ``juice`` will be transferred to the Python object. You must not free it yourself. Singular will modify the diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index 03343b85b99..41cc1fb7c87 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -144,7 +144,7 @@ def __eq__(self, other): sage: loads(R.dumps()) == R True """ - if not is_MPolynomialRing(other): + if not isinstance(other, MPolynomialRing_base): return False return ((self.base_ring(), self.ngens(), self.variable_names(), self.term_order()) == @@ -430,13 +430,16 @@ def __call__(self, x=0, check=True): if P is self: return x - elif P == self: + + if P == self: return MPolynomial_polydict(self, x.element().dict()) - elif self.base_ring().has_coerce_map_from(P): + + if self.base_ring().has_coerce_map_from(P): # it might be in the base ring (i.e. a poly ring over a poly ring) c = self.base_ring()(x) return MPolynomial_polydict(self, {self._zero_tuple: c}) - elif len(P.variable_names()) == len(self.variable_names()): + + if len(P.variable_names()) == len(self.variable_names()): # Map the variables in some crazy way (but in order, # of course). This is here since R(blah) is supposed # to be "make an element of R if at all possible with @@ -446,63 +449,76 @@ def __call__(self, x=0, check=True): for i, a in D.items(): D[i] = K(a) return MPolynomial_polydict(self, D) - elif set(P.variable_names()).issubset(set(self.variable_names())) and self.base_ring().has_coerce_map_from(P.base_ring()): + + if (set(P.variable_names()).issubset(set(self.variable_names())) + and self.base_ring().has_coerce_map_from(P.base_ring())): # If the named variables are a superset of the input, map the variables by name return MPolynomial_polydict(self, self._extract_polydict(x)) - else: - return MPolynomial_polydict(self, x._mpoly_dict_recursive(self.variable_names(), self.base_ring())) + + return MPolynomial_polydict(self, + x._mpoly_dict_recursive(self.variable_names(), + self.base_ring())) elif isinstance(x, MPolynomial_libsingular): P = x.parent() if P == self: - return MPolynomial_polydict(self, x.dict()) - elif self.base_ring().has_coerce_map_from(P): + return MPolynomial_polydict(self, x.monomial_coefficients()) + + if self.base_ring().has_coerce_map_from(P): # it might be in the base ring (i.e. a poly ring over a poly ring) c = self.base_ring()(x) return MPolynomial_polydict(self, {self._zero_tuple: c}) - elif len(P.variable_names()) == len(self.variable_names()): + + if len(P.variable_names()) == len(self.variable_names()): # Map the variables in some crazy way (but in order, # of course). This is here since R(blah) is supposed # to be "make an element of R if at all possible with # no guarantees that this is mathematically solid." K = self.base_ring() - D = x.dict() + D = x.monomial_coefficients() for i, a in D.items(): D[i] = K(a) return MPolynomial_polydict(self, D) - elif set(P.variable_names()).issubset(set(self.variable_names())) and self.base_ring().has_coerce_map_from(P.base_ring()): + + if (set(P.variable_names()).issubset(set(self.variable_names())) + and self.base_ring().has_coerce_map_from(P.base_ring())): # If the named variables are a superset of the input, map the variables by name return MPolynomial_polydict(self, self._extract_polydict(x)) - else: - return MPolynomial_polydict(self, x._mpoly_dict_recursive(self.variable_names(), self.base_ring())) - elif isinstance(x, polynomial_element.Polynomial): - return MPolynomial_polydict(self, x._mpoly_dict_recursive(self.variable_names(), self.base_ring())) + return MPolynomial_polydict(self, + x._mpoly_dict_recursive(self.variable_names(), + self.base_ring())) + + if isinstance(x, polynomial_element.Polynomial): + return MPolynomial_polydict(self, + x._mpoly_dict_recursive(self.variable_names(), + self.base_ring())) - elif isinstance(x, PolyDict): + if isinstance(x, PolyDict): return MPolynomial_polydict(self, x) - elif isinstance(x, dict): + if isinstance(x, dict): K = self.base_ring() return MPolynomial_polydict(self, {i: K(a) for i, a in x.items()}) - elif isinstance(x, fraction_field_element.FractionFieldElement) and x.parent().ring() == self: + if (isinstance(x, fraction_field_element.FractionFieldElement) + and x.parent().ring() == self): if x.denominator() == 1: return x.numerator() - else: - raise TypeError("unable to coerce since the denominator is not 1") - elif isinstance(x, sage.interfaces.abc.SingularElement) and self._has_singular: + raise TypeError("unable to coerce since the denominator is not 1") + + if isinstance(x, sage.interfaces.abc.SingularElement) and self._has_singular: self._singular_().set_ring() try: return x.sage_poly(self) except TypeError: raise TypeError("unable to coerce singular object") - elif hasattr(x, '_polynomial_'): + if hasattr(x, '_polynomial_'): return x._polynomial_(self) - elif isinstance(x, str): + if isinstance(x, str): from sage.misc.sage_eval import sage_eval try: x = sage_eval(x, self.gens_dict_recursive()) @@ -510,7 +526,7 @@ def __call__(self, x=0, check=True): raise TypeError("unable to evaluate {!r} in {}".format(x, self)) return self(x) - elif isinstance(x, sage.interfaces.abc.Macaulay2Element): + if isinstance(x, sage.interfaces.abc.Macaulay2Element): try: s = x.sage_polystring() if len(s) == 0: @@ -524,7 +540,7 @@ def __call__(self, x=0, check=True): raise TypeError("Unable to coerce macaulay2 object") return MPolynomial_polydict(self, x) - elif isinstance(x, pari_gen) and x.type() == 't_POL': + if isinstance(x, pari_gen) and x.type() == 't_POL': # This recursive approach is needed because PARI # represents multivariate polynomials as iterated # univariate polynomials. Below, v is the variable @@ -538,9 +554,9 @@ def __call__(self, x=0, check=True): if isinstance(x, dict): return MPolynomial_polydict(self, x) - else: - c = self.base_ring()(x) - return MPolynomial_polydict(self, {self._zero_tuple: c}) + + c = self.base_ring()(x) + return MPolynomial_polydict(self, {self._zero_tuple: c}) # The following methods are handy for implementing Groebner # basis algorithms. They do only superficial type/sanity checks @@ -554,14 +570,13 @@ def monomial_quotient(self, f, g, coeff=False): INPUT: - - ``f`` -- monomial. + - ``f`` -- monomial - - ``g`` -- monomial. + - ``g`` -- monomial - - ``coeff`` -- divide coefficients as well (default: - False). + - ``coeff`` -- divide coefficients as well (default: ``False``) - OUTPUT: monomial. + OUTPUT: monomial EXAMPLES:: @@ -628,8 +643,8 @@ def monomial_quotient(self, f, g, coeff=False): if not g: raise ZeroDivisionError - fd = f.dict() - gd = g.dict() + fd = f.monomial_coefficients() + gd = g.monomial_coefficients() if not coeff: f = next(iter(fd)) @@ -650,11 +665,11 @@ def monomial_lcm(self, f, g): INPUT: - - ``f`` -- monomial. + - ``f`` -- monomial - - ``g`` -- monomial. + - ``g`` -- monomial - OUTPUT: monomial. + OUTPUT: monomial EXAMPLES:: @@ -683,8 +698,8 @@ def monomial_lcm(self, f, g): """ one = self.base_ring().one() - f, = f.dict() - g, = g.dict() + f, = f.monomial_coefficients() + g, = g.monomial_coefficients() length = len(f) @@ -703,11 +718,9 @@ def monomial_reduce(self, f, G): INPUT: + - ``f`` -- monomial - - ``f`` -- monomial - - - ``G`` -- list/set of mpolynomials - + - ``G`` -- list/set of mpolynomials EXAMPLES:: @@ -765,7 +778,7 @@ def monomial_divides(self, a, b): - ``b`` -- monomial - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -788,8 +801,8 @@ def monomial_divides(self, a, b): if not a: raise ZeroDivisionError - a, = a.dict() - b, = b.dict() + a, = a.monomial_coefficients() + b, = b.monomial_coefficients() return all(b[i] >= a[i] for i in b.common_nonzero_positions(a)) @@ -802,11 +815,11 @@ def monomial_pairwise_prime(self, h, g): INPUT: - - ``h`` -- monomial. + - ``h`` -- monomial - - ``g`` -- monomial. + - ``g`` -- monomial - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -853,9 +866,9 @@ def monomial_all_divisors(self, t): INPUT: - - ``t`` -- a monomial. + - ``t`` -- a monomial - OUTPUT: a list of monomials. + OUTPUT: list of monomials EXAMPLES:: @@ -882,7 +895,7 @@ def addwithcarry(tempvector, maxvector, pos): one = self.base_ring().one() M = list() - v, = t.dict() + v, = t.monomial_coefficients() maxvector = list(v) tempvector = [0] * len(maxvector) @@ -943,8 +956,8 @@ def ideal(self, *gens, **kwds): """ do_coerce = False if len(gens) == 1: - from sage.rings.ideal import is_Ideal - if is_Ideal(gens[0]): + from sage.rings.ideal import Ideal_generic + if isinstance(gens[0], Ideal_generic): if gens[0].ring() is self: return gens[0] gens = gens[0].gens() diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd index 4ce9033dadb..322e25e363b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd @@ -4,6 +4,7 @@ from sage.structure.parent cimport Parent cdef class MPolynomialRing_base(CommutativeRing): cdef object _ngens cdef object _term_order + cdef public object _indices cdef public object _has_singular cdef public object _magma_gens cdef public dict _magma_cache diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 55d2900fa61..19c2ddac7b1 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -26,9 +26,14 @@ from sage.rings.polynomial import polynomial_ring from sage.rings.polynomial.term_order import TermOrder from sage.rings.polynomial.polynomial_ring_constructor import (PolynomialRing, polynomial_default_category) +from sage.rings.polynomial.polydict cimport ETuple def is_MPolynomialRing(x): + from sage.misc.superseded import deprecation_cython + deprecation_cython(38266, + "The function is_MPolynomialRing is deprecated; " + "use 'isinstance(..., MPolynomialRing_base)' instead.") return isinstance(x, MPolynomialRing_base) @@ -94,6 +99,8 @@ cdef class MPolynomialRing_base(CommutativeRing): else: category = polynomial_default_category(base_ring.category(), n) Ring.__init__(self, base_ring, names, category=category) + from sage.combinat.integer_vector import IntegerVectors + self._indices = IntegerVectors(self._ngens) def is_integral_domain(self, proof=True): """ @@ -120,7 +127,7 @@ cdef class MPolynomialRing_base(CommutativeRing): @cached_method def flattening_morphism(self): r""" - Return the flattening morphism of this polynomial ring + Return the flattening morphism of this polynomial ring. EXAMPLES:: @@ -135,7 +142,7 @@ cdef class MPolynomialRing_base(CommutativeRing): Multivariate Polynomial Ring in x, y over Rational Field """ base = self.base_ring() - if is_MPolynomialRing(base) or polynomial_ring.is_PolynomialRing(base): + if isinstance(base, MPolynomialRing_base) or isinstance(base, polynomial_ring.PolynomialRing_general): from sage.rings.polynomial.flatten import FlatteningMorphism return FlatteningMorphism(self) else: @@ -143,7 +150,7 @@ cdef class MPolynomialRing_base(CommutativeRing): def construction(self): """ - Returns a functor ``F`` and base ring ``R`` such that ``F(R) == self``. + Return a functor ``F`` and base ring ``R`` such that ``F(R) == self``. EXAMPLES:: @@ -156,7 +163,6 @@ cdef class MPolynomialRing_base(CommutativeRing): True sage: F(R) == ZZ['x']['y'] False - """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.categories.pushout import MultiPolynomialFunctor @@ -317,7 +323,6 @@ cdef class MPolynomialRing_base(CommutativeRing): order for the subring sage: R.remove_var(x,y,z, order='degrevlex') Multivariate Polynomial Ring in u, v over Integer Ring - """ vars = list(self.variable_names()) for v in var: @@ -341,7 +346,7 @@ cdef class MPolynomialRing_base(CommutativeRing): INPUT: - - ``x`` -- a variable of ``self``. + - ``x`` -- a variable of ``self`` EXAMPLES:: @@ -366,14 +371,14 @@ cdef class MPolynomialRing_base(CommutativeRing): INPUT: - * ``bound`` -- either an integer bounding the total degree or a + - ``bound`` -- either an integer bounding the total degree or a list/tuple of integers bounding the degree of the variables - * ``points`` -- list/tuple containing the evaluation points + - ``points`` -- list/tuple containing the evaluation points - * ``values`` -- list/tuple containing the desired values at ``points`` + - ``values`` -- list/tuple containing the desired values at ``points`` - * ``function`` -- evaluable function in `n` variables, where `n` is the + - ``function`` -- evaluable function in `n` variables, where `n` is the number of variables of the polynomial ring OUTPUT: @@ -558,7 +563,7 @@ cdef class MPolynomialRing_base(CommutativeRing): cdef _coerce_c_impl(self, x): """ Return the canonical coercion of x to this multivariate - polynomial ring, if one is defined, or raise a TypeError. + polynomial ring, if one is defined, or raise a :exc:`TypeError`. The rings that canonically coerce to this polynomial ring are: @@ -590,14 +595,14 @@ cdef class MPolynomialRing_base(CommutativeRing): P = x.parent() # polynomial rings in the same variable over the any base # that coerces in: - if is_MPolynomialRing(P): + if isinstance(P, MPolynomialRing_base): if P.variable_names() == self.variable_names(): if self.has_coerce_map_from(P.base_ring()): return self(x) elif self.base_ring().has_coerce_map_from(P._mpoly_base_ring(self.variable_names())): return self(x) - elif polynomial_ring.is_PolynomialRing(P): + elif isinstance(P, polynomial_ring.PolynomialRing_general): if P.variable_name() in self.variable_names(): if self.has_coerce_map_from(P.base_ring()): return self(x) @@ -615,14 +620,15 @@ cdef class MPolynomialRing_base(CommutativeRing): a dict with respect to ``self.variable_names()``. """ # This is probably horribly inefficient - from sage.rings.polynomial.polydict import ETuple other_vars = list(x.parent().variable_names()) - name_mapping = [(other_vars.index(var) if var in other_vars else -1) for var in self.variable_names()] + name_mapping = [(other_vars.index(var) if var in other_vars else -1) + for var in self.variable_names()] K = self.base_ring() D = {} var_range = range(len(self.variable_names())) - for ix, a in x.dict().iteritems(): - ix = ETuple([0 if name_mapping[t] == -1 else ix[name_mapping[t]] for t in var_range]) + for ix, a in x.monomial_coefficients().items(): + ix = ETuple([0 if name_mapping[t] == -1 else ix[name_mapping[t]] + for t in var_range]) D[ix] = K(a) return D @@ -634,7 +640,7 @@ cdef class MPolynomialRing_base(CommutativeRing): # One is not a parent -- not equal and not ordered return op == Py_NE - if not is_MPolynomialRing(right): + if not isinstance(right, MPolynomialRing_base): return op == Py_NE lft = left @@ -786,8 +792,8 @@ cdef class MPolynomialRing_base(CommutativeRing): INPUT: - - ``gap`` -- (optional GAP instance) Interface to which the - string is addressed. + - ``gap`` -- (optional GAP instance) interface to which the + string is addressed NOTE: @@ -933,8 +939,6 @@ cdef class MPolynomialRing_base(CommutativeRing): raise NotImplementedError def __reduce__(self): - """ - """ base_ring = self.base_ring() n = self.ngens() names = self.variable_names() @@ -986,12 +990,12 @@ cdef class MPolynomialRing_base(CommutativeRing): def _to_monomial(self, i, n, d): """ - Given an index i, a number of variables n and a degree d return - the i-th monomial of degree d in n variables. + Given an index ``i``, a number of variables ``n`` and a degree ``d`` + return the `i`-th monomial of degree `d` in `n` variables. INPUT: - - ``i`` -- index: 0 <= i < binom(n+d-1,n-1) + - ``i`` -- index; ``0 <= i < binom(n+d-1,n-1)`` - ``n`` -- number of variables - ``d`` -- degree @@ -1136,7 +1140,7 @@ cdef class MPolynomialRing_base(CommutativeRing): silently reduced to the maximum number of available terms. - ``choose_degree`` -- choose degrees of monomials randomly first - rather than monomials uniformly random. + rather than monomials uniformly random - ``**kwargs`` -- passed to the random element generator of the base ring @@ -1371,7 +1375,22 @@ cdef class MPolynomialRing_base(CommutativeRing): sage: m = R.monomial(1,2,3) sage: R.monomial(*m.degrees()) == m True + + We also allow to specify the exponents in a single tuple:: + + sage: R.monomial(e) + x*y^2*z^3 + + TESTS: + + Check that ETuples also work:: + + sage: from sage.rings.polynomial.polydict import ETuple + sage: R.monomial(ETuple(e)) + x*y^2*z^3 """ + if len(exponents) == 1 and isinstance((e := exponents[0]), (tuple, ETuple)): + return self({e: self.base_ring().one()}) return self({exponents: self.base_ring().one()}) def monomials_of_degree(self, degree): @@ -1410,18 +1429,18 @@ cdef class MPolynomialRing_base(CommutativeRing): def _macaulay_resultant_getS(self, mon_deg_tuple, dlist): r""" - In the Macaulay resultant algorithm the list of all monomials of the total degree is partitioned into sets `S_i`. - This function returns the index `i` for the set `S_i` for the given monomial. + In the Macaulay resultant algorithm the list of all monomials of the + total degree is partitioned into sets `S_i`. + This function returns the index `i` for the set `S_i` for the given + monomial. INPUT: - - ``mon_deg_tuple`` -- a list representing a monomial of a degree `d` - - ``dlist`` -- a list of degrees ``d_i`` of the polynomials in + - ``mon_deg_tuple`` -- list representing a monomial of a degree `d` + - ``dlist`` -- list of degrees `d_i` of the polynomials in question, where ``d = sum(dlist) - len(dlist) + 1`` - OUTPUT: - - - the index `i` such that the input monomial is in `S_i` + OUTPUT: the index `i` such that the input monomial is in `S_i` EXAMPLES:: @@ -1451,12 +1470,10 @@ cdef class MPolynomialRing_base(CommutativeRing): INPUT: - ``mon_degs`` -- a monomial represented by a vector of degrees - - ``dlist`` -- a list of degrees with respect to which we check + - ``dlist`` -- list of degrees with respect to which we check reducedness - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES: @@ -1483,7 +1500,7 @@ cdef class MPolynomialRing_base(CommutativeRing): INPUT: - - ``dlist`` -- a list of degrees. + - ``dlist`` -- list of degrees OUTPUT: @@ -1545,18 +1562,16 @@ cdef class MPolynomialRing_base(CommutativeRing): INPUT: - - ``args`` -- a list of `n` homogeneous polynomials in `n` variables. + - ``args`` -- list of `n` homogeneous polynomials in `n` variables works when ``args[0]`` is the list of polynomials, or ``args`` is itself the list of polynomials kwds: - ``sparse`` -- boolean (default: ``False``); if ``True``, the function - creates sparse matrices. + creates sparse matrices - OUTPUT: - - - the Macaulay resultant, an element of the base ring of ``self`` + OUTPUT: the Macaulay resultant, an element of the base ring of ``self`` .. TODO:: @@ -1671,7 +1686,6 @@ cdef class MPolynomialRing_base(CommutativeRing): sage: RH = fh.parent() sage: f.resultant(g) == RH.macaulay_resultant([fh, gh]) # needs sage.modules True - """ from sage.matrix.constructor import matrix from sage.matrix.constructor import zero_matrix diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index b559993d39f..37381c084ac 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -168,9 +168,9 @@ from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.rings.infinity import Infinity from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.quotient_ring import is_QuotientRing +from sage.rings.quotient_ring import QuotientRing_nc from sage.structure.sequence import Sequence_generic try: @@ -197,12 +197,16 @@ def is_PolynomialSequence(F): sage: F = Sequence(I, P); F [x^2 + y^2, x^2 - y^2] - sage: from sage.rings.polynomial.multi_polynomial_sequence import is_PolynomialSequence - sage: is_PolynomialSequence(F) + sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence_generic + sage: isinstance(F, PolynomialSequence_generic) True - """ - return isinstance(F,PolynomialSequence_generic) + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_PolynomialSequence is deprecated; " + "use 'isinstance(..., PolynomialSequence_generic)' instead.") + return isinstance(F, PolynomialSequence_generic) + def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): """ @@ -213,7 +217,7 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): - ``arg1`` -- a multivariate polynomial ring, an ideal or a matrix - ``arg2`` -- an iterable object of parts or polynomials - (default:``None``) + (default: ``None``) - ``immutable`` -- if ``True`` the sequence is immutable (default: ``False``) @@ -297,7 +301,7 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): except ImportError: BooleanMonomialMonoid = () - is_ring = lambda r: is_MPolynomialRing(r) or isinstance(r, BooleanMonomialMonoid) or (is_QuotientRing(r) and is_MPolynomialRing(r.cover_ring())) + is_ring = lambda r: isinstance(r, MPolynomialRing_base) or isinstance(r, BooleanMonomialMonoid) or (isinstance(r, QuotientRing_nc) and isinstance(r.cover_ring(), MPolynomialRing_base)) if is_ring(arg1): ring, gens = arg1, arg2 @@ -380,9 +384,9 @@ def __init__(self, parts, ring, immutable=False, cr=False, cr_str=None): INPUT: - - ``part`` -- a list of lists with polynomials + - ``part`` -- list of lists with polynomials - - ``ring`` -- a multivariate polynomial ring + - ``ring`` -- a multivariate polynomial ring - ``immutable`` -- if ``True`` the sequence is immutable (default: ``False``) @@ -619,10 +623,10 @@ def nvariables(self): def algebraic_dependence(self): r""" - Returns the ideal of annihilating polynomials for the + Return the ideal of annihilating polynomials for the polynomials in ``self``, if those polynomials are algebraically dependent. - Otherwise, returns the zero ideal. + Otherwise, return the zero ideal. OUTPUT: @@ -722,7 +726,7 @@ def coefficients_monomials(self, order=None, sparse=True): INPUT: - ``sparse`` -- construct a sparse matrix (default: ``True``) - - ``order`` -- a list or tuple specifying the order of monomials (default: ``None``) + - ``order`` -- list or tuple specifying the order of monomials (default: ``None``) EXAMPLES:: @@ -841,8 +845,8 @@ def subs(self, *args, **kwargs): INPUT: - - ``args`` -- arguments to be passed to :meth:`MPolynomial.subs` - - ``kwargs`` -- keyword arguments to be passed to :meth:`MPolynomial.subs` + - ``args`` -- arguments to be passed to :meth:`MPolynomial.subs` + - ``kwargs`` -- keyword arguments to be passed to :meth:`MPolynomial.subs` EXAMPLES:: @@ -921,7 +925,6 @@ def _repr_(self): sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # needs sage.rings.polynomial.pbori sage: F,s = sr.polynomial_system(); F # needs sage.rings.polynomial.pbori Polynomial Sequence with 36 Polynomials in 20 Variables - """ if len(self) < 20: return Sequence_generic._repr_(self) @@ -958,7 +961,7 @@ def __add__(self, right): b^2 + 2*a*c + 2*b*d - c, a^127 + a] """ - if is_PolynomialSequence(right) and right.ring() == self.ring(): + if isinstance(right, PolynomialSequence_generic) and right.ring() == self.ring(): return PolynomialSequence(self.ring(), self.parts() + right.parts()) elif isinstance(right,(tuple,list)) and all((x.parent() == self.ring() for x in right)): @@ -1105,7 +1108,6 @@ def maximal_degree(self): sage: F = Sequence([], universe=P) sage: F.maximal_degree() -1 - """ try: return max(f.degree() for f in self) @@ -1126,7 +1128,6 @@ def __reduce__(self): sage: f = P.hom([y,z,x]) sage: hash(f) == hash(loads(dumps(f))) True - """ return PolynomialSequence, (self._ring, self._parts, self._is_immutable, self._Sequence_generic__cr, self._Sequence_generic__cr_str) @@ -1196,11 +1197,10 @@ def reduced(self): Check that :issue:`26952` is fixed:: sage: Qp = pAdicField(2) - sage: R. = PolynomialRing(Qp, implementation="generic") # needs sage.rings.padics + sage: R. = PolynomialRing(Qp, implementation='generic') # needs sage.rings.padics sage: F = Sequence([z*x+y^3,z+y^3,3*z+x*y]) sage: F.reduced() [y^3 + z, x*y + (1 + 2 + O(2^20))*z, x*z - z] - """ from sage.rings.polynomial.multi_polynomial_ideal_libsingular import \ interred_libsingular @@ -1234,7 +1234,7 @@ def reduced(self): @singular_gb_standard_options def is_groebner(self, singular=singular): r""" - Returns ``True`` if the generators of this ideal (``self.gens()``) + Return ``True`` if the generators of this ideal (``self.gens()``) form a Groebner basis. Let `I` be the set of generators of this ideal. The check is @@ -1254,7 +1254,6 @@ def is_groebner(self, singular=singular): sage: I2 = Ideal(I.groebner_basis()) sage: I2.basis.is_groebner() True - """ return self.ideal().basis_is_groebner() @@ -1485,7 +1484,8 @@ def _groebner_strategy(self): g.reduction_strategy.opt_red_tail = True return g - def solve(self, algorithm='polybori', n=1, eliminate_linear_variables=True, verbose=False, **kwds): + def solve(self, algorithm='polybori', n=1, + eliminate_linear_variables=True, verbose=False, **kwds): r""" Find solutions of this boolean polynomial system. @@ -1496,27 +1496,26 @@ def solve(self, algorithm='polybori', n=1, eliminate_linear_variables=True, ver INPUT: - * ``self`` -- a sequence of boolean polynomials + - ``self`` -- a sequence of boolean polynomials - * ``algorithm`` -- the method to use. Possible values are - ``polybori``, ``sat`` and ``exhaustive_search``. (default: - ``polybori``, since it is always available) + - ``algorithm`` -- the method to use. Possible values are + ``'polybori'``, ``'sat'`` and ``'exhaustive_search'``. (default: + ``'polybori'``, since it is always available) - * ``n`` -- number of solutions to return. If ``n == +Infinity`` - then all solutions are returned. If `n < \infty` then `n` - solutions are returned if the equations have at least `n` - solutions. Otherwise, all the solutions are - returned. (default: ``1``) + - ``n`` -- (default: 1) number of solutions to return. If + ``n == +Infinity`` then all solutions are returned. If `n < \infty` + then `n` solutions are returned if the equations have at least `n` + solutions. Otherwise, all the solutions are returned. - * ``eliminate_linear_variables`` -- whether to eliminate + - ``eliminate_linear_variables`` -- whether to eliminate variables that appear linearly. This reduces the number of variables (makes solving faster a priori), but is likely to make the equations denser (may make solving slower depending on the method). - * ``verbose`` -- whether to display progress and (potentially) - useful information while the computation runs. (default: - ``False``) + - ``verbose`` -- boolean (default: ``False``); whether to display + progress and (potentially) useful information while the computation + runs EXAMPLES: @@ -1583,7 +1582,6 @@ def solve(self, algorithm='polybori', n=1, eliminate_linear_variables=True, ver sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # needs sage.rings.polynomial.pbori sage: S.solve() # needs sage.rings.polynomial.pbori [] - """ from sage.modules.free_module import VectorSpace @@ -1709,7 +1707,7 @@ def coefficients_monomials(self, order=None, sparse=True): INPUT: - ``sparse`` -- construct a sparse matrix (default: ``True``) - - ``order`` -- a list or tuple specifying the order of monomials (default: ``None``) + - ``order`` -- list or tuple specifying the order of monomials (default: ``None``) EXAMPLES:: diff --git a/src/sage/rings/polynomial/omega.py b/src/sage/rings/polynomial/omega.py index 5f5dfb441e7..797200f4e40 100644 --- a/src/sage/rings/polynomial/omega.py +++ b/src/sage/rings/polynomial/omega.py @@ -311,7 +311,7 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, decoded_factors = [] for factor in factors_denominator: factor = L(factor) - D = factor.dict() + D = factor.monomial_coefficients() if not D: raise ZeroDivisionError('Denominator contains a factor 0.') elif len(D) == 1: @@ -331,7 +331,7 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, numerator = L(numerator) / prod(to_numerator) result_numerator, result_factors_denominator = \ - _Omega_(numerator.dict(), decoded_factors) + _Omega_(numerator.monomial_coefficients(), decoded_factors) if result_numerator == 0: return Factorization([], unit=result_numerator) @@ -350,7 +350,7 @@ def _simplify_(numerator, terms): - ``numerator`` -- a Laurent polynomial - - ``terms`` -- a tuple or other iterable of Laurent polynomials + - ``terms`` -- tuple or other iterable of Laurent polynomials The denominator is the product of factors `1 - t` for each `t` in ``terms``. @@ -394,10 +394,10 @@ def _Omega_(A, decoded_factors): INPUT: - - ``A`` -- a dictionary mapping `a` to `c` representing a summand + - ``A`` -- dictionary mapping `a` to `c` representing a summand `c\mu^a` of the numerator - - ``decoded_factors`` -- a tuple or list of pairs `(z, e)` representing + - ``decoded_factors`` -- tuple or list of pairs `(z, e)` representing a factor `1 - z \mu^e` OUTPUT: @@ -482,9 +482,9 @@ def Omega_ge(a, exponents): INPUT: - - ``a`` -- an integer + - ``a`` -- integer - - ``exponents`` -- a tuple of integers + - ``exponents`` -- tuple of integers OUTPUT: @@ -589,7 +589,7 @@ def subs_power(expression, var, exponent): It is assumed that ``var`` only occurs with exponents divisible by ``exponent``. """ - p = tuple(var.dict().popitem()[0]).index(1) # var is the p-th generator + p = tuple(var.monomial_coefficients().popitem()[0]).index(1) # var is the p-th generator def subs_e(e): e = list(e) @@ -597,7 +597,8 @@ def subs_e(e): e[p] = e[p] // exponent return tuple(e) parent = expression.parent() - result = parent({subs_e(e): c for e, c in expression.dict().items()}) + result = parent({subs_e(e): c + for e, c in expression.monomial_coefficients().items()}) return result def de_power(expression): @@ -638,9 +639,9 @@ def _Omega_numerator_(a, x, y, t): INPUT: - - ``a`` -- an integer + - ``a`` -- integer - - ``x`` and ``y`` -- a tuple of tuples of Laurent polynomials + - ``x``, ``y`` -- tuple of tuples of Laurent polynomials The flattened ``x`` contains `x_1,...,x_n`, the flattened ``y`` the @@ -650,9 +651,7 @@ def _Omega_numerator_(a, x, y, t): - ``t`` -- a temporary Laurent polynomial variable used for substituting - OUTPUT: - - A Laurent polynomial + OUTPUT: a Laurent polynomial The output is normalized such that the corresponding denominator (:func:`_Omega_factors_denominator_`) has constant term `1`. @@ -755,9 +754,9 @@ def _Omega_numerator_P_(a, x, y, t): INPUT: - - ``a`` -- an integer + - ``a`` -- integer - - ``x`` and ``y`` -- a tuple of Laurent polynomials + - ``x``, ``y`` -- tuple of Laurent polynomials The tuple ``x`` here is the flattened ``x`` of :func:`_Omega_numerator_` but without its last entry. @@ -767,9 +766,7 @@ def _Omega_numerator_P_(a, x, y, t): In the (final) result, ``t`` has to be substituted by the last entry of the flattened ``x`` of :func:`_Omega_numerator_`. - OUTPUT: - - A Laurent polynomial + OUTPUT: a Laurent polynomial TESTS:: @@ -839,7 +836,7 @@ def _Omega_factors_denominator_(x, y): INPUT: - - ``x`` and ``y`` -- a tuple of tuples of Laurent polynomials + - ``x``, ``y`` -- tuple of tuples of Laurent polynomials The flattened ``x`` contains `x_1,...,x_n`, the flattened ``y`` the @@ -958,9 +955,7 @@ def homogeneous_symmetric_function(j, x): - ``x`` -- an iterable of variables - OUTPUT: - - A polynomial of the common parent of all entries of ``x`` + OUTPUT: a polynomial of the common parent of all entries of ``x`` EXAMPLES:: diff --git a/src/sage/rings/polynomial/ore_function_element.py b/src/sage/rings/polynomial/ore_function_element.py index 0c1a919351f..fd871fa3b76 100644 --- a/src/sage/rings/polynomial/ore_function_element.py +++ b/src/sage/rings/polynomial/ore_function_element.py @@ -170,7 +170,6 @@ def _richcmp_(self, other, op): sage: D = K.random_element() sage: Q == 0 or D == 0 or (P*D) / (Q*D) == P/Q # long time True - """ if self.parent()._simplification: return richcmp((self._numerator, self._denominator), (other._numerator, other._denominator), op) @@ -614,7 +613,7 @@ def hilbert_shift(self, s, var=None): - ``s`` -- an element in the base ring - - ``var`` -- a string; the variable name + - ``var`` -- string; the variable name EXAMPLES:: @@ -838,7 +837,7 @@ def reduced_trace(self, var=None): INPUT: - - ``var`` -- a string or ``None`` (default: ``None``); + - ``var`` -- string or ``None`` (default: ``None``); the name of the central variable EXAMPLES:: @@ -901,7 +900,7 @@ def reduced_norm(self, var=None): INPUT: - - ``var`` -- a string or ``None`` (default: ``None``); + - ``var`` -- string or ``None`` (default: ``None``); the name of the central variable EXAMPLES:: diff --git a/src/sage/rings/polynomial/ore_function_field.py b/src/sage/rings/polynomial/ore_function_field.py index ad7fc4fe3c1..1c78217508b 100644 --- a/src/sage/rings/polynomial/ore_function_field.py +++ b/src/sage/rings/polynomial/ore_function_field.py @@ -329,7 +329,7 @@ def change_var(self, var): INPUT: - - ``var`` -- a string representing the name of the new variable. + - ``var`` -- string representing the name of the new variable EXAMPLES:: @@ -375,7 +375,7 @@ def twisting_morphism(self, n=1): INPUT: - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) EXAMPLES:: @@ -438,8 +438,8 @@ def gen(self, n=0): INPUT: - - ``n`` -- index of generator to return (default: 0). Exists for - compatibility with other polynomial rings. + - ``n`` -- index of generator to return (default: 0); exists for + compatibility with other polynomial rings EXAMPLES:: @@ -579,7 +579,7 @@ def random_element(self, degree=2, monic=False, *args, **kwds): - ``degree`` -- (default: 2) an integer or a list of two integers; the degrees of the denominator and numerator - - ``monic`` -- (default: ``False``) if ``True``, return a monic + - ``monic`` -- boolean (default: ``False``); if ``True``, return a monic Ore function with monic numerator and denominator - ``*args``, ``**kwds`` -- passed in to the :meth:`random_element` @@ -917,10 +917,10 @@ def center(self, name=None, names=None, default=False): INPUT: - - ``name`` -- a string or ``None`` (default: ``None``); + - ``name`` -- string or ``None`` (default: ``None``); the name for the central variable - - ``default`` -- a boolean (default: ``False``); if ``True``, + - ``default`` -- boolean (default: ``False``); if ``True``, set the default variable name for the center to ``name`` EXAMPLES:: diff --git a/src/sage/rings/polynomial/ore_polynomial_element.pxd b/src/sage/rings/polynomial/ore_polynomial_element.pxd index f38bcb0f0c5..771c4d6325a 100644 --- a/src/sage/rings/polynomial/ore_polynomial_element.pxd +++ b/src/sage/rings/polynomial/ore_polynomial_element.pxd @@ -17,7 +17,7 @@ cdef class OrePolynomial(AlgebraElement): cpdef bint is_zero(self) noexcept cpdef bint is_one(self) noexcept - + cdef _left_quo_rem(self, OrePolynomial other) cdef _right_quo_rem(self, OrePolynomial other) cdef OrePolynomial _left_lcm_cofactor(self, OrePolynomial other) @@ -38,7 +38,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): cdef list _mul_list(self, list A) cpdef _mul_(self, other) - cpdef dict dict(self) + cpdef dict monomial_coefficients(self) cpdef list list(self, bint copy=*) diff --git a/src/sage/rings/polynomial/ore_polynomial_element.pyx b/src/sage/rings/polynomial/ore_polynomial_element.pyx index dc6fbab0ab0..768565840f6 100644 --- a/src/sage/rings/polynomial/ore_polynomial_element.pyx +++ b/src/sage/rings/polynomial/ore_polynomial_element.pyx @@ -274,7 +274,7 @@ cdef class OrePolynomial(AlgebraElement): cdef OrePolynomial _new_c(self, list coeffs, Parent P, char check=0): r""" - Fast creation of a new Ore polynomial + Fast creation of a new Ore polynomial. .. NOTE:: @@ -285,7 +285,7 @@ cdef class OrePolynomial(AlgebraElement): cpdef OrePolynomial _new_constant_poly(self, RingElement a, Parent P, char check=0): r""" - Fast creation of a new constant Ore polynomial + Fast creation of a new constant Ore polynomial. EXAMPLES:: @@ -307,7 +307,7 @@ cdef class OrePolynomial(AlgebraElement): r""" Set the ``n``-th coefficient of ``self``. - This always raises an ``IndexError``, since polynomials are immutable in + This always raises an :exc:`IndexError`, since polynomials are immutable in Sage. EXAMPLES:: @@ -583,7 +583,7 @@ cdef class OrePolynomial(AlgebraElement): cpdef _mod_(self, other): r""" Return the remainder in the *right* Euclidean division of - ``self`` by ``other```. + ``self`` by ``other``. TESTS:: @@ -660,9 +660,7 @@ cdef class OrePolynomial(AlgebraElement): - ``other`` -- an Ore polynomial in the same ring as ``self`` - OUTPUT: - - Return ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -696,9 +694,7 @@ cdef class OrePolynomial(AlgebraElement): - ``other`` -- an Ore polynomial in the same ring as ``self`` - OUTPUT: - - Return ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -746,9 +742,7 @@ cdef class OrePolynomial(AlgebraElement): - ``other`` -- an Ore polynomial in the same ring as ``self`` - OUTPUT: - - Return ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -782,9 +776,7 @@ cdef class OrePolynomial(AlgebraElement): - ``other`` -- an Ore polynomial in the same ring as ``self`` - OUTPUT: - - Return ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -1440,7 +1432,7 @@ cdef class OrePolynomial(AlgebraElement): - ``other`` -- an Ore polynomial in the same ring as ``self`` - - ``monic`` -- a boolean (default: ``True``); whether the right lcm + - ``monic`` -- boolean (default: ``True``); whether the right lcm should be normalized to be monic EXAMPLES:: @@ -1946,7 +1938,7 @@ cdef class OrePolynomial(AlgebraElement): r""" Return the coefficients of the monomials appearing in ``self``. - If ``sparse=True`` (the default), return only the non-zero coefficients. + If ``sparse=True`` (the default), return only the nonzero coefficients. Otherwise, return the same value as ``self.list()``. .. NOTE:: @@ -1968,7 +1960,7 @@ cdef class OrePolynomial(AlgebraElement): def number_of_terms(self): r""" - Return the number of non-zero coefficients of ``self``. + Return the number of nonzero coefficients of ``self``. This is also known as the weight, hamming weight or sparsity. @@ -2140,7 +2132,7 @@ cdef class OrePolynomial(AlgebraElement): INPUT: - - ``n`` -- (default: ``None``); if given, an integer that + - ``n`` -- (default: ``None``) if given, an integer that is at least `0` EXAMPLES:: @@ -2200,7 +2192,7 @@ cdef void lmul_gen(list A, Morphism m, d) noexcept: INPUT: - - ``A`` -- a list of coefficients + - ``A`` -- list of coefficients - ``m`` -- the twisting morphism of the Ore polynomial ring @@ -2441,11 +2433,9 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): INPUT: - - ``n`` -- an integer + - ``n`` -- integer - OUTPUT: - - - the ``n``-th coefficient of ``self`` + OUTPUT: the ``n``-th coefficient of ``self`` EXAMPLES:: @@ -2491,7 +2481,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): else: return (self)._coeffs - cpdef dict dict(self): + cpdef dict monomial_coefficients(self): r""" Return a dictionary representation of ``self``. @@ -2501,6 +2491,11 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): sage: sigma = R.hom([t+1]) sage: S. = R['x',sigma] sage: a = x^2012 + t*x^1006 + t^3 + 2*t + sage: a.monomial_coefficients() + {0: t^3 + 2*t, 1006: t, 2012: 1} + + ``dict`` is an alias:: + sage: a.dict() {0: t^3 + 2*t, 1006: t, 2012: 1} """ @@ -2513,6 +2508,8 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): X[i] = c return X + dict = monomial_coefficients + cpdef Integer degree(self): r""" Return the degree of ``self``. @@ -2634,7 +2631,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): def valuation(self): r""" - Return the minimal degree of a non-zero monomial of ``self``. + Return the minimal degree of a nonzero monomial of ``self``. By convention, the zero Ore polynomial has valuation `+\infty`. @@ -2856,7 +2853,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): r""" Return the coefficients of the monomials appearing in ``self``. - If ``sparse=True`` (the default), return only the non-zero coefficients. + If ``sparse=True`` (the default), return only the nonzero coefficients. Otherwise, return the same value as ``self.list()``. EXAMPLES:: @@ -2885,7 +2882,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): - ``s`` -- an element in the base ring - - ``var`` -- a string; the variable name + - ``var`` -- string; the variable name EXAMPLES:: @@ -3050,10 +3047,10 @@ cdef class OrePolynomialBaseringInjection(Morphism): INPUT: - - ``domain`` -- a ring `R`. This will be the domain of the injection. + - ``domain`` -- a ring `R`; this will be the domain of the injection - - ``codomain`` -- an Ore polynomial ring over ``domain``. This will be - the codomain. + - ``codomain`` -- an Ore polynomial ring over ``domain``; this will be + the codomain TESTS:: @@ -3105,9 +3102,7 @@ cdef class OrePolynomialBaseringInjection(Morphism): - ``e`` -- element belonging to the base ring according to ``self`` - OUTPUT: - - The Ore polynomial corresponding to `e` according to ``self``. + OUTPUT: the Ore polynomial corresponding to `e` according to ``self`` TESTS:: diff --git a/src/sage/rings/polynomial/ore_polynomial_ring.py b/src/sage/rings/polynomial/ore_polynomial_ring.py index b3848f0a10c..f28b90ad198 100644 --- a/src/sage/rings/polynomial/ore_polynomial_ring.py +++ b/src/sage/rings/polynomial/ore_polynomial_ring.py @@ -68,9 +68,9 @@ class OrePolynomialRing(UniqueRepresentation, Parent): - ``twisting_map`` -- either an endomorphism of the base ring, or a (twisted) derivation of it - - ``names`` -- a string or a list of strings + - ``names`` -- string or list of strings - - ``sparse`` -- a boolean (default: ``False``); currently not supported + - ``sparse`` -- boolean (default: ``False``); currently not supported EXAMPLES: @@ -304,7 +304,7 @@ def __classcall_private__(cls, base_ring, twist=None, names=None, sparse=False, If there is no twisting derivation and that the twisting morphism is - `None` ot the identity, a regular `PolynomialRing` is created, unless + ``None`` ot the identity, a regular `PolynomialRing` is created, unless specified otherwise:: sage: # needs sage.rings.finite_rings @@ -348,7 +348,7 @@ def __classcall_private__(cls, base_ring, twist=None, names=None, sparse=False, except IndexError: raise NotImplementedError("multivariate Ore polynomials rings not supported") - # If `polcast` is `True` and there is no twisting morphism and no + # If `polcast` is ``True`` and there is no twisting morphism and no # twisting derivation we return a classical polynomial ring if polcast and derivation is None and morphism is None: return PolynomialRing(base_ring, names, sparse=sparse) @@ -660,7 +660,7 @@ def change_var(self, var): INPUT: - - ``var`` -- a string representing the name of the new variable + - ``var`` -- string representing the name of the new variable EXAMPLES:: @@ -709,7 +709,7 @@ def twisting_morphism(self, n=1): INPUT: - - ``n`` -- an integer (default: 1) + - ``n`` -- integer (default: 1) EXAMPLES:: @@ -972,7 +972,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): - ``degree`` -- (default: ``(-1,2)``) integer with degree or a tuple of integers with minimum and maximum degrees - - ``monic`` -- (default: ``False``) if ``True``, return a monic + - ``monic`` -- boolean (default: ``False``); if ``True``, return a monic Ore polynomial - ``*args``, ``**kwds`` -- passed on to the ``random_element`` method @@ -1014,7 +1014,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): TESTS: If the first tuple element is greater than the second, a - :class:`ValueError` is raised:: + :exc:`ValueError` is raised:: sage: S.random_element(degree=(5,4)) # needs sage.rings.finite_rings Traceback (most recent call last): @@ -1062,14 +1062,14 @@ def random_irreducible(self, degree=2, monic=True, *args, **kwds): INPUT: - - ``degree`` -- Integer with degree (default: 2) - or a tuple of integers with minimum and maximum degrees + - ``degree`` -- integer with degree (default: 2) + or a tuple of integers with minimum and maximum degrees - - ``monic`` -- if ``True``, returns a monic Ore polynomial - (default: ``True``) + - ``monic`` -- if ``True``, returns a monic Ore polynomial + (default: ``True``) - - ``*args, **kwds`` -- passed in to the ``random_element`` method for - the base ring + - ``*args``, ``**kwds`` -- passed in to the ``random_element`` method for + the base ring EXAMPLES:: diff --git a/src/sage/rings/polynomial/padics/polynomial_padic.py b/src/sage/rings/polynomial/padics/polynomial_padic.py index 4103fbf9fe2..30222f0ad59 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic.py @@ -142,7 +142,6 @@ def content(self): sage: f = 13*t^3 + K(0,1)*t sage: f.content() 13 + O(13^8) - """ if self.is_zero(): return self[0] @@ -270,11 +269,11 @@ def root_field(self, names, check_irreducible=True, **kwds): INPUT: - * ``names`` -- name of the generator of the extension + - ``names`` -- name of the generator of the extension - * ``check_irreducible`` -- check whether the polynomial is irreducible + - ``check_irreducible`` -- check whether the polynomial is irreducible - * ``kwds`` -- see :meth:`sage.rings.padics.padic_generic.pAdicGeneric.extension` + - ``kwds`` -- see :meth:`sage.rings.padics.padic_generic.pAdicGeneric.extension` EXAMPLES:: @@ -298,7 +297,6 @@ def root_field(self, names, check_irreducible=True, **kwds): Traceback (most recent call last): ... ValueError: polynomial must be irreducible - """ if check_irreducible and not self.is_irreducible(): @@ -317,7 +315,7 @@ def _pari_padic_factorization_to_sage(G, R, leading_coeff): INPUT: - - ``G`` -- PARI factorization matrix, returned by ``factorpadic``. + - ``G`` -- PARI factorization matrix, returned by ``factorpadic`` - ``R`` -- polynomial ring to be used as parent ring of the factors @@ -325,10 +323,7 @@ def _pari_padic_factorization_to_sage(G, R, leading_coeff): was factored. This can belong to any ring which can be coerced into ``R.base_ring()``. - OUTPUT: - - - A Sage :class:`Factorization`. - + OUTPUT: a Sage :class:`Factorization` """ B = R.base_ring() p = B.prime() diff --git a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py index 5290ef34ed0..668f66fe574 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py @@ -1,6 +1,6 @@ # sage.doctest: needs sage.libs.ntl """ -p-adic Capped Relative Dense Polynomials +`p`-adic Capped Relative Dense Polynomials """ # **************************************************************************** @@ -51,7 +51,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False, ab Check that :issue:`13620` has been fixed:: sage: f = R.zero() - sage: R(f.dict()) + sage: R(f.monomial_coefficients()) 0 Check that :issue:`29829` has been fixed:: @@ -482,7 +482,7 @@ def _sub_(self, right): def _mul_(self, right): r""" - Multiplies ``self`` and ``right``. + Multiply ``self`` and ``right``. ALGORITHM: We use an algorithm thought up by Joe Wetherell to find the precisions of the product. It works as follows: @@ -490,7 +490,7 @@ def _mul_(self, right): = \max(\deg f, \deg g) + 1` (in the actual implementation we use `N = 2^{\lfloor \log_2\max(\deg f, \deg g)\rfloor + 1}`). The valuations and absolute precisions of each coefficient - contribute to the absolute precision of the kth coefficient of + contribute to the absolute precision of the `k`-th coefficient of the product in the following way: for each `i + j = k`, you take the valuation of `a_i` plus the absolute precision of `b_j`, and then take the valuation of `b_j` plus the absolute @@ -623,7 +623,7 @@ def lshift_coeffs(self, shift, no_list=False): def rshift_coeffs(self, shift, no_list=False): """ - Return a new polynomial whose coefficients are p-adically + Return a new polynomial whose coefficients are `p`-adically shifted to the right by ``shift``. .. NOTE:: @@ -668,7 +668,7 @@ def rshift_coeffs(self, shift, no_list=False): def _unsafe_mutate(self, n, value): """ - It's a really bad idea to use this function for p-adic + It's a really bad idea to use this function for `p`-adic polynomials. There are speed issues, and it may not be bug-free currently. """ @@ -752,7 +752,7 @@ def degree(self, secure=False): INPUT: - - ``secure`` -- a boolean (default: ``False``) + - ``secure`` -- boolean (default: ``False``) If ``secure`` is ``True`` and the degree of this polynomial is not determined (because the leading coefficient is @@ -820,9 +820,9 @@ def precision_absolute(self, n=None): INPUT: - - ``self`` -- a p-adic polynomial + - ``self`` -- a `p`-adic polynomial - - ``n`` -- ``None`` or an integer (default ``None``). + - ``n`` -- ``None`` or integer (default: ``None``) OUTPUT: @@ -849,9 +849,9 @@ def precision_relative(self, n=None): INPUT: - - ``self`` -- a p-adic polynomial + - ``self`` -- a `p`-adic polynomial - - ``n`` -- ``None`` or an integer (default ``None``). + - ``n`` -- ``None`` or integer (default: ``None``) OUTPUT: @@ -885,9 +885,9 @@ def valuation_of_coefficient(self, n=None): INPUT: - - ``self`` -- a p-adic polynomial + - ``self`` -- a `p`-adic polynomial - - ``n`` -- ``None`` or an integer (default ``None``). + - ``n`` -- ``None`` or integer (default: ``None``) OUTPUT: @@ -919,14 +919,14 @@ def valuation(self, val_of_var=None): INPUT: - - ``self`` -- a p-adic polynomial + - ``self`` -- a `p`-adic polynomial - - ``val_of_var`` -- ``None`` or a rational (default ``None``). + - ``val_of_var`` -- ``None`` or a rational (default: ``None``) OUTPUT: If ``val_of_var`` is ``None``, returns the largest power of the - variable dividing self. Otherwise, returns the valuation of + variable dividing ``self``. Otherwise, returns the valuation of ``self`` where the variable is assigned valuation ``val_of_var`` EXAMPLES:: @@ -953,8 +953,8 @@ def reverse(self, degree=None): INPUT: - - ``degree`` (``None`` or an integer) -- if specified, truncate or zero - pad the list of coefficients to this degree before reversing it. + - ``degree`` -- ``None`` or integer; if specified, truncate or zero + pad the list of coefficients to this degree before reversing it EXAMPLES:: @@ -1061,7 +1061,6 @@ def quo_rem(self, right, secure=False): sage: R. = Qp(3)[] sage: x.quo_rem(x) (1 + O(3^20), 0) - """ return self._quo_rem_list(right, secure=secure) @@ -1139,9 +1138,7 @@ def newton_polygon(self): If some coefficients have not enough precision an error is raised. - OUTPUT: - - - a :class:`NewtonPolygon` + OUTPUT: a :class:`NewtonPolygon` EXAMPLES:: @@ -1275,11 +1272,9 @@ def newton_slopes(self, repetition=True): INPUT: - - ``repetition`` -- boolean (default ``True``) - - OUTPUT: + - ``repetition`` -- boolean (default: ``True``) - - a list of rationals + OUTPUT: list of rationals EXAMPLES:: diff --git a/src/sage/rings/polynomial/padics/polynomial_padic_flat.py b/src/sage/rings/polynomial/padics/polynomial_padic_flat.py index 46ef0c0a9b9..4db824cd0cc 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic_flat.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic_flat.py @@ -1,5 +1,5 @@ """ -p-adic Flat Polynomials +`p`-adic Flat Polynomials """ # **************************************************************************** diff --git a/src/sage/rings/polynomial/pbori/PyPolyBoRi.py b/src/sage/rings/polynomial/pbori/PyPolyBoRi.py index 18ca366fb85..aa341f35c5d 100644 --- a/src/sage/rings/polynomial/pbori/PyPolyBoRi.py +++ b/src/sage/rings/polynomial/pbori/PyPolyBoRi.py @@ -60,7 +60,7 @@ sage: r = r.clone(names=["z17", "z7"]) sage: [r.variable(idx) for idx in range(3)] [z17, z7, x2] - sage: r = r.clone(names="abcde") + sage: r = r.clone(names='abcde') sage: [r.variable(idx) for idx in range(6)] [a, b, c, d, e, y2] """ @@ -104,7 +104,8 @@ def WeakRingRef(ring): def add_up_polynomials(polys, init): r""" - Adds up the polynomials in polys (which should be a BoolePolynomialVector or a sequence of ??? + Add up the polynomials in polys (which should be a + ``BoolePolynomialVector`` or a sequence of ??? """ if not isinstance(polys, BoolePolynomialVector): vec = BoolePolynomialVector diff --git a/src/sage/rings/polynomial/pbori/blocks.py b/src/sage/rings/polynomial/pbori/blocks.py index 8280fd7db81..dac6ed81303 100644 --- a/src/sage/rings/polynomial/pbori/blocks.py +++ b/src/sage/rings/polynomial/pbori/blocks.py @@ -104,8 +104,8 @@ def g(j): class AdderBlock(AlternatingBlock): - def __init__(self, adder_bits, sums="s", carries="c", input1="a", - input2="b", start_index=0): + def __init__(self, adder_bits, sums='s', carries='c', input1='a', + input2='b', start_index=0): AlternatingBlock.__init__(self, (sums, carries, input1, input2), adder_bits, start_index=start_index, reverse=True) @@ -154,11 +154,14 @@ class HigherOrderBlock: For each dimension a separate start_index and size can be specified. - var_name : variables will be called (multiindex), where multiindex is a tuple of the size + var_name : variables will be called (multiindex), where + multiindex is a tuple of the size - size_tuple : specifies the sizes of the ranges of each component of the multi-indices + size_tuple : specifies the sizes of the ranges of each component of the + multi-indices - start_index_tuple : the multi-indices will be of the form start_index_tuple + a, where a is a multi-index with non-negative components + start_index_tuple : the multi-indices will be of the form + start_index_tuple + a, where a is a multi-index with nonnegative components """ def __init__(self, var_name, size_tuple, start_index_tuple=None, reverse=False): @@ -195,7 +198,7 @@ def var_func(*indices): class InOutBlock: - def __init__(self, out_size, in_size, output="out", input="in", + def __init__(self, out_size, in_size, output='out', input='in', in_start_index=0, out_start_index=0, out_reverse=False, in_reverse=False): self.output = Block(var_name=output, start_index=out_start_index, diff --git a/src/sage/rings/polynomial/pbori/gbcore.py b/src/sage/rings/polynomial/pbori/gbcore.py index 836d5f7a2a6..8371577157d 100644 --- a/src/sage/rings/polynomial/pbori/gbcore.py +++ b/src/sage/rings/polynomial/pbori/gbcore.py @@ -356,7 +356,6 @@ def other_ordering_pre(I, option_set, kwds): sage: from sage.rings.polynomial.pbori.gbcore import groebner_basis sage: groebner_basis(id) [1] - """ if not I: return (I, None) @@ -541,7 +540,7 @@ def groebner_basis(I, heuristic=True, unique_ideal_generator=False, fglm_bound=40000, modified_linear_algebra=True, preprocessor=None, deg_bound=False, - implementation="Python", full_prot=False, prot=False, + implementation='Python', full_prot=False, prot=False, draw_matrices=False, preprocess_only=False, **impl_options): """Computes a Groebner basis of a given ideal I, w.r.t options.""" diff --git a/src/sage/rings/polynomial/pbori/gbrefs.py b/src/sage/rings/polynomial/pbori/gbrefs.py index 0f5436c5b5f..4ac92f359c2 100644 --- a/src/sage/rings/polynomial/pbori/gbrefs.py +++ b/src/sage/rings/polynomial/pbori/gbrefs.py @@ -38,7 +38,7 @@ def load_ref_raw(s): return res -def load_ref(s, ordering="lp", blocks=SINGLE): +def load_ref(s, ordering='lp', blocks=SINGLE): return load_ref_gz_uu(s, ordering, blocks) @@ -68,7 +68,7 @@ def load_ref_gz_uu(s, o, b): uu.decode(ref_file, res) res = res.getvalue() res = StringIO(res) - res = gzip.GzipFile(fileobj=res, mode="r").read() + res = gzip.GzipFile(fileobj=res, mode='r').read() res = res.replace(" ", "") return res @@ -77,7 +77,7 @@ def convert_refs(ref_file_orig): with open(ref_file_orig) as file: content = file.read() buf_out = StringIO() - zipped = gzip.GzipFile(filename=ref_file_orig, mode="w", fileobj=buf_out) + zipped = gzip.GzipFile(filename=ref_file_orig, mode='w', fileobj=buf_out) zipped.write(content) zipped.close() val = buf_out.getvalue() @@ -107,7 +107,7 @@ def clean_data(data): delattr(data, a) -def load_data(file_name, base_dir="./"): +def load_data(file_name, base_dir='./'): in_file = file_name if not re.match("^data", in_file): in_file = "data/" + in_file diff --git a/src/sage/rings/polynomial/pbori/ll.py b/src/sage/rings/polynomial/pbori/ll.py index 5292050d6a7..9ec3a57bb4c 100644 --- a/src/sage/rings/polynomial/pbori/ll.py +++ b/src/sage/rings/polynomial/pbori/ll.py @@ -79,7 +79,7 @@ def eliminate(polys, on_the_fly=False, prot=False, reduction_function=None, lm = p.lex_lead() if lm.deg() == 1: - if not (lm in linear_leading_monomials): + if lm not in linear_leading_monomials: linear_leading_monomials.add(lm) linear_leads.append(p) else: diff --git a/src/sage/rings/polynomial/pbori/meson.build b/src/sage/rings/polynomial/pbori/meson.build new file mode 100644 index 00000000000..c7541ae492d --- /dev/null +++ b/src/sage/rings/polynomial/pbori/meson.build @@ -0,0 +1,42 @@ +brial = cc.find_library('brial', required: false, disabler: true) +# Cannot be found via pkg-config +brial_groebner = cc.find_library('brial_groebner') + +py.install_sources( + 'PyPolyBoRi.py', + '__init__.py', + 'blocks.py', + 'cnf.py', + 'easy_polynomials.py', + 'fglm.py', + 'frontend.py', + 'gbcore.py', + 'gbrefs.py', + 'heuristics.py', + 'interpolate.py', + 'interred.py', + 'll.py', + 'nf.py', + 'parallel.py', + 'pbori.pxd', + 'randompoly.py', + 'rank.py', + 'specialsets.py', + 'statistics.py', + subdir: 'sage/rings/polynomial/pbori', +) + +extension_data_cpp = {'pbori': files('pbori.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/polynomial/pbori', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_ext, inc_rings, inc_src], + dependencies: [py_dep, brial, brial_groebner, cysignals, gmp, m4ri, png], + ) +endforeach + diff --git a/src/sage/rings/polynomial/pbori/nf.py b/src/sage/rings/polynomial/pbori/nf.py index 0148826e033..004abef5243 100644 --- a/src/sage/rings/polynomial/pbori/nf.py +++ b/src/sage/rings/polynomial/pbori/nf.py @@ -591,7 +591,7 @@ def symmGB_F2_C(G, opt_exchange=True, opt_allow_recursion=False, use_noro=False, use_faugere=False, ll=False, opt_linear_algebra_in_last_block=True, max_generators=None, red_tail_deg_growth=True, - modified_linear_algebra=True, matrix_prefix="", + modified_linear_algebra=True, matrix_prefix='', draw_matrices=False): if use_noro: raise NotImplementedError("noro not implemented for symmgb") diff --git a/src/sage/rings/polynomial/pbori/parallel.py b/src/sage/rings/polynomial/pbori/parallel.py index 32eb3894312..134ee6b2adb 100644 --- a/src/sage/rings/polynomial/pbori/parallel.py +++ b/src/sage/rings/polynomial/pbori/parallel.py @@ -19,7 +19,7 @@ def to_fast_pickable(l): INPUT: - - a list of Boolean polynomials + - ``l`` -- a list of Boolean polynomials OUTPUT: @@ -111,11 +111,9 @@ def from_fast_pickable(l, r): INPUT: - See OUTPUT of :func:`to_fast_pickable` + See OUTPUT of :func:`to_fast_pickable`. - OUTPUT: - - a list of Boolean polynomials + OUTPUT: list of Boolean polynomials EXAMPLES:: @@ -266,7 +264,8 @@ def groebner_basis_first_finished(I, *l): INPUT: - ``I`` -- ideal - - ``l`` -- keyword dictionaries, which will be keyword arguments to groebner_basis. + - ``l`` -- keyword dictionaries, which will be keyword arguments to + ``groebner_basis`` OUTPUT: diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 3c06d1e390e..686edf8892d 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -56,7 +56,6 @@ AUTHORS: to improve compatibility with MPolynomial and make the variety() function work on ideals of BooleanPolynomial's. - EXAMPLES: Consider the ideal @@ -258,9 +257,9 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``n`` -- number of variables (an integer > 1) + - ``n`` -- integer > 1; number of variables - - ``names`` -- names of ring variables, may be a string or + - ``names`` -- names of ring variables; may be a string or list/tuple - ``order`` -- term order (default: lex) @@ -473,7 +472,7 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): R = I.ring() return QuotientFunctor(I, names=self.variable_names(), domain=R.category(), codomain=self.category(), - implementation="pbori", + implementation='pbori', order=self.term_order()), R def ngens(self): @@ -496,11 +495,11 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): def gen(self, i=0): """ - Return the i-th generator of this boolean polynomial ring. + Return the `i`-th generator of this boolean polynomial ring. INPUT: - - ``i`` -- an integer or a boolean monomial in one variable + - ``i`` -- integer or a boolean monomial in one variable EXAMPLES:: @@ -569,7 +568,7 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): sage: P. = BooleanPolynomialRing() sage: P.term_order() Lexicographic term order - sage: R = P.change_ring(names=('a', 'b', 'c'), order="deglex") + sage: R = P.change_ring(names=('a', 'b', 'c'), order='deglex') sage: R Boolean PolynomialRing in a, b, c sage: R.term_order() @@ -1093,10 +1092,10 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``gens`` -- list or tuple of generators + - ``gens`` -- list or tuple of generators - - ``coerce`` -- bool (default: ``True``) automatically - coerce the given polynomials to this ring to form the ideal + - ``coerce`` -- boolean (default: ``True``); automatically + coerce the given polynomials to this ring to form the ideal EXAMPLES:: @@ -1126,18 +1125,17 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``degree`` -- maximum degree (default: 2 for len(var_set) > 1, 1 otherwise) - - - ``terms`` -- number of terms requested (default: 5). If more - terms are requested than exist, then this parameter is - silently reduced to the maximum number of available terms. + - ``degree`` -- maximum degree (default: 2 for len(var_set) > 1, 1 otherwise) - - ``choose_degree`` -- choose degree of monomials - randomly first, rather than monomials uniformly random + - ``terms`` -- number of terms requested (default: 5). If more + terms are requested than exist, then this parameter is + silently reduced to the maximum number of available terms. - - ``vars_set`` -- list of integer indices of - generators of self to use in the generated polynomial + - ``choose_degree`` -- choose degree of monomials + randomly first, rather than monomials uniformly random + - ``vars_set`` -- list of integer indices of + generators of ``self`` to use in the generated polynomial EXAMPLES:: @@ -1262,18 +1260,18 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``degree`` -- maximum degree + - ``degree`` -- maximum degree - - ``monom_counts`` -- a list containing total number - of monomials up to given degree + - ``monom_counts`` -- list containing total number + of monomials up to given degree - - ``vars_set`` -- list of variable indices to use in - the generated polynomial + - ``vars_set`` -- list of variable indices to use in + the generated polynomial - - ``dfirst`` -- if ``True`` choose degree - first, otherwise choose the monomial uniformly + - ``dfirst`` -- if ``True`` choose degree + first, otherwise choose the monomial uniformly - - ``l`` -- number of monomials to generate + - ``l`` -- number of monomials to generate EXAMPLES:: @@ -1298,15 +1296,15 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): def _random_monomial_uniform(self, monom_counts, vars_set): r""" Choose a random monomial uniformly from set of monomials in the - variables indexed by ``vars_set`` in self. + variables indexed by ``vars_set`` in ``self``. INPUT: - - ``monom_counts`` -- list of number of monomials up - to given degree + - ``monom_counts`` -- list of number of monomials up + to given degree - - ``vars_set`` -- list of variable indices to use in - the generated monomial + - ``vars_set`` -- list of variable indices to use in + the generated monomial EXAMPLES:: @@ -1346,9 +1344,9 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``degree`` -- maximum degree + - ``degree`` -- maximum degree - - ``vars_set`` -- list of variable indices of self + - ``vars_set`` -- list of variable indices of self EXAMPLES:: @@ -1445,7 +1443,7 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``magma`` -- a magma instance + - ``magma`` -- a magma instance EXAMPLES:: @@ -1474,11 +1472,9 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): INPUT: - - ``zeros`` -- the set of interpolation points mapped - to zero + - ``zeros`` -- the set of interpolation points mapped to zero - - ``ones`` -- the set of interpolation points mapped to - one + - ``ones`` -- the set of interpolation points mapped to one EXAMPLES: @@ -1585,11 +1581,11 @@ cdef class BooleanPolynomialRing(BooleanPolynomialRing_base): def variable(self, i=0): """ - Return the i-th generator of this boolean polynomial ring. + Return the `i`-th generator of this boolean polynomial ring. INPUT: - - ``i`` -- an integer or a boolean monomial in one variable + - ``i`` -- integer or a boolean monomial in one variable EXAMPLES:: @@ -1803,7 +1799,7 @@ def get_var_mapping(ring, other): other. If it is an element, only variables occurring in other are mapped. - Raises ``NameError`` if no such mapping is possible. + Raises :exc:`NameError` if no such mapping is possible. EXAMPLES:: @@ -1879,7 +1875,6 @@ class BooleanMonomialMonoid(UniqueRepresentation, Monoid_class): sage: loads(dumps(M)) is M True sage: TestSuite(M).run() - """ def __init__(self, BooleanPolynomialRing polring): """ @@ -1949,11 +1944,11 @@ class BooleanMonomialMonoid(UniqueRepresentation, Monoid_class): def gen(self, Py_ssize_t i=0): """ - Return the i-th generator of ``self``. + Return the `i`-th generator of ``self``. INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -2027,7 +2022,7 @@ class BooleanMonomialMonoid(UniqueRepresentation, Monoid_class): x Convert elements from :class:`BooleanMonomialMonoid` where the - generators of self include the generators of the other monoid:: + generators of ``self`` include the generators of the other monoid:: sage: from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid sage: R. = BooleanPolynomialRing(2) @@ -2133,7 +2128,6 @@ class BooleanMonomialMonoid(UniqueRepresentation, Monoid_class): sage: M((0,2,0)) x*z - """ cdef BooleanMonomial m cdef PBMonom t @@ -2255,7 +2249,7 @@ cdef class BooleanMonomial(MonoidElement): def __reduce__(self): """ - Pickling + Pickling. TESTS:: @@ -2521,7 +2515,7 @@ cdef class BooleanMonomial(MonoidElement): INPUT: - - ``rhs`` -- a boolean monomial + - ``rhs`` -- boolean monomial EXAMPLES:: @@ -2549,7 +2543,7 @@ cdef class BooleanMonomial(MonoidElement): INPUT: - - ``rhs`` -- a boolean monomial + - ``rhs`` -- boolean monomial EXAMPLES:: @@ -2621,7 +2615,7 @@ cdef class BooleanMonomial(MonoidElement): def iterindex(self): """ - Return an iterator over the indices of the variables in self. + Return an iterator over the indices of the variables in ``self``. EXAMPLES:: @@ -2785,7 +2779,7 @@ cdef class BooleanMonomial(MonoidElement): INPUT: - - ``rhs`` -- a boolean monomial + - ``rhs`` -- boolean monomial EXAMPLES:: @@ -2932,7 +2926,7 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``parent`` -- a boolean polynomial ring + - ``parent`` -- boolean polynomial ring TESTS:: @@ -3513,7 +3507,7 @@ cdef class BooleanPolynomial(MPolynomial): def is_one(BooleanPolynomial self): """ - Check if self is 1. + Check if ``self`` is 1. EXAMPLES:: @@ -3697,7 +3691,7 @@ cdef class BooleanPolynomial(MPolynomial): multivariate polynomial. If this polynomial is not in at most one variable, then a - ``ValueError`` exception is raised. This is checked using the + :exc:`ValueError` exception is raised. This is checked using the :meth:`is_univariate()` method. The new Polynomial is over GF(2) and in the variable ``x`` if no ring ``R`` is provided. @@ -3761,7 +3755,7 @@ cdef class BooleanPolynomial(MPolynomial): def variable(self, i=0): """ - Return the i-th variable occurring in self. The index i is the + Return the i-th variable occurring in ``self``. The index i is the index in ``self.variables()`` EXAMPLES:: @@ -3802,7 +3796,7 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``mon`` -- a monomial + - ``mon`` -- a monomial EXAMPLES:: @@ -3962,10 +3956,9 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``in_dict`` -- (optional) dict with variable:value - pairs + - ``in_dict`` -- (optional) dict with variable:value pairs - - ``**kwds`` -- names parameters + - ``**kwds`` -- names parameters EXAMPLES:: @@ -4053,7 +4046,7 @@ cdef class BooleanPolynomial(MPolynomial): def _magma_init_(self, magma): r""" - Return the Magma representation of self. + Return the Magma representation of ``self``. EXAMPLES:: @@ -4314,7 +4307,6 @@ cdef class BooleanPolynomial(MPolynomial): a*b + a + b + z + 1 sage: f(a+1,b+1,z+1) a*b + a + b + z + 1 - """ return new_BP_from_PBPoly(self._parent, pb_map_every_x_to_x_plus_one(self._pbpoly)) @@ -4363,7 +4355,7 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``rhs`` -- a boolean polynomial + - ``rhs`` -- boolean polynomial EXAMPLES:: @@ -4426,7 +4418,7 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``deg`` -- a degree + - ``deg`` -- a degree EXAMPLES:: @@ -4480,7 +4472,7 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``s`` -- candidate points for evaluation to zero + - ``s`` -- candidate points for evaluation to zero EXAMPLES:: @@ -4589,8 +4581,8 @@ cdef class BooleanPolynomial(MPolynomial): INPUT: - - ``I`` -- a list/set of polynomials in self.parent(). - If I is an ideal, the generators are used. + - ``I`` -- list/set of polynomials in ``self.parent()``; if I is an + ideal, the generators are used EXAMPLES:: @@ -4643,7 +4635,7 @@ cdef class BooleanPolynomial(MPolynomial): cdef class PolynomialConstruct: """ - Implements PolyBoRi's ``Polynomial()`` constructor. + Implement PolyBoRi's ``Polynomial()`` constructor. """ def lead(self, x): """ @@ -4694,7 +4686,7 @@ cdef class PolynomialConstruct: cdef class MonomialConstruct: """ - Implements PolyBoRi's ``Monomial()`` constructor. + Implement PolyBoRi's ``Monomial()`` constructor. """ def __call__(self, x): """ @@ -4732,7 +4724,7 @@ cdef class MonomialConstruct: cdef class VariableConstruct: """ - Implements PolyBoRi's ``Variable()`` constructor. + Implement PolyBoRi's ``Variable()`` constructor. """ def __call__(self, arg, ring=None): """ @@ -4813,9 +4805,9 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): INPUT: - - ``ring`` -- the ring this ideal is defined in + - ``ring`` -- the ring this ideal is defined in - - ``gens`` -- a list of generators + - ``gens`` -- list of generators - ``coerce`` -- coerce all elements to the ring ``ring`` (default: ``True``) @@ -4827,7 +4819,6 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): Ideal (x0*x1*x2*x3 + x0*x1*x3 + x0*x1 + x0*x2 + x0) of Boolean PolynomialRing in x0, x1, x2, x3 sage: loads(dumps(I)) == I True - """ MPolynomialIdeal.__init__(self, ring, gens, coerce) @@ -4853,16 +4844,15 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): INPUT: - - ``algorithm`` -- either ``"polybori"`` (built-in default) - or ``"magma"`` (requires Magma). + - ``algorithm`` -- either ``'polybori'`` (built-in default) + or ``'magma'`` (requires Magma) - ``red_tail`` -- tail reductions in intermediate polynomials, this options affects mainly heuristics. The reducedness of the output polynomials can only be guaranteed by the option - redsb (default: ``True``) + redsb (default: ``True``). - - ``minsb`` -- return a minimal Groebner basis (default: - ``True``) + - ``minsb`` -- return a minimal Groebner basis (default: ``True``) - ``redsb`` -- return a minimal Groebner basis and all tails are reduced (default: ``True``) @@ -4870,8 +4860,7 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): - ``deg_bound`` -- only compute Groebner basis up to a given degree bound (default: ``False``) - - ``faugere`` -- turn off or on the linear algebra (default: - ``False``) + - ``faugere`` -- turn off or on the linear algebra (default: ``False``) - ``linear_algebra_in_last_block`` -- this affects the last block of block orderings and degree orderings. If it is set @@ -4879,12 +4868,12 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): block. (default: ``True``) - ``gauss_on_linear`` -- perform Gaussian elimination on linear - polynomials (default: ``True``) + polynomials (default: ``True``) - ``selection_size`` -- maximum number of polynomials for parallel reductions (default: ``1000``) - - ``heuristic`` -- Turn off heuristic by setting + - ``heuristic`` -- turn off heuristic by setting ``heuristic=False`` (default: ``True``) - ``lazy`` -- (default: ``True``) @@ -4981,7 +4970,6 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): ....: s0s0 + s2s0 + s3s0*s3s1 + s3s0 + 1, s0s0 + s1s1] sage: ideal(problem).groebner_basis() [1] - """ try: return Sequence(sorted(self.__gb, reverse=True), self.ring(), check=False, immutable=True) @@ -5007,7 +4995,7 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): def _groebner_basis(self, **kwds): r""" - Calls PolyBoRi's groebner_basis function. It takes care of the import + Call PolyBoRi's groebner_basis function. It takes care of the import and suitable wrapping (if necessary) EXAMPLES:: @@ -5088,7 +5076,6 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): sage: sols[0]["y"] 1 - """ from sage.misc.converting_dict import KeyConvertingDict R_bool = self.ring() @@ -5134,8 +5121,8 @@ class BooleanPolynomialIdeal(MPolynomialIdeal): If this ideal is spanned by ``(f_1, ..., f_n)`` this method returns ``(g_1, ..., g_s)`` such that: - - `` = `` - - ``LT(g_i) != LT(g_j)`` for all ``i != j``` + - `` = `` + - ``LT(g_i) != LT(g_j)`` for all ``i != j`` - ``LT(g_i)`` does not divide ``m`` for all monomials ``m`` of ``{g_1,...,g_{i-1},g_{i+1},...,g_s}`` @@ -5266,8 +5253,9 @@ cdef class BooleSet: INPUT: - - ``param`` -- either a :class:`CCuddNavigator`, a :class:`BooleSet` or ``None``. - - ``ring`` -- a boolean polynomial ring. + - ``param`` -- either a :class:`CCuddNavigator`, a :class:`BooleSet` or + ``None`` + - ``ring`` -- boolean polynomial ring EXAMPLES:: @@ -5461,7 +5449,6 @@ cdef class BooleSet: X \ Y = \{x | x\in X\;\mathrm{and}\;x\not\in Y\}. - EXAMPLES:: sage: B = BooleanPolynomialRing(5,'x') @@ -5495,7 +5482,6 @@ cdef class BooleSet: X \cup Y = \{x | x\in X\;\mathrm{or}\;x\in Y\}. - EXAMPLES:: sage: B = BooleanPolynomialRing(5,'x') @@ -5572,7 +5558,7 @@ cdef class BooleSet: def __iter__(self): """ - Create an iterator over elements of self. + Create an iterator over elements of ``self``. EXAMPLES:: @@ -5618,7 +5604,7 @@ cdef class BooleSet: INPUT: - - ``vs`` -- a boolean set + - ``vs`` -- boolean set EXAMPLES:: @@ -5797,7 +5783,6 @@ cdef class BooleSet: X \cap Y = \{x | x\in X\;\mathrm{and}\;x\in Y\}. - EXAMPLES:: sage: B = BooleanPolynomialRing(5,'x') @@ -5819,7 +5804,7 @@ cdef class BooleSet: INPUT: - - ``m`` -- a boolean monomial + - ``m`` -- boolean monomial EXAMPLES:: @@ -5838,7 +5823,7 @@ cdef class BooleSet: INPUT: - - ``m`` -- a boolean monomial + - ``m`` -- boolean monomial EXAMPLES:: @@ -5997,7 +5982,7 @@ cdef class BooleanPolynomialVector: INPUT: - - ``I`` -- a list of boolean polynomials. + - ``I`` -- list of boolean polynomials EXAMPLES:: @@ -6191,7 +6176,7 @@ cdef class ReductionStrategy: INPUT: - - ``p`` -- a boolean polynomial. + - ``p`` -- boolean polynomial EXAMPLES:: @@ -6316,7 +6301,7 @@ cdef class ReductionStrategy: INPUT: - - ``p`` -- a boolean polynomial + - ``p`` -- boolean polynomial EXAMPLES:: @@ -6529,11 +6514,9 @@ cdef class GroebnerStrategy: """ def __init__(self, param): """ - INPUT: - - ``param`` -- either ``None`` or a :class:`GroebnerStrategy` - object. + - ``param`` -- either ``None`` or a :class:`GroebnerStrategy` object EXAMPLES:: @@ -6708,7 +6691,7 @@ cdef class GroebnerStrategy: INPUT: - - ``v`` -- a boolean polynomial vector + - ``v`` -- boolean polynomial vector EXAMPLES:: @@ -6811,7 +6794,7 @@ cdef class GroebnerStrategy: def variable_has_value(self, int v): """ - Computes, whether there exists some polynomial of the form + Compute whether there exists some polynomial of the form `v+c` in the Strategy -- where ``c`` is a constant -- in the list of generators. @@ -6852,7 +6835,7 @@ cdef class GroebnerStrategy: INPUT: - - ``p`` -- a boolean polynomial + - ``p`` -- boolean polynomial EXAMPLES:: @@ -6879,7 +6862,6 @@ cdef class GroebnerStrategy: The result is only canonical if the generating set is a Groebner basis. - """ return new_BP_from_PBPoly(self._parent, deref(self._strat).nf(p._pbpoly)) @@ -7126,9 +7108,9 @@ def zeros(pol, BooleSet s): INPUT: - - ``pol`` -- a boolean polynomial + - ``pol`` -- boolean polynomial - - ``s`` -- a set of points encoded as a ``BooleSet`` + - ``s`` -- set of points encoded as a ``BooleSet`` EXAMPLES:: @@ -7324,10 +7306,10 @@ def ll_red_nf_redsb(p, BooleSet reductors): INPUT: - - ``p`` -- a boolean polynomial + - ``p`` -- boolean polynomial - - ``reductors`` -- a boolean set encoding a reduced Groebner basis - with linear leading terms. + - ``reductors`` -- boolean set encoding a reduced Groebner basis + with linear leading terms EXAMPLES:: @@ -7366,10 +7348,10 @@ def ll_red_nf_noredsb(BooleanPolynomial p, BooleSet reductors): INPUT: - - ``p`` -- a boolean polynomial + - ``p`` -- boolean polynomial - - ``reductors`` -- a boolean set encoding a Groebner basis with - linear leading terms. + - ``reductors`` -- boolean set encoding a Groebner basis with + linear leading terms EXAMPLES:: @@ -7399,10 +7381,10 @@ def ll_red_nf_noredsb_single_recursive_call(BooleanPolynomial p, BooleSet reduct INPUT: - - ``p`` -- a boolean polynomial + - ``p`` -- boolean polynomial - - ``reductors`` -- a boolean set encoding a Groebner basis with - linear leading terms. + - ``reductors`` -- boolean set encoding a Groebner basis with + linear leading terms EXAMPLES:: @@ -7439,7 +7421,7 @@ def if_then_else(root, a, b): INPUT: - - ``root`` -- a variable + - ``root`` -- a variable - ``a`` -- the if branch, a ``BooleSet`` or a ``BoolePolynomial`` @@ -7741,7 +7723,7 @@ def easy_linear_factors(BooleanPolynomial p): # todo: merge with pickling from sage.rings.polynomial.pbori.parallel def unpickle_BooleanPolynomial(ring, string): """ - Unpickle boolean polynomials + Unpickle boolean polynomials. EXAMPLES:: @@ -7792,7 +7774,7 @@ cdef class BooleConstant: INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -7809,7 +7791,6 @@ cdef class BooleConstant: sage: from sage.rings.polynomial.pbori.pbori import BooleConstant sage: repr((BooleConstant(0),BooleConstant(1))) # indirect doctest '(0, 1)' - """ if self.is_one(): return '1' @@ -7942,7 +7923,6 @@ cdef class VariableFactory: sage: B. = BooleanPolynomialRing() sage: fac = VariableFactory() sage: fac = VariableFactory(B) - """ if ring is not None: self._factory = PBVariableFactory(ring._pbring) @@ -7978,17 +7958,15 @@ cdef class VariableFactory: cdef class MonomialFactory: """ - Implements PolyBoRi's ``Monomial()`` constructor. If a ring is given is + Implement PolyBoRi's ``Monomial()`` constructor. If a ring is given is can be used as a Monomial factory for the given ring. - EXAMPLES:: sage: from sage.rings.polynomial.pbori.pbori import * sage: B. = BooleanPolynomialRing() sage: fac = MonomialFactory() sage: fac = MonomialFactory(B) - """ def __init__(self, BooleanPolynomialRing ring=None): """ @@ -8053,12 +8031,12 @@ cdef class MonomialFactory: cdef class PolynomialFactory: """ - Implements PolyBoRi's ``Polynomial()`` constructor and + Implement PolyBoRi's ``Polynomial()`` constructor and a polynomial factory for given rings. """ def __init__(self, BooleanPolynomialRing ring=None): """ - Constructs a polynomial factory if ring is given, + Construct a polynomial factory if ring is given, or plain constructor otherwise. EXAMPLES:: @@ -8066,7 +8044,6 @@ cdef class PolynomialFactory: sage: from sage.rings.polynomial.pbori.pbori import * sage: B. = BooleanPolynomialRing() sage: fac = PolynomialFactory() - """ if ring is not None: self._factory = PBPolynomialFactory(ring._pbring) @@ -8101,7 +8078,6 @@ cdef class PolynomialFactory: a sage: PolynomialFactory(B)(1) 1 - """ if self._ring is None: if isinstance(arg, BooleanPolynomial): diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index d78464e1deb..35de7feefe5 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -157,7 +157,7 @@ class G_AlgFactory(UniqueFactory): - ``key`` -- a 6-tuple, formed by a base ring, a tuple of names, two matrices over a polynomial ring over the base ring with the given variable names, a term order, and a category - - ``extra_args`` -- a dictionary, whose only relevant key is 'check'. + - ``extra_args`` -- dictionary, whose only relevant key is 'check' TESTS:: @@ -174,7 +174,7 @@ class G_AlgFactory(UniqueFactory): category, check) def create_key_and_extra_args(self, base_ring, c, d, names=None, order=None, - category=None, check=None): + category=None, check=None, commutative=None): """ Create a unique key for g-algebras. @@ -182,10 +182,11 @@ class G_AlgFactory(UniqueFactory): - ``base_ring`` -- a ring - ``c``, ``d`` -- two matrices - - ``names`` -- a tuple or list of names + - ``names`` -- tuple or list of names - ``order`` -- (optional) term order - ``category`` -- (optional) category - - ``check`` -- optional bool + - ``check`` -- (optional) boolean + - ``commutative`` -- (optional) boolean TESTS:: @@ -193,6 +194,10 @@ class G_AlgFactory(UniqueFactory): sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) # indirect doctest True + + sage: P = A.g_algebra(relations={}, order='lex') + sage: P.category() + Category of commutative algebras over Rational Field """ if names is None: raise ValueError("The generator names must be provided") @@ -213,7 +218,11 @@ class G_AlgFactory(UniqueFactory): d.set_immutable() # Get the correct category - category = check_default_category(Algebras(base_ring), category) + if commutative: + usualcat = Algebras(base_ring).Commutative() + else: + usualcat = Algebras(base_ring) + category = check_default_category(usualcat, category) # Extra arg if check is None: @@ -252,7 +261,7 @@ cdef class NCPolynomialRing_plural(Ring): INPUT: - ``base_ring`` -- base ring (must be either `\GF{q}`, `\ZZ`, `\ZZ/n\ZZ`, `\QQ` or absolute number field) - - ``names`` -- a tuple of names of ring variables + - ``names`` -- tuple of names of ring variables - ``c``, ``d`` -- upper triangular matrices of coefficients, resp. commutative polynomials, satisfying the nondegeneracy conditions, which are to be tested if ``check`` is ``True``. These @@ -758,7 +767,7 @@ cdef class NCPolynomialRing_plural(Ring): INPUT: - ``add_commutative`` (optional bool, default ``False``) + - ``add_commutative`` -- boolean (default: ``False``) OUTPUT: @@ -829,7 +838,7 @@ cdef class NCPolynomialRing_plural(Ring): INPUT: - - ``n`` -- an integer ``>= 0`` + - ``n`` -- nonnegative integer EXAMPLES:: @@ -842,7 +851,6 @@ cdef class NCPolynomialRing_plural(Ring): sage: P.gen(1) is P.gen(1) False - """ cdef poly *_p cdef ring *_ring = self._ring @@ -878,7 +886,7 @@ cdef class NCPolynomialRing_plural(Ring): INPUT: - ``*gens`` -- list or tuple of generators (or several input arguments) - - ``coerce`` -- bool (default: ``True``); this must be a + - ``coerce`` -- boolean (default: ``True``); this must be a keyword argument. Only set it to ``False`` if you are certain that each generator is already in the ring. - ``side`` -- string (either "left", which is the default, or "twosided") @@ -892,7 +900,7 @@ cdef class NCPolynomialRing_plural(Ring): sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x]) Left Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} - sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x], side="twosided") + sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x], side='twosided') Twosided Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} """ coerce = kwds.get('coerce', True) @@ -1348,9 +1356,7 @@ cdef class NCPolynomialRing_plural(Ring): - ``t`` -- a monomial - OUTPUT: - - a list of monomials + OUTPUT: list of monomials EXAMPLES:: @@ -1390,7 +1396,6 @@ def unpickle_NCPolynomial_plural(NCPolynomialRing_plural R, d): sage: p = x*y+2*z+4*x*y*z*x sage: loads(dumps(p)) == p # indirect doctest True - """ cdef ring *r = R._ring cdef poly *m @@ -1398,7 +1403,7 @@ def unpickle_NCPolynomial_plural(NCPolynomialRing_plural R, d): cdef int _i, _e p = p_ISet(0,r) rChangeCurrRing(r) - for mon,c in d.iteritems(): + for mon, c in d.items(): m = p_Init(r) for i,e in mon.sparse_iter(): _i = i @@ -1452,7 +1457,6 @@ cdef class NCPolynomial_plural(RingElement): sage: H. = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) sage: loads(dumps(x*y+2*z+4*x*y*z*x)) 4*x^2*y*z + 8*x^2*y - 4*x*z^2 + x*y - 8*x*z + 2*z - """ return unpickle_NCPolynomial_plural, (self._parent, self.dict()) @@ -1532,7 +1536,7 @@ cdef class NCPolynomial_plural(RingElement): cpdef _add_(left, right): """ - Adds left and right. + Add ``left`` and ``right``. EXAMPLES:: @@ -1561,7 +1565,6 @@ cdef class NCPolynomial_plural(RingElement): Defining x, z, y sage: 3/2*x - 1/2*y - 1 # indirect doctest 3/2*x - 1/2*y - 1 - """ cdef ring *_ring = (left._parent)._ring @@ -1634,7 +1637,7 @@ cdef class NCPolynomial_plural(RingElement): cpdef _div_(left, right): """ - Divide left by right + Divide ``left`` by ``right``. EXAMPLES:: @@ -1668,7 +1671,7 @@ cdef class NCPolynomial_plural(RingElement): else: return (left._parent).fraction_field()(left,right) - def __pow__(NCPolynomial_plural self, exp, ignored): + def __pow__(NCPolynomial_plural self, exp, mod): """ Return ``self**(exp)``. @@ -1694,7 +1697,22 @@ cdef class NCPolynomial_plural(RingElement): Traceback (most recent call last): .... OverflowError: exponent overflow (2147483648) + + Check that using third argument raises an error:: + + sage: A. = FreeAlgebra(QQ, 3) + sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex') + sage: P.inject_variables() + Defining x, z, y + sage: pow(x + y + z, 2, x) + Traceback (most recent call last): + ... + NotImplementedError: pow() with a modulus is not implemented for this ring """ + if mod is not None: + raise NotImplementedError( + "pow() with a modulus is not implemented for this ring" + ) if type(exp) is not Integer: try: exp = Integer(exp) @@ -1760,8 +1778,6 @@ cdef class NCPolynomial_plural(RingElement): Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} sage: sorted(I.std().gens(),key=str) [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1] - - """ cdef ideal *_I cdef NCPolynomialRing_plural parent = self._parent @@ -1887,9 +1903,7 @@ cdef class NCPolynomial_plural(RingElement): self) If x is not specified (or is ``None``), return the total degree, which is the maximum degree of any monomial. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -1917,7 +1931,6 @@ cdef class NCPolynomial_plural(RingElement): -1 sage: P(1).degree(x) 0 - """ cdef ring *r = (self._parent)._ring cdef poly *p = self._poly @@ -2022,14 +2035,12 @@ cdef class NCPolynomial_plural(RingElement): INPUT: - - ``degrees`` -- Can be any of: - - a dictionary of degree restrictions - - a list of degree restrictions (with None in the unrestricted variables) - - a monomial (very fast, but not as flexible) - - OUTPUT: + - ``degrees`` -- can be any of: + - a dictionary of degree restrictions + - a list of degree restrictions (with ``None`` in the unrestricted variables) + - a monomial (very fast, but not as flexible) - element of the parent of this element. + OUTPUT: element of the parent of this element .. NOTE:: @@ -2147,9 +2158,7 @@ cdef class NCPolynomial_plural(RingElement): - ``mon`` -- a monomial - OUTPUT: - - coefficient in base ring + OUTPUT: coefficient in base ring .. SEEALSO:: @@ -2209,6 +2218,9 @@ cdef class NCPolynomial_plural(RingElement): sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3)) sage: f.dict() {(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7} + + sage: f.monomial_coefficients() + {(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7} """ cdef poly *p cdef ring *r @@ -2240,7 +2252,7 @@ cdef class NCPolynomial_plural(RingElement): INPUT: - * "copy" -- ignored + - ``copy`` -- ignored EXAMPLES:: @@ -2265,9 +2277,9 @@ cdef class NCPolynomial_plural(RingElement): INPUT: - - ``codomain`` -- The parent where the images live + - ``codomain`` -- the parent where the images live - - ``im_gens`` -- A list or tuple with the images of the generators of this ring. + - ``im_gens`` -- list or tuple with the images of the generators of this ring EXAMPLES:: @@ -2347,8 +2359,8 @@ cdef class NCPolynomial_plural(RingElement): INPUT: - - ``x`` -- a tuple or, in case of a single-variable MPolynomial - ring ``x`` can also be an integer. + - ``x`` -- tuple or, in case of a single-variable MPolynomial + ring ``x`` can also be an integer EXAMPLES:: @@ -2365,7 +2377,7 @@ cdef class NCPolynomial_plural(RingElement): sage: f[0,0,0] 0 - sage: R. = PolynomialRing(GF(7), implementation="singular"); R + sage: R. = PolynomialRing(GF(7), implementation='singular'); R Multivariate Polynomial Ring in x over Finite Field of size 7 sage: f = 5*x^2 + 3; f -2*x^2 + 3 @@ -2411,9 +2423,8 @@ cdef class NCPolynomial_plural(RingElement): INPUT: - - ``as_ETuples`` -- (default: ``True``) if ``True`` returns the result as an list of ETuples - otherwise returns a list of tuples - + - ``as_ETuples`` -- boolean (default: ``True``); if ``True`` returns + the result as an list of ETuples, otherwise returns a list of tuples EXAMPLES:: @@ -2520,7 +2531,7 @@ cdef class NCPolynomial_plural(RingElement): def monomials(self): """ - Return the list of monomials in ``self`` + Return the list of monomials in ``self``. The returned list is decreasingly ordered by the term ordering of ``self.parent()``. @@ -2858,7 +2869,8 @@ cdef inline NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent, cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring): """ - Construct MPolynomialRing_libsingular from ringWrap, assuming the ground field to be base_ring + Construct ``MPolynomialRing_libsingular`` from ``RingWrap``, assuming the + ground field to be ``base_ring``. EXAMPLES:: @@ -2928,7 +2940,8 @@ cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring): cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring): """ - Construct NCPolynomialRing_plural from ringWrap, assuming the ground field to be base_ring + Construct ``NCPolynomialRing_plural`` from ``RingWrap``, assuming the + ground field to be ``base_ring``. EXAMPLES:: @@ -2996,9 +3009,11 @@ cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring): def new_Ring(RingWrap rw, base_ring): """ - Constructs a Sage ring out of low level RingWrap, which wraps a pointer to a Singular ring. + Construct a Sage ring out of low level ``RingWrap``, which wraps a pointer + to a Singular ring. - The constructed ring is either commutative or noncommutative depending on the Singular ring. + The constructed ring is either commutative or noncommutative depending on + the Singular ring. EXAMPLES:: @@ -3040,7 +3055,6 @@ def new_Ring(RingWrap rw, base_ring): sage: from sage.rings.polynomial.plural import new_Ring sage: R = new_Ring(W, H.base_ring()); R Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1} - """ # import warnings # warnings.warn("This is a hack. Please, use it on your own risk...") @@ -3051,15 +3065,15 @@ def new_Ring(RingWrap rw, base_ring): def SCA(base_ring, names, alt_vars, order='degrevlex'): """ - Return a free graded-commutative algebra + Return a free graded-commutative algebra. This is also known as a free super-commutative algebra. INPUT: - ``base_ring`` -- the ground field - - ``names`` -- a list of variable names - - ``alt_vars`` -- a list of indices of to be anti-commutative variables (odd variables) + - ``names`` -- list of variable names + - ``alt_vars`` -- list of indices of to be anti-commutative variables (odd variables) - ``order`` -- ordering to be used for the constructed algebra EXAMPLES:: @@ -3115,7 +3129,7 @@ def ExteriorAlgebra(base_ring, names,order='degrevlex'): INPUT: - ``base_ring`` -- the ground ring - - ``names`` -- a list of variable names + - ``names`` -- list of variable names EXAMPLES:: diff --git a/src/sage/rings/polynomial/polydict.pyx b/src/sage/rings/polynomial/polydict.pyx index e579052df95..fe2438c8e4f 100644 --- a/src/sage/rings/polynomial/polydict.pyx +++ b/src/sage/rings/polynomial/polydict.pyx @@ -71,7 +71,8 @@ cpdef int gen_index(PolyDict x) noexcept: cpdef ETuple monomial_exponent(PolyDict p): r""" - Return the unique exponent of ``p`` if it is a monomial or raise a ``ValueError``. + Return the unique exponent of ``p`` if it is a monomial or raise a + :exc:`ValueError`. EXAMPLES:: @@ -110,10 +111,10 @@ cdef class PolyDict: """ INPUT: - - ``pdict`` -- dict or list, which represents a multi-variable + - ``pdict`` -- dictionary or list, which represents a multi-variable polynomial with the distribute representation (a copy is made) - - ``zero`` -- deprecated + - ``zero`` -- deprecated - ``remove_zero`` -- deprecated @@ -122,7 +123,7 @@ cdef class PolyDict: - ``force_etuples`` -- deprecated - ``check`` -- if set to ``False`` then assumes that the exponents are - all valid ``ETuple``; in that case the construction is a bit faster. + all valid ``ETuple``; in that case the construction is a bit faster EXAMPLES:: @@ -200,7 +201,7 @@ cdef class PolyDict: INPUT: - - ``zero_test`` -- optional function that performs test to zero of a coefficient + - ``zero_test`` -- (optional) function that performs test to zero of a coefficient EXAMPLES:: @@ -275,7 +276,7 @@ cdef class PolyDict: def coerce_coefficients(self, A): r""" - Coerce the coefficients in the parent ``A`` + Coerce the coefficients in the parent ``A``. EXAMPLES:: @@ -612,7 +613,7 @@ cdef class PolyDict: INPUT: - - ``degrees`` -- a list of degree restrictions; list elements are None + - ``degrees`` -- list of degree restrictions; list elements are ``None`` if the variable in that position should be unrestricted EXAMPLES:: @@ -671,7 +672,7 @@ cdef class PolyDict: ans[ETuple(t)] = self.__repn[S] return self._new(ans) - def is_homogeneous(self): + def is_homogeneous(self, tuple w=None): r""" Return whether this polynomial is homogeneous. @@ -687,12 +688,20 @@ cdef class PolyDict: """ if not self.__repn: return True + cdef size_t s it = iter(self.__repn) - cdef size_t s = ( next(it)).unweighted_degree() - for elt in it: - if ( elt).unweighted_degree() != s: - return False - return True + if w is None: + s = ( next(it)).unweighted_degree() + for elt in it: + if ( elt).unweighted_degree() != s: + return False + return True + else: + s = ( next(it)).weighted_degree(w) + for elt in it: + if ( elt).weighted_degree(w) != s: + return False + return True def is_constant(self): """ @@ -758,8 +767,8 @@ cdef class PolyDict: INPUT: - ``vars`` -- list - - ``atomic_exponents`` -- bool (default: ``True``) - - ``atomic_coefficients`` -- bool (default: ``True``) + - ``atomic_exponents`` -- boolean (default: ``True``) + - ``atomic_coefficients`` -- boolean (default: ``True``) EXAMPLES:: @@ -799,7 +808,9 @@ cdef class PolyDict: ring = self.__repn[E[0]].parent() pos_one = ring.one() neg_one = -pos_one - except AttributeError: + except (AttributeError, ArithmeticError): + # AritchmeticError occurs when self.__repn[E[0]] is a tropical + # semiring element # probably self.__repn[E[0]] is not a ring element pos_one = 1 neg_one = -1 @@ -851,8 +862,8 @@ cdef class PolyDict: INPUT: - ``vars`` -- list - - ``atomic_exponents`` -- bool (default: ``True``) - - ``atomic_coefficients`` -- bool (default: ``True``) + - ``atomic_exponents`` -- boolean (default: ``True``) + - ``atomic_coefficients`` -- boolean (default: ``True``) EXAMPLES:: @@ -900,7 +911,9 @@ cdef class PolyDict: ring = self.__repn[E[0]].parent() pos_one = ring.one() neg_one = -pos_one - except AttributeError: + except (AttributeError, ArithmeticError): + # AritchmeticError occurs when self.__repn[E[0]] is a tropical + # semiring element # probably self.__repn[E[0]] is not a ring element pos_one = 1 neg_one = -1 @@ -952,7 +965,7 @@ cdef class PolyDict: def __iadd__(PolyDict self, PolyDict other): r""" - Inplace addition + Inplace addition. EXAMPLES:: @@ -1026,7 +1039,7 @@ cdef class PolyDict: The algorithm do not test whether a product of coefficients is zero or whether a final coefficient is zero because there is no reliable way - to do so in general (eg power series ring or p-adic rings). + to do so in general (eg power series ring or `p`-adic rings). EXAMPLES: @@ -1137,7 +1150,6 @@ cdef class PolyDict: sage: f = PolyDict({(2,3): 2, (1,2): 3, (2,1): 4}) sage: f.term_lmult(ETuple((1, 2)), -2) PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4} - """ cdef dict v = {} for e, c in self.__repn.items(): @@ -1167,7 +1179,6 @@ cdef class PolyDict: sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4}) sage: f.term_rmult(ETuple((1, 2)), -2) PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4} - """ cdef dict v = {} for e, c in self.__repn.items(): @@ -1216,7 +1227,7 @@ cdef class PolyDict: def derivative(self, PolyDict x): r""" - Return the derivative of ``self`` with respect to ``x`` + Return the derivative of ``self`` with respect to ``x``. EXAMPLES:: @@ -1263,7 +1274,7 @@ cdef class PolyDict: def integral(self, PolyDict x): r""" - Return the integral of ``self`` with respect to ``x`` + Return the integral of ``self`` with respect to ``x``. EXAMPLES:: @@ -1318,7 +1329,7 @@ cdef class PolyDict: def min_exp(self): """ - Returns an ETuple containing the minimum exponents appearing. If + Return an ETuple containing the minimum exponents appearing. If there are no terms at all in the PolyDict, it returns None. The nvars parameter is necessary because a PolyDict doesn't know it @@ -1344,7 +1355,7 @@ cdef class PolyDict: def max_exp(self): """ - Returns an ETuple containing the maximum exponents appearing. If + Return an ETuple containing the maximum exponents appearing. If there are no terms at all in the PolyDict, it returns None. The nvars parameter is necessary because a PolyDict doesn't know it @@ -1432,8 +1443,8 @@ cdef class ETuple: """ cdef ETuple _new(self): """ - Quickly creates a new initialized ETuple with the - same length as self. + Quickly create a new initialized ETuple with the + same length as ``self``. """ cdef type t = type(self) cdef ETuple x = t.__new__(t) @@ -1511,7 +1522,7 @@ cdef class ETuple: def __bool__(self): r""" - Return whether self is nonzero. + Return whether ``self`` is nonzero. TESTS:: @@ -1529,9 +1540,9 @@ cdef class ETuple: def __add__(ETuple self, ETuple other): """ - x.__add__(n) <==> x+n + ``x.__add__(n) <==> x+n``. - concatenates two ETuples + Concatenate two ETuples. EXAMPLES:: @@ -1554,7 +1565,7 @@ cdef class ETuple: def __mul__(ETuple self, factor): """ - x.__mul__(n) <==> x*n + ``x.__mul__(n) <==> x*n``. EXAMPLES:: @@ -1665,7 +1676,7 @@ cdef class ETuple: def __len__(self): """ - x.__len__() <==> len(x) + ``x.__len__() <==> len(x)``. EXAMPLES:: @@ -1678,7 +1689,7 @@ cdef class ETuple: def __contains__(self, elem): """ - x.__contains__(n) <==> n in x + ``x.__contains__(n) <==> n in x``. EXAMPLES:: @@ -1780,7 +1791,7 @@ cdef class ETuple: def __iter__(self): """ - x.__iter__() <==> iter(x) + ``x.__iter__() <==> iter(x)``. TESTS:: @@ -1885,7 +1896,7 @@ cdef class ETuple: INPUT: - - ``w`` -- tuple of non-negative integers + - ``w`` -- tuple of nonnegative integers EXAMPLES:: @@ -1917,7 +1928,7 @@ cdef class ETuple: """ Return the degree of ``self`` divided by its gcd with ``other``. - It amounts to counting the non-negative entries of + It amounts to counting the nonnegative entries of ``self.esub(other)``. """ cdef size_t ind1 = 0 # both ind1 and ind2 will be increased in double steps. @@ -1956,7 +1967,7 @@ cdef class ETuple: INPUT: - ``other`` -- an :class:`~sage.rings.polynomial.polydict.ETuple` - - ``w`` -- tuple of non-negative integers. + - ``w`` -- tuple of nonnegative integers """ if len(w) != self._length: raise ValueError('w must be of the same length as the ETuple') @@ -2218,7 +2229,7 @@ cdef class ETuple: cdef size_t ind cdef ETuple result = self._new() if factor == 0: - result._nonzero = 0 # all zero, no non-zero entries! + result._nonzero = 0 # all zero, no nonzero entries! result._data = sig_malloc(sizeof(int) * result._nonzero * 2) else: result._nonzero = self._nonzero @@ -2433,7 +2444,7 @@ cdef class ETuple: """ Return division of ``self`` by the variable with index ``pos``. - If ``self[pos] == 0`` then a ``ArithmeticError`` is raised. Otherwise, + If ``self[pos] == 0`` then a :exc:`ArithmeticError` is raised. Otherwise, an :class:`~sage.rings.polynomial.polydict.ETuple` is returned that is zero in position ``pos`` and coincides with ``self`` in the other positions. @@ -2558,11 +2569,11 @@ cdef class ETuple: cpdef list nonzero_positions(self, bint sort=False): """ - Return the positions of non-zero exponents in the tuple. + Return the positions of nonzero exponents in the tuple. INPUT: - - ``sort`` -- (default: ``False``) if ``True`` a sorted list is + - ``sort`` -- boolean (default: ``False``); if ``True`` a sorted list is returned; if ``False`` an unsorted list is returned EXAMPLES:: @@ -2577,8 +2588,8 @@ cdef class ETuple: cpdef common_nonzero_positions(self, ETuple other, bint sort=False): """ - Returns an optionally sorted list of non zero positions either - in self or other, i.e. the only positions that need to be + Return an optionally sorted list of nonzero positions either + in ``self`` or other, i.e. the only positions that need to be considered for any vector operation. EXAMPLES:: @@ -2600,12 +2611,12 @@ cdef class ETuple: cpdef list nonzero_values(self, bint sort=True): """ - Return the non-zero values of the tuple. + Return the nonzero values of the tuple. INPUT: - - ``sort`` -- (default: ``True``) if ``True`` the values are sorted - by their indices; otherwise the values are returned unsorted + - ``sort`` -- boolean (default: ``True``); if ``True`` the values are + sorted by their indices. Otherwise the values are returned unsorted. EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_compiled.pyx b/src/sage/rings/polynomial/polynomial_compiled.pyx index 01fac1e932f..dbdd9d55b82 100644 --- a/src/sage/rings/polynomial/polynomial_compiled.pyx +++ b/src/sage/rings/polynomial/polynomial_compiled.pyx @@ -20,8 +20,8 @@ from sage.misc.binary_tree cimport BinaryTree cdef class CompiledPolynomialFunction: """ - Builds a reasonably optimized directed acyclic graph representation - for a given polynomial. A CompiledPolynomialFunction is callable from + Build a reasonably optimized directed acyclic graph representation + for a given polynomial. A ``CompiledPolynomialFunction`` is callable from python, though it is a little faster to call the eval function from pyrex. @@ -95,7 +95,6 @@ cdef class CompiledPolynomialFunction: forthcoming) requires the gaps to considered in order, and adds additional dummies as it goes. Hence, the gaps are put into a binary tree. - """ cdef generic_pd max_gap, dag cdef BinaryTree gaps @@ -232,8 +231,6 @@ cdef class CompiledPolynomialFunction: The r == 0 case in step 3 is equivalent to binary exponentiation. """ - - cdef int m,n,k,r,half cdef generic_pd T,N,H cdef dummy_pd M diff --git a/src/sage/rings/polynomial/polynomial_complex_arb.pyx b/src/sage/rings/polynomial/polynomial_complex_arb.pyx index 8c96385c1e2..7f4fc81a4e5 100644 --- a/src/sage/rings/polynomial/polynomial_complex_arb.pyx +++ b/src/sage/rings/polynomial/polynomial_complex_arb.pyx @@ -383,7 +383,7 @@ cdef class Polynomial_complex_arb(Polynomial): r""" Compute the Euclidean division of this ball polynomial by ``divisor``. - Raises a ``ZeroDivisionError`` when the divisor is zero or its leading + Raises a :exc:`ZeroDivisionError` when the divisor is zero or its leading coefficient contains zero. Returns a pair (quotient, remainder) otherwise. @@ -594,7 +594,7 @@ cdef class Polynomial_complex_arb(Polynomial): INPUT: - - ``expo`` -- non-negative integer exponent + - ``expo`` -- nonnegative integer exponent - ``n`` -- truncation order EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index dcf2af7cdf2..53bb07c2fc4 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -76,7 +76,6 @@ from sage.arith.power cimport generic_power from sage.arith.misc import crt from sage.arith.long cimport pyobject_to_long from sage.misc.mrange import cartesian_product_iterator -from sage.misc.superseded import deprecated_function_alias from sage.structure.factorization import Factorization from sage.structure.richcmp cimport (richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn) @@ -118,9 +117,9 @@ from sage.arith.functions import lcm from sage.rings.polynomial import polynomial_fateman -from sage.rings.ideal import is_Ideal -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing +from sage.rings.ideal import Ideal_generic +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.polynomial.multi_polynomial cimport MPolynomial from sage.rings.polynomial.polynomial_quotient_ring_element import PolynomialQuotientRingElement from sage.misc.cachefunc import cached_function @@ -139,7 +138,7 @@ cpdef is_Polynomial(f): INPUT: - - ``f`` -- an object + - ``f`` -- an object EXAMPLES:: @@ -174,7 +173,6 @@ cpdef is_Polynomial(f): sage: is_Polynomial(f) False """ - from sage.misc.superseded import deprecation deprecation(32709, "the function is_Polynomial is deprecated; use isinstance(x, sage.rings.polynomial.polynomial_element.Polynomial) instead") return isinstance(f, Polynomial) @@ -331,15 +329,13 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``xmin`` -- float + - ``xmin`` -- float - - ``xmax`` -- float + - ``xmax`` -- float - - ``*args, **kwds`` -- passed to either plot or - point + - ``*args, **kwds`` -- passed to either plot or point - - OUTPUT: returns a graphic object. + OUTPUT: a graphic object EXAMPLES:: @@ -369,7 +365,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef _lmul_(self, Element left): """ - Multiply self on the left by a scalar. + Multiply ``self`` on the left by a scalar. EXAMPLES:: @@ -389,7 +385,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef _rmul_(self, Element right): """ - Multiply self on the right by a scalar. + Multiply ``self`` on the right by a scalar. EXAMPLES:: @@ -453,11 +449,9 @@ cdef class Polynomial(CommutativePolynomial): the polynomial. The **first** positional argument is substituted for the polynomial's indeterminate. Remaining arguments, if any, are used **from left to right** to evaluate the coefficients. - - ``**kwds`` -- variable name-value pairs. - - OUTPUT: + - ``**kwds`` -- variable name-value pairs - The value of the polynomial at the point specified by the arguments. + OUTPUT: the value of the polynomial at the point specified by the arguments ALGORITHM: @@ -866,7 +860,7 @@ cdef class Polynomial(CommutativePolynomial): return R(pol) if pol._parent.is_sparse(): coeff_sparse = {} - coeff_dict = pol.dict() + coeff_dict = pol.monomial_coefficients() for i in coeff_dict: coeff_sparse[i * d] = coeff_dict[i] return R(coeff_sparse, check=False) @@ -887,7 +881,7 @@ cdef class Polynomial(CommutativePolynomial): if a.is_monomial(): etup = ETuple(( a).degrees()) if pol._parent.is_sparse(): - coeff_dict = pol.dict() + coeff_dict = pol.monomial_coefficients() return R({etup.emul(key): coeff_dict[key] for key in coeff_dict}) # Dense version return R({etup.emul(i): c for i, c in enumerate(pol)}) @@ -1010,7 +1004,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef _richcmp_(self, other, int op): r""" - Compare the two polynomials self and other. + Compare the two polynomials ``self`` and ``other``. We order polynomials first by degree (but treating 0 as having degree 0), then in dictionary order starting with the @@ -1268,7 +1262,6 @@ cdef class Polynomial(CommutativePolynomial): Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' - """ cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap cdef long result_mon @@ -1553,8 +1546,8 @@ cdef class Polynomial(CommutativePolynomial): def inverse_mod(a, m): """ - Invert the polynomial ``a`` with respect to ``m``, or raise a :class:`ValueError` - if no such inverse exists. + Invert the polynomial ``a`` with respect to ``m``, or raise a + :exc:`ValueError` if no such inverse exists. The parameter ``m`` may be either a single polynomial or an ideal (for consistency with :meth:`inverse_mod` in other rings). @@ -1616,8 +1609,8 @@ cdef class Polynomial(CommutativePolynomial): - Robert Bradshaw (2007-05-31) """ - from sage.rings.ideal import is_Ideal - if is_Ideal(m): + from sage.rings.ideal import Ideal_generic + if isinstance(m, Ideal_generic): v = m.gens_reduced() if len(v) > 1: raise NotImplementedError("Don't know how to invert modulo non-principal ideal %s" % m) @@ -1883,7 +1876,7 @@ cdef class Polynomial(CommutativePolynomial): def multiplication_trunc(self, other, n): r""" - Truncated multiplication + Truncated multiplication. EXAMPLES:: @@ -1955,7 +1948,6 @@ cdef class Polynomial(CommutativePolynomial): sage: f = QQbar['x'](1) # needs sage.rings.number_field sage: f.squarefree_decomposition() # needs sage.rings.number_field 1 - """ if self.degree() < 0: raise ValueError("square-free decomposition not defined for zero polynomial") @@ -1973,15 +1965,14 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``root`` -- whether or not to also return a square - root (default: ``False``) + - ``root`` -- whether or not to also return a square + root (default: ``False``) OUTPUT: - - ``bool`` -- whether or not a square + - boolean; whether or not a square - - ``root`` -- (optional) an actual square root if - found, and ``None`` otherwise. + - (optional) an actual square root if found, and ``None`` otherwise EXAMPLES:: @@ -2048,7 +2039,7 @@ cdef class Polynomial(CommutativePolynomial): def _distinct_degree_factorisation_squarefree(self): """ Helper function for any_irreducible_factor which computes - the distinct degree factorisation of `self`. + the distinct degree factorisation of ``self``. Creates an iterator for all valid degrees `d`, and returns tuples of the form `(a_d, d)` for a polynomial `a_d` the @@ -2211,11 +2202,11 @@ cdef class Polynomial(CommutativePolynomial): def _any_irreducible_factor_squarefree(self, degree=None, ext_degree=None): """ Helper function for :meth:`any_irreducible_factor` which computes - an irreducible factor from self, assuming the input is + an irreducible factor from ``self``, assuming the input is squarefree. Does this by first computing the distinct degree factorisations - of self and then finds a factor with Cantor-Zassenhaus + of ``self`` and then finds a factor with Cantor-Zassenhaus splitting. If ``degree`` is not ``None``, then only irreducible factors of degree @@ -2287,17 +2278,17 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``degree`` (None or positive integer) -- (default: ``None``). + - ``degree`` -- ``None`` or positive integer (default: ``None``). Used for polynomials over finite fields. If ``None``, returns the the first factor found (usually the smallest). Otherwise, attempts to return an irreducible factor of ``self`` of chosen degree ``degree``. - - ``assume_squarefree`` (boolean) -- (default: ``False``). + - ``assume_squarefree`` -- boolean (default: ``False``); Used for polynomials over finite fields. If ``True``, this polynomial is assumed to be squarefree. - - ``assume_equal_deg`` (boolean) -- (default: ``False``). + - ``assume_equal_deg`` -- boolean (default: ``False``); Used for polynomials over finite fields. If ``True``, this polynomial is assumed to be the product of irreducible polynomials of degree equal to ``degree``. @@ -2330,7 +2321,7 @@ cdef class Polynomial(CommutativePolynomial): x^3 + 7*x + 161 If we ask for an irreducible factor which does not exist, the function - will throw a ``ValueError``:: + will throw a :exc:`ValueError`:: sage: # needs sage.rings.finite_rings sage: F = GF(163) @@ -2400,7 +2391,7 @@ cdef class Polynomial(CommutativePolynomial): # For finite fields, we find irreducible factors in the following three steps: # - # 1. Compute the squarefree decomposition of the polynomial `self` + # 1. Compute the squarefree decomposition of the polynomial ``self`` # 2. For each squarefree polynomial find the distinct degree `d` # factorisation, F, which is the product of degree `d` polynomials # dividing the squarefree polynomial @@ -2446,21 +2437,21 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``ring`` -- The ring in which a root is sought. By default - this is the coefficient ring. + - ``ring`` -- the ring in which a root is sought; by default + this is the coefficient ring - - ``degree`` (None or nonzero integer) -- Used for polynomials + - ``degree`` -- ``None`` or nonzero integer; used for polynomials over finite fields. Return a root of degree ``abs(degree)`` over the ground field. If negative, also assumes that all factors of this polynomial are of degree - ``abs(degree)``. If None, returns a root of minimal degree + ``abs(degree)``. If ``None``, returns a root of minimal degree contained within the given ring. - - ``assume_squarefree`` (bool) -- Used for polynomials over + - ``assume_squarefree`` -- boolean; used for polynomials over finite fields. If ``True``, this polynomial is assumed to be squarefree. - - ``assume_equal_deg`` (bool) -- Used for polynomials over + - ``assume_equal_deg`` -- boolean; used for polynomials over finite fields. If ``True``, all factors of this polynomial are assumed to have degree ``degree``. Note that ``degree`` must be set. @@ -2622,7 +2613,7 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError(f"no root of polynomial {self} can be computed over the ring {ring}") # When d != 1 we then find the smallest extension # TODO: What we should do here is compute some minimal - # extension F_ext = self.base_ring().extension(d, names="a") and find a + # extension F_ext = self.base_ring().extension(d, names='a') and find a # root here and then coerce this root into the parent ring. This means we # would work with the smallest possible extension. # However, if we have some element of GF(p^k) and we try and coerce this to @@ -2655,7 +2646,6 @@ cdef class Polynomial(CommutativePolynomial): # ensure that the degree is positive. degree = ZZ(degree) if degree < 0: - from sage.misc.superseded import deprecation deprecation(37170, "negative ``degree`` will be disallowed. Instead use the bool `assume_equal_deg`.") degree = -degree assume_equal_deg = True @@ -2685,12 +2675,12 @@ cdef class Polynomial(CommutativePolynomial): # new ring? if ring is None: # TODO: a faster option would be to create an extension with `f` - # as F_ext = self.base_ring().extension(f, names="a") + # as F_ext = self.base_ring().extension(f, names='a') # however this returns a quotient ring rather than a # FiniteField type if the base field is a non-prime field, # so this slower option is chosen to ensure the root is # over explicitly a FiniteField type. - ring = self.base_ring().extension(degree, names="a") + ring = self.base_ring().extension(degree, names='a') # TODO: The proper thing to do here would be to call # return f.change_ring(ring).any_root() @@ -2938,14 +2928,14 @@ cdef class Polynomial(CommutativePolynomial): q = right sparse = self.parent().is_sparse() if sparse: - d = self.dict() + d = self.monomial_coefficients() else: c = self.list(copy=False) while q > 0: q, r = q.quo_rem(p) if r != 0: if sparse: - tmp = self.parent()({e*k : d[k]**e for k in d}) + tmp = self.parent()({e*k: d[k]**e for k in d}) else: tmp = [0] * (e * len(c) - e + 1) for i in range(len(c)): @@ -2959,13 +2949,13 @@ cdef class Polynomial(CommutativePolynomial): def power_trunc(self, n, prec): r""" - Truncated ``n``-th power of this polynomial up to precision ``prec`` + Truncated ``n``-th power of this polynomial up to precision ``prec``. INPUT: - - ``n`` -- (non-negative integer) power to be taken + - ``n`` -- nonnegative integer; power to be taken - - ``prec`` -- (integer) the precision + - ``prec`` -- integer; the precision EXAMPLES:: @@ -3006,7 +2996,7 @@ cdef class Polynomial(CommutativePolynomial): sage: x.power_trunc(-1, 10) Traceback (most recent call last): ... - ValueError: n must be a non-negative integer + ValueError: n must be a nonnegative integer sage: R. = QQ['x'] sage: y.power_trunc(2**32 - 1, 2) 0 @@ -3020,16 +3010,16 @@ cdef class Polynomial(CommutativePolynomial): cpdef Polynomial _power_trunc(self, unsigned long n, long prec): r""" - Truncated ``n``-th power of this polynomial up to precision ``prec`` + Truncated ``n``-th power of this polynomial up to precision ``prec``. This method is overridden for certain subclasses when a library function is available. INPUT: - - ``n`` -- (non-negative integer) power to be taken + - ``n`` -- nonnegative integer; power to be taken - - ``prec`` -- (integer) the precision + - ``prec`` -- integer; the precision TESTS:: @@ -3061,7 +3051,7 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``name`` -- None or a string; used for printing the variable. + - ``name`` -- ``None`` or a string; used for printing the variable EXAMPLES:: @@ -3284,16 +3274,16 @@ cdef class Polynomial(CommutativePolynomial): def __setitem__(self, n, value): """ - Set the n-th coefficient of this polynomial. This always raises an - IndexError, since in Sage polynomials are immutable. + Set the `n`-th coefficient of this polynomial. This always raises an + :exc:`IndexError`, since in Sage polynomials are immutable. INPUT: - - ``n`` -- an integer + - ``n`` -- integer - - ``value`` -- value to set the n-th coefficient to + - ``value`` -- value to set the `n`-th coefficient to - OUTPUT: an :class:`IndexError` is always raised. + OUTPUT: an :exc:`IndexError` is always raised EXAMPLES:: @@ -3484,13 +3474,11 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``self`` -- Polynomial - - - ``right`` -- Polynomial (over same base ring as - self) + - ``self`` -- polynomial + - ``right`` -- polynomial (over same base ring as ``self``) - OUTPUT: Polynomial - The product self\*right. + OUTPUT: polynomial; the product ``self * right`` ALGORITHM: Based on a paper by R. Fateman @@ -3515,7 +3503,6 @@ cdef class Polynomial(CommutativePolynomial): Advantages: - - Faster than Karatsuba over `\QQ` and `\ZZ` (but much slower still than calling NTL's optimized C++ implementation, which is the default over @@ -3523,23 +3510,20 @@ cdef class Polynomial(CommutativePolynomial): - Potentially less complicated. - Drawbacks: + - Slower over R when the degree of both of polynomials is less + than 250 (roughly). - - Slower over R when the degree of both of polynomials is less - than 250 (roughly). - - - Over R, results may not be as accurate as the Karatsuba case. - This is because we represent coefficients of polynomials over R as - fractions, then convert them back to floating-point numbers. - + - Over R, results may not be as accurate as the Karatsuba case. + This is because we represent coefficients of polynomials over R as + fractions, then convert them back to floating-point numbers. AUTHORS: - Didier Deshommes (2006-05-25) """ - return self._parent(polynomial_fateman._mul_fateman_mul(self,right)) + return self._parent(polynomial_fateman._mul_fateman_mul(self, right)) @cython.boundscheck(False) @cython.wraparound(False) @@ -3553,16 +3537,14 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``self`` -- Polynomial - - ``right`` -- Polynomial (over same base ring as ``self``) - - ``K_threshold`` -- (optional) Integer. A threshold to fall back to - schoolbook algorithm. In the recursion, if one of the polynomials - is of degree less that K_threshold then the classic quadratic - polynomial is used. + - ``self`` -- polynomial + - ``right`` -- polynomial (over same base ring as ``self``) + - ``K_threshold`` -- (optional) Integer. A threshold to fall back to + schoolbook algorithm. In the recursion, if one of the polynomials + is of degree less that K_threshold then the classic quadratic + polynomial is used. - OUTPUT: - - The product ``self * right``. + OUTPUT: the product ``self * right`` ALGORITHM: @@ -3591,7 +3573,7 @@ cdef class Polynomial(CommutativePolynomial): to recursively compute `fg`. - If `self` is a polynomial of degree n and `right` is a polynomial of + If ``self`` is a polynomial of degree n and `right` is a polynomial of degree m with n < m, then we interpret `right` as .. MATH:: @@ -3599,7 +3581,7 @@ cdef class Polynomial(CommutativePolynomial): g0 + g1 * x^n + g2 * x^{2n} + ... + gq * x^{nq} where `gi` are polynomials of degree <= n. We then compute each product - `gi*right` with Karatsuba multiplication and reconstruct `self*right` + ``gi*right`` with Karatsuba multiplication and reconstruct ``self*right`` from the partial products. The theoretical complexity for multiplying two polynomials of the same @@ -3800,7 +3782,7 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``R`` -- a ring or morphism. + - ``R`` -- a ring or morphism EXAMPLES:: @@ -3898,7 +3880,7 @@ cdef class Polynomial(CommutativePolynomial): cdef dict D = {} cdef tuple leftovers = (0,) * (len(variables) - len(prev_variables) - 1) for k in range(len(mpolys)): - for i,a in mpolys[k].iteritems(): + for i, a in mpolys[k].items(): j = ETuple((k,) + leftovers) D[i + j] = a @@ -3963,7 +3945,7 @@ cdef class Polynomial(CommutativePolynomial): def euclidean_degree(self): r""" - Return the degree of this element as an element of an Euclidean domain. + Return the degree of this element as an element of a Euclidean domain. If this polynomial is defined over a field, this is simply its :meth:`degree`. @@ -3977,7 +3959,6 @@ cdef class Polynomial(CommutativePolynomial): Traceback (most recent call last): ... NotImplementedError - """ from sage.categories.fields import Fields if self.base_ring() in Fields(): @@ -4075,7 +4056,7 @@ cdef class Polynomial(CommutativePolynomial): def numerator(self): """ - Return a numerator of ``self``, computed as ``self * self.denominator()`` + Return a numerator of ``self``, computed as ``self * self.denominator()``. Note that some subclasses may implement its own numerator function. For example, see @@ -4480,7 +4461,7 @@ cdef class Polynomial(CommutativePolynomial): if self.get_unsafe(n) else zero for n in range(self.degree() + 1)] return S(p) - def dict(self): + def monomial_coefficients(self): """ Return a sparse dictionary representation of this univariate polynomial. @@ -4489,6 +4470,11 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + -1/7*x + 13 + sage: f.monomial_coefficients() + {0: 13, 1: -1/7, 3: 1} + + ``dict`` is an alias:: + sage: f.dict() {0: 13, 1: -1/7, 3: 1} """ @@ -4501,6 +4487,8 @@ cdef class Polynomial(CommutativePolynomial): X[i] = c return X + dict = monomial_coefficients + def factor(self, **kwargs): r""" Return the factorization of ``self`` over its base ring. @@ -5157,10 +5145,10 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``names`` -- (default: ``None``) a variable name for the splitting field. + - ``names`` -- (default: ``None``) a variable name for the splitting field - - ``map`` -- (default: ``False``) also return an embedding of - ``self`` into the resulting field. + - ``map`` -- boolean (default: ``False``); also return an embedding of + ``self`` into the resulting field - ``kwds`` -- additional keywords depending on the type. Currently, only number fields are implemented. See @@ -5288,13 +5276,13 @@ cdef class Polynomial(CommutativePolynomial): sage: # needs sage.rings.finite_rings sage: P. = PolynomialRing(GF(401^13, 'a')) sage: t = 2*x^14 - 5 + 6*x - sage: t.splitting_field('b') + sage: t.splitting_field('b') # long time (16s) Finite Field in b of size 401^104 sage: t = 24*x^13 + 2*x^12 + 14 - sage: t.splitting_field('b') + sage: t.splitting_field('b') # long time (39s) Finite Field in b of size 401^156 sage: t = x^56 - 14*x^3 - sage: t.splitting_field('b') + sage: t.splitting_field('b') # long time (2s) Finite Field in b of size 401^52 sage: R. = QQ[] @@ -5303,7 +5291,6 @@ cdef class Polynomial(CommutativePolynomial): Traceback (most recent call last): ... TypeError: You must specify the name of the generator. - """ if names is None: raise TypeError("You must specify the name of the generator.") @@ -5546,13 +5533,12 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``n`` (default: ``None``) -- if provided, should equal + - ``n`` -- (default: ``None``) if provided, should equal `q-1` where ``self.parent()`` is the field with `q` - elements; otherwise it will be computed. + elements; otherwise it will be computed - - ``n_prime_divs`` (default: ``None``) -- if provided, should - be a list of the prime divisors of `n`; otherwise it - will be computed. + - ``n_prime_divs`` -- (default: ``None``) if provided, should be a list + of the prime divisors of `n`; otherwise it will be computed .. NOTE:: @@ -5673,7 +5659,7 @@ cdef class Polynomial(CommutativePolynomial): n = q ** self.degree() - 1 y = self._parent.quo(self).gen() from sage.groups.generic import order_from_multiple - return n == order_from_multiple(y, n, n_prime_divs, operation="*") + return n == order_from_multiple(y, n, n_prime_divs, operation='*') elif isinstance(R, sage.rings.abc.Order): K = R.number_field() return K.fractional_ideal(self.coefficients()) == K.fractional_ideal(1) @@ -5684,12 +5670,7 @@ cdef class Polynomial(CommutativePolynomial): """ Return ``True`` if this is a constant polynomial. - OUTPUT: - - - - ``bool`` -- ``True`` if and only if this polynomial is - constant - + OUTPUT: boolean; ``True`` if and only if this polynomial is constant EXAMPLES:: @@ -5859,9 +5840,9 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``right`` -- a polynomial in the same ring as ``self``. - - ``variable`` -- optional, included for compatibility with the multivariate - case only. The variable of the polynomials. + - ``right`` -- a polynomial in the same ring as ``self`` + - ``variable`` -- (optional) included for compatibility with the + multivariate case only; the variable of the polynomials EXAMPLES:: @@ -5976,7 +5957,7 @@ cdef class Polynomial(CommutativePolynomial): # sylvester_matrix() in multi_polynomial.pyx. if self._parent != right.parent(): - a, b = coercion_model.canonical_coercion(self,right) + a, b = coercion_model.canonical_coercion(self, right) variable = a.parent()(self.variables()[0]) #We add the variable to cover the case that right is a multivariate #polynomial @@ -6051,7 +6032,7 @@ cdef class Polynomial(CommutativePolynomial): def is_monic(self): """ - Returns ``True`` if this polynomial is monic. The zero polynomial is by + Return ``True`` if this polynomial is monic. The zero polynomial is by definition not monic. EXAMPLES:: @@ -6074,7 +6055,7 @@ cdef class Polynomial(CommutativePolynomial): - Naqi Jaffery (2006-01-24): examples """ - return not self.is_zero() and self[self.degree()] == 1 + return not self.is_zero() and self[self.degree()] == self.base_ring().one() def is_unit(self): r""" @@ -6318,7 +6299,7 @@ cdef class Polynomial(CommutativePolynomial): r""" Return the coefficients of the monomials appearing in ``self``. - If ``sparse=True`` (the default), it returns only the non-zero coefficients. + If ``sparse=True`` (the default), it returns only the nonzero coefficients. Otherwise, it returns the same value as ``self.list()``. (In this case, it may be slightly faster to invoke ``self.list()`` directly.) In either case, the coefficients are ordered by increasing degree. @@ -6348,9 +6329,9 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -6430,12 +6411,12 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -6480,12 +6461,12 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default :class:`RealField` precision). + default :class:`RealField` precision) - OUTPUT: a real number. + OUTPUT: a real number EXAMPLES:: @@ -6598,18 +6579,13 @@ cdef class Polynomial(CommutativePolynomial): def padded_list(self, n=None): """ - Return list of coefficients of ``self`` up to (but not including) - `q^n`. + Return list of coefficients of ``self`` up to (but not including) `q^n`. - Includes 0's in the list on the right so that the list has length - `n`. + Includes 0s in the list on the right so that the list has length `n`. INPUT: - - - ``n`` -- (default: None); if given, an integer that - is at least 0 - + - ``n`` -- (default: ``None``) if given, an integer that is at least 0 EXAMPLES:: @@ -6658,7 +6634,7 @@ cdef class Polynomial(CommutativePolynomial): - ``m`` -- a monomial - OUTPUT: Coefficient in base ring. + OUTPUT: coefficient in base ring EXAMPLES:: @@ -6740,17 +6716,14 @@ cdef class Polynomial(CommutativePolynomial): INPUT: + - ``n`` -- integer; the number of iterations - - ``n`` -- an integer (the number of iterations), - - - ``x0`` -- an initial guess `x_0`. + - ``x0`` -- an initial guess `x_0` - - OUTPUT: A list of numbers hopefully approximating a root of - `f(x)=0`. + OUTPUT: list of numbers hopefully approximating a root of `f(x)=0` If one of the iterates is a critical point of `f`, a - :class:`ZeroDivisionError` exception is raised. + :exc:`ZeroDivisionError` exception is raised. EXAMPLES:: @@ -7039,7 +7012,7 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``name`` -- (default: None) Variable name. If not given, use + - ``name`` -- (default: ``None``) variable name. If not given, use ``self.parent().variable_name()``. This argument is irrelevant for constant polynomials. @@ -7204,9 +7177,9 @@ cdef class Polynomial(CommutativePolynomial): sage: f = R('e*i') * x + x^2 sage: f._giac_init_() '((1)*1)*sageVARx^2+((1)*sageVARe*sageVARi)*sageVARx' - sage: giac(f) + sage: giac(f) # needs giac sageVARx^2+sageVARe*sageVARi*sageVARx - sage: giac(R.zero()) + sage: giac(R.zero()) # needs giac 0 """ g = 'sageVAR' + self.variable_name() @@ -7347,7 +7320,7 @@ cdef class Polynomial(CommutativePolynomial): - ``other`` -- a polynomial - OUTPUT: a list of polynomials in the same ring as ``self`` + OUTPUT: list of polynomials in the same ring as ``self`` EXAMPLES:: @@ -7369,7 +7342,6 @@ cdef class Polynomial(CommutativePolynomial): REFERENCES: :wikipedia:`Polynomial_greatest_common_divisor#Subresultants` - """ P, Q = self, other if P.degree() < Q.degree(): @@ -7441,9 +7413,9 @@ cdef class Polynomial(CommutativePolynomial): as this polynomial - ``op`` -- ``operator.OP`` where ``OP=add`` or ``sub`` or ``mul`` or - ``truediv``. + ``truediv`` - - ``algorithm`` -- can be ``"resultant"`` or ``"BFSS"``; + - ``algorithm`` -- can be ``'resultant'`` or ``'BFSS'``; by default the former is used when the polynomials have few nonzero coefficients and small degrees or if the base ring is not `\ZZ` or `\QQ`. Otherwise the latter is used. @@ -7463,15 +7435,15 @@ cdef class Polynomial(CommutativePolynomial): .. TODO:: - - The [BFSS2006]_ algorithm has been implemented here only in the case of - polynomials over rationals. For other rings of zero characteristic - (or if the characteristic is larger than the product of the degrees), - one needs to implement a generic method ``_exp_series``. In the - general case of non-zero characteristic there is an alternative - algorithm in the same paper. + - The [BFSS2006]_ algorithm has been implemented here only in the case of + polynomials over rationals. For other rings of zero characteristic + (or if the characteristic is larger than the product of the degrees), + one needs to implement a generic method ``_exp_series``. In the + general case of nonzero characteristic there is an alternative + algorithm in the same paper. - - The Newton series computation can be done much more efficiently! - See [BFSS2006]_. + - The Newton series computation can be done much more efficiently! + See [BFSS2006]_. EXAMPLES:: @@ -7550,7 +7522,7 @@ cdef class Polynomial(CommutativePolynomial): raise TypeError("p2 must be a polynomial") p1, p2 = coercion_model.canonical_coercion(p1, p2) K = p1.parent() - assert is_PolynomialRing(p1.parent()) + assert isinstance(p1.parent(), PolynomialRing_general) S = K.base_ring() Sf = S.fraction_field() @@ -7654,13 +7626,12 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - `k` -- a non-negative integer + - ``k`` -- nonnegative integer - - ``algorithm`` -- ``None`` (default), ``"resultant"`` or ``"BFSS"``. - See :meth:`.composed_op` + - ``algorithm`` -- ``None`` (default), ``'resultant'``, or ``'BFSS'``; + see :meth:`.composed_op` - - ``monic`` -- ``False`` (default) or ``True``. - See :meth:`.composed_op` + - ``monic`` -- boolean (default: ``False``); see :meth:`.composed_op` OUTPUT: @@ -7722,9 +7693,9 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - `n` -- an integer + - ``n`` -- integer - - ``monic`` -- boolean (default ``False``) + - ``monic`` -- boolean (default: ``False``) if set to ``True``, force the output to be monic EXAMPLES:: @@ -7758,7 +7729,6 @@ cdef class Polynomial(CommutativePolynomial): (-1) * (x - c^3) * (x - b^3) * (x - a^3) sage: f.adams_operator_on_roots(3, monic=True).factor() # needs sage.libs.singular (x - c^3) * (x - b^3) * (x - a^3) - """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -7874,7 +7844,7 @@ cdef class Polynomial(CommutativePolynomial): leading coefficient of ``self``, and the roots of ``self`` are `r_1, \ldots, r_n`. - OUTPUT: An element of the base ring of the polynomial ring. + OUTPUT: an element of the base ring of the polynomial ring ALGORITHM: @@ -7979,13 +7949,16 @@ cdef class Polynomial(CommutativePolynomial): 4 + 4*T + O(T^2) """ # Late import to avoid cyclic dependencies: - from sage.rings.power_series_ring import is_PowerSeriesRing + from sage.rings.power_series_ring import PowerSeriesRing_generic + try: + from sage.rings.lazy_series_ring import LazyPowerSeriesRing + except ImportError: + LazyPowerSeriesRing = () if self.is_zero(): return self # return 0 n = self.degree() base_ring = self._parent.base_ring() - if (is_MPolynomialRing(base_ring) or - is_PowerSeriesRing(base_ring)): + if isinstance(base_ring, (MPolynomialRing_base, PowerSeriesRing_generic, LazyPowerSeriesRing)): # It is often cheaper to compute discriminant of simple # multivariate polynomial and substitute the real # coefficients into that result (see #16014). @@ -8036,7 +8009,7 @@ cdef class Polynomial(CommutativePolynomial): sage: f.reverse(degree=1.5r) Traceback (most recent call last): ... - ValueError: degree argument must be a non-negative integer, got 1.5 + ValueError: degree argument must be a nonnegative integer, got 1.5 sage: f.reverse(0) -3*x @@ -8048,10 +8021,10 @@ cdef class Polynomial(CommutativePolynomial): cdef unsigned long d if degree is not None: if degree < 0: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) d = degree if d != degree: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) if len(v) < degree+1: v.reverse() v = [self.base_ring().zero()]*(degree+1-len(v)) + v @@ -8072,17 +8045,16 @@ cdef class Polynomial(CommutativePolynomial): INPUT: + - ``ring`` -- the ring to find roots in - - ``ring`` -- the ring to find roots in - - - ``multiplicities`` -- bool (default: ``True``) if ``True`` - return list of pairs `(r, n)`, where `r` is the root and `n` is the - multiplicity. If ``False``, just return the unique roots, with no - information about multiplicities. + - ``multiplicities`` -- boolean (default: ``True``); if ``True`` + return list of pairs `(r, n)`, where `r` is the root and `n` is the + multiplicity. If ``False``, just return the unique roots, with no + information about multiplicities. - - ``algorithm`` -- the root-finding algorithm to use. - We attempt to select a reasonable algorithm by default, but this - lets the caller override our choice. + - ``algorithm`` -- the root-finding algorithm to use. + We attempt to select a reasonable algorithm by default, but this + lets the caller override our choice. By default, this finds all the roots that lie in the base ring of @@ -8436,6 +8408,9 @@ cdef class Polynomial(CommutativePolynomial): UserWarning: roots may have been lost... [[1.00000000000 +/- ...e-12] + [+/- ...e-11]*I, [1.0000000000 +/- ...e-12] + [+/- ...e-12]*I] + sage: ((x - 1)^2).roots(multiplicities=False, proof=False, warn=False) + [[1.00000000000 +/- ...e-12] + [+/- ...e-11]*I, + [1.0000000000 +/- ...e-12] + [+/- ...e-12]*I] Note that coefficients in a number field with defining polynomial `x^2 + 1` are considered to be Gaussian rationals (with the @@ -8752,7 +8727,7 @@ cdef class Polynomial(CommutativePolynomial): sage: eq.roots(multiplicities=False) # needs sage.libs.pari [3109038, 17207405] - Test that roots in fixed modulus p-adic fields work (:issue:`17598`):: + Test that roots in fixed modulus `p`-adic fields work (:issue:`17598`):: sage: len(cyclotomic_polynomial(3).roots(ZpFM(739, 566))) # needs sage.rings.padics 2 @@ -8851,7 +8826,7 @@ cdef class Polynomial(CommutativePolynomial): 'you expect.') import numpy - from numpy.linalg.linalg import LinAlgError + from numpy.linalg import LinAlgError from sage.rings.complex_double import CDF numpy_dtype = ('complex' if input_complex else 'double') @@ -9269,7 +9244,6 @@ cdef class Polynomial(CommutativePolynomial): 5 sage: pol.number_of_roots_in_interval(0, 2) 3 - """ pol = self // self.gcd(self.derivative()) # squarefree part if a is None: @@ -9503,9 +9477,9 @@ cdef class Polynomial(CommutativePolynomial): - ``self`` -- polynomial with rational or integer coefficients - - ``return_q`` -- (default ``False``) if ``True``, return a second value `q` - which is the prime power with respect to which this is `q`-Weil, - or 0 if there is no such value. + - ``return_q`` -- (default: ``False``) if ``True``, return a second + value `q` which is the prime power with respect to which this is + `q`-Weil, or 0 if there is no such value EXAMPLES:: @@ -9691,7 +9665,6 @@ cdef class Polynomial(CommutativePolynomial): sage: h1.xgcd(h2) (x*y, 1, 0) sage: del R._xgcd_univariate_polynomial - """ if hasattr(self.base_ring(), '_xgcd_univariate_polynomial'): return self.base_ring()._xgcd_univariate_polynomial(self, other) @@ -9930,7 +9903,7 @@ cdef class Polynomial(CommutativePolynomial): def args(self): """ Return the generator of this polynomial ring, which is the (only) - argument used when calling self. + argument used when calling ``self``. EXAMPLES:: @@ -9988,7 +9961,7 @@ cdef class Polynomial(CommutativePolynomial): _p = self._parent.coerce(p) elif p is infinity.infinity: return -self.degree() - elif is_Ideal(p) and p.ring() is self._parent: # eventually need to handle fractional ideals in the fraction field + elif isinstance(p, Ideal_generic) and p.ring() is self._parent: # eventually need to handle fractional ideals in the fraction field if self._parent.base_ring().is_field(): # common case _p = p.gen() else: @@ -10106,8 +10079,6 @@ cdef class Polynomial(CommutativePolynomial): True sage: x.is_irreducible.cache # needs sage.libs.pari True - - """ if self.is_zero(): return False @@ -10205,7 +10176,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef Polynomial truncate(self, long n): r""" Return the polynomial of degree `< n` which is equivalent - to self modulo `x^n`. + to ``self`` modulo `x^n`. EXAMPLES:: @@ -10221,7 +10192,7 @@ cdef class Polynomial(CommutativePolynomial): """ # __getitem__ already returns a polynomial!! # We must not have check=False, since 0 must not have _coeffs = [0]. - return self._parent(self[:n])#, check=False) + return self._parent(self[:n]) # , check=False) cdef _inplace_truncate(self, long prec): return self.truncate(prec) @@ -10342,7 +10313,6 @@ cdef class Polynomial(CommutativePolynomial): sage: (x^2).is_squarefree() True sage: del(QQbar._is_squarefree_univariate_polynomial) - """ B = self._parent.base_ring() if B not in sage.categories.integral_domains.IntegralDomains(): @@ -10366,7 +10336,6 @@ cdef class Polynomial(CommutativePolynomial): False sage: (x*(x+1)).is_squarefree() # indirect doctest # needs sage.rings.number_field True - """ B = self.parent().base_ring() @@ -10413,7 +10382,8 @@ cdef class Polynomial(CommutativePolynomial): sage: radical(12 * x^5) 6*x - If self has a factor of multiplicity divisible by the characteristic (see :issue:`8736`):: + If ``self`` has a factor of multiplicity divisible by the + characteristic (see :issue:`8736`):: sage: P. = GF(2)[] sage: (x^3 + x^2).radical() # needs sage.rings.finite_rings @@ -10468,10 +10438,7 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - - ``p`` -- (positive integer or +infinity) the degree - of the norm - + - ``p`` -- positive integer or +infinity; the degree of the norm EXAMPLES:: @@ -10534,7 +10501,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef long number_of_terms(self) noexcept: """ - Return the number of non-zero coefficients of ``self``. + Return the number of nonzero coefficients of ``self``. Also called weight, Hamming weight or sparsity. @@ -10571,7 +10538,7 @@ cdef class Polynomial(CommutativePolynomial): def map_coefficients(self, f, new_base_ring=None): """ - Return the polynomial obtained by applying ``f`` to the non-zero + Return the polynomial obtained by applying ``f`` to the nonzero coefficients of ``self``. If ``f`` is a :class:`sage.categories.map.Map`, then the resulting @@ -10581,10 +10548,10 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``f`` -- a callable that will be applied to the coefficients of ``self``. + - ``f`` -- a callable that will be applied to the coefficients of ``self`` - - ``new_base_ring`` (optional) -- if given, the resulting polynomial - will be defined over this ring. + - ``new_base_ring`` -- (optional) if given, the resulting polynomial + will be defined over this ring EXAMPLES:: @@ -10632,9 +10599,9 @@ cdef class Polynomial(CommutativePolynomial): R = R.change_ring(new_base_ring) elif isinstance(f, Map): R = R.change_ring(f.codomain()) - return R({k: f(v) for k, v in self.dict().items()}) + return R({k: f(v) for k, v in self.monomial_coefficients().items()}) - def is_cyclotomic(self, certificate=False, algorithm="pari"): + def is_cyclotomic(self, certificate=False, algorithm='pari'): r""" Test if this polynomial is a cyclotomic polynomial. @@ -10642,7 +10609,7 @@ cdef class Polynomial(CommutativePolynomial): all roots are roots of unity. By default the answer is a boolean. But if ``certificate`` is ``True``, - the result is a non-negative integer: it is ``0`` if ``self`` is not + the result is a nonnegative integer: it is ``0`` if ``self`` is not cyclotomic, and a positive integer ``n`` if ``self`` is the `n`-th cyclotomic polynomial. @@ -10654,10 +10621,10 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``certificate`` -- boolean, default to ``False``. Only works with - ``algorithm`` set to ``"pari"``. + - ``certificate`` -- boolean (default: ``False``); only works with + ``algorithm`` set to ``'pari'`` - - ``algorithm`` -- either ``"pari"`` or ``"sage"`` (default is ``"pari"``) + - ``algorithm`` -- either ``'pari'`` (default) or ``'sage'`` ALGORITHM: @@ -10693,14 +10660,14 @@ cdef class Polynomial(CommutativePolynomial): sage: # needs sage.libs.pari sage: f = x^16 + x^14 - x^10 + x^8 - x^6 + x^2 + 1 - sage: f.is_cyclotomic(algorithm="pari") + sage: f.is_cyclotomic(algorithm='pari') False - sage: f.is_cyclotomic(algorithm="sage") + sage: f.is_cyclotomic(algorithm='sage') False sage: g = x^16 + x^14 - x^10 - x^8 - x^6 + x^2 + 1 - sage: g.is_cyclotomic(algorithm="pari") + sage: g.is_cyclotomic(algorithm='pari') True - sage: g.is_cyclotomic(algorithm="sage") + sage: g.is_cyclotomic(algorithm='sage') True sage: y = polygen(QQ) @@ -10711,7 +10678,7 @@ cdef class Polynomial(CommutativePolynomial): Invalid arguments:: - sage: (x - 3).is_cyclotomic(algorithm="sage", certificate=True) # needs sage.libs.pari + sage: (x - 3).is_cyclotomic(algorithm='sage', certificate=True) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: no implementation of the certificate within Sage @@ -10722,20 +10689,20 @@ cdef class Polynomial(CommutativePolynomial): sage: (z - 1).is_cyclotomic() Traceback (most recent call last): ... - NotImplementedError: not implemented in non-zero characteristic + NotImplementedError: not implemented in nonzero characteristic TESTS:: sage: R = ZZ['x'] sage: for _ in range(20): # needs sage.libs.pari ....: p = R.random_element(degree=randint(10,20)) - ....: ans_pari = p.is_cyclotomic(algorithm="pari") - ....: ans_sage = p.is_cyclotomic(algorithm="sage") + ....: ans_pari = p.is_cyclotomic(algorithm='pari') + ....: ans_sage = p.is_cyclotomic(algorithm='sage') ....: assert ans_pari == ans_sage, "problem with p={}".format(p) sage: for d in range(2, 20): # needs sage.libs.pari ....: p = cyclotomic_polynomial(d) - ....: assert p.is_cyclotomic(algorithm="pari"), "pari problem with p={}".format(p) - ....: assert p.is_cyclotomic(algorithm="sage"), "sage problem with p={}".format(p) + ....: assert p.is_cyclotomic(algorithm='pari'), "pari problem with p={}".format(p) + ....: assert p.is_cyclotomic(algorithm='sage'), "sage problem with p={}".format(p) Test the output type when ``certificate=True``:: @@ -10753,7 +10720,7 @@ cdef class Polynomial(CommutativePolynomial): """ S = self.base_ring() if S.characteristic() != 0: - raise NotImplementedError("not implemented in non-zero characteristic") + raise NotImplementedError("not implemented in nonzero characteristic") if S != ZZ: try: f = self.change_ring(ZZ) @@ -10800,14 +10767,14 @@ cdef class Polynomial(CommutativePolynomial): # second case selfminus = self(-gen) if f1 == selfminus: - if selfminus.leading_coefficient() < 0 and (-selfminus).is_cyclotomic(algorithm="sage"): + if selfminus.leading_coefficient() < 0 and (-selfminus).is_cyclotomic(algorithm='sage'): return True - elif selfminus.is_cyclotomic(algorithm="sage"): + elif selfminus.is_cyclotomic(algorithm='sage'): return True # third case, we need to take a square root ans, ff1 = f1.is_square(True) - return ans and ff1.is_cyclotomic(algorithm="sage") + return ans and ff1.is_cyclotomic(algorithm='sage') def is_cyclotomic_product(self): r""" @@ -10841,10 +10808,10 @@ cdef class Polynomial(CommutativePolynomial): sage: (x - 1).is_cyclotomic_product() Traceback (most recent call last): ... - NotImplementedError: not implemented in non-zero characteristic + NotImplementedError: not implemented in nonzero characteristic """ if self.base_ring().characteristic() != 0: - raise NotImplementedError("not implemented in non-zero characteristic") + raise NotImplementedError("not implemented in nonzero characteristic") if self.base_ring() != ZZ: try: f = self.change_ring(ZZ) @@ -10902,11 +10869,11 @@ cdef class Polynomial(CommutativePolynomial): sage: (x-1).cyclotomic_part() Traceback (most recent call last): ... - NotImplementedError: not implemented in non-zero characteristic + NotImplementedError: not implemented in nonzero characteristic """ S = self.base_ring() if S.characteristic(): - raise NotImplementedError("not implemented in non-zero characteristic") + raise NotImplementedError("not implemented in nonzero characteristic") if not S.is_exact(): raise NotImplementedError("not implemented for inexact base rings") R = self._parent @@ -11063,7 +11030,6 @@ cdef class Polynomial(CommutativePolynomial): sage: f = x^2 + x + 1 sage: f.homogenize(0) 3*x^2 - """ if self.is_homogeneous(): return self @@ -11285,7 +11251,7 @@ cdef class Polynomial(CommutativePolynomial): The method might fail if the exponent ``n`` or the coefficient of lowest degree is not invertible in the base ring. In both cases an - ``ArithmeticError`` is raised. + :exc:`ArithmeticError` is raised. INPUT: @@ -11293,7 +11259,7 @@ cdef class Polynomial(CommutativePolynomial): - ``prec`` -- positive integer; the precision of the result - - ``start`` -- optional; the first term of the result. This + - ``start`` -- (optional) the first term of the result. This is only considered when the valuation is zero, i.e. when the polynomial has a nonzero constant term. @@ -11554,7 +11520,6 @@ cdef class Polynomial(CommutativePolynomial): phi = SpecializationMorphism(self._parent,D) return phi(self) - def _log_series(self, long n): r""" Return the power series expansion of logarithm of this polynomial, @@ -11711,6 +11676,7 @@ cdef class Polynomial(CommutativePolynomial): """ raise NotImplementedError + # ----------------- inner functions ------------- # Cython can't handle function definitions inside other function @@ -11766,6 +11732,7 @@ cdef list do_schoolbook_product(list x, list y, Py_ssize_t deg): coeffs[k] = sum return coeffs + @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) @@ -11777,11 +11744,11 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh INPUT: - - `left`: a list representing a polynomial - - `right`: a list representing a polynomial - - `K_threshold`: an Integer, a threshold to pass to the classical - quadratic algorithm. During Karatsuba recursion, if one of the lists - has length <= K_threshold the classical product is used instead. + - ``left`` -- list representing a polynomial + - ``right`` -- list representing a polynomial + - ``K_threshold`` -- an Integer, a threshold to pass to the classical + quadratic algorithm. During Karatsuba recursion, if one of the lists + has length <= K_threshold the classical product is used instead. TESTS: @@ -11848,6 +11815,7 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh output.extend(carry[n-1:]) return output + @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) @@ -11856,25 +11824,23 @@ cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold,Py_ssize_t Core routine for Karatsuba multiplication. This function works for two polynomials of the same degree. - Input: + INPUT: - - left: a list containing a slice representing a polynomial - - right: a list containing the slice representing a polynomial with the - same length as left - - K_threshold: an integer. For lists of length <= K_threshold, the - quadratic polynomial multiplication is used. - - start_l: the index of left where the actual polynomial starts - - start_r: the index of right where the actual polynomial starts - - num_elts: the length of the polynomials. + - ``left`` -- list containing a slice representing a polynomial + - ``right`` -- list containing the slice representing a polynomial with the + same length as ``left`` + - ``K_threshold`` -- integer; for lists of ``length <= K_threshold``, the + quadratic polynomial multiplication is used + - ``start_l`` -- the index of ``left`` where the actual polynomial starts + - ``start_r`` -- the index of ``right`` where the actual polynomial starts + - ``num_elts`` -- the length of the polynomials Thus, the actual polynomials we want to multiply are represented by the - slices: left[ start_l: start_l+num_elts ], right[ right_l: right_l+num_elts ]. + slices: ``left[ start_l: start_l+num_elts ]``, ``right[ right_l: right_l+num_elts ]``. We use this representation in order to avoid creating slices of lists and create smaller lists. - Output: - - - a list representing the product of the polynomials + OUTPUT: list representing the product of the polynomials Doctested indirectly in _mul_karatsuba @@ -12140,7 +12106,7 @@ cdef class Polynomial_generic_dense(Polynomial): sage: class BrokenRational(Rational): ....: def __bool__(self): - ....: raise NotImplementedError("cannot check whether number is non-zero") + ....: raise NotImplementedError("cannot check whether number is nonzero") ....: sage: z = BrokenRational() sage: R. = QQ[] @@ -12148,7 +12114,7 @@ cdef class Polynomial_generic_dense(Polynomial): sage: Polynomial_generic_dense(R, [z]) Traceback (most recent call last): ... - NotImplementedError: cannot check whether number is non-zero + NotImplementedError: cannot check whether number is nonzero """ cdef list x = self._coeffs cdef Py_ssize_t n = len(x) - 1 @@ -12385,7 +12351,6 @@ cdef class Polynomial_generic_dense(Polynomial): sage: type(f.degree()) - """ return smallInteger(len(self._coeffs) - 1) @@ -12439,8 +12404,8 @@ cdef class Polynomial_generic_dense(Polynomial): Return the quotient and remainder of the Euclidean division of ``self`` and ``other``. - Raises a :class:`ZeroDivisionError` if ``other`` is zero. Raises an - :class:`ArithmeticError` if the division is not exact. + Raises a :exc:`ZeroDivisionError` if ``other`` is zero. Raises an + :exc:`ArithmeticError` if the division is not exact. EXAMPLES:: @@ -12543,7 +12508,7 @@ cdef class Polynomial_generic_dense(Polynomial): cpdef Polynomial truncate(self, long n): r""" Return the polynomial of degree `< n` which is equivalent - to self modulo `x^n`. + to ``self`` modulo `x^n`. EXAMPLES:: @@ -12581,6 +12546,7 @@ cdef class Polynomial_generic_dense(Polynomial): self._coeffs = self._coeffs[:n] return self + def make_generic_polynomial(parent, coeffs): return parent(coeffs) @@ -12627,13 +12593,13 @@ def universal_discriminant(n): cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): r""" - Generic truncated power algorithm + Generic truncated power algorithm. INPUT: - ``p`` -- a polynomial - - ``n`` -- an integer (of type :class:`sage.rings.integer.Integer`) + - ``n`` -- integer (of type :class:`sage.rings.integer.Integer`) - ``prec`` -- a precision (should fit into a C ``long``) @@ -12652,7 +12618,7 @@ cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): ....: assert p.power_trunc(n, prec) == generic_power_trunc(p, n, prec), "p = {} n = {} prec = {}".format(p, n, prec) """ if mpz_sgn(n.value) < 0: - raise ValueError("n must be a non-negative integer") + raise ValueError("n must be a nonnegative integer") elif prec <= 0: return p._parent.zero() @@ -12721,11 +12687,11 @@ cpdef list _dict_to_list(dict x, zero): if isinstance(n, tuple): # a mpoly dict n = n[0] v = [zero] * (n+1) - for i, z in x.iteritems(): + for i, z in x.items(): v[i[0]] = z else: v = [zero] * (n+1) - for i, z in x.iteritems(): + for i, z in x.items(): v[i] = z return v @@ -12763,9 +12729,9 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): r""" INPUT: - - ``secure`` -- a boolean (default: ``False``) + - ``secure`` -- boolean (default: ``False``) - OUTPUT: The degree of ``self``. + OUTPUT: the degree of ``self`` If ``secure`` is ``True`` and the degree of this polynomial is not determined (because the leading coefficient is @@ -13102,7 +13068,6 @@ cdef class PolynomialBaseringInjection(Morphism): sage: R.is_subring(S) # indirect doctest True - """ return True @@ -13115,7 +13080,6 @@ cdef class PolynomialBaseringInjection(Morphism): sage: R. = ZZ[] sage: R.coerce_map_from(ZZ).is_surjective() False - """ return False diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 370d8f22fc6..c3df26200e2 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -39,16 +39,16 @@ except ImportError: pari_gen = () -from sage.structure.richcmp import richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn from sage.structure.element import coerce_binop, parent +from sage.structure.factorization import Factorization +from sage.structure.richcmp import richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn from sage.rings.infinity import infinity, Infinity from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer -from sage.structure.factorization import Factorization - from sage.rings.padics.precision_error import PrecisionError + class Polynomial_generic_sparse(Polynomial): """ A generic sparse polynomial. @@ -80,7 +80,6 @@ class Polynomial_generic_sparse(Polynomial): s + Tbar sage: (s + T)**2 s^2 + 2*Tbar*s + 4 - """ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): """ @@ -100,18 +99,18 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): R = parent.base_ring() if isinstance(x, Polynomial): if x.parent() == self.parent(): - x = dict(x.dict()) + x = x.monomial_coefficients() elif x.parent() == R: - x = {0:x} + x = {0: x} else: w = {} - for n, c in x.dict().items(): + for n, c in x.monomial_coefficients().items(): w[n] = R(c) # The following line has been added in github issue #9944. # Apparently, the "else" case has never occurred before. x = w elif isinstance(x, (list, tuple)): - x = dict((i, c) for (i, c) in enumerate(x) if c) + x = {i: c for i, c in enumerate(x) if c} elif isinstance(x, pari_gen): y = {} for i in range(len(x)): @@ -119,7 +118,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): x = y check = True elif not isinstance(x, dict): - x = {0:x} # constant polynomials + x = {0: x} # constant polynomials if check: self.__coeffs = {} for i, z in x.items(): @@ -129,7 +128,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): if check: self.__normalize() - def dict(self): + def monomial_coefficients(self): """ Return a new copy of the dict of the underlying elements of ``self``. @@ -139,14 +138,21 @@ def dict(self): sage: R. = PolynomialRing(Integers(8), sparse=True) sage: f = 5 + w^1997 - w^10000; f 7*w^10000 + w^1997 + 5 - sage: d = f.dict(); d + sage: d = f.monomial_coefficients(); d {0: 5, 1997: 1, 10000: 7} sage: d[0] = 10 + sage: f.monomial_coefficients() + {0: 5, 1997: 1, 10000: 7} + + ``dict`` is an alias:: + sage: f.dict() {0: 5, 1997: 1, 10000: 7} """ return dict(self.__coeffs) + dict = monomial_coefficients + def coefficients(self, sparse=True): """ Return the coefficients of the monomials appearing in ``self``. @@ -569,7 +575,6 @@ def __floordiv__(self, right): -3/2 sage: f.quo_rem(1+2*x) (4*x^2 + 4*x + 5/2, -3/2) - """ P = self.parent() if P is parent(right): @@ -801,10 +806,10 @@ def quo_rem(self, other): Return the quotient and remainder of the Euclidean division of ``self`` and ``other``. - Raises :class:`ZeroDivisionError` if ``other`` is zero. + Raises :exc:`ZeroDivisionError` if ``other`` is zero. - Raises :class:`ArithmeticError` if ``other`` has a nonunit leading coefficient - and this causes the Euclidean division to fail. + Raises :exc:`ArithmeticError` if ``other`` has a nonunit leading + coefficient and this causes the Euclidean division to fail. EXAMPLES:: @@ -906,26 +911,26 @@ def quo_rem(self, other): return (quo,rem) @coerce_binop - def gcd(self,other,algorithm=None): + def gcd(self, other, algorithm=None): r""" - Return the gcd of this polynomial and ``other`` + Return the gcd of this polynomial and ``other``. INPUT: - ``other`` -- a polynomial defined over the same ring as this - polynomial. + polynomial ALGORITHM: Two algorithms are provided: - - ``generic`` -- Uses the generic implementation, which depends on the - base ring being a UFD or a field. - - ``dense`` -- The polynomials are converted to the dense representation, - their gcd is computed and is converted back to the sparse - representation. + - ``'generic'`` -- uses the generic implementation, which depends on the + base ring being a UFD or a field + - ``'dense'`` -- the polynomials are converted to the dense + representation, their gcd is computed and is converted back to the + sparse representation - Default is ``dense`` for polynomials over `\ZZ` and ``generic`` in the + Default is ``'dense'`` for polynomials over `\ZZ` and ``'generic'`` in the other cases. EXAMPLES:: @@ -935,11 +940,11 @@ def gcd(self,other,algorithm=None): sage: q = 2*x^4 - x^3 - 2*x^2 - 4*x - 1 sage: gcd(p, q) x^2 + x + 1 - sage: gcd(p, q, algorithm="dense") + sage: gcd(p, q, algorithm='dense') x^2 + x + 1 - sage: gcd(p, q, algorithm="generic") + sage: gcd(p, q, algorithm='generic') x^2 + x + 1 - sage: gcd(p, q, algorithm="foobar") + sage: gcd(p, q, algorithm='foobar') Traceback (most recent call last): ... ValueError: Unknown algorithm 'foobar' @@ -1352,8 +1357,8 @@ def factor_of_slope(self, slope=None): """ INPUT: - - ``slope`` -- a rational number (default: the first slope - in the Newton polygon of ``self``) + - ``slope`` -- a rational number (default: the first slope + in the Newton polygon of ``self``) OUTPUT: @@ -1494,17 +1499,15 @@ def _roots(self, secure, minval, hint): INPUT: - - ``secure`` -- a boolean; whether we raise an error or + - ``secure`` -- boolean; whether we raise an error or not in case of multiple roots - - ``minval`` -- an integer + - ``minval`` -- integer - - ``hint`` -- a list or ``None``; if given, it must be the + - ``hint`` -- list or ``None``; if given, it must be the list of roots of the residual polynomial of slope ``minval`` - OUTPUT: - - A list of pairs ``(root, multiplicity)`` + OUTPUT: list of pairs ``(root, multiplicity)`` TESTS:: @@ -1513,13 +1516,12 @@ def _roots(self, secure, minval, hint): sage: S. = R[] sage: P = (x-1) * (x-2) * (x-4) * (x-8) * (x-16) sage: Q = P^2 - sage: Q.roots(algorithm="sage") # indirect doctest + sage: Q.roots(algorithm='sage') # indirect doctest [(2^4 + O(2^14), 2), (2^3 + O(2^13), 2), (2^2 + O(2^12), 2), (2 + O(2^11), 2), (1 + O(2^10), 2)] - """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing K = self.base_ring() diff --git a/src/sage/rings/polynomial/polynomial_fateman.py b/src/sage/rings/polynomial/polynomial_fateman.py index 8ccf13eba09..ab13dd72708 100644 --- a/src/sage/rings/polynomial/polynomial_fateman.py +++ b/src/sage/rings/polynomial/polynomial_fateman.py @@ -16,9 +16,11 @@ def _mul_fateman_to_int2(f_list, g_list): """ - Convert a polynomial to an integer by evaluating it + Convert a polynomial to an integer by evaluating it. - INPUT: p, a list of integers + INPUT: + + - ``f_list``, ``g_list`` -- lists of integers OUTPUT: padding """ @@ -30,11 +32,10 @@ def _mul_fateman_to_int2(f_list, g_list): def _mul_fateman_to_poly(number, padding): """ - Converts a number to a polynomial, according to a padding. - - OUTPUT: + Convert a number to a polynomial, according to a padding. - a list containing the coefficient of a polynomial of degree len(list) + OUTPUT: list containing the coefficient of a polynomial of degree + ``len(list)`` """ coeffs = [] flag = 0 diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pyx b/src/sage/rings/polynomial/polynomial_gf2x.pyx index c3bafe951ca..cf4a224dda9 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pyx +++ b/src/sage/rings/polynomial/polynomial_gf2x.pyx @@ -256,6 +256,12 @@ cdef class Polynomial_GF2X(Polynomial_template): verbose("Res %5.3f s"%cputime(t),level=1) return res + # Other polynomials have compose_mod as methods following the naming of + # NTL/Flint bindings but the above method predates these. We expose + # compose_mod here so all polynomial ring elements which support this can + # use either name + compose_mod = modular_composition + @cached_method def is_irreducible(self): r""" @@ -277,7 +283,6 @@ cdef class Polynomial_GF2X(Polynomial_template): False sage: f.is_irreducible.cache False - """ return 0 != GF2X_IterIrredTest(self.x) @@ -310,6 +315,7 @@ def GF2X_BuildIrred_list(n): GF2X_BuildIrred(f, int(n)) return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in range(n + 1)] + def GF2X_BuildSparseIrred_list(n): """ Return the list of coefficients of an irreducible polynomial of @@ -330,6 +336,7 @@ def GF2X_BuildSparseIrred_list(n): GF2X_BuildSparseIrred(f, int(n)) return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in range(n + 1)] + def GF2X_BuildRandomIrred_list(n): """ Return the list of coefficients of an irreducible polynomial of diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx index 3f38f23ffdc..fc2ab9b584e 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx @@ -102,17 +102,16 @@ cdef class Polynomial_integer_dense_flint(Polynomial): """ fmpz_poly_init(self._poly) - def __dealloc__(self): r""" - calls the underlying FLINT fmpz_poly destructor + Call the underlying FLINT fmpz_poly destructor """ fmpz_poly_clear(self._poly) cdef Polynomial_integer_dense_flint _new(self): r""" - Quickly creates a new initialized Polynomial_integer_dense_flint - with the correct parent and _is_gen == 0. + Quickly create a new initialized ``Polynomial_integer_dense_flint`` + with the correct parent and ``_is_gen == 0``. """ cdef Polynomial_integer_dense_flint x = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint) x._parent = self._parent @@ -121,19 +120,18 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef Polynomial _new_constant_poly(self, a, Parent P): r""" - Quickly creates a new constant polynomial with value a in parent P + Quickly create a new constant polynomial with value ``a`` in parent ``P``. ASSUMPTION: - The given value has to be in the base ring of P. This assumption is not - verified. + The given value has to be in the base ring of ``P``. This assumption is + not verified. EXAMPLES:: sage: R. = ZZ[] sage: x._new_constant_poly(2,R) 2 - """ cdef Polynomial_integer_dense_flint x = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint) x._parent = P @@ -212,7 +210,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: ZZ['x']({2^3: 1}) x^8 - """ Polynomial.__init__(self, parent, is_gen=is_gen) @@ -364,7 +361,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def __call__(self, *x, **kwds): """ - Calls this polynomial with the given parameters, which can be + Call this polynomial with the given parameters, which can be interpreted as polynomial composition or evaluation by this method. @@ -504,7 +501,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: R(-1).content() -1 - """ if self.is_zero(): return ZZ.zero() @@ -655,7 +651,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sig_off() return x - cpdef _sub_(self, right): r""" Return ``self`` minus ``right``. @@ -675,7 +670,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sig_off() return x - cpdef _neg_(self): r""" Return negative of ``self``. @@ -837,7 +831,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sig_off() return x - @coerce_binop def lcm(self, right): """ @@ -958,7 +951,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): else: return self._parent(rr), ss, tt - cpdef _mul_(self, right): r""" Return ``self`` multiplied by ``right``. @@ -978,7 +970,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef Polynomial _mul_trunc_(self, Polynomial right, long n): r""" - Truncated multiplication + Truncated multiplication. .. SEEALSO:: @@ -1043,7 +1035,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sig_off() return x - def __pow__(Polynomial_integer_dense_flint self, exp, ignored): + def __pow__(Polynomial_integer_dense_flint self, exp, mod): """ EXAMPLES:: @@ -1122,10 +1114,23 @@ cdef class Polynomial_integer_dense_flint(Polynomial): ... TypeError: no canonical coercion from Univariate Polynomial Ring in R over Integer Ring to Rational Field + + Check that using third argument raises an error:: + + sage: R. = PolynomialRing(ZZ, implementation='FLINT') + sage: pow(x, 2, x) + Traceback (most recent call last): + ... + NotImplementedError: pow() with a modulus is not implemented for this ring """ cdef long nn cdef Polynomial_integer_dense_flint res + if mod is not None: + raise NotImplementedError( + "pow() with a modulus is not implemented for this ring" + ) + try: nn = pyobject_to_long(exp) except TypeError: @@ -1167,7 +1172,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef Polynomial _power_trunc(self, unsigned long n, long prec): r""" - Truncated power + Truncated power. TESTS:: @@ -1310,10 +1315,10 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _unsafe_mutate(self, long n, value): r""" - Sets coefficient of `x^n` to value. + Set coefficient of `x^n` to value. This is very unsafe, because Sage polynomials are supposed to be - immutable. (Shhhh don't tell anyone!) + immutable. EXAMPLES:: @@ -1363,11 +1368,10 @@ cdef class Polynomial_integer_dense_flint(Polynomial): return real_roots(self) -## def __copy__(self): -## f = Polynomial_integer_dense(self.parent()) -## f._poly = self._poly.copy() -## return f - + # def __copy__(self): + # f = Polynomial_integer_dense(self.parent()) + # f._poly = self._poly.copy() + # return f def degree(self, gen=None): """ @@ -1488,7 +1492,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): variable = self.parent().variable_name() return pari(self.list()).Polrev(variable) - def squarefree_decomposition(Polynomial_integer_dense_flint self): """ Return the square-free decomposition of ``self``. This is @@ -1515,7 +1518,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: f=-x^2 sage: f.squarefree_decomposition() (-1) * x^2 - """ cdef ZZX_c** v cdef long* e @@ -1658,7 +1660,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): - ``p`` -- prime - OUTPUT: factorization of ``self`` reduced modulo `p`. + OUTPUT: factorization of ``self`` reduced modulo `p` EXAMPLES:: @@ -1698,7 +1700,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): - ``prec`` -- integer; the precision - OUTPUT: factorization of ``self`` over the completion at `p`. + OUTPUT: factorization of ``self`` over the completion at `p` EXAMPLES:: @@ -1714,7 +1716,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: f.factor_padic(5, 10) (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 * ((5 + O(5^10))*x + 1 + O(5^10))^2 - """ from sage.rings.padics.factory import Zp @@ -1748,7 +1749,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): """ return [self.get_unsafe(i) for i in range(self.degree()+1)] - @coerce_binop def resultant(self, other, proof=True): """ @@ -1815,7 +1815,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: p.reverse(degree=1.5r) Traceback (most recent call last): ... - ValueError: degree argument must be a non-negative integer, got 1.5 + ValueError: degree argument must be a nonnegative integer, got 1.5 Check that this implementation is compatible with the generic one:: @@ -1828,10 +1828,10 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cdef unsigned long d if degree is not None: if degree < 0: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) d = degree if d != degree: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) # FLINT expects length fmpz_poly_reverse(res._poly, self._poly, d+1) else: @@ -1853,7 +1853,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: f.revert_series(-1) Traceback (most recent call last): ... - ValueError: argument n must be a non-negative integer, got -1 + ValueError: argument n must be a nonnegative integer, got -1 sage: g = - t^3 + t^5 sage: g.revert_series(6) @@ -1864,7 +1864,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cdef Polynomial_integer_dense_flint res = self._new() cdef unsigned long m if n < 0: - raise ValueError("argument n must be a non-negative integer, got {}".format(n)) + raise ValueError("argument n must be a nonnegative integer, got {}".format(n)) m = n if not self[0].is_zero() or not self[1].is_unit(): raise ValueError("self must have constant coefficient 0 and a unit for coefficient {}^1".format(self.parent().gen())) diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx index c4f175040bb..142c7b324ad 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @@ -69,21 +69,21 @@ from sage.libs.ntl.ZZX cimport * from sage.rings.polynomial.evaluation_ntl cimport ZZX_evaluation_mpfr, ZZX_evaluation_mpfi + cdef class Polynomial_integer_dense_ntl(Polynomial): r""" A dense polynomial over the integers, implemented via NTL. """ cdef Polynomial_integer_dense_ntl _new(self): r""" - Quickly creates a new initialized Polynomial_integer_dense_ntl - with the correct parent and _is_gen == 0. + Quickly create a new initialized ``Polynomial_integer_dense_ntl`` + with the correct parent and ``_is_gen == 0``. """ cdef Polynomial_integer_dense_ntl x = Polynomial_integer_dense_ntl.__new__(Polynomial_integer_dense_ntl) x._parent = self._parent x._is_gen = 0 return x - def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): r""" EXAMPLES:: @@ -236,7 +236,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): mpz_to_ZZ(&y, (a).value) ZZX_SetCoeff(self._poly, i, y) - def content(self): r""" Return the greatest common divisor of the coefficients of this @@ -430,7 +429,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): cpdef _add_(self, right): r""" - Returns self plus right. + Return ``self`` plus ``right``. EXAMPLES:: @@ -445,10 +444,9 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): (right)._poly) return x - cpdef _sub_(self, right): r""" - Return self minus right. + Return ``self`` minus ``right``. EXAMPLES:: @@ -463,10 +461,9 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): (right)._poly) return x - cpdef _neg_(self): r""" - Returns negative of ``self``. + Return negative of ``self``. EXAMPLES:: @@ -479,7 +476,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): ZZX_negate(x._poly, self._poly) return x - @coerce_binop def quo_rem(self, right): r""" @@ -529,7 +525,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): (0, 0) sage: z.quo_rem(2*x) (0, 0) - """ cdef Polynomial_integer_dense_ntl _right = right @@ -566,7 +561,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): return qq, rr - @coerce_binop def gcd(self, right): r""" @@ -588,7 +582,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): del temp return x - @coerce_binop def lcm(self, right): """ @@ -678,10 +671,9 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): S = self.parent() return S(rr), ss, tt - cpdef _mul_(self, right): r""" - Returns self multiplied by right. + Return ``self`` multiplied by ``right``. EXAMPLES:: @@ -696,7 +688,8 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): cpdef _lmul_(self, Element right): r""" - Returns self multiplied by right, where right is a scalar (integer). + Return ``self`` multiplied by ``right``, where ``right`` is a scalar + (integer). EXAMPLES:: @@ -715,7 +708,8 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): cpdef _rmul_(self, Element right): r""" - Returns self multiplied by right, where right is a scalar (integer). + Return ``self`` multiplied by ``right``, where ``right`` is a scalar + (integer). EXAMPLES:: @@ -732,7 +726,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): ZZX_mul_ZZ(x._poly, self._poly, _right) return x - def __floordiv__(self, right): """ EXAMPLES:: @@ -763,10 +756,10 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def _unsafe_mutate(self, long n, value): r""" - Sets coefficient of `x^n` to value. + Set coefficient of `x^n` to ``value``. This is very unsafe, because Sage polynomials are supposed - to be immutable. (Shhhh don't tell anyone!) + to be immutable. EXAMPLES:: @@ -784,10 +777,9 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): mpz_to_ZZ(&y, (value).value) ZZX_SetCoeff(self._poly, n, y) - def real_root_intervals(self): """ - Returns isolating intervals for the real roots of this polynomial. + Return isolating intervals for the real roots of this polynomial. EXAMPLES: We compute the roots of the characteristic polynomial of some Salem numbers:: @@ -802,11 +794,10 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): return real_roots(self) -## def __copy__(self): -## f = Polynomial_integer_dense(self.parent()) -## f._poly = self._poly.copy() -## return f - + # def __copy__(self): + # f = Polynomial_integer_dense(self.parent()) + # f._poly = self._poly.copy() + # return f def degree(self, gen=None): """ @@ -854,7 +845,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): del temp return x - def __pari__(self, variable=None): """ EXAMPLES:: @@ -868,7 +858,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): variable = self.parent().variable_name() return pari(self.list()).Polrev(variable) - def squarefree_decomposition(self): """ Return the square-free decomposition of ``self``. This is @@ -892,7 +881,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): sage: f = -x^2 sage: f.squarefree_decomposition() (-1) * x^2 - """ cdef Polynomial_integer_dense_ntl p = self c = p.content() @@ -916,7 +904,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def _factor_pari(self): """ - Use pari to factor self. + Use pari to factor ``self``. EXAMPLES:: @@ -932,7 +920,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def _factor_ntl(self): """ - Use NTL to factor self. + Use NTL to factor ``self``. AUTHOR: @@ -1012,7 +1000,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): - ``p`` -- prime - OUTPUT: factorization of ``self`` reduced modulo `p`. + OUTPUT: factorization of ``self`` reduced modulo `p` EXAMPLES:: @@ -1052,9 +1040,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): - ``prec`` -- integer; the precision - OUTPUT: - - - factorization of ``self`` over the completion at `p`. + OUTPUT: factorization of ``self`` over the completion at `p` EXAMPLES:: @@ -1070,7 +1056,6 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): sage: f.factor_padic(5, 10) (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 * ((5 + O(5^10))*x + 1 + O(5^10))^2 - """ from sage.rings.padics.factory import Zp @@ -1104,11 +1089,10 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): """ return [self.get_unsafe(i) for i in range(self.degree()+1)] - @coerce_binop def resultant(self, other, proof=True): """ - Returns the resultant of ``self`` and ``other``, which must lie in the same + Return the resultant of ``self`` and ``other``, which must lie in the same polynomial ring. If ``proof=False`` (the default is ``proof=True``), then this function may use a diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index 29c75a19d30..68605382f1f 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -96,7 +96,6 @@ cdef class Polynomial_dense_mod_n(Polynomial): sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_mod_n sage: isinstance(f, Polynomial_dense_mod_n) True - """ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): @@ -425,6 +424,49 @@ cdef class Polynomial_dense_mod_n(Polynomial): """ return small_roots(self, *args, **kwds) + def compose_mod(self, other, modulus): + r""" + Compute `f(g) \pmod h`. + + To be precise about the order fo compostion, given ``self``, ``other`` + and ``modulus`` as `f(x)`, `g(x)` and `h(x)` compute `f(g(x)) \bmod h(x)`. + + INPUT: + + - ``other`` -- a polynomial `g(x)` + - ``modulus`` -- a polynomial `h(x)` + + EXAMPLES:: + + sage: R. = GF(2**127 - 1)[] + sage: f = R.random_element() + sage: g = R.random_element() + sage: g.compose_mod(g, f) == g(g) % f + True + + sage: R. = GF(163)[] + sage: f = R([i for i in range(100)]) + sage: g = R([i**2 for i in range(100)]) + sage: h = 1 + x + x**5 + sage: f.compose_mod(g, h) + 82*x^4 + 56*x^3 + 45*x^2 + 60*x + 127 + sage: f.compose_mod(g, h) == f(g) % h + True + + AUTHORS: + + - Giacomo Pope (2024-08) initial implementation + """ + elt = self.ntl_ZZ_pX() + mod = modulus.ntl_ZZ_pX() + other = other.ntl_ZZ_pX() + res = elt.compose_mod(other, mod) + return self.parent()(res, construct=True) + + # compose_mod is the natural name from the NTL bindings, but polynomial_gf2x + # has modular_composition as the method name so here we allow both + modular_composition = compose_mod + def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds): r""" @@ -446,9 +488,9 @@ def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds): - ``X`` -- an absolute bound for the root (default: see above) - ``beta`` -- compute a root mod `b` where `b` is a factor of `N` and `b - \ge N^\beta`. (Default: 1.0, so `b = N`.) - - ``epsilon`` -- the parameter `\epsilon` described above. (Default: `\beta/8`) - - ``**kwds`` -- passed through to method :meth:`Matrix_integer_dense.LLL() `. + \ge N^\beta` (default: 1.0, so `b = N`.) + - ``epsilon`` -- the parameter `\epsilon` described above. (default: `\beta/8`) + - ``**kwds`` -- passed through to method :meth:`Matrix_integer_dense.LLL() ` EXAMPLES: @@ -990,7 +1032,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def shift(self, n): """ - Shift self to left by `n`, which is multiplication by `x^n`, + Shift ``self`` to left by `n`, which is multiplication by `x^n`, truncating if `n` is negative. EXAMPLES:: @@ -1011,7 +1053,6 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): True sage: p.shift(-3).is_zero() True - """ return self << n @@ -1089,8 +1130,8 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): INPUT: - - ``degree`` (``None`` or an integer) -- if specified, truncate or zero - pad the list of coefficients to this degree before reversing it. + - ``degree`` -- ``None`` or integer; if specified, truncate or zero + pad the list of coefficients to this degree before reversing it EXAMPLES:: @@ -1141,7 +1182,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def valuation(self): """ Return the valuation of ``self``, that is, the power of the - lowest non-zero monomial of ``self``. + lowest nonzero monomial of ``self``. EXAMPLES:: @@ -1193,7 +1234,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def __call__(self, *args, **kwds): """ - Evaluate self at ``x``. If ``x`` is a single argument coercible into + Evaluate ``self`` at ``x``. If ``x`` is a single argument coercible into the base ring of ``self``, this is done directly in NTL, otherwise the generic Polynomial call code is used. @@ -1212,6 +1253,22 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): sage: S. = PolynomialRing(Integers(5), implementation='NTL') sage: f(y) y^3 + 2 + + TESTS:: + + sage: R. = PolynomialRing(Integers(100), implementation='NTL') + sage: f = x^3 + 7 + sage: f(1).parent() == R.base_ring() + True + sage: f(int(1)).parent() == R.base_ring() + True + sage: f(x + 1).parent() == f.parent() + True + + sage: R. = PolynomialRing(Zmod(12), 'x', implementation='NTL') + sage: u = Zmod(4)(3) + sage: x(u).parent() == u.parent() + True """ if len(args) != 1 or len(kwds) != 0: return Polynomial.__call__(self, *args, **kwds) @@ -1232,7 +1289,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): return Polynomial.__call__(self, *args, **kwds) else: zz_pX_eval(fx.x, self.x, x.x) - return self._parent(int(fx)) + return self._parent._base(int(fx)) cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): @@ -1434,7 +1491,6 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): sage: R. = PolynomialRing(Integers(10^30), implementation='NTL') sage: type(R(0)^0) == type(R(0)) True - """ cdef bint recip = 0, do_sig cdef long e = ee @@ -1545,7 +1601,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): def shift(self, n): """ - Shift self to left by `n`, which is multiplication by `x^n`, + Shift ``self`` to left by `n`, which is multiplication by `x^n`, truncating if `n` is negative. EXAMPLES:: @@ -1566,7 +1622,6 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): True sage: p.shift(-3).is_zero() True - """ return self << n @@ -1644,8 +1699,8 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): INPUT: - - ``degree`` (``None`` or an integer) -- if specified, truncate or zero - pad the list of coefficients to this degree before reversing it. + - ``degree`` -- ``None`` or integer; if specified, truncate or zero + pad the list of coefficients to this degree before reversing it EXAMPLES:: @@ -1683,7 +1738,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): def valuation(self): """ Return the valuation of ``self``, that is, the power of the - lowest non-zero monomial of ``self``. + lowest nonzero monomial of ``self``. EXAMPLES:: @@ -1769,6 +1824,25 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): sage: S. = PolynomialRing(Integers(5), implementation='NTL') sage: f(y) y^3 + 2 + + TESTS:: + + sage: R. = PolynomialRing(Integers(10^30), implementation='NTL') + sage: f = x^3 + 7 + sage: f(1).parent() == R.base_ring() + True + sage: f(int(1)).parent() == R.base_ring() + True + sage: f(x + 1).parent() == f.parent() + True + + sage: R. = PolynomialRing(Zmod(10^30), 'x', implementation='NTL') + sage: u = Zmod(10^29)(3) + sage: x(u).parent() == u.parent() + True + sage: v = Zmod(10)(3) + sage: x(v).parent() == v.parent() + True """ if len(args) != 1 or len(kwds) != 0: return Polynomial.__call__(self, *args, **kwds) @@ -1787,7 +1861,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): return Polynomial.__call__(self, *args, **kwds) else: ZZ_pX_eval(fx.x, self.x, x.x) - return self._parent(fx._integer_()) + return self._parent._base(fx._integer_()) cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): @@ -1892,7 +1966,6 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): sage: f, g = x + 2, x^2 - 1 sage: f.gcd(g) x + 2 - """ g = self.ntl_ZZ_pX().gcd(right.ntl_ZZ_pX()) return self.parent()(g, construct=True) @@ -1924,7 +1997,6 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): (x^2 + x + 1, 0, 1) sage: ((x - 1)*(x + 1)).xgcd(x*(x - 1)) (x + 2, 1, 2) - """ r, s, t = self.ntl_ZZ_pX().xgcd(other.ntl_ZZ_pX()) return self.parent()(r, construct=True), self.parent()(s, construct=True), self.parent()(t, construct=True) diff --git a/src/sage/rings/polynomial/polynomial_number_field.pyx b/src/sage/rings/polynomial/polynomial_number_field.pyx index 80d7af0e4b1..7cef7645964 100644 --- a/src/sage/rings/polynomial/polynomial_number_field.pyx +++ b/src/sage/rings/polynomial/polynomial_number_field.pyx @@ -63,20 +63,21 @@ We can also construct polynomials over relative number fields:: 1 """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2014 Luis Felipe Tabera Alonso # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_dense_field from sage.rings.rational_field import QQ from sage.structure.element import coerce_binop from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): """ Class of dense univariate polynomials over an absolute number field. @@ -88,20 +89,20 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): INPUT: - ``parent`` -- the polynomial ring in which to construct the - element. + element - - ``x`` -- (default: None) an object representing the + - ``x`` -- (default: ``None``) an object representing the polynomial, e.g. a list of coefficients. See :meth:`sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field.__init__` for more details. - - ``check`` -- boolean (default: ``True``) if True, make sure that - the coefficients of the polynomial are in the base ring. + - ``check`` -- boolean (default: ``True``); if ``True``, make sure that + the coefficients of the polynomial are in the base ring - - ``is_gen`` -- boolean (default: ``False``) if True, `x` is the - distinguished generator of the polynomial ring. + - ``is_gen`` -- boolean (default: ``False``); if ``True``, `x` is the + distinguished generator of the polynomial ring - - ``construct`` -- (default: ``False``) boolean, unused. + - ``construct`` -- boolean (default: ``False``); unused EXAMPLES:: @@ -123,9 +124,9 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): INPUT: - - ``other`` -- a polynomial with the same parent as ``self``. + - ``other`` -- a polynomial with the same parent as ``self`` - OUTPUT: The monic gcd of ``self`` and ``other``. + OUTPUT: the monic gcd of ``self`` and ``other`` EXAMPLES:: @@ -222,20 +223,20 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): INPUT: - ``parent`` -- polynomial ring in which to construct the - element. + element - ``x`` -- (default: ``None``) an object representing the polynomial, e.g. a list of coefficients. See :meth:`sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field.__init__` for more details. - - ``check`` -- boolean (default: ``True``) if ``True``, make sure that - the coefficients of the polynomial are in the base ring. + - ``check`` -- boolean (default: ``True``); if ``True``, make sure that + the coefficients of the polynomial are in the base ring - - ``is_gen`` -- boolean (default: ``False``) if ``True``, ``x`` is the - distinguished generator of the polynomial ring. + - ``is_gen`` -- boolean (default: ``False``); if ``True``, ``x`` is the + distinguished generator of the polynomial ring - - ``construct`` -- (default: ``False``) boolean, unused. + - ``construct`` -- boolean (default: ``False``); unused EXAMPLES:: @@ -258,11 +259,9 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): INPUT: - - ``other`` -- a polynomial with the same parent as ``self``. - - OUTPUT: + - ``other`` -- a polynomial with the same parent as ``self`` - The monic gcd of ``self`` and ``other``. + OUTPUT: the monic gcd of ``self`` and ``other`` See :meth:`Polynomial_absolute_number_field_dense.gcd` for more details. diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 0ce0673ad67..e12977e8464 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -68,13 +68,13 @@ class PolynomialQuotientRingFactory(UniqueFactory): INPUT: - - ``ring`` -- a univariate polynomial ring + - ``ring`` -- a univariate polynomial ring - - ``polynomial`` -- an element of ``ring`` with a unit leading coefficient + - ``polynomial`` -- an element of ``ring`` with a unit leading coefficient - - ``names`` -- (optional) name for the variable + - ``names`` -- (optional) name for the variable - OUTPUT: Creates the quotient ring `R/I`, where `R` is the ring and `I` is + OUTPUT: creates the quotient ring `R/I`, where `R` is the ring and `I` is the principal ideal generated by ``polynomial``. EXAMPLES: @@ -175,7 +175,6 @@ class PolynomialQuotientRingFactory(UniqueFactory): sage: f = x^2 - 1 sage: R.quotient_by_principal_ideal(f) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 - """ def create_key(self, ring, polynomial, names=None): r""" @@ -212,7 +211,6 @@ def create_key(self, ring, polynomial, names=None): sage: R.quo(x + 1) is R.quo(2*x + 2) True - """ if not isinstance(ring, PolynomialRing_commutative): raise TypeError("ring must be a polynomial ring") @@ -242,7 +240,6 @@ def create_object(self, version, key): sage: PolynomialQuotientRing.create_object((8, 0, 0), ....: (R, x^2 - 1, ('xbar'))) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 - """ ring, polynomial, names = key @@ -266,6 +263,10 @@ def create_object(self, version, key): PolynomialQuotientRing = PolynomialQuotientRingFactory("PolynomialQuotientRing") def is_PolynomialQuotientRing(x): + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_PolynomialQuotientRing is deprecated; " + "use 'isinstance(..., PolynomialQuotientRing_generic)' instead.") return isinstance(x, PolynomialQuotientRing_generic) @@ -415,7 +416,6 @@ def __init__(self, ring, polynomial, name=None, category=None): ... , ... - """ if not isinstance(ring, PolynomialRing_commutative): raise TypeError("R must be a univariate polynomial ring.") @@ -447,11 +447,9 @@ def _element_constructor_(self, x): INPUT: + - ``x`` -- object to be converted - - ``x`` -- object to be converted - - - OUTPUT: an element obtained by converting x into this ring. + OUTPUT: an element obtained by converting x into this ring EXAMPLES:: @@ -525,7 +523,6 @@ def _element_constructor_(self, x): sage: Q3('x*ybar^2') -x - """ if not isinstance(x, str): try: @@ -585,7 +582,6 @@ def _coerce_map_from_(self, R): sage: Q2 = R.quo([(y^2 + 1)]) sage: Q2.has_coerce_map_from(Q1) False - """ if self.__ring.has_coerce_map_from(R): return True @@ -670,7 +666,6 @@ def lift(self, x): -2*xbar sage: Q.0^3 -2*xbar - """ return x.lift() @@ -762,7 +757,6 @@ def _singular_init_(self, S=None): _[1]=xbar^2+1 sage: singular(Q.gen()) # needs sage.libs.singular xbar - """ if S is None: from sage.interfaces.singular import singular as S @@ -780,7 +774,7 @@ def _repr_(self): def construction(self): """ - Functorial construction of ``self`` + Functorial construction of ``self``. EXAMPLES:: @@ -1067,7 +1061,6 @@ def is_field(self, proof=True): (1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring sage: F2.is_field(proof = False) False - """ ret = self.base_ring().is_field(proof) try: @@ -1266,19 +1259,17 @@ def random_element(self, degree=None, *args, **kwds): INPUT: - - ``degree`` -- Optional argument: either an integer for fixing the + - ``degree`` -- (optional) argument; either an integer for fixing the degree, or a tuple of the minimum and maximum degree. By default the degree is n - 1 with n the degree of the polynomial ring. Note that the degree of the polynomial is fixed before the modulo calculation. So when `degree` is bigger than the degree of the polynomial ring, the degree of the returned polynomial would be lower than `degree`. - - ``*args``, ``**kwds`` -- Arguments for randomization that are passed + - ``*args``, ``**kwds`` -- arguments for randomization that are passed on to the ``random_element`` method of the polynomial ring, and from there to the base ring - OUTPUT: - - Element of this quotient ring + OUTPUT: element of this quotient ring EXAMPLES:: @@ -1298,7 +1289,7 @@ def random_element(self, degree=None, *args, **kwds): @cached_method def _S_decomposition(self, S): """ - Compute the decomposition of self into a product of number fields. + Compute the decomposition of ``self`` into a product of number fields. This is an internal function used by :meth:`S_class_group`, :meth:`S_units` and :meth:`selmer_generators`. @@ -1342,10 +1333,10 @@ def _S_decomposition(self, S): if not isinstance(K, NumberField) or not self.__polynomial.is_squarefree(): raise NotImplementedError - from sage.rings.ideal import is_Ideal + from sage.rings.ideal import Ideal_generic for p in S: # second check due to inconsistency over QQ - see # 7596 - if not (is_Ideal(p) + if not (isinstance(p, Ideal_generic) and (p.ring() is K or p.ring() is K.ring_of_integers()) and p.is_prime()): raise TypeError("S must be a list of prime ideals of the base field.") @@ -1398,9 +1389,9 @@ def S_class_group(self, S, proof=True): INPUT: - - ``S`` -- a set of primes of the coefficient ring + - ``S`` -- set of primes of the coefficient ring - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: @@ -1572,7 +1563,7 @@ def class_group(self, proof=True): INPUT: - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: @@ -1668,22 +1659,21 @@ def class_group(self, proof=True): sage: type(CG[0][1]) - """ return self.S_class_group((), proof=proof) def S_units(self, S, proof=True): """ - If self is an étale algebra `D` over a number field `K` (i.e. + If ``self`` is an étale algebra `D` over a number field `K` (i.e. a quotient of `K[x]` by a squarefree polynomial) and `S` is a finite set of places of `K`, return a list of generators of the group of `S`-units of `D`. INPUT: - - ``S`` -- a set of primes of the base field + - ``S`` -- set of primes of the base field - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: @@ -1745,7 +1735,6 @@ def S_units(self, S, proof=True): sage: type(U[1][1]) - """ fields, isos, iso_classes = self._S_decomposition(tuple(S)) n = len(fields) @@ -1778,7 +1767,7 @@ def units(self, proof=True): INPUT: - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: @@ -1842,13 +1831,12 @@ def units(self, proof=True): sage: type(U[1][1]) - """ return self.S_units((), proof=proof) def selmer_generators(self, S, m, proof=True): r""" - If self is an étale algebra `D` over a number field `K` (i.e. + If ``self`` is an étale algebra `D` over a number field `K` (i.e. a quotient of `K[x]` by a squarefree polynomial) and `S` is a finite set of places of `K`, compute the Selmer group `D(S,m)`. This is the subgroup of `D^*/(D^*)^m` consisting of @@ -1857,11 +1845,11 @@ def selmer_generators(self, S, m, proof=True): INPUT: - - ``S`` -- A set of primes of the coefficient ring (which is a number field). + - ``S`` -- set of primes of the coefficient ring (which is a number field) - - ``m`` -- a positive integer + - ``m`` -- positive integer - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: @@ -1889,7 +1877,6 @@ def selmer_generators(self, S, m, proof=True): ....: K.ideal(3, a + 1), ....: K.ideal(a)], 3) [2, a + 1, -a] - """ fields, isos, iso_classes = self._S_decomposition(tuple(S)) n = len(fields) @@ -1931,7 +1918,6 @@ def _factor_multivariate_polynomial(self, f, proof=True): sage: F = t * x sage: F.factor(proof=False) # needs sage.modules (x) * t - """ from sage.structure.factorization import Factorization @@ -1963,7 +1949,6 @@ def _factor_univariate_polynomial(self, f): (T + y) * (T + y + 1) sage: (y*T^2 + y*T + y*x).factor() # indirect doctest # needs sage.modules (y) * (T + y) * (T + y + 1) - """ from sage.structure.factorization import Factorization @@ -2033,7 +2018,6 @@ def _isomorphic_ring(self): sage: R. = K[] # needs sage.rings.finite_rings sage: from_L, to_L, L = R.quo(b)._isomorphic_ring(); L # needs sage.rings.finite_rings Finite Field in a of size 2^2 - """ from sage.categories.homset import Hom from sage.categories.morphism import SetMorphism @@ -2156,7 +2140,6 @@ def _test_isomorphic_ring(self, **options): sage: R. = L[] sage: M. = L.extension(c^2 + b*c + b) sage: M._test_isomorphic_ring() - """ tester = self._tester(**options) @@ -2215,7 +2198,6 @@ class PolynomialQuotientRing_coercion(DefaultConvertMap_unique): To: Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 sage: f == g True - """ def is_injective(self): r""" @@ -2232,7 +2214,6 @@ def is_injective(self): sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)) sage: f.is_injective() True - """ if (self.domain().modulus().change_ring(self.codomain().base_ring()) == self.codomain().modulus() and self.domain().modulus().leading_coefficient().is_unit()): @@ -2267,7 +2248,6 @@ def is_surjective(self): sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2)) sage: f.is_surjective() False - """ constant_map_is_surjective = self.codomain().base_ring().coerce_map_from(self.domain().base_ring()).is_surjective() if constant_map_is_surjective: @@ -2290,7 +2270,6 @@ def _richcmp_(self, other, op): False sage: f == f True - """ if type(self) is not type(other): return NotImplemented @@ -2353,7 +2332,6 @@ def field_extension(self, names): - homomorphism from field to ``self`` - EXAMPLES:: sage: # needs sage.rings.number_field diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py index f6eb840ff91..c167caeb352 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py @@ -104,7 +104,6 @@ class PolynomialQuotientRingElement(polynomial_singular_interface.Polynomial_sin xi sage: (singular(xi)*singular(xi)).NF('std(0)') # needs sage.libs.singular -1 - """ def __init__(self, parent, polynomial, check=True): """ @@ -112,14 +111,13 @@ def __init__(self, parent, polynomial, check=True): INPUT: + - ``parent`` -- a quotient of a polynomial ring - - ``parent`` -- a quotient of a polynomial ring - - - ``polynomial`` -- a polynomial + - ``polynomial`` -- a polynomial - - ``check`` -- bool (optional): whether or not to - verify that x is a valid element of the polynomial ring and reduced - (mod the modulus). + - ``check`` -- boolean (default: ``True``); whether or not to + verify that x is a valid element of the polynomial ring and reduced + (mod the modulus). """ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic from sage.rings.polynomial.polynomial_element import Polynomial @@ -147,7 +145,7 @@ def __init__(self, parent, polynomial, check=True): Q = P(0) X = P.gen() while R.degree() >= B.degree(): - S = P((R.leading_coefficient()/B.leading_coefficient())) * X**(R.degree()-B.degree()) + S = P(R.leading_coefficient()/B.leading_coefficient()) * X**(R.degree()-B.degree()) Q = Q + S R = R - S*B polynomial = R @@ -399,7 +397,7 @@ def __invert__(self): sage: (2*y)^(-1) -1/2*y - 1 - Raises a ``ZeroDivisionError`` if this element is not a unit:: + Raises a :exc:`ZeroDivisionError` if this element is not a unit:: sage: (y+1)^(-1) Traceback (most recent call last): @@ -457,7 +455,6 @@ def field_extension(self, names): - ``names`` -- name of generator of output field - OUTPUT: - field @@ -466,7 +463,6 @@ def field_extension(self, names): - homomorphism from field to ``self`` - EXAMPLES:: sage: # needs sage.rings.number_field @@ -584,9 +580,7 @@ def charpoly(self, var): INPUT: - - - ``var`` -- string; the variable name - + - ``var`` -- string; the variable name EXAMPLES:: @@ -721,7 +715,7 @@ def minpoly(self): We make sure that the previous example works on random examples:: - sage: # needs sage.rings.finite_rings + sage: # long time, needs sage.rings.finite_rings sage: p = random_prime(50) sage: K. = GF((p, randrange(1,20))) sage: L. = K.extension(randrange(2,20)) diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index a43e34a3fc9..ceaa9d7b2d5 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -108,11 +108,9 @@ cdef class Polynomial_rational_flint(Polynomial): cdef Polynomial_rational_flint _new(self): """ - Quickly creates a new polynomial object in this class. + Quickly create a new polynomial object in this class. - OUTPUT: - - - Polynomial of type Polynomial_rational_flint + OUTPUT: polynomial of type ``Polynomial_rational_flint`` TESTS:: @@ -129,7 +127,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef Polynomial _new_constant_poly(self, x, Parent P): r""" - Quickly creates a new constant polynomial with value x in parent P + Quickly create a new constant polynomial with value x in parent P. ASSUMPTION: @@ -165,7 +163,6 @@ cdef class Polynomial_rational_flint(Polynomial): fmpq_poly_set_si(res._poly, int(x)) return res - def __cinit__(self): """ Initialises the underlying data structure. @@ -179,7 +176,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __dealloc__(self): """ - Deallocates the underlying data structure. + Deallocate the underlying data structure. TESTS:: @@ -195,15 +192,15 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``parent`` -- Polynomial ring, the parent of ``self`` - - ``x`` -- Data for the new polynomial self, e.g. a polynomial, an + - ``parent`` -- polynomial ring, the parent of ``self`` + - ``x`` -- data for the new polynomial ``self``, e.g. a polynomial, an integer, a rational, a list of rationals, a dictionary with keys the degrees and the rational coefficients, etc (default: ``None``) - - `check`` -- Whether the integrity of the data needs to be verified, + - ``check`` -- whether the integrity of the data needs to be verified, largely ignored by this method (default: ``True``) - - ``is_gen`` -- Whether self shall be initialised as the generator of + - ``is_gen`` -- whether ``self`` shall be initialised as the generator of the parent polynomial ring - - ``construct`` -- Whether the element shall always be constructed + - ``construct`` -- whether the element shall always be constructed as an independent copy of any input data (default: ``False``) TESTS:: @@ -397,8 +394,8 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``n`` -- Degree of the monomial whose coefficient is to be - returned. + - ``n`` -- degree of the monomial whose coefficient is to be + returned EXAMPLES:: @@ -415,7 +412,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _unsafe_mutate(self, unsigned long n, value): """ - Sets the `n`-th coefficient of ``self`` to value. + Set the `n`-th coefficient of ``self`` to ``value``. TESTS:: @@ -456,7 +453,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __call__(self, *x, **kwds): """ - Calls this polynomial with the given parameters, which can be + Call this polynomial with the given parameters, which can be interpreted as polynomial composition or evaluation by this method. @@ -562,11 +559,11 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef Polynomial truncate(self, long n): """ - Return self truncated modulo `t^n`. + Return ``self`` truncated modulo `t^n`. INPUT: - - ``n`` -- The power of `t` modulo which ``self`` is truncated + - ``n`` -- the power of `t` modulo which ``self`` is truncated EXAMPLES:: @@ -598,9 +595,9 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``degree`` (``None`` or integral value that fits in an ``unsigned - long``, default: degree of ``self``) - if specified, truncate or zero - pad the list of coefficients to this degree before reversing it. + - ``degree`` -- ``None`` or integral value that fits in an ``unsigned + long`` (default: degree of ``self``); if specified, truncate or zero + pad the list of coefficients to this degree before reversing it EXAMPLES: @@ -642,7 +639,7 @@ cdef class Polynomial_rational_flint(Polynomial): We illustrate two ways in which the interpretation of ``degree`` as an unsigned long int may fail. Firstly, an integral value which is - too large, yielding an ``OverflowError``:: + too large, yielding an :exc:`OverflowError`:: sage: R. = QQ[] sage: f = 1 + t/2 @@ -701,7 +698,7 @@ cdef class Polynomial_rational_flint(Polynomial): sage: f.revert_series(-1) Traceback (most recent call last): - ValueError: argument n must be a non-negative integer, got -1 + ValueError: argument n must be a nonnegative integer, got -1 sage: g = - t^3/3 + t^5/5 sage: g.revert_series(6) @@ -713,7 +710,7 @@ cdef class Polynomial_rational_flint(Polynomial): cdef Polynomial_rational_flint res = self._new() cdef unsigned long m if n < 0: - raise ValueError("argument n must be a non-negative integer, got {}".format(n)) + raise ValueError("argument n must be a nonnegative integer, got {}".format(n)) m = n if not self[0].is_zero() or not self[1].is_unit(): raise ValueError("self must have constant coefficient 0 and a unit for coefficient {}^1".format(self.parent().gen())) @@ -765,7 +762,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __bool__(self): """ - Return whether or not ``self`` is non-zero. + Return whether or not ``self`` is nonzero. EXAMPLES:: @@ -784,7 +781,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __lshift__(self, n): """ - Notationally multiplies self by `t^n`. + Notationally multiply ``self`` by `t^n`. EXAMPLES:: @@ -817,7 +814,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __rshift__(self, n): """ - Notationally returns the quotient of Euclidean division of ``self`` + Notationally return the quotient of Euclidean division of ``self`` by `t^n`. EXAMPLES:: @@ -935,7 +932,7 @@ cdef class Polynomial_rational_flint(Polynomial): Return the quotient and remainder of the Euclidean division of ``self`` and ``right``. - Raises a :class:`ZeroDivisionError` if ``right`` is zero. + Raises a :exc:`ZeroDivisionError` if ``right`` is zero. EXAMPLES:: @@ -1163,23 +1160,21 @@ cdef class Polynomial_rational_flint(Polynomial): if do_sig: sig_off() return res - def __pow__(Polynomial_rational_flint self, exp, ignored): + def __pow__(Polynomial_rational_flint self, exp, mod): """ - Return self raised to the power of exp. + Return ``self`` raised to the power of ``exp``. The corner case of ``exp == 0`` is handled by returning the constant polynomial 1. Note that this includes the case ``0^0 == 1``. - This method only supports integral values for exp that fit into + This method only supports integral values for ``exp`` that fit into a signed long int (except when this is a constant polynomial). INPUT: - - ``exp`` -- Exponent + - ``exp`` -- exponent - OUTPUT: - - Polynomial; this polynomial raised to the power of ``exp`` + OUTPUT: polynomial; this polynomial raised to the power of ``exp`` EXAMPLES:: @@ -1271,10 +1266,23 @@ cdef class Polynomial_rational_flint(Polynomial): ... TypeError: no canonical coercion from Univariate Polynomial Ring in R over Rational Field to Rational Field + + Check that using third argument raises an error:: + + sage: R. = PolynomialRing(QQ) + sage: pow(x, 2, x) + Traceback (most recent call last): + ... + NotImplementedError: pow() with a modulus is not implemented for this ring """ cdef Polynomial_rational_flint res cdef long n + if mod is not None: + raise NotImplementedError( + "pow() with a modulus is not implemented for this ring" + ) + try: n = pyobject_to_long(exp) except TypeError: @@ -1448,7 +1456,7 @@ cdef class Polynomial_rational_flint(Polynomial): """ Return the numerator of ``self``. - Representing self as the quotient of an integer polynomial and + Representing ``self`` as the quotient of an integer polynomial and a positive integer denominator (coprime to the content of the polynomial), returns the integer polynomial. @@ -1493,13 +1501,11 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``var`` -- Must be either (equal to) the generator of the polynomial - ring to which this polynomial belongs, or ``None``; either way the - behaviour is the same. - - OUTPUT: + - ``var`` -- must be either (equal to) the generator of the polynomial + ring to which this polynomial belongs, or ``None``; either way the + behaviour is the same - - Derivative as a ``Polynomial_rational_flint`` + OUTPUT: derivative as a ``Polynomial_rational_flint`` .. SEEALSO:: :meth:`~Polynomial.derivative` @@ -1603,7 +1609,7 @@ cdef class Polynomial_rational_flint(Polynomial): ring. By definition, over any integral domain, an element `r` is irreducible - if and only if it is non-zero, not a unit and whenever `r = ab` then + if and only if it is nonzero, not a unit and whenever `r = ab` then `a` or `b` is a unit. EXAMPLES:: @@ -1632,7 +1638,6 @@ cdef class Polynomial_rational_flint(Polynomial): True sage: f.is_irreducible.cache True - """ cdef Polynomial_integer_dense_flint primitive cdef unsigned long length = fmpq_poly_length(self._poly) @@ -1930,7 +1935,7 @@ cdef class Polynomial_rational_flint(Polynomial): def _cos_series(self, long prec): r""" - Return the cosine of this polynomial up to precision ``prec`` + Return the cosine of this polynomial up to precision ``prec``. EXAMPLES:: @@ -2073,18 +2078,18 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``self`` -- Irreducible polynomial + - ``self`` -- irreducible polynomial - - ``pari_group`` -- bool (default: ``False``); if ``True`` instead - return the Galois group as a PARI group. This has a useful label - in it, and may be slightly faster since it doesn't require looking - up a group in GAP. To get a permutation group from a PARI - group ``P``, type ``PermutationGroup(P)``. + - ``pari_group`` -- boolean (default: ``False``); if ``True`` instead + return the Galois group as a PARI group. This has a useful label + in it, and may be slightly faster since it doesn't require looking + up a group in GAP. To get a permutation group from a PARI + group ``P``, type ``PermutationGroup(P)``. - - ``algorithm`` -- ``'pari'``, ``'gap'``, ``'kash'``, ``'magma'`` (default: - ``'pari'``, for degrees is at most 11; - ``'gap'``, for degrees from 12 to 15; - ``'kash'``, for degrees from 16 or more). + - ``algorithm`` -- ``'pari'``, ``'gap'``, ``'kash'``, ``'magma'`` (default: + ``'pari'``, for degrees is at most 11; + ``'gap'``, for degrees from 12 to 15; + ``'kash'``, for degrees from 16 or more). OUTPUT: Galois group @@ -2251,13 +2256,13 @@ cdef class Polynomial_rational_flint(Polynomial): Return the factorization of ``self`` modulo the prime `p`. Assumes that the degree of this polynomial is at least one, and raises - a :class:`ValueError` otherwise. + a :exc:`ValueError` otherwise. INPUT: - - ``p`` -- Prime number + - ``p`` -- prime number - OUTPUT: Factorization of this polynomial modulo `p` + OUTPUT: factorization of this polynomial modulo `p` EXAMPLES:: @@ -2273,7 +2278,6 @@ cdef class Polynomial_rational_flint(Polynomial): sage: R. = QQ[] sage: (zeta^2 + zeta + 1).factor_mod(7) (zeta + 3) * (zeta + 5) - """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -2296,9 +2300,9 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``p`` -- Prime number + - ``p`` -- prime number - - ``prec`` -- Integer; the precision + - ``prec`` -- integer; the precision OUTPUT: factorization of ``self`` viewed as a `p`-adic polynomial @@ -2349,7 +2353,7 @@ cdef class Polynomial_rational_flint(Polynomial): sage: f.factor_padic(3, -1) Traceback (most recent call last): ... - ValueError: prec_cap must be non-negative + ValueError: prec_cap must be nonnegative sage: f.factor_padic(6, 10) Traceback (most recent call last): ... @@ -2384,8 +2388,8 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``p`` -- Prime number; coerceable to :class:`Integer` - - ``e`` -- Exponent; coerceable to :class:`Integer` + - ``p`` -- prime number; coerceable to :class:`Integer` + - ``e`` -- exponent; coerceable to :class:`Integer` OUTPUT: Hensel lifts; list of polynomials over `\ZZ / p^e \ZZ` @@ -2421,7 +2425,6 @@ cdef class Polynomial_rational_flint(Polynomial): Traceback (most recent call last): ... ValueError: I^2 + 1 is not square-free modulo 2 - """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing @@ -2466,7 +2469,7 @@ cdef class Polynomial_rational_flint(Polynomial): The discriminant of constant polynomials is defined to be 0. - OUTPUT: Discriminant, an element of the base ring of the polynomial ring + OUTPUT: discriminant, an element of the base ring of the polynomial ring .. NOTE:: @@ -2523,7 +2526,6 @@ cdef class Polynomial_rational_flint(Polynomial): sage: R. = QQ[] sage: (I^2 + 1).discriminant() -4 - """ return QQ(self._pari_with_name().poldisc()) @@ -2553,7 +2555,6 @@ cdef class Polynomial_rational_flint(Polynomial): sage: u = x^7 - 2 sage: u.galois_group_davenport_smith_test() 0 - """ from sage.arith.misc import primes_first_n from sage.rings.finite_rings.integer_mod_ring import IntegerModRing diff --git a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx index bd3e95f8420..cfcdcabdcb5 100644 --- a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +++ b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx @@ -55,7 +55,6 @@ cdef class PolynomialRealDense(Polynomial): sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: isinstance(f, PolynomialRealDense) True - """ cdef Py_ssize_t _degree @@ -259,7 +258,7 @@ cdef class PolynomialRealDense(Polynomial): cpdef Polynomial truncate(self, long n): r""" - Returns the polynomial of degree `< n` which is equivalent to self + Return the polynomial of degree `< n` which is equivalent to ``self`` modulo `x^n`. EXAMPLES:: @@ -312,7 +311,7 @@ cdef class PolynomialRealDense(Polynomial): cpdef shift(self, Py_ssize_t n): r""" - Returns this polynomial multiplied by the power `x^n`. If `n` + Return this polynomial multiplied by the power `x^n`. If `n` is negative, terms below `x^n` will be discarded. Does not change this polynomial. @@ -567,8 +566,8 @@ cdef class PolynomialRealDense(Polynomial): INPUT: - - ``degree`` (``None`` or an integer) -- if specified, truncate or zero - pad the list of coefficients to this degree before reversing it. + - ``degree`` -- ``None`` or an integer; if specified, truncate or zero + pad the list of coefficients to this degree before reversing it EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index d0d2d1241ab..2bda9f6f9c3 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -191,6 +191,10 @@ def is_PolynomialRing(x): sage: from sage.rings.polynomial.polynomial_ring import is_PolynomialRing sage: from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing sage: is_PolynomialRing(2) + doctest:warning... + DeprecationWarning: The function is_PolynomialRing is deprecated; + use 'isinstance(..., PolynomialRing_general)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. False This polynomial ring is not univariate. @@ -200,6 +204,10 @@ def is_PolynomialRing(x): sage: is_PolynomialRing(ZZ['x,y,z']) False sage: is_MPolynomialRing(ZZ['x,y,z']) + doctest:warning... + DeprecationWarning: The function is_MPolynomialRing is deprecated; + use 'isinstance(..., MPolynomialRing_base)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. True :: @@ -214,13 +222,17 @@ def is_PolynomialRing(x): :: sage: # needs sage.libs.singular - sage: R. = PolynomialRing(ZZ, implementation="singular"); R + sage: R. = PolynomialRing(ZZ, implementation='singular'); R Multivariate Polynomial Ring in w over Integer Ring sage: is_PolynomialRing(R) False sage: type(R) """ + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_PolynomialRing is deprecated; " + "use 'isinstance(..., PolynomialRing_general)' instead.") return isinstance(x, PolynomialRing_general) @@ -244,15 +256,25 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: category(ZZ['x']) Join of Category of unique factorization domains + and Category of algebras with basis over + (Dedekind domains and euclidean domains + and noetherian rings and infinite enumerated sets + and metric spaces) and Category of commutative algebras over (Dedekind domains and euclidean domains and noetherian rings and infinite enumerated sets and metric spaces) and Category of infinite sets + sage: category(GF(7)['x']) Join of Category of euclidean domains - and Category of commutative algebras over - (finite enumerated fields and subquotients of monoids and quotients of semigroups) and Category of infinite sets + and Category of algebras with basis over + (finite enumerated fields and subquotients of monoids + and quotients of semigroups) + and Category of commutative algebras over + (finite enumerated fields and subquotients of monoids + and quotients of semigroups) + and Category of infinite sets TESTS: @@ -302,6 +324,8 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, self.__cyclopoly_cache = {} self._has_singular = False Ring.__init__(self, base_ring, names=name, normalize=True, category=category) + from sage.rings.semirings.non_negative_integer_semiring import NonNegativeIntegerSemiring + self._indices = NonNegativeIntegerSemiring() self._populate_coercion_lists_(convert_method_name='_polynomial_') def __reduce__(self): @@ -388,7 +412,7 @@ def _element_constructor_(self, x=None, check=True, is_gen=False, sage: S(x) x - Throw a :class:`TypeError` if any of the coefficients cannot be coerced + Throw a :exc:`TypeError` if any of the coefficients cannot be coerced into the base ring (:issue:`6777`):: sage: RealField(300)['x']( [ 1, ComplexField(300).gen(), 0 ]) # needs sage.rings.real_mpfr @@ -490,11 +514,11 @@ def _implementation_names(cls, implementation, base_ring, sparse=False): INPUT: - ``implementation`` -- either a string denoting a specific - implementation or ``None`` for the default. + implementation or ``None`` for the default - - ``base_ring`` -- the base ring for the polynomial ring. + - ``base_ring`` -- the base ring for the polynomial ring - - ``sparse`` -- (boolean) whether the implementation is sparse. + - ``sparse`` -- boolean; whether the implementation is sparse OUTPUT: @@ -506,7 +530,7 @@ def _implementation_names(cls, implementation, base_ring, sparse=False): ``None``. - if the implementation is not supported, raise a - ``ValueError``. + :exc:`ValueError`. EXAMPLES:: @@ -535,7 +559,7 @@ def _implementation_names_impl(implementation, base_ring, sparse): The behaviour is exactly the same, except that an unknown implementation returns ``NotImplemented`` instead of raising - ``ValueError``. + :exc:`ValueError`. EXAMPLES:: @@ -603,7 +627,7 @@ def some_elements(self): @cached_method def flattening_morphism(self): r""" - Return the flattening morphism of this polynomial ring + Return the flattening morphism of this polynomial ring. EXAMPLES:: @@ -616,9 +640,9 @@ def flattening_morphism(self): sage: QQ['x'].flattening_morphism() Identity endomorphism of Univariate Polynomial Ring in x over Rational Field """ - from .multi_polynomial_ring import is_MPolynomialRing + from .multi_polynomial_ring import MPolynomialRing_base base = self.base_ring() - if is_PolynomialRing(base) or is_MPolynomialRing(base): + if isinstance(base, PolynomialRing_general) or isinstance(base, MPolynomialRing_base): from .flatten import FlatteningMorphism return FlatteningMorphism(self) else: @@ -718,9 +742,9 @@ def _coerce_map_from_(self, P): - polynomial rings in the same variable over any base ring that canonically coerces to the base ring of this ring. - - a multivariate polynomial ring P such that self's variable name + - a multivariate polynomial ring P such that ``self``'s variable name is among the variable names of P, and the ring obtained by - removing that variable is different from the base ring of self, + removing that variable is different from the base ring of ``self``, but coerces into it. (see :issue:`813` for a discussion of this) Caveat: There is no coercion from a dense into a sparse @@ -770,9 +794,9 @@ def _coerce_map_from_(self, P): implementation to the default FLINT implementation:: sage: del R, S # clear values from doctests above - sage: R = PolynomialRing(ZZ, 't', implementation="NTL") # needs sage.libs.ntl - sage: S = PolynomialRing(ZZ, 't', implementation="FLINT") # needs sage.libs.flint - sage: T = PolynomialRing(ZZ, 't', implementation="generic") + sage: R = PolynomialRing(ZZ, 't', implementation='NTL') # needs sage.libs.ntl + sage: S = PolynomialRing(ZZ, 't', implementation='FLINT') # needs sage.libs.flint + sage: T = PolynomialRing(ZZ, 't', implementation='generic') sage: R.has_coerce_map_from(S) # needs sage.libs.flint sage.libs.ntl False sage: R.has_coerce_map_from(T) # needs sage.libs.ntl @@ -803,7 +827,7 @@ def _coerce_map_from_(self, P): # polynomial rings in the same variable over a base that canonically # coerces into self.base_ring() - if is_PolynomialRing(P): + if isinstance(P, PolynomialRing_general): if self.construction()[0] != P.construction()[0]: # Construction (including variable names) must be the # same to allow coercion @@ -842,8 +866,8 @@ def _coerce_map_from_(self, P): return PolynomialRingHomomorphism_from_base(RingHomset(P, self), f) # Last, we consider multivariate polynomial rings: - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing - if is_MPolynomialRing(P) and self.variable_name() in P.variable_names(): + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base + if isinstance(P, MPolynomialRing_base) and self.variable_name() in P.variable_names(): P_ = P.remove_var(self.variable_name()) return self.base_ring() != P_ and self.base_ring().has_coerce_map_from(P_) @@ -1116,11 +1140,9 @@ def variable_names_recursive(self, depth=sage.rings.infinity.infinity): INPUT: - - ``depth`` -- an integer or :mod:`Infinity `. - - OUTPUT: + - ``depth`` -- integer or :mod:`Infinity ` - A tuple of strings. + OUTPUT: a tuple of strings EXAMPLES:: @@ -1143,9 +1165,8 @@ def variable_names_recursive(self, depth=sage.rings.infinity.infinity): def _mpoly_base_ring(self, variables=None): r""" - Returns the base ring if this is viewed as a polynomial ring over - ``variables``. See also - Polynomial._mpoly_dict_recursive + Return the base ring if this is viewed as a polynomial ring over + ``variables``. See also ``Polynomial._mpoly_dict_recursive``. """ if variables is None: variables = self.variable_names_recursive() @@ -1180,7 +1201,7 @@ def characteristic(self): def cyclotomic_polynomial(self, n): """ - Return the nth cyclotomic polynomial as a polynomial in this + Return the `n`-th cyclotomic polynomial as a polynomial in this polynomial ring. For details of the implementation, see the documentation for :func:`sage.rings.polynomial.cyclotomic.cyclotomic_coeffs`. @@ -1371,14 +1392,14 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): INPUT: - - ``degree`` -- (default: ``(-1, 2)``) integer for fixing the degree or - a tuple of minimum and maximum degrees + - ``degree`` -- (default: ``(-1, 2)``) integer for fixing the degree or + a tuple of minimum and maximum degrees - - ``monic`` -- boolean (optional); indicate whether the sampled - polynomial should be monic + - ``monic`` -- boolean (default: ``False``); indicate whether the sampled + polynomial should be monic - - ``*args, **kwds`` -- additional keyword parameters passed on to the - ``random_element`` method for the base ring + - ``*args, **kwds`` -- additional keyword parameters passed on to the + ``random_element`` method for the base ring EXAMPLES:: @@ -1596,7 +1617,7 @@ def _Karatsuba_threshold(self): 0 """ base_ring = self.base_ring() - if is_PolynomialRing(base_ring): + if isinstance(base_ring, PolynomialRing_general): return 0 try: from sage.matrix.matrix_space import MatrixSpace @@ -1654,12 +1675,11 @@ def polynomials( self, of_degree=None, max_degree=None ): INPUT: Pass exactly one of: - - ``max_degree`` -- an int; the iterator will generate - all polynomials which have degree less than or equal to - ``max_degree`` + - ``max_degree`` -- an int; the iterator will generate all polynomials + which have degree less than or equal to ``max_degree`` - - ``of_degree`` -- an int; the iterator will generate - all polynomials which have degree ``of_degree`` + - ``of_degree`` -- an int; the iterator will generate + all polynomials which have degree ``of_degree`` OUTPUT: an iterator @@ -1720,13 +1740,11 @@ def monics( self, of_degree=None, max_degree=None ): INPUT: Pass exactly one of: - - ``max_degree`` -- an int; the iterator will generate - all monic polynomials which have degree less than or equal to - ``max_degree`` - - - ``of_degree`` -- an int; the iterator will generate - all monic polynomials which have degree ``of_degree`` + - ``max_degree`` -- an int; the iterator will generate all monic + polynomials which have degree less than or equal to ``max_degree`` + - ``of_degree`` -- an int; the iterator will generate + all monic polynomials which have degree ``of_degree`` OUTPUT: an iterator @@ -1802,8 +1820,8 @@ def quotient_by_principal_ideal(self, f, names=None, **kwds): INPUT: - ``f`` -- either a polynomial in ``self``, or a principal - ideal of ``self``. - - further named arguments that are passed to the quotient constructor. + ideal of ``self`` + - further named arguments that are passed to the quotient constructor EXAMPLES:: @@ -1861,10 +1879,13 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=True, algori INPUT: - ``p`` -- the polynomial whose roots are computed - - ``ring`` -- the ring to find roots (default is the base ring of ``p``) - - ``multiplicities`` -- bool (default: ``True``): if ``True``, return a list of pairs ``(root, multiplicity)``; if ``False`` return a list of roots + - ``ring`` -- the ring to find roots (default: the base ring of ``p``) + - ``multiplicities`` -- boolean (default: ``True``); if ``True``, + return a list of pairs ``(root, multiplicity)``; if ``False`` return + a list of roots - ``algorithm`` -- ignored (TODO: remove) - - ``degree_bound`` -- if not ``None``, return only roots of degree at most ``degree_bound`` + - ``degree_bound`` -- if not ``None``, return only roots of degree at + most ``degree_bound`` EXAMPLES:: @@ -1904,7 +1925,7 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=True, algori class PolynomialRing_integral_domain(PolynomialRing_commutative, PolynomialRing_singular_repr, IntegralDomain): - def __init__(self, base_ring, name="x", sparse=False, implementation=None, + def __init__(self, base_ring, name='x', sparse=False, implementation=None, element_class=None, category=None): """ TESTS:: @@ -1965,16 +1986,16 @@ def weil_polynomials(self, d, q, sign=1, lead=1): INPUT: - - ``d`` -- integer, the degree of the polynomials + - ``d`` -- integer; the degree of the polynomials - - ``q`` -- integer, the square of the complex absolute value of the + - ``q`` -- integer; the square of the complex absolute value of the roots - - ``sign`` -- integer (default `1`), the sign `s` of the functional + - ``sign`` -- integer (default: `1`); the sign `s` of the functional equation - - ``lead`` -- integer, list of integers or list of pairs of integers - (default `1`), constraints on the leading few coefficients of the + - ``lead`` -- integer; list of integers or list of pairs of integers + (default: `1`), constraints on the leading few coefficients of the generated polynomials. If pairs `(a, b)` of integers are given, they are treated as a constraint of the form `\equiv a \pmod{b}`; the moduli must be in decreasing order by divisibility, and the modulus @@ -2135,7 +2156,7 @@ def construction(self): class PolynomialRing_field(PolynomialRing_integral_domain, PrincipalIdealDomain): - def __init__(self, base_ring, name="x", sparse=False, implementation=None, + def __init__(self, base_ring, name='x', sparse=False, implementation=None, element_class=None, category=None): """ TESTS:: @@ -2202,7 +2223,7 @@ def _element_class(): def _ideal_class_(self, n=0): """ - Returns the class representing ideals in univariate polynomial rings + Return the class representing ideals in univariate polynomial rings over fields. EXAMPLES:: @@ -2221,12 +2242,12 @@ def divided_difference(self, points, full_table=False): INPUT: - - ``points`` -- a list of pairs `(x_0, y_0), (x_1, y_1), + - ``points`` -- list of pairs `(x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)` of elements of the base ring of ``self``, where `x_i - x_j` is invertible for `i \neq j`. This method converts the `x_i` and `y_i` into the base ring of ``self``. - - ``full_table`` -- boolean (default: ``False``): If ``True``, + - ``full_table`` -- boolean (default: ``False``); if ``True``, return the full divided-difference table. If ``False``, only return entries along the main diagonal; these are the Newton divided-difference coefficients `F_{i,i}`. @@ -2303,19 +2324,19 @@ def divided_difference(self, points, full_table=False): else: return [F[i][i] for i in range(n)] - def lagrange_polynomial(self, points, algorithm="divided_difference", previous_row=None): + def lagrange_polynomial(self, points, algorithm='divided_difference', previous_row=None): r""" Return the Lagrange interpolation polynomial through the given points. INPUT: - - ``points`` -- a list of pairs `(x_0, y_0), (x_1, y_1), + - ``points`` -- list of pairs `(x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)` of elements of the base ring of ``self``, where `x_i - x_j` is invertible for `i \neq j`. This method converts the `x_i` and `y_i` into the base ring of ``self``. - - ``algorithm`` -- (default: ``'divided_difference'``): one of + - ``algorithm`` -- (default: ``'divided_difference'``) one of the following: - ``'divided_difference'``: use the method of divided @@ -2331,7 +2352,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r table, instead of the full table itself. Generating the full table can be memory inefficient. - - ``previous_row`` -- (default: ``None``): This option is only + - ``previous_row`` -- (default: ``None``) this option is only relevant if used with ``algorithm='neville'``. If provided, this should be the last row of the table resulting from a previous use of Neville's method. If such a row is passed, @@ -2379,7 +2400,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r sage: R = PolynomialRing(QQ, 'x') sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)], - ....: algorithm="neville") + ....: algorithm='neville') [9, -11/7*x + 19/7, -17/42*x^2 - 83/42*x + 53/7, @@ -2389,24 +2410,24 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r sage: R = PolynomialRing(GF(2**3, 'a'), 'x') sage: a = R.base_ring().gen() sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)], - ....: algorithm="neville") + ....: algorithm='neville') [a^2 + a + 1, x + a + 1, a^2*x^2 + a^2*x + a^2] Repeated use of Neville's method to get better Lagrange interpolation polynomials:: sage: R = PolynomialRing(QQ, 'x') - sage: p = R.lagrange_polynomial([(0,1), (2,2)], algorithm="neville") + sage: p = R.lagrange_polynomial([(0,1), (2,2)], algorithm='neville') sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)], - ....: algorithm="neville", previous_row=p)[-1] + ....: algorithm='neville', previous_row=p)[-1] -23/84*x^3 - 11/84*x^2 + 13/7*x + 1 sage: # needs sage.rings.finite_rings sage: R = PolynomialRing(GF(2**3, 'a'), 'x') sage: a = R.base_ring().gen() - sage: p = R.lagrange_polynomial([(a^2+a, a), (a, 1)], algorithm="neville") + sage: p = R.lagrange_polynomial([(a^2+a, a), (a, 1)], algorithm='neville') sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)], - ....: algorithm="neville", previous_row=p)[-1] + ....: algorithm='neville', previous_row=p)[-1] a^2*x^2 + a^2*x + a^2 TESTS: @@ -2414,16 +2435,16 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r The value for ``algorithm`` must be either ``'divided_difference'`` (default), or ``'neville'``:: - sage: R = PolynomialRing(QQ, "x") - sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm="abc") + sage: R = PolynomialRing(QQ, 'x') + sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm='abc') Traceback (most recent call last): ... ValueError: algorithm must be one of 'divided_difference' or 'neville' - sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm="divided difference") + sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm='divided difference') Traceback (most recent call last): ... ValueError: algorithm must be one of 'divided_difference' or 'neville' - sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm="") + sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm='') Traceback (most recent call last): ... ValueError: algorithm must be one of 'divided_difference' or 'neville' @@ -2433,7 +2454,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r ``divided_difference``, or a list of elements of ``self`` in the case of ``neville``:: - sage: R = PolynomialRing(QQ, "x") + sage: R = PolynomialRing(QQ, 'x') sage: R.lagrange_polynomial([]).parent() == R True sage: R.lagrange_polynomial([(2, 3)]).parent() == R @@ -2581,7 +2602,7 @@ class PolynomialRing_dense_finite_field(PolynomialRing_field): sage: type(R) # needs sage.rings.finite_rings """ - def __init__(self, base_ring, name="x", element_class=None, implementation=None): + def __init__(self, base_ring, name='x', element_class=None, implementation=None): """ TESTS:: @@ -2651,20 +2672,17 @@ def irreducible_element(self, n, algorithm=None): INPUT: - - ``n`` -- integer: degree of the polynomial to construct + - ``n`` -- integer; degree of the polynomial to construct - - ``algorithm`` -- string: algorithm to use, or ``None`` + - ``algorithm`` -- string (algorithm to use) or ``None``: - ``'random'`` or ``None``: - try random polynomials until an irreducible - one is found. + try random polynomials until an irreducible one is found - ``'first_lexicographic'``: try polynomials in - lexicographic order until an irreducible one is found. + lexicographic order until an irreducible one is found - OUTPUT: - - A monic irreducible polynomial of degree `n` in ``self``. + OUTPUT: a monic irreducible polynomial of degree `n` in ``self`` EXAMPLES:: @@ -2675,10 +2693,10 @@ def irreducible_element(self, n, algorithm=None): sage: f.is_irreducible() True sage: R = GF(19)['x'] - sage: R.irreducible_element(21, algorithm="first_lexicographic") + sage: R.irreducible_element(21, algorithm='first_lexicographic') x^21 + x + 5 sage: R = GF(5**2, 'a')['x'] - sage: R.irreducible_element(17, algorithm="first_lexicographic") + sage: R.irreducible_element(17, algorithm='first_lexicographic') x^17 + a*x + 4*a + 3 AUTHORS: @@ -2724,9 +2742,7 @@ def _roth_ruckenstein(self, p, degree_bound, precision): - ``precision`` -- if given, roots are computed modulo `x^d` where `d` is ``precision`` (see below) - OUTPUT: - - The list of roots of ``p`` of degree at most ``degree_bound``: + OUTPUT: the list of roots of ``p`` of degree at most ``degree_bound``: - If `precision = None` actual roots are computed, i.e. all `f \in F[x]` such that `p(f) = 0`. @@ -2819,9 +2835,7 @@ def _alekhnovich(self, p, degree_bound, precision=None, dc_threshold=None): - ``dc_threshold`` -- if given, the algorithm calls :meth:`_roth_ruckenetein` to compute roots of degree at most ``dc_threshold`` - OUTPUT: - - The list of roots of ``p`` of degree at most ``degree_bound``: + OUTPUT: the list of roots of ``p`` of degree at most ``degree_bound``: - If `precision = None` actual roots are computed, i.e. all `f \in F[x]` such that `p(f) = 0`. @@ -2873,7 +2887,7 @@ def _alekhnovich(self, p, degree_bound, precision=None, dc_threshold=None): """ def alekh_rec(p, k, degree_bound, lvl): r""" - Recursive core method for Alekhnovich algorithm." + Recursive core method for Alekhnovich algorithm. INPUT: @@ -2943,11 +2957,11 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=False, algor INPUT: - ``p`` -- the polynomial whose roots are computed - - ``ring`` -- the ring to find roots (default is the base ring of ``p``) - - ``multiplicities`` -- bool (default: ``True``): currently, roots are only - computed without their multiplicities. - - ``algorithm`` -- the algorithm to use: either ``"Alekhnovich"`` (default) - or ``"Roth-Ruckenstein"`` + - ``ring`` -- the ring to find roots (default: the base ring of ``p``) + - ``multiplicities`` -- boolean (default: ``True``); currently, roots are only + computed without their multiplicities + - ``algorithm`` -- the algorithm to use: either ``'Alekhnovich'`` (default) + or ``'Roth-Ruckenstein'`` - ``degree_bound`` -- if not ``None``, return only roots of degree at most ``degree_bound`` @@ -2961,7 +2975,7 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=False, algor [x^2 + 11*x + 1, x + 1] sage: p.roots(multiplicities=False, degree_bound=1) [x + 1] - sage: p.roots(multiplicities=False, algorithm="Roth-Ruckenstein") + sage: p.roots(multiplicities=False, algorithm='Roth-Ruckenstein') [x^2 + 11*x + 1, x + 1] TESTS: @@ -3066,7 +3080,7 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, class PolynomialRing_dense_padic_ring_generic(PolynomialRing_cdvr): r""" - A class for dense polynomial ring over p-adic rings + A class for dense polynomial ring over `p`-adic rings """ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None): PolynomialRing_cdvr.__init__(self, base_ring, sparse=False, name=name, @@ -3095,7 +3109,7 @@ def _implementation_names_impl(implementation, base_ring, sparse): class PolynomialRing_dense_padic_field_generic(PolynomialRing_cdvf): r""" - A class for dense polynomial ring over p-adic fields + A class for dense polynomial ring over `p`-adic fields """ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None): PolynomialRing_cdvf.__init__(self, base_ring, sparse=False, name=name, @@ -3384,7 +3398,7 @@ def residue_field(self, ideal, names=None): class PolynomialRing_dense_mod_p(PolynomialRing_dense_finite_field, PolynomialRing_dense_mod_n, PolynomialRing_singular_repr): - def __init__(self, base_ring, name="x", implementation=None, element_class=None, category=None): + def __init__(self, base_ring, name='x', implementation=None, element_class=None, category=None): """ TESTS:: @@ -3464,13 +3478,13 @@ def _implementation_names_impl(implementation, base_ring, sparse): TESTS:: sage: # needs sage.libs.ntl - sage: PolynomialRing(GF(2), 'x', implementation="GF2X") + sage: PolynomialRing(GF(2), 'x', implementation='GF2X') Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: PolynomialRing(GF(2), 'x', implementation="NTL") + sage: PolynomialRing(GF(2), 'x', implementation='NTL') Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) sage: PolynomialRing(GF(2), 'x', implementation=None) Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: PolynomialRing(GF(3), 'x', implementation="GF2X") + sage: PolynomialRing(GF(3), 'x', implementation='GF2X') Traceback (most recent call last): ... ValueError: GF2X only supports modulus 2 @@ -3507,17 +3521,17 @@ def irreducible_element(self, n, algorithm=None): INPUT: - - ``n`` -- integer: the degree of the polynomial to construct + - ``n`` -- integer; the degree of the polynomial to construct - - ``algorithm`` -- string: algorithm to use, or ``None``. - Currently available options are: + - ``algorithm`` -- string (algorithm to use) or ``None``; + currently available options are: - ``'adleman-lenstra'``: a variant of the Adleman--Lenstra algorithm as implemented in PARI. - ``'conway'``: look up the Conway polynomial of degree `n` over the field of `p` elements in the database; raise a - ``RuntimeError`` if it is not found. + :exc:`RuntimeError` if it is not found. - ``'ffprimroot'``: use the :pari:`ffprimroot` function from PARI. @@ -3543,42 +3557,40 @@ def irreducible_element(self, n, algorithm=None): is used if `p = 2`, and the algorithm ``'adleman-lenstra'`` if `p > 2`. - OUTPUT: - - A monic irreducible polynomial of degree `n` in ``self``. + OUTPUT: a monic irreducible polynomial of degree `n` in ``self`` EXAMPLES:: sage: # needs sage.rings.finite_rings sage: GF(5)['x'].irreducible_element(2) x^2 + 4*x + 2 - sage: GF(5)['x'].irreducible_element(2, algorithm="adleman-lenstra") + sage: GF(5)['x'].irreducible_element(2, algorithm='adleman-lenstra') x^2 + x + 1 - sage: GF(5)['x'].irreducible_element(2, algorithm="primitive") + sage: GF(5)['x'].irreducible_element(2, algorithm='primitive') x^2 + 4*x + 2 - sage: GF(5)['x'].irreducible_element(32, algorithm="first_lexicographic") + sage: GF(5)['x'].irreducible_element(32, algorithm='first_lexicographic') x^32 + 2 - sage: GF(5)['x'].irreducible_element(32, algorithm="conway") + sage: GF(5)['x'].irreducible_element(32, algorithm='conway') Traceback (most recent call last): ... RuntimeError: requested Conway polynomial not in database. - sage: GF(5)['x'].irreducible_element(32, algorithm="primitive") + sage: GF(5)['x'].irreducible_element(32, algorithm='primitive') x^32 + ... In characteristic 2:: sage: GF(2)['x'].irreducible_element(33) # needs sage.rings.finite_rings x^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1 - sage: GF(2)['x'].irreducible_element(33, algorithm="minimal_weight") # needs sage.rings.finite_rings + sage: GF(2)['x'].irreducible_element(33, algorithm='minimal_weight') # needs sage.rings.finite_rings x^33 + x^10 + 1 In degree 1:: sage: GF(97)['x'].irreducible_element(1) # needs sage.rings.finite_rings x + 96 - sage: GF(97)['x'].irreducible_element(1, algorithm="conway") # needs sage.rings.finite_rings + sage: GF(97)['x'].irreducible_element(1, algorithm='conway') # needs sage.rings.finite_rings x + 92 - sage: GF(97)['x'].irreducible_element(1, algorithm="adleman-lenstra") # needs sage.rings.finite_rings + sage: GF(97)['x'].irreducible_element(1, algorithm='adleman-lenstra') # needs sage.rings.finite_rings x AUTHORS: @@ -3679,15 +3691,15 @@ def fraction_field(self): return super().fraction_field() -def polygen(ring_or_element, name="x"): +def polygen(ring_or_element, name='x'): """ Return a polynomial indeterminate. INPUT: - - ``polygen(base_ring, name="x")`` + - ``polygen(base_ring, name='x')`` - - ``polygen(ring_element, name="x")`` + - ``polygen(ring_element, name='x')`` If the first input is a ring, return a polynomial generator over that ring. If it is a ring element, return a polynomial generator @@ -3701,7 +3713,7 @@ def polygen(ring_or_element, name="x"): sage: parent(z) Univariate Polynomial Ring in z over Rational Field - .. note:: + .. NOTE:: If you give a list or comma-separated string to :func:`polygen`, you'll get a tuple of indeterminates, exactly as if you called @@ -3721,7 +3733,7 @@ def polygen(ring_or_element, name="x"): return t.gen() -def polygens(base_ring, names="x", *args): +def polygens(base_ring, names='x', *args): """ Return indeterminates over the given base ring with the given names. diff --git a/src/sage/rings/polynomial/polynomial_ring_constructor.py b/src/sage/rings/polynomial/polynomial_ring_constructor.py index e417e8a6779..5cbc74dd1d5 100644 --- a/src/sage/rings/polynomial/polynomial_ring_constructor.py +++ b/src/sage/rings/polynomial/polynomial_ring_constructor.py @@ -76,15 +76,15 @@ def PolynomialRing(base_ring, *args, **kwds): - ``base_ring`` -- a ring - - ``n`` -- an integer + - ``n`` -- integer - - ``name`` -- a string + - ``name`` -- string - - ``names`` -- a list or tuple of names (strings), or a comma separated string + - ``names`` -- list or tuple of names (strings), or a comma separated string - - ``var_array`` -- a list or tuple of names, or a comma separated string + - ``var_array`` -- list or tuple of names, or a comma separated string - - ``sparse`` -- bool: whether or not elements are sparse. The + - ``sparse`` -- boolean; whether or not elements are sparse. The default is a dense representation (``sparse=False``) for univariate rings and a sparse representation (``sparse=True``) for multivariate rings. @@ -92,15 +92,15 @@ def PolynomialRing(base_ring, *args, **kwds): - ``order`` -- string or :class:`~sage.rings.polynomial.term_order.TermOrder` object, e.g., - - ``'degrevlex'`` (default) -- degree reverse lexicographic - - ``'lex'`` -- lexicographic + - ``'degrevlex'`` -- default; degree reverse lexicographic + - ``'lex'`` -- lexicographic - ``'deglex'`` -- degree lexicographic - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering - ``implementation`` -- string or None; selects an implementation in cases where Sage includes multiple choices (currently `\ZZ[x]` can be implemented with ``'NTL'`` or ``'FLINT'``; default is ``'FLINT'``). - For many base rings, the ``"singular"`` implementation is available. + For many base rings, the ``'singular'`` implementation is available. One can always specify ``implementation="generic"`` for a generic Sage implementation which does not use any specialized library. @@ -269,9 +269,9 @@ def PolynomialRing(base_ring, *args, **kwds): The Singular implementation always returns a multivariate ring, even for 1 variable:: - sage: PolynomialRing(QQ, "x", implementation="singular") # needs sage.libs.singular + sage: PolynomialRing(QQ, "x", implementation='singular') # needs sage.libs.singular Multivariate Polynomial Ring in x over Rational Field - sage: P. = PolynomialRing(QQ, implementation="singular"); P # needs sage.libs.singular + sage: P. = PolynomialRing(QQ, implementation='singular'); P # needs sage.libs.singular Multivariate Polynomial Ring in x over Rational Field **3. PolynomialRing(base_ring, n, names, ...)** (where the arguments @@ -407,43 +407,43 @@ def PolynomialRing(base_ring, *args, **kwds): NotImplementedError: a dense representation of multivariate polynomials is not supported Check uniqueness if the same implementation is used for different - values of the ``"implementation"`` keyword:: + values of the ``'implementation'`` keyword:: - sage: R = PolynomialRing(QQbar, 'j', implementation="generic") # needs sage.rings.number_field + sage: R = PolynomialRing(QQbar, 'j', implementation='generic') # needs sage.rings.number_field sage: S = PolynomialRing(QQbar, 'j', implementation=None) # needs sage.rings.number_field sage: R is S # needs sage.rings.number_field True - sage: R = PolynomialRing(ZZ['t'], 'j', implementation="generic") + sage: R = PolynomialRing(ZZ['t'], 'j', implementation='generic') sage: S = PolynomialRing(ZZ['t'], 'j', implementation=None) sage: R is S True sage: # needs sage.rings.number_field - sage: R = PolynomialRing(QQbar, 'j,k', implementation="generic") + sage: R = PolynomialRing(QQbar, 'j,k', implementation='generic') sage: S = PolynomialRing(QQbar, 'j,k', implementation=None) sage: R is S True sage: # needs sage.libs.singular - sage: R = PolynomialRing(ZZ, 'j,k', implementation="singular") + sage: R = PolynomialRing(ZZ, 'j,k', implementation='singular') sage: S = PolynomialRing(ZZ, 'j,k', implementation=None) sage: R is S True - sage: R = PolynomialRing(ZZ, 'p', sparse=True, implementation="generic") + sage: R = PolynomialRing(ZZ, 'p', sparse=True, implementation='generic') sage: S = PolynomialRing(ZZ, 'p', sparse=True) sage: R is S True The generic implementation is different in some cases:: - sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) + sage: R = PolynomialRing(GF(2), 'j', implementation='generic'); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) - sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) + sage: R = PolynomialRing(ZZ, 'x,y', implementation='generic'); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) sage: S = PolynomialRing(ZZ, 'x,y'); TestSuite(S).run(skip='_test_elements'); type(S) # needs sage.libs.singular @@ -471,19 +471,19 @@ def PolynomialRing(base_ring, *args, **kwds): Traceback (most recent call last): ... ValueError: unknown implementation 'FLINT' for multivariate polynomial rings - sage: R. = PolynomialRing(QQbar, implementation="whatever") # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, implementation='whatever') # needs sage.rings.number_field Traceback (most recent call last): ... ValueError: unknown implementation 'whatever' for dense polynomial rings over Algebraic Field - sage: R. = PolynomialRing(ZZ['t'], implementation="whatever") + sage: R. = PolynomialRing(ZZ['t'], implementation='whatever') Traceback (most recent call last): ... ValueError: unknown implementation 'whatever' for dense polynomial rings over Univariate Polynomial Ring in t over Integer Ring - sage: PolynomialRing(RR, "x,y", implementation="whatever") + sage: PolynomialRing(RR, "x,y", implementation='whatever') Traceback (most recent call last): ... ValueError: unknown implementation 'whatever' for multivariate polynomial rings - sage: PolynomialRing(RR, name="x", implementation="singular") # needs sage.libs.singular + sage: PolynomialRing(RR, name='x', implementation='singular') # needs sage.libs.singular Traceback (most recent call last): ... NotImplementedError: polynomials over Real Field with 53 bits of precision are not supported in Singular @@ -537,32 +537,32 @@ def PolynomialRing(base_ring, *args, **kwds): sage: PolynomialRing(4) Traceback (most recent call last): ... - TypeError: base_ring 4 must be a ring + TypeError: base_ring 4 must be a ring or the tropical semiring sage: PolynomialRing(QQ, -1) Traceback (most recent call last): ... - ValueError: number of variables must be non-negative + ValueError: number of variables must be nonnegative sage: PolynomialRing(QQ, 1) Traceback (most recent call last): ... TypeError: you must specify the names of the variables - sage: PolynomialRing(QQ, "x", None) + sage: PolynomialRing(QQ, 'x', None) Traceback (most recent call last): ... TypeError: invalid arguments ('x', None) for PolynomialRing - sage: PolynomialRing(QQ, "x", "y") + sage: PolynomialRing(QQ, 'x', 'y') Traceback (most recent call last): ... TypeError: variable names specified twice: 'x' and 'y' - sage: PolynomialRing(QQ, 1, "x", 2) + sage: PolynomialRing(QQ, 1, 'x', 2) Traceback (most recent call last): ... TypeError: number of variables specified twice: 1 and 2 - sage: PolynomialRing(QQ, "x", names="x") + sage: PolynomialRing(QQ, 'x', names='x') Traceback (most recent call last): ... TypeError: variable names specified twice inconsistently: ('x',) and 'x' - sage: PolynomialRing(QQ, name="x", names="x") + sage: PolynomialRing(QQ, name='x', names='x') Traceback (most recent call last): ... TypeError: keyword argument 'name' cannot be combined with 'names' @@ -593,18 +593,18 @@ def PolynomialRing(base_ring, *args, **kwds): Multivariate Polynomial Ring in x, y, z over Rational Field sage: Q0 = PolynomialRing(QQ,[]); TestSuite(Q0).run(skip=['_test_elements', '_test_elements_eq_transitive', '_test_gcd_vs_xgcd', '_test_quo_rem']); Q0 Multivariate Polynomial Ring in no variables over Rational Field - sage: P. = PolynomialRing(QQ, implementation="singular"); TestSuite(P).run(skip=['_test_construction', '_test_elements', # needs sage.libs.singular + sage: P. = PolynomialRing(QQ, implementation='singular'); TestSuite(P).run(skip=['_test_construction', '_test_elements', # needs sage.libs.singular ....: '_test_euclidean_degree', '_test_quo_rem']); P Multivariate Polynomial Ring in x over Rational Field sage: Q1 = PolynomialRing(QQ,"x",1); TestSuite(Q1).run(skip=['_test_construction', '_test_elements', '_test_euclidean_degree', '_test_quo_rem']); Q1 Multivariate Polynomial Ring in x over Rational Field sage: Q0 = PolynomialRing(QQ,"x",0); TestSuite(Q0).run(skip=['_test_elements', '_test_elements_eq_transitive', '_test_gcd_vs_xgcd', '_test_quo_rem']); Q0 Multivariate Polynomial Ring in no variables over Rational Field - sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) + sage: R = PolynomialRing(GF(2), 'j', implementation='generic'); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) - sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) + sage: R = PolynomialRing(ZZ, 'x,y', implementation='generic'); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) sage: S = PolynomialRing(ZZ, 'x,y'); TestSuite(S).run(skip='_test_elements'); type(S) # needs sage.libs.singular @@ -622,8 +622,9 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R. = PolynomialRing(RIF,2) sage: TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']) """ - if base_ring not in Rings(): - raise TypeError("base_ring {!r} must be a ring".format(base_ring)) + from sage.rings.semirings.tropical_semiring import TropicalSemiring + if base_ring not in Rings() and not isinstance(base_ring, TropicalSemiring): + raise TypeError("base_ring {!r} must be a ring or the tropical semiring".format(base_ring)) n = -1 # Unknown number of variables names = None # Unknown variable names @@ -665,7 +666,7 @@ def PolynomialRing(base_ring, *args, **kwds): for arg in args: k = Integer(arg) if k < 0: - raise ValueError("number of variables must be non-negative") + raise ValueError("number of variables must be nonnegative") suffixes = [s + str(i) for s in suffixes for i in range(k)] names = [v + s for s in suffixes for v in names] else: # No "var_array" keyword @@ -689,7 +690,7 @@ def PolynomialRing(base_ring, *args, **kwds): if n >= 0: raise TypeError("number of variables specified twice: %r and %r" % (n, arg)) if k < 0: - raise ValueError("number of variables must be non-negative") + raise ValueError("number of variables must be nonnegative") n = k # If number of variables was explicitly given, always # return a multivariate ring @@ -792,7 +793,11 @@ def _single_variate(base_ring, name, sparse=None, implementation=None, order=Non # Generic implementations if constructor is None: - if base_ring not in _CommutativeRings: + from sage.rings.semirings.tropical_semiring import TropicalSemiring + if isinstance(base_ring, TropicalSemiring): + from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring + constructor = TropicalPolynomialSemiring + elif base_ring not in _CommutativeRings: constructor = polynomial_ring.PolynomialRing_general elif base_ring in _CompleteDiscreteValuationRings: constructor = polynomial_ring.PolynomialRing_cdvr @@ -804,6 +809,7 @@ def _single_variate(base_ring, name, sparse=None, implementation=None, order=Non constructor = polynomial_ring.PolynomialRing_integral_domain else: constructor = polynomial_ring.PolynomialRing_commutative + implementation_names = constructor._implementation_names(implementation, base_ring, sparse) # Only use names which are not supported by the specialized class. @@ -822,7 +828,7 @@ def _single_variate(base_ring, name, sparse=None, implementation=None, order=Non return R -def _multi_variate(base_ring, names, sparse=None, order="degrevlex", implementation=None): +def _multi_variate(base_ring, names, sparse=None, order='degrevlex', implementation=None): if sparse is None: sparse = True if not sparse: @@ -861,7 +867,11 @@ def _multi_variate(base_ring, names, sparse=None, order="degrevlex", implementat if R is None and implementation == "generic": from . import multi_polynomial_ring - if base_ring in _Domains: + from sage.rings.semirings.tropical_semiring import TropicalSemiring + if isinstance(base_ring, TropicalSemiring): + from sage.rings.semirings.tropical_mpolynomial import TropicalMPolynomialSemiring + constructor = TropicalMPolynomialSemiring + elif base_ring in _Domains: constructor = multi_polynomial_ring.MPolynomialRing_polydict_domain else: constructor = multi_polynomial_ring.MPolynomialRing_polydict @@ -899,30 +909,37 @@ def polynomial_default_category(base_ring_category, n_variables): INPUT: - - ``base_ring_category`` -- The category of ring over which the polynomial + - ``base_ring_category`` -- the category of ring over which the polynomial ring shall be defined - ``n_variables`` -- number of variables EXAMPLES:: sage: from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category - sage: polynomial_default_category(Rings(),1) is Algebras(Rings()).Infinite() - True - sage: polynomial_default_category(Rings().Commutative(),1) is Algebras(Rings().Commutative()).Commutative().Infinite() - True - sage: polynomial_default_category(Fields(),1) is EuclideanDomains() & Algebras(Fields()).Infinite() - True - sage: polynomial_default_category(Fields(),2) is UniqueFactorizationDomains() & CommutativeAlgebras(Fields()).Infinite() - True - - sage: QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).Infinite() + sage: polynomial_default_category(Rings(), 1) + Category of infinite algebras with basis over rings + sage: polynomial_default_category(Rings().Commutative(), 1) + Category of infinite commutative algebras with basis + over commutative rings + sage: polynomial_default_category(Fields(), 1) + Join of Category of euclidean domains + and Category of algebras with basis over fields + and Category of commutative algebras over fields + and Category of infinite sets + sage: polynomial_default_category(Fields(), 2) + Join of Category of unique factorization domains + and Category of algebras with basis over fields + and Category of commutative algebras over fields + and Category of infinite sets + + sage: QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite() True - sage: QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).Infinite() + sage: QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite() True - sage: QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).Infinite() + sage: QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).WithBasis().Infinite() True """ - category = Algebras(base_ring_category) + category = Algebras(base_ring_category).WithBasis() if n_variables: # here we assume the base ring to be nonzero @@ -947,7 +964,7 @@ def polynomial_default_category(base_ring_category, n_variables): return category -def BooleanPolynomialRing_constructor(n=None, names=None, order="lex"): +def BooleanPolynomialRing_constructor(n=None, names=None, order='lex'): """ Construct a boolean polynomial ring with the following parameters: diff --git a/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx b/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx index c2f0e900c2a..087e520dc23 100644 --- a/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx +++ b/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx @@ -33,7 +33,6 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): Natural morphism: From: Integer Ring To: Rational Field - """ cpdef Element _call_(self, x): """ @@ -55,12 +54,11 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) sage: G(A.gen()^1000000) 1.0...*x^1000000 - """ P = self.codomain() f = self.underlying_map() if P.is_sparse(): - return P({a: f(b) for a, b in x.dict().iteritems()}) + return P({a: f(b) for a, b in x.monomial_coefficients().items()}) else: return P([f(b) for b in x]) @@ -86,12 +84,12 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) sage: G(A.gen()^1000000, True, construct=False) x^1000000 - """ P = self.codomain() f = self.underlying_map() if P.is_sparse(): - return P({a: f(b) for a, b in x.dict().iteritems()}, *args, **kwds) + return P({a: f(b) for a, b in x.monomial_coefficients().items()}, + *args, **kwds) else: return P([f(b) for b in x], *args, **kwds) @@ -105,7 +103,6 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: S. = QQ[] sage: R.hom(S).is_injective() True - """ return self.underlying_map().is_injective() @@ -119,6 +116,5 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: S. = Zmod(2)[] sage: R.hom(S).is_surjective() True - """ return self.underlying_map().is_surjective() diff --git a/src/sage/rings/polynomial/polynomial_singular_interface.py b/src/sage/rings/polynomial/polynomial_singular_interface.py index ee7c243087f..1bdca3af614 100644 --- a/src/sage/rings/polynomial/polynomial_singular_interface.py +++ b/src/sage/rings/polynomial/polynomial_singular_interface.py @@ -172,7 +172,7 @@ def _do_singular_init_(singular, base_ring, char, _vars, order): class PolynomialRing_singular_repr: """ - Implements methods to convert polynomial rings to Singular. + Implement methods to convert polynomial rings to Singular. This class is a base class for all univariate and multivariate polynomial rings which support conversion from and to Singular @@ -221,7 +221,7 @@ def _singular_(self, singular=None): // : names x // block 2 : ordering C - sage: R = PolynomialRing(GF(127), 'x', implementation="singular") # needs sage.libs.singular + sage: R = PolynomialRing(GF(127), 'x', implementation='singular') # needs sage.libs.singular sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: ZZ/127 @@ -230,7 +230,7 @@ def _singular_(self, singular=None): // : names x // block 2 : ordering C - sage: R = PolynomialRing(QQ, 'x', implementation="singular") # needs sage.libs.singular + sage: R = PolynomialRing(QQ, 'x', implementation='singular') # needs sage.libs.singular sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ @@ -451,7 +451,7 @@ def can_convert_to_singular(R): class Polynomial_singular_repr: """ - Implements coercion of polynomials to Singular polynomials. + Implement coercion of polynomials to Singular polynomials. This class is a base class for all (univariate and multivariate) polynomial classes which support conversion from and to @@ -477,7 +477,7 @@ def _singular_func(self, singular=None): INPUT: - - ``singular`` -- Singular instance to use. + - ``singular`` -- Singular instance to use EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_template.pxi b/src/sage/rings/polynomial/polynomial_template.pxi index 31f2903f318..b76d62a9e92 100644 --- a/src/sage/rings/polynomial/polynomial_template.pxi +++ b/src/sage/rings/polynomial/polynomial_template.pxi @@ -24,9 +24,11 @@ from sage.libs.pari.all import pari_gen import operator + def make_element(parent, args): return parent(*args) + cdef inline Polynomial_template element_shift(self, int n): if not isinstance(self, Polynomial_template): if n > 0: @@ -75,7 +77,7 @@ cdef class Polynomial_template(Polynomial): We illustrate the generic glueing using univariate polynomials over `\mathop{\mathrm{GF}}(2)`. - .. note:: + .. NOTE:: Implementations using this template MUST implement coercion from base ring elements and :meth:`get_unsafe`. See @@ -340,7 +342,7 @@ cdef class Polynomial_template(Polynomial): @coerce_binop def gcd(self, Polynomial_template other): """ - Return the greatest common divisor of self and other. + Return the greatest common divisor of ``self`` and ``other``. EXAMPLES:: @@ -369,7 +371,7 @@ cdef class Polynomial_template(Polynomial): sage: f.gcd(g) Traceback (most recent call last): ... - ValueError: non-invertible elements encountered during GCD + RuntimeError: FLINT gcd calculation failed """ if celement_is_zero(&self.x, (self)._cparent): return other @@ -392,7 +394,7 @@ cdef class Polynomial_template(Polynomial): @coerce_binop def xgcd(self, Polynomial_template other): """ - Computes extended gcd of self and other. + Compute extended gcd of ``self`` and ``other``. EXAMPLES:: @@ -586,7 +588,6 @@ cdef class Polynomial_template(Polynomial): return -2 return result - def __pow__(self, ee, modulus): """ EXAMPLES:: @@ -780,7 +781,7 @@ cdef class Polynomial_template(Polynomial): cpdef Polynomial truncate(self, long n): r""" - Returns this polynomial mod `x^n`. + Return this polynomial mod `x^n`. EXAMPLES:: @@ -816,7 +817,7 @@ cdef class Polynomial_template(Polynomial): def _singular_(self, singular=None): r""" - Return Singular representation of this polynomial + Return Singular representation of this polynomial. INPUT: diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 8c68cabe038..5b3539d6b70 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -140,7 +140,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): cpdef Polynomial _new_constant_poly(self, x, Parent P): r""" - Quickly creates a new constant polynomial with value x in parent P. + Quickly create a new constant polynomial with value x in parent P. ASSUMPTION: @@ -160,7 +160,6 @@ cdef class Polynomial_zmod_flint(Polynomial_template): Traceback (most recent call last): ... ValueError: invalid literal for int() with base 10: '4.1' - """ cdef type t = type(self) cdef Polynomial_template r = t.__new__(t) @@ -176,9 +175,8 @@ cdef class Polynomial_zmod_flint(Polynomial_template): INPUT: - - ``x`` -- a list of coefficients; the coefficients are assumed to be - reduced already and the list contains no trailing zeroes. - + - ``x`` -- list of coefficients; the coefficients are assumed to be + reduced already and the list contains no trailing zeroes EXAMPLES:: @@ -238,7 +236,6 @@ cdef class Polynomial_zmod_flint(Polynomial_template): (99998, 1) sage: p[d], p[v] (2, 1) - """ sig_on() fmpz_poly_get_nmod_poly(&self.x, x) @@ -275,11 +272,11 @@ cdef class Polynomial_zmod_flint(Polynomial_template): INPUT: **either** - - a -- ring element; need not be in the coefficient ring of the - polynomial. - - a dictionary for kwds:value pairs. If the variable name of the - polynomial is a keyword it is substituted in; otherwise this - polynomial is returned unchanged. + - ``a`` -- ring element; need not be in the coefficient ring of the + polynomial + - a dictionary for kwds:value pairs; if the variable name of the + polynomial is a keyword it is substituted in, otherwise this + polynomial is returned unchanged EXAMPLES:: @@ -422,7 +419,6 @@ cdef class Polynomial_zmod_flint(Polynomial_template): multiplication and then truncating. The function is tuned for length `n` about half the length of a full product. - EXAMPLES:: sage: P. = GF(7)[] @@ -724,7 +720,6 @@ cdef class Polynomial_zmod_flint(Polynomial_template): True sage: s.is_irreducible.cache True - """ if not self: return False @@ -767,7 +762,19 @@ cdef class Polynomial_zmod_flint(Polynomial_template): sage: P. = GF(7)[] sage: (6*x+3).squarefree_decomposition() (6) * (x + 4) + + Test zero polynomial:: + + sage: R. = PolynomialRing(GF(65537), implementation="FLINT") + sage: R.zero().squarefree_decomposition() + Traceback (most recent call last): + ... + ArithmeticError: square-free decomposition of 0 is not defined """ + if self.is_zero(): + raise ArithmeticError( + "square-free decomposition of 0 is not defined" + ) if not self.base_ring().is_field(): raise NotImplementedError("square free factorization of polynomials over rings with composite characteristic is not implemented") @@ -809,9 +816,19 @@ cdef class Polynomial_zmod_flint(Polynomial_template): ... AlarmInterrupt + Test zero polynomial:: + + sage: R. = PolynomialRing(GF(65537), implementation="FLINT") + sage: R.zero().factor() + Traceback (most recent call last): + ... + ArithmeticError: factorization of 0 is not defined + """ - R = self.base_ring() + if self.is_zero(): + raise ArithmeticError("factorization of 0 is not defined") + R = self.base_ring() if not R.is_field(): p,e = R.characteristic().is_prime_power(get_data=True) if not e: @@ -830,7 +847,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): """ Return this polynomial divided by its leading coefficient. - Raises :class:`ValueError` if the leading coefficient is not invertible in the + Raises :exc:`ValueError` if the leading coefficient is not invertible in the base ring. EXAMPLES:: @@ -910,7 +927,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): sage: p.reverse(degree=1.5r) Traceback (most recent call last): ... - ValueError: degree argument must be a non-negative integer, got 1.5 + ValueError: degree argument must be a nonnegative integer, got 1.5 Check that this implementation is compatible with the generic one:: @@ -923,10 +940,10 @@ cdef class Polynomial_zmod_flint(Polynomial_template): cdef unsigned long d if degree is not None: if degree < 0: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) d = degree if d != degree: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) nmod_poly_reverse(&res.x, &self.x, d+1) # FLINT expects length else: nmod_poly_reverse(&res.x, &self.x, nmod_poly_length(&self.x)) @@ -946,7 +963,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): sage: f.revert_series(-1) Traceback (most recent call last): ... - ValueError: argument n must be a non-negative integer, got -1 + ValueError: argument n must be a nonnegative integer, got -1 sage: g = - t^3 + t^5 sage: g.revert_series(6) @@ -963,7 +980,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): cdef Polynomial_zmod_flint res = self._new() cdef unsigned long m if n < 0: - raise ValueError("argument n must be a non-negative integer, got {}".format(n)) + raise ValueError("argument n must be a nonnegative integer, got {}".format(n)) m = n if not self[0].is_zero() or not self[1].is_unit(): raise ValueError("self must have constant coefficient 0 and a unit for coefficient {}^1".format(self.parent().gen())) @@ -995,3 +1012,48 @@ cdef class Polynomial_zmod_flint(Polynomial_template): from sage.rings.polynomial.polynomial_ring_constructor import _single_variate R = _single_variate(parent.base_ring(), name=name, implementation='NTL') return parent(R(self % other).minpoly_mod(R(other))) + + def compose_mod(self, other, modulus): + r""" + Compute `f(g) \bmod h`. + + To be precise about the order fo compostion, given ``self``, ``other`` + and ``modulus`` as `f(x)`, `g(x)` and `h(x)` compute `f(g(x)) \bmod h(x)`. + + INPUT: + + - ``other`` -- a polynomial `g(x)` + - ``modulus`` -- a polynomial `h(x)` + + EXAMPLES:: + + sage: R. = GF(163)[] + sage: f = R.random_element() + sage: g = R.random_element() + sage: g.compose_mod(g, f) == g(g) % f + True + + sage: f = R([i for i in range(100)]) + sage: g = R([i**2 for i in range(100)]) + sage: h = 1 + x + x**5 + sage: f.compose_mod(g, h) + 82*x^4 + 56*x^3 + 45*x^2 + 60*x + 127 + sage: f.compose_mod(g, h) == f(g) % h + True + + AUTHORS: + + - Giacomo Pope (2024-08) initial implementation + """ + cdef Polynomial_zmod_flint res = self._new() + + sig_on() + nmod_poly_compose_mod(&res.x, &(self).x, &(other).x, &(modulus).x) + sig_off() + + return res + + # compose_mod is the natural name from the Flint bindings, but + # polynomial_gf2x has modular_composition as the method name so here we + # allow both + modular_composition = compose_mod diff --git a/src/sage/rings/polynomial/polynomial_zz_pex.pyx b/src/sage/rings/polynomial/polynomial_zz_pex.pyx index f38f80ee49b..ec33846f2d9 100644 --- a/src/sage/rings/polynomial/polynomial_zz_pex.pyx +++ b/src/sage/rings/polynomial/polynomial_zz_pex.pyx @@ -256,7 +256,6 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): ....: P = PolynomialRing(F, 'x') ....: f = P.random_element(8) ....: assert f(b) == sum(c * b^i for i, c in enumerate(f)) - """ cdef ntl_ZZ_pE _a cdef ZZ_pE_c c_b @@ -318,17 +317,17 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): K = self._parent.base_ring() return K(K.polynomial_ring()(ZZ_pE_c_to_list(r))) - def is_irreducible(self, algorithm="fast_when_false", iter=1): + def is_irreducible(self, algorithm='fast_when_false', iter=1): r""" Return ``True`` precisely when ``self`` is irreducible over its base ring. INPUT: - - ``algorithm`` -- a string (default ``"fast_when_false"``), + - ``algorithm`` -- string (default: ``'fast_when_false'``); there are 3 available algorithms: - ``"fast_when_true"``, ``"fast_when_false"``, and ``"probabilistic".`` + ``'fast_when_true'``, ``'fast_when_false'``, and ``'probabilistic'`` - - ``iter`` -- (default: 1) if the algorithm is ``"probabilistic"``, + - ``iter`` -- (default: 1) if the algorithm is ``'probabilistic'``, defines the number of iterations. The error probability is bounded by `q^{\text{-iter}}` for polynomials in `\GF{q}[x]`. @@ -337,18 +336,18 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): sage: K. = GF(next_prime(2**60)**3) sage: R. = PolynomialRing(K, implementation='NTL') sage: P = x^3 + (2-a)*x + 1 - sage: P.is_irreducible(algorithm="fast_when_false") + sage: P.is_irreducible(algorithm='fast_when_false') True - sage: P.is_irreducible(algorithm="fast_when_true") + sage: P.is_irreducible(algorithm='fast_when_true') True - sage: P.is_irreducible(algorithm="probabilistic") + sage: P.is_irreducible(algorithm='probabilistic') True sage: Q = (x^2+a)*(x+a^3) - sage: Q.is_irreducible(algorithm="fast_when_false") + sage: Q.is_irreducible(algorithm='fast_when_false') False - sage: Q.is_irreducible(algorithm="fast_when_true") + sage: Q.is_irreducible(algorithm='fast_when_true') False - sage: Q.is_irreducible(algorithm="probabilistic") + sage: Q.is_irreducible(algorithm='probabilistic') False """ self._parent._modulus.restore() @@ -519,7 +518,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): sage: f.reverse(degree=-5) Traceback (most recent call last): ... - ValueError: degree argument must be a non-negative integer, got -5 + ValueError: degree argument must be a nonnegative integer, got -5 Check that this implementation is compatible with the generic one:: @@ -541,10 +540,10 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): cdef unsigned long d if degree is not None: if degree < 0: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) d = degree if d != degree: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree)) ZZ_pEX_reverse_hi(r.x, ( self).x, d) else: ZZ_pEX_reverse(r.x, ( self).x) @@ -596,7 +595,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): """ self._parent._modulus.restore() - # Ensure precision is non-negative + # Ensure precision is nonnegative if prec <= 0: raise ValueError("the precision must be positive, got {}".format(prec)) @@ -712,3 +711,67 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): ZZ_pEX_PowerMod_ZZ_pre(r.x, y, e_ZZ, mod) sig_off() return r + + def compose_mod(self, other, modulus): + r""" + Compute `f(g) \bmod h`. + + To be precise about the order fo compostion, given ``self``, ``other`` + and ``modulus`` as `f(x)`, `g(x)` and `h(x)` compute `f(g(x)) \bmod h(x)`. + + INPUT: + + - ``other`` -- a polynomial `g(x)` + - ``modulus`` -- a polynomial `h(x)` + + EXAMPLES:: + + sage: R. = GF(3**6)[] + sage: f = R.random_element() + sage: g = R.random_element() + sage: g.compose_mod(g, f) == g(g) % f + True + + sage: F. = GF(3**6) + sage: R. = F[] + sage: f = 2*z3^2*x^2 + (z3 + 1)*x + z3^2 + 2 + sage: g = (z3^2 + 2*z3)*x^2 + (2*z3 + 2)*x + 2*z3^2 + z3 + 2 + sage: h = (2*z3 + 2)*x^2 + (2*z3^2 + 1)*x + 2*z3^2 + z3 + 2 + sage: f.compose_mod(g, h) + (z3^5 + z3^4 + z3^3 + z3^2 + z3)*x + z3^5 + z3^3 + 2*z3 + 2 + sage: f.compose_mod(g, h) == f(g) % h + True + + AUTHORS: + + - Giacomo Pope (2024-08) initial implementation + """ + self._parent._modulus.restore() + + # Ensure all the parents match + if other.parent() is not self._parent: + other = self._parent.coerce(other) + if modulus.parent() is not self._parent: + modulus = self._parent.coerce(modulus) + + # Create the output polynomial + cdef Polynomial_ZZ_pEX r + r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX) + celement_construct(&r.x, (self)._cparent) + r._parent = (self)._parent + r._cparent = (self)._cparent + + # Create ZZ_pEX_Modulus type from modulus input + cdef ZZ_pEX_Modulus_c mod + ZZ_pEX_Modulus_build(mod, (modulus).x) + + # Compute f(g) mod h + sig_on() + ZZ_pEX_CompMod(r.x, (self).x, ((other % modulus)).x, mod) + sig_off() + + return r + + # compose_mod is the natural name from the NTL bindings, but polynomial_gf2x + # has modular_composition as the method name so here we allow both + modular_composition = compose_mod diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index 99587194f5f..a91a95a1d55 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -322,15 +322,15 @@ cdef class interval_bernstein_polynomial: cdef void update_variations(self, interval_bernstein_polynomial bp1, interval_bernstein_polynomial bp2) noexcept: """ - Update the max_variations of bp1 and bp2 (which are assumed to be - the result of splitting this polynomial). + Update the max_variations of ``bp1`` and ``bp2`` (which are assumed to + be the result of splitting this polynomial). - If we knew the number of variations of self, bp1, and bp2 exactly, - we would have - self.variations == bp1.variations + bp2.variations + 2*n + If we knew the number of variations of ``self``, ``bp1``, and ``bp2`` + exactly, we would have + ``self.variations == bp1.variations + bp2.variations + 2*n`` for some nonnegative integer n. Thus, we can use our information - on min and max variations on self and bp1 (or bp2) to refine the range - on bp2 (or bp1). + on min and max variations on ``self`` and ``bp1`` (or ``bp2``) to + refine the range on ``bp2`` (or ``bp1``). """ if self.max_variations - bp1.min_variations < bp2.max_variations: bp2.max_variations = self.max_variations - bp1.min_variations @@ -697,7 +697,8 @@ cdef class interval_bernstein_polynomial_integer(interval_bernstein_polynomial): OUTPUT: - ``bp1``, ``bp2`` -- the new interval Bernstein polynomials - - ``ok`` -- a boolean; True if the sign of the original polynomial at mid is known + - ``ok`` -- boolean; ``True`` if the sign of the original polynomial at + mid is known EXAMPLES:: @@ -1488,7 +1489,6 @@ cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): with intervals, not exactly, we cannot necessarily compute the exact number of sign variations; instead, we compute lower and upper bounds on this number. - """ cdef numpy.ndarray[double, ndim=1] cd = self.coeffs._vector_numpy @@ -1572,7 +1572,8 @@ cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): OUTPUT: - ``bp1``, ``bp2`` -- the new interval Bernstein polynomials - - ``ok`` -- a boolean; ``True`` if the sign of the original polynomial at ``mid`` is known + - ``ok`` -- boolean; ``True`` if the sign of the original polynomial at + ``mid`` is known EXAMPLES:: @@ -1970,7 +1971,7 @@ def bitsize_doctest(n): def degree_reduction_next_size(n): """ - Given n (a polynomial degree), returns either a smaller integer or None. + Given n (a polynomial degree), returns either a smaller integer or ``None``. This defines the sequence of degrees followed by our degree reduction implementation. @@ -2575,7 +2576,7 @@ class bernstein_polynomial_factory_intlist(bernstein_polynomial_factory): def __init__(self, coeffs): """ - Initializes a bernstein_polynomial_factory_intlist, + Initialize a ``bernstein_polynomial_factory_intlist``, given a list of integer coefficients. EXAMPLES:: @@ -2601,7 +2602,7 @@ class bernstein_polynomial_factory_intlist(bernstein_polynomial_factory): def coeffs_bitsize(self): """ - Computes the approximate log2 of the maximum of the absolute + Compute the approximate log2 of the maximum of the absolute values of the coefficients. EXAMPLES:: @@ -2654,7 +2655,7 @@ class bernstein_polynomial_factory_ratlist(bernstein_polynomial_factory): def __init__(self, coeffs): """ - Initializes a bernstein_polynomial_factory_intlist, + Initialize a ``bernstein_polynomial_factory_intlist``, given a list of rational coefficients. EXAMPLES:: @@ -2680,7 +2681,7 @@ class bernstein_polynomial_factory_ratlist(bernstein_polynomial_factory): def coeffs_bitsize(self): """ - Computes the approximate log2 of the maximum of the absolute + Compute the approximate log2 of the maximum of the absolute values of the coefficients. EXAMPLES:: @@ -2740,7 +2741,7 @@ class bernstein_polynomial_factory_ar(bernstein_polynomial_factory): def __init__(self, poly, neg): """ - Initializes a bernstein_polynomial_factory_ar, + Initialize a ``bernstein_polynomial_factory_ar``, given a polynomial with algebraic real coefficients. If neg is True, then gives the Bernstein polynomial for the negative half-line; if neg is False, the positive. @@ -2785,7 +2786,7 @@ class bernstein_polynomial_factory_ar(bernstein_polynomial_factory): def coeffs_bitsize(self): """ - Computes the approximate log2 of the maximum of the absolute + Compute the approximate log2 of the maximum of the absolute values of the coefficients. EXAMPLES:: @@ -3567,7 +3568,7 @@ cdef class island: def less_bits(self, ancestors, interval_bernstein_polynomial bp): """ - Heuristically pushes lower-precision polynomials on + Heuristically push lower-precision polynomials on the polynomial stack. See the class documentation for class island for more information. """ @@ -4558,7 +4559,7 @@ def max_bitsize_intvec_doctest(b): def dprod_imatrow_vec(Matrix_integer_dense m, Vector_integer_dense v, int k): """ - Computes the dot product of row k of the matrix m with the vector v + Compute the dot product of row k of the matrix m with the vector v (that is, compute one element of the product m*v). If v has more elements than m has columns, then elements of v are diff --git a/src/sage/rings/polynomial/refine_root.pyx b/src/sage/rings/polynomial/refine_root.pyx index 32a9ce8c8e4..1d6eb6bb146 100644 --- a/src/sage/rings/polynomial/refine_root.pyx +++ b/src/sage/rings/polynomial/refine_root.pyx @@ -75,7 +75,7 @@ def refine_root(ip, ipd, irt, fld): # unless either the real or imaginary component of the root is zero. # If the real or imaginary component is zero, then we could spend # a long time computing closer and closer approximations to that - # component. (This doesn't happen for non-zero components, because + # component. (This doesn't happen for nonzero components, because # of the imprecision of floating-point numbers combined with the # outward interval rounding; but close to zero, MPFI provides # extremely precise numbers.) diff --git a/src/sage/rings/polynomial/skew_polynomial_element.pyx b/src/sage/rings/polynomial/skew_polynomial_element.pyx index cf5fd9bd090..70bc7f5b448 100644 --- a/src/sage/rings/polynomial/skew_polynomial_element.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_element.pyx @@ -134,7 +134,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): INPUT: - - ``exp`` -- an integer + - ``exp`` -- integer - ``modulus`` -- a skew polynomial in the same ring as ``self`` @@ -276,9 +276,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): - ``eval_pt`` -- element of the base ring of ``self`` - OUTPUT: - - The operator evaluation of ``self`` at ``eval_pt``. + OUTPUT: the operator evaluation of ``self`` at ``eval_pt`` .. TODO:: @@ -339,9 +337,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): - ``eval_pt`` -- element of the base ring of ``self`` - OUTPUT: - - The value of the polynomial at the point specified by the argument. + OUTPUT: the value of the polynomial at the point specified by the argument EXAMPLES:: @@ -388,7 +384,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): INPUT: - - `n` -- an integer, the power of conjugation + - ``n`` -- integer; the power of conjugation EXAMPLES:: @@ -434,9 +430,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): - ``eval_pts`` -- list of points at which ``self`` is to be evaluated - OUTPUT: - - List of values of ``self`` at the ``eval_pts``. + OUTPUT: list of values of ``self`` at the ``eval_pts`` .. TODO:: diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx index b9538d07263..0c8c660c18c 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx @@ -100,7 +100,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): N = self._parent._working_center(self.reduced_norm(var=False)) return N.is_irreducible() - def type(self, N): r""" Return the `N`-type of this skew polynomial (see definition below). @@ -209,7 +208,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): self._types[N] = type return type - # Finding divisors # ---------------- @@ -288,7 +286,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): continue return D - def _reduced_norm_factor_uniform(self): r""" Return a factor of the reduced norm of this skew @@ -357,7 +354,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): if random < count[i]: return F[i][0] - def _irreducible_divisors(self, bint right): r""" Return an iterator over all irreducible monic @@ -369,7 +365,7 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): INPUT: - - ``right`` -- a boolean; if ``True``, return right divisors, + - ``right`` -- boolean; if ``True``, return right divisors, otherwise, return left divisors TESTS:: @@ -469,14 +465,13 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): d, _ = quo_rem2(P, d) yield d - def right_irreducible_divisor(self, uniform=False): r""" Return a right irreducible divisor of this skew polynomial. INPUT: - - ``uniform`` -- a boolean (default: ``False``); whether the + - ``uniform`` -- boolean (default: ``False``); whether the output irreducible divisor should be uniformly distributed among all possibilities @@ -551,7 +546,7 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): INPUT: - - ``uniform`` -- a boolean (default: ``False``); whether the + - ``uniform`` -- boolean (default: ``False``); whether the output irreducible divisor should be uniformly distributed among all possibilities @@ -617,7 +612,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): if LD.degree() == degN: return LD - def right_irreducible_divisors(self): r""" Return an iterator over all irreducible monic right divisors @@ -686,7 +680,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): """ return self._irreducible_divisors(False) - def count_irreducible_divisors(self): r""" Return the number of irreducible monic divisors of @@ -744,7 +737,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): count += (cardL**m - 1) // (cardL - 1) return count - # Finding factorizations # ---------------------- @@ -926,14 +918,13 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): factors.reverse() return Factorization(factors, sort=False, unit=unit) - def factor(self, uniform=False): r""" Return a factorization of this skew polynomial. INPUT: - - ``uniform`` -- a boolean (default: ``False``); whether the + - ``uniform`` -- boolean (default: ``False``); whether the output irreducible divisor should be uniformly distributed among all possibilities @@ -994,7 +985,6 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): F = self._factorization return F - def count_factorizations(self): r""" Return the number of factorizations (as a product of a diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx index fcda4420378..f90484cba62 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx @@ -157,8 +157,8 @@ cdef class SkewPolynomial_finite_order_dense(SkewPolynomial_generic_dense): INPUT: - - ``var`` -- a string or ``False`` or ``None`` (default: ``None``); - the variable name; if ``False``, return the list of coefficients + - ``var`` -- string or ``False`` or ``None`` (default: ``None``); + the variable name. If ``False``, return the list of coefficients. EXAMPLES:: @@ -228,8 +228,8 @@ cdef class SkewPolynomial_finite_order_dense(SkewPolynomial_generic_dense): INPUT: - - ``var`` -- a string or ``False`` or ``None`` (default: ``None``); - the variable name; if ``False``, return the list of coefficients + - ``var`` -- string or ``False`` or ``None`` (default: ``None``); + the variable name. If ``False``, return the list of coefficients. .. NOTE:: @@ -341,7 +341,7 @@ cdef class SkewPolynomial_finite_order_dense(SkewPolynomial_generic_dense): INPUT: - - ``var`` -- a string, a pair of strings or ``None`` + - ``var`` -- string, a pair of strings or ``None`` (default: ``None``); the variable names used for the characteristic polynomial and the center @@ -449,7 +449,7 @@ cdef class SkewPolynomial_finite_order_dense(SkewPolynomial_generic_dense): ALGORITHM: - #. Sage first checks whether ``self`` is itself in the + #. Sage first checks whether self is itself in the center. It if is, it returns ``self`` #. If an optimal bound was previously computed and @@ -518,7 +518,6 @@ cdef class SkewPolynomial_finite_order_dense(SkewPolynomial_generic_dense): return center(self._optbound) return self.reduced_norm() - def optimal_bound(self): r""" Return the optimal bound of this skew polynomial (i.e. diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index db5285ff66f..6feadce07b1 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -106,11 +106,9 @@ def _minimal_vanishing_polynomial(R, eval_pts): - ``R`` -- a skew polynomial ring over a field - - ``eval_pts`` -- a list of evaluation points - - OUTPUT: + - ``eval_pts`` -- list of evaluation points - The minimal vanishing polynomial. + OUTPUT: the minimal vanishing polynomial EXAMPLES:: @@ -164,9 +162,7 @@ def _lagrange_polynomial(R, eval_pts, values): - ``values`` -- list of values that the Lagrange polynomial takes at the respective ``eval_pts`` - OUTPUT: - - - the Lagrange polynomial + OUTPUT: the Lagrange polynomial EXAMPLES:: @@ -269,9 +265,7 @@ def minimal_vanishing_polynomial(self, eval_pts): independent over the fixed field of the twisting morphism of the associated skew polynomial ring - OUTPUT: - - The minimal vanishing polynomial. + OUTPUT: the minimal vanishing polynomial EXAMPLES:: @@ -319,13 +313,11 @@ def lagrange_polynomial(self, points): INPUT: - - ``points`` -- a list of pairs `(x_1, y_1), \ldots, (x_n, y_n)` of + - ``points`` -- list of pairs `(x_1, y_1), \ldots, (x_n, y_n)` of elements of the base ring of ``self``; the `x_i` should be linearly independent over the fixed field of ``self.twisting_morphism()`` - OUTPUT: - - The Lagrange polynomial. + OUTPUT: the Lagrange polynomial EXAMPLES:: @@ -366,7 +358,7 @@ def lagrange_polynomial(self, points): raise TypeError("the evaluation points must be distinct") zero_i = [i for i in range(l) if eval_pts[i].is_zero()] if zero_i and not values[zero_i[0]].is_zero(): - raise TypeError("a skew polynomial always evaluates to 0 at 0, but a non-zero value was requested") + raise TypeError("a skew polynomial always evaluates to 0 at 0, but a nonzero value was requested") return _lagrange_polynomial(_base_ring_to_fraction_field(self), eval_pts, values) @@ -640,10 +632,10 @@ def center(self, name=None, names=None, default=False): INPUT: - - ``name`` -- a string or ``None`` (default: ``None``); + - ``name`` -- string or ``None`` (default: ``None``); the name for the central variable (namely `x^r`) - - ``default`` -- a boolean (default: ``False``); if ``True``, + - ``default`` -- boolean (default: ``False``); if ``True``, set the default variable name for the center to ``name`` EXAMPLES:: @@ -877,7 +869,7 @@ def _retraction(self, x, newmap=False, seed=None): INPUT: - - ``newmap`` -- a boolean (default: ``False``); whether we + - ``newmap`` -- boolean (default: ``False``); whether we first create and use a new retraction map - ``seed`` -- an element of the base ring or ``None`` (default: diff --git a/src/sage/rings/polynomial/symmetric_ideal.py b/src/sage/rings/polynomial/symmetric_ideal.py index 660e9f9fe4b..869af07d904 100644 --- a/src/sage/rings/polynomial/symmetric_ideal.py +++ b/src/sage/rings/polynomial/symmetric_ideal.py @@ -67,7 +67,8 @@ class SymmetricIdeal(Ideal_generic): r""" - Ideal in an Infinite Polynomial Ring, invariant under permutation of variable indices + Ideal in an Infinite Polynomial Ring, invariant under permutation of + variable indices. THEORY: @@ -176,7 +177,6 @@ class SymmetricIdeal(Ideal_generic): Infinite polynomial ring in x, y over Rational Field sage: I * I == X * (x[1]^2) # needs sage.combinat False - """ def __init__(self, ring, gens, coerce=True): @@ -185,7 +185,8 @@ def __init__(self, ring, gens, coerce=True): - ``ring`` -- an infinite polynomial ring - ``gens`` -- generators of this ideal - - ``coerce`` -- (bool, default ``True``) coerce the given generators into ``ring`` + - ``coerce`` -- boolean (default ``True``); coerce the given generators + into ``ring`` EXAMPLES:: @@ -197,7 +198,6 @@ def __init__(self, ring, gens, coerce=True): sage: J = SymmetricIdeal(X, [x[1]^2 + y[2]^2, x[1]*x[2]*y[3] + x[1]*y[4]]) sage: I == J True - """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) @@ -209,7 +209,6 @@ def __repr__(self): sage: I = X * (x[1]^2 + y[2]^2, x[1]*x[2]*y[3] + x[1]*y[4]) sage: I # indirect doctest Symmetric Ideal (x_1^2 + y_2^2, x_2*x_1*y_3 + x_1*y_4) of Infinite polynomial ring in x, y over Rational Field - """ return f"Symmetric Ideal {self._repr_short()} of {self.ring()}" @@ -222,7 +221,6 @@ def _latex_(self): sage: I = X * (x[1]*y[2]) sage: latex(I) # indirect doctest \left(x_{1} y_{2}\right)\Bold{Q}[x_{\ast}, y_{\ast}][\mathfrak{S}_{\infty}] - """ from sage.misc.latex import latex return r'\left({}\right){}[\mathfrak{{S}}_{{\infty}}]'.format(", ".join(latex(g) for g in self.gens()), latex(self.ring())) @@ -305,7 +303,6 @@ def __pow__(self, n): sage: I = X * (x[1]) sage: I^2 # indirect doctest # needs sage.combinat Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x over Rational Field - """ OUT = SymmetricIdeal(self.ring(), [1]) for i in range(n): @@ -324,7 +321,7 @@ def is_maximal(self): It is not checked whether ``self`` is in fact a symmetric Groebner basis. A wrong answer can result if this assumption does not - hold. A :class:`NotImplementedError` is raised if the base ring is not + hold. A :exc:`NotImplementedError` is raised if the base ring is not a field, since symmetric Groebner bases are not implemented in this setting. @@ -347,7 +344,6 @@ def is_maximal(self): Infinite polynomial ring in x, y over Rational Field sage: I.is_maximal() # needs sage.combinat True - """ if not self.base_ring().is_field(): raise NotImplementedError @@ -366,13 +362,11 @@ def reduce(self, I, tailreduce=False): INPUT: - ``I`` -- an Infinite Polynomial, or a Symmetric Ideal or a - list of Infinite Polynomials. - - ``tailreduce`` -- (bool, default ``False``) If ``True``, the - non-leading terms will be reduced as well. - - OUTPUT: + list of Infinite Polynomials + - ``tailreduce`` -- boolean (default ``False``); if ``True``, the + non-leading terms will be reduced as well - Symmetric reduction of ``self`` with respect to ``I``. + OUTPUT: symmetric reduction of ``self`` with respect to ``I`` THEORY: @@ -415,7 +409,6 @@ def reduce(self, I, tailreduce=False): sage: I.reduce(J, tailreduce=True) # needs sage.combinat Symmetric Ideal (x_3^2*y_1) of Infinite polynomial ring in x, y over Rational Field - """ if I in self.ring(): # we want to reduce a polynomial by self return self.ring()(I).reduce(self) @@ -435,11 +428,11 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None INPUT: - - ``tailreduce`` -- (bool, default ``True``) If ``True``, the + - ``tailreduce`` -- boolean (default: ``True``); if ``True``, the interreduction is also performed on the non-leading monomials. - - ``sorted`` -- (bool, default ``False``) If ``True``, it is assumed that the + - ``sorted`` -- boolean (default: ``False``); if ``True``, it is assumed that the generators of ``self`` are already increasingly sorted. - - ``report`` -- (object, default ``None``) If not ``None``, some information on the + - ``report`` -- object (default ``None``); if not ``None``, some information on the progress of computation is printed - ``RStrat`` -- (:class:`~sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy`, default ``None``) A reduction strategy to which the polynomials resulting @@ -497,7 +490,6 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None sage: R = SymmetricReductionStrategy(X, [x[1]^2]) sage: I.interreduction(RStrat=R) # needs sage.combinat Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational Field - """ DONE = [] TODO = [] @@ -566,7 +558,8 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None def interreduced_basis(self): """ - A fully symmetrically reduced generating set (type :class:`~sage.structure.sequence.Sequence`) of self. + A fully symmetrically reduced generating set (type + :class:`~sage.structure.sequence.Sequence`) of ``self``. This does essentially the same as :meth:`interreduction` with the option 'tailreduce', but it returns a @@ -579,7 +572,6 @@ def interreduced_basis(self): sage: I = X * (x[1] + x[2], x[1]*x[2]) sage: I.interreduced_basis() # needs sage.combinat [-x_1^2, x_2 + x_1] - """ return Sequence(self.interreduction(tailreduce=True).gens(), self.ring(), check=False) @@ -589,15 +581,15 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F INPUT: - - ``N`` -- (integer, default ``None``) Apply permutations in + - ``N`` -- integer (default: ``None``); apply permutations in `Sym(N)`. If it is not given then it will be replaced by the maximal variable index occurring in the generators of ``self.interreduction().squeezed()``. - - ``tailreduce`` -- (bool, default ``False``) If ``True``, perform + - ``tailreduce`` -- boolean (default: ``False``); if ``True``, perform tail reductions. - - ``report`` -- (object, default ``None``) If not ``None``, report + - ``report`` -- object (default ``None``); if not ``None``, report on the progress of computations. - - ``use_full_group`` (optional) -- If ``True``, apply *all* elements of + - ``use_full_group`` -- (optional) if ``True``, apply *all* elements of `Sym(N)` to the generators of ``self`` (this is what [AB2008]_ originally suggests). The default is to apply all elementary transpositions to the generators of ``self.squeezed()``, @@ -631,7 +623,6 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field sage: I.symmetrisation(N=3, use_full_group=True) # needs sage.combinat Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field - """ newOUT = self.interreduction(tailreduce=tailreduce, report=report).squeezed() R = self.ring() @@ -688,7 +679,6 @@ def symmetric_basis(self): sage: I = X * (x[1] + x[2], x[1]*x[2]) sage: I.symmetric_basis() # needs sage.combinat [x_1^2, x_2 + x_1] - """ return Sequence(self.symmetrisation(tailreduce=True).normalisation().gens(), self.ring(), check=False) @@ -705,7 +695,6 @@ def normalisation(self): sage: I.normalisation() Symmetric Ideal (x_2 + 3/4*x_1, x_2*x_1) of Infinite polynomial ring in x over Rational Field - """ return SymmetricIdeal(self.ring(), [X / X.lc() for X in self.gens() if X._p != 0]) @@ -730,7 +719,6 @@ def squeezed(self): sage: I.squeezed() Symmetric Ideal (x_2*y_1, x_1*y_2) of Infinite polynomial ring in x, y over Rational Field - """ return SymmetricIdeal(self.ring(), [X.squeezed() for X in self.gens()]) @@ -741,15 +729,15 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= INPUT: - - ``tailreduce`` -- (bool, default ``False``) If ``True``, use tail reduction + - ``tailreduce`` -- boolean (default: ``False``); if ``True``, use tail reduction in intermediate computations - - ``reduced`` -- (bool, default ``True``) If ``True``, return the reduced normalised - symmetric Groebner basis. - - ``algorithm`` -- (string, default ``None``) Determine the algorithm (see below for - available algorithms). - - ``report`` -- (object, default ``None``) If not ``None``, print information on the - progress of computation. - - ``use_full_group`` -- (bool, default ``False``) If ``True`` then proceed as + - ``reduced`` -- boolean (default: ``True``); if ``True``, return the reduced normalised + symmetric Groebner basis + - ``algorithm`` -- string (default: ``None``); determine the algorithm (see below for + available algorithms) + - ``report`` -- object (default ``None``); if not ``None``, print information on the + progress of computation + - ``use_full_group`` -- boolean (default: ``False``); if ``True`` then proceed as originally suggested by [AB2008]_. Our default method should be faster; see :meth:`symmetrisation` for more details. @@ -802,7 +790,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= If only a system is given - e.g. 'magma' - the default algorithm is chosen for that system. - .. note:: + .. NOTE:: The Singular and libSingular versions of the respective algorithms are identical, but the former calls an external @@ -900,7 +888,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= [x_1] The Aschenbrenner-Hillar algorithm is only guaranteed to work - if the base ring is a field. So, we raise a :class:`TypeError` if this + if the base ring is a field. So, we raise a :exc:`TypeError` if this is not the case:: sage: R. = InfinitePolynomialRing(ZZ) diff --git a/src/sage/rings/polynomial/symmetric_reduction.pyx b/src/sage/rings/polynomial/symmetric_reduction.pyx index 98305d20769..0794ca8a941 100644 --- a/src/sage/rings/polynomial/symmetric_reduction.pyx +++ b/src/sage/rings/polynomial/symmetric_reduction.pyx @@ -131,12 +131,12 @@ cdef class SymmetricReductionStrategy: INPUT: - ``Parent`` -- an Infinite Polynomial Ring, see - :mod:`~sage.rings.polynomial.infinite_polynomial_element`. - - ``L`` -- (list, default the empty list) List of elements of ``Parent`` - with respect to which will be reduced. - - ``good_input`` -- (bool, default ``None``) If this optional parameter + :mod:`~sage.rings.polynomial.infinite_polynomial_element` + - ``L`` -- list (default: the empty list); list of elements of ``Parent`` + with respect to which will be reduced + - ``good_input`` -- boolean (default: ``None``); if this optional parameter is true, it is assumed that each element of ``L`` is symmetrically - reduced with respect to the previous elements of ``L``. + reduced with respect to the previous elements of ``L`` EXAMPLES:: @@ -147,7 +147,6 @@ cdef class SymmetricReductionStrategy: y_3 + 3*y_2^2*y_1 + 2*y_2*y_1^2 sage: S.tailreduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) # needs sage.combinat y_3 - """ def __init__(self, Parent, L=None, tailreduce=False, good_input=None): """ @@ -158,7 +157,6 @@ cdef class SymmetricReductionStrategy: sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]], good_input=True) sage: S == loads(dumps(S)) True - """ self._parent = Parent if hasattr(Parent, '_P'): @@ -258,7 +256,7 @@ cdef class SymmetricReductionStrategy: def gens(self): """ - Return the list of Infinite Polynomials modulo which self reduces. + Return the list of Infinite Polynomials modulo which ``self`` reduces. EXAMPLES:: @@ -272,22 +270,21 @@ cdef class SymmetricReductionStrategy: y_2^2*y_1 sage: S.gens() [y_2*y_1^2, y_2^2*y_1] - """ return self._lm def setgens(self, L): """ - Define the list of Infinite Polynomials modulo which self reduces. + Define the list of Infinite Polynomials modulo which ``self`` reduces. INPUT: - - ``L`` -- a list of elements of the underlying infinite polynomial ring. + - ``L`` -- list of elements of the underlying infinite polynomial ring .. NOTE:: It is not tested if ``L`` is a good input. That method simply - assigns a *copy* of ``L`` to the generators of self. + assigns a *copy* of ``L`` to the generators of ``self``. EXAMPLES:: @@ -305,7 +302,6 @@ cdef class SymmetricReductionStrategy: False sage: R.gens() == S.gens() True - """ self._lm = [X for X in L] @@ -326,7 +322,6 @@ cdef class SymmetricReductionStrategy: sage: S.reset() sage: S Symmetric Reduction Strategy in Infinite polynomial ring in y over Rational Field - """ self._lm = [] self._lengths = [] @@ -346,7 +341,6 @@ cdef class SymmetricReductionStrategy: y_2*y_1^2, y_2^2*y_1 with tailreduction - """ s = "Symmetric Reduction Strategy in %s" % self._parent if self._lm: @@ -359,11 +353,10 @@ cdef class SymmetricReductionStrategy: """ INPUT: - A polynomial or an infinite polynomial + A polynomial or an infinite polynomial. - OUTPUT: - - A polynomial whose parent ring allows for coercion of any generator of self + OUTPUT: a polynomial whose parent ring allows for coercion of any + generator of ``self`` EXAMPLES:: @@ -379,7 +372,6 @@ cdef class SymmetricReductionStrategy: True sage: S(p) == S(p._p) True - """ if hasattr(p, '_p'): p = p._p @@ -412,8 +404,8 @@ cdef class SymmetricReductionStrategy: INPUT: - - ``p`` -- An element of the underlying infinite polynomial ring. - - ``good_input`` -- (bool, default ``None``) If ``True``, it is + - ``p`` -- an element of the underlying infinite polynomial ring + - ``good_input`` -- boolean (default: ``None``); if ``True``, it is assumed that ``p`` is reduced with respect to ``self``. Otherwise, this reduction will be done first (which may cost some time). @@ -471,7 +463,6 @@ cdef class SymmetricReductionStrategy: In the previous example, ``x[3] + x[2]`` is added without being reduced to zero. - """ from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial p = InfinitePolynomial(self._parent, self(p)) @@ -525,16 +516,14 @@ cdef class SymmetricReductionStrategy: INPUT: - - ``p`` -- an element of the underlying infinite polynomial ring. - - ``notail`` -- (bool, default ``False``) If ``True``, tail reduction + - ``p`` -- an element of the underlying infinite polynomial ring + - ``notail`` -- boolean (default: ``False``); if ``True``, tail reduction is avoided (but there is no guarantee that there will be no tail - reduction at all). - - ``report`` -- (object, default ``None``) If not ``None``, print - information on the progress of the computation. + reduction at all) + - ``report`` -- object (default: ``None``); if not ``None``, print + information on the progress of the computation - OUTPUT: - - Reduction of ``p`` with respect to ``self``. + OUTPUT: reduction of ``p`` with respect to ``self`` .. NOTE:: @@ -568,7 +557,6 @@ cdef class SymmetricReductionStrategy: Each ':' indicates that one reduction of the leading monomial was performed. Eventually, the '>' indicates that the computation is finished. - """ from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial cdef list lml = self._lm @@ -623,9 +611,9 @@ cdef class SymmetricReductionStrategy: INPUT: - - ``p`` -- an element of the underlying infinite polynomial ring. - - ``report`` -- (object, default ``None``) If not ``None``, print - information on the progress of the computation. + - ``p`` -- an element of the underlying infinite polynomial ring + - ``report`` -- object (default: ``None``); if not ``None``, print + information on the progress of the computation OUTPUT: diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index 431e3b03fa6..1bed10ba867 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -519,7 +519,7 @@ Block term order defined by term orders `<_1, <_2, \dots, <_n`. `x^a < x^b` if and only if `a = b` with respect to the first `n-1` term orders and `a <_n b` -with respect to the `n`th term order `<_n`. +with respect to the `n`-th term order `<_n`. """ description_mapping = { @@ -573,13 +573,13 @@ def __init__(self, name='lex', n=0, force=False): INPUT: - - ``name`` -- name of the term order (default: lex) + - ``name`` -- name of the term order (default: ``'lex'``) - - ``n`` -- number of variables (default is `0`) weights for + - ``n`` -- number of variables (default: `0`) weights for weighted degree orders. The weights are converted to integers and must be positive. - - ``force`` -- ignore unknown term orders. + - ``force`` -- ignore unknown term orders See the ``sage.rings.polynomial.term_order`` module for help which names and orders are available. @@ -623,7 +623,7 @@ def __init__(self, name='lex', n=0, force=False): (Degree reverse lexicographic term order of length 5, Degree lexicographic term order of length 2) - .. note:: + .. NOTE:: The optional `n` parameter is not necessary if only non-block orders like `deglex` are @@ -632,7 +632,7 @@ def __init__(self, name='lex', n=0, force=False): TESTS: - We demonstrate that non-positive weights are refused and non-integral weights + We demonstrate that nonpositive weights are refused and non-integral weights are converted to integers (and potentially rounded):: sage: N. = PolynomialRing(QQ, 3, order=TermOrder('wdeglex',[-1,2,-3])) @@ -864,7 +864,7 @@ def __init__(self, name='lex', n=0, force=False): def __hash__(self): r""" - A hash function + A hash function. EXAMPLES:: @@ -874,7 +874,7 @@ def __hash__(self): def __copy(self, other): """ - Copy other term order to self. + Copy ``other`` term order to ``self``. EXAMPLES:: @@ -993,7 +993,6 @@ def sortkey_deglex(self, f): False sage: x > 1 # needs sage.rings.number_field True - """ return (sum(f.nonzero_values(sort=False)), f) @@ -1013,7 +1012,6 @@ def sortkey_degrevlex(self, f): False sage: x > 1 # needs sage.rings.number_field True - """ return (sum(f.nonzero_values(sort=False)), f.reversed().emul(-1)) @@ -1891,7 +1889,6 @@ def matrix(self): sage: t.matrix() # needs sage.modules [1 2] [0 1] - """ return self._matrix @@ -1978,7 +1975,7 @@ def __ne__(self, other): def __add__(self, other): """ - Construct a block order combining self and other. + Construct a block order combining ``self`` and ``other``. INPUT: @@ -2019,7 +2016,7 @@ def __len__(self): def __getitem__(self, i): r""" - Return the i-th block of this term order. + Return the `i`-th block of this term order. INPUT: @@ -2159,7 +2156,7 @@ def is_weighted_degree_order(self): def termorder_from_singular(S): """ - Return the Sage term order of the basering in the given Singular interface + Return the Sage term order of the basering in the given Singular interface. INPUT: diff --git a/src/sage/rings/polynomial/toy_buchberger.py b/src/sage/rings/polynomial/toy_buchberger.py index 5ee623b4ef0..f00f4bdbabd 100644 --- a/src/sage/rings/polynomial/toy_buchberger.py +++ b/src/sage/rings/polynomial/toy_buchberger.py @@ -157,7 +157,7 @@ def spol(f, g): INPUT: - - ``f, g`` -- polynomials + - ``f``, ``g`` -- polynomials OUTPUT: the S-polynomial of f and g @@ -301,7 +301,7 @@ def update(G, B, h): - ``G`` -- an intermediate Groebner basis - - ``B`` -- a set of critical pairs + - ``B`` -- set of critical pairs - ``h`` -- a polynomial @@ -378,7 +378,7 @@ def select(P): INPUT: - - ``P`` -- a list of critical pairs + - ``P`` -- list of critical pairs OUTPUT: an element of P @@ -401,7 +401,7 @@ def inter_reduction(Q): INPUT: - - ``Q`` -- a set of polynomials + - ``Q`` -- set of polynomials OUTPUT: diff --git a/src/sage/rings/polynomial/toy_d_basis.py b/src/sage/rings/polynomial/toy_d_basis.py index ec783625140..fe8b367cb22 100644 --- a/src/sage/rings/polynomial/toy_d_basis.py +++ b/src/sage/rings/polynomial/toy_d_basis.py @@ -276,11 +276,9 @@ def select(P): INPUT: - - ``P`` -- a list of critical pairs + - ``P`` -- list of critical pairs - OUTPUT: - - an element of P + OUTPUT: an element of P EXAMPLES:: @@ -315,12 +313,10 @@ def update(G, B, h): INPUT: - ``G`` -- an intermediate Groebner basis - - ``B`` -- a list of critical pairs + - ``B`` -- list of critical pairs - ``h`` -- a polynomial - OUTPUT: - - ``G,B`` where ``G`` and ``B`` are updated + OUTPUT: ``G,B`` where ``G`` and ``B`` are updated EXAMPLES:: diff --git a/src/sage/rings/polynomial/toy_variety.py b/src/sage/rings/polynomial/toy_variety.py index 7a393595b61..ba67a1ece2e 100644 --- a/src/sage/rings/polynomial/toy_variety.py +++ b/src/sage/rings/polynomial/toy_variety.py @@ -42,11 +42,9 @@ def is_triangular(B) -> bool: INPUT: - - ``B`` -- a list/tuple of polynomials or a multivariate polynomial ideal + - ``B`` -- list/tuple of polynomials or a multivariate polynomial ideal - OUTPUT: - - ``True`` if the basis is triangular; ``False`` otherwise. + OUTPUT: ``True`` if the basis is triangular; ``False`` otherwise EXAMPLES:: @@ -90,11 +88,9 @@ def coefficient_matrix(polys): INPUT: - - ``polys`` -- a list/tuple of polynomials - - OUTPUT: + - ``polys`` -- list/tuple of polynomials - A matrix ``M`` of the coefficients of ``polys`` + OUTPUT: a matrix ``M`` of the coefficients of ``polys`` EXAMPLES:: @@ -149,7 +145,7 @@ def is_linearly_dependent(polys) -> bool: INPUT: - - ``polys`` -- a list/tuple of polynomials + - ``polys`` -- list/tuple of polynomials OUTPUT: @@ -204,7 +200,7 @@ def linear_representation(p, polys): INPUT: - ``p`` -- a polynomial - - ``polys`` -- a list/tuple of polynomials + - ``polys`` -- list/tuple of polynomials OUTPUT: @@ -242,12 +238,10 @@ def triangular_factorization(B, n=-1): INPUT: - - ``B`` -- a list/tuple of polynomials or a multivariate polynomial ideal + - ``B`` -- list/tuple of polynomials or a multivariate polynomial ideal - ``n`` -- the recursion parameter (default: ``-1``) - OUTPUT: - - A list ``T`` of triangular sets ``T_0``, ``T_1``, etc. + OUTPUT: list ``T`` of triangular sets ``T_0``, ``T_1``, etc. EXAMPLES:: @@ -320,7 +314,7 @@ def elim_pol(B, n=-1): INPUT: - - ``B`` -- a list/tuple of polynomials or a multivariate polynomial ideal + - ``B`` -- list/tuple of polynomials or a multivariate polynomial ideal - ``n`` -- the variable to check (see above) (default: ``-1``) EXAMPLES:: diff --git a/src/sage/rings/polynomial/weil/meson.build b/src/sage/rings/polynomial/weil/meson.build new file mode 100644 index 00000000000..2c9bd006919 --- /dev/null +++ b/src/sage/rings/polynomial/weil/meson.build @@ -0,0 +1,19 @@ +py.install_sources( + 'all.py', + 'power_sums.h', + subdir: 'sage/rings/polynomial/weil', +) + +extension_data = {'weil_polynomials' : files('weil_polynomials.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/polynomial/weil', + install: true, + include_directories: [inc_cpython, inc_flint, inc_rings, inc_src], + dependencies: [py_dep, cysignals, flint, gmp], + ) +endforeach + diff --git a/src/sage/rings/polynomial/weil/weil_polynomials.pyx b/src/sage/rings/polynomial/weil/weil_polynomials.pyx index f9d61a2a352..e2dd7bd04e7 100755 --- a/src/sage/rings/polynomial/weil/weil_polynomials.pyx +++ b/src/sage/rings/polynomial/weil/weil_polynomials.pyx @@ -143,7 +143,6 @@ cdef class dfs_manager: def __dealloc__(self): """ Deallocate memory. - """ ps_static_clear(self.ps_st_data) self.ps_st_data = NULL @@ -231,6 +230,7 @@ cdef class dfs_manager: raise RuntimeError("Node limit ({0:%d}) exceeded".format(self.node_limit)) return ans + class WeilPolynomials_iter(): r""" Iterator created by WeilPolynomials. @@ -303,13 +303,13 @@ class WeilPolynomials_iter(): coefflist.append(j) modlist.append(k) # Remove cofactor from initial coefficients - if num_cofactor == 1: #cofactor x + sqrt(q) + if num_cofactor == 1: # cofactor x + sqrt(q) for i in range(1, len(coefflist)): coefflist[i] -= coefflist[i-1]*q.sqrt() - elif num_cofactor == 2: #cofactor x + sqrt(q) + elif num_cofactor == 2: # cofactor x + sqrt(q) for i in range(1, len(coefflist)): coefflist[i] += coefflist[i-1]*q.sqrt() - elif num_cofactor == 3: #cofactor x^2 - q + elif num_cofactor == 3: # cofactor x^2 - q for i in range(2, len(coefflist)): coefflist[i] += coefflist[i-2]*q # Asymmetrize initial coefficients @@ -333,7 +333,7 @@ class WeilPolynomials_iter(): def __iter__(self): r""" - Return the iterator (i.e. `self`). + Return the iterator (i.e. ``self``). EXAMPLES:: @@ -409,34 +409,34 @@ class WeilPolynomials(): INPUT: - - ``d`` -- integer, the degree of the polynomials + - ``d`` -- integer; the degree of the polynomials - - ``q`` -- integer, the square of the complex absolute value of the roots + - ``q`` -- integer; the square of the complex absolute value of the roots - - ``sign`` -- integer (default `1`), the sign `s` of the functional equation + - ``sign`` -- integer (default: `1`); the sign `s` of the functional equation - - ``lead`` -- integer, list of integers or pairs of integers (default `1`) + - ``lead`` -- integer (default: `1`); list of integers or pairs of integers These are constraints on the leading coefficients of the generated polynomials. If pairs `(a, b)` of integers are given, they are treated as a constraint of the form `\equiv a \pmod{b}`; the moduli must be in decreasing order by divisibility, and the modulus of the leading coefficient must be 0. - - ``node_limit`` -- integer (default ``None``) + - ``node_limit`` -- integer (default: ``None``) If set, imposes an upper bound on the number of terminal nodes during the search - (will raise a ``RuntimeError`` if exceeded). + (will raise a :exc:`RuntimeError` if exceeded). - - ``parallel`` -- boolean (default ``False``), whether to use multiple processes + - ``parallel`` -- boolean (default: ``False``); whether to use multiple processes If set, will raise an error unless this file was compiled with OpenMP support (see instructions at the top of :mod:`sage.rings.polynomial.weil.weil_polynomials`). - - ``squarefree`` -- boolean (default ``False``), + - ``squarefree`` -- boolean (default: ``False``) If set, only squarefree polynomials will be returned. - - ``polring`` -- optional, a polynomial ring in which to construct the results + - ``polring`` -- (optional) a polynomial ring in which to construct the results EXAMPLES: diff --git a/src/sage/rings/power_series_mpoly.pyx b/src/sage/rings/power_series_mpoly.pyx index 714d939c30b..741b0ad94e7 100644 --- a/src/sage/rings/power_series_mpoly.pyx +++ b/src/sage/rings/power_series_mpoly.pyx @@ -3,7 +3,7 @@ from sage.rings.power_series_ring_element cimport PowerSeries from sage.structure.element cimport Element from sage.rings.infinity import infinity -from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing +from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base from sage.rings import power_series_poly @@ -56,13 +56,13 @@ cdef class PowerSeries_mpoly(PowerSeries): # avoid having an if statement in the inner loop of a # doubly-nested for loop. d = {} - if is_MPolynomialRing(B): + if isinstance(B, MPolynomialRing_base): for i in range(len(v)): - for n, c in v[i].dict().iteritems(): + for n, c in v[i].monomial_coefficients().items(): d[tuple(n) + (i,)] = c else: for i in range(len(v)): - for n, c in v[i].dict().iteritems(): + for n, c in v[i].monomial_coefficients().items(): d[(n,i)] = c self.__f = S(d) @@ -116,7 +116,6 @@ cdef class PowerSeries_mpoly(PowerSeries): prec = prec, check =True) - def __iter__(self): """ Return an iterator over the coefficients of this power series. diff --git a/src/sage/rings/power_series_pari.pyx b/src/sage/rings/power_series_pari.pyx index c9ff9beeee7..8f7ff769dd1 100644 --- a/src/sage/rings/power_series_pari.pyx +++ b/src/sage/rings/power_series_pari.pyx @@ -128,7 +128,6 @@ cdef class PowerSeries_pari(PowerSeries): - ``check`` -- ignored, but accepted for compatibility with :class:`~sage.rings.power_series_poly.PowerSeries_poly` - """ def __init__(self, parent, f=0, prec=infinity, check=None): """ @@ -141,7 +140,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: TestSuite(q).run() sage: f = q - q^3 + O(q^10) sage: TestSuite(f).run() - """ cdef Parent f_parent cdef pari_gen g @@ -214,7 +212,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: R. = PowerSeriesRing(ZZ, implementation='pari') sage: hash(t^2 + 1) == hash(pari(t^2 + 1)) True - """ return hash(self.g) @@ -230,7 +227,6 @@ cdef class PowerSeries_pari(PowerSeries): True sage: f == loads(dumps(f)) True - """ return PowerSeries_pari, (self._parent, self.g, self._prec, False) @@ -243,7 +239,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: R. = PowerSeriesRing(GF(7), implementation='pari') sage: (3 - t^3 + O(t^5)).__pari__() Mod(3, 7) + Mod(6, 7)*t^3 + O(t^5) - """ return self.g @@ -257,7 +252,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: f = 3 - t^3 + O(t^5) sage: f.polynomial() 6*t^3 + 3 - """ return self._parent._poly_ring()(self.list()) @@ -276,7 +270,6 @@ cdef class PowerSeries_pari(PowerSeries): 7 sage: R(0).valuation() +Infinity - """ if not self.g: return self._prec @@ -295,7 +288,6 @@ cdef class PowerSeries_pari(PowerSeries): False sage: bool(O(t^18)) False - """ return bool(self.g) @@ -394,7 +386,6 @@ cdef class PowerSeries_pari(PowerSeries): 1 + a*x + a^2*x^2 + a^3*x^3 + a^4*x^4 + a^5*x^5 + a^6*x^6 + O(x^7) sage: h(x^2, a=3) 1 + 3*x^2 + 4*x^4 + 2*x^6 + x^8 + 3*x^10 + 4*x^12 + O(x^14) - """ if len(kwds) >= 1: name = self._parent.variable_name() @@ -437,7 +428,7 @@ cdef class PowerSeries_pari(PowerSeries): return Q(self.polynomial()(a)).add_bigoh(t * self._prec) elif isinstance(Q, (PowerSeriesRing_generic, LaurentSeriesRing)): # In Sage, we want an error to be raised when trying to - # substitute a series of non-positive valuation, but PARI + # substitute a series of nonpositive valuation, but PARI # (2.8.0-development) does not do this. For example, # subst(1 + O(x), x, 1/y) yields O(y^-1). if a.valuation() <= 0: @@ -463,7 +454,7 @@ cdef class PowerSeries_pari(PowerSeries): same precision, whose coefficients are the same as ``self`` for those indices in the slice, and 0 otherwise. - Returns 0 for negative coefficients. Raises an ``IndexError`` + Returns 0 for negative coefficients. Raises an :exc:`IndexError` if trying to access beyond known coefficients. EXAMPLES:: @@ -491,7 +482,6 @@ cdef class PowerSeries_pari(PowerSeries): 1 + t^3 - 4*t^4 + O(t^7) sage: f[:4] 1 + t^3 + O(t^7) - """ cdef long t if isinstance(n, slice): @@ -516,7 +506,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: R. = PowerSeriesRing(QQ, default_prec=6, implementation='pari') sage: ~(R(1-t)) 1 + t + t^2 + t^3 + t^4 + t^5 + O(t^6) - """ h = ~self.g if h.valuation(self._parent.variable_name()) < 0: @@ -533,7 +522,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: f = t + 17/5*t^3 + 2*t^4 + O(t^5) sage: -f -t - 17/5*t^3 - 2*t^4 + O(t^5) - """ return construct_from_pari(self._parent, -self.g) @@ -549,7 +537,6 @@ cdef class PowerSeries_pari(PowerSeries): 27 - 27*t^3 + O(t^5) sage: b = f^-3; b 1/27 + 1/27*t^3 + O(t^5) - """ h = self.g ** n if h.valuation(self._parent.variable_name()) < 0: @@ -569,7 +556,6 @@ cdef class PowerSeries_pari(PowerSeries): x^2 + O(x^3) sage: f+g x^2 + O(x^3) - """ return construct_from_pari(self._parent, self.g + (right).g) @@ -583,7 +569,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: R. = PowerSeriesRing(k, implementation='pari') sage: w*t^2 -w*t +13 - (w*t^2 + w*t) 13 - 2*w*t - """ return construct_from_pari(self._parent, self.g - (right).g) @@ -596,7 +581,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: k. = PowerSeriesRing(ZZ, implementation='pari') sage: (1+17*w+15*w^3+O(w^5))*(19*w^10+O(w^12)) 19*w^10 + 323*w^11 + O(w^12) - """ return construct_from_pari(self._parent, self.g * (right).g) @@ -610,7 +594,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: f = t + 3*t^4 + O(t^11) sage: f * GF(7)(3) 3*t + 2*t^4 + O(t^11) - """ return construct_from_pari(self._parent, self.g * c) @@ -624,7 +607,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: f = 1 + 3*t^4 + O(t^120) sage: 2 * f 2 + 6*t^4 + O(t^120) - """ return construct_from_pari(self._parent, c * self.g) @@ -643,7 +625,6 @@ cdef class PowerSeries_pari(PowerSeries): t^-1 + 10 sage: g.parent() Laurent Series Ring in t over Finite Field of size 11 - """ h = self.g / (right).g if h.valuation(self._parent.variable_name()) < 0: @@ -668,7 +649,6 @@ cdef class PowerSeries_pari(PowerSeries): sage: S. = PowerSeriesRing(pAdicRing(5), implementation='pari') sage: (2 + u).list() [2 + O(5^20), 1 + O(5^20)] - """ cdef pari_gen g = self.g cdef long vn = get_var(self._parent.variable_name()) @@ -692,10 +672,10 @@ cdef class PowerSeries_pari(PowerSeries): INPUT: - - ``n`` -- a non-negative integer (optional); if `n` is not - given, it will be taken to be the precision of ``self`, - unless this is ``+Infinity``, in which case we just - return ``self.list()`` + - ``n`` -- nonnegative integer (optional); if `n` is not + given, it will be taken to be the precision of ``self``, + unless this is ``+Infinity``, in which case we just + return ``self.list()`` EXAMPLES:: @@ -718,7 +698,6 @@ cdef class PowerSeries_pari(PowerSeries): [1, -17, 13, 0, 10] sage: g.padded_list(10) [1, -17, 13, 0, 10, 0, 0, 0, 0, 0] - """ if n is None: if self._prec is infinity: @@ -755,7 +734,7 @@ cdef class PowerSeries_pari(PowerSeries): else: return [R(g)] + [R.zero()] * (n - 1) - def dict(self): + def monomial_coefficients(self): """ Return a dictionary of coefficients for ``self``. @@ -767,11 +746,17 @@ cdef class PowerSeries_pari(PowerSeries): sage: R. = PowerSeriesRing(ZZ, implementation='pari') sage: f = 1 + t^10 + O(t^12) - sage: f.dict() + sage: f.monomial_coefficients() {0: 1, 10: 1} + ``dict`` is an alias:: + + sage: f.dict() + {0: 1, 10: 1} """ - return self.polynomial().dict() + return self.polynomial().monomial_coefficients() + + dict = monomial_coefficients def _derivative(self, var=None): """ @@ -804,7 +789,6 @@ cdef class PowerSeries_pari(PowerSeries): 4*t^3*x^3 + O(x^4) sage: f._derivative(t) 3*t^2*x^4 + O(x^5) - """ if var is None: var = self._parent.variable_name() @@ -848,7 +832,6 @@ cdef class PowerSeries_pari(PowerSeries): 1/2*a*t^2 + 5/3*t^3 sage: f.integral(a) 1/2*a^2*t + 5*a*t^2 - """ if var is None: var = self._parent.variable_name() @@ -937,7 +920,6 @@ cdef class PowerSeries_pari(PowerSeries): Traceback (most recent call last): ... PariError: domain error in serreverse: valuation != 1 - """ cdef PowerSeries_pari f if self._prec is infinity: diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index cb0b0fcad1e..309d72c8f6a 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -174,21 +174,21 @@ cdef class PowerSeries_poly(PowerSeries): def __call__(self, *x, **kwds): """ - Evaluate the series at x=a. + Evaluate the series at `x=a`. INPUT: - - ``x``: + - ``x``: - - a tuple of elements the first of which can be meaningfully - substituted in ``self``, with the remainder used for substitution - in the coefficients of ``self``. + - a tuple of elements the first of which can be meaningfully + substituted in ``self``, with the remainder used for substitution + in the coefficients of ``self``. - - a dictionary for kwds:value pairs. If the variable name of - self is a keyword it is substituted for. Other keywords - are used for substitution in the coefficients of self. + - a dictionary for kwds:value pairs. If the variable name of + ``self`` is a keyword it is substituted for. Other keywords + are used for substitution in the coefficients of ``self``. - OUTPUT: the value of ``self`` after substitution. + OUTPUT: the value of ``self`` after substitution EXAMPLES:: @@ -232,7 +232,7 @@ cdef class PowerSeries_poly(PowerSeries): sage: f(2*u + u^3 + O(u^5)) 4*u^2 + u^3 + 4*u^4 + 5*u^5 + O(u^6) - As can a p-adic integer as long as the coefficient ring is compatible:: + As can a `p`-adic integer as long as the coefficient ring is compatible:: sage: f(100 + O(5^7)) # needs sage.rings.padics 5^4 + 3*5^5 + 4*5^6 + 2*5^7 + 2*5^8 + O(5^9) @@ -409,7 +409,7 @@ cdef class PowerSeries_poly(PowerSeries): Return the ``n``-th coefficient of ``self``. This returns 0 for negative coefficients and raises an - ``IndexError`` if trying to access beyond known coefficients. + :exc:`IndexError` if trying to access beyond known coefficients. If ``n`` is a slice object ``[:k]``, this will return a power series of the same precision, whose coefficients are the same @@ -675,7 +675,7 @@ cdef class PowerSeries_poly(PowerSeries): sage: u*v 1 + O(t^12) - If we try a non-zero, non-unit constant term, we end up in + If we try a nonzero, non-unit constant term, we end up in the fraction field, i.e. the Laurent series ring:: sage: R. = PowerSeriesRing(ZZ) @@ -700,7 +700,6 @@ cdef class PowerSeries_poly(PowerSeries): Traceback (most recent call last): ... ValueError: must be an integral domain - """ if self.is_one(): return self @@ -765,7 +764,7 @@ cdef class PowerSeries_poly(PowerSeries): def truncate_powerseries(self, long prec): r""" Given input ``prec`` = `n`, returns the power series of degree - `< n` which is equivalent to self modulo `x^n`. + `< n` which is equivalent to ``self`` modulo `x^n`. EXAMPLES:: @@ -795,7 +794,7 @@ cdef class PowerSeries_poly(PowerSeries): """ return self.__f.list() - def dict(self): + def monomial_coefficients(self): """ Return a dictionary of coefficients for ``self``. @@ -807,10 +806,17 @@ cdef class PowerSeries_poly(PowerSeries): sage: R. = ZZ[[]] sage: f = 1 + t^10 + O(t^12) + sage: f.monomial_coefficients() + {0: 1, 10: 1} + + ``dict`` is an alias:: + sage: f.dict() {0: 1, 10: 1} """ - return self.__f.dict() + return self.__f.monomial_coefficients() + + dict = monomial_coefficients def _derivative(self, var=None): """ @@ -1122,9 +1128,7 @@ cdef class PowerSeries_poly(PowerSeries): - ``m``, ``n`` -- integers, describing the degrees of the polynomials - OUTPUT: - - a ratio of two polynomials + OUTPUT: a ratio of two polynomials ALGORITHM: diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index 1052d963bdc..e6c932aadff 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -44,7 +44,8 @@ x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 + O(x^10) sage: R. = PowerSeriesRing(QQ, default_prec=15) sage: sin(x) - x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11 + 1/6227020800*x^13 + O(x^15) + x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11 + + 1/6227020800*x^13 + O(x^15) An iterated example:: @@ -139,8 +140,6 @@ from sage.misc.lazy_import import lazy_import from sage.rings import ( integer, - laurent_series_ring, - laurent_series_ring_element, power_series_mpoly, power_series_poly, power_series_ring_element, @@ -148,11 +147,12 @@ ) from sage.rings.fraction_field_element import FractionFieldElement from sage.rings.infinity import infinity -from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.structure.category_object import normalize_names from sage.structure.element import Expression, parent +from sage.structure.parent import Parent from sage.structure.nonexact import Nonexact from sage.structure.unique_representation import UniqueRepresentation @@ -175,6 +175,8 @@ LaurentSeriesRing = () LaurentSeries = () +lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') + def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, sparse=False, default_prec=None, order='negdeglex', @@ -185,24 +187,22 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, INPUT: + - ``base_ring`` -- a commutative ring - - ``base_ring`` -- a commutative ring - - - ``name``, ``names`` -- name(s) of the indeterminate + - ``name``, ``names`` -- name(s) of the indeterminate - ``default_prec`` -- the default precision used if an exact object must - be changed to an approximate object in order to do an arithmetic - operation. If left as ``None``, it will be set to the global - default (20) in the univariate case, and 12 in the multivariate case. + be changed to an approximate object in order to do an arithmetic + operation. If left as ``None``, it will be set to the global + default (20) in the univariate case, and 12 in the multivariate case. - - ``sparse`` -- (default: ``False``) whether power series - are represented as sparse objects. + - ``sparse`` -- boolean (default: ``False``); whether power series + are represented as sparse objects - ``order`` -- (default: ``negdeglex``) term ordering, for multivariate case - ``num_gens`` -- number of generators, for multivariate case - There is a unique power series ring over each base ring with given variable name. Two power series over the same base ring with different variable names are not equal or isomorphic. @@ -355,7 +355,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, * :func:`sage.misc.defaults.set_series_precision` """ - #multivariate case: + # multivariate case: # examples for first case: # PowerSeriesRing(QQ,'x,y,z') # PowerSeriesRing(QQ,['x','y','z']) @@ -364,7 +364,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, names = name if isinstance(names, (tuple, list)) and len(names) > 1 or (isinstance(names, str) and ',' in names): return _multi_variate(base_ring, num_gens=arg2, names=names, - order=order, default_prec=default_prec, sparse=sparse) + order=order, default_prec=default_prec, sparse=sparse) # examples for second case: # PowerSeriesRing(QQ,3,'t') if arg2 is None and num_gens is not None: @@ -373,7 +373,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, if (isinstance(arg2, str) and isinstance(names, (int, integer.Integer))): return _multi_variate(base_ring, num_gens=names, names=arg2, - order=order, default_prec=default_prec, sparse=sparse) + order=order, default_prec=default_prec, sparse=sparse) # univariate case: the arguments to PowerSeriesRing used to be # (base_ring, name=None, default_prec=20, names=None, sparse=False), @@ -385,11 +385,10 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, elif arg2 is not None: default_prec = arg2 - ## too many things (padics, elliptic curves) depend on this behavior, - ## so no warning for now. - ## + # ## too many things (padics, elliptic curves) depend on this behavior, + # ## so no warning for now. - # if isinstance(name, (int,integer.Integer)) or isinstance(arg2,(int,integer.Integer)): + # if isinstance(name, (int, integer.Integer)) or isinstance(arg2, (int, integer.Integer)): # deprecation(issue_number, "This behavior of PowerSeriesRing is being deprecated in favor of constructing multivariate power series rings. (See Github issue #1956.)") # the following is the original, univariate-only code @@ -427,8 +426,9 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, raise TypeError("base_ring must be a commutative ring") return R + def _multi_variate(base_ring, num_gens=None, names=None, - order='negdeglex', default_prec=None, sparse=False): + order='negdeglex', default_prec=None, sparse=False): """ Construct multivariate power series ring. """ @@ -436,7 +436,7 @@ def _multi_variate(base_ring, num_gens=None, names=None, raise TypeError("you must specify a variable name or names") if num_gens is None: - if isinstance(names,str): + if isinstance(names, str): num_gens = len(names.split(',')) elif isinstance(names, (list, tuple)): num_gens = len(names) @@ -458,6 +458,7 @@ def _multi_variate(base_ring, num_gens=None, names=None, def _single_variate(): pass + def is_PowerSeriesRing(R): """ Return ``True`` if this is a *univariate* power series ring. This is in @@ -468,6 +469,10 @@ def is_PowerSeriesRing(R): sage: from sage.rings.power_series_ring import is_PowerSeriesRing sage: is_PowerSeriesRing(10) + doctest:warning... + DeprecationWarning: The function is_PowerSeriesRing is deprecated; + use 'isinstance(..., (PowerSeriesRing_generic, LazyPowerSeriesRing) and ....ngens() == 1)' instead. + See https://github.com/sagemath/sage/issues/38290 for details. False sage: is_PowerSeriesRing(QQ[['x']]) True @@ -476,13 +481,17 @@ def is_PowerSeriesRing(R): sage: is_PowerSeriesRing(LazyPowerSeriesRing(QQ, 'x, y')) False """ - from sage.rings.lazy_series_ring import LazyPowerSeriesRing + from sage.misc.superseded import deprecation + deprecation(38290, + "The function is_PowerSeriesRing is deprecated; " + "use 'isinstance(..., (PowerSeriesRing_generic, LazyPowerSeriesRing) and ....ngens() == 1)' instead.") if isinstance(R, (PowerSeriesRing_generic, LazyPowerSeriesRing)): return R.ngens() == 1 else: return False -class PowerSeriesRing_generic(UniqueRepresentation, ring.CommutativeRing, Nonexact): + +class PowerSeriesRing_generic(UniqueRepresentation, Parent, Nonexact): """ A power series ring. """ @@ -490,19 +499,17 @@ class PowerSeriesRing_generic(UniqueRepresentation, ring.CommutativeRing, Nonexa def __init__(self, base_ring, name=None, default_prec=None, sparse=False, implementation=None, category=None): """ - Initializes a power series ring. + Initialize a power series ring. INPUT: + - ``base_ring`` -- a commutative ring - - ``base_ring`` -- a commutative ring - - - ``name`` -- name of the indeterminate + - ``name`` -- name of the indeterminate - - ``default_prec`` -- the default precision + - ``default_prec`` -- the default precision - - ``sparse`` -- whether or not power series are - sparse + - ``sparse`` -- whether or not power series are sparse - ``implementation`` -- either ``'poly'``, ``'mpoly'``, or ``'pari'``. Other values (for example ``'NTL'``) are passed to @@ -540,14 +547,13 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, Category of complete discrete valuation rings sage: TestSuite(R).run() - It is checked that the default precision is non-negative + It is checked that the default precision is nonnegative (see :issue:`19409`):: sage: PowerSeriesRing(ZZ, 'x', default_prec=-5) Traceback (most recent call last): ... - ValueError: default_prec (= -5) must be non-negative - + ValueError: default_prec (= -5) must be nonnegative """ if implementation is None: try: @@ -571,7 +577,7 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, from sage.misc.defaults import series_precision default_prec = series_precision() elif default_prec < 0: - raise ValueError("default_prec (= %s) must be non-negative" + raise ValueError("default_prec (= %s) must be nonnegative" % default_prec) if implementation == 'poly': @@ -580,7 +586,7 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, K = base_ring names = K.variable_names() + (name,) self.__mpoly_ring = PolynomialRing(K.base_ring(), names=names) - assert is_MPolynomialRing(self.__mpoly_ring) + assert isinstance(self.__mpoly_ring, MPolynomialRing_base) self.Element = power_series_mpoly.PowerSeries_mpoly elif implementation == 'pari': from .power_series_pari import PowerSeries_pari @@ -588,9 +594,9 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, else: raise ValueError('unknown power series implementation: %r' % implementation) - ring.CommutativeRing.__init__(self, base_ring, names=name, - category=getattr(self, '_default_category', - _CommutativeRings)) + Parent.__init__(self, base=base_ring, names=name, + category=getattr(self, '_default_category', + _CommutativeRings)) Nonexact.__init__(self, default_prec) if implementation == 'pari': self.__generator = self.element_class(self, R.gen().__pari__()) @@ -711,8 +717,9 @@ def _coerce_map_from_(self, S): """ if self.base_ring().has_coerce_map_from(S): return True - if (is_PolynomialRing(S) or is_PowerSeriesRing(S)) and self.base_ring().has_coerce_map_from(S.base_ring()) \ - and self.variable_names() == S.variable_names(): + if (isinstance(S, (PolynomialRing_general, PowerSeriesRing_generic, LazyPowerSeriesRing)) + and self.base_ring().has_coerce_map_from(S.base_ring()) + and self.variable_names() == S.variable_names()): return True def _element_constructor_(self, f, prec=infinity, check=True): @@ -724,14 +731,12 @@ def _element_constructor_(self, f, prec=infinity, check=True): INPUT: + - ``f`` -- object, e.g., a power series ring element - - ``f`` -- object, e.g., a power series ring element + - ``prec`` -- (default: infinity) truncation precision for coercion - - ``prec`` -- (default: infinity); truncation precision - for coercion - - - ``check`` -- bool (default: ``True``), whether to verify - that the coefficients, etc., coerce in correctly. + - ``check`` -- boolean (default: ``True``); whether to verify + that the coefficients, etc., coerce in correctly EXAMPLES:: @@ -789,7 +794,7 @@ def _element_constructor_(self, f, prec=infinity, check=True): sage: R(ex) 1 + euler_gamma*y + (1/2*euler_gamma^2 + 1/12*pi^2)*y^2 + O(y^3) - Laurent series with non-negative valuation are accepted (see + Laurent series with nonnegative valuation are accepted (see :issue:`6431`):: sage: L. = LaurentSeriesRing(QQ) @@ -801,13 +806,13 @@ def _element_constructor_(self, f, prec=infinity, check=True): ... TypeError: self is not a power series - It is checked that the precision is non-negative + It is checked that the precision is nonnegative (see :issue:`19409`):: sage: PowerSeriesRing(ZZ, 'x')(1, prec=-5) Traceback (most recent call last): ... - ValueError: prec (= -5) must be non-negative + ValueError: prec (= -5) must be nonnegative From lazy series:: @@ -821,7 +826,7 @@ def _element_constructor_(self, f, prec=infinity, check=True): if prec is not infinity: prec = integer.Integer(prec) if prec < 0: - raise ValueError("prec (= %s) must be non-negative" % prec) + raise ValueError("prec (= %s) must be nonnegative" % prec) if isinstance(f, power_series_ring_element.PowerSeries) and f.parent() is self: if prec >= f.prec(): return f @@ -829,7 +834,7 @@ def _element_constructor_(self, f, prec=infinity, check=True): elif isinstance(f, LaurentSeries) and f.parent().power_series_ring() is self: return self(f.power_series(), prec, check=check) elif isinstance(f, MagmaElement) and str(f.Type()) == 'RngSerPowElt': - v = sage_eval(f.Eltseq()) + v = sage_eval(f.Eltseq()) # could use .sage() ? return self(v) * (self.gen(0)**f.Valuation()) elif isinstance(f, FractionFieldElement): if self.base_ring().has_coerce_map_from(f.parent()): @@ -843,7 +848,8 @@ def _element_constructor_(self, f, prec=infinity, check=True): if isinstance(f, SymbolicSeries): if str(f.default_variable()) == self.variable_name(): return self.element_class(self, f.list(), - f.degree(f.default_variable()), check=check) + f.degree(f.default_variable()), + check=check) else: raise TypeError("Can only convert series into ring with same variable name.") else: @@ -875,7 +881,6 @@ def construction(self): sage: c, S = R.construction() sage: R == c(S) True - """ from sage.categories.pushout import CompletionFunctor if self.is_sparse(): @@ -886,19 +891,19 @@ def construction(self): def _coerce_impl(self, x): """ - Return canonical coercion of x into self. + Return canonical coercion of x into ``self``. - Rings that canonically coerce to this power series ring R: + Rings that canonically coerce to this power series ring `R`: - - R itself + - `R` itself - Any power series ring in the same variable whose base ring - canonically coerces to the base ring of R. + canonically coerces to the base ring of `R` - Any ring that canonically coerces to the polynomial ring - over the base ring of R. + over the base ring of `R` - - Any ring that canonically coerces to the base ring of R + - Any ring that canonically coerces to the base ring of `R` EXAMPLES:: @@ -946,7 +951,7 @@ def _coerce_impl(self, x): """ try: P = x.parent() - if is_PowerSeriesRing(P): + if isinstance(P, (PowerSeriesRing_generic, LazyPowerSeriesRing)): if P.variable_name() == self.variable_name(): if self.has_coerce_map_from(P.base_ring()): return self(x) @@ -972,10 +977,10 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): sage: g(-1 + 3/5 * t) -1 + 3/5*t^2 - .. note:: + .. NOTE:: There are no ring homomorphisms from the ring of all formal - power series to most rings, e.g, the p-adic field, since + power series to most rings, e.g, the `p`-adic field, since you can always (mathematically!) construct some power series that doesn't converge. Note that 0 is not a *ring* homomorphism. @@ -985,7 +990,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): if base_map is None and not codomain.has_coerce_map_from(self.base_ring()): return False v = im_gens[0] - if is_PowerSeriesRing(codomain) or isinstance(codomain, LaurentSeriesRing): + if isinstance(codomain, (PowerSeriesRing_generic, LazyPowerSeriesRing, LaurentSeriesRing)): try: return v.valuation() > 0 or v.is_nilpotent() except NotImplementedError: @@ -1095,6 +1100,18 @@ def gen(self, n=0): raise IndexError("generator n>0 not defined") return self.__generator + def gens(self) -> tuple: + """ + Return the generators of this ring. + + EXAMPLES:: + + sage: R. = PowerSeriesRing(ZZ) + sage: R.gens() + (t,) + """ + return (self.__generator,) + def uniformizer(self): """ Return a uniformizer of this power series ring if it is @@ -1138,17 +1155,17 @@ def random_element(self, prec=None, *args, **kwds): INPUT: - - ``prec`` -- Integer specifying precision of output (default: - default precision of ``self``) + - ``prec`` -- integer specifying precision of output (default: + default precision of ``self``) - - ``*args``, ``**kwds`` -- Passed on to the ``random_element`` method for - the base ring + - ``*args``, ``**kwds`` -- passed on to the ``random_element`` method for + the base ring OUTPUT: - - Power series with precision ``prec`` whose coefficients are - random elements from the base ring, randomized subject to the - arguments ``*args`` and ``**kwds`` + Power series with precision ``prec`` whose coefficients are + random elements from the base ring, randomized subject to the + arguments ``*args`` and ``**kwds``. ALGORITHM: @@ -1192,7 +1209,6 @@ def random_element(self, prec=None, *args, **kwds): 1/87 - 3/70*v - 3/44*v^2 + O(v^3) sage: SR.random_element(3, max=10, min=-10) # random 2.85948321262904 - 9.73071330911226*v - 6.60414378519265*v^2 + O(v^3) - """ if prec is None: prec = self.default_prec() @@ -1356,6 +1372,7 @@ def _get_action_(self, other, op, self_is_left): return BaseRingFloorDivAction(other, self, is_left=False) return super()._get_action_(other, op, self_is_left) + class PowerSeriesRing_over_field(PowerSeriesRing_domain): _default_category = CompleteDiscreteValuationRings() diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index 8e1b76a7cc9..b1ca6ea4ab1 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -96,7 +96,7 @@ With power series the behavior is the same. # **************************************************************************** from cpython.object cimport Py_EQ, Py_NE -from sage.rings.infinity import infinity, is_Infinite +from sage.rings.infinity import infinity, InfinityElement from sage.rings.rational_field import QQ @@ -125,6 +125,9 @@ def is_PowerSeries(x): sage: R. = PowerSeriesRing(ZZ) sage: from sage.rings.power_series_ring_element import is_PowerSeries sage: is_PowerSeries(1 + x^2) + doctest:warning... + DeprecationWarning: The function is_PowerSeries is deprecated; use 'isinstance(..., PowerSeries)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. True sage: is_PowerSeries(x - x) True @@ -135,6 +138,10 @@ def is_PowerSeries(x): sage: is_PowerSeries(1 + x^2) # needs sage.symbolic False """ + from sage.misc.superseded import deprecation_cython + deprecation_cython(38266, + "The function is_PowerSeries is deprecated; " + "use 'isinstance(..., PowerSeries)' instead.") return isinstance(x, PowerSeries) @@ -164,7 +171,7 @@ cdef class PowerSeries(AlgebraElement): def __hash__(self): """ - Compute a hash of self. + Compute a hash of ``self``. EXAMPLES:: @@ -224,7 +231,7 @@ cdef class PowerSeries(AlgebraElement): sage: (1 + 2*t).is_gen() False - Note that this only returns True on the actual generator, not on + Note that this only returns ``True`` on the actual generator, not on something that happens to be equal to it. :: @@ -269,7 +276,7 @@ cdef class PowerSeries(AlgebraElement): def change_ring(self, R): """ - Change if possible the coefficients of self to lie in R. + Change if possible the coefficients of ``self`` to lie in R. EXAMPLES:: @@ -313,7 +320,7 @@ cdef class PowerSeries(AlgebraElement): cpdef _richcmp_(self, right, int op): r""" - Comparison of self and ``right``. + Comparison of ``self`` and ``right``. We say two approximate power series are equal if they agree for all coefficients up to the *minimum* of the precisions of each. @@ -403,7 +410,7 @@ cdef class PowerSeries(AlgebraElement): def coefficients(self): """ - Return the nonzero coefficients of self. + Return the nonzero coefficients of ``self``. EXAMPLES:: @@ -417,7 +424,7 @@ cdef class PowerSeries(AlgebraElement): def exponents(self): """ - Return the exponents appearing in self with nonzero coefficients. + Return the exponents appearing in ``self`` with nonzero coefficients. EXAMPLES:: @@ -479,7 +486,7 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``absprec`` -- an integer or ``None`` (default: ``None``), the + - ``absprec`` -- integer or ``None`` (default: ``None``); the absolute precision of the result. If ``None``, lifts to an exact element. @@ -491,7 +498,6 @@ cdef class PowerSeries(AlgebraElement): t + t^2 + O(t^10) sage: x.lift_to_precision() t + t^2 - """ if absprec is not None and absprec <= self.precision_absolute(): return self @@ -531,20 +537,17 @@ cdef class PowerSeries(AlgebraElement): def padded_list(self, n=None): """ - Return a list of coefficients of self up to (but not including) + Return a list of coefficients of ``self`` up to (but not including) `q^n`. - Includes 0's in the list on the right so that the list has length - `n`. + Includes 0s in the list on the right so that the list has length `n`. INPUT: - - - ``n`` -- (optional) an integer that is at least 0. If ``n`` is - not given, it will be taken to be the precision of self, - unless this is ``+Infinity``, in which case we just return - ``self.list()``. - + - ``n`` -- (optional) an integer that is at least 0. If ``n`` is + not given, it will be taken to be the precision of ``self``, + unless this is ``+Infinity``, in which case we just return + ``self.list()``. EXAMPLES:: @@ -794,7 +797,6 @@ cdef class PowerSeries(AlgebraElement): s += " + %s"%bigoh return s.lstrip(" ") - def truncate(self, prec=infinity): """ The polynomial obtained from power series by truncation. @@ -843,7 +845,7 @@ cdef class PowerSeries(AlgebraElement): `t` is the indeterminate of the power series ring. If `n` is negative return 0. If `n` is beyond the precision, raise an - IndexError. + :exc:`IndexError`. EXAMPLES:: @@ -1008,7 +1010,7 @@ cdef class PowerSeries(AlgebraElement): def valuation_zero_part(self): r""" - Factor self as `q^n \cdot (a_0 + a_1 q + \cdots)` with + Factor ``self`` as `q^n \cdot (a_0 + a_1 q + \cdots)` with `a_0` nonzero. Then this function returns `a_0 + a_1 q + \cdots` . @@ -1043,7 +1045,7 @@ cdef class PowerSeries(AlgebraElement): else: n = int(n) v = {} - for k, x in self.dict().iteritems(): + for k, x in self.monomial_coefficients().items(): if k >= n: v[k-n] = x return self._parent(v, self.prec()-n) @@ -1076,7 +1078,6 @@ cdef class PowerSeries(AlgebraElement): True sage: (1/(2*x)).parent() Laurent Series Ring in x over Rational Field - """ denom = denom_r if denom.is_zero(): @@ -1134,7 +1135,6 @@ cdef class PowerSeries(AlgebraElement): x + x^3 sage: O(x^4)^(1/2) O(x^2) - """ try: right = QQ.coerce(r) @@ -1232,8 +1232,8 @@ cdef class PowerSeries(AlgebraElement): def is_monomial(self): """ - Return ``True`` if this element is a monomial. That is, if self is - `x^n` for some non-negative integer `n`. + Return ``True`` if this element is a monomial. That is, if ``self`` is + `x^n` for some nonnegative integer `n`. EXAMPLES:: @@ -1254,20 +1254,20 @@ cdef class PowerSeries(AlgebraElement): def map_coefficients(self, f, new_base_ring=None): r""" - Return the series obtained by applying ``f`` to the non-zero + Return the series obtained by applying ``f`` to the nonzero coefficients of ``self``. If ``f`` is a :class:`sage.categories.map.Map`, then the resulting series will be defined over the codomain of ``f``. Otherwise, the - resulting polynomial will be over the same ring as self. Set + resulting polynomial will be over the same ring as ``self``. Set ``new_base_ring`` to override this behaviour. INPUT: - - ``f`` -- a callable that will be applied to the coefficients of self. + - ``f`` -- a callable that will be applied to the coefficients of ``self`` - - ``new_base_ring`` (optional) -- if given, the resulting polynomial - will be defined over this ring. + - ``new_base_ring`` -- (optional) if given, the resulting polynomial + will be defined over this ring EXAMPLES:: @@ -1396,9 +1396,7 @@ cdef class PowerSeries(AlgebraElement): 1 / (1 - A_1 t / (1 - A_2 t / (1 - A_3 t / (1 - \cdots)))) - OUTPUT: - - `A_n` for `n \geq 1` + OUTPUT: `A_n` for `n \geq 1` The expansion is done as long as possible given the precision. Whenever the expansion is not well-defined, because it would @@ -1511,22 +1509,21 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- integer (default: ``None``): if not ``None`` and the series - has infinite precision, truncates series at precision - ``prec``. + - ``prec`` -- integer (default: ``None``); if not ``None`` and the + series has infinite precision, truncates series at precision ``prec`` - - ``extend`` -- bool (default: ``False``); if ``True``, return a square - root in an extension ring, if necessary. Otherwise, raise - a :class:`ValueError` if the square root is not in the base power series + - ``extend`` -- boolean (default: ``False``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise + a :exc:`ValueError` if the square root is not in the base power series ring. For example, if ``extend`` is ``True``, the square root of a power series with odd degree leading coefficient is defined as an element of a formal extension ring. - - ``name`` -- string; if ``extend`` is ``True``, you must also specify the print - name of the formal square root. + - ``name`` -- string; if ``extend`` is ``True``, you must also + specify the print name of the formal square root - - ``all`` -- bool (default: ``False``); if ``True``, return all square - roots of ``self``, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of ``self``, instead of just one ALGORITHM: Newton's method @@ -1838,12 +1835,10 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. - - OUTPUT: + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to - A new power series. + OUTPUT: a new power series EXAMPLES: @@ -1865,7 +1860,7 @@ cdef class PowerSeries(AlgebraElement): sage: f.cos(prec=2) 1 + O(a, b)^2 - If the power series has a non-zero constant coefficient `c`, + If the power series has a nonzero constant coefficient `c`, one raises an error:: sage: g = 2+f @@ -1901,7 +1896,7 @@ cdef class PowerSeries(AlgebraElement): assert(val >= 1) prec = min(prec, self.prec()) - if is_Infinite(prec): + if isinstance(prec, InfinityElement): prec = R.default_prec() n_inv_factorial = R.base_ring().one() x_pow_n = R.one() @@ -1923,12 +1918,10 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to - OUTPUT: - - A new power series. + OUTPUT: a new power series EXAMPLES: @@ -1950,7 +1943,7 @@ cdef class PowerSeries(AlgebraElement): sage: f.sin(prec=2) a + b + O(a, b)^2 - If the power series has a non-zero constant coefficient `c`, + If the power series has a nonzero constant coefficient `c`, one raises an error:: sage: g = 2+f @@ -1987,7 +1980,7 @@ cdef class PowerSeries(AlgebraElement): x = self prec = min(prec, self.prec()) - if is_Infinite(prec): + if isinstance(prec, InfinityElement): prec = R.default_prec() n_inv_factorial = R.base_ring().one() x_pow_n = x @@ -2009,12 +2002,10 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. - - OUTPUT: + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to - A new power series. + OUTPUT: a new power series EXAMPLES: @@ -2036,7 +2027,7 @@ cdef class PowerSeries(AlgebraElement): sage: f.tan(prec=2) a + b + O(a, b)^2 - If the power series has a non-zero constant coefficient `c`, + If the power series has a nonzero constant coefficient `c`, one raises an error:: sage: g = 2 + f @@ -2073,12 +2064,10 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to - OUTPUT: - - A new power series. + OUTPUT: a new power series EXAMPLES: @@ -2100,7 +2089,7 @@ cdef class PowerSeries(AlgebraElement): sage: f.sinh(prec=2) a + b + O(a, b)^2 - If the power series has a non-zero constant coefficient `c`, + If the power series has a nonzero constant coefficient `c`, one raises an error:: sage: g = 2 + f @@ -2126,7 +2115,6 @@ cdef class PowerSeries(AlgebraElement): sage: sinh(a^2 + T.O(5)) a^2 + O(a, b)^5 - """ R = self.parent() @@ -2140,7 +2128,7 @@ cdef class PowerSeries(AlgebraElement): x = self prec = min(prec, self.prec()) - if is_Infinite(prec): + if isinstance(prec, InfinityElement): prec = R.default_prec() n_inv_factorial = R.base_ring().one() x_pow_n = x @@ -2162,12 +2150,10 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to - OUTPUT: - - A new power series. + OUTPUT: a new power series EXAMPLES: @@ -2189,7 +2175,7 @@ cdef class PowerSeries(AlgebraElement): sage: f.cosh(prec=2) 1 + O(a, b)^2 - If the power series has a non-zero constant coefficient `c`, + If the power series has a nonzero constant coefficient `c`, one raises an error:: sage: g = 2 + f @@ -2215,7 +2201,6 @@ cdef class PowerSeries(AlgebraElement): sage: cosh(a^2 + T.O(5)) 1 + 1/2*a^4 + O(a, b)^5 - """ R = self.parent() @@ -2228,7 +2213,7 @@ cdef class PowerSeries(AlgebraElement): assert(val >= 1) prec = min(prec, self.prec()) - if is_Infinite(prec): + if isinstance(prec, InfinityElement): prec = R.default_prec() n_inv_factorial = R.base_ring().one() x_pow_n = R.one() @@ -2250,12 +2235,10 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- Integer or ``infinity``. The degree to truncate - the result to. + - ``prec`` -- integer or ``infinity``; the degree to truncate + the result to - OUTPUT: - - A new power series. + OUTPUT: a new power series EXAMPLES: @@ -2277,7 +2260,7 @@ cdef class PowerSeries(AlgebraElement): sage: f.tanh(prec=2) a + b + O(a, b)^2 - If the power series has a non-zero constant coefficient `c`, + If the power series has a nonzero constant coefficient `c`, one raises an error:: sage: g = 2 + f @@ -2303,7 +2286,6 @@ cdef class PowerSeries(AlgebraElement): sage: tanh(a^2 + T.O(5)) a^2 + O(a, b)^5 - """ if not self[0].is_zero(): raise ValueError('can only apply tanh to formal power ' @@ -2328,7 +2310,7 @@ cdef class PowerSeries(AlgebraElement): sage: p.O(-5) Traceback (most recent call last): ... - ValueError: prec (= -5) must be non-negative + ValueError: prec (= -5) must be nonnegative """ if prec is infinity or prec >= self.prec(): return self @@ -2346,16 +2328,15 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``self`` -- the power series `a(t)` + - ``self`` -- the power series `a(t)` - - ``b`` -- the power series `b(t)` (default is - zero) + - ``b`` -- the power series `b(t)` (default: zero) - - ``f0`` -- the constant term of `f` ("initial - condition") (default is 1) + - ``f0`` -- the constant term of `f` ("initial condition") + (default: 1) - - ``prec`` -- desired precision of result (this will be - reduced if either a or b have less precision available) + - ``prec`` -- desired precision of result (this will be + reduced if either a or b have less precision available) OUTPUT: the power series `f`, to indicated precision @@ -2373,7 +2354,7 @@ cdef class PowerSeries(AlgebraElement): - For other coefficient rings, things are more complicated. A solution may not exist, and if it does it - may not be unique. Generally, by the time the nth term + may not be unique. Generally, by the time the `n`-th term has been computed, the algorithm will have attempted divisions by `n!` in the coefficient ring. So if your coefficient ring has enough 'precision', and if your @@ -2430,7 +2411,7 @@ cdef class PowerSeries(AlgebraElement): if prec == 0: return self._parent(0, 0) if prec < 0: - raise ValueError("prec (=%s) must be a non-negative integer" % prec) + raise ValueError("prec (=%s) must be a nonnegative integer" % prec) base_ring = self._parent.base_ring() R = PolynomialRing(base_ring, self._parent.variable_name()) @@ -2449,10 +2430,7 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - - ``prec`` -- integer; default is - ``self.parent().default_prec`` - + - ``prec`` -- integer (default: ``self.parent().default_prec``) ALGORITHM: See :meth:`.solve_linear_de`. @@ -2563,7 +2541,7 @@ cdef class PowerSeries(AlgebraElement): INPUT: - - ``prec`` -- integer; default is ``self.parent().default_prec()`` + - ``prec`` -- integer (default: ``self.parent().default_prec()``) ALGORITHM: See :meth:`solve_linear_de()`. @@ -2725,7 +2703,6 @@ cdef class PowerSeries(AlgebraElement): """ return multi_derivative(self, args) - def __setitem__(self, n, value): """ Called when an attempt is made to change a power series. @@ -2836,7 +2813,7 @@ cdef class PowerSeries(AlgebraElement): def _solve_linear_de(R, N, L, a, b, f0): r""" - Internal function used by PowerSeries.solve_linear_de(). + Internal function used by ``PowerSeries.solve_linear_de()``. INPUT: @@ -2846,29 +2823,25 @@ def _solve_linear_de(R, N, L, a, b, f0): - ``L`` -- integer >= 1 - - ``a`` -- list of coefficients of `a`, any - length, all coefficients should belong to base ring of R. - - - ``b`` -- list of coefficients of `b`, length - at least `L` (only first `L` coefficients are - used), all coefficients should belong to base ring of R. + - ``a`` -- list of coefficients of `a`, any length, all coefficients should + belong to base ring of `R` - - ``f0`` -- constant term of `f` (only used if - `N == 0`), should belong to base ring of R. + - ``b`` -- list of coefficients of `b`, length at least `L` (only first `L` + coefficients are used), all coefficients should belong to base ring of `R` + - ``f0`` -- constant term of `f` (only used if ``N == 0``), should belong + to base ring of `R` - OUTPUT: List of coefficients of `f` (length exactly - `L`), where `f` is a solution to the linear - inhomogeneous differential equation: + OUTPUT: list of coefficients of `f` (length exactly `L`), where `f` is a + solution to the linear inhomogeneous differential equation: .. MATH:: (t^N f)' = a t^N f + t^{N-1} b + O(t^{N+L-1}). - The constant term of `f` is taken to be f0 if - `N == 0`, and otherwise is determined by - `N f_0 = b_0`. + The constant term of `f` is taken to be f0 if `N == 0`, and otherwise is + determined by `N f_0 = b_0`. ALGORITHM: The algorithm implemented here is inspired by the "fast lazy multiplication algorithm" described in the paper "Lazy @@ -2942,11 +2915,11 @@ def _solve_linear_de(R, N, L, a, b, f0): g = _solve_linear_de(R, N, L2, a, b, f0) term1 = R(g) # we must not have check=False, since otherwise [..., 0, 0] is not stripped - term2 = R(a[:L]) #, check=False) + term2 = R(a[:L]) # , check=False) product = (term1 * term2).list() # todo: perhaps next loop could be made more efficient - c = b[L2 : L] + c = b[L2:L] for j in range(L2 - 1, min(L-1, len(product))): c[j - (L2-1)] = c[j - (L2-1)] + product[j] diff --git a/src/sage/rings/puiseux_series_ring.py b/src/sage/rings/puiseux_series_ring.py index d63b5bcc665..06b752f92df 100644 --- a/src/sage/rings/puiseux_series_ring.py +++ b/src/sage/rings/puiseux_series_ring.py @@ -27,16 +27,19 @@ from sage.categories.fields import Fields from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import infinity from sage.rings.laurent_series_ring import LaurentSeriesRing from sage.rings.laurent_series_ring_element import LaurentSeries -from sage.rings.power_series_ring import is_PowerSeriesRing from sage.rings.power_series_ring_element import PowerSeries from sage.rings.puiseux_series_ring_element import PuiseuxSeries from sage.structure.element import parent from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') +lazy_import('sage.rings.power_series_ring', 'PowerSeriesRing_generic') + class PuiseuxSeriesRing(UniqueRepresentation, Parent): """ @@ -204,7 +207,7 @@ def fraction_field(self): If the base ring is a field, then Puiseux series are already a field. If the base ring is a domain, then the Puiseux series over its fraction - field is returned. Otherwise, raise a :class:`ValueError`. + field is returned. Otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -340,7 +343,7 @@ def _element_constructor_(self, x, e=1, prec=infinity): def _coerce_map_from_(self, P): r""" - Return a coercion map from `P` to `self`, or `True`, or `None`. + Return a coercion map from `P` to ``self``, or ``True``, or ``None``. The following rings admit a coercion map to the Puiseux series ring `A((x-a)^(1/e))`: @@ -351,7 +354,7 @@ def _coerce_map_from_(self, P): variable `(x-a)` over a ring admitting a coercion map to `A` - any Puiseux series ring with the same center `a` and ramification - index equal to a multiple of `self`'s ramification index. For + index equal to a multiple of ``self``'s ramification index. For example, Puiseux series in (x-a)^(1/2) can be interpreted as Puiseux series in (x-a)^(1/4). @@ -379,10 +382,10 @@ def _coerce_map_from_(self, P): # Laurent series rings, power series rings, and polynomial rings with # the same variable name and the base rings are coercible - if ((isinstance(P, PuiseuxSeriesRing) or isinstance(P, LaurentSeriesRing) or - is_PowerSeriesRing(P)) and - P.variable_name() == self.variable_name() and - A.has_coerce_map_from(P.base_ring())): + if (isinstance(P, (PuiseuxSeriesRing, LaurentSeriesRing, + PowerSeriesRing_generic, LazyPowerSeriesRing)) + and P.variable_name() == self.variable_name() + and A.has_coerce_map_from(P.base_ring())): return True # # other Puiseux series rings with the same variable name and diff --git a/src/sage/rings/puiseux_series_ring_element.pyx b/src/sage/rings/puiseux_series_ring_element.pyx index 96aa6eaef6e..902ce96bd7c 100644 --- a/src/sage/rings/puiseux_series_ring_element.pyx +++ b/src/sage/rings/puiseux_series_ring_element.pyx @@ -133,12 +133,12 @@ cdef class PuiseuxSeries(AlgebraElement): - ``parent`` -- the parent ring - - ``f`` -- one of the following types of inputs: + - ``f`` -- one of the following types of inputs: * instance of :class:`PuiseuxSeries` * instance that can be coerced into the Laurent series ring of the parent - - ``e`` -- integer (default: 1) the ramification index + - ``e`` -- integer (default: 1); the ramification index EXAMPLES:: diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 73e8878150c..300d64b8279 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -124,7 +124,7 @@ sage: AA((-4)^(1/4)) Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real The coercion, however, goes in the other direction, since not all symbolic expressions are algebraic numbers:: @@ -411,7 +411,7 @@ real (has an imaginary component of exactly zero). Converting from either ``AA`` or ``QQbar`` to ``ZZ`` or ``QQ`` succeeds only if the number actually is an integer or rational. If conversion fails, a -ValueError will be raised. +:exc:`ValueError` will be raised. Here are examples of all of these conversions:: @@ -543,14 +543,14 @@ ....: (83132288614462248899077910195645998*a + 254420831388756945210526696075302411552001)*y^2) sage: lc = lc.change_ring(QQbar) sage: lc.roots(CIF) - [(-1.0005054922387982573627768714?, 2), - (-1.0000000000000000000000000000?, 2), - (-0.9999999996626050731848036720993?, 1), + [(-1.000505492239?, 2), + (-1.000000000000?, 2), + (-0.999999999662605?, 1), (0, 2), - (1.0000000000000000000000000000?, 2), - (1.0005054922387982573627768714?, 2), - (0.999999586737109168744488? + 0.?e-43*I, 1), - (0.999999999662605073184804? + 0.?e-43*I, 1)] + (1.000000000000?, 2), + (1.000505492239?, 2), + (0.999999587? + 0.?e-11*I, 1), + (0.999999999? + 0.?e-11*I, 1)] Check that issue:`37927` is fixed:: @@ -928,6 +928,14 @@ def _factor_multivariate_polynomial(self, f, proof=True): sage: AA['x','y'](1).factor() # indirect doctest 1 + Test :issue:`#33327`:: + + sage: # needs sage.libs.singular + sage: S. = QQbar[] + sage: p = a^2 + 7*c^2 + sage: factor(p) + (a + (-2.645751311064591?*I)*c) * (a + 2.645751311064591?*I*c) + """ from sage.interfaces.singular import singular from sage.structure.factorization import Factorization @@ -973,16 +981,16 @@ def _factor_multivariate_polynomial(self, f, proof=True): numfield_polynomial_flat = numfield.polynomial()(nf_gen) - polynomial_flat = sum(flat_ring({(0,)+tuple(k):1}) + polynomial_flat = sum(flat_ring({(0,) + tuple(k): 1}) * v.polynomial()(nf_gen) - for k,v in numfield_f.dict().items()) + for k, v in numfield_f.monomial_coefficients().items()) norm_flat = polynomial_flat.resultant(numfield_polynomial_flat, nf_gen) norm_f = norm_flat((0,)+norm_ring.gens()) else: norm_f = numfield_f - R = norm_f._singular_().absFactorize() + R = norm_f._singular_().absFactorize('"SAGE_ALGEBRAIC"') singular.setring(R) L = singular('absolute_factors') @@ -1149,7 +1157,7 @@ def _element_constructor_(self, x): if x.imag().is_zero(): return x.real() else: - raise ValueError("Cannot coerce algebraic number with non-zero imaginary part to algebraic real") + raise ValueError("Cannot coerce algebraic number with nonzero imaginary part to algebraic real") elif hasattr(x, '_algebraic_'): return x._algebraic_(AA) return AlgebraicReal(x) @@ -1351,11 +1359,11 @@ def ngens(self): def zeta(self, n=2): r""" Return an `n`-th root of unity in this field. This will raise a - ``ValueError`` if `n \ne \{1, 2\}` since no such root exists. + :exc:`ValueError` if `n \ne \{1, 2\}` since no such root exists. INPUT: - - ``n`` (integer) -- default 2 + - ``n`` -- integer (default: 2) EXAMPLES:: @@ -1447,7 +1455,7 @@ def random_element(self, poly_degree=2, *args, **kwds): INPUT: - - ``poly_degree`` -- default: 2; degree of the random + - ``poly_degree`` -- (default: 2) degree of the random polynomial over the integers of which the returned algebraic real number is a (real part of a) root. This is not necessarily the degree of the minimal polynomial of the @@ -1551,7 +1559,6 @@ def _factor_univariate_polynomial(self, f): (12) * (x^2 + 0.3333333333333334?) sage: AA._factor_univariate_polynomial(EllipticCurve('11a1').change_ring(AA).division_polynomial(5)) # needs sage.schemes (5) * (x - 16.00000000000000?) * (x - 5.000000000000000?) * (x - 1.959674775249769?) * (x + 2.959674775249769?) * (x^2 - 2.854101966249685?*x + 15.47213595499958?) * (x^2 + 1.909830056250526?*x + 1.660606461254312?) * (x^2 + 3.854101966249685?*x + 6.527864045000421?) * (x^2 + 13.09016994374948?*x + 93.33939353874569?) - """ rr = f.roots() cr = [(r, e) for r, e in f.roots(QQbar) if r.imag() > 0] @@ -1681,7 +1688,7 @@ def _element_constructor_(self, x): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -1850,11 +1857,11 @@ def ngens(self): @cached_method def zeta(self, n=4): r""" - Return a primitive `n`'th root of unity, specifically `\exp(2*\pi*i/n)`. + Return a primitive `n`-th root of unity, specifically `\exp(2*\pi*i/n)`. INPUT: - - ``n`` (integer) -- default 4 + - ``n`` -- integer (default: 4) EXAMPLES:: @@ -1933,7 +1940,7 @@ def random_element(self, poly_degree=2, *args, **kwds): INPUT: - - ``poly_degree`` -- default: 2; degree of the random polynomial over + - ``poly_degree`` -- (default: 2) degree of the random polynomial over the integers of which the returned algebraic number is a root. This is not necessarily the degree of the minimal polynomial of the number. Increase this parameter to achieve a greater diversity of @@ -2110,7 +2117,6 @@ def _factor_univariate_polynomial(self, f): -1 sage: QQbar._factor_univariate_polynomial(EllipticCurve('11a1').change_ring(QQbar).division_polynomial(5)) # needs sage.schemes (5) * (x - 16) * (x - 5) * (x - 1.959674775249769?) * (x - 1.427050983124843? - 3.665468789467727?*I) * (x - 1.427050983124843? + 3.665468789467727?*I) * (x + 0.9549150281252629? - 0.8652998037182486?*I) * (x + 0.9549150281252629? + 0.8652998037182486?*I) * (x + 1.927050983124843? - 1.677599044300515?*I) * (x + 1.927050983124843? + 1.677599044300515?*I) * (x + 2.959674775249769?) * (x + 6.545084971874737? - 7.106423590645660?*I) * (x + 6.545084971874737? + 7.106423590645660?*I) - """ from sage.structure.factorization import Factorization return Factorization([(f.parent()([-r, 1]), e) for r, e in f.roots()], @@ -2202,9 +2208,9 @@ def tail_prec_seq(): def rational_exact_root(r, d): r""" - Check whether the rational `r` is an exact `d`'th power. + Check whether the rational `r` is an exact `d`-th power. - If so, this returns the `d`'th root of `r`; otherwise, this returns ``None``. + If so, this returns the `d`-th root of `r`; otherwise, this returns ``None``. EXAMPLES:: @@ -2336,7 +2342,7 @@ def do_polred(poly, threshold=32): INPUT: - ``poly`` -- a monic irreducible polynomial with integer coefficients - - ``threshold`` -- an integer used to decide whether to run ``polredbest`` + - ``threshold`` -- integer used to decide whether to run ``polredbest`` OUTPUT: @@ -2544,17 +2550,17 @@ def number_field_elements_from_algebraics(numbers, minimal=False, - ``numbers`` -- a number or list of numbers - - ``minimal`` -- Boolean (default: ``False``). Whether to minimize the + - ``minimal`` -- boolean (default: ``False``); whether to minimize the degree of the extension - - ``same_field`` -- Boolean (default: ``False``). See below + - ``same_field`` -- boolean (default: ``False``); see below - - ``embedded`` -- Boolean (default: ``False``). Whether to make the + - ``embedded`` -- boolean (default: ``False``); whether to make the NumberField embedded - ``name`` -- string (default: ``'a'``); name of the primitive element - - ``prec`` -- integer (default: ``53``). The number of bit of precision + - ``prec`` -- integer (default: 53); the number of bit of precision to guarantee finding real roots OUTPUT: @@ -2835,6 +2841,18 @@ def number_field_elements_from_algebraics(numbers, minimal=False, sage: res[0] Number Field in a with defining polynomial y^24 - 107010*y^22 - 24*y^21 + ... + 250678447193040618624307096815048024318853254384 with a = 93.32530798172420? + + Test that the semantic of ``AA`` constructor does not affect this function (:issue:`36735`):: + + sage: AA((-1)^(2/3)) + 1 + sage: number_field_elements_from_algebraics([(-1)^(2/3)]) + (Cyclotomic Field of order 6 and degree 2, + [zeta6 - 1], + Ring morphism: + From: Cyclotomic Field of order 6 and degree 2 + To: Algebraic Field + Defn: zeta6 |--> 0.500000000000000? + 0.866025403784439?*I) """ gen = qq_generator @@ -2856,15 +2874,10 @@ def mk_algebraic(x): return x return QQbar(x) - # Try to cast into AA - try: - aa_numbers = [AA(_) for _ in numbers] - numbers = aa_numbers - real_case = True - except (ValueError, TypeError): - real_case = False - # Make the numbers algebraic numbers = [mk_algebraic(_) for _ in numbers] + real_case = all(x in AA for x in numbers) + if real_case: + numbers = [AA(x) for x in numbers] # Make the numbers have a real exact underlying field real_numbers = [] @@ -2934,14 +2947,14 @@ def cmp_elements_with_same_minpoly(a, b, p): INPUT: - - ``a`` and ``b`` -- elements of the algebraic or the real algebraic field + - ``a``, ``b`` -- elements of the algebraic or the real algebraic field with same minimal polynomial - ``p`` -- the minimal polynomial OUTPUT: - `-1`, `0`, `1`, `None` depending on whether `a < b`, `a = b` or `a > b` or + `-1`, `0`, `1`, ``None`` depending on whether `a < b`, `a = b` or `a > b` or the function did not succeed with the given precision of `a` and `b`. EXAMPLES:: @@ -3101,7 +3114,7 @@ def __reduce__(self): def __hash__(self): r""" - Return a hash value for self. This will depend on the order that + Return a hash value for ``self``. This will depend on the order that commands get executed at load time, so we do not test the value that is returned, just that it does not raise an error. @@ -3158,7 +3171,7 @@ def is_complex(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -3183,7 +3196,7 @@ def _repr_(self): def root_as_algebraic(self): r""" - Return the root attached to self as an algebraic number. + Return the root attached to ``self`` as an algebraic number. EXAMPLES:: @@ -3209,7 +3222,7 @@ def is_trivial(self): def field(self): r""" - Return the number field attached to self. + Return the number field attached to ``self``. EXAMPLES:: @@ -3429,7 +3442,6 @@ def super_poly(self, super, checked=None): -a^3 + 3*a sage: gen3.super_poly(gen2_3) a^2 - 2 - """ if checked is None: checked = {} @@ -3450,7 +3462,7 @@ def super_poly(self, super, checked=None): def __call__(self, elt): """ - Takes an algebraic number which is represented as either a + Take an algebraic number which is represented as either a rational or a number field element, and which is in a subfield of the field generated by this generator. Lifts the number into the field of this generator, and returns either a @@ -3514,7 +3526,7 @@ def is_simple(self): Check whether this descriptor represents a value with the same algebraic degree as the number field associated with the descriptor. - This returns ``True`` if self is an ``ANRational``, or a minimal + This returns ``True`` if ``self`` is an ``ANRational``, or a minimal ``ANExtensionElement``. EXAMPLES:: @@ -3544,7 +3556,7 @@ def is_simple(self): def neg(self, n): r""" - Negation of self. + Negation of ``self``. EXAMPLES:: @@ -3570,7 +3582,7 @@ def invert(self, n): def abs(self, n): r""" - Absolute value of self. + Absolute value of ``self``. EXAMPLES:: @@ -3583,7 +3595,7 @@ def abs(self, n): def real(self, n): r""" - Real part of self. + Real part of ``self``. EXAMPLES:: @@ -3599,7 +3611,7 @@ def real(self, n): def imag(self, n): r""" - Imaginary part of self. + Imaginary part of ``self``. EXAMPLES:: @@ -3615,7 +3627,7 @@ def imag(self, n): def conjugate(self, n): r""" - Complex conjugate of self. + Complex conjugate of ``self``. EXAMPLES:: @@ -3631,8 +3643,8 @@ def conjugate(self, n): def norm(self, n): r""" - Field norm of self from `\overline{\QQ}` to its real subfield - `\mathbf{A}`, i.e.~the square of the usual complex absolute value. + Field norm of ``self`` from `\overline{\QQ}` to its real subfield + `\mathbf{A}`, i.e. the square of the usual complex absolute value. EXAMPLES:: @@ -4018,7 +4030,6 @@ def __hash__(self): sage: h2 = hash(QQbar(1/2^100)) sage: hash(h1) == hash(h2) True - """ # The only way I can think of to hash algebraic numbers without @@ -4195,7 +4206,7 @@ def is_square(self): (boolean) ``True`` in all cases for elements of ``QQbar``; - ``True`` for non-negative elements of ``AA``; + ``True`` for nonnegative elements of ``AA``; otherwise ``False`` EXAMPLES:: @@ -4233,13 +4244,13 @@ def sqrt(self, all=False, extend=True): INPUT: - - ``extend`` -- bool (default: ``True``); ignored if self is in QQbar, or - positive in AA. If self is negative in AA, do the following: if True, - return a square root of self in QQbar, otherwise raise a ValueError. + - ``extend`` -- boolean (default: ``True``); ignored if ``self`` is in QQbar, or + positive in AA. If ``self`` is negative in AA, do the following: if True, + return a square root of ``self`` in QQbar, otherwise raise a :exc:`ValueError`. - - ``all`` -- bool (default: ``False``); if True, return a list of all square - roots. If False, return just one square root, or raise an ValueError - if self is a negative element of AA and extend=False. + - ``all`` -- boolean (default: ``False``); if ``True``, return a list of all square + roots. If ``False``, return just one square root, or raise an :exc:`ValueError` + if ``self`` is a negative element of AA and extend=False. OUTPUT: @@ -4314,12 +4325,12 @@ def nth_root(self, n, all=False): INPUT: - - ``all`` -- bool (default: ``False``). If ``True``, return a list of - all `n`-th roots as complex algebraic numbers. + - ``all`` -- boolean (default: ``False``); if ``True``, return a list of + all `n`-th roots as complex algebraic numbers .. WARNING:: - Note that for odd `n`, all=`False` and negative real numbers, + Note that for odd `n`, all ``False`` and negative real numbers, ``AlgebraicReal`` and ``AlgebraicNumber`` values give different answers: ``AlgebraicReal`` values prefer real results, and ``AlgebraicNumber`` values return the principal root. @@ -4375,14 +4386,14 @@ def as_number_field_element(self, minimal=False, embedded=False, prec=53): INPUT: - - ``minimal`` -- Boolean (default: ``False``). Whether to minimize the - degree of the extension. + - ``minimal`` -- boolean (default: ``False``); whether to minimize the + degree of the extension - - ``embedded`` -- Boolean (default: ``False``). Whether to make the - NumberField embedded. + - ``embedded`` -- boolean (default: ``False``); whether to make the + NumberField embedded - - ``prec`` -- integer (default: ``53``). The number of bit of precision - to guarantee finding real roots. + - ``prec`` -- integer (default: 53); the number of bit of precision + to guarantee finding real roots This may not return the smallest such number field, unless ``minimal=True`` is specified. @@ -4481,6 +4492,26 @@ def as_number_field_element(self, minimal=False, embedded=False, prec=53): """ return number_field_elements_from_algebraics(self, minimal=minimal, embedded=embedded, prec=prec) + def is_integral(self): + r""" + Check if this number is an algebraic integer. + + EXAMPLES:: + + sage: QQbar(sqrt(-23)).is_integral() + True + sage: AA(sqrt(23/2)).is_integral() + False + + TESTS: + + Method should return the same value as :meth:`NumberFieldElement.is_integral`:: + + sage: for a in [QQbar(2^(1/3)), AA(2^(1/3)), QQbar(sqrt(1/2)), AA(1/2), AA(2), QQbar(1/2)]: + ....: assert a.as_number_field_element()[1].is_integral() == a.is_integral() + """ + return all(a in ZZ for a in self.minpoly()) + def exactify(self): """ Compute an exact representation for this number. @@ -4684,7 +4715,7 @@ def interval_fast(self, field): def interval_diameter(self, diam): """ - Compute an interval representation of self with ``diameter()`` at + Compute an interval representation of ``self`` with ``diameter()`` at most ``diam``. The precision of the returned value is unpredictable. EXAMPLES:: @@ -4709,7 +4740,7 @@ def interval_diameter(self, diam): def interval(self, field): r""" Given an interval (or ball) field (real or complex, as appropriate) of - precision `p`, compute an interval representation of self with + precision `p`, compute an interval representation of ``self`` with ``diameter()`` at most `2^{-p}`; then round that representation into the given field. Here ``diameter()`` is relative diameter for intervals not containing 0, and absolute diameter for @@ -4968,7 +4999,7 @@ def _richcmp_(self, other, op): slower because the algorithm needs to check the equality of the real parts:: - sage: sorted(p2.roots(QQbar,False)) # long time - 3 secs + sage: sorted(p2.roots(QQbar,False)) # long time (3s) [1.000000000000000? - 4.016778562562223?*I, 1.000000000000000? - 3.850538755978243?*I, 1.000000000000000? - 3.390564396412898?*I, @@ -5084,9 +5115,9 @@ def _richcmp_(self, other, op): def _mpfr_(self, field): r""" - Given a ``RealField``, compute a good approximation to self in - that field. Works only if the imaginary component of self is - exactly zero; otherwise it raises a ``ValueError``. + Given a ``RealField``, compute a good approximation to ``self`` in + that field. Works only if the imaginary component of ``self`` is + exactly zero; otherwise it raises a :exc:`ValueError`. EXAMPLES:: @@ -5097,15 +5128,15 @@ def _mpfr_(self, field): sage: QQbar.zeta(3)._mpfr_(RR) Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real """ return AA(self)._mpfr_(field) def __float__(self): r""" - Compute a good float approximation to self. Works only if the - imaginary component of self is exactly zero; otherwise it - raises a ``ValueError``. + Compute a good float approximation to ``self``. Works only if the + imaginary component of ``self`` is exactly zero; otherwise it + raises a :exc:`ValueError`. EXAMPLES:: @@ -5116,13 +5147,13 @@ def __float__(self): sage: float(QQbar.zeta(3)) Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real """ return AA(self).__float__() def __complex__(self): r""" - Compute a good complex approximation to self. + Compute a good complex approximation to ``self``. EXAMPLES:: @@ -5135,7 +5166,7 @@ def __complex__(self): def _complex_double_(self, cdf): r""" - Compute a good approximation to self in CDF. + Compute a good approximation to ``self`` in CDF. EXAMPLES:: @@ -5159,7 +5190,7 @@ def _interval_fast(self, prec): def _integer_(self, ZZ=None): """ - Return self as an Integer. + Return ``self`` as an Integer. EXAMPLES:: @@ -5170,7 +5201,7 @@ def _integer_(self, ZZ=None): sage: QQbar.zeta(6)._integer_() Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real sage: # needs sage.symbolic sage: QQbar(sqrt(17))._integer_() @@ -5188,7 +5219,7 @@ def _integer_(self, ZZ=None): def _rational_(self): """ - Return self as a Rational. + Return ``self`` as a Rational. EXAMPLES:: @@ -5199,7 +5230,7 @@ def _rational_(self): sage: (QQbar.zeta(7)^3)._rational_() Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real sage: # needs sage.symbolic sage: QQbar(sqrt(2))._rational_() @@ -5300,7 +5331,7 @@ def interval_exact(self, field): def _complex_mpfr_field_(self, field): r""" - Compute an approximation to self in the given field, which must + Compute an approximation to ``self`` in the given field, which must be a complex field. EXAMPLES:: @@ -5639,7 +5670,7 @@ def _richcmp_(self, other, op): def _integer_(self, Z=None): """ - Return self as an Integer. + Return ``self`` as an Integer. EXAMPLES:: @@ -5775,7 +5806,7 @@ def trunc(self): def _rational_(self): """ - Return self as a Rational. + Return ``self`` as a Rational. EXAMPLES:: @@ -6026,7 +6057,8 @@ def sign(self): def _interval_fast(self, prec): r""" - Compute an approximation to this ``AlgebraicReal`` object in a real interval field of precision prec. + Compute an approximation to this ``AlgebraicReal`` object in a real + interval field of precision ``prec``. EXAMPLES:: @@ -6074,7 +6106,6 @@ def interval_exact(self, field): sage: from sage.rings.qqbar import QQbar_hash_offset sage: len([(r[0] + QQbar_hash_offset).interval_exact(CIF) for r in roots]) 7 - """ for extra in (0, 40): target = RR(1.0) >> (field.prec() + extra) @@ -6163,7 +6194,7 @@ def real_number(self, field): def __float__(self): r""" - Compute a good float approximation to self. + Compute a good float approximation to ``self``. EXAMPLES:: @@ -6295,14 +6326,14 @@ class AlgebraicNumberPowQQAction(Action): - ``G`` -- must be ``QQ`` - - ``S`` -- the parent on which to act, either ``AA`` or ``QQbar``. + - ``S`` -- the parent on which to act, either ``AA`` or ``QQbar`` .. NOTE:: - To compute ``x ^ (a/b)``, we take the `b`'th root of `x`; then - we take that to the `a`'th power. If `x` is a negative algebraic - real and `b` is odd, take the real `b`'th root; otherwise take - the principal `b`'th root. + To compute ``x ^ (a/b)``, we take the `b`-th root of `x`; then + we take that to the `a`-th power. If `x` is a negative algebraic + real and `b` is odd, take the real `b`-th root; otherwise take + the principal `b`-th root. EXAMPLES: @@ -6460,7 +6491,7 @@ def _act_(self, e, x): if prec is None: # We know that x.real() < 0, since x._value # crosses the negative real line and x._value - # is known to be non-zero. + # is known to be nonzero. isgn = x.imag().sign() val = x._value argument = val.argument() @@ -6549,7 +6580,7 @@ def __reduce__(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -6589,7 +6620,8 @@ def handle_sage_input(self, sib, coerce, is_qqbar): def _interval_fast(self, prec): r""" - Return an approximation to self in a real interval field of precision prec. + Return an approximation to ``self`` in a real interval field of + precision ``prec``. EXAMPLES:: @@ -6612,7 +6644,7 @@ def generator(self): def is_complex(self): r""" - Return ``False``, since rational numbers are real + Return ``False``, since rational numbers are real. EXAMPLES:: @@ -6635,7 +6667,7 @@ def exactify(self): def is_simple(self): """ - Checks whether this descriptor represents a value with the same + Check whether this descriptor represents a value with the same algebraic degree as the number field associated with the descriptor. This is always true for rational numbers. @@ -6701,7 +6733,7 @@ def abs(self, n): def rational_argument(self, n): r""" - Return the argument of self divided by `2 \pi`, or ``None`` if this + Return the argument of ``self`` divided by `2 \pi`, or ``None`` if this element is 0. EXAMPLES:: @@ -6907,7 +6939,7 @@ def _sage_input_(self, sib, coerce): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -7097,7 +7129,7 @@ def __reduce__(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -7177,7 +7209,7 @@ def handle_sage_input(self, sib, coerce, is_qqbar): def is_complex(self): r""" Whether this is a root in `\overline{\QQ}` (rather than `\mathbf{A}`). - Note that this may return True even if the root is actually real, as + Note that this may return ``True`` even if the root is actually real, as the second example shows; it does *not* trigger exact computation to see if the root is real. @@ -7216,7 +7248,7 @@ def conjugate(self, n): def refine_interval(self, interval, prec): r""" - Takes an interval which is assumed to enclose exactly one root + Take an interval which is assumed to enclose exactly one root of the polynomial (or, with multiplicity=`k`, exactly one root of the `k-1`-st derivative); and a precision, in bits. @@ -7247,7 +7279,7 @@ def refine_interval(self, interval, prec): def _real_refine_interval(self, interval, prec): r""" - Does the calculation for ``refine_interval``. + Do the calculation for ``refine_interval``. EXAMPLES:: @@ -7389,7 +7421,7 @@ def _real_refine_interval(self, interval, prec): def _complex_refine_interval(self, interval, prec): r""" - Takes an interval which is assumed to enclose exactly one root + Take an interval which is assumed to enclose exactly one root of the polynomial (or, with multiplicity=`k`, exactly one root of the `k-1`-st derivative); and a precision, in bits. @@ -7981,8 +8013,8 @@ def simplify(self, n): INPUT: - - ``n`` -- The element of ``AA`` or ``QQbar`` corresponding - to this descriptor. + - ``n`` -- the element of ``AA`` or ``QQbar`` corresponding + to this descriptor EXAMPLES:: @@ -8103,7 +8135,6 @@ def conjugate(self, n): sage: (b.conjugate("random").generator() == c.generator() # needs sage.symbolic ....: and b.conjugate("random").field_element_value() == c.field_element_value()) True - """ if self._exactly_real: return self @@ -8115,7 +8146,7 @@ def conjugate(self, n): def norm(self, n): r""" - Norm of ``self`` (square of complex absolute value) + Norm of ``self`` (square of complex absolute value). EXAMPLES:: @@ -8620,7 +8651,8 @@ def is_complex(self): def _interval_fast(self, prec): r""" - Calculate an approximation to self in an interval field of precision prec. + Calculate an approximation to ``self`` in an interval field of + precision ``prec``. EXAMPLES:: diff --git a/src/sage/rings/qqbar_decorators.py b/src/sage/rings/qqbar_decorators.py index 13d6d562824..7343a0b9b08 100644 --- a/src/sage/rings/qqbar_decorators.py +++ b/src/sage/rings/qqbar_decorators.py @@ -86,13 +86,13 @@ def wrapper(*args, **kwds): from sage.misc.flatten import flatten from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.multi_polynomial import MPolynomial - from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence, is_PolynomialSequence + from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence, PolynomialSequence_generic from sage.rings.ideal import Ideal, Ideal_generic from sage.rings.abc import AlgebraicField_common if not any(isinstance(a, (Polynomial, MPolynomial, Ideal_generic)) and isinstance(a.base_ring(), AlgebraicField_common) - or is_PolynomialSequence(a) + or isinstance(a, PolynomialSequence_generic) and isinstance(a.ring().base_ring(), AlgebraicField_common) for a in args): return func(*args, **kwds) @@ -123,7 +123,7 @@ def forward_map(item): return item.map_coefficients(elem_dict.__getitem__, new_base_ring=numfield) elif isinstance(item, MPolynomial): return item.map_coefficients(elem_dict.__getitem__, new_base_ring=numfield) - elif is_PolynomialSequence(item): + elif isinstance(item, PolynomialSequence_generic): return PolynomialSequence(map(forward_map, item), immutable=item.is_immutable()) elif isinstance(item, list): @@ -144,7 +144,7 @@ def reverse_map(item): return item.map_coefficients(morphism) elif isinstance(item, MPolynomial): return item.map_coefficients(morphism) - elif is_PolynomialSequence(item): + elif isinstance(item, PolynomialSequence_generic): return PolynomialSequence(map(reverse_map, item), immutable=item.is_immutable()) elif isinstance(item, list): diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 468f81115b7..4cf3979265f 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -130,7 +130,7 @@ def QuotientRing(R, I, names=None, **kwds): r""" - Creates a quotient ring of the ring `R` by the twosided ideal `I`. + Create a quotient ring of the ring `R` by the twosided ideal `I`. Variables are labeled by ``names`` (if the quotient ring is a quotient of a polynomial ring). If ``names`` isn't given, 'bar' will be appended @@ -138,15 +138,15 @@ def QuotientRing(R, I, names=None, **kwds): INPUT: - - ``R`` -- a ring. + - ``R`` -- a ring - - ``I`` -- a twosided ideal of `R`. + - ``I`` -- a twosided ideal of `R` - ``names`` -- (optional) a list of strings to be used as names for - the variables in the quotient ring `R/I`. + the variables in the quotient ring `R/I` - further named arguments that will be passed to the constructor - of the quotient ring instance. + of the quotient ring instance OUTPUT: `R/I` - the quotient ring `R` mod the ideal `I` @@ -342,7 +342,7 @@ def QuotientRing(R, I, names=None, **kwds): def is_QuotientRing(x): """ - Tests whether or not ``x`` inherits from :class:`QuotientRing_nc`. + Test whether or not ``x`` inherits from :class:`QuotientRing_nc`. EXAMPLES:: @@ -351,6 +351,10 @@ def is_QuotientRing(x): sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: S = R.quotient_ring(I) sage: is_QuotientRing(S) + doctest:warning... + DeprecationWarning: The function is_QuotientRing is deprecated; + use 'isinstance(..., QuotientRing_nc)' instead. + See https://github.com/sagemath/sage/issues/38266 for details. True sage: is_QuotientRing(R) False @@ -366,6 +370,10 @@ def is_QuotientRing(x): sage: is_QuotientRing(F) False """ + from sage.misc.superseded import deprecation + deprecation(38266, + "The function is_QuotientRing is deprecated; " + "use 'isinstance(..., QuotientRing_nc)' instead.") return isinstance(x, QuotientRing_nc) @@ -455,11 +463,11 @@ def __init__(self, R, I, names, category=None): INPUT: - - ``R`` -- a ring. + - ``R`` -- a ring - - ``I`` -- a twosided ideal of `R`. + - ``I`` -- a twosided ideal of `R` - - ``names`` -- a list of generator names. + - ``names`` -- list of generator names EXAMPLES:: @@ -474,7 +482,6 @@ def __init__(self, R, I, names, category=None): -b*c sage: a^3 -b*c*a - b*c*b - b*c*c - """ if R not in _Rings: raise TypeError("The first argument must be a ring, but %s is not" % R) @@ -511,7 +518,7 @@ def __init__(self, R, I, names, category=None): def construction(self): """ - Returns the functorial construction of ``self``. + Return the functorial construction of ``self``. EXAMPLES:: @@ -591,7 +598,7 @@ def is_commutative(self): This is certainly the case if the cover ring is commutative. Otherwise, if this ring has a finite number of generators, it is tested whether they commute. If the number of generators is - infinite, a ``NotImplementedError`` is raised. + infinite, a :exc:`NotImplementedError` is raised. AUTHOR: @@ -623,7 +630,6 @@ def is_commutative(self): sage: R = F.quo(J) sage: R.is_commutative() True - """ try: if self.__R.is_commutative(): @@ -747,7 +753,6 @@ def lifting_map(self): To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5 Defn: Choice of lifting map - """ try: return self.__lift @@ -783,7 +788,6 @@ def lift(self, x=None): Defn: Choice of lifting map sage: S.lift(S.0) == x # needs sage.libs.singular True - """ if x is None: return self.lifting_map() @@ -795,11 +799,9 @@ def retract(self,x): INPUT: - - ``x`` -- An element of the cover ring - - OUTPUT: + - ``x`` -- an element of the cover ring - The image of the given element in ``self``. + OUTPUT: the image of the given element in ``self`` EXAMPLES:: @@ -807,7 +809,6 @@ def retract(self,x): sage: S = R.quotient(x^2 + y^2) sage: S.retract((x+y)^2) # needs sage.libs.singular 2*xbar*ybar - """ return self.cover()(x) @@ -831,7 +832,7 @@ def characteristic(self): def defining_ideal(self): r""" - Returns the ideal generating this quotient ring. + Return the ideal generating this quotient ring. EXAMPLES: @@ -859,7 +860,7 @@ def defining_ideal(self): @cached_method def is_field(self, proof=True): r""" - Returns ``True`` if the quotient ring is a field. Checks to see if the + Return ``True`` if the quotient ring is a field. Checks to see if the defining ideal is maximal. TESTS:: @@ -889,9 +890,9 @@ def is_field(self, proof=True): def is_integral_domain(self, proof=True): r""" With ``proof`` equal to ``True`` (the default), this function may - raise a ``NotImplementedError``. + raise a :exc:`NotImplementedError`. - When ``proof`` is ``False``, if ``True`` is returned, then self is + When ``proof`` is ``False``, if ``True`` is returned, then ``self`` is definitely an integral domain. If the function returns ``False``, then either ``self`` is not an integral domain or it was unable to determine whether or not ``self`` is an integral domain. @@ -960,7 +961,7 @@ def is_noetherian(self): def cover_ring(self): r""" - Returns the cover ring of the quotient ring: that is, the original + Return the cover ring of the quotient ring: that is, the original ring `R` from which we modded out an ideal, `I`. EXAMPLES:: @@ -1177,7 +1178,7 @@ def __richcmp__(self, other, op): def ngens(self): r""" - Returns the number of generators for this quotient ring. + Return the number of generators for this quotient ring. .. TODO:: @@ -1216,7 +1217,7 @@ def ngens(self): def gen(self, i=0): r""" - Returns the `i`-th generator for this quotient ring. + Return the `i`-th generator for this quotient ring. EXAMPLES:: @@ -1247,7 +1248,7 @@ def gen(self, i=0): def _singular_(self, singular=None): """ - Returns the Singular quotient ring of ``self`` if the base ring is + Return the Singular quotient ring of ``self`` if the base ring is coercible to Singular. If a valid Singular representation is found it is used otherwise a @@ -1255,8 +1256,8 @@ def _singular_(self, singular=None): INPUT: - - ``singular`` -- Singular instance (default: the - default Singular instance) + - ``singular`` -- Singular instance (default: the + default Singular instance) .. NOTE:: @@ -1291,7 +1292,7 @@ def _singular_(self, singular=None): def _singular_init_(self, singular=None): """ - Returns a newly created Singular quotient ring matching ``self`` if + Return a newly created Singular quotient ring matching ``self`` if the base ring is coercible to Singular. See ``_singular_`` @@ -1319,7 +1320,7 @@ def _magma_init_(self, magma): INPUT: - - ``magma`` -- a Magma instance + - ``magma`` -- a Magma instance EXAMPLES:: @@ -1380,7 +1381,7 @@ def random_element(self): class QuotientRing_generic(QuotientRing_nc, ring.CommutativeRing): r""" - Creates a quotient ring of a *commutative* ring `R` by the ideal `I`. + Create a quotient ring of a *commutative* ring `R` by the ideal `I`. EXAMPLES:: @@ -1397,11 +1398,11 @@ def __init__(self, R, I, names, category=None): INPUT: - - ``R`` -- a ring that is a :class:`~sage.rings.ring.CommutativeRing`. + - ``R`` -- a ring that is a :class:`~sage.rings.ring.CommutativeRing` - - ``I`` -- an ideal of `R`. + - ``I`` -- an ideal of `R` - - ``names`` -- a list of generator names. + - ``names`` -- list of generator names TESTS:: @@ -1466,7 +1467,6 @@ def _macaulay2_init_(self, macaulay2=None): --------------------- 2 2 (x + 3x + 4, x + 1) - """ if macaulay2 is None: from sage.interfaces.macaulay2 import macaulay2 as m2_default @@ -1474,10 +1474,14 @@ def _macaulay2_init_(self, macaulay2=None): I = self.defining_ideal()._macaulay2_(macaulay2) return I.ring()._operator('/', I) - def _ideal_class_(self, num_gens): + def _ideal_class_(self, n=0): r""" Use a specialized class for quotient ring ideals. + INPUT: + + - ``n`` -- integer (default: ``0``); the number of generators + EXAMPLES:: sage: type(Zmod(14).ideal(2)) @@ -1487,10 +1491,11 @@ def _ideal_class_(self, num_gens): sage: type(Zmod(14).ideal([2,7])) """ - if num_gens == 1: + if n == 1: return QuotientRingIdeal_principal return QuotientRingIdeal_generic + class QuotientRingIdeal_generic(ideal.Ideal_generic): r""" Specialized class for quotient-ring ideals. diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 9572de38f10..6699ae9f74b 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -37,7 +37,7 @@ class QuotientRingElement(RingElement): - ``rep`` -- a representative of the element in `R`; this is used as the internal representation of the element - - ``reduce`` -- bool (default: ``True``) -- if True, then the + - ``reduce`` -- boolean (default: ``True``); if ``True``, then the internal representation of the element is ``rep`` reduced modulo the ideal `I` @@ -121,7 +121,7 @@ def _reduce_(self): def lift(self): """ - If self is an element of `R/I`, then return self as an + If ``self`` is an element of `R/I`, then return ``self`` as an element of `R`. EXAMPLES:: @@ -137,7 +137,7 @@ def lift(self): def __bool__(self): """ - Return ``True`` if quotient ring element is non-zero in the + Return ``True`` if quotient ring element is nonzero in the quotient ring `R/I`, by determining whether the element is in `I`. @@ -159,7 +159,7 @@ def __bool__(self): def is_unit(self): """ - Return ``True`` if self is a unit in the quotient ring. + Return ``True`` if ``self`` is a unit in the quotient ring. EXAMPLES:: @@ -209,7 +209,6 @@ def _repr_(self): sage: Q = S.quo(I) sage: Q.0 Sq(1) - """ from sage.structure.parent_gens import localvars P = self.parent() @@ -462,7 +461,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None): - ``codomain`` -- a ring - - ``im_gens`` -- a tuple of elements `f(x)` in ``codomain``, + - ``im_gens`` -- tuple of elements `f(x)` in ``codomain``, one for each `x` in ``self.parent().gens()``, that define a homomorphism `f` from ``self.parent()`` to ``codomain`` @@ -493,7 +492,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None): def __int__(self): """ - Try to convert self (an element of `R/I`) to an integer by + Try to convert ``self`` (an element of `R/I`) to an integer by converting its lift in `R` to an integer. Return a TypeError if no such conversion can be found. @@ -725,7 +724,6 @@ def lm(self): sage: (a+3*a*b+b).lm() # needs sage.libs.singular a*b - """ return self.__class__(self.parent(), self.__rep.lm()) @@ -783,9 +781,7 @@ def monomials(self): """ Return the monomials in ``self``. - OUTPUT: - - A list of monomials. + OUTPUT: list of monomials EXAMPLES:: @@ -803,12 +799,11 @@ def monomials(self): def _singular_(self, singular=None): """ - Return Singular representation of self. + Return Singular representation of ``self``. INPUT: - - ``singular`` -- a non-standard interpreter may be - provided + - ``singular`` -- a non-standard interpreter may be provided EXAMPLES:: @@ -851,7 +846,7 @@ def _singular_(self, singular=None): def _magma_init_(self, magma): """ - Returns the Magma representation of this quotient ring element. + Return the Magma representation of this quotient ring element. EXAMPLES:: @@ -943,7 +938,7 @@ def reduce(self, G): INPUT: - - ``G`` -- a list of quotient ring elements + - ``G`` -- list of quotient ring elements .. WARNING:: diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 819a85dbc35..272650abeef 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -82,6 +82,7 @@ from sage.structure.richcmp cimport rich_to_bool_sgn RealNumber_classes = () + def _register_real_number_class(cls): r""" Register ``cls``. @@ -199,12 +200,10 @@ cpdef Integer integer_rational_power(Integer a, Rational b): INPUT: - - a -- an ``Integer`` - - b -- a nonnegative ``Rational`` - - OUTPUT: + - ``a`` -- an ``Integer`` + - ``b`` -- a nonnegative ``Rational`` - `a^b` as an ``Integer`` or ``None`` + OUTPUT: `a^b` as an ``Integer`` or ``None`` EXAMPLES:: @@ -518,9 +517,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``x`` -- object (default: ``None``) + - ``x`` -- object (default: ``None``) - - ``base`` -- base if ``x`` is a string + - ``base`` -- base if ``x`` is a string EXAMPLES:: @@ -707,9 +706,7 @@ cdef class Rational(sage.structure.element.FieldElement): Return a list with the rational element in it, to be compatible with the method for number fields. - OUTPUT: - - - ``list`` -- the list ``[self]`` + OUTPUT: the list ``[self]`` EXAMPLES:: @@ -719,14 +716,14 @@ cdef class Rational(sage.structure.element.FieldElement): """ return [ self ] - def continued_fraction_list(self, type="std"): + def continued_fraction_list(self, type='std'): r""" Return the list of partial quotients of this rational number. INPUT: - - ``type`` -- either "std" (the default) for the standard continued - fractions or "hj" for the Hirzebruch-Jung ones. + - ``type`` -- either ``'std'`` (the default) for the standard continued + fractions or ``'hj'`` for the Hirzebruch-Jung ones EXAMPLES:: @@ -845,9 +842,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``left, right`` -- objects + - ``left``, ``right`` -- objects - - ``op`` -- integer + - ``op`` -- integer EXAMPLES:: @@ -1117,9 +1114,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``codomain`` -- object (usually a ring) + - ``codomain`` -- object (usually a ring) - - ``im_gens`` -- list of elements of ``codomain`` + - ``im_gens`` -- list of elements of ``codomain`` EXAMPLES:: @@ -1158,12 +1155,11 @@ cdef class Rational(sage.structure.element.FieldElement): def valuation(self, p): r""" - Return the power of ``p`` in the factorization of self. + Return the power of ``p`` in the factorization of ``self``. INPUT: - - - ``p`` -- a prime number + - ``p`` -- a prime number OUTPUT: @@ -1205,10 +1201,10 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``p`` -- a prime number + - ``p`` -- a prime number - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -1244,8 +1240,8 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -1280,8 +1276,8 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -1323,8 +1319,8 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -1355,8 +1351,8 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``prec`` (int) -- desired floating point precision (default: - default :class:`RealField` precision). + - ``prec`` -- integer (default: default :class:`RealField` precision); + desired floating point precision OUTPUT: @@ -1395,7 +1391,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return whether or not this rational number is a square. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -1421,10 +1417,10 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - ``L`` -- a number field - - ``element`` -- (default: ``False``) boolean whether to also output + - ``element`` -- boolean (default: ``False``); whether to also output an element of which ``self`` is a norm - - ``proof`` -- If ``True``, then the output is correct unconditionally. - If ``False``, then the output assumes GRH. + - ``proof`` -- if ``True``, then the output is correct unconditionally; + if ``False``, then the output assumes GRH OUTPUT: @@ -1533,7 +1529,7 @@ cdef class Rational(sage.structure.element.FieldElement): If `K` is known to be Galois, set ``extra_primes = 0`` (in this case, ``self`` is a norm iff `b = 1`). - If ``extra_primes`` is non-zero, the program adds to `S` the following + If ``extra_primes`` is nonzero, the program adds to `S` the following prime ideals, depending on the sign of extra_primes. If ``extra_primes > 0``, the ideals of norm less than ``extra_primes``. And if ``extra_primes < 0``, the ideals dividing ``extra_primes``. @@ -1545,10 +1541,10 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``K`` -- a number field - - ``proof`` -- whether to certify the output of bnfinit. - If ``False``, then correctness of the output depends on GRH. - - ``extra_primes`` -- an integer as explained above + - ``K`` -- a number field + - ``proof`` -- whether to certify the output of bnfinit; + if ``False``, then correctness of the output depends on GRH + - ``extra_primes`` -- integer as explained above OUTPUT: @@ -1580,16 +1576,15 @@ cdef class Rational(sage.structure.element.FieldElement): a, b = K.pari_bnf(proof=proof).bnfisnorm(self, flag=extra_primes) return K(a), Rational(b) - def is_perfect_power(self, expected_value=False): r""" Return ``True`` if ``self`` is a perfect power. INPUT: - - ``expected_value`` -- (bool) whether or not this rational is expected - be a perfect power. This does not affect the correctness of the - output, only the runtime. + - ``expected_value`` -- boolean; whether or not this rational is + expected to be a perfect power. This does not affect the correctness + of the output, only the runtime. If ``expected_value`` is ``False`` (default) it will check the smallest of the numerator and denominator is a perfect power @@ -1740,9 +1735,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``p`` -- a prime number, or ``infinity`` + - ``p`` -- a prime number, or ``infinity`` - - ``check`` -- (default: ``True``); check if `p` is prime + - ``check`` -- boolean (default: ``True``); check if `p` is prime EXAMPLES:: @@ -1795,13 +1790,13 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``p`` -- a prime + - ``p`` -- a prime OUTPUT: - - ``int`` -- the `p`-adic valuation of this rational + - integer; the `p`-adic valuation of this rational - - ``Rational`` -- `p`-adic unit part of ``self`` + - ``Rational``; `p`-adic unit part of ``self`` EXAMPLES:: @@ -1857,7 +1852,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``S`` -- list or tuple of primes. + - ``S`` -- list or tuple of primes OUTPUT: rational @@ -1881,7 +1876,6 @@ cdef class Rational(sage.structure.element.FieldElement): 0 sage: QQ(-700/99).prime_to_S_part([]) -700/99 - """ if self.is_zero(): return self @@ -1896,17 +1890,17 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``prec`` -- integer (default: ``None``): if ``None``, returns - an exact square root; otherwise returns a numerical square root if - necessary, to the given bits of precision. + - ``prec`` -- integer (default: ``None``); if ``None``, returns + an exact square root; otherwise returns a numerical square root if + necessary, to the given bits of precision. - - ``extend`` -- bool (default: ``True``); if ``True``, return a - square root in an extension ring, if necessary. Otherwise, raise a - ``ValueError`` if the square is not in the base ring. Ignored if ``prec`` - is not ``None``. + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise a + :exc:`ValueError` if the square is not in the base ring. Ignored if + ``prec`` is not ``None``. - - ``all`` -- bool (default: ``False``); if ``True``, return all - square roots of ``self`` (a list of length 0, 1, or 2). + - ``all`` -- boolean (default: ``False``); if ``True``, return all + square roots of ``self`` (a list of length 0, 1, or 2) EXAMPLES:: @@ -2060,12 +2054,12 @@ cdef class Rational(sage.structure.element.FieldElement): def nth_root(self, int n): r""" - Computes the `n`-th root of ``self``, or raises a - ``ValueError`` if ``self`` is not a perfect `n`-th power. + Compute the `n`-th root of ``self``, or raises a + :exc:`ValueError` if ``self`` is not a perfect `n`-th power. INPUT: - - ``n`` -- integer (must fit in C ``int`` type) + - ``n`` -- integer (must fit in C ``int`` type) AUTHORS: @@ -2124,11 +2118,11 @@ cdef class Rational(sage.structure.element.FieldElement): def is_nth_power(self, int n): r""" - Return ``True`` if self is an `n`-th power, else ``False``. + Return ``True`` if ``self`` is an `n`-th power, else ``False``. INPUT: - - ``n`` -- integer (must fit in C ``int`` type) + - ``n`` -- integer (must fit in C ``int`` type) .. NOTE:: @@ -2155,7 +2149,6 @@ cdef class Rational(sage.structure.element.FieldElement): False sage: QQ(-25).is_nth_power(2) False - """ if n == 0: raise ValueError("n cannot be zero") @@ -2172,7 +2165,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``base`` -- integer (default: 10); base must be between 2 and 36. + - ``base`` -- integer (default: 10); base must be between 2 and 36 OUTPUT: string @@ -2297,9 +2290,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``n`` -- an integer (error if not 0 or -1) + - ``n`` -- integer (error if not 0 or -1) - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -2321,7 +2314,7 @@ cdef class Rational(sage.structure.element.FieldElement): ################################################################ def __add__(left, right): """ - Return ``left`` plus ``right`` + Return ``left`` plus ``right``. EXAMPLES:: @@ -2362,7 +2355,7 @@ cdef class Rational(sage.structure.element.FieldElement): def __sub__(left, right): """ - Return ``left`` minus ``right`` + Return ``left`` minus ``right``. EXAMPLES:: @@ -2473,7 +2466,7 @@ cdef class Rational(sage.structure.element.FieldElement): def __truediv__(left, right): """ - Return ``left`` divided by ``right`` + Return ``left`` divided by ``right``. EXAMPLES:: @@ -2534,7 +2527,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return the multiplicative inverse of ``self``. - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -2712,7 +2705,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return ``self``. - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -2727,7 +2720,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return the negative of ``self``. - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -2745,7 +2738,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return ``True`` if this rational number is nonzero. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -2761,7 +2754,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return the absolute value of this rational number. - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -2781,7 +2774,7 @@ cdef class Rational(sage.structure.element.FieldElement): depending on whether this number is negative, zero, or positive respectively. - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -2801,7 +2794,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``n`` -- an unsigned long integer + - ``n`` -- an unsigned long integer OUTPUT: integer @@ -2832,7 +2825,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``other`` -- object that coerces to an integer. + - ``other`` -- object that coerces to an integer OUTPUT: integer @@ -2866,9 +2859,7 @@ cdef class Rational(sage.structure.element.FieldElement): Return the norm from `\QQ` to `\QQ` of `x` (which is just `x`). This was added for compatibility with :class:`NumberField`. - OUTPUT: - - - ``Rational`` -- reference to ``self`` + OUTPUT: ``Rational`` -- reference to ``self`` EXAMPLES:: @@ -2883,7 +2874,8 @@ cdef class Rational(sage.structure.element.FieldElement): def relative_norm(self): """ - Return the norm from Q to Q of x (which is just x). This was added for compatibility with NumberFields + Return the norm from Q to Q of x (which is just x). This was added for + compatibility with NumberFields. EXAMPLES:: @@ -2897,7 +2889,8 @@ cdef class Rational(sage.structure.element.FieldElement): def absolute_norm(self): """ - Return the norm from Q to Q of x (which is just x). This was added for compatibility with NumberFields + Return the norm from Q to Q of x (which is just x). This was added for + compatibility with NumberFields. EXAMPLES:: @@ -2914,9 +2907,7 @@ cdef class Rational(sage.structure.element.FieldElement): Return the trace from `\QQ` to `\QQ` of `x` (which is just `x`). This was added for compatibility with :class:`NumberFields`. - OUTPUT: - - - ``Rational`` -- reference to self + OUTPUT: ``Rational`` -- reference to ``self`` EXAMPLES:: @@ -2938,9 +2929,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``var`` -- a string + - ``var`` -- string - OUTPUT: Polynomial + OUTPUT: polynomial EXAMPLES:: @@ -2968,9 +2959,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``var`` -- a string + - ``var`` -- string - OUTPUT: Polynomial + OUTPUT: polynomial EXAMPLES:: @@ -2991,7 +2982,7 @@ cdef class Rational(sage.structure.element.FieldElement): Return ``self`` coerced to an integer. Of course this rational number must have a denominator of 1. - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -3036,7 +3027,7 @@ cdef class Rational(sage.structure.element.FieldElement): def __int__(self): """ - Convert this rational to a Python ``int`` + Convert this rational to a Python ``int``. This truncates ``self`` if ``self`` has a denominator (which is consistent with Python's ``long(floats)``). @@ -3104,7 +3095,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return the factorization of this rational number. - OUTPUT: Factorization + OUTPUT: factorization EXAMPLES:: @@ -3125,9 +3116,9 @@ cdef class Rational(sage.structure.element.FieldElement): def support(self): """ Return a sorted list of the primes where this rational number has - non-zero valuation. + nonzero valuation. - OUTPUT: The set of primes appearing in the factorization of this + OUTPUT: the set of primes appearing in the factorization of this rational with nonzero exponent, as a sorted list. EXAMPLES:: @@ -3317,7 +3308,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return the floor of this rational number as an integer. - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -3341,7 +3332,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ Return the ceiling of this rational number. - OUTPUT: Integer + OUTPUT: integer If this rational number is an integer, this returns this number, otherwise it returns the floor of this number +1. @@ -3392,18 +3383,18 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``self`` -- a rational number + - ``self`` -- a rational number - - ``mode`` -- a rounding mode for half integers: + - ``mode`` -- a rounding mode for half integers: - - 'toward' rounds toward zero - - 'away' (default) rounds away from zero - - 'up' rounds up - - 'down' rounds down - - 'even' rounds toward the even integer - - 'odd' rounds toward the odd integer + - ``'toward'`` rounds toward zero + - ``'away'`` (default) rounds away from zero + - ``'up'`` rounds up + - ``'down'`` rounds down + - ``'even'`` rounds toward the even integer + - ``'odd'`` rounds toward the odd integer - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -3485,7 +3476,7 @@ cdef class Rational(sage.structure.element.FieldElement): The max absolute value of the numerator and denominator of ``self``, as an :class:`Integer`. - OUTPUT: Integer + OUTPUT: integer EXAMPLES:: @@ -3506,7 +3497,6 @@ cdef class Rational(sage.structure.element.FieldElement): .. NOTE:: For the logarithmic height, use :meth:`global_height()`. - """ x = abs(self.numer()) if x > self.denom(): @@ -3521,11 +3511,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``other`` -- Rational + - ``other`` -- Rational - OUTPUT: - - - ``Rational`` -- 0 or 1 + OUTPUT: ``Rational`` -- 0 or 1 EXAMPLES:: @@ -3560,12 +3548,11 @@ cdef class Rational(sage.structure.element.FieldElement): else: return sage.rings.infinity.infinity - def multiplicative_order(self): """ Return the multiplicative order of ``self``. - OUTPUT: Integer or ``infinity`` + OUTPUT: integer or ``infinity`` EXAMPLES:: @@ -3594,7 +3581,7 @@ cdef class Rational(sage.structure.element.FieldElement): r""" Determine if a rational number is one. - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -3611,7 +3598,7 @@ cdef class Rational(sage.structure.element.FieldElement): Determine if a rational number is integral (i.e., is in `\ZZ`). - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -3633,10 +3620,9 @@ cdef class Rational(sage.structure.element.FieldElement): """ return True - #Function alias for checking if the number is a integer. Added to solve issue 15500 + # Function alias for checking if the number is a integer. Added to solve issue 15500 is_integer = is_integral - def is_S_integral(self, S=[]): r""" Determine if the rational number is ``S``-integral. @@ -3647,9 +3633,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``S`` -- list or tuple of primes. + - ``S`` -- list or tuple of primes - OUTPUT: bool + OUTPUT: boolean .. NOTE:: @@ -3678,9 +3664,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``S`` -- list or tuple of primes. + - ``S`` -- list or tuple of primes - OUTPUT: bool + OUTPUT: boolean .. NOTE:: @@ -3722,9 +3708,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``x, y`` -- integer or rational + - ``x``, ``y`` -- integer or rational - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -3770,9 +3756,9 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``x, y`` -- integer or rational + - ``x``, ``y`` -- integer or rational - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -4079,7 +4065,7 @@ cdef double mpq_get_d_nearest(mpq_t x) except? -648555075988944.5: pass else: if not remainder_is_zero: - # Remainder is non-zero: round away from zero + # Remainder is nonzero: round away from zero q64 += 1 else: # Halfway case: round to even @@ -4097,13 +4083,13 @@ cdef double mpq_get_d_nearest(mpq_t x) except? -648555075988944.5: @cython.binding(True) def make_rational(s): """ - Make a rational number from ``s`` (a string in base 32) + Make a rational number from ``s`` (a string in base 32). INPUT: - - ``s`` -- string in base 32 + - ``s`` -- string in base 32 - OUTPUT: Rational + OUTPUT: rational EXAMPLES:: @@ -4192,7 +4178,6 @@ cdef class Z_to_Q(Morphism): sage: QQ.coerce_map_from(ZZ).is_surjective() False - """ return False diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 62d85cf3380..f1b414089e2 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -294,7 +294,7 @@ def __len__(self): """ Return the number of elements in ``self``. - Since this does not have a size, this throws a ``TypeError``. + Since this does not have a size, this throws a :exc:`TypeError`. EXAMPLES:: @@ -410,7 +410,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): def __iter__(self): r""" - Creates an iterator that generates the rational numbers without + Create an iterator that generates the rational numbers without repetition, in order of the height. See also :meth:`range_by_height()`. @@ -496,8 +496,7 @@ def range_by_height(self, start, end=None): if end is None: end = start start = 1 - if start < 1: - start = 1 + start = max(start, 1) for height in ZZ.range(start, end): if height == 1: yield self(0) @@ -516,13 +515,11 @@ def primes_of_bounded_norm_iter(self, B): INPUT: - - ``B`` -- a positive integer; upper bound on the primes generated. - - OUTPUT: + - ``B`` -- positive integer; upper bound on the primes generated - An iterator over all integer primes less than or equal to `B`. + OUTPUT: an iterator over all integer primes less than or equal to `B` - .. note:: + .. NOTE:: This function exists for compatibility with the related number field method, though it returns prime integers, not ideals. @@ -604,7 +601,8 @@ def signature(self): def embeddings(self, K): r""" - Return list of the one embedding of `\QQ` into `K`, if it exists. + Return the list containing the unique embedding of `\QQ` into `K`, + if it exists, and an empty list otherwise. EXAMPLES:: @@ -615,16 +613,17 @@ def embeddings(self, K): From: Rational Field To: Cyclotomic Field of order 5 and degree 4] - `K` must have characteristic 0:: + The field `K` must have characteristic `0` for an embedding of `\QQ` + to exist:: sage: QQ.embeddings(GF(3)) - Traceback (most recent call last): - ... - ValueError: no embeddings of the rational field into K. + [] """ - if K.characteristic(): - raise ValueError("no embeddings of the rational field into K.") - return [self.hom(K)] + if K.characteristic() == 0: + v = [self.hom(K)] + else: + v = [] + return Sequence(v, check=False, universe=self.Hom(K)) def automorphisms(self): r""" @@ -730,12 +729,12 @@ def residue_field(self, p, check=True): INPUT: - - ``p`` -- a prime integer. + - ``p`` -- prime integer - - ``check`` (default ``True``) -- if ``True``, check the primality of - `p`, else do not. + - ``check`` -- (default: ``True``) if ``True``, check the primality of + `p`, else do not - OUTPUT: The residue field at this prime. + OUTPUT: the residue field at this prime EXAMPLES:: @@ -758,12 +757,12 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): INPUT: - - ``S`` -- a list of rational primes, the infinite place as real + - ``S`` -- list of rational primes, the infinite place as real embedding of `\QQ` or as `-1` - - ``b`` -- a non-zero rational number which is a non-square locally - at every prime in ``S``. - - ``check`` -- ``bool`` (default: ``True``) perform additional checks on - input and confirm the output. + - ``b`` -- a nonzero rational number which is a non-square locally + at every prime in ``S`` + - ``check`` -- boolean (default: ``True``); perform additional checks on + input and confirm the output OUTPUT: @@ -834,7 +833,6 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): AUTHORS: - Simon Brandhorst, Juanita Duque, Anna Haensch, Manami Roy, Sandi Rudzinski (10-24-2017) - """ from sage.arith.misc import hilbert_symbol, is_prime from sage.matrix.constructor import matrix @@ -933,7 +931,7 @@ def gens(self): def gen(self, n=0): r""" - Return the ``n``-th generator of `\QQ`. + Return the n-th generator of `\QQ`. There is only the 0-th generator, which is 1. @@ -1116,7 +1114,6 @@ def polynomial(self): sage: QQ.polynomial() x - """ from sage.rings.polynomial.polynomial_ring import polygen return polygen(self) @@ -1141,7 +1138,7 @@ def some_elements(self): See :func:`TestSuite` for a typical use case. - OUTPUT: An iterator over 100 elements of `\QQ`. + OUTPUT: an iterator over 100 elements of `\QQ` EXAMPLES:: @@ -1187,13 +1184,13 @@ def random_element(self, num_bound=None, den_bound=None, *args, **kwds): INPUT: - - ``num_bound`` -- a positive integer, specifying a bound - on the absolute value of the numerator. - If absent, no bound is enforced. + - ``num_bound`` -- positive integer, specifying a bound + on the absolute value of the numerator. + If absent, no bound is enforced. - - ``den_bound`` -- a positive integer, specifying a bound - on the value of the denominator. - If absent, the bound for the numerator will be reused. + - ``den_bound`` -- positive integer, specifying a bound + on the value of the denominator. + If absent, the bound for the numerator will be reused. Any extra positional or keyword arguments are passed through to :meth:`sage.rings.integer_ring.IntegerRing_class.random_element`. @@ -1255,8 +1252,7 @@ def zeta(self, n=2): INPUT: - - ``n`` -- integer (default: 2) order of the root of - unity + - ``n`` -- integer (default: 2); order of the root of unity EXAMPLES:: @@ -1284,13 +1280,13 @@ def selmer_generators(self, S, m, proof=True, orders=False): INPUT: - - ``S`` -- a set of primes + - ``S`` -- set of primes - - ``m`` -- a positive integer + - ``m`` -- positive integer - ``proof`` -- ignored - - ``orders`` (default ``False``) -- if ``True``, output two lists, the + - ``orders`` -- (default: ``False``) if ``True``, output two lists, the generators and their orders OUTPUT: @@ -1332,7 +1328,6 @@ def selmer_generators(self, S, m, proof=True, orders=False): ([-1, 2, 3, 5, 7], [2, 2, 2, 2, 2]) sage: QQ.selmer_generators((2,3,5,7,), 3, orders=True) ([2, 3, 5, 7], [3, 3, 3, 3]) - """ gens = list(S) ords = [ZZ(m)] * len(S) @@ -1353,9 +1348,9 @@ def selmer_group_iterator(self, S, m, proof=True): INPUT: - - ``S`` -- a set of primes + - ``S`` -- set of primes - - ``m`` -- a positive integer + - ``m`` -- positive integer - ``proof`` -- ignored @@ -1389,7 +1384,7 @@ def selmer_space(self, S, p, proof=None): INPUT: - - ``S`` -- a list of prime numbers + - ``S`` -- list of prime numbers - ``p`` -- a prime number @@ -1445,7 +1440,7 @@ def selmer_space(self, S, p, proof=None): sage: fromQS2((0,1,1)) -7 - The map ``fromQS2`` is only well-defined modulo `p`'th powers + The map ``fromQS2`` is only well-defined modulo `p`-th powers (in this case, modulo squares):: sage: toQS2(-5/7) # needs sage.modules sage.rings.number_field @@ -1463,7 +1458,6 @@ def selmer_space(self, S, p, proof=None): ... ValueError: argument 210 should have valuations divisible by 2 at all primes in [5, 7] - """ from sage.rings.number_field.selmer_group import pSelmerGroup return pSelmerGroup(self, S, p) @@ -1476,7 +1470,7 @@ def quadratic_defect(self, a, p, check=True): - ``a`` -- an element of ``self`` - ``p`` -- a prime ideal or a prime number - - ``check`` -- (default: ``True``); check if `p` is prime + - ``check`` -- (default: ``True``) check if `p` is prime REFERENCE: @@ -1572,7 +1566,6 @@ def _axiom_init_(self): Fraction Integer sage: fricas(QQ) #optional - fricas # indirect doctest Fraction(Integer) - """ return 'Fraction Integer' @@ -1586,7 +1579,6 @@ def _polymake_init_(self): sage: polymake(QQ) #optional - jupymake # indirect doctest Rational - """ return '"Rational"' @@ -1683,7 +1675,6 @@ def valuation(self, p): :meth:`NumberField_generic.valuation() `, :meth:`IntegerRing_class.valuation() ` - """ from sage.rings.padics.padic_valuation import pAdicValuation return pAdicValuation(self, p) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 4b34af0e8bf..3c063f193a8 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -94,7 +94,7 @@ above warning, inexact balls are not considered equal to themselves):: sage: a == b False -A ball is non-zero in the sense of comparison if and only if it does not +A ball is nonzero in the sense of comparison if and only if it does not contain zero. :: sage: a = RBF(RIF(-0.5, 0.5)) @@ -241,11 +241,11 @@ cdef void mpfi_to_arb(arb_t target, const mpfi_t source, const long precision) n INPUT: - - ``target`` -- an ``arb_t``. + - ``target`` -- an ``arb_t`` - - ``source`` -- an ``mpfi_t``. + - ``source`` -- an ``mpfi_t`` - - ``precision`` -- an integer `\ge 2`. + - ``precision`` -- integer `\ge 2` TESTS:: @@ -285,18 +285,17 @@ cdef int arb_to_mpfi(mpfi_t target, arb_t source, const long precision) except - INPUT: - - ``target`` -- an ``mpfi_t``. + - ``target`` -- an ``mpfi_t`` - - ``source`` -- an ``arb_t``. + - ``source`` -- an ``arb_t`` - - ``precision`` -- an integer `\ge 2`. + - ``precision`` -- integer `\ge 2` EXAMPLES:: sage: RIF(RBF(2)**(2**100)) [5.8756537891115869e1388255822130839282 .. +infinity] # 64-bit [2.098... .. +infinity] # 32-bit - """ cdef mpfr_t left cdef mpfr_t right @@ -323,7 +322,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): INPUT: - - ``precision`` -- an integer `\ge 2`. + - ``precision`` -- integer `\ge 2` EXAMPLES:: @@ -396,7 +395,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): INPUT: - - ``precision`` -- an integer `\ge 2`. + - ``precision`` -- integer `\ge 2` EXAMPLES:: @@ -418,7 +417,6 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): Real ball field with 53 bits of precision sage: RBF.base_ring() Real ball field with 53 bits of precision - """ if precision < 2: raise ValueError("precision must be at least 2") @@ -541,7 +539,6 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): [-3.932239737431101 +/- 5.58e-16] sage: v.overlaps(RealBallField(100)(3/2).zetaderiv(1)) # needs sage.symbolic True - """ # Symbolic expressions are handled in a special way, see # Expression._arb_(). A call like RBF(expr, rad) converts expr to a @@ -1118,7 +1115,6 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): Traceback (most recent call last): ... ValueError: expected a nonnegative index - """ cdef RealBall res cdef Integer n_as_Integer = ZZ.coerce(n) @@ -1138,9 +1134,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): r""" Return the relative accuracy of exact elements measured in bits. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -1195,7 +1189,7 @@ def create_RealBall(parent, serialized): cdef class RealBall(RingElement): """ - Hold one ``arb_t`` + Hold one ``arb_t``. EXAMPLES:: @@ -1235,12 +1229,12 @@ cdef class RealBall(RingElement): INPUT: - - ``parent`` -- a :class:`RealBallField`. + - ``parent`` -- a :class:`RealBallField` - - ``mid`` (optional) -- ball midpoint, see examples below. If omitted, + - ``mid`` -- (optional) ball midpoint, see examples below. If omitted, initialize the ball to zero, ignoring the ``rad`` argument. - - ``rad`` (optional) -- a :class:`RealNumber` or a Python float, ball + - ``rad`` -- (optional) a :class:`RealNumber` or a Python float, ball radius. If the midpoint is not exactly representable in floating-point, the radius is adjusted to account for the roundoff error. @@ -1524,9 +1518,7 @@ cdef class RealBall(RingElement): """ Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1571,9 +1563,7 @@ cdef class RealBall(RingElement): """ Return a :mod:`real interval ` containing this ball. - OUTPUT: - - A :class:`~sage.rings.real_mpfi.RealIntervalFieldElement`. + OUTPUT: a :class:`~sage.rings.real_mpfi.RealIntervalFieldElement` EXAMPLES:: @@ -1602,7 +1592,6 @@ cdef class RealBall(RingElement): Traceback (most recent call last): ... ValueError: [3.141592653589793 +/- ...e-16] does not contain a unique integer - """ cdef Integer res cdef fmpz_t tmp @@ -1870,13 +1859,11 @@ cdef class RealBall(RingElement): INPUT: - - ``test_zero`` (boolean, default ``False``) -- if ``True``, + - ``test_zero`` -- boolean (default: ``False``); if ``True``, make sure that the returned lower bound is positive, raising an error if the ball contains zero. - OUTPUT: - - A ball with zero radius + OUTPUT: a ball with zero radius EXAMPLES:: @@ -1910,9 +1897,7 @@ cdef class RealBall(RingElement): """ Return an upper bound for the absolute value of this ball. - OUTPUT: - - A ball with zero radius + OUTPUT: a ball with zero radius EXAMPLES:: @@ -1936,13 +1921,11 @@ cdef class RealBall(RingElement): INPUT: - - ``rnd`` (string) -- rounding mode for the parent of the result (does + - ``rnd`` -- string; rounding mode for the parent of the result (does not affect its value!), see :meth:`sage.rings.real_mpfi.RealIntervalFieldElement.upper` - OUTPUT: - - A real number. + OUTPUT: a real number EXAMPLES:: @@ -1964,13 +1947,11 @@ cdef class RealBall(RingElement): INPUT: - - ``rnd`` (string) -- rounding mode for the parent of the result (does + - ``rnd`` -- string; rounding mode for the parent of the result (does not affect its value!), see :meth:`sage.rings.real_mpfi.RealIntervalFieldElement.lower` - OUTPUT: - - A real number. + OUTPUT: a real number EXAMPLES:: @@ -1990,13 +1971,11 @@ cdef class RealBall(RingElement): INPUT: - - ``rnd`` (string) -- rounding mode for the parent of the resulting + - ``rnd`` -- string; rounding mode for the parent of the resulting floating-point numbers (does not affect their values!), see :meth:`sage.rings.real_mpfi.RealIntervalFieldElement.upper` - OUTPUT: - - A pair of real numbers. + OUTPUT: a pair of real numbers EXAMPLES:: @@ -2154,12 +2133,10 @@ cdef class RealBall(RingElement): INPUT: - - ``ampl`` -- A real ball (or an object that can be coerced to a real - ball). - - OUTPUT: + - ``ampl`` -- a real ball (or an object that can be coerced to a real + ball) - A new real ball. + OUTPUT: a new real ball EXAMPLES:: @@ -2621,7 +2598,6 @@ cdef class RealBall(RingElement): sage: b.contains_exact(1r) True - """ cdef fmpz_t tmpz cdef fmpq_t tmpq @@ -2732,7 +2708,7 @@ cdef class RealBall(RingElement): .. WARNING:: - Contrary to the usual convention, a return value of True does + Contrary to the usual convention, a return value of ``True`` does not imply that all points of the ball satisfy the predicate. This is due to the way comparisons with symbolic infinities work in sage. @@ -2799,7 +2775,6 @@ cdef class RealBall(RingElement): nan sage: RBF(RIF(-0.1,0.1)) [+/- 0.101] - """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3055,7 +3030,7 @@ cdef class RealBall(RingElement): INPUT: - - ``shift`` -- integer, may be negative. + - ``shift`` -- integer; may be negative EXAMPLES:: @@ -3108,7 +3083,7 @@ cdef class RealBall(RingElement): INPUT: - - ``shift`` -- integer, may be negative. + - ``shift`` -- integer; may be negative EXAMPLES:: @@ -3139,7 +3114,7 @@ cdef class RealBall(RingElement): INPUT: - - ``base`` (optional, positive real ball or number) -- if ``None``, + - ``base`` -- (optional) positive real ball or number; if ``None``, return the natural logarithm ``ln(self)``, otherwise, return the general logarithm ``ln(self)/ln(base)`` @@ -3537,7 +3512,7 @@ cdef class RealBall(RingElement): def erfi(self): """ - Imaginary error function + Imaginary error function. EXAMPLES:: @@ -3552,7 +3527,7 @@ cdef class RealBall(RingElement): def Ei(self): """ - Exponential integral + Exponential integral. EXAMPLES:: @@ -3572,7 +3547,7 @@ cdef class RealBall(RingElement): def Si(self): """ - Sine integral + Sine integral. EXAMPLES:: @@ -3594,7 +3569,7 @@ cdef class RealBall(RingElement): def Ci(self): """ - Cosine integral + Cosine integral. EXAMPLES:: @@ -3616,7 +3591,7 @@ cdef class RealBall(RingElement): def Shi(self): """ - Hyperbolic sine integral + Hyperbolic sine integral. EXAMPLES:: @@ -3638,7 +3613,7 @@ cdef class RealBall(RingElement): def Chi(self): """ - Hyperbolic cosine integral + Hyperbolic cosine integral. EXAMPLES:: @@ -3660,7 +3635,7 @@ cdef class RealBall(RingElement): def li(self): """ - Logarithmic integral + Logarithmic integral. EXAMPLES:: @@ -3684,7 +3659,7 @@ cdef class RealBall(RingElement): def Li(self): """ - Offset logarithmic integral + Offset logarithmic integral. EXAMPLES:: @@ -3701,11 +3676,11 @@ cdef class RealBall(RingElement): def beta(self, a, z=1): """ - (Incomplete) beta function + (Incomplete) beta function. INPUT: - - ``a``, ``z`` (optional) -- real balls + - ``a``, ``z`` -- (optional) real balls OUTPUT: @@ -3740,7 +3715,7 @@ cdef class RealBall(RingElement): def gamma(self, a=None): r""" - Image of this ball by the (upper incomplete) Euler Gamma function + Image of this ball by the (upper incomplete) Euler Gamma function. For `a` real, return the upper incomplete Gamma function `\Gamma(self,a)`. @@ -3782,7 +3757,7 @@ cdef class RealBall(RingElement): def gamma_inc_lower(self, a): r""" - Image of this ball by the lower incomplete Euler Gamma function + Image of this ball by the lower incomplete Euler Gamma function. For `a` real, return the lower incomplete Gamma function of `\Gamma(self,a)`. @@ -3806,7 +3781,7 @@ cdef class RealBall(RingElement): """ Return the image of this ball by the logarithmic Gamma function. - The complex branch structure is assumed, so if ``self`` <= 0, the result + The complex branch structure is assumed, so if ``self <= 0``, the result is an indeterminate interval. EXAMPLES:: @@ -3862,7 +3837,7 @@ cdef class RealBall(RingElement): cpdef RealBall psi(self): """ - Compute the digamma function with argument self. + Compute the digamma function with argument ``self``. EXAMPLES:: @@ -3911,7 +3886,7 @@ cdef class RealBall(RingElement): def zetaderiv(self, k): r""" - Return the image of this ball by the k-th derivative of the Riemann + Return the image of this ball by the `k`-th derivative of the Riemann zeta function. For a more flexible interface, see the low-level method diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index d0ef9a4bb62..129603749d3 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -92,7 +92,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): sage: RDF(2/3) 0.6666666666666666 - A ``TypeError`` is raised if the coercion doesn't make sense:: + A :exc:`TypeError` is raised if the coercion doesn't make sense:: sage: RDF(QQ['x'].0) Traceback (most recent call last): @@ -151,7 +151,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): cpdef bint is_exact(self) except -2: """ - Returns ``False``, because doubles are not exact. + Return ``False``, because doubles are not exact. EXAMPLES:: @@ -233,7 +233,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): def construction(self): r""" - Returns the functorial construction of ``self``, namely, completion of + Return the functorial construction of ``self``, namely, completion of the rational numbers with respect to the prime at `\infty`. Also preserves other information that makes this field unique (i.e. @@ -462,7 +462,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): def characteristic(self): """ - Returns 0, since the field of real numbers has characteristic 0. + Return 0, since the field of real numbers has characteristic 0. EXAMPLES:: @@ -523,7 +523,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): def pi(self): r""" - Returns `\pi` to double-precision. + Return `\pi` to double-precision. EXAMPLES:: @@ -572,7 +572,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): def zeta(self, n=2): """ Return an `n`-th root of unity in the real field, if one - exists, or raise a ``ValueError`` otherwise. + exists, or raise a :exc:`ValueError` otherwise. EXAMPLES:: @@ -760,7 +760,7 @@ cdef class RealDoubleElement(FieldElement): def ulp(self): """ - Returns the unit of least precision of ``self``, which is the + Return the unit of least precision of ``self``, which is the weight of the least significant bit of ``self``. This is always a strictly positive number. It is also the gap between this number and the closest number with larger absolute value that @@ -844,7 +844,6 @@ cdef class RealDoubleElement(FieldElement): sage: x = u * 2^52 # smallest normal number sage: x.ulp() == u True - """ # First, check special values if self._value == 0: @@ -1364,7 +1363,7 @@ cdef class RealDoubleElement(FieldElement): def __neg__(self): """ - Negates ``self``. + Negate ``self``. EXAMPLES:: @@ -1377,7 +1376,7 @@ cdef class RealDoubleElement(FieldElement): def conjugate(self): r""" - Returns the complex conjugate of this real number, which is + Return the complex conjugate of this real number, which is the real number itself. EXAMPLES:: @@ -1389,7 +1388,7 @@ cdef class RealDoubleElement(FieldElement): def __abs__(self): """ - Returns the absolute value of ``self``. + Return the absolute value of ``self``. EXAMPLES:: @@ -1410,7 +1409,7 @@ cdef class RealDoubleElement(FieldElement): cpdef RealDoubleElement abs(RealDoubleElement self): """ - Returns the absolute value of ``self``. + Return the absolute value of ``self``. EXAMPLES:: @@ -1454,7 +1453,7 @@ cdef class RealDoubleElement(FieldElement): def multiplicative_order(self): r""" - Returns `n` such that ``self^n == 1``. + Return `n` such that ``self^n == 1``. Only `\pm 1` have finite multiplicative order. @@ -1475,7 +1474,7 @@ cdef class RealDoubleElement(FieldElement): def sign(self): """ - Returns -1,0, or 1 if ``self`` is negative, zero, or positive; + Return -1, 0, or 1 if ``self`` is negative, zero, or positive; respectively. EXAMPLES:: @@ -1600,7 +1599,7 @@ cdef class RealDoubleElement(FieldElement): def _rpy_(self): """ - Returns ``self.__float__()`` for rpy to convert into the + Return ``self.__float__()`` for rpy to convert into the appropriate R object. EXAMPLES:: @@ -1637,7 +1636,7 @@ cdef class RealDoubleElement(FieldElement): 0.333333333333333 If we coerce to a higher-precision field the extra bits appear - random; they are actually 0's in base 2. + random; they are actually 0s in base 2. :: @@ -1802,12 +1801,12 @@ cdef class RealDoubleElement(FieldElement): INPUT: - - ``extend`` -- bool (default: ``True``); if ``True``, return a - square root in a complex field if necessary if ``self`` is negative; - otherwise raise a ``ValueError``. + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in a complex field if necessary if ``self`` is negative. + Otherwise raise a :exc:`ValueError`. - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots EXAMPLES:: @@ -1858,7 +1857,7 @@ cdef class RealDoubleElement(FieldElement): """ Return whether or not this number is a square in this field. For the real numbers, this is ``True`` if and only if ``self`` is - non-negative. + nonnegative. EXAMPLES:: @@ -1873,7 +1872,7 @@ cdef class RealDoubleElement(FieldElement): def is_integer(self): """ - Return ``True`` if this number is a integer + Return ``True`` if this number is a integer. EXAMPLES:: diff --git a/src/sage/rings/real_double_element_gsl.pyx b/src/sage/rings/real_double_element_gsl.pyx index cf2be375b78..001564dee37 100644 --- a/src/sage/rings/real_double_element_gsl.pyx +++ b/src/sage/rings/real_double_element_gsl.pyx @@ -17,11 +17,11 @@ cdef class RealDoubleElement_gsl(RealDoubleElement): def nth_root(self, int n): """ - Return the `n^{th}` root of ``self``. + Return the `n`-th root of ``self``. INPUT: - - ``n`` -- an integer + - ``n`` -- integer OUTPUT: @@ -502,7 +502,7 @@ cdef class RealDoubleElement_gsl(RealDoubleElement): the interval `(-\pi, \pi]`. Specifically, it is the unique `x \in (-\pi, \pi]` such - that ```self`` `= x + 2\pi n` for some `n \in \ZZ`. + that ``self`` `= x + 2\pi n` for some `n \in \ZZ`. EXAMPLES:: @@ -546,7 +546,7 @@ cdef class RealDoubleElement_gsl(RealDoubleElement): def hypot(self, other): r""" - Computes the value `\sqrt{s^2 + o^2}` where `s` is ``self`` and `o` + Compute the value `\sqrt{s^2 + o^2}` where `s` is ``self`` and `o` is ``other`` in such a way as to avoid overflow. EXAMPLES:: diff --git a/src/sage/rings/real_field.py b/src/sage/rings/real_field.py index 7b8e17eb5b9..d0302c47ee5 100644 --- a/src/sage/rings/real_field.py +++ b/src/sage/rings/real_field.py @@ -1,4 +1,4 @@ -def create_RealField(prec=53, type="MPFR", rnd="RNDN", sci_not=0): +def create_RealField(prec=53, type='MPFR', rnd='RNDN', sci_not=0): """ Create a real field with given precision, type, rounding mode and scientific notation. @@ -7,7 +7,7 @@ def create_RealField(prec=53, type="MPFR", rnd="RNDN", sci_not=0): INPUT: - - ``prec`` -- a positive integer + - ``prec`` -- positive integer - ``type`` -- type of real field: @@ -26,9 +26,7 @@ def create_RealField(prec=53, type="MPFR", rnd="RNDN", sci_not=0): - ``sci_not`` -- boolean, whether to use scientific notation for printing - OUTPUT: - - the appropriate real field + OUTPUT: the appropriate real field EXAMPLES:: diff --git a/src/sage/rings/real_interval_absolute.pyx b/src/sage/rings/real_interval_absolute.pyx index e1c60c049c7..50baf63a0e9 100644 --- a/src/sage/rings/real_interval_absolute.pyx +++ b/src/sage/rings/real_interval_absolute.pyx @@ -212,7 +212,7 @@ cdef class RealIntervalAbsoluteField_class(Field): def absprec(self): """ - Returns the absolute precision of self. + Return the absolute precision of ``self``. EXAMPLES:: diff --git a/src/sage/rings/real_lazy.pyx b/src/sage/rings/real_lazy.pyx index 4b241818d84..8fe3a8281d0 100644 --- a/src/sage/rings/real_lazy.pyx +++ b/src/sage/rings/real_lazy.pyx @@ -110,7 +110,6 @@ cdef class LazyField(Field): sage: RLF # indirect doctest Real Lazy Field - """ Field.__init__(self,base or self, names=names, normalize=normalize, category=category) @@ -193,7 +192,7 @@ cdef class LazyField(Field): def algebraic_closure(self): """ - Returns the algebraic closure of ``self``, i.e., the complex lazy + Return the algebraic closure of ``self``, i.e., the complex lazy field. EXAMPLES:: @@ -258,7 +257,7 @@ class RealLazyField_class(LazyField): """ def interval_field(self, prec=None): """ - Returns the interval field that represents the same mathematical + Return the interval field that represents the same mathematical field as ``self``. EXAMPLES:: @@ -276,7 +275,7 @@ class RealLazyField_class(LazyField): def construction(self): """ - Returns the functorial construction of ``self``, namely, the + Return the functorial construction of ``self``, namely, the completion of the rationals at infinity to infinite precision. EXAMPLES:: @@ -409,7 +408,7 @@ class ComplexLazyField_class(LazyField): def interval_field(self, prec=None): """ - Returns the interval field that represents the same mathematical + Return the interval field that represents the same mathematical field as ``self``. EXAMPLES:: @@ -447,7 +446,7 @@ class ComplexLazyField_class(LazyField): def construction(self): """ - Returns the functorial construction of ``self``, namely, + Return the functorial construction of ``self``, namely, algebraic closure of the real lazy field. EXAMPLES:: @@ -513,7 +512,7 @@ CLF = ComplexLazyField_class() def ComplexLazyField(): """ - Returns the lazy complex field. + Return the lazy complex field. EXAMPLES: @@ -745,7 +744,7 @@ cdef class LazyFieldElement(FieldElement): def approx(self): """ - Returns ``self`` as an element of an interval field. + Return ``self`` as an element of an interval field. EXAMPLES:: @@ -859,13 +858,12 @@ cdef class LazyFieldElement(FieldElement): def __dir__(self): """ - Adds the named_unops to ``__dir__`` so that tab completion works. + Add the named_unops to ``__dir__`` so that tab completion works. TESTS:: sage: "log" in RLF(sqrt(8)).__dir__() # needs sage.symbolic True - """ return FieldElement.__dir__(self) + named_unops @@ -890,7 +888,7 @@ cdef class LazyFieldElement(FieldElement): def continued_fraction(self): r""" - Return the continued fraction of self. + Return the continued fraction of ``self``. EXAMPLES:: @@ -923,7 +921,7 @@ cdef class LazyWrapper(LazyFieldElement): cpdef int depth(self) noexcept: """ - Returns the depth of ``self`` as an expression, which is always 0. + Return the depth of ``self`` as an expression, which is always 0. EXAMPLES:: @@ -1049,7 +1047,7 @@ cdef class LazyWrapper(LazyFieldElement): def continued_fraction(self): r""" - Return the continued fraction of self. + Return the continued fraction of ``self``. EXAMPLES:: @@ -1204,7 +1202,7 @@ cdef class LazyUnop(LazyFieldElement): def __init__(self, LazyField parent, arg, op): """ - Represents a unevaluated single function of one variable. + Represent a unevaluated single function of one variable. EXAMPLES:: @@ -1369,7 +1367,7 @@ cdef class LazyNamedUnop(LazyUnop): def approx(self): """ - Does something reasonable with functions that are not defined on the + Do something reasonable with functions that are not defined on the interval fields. TESTS:: diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 95b472e912c..11953a50ab5 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -175,7 +175,7 @@ EXAMPLES:: Comparison with infinity is defined through coercion to the infinity ring where semi-infinite intervals are sent to their central value -(plus or minus infinity); This implements the above convention for +(plus or minus infinity); this implements the above convention for inequalities:: sage: InfinityRing.has_coerce_map_from(RIF) @@ -231,6 +231,8 @@ specified if given a non-interval and an interval:: TESTS:: sage: import numpy # needs numpy + sage: if int(numpy.version.short_version[0]) > 1: # needs numpy + ....: numpy.set_printoptions(legacy="1.25") # needs numpy sage: RIF(2) == numpy.int8('2') # needs numpy True sage: numpy.int8('2') == RIF(2) # needs numpy @@ -311,14 +313,14 @@ cpdef RealIntervalField_class RealIntervalField(prec=53, sci_not=False): INPUT: - - ``prec`` -- (integer) precision; default = 53: - The number of bits used to represent the mantissa of a - floating-point number. The precision can be any integer between - :func:`mpfr_prec_min()` and :func:`mpfr_prec_max()`. In the current - implementation, :func:`mpfr_prec_min()` is equal to 2. + - ``prec`` -- integer (default: 53); precision. + The number of bits used to represent the mantissa of a + floating-point number. The precision can be any integer between + :func:`mpfr_prec_min()` and :func:`mpfr_prec_max()`. In the current + implementation, :func:`mpfr_prec_min()` is equal to 2. - - ``sci_not`` -- (default: ``False``) whether or not to display using - scientific notation + - ``sci_not`` -- boolean (default: ``False``); whether or not to display using + scientific notation EXAMPLES:: @@ -350,16 +352,16 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): INPUT: - - ``prec`` -- (integer) precision; default = 53 ``prec`` is - the number of bits used to represent the mantissa of a - floating-point number. The precision can be any integer between - :func:`~sage.rings.real_mpfr.mpfr_prec_min()` and - :func:`~sage.rings.real_mpfr.mpfr_prec_max()`. In the current - implementation, :func:`~sage.rings.real_mpfr.mpfr_prec_min()` - is equal to 2. + - ``prec`` -- integer (default: 53); precision ``prec`` is + the number of bits used to represent the mantissa of a + floating-point number. The precision can be any integer between + :func:`~sage.rings.real_mpfr.mpfr_prec_min()` and + :func:`~sage.rings.real_mpfr.mpfr_prec_max()`. In the current + implementation, :func:`~sage.rings.real_mpfr.mpfr_prec_min()` + is equal to 2. - - ``sci_not`` -- (default: ``False``) whether or not to display using - scientific notation + - ``sci_not`` -- boolean (default: ``False``); whether or not to display using + scientific notation EXAMPLES:: @@ -543,7 +545,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): self._multiplicative_order = None from sage.categories.fields import Fields Field.__init__(self, self, category=Fields().Infinite()) - self._populate_coercion_lists_(convert_method_name="_real_mpfi_") + self._populate_coercion_lists_(convert_method_name='_real_mpfi_') def lower_field(self): """ @@ -668,7 +670,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): cpdef bint is_exact(self) except -2: """ - Returns whether or not this field is exact, which is always ``False``. + Return whether or not this field is exact, which is always ``False``. EXAMPLES:: @@ -685,12 +687,12 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): - ``x`` -- a number, string, or 2-tuple - - ``y`` -- (default: ``None``); if given ``x`` is set to ``(x,y)``; + - ``y`` -- (default: ``None``) if given ``x`` is set to ``(x,y)``; this is so you can write ``R(2,3)`` to make the interval from 2 to 3 - ``base`` -- integer (default: 10); only used if ``x`` is a string - OUTPUT: an element of this real interval field. + OUTPUT: an element of this real interval field EXAMPLES:: @@ -734,7 +736,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def construction(self): r""" - Returns the functorial construction of ``self``, namely, completion of + Return the functorial construction of ``self``, namely, completion of the rational numbers with respect to the prime at `\infty`, and the note that this is an interval field. @@ -986,7 +988,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def characteristic(self): """ - Returns 0, since the field of real numbers has characteristic 0. + Return 0, since the field of real numbers has characteristic 0. EXAMPLES:: @@ -1038,7 +1040,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def to_prec(self, prec): """ - Returns a real interval field to the given precision. + Return a real interval field to the given precision. EXAMPLES:: @@ -1066,7 +1068,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def pi(self): r""" - Returns `\pi` to the precision of this field. + Return `\pi` to the precision of this field. EXAMPLES:: @@ -1085,7 +1087,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def euler_constant(self): """ - Returns Euler's gamma constant to the precision of this field. + Return Euler's gamma constant to the precision of this field. EXAMPLES:: @@ -1098,7 +1100,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def log2(self): r""" - Returns `\log(2)` to the precision of this field. + Return `\log(2)` to the precision of this field. EXAMPLES:: @@ -1121,7 +1123,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): INPUT: - - ``status`` -- boolean optional flag + - ``status`` -- boolean optional flag EXAMPLES:: @@ -1142,7 +1144,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): def zeta(self, n=2): """ Return an `n`-th root of unity in the real field, if one - exists, or raise a ``ValueError`` otherwise. + exists, or raise a :exc:`ValueError` otherwise. EXAMPLES:: @@ -1174,7 +1176,7 @@ cdef class RealIntervalFieldElement(RingElement): """ def __cinit__(self, parent, *args, **kwds): """ - Initialize the parent of this element and allocate memory + Initialize the parent of this element and allocate memory. TESTS:: @@ -1342,13 +1344,13 @@ cdef class RealIntervalFieldElement(RingElement): def _interface_init_(self, I=None): """ - Raise a ``TypeError``. + Raise a :exc:`TypeError`. This function would return the string representation of ``self`` that makes sense as a default representation of a real interval in other computer algebra systems. But, most other computer algebra systems do not support interval arithmetic, so instead we just raise a - ``TypeError``. + :exc:`TypeError`. Define the appropriate ``_cas_init_`` function if there is a computer algebra system you would like to support. @@ -1483,19 +1485,19 @@ cdef class RealIntervalFieldElement(RingElement): INPUT: - - ``base`` -- base for output + - ``base`` -- base for output - - ``style`` -- The printing style; either ``'brackets'`` or - ``'question'`` (or ``None``, to use the current default). + - ``style`` -- the printing style; either ``'brackets'`` or + ``'question'`` (or ``None``, to use the current default) - - ``no_sci`` -- if ``True`` do not print using scientific - notation; if ``False`` print with scientific notation; if ``None`` - (the default), print how the parent prints. + - ``no_sci`` -- if ``True`` do not print using scientific + notation; if ``False`` print with scientific notation; if ``None`` + (the default), print how the parent prints. - - ``e`` -- symbol used in scientific notation + - ``e`` -- symbol used in scientific notation - - ``error_digits`` -- The number of digits of error to - print, in ``'question'`` style. + - ``error_digits`` -- the number of digits of error to + print, in ``'question'`` style We support two different styles of printing; ``'question'`` style and ``'brackets'`` style. In question style (the default), we print the @@ -1854,7 +1856,6 @@ cdef class RealIntervalFieldElement(RingElement): sage: v = RIF(1.0 >> -mpfr_get_exp_min()+1); v 2.3825649048879511?e-323228497 # 32-bit 8.5096913117408362?e-1388255822130839284 # 64-bit - """ if not(mpfr_number_p(&self.value.left) and mpfr_number_p(&self.value.right)): raise ValueError("_str_question_style on NaN or infinity") @@ -2205,7 +2206,7 @@ cdef class RealIntervalFieldElement(RingElement): # Interval-specific functions def lower(self, rnd=None): """ - Return the lower bound of this interval + Return the lower bound of this interval. INPUT: @@ -2256,7 +2257,7 @@ cdef class RealIntervalFieldElement(RingElement): def upper(self, rnd=None): """ - Return the upper bound of ``self`` + Return the upper bound of ``self``. INPUT: @@ -2432,7 +2433,7 @@ cdef class RealIntervalFieldElement(RingElement): def fp_rank_diameter(self): r""" - Computes the diameter of this interval in terms of the + Compute the diameter of this interval in terms of the "floating-point rank". The floating-point rank is the number of floating-point numbers (of @@ -2547,7 +2548,7 @@ cdef class RealIntervalFieldElement(RingElement): def bisection(self): """ - Returns the bisection of ``self`` into two intervals of half the size + Return the bisection of ``self`` into two intervals of half the size whose union is ``self`` and intersection is :meth:`center()`. EXAMPLES:: @@ -2915,7 +2916,7 @@ cdef class RealIntervalFieldElement(RingElement): def __lshift__(x, y): """ - Returns `x * 2^y`, for `y` an integer. Much faster + Return `x * 2^y`, for `y` an integer. Much faster than an ordinary multiplication. EXAMPLES:: @@ -2983,7 +2984,7 @@ cdef class RealIntervalFieldElement(RingElement): def precision(self): """ - Returns the precision of ``self``. + Return the precision of ``self``. EXAMPLES:: @@ -2997,12 +2998,12 @@ cdef class RealIntervalFieldElement(RingElement): prec = precision ################### - # Rounding etc + # Rounding etc. ################### def floor(self): """ - Return the floor of this interval as an interval + Return the floor of this interval as an interval. The floor of a real number `x` is the largest integer smaller than or equal to `x`. @@ -3010,7 +3011,7 @@ cdef class RealIntervalFieldElement(RingElement): .. SEEALSO:: - :meth:`unique_floor` -- method which returns the floor as an integer - if it is unique or raises a ``ValueError`` otherwise. + if it is unique or raises a :exc:`ValueError` otherwise - :meth:`ceil` -- truncation towards plus infinity - :meth:`round` -- rounding - :meth:`trunc` -- truncation towards zero @@ -3040,7 +3041,7 @@ cdef class RealIntervalFieldElement(RingElement): def ceil(self): """ - Return the ceiling of this interval as an interval + Return the ceiling of this interval as an interval. The ceiling of a real number `x` is the smallest integer larger than or equal to `x`. @@ -3048,7 +3049,7 @@ cdef class RealIntervalFieldElement(RingElement): .. SEEALSO:: - :meth:`unique_ceil` -- return the ceil as an integer if it is - unique and raises a ``ValueError`` otherwise + unique and raises a :exc:`ValueError` otherwise - :meth:`floor` -- truncation towards minus infinity - :meth:`trunc` -- truncation towards zero - :meth:`round` -- rounding @@ -3077,12 +3078,12 @@ cdef class RealIntervalFieldElement(RingElement): def round(self): r""" - Return the nearest integer of this interval as an interval + Return the nearest integer of this interval as an interval. .. SEEALSO:: - :meth:`unique_round` -- return the round as an integer if it is - unique and raises a ``ValueError`` otherwise + unique and raises a :exc:`ValueError` otherwise - :meth:`floor` -- truncation towards `-\infty` - :meth:`ceil` -- truncation towards `+\infty` - :meth:`trunc` -- truncation towards `0` @@ -3114,15 +3115,15 @@ cdef class RealIntervalFieldElement(RingElement): def trunc(self): r""" - Return the truncation of this interval as an interval + Return the truncation of this interval as an interval. - The truncation of `x` is the floor of `x` if `x` is non-negative or the + The truncation of `x` is the floor of `x` if `x` is nonnegative or the ceil of `x` if `x` is negative. .. SEEALSO:: - :meth:`unique_trunc` -- return the trunc as an integer if it is - unique and raises a ``ValueError`` otherwise + unique and raises a :exc:`ValueError` otherwise - :meth:`floor` -- truncation towards `-\infty` - :meth:`ceil` -- truncation towards `+\infty` - :meth:`round` -- rounding @@ -3300,7 +3301,7 @@ cdef class RealIntervalFieldElement(RingElement): This method returns `+1` if all elements in this interval are positive, `-1` if all of them are negative and `0` if it contains only zero. - Otherwise it raises a :class:`ValueError`. + Otherwise it raises a :exc:`ValueError`. EXAMPLES:: @@ -3335,7 +3336,7 @@ cdef class RealIntervalFieldElement(RingElement): def argument(self): r""" The argument of this interval, if it is well-defined, in the - complex sense. Otherwise raises a :class:`ValueError`. + complex sense. Otherwise raises a :exc:`ValueError`. OUTPUT: @@ -3359,7 +3360,6 @@ cdef class RealIntervalFieldElement(RingElement): Traceback (most recent call last): ... ValueError: Can't take the argument of interval strictly containing zero - """ k=self.parent() if mpfi_is_zero(self.value): @@ -3374,9 +3374,9 @@ cdef class RealIntervalFieldElement(RingElement): def unique_floor(self): """ Return the unique floor of this interval, if it is well defined, - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. - OUTPUT: an integer. + OUTPUT: integer .. SEEALSO:: @@ -3403,9 +3403,9 @@ cdef class RealIntervalFieldElement(RingElement): def unique_ceil(self): """ Return the unique ceiling of this interval, if it is well defined, - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. - OUTPUT: an integer. + OUTPUT: integer .. SEEALSO:: @@ -3432,9 +3432,9 @@ cdef class RealIntervalFieldElement(RingElement): def unique_round(self): """ Return the unique round (nearest integer) of this interval, - if it is well defined, otherwise raise a :class:`ValueError`. + if it is well defined, otherwise raise a :exc:`ValueError`. - OUTPUT: an integer. + OUTPUT: integer .. SEEALSO:: @@ -3494,7 +3494,7 @@ cdef class RealIntervalFieldElement(RingElement): def unique_trunc(self): r""" Return the nearest integer toward zero if it is unique, otherwise raise - a :class:`ValueError`. + a :exc:`ValueError`. .. SEEALSO:: @@ -3526,7 +3526,7 @@ cdef class RealIntervalFieldElement(RingElement): def unique_integer(self): """ Return the unique integer in this interval, if there is exactly one, - otherwise raise a :class:`ValueError`. + otherwise raise a :exc:`ValueError`. EXAMPLES:: @@ -3657,7 +3657,7 @@ cdef class RealIntervalFieldElement(RingElement): cdef Rational _simplest_rational_helper(self): """ - Returns the simplest rational in an interval which is either equal + Return the simplest rational in an interval which is either equal to or slightly larger than ``self``. We assume that both endpoints of ``self`` are nonnegative. """ @@ -4031,7 +4031,7 @@ cdef class RealIntervalFieldElement(RingElement): def overlaps(self, RealIntervalFieldElement other): """ - Return ``True`` if ``self`` and other are intervals with at least one + Return ``True`` if ``self`` and ``other`` are intervals with at least one value in common. For intervals ``a`` and ``b``, we have ``a.overlaps(b)`` iff ``not(a!=b)``. @@ -4056,7 +4056,7 @@ cdef class RealIntervalFieldElement(RingElement): def intersection(self, other): """ Return the intersection of two intervals. If the intervals do not - overlap, raises a ``ValueError``. + overlap, raises a :exc:`ValueError`. EXAMPLES:: @@ -4519,7 +4519,7 @@ cdef class RealIntervalFieldElement(RingElement): def exp(self): r""" - Returns `e^\mathtt{self}` + Return `e^\mathtt{self}`. EXAMPLES:: @@ -4549,7 +4549,7 @@ cdef class RealIntervalFieldElement(RingElement): def exp2(self): r""" - Returns `2^\mathtt{self}` + Return `2^\mathtt{self}`. EXAMPLES:: @@ -4577,7 +4577,7 @@ cdef class RealIntervalFieldElement(RingElement): def is_int(self): r""" - Checks to see whether this interval includes exactly one integer. + Check to see whether this interval includes exactly one integer. OUTPUT: @@ -4980,7 +4980,7 @@ cdef class RealIntervalFieldElement(RingElement): def algdep(self, n): r""" - Returns a polynomial of degree at most `n` which is + Return a polynomial of degree at most `n` which is approximately satisfied by ``self``. .. NOTE:: @@ -5135,13 +5135,7 @@ cdef class RealIntervalFieldElement(RingElement): """ Return the digamma function evaluated on ``self``. - INPUT: - - None. - - OUTPUT: - - A :class:`RealIntervalFieldElement`. + OUTPUT: a :class:`RealIntervalFieldElement` EXAMPLES:: @@ -5192,7 +5186,7 @@ cdef _simplest_rational_exact(Rational low, Rational high, int low_open, int hig """ Return the simplest rational between ``low`` and ``high``. May return ``low`` or ``high`` unless ``low_open`` or ``high_open`` (respectively) are - ``True`` (non-zero). We assume that ``low`` and ``high`` are both + ``True`` (nonzero). We assume that ``low`` and ``high`` are both nonnegative, and that ``high > low``. This is a helper function for @@ -5264,19 +5258,18 @@ def RealInterval(s, upper=None, int base=10, int pad=0, min_prec=53): INPUT: - - ``s`` -- a string that defines a real number (or - something whose string representation defines a number) + - ``s`` -- string that defines a real number (or + something whose string representation defines a number) - - ``upper`` -- (default: ``None``); upper endpoint of - interval if given, in which case ``s`` is the lower endpoint + - ``upper`` -- (default: ``None``) upper endpoint of + interval if given, in which case ``s`` is the lower endpoint - - ``base`` -- an integer between 2 and 36 + - ``base`` -- integer between 2 and 36 - - ``pad`` -- (default: 0) an integer - - - ``min_prec`` -- number will have at least this many - bits of precision, no matter what + - ``pad`` -- integer (default: 0) + - ``min_prec`` -- number will have at least this many + bits of precision, no matter what EXAMPLES:: @@ -5306,7 +5299,6 @@ def RealInterval(s, upper=None, int base=10, int pad=0, min_prec=53): ....: assert len(str(z))-4 >= k ....: except TypeError: ....: pass - """ if not isinstance(s, str): s = str(s) diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 9e905c9c721..7e1ab748b55 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -386,17 +386,17 @@ cpdef RealField(mpfr_prec_t prec=53, int sci_not=0, rnd=MPFR_RNDN): INPUT: - - ``prec`` -- (integer) precision; default = 53 prec is + - ``prec`` -- integer (default: 53); precision ``prec`` is the number of bits used to represent the mantissa of a floating-point number. The precision can be any integer between :func:`mpfr_prec_min()` and :func:`mpfr_prec_max()`. In the current implementation, :func:`mpfr_prec_min()` is equal to 2. - - ``sci_not`` -- (default: ``False``) if ``True``, always display using - scientific notation; if ``False``, display using scientific notation - only for very large or very small numbers + - ``sci_not`` -- boolean (default: ``False``); if ``True``, always display + using scientific notation. If ``False``, display using scientific + notation only for very large or very small numbers. - - ``rnd`` -- (string) the rounding mode: + - ``rnd`` -- string; the rounding mode: - ``'RNDN'`` -- (default) round to nearest (ties go to the even number): Knuth says this is the best choice to prevent "floating @@ -966,7 +966,7 @@ cdef class RealField_class(sage.rings.abc.RealField): def characteristic(self): """ - Returns 0, since the field of real numbers has characteristic 0. + Return 0, since the field of real numbers has characteristic 0. EXAMPLES:: @@ -991,7 +991,7 @@ cdef class RealField_class(sage.rings.abc.RealField): def __hash__(self): """ - Returns a hash function of the field, which takes into account + Return a hash function of the field, which takes into account the precision and rounding convention. EXAMPLES:: @@ -1088,7 +1088,7 @@ cdef class RealField_class(sage.rings.abc.RealField): def euler_constant(self): """ - Returns Euler's gamma constant to the precision of this field. + Return Euler's gamma constant to the precision of this field. EXAMPLES:: @@ -1104,7 +1104,7 @@ cdef class RealField_class(sage.rings.abc.RealField): def catalan_constant(self): """ - Returns Catalan's constant to the precision of this field. + Return Catalan's constant to the precision of this field. EXAMPLES:: @@ -1238,7 +1238,7 @@ cdef class RealField_class(sage.rings.abc.RealField): INPUT: - - ``status`` -- boolean optional flag + - ``status`` -- boolean optional flag EXAMPLES:: @@ -1268,7 +1268,7 @@ cdef class RealField_class(sage.rings.abc.RealField): def zeta(self, n=2): """ Return an `n`-th root of unity in the real field, if one - exists, or raise a ``ValueError`` otherwise. + exists, or raise a :exc:`ValueError` otherwise. EXAMPLES:: @@ -1327,7 +1327,6 @@ cdef class RealField_class(sage.rings.abc.RealField): (x - 1.0000000000000000000000000000)^3 sage: k._factor_univariate_polynomial( x^2 - 3 ) (x - 1.7320508075688772935274463415) * (x + 1.7320508075688772935274463415) - """ R = f.parent() F = list(f._pari_with_name().factor()) @@ -1358,7 +1357,7 @@ cdef class RealNumber(sage.structure.element.RingElement): """ def __cinit__(self, parent, x=None, base=None): """ - Initialize the parent of this element and allocate memory + Initialize the parent of this element and allocate memory. TESTS:: @@ -1800,7 +1799,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def __hash__(self): """ - Returns the hash of self, which coincides with the python float + Return the hash of self, which coincides with the Python float (and often int) type. This has the drawback that two very close high precision numbers @@ -1872,8 +1871,8 @@ cdef class RealNumber(sage.structure.element.RingElement): - ``base`` -- (default: 10) base for output - - ``digits`` -- (default: 0) number of digits to display. When - ``digits`` is zero, choose this automatically. + - ``digits`` -- (default: 0) number of digits to display; when + ``digits`` is zero, choose this automatically - ``no_sci`` -- if 2, never print using scientific notation; if ``True``, use scientific notation only for large or small @@ -1883,12 +1882,12 @@ cdef class RealNumber(sage.structure.element.RingElement): - ``e`` -- symbol used in scientific notation; defaults to 'e' for base=10, and '@' otherwise - - ``truncate`` -- (default: ``False``) if ``True``, round off the + - ``truncate`` -- boolean (default: ``False``); if ``True``, round off the last digits in base-10 printing to lessen confusing base-2 roundoff issues. This flag may not be used in other bases or when ``digits`` is given. - - ``skip_zeroes`` -- (default: ``False``) if ``True``, skip + - ``skip_zeroes`` -- boolean (default: ``False``); if ``True``, skip trailing zeroes in mantissa EXAMPLES:: @@ -2244,7 +2243,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def fp_rank(self): r""" - Returns the floating-point rank of this number. That is, if you + Return the floating-point rank of this number. That is, if you list the floating-point numbers of this precision in order, and number them starting with `0.0 \rightarrow 0` and extending the list to positive and negative infinity, returns the number @@ -2559,7 +2558,7 @@ cdef class RealNumber(sage.structure.element.RingElement): cpdef _div_(self, right): """ - Divide ``self`` by other, where both are real numbers with the same + Divide ``self`` by ``other``, where both are real numbers with the same parent. EXAMPLES:: @@ -2773,7 +2772,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def ulp(self, field=None): """ - Returns the unit of least precision of ``self``, which is the + Return the unit of least precision of ``self``, which is the weight of the least significant bit of ``self``. This is always a strictly positive number. It is also the gap between this number and the closest number with larger absolute value that @@ -2781,8 +2780,8 @@ cdef class RealNumber(sage.structure.element.RingElement): INPUT: - - ``field`` -- :class:`RealField` used as parent of the result. - If not specified, use ``parent(self)``. + - ``field`` -- :class:`RealField` used as parent of the result; + if not specified, use ``parent(self)`` .. NOTE:: @@ -2813,7 +2812,7 @@ cdef class RealNumber(sage.structure.element.RingElement): sage: (a+b)/2 in [a,b] True - The ulp of zero is the smallest non-zero number:: + The ulp of zero is the smallest nonzero number:: sage: a = RR(0).ulp() sage: a @@ -2823,7 +2822,7 @@ cdef class RealNumber(sage.structure.element.RingElement): 1 The ulp of very small numbers results in underflow, so the - smallest non-zero number is returned instead:: + smallest nonzero number is returned instead:: sage: a.ulp() == a True @@ -2885,7 +2884,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def epsilon(self, field=None): """ - Returns ``abs(self)`` divided by `2^b` where `b` is the + Return ``abs(self)`` divided by `2^b` where `b` is the precision in bits of ``self``. Equivalently, return ``abs(self)`` multiplied by the :meth:`ulp` of 1. @@ -2895,8 +2894,8 @@ cdef class RealNumber(sage.structure.element.RingElement): INPUT: - - ``field`` -- :class:`RealField` used as parent of the result. - If not specified, use ``parent(self)``. + - ``field`` -- :class:`RealField` used as parent of the result + If not specified, use ``parent(self)`` OUTPUT: @@ -2959,7 +2958,7 @@ cdef class RealNumber(sage.structure.element.RingElement): return x ################### - # Rounding etc + # Rounding etc. ################### cpdef _mod_(left, right): @@ -3286,7 +3285,6 @@ cdef class RealNumber(sage.structure.element.RingElement): 3.1415926535 8979323846 26433833 sage: fricas(R(pi)) # optional - fricas 3.1415926535_8979323846_26433833 - """ prec = self.parent().prec() @@ -3445,7 +3443,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def exact_rational(self): """ - Returns the exact rational representation of this floating-point + Return the exact rational representation of this floating-point number. EXAMPLES:: @@ -4164,12 +4162,12 @@ cdef class RealNumber(sage.structure.element.RingElement): INPUT: - - ``extend`` -- bool (default: ``True``); if ``True``, return a - square root in a complex field if necessary if ``self`` is negative; - otherwise raise a ``ValueError`` + - ``extend`` -- boolean (default: ``True``); if ``True``, return a + square root in a complex field if necessary if ``self`` is negative. + Otherwise raise a :exc:`ValueError`. - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots EXAMPLES:: @@ -4227,7 +4225,7 @@ cdef class RealNumber(sage.structure.element.RingElement): """ Return whether or not this number is a square in this field. For the real numbers, this is ``True`` if and only if ``self`` is - non-negative. + nonnegative. EXAMPLES:: @@ -4387,7 +4385,6 @@ cdef class RealNumber(sage.structure.element.RingElement): sage: r = R(NaN); r.log() # needs sage.symbolic NaN - """ if mpfr_nan_p(self.value): return self @@ -4658,7 +4655,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def eint(self): """ - Returns the exponential integral of this number. + Return the exponential integral of this number. EXAMPLES:: @@ -4967,7 +4964,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def sec(self): """ - Returns the secant of this number + Return the secant of this number. EXAMPLES:: @@ -5049,9 +5046,7 @@ cdef class RealNumber(sage.structure.element.RingElement): - ``right`` -- another real number - OUTPUT: - - - the AGM of ``self`` and ``other`` + OUTPUT: the AGM of ``self`` and ``other`` EXAMPLES:: @@ -5304,7 +5299,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def zeta(self): r""" - Return the Riemann zeta function evaluated at this real number + Return the Riemann zeta function evaluated at this real number. .. NOTE:: @@ -5381,18 +5376,16 @@ cdef class RealNumber(sage.structure.element.RingElement): def nth_root(self, int n, int algorithm=0): r""" - Return an `n^{th}` root of ``self``. + Return an `n`-th root of ``self``. INPUT: - - ``n`` -- A positive number, rounded down to the - nearest integer. Note that `n` should be less than - ```sys.maxsize```. + - ``n`` -- a positive number, rounded down to the nearest integer; + note that `n` should be less than ``sys.maxsize`` - - ``algorithm`` -- Set this to 1 to call mpfr directly, - set this to 2 to use interval arithmetic and logarithms, or leave - it at the default of 0 to choose the algorithm which is estimated - to be faster. + - ``algorithm`` -- set this to 1 to call mpfr directly, set this to 2 + to use interval arithmetic and logarithms, or leave it at the default + of 0 to choose the algorithm which is estimated to be faster AUTHORS: @@ -5437,7 +5430,7 @@ cdef class RealNumber(sage.structure.element.RingElement): ... ValueError: taking an even root of a negative number - The `n^{th}` root of 0 is defined to be 0, for any `n`:: + The `n`-th root of 0 is defined to be 0, for any `n`:: sage: R(0).nth_root(6) 0.000000000000000 @@ -5712,9 +5705,7 @@ cdef class RealLiteral(RealNumber): If neither ``prec`` nor ``digits`` is given, the default precision is 53 bits (roughly 16 digits). - OUTPUT: - - A ``RealNumber`` with the given precision. + OUTPUT: a ``RealNumber`` with the given precision EXAMPLES:: @@ -5749,7 +5740,7 @@ RR = RealField() RR_min_prec = RealField(MPFR_PREC_MIN) -def create_RealNumber(s, int base=10, int pad=0, rnd="RNDN", int min_prec=53): +def create_RealNumber(s, int base=10, int pad=0, rnd='RNDN', int min_prec=53): r""" Return the real number defined by the string ``s`` as an element of ``RealField(prec=n)``, where ``n`` potentially has slightly @@ -5757,12 +5748,12 @@ def create_RealNumber(s, int base=10, int pad=0, rnd="RNDN", int min_prec=53): INPUT: - - ``s`` -- a string that defines a real number (or + - ``s`` -- string that defines a real number (or something whose string representation defines a number) - - ``base`` -- an integer between 2 and 62 + - ``base`` -- integer between 2 and 62 - - ``pad`` -- an integer >= 0. + - ``pad`` -- nonnegative integer - ``rnd`` -- rounding mode: @@ -5772,7 +5763,7 @@ def create_RealNumber(s, int base=10, int pad=0, rnd="RNDN", int min_prec=53): - ``'RNDU'`` -- round up - ``min_prec`` -- number will have at least this many - bits of precision, no matter what. + bits of precision, no matter what EXAMPLES:: @@ -5803,7 +5794,7 @@ def create_RealNumber(s, int base=10, int pad=0, rnd="RNDN", int min_prec=53): 14070.0000000000 sage: RealNumber("aaa", base=37) 50652.0000000000 - sage: RealNumber("3.4", base="foo") + sage: RealNumber("3.4", base='foo') Traceback (most recent call last): ... TypeError: an integer is required @@ -6011,7 +6002,7 @@ cdef class QQtoRR(Map): cdef class double_toRR(Map): cpdef Element _call_(self, x): """ - Takes anything that can be converted to a double. + Take anything that can be converted to a double. EXAMPLES:: @@ -6031,7 +6022,7 @@ cdef class double_toRR(Map): cdef class int_toRR(Map): cpdef Element _call_(self, x): """ - Takes Python int/long instances. + Take Python int/long instances. EXAMPLES:: diff --git a/src/sage/rings/ring.pxd b/src/sage/rings/ring.pxd index 726f571161f..7f09fd80e87 100644 --- a/src/sage/rings/ring.pxd +++ b/src/sage/rings/ring.pxd @@ -6,9 +6,6 @@ cpdef bint _is_Field(x) except -2 cdef class Ring(ParentWithGens): cdef public object _zero_element cdef public object _one_element - cdef public object _zero_ideal - cdef public object _unit_ideal - cdef public object _ideal_monoid cdef class CommutativeRing(Ring): diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index d546fca961b..17d0150357d 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -18,10 +18,10 @@ The class inheritance hierarchy is: - :class:`Ring` (to be deprecated) - - :class:`Algebra` (to be deprecated) + - :class:`Algebra` (deprecated and essentially removed) - :class:`CommutativeRing` - - :class:`NoetherianRing` (deprecated) + - :class:`NoetherianRing` (deprecated and essentially removed) - :class:`CommutativeAlgebra` (deprecated and essentially removed) - :class:`IntegralDomain` (deprecated) @@ -70,12 +70,12 @@ This is to test a deprecation:: sage: from sage.rings.ring import CommutativeAlgebra sage: class Nein(CommutativeAlgebra): ....: pass - sage: F = Nein(QQ, QQ) + sage: F = Nein(QQ) ...: DeprecationWarning: use the category CommutativeAlgebras See https://github.com/sagemath/sage/issues/37999 for details. sage: F.category() - Category of commutative rings + Category of commutative algebras over Rational Field sage: from sage.rings.ring import PrincipalIdealDomain sage: class Non(PrincipalIdealDomain): @@ -86,6 +86,17 @@ This is to test a deprecation:: See https://github.com/sagemath/sage/issues/37719 for details. sage: F.category() Category of principal ideal domains + + sage: from sage.rings.ring import Algebra + sage: class Nichts(Algebra): + ....: pass + sage: F = Nichts(QQ) + ...: + DeprecationWarning: use the category Algebras + See https://github.com/sagemath/sage/issues/38502 for details. + sage: F.category() + Category of algebras over Rational Field + """ # **************************************************************************** @@ -105,6 +116,8 @@ from sage.structure.parent cimport Parent from sage.structure.category_object cimport check_default_category from sage.misc.prandom import randint from sage.categories.rings import Rings +from sage.categories.algebras import Algebras +from sage.categories.commutative_algebras import CommutativeAlgebras from sage.categories.commutative_rings import CommutativeRings from sage.categories.integral_domains import IntegralDomains from sage.categories.dedekind_domains import DedekindDomains @@ -142,6 +155,7 @@ cdef class Ring(ParentWithGens): Running the test suite of self.an_element() running ._test_category() . . . pass running ._test_eq() . . . pass + running ._test_monomial_coefficients() . . . pass running ._test_new() . . . pass running ._test_nonzero_equal() . . . pass running ._test_not_implemented_methods() . . . pass @@ -171,20 +185,29 @@ cdef class Ring(ParentWithGens): Test against another bug fixed in :issue:`9944`:: sage: QQ['x'].category() - Join of Category of euclidean domains and Category of commutative algebras over - (number fields and quotient fields and metric spaces) and Category of infinite sets + Join of Category of euclidean domains + and Category of algebras with basis + over (number fields and quotient fields and metric spaces) + and Category of commutative algebras + over (number fields and quotient fields and metric spaces) + and Category of infinite sets sage: QQ['x','y'].category() Join of Category of unique factorization domains + and Category of algebras with basis + over (number fields and quotient fields and metric spaces) and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets sage: PolynomialRing(MatrixSpace(QQ, 2),'x').category() # needs sage.modules - Category of infinite algebras over (finite dimensional algebras with basis over - (number fields and quotient fields and metric spaces) and infinite sets) + Category of infinite algebras with basis + over (finite dimensional algebras with basis + over (number fields and quotient fields and metric spaces) + and infinite sets) sage: PolynomialRing(SteenrodAlgebra(2),'x').category() # needs sage.combinat sage.modules - Category of infinite algebras over (super Hopf algebras with basis - over Finite Field of size 2 and supercocommutative super coalgebras - over Finite Field of size 2) + Category of infinite algebras with basis + over (super Hopf algebras with basis over Finite Field of size 2 + and supercocommutative super coalgebras + over Finite Field of size 2) TESTS:: @@ -256,7 +279,7 @@ cdef class Ring(ParentWithGens): def __len__(self): r""" Return the cardinality of this ring if it is finite, else raise - a ``NotImplementedError``. + a :exc:`NotImplementedError`. EXAMPLES:: @@ -338,36 +361,6 @@ cdef class Ring(ParentWithGens): # initialisation has finished. return self._category or _Rings - def ideal_monoid(self): - """ - Return the monoid of ideals of this ring. - - EXAMPLES:: - - sage: # needs sage.combinat sage.modules - sage: F. = FreeAlgebra(ZZ, 3) - sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F - sage: Q = F.quotient(I) - sage: Q.ideal_monoid() - Monoid of ideals of Quotient of Free Algebra on 3 generators (x, y, z) - over Integer Ring by the ideal (x*y + y*z, x^2 + x*y - y*x - y^2) - sage: F. = FreeAlgebra(ZZ, implementation='letterplace') - sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F - sage: Q = F.quo(I) - sage: Q.ideal_monoid() - Monoid of ideals of Quotient of Free Associative Unital Algebra - on 3 generators (x, y, z) over Integer Ring - by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) - - """ - if self._ideal_monoid is not None: - return self._ideal_monoid - else: - from sage.rings.noncommutative_ideals import IdealMonoid_nc - M = IdealMonoid_nc(self) - self._ideal_monoid = M - return M - def ideal(self, *args, **kwds): """ Return the ideal defined by ``x``, i.e., generated by ``x``. @@ -376,7 +369,7 @@ cdef class Ring(ParentWithGens): - ``*x`` -- list or tuple of generators (or several input arguments) - - ``coerce`` -- bool (default: ``True``); this must be a keyword + - ``coerce`` -- boolean (default: ``True``); this must be a keyword argument. Only set it to ``False`` if you are certain that each generator is already in the ring. @@ -502,7 +495,6 @@ cdef class Ring(ParentWithGens): Right Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis sage: A * [A.1 + A.2, A.1^2] * A Twosided Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis - """ if isinstance(self, Ring): if self.is_commutative(): @@ -541,72 +533,6 @@ cdef class Ring(ParentWithGens): else: raise TypeError("Don't know how to transform %s into an ideal of %s" % (self, x)) - def principal_ideal(self, gen, coerce=True): - """ - Return the principal ideal generated by gen. - - EXAMPLES:: - - sage: R. = ZZ[] - sage: R.principal_ideal(x+2*y) - Ideal (x + 2*y) of Multivariate Polynomial Ring in x, y over Integer Ring - """ - C = self._ideal_class_(1) - if coerce: - gen = self(gen) - return C(self, [gen]) - - def unit_ideal(self): - """ - Return the unit ideal of this ring. - - EXAMPLES:: - - sage: Zp(7).unit_ideal() # needs sage.rings.padics - Principal ideal (1 + O(7^20)) of 7-adic Ring with capped relative precision 20 - """ - if self._unit_ideal is None: - I = Ring.ideal(self, [self(1)], coerce=False) - self._unit_ideal = I - return I - return self._unit_ideal - - def zero_ideal(self): - """ - Return the zero ideal of this ring (cached). - - EXAMPLES:: - - sage: ZZ.zero_ideal() - Principal ideal (0) of Integer Ring - sage: QQ.zero_ideal() - Principal ideal (0) of Rational Field - sage: QQ['x'].zero_ideal() - Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field - - The result is cached:: - - sage: ZZ.zero_ideal() is ZZ.zero_ideal() - True - - TESTS: - - Make sure that :issue:`13644` is fixed:: - - sage: # needs sage.rings.padics - sage: K = Qp(3) - sage: R. = K[] - sage: L. = K.extension(a^2-3) - sage: L.ideal(a) - Principal ideal (1 + O(a^40)) of 3-adic Eisenstein Extension Field in a defined by a^2 - 3 - - """ - if self._zero_ideal is None: - I = Ring.ideal(self, [self.zero()], coerce=False) - self._zero_ideal = I - return I - return self._zero_ideal - def zero(self): """ Return the zero element of this ring (cached). @@ -661,15 +587,15 @@ cdef class Ring(ParentWithGens): INPUT: - - ``proof`` -- (default: ``True``) Determines what to do in unknown - cases + - ``proof`` -- boolean (default: ``True``); determines what to do in + unknown cases ALGORITHM: If the parameter ``proof`` is set to ``True``, the returned value is correct but the method might throw an error. Otherwise, if it is set - to ``False``, the method returns True if it can establish that self is - a field and False otherwise. + to ``False``, the method returns ``True`` if it can establish that + ``self`` is a field and ``False`` otherwise. EXAMPLES:: @@ -731,7 +657,7 @@ cdef class Ring(ParentWithGens): Return ``True`` if the canonical map from ``self`` to ``other`` is injective. - Raises a ``NotImplementedError`` if not known. + Raises a :exc:`NotImplementedError` if not known. EXAMPLES:: @@ -814,19 +740,17 @@ cdef class Ring(ParentWithGens): def zeta(self, n=2, all=False): """ Return a primitive ``n``-th root of unity in ``self`` if there - is one, or raise a ``ValueError`` otherwise. + is one, or raise a :exc:`ValueError` otherwise. INPUT: - ``n`` -- positive integer - - ``all`` -- bool (default: ``False``); whether to return - a list of all primitive `n`-th roots of unity. If True, raise a ``ValueError`` - if ``self`` is not an integral domain. + - ``all`` -- boolean (default: ``False``); whether to return + a list of all primitive `n`-th roots of unity. If ``True``, raise a + :exc:`ValueError` if ``self`` is not an integral domain. - OUTPUT: - - Element of ``self`` of finite order + OUTPUT: element of ``self`` of finite order EXAMPLES:: @@ -932,9 +856,9 @@ cdef class Ring(ParentWithGens): TESTS: - The following example returns a ``NotImplementedError`` since the + The following example returns a :exc:`NotImplementedError` since the generic ring class ``__call__`` function returns a - ``NotImplementedError``. Note that + :exc:`NotImplementedError`. Note that ``sage.rings.ring.Ring.random_element`` performs a call in the generic ring class by a random integer:: @@ -947,25 +871,6 @@ cdef class Ring(ParentWithGens): """ return self(randint(-bound,bound)) - def ideal_monoid(self): - """ - Return the monoid of ideals of this ring. - - EXAMPLES:: - - sage: ZZ.ideal_monoid() - Monoid of ideals of Integer Ring - sage: R.=QQ[]; R.ideal_monoid() - Monoid of ideals of Univariate Polynomial Ring in x over Rational Field - """ - if self._ideal_monoid is not None: - return self._ideal_monoid - else: - from sage.rings.ideal_monoid import IdealMonoid - M = IdealMonoid(self) - self._ideal_monoid = M - return M - @cached_method def epsilon(self): """ @@ -1188,32 +1093,14 @@ cdef class CommutativeRing(Ring): """ raise NotImplementedError - def ideal_monoid(self): - """ - Return the monoid of ideals of this ring. - - EXAMPLES:: - - sage: ZZ.ideal_monoid() - Monoid of ideals of Integer Ring - sage: R.=QQ[]; R.ideal_monoid() - Monoid of ideals of Univariate Polynomial Ring in x over Rational Field - """ - if self._ideal_monoid is not None: - return self._ideal_monoid - else: - from sage.rings.ideal_monoid import IdealMonoid - M = IdealMonoid(self) - self._ideal_monoid = M - return M - def extension(self, poly, name=None, names=None, **kwds): """ - Algebraically extends self by taking the quotient ``self[x] / (f(x))``. + Algebraically extend ``self`` by taking the quotient + ``self[x] / (f(x))``. INPUT: - - ``poly`` -- A polynomial whose coefficients are coercible into + - ``poly`` -- a polynomial whose coefficients are coercible into ``self`` - ``name`` -- (optional) name for the root of `f` @@ -1280,11 +1167,10 @@ cdef class IntegralDomain(CommutativeRing): INPUT: - - ``category`` (default: ``None``) -- a category, or ``None`` + - ``category`` -- (default: ``None``) a category, or ``None`` This method is used by all the abstract subclasses of - :class:`IntegralDomain`, like :class:`NoetherianRing`, - :class:`Field`, ... in order to + :class:`IntegralDomain`, like :class:`Field`, ... in order to avoid cascade calls Field.__init__ -> IntegralDomain.__init__ -> ... @@ -1317,7 +1203,7 @@ cdef class IntegralDomain(CommutativeRing): fractions; otherwise return ``False``. When no algorithm is implemented for this, then this - function raises a ``NotImplementedError``. + function raises a :exc:`NotImplementedError`. Note that ``is_integrally_closed`` has a naive implementation in fields. For every field `F`, `F` is its own field of fractions, @@ -1370,7 +1256,7 @@ cdef class NoetherianRing(CommutativeRing): _default_category = NoetherianRings() def __init__(self, *args, **kwds): - deprecation(37234, "use the category DedekindDomains") + deprecation(37234, "use the category NoetherianRings") super().__init__(*args, **kwds) @@ -1429,6 +1315,11 @@ _Fields = Fields() cdef class Field(CommutativeRing): """ Generic field + + TESTS:: + + sage: QQ.is_noetherian() + True """ _default_category = _Fields @@ -1548,17 +1439,6 @@ cdef class Field(CommutativeRing): """ return True - def is_noetherian(self): - """ - Return ``True`` since fields are Noetherian rings. - - EXAMPLES:: - - sage: QQ.is_noetherian() - True - """ - return True - def krull_dimension(self): """ Return the Krull dimension of this field, which is 0. @@ -1608,34 +1488,72 @@ cdef class Field(CommutativeRing): """ raise NotImplementedError("Algebraic closures of general fields not implemented.") - -cdef class Algebra(Ring): - """ - Generic algebra - """ - def __init__(self, base_ring, names=None, normalize=True, category=None): - """ - Initialize ``self``. + def an_embedding(self, K): + r""" + Return some embedding of this field into another field `K`, + and raise a :class:`ValueError` if none exists. EXAMPLES:: - sage: A = Algebra(ZZ); A # needs sage.modules - + sage: GF(2).an_embedding(GF(4)) + Ring morphism: + From: Finite Field of size 2 + To: Finite Field in z2 of size 2^2 + Defn: 1 |--> 1 + sage: GF(4).an_embedding(GF(8)) + Traceback (most recent call last): + ... + ValueError: no embedding from Finite Field in z2 of size 2^2 to Finite Field in z3 of size 2^3 + sage: GF(4).an_embedding(GF(16)) + Ring morphism: + From: Finite Field in z2 of size 2^2 + To: Finite Field in z4 of size 2^4 + Defn: z2 |--> z4^2 + z4 + + :: + + sage: CyclotomicField(5).an_embedding(QQbar) + Coercion map: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + sage: CyclotomicField(3).an_embedding(CyclotomicField(7)) + Traceback (most recent call last): + ... + ValueError: no embedding from Cyclotomic Field of order 3 and degree 2 to Cyclotomic Field of order 7 and degree 6 + sage: CyclotomicField(3).an_embedding(CyclotomicField(6)) + Generic morphism: + From: Cyclotomic Field of order 3 and degree 2 + To: Cyclotomic Field of order 6 and degree 2 + Defn: zeta3 -> zeta6 - 1 """ - # This is a low-level class. For performance, we trust that the category - # is fine, if it is provided. If it isn't, we use the category of Algebras(base_ring). - if category is None: - category = check_default_category(Algebras(base_ring), category) - Ring.__init__(self,base_ring, names=names, normalize=normalize, - category=category) + if self.characteristic() != K.characteristic(): + raise ValueError(f'no embedding from {self} to {K}: incompatible characteristics') + H = self.Hom(K) + try: + return H.natural_map() + except TypeError: + pass + from sage.categories.sets_cat import EmptySetError + try: + return H.an_element() + except EmptySetError: + raise ValueError(f'no embedding from {self} to {K}') -cdef class CommutativeAlgebra(CommutativeRing): - __default_category = _CommutativeRings +cdef class Algebra(Ring): + def __init__(self, base_ring, *args, **kwds): + if 'category' not in kwds: + kwds['category'] = Algebras(base_ring) + deprecation(38502, "use the category Algebras") + super().__init__(base_ring, *args, **kwds) + + +cdef class CommutativeAlgebra(CommutativeRing): def __init__(self, base_ring, *args, **kwds): + self._default_category = CommutativeAlgebras(base_ring) deprecation(37999, "use the category CommutativeAlgebras") - super().__init__(*args, **kwds) + super().__init__(base_ring, *args, **kwds) def is_Ring(x): @@ -1646,9 +1564,16 @@ def is_Ring(x): sage: from sage.rings.ring import is_Ring sage: is_Ring(ZZ) + doctest:warning... + DeprecationWarning: The function is_Ring is deprecated; use '... in Rings()' instead + See https://github.com/sagemath/sage/issues/38288 for details. True sage: MS = MatrixSpace(QQ, 2) # needs sage.modules sage: is_Ring(MS) # needs sage.modules True """ + from sage.misc.superseded import deprecation_cython + deprecation_cython(38288, + "The function is_Ring is deprecated; " + "use '... in Rings()' instead") return x in _Rings diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index 9c214a1ffee..174af6dd415 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -148,7 +148,7 @@ def tower_bases(ring, degree): - ``ring`` -- a commutative ring - - ``degree`` -- a boolean + - ``degree`` -- boolean EXAMPLES:: @@ -207,7 +207,7 @@ def common_base(K, L, degree): - ``L`` -- a commutative ring - - ``degree`` -- a boolean; if true, return the degree of + - ``degree`` -- boolean; if ``True``, return the degree of ``K`` and ``L`` over their common base EXAMPLES:: @@ -234,7 +234,6 @@ def common_base(K, L, degree): Traceback (most recent call last): ... NotImplementedError: unable to find a common base - """ bases_K, degrees_K = tower_bases(K, degree) bases_L, degrees_L = tower_bases(L, degree) @@ -358,13 +357,13 @@ class RingExtensionFactory(UniqueFactory): ring or ``None`` (default: ``None``); the defining morphism of this extension or its base (if it coerces to ``ring``) - - ``gens`` -- a list of generators of this extension (over its base) - or ``None`` (default: ``None``); + - ``gens`` -- list of generators of this extension (over its base) + or ``None`` (default: ``None``) - - ``names`` -- a list or a tuple of variable names or ``None`` + - ``names`` -- list or a tuple of variable names or ``None`` (default: ``None``) - - ``constructors`` -- a list of constructors; each constructor + - ``constructors`` -- list of constructors; each constructor is a pair `(class, arguments)` where `class` is the class implementing the extension and `arguments` is the dictionary of arguments to pass in to init function @@ -424,7 +423,7 @@ class RingExtensionFactory(UniqueFactory): if not isinstance(defining_morphism, RingExtensionHomomorphism): defining_morphism = RingExtensionHomomorphism(defining_morphism.parent(), defining_morphism) if isinstance(ring, RingExtension_generic): - defining_morphism = backend_morphism(defining_morphism, forget="codomain") + defining_morphism = backend_morphism(defining_morphism, forget='codomain') if (ring)._is_backend_exposed: print_as = (ring)._backend else: @@ -512,7 +511,6 @@ cdef class RingExtension_generic(CommutativeRing): sage: TestSuite(Q).run() - """ Element = RingExtensionElement @@ -524,27 +522,25 @@ cdef class RingExtension_generic(CommutativeRing): - ``defining_morphism`` -- a ring homomorphism - - ``print_options`` -- a dictionary + - ``print_options`` -- dictionary - - ``import_methods`` -- a boolean (default: ``True``); whether this + - ``import_methods`` -- boolean (default: ``True``); whether this parent (resp. its elements) import the methods of the backend parent class (resp. element class) - - ``is_backend_exposed`` -- a boolean (default: ``False``); whether + - ``is_backend_exposed`` -- boolean (default: ``False``); whether the backend ring can be exposed to the user - ``category`` -- the category for the resulting parent (default: ``CommutativeRings()``) - .. NOTE: + .. NOTE:: The attribute ``is_backend_exposed`` is only used for printing; when it is ``False``, printing an element like its backend is - disabled (and a :class:`RuntimeError` is raised when it would occur). + disabled (and a :exc:`RuntimeError` is raised when it would occur). - OUTPUT: - - The extension defined by ``defining_morphism`` + OUTPUT: the extension defined by ``defining_morphism`` EXAMPLES:: @@ -567,7 +563,6 @@ cdef class RingExtension_generic(CommutativeRing): Traceback (most recent call last): ... ValueError: exotic defining morphism between two rings in the tower; consider using another variable name - """ cdef CommutativeRing base, ring cdef CommutativeRing b, backend @@ -726,7 +721,6 @@ cdef class RingExtension_generic(CommutativeRing): sage: E = GF(5^3).over() # needs sage.rings.finite_rings sage: E.construction() # needs sage.rings.finite_rings - """ # One could define a construction functor K' -> K' otimes_K L, but we leave this to another issue pass @@ -737,7 +731,7 @@ cdef class RingExtension_generic(CommutativeRing): INPUT: - - ``force`` -- a boolean (default: ``False``); if ``False``, + - ``force`` -- boolean (default: ``False``); if ``False``, raise an error if the backend is not exposed EXAMPLES:: @@ -751,7 +745,6 @@ cdef class RingExtension_generic(CommutativeRing): Finite Field in z3 of size 5^3 sage: E.backend() is K True - """ if force or self._is_backend_exposed: return self._backend @@ -790,7 +783,7 @@ cdef class RingExtension_generic(CommutativeRing): INPUT: - - ``over`` -- an integer or ``Infinity`` (default: ``0``); the maximum + - ``over`` -- integer or ``Infinity`` (default: ``0``); the maximum number of bases included in the printing of this extension - ``base`` -- a base over which this extension is finite free; @@ -850,15 +843,13 @@ cdef class RingExtension_generic(CommutativeRing): def _print_option_over(self, over): """ - Check and normalize the print option ``over`` + Check and normalize the print option ``over``. INPUT: - - ``over`` -- an integer or ``Infinity`` + - ``over`` -- integer or ``Infinity`` - OUTPUT: - - The normalized value of ``over`` + OUTPUT: the normalized value of ``over`` TESTS:: @@ -885,10 +876,9 @@ cdef class RingExtension_generic(CommutativeRing): INPUT: - - ``over`` -- an integer, ``Infinity`` or ``None``; the maximum + - ``over`` -- integer, ``Infinity`` or ``None``; the maximum number of bases included in the print representation of - this extension; - if ``None``, use the print options of this extension. + this extension. If ``None``, use the print options of this extension. EXAMPLES:: @@ -949,10 +939,9 @@ cdef class RingExtension_generic(CommutativeRing): r""" Return a LaTeX representation of this extension. - - ``over`` -- an integer, ``Infinity`` or ``None``; the maximum + - ``over`` -- integer, ``Infinity`` or ``None``; the maximum number of bases included in the LaTeX representation of - this extension; - if ``None``, use the print options of this extension. + this extension. If ``None``, use the print options of this extension. EXAMPLES:: @@ -1016,8 +1005,8 @@ cdef class RingExtension_generic(CommutativeRing): If `L/K` is an extension, a coercion map `K \to (L/K)` (acting through the defining morphism of `L/K`) is set. - If ``L_1/K_1` and `L_2/K_2` are two extensions, a coercion - map `(L_1/K_1) \to (L_2/K_2)`` is set when `L_1` coerces to + If `L_1/K_1` and `L_2/K_2` are two extensions, a coercion + map `(L_1/K_1) \to (L_2/K_2)` is set when `L_1` coerces to `L_2` and `K_1` coerces to `K_2` in such a way that the appropriate diagram commutes. @@ -1069,7 +1058,6 @@ cdef class RingExtension_generic(CommutativeRing): False sage: B.has_coerce_map_from(A) True - """ cdef RingExtension_generic right if isinstance(other, RingExtension_generic): @@ -1254,7 +1242,6 @@ cdef class RingExtension_generic(CommutativeRing): Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base sage: L._check_base(None) is L.base() # needs sage.rings.finite_rings True - """ cdef CommutativeRing b if base is None: @@ -1323,7 +1310,6 @@ cdef class RingExtension_generic(CommutativeRing): 1/2 sage: x.parent() Rational Field over its base - """ elt = self._backend.an_element() return self.element_class(self, elt) @@ -1527,7 +1513,7 @@ cdef class RingExtension_generic(CommutativeRing): def relative_degree(self): r""" - Return the degree of this extension over its base + Return the degree of this extension over its base. EXAMPLES:: @@ -1543,7 +1529,7 @@ cdef class RingExtension_generic(CommutativeRing): def absolute_degree(self): r""" - Return the degree of this extension over its absolute base + Return the degree of this extension over its absolute base. EXAMPLES:: @@ -1692,7 +1678,7 @@ cdef class RingExtension_generic(CommutativeRing): INPUT: - - ``proof`` -- a boolean (default: ``False``) + - ``proof`` -- boolean (default: ``False``) EXAMPLES:: @@ -1718,7 +1704,7 @@ cdef class RingExtension_generic(CommutativeRing): INPUT: - - ``extend_base`` -- a boolean (default: ``False``); + - ``extend_base`` -- boolean (default: ``False``) If ``extend_base`` is ``False``, the fraction field of the extension `L/K` is defined as `\textrm{Frac}(L)/L/K`, except @@ -1793,7 +1779,7 @@ cdef class RingExtension_generic(CommutativeRing): INPUT: - - ``extend_base`` -- a boolean (default: ``False``); see + - ``extend_base`` -- boolean (default: ``False``); see :meth:`fraction_field` for more informations TESTS:: @@ -1848,7 +1834,6 @@ cdef class RingExtension_generic(CommutativeRing): to Field in z12 with defining polynomial x^6 + (4*z2 + 3)*x^5 + x^4 + (3*z2 + 1)*x^3 + x^2 + (4*z2 + 1)*x + z2 over its base in Category of sets - """ from sage.rings.ring_extension_homset import RingExtensionHomset if category.is_subcategory(CommutativeRings()): @@ -1875,7 +1860,7 @@ cdef class RingExtension_generic(CommutativeRing): - ``category`` -- the category of the resulting morphism - - ``check`` -- a boolean (default: ``True``); whether to verify that the + - ``check`` -- boolean (default: ``True``); whether to verify that the images of generators extend to define a map (using only canonical coercions) EXAMPLES:: @@ -1930,9 +1915,7 @@ cdef class RingExtension_generic(CommutativeRing): r""" Return the characteristic of the extension as a ring. - OUTPUT: - - A prime number or zero. + OUTPUT: a prime number or zero EXAMPLES:: @@ -2001,7 +1984,6 @@ cdef class RingExtensionFractionField(RingExtension_generic): sage: TestSuite(Q).run() - """ Element = RingExtensionFractionFieldElement @@ -2120,12 +2102,12 @@ cdef class RingExtensionWithBasis(RingExtension_generic): - ``defining_morphism`` -- a ring homomorphism - - ``basis`` -- a tuple of elements in this extension + - ``basis`` -- tuple of elements in this extension - - ``names`` -- a tuple of strings or ``None`` (default: ``None``); + - ``names`` -- tuple of strings or ``None`` (default: ``None``); the way the elements of the basis are printed - - ``check`` -- a boolean (default: ``True``); whether to check if + - ``check`` -- boolean (default: ``True``); whether to check if ``basis`` is indeed a basis TESTS:: @@ -2196,7 +2178,6 @@ cdef class RingExtensionWithBasis(RingExtension_generic): ... ValueError: not (explicitly) defined over Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base - """ if 'print_elements_as' in self._print_options: raise NotImplementedError("printing is handled by an external function or another parent") @@ -2351,7 +2332,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): - ``base`` -- a commutative ring (which might be itself an extension) or ``None`` (default: ``None``) - - ``map`` -- boolean (default ``True``); whether to return + - ``map`` -- boolean (default: ``True``); whether to return isomorphisms between this ring and V OUTPUT: @@ -2424,7 +2405,6 @@ cdef class RingExtensionWithBasis(RingExtension_generic): Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field in z3 of size 11^3 - """ base = self._check_base(base) return self._free_module(base, map) @@ -2440,7 +2420,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): - ``base`` -- a commutative ring (which might be itself an extension) or ``None`` (default: ``None``) - - ``map`` -- boolean (default ``True``); whether to return + - ``map`` -- boolean (default: ``True``); whether to return isomorphisms between this ring and V OUTPUT: @@ -2462,7 +2442,6 @@ cdef class RingExtensionWithBasis(RingExtension_generic): ....: V, i, j = L.free_module(base) ....: assert([i(v) for v in V.basis()] == L.basis_over(base)) ....: assert([j(x) for x in L.basis_over(base)] == V.basis()) - """ d = self._degree_over(base) if map: @@ -2477,7 +2456,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): INPUT: - - ``extend_base`` -- a boolean (default: ``False``); + - ``extend_base`` -- boolean (default: ``False``) If ``extend_base`` is ``False``, the fraction field of the extension `L/K` is defined as `\textrm{Frac}(L)/L/K`, except @@ -2567,7 +2546,6 @@ cdef class RingExtensionWithGen(RingExtensionWithBasis): sage: type(K) sage: TestSuite(K).run() - """ def __init__(self, defining_morphism, gen, names, check=True, **kwargs): r""" @@ -2579,10 +2557,10 @@ cdef class RingExtensionWithGen(RingExtensionWithBasis): - ``gen`` -- a generator of this extension - - ``names`` -- a tuple of strings or ``None`` (default: ``None``); + - ``names`` -- tuple of strings or ``None`` (default: ``None``); the way the elements of the basis are printed - - ``check`` -- a boolean (default: ``True``); whether to check if + - ``check`` -- boolean (default: ``True``); whether to check if ``gen`` is indeed a generator TESTS:: @@ -2722,7 +2700,7 @@ cdef class RingExtensionWithGen(RingExtensionWithBasis): INPUT: - - ``extend_base`` -- a boolean (default: ``False``); + - ``extend_base`` -- boolean (default: ``False``) If ``extend_base`` is ``False``, the fraction field of the extension `L/K` is defined as `\textrm{Frac}(L)/L/K`, except diff --git a/src/sage/rings/ring_extension_conversion.pyx b/src/sage/rings/ring_extension_conversion.pyx index eeb6077cd0a..482b74552c8 100644 --- a/src/sage/rings/ring_extension_conversion.pyx +++ b/src/sage/rings/ring_extension_conversion.pyx @@ -243,7 +243,7 @@ cdef _backend_morphism(f): return ring.coerce_map_from(domain) raise NotImplementedError -cpdef backend_morphism(f, forget="all"): +cpdef backend_morphism(f, forget='all'): r""" Return the backend morphism of ``f``. @@ -251,8 +251,8 @@ cpdef backend_morphism(f, forget="all"): - ``f`` -- a map - - ``forget`` -- a string, either ``all`` or ``domain`` or ``codomain`` - (default: ``all``); whether to switch to the backend for the domain, + - ``forget`` -- string; either ``'all'`` or ``'domain'`` or ``'codomain'`` + (default: ``'all'``). Whether to switch to the backend for the domain, the codomain or both of them. EXAMPLES:: @@ -269,13 +269,13 @@ cpdef backend_morphism(f, forget="all"): Ring endomorphism of Finite Field in z3 of size 7^3 Defn: z3 |--> 3*z3^2 + 5*z3 - sage: backend_morphism(f, forget="domain") + sage: backend_morphism(f, forget='domain') Ring morphism: From: Finite Field in z3 of size 7^3 To: Field in a with defining polynomial x^3 + 6*x^2 + 4 over its base Defn: z3 |--> 5*a + 3*a^2 - sage: backend_morphism(f, forget="codomain") + sage: backend_morphism(f, forget='codomain') Ring morphism: From: Field in a with defining polynomial x^3 + 6*x^2 + 4 over its base To: Finite Field in z3 of size 7^3 diff --git a/src/sage/rings/ring_extension_element.pyx b/src/sage/rings/ring_extension_element.pyx index 729793d3bfa..67b6aa90879 100644 --- a/src/sage/rings/ring_extension_element.pyx +++ b/src/sage/rings/ring_extension_element.pyx @@ -46,7 +46,6 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): sage: K = GF(5^4).over() # needs sage.rings.finite_rings sage: x = K.random_element() # needs sage.rings.finite_rings sage: TestSuite(x).run() # needs sage.rings.finite_rings - """ def __init__(self, RingExtension_generic parent, x, *args, **kwds): r""" @@ -274,7 +273,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): INPUT: - - ``force`` -- a boolean (default: ``False``); if ``False``, + - ``force`` -- boolean (default: ``False``); if ``False``, raise an error if the backend is not exposed EXAMPLES:: @@ -290,7 +289,6 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): 4*z4^3 + 2*z4^2 + 4*z4 + 4 sage: y.parent() Finite Field in z4 of size 5^4 - """ if force or ((self._parent))._is_backend_exposed: return self._backend @@ -341,7 +339,6 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): sage: x = 4*v^7 + v^6 + 3*v^4 + v^3 + v^2 + 4 sage: x.in_base() u - """ cdef RingExtension_generic parent = self._parent if isinstance(parent, RingExtensionWithGen): @@ -572,7 +569,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): INPUT: - - ``root`` -- a boolean (default: ``False``); if ``True``, + - ``root`` -- boolean (default: ``False``); if ``True``, return also a square root EXAMPLES:: @@ -604,16 +601,16 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): INPUT: - - ``extend`` -- a boolean (default: ``True``); if "True", + - ``extend`` -- boolean (default: ``True``); if ``True``, return a square root in an extension ring, if necessary. - Otherwise, raise a :class:`ValueError` if the root is not in - the ring + Otherwise, raise a :exc:`ValueError` if the root is not in + the ring. - - ``all`` -- a boolean (default: ``False``); if ``True``, - return all square roots of this element, instead of just one. + - ``all`` -- boolean (default: ``False``); if ``True``, + return all square roots of this element, instead of just one - - ``name`` -- Required when ``extend=True`` and ``self`` is not a - square. This will be the name of the generator extension. + - ``name`` -- required when ``extend=True`` and ``self`` is not a + square; this will be the name of the generator extension .. NOTE:: diff --git a/src/sage/rings/ring_extension_morphism.pyx b/src/sage/rings/ring_extension_morphism.pyx index 7a870e80182..2768bdac81c 100644 --- a/src/sage/rings/ring_extension_morphism.pyx +++ b/src/sage/rings/ring_extension_morphism.pyx @@ -108,7 +108,7 @@ cdef class RingExtensionHomomorphism(RingMap): the action of this morphism on one of the bases of the domain; if ``None``, a coercion map is used - - ``check`` -- a boolean (default: ``True``); whether to check if + - ``check`` -- boolean (default: ``True``); whether to check if the given data define a valid homomorphism TESTS:: @@ -293,7 +293,6 @@ cdef class RingExtensionHomomorphism(RingMap): Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> 2 + 2*a*b + (2 - a)*b^2 sage: phi.base_map() # needs sage.rings.finite_rings - """ domain = self.domain() codomain = self.codomain() @@ -634,7 +633,6 @@ cdef class RingExtensionBackendReverseIsomorphism(RingExtensionHomomorphism): sage: type(f) sage: TestSuite(f).run() - """ def __init__(self, parent): r""" @@ -717,7 +715,6 @@ cdef class MapFreeModuleToRelativeRing(Map): sage: V, i, j = K.free_module() # needs sage.rings.finite_rings sage: type(i) # needs sage.rings.finite_rings - """ def __init__(self, E, K): r""" @@ -740,7 +737,7 @@ cdef class MapFreeModuleToRelativeRing(Map): """ self._degree = E.degree(K) self._basis = [ (x)._backend for x in E.basis_over(K) ] - self._f = backend_morphism(E.defining_morphism(K), forget="codomain") + self._f = backend_morphism(E.defining_morphism(K), forget='codomain') domain = K ** self._degree parent = domain.Hom(E) Map.__init__(self, parent) @@ -804,7 +801,6 @@ cdef class MapRelativeRingToFreeModule(Map): sage: V, i, j = K.free_module() # needs sage.rings.finite_rings sage: type(j) # needs sage.rings.finite_rings - """ def __init__(self, E, K): r""" @@ -829,7 +825,7 @@ cdef class MapRelativeRingToFreeModule(Map): self._degree = (E)._degree_over(K) self._basis = [ (x)._backend for x in E.basis_over(K) ] - f = backend_morphism(E.defining_morphism(K), forget="codomain") + f = backend_morphism(E.defining_morphism(K), forget='codomain') codomain = K ** self._degree Map.__init__(self, E.Hom(codomain)) diff --git a/src/sage/rings/semirings/meson.build b/src/sage/rings/semirings/meson.build new file mode 100644 index 00000000000..e1e4e627ba3 --- /dev/null +++ b/src/sage/rings/semirings/meson.build @@ -0,0 +1,22 @@ +py.install_sources( + 'all.py', + 'non_negative_integer_semiring.py', + 'tropical_mpolynomial.py', + 'tropical_polynomial.py', + 'tropical_variety.py', + subdir: 'sage/rings/semirings', +) + +extension_data = {'tropical_semiring' : files('tropical_semiring.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/rings/semirings', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/rings/semirings/non_negative_integer_semiring.py b/src/sage/rings/semirings/non_negative_integer_semiring.py index 1c01fc47eb5..4fc0309a44d 100644 --- a/src/sage/rings/semirings/non_negative_integer_semiring.py +++ b/src/sage/rings/semirings/non_negative_integer_semiring.py @@ -1,21 +1,22 @@ r""" Non Negative Integer Semiring """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Nicolas Borie # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.sets.non_negative_integers import NonNegativeIntegers from sage.categories.semirings import Semirings from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.sets.family import Family + class NonNegativeIntegerSemiring(NonNegativeIntegers): r""" - A class for the semiring of the non negative integers + A class for the semiring of the nonnegative integers. This parent inherits from the infinite enumerated set of non negative integers and endows it with its natural semiring @@ -58,7 +59,6 @@ class NonNegativeIntegerSemiring(NonNegativeIntegers): Integer Ring sage: x+3 18 - """ def __init__(self): r""" @@ -70,9 +70,10 @@ def __init__(self): Category of facade infinite enumerated commutative semirings sage: TestSuite(NN).run() """ - NonNegativeIntegers.__init__(self, category=(Semirings().Commutative(), InfiniteEnumeratedSets()) ) + NonNegativeIntegers.__init__(self, category=(Semirings().Commutative(), + InfiniteEnumeratedSets())) - def _repr_(self): + def _repr_(self) -> str: r""" EXAMPLES:: @@ -83,7 +84,7 @@ def _repr_(self): def additive_semigroup_generators(self): r""" - Returns the additive semigroup generators of ``self``. + Return the additive semigroup generators of ``self``. EXAMPLES:: diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py new file mode 100644 index 00000000000..d8df667530b --- /dev/null +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -0,0 +1,691 @@ +r""" +Multivariate Tropical Polynomials + +AUTHORS: + +- Verrel Rievaldo Wijaya (2024-06): initial version + +EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: z.parent() + Multivariate Tropical Polynomial Semiring in x, y, z over Rational Field + sage: R(2)*x + R(-1)*x + R(5)*y + R(-3) + (-1)*x + 5*y + (-3) + sage: (x+y+z)^2 + 0*x^2 + 0*x*y + 0*y^2 + 0*x*z + 0*y*z + 0*z^2 + +REFERENCES: + +- [Bru2014]_ +- [Fil2017]_ +""" + +# **************************************************************************** +# Copyright (C) 2024 Verrel Rievaldo Wijaya +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation +from sage.rings.polynomial.multi_polynomial_element import MPolynomial_polydict + + +class TropicalMPolynomial(MPolynomial_polydict): + r""" + A multivariate tropical polynomial. + + Let `x_1, x_2, \ldots, x_n` be indeterminants. A tropical monomial is + any product of these variables, possibly including repetitions: + `x_1^{i_1}\cdots x_n^{i_n}` where `i_j \in \{0,1,\ldots\}`, for all + `j\in \{1,\ldots,n\}`. A multivariate tropical polynomial is a finite + linear combination of tropical monomials, + `p(x_1, \ldots, x_n) = \sum_{i=1}^n c_i x_1^{i_1}\cdots x_n^{i_n}`. + + In classical arithmetic, we can rewrite the general form of a tropical + monomial: `x_1^{i_1}\cdots x_n^{i_n} \mapsto i_1 x_1 + \cdots + i_n x_n`. + Thus, the tropical polynomial can be viewed as the minimum (maximum) of + a finite collection of linear functions. + + EXAMPLES: + + Construct a multivariate tropical polynomial semiring in two variables:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T); R + Multivariate Tropical Polynomial Semiring in a, b over Rational Field + + Define some multivariate tropical polynomials:: + + sage: p1 = R(3)*a*b + a + R(-1)*b; p1 + 3*a*b + 0*a + (-1)*b + sage: p2 = R(1)*a + R(1)*b + R(1)*a*b; p2 + 1*a*b + 1*a + 1*b + + Some basic arithmetic operations for multivariate tropical polynomials:: + + sage: p1 + p2 + 3*a*b + 1*a + 1*b + sage: p1 * p2 + 4*a^2*b^2 + 4*a^2*b + 4*a*b^2 + 1*a^2 + 1*a*b + 0*b^2 + sage: T(2) * p1 + 5*a*b + 2*a + 1*b + sage: p1(T(1),T(2)) + 6 + + Let us look at the different result for tropical curve and 3d graph + of tropical polynomial in two variables when different algebra is used. + First for the min-plus algebra:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: p1 = R(3)*a*b + a + R(-1)*b + sage: p1.tropical_variety() + Tropical curve of 3*a*b + 0*a + (-1)*b + sage: p1.tropical_variety().plot() + Graphics object consisting of 3 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=True) + R = PolynomialRing(T, ('a,b')) + a, b = R.gen(), R.gen(1) + p1 = R(3)*a*b + a + R(-1)*b + tv1 = p1.tropical_variety() + sphinx_plot(tv1.plot()) + + Tropical polynomial in two variables will induce a function in three + dimension that consists of a number of surfaces:: + + sage: p1.plot3d() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=True) + R = PolynomialRing(T, ('a,b')) + a, b = R.gen(), R.gen(1) + p1 = R(3)*a*b + a + R(-1)*b + sphinx_plot(p1.plot3d()) + + If we use a max-plus algebra, we will get a slightly different result:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R(3)*a*b + a + R(-1)*b + sage: p1.tropical_variety() + Tropical curve of 3*a*b + 0*a + (-1)*b + sage: p1.tropical_variety().plot() + Graphics object consisting of 3 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('a,b')) + a, b = R.gen(), R.gen(1) + p1 = R(3)*a*b + a + R(-1)*b + tv1 = p1.tropical_variety() + sphinx_plot(tv1.plot()) + + :: + + sage: p1.plot3d() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('a,b')) + a, b = R.gen(), R.gen(1) + p1 = R(3)*a*b + a + R(-1)*b + sphinx_plot(p1.plot3d()) + + TESTS: + + There is no subtraction defined for tropical polynomials:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: a - b + Traceback (most recent call last): + ... + ArithmeticError: cannot negate any non-infinite element + """ + def subs(self, fixed=None, **kwds): + r""" + Fix some given variables in ``self`` and return the changed + tropical multivariate polynomials. + + .. SEEALSO:: + + :meth:`sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict.subs` + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + y + R(3) + sage: p1((R(4),y)) + 0*y + 8 + sage: p1.subs({x: 4}) + 0*y + 8 + """ + variables = list(self.parent().gens()) + for i in range(len(variables)): + if str(variables[i]) in kwds: + variables[i] = kwds[str(variables[i])] + elif fixed: + if variables[i] in fixed: + variables[i] = fixed[variables[i]] + elif i in fixed: + variables[i] = fixed[i] + if len(kwds) < len(variables): + for i, v in enumerate(variables): + variables[i] = self.parent()(v) + return self(tuple(variables)) + + def plot3d(self, color='random'): + """ + Return the 3d plot of ``self``. + + Only implemented for tropical polynomial in two variables. + The `x`-`y` axes for this 3d plot is the same as the `x`-`y` + axes of the corresponding tropical curve. + + OUTPUT: Graphics3d Object + + EXAMPLES: + + A simple tropical polynomial that consist of only one surface:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + sage: p1.plot3d() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = x**2 + sphinx_plot(p1.plot3d()) + + Tropical polynomials often have graphs that represent a combination + of multiple surfaces:: + + sage: p2 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + sage: p2.plot3d() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p2 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + sphinx_plot(p2.plot3d()) + + :: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p3 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p3.plot3d() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p3 = R(2)*x**2 + x*y + R(2)*y**2 + x + R(-1)*y + R(3) + sphinx_plot(p3.plot3d()) + + TESTS:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x*y*z + x + sage: p1.plot3d() + Traceback (most recent call last): + ... + NotImplementedError: can only plot the graph of tropical + multivariate polynomial in two variables + """ + from random import random + from sage.plot.graphics import Graphics + from sage.geometry.polyhedron.constructor import Polyhedron + from sage.sets.real_set import RealSet + from sage.symbolic.relation import solve + + if len(self.parent().variable_names()) != 2: + raise NotImplementedError("can only plot the graph of tropical " + "multivariate polynomial in two variables") + tv = self.tropical_variety() + axes = tv._axes() + edge = set() + if tv.components(): + v = tv._vars[0] + T = self.parent().base() + R = self.base_ring().base_ring() + + # Finding the point of curve that touch the edge of the axes + for comp in tv.components(): + if len(comp[1]) == 1: + valid_int = RealSet(comp[1][0]) + else: + valid_int = RealSet(comp[1][0]).intersection(RealSet(comp[1][1])) + for i, eqn in enumerate(comp[0]): + j = (i+1) % 2 + if not eqn.is_numeric(): + for k in range(2): + sol = solve(eqn == axes[i][k], v) + if sol[0].rhs() in valid_int: + valid_point = [R(eq.subs(**{str(v): sol[0].rhs()})) for eq in comp[0]] + if valid_point[j] in RealSet(axes[j]): + edge.add(tuple(valid_point)) + + # Combine the edge, vertices, and corner point + vertices = self.tropical_variety().vertices() + corner = set() + for i in axes[0]: + for j in axes[1]: + corner.add((i, j)) + marks = corner | vertices | edge + + # Calculate the value of polynomial at each marked point + variables = self.parent().gens() + terms = [a*variables[0]**b[0] * variables[1]**b[1] for a, b in zip(self.coefficients(), self.exponents())] + point_terms = {} + for mark in marks: + mark_terms = [] + value = self(T(mark[0]), T(mark[1])) + value_terms = [term(T(mark[0]), T(mark[1])) for term in terms] + mark_terms.extend(terms[i] for i in range(len(terms)) + if value_terms[i] == value) + point_terms[(R(mark[0]), R(mark[1]), value.lift())] = mark_terms + + # Plot the points that attained its value at one term only + combined_plot = Graphics() + for elms in point_terms.values(): + if len(elms) == 1: + poly_vert = [] + term = elms[0] + for p, t in point_terms.items(): + if term in t: + poly_vert.append(p) + t.remove(term) + if color == 'random': + rand_color = (random(), random(), random()) + plot = Polyhedron(vertices=poly_vert).plot(color=rand_color) + combined_plot += plot + + # Plot the remaining points + for remain in point_terms.values(): + for term in remain: + poly_vert = [] + for p, t in point_terms.items(): + if term in t: + poly_vert.append(p) + t.remove(term) + if color == 'random': + rand_color = (random(), random(), random()) + plot = Polyhedron(vertices=poly_vert).plot(color=rand_color) + combined_plot += plot + return combined_plot + + def tropical_variety(self): + r""" + Return tropical roots of ``self``. + + In the multivariate case, the roots can be represented by a + tropical variety. In two dimensions, this is known as a tropical + curve. For dimensions higher than two, it is referred to as a + tropical hypersurface. + + OUTPUT: a :class:`sage.rings.semirings.tropical_variety.TropicalVariety` + + EXAMPLES: + + Tropical curve for tropical polynomials in two variables:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + R(0); p1 + 0*x + 0*y + 0 + sage: p1.tropical_variety() + Tropical curve of 0*x + 0*y + 0 + + Tropical hypersurface for tropical polynomials in more than two + variables:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(1)*x*y + R(-1/2)*x*z + R(4)*z^2; p1 + 1*x*y + (-1/2)*x*z + 4*z^2 + sage: p1.tropical_variety() + Tropical surface of 1*x*y + (-1/2)*x*z + 4*z^2 + """ + from sage.rings.semirings.tropical_variety import TropicalCurve, TropicalSurface, TropicalVariety + + if self.parent().ngens() == 2: + return TropicalCurve(self) + if self.parent().ngens() == 3: + return TropicalSurface(self) + return TropicalVariety(self) + + def _repr_(self): + r""" + Return string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: x + R(-1)*y + R(-3) + 0*x + (-1)*y + (-3) + """ + if not self.monomial_coefficients(): + return str(self.parent().base().zero()) + s = super()._repr_() + if self.monomials()[-1].is_constant(): + if self.monomial_coefficient(self.parent()(0)) < 0: + s = s.replace(" - ", " + -") + const = str(self.monomial_coefficient(self.parent(0))) + s = s.replace(f" {const}", f" ({const})") + return s + + def _latex_(self): + r""" + Return the latex representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + R(-1)*x*y + R(-1) + sage: latex(p1) + 0 x^{2} + \left(-1\right) x y + \left(-1\right) + sage: latex(R.zero()) + \infty + """ + if not self.monomial_coefficients(): + return self.parent().base().zero()._latex_() + s = super()._latex_() + if self.monomials()[-1].is_constant(): + if self.monomial_coefficient(self.parent()(0)) < 0: + s = s.replace(" - ", " + -") + const = str(self.monomial_coefficient(self.parent(0))) + s = s.replace(f" {const}", f" \\left({const}\\right)") + return s + + +class TropicalMPolynomialSemiring(UniqueRepresentation, Parent): + r""" + The semiring of tropical polynomials in multiple variables. + + This is the commutative semiring consisting of all finite linear + combinations of tropical monomials under (tropical) addition + and multiplication with coefficients in a tropical semiring. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: f = T(1)*x + T(-1)*y + sage: g = T(2)*x + T(-2)*y + sage: f + g + 1*x + (-2)*y + sage: f * g + 3*x^2 + (-1)*x*y + (-3)*y^2 + sage: f + R.zero() == f + True + sage: f * R.zero() == R.zero() + True + sage: f * R.one() == f + True + """ + def __init__(self, base_semiring, n, names, order): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 5, 'x') + sage: TestSuite(R).run() + """ + from sage.rings.semirings.tropical_semiring import TropicalSemiring + from sage.categories.semirings import Semirings + if not isinstance(base_semiring, TropicalSemiring): + raise ValueError(f"{base_semiring} is not a tropical semiring") + Parent.__init__(self, base=base_semiring, names=names, category=Semirings()) + self._ngens = n + self._term_order = order + + def term_order(self): + """ + Return the defined term order of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: R.term_order() + Degree reverse lexicographic term order + """ + return self._term_order + + Element = TropicalMPolynomial + + def _element_constructor_(self, x): + r"""" + Convert ``x`` into ``self``. + + INPUT: + + - ``x`` -- ``dict``, constant, or :class:`MPolynomial` + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x,y') + sage: dict1 = {(1,0):0, (0,1):-1, (1,1):3} + sage: p1 = R(dict1); p1 + 3*x*y + 0*x + (-1)*y + sage: S. = PolynomialRing(QQ) + sage: f = -x*y + 1 + sage: R(f) + (-1)*x*y + 1 + + TESTS:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: S. = PolynomialRing(T) + sage: R(a + b) + Traceback (most recent call last): + ... + ValueError: can not convert 0*a + 0*b to Multivariate Tropical + Polynomial Semiring in x, y over Rational Field + """ + from sage.rings.polynomial.multi_polynomial import MPolynomial + if isinstance(x, TropicalMPolynomial): + if x.parent() is not self: + raise ValueError(f"can not convert {x} to {self}") + if isinstance(x, MPolynomial): + if x.parent().variable_names() == self.variable_names(): + x = x.monomial_coefficients() + else: + raise ValueError(f"can not convert {x} to {self}") + elif (x in self.base().base_ring()) or (x in self.base()): + term = [0] * self.ngens() + x = {tuple(term): x} + + if isinstance(x, dict): + for key, value in x.items(): + x[key] = self.base()(value) + return self.element_class(self, x) + + @cached_method + def one(self): + r""" + Return the multiplicative identity of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x,y') + sage: R.one() + 0 + """ + exponent = [0] * self.ngens() + return self.element_class(self, {tuple(exponent): self.base().one()}) + + @cached_method + def zero(self): + r""" + Return the additive identity of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x,y') + sage: R.zero() + +infinity + """ + exponent = [0] * self.ngens() + return self.element_class(self, {tuple(exponent): self.base().zero()}) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(RR) + sage: R. = PolynomialRing(T); R + Multivariate Tropical Polynomial Semiring in u, v, w over Real + Field with 53 bits of precision + """ + if self._ngens == 0: + return (f"Multivariate Tropical Polynomial Semiring in no variables" + f" over {self.base_ring().base_ring()}") + return (f"Multivariate Tropical Polynomial Semiring in {', '.join(self.variable_names())}" + f" over {self.base_ring().base_ring()}") + + def random_element(self, degree=2, terms=None, choose_degree=False, + *args, **kwargs): + r""" + Return a random multivariate tropical polynomial from ``self``. + + OUTPUT: a :class:`TropicalMPolynomial` + + .. SEEALSO:: + + :meth:`sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base.random_element` + + EXAMPLES: + + A random polynomial of at most degree `d` and at most `t` terms:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: f = R.random_element(2, 5) + sage: f.degree() <= 2 + True + sage: f.parent() is R + True + sage: len(list(f)) <= 5 + True + + Choose degrees of monomials randomly first rather than monomials + uniformly random:: + + sage: f = R.random_element(3, 6, choose_degree=True) + sage: f.degree() <= 3 + True + sage: f.parent() is R + True + sage: len(list(f)) <= 6 + True + """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self.base().base_ring(), self.variable_names()) + f = R.random_element(degree=degree, terms=terms, choose_degree=choose_degree, + *args, **kwargs) + new_dict = {key: self.base()(value) + for key, value in f.monomial_coefficients().items()} + return self.element_class(self, new_dict) + + def gen(self, n=0): + r""" + Return the ``n``-th generator of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: R.gen() + 0*a + sage: R.gen(2) + 0*c + + TESTS:: + + sage: R.gen(3) + Traceback (most recent call last): + ... + IndexError: tuple index out of range + """ + return self.gens()[n] + + @cached_method + def gens(self): + r""" + Return the generators of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 5, 'x') + sage: R.gens() + (0*x0, 0*x1, 0*x2, 0*x3, 0*x4) + """ + gens = [] + for i in range(self.ngens()): + exponent = [0] * self.ngens() + exponent[i] = 1 + element = self.element_class(self, {tuple(exponent): self.base().one()}) + gens.append(element) + return tuple(gens) + + def ngens(self): + r""" + Return the number of generators of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 10, 'z') + sage: R.ngens() + 10 + """ + from sage.rings.integer_ring import ZZ + return ZZ(self._ngens) diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py new file mode 100644 index 00000000000..c0dff405ac9 --- /dev/null +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -0,0 +1,993 @@ +r""" +Univariate Tropical Polynomials + +AUTHORS: + +- Verrel Rievaldo Wijaya (2024-06): initial version + +EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: x.parent() + Univariate Tropical Polynomial Semiring in x over Rational Field + sage: (x + R(3)*x) * (x^2 + x) + 3*x^3 + 3*x^2 + sage: (x^2 + R(1)*x + R(-1))^2 + 0*x^4 + 1*x^3 + 2*x^2 + 0*x + (-2) + +REFERENCES: + +- [Bru2014]_ +- [Fil2017]_ +""" + +# **************************************************************************** +# Copyright (C) 2024 Verrel Rievaldo Wijaya +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.parent import Parent +from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse + + +class TropicalPolynomial(Polynomial_generic_sparse): + r""" + A univariate tropical polynomial. + + A tropical polynomial is a polynomial whose coefficients come from + a tropical semiring. Tropical polynomial induces a function which is + piecewise linear, where each segment of the function has a non-negative + integer slope. Tropical roots (zeros) of polynomial `P(x)` is defined + as all points `x_0` for which the graph of `P(x)` change its slope. + The difference in the slopes of the two pieces adjacent to this root + gives the order of the root. + + The tropical polynomials are implemented with a sparse format by using + a ``dict`` whose keys are the exponent and values the corresponding + coefficients. Each coefficient is a tropical number. + + EXAMPLES: + + First, we construct a tropical polynomial semiring by defining a base + tropical semiring and then inputting it to :class:`PolynomialRing`:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T); R + Univariate Tropical Polynomial Semiring in x over Rational Field + sage: R.0 + 0*x + + One way to construct an element is to provide a list or tuple of + coefficients. Another way to define an element is to write a polynomial + equation with each coefficient converted to the semiring:: + + sage: p1 = R([1,4,None,0]); p1 + 0*x^3 + 4*x + 1 + sage: p2 = R(1)*x^2 + R(2)*x + R(3); p2 + 1*x^2 + 2*x + 3 + + We can do some basic arithmetic operations for these tropical polynomials. + Remember that numbers given have to be in the tropical semiring. + If not, then it will raise an error:: + + sage: p1 + p2 + 0*x^3 + 1*x^2 + 4*x + 3 + sage: p1 * p2 + 1*x^5 + 2*x^4 + 5*x^3 + 6*x^2 + 7*x + 4 + sage: 2 * p1 + Traceback (most recent call last): + ... + ArithmeticError: cannot negate any non-infinite element + sage: T(2) * p1 + 2*x^3 + 6*x + 3 + sage: p1(3) + Traceback (most recent call last): + ... + TypeError: no common canonical parent for objects with parents: + 'Tropical semiring over Rational Field' and 'Integer Ring' + sage: p1(T(3)) + 9 + + We can find all tropical roots of a tropical polynomial, counted + with their multiplicities:: + + sage: p1.roots() + [-3, 2, 2] + sage: p2.roots() + [1, 1] + + Even though every tropical polynomials have tropical roots, this does not + neccessarily means it can be factored into its linear factors:: + + sage: p1.factor() + (0) * (0*x^3 + 4*x + 1) + sage: p2.factor() + (1) * (0*x + 1)^2 + + Every tropical polynomial `p(x)` have a corresponding unique tropical + polynomial `\bar{p}(x)` with the same roots that can be factored. We + call `\bar{p}(x)` the tropical polynomial split form of `p(x)`:: + + sage: p1.split_form() + 0*x^3 + 2*x^2 + 4*x + 1 + sage: p2.split_form() + 1*x^2 + 2*x + 3 + + Every tropical polynomial induce a piecewise linear function that can be + invoked in the following way:: + + sage: p1.piecewise_function() + piecewise(x|-->1 on (-oo, -3], x|-->x + 4 on (-3, 2), x|-->3*x on [2, +oo); x) + sage: p1.plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, 'x') + p1 = R([1,4,None,0]) + sphinx_plot(p1.plot()) + + :: + + sage: p2.piecewise_function() + piecewise(x|-->3 on (-oo, 1], x|-->2*x + 1 on (1, +oo); x) + sage: p2.plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, 'x') + x = R.gen() + p2 = R(1)*x**2 + R(2)*x + R(3) + sphinx_plot(plot(p2, xmin=-1, xmax=3)) + + TESTS: + + There is no subtraction for tropical polynomials because element in + tropical semiring doesn't necessarily have additive inverse:: + + sage: -p1 + Traceback (most recent call last): + ... + ArithmeticError: cannot negate any non-infinite element + """ + def roots(self): + r""" + Return the list of all tropical roots of ``self``, counted with + multiplicity. + + OUTPUT: a list of tropical numbers + + ALGORITHM: + + For each pair of monomials in the polynomial, we find the point + where their values are equal. This is the same as solving the + equation `c_1 + a_1 \cdot x = c_2 + a_2 \cdot x` for `x`, where + `(c_1, a_1)` and `(c_2, a_2)` are the coefficients and exponents + of monomials. + + The solution to this equation is `x = (c_2-c_1)/(a_1-a_2)`. We + substitute this `x` to each monomials in polynomial and check if + the maximum (minimum) is achieved by the previous two monomials. + If it is, then `x` is the root of tropical polynomial. In this + case, the order of the root at `x` is the maximum of `|i-j|` for + all possible pairs `i,j` which realise this maximum (minimum). + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: p1 = R([5,4,1,0,2,4,3]); p1 + 3*x^6 + 4*x^5 + 2*x^4 + 0*x^3 + 1*x^2 + 4*x + 5 + sage: p1.roots() + [-1, -1, -1, 1, 2, 2] + + There will be no tropical root for constant polynomial. Additionaly, + for a monomial, the tropical root is assumed to be the additive + identity of its base tropical semiring:: + + sage: p2 = R(2) + sage: p2.roots() + [] + sage: p3 = x^3 + sage: p3.roots() + [+infinity, +infinity, +infinity] + """ + from itertools import combinations + tropical_roots = [] + data = self.monomial_coefficients() + R = self.parent().base() + if len(data) == 1: + exponent = next(iter(data)) + if not exponent: + return tropical_roots + return [R.zero()] * exponent + dict_root = {} + dict_coeff = {i: c.lift() for i, c in data.items()} + for comb in combinations(dict_coeff, 2): + index1, index2 = comb[0], comb[1] + root = (dict_coeff[index1]-dict_coeff[index2]) / (index2-index1) + val_root = dict_coeff[index1] + index1*root + check_maks = True + for key in dict_coeff: + if key not in comb: + val = dict_coeff[key] + key*root + if R._use_min: + if val < val_root: + check_maks = False + break + elif val > val_root: + check_maks = False + break + if check_maks: + order = abs(index1-index2) + if root not in dict_root: + dict_root[root] = order + elif order > dict_root[root]: + dict_root[root] = order + for root in dict_root: + tropical_roots += [root] * dict_root[root] + return sorted(tropical_roots) + + def split_form(self): + r""" + Return the tropical polynomial which has the same roots as ``self`` + but which can be reduced to its linear factors. + + If a tropical polynomial has roots at `x_1, x_2, \ldots, x_n`, then + its split form is the tropical product of linear terms of the form + `(x + x_i)` for all `i=1,2,\ldots,n`. + + OUTPUT: :class:`TropicalPolynomial` + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: p1 = R([5,4,1,0,2,4,3]); p1 + 3*x^6 + 4*x^5 + 2*x^4 + 0*x^3 + 1*x^2 + 4*x + 5 + sage: p1.split_form() + 3*x^6 + 2*x^5 + 1*x^4 + 0*x^3 + 1*x^2 + 3*x + 5 + + :: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R([5,4,1,0,2,4,3]) + sage: p1.split_form() + 3*x^6 + 4*x^5 + 21/5*x^4 + 22/5*x^3 + 23/5*x^2 + 24/5*x + 5 + + TESTS: + + We verify that the roots of tropical polynomial and its split form + is really the same:: + + sage: p1.roots() == p1.split_form().roots() + True + """ + roots = self.roots() + R = self.parent() + poly = R(self.monomial_coefficients()[self.degree()].lift()) + for root in roots: + linear = R([root, 0]) + poly *= linear + return poly + + def factor(self): + r""" + Return the factorization of ``self`` into its tropical linear factors. + + Note that the factor `x - x_0` in classical algebra gets transformed + to the factor `x + x_0`, since the root of the tropical polynomial + `x + x_0` is `x_0` and not `-x_0`. However, not every tropical + polynomial can be factored. + + OUTPUT: a :class:'Factorization' + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: p1 = R([6,3,1,0]); p1 + 0*x^3 + 1*x^2 + 3*x + 6 + sage: factor(p1) + (0) * (0*x + 1) * (0*x + 2) * (0*x + 3) + + Such factorization is not always possible:: + + sage: p2 = R([4,4,2]); p2 + 2*x^2 + 4*x + 4 + sage: p2.factor() + (2) * (0*x^2 + 2*x + 2) + + TESTS: + + The factorization for a constant:: + + sage: p3 = R(3) + sage: p3.factor() + (3) * 0 + """ + from sage.structure.factorization import Factorization + unit = self.monomial_coefficients()[self.degree()] + if self != self.split_form() or not self.roots(): + factor = [(self * self.parent(-unit.lift()), 1)] + return Factorization(factor, unit=unit) + + R = self.parent() + roots_order = {} + for root in self.roots(): + if root in roots_order: + roots_order[root] += 1 + else: + roots_order[root] = 1 + factors = [(R([root, 0]), roots_order[root]) + for root in roots_order] + return Factorization(factors, unit=unit) + + def piecewise_function(self): + r""" + Return the tropical polynomial function of ``self``. + + The function is a piecewise linear function with the domains are + divided by the roots. First we convert each term of polynomial to + its corresponding linear function. Next, we must determine which + term achieves the minimum (maximum) at each interval. + + OUTPUT: A piecewise function + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R([4,2,1,3]); p1 + 3*x^3 + 1*x^2 + 2*x + 4 + sage: p1.piecewise_function() + piecewise(x|-->4 on (-oo, 1/3], x|-->3*x + 3 on (1/3, +oo); x) + + A constant tropical polynomial will result in a constant function:: + + sage: p2 = R(3) + sage: p2.piecewise_function() + 3 + + A monomial will resulted in a linear function:: + + sage: p3 = R(1)*x^3 + sage: p3.piecewise_function() + 3*x + 1 + """ + from sage.symbolic.ring import SR + from sage.functions.piecewise import piecewise + from sage.sets.real_set import RealSet + + x = SR.var('x') + data = self.monomial_coefficients() + R = self.parent().base() + if not self.roots(): + f = data[0].lift() + return f + + if len(data) == 1: + gradient = list(data)[0] + intercept = data[gradient].lift() + f = intercept + gradient*x + return f + + unique_root = sorted(set(self.roots())) + pieces = [] + domain = [] + for i in range(len(unique_root) + 1): + if i == 0: + test_number = R(unique_root[i] - 1) + elif i == len(unique_root): + test_number = R(unique_root[i-1] + 1) + else: + test_number = R((unique_root[i]+unique_root[i-1]) / 2) + terms = {i: c * test_number**i for i, c in data.items()} + if R._use_min: + critical = min(terms.values()) + else: + critical = max(terms.values()) + found_key = None + for key, value in terms.items(): + if value == critical: + found_key = key + break + gradient = found_key + intercept = data[found_key].lift() + + # To make sure all roots is included in the domain + if i == 0: + interval = RealSet.unbounded_below_closed(unique_root[i]) + piecewise_linear = (interval, intercept + gradient*x) + domain.append(interval) + elif i == len(unique_root): + if domain[i-1][0].upper_closed(): + interval = RealSet.unbounded_above_open(unique_root[i-1]) + else: + interval = RealSet.unbounded_above_closed(unique_root[i-1]) + piecewise_linear = (interval, intercept + gradient*x) + domain.append(interval) + else: + if domain[i-1][0].upper_closed(): + interval = RealSet((unique_root[i-1], unique_root[i])) + else: + interval = RealSet([unique_root[i-1], unique_root[i]]) + piecewise_linear = (interval, intercept + gradient*x) + domain.append(interval) + pieces.append(piecewise_linear) + + f = piecewise(pieces) + return f + + def plot(self, xmin=None, xmax=None): + r""" + Return the plot of ``self``, which is the tropical polynomial + function we get from ``self.piecewise_function()``. + + INPUT: + + - ``xmin`` -- (optional) real number + - ``xmax`` -- (optional) real number + + OUTPUT: + + If ``xmin`` and ``xmax`` is given, then it return a plot of + piecewise linear function of ``self`` with the axes start from + ``xmin`` to ``xmax``. Otherwise, the domain will start from the + the minimum root of ``self`` minus 1 to maximum root of ``self`` + plus 1. If the function of ``self`` is constant or linear, then + the default domain will be `[-1,1]`. + + EXAMPLES: + + If the tropical semiring use a max-plus algebra, then the graph + will be of piecewise linear convex function:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R([4,2,1,3]); p1 + 3*x^3 + 1*x^2 + 2*x + 4 + sage: p1.roots() + [1/3, 1/3, 1/3] + sage: p1.plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, 'x') + p1 = p1 = R([4,2,1,3]) + sphinx_plot(p1.plot()) + + A different result will be obtained if the tropical semiring employs + a min-plus algebra. Rather, a graph of the piecewise linear concave + function will be obtained:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: p1 = R([4,2,1,3]) + sage: p1.roots() + [-2, 1, 2] + sage: p1.plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=True) + R = PolynomialRing(T, 'x') + p1 = R([4,2,1,3]) + sphinx_plot(plot(p1, xmin=-4, xmax=4)) + + TESTS: + + If ``xmin`` or ``xmax`` is given as an input, then the others also + have to be given. Otherwise it will raise an error:: + + sage: plot(p1, 5) + Traceback (most recent call last): + ... + ValueError: expected 2 inputs for xmin and xmax, but got 1 + + Error also occured when ``xmin`` is greater or equal than``xmax``:: + + sage: plot(p1, 5, 3) + Traceback (most recent call last): + ... + ValueError: xmin = 5 should be less than xmax = 3 + """ + from sage.plot.plot import plot + f = self.piecewise_function() + if (xmin is None) and (xmax is None): + roots = sorted(self.roots()) + if (not roots) or (self.parent().base().zero() in roots): + return plot(f, xmin=-1, xmax=1) + else: + return plot(f, xmin=roots[0]-1, xmax=roots[-1]+1) + elif xmin is None or xmax is None: + raise ValueError("expected 2 inputs for xmin and xmax, but got 1") + elif xmin >= xmax: + raise ValueError(f"xmin = {xmin} should be less than xmax = {xmax}") + return plot(f, xmin=xmin, xmax=xmax) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: R([-3,-1,2,-1]) + (-1)*x^3 + 2*x^2 + (-1)*x + (-3) + """ + import re + if not self.monomial_coefficients(): + return str(self.parent().base().zero()) + + def replace_negatives(expr): + modified_expr = re.sub(r'(-\d+/\d+|-\d+)', r'(\1)', expr) + return modified_expr + + s = super()._repr() + v = self.parent().variable_name() + if s[0] == v: + s = "1*" + s + s = s.replace(" - ", " + -") + s = s.replace(" + "+v, " + 1*"+v) + s = s.replace("-"+v, "-1*"+v) + s = replace_negatives(s) + return s + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: p1 = R([-1,2,None,-3]) + sage: latex(p1) + \left(-3\right) x^{3} + 2 x + \left(-1\right) + """ + s = " " + coeffs = self.list(copy=False) + m = len(coeffs) + name = self.parent().latex_variable_names()[0] + for n in reversed(range(m)): + x = coeffs[n] + x = x._latex_() + if x != self.parent().base().zero()._latex_(): + if n != m-1: + s += " + " + if x.find("-") == 0: + x = "\\left(" + x + "\\right)" + if n > 1: + v = f"|{name}^{{{n}}}" + elif n == 1: + v = f"|{name}" + else: + v = "" + s += f"{x} {v}" + s = s.replace("|", "") + if s == " ": + return self.parent().base().zero()._latex_() + return s[1:].lstrip().rstrip() + + +class TropicalPolynomialSemiring(UniqueRepresentation, Parent): + r""" + The semiring of univariate tropical polynomials. + + This is the commutative semiring consisting of finite linear + combinations of tropical monomials under (tropical) + addition and multiplication with the identity element + being `+\infty` (or `-\infty` depending on whether the + base tropical semiring is using min-plus or max-plus algebra). + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: f = T(1)*x + sage: g = T(2)*x + sage: f + g + 1*x + sage: f * g + 3*x^2 + sage: f + R.zero() == f + True + sage: f * R.zero() == R.zero() + True + sage: f * R.one() == f + True + """ + @staticmethod + def __classcall_private__(cls, base_semiring, names): + """ + Ensures the names parameter is a tuple. + + EXAMPLES:: + + sage: from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring + sage: T = TropicalSemiring(ZZ) + sage: TPS = TropicalPolynomialSemiring + sage: TPS(T, 'x') == TPS(T, ('x')) + True + """ + if isinstance(names, str): + names = (names,) + return super().__classcall__(cls, base_semiring, tuple(names)) + + def __init__(self, base_semiring, names): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: TestSuite(R).run() + + TESTS:: + + sage: from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring + sage: TropicalPolynomialSemiring(ZZ, names='x') + Traceback (most recent call last): + ... + ValueError: Integer Ring is not a tropical semiring + """ + from sage.categories.semirings import Semirings + from sage.rings.semirings.tropical_semiring import TropicalSemiring + if not isinstance(base_semiring, TropicalSemiring): + raise ValueError(f"{base_semiring} is not a tropical semiring") + Parent.__init__(self, base=base_semiring, names=names, category=Semirings()) + + Element = TropicalPolynomial + + def _element_constructor_(self, x=None, check=True): + """ + Convert ``x`` into ``self``, possibly non-canonically. + + INPUT: + + - ``x`` -- a list or tuple of coefficients, a polynomial, or a + dictionary + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: R([1,2,3]) + 3*x^2 + 2*x + 1 + sage: S. = PolynomialRing(QQ) + sage: R(x^2 - x + 1) + 1*x^2 + (-1)*x + 1 + + If ``x`` is a tropical polynomial from different semiring, then it + will converted to constant:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: S. = PolynomialRing(T) + sage: p1 = R(y); p1 + 0*y + sage: p1.parent() + Univariate Tropical Polynomial Semiring in x over Rational Field + sage: p1.degree() + 0 + """ + if isinstance(x, (list, tuple)): + for i, coeff in enumerate(x): + if coeff == 0: + x[i] = self.base().one() + elif isinstance(x, TropicalPolynomial): + if x.parent() is not self: + x = {0: x} + check = False + return self.element_class(self, x, check=check) + + @cached_method + def one(self): + """ + Return the multiplicative identity of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: R.one() + 0 + """ + return self.element_class(self, [self.base().one()]) + + @cached_method + def zero(self): + """ + Return the additive identity of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: R.zero() + +infinity + """ + return self.element_class(self, [self.base().zero()]) + + def _repr_(self): + """ + Return a string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(ZZ) + sage: R. = PolynomialRing(T); R + Univariate Tropical Polynomial Semiring in abc over Integer Ring + """ + return (f"Univariate Tropical Polynomial Semiring in {self.variable_name()}" + f" over {self.base_ring().base_ring()}") + + def gen(self, n=0): + """ + Return the indeterminate generator of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: R.gen() + 0*abc + + TESTS:: + + sage: R.gen(2) + Traceback (most recent call last): + ... + IndexError: generator n not defined + """ + if n != 0: + raise IndexError("generator n not defined") + return self.gens()[n] + + @cached_method + def gens(self): + """ + Return a tuple whose entries are the generators for ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: R.gens() + (0*abc,) + """ + R = self.base() + return (self.element_class(self, [R.zero(), R.one()]),) + + def ngens(self): + """ + Return the number of generators of ``self``, which is 1 + since it is a univariate polynomial ring. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: R.ngens() + 1 + """ + from sage.rings.integer_ring import ZZ + return ZZ.one() + + def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): + r""" + Return a random tropical polynomial of given degrees (bounds). + + OUTPUT: a :class:`TropicalPolynomial` + + .. SEEALSO:: + + :meth:`sage.rings.polynomial.polynomial_ring.PolynomialRing_general.random_element` + + EXAMPLES: + + Tropical polynomial over an integer with each coefficient bounded + between ``x`` and ``y``:: + + sage: T = TropicalSemiring(ZZ) + sage: R = PolynomialRing(T, 'x') + sage: f = R.random_element(8, x=3, y=10) + sage: f.degree() + 8 + sage: f.parent() is R + True + sage: all(a >= T(3) for a in f.coefficients()) + True + sage: all(a < T(10) for a in f.coefficients()) + True + + If a tuple of two integers is provided for the ``degree`` argument, + a polynomial is selected with degrees within that range:: + + sage: all(R.random_element(degree=(1, 5)).degree() in range(1, 6) for _ in range(10^3)) + True + + Note that the zero polynomial (`\pm \infty`) has degree `-1`. + To include it, set the minimum degree to `-1`:: + + sage: while R.random_element(degree=(-1,2), x=-1, y=1) != R.zero(): + ....: pass + + Monic polynomials are chosen among all monic polynomials with degree + between the given ``degree`` argument:: + + sage: all(R.random_element(degree=(-1, 2), monic=True).is_monic() for _ in range(10^3)) + True + """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self.base().base_ring(), self.variable_names()) + f = R.random_element(degree=degree, monic=monic, *args, **kwds) + new_dict = f.monomial_coefficients() + if monic: + new_dict[f.degree()] = 0 + return self.element_class(self, new_dict) + + def is_sparse(self): + """ + Return ``True`` to indicate that the objects are sparse polynomials. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R = PolynomialRing(T, 'x') + sage: R.is_sparse() + True + """ + return True + + def interpolation(self, points): + """ + Return a tropical polynomial with its function is a linear + interpolation of point in ``points`` if possible. + + If there is only one point, then it will give a constant polynomial. + Because we are using linear interpolation, each point is actually + a root of the resulted tropical polynomial. + + INPUT: + + - ``points`` -- a list of tuples ``(x, y)`` + + OUTPUT: a :class:`TropicalPolynomial` + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R = PolynomialRing(T, 'x') + sage: points = [(-2,-3),(1,3),(2,4)] + sage: p1 = R.interpolation(points); p1 + 1*x^2 + 2*x + 4 + sage: p1.plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=True) + R = PolynomialRing(T, 'x') + points = [(-2,-3),(1,3),(2,4)] + p1 = R.interpolation(points) + sphinx_plot(p1.plot()) + + :: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R = PolynomialRing(T,'x') + sage: points = [(0,0),(1,1),(2,4)] + sage: p1 = R.interpolation(points); p1 + (-2)*x^3 + (-1)*x^2 + 0*x + 0 + sage: p1.plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, 'x') + points = [(0,0),(1,1),(2,4)] + p1 = R.interpolation(points) + sphinx_plot(p1.plot()) + + TESTS: + + Every piecewise linear component of tropical polynomial function + has to have an integer slope:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R = PolynomialRing(T,'x') + sage: points = [(0,0),(2,3)] + sage: R.interpolation(points) + Traceback (most recent call last): + ... + ValueError: the slope is not an integer + + For max-plus algebra, the slope of the componenets has to be + increasing as we move from left to right. Conversely for min-plus + algebra, the slope of the componenets has to be decreasing from + left to right:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R = PolynomialRing(T,'x') + sage: points = [(-2,-3),(1,3),(2,4)] + sage: R.interpolation(points) + Traceback (most recent call last): + ... + ValueError: can not interpolate these points + """ + points = sorted(points, key=lambda point: point[0]) + all_slope = [0] + roots = {} + R = self.base() + if R._use_min: + point_order = range(len(points)-1, 0, -1) + else: + point_order = range(len(points)-1) + for i in point_order: + if R._use_min: + slope = (points[i-1][1]-points[i][1]) / (points[i-1][0]-points[i][0]) + else: + slope = (points[i+1][1]-points[i][1]) / (points[i+1][0]-points[i][0]) + if not slope.is_integer(): + raise ValueError("the slope is not an integer") + if slope < all_slope[-1]: + raise ValueError("can not interpolate these points") + elif slope > all_slope[-1]: + order = slope - all_slope[-1] + all_slope.append(slope) + roots[points[i][0]] = order + + if len(all_slope) == 1: # constant polynomial + return self(points[0][1]) + + result = self.one() + for root, order in roots.items(): + result *= self([root, 0])**order + test_value = result(R(points[0][0])) + unit = R(points[0][1] - test_value.lift()) + result *= unit + return result + + @classmethod + def _implementation_names(cls, implementation, base_ring, sparse): + """ + Return the only implementation currently available for this semiring, + which is ``[None]``. + + EXAMPLES:: + + sage: from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring + sage: T = TropicalSemiring(QQ) + sage: TropicalPolynomialSemiring._implementation_names(None, T, True) + [None] + """ + names = [None] + assert isinstance(names, list) + assert implementation in names + return names diff --git a/src/sage/rings/semirings/tropical_semiring.pyx b/src/sage/rings/semirings/tropical_semiring.pyx index aa3ea3da761..205966541ab 100644 --- a/src/sage/rings/semirings/tropical_semiring.pyx +++ b/src/sage/rings/semirings/tropical_semiring.pyx @@ -40,7 +40,7 @@ cdef class TropicalSemiringElement(Element): cdef TropicalSemiringElement _new(self): """ - Return a new tropical semiring element with parent ``self`. + Return a new tropical semiring element with parent ``self``. """ cdef TropicalSemiringElement x x = TropicalSemiringElement.__new__(TropicalSemiringElement) @@ -468,8 +468,8 @@ class TropicalSemiring(Parent, UniqueRepresentation): INPUT: - ``base`` -- the base ordered additive semigroup `R` - - ``use_min`` -- (default: ``True``) if ``True``, then the semiring uses - `a \oplus b = \min(a, b)`; otherwise uses `a \oplus b = \max(a, b)` + - ``use_min`` -- boolean (default: ``True``); if ``True``, then the semiring uses + `a \oplus b = \min(a, b)`. Otherwise uses `a \oplus b = \max(a, b)`. EXAMPLES:: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py new file mode 100644 index 00000000000..3eb04372d13 --- /dev/null +++ b/src/sage/rings/semirings/tropical_variety.py @@ -0,0 +1,1178 @@ +r""" +Tropical Varieties + +A tropical variety is a piecewise-linear geometric object derived from +a classical algebraic variety by using tropical mathematics, where the +tropical semiring replaces the usual arithmetic operations. + +AUTHORS: + +- Verrel Rievaldo Wijaya (2024-06): initial version + +REFERENCES: + +- [Bru2014]_ +- [Fil2017]_ +""" + +# **************************************************************************** +# Copyright (C) 2024 Verrel Rievaldo Wijaya +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.structure.sage_object import SageObject +from sage.rings.infinity import infinity +from sage.structure.unique_representation import UniqueRepresentation + + +class TropicalVariety(UniqueRepresentation, SageObject): + r""" + A tropical variety in `\RR^n`. + + A tropical variety is defined as a corner locus of tropical polynomial + function. This means it consist of all points in `\RR^n` for which + the minimum (maximum) of the function is attained at least twice. + + We represent the tropical variety as a list of lists, where the + inner list consist of three parts. The first one is a parametric + equations for tropical roots. The second one is the condition + for parameters. The third one is the order of the corresponding + component. + + INPUT: + + - ``poly`` -- a :class:`TropicalMPolynomial` + + ALGORITHM: + + We need to determine a corner locus of this tropical polynomial + function, which is all points `(x_1, x_2, \ldots, x_n)` for which + the maximum (minimum) is obtained at least twice. First, we convert + each monomial to its corresponding linear function. Then for each two + monomials of polynomial, we find the points where their values are + equal. Since we attempt to solve the equality of two equations in `n` + variables, the solution set will be described by `n-1` parameters. + + Next, we need to check if the value of previous two monomials at the + points in solution set is really the maximum (minimum) of function. + We do this by solving the inequality of the previous monomial with all + other monomials in the polynomial after substituting the parameter. + This will give us the condition of parameters. Each of this condition + is then combined by union operator. If this final condition is not an + empty set, then it represent one component of tropical root. Then we + calculate the weight of this particular component by the maximum of + gcd of the numbers `|i-k|` and `|j-l|` for all pairs `(i,j)` and + `(k,l)` such that the value of on this component is given by the + corresponding monomials. + + EXAMPLES: + + We construct a tropical variety in `\RR^2`, where it is called a + tropical curve:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R(1)*x + x*y + R(0); p1 + 0*x*y + 1*x + 0 + sage: tv = p1.tropical_variety(); tv + Tropical curve of 0*x*y + 1*x + 0 + sage: tv.components() + [[(t1, 1), [t1 >= -1], 1], [(-1, t1), [t1 <= 1], 1], [(-t1, t1), [t1 >= 1], 1]] + sage: tv.vertices() + {(-1, 1)} + sage: tv.plot() + Graphics object consisting of 3 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = R(1)*x + x*y + R(0) + sphinx_plot(p1.tropical_variety().plot()) + + A slightly different result will be obtained if we use min-plus algebra + for the base tropical semiring:: + + sage: T = TropicalSemiring(QQ, use_min=True) + sage: R. = PolynomialRing(T) + sage: p1 = R(1)*x + x*y + R(0) + sage: tv = p1.tropical_variety(); tv + Tropical curve of 0*x*y + 1*x + 0 + sage: tv.components() + [[(t1, 1), [t1 <= -1], 1], [(-1, t1), [t1 >= 1], 1], [(-t1, t1), [t1 <= 1], 1]] + sage: tv.plot() + Graphics object consisting of 3 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=True) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = R(1)*x + x*y + R(0) + sphinx_plot(p1.tropical_variety().plot()) + + Tropical variety can consist of multiple components with varying orders:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R(7) + T(4)*x + y + R(4)*x*y + R(3)*y^2 + R(-3)*x^2 + sage: tv = p1.tropical_variety(); tv + Tropical curve of (-3)*x^2 + 4*x*y + 3*y^2 + 4*x + 0*y + 7 + sage: tv.components() + [[(3, t1), [t1 <= 0], 1], + [(-t1 + 3, t1), [0 <= t1, t1 <= 2], 1], + [(t1, 2), [t1 <= 1], 2], + [(t1, 0), [3 <= t1, t1 <= 7], 1], + [(7, t1), [t1 <= 0], 1], + [(t1 - 1, t1), [2 <= t1], 1], + [(t1 + 7, t1), [0 <= t1], 1]] + sage: tv.plot() + Graphics object consisting of 8 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = R(7) + T(4)*x + y + R(4)*x*y + R(3)*y**2 + R(-3)*x**2 + sphinx_plot(p1.tropical_variety().plot()) + + If the tropical polynomial have `n>2` variables, then the result will be + a tropical hypersurface embedded in a real space `\RR^n`:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x*y + R(-1/2)*x*z + R(4)*z^2 + a*x + sage: tv = p1.tropical_variety(); tv + Tropical hypersurface of 0*a*x + 0*x*y + (-1/2)*x*z + 4*z^2 + sage: tv.components() + [[(t1, t2, t3 - 1/2, t3), [t2 - 9/2 <= t3, t3 <= t1 + 1/2, t2 - 5 <= t1], 1], + [(t1, 2*t2 - t3 + 4, t3, t2), [t3 + 1/2 <= t2, t3 <= t1], 1], + [(t1, t2, t1, t3), [max(t1 + 1/2, 1/2*t1 + 1/2*t2 - 2) <= t3], 1], + [(t1, t2 + 9/2, t3, t2), [t2 <= min(t3 + 1/2, t1 + 1/2)], 1], + [(t1 - 1/2, t2, t3, t1), [t2 - 9/2 <= t1, t1 <= t3 + 1/2, t2 - 5 <= t3], 1], + [(2*t1 - t2 + 4, t2, t3, t1), [t1 <= min(1/2*t2 + 1/2*t3 - 2, t2 - 9/2)], 1]] + """ + def __init__(self, poly): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: tv = (x+y).tropical_variety() + sage: TestSuite(tv).run() + + TESTS:: + + sage: from sage.rings.semirings.tropical_variety import TropicalVariety + sage: R. = QQ[] + sage: p1 = x + y + sage: TropicalVariety(p1) + Traceback (most recent call last): + ... + ValueError: x + y is not a multivariate tropical polynomial + """ + import operator + from itertools import combinations + from sage.symbolic.ring import SR + from sage.symbolic.relation import solve + from sage.arith.misc import gcd + from sage.rings.semirings.tropical_mpolynomial import TropicalMPolynomial + + if not isinstance(poly, TropicalMPolynomial): + raise ValueError(f"{poly} is not a multivariate tropical polynomial") + + self._poly = poly + self._hypersurface = [] + tropical_roots = [] + variables = [SR.var(name) + for name in poly.parent().variable_names()] + + # Convert each term to its linear function + linear_eq = {} + pd = poly.monomial_coefficients() + for key in pd: + eq = sum(variables[i] * e for i, e in enumerate(key)) + eq += pd[key].lift() + linear_eq[key] = eq + temp_keys = [] + temp_order = [] + + # Checking for all possible combinations of two terms + for keys in combinations(pd, 2): + sol = solve(linear_eq[keys[0]] == linear_eq[keys[1]], variables) + + # Parametric solution of the chosen two terms + final_sol = [s.right() for s in sol[0]] + xy_interval = [] + xy_interval.append(tuple(final_sol)) + + # Comparing with other terms + min_max = linear_eq[keys[0]] + for i, v in enumerate(variables): + min_max = min_max.subs(**{str(v): final_sol[i]}) + all_sol_compare = [] + no_solution = False + for compare in pd: + if compare not in keys: + temp_compare = linear_eq[compare] + for i, v in enumerate(variables): + temp_compare = temp_compare.subs(**{str(v): final_sol[i]}) + if min_max == temp_compare: + sol_compare = [[]] + elif poly.parent().base()._use_min: + sol_compare = solve(min_max < temp_compare, variables) + else: + sol_compare = solve(min_max > temp_compare, variables) + if sol_compare: + if isinstance(sol_compare[0], list): + if sol_compare[0]: + all_sol_compare.append(sol_compare[0][0]) + else: # solution is unbounded on one side + all_sol_compare.append(sol_compare[0]) + else: + no_solution = True + break + + # Solve the condition for parameter + if not no_solution: + parameter = set() + for sol in all_sol_compare: + parameter = parameter.union(set(sol.variables())) + parameter_solution = solve(all_sol_compare, list(parameter)) + if parameter_solution: + xy_interval.append(parameter_solution[0]) + tropical_roots.append(xy_interval) + # Calculate the order + index_diff = [abs(ai - bi) + for ai, bi in zip(keys[0], keys[1])] + order = gcd(index_diff) + temp_order.append(order) + temp_keys.append(keys) + + # Changing all the operator symbol to be <= or >= + self._keys = [] + components = [] + dim_param = 0 + if tropical_roots: + dim_param = len(tropical_roots[0][0]) - 1 + vars = [SR.var(f't{i}') for i in range(1, dim_param + 1)] + for arg in tropical_roots: + subs_dict = {} + index_vars = 0 + new_eq = [] + for eq in arg[0]: + var_eq = eq.variables() + for var in var_eq: + if var not in subs_dict: + subs_dict[var] = vars[index_vars] + index_vars += 1 + new_eq.append(eq.subs(subs_dict)) + new_eq = tuple(new_eq) + arg.remove(arg[0]) + arg.insert(0, new_eq) + if not arg[1] or not isinstance(arg[1], list): + arg[1] = [] + for var in vars: + expr1 = -infinity < var + expr2 = var < infinity + arg[1].append(expr1) + arg[1].append(expr2) + else: + params = arg[1] + arg.remove(params) + new_param = [] + for param in params: + lhs = param.lhs().subs(subs_dict) + rhs = param.rhs().subs(subs_dict) + if param.operator() == operator.gt: + expr = lhs >= rhs + else: + expr = lhs <= rhs + new_param.append(expr) + arg.insert(1, new_param) + components.append(arg) + + # Determine the order of each component + self._vars = vars + final_order = [] + for i, component in enumerate(components): + if component not in self._hypersurface: + self._hypersurface.append(component) + final_order.append(temp_order[i]) + self._keys.append(temp_keys[i]) + else: + index = self._hypersurface.index(component) + if temp_order[i] > final_order[index]: + final_order[index] = temp_order[i] + self._keys[index] = temp_keys[i] + for i in range(len(self._hypersurface)): + self._hypersurface[i].append(final_order[i]) + + def dimension(self): + """ + Return the dimension of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x*y + R(-1)*x*z + sage: p1.tropical_variety().dimension() + 4 + """ + return self._poly.parent().ngens() + + def number_of_components(self): + """ + Return the number of components that make up ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x*y*a + x*z + y^2 + a*x + y + z + sage: p1.tropical_variety().number_of_components() + 13 + """ + from sage.rings.integer_ring import ZZ + return ZZ(len(self._hypersurface)) + + def _repr_(self): + """ + Return a string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: (w).tropical_variety() + Tropical hypersurface of 0*w + """ + return f"Tropical hypersurface of {self._poly}" + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: tv = (R(1)*w^2 + x*y*z + R(-1)).tropical_variety() + sage: latex(tv) + TV\left(0 x y z + 1 w^{2} + \left(-1\right)\right) + """ + return f"TV\\left({self._poly._latex_()}\\right)" + + def components(self): + """ + Return all components of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: tv = (a+x+y+z).tropical_variety() + sage: tv.components() + [[(t1, t1, t2, t3), [t1 <= min(t3, t2)], 1], + [(t1, t2, t1, t3), [t1 <= t3, t1 <= t2], 1], + [(t1, t2, t3, t1), [t1 <= min(t3, t2)], 1], + [(t1, t2, t2, t3), [t2 <= t3, t2 <= t1], 1], + [(t1, t2, t3, t2), [t2 <= min(t3, t1)], 1], + [(t1, t2, t3, t3), [t3 <= min(t1, t2)], 1]] + """ + return self._hypersurface + + def _components_intersection(self): + r""" + Return the intersection of three or more components of ``self``. + + For a tropical variety in `\RR^n`, the intersection is characterized + by a linear equation in `\RR^{n-1}`. Specifically, this becomes a + vertex for tropical curve and an edges for tropical surface. + + OUTPUT: + + A dictionary where the keys represent component indices and the + values are lists of tuples. Each tuple contains a parametric + equation of points and the corresponding parameter's condition. + + EXAMPLES: + + In two dimension, it will provide vertices that are incident with + each component:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: tv = p1.tropical_variety() + sage: tv._components_intersection() + {0: [((-2, 0), {})], + 1: [((-2, 0), {})], + 2: [((-1, -3), {})], + 3: [((-2, 0), {}), ((-1, 0), {})], + 4: [((-1, -3), {}), ((-1, 0), {})], + 5: [((-1, -3), {})], + 6: [((-1, 0), {}), ((3, 4), {})], + 7: [((3, 4), {})], + 8: [((3, 4), {})]} + + In three dimensions, it will provide all parametric equations of + lines that lie within each component:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + z + x^2 + sage: tv = p1.tropical_variety() + sage: tv._components_intersection() + {0: [((t2, t2, t2), {0 <= t2}), ((0, 0, t2), {0 <= t2})], + 1: [((0, t2, 0), {0 <= t2}), ((t2, t2, t2), {0 <= t2})], + 2: [((0, t1, 0), {0 <= t1}), ((0, 0, t2), {0 <= t2})], + 3: [((t1, t1, t1), {0 <= t1}), ((t1, 2*t1, 2*t1), {t1 <= 0})], + 4: [((1/2*t2, t2, t2), {t2 <= 0}), ((0, 0, t2), {0 <= t2})], + 5: [((0, t2, 0), {0 <= t2}), ((1/2*t2, t2, t2), {t2 <= 0})]} + """ + import operator + from sage.functions.min_max import max_symbolic, min_symbolic + from sage.symbolic.relation import solve + from sage.sets.set import Set + + def update_result(result): + sol_param = solve(new_expr, vars) + sol_param_sim = set() + for sol in sol_param: + if sol == []: + for v in vars: + if v != var: + sol_param_sim.add(v < infinity) + elif isinstance(sol, list): + for eqn in sol: + if eqn.operator() == operator.eq: + if not eqn.rhs().is_numeric(): + eqn_var = eqn.rhs().variables() + param_var = [v for v in eqn_var if v in vars] + if not param_var: + v = eqn.lhs() + if v != var: + sol_param_sim.add(v < infinity) + elif eqn.operator() == operator.lt: + sol_param_sim.add(eqn.lhs() <= eqn.rhs()) + elif eqn.operator() == operator.gt: + sol_param_sim.add(eqn.lhs() >= eqn.rhs()) + else: + sol_param_sim.add(sol) + # Checking there are no conditions with the same variables + # that use the <= and >= operators simultaneously + unique_sol_param = set() + temp = list(sol_param_sim) + op_temp = {i: set(temp[i].operands()) for i in range(len(temp))} + for s_value in op_temp.values(): + match_keys = [k for k, v in op_temp.items() if v == s_value] + if len(match_keys) == 1: + for i in match_keys: + unique_sol_param.add(temp[i]) + + if (unique_sol_param) or (self.dimension() == 2): + if not unique_sol_param: + unique_sol_param = Set() + if index not in result: + result[index] = [(tuple(points), unique_sol_param)] + else: + result[index].append((tuple(points), unique_sol_param)) + + result = {} + vars = self._vars + for index, comp in enumerate(self._hypersurface): + for expr in comp[1]: + left = expr.lhs() + right = expr.rhs() + # If the lhs contains a min or max operator + if (left.operator() == max_symbolic) or (left.operator() == min_symbolic): + for operand in expr.lhs().operands(): + points = list(comp[0]) + new_expr = [e.subs(**{str(right): operand}) for e in comp[1]] + for i, p in enumerate(points): + new_eq = p.subs(**{str(right): operand}) + points[i] = new_eq + update_result(result) + # If the rhs contains a min or max operator + elif (right.operator() == max_symbolic) or (right.operator() == min_symbolic): + for operand in expr.rhs().operands(): + points = list(comp[0]) + new_expr = [e.subs(**{str(left): operand}) for e in comp[1]] + for i, p in enumerate(points): + new_eq = p.subs(**{str(left): operand}) + points[i] = new_eq + update_result(result) + else: + var = expr.variables()[0] + points = list(comp[0]) + subs_expr = solve(left == right, var)[0].rhs() + new_expr = [e.subs(**{str(var): subs_expr}) for e in comp[1]] + for i, p in enumerate(points): + new_eq = p.subs(**{str(var): subs_expr}) + points[i] = new_eq + update_result(result) + return result + + +class TropicalSurface(TropicalVariety): + r""" + A tropical surface in `\RR^3`. + + The tropical surface consists of planar regions and facets, which we + can call cells. These cells are connected in such a way that they form + a piecewise linear structure embedded in three-dimensional space. These + cells meet along edges, where the balancing condition is satisfied. + This balancing condition ensures that the sum of the outgoing normal + vectors at each edge is zero, reflecting the equilibrium. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + z + R(0) + sage: tv = p1.tropical_variety(); tv + Tropical surface of 0*x + 0*y + 0*z + 0 + sage: tv.components() + [[(t1, t1, t2), [t2 <= t1, 0 <= t1], 1], + [(t1, t2, t1), [max(0, t2) <= t1], 1], + [(0, t1, t2), [t2 <= 0, t1 <= 0], 1], + [(t1, t2, t2), [max(0, t1) <= t2], 1], + [(t1, 0, t2), [t2 <= 0, t1 <= 0], 1], + [(t1, t2, 0), [t1 <= 0, t2 <= 0], 1]] + """ + def _axes(self): + r""" + Set the default axes for ``self``. + + This default axes is used for the 3d plot. The axes is centered + around where the intersection of the components occured so it + gives a nice visual representation for the interactions between + different components of the surface. Additionally, it enhances + the visibility and interpretation of how the components align + and interact in three-dimensional space. + + OUTPUT: + + A list of three lists, where the first inner list represent value + of x-axis, the second inner list represent value of y-axis, and + the third inner list represent value of z-axis. If there are + either no components or only one component, the axis will be set + to `[[-1, 1], [-1, 1], [-1, 1]]`. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + sage: p1.tropical_variety()._axes() + [[-1, 1], [-1, 1], [-1, 1]] + sage: p2 = x + y + z + x^2 + R(1) + sage: p2.tropical_variety()._axes() + [[-1, 2], [-1, 2], [-1, 2]] + """ + from sage.symbolic.relation import solve + from sage.arith.srange import srange + + if not self._hypersurface: + return [[-1, 1], [-1, 1], [-1, 1]] + elif len(self._hypersurface) == 1: + bound = 1 + for eqn in self._hypersurface[0][0]: + for op in eqn.operands(): + if op.is_numeric(): + bound = max(op, bound) + return [[-bound, bound]] * 3 + + u_set = set() + v_set = set() + for comp in self._hypersurface: + list_expr = [] + temp_u = set() + temp_v = set() + for expr in comp[1]: + if expr.lhs().is_numeric(): + if bool(expr.rhs() == self._vars[0]): + temp_u.add(expr.lhs()) + else: + temp_v.add(expr.lhs()) + elif expr.rhs().is_numeric(): + if bool(expr.lhs() == self._vars[0]): + temp_u.add(expr.rhs()) + else: + temp_v.add(expr.rhs()) + else: + list_expr.append(expr) + if not temp_u: + temp_u.add(0) + if not temp_v: + temp_v.add(0) + for expr in list_expr: + for u in temp_u: + sol = solve(expr.subs(**{str(self._vars[0]): u}), self._vars[1]) + if not sol: + temp_v.add(0) + elif not sol[0]: + temp_v.add(0) + else: + temp_v.add(sol[0][0].rhs()) + for v in temp_v: + sol = solve(expr.subs(**{str(self._vars[1]): v}), self._vars[0]) + if not sol: + temp_u.add(0) + elif not sol[0]: + temp_u.add(0) + else: + temp_u.add(sol[0][0].rhs()) + u_set = u_set.union(temp_u) + v_set = v_set.union(temp_v) + axes = [[min(u_set)-1, max(u_set)+1], [min(v_set)-1, max(v_set)+1]] + + # Finding the z-axis + step = 10 + du = (axes[0][1]-axes[0][0]) / step + dv = (axes[1][1]-axes[1][0]) / step + u_range = srange(axes[0][0], axes[0][1]+du, du) + v_range = srange(axes[1][0], axes[1][1]+dv, dv) + zmin, zmax = None, None + for comp in self._hypersurface: + for u in u_range: + for v in v_range: + checkpoint = True + for exp in comp[1]: + final_exp = exp.subs(**{str(self._vars[0]): u, str(self._vars[1]): v}) + if not final_exp: + checkpoint = False + break + if checkpoint: + z = comp[0][2].subs(**{str(self._vars[0]): u, str(self._vars[1]): v}) + if (zmin is None) and (zmax is None): + zmin = z + zmax = z + else: + zmin = min(z, zmin) + zmax = max(z, zmax) + axes.append([zmin, zmax]) + return axes + + def _polygon_vertices(self): + r""" + Return the vertices of the polygon for each components of ``self`` + to be used for plotting. + + OUTPUT: + + A dictionary where the keys represent component indices and the + values are a set of points in three dimensional space. + + EXAMPLES: + + A tropical surface with only one component:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + z + sage: tv1 = p1.tropical_variety() + sage: tv1._polygon_vertices() + {0: {(-1, -1, -1), (-1, 1, -1), (1, -1, 1), (1, 1, 1)}} + + A tropical surface with multiple components:: + + sage: p2 = x^2 + x + y + z + R(1) + sage: tv2 = p2.tropical_variety() + sage: tv2._polygon_vertices() + {0: {(0, 0, 0), (0, 0, 2), (1, 1, 1), (2, 2, 2)}, + 1: {(0, 0, 0), (0, 2, 0), (1, 1, 1), (2, 2, 2)}, + 2: {(0, 0, 0), (0, 0, 2), (0, 2, 0), (0, 2, 2)}, + 3: {(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2)}, + 4: {(-1/2, -1, -1), (0, 0, 0), (1, 1, 1), (2, -1, -1), (2, 1, 1)}, + 5: {(-1/2, -1, -1), (-1/2, -1, 2), (0, 0, 0), (0, 0, 2)}, + 6: {(1, 1, 1), (1, 1, 2), (2, 1, 1), (2, 1, 2)}, + 7: {(-1/2, -1, -1), (-1/2, 2, -1), (0, 0, 0), (0, 2, 0)}, + 8: {(1, 1, 1), (1, 2, 1), (2, 1, 1), (2, 2, 1)}} + """ + from sage.sets.real_set import RealSet + from sage.symbolic.relation import solve + from sage.rings.rational_field import QQ + + poly_verts = {i: set() for i in range(self.number_of_components())} + axes = self._axes() + comps = self.components() + vars = self._vars + comps_int = self._components_intersection() + + # Finding the inside vertices + for index, lines in comps_int.items(): + for line in lines: + v = list(line[1])[0].variables()[0] + for param in line[1]: + left = param.lhs() + right = param.rhs() + if left.is_numeric(): + vertex = [QQ(e.subs(**{str(v): left})) for e in line[0]] + poly_verts[index].add(tuple(vertex)) + elif right.is_numeric(): + vertex = [QQ(e.subs(**{str(v): right})) for e in line[0]] + poly_verts[index].add(tuple(vertex)) + + def find_edge_vertices(i): + j = (i+1) % 2 + if i == 0: # interval for t1 + interval = interval1 + else: # interval for t2 + interval = interval2 + for p in [interval.inf(), interval.sup()]: + new_param = [e.subs(**{str(vars[i]): p}) for e in comps[index][1]] + sol = solve(new_param, vars[j]) + if sol: + interval_param = RealSet() + for s in sol: + if s != []: + # Handle cases where 's' is not a list (s = r1 < +Infinity), + # or if 's' is a list, ensure that its elements define a real + # interval (catch invalid cases like s = [t1 == r100]). + try: + interval_param += RealSet(s[0]) + except (IndexError, ValueError): + interval_param += RealSet(-infinity, infinity) + else: + interval_param += RealSet(-infinity, infinity) + interval_param = interval_param.intersection(interval2) + if is_doublevar: + int1 = RealSet() + for s1 in sol1: + subs1 = solve(s1[0].subs(**{str(vars[i]): p}), vars[j]) + try: + int1 += RealSet(subs1[0]) + except TypeError: + int1 += RealSet(subs1[0][0]) + int2 = RealSet() + for s2 in sol2: + subs2 = solve(s2[0].subs(**{str(vars[i]): p}), vars[j]) + try: + int2 += RealSet(subs2[0]) + except TypeError: + int2 += RealSet(subs2[0][0]) + final_int = int1.intersection(int2) + interval_param = interval_param.intersection(final_int) + if interval_param: + vertex1 = [QQ(e.subs(**{str(vars[i]): p, str(vars[j]): interval_param.inf()})) for e in comps[index][0]] + vertex2 = [QQ(e.subs(**{str(vars[i]): p, str(vars[j]): interval_param.sup()})) for e in comps[index][0]] + poly_verts[index].add(tuple(vertex1)) + poly_verts[index].add(tuple(vertex2)) + + # Find the interval of parameter for outer vertex + for index in range(len(comps)): + interval1 = RealSet(-infinity, infinity) # represent t1 + interval2 = RealSet(-infinity, infinity) # represent t2 + is_doublevar = False + for i, point in enumerate(comps[index][0]): + pv = point.variables() + if len(pv) == 1: + temp1 = RealSet(solve(point >= axes[i][0], pv[0])[0][0]) + temp2 = RealSet(solve(point <= axes[i][1], pv[0])[0][0]) + temp = temp1.intersection(temp2) + if pv[0] == vars[0]: + interval1 = interval1.intersection(temp) + else: + interval2 = interval2.intersection(temp) + elif len(pv) == 2: + sol1 = solve(point >= axes[i][0], pv) + sol2 = solve(point <= axes[i][1], pv) + is_doublevar = True + # Finding the edge vertices (those that touch the axes) + find_edge_vertices(0) # t1 fixed + find_edge_vertices(1) # t2 fixed + return poly_verts + + def plot(self, color='random'): + """ + Return the plot of ``self`` by constructing a polyhedron from + vertices in ``self.polygon_vertices()``. + + INPUT: + + - ``color`` -- string or tuple that represent a color (default: + ``random``); ``random`` means each polygon will be assigned + a different color. If instead a specific ``color`` is provided, + then all polygon will be given the same color. + + OUTPUT: Graphics3d Object + + EXAMPLES: + + A tropical surface that consist of only one cell:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + z + sage: tv = p1.tropical_variety() + sage: tv.plot() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y,z')) + x, y, z = R.gen(), R.gen(1), R.gen(2) + p1 = x + z + sphinx_plot(p1.tropical_variety().plot()) + + A tropical surface with multiple cell that exhibit complex and + intriguing geometric structures:: + + sage: p2 = x^2 + x + y + z + R(1) + sage: tv = p2.tropical_variety() + sage: tv.plot() + Graphics3d Object + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y,z')) + x, y, z = R.gen(), R.gen(1), R.gen(2) + p2 = x**2 + x + y + z + R(1) + sphinx_plot(p2.tropical_variety().plot()) + """ + from random import random + from sage.plot.graphics import Graphics + from sage.geometry.polyhedron.constructor import Polyhedron + + if color == 'random': + colors = [] + for _ in range(self.number_of_components()): + color = (random(), random(), random()) + colors.append(color) + elif isinstance(color, str): + colors = [color] * self.number_of_components() + else: + colors = color + + combined_plot = Graphics() + for i, vertex in self._polygon_vertices().items(): + points = list(vertex) + plot = Polyhedron(vertices=points).plot(color=colors[i]) + combined_plot += plot + return combined_plot + + def _repr_(self): + """ + Return a string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: (x^4+z^2).tropical_variety() + Tropical surface of 0*x^4 + 0*z^2 + """ + return f"Tropical surface of {self._poly}" + + +class TropicalCurve(TropicalVariety): + r""" + A tropical curve in `\RR^2`. + + The tropical curve consists of line segments and half-lines, which we + call edges. These edges are connected in such a way that they form a + piecewise linear graph embedded in the plane. These edges meet at + a vertices, where the balancing condition is satisfied. This balancing + condition ensures that the sum of the outgoing slopes at each vertex + is zero, reflecting the equilibrium. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + R(0) + sage: tv = p1.tropical_variety(); tv + Tropical curve of 0*x + 0*y + 0 + sage: tv.components() + [[(t1, t1), [t1 >= 0], 1], [(0, t1), [t1 <= 0], 1], [(t1, 0), [t1 <= 0], 1]] + """ + def _axes(self): + """ + Set the default axes for ``self``. + + This default axes is used for plot of tropical curve and also the + 3d plot of tropical polynomial function. The axes is chosen by first + find all vertices of this tropical curve. Then we choose the minimum + and maximum of all x-component in this vertices to be the x-axis. + The same apply to the y-axis. + + OUTPUT: + + A list of two lists, where the first inner list represent value of + x-axis and the second inner list represent value of y-axis. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + sage: p1.tropical_variety()._axes() + [[-1, 1], [-1, 1]] + sage: p2 = R(12)*x*y + R(-2)*y^2 + R(16)*y + R(25) + sage: p2.tropical_variety()._axes() + [[-3/2, 1/2], [25/2, 29/2]] + """ + if self.number_of_components() == 0: + return [[-1, 1], [-1, 1]] + if self.number_of_components() <= 2: + bound = 1 + for comps in self._hypersurface: + eqns = comps[0] + temp_operands = [] + for eq in eqns: + if not eq.operator(): + temp_operands.append(eq) + else: + temp_operands += eq.operands() + for op in temp_operands: + if op.is_numeric(): + bound = max(abs(op), bound) + return [[-bound, bound]] * 2 + + verts = self.vertices() + xmin = xmax = list(verts)[0][0] + for vertex in verts: + if vertex[0] < xmin: + xmin = vertex[0] + elif vertex[0] > xmax: + xmax = vertex[0] + ymin = ymax = list(verts)[0][1] + for vertex in verts: + if vertex[1] < ymin: + ymin = vertex[1] + elif vertex[1] > ymax: + ymax = vertex[1] + return [[xmin-1, xmax+1], [ymin-1, ymax+1]] + + def vertices(self): + r""" + Return all vertices of ``self``, which is the point where three or + more edges intersect. + + OUTPUT: A set of `(x,y)` points + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + sage: p1.tropical_variety().vertices() + set() + sage: p2 = R(-2)*x^2 + R(-1)*x + R(1/2)*y + R(1/6) + sage: p2.tropical_variety().vertices() + {(1, -1/2), (7/6, -1/3)} + """ + if len(self._hypersurface) < 3: + return set() + + vertices = set() + for i, component in enumerate(self._hypersurface): + parametric_function = component[0] + var = component[1][0].variables()[0] + interval = self._parameter_intervals()[i] + lower = interval[0].lower() + upper = interval[0].upper() + if lower != -infinity: + x = parametric_function[0].subs(**{str(var): lower}) + y = parametric_function[1].subs(**{str(var): lower}) + vertices.add((x, y)) + if upper != infinity: + x = parametric_function[0].subs(**{str(var): upper}) + y = parametric_function[1].subs(**{str(var): upper}) + vertices.add((x, y)) + return vertices + + def _parameter_intervals(self): + r""" + Return the intervals of each component's parameter of ``self``. + + OUTPUT: A list of ``RealSet`` + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = y + y^2 + sage: p1.tropical_variety()._parameter_intervals() + [(-oo, +oo)] + sage: p2 = x^2 + R(-1)*x*y + R(-1)*x + R(1/3) + sage: p2.tropical_variety()._parameter_intervals() + [(-oo, 0], [0, +oo), [-1, 4/3], (-oo, 0], [0, +oo)] + """ + from sage.sets.real_set import RealSet + + intervals = [] + R = self._poly.parent().base().base_ring() + for component in self._hypersurface: + if len(component[1]) == 1: + interval = RealSet(component[1][0]) + else: + lower = component[1][0].left() + upper = component[1][1].right() + if lower == -infinity: + interval = RealSet(-infinity, infinity) + else: + interval = RealSet([R(lower), R(upper)]) + intervals.append(interval) + return intervals + + def plot(self): + """ + Return the plot of ``self``. + + Generates a visual representation of the tropical curve in cartesian + coordinates. The plot shows piecewise-linear segments representing + each components. The axes are centered around the vertices. + + OUTPUT: + + A Graphics object. The weight of the component will be written if it + is greater or equal than 2. The weight is written near the vertex. + + EXAMPLES: + + A polynomial with only two terms will give one straight line:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: (y+R(1)).tropical_variety().components() + [[(t1, 1), [-Infinity < t1, t1 < +Infinity], 1]] + sage: (y+R(1)).tropical_variety().plot() + Graphics object consisting of 1 graphics primitive + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + sphinx_plot((y+R(1)).tropical_variety().plot()) + + An intriguing and fascinating tropical curve can be obtained with + a more complex tropical polynomial:: + + sage: p1 = R(1) + R(2)*x + R(3)*y + R(6)*x*y + R(10)*x*y^2 + sage: p1.tropical_variety().components() + [[(-1, t1), [-2 <= t1], 1], + [(t1, -2), [-1 <= t1], 1], + [(t1 + 1, t1), [-4 <= t1, t1 <= -2], 1], + [(t1, -4), [t1 <= -3], 2], + [(-t1 - 7, t1), [t1 <= -4], 1]] + sage: p1.tropical_variety().plot() + Graphics object consisting of 6 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = R(1) + R(2)*x + R(3)*y + R(6)*x*y + R(10)*x*y**2 + sphinx_plot(p1.tropical_variety().plot()) + + Another tropical polynomial with numerous components, resulting + in a more intricate structure:: + + sage: p2 = (x^6 + R(4)*x^4*y^2 + R(2)*x^3*y^3 + R(3)*x^2*y^4 + x*y^5 + ....: + R(7)*x^2 + R(5)*x*y + R(3)*y^2 + R(2)*x + y + R(10)) + sage: p2.tropical_variety().plot() + Graphics object consisting of 11 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p2 = x**6 + R(4)*x**4*y**2 + R(2)*x**3*y**3 + R(3)*x**2*y**4 + \ + x*y**5 + R(7)*x**2 + R(5)*x*y + R(3)*y**2 + R(2)*x + y + R(10) + sphinx_plot(p2.tropical_variety().plot()) + """ + from sage.plot.plot import plot + from sage.plot.text import text + from sage.plot.graphics import Graphics + from sage.plot.plot import parametric_plot + + if not self._hypersurface: + return plot(lambda x: float('nan'), {-1, 1}) + + combined_plot = Graphics() + large_int = 100 + intervals = self._parameter_intervals() + for i, component in enumerate(self._hypersurface): + var = component[1][0].variables()[0] + parametric_function = component[0] + order = component[2] + interval = intervals[i] + if interval[0].lower() == -infinity: + lower = interval[0].upper() - large_int + upper = interval[0].upper() + midpoint = upper - 0.5 + elif interval[0].upper() == infinity: + lower = interval[0].lower() + upper = interval[0].lower() + large_int + midpoint = lower + 0.5 + else: + lower = interval[0].lower() + upper = interval[0].upper() + midpoint = (lower+upper) / 2 + + if (lower == infinity) and (upper == infinity): + midpoint = 0 + plot = parametric_plot(parametric_function, (var, -large_int, + large_int), color='red') + else: + plot = parametric_plot(parametric_function, (var, lower, upper), + color='red') + + # Add the order if it is greater than or equal to 2 + if component[2] > 1: + point = [] + for eq in component[0]: + value = eq.subs(**{str(var): midpoint}) + point.append(value) + text_order = text(str(order), (point[0], point[1]), + fontsize=16, color='black') + combined_plot += plot + text_order + else: + combined_plot += plot + + # Set default axes + axes = self._axes() + xmin, xmax = axes[0][0], axes[0][1] + ymin, ymax = axes[1][0], axes[1][1] + combined_plot.set_axes_range(xmin=xmin, xmax=xmax, + ymin=ymin, ymax=ymax) + return combined_plot + + def _repr_(self): + """ + Return a string representation of ``self``. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: (x^2+R(0)).tropical_variety() + Tropical curve of 0*x^2 + 0 + """ + return f"Tropical curve of {self._poly}" diff --git a/src/sage/rings/sum_of_squares.pyx b/src/sage/rings/sum_of_squares.pyx index 5cd916690de..bd403de75e9 100644 --- a/src/sage/rings/sum_of_squares.pyx +++ b/src/sage/rings/sum_of_squares.pyx @@ -130,12 +130,13 @@ cdef int three_squares_c(uint_fast32_t n, uint_fast32_t res[3]) noexcept: return 1 + def two_squares_pyx(uint32_t n): r""" - Return a pair of non-negative integers ``(i,j)`` such that `i^2 + j^2 = n`. + Return a pair of nonnegative integers ``(i,j)`` such that `i^2 + j^2 = n`. - If ``n`` is not a sum of two squares, a ``ValueError`` is raised. The input - must be lesser than `2^{32}=4294967296`, otherwise an ``OverflowError`` is + If ``n`` is not a sum of two squares, a :exc:`ValueError` is raised. The input + must be less than `2^{32}=4294967296`, otherwise an :exc:`OverflowError` is raised. .. SEEALSO:: @@ -184,14 +185,15 @@ def two_squares_pyx(uint32_t n): return (integer.smallInteger(i[0]), integer.smallInteger(i[1])) sig_off() - raise ValueError("%d is not a sum of 2 squares"%n) + raise ValueError("%d is not a sum of 2 squares" % n) + def is_sum_of_two_squares_pyx(uint32_t n): r""" Return ``True`` if ``n`` is a sum of two squares and ``False`` otherwise. The input must be smaller than `2^{32} = 4294967296`, otherwise an - ``OverflowError`` is raised. + :exc:`OverflowError` is raised. EXAMPLES:: @@ -214,13 +216,15 @@ def is_sum_of_two_squares_pyx(uint32_t n): sig_off() return False + def three_squares_pyx(uint32_t n): r""" - If ``n`` is a sum of three squares return a 3-tuple ``(i,j,k)`` of Sage integers - such that `i^2 + j^2 + k^2 = n` and `i \leq j \leq k`. Otherwise raise a ``ValueError``. + If ``n`` is a sum of three squares return a 3-tuple ``(i,j,k)`` of Sage + integers such that `i^2 + j^2 + k^2 = n` and `i \leq j \leq k`. Otherwise + raise a :exc:`ValueError`. - The input must be lesser than `2^{32}=4294967296`, otherwise an - ``OverflowError`` is raised. + The input must be less than `2^{32}=4294967296`, otherwise an + :exc:`OverflowError` is raised. EXAMPLES:: @@ -266,15 +270,16 @@ def three_squares_pyx(uint32_t n): return (integer.smallInteger(i[0]), integer.smallInteger(i[1]), integer.smallInteger(i[2])) sig_off() - raise ValueError("%d is not a sum of 3 squares"%n) + raise ValueError("%d is not a sum of 3 squares" % n) + def four_squares_pyx(uint32_t n): r""" - Return a 4-tuple of non-negative integers ``(i,j,k,l)`` such that `i^2 + j^2 + Return a 4-tuple of nonnegative integers ``(i,j,k,l)`` such that `i^2 + j^2 + k^2 + l^2 = n` and `i \leq j \leq k \leq l`. - The input must be lesser than `2^{32}=4294967296`, otherwise an - ``OverflowError`` is raised. + The input must be less than `2^{32}=4294967296`, otherwise an + :exc:`OverflowError` is raised. .. SEEALSO:: diff --git a/src/sage/rings/tate_algebra.py b/src/sage/rings/tate_algebra.py index 52f264b1761..d80060696be 100644 --- a/src/sage/rings/tate_algebra.py +++ b/src/sage/rings/tate_algebra.py @@ -95,7 +95,7 @@ 1 + 2^2 + a*2^4 + O(2^5) sage: u = polygen(ZZ, 'u') - sage: L. = K.change(print_mode="series").extension(u^3 - 2) + sage: L. = K.change(print_mode='series').extension(u^3 - 2) sage: g(pi, 2*pi) pi^7 + pi^8 + pi^19 + pi^20 + O(pi^21) @@ -173,14 +173,14 @@ class TateAlgebraFactory(UniqueFactory): - ``base`` -- a `p`-adic ring or field; if a ring is given, the Tate algebra over its fraction field will be constructed - - ``prec`` -- an integer or ``None`` (default: ``None``), the - precision cap; it is used if an exact object must be truncated + - ``prec`` -- integer or ``None`` (default: ``None``); the + precision cap. It is used if an exact object must be truncated in order to do an arithmetic operation. If left as ``None``, it will be set to the precision cap of the base field. - - ``log_radii`` -- an integer or a list or a tuple of integers - (default: ``0``), the value(s) `v_i`. + - ``log_radii`` -- integer or a list or a tuple of integers + (default: ``0``); the value(s) `v_i`. If an integer is given, this will be the common value for all `v_i`. @@ -251,9 +251,9 @@ def create_key(self, base, prec=None, log_radii=ZZ(0), names=None, order='degrev - ``base`` -- a `p`-adic ring or field - - ``prec`` -- an integer or ``None`` (default: ``None``) + - ``prec`` -- integer or ``None`` (default: ``None``) - - ``log_radii`` -- an integer or a list or a tuple of integers + - ``log_radii`` -- integer or a list or a tuple of integers (default: ``0``) - ``names`` -- names of the indeterminates @@ -291,7 +291,6 @@ def create_key(self, base, prec=None, log_radii=ZZ(0), names=None, order='degrev Traceback (most recent call last): ... ValueError: unknown term order 'myorder' - """ if not isinstance(base, pAdicGeneric): raise TypeError("the base ring must be a p-adic ring or a p-adic field") @@ -328,7 +327,6 @@ def create_object(self, version, key): sage: key = TateAlgebra.create_key(Zp(2), names=('x','y')) sage: TateAlgebra.create_object((8,4,6), key) Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 20 - """ (base, prec, log_radii, names, order) = key return TateAlgebra_generic(base, prec, log_radii, names, order) @@ -342,20 +340,19 @@ def create_object(self, version, key): class TateTermMonoid(Monoid_class, UniqueRepresentation): r""" - A base class for Tate algebra terms + A base class for Tate algebra terms. A term in a Tate algebra `K\{X_1,\dots,X_n\}` (resp. in its ring of integers) is a monomial in this ring. Those terms form a pre-ordered monoid, with term multiplication and the term order of the parent Tate algebra. - """ Element = TateAlgebraTerm def __init__(self, A): r""" - Initialize the Tate term monoid + Initialize the Tate term monoid. INPUT: @@ -373,7 +370,6 @@ def __init__(self, A): sage: A. = TateAlgebra(Zp(2), log_radii=1) sage: T = A.monoid_of_terms() sage: TestSuite(T).run() - """ # This function is not exposed to the user # so we do not check the inputs @@ -392,15 +388,14 @@ def __init__(self, A): def _repr_(self): r""" - Return a string representation of this Tate term monoid + Return a string representation of this Tate term monoid. EXAMPLES:: sage: R = pAdicRing(2, 10) - sage: A. = TateAlgebra(R, log_radii=[1,1], order="lex") + sage: A. = TateAlgebra(R, log_radii=[1,1], order='lex') sage: A.monoid_of_terms() # indirect doctest Monoid of terms in x (val >= -1), y (val >= -1) over 2-adic Field with capped relative precision 10 - """ if self._ngens == 0: return "Monoid of terms over %s" % self._base @@ -410,16 +405,15 @@ def _repr_(self): def _latex_(self): r""" - Return a LaTeX representation of this Tate term monoid + Return a LaTeX representation of this Tate term monoid. EXAMPLES:: sage: R = pAdicRing(2, 10) - sage: A. = TateAlgebra(R, log_radii=[1,1], order="lex") + sage: A. = TateAlgebra(R, log_radii=[1,1], order='lex') sage: M = A.monoid_of_terms() sage: M._latex_() '\\verb"Terms"(\\Bold{Q}_{2}\\{x,y\\}_{(1,1)})' - """ return '\\verb"Terms"(%s)' % self._parent_algebra._latex_() @@ -479,7 +473,7 @@ def _coerce_map_from_(self, R): Term orders must also match:: - sage: B. = TateAlgebra(R, order="lex") + sage: B. = TateAlgebra(R, order='lex') sage: U = B.monoid_of_terms() sage: T.has_coerce_map_from(U) # indirect doctest False @@ -519,7 +513,6 @@ def algebra_of_series(self): Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 10 sage: T.algebra_of_series() is A True - """ return self._parent_algebra @@ -552,7 +545,6 @@ def base_ring(self): 2-adic Ring with capped relative precision 10 sage: Ao.base_ring() is R True - """ return self._base @@ -567,7 +559,6 @@ def variable_names(self): sage: T = A.monoid_of_terms() sage: T.variable_names() ('x', 'y') - """ return self._names @@ -586,7 +577,6 @@ def log_radii(self): sage: B. = TateAlgebra(R, log_radii=[1,2]) sage: B.monoid_of_terms().log_radii() (1, 2) - """ return tuple(self._log_radii) @@ -606,13 +596,12 @@ def term_order(self): sage: T = A.monoid_of_terms() sage: T.term_order() Lexicographic term order - """ return self._order def ngens(self): r""" - Return the number of variables in the Tate term monoid + Return the number of variables in the Tate term monoid. EXAMPLES:: @@ -621,7 +610,6 @@ def ngens(self): sage: T = A.monoid_of_terms() sage: T.ngens() 2 - """ return self._ngens @@ -636,17 +624,16 @@ def gens(self): sage: T = A.monoid_of_terms() sage: T.gens() (...0000000001*x, ...0000000001*y) - """ return tuple([self(g) for g in self._parent_algebra.gens()]) def gen(self, n=0): r""" - Return the ``n``-th generator of this monoid of terms. + Return the `n`-th generator of this monoid of terms. INPUT: - - ``n`` -- an integer (default: ``0``), the index of + - ``n`` -- integer (default: `0`); the index of the requested generator EXAMPLES:: @@ -664,7 +651,6 @@ def gen(self, n=0): Traceback (most recent call last): ... ValueError: generator not defined - """ return self(self._parent_algebra.gen(n)) @@ -679,7 +665,6 @@ def some_elements(self): sage: T = A.monoid_of_terms() sage: T.some_elements() [...00000000010, ...0000000001*x, ...0000000001*y, ...00000000010*x*y] - """ elts = [ self(self._field.uniformizer()) ] + list(self.gens()) elts.append(prod(elts)) @@ -692,7 +677,7 @@ def some_elements(self): class TateAlgebra_generic(Parent): def __init__(self, field, prec, log_radii, names, order, integral=False): """ - Initialize the Tate algebra + Initialize the Tate algebra. TESTS:: @@ -702,7 +687,6 @@ def __init__(self, field, prec, log_radii, names, order, integral=False): We check that univariate Tate algebras work correctly:: sage: B. = TateAlgebra(Zp(3)) - """ from sage.misc.latex import latex_variable_name from sage.rings.polynomial.polynomial_ring_constructor import _multi_variate @@ -740,14 +724,13 @@ def __init__(self, field, prec, log_radii, names, order, integral=False): def _an_element_(self): r""" - Return an element of this Tate algebra + Return an element of this Tate algebra. EXAMPLES:: sage: A. = TateAlgebra(Zp(2), log_radii=1) sage: A.an_element() # indirect doctest (1 + O(2^20))*x - """ return self.gen() @@ -797,7 +780,7 @@ def _coerce_map_from_(self, R): If the tame order changes, there is no coercion either:: - sage: B. = TateAlgebra(R, order="lex") + sage: B. = TateAlgebra(R, order='lex') sage: B.has_coerce_map_from(A) # indirect doctest False @@ -815,7 +798,6 @@ def _coerce_map_from_(self, R): sage: C. = TateAlgebra(S, log_radii=[2,-2]) sage: C.has_coerce_map_from(B) # indirect doctest True - """ base = self._base if base.has_coerce_map_from(R): @@ -838,8 +820,8 @@ def _pushout_(self, R): """ Return the pushout of this Tate algebra with ``R``. - This is only implemented when ``R`` is a p-adic ring or - a p-adic field. + This is only implemented when ``R`` is a `p`-adic ring or + a `p`-adic field. EXAMPLES:: @@ -876,7 +858,6 @@ def _pushout_(self, R): (pi + O(pi^41))*v sage: (pi*v).parent() is A2 True - """ if isinstance(R, pAdicGeneric): base = pushout(self._base, R) @@ -889,13 +870,13 @@ def _pushout_(self, R): else: return A.integer_ring() - def _ideal_class_(self, n): + def _ideal_class_(self, n=0): r""" Return the class that handles ideals in this Tate algebra. INPUT: - - ``n`` -- number of generators + - ``n`` -- integer (default: ``0``); the number of generators EXAMPLES:: @@ -926,11 +907,11 @@ def prime(self): def gen(self, n=0): r""" - Return the ``n``-th generator of this Tate algebra. + Return the `n`-th generator of this Tate algebra. INPUT: - - ``n`` -- an integer (default: ``0``), the index of + - ``n`` -- integer (default: `0`); the index of the requested generator EXAMPLES:: @@ -947,7 +928,6 @@ def gen(self, n=0): Traceback (most recent call last): ... ValueError: generator not defined - """ try: return self._gens[n] @@ -964,7 +944,6 @@ def gens(self): sage: A. = TateAlgebra(R) sage: A.gens() (...0000000001*x, ...0000000001*y) - """ return tuple(self._gens) @@ -978,7 +957,6 @@ def ngens(self): sage: A. = TateAlgebra(R) sage: A.ngens() 2 - """ return self._ngens @@ -1006,7 +984,6 @@ def some_elements(self): ...0000000010*y, ...0000000001*y + ...00000000010*x*y, ...00000000100*x*y] - """ terms = [ self.zero() ] + [ self(t) for t in self.monoid_of_terms().some_elements() ] return [ terms[i] + terms[j] for i in range(len(terms)) for j in range(i, len(terms)) ] @@ -1024,7 +1001,6 @@ def _repr_(self): sage: A.integer_ring() Integer ring of the Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 10 - """ vars = ", ".join("%s (val >= %s)" % (var, -r) for var, r in zip(self._names, self._log_radii)) @@ -1049,7 +1025,6 @@ def _latex_(self): sage: B. = TateAlgebra(R, log_radii=[1,2]) sage: B._latex_() '\\Bold{Q}_{2}\\{u_{1},u_{2}\\}_{(1,2)}' - """ from sage.misc.latex import latex s = r"%s\{%s\}" % (latex(self._field), ",".join(self._latex_names)) @@ -1072,7 +1047,6 @@ def variable_names(self): sage: A. = TateAlgebra(R) sage: A.variable_names() ('x', 'y') - """ return self._names @@ -1095,7 +1069,6 @@ def log_radii(self): sage: C. = TateAlgebra(R, log_radii=(1,-1)) sage: C.log_radii() (1, -1) - """ return self._log_radii @@ -1116,7 +1089,6 @@ def integer_ring(self): True sage: x/2 in Ao False - """ return self._integer_ring @@ -1130,7 +1102,6 @@ def monoid_of_terms(self): sage: A. = TateAlgebra(R) sage: A.monoid_of_terms() Monoid of terms in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 10 - """ return self._parent_terms @@ -1148,7 +1119,6 @@ def term_order(self): sage: A. = TateAlgebra(R, order='lex') sage: A.term_order() Lexicographic term order - """ return self._order @@ -1182,7 +1152,6 @@ def precision_cap(self): sage: A. = TateAlgebra(R, prec=20) sage: A.precision_cap() 20 - """ return self._cap @@ -1211,7 +1180,6 @@ def absolute_e(self): sage: A. = TateAlgebra(S) sage: A.absolute_e() 2 - """ return self._base.absolute_e() @@ -1225,7 +1193,6 @@ def characteristic(self): sage: A. = TateAlgebra(R) sage: A.characteristic() 0 - """ return self.base_ring().characteristic() @@ -1235,20 +1202,20 @@ def random_element(self, degree=2, terms=5, integral=False, prec=None): INPUT: - - ``degree`` -- an integer (default: 2), an upper bound on + - ``degree`` -- integer (default: 2); an upper bound on the total degree of the result - - ``terms`` -- an integer (default: 5), the maximal number + - ``terms`` -- integer (default: 5); the maximal number of terms of the result - - ``integral`` -- a boolean (default: ``False``); if ``True`` + - ``integral`` -- boolean (default: ``False``); if ``True`` the result will be in the ring of integers - ``prec`` -- (optional) an integer, the precision of the result EXAMPLES:: - sage: R = Zp(2, prec=10, print_mode="digits") + sage: R = Zp(2, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: A.random_element() # random (...00101000.01)*y + ...1111011111*x^2 + ...0010010001*x*y @@ -1278,7 +1245,6 @@ def random_element(self, degree=2, terms=5, integral=False, prec=None): sage: B.random_element(integral=True) # random (...1111111.001)*x*y + (...111000101.1)*x + (...11010111.01)*y^2 + ...0010011011*y + ...0010100011000 - """ if integral or self._integral: polring = self._polynomial_ring.change_ring(self._field.integer_ring()) diff --git a/src/sage/rings/tate_algebra_element.pyx b/src/sage/rings/tate_algebra_element.pyx index 86b0a4dba52..022b5d1c880 100644 --- a/src/sage/rings/tate_algebra_element.pyx +++ b/src/sage/rings/tate_algebra_element.pyx @@ -44,7 +44,7 @@ def _pushout_family(elements, initial=ZZ): INPUT: - - ``elements`` -- a list of elements + - ``elements`` -- list of elements - ``initial`` -- a parent @@ -59,7 +59,6 @@ def _pushout_family(elements, initial=ZZ): sage: _pushout_family([a, x, 3]) Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Unramified Extension Field in a defined by x^2 + x + 1 - """ from sage.structure.coerce_exceptions import CoercionException from sage.categories.pushout import pushout @@ -88,7 +87,7 @@ cdef class TateAlgebraTerm(MonoidElement): - ``coeff`` -- an element in the base field - - ``exponent`` -- a tuple of length ``n`` + - ``exponent`` -- tuple of length ``n`` EXAMPLES:: @@ -104,17 +103,16 @@ cdef class TateAlgebraTerm(MonoidElement): Traceback (most recent call last): ... TypeError: a term cannot be zero - """ def __init__(self, parent, coeff, exponent=None): """ - Initialize a Tate algebra term + Initialize a Tate algebra term. INPUT: - ``coeff`` -- an element in the base field - - ``exponent`` -- a tuple + - ``exponent`` -- tuple TESTS:: @@ -124,7 +122,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: t = T(x) sage: TestSuite(t).run() - """ MonoidElement.__init__(self, parent) field = parent.base_ring().fraction_field() @@ -163,7 +160,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: hash(t) == hash((t.coefficient(), t.exponent())) True - """ return hash((self._coeff, self._exponent)) @@ -181,7 +177,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...0000000001*x*y sage: 2*t # indirect doctest ...00000000010*x*y - """ cdef TateAlgebraTerm ans = TateAlgebraTerm.__new__(TateAlgebraTerm) ans._parent = self._parent @@ -198,7 +193,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: t = x.leading_term() sage: loads(dumps(t)) == t # indirect doctest True - """ return TateAlgebraTerm, (self.parent(), self._coeff, self._exponent) @@ -226,7 +220,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: T = A.monoid_of_terms() sage: T(2*x*y) # indirect doctest ...00000000010*x*y - """ parent = self._parent if self._coeff._is_atomic() or (-self._coeff)._is_atomic(): @@ -288,7 +281,6 @@ cdef class TateAlgebraTerm(MonoidElement): (2 + O(2^11))*x*y sage: t.coefficient() 2 + O(2^11) - """ return self._coeff @@ -306,7 +298,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: t = T(2,(1,1)) sage: t.exponent() (1, 1) - """ return self._exponent @@ -329,7 +320,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...0000000011*x^2*y sage: s*t # indirect doctest ...00000000110*x^3*y^2 - """ cdef TateAlgebraTerm ans = self._new_c() ans._exponent = self._exponent.eadd((other)._exponent) @@ -376,7 +366,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: t = T(x*y^3) sage: s > t # indirect doctest True - """ cdef long c = other._valuation_c() - self._valuation_c() if not c: @@ -436,7 +425,6 @@ cdef class TateAlgebraTerm(MonoidElement): True sage: s == ss False - """ if op == Py_EQ: return ((self)._coeff == (other)._coeff @@ -460,7 +448,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...0000000011*x^2*y^2 sage: s.monomial() ...0000000001*x^2*y^2 - """ cdef TateAlgebraTerm ans = self._new_c() ans._coeff = self._parent._field(1) @@ -506,7 +493,6 @@ cdef class TateAlgebraTerm(MonoidElement): 0 sage: s.monomial().valuation() -4 - """ cdef TateAlgebraTerm ans = self._new_c() cdef long v = self._exponent.dotprod(self._parent._log_radii) @@ -537,7 +523,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...000000000100*x^2*y^2 sage: t.valuation() -2 - """ return ZZ(self._valuation_c()) @@ -554,7 +539,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...000000000100*x^2*y^2 sage: t.valuation() # indirect doctest 2 - """ return (self._coeff).valuation_c() - self._exponent.dotprod(self._parent._log_radii) @@ -574,7 +558,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: t = M(x*y) sage: t(0, 1) 0 - """ cdef Element ans = self._coeff cdef ETuple exponent = self._exponent @@ -619,7 +602,6 @@ cdef class TateAlgebraTerm(MonoidElement): Traceback (most recent call last): ... TypeError: cannot coerce all the elements to the same parent - """ parent = self._parent if len(args) != parent._ngens: @@ -685,7 +667,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: To = Ao.monoid_of_terms() sage: To(s).is_coprime_with(To(t)) False - """ for i in range(self._parent.ngens()): if self._exponent[i] > 0 and other.exponent()[i] > 0: @@ -722,7 +703,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...000000000100*x*y^3 sage: s.gcd(t) ...000000000100*x*y^2 - """ return self._gcd_c(other) @@ -759,7 +739,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: T = A.monoid_of_terms() sage: T(x^5).gcd(T(y^5)) ...00000.00001 - """ cdef TateAlgebraTerm ans = self._new_c() cdef long val @@ -792,7 +771,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...000000000100*x*y^3 sage: s.lcm(t) ...0000000001000*x^2*y^3 - """ return self._lcm_c(other) @@ -824,7 +802,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: s.gcd(t) * s.lcm(t) == s * t True - """ cdef TateAlgebraTerm ans = self._new_c() cdef long val @@ -842,7 +819,7 @@ cdef class TateAlgebraTerm(MonoidElement): - ``other`` -- a Tate term - - ``integral`` -- (default: ``False``); if ``True``, test + - ``integral`` -- (default: ``False``) if ``True``, test for divisibility in the ring of integers of the Tate algebra EXAMPLES:: @@ -887,7 +864,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: s.is_divisible_by(to) True - """ return (other)._divides_c(self, integral) @@ -900,7 +876,7 @@ cdef class TateAlgebraTerm(MonoidElement): - ``other`` -- a Tate term - - ``integral`` -- (default: ``False``); if ``True``, test for + - ``integral`` -- (default: ``False``) if ``True``, test for divisibility in the ring of integers of the Tate algebra EXAMPLES:: @@ -945,7 +921,6 @@ cdef class TateAlgebraTerm(MonoidElement): sage: to.divides(s) True - """ return self._divides_c(other, integral) @@ -957,7 +932,7 @@ cdef class TateAlgebraTerm(MonoidElement): - ``other`` -- a Tate term - - ``integral`` -- (default: ``False``) if ``True``, test for + - ``integral`` -- boolean (default: ``False``); if ``True``, test for divisibility in the ring of integers of the Tate algebra EXAMPLES:: @@ -971,7 +946,6 @@ cdef class TateAlgebraTerm(MonoidElement): ...000000000100*x*y^3 sage: t.divides(s) # indirect doctest False - """ parent = self._parent if (integral or not parent.base_ring().is_field()) and self.valuation() > other.valuation(): @@ -1007,13 +981,11 @@ cdef class TateAlgebraTerm(MonoidElement): Traceback (most recent call last): ... ValueError: the division is not exact - """ if not self.is_divisible_by(other): raise ValueError("the division is not exact") return (self)._floordiv_c(other) - cdef TateAlgebraTerm _floordiv_c(self, TateAlgebraTerm other): r""" Return the result of the exact division of this term by ``other``. @@ -1040,7 +1012,6 @@ cdef class TateAlgebraTerm(MonoidElement): Traceback (most recent call last): ... ValueError: the division is not exact - """ cdef TateAlgebraTerm ans = self._new_c() ans._exponent = self.exponent().esub(other.exponent()) @@ -1062,7 +1033,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...00001 + ...00010*x + O(2^5 * ) sage: A(2*x+1, prec=20) ...0000000001 + ...00000000010*x + O(2^20 * ) - """ def __init__(self, parent, x, prec=None, reduce=True): r""" @@ -1073,7 +1043,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: R = Zp(2, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: TestSuite(x).run() - """ cdef TateAlgebraElement xc CommutativeAlgebraElement.__init__(self, parent) @@ -1105,7 +1074,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): else: try: poly = parent._polynomial_ring(x) - self._poly = PolyDict(poly.dict(), None) + self._poly = PolyDict(poly.monomial_coefficients(), None) except TypeError: # last chance: we first try to convert to the rational Tate series if parent._integral: @@ -1131,7 +1100,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: A. = TateAlgebra(R) sage: x + y # indirect doctest ...0000000001*x + ...0000000001*y - """ cdef TateAlgebraElement ans = TateAlgebraElement.__new__(TateAlgebraElement) ans._parent = self._parent @@ -1147,7 +1115,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: A. = TateAlgebra(R) sage: A(78612, prec=3) # indirect doctest ...100 + O(2^3 * ) - """ self._is_normalized = True if self._prec is Infinity: @@ -1193,7 +1160,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: A(x + 2*x^2 + x^3, prec=5) ...00001*x^3 + ...00001*x + ...00010*x^2 + O(2^5 * ) - """ base = self._parent.base_ring() nvars = self._parent.ngens() @@ -1307,7 +1273,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): 5 sage: h.precision_absolute() 5 - """ cdef TateAlgebraElement ans = self._new_c() ans._poly = self._poly + (other)._poly @@ -1327,7 +1292,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2 sage: -f # indirect doctest ...1111111111*x^3 + ...1111111111*x + ...11111111110*x^2 - """ cdef TateAlgebraElement ans = self._new_c() cdef Element s = self._parent.base_ring()(-1) @@ -1360,7 +1324,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): 5 sage: h.precision_absolute() 5 - """ cdef TateAlgebraElement ans = self._new_c() ans._poly = self._poly - (other)._poly @@ -1393,7 +1356,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): 5 sage: h.precision_absolute() 6 - """ cdef TateAlgebraElement ans = self._new_c() a = self._prec + (other).valuation() @@ -1418,7 +1380,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: 6*f # indirect doctest ...00000000110*x^3 + ...00000000110*x + ...000000001100*x^2 - """ cdef TateAlgebraElement ans = self._new_c() ans._poly = self._poly.scalar_lmult(right) @@ -1431,7 +1392,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); the precision at which the result is computed, if ``None``, the result is truncated according to the cap of the parent @@ -1462,7 +1423,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... ValueError: this series in not invertible - """ cdef TateAlgebraTerm t cdef long v, curprec @@ -1519,7 +1479,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: Ao = A.integer_ring() sage: Ao(f).is_unit() False - """ if self.is_zero(): return False @@ -1544,7 +1503,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): EXAMPLES:: - sage: R = Zp(3, prec=4, print_mode="digits") + sage: R = Zp(3, prec=4, print_mode='digits') sage: A. = TateAlgebra(R) sage: (x + y)^3 ...0001*x^3 + ...0001*y^3 + ...0010*x^2*y + ...0010*x*y^2 @@ -1556,7 +1515,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0001 + ...2210*x^2 + ...1100*x^4 + ...2200*y^2 + ...1000*x^6 + ...1000*x^2*y^2 + O(3^4 * ) - or a square root (or more generally a nth root):: + or a square root (or more generally an n-th root):: sage: g = f^(1/2); g ...0001 + ...0010*x^2 + ...1100*x^4 + ...1200*y^2 + ...2000*x^6 @@ -1591,7 +1550,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): True sage: f^(x*y) == (f^y)^x True - """ cdef TateAlgebraElement temp cdef long p, v, e @@ -1630,13 +1588,13 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); the precision at which the result is computed, if ``None``, the result is truncated according to the cap of the parent EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 6*x^2 + 9*y^2 sage: g = f.sqrt(); g @@ -1660,24 +1618,22 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... ValueError: not in the domain of convergence - """ return self.nth_root(2, prec) - def sqrt(self, prec=None): r""" Return the square root of this series. INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); the precision at which the result is computed, if ``None``, the result is truncated according to the cap of the parent EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 6*x^2 + 9*y^2 sage: g = f.sqrt(); g @@ -1701,30 +1657,28 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... ValueError: not in the domain of convergence - """ return self.nth_root(2, prec) - def nth_root(self, n=2, prec=None): r""" - Return the ``n``-th root of this series. + Return the `n`-th root of this series. INPUT: - - ``n`` -- an integer (default: ``2``) + - ``n`` -- integer (default: `2`) - - ``prec`` -- an integer or ``None`` (default: ``None``); + - ``prec`` -- integer or ``None`` (default: ``None``); the precision at which the result is computed, if ``None``, the result is truncated according to the cap of the parent .. NOTE:: - The ``n``-th root is computed as `\exp(\frac 1 n \log(f))`. + The `n`-th root is computed as `\exp(\frac 1 n \log(f))`. EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 9*x^2 + 9*y^2 sage: g = f.nth_root(3, prec=3); g @@ -1745,7 +1699,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... ValueError: not in the domain of convergence - """ if n not in ZZ or n == 0: raise ValueError("n must be a nonzero integer") @@ -1791,7 +1744,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): root += scalar * root * (1 - a * root**n) return root - cpdef _richcmp_(self, other, int op): r""" Compare this series with ``other`` according to @@ -1835,7 +1787,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): False sage: f == g - 2 True - """ diff = self - other c = None @@ -1907,7 +1858,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f(pi, v) (pi^2 + O(pi^42)) + (1 + O(pi^40))*v^2 - """ cdef TateAlgebraTerm t parent = self._parent @@ -1945,7 +1895,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x^4 + ...0000000001 + ...000000000100*x*y sage: t*f # indirect doctest ...0000000011*x^6 + ...0000000011*x^2 + ...000000001100*x^3*y - """ cdef TateAlgebraElement ans = self._new_c() ans._poly = self._poly.term_lmult(term._exponent, term._coeff) @@ -1959,7 +1908,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer EXAMPLES:: @@ -1969,7 +1918,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2 sage: f << 2 # indirect doctest ...000000000100*x^3 + ...000000000100*x + ...0000000001000*x^2 - """ cdef dict coeffs = { } cdef ETuple e @@ -1988,7 +1936,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2003,7 +1951,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...00001*x^3 + ...00001*x + ...00010*x^2 + O(2^5 * ) sage: g << 2 ...0000100*x^3 + ...0000100*x + ...0001000*x^2 + O(2^7 * ) - """ cdef dict coeffs = { } cdef ETuple e @@ -2032,7 +1979,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2053,7 +2000,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: Ao = A.integer_ring() sage: Ao(f) << -1 ...0000000001*x^2 + ...000000000*x^3 + ...000000000*x - """ return (self)._lshift_c(n) @@ -2064,7 +2010,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2084,7 +2030,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: Ao = A.integer_ring() sage: Ao(f) << -1 ...0000000001*x^2 + ...000000000*x^3 + ...000000000*x - """ return (self)._lshift_c(-n) @@ -2111,7 +2056,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``), + - ``prec`` -- integer or ``None`` (default: ``None``), the precision at which the series should be compared to zero EXAMPLES:: @@ -2131,7 +2076,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): False sage: g.is_zero(4) True - """ cdef list terms = self._terms_c(include_zero=False) if prec is None: @@ -2146,7 +2090,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``log_radii`` -- an integer or a tuple; the log-radii of + - ``log_radii`` -- integer or a tuple; the log-radii of convergence of the smaller domain (see :class:`TateAlgebra` for more details) @@ -2167,7 +2111,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f.restriction([-1,-2]) ...00000000010*x + ...0000000001*y^2 - """ parent = self._parent from sage.rings.tate_algebra import TateAlgebra @@ -2193,7 +2136,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f = 2*x^2 + x sage: f.terms() [...0000000001*x, ...00000000010*x^2] - """ if not self._is_normalized: self._normalize() @@ -2206,8 +2148,8 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``include_zero`` -- a boolean (default: ``True``); if ``True``, - include terms which are indistinguishable from zero. + - ``include_zero`` -- boolean (default: ``True``); if ``True``, + include terms which are indistinguishable from zero EXAMPLES:: @@ -2216,7 +2158,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f = 2*x^2 + x sage: f.terms() # indirect doctest [...0000000001*x, ...00000000010*x^2] - """ cdef pAdicGenericElement c cdef ETuple e @@ -2248,11 +2189,10 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f = 2*x^2 + x sage: f.monomials() # indirect doctest [...0000000001*x, ...0000000001*x^2] - """ return [ t.monomial() for t in self.terms() ] - def dict(self): + def monomial_coefficients(self): """ Return a dictionary whose keys are the exponents and whose values are the corresponding coefficients of this series. @@ -2262,20 +2202,26 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: R = Zp(2, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 2*x^2 + x - sage: f.dict() + sage: f.monomial_coefficients() {(1, 0): ...0000000001, (2, 0): ...00000000010} + ``dict`` is an alias:: + + sage: f.dict() + {(1, 0): ...0000000001, (2, 0): ...00000000010} """ self._normalize() return dict(self._poly.__repn) + dict = monomial_coefficients + def coefficient(self, exponent): r""" - Return the coefficient corresponding to the given exponent + Return the coefficient corresponding to the given exponent. INPUT: - - ``exponent`` -- a tuple of integers + - ``exponent`` -- tuple of integers EXAMPLES:: @@ -2313,11 +2259,11 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): def __getitem__(self, exponent): r""" - Return the coefficient corresponding to the given exponent + Return the coefficient corresponding to the given exponent. INPUT: - - ``exponent`` -- a tuple of integers + - ``exponent`` -- tuple of integers TESTS:: @@ -2348,7 +2294,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f = x + 2*x^2 sage: f.coefficients() [...0000000001, ...00000000010] - """ return [ t.coefficient() for t in self.terms() ] @@ -2358,7 +2303,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``n`` -- an integer + - ``n`` -- integer EXAMPLES:: @@ -2373,7 +2318,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...100000*x + O(2^6 * ) sage: g.precision_absolute() 6 - """ return self._parent(self, prec=n) @@ -2383,7 +2327,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``); if + - ``prec`` -- integer or ``None`` (default: ``None``); if ``None``, the cap of the parent is used if it is higher than the current precision @@ -2413,11 +2357,10 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): In the next example, the precision on the coefficient is only lifted to ``O(2^10)`` because it is limited by the cap of the underlying - p-adic ring:: + `p`-adic ring:: sage: g.lift_to_precision(20) (1 + O(2^10))*x*y + (1 + O(2^10))*x + (1 + O(2^10))*y + O(2^20 * ) - """ cdef TateAlgebraElement ans = self._new_c() # Hmm, shouldn't we add a keyword argument to lift_to_precision() @@ -2428,7 +2371,9 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): return elt.lift_to_precision(prec) except PrecisionError: return elt.lift_to_precision() - ans._poly = PolyDict({ e: lift_without_error(c) for (e,c) in self._poly.__repn.iteritems() }, None) + ans._poly = PolyDict({e: lift_without_error(c) + for e, c in self._poly.__repn.items()}, + None) if prec is None: prec = self._parent.precision_cap() ans._prec = max(self._prec, prec) @@ -2459,7 +2404,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x + ...00000000010*x^2 + O(2^20 * ) sage: g.precision_absolute() 20 - """ return self._prec @@ -2499,7 +2443,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f = x^4 + 4*x*y + 1 sage: f.valuation() -4 - """ cdef TateAlgebraTerm t cdef list terms = self._terms_c() @@ -2549,13 +2492,13 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - `prec` -- an integer or ``None`` (default: ``None``); the + - ``prec`` -- integer or ``None`` (default: ``None``); the absolute precision at which the result is computed, if ``None`` the cap of the Tate algebra is used EXAMPLES:: - sage: R = Zp(3, 10, print_mode="digits") + sage: R = Zp(3, 10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 3*x + 9*y^2 sage: f.log() @@ -2606,7 +2549,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: logf.exp() == f True - """ # This code is mostly copied from sage.rings.padics.padic_generic_element # (should we find a way to share it?) @@ -2711,13 +2653,13 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - `prec` -- an integer or ``None`` (default: ``None``); the + - ``prec`` -- integer or ``None`` (default: ``None``); the absolute precision at which the result is computed, if ``None`` the cap of the Tate algebra is used EXAMPLES:: - sage: R = Zp(3, 10, print_mode="digits") + sage: R = Zp(3, 10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 9*y sage: f.exp() @@ -2765,7 +2707,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: expf.log() == f # long time True - """ # This code is mostly copied from sage.rings.padics.padic_generic_element # (should we find a way to share it?) @@ -2801,7 +2742,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): series += nfactorial return series / nfactorial - def leading_term(self, secure=False): r""" Return the leading term of this series. @@ -2815,10 +2755,10 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``secure`` -- a boolean (default: ``False``); if ``True``, + - ``secure`` -- boolean (default: ``False``); if ``True``, raises an error if the leading term cannot be determined due to the existence of terms which are indistinguishable - from zero; if ``False``, discard silently these terms + from zero. If ``False``, discard silently these terms. EXAMPLES:: @@ -2867,7 +2807,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): .. SEEALSO:: :meth:`leading_coefficient`, :meth:`leading_monomial` - """ cdef list terms cdef TateAlgebraTerm term @@ -2885,7 +2824,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): else: raise ValueError("zero has no leading term") - def leading_coefficient(self, secure=False): """ Return the leading coefficient of this series. @@ -2896,14 +2834,14 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``secure`` -- a boolean (default: ``False``); if ``True``, + - ``secure`` -- boolean (default: ``False``); if ``True``, raises an error if the leading term cannot be determined due to the existence of terms which are indistinguishable - from zero; if ``False``, discard silently these terms + from zero. If ``False``, discard silently these terms. EXAMPLES:: - sage: R = Zp(2, prec=10, print_mode="terse") + sage: R = Zp(2, prec=10, print_mode='terse') sage: A. = TateAlgebra(R) sage: f = x^4 + 3*x*y + 1; f (1 + O(2^10))*x^4 + (3 + O(2^10))*x*y + (1 + O(2^10)) @@ -2918,7 +2856,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): .. SEEALSO:: :meth:`leading_term`, :meth:`leading_monomial` - """ return self.leading_term(secure=secure).coefficient() @@ -2932,10 +2869,10 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``secure`` -- a boolean (default: ``False``); if ``True``, + - ``secure`` -- boolean (default: ``False``); if ``True``, raises an error if the leading term cannot be determined due to the existence of terms which are indistinguishable - from zero; if ``False``, discard silently these terms + from zero. If ``False``, discard silently these terms. EXAMPLES:: @@ -2954,7 +2891,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): .. SEEALSO:: :meth:`leading_term`, :meth:`leading_coefficient` - """ return self.leading_term(secure=secure).monomial() @@ -2991,7 +2927,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... ZeroDivisionError: rational division by zero - """ cdef TateAlgebraElement ans = self._new_c() cdef TateAlgebraTerm t @@ -3026,15 +2961,11 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...00000000010 + ...0000000001*x*y sage: g.is_monic() False - """ if self.valuation() != 0: return False c = self.leading_coefficient() - if c != 0 and c.unit_part() == 1: - return True - return False - + return c != 0 and c.unit_part() == 1 def weierstrass_degree(self): r""" @@ -3053,7 +2984,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x*y + ...0000000001*y + ...00000000010*x^4 sage: f.weierstrass_degree() 2 - """ v = self.valuation() return self.residue(v+1).degree() @@ -3075,7 +3005,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x*y + ...0000000001*y + ...00000000010*x^4 sage: f.degree() 2 - """ return self.weierstrass_degree() @@ -3096,7 +3025,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x^2 + ...0000000001*y^2 + ...0000000001*y + ...00000000010*x^3 sage: f.weierstrass_degrees() (2, 2) - """ v = self.valuation() return self.residue(v+1).degrees() @@ -3118,7 +3046,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...0000000001*x^2 + ...0000000001*y^2 + ...0000000001*y + ...00000000010*x^3 sage: f.degrees() (2, 2) - """ return self.weierstrass_degrees() @@ -3130,7 +3057,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): INPUT: - - ``n`` -- an integer (default: ``1``) + - ``n`` -- integer (default: `1`) EXAMPLES:: @@ -3147,14 +3074,14 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: f.residue(2).parent() Multivariate Polynomial Ring in x, y over Ring of integers modulo 4 - The residue can only be computed for series with non-negative valuation. + The residue can only be computed for series with nonnegative valuation. sage: g = f >> 2; g ...00000000.01*x^2 + ...00000000.01*y^2 + ...00000000.11*y + ...000000001.1*x^3 sage: g.residue() Traceback (most recent call last): ... - ValueError: element must have non-negative valuation in order to compute residue + ValueError: element must have nonnegative valuation in order to compute residue The residue is not implemented for series with convergence radius different from 1. @@ -3164,7 +3091,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... NotImplementedError: residues are only implemented for radius 1 - """ for r in self._parent.log_radii(): if r != 0: @@ -3175,7 +3101,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): try: Rn = self.base_ring().residue_ring(n) except (AttributeError, NotImplementedError): - Rn = self.base_ring().change(field=False, type="fixed-mod", prec=n) + Rn = self.base_ring().change(field=False, type='fixed-mod', prec=n) poly = self._parent._polynomial_ring(self._poly) return poly.change_ring(Rn) @@ -3187,13 +3113,13 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): - ``divisors`` -- the list of divisors - - ``quo`` -- a boolean, whether we should compute the quotients + - ``quo`` -- boolean; whether we should compute the quotients - - ``rem`` -- a boolean, whether we should compute the remainder + - ``rem`` -- boolean; whether we should compute the remainder TESTS:: - sage: R = Zp(2, 5, print_mode="digits") + sage: R = Zp(2, 5, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2 sage: g = x^2 @@ -3202,7 +3128,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...00011*y sage: r ...00001 + ...00010*x*y + ...00100*x*y^2 + O(2^5 * ) - """ cdef dict coeffs = { } cdef TateAlgebraElement f @@ -3260,9 +3185,9 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): - ``divisors`` -- the list of divisors - - ``quo`` -- a boolean, whether we should compute the quotients + - ``quo`` -- boolean; whether we should compute the quotients - - ``rem`` -- a boolean, whether we should compute the remainder + - ``rem`` -- boolean; whether we should compute the remainder TESTS:: @@ -3300,7 +3225,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... TypeError: cannot coerce all the elements to the same parent - """ parent = self.parent() if self.precision_absolute() is Infinity: @@ -3344,7 +3268,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): EXAMPLES:: - sage: R = Zp(2, 5, print_mode="digits") + sage: R = Zp(2, 5, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2 sage: g = x^2 @@ -3367,7 +3291,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): ...00001 + ...01100*x + O(2^5 * ) sage: f == g0*q[0] + g1*q[1] + r True - """ return (self)._quo_rem_check(divisors, True, True) @@ -3382,7 +3305,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): EXAMPLES:: - sage: R = Zp(2, 5, print_mode="digits") + sage: R = Zp(2, 5, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2 sage: g = x^2 @@ -3395,7 +3318,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: g1 = x*y + 2*x sage: f % [g0, g1] ...00001 + ...01100*x + O(2^5 * ) - """ return (self)._quo_rem_check(divisors, False, True) @@ -3410,7 +3332,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): EXAMPLES:: - sage: R = Zp(2, 5, print_mode="digits") + sage: R = Zp(2, 5, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2 sage: g = x^2 @@ -3423,7 +3345,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: g1 = x*y + 2*x sage: f // [g0, g1] [...00011*y, ...11010 + ...00100*y] - """ return (self)._quo_rem_check(divisors, True, False) @@ -3435,7 +3356,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 @@ -3456,7 +3377,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): sage: h = A.random_element() sage: (h + s).reduce(I) == h.reduce(I) True - """ return self % I.groebner_basis() @@ -3485,7 +3405,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): EXAMPLES:: - sage: R = Zp(2, 5, print_mode="digits") + sage: R = Zp(2, 5, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = x^3*y + 2*x*y + 4*x^2 sage: g = 2*x*y^2 + 2*x @@ -3501,7 +3421,6 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): Traceback (most recent call last): ... ValueError: the S-polynomial of zero is not defined - """ try: return self._Spoly_c(other) @@ -3520,13 +3439,12 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): We check that the S-polynomial of two monomials vanishes:: - sage: R = Zp(3, 5, print_mode="digits") + sage: R = Zp(3, 5, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = x^3*y^2 sage: g = x^2*y^3 sage: f.Spoly(g) 0 - """ cdef TateAlgebraTerm st = self._terms_c()[0] cdef TateAlgebraTerm ot = other._terms_c()[0] diff --git a/src/sage/rings/tate_algebra_ideal.pyx b/src/sage/rings/tate_algebra_ideal.pyx index acad1be5fd3..830b01686c2 100644 --- a/src/sage/rings/tate_algebra_ideal.pyx +++ b/src/sage/rings/tate_algebra_ideal.pyx @@ -35,45 +35,45 @@ from heapq import heappush, heappop from cysignals.signals cimport sig_check + class TateAlgebraIdeal(Ideal_generic): r""" - Initialize a class for ideals in a Tate series algebra + Initialize a class for ideals in a Tate series algebra. EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 sage: I = A.ideal([f,g]); I Ideal (...0000000012*x*y^2 + ...00000000010*x^2, ...0000000012*x^2*y + ...00000000010) of Tate Algebra in x (val >= 0), y (val >= 0) over 3-adic Field with capped relative precision 10 - """ #@cached_method def groebner_basis(self, prec=None, algorithm='VaPoTe', **options): r""" - Compute a Groebner basis of the ideal + Compute a Groebner basis of the ideal. INPUT: - - ``prec`` -- an integer or ``None`` (default: ``None``), the precision + - ``prec`` -- integer or ``None`` (default: ``None``); the precision at which the computations are carried. If ``None``, defaults to the - algebra precision cap + algebra precision cap. - - ``algorithm`` -- a string (default: ``VaPoTe``), the algorithm to + - ``algorithm`` -- string (default: ``'VaPoTe'``), the algorithm to use in the calculations; available algorithms are: - - ``buchberger``: classical Buchberger algorithm + - ``'buchberger'``: classical Buchberger algorithm - - ``buchberger-integral``: first computes a Groebner basis of the + - ``'buchberger-integral'``: first computes a Groebner basis of the ideal generated by the same generators over the ring of integers (provides better numerical stability) - - ``PoTe``: a F5-type algorithm where signatures are ordered by + - ``'PoTe'``: a F5-type algorithm where signatures are ordered by position over term - - ``VaPoTe``: a F5-type algorithm where signatures are ordered + - ``'VaPoTe'``: a F5-type algorithm where signatures are ordered by valuation over position over term We refer to [CVV2019]_ and [CVV2020]_ for a detailed description @@ -120,7 +120,7 @@ class TateAlgebraIdeal(Ideal_generic): EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 @@ -139,7 +139,7 @@ class TateAlgebraIdeal(Ideal_generic): sage: g = x^4*y^5 + x^5*y^2 + x^4 + 5*x^2*y + 2*x^5*y^4 + 2*x^6*y + 6*x^3*y^3 sage: h = 2*x^6*y^4 + 2*x^4 + 4*x^5*y^2 + 8*x^8*y^2 + 8*x^7*y^3 + 8*x^6*y sage: I = A.ideal([f,g,h]) - sage: I.groebner_basis(algorithm="buchberger-integral") + sage: I.groebner_basis(algorithm='buchberger-integral') [...0001*x^4 + O(2^4 * ), ...0001*x^2*y + O(2^4 * ), ...0001*y^2 + O(2^4 * )] @@ -150,11 +150,10 @@ class TateAlgebraIdeal(Ideal_generic): TESTS:: - sage: I.groebner_basis(algorithm="F4") + sage: I.groebner_basis(algorithm='F4') Traceback (most recent call last): ... NotImplementedError: available algorithms are 'buchberger', 'buchberger-integral', 'PoTe' and 'VaPoTe' - """ if prec is None: prec = self.ring().precision_cap() @@ -171,7 +170,7 @@ class TateAlgebraIdeal(Ideal_generic): def _contains_(self, x): r""" - Return ``True`` if ``x`` lies in this ideal + Return ``True`` if ``x`` lies in this ideal. INPUT: @@ -195,14 +194,13 @@ class TateAlgebraIdeal(Ideal_generic): sage: I.random_element() in I True - """ rgb = self.groebner_basis() return (x % rgb).is_zero() def _contains_ideal(self, I): r""" - Return ``True`` if ``I`` is contained in this ideal + Return ``True`` if ``I`` is contained in this ideal. INPUT: @@ -210,7 +208,7 @@ class TateAlgebraIdeal(Ideal_generic): EXAMPLES:: - sage: R = Zp(3,prec=10,print_mode="digits") + sage: R = Zp(3,prec=10,print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 @@ -263,7 +261,6 @@ class TateAlgebraIdeal(Ideal_generic): True sage: A.ideal([f]) == I False - """ if op == op_GT: return self._contains_ideal(other) and not other._contains_ideal(self) @@ -295,7 +292,7 @@ class TateAlgebraIdeal(Ideal_generic): Over classical Tate algebras (where `\pi` is invertible), this method always returns ``True``:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 @@ -321,7 +318,6 @@ class TateAlgebraIdeal(Ideal_generic): sage: Ao.ideal([3*f]).is_saturated() False - """ if self.ring().base_ring().is_field(): return True @@ -353,7 +349,7 @@ class TateAlgebraIdeal(Ideal_generic): Over classical Tate algebras (where `\pi` is invertible), this method always returns the same ideal:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 @@ -390,7 +386,6 @@ class TateAlgebraIdeal(Ideal_generic): True sage: 3*Ios < Io True - """ if self.ring().base_ring().is_field(): return self @@ -406,7 +401,7 @@ class TateAlgebraIdeal(Ideal_generic): def groebner_basis_buchberger(I, prec, py_integral): r""" - Compute a Groebner basis of the Tate algebra ideal I using Buchberger's algorithm + Compute a Groebner basis of the Tate algebra ideal I using Buchberger's algorithm. INPUT: @@ -415,7 +410,7 @@ def groebner_basis_buchberger(I, prec, py_integral): - ``prec`` -- the related precision at which the initial generators are truncated - - ``integral`` -- a boolean; if ``True``, first compute a + - ``integral`` -- boolean; if ``True``, first compute a Grobner basis of the ideal generated by the same generators over the ring over the ring of integers @@ -426,7 +421,7 @@ def groebner_basis_buchberger(I, prec, py_integral): EXAMPLES:: - sage: R = Zp(3, prec=10, print_mode="digits"); + sage: R = Zp(3, prec=10, print_mode='digits'); sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 @@ -436,7 +431,6 @@ def groebner_basis_buchberger(I, prec, py_integral): [...000000001*x^3 + ...222222222*y + O(3^9 * ), ...0000000001*x^2*y + ...1210121020 + O(3^10 * ), ...000000001*y^2 + ...210121020*x + O(3^9 * )] - """ cdef list gb, rgb, indices, ts, S = [ ] cdef int i, j, l @@ -568,7 +562,7 @@ def groebner_basis_buchberger(I, prec, py_integral): cdef Jpair(p1, p2): r""" - Return the J-pair of ``p1`` and ``p2`` + Return the J-pair of ``p1`` and ``p2``. INPUT: @@ -601,11 +595,11 @@ cdef Jpair(p1, p2): cdef TateAlgebraElement regular_reduce(sgb, TateAlgebraTerm s, TateAlgebraElement v, stopval): r""" - Return the result of the regular reduction of the pair ``(s,v)`` by ``sgb`` + Return the result of the regular reduction of the pair ``(s,v)`` by ``sgb``. INPUT: - - ``sgb`` -- a list of pairs (signature, series), candidate to be a strong + - ``sgb`` -- list of pairs (signature, series), candidate to be a strong Groebner basis; all leading coefficients are assumed to be a power of the uniformizer @@ -685,11 +679,11 @@ cdef TateAlgebraElement regular_reduce(sgb, TateAlgebraTerm s, TateAlgebraElemen cdef TateAlgebraElement reduce(gb, TateAlgebraElement v, stopval): r""" - Return the result of the reduction of ``v`` by ``gb`` + Return the result of the reduction of ``v`` by ``gb``. INPUT: - - ``gb`` -- a list of reductors + - ``gb`` -- list of reductors - ``v`` -- a series @@ -751,18 +745,18 @@ cdef TateAlgebraElement reduce(gb, TateAlgebraElement v, stopval): def print_pair(p, verbose): r""" - Return a string representation of the pair ``p`` + Return a string representation of the pair ``p``. INPUT: - ``p`` -- a pair (signature, series) - - ``verbose`` -- an integer + - ``verbose`` -- integer TESTS:: sage: from sage.rings.tate_algebra_ideal import print_pair - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: v = 3*x^2 + 5*x*y^2 sage: s = v.leading_term() @@ -785,6 +779,7 @@ def print_pair(p, verbose): s, v = p return "(sign = %s, series = %s + ...)" % (s, v.leading_term()) + def groebner_basis_pote(I, prec, verbose=0): r""" Run the PoTe algorithm to compute the Groebner basis of ``I`` @@ -796,21 +791,21 @@ def groebner_basis_pote(I, prec, verbose=0): - ``prec`` -- the precision at which the Groebner basis is computed - - ``verbose`` -- an integer (default: ``0``) + - ``verbose`` -- integer (default: 0) TESTS:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 sage: I = A.ideal([f,g]) - sage: I.groebner_basis(algorithm="PoTe") # indirect doctest + sage: I.groebner_basis(algorithm='PoTe') # indirect doctest [...000000001*x^3 + ...222222222*y + O(3^9 * ), ...0000000001*x^2*y + ...1210121020 + O(3^10 * ), ...000000001*y^2 + ...210121020*x + O(3^9 * )] - sage: I.groebner_basis(algorithm="PoTe", verbose=2) # indirect doctest + sage: I.groebner_basis(algorithm='PoTe', verbose=2) # indirect doctest --- new generator: ...0000000001*x*y^2 + ... 0 initial J-pairs @@ -849,7 +844,7 @@ def groebner_basis_pote(I, prec, verbose=0): We check that :issue:`30101` is fixed:: - sage: I.groebner_basis(algorithm="PoTe", prec=100) # indirect doctest + sage: I.groebner_basis(algorithm='PoTe', prec=100) # indirect doctest [...0000000001*x^3 + ...2222222222*y + ...000000000*x^2*y^2 + O(3^99 * ), ...0000000001*x^2*y + ...01210121020 + O(3^100 * ), ...0000000001*y^2 + ...01210121020*x + ...0000000000*x^3*y + O(3^99 * )] @@ -1026,34 +1021,34 @@ def groebner_basis_vapote(I, prec, verbose=0, interrupt_red_with_val=False, inte - ``prec`` -- the precision at which the Groebner basis is computed - - ``verbose`` -- an integer (default: ``0``) + - ``verbose`` -- integer (default: 0) - - ``interrupt_red_with_val`` -- a boolean (default: ``False``); if + - ``interrupt_red_with_val`` -- boolean (default: ``False``); if regular reductions have to be interrupted as soon as the valuation raises - - ``interrupt_interred_with_val`` -- a boolean (default: ``False''); + - ``interrupt_interred_with_val`` -- boolean (default: ``False''); if intermediate interreductions of the Groebner basis have to be interrupted as soon as the valuation raises TESTS:: - sage: R = Zp(3, prec=10, print_mode="digits") + sage: R = Zp(3, prec=10, print_mode='digits') sage: A. = TateAlgebra(R) sage: f = 3*x^2 + 5*x*y^2 sage: g = 5*x^2*y + 3 sage: I = A.ideal([f,g]) - sage: I.groebner_basis(algorithm="VaPoTe") # indirect doctest + sage: I.groebner_basis(algorithm='VaPoTe') # indirect doctest [...000000001*x^3 + ...222222222*y + O(3^9 * ), ...0000000001*x^2*y + ...1210121020 + O(3^10 * ), ...000000001*y^2 + ...210121020*x + O(3^9 * )] - sage: I.groebner_basis(algorithm="VaPoTe", interrupt_red_with_val=True) # indirect doctest + sage: I.groebner_basis(algorithm='VaPoTe', interrupt_red_with_val=True) # indirect doctest [...000000001*x^3 + ...222222222*y + O(3^9 * ), ...0000000001*x^2*y + ...1210121020 + O(3^10 * ), ...000000001*y^2 + ...210121020*x + O(3^9 * )] - sage: I.groebner_basis(algorithm="VaPoTe", verbose=2) # indirect doctest + sage: I.groebner_basis(algorithm='VaPoTe', verbose=2) # indirect doctest grobner basis reduced --- new generator: ...0000000012*x*y^2 + ... @@ -1095,7 +1090,7 @@ def groebner_basis_vapote(I, prec, verbose=0, interrupt_red_with_val=False, inte We check that :issue:`30101` is fixed:: - sage: I.groebner_basis(algorithm="VaPoTe", prec=100) # indirect doctest + sage: I.groebner_basis(algorithm='VaPoTe', prec=100) # indirect doctest [...0000000001*x^3 + ...2222222222*y + ...000000000*x^2*y^2 + O(3^99 * ), ...0000000001*x^2*y + ...01210121020 + O(3^100 * ), ...0000000001*y^2 + ...01210121020*x + ...0000000000*x^3*y + O(3^99 * )] diff --git a/src/sage/rings/tests.py b/src/sage/rings/tests.py index ef8d65da7e1..3796ef7b276 100644 --- a/src/sage/rings/tests.py +++ b/src/sage/rings/tests.py @@ -102,7 +102,7 @@ def integer_mod_ring(): def padic_field(): """ - Return a random p-adic field modulo n with p at most 10000 + Return a random `p`-adic field modulo n with p at most 10000 and precision between 10 and 100. EXAMPLES:: @@ -344,12 +344,10 @@ def test_random_elements(level=MAX_LEVEL, trials=1): INPUT: - - level -- (default: MAX_LEVEL); controls the types of rings to use - - trials -- A positive integer (default 1); the number of trials - to run. - - seed -- the random seed to use; if not specified, uses a truly - random seed. - - print_seed -- If True (default: ``False``), prints the random seed chosen. + - ``level`` -- (default: ``MAX_LEVEL``) controls the types of rings to use + - ``trials`` -- a positive integer (default: 1); the number of trials to run + - ``seed`` -- the random seed to use; if not specified, uses a truly random seed + - ``print_seed`` -- if ``True`` (default: ``False``), prints the random seed chosen EXAMPLES:: @@ -395,12 +393,10 @@ def test_random_arith(level=MAX_LEVEL, trials=1): INPUT: - - ``level`` -- (default: ``MAX_LEVEL``); controls the types of rings to use - - ``trials`` -- A positive integer (default: 1); the number of trials - to run. - - ``seed`` -- the random seed to use; if not specified, uses a truly - random seed. - - ``print_seed`` -- If ``True`` (default: ``False``), prints the random seed chosen. + - ``level`` -- (default: ``MAX_LEVEL``) controls the types of rings to use + - ``trials`` -- positive integer (default: 1); the number of trials to run + - ``seed`` -- the random seed to use; if not specified, uses a truly random seed + - ``print_seed`` -- if ``True`` (default: ``False``), prints the random seed chosen EXAMPLES:: @@ -486,7 +482,6 @@ def test_karatsuba_multiplication(base_ring, maxdeg1, maxdeg2, sage: test_karatsuba_multiplication(ZZ, 10000, 10000, # long time ....: ref_mul=lambda f,g: f*g, ....: base_ring_random_elt_args=[100000]) - """ from sage.misc.prandom import randint from sage.misc.sage_input import sage_input diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index ee3e48a1bd5..8ad6ee44868 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -642,7 +642,7 @@ def _algebraic_(self, R): sage: AA(UCF.gen(5)) Traceback (most recent call last): ... - ValueError: Cannot coerce algebraic number with non-zero imaginary + ValueError: Cannot coerce algebraic number with nonzero imaginary part to algebraic real """ return R(QQbar(self)) @@ -1047,13 +1047,13 @@ def sqrt(self, extend=True, all=False): INPUT: - - ``extend`` -- bool (default: ``True``); if ``True``, might return a - square root in the algebraic closure of the rationals. If false, - return a square root in the universal cyclotomic field or raises - an error. + - ``extend`` -- boolean (default: ``True``); if ``True``, might return + a square root in the algebraic closure of the rationals. If + ``False``, return a square root in the universal cyclotomic field or + raises an error. - - ``all`` -- bool (default: ``False``); if ``True``, return a - list of all square roots. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + list of all square roots EXAMPLES:: @@ -1249,7 +1249,7 @@ def minpoly(self, var='x'): INPUT: - - ``var`` -- (default: 'x') the name of the variable to use. + - ``var`` -- (default: ``'x'``) the name of the variable to use EXAMPLES:: @@ -1586,8 +1586,8 @@ def _factor_univariate_polynomial(self, f): OUTPUT: - - A factorization of ``f`` over self into a unit and monic irreducible - factors + A factorization of ``f`` over ``self`` into a unit and monic + irreducible factors. .. NOTE:: @@ -1620,7 +1620,7 @@ def _factor_univariate_polynomial(self, f): (x - 2) * (x - 2*E(3)) * (x - 2*E(3)^2) In most situations, the factorization will fail with a - :class:`NotImplementedError`:: + :exc:`NotImplementedError`:: sage: (x^3 - 2).factor() Traceback (most recent call last): @@ -1656,7 +1656,7 @@ def _factor_univariate_polynomial(self, f): if f.degree() == 1: return Factorization([(f, 1)], unit) - # From now on, we restrict to polynomial with rational cofficients. The + # From now on, we restrict to polynomial with rational coefficients. The # factorization is provided only in the case it is a product of # cyclotomic polynomials and quadratic polynomials. In this situation # the roots belong to UCF and the polynomial factorizes as a product of diff --git a/src/sage/rings/valuation/augmented_valuation.py b/src/sage/rings/valuation/augmented_valuation.py index 3d415c6e83c..b9f0229f787 100644 --- a/src/sage/rings/valuation/augmented_valuation.py +++ b/src/sage/rings/valuation/augmented_valuation.py @@ -182,7 +182,6 @@ class AugmentedValuationFactory(UniqueFactory): sage: ww = w.augmentation(x, 2) sage: ww._base_valuation is v True - """ def create_key(self, base_valuation, phi, mu, check=True): r""" @@ -205,7 +204,6 @@ def create_key(self, base_valuation, phi, mu, check=True): sage: ww = v.augmentation(x, 1) sage: w is ww True - """ if check: is_key, reason = base_valuation.is_key(phi, explain=True) @@ -236,7 +234,6 @@ def create_object(self, version, key): sage: R. = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = v.augmentation(x^2 + x + 1, 1) # indirect doctest - """ base_valuation, phi, mu = key @@ -285,7 +282,6 @@ class AugmentedValuation_base(InductiveValuation): sage: # needs sage.rings.number_field sage: TestSuite(w).run() # long time sage: TestSuite(ww).run() # long time - """ def __init__(self, parent, v, phi, mu): r""" @@ -301,7 +297,6 @@ def __init__(self, parent, v, phi, mu): sage: isinstance(w, AugmentedValuation_base) True sage: TestSuite(w).run() # long time # needs sage.numerical.mip - """ InductiveValuation.__init__(self, parent, phi) @@ -317,7 +312,7 @@ def equivalence_unit(self, s, reciprocal=False): - ``s`` -- a rational number - - ``reciprocal`` -- a boolean (default: ``False``); whether or not to + - ``reciprocal`` -- boolean (default: ``False``); whether or not to return the equivalence unit as the :meth:`~sage.rings.valuation.inductive_valuation.InductiveValuation.equivalence_reciprocal` of the equivalence unit of valuation ``-s``. @@ -356,7 +351,6 @@ def equivalence_unit(self, s, reciprocal=False): sage: ww = w.augmentation(x^4 + 8, 5) # needs sage.libs.ntl sage: ww.equivalence_unit(1/2) # needs sage.libs.ntl (2^-1 + O(2^4))*x^2 - """ if reciprocal: ret = self._base_valuation.element_with_valuation(s) @@ -379,9 +373,7 @@ def element_with_valuation(self, s): - ``s`` -- a rational number in the value group of this valuation - OUTPUT: - - An element in the domain of this valuation + OUTPUT: an element in the domain of this valuation EXAMPLES:: @@ -405,7 +397,6 @@ def element_with_valuation(self, s): ... ValueError: s must be in the value group of the valuation but 1/3 is not in Additive Abelian Group generated by 1/2. - """ if s not in self.value_group(): raise ValueError("s must be in the value group of the valuation but %r is not in %r." % (s, self.value_group())) @@ -432,7 +423,6 @@ def _repr_(self): sage: w # indirect doctest [ Gauss valuation induced by 2-adic valuation, v((1 + O(2^5))*x^2 + (1 + O(2^5))*x + u + O(2^5)) = 1/2 ] - """ vals = self.augmentation_chain() vals.reverse() @@ -461,7 +451,6 @@ def augmentation_chain(self): sage: ww.augmentation_chain() [[ Gauss valuation induced by 2-adic valuation, v(x) = 2 ], Gauss valuation induced by 2-adic valuation] - """ return [self] + self._base_valuation.augmentation_chain() @@ -470,9 +459,7 @@ def psi(self): r""" Return the minimal polynomial of the residue field extension of this valuation. - OUTPUT: - - A polynomial in the residue ring of the base valuation + OUTPUT: a polynomial in the residue ring of the base valuation EXAMPLES:: @@ -486,7 +473,6 @@ def psi(self): sage: ww = w.augmentation((x^2 + x + u)^2 + 2, 5/3) sage: ww.psi() x + 1 - """ R = self._base_valuation.equivalence_unit(-self._base_valuation(self._phi)) F = self._base_valuation.reduce(self._phi * R, check=False).monic() @@ -511,7 +497,6 @@ def E(self): sage: w = v.augmentation(x, 1/2) sage: w.E() 2 - """ if self.augmentation_chain()[-1]._base_valuation.is_trivial(): raise NotImplementedError("ramification index is not defined over a trivial Gauss valuation") @@ -535,7 +520,6 @@ def F(self): sage: w = v.augmentation(x, 1/2) sage: w.F() 1 - """ return self.phi().degree() // self._base_valuation.E() @@ -550,13 +534,12 @@ def extensions(self, ring): sage: w = v.augmentation(x^2 + x + 1, 1) sage: w.extensions(GaussianIntegers().fraction_field()['x']) # needs sage.rings.number_field [[ Gauss valuation induced by 2-adic valuation, v(x^2 + x + 1) = 1 ]] - """ if ring is self.domain(): return [self] - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring): # univariate + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general): # univariate base_valuations = self._base_valuation.extensions(ring) phi = self.phi().change_ring(ring.base_ring()) @@ -595,8 +578,8 @@ def restriction(self, ring): base = self._base_valuation.restriction(ring) if ring.is_subring(self.domain().base_ring()): return base - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring): # univariate + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general): # univariate return base.augmentation(self.phi().change_ring(ring.base_ring()), self._mu) return super().restriction(ring) @@ -612,7 +595,6 @@ def uniformizer(self): sage: w.uniformizer() 2 - """ return self.element_with_valuation(self.value_group()._generator) @@ -628,7 +610,6 @@ def is_gauss_valuation(self): sage: w.is_gauss_valuation() False - """ assert (self._mu > 0) return False @@ -650,7 +631,6 @@ def monic_integral_model(self, G): Ring endomorphism of Univariate Polynomial Ring in x over Rational Field Defn: x |--> 2*x, x^2 + 1/5*x + 1/5) - """ return self._base_valuation.monic_integral_model(G) @@ -674,7 +654,6 @@ def _ge_(self, other): True sage: www >= ww False - """ from .gauss_valuation import GaussValuation_generic if other.is_trivial(): @@ -700,7 +679,6 @@ def is_trivial(self): sage: w = v.augmentation(x^2 + x + 1, 1) sage: w.is_trivial() False - """ # We need to override the default implementation from valuation_space # because that one uses uniformizer() which might not be implemented if @@ -718,7 +696,6 @@ def scale(self, scalar): sage: w = v.augmentation(x^2 + x + 1, 1) sage: 3*w # indirect doctest [ Gauss valuation induced by 3 * 2-adic valuation, v(x^2 + x + 1) = 3 ] - """ if scalar in QQ and scalar > 0 and scalar != 1: return self._base_valuation.scale(scalar).augmentation(self.phi(), scalar * self._mu) @@ -738,7 +715,6 @@ def _residue_ring_generator_name(self): sage: w = v.augmentation(x^2 + x + 1, 1) sage: w._residue_ring_generator_name() 'u1' - """ base = self._base_valuation.residue_ring().base() # we need a name for a generator that is not present already in base @@ -779,7 +755,6 @@ def _relative_size(self, f): 1 sage: w._relative_size(1048576*x^2 + 1048576*x + 1048576) 11 - """ return self._base_valuation._relative_size(f) @@ -797,7 +772,6 @@ def is_negative_pseudo_valuation(self): sage: w = v.augmentation(x, infinity) sage: w.is_negative_pseudo_valuation() False - """ return False @@ -815,10 +789,9 @@ def change_domain(self, ring): sage: v = v.augmentation(x, 1) sage: v.change_domain(QQ['x']) [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] - """ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring) and ring.variable_name() == self.domain().variable_name(): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general) and ring.variable_name() == self.domain().variable_name(): return self._base_valuation.change_domain(ring).augmentation(self.phi().change_ring(ring.base_ring()), self._mu, check=False) return super().change_domain(ring) @@ -833,7 +806,6 @@ class FinalAugmentedValuation(AugmentedValuation_base, FinalInductiveValuation): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: w = v.augmentation(x, 1) - """ def __init__(self, parent, v, phi, mu): r""" @@ -845,7 +817,6 @@ def __init__(self, parent, v, phi, mu): sage: from sage.rings.valuation.augmented_valuation import FinalAugmentedValuation sage: isinstance(w, FinalAugmentedValuation) True - """ AugmentedValuation_base.__init__(self, parent, v, phi, mu) FinalInductiveValuation.__init__(self, parent, phi) @@ -854,7 +825,7 @@ def __init__(self, parent, v, phi, mu): def residue_ring(self): r""" Return the residue ring of this valuation, i.e., the elements of - non-negative valuation modulo the elements of positive valuation. + nonnegative valuation modulo the elements of positive valuation. EXAMPLES:: @@ -898,7 +869,6 @@ def residue_ring(self): Number Field in uu1 with defining polynomial y^2 - 2 over its base field sage: w.residue_field().base_field() Number Field in u1 with defining polynomial x^2 + 2 - """ # the following is correct, even if the polynomial ring is not over a field @@ -922,7 +892,7 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations - ``f`` -- an element in the domain of this valuation - - ``check`` -- whether or not to check whether ``f`` has non-negative + - ``check`` -- whether or not to check whether ``f`` has nonnegative valuation (default: ``True``) - ``degree_bound`` -- an a-priori known bound on the degree of the @@ -994,14 +964,13 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations x sage: ww.reduce(f + g) x + 1 - """ f = self.domain().coerce(f) if check: v = self(f) if v < 0: - raise ValueError("f must have non-negative valuation") + raise ValueError("f must have nonnegative valuation") elif v > 0: return self.residue_ring().zero() @@ -1039,7 +1008,6 @@ def _residue_field_generator(self): sage: w = v.augmentation(x^2 + x + u, infinity) sage: w._residue_field_generator() # needs sage.rings.number_field u1 - """ if self.psi().degree() == 1: ret = self.residue_ring()(-self.psi()[0]) @@ -1061,9 +1029,7 @@ def lift(self, F): We simply undo the steps performed in :meth:`reduce`. - OUTPUT: - - A polynomial in the domain of the valuation with reduction ``F`` + OUTPUT: a polynomial in the domain of the valuation with reduction ``F`` EXAMPLES:: @@ -1100,7 +1066,6 @@ def lift(self, F): sage: v = v0.augmentation(x^2 + x + 2, 1) sage: v.lift(v.reduce(x)) == x True - """ F = self.residue_ring().coerce(F) @@ -1140,7 +1105,6 @@ class NonFinalAugmentedValuation(AugmentedValuation_base, NonFinalInductiveValua sage: R. = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = v.augmentation(x^2 + x + 1, 1) - """ def __init__(self, parent, v, phi, mu): r""" @@ -1152,7 +1116,6 @@ def __init__(self, parent, v, phi, mu): sage: from sage.rings.valuation.augmented_valuation import NonFinalAugmentedValuation sage: isinstance(w, NonFinalAugmentedValuation) True - """ AugmentedValuation_base.__init__(self, parent, v, phi, mu) NonFinalInductiveValuation.__init__(self, parent, phi) @@ -1161,7 +1124,7 @@ def __init__(self, parent, v, phi, mu): def residue_ring(self): r""" Return the residue ring of this valuation, i.e., the elements of - non-negative valuation modulo the elements of positive valuation. + nonnegative valuation modulo the elements of positive valuation. EXAMPLES:: @@ -1178,7 +1141,6 @@ def residue_ring(self): sage: w = v.augmentation(x, 1) sage: w.residue_ring() Univariate Polynomial Ring in x over Finite Field of size 2 (using ...) - """ from sage.categories.fields import Fields if self.domain().base() not in Fields(): @@ -1205,7 +1167,7 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations - ``f`` -- an element in the domain of this valuation - - ``check`` -- whether or not to check whether ``f`` has non-negative + - ``check`` -- whether or not to check whether ``f`` has nonnegative valuation (default: ``True``) - ``degree_bound`` -- an a-priori known bound on the degree of the @@ -1279,7 +1241,6 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations x sage: ww.reduce(f + g) x + 1 - """ f = self.domain().coerce(f) @@ -1349,7 +1310,6 @@ def _residue_field_generator(self): sage: w = v.augmentation(x^2 + x + u, 1/2) sage: w._residue_field_generator() u1 - """ if self.residue_ring() == self._base_valuation.residue_ring(): assert self.psi().degree() == 1 @@ -1426,12 +1386,11 @@ def lift(self, F, report_coefficients=False): (2^-1 + O(2^9))*x^2 + (2^-1 + O(2^9))*x + u*2^-1 + O(2^9) sage: F == ww.reduce(f) True - """ F = self.residue_ring().coerce(F) from sage.categories.fields import Fields - if not self.domain().base_ring() in Fields(): + if self.domain().base_ring() not in Fields(): raise NotImplementedError("only implemented for polynomial rings over fields") if F.is_constant(): @@ -1518,12 +1477,11 @@ def lift_to_key(self, F, check=True): 12 sage: ww.is_key(f) True - """ F = self.residue_ring().coerce(F) from sage.categories.fields import Fields - if not self.domain().base_ring() in Fields(): + if self.domain().base_ring() not in Fields(): raise NotImplementedError("only implemented for polynomial rings over fields") if check: @@ -1550,7 +1508,7 @@ def lift_to_key(self, F, check=True): coefficients[-2] %= self.phi() tau = self.value_group().index(self._base_valuation.value_group()) vf = self._mu * tau * F.degree() - ret = self.domain().change_ring(self.domain())([c for c in coefficients])(self.phi()**tau) + ret = self.domain().change_ring(self.domain())(coefficients)(self.phi()**tau) ret = self.simplify(ret, error=vf, force=True) ret = ret.map_coefficients(_lift_to_maximal_precision) assert (ret == self.phi()) == (F == F.parent().gen()) @@ -1571,7 +1529,6 @@ def _Q(self, e): sage: w._Q(1) 2 - """ tau = self.value_group().index(self._base_valuation.value_group()) v = self._mu * tau @@ -1591,7 +1548,6 @@ def _Q_reciprocal(self, e=1): sage: w._Q_reciprocal() 1/2 - """ if e == 1: return self.equivalence_reciprocal(self._Q(1), check=False) @@ -1621,7 +1577,6 @@ class FiniteAugmentedValuation(AugmentedValuation_base, FiniteInductiveValuation sage: S. = R[] sage: v = GaussValuation(S) sage: w = v.augmentation(x^2 + x + u, 1/2) - """ def __init__(self, parent, v, phi, mu): r""" @@ -1635,7 +1590,6 @@ def __init__(self, parent, v, phi, mu): sage: from sage.rings.valuation.augmented_valuation import FiniteAugmentedValuation sage: isinstance(w, FiniteAugmentedValuation) True - """ AugmentedValuation_base.__init__(self, parent, v, phi, mu) FiniteInductiveValuation.__init__(self, parent, phi) @@ -1657,7 +1611,6 @@ def value_group(self): sage: ww = w.augmentation((x^2 + x + u)^2 + 2, 5/3) sage: ww.value_group() Additive Abelian Group generated by 1/6 - """ return self._base_valuation.value_group() + self._mu @@ -1677,7 +1630,6 @@ def value_semigroup(self): sage: ww = w.augmentation((x^2 + x + u)^2 + 2, 5/3) sage: ww.value_semigroup() Additive Abelian Semigroup generated by 1/2, 5/3 - """ return self._base_valuation.value_semigroup() + self._mu @@ -1716,7 +1668,6 @@ def valuations(self, f, coefficients=None, call_error=False): sage: ww = w.augmentation((x^2 + x + u)^2 + 2, 5/3) sage: list(ww.valuations( ((x^2 + x + u)^2 + 2)^3 )) [+Infinity, +Infinity, +Infinity, 5] - """ f = self.domain().coerce(f) @@ -1802,7 +1753,6 @@ def simplify(self, f, error=None, force=False, effective_degree=None, size_heuri [ Gauss valuation induced by 2-adic valuation, v(x) = 3/2, v(x^2 + 8) = 13/4, v(x^4 + 16*x^2 + 32*x + 64) = 20/3 ], v(y + 4*x + 8) = 31/8 ]] - """ f = self.domain().coerce(f) @@ -1874,7 +1824,6 @@ def lower_bound(self, f): sage: w = v.augmentation(x^2 + x + u, 1/2) sage: w.lower_bound(x^2 + x + u) 0 - """ f = self.domain().coerce(f) @@ -1917,7 +1866,6 @@ def upper_bound(self, f): sage: w = v.augmentation(x^2 + x + u, 1/2) sage: w.upper_bound(x^2 + x + u) 1/2 - """ f = self.domain().coerce(f) @@ -1936,7 +1884,6 @@ class FinalFiniteAugmentedValuation(FiniteAugmentedValuation, FinalAugmentedValu sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: w = v.augmentation(x, 1) - """ def __init__(self, parent, v, phi, mu): r""" @@ -1948,7 +1895,6 @@ def __init__(self, parent, v, phi, mu): sage: from sage.rings.valuation.augmented_valuation import FinalFiniteAugmentedValuation sage: isinstance(w, FinalFiniteAugmentedValuation) True - """ FiniteAugmentedValuation.__init__(self, parent, v, phi, mu) FinalAugmentedValuation.__init__(self, parent, v, phi, mu) @@ -1975,7 +1921,6 @@ def __init__(self, parent, v, phi, mu): sage: from sage.rings.valuation.augmented_valuation import NonFinalFiniteAugmentedValuation sage: isinstance(w, NonFinalFiniteAugmentedValuation) True - """ FiniteAugmentedValuation.__init__(self, parent, v, phi, mu) NonFinalAugmentedValuation.__init__(self, parent, v, phi, mu) @@ -1992,7 +1937,6 @@ class InfiniteAugmentedValuation(FinalAugmentedValuation, InfiniteInductiveValua sage: R. = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = v.augmentation(x, infinity) - """ def __init__(self, parent, v, phi, mu): r""" @@ -2004,7 +1948,6 @@ def __init__(self, parent, v, phi, mu): sage: from sage.rings.valuation.augmented_valuation import InfiniteAugmentedValuation sage: isinstance(w, InfiniteAugmentedValuation) True - """ FinalAugmentedValuation.__init__(self, parent, v, phi, mu) InfiniteInductiveValuation.__init__(self, parent, phi) @@ -2023,7 +1966,6 @@ def value_group(self): sage: w = v.augmentation(x, infinity) sage: w.value_group() Additive Abelian Group generated by 1 - """ return self._base_valuation.value_group() @@ -2041,7 +1983,6 @@ def value_semigroup(self): sage: w = v.augmentation(x, infinity) sage: w.value_semigroup() Additive Abelian Semigroup generated by 1 - """ return self._base_valuation.value_semigroup() @@ -2077,7 +2018,6 @@ def valuations(self, f, coefficients=None, call_error=False): sage: w = v.augmentation(x, infinity) sage: list(w.valuations(x^2 + 1)) [0, +Infinity, +Infinity] - """ f = self.domain().coerce(f) @@ -2121,7 +2061,6 @@ def simplify(self, f, error=None, force=False, effective_degree=None): sage: w = v.augmentation(x^2 + x + u, infinity) sage: w.simplify(x^10/2 + 1, force=True) (u + 1)*2^-1 + O(2^4) - """ f = self.domain().coerce(f) @@ -2149,7 +2088,6 @@ def lower_bound(self, f): sage: w = v.augmentation(x^2 + x + u, infinity) sage: w.lower_bound(x^2 + x + u) +Infinity - """ return self._base_valuation.lower_bound(next(self.coefficients(f))) @@ -2169,6 +2107,5 @@ def upper_bound(self, f): sage: w = v.augmentation(x^2 + x + u, infinity) sage: w.upper_bound(x^2 + x + u) +Infinity - """ return self._base_valuation.upper_bound(next(self.coefficients(f))) diff --git a/src/sage/rings/valuation/developing_valuation.py b/src/sage/rings/valuation/developing_valuation.py index f99c2b5161c..8b77224f591 100644 --- a/src/sage/rings/valuation/developing_valuation.py +++ b/src/sage/rings/valuation/developing_valuation.py @@ -67,7 +67,6 @@ class DevelopingValuation(DiscretePseudoValuation): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def __init__(self, parent, phi): r""" @@ -78,13 +77,12 @@ def __init__(self, parent, phi): sage: from sage.rings.valuation.developing_valuation import DevelopingValuation sage: isinstance(v, DevelopingValuation) True - """ DiscretePseudoValuation.__init__(self, parent) domain = parent.domain() - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if not is_PolynomialRing(domain) or not domain.ngens() == 1: + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if not isinstance(domain, PolynomialRing_general) or not domain.ngens() == 1: raise TypeError("domain must be a univariate polynomial ring but %r is not" % (domain,)) phi = domain.coerce(phi) @@ -104,7 +102,6 @@ def phi(self): sage: v = GaussValuation(S) # needs sage.libs.ntl sage: v.phi() # needs sage.libs.ntl (1 + O(2^5))*x - """ return self._phi @@ -118,7 +115,7 @@ def effective_degree(self, f, valuations=None): INPUT: - - ``f`` -- a non-zero polynomial in the domain of this valuation + - ``f`` -- a nonzero polynomial in the domain of this valuation EXAMPLES:: @@ -130,12 +127,11 @@ def effective_degree(self, f, valuations=None): 1 sage: v.effective_degree(2*x + 1) 0 - """ f = self.domain().coerce(f) if f.is_zero(): - raise ValueError("the effective degree is only defined for non-zero polynomials") + raise ValueError("the effective degree is only defined for nonzero polynomials") if valuations is None: valuations = list(self.valuations(f)) @@ -161,7 +157,6 @@ def _pow(self, f, e, error, effective_degree): sage: v = GaussValuation(S) sage: v._pow(2*x + 1, 10, effective_degree=0, error=5) 1 + O(2^5) - """ if e == 0: return self.domain().one() @@ -199,7 +194,6 @@ def coefficients(self, f): sage: v = v.augmentation( x^2 + x + 1, 1) sage: list(v.coefficients(f)) [(1 + O(2^5))*x + 2 + O(2^5), 1 + O(2^5)] - """ domain = self.domain() f = domain.coerce(f) @@ -252,7 +246,6 @@ def newton_polygon(self, f, valuations=None): Finite Newton polygon with 2 vertices: (0, 0), (1, 1) sage: v.newton_polygon( f * v.phi()^3 ) # needs sage.geometry.polyhedron Finite Newton polygon with 2 vertices: (3, 3), (4, 4) - """ f = self.domain().coerce(f) @@ -287,7 +280,6 @@ def _call_(self, f): 3 sage: v(S.zero()) +Infinity - """ f = self.domain().coerce(f) @@ -325,7 +317,6 @@ def valuations(self, f): sage: f = x^2 + 2*x + 16 sage: list(v.valuations(f)) [4, 1, 0] - """ def _test_effective_degree(self, **options): diff --git a/src/sage/rings/valuation/gauss_valuation.py b/src/sage/rings/valuation/gauss_valuation.py index 0443ba9c670..ca67b25274e 100644 --- a/src/sage/rings/valuation/gauss_valuation.py +++ b/src/sage/rings/valuation/gauss_valuation.py @@ -87,10 +87,9 @@ def create_key(self, domain, v=None): Traceback (most recent call last): ... ValueError: the domain of v must be the base ring of domain but 2-adic valuation is not defined over Integer Ring but over Rational Field - """ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if not is_PolynomialRing(domain): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if not isinstance(domain, PolynomialRing_general): raise TypeError("GaussValuations can only be created over polynomial rings but %r is not a polynomial ring" % (domain,)) if not domain.ngens() == 1: raise NotImplementedError("domain must be univariate but %r is not univariate" % (domain,)) @@ -115,7 +114,6 @@ def create_object(self, version, key, **extra_args): sage: R. = QQ[] sage: GaussValuation.create_object(0, (R, v)) Gauss valuation induced by 2-adic valuation - """ domain, v = key from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace @@ -151,7 +149,6 @@ class GaussValuation_generic(NonFinalInductiveValuation): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def __init__(self, parent, v): """ @@ -162,7 +159,6 @@ def __init__(self, parent, v): sage: v = GaussValuation(S, QQ.valuation(5)) sage: isinstance(v, GaussValuation_generic) True - """ NonFinalInductiveValuation.__init__(self, parent, parent.domain().gen()) @@ -178,7 +174,6 @@ def value_group(self): sage: v = GaussValuation(S, QQ.valuation(5)) sage: v.value_group() Additive Abelian Group generated by 1 - """ return self._base_valuation.value_group() @@ -192,7 +187,6 @@ def value_semigroup(self): sage: v = GaussValuation(S, QQ.valuation(5)) sage: v.value_semigroup() Additive Abelian Semigroup generated by -1, 1 - """ return self._base_valuation.value_semigroup() @@ -223,7 +217,6 @@ def uniformizer(self): 5 sage: v.uniformizer().parent() is S True - """ return self.domain()(self._base_valuation.uniformizer()) @@ -244,9 +237,8 @@ def valuations(self, f, coefficients=None, call_error=False): assuming that the result is only used to compute the valuation of ``f`` (default: ``False``) - OUTPUT: - - A list, each entry a rational numbers or infinity, the valuations of `f_0, f_1\phi, \dots` + OUTPUT: list, each entry a rational numbers or infinity, the valuations + of `f_0, f_1\phi, \dots` EXAMPLES:: @@ -297,7 +289,6 @@ def residue_ring(self): sage: v = GaussValuation(S) # needs sage.libs.ntl sage: v.residue_ring() # needs sage.libs.ntl Univariate Polynomial Ring in x over Finite Field of size 2 (using ...) - """ return self.domain().change_ring(self._base_valuation.residue_ring()) @@ -309,7 +300,7 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations - ``f`` -- an integral element of the domain of this valuation - - ``check`` -- whether or not to check whether ``f`` has non-negative + - ``check`` -- whether or not to check whether ``f`` has nonnegative valuation (default: ``True``) - ``degree_bound`` -- an a-priori known bound on the degree of the @@ -321,9 +312,7 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations - ``valuations`` -- the valuations of ``coefficients`` or ``None`` (default: ``None``); ignored - OUTPUT: - - A polynomial in the :meth:`residue_ring` of this valuation. + OUTPUT: a polynomial in the :meth:`residue_ring` of this valuation EXAMPLES:: @@ -347,7 +336,6 @@ def reduce(self, f, check=True, degree_bound=None, coefficients=None, valuations .. SEEALSO:: :meth:`lift` - """ f = self.domain().coerce(f) @@ -421,7 +409,6 @@ def lift_to_key(self, F): sage: y = v.residue_ring().gen() sage: f = v.lift_to_key(y^2 + y + 1); f x^2 + x + 1 - """ F = self.residue_ring().coerce(F) @@ -443,7 +430,7 @@ def equivalence_unit(self, s, reciprocal=False): - ``s`` -- an element of the :meth:`value_group` - - ``reciprocal`` -- a boolean (default: ``False``); whether or not to + - ``reciprocal`` -- boolean (default: ``False``); whether or not to return the equivalence unit as the :meth:`~sage.rings.valuation.inductive_valuation.InductiveValuation.equivalence_reciprocal` of the equivalence unit of valuation ``-s`` @@ -456,7 +443,6 @@ def equivalence_unit(self, s, reciprocal=False): 3^2 + O(3^7) sage: v.equivalence_unit(-2) 3^-2 + O(3^3) - """ if reciprocal: return self.equivalence_reciprocal(self.equivalence_unit(-s)) @@ -474,7 +460,6 @@ def element_with_valuation(self, s): sage: v = GaussValuation(R, QQ.valuation(2)) sage: v.element_with_valuation(-2) 1/4 - """ return self.equivalence_unit(s) @@ -491,7 +476,6 @@ def E(self): sage: v = GaussValuation(S) sage: v.E() 1 - """ from sage.rings.integer_ring import ZZ return ZZ.one() @@ -509,7 +493,6 @@ def F(self): sage: v = GaussValuation(S) sage: v.F() 1 - """ from sage.rings.integer_ring import ZZ return ZZ.one() @@ -525,10 +508,9 @@ def change_domain(self, ring): sage: w = GaussValuation(R, v) sage: w.change_domain(QQ['x']) Gauss valuation induced by 2-adic valuation - """ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring) and ring.ngens() == 1: + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general) and ring.ngens() == 1: base_valuation = self._base_valuation.change_domain(ring.base_ring()) return GaussValuation(self.domain().change_ring(ring.base_ring()), base_valuation) return super().change_domain(ring) @@ -544,10 +526,9 @@ def extensions(self, ring): sage: w = GaussValuation(R, v) sage: w.extensions(GaussianIntegers()['x']) # needs sage.rings.number_field [Gauss valuation induced by 2-adic valuation] - """ - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring) and ring.ngens() == 1: + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general) and ring.ngens() == 1: if self.domain().is_subring(ring): return [GaussValuation(ring, w) for w in self._base_valuation.extensions(ring.base_ring())] return super().extensions(ring) @@ -563,12 +544,11 @@ def restriction(self, ring): sage: w = GaussValuation(R, v) sage: w.restriction(ZZ) 2-adic valuation - """ if ring.is_subring(self.domain().base_ring()): return self._base_valuation.restriction(ring) - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring) and ring.ngens() == 1: + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general) and ring.ngens() == 1: if ring.base().is_subring(self.domain().base()): return GaussValuation(ring, self._base_valuation.restriction(ring.base())) return super().restriction(ring) @@ -585,7 +565,6 @@ def is_gauss_valuation(self): sage: v = GaussValuation(S) sage: v.is_gauss_valuation() True - """ return True @@ -602,7 +581,6 @@ def augmentation_chain(self): sage: v = GaussValuation(S) sage: v.augmentation_chain() [Gauss valuation induced by 2-adic valuation] - """ return [self] @@ -617,7 +595,6 @@ def is_trivial(self): sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v.is_trivial() True - """ return self._base_valuation.is_trivial() @@ -637,7 +614,6 @@ def monic_integral_model(self, G): Ring endomorphism of Univariate Polynomial Ring in x over 2-adic Field with capped relative precision 5 Defn: (1 + O(2^5))*x |--> (2 + O(2^6))*x, (1 + O(2^5))*x^2 + (1 + 2^2 + 2^3 + O(2^5))*x + 1 + 2^2 + 2^3 + O(2^5)) - """ if not G.is_monic(): # this might fail if the base ring is not a field @@ -672,7 +648,6 @@ def _ge_(self, other): False sage: w >= v False - """ if isinstance(other, GaussValuation_generic): return self._base_valuation >= other._base_valuation @@ -693,7 +668,6 @@ def scale(self, scalar): sage: v = GaussValuation(R, QQ.valuation(2)) sage: 3*v # indirect doctest Gauss valuation induced by 3 * 2-adic valuation - """ from sage.rings.rational_field import QQ if scalar in QQ and scalar > 0 and scalar != 1: @@ -725,7 +699,6 @@ def _relative_size(self, f): sage: v._relative_size(1024*x + 1) 1 - """ return self._base_valuation._relative_size(f[0]) @@ -767,7 +740,6 @@ def simplify(self, f, error=None, force=False, size_heuristic_bound=32, effectiv sage: f = x^10/2 + 1 sage: v.simplify(f) (2^-1 + O(2^4))*x^10 + 1 + O(2^5) - """ f = self.domain().coerce(f) @@ -801,7 +773,6 @@ def lower_bound(self, f): 1 sage: v(1024*x + 2) 1 - """ from sage.rings.infinity import infinity coefficients = f.coefficients(sparse=True) diff --git a/src/sage/rings/valuation/inductive_valuation.py b/src/sage/rings/valuation/inductive_valuation.py index 40f405e1b21..470e4990bed 100644 --- a/src/sage/rings/valuation/inductive_valuation.py +++ b/src/sage/rings/valuation/inductive_valuation.py @@ -55,7 +55,6 @@ class InductiveValuation(DevelopingValuation): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def is_equivalence_unit(self, f, valuations=None): r""" @@ -79,7 +78,6 @@ def is_equivalence_unit(self, f, valuations=None): False sage: v.is_equivalence_unit(2*x + 1) True - """ f = self.domain().coerce(f) @@ -167,7 +165,6 @@ def equivalence_reciprocal(self, f, coefficients=None, valuations=None, check=Tr sage: f_ = w.equivalence_reciprocal(f) sage: w.reduce(f*f_) 1 - """ f = self.domain().coerce(f) @@ -200,7 +197,7 @@ def equivalence_reciprocal(self, f, coefficients=None, valuations=None, check=Tr h = self.simplify(h, -vf) - # it might be the case that f*h has non-zero valuation because h has + # it might be the case that f*h has nonzero valuation because h has # insufficient precision, so we must not assert that here but only # until we lifted to higher precision @@ -223,7 +220,6 @@ def mu(self): sage: v = GaussValuation(R, QQ.valuation(2)) sage: v.mu() 0 - """ return self(self.phi()) @@ -236,7 +232,7 @@ def equivalence_unit(self, s, reciprocal=False): - ``s`` -- an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.value_group` - - ``reciprocal`` -- a boolean (default: ``False``); whether or not to + - ``reciprocal`` -- boolean (default: ``False``); whether or not to return the equivalence unit as the :meth:`equivalence_reciprocal` of the equivalence unit of valuation ``-s``. @@ -263,7 +259,6 @@ def equivalence_unit(self, s, reciprocal=False): ... ValueError: s must be in the value semigroup of this valuation but -1 is not in Additive Abelian Semigroup generated by 1 - """ @abstract_method @@ -280,7 +275,6 @@ def augmentation_chain(self): sage: v = GaussValuation(S) sage: v.augmentation_chain() [Gauss valuation induced by 2-adic valuation] - """ @abstract_method @@ -296,7 +290,6 @@ def is_gauss_valuation(self): sage: v = GaussValuation(S) sage: v.is_gauss_valuation() True - """ @abstract_method @@ -313,7 +306,6 @@ def E(self): sage: v = GaussValuation(S) sage: v.E() 1 - """ @abstract_method @@ -329,7 +321,6 @@ def F(self): sage: v = GaussValuation(S) sage: v.F() 1 - """ @abstract_method @@ -349,7 +340,6 @@ def monic_integral_model(self, G): Ring endomorphism of Univariate Polynomial Ring in x over Rational Field Defn: x |--> 2*x, x^2 + 1/5*x + 1/5) - """ @abstract_method @@ -374,7 +364,6 @@ def element_with_valuation(self, s): ... ValueError: s must be in the value semigroup of this valuation but -2 is not in Additive Abelian Semigroup generated by 1 - """ def _test_element_with_valuation_inductive_valuation(self, **options): @@ -386,7 +375,6 @@ def _test_element_with_valuation_inductive_valuation(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: v._test_element_with_valuation_inductive_valuation() - """ tester = self._tester(**options) chain = self.augmentation_chain() @@ -419,7 +407,6 @@ def _test_EF(self, **options): sage: S. = R[] sage: v = GaussValuation(S) sage: v._test_EF() - """ tester = self._tester(**options) chain = self.augmentation_chain() @@ -442,7 +429,6 @@ def _test_augmentation_chain(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_augmentation_chain() - """ tester = self._tester(**options) chain = self.augmentation_chain() @@ -460,7 +446,6 @@ def _test_equivalence_unit(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_equivalence_unit() - """ tester = self._tester(**options) @@ -492,7 +477,6 @@ def _test_is_equivalence_unit(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_is_equivalence_unit() - """ tester = self._tester(**options) tester.assertFalse(self.is_equivalence_unit(self.phi())) @@ -506,7 +490,6 @@ def _test_equivalence_reciprocal(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_equivalence_reciprocal() - """ tester = self._tester(**options) S = tester.some_elements(self.domain().some_elements()) @@ -536,7 +519,6 @@ def _test_inductive_valuation_inheritance(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_inductive_valuation_inheritance() - """ tester = self._tester(**options) tester.assertNotEqual(isinstance(self, InfiniteInductiveValuation), @@ -555,7 +537,6 @@ class FiniteInductiveValuation(InductiveValuation, DiscreteValuation): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) - """ def __init__(self, parent, phi): r""" @@ -566,7 +547,6 @@ def __init__(self, parent, phi): sage: from sage.rings.valuation.inductive_valuation import FiniteInductiveValuation sage: isinstance(v, FiniteInductiveValuation) True - """ InductiveValuation.__init__(self, parent, phi) DiscreteValuation.__init__(self, parent) @@ -582,7 +562,6 @@ def extensions(self, other): sage: K. = FunctionField(QQ) sage: v.extensions(K) [Trivial valuation on Rational Field] - """ from sage.categories.function_fields import FunctionFields if other in FunctionFields() and other.ngens() == 1: @@ -605,7 +584,6 @@ class NonFinalInductiveValuation(FiniteInductiveValuation, DiscreteValuation): sage: S. = R[] sage: v = GaussValuation(S) sage: v = v.augmentation(x^2 + x + u, 1) - """ def __init__(self, parent, phi): r""" @@ -619,7 +597,6 @@ def __init__(self, parent, phi): sage: from sage.rings.valuation.inductive_valuation import NonFinalInductiveValuation sage: isinstance(v, NonFinalInductiveValuation) True - """ FiniteInductiveValuation.__init__(self, parent, phi) DiscreteValuation.__init__(self, parent) @@ -638,7 +615,7 @@ def augmentation(self, phi, mu, check=True): - ``mu`` -- a rational number or infinity, the valuation of ``phi`` in the extended valuation - - ``check`` -- a boolean (default: ``True``), whether or not to check + - ``check`` -- boolean (default: ``True``); whether or not to check the correctness of the parameters EXAMPLES:: @@ -677,7 +654,6 @@ def augmentation(self, phi, mu, check=True): .. SEEALSO:: :mod:`~sage.rings.valuation.augmented_valuation` - """ from .augmented_valuation import AugmentedValuation return AugmentedValuation(self, phi, mu, check) @@ -695,7 +671,7 @@ def mac_lane_step(self, G, principal_part_bound=None, assume_squarefree=False, a - ``G`` -- a squarefree monic non-constant integral polynomial ``G`` which is not an :meth:`equivalence unit ` - - ``principal_part_bound`` -- an integer or ``None`` (default: + - ``principal_part_bound`` -- integer or ``None`` (default: ``None``), a bound on the length of the principal part, i.e., the section of negative slope, of the Newton polygon of ``G`` @@ -786,7 +762,6 @@ def mac_lane_step(self, G, principal_part_bound=None, assume_squarefree=False, a sage: f = x^4 - 30*x^2 - 75 sage: v.mac_lane_step(f) # needs sage.geometry.polyhedron [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = 3/4 ]] - """ G = self.domain().coerce(G) @@ -823,7 +798,7 @@ def mac_lane_step(self, G, principal_part_bound=None, assume_squarefree=False, a raise ValueError("G must be squarefree") from sage.rings.infinity import infinity - assert self(G) is not infinity # this is a valuation and G is non-zero + assert self(G) is not infinity # this is a valuation and G is nonzero ret = [] @@ -944,7 +919,7 @@ def is_key(self, phi, explain=False, assume_equivalence_irreducible=False): - ``phi`` -- a polynomial in the domain of this valuation - - ``explain`` -- a boolean (default: ``False``), if ``True``, return a + - ``explain`` -- boolean (default: ``False``); if ``True``, return a string explaining why ``phi`` is not a key polynomial EXAMPLES:: @@ -962,7 +937,6 @@ def is_key(self, phi, explain=False, assume_equivalence_irreducible=False): sage: w = v.augmentation(x, 1) sage: w.is_key(x + 1, explain = True) (False, 'phi must be minimal') - """ phi = self.domain().coerce(phi) @@ -986,7 +960,7 @@ def is_minimal(self, f, assume_equivalence_irreducible=False): valuation. A polynomial `f` is minimal with respect to `v` if it is not a constant - and any non-zero polynomial `h` which is `v`-divisible by `f` has at + and any nonzero polynomial `h` which is `v`-divisible by `f` has at least the degree of `f`. A polynomial `h` is `v`-divisible by `f` if there is a polynomial `c` @@ -1027,7 +1001,6 @@ def is_minimal(self, f, assume_equivalence_irreducible=False): True sage: v2.is_minimal(x^4 + 4) # needs sage.libs.ntl False - """ f = self.domain().coerce(f) @@ -1092,7 +1065,6 @@ def _equivalence_reduction(self, f, coefficients=None, valuations=None, degree_b sage: v = GaussValuation(R, QQ.valuation(2)) sage: v._equivalence_reduction(2*x^6 + 4*x^5 + 2*x^4 + 8) (1, 4, x^2 + 1) - """ f = self.domain().coerce(f) @@ -1159,7 +1131,6 @@ def is_equivalence_irreducible(self, f, coefficients=None, valuations=None): False sage: v.is_equivalence_irreducible(x^2 + 2) False - """ f = self.domain().coerce(f) @@ -1188,7 +1159,7 @@ def equivalence_decomposition(self, f, assume_not_equivalence_unit=False, coeffi INPUT: - - ``f`` -- a non-zero polynomial in the domain of this valuation + - ``f`` -- a nonzero polynomial in the domain of this valuation - ``assume_not_equivalence_unit`` -- whether or not to assume that ``f`` is not an :meth:`equivalence unit ` @@ -1299,7 +1270,6 @@ def equivalence_decomposition(self, f, assume_not_equivalence_unit=False, coeffi x^4 - 343/2*x^2 + 1294139 sage: v2.is_equivalent(F.prod(), f) True - """ f = self.domain().coerce(f) @@ -1369,11 +1339,9 @@ def minimal_representative(self, f): INPUT: - - ``f`` -- a non-zero polynomial which is not an equivalence unit - - OUTPUT: + - ``f`` -- a nonzero polynomial which is not an equivalence unit - A factorization which has `e` as its unit and `a` as its unique factor. + OUTPUT: a factorization which has `e` as its unit and `a` as its unique factor ALGORITHM: @@ -1403,12 +1371,11 @@ def minimal_representative(self, f): True sage: v.is_equivalent(F.prod(), f) True - """ f = self.domain().coerce(f) from sage.categories.fields import Fields - if not self.domain().base_ring() in Fields(): + if self.domain().base_ring() not in Fields(): raise NotImplementedError("only implemented for polynomial rings over fields") if f.is_zero(): @@ -1473,7 +1440,6 @@ def lift_to_key(self, F): sage: u0 = v.residue_ring().base_ring().gen() sage: f = v.lift_to_key(y^2 + y + u0); f (1 + O(2^10))*x^2 + (1 + O(2^10))*x + u + O(2^10) - """ def _eliminate_denominators(self, f): @@ -1484,7 +1450,7 @@ def _eliminate_denominators(self, f): INPUT: - ``f`` -- a polynomial with coefficients in the fraction field of the - base ring of the domain of this valuation. + base ring of the domain of this valuation EXAMPLES:: @@ -1509,7 +1475,6 @@ def _eliminate_denominators(self, f): sage: w._eliminate_denominators(x^3/2 + x) x - """ if f in self.domain(): return self.domain()(f) @@ -1550,7 +1515,6 @@ def _test_eliminate_denominators(self, **options): sage: R. = ZZ[] sage: v = GaussValuation(R, ZZ.valuation(2)) sage: v._test_eliminate_denominators() - """ tester = self._tester(**options) @@ -1577,7 +1541,6 @@ def _test_lift_to_key(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_lift_to_key() # needs sage.rings.number_field - """ tester = self._tester(**options) @@ -1625,7 +1588,6 @@ def _test_is_equivalence_irreducible(self, **options): sage: R. = QQ[] sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)) sage: v._test_is_equivalence_irreducible() - """ tester = self._tester(**options) S = tester.some_elements(self.domain().some_elements()) @@ -1668,7 +1630,6 @@ class InfiniteInductiveValuation(FinalInductiveValuation, InfiniteDiscretePseudo sage: R. = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = v.augmentation(x^2 + x + 1, infinity) - """ def __init__(self, parent, base_valuation): r""" @@ -1680,7 +1641,6 @@ def __init__(self, parent, base_valuation): sage: from sage.rings.valuation.inductive_valuation import InfiniteInductiveValuation sage: isinstance(w, InfiniteInductiveValuation) True - """ FinalInductiveValuation.__init__(self, parent, base_valuation) InfiniteDiscretePseudoValuation.__init__(self, parent) @@ -1698,10 +1658,9 @@ def change_domain(self, ring): sage: w = v.augmentation(x^2 + x + 1, infinity) sage: w.change_domain(R.quo(x^2 + x + 1)) 2-adic valuation - """ - from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing - if is_PolynomialQuotientRing(ring) and ring.base() is self.domain() and ring.modulus() == self.phi(): + from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic + if isinstance(ring, PolynomialQuotientRing_generic) and ring.base() is self.domain() and ring.modulus() == self.phi(): return self.restriction(self.domain().base())._extensions_to_quotient(ring, approximants=[self])[0] return super().change_domain(ring) @@ -1722,6 +1681,5 @@ def _lift_to_maximal_precision(c): sage: x = 1 sage: _lift_to_maximal_precision(x) 1 - """ return c if c.parent().is_exact() else c.lift_to_precision() diff --git a/src/sage/rings/valuation/limit_valuation.py b/src/sage/rings/valuation/limit_valuation.py index 11b41cf9fed..86a64d23f99 100644 --- a/src/sage/rings/valuation/limit_valuation.py +++ b/src/sage/rings/valuation/limit_valuation.py @@ -97,7 +97,7 @@ class LimitValuationFactory(UniqueFactory): uniquely augmented (possibly only in the limit) to a pseudo-valuation that sends ``G`` to infinity. - - ``G`` -- a squarefree polynomial in the domain of ``base_valuation``. + - ``G`` -- a squarefree polynomial in the domain of ``base_valuation`` EXAMPLES:: @@ -106,7 +106,6 @@ class LimitValuationFactory(UniqueFactory): sage: w = valuations.LimitValuation(v, x) sage: w(x) +Infinity - """ def create_key(self, base_valuation, G): r""" @@ -128,7 +127,6 @@ def create_key(self, base_valuation, G): The point here is that this is not meant to be invoked from user code. But mostly from other factories which have made sure that the parameters are normalized already. - """ if not base_valuation.restriction(G.parent().base_ring()).is_discrete_valuation(): raise ValueError("base_valuation must be discrete on the coefficient ring.") @@ -143,7 +141,6 @@ def create_object(self, version, key): sage: R. = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = valuations.LimitValuation(v, x^2 + 1) # indirect doctest - """ base_valuation, G = key from .valuation_space import DiscretePseudoValuationSpace @@ -184,7 +181,6 @@ class LimitValuation_generic(DiscretePseudoValuation): sage: isinstance(w._base_valuation, LimitValuation_generic) # needs sage.rings.function_field True sage: TestSuite(w._base_valuation).run() # long time # needs sage.rings.function_field - """ def __init__(self, parent, approximation): r""" @@ -197,7 +193,6 @@ def __init__(self, parent, approximation): sage: from sage.rings.valuation.limit_valuation import LimitValuation_generic sage: isinstance(v._base_valuation, LimitValuation_generic) True - """ DiscretePseudoValuation.__init__(self, parent) @@ -210,10 +205,10 @@ def reduce(self, f, check=True): INPUT: - - ``f`` -- an element in the domain of this valuation of non-negative + - ``f`` -- an element in the domain of this valuation of nonnegative valuation - - ``check`` -- whether or not to check that ``f`` has non-negative + - ``check`` -- whether or not to check that ``f`` has nonnegative valuation (default: ``True``) EXAMPLES:: @@ -226,7 +221,6 @@ def reduce(self, f, check=True): sage: w = v.extension(L) sage: w.reduce(y) # indirect doctest u1 - """ f = self.domain().coerce(f) self._improve_approximation_for_reduce(f) @@ -247,7 +241,6 @@ def _call_(self, f): sage: w = v.extension(L) sage: w(y) # indirect doctest 1/2 - """ self._improve_approximation_for_call(f) return self._approximation(f) @@ -297,7 +290,6 @@ def _improve_approximation_for_reduce(self, f): sage: u._approximation [ Gauss valuation induced by (x - 1341)-adic valuation, v(y + 1/64*x^2 - 1349/32*x + 1819609/64) = 3 ] - """ @abstract_method @@ -337,7 +329,6 @@ def _improve_approximation_for_call(self, f): 1/2 sage: u._approximation [ Gauss valuation induced by (x - 23)-adic valuation, v(y) = 1/2, v(y^2 - x + 23) = +Infinity ] - """ def _repr_(self): @@ -354,7 +345,6 @@ def _repr_(self): sage: w = v.extension(L) sage: w._base_valuation # indirect doctest [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2 , … ] - """ from sage.rings.infinity import infinity from .augmented_valuation import AugmentedValuation_base @@ -384,7 +374,6 @@ class MacLaneLimitValuation(LimitValuation_generic, InfiniteDiscretePseudoValuat sage: v = K.valuation(2) sage: u = v._base_valuation; u [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 , … ] - """ def __init__(self, parent, approximation, G): r""" @@ -398,7 +387,6 @@ def __init__(self, parent, approximation, G): sage: from sage.rings.valuation.limit_valuation import MacLaneLimitValuation sage: isinstance(u, MacLaneLimitValuation) True - """ LimitValuation_generic.__init__(self, parent, approximation) InfiniteDiscretePseudoValuation.__init__(self, parent) @@ -418,12 +406,11 @@ def extensions(self, ring): sage: u = v._base_valuation sage: u.extensions(QQ['x']) [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 , … ]] - """ if self.domain() is ring: return [self] - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ring) and self.domain().base_ring().is_subring(ring.base_ring()): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ring, PolynomialRing_general) and self.domain().base_ring().is_subring(ring.base_ring()): if self.domain().base_ring().fraction_field() is ring.base_ring(): return [LimitValuation(self._initial_approximation.change_domain(ring), self._G.change_ring(ring.base_ring()))] @@ -451,7 +438,6 @@ def lift(self, F): u1 sage: w.lift(s) # indirect doctest y - """ F = self.residue_ring().coerce(F) return self._initial_approximation.lift(F) @@ -470,7 +456,6 @@ def uniformizer(self): sage: w = v.extension(L) sage: w.uniformizer() # indirect doctest y - """ return self._initial_approximation.uniformizer() @@ -495,7 +480,6 @@ def _call_(self, f): sage: w = valuations.LimitValuation(V[2], f) sage: w((x^2 + 7) * (x + 3)) +Infinity - """ self._improve_approximation_for_call(f) if self._G.divides(f): @@ -528,7 +512,6 @@ def _improve_approximation(self): sage: u._improve_approximation() # needs sage.rings.number_field sage: u._approximation # needs sage.rings.number_field [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2, v(t^2 + 1) = +Infinity ] - """ from sage.rings.infinity import infinity if self._approximation(self._G) is infinity: @@ -575,7 +558,7 @@ def _improve_approximation_for_call(self, f): Write `L=K[x]/(G)` and consider `g` a representative of the class of ``f`` in `K[x]` (of minimal degree.) Write `v` for - ``self._approximation` and `\phi` for the last key polynomial of + ``self._approximation`` and `\phi` for the last key polynomial of `v`. With repeated quotient and remainder `g` has a unique expansion as `g=\sum a_i\phi^i`. Suppose that `g` is an equivalence-unit with respect to ``self._approximation``, i.e., @@ -595,7 +578,6 @@ def _improve_approximation_for_call(self, f): finitely many steps. From this we can deduce the valuation of `s` (and in fact replace `G` with the factor with infinite valuation for all future computations.) - """ from sage.rings.infinity import infinity if self._approximation(self._approximation.phi()) is infinity: @@ -653,7 +635,6 @@ def _improve_approximation_for_reduce(self, f): The reduction produced by the approximation is correct for an equivalence-unit, see :meth:`_improve_approximation_for_call`. - """ if self._approximation(f) > 0: return @@ -673,7 +654,6 @@ def residue_ring(self): sage: w = v.extension(L) sage: w.residue_ring() Finite Field of size 2 - """ R = self._initial_approximation.residue_ring() from sage.categories.fields import Fields @@ -681,8 +661,8 @@ def residue_ring(self): # the approximation ends in v(phi)=infty return R else: - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - assert (is_PolynomialRing(R)) + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + assert (isinstance(R, PolynomialRing_general)) return R.base_ring() def _ge_(self, other): @@ -703,7 +683,6 @@ def _ge_(self, other): True sage: valuations.LimitValuation(V[2], F) >= valuations.LimitValuation(V[2], G) True - """ if other.is_trivial(): return other.is_discrete_valuation() @@ -744,7 +723,6 @@ def restriction(self, ring): sage: w = v.extension(L) sage: w._base_valuation.restriction(K) 2-adic valuation - """ if ring.is_subring(self.domain().base()): return self._initial_approximation.restriction(ring) @@ -790,7 +768,6 @@ def _weakly_separating_element(self, other): has a huge impact on the runtime:: sage: u.separating_element([ww,w,v,uu]) # not tested, takes forever - """ from .scaled_valuation import ScaledValuation_generic v = self.restriction(self.domain().base()) @@ -825,7 +802,6 @@ def value_semigroup(self): sage: u,uu = v.extensions(L) sage: u.value_semigroup() Additive Abelian Semigroup generated by -1, 1 - """ return self._initial_approximation.value_semigroup() @@ -843,7 +819,6 @@ def element_with_valuation(self, s): sage: u = v.extension(L) sage: u.element_with_valuation(1/2) t + 1 - """ return self._initial_approximation.element_with_valuation(s) @@ -869,7 +844,6 @@ def _relative_size(self, f): sage: u = v.extension(L) sage: u._relative_size(1024*t + 1024) 6 - """ return self._initial_approximation._relative_size(f) @@ -891,7 +865,6 @@ def simplify(self, f, error=None, force=False): sage: u = v.extension(L) sage: u.simplify(t + 1024, force=True) t - """ f = self.domain().coerce(f) @@ -923,7 +896,6 @@ def lower_bound(self, f): 10 sage: u(1024*t + 1024) 21/2 - """ f = self.domain().coerce(f) return self._approximation.lower_bound(f) @@ -947,7 +919,6 @@ def upper_bound(self, f): 21/2 sage: u(1024*t + 1024) 21/2 - """ f = self.domain().coerce(f) self._improve_approximation_for_call(f) diff --git a/src/sage/rings/valuation/mapped_valuation.py b/src/sage/rings/valuation/mapped_valuation.py index a4ccf3feec0..0c9dde8d423 100644 --- a/src/sage/rings/valuation/mapped_valuation.py +++ b/src/sage/rings/valuation/mapped_valuation.py @@ -52,7 +52,6 @@ class MappedValuation_base(DiscretePseudoValuation): TESTS:: sage: TestSuite(w).run() # long time # needs sage.rings.function_field - """ def __init__(self, parent, base_valuation): r""" @@ -76,7 +75,6 @@ def __init__(self, parent, base_valuation): sage: from sage.rings.valuation.mapped_valuation import MappedValuation_base sage: isinstance(w, MappedValuation_base) True - """ DiscretePseudoValuation.__init__(self, parent) @@ -97,7 +95,6 @@ def _repr_(self): sage: v = valuations.pAdicValuation(QQ, 2) sage: v.extension(L) # indirect doctest # needs sage.rings.number_field 2-adic valuation - """ def residue_ring(self): @@ -112,7 +109,6 @@ def residue_ring(self): sage: v = valuations.pAdicValuation(QQ, 2) sage: v.extension(L).residue_ring() # needs sage.rings.number_field Finite Field of size 2 - """ return self._base_valuation.residue_ring() @@ -128,7 +124,6 @@ def uniformizer(self): sage: v = valuations.pAdicValuation(QQ, 2) sage: v.extension(L).uniformizer() # needs sage.rings.number_field t + 1 - """ return self._from_base_domain(self._base_valuation.uniformizer()) @@ -146,7 +141,6 @@ def _to_base_domain(self, f): sage: w = v.extensions(L)[0] sage: w._to_base_domain(y).parent() Univariate Polynomial Ring in y over Rational function field in x over Rational Field - """ return self._base_valuation.domain().coerce(f) @@ -164,7 +158,6 @@ def _from_base_domain(self, f): sage: w = v.extension(L) sage: w._from_base_domain(w._base_valuation.domain().gen()).parent() Function field in y defined by y^2 - x - """ return self.domain().coerce(f) @@ -182,7 +175,6 @@ def _call_(self, f): sage: w = v.extension(L) sage: w(y) # indirect doctest 1/2 - """ return self._base_valuation(self._to_base_domain(f)) @@ -200,7 +192,6 @@ def reduce(self, f): sage: w = v.extension(L) sage: w.reduce(y) u1 - """ return self._from_base_residue_ring(self._base_valuation.reduce(self._to_base_domain(f))) @@ -219,7 +210,6 @@ def lift(self, F): sage: w = v.extension(L) sage: w.lift(w.residue_field().gen()) y - """ F = self.residue_ring().coerce(F) F = self._to_base_residue_ring(F) @@ -257,7 +247,6 @@ def simplify(self, x, error=None, force=False): sage: w.simplify(y + x^32, force=True) # needs sage.rings.function_field y - """ return self._from_base_domain(self._base_valuation.simplify(self._to_base_domain(x), error=error, force=force)) @@ -287,7 +276,6 @@ def _relative_size(self, x): sage: w._relative_size(y + x^32) # needs sage.rings.function_field 1 - """ return self._base_valuation._relative_size(self._to_base_domain(x)) @@ -306,7 +294,6 @@ def _to_base_residue_ring(self, F): sage: w = v.extensions(L)[0] sage: w._to_base_residue_ring(1) 1 - """ return self._base_valuation.residue_ring().coerce(F) @@ -325,7 +312,6 @@ def _from_base_residue_ring(self, F): sage: w = v.extensions(L)[0] sage: w._from_base_residue_ring(1) 1 - """ return self.residue_ring().coerce(F) @@ -343,7 +329,6 @@ def element_with_valuation(self, s): sage: u,uu = v.extensions(L) sage: u.element_with_valuation(1) 5 - """ return self._from_base_domain(self._base_valuation.element_with_valuation(s)) @@ -361,7 +346,6 @@ def _test_to_from_base_domain(self, **options): sage: v = K.valuation(0) sage: w = v.extensions(L)[0] sage: w._test_to_from_base_domain() - """ tester = self._tester(**options) @@ -383,7 +367,6 @@ def _test_to_from_base_residue_ring(self, **options): sage: v = K.valuation(0) sage: w = v.extensions(L)[0] sage: w._test_to_from_base_residue_ring() - """ tester = self._tester(**options) @@ -416,7 +399,6 @@ class FiniteExtensionFromInfiniteValuation(MappedValuation_base, DiscreteValuati sage: v = K.valuation(0) sage: w = v.extension(L); w (x)-adic valuation - """ def __init__(self, parent, base_valuation): r""" @@ -432,7 +414,6 @@ def __init__(self, parent, base_valuation): sage: isinstance(w, FiniteExtensionFromInfiniteValuation) True sage: TestSuite(w).run() # long time - """ MappedValuation_base.__init__(self, parent, base_valuation) DiscreteValuation.__init__(self, parent) @@ -452,7 +433,6 @@ def _eq_(self, other): sage: ww = v.extension(L) sage: w == ww # indirect doctest True - """ return (isinstance(other, FiniteExtensionFromInfiniteValuation) and self._base_valuation == other._base_valuation) @@ -471,7 +451,6 @@ def restriction(self, ring): sage: w = v.extension(L) sage: w.restriction(K) is v True - """ if ring.is_subring(self._base_valuation.domain().base()): return self._base_valuation.restriction(ring) @@ -496,7 +475,6 @@ def _weakly_separating_element(self, other): sage: u,uu = v.extensions(L) sage: u.separating_element([w,uu]) # indirect doctest 1/20*t + 7/20 - """ if isinstance(other, FiniteExtensionFromInfiniteValuation): return self.domain()(self._base_valuation._weakly_separating_element(other._base_valuation)) @@ -524,7 +502,6 @@ def _relative_size(self, x): sage: w = v.extension(L) sage: w._relative_size(1024*t + 1024) 6 - """ return self._base_valuation._relative_size(self._to_base_domain(x)) @@ -547,7 +524,6 @@ def simplify(self, x, error=None, force=False): sage: f = 125*t + 1 sage: u.simplify(f, error=u(f), force=True) 1 - """ x = self.domain().coerce(x) @@ -575,7 +551,6 @@ def lower_bound(self, x): 0 sage: u(t + 2) 1 - """ x = self.domain().coerce(x) return self._base_valuation.lower_bound(self._to_base_domain(x)) @@ -599,7 +574,6 @@ def upper_bound(self, x): True sage: u(t + 2) 1 - """ x = self.domain().coerce(x) return self._base_valuation.upper_bound(self._to_base_domain(x)) @@ -625,7 +599,6 @@ class FiniteExtensionFromLimitValuation(FiniteExtensionFromInfiniteValuation): sage: TestSuite(w[0]).run() # long time # needs sage.rings.function_field sage: TestSuite(w[1]).run() # long time # needs sage.rings.function_field - """ def __init__(self, parent, approximant, G, approximants): r""" @@ -644,7 +617,6 @@ def __init__(self, parent, approximant, G, approximants): sage: from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation sage: isinstance(w, FiniteExtensionFromLimitValuation) True - """ # keep track of all extensions to this field extension so we can print # this valuation nicely, dropping any unnecessary information @@ -662,7 +634,6 @@ def _repr_(self): sage: valuations.pAdicValuation(GaussianIntegers().fraction_field(), 2) # indirect doctest # needs sage.rings.number_field 2-adic valuation - """ from .limit_valuation import MacLaneLimitValuation if isinstance(self._base_valuation, MacLaneLimitValuation): diff --git a/src/sage/rings/valuation/scaled_valuation.py b/src/sage/rings/valuation/scaled_valuation.py index d17edc246c7..458400a7e0f 100644 --- a/src/sage/rings/valuation/scaled_valuation.py +++ b/src/sage/rings/valuation/scaled_valuation.py @@ -71,7 +71,6 @@ def create_object(self, version, key): sage: 3*ZZ.valuation(2) # indirect doctest 3 * 2-adic valuation - """ base, s = key @@ -97,7 +96,6 @@ class ScaledValuation_generic(DiscreteValuation): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def __init__(self, parent, base_valuation, s): r""" @@ -115,7 +113,6 @@ def __init__(self, parent, base_valuation, s): sage: from sage.rings.valuation.scaled_valuation import ScaledValuation_generic sage: isinstance(v, ScaledValuation_generic) True - """ DiscreteValuation.__init__(self, parent) self._base_valuation = base_valuation @@ -141,7 +138,6 @@ def residue_ring(self): sage: v = 3*ZZ.valuation(2) sage: v.residue_ring() Finite Field of size 2 - """ return self._base_valuation.residue_ring() @@ -154,7 +150,6 @@ def uniformizer(self): sage: v = 3*ZZ.valuation(2) sage: v.uniformizer() 2 - """ return self._base_valuation.uniformizer() @@ -167,7 +162,6 @@ def _call_(self, f): sage: v = 3*ZZ.valuation(2) sage: v(2) 3 - """ return self._scale * self._base_valuation(f) @@ -180,7 +174,6 @@ def reduce(self, f): sage: v = 3*ZZ.valuation(2) sage: v.reduce(1) 1 - """ return self._base_valuation.reduce(f) @@ -195,7 +188,6 @@ def lift(self, F): sage: v = 3*ZZ.valuation(2) sage: v.lift(1) 1 - """ return self._base_valuation.lift(F) @@ -209,7 +201,6 @@ def extensions(self, ring): sage: v.extensions(GaussianIntegers().fraction_field()) # needs sage.rings.number_field [3 * [ 5-adic valuation, v(x + 2) = 1 ]-adic valuation, 3 * [ 5-adic valuation, v(x + 3) = 1 ]-adic valuation] - """ return [ScaledValuation(w, self._scale) for w in self._base_valuation.extensions(ring)] @@ -222,7 +213,6 @@ def restriction(self, ring): sage: v = 3*QQ.valuation(5) sage: v.restriction(ZZ) 3 * 5-adic valuation - """ restricted = self._base_valuation.restriction(ring) if restricted.is_trivial(): @@ -242,7 +232,6 @@ def _strictly_separating_element(self, other): sage: v3 = 12 * QQ.valuation(3) sage: v2._strictly_separating_element(v3) 2/3 - """ return self._base_valuation._strictly_separating_element(other) @@ -259,7 +248,6 @@ def _weakly_separating_element(self, other): sage: v3 = 12 * QQ.valuation(3) sage: v2._weakly_separating_element(v3) 2 - """ return self._base_valuation._weakly_separating_element(other) @@ -283,7 +271,6 @@ def _ge_(self, other): sage: v2 > v2/2 True - """ if self == other: return True @@ -318,7 +305,6 @@ def _le_(self, other): sage: v2 < v2/2 False - """ return other / self._scale >= self._base_valuation @@ -331,6 +317,5 @@ def value_semigroup(self): sage: v2 = QQ.valuation(2) sage: (2*v2).value_semigroup() Additive Abelian Semigroup generated by -2, 2 - """ return self._scale * self._base_valuation.value_semigroup() diff --git a/src/sage/rings/valuation/trivial_valuation.py b/src/sage/rings/valuation/trivial_valuation.py index 6ba86ab5888..a8c2ff16618 100644 --- a/src/sage/rings/valuation/trivial_valuation.py +++ b/src/sage/rings/valuation/trivial_valuation.py @@ -248,7 +248,7 @@ def _ge_(self, other): class TrivialDiscreteValuation(TrivialDiscretePseudoValuation_base, DiscreteValuation): r""" - The trivial valuation that is zero on non-zero elements. + The trivial valuation that is zero on nonzero elements. EXAMPLES:: diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 863d3b423a4..2deeb100ffc 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -77,7 +77,6 @@ class DiscretePseudoValuation(Morphism): TESTS:: sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron - """ def __init__(self, parent): r""" @@ -86,7 +85,6 @@ def __init__(self, parent): sage: from sage.rings.valuation.valuation import DiscretePseudoValuation sage: isinstance(ZZ.valuation(2), DiscretePseudoValuation) True - """ Morphism.__init__(self, parent=parent) @@ -105,7 +103,6 @@ def is_equivalent(self, f, g): False sage: v.is_equivalent(0, 0) True - """ from sage.rings.infinity import infinity if self(f) is infinity: @@ -127,7 +124,6 @@ def __hash__(self): sage: v = QQ.valuation(2) sage: hash(v) == hash(v) # indirect doctest True - """ return self._hash_() @@ -148,7 +144,6 @@ def _hash_(self): sage: v = QQ.valuation(2) sage: hash(v) == hash(v) # indirect doctest True - """ return id(self) @@ -212,7 +207,6 @@ def _eq_(self, other): sage: v = valuations.TrivialValuation(QQ) sage: v == v True - """ return self is other @@ -295,7 +289,6 @@ class InfiniteDiscretePseudoValuation(DiscretePseudoValuation): sage: isinstance(w, InfiniteDiscretePseudoValuation) True sage: TestSuite(w).run() # long time # needs sage.geometry.polyhedron sage.rings.padics - """ def is_discrete_valuation(self): r""" @@ -311,7 +304,6 @@ def is_discrete_valuation(self): sage: w = v.augmentation(x, infinity) sage: w.is_discrete_valuation() False - """ return False @@ -332,7 +324,6 @@ class NegativeInfiniteDiscretePseudoValuation(InfiniteDiscretePseudoValuation): TESTS:: sage: TestSuite(w).run() # long time - """ def is_negative_pseudo_valuation(self): r""" @@ -349,7 +340,6 @@ def is_negative_pseudo_valuation(self): sage: w = K.valuation(v) sage: w.is_negative_pseudo_valuation() True - """ return True @@ -372,7 +362,6 @@ class DiscreteValuation(DiscretePseudoValuation): sage: isinstance(w, DiscreteValuation) True sage: TestSuite(w).run() # long time # needs sage.geometry.polyhedron sage.rings.padics - """ def is_discrete_valuation(self): r""" @@ -383,11 +372,10 @@ def is_discrete_valuation(self): sage: v = valuations.TrivialValuation(ZZ) sage: v.is_discrete_valuation() True - """ return True - def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=True, required_precision=-1, require_incomparability=False, require_maximal_degree=False, algorithm="serial"): + def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=True, required_precision=-1, require_incomparability=False, require_maximal_degree=False, algorithm='serial'): r""" Return approximants on `K[x]` for the extensions of this valuation to `L=K[x]/(G)`. @@ -400,12 +388,12 @@ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=Tru - ``G`` -- a monic squarefree integral polynomial in a univariate polynomial ring over the domain of this valuation - - ``assume_squarefree`` -- a boolean (default: ``False``), whether to + - ``assume_squarefree`` -- boolean (default: ``False``); whether to assume that ``G`` is squarefree. If ``True``, the squafreeness of ``G`` is not verified though it is necessary when ``require_final_EF`` is set for the algorithm to terminate. - - ``require_final_EF`` -- a boolean (default: ``True``); whether to + - ``require_final_EF`` -- boolean (default: ``True``); whether to require the returned key polynomials to be in one-to-one correspondance to the extensions of this valuation to ``L`` and require them to have the ramification index and residue degree of the @@ -415,20 +403,20 @@ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=Tru to require the last key polynomial of the returned valuations to have at least that valuation. - - ``require_incomparability`` -- a boolean (default: ``False``); + - ``require_incomparability`` -- boolean (default: ``False``); whether to require the returned valuations to be incomparable (with respect to the partial order on valuations defined by comparing them pointwise.) - - ``require_maximal_degree`` -- a boolean (default: ``False``); whether + - ``require_maximal_degree`` -- boolean (default: ``False``); whether to require the last key polynomial of the returned valuation to have maximal degree. This is most relevant when using this algorithm to compute approximate factorizations of ``G``, when set to ``True``, the last key polynomial has the same degree as the corresponding factor. - - ``algorithm`` -- one of ``"serial"`` or ``"parallel"`` (default: - ``"serial"``); whether or not to parallelize the algorithm + - ``algorithm`` -- one of ``'serial'`` or ``'parallel'`` (default: + ``'serial'``); whether or not to parallelize the algorithm EXAMPLES:: @@ -689,7 +677,6 @@ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=Tru v(x^36 + 60552000*x^33 + 268157412*x^30 + 173881701*x^27 + 266324841*x^24 + 83125683*x^21 + 111803814*x^18 + 31925826*x^15 + 205726716*x^12 + 17990262*x^9 + 351459648*x^6 + 127014399*x^3 + 359254116) = +Infinity ]] - """ R = G.parent() if R.base_ring() is not self.domain(): @@ -821,7 +808,6 @@ def _pow(self, x, e, error): 4 sage: v._pow(2, 1000, error=4) 0 - """ if e == 0: return self.domain().one() @@ -844,8 +830,8 @@ def mac_lane_approximant(self, G, valuation, approximants=None): - ``valuation`` -- a valuation on the parent of ``G`` - - ``approximants`` -- the output of :meth:`mac_lane_approximants`. - If not given, it is computed. + - ``approximants`` -- the output of :meth:`mac_lane_approximants`; + if not given, it is computed EXAMPLES:: @@ -910,7 +896,6 @@ def mac_lane_approximant(self, G, valuation, approximants=None): sage: w = GaussValuation(R, v).augmentation(x + 3, 2) sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1 ] - """ if valuation.restriction(valuation.domain().base_ring()) is not self: raise ValueError @@ -951,7 +936,7 @@ def montes_factorization(self, G, assume_squarefree=False, required_precision=No - ``G`` -- a monic polynomial over the domain of this valuation - - ``assume_squarefree`` -- a boolean (default: ``False``), whether to + - ``assume_squarefree`` -- boolean (default: ``False``); whether to assume ``G`` to be squarefree - ``required_precision`` -- a number or infinity (default: @@ -1021,7 +1006,6 @@ def montes_factorization(self, G, assume_squarefree=False, required_precision=No The underlying algorithm is described in [Mac1936II]_ and thoroughly analyzed in [GMN2008]_. - """ if required_precision is None: from sage.rings.infinity import infinity @@ -1053,16 +1037,15 @@ def _ge_(self, other): sage: w = QQ.valuation(2) sage: v >= w False - """ if other.is_trivial(): return other.is_discrete_valuation() return super()._ge_(other) -class MacLaneApproximantNode(): +class MacLaneApproximantNode: r""" - A node in the tree computed by :meth:`DiscreteValuation.mac_lane_approximants` + A node in the tree computed by :meth:`DiscreteValuation.mac_lane_approximants`. Leaves in the computation of the tree of approximants :meth:`~DiscreteValuation.mac_lane_approximants`. Each vertex consists of a @@ -1080,7 +1063,6 @@ class MacLaneApproximantNode(): sage: v = ZZ.valuation(3) sage: v.extension(GaussianIntegers()) # indirect doctest # needs sage.rings.number_field sage.rings.padics 3-adic valuation - """ def __init__(self, valuation, parent, ef, principal_part_bound, coefficients, valuations): r""" @@ -1089,7 +1071,6 @@ def __init__(self, valuation, parent, ef, principal_part_bound, coefficients, va sage: from sage.rings.valuation.valuation import MacLaneApproximantNode sage: node = MacLaneApproximantNode(QQ.valuation(2), None, 1, None, None, None) sage: TestSuite(node).run() - """ self.valuation = valuation self.parent = parent @@ -1112,7 +1093,6 @@ def __eq__(self, other): False sage: n == n True - """ if type(self) is not type(other): return False @@ -1131,7 +1111,6 @@ def __ne__(self, other): True sage: n != n False - """ return not (self == other) diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index 3eb143a6d4b..24e5f598624 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -99,7 +99,6 @@ class DiscretePseudoValuationSpace(UniqueRepresentation, Homset): TESTS:: sage: TestSuite(H).run() # long time - """ def __init__(self, domain): r""" @@ -108,7 +107,6 @@ def __init__(self, domain): sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: isinstance(QQ.valuation(2).parent(), DiscretePseudoValuationSpace) True - """ from .value_group import DiscreteValuationCodomain # A valuation is a map from an additive semigroup to an additive semigroup, however, it @@ -140,7 +138,6 @@ def _abstract_element_class(self): sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: isinstance(QQ.valuation(2), DiscretePseudoValuationSpace.ElementMethods) # indirect doctest True - """ class_name = "%s._abstract_element_class" % self.__class__.__name__ from sage.structure.dynamic_class import dynamic_class @@ -156,7 +153,6 @@ def _get_action_(self, S, op, self_on_left): sage: from operator import mul sage: v.parent().get_action(ZZ, mul) # indirect doctest Right action by Integer Ring on Discrete pseudo-valuations on Rational Field - """ from operator import mul from sage.rings.infinity import InfinityRing @@ -175,7 +171,6 @@ def _an_element_(self): sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: DiscretePseudoValuationSpace(QQ).an_element() # indirect doctest Trivial pseudo-valuation on Rational Field - """ from .trivial_valuation import TrivialPseudoValuation return TrivialPseudoValuation(self.domain()) @@ -189,7 +184,6 @@ def _repr_(self): sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: DiscretePseudoValuationSpace(QQ) # indirect doctest Discrete pseudo-valuations on Rational Field - """ return "Discrete pseudo-valuations on %r" % (self.domain(),) @@ -205,7 +199,6 @@ def __contains__(self, x): True sage: QQ.valuation(2) in H True - """ # override the logic from Homset with the original implementation for Parent # which entirely relies on a proper implementation of @@ -223,7 +216,6 @@ def __call__(self, x): sage: H = DiscretePseudoValuationSpace(QQ) sage: H(QQ.valuation(2)) 2-adic valuation - """ # override the logic from Homset with the original implementation for Parent # which entirely relies on a proper implementation of @@ -233,7 +225,7 @@ def __call__(self, x): def _element_constructor_(self, x): r""" - Create an element in this space from ``x``, + Create an element in this space from ``x``. EXAMPLES: @@ -252,7 +244,6 @@ def _element_constructor_(self, x): False sage: Z(Q(v)) in Z True - """ if isinstance(x.parent(), DiscretePseudoValuationSpace): if x.domain() is not self.domain(): @@ -301,7 +292,6 @@ class ElementMethods: sage: m = H.__make_element_class__(DiscretePseudoValuation)(H) sage: m._test_category() - """ def is_discrete_pseudo_valuation(self): r""" @@ -311,7 +301,6 @@ def is_discrete_pseudo_valuation(self): sage: QQ.valuation(2).is_discrete_pseudo_valuation() True - """ return True @@ -326,7 +315,6 @@ def is_discrete_valuation(self): sage: QQ.valuation(2).is_discrete_valuation() True - """ def is_negative_pseudo_valuation(self): @@ -339,7 +327,6 @@ def is_negative_pseudo_valuation(self): sage: QQ.valuation(2).is_negative_pseudo_valuation() False - """ from sage.categories.fields import Fields if self.is_discrete_valuation(): @@ -362,14 +349,13 @@ def is_trivial(self): sage: QQ.valuation(7).is_trivial() False - """ from sage.rings.infinity import infinity if self(self.domain().one()) is infinity: # the constant infinity return True if self(self.uniformizer()) != 0: - # not constant on the non-zero elements + # not constant on the nonzero elements return False return True @@ -394,7 +380,6 @@ def uniformizer(self): Traceback (most recent call last): ... ValueError: Trivial valuations do not define a uniformizing element - """ @cached_method @@ -418,7 +403,6 @@ def value_group(self): Traceback (most recent call last): ... ValueError: The trivial pseudo-valuation that is infinity everywhere does not have a value group. - """ from .value_group import DiscreteValueGroup return DiscreteValueGroup(self(self.uniformizer())) @@ -454,7 +438,6 @@ def value_semigroup(self): sage: u = w.augmentation(x, 5/3) sage: u.value_semigroup() Additive Abelian Semigroup generated by 1, 5/3 - """ from sage.categories.fields import Fields if self.domain() in Fields(): @@ -473,7 +456,6 @@ def element_with_valuation(self, s): sage: v = ZZ.valuation(2) sage: v.element_with_valuation(10) 1024 - """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -492,7 +474,7 @@ def element_with_valuation(self, s): def residue_ring(self): r""" Return the residue ring of this valuation, i.e., the elements of - non-negative valuation modulo the elements of positive valuation. + nonnegative valuation modulo the elements of positive valuation. EXAMPLES:: sage: QQ.valuation(2).residue_ring() @@ -509,13 +491,12 @@ def residue_ring(self): Integer Ring sage: GaussValuation(ZZ['x'], ZZ.valuation(2)).residue_ring() Univariate Polynomial Ring in x over Finite Field of size 2... - """ def residue_field(self): r""" Return the residue field of this valuation, i.e., the field of - fractions of the :meth:`residue_ring`, the elements of non-negative + fractions of the :meth:`residue_ring`, the elements of nonnegative valuation modulo the elements of positive valuation. EXAMPLES:: @@ -529,14 +510,13 @@ def residue_field(self): Rational Field sage: GaussValuation(ZZ['x'], ZZ.valuation(2)).residue_field() Rational function field in x over Finite Field of size 2 - """ ret = self.residue_ring() from sage.categories.fields import Fields if ret in Fields(): return ret - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - if is_PolynomialRing(ret): + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + if isinstance(ret, PolynomialRing_general): from sage.rings.function_field.constructor import FunctionField return FunctionField(ret.base_ring().fraction_field(), names=(ret.variable_name(),)) return ret.fraction_field() @@ -559,8 +539,7 @@ def reduce(self, x): sage: v.reduce(1/2) Traceback (most recent call last): ... - ValueError: reduction is only defined for elements of non-negative valuation - + ValueError: reduction is only defined for elements of nonnegative valuation """ @abstract_method @@ -574,7 +553,6 @@ def lift(self, X): sage: v = QQ.valuation(2) sage: v.lift(v.residue_ring().one()) 1 - """ def extension(self, ring): @@ -603,7 +581,6 @@ def extensions(self, ring): sage: v = ZZ.valuation(2) sage: v.extensions(QQ) [2-adic valuation] - """ if ring is self.domain(): return [self] @@ -619,7 +596,6 @@ def restriction(self, ring): sage: w = v.restriction(ZZ) sage: w.domain() Integer Ring - """ if ring is self.domain(): return self @@ -638,7 +614,6 @@ def change_domain(self, ring): sage: v = QQ.valuation(3) sage: v.change_domain(ZZ) 3-adic valuation - """ if ring is self.domain(): return self @@ -654,7 +629,7 @@ def scale(self, scalar): INPUT: - - ``scalar`` -- a non-negative rational number or infinity + - ``scalar`` -- a nonnegative rational number or infinity EXAMPLES:: @@ -684,7 +659,6 @@ def scale(self, scalar): +Infinity sage: w(0) +Infinity - """ from sage.rings.infinity import infinity if scalar is infinity: @@ -696,7 +670,7 @@ def scale(self, scalar): if scalar == 1: return self if scalar < 0: - raise ValueError("scalar must be non-negative") + raise ValueError("scalar must be nonnegative") if self.is_trivial(): return self @@ -720,7 +694,6 @@ def separating_element(self, others): sage: v5 = QQ.valuation(5) sage: v2.separating_element([v3,v5]) 4/15 - """ try: iter(others) @@ -791,7 +764,6 @@ def _strictly_separating_element(self, other): sage: v3 = QQ.valuation(3) sage: v2._strictly_separating_element(v3) 2/3 - """ from sage.rings.infinity import infinity @@ -814,14 +786,14 @@ def _strictly_separating_element(self, other): # option this generically. return self.domain()(~denominator) - # We need non-negative integers a and b such that + # We need nonnegative integers a and b such that # a*n - b*d > 0 and a*nn - b*dd < 0 if nn == 0: # the above becomes b != 0 and a/b > d/n b = 1 a = (d/n + 1).floor() else: - # Since n,nn,d,dd are all non-negative this is essentially equivalent to + # Since n,nn,d,dd are all nonnegative this is essentially equivalent to # a/b > d/n and b/a > nn/dd # which is # dd/nn > a/b > d/n @@ -874,7 +846,6 @@ def _weakly_separating_element(self, other): sage: v3 = QQ.valuation(3) sage: v2._weakly_separating_element(v3) 2 - """ ret = self.uniformizer() if self(ret) > other(ret): @@ -886,7 +857,7 @@ def shift(self, x, s): Shift ``x`` in its expansion with respect to :meth:`uniformizer` by ``s`` "digits". - For non-negative ``s``, this just returns ``x`` multiplied by a + For nonnegative ``s``, this just returns ``x`` multiplied by a power of the uniformizer `\pi`. For negative ``s``, it does the same but when not over a field, it @@ -914,7 +885,6 @@ def shift(self, x, s): x sage: w.shift(x + 2*x^2, -1) x^2 - """ from sage.rings.integer_ring import ZZ x = self.domain().coerce(x) @@ -953,7 +923,6 @@ def simplify(self, x, error=None, force=False): 2 sage: v.simplify(6, error=0, force=True) 0 - """ x = self.domain().coerce(x) @@ -973,7 +942,6 @@ def lower_bound(self, x): sage: v = ZZ.valuation(2) sage: v.lower_bound(2^10) 10 - """ return self(x) @@ -989,7 +957,6 @@ def upper_bound(self, x): sage: v = ZZ.valuation(2) sage: v.upper_bound(2^10) 10 - """ return self(x) @@ -1027,7 +994,6 @@ def inverse(self, x, precision): sage: v = QQ.valuation(2) sage: v.inverse(2, 2) 1/2 - """ return x.inverse_of_unit() @@ -1055,7 +1021,6 @@ def _relative_size(self, x): sage: v._relative_size(2**20) 1 - """ return 1 @@ -1067,7 +1032,6 @@ def _test_is_negative_pseudo_valuation(self, **options): sage: v = ZZ.valuation(3) sage: v._test_is_negative_pseudo_valuation() - """ tester = self._tester(**options) @@ -1090,7 +1054,6 @@ def _test_bounds(self, **options): sage: v = ZZ.valuation(3) sage: v._test_bounds() - """ tester = self._tester(**options) @@ -1107,7 +1070,6 @@ def _test_simplify(self, **options): sage: v = ZZ.valuation(3) sage: v._test_simplify() - """ tester = self._tester(**options) @@ -1150,7 +1112,6 @@ def _test_shift(self, **options): sage: v = ZZ.valuation(3) sage: v._test_shift() - """ if self.is_trivial() and not self.is_discrete_valuation(): return @@ -1186,7 +1147,6 @@ def _test_scale(self, **options): sage: v = ZZ.valuation(3) sage: v._test_scale() - """ tester = self._tester(**options) @@ -1223,7 +1183,6 @@ def _test_add(self, **options): sage: v = ZZ.valuation(3) sage: v._test_add() - """ tester = self._tester(**options) S = self.domain().some_elements() @@ -1241,7 +1200,6 @@ def _test_infinite_zero(self, **options): sage: v = QQ.valuation(5) sage: v._test_infinite_zero() - """ tester = self._tester(**options) from sage.rings.infinity import infinity @@ -1255,7 +1213,6 @@ def _test_mul(self, **options): sage: v = QQ.valuation(5) sage: v._test_mul() - """ tester = self._tester(**options) S = self.domain().some_elements() @@ -1268,7 +1225,7 @@ def _test_mul(self, **options): def _test_no_infinite_units(self, **options): r""" - Checks that no units are sent to infinity. + Check that no units are sent to infinity. TESTS:: @@ -1284,7 +1241,6 @@ def _test_no_infinite_units(self, **options): +Infinity sage: v.is_trivial() True - """ if not self.is_discrete_valuation() and self.is_trivial(): return @@ -1305,7 +1261,6 @@ def _test_value_group(self, **options): sage: v = QQ.valuation(5) sage: v._test_value_group() - """ from sage.rings.infinity import infinity tester = self._tester(**options) @@ -1334,7 +1289,6 @@ def _test_value_semigroup(self, **options): sage: v = QQ.valuation(5) sage: v._test_value_semigroup() # needs sage.geometry.polyhedron - """ tester = self._tester(**options) @@ -1353,7 +1307,6 @@ def _test_element_with_valuation(self, **options): sage: v = QQ.valuation(5) sage: v._test_element_with_valuation() # needs sage.geometry.polyhedron - """ tester = self._tester(**options) @@ -1372,7 +1325,6 @@ def _test_residue_ring(self, **options): sage: v = QQ.valuation(5) sage: v._test_residue_ring() - """ tester = self._tester(**options) @@ -1404,7 +1356,6 @@ def _test_reduce(self, **options): sage: v = QQ.valuation(5) sage: v._test_reduce() - """ tester = self._tester(**options) @@ -1443,7 +1394,6 @@ def _test_lift(self, **options): sage: v = QQ.valuation(5) sage: v._test_lift() - """ tester = self._tester(**options) @@ -1473,7 +1423,6 @@ def _test_restriction(self, **options): sage: v = QQ.valuation(5) sage: v._test_restriction() - """ tester = self._tester(**options) @@ -1487,7 +1436,6 @@ def _test_extension(self, **options): sage: v = QQ.valuation(5) sage: v._test_extension() - """ tester = self._tester(**options) @@ -1502,7 +1450,6 @@ def _test_change_domain(self, **options): sage: v = QQ.valuation(5) sage: v._test_change_domain() - """ tester = self._tester(**options) @@ -1516,7 +1463,6 @@ def _test_no_infinite_nonzero(self, **options): sage: v = QQ.valuation(5) sage: v._test_no_infinite_nonzero() - """ if not self.is_discrete_valuation(): return @@ -1535,7 +1481,6 @@ def _test_residue_field(self, **options): sage: v = QQ.valuation(5) sage: v._test_residue_field() - """ if not self.is_discrete_valuation(): return @@ -1581,7 +1526,6 @@ def _test_ge(self, **options): sage: v = QQ.valuation(5) sage: v._test_ge() - """ tester = self._tester(**options) @@ -1602,7 +1546,6 @@ def _test_le(self, **options): sage: v = QQ.valuation(5) sage: v._test_le() - """ tester = self._tester(**options) @@ -1623,7 +1566,6 @@ def _test_inverse(self, **options): sage: v = QQ.valuation(5) sage: v._test_inverse() - """ tester = self._tester(**options) diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index b35d07e70a3..f3afd30c413 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -46,7 +46,6 @@ class DiscreteValuationCodomain(UniqueRepresentation, Parent): TESTS:: sage: TestSuite(C).run() # long time - """ def __init__(self): r""" @@ -55,7 +54,6 @@ def __init__(self): sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain sage: isinstance(QQ.valuation(2).codomain(), DiscreteValuationCodomain) True - """ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.categories.additive_monoids import AdditiveMonoids @@ -79,7 +77,6 @@ def _element_constructor_(self, x): +Infinity sage: DiscreteValuationCodomain()(-infinity) -Infinity - """ if x is infinity: return x @@ -98,7 +95,6 @@ def _repr_(self): sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain sage: DiscreteValuationCodomain() # indirect doctest Codomain of Discrete Valuations - """ return "Codomain of Discrete Valuations" @@ -137,12 +133,11 @@ class DiscreteValueGroup(UniqueRepresentation, Parent): sage: TestSuite(D1).run() # long time sage: TestSuite(D2).run() # long time sage: TestSuite(D3).run() # long time - """ @staticmethod def __classcall__(cls, generator): r""" - Normalizes ``generator`` to a positive rational so that this is a + Normalize ``generator`` to a positive rational so that this is a unique parent. TESTS:: @@ -150,7 +145,6 @@ def __classcall__(cls, generator): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(1) is DiscreteValueGroup(-1) True - """ generator = QQ.coerce(generator).abs() return super().__classcall__(cls, generator) @@ -162,7 +156,6 @@ def __init__(self, generator): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: isinstance(DiscreteValueGroup(0), DiscreteValueGroup) True - """ from sage.categories.modules import Modules self._generator = generator @@ -195,7 +188,6 @@ def _element_constructor_(self, x): Traceback (most recent call last): ... ValueError: `1/2` is not in Additive Abelian Group generated by 1. - """ x = QQ.coerce(x) if x == 0 or (self._generator != 0 and x / self._generator in ZZ): @@ -212,7 +204,6 @@ def _repr_(self): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(0) # indirect doctest Trivial Additive Abelian Group - """ if self.is_trivial(): return "Trivial Additive Abelian Group" @@ -238,7 +229,6 @@ def __add__(self, other): Additive Abelian Group generated by 1/2 sage: DiscreteValueGroup(2/7) + DiscreteValueGroup(4/9) Additive Abelian Group generated by 2/63 - """ if isinstance(other, DiscreteValueGroup): return DiscreteValueGroup(self._generator.gcd(other._generator)) @@ -299,7 +289,6 @@ def index(self, other): Traceback (most recent call last): ... ValueError: other must be a subgroup of this group - """ if not isinstance(other, DiscreteValueGroup): raise ValueError("other must be a DiscreteValueGroup") @@ -321,7 +310,6 @@ def numerator(self): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(3/8).numerator() 3 - """ return self._generator.numerator() @@ -334,7 +322,6 @@ def denominator(self): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(3/8).denominator() 8 - """ return self._generator.denominator() @@ -347,7 +334,6 @@ def gen(self): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(-3/8).gen() 3/8 - """ return self._generator @@ -360,7 +346,6 @@ def some_elements(self): sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(-3/8).some_elements() [3/8, -3/8, 0, 42, 3/2, -3/2, 9/8, -9/8] - """ return [self._generator, -self._generator] + [x for x in QQ.some_elements() if x in self] @@ -375,7 +360,6 @@ def is_trivial(self): False sage: DiscreteValueGroup(0).is_trivial() True - """ return self._generator.is_zero() @@ -394,7 +378,6 @@ def _element_with_valuation(self, subgroup, s): (-3, 1) sage: DiscreteValueGroup(3/8)._element_with_valuation(DiscreteValueGroup(3), 33/8) (3, 1) - """ if s not in self: raise ValueError("s must be in the value group but %r is not in %r." % (s, self)) @@ -432,7 +415,6 @@ class DiscreteValueSemigroup(UniqueRepresentation, Parent): sage: TestSuite(D1).run() # long time sage: TestSuite(D2).run() # long time # needs sage.geometry.polyhedron sage: TestSuite(D3).run() # long time # needs sage.numerical.mip - """ @staticmethod def __classcall__(cls, generators): @@ -454,7 +436,6 @@ def __classcall__(cls, generators): sage: DiscreteValueSemigroup([1,-1,1/3]) is DiscreteValueSemigroup([1/3,-1/3]) False - """ if generators in QQ: generators = [generators] @@ -482,7 +463,6 @@ def __init__(self, generators): sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: isinstance(DiscreteValueSemigroup([0]), DiscreteValueSemigroup) True - """ from sage.categories.additive_magmas import AdditiveMagmas self._generators = generators @@ -513,7 +493,6 @@ def _solve_linear_program(self, target): {0: 1, 1: 0, 2: 2} sage: 1*2 + 0*3 + 2*5 12 - """ if len(self._generators) == 0: if target == 0: @@ -536,7 +515,7 @@ def _solve_linear_program(self, target): return {0: exp, 1: 0} from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException - P = MixedIntegerLinearProgram(maximization=False, solver="ppl") + P = MixedIntegerLinearProgram(maximization=False, solver='ppl') x = P.new_variable(integer=True, nonnegative=True) constraint = sum([g * x[i] for i, g in enumerate(self._generators)]) == target @@ -587,7 +566,6 @@ def _repr_(self): sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup(0) # indirect doctest Trivial Additive Abelian Semigroup - """ if self.is_trivial(): return "Trivial Additive Abelian Semigroup" @@ -613,7 +591,6 @@ def __add__(self, other): Additive Abelian Semigroup generated by 1/2 sage: DiscreteValueGroup(2/7) + DiscreteValueSemigroup(4/9) Additive Abelian Semigroup generated by -2/7, 2/7, 4/9 - """ if isinstance(other, DiscreteValueSemigroup): return DiscreteValueSemigroup(self._generators + other._generators) @@ -643,7 +620,6 @@ def _mul_(self, other, switch_sides=False): Additive Abelian Semigroup generated by 1/4 sage: D * 0 Trivial Additive Abelian Semigroup - """ other = QQ.coerce(other) return DiscreteValueSemigroup([g*other for g in self._generators]) @@ -657,7 +633,6 @@ def gens(self): sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup(-3/8).gens() (-3/8,) - """ return tuple(self._generators) @@ -691,7 +666,6 @@ def is_trivial(self): False sage: DiscreteValueSemigroup([]).is_trivial() True - """ return len(self._generators) == 0 diff --git a/src/sage/sandpiles/examples.py b/src/sage/sandpiles/examples.py index a7615723e81..279d0cfae0c 100644 --- a/src/sage/sandpiles/examples.py +++ b/src/sage/sandpiles/examples.py @@ -51,15 +51,9 @@ class SandpileExamples: """ def __call__(self): r""" - If sandpiles() is executed, return a helpful message. + If ``sandpiles()`` is executed, return a helpful message. - INPUT: - - None - - OUTPUT: - - None + OUTPUT: none EXAMPLES:: @@ -78,11 +72,9 @@ def Complete(self, n): INPUT: - - ``n`` -- positive integer - - OUTPUT: + - ``n`` -- positive integer - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -100,11 +92,9 @@ def Cycle(self, n): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - OUTPUT: - - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -125,13 +115,7 @@ def Diamond(self): """ Sandpile on the diamond graph. - INPUT: - - None - - OUTPUT: - - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -147,11 +131,9 @@ def Fan(self, n, deg_three_verts=False): INPUT: - - ``n`` -- a non-negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -183,11 +165,9 @@ def Grid(self, m, n): INPUT: - - ``m``, ``n`` -- negative integers + - ``m``, ``n`` -- negative integers - OUTPUT: - - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -211,13 +191,7 @@ def House(self): """ Sandpile on the House graph. - INPUT: - - None - - OUTPUT: - - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -233,11 +207,9 @@ def Wheel(self, n): INPUT: - - ``n`` -- a non-negative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - Sandpile + OUTPUT: Sandpile EXAMPLES:: diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index b8697213bf0..6fb9720b945 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -363,7 +363,7 @@ def _sandpile_help(cls, usage, verbose=True): """ - Prints help text for classes in this module; see the ``help()`` methods on + Print help text for classes in this module; see the ``help()`` methods on individual classes in this module for example usage. """ @@ -415,10 +415,7 @@ def version(): r""" The version number of Sage Sandpiles. - OUTPUT: - - string - + OUTPUT: string EXAMPLES:: @@ -438,11 +435,9 @@ def help(verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - printed string + OUTPUT: printed string EXAMPLES:: @@ -517,8 +512,8 @@ def __init__(self, g, sink=None): INPUT: - - ``g`` -- dict for directed multigraph with edges weighted by - nonnegative integers (see NOTE), a Graph or DiGraph. + - ``g`` -- dictionary for directed multigraph with edges weighted by + nonnegative integers (see NOTE), a Graph or DiGraph - ``sink`` -- (optional) A sink vertex. Any outgoing edges from the designated sink are ignored for the purposes of stabilization. It is @@ -526,9 +521,7 @@ def __init__(self, g, sink=None): ``sink`` argument is omitted, the first vertex in the list of the Sandpile's vertices is set as the sink. - OUTPUT: - - Sandpile + OUTPUT: Sandpile EXAMPLES: @@ -653,9 +646,7 @@ def __copy__(self): """ Make a copy of this sandpile. - OUTPUT: - - A new :class:`Sandpile` instance. + OUTPUT: a new :class:`Sandpile` instance EXAMPLES:: @@ -757,9 +748,7 @@ def __str__(self) -> str: r""" The name of the sandpile. - OUTPUT: - - string + OUTPUT: string EXAMPLES:: @@ -775,7 +764,7 @@ def __str__(self) -> str: def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: @@ -831,9 +820,7 @@ def dict(self): r""" A dictionary of dictionaries representing a directed graph. - OUTPUT: - - dict + OUTPUT: dictionary EXAMPLES:: @@ -852,9 +839,7 @@ def sink(self): r""" The sink vertex. - OUTPUT: - - sink vertex + OUTPUT: sink vertex EXAMPLES:: @@ -873,9 +858,7 @@ def laplacian(self): r""" The Laplacian matrix of the graph. Its *rows* encode the vertex firing rules. - OUTPUT: - - matrix + OUTPUT: matrix EXAMPLES:: @@ -897,9 +880,7 @@ def reduced_laplacian(self): r""" The reduced Laplacian matrix of the graph. - OUTPUT: - - matrix + OUTPUT: matrix EXAMPLES:: @@ -925,9 +906,7 @@ def group_order(self): r""" The size of the sandpile group. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -955,10 +934,7 @@ def max_stable(self): r""" The maximal stable configuration. - OUTPUT: - - SandpileConfig (the maximal stable configuration) - + OUTPUT: SandpileConfig (the maximal stable configuration) EXAMPLES:: @@ -1024,9 +1000,7 @@ def out_degree(self, v=None): - ``v`` -- (optional) vertex name - OUTPUT: - - integer or dict + OUTPUT: integer or dict EXAMPLES:: @@ -1063,9 +1037,7 @@ def in_degree(self, v=None): - ``v`` -- (optional) vertex name - OUTPUT: - - integer or dict + OUTPUT: integer or dict EXAMPLES:: @@ -1173,9 +1145,7 @@ def burning_script(self): r""" A script for the minimal burning configuration. - OUTPUT: - - dict + OUTPUT: dictionary EXAMPLES:: @@ -1225,9 +1195,7 @@ def nonsink_vertices(self): r""" The nonsink vertices. - OUTPUT: - - list of vertices + OUTPUT: list of vertices EXAMPLES:: @@ -1245,9 +1213,7 @@ def all_k_config(self, k): - ``k`` -- integer - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -1261,9 +1227,7 @@ def zero_config(self): r""" The all-zero configuration. - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -1287,7 +1251,7 @@ def zero_config(self): def _set_identity(self): r""" - Computes ``_identity``, the variable holding the identity configuration + Compute ``_identity``, the variable holding the identity configuration of the sandpile group, when ``identity()`` is first called by a user. EXAMPLES:: @@ -1303,16 +1267,13 @@ def _set_identity(self): def identity(self, verbose=True): r""" The identity configuration. If ``verbose`` is ``False``, the - configuration are converted to a list of integers. + configuration is converted to a list of integers. INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - SandpileConfig or a list of integers If ``verbose`` is ``False``, the - configuration are converted to a list of integers. + OUTPUT: SandpileConfig or a list of integers EXAMPLES:: @@ -1331,7 +1292,7 @@ def identity(self, verbose=True): def _set_recurrents(self): """ - Computes ``_recurrents``, the variable holding the list of recurrent + Compute ``_recurrents``, the variable holding the list of recurrent configurations, when ``recurrents()`` is first called by a user. EXAMPLES:: @@ -1370,12 +1331,9 @@ def recurrents(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: - - list of recurrent configurations + - ``verbose`` -- boolean (default: ``True``) + OUTPUT: list of recurrent configurations EXAMPLES:: @@ -1409,7 +1367,7 @@ def recurrents(self, verbose=True): def _set_superstables(self): r""" - Computes ``_superstables``, the variable holding the list of superstable + Compute ``_superstables``, the variable holding the list of superstable configurations, when ``superstables()`` is first called by a user. EXAMPLES:: @@ -1429,12 +1387,9 @@ def superstables(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: - - list of SandpileConfig + - ``verbose`` -- boolean (default: ``True``) + OUTPUT: list of SandpileConfig EXAMPLES:: @@ -1489,7 +1444,7 @@ def group_gens(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean + - ``verbose`` -- boolean (default: ``True``) OUTPUT: @@ -1521,9 +1476,7 @@ def genus(self): This is only defined for undirected graphs. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -1541,9 +1494,7 @@ def is_undirected(self): Is the underlying graph undirected? ``True`` if `(u,v)` is and edge if and only if `(v,u)` is an edge, each edge with the same weight. - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -1557,7 +1508,7 @@ def is_undirected(self): def _set_min_recurrents(self): r""" - Computes the minimal recurrent elements. If the underlying graph is + Compute the minimal recurrent elements. If the underlying graph is undirected, these are the recurrent elements of least degree. EXAMPLES:: @@ -1586,11 +1537,9 @@ def min_recurrents(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - list of SandpileConfig + OUTPUT: list of SandpileConfig EXAMPLES:: @@ -1623,11 +1572,9 @@ def max_superstables(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - tuple of SandpileConfig + OUTPUT: tuple of SandpileConfig EXAMPLES:: @@ -1657,9 +1604,7 @@ def tutte_polynomial(self): The Tutte polynomial of the underlying graph. Only defined for undirected sandpile graphs. - OUTPUT: - - polynomial + OUTPUT: polynomial EXAMPLES:: @@ -1706,11 +1651,9 @@ def avalanche_polynomial(self, multivariable=True): INPUT: - - ``multivariable`` -- (default: ``True``) boolean - - OUTPUT: + - ``multivariable`` -- boolean (default: ``True``) - polynomial + OUTPUT: polynomial EXAMPLES:: @@ -1746,11 +1689,9 @@ def nonspecial_divisors(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean + - ``verbose`` -- boolean (default: ``True``) - OUTPUT: - - list (of divisors) + OUTPUT: list (of divisors) EXAMPLES:: @@ -1793,9 +1734,7 @@ def canonical_divisor(self): The canonical divisor. This is the divisor with `\deg(v)-2` grains of sand on each vertex (not counting loops). Only for undirected graphs. - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -1816,7 +1755,7 @@ def canonical_divisor(self): def _set_invariant_factors(self): r""" - Computes the variable holding the elementary divisors of the sandpile + Compute the variable holding the elementary divisors of the sandpile group when ``invariant_factors()`` is first called by the user. EXAMPLES:: @@ -1835,9 +1774,7 @@ def invariant_factors(self): r""" The invariant factors of the sandpile group. - OUTPUT: - - list of integers + OUTPUT: list of integers EXAMPLES:: @@ -1849,7 +1786,7 @@ def invariant_factors(self): def _set_hilbert_function(self): """ - Computes the variables holding the Hilbert function of the homogeneous + Compute the variables holding the Hilbert function of the homogeneous homogeneous toppling ideal, the first differences of the Hilbert function, and the postulation number for the zero-set of the sandpile ideal when any one of these is called by the user. @@ -1875,9 +1812,7 @@ def h_vector(self): this is the list of first differences of the Hilbert function of the (homogeneous) toppling ideal. - OUTPUT: - - list of nonnegative integers + OUTPUT: list of nonnegative integers EXAMPLES:: @@ -1893,9 +1828,7 @@ def hilbert_function(self): r""" The Hilbert function of the homogeneous toppling ideal. - OUTPUT: - - list of nonnegative integers + OUTPUT: list of nonnegative integers EXAMPLES:: @@ -1912,9 +1845,7 @@ def postulation(self): The postulation number of the toppling ideal. This is the largest weight of a superstable configuration of the graph. - OUTPUT: - - nonnegative integer + OUTPUT: nonnegative integer EXAMPLES:: @@ -1944,9 +1875,7 @@ def smith_form(self): Laplacian, `D` is diagonal, and `U` and `V` are invertible over the integers. - OUTPUT: - - list of integer matrices + OUTPUT: list of integer matrices EXAMPLES:: @@ -1969,9 +1898,7 @@ def reorder_vertices(self): After reordering, vertex `u` comes before vertex `v` in the list of vertices if `u` is closer to the sink. - OUTPUT: - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -2047,11 +1974,9 @@ def jacobian_representatives(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - list of SandpileDivisor (or of lists representing divisors) + OUTPUT: list of SandpileDivisor (or of lists representing divisors) EXAMPLES: @@ -2103,11 +2028,9 @@ def picard_representatives(self, d, verbose=True): - ``d`` -- integer - - ``verbose`` -- (default: ``True``) boolean + - ``verbose`` -- boolean (default: ``True``) - OUTPUT: - - list of SandpileDivisors (or lists representing divisors) + OUTPUT: slist of SandpileDivisors (or lists representing divisors) EXAMPLES:: @@ -2138,10 +2061,7 @@ def stable_configs(self, smax=None): - ``smax`` -- (optional) SandpileConfig or list representing a SandpileConfig - - OUTPUT: - - generator for all stable configurations + OUTPUT: generator for all stable configurations EXAMPLES:: @@ -2173,13 +2093,13 @@ def markov_chain(self, state, distrib=None): INPUT: - - ``state`` -- SandpileConfig, SandpileDivisor, or list representing one of these + - ``state`` -- SandpileConfig, SandpileDivisor, or list representing + one of these - - ``distrib`` -- (optional) list of nonnegative numbers summing to 1 (representing a prob. dist.) - - OUTPUT: + - ``distrib`` -- (optional) list of nonnegative numbers summing to 1 + (representing a prob. dist.) - generator for Markov chain (see NOTE) + OUTPUT: generator for Markov chain (see NOTE) EXAMPLES:: @@ -2313,9 +2233,7 @@ def stationary_density(self): r""" The stationary density of the sandpile. - OUTPUT: - - rational number + OUTPUT: rational number EXAMPLES:: @@ -2350,9 +2268,7 @@ def all_k_div(self, k): - ``k`` -- integer - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -2366,9 +2282,7 @@ def zero_div(self): r""" The all-zero divisor. - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -2412,10 +2326,7 @@ def betti_complexes(self): r""" The support-complexes with non-trivial homology. (See NOTE.) - OUTPUT: - - list (of pairs [divisors, corresponding simplicial complex]) - + OUTPUT: list (of pairs [divisors, corresponding simplicial complex]) EXAMPLES:: @@ -2516,9 +2427,7 @@ def unsaturated_ideal(self): r""" The unsaturated, homogeneous toppling ideal. - OUTPUT: - - ideal + OUTPUT: ideal EXAMPLES:: @@ -2538,11 +2447,9 @@ def ideal(self, gens=False): INPUT: - - ``gens`` -- (default: ``False``) boolean + - ``gens`` -- boolean (default: ``False``) - OUTPUT: - - ideal or, optionally, the generators of an ideal + OUTPUT: ideal or, optionally, the generators of an ideal EXAMPLES:: @@ -2567,9 +2474,7 @@ def ring(self): r""" The ring containing the homogeneous toppling ideal. - OUTPUT: - - ring + OUTPUT: ring EXAMPLES:: @@ -2630,11 +2535,9 @@ def resolution(self, verbose=False): INPUT: - - ``verbose`` -- (default: ``False``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``False``) - free resolution of the toppling ideal + OUTPUT: free resolution of the toppling ideal EXAMPLES:: @@ -2670,7 +2573,7 @@ def resolution(self, verbose=False): def _set_groebner(self): r""" - Computes a Groebner basis for the homogeneous toppling ideal with + Compute a Groebner basis for the homogeneous toppling ideal with respect to the standard sandpile ordering (see ``ring``). EXAMPLES:: @@ -2687,9 +2590,7 @@ def groebner(self): A Groebner basis for the homogeneous toppling ideal. It is computed with respect to the standard sandpile ordering (see ``ring``). - OUTPUT: - - Groebner basis + OUTPUT: Groebner basis EXAMPLES:: @@ -2708,12 +2609,9 @@ def betti(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: - - Betti numbers for the sandpile + - ``verbose`` -- boolean (default: ``True``) + OUTPUT: Betti numbers for the sandpile EXAMPLES:: @@ -2740,9 +2638,7 @@ def solve(self): Approximations of the complex affine zeros of the sandpile ideal. - OUTPUT: - - list of complex numbers + OUTPUT: list of complex numbers EXAMPLES:: @@ -2813,9 +2709,7 @@ def points(self): Generators for the multiplicative group of zeros of the sandpile ideal. - OUTPUT: - - list of complex numbers + OUTPUT: list of complex numbers EXAMPLES: @@ -2839,9 +2733,7 @@ def symmetric_recurrents(self, orbits): - ``orbits`` -- list of lists partitioning the vertices - OUTPUT: - - list of recurrent configurations + OUTPUT: list of recurrent configurations EXAMPLES:: @@ -2896,11 +2788,9 @@ def help(verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - printed string + OUTPUT: printed string EXAMPLES:: @@ -2925,10 +2815,10 @@ def help(verbose=True): fire_unstable -- Fire all unstable vertices. fire_vertex -- Fire the given vertex. help -- List of SandpileConfig methods. - is_recurrent -- Is the configuration recurrent? - is_stable -- Is the configuration stable? - is_superstable -- Is the configuration superstable? - is_symmetric -- Is the configuration symmetric? + is_recurrent -- Return whether the configuration is recurrent. + is_stable -- Return whether the configuration is stable. + is_superstable -- Return whether the configuration is superstable. + is_symmetric -- Return whether the configuration is symmetric. order -- The order of the equivalent recurrent element. sandpile -- The configuration's underlying sandpile. show -- Show the configuration. @@ -2957,11 +2847,9 @@ def __init__(self, S, c): - ``S`` -- Sandpile - - ``c`` -- dict or list representing a configuration + - ``c`` -- dictionary or list representing a configuration - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3017,7 +2905,7 @@ def __setitem__(self, key, item): INPUT: - ``key``, ``item`` -- objects + - ``key``, ``item`` -- objects EXAMPLES:: @@ -3082,9 +2970,7 @@ def _set_deg(self): r""" Compute and store the degree of the configuration. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -3100,9 +2986,7 @@ def deg(self): r""" The degree of the configuration. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -3121,9 +3005,7 @@ def __add__(self, other): - ``other`` -- SandpileConfig - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -3145,9 +3027,7 @@ def __sub__(self, other): - ``other`` -- SandpileConfig - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -3170,9 +3050,7 @@ def __rsub__(self, other): - ``other`` -- SandpileConfig - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -3199,9 +3077,7 @@ def __neg__(self): r""" The additive inverse of the configuration. - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3223,9 +3099,7 @@ def __mul__(self, other): - ``other`` -- SandpileConfig or Integer - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3258,11 +3132,9 @@ def __rmul__(self, other): INPUT: - - ``other`` -- Integer - - OUTPUT: + - ``other`` -- integer - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3279,16 +3151,14 @@ def __rmul__(self, other): def __le__(self, other): r""" - ``True`` if every component of ``self`` is at most that of + Return ``True`` if every component of ``self`` is at most that of ``other``. INPUT: - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3311,16 +3181,14 @@ def __le__(self, other): def __lt__(self, other): r""" - ``True`` if every component of ``self`` is at most that + Return ``True`` if every component of ``self`` is at most that of ``other`` and the two configurations are not equal. INPUT: - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3338,16 +3206,14 @@ def __lt__(self, other): def __ge__(self, other): r""" - ``True`` if every component of ``self`` is at least that of + Return ``True`` if every component of ``self`` is at least that of ``other``. INPUT: - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3370,16 +3236,14 @@ def __ge__(self, other): def __gt__(self, other): r""" - ``True`` if every component of ``self`` is at least that + Return ``True`` if every component of ``self`` is at least that of ``other`` and the two configurations are not equal. INPUT: - ``other`` -- SandpileConfig - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3407,9 +3271,7 @@ def __pow__(self, k): - ``k`` -- SandpileConfig - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3448,9 +3310,7 @@ def __and__(self, other): - ``other`` -- SandpileConfig - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3471,9 +3331,7 @@ def sandpile(self): r""" The configuration's underlying sandpile. - OUTPUT: - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -3492,9 +3350,7 @@ def values(self): The list is sorted in the order of the vertices. - OUTPUT: - - list of integers + OUTPUT: list of integers boolean @@ -3515,9 +3371,7 @@ def dualize(self): r""" The difference with the maximal stable configuration. - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3540,9 +3394,7 @@ def fire_vertex(self, v): - ``v`` -- vertex - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3567,9 +3419,7 @@ def fire_script(self, sigma): - ``sigma`` -- SandpileConfig or (list or dict representing a SandpileConfig) - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3598,9 +3448,7 @@ def unstable(self): r""" The unstable vertices. - OUTPUT: - - list of vertices + OUTPUT: list of vertices EXAMPLES:: @@ -3616,9 +3464,7 @@ def fire_unstable(self): r""" Fire all unstable vertices. - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3637,7 +3483,7 @@ def fire_unstable(self): def _set_stabilize(self): r""" - Computes the stabilized configuration and its firing vector. + Compute the stabilized configuration and its firing vector. EXAMPLES:: @@ -3669,11 +3515,9 @@ def stabilize(self, with_firing_vector=False): INPUT: - - ``with_firing_vector`` -- (default: ``False``) boolean + - ``with_firing_vector`` -- boolean (default: ``False``) - OUTPUT: - - ``SandpileConfig`` or ``[SandpileConfig, firing_vector]`` + OUTPUT: ``SandpileConfig`` or ``[SandpileConfig, firing_vector]`` EXAMPLES:: @@ -3700,9 +3544,7 @@ def __invert__(self): r""" The stabilized configuration. - OUTPUT: - - ``SandpileConfig`` + OUTPUT: ``SandpileConfig`` Returns the stabilized configuration. @@ -3719,9 +3561,7 @@ def support(self): r""" The vertices containing sand. - OUTPUT: - - list - support of the configuration + OUTPUT: list - support of the configuration EXAMPLES:: @@ -3744,9 +3584,7 @@ def add_random(self, distrib=None): - ``distrib`` -- (optional) list of nonnegative numbers summing to 1 (representing a prob. dist.) - OUTPUT: - - SandpileConfig + OUTPUT: SandpileConfig EXAMPLES:: @@ -3819,9 +3657,7 @@ def order(self): r""" The order of the equivalent recurrent element. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -3845,11 +3681,9 @@ def order(self): def is_stable(self): r""" - Is the configuration stable? - - OUTPUT: + Return whether the configuration is stable. - boolean + OUTPUT: boolean EXAMPLES:: @@ -3868,7 +3702,7 @@ def is_stable(self): def _set_equivalent_recurrent(self): r""" - Sets the equivalent recurrent configuration and the corresponding + Set the equivalent recurrent configuration and the corresponding firing vector. EXAMPLES:: @@ -3901,12 +3735,9 @@ def equivalent_recurrent(self, with_firing_vector=False): INPUT: - - ``with_firing_vector`` -- (default: ``False``) boolean - - OUTPUT: - - SandpileConfig or [SandpileConfig, firing_vector] + - ``with_firing_vector`` -- boolean (default: ``False``) + OUTPUT: SandpileConfig or [SandpileConfig, firing_vector] EXAMPLES:: @@ -3934,7 +3765,7 @@ def equivalent_recurrent(self, with_firing_vector=False): def _set_is_recurrent(self): r""" - Computes and stores whether the configuration is recurrent. + Compute and store whether the configuration is recurrent. EXAMPLES:: @@ -3956,11 +3787,9 @@ def _set_is_recurrent(self): def is_recurrent(self): r""" - Is the configuration recurrent? + Return whether the configuration is recurrent. - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -3974,13 +3803,10 @@ def is_recurrent(self): def _set_equivalent_superstable(self): r""" - Sets the superstable configuration equivalent to the given + Set the superstable configuration equivalent to the given configuration and its corresponding firing vector. - OUTPUT: - - [configuration, firing_vector] - + OUTPUT: [configuration, firing_vector] EXAMPLES:: @@ -4000,12 +3826,9 @@ def equivalent_superstable(self, with_firing_vector=False): INPUT: - - ``with_firing_vector`` -- (default: ``False``) boolean - - OUTPUT: - - SandpileConfig or [SandpileConfig, firing_vector] + - ``with_firing_vector`` -- boolean (default: ``False``) + OUTPUT: SandpileConfig or [SandpileConfig, firing_vector] EXAMPLES:: @@ -4033,11 +3856,9 @@ def equivalent_superstable(self, with_firing_vector=False): def _set_is_superstable(self): r""" - Computes and stores whether ``config`` is superstable. + Compute and store whether ``config`` is superstable. - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4056,11 +3877,9 @@ def _set_is_superstable(self): def is_superstable(self): r""" - Is the configuration superstable? + Return whether the configuration is superstable. - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4072,17 +3891,15 @@ def is_superstable(self): def is_symmetric(self, orbits) -> bool: r""" - Is the configuration symmetric? Return ``True`` if the values of the + Return whether the configuration is symmetric. Return ``True`` if the values of the configuration are constant over the vertices in each sublist of ``orbits``. INPUT: - - ``orbits`` -- list of lists of vertices + - ``orbits`` -- list of lists of vertices - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4105,9 +3922,7 @@ def burst_size(self, v): - ``v`` -- vertex - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -4142,11 +3957,13 @@ def show(self, sink=True, colors=True, heights=False, directed=None, **kwds): INPUT: - - ``sink`` -- (default: ``True``) whether to show the sink + - ``sink`` -- boolean (default: ``True``); whether to show the sink - - ``colors`` -- (default: ``True``) whether to color-code the amount of sand on each vertex + - ``colors`` -- boolean (default: ``True``); whether to color-code the + amount of sand on each vertex - - ``heights`` -- (default: ``False``) whether to label each vertex with the amount of sand + - ``heights`` -- boolean (default: ``False``); whether to label each + vertex with the amount of sand - ``directed`` -- (optional) whether to draw directed edges @@ -4219,11 +4036,9 @@ def help(verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - printed string + OUTPUT: printed string EXAMPLES:: @@ -4241,11 +4056,11 @@ def help(verbose=True): fire_unstable -- Fire all unstable vertices. fire_vertex -- Fire the given vertex. help -- List of SandpileDivisor methods. - is_alive -- Is the divisor stabilizable? - is_linearly_equivalent -- Is the given divisor linearly equivalent? - is_q_reduced -- Is the divisor q-reduced? - is_symmetric -- Is the divisor symmetric? - is_weierstrass_pt -- Is the given vertex a Weierstrass point? + is_alive -- Return whether the divisor is stabilizable. + is_linearly_equivalent -- Return whether the given divisor is linearly equivalent. + is_q_reduced -- Return whether the divisor is q-reduced. + is_symmetric -- Return whether the divisor is symmetric. + is_weierstrass_pt -- Return whether the given vertex is a Weierstrass point. polytope -- The polytope determining the complete linear system. polytope_integer_pts -- The integer points inside divisor's polytope. q_reduced -- The linearly equivalent q-reduced divisor. @@ -4275,11 +4090,9 @@ def __init__(self, S, D): - ``S`` -- Sandpile - - ``D`` -- dict or list representing a divisor - - OUTPUT: + - ``D`` -- dictionary or list representing a divisor - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4307,7 +4120,7 @@ def __deepcopy__(self, memo): INPUT: - memo -- (optional) dict + - ``memo`` -- (optional) dictionary EXAMPLES:: @@ -4330,7 +4143,7 @@ def __setitem__(self, key, item): INPUT: - ``key``, ``item`` -- objects + - ``key``, ``item`` -- objects EXAMPLES:: @@ -4422,9 +4235,7 @@ def _set_deg(self): r""" Compute and store the degree of the divisor. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -4440,9 +4251,7 @@ def deg(self): r""" The degree of the divisor. - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -4461,9 +4270,7 @@ def __add__(self, other): - ``other`` -- SandpileDivisor - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -4485,9 +4292,7 @@ def __mul__(self, other): - ``other`` -- integer - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4508,11 +4313,9 @@ def __rmul__(self, other): INPUT: - - ``other`` -- Integer - - OUTPUT: + - ``other`` -- integer - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4535,9 +4338,7 @@ def __radd__(self, other): - ``other`` -- SandpileDivisor - OUTPUT: - - sum of ``self`` and ``other`` + OUTPUT: sum of ``self`` and ``other`` EXAMPLES:: @@ -4560,9 +4361,7 @@ def __sub__(self, other): - ``other`` -- SandpileDivisor - OUTPUT: - - Difference of ``self`` and ``other`` + OUTPUT: difference of ``self`` and ``other`` EXAMPLES:: @@ -4585,9 +4384,7 @@ def __rsub__(self, other): - ``other`` -- SandpileDivisor - OUTPUT: - - Difference of ``self`` and ``other`` + OUTPUT: difference of ``self`` and ``other`` EXAMPLES:: @@ -4608,9 +4405,7 @@ def __neg__(self): r""" The additive inverse of the divisor. - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4623,16 +4418,14 @@ def __neg__(self): def __le__(self, other): r""" - ``True`` if every component of ``self`` is at most that of + Return ``True`` if every component of ``self`` is at most that of ``other``. INPUT: - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4655,16 +4448,14 @@ def __le__(self, other): def __lt__(self, other): r""" - ``True`` if every component of ``self`` is at most that + Return ``True`` if every component of ``self`` is at most that of ``other`` and the two divisors are not equal. INPUT: - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4682,16 +4473,14 @@ def __lt__(self, other): def __ge__(self, other): r""" - ``True`` if every component of ``self`` is at least that of + Return ``True`` if every component of ``self`` is at least that of ``other``. INPUT: - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4714,16 +4503,14 @@ def __ge__(self, other): def __gt__(self, other): r""" - ``True`` if every component of ``self`` is at least that + Return ``True`` if every component of ``self`` is at least that of ``other`` and the two divisors are not equal. INPUT: - ``other`` -- SandpileDivisor - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4743,9 +4530,7 @@ def sandpile(self): r""" The divisor's underlying sandpile. - OUTPUT: - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -4764,9 +4549,7 @@ def values(self): The list is sorted in the order of the vertices. - OUTPUT: - - list of integers + OUTPUT: list of integers boolean @@ -4787,9 +4570,7 @@ def dualize(self): r""" The difference with the maximal stable divisor. - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4810,9 +4591,7 @@ def fire_vertex(self, v): - ``v`` -- vertex - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4836,9 +4615,7 @@ def fire_script(self, sigma): - ``sigma`` -- SandpileDivisor or (list or dict representing a SandpileDivisor) - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4866,9 +4643,7 @@ def unstable(self): r""" The unstable vertices. - OUTPUT: - - list of vertices + OUTPUT: list of vertices EXAMPLES:: @@ -4884,9 +4659,7 @@ def fire_unstable(self): r""" Fire all unstable vertices. - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -4927,11 +4700,9 @@ def q_reduced(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - SandpileDivisor or list representing SandpileDivisor + OUTPUT: SandpileDivisor or list representing SandpileDivisor EXAMPLES:: @@ -4954,12 +4725,10 @@ def q_reduced(self, verbose=True): def is_q_reduced(self): r""" - Is the divisor `q`-reduced? This would mean that `self = c + kq` where + Return whether the divisor is `q`-reduced. This would mean that `self = c + kq` where `c` is superstable, `k` is an integer, and `q` is the sink vertex. - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -4994,18 +4763,16 @@ def is_q_reduced(self): def is_linearly_equivalent(self, D, with_firing_vector=False): r""" - Is the given divisor linearly equivalent? Optionally, returns the + Return whether the given divisor is linearly equivalent. Optionally, returns the firing vector. (See NOTE.) INPUT: - ``D`` -- SandpileDivisor or list, tuple, etc. representing a divisor - - ``with_firing_vector`` -- (default: ``False``) boolean + - ``with_firing_vector`` -- boolean (default: ``False``) - OUTPUT: - - boolean or integer vector + OUTPUT: boolean or integer vector EXAMPLES:: @@ -5068,9 +4835,7 @@ def simulate_threshold(self, distrib=None): - ``distrib`` -- (optional) list of nonnegative numbers representing a probability distribution on the vertices - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -5105,11 +4870,11 @@ def simulate_threshold(self, distrib=None): def _set_linear_system(self): r""" - Computes and stores the complete linear system of a divisor. + Compute and store the complete linear system of a divisor. OUTPUT: - dict - ``{num_homog: int, homog:list, num_inhomog:int, inhomog:list}`` + dictionary; ``{num_homog: int, homog:list, num_inhomog:int, inhomog:list}`` EXAMPLES:: @@ -5219,9 +4984,7 @@ def polytope(self): r""" The polytope determining the complete linear system. - OUTPUT: - - polytope + OUTPUT: polytope EXAMPLES:: @@ -5270,9 +5033,7 @@ def polytope_integer_pts(self): here is the one determining the divisor's complete linear system (see the documentation for ``polytope``). - OUTPUT: - - tuple of integer vectors + OUTPUT: tuple of integer vectors EXAMPLES:: @@ -5319,13 +5080,11 @@ def effective_div(self, verbose=True, with_firing_vectors=False): INPUT: - - ``verbose`` -- (default: ``True``) boolean + - ``verbose`` -- boolean (default: ``True``) - - ``with_firing_vectors`` -- (default: ``False``) boolean - - OUTPUT: + - ``with_firing_vectors`` -- boolean (default: ``False``) - list (of divisors) + OUTPUT: list (of divisors) EXAMPLES:: @@ -5392,7 +5151,7 @@ def _set_rank(self, set_witness=False): INPUT: - - ``verbose`` -- (default: ``False``) boolean + - ``verbose`` -- boolean (default: ``False``) EXAMPLES:: @@ -5463,11 +5222,9 @@ def rank(self, with_witness=False): INPUT: - - ``with_witness`` -- (default: ``False``) boolean + - ``with_witness`` -- boolean (default: ``False``) - OUTPUT: - - integer or (integer, SandpileDivisor) + OUTPUT: integer or (integer, SandpileDivisor) EXAMPLES:: @@ -5523,12 +5280,12 @@ def rank(self, with_witness=False): def _set_r_of_D(self, verbose=False): r""" - Computes `r(D)` and an effective divisor `F` such that `|D - F|` is + Compute `r(D)` and an effective divisor `F` such that `|D - F|` is empty. INPUT: - - ``verbose`` -- (default: ``False``) boolean + - ``verbose`` -- boolean (default: ``False``) EXAMPLES:: @@ -5579,9 +5336,7 @@ def weierstrass_rank_seq(self, v='sink'): - ``v`` -- (default: ``sink``) vertex - OUTPUT: - - tuple of int + OUTPUT: tuple of int EXAMPLES:: @@ -5619,11 +5374,9 @@ def weierstrass_gap_seq(self, v='sink', weight=True): - ``v`` -- (default: ``sink``) vertex - - ``weight`` -- (default: ``True``) boolean - - OUTPUT: + - ``weight`` -- boolean (default: ``True``) - list or (list of list) of integers + OUTPUT: list or (list of list) of integers EXAMPLES:: @@ -5658,15 +5411,13 @@ def weierstrass_gap_seq(self, v='sink', weight=True): def is_weierstrass_pt(self, v='sink'): r""" - Is the given vertex a Weierstrass point? + Return whether the given vertex is a Weierstrass point. INPUT: - ``v`` -- (default: ``sink``) vertex - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -5707,15 +5458,14 @@ def _set_weierstrass_pts(self): def weierstrass_pts(self, with_rank_seq=False): r""" - The Weierstrass points (vertices). Optionally, return the corresponding rank sequences. + The Weierstrass points (vertices). Optionally, return the corresponding + rank sequences. INPUT: - - ``with_rank_seq`` -- (default: ``False``) boolean + - ``with_rank_seq`` -- boolean (default: ``False``) - OUTPUT: - - tuple of vertices or list of (vertex, rank sequence) + OUTPUT: tuple of vertices or list of (vertex, rank sequence) EXAMPLES:: @@ -5745,11 +5495,9 @@ def weierstrass_div(self, verbose=True): INPUT: - - ``verbose`` -- (default: ``True``) boolean - - OUTPUT: + - ``verbose`` -- boolean (default: ``True``) - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -5779,9 +5527,7 @@ def support(self): r""" List of vertices at which the divisor is nonzero. - OUTPUT: - - list representing the support of the divisor + OUTPUT: list representing the support of the divisor EXAMPLES:: @@ -5796,7 +5542,7 @@ def support(self): def _set_Dcomplex(self): r""" - Computes the simplicial complex determined by the supports of the + Compute the simplicial complex determined by the supports of the linearly equivalent effective divisors. EXAMPLES:: @@ -5834,9 +5580,7 @@ def Dcomplex(self): r""" The support-complex. (See NOTE.) - OUTPUT: - - simplicial complex + OUTPUT: simplicial complex EXAMPLES:: @@ -5861,9 +5605,7 @@ def betti(self): r""" The Betti numbers for the support-complex. (See NOTE.) - OUTPUT: - - dictionary of integers + OUTPUT: dictionary of integers EXAMPLES:: @@ -5887,9 +5629,7 @@ def add_random(self, distrib=None): - ``distrib`` -- (optional) list of nonnegative numbers representing a probability distribution on the vertices - OUTPUT: - - SandpileDivisor + OUTPUT: SandpileDivisor EXAMPLES:: @@ -5917,7 +5657,7 @@ def add_random(self, distrib=None): def is_symmetric(self, orbits): r""" - Is the divisor symmetric? Return ``True`` if the values of the + Return whether the divisor is symmetric. Return ``True`` if the values of the configuration are constant over the vertices in each sublist of ``orbits``. @@ -5925,9 +5665,7 @@ def is_symmetric(self, orbits): - ``orbits`` -- list of lists of vertices - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -5974,17 +5712,15 @@ def _set_life(self): def is_alive(self, cycle=False): r""" - Is the divisor stabilizable? In other words, will the divisor stabilize + Return whether the divisor is stabilizable. In other words, will the divisor stabilize under repeated firings of all unstable vertices? Optionally returns the resulting cycle. INPUT: - - ``cycle`` -- (default: ``False``) boolean + - ``cycle`` -- boolean (default: ``False``) - OUTPUT: - - boolean or optionally, a list of SandpileDivisors + OUTPUT: boolean or optionally, a list of SandpileDivisors EXAMPLES:: @@ -6028,7 +5764,7 @@ def stabilize(self, with_firing_vector=False): INPUT: - - ``with_firing_vector`` -- (default: ``False``) boolean + - ``with_firing_vector`` -- boolean (default: ``False``) EXAMPLES:: @@ -6049,7 +5785,8 @@ def show(self, heights=True, directed=None, **kwds): INPUT: - - ``heights`` -- (default: ``True``) whether to label each vertex with the amount of sand + - ``heights`` -- boolean (default: ``True``); whether to label each + vertex with the amount of sand - ``directed`` -- (optional) whether to draw directed edges @@ -6086,16 +5823,14 @@ def show(self, heights=True, directed=None, **kwds): def sandlib(selector=None): r""" - Returns the sandpile identified by ``selector``. If no argument is + Return the sandpile identified by ``selector``. If no argument is given, a description of the sandpiles in the sandlib is printed. INPUT: - ``selector`` -- (optional) identifier or None - OUTPUT: - - sandpile or description + OUTPUT: Sandpile or description EXAMPLES:: @@ -6172,9 +5907,7 @@ def triangle_sandpile(n): - ``n`` -- integer - OUTPUT: - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -6218,9 +5951,7 @@ def aztec_sandpile(n): - ``n`` -- integer - OUTPUT: - - dictionary for the aztec diamond graph + OUTPUT: dictionary for the aztec diamond graph EXAMPLES:: @@ -6274,14 +6005,11 @@ def glue_graphs(g, h, glue_g, glue_h): INPUT: - - ``g``, ``h`` -- dictionaries for directed multigraphs - - - ``glue_h``, ``glue_g`` -- dictionaries for a vertex - - OUTPUT: + - ``g``, ``h`` -- dictionaries for directed multigraphs - dictionary for a directed multigraph + - ``glue_h``, ``glue_g`` -- dictionaries for a vertex + OUTPUT: dictionary for a directed multigraph EXAMPLES:: @@ -6357,7 +6085,7 @@ def glue_graphs(g, h, glue_g, glue_h): def firing_graph(S, eff): r""" - Creates a digraph with divisors as vertices and edges between two divisors + Create a digraph with divisors as vertices and edges between two divisors `D` and `E` if firing a single vertex in `D` gives `E`. INPUT: @@ -6366,9 +6094,7 @@ def firing_graph(S, eff): - ``eff`` -- list of divisors - OUTPUT: - - DiGraph + OUTPUT: DiGraph EXAMPLES:: @@ -6394,7 +6120,7 @@ def firing_graph(S, eff): def parallel_firing_graph(S, eff): r""" - Creates a digraph with divisors as vertices and edges between two divisors + Create a digraph with divisors as vertices and edges between two divisors `D` and `E` if firing all unstable vertices in `D` gives `E`. INPUT: @@ -6403,9 +6129,7 @@ def parallel_firing_graph(S, eff): - ``eff`` -- list of divisors - OUTPUT: - - DiGraph + OUTPUT: DiGraph EXAMPLES:: @@ -6442,9 +6166,7 @@ def admissible_partitions(S, k): - ``k`` -- integer - OUTPUT: - - partitions + OUTPUT: partitions EXAMPLES:: @@ -6496,9 +6218,7 @@ def partition_sandpile(S, p): - ``p`` -- partition of the vertices of ``S`` - OUTPUT: - - Sandpile + OUTPUT: Sandpile EXAMPLES:: @@ -6542,9 +6262,7 @@ def min_cycles(G, v): - ``v`` -- vertex of ``G`` - OUTPUT: - - list of lists of vertices + OUTPUT: list of lists of vertices EXAMPLES:: @@ -6560,16 +6278,14 @@ def min_cycles(G, v): def wilmes_algorithm(M): r""" - Computes an integer matrix `L` with the same integer row span as `M` and + Compute an integer matrix `L` with the same integer row span as `M` and such that `L` is the reduced Laplacian of a directed multigraph. INPUT: - ``M`` -- square integer matrix of full rank - OUTPUT: - - integer matrix (``L``) + OUTPUT: integer matrix (``L``) EXAMPLES:: diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index d321366d0a0..bad6b33d4d3 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -50,7 +50,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): ``None`` then :class:`sage.sat.solvers.cryptominisat.CryptoMiniSat` is used to construct a new converter. (default: ``None``) - - ``target_variables`` -- a list of variables. The elements of the list are + - ``target_variables`` -- list of variables. The elements of the list are used to exclude a particular combination of variable assignments of a solution from any further solution. Furthermore ``target_variables`` denotes which variable-value pairs appear in the solutions. If @@ -59,14 +59,14 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): (default: ``None``) - ``**kwds`` -- parameters can be passed to the converter and the - solver by prefixing them with ``c_`` and ``s_`` respectively. For - example, to increase CryptoMiniSat's verbosity level, pass - ``s_verbosity=1``. + solver by prefixing them with ``c_`` and ``s_`` respectively. For + example, to increase CryptoMiniSat's verbosity level, pass + ``s_verbosity=1``. OUTPUT: - A list of dictionaries, each of which contains a variable - assignment solving ``F``. + A list of dictionaries, each of which contains a variable assignment + solving ``F``. EXAMPLES: @@ -335,9 +335,7 @@ def learn(F, converter=None, solver=None, max_learnt_length=3, interreduction=Fa ``s_`` respectively. For example, to increase CryptoMiniSat's verbosity level, pass ``s_verbosity=1``. - OUTPUT: - - A sequence of Boolean polynomials. + OUTPUT: a sequence of Boolean polynomials EXAMPLES:: diff --git a/src/sage/sat/converters/anf2cnf.py b/src/sage/sat/converters/anf2cnf.py index e6dd330feff..2316551fa2d 100644 --- a/src/sage/sat/converters/anf2cnf.py +++ b/src/sage/sat/converters/anf2cnf.py @@ -8,5 +8,6 @@ - Martin Albrecht (2012): first version """ -class ANF2CNFConverter(): + +class ANF2CNFConverter: pass diff --git a/src/sage/sat/converters/polybori.py b/src/sage/sat/converters/polybori.py index f45e9740475..27437c472ec 100644 --- a/src/sage/sat/converters/polybori.py +++ b/src/sage/sat/converters/polybori.py @@ -237,7 +237,7 @@ def choose(s): while not rest.empty(): l = choose(rest) l_variables = set(l.variables()) - block_dict = dict([(v, 1 if v in l_variables else 0) for v in variables]) + block_dict = {v: (1 if v in l_variables else 0) for v in variables} l = l.set() self.random_generator.shuffle(variables) for v in variables: @@ -257,7 +257,6 @@ def clauses_sparse(self, f): - ``f`` -- a :class:`sage.rings.polynomial.pbori.BooleanPolynomial` - EXAMPLES:: sage: B. = BooleanPolynomialRing() @@ -347,13 +346,13 @@ def clauses_dense(self, f): @cached_method def monomial(self, m): """ - Return SAT variable for ``m`` + Return SAT variable for ``m``. INPUT: - - ``m`` -- a monomial. + - ``m`` -- a monomial - OUTPUT: An index for a SAT variable corresponding to ``m``. + OUTPUT: an index for a SAT variable corresponding to ``m`` EXAMPLES:: @@ -383,7 +382,7 @@ def monomial(self, m): sage: e.phi [None, a, b, c, a*b, a*b*c] - .. note:: + .. NOTE:: For correctness, this function is cached. """ @@ -443,7 +442,7 @@ def split_xor(self, monomial_list, equal_zero): INPUT: - - ``monomial_list`` -- a list of monomials + - ``monomial_list`` -- list of monomials - ``equal_zero`` -- is the constant coefficient zero? EXAMPLES:: @@ -543,8 +542,7 @@ def __call__(self, F): - ``F`` -- an iterable of :class:`sage.rings.polynomial.pbori.BooleanPolynomial` - OUTPUT: An inverse map int -> variable - + OUTPUT: an inverse map int -> variable EXAMPLES:: @@ -582,7 +580,7 @@ def __call__(self, F): def to_polynomial(self, c): """ - Convert clause to :class:`sage.rings.polynomial.pbori.BooleanPolynomial` + Convert clause to :class:`sage.rings.polynomial.pbori.BooleanPolynomial`. INPUT: diff --git a/src/sage/sat/meson.build b/src/sage/sat/meson.build new file mode 100644 index 00000000000..a1a0246dfce --- /dev/null +++ b/src/sage/sat/meson.build @@ -0,0 +1,4 @@ +py.install_sources('all.py', 'boolean_polynomials.py', subdir: 'sage/sat') + +install_subdir('converters', install_dir: sage_install_dir / 'sat') +subdir('solvers') diff --git a/src/sage/sat/solvers/cryptominisat.py b/src/sage/sat/solvers/cryptominisat.py index 27955c43eef..e23c3491ccc 100644 --- a/src/sage/sat/solvers/cryptominisat.py +++ b/src/sage/sat/solvers/cryptominisat.py @@ -22,9 +22,9 @@ from .satsolver import SatSolver from sage.misc.lazy_import import lazy_import -from sage.features import PythonModule -lazy_import('pycryptosat', ['Solver'], - feature=PythonModule('pycryptosat', spkg='pycryptosat')) +from sage.features.sat import Pycryptosat + +lazy_import('pycryptosat', ['Solver'], feature=Pycryptosat()) class CryptoMiniSat(SatSolver): @@ -33,12 +33,12 @@ class CryptoMiniSat(SatSolver): INPUT: - - ``verbosity`` -- an integer between 0 and 15 (default: 0). Verbosity. + - ``verbosity`` -- integer between 0 and 15 (default: 0) - - ``confl_limit`` -- an integer (default: ``None``). Abort after this many + - ``confl_limit`` -- integer (default: ``None``); abort after this many conflicts. If set to ``None``, never aborts. - - ``threads`` -- an integer (default: None). The number of thread to + - ``threads`` -- integer (default: ``None``); the number of thread to use. If set to ``None``, the number of threads used corresponds to the number of cpus. @@ -74,7 +74,7 @@ def var(self, decision=None): INPUT: - - ``decision`` -- accepted for compatibility with other solvers, ignored. + - ``decision`` -- accepted for compatibility with other solvers; ignored EXAMPLES:: @@ -119,9 +119,9 @@ def add_clause(self, lits): INPUT: - - ``lits`` -- a tuple of nonzero integers. + - ``lits`` -- tuple of nonzero integers - .. note:: + .. NOTE:: If any element ``e`` in ``lits`` has ``abs(e)`` greater than the number of variables generated so far, then new @@ -147,10 +147,10 @@ def add_xor_clause(self, lits, rhs=True): INPUT: - - ``lits`` -- a tuple of positive integers. + - ``lits`` -- tuple of positive integers - - ``rhs`` -- boolean (default: ``True``). Whether this XOR clause should - be evaluated to ``True`` or ``False``. + - ``rhs`` -- boolean (default: ``True``); whether this XOR clause should + be evaluated to ``True`` or ``False`` EXAMPLES:: diff --git a/src/sage/sat/solvers/dimacs.py b/src/sage/sat/solvers/dimacs.py index aafccfab48b..61d5460d432 100644 --- a/src/sage/sat/solvers/dimacs.py +++ b/src/sage/sat/solvers/dimacs.py @@ -6,7 +6,7 @@ Currently, interfaces to **RSat** and **Glucose** are included by default. -.. note:: +.. NOTE:: Our SAT solver interfaces are 1-based, i.e., literals start at 1. This is consistent with the popular DIMACS format for SAT solving but not with Pythion's 0-based convention. However, this @@ -42,7 +42,7 @@ class DIMACS(SatSolver): """ Generic DIMACS Solver. - .. note:: + .. NOTE:: Usually, users won't have to use this class directly but some class which inherits from this class. @@ -73,8 +73,7 @@ def __init__(self, command=None, filename=None, verbosity=0, **kwds): - ``verbosity`` -- a verbosity level, where zero means silent and anything else means verbose output. (default: ``0``) - - ``**kwds`` -- accepted for compatibility with other solves, - ignored. + - ``**kwds`` -- accepted for compatibility with other solvers; ignored TESTS:: @@ -82,8 +81,10 @@ def __init__(self, command=None, filename=None, verbosity=0, **kwds): sage: DIMACS() DIMACS Solver: '' """ + self._headname_file_created_during_init = False if filename is None: filename = tmp_filename() + self._headname_file_created_during_init = True self._headname = filename self._verbosity = verbosity @@ -114,11 +115,31 @@ def __del__(self): sage: from sage.sat.solvers.dimacs import DIMACS sage: d = DIMACS(command="iliketurtles {input}") sage: del d + + We check that files created during initialization are properly + deleted (:issue:`38328`):: + + sage: from sage.sat.solvers.dimacs import DIMACS + sage: d = DIMACS(command="iliketurtles {input}") + sage: filename = d._headname + sage: os.path.exists(filename) + True + sage: del d + sage: os.path.exists(filename) + False + + :: + + sage: fn = tmp_filename() + sage: d = DIMACS(filename=fn) + sage: del d """ if not self._tail.closed: self._tail.close() if os.path.exists(self._tail.name): os.unlink(self._tail.name) + if self._headname_file_created_during_init and os.path.exists(self._headname): + os.unlink(self._headname) def var(self, decision=None): """ @@ -126,7 +147,7 @@ def var(self, decision=None): INPUT: - - ``decision`` -- accepted for compatibility with other solvers, ignored. + - ``decision`` -- accepted for compatibility with other solvers; ignored EXAMPLES:: @@ -161,9 +182,9 @@ def add_clause(self, lits): INPUT: - - ``lits`` -- a tuple of integers != 0 + - ``lits`` -- tuple of nonzero integers - .. note:: + .. NOTE:: If any element ``e`` in ``lits`` has ``abs(e)`` greater than the number of variables generated so far, then new @@ -232,7 +253,7 @@ def write(self, filename=None): tail.close() head = open(headname,"a") - tail = open(self._tail.name,"r") + tail = open(self._tail.name) head.write(tail.read()) tail.close() head.close() @@ -280,7 +301,7 @@ def clauses(self, filename=None): else: tail = self._tail tail.close() - tail = open(self._tail.name,"r") + tail = open(self._tail.name) clauses = [] for line in tail.readlines(): @@ -304,7 +325,7 @@ def render_dimacs(clauses, filename, nlits): INPUT: - - ``clauses`` -- a list of clauses, either in simple format as a list of + - ``clauses`` -- list of clauses, either in simple format as a list of literals or in extended format for CryptoMiniSat: a tuple of literals, ``is_xor`` and ``rhs``. @@ -498,7 +519,6 @@ def __call__(self, assumptions=None): ....: except ZeroDivisionError: ....: pass sage: solve_sat(F, solver=sage.sat.solvers.RSat) # optional - rsat, needs sage.rings.finite_rings sage.rings.polynomial.pbori - """ if assumptions is not None: raise NotImplementedError("Assumptions are not supported for DIMACS based solvers.") @@ -520,7 +540,8 @@ def __call__(self, assumptions=None): assert L[-1] == "0", "last digit of solution line must be zero (not {})".format(L[-1]) return (None,) + tuple(int(e) > 0 for e in L[:-1]) else: - raise ValueError("When parsing the output, no line starts with letter v or s") + raise ValueError("When parsing the output(={}), no line starts with letter v or s".format(self._output)) + class RSat(DIMACS): """ @@ -554,7 +575,6 @@ class RSat(DIMACS): sage: solver.add_clause((-1,-2)) sage: solver() # optional - rsat False - """ command = "rsat {input} -v -s" @@ -620,10 +640,10 @@ class Glucose(DIMACS): c... s SATISFIABLE v -1 -2 ... 100 0 - """ command = "glucose -verb=0 -model {input}" + class GlucoseSyrup(DIMACS): """ An instance of the Glucose-syrup parallel solver. @@ -684,13 +704,13 @@ class GlucoseSyrup(DIMACS): c... s SATISFIABLE v -1 -2 ... 100 0 - """ command = "glucose-syrup -model -verb=0 {input}" + class Kissat(DIMACS): """ - An instance of the Kissat SAT solver + An instance of the Kissat SAT solver. For information on Kissat see: http://fmv.jku.at/kissat/ @@ -748,7 +768,6 @@ class Kissat(DIMACS): v ... v ... v ... 100 0 - """ command = "kissat -q {input}" diff --git a/src/sage/sat/solvers/meson.build b/src/sage/sat/solvers/meson.build new file mode 100644 index 00000000000..86657c5c854 --- /dev/null +++ b/src/sage/sat/solvers/meson.build @@ -0,0 +1,23 @@ +py.install_sources( + '__init__.py', + 'cryptominisat.py', + 'dimacs.py', + 'picosat.py', + 'sat_lp.py', + 'satsolver.pxd', + subdir: 'sage/sat/solvers', +) + +extension_data = {'satsolver' : files('satsolver.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/sat/solvers', + install: true, + include_directories: [], + dependencies: [py_dep, gmp], + ) +endforeach + diff --git a/src/sage/sat/solvers/picosat.py b/src/sage/sat/solvers/picosat.py index a88f69da883..fb8c10afd80 100644 --- a/src/sage/sat/solvers/picosat.py +++ b/src/sage/sat/solvers/picosat.py @@ -21,9 +21,9 @@ from .satsolver import SatSolver from sage.misc.lazy_import import lazy_import -from sage.features import PythonModule -lazy_import('pycosat', ['solve'], - feature=PythonModule('pycosat', spkg='pycosat')) +from sage.features.sat import Pycosat + +lazy_import('pycosat', ['solve'], feature=Pycosat()) class PicoSAT(SatSolver): @@ -32,9 +32,9 @@ class PicoSAT(SatSolver): INPUT: - - ``verbosity`` -- an integer between 0 and 2 (default: 0); verbosity + - ``verbosity`` -- integer between 0 and 2 (default: 0) - - ``prop_limit`` -- an integer (default: 0); the propagation limit + - ``prop_limit`` -- integer (default: 0); the propagation limit EXAMPLES:: @@ -112,7 +112,7 @@ def add_clause(self, lits): INPUT: - - ``lits`` -- a tuple of nonzero integers + - ``lits`` -- tuple of nonzero integers .. NOTE:: diff --git a/src/sage/sat/solvers/sat_lp.py b/src/sage/sat/solvers/sat_lp.py index de9f8b082c7..5a027f6ae9b 100644 --- a/src/sage/sat/solvers/sat_lp.py +++ b/src/sage/sat/solvers/sat_lp.py @@ -10,14 +10,15 @@ from .satsolver import SatSolver from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException + class SatLP(SatSolver): def __init__(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Initializes the instance + Initialize the instance. INPUT: - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -25,15 +26,15 @@ def __init__(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): of the class :class:`MixedIntegerLinearProgram `. - - ``verbose`` -- integer (default: ``0``). Sets the level of verbosity + - ``verbose`` -- integer (default: 0); sets the level of verbosity of the LP solver. Set to 0 by default, which means quiet. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` EXAMPLES:: - sage: S=SAT(solver="LP"); S + sage: S=SAT(solver='LP'); S an ILP-based SAT Solver """ SatSolver.__init__(self) @@ -48,7 +49,7 @@ def var(self): EXAMPLES:: - sage: S=SAT(solver="LP"); S + sage: S=SAT(solver='LP'); S an ILP-based SAT Solver sage: S.var() 1 @@ -65,7 +66,7 @@ def nvars(self): EXAMPLES:: - sage: S=SAT(solver="LP"); S + sage: S=SAT(solver='LP'); S an ILP-based SAT Solver sage: S.var() 1 @@ -82,9 +83,9 @@ def add_clause(self, lits): INPUT: - - ``lits`` -- a tuple of integers != 0 + - ``lits`` -- tuple of nonzero integers - .. note:: + .. NOTE:: If any element ``e`` in ``lits`` has ``abs(e)`` greater than the number of variables generated so far, then new @@ -92,7 +93,7 @@ def add_clause(self, lits): EXAMPLES:: - sage: S=SAT(solver="LP"); S + sage: S=SAT(solver='LP'); S an ILP-based SAT Solver sage: for u,v in graphs.CycleGraph(6).edges(sort=False, labels=False): ....: u,v = u+1,v+1 @@ -120,7 +121,7 @@ def __call__(self): EXAMPLES:: sage: def is_bipartite_SAT(G): - ....: S=SAT(solver="LP"); S + ....: S=SAT(solver='LP'); S ....: for u,v in G.edges(sort=False, labels=False): ....: u,v = u+1,v+1 ....: S.add_clause((u,v)) @@ -148,7 +149,7 @@ def __repr__(self): """ TESTS:: - sage: S=SAT(solver="LP"); S + sage: S=SAT(solver='LP'); S an ILP-based SAT Solver """ return "an ILP-based SAT Solver" diff --git a/src/sage/sat/solvers/satsolver.pyx b/src/sage/sat/solvers/satsolver.pyx index 7b63a1ee87d..9de7b4a9ca7 100644 --- a/src/sage/sat/solvers/satsolver.pyx +++ b/src/sage/sat/solvers/satsolver.pyx @@ -67,7 +67,7 @@ cdef class SatSolver: INPUT: - - ``lits`` -- a tuple of integers != 0 + - ``lits`` -- tuple of nonzero integers .. NOTE:: @@ -111,7 +111,7 @@ cdef class SatSolver: INPUT: - - ``filename`` -- The name of a file as a string or a file object + - ``filename`` -- the name of a file as a string or a file object EXAMPLES:: @@ -269,7 +269,6 @@ cdef class SatSolver: If ``filename`` points to a writable file, then the list of original clauses is written to that file in DIMACS format. - EXAMPLES:: sage: from sage.sat.solvers.satsolver import SatSolver @@ -320,58 +319,58 @@ def SAT(solver=None, *args, **kwds): INPUT: - - ``solver`` (string) -- select a solver. Admissible values are: + - ``solver`` -- string; select a solver. Admissible values are: - - ``"cryptominisat"`` -- note that the pycryptosat package must be - installed. + - ``'cryptominisat'`` -- note that the pycryptosat package must be + installed - - ``"picosat"`` -- note that the pycosat package must be installed. + - ``'picosat'`` -- note that the pycosat package must be installed - - ``"glucose"`` -- note that the glucose package must be installed. + - ``'glucose'`` -- note that the glucose package must be installed - - ``"glucose-syrup"`` -- note that the glucose package must be installed. + - ``'glucose-syrup'`` -- note that the glucose package must be installed - - ``"LP"`` -- use :class:`~sage.sat.solvers.sat_lp.SatLP` to solve the - SAT instance. + - ``'LP'`` -- use :class:`~sage.sat.solvers.sat_lp.SatLP` to solve the + SAT instance - - ``None`` (default) -- use CryptoMiniSat if available, else PicoSAT if - available, and a LP solver otherwise. + - ``None`` -- default; use CryptoMiniSat if available, else PicoSAT if + available, and a LP solver otherwise EXAMPLES:: - sage: SAT(solver="LP") # needs sage.numerical.mip + sage: SAT(solver='LP') # needs sage.numerical.mip an ILP-based SAT Solver TESTS:: - sage: SAT(solver="Wouhouuuuuu") + sage: SAT(solver='Wouhouuuuuu') Traceback (most recent call last): ... ValueError: Solver 'Wouhouuuuuu' is not available Forcing CryptoMiniSat:: - sage: SAT(solver="cryptominisat") # optional - pycryptosat + sage: SAT(solver='cryptominisat') # optional - pycryptosat CryptoMiniSat solver: 0 variables, 0 clauses. Forcing PicoSat:: - sage: SAT(solver="picosat") # optional - pycosat + sage: SAT(solver='picosat') # optional - pycosat PicoSAT solver: 0 variables, 0 clauses. Forcing Glucose:: - sage: SAT(solver="glucose") + sage: SAT(solver='glucose') DIMACS Solver: 'glucose -verb=0 -model {input}' Forcing Glucose Syrup:: - sage: SAT(solver="glucose-syrup") + sage: SAT(solver='glucose-syrup') DIMACS Solver: 'glucose-syrup -model -verb=0 {input}' Forcing Kissat:: - sage: SAT(solver="kissat") + sage: SAT(solver='kissat') DIMACS Solver: 'kissat -q {input}' """ if solver is None: diff --git a/src/sage/schemes/affine/affine_homset.py b/src/sage/schemes/affine/affine_homset.py old mode 100644 new mode 100755 index f90bcfffec1..e2dc72eadd0 --- a/src/sage/schemes/affine/affine_homset.py +++ b/src/sage/schemes/affine/affine_homset.py @@ -10,7 +10,7 @@ the rational points are implemented by such scheme morphisms. This is done by :class:`SchemeHomset_points` and its subclasses. -.. note:: +.. NOTE:: You should not create the Hom-sets manually. Instead, use the :meth:`~sage.structure.parent.Hom` method that is inherited by all @@ -36,8 +36,6 @@ from sage.misc.verbose import verbose from sage.rings.integer_ring import ZZ -from sage.rings.real_mpfr import RR -from sage.rings.cc import CC from sage.rings.rational_field import RationalField from sage.categories.fields import Fields from sage.categories.number_fields import NumberFields @@ -93,7 +91,7 @@ def _repr_(self): """ Return a string representation of a homset. - OUTPUT: A string. + OUTPUT: string EXAMPLES:: @@ -180,9 +178,7 @@ def points(self, **kwds): by lowering the tolerance. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- real number (default: 0). The bound for the height of the coordinates. Only used for subschemes with @@ -192,15 +188,13 @@ def points(self, **kwds): For numerically inexact fields, points are on the subscheme if they satisfy the equations to within tolerance. - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 - for enumeration over number fields. + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm-4 for enumeration over number fields - ``precision`` -- the precision to use for computing the elements of - bounded height of number fields. - - OUTPUT: + bounded height of number fields - - a list of rational points of a affine scheme + OUTPUT: list of rational points of a affine scheme .. WARNING:: @@ -268,6 +262,7 @@ def points(self, **kwds): if hasattr(X.base_ring(), 'precision'): numerical = True verbose("Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.", level=0) + from sage.rings.real_mpfr import RR zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10))) if zero_tol <= 0: raise ValueError("tolerance must be positive") @@ -384,7 +379,7 @@ def numerical_points(self, F=None, **kwds): For numerically inexact fields, points are on the subscheme if they satisfy the equations to within tolerance. - OUTPUT: A list of points in the ambient space. + OUTPUT: list of points in the ambient space .. WARNING:: @@ -438,7 +433,7 @@ def numerical_points(self, F=None, **kwds): """ from sage.schemes.affine.affine_space import AffineSpace_generic if F is None: - F = CC + from sage.rings.cc import CC as F if F not in Fields() or not hasattr(F, 'precision'): raise TypeError('F must be a numerical field') X = self.codomain() @@ -455,6 +450,7 @@ def numerical_points(self, F=None, **kwds): return [] # if X zero-dimensional + from sage.rings.real_mpfr import RR zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10))) if zero_tol <= 0: raise ValueError("tolerance must be positive") diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py old mode 100644 new mode 100755 index d99e2843410..0eba4c662ec --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -49,8 +49,6 @@ import sage.rings.abc -from sage.calculus.functions import jacobian - from sage.categories.homset import Hom, End from sage.categories.fields import Fields @@ -274,15 +272,13 @@ def __call__(self, x, check=True): def __eq__(self, right): """ - Tests the equality of two affine maps. + Test the equality of two affine maps. INPUT: - ``right`` -- a map on affine space - OUTPUT: - - ``True`` if the two affine maps define the same map. + OUTPUT: ``True`` if the two affine maps define the same map EXAMPLES:: @@ -312,15 +308,13 @@ def __eq__(self, right): def __ne__(self, right): """ - Tests the inequality of two affine maps. + Test the inequality of two affine maps. INPUT: - ``right`` -- a map on affine space - OUTPUT: - - ``True`` if the two affine maps define the same map. + OUTPUT: ``True`` if the two affine maps define the same map EXAMPLES:: @@ -444,7 +438,7 @@ def homogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, + - ``n`` -- tuple of nonnegative integers; if ``n`` is an integer, then the two values of the tuple are assumed to be the same OUTPUT: a morphism from the projective embedding of the domain of this map @@ -638,9 +632,7 @@ def as_dynamical_system(self): """ Return this endomorphism as a :class:`DynamicalSystem_affine`. - OUTPUT: - - - :class:`DynamicalSystem_affine` + OUTPUT: :class:`DynamicalSystem_affine` EXAMPLES:: @@ -697,9 +689,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -755,14 +747,12 @@ def local_height(self, v, prec=None): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default RealField precision) - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -811,14 +801,12 @@ def local_height_arch(self, i, prec=None): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default RealField precision) - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -862,9 +850,7 @@ def jacobian(self): The `(i, j)` entry of the Jacobian matrix is the partial derivative ``diff(functions[i], variables[j])``. - OUTPUT: - - - matrix with coordinates in the coordinate ring of the map. + OUTPUT: matrix with coordinates in the coordinate ring of the map EXAMPLES:: @@ -896,6 +882,9 @@ def jacobian(self): return self.__jacobian except AttributeError: pass + + from sage.calculus.functions import jacobian + self.__jacobian = jacobian(list(self), self.domain().ambient_space().gens()) return self.__jacobian @@ -1029,8 +1018,7 @@ def degree(self): poly_numerator = poly.numerator() poly_denominator = poly.denominator() degree = max(poly_numerator.degree(), poly_denominator.degree()) - if degree > max_degree: - max_degree = degree + max_degree = max(degree, max_degree) # polynomial affine map elif poly.degree() > max_degree: max_degree = poly.degree() @@ -1058,7 +1046,7 @@ def weil_restriction(self): morphism from the Weil restriction of the domain to the Weil restriction of the codomain. - OUTPUT: Scheme morphism on the Weil restrictions of the domain + OUTPUT: scheme morphism on the Weil restrictions of the domain and codomain of the map. EXAMPLES:: @@ -1291,7 +1279,6 @@ def indeterminacy_points(self, F=None): sage: f = A2.hom([x*y, y, x], P2) sage: f.indeterminacy_points() # needs sage.libs.singular [(0, 0)] - """ if F is None: fcn = self @@ -1523,7 +1510,6 @@ def indeterminacy_locus(self): y*z sage: L.dimension() # needs sage.libs.singular 1 - """ # homogenize using 0th affine patch both for domain and codomain h = self.homogenize(0) diff --git a/src/sage/schemes/affine/affine_point.py b/src/sage/schemes/affine/affine_point.py old mode 100644 new mode 100755 index bf6dc2258bc..eb13ba7c2cd --- a/src/sage/schemes/affine/affine_point.py +++ b/src/sage/schemes/affine/affine_point.py @@ -22,8 +22,9 @@ # **************************************************************************** from sage.categories.number_fields import NumberFields +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ -from sage.schemes.generic.morphism import SchemeMorphism_point, SchemeMorphism, is_SchemeMorphism +from sage.schemes.generic.morphism import SchemeMorphism_point, SchemeMorphism from sage.structure.sequence import Sequence _NumberFields = NumberFields() @@ -42,9 +43,9 @@ class SchemeMorphism_point_affine(SchemeMorphism_point): - ``X`` -- a subscheme of an ambient affine space over a ring `R` - - ``v`` -- a list/tuple/iterable of coordinates in `R` + - ``v`` -- list/tuple/iterable of coordinates in `R` - - ``check`` -- boolean (default:``True``); whether to + - ``check`` -- boolean (default: ``True``); whether to check the input for consistency EXAMPLES:: @@ -69,7 +70,7 @@ def __init__(self, X, v, check=True): SchemeMorphism.__init__(self, X) if check: from sage.categories.commutative_rings import CommutativeRings - if is_SchemeMorphism(v): + if isinstance(v, SchemeMorphism): v = list(v) else: try: @@ -91,7 +92,7 @@ def __init__(self, X, v, check=True): def _matrix_times_point_(self, mat, dom): r""" - Multiplies the point on the left by a matrix ``mat``. + Multiply the point on the left by a matrix ``mat``. INPUT: @@ -138,7 +139,7 @@ def _matrix_times_point_(self, mat, dom): def __hash__(self): r""" - Computes the hash value of this affine point. + Compute the hash value of this affine point. EXAMPLES:: @@ -152,22 +153,19 @@ def __hash__(self): sage: pt = A([1, 2, -i]) # needs sage.rings.real_mpfr sage.symbolic sage: hash(pt) == hash(tuple(pt)) # needs sage.rings.real_mpfr sage.symbolic True - """ return hash(tuple(self)) def global_height(self, prec=None): r""" - Returns the logarithmic height of the point. + Return the logarithmic height of the point. INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: - - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -202,7 +200,7 @@ def global_height(self, prec=None): else: R = RealField(prec) H = max([self[i].abs() for i in range(self.codomain().ambient_space().dimension_relative())]) - return R(max(H,1)).log() + return R(max(H, 1)).log() if self.domain().base_ring() in _NumberFields or isinstance(self.domain().base_ring(), sage.rings.abc.Order): return max([self[i].global_height(prec) for i in range(self.codomain().ambient_space().dimension_relative())]) else: @@ -214,11 +212,9 @@ def homogenize(self, n): INPUT: - - ``n`` -- integer between 0 and dimension of the map, inclusive. - - OUTPUT: + - ``n`` -- integer between 0 and dimension of the map, inclusive - - A point in the projectivization of the codomain of the map . + OUTPUT: a point in the projectivization of the codomain of the map EXAMPLES:: @@ -278,7 +274,7 @@ def weil_restriction(self): the equivalent point on the Weil restriction of its codomain. - OUTPUT: Scheme point on the Weil restriction of the codomain of this point. + OUTPUT: scheme point on the Weil restriction of the codomain of this point EXAMPLES:: @@ -345,9 +341,9 @@ def intersection_multiplicity(self, X): INPUT: - - ``X`` -- a subscheme in the same ambient space as that of the codomain of this point. + - ``X`` -- a subscheme in the same ambient space as that of the codomain of this point - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: @@ -384,7 +380,7 @@ def multiplicity(self): Uses the subscheme multiplicity implementation. This point must be a point on an affine subscheme. - OUTPUT: an integer. + OUTPUT: integer EXAMPLES:: @@ -430,9 +426,9 @@ class SchemeMorphism_point_affine_finite_field(SchemeMorphism_point_affine_field def __hash__(self): r""" - Returns the integer hash of the point. + Return the integer hash of the point. - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/schemes/affine/affine_rational_point.py b/src/sage/schemes/affine/affine_rational_point.py old mode 100644 new mode 100755 index 0f4a0f0bbe6..034637c8862 --- a/src/sage/schemes/affine/affine_rational_point.py +++ b/src/sage/schemes/affine/affine_rational_point.py @@ -62,8 +62,8 @@ def enum_affine_rational_field(X, B): INPUT: - - ``X`` -- a scheme or set of abstract rational points of a scheme. - - ``B`` -- a positive integer bound. + - ``X`` -- a scheme or set of abstract rational points of a scheme + - ``B`` -- a positive integer bound OUTPUT: @@ -170,15 +170,13 @@ def enum_affine_number_field(X, **kwds): [DK2013]_. Algorithm 5 is used for imaginary quadratic fields. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- a real number - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm algorithm-4 - - ``precision`` -- the precision to use for computing the elements of bounded height of number fields. + - ``precision`` -- the precision to use for computing the elements of bounded height of number fields OUTPUT: @@ -240,8 +238,8 @@ def enum_affine_finite_field(X): INPUT: - - ``X`` -- a scheme defined over a finite field or a set of abstract - rational points of such a scheme. + - ``X`` -- a scheme defined over a finite field or a set of abstract + rational points of such a scheme OUTPUT: diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py old mode 100644 new mode 100755 index 889d9005ed6..b21ac4a7de6 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -15,8 +15,8 @@ from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.finite_rings.finite_field_base import FiniteField from sage.categories.map import Map from sage.categories.fields import Fields @@ -109,7 +109,7 @@ def AffineSpace(n, R=None, names=None, ambient_projective_space=None, ... NameError: variable names passed to AffineSpace conflict with names in ring """ - if (is_MPolynomialRing(n) or is_PolynomialRing(n)) and R is None: + if (isinstance(n, MPolynomialRing_base) or isinstance(n, PolynomialRing_general)) and R is None: R = n if names is not None: # Check for the case that the user provided a variable name @@ -233,8 +233,8 @@ def __iter__(self): def ngens(self): """ - Return the number of generators of self, i.e. the number of - variables in the coordinate ring of self. + Return the number of generators of ``self``, i.e. the number of + variables in the coordinate ring of ``self``. EXAMPLES:: @@ -247,8 +247,8 @@ def ngens(self): def rational_points(self, F=None): """ - Return the list of ``F``-rational points on the affine space self, - where ``F`` is a given finite field, or the base ring of self. + Return the list of ``F``-rational points on the affine space ``self``, + where ``F`` is a given finite field, or the base ring of ``self``. EXAMPLES:: @@ -332,14 +332,14 @@ def _latex_(self): EXAMPLES:: sage: print(latex(AffineSpace(1, ZZ, 'x'))) - \mathbf{A}_{\Bold{Z}}^1 + \mathbf{A}_{\Bold{Z}}^{1} TESTS:: - sage: AffineSpace(3, Zp(5), 'y')._latex_() # needs sage.rings.padics - '\\mathbf{A}_{\\Bold{Z}_{5}}^3' + sage: AffineSpace(11, Zp(5), 'y')._latex_() # needs sage.rings.padics + '\\mathbf{A}_{\\Bold{Z}_{5}}^{11}' """ - return "\\mathbf{A}_{%s}^%s" % (latex(self.base_ring()), self.dimension_relative()) + return "\\mathbf{A}_{%s}^{%s}" % (latex(self.base_ring()), self.dimension_relative()) def _morphism(self, *args, **kwds): """ @@ -485,7 +485,7 @@ def _latex_generic_point(self, v=None): def _check_satisfies_equations(self, v): """ Return ``True`` if ``v`` defines a point on the scheme ``self``; raise a - :class:`TypeError` otherwise. + :exc:`TypeError` otherwise. EXAMPLES:: @@ -526,11 +526,9 @@ def __pow__(self, m): INPUT: - - ``m`` -- integer. + - ``m`` -- integer - OUTPUT: - - - affine ambient space. + OUTPUT: affine ambient space EXAMPLES:: @@ -559,9 +557,9 @@ def __mul__(self, right): INPUT: - - ``right`` -- an affine space or subscheme. + - ``right`` -- an affine space or subscheme - OUTPUT: an affine space.= or subscheme. + OUTPUT: an affine space.= or subscheme EXAMPLES:: @@ -621,9 +619,9 @@ def change_ring(self, R): INPUT: - - ``R`` -- commutative ring or morphism. + - ``R`` -- commutative ring or morphism - OUTPUT: An affine space over ``R``. + OUTPUT: an affine space over ``R`` .. NOTE:: @@ -675,18 +673,16 @@ def coordinate_ring(self): def _validate(self, polynomials): """ If ``polynomials`` is a tuple of valid polynomial functions on the affine space, - return ``polynomials``, otherwise raise :class:`TypeError`. + return ``polynomials``, otherwise raise :exc:`TypeError`. Since this is an affine space, all polynomials are valid. INPUT: - ``polynomials`` -- tuple of polynomials in the coordinate ring of - this space. + this space - OUTPUT: - - - tuple of polynomials in the coordinate ring of this space. + OUTPUT: tuple of polynomials in the coordinate ring of this space EXAMPLES:: @@ -703,15 +699,12 @@ def projective_embedding(self, i=None, PP=None): INPUT: + - ``i`` -- integer (default: dimension of self = last coordinate) + determines which projective embedding to compute. The embedding is + that which has a 1 in the `i`-th coordinate, numbered from 0. - - ``i`` -- integer (default: dimension of self = last - coordinate) determines which projective embedding to compute. The - embedding is that which has a 1 in the i-th coordinate, numbered - from 0. - - - ``PP`` -- (default: None) ambient projective space, i.e., - codomain of morphism; this is constructed if it is not - given. + - ``PP`` -- (default: ``None``) ambient projective space, i.e., + codomain of morphism; this is constructed if it is not given. EXAMPLES:: @@ -800,7 +793,7 @@ def subscheme(self, X, **kwds): INPUT: - - ``X`` -- a list or tuple of equations. + - ``X`` -- list or tuple of equations EXAMPLES:: @@ -874,13 +867,13 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): INPUT: - - ``n`` -- a non-negative integer. + - ``n`` -- nonnegative integer - - ``kind`` -- ``first`` or ``second`` specifying which kind of chebyshev the user would like - to generate. Defaults to ``first``. + - ``kind`` -- ``'first'`` (default) or ``'second'`` specifying which + kind of Chebyshev the user would like to generate - - ``monic`` -- ``True`` or ``False`` specifying if the polynomial defining the system - should be monic or not. Defaults to ``False``. + - ``monic`` -- boolean (default: ``False``) specifying if the + polynomial defining the system should be monic or not OUTPUT: :class:`DynamicalSystem_affine` @@ -912,7 +905,7 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): sage: A.chebyshev_polynomial(-4, 'second') Traceback (most recent call last): ... - ValueError: first parameter 'n' must be a non-negative integer + ValueError: first parameter 'n' must be a nonnegative integer :: @@ -942,7 +935,7 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): raise TypeError("affine space must be of dimension 1") n = ZZ(n) if n < 0: - raise ValueError("first parameter 'n' must be a non-negative integer") + raise ValueError("first parameter 'n' must be a nonnegative integer") from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine from sage.functions.orthogonal_polys import chebyshev_T, chebyshev_U @@ -1030,19 +1023,15 @@ def points_of_bounded_height(self, **kwds): slightly larger than the bound may be returned. This can be controlled by lowering the tolerance. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- a real number - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm algorithm-4 - ``precision`` -- the precision to use for computing the elements of bounded height of number fields - OUTPUT: - - - an iterator of points in self + OUTPUT: an iterator of points in self EXAMPLES:: @@ -1108,7 +1097,7 @@ def weil_restriction(self): If the field is a finite field, then this computes the Weil restriction to the prime subfield. - OUTPUT: Affine space of dimension ``d * self.dimension_relative()`` + OUTPUT: affine space of dimension ``d * self.dimension_relative()`` over the base field of ``self.base_ring()``. EXAMPLES:: @@ -1224,7 +1213,6 @@ def translation(self, p, q=None): (x + 3, y + 3, z + 3) sage: psi * phi == A.translation(p, q) True - """ gens = self.gens() diff --git a/src/sage/schemes/affine/affine_subscheme.py b/src/sage/schemes/affine/affine_subscheme.py old mode 100644 new mode 100755 index 6ac0e7508d9..a6b550c6ec8 --- a/src/sage/schemes/affine/affine_subscheme.py +++ b/src/sage/schemes/affine/affine_subscheme.py @@ -20,8 +20,6 @@ # **************************************************************************** from sage.categories.fields import Fields -from sage.interfaces.singular import singular -from sage.modules.free_module_element import vector from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme from .affine_morphism import SchemeMorphism_polynomial_affine_subscheme_field @@ -87,7 +85,6 @@ def _morphism(self, *args, **kwds): Scheme endomorphism of Affine Space of dimension 3 over Integer Ring Defn: Defined on coordinates by sending (x, y, z) to (x, y, z) - """ return self.ambient_space()._morphism(*args, **kwds) @@ -140,13 +137,12 @@ def projective_embedding(self, i=None, PP=None): INPUT: - - ``i`` -- integer (default: dimension of self = last - coordinate) determines which projective embedding to compute. The - embedding is that which has a 1 in the i-th coordinate, numbered - from 0. + - ``i`` -- integer (default: dimension of self = last coordinate); + determines which projective embedding to compute. The embedding is + that which has a 1 in the `i`-th coordinate, numbered from 0. - - ``PP`` -- (default: None) ambient projective space, i.e., ambient space - of codomain of morphism; this is constructed if it is not given. + - ``PP`` -- (default: ``None``) ambient projective space, i.e., ambient + space of codomain of morphism; this is constructed if it is not given EXAMPLES:: @@ -249,12 +245,13 @@ def projective_closure(self, i=None, PP=None): INPUT: - - ``i`` -- (default: None) determines the embedding to use to compute the projective - closure of this affine subscheme. The embedding used is the one which has a 1 in the - i-th coordinate, numbered from 0. + - ``i`` -- (default: ``None``) determines the embedding to use to + compute the projective closure of this affine subscheme. The + embedding used is the one which has a 1 in the i-th coordinate, + numbered from 0. - - ``PP`` -- (default: None) ambient projective space, i.e., ambient space - of codomain of morphism; this is constructed if it is not given + - ``PP`` -- (default: ``None``) ambient projective space, i.e., ambient + space of codomain of morphism; this is constructed if it is not given OUTPUT: a projective subscheme @@ -289,12 +286,12 @@ def is_smooth(self, point=None): INPUT: - - ``point`` -- A point or ``None`` (default). The point to - test smoothness at. + - ``point`` -- a point or ``None`` (default). The point to + test smoothness at OUTPUT: - Boolean. If no point was specified, returns whether the + boolean; if no point was specified, returns whether the algebraic subscheme is smooth everywhere. Otherwise, smoothness at the specified point is tested. @@ -346,11 +343,11 @@ def intersection_multiplicity(self, X, P): INPUT: - - ``X`` -- subscheme in the same ambient space as this subscheme. + - ``X`` -- subscheme in the same ambient space as this subscheme - - ``P`` -- a point in the intersection of this subscheme with ``X``. + - ``P`` -- a point in the intersection of this subscheme with ``X`` - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -414,10 +411,11 @@ def intersection_multiplicity(self, X, P): J = X.defining_ideal() # move P to the origin and localize chng_coords = [AA.gens()[i] + P[i] for i in range(AA.dimension_relative())] - R = AA.coordinate_ring().change_ring(order="negdegrevlex") + R = AA.coordinate_ring().change_ring(order='negdegrevlex') Iloc = R.ideal([f(chng_coords) for f in I.gens()]) Jloc = R.ideal([f(chng_coords) for f in J.gens()]) # compute the intersection multiplicity with Serre's Tor formula using Singular + from sage.interfaces.singular import singular singular.lib("homolog.lib") i = 0 s = 0 @@ -437,11 +435,9 @@ def multiplicity(self, P): INPUT: - - ``P`` -- a point on this subscheme. - - OUTPUT: + - ``P`` -- a point on this subscheme - An integer. + OUTPUT: integer EXAMPLES:: @@ -492,6 +488,8 @@ def multiplicity(self, P): except TypeError: raise TypeError("(=%s) is not a point on (=%s)" % (P, self)) + from sage.interfaces.singular import singular + # Apply a linear change of coordinates to self so that P is sent to the origin # and then compute the multiplicity of the local ring of the translated subscheme # corresponding to the point (0,...,0) @@ -578,6 +576,8 @@ def tangent_space(self, p): sage: _.dimension() 1 """ + from sage.modules.free_module_element import vector + A = self.ambient_space() R = A.coordinate_ring() gens = R.gens() diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py old mode 100644 new mode 100755 index a9299e4e732..cf232a02a71 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -12,10 +12,10 @@ - Type II points are represented by a center and a rational power of `p`. -- Type III points are represented by a center and a non-negative real radius. +- Type III points are represented by a center and a nonnegative real radius. - Type IV points are represented by a finite list of centers and a finite list of - non-negative radii. + nonnegative radii. For an exposition of Berkovich space over `\CC_p`, see Chapter 6 of [Ben2019]_. For a more involved exposition, see Chapter 1 and 2 of [BR2010]_. @@ -33,17 +33,20 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.structure.element import Element -from sage.structure.element import Expression import sage.rings.abc -from sage.rings.real_mpfr import RR, RealNumber -from sage.rings.padics.padic_generic_element import pAdicGenericElement -from sage.rings.padics.padic_base_generic import pAdicBaseGeneric -from sage.schemes.projective.projective_space import ProjectiveSpace -from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field -from sage.rings.rational_field import QQ -from sage.rings.integer_ring import ZZ + +from sage.categories.function_fields import FunctionFields +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import Infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.real_mpfr import RealNumber, RR +from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field +from sage.schemes.projective.projective_space import ProjectiveSpace +from sage.structure.element import Element, Expression + +lazy_import('sage.rings.padics.padic_generic_element', 'pAdicGenericElement') +lazy_import('sage.rings.padics.padic_base_generic', 'pAdicBaseGeneric') class Berkovich_Element(Element): @@ -82,7 +85,6 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= sage: B(4) Type I point centered at 4 + O(5^20) """ - from sage.rings.function_field.element import is_FunctionFieldElement from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.fraction_field_element import FractionFieldElement_1poly_field self._type = None @@ -107,8 +109,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= if not error_check: return - # is_FunctionFieldElement calls .parent - elif hasattr(center, "parent") and hasattr(radius, 'parent'): + elif isinstance(center, Element) and isinstance(radius, Element): from sage.rings.polynomial.multi_polynomial import MPolynomial if isinstance(center, MPolynomial): try: @@ -117,10 +118,10 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= raise TypeError('center was %s, a multivariable polynomial' % center) # check if the radius and the center are functions - center_func_check = is_FunctionFieldElement(center) or isinstance(center, Polynomial) or\ - isinstance(center, FractionFieldElement_1poly_field) or isinstance(center, Expression) - radius_func_check = is_FunctionFieldElement(radius) or isinstance(radius, Polynomial) or\ - isinstance(radius, FractionFieldElement_1poly_field) or isinstance(radius, Expression) + center_func_check = center.parent() in FunctionFields() or \ + isinstance(center, (Polynomial, FractionFieldElement_1poly_field, Expression)) + radius_func_check = radius.parent() in FunctionFields() or \ + isinstance(radius, (Polynomial, FractionFieldElement_1poly_field, Expression)) if center_func_check: # check that both center and radii are supported univariate function @@ -415,7 +416,7 @@ def _custom_abs(self, x): Return the absolute value of ``x`` with respect to the norm on ``Cp``. Used to simplify code, as ``x`` may be a point of a number field - or a p-adic field. + or a `p`-adic field. EXAMPLES:: @@ -446,7 +447,7 @@ def center_function(self): Not defined unless this point is a type IV point created by using a univariate function to compute centers. - OUTPUT: A univariate function. + OUTPUT: a univariate function EXAMPLES:: @@ -474,7 +475,7 @@ def radius_function(self): Not defined unless this point is a type IV point created by using a univariate function to compute radii. - OUTPUT: A univariate function. + OUTPUT: a univariate function EXAMPLES:: @@ -502,7 +503,7 @@ def precision(self): This integer is the number of disks used in the approximation of the type IV point. Not defined for type I, II, or III points. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -526,7 +527,7 @@ def ideal(self): r""" The ideal which defines an embedding of the ``base_ring`` into `\CC_p`. - If this Berkovich space is backed by a p-adic field, then an embedding is + If this Berkovich space is backed by a `p`-adic field, then an embedding is already specified, and this returns ``None``. EXAMPLES:: @@ -539,7 +540,6 @@ def ideal(self): sage: B = Berkovich_Cp_Projective(3) sage: B(0).ideal() - """ return self.parent().ideal() @@ -578,8 +578,8 @@ def radius(self): OUTPUT: - - A non-negative real number for type I, II, or III points. - - A list of non-negative real numbers for type IV points. + - A nonnegative real number for type I, II, or III points. + - A list of nonnegative real numbers for type IV points. EXAMPLES:: @@ -611,10 +611,10 @@ def diameter(self, basepoint=Infinity): INPUT: - - ``basepoint`` -- (default = Infinity) A point of the - same Berkovich space as this point. + - ``basepoint`` -- (default: ``Infinity``) a point of the + same Berkovich space as this point - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -657,7 +657,7 @@ def diameter(self, basepoint=Infinity): if self._radius_func is None: return self._radius_lst[-1] from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(QQ, names="x") + R = PolynomialRing(QQ, names='x') x = R.gens()[0] if isinstance(self._radius_func, Expression): radius_func_variable = self._radius_func.variables()[0] @@ -666,7 +666,7 @@ def diameter(self, basepoint=Infinity): radius_expr = self._radius_func(x) from sage.symbolic.ring import SymbolicRing as SR radius_expr = SR(RR)(radius_expr) - return radius_expr.limit(x="oo") + return radius_expr.limit(x='oo') return self._radius if not isinstance(basepoint, Berkovich_Element_Cp): raise TypeError('basepoint must be a point of Berkovich space, not %s' % basepoint) @@ -687,9 +687,9 @@ def path_distance_metric(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point - OUTPUT: A finite or infinite real number. + OUTPUT: a finite or infinite real number EXAMPLES:: @@ -737,10 +737,10 @@ def Hsia_kernel(self, other, basepoint): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. - - ``basepoint`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point + - ``basepoint`` -- a point of the same Berkovich space as this point - OUTPUT: A finite or infinite real number. + OUTPUT: a finite or infinite real number EXAMPLES:: @@ -759,7 +759,6 @@ def Hsia_kernel(self, other, basepoint): sage: Q3 = B(1/2) sage: Q1.Hsia_kernel(Q2, Q3) +infinity - """ if not isinstance(other, type(self)): raise TypeError('other must be a point of Berkovich space. other was %s' % other) @@ -784,9 +783,9 @@ def small_metric(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -846,10 +845,10 @@ def potential_kernel(self, other, basepoint): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. - - ``basepoint`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point + - ``basepoint`` -- a point of the same Berkovich space as this point - OUTPUT: A finite or infinite real number. + OUTPUT: a finite or infinite real number EXAMPLES:: @@ -889,9 +888,9 @@ def spherical_kernel(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -927,9 +926,9 @@ def Hsia_kernel_infinity(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -958,7 +957,7 @@ def center(self): Return the center of the corresponding disk (or sequence of disks) in `\CC_p`. - OUTPUT: An element of the ``base`` of the parent Berkovich space. + OUTPUT: an element of the ``base`` of the parent Berkovich space EXAMPLES:: @@ -990,7 +989,7 @@ def type_of_point(self): r""" Return the type of this point of Berkovich space over `\CC_p`. - OUTPUT: An integer between 1 and 4 inclusive. + OUTPUT: integer between 1 and 4 inclusive EXAMPLES:: @@ -1009,7 +1008,7 @@ def prime(self): """ The residue characteristic of the parent. - OUTPUT: A prime integer. + OUTPUT: a prime integer EXAMPLES:: @@ -1110,10 +1109,10 @@ class Berkovich_Element_Cp_Affine(Berkovich_Element_Cp): INPUT: - - ``center`` -- For type I, II, and III points, the center of the + - ``center`` -- for type I, II, and III points, the center of the corresponding disk in `\CC_p`. If the parent Berkovich space was created using a number field `K`, then ``center`` must be an element of `K`. Otherwise, ``center`` must be an element of a - p-adic field. For type IV points, can be a list of centers used to approximate the point or a + `p`-adic field. For type IV points, can be a list of centers used to approximate the point or a univariate function that computes the centers (computation starts at 1). - ``radius`` -- (optional) For type I, II, and III points, the radius of the @@ -1122,11 +1121,11 @@ class Berkovich_Element_Cp_Affine(Berkovich_Element_Cp): computes the radii (computation starts at 1). - ``power`` -- (optional) Rational number. Used for constructing type II points; specifies - the power of ``p`` such that `p^\text{power}` = radius. + the power of ``p`` such that `p^\text{power}` = radius - - ``prec`` -- (default: 20) The number of disks to be used to approximate a type IV point. + - ``prec`` -- (default: 20) the number of disks to be used to approximate a type IV point - - ``error_check`` -- (default: ``True``) If error checking should be run on input. If + - ``error_check`` -- boolean (default: ``True``); if error checking should be run on input. If input is correctly formatted, can be set to ``False`` for better performance. WARNING: with error check set to ``False``, any error in the input will lead to incorrect results. @@ -1267,7 +1266,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check raise TypeError('use as_affine_point to convert to affine Berkovich space') Berkovich_Element_Cp.__init__(self, parent=parent, center=center, radius=radius, power=power, - prec=prec, space_type="affine", error_check=error_check) + prec=prec, space_type='affine', error_check=error_check) def as_projective_point(self): r""" @@ -1411,12 +1410,12 @@ def lt(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point OUTPUT: - - ``True`` -- If this point is less than ``other`` in the standard partial order. - - ``False`` -- Otherwise. + - ``True`` -- if this point is less than ``other`` in the standard partial order + - ``False`` -- otherwise EXAMPLES:: @@ -1488,12 +1487,12 @@ def gt(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point OUTPUT: - - ``True`` -- If this point is greater than ``other`` in the standard partial order. - - ``False`` -- Otherwise. + - ``True`` -- if this point is greater than ``other`` in the standard partial order + - ``False`` -- otherwise EXAMPLES:: @@ -1556,11 +1555,11 @@ def join(self, other, basepoint=Infinity): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. - - ``basepoint`` -- (default: Infinity) A point of the same - Berkovich space as this point or Infinity. + - ``other`` -- a point of the same Berkovich space as this point + - ``basepoint`` -- (default: ``Infinity``) a point of the same + Berkovich space as this point or ``Infinity`` - OUTPUT: A point of the same Berkovich space. + OUTPUT: a point of the same Berkovich space EXAMPLES:: @@ -1637,7 +1636,7 @@ def involution_map(self): then the image under the involution map is not defined. To avoid this error, increase precision. - OUTPUT: A point of the same Berkovich space. + OUTPUT: a point of the same Berkovich space EXAMPLES: @@ -1726,8 +1725,8 @@ def contained_in_interval(self, start, end): INPUT: - - ``start`` -- A point of the same Berkovich space as this point. - - ``end`` -- A point of the same Berkovich space as this point. + - ``start`` -- a point of the same Berkovich space as this point + - ``end`` -- a point of the same Berkovich space as this point OUTPUT: @@ -1790,10 +1789,10 @@ class Berkovich_Element_Cp_Projective(Berkovich_Element_Cp): INPUT: - - ``center`` -- For type I, II, and III points, the center of the + - ``center`` -- for type I, II, and III points, the center of the corresponding disk in `P^1(\CC_p)`. If the parent Berkovich space was created using a number field `K`, then ``center`` can be an element of `P^1(K)`. Otherwise, ``center`` - must be an element of a projective space of dimension 1 over a padic field. + must be an element of a projective space of dimension 1 over a `p`-adic field. For type IV points, can be a list of centers used to approximate the point or a univariate function that computes the centers (computation starts at 1). @@ -1805,9 +1804,9 @@ class Berkovich_Element_Cp_Projective(Berkovich_Element_Cp): - ``power`` -- (optional) Rational number. Used for constructing type II points; specifies the power of ``p`` such that `p^\text{power}` = radius - - ``prec`` -- (default: 20) The number of disks to be used to approximate a type IV point + - ``prec`` -- (default: 20) the number of disks to be used to approximate a type IV point - - ``error_check`` -- (default: ``True``) If error checking should be run on input. If + - ``error_check`` -- boolean (default: ``True``); if error checking should be run on input. If input is correctly formatted, can be set to ``False`` for better performance. WARNING: with error check set to ``False``, any error in the input will lead to incorrect results. @@ -1906,13 +1905,13 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check raise TypeError('use as_projective_point to convert to projective Berkovich space') Berkovich_Element_Cp.__init__(self, parent=parent, center=center, radius=radius, power=power, - prec=prec, space_type="projective", error_check=error_check) + prec=prec, space_type='projective', error_check=error_check) def as_affine_point(self): """ Return the corresponding affine point after dehomogenizing at infinity. - OUTPUT: A point of affine Berkovich space. + OUTPUT: a point of affine Berkovich space EXAMPLES:: @@ -2059,12 +2058,12 @@ def lt(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point OUTPUT: - - ``True`` -- If this point is less than ``other`` in the standard partial order. - - ``False`` -- Otherwise. + - ``True`` -- if this point is less than ``other`` in the standard partial order + - ``False`` -- otherwise EXAMPLES:: @@ -2154,12 +2153,12 @@ def gt(self, other): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. + - ``other`` -- a point of the same Berkovich space as this point OUTPUT: - - ``True`` -- If this point is greater than ``other`` in the standard partial order. - - ``False`` -- Otherwise. + - ``True`` -- if this point is greater than ``other`` in the standard partial order + - ``False`` -- otherwise EXAMPLES:: @@ -2239,11 +2238,11 @@ def join(self, other, basepoint=Infinity): INPUT: - - ``other`` -- A point of the same Berkovich space as this point. - - ``basepoint`` -- (default: Infinity) A point of the same - Berkovich space as this point, or infinity. + - ``other`` -- a point of the same Berkovich space as this point + - ``basepoint`` -- (default: ``Infinity``) a point of the same + Berkovich space as this point, or ``Infinity`` - OUTPUT: A point of the same Berkovich space. + OUTPUT: a point of the same Berkovich space EXAMPLES:: @@ -2401,7 +2400,7 @@ def involution_map(self): then the image under the involution map is not defined. To avoid this error, increase precision. - OUTPUT: A point of the same Berkovich space. + OUTPUT: a point of the same Berkovich space EXAMPLES: @@ -2496,8 +2495,8 @@ def contained_in_interval(self, start, end): INPUT: - - ``start`` -- A point of the same Berkovich space as this point. - - ``end`` -- A point of the same Berkovich space as this point. + - ``start`` -- a point of the same Berkovich space as this point + - ``end`` -- a point of the same Berkovich space as this point OUTPUT: diff --git a/src/sage/schemes/berkovich/berkovich_space.py b/src/sage/schemes/berkovich/berkovich_space.py old mode 100644 new mode 100755 index 0692379530f..f5455937b43 --- a/src/sage/schemes/berkovich/berkovich_space.py +++ b/src/sage/schemes/berkovich/berkovich_space.py @@ -31,18 +31,21 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +import sage.rings.abc + +from sage.categories.number_fields import NumberFields +from sage.categories.topological_spaces import TopologicalSpaces +from sage.misc.lazy_import import lazy_import +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.schemes.affine.affine_space import AffineSpace_generic from sage.schemes.berkovich.berkovich_cp_element import (Berkovich_Element_Cp_Affine, Berkovich_Element_Cp_Projective) -from sage.structure.parent import Parent -from sage.schemes.affine.affine_space import AffineSpace_generic from sage.schemes.projective.projective_space import ProjectiveSpace_ring, ProjectiveSpace +from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.categories.number_fields import NumberFields -import sage.rings.abc -from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ -from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal -from sage.categories.topological_spaces import TopologicalSpaces + +lazy_import('sage.rings.number_field.number_field_ideal', 'NumberFieldFractionalIdeal') def is_Berkovich(space) -> bool: @@ -131,11 +134,11 @@ def residue_characteristic(self): def is_padic_base(self): """ - Return ``True`` if this Berkovich space is backed by a p-adic field. + Return ``True`` if this Berkovich space is backed by a `p`-adic field. OUTPUT: - - ``True`` if this Berkovich space was created with a p-adic field. + - ``True`` if this Berkovich space was created with a `p`-adic field. - ``False`` otherwise. EXAMPLES:: @@ -179,7 +182,7 @@ def ideal(self): r""" The ideal which defines an embedding of the ``base_ring`` into `\CC_p`. - If this Berkovich space is backed by a p-adic field, then an embedding is + If this Berkovich space is backed by a `p`-adic field, then an embedding is already specified, and this returns ``None``. OUTPUT: @@ -188,7 +191,7 @@ def ideal(self): - A prime of `\QQ` if ``base_ring`` is `\QQ`. - - ``None`` if ``base_ring`` is a p-adic field. + - ``None`` if ``base_ring`` is a `p`-adic field. EXAMPLES:: @@ -309,14 +312,14 @@ class Berkovich_Cp_Affine(Berkovich_Cp): for all `f \in \CC_p[x]`. We can represent the Berkovich affine line in two separate ways: - either using a p-adic field to represent elements or using + either using a `p`-adic field to represent elements or using a number field to represent elements while storing an ideal of the ring of integers of the number field, which specifies an embedding of the number field into `\CC_p`. See the examples. INPUT: - - ``base`` -- Three cases: + - ``base`` -- three cases: * a prime number `p`. Centers of elements are then represented as points of `\QQ_p`. @@ -364,8 +367,8 @@ class Berkovich_Cp_Affine(Berkovich_Cp): Type I point centered at 2 + O(3) Note that this point has very low precision, as ``B`` was initialized - with a p-adic field of capped-relative precision one. For high precision, - pass in a high precision p-adic field:: + with a `p`-adic field of capped-relative precision one. For high precision, + pass in a high precision `p`-adic field:: sage: B = Berkovich_Cp_Affine(Qp(3, 1000)); B Affine Berkovich line over Cp(3) of precision 1000 @@ -396,7 +399,7 @@ class Berkovich_Cp_Affine(Berkovich_Cp): ring of integers of the number field. Specifying the ideal uniquely specifies an embedding of the number field into `\CC_p`. - Unlike in the case where Berkovich space is backed by a p-adic + Unlike in the case where Berkovich space is backed by a `p`-adic field, any point of a Berkovich space backed by a number field must be centered at a point of that number field:: @@ -518,14 +521,14 @@ class Berkovich_Cp_Projective(Berkovich_Cp): of the Berkovich affine line. We can represent the Berkovich projective line in two separate ways: - either using a p-adic field to represent elements or using + either using a `p`-adic field to represent elements or using a number field to represent elements while storing an ideal of the ring of integers of the number field, which specifies an embedding of the number field into `\CC_p`. See the examples. INPUT: - - ``base`` -- Three cases: + - ``base`` -- three cases: * a prime number `p`. Centers of elements are then represented as points of projective space of dimension 1 over `\QQ_p`. @@ -560,7 +563,7 @@ class Berkovich_Cp_Projective(Berkovich_Cp): For details about element construction, see the documentation of :class:`Berkovich_Element_Cp_Projective`. Initializing a Berkovich projective - line by passing in a p-adic space looks the same:: + line by passing in a `p`-adic space looks the same:: sage: B = Berkovich_Cp_Projective(Qp(3)); B Projective Berkovich line over Cp(3) of precision 20 @@ -597,7 +600,7 @@ class Berkovich_Cp_Projective(Berkovich_Cp): of the number field. Specifying the ideal uniquely specifies an embedding of the number field into `\CC_p`. - Unlike in the case where Berkovich space is backed by a p-adic + Unlike in the case where Berkovich space is backed by a `p`-adic field, any point of a Berkovich space backed by a number field must be centered at a point of that number field:: @@ -680,7 +683,7 @@ def base_ring(self): r""" The base ring of this Berkovich Space. - OUTPUT: A field. + OUTPUT: a field EXAMPLES:: diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py old mode 100644 new mode 100755 index dbdb2dfa4cd..0b647c8411b --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -124,26 +124,21 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -import sage.rings.abc +from builtins import sum as add -from sage.misc.lazy_attribute import lazy_attribute -from sage.misc.cachefunc import cached_method +import sage.rings.abc from sage.arith.misc import binomial -from sage.interfaces.singular import singular -from builtins import sum as add - from sage.categories.fields import Fields from sage.categories.finite_fields import FiniteFields from sage.categories.homset import Hom, End, hom from sage.categories.number_fields import NumberFields - from sage.matrix.constructor import matrix - +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.misc.lazy_import import lazy_import - +from sage.rings.infinity import infinity from sage.rings.polynomial.multi_polynomial_element import degree_lowest_rational_function -from sage.rings.number_field.number_field import NumberField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField from sage.rings.infinity import infinity @@ -152,6 +147,10 @@ from sage.schemes.affine.affine_subscheme import (AlgebraicScheme_subscheme_affine, AlgebraicScheme_subscheme_affine_field) +lazy_import('sage.interfaces.singular', 'singular') +lazy_import('sage.rings.number_field.number_field', 'NumberField') +lazy_import('sage.rings.qqbar', 'number_field_elements_from_algebraics') + from .curve import Curve_generic from .point import (AffineCurvePoint_field, @@ -164,8 +163,6 @@ from .closed_point import IntegralAffineCurveClosedPoint -lazy_import('sage.rings.qqbar', 'number_field_elements_from_algebraics') - class AffineCurve(Curve_generic, AlgebraicScheme_subscheme_affine): """ @@ -232,13 +229,13 @@ def projective_closure(self, i=0, PP=None): INPUT: - - ``i`` -- (default: 0) the index of the affine coordinate chart of the projective space that the affine - ambient space of this curve embeds into. + - ``i`` -- (default: 0) the index of the affine coordinate chart of the + projective space that the affine ambient space of this curve embeds into - - ``PP`` -- (default: None) ambient projective space to compute the projective closure in. This is - constructed if it is not given. + - ``PP`` -- (default: ``None``) ambient projective space to compute the + projective closure in; this is constructed if it is not given - OUTPUT: A curve in projective space. + OUTPUT: a curve in projective space EXAMPLES:: @@ -320,15 +317,15 @@ def divisor_of_function(self, r): """ Return the divisor of a function on a curve. - INPUT: r is a rational function on X - - OUTPUT: + INPUT: + - ``r`` -- a rational function on X - - ``list`` -- The divisor of r represented as a list of - coefficients and points. (TODO: This will change to a more - structural output in the future.) + OUTPUT: + - ``list`` -- the divisor of r represented as a list of coefficients + and points. (TODO: This will change to a more structural output in + the future.) EXAMPLES:: @@ -375,12 +372,10 @@ def local_coordinates(self, pt, n): INPUT: + - ``pt`` -- an F-rational point on X which is not a + point of ramification for the projection (x,y) - x - - ``pt`` -- an F-rational point on X which is not a - point of ramification for the projection (x,y) - x. - - - ``n`` -- the number of terms desired - + - ``n`` -- the number of terms desired OUTPUT: x = x0 + t y = y0 + power series in t @@ -445,11 +440,10 @@ def plot(self, *args, **kwds): INPUT: - - ``*args`` -- optional tuples (variable, minimum, maximum) for - plotting dimensions + - ``*args`` -- (optional) tuples (variable, minimum, maximum) for + plotting dimensions - - ``**kwds`` -- optional keyword arguments passed on to - ``implicit_plot`` + - ``**kwds`` -- optional keyword arguments passed on to ``implicit_plot`` EXAMPLES: @@ -490,11 +484,11 @@ def is_transverse(self, C, P): INPUT: - - ``C`` -- a curve in the ambient space of this curve. + - ``C`` -- a curve in the ambient space of this curve - - ``P`` -- a point in the intersection of both curves. + - ``P`` -- a point in the intersection of both curves - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -548,9 +542,9 @@ def multiplicity(self, P): INPUT: - - ``P`` -- a point in the ambient space of this curve. + - ``P`` -- a point in the ambient space of this curve - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -585,7 +579,7 @@ def multiplicity(self, P): TypeError: (=(1, 1)) is not a point on (=Affine Plane Curve over Rational Field defined by x^6 - x^3 + y^3) """ - if not self.base_ring() in Fields(): + if self.base_ring() not in Fields(): raise TypeError("curve must be defined over a field") # Check whether P is a point on this curve @@ -612,12 +606,12 @@ def tangents(self, P, factor=True): - ``P`` -- a point on this curve - - ``factor`` -- (default: ``True``) whether to attempt computing the + - ``factor`` -- boolean (default: ``True``); whether to attempt computing the polynomials of the individual tangent lines over the base field of this curve, or to just return the polynomial corresponding to the union of the tangent lines (which requires fewer computations) - OUTPUT: A list of polynomials in the coordinate ring of the ambient space. + OUTPUT: list of polynomials in the coordinate ring of the ambient space EXAMPLES:: @@ -781,9 +775,8 @@ def rational_parameterization(self): The rational parameterization may have coefficients in a quadratic extension of the rational field. - OUTPUT: - - - a birational map between `\mathbb{A}^{1}` and this curve, given as a scheme morphism. + OUTPUT: a birational map between `\mathbb{A}^{1}` and this curve, given + as a scheme morphism EXAMPLES:: @@ -859,13 +852,24 @@ def __init__(self, A, X): sage: A. = AffineSpace(GF(7), 3) sage: C = Curve([x^2 - z, z - 8*x], A); C Affine Curve over Finite Field of size 7 defined by x^2 - z, -x + z + + TESTS:: + + sage: K. = QQ[] + sage: t1 = x^2*z^2 + y*t + sage: t2 = y*z^2 + x^2*t + sage: C = Curve([x^4 - y^2 - 19, z^4 - t^2 - 23, t1^2 - t2^2 - 19*23]) + Traceback (most recent call last): + ... + ValueError: defining equations (=[x^4 - y^2 - 19, z^4 - t^2 - 23, + x^4*z^4 - y^2*z^4 - x^4*t^2 + y^2*t^2 - 437]) define a scheme of dimension 2 != 1 """ super().__init__(A, X) - if not A.base_ring() in Fields(): + if A.base_ring() not in Fields(): raise TypeError("curve not defined over a field") - d = self.dimension() + d = super(Curve_generic, self).dimension() if d != 1: raise ValueError("defining equations (={}) define a scheme of dimension {} != 1".format(X, d)) @@ -876,7 +880,7 @@ def projection(self, indices, AS=None): INPUT: - - ``indices`` -- a list or tuple of distinct integers specifying the + - ``indices`` -- list or tuple of distinct integers specifying the indices of the coordinates to use in the projection. Can also be a list or tuple consisting of variables of the coordinate ring of the ambient space of this curve. If integers are used to specify the coordinates, 0 @@ -884,12 +888,12 @@ def projection(self, indices, AS=None): two and one less than the dimension of the ambient space of this curve, inclusive. - - ``AS`` -- (default: None) the affine space the projected curve will + - ``AS`` -- (default: ``None``) the affine space the projected curve will be defined in. This space must be defined over the same base field as this curve, and must have dimension equal to the length of ``indices``. This space is constructed if not specified. - OUTPUT: A tuple of + OUTPUT: a tuple of - a scheme morphism from this curve to affine space of dimension equal to the number of coordinates specified in ``indices`` @@ -927,7 +931,10 @@ def projection(self, indices, AS=None): To: Affine Space of dimension 3 over Rational Field Defn: Defined on coordinates by sending (x, y, z, w) to (x, y, z), - Affine Curve over Rational Field defined by c - 1, b - 3, a - 2) + Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: + c - 1, + b - 3, + a - 2) :: @@ -1045,12 +1052,12 @@ def plane_projection(self, AP=None): INPUT: - - ``AP`` -- (default: None) the affine plane to project this curve + - ``AP`` -- (default: ``None``) the affine plane to project this curve into. This space must be defined over the same base field as this curve, and must have dimension two. This space will be constructed if not specified. - OUTPUT: A tuple of + OUTPUT: a tuple of - a scheme morphism from this curve into an affine plane @@ -1112,21 +1119,21 @@ def blowup(self, P=None): INPUT: - - ``P`` -- (default: None) a point on this curve at which to blow up; - if ``None``, then ``P`` is taken to be the origin. + - ``P`` -- (default: ``None``) a point on this curve at which to blow up; + if ``None``, then ``P`` is taken to be the origin - OUTPUT: A tuple of + OUTPUT: a tuple of - a tuple of curves in affine space of the same dimension as the ambient space of this curve, which define the blow up in each affine chart. - - a tuple of tuples such that the jth element of the ith tuple is the - transition map from the ith affine patch to the jth affine patch. + - a tuple of tuples such that the j-th element of the i-th tuple is the + transition map from the i-th affine patch to the j-th affine patch. - a tuple consisting of the restrictions of the projection map from the blow up back to the original curve, restricted to each affine patch. - There the ith element will be the projection from the ith affine patch. + There the i-th element will be the projection from the i-th affine patch. EXAMPLES:: @@ -1313,7 +1320,7 @@ def blowup(self, P=None): self(P) except TypeError: raise TypeError("(=%s) must be a point on this curve" % P) - if not self.base_ring() in Fields(): + if self.base_ring() not in Fields(): raise TypeError("the base ring of this curve must be a field") if not self.is_irreducible(): raise TypeError("this curve must be irreducible") @@ -1419,26 +1426,26 @@ def resolution_of_singularities(self, extend=False): INPUT: - - ``extend`` -- (default: ``False``) specifies whether to extend the base - field when necessary to find all singular points when this curve is - defined over a number field. If ``extend`` is ``False``, then only - singularities with coordinates in the base field of this curve will be - resolved. However, setting ``extend`` to ``True`` will slow down - computations. + - ``extend`` -- boolean (default: ``False``); specifies whether to + extend the base field when necessary to find all singular points when + this curve is defined over a number field. If ``extend`` is + ``False``, then only singularities with coordinates in the base field + of this curve will be resolved. However, setting ``extend`` to + ``True`` will slow down computations. - OUTPUT: A tuple of + OUTPUT: a tuple of - a tuple of curves in affine space of the same dimension as the ambient space of this curve, which represent affine patches of the resolution of singularities. - - a tuple of tuples such that the jth element of the ith tuple is the - transition map from the ith patch to the jth patch. + - a tuple of tuples such that the j-th element of the i-th tuple is the + transition map from the i-th patch to the j-th patch. - a tuple consisting of birational maps from the patches back to the original curve that were created by composing the projection maps - generated from the blow up computations. There the ith element will be - a map from the ith patch. + generated from the blow up computations. There the i-th element will + be a map from the i-th patch. EXAMPLES:: @@ -1804,11 +1811,11 @@ def fundamental_group(self, simplified=True, puiseux=True): INPUT: - - ``simplified`` -- (default: ``True``) boolean to simplify the presentation. + - ``simplified`` -- boolean (default: ``True``); to simplify the presentation - - ``puiseux`` -- (default: ``True``) boolean to decide if the + - ``puiseux`` -- boolean (default: ``True``); to decide if the presentation is constructed in the classical way or using Puiseux - shortcut. + shortcut OUTPUT: @@ -1912,7 +1919,6 @@ def braid_monodromy(self): Traceback (most recent call last): ... NotImplementedError: the base field must have an embedding to the algebraic field - """ from sage.schemes.curves.zariski_vankampen import braid_monodromy F = self.base_ring() @@ -1925,9 +1931,9 @@ def braid_monodromy(self): def riemann_surface(self, **kwargs): r""" - Return the complex Riemann surface determined by this curve + Return the complex Riemann surface determined by this curve. - OUTPUT: A :class:`~sage.schemes.riemann_surfaces.riemann_surface.RiemannSurface` object. + OUTPUT: a :class:`~sage.schemes.riemann_surfaces.riemann_surface.RiemannSurface` object EXAMPLES:: @@ -1968,7 +1974,7 @@ def riemann_roch_basis(self, D): divisor `Div = d_1P_1 + \dots + d_nP_n`, where `X(F) = \{P_1, \dots, P_n\}`. The ordering is that dictated by ``places_on_curve``. - OUTPUT: A basis of `L(Div)`. + OUTPUT: a basis of `L(Div)`. EXAMPLES:: @@ -2000,13 +2006,13 @@ def riemann_roch_basis(self, D): return [g[1].sage() / g[2].sage() for g in G.BrillNoether(P)] - def rational_points(self, algorithm="enum"): + def rational_points(self, algorithm='enum'): r""" Return sorted list of all rational points on this curve. INPUT: - - ``algorithm`` -- possible choices: + - ``algorithm`` -- possible choices: + ``'enum'`` -- use *very* naive point enumeration to find all rational points on this curve over a finite field. @@ -2019,7 +2025,7 @@ def rational_points(self, algorithm="enum"): .. NOTE:: The Brill-Noether package does not always work. When it fails, a - RuntimeError exception is raised. + :exc:`RuntimeError` exception is raised. EXAMPLES:: @@ -2087,8 +2093,8 @@ def rational_points(self, algorithm="enum"): return sorted(set(pnts)) elif algorithm == "all": - S_enum = self.rational_points(algorithm="enum") - S_bn = self.rational_points(algorithm="bn") + S_enum = self.rational_points(algorithm='enum') + S_bn = self.rational_points(algorithm='bn') if S_enum != S_bn: raise RuntimeError("Bug in rational_points -- different algorithms give different answers for curve %s!" % self) return S_enum @@ -2200,7 +2206,7 @@ def function(self, f): - ``f`` -- an element of the fraction field of the coordinate ring of the ambient space or the coordinate ring of the curve - OUTPUT: An element of the function field of this curve. + OUTPUT: an element of the function field of this curve EXAMPLES:: @@ -2248,7 +2254,7 @@ def pull_from_function_field(self, f): INPUT: - - ``f`` -- an element of the function field + - ``f`` -- an element of the function field OUTPUT: @@ -2689,7 +2695,7 @@ def places_on(self, point): - ``point`` -- a closed point of the curve - OUTPUT: A list of the places of the function field of the curve. + OUTPUT: list of the places of the function field of the curve EXAMPLES:: @@ -2862,7 +2868,7 @@ def closed_points(self, degree=1): INPUT: - - ``degree`` -- a positive integer + - ``degree`` -- positive integer EXAMPLES:: diff --git a/src/sage/schemes/curves/closed_point.py b/src/sage/schemes/curves/closed_point.py old mode 100644 new mode 100755 index 50cd46605bc..384487a4fd0 --- a/src/sage/schemes/curves/closed_point.py +++ b/src/sage/schemes/curves/closed_point.py @@ -90,7 +90,7 @@ class IntegralCurveClosedPoint(CurveClosedPoint): INPUT: - - ``curve`` -- the curve to which the closed point belongs + - ``curve`` -- the curve to which the closed point belongs - ``prime_ideal`` -- a prime ideal @@ -310,7 +310,7 @@ def projective(self, i=0): INPUT: - - ``i`` -- an integer + - ``i`` -- integer EXAMPLES:: @@ -391,7 +391,7 @@ def affine(self, i=None): INPUT: - - ``i`` -- an integer; if not specified, it is chosen automatically. + - ``i`` -- integer; if not specified, it is chosen automatically EXAMPLES:: diff --git a/src/sage/schemes/curves/constructor.py b/src/sage/schemes/curves/constructor.py old mode 100644 new mode 100755 index 687a238fcfa..beff4dd649d --- a/src/sage/schemes/curves/constructor.py +++ b/src/sage/schemes/curves/constructor.py @@ -39,7 +39,7 @@ from sage.categories.number_fields import NumberFields from sage.rings.polynomial.multi_polynomial import MPolynomial -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.rational_field import QQ @@ -107,7 +107,7 @@ def Curve(F, A=None): - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme - - ``A`` -- (default: None) an ambient space in which to create the curve + - ``A`` -- (default: ``None``) an ambient space in which to create the curve EXAMPLES: @@ -240,7 +240,7 @@ def Curve(F, A=None): if isinstance(F, (list, tuple)): P = Sequence(F).universe() - if not is_MPolynomialRing(P): + if not isinstance(P, MPolynomialRing_base): raise TypeError("universe of F must be a multivariate polynomial ring") for f in F: if not f.is_homogeneous(): diff --git a/src/sage/schemes/curves/curve.py b/src/sage/schemes/curves/curve.py old mode 100644 new mode 100755 index 1ae4b4144b3..be072ba3873 --- a/src/sage/schemes/curves/curve.py +++ b/src/sage/schemes/curves/curve.py @@ -153,8 +153,8 @@ def divisor_group(self, base_ring=None): INPUT: - - ``base_ring`` -- the base ring of the divisor group. Usually, this is - `\ZZ` (default) or `\QQ`. + - ``base_ring`` -- the base ring of the divisor group; usually, this is + `\ZZ` (default) or `\QQ` OUTPUT: the divisor group of the curve @@ -275,9 +275,7 @@ def singular_subscheme(self): r""" Return the subscheme of singular points of this curve. - OUTPUT: - - - a subscheme in the ambient space of this curve. + OUTPUT: a subscheme in the ambient space of this curve EXAMPLES:: @@ -315,10 +313,10 @@ def singular_points(self, F=None): INPUT: - - ``F`` -- (default: None) field over which to find the singular + - ``F`` -- (default: ``None``) field over which to find the singular points; if not given, the base ring of this curve is used - OUTPUT: a list of points in the ambient space of this curve + OUTPUT: list of points in the ambient space of this curve EXAMPLES:: @@ -362,13 +360,13 @@ def is_singular(self, P=None): INPUT: - - ``P`` -- (default: None) a point on this curve + - ``P`` -- (default: ``None``) a point on this curve OUTPUT: - A boolean. If a point ``P`` is provided, and if ``P`` lies on this - curve, returns True if ``P`` is a singular point of this curve, and - False otherwise. If no point is provided, returns True or False + boolean; if a point ``P`` is provided, and if ``P`` lies on this + curve, returns ``True`` if ``P`` is a singular point of this curve, and + ``False`` otherwise. If no point is provided, returns ``True`` or False depending on whether this curve is or is not singular, respectively. EXAMPLES:: @@ -395,9 +393,9 @@ def intersects_at(self, C, P): INPUT: - - ``C`` -- a curve in the same ambient space as this curve. + - ``C`` -- a curve in the same ambient space as this curve - - ``P`` -- a point in the ambient space of this curve. + - ``P`` -- a point in the ambient space of this curve EXAMPLES:: @@ -450,11 +448,11 @@ def intersection_points(self, C, F=None): - ``C`` -- a curve in the same ambient space as this curve - - ``F`` -- (default: None); field over which to compute the + - ``F`` -- (default: ``None``) field over which to compute the intersection points; if not specified, the base ring of this curve is used - OUTPUT: a list of points in the ambient space of this curve + OUTPUT: list of points in the ambient space of this curve EXAMPLES:: diff --git a/src/sage/schemes/curves/plane_curve_arrangement.py b/src/sage/schemes/curves/plane_curve_arrangement.py old mode 100644 new mode 100755 index e82ec07328d..63e8d03f556 --- a/src/sage/schemes/curves/plane_curve_arrangement.py +++ b/src/sage/schemes/curves/plane_curve_arrangement.py @@ -79,7 +79,7 @@ def __init__(self, parent, curves, check=True): - ``parent`` -- the parent :class:`PlaneCurveArrangements` - - ``curves`` -- a tuple of curves + - ``curves`` -- tuple of curves EXAMPLES:: @@ -111,10 +111,6 @@ def __getitem__(self, i): - ``i`` -- integer - OUTPUT: - - The `i`-th curve. - EXAMPLES:: sage: H. = AffinePlaneCurveArrangements(QQ) @@ -138,9 +134,7 @@ def ncurves(self): r""" Return the number of curves in the arrangement. - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -159,9 +153,7 @@ def curves(self): r""" Return the curves in the arrangement as a tuple. - OUTPUT: - - A tuple. + OUTPUT: a tuple EXAMPLES:: @@ -182,9 +174,7 @@ def _repr_(self): r""" String representation for a curve arrangement. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -237,9 +227,7 @@ def union(self, other): - ``other`` -- a curve arrangement or something that can be converted into a curve arrangement - OUTPUT: - - A new curve arrangement. + OUTPUT: a new curve arrangement EXAMPLES:: @@ -334,9 +322,7 @@ def coordinate_ring(self): """ Return the coordinate ring of ``self``. - OUTPUT: - - The coordinate ring of the curve arrangement. + OUTPUT: the coordinate ring of the curve arrangement EXAMPLES:: @@ -450,7 +436,7 @@ def __init__(self, parent, curves, check=True): - ``parent`` -- the parent :class:`AffinePlaneCurveArrangements` - - ``curves`` -- a tuple of curves + - ``curves`` -- tuple of curves EXAMPLES:: @@ -499,9 +485,7 @@ def fundamental_group(self, simplified=True, vertical=True, - ``projective`` -- boolean (default: ``False``); to be used in the method for projective curves - OUTPUT: - - A finitely presented group. + OUTPUT: a finitely presented group .. NOTE:: @@ -799,7 +783,7 @@ def __init__(self, parent, curves, check=True): - ``parent`` -- the parent :class:`ProjectivePlaneCurveArrangements` - - ``curves`` -- a tuple of curves + - ``curves`` -- tuple of curves EXAMPLES:: @@ -832,9 +816,7 @@ def fundamental_group(self, simplified=True): - ``simplified`` -- boolean (default: ``True``); set if the group is simplified - OUTPUT: - - A finitely presented group. + OUTPUT: a finitely presented group .. NOTE:: @@ -1045,9 +1027,7 @@ def coordinate_ring(self): """ Return the coordinate ring. - OUTPUT: - - The coordinate ring of the curve arrangement. + OUTPUT: the coordinate ring of the curve arrangement EXAMPLES:: @@ -1063,7 +1043,7 @@ def change_ring(self, base_ring): INPUT: - - ``base_ring`` -- a ring; the new base ring. + - ``base_ring`` -- a ring; the new base ring OUTPUT: @@ -1106,9 +1086,7 @@ def _repr_(self): """ Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1180,11 +1158,9 @@ def _an_element_(self): @cached_method def ngens(self): """ - Return the number of variables, i.e. 2 or 3, kept for completness. + Return the number of variables, i.e. 2 or 3, kept for completeness. - OUTPUT: - - An integer, 2 or 3, depending if the arrangement is projective or affine. + OUTPUT: integer, 2 or 3, depending if the arrangement is projective or affine EXAMPLES:: @@ -1201,9 +1177,7 @@ def gens(self): """ Return the coordinates. - OUTPUT: - - A tuple of linear expressions, one for each linear variable. + OUTPUT: a tuple of linear expressions, one for each linear variable EXAMPLES:: @@ -1224,9 +1198,7 @@ def gen(self, i): - ``i`` -- integer - OUTPUT: - - A variable. + OUTPUT: a variable EXAMPLES:: diff --git a/src/sage/schemes/curves/point.py b/src/sage/schemes/curves/point.py old mode 100644 new mode 100755 index 5fd9e684876..e74e009b1ce --- a/src/sage/schemes/curves/point.py +++ b/src/sage/schemes/curves/point.py @@ -296,8 +296,8 @@ def tangents(self): r""" Return the tangents at this point of the affine plane curve this point is on. - OUTPUT: a list of polynomials in the coordinate ring of the ambient - space of the curve this point is on. + OUTPUT: list of polynomials in the coordinate ring of the ambient + space of the curve this point is on EXAMPLES:: @@ -343,7 +343,7 @@ def is_transverse(self, D): INPUT: - - ``D`` -- a curve in the same ambient space as the curve this point is on. + - ``D`` -- a curve in the same ambient space as the curve this point is on EXAMPLES:: diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py old mode 100644 new mode 100755 index 6045cc3ea70..77c94b61c04 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -136,32 +136,31 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.misc.lazy_attribute import lazy_attribute -from sage.misc.cachefunc import cached_method +from builtins import sum as add from sage.categories.fields import Fields from sage.categories.homset import hom, Hom, End from sage.categories.number_fields import NumberFields - -from sage.interfaces.singular import singular +from sage.libs.singular.function import singular_function, lib as singular_lib, get_printlevel, set_printlevel from sage.matrix.constructor import matrix -from builtins import sum as add +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.lazy_import import lazy_import +from sage.misc.persist import register_unpickle_override from sage.misc.sage_eval import sage_eval - -from sage.rings.polynomial.multi_polynomial_element import degree_lowest_rational_function +from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing -from sage.rings.number_field.number_field import NumberField +from sage.rings.polynomial.multi_polynomial_element import degree_lowest_rational_function from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.qqbar import (number_field_elements_from_algebraics, - QQbar) from sage.rings.rational_field import RationalField -from sage.rings.integer import Integer - from sage.schemes.projective.projective_space import ProjectiveSpace, ProjectiveSpace_ring - from sage.schemes.projective.projective_subscheme import (AlgebraicScheme_subscheme_projective, AlgebraicScheme_subscheme_projective_field) +lazy_import('sage.interfaces.singular', 'singular') +lazy_import('sage.rings.number_field.number_field', 'NumberField') +lazy_import('sage.rings.qqbar', ['number_field_elements_from_algebraics', 'QQbar']) + from .curve import Curve_generic from .point import (ProjectiveCurvePoint_field, @@ -173,7 +172,6 @@ IntegralProjectivePlaneCurvePoint_finite_field) from .closed_point import IntegralProjectiveCurveClosedPoint -from sage.misc.persist import register_unpickle_override class ProjectiveCurve(Curve_generic, AlgebraicScheme_subscheme_projective): @@ -241,10 +239,10 @@ def affine_patch(self, i, AA=None): - ``i`` -- affine coordinate chart of the projective ambient space of this curve to compute affine patch with respect to - - ``AA`` -- (default: None) ambient affine space, this is constructed + - ``AA`` -- (default: ``None``) ambient affine space, this is constructed if it is not given - OUTPUT: A curve in affine space. + OUTPUT: a curve in affine space EXAMPLES:: @@ -283,16 +281,16 @@ def projection(self, P=None, PS=None): INPUT: - - ``P`` -- (default: None) a point not on this curve that will be used - to define the projection map; this is constructed if not specified. + - ``P`` -- (default: ``None``) a point not on this curve that will be used + to define the projection map; this is constructed if not specified - - ``PS`` -- (default: None) the projective space the projected curve + - ``PS`` -- (default: ``None``) the projective space the projected curve will be defined in. This space must be defined over the same base ring as this curve, and must have dimension one less than that of the ambient space of this curve. This space will be constructed if not specified. - OUTPUT: A tuple of + OUTPUT: a tuple of - a scheme morphism from this curve into a projective space of dimension one less than that of the ambient space of this curve @@ -502,12 +500,12 @@ def plane_projection(self, PP=None): INPUT: - - ``PP`` -- (default: None) the projective plane the projected curve + - ``PP`` -- (default: ``None``) the projective plane the projected curve will be defined in. This space must be defined over the same base field as this curve, and must have dimension two. This space is constructed if not specified. - OUTPUT: A tuple of + OUTPUT: a tuple of - a scheme morphism from this curve into a projective plane @@ -642,10 +640,12 @@ def divisor_of_function(self, r): """ Return the divisor of a function on a curve. - INPUT: ``r`` is a rational function on X + INPUT: + + - ``r`` is a rational function on X - OUTPUT: A list. The divisor of r represented as a list of coefficients and - points. (TODO: This will change to a more structural output in the + OUTPUT: list; the divisor of r represented as a list of coefficients + and points. (TODO: This will change to a more structural output in the future.) EXAMPLES:: @@ -688,7 +688,7 @@ def local_coordinates(self, pt, n): INPUT: - ``pt`` -- a rational point on X which is not a point of ramification - for the projection `(x,y) \to x`. + for the projection `(x,y) \to x` - ``n`` -- the number of terms desired @@ -757,17 +757,16 @@ def plot(self, *args, **kwds): INPUT: - - ``self`` -- an affine plane curve + - ``self`` -- an affine plane curve - - ``patch`` -- (optional) the affine patch to be plotted; if not - specified, the patch corresponding to the last projective - coordinate being nonzero + - ``patch`` -- (optional) the affine patch to be plotted; if not + specified, the patch corresponding to the last projective + coordinate being nonzero - - ``*args`` -- optional tuples (variable, minimum, maximum) for - plotting dimensions + - ``*args`` -- (optional) tuples (variable, minimum, maximum) for + plotting dimensions - - ``**kwds`` -- optional keyword arguments passed on to - ``implicit_plot`` + - ``**kwds`` -- optional keyword arguments passed on to ``implicit_plot`` EXAMPLES: @@ -905,7 +904,7 @@ def degree(self): For a plane curve, this is just the degree of its defining polynomial. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -925,12 +924,12 @@ def tangents(self, P, factor=True): INPUT: - - ``P`` -- a point on this curve. + - ``P`` -- a point on this curve - - ``factor`` -- (default: ``True``) whether to attempt computing the + - ``factor`` -- boolean (default: ``True``); whether to attempt computing the polynomials of the individual tangent lines over the base field of this curve, or to just return the polynomial corresponding to the union of - the tangent lines (which requires fewer computations). + the tangent lines (which requires fewer computations) OUTPUT: @@ -1003,12 +1002,13 @@ def is_ordinary_singularity(self, P): INPUT: - - ``P`` -- a point on this curve. + - ``P`` -- a point on this curve OUTPUT: - - Boolean. True or False depending on whether ``P`` is or is not an ordinary singularity of this - curve, respectively. An error is raised if ``P`` is not a singular point of this curve. + boolean; ``True`` or ``False`` depending on whether ``P`` is or is not + an ordinary singularity of this curve, respectively. An error is raised + if ``P`` is not a singular point of this curve. EXAMPLES:: @@ -1103,10 +1103,9 @@ def quadratic_transform(self): degs = [G.degree()]*len(L) for F in G.monomials(): for i in range(len(L)): - if F.degree(L[i]) < degs[i]: - degs[i] = F.degree(L[i]) + degs[i] = min(F.degree(L[i]), degs[i]) T = [] - for item in G.dict().items(): + for item in G.monomial_coefficients().items(): tup = tuple([item[0][i] - degs[i] for i in range(len(L))]) T.append((tup, item[1])) G = R(dict(T)) @@ -1127,12 +1126,12 @@ def excellent_position(self, Q): INPUT: - - ``Q`` -- a point on this curve. + - ``Q`` -- a point on this curve OUTPUT: - - a scheme morphism from this curve to a curve in excellent position that is a restriction of a change - of coordinates map of the projective plane. + A scheme morphism from this curve to a curve in excellent position that + is a restriction of a change of coordinates map of the projective plane. EXAMPLES:: @@ -1281,11 +1280,11 @@ def excellent_position(self, Q): if j == 0: div_pow = min(e[1] for e in npoly.exponents()) npoly = PP.coordinate_ring()({(v0, v1 - div_pow, v2): g - for (v0, v1, v2), g in npoly.dict().items()}) + for (v0, v1, v2), g in npoly.monomial_coefficients().items()}) else: div_pow = min(e[0] for e in npoly.exponents()) npoly = PP.coordinate_ring()({(v0 - div_pow, v1, v2): g - for (v0, v1, v2), g in npoly.dict().items()}) + for (v0, v1, v2), g in npoly.monomial_coefficients().items()}) # check the degree again if npoly.degree() != d - r: need_continue = True @@ -1467,7 +1466,7 @@ def extension(self): # make sure the defining polynomial variable names are the same for K, N N = NumberField(K.defining_polynomial().parent()(F.defining_polynomial()), str(K.gen())) return N.composite_fields(K, both_maps=True)[0][1]*F.embeddings(N)[0] - if not self.base_ring() in NumberFields(): + if self.base_ring() not in NumberFields(): raise NotImplementedError("the base ring of this curve must be a number field") if not self.is_irreducible(): raise TypeError("this curve must be irreducible") @@ -1500,7 +1499,7 @@ def extension(self): try: temp_pt = (temp_qua*temp_exc)(temp_exc.domain()(pts[i])) pts.pop(i) - if not PP(list(temp_pt)) in [PP(list(tpt)) for tpt in pts]: + if PP(list(temp_pt)) not in [PP(list(tpt)) for tpt in pts]: pts.append(temp_pt) except (TypeError, ValueError): pass @@ -1520,7 +1519,7 @@ def extension(self): newpts = [PP(list(pt) + [0]) for pt in X.rational_points()] # avoid duplicates for pt in newpts: - if not PP(list(pt)) in [PP(list(tpt)) for tpt in pts]: + if PP(list(pt)) not in [PP(list(tpt)) for tpt in pts]: pts.append(pt) return phi @@ -1533,11 +1532,11 @@ def is_transverse(self, C, P): INPUT: - - ``C`` -- a curve in the ambient space of this curve. + - ``C`` -- a curve in the ambient space of this curve - - ``P`` -- a point in the intersection of both curves. + - ``P`` -- a point in the intersection of both curves - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1593,12 +1592,25 @@ def __init__(self, A, X, category=None): sage: C = Curve(x*y^2*z^7 - x^10 - x^2*z^8) sage: loads(dumps(C)) == C True + + TESTS:: + + sage: P. = ProjectiveSpace(QQ, 4) + sage: C = Curve([x0^4 - x1^2*x4^2 - 19*x4^4, x2^4 - x3^2*x4^2 - 23*x4^4]) + Traceback (most recent call last): + ... + ValueError: defining equations (=[x0^4 - x1^2*x4^2 - 19*x4^4, x2^4 - x3^2*x4^2 - 23*x4^4]) + define a scheme of dimension 2 != 1 """ super().__init__(A, X, category=category) - if not A.base_ring() in Fields(): + if A.base_ring() not in Fields(): raise TypeError("curve not defined over a field") + d = super(Curve_generic, self).dimension() + if d != 1: + raise ValueError(f"defining equations (={X}) define a scheme of dimension {d} != 1") + @lazy_attribute def _genus(self): """ @@ -1663,10 +1675,18 @@ def is_complete_intersection(self): sage: C.is_complete_intersection() False """ - singular.lib("sing.lib") - id = singular.simplify(self.defining_ideal(), 10) - L = singular.is_ci(id).sage() - return len(self.ambient_space().gens()) - len(id.sage().gens()) == L[-1] + singular_lib("sing.lib") + simplify = singular_function("simplify") + is_ci = singular_function("is_ci") + + # verbose unless printlevel is -1. + saved_printlevel = get_printlevel() + set_printlevel(-1) + id = simplify(self.defining_ideal(), 10) + L = is_ci(id)[-1] + set_printlevel(saved_printlevel) + + return len(self.ambient_space().gens()) - len(id) == L def tangent_line(self, p): """ @@ -1684,7 +1704,6 @@ def tangent_line(self, p): sage: C.tangent_line(p) Projective Curve over Rational Field defined by -2*x + y + w, -3*x + z + 2*w - """ for i in range(len(p)): if p[i]: @@ -1819,9 +1838,7 @@ def rational_parameterization(self): The rational parameterization may have coefficients in a quadratic extension of the rational field. - OUTPUT: - - - a birational map between `\mathbb{P}^{1}` and this curve, given as a scheme morphism. + OUTPUT: a birational map between `\mathbb{P}^{1}` and this curve, given as a scheme morphism EXAMPLES:: @@ -1864,20 +1881,22 @@ def rational_parameterization(self): raise TypeError("this curve must have geometric genus zero") if not isinstance(self.base_ring(), RationalField): raise TypeError("this curve must be defined over the rational field") + singular.lib("paraplanecurves.lib") - R = singular.paraPlaneCurve(self.defining_polynomial()) - singular.setring(R) - param = singular('PARA').sage().gens() + R = singular.paraPlaneCurve(self.defining_polynomial()) # ring + R.set_ring() + param = singular('PARA').sage().gens() # ideal R = R.sage() + C = self.change_ring(R.base_ring()) H = Hom(ProjectiveSpace(R.base_ring(), 1, R.gens()), C) return H(param) def riemann_surface(self, **kwargs): r""" - Return the complex Riemann surface determined by this curve + Return the complex Riemann surface determined by this curve. - OUTPUT: A :class:`~sage.schemes.riemann_surfaces.riemann_surface.RiemannSurface` object. + OUTPUT: a :class:`~sage.schemes.riemann_surfaces.riemann_surface.RiemannSurface` object EXAMPLES:: @@ -1886,7 +1905,6 @@ def riemann_surface(self, **kwargs): sage: C.riemann_surface() Riemann surface defined by polynomial f = x^3 + 3*y^3 + 5 = 0, with 53 bits of precision - """ return self.affine_patch(2).riemann_surface(**kwargs) @@ -1905,9 +1923,7 @@ def rational_points_iterator(self): - ``self`` -- a projective curve - OUTPUT: - - A generator of all the rational points on the curve defined over its base field. + OUTPUT: a generator of all the rational points on the curve defined over its base field EXAMPLES:: @@ -1971,7 +1987,6 @@ def rational_points_iterator(self): Traceback (most recent call last): ... StopIteration - """ g = self.defining_polynomial() K = g.parent().base_ring() @@ -2014,11 +2029,9 @@ def _points_via_singular(self, sort=True): INPUT: - - - ``sort`` -- bool (default: ``True``), if ``True`` return the - point list sorted. If ``False``, returns the points in the order - computed by Singular. - + - ``sort`` -- boolean (default: ``True``); if ``True`` return the + point list sorted. If ``False``, returns the points in the order + computed by Singular. EXAMPLES:: @@ -2035,10 +2048,10 @@ def _points_via_singular(self, sort=True): (0 : 0 : 1), (2 : 3 : 1)] - .. note:: + .. NOTE:: The Brill-Noether package does not always work (i.e., the - 'bn' algorithm. When it fails a :class:`RuntimeError` exception is + 'bn' algorithm. When it fails a :exc:`RuntimeError` exception is raised. """ f = self.defining_polynomial()._singular_() @@ -2053,7 +2066,7 @@ def _points_via_singular(self, sort=True): X2 = singular.NSplaces(1, X1) R = X2[5][1][1] - singular.set_ring(R) + R.set_ring() # We use sage_flattened_str_list since iterating through # the entire list through the sage/singular interface directly @@ -2085,10 +2098,10 @@ def riemann_roch_basis(self, D): INPUT: - - ``D`` -- a divisor + - ``D`` -- a divisor - OUTPUT: A list of function field elements that form a basis of the - Riemann-Roch space. + OUTPUT: list of function field elements that form a basis of the + Riemann-Roch space EXAMPLES:: @@ -2137,7 +2150,7 @@ def riemann_roch_basis(self, D): pnts = [(int(v[i][0]), int(v[i][2])-1) for i in range(len(v))] # retrieve coordinates of rational points R = X2[5][1][1] - singular.set_ring(R) + R.set_ring() v = singular('POINTS').sage_flattened_str_list() coords = [self(int(v[3*i]), int(v[3*i+1]), int(v[3*i+2])) for i in range(len(v)//3)] # build correct representation of D for singular @@ -2158,28 +2171,28 @@ def riemann_roch_basis(self, D): V = [(sage_eval(a, vars)/sage_eval(b, vars)) for a, b in LG] return V - def rational_points(self, algorithm="enum", sort=True): + def rational_points(self, algorithm='enum', sort=True): r""" Return the rational points on this curve. INPUT: - - ``algorithm`` -- one of + - ``algorithm`` -- one of - - ``'enum'`` -- straightforward enumeration + - ``'enum'`` -- straightforward enumeration - - ``'bn'`` -- via Singular's brnoeth package. + - ``'bn'`` -- via Singular's brnoeth package - - ``sort`` -- boolean (default: ``True``); whether the output - points should be sorted. If False, the order of the output + - ``sort`` -- boolean (default: ``True``); whether the output + points should be sorted. If ``False``, the order of the output is non-deterministic. - OUTPUT: A list of all the rational points on the curve, possibly sorted. + OUTPUT: list of all the rational points on the curve, possibly sorted .. NOTE:: The Brill-Noether package does not always work (i.e., the 'bn' - algorithm. When it fails a :class:`RuntimeError` exception is raised. + algorithm. When it fails a :exc:`RuntimeError` exception is raised. EXAMPLES:: @@ -2234,7 +2247,6 @@ def rational_points(self, algorithm="enum", sort=True): sage: C = Curve(f); pts = C.rational_points() sage: pts [(0 : 0 : 1), (0 : 1 : 0), (1 : 0 : 0)] - """ if algorithm == "enum": points = list(self.rational_points_iterator()) @@ -2250,8 +2262,8 @@ def rational_points(self, algorithm="enum", sort=True): return self._points_via_singular(sort=sort) if algorithm == "all": - S_enum = self.rational_points(algorithm="enum") - S_bn = self.rational_points(algorithm="bn") + S_enum = self.rational_points(algorithm='enum') + S_bn = self.rational_points(algorithm='bn') if S_enum != S_bn: raise RuntimeError("Bug in rational_points -- different\ algorithms give different answers for\ @@ -2284,7 +2296,7 @@ def __init__(self, A, f): ideal = self.defining_ideal() gs = self.ambient_space().gens() for i in range(self.ngens()): - if not gs[i] in ideal: + if gs[i] not in ideal: self._open_affine = self.affine_patch(i) self._open_affine_index = i break @@ -2361,7 +2373,7 @@ def function(self, f): - ``f`` -- a fraction of homogeneous polynomials of the coordinate ring of the ambient space of the curve - OUTPUT: An element of the function field. + OUTPUT: an element of the function field EXAMPLES:: @@ -2415,7 +2427,7 @@ def pull_from_function_field(self, f): INPUT: - - ``f`` -- an element of the function field + - ``f`` -- an element of the function field OUTPUT: @@ -2536,7 +2548,6 @@ def _singularities(self): sage: D = Curve(x) sage: D._singularities [] - """ S = self.ambient_space().coordinate_ring() to_F = self._map_to_function_field @@ -2722,7 +2733,7 @@ def places_on(self, point): # determine the affine patch where the point lies S = prime.ring() for i in range(S.ngens()): - if not S.gen(i) in prime: + if S.gen(i) not in prime: break phi = self._map_to_function_field @@ -2843,7 +2854,7 @@ def closed_points(self, degree=1): INPUT: - - ``degree`` -- a positive integer + - ``degree`` -- positive integer EXAMPLES:: @@ -2900,7 +2911,6 @@ def L_polynomial(self, name='t'): sage: Cbar = C.projective_closure() sage: Cbar.L_polynomial() 9*t^4 - 3*t^3 + t^2 - t + 1 - """ F = self.function_field() L = F.L_polynomial() @@ -2938,7 +2948,6 @@ def number_of_rational_points(self, r=1): Finite Field in z3 of size 3^3 sage: len(D.closed_points()) 21 - """ q = self.base_ring().order() L = self.L_polynomial() @@ -2990,12 +2999,12 @@ def Hasse_bounds(q, genus=1): INPUT: - - ``q`` (int) -- a prime power + - ``q`` -- integer; a prime power - - ``genus`` (int, default 1) -- a non-negative integer, + - ``genus`` -- nonnegative integer (default: 1) - OUTPUT: A tuple. The Hasse bounds (lb,ub) for the cardinality of a curve of - genus ``genus`` defined over `\GF{q}`. + OUTPUT: tuple; the Hasse bounds (lb,ub) for the cardinality of a curve of + genus ``genus`` defined over `\GF{q}` EXAMPLES:: diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py old mode 100644 new mode 100755 index 7dec97439db..47485b86340 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -42,21 +42,21 @@ # https://www.gnu.org/licenses/ # **************************************************************************** import itertools -from copy import copy +from copy import copy from itertools import combinations + from sage.combinat.permutation import Permutation from sage.functions.generalized import sign from sage.geometry.voronoi_diagram import VoronoiDiagram from sage.graphs.graph import Graph from sage.groups.braid import BraidGroup -from sage.groups.finitely_presented import wrap_FpGroup from sage.groups.free_group import FreeGroup from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.libs.braiding import leftnormalform, rightnormalform from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_function from sage.misc.flatten import flatten +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.parallel.decorate import parallel from sage.rings.complex_interval_field import ComplexIntervalField @@ -67,7 +67,9 @@ from sage.rings.qqbar import QQbar from sage.rings.rational_field import QQ from sage.rings.real_mpfr import RealField -from .constructor import Curve +from sage.schemes.curves.constructor import Curve + +lazy_import('sage.libs.braiding', ['leftnormalform', 'rightnormalform']) roots_interval_cache = {} @@ -78,13 +80,11 @@ def braid_from_piecewise(strands): INPUT: - - ``strands`` -- a list of lists of tuples ``(t, c1, c2)``, where ``t`` + - ``strands`` -- list of lists of tuples ``(t, c1, c2)``, where ``t`` is a number between 0 and 1, and ``c1`` and ``c2`` are rationals - or algebraic reals. + or algebraic reals - OUTPUT: - - The braid formed by the piecewise linear strands. + OUTPUT: the braid formed by the piecewise linear strands EXAMPLES:: @@ -177,12 +177,10 @@ def discrim(pols) -> tuple: INPUT: - - ``pols`` -- a list or tuple of polynomials in two variables with - coefficients in a number field with a fixed embedding in `\QQbar`. - - OUTPUT: + - ``pols`` -- list or tuple of polynomials in two variables with + coefficients in a number field with a fixed embedding in `\QQbar` - A tuple with the roots of the discriminant in `\QQbar`. + OUTPUT: a tuple with the roots of the discriminant in `\QQbar` EXAMPLES:: @@ -228,7 +226,7 @@ def corrected_voronoi_diagram(points): INPUT: - - ``points`` -- a tuple of complex numbers + - ``points`` -- tuple of complex numbers OUTPUT: @@ -284,13 +282,13 @@ def orient_circuit(circuit, convex=False, precision=53, verbose=False): INPUT: - - ``circuit`` -- a circuit in the graph of a Voronoi Diagram, given + - ``circuit`` -- a circuit in the graph of a Voronoi Diagram, given by a list of edges - ``convex`` -- boolean (default: ``False``); if set to ``True`` a simpler computation is made - - ``precision`` -- bits of precision (default: 53) + - ``precision`` -- bits of precision (default: 53) - ``verbose`` -- boolean (default: ``False``); for testing purposes @@ -388,10 +386,10 @@ def voronoi_cells(V, vertical_lines=frozenset()): - ``G`` -- the graph of the 1-skeleton of ``V`` - ``E`` -- the subgraph of the boundary - ``p`` -- a vertex in ``E`` - - ``EC`` -- a list of vertices (representing a counterclockwise orientation + - ``EC`` -- list of vertices (representing a counterclockwise orientation of ``E``) with identical first and last elements) - ``DG`` -- the dual graph of ``V``, where the vertices are labelled - by the compact regions of ``V`` and the edges by their dual edges. + by the compact regions of ``V`` and the edges by their dual edges - ``vertical_regions`` -- dictionary for the regions associated with vertical lines @@ -490,7 +488,7 @@ def followstrand(f, factors, x0, x1, y0a, prec=53) -> list: INPUT: - ``f`` -- an irreducible polynomial in two variables - - ``factors`` -- a list of irreducible polynomials in two variables + - ``factors`` -- list of irreducible polynomials in two variables - ``x0`` -- a complex value, where the homotopy starts - ``x1`` -- a complex value, where the homotopy ends - ``y0a`` -- an approximate solution of the polynomial `F(y) = f(x_0, y)` @@ -608,7 +606,7 @@ def newton(f, x0, i0): sage: n 0.0? sage: n.real().endpoints() - (-0.0460743801652894, 0.0291454081632654) + (-0.0147727272727274, 0.00982142857142862) sage: n.imag().endpoints() (0.000000000000000, -0.000000000000000) """ @@ -621,11 +619,9 @@ def fieldI(field): INPUT: - - ``field`` -- a number field with an embedding in `\QQbar`. - - OUTPUT: + - ``field`` -- a number field with an embedding in `\QQbar` - The extension ``F`` of ``field`` containing ``I`` with an embedding in `\QQbar`. + OUTPUT: the extension ``F`` of ``field`` containing ``I`` with an embedding in `\QQbar` EXAMPLES:: @@ -736,7 +732,7 @@ def roots_interval(f, x0): diam = min((CF(r) - CF(r0)).abs() for r0 in roots[:i] + roots[i + 1:]) / divisor envelop = IF(diam) * IF((-1, 1), (-1, 1)) - while not newton(fx, r, r + envelop) in r + envelop: + while newton(fx, r, r + envelop) not in r + envelop: prec += 53 IF = ComplexIntervalField(prec) CF = ComplexField(prec) @@ -788,7 +784,7 @@ def populate_roots_interval_cache(inputs): INPUT: - - ``inputs`` -- a list of tuples ``(f, x0)`` + - ``inputs`` -- list of tuples ``(f, x0)`` EXAMPLES:: @@ -808,7 +804,6 @@ def populate_roots_interval_cache(inputs): 0.4795466549853897? - 1.475892845355996?*I: 1.? - 2.?*I, 0.4795466549853897? + 1.475892845355996?*I: 1.? + 2.?*I, 14421467174121563/9293107134194871: 2.? + 0.?*I} - """ global roots_interval_cache tocompute = [inp for inp in inputs if inp not in roots_interval_cache] @@ -831,15 +826,13 @@ def braid_in_segment(glist, x0, x1, precision={}): INPUT: - - ``glist`` -- a tuple of polynomials in two variables + - ``glist`` -- tuple of polynomials in two variables - ``x0`` -- a Gauss rational - ``x1`` -- a Gauss rational - - ``precision`` -- a dictionary (default: `{}`) which assigns a number + - ``precision`` -- dictionary (default: `{}`) which assigns a number precision bits to each element of ``glist`` - OUTPUT: - - A braid. + OUTPUT: a braid EXAMPLES:: @@ -952,7 +945,7 @@ def geometric_basis(G, E, EC0, p, dual_graph, vertical_regions={}) -> list: - ``E`` -- a subgraph of ``G`` which is a cycle containing the bounded edges touching an unbounded region of a Voronoi Diagram - - ``EC0`` -- A counterclockwise orientation of the vertices of ``E`` + - ``EC0`` -- a counterclockwise orientation of the vertices of ``E`` - ``p`` -- a vertex of ``E`` @@ -966,7 +959,7 @@ def geometric_basis(G, E, EC0, p, dual_graph, vertical_regions={}) -> list: the vertices of ``dual_graph`` to fix regions associated with vertical lines - OUTPUT: A geometric basis and a dictionary. + OUTPUT: a geometric basis and a dictionary The geometric basis is formed by a list of sequences of paths. Each path is a ist of vertices, that form a closed path in ``G``, based at ``p``, that goes @@ -1142,7 +1135,7 @@ def vertical_lines_in_braidmon(pols) -> list: OUTPUT: A list with the indices of the vertical lines in ``flist`` if there is - no other componnet with vertical asymptote; otherwise it returns an empty + no other component with vertical asymptote; otherwise it returns an empty list. EXAMPLES:: @@ -1230,7 +1223,7 @@ def braid_monodromy(f, arrangement=(), vertical=False): - ``arrangement`` -- tuple (default: ``()``); an optional tuple of polynomials whose product equals ``f`` - - ``vertical`` -- boolean (default: ``False`); if set to ``True``, + - ``vertical`` -- boolean (default: ``False``); if set to ``True``, ``arrangements`` contains more than one polynomial, some of them are of degree `1` in `x` and degree `0` in `y`, and none of the other components have vertical asymptotes, then these @@ -1253,7 +1246,7 @@ def braid_monodromy(f, arrangement=(), vertical=False): of a braid corresponding to a vertical line with index ``i`` in ``arrangement``, then ``dv[j] = i``. - - A non-negative integer: the number of strands of the braids, + - A nonnegative integer: the number of strands of the braids, only necessary if the list of braids is empty. .. NOTE:: @@ -1309,7 +1302,7 @@ def braid_monodromy(f, arrangement=(), vertical=False): g = f.parent()(prod(glist)) d = g.degree(y) if not arrangement_v: # change of coordinates only if indices_v is empty - while not g.coefficient(y**d) in F: + while g.coefficient(y**d) not in F: g = g.subs({x: x + y}) d = g.degree(y) arrangement_h = tuple(f1.subs({x: x + y}) for f1 in arrangement_h) @@ -1497,8 +1490,8 @@ def braid2rels(L): INPUT: - - ``L`` -- a tuple whose first element is a positive braid and the second - element is a list of permutation braids. + - ``L`` -- tuple whose first element is a positive braid and the second + element is a list of permutation braids OUTPUT: @@ -1543,7 +1536,7 @@ def braid2rels(L): P.SetTzOptions(dic) P.TzGoGo() P.TzGoGo() - gb = wrap_FpGroup(P.FpGroupPresentation()) + gb = P.FpGroupPresentation().sage() U = [rel.Tietze() for rel in gb.relations()] return U @@ -1567,10 +1560,10 @@ def fundamental_group_from_braid_mon(bm, degree=None, INPUT: - - ``bm`` -- a list of braids + - ``bm`` -- list of braids - ``degree`` -- integer (default: ``None``); only needed if the braid - monodromy is an empty list. + monodromy is an empty list - ``simplified`` -- boolean (default: ``True``); if set to ``True`` the presentation will be simplified (see below) @@ -1588,7 +1581,7 @@ def fundamental_group_from_braid_mon(bm, degree=None, - ``vertical`` -- list of integers (default: ``[]``); the indices in ``[0 .. r - 1]`` of the braids that surround a vertical line - If ``projective``` is ``False`` and ``puiseux`` is + If ``projective`` is ``False`` and ``puiseux`` is ``True``, a Zariski-VanKampen presentation is returned. OUTPUT: @@ -1690,7 +1683,7 @@ def fundamental_group(f, simplified=True, projective=False, puiseux=True): with a wedge of 2-spheres. One relation is added if ``projective`` is set to ``True``. - If ``projective``` is ``False`` and ``puiseux`` is + If ``projective`` is ``False`` and ``puiseux`` is ``True``, a Zariski-VanKampen presentation is returned. OUTPUT: @@ -1759,7 +1752,7 @@ def fundamental_group(f, simplified=True, projective=False, puiseux=True): x, y = g.parent().gens() F = g.parent().base_ring() d = g.degree(y) - while not g.coefficient(y**d) in F: + while g.coefficient(y**d) not in F: g = g.subs({x: x + y}) d = g.degree(y) if projective: diff --git a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py old mode 100644 new mode 100755 index e28289e1d84..649e565e797 --- a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py +++ b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py @@ -8,7 +8,8 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** from sage.rings.integer_ring import ZZ -from sage.functions.log import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.log", "log") def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor=[1]): @@ -31,9 +32,8 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= - ``known_factor`` -- the list of coefficients of the known factor - OUTPUT: - - A list of integers corresponding to the characteristic polynomial of the Frobenius action. + OUTPUT: list of integers corresponding to the characteristic polynomial + of the Frobenius action EXAMPLES:: diff --git a/src/sage/schemes/cyclic_covers/constructor.py b/src/sage/schemes/cyclic_covers/constructor.py old mode 100644 new mode 100755 index 6ff76f69c0a..92366cfbb79 --- a/src/sage/schemes/cyclic_covers/constructor.py +++ b/src/sage/schemes/cyclic_covers/constructor.py @@ -25,13 +25,12 @@ def CyclicCover(r, f, names=None, check_smooth=True): - ``r`` -- the order of the cover - - ``f`` -- univariate polynomial if not given, then it defaults to 0. + - ``f`` -- univariate polynomial if not given, then it defaults to 0 - - ``names`` (default: ``["x","y"]``) -- names for the - coordinate functions + - ``names`` -- (default: ``["x","y"]``) names for the coordinate functions - - ``check_squarefree`` (default: ``True``) -- test if - the input defines a unramified cover of the projective line. + - ``check_squarefree`` -- boolean (default: ``True``); test if + the input defines a unramified cover of the projective line .. WARNING:: @@ -97,14 +96,12 @@ def CyclicCover(r, f, names=None, check_smooth=True): Input with integer coefficients creates objects with the integers as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`). - In other words, it is checked that the discriminant is non-zero, but it is + In other words, it is checked that the discriminant is nonzero, but it is not checked whether the discriminant is a unit in `\ZZ^*`:: sage: R. = ZZ[] sage: CyclicCover(5, (x^3-x+2)*(x^6-1)) Cyclic Cover of P^1 over Integer Ring defined by y^5 = x^9 - x^7 + 2*x^6 - x^3 + x - 2 - - """ if not isinstance(f, Polynomial): raise TypeError("Arguments f (= %s) must be a polynomial" % (f,)) diff --git a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py old mode 100644 new mode 100755 index 6ad36e761d7..850d9e975ea --- a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py +++ b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py @@ -66,19 +66,20 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** - from sage.arith.misc import euler_phi -from sage.functions.other import ceil, binomial, floor -from sage.functions.log import log -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.power_series_ring import PowerSeriesRing -from sage.rings.padics.factory import Zp, Zq, Qq -from sage.rings.integer_ring import ZZ -from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.matrix.constructor import matrix, zero_matrix -from sage.modules.free_module_element import vector -from sage.schemes.hyperelliptic_curves.hypellfrob import interval_products from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import +from sage.modules.free_module_element import vector +from sage.rings.finite_rings.integer_mod_ring import IntegerModRing +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.power_series_ring import PowerSeriesRing + +lazy_import("sage.functions.log", "log") +lazy_import("sage.functions.other", ["ceil", "binomial", "floor"]) +lazy_import('sage.rings.padics.factory', ['Zp', 'Zq', 'Qq']) +lazy_import('sage.schemes.hyperelliptic_curves.hypellfrob', 'interval_products') from .charpoly_frobenius import charpoly_frobenius from . import cycliccover_generic @@ -86,16 +87,16 @@ def _N0_nodenominators(p, g, n): """ - Return the necessary p-adic precision for the Frobenius matrix to deduce + Return the necessary `p`-adic precision for the Frobenius matrix to deduce the characteristic polynomial of Frobenius using the Newton identities, using :meth:`charpoly_frobenius`, which assumes that the Frobenius matrix is integral, i.e., has no denominators. INPUT: - - `p` -- prime - - `g` -- genus - - `n` -- degree of residue field + - ``p`` -- prime + - ``g`` -- genus + - ``n`` -- degree of residue field TESTS:: @@ -122,7 +123,6 @@ def __init__(self, AA, r, f, names=None, verbose=0): 1 + 8*t + 102*t^2 + O(t^3) sage: C.frobenius_polynomial().reverse()(t)/((1-t)*(1-p*t)) + O(t^5) 1 + 8*t + 102*t^2 + 1384*t^3 + 18089*t^4 + O(t^5) - """ cycliccover_generic.CyclicCover_generic.__init__(self, AA, r, f, names=names) self._verbose = verbose @@ -232,22 +232,22 @@ def right_side_log(n): self._Zq = IntegerModRing(self._p**self._N) if self._sqrtp: self._Zq0 = IntegerModRing(self._p**(self._N - 1)) - self._Qq = Qq(self._p, prec=self._N, type="capped-rel") + self._Qq = Qq(self._p, prec=self._N, type='capped-rel') self._w = 1 else: self._Zq = Zq( self._q, - names="w", + names='w', modulus=self._Fq.polynomial(), prec=self._N, - type="capped-abs", + type='capped-abs', ) self._w = self._Zq.gen() self._Qq = self._Zq.fraction_field() else: self._Zq = Qq( self._q, - names="w", + names='w', modulus=self._Fq.polynomial(), prec=self._N + self._extraworkingprec, ) @@ -327,14 +327,14 @@ def _divide_vector(self, D, vect, R): def _frob_sparse(self, i, j, N0): r""" - Compute `Frob(x^i y^(-j) dx ) / dx` for y^r = f(x) with N0 terms + Compute `Frob(x^i y^(-j) dx ) / dx` for y^r = f(x) with N0 terms. INPUT: - - ``i`` -- The power of x in the expression `Frob(x^i dx/y^j) / dx` + - ``i`` -- the power of x in the expression `Frob(x^i dx/y^j) / dx` - - ``j`` -- The (negative) power of y in the expression - `Frob(x^i dx/y^j) / dx` + - ``j`` -- the (negative) power of y in the expression + `Frob(x^i dx/y^j) / dx` OUTPUT: @@ -583,7 +583,6 @@ def _vertical_matrix_reduction(self, s0): [ 74203580341 2817857481 75142866164] [108017870113 0 2817857481] )) - """ d = self._d @@ -824,7 +823,7 @@ def _reduce_vector_horizontal_plain(self, G, e, s, k=1): def _reduce_vector_vertical(self, G, s0, s, k=1): r""" - Reduce the vector `G` representing an element of `W_{-1,rs + s0}` by `r k` steps + Reduce the vector `G` representing an element of `W_{-1,rs + s0}` by `r k` steps. INPUT: @@ -833,7 +832,7 @@ def _reduce_vector_vertical(self, G, s0, s, k=1): OUTPUT: - a vector -- `H \in W_{-1, r*(s - k) + s0}` such that - `G y^{-(r*s + s0)} dx \cong H y^{-(r*(s -k) + s0)} dx` + `G y^{-(r*s + s0)} dx \cong H y^{-(r*(s -k) + s0)} dx` TESTS:: @@ -905,7 +904,6 @@ def _initialize_fat_vertical(self, s0, max_upper_target): """ Initialise reduction matrices for vertical reductions for blocks from `s0` to `s0 + max_upper_target`. - TESTS:: sage: p = 4999 @@ -952,8 +950,8 @@ def _frob(self, i, j, N0): INPUT: - - `i`,`j` -- exponents of the basis differential - - `N0` -- desired p-adic precision for the Frobenius expansion + - ``i``, ``j`` -- exponents of the basis differential + - ``N0`` -- desired `p`-adic precision for the Frobenius expansion TESTS:: @@ -1018,7 +1016,7 @@ def _frob(self, i, j, N0): @cached_method def frobenius_matrix(self, N=None): """ - Compute p-adic Frobenius matrix to precision p^N. + Compute `p`-adic Frobenius matrix to precision `p^N`. If `N` not supplied, a default value is selected, which is the minimum needed to recover the charpoly unambiguously. @@ -1242,8 +1240,6 @@ def frobenius_polynomial(self): ....: else: ....: True True - - """ self._init_frob() F = self.frobenius_matrix(self._N0) diff --git a/src/sage/schemes/cyclic_covers/cycliccover_generic.py b/src/sage/schemes/cyclic_covers/cycliccover_generic.py old mode 100644 new mode 100755 index 2ef6b734300..9b21549a8b1 --- a/src/sage/schemes/cyclic_covers/cycliccover_generic.py +++ b/src/sage/schemes/cyclic_covers/cycliccover_generic.py @@ -44,7 +44,7 @@ class CyclicCover_generic(AffinePlaneCurve): def __init__(self, AA, r, f, names=None): """ - Cyclic covers over a general ring + Cyclic covers over a general ring. INPUT: @@ -52,10 +52,10 @@ def __init__(self, AA, r, f, names=None): - ``r`` -- degree of the cover - - ``f`` -- univariate polynomial + - ``f`` -- univariate polynomial - - ``names`` (default: ``["x","y"]``) -- names for the - coordinate functions + - ``names`` -- (default: ``["x","y"]``); names for the + coordinate functions TESTS:: @@ -244,7 +244,6 @@ def projective_closure(self, **kwds): sage: ZZx. = ZZ[] sage: CyclicCover(5, x^5 + x + 1).projective_closure() Projective Plane Curve over Integer Ring defined by x0^5 + x0^4*x1 + x1^5 - x2^5 - """ # test d = 3 and 4 if self._d == self._r: @@ -252,7 +251,7 @@ def projective_closure(self, **kwds): else: raise NotImplementedError("Weighted Projective Space is not implemented") - def cover_polynomial(self, K=None, var="x"): + def cover_polynomial(self, K=None, var='x'): """ Return the polynomial defining the cyclic cover. @@ -260,7 +259,6 @@ def cover_polynomial(self, K=None, var="x"): sage: ZZx. = ZZ[]; CyclicCover(5, x^5 + x + 1).cover_polynomial() x^5 + x + 1 - """ if K is None: diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py old mode 100644 new mode 100755 index 755f8be2f50..7b64cd63883 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -1,11 +1,13 @@ "Birch and Swinnerton-Dyer formulas" from sage.arith.misc import prime_divisors +from sage.misc.lazy_import import lazy_import +from sage.rings.infinity import Infinity from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ -from sage.rings.infinity import Infinity -from sage.rings.number_field.number_field import QuadraticField -from sage.functions.other import ceil + +lazy_import("sage.functions.other", "ceil") +lazy_import("sage.rings.number_field.number_field", "QuadraticField") class BSD_data: @@ -93,6 +95,7 @@ def simon_two_descent_work(E, two_tor_rk): ... DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari. See https://github.com/sagemath/sage/issues/35621 for details. + ... (0, 0, 0, 0, []) sage: E = EllipticCurve('37a') sage: simon_two_descent_work(E, E.two_torsion_rank()) @@ -146,6 +149,7 @@ def mwrank_two_descent_work(E, two_tor_rk): sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens + def pari_two_descent_work(E): r""" Prepare the output from pari by two-isogeny. @@ -154,7 +158,7 @@ def pari_two_descent_work(E): - ``E`` -- an elliptic curve - OUTPUT: A tuple of 5 elements with the first 4 being integers. + OUTPUT: a tuple of 5 elements with the first 4 being integers - a lower bound on the rank @@ -181,7 +185,6 @@ def pari_two_descent_work(E): sage: E = EllipticCurve('66b3') sage: pari_two_descent_work(E) (0, 0, 2, 2, []) - """ ep = E.pari_curve() lower, rank_upper_bd, s, pts = ep.ellrank() @@ -302,24 +305,24 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, - ``E`` -- an elliptic curve - - ``verbosity`` -- int, how much information about the proof to print. + - ``verbosity`` -- integer; how much information about the proof to print - 0: print nothing - 1: print sketch of proof - 2: print information about remaining primes - - ``two_desc`` -- string (default ``'mwrank'``), what to use for the - two-descent. Options are ``'mwrank', 'pari', 'sage'`` + - ``two_desc`` -- string (default: ``'mwrank'``); what to use for the + two-descent. Options are ``'mwrank', 'pari', 'sage'``. - - ``proof`` -- bool or None (default: None, see - proof.elliptic_curve or sage.structure.proof). If False, this + - ``proof`` -- boolean or ``None`` (default: None, see + proof.elliptic_curve or sage.structure.proof). If ``False``, this function just immediately returns the empty list. - ``secs_hi`` -- maximum number of seconds to try to compute the Heegner index before switching over to trying to compute the Heegner index bound. (Rank 0 only!) - - ``return_BSD`` -- bool (default: ``False``) whether to return an object + - ``return_BSD`` -- boolean (default: ``False``); whether to return an object which contains information to reconstruct a proof .. NOTE:: @@ -496,7 +499,6 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, p = 2: True by 2-descent True for p not in {2} by Kolyvagin. [] - """ if proof is None: from sage.structure.proof.proof import get_flag @@ -872,8 +874,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, # Try harder to compute the Heegner index, where it matters if heegner_index is None: - if max_height < 18: - max_height = 18 + max_height = max(max_height, 18) for D in BSD.heegner_index_upper_bound: M = BSD.heegner_index_upper_bound[D] for p in kolyvagin_primes: diff --git a/src/sage/schemes/elliptic_curves/Qcurves.py b/src/sage/schemes/elliptic_curves/Qcurves.py old mode 100644 new mode 100755 index e0f55597f90..b8e9b7411fb --- a/src/sage/schemes/elliptic_curves/Qcurves.py +++ b/src/sage/schemes/elliptic_curves/Qcurves.py @@ -32,15 +32,15 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): INPUT: - - ``E`` (elliptic curve) -- an elliptic curve over a number field. + - ``E`` -- elliptic curve over a number field - - ``maxp`` (int, default 100): bound on primes used for checking + - ``maxp`` -- integer (default: 100); bound on primes used for checking necessary local conditions. The result will not depend on this, but using a larger value may return ``False`` faster. - - ``certificate`` (bool, default ``False``): if ``True`` then a + - ``certificate`` -- boolean (default: ``False``); if ``True`` then a second value is returned giving a certificate for the - `\QQ`-curve property. + `\QQ`-curve property OUTPUT: @@ -82,7 +82,7 @@ def is_Q_curve(E, maxp=100, certificate=False, verbose=False): the conductor norm. 3. For all primes `p\mid N` check that the valuations of `j` at - all `P\mid p` are either all negative or all non-negative; if not, + all `P\mid p` are either all negative or all nonnegative; if not, return ``False``. 4. For `p\le maxp`, `p\not\mid N`, check that either `E` is @@ -402,13 +402,13 @@ def Step4Test(E, B, oldB=0, verbose=False): INPUT: - - `E` (elliptic curve): an elliptic curve defined over a number field + - ``E`` -- elliptic curve defined over a number field - - `B` (integer): upper bound on primes to test + - ``B`` -- integer; upper bound on primes to test - - ``oldB`` (integer, default 0): lower bound on primes to test + - ``oldB`` -- integer (default: 0); lower bound on primes to test - - ``verbose`` (boolean, default ``False``): verbosity flag + - ``verbose`` -- boolean (default: ``False``); verbosity flag OUTPUT: @@ -496,9 +496,9 @@ def conjugacy_test(jlist, verbose=False): INPUT: - - ``jlist`` (list): a list of algebraic numbers in the same field + - ``jlist`` -- list of algebraic numbers in the same field - - ``verbose`` (boolean, default ``False``): verbosity flag + - ``verbose`` -- boolean (default: ``False``); verbosity flag OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/all.py b/src/sage/schemes/elliptic_curves/all.py index 84f7b0d5a50..df527315527 100644 --- a/src/sage/schemes/elliptic_curves/all.py +++ b/src/sage/schemes/elliptic_curves/all.py @@ -27,10 +27,10 @@ lazy_import('sage.schemes.elliptic_curves.jacobian', 'Jacobian') lazy_import('sage.schemes.elliptic_curves.ell_finite_field', 'special_supersingular_curve') - lazy_import('sage.schemes.elliptic_curves.ell_rational_field', ['cremona_curves', 'cremona_optimal_curves']) +from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_with_prime_order from sage.schemes.elliptic_curves.cm import (cm_orders, cm_j_invariants, cm_j_invariants_and_orders, diff --git a/src/sage/schemes/elliptic_curves/cm.py b/src/sage/schemes/elliptic_curves/cm.py old mode 100644 new mode 100755 index d63589020c4..6760719e789 --- a/src/sage/schemes/elliptic_curves/cm.py +++ b/src/sage/schemes/elliptic_curves/cm.py @@ -34,12 +34,10 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.interfaces.magma import magma from sage.rings.integer import Integer from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ from sage.rings.integer_ring import IntegerRing -from sage.rings.number_field.number_field import is_fundamental_discriminant from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.misc.cachefunc import cached_function @@ -53,9 +51,9 @@ def hilbert_class_polynomial(D, algorithm=None): INPUT: - - ``D`` (int) -- a negative integer congruent to 0 or 1 modulo 4. + - ``D`` -- negative integer congruent to 0 or 1 modulo 4 - - ``algorithm`` (string, default None). + - ``algorithm`` -- string (default: ``None``) OUTPUT: @@ -91,19 +89,19 @@ def hilbert_class_polynomial(D, algorithm=None): x^3 + 3491750*x^2 - 5151296875*x + 12771880859375 sage: hilbert_class_polynomial(-37*4) x^2 - 39660183801072000*x - 7898242515936467904000000 - sage: hilbert_class_polynomial(-37*4, algorithm="magma") # optional - magma + sage: hilbert_class_polynomial(-37*4, algorithm='magma') # optional - magma x^2 - 39660183801072000*x - 7898242515936467904000000 sage: hilbert_class_polynomial(-163) x + 262537412640768000 - sage: hilbert_class_polynomial(-163, algorithm="sage") + sage: hilbert_class_polynomial(-163, algorithm='sage') x + 262537412640768000 - sage: hilbert_class_polynomial(-163, algorithm="magma") # optional - magma + sage: hilbert_class_polynomial(-163, algorithm='magma') # optional - magma x + 262537412640768000 TESTS:: - sage: all(hilbert_class_polynomial(d, algorithm="arb") == - ....: hilbert_class_polynomial(d, algorithm="sage") + sage: all(hilbert_class_polynomial(d, algorithm='arb') == + ....: hilbert_class_polynomial(d, algorithm='sage') ....: for d in range(-1,-100,-1) if d % 4 in [0, 1]) True """ @@ -121,6 +119,7 @@ def hilbert_class_polynomial(D, algorithm=None): return sage.libs.arb.arith.hilbert_class_polynomial(D) if algorithm == "magma": + from sage.interfaces.magma import magma magma.eval("R := PolynomialRing(IntegerRing())") f = str(magma.eval("HilbertClassPolynomial(%s)" % D)) return IntegerRing()['x'](f) @@ -183,10 +182,9 @@ def is_HCP(f, check_monic_irreducible=True): INPUT: - - ``f`` -- a polynomial in `\ZZ[X]`. - - ``check_monic_irreducible`` (boolean, default ``True``) -- if - ``True``, check that ``f`` is a monic, irreducible, integer - polynomial. + - ``f`` -- a polynomial in `\ZZ[X]` + - ``check_monic_irreducible`` -- boolean (default: ``True``); if ``True``, + check that ``f`` is a monic, irreducible, integer polynomial OUTPUT: @@ -289,15 +287,16 @@ def is_HCP(f, check_monic_irreducible=True): return zero return D if f == hilbert_class_polynomial(D) else zero + def OrderClassNumber(D0,h0,f): r""" Return the class number h(f**2 * D0), given h(D0)=h0. INPUT: - - ``D0`` (integer) -- a negative fundamental discriminant - - ``h0`` (integer) -- the class number of the (maximal) imaginary quadratic order of discriminant ``D0`` - - ``f`` (integer) -- a positive integer + - ``D0`` -- integer; a negative fundamental discriminant + - ``h0`` -- integer; the class number of the (maximal) imaginary quadratic order of discriminant ``D0`` + - ``f`` -- positive integer OUTPUT: @@ -322,7 +321,6 @@ def OrderClassNumber(D0,h0,f): [1, 1, 2, 2, 2, 4, 4, 4, 6, 4, 6, 8, 6, 8, 8, 8, 8, 12, 10] sage: all([OrderClassNumber(D0,h,f) == (D0*f**2).class_number() for f in srange(1,20)]) True - """ if not D0.is_fundamental_discriminant(): raise ValueError("{} is not a fundamental discriminant".format(D0)) @@ -402,9 +400,8 @@ def cm_j_invariants_and_orders(K, proof=None): OUTPUT: - (list) A list of 3-tuples `(D,f,j)` where `j` is a CM - `j`-invariant in `K` with quadratic fundamental discriminant `D` - and conductor `f`. + A list of 3-tuples `(D,f,j)` where `j` is a CM `j`-invariant in `K` with + quadratic fundamental discriminant `D` and conductor `f`. EXAMPLES:: @@ -479,12 +476,10 @@ def cm_orders(h, proof=None): INPUT: - - `h` -- positive integer + - ``h`` -- positive integer - ``proof`` -- (default: proof.number_field()) - OUTPUT: - - - list of 2-tuples `(D,f)` sorted lexicographically by `(|D|, f)` + OUTPUT: list of 2-tuples `(D,f)` sorted lexicographically by `(|D|, f)` EXAMPLES:: @@ -629,7 +624,7 @@ class number `h`, and the number of fundamental negative discriminants with INPUT: - - `h` -- integer + - ``h`` -- integer EXAMPLES:: @@ -648,7 +643,6 @@ class number `h`, and the number of fundamental negative discriminants with Traceback (most recent call last): ... NotImplementedError: largest fundamental discriminant not available for class number 101 - """ h = Integer(h) if h <= 0: @@ -659,6 +653,7 @@ class number `h`, and the number of fundamental negative discriminants with except KeyError: raise NotImplementedError("largest fundamental discriminant not available for class number %s" % h) + def largest_disc_with_class_number(h): r""" Return largest absolute value of any negative discriminant with @@ -679,7 +674,7 @@ class number `h`, and the number of fundamental negative INPUT: - - `h` -- integer + - ``h`` -- integer EXAMPLES:: @@ -710,7 +705,6 @@ class number `h` is also the largest discriminant, but this is not (3763, 51) sage: largest_disc_with_class_number(6) (4075, 101) - """ h = Integer(h) if h <= 0: @@ -731,6 +725,7 @@ class number `h` is also the largest discriminant, but this is not [(-3, 1), (-3, 2), (-3, 3), (-4, 1), (-4, 2), (-7, 1), (-7, 2), (-8, 1), (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)]]} + def discriminants_with_bounded_class_number(hmax, B=None, proof=None): r"""Return a dictionary with keys class numbers `h\le hmax` and values the list of all pairs `(D_0, f)`, with `D_0<0` a fundamental discriminant such @@ -740,15 +735,13 @@ def discriminants_with_bounded_class_number(hmax, B=None, proof=None): INPUT: - ``hmax`` -- integer - - `B` -- integer or None; if None returns all pairs + - ``B`` -- integer or ``None``; if ``None`` returns all pairs - ``proof`` -- this code calls the PARI function :pari:`qfbclassno`, so it could give wrong answers when ``proof``==``False`` (though only for discriminants greater than `2\cdot10^{10}`). The default is the current value of ``proof.number_field()``. - OUTPUT: - - - dictionary + OUTPUT: dictionary .. NOTE:: @@ -784,7 +777,6 @@ def discriminants_with_bounded_class_number(hmax, B=None, proof=None): sage: sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(hmax=5, B=50) {1: [(-3, 1), (-3, 2), (-3, 3), (-4, 1), (-4, 2), (-7, 1), (-7, 2), (-8, 1), (-11, 1), (-19, 1), (-43, 1)], 2: [(-3, 4), (-4, 3), (-8, 2), (-15, 1), (-20, 1), (-24, 1), (-35, 1), (-40, 1)], 3: [(-11, 2), (-23, 1), (-31, 1)], 4: [(-39, 1)], 5: [(-47, 1)]} - """ hmax = Integer(hmax) global hDf_dict @@ -901,11 +893,11 @@ def is_cm_j_invariant(j, algorithm='CremonaSutherland', method=None): - ``j`` -- an element of a number field `K` - - ``algorithm`` (string, default 'CremonaSutherland') -- the algorithm - used, either 'CremonaSutherland' (the default, very much faster - for all but very small degrees), 'exhaustive' or 'reduction' + - ``algorithm`` -- string (default: ``'CremonaSutherland'``); the algorithm + used, either ``'CremonaSutherland'`` (the default, very much faster + for all but very small degrees), ``'exhaustive'`` or ``'reduction'`` - - ``method`` (string) -- deprecated name for ``algorithm`` + - ``method`` -- string; deprecated name for ``algorithm`` OUTPUT: @@ -966,7 +958,6 @@ def is_cm_j_invariant(j, algorithm='CremonaSutherland', method=None): sage: from sage.schemes.elliptic_curves.cm import is_cm_j_invariant sage: all(is_cm_j_invariant(j) == (True, (d,f)) for d,f,j in cm_j_invariants_and_orders(QQ)) True - """ if method: if not algorithm: diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py old mode 100644 new mode 100755 index 21470bd890a..831ee47e280 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -28,7 +28,7 @@ from sage.rings.rational_field import RationalField import sage.rings.abc -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.number_field.number_field_base import NumberField from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.polynomial.multi_polynomial import MPolynomial @@ -65,7 +65,7 @@ class EllipticCurveFactory(UniqueFactory): - ``EllipticCurve(label)``: Returns the elliptic curve over `\QQ` from the Cremona database with the given label. The label is a - string, such as ``"11a"`` or ``"37b2"``. The letters in the + string, such as ``'11a'`` or ``'37b2'``. The letters in the label *must* be lower case (Cremona's new labeling). - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic @@ -197,7 +197,7 @@ class EllipticCurveFactory(UniqueFactory): By default, when a rational value of `j` is given, the constructed curve is a minimal twist (minimal conductor for curves with that `j`-invariant). This can be changed by setting the optional - parameter ``minimal_twist``, which is True by default, to False:: + parameter ``minimal_twist``, which is ``True`` by default, to ``False``:: sage: EllipticCurve(j=100) Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field @@ -438,6 +438,9 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, # Interpret x as a Cremona or LMFDB label. from sage.databases.cremona import CremonaDatabase x, data = CremonaDatabase().coefficients_and_data(x) + # data is only valid for elliptic curves over QQ. + if R not in (None, QQ): + data = {} # User-provided keywords may override database entries. data.update(kwds) kwds = data @@ -457,7 +460,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, return (R, tuple(R(a) for a in x)), kwds - def create_object(self, version, key, **kwds): + def create_object(self, version, key, *, names=None, **kwds): r""" Create an object from a ``UniqueFactory`` key. @@ -467,18 +470,46 @@ def create_object(self, version, key, **kwds): sage: type(E) + ``names`` is ignored at the moment, however it is used to support a convenient way to get a generator:: + + sage: E.

= EllipticCurve(QQ, [1, 3]) + sage: P + (-1 : 1 : 1) + sage: E.

= EllipticCurve(GF(5), [1, 3]) + sage: P + (4 : 1 : 1) + .. NOTE:: Keyword arguments are currently only passed to the constructor for elliptic curves over `\QQ`; elliptic curves over other fields do not support them. + + TESTS:: + + sage: E = EllipticCurve.create_object(0, (QQ, (1, 2, 0, 1, 2)), rank=2) + sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2)), rank=2) + Traceback (most recent call last): + ... + TypeError: unexpected keyword arguments: {'rank': 2} + + Coverage tests:: + + sage: E = EllipticCurve(QQ, [2, 5], modular_degree=944, regulator=1) + sage: E.modular_degree() + 944 + sage: E.regulator() + 1.00000000000000 """ R, x = key if R is QQ: from .ell_rational_field import EllipticCurve_rational_field return EllipticCurve_rational_field(x, **kwds) - elif isinstance(R, NumberField): + elif kwds: + raise TypeError(f"unexpected keyword arguments: {kwds}") + + if isinstance(R, NumberField): from .ell_number_field import EllipticCurve_number_field return EllipticCurve_number_field(R, x) elif isinstance(R, sage.rings.abc.pAdicField): @@ -504,10 +535,9 @@ def EllipticCurve_from_Weierstrass_polynomial(f): INPUT: - - ``f`` -- a inhomogeneous cubic polynomial in long Weierstrass - form. + - ``f`` -- a inhomogeneous cubic polynomial in long Weierstrass form - OUTPUT: The elliptic curve defined by it. + OUTPUT: the elliptic curve defined by it EXAMPLES:: @@ -537,6 +567,7 @@ def EllipticCurve_from_Weierstrass_polynomial(f): """ return EllipticCurve(coefficients_from_Weierstrass_polynomial(f)) + def coefficients_from_Weierstrass_polynomial(f): r""" Return the coefficients `[a_1, a_2, a_3, a_4, a_6]` of a cubic in @@ -613,9 +644,9 @@ def EllipticCurve_from_j(j, minimal_twist=True): INPUT: - - ``j`` -- an element of some field. + - ``j`` -- an element of some field - - ``minimal_twist`` (boolean, default: ``True``) -- If True and ``j`` + - ``minimal_twist``-- boolean (default: ``True``); if ``True`` and ``j`` is in `\QQ`, the curve returned is a minimal twist, i.e. has minimal conductor; when there is more than one curve with minimal conductor, the curve returned is the one whose label @@ -623,9 +654,7 @@ def EllipticCurve_from_j(j, minimal_twist=True): the one whose minimal a-invariants are first lexicographically. If `j` is not in `\QQ` this parameter is ignored. - OUTPUT: - - An elliptic curve with `j`-invariant `j`. + OUTPUT: an elliptic curve with `j`-invariant `j` EXAMPLES:: @@ -644,7 +673,7 @@ def EllipticCurve_from_j(j, minimal_twist=True): 1 The ``minimal_twist`` parameter (ignored except over `\QQ` and - True by default) controls whether or not a minimal twist is + ``True`` by default) controls whether or not a minimal twist is computed:: sage: EllipticCurve_from_j(100) @@ -685,7 +714,7 @@ def coefficients_from_j(j, minimal_twist=True): [1, 0, 0, 36, 3455] The ``minimal_twist`` parameter (ignored except over `\QQ` and - True by default) controls whether or not a minimal twist is + ``True`` by default) controls whether or not a minimal twist is computed:: sage: coefficients_from_j(100) @@ -777,15 +806,15 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): - ``F`` -- a homogeneous cubic in three variables with rational coefficients, as a polynomial ring element, defining a smooth - plane cubic curve `C`. + plane cubic curve `C` - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on `C`, or ``None``. If ``None`` then a rational flex will be used as a base point if one exists, otherwise an error will be raised. - - ``morphism`` -- boolean (default: ``True``). If ``True`` + - ``morphism`` -- boolean (default: ``True``); if ``True`` returns a birational isomorphism from `C` to a Weierstrass - elliptic curve `E`, otherwise just returns `E`. + elliptic curve `E`, otherwise just returns `E` OUTPUT: @@ -1098,7 +1127,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): # check the input R = F.parent() K = R.base_ring() - if not is_MPolynomialRing(R): + if not isinstance(R, MPolynomialRing_base): raise TypeError('equation must be a polynomial') if R.ngens() != 3 or F.nvariables() != 3: raise TypeError('equation must be a polynomial in three variables') @@ -1247,13 +1276,11 @@ def tangent_at_smooth_point(C,P): INPUT: - - ``C`` -- a projective plane curve. + - ``C`` -- a projective plane curve - - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on `C`. + - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on `C` - OUTPUT: - - The linear form defining the tangent at `P` to `C`. + OUTPUT: the linear form defining the tangent at `P` to `C` EXAMPLES:: @@ -1282,6 +1309,7 @@ def tangent_at_smooth_point(C,P): except NotImplementedError: return C.tangents(P,factor=False)[0] + def chord_and_tangent(F, P): r"""Return the third point of intersection of a cubic with the tangent at one point. @@ -1292,7 +1320,7 @@ def chord_and_tangent(F, P): plane cubic curve. - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on the - curve `F=0`. + curve `F=0` OUTPUT: @@ -1333,7 +1361,7 @@ def chord_and_tangent(F, P): from sage.schemes.curves.constructor import Curve # check the input R = F.parent() - if not is_MPolynomialRing(R): + if not isinstance(R, MPolynomialRing_base): raise TypeError('equation must be a polynomial') if R.ngens() != 3: raise TypeError('{} is not a polynomial in three variables'.format(F)) @@ -1358,15 +1386,13 @@ def chord_and_tangent(F, P): def projective_point(p): r""" - Return equivalent point with denominators removed + Return equivalent point with denominators removed. INPUT: - - ``P``, ``Q`` -- list/tuple of projective coordinates. - - OUTPUT: + - ``P``, ``Q`` -- list/tuple of projective coordinates - List of projective coordinates. + OUTPUT: list of projective coordinates EXAMPLES:: @@ -1394,11 +1420,11 @@ def are_projectively_equivalent(P, Q, base_ring): INPUT: - - ``P``, ``Q`` -- list/tuple of projective coordinates. + - ``P``, ``Q`` -- list/tuple of projective coordinates - - ``base_ring`` -- the base ring. + - ``base_ring`` -- the base ring - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1421,10 +1447,10 @@ def EllipticCurves_with_good_reduction_outside_S(S=[], proof=None, verbose=False - ``S`` -- list of primes (default: empty list) - - ``proof`` -- boolean (default ``True``): the MW basis for + - ``proof`` -- boolean (default: ``True``); the MW basis for auxiliary curves will be computed with this proof flag - - ``verbose`` -- boolean (default ``False``): if ``True``, some details + - ``verbose`` -- boolean (default: ``False``); if ``True``, some details of the computation will be output .. NOTE:: diff --git a/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx b/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx old mode 100644 new mode 100755 index 4bd4cc6cea9..16bad60ba56 --- a/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx +++ b/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx @@ -89,7 +89,7 @@ def test_valuation(a, p): cdef int padic_square(mpz_t a, mpz_t p) noexcept: """ - Test if a is a p-adic square. + Test if a is a `p`-adic square. """ cdef unsigned long v cdef mpz_t aa @@ -134,7 +134,7 @@ def test_padic_square(a, p): cdef int lemma6(mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t e, mpz_t x, mpz_t p, unsigned long nu) noexcept: """ - Implements Lemma 6 of BSD's "Notes on elliptic curves, I" for odd p. + Implement Lemma 6 of BSD's "Notes on elliptic curves, I" for odd `p`. Returns -1 for insoluble, 0 for undecided, +1 for soluble. """ @@ -184,7 +184,7 @@ cdef int lemma6(mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t e, cdef int lemma7(mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t e, mpz_t x, mpz_t p, unsigned long nu) noexcept: """ - Implements Lemma 7 of BSD's "Notes on elliptic curves, I" for p=2. + Implement Lemma 7 of BSD's "Notes on elliptic curves, I" for `p=2`. Returns -1 for insoluble, 0 for undecided, +1 for soluble. """ @@ -948,7 +948,7 @@ def test_qpls(a, b, c, d, e, p): cdef int everywhere_locally_soluble(mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t e) except -1: """ - Returns whether the quartic has local solutions at all primes p. + Return whether the quartic has local solutions at all primes `p`. """ cdef Integer A, B, C, D, E, Delta,p cdef mpz_t mpz_2 diff --git a/src/sage/schemes/elliptic_curves/ec_database.py b/src/sage/schemes/elliptic_curves/ec_database.py old mode 100644 new mode 100755 index f3de993ff5e..7d418feb437 --- a/src/sage/schemes/elliptic_curves/ec_database.py +++ b/src/sage/schemes/elliptic_curves/ec_database.py @@ -72,6 +72,7 @@ from .constructor import EllipticCurve + class EllipticCurves: def rank(self, rank, tors=0, n=10, labels=False): r""" @@ -80,18 +81,16 @@ def rank(self, rank, tors=0, n=10, labels=False): INPUT: - - ``rank`` (int) -- the desired rank - - - ``tors`` (int, default 0) -- the desired torsion order (ignored if 0) + - ``rank`` -- integer; the desired rank - - ``n`` (int, default 10) -- the maximum number of curves returned. + - ``tors`` -- integer (default: 0); the desired torsion order (ignored if 0) - - ``labels`` (bool, default: ``False``) -- if True, return Cremona - labels instead of curves. + - ``n`` -- integer (default: 10); the maximum number of curves returned - OUTPUT: + - ``labels`` -- boolean (default: ``False``); if ``True``, return Cremona + labels instead of curves - (list) A list at most `n` of elliptic curves of required rank. + OUTPUT: list at most `n` of elliptic curves of required rank EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py old mode 100644 new mode 100755 index 496731a6c7d..ba752e11c10 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -103,6 +103,8 @@ # Private function for parsing input to determine the type of # algorithm # + + def _isogeny_determine_algorithm(E, kernel): r""" Helper function to infer the algorithm to be used from the @@ -121,9 +123,7 @@ def _isogeny_determine_algorithm(E, kernel): - ``kernel`` -- either a list of points on ``E``, or a univariate polynomial or list of coefficients of a univariate polynomial - OUTPUT: - - (string) Either ``"velu"`` or ``"kohel"``. + OUTPUT: string; either ``'velu'`` or ``'kohel'``. EXAMPLES: @@ -173,6 +173,7 @@ def _isogeny_determine_algorithm(E, kernel): raise ValueError("invalid parameters to EllipticCurveIsogeny constructor") + def isogeny_codomain_from_kernel(E, kernel): r""" Compute the isogeny codomain given a kernel. @@ -185,9 +186,7 @@ def isogeny_codomain_from_kernel(E, kernel): or a kernel polynomial (specified as either a univariate polynomial or a coefficient list) - OUTPUT: - - (elliptic curve) The codomain of the separable normalized isogeny + OUTPUT: elliptic curve) The codomain of the separable normalized isogeny defined by this kernel. EXAMPLES:: @@ -227,6 +226,7 @@ def isogeny_codomain_from_kernel(E, kernel): raise NotImplementedError + def compute_codomain_formula(E, v, w): r""" Compute the codomain curve given parameters `v` and `w` (as in @@ -267,6 +267,7 @@ def compute_codomain_formula(E, v, w): return EllipticCurve([a1, a2, a3, A4, A6]) + def compute_vw_kohel_even_deg1(x0, y0, a1, a2, a4): r""" Compute Vélu's `(v,w)` using Kohel's formulas for isogenies of @@ -278,9 +279,7 @@ def compute_vw_kohel_even_deg1(x0, y0, a1, a2, a4): - ``a1``, ``a2``, ``a4`` -- invariants of `E` - OUTPUT: - - (tuple) Vélu's isogeny parameters `(v,w)`. + OUTPUT: Vélu's isogeny parameters `(v,w)`. EXAMPLES: @@ -304,6 +303,7 @@ def compute_vw_kohel_even_deg1(x0, y0, a1, a2, a4): w = x0 * v return v, w + def compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3): r""" Compute Vélu's `(v,w)` using Kohel's formulas for isogenies of @@ -316,9 +316,7 @@ def compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3): - ``s1``, ``s2``, ``s3`` -- signed coefficients of the 2-division polynomial of `E` - OUTPUT: - - (tuple) Vélu's isogeny parameters `(v,w)`. + OUTPUT: Vélu's isogeny parameters `(v,w)`. EXAMPLES: @@ -343,6 +341,7 @@ def compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3): w = 3*(s1**3 - 3*s1*s2 + 3*s3) + (b2*temp1 + b4*s1)/2 return v, w + def compute_vw_kohel_odd(b2, b4, b6, s1, s2, s3, n): r""" Compute Vélu's `(v,w)` using Kohel's formulas for isogenies of odd @@ -355,11 +354,9 @@ def compute_vw_kohel_odd(b2, b4, b6, s1, s2, s3, n): - ``s1``, ``s2``, ``s3`` -- signed coefficients of lowest powers of `x` in the kernel polynomial - - ``n`` (integer) -- the degree - - OUTPUT: + - ``n`` -- integer; the degree - (tuple) Vélu's isogeny parameters `(v,w)`. + OUTPUT: Vélu's isogeny parameters `(v,w)` EXAMPLES: @@ -383,6 +380,7 @@ def compute_vw_kohel_odd(b2, b4, b6, s1, s2, s3, n): w = 10*(s1**3 - 3*s1*s2 + 3*s3) + 2*b2*(s1**2 - 2*s2) + 3*b4*s1 + n*b6 return v, w + def compute_codomain_kohel(E, kernel): r""" Compute the codomain from the kernel polynomial using Kohel's @@ -392,13 +390,11 @@ def compute_codomain_kohel(E, kernel): - ``E`` -- domain elliptic curve - - ``kernel`` (polynomial or list) -- the kernel polynomial, or a + - ``kernel`` -- polynomial or list; the kernel polynomial, or a list of its coefficients - OUTPUT: - - (elliptic curve) The codomain elliptic curve of the isogeny - defined by ``kernel``. + OUTPUT: elliptic curve; the codomain elliptic curve of the isogeny + defined by ``kernel`` EXAMPLES:: @@ -492,6 +488,7 @@ def compute_codomain_kohel(E, kernel): return compute_codomain_formula(E, v, w) + def two_torsion_part(E, psi): r""" Return the greatest common divisor of ``psi`` and the 2-torsion @@ -503,10 +500,7 @@ def two_torsion_part(E, psi): - ``psi`` -- a univariate polynomial over the base field of ``E`` - OUTPUT: - - (polynomial) The `\gcd` of ``psi`` and the 2-torsion polynomial - of ``E``. + OUTPUT: polynomial; the `\gcd` of ``psi`` and the 2-torsion polynomial of ``E`` EXAMPLES: @@ -548,14 +542,13 @@ class EllipticCurveIsogeny(EllipticCurveHom): INPUT: - - ``E`` -- an elliptic curve, the domain of the isogeny to - initialize. + - ``E`` -- an elliptic curve; the domain of the isogeny to initialize - - ``kernel`` -- a kernel: either a point on ``E``, a list of + - ``kernel`` -- a kernel; either a point on ``E``, a list of points on ``E``, a monic kernel polynomial, or ``None``. If initializing from a domain/codomain, this must be ``None``. - - ``codomain`` -- an elliptic curve (default: ``None``). + - ``codomain`` -- an elliptic curve (default: ``None``) - If ``kernel`` is ``None``, then ``degree`` must be given as well and the given ``codomain`` must be the codomain of a cyclic, @@ -566,7 +559,7 @@ class EllipticCurveIsogeny(EllipticCurveHom): this case, the isogeny is post-composed with an isomorphism so that the codomain equals the given curve. - - ``degree`` -- an integer (default: ``None``). + - ``degree`` -- integer (default: ``None``) - If ``kernel`` is ``None``, then this is the degree of the isogeny from ``E`` to ``codomain``. @@ -575,20 +568,20 @@ class EllipticCurveIsogeny(EllipticCurveHom): whether or not to skip a `\gcd` of the given kernel polynomial with the two-torsion polynomial of ``E``. - - ``model`` -- a string (default: ``None``). Supported values + - ``model`` -- string (default: ``None``); supported values (cf. :func:`~sage.schemes.elliptic_curves.ell_field.compute_model`): - - ``"minimal"``: If ``E`` is a curve over the rationals or + - ``'minimal'`` -- if ``E`` is a curve over the rationals or over a number field, then the codomain is a global minimal model where this exists. - - ``"short_weierstrass"``: The codomain is a short Weierstrass curve, + - ``'short_weierstrass'`` -- the codomain is a short Weierstrass curve, assuming one exists. - - ``"montgomery"``: The codomain is an (untwisted) Montgomery + - ``'montgomery'`` -- the codomain is an (untwisted) Montgomery curve, assuming one exists over this field. - - ``check`` (default: ``True``) -- check whether the input is valid. + - ``check`` -- boolean (default: ``True``); check whether the input is valid. Setting this to ``False`` can lead to significant speedups. EXAMPLES: @@ -1104,9 +1097,7 @@ def _eval(self, P): - ``P`` -- a sequence of 3 coordinates defining a point on ``self`` - OUTPUT: - - The result of evaluating ``self`` at the given point. + OUTPUT: the result of evaluating ``self`` at the given point EXAMPLES:: @@ -1255,7 +1246,6 @@ def _call_(self, P): (0 : 1 : 1) sage: Q.order() +Infinity - """ if P.is_zero(): return self._codomain(0) @@ -1466,7 +1456,7 @@ def _latex_(self): Return the rational maps of the isogeny as a LaTeX string. This function returns a latex string representing the isogeny - self as the `x` and `y` coordinate rational functions. + ``self`` as the `x` and `y` coordinate rational functions. EXAMPLES:: @@ -1647,7 +1637,7 @@ def __initialize_rational_maps(self, precomputed_maps=None): INPUT: - - ``precomputed_maps`` (default ``None``) -- tuple `(X,Y)` + - ``precomputed_maps`` -- (default: ``None``) tuple `(X,Y)` of rational functions in `x,y` EXAMPLES: @@ -2903,7 +2893,7 @@ def scaling_factor(self): Check for :issue:`36638`:: - sage: phi.scaling_factor().parent() # needs sage.rings.finite_rings + sage: phi.scaling_factor().parent() # needs sage.rings.finite_rings Finite Field in z2 of size 257^2 ALGORITHM: The "inner" isogeny is normalized by construction, @@ -3443,8 +3433,7 @@ def compute_isogeny_bmss(E1, E2, l): sprec = 8 while sprec < 4 * l: assert sprec % 2 == 0 - if sprec > 2 * l: - sprec = 2 * l + sprec = min(sprec, 2 * l) # s1 => s1 + x^k s2 # 2 s1' s2' - dG/dS(x, s1) s2 = G(x, s1) - s1'2 s1 = S @@ -3475,6 +3464,7 @@ def compute_isogeny_bmss(E1, E2, l): ker = Rx(Q).reverse(degree=l//2) return ker.monic() + def compute_isogeny_stark(E1, E2, ell): r""" Return the kernel polynomial of an isogeny of degree ``ell`` @@ -3482,20 +3472,18 @@ def compute_isogeny_stark(E1, E2, ell): INPUT: - - ``E1`` -- domain elliptic curve in short Weierstrass form + - ``E1`` -- domain elliptic curve in short Weierstrass form - - ``E2`` -- codomain elliptic curve in short Weierstrass form + - ``E2`` -- codomain elliptic curve in short Weierstrass form - ``ell`` -- the degree of an isogeny from ``E1`` to ``E2`` - OUTPUT: - - The kernel polynomial of an isogeny from ``E1`` to ``E2``. + OUTPUT: the kernel polynomial of an isogeny from ``E1`` to ``E2`` .. NOTE:: If there is no degree-``ell``, cyclic, separable, normalized - isogeny from ``E1`` to ``E2``, a :class:`ValueError` will be + isogeny from ``E1`` to ``E2``, a :exc:`ValueError` will be raised. ALGORITHM: @@ -3603,24 +3591,22 @@ def compute_isogeny_kernel_polynomial(E1, E2, ell, algorithm=None): INPUT: - - ``E1`` -- domain elliptic curve in short Weierstrass form + - ``E1`` -- domain elliptic curve in short Weierstrass form - - ``E2`` -- codomain elliptic curve in short Weierstrass form + - ``E2`` -- codomain elliptic curve in short Weierstrass form - - ``ell`` -- the degree of an isogeny from ``E1`` to ``E2`` + - ``ell`` -- the degree of an isogeny from ``E1`` to ``E2`` - ``algorithm`` -- ``None`` (default, choose automatically) or - ``"bmss"`` (:func:`compute_isogeny_bmss`) or - ``"stark"`` (:func:`compute_isogeny_stark`) - - OUTPUT: + ``'bmss'`` (:func:`compute_isogeny_bmss`) or + ``'stark'`` (:func:`compute_isogeny_stark`) - The kernel polynomial of an isogeny from ``E1`` to ``E2``. + OUTPUT: the kernel polynomial of an isogeny from ``E1`` to ``E2`` .. NOTE:: If there is no degree-``ell``, cyclic, separable, normalized - isogeny from ``E1`` to ``E2``, a :class:`ValueError` will be + isogeny from ``E1`` to ``E2``, a :exc:`ValueError` will be raised. EXAMPLES:: @@ -3682,6 +3668,7 @@ def compute_isogeny_kernel_polynomial(E1, E2, ell, algorithm=None): raise NotImplementedError(f'unknown algorithm {algorithm}') + def compute_intermediate_curves(E1, E2): r""" Return intermediate curves and isomorphisms. @@ -3778,6 +3765,7 @@ def compute_intermediate_curves(E1, E2): post_iso = WeierstrassIsomorphism(E2w, urst, E2) return E1w, E2w, pre_iso, post_iso + def compute_sequence_of_maps(E1, E2, ell): r""" Return intermediate curves, isomorphisms and kernel polynomial. @@ -3877,6 +3865,7 @@ def compute_sequence_of_maps(E1, E2, ell): # Utility functions for manipulating isogeny degree matrices + def fill_isogeny_matrix(M): """ Return a filled isogeny matrix giving all degrees from one giving only prime degrees. @@ -3884,14 +3873,14 @@ def fill_isogeny_matrix(M): INPUT: - ``M`` -- a square symmetric matrix whose off-diagonal `i`, `j` - entry is either a prime `l` if the `i`'th and `j`'th curves + entry is either a prime `l` if the `i`-th and `j`-th curves have an `l`-isogeny between them, otherwise `0` OUTPUT: - (matrix) A square matrix with entries `1` on the diagonal, and in + A square matrix with entries `1` on the diagonal, and in general the `i`, `j` entry is `d>0` if `d` is the minimal degree - of an isogeny from the `i`'th to the `j`'th curve. + of an isogeny from the `i`-th to the `j`-th curve. EXAMPLES:: @@ -3936,6 +3925,7 @@ def pr(M1, M2): M2 = pr(M0, M1) return M1 + def unfill_isogeny_matrix(M): """ Reverses the action of ``fill_isogeny_matrix``. @@ -3946,7 +3936,7 @@ def unfill_isogeny_matrix(M): OUTPUT: - (matrix) A square symmetric matrix obtained from ``M`` by + A square symmetric matrix obtained from ``M`` by replacing non-prime entries with `0`. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/ell_egros.py b/src/sage/schemes/elliptic_curves/ell_egros.py old mode 100644 new mode 100755 index 7004995aec6..365070a3809 --- a/src/sage/schemes/elliptic_curves/ell_egros.py +++ b/src/sage/schemes/elliptic_curves/ell_egros.py @@ -95,7 +95,7 @@ def is_possible_j(j, S=[]): r""" - Tests if the rational `j` is a possible `j`-invariant of an + Test if the rational `j` is a possible `j`-invariant of an elliptic curve with good reduction outside `S`. .. NOTE:: @@ -155,7 +155,7 @@ def egros_from_j_1728(S=[]): INPUT: - - S -- list of primes (default: empty list). + - ``S`` -- list of primes (default: empty list) .. NOTE:: @@ -199,7 +199,7 @@ def egros_from_j_0(S=[]): INPUT: - - S -- list of primes (default: empty list). + - ``S`` -- list of primes (default: empty list) .. NOTE:: @@ -247,9 +247,9 @@ def egros_from_j(j, S=[]): INPUT: - - j -- a rational number. + - ``j`` -- a rational number - - S -- list of primes (default: empty list). + - ``S`` -- list of primes (default: empty list) .. NOTE:: @@ -302,9 +302,9 @@ def egros_from_jlist(jlist, S=[]): INPUT: - - j -- list of rational numbers. + - ``j`` -- list of rational numbers - - S -- list of primes (default: empty list). + - ``S`` -- list of primes (default: empty list) .. NOTE:: @@ -341,19 +341,19 @@ def egros_from_jlist(jlist, S=[]): def egros_get_j(S=[], proof=None, verbose=False): r""" - Returns a list of rational `j` such that all elliptic curves + Return a list of rational `j` such that all elliptic curves defined over `\QQ` with good reduction outside `S` have `j`-invariant in the list, sorted by height. INPUT: - - ``S`` -- list of primes (default: empty list). + - ``S`` -- list of primes (default: empty list) - - ``proof`` -- ``True``/``False`` (default ``True``): the MW basis for - auxiliary curves will be computed with this proof flag. + - ``proof`` -- boolean (default: ``True``); the MW basis for + auxiliary curves will be computed with this proof flag - - ``verbose`` -- ``True``/``False`` (default ``False````): if ``True``, some - details of the computation will be output. + - ``verbose`` -- boolean (default: ``False``); if ``True``, some + details of the computation will be output .. NOTE:: diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py old mode 100644 new mode 100755 index 237c838b3d4..a63dbf57809 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -27,6 +27,7 @@ from .ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel from . import ell_generic + class EllipticCurve_field(ell_generic.EllipticCurve_generic, ProjectivePlaneCurve_field): def __init__(self, R, data, category=None): @@ -101,14 +102,14 @@ def quadratic_twist(self, D=None): INPUT: - - ``D`` (default None) the twisting parameter (see below). + - ``D`` -- (default: ``None``) the twisting parameter (see below) In characteristics other than 2, `D` must be nonzero, and the - twist is isomorphic to self after adjoining `\sqrt(D)` to the + twist is isomorphic to ``self`` after adjoining `\sqrt(D)` to the base. In characteristic 2, `D` is arbitrary, and the twist is - isomorphic to self after adjoining a root of `x^2+x+D` to the + isomorphic to ``self`` after adjoining a root of `x^2+x+D` to the base. In characteristic 2 when `j=0`, this is not implemented. @@ -267,7 +268,7 @@ def quartic_twist(self, D): INPUT: - - ``D`` (must be nonzero) -- the twisting parameter + - ``D`` -- (must be nonzero) the twisting parameter .. NOTE:: @@ -311,7 +312,7 @@ def sextic_twist(self, D): INPUT: - - ``D`` (must be nonzero) -- the twisting parameter + - ``D`` -- (must be nonzero) the twisting parameter .. NOTE:: @@ -357,7 +358,7 @@ def is_quadratic_twist(self, other): INPUT: - - ``other`` -- an elliptic curve with the same base field as ``self``. + - ``other`` -- an elliptic curve with the same base field as ``self`` OUTPUT: @@ -513,7 +514,7 @@ def is_quartic_twist(self, other): INPUT: - - ``other`` -- an elliptic curves with the same base field as self. + - ``other`` -- an elliptic curves with the same base field as ``self`` OUTPUT: @@ -582,7 +583,7 @@ def is_sextic_twist(self, other): INPUT: - - ``other`` -- an elliptic curves with the same base field as self. + - ``other`` -- an elliptic curves with the same base field as ``self`` OUTPUT: @@ -647,22 +648,21 @@ def is_sextic_twist(self, other): def descend_to(self, K, f=None): r""" - Given an elliptic curve self defined over a field `L` and a + Given an elliptic curve ``self`` defined over a field `L` and a subfield `K` of `L`, return all elliptic curves over `K` which - are isomorphic over `L` to self. + are isomorphic over `L` to ``self``. INPUT: - - `K` -- a field which embeds into the base field `L` of self. + - ``K`` -- a field which embeds into the base field `L` of ``self`` - - `f` (optional) -- an embedding of `K` into `L`. Ignored if - `K` is `\QQ`. + - ``f`` -- (optional) an embedding of `K` into `L`; ignored if + `K` is `\QQ` OUTPUT: A list (possibly empty) of elliptic curves defined over `K` - which are isomorphic to self over `L`, up to isomorphism over - `K`. + which are isomorphic to ``self`` over `L`, up to isomorphism over `K`. .. NOTE:: @@ -824,9 +824,9 @@ def division_field(self, n, names='t', map=False, **kwds): INPUT: - - `n` -- a positive integer + - ``n`` -- positive integer - ``names`` -- (default: ``'t'``) a variable name for the division field - - ``map`` -- (default: ``False``) also return an embedding of the + - ``map`` -- boolean (default: ``False``); also return an embedding of the :meth:`base_field` into the resulting field - ``kwds`` -- additional keyword arguments passed to :func:`~sage.rings.polynomial.polynomial_element.Polynomial.splitting_field` @@ -1077,7 +1077,7 @@ def division_field(self, n, names='t', map=False, **kwds): if n == 2 or f.is_constant(): # For n = 2, the division field is the splitting field of # the division polynomial. - # If f is a non-zero constant, the n-torsion is trivial: + # If f is a nonzero constant, the n-torsion is trivial: # This means the curve must be supersingular and n == p. return f.splitting_field(names, map=map, **kwds) @@ -1197,7 +1197,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al INPUT: - - ``kernel`` -- a kernel: either a point on this curve, a list of + - ``kernel`` -- a kernel; either a point on this curve, a list of points on this curve, a monic kernel polynomial, or ``None``. If initializing from a codomain, this must be ``None``. @@ -1212,7 +1212,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al this case, the isogeny is post-composed with an isomorphism so that the codomain equals the given curve. - - ``degree`` -- an integer (default: ``None``). + - ``degree`` -- integer (default: ``None``). - If ``kernel`` is ``None``, then this is the degree of the isogeny from this curve to ``codomain``. @@ -1221,58 +1221,58 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al whether or not to skip a `\gcd` of the given kernel polynomial with the two-torsion polynomial of this curve. - - ``model`` -- a string (default: ``None``). Supported values + - ``model`` -- string (default: ``None``); supported values (cf. :func:`~sage.schemes.elliptic_curves.ell_field.compute_model`): - - ``"minimal"``: If ``self`` is a curve over the rationals or + - ``'minimal'``: if ``self`` is a curve over the rationals or over a number field, then the codomain is a global minimal model where this exists. - - ``"short_weierstrass"``: The codomain is a short Weierstrass curve, + - ``'short_weierstrass'``: the codomain is a short Weierstrass curve, assuming one exists. - - ``"montgomery"``: The codomain is an (untwisted) Montgomery + - ``'montgomery'``: the codomain is an (untwisted) Montgomery curve, assuming one exists over this field. - - ``check`` (default: ``True``) -- check whether the input is valid. + - ``check`` -- boolean (default: ``True``); check whether the input is valid. Setting this to ``False`` can lead to significant speedups. - - ``algorithm`` -- string (optional). The possible choices are: + - ``algorithm`` -- string (optional); the possible choices are: - - ``"velusqrt"``: Use + - ``'velusqrt'``: Use :class:`~sage.schemes.elliptic_curves.hom_velusqrt.EllipticCurveHom_velusqrt`. - - ``"factored"``: Use + - ``'factored'``: Use :class:`~sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite` to decompose the isogeny into prime-degree steps. - - ``"traditional"``: Use + - ``'traditional'``: Use :class:`~sage.schemes.elliptic_curves.ell_curve_isogeny.EllipticCurveIsogeny`. When ``algorithm`` is not specified, and ``kernel`` is not ``None``, an algorithm is selected using the following criteria: - - if ``kernel`` is a list of multiple points, ``"factored"`` is selected. + - if ``kernel`` is a list of multiple points, ``'factored'`` is selected. - If ``kernel`` is a single point, or a list containing a single point: - - if the order of the point is unknown, ``"traditional"`` is selected. + - if the order of the point is unknown, ``'traditional'`` is selected. - - If the order is known and composite, ``"factored"`` is selected. + - If the order is known and composite, ``'factored'`` is selected. - - If the order is known and prime, a choice between ``"velusqrt"`` and - ``"traditional"`` is done according to the ``velu_sqrt_bound`` + - If the order is known and prime, a choice between ``'velusqrt'`` and + ``'traditional'`` is done according to the ``velu_sqrt_bound`` parameter (see below). - If none of the previous apply, ``"traditional"`` is selected. + If none of the previous apply, ``'traditional'`` is selected. - - ``velu_sqrt_bound`` -- an integer (default: ``None``). Establish the highest - (prime) degree for which the ``"traditional"`` algorithm should be selected - instead of ``"velusqrt"``. If ``None``, the default value from + - ``velu_sqrt_bound`` -- integer (default: ``None``); establish the highest + (prime) degree for which the ``'traditional'`` algorithm should be selected + instead of ``'velusqrt'``. If ``None``, the default value from :class:`~sage.schemes.elliptic_curves.hom_velusqrt._VeluBoundObj` is used. This value is initially set to 1000, but can be modified by the user. If an integer is supplied and the isogeny computation goes through the - ``"factored"`` algorithm, the same integer is supplied to each factor. + ``'factored'`` algorithm, the same integer is supplied to each factor. The ``degree`` parameter is not supported when an ``algorithm`` is specified. @@ -1321,7 +1321,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al sage: E = EllipticCurve(GF(2^32 - 5), [170246996, 2036646110]) # needs sage.rings.finite_rings sage: P = E.lift_x(2) # needs sage.rings.finite_rings - sage: E.isogeny(P, algorithm="factored") # needs sage.rings.finite_rings + sage: E.isogeny(P, algorithm='factored') # needs sage.rings.finite_rings Composite morphism of degree 1073721825 = 3^4*5^2*11*19*43*59: From: Elliptic Curve defined by y^2 = x^3 + 170246996*x + 2036646110 over Finite Field of size 4294967291 @@ -1384,7 +1384,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al To: Elliptic Curve defined by y^2 = x^3 + 95*x + 68 over Finite Field of size 97 sage: _velu_sqrt_bound.set(1000) # Reset bound - If the order of the point is unknown, fall back to ``"traditional"``:: + If the order of the point is unknown, fall back to ``'traditional'``:: sage: E = EllipticCurve_from_j(GF(97)(42)) sage: P = E(2, 39) @@ -1427,7 +1427,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al sage: phi.codomain()._order 170141183460469231746191640949390434666 - Check that ``"factored"`` recursively apply `velu_sqrt_bound`:: + Check that ``'factored'`` recursively apply `velu_sqrt_bound`:: sage: from sage.schemes.elliptic_curves.hom_velusqrt import _velu_sqrt_bound sage: _velu_sqrt_bound.get() @@ -1496,8 +1496,9 @@ def isogeny_codomain(self, kernel): INPUT: - - ``kernel`` -- Either a list of points in the kernel of the isogeny, - or a kernel polynomial (specified as either a univariate polynomial or a coefficient list.) + - ``kernel`` -- either a list of points in the kernel of the isogeny, + or a kernel polynomial (specified as either a univariate polynomial + or a coefficient list) OUTPUT: @@ -1547,16 +1548,16 @@ def kernel_polynomial_from_point(self, P, *, algorithm=None): sage: E.kernel_polynomial_from_point(K) x^21 + 7*x^20 + 22*x^19 + 4*x^18 + 7*x^17 + 81*x^16 + 41*x^15 + 68*x^14 + 18*x^13 + 58*x^12 + 31*x^11 + 26*x^10 + 62*x^9 + 20*x^8 + 73*x^7 + 23*x^6 + 66*x^5 + 79*x^4 + 12*x^3 + 40*x^2 + 50*x + 93 - The ``"minpoly"`` algorithm is often much faster than the - ``"basic"`` algorithm:: + The ``'minpoly'`` algorithm is often much faster than the + ``'basic'`` algorithm:: sage: from sage.schemes.elliptic_curves.ell_field import EllipticCurve_field, point_of_order sage: p = 2^127 - 1 sage: E = EllipticCurve(GF(p), [1,0]) - sage: P = point_of_order(E, 31) - sage: %timeit E.kernel_polynomial_from_point(P, algorithm='basic') # not tested + sage: P = point_of_order(E, 31) # long time (8.5s) + sage: %timeit E.kernel_polynomial_from_point(P, algorithm='basic') # not tested 4.38 ms ± 13.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) - sage: %timeit E.kernel_polynomial_from_point(P, algorithm='minpoly') # not tested + sage: %timeit E.kernel_polynomial_from_point(P, algorithm='minpoly') # not tested 854 µs ± 1.56 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each) Example of finding all the rational isogenies using this method:: @@ -1587,13 +1588,13 @@ def kernel_polynomial_from_point(self, P, *, algorithm=None): ALGORITHM: - - The ``"basic"`` algorithm is to multiply together all the linear + - The ``'basic'`` algorithm is to multiply together all the linear factors `(X - x([i]P))` of the kernel polynomial using a product tree, then converting the result to the base field of the curve. Its complexity is `\widetilde O(\ell k)` where `k` is the extension degree. - - The ``"minpoly"`` algorithm is + - The ``'minpoly'`` algorithm is [EPSV2023]_, Algorithm 4 (``KernelPolynomialFromIrrationalX``). Over finite fields, its complexity is `O(\ell k) + \widetilde O(\ell)` where `k` is the extension degree. @@ -1648,7 +1649,7 @@ def kernel_polynomial_from_divisor(self, f, l, *, check=True): defined by `f`. If the given polynomial does not define a rational subgroup, a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. This method is currently only implemented for prime `l`. @@ -1738,14 +1739,14 @@ def isogenies_prime_degree(self, l=None, max_l=31): INPUT: - - ``l`` -- a prime or a list of primes. + - ``l`` -- a prime or a list of primes - ``max_l`` -- (default: 31) a bound on the primes to be tested. - This is only used if ``l`` is None. + This is only used if ``l`` is ``None``. OUTPUT: - (list) All separable `l`-isogenies for the given `l` with domain self. + (list) All separable `l`-isogenies for the given `l` with domain ``self``. ALGORITHM: @@ -2018,24 +2019,22 @@ def isogenies_prime_degree(self, l=None, max_l=31): def is_isogenous(self, other, field=None): """ - Return whether or not self is isogenous to other. + Return whether or not ``self`` is isogenous to ``other``. INPUT: - - ``other`` -- another elliptic curve. + - ``other`` -- another elliptic curve - - ``field`` (default None) -- Currently not implemented. A + - ``field`` -- (default: ``None``) currently not implemented. A field containing the base fields of the two elliptic curves onto which the two curves may be extended to test if they are isogenous over this field. By default ``is_isogenous`` will not try to find this field unless one of the curves can be - be extended into the base field of the other, in which case + be extended into the base field of the ``other``, in which case it will test over the larger base field. - OUTPUT: - - (bool) True if there is an isogeny from curve ``self`` to - curve ``other`` defined over ``field``. + OUTPUT: boolean; ``True`` if there is an isogeny from curve ``self`` to + curve ``other`` defined over ``field`` METHOD: @@ -2083,9 +2082,9 @@ def weierstrass_p(self, prec=20, algorithm=None): - ``prec`` -- precision - - ``algorithm`` -- string or ``None`` (default: ``None``): - a choice of algorithm among ``"pari"``, ``"fast"``, ``"quadratic"``; - or ``None`` to let this function determine the best algorithm to use. + - ``algorithm`` -- string or ``None`` (default: ``None``); + a choice of algorithm among ``'pari'``, ``'fast'``, ``'quadratic'`` + or ``None`` to let this function determine the best algorithm to use OUTPUT: @@ -2129,7 +2128,7 @@ def hasse_invariant(self): characteristic, and is an element of the field which is zero if and only if the curve is supersingular. Over a field of characteristic zero, where the Hasse invariant is undefined, - a ``ValueError`` is raised. + a :exc:`ValueError` is raised. EXAMPLES:: @@ -2214,7 +2213,7 @@ class of curves. If the j-invariant is not unique in the isogeny class, append ``*`` to it to indicate a twist. Otherwise, if ``False`` label vertices by the equation of a representative curve. - OUTPUT: A :class:`Graph` or :class:`DiGraph`. + OUTPUT: a :class:`Graph` or :class:`DiGraph` EXAMPLES: @@ -2400,8 +2399,8 @@ class of curves. If the j-invariant is not unique in the isogeny else: from sage.graphs.graph import Graph as GraphType - G = GraphType(A, format="adjacency_matrix", - data_structure="static_sparse") + G = GraphType(A, format='adjacency_matrix', + data_structure='static_sparse') # inplace relabelling is necessary for static_sparse graphs GL = G.relabel(labels, inplace=False) return GL @@ -2456,26 +2455,24 @@ def compute_model(E, name): INPUT: - - ``E`` (elliptic curve) + - ``E`` -- elliptic curve - - ``name`` (string) -- current options: + - ``name`` -- string; current options: - - ``"minimal"``: Return a global minimal model of ``E`` if it + - ``'minimal'``: Return a global minimal model of ``E`` if it exists, and a semi-global minimal model otherwise. For this choice, ``E`` must be defined over a number field. See :meth:`~sage.schemes.elliptic_curves.ell_number_field.EllipticCurve_number_field.global_minimal_model`. - - ``"short_weierstrass"``: Return a short Weierstrass model of ``E`` + - ``'short_weierstrass'``: Return a short Weierstrass model of ``E`` assuming one exists. See :meth:`~sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.short_weierstrass_model`. - - ``"montgomery"``: Return an (untwisted) Montgomery model of ``E`` + - ``'montgomery'``: Return an (untwisted) Montgomery model of ``E`` assuming one exists over this field. See :meth:`~sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.montgomery_model`. - OUTPUT: - - An elliptic curve of the specified type isomorphic to `E`. + OUTPUT: an elliptic curve of the specified type isomorphic to `E` EXAMPLES:: @@ -2505,6 +2502,7 @@ def compute_model(E, name): raise NotImplementedError(f'cannot compute {name} model') + def point_of_order(E, n): r""" Given an elliptic curve `E` over a finite field or a number field diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py old mode 100644 new mode 100755 index a6e9cf2e845..905cc63e149 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -15,6 +15,8 @@ - Lorenz Panny, John Cremona (2023-02): ``.twists()`` - Lorenz Panny (2023): ``special_supersingular_curve()`` + +- Martin Grenouilloux, Gareth Ma (2024-09): ``EllipticCurve_with_prime_order()`` """ # **************************************************************************** @@ -96,7 +98,7 @@ def plot(self, *args, **kwds): INPUT: - ``*args``, ``**kwds`` -- all other options are passed - to the circle graphing primitive. + to the circle graphing primitive EXAMPLES:: @@ -240,11 +242,9 @@ def count_points(self, n=1): INPUT: - - ``n`` (int) -- a positive integer - - OUTPUT: + - ``n`` -- positive integer - If `n=1`, returns the cardinality of the curve over its base field. + OUTPUT: if `n=1`, returns the cardinality of the curve over its base field If `n>1`, returns a list `[c_1, c_2, ..., c_n]` where `c_d` is the cardinality of the curve over the extension of degree `d` @@ -296,9 +296,9 @@ def random_element(self): Choose the point at infinity with probability `1/(2q + 1)`. Otherwise, take a random element from the field as x-coordinate - and compute the possible y-coordinates. Return the i'th + and compute the possible y-coordinates. Return the i-th possible y-coordinate, where i is randomly chosen to be 0 or 1. - If the i'th y-coordinate does not exist (either there is no + If the i-th y-coordinate does not exist (either there is no point with the given x-coordinate or we hit a 2-torsion point with i == 1), try again. @@ -431,24 +431,24 @@ def cardinality(self, algorithm=None, extension_degree=1): - ``algorithm`` -- (optional) string: - - ``'pari'`` -- use the PARI C-library function ``ellcard``. + - ``'pari'`` -- use the PARI C-library function ``ellcard`` - ``'bsgs'`` -- use the baby-step giant-step method as implemented in Sage, with the Cremona-Sutherland version - of Mestre's trick. + of Mestre's trick - - ``'exhaustive'`` -- naive point counting. + - ``'exhaustive'`` -- naive point counting - ``'subfield'`` -- reduce to a smaller field, provided that - the j-invariant lies in a subfield. + the j-invariant lies in a subfield - ``'all'`` -- compute cardinality with both ``'pari'`` and ``'bsgs'``; return result if they agree or raise a - ``AssertionError`` if they do not + :exc:`AssertionError` if they do not - - ``extension_degree`` -- an integer `d` (default: 1): if the + - ``extension_degree`` -- integer `d` (default: 1); if the base field is `\GF{q}`, return the cardinality of ``self`` - over the extension `\GF{q^d}` of degree `d`. + over the extension `\GF{q^d}` of degree `d` OUTPUT: @@ -503,12 +503,12 @@ def cardinality(self, algorithm=None, extension_degree=1): sage: # needs sage.rings.finite_rings sage: k. = GF(11^100) sage: E1 = EllipticCurve(k, [3,3]) - sage: N1 = E1.cardinality(algorithm="subfield"); N1 + sage: N1 = E1.cardinality(algorithm='subfield'); N1 137806123398222701841183371720896367762643312000384671846835266941791510341065565176497846502742959856128 sage: E1.cardinality_pari() == N1 True sage: E2 = E1.quadratic_twist() - sage: N2 = E2.cardinality(algorithm="subfield"); N2 + sage: N2 = E2.cardinality(algorithm='subfield'); N2 137806123398222701841183371720896367762643312000384656816094284101308193849980588362304472492174093035876 sage: E2.cardinality_pari() == N2 True @@ -823,7 +823,7 @@ def gens(self): the same each time, although they should remain fixed within a single run of Sage unless :meth:`abelian_group` is called.) - OUTPUT: a tuple of points on the curve. + OUTPUT: a tuple of points on the curve - if the group is trivial: an empty tuple. @@ -928,7 +928,7 @@ def __iter__(self): def __getitem__(self, n): """ - Return the n'th point in self's __points list. + Return the n-th point in ``self``'s ``__points`` list. This enables users to iterate over the curve's point set. @@ -1163,28 +1163,27 @@ def torsion_basis(self, n): def is_isogenous(self, other, field=None, proof=True): """ - Return whether or not self is isogenous to other. + Return whether or not ``self`` is isogenous to ``other``. INPUT: - - ``other`` -- another elliptic curve. + - ``other`` -- another elliptic curve - - ``field`` (default None) -- a field containing the base + - ``field`` -- (default: ``None``) a field containing the base fields of the two elliptic curves into which the two curves may be extended to test if they are isogenous over this field. By default is_isogenous will not try to find this field unless one of the curves can be extended into the base - field of the other, in which case it will test over the + field of the ``other``, in which case it will test over the larger base field. - - ``proof`` (default: ``True``) -- this parameter is here only to - be consistent with versions for other types of elliptic - curves. + - ``proof`` -- boolean (default: ``True``); this parameter is here only + to be consistent with versions for other types of elliptic curves OUTPUT: - (bool) True if there is an isogeny from curve ``self`` to - curve ``other`` defined over ``field``. + boolean; ``True`` if there is an isogeny from curve ``self`` to + curve ``other`` defined over ``field`` EXAMPLES:: @@ -1286,13 +1285,13 @@ def is_isogenous(self, other, field=None, proof=True): def is_supersingular(self, proof=True): r""" - Return True if this elliptic curve is supersingular, else False. + Return ``True`` if this elliptic curve is supersingular, else ``False``. INPUT: - - ``proof`` (boolean, default: ``True``) -- If True, returns a - proved result. If False, then a return value of False is - certain but a return value of True may be based on a + - ``proof``-- boolean (default: ``True``); if ``True``, returns a + proved result. If ``False``, then a return value of ``False`` is + certain but a return value of ``True`` may be based on a probabilistic test. See the documentation of the function :meth:`is_j_supersingular` for more details. @@ -1320,13 +1319,13 @@ def is_supersingular(self, proof=True): def is_ordinary(self, proof=True): r""" - Return True if this elliptic curve is ordinary, else False. + Return ``True`` if this elliptic curve is ordinary, else ``False``. INPUT: - - ``proof`` (boolean, default: ``True``) -- If True, returns a - proved result. If False, then a return value of True is - certain but a return value of False may be based on a + - ``proof``-- boolean (default: ``True``); if ``True``, returns a + proved result. If ``False``, then a return value of ``True`` is + certain but a return value of ``False`` may be based on a probabilistic test. See the documentation of the function :meth:`is_j_supersingular` for more details. @@ -1344,6 +1343,113 @@ def is_ordinary(self, proof=True): """ return not is_j_supersingular(self.j_invariant(), proof=proof) + def has_order(self, value, num_checks=8): + r""" + Return ``True`` if the curve has order ``value``. + + INPUT: + + - ``value`` -- integer in the Hasse-Weil range for this curve + + - ``num_checks``-- integer (default: `8`); the number of times to check + whether ``value`` times a random point on this curve equals the + identity. If ``value`` is a prime and the curve is over a field of + order at least `5`, it is sufficient to pass in ``num_checks=1`` - + see the examples below. + + .. NOTE:: + + Since the method is probabilistic, there is a possibility for the + method to yield false positives (i.e. returning ``True`` even when + the result is ``False``). Even worse, it is possible for this to + happen even when ``num_checks`` is increased arbitrarily. See below + for an example and :issue:`38617` for an open discussion. + + EXAMPLES: + + For curves over small finite fields, the order is computed and compared + directly:: + + sage: E = EllipticCurve(GF(7), [0, 1]) + sage: E.order() + 12 + sage: E.has_order(12, num_checks=0) + True + sage: E.has_order(11, num_checks=0) + False + sage: E.has_order(13, num_checks=0) + False + + This tests the method on a random curve:: + + sage: # long time (10s) + sage: p = random_prime(2**128, lbound=2**127) + sage: K = GF((p, 2), name="a") + sage: E = EllipticCurve(K, [K.random_element() for _ in range(2)]) + sage: N = E.order() + sage: E.has_order(N, num_checks=20) + True + sage: E.has_order(N + 1) + False + + This demonstrates the bug mentioned in the NOTE above. The last return + value should be ``False`` after :issue:`38617` is fixed:: + + sage: E = EllipticCurve(GF(5443568676570036275321323), [0, 13]) + sage: N = 2333145661241 + sage: E.order() == N^2 + True + sage: E.has_order(N^2) + True + sage: del E._order + sage: E.has_order(N^2 + N) + True + + Due to the nature of the algorithm (testing multiple of points) and the Hasse-Weil bound, we see that for testing prime orders, ``num_checks=1`` is sufficient:: + + sage: p = random_prime(1000) + sage: E = EllipticCurve(GF(p), j=randrange(p)) + sage: q = random_prime(p + 20, lbound=p - 20) + sage: E.has_order(q, num_checks=20) == E.has_order(q, num_checks=1) + True + + AUTHORS: + + - Mariah Lenox (2011-02-16): Initial implementation + + - Gareth Ma (2024-01-21): Fix bug for small curves + """ + q = self.base_field().order() + a, b = Hasse_bounds(q, 1) + if not a <= value <= b: + return False + + # For really small values, the random tests are too weak to detect wrong + # orders So we go with computing directly instead. + # In #38341, the bound has been increased to a large value (2^64), but + # it should be decreased (to ~100) after bug #38617 is fixed. + if q <= 2**64 or hasattr(self, "_order"): + return self.order() == value + + # This might be slow + # if value.is_prime(): + # num_checks = 1 + + # Is value * random == identity? + for _ in range(num_checks): + while True: + G = self.random_point() + if not G.is_zero(): + break + + if not (value * G).is_zero(): + return False + + # TODO: uncomment this and remove the line in `set_order` after 38617 is fixed. + # self._order = value + + return True + def set_order(self, value, *, check=True, num_checks=8): r""" Set the value of ``self._order`` to ``value``. @@ -1353,19 +1459,16 @@ def set_order(self, value, *, check=True, num_checks=8): INPUT: - - ``value`` -- integer in the Hasse-Weil range for this - curve. + - ``value`` -- integer in the Hasse-Weil range for this curve - - ``check`` (boolean, default: ``True``) -- whether or - not to run sanity checks on the input. + - ``check``-- boolean (default: ``True``); whether or + not to run sanity checks on the input - - ``num_checks`` (integer, default: 8) -- if ``check`` is + - ``num_checks``-- integer (default: `8`); if ``check`` is ``True``, the number of times to check whether ``value`` - times a random point on this curve equals the identity. - - OUTPUT: + times a random point on this curve equals the identity - None + OUTPUT: none EXAMPLES: @@ -1407,42 +1510,41 @@ def set_order(self, value, *, check=True, num_checks=8): sage: E.set_order(0) Traceback (most recent call last): ... - ValueError: Value 0 illegal (not an integer in the Hasse range) + ValueError: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 does not have order 0 sage: E.set_order(1000) Traceback (most recent call last): ... - ValueError: Value 1000 illegal (not an integer in the Hasse range) + ValueError: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 does not have order 1000 - It is also very likely an error to pass a value which is not - the actual order of this curve. How unlikely is determined by - ``num_checks``, the factorization of the actual order, and the - actual group structure:: + It is also very likely an error to pass a value which is not the actual + order of this curve. How unlikely is determined by ``num_checks``, the + factorization of the actual order, and the actual group structure:: sage: E = EllipticCurve(GF(1009), [0, 1]) # This curve has order 948 sage: E.set_order(947) Traceback (most recent call last): ... - ValueError: Value 947 illegal (multiple of random point not the identity) + ValueError: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 1009 does not have order 947 - For curves over small finite fields, the order is cheap to compute, so it is computed - directly and compared:: + For curves over small finite fields, the order is cheap to compute, so + it is computed directly and compared:: sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12 sage: E.set_order(11) Traceback (most recent call last): ... - ValueError: Value 11 illegal (correct order is 12) + ValueError: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 does not have order 11 TESTS: - The previous version's random tests are not strong enough. In particular, the following used - to work:: + The previous version's random tests are not strong enough. In particular, + the following used to work:: sage: E = EllipticCurve(GF(2), [0, 0, 1, 1, 1]) # This curve has order 1 sage: E.set_order(3) Traceback (most recent call last): ... - ValueError: Value 3 illegal (correct order is 1) + ValueError: Elliptic Curve defined by y^2 + y = x^3 + x + 1 over Finite Field of size 2 does not have order 3 :: @@ -1450,12 +1552,12 @@ def set_order(self, value, *, check=True, num_checks=8): sage: E.set_order(4, num_checks=0) Traceback (most recent call last): ... - ValueError: Value 4 illegal (correct order is 12) + ValueError: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 does not have order 4 sage: E.order() 12 - .. TODO:: Add provable correctness check by computing the abelian group structure and - comparing. + .. TODO:: Add provable correctness check by computing the abelian group + structure and comparing. AUTHORS: @@ -1465,24 +1567,8 @@ def set_order(self, value, *, check=True, num_checks=8): """ value = Integer(value) - if check: - # Is value in the Hasse range? - q = self.base_field().order() - a,b = Hasse_bounds(q,1) - if not a <= value <= b: - raise ValueError(f"Value {value} illegal (not an integer in the Hasse range)") - - # For really small values, the random tests are too weak to detect wrong orders - # So we go with computing directly instead. - if q <= 100: - if self.order() != value: - raise ValueError(f"Value {value} illegal (correct order is {self.order()})") - - # Is value*random == identity? - for _ in range(num_checks): - G = self.random_point() - if value * G != self(0): - raise ValueError(f"Value {value} illegal (multiple of random point not the identity)") + if check and not self.has_order(value, num_checks=num_checks): + raise ValueError(f"{self} does not have order {value}") # TODO: It might help some of PARI's algorithms if we # could copy this over to the .pari_curve() as well. @@ -1538,7 +1624,7 @@ def height_above_floor(self, ell, e): INPUT: - ``ell`` -- a prime number - - ``e`` -- a non-negative integer, the ell-adic valuation of + - ``e`` -- nonnegative integer, the `\ell`-adic valuation of the conductor the Frobenius order @@ -1565,7 +1651,6 @@ def height_above_floor(self, ell, e): -1 * 2^10 * 11 * 61 sage: E.height_above_floor(2,8) 5 - """ if self.is_supersingular(): raise ValueError("{} is not ordinary".format(self)) @@ -1606,13 +1691,13 @@ def endomorphism_discriminant_from_class_number(self, h): INPUT: - - ``h`` -- a positive integer + - ``h`` -- positive integer OUTPUT: - (integer) The discriminant of the endomorphism ring `\text{End}(E)`, if + integer; the discriminant of the endomorphism ring `\text{End}(E)`, if this has class number ``h``. If `\text{End}(E)` does not have class - number ``h``, a ``ValueError`` is raised. + number ``h``, a :exc:`ValueError` is raised. ALGORITHM: @@ -1622,7 +1707,7 @@ def endomorphism_discriminant_from_class_number(self, h): must be a multiple of `h_0`, compute the possible conductors, using :meth:`height_above_floor` for each prime `\ell` dividing the quotient `h/h_0`. If exactly one conductor `f` - remains, return `f^2D_0`, otherwise raise a ``ValueError``; + remains, return `f^2D_0`, otherwise raise a :exc:`ValueError`; this can onlyhappen when the input value of `h` was incorrect. .. NOTE:: @@ -1644,7 +1729,6 @@ def endomorphism_discriminant_from_class_number(self, h): sage: H = hilbert_class_polynomial(-671) sage: H(E.j_invariant()) == 0 and H.degree()==30 True - """ F = self.base_field() if not F.is_finite(): @@ -1876,6 +1960,7 @@ def twists(self): return [self, self.quadratic_twist(D)] + def curves_with_j_0(K): r""" Return a complete list of pairwise nonisomorphic elliptic curves with `j`-invariant 0 over the finite field `K`. @@ -1945,6 +2030,7 @@ def curves_with_j_0(K): # then you can also compute the orders! return curves + def curves_with_j_1728(K): r""" Return a complete list of pairwise nonisomorphic elliptic curves with `j`-invariant 1728 over the finite field `K`. @@ -2001,6 +2087,7 @@ def curves_with_j_1728(K): curves = [EllipticCurve(K, [D**i, 0]) for i in range(4)] return curves + def curves_with_j_0_char2(K): r""" Return a complete list of pairwise nonisomorphic elliptic curves with `j`-invariant 0 over the finite field `K` of characteristic 2. @@ -2094,6 +2181,7 @@ def curves_with_j_0_char2(K): return [EllipticCurve(K, ai) for ai in [[0,0,1,0,0], [0,0,1,0,b], [0,0,1,c,0], [0,0,a,0,0], [0,0,a,0,d], [0,0,asq,0,0], [0,0,asq,0,e]]] + def curves_with_j_0_char3(K): r""" Return a complete list of pairwise nonisomorphic elliptic curves with `j`-invariant 0 over the finite field `K` of characteristic 3. @@ -2190,6 +2278,7 @@ def curves_with_j_0_char3(K): supersingular_j_polynomials = {} + def fill_ss_j_dict(): r""" Fill the global cache of supersingular j-_polynomials. @@ -2259,6 +2348,7 @@ def fill_ss_j_dict(): supersingular_j_polynomials[283] = [212, 4, 42, 155, 38, 1, 270, 175, 172, 256, 264, 232, 50, 82, 244, 127, 148, 46, 249, 72, 59, 124, 75, 1] supersingular_j_polynomials[293] = [264, 66, 165, 144, 243, 25, 163, 210, 18, 107, 160, 153, 70, 255, 91, 211, 22, 7, 256, 50, 150, 94, 225, 60, 1] + def supersingular_j_polynomial(p, use_cache=True): r""" Return a polynomial whose roots are the supersingular @@ -2266,9 +2356,9 @@ def supersingular_j_polynomial(p, use_cache=True): INPUT: - - `p` (integer) -- a prime number. + - ``p`` -- integer; a prime number - - ``use_cache`` (boolean, default ``True``) -- use cached coefficients if they exist + - ``use_cache`` -- boolean (default: ``True``); use cached coefficients if they exist ALGORITHM: @@ -2340,22 +2430,21 @@ def supersingular_j_polynomial(p, use_cache=True): supersingular_j_polynomials[p] = R.coefficients(sparse=False) return R + def is_j_supersingular(j, proof=True): r""" - Return True if `j` is a supersingular `j`-invariant. + Return ``True`` if `j` is a supersingular `j`-invariant. INPUT: - - ``j`` (finite field element) -- an element of a finite field + - ``j`` -- finite field element - - ``proof`` (boolean, default: ``True``) -- If True, returns a proved - result. If False, then a return value of False is certain but a - return value of True may be based on a probabilistic test. See + - ``proof``-- boolean (default: ``True``); if ``True``, returns a proved + result. If ``False``, then a return value of ``False`` is certain but a + return value of ``True`` may be based on a probabilistic test. See the ALGORITHM section below for more details. - OUTPUT: - - (boolean) True if `j` is supersingular, else False. + OUTPUT: boolean; ``True`` if `j` is supersingular, else ``False`` ALGORITHM: @@ -2366,9 +2455,9 @@ def is_j_supersingular(j, proof=True): `j=1728`, the curve is supersingular if and only if `p=3` or `p\equiv2\pmod{3}`. Next, if the base field is the prime field `{\rm GF}(p)`, we check that `(p+1)P=0` for several random points - `P`, returning False if any fail: supersingular curves over `{\rm + `P`, returning ``False`` if any fail: supersingular curves over `{\rm GF}(p)` have cardinality `p+1`. If Proof is false we now return - True. Otherwise we compute the cardinality and return True if and + ``True``. Otherwise we compute the cardinality and return ``True`` if and only if it is divisible by `p`. EXAMPLES:: @@ -2475,10 +2564,13 @@ def is_j_supersingular(j, proof=True): return E.trace_of_frobenius() % p == 0 -def special_supersingular_curve(F, *, endomorphism=False): + +def special_supersingular_curve(F, q=None, *, endomorphism=False): r""" - Given a finite field ``F``, construct a "special" supersingular - elliptic curve `E` defined over ``F``. + Given a finite field ``F`` of characteristic `p`, and optionally + a positive integer `q` such that the Hilbert conductor of `-q` + and `-p` equals `p`, construct a "special" supersingular elliptic + curve `E` defined over ``F``. Such a curve @@ -2487,20 +2579,31 @@ def special_supersingular_curve(F, *, endomorphism=False): - has group structure `E(\mathbb F_p) \cong \ZZ/(p+1)` and `E(\mathbb F_{p^2}) \cong \ZZ/(p+1) \times \ZZ/(p+1)`; - - has an endomorphism `\vartheta` of small degree `q` that + - has an endomorphism `\vartheta` of degree `q` that anticommutes with the `\mathbb F_p`-Frobenius on `E`. (The significance of `\vartheta` is that any such endomorphism, together with the `\mathbb F_p`-Frobenius, generates the endomorphism algebra `\mathrm{End}(E) \otimes \QQ`.) + The complexity grows exponentially in `\log(q)`. Automatically + chosen values of `q` lie in `O((\log p)^2)` assuming GRH. + INPUT: - - ``F`` -- finite field `\mathbb F_{p^r}`; + - ``F`` -- finite field `\mathbb F_{p^r}` + + - ``q`` -- positive integer (optional, default ``None``) - - ``endomorphism`` -- boolean (default: ``False``): - When set to ``True``, it is required that `2 \mid r`, and - the function then additionally returns `\vartheta`. + - ``endomorphism`` -- boolean (default: ``False``); when set to ``True``, + it is required that `2 \mid r`, and the function then additionally + returns `\vartheta` + + .. WARNING:: + + Due to :issue:`38481`, calling this function with a value of `q` + larger than approximately `p/4` may currently fail. This failure + will not occur for automatically chosen values of `q`. EXAMPLES:: @@ -2514,8 +2617,8 @@ def special_supersingular_curve(F, *, endomorphism=False): Via: (u,r,s,t) = (389*z2 + 241, 0, 0, 0)) sage: special_supersingular_curve(GF(1021^2), endomorphism=True) - (Elliptic Curve defined by y^2 = x^3 + 785*x + 794 over Finite Field in z2 of size 1021^2, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 785*x + 794 over Finite Field in z2 of size 1021^2 to Elliptic Curve defined by y^2 = x^3 + 785*x + 794 over Finite Field in z2 of size 1021^2) + (Elliptic Curve defined by y^2 = x^3 + 791*x + 230 over Finite Field in z2 of size 1021^2, + Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 791*x + 230 over Finite Field in z2 of size 1021^2 to Elliptic Curve defined by y^2 = x^3 + 791*x + 230 over Finite Field in z2 of size 1021^2) sage: special_supersingular_curve(GF(1031^2), endomorphism=True) (Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1031^2, @@ -2540,6 +2643,20 @@ def special_supersingular_curve(F, *, endomorphism=False): Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1051^2 Via: (u,r,s,t) = (922*z2 + 129, 0, 0, 0)) + We can also supply a suitable value of `q` ourselves:: + + sage: special_supersingular_curve(GF(1019), q=99) + Elliptic Curve defined by y^2 = x^3 + 211*x + 808 over Finite Field of size 1019 + + sage: special_supersingular_curve(GF(1019^2), q=99, endomorphism=True) + (Elliptic Curve defined by y^2 = x^3 + 211*x + 808 over Finite Field in z2 of size 1019^2, + Isogeny of degree 99 from Elliptic Curve defined by y^2 = x^3 + 211*x + 808 over Finite Field in z2 of size 1019^2 to Elliptic Curve defined by y^2 = x^3 + 211*x + 808 over Finite Field in z2 of size 1019^2) + + sage: special_supersingular_curve(GF(1013), q=99) + Traceback (most recent call last): + ... + ValueError: invalid choice of q + TESTS:: sage: p = random_prime(1000) @@ -2588,6 +2705,35 @@ def special_supersingular_curve(F, *, endomorphism=False): sage: pi * endo == -endo * pi True + Also try it when `q` is given: + + sage: p = random_prime(300, lbound=10) + sage: k = ZZ(randrange(1, 5)) + sage: while True: + ....: q = randrange(1, p//4) # upper bound p//4 is a workaround for #38481 + ....: if QuaternionAlgebra(-q, -p).discriminant() == p: + ....: break + sage: E = special_supersingular_curve(GF((p, k)), q) + sage: E.is_supersingular() + True + sage: F. = GF((p, 2*k)) + sage: E, endo = special_supersingular_curve(F, q, endomorphism=True) + sage: E.is_supersingular() + True + sage: E.j_invariant() in GF(p) + True + sage: endo.domain() is endo.codomain() is E + True + sage: endo.degree() == q + True + sage: endo.trace() + 0 + sage: pi = E.frobenius_isogeny() + sage: pi.codomain() is pi.domain() is E + True + sage: pi * endo == -endo * pi + True + .. NOTE:: This function makes no guarantees about the distribution of @@ -2604,42 +2750,49 @@ def special_supersingular_curve(F, *, endomorphism=False): if endomorphism and deg % 2: raise ValueError('endomorphism was requested but is not defined over given field') - E = None + if q is not None: + from sage.arith.misc import hilbert_conductor + if p.divides(q) or hilbert_conductor(-q, -p) != p: + raise ValueError('invalid choice of q') # first find the degree q of our special endomorphism - if p == 2: - q = 3 - E = EllipticCurve(F, [0,0,1,0,0]) - - elif p % 4 == 3: - q = 1 - E = EllipticCurve(F, [1,0]) - - elif p % 3 == 2: - q = 3 - E = EllipticCurve(F, [0,1]) - - elif p % 8 == 5: - q = 2 - E = EllipticCurve(F, [-4320, 96768]) - - else: - from sage.arith.misc import legendre_symbol - for q in map(ZZ, range(3,p,4)): - if not q.is_prime(): - continue - if legendre_symbol(-q, p) == -1: - break + if q is None: + if p == 2: + q = 3 + elif p % 4 == 3: + q = 1 + elif p % 3 == 2: + q = 3 + elif p % 8 == 5: + q = 2 else: - assert False # should never happen - - if E is None: - from sage.arith.misc import fundamental_discriminant - from sage.schemes.elliptic_curves.cm import hilbert_class_polynomial - H = hilbert_class_polynomial(fundamental_discriminant(-q)) - j = H.change_ring(GF(p)).any_root() + from sage.arith.misc import legendre_symbol + for q in map(ZZ, range(3,p,4)): + if not q.is_prime(): + continue + if legendre_symbol(-q, p) == -1: + break + else: # should never happen + assert False, 'bug in special_supersingular_curve()' + q = ZZ(q) + + from sage.arith.misc import fundamental_discriminant + from sage.schemes.elliptic_curves.cm import hilbert_class_polynomial + H = hilbert_class_polynomial(fundamental_discriminant(-q)) + j = H.change_ring(GF(p)).any_root() + if j.is_zero(): + if p == 2: + ainvs = [0,0,1,0,0] + elif p == 3: + ainvs = [1,0] + else: + ainvs = [0,1] + elif j == 1728: + ainvs = [1,0] + else: a = 27 * j / (4 * (1728-j)) - E = EllipticCurve(F, [a,-a]) + ainvs = [a,-a] + E = EllipticCurve(F, ainvs) if ZZ(2).divides(deg): k = deg//2 @@ -2650,34 +2803,38 @@ def special_supersingular_curve(F, *, endomorphism=False): if not endomorphism: return E - if q == 1 or p <= 13: - if q == 1: - endos = E.automorphisms() - else: - endos = (iso*phi for phi in E.isogenies_prime_degree(q) - for iso in phi.codomain().isomorphisms(E)) - endo = next(endo for endo in endos if endo.trace().is_zero()) - + if q.is_one(): + endo = next(auto for auto in E.automorphisms() if auto.trace().is_zero()) else: - from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - iso = WeierstrassIsomorphism(None, (F(-q).sqrt(),0,0,0), E) - if q == 3 and E.a_invariants() == (0,0,0,0,1): - # workaround for #21883 - endo = E.isogeny(E(0,1)) - else: - endo = E.isogeny(None, iso.domain(), degree=q) - endo = iso * endo + iso = E.isomorphism(F(-q).sqrt(), is_codomain=True) + try: + endo = iso * E.isogeny(None, iso.domain(), degree=q) + except (NotImplementedError, ValueError): #FIXME catching ValueError here is a workaround for #38481 + #FIXME this code could be simplified/optimized after #37388 and/or #35949 + def _isogs(E, d): + if d.is_one(): + yield E.identity_morphism() + return + l = d.prime_factors()[-1] + for phi in E.isogenies_prime_degree(l): + for psi in _isogs(phi.codomain(), d//l): + yield psi * phi + endos = (iso*phi for phi in _isogs(E, q) for iso in phi.codomain().isomorphisms(E)) +# endos = (iso*phi for phi in E.isogenies_degree(q) +# for iso in phi.codomain().isomorphisms(E)) + endo = next(endo for endo in endos if endo.trace().is_zero()) endo._degree = ZZ(q) endo.trace.set_cache(ZZ.zero()) return E, endo + def EllipticCurve_with_order(m, *, D=None): r""" Return an iterator for elliptic curves over finite fields with the given order. The curves are computed using the Complex Multiplication (CM) method. - A `:sage:`~sage.structure.factorization.Factorization` can be passed for ``m``, in which case + A :class:`~sage.structure.factorization.Factorization` can be passed for ``m``, in which case the algorithm is more efficient. If ``D`` is specified, it is used as the discriminant. @@ -2724,8 +2881,8 @@ def EllipticCurve_with_order(m, *, D=None): sage: all(E.order() == 21 for E in Es) True - Indeed, we can verify that this is correct. Hasse's bounds tell us that $p \leq 50$ - (approximately), and the rest can be checked via bruteforce:: + Indeed, we can verify that this is correct. Hasse's bounds tell us that + `p \leq 50` (approximately), and the rest can be checked via bruteforce:: sage: for p in prime_range(50): ....: for j in range(p): @@ -2761,7 +2918,7 @@ def find_q(m, m4_fac, D): m_val = m if D is None: - Ds = (D for D in range(-4 * m_val, 0) if D % 4 in [0, 1]) + Ds = (D for D in range(-1, -4 * m_val - 1, -1) if D % 4 in [0, 1]) else: assert D < 0 and D % 4 in [0, 1] Ds = [D] @@ -2773,17 +2930,325 @@ def find_q(m, m4_fac, D): continue H = hilbert_class_polynomial(D) - K = GF(q) - roots = H.roots(ring=K) - for j0, _ in roots: + for j0 in H.roots(ring=GF(q), multiplicities=False): E = EllipticCurve(j=j0) for Et in E.twists(): if any(Et.is_isomorphic(E) for E in seen): continue - try: - # This tests whether the curve has given order - Et.set_order(m_val) + # This tests whether the curve has given order + if Et.has_order(m_val): + # TODO: remove after 38617 + Et.set_order(m_val, check=False) seen.add(Et) yield Et - except ValueError: - pass + +def EllipticCurve_with_prime_order(N): + r""" + Given a prime number ``N``, find another prime number `p` and construct an + elliptic curve `E` defined over `\mathbb F_p` such that + `\#E(\mathbb F_p) = N`. + + INPUT: + + - ``N`` -- integer; the order for which we seek an elliptic curve. Must be a + prime number. + + OUTPUT: an iterator of (some) elliptic curves `E/\mathbb F_p` of order ``N`` + + ALGORITHM: + + Our algorithm is based on [BS2007]_, Algorithm 2.2, but we deviate for + several key steps. Firstly, the authors in the paper perform the search for + a suitable `D` *incrementally*, by enlarging the table `S` by `log(N)`-size + interval of primes `p` and testing all products of distinct primes `p` (or + rather `p^*`). We find this difficult to implement without testing + duplicate `D`\s, so we instead enlarge the table one prime at a time + (effectively replacing `[r\log(N), (r + 1)\log(N)]` in the paper by `[r, + r]`). To compensate for the speed loss, we begin the algorithm by + prefilling `S` with the primes below `1000` (satisfying quadratic + reciprocity properties). The constant `1000` is determined experimentally + to be fast for many purposes, and for most `N` we tested we are able to + find a suitable small `D` without increasing the size of `S`. + + The paper also doesn't specify how to enumerate such `D`\s, which recall + should be product of distinct values in the table `S`. We implement this + with a priority queue (min heap), which also allows us to search for the + suitable `D`\s in increasing (absolute value) order. This is suitable for + the algorithm because smaller `D` means the Hilbert class polynomial is + computed quicker. + + Finally, to avoid repeatedly testing the same `D`\s, we require the latest + prime to be added to the table to be included as a factor of `D` (see code + for more explanation). As we need to find integers `x, y` such that `x^2 + + (-D)y^2 = 4N` with `D < 0` and `N` prime, we actually need `|D| \leq 4N`, + so we terminate the algorithm when the primes in the table are larger than + that bound. This makes the iterator return all curves it can find in finite + time. + + ALGORITHM: Based on [BS2007]_, Algorithm 2.2 + + EXAMPLES:: + + sage: N = 8314040072427107567 + sage: E = next(EllipticCurve_with_prime_order(N)) + sage: E + Elliptic Curve defined by y^2 = x^3 + 4757897140353078952*x + 1841350074072114366 + over Finite Field of size 8314040074357871443 + sage: E.has_order(N) + True + + The returned curves are sometimes random because + :meth:`~sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field.twists` + is not deterministic. However, it's always isomorphic:: + + sage: E = next(EllipticCurve_with_prime_order(23)); E # random + Elliptic Curve defined by y^2 = x^3 + 12*x + 6 over Finite Field of size 17 + sage: E.is_isomorphic(EllipticCurve(GF(17), [3, 5])) + True + + You can directly iterate over the iterator; here only on the first 10 + curves:: + + sage: N = 54675917 + sage: for _, E in zip(range(10), EllipticCurve_with_prime_order(N)): + ....: assert E.has_order(N) + + It works for large primes:: + + sage: N = 2666207849820848272386538889527600954292544013630953455833 + sage: E = next(EllipticCurve_with_prime_order(N)); E + Elliptic Curve defined by y^2 = x^3 + 2666207849820848272386538889427721639173508298483739490459*x + + 77986137112576 over Finite Field of size 2666207849820848272386538889427721639173508298487130585243 + sage: E.has_order(N) + True + + Another example for large primes:: + + sage: N = next_prime(2^256) + sage: E = next(EllipticCurve_with_prime_order(N)); E # random + Elliptic Curve defined by y^2 = x^3 + 6056521267553273205988520276135607487700943205131813669424576873701361709521*x + + 86942739955486781674010637133214195706465136689012129911736706024465988573567 over Finite Field of size + 115792089237316195423570985008687907853847329310253429036565151476471048389761 + sage: E.j_invariant() + 111836223967433630316209796253554285080540088646141285337487360944738698436350 + sage: E.has_order(N) + True + + Note that the iterator does *not* return all curves with the given order:: + + sage: any(E.base_ring() is GF(7) for E in EllipticCurve_with_prime_order(7)) + False + sage: EllipticCurve(GF(7), [0, 5]).order() + 7 + + However, experimentally it returns many of them. Here it returns all of + them:: + + sage: N = 23 + sage: set_random_seed(1337) # as the function returns random twists of curves + sage: curves = list(EllipticCurve_with_prime_order(N)); curves # random + [Elliptic Curve defined by y^2 = x^3 + 3*x + 5 over Finite Field of size 17, + Elliptic Curve defined by y^2 = x^3 + 19*x + 14 over Finite Field of size 31, + Elliptic Curve defined by y^2 = x^3 + 2*x + 9 over Finite Field of size 19, + Elliptic Curve defined by y^2 = x^3 + 7*x + 18 over Finite Field of size 29, + Elliptic Curve defined by y^2 = x^3 + 20*x + 20 over Finite Field of size 23, + Elliptic Curve defined by y^2 = x^3 + 10*x + 16 over Finite Field of size 23] + sage: import itertools + sage: # These are the only primes, by the Hasse-Weil bound + sage: for q in prime_range(17, 35): + ....: K = GF(q) + ....: for u in itertools.product(range(q), repeat=2): + ....: try: E = EllipticCurve(GF(q), u) + ....: except ArithmeticError: continue + ....: if E.has_order(N): + ....: assert any(E.is_isomorphic(E_) for E_ in curves) + + The algorithm is efficient for small ``N`` due to the low number of suitable + discriminants (see the ``abs_products_under`` internal function of the code + for details):: + + sage: len(list(EllipticCurve_with_prime_order(next_prime(5000)))) + 534 + sage: len(list(EllipticCurve_with_prime_order(next_prime(50000)))) # long time (6s) + 3841 + + There is different verbose data for level `2` to `4`, though level `3` + rarely logs anything (it logs when a new prime `p` is added to the + smoothness bound):: + + sage: from sage.misc.verbose import set_verbose + sage: set_random_seed(1337) # as the function returns random twists of curves + sage: for _, E in zip(range(3), EllipticCurve_with_prime_order(10^9 + 7)): + ....: print(E) + Elliptic Curve defined by y^2 = x^3 + 265977778*x + 120868502 over Finite Field of size 1000041437 + Elliptic Curve defined by y^2 = x^3 + 689795416*x + 188156157 over Finite Field of size 999969307 + Elliptic Curve defined by y^2 = x^3 + 999178436*x + 900579394 over Finite Field of size 999969307 + sage: set_verbose(2) + sage: set_random_seed(1337) + sage: for _, E in zip(range(3), EllipticCurve_with_prime_order(10^9 + 7)): + ....: print(E) + verbose 2 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Computing the Hilbert class polynomial H_-163 + Elliptic Curve defined by y^2 = x^3 + 265977778*x + 120868502 over Finite Field of size 1000041437 + verbose 2 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Computing the Hilbert class polynomial H_-667 + Elliptic Curve defined by y^2 = x^3 + 689795416*x + 188156157 over Finite Field of size 999969307 + Elliptic Curve defined by y^2 = x^3 + 999178436*x + 900579394 over Finite Field of size 999969307 + sage: set_verbose(4) + sage: set_random_seed(1337) + sage: for _, E in zip(range(3), EllipticCurve_with_prime_order(10^9 + 7)): + ....: print(E) + verbose 4 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Testing D=-19 + ... + verbose 4 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Testing D=-163 + verbose 2 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Computing the Hilbert class polynomial H_-163 + Elliptic Curve defined by y^2 = x^3 + 265977778*x + 120868502 over Finite Field of size 1000041437 + verbose 4 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Testing D=-179 + ... + verbose 4 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Testing D=-667 + verbose 2 (...: ell_finite_field.py, EllipticCurve_with_prime_order) Computing the Hilbert class polynomial H_-667 + Elliptic Curve defined by y^2 = x^3 + 689795416*x + 188156157 over Finite Field of size 999969307 + Elliptic Curve defined by y^2 = x^3 + 999178436*x + 900579394 over Finite Field of size 999969307 + + TESTS:: + + sage: list(EllipticCurve_with_prime_order(2)) + [Elliptic Curve defined by y^2 + x*y + y = x^3 + 1 over Finite Field of size 2, + Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field of size 3, + Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 5] + + sage: set_verbose(0) + sage: for N in prime_range(3, 100): + ....: E = next(EllipticCurve_with_prime_order(N)) + ....: assert E.has_order(N) + + sage: N = 113 + sage: for _, E in zip(range(30), EllipticCurve_with_prime_order(N)): + ....: assert E.has_order(N) + + sage: N = 15175980689839334471 + sage: E = next(EllipticCurve_with_prime_order(N)) + sage: E.has_order(N) + True + + sage: N = next_prime(123456789) + sage: E = next(EllipticCurve_with_prime_order(N)) + sage: E.has_order(N) + True + + sage: N = 123456789 + sage: E = next(EllipticCurve_with_prime_order(N)) + Traceback (most recent call last): + ... + ValueError: input order is not a prime + + sage: E = next(EllipticCurve_with_prime_order(0)) + Traceback (most recent call last): + ... + ValueError: input order is not a prime + + sage: E = next(EllipticCurve_with_prime_order(-7)) + Traceback (most recent call last): + ... + ValueError: input order is not a prime + + AUTHORS: + + - Martin Grenouilloux, Gareth Ma (2024-09): initial implementation + """ + import itertools + from sage.arith.misc import is_prime, legendre_symbol + from sage.misc.verbose import verbose + from sage.quadratic_forms.binary_qf import BinaryQF + from sage.rings.fast_arith import prime_range + from sage.schemes.elliptic_curves.cm import hilbert_class_polynomial + from sage.sets.primes import Primes + + if not is_prime(N): + raise ValueError("input order is not a prime") + + if N == 2: + yield from [ + EllipticCurve(GF(2), [1, 0, 1, 0, 1]), + EllipticCurve(GF(3), [0, 2, 0, 0, 2]), + EllipticCurve(GF(5), [2, 0]) + ] + return + + # We start with small primes directly to accelerate the search. Note that + # 1000 is a magic constant, it's just fast enough to compute without + # sacrificing much speed. + # The if-then-else term is (-1)^((p - 1) / 2) * p in [BS2007]_ page 5. + S = [(-p if p % 4 == 3 else p) for p in prime_range(3, min(1000, 4 * N)) + if legendre_symbol(N, p) == 1] + + def abs_products_under(bound): + """ + This function returns an iterator of all numbers with absolute value not + exceeding ``bound`` expressable as product of distinct elements in ``S`` + in ascending order. + """ + import heapq + hq = [(1, 1, -1)] + while len(hq): + abs_n, n, idx = heapq.heappop(hq) + yield n + for nxt in range(idx + 1, len(S)): + if abs_n * abs(S[nxt]) <= bound: + heapq.heappush(hq, (abs_n * abs(S[nxt]), n * S[nxt], nxt)) + else: + break + + # We add p = 1 to process the small primes. + for p in itertools.chain([1], Primes()): + if p != 1: + if p < abs(S[-1]): + continue + + if legendre_symbol(N, p) != 1: + continue + + # Later we need x^2 + (-D)y^2 = 4N, and since y = 0 has no + # solution, we need p = |p_star| <= |-D| <= 4N. This is a stopping + # condition for the algorithm. + if p > 4 * N: + break + + verbose(f"Considering {len(S) + 1}th valid prime {p}", level=3) + + p_star = -p if p % 4 == 3 else p + + for e in abs_products_under(4 * N // p): + # According to the paper, the expected minimum D to work is + # O(log(N)^2) + D = p_star * e + assert abs(D) <= 4 * N + + if D % 8 != 5 or D >= 0: + continue + + verbose(f"Testing {D=}", level=4) + + Q = BinaryQF([1, 0, -D]) + sol = Q.solve_integer(4 * N, algorithm='cornacchia') + if sol is None: + continue + + x, _ = sol + for p_i in [N + 1 - x, N + 1 + x]: + if is_prime(p_i): + verbose(f"Computing the Hilbert class polynomial H_{D}", + level=2) + H = hilbert_class_polynomial(D) + K = GF(p_i) + for j0 in H.roots(ring=K, multiplicities=False): + E = EllipticCurve(K, j=j0) + # `E.twists()` also contains E. + for Et in E.twists(): + # `num_checks=1` is sufficient for prime order + if Et.has_order(N, num_checks=1): + # TODO: remove after 38617 + Et.set_order(N, check=False) + yield Et + + if p != 1: + # Extending our prime list and continuing onto the next round. + S.append(p_star) diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py old mode 100644 new mode 100755 index 16347cc6a6f..6ca3f1fdb46 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -10,7 +10,7 @@ Note that the (usual) scheme-theoretic definition of an elliptic curve over `R` would require the discriminant to be a unit in `R`; Sage only imposes that the -discriminant is non-zero. Also note that in Magma, "Weierstrass Model" refers +discriminant is nonzero. Also note that in Magma, "Weierstrass Model" refers to a model with `a_1=a_2=a_3=0`, which is called *Short Weierstrass Model* in Sage; these do not always exist in characteristics 2 and 3. @@ -133,8 +133,8 @@ def __init__(self, K, ainvs, category=None): - ``K`` -- a ring - - ``ainvs`` -- a list or tuple `[a_1, a_2, a_3, a_4, a_6]` of - Weierstrass coefficients. + - ``ainvs`` -- list or tuple `[a_1, a_2, a_3, a_4, a_6]` of + Weierstrass coefficients .. NOTE:: @@ -272,7 +272,7 @@ def _latex_(self): """ Internal function. Return a latex string for this elliptic curve. - Users will normally use latex() instead. + Users will normally use :func:`latex` instead. EXAMPLES:: @@ -434,7 +434,7 @@ def _symbolic_(self, SR): def __contains__(self, P): """ - Return True if and only if P is a point on the elliptic curve. + Return ``True`` if and only if P is a point on the elliptic curve. P just has to be something that can be coerced to a point. @@ -492,7 +492,7 @@ def __call__(self, *args, **kwds): sage: E([0,1,0]) (0 : 1 : 0) - Over a field, points are normalized so the 3rd entry (if non-zero) + Over a field, points are normalized so the 3rd entry (if nonzero) is 1:: sage: E(105, -69, 125) @@ -528,7 +528,7 @@ def __call__(self, *args, **kwds): sage: P + P (0 : 1 : 0) - Another example involving p-adics:: + Another example involving `p`-adics:: sage: E = EllipticCurve('37a1') sage: P = E([0,0]); P @@ -602,13 +602,11 @@ def _reduce_point(self, R, p): INPUT: - - R -- a point on an elliptic curve - - p -- a prime + - ``R`` -- a point on an elliptic curve + - ``p`` -- a prime - OUTPUT: - - S -- the corresponding point of the elliptic curve containing - R, but reduced modulo p + OUTPUT: S; the corresponding point of the elliptic curve containing + R, but reduced modulo p EXAMPLES: @@ -645,7 +643,7 @@ def _reduce_point(self, R, p): def is_x_coord(self, x): r""" - Return True if ``x`` is the `x`-coordinate of a point on this curve. + Return ``True`` if ``x`` is the `x`-coordinate of a point on this curve. .. NOTE:: @@ -723,13 +721,13 @@ def lift_x(self, x, all=False, extend=False): INPUT: - - ``x`` -- an element of the base ring of the curve, or of an extension. + - ``x`` -- an element of the base ring of the curve, or of an extension - - ``all`` (bool, default: ``False``) -- if True, return a (possibly - empty) list of all points; if False, return just one point, - or raise a :class:`ValueError` if there are none. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + (possibly empty) list of all points; if ``False``, return just one + point, or raise a :exc:`ValueError` if there are none. - - ``extend`` (bool, default: ``False``) -- + - ``extend`` -- boolean (default: ``False``); - if ``False``, extend the base if necessary and possible to include `x`, and only return point(s) defined over this @@ -1029,11 +1027,11 @@ def __is_over_RationalField(self): def is_on_curve(self, x, y): r""" - Return True if `(x,y)` is an affine point on this curve. + Return ``True`` if `(x,y)` is an affine point on this curve. INPUT: - - ``x``, ``y`` -- elements of the base ring of the curve. + - ``x``, ``y`` -- elements of the base ring of the curve EXAMPLES:: @@ -1498,7 +1496,7 @@ def rst_transform(self, r, s, t): INPUT: - - ``r``, ``s``, ``t`` -- three elements of the base ring. + - ``r``, ``s``, ``t`` -- three elements of the base ring OUTPUT: @@ -1528,7 +1526,7 @@ def scale_curve(self, u): INPUT: - - ``u`` -- an invertible element of the base ring. + - ``u`` -- an invertible element of the base ring OUTPUT: @@ -1683,7 +1681,7 @@ def isomorphism(self, u, r=0, s=0, t=0, *, is_codomain=False): def division_polynomial_0(self, n, x=None): r""" - Return the `n^{th}` torsion (division) polynomial, without + Return the `n`-th torsion (division) polynomial, without the 2-torsion factor if `n` is even, as a polynomial in `x`. These are the polynomials `g_n` defined in [MT1991]_, but with @@ -1705,10 +1703,10 @@ def division_polynomial_0(self, n, x=None): - ``n`` -- positive integer, or the special values ``-1`` and ``-2`` which mean `B_6 = (2y + a_1 x + a_3)^2` and `B_6^2` respectively (in - the notation of [MT1991]_); or a list of integers. + the notation of [MT1991]_), or a list of integers - ``x`` -- a ring element to use as the "x" variable or ``None`` - (default: ``None``). If ``None``, then a new polynomial ring will + (default: ``None``); if ``None``, then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as ``x``. Note that ``x`` does not need to be a generator of a polynomial ring; any ring element is ok. This @@ -1864,7 +1862,7 @@ def two_division_polynomial(self, x=None): INPUT: - - ``x`` -- optional ring element to use as the `x` variable. + - ``x`` -- (optional) ring element to use as the `x` variable. If ``x`` is ``None``, then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as ``x``. Note that ``x`` does @@ -1887,16 +1885,16 @@ def two_division_polynomial(self, x=None): def division_polynomial(self, m, x=None, two_torsion_multiplicity=2, force_evaluate=None): r""" - Return the `m^{th}` division polynomial of this elliptic + Return the `m`-th division polynomial of this elliptic curve evaluated at `x`. The division polynomial is cached if `x` is ``None``. INPUT: - - ``m`` -- positive integer. + - ``m`` -- positive integer - - ``x`` -- optional ring element to use as the `x` variable. + - ``x`` -- (optional) ring element to use as the `x` variable. If `x` is ``None`` (omitted), then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as `x`. Note that `x` does not need to @@ -1925,7 +1923,7 @@ def division_polynomial(self, m, x=None, two_torsion_multiplicity=2, force_evalu When `x` is not ``None``, it should be a tuple of length 2, and the evaluation of such a polynomial at `x` is returned. - - ``force_evaluate`` (optional) -- 0, 1, or 2 + - ``force_evaluate`` -- (optional) 0, 1, or 2 By default, this method makes use of previously cached generic division polynomials to compute the value of the polynomial at @@ -2113,7 +2111,7 @@ def _multiple_x_numerator(self, n, x=None): INPUT: - - ``n``, ``x`` -- as described in :meth:`division_polynomial_0`. + - ``n``, ``x`` -- as described in :meth:`division_polynomial_0` If ``x`` is ``None``, the result is cached. This is so that on calling ``P.division_points(n)`` for the same `n` and different points `P` (on @@ -2237,7 +2235,7 @@ def _multiple_x_denominator(self, n, x=None): INPUT: - - ``n``, ``x`` -- as described in :meth:`division_polynomial_0`. + - ``n``, ``x`` -- as described in :meth:`division_polynomial_0` If ``x`` is ``None``, the result is cached. This is so that on calling ``P.division_points(n)`` for the same `n` and different points `P` (on @@ -2321,7 +2319,7 @@ def _multiple_x_denominator(self, n, x=None): def multiplication_by_m(self, m, x_only=False): r""" - Return the multiplication-by-`m` map from ``self`` to ``self`` + Return the multiplication-by-`m` map from ``self`` to ``self``. The result is a pair of rational functions in two variables `x`, `y` (or a rational function in one variable `x` if @@ -2329,11 +2327,10 @@ def multiplication_by_m(self, m, x_only=False): INPUT: - - ``m`` -- a nonzero integer + - ``m`` -- nonzero integer - - ``x_only`` -- boolean (default: ``False``) if ``True``, return - only the `x`-coordinate of the map (as a rational function - in one variable). + - ``x_only`` -- boolean (default: ``False``); if ``True``, return only + the `x`-coordinate of the map (as a rational function in one variable) OUTPUT: @@ -2457,7 +2454,7 @@ def multiplication_by_m(self, m, x_only=False): p = self.base_ring().characteristic() if m == 0: - raise ValueError("m must be a non-zero integer") + raise ValueError("m must be a nonzero integer") if x_only: x = polygen(self.base_ring(), 'x') @@ -2531,7 +2528,7 @@ def multiplication_by_m_isogeny(self, m): INPUT: - - ``m`` -- a nonzero integer + - ``m`` -- nonzero integer OUTPUT: @@ -2693,7 +2690,7 @@ def isomorphism_to(self, other): INPUT: - - ``other`` -- an elliptic curve isomorphic to ``self``. + - ``other`` -- an elliptic curve isomorphic to ``self`` OUTPUT: @@ -2701,7 +2698,7 @@ def isomorphism_to(self, other): .. NOTE:: - If the curves in question are not isomorphic, a ``ValueError`` + If the curves in question are not isomorphic, a :exc:`ValueError` is raised. EXAMPLES:: @@ -2745,13 +2742,13 @@ def automorphisms(self, field=None): INPUT: - - ``field`` (default ``None``) -- a field into which the + - ``field`` -- (default: ``None``) a field into which the coefficients of the curve may be coerced (by default, uses - the base field of the curve). + the base field of the curve) OUTPUT: - (list) A list of :class:`~wm.WeierstrassIsomorphism` objects + A list of :class:`~wm.WeierstrassIsomorphism` objects consisting of all the isomorphisms from the curve ``self`` to itself defined over ``field``. @@ -2828,15 +2825,15 @@ def isomorphisms(self, other, field=None): INPUT: - - ``other`` -- another elliptic curve. + - ``other`` -- another elliptic curve - - ``field`` (default ``None``) -- a field into which the + - ``field`` -- (default: ``None``) a field into which the coefficients of the curves may be coerced (by default, uses - the base field of the curves). + the base field of the curves) OUTPUT: - (list) A list of :class:`~wm.WeierstrassIsomorphism` objects consisting of all + A list of :class:`~wm.WeierstrassIsomorphism` objects consisting of all the isomorphisms from the curve ``self`` to the curve ``other`` defined over ``field``. @@ -2885,15 +2882,15 @@ def is_isomorphic(self, other, field=None): INPUT: - - ``other`` -- another elliptic curve. + - ``other`` -- another elliptic curve - - ``field`` (default None) -- a field into which the + - ``field`` -- (default: ``None``) a field into which the coefficients of the curves may be coerced (by default, uses the base field of the curves). OUTPUT: - (bool) True if there is an isomorphism from curve ``self`` to + boolean; ``True`` if there is an isomorphism from curve ``self`` to curve ``other`` defined over ``field``. EXAMPLES:: @@ -2925,7 +2922,8 @@ def is_isomorphic(self, other, field=None): def change_weierstrass_model(self, *urst): r""" - Return a new Weierstrass model of ``self`` under the standard transformation `(u,r,s,t)` + Return a new Weierstrass model of ``self`` under the standard + transformation `(u,r,s,t)`. .. MATH:: @@ -2950,16 +2948,14 @@ def change_weierstrass_model(self, *urst): def short_weierstrass_model(self, complete_cube=True): """ - Return a short Weierstrass model for self. + Return a short Weierstrass model for ``self``. INPUT: - ``complete_cube`` -- boolean (default: ``True``); for - meaning, see below. - - OUTPUT: + meaning, see below - An elliptic curve. + OUTPUT: an elliptic curve If ``complete_cube=True``: Return a model of the form `y^2 = x^3 + a*x + b` for this curve. The characteristic @@ -3272,9 +3268,9 @@ def plot(self, xmin=None, xmax=None, components='both', **args): INPUT: - ``xmin``, ``xmax`` -- (optional) points will be computed at - least within this range, but possibly farther. + least within this range, but possibly farther - - ``components`` -- a string, one of the following: + - ``components`` -- string; one of the following: - ``both`` -- (default), scale so that both bounded and unbounded components appear @@ -3284,7 +3280,7 @@ def plot(self, xmin=None, xmax=None, components='both', **args): component. - ``unbounded`` -- scale the plot to show the unbounded - component, including the two flex points. + component, including the two flex points - ``plot_points`` -- passed to :func:`sage.plot.generate_plot_points` @@ -3491,10 +3487,10 @@ def _p_primary_torsion_basis(self, p, m=None): INPUT: - - ``p`` (integer) -- a prime number. + - ``p`` -- integer; a prime number - - ``m`` (integer or None) -- if not None, the `p`-primary torsion will - be assumed to have order at most `p^m`. + - ``m`` -- integer or ``None``; if not ``None``, the `p`-primary + torsion will be assumed to have order at most `p^m` OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_local_data.py b/src/sage/schemes/elliptic_curves/ell_local_data.py old mode 100644 new mode 100755 index f600259eef7..7434659b5a2 --- a/src/sage/schemes/elliptic_curves/ell_local_data.py +++ b/src/sage/schemes/elliptic_curves/ell_local_data.py @@ -102,7 +102,7 @@ from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal from sage.rings.number_field.number_field_base import NumberField -from sage.rings.ideal import is_Ideal +from sage.rings.ideal import Ideal_generic from .constructor import EllipticCurve from .kodaira_symbol import KodairaSymbol @@ -118,17 +118,17 @@ class EllipticCurveLocalData(SageObject): INPUT: - - ``E`` -- an elliptic curve defined over a number field, or `\QQ`. + - ``E`` -- an elliptic curve defined over a number field, or `\QQ` - - ``P`` -- a prime ideal of the field, or a prime integer if the field is `\QQ`. + - ``P`` -- a prime ideal of the field, or a prime integer if the field is `\QQ` - - ``proof`` (bool) -- if ``True``, only use provably correct - methods (default controlled by global proof module). Note + - ``proof`` -- boolean; if ``True``, only use provably correct + methods (default: controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - - ``algorithm`` (string, default: "pari") -- Ignored unless the + - ``algorithm`` -- string (default: ``'pari'``); ignored unless the base field is `\QQ`. If "pari", use the PARI C-library ``ellglobalred`` implementation of Tate's algorithm over `\QQ`. If "generic", use the general number field @@ -155,29 +155,29 @@ class EllipticCurveLocalData(SageObject): Tamagawa Number: 2 """ - def __init__(self, E, P, proof=None, algorithm="pari", globally=False): + def __init__(self, E, P, proof=None, algorithm='pari', globally=False): r""" Initialize the reduction data for the elliptic curve `E` at the prime `P`. INPUT: - - ``E`` -- an elliptic curve defined over a number field, or `\QQ`. + - ``E`` -- an elliptic curve defined over a number field, or `\QQ` - - ``P`` -- a prime ideal of the field, or a prime integer if the field is `\QQ`. + - ``P`` -- a prime ideal of the field, or a prime integer if the field is `\QQ` - - ``proof`` (bool)-- if True, only use provably correct - methods (default controlled by global proof module). Note + - ``proof`` -- boolean; if ``True``, only use provably correct + methods (default: controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - - ``algorithm`` (string, default: "pari") -- Ignored unless the + - ``algorithm`` -- string (default: ``'pari'``); ignored unless the base field is `\QQ`. If "pari", use the PARI C-library ``ellglobalred`` implementation of Tate's algorithm over `\QQ`. If "generic", use the general number field implementation. - - ``globally`` (bool, default: ``False``) -- If True, the algorithm + - ``globally`` -- boolean (default: ``False``); if ``True``, the algorithm uses the generators of principal ideals rather than an arbitrary uniformizer. @@ -203,7 +203,7 @@ def __init__(self, E, P, proof=None, algorithm="pari", globally=False): :: - sage: EllipticCurveLocalData(E, 2, algorithm="generic") + sage: EllipticCurveLocalData(E, 2, algorithm='generic') Local data at Principal ideal (2) of Integer Ring: Reduction type: bad non-split multiplicative Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 @@ -215,7 +215,7 @@ def __init__(self, E, P, proof=None, algorithm="pari", globally=False): :: - sage: EllipticCurveLocalData(E, 2, algorithm="pari") + sage: EllipticCurveLocalData(E, 2, algorithm='pari') Local data at Principal ideal (2) of Integer Ring: Reduction type: bad non-split multiplicative Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 @@ -227,7 +227,7 @@ def __init__(self, E, P, proof=None, algorithm="pari", globally=False): :: - sage: EllipticCurveLocalData(E, 2, algorithm="unknown") + sage: EllipticCurveLocalData(E, 2, algorithm='unknown') Traceback (most recent call last): ... ValueError: algorithm must be one of 'pari', 'generic' @@ -315,7 +315,7 @@ def minimal_model(self, reduce=True): INPUT: - - ``reduce`` -- (default: ``True``) if set to ``True`` and if + - ``reduce`` -- boolean (default: ``True``); if set to ``True`` and if the initial elliptic curve had globally integral coefficients, then the elliptic curve returned by Tate's algorithm will be "reduced" as specified in _reduce_model() @@ -346,15 +346,15 @@ def minimal_model(self, reduce=True): over Number Field in a with defining polynomial x^3 + x + 1 sage: E = EllipticCurve([2, 1, 0, -2, -1]) - sage: E.local_data(ZZ.ideal(2), algorithm="generic").minimal_model(reduce=False) + sage: E.local_data(ZZ.ideal(2), algorithm='generic').minimal_model(reduce=False) Elliptic Curve defined by y^2 + 2*x*y + 2*y = x^3 + x^2 - 4*x - 2 over Rational Field - sage: E.local_data(ZZ.ideal(2), algorithm="pari").minimal_model(reduce=False) + sage: E.local_data(ZZ.ideal(2), algorithm='pari').minimal_model(reduce=False) Traceback (most recent call last): ... ValueError: the argument reduce must not be False if algorithm=pari is used - sage: E.local_data(ZZ.ideal(2), algorithm="generic").minimal_model() + sage: E.local_data(ZZ.ideal(2), algorithm='generic').minimal_model() Elliptic Curve defined by y^2 = x^3 - x^2 - 3*x + 2 over Rational Field - sage: E.local_data(ZZ.ideal(2), algorithm="pari").minimal_model() + sage: E.local_data(ZZ.ideal(2), algorithm='pari').minimal_model() Elliptic Curve defined by y^2 = x^3 - x^2 - 3*x + 2 over Rational Field :issue:`14476`:: @@ -508,7 +508,7 @@ def bad_reduction_type(self): OUTPUT: - (int or ``None``): + integer or ``None``: - +1 for split multiplicative reduction - -1 for non-split multiplicative reduction @@ -697,12 +697,12 @@ def _tate(self, proof=None, globally=False): (tuple) ``(Emin, p, val_disc, fp, KS, cp)`` where: - - ``Emin`` (EllipticCurve) is a model (integral and) minimal at P - - ``p`` (int) is the residue characteristic - - ``val_disc`` (int) is the valuation of the local minimal discriminant - - ``fp`` (int) is the valuation of the conductor - - ``KS`` (string) is the Kodaira symbol - - ``cp`` (int) is the Tamagawa number + - ``Emin`` -- :class:`EllipticCurve`; a model (integral and) minimal at P + - ``p`` -- integer; the residue characteristic + - ``val_disc`` -- integer; the valuation of the local minimal discriminant + - ``fp`` -- integer; the valuation of the conductor + - ``KS`` -- string; the Kodaira symbol + - ``cp`` -- integer; the Tamagawa number EXAMPLES (this raised a type error in sage prior to 4.4.4, see :issue:`7930`) :: @@ -759,7 +759,7 @@ def _tate(self, proof=None, globally=False): # reduce (mod P) elements of K which are not integral (but are # P-integral). However, if the model is non-minimal and we # end up dividing a_i by pi^i then at that point we use a - # uniformiser pi which has non-positive valuation at all other + # uniformiser pi which has nonpositive valuation at all other # primes, so that we can divide by it without losing # integrality at other primes. @@ -805,7 +805,8 @@ def _tate(self, proof=None, globally=False): def _pquadroots(a, b, c): r""" - Local function returning True iff `ax^2 + bx + c` has roots modulo `P` + Local function returning ``True`` iff `ax^2 + bx + c` has roots + modulo `P`. """ (a, b, c) = (F(a), F(b), F(c)) if a == 0: @@ -1129,19 +1130,17 @@ def check_prime(K, P): INPUT: - - ``K`` -- a number field (including `\QQ`). + - ``K`` -- a number field (including `\QQ`) - - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``. + - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K`` - OUTPUT: - - - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`. + OUTPUT: if ``K`` is `\QQ`: the prime integer equal to or which generates `P` - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`. .. NOTE:: - If `P` is not a prime and does not generate a prime, a :class:`TypeError` + If `P` is not a prime and does not generate a prime, a :exc:`TypeError` is raised. EXAMPLES:: @@ -1185,7 +1184,7 @@ def check_prime(K, P): raise TypeError("The element %s is not prime" % (P,)) elif P in QQ: raise TypeError("The element %s is not prime" % (P,)) - elif is_Ideal(P) and P.base_ring() is ZZ: + elif isinstance(P, Ideal_generic) and P.base_ring() is ZZ: if P.is_prime(): return P.gen() else: diff --git a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py old mode 100644 new mode 100755 index 0b8039aeb36..b6bdccff654 --- a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py +++ b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py @@ -39,7 +39,7 @@ 1/3 sage: m(1/17) -2/3 - sage: m2 = E.modular_symbol(-1, implementation="sage") + sage: m2 = E.modular_symbol(-1, implementation='sage') sage: m2(0) 0 sage: m2(1/5) @@ -107,18 +107,19 @@ oo = Cusps(infinity) zero = Integer(0) + def modular_symbol_space(E, sign, base_ring, bound=None): r""" - Creates the space of modular symbols of a given sign over a give base_ring, + Create the space of modular symbols of a given sign over a give base_ring, attached to the isogeny class of the elliptic curve ``E``. INPUT: - ``E`` -- an elliptic curve over `\QQ` - - ``sign`` -- integer, -1, 0, or 1 + - ``sign`` -- integer; -1, 0, or 1 - ``base_ring`` -- ring - - ``bound`` -- (default: None) maximum number of Hecke operators to - use to cut out modular symbols factor. If None, use + - ``bound`` -- (default: ``None``) maximum number of Hecke operators to + use to cut out modular symbols factor. If ``None``, use enough to provably get the correct answer. OUTPUT: a space of modular symbols @@ -172,7 +173,7 @@ def sign(self): sage: m = EllipticCurve('11a1').modular_symbol() sage: m.sign() 1 - sage: m = EllipticCurve('11a1').modular_symbol(sign=-1, implementation="sage") + sage: m = EllipticCurve('11a1').modular_symbol(sign=-1, implementation='sage') sage: m.sign() -1 """ @@ -212,7 +213,7 @@ def _repr_(self): sage: m Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field - sage: m = EllipticCurve('43a1').modular_symbol(sign=-1, implementation="sage") + sage: m = EllipticCurve('43a1').modular_symbol(sign=-1, implementation='sage') sage: m Modular symbol with sign -1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 + x^2 over Rational Field @@ -220,6 +221,7 @@ def _repr_(self): return "Modular symbol with sign %s over %s attached to %s" % ( self._sign, self._base_ring, self._E) + class ModularSymbolECLIB(ModularSymbol): def __init__(self, E, sign, nap=1000): r"""Modular symbols attached to `E` using ``eclib``. @@ -236,10 +238,10 @@ def __init__(self, E, sign, nap=1000): - ``E`` -- an elliptic curve - - ``sign`` -- an integer, -1 or 1 + - ``sign`` -- integer; -1 or 1 - - ``nap`` -- (int, default 1000): the number of ap of E to use - in determining the normalisation of the modular symbols. + - ``nap`` -- integer (default: 1000); the number of ap of E to use + in determining the normalisation of the modular symbols EXAMPLES:: @@ -265,12 +267,12 @@ def __init__(self, E, sign, nap=1000): sage: M(1/7) 1/2 - sage: M = EllipticCurve('121d1').modular_symbol(implementation="eclib") + sage: M = EllipticCurve('121d1').modular_symbol(implementation='eclib') sage: M(0) 2 sage: E = EllipticCurve('15a1') - sage: [C.modular_symbol(implementation="eclib")(0) for C in E.isogeny_class()] + sage: [C.modular_symbol(implementation='eclib')(0) for C in E.isogeny_class()] [1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1] Since :issue:`10256`, the interface for negative modular symbols in eclib is available:: @@ -297,7 +299,7 @@ def __init__(self, E, sign, nap=1000): TESTS (for :issue:`10236`):: sage: E = EllipticCurve('11a1') - sage: m = E.modular_symbol(implementation="eclib") + sage: m = E.modular_symbol(implementation='eclib') sage: m(1/7) 7/10 sage: m(0) @@ -344,7 +346,7 @@ def _call_with_caching(self, r, base_at_infinity=True): EXAMPLES:: - sage: m = EllipticCurve('11a1').modular_symbol(implementation="eclib") + sage: m = EllipticCurve('11a1').modular_symbol(implementation='eclib') sage: m._call_with_caching(0) 1/5 """ @@ -363,7 +365,7 @@ def __call__(self, r, base_at_infinity=True): EXAMPLES:: - sage: m = EllipticCurve('11a1').modular_symbol(implementation="eclib") + sage: m = EllipticCurve('11a1').modular_symbol(implementation='eclib') sage: m(0) 1/5 """ @@ -375,21 +377,21 @@ def __call__(self, r, base_at_infinity=True): class ModularSymbolSage(ModularSymbol): - def __init__(self, E, sign, normalize="L_ratio"): + def __init__(self, E, sign, normalize='L_ratio'): """Modular symbols attached to `E` using ``sage``. INPUT: - ``E`` -- an elliptic curve - - ``sign`` -- an integer, -1 or 1 - - ``normalize`` -- either 'L_ratio' (default), 'period', or - 'none'; For 'L_ratio', the modular symbol is correctly + - ``sign`` -- integer; -1 or 1 + - ``normalize`` -- either ``'L_ratio'`` (default), ``'period'``, or + ``'none'``; For ``'L_ratio'``, the modular symbol is correctly normalized by comparing it to the quotient of `L(E,1)` by the least positive period for the curve and some small - twists. The normalization 'period' uses the + twists. The normalization ``'period'`` uses the integral_period_map for modular symbols and is known to be equal to the above normalization up to the sign and a - possible power of 2. For 'none', the modular symbol is + possible power of 2. For ``'none'``, the modular symbol is almost certainly not correctly normalized, i.e. all values will be a fixed scalar multiple of what they should be. But the initial computation of the modular symbol is much @@ -424,22 +426,22 @@ def __init__(self, E, sign, normalize="L_ratio"): sage: M._scaling 1 - sage: M = EllipticCurve('121d1').modular_symbol(implementation="sage") + sage: M = EllipticCurve('121d1').modular_symbol(implementation='sage') sage: M(0) 2 - sage: M = EllipticCurve('121d1').modular_symbol(implementation="sage", + sage: M = EllipticCurve('121d1').modular_symbol(implementation='sage', ....: normalize='none') sage: M(0) 1 sage: E = EllipticCurve('15a1') - sage: [C.modular_symbol(implementation="sage", normalize='L_ratio')(0) + sage: [C.modular_symbol(implementation='sage', normalize='L_ratio')(0) ....: for C in E.isogeny_class()] [1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1] - sage: [C.modular_symbol(implementation="sage", normalize='period')(0) + sage: [C.modular_symbol(implementation='sage', normalize='period')(0) ....: for C in E.isogeny_class()] [1/8, 1/16, 1/8, 1/4, 1/16, 1/32, 1/4, 1/2] - sage: [C.modular_symbol(implementation="sage", normalize='none')(0) + sage: [C.modular_symbol(implementation='sage', normalize='none')(0) ....: for C in E.isogeny_class()] [1, 1, 1, 1, 1, 1, 1, 1] """ @@ -472,27 +474,27 @@ def _find_scaling_L_ratio(self): r""" This function is use to set ``_scaling``, the factor used to adjust the scalar multiple of the modular symbol. - If `[0]`, the modular symbol evaluated at 0, is non-zero, we can just scale + If `[0]`, the modular symbol evaluated at 0, is nonzero, we can just scale it with respect to the approximation of the L-value. It is known that the quotient is a rational number with small denominator. Otherwise we try to scale using quadratic twists. - ``_scaling`` will be set to a rational non-zero multiple if we succeed and to 1 otherwise. + ``_scaling`` will be set to a rational nonzero multiple if we succeed and to 1 otherwise. Even if we fail we scale at least to make up the difference between the periods of the `X_0`-optimal curve and our given curve `E` in the isogeny class. EXAMPLES:: - sage: m = EllipticCurve('11a1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('11a1').modular_symbol(implementation='sage') sage: m._scaling 1/5 - sage: m = EllipticCurve('11a2').modular_symbol(implementation="sage") + sage: m = EllipticCurve('11a2').modular_symbol(implementation='sage') sage: m._scaling 1 - sage: m = EllipticCurve('11a3').modular_symbol(implementation="sage") + sage: m = EllipticCurve('11a3').modular_symbol(implementation='sage') sage: m._scaling 1/25 - sage: m = EllipticCurve('37a1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('37a1').modular_symbol(implementation='sage') sage: m._scaling -1 sage: m = EllipticCurve('37a1').modular_symbol() @@ -501,16 +503,16 @@ def _find_scaling_L_ratio(self): sage: m = EllipticCurve('389a1').modular_symbol() sage: m._scaling 1 - sage: m = EllipticCurve('389a1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('389a1').modular_symbol(implementation='sage') sage: m._scaling 1 - sage: m = EllipticCurve('196a1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('196a1').modular_symbol(implementation='sage') sage: m._scaling 1 Some harder cases fail:: - sage: m = EllipticCurve('121b1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('121b1').modular_symbol(implementation='sage') Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1 and a power of 2 sage: m._scaling 1 @@ -520,8 +522,8 @@ def _find_scaling_L_ratio(self): sage: rk0 = ['11a1', '11a2', '15a1', '27a1', '37b1'] sage: for la in rk0: # long time (3s on sage.math, 2011) ....: E = EllipticCurve(la) - ....: me = E.modular_symbol(implementation="eclib") - ....: ms = E.modular_symbol(implementation="sage") + ....: me = E.modular_symbol(implementation='eclib') + ....: ms = E.modular_symbol(implementation='sage') ....: print("{} {} {}".format(E.lseries().L_ratio()*E.real_components(), me(0), ms(0))) 1/5 1/5 1/5 1 1 1 @@ -558,7 +560,7 @@ def _find_scaling_L_ratio(self): Dlist = [5,8,12,13,17,21,24,28,29, 33, 37, 40, 41, 44, 53, 56, 57, 60, 61, 65, 69, 73, 76, 77, 85, 88, 89, 92, 93, 97] # a list of positive fundamental discriminants j = 0 at0 = 0 - # computes [0]+ for the twist of E by D until one value is non-zero + # computes [0]+ for the twist of E by D until one value is nonzero while j < 30 and at0 == 0 : D = Dlist[j] # the following line checks if the twist of the newform of E by D is a newform @@ -580,7 +582,7 @@ def _find_scaling_L_ratio(self): j = 0 at0 = 0 while j < 30 and at0 == 0 : - # computes [0]+ for the twist of E by D until one value is non-zero + # computes [0]+ for the twist of E by D until one value is nonzero D = Dlist[j] if all( valuation(E.conductor(),ell) <= valuation(D,ell) for ell in prime_divisors(D) ) : at0 = - sum([kronecker_symbol(D,u) * self(ZZ(u)/D) for u in range(1,abs(D))]) @@ -712,7 +714,7 @@ def _call_with_caching(self, r): EXAMPLES:: - sage: m = EllipticCurve('11a1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('11a1').modular_symbol(implementation='sage') sage: m._call_with_caching(0) 1/5 """ @@ -733,7 +735,7 @@ def __call__(self, r, base_at_infinity=True): EXAMPLES:: - sage: m = EllipticCurve('11a1').modular_symbol(implementation="sage") + sage: m = EllipticCurve('11a1').modular_symbol(implementation='sage') sage: m(0) 1/5 """ diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py old mode 100644 new mode 100755 index a139cab50ce..eea2e5cc243 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -178,7 +178,7 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, - ``self`` -- an elliptic curve `E` over a number field `K` - - ``verbose`` -- 0, 1, 2, or 3 (default: 0), the verbosity level + - ``verbose`` -- 0, 1, 2, or 3 (default: 0); the verbosity level - ``lim1`` -- (default: 2) limit on trivial points on quartics @@ -192,14 +192,14 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, small and large prime numbers. Use probabilistic tests for large primes. If 0, do not use probabilistic tests. - - ``known_points`` -- (default: None) list of known points on + - ``known_points`` -- (default: ``None``) list of known points on the curve OUTPUT: a triple ``(lower, upper, list)`` consisting of - - ``lower`` (integer) -- lower bound on the rank + - ``lower`` -- integer; lower bound on the rank - - ``upper`` (integer) -- upper bound on the rank + - ``upper`` -- integer; upper bound on the rank - ``list`` -- list of points in `E(K)` @@ -250,15 +250,6 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, listpoints = [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] (1, 1, [(1/2*a + 3/2 : -a - 2 : 1)]) - sage: v = E.simon_two_descent(verbose=2) - K = bnfinit(y^2 + 7); - a = Mod(y,K.pol); - bnfellrank(K, [0, 0, 0, 1, a], [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7)]]); - ... - v = [1, 1, [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7)]]] - sage: v - (1, 1, [(1/2*a + 3/2 : -a - 2 : 1)]) - A curve with 2-torsion:: sage: K. = NumberField(x^2 + 7) @@ -318,19 +309,19 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, return t def height_pairing_matrix(self, points=None, precision=None, normalised=True): - r"""Return the height pairing matrix of the given points. + r""" + Return the height pairing matrix of the given points. INPUT: - - ``points`` (list or ``None`` (default)) -- a list of points - on this curve, or ``None``, in which case self.gens() will - be used. + - ``points`` -- list or ``None`` (default); list of points + on this curve, or ``None``, in which case ``self.gens()`` will + be used - - ``precision`` (int or ``None`` (default)) -- number of bits - of precision of result, or ``None``, for default RealField - precision. + - ``precision`` -- integer or ``None`` (default); number of bits + of precision of result, or ``None``, for default RealField precision - - ``normalised`` (bool, default ``True``) -- if ``True``, use + - ``normalised`` -- boolean (default: ``True``); if ``True``, use normalised heights which are independent of base change. Otherwise use the non-normalised Néron-Tate height, as required for the regulator in the BSD conjecture. @@ -416,12 +407,12 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): INPUT: - - ``points`` -- (default: empty list) a list of points on this curve + - ``points`` -- (default: empty list) a list of points on this curve - - ``precision`` -- int or None (default: None): the precision - in bits of the result (default real precision if None) + - ``precision`` -- integer or ``None`` (default); the + precision in bits of the result (default: real precision if ``None``) - - ``normalised`` (bool, default ``True``) -- if ``True``, use + - ``normalised`` -- boolean (default: ``True``); if ``True``, use normalised heights which are independent of base change. Otherwise use the non-normalised Néron-Tate height, as required for the regulator in the BSD conjecture @@ -522,16 +513,16 @@ def regulator_of_points(self, points=[], precision=None, normalised=True): if points is None: points = [] mat = self.height_pairing_matrix(points=points, precision=precision, normalised=normalised) - return mat.det(algorithm="hessenberg") + return mat.det(algorithm='hessenberg') def is_local_integral_model(self, *P): r""" - Tests if self is integral at the prime ideal `P`, or at all the + Test if ``self`` is integral at the prime ideal `P`, or at all the primes if `P` is a list or tuple. INPUT: - - ``*P`` -- a prime ideal, or a list or tuple of primes. + - ``*P`` -- a prime ideal, or a list or tuple of primes EXAMPLES:: @@ -552,7 +543,7 @@ def is_local_integral_model(self, *P): def local_integral_model(self,*P): r""" - Return a model of self which is integral at the prime ideal `P`. + Return a model of ``self`` which is integral at the prime ideal `P`. .. NOTE:: @@ -561,7 +552,7 @@ def local_integral_model(self,*P): INPUT: - - ``*P`` -- a prime ideal, or a list or tuple of primes. + - ``*P`` -- a prime ideal, or a list or tuple of primes EXAMPLES:: @@ -603,7 +594,7 @@ def is_global_integral_model(self): def global_integral_model(self): r""" - Return a model of self which is integral at all primes. + Return a model of ``self`` which is integral at all primes. EXAMPLES:: @@ -805,7 +796,7 @@ def _scale_by_units(self): sage: K. = QuadraticField(4569) sage: j = 46969655/32768 sage: E = EllipticCurve(j=K(j)) - sage: C = E.isogeny_class() + sage: C = E.isogeny_class() # long time (9.5s) """ K = self.base_field() r1, r2 = K.signature() @@ -838,28 +829,29 @@ def _scale_by_units(self): u = prod([uj**ej for uj,ej in zip(fu,es)]) return self.scale_curve(u) - def local_data(self, P=None, proof=None, algorithm="pari", globally=False): + def local_data(self, P=None, proof=None, algorithm='pari', globally=False): r""" Local data for this elliptic curve at the prime `P`. INPUT: - - ``P`` -- either None, a prime ideal of the base field of self, or an element of the base field that generates a prime ideal. + - ``P`` -- either ``None``, a prime ideal of the base field of ``self``, + or an element of the base field that generates a prime ideal - ``proof`` -- whether to only use provably correct methods (default controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - - ``algorithm`` (string, default: "pari") -- Ignored unless the - base field is `\QQ`. If "pari", use the PARI C-library + - ``algorithm`` -- string (default: ``'pari'``); ignored unless the + base field is `\QQ`. If ``'pari'``, use the PARI C-library :pari:`ellglobalred` implementation of Tate's algorithm over - `\QQ`. If "generic", use the general number field + `\QQ`. If ``'generic'``, use the general number field implementation. - ``globally`` -- whether the local algorithm uses global generators for the prime ideals. Default is False, which will not require any - information about the class group. If True, a generator for `P` + information about the class group. If ``True``, a generator for `P` will be used if `P` is principal. Otherwise, or if ``globally`` is False, the minimal model returned will preserve integrality at other primes, but not minimality. @@ -942,7 +934,7 @@ def local_data(self, P=None, proof=None, algorithm="pari", globally=False): return self._get_local_data(P,proof,algorithm,globally) - def _get_local_data(self, P, proof, algorithm="pari", globally=False): + def _get_local_data(self, P, proof, algorithm='pari', globally=False): r""" Internal function to create data for this elliptic curve at the prime `P`. @@ -952,22 +944,22 @@ def _get_local_data(self, P, proof, algorithm="pari", globally=False): INPUT: - - ``P`` -- either None or a prime ideal of the base field of self. + - ``P`` -- either ``None`` or a prime ideal of the base field of ``self`` - ``proof`` -- whether to only use provably correct methods (default controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - - ``algorithm`` (string, default: "pari") -- Ignored unless the - base field is `\QQ`. If "pari", use the PARI C-library + - ``algorithm`` -- string (default: ``'pari'``); ignored unless the + base field is `\QQ`. If ``'pari'``, use the PARI C-library :pari:`ellglobalred` implementation of Tate's algorithm over - `\QQ`. If "generic", use the general number field + `\QQ`. If ``'generic'``, use the general number field implementation. - ``globally`` -- whether the local algorithm uses global generators for the prime ideals. Default is False, which will not require any - information about the class group. If True, a generator for `P` + information about the class group. If ``True``, a generator for `P` will be used if `P` is principal. Otherwise, or if ``globally`` is False, the minimal model returned will preserve integrality at other primes, but not minimality. @@ -1006,23 +998,23 @@ def _get_local_data(self, P, proof, algorithm="pari", globally=False): self._local_data[P, proof, algorithm, globally] = EllipticCurveLocalData(self, P, proof, algorithm, globally) return self._local_data[P, proof, algorithm, globally] - def local_minimal_model(self, P, proof=None, algorithm="pari"): + def local_minimal_model(self, P, proof=None, algorithm='pari'): r""" Return a model which is integral at all primes and minimal at `P`. INPUT: - - ``P`` -- either None or a prime ideal of the base field of self. + - ``P`` -- either ``None`` or a prime ideal of the base field of ``self`` - ``proof`` -- whether to only use provably correct methods (default controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - - ``algorithm`` (string, default: "pari") -- Ignored unless the - base field is `\QQ`. If "pari", use the PARI C-library + - ``algorithm`` -- string (default: ``'pari'``); ignored unless the + base field is `\QQ`. If ``'pari'``, use the PARI C-library :pari:`ellglobalred` implementation of Tate's algorithm over - `\QQ`. If "generic", use the general number field + `\QQ`. If ``'generic'``, use the general number field implementation. OUTPUT: @@ -1056,16 +1048,16 @@ def local_minimal_model(self, P, proof=None, algorithm="pari"): def has_good_reduction(self, P): r""" - Return True if this elliptic curve has good reduction at the prime `P`. + Return ``True`` if this elliptic curve has good reduction at the prime `P`. INPUT: - - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + - ``P`` -- a prime ideal of the base field of ``self``, or a field + element generating such an ideal OUTPUT: - (bool) -- True if the curve has good reduction at `P`, else False. + boolean; ``True`` if the curve has good reduction at `P`, else ``False``. .. NOTE:: @@ -1090,16 +1082,16 @@ def has_good_reduction(self, P): def has_bad_reduction(self, P): r""" - Return True if this elliptic curve has bad reduction at the prime `P`. + Return ``True`` if this elliptic curve has bad reduction at the prime `P`. INPUT: - - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + - ``P`` -- a prime ideal of the base field of ``self``, or a field + element generating such an ideal OUTPUT: - (bool) True if the curve has bad reduction at `P`, else False. + boolean; ``True`` if the curve has bad reduction at `P`, else ``False``. .. NOTE:: @@ -1124,7 +1116,8 @@ def has_bad_reduction(self, P): def has_multiplicative_reduction(self, P): r""" - Return True if this elliptic curve has (bad) multiplicative reduction at the prime `P`. + Return ``True`` if this elliptic curve has (bad) multiplicative + reduction at the prime `P`. .. NOTE:: @@ -1133,13 +1126,13 @@ def has_multiplicative_reduction(self, P): INPUT: - - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + - ``P`` -- a prime ideal of the base field of ``self``, or a field + element generating such an ideal OUTPUT: - (bool) True if the curve has multiplicative reduction at `P`, - else False. + boolean; ``True`` if the curve has multiplicative reduction at `P`, + else ``False``. EXAMPLES:: @@ -1158,17 +1151,17 @@ def has_multiplicative_reduction(self, P): def has_split_multiplicative_reduction(self, P): r""" - Return True if this elliptic curve has (bad) split multiplicative reduction at the prime `P`. + Return ``True`` if this elliptic curve has (bad) split multiplicative reduction at the prime `P`. INPUT: - - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + - ``P`` -- a prime ideal of the base field of ``self``, or a field + element generating such an ideal OUTPUT: - (bool) True if the curve has split multiplicative reduction at - `P`, else False. + boolean; ``True`` if the curve has split multiplicative reduction at + `P`, else ``False``. EXAMPLES:: @@ -1187,17 +1180,18 @@ def has_split_multiplicative_reduction(self, P): def has_nonsplit_multiplicative_reduction(self, P): r""" - Return True if this elliptic curve has (bad) non-split multiplicative reduction at the prime `P`. + Return ``True`` if this elliptic curve has (bad) non-split + multiplicative reduction at the prime `P`. INPUT: - - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + - ``P`` -- a prime ideal of the base field of ``self``, or a field + element generating such an ideal OUTPUT: - (bool) True if the curve has non-split multiplicative - reduction at `P`, else False. + boolean; ``True`` if the curve has non-split multiplicative + reduction at `P`, else ``False``. EXAMPLES:: @@ -1216,16 +1210,18 @@ def has_nonsplit_multiplicative_reduction(self, P): def has_additive_reduction(self, P): r""" - Return True if this elliptic curve has (bad) additive reduction at the prime `P`. + Return ``True`` if this elliptic curve has (bad) additive reduction at + the prime `P`. INPUT: - - ``P`` -- a prime ideal of the base field of self, or a field - element generating such an ideal. + - ``P`` -- a prime ideal of the base field of ``self``, or a field + element generating such an ideal OUTPUT: - (bool) True if the curve has additive reduction at `P`, else False. + boolean; ``True`` if the curve has additive reduction at `P`, else + ``False``. EXAMPLES:: @@ -1248,16 +1244,14 @@ def tamagawa_number(self, P, proof=None): INPUT: - - ``P`` -- either None or a prime ideal of the base field of self. + - ``P`` -- either ``None`` or a prime ideal of the base field of ``self`` - ``proof`` -- whether to only use provably correct methods (default controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - OUTPUT: - - (positive integer) The Tamagawa number of the curve at `P`. + OUTPUT: positive integer; the Tamagawa number of the curve at `P` EXAMPLES:: @@ -1304,16 +1298,14 @@ def tamagawa_exponent(self, P, proof=None): INPUT: - - ``P`` -- either None or a prime ideal of the base field of self. + - ``P`` -- either ``None`` or a prime ideal of the base field of ``self`` - ``proof`` -- whether to only use provably correct methods (default controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - OUTPUT: - - (positive integer) The Tamagawa index of the curve at P. + OUTPUT: positive integer; the Tamagawa index of the curve at P EXAMPLES:: @@ -1343,9 +1335,7 @@ def tamagawa_product(self): additional factor when the model is not globally minimal, as required by the BSD formula. - OUTPUT: - - A positive integer. + OUTPUT: a positive integer EXAMPLES:: @@ -1398,9 +1388,7 @@ def tamagawa_product_bsd(self): of the Tamagawa numbers, so the two definitions only agree when the model is global minimal. - OUTPUT: - - A rational number + OUTPUT: a rational number EXAMPLES:: @@ -1454,16 +1442,14 @@ def kodaira_symbol(self, P, proof=None): INPUT: - - ``P`` -- either None or a prime ideal of the base field of self. + - ``P`` -- either ``None`` or a prime ideal of the base field of ``self`` - ``proof`` -- whether to only use provably correct methods (default controlled by global proof module). Note that the proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - OUTPUT: - - The Kodaira Symbol of the curve at ``P``, represented as a string. + OUTPUT: the Kodaira Symbol of the curve at ``P``, represented as a string EXAMPLES:: @@ -1491,9 +1477,7 @@ def conductor(self): Return the conductor of this elliptic curve as a fractional ideal of the base field. - OUTPUT: - - (fractional ideal) The conductor of the curve. + OUTPUT: fractional ideal; the conductor of the curve EXAMPLES:: @@ -1628,7 +1612,7 @@ def non_minimal_primes(self): sage: Emin.non_minimal_primes() [] - If the model is not globally integral, a ``ValueError`` is + If the model is not globally integral, a :exc:`ValueError` is raised:: sage: E = EllipticCurve([0, 0, 0, 1/2, 1/3]) @@ -1757,7 +1741,7 @@ def has_global_minimal_model(self): OUTPUT: - Boolean, True iff a global minimal model exists, i.e. an + boolean; ``True`` iff a global minimal model exists, i.e. an integral model which is minimal at every prime. EXAMPLES:: @@ -1773,7 +1757,7 @@ def has_global_minimal_model(self): def global_minimal_model(self, proof=None, semi_global=False): r""" - Return a model of self that is integral, and minimal. + Return a model of ``self`` that is integral, and minimal. .. NOTE:: @@ -1789,7 +1773,7 @@ def global_minimal_model(self, proof=None, semi_global=False): proof module is number_field, not elliptic_curves, since the functions that actually need the flag are in number fields. - - ``semi_global`` (boolean, default: ``False``) -- if there is no + - ``semi_global``-- boolean (default: ``False``); if there is no global minimal mode, return a semi-global minimal model (minimal at all but one prime) instead, if True; raise an error if False. No effect if a global minimal model exists. @@ -1922,9 +1906,7 @@ def reduction(self,place): - ``place`` -- a prime ideal in the base field of the curve - OUTPUT: - - An elliptic curve over a finite field, the residue field of the place. + OUTPUT: an elliptic curve over a finite field, the residue field of the place EXAMPLES:: @@ -1971,7 +1953,7 @@ def torsion_subgroup(self): r""" Return the torsion subgroup of this elliptic curve. - OUTPUT: The :class:`EllipticCurveTorsionSubgroup` associated to this elliptic + OUTPUT: the :class:`EllipticCurveTorsionSubgroup` associated to this elliptic curve. EXAMPLES:: @@ -2030,9 +2012,7 @@ def torsion_order(self): r""" Return the order of the torsion subgroup of this elliptic curve. - OUTPUT: - - (integer) the order of the torsion subgroup of this elliptic curve. + OUTPUT: integer EXAMPLES:: @@ -2072,9 +2052,7 @@ def torsion_points(self): r""" Return a list of the torsion points of this elliptic curve. - OUTPUT: - - (list) A sorted list of the torsion points. + OUTPUT: sorted list of the torsion points EXAMPLES:: @@ -2162,11 +2140,11 @@ def rank_bounds(self, **kwds): INPUT: - - ``verbose`` -- 0, 1, 2, or 3 (default: 0), the verbosity level + - ``verbose`` -- 0, 1, 2, or 3 (default: 0); the verbosity level - - ``lim1`` -- (default: 2) limit on trivial points on quartics + - ``lim1`` -- (default: 2) limit on trivial points on quartics - - ``lim3`` -- (default: 4) limit on points on ELS quartics + - ``lim3`` -- (default: 4) limit on points on ELS quartics - ``limtriv`` -- (default: 2) limit on trivial points on elliptic curve @@ -2176,12 +2154,10 @@ def rank_bounds(self, **kwds): small and large prime numbers. Use probabilistic tests for large primes. If 0, do not use probabilistic tests. - - ``known_points`` -- (default: None) list of known points on + - ``known_points`` -- (default: ``None``) list of known points on the curve - OUTPUT: - - lower and upper bounds for the rank of the Mordell-Weil group + OUTPUT: lower and upper bounds for the rank of the Mordell-Weil group .. NOTE:: @@ -2239,11 +2215,11 @@ def rank(self, **kwds): INPUT: - - ``verbose`` -- 0, 1, 2, or 3 (default: 0), the verbosity level + - ``verbose`` -- 0, 1, 2, or 3 (default: 0); the verbosity level - - ``lim1`` -- (default: 2) limit on trivial points on quartics + - ``lim1`` -- (default: 2) limit on trivial points on quartics - - ``lim3`` -- (default: 4) limit on points on ELS quartics + - ``lim3`` -- (default: 4) limit on points on ELS quartics - ``limtriv`` -- (default: 2) limit on trivial points on elliptic curve @@ -2253,14 +2229,14 @@ def rank(self, **kwds): small and large prime numbers. Use probabilistic tests for large primes. If 0, do not use probabilistic tests. - - ``known_points`` -- (default: None) list of known points on + - ``known_points`` -- (default: ``None``) list of known points on the curve OUTPUT: If the upper and lower bounds given by Simon two-descent are the same, then the rank has been uniquely identified and we - return this. Otherwise, we raise a :class:`ValueError` with an error + return this. Otherwise, we raise a :exc:`ValueError` with an error message specifying the upper and lower bounds. .. NOTE:: @@ -2321,11 +2297,11 @@ def gens(self, **kwds): INPUT: - - ``verbose`` -- 0, 1, 2, or 3 (default: 0), the verbosity level + - ``verbose`` -- 0, 1, 2, or 3 (default: 0); the verbosity level - - ``lim1`` -- (default: 2) limit on trivial points on quartics + - ``lim1`` -- (default: 2) limit on trivial points on quartics - - ``lim3`` -- (default: 4) limit on points on ELS quartics + - ``lim3`` -- (default: 4) limit on points on ELS quartics - ``limtriv`` -- (default: 2) limit on trivial points on elliptic curve @@ -2335,12 +2311,10 @@ def gens(self, **kwds): small and large prime numbers. Use probabilistic tests for large primes. If 0, do not use probabilistic tests. - - ``known_points`` -- (default: None) list of known points on + - ``known_points`` -- (default: ``None``) list of known points on the curve - OUTPUT: - - A set of points of infinite order given by the Simon two-descent. + OUTPUT: a set of points of infinite order given by the Simon two-descent .. NOTE:: @@ -2416,7 +2390,7 @@ def period_lattice(self, embedding): INPUT: - - ``embedding`` -- an embedding of the base number field into `\RR` or `\CC`. + - ``embedding`` -- an embedding of the base number field into `\RR` or `\CC` .. NOTE:: @@ -2529,7 +2503,7 @@ def real_components(self, embedding): def height_function(self): """ - Return the canonical height function attached to self. + Return the canonical height function attached to ``self``. EXAMPLES:: @@ -2555,17 +2529,17 @@ def isogeny_class(self, reducible_primes=None, algorithm='Billerey', minimal_mod INPUT: - - ``reducible_primes`` (list of ints, or None (default)) -- if - not None then this should be a list of primes; in computing + - ``reducible_primes`` -- list of integers or ``None`` (default)); if + not ``None`` then this should be a list of primes; in computing the isogeny class, only composites isogenies of these degrees will be used. - - ``algorithm`` (string, default ``'Billerey'``) -- the algorithm + - ``algorithm`` -- string (default: ``'Billerey'``); the algorithm to use to compute the reducible primes. Ignored for CM curves or if ``reducible_primes`` is provided. Values are ``'Billerey'`` (default), ``'Larson'``, and ``'heuristic'``. - - ``minimal_models`` (bool, default ``True``) -- if ``True``, + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves in the class will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -2945,27 +2919,25 @@ class number is only `3` is that the class also contains three def isogenies_prime_degree(self, l=None, algorithm='Billerey', minimal_models=True): r""" - Return a list of `\ell`-isogenies from self, where `\ell` is a + Return a list of `\ell`-isogenies from ``self``, where `\ell` is a prime. INPUT: - - ``l`` -- either None or a prime or a list of primes. + - ``l`` -- either ``None`` or a prime or a list of primes - - ``algorithm`` (string, default 'Billerey') -- the algorithm - to use to compute the reducible primes when ``l`` is None. + - ``algorithm`` -- string (default: ``'Billerey'``); the algorithm + to use to compute the reducible primes when ``l`` is ``None``. Ignored for CM curves or if ``l`` is provided. Values are 'Billerey' (default), 'Larson', and 'heuristic'. - - ``minimal_models`` (bool, default ``True``) -- if ``True``, + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. - OUTPUT: - - (list) `\ell`-isogenies for the given `\ell` or if `\ell` is None, all - isogenies of prime degree (see below for the CM case). + OUTPUT: list; `\ell`-isogenies for the given `\ell` or if `\ell` is + ``None``, all isogenies of prime degree (see below for the CM case) .. NOTE:: @@ -3060,26 +3032,26 @@ def isogenies_prime_degree(self, l=None, algorithm='Billerey', minimal_models=Tr def is_isogenous(self, other, proof=True, maxnorm=100): """ - Return whether or not self is isogenous to other. + Return whether or not ``self`` is isogenous to ``other``. INPUT: - - ``other`` -- another elliptic curve. + - ``other`` -- another elliptic curve - - ``proof`` (default: ``True``) -- If ``False``, the function will - return ``True`` whenever the two curves have the same + - ``proof`` -- boolean (default: ``True``); if ``False``, the function + will return ``True`` whenever the two curves have the same conductor and are isogenous modulo `p` for all primes `p` of norm up to ``maxnorm``. If ``True``, the function returns False when the previous condition does not hold, and if it does hold we compute the complete isogeny class to see if the curves are indeed isogenous. - - ``maxnorm`` (integer, default 100) -- The maximum norm of - primes `p` for which isogeny modulo `p` will be checked. + - ``maxnorm`` -- integer (default: 100); the maximum norm of + primes `p` for which isogeny modulo `p` will be checked OUTPUT: - (bool) True if there is an isogeny from curve ``self`` to + boolean; ``True`` if there is an isogeny from curve ``self`` to curve ``other``. EXAMPLES:: @@ -3238,16 +3210,14 @@ def is_isogenous(self, other, proof=True, maxnorm=100): def isogeny_degree(self, other): """ - Return the minimal degree of an isogeny between self and - other, or 0 if no isogeny exists. + Return the minimal degree of an isogeny between ``self`` and + ``other``, or 0 if no isogeny exists. INPUT: - - ``other`` -- another elliptic curve. - - OUTPUT: + - ``other`` -- another elliptic curve - (int) The degree of an isogeny from ``self`` to ``other``, or 0. + OUTPUT: integer; the degree of an isogeny from ``self`` to ``other``, or 0 EXAMPLES:: @@ -3306,17 +3276,17 @@ def reducible_primes(self, algorithm='Billerey', max_l=None, INPUT: - - ``algorithm`` (string) -- only relevant for non-CM curves. + - ``algorithm`` -- string; only relevant for non-CM curves Either 'Billerey", to use the methods of [Bil2011]_, 'Larson' to use Larson's implementation using Galois representations, or 'heuristic' (see below). - - ``max_l`` (int or ``None``) -- only relevant for non-CM + - ``max_l`` -- integer or ``None``; only relevant for non-CM curves and algorithms 'Billerey' and 'heuristic. Controls the maximum prime used in either algorithm. If ``None``, use the default for that algorithm. - - ``num_l`` (int or ``None``) -- only relevant for non-CM + - ``num_l`` -- integer or ``None``; only relevant for non-CM curves and algorithm 'Billerey'. Controls the maximum number of primes used in the algorithm. If ``None``, use the default for that algorithm. @@ -3370,8 +3340,8 @@ def lll_reduce(self, points, height_matrix=None, precision=None): INPUT: - - ``points`` -- a list of points on this elliptic - curve, which should be independent. + - ``points`` -- list of points on this elliptic + curve, which should be independent - ``height_matrix`` -- the height-pairing matrix of the points, or ``None``. If ``None``, it will be computed. @@ -3380,7 +3350,7 @@ def lll_reduce(self, points, height_matrix=None, precision=None): computations (default: ``None``, for default RealField precision; ignored if ``height_matrix`` is supplied) - OUTPUT: A tuple (newpoints, U) where U is a unimodular integer + OUTPUT: a tuple (newpoints, U) where U is a unimodular integer matrix, new_points is the transform of points by U, such that new_points has LLL-reduced height pairing matrix @@ -3711,14 +3681,14 @@ def is_Q_curve(self, maxp=100, certificate=False, verbose=False): INPUT: - - ``maxp`` (int, default 100): bound on primes used for + - ``maxp`` -- integer (default: 100); bound on primes used for checking necessary local conditions. The result will not depend on this, but using a larger value may return ``False`` faster. - - ``certificate`` (bool, default ``False``): if ``True`` then + - ``certificate`` -- boolean (default: ``False``); if ``True`` then a second value is returned giving a certificate for the - `\QQ`-curve property. + `\QQ`-curve property OUTPUT: @@ -3862,42 +3832,42 @@ def saturation(self, points, verbose=False, order are ignored; the remaining points should be independent, or an error is raised. - - ``verbose`` (bool) -- (default: ``False``), if ``True``, give - verbose output. + - ``verbose`` -- boolean (default: ``False``); if ``True``, give + verbose output - - ``max_prime`` (int, default 0) -- saturation is performed + - ``max_prime`` -- integer (default: 0); saturation is performed for all primes up to ``max_prime``. If ``max_prime`` is 0, perform saturation at *all* primes, i.e., compute the true saturation. - - ``odd_primes_only`` (bool, default ``False``) -- only do - saturation at odd primes. + - ``odd_primes_only`` -- boolean (default: ``False``); only do + saturation at odd primes - - ``one_prime`` (int, default 0) -- if nonzero, only do - saturation at this prime. + - ``one_prime`` -- integer (default: 0); if nonzero, only do + saturation at this prime The following two inputs are optional, and may be provided to speed up the computation. - - ``lower_ht_bound`` (real, default ``None``) -- lower bound of - the regulator `E(K)`, if known. + - ``lower_ht_bound`` -- real (default: ``None``); lower bound of + the regulator `E(K)`, if known - - ``reg`` (real, default ``None``) -- regulator of the span of - points, if known. + - ``reg`` -- real (default: ``None``); regulator of the span of + points, if known - - ``debug`` (int, default 0) -- used for debugging and - testing. + - ``debug`` -- integer (default: 0); used for debugging and + testing OUTPUT: - - ``saturation`` (list) -- points that form a basis for the - saturation. + - ``saturation`` -- list; points that form a basis for the + saturation - - ``index`` (int) -- the index of the group generated by the - input points in their saturation. + - ``index`` -- integer; the index of the group generated by the + input points in their saturation - - ``regulator`` (real with default precision, or ``None``) -- - regulator of saturated points. + - ``regulator`` -- real with default precision, or ``None``; + regulator of saturated points EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/ell_padic_field.py b/src/sage/schemes/elliptic_curves/ell_padic_field.py old mode 100644 new mode 100755 index 2867ff51d23..32f4a48a807 --- a/src/sage/schemes/elliptic_curves/ell_padic_field.py +++ b/src/sage/schemes/elliptic_curves/ell_padic_field.py @@ -1,6 +1,6 @@ # sage.doctest: needs sage.rings.padics """ -Elliptic curves over padic fields +Elliptic curves over `p`-adic fields """ # **************************************************************************** # Copyright (C) 2007 Robert Bradshaw @@ -30,7 +30,7 @@ class EllipticCurve_padic_field(EllipticCurve_field, HyperellipticCurve_padic_field): """ - Elliptic curve over a padic field. + Elliptic curve over a `p`-adic field. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py old mode 100644 new mode 100755 index 63d50cc0b0d..d9b7189552e --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -75,7 +75,7 @@ Arithmetic over `\ZZ/N\ZZ` with composite `N` is supported. When an operation tries to invert a non-invertible element, a -:class:`ZeroDivisionError` is raised and a factorization of the modulus appears +:exc:`ZeroDivisionError` is raised and a factorization of the modulus appears in the error message:: sage: N = 1715761513 @@ -117,32 +117,28 @@ import math -from sage.rings.padics.factory import Qp -from sage.rings.padics.precision_error import PrecisionError - +import sage.groups.generic as generic import sage.rings.abc +from sage.misc.lazy_import import lazy_import +from sage.rings.finite_rings.integer_mod import Mod from sage.rings.infinity import Infinity as oo from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ +from sage.rings.padics.precision_error import PrecisionError from sage.rings.rational_field import QQ -from sage.rings.finite_rings.integer_mod import Mod -from sage.rings.real_mpfr import RealField -from sage.rings.real_mpfr import RR -import sage.groups.generic as generic - -from sage.structure.element import AdditiveGroupElement -from sage.structure.sequence import Sequence -from sage.structure.richcmp import richcmp - -from sage.structure.coerce_actions import IntegerMulAction - +from sage.rings.real_mpfr import RealField, RR from sage.schemes.curves.projective_curve import Hasse_bounds +from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring, SchemeMorphism_point_abelian_variety_field) -from sage.schemes.generic.morphism import is_SchemeMorphism +from sage.structure.coerce_actions import IntegerMulAction +from sage.structure.element import AdditiveGroupElement +from sage.structure.richcmp import richcmp +from sage.structure.sequence import Sequence -from .constructor import EllipticCurve +lazy_import('sage.rings.padics.factory', 'Qp') +lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') try: from sage.libs.pari.all import pari, PariError @@ -179,7 +175,8 @@ def curve(self): sage: K. = NumberField(x^2 - 3,'a') # needs sage.rings.number_field sage: P = E.base_extend(K)(1, a) # needs sage.rings.number_field sage: P.scheme() # needs sage.rings.number_field - Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^2 - 3 + Elliptic Curve defined by y^2 = x^3 + x + 1 over + Number Field in a with defining polynomial x^2 - 3 """ return self.scheme() @@ -276,9 +273,9 @@ def __init__(self, curve, v, check=True): INPUT: - - curve -- an elliptic curve - - v -- data determining a point (another point, the integer - 0, or a tuple of coordinates) + - ``curve`` -- an elliptic curve + - ``v`` -- data determining a point (another point, the integer + 0, or a tuple of coordinates) EXAMPLES:: @@ -294,7 +291,7 @@ def __init__(self, curve, v, check=True): """ point_homset = curve.point_homset() R = point_homset.value_ring() - if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field): + if isinstance(v, SchemeMorphism): v = list(v) elif v == 0: v = (R.zero(), R.one(), R.zero()) @@ -409,7 +406,7 @@ def _richcmp_(self, other, op): def __pari__(self): r""" - Converts this point to PARI format. + Convert this point to PARI format. EXAMPLES:: @@ -455,7 +452,7 @@ def order(self): Return the order of this point on the elliptic curve. If the point is zero, returns 1, otherwise raise a - :class:`NotImplementedError`. + :exc:`NotImplementedError`. For curves over number fields and finite fields, see below. @@ -511,7 +508,7 @@ def has_order(self, n): INPUT: - - ``n`` -- integer, or its :class:`~sage.structure.factorization.Factorization` + - ``n`` -- integer or its :class:`~sage.structure.factorization.Factorization` ALGORITHM: @@ -635,11 +632,11 @@ def has_finite_order(self): def has_infinite_order(self): """ - Return True if this point has infinite additive order as an element + Return ``True`` if this point has infinite additive order as an element of the group of points on this curve. For fields other than number fields and finite fields, this is - NotImplemented unless self.is_zero(). + NotImplemented unless ``self.is_zero()``. EXAMPLES:: @@ -667,7 +664,7 @@ def plot(self, **args): INPUT: - ``**args`` -- all arguments get passed directly onto the point - plotting function. + plotting function EXAMPLES:: @@ -686,7 +683,7 @@ def plot(self, **args): def _add_(self, right): """ - Add self to right. + Add ``self`` to ``right``. EXAMPLES:: @@ -776,7 +773,7 @@ def _add_(self, right): def _sub_(self, right): """ - Subtract right from self. + Subtract ``right`` from ``self``. EXAMPLES:: @@ -822,7 +819,7 @@ def __neg__(self): def xy(self): """ Return the `x` and `y` coordinates of this point, as a 2-tuple. - If this is the point at infinity, a :class:`ZeroDivisionError` is raised. + If this is the point at infinity, a :exc:`ZeroDivisionError` is raised. EXAMPLES:: @@ -845,7 +842,7 @@ def xy(self): def x(self): """ Return the `x` coordinate of this point, as an element of the base field. - If this is the point at infinity, a :class:`ZeroDivisionError` is raised. + If this is the point at infinity, a :exc:`ZeroDivisionError` is raised. EXAMPLES:: @@ -868,7 +865,7 @@ def x(self): def y(self): """ Return the `y` coordinate of this point, as an element of the base field. - If this is the point at infinity, a :class:`ZeroDivisionError` is raised. + If this is the point at infinity, a :exc:`ZeroDivisionError` is raised. EXAMPLES:: @@ -890,16 +887,16 @@ def y(self): def is_divisible_by(self, m): """ - Return True if there exists a point `Q` defined over the same - field as self such that `mQ` == self. + Return ``True`` if there exists a point `Q` defined over the same + field as ``self`` such that `mQ` == ``self``. INPUT: - - ``m`` -- a positive integer. + - ``m`` -- positive integer OUTPUT: - (bool) -- True if there is a solution, else False. + boolean; ``True`` if there is a solution, else False. .. WARNING:: @@ -1014,21 +1011,19 @@ def division_points(self, m, poly_only=False): r""" Return a list of all points `Q` such that `mQ=P` where `P` = ``self``. - Only points on the elliptic curve containing self and defined + Only points on the elliptic curve containing ``self`` and defined over the base field are included. INPUT: - - ``m`` -- a positive integer + - ``m`` -- positive integer - - ``poly_only`` -- bool (default: ``False``); if True return + - ``poly_only`` -- boolean (default: ``False``); if ``True`` return polynomial whose roots give all possible `x`-coordinates of - `m`-th roots of ``self``. + `m`-th roots of ``self`` - OUTPUT: - - (list) -- a (possibly empty) list of solutions `Q` to `mQ=P`, - where `P` = self. + OUTPUT: a (possibly empty) list of solutions `Q` to `mQ=P`, + where `P` = ``self`` EXAMPLES: @@ -1153,12 +1148,19 @@ def division_points(self, m, poly_only=False): 3 sage: [(Q,Q._order) for Q in P.division_points(4)] [((-2 : -7 : 1), 6), ((1 : 2 : 1), 6), ((4 : -7 : 1), 3), ((13 : 38 : 1), 6)] + + Check for :issue:`38796`:: + + sage: E = EllipticCurve(GF(127), [1,1]) + sage: P = E(72, 24) + sage: [-1*Q for Q in P.division_points(-1)] + [(72 : 24 : 1)] """ # Coerce the input m to an integer m = Integer(m) # Check for trivial cases of m = 1, -1 and 0. if m == 1 or m == -1: - return [self] + return [m*self] if m == 0: if self == 0: # then every point Q is a solution, but... return [self] @@ -1260,20 +1262,19 @@ def division_points(self, m, poly_only=False): def _divide_out(self, p): r""" - Return `(Q,k)` where `p^kQ` == self and `Q` cannot be divided by `p`. + Return `(Q,k)` where `p^kQ` == ``self`` and `Q` cannot be divided by `p`. .. WARNING:: It is up to the caller to make sure that this does not loop endlessly. It is used in ``EllipticCurve_generic._p_primary_torsion_basis()``, when - self will always have (finite) order which is a power of `p`, + ``self`` will always have (finite) order which is a power of `p`, so that the order of `Q` increases by a factor of `p` at each stage. Since it will clearly be in danger of looping when - self.is_zero(), this case is caught, but otherwise caveat - user. + ``self.is_zero()``, this case is caught, but otherwise caveat user. EXAMPLES:: @@ -1326,7 +1327,7 @@ def set_order(self, value=None, *, multiple=None, check=True): - ``value`` -- positive integer - ``multiple`` -- positive integer; mutually exclusive with ``value`` - OUTPUT: ``None`` + OUTPUT: none EXAMPLES: @@ -1483,17 +1484,17 @@ def set_order(self, value=None, *, multiple=None, check=True): def _line_(self, R, Q): r""" - Computes the value at `Q` of a straight line through points - self and `R`. + Compute the value at `Q` of a straight line through points + ``self`` and `R`. INPUT: - - ``R``, ``Q`` -- points on self.curve() with ``Q`` nonzero. + - ``R``, ``Q`` -- points on ``self.curve()`` with `Q` nonzero OUTPUT: - An element of the base field self.curve().base_field(). - A ValueError is raised if ``Q`` is zero. + An element of the base field ``self.curve().base_field()``. + A :exc:`ValueError` is raised if `Q` is zero. EXAMPLES:: @@ -1564,15 +1565,15 @@ def _miller_(self, Q, n): INPUT: - - ``Q`` -- a nonzero point on self.curve(). + - ``Q`` -- a nonzero point on ``self.curve()`` - - ``n`` -- a nonzero integer. If `n<0` then return `Q` - evaluated at `1/(v_{nP}*f_{n,P})` (used in the ate pairing). + - ``n`` -- nonzero integer; if `n<0` then return `Q` + evaluated at `1/(v_{nP}*f_{n,P})` (used in the ate pairing) OUTPUT: An element in the base field ``self.curve().base_field()``. - A :class:`ValueError` is raised if `Q` is zero. + A :exc:`ValueError` is raised if `Q` is zero. EXAMPLES:: @@ -1745,19 +1746,17 @@ def weil_pairing(self, Q, n, algorithm=None): INPUT: - - ``Q`` -- another point on the same curve as ``self``. + - ``Q`` -- another point on the same curve as ``self`` - - ``n`` -- an integer `n` such that `nP = nQ = (0:1:0)`, where - `P` is ``self``. + - ``n`` -- integer `n` such that `nP = nQ = (0:1:0)`, where + `P` is ``self`` - - ``algorithm`` (default: ``None``) -- choices are ``pari`` - and ``sage``. PARI is usually significantly faster, but it + - ``algorithm`` -- (default: ``None``) choices are ``'pari'`` + and ``'sage'``. PARI is usually significantly faster, but it only works over finite fields. When ``None`` is given, a suitable algorithm is chosen automatically. - OUTPUT: - - An `n`'th root of unity in the base field of the curve. + OUTPUT: an `n`-th root of unity in the base field of the curve EXAMPLES:: @@ -1851,7 +1850,7 @@ def weil_pairing(self, Q, n, algorithm=None): - For ``algorithm='sage'``: Implemented using Proposition 8 in [Mil2004]_. The value 1 is returned for linearly dependent input points. This condition - is caught via a :class:`ZeroDivisionError`, since the use of a + is caught via a :exc:`ZeroDivisionError`, since the use of a discrete logarithm test for linear dependence is much too slow for large `n`. @@ -1937,21 +1936,21 @@ def tate_pairing(self, Q, n, k, q=None): INPUT: - - ``P=self`` -- Elliptic curve point having order n + - ``P=self`` -- elliptic curve point having order `n` - - ``Q`` -- Elliptic curve point on same curve as P (can be any order) + - ``Q`` -- elliptic curve point on same curve as `P` (can be any order) - - ``n`` -- positive integer: order of P + - ``n`` -- positive integer; order of `P` - - ``k`` -- positive integer: embedding degree + - ``k`` -- positive integer; embedding degree - - ``q`` -- positive integer: size of base field (the "big" + - ``q`` -- positive integer; size of base field (the "big" field is `GF(q^k)`. `q` needs to be set only if its value cannot be deduced.) OUTPUT: - An `n`'th root of unity in the base field ``self.curve().base_field()`` + An `n`-th root of unity in the base field ``self.curve().base_field()``. EXAMPLES: @@ -2129,18 +2128,18 @@ def ate_pairing(self, Q, n, k, t, q=None): INPUT: - - `P` (``=self``) -- a point of order `n`, in `ker(\pi-1)`, where - `\pi` is the `q`-Frobenius map (e.g., `P` is `q`-rational). + - ``P`` (``=self``) -- a point of order `n`, in `ker(\pi-1)`, where + `\pi` is the `q`-Frobenius map (e.g., `P` is `q`-rational) - ``Q`` -- a point of order `n` in `ker(\pi-q)` - - ``n`` -- the order of `P` and `Q`. + - ``n`` -- the order of `P` and `Q` - - ``k`` -- the embedding degree. + - ``k`` -- the embedding degree - - ``t`` -- the trace of Frobenius of the curve over `GF(q)`. + - ``t`` -- the trace of Frobenius of the curve over `GF(q)` - - ``q`` -- (default: None) the size of base field (the "big" + - ``q`` -- (default: ``None``) the size of base field (the "big" field is `GF(q^k)`). `q` needs to be set only if its value cannot be deduced. @@ -2387,6 +2386,7 @@ def point_of_jacobian_of_curve(self): G = J.group(self.base_ring()) return G(P - P.degree()*Pinf) + class EllipticCurvePoint_number_field(EllipticCurvePoint_field): """ A point on an elliptic curve over a number field. @@ -2537,7 +2537,7 @@ def has_finite_order(self): def has_infinite_order(self): r""" - Return True iff this point has infinite order on the elliptic curve. + Return ``True`` iff this point has infinite order on the elliptic curve. EXAMPLES:: @@ -2560,7 +2560,7 @@ def has_infinite_order(self): def is_on_identity_component(self, embedding=None): r""" - Return True iff this point is on the identity component of + Return ``True`` iff this point is on the identity component of its curve with respect to a given (real or complex) embedding. INPUT: @@ -2574,8 +2574,8 @@ def is_on_identity_component(self, embedding=None): OUTPUT: - (bool) -- ``True`` iff the point is on the identity component of - the curve. (If the point is zero then the result is True.) + boolean; ``True`` iff the point is on the identity component of + the curve. (If the point is zero then the result is ``True``.) EXAMPLES: @@ -2638,7 +2638,7 @@ def is_on_identity_component(self, embedding=None): def has_good_reduction(self, P=None): r""" - Returns True iff this point has good reduction modulo a prime. + Return ``True`` iff this point has good reduction modulo a prime. INPUT: @@ -2647,9 +2647,9 @@ def has_good_reduction(self, P=None): OUTPUT: - (bool) If a prime `P` of the base field is specified, returns - True iff the point has good reduction at `P`; otherwise, - return true if the point has god reduction at all primes in + boolean; if a prime `P` of the base field is specified, returns + ``True`` iff the point has good reduction at `P`; otherwise, + return ``True`` if the point has god reduction at all primes in the support of the discriminant of this model. EXAMPLES:: @@ -2764,13 +2764,11 @@ def reduction(self, p): INPUT: - - ``self`` -- A point on an elliptic curve. + - ``self`` -- a point on an elliptic curve - ``p`` -- a prime number - OUTPUT: - - The point reduced to be a point on the elliptic curve modulo `p`. + OUTPUT: the point reduced to be a point on the elliptic curve modulo `p` EXAMPLES:: @@ -2816,25 +2814,23 @@ def height(self, precision=None, normalised=True, algorithm='pari'): INPUT: - - ``self`` -- a point on an elliptic curve over a number field - `K`. + - ``self`` -- a point on an elliptic curve over a number field `K` - - ``precision`` -- positive integer, or None (default). The - precision in bits of the result. If None, the default real + - ``precision`` -- positive integer, or ``None`` (default). The + precision in bits of the result. If ``None``, the default real precision is used. - - ``normalised`` -- boolean. If True (default), the height is - normalised to be invariant under extension of `K`. If False, - return this normalised height multiplied by the degree of - `K`. + - ``normalised`` -- boolean. If ``True`` (default), the height is + normalised to be invariant under extension of `K`. If ``False``, + return this normalised height multiplied by the degree of `K`. - - ``algorithm`` -- string: either ``'pari'`` (default) or ``'sage'``. + - ``algorithm`` -- string; either ``'pari'`` (default) or ``'sage'``. If ``'pari'`` and the base field is `\QQ`, use the PARI library function; otherwise use the Sage implementation. OUTPUT: - The rational number 0, or a non-negative real number. + The rational number 0, or a nonnegative real number. There are two normalisations used in the literature, one of which is double the other. We use the larger of the two, which @@ -3041,6 +3037,19 @@ def height(self, precision=None, normalised=True, algorithm='pari'): sage: P2 = F([2,5]) # needs sage.rings.number_field sage: P2.height() # needs sage.rings.number_field 1.06248137652528 + + This shows that the bug reported at :issue:`36834` (incorrect + value when the model is not integral) has been fixed:: + + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^2 - 84131656042917) + sage: E = EllipticCurve(K, [0, 0, 0, -5482707841/48, -244634179112639/864]) + sage: P = E(349189/12, 1/2*a) + sage: P.height() + 10.4560438181991 + sage: [(n*P).height()/P.height() for n in [2,3,4,5]] + [4.00000000000000, 9.00000000000000, 16.0000000000000, 25.0000000000000] + """ if self.has_finite_order(): return QQ(0) @@ -3079,26 +3088,24 @@ def height(self, precision=None, normalised=True, algorithm='pari'): def archimedean_local_height(self, v=None, prec=None, weighted=False): """ - Compute the local height of self at the archimedean place `v`. + Compute the local height of ``self`` at the archimedean place `v`. INPUT: - - ``self`` -- a point on an elliptic curve over a number field - `K`. + - ``self`` -- a point on an elliptic curve over a number field `K` - ``v`` -- a real or complex embedding of K, or None (default). If `v` is a real or complex embedding, return the local - height of self at `v`. If `v` is None, return the total + height of ``self`` at `v`. If `v` is None, return the total archimedean contribution to the global height. - - ``prec`` -- integer, or None (default). The precision of the - computation. If None, the precision is deduced from `v`. + - ``prec`` -- integer or ``None`` (default). The precision of the + computation. If ``None``, the precision is deduced from `v` - - ``weighted`` -- boolean. If False (default), the height is - normalised to be invariant under extension of `K`. If True, + - ``weighted`` -- boolean. If ``False`` (default), the height is + normalised to be invariant under extension of `K`. If ``True``, return this normalised height multiplied by the local degree - if `v` is a single place, or by the degree of `K` if `v` is - None. + if `v` is a single place, or by the degree of `K` if `v` is ``None``. OUTPUT: @@ -3146,7 +3153,7 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False): sage: P.archimedean_local_height() 1.98723816350773 - Local heights of torsion points can be non-zero (unlike the + Local heights of torsion points can be nonzero (unlike the global height):: sage: # needs sage.rings.number_field @@ -3314,26 +3321,31 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False): def non_archimedean_local_height(self, v=None, prec=None, weighted=False, is_minimal=None): """ - Compute the local height of ``self`` at the non-archimedean place `v`. + Compute the local height of ``self`` at non-archimedean places. INPUT: - - ``self`` -- a point on an elliptic curve over a number field - `K`. + - ``self`` -- a point on an elliptic curve over a number field `K` - ``v`` -- a non-archimedean place of `K`, or ``None`` (default). If `v` is a non-archimedean place, return the local height - of self at `v`. If `v` is ``None``, return the total + of ``self`` at `v`. If `v` is ``None``, return the total non-archimedean contribution to the global height. - - ``prec`` -- integer, or ``None`` (default). The precision of the - computation. If ``None``, the height is returned symbolically. + - ``prec`` -- integer; or ``None`` (default). The precision of the + computation. If ``None``, the height is returned symbolically - ``weighted`` -- boolean. If ``False`` (default), the height is normalised to be invariant under extension of `K`. If ``True``, return this normalised height multiplied by the local degree - if `v` is a single place, or by the degree of `K` if `v` is - None. + if `v` is a single place, or by the degree of `K` if `v` is ``None``. + + - ``is_minimal`` -- boolean, or ``None`` (default). Ignored + when ``v`` is ``None`` (default) or ``True``. Otherwise, + when the place ``v`` is specified: if ``True``, the model is + assumed to be both locally integral and a local minimal + model; if ``None`` (default) or ``False``, a local minimal + model is computed and the computation is done on that model. OUTPUT: @@ -3382,7 +3394,7 @@ def non_archimedean_local_height(self, v=None, prec=None, sage: P.non_archimedean_local_height() -log(3) - Local heights of torsion points can be non-zero (unlike the + Local heights of torsion points can be nonzero (unlike the global height):: sage: # needs sage.rings.number_field @@ -3419,6 +3431,20 @@ def non_archimedean_local_height(self, v=None, prec=None, sage: P = E(2,5) sage: P.non_archimedean_local_height(2) -2/3*log(2) + + This shows that the bug reported at :issue:`36834` (incorrect + value when the model is not integral) has been fixed:: + + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(84131656042917) + sage: E = EllipticCurve(K, [0, 0, 0, -5482707841/48, -244634179112639/864]) + sage: P = E(349189/12, 1/2*a) + sage: h = P.non_archimedean_local_height() + sage: h + 1/2*log(144) - log(3) - 2*log(2) + sage: h.numerator().simplify_log() + 0 + """ if prec: log = lambda x: RealField(prec)(x).log() @@ -3441,21 +3467,17 @@ def non_archimedean_local_height(self, v=None, prec=None, for p, e in factorD if not p.divides(c)) + sum(self.non_archimedean_local_height(p, prec, weighted=True) - c.valuation(p) * log(p) - for p, e in factorD if e >= 12 and p.divides(c))) + for p, e in factorD if e >= 12 and c.valuation(p))) else: factorD = K.factor(D) if self[0] == 0: c = K.ideal(1) else: c = K.ideal(self[0]).denominator() - # The last sum is for bad primes that divide c where - # the model is not minimal. h = (log(c.norm()) - + sum(self.non_archimedean_local_height(v, prec, weighted=True, is_minimal=(e < 12)) - for v, e in factorD if not v.divides(c)) + sum(self.non_archimedean_local_height(v, prec, weighted=True) - c.valuation(v) * log(v.norm()) - for v, e in factorD if e >= 12 and v.divides(c))) + for v, e in factorD)) if not weighted: h /= K.degree() return h @@ -3513,12 +3535,12 @@ def elliptic_logarithm(self, embedding=None, precision=100, INPUT: - - ``embedding``: an embedding of the base field into `\RR` or `\CC` + - ``embedding`` -- an embedding of the base field into `\RR` or `\CC` - - ``precision``: a positive integer (default 100) setting the + - ``precision`` -- a positive integer (default: 100) setting the number of bits of precision for the computation - - ``algorithm``: either ``'pari'`` (default for real embeddings) + - ``algorithm`` -- either ``'pari'`` (default: for real embeddings) to use PARI's :pari:`ellpointtoz`, or ``'sage'`` for a native implementation. Ignored for complex embeddings. @@ -3717,12 +3739,14 @@ def elliptic_logarithm(self, embedding=None, precision=100, def padic_elliptic_logarithm(self, p, absprec=20): r""" - Computes the `p`-adic elliptic logarithm of this point. + Compute the `p`-adic elliptic logarithm of this point. INPUT: - - ``p`` -- integer: a prime ``absprec`` -- integer (default: 20): - the initial `p`-adic absolute precision of the computation + - ``p`` -- integer; a prime + + - ``absprec`` -- integer (default: 20); the initial `p`-adic absolute + precision of the computation OUTPUT: @@ -3858,7 +3882,7 @@ class EllipticCurvePoint_finite_field(EllipticCurvePoint_field): """ def _magma_init_(self, magma): """ - Return a string representation of self that ``MAGMA`` can + Return a string representation of ``self`` that ``MAGMA`` can use for input. EXAMPLES:: @@ -3930,7 +3954,12 @@ def log(self, base): In other words, return an integer `x` such that `xP = Q` where `P` is ``base`` and `Q` is this point. - A :class:`ValueError` is raised if there is no solution. + If ``base`` is a list or tuple of two points, then this function + solves a two-dimensional discrete logarithm: Given `(P_1,P_2)` in + ``base``, it returns a tuple of integers `(x,y)` such that + `[x]P_1 + [y]P_2 = Q`, where `Q` is this point. + + A :exc:`ValueError` is raised if there is no solution. ALGORITHM: @@ -3954,20 +3983,32 @@ def log(self, base): For anomalous curves with `\#E = p`, the :meth:`padic_elliptic_logarithm` function is called. + For two-dimensional logarithms, we first compute the Weil pairings + of `Q` with `P_1` and `P_2` and their logarithms relative to the + pairing of `P_1` and `P_2`; this allows reading off `x` and `y` + modulo the part of the order where `P_1` and `P_2` are independent. + Modulo the remaining part of the order the logarithm ends up being + effectively one-dimensional, so we can reduce the problem to the + basic one-dimensional case and finally recombine the results. + INPUT: - - ``base`` (point) -- another point on the same curve as ``self``. + - ``base`` -- another point or sequence of two points on the same + curve as ``self`` OUTPUT: (integer) -- The discrete logarithm of `Q` with respect to `P`, which is an integer `x` with `0\le x<\mathrm{ord}(P)` such that - `xP=Q`, if one exists. + `xP=Q`, if one exists. In the case of two points `P_1,P_2`, two + integers `x,y` with `0\le x<\mathrm{ord}(P_1)` and + `0\le y<\mathrm{ord}(P_2)` such that `[x]P_1 + [y]P_2 = Q`. AUTHORS: - John Cremona. Adapted to use generic functions 2008-04-05. - Lorenz Panny (2022): switch to PARI. + - Lorenz Panny (2024): the two-dimensional case. EXAMPLES:: @@ -3982,6 +4023,18 @@ def log(self, base): sage: Q.log(P) 400 + :: + + sage: # needs sage.rings.finite_rings + sage: F = GF((5, 60), 'a') + sage: E = EllipticCurve(F, [1, 1]) + sage: E.abelian_group() + Additive abelian group isomorphic to Z/194301464603136995341424045476456938000 + Z/4464 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^60 + sage: P, Q = E.gens() # cached generators from .abelian_group() + sage: T = 1234567890987654321*P + 1337*Q + sage: T.log([P, Q]) + (1234567890987654321, 1337) + TESTS: Some random testing:: @@ -3996,15 +4049,90 @@ def log(self, base): sage: x = Q.log(P) sage: x*P == Q True + + :: + + sage: # needs sage.rings.finite_rings + sage: sz = randint(16,24) + sage: e = randint(1,6) + sage: p = random_prime(ceil(2**(sz/e))) + sage: E = EllipticCurve(j=GF((p,e),'a').random_element()) + sage: E = choice(E.twists()) + sage: P = E.random_point() + sage: Q = E.random_point() + sage: T = randrange(2^99) * P + randrange(2^99) * Q + sage: x, y = T.log([P, Q]) + sage: 0 <= x < P.order() + True + sage: 0 <= y < Q.order() + True + sage: T == x*P + y*Q + True """ + # handle the two-dimensional case first + if isinstance(base, (list, tuple)): + if not base: + return self.log(self.curve().zero()) + elif len(base) == 1: + return self.log(base[0]) + elif len(base) > 2: + raise ValueError('sequence must have length <= 2') + + P1, P2 = base + if P1 not in self.parent() or P2 not in self.parent(): + raise ValueError('points do not lie on the same curve') + + n1, n2 = P1.order(), P2.order() + n = n1.lcm(n2) + if not hasattr(self, '_order'): + if n * self: + raise ValueError('ECDLog problem has no solution (order does not divide order of base)') + self.set_order(multiple=n, check=False) + if not self.order().divides(n): + raise ValueError('ECDLog problem has no solution (order does not divide order of base)') + + # find the solution modulo the part where P1,P2 are independent + z = P1.weil_pairing(P2, n) + o = generic.order_from_multiple(z, n1.gcd(n2), operation='*') + if o.is_one(): + # slight optimization, but also workaround for PARI bug #2562 + x0, y0 = ZZ.zero(), ZZ.zero() + else: + v = self.weil_pairing(P2, n) + w = P1.weil_pairing(self, n) + x0, y0 = v.log(z, o), w.log(z, o) + + T = self - x0*P1 - y0*P2 + if not T: + return x0, y0 + + T1 = n//n1 * T + T2 = n//n2 * T + T1.set_order(multiple=n1, check=False) + T2.set_order(multiple=n2, check=False) + x1 = T1.log(o*P1) + y1 = T2.log(o*P2) + +# assert n//n1 * self == (x1*o + n//n1*x0) * P1 + n//n1*y0 * P2 +# assert n//n2 * self == n//n2*x0 * P1 + (y1*o + n//n2*y0) * P2 + + _,u,v = (n//n1).xgcd(n//n2) + assert _.is_one() + x = (u * (x1*o + n//n1*x0) + v * (n//n2*x0)) % n1 + y = (u * (n//n1*y0) + v * (y1*o + n//n2*y0)) % n2 + +# assert x*P1 + y*P2 == self + return x, y + if base not in self.parent(): raise ValueError('not a point on the same curve') n = base.order() - if n*self: + if (hasattr(self, '_order') and not self._order.divides(n)) or n*self: raise ValueError('ECDLog problem has no solution (order does not divide order of base)') E = self.curve() F = E.base_ring() p = F.cardinality() + if F.is_prime_field() and n == p: # Anomalous case return base.padic_elliptic_logarithm(self, p) @@ -4053,8 +4181,8 @@ def padic_elliptic_logarithm(self,Q, p): INPUT: - - ``Q`` (point) -- another point on the same curve as ``self``. - - ``p`` (integer) -- a prime equal to the order of the curve. + - ``Q`` -- point; another point on the same curve as ``self`` + - ``p`` -- integer; a prime equal to the order of the curve OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py old mode 100644 new mode 100755 index 1dba8a94ba1..d00187d49a2 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -47,66 +47,60 @@ # # https://www.gnu.org/licenses/ ############################################################################## -from itertools import product - -from . import constructor -from . import BSD -from .ell_generic import EllipticCurve_generic -from . import ell_modular_symbols -from .ell_number_field import EllipticCurve_number_field -from . import ell_point -from . import ell_tate_curve -from . import ell_torsion -from . import heegner -from . import mod5family -from .modular_parametrization import ModularParameterization -from . import padics -from sage.modular.modsym.modsym import ModularSymbols -from sage.modular.pollack_stevens.space import ps_modsym_from_elliptic_curve +from copy import copy +from itertools import product +from math import sqrt +import sage.arith.all as arith +import sage.databases.cremona import sage.modular.modform.constructor import sage.modular.modform.element -import sage.databases.cremona -import sage.arith.all as arith -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.matrix.matrix_space import MatrixSpace +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import +from sage.misc.misc_c import prod, prod as mul +from sage.misc.verbose import verbose as verbose_verbose +from sage.modular.modsym.modsym import ModularSymbols +from sage.modular.pollack_stevens.space import ps_modsym_from_elliptic_curve +from sage.rings.complex_mpfr import ComplexField from sage.rings.fast_arith import prime_range -from sage.rings.real_mpfr import RR -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.structure.element import RingElement -from sage.rings.power_series_ring import PowerSeriesRing +from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.rings.infinity import Infinity as oo +from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ, IntegerRing +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.rational_field import QQ -from sage.rings.integer import Integer -from sage.rings.real_mpfi import RealIntervalField -from sage.rings.real_mpfr import RealField -from sage.rings.complex_mpfr import ComplexField from sage.rings.rational_field import RationalField - +from sage.rings.real_mpfi import RealIntervalField +from sage.rings.real_mpfr import RealField, RR from sage.structure.coerce import py_scalar_to_element -from sage.structure.element import Element -from sage.misc.misc_c import prod as mul -from sage.misc.misc_c import prod -from sage.misc.lazy_import import lazy_import -from sage.misc.verbose import verbose as verbose_verbose - -from sage.functions.log import log +from sage.structure.element import Element, RingElement -from sage.matrix.matrix_space import MatrixSpace +lazy_import("sage.functions.log", "log") lazy_import('sage.libs.pari.all', 'pari') lazy_import("sage.functions.gamma", "gamma_inc") -from math import sqrt -from sage.interfaces.gp import gp -from sage.misc.cachefunc import cached_method -from copy import copy +lazy_import('sage.interfaces.gp', 'gp') + +from . import constructor +from . import BSD +from .ell_generic import EllipticCurve_generic +from . import ell_modular_symbols +from .ell_number_field import EllipticCurve_number_field +from . import ell_point +from . import ell_tate_curve +from . import ell_torsion +from . import heegner +from . import mod5family +from .modular_parametrization import ModularParameterization +from . import padics Q = RationalField() C = ComplexField() R = RealField() Z = IntegerRing() -IR = RealIntervalField(20) _MAX_HEIGHT = 21 @@ -125,7 +119,7 @@ class EllipticCurve_rational_field(EllipticCurve_number_field): INPUT: - - ``ainvs`` -- a list or tuple `[a_1, a_2, a_3, a_4, a_6]` of + - ``ainvs`` -- list or tuple `[a_1, a_2, a_3, a_4, a_6]` of Weierstrass coefficients .. NOTE:: @@ -163,6 +157,13 @@ def __init__(self, ainvs, **kwds): TESTS: + Passing unexpected keyword arguments will raise an error:: + + sage: EllipticCurve.create_object(0, (QQ, (1, 2, 0, 1, 2)), base=QQ) + Traceback (most recent call last): + ... + TypeError: unexpected keyword arguments: {'base': Rational Field} + When constructing a curve from the large database using a label, we must be careful that the copied generators have the right curve (see :issue:`10999`: the following used not to work when @@ -187,21 +188,23 @@ def __init__(self, ainvs, **kwds): EllipticCurve_number_field.__init__(self, Q, ainvs) if 'conductor' in kwds: - self._set_conductor(kwds['conductor']) + self._set_conductor(kwds.pop('conductor')) if 'cremona_label' in kwds: - self._set_cremona_label(kwds['cremona_label']) + self._set_cremona_label(kwds.pop('cremona_label')) if 'gens' in kwds: - self._set_gens(kwds['gens']) + self._set_gens(kwds.pop('gens')) if 'lmfdb_label' in kwds: - self._lmfdb_label = kwds['lmfdb_label'] + self._lmfdb_label = kwds.pop('lmfdb_label') if 'modular_degree' in kwds: - self._set_modular_degree(kwds['modular_degree']) + self._set_modular_degree(kwds.pop('modular_degree')) if 'rank' in kwds: - self._set_rank(kwds['rank']) + self._set_rank(kwds.pop('rank')) if 'regulator' in kwds: - self.__regulator = (kwds['regulator'], True) + self.__regulator = (kwds.pop('regulator'), True) if 'torsion_order' in kwds: - self._set_torsion_order(kwds['torsion_order']) + self._set_torsion_order(kwds.pop('torsion_order')) + if kwds: + raise TypeError(f"unexpected keyword arguments: {kwds}") def _set_rank(self, r): r""" @@ -364,7 +367,7 @@ def is_p_integral(self, p): INPUT: - - ``p`` -- a prime integer + - ``p`` -- prime integer EXAMPLES:: @@ -414,7 +417,7 @@ def mwrank(self, options=''): INPUT: - - ``options`` (string) -- run-time options passed when starting mwrank. + - ``options`` -- string; run-time options passed when starting mwrank. The format is as follows (see below for examples of usage): - ``-v n`` (verbosity level) sets verbosity to n (default=1) @@ -427,9 +430,7 @@ def mwrank(self, options=''): - ``-d`` (skip_2nd_descent flag) if set, skips the second descent for curves with 2-torsion (default: not set) - ``-S n`` (sat_bd) upper bound on saturation primes (default=100, -1 for automatic) - OUTPUT: - - - (string) -- output of mwrank on this curve + OUTPUT: string; output of mwrank on this curve .. NOTE:: @@ -479,43 +480,42 @@ def mwrank(self, options=''): mwrank = Mwrank(options=options) return mwrank(list(self.a_invariants())) - def conductor(self, algorithm="pari"): + def conductor(self, algorithm='pari'): r""" Return the conductor of the elliptic curve. INPUT: - - ``algorithm`` -- str, (default: "pari") + - ``algorithm`` -- string (default: ``'pari'``) - - ``"pari"`` -- use the PARI C-library :pari:`ellglobalred` + - ``'pari'`` -- use the PARI C-library :pari:`ellglobalred` implementation of Tate's algorithm - - ``"mwrank"`` -- use Cremona's mwrank implementation + - ``'mwrank'`` -- use Cremona's mwrank implementation of Tate's algorithm; can be faster if the curve has integer coefficients (TODO: limited to small conductor until mwrank gets integer factorization) - - ``"gp"`` -- use the GP interpreter + - ``'gp'`` -- use the GP interpreter - - ``"generic"`` -- use the general number field - implementation + - ``'generic'`` -- use the general number field implementation - - ``"all"`` -- use all four implementations, verify + - ``'all'`` -- use all four implementations, verify that the results are the same (or raise an error), and output the common value EXAMPLES:: sage: E = EllipticCurve([1, -1, 1, -29372, -1932937]) - sage: E.conductor(algorithm="pari") + sage: E.conductor(algorithm='pari') 3006 - sage: E.conductor(algorithm="mwrank") + sage: E.conductor(algorithm='mwrank') 3006 - sage: E.conductor(algorithm="gp") + sage: E.conductor(algorithm='gp') 3006 - sage: E.conductor(algorithm="generic") + sage: E.conductor(algorithm='generic') 3006 - sage: E.conductor(algorithm="all") + sage: E.conductor(algorithm='all') 3006 .. NOTE:: @@ -527,7 +527,7 @@ def conductor(self, algorithm="pari"): TESTS:: - sage: E.conductor(algorithm="bogus") + sage: E.conductor(algorithm='bogus') Traceback (most recent call last): ... ValueError: algorithm 'bogus' is not known @@ -662,7 +662,7 @@ def database_attributes(self): the elliptic curve database. If there is no elliptic curve isomorphic to ``self`` in the - database, a :class:`LookupError` is raised. + database, a :exc:`LookupError` is raised. EXAMPLES:: @@ -694,7 +694,7 @@ def database_attributes(self): def database_curve(self): r""" Return the curve in the elliptic curve database isomorphic to this - curve, if possible. Otherwise raise a ``LookupError`` exception. + curve, if possible. Otherwise raise a :exc:`LookupError` exception. Since :issue:`11474`, this returns exactly the same curve as :meth:`minimal_model`; the only difference is the additional @@ -730,13 +730,12 @@ def Np(self, p): INPUT: - - ``p`` (int) -- a prime, not necessarily of good reduction + - ``p`` -- integer; a prime, not necessarily of good reduction OUTPUT: - (int) The number ofpoints on the reduction of `E` modulo `p` - (including the singular point when `p` is a prime of bad - reduction). + integer; the number of points on the reduction of `E` modulo `p` + (including the singular point when `p` is a prime of bad reduction). EXAMPLES:: @@ -765,7 +764,7 @@ def Np(self, p): #################################################################### def mwrank_curve(self, verbose=False): r""" - Construct an mwrank_EllipticCurve from this elliptic curve + Construct an mwrank_EllipticCurve from this elliptic curve. The resulting mwrank_EllipticCurve has available methods from John Cremona's eclib library. @@ -801,11 +800,10 @@ def two_descent(self, verbose=True, INPUT: - - ``verbose`` -- (default: ``True``) print what mwrank is - doing; if ``False``, **no output** is printed + - ``verbose`` -- boolean (default: ``True``); print what mwrank is + doing. If ``False``, **no output** is printed. - - ``selmer_only`` -- (default: ``False``) selmer_only - switch + - ``selmer_only`` -- boolean (default: ``False``); selmer_only switch - ``first_limit`` -- (default: 20) firstlim is bound on x+z second_limit- (default: 8) secondlim is bound on log max @@ -856,7 +854,7 @@ def aplist(self, n, python_ints=False): - ``n`` -- integer - - ``python_ints`` -- bool (default: ``False``); if ``True`` + - ``python_ints`` -- boolean (default: ``False``); if ``True`` return a list of Python ints instead of Sage integers OUTPUT: list of integers @@ -894,7 +892,7 @@ def anlist(self, n, python_ints=False): - ``n`` -- integer - - ``python_ints`` -- bool (default: ``False``); if ``True`` + - ``python_ints`` -- boolean (default: ``False``); if ``True`` return a list of Python ints instead of Sage integers OUTPUT: list of integers @@ -964,16 +962,14 @@ def anlist(self, n, python_ints=False): def q_expansion(self, prec): r""" - Return the `q`-expansion to precision prec of the newform + Return the `q`-expansion to precision ``prec`` of the newform attached to this elliptic curve. INPUT: - - ``prec`` -- an integer - - OUTPUT: + - ``prec`` -- integer - a power series (in the variable 'q') + OUTPUT: a power series (in the variable 'q') .. NOTE:: @@ -1061,11 +1057,9 @@ def modular_symbol_space(self, sign=1, base_ring=Q, bound=None): def abelian_variety(self): r""" - Return self as a modular abelian variety. - - OUTPUT: + Return ``self`` as a modular abelian variety. - - a modular abelian variety + OUTPUT: a modular abelian variety EXAMPLES:: @@ -1110,31 +1104,29 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) INPUT: - - ``sign`` -- +1 (default) or -1. - - - ``normalize`` -- (default: ``None``); either 'L_ratio', 'period', - or 'none'; ignored unless ``implementation`` is 'sage'. - For 'L_ratio', the modular symbol tries to normalize - correctly as explained below by comparing it to ``L_ratio`` - for the curve and some small twists. The normalization - 'period' uses the ``integral_period_map`` for modular - symbols which is known to be equal to the desired - normalization, up to the sign and a possible power of 2. - With normalization 'none', the modular symbol is almost - certainly not correctly normalized, i.e. all values will be + - ``sign`` -- +1 (default) or -1 + + - ``normalize`` -- (default: ``None``) either ``'L_ratio'``, + ``'period'``, or ``'none'``; ignored unless ``implementation`` is + ``'sage'``. For ``'L_ratio'``, the modular symbol tries to normalize + correctly as explained below by comparing it to ``L_ratio`` for the + curve and some small twists. The normalization ``'period'`` uses the + ``integral_period_map`` for modular symbols which is known to be + equal to the desired normalization, up to the sign and a possible + power of 2. With normalization ``'none'``, the modular symbol is + almost certainly not correctly normalized, i.e. all values will be a fixed scalar multiple of what they should be. - - ``implementation`` -- either 'eclib' (default), 'sage' or - 'num'. Here, 'eclib' uses Cremona's ``C++`` implementation - in the ``eclib`` library, 'sage' uses an implementation - within Sage which is often quite a bit slower, and 'num' - uses Wuthrich's implementation of numerical modular - symbols. + - ``implementation`` -- either ``'eclib'`` (default), ``'sage'`` or + ``'num'``. Here, ``'eclib'`` uses Cremona's ``C++`` implementation + in the ``eclib`` library, ``'sage'`` uses an implementation + within Sage which is often quite a bit slower, and ``'num'`` + uses Wuthrich's implementation of numerical modular symbols. - - ``nap`` -- (int, default 0); ignored unless implementation is - 'eclib'. The number of ap of E to use in determining the + - ``nap`` -- integer (default: 0); ignored unless implementation is + ``'eclib'``. The number of ap of E to use in determining the normalisation of the modular symbols. If 0 (the default), - then the value of 100*E.conductor().isqrt() is used. Using + then the value of ``100*E.conductor().isqrt()`` is used. Using too small a value can lead to incorrect normalisation. DEFINITION: @@ -1161,7 +1153,7 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) ALGORITHM: - For the implementations 'sage' and 'eclib', the used + For the implementations ``'sage'`` and ``'eclib'``, the used algorithm starts by finding the space of modular symbols within the full space of all modular symbols of that level. This initial step will take a very long time if the @@ -1169,7 +1161,7 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) conductors). Once the space is determined, each evaluation is very fast (logarithmic in the denominator of `r`). - The implementation 'num' uses a different algorithm. It + The implementation ``'num'`` uses a different algorithm. It uses numerical integration along paths in the upper half plane. The bounds are rigorously proved so that the outcome is known to be correct. The initial step costs no time, @@ -1195,7 +1187,7 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) :: sage: E = EllipticCurve('121b1') - sage: M = E.modular_symbol(implementation="sage") + sage: M = E.modular_symbol(implementation='sage') Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1 and a power of 2 sage: M(1/7) @@ -1207,7 +1199,7 @@ def modular_symbol(self, sign=+1, normalize=None, implementation='eclib', nap=0) sage: E = EllipticCurve([999,997]) sage: E.conductor() 16059400956 - sage: m = E.modular_symbol(implementation="num") + sage: m = E.modular_symbol(implementation='num') sage: m(0) # long time 16 @@ -1317,11 +1309,9 @@ def modular_symbol_numerical(self, sign=1, prec=20): - ``sign`` -- either +1 (default) or -1 - - ``prec`` -- an integer (default 20) - - OUTPUT: + - ``prec`` -- integer (default: 20) - - a real number + OUTPUT: a real number ALGORITHM: @@ -1435,27 +1425,27 @@ def q_eigenform(self, prec): """ return self.q_expansion(prec) - def analytic_rank(self, algorithm="pari", leading_coefficient=False): + def analytic_rank(self, algorithm='pari', leading_coefficient=False): r""" Return an integer that is *probably* the analytic rank of this elliptic curve. INPUT: - - ``algorithm`` -- (default: 'pari'), String + - ``algorithm`` -- string (default: ``'pari'``): - - ``'pari'`` -- use the PARI library function. + - ``'pari'`` -- use the PARI library function - ``'sympow'`` -- use Watkins's program sympow - - ``'rubinstein'`` -- use Rubinstein's L-function C++ program lcalc. + - ``'rubinstein'`` -- use Rubinstein's `L`-function C++ program lcalc - ``'magma'`` -- use MAGMA - - ``'zero_sum'`` -- Use the rank bounding zero sum method implemented + - ``'zero_sum'`` -- use the rank bounding zero sum method implemented in :meth:`analytic_rank_upper_bound` - ``'all'`` -- compute with PARI, sympow and lcalc, check that - the answers agree, and return the common answer. + the answers agree, and return the common answer - - ``leading_coefficient`` -- (default: ``False``) Boolean; if set to - True, return a tuple `(rank, lead)` where `lead` is the value of - the first non-zero derivative of the L-function of the elliptic + - ``leading_coefficient`` -- boolean (default: ``False``); if set to + ``True``, return a tuple ``(rank, lead)`` where ``lead`` is the value + of the first nonzero derivative of the `L`-function of the elliptic curve. Only implemented for ``algorithm='pari'``. .. NOTE:: @@ -1498,7 +1488,7 @@ def analytic_rank(self, algorithm="pari", leading_coefficient=False): With the optional parameter leading_coefficient set to ``True``, a tuple of both the analytic rank and the leading term of the - L-series at `s = 1` is returned. This only works for + `L`-series at `s = 1` is returned. This only works for ``algorithm=='pari'``:: sage: EllipticCurve([0,-1,1,-10,-20]).analytic_rank(leading_coefficient=True) @@ -1515,7 +1505,7 @@ def analytic_rank(self, algorithm="pari", leading_coefficient=False): TESTS: When the input is horrendous, some of the algorithms just bomb - out with a ``RuntimeError``:: + out with a :exc:`RuntimeError`:: sage: EllipticCurve([1234567,89101112]).analytic_rank(algorithm='rubinstein') Traceback (most recent call last): @@ -1572,11 +1562,11 @@ def analytic_rank_upper_bound(self, max_Delta=None, adaptive=True, N=None, - root_number="compute", + root_number='compute', bad_primes=None, ncpus=None): r""" - Return an upper bound for the analytic rank of self, conditional on + Return an upper bound for the analytic rank of ``self``, conditional on the Generalized Riemann Hypothesis, via computing the zero sum `\sum_{\gamma} f(\Delta\gamma),` where `\gamma` ranges over the imaginary parts of the zeros of `L(E,s)` @@ -1589,18 +1579,18 @@ def analytic_rank_upper_bound(self, INPUT: - - ``max_Delta`` -- (default: ``None``) If not ``None``, a positive real value - specifying the maximum Delta value used in the zero sum; larger + - ``max_Delta`` -- (default: ``None``) if not ``None``, a positive real + value specifying the maximum Delta value used in the zero sum; larger values of Delta yield better bounds - but runtime is exponential in Delta. If left as ``None``, Delta is set to `\min\{\frac{1}{\pi}(\log(N+1000)/2-\log(2\pi)-\eta), 2.5\}`, - where `N` is the conductor of the curve attached to self, and `\eta` + where `N` is the conductor of the curve attached to ``self``, and `\eta` is the Euler-Mascheroni constant `= 0.5772...`; the crossover point is at conductor around `8.3 \cdot 10^8`. For the former value, empirical results show that for about 99.7% of all curves the returned value is the actual analytic rank. - - ``adaptive`` -- (default: ``True``) boolean + - ``adaptive`` -- boolean (default: ``True``): - ``True`` -- the computation is first run with small and then successively larger `\Delta` values up to max_Delta. If at any @@ -1608,30 +1598,30 @@ def analytic_rank_upper_bound(self, or True), the computation halts and that value is returned; otherwise the minimum of the computed bounds is returned. - ``False`` -- the computation is run a single time with `\Delta` - equal to ``max_Delta``, and the resulting bound returned. + equal to ``max_Delta``, and the resulting bound returned - - ``N`` -- (default: ``None``) If not ``None``, a positive integer equal + - ``N`` -- (default: ``None``) if not ``None``, a positive integer equal to the conductor of ``self``. This is passable so that rank estimation can be done for curves whose (large) conductor has been precomputed. - - ``root_number`` -- (default: "compute") string or integer + - ``root_number`` -- (default: ``'compute'``) string or integer: - - ``"compute"`` -- the root number of self is computed and used to + - ``'compute'`` -- the root number of ``self`` is computed and used to (possibly) lower the analytic rank estimate by 1. - - ``"ignore"`` -- the above step is omitted + - ``'ignore'`` -- the above step is omitted - ``1`` -- this value is assumed to be the root number of - self. This is passable so that rank estimation can be done for + ``self``. This is passable so that rank estimation can be done for curves whose root number has been precomputed. - ``-1`` -- this value is assumed to be the root number of - self. This is passable so that rank estimation can be done for + ``self``. This is passable so that rank estimation can be done for curves whose root number has been precomputed. - - ``bad_primes`` -- (default: ``None``) If not ``None``, a list of the primes - of bad reduction for the curve attached to self. This is passable + - ``bad_primes`` -- (default: ``None``) if not ``None``, a list of the primes + of bad reduction for the curve attached to ``self``. This is passable so that rank estimation can be done for curves of large conductor whose bad primes have been precomputed. - - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer + - ``ncpus`` -- (default: ``None``) if not ``None``, a positive integer defining the maximum number of CPUs to be used for the computation. If left as None, the maximum available number of CPUs will be used. Note: Due to parallelization overhead, multiple processors will @@ -1652,8 +1642,8 @@ def analytic_rank_upper_bound(self, OUTPUT: - A non-negative integer greater than or equal to the analytic rank of - self. + A nonnegative integer greater than or equal to the analytic rank of + ``self``. .. NOTE:: @@ -1693,7 +1683,7 @@ def analytic_rank_upper_bound(self, ....: E = elliptic_curves.rank(r)[0] ....: print((r, E.analytic_rank_upper_bound(max_Delta=1, ....: adaptive=False, - ....: root_number="ignore"))) + ....: root_number='ignore'))) (0, 0) (1, 1) (2, 2) @@ -1712,9 +1702,9 @@ def analytic_rank_upper_bound(self, sage: E = EllipticCurve("974b1") sage: r = E.rank(); r 0 - sage: E.analytic_rank_upper_bound(max_Delta=1, root_number="ignore") + sage: E.analytic_rank_upper_bound(max_Delta=1, root_number='ignore') 1 - sage: E.analytic_rank_upper_bound(max_Delta=1.3, root_number="ignore") + sage: E.analytic_rank_upper_bound(max_Delta=1.3, root_number='ignore') 0 Knowing the root number of `E` allows us to use smaller Delta values @@ -1722,7 +1712,7 @@ def analytic_rank_upper_bound(self, :: - sage: E.analytic_rank_upper_bound(max_Delta=0.6, root_number="compute") + sage: E.analytic_rank_upper_bound(max_Delta=0.6, root_number='compute') 0 There are a small number of curves which have pathologically low-lying @@ -1807,14 +1797,14 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, and large prime numbers. Use probabilistic tests for large primes. If 0, don't any probabilistic tests. - - ``known_points`` -- (default: None) list of known points on + - ``known_points`` -- (default: ``None``) list of known points on the curve OUTPUT: a triple ``(lower, upper, list)`` consisting of - - ``lower`` (integer) -- lower bound on the rank + - ``lower`` -- integer; lower bound on the rank - - ``upper`` (integer) -- upper bound on the rank + - ``upper`` -- integer; upper bound on the rank - ``list`` -- list of points of infinite order in `E(\QQ)` @@ -1847,6 +1837,10 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, ... DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari. See https://github.com/sagemath/sage/issues/35621 for details. + doctest:warning + ... + DeprecationWarning: please use the 2-descent algorithm over QQ inside pari + See https://github.com/sagemath/sage/issues/38461 for details. (0, 0, []) sage: E = EllipticCurve('37a1') sage: E.simon_two_descent() @@ -1947,7 +1941,7 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, return rank_low_bd, two_selmer_rank, pts - two_descent_simon = simon_two_descent + two_descent_simon = simon_two_descent # deprecated in #35621 def three_selmer_rank(self, algorithm='UseSUnits'): r""" @@ -2012,7 +2006,7 @@ def rank(self, use_database=True, verbose=False, - ``use_database`` -- boolean (default: ``True``); if ``True``, try to look up the rank in the Cremona database - - ``verbose`` -- (default: ``False``) if specified changes + - ``verbose`` -- boolean (default: ``False``); if specified changes the verbosity of mwrank computations - ``algorithm`` -- (default: ``'mwrank_lib'``) one of: @@ -2023,10 +2017,10 @@ def rank(self, use_database=True, verbose=False, - ``'pari'`` -- call ellrank in pari - - ``only_use_mwrank`` -- (default: ``True``) if ``False`` try + - ``only_use_mwrank`` -- boolean (default: ``True``); if ``False`` try using analytic rank methods first - - ``proof`` -- bool (default: ``None``, see + - ``proof`` -- boolean (default: ``None``, see ``proof.elliptic_curve`` or ``sage.structure.proof``); note that results obtained from databases are considered ``proof=True`` @@ -2038,7 +2032,7 @@ def rank(self, use_database=True, verbose=False, OUTPUT: the rank of the elliptic curve as :class:`Integer` - IMPLEMENTATION: Uses L-functions, mwrank, pari, and databases. + IMPLEMENTATION: uses `L`-functions, mwrank, pari, and databases EXAMPLES:: @@ -2054,7 +2048,7 @@ def rank(self, use_database=True, verbose=False, 4 sage: EllipticCurve([0, 0, 1, -79, 342]).rank(proof=False) 5 - sage: EllipticCurve([0, 0, 1, -79, 342]).rank(algorithm="pari") + sage: EllipticCurve([0, 0, 1, -79, 342]).rank(algorithm='pari') 5 Examples with denominators in defining equations:: @@ -2076,12 +2070,12 @@ def rank(self, use_database=True, verbose=False, Traceback (most recent call last): ... RuntimeError: rank not provably correct (lower bound: 0) - sage: EllipticCurve([1,0,0,0,37455]).rank(algorithm="pari") + sage: EllipticCurve([1,0,0,0,37455]).rank(algorithm='pari') 0 TESTS:: - sage: EllipticCurve([1,10000]).rank(algorithm="garbage") + sage: EllipticCurve([1,10000]).rank(algorithm='garbage') Traceback (most recent call last): ... ValueError: unknown algorithm 'garbage' @@ -2089,7 +2083,7 @@ def rank(self, use_database=True, verbose=False, An example to check if the points are saturated:: sage: E = EllipticCurve([0,0, 1, -7, 6]) - sage: E.gens(use_database=False, algorithm="pari") # random + sage: E.gens(use_database=False, algorithm='pari') # random [(2 : 0 : 1), (-1 : 3 : 1), (11 : 35 : 1)] sage: E.saturation(_)[1] 1 @@ -2113,7 +2107,7 @@ def rank(self, use_database=True, verbose=False, determined using pari only:: sage: E =EllipticCurve([-113^2,0]) - sage: E.rank(use_database=False, verbose=False, algorithm="pari") + sage: E.rank(use_database=False, verbose=False, algorithm='pari') Traceback (most recent call last): ... RuntimeError: rank not provably correct (lower bound: 0, upper bound:2). Hint: increase pari_effort. @@ -2242,15 +2236,14 @@ def rank(self, use_database=True, verbose=False, def gens(self, proof=None, **kwds): r""" - Return generators for the Mordell-Weil group `E(Q)` *modulo* - torsion. + Return generators for the Mordell-Weil group `E(Q)` *modulo* torsion. INPUT: - - ``proof`` -- bool or None (default None), see + - ``proof`` -- boolean or ``None`` (default: ``None``), see ``proof.elliptic_curve`` or ``sage.structure.proof`` - - ``verbose`` -- (default: None), if specified changes the + - ``verbose`` -- (default: ``None``) if specified changes the verbosity of mwrank computations - ``rank1_search`` -- (default: 10), if the curve has analytic @@ -2258,18 +2251,18 @@ def gens(self, proof=None, **kwds): this logarithmic height. If this fails, the usual mwrank procedure is called. - - algorithm -- one of the following: + - ``algorithm`` -- one of the following: - - ``'mwrank_shell'`` (default) -- call mwrank shell command + - ``'mwrank_shell'`` -- default; call mwrank shell command - ``'mwrank_lib'`` -- call mwrank C library - ``'pari'`` -- use ellrank in pari - - ``only_use_mwrank`` -- bool (default: ``True``) if False, first + - ``only_use_mwrank`` -- boolean (default: ``True``); if ``False``, first attempts to use more naive, natively implemented methods - - ``use_database`` -- bool (default: ``True``) if True, attempts to + - ``use_database`` -- boolean (default: ``True``); if ``True``, attempts to find curve and gens in the (optional) database - ``descent_second_limit`` -- (default: 12) used in 2-descent @@ -2303,10 +2296,10 @@ def gens(self, proof=None, **kwds): sage: E = EllipticCurve('389a') sage: E.gens() # random output [(-1 : 1 : 1), (0 : 0 : 1)] - sage: E.gens(algorithm="pari") # random output + sage: E.gens(algorithm='pari') # random output [(5/4 : 5/8 : 1), (0 : 0 : 1)] sage: E = EllipticCurve([0,2429469980725060,0,275130703388172136833647756388,0]) - sage: len(E.gens(algorithm="pari")) # not tested (takes too long) + sage: len(E.gens(algorithm='pari')) # not tested (takes too long) 14 A non-integral example:: @@ -2323,7 +2316,7 @@ def gens(self, proof=None, **kwds): over Rational Field sage: E1.gens() # random (if database not used) [(-400 : 8000 : 1), (0 : -8000 : 1)] - sage: E1.gens(algorithm="pari") #random + sage: E1.gens(algorithm='pari') #random [(-400 : 8000 : 1), (0 : -8000 : 1)] TESTS:: @@ -2333,15 +2326,14 @@ def gens(self, proof=None, **kwds): 2 sage: E.saturation(E.gens())[1] 1 - sage: len(E.gens(algorithm="pari")) + sage: len(E.gens(algorithm='pari')) 2 - sage: E.saturation(E.gens(algorithm="pari"))[1] + sage: E.saturation(E.gens(algorithm='pari'))[1] 1 sage: E = EllipticCurve([-3/8,-2/3]) sage: P = E.lift_x(10/9) sage: set(E.gens()) <= set([P,-P]) True - """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2394,29 +2386,16 @@ def _compute_gens(self, proof, True sage: E = EllipticCurve([-127^2,0]) - sage: E.gens(use_database=False, algorithm="pari",pari_effort=4) # random + sage: E.gens(use_database=False, algorithm='pari',pari_effort=4) # random [(611429153205013185025/9492121848205441 : 15118836457596902442737698070880/924793900700594415341761 : 1)] TESTS:: sage: P = E.lift_x(611429153205013185025/9492121848205441) - sage: set(E.gens(use_database=False, algorithm="pari",pari_effort=4)) <= set([P+T for T - ....: in E.torsion_points()] + [-P+T for T in E.torsion_points()]) - True - - sage: E = EllipticCurve([-157^2,0]) - sage: E.gens(use_database=False, algorithm="pari") - Traceback (most recent call last): - ... - RuntimeError: generators could not be determined. So far we found []. Hint: increase pari_effort. - sage: ge = E.gens(use_database=False, algorithm="pari",pari_effort=10) - sage: ge #random - [(-166136231668185267540804/2825630694251145858025 : 167661624456834335404812111469782006/150201095200135518108761470235125 : 1)] - sage: P = E.lift_x(-166136231668185267540804/2825630694251145858025) - sage: set(E.gens(use_database=False, algorithm="pari",pari_effort=4)) <= set([P+T for T - ....: in E.torsion_points()] + [-P+T for T in E.torsion_points()]) + sage: ge = set(E.gens(use_database=False, algorithm='pari',pari_effort=4)) + sage: ge <= set([P+T for T in E.torsion_points()] + ....: + [-P+T for T in E.torsion_points()]) True - """ # If the optional extended database is installed and an # isomorphic curve is in the database then its gens will be @@ -2611,11 +2590,11 @@ def regulator(self, proof=None, precision=53, **kwds): INPUT: - - ``proof`` -- bool or ``None`` (default: ``None``, see + - ``proof`` -- boolean or ``None`` (default: ``None``, see proof.[tab] or sage.structure.proof). Note that results from - databases are considered proof = True + databases are considered ``proof = True``. - - ``precision`` -- (int, default 53): the precision in bits of + - ``precision`` -- integer (default: 53); the precision in bits of the result - ``**kwds`` -- passed to :meth:`gens()` method @@ -2672,19 +2651,19 @@ def saturation(self, points, verbose=False, max_prime=-1, min_prime=2): INPUT: - - ``points (list)`` -- list of points on `E` + - ``points`` -- list of points on `E` - - ``verbose (bool)`` -- (default: ``False``) if ``True``, give + - ``verbose`` -- boolean (default: ``False``); if ``True``, give verbose output - - ``max_prime`` -- int (default: `-1`); if `-1` (the default), an + - ``max_prime`` -- integer (default: `-1`); if `-1`, an upper bound is computed for the primes at which the subgroup may not be saturated, and saturation is performed for all primes up to this bound; otherwise, the bound used is the minimum of ``max_prime`` and the computed bound - - ``min_prime (int)`` -- (default: `2`) only do `p`-saturation - at primes `p` greater than or equal to this + - ``min_prime`` -- integer (default: `2`); only do `p`-saturation + at primes `p` greater than or equal to this .. NOTE:: @@ -2696,14 +2675,14 @@ def saturation(self, points, verbose=False, max_prime=-1, min_prime=2): OUTPUT: - - ``saturation (list)`` -- points that form a basis for + - ``saturation`` -- list; points that form a basis for the saturation - - ``index (int)`` -- the index of the group generated + - ``index`` -- integer; the index of the group generated by points in their saturation - - ``regulator (real with default precision)`` -- - regulator of saturated points. + - ``regulator`` -- real with default precision; regulator of saturated + points ALGORITHM: @@ -2715,7 +2694,7 @@ def saturation(self, points, verbose=False, max_prime=-1, min_prime=2): .. NOTE:: - In versons of ``eclib`` up to ``v20190909``, division of + In versions of ``eclib`` up to ``v20190909``, division of points in ``eclib`` was done using floating point methods, without automatic handling of precision, so that `p`-saturation sometimes failed unless @@ -2779,7 +2758,6 @@ def saturation(self, points, verbose=False, max_prime=-1, min_prime=2): sage: Q = E([-82,54]) sage: E.saturation([2*Q], max_prime=10) ([(-82 : 54 : 1)], 2, 2.36570863272098) - """ if not isinstance(points, list): raise TypeError("points (=%s) must be a list." % points) @@ -3008,14 +2986,13 @@ def point_search(self, height_limit, verbose=False, rank_bound=None): points = self.saturation(points, verbose=verbose)[0] return points - def selmer_rank(self, algorithm="pari"): + def selmer_rank(self, algorithm='pari'): r""" Return the rank of the 2-Selmer group of the curve. INPUT: - - ``algorithm`` -- (default:``'pari'``) - either ``'pari'`` or ``'mwrank'`` + - ``algorithm`` -- either ``'pari'`` (default) or ``'mwrank'`` EXAMPLES: This example has rank 1, Sha[2] of order 4 and @@ -3024,7 +3001,7 @@ def selmer_rank(self, algorithm="pari"): sage: E = EllipticCurve([1, 1, 1, 508, -2551]) sage: E.selmer_rank() 4 - sage: E.selmer_rank(algorithm="mwrank") + sage: E.selmer_rank(algorithm='mwrank') 4 The following is the curve 960d1, which has rank 0, but @@ -3033,7 +3010,7 @@ def selmer_rank(self, algorithm="pari"): sage: E = EllipticCurve([0, -1, 0, -900, -10098]) sage: E.selmer_rank() 3 - sage: E.selmer_rank(algorithm="mwrank") + sage: E.selmer_rank(algorithm='mwrank') 3 This curve has rank 1, and 4 elements in Sha[2]. @@ -3067,15 +3044,14 @@ def selmer_rank(self, algorithm="pari"): else: raise ValueError(f"unknown {algorithm=}") - def rank_bound(self, algorithm="pari"): + def rank_bound(self, algorithm='pari'): r""" Return the upper bound on the rank of the curve, computed using a 2-descent. INPUT: - - ``algorithm`` -- (default:``'pari'``) - either ``'pari'`` or ``'mwrank'`` + - ``algorithm`` -- either ``'pari'`` (default) or ``'mwrank'`` In many cases, this is the actual rank of the curve. @@ -3094,7 +3070,7 @@ def rank_bound(self, algorithm="pari"): sage: E = EllipticCurve([0, -1, 1, -929, -10595]) sage: E.rank_bound() 0 - sage: E.rank_bound(algorithm="mwrank") + sage: E.rank_bound(algorithm='mwrank') 2 In the following last example, both algorithm only determine a rank bound larger than the actual rank:: @@ -3102,7 +3078,7 @@ def rank_bound(self, algorithm="pari"): sage: E = EllipticCurve([1, 1, 1, -896670, -327184905]) sage: E.rank_bound() 2 - sage: E.rank_bound(algorithm="mwrank") + sage: E.rank_bound(algorithm='mwrank') 2 sage: E.rank(only_use_mwrank=False) # uses L-function 0 @@ -3197,7 +3173,7 @@ def is_minimal(self): def is_p_minimal(self, p): r""" - Tests if curve is ``p``-minimal at a given prime ``p``. + Test if curve is `p`-minimal at a given prime `p`. INPUT: @@ -3205,8 +3181,8 @@ def is_p_minimal(self, p): OUTPUT: - - ``True`` -- if curve is p-minimal - - ``False`` -- if curve is not p-minimal + - ``True`` -- if curve is `p`-minimal + - ``False`` -- if curve is not `p`-minimal EXAMPLES:: @@ -3414,7 +3390,7 @@ def has_good_reduction_outside_S(self, S=None): INPUT: - - ``S`` -- list of primes (default: ``[]``). + - ``S`` -- list of primes (default: ``[]``) .. NOTE:: @@ -3549,10 +3525,10 @@ def elliptic_exponential(self, z, embedding=None): def lseries(self): r""" - Return the L-series of this elliptic curve. + Return the `L`-series of this elliptic curve. Further documentation is available for the functions which apply to - the L-series. + the `L`-series. EXAMPLES:: @@ -3569,16 +3545,16 @@ def lseries(self): def lseries_gross_zagier(self, A): r""" - Return the Gross-Zagier L-series attached to ``self`` + Return the Gross-Zagier `L`-series attached to ``self`` and an ideal class `A`. INPUT: - ``A`` -- an ideal class in an imaginary quadratic number field `K` - This L-series `L(E,A,s)` is defined as the product of a shifted L-function of the + This `L`-series `L(E,A,s)` is defined as the product of a shifted `L`-function of the quadratic character associated to `K` and the Dirichlet series whose `n`-th - coefficient is the product of the `n`-th factor of the L-series of `E` and + coefficient is the product of the `n`-th factor of the `L`-series of `E` and the number of integral ideal in `A` of norm `n`. For any character `\chi` on the class group of `K`, one gets `L_K(E,\chi,s) = \sum_{A} \chi(A) L(E,A,s)` where `A` runs through the class group of `K`. @@ -3650,8 +3626,8 @@ def _F(n, t): def is_local_integral_model(self, *p): r""" - Tests if ``self`` is integral at the prime ``p``, or at all the - primes if ``p`` is a list or tuple of primes. + Test if ``self`` is integral at the prime `p`, or at all the + primes if `p` is a list or tuple of primes. EXAMPLES:: @@ -3673,7 +3649,7 @@ def is_local_integral_model(self, *p): def local_integral_model(self, p): r""" - Return a model of self which is integral at the prime ``p``. + Return a model of ``self`` which is integral at the prime `p`. EXAMPLES:: @@ -3749,7 +3725,7 @@ def integral_short_weierstrass_model(self): B /= Integer(p**(6 * e)) return constructor.EllipticCurve([A, B]) - def _generalized_congmod_numbers(self, M, invariant="both"): + def _generalized_congmod_numbers(self, M, invariant='both'): r""" Internal method to compute the generalized modular degree and congruence number at level `MN`, where `N` is the conductor of `E`. @@ -3763,16 +3739,16 @@ def _generalized_congmod_numbers(self, M, invariant="both"): INPUT: - - ``M`` -- non-negative integer; this function is only ever called on + - ``M`` -- nonnegative integer; this function is only ever called on `M > 1`, although the algorithm works fine for the case `M = 1` - - ``invariant`` -- string (default: ``"both"``); options are: + - ``invariant`` -- string (default: ``'both'``); options are: - - "both" -- both modular degree and congruence number at level `MN` are computed + - ``'both'`` -- both modular degree and congruence number at level `MN` are computed - - "moddeg" -- only modular degree is computed + - ``'moddeg'`` -- only modular degree is computed - - "congnum" -- only congruence number is computed + - ``'congnum'`` -- only congruence number is computed OUTPUT: @@ -3843,7 +3819,7 @@ def modular_degree(self, algorithm='sympow', M=1): INPUT: - - ``algorithm`` -- string: + - ``algorithm`` -- string; one of * ``'sympow'`` -- (default) use Mark Watkin's (newer) C program sympow @@ -3851,7 +3827,7 @@ def modular_degree(self, algorithm='sympow', M=1): * ``'magma'`` -- requires that MAGMA be installed (also implemented by Mark Watkins) - - ``M`` -- non-negative integer; the modular degree at level `MN` + - ``M`` -- nonnegative integer; the modular degree at level `MN` is returned (see above) .. NOTE:: @@ -4024,7 +4000,7 @@ def congruence_number(self, M=1): INPUT: - - ``M`` -- non-negative integer; congruence number is computed + - ``M`` -- nonnegative integer; congruence number is computed at level `MN`, where `N` is the conductor of ``self`` EXAMPLES:: @@ -4100,7 +4076,7 @@ def congruence_number(self, M=1): def cremona_label(self, space=False): r""" Return the Cremona label associated to (the minimal model) of this - curve, if it is known. If not, raise a ``LookupError`` exception. + curve, if it is known. If not, raise a :exc:`LookupError` exception. EXAMPLES:: @@ -4250,7 +4226,7 @@ def torsion_subgroup(self): r""" Return the torsion subgroup of this elliptic curve. - OUTPUT: The EllipticCurveTorsionSubgroup instance associated to + OUTPUT: the EllipticCurveTorsionSubgroup instance associated to this elliptic curve. .. NOTE:: @@ -4295,10 +4271,9 @@ def torsion_subgroup(self): def torsion_points(self): r""" - Return the torsion points of this elliptic curve as a sorted - list. + Return the torsion points of this elliptic curve as a sorted list. - OUTPUT: A list of all the torsion points on this elliptic curve. + OUTPUT: list of all the torsion points on this elliptic curve EXAMPLES:: @@ -4369,12 +4344,12 @@ def root_number(self, p=None): r""" Return the root number of this elliptic curve. - This is 1 if the order of vanishing of the L-function `L(E,s)` at 1 + This is 1 if the order of vanishing of the `L`-function `L(E,s)` at 1 is even, and -1 if it is odd. INPUT: - - `p` -- (optional) if given, return the local root number at ``p`` + - ``p`` -- (optional) if given, return the local root number at ``p`` EXAMPLES:: @@ -4450,7 +4425,7 @@ def cm_discriminant(self): Return the associated quadratic discriminant if this elliptic curve has Complex Multiplication over the algebraic closure. - A :class:`ValueError` is raised if the curve does not have CM (see the + A :exc:`ValueError` is raised if the curve does not have CM (see the function :meth:`has_cm()`). EXAMPLES:: @@ -4672,29 +4647,29 @@ def minimal_quadratic_twist(self): ########################################################## # Isogeny class ########################################################## - def isogeny_class(self, algorithm="sage", order=None): + def isogeny_class(self, algorithm='sage', order=None): r""" Return the `\QQ`-isogeny class of this elliptic curve. INPUT: - - ``algorithm`` -- string: one of the following: + - ``algorithm`` -- string; one of - - "database" -- use the Cremona database (only works if + - ``'database'`` -- use the Cremona database (only works if curve is isomorphic to a curve in the database) - - "sage" (default) -- use the native Sage implementation. + - ``'sage'`` (default) -- use the native Sage implementation - ``order`` -- ``None``, string, or list of curves (default: - ``None``); If not ``None`` then the curves in the class are + ``None``); if not ``None`` then the curves in the class are reordered after being computed. Note that if the order is ``None`` then the resulting order will depend on the algorithm. - - If ``order`` is "database" or "sage", then the reordering + - If ``order`` is ``'database'`` or ``'sage'``, then the reordering is so that the order of curves matches the order produced by that algorithm. - - If ``order`` is "lmfdb" then the curves are sorted + - If ``order`` is ``'lmfdb'`` then the curves are sorted lexicographically by a-invariants, in the LMFDB database. - If ``order`` is a list of curves, then the curves in the @@ -4717,7 +4692,7 @@ class are reordered to be isomorphic with the specified EXAMPLES:: - sage: isocls = EllipticCurve('37b').isogeny_class(order="lmfdb") + sage: isocls = EllipticCurve('37b').isogeny_class(order='lmfdb') sage: isocls Elliptic curve isogeny class 37b sage: isocls.curves @@ -4731,7 +4706,7 @@ class are reordered to be isomorphic with the specified :: - sage: isocls = EllipticCurve('37b').isogeny_class('database', order="lmfdb"); isocls.curves + sage: isocls = EllipticCurve('37b').isogeny_class('database', order='lmfdb'); isocls.curves (Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field, Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field, Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field) @@ -4934,14 +4909,14 @@ def isogenies_prime_degree(self, l=None): def is_isogenous(self, other, proof=True, maxp=200): r""" - Return whether or not self is isogenous to other. + Return whether or not ``self`` is isogenous to other. INPUT: - ``other`` -- another elliptic curve - - ``proof`` -- (default: ``True``) if ``False``, the function will - return ``True`` whenever the two curves have the same + - ``proof`` -- boolean (default: ``True``); if ``False``, the function + will return ``True`` whenever the two curves have the same conductor and are isogenous modulo `p` for `p` up to ``maxp``; otherwise this test is followed by a rigorous test (which may be more time-consuming) @@ -4951,7 +4926,7 @@ def is_isogenous(self, other, proof=True, maxp=200): OUTPUT: - (bool) True if there is an isogeny from curve ``self`` to + boolean; ``True`` if there is an isogeny from curve ``self`` to curve ``other``. ALGORITHM: @@ -5249,7 +5224,7 @@ def manin_constant(self): that in each class there is at least one, more precisely the so-called strong Weil curve or `X_0(N)`-optimal curve, that has Manin constant `1`. - OUTPUT: An integer. + OUTPUT: integer This function only works if the curve is in the installed Cremona database. Sage includes by default a small database; @@ -5320,11 +5295,9 @@ def _shortest_paths(self): r""" Technical internal function that returns the list of isogenies curves and corresponding dictionary of shortest isogeny paths - from self to each other curve in the isogeny class. + from ``self`` to each other curve in the isogeny class. - OUTPUT: - - list, dict + OUTPUT: list, dictionary EXAMPLES:: @@ -5458,7 +5431,7 @@ def is_ordinary(self, p, ell=None): - ``p`` -- a prime - ``ell`` -- a prime (default: ``p``) - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -5483,7 +5456,7 @@ def is_good(self, p, check=True): - ``p`` -- a prime - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -5502,8 +5475,8 @@ def is_good(self, p, check=True): def is_supersingular(self, p, ell=None): r""" - Return ``True`` precisely when p is a prime of good reduction and the - mod-``p`` representation attached to this elliptic curve is + Return ``True`` precisely when `p` is a prime of good reduction and the + mod-`p` representation attached to this elliptic curve is supersingular at ell. INPUT: @@ -5511,7 +5484,7 @@ def is_supersingular(self, p, ell=None): - ``p`` -- a prime - ``ell`` -- a prime (default: ``p``) - OUTPUT: bool + OUTPUT: boolean EXAMPLES:: @@ -5603,13 +5576,13 @@ def eval_modular_form(self, points, order): INPUT: - - ``points`` -- a list of points in the upper half-plane + - ``points`` -- list of points in the upper half-plane - - ``order`` -- a nonnegative integer + - ``order`` -- nonnegative integer The ``order`` parameter is the number of terms used in the summation. - OUTPUT: A list of values for `s` in ``points`` + OUTPUT: list of values for `s` in ``points`` EXAMPLES:: @@ -5745,8 +5718,7 @@ def tate_curve(self, p): INPUT: - - `p` -- a prime where the curve has split multiplicative - reduction + - ``p`` -- a prime where the curve has split multiplicative reduction EXAMPLES:: @@ -5845,17 +5817,13 @@ def faltings_height(self, stable=False, prec=None): INPUT: - - ``stable`` -- boolean (default: ``False``); if ``True``, - return the *stable* Faltings height, otherwise the unstable - height - - - ``prec`` -- integer (default: ``None``); bit - precision of output; if ``None``, use standard - precision (53 bits) + - ``stable`` -- boolean (default: ``False``); if ``True``, return the + *stable* Faltings height, otherwise the unstable height - OUTPUT: + - ``prec`` -- integer (default: ``None``); bit precision of output; if + ``None``, use standard precision (53 bits) - (real) the Faltings height of this elliptic curve. + OUTPUT: real; the Faltings height of this elliptic curve .. NOTE:: @@ -5938,11 +5906,10 @@ def antilogarithm(self, z, max_denominator=None): OUTPUT: - - point on the curve: the rational point which is the - image of `z` under the Weierstrass parametrization, if it - exists and can be determined from `z` and the given value - of max_denominator (if any); otherwise a :class:`ValueError` exception - is raised. + A point on the curve: the rational point which is the image of `z` + under the Weierstrass parametrization, if it exists and can be + determined from `z` and the given value of max_denominator (if any); + otherwise a :exc:`ValueError` exception is raised. EXAMPLES:: @@ -5985,12 +5952,12 @@ def integral_x_coords_in_interval(self,xmin,xmax): INPUT: - - ``xmin``, ``xmax`` (integers) -- two integers + - ``xmin``, ``xmax`` -- two integers OUTPUT: - (set) The set of integers `x` with `xmin\le x\le xmax` which - are `x`-coordinates of rational points on the elliptic curve. + The set of integers `x` with `xmin\le x\le xmax` which are + `x`-coordinates of rational points on the elliptic curve. EXAMPLES:: @@ -6038,7 +6005,7 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): - ``verbose`` -- boolean (default: ``False``); if ``True``, some details of the computation are output - OUTPUT: A sorted list of all the integral points on `E` (up to sign + OUTPUT: a sorted list of all the integral points on `E` (up to sign unless ``both_signs`` is ``True``) .. NOTE:: @@ -6171,7 +6138,7 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): ############################## begin ################################ def point_preprocessing(free,tor): r""" - Transforms the mw_basis ``free`` into a `\ZZ`-basis for + Transform the mw_basis ``free`` into a `\ZZ`-basis for `E(\QQ)\cap E^0(`\RR)`. If there is a torsion point on the "egg" we add it to any of the gens on the egg; otherwise we replace the free generators with generators of a @@ -6234,10 +6201,11 @@ def point_preprocessing(free,tor): e1,e2,e3 = ei if r >= 1: #preprocessing of mw_base only necessary if rank > 0 mw_base = point_preprocessing(mw_base, tors_points) - #at most one point in E^{egg} + # at most one point in E^{egg} - elif disc < 0: # one real component => 1 root in RR (=: e3), - # 2 roots in C (e1,e2) + elif disc < 0: + # one real component => 1 root in RR (=: e3), + # 2 roots in C (e1,e2) roots = pol.roots(C,multiplicities=False) e3 = pol.roots(R,multiplicities=False)[0] roots.remove(e3) @@ -6329,8 +6297,7 @@ def point_preprocessing(free,tor): c1_LLL = -R.one() for i in range(n): tmp = R(b1_norm/(m_gram.row(i).norm())) - if tmp > c1_LLL: - c1_LLL = tmp + c1_LLL = max(tmp, c1_LLL) if c1_LLL < 0: raise RuntimeError('Unexpected intermediate result. Please try another Mordell-Weil base') @@ -6438,8 +6405,8 @@ def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, details of the computation are output - ``proof`` -- boolean (default: ``True``); if ``True`` ALL - S-integral points will be returned. If False, the MW basis - will be computed with the proof=False flag, and also the + S-integral points will be returned. If ``False``, the MW basis + will be computed with the ``proof=False`` flag, and also the time-consuming final call to S_integral_x_coords_with_abs_bounded_by(abs_bound) is omitted. Use this only if the computation takes too long, @@ -6449,7 +6416,7 @@ def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, OUTPUT: A sorted list of all the S-integral points on E (up to sign - unless both_signs is True) + unless ``both_signs`` is ``True``). .. NOTE:: @@ -6655,8 +6622,7 @@ def reduction_at(p): c1_LLL = -R.one() for i in range(n): tmp = R(b1_norm/(m_gram.row(i).norm())) - if tmp > c1_LLL: - c1_LLL = tmp + c1_LLL = max(tmp, c1_LLL) if c1_LLL < 0: raise RuntimeError('Unexpected intermediate result. Please try another Mordell-Weil base') d_L_0 = R(b1_norm**2 / c1_LLL) @@ -6720,16 +6686,16 @@ def test_with_T(R): for T in tors_points: test(R+T) - # For small rank and small H_q perform simple search + # For small rank and small H_q perform simple search if r == 1 and N <= 10: for P in multiples(mw_base[0],N+1): test_with_T(P) return xs - # explicit computation and testing linear combinations - # ni loops through all tuples (n_1,...,n_r) with |n_i| <= N - # stops when (0,0,...,0) is reached because after that, only inverse points of - # previously tested points would be tested + # explicit computation and testing linear combinations + # ni loops through all tuples (n_1,...,n_r) with |n_i| <= N + # stops when (0,0,...,0) is reached because after that, only inverse points of + # previously tested points would be tested E0 = E(0) ni = [-N for i in range(r)] @@ -6882,13 +6848,14 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): prec *= 2 RR = RealField(prec) ei = pol.roots(RR,multiplicities=False) - e1,e2,e3 = ei - elif disc < 0: # one real component => 1 root in RR (=: e3), - # 2 roots in C (e1,e2) + e1, e2, e3 = ei + elif disc < 0: + # one real component => 1 root in RR (=: e3), + # 2 roots in C (e1,e2) roots = pol.roots(C,multiplicities=False) e3 = pol.roots(R,multiplicities=False)[0] roots.remove(e3) - e1,e2 = roots + e1, e2 = roots len_tors = len(tors_points) n = r + 1 @@ -6898,7 +6865,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): M = U.transpose()*M*U # NB "lambda" is a reserved word in Python! - lamda = min(M.charpoly(algorithm="hessenberg").roots(multiplicities=False)) + lamda = min(M.charpoly(algorithm='hessenberg').roots(multiplicities=False)) max_S = max(S) len_S += 1 #Counting infinity (always "included" in S) if verbose: @@ -6921,10 +6888,10 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): if verbose: print('k1,k2,k3,k4', k1, k2, k3, k4) sys.stdout.flush() - #H_q -> [PZGH]:N_0 (due to consistency to integral_points()) + # H_q -> [PZGH]:N_0 (due to consistency to integral_points()) H_q = R(((k1/2+k2)/lamda).sqrt()) - #computation of logs + # computation of logs mw_base_log = [(pts.elliptic_logarithm().abs())*(len_tors/w1) for pts in mw_base] mw_base_p_log = [] beta = [] @@ -6934,7 +6901,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): Np = E.Np(p) cp = E.tamagawa_exponent(p) mp_temp = Z(len_tors).lcm(cp*Np) - mp.append(mp_temp) #only necessary because of verbose below + mp.append(mp_temp) # only necessary because of verbose below p_prec = 30+E.discriminant().valuation(p) p_prec_ok = False while not p_prec_ok: @@ -6945,7 +6912,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): p_prec_ok = True except ValueError: p_prec *= 2 - #reorder mw_base_p: last value has minimal valuation at p + # reorder mw_base_p: last value has minimal valuation at p mw_base_p_log_val = [mw_base_p_log[tmp][i].valuation() for i in range(r)] if verbose: print("mw_base_p_log_val = ",mw_base_p_log_val) @@ -6955,7 +6922,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): print("min_psi = ", min_psi) mw_base_p_log[tmp].remove(min_psi) mw_base_p_log[tmp].append(min_psi) - #beta needed for reduction at p later on + # beta needed for reduction at p later on try: beta.append([-mw_base_p_log[tmp][j]/min_psi for j in range(r)]) except ValueError: @@ -6970,7 +6937,8 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): print('mw_base_p_log', mw_base_p_log) sys.stdout.flush() - #constants in reduction (not needed to be computed every reduction step) + # constants in reduction + # (not needed to be computed every reduction step) k5 = R((2*len_tors)/(3*w1)) k6 = R((k2/len_S).exp()) k7 = R(lamda/len_S) @@ -6981,20 +6949,20 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): break_cond = 0 M = MatrixSpace(Z,n) - #Reduction of initial bound + # Reduction of initial bound if verbose: print('initial bound', H_q) sys.stdout.flush() while break_cond < 0.9: - #reduction at infinity + # reduction at infinity bound_list = [] c = R((H_q**n)*100) m = copy(M.identity_matrix()) for i in range(r): m[i, r] = R(c*mw_base_log[i]).round() m[r,r] = max(Z(1), R(c*w1).round()) - #LLL - implemented in sage - operates on rows not on columns + # LLL - implemented in sage - operates on rows not on columns m_LLL = m.LLL() m_gram = m_LLL.gram_schmidt()[0] b1_norm = R(m_LLL.row(0).norm()) @@ -7003,8 +6971,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): c1_LLL = -R.one() for i in range(n): tmp = R(b1_norm/(m_gram.row(i).norm())) - if tmp > c1_LLL: - c1_LLL = tmp + c1_LLL = max(tmp, c1_LLL) if c1_LLL < 0: raise RuntimeError('Unexpected intermediate result. Please try another Mordell-Weil base') d_L_0 = R(b1_norm**2 / c1_LLL) @@ -7131,6 +7098,7 @@ def cremona_curves(conductors): conductors = [conductors] return sage.databases.cremona.CremonaDatabase().iter(conductors) + def cremona_optimal_curves(conductors): r""" Return iterator over all known optimal curves (in database) with @@ -7157,6 +7125,7 @@ def cremona_optimal_curves(conductors): conductors = [conductors] return sage.databases.cremona.CremonaDatabase().iter_optimal(conductors) + def integral_points_with_bounded_mw_coeffs(E, mw_base, N, x_bound): r""" Return the set of integers `x` which are @@ -7167,15 +7136,14 @@ def integral_points_with_bounded_mw_coeffs(E, mw_base, N, x_bound): INPUT: - ``E`` -- an elliptic curve - - ``mw_base`` -- a list of points on `E` (generators) - - ``N`` -- a positive integer (bound on coefficients) + - ``mw_base`` -- list of points on `E` (generators) + - ``N`` -- positive integer (bound on coefficients) - ``x_bound`` -- a positive real number (upper bound on size of x-coordinates) OUTPUT: - (list) list of integral points on `E` which are linear combinations - of the given points with coefficients bounded by `N` in absolute - value. + list of integral points on `E` which are linear combinations of the given + points with coefficients bounded by `N` in absolute value. TESTS: @@ -7304,13 +7272,13 @@ def elliptic_curve_congruence_graph(curves): INPUT: - - ``curves`` -- a list of elliptic curves + - ``curves`` -- list of elliptic curves OUTPUT: The graph with each curve as a vertex (labelled by its Cremona label) and an edge from `E` to `F` labelled `p` if and only if `E` is - congruent to `F` mod `p` + congruent to `F` mod `p`. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/ell_tate_curve.py b/src/sage/schemes/elliptic_curves/ell_tate_curve.py old mode 100644 new mode 100755 index 70697a4b036..7defaf1d50c --- a/src/sage/schemes/elliptic_curves/ell_tate_curve.py +++ b/src/sage/schemes/elliptic_curves/ell_tate_curve.py @@ -39,17 +39,18 @@ # # https://www.gnu.org/licenses/ ###################################################################### -from sage.rings.integer_ring import ZZ -from sage.rings.padics.factory import Qp -from sage.structure.sage_object import SageObject -from sage.structure.richcmp import richcmp, richcmp_method from sage.arith.functions import lcm as LCM +from sage.matrix.constructor import matrix +from sage.misc.functional import denominator, log +from sage.misc.lazy_import import lazy_import +from sage.misc.misc_c import prod from sage.modular.modform.constructor import EisensteinForms, CuspForms +from sage.rings.integer_ring import ZZ from sage.schemes.elliptic_curves.constructor import EllipticCurve -from sage.functions.log import log -from sage.misc.functional import denominator -from sage.misc.misc_c import prod -from sage.matrix.constructor import matrix +from sage.structure.richcmp import richcmp, richcmp_method +from sage.structure.sage_object import SageObject + +lazy_import('sage.rings.padics.factory', 'Qp') @richcmp_method @@ -81,7 +82,7 @@ def __init__(self, E, p): - ``E`` -- an elliptic curve over the rational numbers - ``p`` -- a prime where `E` has multiplicative reduction, - i.e., such that `j(E)` has negative valuation. + i.e., such that `j(E)` has negative valuation EXAMPLES:: @@ -166,7 +167,7 @@ def parameter(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -208,7 +209,7 @@ def curve(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -243,7 +244,7 @@ def _Csquare(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -268,7 +269,7 @@ def E2(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -312,10 +313,10 @@ def parametrisation_onto_tate_curve(self, u, prec=None): INPUT: - - ``u`` -- a non-zero `p`-adic number. + - ``u`` -- a nonzero `p`-adic number - - ``prec`` -- the `p`-adic precision, default is the relative precision of ``u`` - otherwise 20. + - ``prec`` -- the `p`-adic precision; default is the relative precision + of ``u``, otherwise 20 EXAMPLES:: @@ -374,7 +375,7 @@ def L_invariant(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -405,7 +406,7 @@ def _isomorphism(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -442,7 +443,7 @@ def _inverse_isomorphism(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -465,9 +466,9 @@ def lift(self, P, prec=20): INPUT: - - ``P`` -- a point on the elliptic curve. + - ``P`` -- a point on the elliptic curve - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: @@ -521,10 +522,10 @@ def parametrisation_onto_original_curve(self, u, prec=None): INPUT: - - ``u`` -- a non-zero `p`-adic number. + - ``u`` -- a nonzero `p`-adic number - - ``prec`` -- the `p`-adic precision, default is the relative precision of ``u`` - otherwise 20. + - ``prec`` -- the `p`-adic precision; default is the relative precision + of ``u``, otherwise 20 EXAMPLES:: @@ -577,11 +578,9 @@ def padic_height(self, prec=20): INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. - - OUTPUT: + - ``prec`` -- the `p`-adic precision (default: 20) - - A function that can be evaluated on rational points of `E`. + OUTPUT: a function that can be evaluated on rational points of `E` EXAMPLES:: @@ -634,11 +633,11 @@ def padic_regulator(self, prec=20): The `p`-adic Birch and Swinnerton-Dyer conjecture predicts that this value appears in the formula for the leading term of - the `p`-adic L-function. + the `p`-adic `L`-function. INPUT: - - ``prec`` -- the `p`-adic precision, default is 20. + - ``prec`` -- the `p`-adic precision (default: 20) EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/ell_torsion.py b/src/sage/schemes/elliptic_curves/ell_torsion.py old mode 100644 new mode 100755 index cc543b339a4..ade14590440 --- a/src/sage/schemes/elliptic_curves/ell_torsion.py +++ b/src/sage/schemes/elliptic_curves/ell_torsion.py @@ -137,11 +137,11 @@ class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper): """ def __init__(self, E): r""" - Initialization function for EllipticCurveTorsionSubgroup class + Initialization function for EllipticCurveTorsionSubgroup class. INPUT: - - ``E`` -- An elliptic curve defined over a number field (including `\QQ`) + - ``E`` -- an elliptic curve defined over a number field (including `\QQ`) EXAMPLES:: @@ -287,7 +287,7 @@ def torsion_bound(E, number_of_places=20): - ``E`` -- an elliptic curve over `\QQ` or a number field - - ``number_of_places`` (positive integer, default = 20) -- the + - ``number_of_places`` -- positive integer (default: 20); the number of places that will be used to find the bound OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_wp.py b/src/sage/schemes/elliptic_curves/ell_wp.py old mode 100644 new mode 100755 index 8532ce08b74..5c8e7930830 --- a/src/sage/schemes/elliptic_curves/ell_wp.py +++ b/src/sage/schemes/elliptic_curves/ell_wp.py @@ -54,6 +54,7 @@ # Note: Part of the documentation is replicated in ell_field.py for # users' convenience. Make sure to keep the two copies synchronized. + def weierstrass_p(E, prec=20, algorithm=None): r""" Compute the Weierstrass `\wp`-function on an elliptic curve. @@ -64,9 +65,9 @@ def weierstrass_p(E, prec=20, algorithm=None): - ``prec`` -- precision - - ``algorithm`` -- string or ``None`` (default: ``None``): - a choice of algorithm among ``"pari"``, ``"fast"``, ``"quadratic"``; - or ``None`` to let this function determine the best algorithm to use. + - ``algorithm`` -- string or ``None`` (default: ``None``); + a choice of algorithm among ``'pari'``, ``'fast'``, ``'quadratic'``, + or ``None`` to let this function determine the best algorithm to use OUTPUT: @@ -110,7 +111,7 @@ def weierstrass_p(E, prec=20, algorithm=None): NotImplementedError: currently no algorithms for computing the Weierstrass p-function for that characteristic / precision pair is implemented. Lower the precision below char(k) - 2 - sage: E.weierstrass_p(prec=9, algorithm="quadratic") + sage: E.weierstrass_p(prec=9, algorithm='quadratic') Traceback (most recent call last): ... ValueError: for computing the Weierstrass p-function via the quadratic @@ -165,9 +166,10 @@ def weierstrass_p(E, prec=20, algorithm=None): u = E.isomorphism_to(Esh).u return wp(z*u) * u**2 + def compute_wp_pari(E,prec): r""" - Computes the Weierstrass `\wp`-function with the ``ellwp`` function + Compute the Weierstrass `\wp`-function with the ``ellwp`` function from PARI. EXAMPLES:: @@ -206,7 +208,7 @@ def compute_wp_quadratic(k, A, B, prec): - ``k`` -- the field of definition of the curve - ``A`` -- and - ``B`` -- the coefficients of the elliptic curve - - ``prec`` -- the precision to which we compute the series. + - ``prec`` -- the precision to which we compute the series OUTPUT: @@ -251,9 +253,10 @@ def compute_wp_quadratic(k, A, B, prec): return pe(Z**2).add_bigoh(prec) + def compute_wp_fast(k, A, B, m): r""" - Computes the Weierstrass function of an elliptic curve defined by short Weierstrass model: + Compute the Weierstrass function of an elliptic curve defined by short Weierstrass model: `y^2 = x^3 + Ax + B`. It does this with as fast as polynomial of degree `m` can be multiplied together in the base ring, i.e. `O(M(n))` in the notation of [BMSS2006]_. @@ -264,11 +267,9 @@ def compute_wp_fast(k, A, B, m): - ``k`` -- the base field of the curve - ``A`` -- and - ``B`` -- as the coefficients of the short Weierstrass model `y^2 = x^3 +Ax +B`, and - - ``m`` -- the precision to which the function is computed to. - - OUTPUT: + - ``m`` -- the precision to which the function is computed to - the Weierstrass `\wp` function as a Laurent series to precision `m`. + OUTPUT: the Weierstrass `\wp` function as a Laurent series to precision `m` ALGORITHM: @@ -318,7 +319,7 @@ def compute_wp_fast(k, A, B, m): def solve_linear_differential_system(a, b, c, alpha): r""" - Solves a system of linear differential equations: `af' + bf = c` and `f'(0) = \alpha` + Solve a system of linear differential equations: `af' + bf = c` and `f'(0) = \alpha` where `a`, `b`, and `c` are power series in one variable and `\alpha` is a constant in the coefficient ring. ALGORITHM: diff --git a/src/sage/schemes/elliptic_curves/formal_group.py b/src/sage/schemes/elliptic_curves/formal_group.py old mode 100644 new mode 100755 index ae3dceb8555..3524c492a2f --- a/src/sage/schemes/elliptic_curves/formal_group.py +++ b/src/sage/schemes/elliptic_curves/formal_group.py @@ -118,7 +118,7 @@ def w(self, prec=20): .. WARNING:: - The resulting power series will have precision prec, but + The resulting power series will have precision ``prec``, but its parent PowerSeriesRing will have default precision 20 (or whatever the default default is). @@ -251,7 +251,7 @@ def x(self, prec=20): .. WARNING:: - The resulting series will have precision prec, but its + The resulting series will have precision ``prec``, but its parent PowerSeriesRing will have default precision 20 (or whatever the default default is). @@ -289,7 +289,7 @@ def y(self, prec=20): .. WARNING:: - The resulting series will have precision prec, but its + The resulting series will have precision ``prec``, but its parent PowerSeriesRing will have default precision 20 (or whatever the default default is). @@ -338,7 +338,7 @@ def differential(self, prec=20): .. WARNING:: - The resulting series will have precision prec, but its + The resulting series will have precision ``prec``, but its parent PowerSeriesRing will have default precision 20 (or whatever the default default is). @@ -417,7 +417,7 @@ def inverse(self, prec=20): .. WARNING:: - The resulting power series will have precision prec, but + The resulting power series will have precision ``prec``, but its parent PowerSeriesRing will have default precision 20 (or whatever the default default is). @@ -579,7 +579,7 @@ def mult_by_n(self, n, prec=10): .. WARNING:: - The resulting power series will have precision prec, but + The resulting power series will have precision ``prec``, but its parent PowerSeriesRing will have default precision 20 (or whatever the default default is). diff --git a/src/sage/schemes/elliptic_curves/gal_reps.py b/src/sage/schemes/elliptic_curves/gal_reps.py old mode 100644 new mode 100755 index 14700ad86c7..b9360acdf56 --- a/src/sage/schemes/elliptic_curves/gal_reps.py +++ b/src/sage/schemes/elliptic_curves/gal_reps.py @@ -130,7 +130,7 @@ def _ex_set(p): """ - Gives the set of the only values of trace^2/det + Give the set of the only values of trace^2/det that appear in a exceptional subgroup in PGL_2(F_p). EXAMPLES:: @@ -180,7 +180,7 @@ class GaloisRepresentation(SageObject): def __init__(self, E): r""" - see ``GaloisRepresentation`` for documentation + See ``GaloisRepresentation`` for documentation. EXAMPLES:: @@ -193,7 +193,7 @@ def __init__(self, E): def __repr__(self): r""" - string representation of the class + String representation of the class. EXAMPLES:: @@ -205,7 +205,7 @@ def __repr__(self): def __eq__(self,other): r""" - Compares two Galois representations. + Compare two Galois representations. We define tho compatible families of representations attached to elliptic curves to be isomorphic if the curves are equal. @@ -253,7 +253,7 @@ def elliptic_curve(self): def is_reducible(self, p): r""" - Return True if the mod-p representation is + Return ``True`` if the mod-p representation is reducible. This is equivalent to the existence of an isogeny defined over `\QQ` of degree `p` from the elliptic curve. @@ -262,7 +262,7 @@ def is_reducible(self, p): - ``p`` -- a prime number - OUTPUT: A boolean. + OUTPUT: boolean The answer is cached. @@ -307,13 +307,13 @@ def is_reducible(self, p): def is_irreducible(self, p): r""" - Return True if the mod p representation is irreducible. + Return ``True`` if the mod p representation is irreducible. INPUT: - ``p`` -- a prime number - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -362,22 +362,20 @@ def reducible_primes(self): def is_surjective(self, p, A=1000): r""" - Return True if the mod-p representation is + Return ``True`` if the mod-p representation is surjective onto `Aut(E[p]) = GL_2(\GF{p})`. - False if it is not, or None if we were unable to + ``False`` if it is not, or ``None`` if we were unable to determine whether it is or not. INPUT: - - ``p`` (integer) -- a prime number + - ``p`` -- integer; a prime number - - ``A`` (integer) -- a bound on the number of `a_p` to use + - ``A`` -- integer; a bound on the number of `a_p` to use - OUTPUT: - - - (boolean) -- True if the mod-p representation is surjective - and False if not. + OUTPUT: boolean; ``True`` if the mod-p representation is surjective + and ``False`` if not The answer is cached. @@ -418,13 +416,13 @@ def is_surjective(self, p, A=1000): REMARKS: 1. If `p \geq 5` then the mod-p representation is - surjective if and only if the p-adic representation is + surjective if and only if the `p`-adic representation is surjective. When `p = 2, 3` there are counterexamples. See papers of Dokchitsers and Elkies for more details. 2. For the primes `p=2` and 3, this will always answer either - True or False. For larger primes it might give None. + ``True`` or ``False``. For larger primes it might give ``None``. """ if not arith.is_prime(p): raise TypeError("p (=%s) must be prime." % p) @@ -443,7 +441,7 @@ def is_surjective(self, p, A=1000): def _is_surjective(self, p, A): r""" - helper function for ``is_surjective`` + Helper function for ``is_surjective``. The value of `A` is as before, except that `A=-1` is a special code to stop before @@ -607,12 +605,12 @@ def non_surjective(self, A=1000): INPUT: - - ``A`` -- an integer (default 1000). By increasing this parameter - the resulting set might get smaller. + - ``A`` -- integer (default: 1000); by increasing this parameter + the resulting set might get smaller OUTPUT: - - ``list`` -- if the curve has CM, returns [0]. + - ``list`` -- if the curve has CM, returns ``[0]``. Otherwise, returns a list of primes where mod-p representation is very likely not surjective. At any prime not in this list, the representation is definitely surjective. @@ -708,9 +706,9 @@ def image_type(self, p): INPUT: - - ``p`` a prime number + - ``p`` -- a prime number - OUTPUT: A string. + OUTPUT: string EXAMPLES:: @@ -1105,13 +1103,11 @@ def image_classes(self,p,bound=10000): INPUT: - - a prime ``p`` + - ``p`` -- a prime - - a natural number ``bound`` (default: 10000) - - OUTPUT: + - ``bound`` -- a natural number (default: 10000) - - a list of `p` real numbers in the interval `[0,1]` adding up to 1 + OUTPUT: list of `p` real numbers in the interval `[0,1]` adding up to 1 EXAMPLES:: @@ -1238,15 +1234,15 @@ def is_unramified(self,p,ell): if the inertia group at a place above `\ell` in `\text{Gal}(\bar\QQ/\QQ)` has trivial image in `GL_2(\ZZ_p)`. - For a Galois representation attached to an elliptic curve `E`, this returns True if `\ell\neq p` - and `E` has good reduction at `\ell`. + For a Galois representation attached to an elliptic curve `E`, this + returns ``True`` if `\ell\neq p` and `E` has good reduction at `\ell`. INPUT: - - ``p`` a prime - - ``ell`` another prime + - ``p`` -- a prime + - ``ell`` -- another prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1271,15 +1267,15 @@ def is_unipotent(self,p,ell): Return true if the Galois representation to `GL_2(\ZZ_p)` is unipotent at `\ell\neq p`, i.e. if the inertia group at a place above `\ell` in `\text{Gal}(\bar\QQ/\QQ)` maps into a Borel subgroup. - For a Galois representation attached to an elliptic curve `E`, this returns True if + For a Galois representation attached to an elliptic curve `E`, this returns ``True`` if `E` has semi-stable reduction at `\ell`. INPUT: - - ``p`` a prime - - ``ell`` a different prime + - ``p`` -- a prime + - ``ell`` -- a different prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1313,10 +1309,10 @@ def is_quasi_unipotent(self,p,ell): INPUT: - - ``p`` a prime - - ``ell`` a different prime + - ``p`` -- a prime + - ``ell`` -- a different prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1344,9 +1340,9 @@ def is_ordinary(self,p): INPUT: - - ``p`` a prime + - ``p`` -- a prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1372,9 +1368,9 @@ def is_crystalline(self,p): INPUT: - - ``p`` a prime + - ``p`` -- a prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1397,9 +1393,9 @@ def is_potentially_crystalline(self,p): INPUT: - - ``p`` a prime + - ``p`` -- a prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1421,9 +1417,9 @@ def is_semistable(self,p): INPUT: - - ``p`` a prime + - ``p`` -- a prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1443,13 +1439,13 @@ def is_potentially_semistable(self,p): r""" Return true if the `p`-adic Galois representation to `GL_2(\ZZ_p)` is potentially semistable. - For an elliptic curve `E`, this returns True always + For an elliptic curve `E`, this returns ``True`` always INPUT: - - ``p`` a prime + - ``p`` -- a prime - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py old mode 100644 new mode 100755 index e049b72fa76..a4eb66a6df7 --- a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py +++ b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py @@ -47,16 +47,18 @@ from sage.arith.misc import legendre_symbol, primes from sage.misc.functional import cyclotomic_polynomial +from sage.misc.lazy_import import lazy_import from sage.modules.free_module import VectorSpace from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.infinity import Infinity from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.rings.number_field.number_field import NumberField from sage.rings.rational_field import QQ from sage.sets.set import Set from sage.structure.sage_object import SageObject +lazy_import('sage.rings.number_field.number_field', 'NumberField') + class GaloisRepresentation(SageObject): r""" @@ -132,7 +134,7 @@ def __repr__(self): def __eq__(self,other): r""" - Compares two Galois representations. + Compare two Galois representations. We define two compatible families of representations attached to elliptic curves to be equal if the curves are isomorphic. @@ -176,15 +178,14 @@ def non_surjective(self, A=100): INPUT: - - ``A`` -- int (a bound on the number of traces of Frobenius to use - while trying to prove surjectivity). + - ``A`` -- integer; a bound on the number of traces of Frobenius to use + while trying to prove surjectivity OUTPUT: - - ``list`` -- A list of primes where mod-`p` representation is - very likely not surjective. At any prime not in this list, - the representation is definitely surjective. If `E` has CM, - the list [0] is returned. + A list of primes where mod-`p` representation is very likely not + surjective. At any prime not in this list, the representation is + definitely surjective. If `E` has CM, the list ``[0]`` is returned. EXAMPLES:: @@ -232,10 +233,10 @@ def is_surjective(self, p, A=100): INPUT: - * ``p`` -- a prime number. + - ``p`` -- prime number - * ``A`` -- (integer) a bound on the number of traces of Frobenius to use - while trying to prove surjectivity. + - ``A`` -- integer; a bound on the number of traces of Frobenius to use + while trying to prove surjectivity EXAMPLES:: @@ -290,18 +291,17 @@ def isogeny_bound(self, A=100): INPUT: - - ``A`` -- int (a bound on the number of traces of Frobenius to - use while trying to prove the mod-`p` - representation is not contained in a Borel). + - ``A`` -- integer; a bound on the number of traces of Frobenius to + use while trying to prove the mod-`p` representation is not contained + in a Borel OUTPUT: - - ``list`` -- A list of primes which contains (but may not be - equal to) all `p` for which the image of the mod-`p` - representation is contained in a Borel subgroup. At any - prime not in this list, the image is definitely not - contained in a Borel. If E has `CM` defined over `K`, the list - [0] is returned. + A list of primes which contains (but may not be equal to) all `p` for + which the image of the mod-`p` representation is contained in a Borel + subgroup. At any prime not in this list, the image is definitely not + contained in a Borel. If E has `CM` defined over `K`, the list ``[0]`` + is returned. EXAMPLES:: @@ -377,11 +377,10 @@ def reducible_primes(self): OUTPUT: - - ``list`` -- A list of those primes `p` for which the mod-`p` - representation is contained in a Borel subgroup, i.e. is - reducible. If E has CM *defined over K*, the list [0] is - returned (in this case the representation is reducible for - infinitely many primes). + A list of those primes `p` for which the mod-`p` representation is + contained in a Borel subgroup, i.e. is reducible. If E has CM + *defined over K*, the list ``[0]`` is returned (in this case the + representation is reducible for infinitely many primes). EXAMPLES:: @@ -423,6 +422,7 @@ def reducible_primes(self): return [l for l in self.isogeny_bound() if self.E.isogenies_prime_degree(l)] + def _non_surjective(E, patience=100): r""" Return a list of primes `p` including all primes for which the mod-`p` @@ -430,16 +430,16 @@ def _non_surjective(E, patience=100): INPUT: - - ``E`` -- EllipticCurve (over a number field). + - ``E`` -- :class:`EllipticCurve` (over a number field) - - ``A`` -- int (a bound on the number of traces of Frobenius to use - while trying to prove surjectivity). + - ``A`` -- integer; a bound on the number of traces of Frobenius to use + while trying to prove surjectivity OUTPUT: - - ``list`` -- A list of primes where mod-`p` representation is very likely - not surjective. At any prime not in this list, the representation is - definitely surjective. If E has CM, a :class:`ValueError` is raised. + A list of primes where mod-`p` representation is very likely not + surjective. At any prime not in this list, the representation is + definitely surjective. If E has CM, a :exc:`ValueError` is raised. EXAMPLES:: @@ -503,19 +503,17 @@ def Frobenius_filter(E, L, patience=100): INPUT: - - ``E`` -- EllipticCurve over a number field. + - ``E`` -- :class:`EllipticCurve` over a number field - - ``L`` -- a list of prime numbers. + - ``L`` -- list of prime numbers - - ``patience`` (int), default 100 -- a positive integer bounding - the number of traces of Frobenius to use while trying to prove - irreducibility. + - ``patience`` -- positive integer (default: 100) bounding the number of + traces of Frobenius to use while trying to prove irreducibility OUTPUT: - - list -- The list of all primes `\ell` in L for which the mod - `\ell` image might be contained in a Borel subgroup of - `GL_2(\mathbf{F}_{\ell})`. + The list of all primes `\ell` in L for which the mod `\ell` image might be + contained in a Borel subgroup of `GL_2(\mathbf{F}_{\ell})`. EXAMPLES:: @@ -604,17 +602,17 @@ def _exceptionals(E, L, patience=1000): INPUT: - - ``E`` -- EllipticCurve over a number field. + - ``E`` -- :class:`EllipticCurve` over a number field - - ``L`` -- a list of prime numbers. + - ``L`` -- list of prime numbers - - ``patience`` (int) -- a bound on the number of traces of Frobenius to - use while trying to prove surjectivity. + - ``patience`` -- integer; a bound on the number of traces of Frobenius to + use while trying to prove surjectivity OUTPUT: - - list -- The list of all primes l in L for which the mod l image - might fail to be surjective. + The list of all primes l in L for which the mod l image might fail to be + surjective. EXAMPLES:: @@ -753,7 +751,7 @@ def _over_numberfield(E): INPUT: - - ``E`` -- EllipticCurve over a number field. + - ``E`` -- :class:`EllipticCurve` over a number field OUTPUT: @@ -768,7 +766,6 @@ def _over_numberfield(E): sage: E = EllipticCurve([1, 2]) sage: sage.schemes.elliptic_curves.gal_reps_number_field._over_numberfield(E) Elliptic Curve defined by y^2 = x^3 + x + 2 over Number Field in a with defining polynomial x - """ K = E.base_field() @@ -779,6 +776,7 @@ def _over_numberfield(E): K = K.absolute_field('a') return E.change_ring(K) + def deg_one_primes_iter(K, principal_only=False): r""" Return an iterator over degree 1 primes of ``K``. @@ -786,7 +784,7 @@ def deg_one_primes_iter(K, principal_only=False): INPUT: - ``K`` -- a number field - - ``principal_only`` -- bool; if ``True``, only yield principal primes + - ``principal_only`` -- boolean; if ``True``, only yield principal primes OUTPUT: @@ -827,20 +825,21 @@ def deg_one_primes_iter(K, principal_only=False): if not principal_only or P.is_principal(): yield P + def _semistable_reducible_primes(E, verbose=False): r"""Find a list containing all semistable primes l unramified in K/QQ for which the Galois image for E could be reducible. INPUT: - - ``E`` -- EllipticCurve over a number field. + - ``E`` -- :class:`EllipticCurve` over a number field OUTPUT: A list of primes, which contains all primes `l` unramified in `K/\mathbb{QQ}`, such that `E` is semistable at all primes lying over `l`, and the Galois image at `l` is reducible. If `E` has CM - defined over its ground field, a ``ValueError`` is raised. + defined over its ground field, a :exc:`ValueError` is raised. EXAMPLES:: @@ -1009,19 +1008,18 @@ def _possible_normalizers(E, SA): INPUT: - - ``E`` -- EllipticCurve over a number field K. + - ``E`` -- :class:`EllipticCurve` over a number field K - - ``SA`` -- a list of primes of K. + - ``SA`` -- list of primes of K OUTPUT: - - list -- A list of primes, which contains all primes `l` such that the - Galois image at `l` is contained in the normalizer of a Cartan - subgroup, such that the corresponding quadratic character is - ramified only at primes in SA. + - a list of primes, which contains all primes `l` such that the Galois + image at `l` is contained in the normalizer of a Cartan subgroup, such + that the corresponding quadratic character is ramified only at primes in SA. - - If `E` has geometric CM that is not defined over its ground field, a - ValueError is raised. + - if `E` has geometric CM that is not defined over its ground field, a + :exc:`ValueError` is raised. EXAMPLES:: @@ -1156,6 +1154,7 @@ def _possible_normalizers(E, SA): # elliptiques", Nicolas Billerey, https://arxiv.org/abs/0908.1084 # + def Billerey_P_l(E, l): r""" Return Billerey's `P_l^*` as defined in [Bil2011]_, equation (9). @@ -1163,7 +1162,7 @@ def Billerey_P_l(E, l): INPUT: - ``E`` -- an elliptic curve over a number field `K`, given by a - global integral model. + global integral model - ``l`` -- a rational prime @@ -1191,6 +1190,7 @@ def Billerey_P_l(E, l): P = P.composed_op(E.reduction(q).frobenius_polynomial().adams_operator_on_roots(12*e), mul, monic=True) return P + def Billerey_B_l(E,l,B=0): r""" Return Billerey's `B_l`, adapted from the definition in [Bil2011]_, after (9). @@ -1198,11 +1198,12 @@ def Billerey_B_l(E,l,B=0): INPUT: - ``E`` -- an elliptic curve over a number field `K`, given by a - global integral model. + global integral model - - ``l`` (int) -- a rational prime + - ``l`` -- integer; a rational prime - - ``B`` (int) -- 0 or LCM of previous `B_l`: the prime-to-B part of this `B_l` is ignored. + - ``B`` -- integer; 0 or LCM of previous `B_l` the prime-to-B part of this + `B_l` is ignored EXAMPLES:: @@ -1240,11 +1241,12 @@ def Billerey_R_q(E, q, B=0): INPUT: - ``E`` -- an elliptic curve over a number field `K`, given by a - global integral model. + global integral model - ``q`` -- a prime ideal of `K` - - ``B`` (int) -- 0 or LCM of previous `R_q`: the prime-to-B part of this `R_q` is ignored. + - ``B`` -- integer; 0 or LCM of previous `R_q` the prime-to-B part of this + `R_q` is ignored EXAMPLES:: @@ -1284,21 +1286,21 @@ def Billerey_B_bound(E, max_l=200, num_l=8, small_prime_bound=0, debug=False): nonzero values are found (at most). Return the list of primes dividing all `B_l` computed, excluding those dividing 6 or ramified or of bad reduction or less than small_prime_bound. If - no non-zero values are found return [0]. + no nonzero values are found return ``[0]``. INPUT: - ``E`` -- an elliptic curve over a number field `K`, given by a - global integral model. + global integral model - - ``max_l`` (int, default 200) -- maximum size of primes l to check. + - ``max_l`` -- integer (default: 200); maximum size of primes l to check - - ``num_l`` (int, default 8) -- maximum number of primes l to check. + - ``num_l`` integer (default: 8); maximum number of primes l to check - - ``small_prime_bound`` (int, default 0) -- remove primes less - than this from the output. + - ``small_prime_bound`` -- integer (default: 0); remove primes less + than this from the output - - ``debug`` (bool, default ``False``) -- if ``True`` prints details. + - ``debug`` -- boolean (default: ``False``); if ``True`` prints details .. NOTE:: @@ -1392,23 +1394,23 @@ def Billerey_R_bound(E, max_l=200, num_l=8, small_prime_bound=None, debug=False) (at most) until ``num_l`` nonzero values are found (at most). Return the list of primes dividing all ``R_q`` computed, excluding those dividing 6 or ramified or of bad reduction or less than - small_prime_bound. If no non-zero values are found return [0]. + small_prime_bound. If no nonzero values are found return ``[0]``. INPUT: - ``E`` -- an elliptic curve over a number field `K`, given by a - global integral model. + global integral model - - ``max_l`` (int, default 200) -- maximum size of rational primes - l for which the primes q above l are checked. + - ``max_l`` -- integer (default: 200); maximum size of rational primes + l for which the primes q above l are checked - - ``num_l`` (int, default 8) -- maximum number of rational primes - l for which the primes q above l are checked. + - ``num_l`` -- integer (default: 8); maximum number of rational primes + l for which the primes q above l are checked - - ``small_prime_bound`` (int, default 0) -- remove primes less - than this from the output. + - ``small_prime_bound`` -- integer (default: 0); remove primes less + than this from the output - - ``debug`` (bool, default ``False``) -- if ``True`` prints details. + - ``debug`` -- boolean (default: ``False``); if ``True`` prints details .. NOTE:: @@ -1501,13 +1503,13 @@ def reducible_primes_Billerey(E, num_l=None, max_l=None, verbose=False): INPUT: - - ``E`` -- an elliptic curve defined over a number field `K`. + - ``E`` -- an elliptic curve defined over a number field `K` - - ``max_l`` (int or ``None`` (default)) -- the maximum prime + - ``max_l`` -- integer or ``None`` (default); the maximum prime `\ell` to use for the B-bound and R-bound. If ``None``, a default value will be used. - - ``num_l`` (int or ``None`` (default)) -- the number of primes + - ``num_l`` -- integer or ``None`` (default); the number of primes `\ell` to use for the B-bound and R-bound. If ``None``, a default value will be used. @@ -1524,7 +1526,7 @@ def reducible_primes_Billerey(E, num_l=None, max_l=None, verbose=False): Provided that one of these methods succeeds in producing a finite list of primes we check these using a local condition, and finally test that the primes returned actually are reducible. Otherwise - we return [0]. + we return ``[0]``. EXAMPLES:: @@ -1630,11 +1632,11 @@ def reducible_primes_naive(E, max_l=None, num_P=None, verbose=False): - ``E`` -- an elliptic curve defined over a number field `K` - - ``max_l`` (int or ``None`` (default)) -- the maximum prime - `\ell` to test. + - ``max_l`` -- integer or ``None`` (default); the maximum prime + `\ell` to test - - ``num_P`` (int or ``None`` (default)) -- the number of primes - `P` of `K` to use in testing each `\ell`. + - ``num_P`` -- integer or ``None`` (default); the number of primes + `P` of `K` to use in testing each `\ell` EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/gp_simon.py b/src/sage/schemes/elliptic_curves/gp_simon.py index 39a60361ec6..6be377e2f74 100644 --- a/src/sage/schemes/elliptic_curves/gp_simon.py +++ b/src/sage/schemes/elliptic_curves/gp_simon.py @@ -16,31 +16,20 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** +from pathlib import Path -from sage.structure.parent_gens import localvars +from cypari2.handle_error import PariError -from sage.interfaces.gp import Gp -from sage.misc.sage_eval import sage_eval +from sage.env import SAGE_EXTCODE +from sage.libs.pari import pari from sage.misc.randstate import current_randstate +from sage.misc.superseded import deprecation from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ +from sage.structure.parent_gens import localvars -gp = None -def init(): - """ - Function to initialize the gp process - """ - global gp - if gp is None: - import os - from sage.env import DOT_SAGE - logfile = os.path.join(DOT_SAGE, 'gp-simon.log') - gp = Gp(script_subdirectory='simon', logfile=logfile) - gp.read("ellQ.gp") - gp.read("ell.gp") - gp.read("qfsolve.gp") - gp.read("resultant3.gp") +simon_dir = Path(SAGE_EXTCODE) / 'pari' / 'simon' def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, @@ -57,6 +46,9 @@ def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, sage: import sage.schemes.elliptic_curves.gp_simon sage: E = EllipticCurve('389a1') sage: sage.schemes.elliptic_curves.gp_simon.simon_two_descent(E) + doctest:warning...: + DeprecationWarning: please use the 2-descent algorithm over QQ inside pari + See https://github.com/sagemath/sage/issues/38461 for details. (2, 2, [(5/4 : 5/8 : 1), (-3/4 : 7/8 : 1)]) TESTS:: @@ -92,37 +84,38 @@ def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, sage: E.simon_two_descent() # long time (0, 2, []) """ - init() + pari.read(simon_dir / "ellQ.gp") + pari.read(simon_dir / "ell.gp") + pari.read(simon_dir / "qfsolve.gp") + pari.read(simon_dir / "resultant3.gp") - current_randstate().set_seed_gp(gp) + current_randstate().set_seed_pari() K = E.base_ring() K_orig = K + E_orig = E + # The following is to correct the bug at #5204: the gp script # fails when K is a number field whose generator is called 'x'. # It also deals with relative number fields. - E_orig = E + if K is not QQ: K = K_orig.absolute_field('a') + y = K.gen() from_K, to_K = K.structure() E = E_orig.change_ring(to_K) - known_points = [P.change_ring(to_K) for P in known_points] - # Simon's program requires that this name be y. with localvars(K.polynomial().parent(), 'y'): - gp.eval("K = bnfinit(%s);" % K.polynomial()) - if verbose >= 2: - print("K = bnfinit(%s);" % K.polynomial()) - gp.eval("%s = Mod(y,K.pol);" % K.gen()) - if verbose >= 2: - print("%s = Mod(y,K.pol);" % K.gen()) + # Simon's program requires that this name be y. + K_pari = pari.bnfinit(K.polynomial()) + known_points = [P.change_ring(to_K) for P in known_points] else: + deprecation(38461, "please use the 2-descent algorithm over QQ inside pari") from_K = lambda x: x - to_K = lambda x: x - # The block below mimics the defaults in Simon's scripts, and needs to be changed - # when these are updated. + # The block below mimics the defaults in Simon's scripts. + # They need to be changed when these are updated. if K is QQ: - cmd = 'ellQ_ellrank(%s, %s);' % (list(E.ainvs()), [P.__pari__() for P in known_points]) + over_QQ = True if lim1 is None: lim1 = 5 if lim3 is None: @@ -130,7 +123,7 @@ def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, if limtriv is None: limtriv = 3 else: - cmd = 'bnfellrank(K, %s, %s);' % (list(E.ainvs()), [P.__pari__() for P in known_points]) + over_QQ = False if lim1 is None: lim1 = 2 if lim3 is None: @@ -138,29 +131,21 @@ def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, if limtriv is None: limtriv = 2 - gp('DEBUGLEVEL_ell=%s; LIM1=%s; LIM3=%s; LIMTRIV=%s; MAXPROB=%s; LIMBIGPRIME=%s;' % ( - verbose, lim1, lim3, limtriv, maxprob, limbigprime)) - - if verbose >= 2: - print(cmd) - s = gp.eval('ans=%s;' % cmd) - if s.find(" *** ") != -1: - raise RuntimeError("\n%s\nAn error occurred while running Simon's 2-descent program" % s) - if verbose > 0: - print(s) - v = gp.eval('ans') - if v == 'ans': # then the call to ellQ_ellrank() or bnfellrank() failed - raise RuntimeError("An error occurred while running Simon's 2-descent program") - if verbose >= 2: - print("v = %s" % v) - - # pari represents field elements as Mod(poly, defining-poly) - # so this function will return the respective elements of K - def _gp_mod(*args): - return args[0] - ans = sage_eval(v, {'Mod': _gp_mod, 'y': K.gen(0)}) - lower = ZZ(ans[0]) - upper = ZZ(ans[1]) - points = [E_orig([from_K(c) for c in list(P)]) for P in ans[2]] + pari('DEBUGLEVEL_ell=%s; LIM1=%s; LIM3=%s; LIMTRIV=%s; MAXPROB=%s; LIMBIGPRIME=%s;' % ( + verbose, lim1, lim3, limtriv, maxprob, limbigprime)) + + try: + if over_QQ: + ans = pari("ellQ_ellrank")(E, known_points) + else: + ans = pari("bnfellrank")(K_pari, E, known_points) + except PariError as err: + raise RuntimeError("an error occurred while running Simon's 2-descent program") from err + + loc = {} if over_QQ else {'y': y} + lower, upper, pts = ans.sage(locals=loc) + lower = ZZ(lower) + upper = ZZ(upper) + points = [E_orig([from_K(c) for c in P]) for P in pts] points = [P for P in points if P.has_infinite_order()] return lower, upper, points diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py old mode 100644 new mode 100755 index 1c4d0505af0..1bff085023c --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -98,15 +98,6 @@ from itertools import product import sage.rings.abc -import sage.rings.number_field.number_field_element -import sage.rings.number_field.number_field as number_field -from sage.rings.number_field.number_field import NumberField -from sage.rings.number_field.number_field import QuadraticField -from sage.rings.real_mpfr import RealField -from sage.rings.complex_mpfr import ComplexField -from sage.rings.real_mpfi import RealIntervalField -from sage.rings.infinity import Infinity as infinity -from sage.rings.fast_arith import prime_range from sage.arith.functions import lcm from sage.arith.misc import (binomial, factorial, prime_divisors, @@ -115,21 +106,28 @@ from sage.matrix.matrix_space import MatrixSpace from sage.misc.cachefunc import cached_method from sage.misc.misc_c import prod +from sage.misc.lazy_import import lazy_import from sage.misc.verbose import verbose from sage.modular.modsym.p1list import P1List -from sage.rings.complex_double import CDF +from sage.quadratic_forms.binary_qf import BinaryQF, BinaryQF_reduced_representatives from sage.rings.factorint import factor_trial_division +from sage.rings.fast_arith import prime_range from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers +from sage.rings.infinity import Infinity as infinity from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ -from sage.quadratic_forms.binary_qf import BinaryQF -from sage.quadratic_forms.binary_qf import BinaryQF_reduced_representatives from sage.rings.number_field.number_field_element_base import NumberFieldElement_base +from sage.rings.rational_field import QQ from sage.structure.sage_object import SageObject from sage.structure.richcmp import (richcmp_method, richcmp, richcmp_not_equal, rich_to_bool) +lazy_import('sage.rings.complex_double', 'CDF') +lazy_import('sage.rings.complex_mpfr', 'ComplexField') +lazy_import('sage.rings.number_field.number_field', ['NumberField', 'QuadraticField']) +lazy_import('sage.rings.real_mpfi', 'RealIntervalField') +lazy_import('sage.rings.real_mpfr', 'RealField') + ############################################################################### # # The exported functions, which are in most cases enough to get the @@ -140,6 +138,7 @@ # ############################################################################### + def heegner_points(N, D=None, c=None): """ Return all Heegner points of given level `N`. Can also restrict @@ -148,11 +147,11 @@ def heegner_points(N, D=None, c=None): INPUT: - - `N` -- level (positive integer) + - ``N`` -- level (positive integer) - - `D` -- discriminant (negative integer) + - ``D`` -- discriminant (negative integer) - - `c` -- conductor (positive integer) + - ``c`` -- conductor (positive integer) EXAMPLES:: @@ -181,11 +180,11 @@ def heegner_point(N, D=None, c=1): INPUT: - - `N` -- level (positive integer) + - ``N`` -- level (positive integer) - - `D` -- discriminant (optional: default first valid `D`) + - ``D`` -- discriminant (optional: default first valid `D`) - - `c` -- conductor (positive integer, default: 1) + - ``c`` -- conductor (positive integer, default: 1) EXAMPLES:: @@ -245,11 +244,11 @@ def __init__(self, D, c, check=True): """ INPUT: - - `D` -- discriminant of quadratic imaginary field + - ``D`` -- discriminant of quadratic imaginary field - - `c` -- conductor (positive integer coprime to `D`) + - ``c`` -- conductor (positive integer coprime to `D`) - - ``check`` -- bool (default: ``True``); whether to check + - ``check`` -- boolean (default: ``True``); whether to check validity of input EXAMPLES:: @@ -527,7 +526,7 @@ def quadratic_field(self): """ D = self.__D var = 'sqrt_minus_%s' % (-D) - return number_field.QuadraticField(D,var) + return QuadraticField(D,var) @cached_method def galois_group(self, base=QQ): @@ -566,7 +565,7 @@ def galois_group(self, base=QQ): def is_subfield(self, M): """ Return ``True`` if this ring class field is a subfield of the ring class field `M`. - If `M` is not a ring class field, then a :class:`TypeError` is raised. + If `M` is not a ring class field, then a :exc:`TypeError` is raised. EXAMPLES:: @@ -599,6 +598,7 @@ def is_subfield(self, M): # ################################################################################## + class GaloisGroup(SageObject): """ A Galois group of a ring class field. @@ -704,9 +704,9 @@ def __call__(self, x): INPUT: - - `x` -- automorphism or quadratic field element + - ``x`` -- automorphism or quadratic field element - OUTPUT: An automorphism (or ``TypeError``) + OUTPUT: an automorphism (or :exc:`TypeError`) EXAMPLES:: @@ -722,7 +722,7 @@ def __call__(self, x): sage: G(alpha) Class field automorphism defined by 14*x^2 - 10*x*y + 25*y^2 - A :class:`TypeError` is raised when the coercion is not possible:: + A :exc:`TypeError` is raised when the coercion is not possible:: sage: G(0) Traceback (most recent call last): @@ -815,9 +815,7 @@ def kolyvagin_generators(self): identity element of `\textrm{Gal}(K_p/K_1)` for all `p \neq p_i` and to a choice of generator of `\textrm{Gal}(K_{p_i}/K_1)`. - OUTPUT: - - - list of elements of ``self`` + OUTPUT: list of elements of ``self`` EXAMPLES:: @@ -855,9 +853,7 @@ def lift_of_hilbert_class_field_galois_group(self): this function returns noncanonical choices of lifts of the elements of the quotient group `\textrm{Gal}(K_1/K)`. - OUTPUT: - - - tuple of elements of self + OUTPUT: tuple of elements of ``self`` EXAMPLES:: @@ -965,11 +961,9 @@ def _quadratic_form_to_alpha(self, f): """ INPUT: - - `f` -- a binary quadratic form with discriminant `c^2 D` + - ``f`` -- a binary quadratic form with discriminant `c^2 D` - OUTPUT: - - - an element of the ring of integers of the quadratic imaginary field + OUTPUT: an element of the ring of integers of the quadratic imaginary field EXAMPLES:: @@ -1003,7 +997,7 @@ def _alpha_to_automorphism(self, alpha): INPUT: - - `\alpha` -- element of quadratic imaginary field coprime to conductor + - ``alpha`` -- element of quadratic imaginary field coprime to conductor EXAMPLES:: @@ -1034,11 +1028,10 @@ def _alpha_to_p1_element(self, alpha): INPUT: - - `\alpha` -- element of the ring of integers of the quadratic imaginary field - - OUTPUT: + - ``alpha`` -- element of the ring of integers of the quadratic + imaginary field - - 2-tuple of integers + OUTPUT: 2-tuple of integers EXAMPLES:: @@ -1081,9 +1074,7 @@ def _p1_element_to_alpha(self, uv): - ``uv`` -- pair of integers - OUTPUT: - - - element of maximal order of quadratic field + OUTPUT: element of maximal order of quadratic field EXAMPLES:: @@ -1455,9 +1446,9 @@ def __init__(self, parent, quadratic_form, alpha=None): - ``parent`` -- a group of automorphisms of a ring class field - ``quadratic_form`` -- a binary quadratic form that - defines an element of the Galois group of `K_c` over `K`. + defines an element of the Galois group of `K_c` over `K` - - ``\alpha`` -- (default: ``None``) optional data that specified + - ``alpha`` -- (default: ``None``) optional data that specified element corresponding element of `(\mathcal{O}_K / c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*`, via class field theory. @@ -1699,7 +1690,7 @@ def ideal(self): ## ## INPUT: ## -## - `z` -- a Heegner point on `X_0(N)` or an elliptic curve +## - ``z`` -- a Heegner point on `X_0(N)` or an elliptic curve ## ## OUTPUT: ## @@ -1755,11 +1746,11 @@ def __init__(self, N, D, c): """ INPUT: - - `N` -- (positive integer) the level + - ``N`` -- (positive integer) the level - - `D` -- (negative integer) fundamental discriminant + - ``D`` -- (negative integer) fundamental discriminant - - `c` -- (positive integer) conductor + - ``c`` -- (positive integer) conductor Since this is an abstract base class, no type or compatibility checks are done, as those are all assumed to be done in the @@ -1980,7 +1971,7 @@ def __init__(self, N): """ INPUT: - - `N` -- level, a positive integer + - ``N`` -- level, a positive integer EXAMPLES:: @@ -2084,9 +2075,9 @@ def discriminants(self, n=10, weak=False): INPUT: - - `n` -- nonnegative integer + - ``n`` -- nonnegative integer - - ``weak`` -- bool (default: ``False``); if ``True`` only require + - ``weak`` -- boolean (default: ``False``); if ``True`` only require weak Heegner hypothesis, which is the same as usual but without the condition that `\gcd(D,N)=1`. @@ -2122,6 +2113,7 @@ def discriminants(self, n=10, weak=False): v.append(D) return v + class HeegnerPoints_level_disc(HeegnerPoints): """ Set of Heegner points of given level and all conductors associated @@ -2150,9 +2142,9 @@ def __init__(self, N, D): """ INPUT: - - `N` -- positive integer + - ``N`` -- positive integer - - `D` -- negative fundamental discriminant + - ``D`` -- negative fundamental discriminant EXAMPLES:: @@ -2232,7 +2224,7 @@ def quadratic_field(self): """ D = self.__D var = 'sqrt_minus_%s' % (-D) - return number_field.QuadraticField(D,var) + return QuadraticField(D,var) def kolyvagin_conductors(self, r=None, n=10, E=None, m=None): r""" @@ -2249,13 +2241,13 @@ def kolyvagin_conductors(self, r=None, n=10, E=None, m=None): INPUT: - - `r` -- (default: ``None``) nonnegative integer or ``None`` + - ``r`` -- (default: ``None``) nonnegative integer or ``None`` - - `n` -- positive integer + - ``n`` -- positive integer - - `E` -- an elliptic curve + - ``E`` -- an elliptic curve - - `m` -- a positive integer + - ``m`` -- positive integer EXAMPLES:: @@ -2311,17 +2303,17 @@ def is_kolyvagin_conductor(N, E, D, r, n, c): INPUT: - - `N` -- level (positive integer) + - ``N`` -- level (positive integer) - - `E` -- elliptic curve or ``None`` + - ``E`` -- elliptic curve or ``None`` - - `D` -- negative fundamental discriminant + - ``D`` -- negative fundamental discriminant - - `r` -- number of prime factors (nonnegative integer) or ``None`` + - ``r`` -- number of prime factors (nonnegative integer) or ``None`` - - `n` -- torsion order (i.e., do we get class in `(E(K_c)/n E(K_c))^{Gal(K_c/K)}`?) + - ``n`` -- torsion order (i.e., do we get class in `(E(K_c)/n E(K_c))^{Gal(K_c/K)}`?) - - `c` -- conductor (positive integer) + - ``c`` -- conductor (positive integer) EXAMPLES:: @@ -2399,11 +2391,11 @@ def __init__(self, N, D, c=ZZ(1)): INPUT: - - `N` -- positive integer (the level) + - ``N`` -- positive integer (the level) - - `D` -- negative fundamental discriminant + - ``D`` -- negative fundamental discriminant - - `c` -- conductor (default: 1) + - ``c`` -- conductor (default: 1) EXAMPLES:: @@ -2647,7 +2639,7 @@ def points(self, beta=None): def plot(self, *args, **kwds): """ - Returns plot of all the representatives in the upper half + Return plot of all the representatives in the upper half plane of the Heegner points in this set of Heegner points. The inputs to this function get passed onto the point command. @@ -2697,18 +2689,18 @@ def __init__(self, N, D, c=ZZ(1), f=None, check=True): r""" INPUT: - - `N` -- positive integer + - ``N`` -- positive integer - - `D` -- fundamental discriminant, a negative integer + - ``D`` -- fundamental discriminant, a negative integer - - `c` -- conductor, a positive integer coprime to `N` + - ``c`` -- conductor, a positive integer coprime to `N` - - `f` -- binary quadratic form, 3-tuple `(A,B,C)` of coefficients + - ``f`` -- binary quadratic form, 3-tuple `(A,B,C)` of coefficients of `AX^2 + BXY + CY^2`, or element of quadratic imaginary - field `\QQ(\sqrt{D})` in the upper half plan. + field `\QQ(\sqrt{D})` in the upper half plane - - ``check`` -- bool, default: ``True``. should not be used - except internally. + - ``check`` -- boolean (default: ``True``); should not be used + except internally EXAMPLES:: @@ -2818,7 +2810,7 @@ def atkin_lehner_act(self, Q=None): INPUT: - - `Q` -- positive divisor of `N`; if not given, default to `N` + - ``Q`` -- positive divisor of `N`; if not given, default to `N` EXAMPLES:: @@ -3013,12 +3005,12 @@ def __init__(self, E, x, check=True): r""" INPUT: - - `E` -- an elliptic curve over the rational numbers + - ``E`` -- an elliptic curve over the rational numbers - - `x` -- Heegner point on `X_0(N)` + - ``x`` -- Heegner point on `X_0(N)` - - ``check`` -- bool (default: ``True``); if ``True``, ensure that `D`, - `c` are of type Integer and define a Heegner point on `E` + - ``check`` -- boolean (default: ``True``); if ``True``, ensure that `D`, + `c` are of type Integer and define a Heegner point on `E` EXAMPLES:: @@ -3046,7 +3038,7 @@ def satisfies_kolyvagin_hypothesis(self, n=None): INPUT: - - `n` -- positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -3234,9 +3226,7 @@ def _trace_index(self, *args, **kwds): the inputs to this function and more details about what is computed. In particular, the returned index can be off at 2. - OUTPUT: - - - ``Integer`` -- returns an integer + OUTPUT: ``Integer`` -- returns an integer EXAMPLES:: @@ -3392,13 +3382,13 @@ def x_poly_exact(self, prec=53, algorithm='lll'): """ Return irreducible polynomial over the rational numbers satisfied by the `x` coordinate of this Heegner point. A - ValueError is raised if the precision is clearly insignificant + :exc:`ValueError` is raised if the precision is clearly insignificant to define a point on the curve. .. WARNING:: It is in theory possible for this function to not raise a - ValueError, find a polynomial, but via some very unlikely + :exc:`ValueError`, find a polynomial, but via some very unlikely coincidence that point is not actually this Heegner point. INPUT: @@ -3464,7 +3454,6 @@ def x_poly_exact(self, prec=53, algorithm='lll'): (a : -4*a + 3 : 1) sage: all(c.parent().disc() == -7 for c in PE) True - """ L = self.ring_class_field() n = L.absolute_degree() @@ -3488,7 +3477,7 @@ def _check_poly_discriminant(self, f): INPUT: - - `f` -- a polynomial + - ``f`` -- a polynomial EXAMPLES:: @@ -3518,15 +3507,14 @@ def point_exact(self, prec=53, algorithm='lll', var='a', optimize=False): """ Return exact point on the elliptic curve over a number field defined by computing this Heegner point to the given number of - bits of precision. A ValueError is raised if the precision + bits of precision. A :exc:`ValueError` is raised if the precision is clearly insignificant to define a point on the curve. .. WARNING:: It is in theory possible for this function to not raise a - ValueError, find a point on the curve, but via some very - unlikely coincidence that point is not actually this Heegner - point. + :exc:`ValueError`, find a point on the curve, but via some very + unlikely coincidence that point is not actually this Heegner point. .. WARNING:: @@ -3538,11 +3526,11 @@ def point_exact(self, prec=53, algorithm='lll', var='a', optimize=False): - ``prec`` -- integer (default: 53) - ``algorithm`` -- see the description of the algorithm - parameter for the ``x_poly_exact`` method. + parameter for the ``x_poly_exact`` method - - ``var`` -- string (default: 'a') + - ``var`` -- string (default: ``'a'``) - - ``optimize`` -- bool (default; False) if ``True``, try to + - ``optimize`` -- boolean (default: ``False``); if ``True``, try to optimize defining polynomial for the number field that the point is defined over. Off by default, since this can be very expensive. @@ -3686,9 +3674,7 @@ def _numerical_approx_xy_poly(self, prec=53): - ``prec`` -- positive integer (default: 53) - OUTPUT: - - - 2-tuple of polynomials with floating point coefficients + OUTPUT: 2-tuple of polynomials with floating point coefficients EXAMPLES:: @@ -3721,9 +3707,7 @@ def _xy_poly_nearby(self, prec=53, max_error=10**(-10)): - ``max_error`` -- very small floating point number - OUTPUT: - - - 2-tuple of polynomials with rational coefficients + OUTPUT: 2-tuple of polynomials with rational coefficients EXAMPLES:: @@ -3789,7 +3773,7 @@ def _trace_numerical_conductor_1(self, prec=53): INPUT: - - `prec` -- bits precision (default: 53) + - ``prec`` -- bits precision (default: 53) EXAMPLES:: @@ -3903,7 +3887,7 @@ def _qf_to_tau(self, f): INPUT: - - `f` -- binary quadratic form + - ``f`` -- binary quadratic form EXAMPLES:: @@ -3956,13 +3940,11 @@ def _qf_atkin_lehner_act(self, Q, f): INPUT: - - `Q` -- integer that divides the level `N` - - - `f` -- quadratic form + - ``Q`` -- integer that divides the level `N` - OUTPUT: + - ``f`` -- quadratic form - - quadratic form + OUTPUT: quadratic form EXAMPLES:: @@ -4009,7 +3991,7 @@ def kolyvagin_cohomology_class(self, n=None): INPUT: - - `n` -- positive integer that divides the gcd of `a_p` + - ``n`` -- positive integer that divides the gcd of `a_p` and `p+1` for all `p` dividing the conductor. If `n` is ``None``, choose the largest valid `n`. @@ -4024,6 +4006,8 @@ def kolyvagin_cohomology_class(self, n=None): ######################################################################################### # Kolyvagin Points P_c ######################################################################################### + + class KolyvaginPoint(HeegnerPoint): """ A Kolyvagin point. @@ -4341,7 +4325,7 @@ def _trace_exact_conductor_1(self, prec=53): the case of conductor 1, computed using prec bits of precision, then approximated using some algorithm (e.g., continued fractions). If the precision is not enough to - determine a point on the curve, then a :class:`RuntimeError` is raised. + determine a point on the curve, then a :exc:`RuntimeError` is raised. Even if the precision determines a point, there is no guarantee that it is correct. @@ -4369,9 +4353,9 @@ def _recognize_point_over_QQ(self, P, n): INPUT: - - `P` -- numerical approximation for a point on `E` + - ``P`` -- numerical approximation for a point on `E` - - `n` -- upper bound on divisibility index of `P` in group `E(\QQ)` + - ``n`` -- upper bound on divisibility index of `P` in group `E(\QQ)` EXAMPLES:: @@ -4473,7 +4457,7 @@ def mod(self, p, prec=53): ## ## INPUT: ## -## - `n` -- positive integer +## - ``n`` -- positive integer ## ## - ``prec`` -- positive integer (default: 53) ## @@ -4487,7 +4471,7 @@ def kolyvagin_cohomology_class(self, n=None): """ INPUT: - - `n` -- positive integer that divides the gcd of `a_p` + - ``n`` -- positive integer that divides the gcd of `a_p` and `p+1` for all `p` dividing the conductor. If `n` is ``None``, choose the largest valid `n`. @@ -4633,12 +4617,8 @@ def heegner_point(self): """ return self.__kolyvagin_point.heegner_point() -class KolyvaginCohomologyClassEn(KolyvaginCohomologyClass): - """ - EXAMPLES: - - """ +class KolyvaginCohomologyClassEn(KolyvaginCohomologyClass): def _repr_(self): """ @@ -4771,11 +4751,11 @@ def satisfies_heegner_hypothesis(self, D, c=ZZ(1)): INPUT: - - `D` -- negative integer + - ``D`` -- negative integer - - `c` -- positive integer (default: 1) + - ``c`` -- positive integer (default: 1) - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -4808,9 +4788,9 @@ def heegner_discriminants(self, n=5): INPUT: - - `n` -- positive integer (default: 5) + - ``n`` -- positive integer (default: 5) - OUTPUT: A list. + OUTPUT: list EXAMPLES:: @@ -4837,11 +4817,11 @@ def heegner_conductors(self, D, n=5): INPUT: - - `D` -- negative integer; a fundamental Heegner discriminant + - ``D`` -- negative integer; a fundamental Heegner discriminant - - `n` -- positive integer (default: 5) + - ``n`` -- positive integer (default: 5) - OUTPUT: A list. + OUTPUT: list EXAMPLES:: @@ -4863,11 +4843,11 @@ def optimal_embeddings(self, D, c, R): """ INPUT: - - `D` -- negative fundamental discriminant + - ``D`` -- negative fundamental discriminant - - `c` -- integer coprime + - ``c`` -- integer coprime - - `R` -- Eichler order + - ``R`` -- Eichler order EXAMPLES:: @@ -4914,7 +4894,7 @@ def brandt_module(self): @cached_method def quaternion_algebra(self): """ - Return the rational quaternion algebra used to implement self. + Return the rational quaternion algebra used to implement ``self``. EXAMPLES:: @@ -4930,8 +4910,8 @@ def right_ideals(self): EXAMPLES:: sage: heegner_points(11).reduce_mod(3).right_ideals() - (Fractional ideal (2 + 2*j + 28*k, 2*i + 26*k, 4*j + 12*k, 44*k), - Fractional ideal (2 + 2*j + 28*k, 2*i + 4*j + 38*k, 8*j + 24*k, 88*k)) + (Fractional ideal (4, 44*i, 2 + 8*i + 2*j, 34*i + 2*k), + Fractional ideal (8, 88*i, 2 + 52*i + 2*j, 4 + 78*i + 2*k)) """ return self.brandt_module().right_ideals() @@ -4965,11 +4945,11 @@ def heegner_divisor(self, D, c=ZZ(1)): INPUT: - - `D` -- discriminant (negative integer) + - ``D`` -- discriminant (negative integer) - - `c` -- conductor (positive integer) + - ``c`` -- conductor (positive integer) - OUTPUT: A Brandt module element. + OUTPUT: a Brandt module element EXAMPLES:: @@ -5029,9 +5009,9 @@ def modp_splitting_data(self, p): INPUT: - - `p` -- unramified odd prime + - ``p`` -- unramified odd prime - OUTPUT: A 2-tuple of matrices over finite field. + OUTPUT: a 2-tuple of matrices over finite field EXAMPLES:: @@ -5114,7 +5094,7 @@ def modp_splitting_map(self, p): INPUT: - - `p` -- prime number + - ``p`` -- prime number EXAMPLES:: @@ -5147,9 +5127,9 @@ def cyclic_subideal_p1(self, I, c): INPUT: - - `I` -- right ideal of Eichler order or in quaternion algebra + - ``I`` -- right ideal of Eichler order or in quaternion algebra - - `c` -- square free integer (currently must be odd prime + - ``c`` -- square free integer (currently must be odd prime and coprime to level, discriminant, characteristic, etc. OUTPUT: @@ -5161,14 +5141,10 @@ def cyclic_subideal_p1(self, I, c): sage: H = heegner_points(11).reduce_mod(7) sage: I = H.brandt_module().right_ideals()[0] sage: sorted(H.cyclic_subideal_p1(I, 3).items()) - [((0, 1), - Fractional ideal (2 + 2*j + 32*k, 2*i + 8*j + 82*k, 12*j + 60*k, 132*k)), - ((1, 0), - Fractional ideal (2 + 10*j + 28*k, 2*i + 4*j + 62*k, 12*j + 60*k, 132*k)), - ((1, 1), - Fractional ideal (2 + 2*j + 76*k, 2*i + 4*j + 106*k, 12*j + 60*k, 132*k)), - ((1, 2), - Fractional ideal (2 + 10*j + 116*k, 2*i + 8*j + 38*k, 12*j + 60*k, 132*k))] + [((0, 1), Fractional ideal (12, 132*i, 10 + 76*i + 2*j, 4 + 86*i + 2*k)), + ((1, 0), Fractional ideal (12, 132*i, 2 + 32*i + 2*j, 8 + 130*i + 2*k)), + ((1, 1), Fractional ideal (12, 132*i, 10 + 32*i + 2*j, 8 + 86*i + 2*k)), + ((1, 2), Fractional ideal (12, 132*i, 2 + 76*i + 2*j, 4 + 130*i + 2*k))] sage: len(H.cyclic_subideal_p1(I, 17)) 18 """ @@ -5203,9 +5179,9 @@ def galois_group_over_hilbert_class_field(self, D, c): INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `c` -- conductor (square-free integer) + - ``c`` -- conductor (square-free integer) EXAMPLES:: @@ -5227,9 +5203,9 @@ def galois_group_over_quadratic_field(self, D, c): INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `c` -- conductor (square-free integer) + - ``c`` -- conductor (square-free integer) EXAMPLES:: @@ -5251,9 +5227,9 @@ def quadratic_field(self, D): INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - OUTPUT: A quadratic number field. + OUTPUT: a quadratic number field EXAMPLES:: @@ -5274,14 +5250,14 @@ def kolyvagin_cyclic_subideals(self, I, p, alpha_quaternion): INPUT: - - `I` -- right ideal of the quaternion algebra + - ``I`` -- right ideal of the quaternion algebra - - `p` -- prime number + - ``p`` -- prime number - ``alpha_quaternion`` -- image in the quaternion algebra - of generator `\alpha` for `(\mathcal{O}_K / c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*`. + of generator `\alpha` for `(\mathcal{O}_K / c\mathcal{O}_K)^* / (\ZZ/c\ZZ)^*` - OUTPUT: A list of 2-tuples. + OUTPUT: list of 2-tuples EXAMPLES:: @@ -5293,24 +5269,12 @@ def kolyvagin_cyclic_subideals(self, I, p, alpha_quaternion): sage: alpha_quaternion = f(g[0]); alpha_quaternion 1 - 77/192*i - 5/128*j - 137/384*k sage: H.kolyvagin_cyclic_subideals(I, 5, alpha_quaternion) - [(Fractional ideal (2 + 2/3*i + 364*j + 231928/3*k, - 4/3*i + 946*j + 69338/3*k, - 1280*j + 49920*k, 94720*k), 0), - (Fractional ideal (2 + 2/3*i + 108*j + 31480/3*k, - 4/3*i + 434*j + 123098/3*k, - 1280*j + 49920*k, 94720*k), 1), - (Fractional ideal (2 + 2/3*i + 876*j + 7672/3*k, - 4/3*i + 434*j + 236762/3*k, - 1280*j + 49920*k, 94720*k), 2), - (Fractional ideal (2 + 2/3*i + 364*j + 61432/3*k, - 4/3*i + 178*j + 206810/3*k, - 1280*j + 49920*k, 94720*k), 3), - (Fractional ideal (2 + 2/3*i + 876*j + 178168/3*k, - 4/3*i + 1202*j + 99290/3*k, - 1280*j + 49920*k, 94720*k), 4), - (Fractional ideal (2 + 2/3*i + 1132*j + 208120/3*k, - 4/3*i + 946*j + 183002/3*k, - 1280*j + 49920*k, 94720*k), 5)] + [(Fractional ideal (2560, 1280 + 47360*i, 1146 + 37678*i + 4*j, 212 + 54664/3*i + 2*j + 2/3*k), 0), + (Fractional ideal (2560, 1280 + 47360*i, 2426 + 9262*i + 4*j, 2004 + 83080/3*i + 2*j + 2/3*k), 1), + (Fractional ideal (2560, 1280 + 47360*i, 1914 + 9262*i + 4*j, 1748 + 111496/3*i + 2*j + 2/3*k), 2), + (Fractional ideal (2560, 1280 + 47360*i, 2170 + 18734*i + 4*j, 212 + 111496/3*i + 2*j + 2/3*k), 3), + (Fractional ideal (2560, 1280 + 47360*i, 890 + 28206*i + 4*j, 1748 + 54664/3*i + 2*j + 2/3*k), 4), + (Fractional ideal (2560, 1280 + 47360*i, 634 + 37678*i + 4*j, 2516 + 83080/3*i + 2*j + 2/3*k), 5)] """ X = I.cyclic_right_subideals(p, alpha_quaternion) return [(J, i) for i, J in enumerate(X)] @@ -5327,9 +5291,9 @@ def kolyvagin_generator(self, K, p): INPUT: - - `K` -- quadratic imaginary field + - ``K`` -- quadratic imaginary field - - `p` -- inert prime + - ``p`` -- inert prime EXAMPLES:: @@ -5378,9 +5342,9 @@ def kolyvagin_generators(self, K, c): INPUT: - - `K` -- quadratic imaginary field + - ``K`` -- quadratic imaginary field - - `c` -- square free product of inert prime + - ``c`` -- square free product of inert prime EXAMPLES:: @@ -5419,11 +5383,11 @@ def kolyvagin_sigma_operator(self, D, c, r, bound=None): INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `c` -- conductor (square-free integer, need not be prime) + - ``c`` -- conductor (square-free integer, need not be prime) - - `r` -- nonnegative integer + - ``r`` -- nonnegative integer - ``bound`` -- (default: ``None``), if given, controls precision of computation of theta series, which could @@ -5544,9 +5508,9 @@ def modp_dual_elliptic_curve_factor(self, E, p, bound=10): INPUT: - - `E` -- elliptic curve of conductor equal to the level of ``self`` + - ``E`` -- elliptic curve of conductor equal to the level of ``self`` - - `p` -- prime number + - ``p`` -- prime number - ``bound`` -- positive integer (default: 10) @@ -5591,11 +5555,11 @@ def rational_kolyvagin_divisor(self, D, c): INPUT: - - `D` -- discriminant (negative integer) + - ``D`` -- discriminant (negative integer) - - `c` -- conductor (positive integer) + - ``c`` -- conductor (positive integer) - OUTPUT: Brandt module element (or tuple of them). + OUTPUT: Brandt module element (or tuple of them) EXAMPLES:: @@ -5634,13 +5598,13 @@ def kolyvagin_point_on_curve(self, D, c, E, p, bound=10): INPUT: - - `D` -- fundamental negative discriminant + - ``D`` -- fundamental negative discriminant - - `c` -- conductor + - ``c`` -- conductor - - `E` -- elliptic curve of conductor the level of self + - ``E`` -- elliptic curve of conductor the level of self - - `p` -- odd prime number such that we consider image in + - ``p`` -- odd prime number such that we consider image in `E(\GF{\ell^2}) / p E(\GF{\ell^2})` - ``bound`` -- integer (default: 10) @@ -5656,6 +5620,7 @@ def kolyvagin_point_on_curve(self, D, c, E, p, bound=10): V = self.modp_dual_elliptic_curve_factor(E, p, bound) return [b.dot_product(k.element().change_ring(GF(p))) for b in V.basis()] + def kolyvagin_reduction_data(E, q, first_only=True): r""" Given an elliptic curve of positive rank and a prime `q`, this @@ -5665,28 +5630,26 @@ def kolyvagin_reduction_data(E, q, first_only=True): INPUT: - - `E` -- elliptic curve over `\QQ` of rank 1 or 2 + - ``E`` -- elliptic curve over `\QQ` of rank 1 or 2 - - `q` -- an odd prime that does not divide the order of the - rational torsion subgroup of `E` + - ``q`` -- an odd prime that does not divide the order of the + rational torsion subgroup of `E` - - ``first_only`` -- bool (default: ``True``) whether two only return - the first prime that one can work modulo to get data about - the Euler system + - ``first_only`` -- boolean (default: ``True``); whether two only return + the first prime that one can work modulo to get data about the Euler system OUTPUT in the rank 1 case or when the default flag ``first_only=True``: - - `\ell` -- first good odd prime satisfying the Kolyvagin - condition that `q` divides \gcd(a_{\ell},\ell+1)` and the - reduction map is surjective to `E(\GF{\ell}) / q - E(\GF{\ell})` + - `\ell` -- first good odd prime satisfying the Kolyvagin condition that + `q` divides \gcd(a_{\ell},\ell+1)` and the reduction map is surjective to + `E(\GF{\ell}) / q E(\GF{\ell})` - - `D` -- discriminant of the first quadratic imaginary field + - ``D`` -- discriminant of the first quadratic imaginary field `K` that satisfies the Heegner hypothesis for `E` such that both `\ell` is inert in `K`, and the twist `E^D` has analytic rank `\leq 1` - - `h_D` -- the class number of `K` + - ``h_D`` -- the class number of `K` - the dimension of the Brandt module `B(\ell,N)`, where `N` is the conductor of `E` @@ -5699,12 +5662,12 @@ def kolyvagin_reduction_data(E, q, first_only=True): - `\ell_2` -- second prime (as above) where reduction map is surjective - - `D` -- discriminant of the first quadratic imaginary field + - ``D`` -- discriminant of the first quadratic imaginary field `K` that satisfies the Heegner hypothesis for `E` such that both `\ell_1` and `\ell_2` are simultaneously inert in `K`, and the twist `E^D` has analytic rank `\leq 1` - - `h_D` -- the class number of `K` + - ``h_D`` -- the class number of `K` - the dimension of the Brandt module `B(\ell_1,N)`, where `N` is the conductor of `E` @@ -5864,6 +5827,7 @@ def kernel_of_reduction(ell): BrandtModule(ell_1,N).dimension(), BrandtModule(ell_2,N).dimension()) + class HeegnerQuatAlgEmbedding(SageObject): r""" The homomorphism `\mathcal{O} \to R`, where `\mathcal{O}` is the @@ -5884,13 +5848,13 @@ def __init__(self, D, c, R, beta): r""" INPUT: - - `D` -- negative fundamental discriminant + - ``D`` -- negative fundamental discriminant - - `c` -- positive integer coprime to `D` + - ``c`` -- positive integer coprime to `D` - - `R` -- Eichler order in a rational quaternion algebra + - ``R`` -- Eichler order in a rational quaternion algebra - - `\beta` -- element of `R` such that the homomorphism + - ``beta`` -- element of `R` such that the homomorphism sends `c\sqrt{D}` to `\beta` EXAMPLES:: @@ -5946,7 +5910,7 @@ def __call__(self, x): INPUT: - - `x` -- element of the quadratic order + - ``x`` -- element of the quadratic order EXAMPLES:: @@ -6116,11 +6080,11 @@ def quadratic_order(D, c, names='a'): INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `c` -- conductor + - ``c`` -- conductor - - ``names`` -- string (default: 'a') + - ``names`` -- string (default: ``'a'``) OUTPUT: @@ -6147,6 +6111,7 @@ def quadratic_order(D, c, names='a'): R = K.order([t]) return R, R(t) + def class_number(D): """ Return the class number of the quadratic field with fundamental @@ -6154,7 +6119,7 @@ def class_number(D): INPUT: - - `D` -- integer + - ``D`` -- integer EXAMPLES:: @@ -6165,7 +6130,7 @@ def class_number(D): sage: sage.schemes.elliptic_curves.heegner.class_number(-163) 1 - A :class:`ValueError` is raised when `D` is not a fundamental + A :exc:`ValueError` is raised when `D` is not a fundamental discriminant:: sage: sage.schemes.elliptic_curves.heegner.class_number(-5) @@ -6177,15 +6142,16 @@ def class_number(D): raise ValueError("D (=%s) must be a fundamental discriminant" % D) return D.class_number() + def is_inert(D, p): r""" Return ``True`` if p is an inert prime in the field `\QQ(\sqrt{D})`. INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `p` -- prime integer + - ``p`` -- prime integer EXAMPLES:: @@ -6200,15 +6166,16 @@ def is_inert(D, p): F = K.factor(p) return len(F) == 1 and F[0][1] == 1 + def is_split(D, p): r""" Return ``True`` if p is a split prime in the field `\QQ(\sqrt{D})`. INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `p` -- prime integer + - ``p`` -- prime integer EXAMPLES:: @@ -6223,15 +6190,16 @@ def is_split(D, p): F = K.factor(p) return len(F) == 2 + def is_ramified(D, p): r""" Return ``True`` if p is a ramified prime in the field `\QQ(\sqrt{D})`. INPUT: - - `D` -- fundamental discriminant + - ``D`` -- fundamental discriminant - - `p` -- prime integer + - ``p`` -- prime integer EXAMPLES:: @@ -6244,6 +6212,7 @@ def is_ramified(D, p): """ return QuadraticField(D,'a').discriminant() % p == 0 + def nearby_rational_poly(f, **kwds): r""" Return a polynomial whose coefficients are rational numbers close @@ -6251,7 +6220,7 @@ def nearby_rational_poly(f, **kwds): INPUT: - - `f` -- polynomial with real floating point entries + - ``f`` -- polynomial with real floating point entries - ``**kwds`` -- passed on to ``nearby_rational`` method @@ -6269,6 +6238,7 @@ def nearby_rational_poly(f, **kwds): R = QQ['X'] return R([a.nearby_rational(**kwds) for a in f]) + def simplest_rational_poly(f, prec): """ Return a polynomial whose coefficients are as simple as possible @@ -6276,7 +6246,7 @@ def simplest_rational_poly(f, prec): INPUT: - - `f` -- polynomial with real floating point entries + - ``f`` -- polynomial with real floating point entries - ``prec`` -- positive integer @@ -6291,6 +6261,7 @@ def simplest_rational_poly(f, prec): Z = RealField(prec) return R([Z(a).simplest_rational() for a in f]) + def satisfies_weak_heegner_hypothesis(N, D): r""" Check that `D` satisfies the weak Heegner hypothesis relative to `N`. @@ -6303,9 +6274,9 @@ def satisfies_weak_heegner_hypothesis(N, D): INPUT: - - `N` -- positive integer + - ``N`` -- positive integer - - `D` -- negative integer + - ``D`` -- negative integer EXAMPLES:: @@ -6346,9 +6317,9 @@ def make_monic(f): INPUT: - - `f` -- polynomial over the rational numbers + - ``f`` -- polynomial over the rational numbers - OUTPUT: A monic integral polynomial and an integer. + OUTPUT: a monic integral polynomial and an integer EXAMPLES:: @@ -6403,7 +6374,7 @@ def make_monic(f): def ell_heegner_point(self, D, c=ZZ(1), f=None, check=True): r""" - Returns the Heegner point on this curve associated to the + Return the Heegner point on this curve associated to the quadratic imaginary field `K=\QQ(\sqrt{D})`. If the optional parameter `c` is given, returns the higher Heegner @@ -6411,16 +6382,16 @@ def ell_heegner_point(self, D, c=ZZ(1), f=None, check=True): INPUT: - - `D` -- a Heegner discriminant + - ``D`` -- a Heegner discriminant - - `c` -- (default: 1) conductor, must be coprime to `DN` + - ``c`` -- (default: 1) conductor, must be coprime to `DN` - - `f` -- binary quadratic form or 3-tuple `(A,B,C)` of coefficients + - ``f`` -- binary quadratic form or 3-tuple `(A,B,C)` of coefficients of `AX^2 + BXY + CY^2` - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - OUTPUT: The Heegner point `y_c`. + OUTPUT: the Heegner point `y_c` EXAMPLES:: @@ -6466,6 +6437,7 @@ def ell_heegner_point(self, D, c=ZZ(1), f=None, check=True): y = HeegnerPointOnX0N(self.conductor(), D, c, f, check=check) return y.map_to_curve(self) + def kolyvagin_point(self, D, c=ZZ(1), check=True): r""" Return the Kolyvagin point on this curve associated to the @@ -6473,13 +6445,13 @@ def kolyvagin_point(self, D, c=ZZ(1), check=True): INPUT: - - `D` -- a Heegner discriminant + - ``D`` -- a Heegner discriminant - - `c` -- (default: 1) conductor, must be coprime to `DN` + - ``c`` -- (default: 1) conductor, must be coprime to `DN` - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - OUTPUT: The Kolyvagin point `P` of conductor `c`. + OUTPUT: the Kolyvagin point `P` of conductor `c` EXAMPLES:: @@ -6498,17 +6470,18 @@ def kolyvagin_point(self, D, c=ZZ(1), check=True): """ return self.heegner_point(D,c,check=check).kolyvagin_point() + def ell_heegner_discriminants(self, bound): """ - Return the list of self's Heegner discriminants between -1 and + Return the list of ``self``'s Heegner discriminants between -1 and -bound. INPUT: - - ``bound (int)`` -- upper bound for -discriminant + - ``bound`` -- integer; upper bound for -discriminant - OUTPUT: The list of Heegner discriminants between -1 and -bound for - the given elliptic curve. + OUTPUT: the list of Heegner discriminants between -1 and -bound for + the given elliptic curve EXAMPLES:: @@ -6522,15 +6495,15 @@ def ell_heegner_discriminants(self, bound): def ell_heegner_discriminants_list(self, n): """ - Return the list of self's first `n` Heegner discriminants smaller + Return the list of ``self``'s first `n` Heegner discriminants smaller than -5. INPUT: - - ``n (int)`` -- the number of discriminants to compute + - ``n`` -- integer; the number of discriminants to compute - OUTPUT: The list of the first n Heegner discriminants smaller than - -5 for the given elliptic curve. + OUTPUT: the list of the first `n` Heegner discriminants smaller than + `-5` for the given elliptic curve EXAMPLES:: @@ -6547,6 +6520,7 @@ def ell_heegner_discriminants_list(self, n): D -= 1 return v + def heegner_point_height(self, D, prec=2, check_rank=True): r""" Use the Gross-Zagier formula to compute the Neron-Tate canonical @@ -6558,16 +6532,16 @@ def heegner_point_height(self, D, prec=2, check_rank=True): INPUT: - - ``D (int)`` -- fundamental discriminant (=/= -3, -4) + - ``D`` -- integer; fundamental discriminant (=/= -3, -4) - - ``prec (int)`` -- (default: 2), use `prec \cdot \sqrt(N) + 20` + - ``prec`` -- integer (default: 2); use `prec \cdot \sqrt(N) + 20` terms of `L`-series in computations, where `N` is the - conductor. + conductor - ``check_rank`` -- whether to check if the rank is at least 2 by - computing the Mordell-Weil rank directly. + computing the Mordell-Weil rank directly - OUTPUT: Interval that contains the height of the Heegner point. + OUTPUT: interval that contains the height of the Heegner point EXAMPLES:: @@ -6654,22 +6628,22 @@ def heegner_index(self, D, min_p=2, prec=5, descent_second_limit=12, INPUT: - - ``D (int)`` -- Heegner discriminant + - ``D`` -- integer; Heegner discriminant - - ``min_p (int)`` -- (default: 2) only rule out primes - = min_p dividing the index. + - ``min_p`` -- integer (default: 2); only rule out primes + = min_p dividing the index - - ``verbose_mwrank (bool)`` -- (default: ``False``); print lots of + - ``verbose_mwrank`` -- boolean (default: ``False``); print lots of mwrank search status information when computing regulator - - ``prec (int)`` -- (default: 5), use prec\*sqrt(N) + - 20 terms of L-series in computations, where N is the conductor. + - ``prec`` -- integer (default: 5);, use prec\*sqrt(N) + + 20 terms of `L`-series in computations, where N is the conductor - ``descent_second_limit`` -- (default: 12)- used in 2-descent when computing regulator of the twist - ``check_rank`` -- whether to check if the rank is at least 2 by - computing the Mordell-Weil rank directly. + computing the Mordell-Weil rank directly OUTPUT: an interval that contains the index, or half the index @@ -6864,14 +6838,14 @@ def heegner_index_bound(self, D=0, prec=5, max_height=None): INPUT: - - ``D (int)`` -- (default: 0) Heegner discriminant; if + - ``D`` -- integer (default: 0); Heegner discriminant; if 0, use the first discriminant -4 that satisfies the Heegner hypothesis - - ``verbose (bool)`` -- (default: ``True``) + - ``verbose`` -- boolean (default: ``True``) - - ``prec (int)`` -- (default: 5), use `prec \cdot \sqrt(N) + 20` - terms of `L`-series in computations, where `N` is the conductor. + - ``prec`` -- integer (default: 5); use `prec \cdot \sqrt(N) + 20` + terms of `L`-series in computations, where `N` is the conductor - ``max_height (float)`` -- should be = 21; bound on logarithmic naive height used in point searches. Make smaller to @@ -6883,7 +6857,7 @@ def heegner_index_bound(self, D=0, prec=5, max_height=None): - ``v`` -- list or int (bad primes or 0 or -1) - ``D`` -- the discriminant that was used (this is - useful if `D` was automatically selected). + useful if `D` was automatically selected) - ``exact`` -- either False, or the exact Heegner index (up to factors of 2) @@ -6985,9 +6959,9 @@ def _heegner_index_in_EK(self, D): INPUT: - - `D` -- negative integer; the Heegner discriminant + - ``D`` -- negative integer; the Heegner discriminant - OUTPUT: A power of 2 -- the given index. + OUTPUT: a power of 2 -- the given index EXAMPLES: @@ -7078,15 +7052,16 @@ def _heegner_index_in_EK(self, D): self.__heegner_index_in_EK[D] = index return index + def heegner_sha_an(self, D, prec=53): r""" Return the conjectural (analytic) order of Sha for E over the field `K=\QQ(\sqrt{D})`. INPUT: - - `D` -- negative integer; the Heegner discriminant + - ``D`` -- negative integer; the Heegner discriminant - - prec -- integer (default: 53); bits of precision to + - ``prec`` -- integer (default: 53); bits of precision to compute analytic order of Sha OUTPUT: @@ -7236,7 +7211,7 @@ def heegner_sha_an(self, D, prec=53): def _heegner_forms_list(self, D, beta=None, expected_count=None): r""" - Returns a list of quadratic forms corresponding to Heegner points + Return a list of quadratic forms corresponding to Heegner points with discriminant `D` and a choice of `\beta` a square root of `D` mod `4N`. Specifically, given a quadratic form `f = Ax^2 + Bxy + Cy^2` we let `\tau_f` be a root of `Ax^2 + Bx + C` @@ -7289,6 +7264,7 @@ def _heegner_forms_list(self, D, beta=None, expected_count=None): return all b += 2*N + def _heegner_best_tau(self, D, prec=None): r""" Given a discriminant `D`, find the Heegner point `\tau` in the @@ -7313,9 +7289,10 @@ def _heegner_best_tau(self, D, prec=None): # TODO: make sure a different choice of b is not better? return (-b + ZZ(D).sqrt(prec=prec)) / (2*N) + def satisfies_heegner_hypothesis(self, D): """ - Returns ``True`` precisely when `D` is a fundamental discriminant that + Return ``True`` precisely when `D` is a fundamental discriminant that satisfies the Heegner hypothesis for this elliptic curve. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/height.py b/src/sage/schemes/elliptic_curves/height.py old mode 100644 new mode 100755 index c382ad1eefe..53f440f5db4 --- a/src/sage/schemes/elliptic_curves/height.py +++ b/src/sage/schemes/elliptic_curves/height.py @@ -29,24 +29,26 @@ import numpy import math import bisect + from itertools import product -from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ -from sage.rings.infinity import infinity -from sage.rings.cif import CIF +from sage.arith.functions import lcm +from sage.arith.misc import factorial +from sage.ext.fast_callable import fast_callable +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.rings.cc import CC from sage.rings.complex_double import CDF +from sage.rings.infinity import infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ from sage.rings.real_double import RDF -from sage.rings.real_mpfi import RIF from sage.rings.real_mpfr import RR -from sage.misc.cachefunc import cached_method -from sage.arith.functions import lcm -from sage.arith.misc import factorial -from sage.ext.fast_callable import fast_callable -from sage.functions.log import log, exp -from sage.symbolic.ring import SR +lazy_import("sage.functions.log", ["log", "exp"]) +lazy_import("sage.rings.cif", "CIF") +lazy_import("sage.rings.real_mpfi", "RIF") +lazy_import("sage.symbolic.ring", "SR") class UnionOfIntervals: @@ -107,7 +109,7 @@ def __init__(self, endpoints): def finite_endpoints(self): r""" - Returns the finite endpoints of this union of intervals. + Return the finite endpoints of this union of intervals. EXAMPLES:: @@ -121,7 +123,7 @@ def finite_endpoints(self): def intervals(self): r""" - Returns the intervals in self, as a list of 2-tuples. + Return the intervals in self, as a list of 2-tuples. EXAMPLES:: @@ -135,7 +137,7 @@ def intervals(self): def is_empty(self): r""" - Returns whether self is empty. + Return whether ``self`` is empty. EXAMPLES:: @@ -230,7 +232,7 @@ def __radd__(self, other): def __invert__(self): r""" - Return the closure of the complement of self. + Return the closure of the complement of ``self``. .. NOTE:: @@ -266,10 +268,10 @@ def join(L, condition): INPUT: - - ``L`` (list) -- a list of UnionOfIntervals instances + - ``L`` -- list of UnionOfIntervals instances - - ``condition`` (function) -- either ``any`` or ``all``, or - some other boolean function of a list of boolean values. + - ``condition`` -- function; either ``any`` or ``all``, or + some other boolean function of a list of boolean values OUTPUT: @@ -317,7 +319,7 @@ def union(cls, L): INPUT: - - ``L`` (list) -- a list of UnionOfIntervals instances + - ``L`` -- list of UnionOfIntervals instances OUTPUT: @@ -347,7 +349,7 @@ def intersection(cls, L): INPUT: - - ``L`` (list) -- a list of UnionOfIntervals instances + - ``L`` -- list of UnionOfIntervals instances OUTPUT: @@ -379,11 +381,9 @@ def __or__(left, right): INPUT: - - ``left``, ``right`` (UnionOfIntervals) -- two UnionOfIntervals instances - - OUTPUT: + - ``left``, ``right`` -- two UnionOfIntervals instances - A new UnionOfIntervals instance representing the union of ``left`` and ``right``. + OUTPUT: a new UnionOfIntervals instance representing the union of ``left`` and ``right`` EXAMPLES:: @@ -403,11 +403,9 @@ def __and__(left, right): INPUT: - - ``left``, ``right`` (UnionOfIntervals) -- two UnionOfIntervals instances - - OUTPUT: + - ``left``, ``right`` -- two UnionOfIntervals instances - A new UnionOfIntervals instance representing the intersection of ``left`` and ``right``. + OUTPUT: a new UnionOfIntervals instance representing the intersection of ``left`` and ``right`` EXAMPLES:: @@ -423,15 +421,13 @@ def __and__(left, right): def __contains__(self, x): r""" - Return True if ``x`` is in the UnionOfIntervals. + Return ``True`` if ``x`` is in the UnionOfIntervals. INPUT: - - ``x`` (real) -- a real number + - ``x`` -- real number - OUTPUT: - - Boolean: True if and only if ``x`` is in the union of intervals. + OUTPUT: boolean; ``True`` if and only if `x` is in the union of intervals EXAMPLES:: @@ -475,11 +471,11 @@ def __repr__(self): def nonneg_region(f): r""" - Returns the UnionOfIntervals representing the region where ``f`` is non-negative. + Return the UnionOfIntervals representing the region where ``f`` is nonnegative. INPUT: - - ``f`` (polynomial) -- a univariate polynomial over `\RR`. + - ``f`` -- a univariate polynomial over `\RR` OUTPUT: @@ -518,15 +514,16 @@ def nonneg_region(f): sign_changes += [infinity] return UnionOfIntervals(sign_changes) + def inf_max_abs(f, g, D): r""" - Returns `\inf_D(\max(|f|, |g|))`. + Return `\inf_D(\max(|f|, |g|))`. INPUT: - - ``f``, ``g`` (polynomials) -- real univariate polynomials + - ``f``, ``g`` -- real univariate polynomials - - ``D`` (:class:`UnionOfIntervals`) -- a subset of `\RR` + - ``D`` -- :class:`UnionOfIntervals`; a subset of `\RR` OUTPUT: @@ -564,15 +561,15 @@ def inf_max_abs(f, g, D): def min_on_disk(f, tol, max_iter=10000): r""" - Returns the minimum of a real-valued complex function on a square. + Return the minimum of a real-valued complex function on a square. INPUT: - ``f`` -- a function from CIF to RIF - - ``tol`` (real) -- a positive real number + - ``tol`` -- a positive real number - - ``max_iter`` (integer, default 10000) -- a positive integer + - ``max_iter`` -- integer (default: 10000); a positive integer bounding the number of iterations to be used OUTPUT: @@ -657,9 +654,9 @@ def rat_term_CIF(z, try_strict=True): INPUT: - - ``z`` (complex) -- a CIF element + - ``z`` -- complex; a CIF element - - ``try_strict`` (bool) -- flag + - ``try_strict`` -- boolean; flag EXAMPLES:: @@ -723,9 +720,9 @@ def eps(err, is_real): INPUT: - - ``err`` (real) -- a positive real number, the radius of the interval + - ``err`` -- a positive real number; the radius of the interval - - ``is_real`` (boolean) -- if True, returns a real interval in + - ``is_real`` -- boolean; if ``True``, returns a real interval in RIF, else a complex interval in CIF OUTPUT: @@ -774,7 +771,7 @@ def __init__(self, E): INPUT: - - `E` -- an elliptic curve defined over a number field + - ``E`` -- an elliptic curve defined over a number field EXAMPLES:: @@ -862,11 +859,9 @@ def __call__(self, P): INPUT: - - ``P`` -- a point on the elliptic curve. + - ``P`` -- a point on the elliptic curve - OUTPUT: - - The canonical height of ``P``. + OUTPUT: the canonical height of ``P`` EXAMPLES:: @@ -976,7 +971,7 @@ def e_p(self, p): INPUT: - - ``p`` -- a prime ideal of `K` (or a prime number if `K=\QQ`). + - ``p`` -- a prime ideal of `K` (or a prime number if `K=\QQ`) OUTPUT: @@ -1031,7 +1026,7 @@ def DE(self, n): INPUT: - - ``n`` (int) -- a positive integer + - ``n`` -- positive integer OUTPUT: @@ -1095,9 +1090,9 @@ def B(self, n, mu): INPUT: - - ``n`` (int) -- a positive integer + - ``n`` -- positive integer - - ``mu`` (real) -- a positive real number + - ``mu`` -- positive real number OUTPUT: @@ -1135,11 +1130,11 @@ def psi(self, xi, v): INPUT: - - ``xi`` (real) -- the real x-coordinate of a point on the + - ``xi`` -- real; the real x-coordinate of a point on the curve in the connected component with respect to a real - embedding. + embedding - - ``v`` (embedding) -- a real embedding of the number field. + - ``v`` -- a real embedding of the number field OUTPUT: @@ -1202,9 +1197,9 @@ def S(self, xi1, xi2, v): INPUT: - - ``xi1``, ``xi2`` (real) -- real numbers with `\xi_1\le\xi_2`. + - ``xi1``, ``xi2`` -- real numbers with `\xi_1\le\xi_2` - - ``v`` (embedding) -- a real embedding of the field. + - ``v`` -- a real embedding of the field OUTPUT: @@ -1250,11 +1245,11 @@ def Sn(self, xi1, xi2, n, v): INPUT: - - ``xi1``, ``xi2`` (real) -- real numbers with `\xi_1\le\xi_2`. + - ``xi1``, ``xi2`` -- real numbers with `\xi_1\le\xi_2` - - ``n`` (integer) -- a positive integer. + - ``n`` -- positive integer - - ``v`` (embedding) -- a real embedding of the field. + - ``v`` -- a real embedding of the field OUTPUT: @@ -1293,17 +1288,17 @@ def Sn(self, xi1, xi2, n, v): def real_intersection_is_empty(self, Bk, v): r""" - Returns True iff an intersection of `S_n^{(v)}` sets is empty. + Return ``True`` iff an intersection of `S_n^{(v)}` sets is empty. INPUT: - - ``Bk`` (list) -- a list of reals. + - ``Bk`` -- list of reals - - ``v`` (embedding) -- a real embedding of the number field. + - ``v`` -- a real embedding of the number field OUTPUT: - True or False, according as the intersection of the unions of + ``True`` or ``False``, according as the intersection of the unions of intervals `S_n^{(v)}(-b,b)` for `b` in the list ``Bk`` is empty or not. When ``Bk`` is the list of `b=B_n(\mu)` for `n=1,2,3,\dots` for some `\mu>0` this means that all @@ -1361,7 +1356,7 @@ def tau(self, v): INPUT: - - ``v`` (embedding) -- a real or complex embedding of the number field. + - ``v`` -- a real or complex embedding of the number field OUTPUT: @@ -1383,7 +1378,7 @@ def wp_c(self, v): INPUT: - - ``v`` (embedding) -- a real or complex embedding of the number field. + - ``v`` -- a real or complex embedding of the number field OUTPUT: @@ -1422,15 +1417,15 @@ def fk_intervals(self, v=None, N=20, domain=CIF): INPUT: - - ``v`` (embedding) -- an embedding of the number field. If - None (default) use the real embedding if the field is `\QQ` + - ``v`` -- an embedding of the number field. If + ``None`` (default) use the real embedding if the field is `\QQ` and raise an error for other fields. - - ``N`` (int) -- The number of terms to use in the - `q`-expansion of `\wp`. + - ``N`` -- integer; the number of terms to use in the + `q`-expansion of `\wp` - - ``domain`` (complex field) -- the model of `\CC` to use, for - example ``CDF`` of ``CIF`` (default). + - ``domain`` -- (complex field) the model of `\CC` to use, for + example ``CDF`` of ``CIF`` (default) OUTPUT: @@ -1522,16 +1517,16 @@ def wp_intervals(self, v=None, N=20, abs_only=False): INPUT: - - ``v`` (embedding) -- an embedding of the number field. If - None (default) use the real embedding if the field is `\QQ` - and raise an error for other fields. + - ``v`` -- an embedding of the number field; if + ``None`` (default) use the real embedding if the field is `\QQ` + and raise an error for other fields - - ``N`` (int, default 20) -- The number of terms to use in the - `q`-expansion of `\wp`. + - ``N`` -- integer (default: 20); The number of terms to use in the + `q`-expansion of `\wp` - - ``abs_only`` (boolean, default: ``False``) -- flag to determine - whether (if True) the error adjustment should use the - absolute value or (if False) the real and imaginary parts. + - ``abs_only``-- boolean (default: ``False``); flag to determine + whether (if ``True``) the error adjustment should use the + absolute value or (if ``False``) the real and imaginary parts OUTPUT: @@ -1608,13 +1603,13 @@ def wp_on_grid(self, v, N, half=False): INPUT: - - ``v`` (embedding) -- an embedding of the number field. + - ``v`` -- an embedding of the number field - - ``N`` (int) -- The number of terms to use in the - `q`-expansion of `\wp`. + - ``N`` -- integer; the number of terms to use in the + `q`-expansion of `\wp` - - ``half`` (boolean, default: ``False``) -- if True, use an array of - size `N\times N/2` instead of `N\times N`. + - ``half``-- boolean (default: ``False``); if ``True``, use an array of + size `N\times N/2` instead of `N\times N` OUTPUT: @@ -1659,22 +1654,22 @@ def wp_on_grid(self, v, N, half=False): def complex_intersection_is_empty(self, Bk, v, verbose=False, use_half=True): r""" - Returns True iff an intersection of `T_n^{(v)}` sets is empty. + Return ``True`` iff an intersection of `T_n^{(v)}` sets is empty. INPUT: - - ``Bk`` (list) -- a list of reals. + - ``Bk`` -- list of reals - - ``v`` (embedding) -- a complex embedding of the number field. + - ``v`` -- a complex embedding of the number field - - ``verbose`` (boolean, default: ``False``) -- verbosity flag. + - ``verbose``-- boolean (default: ``False``); verbosity flag - - ``use_half`` (boolean, default: ``False``) -- if True, use only half - the fundamental region. + - ``use_half``-- boolean (default: ``False``); if ``True``, use only half + the fundamental region OUTPUT: - True or False, according as the intersection of the unions of + ``True`` or ``False``, according as the intersection of the unions of intervals `T_n^{(v)}(-b,b)` for `b` in the list ``Bk`` (see [Tho2010]_, section 7) is empty or not. When ``Bk`` is the list of `b=\sqrt{B_n(\mu)}` for `n=1,2,3,\dots` for some `\mu>0` this @@ -1784,11 +1779,11 @@ def test_mu(self, mu, N, verbose=True): INPUT: - - ``mu`` (real) -- a positive real number + - ``mu`` -- positive real number - - ``N`` (integer) -- upper bound on the multiples to be used. + - ``N`` -- integer; upper bound on the multiples to be used - - ``verbose`` (boolean, default: ``True``) -- verbosity flag. + - ``verbose``-- boolean (default: ``True``); verbosity flag OUTPUT: @@ -1881,15 +1876,15 @@ def test_mu(self, mu, N, verbose=True): def min_gr(self, tol, n_max, verbose=False): r""" - Returns a lower bound for points of infinite order with good reduction. + Return a lower bound for points of infinite order with good reduction. INPUT: - - ``tol`` -- tolerance in output (see below). + - ``tol`` -- tolerance in output (see below) - - ``n_max`` -- how many multiples to use in iteration. + - ``n_max`` -- how many multiples to use in iteration - - ``verbose`` (boolean, default: ``False``) -- verbosity flag. + - ``verbose``-- boolean (default: ``False``); verbosity flag OUTPUT: @@ -2007,15 +2002,15 @@ def min_gr(self, tol, n_max, verbose=False): def min(self, tol, n_max, verbose=False): r""" - Returns a lower bound for all points of infinite order. + Return a lower bound for all points of infinite order. INPUT: - - ``tol`` -- tolerance in output (see below). + - ``tol`` -- tolerance in output (see below) - - ``n_max`` -- how many multiples to use in iteration. + - ``n_max`` -- how many multiples to use in iteration - - ``verbose`` (boolean, default: ``False``) -- verbosity flag. + - ``verbose``-- boolean (default: ``False``); verbosity flag OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py old mode 100644 new mode 100755 index fe450c89c5c..722dac306c7 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -270,6 +270,13 @@ def _richcmp_(self, other, op): if lx != rx: return richcmp_not_equal(lx, rx, op) + # Check the Weierstraß scaling factor, too (should be fast) + + if op == op_EQ or op == op_NE: + lx, rx = self.scaling_factor(), other.scaling_factor() + if lx != rx: + return richcmp_not_equal(lx, rx, op) + # Do self or other have specialized comparison methods? ret = self._comparison_impl(self, other, op) @@ -561,8 +568,8 @@ def formal(self, prec=20): INPUT: - - ``prec`` -- (default: 20), the precision with which the - computations in the formal group are carried out. + - ``prec`` -- (default: 20) the precision with which the + computations in the formal group are carried out EXAMPLES:: @@ -1118,10 +1125,8 @@ def matrix_on_subgroup(self, domain_gens, codomain_gens=None): imP = self._eval(P) imQ = self._eval(Q) - from sage.groups.additive_abelian.additive_abelian_wrapper import AdditiveAbelianGroupWrapper - H = AdditiveAbelianGroupWrapper(R.parent(), [R,S], [n,n]) - vecP = H.discrete_log(imP) - vecQ = H.discrete_log(imQ) + vecP = imP.log([R, S]) + vecQ = imQ.log([R, S]) from sage.matrix.constructor import matrix from sage.rings.finite_rings.integer_mod_ring import Zmod @@ -1176,6 +1181,12 @@ def compare_via_evaluation(left, right): F = E.base_ring() if isinstance(F, finite_field_base.FiniteField): + # check at a random rational point first + P = E.random_point() + if left(P) != right(P): + return False + + # then extend to a field with enough points to conclude q = F.cardinality() d = left.degree() e = integer_floor(1 + 2 * (2*d.sqrt() + 1).log(q)) # from Hasse bound @@ -1183,6 +1194,7 @@ def compare_via_evaluation(left, right): EE = E.base_extend(F.extension(e, 'U')) # named extension is faster Ps = EE.gens() return all(left._eval(P) == right._eval(P) for P in Ps) + elif isinstance(F, number_field_base.NumberField): for _ in range(100): P = E.lift_x(F.random_element(), extend=True) @@ -1190,6 +1202,7 @@ def compare_via_evaluation(left, right): return left._eval(P) == right._eval(P) else: assert False, "couldn't find a point of infinite order" + else: raise NotImplementedError('not implemented for this base field') diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py old mode 100644 new mode 100755 index d687c07c2bd..6952f2a0e11 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -449,9 +449,9 @@ def from_factors(cls, maps, E=None, strict=True): INPUT: - ``maps`` -- sequence of :class:`EllipticCurveHom` objects - - ``E`` (optional) -- the domain elliptic curve - - ``strict`` (default: ``True``) -- if ``True``, - always return an :class:`EllipticCurveHom_composite` object; + - ``E`` -- (optional) the domain elliptic curve + - ``strict`` -- boolean (default: ``True``); if ``True``, + always return an :class:`EllipticCurveHom_composite` object, else may return another :class:`EllipticCurveHom` type OUTPUT: the composite of ``maps`` diff --git a/src/sage/schemes/elliptic_curves/hom_sum.py b/src/sage/schemes/elliptic_curves/hom_sum.py old mode 100644 new mode 100755 index ab10ec0d530..50f03d6d761 --- a/src/sage/schemes/elliptic_curves/hom_sum.py +++ b/src/sage/schemes/elliptic_curves/hom_sum.py @@ -560,7 +560,6 @@ def scaling_factor(self): the standard Weierstrass differentials on `E_i` defined by `\mathrm dx/(2y+a_1x+a_3)`. - EXAMPLES:: sage: E = EllipticCurve(GF(101), [5,5]) diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py old mode 100644 new mode 100755 index ad6a8919261..d8cf1971f45 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -135,6 +135,7 @@ from .ell_finite_field import EllipticCurve_finite_field from .hom import EllipticCurveHom, compare_via_evaluation + class _VeluBoundObj: """ Helper object to define the point in which isogeny @@ -165,6 +166,7 @@ def __repr__(self): _velu_sqrt_bound = _VeluBoundObj() + def _choose_IJK(n): r""" Helper function to choose an "index system" for the set @@ -201,6 +203,7 @@ def _choose_IJK(n): K = range(4*b*c+1, n, 2) return I, J, K + def _points_range(rr, P, Q=None): r""" Return an iterator yielding all points `Q + [i]P` where `i` runs @@ -699,7 +702,7 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 385*x + 42 over Finite Field of size 419 - sage: EllipticCurveHom_velusqrt(E, K, model="montgomery") + sage: EllipticCurveHom_velusqrt(E, K, model='montgomery') Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + x over Finite Field of size 419 diff --git a/src/sage/schemes/elliptic_curves/isogeny_class.py b/src/sage/schemes/elliptic_curves/isogeny_class.py old mode 100644 new mode 100755 index b20e173cff9..13edc68a022 --- a/src/sage/schemes/elliptic_curves/isogeny_class.py +++ b/src/sage/schemes/elliptic_curves/isogeny_class.py @@ -57,7 +57,7 @@ def __init__(self, E, label=None, empty=False): INPUT: - ``label`` -- string or ``None``, a Cremona or LMFDB label, used - in printing. Ignored if base field is not `\QQ`. + in printing; ignored if base field is not `\QQ` EXAMPLES:: @@ -102,7 +102,7 @@ def __getitem__(self, i): EXAMPLES:: sage: E = EllipticCurve('990j1') - sage: iso = E.isogeny_class(order="lmfdb") # orders lexicographically on a-invariants + sage: iso = E.isogeny_class(order='lmfdb') # orders lexicographically on a-invariants sage: iso[2] == E # indirect doctest True """ @@ -114,17 +114,17 @@ def index(self, C): INPUT: - - ``C`` -- an elliptic curve in this isogeny class. + - ``C`` -- an elliptic curve in this isogeny class OUTPUT: - - ``i`` -- an integer so that the ``i`` th curve in the class + - ``i`` -- integer so that the ``i`` th curve in the class is isomorphic to ``C`` EXAMPLES:: sage: E = EllipticCurve('990j1') - sage: iso = E.isogeny_class(order="lmfdb") # orders lexicographically on a-invariants + sage: iso = E.isogeny_class(order='lmfdb') # orders lexicographically on a-invariants sage: iso.index(E.short_weierstrass_model()) 2 """ @@ -235,12 +235,10 @@ def __contains__(self, x): """ INPUT: - - ``x`` -- a Python object. + - ``x`` -- a Python object - OUTPUT: - - - boolean -- ``True`` iff ``x`` is an elliptic curve in this - isogeny class. + OUTPUT: boolean; ``True`` iff ``x`` is an elliptic curve in this + isogeny class .. NOTE:: @@ -267,8 +265,8 @@ def matrix(self, fill=True): INPUT: - - ``fill`` -- boolean (default ``True``). If ``False`` then the - matrix will contain only zeros and prime entries; if ``True`` it + - ``fill`` -- boolean (default: ``True``); if ``False`` then the + matrix will contain only zeros and prime entries. If ``True`` it will fill in the other degrees. EXAMPLES:: @@ -341,7 +339,7 @@ def isogenies(self, fill=False): INPUT: - - ``fill`` -- boolean (default ``False``). Whether to only return + - ``fill`` -- boolean (default: ``False``); whether to only return prime degree isogenies. Currently only implemented for ``fill=False``. @@ -501,15 +499,15 @@ def reorder(self, order): INPUT: - - ``order`` -- None, a string or an iterable over all curves - in this class. See + - ``order`` -- ``None``, a string or an iterable over all curves in + this class. See :meth:`sage.schemes.elliptic_curves.ell_rational_field.EllipticCurve_rational_field.isogeny_class` for more details. OUTPUT: - - Another :class:`IsogenyClass_EC` with the curves reordered - (and matrices and maps changed as appropriate) + Another :class:`IsogenyClass_EC` with the curves reordered (and + matrices and maps changed as appropriate). EXAMPLES:: @@ -588,19 +586,18 @@ def __init__(self, E, reducible_primes=None, algorithm='Billerey', minimal_model r""" INPUT: - - ``E`` -- an elliptic curve over a number field. + - ``E`` -- an elliptic curve over a number field - - ``reducible_primes`` (list of ints, or ``None`` (default)) -- if - not ``None`` then this should be a list of primes; in computing - the isogeny class, only composites isogenies of these - degrees will be used. + - ``reducible_primes`` -- list of integers, or ``None`` (default); if + not ``None`` then this should be a list of primes; in computing the + isogeny class, only composites isogenies of these degrees will be used. - - ``algorithm`` (string, default ``'Billerey'``) -- the algorithm + - ``algorithm`` -- string (default: ``'Billerey'``); the algorithm to use to compute the reducible primes. Ignored for CM curves or if ``reducible_primes`` is provided. Values are ``'Billerey'`` (default), ``'Larson'``, and ``'heuristic'``. - - ``minimal_models`` (bool, default ``True``) -- if ``True``, + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves in the class will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -995,23 +992,23 @@ class IsogenyClass_EC_Rational(IsogenyClass_EC_NumberField): r""" Isogeny classes for elliptic curves over `\QQ`. """ - def __init__(self, E, algorithm="sage", label=None, empty=False): + def __init__(self, E, algorithm='sage', label=None, empty=False): r""" INPUT: - - ``E`` -- an elliptic curve over `\QQ`. + - ``E`` -- an elliptic curve over `\QQ` - - ``algorithm`` -- a string (default ``"sage"``). One of the + - ``algorithm`` -- string (default: ``'sage'``); one of the following: - - ``"sage"`` -- Use sage's implementation to compute the curves, + - ``'sage'`` -- use sage's implementation to compute the curves, matrix and isogenies - - ``"database"`` -- Use the Cremona database (only works if the + - ``'database'`` -- use the Cremona database (only works if the curve is in the database) - - ``label`` -- a string, the label of this isogeny class - (e.g. '15a' or '37.b'). Used in printing. + - ``label`` -- string; the label of this isogeny class + (e.g. '15a' or '37.b'), used in printing - ``empty`` -- don't compute the curves right now (used when reordering) @@ -1129,7 +1126,7 @@ def isogeny_degrees_cm(E, verbose=False): INPUT: - - ``E`` -- An elliptic curve defined over a number field. + - ``E`` -- an elliptic curve defined over a number field OUTPUT: @@ -1202,7 +1199,6 @@ def isogeny_degrees_cm(E, verbose=False): sage: from sage.schemes.elliptic_curves.isogeny_class import isogeny_degrees_cm sage: isogeny_degrees_cm(E) [3, 5] - """ if not E.has_cm(): raise ValueError("possible_isogeny_degrees_cm(E) requires E to be an elliptic curve with CM") @@ -1323,6 +1319,7 @@ def isogeny_degrees_cm(E, verbose=False): print("List of primes after filtering: %s" % L) return L + def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, num_l=None, exact=True, verbose=False): r""" @@ -1331,24 +1328,24 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, INPUT: - - ``E`` -- An elliptic curve defined over a number field. + - ``E`` -- an elliptic curve defined over a number field - - ``algorithm`` (string, default ``'Billerey'``) -- Algorithm to be + - ``algorithm`` -- string (default: ``'Billerey'``); algorithm to be used for non-CM curves: either ``'Billerey'``, ``'Larson'``, or ``'heuristic'``. Only relevant for non-CM curves and base fields other than `\QQ`. - - ``max_l`` (int or ``None``) -- only relevant for non-CM curves + - ``max_l`` -- integer or ``None``; only relevant for non-CM curves and algorithms ``'Billerey'`` and ``'heuristic'``. Controls the maximum prime used in either algorithm. If ``None``, use the default for that algorithm. - - ``num_l`` (int or ``None``) -- only relevant for non-CM curves + - ``num_l`` -- integer or ``None``; only relevant for non-CM curves and algorithm ``'Billerey'``. Controls the maximum number of primes used in the algorithm. If ``None``, use the default for that algorithm. - - ``exact`` (bool, default ``True``) -- if ``True``, perform an + - ``exact`` -- boolean (default: ``True``); if ``True``, perform an additional check that the primes returned are all reducible. If ``False``, skip this step, in which case some of the primes returned may be irreducible. @@ -1399,7 +1396,7 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, Over an extension field:: sage: E3 = E.change_ring(CyclotomicField(3)) - sage: possible_isogeny_degrees(E3) + sage: possible_isogeny_degrees(E3) # long time (5s) [5] sage: [phi.degree() for phi in E3.isogenies_prime_degree()] [5, 5] @@ -1421,7 +1418,7 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, sage: K. = NumberField(x^4 - 5*x^2 + 3) sage: E = EllipticCurve(K, [a^2 - 2, -a^2 + 3, a^2 - 2, -50*a^2 + 35, 95*a^2 - 67]) - sage: possible_isogeny_degrees(E, exact=False, algorithm='Billerey') + sage: possible_isogeny_degrees(E, exact=False, algorithm='Billerey') # long time (6.5s) [2, 5] sage: possible_isogeny_degrees(E, exact=False, algorithm='Larson') [2, 5] @@ -1432,7 +1429,7 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, This function only returns the primes which are isogeny degrees:: - sage: Set(E.isogeny_class().matrix().list()) + sage: Set(E.isogeny_class().matrix().list()) # long time (7s) {1, 2, 4, 5, 20, 10} For curves with CM by a quadratic order of class number greater diff --git a/src/sage/schemes/elliptic_curves/isogeny_small_degree.py b/src/sage/schemes/elliptic_curves/isogeny_small_degree.py old mode 100644 new mode 100755 index 9f08f428564..6a0194fb0f9 --- a/src/sage/schemes/elliptic_curves/isogeny_small_degree.py +++ b/src/sage/schemes/elliptic_curves/isogeny_small_degree.py @@ -45,6 +45,7 @@ # only finitely many `j`-invariants each. are also implemented. ########################################################################## + @cached_function def Fricke_polynomial(l): r""" @@ -170,10 +171,10 @@ def Psi(l, use_stored=True): INPUT: - - ``l`` -- either 2, 3, 5, 7, or 13. + - ``l`` -- either 2, 3, 5, 7, or 13 - - ``use_stored`` (boolean, default: ``True``) -- If True, use - precomputed values, otherwise compute them on the fly. + - ``use_stored``-- boolean (default: ``True``); if ``True``, use + precomputed values, otherwise compute them on the fly .. NOTE:: @@ -238,11 +239,11 @@ def isogenies_prime_degree_genus_0(E, l=None, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``l`` -- either None or 2, 3, 5, 7, or 13. + - ``l`` -- either ``None`` or 2, 3, 5, 7, or 13 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -373,8 +374,8 @@ def _sporadic_Q_data(j): INPUT: - - ``j`` -- The `j`-invariant of a sporadic curve, i.e. one of the - keys of ``sporadic_j``. + - ``j`` -- the `j`-invariant of a sporadic curve, i.e. one of the + keys of ``sporadic_j`` OUTPUT: @@ -578,9 +579,9 @@ def isogenies_sporadic_Q(E, l=None, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve defined over `\QQ`. + - ``E`` -- an elliptic curve defined over `\QQ` - - ``l`` -- either None or a prime number. + - ``l`` -- either ``None`` or a prime number OUTPUT: @@ -725,9 +726,9 @@ def isogenies_2(E, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -770,9 +771,9 @@ def isogenies_3(E, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -813,6 +814,7 @@ def isogenies_3(E, minimal_models=True): # 6 special cases: `l` = 5, 7, 13 and `j` = 0, 1728. + def isogenies_5_0(E, minimal_models=True): r""" Return a list of all the 5-isogenies with domain ``E`` when the @@ -820,9 +822,9 @@ def isogenies_5_0(E, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve with j-invariant 0. + - ``E`` -- an elliptic curve with j-invariant 0 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -916,6 +918,7 @@ def isogenies_5_0(E, minimal_models=True): isogs = [isog * iso for isog in isogs] return isogs + def isogenies_5_1728(E, minimal_models=True): r""" Return a list of 5-isogenies with domain ``E`` when the j-invariant is @@ -923,9 +926,9 @@ def isogenies_5_1728(E, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve with j-invariant 1728. + - ``E`` -- an elliptic curve with j-invariant 1728 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -1051,15 +1054,16 @@ def isogenies_5_1728(E, minimal_models=True): isogs = [isog * iso for isog in isogs] return isogs + def isogenies_7_0(E, minimal_models=True): r""" Return list of all 7-isogenies from E when the j-invariant is 0. INPUT: - - ``E`` -- an elliptic curve with j-invariant 0. + - ``E`` -- an elliptic curve with j-invariant 0 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -1191,15 +1195,16 @@ def isogenies_7_0(E, minimal_models=True): isogs = [isog * iso for isog in isogs] return isogs + def isogenies_7_1728(E, minimal_models=True): r""" Return list of all 7-isogenies from E when the j-invariant is 1728. INPUT: - - ``E`` -- an elliptic curve with j-invariant 1728. + - ``E`` -- an elliptic curve with j-invariant 1728 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -1290,15 +1295,16 @@ def isogenies_7_1728(E, minimal_models=True): isogs = [isog * iso for isog in isogs] return isogs + def isogenies_13_0(E, minimal_models=True): """ Return list of all 13-isogenies from E when the j-invariant is 0. INPUT: - - ``E`` -- an elliptic curve with j-invariant 0. + - ``E`` -- an elliptic curve with j-invariant 0 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -1448,9 +1454,9 @@ def isogenies_13_1728(E, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve with j-invariant 1728. + - ``E`` -- an elliptic curve with j-invariant 1728 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -1599,6 +1605,7 @@ def isogenies_13_1728(E, minimal_models=True): hyperelliptic_primes = [11, 17, 19, 23, 29, 31, 41, 47, 59, 71] + @cached_function def _hyperelliptic_isogeny_data(l): r""" @@ -1608,9 +1615,8 @@ def _hyperelliptic_isogeny_data(l): - ``l`` -- a prime in [11, 17, 19, 23, 29, 31, 41, 47, 59, 71] - OUTPUT: - - - A dict holding a collection of precomputed data needed for computing `l`-isogenies. + OUTPUT: a dict holding a collection of precomputed data needed for + computing `l`-isogenies EXAMPLES:: @@ -1750,11 +1756,9 @@ def Psi2(l): INPUT: - - ``l`` -- either 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71. - - OUTPUT: + - ``l`` -- either 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71 - The generic `l`-kernel polynomial. + OUTPUT: the generic `l`-kernel polynomial EXAMPLES:: @@ -1821,11 +1825,11 @@ def isogenies_prime_degree_genus_plus_0(E, l=None, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``l`` -- either None or 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71. + - ``l`` -- either ``None`` or 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -2042,8 +2046,8 @@ def isogenies_prime_degree_genus_plus_0(E, l=None, minimal_models=True): psi = Fxuv(Psi2(l)) for u0, v0 in S: - A4 = Fuv(data['A4'])(u0,v0) #non-zero since j!=0 - A6 = Fuv(data['A6'])(u0,v0) #non-zero since j!=1728 + A4 = Fuv(data['A4'])(u0,v0) # nonzero since j!=0 + A6 = Fuv(data['A6'])(u0,v0) # nonzero since j!=1728 T = (c4*A6)/(2*c6*A4) kernels += [psi((36*X+3*b2)*T,u0,v0).monic()] return [E.isogeny(ker) for ker in kernels] @@ -2055,11 +2059,11 @@ def isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve with j-invariant 0. + - ``E`` -- an elliptic curve with j-invariant 0 - - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71. + - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -2146,7 +2150,7 @@ def isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=True): psi = Fxuv(Psi2(l)) for u0,v0 in S: - A6 = Fuv(data['A6'])(u0,v0) # non-zero since j!=1728 + A6 = Fuv(data['A6'])(u0,v0) # nonzero since j!=1728 kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**3-A6/(-54*c6)).roots(multiplicities=False)] return [E.isogeny(ker) for ker in kernels] @@ -2157,11 +2161,11 @@ def isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve with j-invariant 1728. + - ``E`` -- an elliptic curve with j-invariant 1728 - - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71. + - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71 - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -2270,7 +2274,7 @@ def isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=True): psi = Fxuv(Psi2(l)) for u0,v0 in S: - A4 = Fuv(data['A4'])(u0,v0) # non-zero since j!=0 + A4 = Fuv(data['A4'])(u0,v0) # nonzero since j!=0 kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**2-A4/(-27*c4)).roots(multiplicities=False)] return [E.isogeny(ker) for ker in kernels] @@ -2282,11 +2286,9 @@ def _least_semi_primitive(p): INPUT: - - ``p`` -- an odd prime power. + - ``p`` -- an odd prime power - OUTPUT: - - the smallest semi-primitive root modulo `p`. + OUTPUT: the smallest semi-primitive root modulo `p` .. NOTE:: @@ -2325,15 +2327,15 @@ def is_kernel_polynomial(E, m, f): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``m`` -- a positive integer. + - ``m`` -- positive integer - - ``f`` -- a polynomial over the base field of ``E``. + - ``f`` -- a polynomial over the base field of ``E`` OUTPUT: - (bool) ``True`` if ``E`` has a cyclic isogeny of degree ``m`` with + boolean; ``True`` if ``E`` has a cyclic isogeny of degree ``m`` with kernel polynomial ``f``, else ``False``. ALGORITHM: @@ -2434,11 +2436,11 @@ def isogenies_prime_degree_general(E, l, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``l`` -- a prime. + - ``l`` -- a prime - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. @@ -2623,19 +2625,17 @@ def isogenies_prime_degree(E, l, minimal_models=True): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``l`` -- a prime. + - ``l`` -- a prime - - ``minimal_models`` (bool, default ``True``) -- if ``True``, all + - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all curves computed will be minimal or semi-minimal models. Over fields of larger degree it can be expensive to compute these so set to ``False``. Ignored except over number fields other than `QQ`. - OUTPUT: - - A list of all separable isogenies of degree `l` with domain ``E``. + OUTPUT: list of all separable isogenies of degree `l` with domain ``E`` EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/jacobian.py b/src/sage/schemes/elliptic_curves/jacobian.py old mode 100644 new mode 100755 index 9099a803afc..8aa868dcc92 --- a/src/sage/schemes/elliptic_curves/jacobian.py +++ b/src/sage/schemes/elliptic_curves/jacobian.py @@ -62,9 +62,9 @@ def Jacobian(X, **kwds): INPUT: - ``X`` -- polynomial, algebraic variety, or anything else that - has a Jacobian elliptic curve. + has a Jacobian elliptic curve - - ``kwds`` -- optional keyword arguments. + - ``kwds`` -- optional keyword arguments The input ``X`` can be one of the following: @@ -118,13 +118,13 @@ def Jacobian(X, **kwds): def Jacobian_of_curve(curve, morphism=False): """ - Return the Jacobian of a genus-one curve + Return the Jacobian of a genus-one curve. INPUT: - - ``curve`` -- a one-dimensional algebraic variety of genus one. + - ``curve`` -- a one-dimensional algebraic variety of genus one - OUTPUT: Its Jacobian elliptic curve. + OUTPUT: its Jacobian elliptic curve EXAMPLES:: @@ -155,7 +155,7 @@ def Jacobian_of_equation(polynomial, variables=None, curve=None): INPUT: - ``F`` -- a polynomial defining a plane curve of genus one. May - be homogeneous or inhomogeneous. + be homogeneous or inhomogeneous - ``variables`` -- list of two or three variables or ``None`` (default). The inhomogeneous or homogeneous coordinates. By diff --git a/src/sage/schemes/elliptic_curves/kodaira_symbol.py b/src/sage/schemes/elliptic_curves/kodaira_symbol.py old mode 100644 new mode 100755 index 8e081e4705a..50f94199a36 --- a/src/sage/schemes/elliptic_curves/kodaira_symbol.py +++ b/src/sage/schemes/elliptic_curves/kodaira_symbol.py @@ -7,7 +7,7 @@ The standard notation for Kodaira Symbols is as a string which is one of `\rm{I}_m`, `\rm{II}`, `\rm{III}`, `\rm{IV}`, `\rm{I}^*_m`, `\rm{II}^*`, `\rm{III}^*`, `\rm{IV}^*`, where `m` denotes a -non-negative integer. These have been encoded by single integers by +nonnegative integer. These have been encoded by single integers by different people. For convenience we give here the conversion table between strings, the eclib coding and the PARI encoding. @@ -80,7 +80,7 @@ def __init__(self, symbol): INPUT: - - ``symbol`` (string or integer) -- The string should be a + - ``symbol`` -- string or integer; the string should be a standard string representation (e.g. III*) of a Kodaira symbol, which will be parsed. Alternatively, use the PARI encoding of Kodaira symbols as integers. @@ -316,7 +316,9 @@ def KodairaSymbol(symbol): INPUT: - - ``symbol`` (string or integer) -- Either a string of the form "I0", "I1", ..., "In", "II", "III", "IV", "I0*", "I1*", ..., "In*", "II*", "III*", or "IV*", or an integer encoding a Kodaira symbol using PARI's conventions. + - ``symbol`` -- string or integer; either a string of the form + "I0", "I1", ..., "In", "II", "III", "IV", "I0*", "I1*", ..., "In*", "II*", "III*", or "IV*", + or an integer encoding a Kodaira symbol using PARI's conventions OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/kraus.py b/src/sage/schemes/elliptic_curves/kraus.py old mode 100644 new mode 100755 index b117e8f7ba7..49dff06b493 --- a/src/sage/schemes/elliptic_curves/kraus.py +++ b/src/sage/schemes/elliptic_curves/kraus.py @@ -108,15 +108,15 @@ def c4c6_model(c4, c6, assume_nonsingular=False): - ``c4``, ``c6`` -- elements of a number field - - ``assume_nonsingular`` (boolean, default ``False``) -- if ``True``, - check for integrality and nosingularity. + - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``, + check for integrality and nosingularity OUTPUT: The elliptic curve with a-invariants `[0,0,0,-c_4/48,-c_6/864]`, whose c-invariants are the given `c_4`, `c_6`. If the supplied invariants are singular, returns ``None`` when ``assume_nonsingular`` is ``False`` and - raises an :class:`ArithmeticError` otherwise. + raises an :exc:`ArithmeticError` otherwise. EXAMPLES:: @@ -149,7 +149,7 @@ def make_integral(a, P, e): - ``P`` -- a prime ideal of the number field - - ``e`` -- a positive integer + - ``e`` -- positive integer OUTPUT: @@ -364,8 +364,8 @@ def check_Kraus_local_3(c4, c6, P, assume_nonsingular=False, debug=False): - ``P`` -- a prime ideal of the number field which divides 3 - - ``assume_nonsingular`` (boolean, default ``False``) -- if ``True``, - check for integrality and nosingularity. + - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``, + check for integrality and nosingularity OUTPUT: @@ -591,8 +591,8 @@ def check_Kraus_local_2(c4, c6, P, a1=None, assume_nonsingular=False): - ``a1`` -- an integral elements of a number field, or ``None`` (default) - - ``assume_nonsingular`` (boolean, default ``False``) -- if ``True``, - check for integrality and nonsingularity. + - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``, + check for integrality and nonsingularity OUTPUT: @@ -681,8 +681,8 @@ def check_Kraus_local(c4, c6, P, assume_nonsingular=False): - ``P`` -- a prime ideal of the number field - - ``assume_nonsingular`` (boolean, default ``False``) -- if ``True``, - check for integrality and nonsingularity. + - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``, + check for integrality and nonsingularity OUTPUT: @@ -753,8 +753,8 @@ def check_Kraus_global(c4, c6, assume_nonsingular=False, debug=False): - ``c4``, ``c6`` -- elements of a number field - - ``assume_nonsingular`` (boolean, default ``False``) -- if ``True``, - check for integrality and nonsingularity. + - ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``, + check for integrality and nonsingularity OUTPUT: @@ -926,8 +926,8 @@ def semi_global_minimal_model(E, debug=False): - ``E`` -- an elliptic curve over a number field - - ``debug`` (boolean, default ``False``) -- if ``True``, prints some - messages about the progress of the computation. + - ``debug`` -- boolean (default: ``False``); if ``True``, prints some + messages about the progress of the computation OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/lseries_ell.py b/src/sage/schemes/elliptic_curves/lseries_ell.py old mode 100644 new mode 100755 index 73fb8a63659..74f5233c0e1 --- a/src/sage/schemes/elliptic_curves/lseries_ell.py +++ b/src/sage/schemes/elliptic_curves/lseries_ell.py @@ -17,16 +17,16 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from math import ceil, log, sqrt -from sage.structure.sage_object import SageObject -from sage.rings.real_mpfr import RealField -from sage.rings.rational_field import RationalField -from math import sqrt, log, ceil -import sage.functions.exp_integral as exp_integral -from sage.misc.verbose import verbose from sage.misc.cachefunc import cached_method +from sage.misc.verbose import verbose +from sage.rings.rational_field import RationalField +from sage.rings.real_mpfr import RealField +from sage.structure.sage_object import SageObject class Lseries_ell(SageObject): @@ -70,9 +70,9 @@ def taylor_series(self, a=1, prec=53, series_prec=6, var='z'): INPUT: - ``a`` -- complex number - - ``prec`` -- integer, precision in bits (default 53) - - ``series_prec`` -- integer (default 6) - - ``var`` -- variable (default 'z') + - ``prec`` -- integer; precision in bits (default: 53) + - ``series_prec`` -- integer (default: 6) + - ``var`` -- variable (default: ``'z'``) EXAMPLES:: @@ -111,25 +111,25 @@ def dokchitser(self, prec=53, INPUT: - - ``prec`` -- optional integer (default 53) bits precision + - ``prec`` -- integer (default: 53); bits precision - - ``max_imaginary_part`` -- optional real number (default 0) + - ``max_imaginary_part`` -- real number (default: 0) - - ``max_asymp_coeffs`` -- optional integer (default 40) + - ``max_asymp_coeffs`` -- integer (default: 40) - - ``algorithm`` -- optional string: 'gp' (default), 'pari' or 'magma' + - ``algorithm`` -- string; ``'gp'`` (default), ``'pari'``, or ``'magma'`` - If algorithm is "gp", this returns an interface to Tim - Dokchitser's program for computing with the L-functions. + If algorithm is ``'gp'``, this returns an interface to Tim + Dokchitser's program for computing with the `L`-functions. If algorithm is "pari", this returns instead an interface to Pari's - own general implementation of L-functions. + own general implementation of `L`-functions. .. NOTE:: If algorithm='magma', then the precision is in digits rather - than bits and the object returned is a Magma L-series, which has - different functionality from the Sage L-series. + than bits and the object returned is a Magma `L`-series, which has + different functionality from the Sage `L`-series. EXAMPLES:: @@ -143,7 +143,7 @@ def dokchitser(self, prec=53, If the curve has too large a conductor, it is not possible to compute with the `L`-series using this command. Instead a - ``RuntimeError`` is raised:: + :exc:`RuntimeError` is raised:: sage: e = EllipticCurve([1,1,0,-63900,-1964465932632]) sage: L = e.lseries().dokchitser(15, algorithm='gp') @@ -154,7 +154,7 @@ def dokchitser(self, prec=53, Using the "pari" algorithm:: sage: E = EllipticCurve('37a') - sage: L = E.lseries().dokchitser(algorithm="pari") + sage: L = E.lseries().dokchitser(algorithm='pari') sage: L(2) 0.381575408260711 """ @@ -208,9 +208,7 @@ def sympow(self, n, prec): - ``prec`` -- integer - OUTPUT: - - - (string) -- real number to ``prec`` digits of precision as a string. + OUTPUT: string; real number to ``prec`` digits of precision as a string .. NOTE:: @@ -233,20 +231,18 @@ def sympow(self, n, prec): def sympow_derivs(self, n, prec, d): r""" - Return 0-th to `d`-th derivatives of `L( Sym^{(n)}(E, + Return `0`-th to `d`-th derivatives of `L( Sym^{(n)}(E, \text{edge}))` to ``prec`` digits of precision. INPUT: - - n -- integer - - - prec -- integer + - ``n`` -- integer - - d -- integer + - ``prec`` -- integer - OUTPUT: + - ``d`` -- integer - - a string, exactly as output by sympow + OUTPUT: string; exactly as output by sympow .. NOTE:: @@ -379,7 +375,7 @@ def twist_values(self, s, dmin, dmax): .. NOTE:: - The L-series is normalized so that the center of the + The `L`-series is normalized so that the center of the critical strip is 1. INPUT: @@ -432,7 +428,7 @@ def twist_zeros(self, n, dmin, dmax): .. NOTE:: - The L-series is normalized so that the center of the + The `L`-series is normalized so that the center of the critical strip is 1. INPUT: @@ -445,8 +441,8 @@ def twist_zeros(self, n, dmin, dmax): OUTPUT: - - dict -- keys are the discriminants `d`, and - values are list of corresponding zeros. + - ``dict`` -- keys are the discriminants `d`, and + values are list of corresponding zeros EXAMPLES:: @@ -467,11 +463,11 @@ def at1(self, k=None, prec=None): INPUT: - - ``k`` -- number of terms of the series. If zero or ``None``, - use `k = \sqrt{N}`, where `N` is the conductor. + - ``k`` -- number of terms of the series; if zero or ``None``, + use `k = \sqrt{N}`, where `N` is the conductor - - ``prec`` -- numerical precision in bits. If zero or ``None``, - use a reasonable automatic default. + - ``prec`` -- numerical precision in bits; if zero or ``None``, + use a reasonable automatic default OUTPUT: @@ -613,11 +609,11 @@ def deriv_at1(self, k=None, prec=None): INPUT: - - ``k`` -- number of terms of the series. If zero or ``None``, - use `k = \sqrt{N}`, where `N` is the conductor. + - ``k`` -- number of terms of the series; if zero or ``None``, + use `k = \sqrt{N}`, where `N` is the conductor - - ``prec`` -- numerical precision in bits. If zero or ``None``, - use a reasonable automatic default. + - ``prec`` -- numerical precision in bits; if zero or ``None``, + use a reasonable automatic default OUTPUT: @@ -716,10 +712,12 @@ def deriv_at1(self, k=None, prec=None): # positive, so L'(E,1) = 0. return (R.zero(), Rerror.zero()) + from sage.functions.exp_integral import exponential_integral_1 + an = self.__E.anlist(k) # list of Sage Integers pi = R.pi() sqrtN = R(self.__E.conductor()).sqrt() - v = exp_integral.exponential_integral_1(2*pi/sqrtN, k) + v = exponential_integral_1(2*pi/sqrtN, k) # Compute series sum and accumulate floating point errors L = R.zero() @@ -749,7 +747,7 @@ def deriv_at1(self, k=None, prec=None): def __call__(self, s): r""" - Returns the value of the L-series of the elliptic curve E at s, where s + Return the value of the `L`-series of the elliptic curve E at s, where s must be a real number. .. NOTE:: @@ -773,7 +771,7 @@ def __call__(self, s): def L1_vanishes(self): r""" - Returns whether or not `L(E,1) = 0`. The result is provably + Return whether or not `L(E,1) = 0`. The result is provably correct if the Manin constant of the associated optimal quotient is <= 2. This hypothesis on the Manin constant is true for all curves of conductor <= 40000 (by Cremona) and @@ -922,14 +920,12 @@ def zero_sums(self, N=None): INPUT: - - ``N`` -- (default: ``None``) If not ``None``, the conductor of the + - ``N`` -- (default: ``None``) if not ``None``, the conductor of the elliptic curve attached to ``self``. This is passable so that zero sum computations can be done on curves for which the conductor has been precomputed. - OUTPUT: - - A ``LFunctionZeroSum_EllipticCurve`` instance. + OUTPUT: a ``LFunctionZeroSum_EllipticCurve`` instance EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/meson.build b/src/sage/schemes/elliptic_curves/meson.build new file mode 100644 index 00000000000..3448c5d1c0a --- /dev/null +++ b/src/sage/schemes/elliptic_curves/meson.build @@ -0,0 +1,71 @@ +py.install_sources( + 'BSD.py', + 'Qcurves.py', + 'all.py', + 'cardinality.py', + 'cm.py', + 'constructor.py', + 'ec_database.py', + 'ell_curve_isogeny.py', + 'ell_egros.py', + 'ell_field.py', + 'ell_finite_field.py', + 'ell_generic.py', + 'ell_local_data.py', + 'ell_modular_symbols.py', + 'ell_number_field.py', + 'ell_padic_field.py', + 'ell_point.py', + 'ell_rational_field.py', + 'ell_tate_curve.py', + 'ell_torsion.py', + 'ell_wp.py', + 'formal_group.py', + 'gal_reps.py', + 'gal_reps_number_field.py', + 'gp_simon.py', + 'heegner.py', + 'height.py', + 'hom.py', + 'hom_composite.py', + 'hom_frobenius.py', + 'hom_scalar.py', + 'hom_sum.py', + 'hom_velusqrt.py', + 'homset.py', + 'isogeny_class.py', + 'isogeny_small_degree.py', + 'jacobian.py', + 'kodaira_symbol.py', + 'kraus.py', + 'lseries_ell.py', + 'mod5family.py', + 'mod_poly.py', + 'modular_parametrization.py', + 'padic_lseries.py', + 'padics.py', + 'period_lattice.py', + 'saturation.py', + 'sha_tate.py', + 'weierstrass_morphism.py', + 'weierstrass_transform.py', + subdir: 'sage/schemes/elliptic_curves', +) + +extension_data = { + 'descent_two_isogeny' : files('descent_two_isogeny.pyx'), + 'mod_sym_num' : files('mod_sym_num.pyx'), + 'period_lattice_region' : files('period_lattice_region.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/schemes/elliptic_curves', + install: true, + include_directories: [inc_cpython, inc_flint, inc_numpy, inc_rings], + dependencies: [py_dep, cypari2, cysignals, flint, gmp, mpfr, pari], + ) +endforeach + diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py old mode 100644 new mode 100755 index 580e2aa7598..02ba61efb41 --- a/src/sage/schemes/elliptic_curves/mod_poly.py +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -42,7 +42,7 @@ def classical_modular_polynomial(l, j=None): INPUT: - - ``l`` -- positive integer. + - ``l`` -- positive integer - ``j`` -- either ``None`` or a ring element: * if ``None`` is given, the original modular polynomial @@ -136,7 +136,7 @@ def classical_modular_polynomial(l, j=None): # If the generic polynomial is in the cache or the database, evaluating # it directly should always be faster than recomputing it from scratch. - if l in _cache: + if l in _cache: return _cache[l](j, Y) try: Phi = _db[l] diff --git a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx old mode 100644 new mode 100755 index 200651274ea..e55500f0d0f --- a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx +++ b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx @@ -23,8 +23,8 @@ imaginary part of a period on the imaginary axis. The theorem of Manin-Drinfeld shows that the modular symbols are rational numbers with small denominator. They are used for the -computation of special values of the L-function of `E` twisted by -Dirichlet characters and for the computation of `p`-adic L-functions. +computation of special values of the `L`-function of `E` twisted by +Dirichlet characters and for the computation of `p`-adic `L`-functions. ALGORITHM: @@ -61,7 +61,7 @@ The most likely usage for the code is through the functions ``modular_symbol_numerical``:: sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(0) 0 sage: M(1/123) @@ -77,7 +77,7 @@ accessible, too):: sage: E = EllipticCurve([101,103]) sage: E.conductor() 35261176 - sage: M = E.modular_symbol(implementation="num", sign=-1) + sage: M = E.modular_symbol(implementation='num', sign=-1) sage: M Numerical modular symbol attached to Elliptic Curve defined by y^2 = x^3 + 101*x + 103 over Rational Field @@ -127,7 +127,7 @@ very long time to return a value. However it is possible to compute them for smaller conductors:: sage: E = EllipticCurve("664a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(1/2) 0 @@ -136,7 +136,7 @@ can twist to a semistable curve, like in this example:: sage: C = EllipticCurve("11a1") sage: E = C.quadratic_twist(101) - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(1/101) 41 @@ -256,9 +256,9 @@ cdef llong llxgcd(llong a, llong b, llong *ss, llong *tt) except -1: q = 0 r = 0 s = 1 - while (b): + while b: c = a % b - quot = a/b + quot = a // b a = b b = c new_r = p - quot*r @@ -313,17 +313,19 @@ cdef int proj_normalise(llong N, llong u, llong v, INPUT: - - ``N`` -- an integer (the modulus or level) + - ``N`` -- integer (the modulus or level) - - ``u`` -- an integer (the first coordinate of (u:v)) + - ``u`` -- integer (the first coordinate of (u:v)) - - ``v`` -- an integer (the second coordinate of (u:v)) + - ``v`` -- integer (the second coordinate of (u:v)) - OUTPUT: If gcd(u,v,N) = 1, then returns (in a pointer) + OUTPUT: + + If `\gcd(u,v,N) = 1`, then returns (in a pointer) - - ``uu`` -- an integer + - ``uu`` -- integer - - ``vv`` -- an integer + - ``vv`` -- integer if `\gcd(u,v,N) \not= 1`, returns 0, 0, 0. """ @@ -363,9 +365,9 @@ cdef int proj_normalise(llong N, llong u, llong v, # Now g = s*u + t*N, so s is a "pseudo-inverse" of u mod N # Adjust s modulo N/g so it is coprime to N. if g != 1: - d = N / g + d = N // g while llgcd(s, N) != 1: - s = (s+d) % N + s = (s + d) % N # verbose(" now g=%s, s=%s, t=%s" % (g,s,t), level=5) # Multiply [u,v] by s; then [s*u,s*v] = [g,s*v] (mod N) @@ -374,7 +376,7 @@ cdef int proj_normalise(llong N, llong u, llong v, min_v = v min_t = 1 if g != 1: - Ng = N / g + Ng = N // g vNg = (v * Ng) % N t = 1 k = 2 @@ -454,24 +456,24 @@ cdef int best_proj_point(llong u, llong v, llong N, else: # cases like (p:q) mod p*q drop here p = llgcd(u, N) q = llgcd(v, N) - Nnew = N / p / q - w = ((u/p) * llinvmod(v/q, Nnew)) % Nnew - y0 = N/q + Nnew = (N // p) // q + w = ((u // p) * llinvmod(v // q, Nnew)) % Nnew + y0 = N // q y1 = 0 x0 = w*p x1 = q # y will always be the longer and x the shorter - while llabs(x0) + llabs(x1) < llabs(y0)+llabs(y1): + while llabs(x0) + llabs(x1) < llabs(y0) + llabs(y1): if llsign(x0) == llsign(x1): - r = (y0+y1) / (x0+x1) + r = (y0+y1) // (x0+x1) else: - r = (y0-y1) / (x0-x1) + r = (y0-y1) // (x0-x1) t0 = y0 - r * x0 t1 = y1 - r * x1 s0 = t0 - x0 s1 = t1 - x1 - if llabs(s0)+llabs(s1) < llabs(t0)+llabs(t1): + if llabs(s0) + llabs(s1) < llabs(t0) + llabs(t1): t0 = s0 t1 = s1 # t is now the shortest vector on the line y + RR x @@ -591,7 +593,7 @@ cdef class _CuspsForModularSymbolNumerical: a -= m self._r = Rational((a, m)) B = llgcd(m, N) - self._width = N / B + self._width = N // B self._a = a self._m = m self._N_level = N @@ -623,7 +625,7 @@ cdef class _CuspsForModularSymbolNumerical: # verbose(" enter atkin_lehner for cusp r=%s" % self._r, level=5) Q = self._width B = llgcd(self._m, self._N_level) - c = self._m / B + c = self._m // B if llgcd(Q, B) != 1: raise ValueError("This cusp is not in the Atkin-Lehner " "orbit of oo.") @@ -690,7 +692,7 @@ cdef class ModularSymbolNumerical: INPUT: - - ``E`` -- an elliptic curve over the rational numbers. + - ``E`` -- an elliptic curve over the rational numbers - ``sign`` -- either -1 or +1 (default). This sets the default value of ``sign`` throughout the class. Both are still accessible. @@ -700,14 +702,14 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(0) 0 sage: M(77/57) -1 sage: M(33/37, -1) 2 - sage: M = E.modular_symbol(sign=-1, implementation="num") + sage: M = E.modular_symbol(sign=-1, implementation='num') sage: M(2/7) 2 @@ -748,7 +750,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve([1,-1]) - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(12/11) # indirect doctest 1/2 """ @@ -768,7 +770,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("27a1") - sage: M = E. modular_symbol(implementation="num") + sage: M = E. modular_symbol(implementation='num') sage: M(1/9) 1/2 sage: M(1/3) @@ -818,7 +820,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("14a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M Numerical modular symbol attached to Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field """ @@ -831,7 +833,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("15a4") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.elliptic_curve() Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + 35*x - 28 over Rational Field """ @@ -846,30 +848,30 @@ cdef class ModularSymbolNumerical: - ``r`` -- a rational (or integer) - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken - ``use_twist`` -- boolean (default: ``True``); decides if we - allow to use a quadratic twist. + allow to use a quadratic twist OUTPUT: a rational number EXAMPLES:: sage: E = EllipticCurve("36a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(2/5) -1/3 sage: M(2/5, -1) 1/2 sage: E = EllipticCurve("54a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(5/9) -1/2 sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(234/567) 0 sage: M(112379/43568779) @@ -911,20 +913,20 @@ cdef class ModularSymbolNumerical: - ``r`` -- a rational (or integer) - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken - - ``prec`` -- an integer (default 20) + - ``prec`` -- integer (default: 20) - - ``use_twist`` -- True (default) allows to use a - quadratic twist of the curve to lower the conductor. + - ``use_twist`` -- ``True`` (default) allows to use a + quadratic twist of the curve to lower the conductor OUTPUT: a real number EXAMPLES:: sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.approximative_value(123/567) # abs tol 1e-11 -4.00000000000845 sage: M.approximative_value(123/567,prec=2) # abs tol 1e-9 @@ -933,7 +935,7 @@ cdef class ModularSymbolNumerical: sage: E = EllipticCurve([11,88]) sage: E.conductor() 1715296 - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.approximative_value(0,prec=2) # abs tol 1e-11 -0.0000176374317982166 sage: M.approximative_value(1/7,prec=2) # abs tol 1e-11 @@ -996,7 +998,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("20a2") - sage: M = E.modular_symbol(implementation="num") #indirect doctest + sage: M = E.modular_symbol(implementation='num') #indirect doctest """ self._epsQs = {d: prod(self._E.root_number(p) for p in d.prime_divisors()) @@ -1017,7 +1019,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("240b3") - sage: M = E.modular_symbol(implementation="num") #indirect doctest + sage: M = E.modular_symbol(implementation='num') #indirect doctest """ from sage.databases.cremona import CremonaDatabase @@ -1152,7 +1154,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve("63a2") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(3/4, use_twist=True) # indirect doctest -1 """ @@ -1212,9 +1214,9 @@ cdef class ModularSymbolNumerical: - ``sign`` -- either +1 or -1 - - ``unitary`` -- a boolean (int) + - ``unitary`` -- boolean (int) - OUTPUT: a rational. + OUTPUT: a rational EXAMPLES:: @@ -1268,7 +1270,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve([-11,13]) - sage: M = E.modular_symbol(implementation="num") #indirect doctest + sage: M = E.modular_symbol(implementation='num') #indirect doctest """ cdef int n # verbose(" enter _initialise_an_coeffients", level=5) @@ -1293,7 +1295,7 @@ cdef class ModularSymbolNumerical: INPUT: - - ``T`` -- an integer + - ``T`` -- integer EXAMPLES:: @@ -1346,12 +1348,12 @@ cdef class ModularSymbolNumerical: def clear_cache(self): r""" - Clear the cached values in all methods of this class + Clear the cached values in all methods of this class. EXAMPLES:: sage: E = EllipticCurve("11a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(0) 1/5 sage: M.clear_cache() @@ -1376,15 +1378,13 @@ cdef class ModularSymbolNumerical: - ``tau`` -- a point in the upper half plane - - ``number_of_terms`` -- an integer describing + - ``number_of_terms`` -- integer describing how many terms to sum - - ``prec`` -- an integer, setting the precision + - ``prec`` -- integer; setting the precision to ``prec`` bits in all of the computation - OUTPUT: - - - a complex number + OUTPUT: a complex number EXAMPLES:: @@ -1450,12 +1450,10 @@ cdef class ModularSymbolNumerical: - ``tau`` -- a point in the upper half plane - - ``number_of_terms`` -- an integer describing + - ``number_of_terms`` -- integer describing how many terms to sum - OUTPUT: - - - a complex number + OUTPUT: a complex number EXAMPLES:: @@ -1508,12 +1506,12 @@ cdef class ModularSymbolNumerical: - ``y`` -- a positive real number - - ``m`` -- an integer + - ``m`` -- integer - - ``number_of_terms`` -- an integer describing + - ``number_of_terms`` -- integer describing how many terms to sum - OUTPUT: a list of real numbers (in a pointer) + OUTPUT: list of real numbers (in a pointer) EXAMPLES:: @@ -1578,15 +1576,15 @@ cdef class ModularSymbolNumerical: - ``y`` -- a positive real number - - ``m`` -- an integer + - ``m`` -- integer - - ``number_of_terms`` -- an integer describing + - ``number_of_terms`` -- integer describing how many terms to sum - - ``prec`` -- an integer, setting the precision + - ``prec`` -- integer setting the precision to ``prec`` bits in all of the computation - OUTPUT: a list of real numbers + OUTPUT: list of real numbers EXAMPLES:: @@ -1661,9 +1659,7 @@ cdef class ModularSymbolNumerical: - ``eps`` -- a positive real number, the maximal allowed error - OUTPUT: - - two integers `T` and `b` + OUTPUT: two integers `T` and `b` If `T` would be larger than `2^31`, the value (-1,-1) is returned instead. @@ -1768,22 +1764,22 @@ cdef class ModularSymbolNumerical: INPUT: - - ``m`` -- an integer (long long) + - ``m`` -- integer (long long) - ``z`` -- another integer (long long) - - ``eps`` -- either None (default) or a real number (double), + - ``eps`` -- either ``None`` (default) or a real number (double), describing the precision to which the terms are computed. - Each term is off by less than ``eps``/``m``. If None, the + Each term is off by less than ``eps``/``m``. If ``None``, the ``eps`` is chosen from the precomputed precision related to the periods. - OUTPUT: a list of `m` real numbers + OUTPUT: list of `m` real numbers EXAMPLES:: sage: E = EllipticCurve("43a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M._kappa(3,4) # abs tol 1e-11 [-5.379533671373222e-05, 0.043215661934968536, -0.0018675632930897528] sage: M._kappa(3,17) # abs tol 1e-11 @@ -1880,7 +1876,7 @@ cdef class ModularSymbolNumerical: INPUT: - - ```r`` -- a rational number + - ``r`` -- a rational number - ``eps`` -- a positive real number @@ -2024,11 +2020,11 @@ cdef class ModularSymbolNumerical: - ``r``, ``rr`` -- two Rationals - - ``espQ`` and ``espQ`` -- two Integers + - ``espQ``, ``espQ`` -- two Integers - - `` T `` and ``prec`` -- two ints + - ``T``, ``prec`` -- two ints - - `` use_partials -- int: 0 don't use partials, + - ``use_partials`` -- int: 0 don't use partials, 1 use them, 2 (default) decide if meaningful OUTPUT: a complex number @@ -2129,12 +2125,12 @@ cdef class ModularSymbolNumerical: verbose(" yields %s " % int2c, level=3) ans = int2c + int1c else: # use_partials - g = llgcd(Q,QQ) + g = llgcd(Q, QQ) D = Q * QQ D /= g D *= llabs(a*mm-aa*m) - xi = (Q*aa*u+v*mm) * QQ /g * llsign(a*mm-aa*m) - xixi = (QQ*a*uu+vv*m) * Q /g * llsign(aa*m-a*mm) + xi = (Q*aa*u+v*mm) * (QQ // g) * llsign(a*mm-aa*m) + xixi = (QQ*a*uu+vv*m) * (Q // g) * llsign(aa*m-a*mm) z = Q * QQ * (a*mm-aa*m)**2 ka = self._kappa(D, z, eps/2) twopii = TWOPI * complex("j") @@ -2166,10 +2162,10 @@ cdef class ModularSymbolNumerical: - ``eps`` -- a positive real number - - ``method`` -- a string or None: either "direct", "indirect", - "both". When method is not given (default), then the better - of the two is chosen. "both" raises an error if the two - methods differ by more than ``eps``. + - ``method`` -- string or ``None``: either ``'direct'``, + ``'indirect'``, or ``'both'``. When method is not given (default), + then the better of the two is chosen. ``'both'`` raises an error if + the two methods differ by more than ``eps``. - ``use_partials`` -- int: 0 don't use partials, 1 use them, 2 (default) decide if meaningful @@ -2477,28 +2473,28 @@ cdef class ModularSymbolNumerical: - ``r`` -- a rational number, which has to be a unitary cusp - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken - - ``use_partials`` -- integer: 0 don't use partial summation to do + - ``use_partials`` -- integer; 0 don't use partial summation to do the computation, 1 do use them, 2 (default) decide if it is - meaningful to do so. + meaningful to do so - OUTPUT: a rational number. + OUTPUT: a rational number EXAMPLES:: sage: from sage.schemes.elliptic_curves.mod_sym_num \ ....: import ModularSymbolNumerical sage: E = EllipticCurve("11a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M._value_ioo_to_r(0/1) 1/5 sage: M._value_ioo_to_r(3/11,-1) 1/2 sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M._value_ioo_to_r(0/1) 0 sage: M._value_ioo_to_r(123/456) @@ -2536,15 +2532,15 @@ cdef class ModularSymbolNumerical: INPUT: - - ``r`` and ``rr`` -- two rational number, both have to be - uniraty cusps. + - ``r``, ``rr`` -- two rational numbers, both have to be + unitary cusps - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken - - ``use_partials`` -- integer: 0 don't use partial summation to do + - ``use_partials`` -- integer; 0 don't use partial summation to do the computation, 1 do use them, 2 (default) decide if it is - meaningful to do so. + meaningful to do so OUTPUT: a rational number @@ -2553,7 +2549,7 @@ cdef class ModularSymbolNumerical: sage: from sage.schemes.elliptic_curves.mod_sym_num \ ....: import ModularSymbolNumerical sage: E = EllipticCurve("57a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M._value_r_to_rr(0/1,8/9) 0 sage: M._value_r_to_rr(0/1,8/9,use_partials=0) @@ -2570,7 +2566,7 @@ cdef class ModularSymbolNumerical: 55196272 sage: E.conductor().factor() 2^4 * 3449767 - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M._value_r_to_rr(0/1,4/5) 1 sage: M._value_r_to_rr(7/11,14/75) # long time @@ -2606,29 +2602,29 @@ cdef class ModularSymbolNumerical: INPUT: - - ``r`` and ``rr`` -- two rational numbers + - ``r``, ``rr`` -- two rational numbers - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken OUTPUT: a rational number EXAMPLES:: sage: E = EllipticCurve("11a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.transportable_symbol(0/1,-2/7) -1/2 sage: E = EllipticCurve("37a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.transportable_symbol(0/1,-1/19) 0 sage: M.transportable_symbol(0/1,-1/19,-1) 0 sage: E = EllipticCurve("5077a1") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.transportable_symbol(0/1,-35/144) -3 sage: M.transportable_symbol(0/1,-35/144,-1) @@ -2671,8 +2667,8 @@ cdef class ModularSymbolNumerical: - ``r`` -- a rational number representing a unitary cusp - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken OUTPUT: a rational number @@ -2791,33 +2787,33 @@ cdef class ModularSymbolNumerical: else: # (c:d) = (u:v) but c and d are fairly small # in absolute value - Mu = llgcd(u,N) - Qu = N/Mu - Mv = llgcd(v,N) - Qv = N/Mv - isunitary = (llgcd(Qu,Mu) == 1 and llgcd(Qv,Mv) == 1) + Mu = llgcd(u, N) + Qu = N // Mu + Mv = llgcd(v, N) + Qv = N // Mv + isunitary = (llgcd(Qu, Mu) == 1 and llgcd(Qv, Mv) == 1) if isunitary: # unitary case _ = best_proj_point(u, v, self._N_E, &c, &d) else: # at least one of the two cusps is not unitary du = llgcd(Qu,Mu) - dv = llgcd(Qv,Mv) - NMM = N/Mv/Mu + dv = llgcd(Qv, Mv) + NMM = N // Mv // Mu if dv == 1: c = Mu - d = llinvmod(u/Mu, NMM) + d = llinvmod(u // Mu, NMM) d *= v - d = d % (N/Mu) + d = d % (N // Mu) while llgcd(c,d) != 1: - d += N/Mu + d += N // Mu d = d % N # now (u:v) = (c:d) with c as small as possible. else: d = Mv - c = llinvmod(v/Mv, NMM) + c = llinvmod(v // Mv, NMM) c *= u - c = c % (N/Mv) - while llgcd(c,d) != 1: - c += N/Mv + c = c % (N // Mv) + while llgcd(c, d) != 1: + c += N // Mv c = c % N # now (u:v) = (c:d) with d as small as possible. # verbose(" better representant on P^1: " @@ -2860,18 +2856,18 @@ cdef class ModularSymbolNumerical: INPUT: - - ``u`` -- an integer + - ``u`` -- integer - - ``v`` -- an integer such that `(u:v)` is a projective point + - ``v`` -- integer such that `(u:v)` is a projective point modulo `N` - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken EXAMPLES:: sage: E = EllipticCurve('11a1') - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.manin_symbol(1,3) -1/2 sage: M.manin_symbol(1,3, sign=-1) @@ -2882,7 +2878,7 @@ cdef class ModularSymbolNumerical: 1 sage: E = EllipticCurve('14a1') - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.manin_symbol(1,2) -1/2 sage: M.manin_symbol(17,6) @@ -2992,8 +2988,8 @@ cdef class ModularSymbolNumerical: - ``r`` -- a rational number representing a unitary cusp - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken OUTPUT: a rational number @@ -3127,8 +3123,8 @@ cdef class ModularSymbolNumerical: - ``m`` -- a natural number - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken OUTPUT: a dictionary of fractions with denominator `m` giving rational numbers. @@ -3136,7 +3132,7 @@ cdef class ModularSymbolNumerical: EXAMPLES:: sage: E = EllipticCurve('5077a1') - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.all_values_for_one_denominator(7) {1/7: 3, 2/7: 0, 3/7: -3, 4/7: -3, 5/7: 0, 6/7: 3} sage: [M(a/7) for a in [1..6]] @@ -3145,14 +3141,14 @@ cdef class ModularSymbolNumerical: {1/3: 4, 2/3: -4} sage: E = EllipticCurve('11a1') - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.all_values_for_one_denominator(12) {1/12: 1/5, 5/12: -23/10, 7/12: -23/10, 11/12: 1/5} sage: M.all_values_for_one_denominator(12, -1) {1/12: 0, 5/12: 1/2, 7/12: -1/2, 11/12: 0} sage: E = EllipticCurve('20a1') - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.all_values_for_one_denominator(4) {1/4: 0, 3/4: 0} sage: M.all_values_for_one_denominator(8) @@ -3174,8 +3170,8 @@ cdef class ModularSymbolNumerical: RR = RealField(53) N = self._N_E - Q = N / llgcd(m,N) - if llgcd(m,Q) > 1: + Q = N // llgcd(m, N) + if llgcd(m, Q) > 1: raise NotImplementedError("Only implemented for cusps that are " "in the Atkin-Lehner orbit of oo") # verbose(" compute all partial sums with denominator m=%s" % m, @@ -3227,15 +3223,15 @@ cdef class ModularSymbolNumerical: - ``ra`` -- a rational number - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken OUTPUT: a rational number EXAMPLES:: sage: E = EllipticCurve("735e4") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M(1/19, sign=-1, use_twist=False) #indirect doctest 4 sage: M(1/19, sign=-1, use_twist=True) @@ -3455,17 +3451,17 @@ cdef class ModularSymbolNumerical: - ``ra`` -- a rational number - - ``sign`` -- optional either +1 or -1, or 0 (default), - in which case the sign passed to the class is taken. + - ``sign`` -- either +1 or -1, or 0 (default), + in which case the sign passed to the class is taken - - ``prec`` -- an integer (default 20) + - ``prec`` -- integer (default: 20) OUTPUT: a real number EXAMPLES:: sage: E = EllipticCurve("735e4") - sage: M = E.modular_symbol(implementation="num") + sage: M = E.modular_symbol(implementation='num') sage: M.approximative_value(1/19, sign=-1, prec=20, use_twist=False) # indirect doctest abs tol 1e-11 4.00000000089736 sage: M.approximative_value(1/19, sign=-1, prec=20, use_twist=True) # abs tol 1e-11 @@ -3622,10 +3618,10 @@ def _test_integration(E, a, b, T): - ``E`` -- an elliptic curve - - ``a`` and ``b`` -- two real numbers representing real and + - ``a``, ``b`` -- two real numbers representing real and imaginary part of a complex number tau - - ``T `` -- an integer for the number of terms to use + - ``T `` -- integer for the number of terms to use OUTPUT: a complex number @@ -3665,11 +3661,11 @@ def _test_integration_via_partials(E, y, m, T): - ``y`` -- a real number - - ``m`` -- an integers + - ``m`` -- integer - - ``T `` -- an integer for the number of terms to use + - ``T `` -- integer for the number of terms to use - OUTPUT: a list of `m` real numbers + OUTPUT: list of `m` real numbers EXAMPLES:: @@ -3697,7 +3693,7 @@ def _test_integration_via_partials(E, y, m, T): return res -def _test_against_table(range_of_conductors, other_implementation="sage", list_of_cusps=None, verb=False): +def _test_against_table(range_of_conductors, other_implementation='sage', list_of_cusps=None, verb=False): r""" This test function checks the modular symbols here against the ones implemented already. Note that for some curves the current @@ -3706,14 +3702,14 @@ def _test_against_table(range_of_conductors, other_implementation="sage", list_o INPUT: - - ``range_of_conductors`` -- a list of integers; all curves with - conductors in that list will be tested. + - ``range_of_conductors`` -- list of integers; all curves with + conductors in that list will be tested - - ``list_of_cusps`` -- a list of rationals to be tested + - ``list_of_cusps`` -- list of rationals to be tested - ``verb`` -- if ``True`` (default) prints the values - OUTPUT: Boolean. If ``False`` the function also prints information. + OUTPUT: boolean; if ``False`` the function also prints information EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/modular_parametrization.py b/src/sage/schemes/elliptic_curves/modular_parametrization.py old mode 100644 new mode 100755 index 6ff558a0db0..2df0d64f5cc --- a/src/sage/schemes/elliptic_curves/modular_parametrization.py +++ b/src/sage/schemes/elliptic_curves/modular_parametrization.py @@ -112,7 +112,7 @@ def __repr__(self): def __eq__(self, other): r""" - Compares two modular parametrizations by simply comparing the elliptic curves. + Compare two modular parametrizations by simply comparing the elliptic curves. EXAMPLES:: @@ -253,7 +253,9 @@ def power_series(self, prec=20): the number of significant terms. This means that X will be given up to O(q^(prec-2)) and Y will be given up to O(q^(prec-3)). - OUTPUT: A list of two Laurent series ``[X(x),Y(x)]`` of degrees -2, -3 + OUTPUT: + + A list of two Laurent series [`X(x)`,`Y(x)`] of degrees `-2`, `-3`, respectively, which satisfy the equation of the elliptic curve. There are modular functions on `\Gamma_0(N)` where `N` is the conductor. diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py old mode 100644 new mode 100755 index 73cfb5aded6..1fcc30764b2 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -3,7 +3,7 @@ `p`-adic `L`-functions of elliptic curves To an elliptic curve `E` over the rational numbers and a prime `p`, one -can associate a `p`-adic L-function; at least if `E` does not have additive +can associate a `p`-adic `L`-function; at least if `E` does not have additive reduction at `p`. This function is defined by interpolation of L-values of `E` at twists. Through the main conjecture of Iwasawa theory it should also be equal to a characteristic series of a certain Selmer group. @@ -17,15 +17,15 @@ One can decompose this algebra as the direct product of the subalgebras corresponding to the characters of `\Delta`, which are simply the powers `\tau^\eta` (`0 \le \eta \le p-2`) of the Teichmueller character `\tau: \Delta -\to \ZZ_p^\times`. Projecting the L-function into these components gives `p-1` +\to \ZZ_p^\times`. Projecting the `L`-function into these components gives `p-1` power series in `T`, each with coefficients in `\ZZ_p`. If `E` is supersingular, the series will have coefficients in a quadratic extension of `\QQ_p`, and the coefficients will be unbounded. In this case we have only implemented the series for `\eta = 0`. We have also implemented the -`p`-adic L-series as formulated by Perrin-Riou [BP1993]_, which has coefficients in -the Dieudonné module `D_pE = H^1_{dR}(E/\QQ_p)` of `E`. There is a different -description by Pollack [Pol2003]_ which is not available here. +`p`-adic `L`-series as formulated by Perrin-Riou [BP1993]_, which has +coefficients in the Dieudonné module `D_pE = H^1_{dR}(E/\QQ_p)` of `E`. There +is a different description by Pollack [Pol2003]_ which is not available here. According to the `p`-adic version of the Birch and Swinnerton-Dyer conjecture [MTT1986]_, the order of vanishing of the `L`-function at the trivial character @@ -69,10 +69,9 @@ prime_divisors, kronecker as kronecker_symbol, valuation) -from sage.functions.log import log -from sage.functions.other import floor from sage.misc.cachefunc import cached_method from sage.misc.functional import denominator +from sage.misc.lazy_import import lazy_import from sage.misc.verbose import get_verbose, verbose from sage.modules.free_module_element import vector from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers @@ -80,18 +79,21 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.laurent_series_ring import LaurentSeriesRing -from sage.rings.padics.factory import Qp from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.rational_field import QQ from sage.structure.richcmp import richcmp_method, richcmp from sage.structure.sage_object import SageObject +lazy_import("sage.functions.log", "log") +lazy_import("sage.functions.other", "floor") +lazy_import('sage.rings.padics.factory', 'Qp') + @richcmp_method class pAdicLseries(SageObject): r""" - The `p`-adic L-series of an elliptic curve. + The `p`-adic `L`-series of an elliptic curve. EXAMPLES: @@ -154,14 +156,13 @@ def __init__(self, E, p, implementation='eclib', normalize='L_ratio'): - ``E`` -- an elliptic curve - ``p`` -- a prime of good reduction - - ``implementation`` -- string (default: 'eclib'); either 'eclib' to use - John Cremona's ``eclib`` for the computation of modular - symbols, 'num' to use numerical modular symbols - or 'sage' to use Sage's own implementation + - ``implementation`` -- string (default: ``'eclib'``); either + ``'eclib'`` to use John Cremona's ``eclib`` for the computation of + modular symbols, 'num' to use numerical modular symbols or ``'sage'`` + to use Sage's own implementation - ``normalize`` -- ``'L_ratio'`` (default), ``'period'`` or ``'none'``; - this is describes the way the modular symbols - are normalized. See ``modular_symbol`` of - an elliptic curve over Q for more details. + this is describes the way the modular symbols are normalized. See + ``modular_symbol`` of an elliptic curve over Q for more details. EXAMPLES:: @@ -205,7 +206,7 @@ def __add_negative_space(self): sage: lp.modular_symbol(1/7,sign=-1) #indirect doctest -1/2 """ - self._negative_modular_symbol = self._E.modular_symbol(sign=-1, implementation="sage", normalize=self._normalize) + self._negative_modular_symbol = self._E.modular_symbol(sign=-1, implementation='sage', normalize=self._normalize) def __richcmp__(self, other, op): r""" @@ -229,7 +230,7 @@ def __richcmp__(self, other, op): def elliptic_curve(self): r""" - Return the elliptic curve to which this `p`-adic L-series is associated. + Return the elliptic curve to which this `p`-adic `L`-series is associated. EXAMPLES:: @@ -241,7 +242,7 @@ def elliptic_curve(self): def prime(self): r""" - Return the prime `p` as in 'p-adic L-function'. + Return the prime `p` as in `p`-adic `L`-function'. EXAMPLES:: @@ -276,7 +277,7 @@ def modular_symbol(self, r, sign=+1, quadratic_twist=+1): r""" Return the modular symbol evaluated at `r`. - This is used to compute this `p`-adic L-series. + This is used to compute this `p`-adic `L`-series. Note that the normalization is not correct at this stage: use ``_quotient_of periods_to_twist`` to correct. @@ -351,7 +352,7 @@ def measure(self, a, n, prec, quadratic_twist=+1, sign=+1): \frac{1}{\alpha^{n+1}} \left[\frac{a}{p^{n-1}}\right]^{+}` where `[\cdot]^{+}` is the modular symbol. This is used to define - this `p`-adic L-function (at least when the reduction is good). + this `p`-adic `L`-function (at least when the reduction is good). The optional argument ``sign`` allows the minus symbol `[\cdot]^{-}` to be substituted for the plus symbol. @@ -373,16 +374,16 @@ def measure(self, a, n, prec, quadratic_twist=+1, sign=+1): INPUT: - - ``a`` -- an integer + - ``a`` -- integer - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer - - ``prec`` -- an integer + - ``prec`` -- integer - - ``quadratic_twist`` (default = 1) -- a fundamental discriminant of a quadratic field, - should be coprime to the conductor of `E` + - ``quadratic_twist`` -- (default: 1) a fundamental discriminant of a + quadratic field, should be coprime to the conductor of `E` - - ``sign`` (default = 1) -- an integer, which should be `\pm 1`. + - ``sign`` -- integer (default: 1) which should be `\pm 1` EXAMPLES:: @@ -454,7 +455,7 @@ def alpha(self, prec=20): INPUT: - - ``prec`` -- positive integer, the `p`-adic precision of the root. + - ``prec`` -- positive integer; the `p`-adic precision of the root EXAMPLES: @@ -511,14 +512,14 @@ def alpha(self, prec=20): raise RuntimeError("bug in p-adic L-function alpha") else: # supersingular case f = f.change_ring(K) - A = K.extension(f, names="alpha") + A = K.extension(f, names='alpha') a = A.gen() self._alpha[prec] = a return a def order_of_vanishing(self): r""" - Return the order of vanishing of this `p`-adic L-series. + Return the order of vanishing of this `p`-adic `L`-series. The output of this function is provably correct, due to a theorem of Kato [Kat2004]_. @@ -586,11 +587,9 @@ def teichmuller(self, prec): INPUT: - - ``prec`` -- a positive integer. - - OUTPUT: + - ``prec`` -- positive integer - - a list of `p`-adic numbers, the cached Teichmuller lifts + OUTPUT: list of `p`-adic numbers; the cached Teichmuller lifts EXAMPLES:: @@ -630,8 +629,7 @@ def _e_bounds(self, n, prec): res = [enj] for j in range(1,prec): bino = valuation(binomial(pn,j),self._p) - if bino < enj: - enj = bino + enj = min(bino, enj) res.append(enj) return res @@ -741,13 +739,13 @@ def _quotient_of_periods_to_twist(self, D): class pAdicLseriesOrdinary(pAdicLseries): def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): r""" - Return the `n`-th approximation to the `p`-adic L-series, in the + Return the `n`-th approximation to the `p`-adic `L`-series, in the component corresponding to the `\eta`-th power of the Teichmueller character, as a power series in `T` (corresponding to `\gamma-1` with `\gamma=1+p` as a generator of `1+p\ZZ_p`). Each coefficient is a `p`-adic number whose precision is provably correct. - Here the normalization of the `p`-adic L-series is chosen + Here the normalization of the `p`-adic `L`-series is chosen such that `L_p(E,1) = (1-1/\alpha)^2 L(E,1)/\Omega_E` where `\alpha` is the unit root of the characteristic polynomial of Frobenius on `T_pE` and `\Omega_E` is the @@ -761,7 +759,7 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): - ``prec`` -- (default: 5) maximal number of terms of the series to compute; to compute as many as possible just give a very large number for ``prec``; the result will still be correct. - - ``eta`` (default: 0) an integer (specifying the power of the + - ``eta`` -- (default: 0) an integer (specifying the power of the Teichmueller character on the group of roots of unity in `\ZZ_p^\times`) @@ -769,7 +767,7 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): EXAMPLES: - We compute some `p`-adic L-functions associated to the elliptic + We compute some `p`-adic `L`-functions associated to the elliptic curve 11a:: sage: E = EllipticCurve('11a') @@ -781,8 +779,8 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): 2 + 3 + 3^2 + 2*3^3 + O(3^5) + (1 + 3 + O(3^2))*T + (1 + 2*3 + O(3^2))*T^2 + O(3)*T^3 + O(3)*T^4 + O(T^5) Another example at a prime of bad reduction, where the - `p`-adic L-function has an extra 0 (compared to the non - `p`-adic L-function):: + `p`-adic `L`-function has an extra 0 (compared to the non + `p`-adic `L`-function):: sage: E = EllipticCurve('11a') sage: p = 11 @@ -792,7 +790,7 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): sage: L.series(2) O(11^4) + (10 + O(11))*T + (6 + O(11))*T^2 + (2 + O(11))*T^3 + (5 + O(11))*T^4 + O(T^5) - We compute a `p`-adic L-function that vanishes to order 2:: + We compute a `p`-adic `L`-function that vanishes to order 2:: sage: E = EllipticCurve('389a') sage: p = 3 @@ -813,7 +811,7 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): sage: L.series(3,prec=6) O(3^5) + O(3^2)*T + (2 + 2*3 + O(3^2))*T^2 + (2 + O(3))*T^3 + (1 + O(3))*T^4 + (1 + O(3))*T^5 + O(T^6) - Rather than computing the `p`-adic L-function for the curve '15523a1', one can + Rather than computing the `p`-adic `L`-function for the curve '15523a1', one can compute it as a quadratic_twist:: sage: E = EllipticCurve('43a1') @@ -827,7 +825,7 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): We calculate the `L`-series in the nontrivial Teichmueller components:: - sage: L = EllipticCurve('110a1').padic_lseries(5, implementation="sage") + sage: L = EllipticCurve('110a1').padic_lseries(5, implementation='sage') sage: for j in [0..3]: print(L.series(4, eta=j)) O(5^6) + (2 + 2*5 + 2*5^2 + O(5^3))*T + (5 + 5^2 + O(5^3))*T^2 + (4 + 4*5 + 2*5^2 + O(5^3))*T^3 + (1 + 5 + 3*5^2 + O(5^3))*T^4 + O(T^5) 4 + 3*5 + 2*5^2 + 3*5^3 + 5^4 + O(5^6) + (1 + 3*5 + 4*5^2 + O(5^3))*T + (3 + 4*5 + 3*5^2 + O(5^3))*T^2 + (3 + 3*5^2 + O(5^3))*T^3 + (1 + 2*5 + 2*5^2 + O(5^3))*T^4 + O(T^5) @@ -849,11 +847,11 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): Check that twists by odd Teichmuller characters are ok (:issue:`32258`):: sage: E = EllipticCurve("443c1") - sage: lp = E.padic_lseries(17, implementation="num") + sage: lp = E.padic_lseries(17, implementation='num') sage: l8 = lp.series(2,eta=8,prec=3) sage: l8.list()[0] - 1/lp.alpha() O(17^4) - sage: lp = E.padic_lseries(2, implementation="num") + sage: lp = E.padic_lseries(2, implementation='num') sage: l1 = lp.series(8,eta=1,prec=3) sage: l1.list()[0] - 4/lp.alpha()^2 O(2^9) @@ -984,7 +982,7 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): def is_ordinary(self): r""" - Return ``True`` if the elliptic curve that this L-function is attached + Return ``True`` if the elliptic curve that this `L`-function is attached to is ordinary. EXAMPLES:: @@ -1034,11 +1032,11 @@ def _c_bound(self, sign=+1): 0 sage: EllipticCurve('11a3').padic_lseries(5)._c_bound() 2 - sage: EllipticCurve('11a3').padic_lseries(5, implementation="sage")._c_bound() + sage: EllipticCurve('11a3').padic_lseries(5, implementation='sage')._c_bound() 2 sage: EllipticCurve('50b1').padic_lseries(3)._c_bound() 0 - sage: EllipticCurve('50b1').padic_lseries(3, implementation="sage")._c_bound() + sage: EllipticCurve('50b1').padic_lseries(3, implementation='sage')._c_bound() 1 sage: l = EllipticCurve("11a1").padic_lseries(5) sage: ls = l.series(1,eta=1); @@ -1120,7 +1118,7 @@ def _prec_bounds(self, n, prec, sign=+1): A helper function not designed for direct use. It returns the `p`-adic precisions of the approximation - to the `p`-adic L-function. + to the `p`-adic `L`-function. EXAMPLES:: @@ -1150,13 +1148,13 @@ def _prec_bounds(self, n, prec, sign=+1): class pAdicLseriesSupersingular(pAdicLseries): def series(self, n=3, quadratic_twist=+1, prec=5, eta=0): r""" - Return the `n`-th approximation to the `p`-adic L-series as a + Return the `n`-th approximation to the `p`-adic `L`-series as a power series in `T` (corresponding to `\gamma-1` with `\gamma=1+p` as a generator of `1+p\ZZ_p`). Each coefficient is an element of a quadratic extension of the `p`-adic number whose precision is provably correct. - Here the normalization of the `p`-adic L-series is chosen + Here the normalization of the `p`-adic `L`-series is chosen such that `L_p(E,1) = (1-1/\alpha)^2 L(E,1)/\Omega_E` where `\alpha` is a root of the characteristic polynomial of Frobenius on `T_pE` and `\Omega_E` is the @@ -1170,7 +1168,7 @@ def series(self, n=3, quadratic_twist=+1, prec=5, eta=0): - ``prec`` -- (default: 5) maximal number of terms of the series to compute; to compute as many as possible just give a very large number for ``prec``; the result will still be correct. - - ``eta`` (default: 0) an integer (specifying the power of the + - ``eta`` -- (default: 0) an integer (specifying the power of the Teichmueller character on the group of roots of unity in `\ZZ_p^\times`) @@ -1324,7 +1322,7 @@ def series(self, n=3, quadratic_twist=+1, prec=5, eta=0): def is_ordinary(self): r""" - Return ``True`` if the elliptic curve that this L-function is attached + Return ``True`` if the elliptic curve that this `L`-function is attached to is ordinary. EXAMPLES:: @@ -1353,7 +1351,7 @@ def _prec_bounds(self, n, prec): A helper function not designed for direct use. It returns the `\alpha`-adic precisions of the approximation - to the `p`-adic L-function. + to the `p`-adic `L`-function. EXAMPLES:: @@ -1404,7 +1402,7 @@ def _poly(self, a): def Dp_valued_series(self, n=3, quadratic_twist=+1, prec=5): r""" - Return a vector of two components which are p-adic power series. + Return a vector of two components which are `p`-adic power series. The answer v is such that @@ -1454,7 +1452,7 @@ def Dp_valued_series(self, n=3, quadratic_twist=+1, prec=5): resu = lpv * eps.transpose() return resu - def frobenius(self, prec=20, algorithm="mw"): + def frobenius(self, prec=20, algorithm='mw'): r""" Return a geometric Frobenius `\varphi` on the Dieudonné module `D_p(E)` with respect to the basis `\omega`, the invariant differential, and `\eta=x\omega`. @@ -1535,16 +1533,16 @@ def __phi_bpr(self, prec=0): sage: E = EllipticCurve('11a1') sage: lp = E.padic_lseries(19) - sage: lp.frobenius(prec=1,algorithm="approx") #indirect doctest + sage: lp.frobenius(prec=1,algorithm='approx') #indirect doctest [ O(19^0) 4*19^-1 + O(19^0)] [ 14 + O(19) O(19^0)] sage: E = EllipticCurve('17a1') sage: lp = E.padic_lseries(3) - sage: lp.frobenius(prec=3,algorithm="approx") + sage: lp.frobenius(prec=3,algorithm='approx') [ O(3) 2*3^-1 + 2 + O(3)] [ 1 + O(3^2) O(3)] - sage: lp.frobenius(prec=5,algorithm="approx") + sage: lp.frobenius(prec=5,algorithm='approx') [ 3 + O(3^2) 2*3^-1 + 2 + 3 + O(3^2)] [ 1 + 2*3^2 + O(3^3) 2*3 + O(3^2)] """ @@ -1772,9 +1770,9 @@ def Dp_pairing(vec1,vec2): reg_oe = (reg1 * v2 - reg2 * v1 ) / Dp_pairing(v2, v1) if p < 5: - phi = self.frobenius(min(6, prec), algorithm="approx") + phi = self.frobenius(min(6, prec), algorithm='approx') else: - phi = self.frobenius(prec + 2, algorithm="mw") + phi = self.frobenius(prec + 2, algorithm='mw') c = phi[1, 0] # this is the 'period' [omega,phi(omega)] a = phi[0, 0] diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py old mode 100644 new mode 100755 index fe3a2cbe0cb..87f985e7052 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -25,22 +25,23 @@ from sage.arith.functions import lcm as LCM from sage.arith.misc import valuation -from sage.matrix.constructor import matrix -from sage.misc.misc import newton_method_sizes -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF -from sage.rings.padics.factory import Qp as pAdicField -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -import sage.schemes.hyperelliptic_curves.hypellfrob -import sage.schemes.hyperelliptic_curves.monsky_washnitzer - +from sage.matrix.constructor import Matrix as matrix from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import +from sage.misc.misc import newton_method_sizes from sage.rings.big_oh import O +from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers from sage.rings.integer import Integer from sage.rings.laurent_series_ring import LaurentSeriesRing -from sage.rings.padics.factory import Qp, Zp +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.rational_field import RationalField +import sage.schemes.hyperelliptic_curves.hypellfrob +import sage.schemes.hyperelliptic_curves.monsky_washnitzer + +lazy_import('sage.rings.padics.factory', ['Qp', 'Zp']) + from . import padic_lseries as plseries @@ -62,7 +63,6 @@ def __check_padic_hypotheses(self, p): Traceback (most recent call last): ... ArithmeticError: p must be a good ordinary prime - """ p = Integer(p) if not p.is_prime(): @@ -109,7 +109,7 @@ def _normalize_padic_lseries(self, p, normalize, implementation, precision): def padic_lseries(self, p, normalize=None, implementation='eclib', precision=None): r""" - Return the `p`-adic `L`-series of self at + Return the `p`-adic `L`-series of ``self`` at `p`, which is an object whose approx method computes approximation to the true `p`-adic `L`-series to any desired precision. @@ -189,7 +189,7 @@ def padic_lseries(self, p, normalize=None, implementation='eclib', This may allow for much larger conductor in some instances:: sage: E = EllipticCurve([101,103]) - sage: L = E.padic_lseries(5, implementation="num") + sage: L = E.padic_lseries(5, implementation='num') sage: L.series(2) O(5^4) + (3 + O(5))*T + (1 + O(5))*T^2 + (3 + O(5))*T^3 + O(5)*T^4 + O(T^5) @@ -242,17 +242,16 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): - ``p`` -- prime >= 5 - - ``prec`` -- answer will be returned modulo - `p^{\mathrm{prec}}` + - ``prec`` -- answer will be returned modulo `p^{\mathrm{prec}}` - - ``height`` -- precomputed height function. If not - supplied, this function will call padic_height to compute it. + - ``height`` -- precomputed height function; if not supplied, this function + will call ``padic_height`` to compute it - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic height makes sense + - ``check_hypotheses`` -- boolean; whether to check + that this is a curve for which the `p`-adic height makes sense - OUTPUT: The `p`-adic cyclotomic regulator of this curve, to the - requested precision. + OUTPUT: the `p`-adic cyclotomic regulator of this curve, to the + requested precision If the rank is 0, we output 1. @@ -342,7 +341,7 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses=True): r""" - Computes the cyclotomic `p`-adic height pairing matrix of + Compute the cyclotomic `p`-adic height pairing matrix of this curve with respect to the basis ``self.gens()`` for the Mordell-Weil group for a given odd prime `p` of good ordinary reduction. @@ -352,17 +351,16 @@ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses= - ``p`` -- prime >= 5 - - ``prec`` -- answer will be returned modulo - `p^{\mathrm{prec}}` + - ``prec`` -- answer will be returned modulo `p^{\mathrm{prec}}` - - ``height`` -- precomputed height function. If not - supplied, this function will call padic_height to compute it. + - ``height`` -- precomputed height function; if not supplied, this function + will call ``padic_height`` to compute it - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic height makes sense + - ``check_hypotheses`` -- boolean; whether to check that this is a curve + for which the `p`-adic height makes sense - OUTPUT: The `p`-adic cyclotomic height pairing matrix of this curve - to the given precision. + OUTPUT: the `p`-adic cyclotomic height pairing matrix of this curve + to the given precision AUTHORS: @@ -422,9 +420,10 @@ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses= return M + def _multiply_point(E, R, P, m): r""" - Computes coordinates of a multiple of `P` with entries in a ring. + Compute coordinates of a multiple of `P` with entries in a ring. INPUT: @@ -435,12 +434,13 @@ def _multiply_point(E, R, P, m): non-singular point at all primes - ``R`` -- a ring in which 2 is invertible (typically - `\ZZ/L\ZZ` for some positive odd integer - `L`). + `\ZZ/L\ZZ` for some positive odd integer `L`) - - ``m`` -- an integer, = 1 + - ``m`` -- integer (default: 1) + + OUTPUT: - OUTPUT: A triple `(a', b', d')` such that if the point + A triple `(a', b', d')` such that if the point `mP` has coordinates `(a/d^2, b/d^3)`, then we have `a' \equiv a`, `b' \equiv \pm b`, `d' \equiv \pm d` all in `R` (i.e. modulo @@ -579,6 +579,7 @@ def _multiply_point(E, R, P, m): return theta, omega, psi_m * d + def _multiple_to_make_good_reduction(E): r""" Return the integer `n_2` such that for all points `P` in `E(\QQ)` @@ -591,9 +592,7 @@ def _multiple_to_make_good_reduction(E): - ``E`` -- an elliptic curve over `\QQ` - OUTPUT: - - - a positive integer ``n2`` + OUTPUT: a positive integer ``n2`` EXAMPLE (:issue:`34790`):: @@ -626,7 +625,6 @@ def _multiple_to_make_good_reduction(E): sage: E = EllipticCurve([0,-3^2,0,0,3^7]) # min eq is non-split mult sage: _multiple_to_make_good_reduction(E) 4 - """ if not E.is_integral(): st = ("This only implemented for integral models. " @@ -657,6 +655,7 @@ def _multiple_to_make_good_reduction(E): n2 = LCM(li) return n2 + def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): r""" Compute the cyclotomic `p`-adic height. @@ -665,23 +664,24 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): INPUT: - - ``p`` -- prime >= 5 for which the curve has - semi-stable reduction + - ``p`` -- prime >= 5 for which the curve has semi-stable reduction + + - ``prec`` -- integer >= 1 (default: 20); desired precision of result - - ``prec`` -- integer >= 1 (default 20), desired precision of result + - ``sigma`` -- precomputed value of sigma; if not supplied, this function + will call ``padic_sigma`` to compute it - - ``sigma`` -- precomputed value of sigma. If not - supplied, this function will call padic_sigma to compute it. + - ``check_hypotheses`` -- boolean; whether to check that this is a curve + for which the `p`-adic height makes sense - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic height makes sense + OUTPUT: - OUTPUT: A function that accepts two parameters: + A function that accepts two parameters: - a `\QQ`-rational point on the curve whose height should be computed - - optional boolean flag 'check': if False, it skips some input - checking, and returns the p-adic height of that point to the + - optional boolean flag 'check': if ``False``, it skips some input + checking, and returns the `p`-adic height of that point to the desired precision. - The normalization (sign and a factor 1/2 with respect to some other @@ -863,36 +863,37 @@ def height(P, check=True): def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): r""" - Computes the cyclotomic `p`-adic height. + Compute the cyclotomic `p`-adic height. The equation of the curve must be minimal at `p`. INPUT: - - ``p`` -- prime >= 5 for which the curve has good - ordinary reduction + - ``p`` -- prime >= 5 for which the curve has good ordinary reduction - - ``prec`` -- integer >= 2 (default 20), desired precision of result + - ``prec`` -- integer >= 2 (default: 20); desired precision of result - ``E2`` -- precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied must be correct mod `p^{prec-2}` (or slightly higher in the anomalous case; see the code for details). - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic height makes sense + - ``check_hypotheses`` -- boolean; whether to check + that this is a curve for which the `p`-adic height makes sense + + OUTPUT: - OUTPUT: A function that accepts two parameters: + A function that accepts two parameters: - a `\QQ`-rational point on the curve whose height should be computed - - optional boolean flag 'check': if False, it skips some input + - optional boolean flag 'check': if ``False``, it skips some input checking, and returns the `p`-adic height of that point to the desired precision. - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way - as to make the p-adic Birch Swinnerton-Dyer conjecture hold as stated + as to make the `p`-adic Birch Swinnerton-Dyer conjecture hold as stated in [MTT1986]_. AUTHORS: @@ -1007,7 +1008,7 @@ def height(P, check=True): def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): r""" - Computes the `p`-adic sigma function with respect to the standard + Compute the `p`-adic sigma function with respect to the standard invariant differential `dx/(2y + a_1 x + a_3)`, as defined by Mazur and Tate in [MT1991]_, as a power series in the usual uniformiser `t` at the origin. @@ -1016,30 +1017,26 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): INPUT: - - ``p`` -- prime >= 5 for which the curve has good - ordinary reduction + - ``p`` -- prime >= 5 for which the curve has good ordinary reduction - - ``N`` -- integer >= 1 (default 20), indicates precision of result; + - ``N`` -- integer >= 1 (default: 20); precision of result, see OUTPUT section for description - ``E2`` -- precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied must be correct mod `p^{N-2}`. - - ``check`` -- boolean, whether to perform a + - ``check`` -- boolean; whether to perform a consistency check (i.e. verify that the computed sigma satisfies the defining - - ``differential equation`` -- note that this does NOT - guarantee correctness of all the returned digits, but it comes - pretty close. + - ``differential equation`` -- note that this does NOT guarantee + correctness of all the returned digits, but it comes pretty close - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic sigma function makes - sense + - ``check_hypotheses`` -- boolean; whether to check that this is a curve + for which the `p`-adic sigma function makes sense - OUTPUT: A power series `t + \cdots` with coefficients in - `\ZZ_p`. + OUTPUT: a power series `t + \cdots` with coefficients in `\ZZ_p` The output series will be truncated at `O(t^{N+1})`, and the coefficient of `t^n` for `n \geq 1` will be @@ -1188,7 +1185,7 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): # [Note: there are actually more digits available, but it's a bit # tricky to figure out exactly how many, and we only need p^(N-k+1) # for p-adic height purposes anyway] - K = pAdicField(p, N + 1) + K = Qp(p, N + 1) sigma = sigma.padded_list(N+1) @@ -1227,7 +1224,7 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True): r""" - Compute the p-adic sigma function with respect to the standard + Compute the `p`-adic sigma function with respect to the standard invariant differential `dx/(2y + a_1 x + a_3)`, as defined by Mazur and Tate in [MT1991]_, as a power series in the usual uniformiser `t` at the origin. @@ -1239,25 +1236,21 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) INPUT: - - ``p`` -- prime >= 5 for which the curve has good - ordinary reduction + - ``p`` -- prime >= 5 for which the curve has good ordinary reduction - - ``N`` -- integer >= 2 (default 20), indicates precision of result; + - ``N`` -- integer >= 2 (default: 20); precision of result, see OUTPUT section for description - - ``lamb`` -- integer >= 0, see OUTPUT section for - description + - ``lamb`` -- integer >= 0; see OUTPUT section for description - ``E2`` -- precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied must be correct mod `p^{N-2}`. - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic sigma function makes - sense + - ``check_hypotheses`` -- boolean; whether to check that this is a curve + for which the `p`-adic sigma function makes sense - OUTPUT: A power series `t + \cdots` with coefficients in - `\ZZ_p`. + OUTPUT: a power series `t + \cdots` with coefficients in `\ZZ_p` The coefficient of `t^j` for `j \geq 1` will be correct to precision `O(p^{N - 2 + (3 - j)(lamb + 1)})`. @@ -1372,7 +1365,7 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) # Convert the answer to power series over p-adics; drop the precision # of the t^j coefficient to p^{N - 2 + (3 - j)(lamb + 1)}). - K = pAdicField(p, N - 2 + 3*(lamb+1)) + K = Qp(p, N - 2 + 3*(lamb+1)) sigma = sigma.padded_list(trunc+1) @@ -1387,50 +1380,46 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) return sigma -def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="auto"): +def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm='auto'): r""" - Returns the value of the `p`-adic modular form `E2` + Return the value of the `p`-adic modular form `E2` for `(E, \omega)` where `\omega` is the usual invariant differential `dx/(2y + a_1 x + a_3)`. INPUT: - - ``p`` -- prime (= 5) for which `E` is good - and ordinary + - ``p`` -- prime (= 5) for which `E` is good and ordinary - - ``prec`` -- (relative) p-adic precision (= 1) for - result + - ``prec`` -- (relative) `p`-adic precision (= 1) for result - - ``check`` -- boolean, whether to perform a - consistency check. This will slow down the computation by a - constant factor 2. (The consistency check is to compute the whole - matrix of frobenius on Monsky-Washnitzer cohomology, and verify - that its trace is correct to the specified precision. Otherwise, - the trace is used to compute one column from the other one - (possibly after a change of basis).) + - ``check`` -- boolean; whether to perform a consistency check. This will + slow down the computation by a constant factor 2. (The consistency check + is to compute the whole matrix of frobenius on Monsky-Washnitzer + cohomology, and verify that its trace is correct to the specified + precision. Otherwise, the trace is used to compute one column from the + other one (possibly after a change of basis).) - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the p-adic sigma function makes - sense + - ``check_hypotheses`` -- boolean; whether to check that this is a curve + for which the `p`-adic sigma function makes sense - - ``algorithm`` -- one of "standard", "sqrtp", or - "auto". This selects which version of Kedlaya's algorithm is used. - The "standard" one is the one described in Kedlaya's paper. The - "sqrtp" one has better performance for large `p`, but only - works when `p > 6N` (`N=` prec). The "auto" option - selects "sqrtp" whenever possible. + - ``algorithm`` -- one of ``'standard'``, ``'sqrtp'``, or + ``'auto'``. This selects which version of Kedlaya's algorithm is used. + The ``'standard'`` one is the one described in Kedlaya's paper. The + ``'sqrtp'`` one has better performance for large `p`, but only + works when `p > 6N` (`N=` ``prec``). The ``'auto'`` option + selects ``'sqrtp'`` whenever possible. - Note that if the "sqrtp" algorithm is used, a consistency check + Note that if the ``'sqrtp'`` algorithm is used, a consistency check will automatically be applied, regardless of the setting of the - "check" flag. + ``check`` flag. - OUTPUT: p-adic number to precision prec + OUTPUT: `p`-adic number to precision ``prec`` .. NOTE:: If the discriminant of the curve has nonzero valuation at p, then the result will not be returned mod `p^\text{prec}`, - but it still *will* have prec *digits* of precision. + but it still *will* have ``prec`` *digits* of precision. .. TODO:: @@ -1467,9 +1456,9 @@ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="au sage: EllipticCurve([-1, 1/4]).padic_E2(5, 3) 2 + 4*5 + O(5^3) - TODO: With the old(-er), i.e., = sage-2.4 p-adics we got + TODO: With the old(-er), i.e., = sage-2.4 `p`-adics we got `5 + O(5^2)` as output, i.e., relative precision 1, but - with the newer p-adics we get relative precision 0 and absolute + with the newer `p`-adics we get relative precision 0 and absolute precision 1. :: @@ -1541,7 +1530,7 @@ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="au Here's one using the `p^{1/2}` algorithm:: - sage: EllipticCurve([-1, 1/4]).padic_E2(3001, 3, algorithm="sqrtp") + sage: EllipticCurve([-1, 1/4]).padic_E2(3001, 3, algorithm='sqrtp') 1907 + 2819*3001 + 1124*3001^2 + O(3001^3) """ if self.conductor() % p == 0: @@ -1555,7 +1544,7 @@ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="au frob_p_n = frob_p**prec # todo: think about the sign of this. Is it correct? - output_ring = pAdicField(p, prec) + output_ring = Qp(p, prec) E2_of_X = output_ring( (-12 * frob_p_n[0,1] / frob_p_n[1,1]).lift() ) \ + O(p**prec) @@ -1573,40 +1562,37 @@ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="au return output_ring(E2_of_X * fudge_factor_inverse) -def matrix_of_frobenius(self, p, prec=20, check=False, check_hypotheses=True, algorithm="auto"): +def matrix_of_frobenius(self, p, prec=20, check=False, check_hypotheses=True, algorithm='auto'): r""" - Returns the matrix of Frobenius on the Monsky Washnitzer cohomology of + Return the matrix of Frobenius on the Monsky Washnitzer cohomology of the short Weierstrass model of the minimal model of the elliptic curve. INPUT: - - ``p`` -- prime (>= 3) for which `E` is good - and ordinary + - ``p`` -- prime (>= 3) for which `E` is good and ordinary - - ``prec`` -- (relative) `p`-adic precision for - result (default 20) + - ``prec`` -- (relative) `p`-adic precision for result (default: 20) - - ``check`` -- boolean (default: ``False``), whether to perform a + - ``check`` -- boolean (default: ``False``); whether to perform a consistency check. This will slow down the computation by a constant factor 2. (The consistency check is to verify that its trace is correct to the specified precision. Otherwise, the trace is used to compute one column from the other one (possibly after a change of basis).) - - ``check_hypotheses`` -- boolean, whether to check - that this is a curve for which the `p`-adic sigma function makes - sense + - ``check_hypotheses`` -- boolean; whether to check that this is a curve + for which the `p`-adic sigma function makes sense - - ``algorithm`` -- one of "standard", "sqrtp", or - "auto". This selects which version of Kedlaya's algorithm is used. - The "standard" one is the one described in Kedlaya's paper. The - "sqrtp" one has better performance for large `p`, but only - works when `p > 6N` (`N=` prec). The "auto" option - selects "sqrtp" whenever possible. + - ``algorithm`` -- one of ``'standard'``, ``'sqrtp'``, or + ``'auto'``. This selects which version of Kedlaya's algorithm is used. + The ``'standard'`` one is the one described in Kedlaya's paper. The + ``'sqrtp'`` one has better performance for large `p`, but only + works when `p > 6N` (`N=` prec). The ``'auto'`` option + selects ``'sqrtp'`` whenever possible. - Note that if the "sqrtp" algorithm is used, a consistency check + Note that if the ``'sqrtp'`` algorithm is used, a consistency check will automatically be applied, regardless of the setting of the - "check" flag. + ``check`` flag. OUTPUT: a matrix of `p`-adic number to precision ``prec`` diff --git a/src/sage/schemes/elliptic_curves/period_lattice.py b/src/sage/schemes/elliptic_curves/period_lattice.py old mode 100644 new mode 100755 index aa4662a85ac..e6008a09279 --- a/src/sage/schemes/elliptic_curves/period_lattice.py +++ b/src/sage/schemes/elliptic_curves/period_lattice.py @@ -108,21 +108,20 @@ import sage.rings.abc -from sage.libs.pari.all import pari from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.modules.free_module import FreeModule_generic_pid -from sage.rings.complex_mpfr import ComplexField -from sage.rings.complex_mpfr import ComplexNumber +from sage.rings.complex_mpfr import ComplexField, ComplexNumber from sage.rings.infinity import Infinity from sage.rings.integer_ring import ZZ -from sage.rings.number_field.number_field import refine_embedding -from sage.rings.qqbar import AA, QQbar from sage.rings.rational_field import QQ -from sage.rings.real_mpfr import RealField -from sage.rings.real_mpfr import RealNumber as RealNumber +from sage.rings.real_mpfr import RealField, RealNumber from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage.structure.richcmp import richcmp_method, richcmp, richcmp_not_equal +lazy_import('sage.libs.pari.all', 'pari') +lazy_import('sage.rings.number_field.number_field', 'refine_embedding') + class PeriodLattice(FreeModule_generic_pid): """ @@ -150,9 +149,8 @@ def __init__(self, E, embedding=None): - ``E`` -- an elliptic curve - - ``embedding`` (default: ``None``) -- an embedding of the base - field `K` of ``E`` into a real or complex field. If - ``None``: + - ``embedding`` -- (default: ``None``) an embedding of the base + field `K` of ``E`` into a real or complex field. If ``None``: - use the built-in coercion to `\RR` for `K=\QQ`; @@ -215,6 +213,8 @@ def __init__(self, E, embedding=None): sage: L == loads(dumps(L)) True """ + from sage.rings.qqbar import AA, QQbar + # First we cache the elliptic curve with this period lattice: self.E = E @@ -280,7 +280,7 @@ def __init__(self, E, embedding=None): def __richcmp__(self, other, op): r""" - Comparison function for period lattices + Comparison function for period lattices. TESTS:: @@ -339,11 +339,11 @@ def __call__(self, P, prec=None): INPUT: - - ``P`` (point) -- a point on the elliptic curve associated - with this period lattice. + - ``P`` -- a point on the elliptic curve associated with this period + lattice - - ``prec`` (default: ``None``) -- precision in bits (default - precision if ``None``). + - ``prec`` -- (default: ``None``) precision in bits (default + precision if ``None``) OUTPUT: @@ -400,20 +400,20 @@ def basis(self, prec=None, algorithm='sage'): INPUT: - - ``prec`` (default: ``None``) -- precision in bits (default - precision if ``None``). + - ``prec`` -- (default: ``None``) precision in bits (default + precision if ``None``) - - ``algorithm`` (string, default ``'sage'``) -- choice of + - ``algorithm`` -- string (default: ``'sage'``); choice of implementation (for real embeddings only) between ``'sage'`` (native Sage implementation) or ``'pari'`` (use the PARI - library: only available for real embeddings). + library: only available for real embeddings) OUTPUT: (tuple of Complex) `(\omega_1,\omega_2)` where the lattice is `\ZZ\omega_1 + \ZZ\omega_2`. If the lattice is real then `\omega_1` is real and positive, `\Im(\omega_2)>0` and - `\Re(\omega_1/\omega_2)` is either `0` (for rectangular + `\Re(\omega_2/\omega_1)` is either `0` (for rectangular lattices) or `\frac{1}{2}` (for non-rectangular lattices). Otherwise, `\omega_1/\omega_2` is in the fundamental region of the upper half-plane. If the latter normalisation is required @@ -485,20 +485,20 @@ def gens(self, prec=None, algorithm='sage'): INPUT: - - ``prec`` (default: ``None``) -- precision in bits (default - precision if ``None``). + - ``prec`` -- (default: ``None``) precision in bits (default + precision if ``None``) - - ``algorithm`` (string, default ``'sage'``) -- choice of + - ``algorithm`` -- string (default: ``'sage'``); choice of implementation (for real embeddings only) between ``'sage'`` (native Sage implementation) or ``'pari'`` (use the PARI - library: only available for real embeddings). + library: only available for real embeddings) OUTPUT: (tuple of Complex) `(\omega_1,\omega_2)` where the lattice is `\ZZ\omega_1 + \ZZ\omega_2`. If the lattice is real then `\omega_1` is real and positive, `\Im(\omega_2)>0` and - `\Re(\omega_1/\omega_2)` is either `0` (for rectangular + `\Re(\omega_2/\omega_1)` is either `0` (for rectangular lattices) or `\frac{1}{2}` (for non-rectangular lattices). Otherwise, `\omega_1/\omega_2` is in the fundamental region of the upper half-plane. If the latter normalisation is required @@ -523,13 +523,13 @@ def normalised_basis(self, prec=None, algorithm='sage'): INPUT: - - ``prec`` (default: ``None``) -- precision in bits (default - precision if ``None``). + - ``prec`` -- (default: ``None``) precision in bits (default + precision if ``None``) - - ``algorithm`` (string, default ``'sage'``) -- choice of + - ``algorithm`` -- string (default: ``'sage'``); choice of implementation (for real embeddings only) between ``'sage'`` (native Sage implementation) or ``'pari'`` (use the PARI - library: only available for real embeddings). + library: only available for real embeddings) OUTPUT: @@ -580,13 +580,13 @@ def tau(self, prec=None, algorithm='sage'): INPUT: - - ``prec`` (default: ``None``) -- precision in bits (default - precision if ``None``). + - ``prec`` -- (default: ``None``) precision in bits (default + precision if ``None``) - - ``algorithm`` (string, default 'sage') -- choice of + - ``algorithm`` -- string (default: ``'sage'``); choice of implementation (for real embeddings only) between 'sage' (native Sage implementation) or 'pari' (use the PARI - library: only available for real embeddings). + library: only available for real embeddings) OUTPUT: @@ -637,19 +637,20 @@ def _compute_periods_real(self, prec=None, algorithm='sage'): INPUT: - - `prec` (int or ``None`` (default)) -- floating point - precision (in bits); if None, use the default precision. + - ``prec`` -- integer or ``None`` (default); floating point + precision (in bits). If ``None``, use the default precision. + + - ``algorithm`` string (default: ``'sage'``); choice of implementation between - - `algorithm` (string, default 'sage') -- choice of implementation between - - `pari`: use the PARI library + - ``'pari'`` -- use the PARI library - - `sage`: use a native Sage implementation (with the same underlying algorithm). + - ``'sage'`` -- use a native Sage implementation (with the same underlying algorithm) OUTPUT: (tuple of Complex) `(\omega_1,\omega_2)` where the lattice has the form `\ZZ\omega_1 + \ZZ\omega_2`, `\omega_1` is real and - `\omega_1/\omega_2` has real part either `0` or `frac{1}{2}`. + `\omega_2/\omega_1` has real part either `0` or `frac{1}{2}`. EXAMPLES:: @@ -710,17 +711,17 @@ def _compute_periods_complex(self, prec=None, normalise=True): INPUT: - - ``prec`` (integer or ``None`` (default)) -- floating point precision (in bits); if ``None``, - use the default precision. + - ``prec`` -- integer or ``None`` (default); floating point precision + (in bits); if ``None``, use the default precision - - ``normalise`` (bool, default ``True``) -- whether to normalise the - basis after computation. + - ``normalise`` -- boolean (default: ``True``); whether to normalise the + basis after computation OUTPUT: (tuple of Complex) `(\omega_1,\omega_2)` where the lattice has the form `\ZZ\omega_1 + \ZZ\omega_2`. If `normalise` is - `True`, the basis is normalised so that `(\omega_1/\omega_2)` + ``True``, the basis is normalised so that `(\omega_1/\omega_2)` is in the fundamental region of the upper half plane. EXAMPLES:: @@ -819,7 +820,7 @@ def is_rectangular(self) -> bool: .. NOTE:: - Only defined for real lattices; a :class:`RuntimeError` + Only defined for real lattices; a :exc:`RuntimeError` is raised for non-real lattices. EXAMPLES:: @@ -854,17 +855,17 @@ def real_period(self, prec=None, algorithm='sage'): INPUT: - - ``prec`` (integer or ``None`` (default)) -- real precision in + - ``prec`` -- integer or ``None`` (default); real precision in bits (default real precision if ``None``) - - ``algorithm`` (string, default ``'sage'``) -- choice of + - ``algorithm`` -- string (default: ``'sage'``); choice of implementation (for real embeddings only) between ``'sage'`` (native Sage implementation) or ``'pari'`` (use the PARI - library: only available for real embeddings). + library: only available for real embeddings) .. NOTE:: - Only defined for real lattices; a :class:`RuntimeError` + Only defined for real lattices; a :exc:`RuntimeError` is raised for non-real lattices. EXAMPLES:: @@ -894,11 +895,11 @@ def omega(self, prec=None, bsd_normalise=False): INPUT: - - ``prec`` (int or ``None`` (default)) -- real precision in + - ``prec`` -- integer or ``None`` (default); real precision in bits (default real precision if ``None``) - - ``bsd_normalise`` (bool, default ``False``) -- flag to use - BSD normalisation in the complex case. + - ``bsd_normalise`` -- boolean (default: ``False``); flag to use + BSD normalisation in the complex case OUTPUT: @@ -977,12 +978,12 @@ def basis_matrix(self, prec=None, normalised=False): INPUT: - - ``prec`` (int or ``None`` (default)) -- real precision in - bits (default real precision if ``None``). + - ``prec`` -- integer or ``None`` (default); real precision in + bits (default real precision if ``None``) - - ``normalised`` (bool, default ``False``) -- if ``True`` and the + - ``normalised`` -- boolean (default: ``False``); if ``True`` and the embedding is real, use the normalised basis (see - :meth:`normalised_basis`) instead of the default. + :meth:`normalised_basis`) instead of the default OUTPUT: @@ -1046,8 +1047,8 @@ def complex_area(self, prec=None): INPUT: - - ``prec`` (int or ``None`` (default)) -- real precision in - bits (default real precision if ``None``). + - ``prec`` -- integer or ``None`` (default); real precision in + bits (default real precision if ``None``) EXAMPLES:: @@ -1078,8 +1079,8 @@ def sigma(self, z, prec=None, flag=0): - ``z`` -- a complex number - - ``prec`` (default: ``None``) -- real precision in bits - (default real precision if ``None``). + - ``prec`` -- (default: ``None``) real precision in bits + (default real precision if ``None``) - ``flag`` -- @@ -1179,14 +1180,14 @@ def ei(self): def coordinates(self, z, rounding=None): r""" - Return the coordinates of a complex number w.r.t. the lattice basis + Return the coordinates of a complex number w.r.t. the lattice basis. INPUT: - - ``z`` (complex) -- A complex number. + - ``z`` -- complex number - - ``rounding`` (default ``None``) -- whether and how to round the - output (see below). + - ``rounding`` -- (default: ``None``) whether and how to round the + output (see below) OUTPUT: @@ -1256,11 +1257,11 @@ def coordinates(self, z, rounding=None): def reduce(self, z): r""" - Reduce a complex number modulo the lattice + Reduce a complex number modulo the lattice. INPUT: - - ``z`` (complex) -- A complex number. + - ``z`` -- complex number OUTPUT: @@ -1335,11 +1336,11 @@ def e_log_RC(self, xP, yP, prec=None, reduce=True): the embedded elliptic curve associated with this period lattice. - - ``prec`` (default: ``None``) -- real precision in bits - (default real precision if None). + - ``prec`` -- (default: ``None``) real precision in bits + (default real precision if ``None``) - - ``reduce`` (default: ``True``) -- if ``True``, the result - is reduced with respect to the period lattice basis. + - ``reduce`` -- boolean (default: ``True``); if ``True``, the result + is reduced with respect to the period lattice basis OUTPUT: @@ -1535,14 +1536,14 @@ def elliptic_logarithm(self, P, prec=None, reduce=True): INPUT: - - ``P`` (point) -- A point on the elliptic curve associated - with this period lattice. + - ``P`` -- point on the elliptic curve associated with this period + lattice - - ``prec`` (default: ``None``) -- real precision in bits - (default real precision if ``None``). + - ``prec`` -- (default: ``None``) real precision in bits + (default real precision if ``None``) - - ``reduce`` (default: ``True``) -- if ``True``, the result - is reduced with respect to the period lattice basis. + - ``reduce`` -- boolean (default: ``True``); if ``True``, the result + is reduced with respect to the period lattice basis OUTPUT: @@ -1730,9 +1731,9 @@ def elliptic_exponential(self, z, to_curve=True): INPUT: - - ``z`` (complex) -- A complex number (viewed modulo this period lattice). + - ``z`` -- complex number (viewed modulo this period lattice) - - ``to_curve`` (bool, default ``True``): see below. + - ``to_curve`` -- boolean (default: ``True``); see below OUTPUT: @@ -1942,7 +1943,7 @@ def reduce_tau(tau): INPUT: - - ``tau`` (complex) -- a complex number with positive imaginary part + - ``tau`` -- complex number with positive imaginary part OUTPUT: @@ -2037,11 +2038,11 @@ def extended_agm_iteration(a, b, c): INPUT: - - ``a``, ``b``, ``c`` (real or complex) -- three real or complex numbers. + - ``a``, ``b``, ``c`` -- three real or complex numbers OUTPUT: - (3-tuple) `(a_0,b_0,c_0)`, the limit of the iteration `(a,b,c) \mapsto ((a+b)/2,\sqrt{ab},(c+\sqrt(c^2+b^2-a^2))/2)`. + (3-tuple) `(a_0,b_0,c_0)`, the limit of the iteration `(a,b,c) \mapsto ((a+b)/2,\sqrt{ab},(c+\sqrt{c^2+b^2-a^2})/2)`. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/period_lattice_region.pyx b/src/sage/schemes/elliptic_curves/period_lattice_region.pyx old mode 100644 new mode 100755 index 8f240627e77..40b92ab23eb --- a/src/sage/schemes/elliptic_curves/period_lattice_region.pyx +++ b/src/sage/schemes/elliptic_curves/period_lattice_region.pyx @@ -72,11 +72,13 @@ cdef class PeriodicRegion: def is_empty(self): """ - Returns whether this region is empty. + Return whether this region is empty. EXAMPLES:: sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion sage: data = np.zeros((4, 4)) sage: PeriodicRegion(CDF(2), CDF(2*I), data).is_empty() @@ -89,10 +91,10 @@ cdef class PeriodicRegion: def _ensure_full(self): """ - Ensure the bitmap in self.data represents the entire fundamental + Ensure the bitmap in ``self.data`` represents the entire fundamental parallelogram, expanding symmetry by duplicating data if necessary. - Mutates and returns self. + Mutates and returns ``self``. EXAMPLES:: @@ -124,7 +126,7 @@ cdef class PeriodicRegion: def ds(self): """ - Returns the sides of each parallelogram tile. + Return the sides of each parallelogram tile. EXAMPLES:: @@ -153,12 +155,12 @@ cdef class PeriodicRegion: INPUT: - - ``condition`` (function) -- a boolean-valued function on `\CC`. + - ``condition`` -- boolean-valued function on `\CC` OUTPUT: - True or False according to whether the condition holds for all - lines on the boundary. + boolean according to whether the condition holds for all lines on the + boundary. EXAMPLES:: @@ -187,15 +189,13 @@ cdef class PeriodicRegion: INPUT: - - ``condition`` (function, default None) -- if not None, only - keep tiles in the refinement which satisfy the condition. + - ``condition`` -- function (default: ``None``); if not ``None``, only + keep tiles in the refinement which satisfy the condition - - ``times`` (int, default 1) -- the number of times to refine; - each refinement step halves the mesh size. + - ``times`` -- integer (default: 1); the number of times to refine. + Each refinement step halves the mesh size. - OUTPUT: - - The refined PeriodicRegion. + OUTPUT: the refined PeriodicRegion EXAMPLES:: @@ -241,7 +241,7 @@ cdef class PeriodicRegion: def expand(self, bint corners=True): """ - Returns a region containing this region by adding all neighbors of + Return a region containing this region by adding all neighbors of internal tiles. EXAMPLES:: @@ -295,6 +295,8 @@ cdef class PeriodicRegion: EXAMPLES:: sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion sage: data = np.zeros((10, 10)) sage: data[1:4,1:4] = True @@ -312,11 +314,13 @@ cdef class PeriodicRegion: def __contains__(self, z): """ - Returns whether this region contains the given point. + Return whether this region contains the given point. EXAMPLES:: sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion sage: data = np.zeros((4, 4)) sage: data[1,1] = True @@ -361,7 +365,7 @@ cdef class PeriodicRegion: def __truediv__(self, unsigned int n): """ - Returns a new region of the same resolution that is the image + Return a new region of the same resolution that is the image of this region under the map z -> z/n. The resolution is the same, so some detail may be lost. The result is @@ -370,6 +374,8 @@ cdef class PeriodicRegion: EXAMPLES:: sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion sage: data = np.zeros((20, 20)) @@ -437,7 +443,7 @@ cdef class PeriodicRegion: def __invert__(self): """ - Returns the complement of this region. + Return the complement of this region. EXAMPLES:: @@ -459,7 +465,7 @@ cdef class PeriodicRegion: def __and__(left, right): """ - Returns the intersection of left and right. + Return the intersection of ``left`` and ``right``. EXAMPLES:: @@ -486,7 +492,8 @@ cdef class PeriodicRegion: def __xor__(left, right): """ - Returns the union of left and right less the intersection of left and right. + Return the union of ``left`` and ``right`` minus the intersection of + ``left`` and ``right``. EXAMPLES:: @@ -520,6 +527,8 @@ cdef class PeriodicRegion: TESTS:: sage: import numpy as np + sage: if int(np.version.short_version[0]) > 1: + ....: np.set_printoptions(legacy="1.25") sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion sage: data = np.zeros((4, 4)) sage: data[1, 1] = True @@ -552,7 +561,7 @@ cdef class PeriodicRegion: def border(self, raw=True): """ - Returns the boundary of this region as set of tile boundaries. + Return the boundary of this region as set of tile boundaries. If raw is true, returns a list with respect to the internal bitmap, otherwise returns complex intervals covering the border. diff --git a/src/sage/schemes/elliptic_curves/saturation.py b/src/sage/schemes/elliptic_curves/saturation.py old mode 100644 new mode 100755 index 936948a4267..16c44f16d0a --- a/src/sage/schemes/elliptic_curves/saturation.py +++ b/src/sage/schemes/elliptic_curves/saturation.py @@ -54,21 +54,20 @@ from sage.arith.misc import kronecker as kro from sage.structure.sage_object import SageObject + def reduce_mod_q(x, amodq): r"""The reduction of ``x`` modulo the prime ideal defined by ``amodq``. INPUT: - - ``x`` -- an element of a number field `K`. + - ``x`` -- an element of a number field `K` - ``amodq`` -- an element of `GF(q)` which is a root mod `q` of the defining polynomial of `K`. This defines a degree 1 prime ideal `Q=(q,\alpha-a)` of `K=\QQ(\alpha)`, where `a \bmod q` = ``amodq``. - OUTPUT: - - The image of ``x`` in the residue field of `K` at the prime `Q`. + OUTPUT: the image of ``x`` in the residue field of `K` at the prime `Q` EXAMPLES:: @@ -90,15 +89,16 @@ def reduce_mod_q(x, amodq): except AttributeError: # in case x is in QQ return Fq(x) + class EllipticCurveSaturator(SageObject): r""" Class for saturating points on an elliptic curve over a number field. INPUT: - - ``E`` -- an elliptic curve defined over a number field, or `\QQ`. + - ``E`` -- an elliptic curve defined over a number field, or `\QQ` - - ``verbose`` (boolean, default ``False``) -- verbosity flag. + - ``verbose`` -- boolean (default: ``False``); verbosity flag .. NOTE:: @@ -112,9 +112,9 @@ def __init__(self, E, verbose=False): INPUT: - - ``E`` -- an elliptic curve defined over a number field. + - ``E`` -- an elliptic curve defined over a number field - - ``verbose`` (boolean, default ``False``) -- verbosity flag. + - ``verbose`` -- boolean (default: ``False``); verbosity flag """ self._verbose = verbose self._curve = E @@ -143,7 +143,7 @@ def add_reductions(self, q): INPUT: - ``q`` -- a prime number not dividing the defining polynomial - of ``self.__field``. + of ``self.__field`` OUTPUT: @@ -211,9 +211,9 @@ def full_p_saturation(self, Plist, p): INPUT: - - ``Plist`` (list) -- a list of independent points on one elliptic curve. + - ``Plist`` -- list of independent points on one elliptic curve - - ``p`` (integer) -- a prime number. + - ``p`` -- integer; a prime number OUTPUT: @@ -302,12 +302,12 @@ def p_saturation(self, Plist, p, sieve=True): INPUT: - - ``Plist`` (list) -- a list of independent points on one elliptic curve. + - ``Plist`` -- list of independent points on one elliptic curve - - ``p`` (integer) -- a prime number. + - ``p`` -- integer; a prime number - - ``sieve`` (boolean) -- if True, use a sieve (when there are at - least 2 points); otherwise test all combinations. + - ``sieve`` -- boolean; if ``True``, use a sieve (when there are at + least 2 points), otherwise test all combinations .. NOTE:: @@ -340,7 +340,7 @@ def p_saturation(self, Plist, p, sieve=True): False Here we see an example where 19-saturation is proved, with the - verbose flag set to True so that we can see what is going on:: + verbose flag set to ``True`` so that we can see what is going on:: sage: saturator = EllipticCurveSaturator(EK, verbose=True) sage: saturator.p_saturation([P, Q, R], 19) @@ -386,7 +386,7 @@ def p_saturation(self, Plist, p, sieve=True): -- points were not 2-saturated, gaining index 2 (1, (0 : 1 : 0)) - A CM example where large siecing primes are needed (LMFDB + A CM example where large sieving primes are needed (LMFDB label 2.0.3.1-50625.1-CMb2):: sage: K. = NumberField(x^2 - x + 1) @@ -573,7 +573,7 @@ def p_saturation(self, Plist, p, sieve=True): # really is p*R. Now to enlarge the # span, we may replce the j'th point # in Plist with R, where v[j] is - # non-zero. + # nonzero. if verbose: print("-- points were not {}-saturated, gaining index {}".format(p,p)) j = next(i for i,x in enumerate(v) if x) @@ -587,16 +587,17 @@ def p_saturation(self, Plist, p, sieve=True): rankA = newrank count = 0 + def p_projections(Eq, Plist, p, debug=False): r""" INPUT: - - ``Eq`` -- An elliptic curve over a finite field. + - ``Eq`` -- an elliptic curve over a finite field - - ``Plist`` -- a list of points on `Eq`. + - ``Plist`` -- list of points on `Eq` - - ``p`` -- a prime number. + - ``p`` -- a prime number OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py old mode 100644 new mode 100755 index 6c8cf3c986f..83922981a63 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -14,7 +14,7 @@ But it is not known in general. A theorem of Kolyvagin and Gross-Zagier using Heegner points shows that if the -L-series of an elliptic curve `E/\QQ` does not vanish at 1 or has a simple +`L`-series of an elliptic curve `E/\QQ` does not vanish at 1 or has a simple zero there, then `Sha` is finite. A theorem of Kato, together with theorems from Iwasawa theory, allows for @@ -22,7 +22,7 @@ gives an effective upper bound for it. The (`p`-adic) conjecture of Birch and Swinnerton-Dyer predicts the order of -`Sha` from the leading term of the (`p`-adic) L-series of the elliptic curve. +`Sha` from the leading term of the (`p`-adic) `L`-series of the elliptic curve. Sage can compute a few things about `Sha`. The commands ``an``, ``an_numerical`` and ``an_padic`` compute the conjectural order of `Sha` as a @@ -77,19 +77,23 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** + from math import sqrt -from sage.functions.log import log +import sage.arith.all as arith + +from sage.misc.lazy_import import lazy_import from sage.misc.verbose import verbose from sage.modules.free_module_element import vector from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.rings.padics.factory import Qp from sage.rings.rational_field import Q from sage.rings.real_mpfi import RIF from sage.rings.real_mpfr import RealField from sage.structure.sage_object import SageObject -import sage.arith.all as arith + +lazy_import("sage.functions.log", "log") +lazy_import("sage.rings.padics.factory", "Qp") factor = arith.factor valuation = arith.valuation @@ -139,7 +143,7 @@ def __init__(self, E): INPUT: - - E -- an elliptic curve over `\QQ` + - ``E`` -- an elliptic curve over `\QQ` EXAMPLES:: @@ -209,11 +213,11 @@ def an_numerical(self, prec=None, INPUT: - - ``prec`` -- integer (default: 53) bits precision -- used - for the L-series computation, period, regulator, etc. + - ``prec`` -- integer (default: 53); bits precision -- used + for the `L`-series computation, period, regulator, etc. - ``use_database`` -- whether the rank and generators should be looked up in the database if possible. Default is ``True`` - - ``proof`` -- bool or ``None`` (default: ``None``, see proof.[tab] or + - ``proof`` -- boolean or ``None`` (default: ``None``, see proof.[tab] or sage.structure.proof) proof option passed onto regulator and rank computation. @@ -226,7 +230,7 @@ def an_numerical(self, prec=None, If the curve's generators are not known, computing them may be very time-consuming. Also, computation of the - L-series derivative will be time-consuming for large rank and + `L`-series derivative will be time-consuming for large rank and large conductor, and the computation time for this may increase substantially at greater precision. However, use of very low precision less than about 10 can cause the underlying @@ -300,12 +304,12 @@ def an(self, use_database=False, descent_second_limit=12): INPUT: - - ``use_database`` -- bool (default: ``False``); if ``True``, try + - ``use_database`` -- boolean (default: ``False``); if ``True``, try to use any databases installed to lookup the analytic order of `Sha`, if possible. The order of `Sha` is computed if it cannot be looked up. - - ``descent_second_limit`` -- int (default: 12); limit to use on + - ``descent_second_limit`` -- integer (default: 12); limit to use on point searching for the quartic twist in the hard case This result is proved correct if the order of vanishing is 0 @@ -462,16 +466,16 @@ def an_padic(self, p, prec=0, use_twists=True): - ``p`` -- a prime > 3 - - ``prec`` (optional) -- the precision used in the computation of the + - ``prec`` -- (optional) the precision used in the computation of the `p`-adic L-Series - - ``use_twists`` (default: ``True``) -- If ``True`` the algorithm may + - ``use_twists`` -- boolean (default: ``True``); if ``True`` the algorithm may change to a quadratic twist with minimal conductor to do the modular symbol computations rather than using the modular symbols of the curve itself. If ``False`` it forces the computation using the modular symbols of the curve itself. - OUTPUT: `p`-adic number - that conjecturally equals `\# Sha(E/\QQ)`. + OUTPUT: `p`-adic number - that conjecturally equals `\# Sha(E/\QQ)`. If ``prec`` is set to zero (default) then the precision is set so that at least the first `p`-adic digit of conjectural `\# Sha(E/\QQ)` is @@ -720,13 +724,13 @@ def p_primary_order(self, p): INPUT: - - `p` -- an odd prime + - ``p`` -- an odd prime OUTPUT: - - `e` -- a non-negative integer such that `p^e` is the + - ``e`` -- nonnegative integer such that `p^e` is the order of the `p`-primary order if the conditions are satisfied - and raises a :class:`ValueError` otherwise. + and raises a :exc:`ValueError` otherwise. EXAMPLES:: @@ -771,7 +775,7 @@ def p_primary_bound(self, p): OUTPUT: - - ``e`` -- a non-negative integer such that `p^e` is an upper + - ``e`` -- nonnegative integer such that `p^e` is an upper bound for the order of `Sha(E)(p)` In particular, if this algorithm does not fail, then it proves @@ -916,19 +920,19 @@ def bound_kolyvagin(self, D=0, regulator=None, the Heegner hypothesis for `E`; if not given, use the first such `D` - ``regulator`` -- (optional) regulator of `E(K)`; if not given, will be computed (which could take a long time) - - ``ignore_nonsurj_hypothesis`` (optional: default ``False``) -- - If ``True``, then gives the bound coming from Heegner point + - ``ignore_nonsurj_hypothesis`` -- (default: ``False``); + if ``True``, then gives the bound coming from Heegner point index, but without any hypothesis on surjectivity - of the mod-`p` representation. + of the mod-`p` representation OUTPUT: - - list -- a list of primes such that if `p` divides `Sha(E/K)`, then + - ``list`` -- list of primes such that if `p` divides `Sha(E/K)`, then `p` is in this list, unless `E/K` has complex multiplication or - analytic rank greater than 2 (in which case we return 0). + analytic rank greater than 2 (in which case we return 0) - - index -- the odd part of the index of the Heegner point in the full - group of `K`-rational points on E. (If `E` has CM, returns 0.) + - ``index`` -- the odd part of the index of the Heegner point in the full + group of `K`-rational points on `E` (if `E` has CM, returns 0) REMARKS: @@ -1077,7 +1081,7 @@ def bound_kato(self): Then `{ord}_p(\#Sha(E))` is bounded from above by the `p`-adic valuation of `L(E,1)\cdot\#E(\QQ)_{tor}^2 / (\Omega_E \cdot \prod c_v)`. - If the L-series vanishes, the method ``p_primary_bound`` can be used instead. + If the `L`-series vanishes, the method ``p_primary_bound`` can be used instead. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py old mode 100644 new mode 100755 index 4c3313c9a89..bbd3bc1e9d6 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -32,6 +32,7 @@ from sage.rings.integer import Integer from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + class baseWI: r""" This class implements the basic arithmetic of isomorphisms between @@ -60,7 +61,7 @@ class baseWI: """ def __init__(self, u=1, r=0, s=0, t=0): r""" - Constructor: check for valid parameters (defaults to identity) + Constructor: check for valid parameters (defaults to identity). INPUT: @@ -179,11 +180,9 @@ def __call__(self, EorP): INPUT: - - ``EorP`` -- either an elliptic curve, or a point on an elliptic curve. - - OUTPUT: + - ``EorP`` -- either an elliptic curve, or a point on an elliptic curve - The transformed curve or point. + OUTPUT: the transformed curve or point EXAMPLES:: @@ -227,7 +226,7 @@ def _isomorphisms(E, F): INPUT: - - ``E``, ``F`` (EllipticCurve) -- Two elliptic curves. + - ``E``, ``F`` -- two elliptic curves OUTPUT: @@ -378,12 +377,12 @@ class WeierstrassIsomorphism(EllipticCurveHom, baseWI): INPUT: - - ``E`` -- an ``EllipticCurve``, or ``None`` (see below). + - ``E`` -- an ``EllipticCurve``, or ``None`` (see below) - ``urst`` -- a 4-tuple `(u,r,s,t)`, a :class:`baseWI` object, - or ``None`` (see below). + or ``None`` (see below) - - ``F`` -- an ``EllipticCurve``, or ``None`` (see below). + - ``F`` -- an ``EllipticCurve``, or ``None`` (see below) Given two Elliptic Curves ``E`` and ``F`` (represented by Weierstrass models as usual), and a transformation ``urst`` from ``E`` to ``F``, @@ -617,7 +616,7 @@ def _call_(self, P): INPUT: - - ``P`` (Point) -- a point on the domain curve. + - ``P`` -- Point; a point on the domain curve OUTPUT: @@ -1003,9 +1002,9 @@ def order(self): r""" Compute the order of this Weierstrass isomorphism if it is an automorphism. - A :class:`ValueError` is raised if the domain is not equal to the codomain. + A :exc:`ValueError` is raised if the domain is not equal to the codomain. - A :class:`NotImplementedError` is raised if the order of the automorphism is not 1, 2, 3, 4 or 6. + A :exc:`NotImplementedError` is raised if the order of the automorphism is not 1, 2, 3, 4 or 6. EXAMPLES:: @@ -1073,6 +1072,7 @@ def order(self): raise NotImplementedError("the order of the endomorphism is not 1, 2, 3, 4 or 6") + def identity_morphism(E): r""" Given an elliptic curve `E`, return the identity morphism @@ -1090,6 +1090,7 @@ def identity_morphism(E): zero = R.zero() return WeierstrassIsomorphism(E, (R.one(), zero, zero, zero)) + def negation_morphism(E): r""" Given an elliptic curve `E`, return the negation endomorphism diff --git a/src/sage/schemes/elliptic_curves/weierstrass_transform.py b/src/sage/schemes/elliptic_curves/weierstrass_transform.py old mode 100644 new mode 100755 index 07f897fb315..fcbd4e84023 --- a/src/sage/schemes/elliptic_curves/weierstrass_transform.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_transform.py @@ -62,13 +62,13 @@ def __init__(self, domain, codomain, defining_polynomials, post_multiplication): INPUT: - ``domain``, ``codomain`` -- two schemes, one of which is an - elliptic curve. + elliptic curve - ``defining_polynomials`` -- triplet of polynomials that - define the transformation. + define the transformation - ``post_multiplication`` -- a polynomial to homogeneously - rescale after substituting the defining polynomials. + rescale after substituting the defining polynomials EXAMPLES:: @@ -116,9 +116,7 @@ def post_rescaling(self): Return the homogeneous rescaling to apply after the coordinate substitution. - OUTPUT: - - A polynomial. See the example below. + OUTPUT: a polynomial; see the example below EXAMPLES:: diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py old mode 100644 new mode 100755 index 8cc0e544917..9a0afa5fb93 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -116,7 +116,7 @@ from sage.categories.number_fields import NumberFields -from sage.rings.ideal import is_Ideal +from sage.rings.ideal import Ideal_generic from sage.rings.integer_ring import ZZ from sage.rings.rational_field import RationalField from sage.rings.finite_rings.finite_field_base import FiniteField @@ -134,17 +134,18 @@ from . import ambient_space from . import scheme + def is_AlgebraicScheme(x): """ Test whether ``x`` is an algebraic scheme. INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: - Boolean. Whether ``x`` is an algebraic scheme, that is, a + boolean; whether ``x`` is an algebraic scheme, that is, a subscheme of an ambient space over a ring defined by polynomial equations. @@ -248,18 +249,16 @@ def _latex_(self): sage: S = AlgebraicScheme(P); S Subscheme of Projective Space of dimension 3 over Integer Ring sage: S._latex_() - '\\text{Subscheme of ${\\mathbf P}_{\\Bold{Z}}^3$}' + '\\text{Subscheme of ${\\mathbf P}_{\\Bold{Z}}^{3}$}' """ return r"\text{{Subscheme of ${}$}}".format(latex(self.__A)) def is_projective(self): """ - Return True if self is presented as a subscheme of an ambient + Return ``True`` if ``self`` is presented as a subscheme of an ambient projective space. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -375,7 +374,7 @@ def embedding_morphism(self): or neighborhood of a point then the embedding is the embedding into the original scheme. - * A :class:`NotImplementedError` is raised if the construction of + * A :exc:`NotImplementedError` is raised if the construction of the embedding morphism is not implemented yet. EXAMPLES:: @@ -469,7 +468,7 @@ def embedding_center(self): OUTPUT: - A point of ``self``. This raises :class:`AttributeError` if there + A point of ``self``. This raises :exc:`AttributeError` if there is no distinguished point, depending on how ``self`` was constructed. EXAMPLES:: @@ -534,15 +533,13 @@ def _repr_(self): def _homset(self, *args, **kwds): """ - Construct the Hom-set + Construct the Hom-set. INPUT: Same as :class:`sage.schemes.generic.homset.SchemeHomset_generic`. - OUTPUT: - - The Hom-set of the ambient space. + OUTPUT: the Hom-set of the ambient space EXAMPLES:: @@ -604,9 +601,7 @@ class AlgebraicScheme_quasi(AlgebraicScheme): preferred method to construct such subschemes is to use :meth:`complement` method of algebraic schemes. - OUTPUT: - - An instance of :class:`AlgebraicScheme_quasi`. + OUTPUT: an instance of :class:`AlgebraicScheme_quasi` EXAMPLES:: @@ -628,7 +623,7 @@ def __init__(self, X, Y): INPUT: - - ``X``, ``Y`` -- two subschemes of the same ambient space. + - ``X``, ``Y`` -- two subschemes of the same ambient space TESTS:: @@ -675,7 +670,7 @@ def _latex_(self): x - y sage: U._latex_() '\\text{Quasi-projective subscheme } - (X\\setminus Y)\\subset {\\mathbf P}_{\\Bold{Z}}^2,\\text{ where } + (X\\setminus Y)\\subset {\\mathbf P}_{\\Bold{Z}}^{2},\\text{ where } X \\text{ is defined by }\\text{no polynomials},\\text{ and } Y \\text{ is defined by } x - y.' """ @@ -724,7 +719,7 @@ def _repr_(self): def X(self): """ - Return the scheme `X` such that self is represented as `X - Y`. + Return the scheme `X` such that ``self`` is represented as `X - Y`. EXAMPLES:: @@ -739,7 +734,7 @@ def X(self): def Y(self): """ - Return the scheme `Y` such that self is represented as `X - Y`. + Return the scheme `Y` such that ``self`` is represented as `X - Y`. EXAMPLES:: @@ -755,7 +750,7 @@ def Y(self): def _check_satisfies_equations(self, v): """ Verify that the coordinates of v define a point on this scheme, or - raise a TypeError. + raise a :exc:`TypeError`. EXAMPLES:: @@ -834,16 +829,13 @@ def rational_points(self, **kwds): Return the set of rational points on this algebraic scheme over the field `F`. - INPUT: + INPUT: keyword arguments: - kwds: - - - ``bound`` -- integer (default: 0). The bound for the coordinates for - subschemes with dimension at least 1. - - - ``F`` -- field (default: base ring). The field to compute - the rational points over. + - ``bound`` -- integer (default: 0); the bound for the coordinates for + subschemes with dimension at least 1 + - ``F`` -- field (default: base ring); the field to compute + the rational points over EXAMPLES:: @@ -898,16 +890,14 @@ class AlgebraicScheme_subscheme(AlgebraicScheme): INPUT: - - ``A`` -- ambient space (e.g. affine or projective `n`-space) + - ``A`` -- ambient space (e.g. affine or projective `n`-space) - - ``polynomials`` -- single polynomial, ideal or iterable of defining - polynomials; in any case polynomials must belong to the coordinate - ring of the ambient space and define valid polynomial functions (e.g. - they should be homogeneous in the case of a projective space) + - ``polynomials`` -- single polynomial, ideal or iterable of defining + polynomials; in any case polynomials must belong to the coordinate + ring of the ambient space and define valid polynomial functions (e.g. + they should be homogeneous in the case of a projective space) - OUTPUT: - - - algebraic scheme + OUTPUT: algebraic scheme EXAMPLES:: @@ -936,17 +926,17 @@ def __init__(self, A, polynomials, category=None): Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z """ - from sage.rings.polynomial.multi_polynomial_sequence import is_PolynomialSequence + from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence_generic AlgebraicScheme.__init__(self, A, category=category) self._base_ring = A.base_ring() R = A.coordinate_ring() - if is_Ideal(polynomials): + if isinstance(polynomials, Ideal_generic): I = polynomials polynomials = I.gens() if I.ring() is R: # Otherwise we will recompute I later after self.__I = I # converting generators to the correct ring - if isinstance(polynomials, tuple) or is_PolynomialSequence(polynomials) or is_iterator(polynomials): + if isinstance(polynomials, tuple) or isinstance(polynomials, PolynomialSequence_generic) or is_iterator(polynomials): polynomials = list(polynomials) elif not isinstance(polynomials, list): # Looks like we got a single polynomial @@ -963,7 +953,7 @@ def __init__(self, A, polynomials, category=None): def _check_satisfies_equations(self, v): """ Verify that the coordinates of v define a point on this scheme, or - raise a TypeError. + raise a :exc:`TypeError`. EXAMPLES:: @@ -1047,13 +1037,13 @@ def _latex_(self): Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by: x^2 - y*z sage: S._latex_() - '\\text{Closed subscheme of } {\\mathbf P}_{\\Bold{F}_{11}}^2 \\text{ defined by } x^{2} - y z' + '\\text{Closed subscheme of } {\\mathbf P}_{\\Bold{F}_{11}}^{2} \\text{ defined by } x^{2} - y z' sage: S = P.subscheme([x^2 - y*z, x^5]); S Closed subscheme of Projective Space of dimension 2 over Finite Field of size 11 defined by: x^2 - y*z, x^5 sage: S._latex_() - '\\text{Closed subscheme of } {\\mathbf P}_{\\Bold{F}_{11}}^2 \\text{ defined by } x^{2} - y z, x^{5}' + '\\text{Closed subscheme of } {\\mathbf P}_{\\Bold{F}_{11}}^{2} \\text{ defined by } x^{2} - y z, x^{5}' """ polynomials = ', '.join(latex(f) for f in self.defining_polynomials()) if not polynomials: @@ -1122,7 +1112,6 @@ def normalize_defining_polynomials(self): sage: S.normalize_defining_polynomials() sage: S.defining_polynomials() (x^2 + 2*x*y, 3*x + 8*y) - """ BR = self.base_ring() if (BR == ZZ @@ -1152,9 +1141,7 @@ def defining_ideal(self): Return the ideal that defines this scheme as a subscheme of its ambient space. - OUTPUT: - - An ideal in the coordinate ring of the ambient space. + OUTPUT: an ideal in the coordinate ring of the ambient space EXAMPLES:: @@ -1176,9 +1163,7 @@ def codimension(self): r""" Return the codimension of the algebraic subscheme. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -1277,7 +1262,7 @@ def is_irreducible(self): r""" Return whether this subscheme is or is not irreducible. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -1312,9 +1297,7 @@ def Jacobian_matrix(self): Return the matrix `\frac{\partial f_i}{\partial x_j}` of (formal) partial derivatives. - OUTPUT: - - A matrix of polynomials. + OUTPUT: a matrix of polynomials EXAMPLES:: @@ -1355,9 +1338,7 @@ def Jacobian(self): Jacobian ideal. An example of a reference that does include the defining equations is [Laz2004]_, p. 181. - OUTPUT: - - An ideal in the coordinate ring of the ambient space. + OUTPUT: an ideal in the coordinate ring of the ambient space EXAMPLES:: @@ -1435,7 +1416,7 @@ def reduce(self): def union(self, other): """ - Return the scheme-theoretic union of self and other in their common + Return the scheme-theoretic union of ``self`` and ``other`` in their common ambient space. EXAMPLES: We construct the union of a line and a tripled-point on @@ -1482,9 +1463,11 @@ def __pow__(self, m): """ Return the Cartesian power of this space. - INPUT: ``m`` -- integer. + INPUT: - OUTPUT: subscheme of product of ambient spaces. + - ``m`` -- integer + + OUTPUT: subscheme of product of ambient spaces EXAMPLES:: @@ -1547,7 +1530,7 @@ def __mul__(self, right): - ``right`` -- a subscheme of similar type - OUTPUT: a subscheme of a the product of the ambient spaces. + OUTPUT: a subscheme of a the product of the ambient spaces EXAMPLES:: @@ -1741,18 +1724,16 @@ def rational_points(self, **kwds): modulo primes is used. See the documentation in homset for the details of the sieving algorithm. - INPUT: - - kwds: + INPUT: keyword arguments: - - ``bound`` -- integer (default: 0). The bound for the coordinates for - subschemes with dimension at least 1. + - ``bound`` -- integer (default: 0); the bound for the coordinates for + subschemes with dimension at least 1 - - ``prec`` -- integer (default: 53). The precision to use to - compute the elements of bounded height for number fields. + - ``prec`` -- integer (default: 53); the precision to use to + compute the elements of bounded height for number fields - ``F`` -- field (default: base ring). The field to compute - the rational points over. + the rational points over - ``point_tolerance`` -- positive real number (default: 10^(-10)). For numerically inexact fields, two points are considered the same @@ -1762,7 +1743,8 @@ def rational_points(self, **kwds): For numerically inexact fields, points are on the subscheme if they satisfy the equations to within tolerance. - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm-4 OUTPUT: list of points in subscheme or ambient space @@ -1787,7 +1769,7 @@ def rational_points(self, **kwds): over the rationals:: sage: E = EllipticCurve('37a') # needs sage.schemes - sage: E.rational_points(bound=8) # needs sage.schemes + sage: E.rational_points(bound=8) # needs sage.libs.singular sage.schemes [(-1 : -1 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0), (1/4 : -5/8 : 1), (1/4 : -3/8 : 1), (1 : -1 : 1), (1 : 0 : 1), (2 : -3 : 1), (2 : 2 : 1)] @@ -1796,8 +1778,9 @@ def rational_points(self, **kwds): enumerated. :: sage: Etilde = E.base_extend(GF(3)) # needs sage.schemes - sage: Etilde.rational_points() # needs sage.schemes - [(0 : 1 : 0), (0 : 0 : 1), (0 : 2 : 1), (1 : 0 : 1), (1 : 2 : 1), (2 : 0 : 1), (2 : 2 : 1)] + sage: Etilde.rational_points() # needs sage.libs.singular sage.schemes + [(0 : 1 : 0), (0 : 0 : 1), (0 : 2 : 1), (1 : 0 : 1), + (1 : 2 : 1), (2 : 0 : 1), (2 : 2 : 1)] The class of hyperelliptic curves does not (yet) support desingularization of the places at infinity into two points:: @@ -1805,27 +1788,27 @@ def rational_points(self, **kwds): sage: FF = FiniteField(7) sage: P. = PolynomialRing(FiniteField(7)) sage: C = HyperellipticCurve(x^8 + x + 1) # needs sage.schemes - sage: C.rational_points() # needs sage.schemes + sage: C.rational_points() # needs sage.libs.singular sage.schemes [(0 : 1 : 0), (0 : 1 : 1), (0 : 6 : 1), (2 : 0 : 1), (4 : 0 : 1), (6 : 1 : 1), (6 : 6 : 1)] :: - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.rings.real_mpfr sage: K. = QuadraticField(-3) sage: P. = ProjectiveSpace(K, 2) sage: X = P.subscheme([x^2 - v^2*x*z, y*x - v*z^2]) - sage: X.rational_points(F=CC) + sage: X.rational_points(F=CC) # needs sage.libs.singular [(-3.00000000000000 : -0.577350269189626*I : 1.00000000000000), (0.000000000000000 : 1.00000000000000 : 0.000000000000000)] :: - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.rings.real_mpfr sage: K. = QuadraticField(3) sage: A. = AffineSpace(K, 2) sage: X = A.subscheme([x^2 - v^2*y, y*x - v]) - sage: X.rational_points(F=RR) + sage: X.rational_points(F=RR) # needs sage.libs.singular [(1.73205080756888, 1.00000000000000)] .. TODO:: @@ -1855,15 +1838,13 @@ def rational_points(self, **kwds): def change_ring(self, R): r""" - Returns a new algebraic subscheme which is this subscheme coerced to ``R``. + Return a new algebraic subscheme which is this subscheme coerced to ``R``. INPUT: - - ``R`` -- ring or morphism. - - OUTPUT: + - ``R`` -- ring or morphism - - A new algebraic subscheme which is this subscheme coerced to ``R``. + OUTPUT: a new algebraic subscheme which is this subscheme coerced to ``R`` EXAMPLES:: @@ -2006,7 +1987,7 @@ def weil_restriction(self): If the input and the output ideals are radical, this is equivalent to the statement about algebraic varieties above. - OUTPUT: Affine subscheme - the Weil restriction of ``self``. + OUTPUT: affine subscheme; the Weil restriction of ``self`` EXAMPLES:: diff --git a/src/sage/schemes/generic/ambient_space.py b/src/sage/schemes/generic/ambient_space.py old mode 100644 new mode 100755 index 895cd4a338d..0a624197b07 --- a/src/sage/schemes/generic/ambient_space.py +++ b/src/sage/schemes/generic/ambient_space.py @@ -19,7 +19,7 @@ def is_AmbientSpace(x): """ - Return True if `x` is an ambient space. + Return ``True`` if `x` is an ambient space. EXAMPLES:: @@ -46,9 +46,9 @@ class AmbientSpace(Scheme): INPUT: - - ``n`` -- dimension + - ``n`` -- dimension - - ``R`` -- ring + - ``R`` -- ring """ def __init__(self, n, R=ZZ): """ @@ -123,7 +123,7 @@ def _latex_generic_point(self, coords=None): def _check_satisfies_equations(self, v): """ Verify that the coordinates of v define a point on this scheme, or - raise a TypeError. + raise a :exc:`TypeError`. TESTS:: @@ -138,17 +138,15 @@ def _check_satisfies_equations(self, v): def _validate(self, polynomials): """ - If ``polynomials`` is a tuple of valid polynomial functions on self, - return ``polynomials``, otherwise raise TypeError. + If ``polynomials`` is a tuple of valid polynomial functions on + ``self``, return ``polynomials``, otherwise raise :exc:`TypeError`. INPUT: - ``polynomials`` -- tuple of polynomials in the coordinate ring of - self + ``self`` - OUTPUT: - - - tuple of polynomials in the coordinate ring of self + OUTPUT: tuple of polynomials in the coordinate ring of ``self`` TESTS:: @@ -170,9 +168,7 @@ def change_ring(self, R): - ``R`` -- commutative ring - OUTPUT: - - - ambient space over ``R`` + OUTPUT: ambient space over ``R`` .. NOTE:: @@ -217,15 +213,13 @@ def base_extend(self, R): INPUT: - ``R`` -- a commutative ring, such that there is a natural map from - the base ring of self to ``R``. - - OUTPUT: + the base ring of ``self`` to ``R`` - - an ambient space over ``R`` of the same structure as ``self``. + OUTPUT: an ambient space over ``R`` of the same structure as ``self`` .. NOTE:: - A :class:`ValueError` is raised if there is no such natural map. + A :exc:`ValueError` is raised if there is no such natural map. If you need to drop this condition, use ``self.change_ring(R)``. EXAMPLES:: @@ -271,8 +265,8 @@ def ambient_space(self): def defining_polynomials(self): """ - Return the defining polynomials of the scheme self. Since - self is an ambient space, this is an empty list. + Return the defining polynomials of the scheme ``self``. Since + ``self`` is an ambient space, this is an empty list. EXAMPLES:: @@ -311,7 +305,7 @@ def identity_morphism(self): def gen(self, n=0): """ Return the `n`-th generator of the coordinate ring of the - scheme self. + scheme ``self``. EXAMPLES:: @@ -324,7 +318,7 @@ def gen(self, n=0): def gens(self): """ Return the generators of the coordinate ring of the scheme - self. + ``self``. EXAMPLES:: @@ -340,7 +334,7 @@ def gens(self): def ngens(self): """ Return the number of generators of the coordinate ring of the - scheme self. + scheme ``self``. EXAMPLES:: diff --git a/src/sage/schemes/generic/divisor.py b/src/sage/schemes/generic/divisor.py old mode 100644 new mode 100755 index d46b8caff0e..441efbf36e7 --- a/src/sage/schemes/generic/divisor.py +++ b/src/sage/schemes/generic/divisor.py @@ -42,14 +42,15 @@ #******************************************************************************* from sage.misc.latex import latex +from sage.misc.lazy_import import lazy_import from sage.misc.repr import repr_lincomb from sage.misc.search import search from sage.rings.integer_ring import ZZ -from sage.structure.formal_sum import FormalSum - -from .morphism import is_SchemeMorphism from sage.schemes.affine.affine_space import AffineSpace_generic from sage.schemes.projective.projective_space import ProjectiveSpace_ring +from sage.structure.formal_sum import FormalSum + +lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') def CurvePointToIdeal(C,P): @@ -95,15 +96,13 @@ def CurvePointToIdeal(C,P): def is_Divisor(x): r""" - Test whether ``x`` is an instance of :class:`Divisor_generic` + Test whether ``x`` is an instance of :class:`Divisor_generic`. INPUT: - - ``x`` -- anything. - - OUTPUT: + - ``x`` -- anything - ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -111,10 +110,18 @@ def is_Divisor(x): sage: x,y = AffineSpace(2, GF(5), names='xy').gens() sage: C = Curve(y^2 - x^9 - x) sage: is_Divisor(C.divisor([])) + doctest:warning... + DeprecationWarning: The function is_Divisor is deprecated; + use 'isinstance(..., Divisor_generic)' instead. + See https://github.com/sagemath/sage/issues/38277 for details. True sage: is_Divisor("Ceci n'est pas un diviseur") False """ + from sage.misc.superseded import deprecation + deprecation(38277, + "The function is_Divisor is deprecated; " + "use 'isinstance(..., Divisor_generic)' instead.") return isinstance(x, Divisor_generic) @@ -154,16 +161,15 @@ def __init__(self, v, parent, check=True, reduce=True): INPUT: - - ``v`` -- object. Usually a list of pairs - ``(coefficient,divisor)``. + - ``v`` -- object; usually a list of pairs ``(coefficient,divisor)`` - ``parent`` -- FormalSums(R) module (default: FormalSums(ZZ)) - - ``check`` -- bool (default: ``True``). Whether to coerce + - ``check`` -- boolean (default: ``True``); whether to coerce coefficients into base ring. Setting it to ``False`` can speed up construction. - - ``reduce`` -- reduce (default: ``True``). Whether to combine + - ``reduce`` -- reduce (default: ``True``); whether to combine common terms. Setting it to ``False`` can speed up construction. @@ -187,9 +193,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -217,9 +221,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -264,14 +266,12 @@ class Divisor_curve(Divisor_generic): For any curve `C`, use ``C.divisor(v)`` to construct a divisor on `C`. Here `v` can be either + - a rational point on `C` - - a rational point on `C` - - - a list of rational points - - - a list of 2-tuples `(c,P)`, where `c` is an - integer and `P` is a rational point. + - a list of rational points + - a list of 2-tuples `(c,P)`, where `c` is an + integer and `P` is a rational point TODO: Divisors shouldn't be restricted to rational points. The problem is that the divisor group is the formal sum of the group of @@ -302,12 +302,11 @@ def __init__(self, v, parent=None, check=True, reduce=True): INPUT: - - ``v`` -- a list of pairs ``(c, P)``, where ``c`` is an - integer and ``P`` is a point on a curve. The P's must all - lie on the same curve. + - ``v`` -- list of pairs ``(c, P)``, where ``c`` is an + integer and ``P`` is a point on a curve. The P's must all + lie on the same curve. - - - To create the divisor 0 use ``[(0, P)]``, so as to give the curve. + To create the divisor 0 use ``[(0, P)]``, so as to give the curve. EXAMPLES:: @@ -358,7 +357,7 @@ def __init__(self, v, parent=None, check=True, reduce=True): else: n = ZZ(1) I = t - if is_SchemeMorphism(I): + if isinstance(I, SchemeMorphism): I = CurvePointToIdeal(C,I) else: know_points = False @@ -374,9 +373,7 @@ def _repr_(self): r""" Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: diff --git a/src/sage/schemes/generic/divisor_group.py b/src/sage/schemes/generic/divisor_group.py old mode 100644 new mode 100755 index d6a19f49d60..0b11b1d0982 --- a/src/sage/schemes/generic/divisor_group.py +++ b/src/sage/schemes/generic/divisor_group.py @@ -15,12 +15,15 @@ # http://www.gnu.org/licenses/ #******************************************************************************* +from sage.misc.lazy_import import lazy_import from sage.schemes.generic.divisor import Divisor_generic, Divisor_curve from sage.structure.formal_sum import FormalSums from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ +lazy_import('sage.schemes.curves.curve', 'Curve_generic') + def DivisorGroup(scheme, base_ring=None): r""" @@ -28,15 +31,13 @@ def DivisorGroup(scheme, base_ring=None): INPUT: - - ``scheme`` -- a scheme. + - ``scheme`` -- a scheme - ``base_ring`` -- usually either `\ZZ` (default) or `\QQ`. The coefficient ring of the divisors. Not to be confused with the base ring of the scheme! - OUTPUT: - - An instance of ``DivisorGroup_generic``. + OUTPUT: an instance of ``DivisorGroup_generic`` EXAMPLES:: @@ -49,7 +50,6 @@ def DivisorGroup(scheme, base_ring=None): if base_ring is None: base_ring = ZZ - from sage.schemes.curves.curve import Curve_generic if isinstance(scheme, Curve_generic): DG = DivisorGroup_curve(scheme, base_ring) else: @@ -64,11 +64,9 @@ def is_DivisorGroup(x): INPUT: - - ``x`` -- anything. - - OUTPUT: + - ``x`` -- anything - ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -112,10 +110,9 @@ def __init__(self, scheme, base_ring): INPUT: - - ``scheme`` -- a scheme. + - ``scheme`` -- a scheme - - ``base_ring`` -- the coefficient ring of the divisor - group. + - ``base_ring`` -- the coefficient ring of the divisor group Implementation note: :meth:`__classcall__` sets default value for ``base_ring``. diff --git a/src/sage/schemes/generic/glue.py b/src/sage/schemes/generic/glue.py old mode 100644 new mode 100755 index e70aafa0507..7733030a2ab --- a/src/sage/schemes/generic/glue.py +++ b/src/sage/schemes/generic/glue.py @@ -5,25 +5,24 @@ #******************************************************************************* # Copyright (C) 2006 William Stein # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #******************************************************************************* -from . import morphism -from . import scheme +from sage.misc.lazy_import import lazy_import +from sage.schemes.generic.scheme import Scheme -class GluedScheme(scheme.Scheme): - r""" - INPUT: +lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') - - ``f`` -- open immersion from a scheme `U` to a scheme - `X` +class GluedScheme(Scheme): + r""" + INPUT: - - ``g`` -- open immersion from `U` to a scheme `Y` + - ``f`` -- open immersion from a scheme `U` to a scheme `X` + - ``g`` -- open immersion from `U` to a scheme `Y` - OUTPUT: The scheme obtained by gluing `X` and `Y` along the open set - `U`. + OUTPUT: the scheme obtained by gluing `X` and `Y` along the open set `U` .. NOTE:: @@ -48,9 +47,9 @@ class GluedScheme(scheme.Scheme): """ def __init__(self, f, g, check=True): if check: - if not morphism.is_SchemeMorphism(f): + if not isinstance(f, SchemeMorphism): raise TypeError("f (=%s) must be a scheme morphism" % f) - if not morphism.is_SchemeMorphism(g): + if not isinstance(g, SchemeMorphism): raise TypeError("g (=%s) must be a scheme morphism" % g) if f.domain() != g.domain(): raise ValueError("f (=%s) and g (=%s) must have the same domain" % (f,g)) diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py old mode 100644 new mode 100755 index 7ef792b9b5b..370049d2238 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -10,7 +10,7 @@ are implemented by such scheme morphisms. This is done by :class:`SchemeHomset_points` and its subclasses. -.. note:: +.. NOTE:: You should not create the Hom-sets manually. Instead, use the :meth:`~sage.structure.parent.Hom` method that is inherited by all @@ -129,18 +129,18 @@ def create_key_and_extra_args(self, X, Y, category=None, base=None, INPUT: - - ``X`` -- a scheme. The domain of the morphisms. + - ``X`` -- a scheme; the domain of the morphisms - - ``Y`` -- a scheme. The codomain of the morphisms. + - ``Y`` -- a scheme; the codomain of the morphisms - ``category`` -- a category for the Hom-sets (default: schemes over - given base). + given base) - - ``base`` -- a scheme or a ring. The base scheme of domain + - ``base`` -- a scheme or a ring; the base scheme of domain and codomain schemes. If a ring is specified, the spectrum of that ring will be used as base scheme. - - ``check`` -- boolean (default: ``True``). + - ``check`` -- boolean (default: ``True``) EXAMPLES:: @@ -190,11 +190,11 @@ def create_object(self, version, key, **extra_args): INPUT: - - ``version`` -- object version. Currently not used. + - ``version`` -- object version; currently not used - - ``key`` -- a key created by :meth:`create_key_and_extra_args`. + - ``key`` -- a key created by :meth:`create_key_and_extra_args` - - ``extra_args`` -- a dictionary of extra keyword arguments. + - ``extra_args`` -- dictionary of extra keyword arguments EXAMPLES:: @@ -235,15 +235,15 @@ class SchemeHomset_generic(HomsetWithBase): INPUT: - - ``X`` -- a scheme. The domain of the Hom-set. + - ``X`` -- a scheme; the domain of the Hom-set - - ``Y`` -- a scheme. The codomain of the Hom-set. + - ``Y`` -- a scheme; the codomain of the Hom-set - - ``category`` -- a category (optional). The category of the - Hom-set. + - ``category`` -- a category (optional); the category of the + Hom-set - - ``check`` -- boolean (default: ``True``). Whether to - check the defining data for consistency. + - ``check`` -- boolean (default: ``True``); whether to + check the defining data for consistency EXAMPLES:: @@ -293,9 +293,7 @@ def _repr_(self): r""" Return a string representation. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -318,8 +316,7 @@ def natural_map(self): OUTPUT: A :class:`SchemeMorphism` if there is a natural map from - domain to codomain. Otherwise, a :class:`NotImplementedError` is - raised. + domain to codomain. Otherwise, a :exc:`NotImplementedError` is raised. EXAMPLES:: @@ -342,12 +339,12 @@ def _element_constructor_(self, x, check=True): INPUT: - - `x` -- a ring morphism, or a list or a tuple that define a - ring morphism. + - ``x`` -- a ring morphism, or a list or a tuple that define a + ring morphism - - ``check`` -- boolean (default: ``True``) passed onto + - ``check`` -- boolean (default: ``True``); passed onto functions called by this one to be more careful about input - argument type checking. + argument type checking EXAMPLES:: @@ -630,11 +627,9 @@ def _element_constructor_(self, *v, **kwds): INPUT: - ``v`` -- anything that determines a scheme morphism in the - Hom-set. - - OUTPUT: + Hom-set - The scheme morphism determined by ``v``. + OUTPUT: the scheme morphism determined by ``v`` EXAMPLES:: @@ -663,6 +658,56 @@ def _element_constructor_(self, *v, **kwds): v = v[0] return self.extended_codomain()._point(self, v, **kwds) + def __iter__(self): + r""" + Return an iterator for the set of rational points on this scheme. + + By default, this calls the :meth:`points` method, which is implemented + when the base ring is a field + + - for affine homsets at :meth:`sage.schemes.affine.affine_homset.SchemeHomset_points_affine.points`; + - for projective homsets at :meth:`sage.schemes.projective.projective_homset.SchemeHomset_points_projective_field.points`; + - and toric homsets at :meth:`sage.schemes.toric.homset.SchemeHomset_points_toric_field._enumerator`. + + OUTPUT: iterator over points + + TESTS:: + + sage: E = EllipticCurve(GF(19), [1, 0]) + sage: list(E.point_homset()) + [(0 : 1 : 0), (0 : 0 : 1), (3 : 7 : 1), (3 : 12 : 1), (4 : 7 : 1), + (4 : 12 : 1), (5 : 4 : 1), (5 : 15 : 1), (8 : 8 : 1), (8 : 11 : 1), + (9 : 4 : 1), (9 : 15 : 1), (12 : 7 : 1), (12 : 12 : 1), (13 : 5 : 1), + (13 : 14 : 1), (17 : 3 : 1), (17 : 16 : 1), (18 : 6 : 1), (18 : 13 : 1)] + sage: _ == list(E) + True + sage: E.point_homset().cardinality() + 20 + + :: + + sage: A. = AffineSpace(2, GF(5)) + sage: list(A.point_homset()) + [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), + (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), + (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), + (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), + (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)] + sage: _ == list(A) + True + sage: A.point_homset().cardinality() + 25 + + :: + + sage: P1 = toric_varieties.P1(base_ring=GF(3)) + sage: list(P1.point_homset()) + [[0 : 1], [1 : 0], [1 : 1], [1 : 2]] + sage: P1.point_homset().cardinality() + 4 + """ + yield from self.points() + def extended_codomain(self): r""" Return the codomain with extended base, if necessary. @@ -708,9 +753,7 @@ def _repr_(self): """ Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -724,9 +767,7 @@ def value_ring(self): r""" Return `R` for a point Hom-set `X(\mathrm{Spec}(R))`. - OUTPUT: - - A commutative ring. + OUTPUT: a commutative ring EXAMPLES:: @@ -743,9 +784,7 @@ def cardinality(self): """ Return the number of points. - OUTPUT: - - An integer or infinity. + OUTPUT: integer or infinity EXAMPLES:: @@ -767,9 +806,7 @@ def list(self): """ Return a tuple containing all points. - OUTPUT: - - A tuple containing all points of the toric variety. + OUTPUT: a tuple containing all points of the toric variety EXAMPLES:: diff --git a/src/sage/schemes/generic/hypersurface.py b/src/sage/schemes/generic/hypersurface.py old mode 100644 new mode 100755 index 4d39a7bfc27..a6bb63040b5 --- a/src/sage/schemes/generic/hypersurface.py +++ b/src/sage/schemes/generic/hypersurface.py @@ -23,9 +23,10 @@ from sage.schemes.affine.affine_subscheme import AlgebraicScheme_subscheme_affine from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective + def is_Hypersurface(self): """ - Return True if ``self`` is a hypersurface, i.e. an object of the type + Return ``True`` if ``self`` is a hypersurface, i.e. an object of the type :class:`ProjectiveHypersurface` or :class:`AffineHypersurface`. EXAMPLES:: diff --git a/src/sage/schemes/generic/morphism.py b/src/sage/schemes/generic/morphism.py old mode 100644 new mode 100755 index 8034d0b9b5a..56bfb8da197 --- a/src/sage/schemes/generic/morphism.py +++ b/src/sage/schemes/generic/morphism.py @@ -74,20 +74,20 @@ # https://www.gnu.org/licenses/ # **************************************************************************** - import operator -from sage.structure.element import Element, parent, coercion_model + from sage.arith.power import generic_power -from sage.structure.richcmp import richcmp -from sage.structure.sequence import Sequence from sage.categories.homset import Homset, Hom, End -from sage.rings.fraction_field_element import FractionFieldElement -from sage.rings.fraction_field import FractionField_generic from sage.categories.map import FormalCompositeMap, Map +from sage.categories.morphism import SetMorphism from sage.misc.constant_function import ConstantFunction from sage.misc.lazy_attribute import lazy_attribute -from sage.categories.morphism import SetMorphism +from sage.rings.fraction_field import FractionField_generic +from sage.rings.fraction_field_element import FractionFieldElement from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme +from sage.structure.element import Element, parent, coercion_model +from sage.structure.richcmp import richcmp +from sage.structure.sequence import Sequence def is_SchemeMorphism(f): @@ -96,11 +96,11 @@ def is_SchemeMorphism(f): INPUT: - - ``f`` -- anything. + - ``f`` -- anything OUTPUT: - Boolean. Return ``True`` if ``f`` is a scheme morphism or a point + boolean; return ``True`` if ``f`` is a scheme morphism or a point on an elliptic curve. EXAMPLES:: @@ -111,19 +111,26 @@ def is_SchemeMorphism(f): Defn: Defined on coordinates by sending (x, y) to (y, x^2 + y) sage: from sage.schemes.generic.morphism import is_SchemeMorphism sage: is_SchemeMorphism(f) + doctest:warning... + DeprecationWarning: The function is_SchemeMorphism is deprecated; + use 'isinstance(..., SchemeMorphism)' instead. + See https://github.com/sagemath/sage/issues/38296 for details. True """ - from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field - return isinstance(f, (SchemeMorphism, EllipticCurvePoint_field)) + from sage.misc.superseded import deprecation + deprecation(38296, + "The function is_SchemeMorphism is deprecated; " + "use 'isinstance(..., SchemeMorphism)' instead.") + return isinstance(f, SchemeMorphism) class SchemeMorphism(Element): """ - Base class for scheme morphisms + Base class for scheme morphisms. INPUT: - - ``parent`` -- the parent of the morphism. + - ``parent`` -- the parent of the morphism .. TODO:: @@ -274,9 +281,7 @@ def _repr_defn(self): r""" Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -295,9 +300,7 @@ def _repr_type(self): r""" Return a string representation of the type of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -314,9 +317,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -409,11 +410,9 @@ def __pow__(self, n, dummy=None): INPUT: - - ``n`` -- integer. The exponent. - - OUTPUT: + - ``n`` -- integer; the exponent - A composite map that belongs to the same endomorphism set as ``self``. + OUTPUT: a composite map that belongs to the same endomorphism set as ``self`` EXAMPLES:: @@ -436,9 +435,7 @@ def category(self): """ Return the category of the Hom-set. - OUTPUT: - - A category. + OUTPUT: a category EXAMPLES:: @@ -464,9 +461,7 @@ def is_endomorphism(self) -> bool: """ Return whether the morphism is an endomorphism. - OUTPUT: - - Boolean. Whether the domain and codomain are identical. + OUTPUT: boolean; whether the domain and codomain are identical EXAMPLES:: @@ -483,9 +478,7 @@ def base_ring(self): Return the base ring of ``self``, that is, the ring over which the defining polynomials of ``self`` are defined. - OUTPUT: - - - ring + OUTPUT: ring EXAMPLES:: @@ -605,11 +598,11 @@ def _composition_(self, right, homset): def glue_along_domains(self, other): r""" - Glue two morphism + Glue two morphisms. INPUT: - - ``other`` -- a scheme morphism with the same domain. + - ``other`` -- a scheme morphism with the same domain OUTPUT: @@ -675,7 +668,7 @@ class SchemeMorphism_id(SchemeMorphism): INPUT: - - ``X`` -- the scheme. + - ``X`` -- the scheme EXAMPLES:: @@ -702,9 +695,7 @@ def _repr_defn(self): r""" Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -716,12 +707,12 @@ def _repr_defn(self): class SchemeMorphism_structure_map(SchemeMorphism): r""" - The structure morphism + The structure morphism. INPUT: - ``parent`` -- Hom-set with codomain equal to the base scheme of - the domain. + the domain EXAMPLES:: @@ -752,9 +743,7 @@ def _repr_defn(self): r""" Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -766,16 +755,16 @@ def _repr_defn(self): class SchemeMorphism_spec(SchemeMorphism): """ - Morphism of spectra of rings + Morphism of spectra of rings. INPUT: - - ``parent`` -- Hom-set whose domain and codomain are affine schemes. + - ``parent`` -- Hom-set whose domain and codomain are affine schemes - - ``phi`` -- a ring morphism with matching domain and codomain. + - ``phi`` -- a ring morphism with matching domain and codomain - - ``check`` -- boolean (default:``True``). Whether to - check the input for consistency. + - ``check`` -- boolean (default: ``True``); whether to + check the input for consistency EXAMPLES:: @@ -838,11 +827,9 @@ def _call_(self, x): INPUT: - - ``x`` -- a scheme point. + - ``x`` -- a scheme point - OUTPUT: - - The image scheme point. + OUTPUT: the image scheme point EXAMPLES: @@ -868,9 +855,7 @@ def _repr_type(self): r""" Return a string representation of the type of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -887,9 +872,7 @@ def _repr_defn(self): r""" Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -909,9 +892,7 @@ def ring_homomorphism(self): """ Return the underlying ring homomorphism. - OUTPUT: - - A ring homomorphism. + OUTPUT: a ring homomorphism EXAMPLES:: @@ -942,13 +923,13 @@ class SchemeMorphism_polynomial(SchemeMorphism): INPUT: - ``parent`` -- Hom-set whose domain and codomain are affine or - projective schemes. + projective schemes - - ``polys`` -- a list/tuple/iterable of polynomials defining the - scheme morphism. + - ``polys`` -- list/tuple/iterable of polynomials defining the + scheme morphism - - ``check`` -- boolean (default:``True``). Whether to - check the input for consistency. + - ``check`` -- boolean (default: ``True``); whether to + check the input for consistency EXAMPLES: @@ -978,7 +959,6 @@ class SchemeMorphism_polynomial(SchemeMorphism): ... TypeError: polys (=[e^x, e^y]) must be elements of Multivariate Polynomial Ring in x, y over Rational Field - """ def __init__(self, parent, polys, check=True): """ @@ -1066,11 +1046,9 @@ def _call_(self, x): INPUT: - ``x`` -- a point in the domain or a list or tuple that - defines a point in the domain. - - OUTPUT: + defines a point in the domain - A point in the codomain. + OUTPUT: a point in the codomain EXAMPLES:: @@ -1138,16 +1116,15 @@ def _call_(self, x): def _call_with_args(self, x, args, kwds): """ - Apply this morphism to a point in the domain, with additional arguments + Apply this morphism to a point in the domain, with additional arguments. INPUT: - - ``x`` -- a point in the domain or a list or tuple that defines a point in the domain. - - ``check``, a boolean, either provided by position or name. - - OUTPUT: + - ``x`` -- a point in the domain or a list or tuple that defines a + point in the domain + - ``check`` -- boolean; either provided by position or name - A point in the codomain. + OUTPUT: a point in the codomain EXAMPLES:: @@ -1230,9 +1207,7 @@ def _repr_defn(self): """ Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1249,15 +1224,13 @@ def _repr_defn(self): def __getitem__(self, i): """ - Return the i-th poly with self[i]. + Return the i-th poly with ``self[i]``. INPUT: - ``i`` -- integer - OUTPUT: - - - element of the coordinate ring of the domain + OUTPUT: element of the coordinate ring of the domain EXAMPLES:: @@ -1273,9 +1246,7 @@ def __copy__(self): r""" Return a copy of ``self``. - OUTPUT: - - - :class:`SchemeMorphism_polynomial` + OUTPUT: :class:`SchemeMorphism_polynomial` EXAMPLES:: @@ -1303,7 +1274,7 @@ def coordinate_ring(self): r""" Return the coordinate ring of the ambient projective space. - OUTPUT: A multivariable polynomial ring over the base ring. + OUTPUT: a multivariable polynomial ring over the base ring EXAMPLES:: @@ -1327,19 +1298,19 @@ def coordinate_ring(self): def change_ring(self, R, check=True): r""" - Returns a new :class:`SchemeMorphism_polynomial` which is this map coerced to ``R``. + Return a new :class:`SchemeMorphism_polynomial` which is this map + coerced to ``R``. If ``check`` is ``True``, then the initialization checks are performed. INPUT: - - ``R`` -- ring or morphism. + - ``R`` -- ring or morphism - - ``check`` -- Boolean + - ``check`` -- boolean - OUTPUT: - - - A new :class:`SchemeMorphism_polynomial` which is this map coerced to ``R``. + OUTPUT: a new :class:`SchemeMorphism_polynomial` which is this map + coerced to ``R`` TESTS:: @@ -1370,7 +1341,6 @@ def change_ring(self, R, check=True): ... ValueError: no canonical coercion of base ring of morphism to domain of embedding - EXAMPLES:: sage: P. = ProjectiveSpace(ZZ, 1) @@ -1808,9 +1778,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1825,9 +1793,7 @@ def _latex_(self): r""" Return a latex representation of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1844,9 +1810,7 @@ def __getitem__(self, n): """ Return the ``n``-th coordinate. - OUTPUT: - - The coordinate values as an element of the base ring. + OUTPUT: the coordinate values as an element of the base ring EXAMPLES:: @@ -1863,9 +1827,7 @@ def __iter__(self): """ Iterate over the coordinates of the point. - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -1885,9 +1847,7 @@ def __tuple__(self): """ Return the coordinates as a tuple. - OUTPUT: - - A tuple. + OUTPUT: a tuple EXAMPLES:: @@ -1902,9 +1862,7 @@ def __len__(self): """ Return the number of coordinates. - OUTPUT: - - Integer. The number of coordinates used to describe the point. + OUTPUT: integer. The number of coordinates used to describe the point EXAMPLES:: @@ -1921,12 +1879,10 @@ def _richcmp_(self, other, op): INPUT: - - ``other`` -- anything. To compare against the scheme - morphism ``self``. + - ``other`` -- anything; to compare against the scheme + morphism ``self`` - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -1949,9 +1905,7 @@ def scheme(self): """ Return the scheme whose point is represented. - OUTPUT: - - A scheme. + OUTPUT: a scheme EXAMPLES:: @@ -1964,15 +1918,16 @@ def scheme(self): def change_ring(self, R, check=True): r""" - Returns a new :class:`SchemeMorphism_point` which is this point coerced to ``R``. + Return a new :class:`SchemeMorphism_point` which is this point coerced + to ``R``. If ``check`` is true, then the initialization checks are performed. INPUT: - - ``R`` -- ring or morphism. + - ``R`` -- ring or morphism - - ``check`` -- Boolean + - ``check`` -- boolean OUTPUT: :class:`SchemeMorphism_point` @@ -2048,11 +2003,10 @@ def change_ring(self, R, check=True): def __copy__(self): r""" - Returns a copy of the :class:`SchemeMorphism_point` self coerced to `R`. - - OUTPUT: + Return a copy of the :class:`SchemeMorphism_point` ``self`` coerced to + `R`. - - :class:`SchemeMorphism_point` + OUTPUT: :class:`SchemeMorphism_point` EXAMPLES:: diff --git a/src/sage/schemes/generic/point.py b/src/sage/schemes/generic/point.py old mode 100644 new mode 100755 index 7ef85645f56..4158b350c16 --- a/src/sage/schemes/generic/point.py +++ b/src/sage/schemes/generic/point.py @@ -16,6 +16,7 @@ # or defined by a morphism. ######################################################## + class SchemePoint(Element): """ Base class for points on a scheme, either topological or defined @@ -41,7 +42,7 @@ def __init__(self, S, parent=None): def scheme(self): """ - Return the scheme on which self is a point. + Return the scheme on which ``self`` is a point. EXAMPLES:: @@ -72,9 +73,15 @@ def _repr_(self): # Topological points on a scheme ######################################################## + def is_SchemeTopologicalPoint(x): + from sage.misc.superseded import deprecation + deprecation(38296, + "The function is_SchemeTopologicalPoint is deprecated; " + "use 'isinstance(..., SchemeTopologicalPoint)' instead.") return isinstance(x, SchemeTopologicalPoint) + class SchemeTopologicalPoint(SchemePoint): """ Base class for topological points on schemes. @@ -170,8 +177,8 @@ def __init__(self, S, P, check=False): the Ideal (-x^2 + y*z) of Multivariate Polynomial Ring in x, y, z over Rational Field """ R = S.coordinate_ring() - from sage.rings.ideal import is_Ideal - if not is_Ideal(P): + from sage.rings.ideal import Ideal_generic + if not isinstance(P, Ideal_generic): P = R.ideal(P) elif P.ring() is not R: P = R.ideal(P.gens()) diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py old mode 100644 new mode 100755 index 715c9d2a687..5cae30dae3a --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -19,13 +19,17 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.structure.parent import Parent +from sage.categories.commutative_rings import CommutativeRings from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import +from sage.rings.ideal import Ideal_generic from sage.rings.integer_ring import ZZ -from sage.categories.commutative_rings import CommutativeRings -from sage.rings.ideal import is_Ideal -from sage.structure.unique_representation import UniqueRepresentation from sage.schemes.generic.point import SchemeTopologicalPoint_prime_ideal +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation + +lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') +lazy_import('sage.schemes.elliptic_curves.ell_generic', 'EllipticCurve_generic', as_='EllipticCurve') def is_Scheme(x): @@ -34,11 +38,9 @@ def is_Scheme(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - Boolean. Whether ``x`` derives from :class:`Scheme`. + OUTPUT: boolean; whether ``x`` derives from :class:`Scheme` EXAMPLES:: @@ -68,8 +70,8 @@ class Scheme(Parent): the base scheme. If a commutative ring is passed, the spectrum of the ring will be used as base. - - ``category`` -- the category (optional). Will be automatically - constructed by default. + - ``category`` -- the category (optional); will be automatically + constructed by default EXAMPLES:: @@ -102,9 +104,7 @@ def __init__(self, X=None, category=None): sage: RmodI = R.quotient(I) sage: X = Spec(RmodI) sage: TestSuite(X).run() # needs sage.libs.singular - """ - from sage.schemes.generic.morphism import is_SchemeMorphism from sage.categories.map import Map from sage.categories.rings import Rings @@ -112,7 +112,7 @@ def __init__(self, X=None, category=None): self._base_ring = ZZ elif isinstance(X, Scheme): self._base_scheme = X - elif is_SchemeMorphism(X): + elif isinstance(X, SchemeMorphism): self._base_morphism = X elif X in CommutativeRings(): self._base_ring = X @@ -203,15 +203,13 @@ def __call__(self, *args): """ Call syntax for schemes. - INPUT/OUTPUT: - - The arguments must be one of the following: + INPUT/OUTPUT: the arguments must be one of the following: - a ring or a scheme `S`. Output will be the set `X(S)` of `S`-valued points on `X`. - If `S` is a list or tuple or just the coordinates, return a - point in `X(T)`, where `T` is the base scheme of self. + point in `X(T)`, where `T` is the base scheme of ``self``. EXAMPLES:: @@ -277,11 +275,9 @@ def point_homset(self, S=None): INPUT: - - ``S`` -- a commutative ring. + - ``S`` -- a commutative ring - OUTPUT: - - The set of morphisms `\mathrm{Spec}(S) \to X`. + OUTPUT: the set of morphisms `\mathrm{Spec}(S) \to X` EXAMPLES:: @@ -320,9 +316,7 @@ def point(self, v, check=True): - ``check`` -- boolean (default: ``True``); whether to check the defining data for consistency - OUTPUT: - - A point of the scheme. + OUTPUT: a point of the scheme EXAMPLES:: @@ -380,7 +374,7 @@ def _point_homset(self, *args, **kwds): def __truediv__(self, Y): """ - Return the base extension of self to Y. + Return the base extension of ``self`` to Y. See :meth:`base_extend` for details. @@ -398,11 +392,9 @@ def __truediv__(self, Y): def base_ring(self): """ - Return the base ring of the scheme self. - - OUTPUT: + Return the base ring of the scheme ``self``. - A commutative ring. + OUTPUT: a commutative ring EXAMPLES:: @@ -429,9 +421,7 @@ def base_scheme(self): """ Return the base scheme. - OUTPUT: - - A scheme. + OUTPUT: a scheme EXAMPLES:: @@ -460,9 +450,7 @@ def base_morphism(self): Return the structure morphism from ``self`` to its base scheme. - OUTPUT: - - A scheme morphism. + OUTPUT: a scheme morphism EXAMPLES:: @@ -503,7 +491,7 @@ def coordinate_ring(self): OUTPUT: The global coordinate ring of this scheme, if - defined. Otherwise this raises a :class:`ValueError`. + defined. Otherwise this raises a :exc:`ValueError`. EXAMPLES:: @@ -523,9 +511,7 @@ def dimension_absolute(self): """ Return the absolute dimension of this scheme. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -549,9 +535,7 @@ def dimension_relative(self): """ Return the relative dimension of this scheme over its base. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -569,9 +553,7 @@ def identity_morphism(self): """ Return the identity morphism. - OUTPUT: - - The identity morphism of the scheme ``self``. + OUTPUT: the identity morphism of the scheme ``self`` EXAMPLES:: @@ -598,9 +580,7 @@ def hom(self, x, Y=None, check=True): - ``check`` -- boolean (default: ``True``); whether to check the defining data for consistency - OUTPUT: - - The scheme morphism from ``self`` to ``Y`` defined by ``x``. + OUTPUT: the scheme morphism from ``self`` to ``Y`` defined by ``x`` EXAMPLES:: @@ -630,11 +610,9 @@ def _Hom_(self, Y, category=None, check=True): Hom-set - ``check`` -- boolean (default: ``True``); whether - to check the defining data for consistency. - - OUTPUT: + to check the defining data for consistency - The set of morphisms from ``self`` to ``Y``. + OUTPUT: the set of morphisms from ``self`` to ``Y`` EXAMPLES:: @@ -664,7 +642,7 @@ def count_points(self, n): INPUT: - - ``n`` -- integer. + - ``n`` -- integer OUTPUT: @@ -704,7 +682,7 @@ def zeta_function(self): Derived classes should override this method. - OUTPUT: rational function in one variable. + OUTPUT: rational function in one variable EXAMPLES:: @@ -730,9 +708,7 @@ def zeta_series(self, n, t): - ``t`` -- the variable which the series should be returned - OUTPUT: - - A power series approximating the zeta function of ``self`` + OUTPUT: a power series approximating the zeta function of ``self`` EXAMPLES:: @@ -793,7 +769,7 @@ def zeta_series(self, n, t): def is_AffineScheme(x): """ - Return True if `x` is an affine scheme. + Return ``True`` if `x` is an affine scheme. EXAMPLES:: @@ -836,7 +812,6 @@ class AffineScheme(UniqueRepresentation, Scheme): For affine spaces over a base ring and subschemes thereof, see :class:`sage.schemes.generic.algebraic_scheme.AffineSpace`. - """ def __init__(self, R, S=None, category=None): """ @@ -906,9 +881,7 @@ def _repr_(self): """ Return a string representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -926,9 +899,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -944,9 +915,7 @@ def __call__(self, *args): """ Construct a scheme-valued or topological point of ``self``. - INPUT/OUTPUT: - - The argument ``x`` must be one of the following: + INPUT/OUTPUT: the argument ``x`` must be one of the following: - a prime ideal of the coordinate ring; the output will be the corresponding point of `X` @@ -1016,7 +985,7 @@ def __call__(self, *args): if len(args) == 1: x = args[0] if ((isinstance(x, self.element_class) and (x.parent() is self or x.parent() == self)) - or (is_Ideal(x) and x.ring() is self.coordinate_ring())): + or (isinstance(x, Ideal_generic) and x.ring() is self.coordinate_ring())): # Construct a topological point from x. return self._element_constructor_(x) try: @@ -1046,7 +1015,7 @@ def _element_constructor_(self, x): return x elif x.parent() == self: return self.element_class(self, x.prime_ideal()) - elif is_Ideal(x) and x.ring() is self.coordinate_ring(): + elif isinstance(x, Ideal_generic) and x.ring() is self.coordinate_ring(): return self.element_class(self, x) raise TypeError('cannot convert %s to a topological point of %s' % (x, self)) @@ -1054,9 +1023,7 @@ def _an_element_(self): r""" Return an element of the spectrum of the ring. - OUTPUT: - - A point of the affine scheme ``self``. + OUTPUT: a point of the affine scheme ``self`` EXAMPLES:: @@ -1074,9 +1041,7 @@ def coordinate_ring(self): """ Return the underlying ring of this scheme. - OUTPUT: - - A commutative ring. + OUTPUT: a commutative ring EXAMPLES:: @@ -1102,9 +1067,7 @@ def dimension_absolute(self): """ Return the absolute dimension of this scheme. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -1122,9 +1085,7 @@ def dimension_relative(self): """ Return the relative dimension of this scheme over its base. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -1188,9 +1149,7 @@ def hom(self, x, Y=None): - ``check`` -- boolean (default: ``True``); whether to check the defining data for consistency - OUTPUT: - - The scheme morphism from ``self`` to ``Y`` defined by ``x``. + OUTPUT: the scheme morphism from ``self`` to ``Y`` defined by ``x`` EXAMPLES: diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py old mode 100644 new mode 100755 index 93fc8b7e43c..5c699c0d004 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -54,7 +54,7 @@ def Spec(R, S=None): sage: A is B True - A :class:`TypeError` is raised if the input is not a commutative ring:: + A :exc:`TypeError` is raised if the input is not a commutative ring:: sage: Spec(5) Traceback (most recent call last): diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py old mode 100644 new mode 100755 index 46d01cfd2cb..b3c006b2c19 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -14,8 +14,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.schemes.projective.projective_space import ProjectiveSpace - from .hyperelliptic_generic import HyperellipticCurve_generic from .hyperelliptic_finite_field import HyperellipticCurve_finite_field from .hyperelliptic_rational_field import HyperellipticCurve_rational_field @@ -27,28 +25,27 @@ from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.rational_field import RationalField +from sage.schemes.projective.projective_space import ProjectiveSpace from sage.structure.dynamic_class import dynamic_class def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): r""" - Returns the hyperelliptic curve `y^2 + h y = f`, for + Return the hyperelliptic curve `y^2 + h y = f`, for univariate polynomials `h` and `f`. If `h` is not given, then it defaults to 0. INPUT: - - ``f`` -- univariate polynomial + - ``f`` -- univariate polynomial - - ``h`` -- optional univariate polynomial + - ``h`` -- (optional) univariate polynomial - - ``names`` (default: ``["x","y"]``) -- names for the - coordinate functions + - ``names`` -- (default: ``["x","y"]``) names for the coordinate functions - - ``check_squarefree`` (default: ``True``) -- test if - the input defines a hyperelliptic curve when f is - homogenized to degree `2g+2` and h to degree - `g+1` for some g. + - ``check_squarefree`` -- boolean (default: ``True``); test if the input + defines a hyperelliptic curve when f is homogenized to degree `2g+2` and + h to degree `g+1` for some `g` .. WARNING:: @@ -164,7 +161,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): Input with integer coefficients creates objects with the integers as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`). - In other words, it is checked that the discriminant is non-zero, but it is + In other words, it is checked that the discriminant is nonzero, but it is not checked whether the discriminant is a unit in `\ZZ^*`.:: sage: P. = ZZ[] @@ -205,7 +202,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): # rather than f and h, one of which might be constant. F = h**2 + 4 * f if not isinstance(F, Polynomial): - raise TypeError(f"arguments {f = } and {h = } must be polynomials") + raise TypeError(f"arguments f = {f} and h = {h} must be polynomials") P = F.parent() f = P(f) h = P(h) @@ -223,7 +220,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): # characteristic 2 if h == 0: raise ValueError( - f"for characteristic 2, argument {h = } must be non-zero" + f"for characteristic 2, argument h = {h} must be nonzero" ) if h[g + 1] == 0 and f[2 * g + 1] ** 2 == f[2 * g + 2] * h[g] ** 2: raise ValueError( diff --git a/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx b/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx old mode 100644 new mode 100755 index e0b0e77c568..2b14032ffc9 --- a/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx +++ b/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx @@ -78,7 +78,7 @@ def interval_products(M0, M1, target): INPUT: - ``M0``, ``M1`` -- matrices over `\ZZ/N\ZZ`, so that `M(t) = M_0 + M_1t` - - ``target`` -- a list of integers `a_0, b_0, \dots, a_n, b_n` + - ``target`` -- list of integers `a_0, b_0, \dots, a_n, b_n` ALGORITHM: @@ -116,7 +116,6 @@ def interval_products(M0, M1, target): [[20]] sage: [prod(Matrix(Integers(3^18), 1, 1, [t + 1]) for t in range(3,5))] [[20]] - """ # Sage objects that wrap the NTL objects cdef mat_ZZ_p_c mm0, mm1 @@ -128,8 +127,10 @@ def interval_products(M0, M1, target): cdef long dim = M0.nrows() sig_on() c.restore_c() + sig_off() set_ntl_matrix_modn_dense(mm0, c, M0) set_ntl_matrix_modn_dense(mm1, c, M1) + sig_on() for t in target: targ.push_back(ntl_ZZ(t).x) numintervals = len(target)/2 @@ -163,7 +164,7 @@ def hypellfrob(p, N, Q): - ``p`` -- a prime - ``Q`` -- a monic polynomial in `\ZZ[x]` of odd degree; must have no - multiple roots mod `p`. + multiple roots mod `p` - ``N`` -- precision parameter; the output matrix will be correct modulo `p^N` The prime `p` should satisfy `p > (2g+1)(2N-1)`, where `g = @@ -200,7 +201,6 @@ def hypellfrob(p, N, Q): Remove the restriction on `p`. Probably by merging in Robert's code, which eventually needs a fast C++/NTL implementation. - """ # Sage objects that wrap the NTL objects cdef ntl_ZZ pp @@ -244,7 +244,7 @@ def hypellfrob(p, N, Q): raise ValueError("Could not compute frobenius matrix" ", because the curve is singular at p.") - R = Qp(p, N, print_mode="terse") + R = Qp(p, N, print_mode='terse') prec = big_oh(p**N) data = [[mm[j, i]._integer_() + prec for i in range(2 * g)] for j in range(2 * g)] diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py old mode 100644 new mode 100755 index db37ec0c6d2..469e3eaa2f8 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py @@ -56,11 +56,13 @@ from sage.arith.misc import binomial from sage.rings.power_series_ring import PowerSeriesRing from . import hyperelliptic_generic -from sage.schemes.hyperelliptic_curves.hypellfrob import hypellfrob from sage.misc.cachefunc import cached_method from sage.matrix.constructor import identity_matrix, matrix from sage.misc.functional import rank -from sage.libs.pari.all import pari +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.libs.pari.all', 'pari') +lazy_import('sage.schemes.hyperelliptic_curves.hypellfrob', 'hypellfrob') from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_finite_field @@ -69,9 +71,9 @@ class HyperellipticCurve_finite_field(hyperelliptic_generic.HyperellipticCurve_g ProjectivePlaneCurve_finite_field): def _frobenius_coefficient_bound_charpoly(self): r""" - Computes bound on number of `p`-adic digits needed to recover + Compute bound on number of `p`-adic digits needed to recover frobenius polynomial computing the characteristic polynomial - of the frobenius matrix, i.e. returns `B` so that knowledge of + of the frobenius matrix, i.e. return `B` so that knowledge of `a_1`, ..., `a_g` modulo `p^B` determine frobenius polynomial uniquely. @@ -123,9 +125,9 @@ def _frobenius_coefficient_bound_charpoly(self): def _frobenius_coefficient_bound_traces(self, n=1): r""" - Computes bound on number of `p`-adic digits needed to recover + Compute bound on number of `p`-adic digits needed to recover the number of rational points on `n` extensions computing - traces of the frobenius matrix powers, i.e. returns `B` so that + traces of the frobenius matrix powers, i.e. return `B` so that knowledge of `\tr(M^1)`, ..., `\tr(M^n)` modulo `p^B` determine `N_1`, ..., `N_n` uniquely. @@ -182,7 +184,7 @@ def frobenius_matrix_hypellfrob(self, N=None): If `N` not supplied, a default value is selected, which is the minimum needed to recover the charpoly unambiguously. - .. note:: + .. NOTE:: Implemented using ``hypellfrob``, which means it only works over the prime field `GF(p)`, and requires `p > (2g+1)(2N-1)`. @@ -257,7 +259,7 @@ def frobenius_matrix(self, N=None, algorithm='hypellfrob'): If `N` not supplied, a default value is selected, which is the minimum needed to recover the charpoly unambiguously. - .. note:: + .. NOTE:: Currently only implemented using ``hypellfrob``, which means it only works over the prime field `GF(p)`, @@ -478,7 +480,7 @@ def frobenius_polynomial_pari(self): sage: H.frobenius_polynomial_pari() x^2 - 15*x + 12167 - Over prime fields of odd characteristic, `h` may be non-zero:: + Over prime fields of odd characteristic, `h` may be nonzero:: sage: K = GF(101) sage: R. = PolynomialRing(K) @@ -541,7 +543,7 @@ def frobenius_polynomial(self): sage: H.frobenius_polynomial() x^4 - 3*x^3 + 10*x^2 - 81*x + 729 - Over prime fields of odd characteristic, `h` may be non-zero:: + Over prime fields of odd characteristic, `h` may be nonzero:: sage: K = GF(101) sage: R. = PolynomialRing(K) @@ -968,7 +970,7 @@ def count_points_frobenius_polynomial(self, n=1, f=None): S = PowerSeriesRing(QQ, default_prec=n+1, names='t') frev = f.reverse() # the coefficients() method of power series only returns - # non-zero coefficients so let us use the list() method but + # nonzero coefficients so let us use the list() method but # this does not work for zero which gives the empty list flog = S(frev).log() return [q**(i+1) + 1 + ZZ((i+1)*flog[i+1]) for i in range(n)] @@ -1125,7 +1127,7 @@ def count_points(self, n=1): INPUT: - - ``n`` -- integer. + - ``n`` -- integer OUTPUT: @@ -1441,12 +1443,12 @@ def _Cartier_matrix_cached(self): r""" INPUT: - - 'E' -- Hyperelliptic Curve of the form `y^2 = f(x)` over a + - ``self`` -- Hyperelliptic Curve of the form `y^2 = f(x)` over a finite field, `\GF{q}` OUTPUT: - - matrix(Fq,M)' The matrix `M = (c_(pi-j)), f(x)^((p-1)/2) = \sum c_i x^i` + - 'matrix(Fq,M)' The matrix `M = (c_(pi-j)), f(x)^((p-1)/2) = \sum c_i x^i` - 'Coeff' List of Coeffs of F, this is needed for Hasse-Witt function. - 'g' genus of the curve self, this is needed by a-number. - 'Fq' is the base field of self, and it is needed for Hasse-Witt @@ -1576,11 +1578,13 @@ def Cartier_matrix(self): r""" INPUT: - - ``E`` : Hyperelliptic Curve of the form `y^2 = f(x)` over a finite field, `\GF{q}` + - ``self`` -- Hyperelliptic Curve of the form `y^2 = f(x)` over a + finite field, `\GF{q}` OUTPUT: - - ``M``: The matrix `M = (c_{pi-j})`, where `c_i` are the coefficients of `f(x)^{(p-1)/2} = \sum c_i x^i` + The matrix `M = (c_{pi-j})`, where `c_i` are the coefficients of + `f(x)^{(p-1)/2} = \sum c_i x^i`. REFERENCES: @@ -1774,11 +1778,13 @@ def Hasse_Witt(self): r""" INPUT: - - ``E`` : Hyperelliptic Curve of the form `y^2 = f(x)` over a finite field, `\GF{q}` + - ``self`` -- Hyperelliptic Curve of the form `y^2 = f(x)` over a + finite field, `\GF{q}` OUTPUT: - - ``N`` : The matrix `N = M M^p \dots M^{p^{g-1}}` where `M = c_{pi-j}`, and `f(x)^{(p-1)/2} = \sum c_i x^i` + The matrix `N = M M^p \dots M^{p^{g-1}}` where `M = c_{pi-j}`, and + `f(x)^{(p-1)/2} = \sum c_i x^i`. Reference-N. Yui. On the Jacobian varieties of hyperelliptic curves over fields of characteristic `p > 2`. @@ -1831,12 +1837,10 @@ def a_number(self): r""" INPUT: - - ``E``: Hyperelliptic Curve of the form `y^2 = f(x)` over a finite field, `\GF{q}` - - OUTPUT: - - - ``a`` : a-number + - ``self`` -- Hyperelliptic Curve of the form `y^2 = f(x)` over a + finite field, `\GF{q}` + OUTPUT: a-number EXAMPLES:: @@ -1873,12 +1877,10 @@ def p_rank(self): r""" INPUT: - - ``E`` : Hyperelliptic Curve of the form `y^2 = f(x)` over a finite field, `\GF{q}` - - OUTPUT: - - - ``pr`` :p-rank + - ``self`` -- Hyperelliptic Curve of the form `y^2 = f(x)` over a + finite field, `\GF{q}` + OUTPUT: p-rank EXAMPLES:: diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py old mode 100644 new mode 100755 index 4834152b606..61cd934c0a0 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py @@ -33,15 +33,18 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +import sage.schemes.curves.projective_curve as plane_curve + +from sage.misc.lazy_import import lazy_import from sage.rings.big_oh import O -from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.laurent_series_ring import LaurentSeriesRing +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.real_mpfr import RR -from sage.functions.all import log from sage.structure.category_object import normalize_names -import sage.schemes.curves.projective_curve as plane_curve +lazy_import("sage.functions.all", "log") + def is_HyperellipticCurve(C): """ @@ -127,7 +130,7 @@ def __init__(self, PP, f, h=None, names=None, genus=None): def change_ring(self, R): """ - Returns this HyperellipticCurve over a new base ring ``R``. + Return this HyperellipticCurve over a new base ring ``R``. EXAMPLES:: @@ -169,16 +172,44 @@ def _repr_(self): Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22 sage: C = HyperellipticCurve(f,names='u,v'); C Hyperelliptic Curve over Rational Field defined by v^2 = 4*u^5 - 30*u^3 + 45*u - 22 + sage: C = HyperellipticCurve(x^5 + 1, x^3 + 2); C + Hyperelliptic Curve over Rational Field defined by y^2 + (x^3 + 2)*y = x^5 + 1 """ f, h = self._hyperelliptic_polynomials R = self.base_ring() y = self._printing_ring.gen() x = self._printing_ring.base_ring().gen() - if h == 0: + if h.is_zero(): return "Hyperelliptic Curve over %s defined by %s = %s" % (R, y**2, f(x)) - else: - return "Hyperelliptic Curve over %s defined by %s + %s = %s" % (R, y**2, h(x)*y, f(x)) + return "Hyperelliptic Curve over %s defined by %s + %s = %s" % (R, y**2, h(x)*y, f(x)) + + def _latex_(self): + r""" + LaTeX representation of hyperelliptic curves. + + EXAMPLES:: + + sage: P. = QQ[] + sage: f = 4*x^5 - 30*x^3 + 45*x - 22 + sage: C = HyperellipticCurve(f); latex(C) + \text{Hyperelliptic Curve over $\Bold{Q}$ defined by $y^{2} = 4 x^{5} - 30 x^{3} + 45 x - 22$} + sage: C = HyperellipticCurve(f,names='u,v'); latex(C) + \text{Hyperelliptic Curve over $\Bold{Q}$ defined by $v^{2} = 4 u^{5} - 30 u^{3} + 45 u - 22$} + sage: C = HyperellipticCurve(x^5 + 1, x^2 + 3); latex(C) + \text{Hyperelliptic Curve over $\Bold{Q}$ defined by $y^{2} + \left(x^{2} + 3\right) y = x^{5} + 1$} + """ + + f, h = self._hyperelliptic_polynomials + R = self.base_ring() + y = self._printing_ring.gen() + x = self._printing_ring.base_ring().gen() + if h.is_zero(): + return (fr'\text{{Hyperelliptic Curve over ${R._latex_()}$ ' + f'defined by ${(y**2)._latex_()} = {(f(x))._latex_()}$}}') + return (fr'\text{{Hyperelliptic Curve over ${R._latex_()}$ ' + f'defined by ${(y**2)._latex_()} + {(h(x)*y)._latex_()} = ' + f'{(f(x))._latex_()}$}}') def hyperelliptic_polynomials(self, K=None, var='x'): """ @@ -198,7 +229,7 @@ def hyperelliptic_polynomials(self, K=None, var='x'): def is_singular(self): r""" - Returns False, because hyperelliptic curves are smooth projective + Return ``False``, because hyperelliptic curves are smooth projective curves, as checked on construction. EXAMPLES:: @@ -226,7 +257,7 @@ def is_singular(self): def is_smooth(self): r""" - Returns True, because hyperelliptic curves are smooth projective + Return ``True``, because hyperelliptic curves are smooth projective curves, as checked on construction. EXAMPLES:: @@ -255,7 +286,7 @@ def is_smooth(self): def is_x_coord(self, x): """ - Return True if ``x`` is the `x`-coordinate of a point on this curve. + Return ``True`` if ``x`` is the `x`-coordinate of a point on this curve. .. SEEALSO:: @@ -268,9 +299,8 @@ def is_x_coord(self, x): - ``x`` -- an element of the base ring of the curve - OUTPUT: - - A bool stating whether or not `x` is a x-coordinate of a point on the curve + OUTPUT: boolean stating whether or not `x` is a x-coordinate of a point + on the curve EXAMPLES: @@ -370,13 +400,11 @@ def lift_x(self, x, all=False): - ``x`` -- an element of the base ring of the curve - - ``all`` (bool, default ``False``) -- if ``True``, return a - (possibly empty) list of all points; if ``False``, return - just one point, or raise a :class:`ValueError` if there are none. + - ``all`` -- boolean (default: ``False``); if ``True``, return a + (possibly empty) list of all points. If ``False``, return + just one point, or raise a :exc:`ValueError` if there are none. - OUTPUT: - - A point or list of up to two points on this curve. + OUTPUT: a point or list of up to two points on this curve .. SEEALSO:: @@ -522,7 +550,8 @@ def jacobian(self): def odd_degree_model(self): r""" - Return an odd degree model of self, or raise ValueError if one does not exist over the field of definition. + Return an odd degree model of ``self``, or raise :exc:`ValueError` if + one does not exist over the field of definition. EXAMPLES:: @@ -603,7 +632,8 @@ def odd_degree_model(self): def has_odd_degree_model(self): r""" - Return True if an odd degree model of self exists over the field of definition; False otherwise. + Return ``True`` if an odd degree model of ``self`` exists over the + field of definition; ``False`` otherwise. Use ``odd_degree_model`` to calculate an odd degree model. @@ -654,8 +684,8 @@ def monsky_washnitzer_gens(self): def invariant_differential(self): """ - Returns `dx/2y`, as an element of the Monsky-Washnitzer cohomology - of self + Return `dx/2y`, as an element of the Monsky-Washnitzer cohomology + of ``self``. EXAMPLES:: @@ -663,7 +693,6 @@ def invariant_differential(self): sage: C = HyperellipticCurve(x^5 - 4*x + 4) sage: C.invariant_differential() 1 dx/2y - """ import sage.schemes.hyperelliptic_curves.monsky_washnitzer as m_w S = m_w.SpecialHyperellipticQuotientRing(self) @@ -678,8 +707,8 @@ def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'): INPUT: - - ``P = (a, b)`` -- a non-Weierstrass point on self - - ``prec`` -- desired precision of the local coordinates + - ``P = (a, b)`` -- a non-Weierstrass point on ``self`` + - ``prec`` -- desired precision of the local coordinates - ``name`` -- gen of the power series ring (default: ``t``) OUTPUT: @@ -730,7 +759,7 @@ def local_coordinates_at_weierstrass(self, P, prec=20, name='t'): INPUT: - - ``P`` -- a finite Weierstrass point on self + - ``P`` -- a finite Weierstrass point on ``self`` - ``prec`` -- desired precision of the local coordinates - ``name`` -- gen of the power series ring (default: `t`) @@ -832,11 +861,11 @@ def local_coordinates_at_infinity(self, prec=20, name='t'): def local_coord(self, P, prec=20, name='t'): """ - Calls the appropriate local_coordinates function + Call the appropriate local_coordinates function. INPUT: - - ``P`` -- a point on self + - ``P`` -- a point on ``self`` - ``prec`` -- desired precision of the local coordinates - ``name`` -- generator of the power series ring (default: ``t``) diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py old mode 100644 new mode 100755 index 018d60c22f8..654e33c80fc --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py @@ -12,23 +12,23 @@ # https://www.gnu.org/licenses/ # **************************************************************************** - -from sage.rings.power_series_ring import PowerSeriesRing -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.matrix.constructor import matrix +from sage.misc.lazy_import import lazy_import +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector +from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.rings.infinity import Infinity from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.rational_field import QQ -from sage.rings.padics.factory import Qp as pAdicField -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF -from sage.rings.real_mpfr import RR from sage.rings.rational_field import RationalField -from sage.rings.infinity import Infinity -from sage.functions.log import log -from sage.modules.free_module import VectorSpace -from sage.matrix.constructor import matrix -from sage.modules.free_module_element import vector - +from sage.rings.real_mpfr import RR from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_field +lazy_import("sage.functions.log", "log") +lazy_import("sage.rings.padics.factory", "Qp", as_="pAdicField") + from . import hyperelliptic_generic @@ -50,7 +50,7 @@ def local_analytic_interpolation(self, P, Q): INPUT: - - P and Q points on self in the same residue disc + - ``P``, ``Q`` -- points on ``self`` in the same residue disc OUTPUT: @@ -149,9 +149,9 @@ def local_analytic_interpolation(self, P, Q): def weierstrass_points(self): """ - Return the Weierstrass points of self defined over self.base_ring(), - that is, the point at infinity and those points in the support - of the divisor of `y` + Return the Weierstrass points of ``self`` defined over + ``self.base_ring()``, that is, the point at infinity and those points + in the support of the divisor of `y`. EXAMPLES:: @@ -168,7 +168,7 @@ def weierstrass_points(self): def is_in_weierstrass_disc(self, P): """ - Checks if `P` is in a Weierstrass disc + Check if `P` is in a Weierstrass disc. EXAMPLES:: @@ -198,7 +198,8 @@ def is_in_weierstrass_disc(self, P): def is_weierstrass(self, P): """ - Checks if `P` is a Weierstrass point (i.e., fixed by the hyperelliptic involution) + Check if `P` is a Weierstrass point (i.e., fixed by the hyperelliptic + involution). EXAMPLES:: @@ -228,8 +229,8 @@ def is_weierstrass(self, P): def find_char_zero_weier_point(self, Q): """ - Given `Q` a point on self in a Weierstrass disc, finds the - center of the Weierstrass disc (if defined over self.base_ring()) + Given `Q` a point on ``self`` in a Weierstrass disc, finds the + center of the Weierstrass disc (if defined over ``self.base_ring()``). EXAMPLES:: @@ -263,7 +264,7 @@ def find_char_zero_weier_point(self, Q): def residue_disc(self, P): """ - Gives the residue disc of `P` + Give the residue disc of `P`. EXAMPLES:: @@ -309,7 +310,7 @@ def residue_disc(self, P): def is_same_disc(self, P, Q): """ - Checks if `P,Q` are in same residue disc + Check if `P,Q` are in same residue disc. EXAMPLES:: @@ -338,13 +339,11 @@ def tiny_integrals(self, F, P, Q): INPUT: - - F a list of functions `f_i` - - P a point on self - - Q a point on self (in the same residue disc as P) - - OUTPUT: + - ``F`` -- list of functions `f_i` + - ``P`` -- point on ``self`` + - ``Q`` -- point on ``self`` (in the same residue disc as `P`) - The integrals `\int_P^Q f_i dx/2y` + OUTPUT: the integrals `\int_P^Q f_i dx/2y` EXAMPLES:: @@ -373,7 +372,6 @@ def tiny_integrals(self, F, P, Q): Traceback (most recent call last): ... ValueError: (11^-2 + O(11^3) : 11^-5 + 8*11^-2 + O(11^0) : 1 + O(11^5)) and (0 : 3 + 8*11 + 2*11^2 + 8*11^3 + 2*11^4 + O(11^5) : 1 + O(11^5)) are not in the same residue disc - """ x, y, z = self.local_analytic_interpolation(P, Q) #homogeneous coordinates x = x/z @@ -402,12 +400,10 @@ def tiny_integrals_on_basis(self, P, Q): INPUT: - - P a point on self - - Q a point on self (in the same residue disc as P) - - OUTPUT: + - ``P`` -- point on ``self`` + - ``Q`` -- point on ``self`` (in the same residue disc as `P`) - The integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` + OUTPUT: the integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` EXAMPLES:: @@ -436,7 +432,6 @@ def tiny_integrals_on_basis(self, P, Q): Traceback (most recent call last): ... ValueError: (11^-2 + O(11^3) : 11^-5 + 8*11^-2 + O(11^0) : 1 + O(11^5)) and (0 : 3 + 8*11 + 2*11^2 + 8*11^3 + 2*11^4 + O(11^5) : 1 + O(11^5)) are not in the same residue disc - """ if P == Q: V = VectorSpace(self.base_ring(), 2*self.genus()) @@ -477,17 +472,16 @@ def teichmuller(self, P): def coleman_integrals_on_basis(self, P, Q, algorithm=None): r""" - Computes the Coleman integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` + Compute the Coleman integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}`. INPUT: - - P point on self - - Q point on self - - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) - - OUTPUT: + - ``P`` -- point on ``self`` + - ``Q`` -- point on ``self`` + - ``algorithm`` -- ``None`` (default, uses Frobenius) or teichmuller + (uses Teichmuller points) - the Coleman integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` + OUTPUT: the Coleman integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` EXAMPLES:: @@ -705,14 +699,13 @@ def coleman_integral(self, w, P, Q, algorithm='None'): INPUT: - - w differential (if one of P,Q is Weierstrass, w must be odd) - - P point on self - - Q point on self - - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) - - OUTPUT: + - ``w`` -- differential (if one of P,Q is Weierstrass, w must be odd) + - ``P`` -- point on ``self`` + - ``Q`` -- point on ``self`` + - ``algorithm`` -- ``None`` (default, uses Frobenius) or teichmuller + (uses Teichmuller points) - the Coleman integral `\int_P^Q w` + OUTPUT: the Coleman integral `\int_P^Q w` EXAMPLES: @@ -837,7 +830,6 @@ def coleman_integral(self, w, P, Q, algorithm='None'): - Robert Bradshaw (2007-03) - Kiran Kedlaya (2008-05) - Jennifer Balakrishnan (2010-02) - """ # TODO: implement Jacobians and show the relationship directly import sage.schemes.hyperelliptic_curves.monsky_washnitzer as monsky_washnitzer @@ -872,7 +864,7 @@ def coleman_integral(self, w, P, Q, algorithm='None'): def frobenius(self, P=None): """ - Returns the `p`-th power lift of Frobenius of `P` + Return the `p`-th power lift of Frobenius of `P`. EXAMPLES:: @@ -963,7 +955,7 @@ def _frob(P): def newton_sqrt(self, f, x0, prec): r""" - Takes the square root of the power series `f` by Newton's method + Take the square root of the power series `f` by Newton's method. NOTE: @@ -1009,11 +1001,9 @@ def curve_over_ram_extn(self, deg): INPUT: - - deg: the degree of the ramified extension - - OUTPUT: + - ``deg`` -- the degree of the ramified extension - ``self`` over `\QQ_p(p^(1/deg))` + OUTPUT: ``self`` over `\QQ_p(p^(1/deg))` EXAMPLES:: @@ -1028,7 +1018,6 @@ def curve_over_ram_extn(self, deg): AUTHOR: - Jennifer Balakrishnan - """ from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve K = self.base_ring() @@ -1045,16 +1034,15 @@ def curve_over_ram_extn(self, deg): def get_boundary_point(self, curve_over_extn, P): """ - Given self over an extension field, find a point in the disc of `P` near the boundary + Given ``self`` over an extension field, find a point in the disc of `P` + near the boundary. INPUT: - - curve_over_extn: self over a totally ramified extension - - P: Weierstrass point - - OUTPUT: + - ``curve_over_extn`` -- ``self`` over a totally ramified extension + - ``P`` -- Weierstrass point - a point in the disc of `P` near the boundary + OUTPUT: a point in the disc of `P` near the boundary EXAMPLES:: @@ -1072,7 +1060,6 @@ def get_boundary_point(self, curve_over_extn, P): AUTHOR: - Jennifer Balakrishnan - """ J = curve_over_extn.base_ring() a = J.gen() @@ -1082,17 +1069,15 @@ def get_boundary_point(self, curve_over_extn, P): def P_to_S(self, P, S): r""" - Given a finite Weierstrass point `P` and a point `S` - in the same disc, computes the Coleman integrals `\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}` + Given a finite Weierstrass point `P` and a point `S` in the same disc, + compute the Coleman integrals `\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}`. INPUT: - - P: finite Weierstrass point - - S: point in disc of P - - OUTPUT: + - ``P`` -- finite Weierstrass point + - ``S`` -- point in disc of `P` - Coleman integrals `\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}` + OUTPUT: Coleman integrals `\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}` EXAMPLES:: @@ -1109,7 +1094,6 @@ def P_to_S(self, P, S): AUTHOR: - Jennifer Balakrishnan - """ prec = self.base_ring().precision_cap() deg = (S[0]).parent().defining_polynomial().degree() @@ -1123,18 +1107,16 @@ def P_to_S(self, P, S): def coleman_integral_P_to_S(self, w, P, S): r""" Given a finite Weierstrass point `P` and a point `S` - in the same disc, computes the Coleman integral `\int_P^S w` + in the same disc, compute the Coleman integral `\int_P^S w`. INPUT: - - w: differential - - P: Weierstrass point - - S: point in the same disc of P (S is defined over an extension of `\QQ_p`; coordinates - of S are given in terms of uniformizer `a`) + - ``w`` -- differential + - ``P`` -- Weierstrass point + - ``S`` -- point in the same disc of `P` (S is defined over an extension + of `\QQ_p`; coordinates of S are given in terms of uniformizer `a`) - OUTPUT: - - Coleman integral `\int_P^S w` in terms of `a` + OUTPUT: Coleman integral `\int_P^S w` in terms of `a` EXAMPLES:: @@ -1155,7 +1137,6 @@ def coleman_integral_P_to_S(self, w, P, S): AUTHOR: - Jennifer Balakrishnan - """ prec = self.base_ring().precision_cap() deg = S[0].parent().defining_polynomial().degree() @@ -1167,20 +1148,20 @@ def coleman_integral_P_to_S(self, w, P, S): def S_to_Q(self, S, Q): r""" - Given `S` a point on self over an extension field, computes the - Coleman integrals `\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}` + Given `S` a point on ``self`` over an extension field, compute the + Coleman integrals `\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}`. **one should be able to feed `S,Q` into coleman_integral, but currently that segfaults** INPUT: - - S: a point with coordinates in an extension of `\QQ_p` (with unif. a) - - Q: a non-Weierstrass point defined over `\QQ_p` + - ``S`` -- a point with coordinates in an extension of `\QQ_p` (with unif. a) + - ``Q`` -- a non-Weierstrass point defined over `\QQ_p` OUTPUT: - the Coleman integrals `\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}` in terms of `a` + The Coleman integrals `\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}` in terms of `a`. EXAMPLES:: @@ -1205,7 +1186,6 @@ def S_to_Q(self, S, Q): AUTHOR: - Jennifer Balakrishnan - """ FS = self.frobenius(S) FS = (FS[0],FS[1]) @@ -1252,20 +1232,18 @@ def S_to_Q(self, S, Q): def coleman_integral_S_to_Q(self, w, S, Q): r""" - Compute the Coleman integral `\int_S^Q w` + Compute the Coleman integral `\int_S^Q w`. **one should be able to feed `S,Q` into coleman_integral, but currently that segfaults** INPUT: - - w: a differential - - S: a point with coordinates in an extension of `\QQ_p` - - Q: a non-Weierstrass point defined over `\QQ_p` - - OUTPUT: + - ``w`` -- a differential + - ``S`` -- a point with coordinates in an extension of `\QQ_p` + - ``Q`` -- a non-Weierstrass point defined over `\QQ_p` - the Coleman integral `\int_S^Q w` + OUTPUT: the Coleman integral `\int_S^Q w` EXAMPLES:: @@ -1308,15 +1286,15 @@ def coleman_integral_S_to_Q(self, w, S, Q): def coleman_integral_from_weierstrass_via_boundary(self, w, P, Q, d): r""" - Computes the Coleman integral `\int_P^Q w` via a boundary point + Compute the Coleman integral `\int_P^Q w` via a boundary point in the disc of `P`, defined over a degree `d` extension INPUT: - - w: a differential - - P: a Weierstrass point - - Q: a non-Weierstrass point - - d: degree of extension where coordinates of boundary point lie + - ``w`` -- a differential + - ``P`` -- a Weierstrass point + - ``Q`` -- a non-Weierstrass point + - ``d`` -- degree of extension where coordinates of boundary point lie OUTPUT: diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py old mode 100644 new mode 100755 index 1e33f9b67fd..dc9ddc3e3f5 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py @@ -9,10 +9,11 @@ import sage.rings.abc -from sage.rings.padics.factory import Qp as pAdicField - +from sage.misc.lazy_import import lazy_import from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_field +lazy_import('sage.rings.padics.factory', 'Qp', as_='pAdicField') + from . import hyperelliptic_generic @@ -29,12 +30,12 @@ def matrix_of_frobenius(self, p, prec=20): INPUT: - - ``p`` (prime integer or pAdic ring / field) -- if ``p`` is an integer, + - ``p`` -- prime integer or pAdic ring / field; if ``p`` is an integer, constructs a ``pAdicField`` with ``p`` to compute the matrix of - Frobenius, otherwise uses the supplied pAdic ring or field. + Frobenius, otherwise uses the supplied pAdic ring or field - - ``prec`` (optional) -- if ``p`` is an prime integer, the `p`-adic - precision of the coefficient ring constructed. + - ``prec`` -- (optional) if ``p`` is an prime integer, the `p`-adic + precision of the coefficient ring constructed EXAMPLES:: @@ -66,7 +67,7 @@ def matrix_of_frobenius(self, p, prec=20): def lseries(self, prec=53): """ - Return the L-series of this hyperelliptic curve of genus 2. + Return the `L`-series of this hyperelliptic curve of genus 2. EXAMPLES:: diff --git a/src/sage/schemes/hyperelliptic_curves/invariants.py b/src/sage/schemes/hyperelliptic_curves/invariants.py old mode 100644 new mode 100755 index 7e3e659ba00..3910594a5af --- a/src/sage/schemes/hyperelliptic_curves/invariants.py +++ b/src/sage/schemes/hyperelliptic_curves/invariants.py @@ -18,7 +18,7 @@ def diffxy(f, x, xtimes, y, ytimes): r""" Differentiate a polynomial ``f``, ``xtimes`` with respect to ``x``, and - ```ytimes`` with respect to ``y``. + ``ytimes`` with respect to ``y``. EXAMPLES:: diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py b/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py old mode 100644 new mode 100755 index f72f7bab6e7..032bc3105ba --- a/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py @@ -92,11 +92,12 @@ from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.finite_rings.finite_field_constructor import FiniteField -from sage.rings.number_field.number_field import NumberField from sage.misc.lazy_import import lazy_import from sage.rings.fast_arith import prime_range from sage.arith.misc import GCD as gcd + lazy_import('sage.interfaces.genus2reduction', ['genus2reduction', 'Genus2reduction']) +lazy_import('sage.rings.number_field.number_field', 'NumberField') def satisfies_coefficient_condition(g, p): @@ -141,11 +142,11 @@ def get_is_geom_field(f, C, bad_primes, B=200): INPUT: - - ``f`` -- a polynomial defining the hyperelliptic curve. + - ``f`` -- a polynomial defining the hyperelliptic curve - - ``C`` -- the hyperelliptic curve. + - ``C`` -- the hyperelliptic curve - - ``bad_primes`` -- the list of odd primes of bad reduction. + - ``bad_primes`` -- the list of odd primes of bad reduction - ``B`` -- (default: 200) the bound which appears in the statement of the algorithm from [Lom2019]_ @@ -251,9 +252,9 @@ def is_geom_trivial_when_field(C, bad_primes, B=200): INPUT: - - ``C`` -- the hyperelliptic curve. + - ``C`` -- the hyperelliptic curve - - ``bad_primes`` -- the list of odd primes of bad reduction. + - ``bad_primes`` -- the list of odd primes of bad reduction - ``B`` -- (default: 200) the bound which appears in the statement of the algorithm from [Lom2019]_ diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_g2.py b/src/sage/schemes/hyperelliptic_curves/jacobian_g2.py index b4b4259326e..970bb9cfbf0 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_g2.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_g2.py @@ -22,6 +22,7 @@ # + (4*a4 + 2*c0*c4 + c2^2)*x^4 + (4*a6 + 2*c0*c6 + 2*c2*c4)*x^3 # + (4*a8 + 2*c2*c6 + c4^2)*x^2 + (4*a10 + 2*c4*c6)*x + 4*a12 + c6^2 + class HyperellipticJacobian_g2(jacobian_generic.HyperellipticJacobian_generic): def kummer_surface(self): try: diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py old mode 100644 new mode 100755 index c4544e7cdfc..efc2a805bc0 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py @@ -146,9 +146,7 @@ def dimension(self): """ Return the dimension of this Jacobian. - OUTPUT: - - Integer + OUTPUT: integer EXAMPLES:: @@ -191,11 +189,9 @@ def _have_established_geometrically_trivial(self): INPUT: - - ``self`` -- The Jacobian. - - OUTPUT: + - ``self`` -- the Jacobian - The boolean ``False``; this will be updated by other methods. + OUTPUT: the boolean ``False``; this will be updated by other methods EXAMPLES: @@ -222,11 +218,9 @@ def _have_established_geometrically_field(self): INPUT: - - ``self`` -- The Jacobian. + - ``self`` -- the Jacobian - OUTPUT: - - The boolean ``False``; this will be updated by other methods. + OUTPUT: the boolean ``False``; this will be updated by other methods EXAMPLES: @@ -253,9 +247,9 @@ def geometric_endomorphism_algebra_is_field(self, B=200, proof=False): - ``B`` -- (default: 200) the bound which appears in the statement of the algorithm from [Lom2019]_ - - ``proof`` -- (default: ``False``) whether or not to insist on a provably - correct answer. This is related to the warning in the docstring - of this module: if this function returns ``False``, then + - ``proof`` -- boolean (default: ``False``); whether or not to insist + on a provably correct answer. This is related to the warning in the + docstring of this module: if this function returns ``False``, then strictly speaking this has not been proven to be ``False`` until one has exhibited a non-trivial endomorphism, which these methods are not designed to carry out. If one is convinced that this method should @@ -324,14 +318,14 @@ def geometric_endomorphism_ring_is_ZZ(self, B=200, proof=False): - ``B`` -- (default: 200) the bound which appears in the statement of the algorithm from [Lom2019]_ - - ``proof`` -- (default: ``False``) whether or not to insist on a provably - correct answer. This is related to the warning in the module docstring - of `jacobian_endomorphisms.py`: if this function returns ``False``, then - strictly speaking this has not been proven to be ``False`` until one has - exhibited a non-trivial endomorphism, which the methods in that module - are not designed to carry out. If one is convinced that this method - should return ``True``, but it is returning ``False``, then this can be - exhibited by increasing `B`. + - ``proof`` -- boolean (default: ``False``); whether or not to insist + on a provably correct answer. This is related to the warning in the + module docstring of `jacobian_endomorphisms.py`: if this function + returns ``False``, then strictly speaking this has not been proven to + be ``False`` until one has exhibited a non-trivial endomorphism, + which the methods in that module are not designed to carry out. If + one is convinced that this method should return ``True``, but it is + returning ``False``, then this can be exhibited by increasing `B`. OUTPUT: diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py index 2a192248180..0fdea5814f0 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py @@ -42,14 +42,15 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.integer_ring import ZZ +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_element import Polynomial - +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.schemes.generic.homset import SchemeHomset_points -from sage.schemes.generic.morphism import is_SchemeMorphism -from .jacobian_morphism import JacobianMorphism_divisor_class_field +from sage.schemes.hyperelliptic_curves.jacobian_morphism import JacobianMorphism_divisor_class_field + +lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') class JacobianHomset_divisor_classes(SchemeHomset_points): @@ -111,43 +112,53 @@ def __call__(self, P): (x + 2, y) sage: D1 + D2 (x^2 + 2*x + 2, y + 2*x + 1) + + TESTS: + + Test :issue:`38459`:: + + sage: K. = QQ[] + sage: C = HyperellipticCurve(u^5 - 1) + sage: J = C.jacobian() + sage: J(u - 1, 0) + (x - 1, y) """ if isinstance(P, (Integer, int)) and P == 0: - R = PolynomialRing(self.value_ring(), 'x') + R = self.curve().hyperelliptic_polynomials()[0].parent().change_ring(self.value_ring()) return JacobianMorphism_divisor_class_field(self, (R.one(), R.zero())) elif isinstance(P, (list, tuple)): if len(P) == 1 and P[0] == 0: - R = PolynomialRing(self.value_ring(), 'x') + R = self.curve().hyperelliptic_polynomials()[0].parent().change_ring(self.value_ring()) return JacobianMorphism_divisor_class_field(self, (R.one(), R.zero())) elif len(P) == 2: P1 = P[0] P2 = P[1] if isinstance(P1, Integer) and isinstance(P2, Integer): - R = PolynomialRing(self.value_ring(), 'x') + R = self.curve().hyperelliptic_polynomials()[0].parent().change_ring(self.value_ring()) P1 = R(P1) P2 = R(P2) return JacobianMorphism_divisor_class_field(self, (P1, P2)) if isinstance(P1, Integer) and isinstance(P2, Polynomial): - R = PolynomialRing(self.value_ring(), 'x') + R = self.curve().hyperelliptic_polynomials()[0].parent().change_ring(self.value_ring()) P1 = R(P1) return JacobianMorphism_divisor_class_field(self, (P1, P2)) if isinstance(P2, Integer) and isinstance(P1, Polynomial): - R = PolynomialRing(self.value_ring(), 'x') + R = self.curve().hyperelliptic_polynomials()[0].parent().change_ring(self.value_ring()) P2 = R(P2) return JacobianMorphism_divisor_class_field(self, (P1, P2)) if isinstance(P1, Polynomial) and isinstance(P2, Polynomial): return JacobianMorphism_divisor_class_field(self, tuple(P)) - if is_SchemeMorphism(P1) and is_SchemeMorphism(P2): + if isinstance(P1, SchemeMorphism) and isinstance(P2, SchemeMorphism): return self(P1) - self(P2) raise TypeError("argument P (= %s) must have length 2" % P) elif isinstance(P, JacobianMorphism_divisor_class_field) and self == P.parent(): return P - elif is_SchemeMorphism(P): + elif isinstance(P, SchemeMorphism): x0 = P[0] y0 = P[1] - R, x = PolynomialRing(self.value_ring(), 'x').objgen() + R, x = self.curve().hyperelliptic_polynomials()[0].parent().change_ring(self.value_ring()).objgen() return self((x - x0, R(y0))) raise TypeError("argument P (= %s) does not determine a divisor class" % P) diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py old mode 100644 new mode 100755 index 0a820f5bda6..c0cbccd84ea --- a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py @@ -210,6 +210,7 @@ def cantor_reduction(a, b, f, h, genus): return cantor_reduction(a, b, f, h, genus) return (a, b) + def cantor_composition_simple(D1,D2,f,genus): r""" Given `D_1` and `D_2` two reduced Mumford @@ -268,6 +269,7 @@ def cantor_composition_simple(D1,D2,f,genus): a = a.monic() return (a, b) + def cantor_composition(D1,D2,f,h,genus): r""" EXAMPLES:: @@ -361,11 +363,10 @@ def __init__(self, parent, polys, check=True): INPUT: - - parent -- the parent Homset - - polys -- Mumford's `u` and `v` polynomials - - check (default: ``True``) -- if ``True``, ensure that - polynomials define a divisor on the appropriate curve and are - reduced + - ``parent`` -- the parent Homset + - ``polys`` -- Mumford's `u` and `v` polynomials + - ``check`` -- boolean (default: ``True``); if ``True``, ensure that + polynomials define a divisor on the appropriate curve and are reduced .. warning:: @@ -589,7 +590,7 @@ def point_of_jacobian_of_curve(self): def __list__(self): r""" Return a list `(a(x), b(x))` of the polynomials giving the - Mumford representation of self. + Mumford representation of ``self``. TESTS:: @@ -613,7 +614,7 @@ def __list__(self): def __tuple__(self): r""" Return a tuple `(a(x), b(x))` of the polynomials giving the - Mumford representation of self. + Mumford representation of ``self``. TESTS:: @@ -637,7 +638,7 @@ def __tuple__(self): def __getitem__(self, n): r""" Return the `n`-th item of the pair `(a(x), b(x))` - of polynomials giving the Mumford representation of self. + of polynomials giving the Mumford representation of ``self``. TESTS:: @@ -667,7 +668,7 @@ def __getitem__(self, n): def _richcmp_(self, other, op): r""" - Compare self and other. + Compare ``self`` and ``other``. TESTS:: @@ -789,7 +790,6 @@ def __neg__(self): (u^2 - t, v + u + 1) sage: Q + (-Q) # indirect doctest (1) - """ if self.is_zero(): return self @@ -810,7 +810,7 @@ def __neg__(self): def _add_(self,other): r""" - Return a Mumford representative of the divisor self + other. + Return a Mumford representative of the divisor ``self + other``. EXAMPLES:: @@ -841,7 +841,7 @@ def _add_(self,other): def _sub_(self, other): r""" - Return a Mumford representative of the divisor self - other. + Return a Mumford representative of the divisor ``self - other``. EXAMPLES:: diff --git a/src/sage/schemes/hyperelliptic_curves/kummer_surface.py b/src/sage/schemes/hyperelliptic_curves/kummer_surface.py index dadf1200f01..8cf0104c560 100644 --- a/src/sage/schemes/hyperelliptic_curves/kummer_surface.py +++ b/src/sage/schemes/hyperelliptic_curves/kummer_surface.py @@ -25,6 +25,7 @@ # + (2*c3*c9 + c6^2 + 4*a8)*x^4 + (2*c0*c9 + 2*c3*c6 + 4*a6)*x^3 # + (2*c0*c6 + c3^2 + 4*a4)*x^2 + (2*c0*c3 + 4*a2)*x + c0^2 + 4*a0 + class KummerSurface(AlgebraicScheme_subscheme_projective): def __init__(self, J): """ diff --git a/src/sage/schemes/hyperelliptic_curves/meson.build b/src/sage/schemes/hyperelliptic_curves/meson.build new file mode 100644 index 00000000000..e4b017d4192 --- /dev/null +++ b/src/sage/schemes/hyperelliptic_curves/meson.build @@ -0,0 +1,48 @@ +inc_hypellfrob = include_directories('hypellfrob') +py.install_sources( + 'all.py', + 'constructor.py', + 'hyperelliptic_finite_field.py', + 'hyperelliptic_g2.py', + 'hyperelliptic_generic.py', + 'hyperelliptic_padic_field.py', + 'hyperelliptic_rational_field.py', + 'invariants.py', + 'jacobian_endomorphism_utils.py', + 'jacobian_g2.py', + 'jacobian_generic.py', + 'jacobian_homset.py', + 'jacobian_morphism.py', + 'kummer_surface.py', + 'mestre.py', + 'monsky_washnitzer.py', + subdir: 'sage/schemes/hyperelliptic_curves', +) + +extension_data_cpp = { + 'hypellfrob': files( + 'hypellfrob.pyx', + 'hypellfrob/hypellfrob.cpp', + 'hypellfrob/recurrences_ntl.cpp', + ), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/schemes/hyperelliptic_curves', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [ + inc_cpython, + inc_ext, + inc_ntl, + inc_rings, + inc_rings_finite, + inc_hypellfrob, + ], + dependencies: [py_dep, cysignals, gmp, ntl], + ) +endforeach + diff --git a/src/sage/schemes/hyperelliptic_curves/mestre.py b/src/sage/schemes/hyperelliptic_curves/mestre.py old mode 100644 new mode 100755 index be6439d7b3e..c1ea50fbda4 --- a/src/sage/schemes/hyperelliptic_curves/mestre.py +++ b/src/sage/schemes/hyperelliptic_curves/mestre.py @@ -32,32 +32,30 @@ def HyperellipticCurve_from_invariants(i, reduced=True, precision=None, algorithm='default'): r""" - Returns a hyperelliptic curve with the given Igusa-Clebsch invariants up to + Return a hyperelliptic curve with the given Igusa-Clebsch invariants up to scaling. The output is a curve over the field in which the Igusa-Clebsch invariants are given. The output curve is unique up to isomorphism over the algebraic closure. If no such curve exists over the given field, then raise a - ValueError. + :exc:`ValueError`. INPUT: - ``i`` -- list or tuple of length 4 containing the four Igusa-Clebsch - invariants: I2,I4,I6,I10. - - ``reduced`` -- Boolean (default = True) If True, tries to reduce the - polynomial defining the hyperelliptic curve using the function + invariants: I2,I4,I6,I10 + - ``reduced`` -- boolean (default: ``True``); if ``True``, tries to reduce + the polynomial defining the hyperelliptic curve using the function :func:`reduce_polynomial` (see the :func:`reduce_polynomial` documentation for more details). - - ``precision`` -- integer (default = None) Which precision for real and + - ``precision`` -- integer (default: ``None``); which precision for real and complex numbers should the reduction use. This only affects the - reduction, not the correctness. If None, the algorithm uses the default + reduction, not the correctness. If ``None``, the algorithm uses the default 53 bit precision. - ``algorithm`` -- ``'default'`` or ``'magma'``. If set to ``'magma'``, uses - Magma to parameterize Mestre's conic (needs Magma to be installed). + Magma to parameterize Mestre's conic (needs Magma to be installed) - OUTPUT: - - A hyperelliptic curve object. + OUTPUT: a hyperelliptic curve object EXAMPLES: @@ -167,19 +165,16 @@ def HyperellipticCurve_from_invariants(i, reduced=True, precision=None, if algorithm == 'magma': from sage.interfaces.magma import magma - from sage.misc.sage_eval import sage_eval if MConic.has_rational_point(algorithm='magma'): - parametrization = [l.replace('$.1', 't').replace('$.2', 'u') - for l in str(magma(MConic).Parametrization()).splitlines()[4:7]] - [F1, F2, F3] = [sage_eval(p, locals={'t': t, 'u': 1, 'a': k.gen()}) - for p in parametrization] + parametrization = magma(MConic).Parametrization().DefiningPolynomials().sage() + F1, F2, F3 = (p(t, 1) for p in parametrization) else: raise ValueError(f"No such curve exists over {k} as there are no " f"rational points on {MConic}") else: if MConic.has_rational_point(): parametrization = MConic.parametrization(morphism=False)[0] - [F1, F2, F3] = [p(t, 1) for p in parametrization] + F1, F2, F3 = (p(t, 1) for p in parametrization) else: raise ValueError(f"No such curve exists over {k} as there are no " f"rational points on {MConic}") @@ -228,13 +223,11 @@ def Mestre_conic(i, xyz=False, names='u,v,w'): - ``i`` -- list or tuple of length 4 containing the four Igusa-Clebsch invariants: I2, I4, I6, I10 - - ``xyz`` -- Boolean (default: ``False``) if ``True``, the algorithm also + - ``xyz`` -- boolean (default: ``False``); if ``True``, the algorithm also returns three invariants `x`,`y`,`z` used in Mestre's algorithm - - ``names`` (default: ``'u,v,w'``) -- the variable names for the conic - - OUTPUT: + - ``names`` -- (default: ``'u,v,w'``) the variable names for the conic - A Conic object + OUTPUT: a Conic object EXAMPLES: @@ -276,7 +269,6 @@ def Mestre_conic(i, xyz=False, names='u,v,w'): 321 and 332 of [Mes1991]_. See the code or [LY2001]_ for the detailed formulae defining x, y, z and L. - """ from sage.structure.sequence import Sequence k = Sequence(i).universe() diff --git a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py old mode 100644 new mode 100755 index d9a9996d44e..a533b7d4e92 --- a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +++ b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py @@ -45,33 +45,29 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.arith.misc import integer_ceil as ceil from sage.arith.misc import binomial +from sage.arith.misc import integer_ceil as ceil from sage.categories.algebras import Algebras -from sage.functions.log import log +from sage.categories.integral_domains import IntegralDomains from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.misc.misc import newton_method_sizes from sage.misc.profiler import Profiler from sage.misc.repr import repr_lincomb -from sage.modules.free_module_element import vector from sage.modules.free_module import FreeModule -from sage.modules.free_module_element import FreeModuleElement +from sage.modules.free_module_element import FreeModuleElement, vector from sage.modules.module import Module from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers +from sage.rings.infinity import Infinity from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ +from sage.rings.laurent_series_ring import LaurentSeriesRing +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.power_series_ring import PowerSeriesRing -from sage.rings.rational_field import RationalField as Rationals from sage.rings.rational import Rational -from sage.rings.laurent_series_ring import LaurentSeriesRing -from sage.rings.rational_field import QQ -from sage.rings.integer_ring import ZZ -from sage.categories.integral_domains import IntegralDomains -from sage.rings.infinity import Infinity -from sage.rings.laurent_series_ring import is_LaurentSeriesRing -from sage.rings.padics.factory import Qp as pAdicField -from sage.rings.polynomial.polynomial_element import Polynomial +from sage.rings.rational_field import QQ, RationalField as Rationals from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage.schemes.elliptic_curves.ell_generic import EllipticCurve_generic from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve @@ -81,6 +77,10 @@ from sage.structure.richcmp import richcmp from sage.structure.unique_representation import UniqueRepresentation +lazy_import('sage.functions.log', 'log') +lazy_import('sage.rings.lazy_series_ring', 'LazyLaurentSeriesRing') +lazy_import('sage.rings.padics.factory', 'Qp', as_='pAdicField') + class SpecialCubicQuotientRingElement(ModuleElement): """ @@ -98,7 +98,7 @@ def __init__(self, parent, p0, p1, p2, check=True): - ``p0``, ``p1``, ``p2`` -- coefficients; must be coercible into parent.poly_ring() - - ``check`` -- bool (default: ``True``): whether to carry + - ``check`` -- boolean (default: ``True``); whether to carry out coercion EXAMPLES:: @@ -277,8 +277,8 @@ def scalar_multiply(self, scalar): INPUT: - - ``scalar`` -- either an element of base_ring, or an - element of poly_ring. + - ``scalar`` -- either an element of ``base_ring``, or an + element of ``poly_ring`` EXAMPLES:: @@ -606,7 +606,7 @@ def _element_constructor_(self, *args, check=True): - ``p0``, ``p1``, ``p2`` -- coefficients; must be coercible into poly_ring() - - ``check`` -- bool (default: ``True``): whether to carry + - ``check`` -- boolean (default: ``True``); whether to carry out coercion EXAMPLES:: @@ -662,11 +662,9 @@ def transpose_list(input) -> list[list]: """ INPUT: - - ``input`` -- a list of lists, each list of the same length - - OUTPUT: + - ``input`` -- list of lists, each list of the same length - - ``output`` -- a list of lists such that output[i][j] = input[j][i] + OUTPUT: list of lists such that ``output[i][j] = input[j][i]`` EXAMPLES:: @@ -1024,7 +1022,7 @@ def reduce_all(Q, p, coeffs, offset, compute_exact_form=False): OUTPUT: - ``A``, ``B`` -- pair such that the input differential is - cohomologous to (A + Bx) dx/y. + cohomologous to (A + Bx) dx/y .. NOTE:: @@ -1102,9 +1100,9 @@ def frobenius_expansion_by_newton(Q, p, M): `Q(x) = x^3 + ax + b`, whose coefficient ring is a `Z/(p^M)Z`-algebra - - ``p`` -- residue characteristic of the p-adic field + - ``p`` -- residue characteristic of the `p`-adic field - - ``M`` -- p-adic precision of the coefficient ring + - ``M`` -- `p`-adic precision of the coefficient ring (this will be used to determine the number of Newton iterations) OUTPUT: @@ -1112,7 +1110,7 @@ def frobenius_expansion_by_newton(Q, p, M): - ``F0``, ``F1`` -- elements of ``SpecialCubicQuotientRing(Q)``, as described above - - ``r`` -- non-negative integer, as described above + - ``r`` -- nonnegative integer, as described above EXAMPLES:: @@ -1300,7 +1298,7 @@ def frobenius_expansion_by_series(Q, p, M): - ``F0``, ``F1`` -- elements of ``SpecialCubicQuotientRing(Q)``, as described above - - ``r`` -- non-negative integer, as described above + - ``r`` -- nonnegative integer, as described above EXAMPLES:: @@ -1378,7 +1376,7 @@ def adjusted_prec(p, prec): - ``p`` -- a prime ``p >= 5`` - - ``prec`` -- integer, desired output precision, ``prec >= 1`` + - ``prec`` -- integer; desired output precision, ``prec >= 1`` OUTPUT: adjusted precision (usually slightly more than ``prec``) @@ -1806,7 +1804,6 @@ def matrix_of_frobenius_hyperelliptic(Q, p=None, prec=None, M=None): [ 3*5 + 5^2 + O(5^3) 3*5 + O(5^3) 4*5 + O(5^3) 2 + 5^2 + O(5^3)] [ 4*5 + 4*5^2 + O(5^3) 3*5 + 2*5^2 + O(5^3) 5 + 3*5^2 + O(5^3) 2*5 + 2*5^2 + O(5^3)] [ 5^2 + O(5^3) 5 + 4*5^2 + O(5^3) 4*5 + 3*5^2 + O(5^3) 2*5 + O(5^3)] - """ prof = Profiler() prof("setup") @@ -1935,7 +1932,7 @@ def change_ring(self, R): def __call__(self, *x): """ - Evaluate ``self`` at given arguments + Evaluate ``self`` at given arguments. EXAMPLES:: @@ -1983,7 +1980,7 @@ def __invert__(self): def __bool__(self): """ - Return True iff ``self`` is not zero. + Return ``True`` iff ``self`` is not zero. EXAMPLES:: @@ -2280,7 +2277,7 @@ def coeffs(self, R=None): OUTPUT: - - ``coeffs`` -- a list of coefficients of powers of `x` for each power + - ``coeffs`` -- list of coefficients of powers of `x` for each power of `y` - ``n`` -- an offset indicating the power of `y` of the first list @@ -2412,7 +2409,7 @@ def __init__(self, Q, R=None, invert_y=True): if not hasattr(self, '_curve'): if self._Q.degree() == 3: ainvs = [0, self._Q[2], 0, self._Q[1], self._Q[0]] - self._curve = EllipticCurve(ainvs, check_squarefree=R.is_field()) + self._curve = EllipticCurve(ainvs) else: self._curve = HyperellipticCurve(self._Q, check_squarefree=R.is_field()) @@ -2451,7 +2448,7 @@ def _repr_(self) -> str: sage: x.parent() # indirect doctest SpecialHyperellipticQuotientRing K[x,y,y^-1] / (y^2 = x^5 - 3*x + 1) over Rational Field """ - y_inverse = ",y^-1" if is_LaurentSeriesRing(self._series_ring) else "" + y_inverse = ",y^-1" if isinstance(self._series_ring, (LaurentSeriesRing, LazyLaurentSeriesRing)) else "" return "SpecialHyperellipticQuotientRing K[x,y%s] / (y^2 = %s) over %s" % (y_inverse, self._Q, self.base_ring()) def base_extend(self, R): @@ -2489,7 +2486,7 @@ def change_ring(self, R): over Integer Ring """ return SpecialHyperellipticQuotientRing(self._Q.change_ring(R), R, - is_LaurentSeriesRing(self._series_ring)) + isinstance(self._series_ring, (LaurentSeriesRing, LazyLaurentSeriesRing))) def _element_constructor_(self, val, offset=0, check=True): r""" @@ -2544,7 +2541,7 @@ def zero(self): def gens(self): """ - Return the generators of ``self`` + Return the generators of ``self``. EXAMPLES:: @@ -2558,7 +2555,7 @@ def gens(self): def x(self): r""" - Return the generator `x` of ``self`` + Return the generator `x` of ``self``. EXAMPLES:: @@ -2572,7 +2569,7 @@ def x(self): def y(self): r""" - Return the generator `y` of ``self`` + Return the generator `y` of ``self``. EXAMPLES:: @@ -2830,7 +2827,7 @@ def __init__(self, parent, val, offset=0): - ``val`` -- element of the base ring, or list of coefficients - - ``offset`` -- (default: 0) if non-zero, shift val by `y^\text{offset}` + - ``offset`` -- (default: 0) if nonzero, shift val by `y^\text{offset}` EXAMPLES:: @@ -3156,7 +3153,7 @@ def reduce_neg_y_fast(self, even_degree_only=False): sage: (y^-5*x^2+y^-1*x).diff().reduce_neg_y_fast() ((y^-1)*x + (y^-5)*x^2, 0 dx/2y) - It leaves non-negative powers of `y` alone:: + It leaves nonnegative powers of `y` alone:: sage: y.diff() (-3*1 + 5*x^4) dx/2y @@ -3446,11 +3443,9 @@ def coeffs(self, R=None): INPUT: - - R -- An (optional) base ring in which to cast the coefficients + - ``R`` -- an (optional) base ring in which to cast the coefficients - OUTPUT: - - The raw coefficients of `A` where ``self`` is `A dx/2y`. + OUTPUT: the raw coefficients of `A` where ``self`` is `A dx/2y` EXAMPLES:: @@ -3477,9 +3472,7 @@ def coleman_integral(self, P, Q): - `P`, `Q` -- two points on the underlying curve - OUTPUT: - - `\int_P^Q \text{self}` + OUTPUT: `\int_P^Q \text{self}` EXAMPLES:: @@ -3487,7 +3480,7 @@ def coleman_integral(self, P, Q): sage: E = EllipticCurve(K,[-31/3,-2501/108]) #11a sage: P = E(K(14/3), K(11/2)) sage: w = E.invariant_differential() - sage: w.coleman_integral(P,2*P) + sage: w.coleman_integral(P, 2*P) O(5^6) sage: Q = E([3,58332]) @@ -3570,16 +3563,14 @@ def base_extend(self, R): def change_ring(self, R): """ - Return a new differential ring which is self with the coefficient + Return a new differential ring which is ``self`` with the coefficient ring changed to `R`. INPUT: - ``R`` -- ring of coefficients - OUTPUT: - - ``self`` with the coefficient ring changed to `R`. + OUTPUT: ``self`` with the coefficient ring changed to `R` EXAMPLES:: @@ -3633,7 +3624,7 @@ def dimension(self): def Q(self): """ Return `Q(x)` where the model of the underlying hyperelliptic curve - of self is given by `y^2 = Q(x)`. + of ``self`` is given by `y^2 = Q(x)`. EXAMPLES:: @@ -3856,7 +3847,7 @@ def _element_constructor_(self, val=0, offset=0): - ``parent`` -- Monsky-Washnitzer differential ring (instance of class :class:`~MonskyWashnitzerDifferentialRing` - ``val`` -- element of the base ring, or list of coefficients - - ``offset`` -- (default: 0) if non-zero, shift val by `y^\text{offset}` + - ``offset`` -- (default: 0) if nonzero, shift val by `y^\text{offset}` EXAMPLES:: diff --git a/src/sage/schemes/jacobians/abstract_jacobian.py b/src/sage/schemes/jacobians/abstract_jacobian.py old mode 100644 new mode 100755 index f5c69ea99c1..6ec2880a627 --- a/src/sage/schemes/jacobians/abstract_jacobian.py +++ b/src/sage/schemes/jacobians/abstract_jacobian.py @@ -28,7 +28,7 @@ def is_Jacobian(J): """ - Return True if `J` is of type Jacobian_generic. + Return ``True`` if `J` is of type ``Jacobian_generic``. EXAMPLES:: @@ -188,7 +188,7 @@ def _point(self): OUTPUT: - This method always raises a :class:`NotImplementedError`; it is + This method always raises a :exc:`NotImplementedError`; it is only abstract. EXAMPLES:: @@ -225,9 +225,9 @@ def change_ring(self, R): INPUT: - - ``R`` -- a field. The new base ring. + - ``R`` -- a field; the new base ring - OUTPUT: The Jacobian over the ring `R`. + OUTPUT: the Jacobian over the ring `R` EXAMPLES:: @@ -248,9 +248,9 @@ def base_extend(self, R): INPUT: - - ``R`` -- a field. The new base field. + - ``R`` -- a field; the new base field - OUTPUT: The Jacobian over the ring `R`. + OUTPUT: the Jacobian over the ring `R` EXAMPLES:: diff --git a/src/sage/schemes/meson.build b/src/sage/schemes/meson.build new file mode 100644 index 00000000000..c74c532b930 --- /dev/null +++ b/src/sage/schemes/meson.build @@ -0,0 +1,16 @@ +py.install_sources('all.py', 'overview.py', subdir: 'sage/schemes') + +install_subdir('affine', install_dir: sage_install_dir / 'schemes') +install_subdir('berkovich', install_dir: sage_install_dir / 'schemes') +install_subdir('curves', install_dir: sage_install_dir / 'schemes') +install_subdir('cyclic_covers', install_dir: sage_install_dir / 'schemes') +subdir('elliptic_curves') +install_subdir('generic', install_dir: sage_install_dir / 'schemes') +subdir('hyperelliptic_curves') +install_subdir('jacobians', install_dir: sage_install_dir / 'schemes') +install_subdir('plane_conics', install_dir: sage_install_dir / 'schemes') +install_subdir('plane_quartics', install_dir: sage_install_dir / 'schemes') +install_subdir('product_projective', install_dir: sage_install_dir / 'schemes') +install_subdir('projective', install_dir: sage_install_dir / 'schemes') +install_subdir('riemann_surfaces', install_dir: sage_install_dir / 'schemes') +subdir('toric') diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py old mode 100644 new mode 100755 index 723bc46e916..8ad15fdf5b4 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -153,7 +153,7 @@ def cache_point(self, p): def coefficients(self): r""" - Gives a the `6` coefficients of the conic ``self`` + Give a the `6` coefficients of the conic ``self`` in lexicographic order. EXAMPLES:: @@ -172,7 +172,7 @@ def coefficients(self): def derivative_matrix(self): r""" - Gives the derivative of the defining polynomial of + Give the derivative of the defining polynomial of the conic ``self``, which is a linear map, as a `3 \times 3` matrix. @@ -399,33 +399,32 @@ def gens(self): sage: C. = Conic(GF(3), [1, 1, 1]); C # needs sage.libs.singular Projective Conic Curve over Finite Field of size 3 defined by a^2 + b^2 + c^2 - """ return self.coordinate_ring().gens() def has_rational_point(self, point=False, algorithm='default', read_cache=True): r""" - Return True if and only if the conic ``self`` + Return ``True`` if and only if the conic ``self`` has a point over its base field `B`. - If ``point`` is True, then returns a second output, which is + If ``point`` is ``True``, then returns a second output, which is a rational point if one exists. Points are cached whenever they are found. Cached information - is used if and only if ``read_cache`` is True. + is used if and only if ``read_cache`` is ``True``. ALGORITHM: The parameter ``algorithm`` specifies the algorithm to be used: - - ``'default'`` -- If the base field is real or complex, - use an elementary native Sage implementation. + - ``'default'`` -- if the base field is real or complex, + use an elementary native Sage implementation - ``'magma'`` (requires Magma to be installed) -- delegates the task to the Magma computer algebra - system. + system EXAMPLES:: @@ -567,10 +566,10 @@ def has_rational_point(self, point=False, def has_singular_point(self, point=False): r""" - Return True if and only if the conic ``self`` has a rational + Return ``True`` if and only if the conic ``self`` has a rational singular point. - If ``point`` is True, then also return a rational singular + If ``point`` is ``True``, then also return a rational singular point (or ``None`` if no such point exists). EXAMPLES: @@ -668,7 +667,7 @@ def hom(self, x, Y=None): To: Projective Conic Curve over Rational Field defined by 4*x^2 + y^2 - z^2 Defn: Defined on coordinates by sending (x : y : z) to (1/2*z : y : x) - :class:`ValueError` is raised if the wrong codomain ``Y`` is specified: + :exc:`ValueError` is raised if the wrong codomain ``Y`` is specified: :: @@ -712,7 +711,6 @@ def hom(self, x, Y=None): Polynomial Ring in t over Rational Field defined by 1/(t^2)*x^2 + t*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2 Defn: Defined on coordinates by sending (x : y : z) to (t*x + z : y : z) - """ if isinstance(x, Matrix): from .constructor import Conic @@ -731,7 +729,7 @@ def hom(self, x, Y=None): def is_diagonal(self): r""" - Return True if and only if the conic has the form + Return ``True`` if and only if the conic has the form `a x^2 + b y^2 + c z^2`. EXAMPLES: @@ -750,7 +748,7 @@ def is_diagonal(self): def is_smooth(self): r""" - Return True if and only if ``self`` is smooth. + Return ``True`` if and only if ``self`` is smooth. EXAMPLES: @@ -917,7 +915,7 @@ def parametrization(self, point=None, morphism=True): sage: i[0](p) / i[1](p) x/y - A :class:`ValueError` is raised if ``self`` has no rational point :: + A :exc:`ValueError` is raised if ``self`` has no rational point :: sage: # needs sage.libs.pari sage: C = Conic(x^2 + y^2 + 7*z^2) @@ -927,7 +925,7 @@ def parametrization(self, point=None, morphism=True): ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field! - A :class:`ValueError` is raised if ``self`` is not smooth :: + A :exc:`ValueError` is raised if ``self`` is not smooth :: sage: # needs sage.libs.pari sage: C = Conic(x^2 + y^2) @@ -972,7 +970,7 @@ def parametrization(self, point=None, morphism=True): def point(self, v, check=True): r""" - Constructs a point on ``self`` corresponding to the input ``v``. + Construct a point on ``self`` corresponding to the input ``v``. If ``check`` is True, then checks if ``v`` defines a valid point on ``self``. @@ -1031,7 +1029,6 @@ def random_rational_point(self, *args1, **args2): ... ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2 has no rational points over Rational Field! - """ if not self.is_smooth(): raise NotImplementedError("Sorry, random points not implemented " @@ -1049,7 +1046,7 @@ def rational_point(self, algorithm='default', read_cache=True): r""" Return a point on ``self`` defined over the base field. - This raises a :class:`ValueError` if no rational point exists. + This raises a :exc:`ValueError` if no rational point exists. See ``self.has_rational_point`` for the algorithm used and for the use of the parameters ``algorithm`` and ``read_cache``. @@ -1201,7 +1198,7 @@ def singular_point(self): sage: Conic(GF(2), [1,1,1,1,1,1]).singular_point() (1 : 1 : 1) - :class:`ValueError` is raised if the conic has no rational + :exc:`ValueError` is raised if the conic has no rational singular point :: @@ -1294,6 +1291,5 @@ def variable_names(self): sage: C. = Conic(QQ, [1, 1, 1]); C # needs sage.libs.singular Projective Conic Curve over Rational Field defined by p^2 + q^2 + r^2 - """ return self.defining_polynomial().parent().variable_names() diff --git a/src/sage/schemes/plane_conics/con_finite_field.py b/src/sage/schemes/plane_conics/con_finite_field.py old mode 100644 new mode 100755 index 296cd056d87..3562b2e2765 --- a/src/sage/schemes/plane_conics/con_finite_field.py +++ b/src/sage/schemes/plane_conics/con_finite_field.py @@ -60,7 +60,7 @@ def __init__(self, A, f): def count_points(self, n): r""" - If the base field `B` of `self` is finite of order `q`, + If the base field `B` of ``self`` is finite of order `q`, then returns the number of points over `\GF{q}, ..., \GF{q^n}`. EXAMPLES:: @@ -78,7 +78,7 @@ def count_points(self, n): def has_rational_point(self, point=False, read_cache=True, algorithm='default'): r""" - Always returns ``True`` because self has a point defined over + Always returns ``True`` because ``self`` has a point defined over its finite base field `B`. If ``point`` is True, then returns a second output `S`, which is a diff --git a/src/sage/schemes/plane_conics/con_number_field.py b/src/sage/schemes/plane_conics/con_number_field.py old mode 100644 new mode 100755 index 393b77bc1ff..e09a1f60262 --- a/src/sage/schemes/plane_conics/con_number_field.py +++ b/src/sage/schemes/plane_conics/con_number_field.py @@ -72,40 +72,39 @@ def has_rational_point(self, point=False, obstruction=False, then the output is a boolean ``out`` saying whether ``self`` has a rational point. - If ``point`` or ``obstruction`` is True, then the output is + If ``point`` or ``obstruction`` is ``True``, then the output is a pair ``(out, S)``, where ``out`` is as above and: - - if ``point`` is True and ``self`` has a rational point, + - if ``point`` is ``True`` and ``self`` has a rational point, then ``S`` is a rational point, - - if ``obstruction`` is True, ``self`` has no rational point, + - if ``obstruction`` is ``True``, ``self`` has no rational point, then ``S`` is a prime or infinite place of `B` such that no rational point exists over the completion at ``S``. Points and obstructions are cached whenever they are found. Cached information is used for the output if available, but only - if ``read_cache`` is True. + if ``read_cache`` is ``True``. ALGORITHM: The parameter ``algorithm`` specifies the algorithm to be used: - - ``'rnfisnorm'`` -- Use PARI's ``rnfisnorm`` + - ``'rnfisnorm'`` -- use PARI's ``rnfisnorm`` (cannot be combined with ``obstruction = True``) - - ``'local'`` -- Check if a local solution exists for all primes - and infinite places of `B` and apply the Hasse principle. - (Cannot be combined with ``point = True``.) + - ``'local'`` -- check if a local solution exists for all primes + and infinite places of `B` and apply the Hasse principle + (cannot be combined with ``point = True``) - - ``'default'`` -- Use algorithm ``'rnfisnorm'`` first. + - ``'default'`` -- use algorithm ``'rnfisnorm'`` first. Then, if no point exists and obstructions are requested, use algorithm ``'local'`` to find an obstruction. - ``'magma'`` (requires Magma to be installed) -- delegates the task to the Magma computer algebra - system. - + system EXAMPLES: @@ -123,9 +122,9 @@ def has_rational_point(self, point=False, obstruction=False, sage: C = Conic(K, [1, 3, -5]) sage: C.has_rational_point(point=True, obstruction=True) (False, Fractional ideal (-i - 2)) - sage: C.has_rational_point(algorithm="rnfisnorm") + sage: C.has_rational_point(algorithm='rnfisnorm') False - sage: C.has_rational_point(algorithm="rnfisnorm", obstruction=True, + sage: C.has_rational_point(algorithm='rnfisnorm', obstruction=True, ....: read_cache=False) Traceback (most recent call last): ... @@ -223,7 +222,7 @@ def has_rational_point(self, point=False, obstruction=False, return False, self._local_obstruction else: return False - # `_(in)finite_obstructions` is `None` if the cache is empty, + # `_(in)finite_obstructions` is ``None`` if the cache is empty, # so we explicitly check against a list: if (not point) and self._finite_obstructions == [] and \ self._infinite_obstructions == []: @@ -391,7 +390,7 @@ def local_obstructions(self, finite=True, infinite=True, read_cache=True): If the base field is `\QQ`, then the infinite place is denoted `-1`. - The parameters ``finite`` and ``infinite`` (both True by default) are + The parameters ``finite`` and ``infinite`` (both ``True`` by default) are used to specify whether to look at finite and/or infinite places. Note that ``finite = True`` involves factorization of the determinant of ``self``, hence may be slow. diff --git a/src/sage/schemes/plane_conics/con_rational_field.py b/src/sage/schemes/plane_conics/con_rational_field.py old mode 100644 new mode 100755 index 7be5d2ad242..329193bb5b5 --- a/src/sage/schemes/plane_conics/con_rational_field.py +++ b/src/sage/schemes/plane_conics/con_rational_field.py @@ -23,25 +23,23 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ - import sage.rings.abc -from sage.structure.sequence import Sequence -from sage.schemes.projective.projective_space import ProjectiveSpace +from sage.arith.functions import lcm +from sage.arith.misc import hilbert_symbol from sage.matrix.constructor import Matrix +from sage.misc.lazy_import import lazy_import +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.rational_field import QQ +from sage.schemes.projective.projective_space import ProjectiveSpace +from sage.structure.element import InfinityElement +from sage.structure.sequence import Sequence -from sage.quadratic_forms.qfsolve import qfsolve, qfparam +lazy_import('sage.quadratic_forms.qfsolve', ['qfsolve', 'qfparam']) from .con_number_field import ProjectiveConic_number_field -from sage.structure.element import InfinityElement - -from sage.arith.functions import lcm -from sage.arith.misc import hilbert_symbol - class ProjectiveConic_rational_field(ProjectiveConic_number_field): r""" @@ -98,16 +96,16 @@ def has_rational_point(self, point=False, obstruction=False, The parameter ``algorithm`` specifies the algorithm to be used: - - ``'qfsolve'`` -- Use PARI/GP function :pari:`qfsolve` + - ``'qfsolve'`` -- use PARI/GP function :pari:`qfsolve` - - ``'rnfisnorm'`` -- Use PARI's function :pari:`rnfisnorm` + - ``'rnfisnorm'`` -- use PARI's function :pari:`rnfisnorm` (cannot be combined with ``obstruction = True``) - - ``'local'`` -- Check if a local solution exists for all primes + - ``'local'`` -- check if a local solution exists for all primes and infinite places of `\QQ` and apply the Hasse principle (cannot be combined with ``point = True``) - - ``'default'`` -- Use ``'qfsolve'`` + - ``'default'`` -- use ``'qfsolve'`` - ``'magma'`` (requires Magma to be installed) -- delegates the task to the Magma computer algebra system. @@ -359,7 +357,7 @@ def parametrization(self, point=None, morphism=True): sage: i[0](p) / i[1](p) x/y - A :class:`ValueError` is raised if ``self`` has no rational point :: + A :exc:`ValueError` is raised if ``self`` has no rational point :: sage: # needs sage.libs.pari sage: C = Conic(x^2 + 2*y^2 + z^2) @@ -369,7 +367,7 @@ def parametrization(self, point=None, morphism=True): ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field! - A :class:`ValueError` is raised if ``self`` is not smooth :: + A :exc:`ValueError` is raised if ``self`` is not smooth :: sage: # needs sage.libs.pari sage: C = Conic(x^2 + y^2) diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py old mode 100644 new mode 100755 index bc842415d8e..26522878918 --- a/src/sage/schemes/plane_conics/con_rational_function_field.py +++ b/src/sage/schemes/plane_conics/con_rational_function_field.py @@ -88,7 +88,7 @@ def __init__(self, A, f): def has_rational_point(self, point=False, algorithm='default', read_cache=True): r""" - Returns True if and only if the conic ``self`` + Return ``True`` if and only if the conic ``self`` has a point over its base field `F(t)`, which is a field of rational functions. @@ -226,7 +226,6 @@ def has_rational_point(self, point=False, algorithm='default', ....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5]) sage: C.has_rational_point() True - """ from .constructor import Conic @@ -338,14 +337,14 @@ def _reduce_conic(self): `K=F(t)` and coefficients `a,b,c` such that `a,b,c \in F[t]`, `\gcd(a,b)=\gcd(b,c)=\gcd(c,a)=1` and `abc` is square-free. - Assumes `self` is in diagonal form. + Assumes ``self`` is in diagonal form. OUTPUT: A tuple (coefficients, multipliers), the coefficients of the conic in reduced form and multipliers `\lambda, \mu, \nu \in F(t)^*` such that `(x,y,z) \in F(t)` is a solution of the reduced conic if and only - if `(\lambda x, \mu y, \nu z)` is a solution of `self`. + if `(\lambda x, \mu y, \nu z)` is a solution of ``self``. ALGORITHM: @@ -429,14 +428,14 @@ def find_point(self, supports, roots, case, solution=0): INPUT: - - ``self`` -- conic in reduced form. + - ``self`` -- conic in reduced form - ``supports`` -- 3-tuple where ``supports[i]`` is a list of all monic - irreducible `p \in F[t]` that divide the `i`'th of the 3 coefficients. + irreducible `p \in F[t]` that divide the `i`-th of the 3 coefficients - ``roots`` -- 3-tuple containing lists of roots of all elements of - ``supports[i]``, in the same order. - - ``case`` -- 1 or 0, as in [HC2006]_. + ``supports[i]``, in the same order + - ``case`` -- 1 or 0, as in [HC2006]_ - ``solution`` -- (default: 0) a solution of (5) in [HC2006]_, if - case = 0, 0 otherwise. + ``case`` = 0, 0 otherwise OUTPUT: @@ -504,12 +503,12 @@ def find_point(self, supports, roots, case, solution=0): lastpoly = F(1) for n in range(B): lastpoly = (lastpoly * t) % p - phi_p[A + 2 + n] = vector(F, d, lastpoly.dict()) + phi_p[A + 2 + n] = vector(F, d, lastpoly.monomial_coefficients()) lastpoly = -alpha % p - phi_p[A + B + 2] = vector(F, d, lastpoly.dict()) + phi_p[A + B + 2] = vector(F, d, lastpoly.monomial_coefficients()) for n in range(C): lastpoly = (lastpoly * t) % p - phi_p[A + B + 3 + n] = vector(F, d, lastpoly.dict()) + phi_p[A + B + 3 + n] = vector(F, d, lastpoly.monomial_coefficients()) phi_p[A + B + C + 3] = vector(F, d) phi.append(matrix(phi_p).transpose()) for (i, p) in enumerate(supports[1]): @@ -526,12 +525,12 @@ def find_point(self, supports, roots, case, solution=0): lastpoly = F(1) for n in range(C): lastpoly = (lastpoly * t) % p - phi_p[A + B + 3 + n] = vector(F, d, lastpoly.dict()) + phi_p[A + B + 3 + n] = vector(F, d, lastpoly.monomial_coefficients()) lastpoly = -alpha % p - phi_p[0] = vector(F, d, lastpoly.dict()) + phi_p[0] = vector(F, d, lastpoly.monomial_coefficients()) for n in range(A): lastpoly = (lastpoly * t) % p - phi_p[1 + n] = vector(F, d, lastpoly.dict()) + phi_p[1 + n] = vector(F, d, lastpoly.monomial_coefficients()) phi_p[A + B + C + 3] = vector(F, d) phi.append(matrix(phi_p).transpose()) for (i, p) in enumerate(supports[2]): @@ -548,12 +547,12 @@ def find_point(self, supports, roots, case, solution=0): lastpoly = F(1) for n in range(A): lastpoly = (lastpoly * t) % p - phi_p[1 + n] = vector(F, d, lastpoly.dict()) + phi_p[1 + n] = vector(F, d, lastpoly.monomial_coefficients()) lastpoly = -alpha % p - phi_p[A + 1] = vector(F, d, lastpoly.dict()) + phi_p[A + 1] = vector(F, d, lastpoly.monomial_coefficients()) for n in range(B): lastpoly = (lastpoly * t) % p - phi_p[A + 2 + n] = vector(F, d, lastpoly.dict()) + phi_p[A + 2 + n] = vector(F, d, lastpoly.monomial_coefficients()) phi_p[A + B + C + 3] = vector(F, d) phi.append(matrix(phi_p).transpose()) if case == 0: diff --git a/src/sage/schemes/plane_conics/constructor.py b/src/sage/schemes/plane_conics/constructor.py old mode 100644 new mode 100755 index 308b56f6db0..38652c9c555 --- a/src/sage/schemes/plane_conics/constructor.py +++ b/src/sage/schemes/plane_conics/constructor.py @@ -32,8 +32,8 @@ from sage.rings.number_field.number_field_base import NumberField from sage.rings.polynomial.multi_polynomial import MPolynomial -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.schemes.affine.affine_point import SchemeMorphism_point_affine from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field @@ -59,9 +59,9 @@ def Conic(base_field, F=None, names=None, unique=True): INPUT: - - ``base_field`` -- The base field of the conic. + - ``base_field`` -- the base field of the conic - - ``names`` -- a list, tuple, or comma separated string + - ``names`` -- list, tuple, or comma separated string of three variable names specifying the names of the coordinate functions of the ambient space `\Bold{P}^3`. If not specified or read @@ -89,13 +89,11 @@ def Conic(base_field, F=None, names=None, unique=True): If ``F`` is a list of 5 points in the plane, then the output is a conic through those points. - - ``unique`` -- Used only if ``F`` is a list of points in the plane. - If the conic through the points is not unique, then - raise :class:`ValueError` if and only if ``unique`` is ``True`` + - ``unique`` -- used only if ``F`` is a list of points in the plane; + if the conic through the points is not unique, then + raise :exc:`ValueError` if and only if ``unique`` is ``True`` - OUTPUT: - - A plane projective conic curve defined by ``F`` over a field. + OUTPUT: a plane projective conic curve defined by ``F`` over a field EXAMPLES: @@ -242,7 +240,7 @@ def Conic(base_field, F=None, names=None, unique=True): return ProjectiveConic_rational_field(P2, F) if isinstance(base_field, NumberField): return ProjectiveConic_number_field(P2, F) - if isinstance(base_field, FractionField_generic) and (is_PolynomialRing(base_field.ring()) or is_MPolynomialRing(base_field.ring())): + if isinstance(base_field, FractionField_generic) and (isinstance(base_field.ring(), PolynomialRing_general) or isinstance(base_field.ring(), MPolynomialRing_base)): return ProjectiveConic_rational_function_field(P2, F) return ProjectiveConic_field(P2, F) diff --git a/src/sage/schemes/plane_quartics/quartic_constructor.py b/src/sage/schemes/plane_quartics/quartic_constructor.py old mode 100644 new mode 100755 index df2fdfa60bb..29d49c2d2c4 --- a/src/sage/schemes/plane_quartics/quartic_constructor.py +++ b/src/sage/schemes/plane_quartics/quartic_constructor.py @@ -13,6 +13,7 @@ from .quartic_generic import QuarticCurve_generic + def QuarticCurve(F, PP=None, check=False): """ Return the quartic curve defined by the polynomial ``F``. @@ -21,7 +22,7 @@ def QuarticCurve(F, PP=None, check=False): - ``F`` -- a polynomial in three variables, homogeneous of degree 4 - - ``PP`` -- a projective plane (default: None) + - ``PP`` -- a projective plane (default: ``None``) - ``check`` -- whether to check for smoothness or not (default: ``False``) @@ -48,7 +49,6 @@ def QuarticCurve(F, PP=None, check=False): Traceback (most recent call last): ... ValueError: Argument F (=x^4 + y^4) must be a polynomial in 3 variables - """ if not isinstance(F, MPolynomial): raise ValueError(f"Argument F (={F}) must be a multivariate polynomial") diff --git a/src/sage/schemes/plane_quartics/quartic_generic.py b/src/sage/schemes/plane_quartics/quartic_generic.py old mode 100644 new mode 100755 index 324ec2f9b13..e41eb64d316 --- a/src/sage/schemes/plane_quartics/quartic_generic.py +++ b/src/sage/schemes/plane_quartics/quartic_generic.py @@ -15,12 +15,13 @@ #***************************************************************************** # Copyright (C) 2006 David Kohel # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** import sage.schemes.curves.projective_curve as projective_curve + def is_QuarticCurve(C): """ Check whether ``C`` is a Quartic Curve. @@ -35,7 +36,6 @@ def is_QuarticCurve(C): DeprecationWarning: The function is_QuarticCurve is deprecated; use 'isinstance(..., QuarticCurve_generic)' instead. See https://github.com/sagemath/sage/issues/38022 for details. True - """ from sage.misc.superseded import deprecation deprecation(38022, "The function is_QuarticCurve is deprecated; use 'isinstance(..., QuarticCurve_generic)' instead.") diff --git a/src/sage/schemes/product_projective/homset.py b/src/sage/schemes/product_projective/homset.py old mode 100644 new mode 100755 index ef135a2cd6b..658417398b9 --- a/src/sage/schemes/product_projective/homset.py +++ b/src/sage/schemes/product_projective/homset.py @@ -27,6 +27,7 @@ from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme from sage.schemes.generic.homset import SchemeHomset_points + class SchemeHomset_points_product_projective_spaces_ring(SchemeHomset_points): r""" Set of rational points of a product of projective spaces. @@ -47,11 +48,9 @@ def _element_constructor_(self, v, **kwds): INPUT: - - ``v`` -- anything that determines a scheme morphism in the Hom-set. - - OUTPUT: + - ``v`` -- anything that determines a scheme morphism in the Hom-set - The scheme morphism determined by ``v``. + OUTPUT: the scheme morphism determined by ``v`` EXAMPLES:: @@ -65,6 +64,7 @@ def _element_constructor_(self, v, **kwds): """ return self.codomain()._point(self, v, **kwds) + class SchemeHomset_points_product_projective_spaces_field(SchemeHomset_points_product_projective_spaces_ring): def points(self, **kwds): r""" @@ -91,14 +91,17 @@ def points(self, **kwds): - ``bound`` -- a real number - - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm algorithm 4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm 4 - - ``precision`` -- the precision to use for computing the elements of bounded height of number fields. + - ``precision`` -- the precision to use for computing the elements of + bounded height of number fields - - ``algorithm`` -- either ``'sieve'`` or ``'enumerate'`` algorithms can be used over `\QQ`. If - not specified, ``'enumerate'`` is used only for small height bounds. + - ``algorithm`` -- either ``'sieve'`` or ``'enumerate'`` algorithms can + be used over `\QQ`. If not specified, ``'enumerate'`` is used only + for small height bounds - OUTPUT: A list of rational points of the projective scheme. + OUTPUT: list of rational points of the projective scheme EXAMPLES:: diff --git a/src/sage/schemes/product_projective/morphism.py b/src/sage/schemes/product_projective/morphism.py old mode 100644 new mode 100755 index 7fc09c0860d..e2ebb4e1834 --- a/src/sage/schemes/product_projective/morphism.py +++ b/src/sage/schemes/product_projective/morphism.py @@ -52,12 +52,12 @@ def __init__(self, parent, polys, check=True): INPUT: - - ``parent`` -- Hom-set. + - ``parent`` -- Hom-set - - ``polys`` -- anything that defines a point in the class. + - ``polys`` -- anything that defines a point in the class - - ``check`` -- Boolean. Whether or not to perform input checks. - (Default: ``True``) + - ``check`` -- boolean; whether or not to perform input checks + (default: ``True``) EXAMPLES:: @@ -131,7 +131,7 @@ def __getitem__(self, i): INPUT: - - ``i`` -- integer. + - ``i`` -- integer OUTPUT: @@ -151,7 +151,7 @@ def _repr_defn(self): r""" Return a string representation of this morphism. - OUTPUT: String. + OUTPUT: string EXAMPLES:: @@ -174,12 +174,12 @@ def __call__(self, P, check=True): INPUT: - - ``P`` -- a point in the domain. + - ``P`` -- a point in the domain - - ``check`` -- Boolean; whether or not to perform the input checks - on the image point (Default: ``True``). + - ``check`` -- boolean (default: ``True``); whether or not to perform + the input checks on the image point - OUTPUT: The image point in the codomain. + OUTPUT: the image point in the codomain EXAMPLES:: @@ -239,16 +239,16 @@ def __call__(self, P, check=True): def __eq__(self, right): """ - Tests the equality of two product projective morphisms. + Test the equality of two product projective morphisms. INPUT: - - ``right`` -- a map on product of projective space. + - ``right`` -- a map on product of projective space OUTPUT: - - Boolean -- True if ``self`` and ``right`` define the same product projective - map. False otherwise. + boolean; ``True`` if ``self`` and ``right`` define the same product + projective map. ``False`` otherwise. EXAMPLES:: @@ -304,16 +304,16 @@ def __eq__(self, right): def __ne__(self, right): """ - Tests the inequality of two prduct projective morphisms. + Test the inequality of two prduct projective morphisms. INPUT: - - ``right`` -- a map on product of projective space. + - ``right`` -- a map on product of projective space OUTPUT: - - Boolean -- True if ``self`` and ``right`` define different product - projective maps. False otherwise. + boolean; ``True`` if ``self`` and ``right`` define different product + projective maps. ``False`` otherwise. EXAMPLES:: @@ -356,7 +356,7 @@ def is_morphism(self): the domain of this map generated by the corresponding coordinates of the map. This map is a morphism if and only if each of these subschemes has no points. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -406,9 +406,7 @@ def as_dynamical_system(self): """ Return this endomorphism as a :class:`~sage.dynamics.arithmetic_dynamics.product_projective_ds.DynamicalSystem_product_projective`. - OUTPUT: - - - :class:`~sage.dynamics.arithmetic_dynamics.product_projective_ds.DynamicalSystem_product_projective` + OUTPUT: :class:`~sage.dynamics.arithmetic_dynamics.product_projective_ds.DynamicalSystem_product_projective` EXAMPLES:: @@ -431,11 +429,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default RealField precision) - - a real number. + OUTPUT: a real number .. TODO:: @@ -482,12 +478,12 @@ def local_height(self, v, prec=None): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: diff --git a/src/sage/schemes/product_projective/point.py b/src/sage/schemes/product_projective/point.py old mode 100644 new mode 100755 index 5e1167b7b58..7cbe0065de5 --- a/src/sage/schemes/product_projective/point.py +++ b/src/sage/schemes/product_projective/point.py @@ -52,12 +52,12 @@ def __init__(self, parent, polys, check=True): INPUT: - - ``parent`` -- Hom-set. + - ``parent`` -- Hom-set - - ``polys`` -- anything that defines a point in the class. + - ``polys`` -- anything that defines a point in the class - - ``check`` -- Boolean. Whether or not to perform input checks. - (Default: ``True``) + - ``check`` -- boolean (default: ``True``); whether or not to perform + input checks EXAMPLES:: @@ -110,11 +110,9 @@ def __getitem__(self, i): INPUT: - - ``i`` -- integer. + - ``i`` -- integer - OUTPUT: - - The projective space point that is the ``i``-th coordinate. + OUTPUT: the projective space point that is the ``i``-th coordinate EXAMPLES:: @@ -133,7 +131,7 @@ def _repr_(self): r""" Return a string representation of this point. - OUTPUT: String. + OUTPUT: string EXAMPLES:: @@ -153,9 +151,7 @@ def _richcmp_(self, right, op): - ``other`` -- another point - OUTPUT: - - boolean + OUTPUT: boolean EXAMPLES:: @@ -207,9 +203,7 @@ def __copy__(self): r""" Return a copy of this point. - OUTPUT: - - - a point in the same space as third point. + OUTPUT: a point in the same space as third point EXAMPLES:: @@ -228,7 +222,7 @@ def __iter__(self): r""" Iterate over the coordinates of the point. - OUTPUT: An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -262,7 +256,7 @@ def __hash__(self): """ Compute the hash value of this point. - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: @@ -304,7 +298,7 @@ def normalize_coordinates(self): r""" Remove common factors (componentwise) from the coordinates of this point (including `-1`). - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -319,18 +313,16 @@ def normalize_coordinates(self): def dehomogenize(self, L): r""" - Dehomogenize `k^{th}` point at `L[k]^{th}` coordinate. + Dehomogenize `k`-th point at `L[k]`-th coordinate. This function computes the appropriate affine patch using ``L`` and then returns the dehomogenized point on of this affine space. INPUT: - - ``L`` -- a list of non-negative integers - - OUTPUT: + - ``L`` -- list of nonnegative integers - - :class:`SchemeMorphism_point_affine`. + OUTPUT: :class:`SchemeMorphism_point_affine` EXAMPLES:: @@ -368,7 +360,7 @@ def scale_by(self, t): r""" Scale the coordinates of the point by ``t``, done componentwise. - A :class:`TypeError` occurs if the point is not in the base ring + A :exc:`TypeError` occurs if the point is not in the base ring of the codomain after scaling. INPUT: @@ -399,15 +391,15 @@ def change_ring(self, R, **kwds): INPUT: - - ``R`` -- ring. + - ``R`` -- ring kwds: - - ``check`` -- Boolean. + - ``check`` -- boolean - - ``embedding`` -- field embedding from the base ring of this point to ``R``. + - ``embedding`` -- field embedding from the base ring of this point to ``R`` - OUTPUT: :class:`ProductProjectiveSpaces_point`. + OUTPUT: :class:`ProductProjectiveSpaces_point` EXAMPLES:: @@ -432,9 +424,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -484,12 +476,12 @@ def local_height(self, v, prec=None): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: A real number. + OUTPUT: a real number EXAMPLES:: @@ -524,9 +516,9 @@ def intersection_multiplicity(self, X): INPUT: - - ``X`` -- a subscheme in the same ambient space as the codomain of this point. + - ``X`` -- a subscheme in the same ambient space as the codomain of this point - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -549,7 +541,7 @@ def multiplicity(self): This uses the subscheme implementation of multiplicity. This point must be a point on a subscheme of a product of projective spaces. - OUTPUT: an integer. + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/schemes/product_projective/rational_point.py b/src/sage/schemes/product_projective/rational_point.py old mode 100644 new mode 100755 index 190ed0e36a9..1f29206dfd1 --- a/src/sage/schemes/product_projective/rational_point.py +++ b/src/sage/schemes/product_projective/rational_point.py @@ -78,12 +78,12 @@ def enum_product_projective_rational_field(X, B): - ``X`` -- a scheme or set of abstract rational points of a scheme - - ``B`` -- a positive integer bound + - ``B`` -- positive integer bound OUTPUT: - - a list containing the product projective points of ``X`` of height up - to ``B``, sorted. + A list containing the product projective points of ``X`` of height up + to ``B``, sorted. EXAMPLES:: @@ -173,6 +173,7 @@ def enum_product_projective_rational_field(X, B): return pts + def enum_product_projective_number_field(X, **kwds): r""" Enumerates product projective points on scheme ``X`` defined over a number field. @@ -191,20 +192,20 @@ def enum_product_projective_number_field(X, **kwds): This is an implementation of the revised algorithm (Algorithm 4) in [DK2013]_. Algorithm 5 is used for imaginary quadratic fields. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- a real number - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm-4 - - ``precision`` -- the precision to use for computing the elements of bounded height of number fields. + - ``precision`` -- the precision to use for computing the elements of + bounded height of number fields OUTPUT: - - a list containing the product projective points of ``X`` of - absolute height up to ``B``, sorted. + A list containing the product projective points of ``X`` of + absolute height up to ``B``, sorted. EXAMPLES:: @@ -247,19 +248,20 @@ def enum_product_projective_number_field(X, **kwds): pts.sort() return pts + def enum_product_projective_finite_field(X): r""" Enumerates projective points on scheme ``X`` defined over a finite field. INPUT: - - ``X`` -- a scheme defined over a finite field or a set of abstract - rational points of such a scheme. + - ``X`` -- a scheme defined over a finite field or a set of abstract + rational points of such a scheme OUTPUT: - - a list containing the projective points of ``X`` over the finite field, - sorted. + A list containing the projective points of ``X`` over the finite field, + sorted. EXAMPLES:: @@ -306,7 +308,7 @@ def enum_product_projective_finite_field(X): def sieve(X, bound): r""" - Returns the list of all rational points on scheme + Return the list of all rational points on scheme ``X`` of height up to ``bound``. ALGORITHM: @@ -326,12 +328,12 @@ def sieve(X, bound): - ``X`` -- a scheme with ambient space defined over a product of projective spaces - - ``bound`` -- a positive integer bound + - ``bound`` -- positive integer bound OUTPUT: - - a list containing the rational points of ``X`` of height - up to ``bound``, sorted + A list containing the rational points of ``X`` of height + up to ``bound``, sorted EXAMPLES:: @@ -368,7 +370,7 @@ def sieve(X, bound): def sufficient_primes(x): r""" - Returns a list of primes whose product is > `x` + Return a list of primes whose product is > `x`. """ small_primes = [2,3] prod_primes = 6 diff --git a/src/sage/schemes/product_projective/space.py b/src/sage/schemes/product_projective/space.py old mode 100644 new mode 100755 index ea99ea00559..f183d2676aa --- a/src/sage/schemes/product_projective/space.py +++ b/src/sage/schemes/product_projective/space.py @@ -63,12 +63,12 @@ def is_ProductProjectiveSpaces(x): r""" - Return True if ``x`` is a product of projective spaces. + Return ``True`` if ``x`` is a product of projective spaces. This is an ambient space defined by `\mathbb{P}^n_R \times \cdots \times \mathbb{P}^m_R`, where `R` is a ring and `n,\ldots, m\geq 0` are integers. - OUTPUT: Boolean. + OUTPUT: boolean EXAMPLES:: @@ -95,11 +95,11 @@ def ProductProjectiveSpaces(n, R=None, names='x'): INPUT: - - ``n`` -- a list of integers or a list of projective spaces + - ``n`` -- list of integers or a list of projective spaces - ``R`` -- a ring - - ``names`` -- a string or list of strings + - ``names`` -- string or list of strings EXAMPLES:: @@ -205,11 +205,11 @@ def __init__(self, N, R=QQ, names=None): INPUT: - - ``N`` -- a list or tuple of positive integers + - ``N`` -- list or tuple of positive integers - ``R`` -- a ring - - ``names`` -- a tuple or list of strings; this must either be a single + - ``names`` -- tuple or list of strings; this must either be a single variable name or the complete list of variables EXAMPLES:: @@ -293,8 +293,8 @@ def _latex_(self): EXAMPLES:: sage: latex(ProductProjectiveSpaces([1, 2, 3], ZZ, 'x')) - {\mathbf P}_{\Bold{Z}}^1 \times {\mathbf P}_{\Bold{Z}}^2 \times {\mathbf - P}_{\Bold{Z}}^3 + {\mathbf P}_{\Bold{Z}}^{1} \times {\mathbf P}_{\Bold{Z}}^{2} \times + {\mathbf P}_{\Bold{Z}}^{3} """ return " \\times ".join(PS._latex_() for PS in self) @@ -322,7 +322,7 @@ def __getitem__(self, i): INPUT: - - ``i`` -- a positive integer + - ``i`` -- positive integer OUTPUT: a projective space @@ -342,7 +342,7 @@ def __eq__(self, right): - ``right`` -- a product of projective spaces - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -364,7 +364,7 @@ def __ne__(self, other): - ``other`` -- a product of projective spaces - OUTPUT: Boolean + OUTPUT: boolean EXAMPLES:: @@ -395,9 +395,11 @@ def __pow__(self, m): """ Return the Cartesian power of this space. - INPUT: ``m`` -- integer. + INPUT: + + - ``m`` -- integer - OUTPUT: product of projective spaces. + OUTPUT: product of projective spaces EXAMPLES:: @@ -480,7 +482,7 @@ def components(self): r""" Return the components of this product of projective spaces. - OUTPUT: a list of projective spaces + OUTPUT: list of projective spaces EXAMPLES:: @@ -530,7 +532,7 @@ def dimension_relative_components(self): r""" Return the relative dimension of the product of projective spaces. - OUTPUT: a list of positive integers + OUTPUT: list of positive integers EXAMPLES:: @@ -544,7 +546,7 @@ def dimension_absolute_components(self): r""" Return the absolute dimension of the product of projective spaces. - OUTPUT: a list of positive integers + OUTPUT: list of positive integers EXAMPLES:: @@ -563,9 +565,9 @@ def dimension_absolute_components(self): def num_components(self): r""" - Returns the number of components of this space. + Return the number of components of this space. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -582,7 +584,7 @@ def ngens(self): This is the number of variables in the coordinate ring of the projective space. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -598,9 +600,9 @@ def _factors(self, v): INPUT: - - ``v`` -- a list or tuple + - ``v`` -- list or tuple - OUTPUT: a list of lists + OUTPUT: list of lists EXAMPLES:: @@ -628,8 +630,8 @@ def _degree(self, polynomial): - ``polynomial`` -- a polynomial in the coordinate_ring - OUTPUT: A tuple of integers, one for each projective space component. A - :class:`ValueError` is raised if the polynomial is not multihomogeneous. + OUTPUT: a tuple of integers, one for each projective space component. A + :exc:`ValueError` is raised if the polynomial is not multihomogeneous. EXAMPLES:: @@ -699,17 +701,16 @@ def _point_homset(self, *args, **kwds): def _validate(self, polynomials): r""" If ``polynomials`` is a tuple of valid polynomial functions on this space, - return ``polynomials``, otherwise raise a :class:`TypeError`. + return ``polynomials``, otherwise raise a :exc:`TypeError`. Since this is a product of projective spaces, the polynomials must be multi-homogeneous. INPUT: - - ``polynomials`` -- tuple of polynomials in the coordinate ring of this projective space. - - OUTPUT: + - ``polynomials`` -- tuple of polynomials in the coordinate ring of + this projective space - - tuple of polynomials in the coordinate ring of this space. + OUTPUT: tuple of polynomials in the coordinate ring of this space EXAMPLES:: @@ -750,7 +751,7 @@ def _validate(self, polynomials): def _check_satisfies_equations(self, v): """ Return ``True`` if ``v`` defines a point on the scheme this space; - raise a :class:`TypeError` otherwise. + raise a :exc:`TypeError` otherwise. EXAMPLES:: @@ -810,13 +811,11 @@ def _check_satisfies_equations(self, v): def _an_element_(self): r""" - Returns a (preferably typical) element of this space. + Return a (preferably typical) element of this space. This is used both for illustration and testing purposes. - OUTPUT: - - A point in the this projective space. + OUTPUT: a point in the this projective space EXAMPLES:: @@ -834,11 +833,9 @@ def subscheme(self, X): INPUT: - - ``X`` -- a list or tuple of equations - - OUTPUT: + - ``X`` -- list or tuple of equations - :class:`AlgebraicScheme_subscheme_projective_cartesian_product`. + OUTPUT: :class:`AlgebraicScheme_subscheme_projective_cartesian_product` EXAMPLES:: @@ -870,15 +867,14 @@ def subscheme(self, X): def change_ring(self, R): r""" - Return a product of projective spaces over a ring ``R`` and otherwise the same as this projective space. + Return a product of projective spaces over a ring ``R`` and otherwise + the same as this projective space. INPUT: - ``R`` -- commutative ring or morphism - OUTPUT: - - - Product of projective spaces over ``R``. + OUTPUT: product of projective spaces over ``R`` .. NOTE:: @@ -897,14 +893,15 @@ def change_ring(self, R): def affine_patch(self, I, return_embedding=False): r""" - Return the `I^{th}` affine patch of this projective space product + Return the `I`-th affine patch of this projective space product where ``I`` is a multi-index. INPUT: - - ``I`` -- a list or tuple of positive integers. + - ``I`` -- list or tuple of positive integers - - ``return_embedding`` -- Boolean, if true the projective embedding is also returned. + - ``return_embedding`` -- boolean; if ``True`` the projective embedding + is also returned OUTPUT: @@ -966,14 +963,14 @@ def segre_embedding(self, PP=None, var='u'): INPUT: - - ``PP`` -- (default: ``None``) ambient image projective space; - this is constructed if it is not given. + - ``PP`` -- (default: ``None``) ambient image projective space; + this is constructed if it is not given - - ``var`` -- string, variable name of the image projective space, default `u` (optional). + - ``var`` -- string (default: ``'u'``); variable name of the image + projective space - OUTPUT: - - Hom -- from this space to the appropriate subscheme of projective space. + OUTPUT: Hom; from this space to the appropriate subscheme of projective + space .. TODO:: @@ -1083,6 +1080,7 @@ def segre_embedding(self, PP=None, var='u'): return phi + class ProductProjectiveSpaces_field(ProductProjectiveSpaces_ring): def _point(self, *args, **kwds): """ @@ -1117,13 +1115,13 @@ def _point_homset(self, *args, **kwds): def points_of_bounded_height(self, **kwds): r""" - Returns an iterator of the points in this product of projective spaces with the absolute heights of the - components of at most the given bound. + Return an iterator of the points in this product of projective spaces + with the absolute heights of the components of at most the given bound. - Bound check is strict for the rational field. Requires the base field of this space to be a number field. - Uses the - Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for - computing algebraic numbers up to a given height [DK2013]_. + Bound check is strict for the rational field. Requires the base field + of this space to be a number field. Uses the Doyle-Krumm algorithm 4 + (algorithm 5 for imaginary quadratic) for computing algebraic numbers + up to a given height [DK2013]_. The algorithm requires floating point arithmetic, so the user is allowed to specify the precision for such calculations. @@ -1136,9 +1134,11 @@ def points_of_bounded_height(self, **kwds): - ``bound`` -- a real number - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm-4 - - ``precision`` -- the precision to use for computing the elements of bounded height of number fields. + - ``precision`` -- the precision to use for computing the elements of + bounded height of number fields OUTPUT: an iterator of points in this space @@ -1221,6 +1221,7 @@ def points_of_bounded_height(self, **kwds): P[dim_prefix[i] + j] = pt[j] i += 1 + class ProductProjectiveSpaces_finite_field(ProductProjectiveSpaces_field): def _point(self, *args, **kwds): r""" @@ -1238,7 +1239,7 @@ def _point(self, *args, **kwds): def __iter__(self): r""" - Returns iterator over the elements of this product of projective spaces. + Return an iterator over the elements of this product of projective spaces. EXAMPLES:: diff --git a/src/sage/schemes/product_projective/subscheme.py b/src/sage/schemes/product_projective/subscheme.py old mode 100644 new mode 100755 index 35433ba565b..511f10a973e --- a/src/sage/schemes/product_projective/subscheme.py +++ b/src/sage/schemes/product_projective/subscheme.py @@ -23,6 +23,7 @@ from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective from sage.schemes.projective.projective_space import ProjectiveSpace + class AlgebraicScheme_subscheme_product_projective(AlgebraicScheme_subscheme_projective): r""" Construct an algebraic subscheme of a product of projective spaces. @@ -38,10 +39,10 @@ class AlgebraicScheme_subscheme_product_projective(AlgebraicScheme_subscheme_pro INPUT: - ``A`` -- ambient :class:`Product of Projective Spaces - `. + ` - ``polynomials`` -- single polynomial, ideal or iterable of - defining multi-homogeneous polynomials. + defining multi-homogeneous polynomials EXAMPLES:: @@ -70,11 +71,9 @@ def segre_embedding(self, PP=None): INPUT: - ``PP`` -- (default: ``None``) ambient image projective space; - this is constructed if it is not given. - - OUTPUT: + this is constructed if it is not given - Hom from this subscheme to the appropriate subscheme of projective space + OUTPUT: hom from this subscheme to the appropriate subscheme of projective space EXAMPLES:: @@ -186,7 +185,7 @@ def dimension(self): r""" Return the dimension of the algebraic subscheme. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -263,14 +262,15 @@ def is_smooth(self, point=None): def affine_patch(self, I, return_embedding=False): r""" - Return the `I^{th}` affine patch of this projective scheme + Return the `I`-th affine patch of this projective scheme where `I` is a multi-index. INPUT: - - ``I`` -- a list or tuple of positive integers + - ``I`` -- list or tuple of positive integers - - ``return_embedding`` -- Boolean, if true the projective embedding is also returned + - ``return_embedding`` -- boolean; if ``True`` the projective embedding + is also returned OUTPUT: @@ -336,18 +336,19 @@ def affine_patch(self, I, return_embedding=False): def intersection_multiplicity(self, X, P): r""" - Return the intersection multiplicity of this subscheme and the subscheme ``X`` at the point ``P``. + Return the intersection multiplicity of this subscheme and the + subscheme ``X`` at the point ``P``. - This uses the intersection_multiplicity function for affine subschemes on affine patches of this subscheme - and ``X`` that contain ``P``. + This uses the intersection_multiplicity function for affine subschemes + on affine patches of this subscheme and ``X`` that contain ``P``. INPUT: - - ``X`` -- subscheme in the same ambient space as this subscheme. + - ``X`` -- subscheme in the same ambient space as this subscheme - - ``P`` -- a point in the intersection of this subscheme with ``X``. + - ``P`` -- a point in the intersection of this subscheme with ``X`` - OUTPUT: An integer. + OUTPUT: integer EXAMPLES: @@ -416,9 +417,9 @@ def multiplicity(self, P): INPUT: - - ``P`` -- a point on this subscheme. + - ``P`` -- a point on this subscheme - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py old mode 100644 new mode 100755 index df3db88cda7..232f51188b4 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -20,18 +20,19 @@ from math import floor -from sage.schemes.projective.projective_space import ProjectiveSpace -from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ -from sage.rings.real_mpfr import RealField -from sage.rings.number_field.unit_group import UnitGroup -from sage.arith.misc import gcd from sage.arith.functions import lcm -from sage.matrix.constructor import matrix, column_matrix -from sage.libs.pari.all import pari -from sage.modules.free_module_element import vector +from sage.arith.misc import gcd +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer -from sage.geometry.polyhedron.constructor import Polyhedron +from sage.rings.rational_field import QQ +from sage.schemes.projective.projective_space import ProjectiveSpace + +lazy_import('sage.geometry.polyhedron.constructor', 'Polyhedron') +lazy_import('sage.libs.pari.all', 'pari') +lazy_import('sage.matrix.constructor', ['matrix', 'column_matrix']) +lazy_import('sage.modules.free_module_element', 'vector') +lazy_import('sage.rings.number_field.unit_group', 'UnitGroup') +lazy_import('sage.rings.real_mpfr', 'RealField') def ZZ_points_of_bounded_height(PS, dim, bound): @@ -43,13 +44,11 @@ def ZZ_points_of_bounded_height(PS, dim, bound): - ``PS`` -- a projective space - - ``dim`` -- a positive integer - - - ``bound`` -- a positive integer + - ``dim`` -- positive integer - OUTPUT: + - ``bound`` -- positive integer - - an iterator of points of bounded height + OUTPUT: an iterator of points of bounded height EXAMPLES:: @@ -98,16 +97,14 @@ def QQ_points_of_bounded_height(PS, dim, bound, normalize=False): - ``PS`` -- a projective space - - ``dim`` -- a positive integer + - ``dim`` -- positive integer - ``bound`` -- a real number - ``normalize`` -- boolean (default: ``False``); whether to normalize the coordinates of returned points - OUTPUT: - - - an iterator of points of bounded height + OUTPUT: an iterator of points of bounded height EXAMPLES:: @@ -165,9 +162,7 @@ def IQ_points_of_bounded_height(PS, K, dim, bound): - ``bound`` -- a real number - OUTPUT: - - - an iterator of points of bounded height + OUTPUT: an iterator of points of bounded height EXAMPLES: @@ -241,15 +236,13 @@ def points_of_bounded_height(PS, K, dim, bound, prec=53): - ``K`` -- a number field - - ``dim`` -- a positive integer + - ``dim`` -- positive integer - ``bound`` -- a real number - ``prec`` -- (default: 53) a positive integer - OUTPUT: - - - an iterator of points of bounded height + OUTPUT: an iterator of points of bounded height EXAMPLES:: diff --git a/src/sage/schemes/projective/projective_homset.py b/src/sage/schemes/projective/projective_homset.py old mode 100644 new mode 100755 index bc1a781c00b..7f86f7ea0f6 --- a/src/sage/schemes/projective/projective_homset.py +++ b/src/sage/schemes/projective/projective_homset.py @@ -10,7 +10,7 @@ the rational points are implemented by such scheme morphisms. This is done by :class:`SchemeHomset_points` and its subclasses. -.. note:: +.. NOTE:: You should not create the Hom-sets manually. Instead, use the :meth:`~sage.structure.parent.Hom` method that is inherited by all @@ -37,20 +37,21 @@ # http://www.gnu.org/licenses/ # ***************************************************************************** -from sage.rings.integer_ring import ZZ -from sage.rings.real_mpfr import RR -from sage.rings.cc import CC -from sage.schemes.generic.homset import SchemeHomset_points, SchemeHomset_generic - -from sage.misc.verbose import verbose +from copy import copy -from sage.rings.rational_field import RationalField from sage.categories.fields import Fields from sage.categories.number_fields import NumberFields +from sage.misc.lazy_import import lazy_import +from sage.misc.verbose import verbose from sage.rings.finite_rings.finite_field_base import FiniteField +from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.rational_field import RationalField from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme -from copy import copy +from sage.schemes.generic.homset import SchemeHomset_points, SchemeHomset_generic + +lazy_import('sage.rings.cc', 'CC') +lazy_import('sage.rings.real_mpfr', 'RR') # ******************************************************************* @@ -79,30 +80,26 @@ def points(self, **kwds): basis calculation. For schemes or subschemes with dimension greater than 1 points are determined through enumeration up to the specified bound. - INPUT: - - kwds: + INPUT: keyword arguments: - - ``bound`` -- real number (default: 0). The bound for the coordinates for - subschemes with dimension at least 1. + - ``bound`` -- real number (default: 0); the bound for the coordinates + for subschemes with dimension at least 1 - - ``precision`` -- integer (default: 53). The precision to use to - compute the elements of bounded height for number fields. - - - ``point_tolerance`` -- positive real number (default: `10^{-10}`). - For numerically inexact fields, two points are considered the same - if their coordinates are within tolerance. + - ``precision`` -- integer (default: 53); the precision to use to + compute the elements of bounded height for number fields - - ``zero_tolerance`` -- positive real number (default: `10^{-10}`). - For numerically inexact fields, points are on the subscheme if they - satisfy the equations to within tolerance. + - ``point_tolerance`` -- positive real number (default: `10^{-10}`); + for numerically inexact fields, two points are considered the same + if their coordinates are within tolerance - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 - for enumeration over number fields. + - ``zero_tolerance`` -- positive real number (default: `10^{-10}`); + for numerically inexact fields, points are on the subscheme if they + satisfy the equations to within tolerance - OUTPUT: + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm-4 for enumeration over number fields - - a list of rational points of a projective scheme + OUTPUT: list of rational points of a projective scheme .. WARNING:: @@ -317,7 +314,7 @@ def numerical_points(self, F=None, **kwds): For numerically inexact fields, points are on the subscheme if they satisfy the equations to within tolerance. - OUTPUT: A list of points in the ambient space. + OUTPUT: list of points in the ambient space .. WARNING:: @@ -486,8 +483,7 @@ def points(self, B=0): INPUT: - - ``B`` -- integer (default: 0). The bound for the - coordinates. + - ``B`` -- integer (default: 0); the bound for the coordinates EXAMPLES:: @@ -623,12 +619,9 @@ def _element_constructor_(self, *v, **kwds): INPUT: - - ``v`` -- anything that determines a scheme morphism in the - Hom-set. - - OUTPUT: + - ``v`` -- anything that determines a scheme morphism in the Hom-set - The scheme morphism determined by ``v``. + OUTPUT: the scheme morphism determined by ``v`` EXAMPLES:: @@ -653,9 +646,7 @@ def _repr_(self): """ Return a string representation of this homset. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -676,7 +667,7 @@ def base_extend(self, R): INPUT: - - ``R`` -- a ring. + - ``R`` -- a ring EXAMPLES:: diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py old mode 100644 new mode 100755 index 339406cd9d6..20031e81a41 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -58,25 +58,37 @@ # **************************************************************************** import sys -from sage.arith.misc import GCD as gcd + +import sage.rings.abc + from sage.arith.functions import lcm -from sage.misc.misc_c import prod +from sage.arith.misc import GCD as gcd +from sage.categories.fields import Fields +from sage.categories.finite_fields import FiniteFields +from sage.categories.homset import Hom, End +from sage.categories.number_fields import NumberFields from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute -import sage.rings.abc -from sage.rings.integer import Integer -from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic +from sage.misc.lazy_import import lazy_import +from sage.misc.misc_c import prod from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.fraction_field import FractionField +from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.quotient_ring import QuotientRing_generic from sage.rings.rational_field import QQ from sage.schemes.generic.morphism import SchemeMorphism_polynomial -from sage.categories.finite_fields import FiniteFields -from sage.categories.number_fields import NumberFields -from sage.categories.homset import Hom, End -from sage.categories.fields import Fields + +lazy_import('sage.dynamics.arithmetic_dynamics.generic_ds', 'DynamicalSystem') +lazy_import('sage.dynamics.arithmetic_dynamics.projective_ds', + ['DynamicalSystem_projective', 'DynamicalSystem_projective_field', + 'DynamicalSystem_projective_finite_field']) +lazy_import('sage.rings.algebraic_closure_finite_field', 'AlgebraicClosureFiniteField_generic') +lazy_import('sage.rings.number_field.number_field_ideal', 'NumberFieldFractionalIdeal') +lazy_import('sage.rings.padics.padic_base_generic', 'pAdicGeneric') +lazy_import('sage.rings.padics.padic_valuation', 'pAdicValuation_base') + _NumberFields = NumberFields() _FiniteFields = FiniteFields() @@ -280,9 +292,9 @@ def __call__(self, x, check=True): INPUT: - - ``x`` -- a point or subscheme in domain of this map. + - ``x`` -- a point or subscheme in domain of this map - - ``check`` -- Boolean; if `False` assume that ``x`` is a point. + - ``check`` -- boolean; if ``False`` assume that ``x`` is a point EXAMPLES:: @@ -496,7 +508,7 @@ def _fast_eval(self, x): def __eq__(self, right): """ - Tests the equality of two projective morphisms. + Test the equality of two projective morphisms. INPUT: @@ -547,7 +559,7 @@ def __eq__(self, right): def __ne__(self, right): """ - Tests the inequality of two projective morphisms. + Test the inequality of two projective morphisms. INPUT: @@ -585,7 +597,7 @@ def __ne__(self, right): def _matrix_times_polymap_(self, mat, h): """ - Multiplies the morphism on the left by a matrix ``mat``. + Multiply the morphism on the left by a matrix ``mat``. INPUT: @@ -618,7 +630,6 @@ def _matrix_times_polymap_(self, mat, h): ((1/3*i)*x^2 + (1/2*i)*y^2 : i*y^2) """ from sage.modules.free_module_element import vector - from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem if not mat.is_square(): raise ValueError("matrix must be square") @@ -631,7 +642,7 @@ def _matrix_times_polymap_(self, mat, h): def _polymap_times_matrix_(self, mat, h): """ - Multiplies the morphism on the right by a matrix ``mat``. + Multiply the morphism on the right by a matrix ``mat``. INPUT: @@ -664,7 +675,6 @@ def _polymap_times_matrix_(self, mat, h): (-1/3*x^2 - 1/2*y^2 : -y^2) """ from sage.modules.free_module_element import vector - from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem if not mat.is_square(): raise ValueError("matrix must be square") if mat.nrows() != self.domain().ngens(): @@ -680,9 +690,7 @@ def as_dynamical_system(self): """ Return this endomorphism as a :class:`DynamicalSystem_projective`. - OUTPUT: - - - :class:`DynamicalSystem_projective` + OUTPUT: :class:`DynamicalSystem_projective` EXAMPLES:: @@ -716,14 +724,10 @@ def as_dynamical_system(self): sage: g is f # needs sage.schemes True """ - from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem if isinstance(self, DynamicalSystem): return self if not self.is_endomorphism(): raise TypeError("must be an endomorphism") - from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective - from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective_field - from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective_finite_field R = self.base_ring() if R not in _Fields: return DynamicalSystem_projective(list(self), self.domain()) @@ -735,16 +739,14 @@ def scale_by(self, t): """ Scale each coordinate by a factor of ``t``. - A :class:`TypeError` occurs if the point is not in the coordinate ring + A :exc:`TypeError` occurs if the point is not in the coordinate ring of the parent after scaling. INPUT: - - ``t`` -- a ring element. + - ``t`` -- a ring element - OUTPUT: - - - None. + OUTPUT: none EXAMPLES:: @@ -808,19 +810,15 @@ def normalize_coordinates(self, **kwds): absolute value less than or equal to 1. Only supported when the base ring is a number field. - INPUT: - - kwds: + INPUT: keyword arguments: - ``ideal`` -- (optional) a prime ideal of the base ring of this - morphism. + morphism - ``valuation`` -- (optional) a valuation of the base ring of this - morphism. - - OUTPUT: + morphism - - None. + OUTPUT: none EXAMPLES:: @@ -948,7 +946,6 @@ def normalize_coordinates(self, **kwds): # defined by the ideal/valuation ideal = kwds.pop('ideal', None) if ideal is not None: - from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal if not (ideal in ZZ or isinstance(ideal, NumberFieldFractionalIdeal)): raise TypeError('ideal must be an ideal of a number field, not %s' % ideal) if isinstance(ideal, NumberFieldFractionalIdeal): @@ -980,7 +977,6 @@ def normalize_coordinates(self, **kwds): valuation = kwds.pop('valuation', None) if valuation is not None: - from sage.rings.padics.padic_valuation import pAdicValuation_base if not isinstance(valuation, pAdicValuation_base): raise TypeError('valuation must be a valuation on a number field, not %s' % valuation) if valuation.domain() != self.base_ring(): @@ -1048,7 +1044,6 @@ def normalize_coordinates(self, **kwds): self.scale_by(1 / GCD) # If R is not p-adic, we make the first coordinate positive - from sage.rings.padics.padic_base_generic import pAdicGeneric if not isinstance(R, pAdicGeneric): if self[0].lc() < 0: self.scale_by(-1) @@ -1060,9 +1055,7 @@ def degree(self): The degree is defined as the degree of the homogeneous polynomials that are the coordinates of this map. - OUTPUT: - - - A positive integer + OUTPUT: positive integer EXAMPLES:: @@ -1111,12 +1104,10 @@ def dehomogenize(self, n): INPUT: - - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, then the two values of - the tuple are assumed to be the same. + - ``n`` -- tuple of nonnegative integers; if ``n`` is an integer, then + the two values of the tuple are assumed to be the same - OUTPUT: - - - :class:`SchemeMorphism_polynomial_affine_space`. + OUTPUT: :class:`SchemeMorphism_polynomial_affine_space` EXAMPLES:: @@ -1253,9 +1244,7 @@ def is_morphism(self): the defining polynomials is the unit ideal (no common zeros of the defining polynomials). - OUTPUT: - - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -1314,11 +1303,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default RealField precision) - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -1416,14 +1403,12 @@ def local_height(self, v, prec=None): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default RealField precision) - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -1475,14 +1460,12 @@ def local_height_arch(self, i, prec=None): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: - - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -1526,7 +1509,7 @@ def wronskian_ideal(self): This is the vanishing of the maximal minors of the Jacobian matrix. Not implemented for subvarieties. - OUTPUT: an ideal in the coordinate ring of the domain of this map. + OUTPUT: an ideal in the coordinate ring of the domain of this map EXAMPLES:: @@ -1578,13 +1561,11 @@ def rational_preimages(self, Q, k=1): INPUT: - - ``Q`` -- a rational point or subscheme in the domain of this map. + - ``Q`` -- a rational point or subscheme in the domain of this map - - ``k`` -- positive integer. + - ``k`` -- positive integer - OUTPUT: - - - a list of rational points or a subscheme in the domain of this map. + OUTPUT: a list of rational points or a subscheme in the domain of this map EXAMPLES:: @@ -1764,10 +1745,10 @@ def _number_field_from_algebraics(self): Scheme morphism: From: Projective Space of dimension 1 over Number Field in a with defining polynomial y^4 + 3*y^2 + 1 - with a = 0.?e-151 + 0.618033988749895?*I + with a = 0.?e-113 + 0.618033988749895?*I To: Projective Space of dimension 2 over Number Field in a with defining polynomial y^4 + 3*y^2 + 1 - with a = 0.?e-151 + 0.618033988749895?*I + with a = 0.?e-113 + 0.618033988749895?*I Defn: Defined on coordinates by sending (x : y) to (x^2 + (a^3 + 2*a)*x*y + 3*y^2 : y^2 : (2*a^2 + 3)*x*y) @@ -1941,7 +1922,6 @@ def indeterminacy_locus(self): x*z - y*z, x^2 - y^2, z^2 - """ from sage.misc.superseded import deprecation deprecation(29145, "The meaning of indeterminacy_locus() has changed. Read the docstring.") @@ -2062,7 +2042,7 @@ def reduce_base_field(self): the base ring is a number field, QQbar, a finite field, or algebraic closure of a finite field. - OUTPUT: A scheme morphism. + OUTPUT: a scheme morphism EXAMPLES:: diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py old mode 100644 new mode 100755 index 1efc16af934..7f941ec6726 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -26,26 +26,29 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from copy import copy + +from sage.arith.functions import lcm +from sage.arith.misc import gcd from sage.categories.integral_domains import IntegralDomains from sage.categories.number_fields import NumberFields -_NumberFields = NumberFields() -from sage.rings.integer_ring import ZZ +from sage.misc.lazy_import import lazy_import +from sage.misc.misc_c import prod +from sage.rings.abc import Order from sage.rings.fraction_field import FractionField -from sage.rings.number_field.order import Order as NumberFieldOrder -from sage.rings.qqbar import number_field_elements_from_algebraics +from sage.rings.integer_ring import ZZ from sage.rings.quotient_ring import QuotientRing_generic from sage.rings.rational_field import QQ -from sage.arith.misc import GCD as gcd -from sage.arith.functions import lcm -from sage.misc.misc_c import prod - -from copy import copy +from sage.rings.ring import CommutativeRing from sage.schemes.generic.morphism import (SchemeMorphism, - is_SchemeMorphism, SchemeMorphism_point) from sage.structure.element import AdditiveGroupElement -from sage.structure.sequence import Sequence from sage.structure.richcmp import richcmp, op_EQ, op_NE +from sage.structure.sequence import Sequence + +lazy_import('sage.rings.qqbar', 'number_field_elements_from_algebraics') + +_NumberFields = NumberFields() # -------------------- @@ -58,18 +61,17 @@ class SchemeMorphism_point_projective_ring(SchemeMorphism_point): INPUT: - - ``X`` -- a homset of a subscheme of an ambient projective space over a ring `K`. + - ``X`` -- a homset of a subscheme of an ambient projective space over a ring `K` - - ``v`` -- a list or tuple of coordinates in `K`. + - ``v`` -- list or tuple of coordinates in `K` - - ``check`` -- boolean (default:``True``). Whether to check the input for consistency. + - ``check`` -- boolean (default: ``True``); whether to check the input for consistency EXAMPLES:: sage: P = ProjectiveSpace(2, ZZ) sage: P(2,3,4) (2 : 3 : 4) - """ def __init__(self, X, v, check=True): @@ -161,10 +163,8 @@ def __init__(self, X, v, check=True): SchemeMorphism.__init__(self, X) if check: - from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field - from sage.rings.ring import CommutativeRing d = X.codomain().ambient_space().ngens() - if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field): + if isinstance(v, SchemeMorphism): v = list(v) else: try: @@ -184,7 +184,7 @@ def __init__(self, X, v, check=True): if R in IntegralDomains(): # Over integral domains, any tuple with at least one - # non-zero coordinate is a valid projective point. + # nonzero coordinate is a valid projective point. if not any(v): raise ValueError(f"{v} does not define a valid projective " "point since all entries are zero") @@ -209,9 +209,7 @@ def _richcmp_(self, right, op): - ``right`` -- a point on projective space - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -386,7 +384,7 @@ def __hash__(self): equal hash values. If the base ring is not an integral domain, return the hash of the parent. - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: @@ -428,7 +426,7 @@ def __hash__(self): def _matrix_times_point_(self, mat, dom): r""" - Multiplies the point by a matrix ``mat`` on the left. + Multiply the point by a matrix ``mat`` on the left. INPUT: @@ -487,14 +485,14 @@ def scale_by(self, t): """ Scale the coordinates of the point by ``t``. - A :class:`TypeError` occurs if the point is not in the + A :exc:`TypeError` occurs if the point is not in the base_ring of the codomain after scaling. INPUT: - - ``t`` -- a ring element. + - ``t`` -- a ring element - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -539,7 +537,7 @@ def normalize_coordinates(self): .. WARNING:: The gcd will depend on the base ring. - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -633,11 +631,9 @@ def dehomogenize(self,n): INPUT: - - ``n`` -- non-negative integer. - - OUTPUT: + - ``n`` -- nonnegative integer - - :class:`SchemeMorphism_point_affine`. + OUTPUT: :class:`SchemeMorphism_point_affine` EXAMPLES:: @@ -690,11 +686,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: - - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -749,7 +743,7 @@ def global_height(self, prec=None): if prec is None: prec = 53 K = self.codomain().base_ring() - if K in _NumberFields or isinstance(K, NumberFieldOrder) or K == ZZ: + if K in _NumberFields or K is ZZ or isinstance(K, Order): P = self else: try: @@ -758,7 +752,7 @@ def global_height(self, prec=None): raise TypeError("must be defined over an algebraic field") else: K = P.codomain().base_ring() - if isinstance(K, NumberFieldOrder): + if isinstance(K, Order): K = K.number_field() # first get rid of the denominators denom = lcm([xi.denominator() for xi in P]) @@ -776,18 +770,16 @@ def global_height(self, prec=None): def local_height(self, v, prec=None): r""" - Returns the maximum of the local height of the coordinates of this point. + Return the maximum of the local height of the coordinates of this point. INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default RealField precision) - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -810,18 +802,16 @@ def local_height(self, v, prec=None): def local_height_arch(self, i, prec=None): r""" - Returns the maximum of the local heights at the ``i``-th infinite place of this point. + Return the maximum of the local heights at the ``i``-th infinite place of this point. INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default RealField precision). + default RealField precision) - OUTPUT: - - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -848,17 +838,18 @@ def local_height_arch(self, i, prec=None): def multiplier(self, f, n, check=True): r""" - Returns the multiplier of this point of period ``n`` by the function ``f``. + Return the multiplier of this point of period ``n`` by the function ``f``. ``f`` must be an endomorphism of projective space. INPUT: - - ``f`` -- a endomorphism of this point's codomain. + - ``f`` -- a endomorphism of this point's codomain - - ``n`` -- a positive integer, the period of this point. + - ``n`` -- positive integer; the period of this point - - ``check`` -- check if ``P`` is periodic of period ``n``, Default:True. + - ``check`` -- boolean (default: ``True``); check if ``P`` is periodic + of period ``n`` OUTPUT: @@ -906,18 +897,18 @@ def is_preperiodic(self, f, err=0.1, return_period=False): INPUT: - - ``f`` -- an endomorphism of this point's codomain. + - ``f`` -- an endomorphism of this point's codomain kwds: - - ``err`` -- a positive real number (default: 0.1). + - ``err`` -- a positive real number (default: 0.1) - - ``return_period`` -- boolean (default: ``False``). + - ``return_period`` -- boolean (default: ``False``) OUTPUT: - - boolean -- ``True`` if preperiodic. + - boolean; ``True`` if preperiodic. - if ``return_period`` is ``True``, then ``(0,0)`` if wandering, and ``(m,n)`` if preperiod ``m`` and period ``n``. @@ -1058,13 +1049,13 @@ class SchemeMorphism_point_projective_field(SchemeMorphism_point_projective_ring INPUT: - - ``X`` -- a homset of a subscheme of an ambient projective space - over a field `K`. + - ``X`` -- a homset of a subscheme of an ambient projective space + over a field `K` - - ``v`` -- a list or tuple of coordinates in `K`. + - ``v`` -- list or tuple of coordinates in `K` - - ``check`` -- boolean (default:``True``). Whether to - check the input for consistency. + - ``check`` -- boolean (default: ``True``); whether to + check the input for consistency EXAMPLES:: @@ -1080,7 +1071,7 @@ def __init__(self, X, v, check=True): See :class:`SchemeMorphism_point_projective_ring` for details. - This function still normalizes points so that the rightmost non-zero coordinate is 1. + This function still normalizes points so that the rightmost nonzero coordinate is 1. This is to maintain functionality with current implementations of curves in projectives space (plane, conic, elliptic, etc). The :class:`SchemeMorphism_point_projective_ring` is for general use. @@ -1138,10 +1129,8 @@ def __init__(self, X, v, check=True): self._normalized = False if check: - from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field - from sage.rings.ring import CommutativeRing d = X.codomain().ambient_space().ngens() - if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field): + if isinstance(v, SchemeMorphism): v = list(v) else: try: @@ -1179,9 +1168,9 @@ def __init__(self, X, v, check=True): def __hash__(self): """ - Computes the hash value of this point. + Compute the hash value of this point. - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: @@ -1195,9 +1184,9 @@ def __hash__(self): def normalize_coordinates(self): r""" - Normalizes the point so that the last non-zero coordinate is `1`. + Normalize the point so that the last nonzero coordinate is `1`. - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -1290,9 +1279,9 @@ def _number_field_from_algebraics(self): def clear_denominators(self): r""" - scales by the least common multiple of the denominators. + Scale by the least common multiple of the denominators. - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -1339,9 +1328,9 @@ def intersection_multiplicity(self, X): INPUT: - - ``X`` -- a subscheme in the same ambient space as that of the codomain of this point. + - ``X`` -- a subscheme in the same ambient space as that of the codomain of this point - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: @@ -1380,7 +1369,7 @@ def multiplicity(self): Uses the subscheme multiplicity implementation. This point must be a point on a projective subscheme. - OUTPUT: an integer. + OUTPUT: integer EXAMPLES:: @@ -1431,9 +1420,9 @@ class SchemeMorphism_point_projective_finite_field(SchemeMorphism_point_projecti def __hash__(self): r""" - Returns the integer hash of this point. + Return the integer hash of this point. - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: diff --git a/src/sage/schemes/projective/projective_rational_point.py b/src/sage/schemes/projective/projective_rational_point.py old mode 100644 new mode 100755 index bc4b3fbdcd4..82653894cca --- a/src/sage/schemes/projective/projective_rational_point.py +++ b/src/sage/schemes/projective/projective_rational_point.py @@ -54,19 +54,23 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** + from itertools import product from sage.arith.misc import gcd, next_prime, previous_prime, crt from sage.arith.srange import srange -from sage.rings.integer_ring import ZZ -from sage.rings.real_mpfr import RR -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.misc.mrange import xmrange from sage.schemes.generic.scheme import Scheme from sage.parallel.ncpus import ncpus from sage.parallel.use_fork import p_iter_fork -from sage.matrix.constructor import matrix +from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.rings.integer_ring import ZZ +from sage.schemes.generic.scheme import is_Scheme + +lazy_import('sage.matrix.constructor', 'matrix') +lazy_import('sage.rings.real_mpfr', 'RR') def enum_projective_rational_field(X, B): @@ -76,14 +80,14 @@ def enum_projective_rational_field(X, B): INPUT: - - ``X`` -- a scheme or set of abstract rational points of a scheme. + - ``X`` -- a scheme or set of abstract rational points of a scheme - - ``B`` -- a positive integer bound. + - ``B`` -- a positive integer bound OUTPUT: - - a list containing the projective points of ``X`` of height up to ``B``, - sorted. + A list containing the projective points of ``X`` of height up to ``B``, + sorted. EXAMPLES:: @@ -167,20 +171,18 @@ def enum_projective_number_field(X, **kwds): This is an implementation of the revised algorithm (Algorithm 4) in [DK2013]_. Algorithm 5 is used for imaginary quadratic fields. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- a real number - - ``tolerance`` -- a rational number in (0,1] used in doyle-krumm algorithm-4 + - ``tolerance`` -- a rational number in (0,1] used in Doyle-Krumm + algorithm-4 - - ``precision`` -- the precision to use for computing the elements of bounded height of number fields. - - OUTPUT: + - ``precision`` -- the precision to use for computing the elements of + bounded height of number fields - - a list containing the projective points of ``X`` of absolute height up to ``B``, - sorted. + OUTPUT: a sorted list containing the projective points of ``X`` of absolute + height up to ``B`` EXAMPLES:: @@ -234,13 +236,13 @@ def enum_projective_finite_field(X): INPUT: - - ``X`` -- a scheme defined over a finite field or a set of abstract - rational points of such a scheme. + - ``X`` -- a scheme defined over a finite field or a set of abstract + rational points of such a scheme OUTPUT: - - a list containing the projective points of ``X`` over the finite field, - sorted. + A list containing the projective points of ``X`` over the finite field, + sorted. EXAMPLES:: @@ -310,7 +312,7 @@ def enum_projective_finite_field(X): def sieve(X, bound): r""" - Returns the list of all projective, rational points on scheme ``X`` of + Return the list of all projective, rational points on scheme ``X`` of height up to ``bound``. Height of a projective point `X = (x_1, x_2,\dots, x_n)` is given by @@ -333,12 +335,12 @@ def sieve(X, bound): - ``X`` -- a scheme with ambient space defined over projective space - - ``bound`` -- a positive integer bound + - ``bound`` -- positive integer bound OUTPUT: - - a list containing the projective rational points of ``X`` of height - up to ``bound``, sorted + A list containing the projective rational points of ``X`` of height + up to ``bound``, sorted EXAMPLES:: @@ -398,7 +400,7 @@ def sieve(X, bound): def sufficient_primes(x): r""" - Returns a list of primes whose product is > `x` + Return a list of primes whose product is > `x`. """ small_primes = [2,3] prod_primes = 6 diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py old mode 100644 new mode 100755 index c05588f4698..9f010391eec --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -80,47 +80,52 @@ # **************************************************************************** from itertools import product -from sage.arith.misc import gcd, binomial - -from sage.rings.finite_rings.finite_field_base import FiniteField -from sage.rings.integer import Integer -from sage.rings.integer_ring import ZZ -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.rational_field import QQ, RationalField -from sage.rings.fraction_field import FractionField -from sage.rings.number_field.order import Order +import sage.rings.abc +from sage.arith.misc import gcd, binomial from sage.categories.fields import Fields -from sage.categories.rings import Rings -from sage.categories.number_fields import NumberFields from sage.categories.homset import Hom from sage.categories.map import Map +from sage.categories.number_fields import NumberFields +from sage.categories.rings import Rings +from sage.combinat.integer_vector import IntegerVectors +from sage.combinat.permutation import Permutation +from sage.combinat.subset import Subsets from sage.misc.latex import latex +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.misc.persist import register_unpickle_override - +from sage.rings.finite_rings.finite_field_base import FiniteField +from sage.rings.fraction_field import FractionField +from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.rational_field import QQ, RationalField +from sage.schemes.generic.ambient_space import AmbientSpace from sage.structure.category_object import normalize_names from sage.structure.unique_representation import UniqueRepresentation -from sage.combinat.integer_vector import IntegerVectors -from sage.combinat.integer_vector_weighted import WeightedIntegerVectors -from sage.combinat.permutation import Permutation -from sage.combinat.tuple import Tuples -from sage.combinat.tuple import UnorderedTuples -from sage.combinat.subset import Subsets -from sage.matrix.constructor import matrix -from sage.modules.free_module_element import prepare -from sage.schemes.generic.ambient_space import AmbientSpace from sage.schemes.projective.projective_homset import (SchemeHomset_points_projective_ring, SchemeHomset_points_projective_field, SchemeHomset_polynomial_projective_space) -from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring, - SchemeMorphism_point_projective_field, - SchemeMorphism_point_projective_finite_field) from sage.schemes.projective.projective_morphism import (SchemeMorphism_polynomial_projective_space, SchemeMorphism_polynomial_projective_space_field, SchemeMorphism_polynomial_projective_space_finite_field) +from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring, + SchemeMorphism_point_projective_field, + SchemeMorphism_point_projective_finite_field) + +lazy_import('sage.combinat.integer_vector_weighted', 'WeightedIntegerVectors') +lazy_import('sage.combinat.tuple', ['Tuples', 'UnorderedTuples']) +lazy_import('sage.dynamics.arithmetic_dynamics.projective_ds', 'DynamicalSystem_projective') +lazy_import('sage.matrix.constructor', 'matrix') +lazy_import('sage.modules.free_module_element', 'prepare') +lazy_import('sage.schemes.generic.algebraic_scheme', 'AlgebraicScheme_subscheme') +lazy_import('sage.schemes.product_projective.space', + ['ProductProjectiveSpaces', 'ProductProjectiveSpaces_ring']) +lazy_import('sage.schemes.projective.projective_subscheme', + ['AlgebraicScheme_subscheme_projective', 'AlgebraicScheme_subscheme_projective_field']) # for better efficiency @@ -131,7 +136,7 @@ def is_ProjectiveSpace(x): r""" - Return True if ``x`` is a projective space. + Return ``True`` if ``x`` is a projective space. In other words, if ``x`` is an ambient space `\mathbb{P}^n_R`, where `R` is a ring and `n\geq 0` is an integer. @@ -243,7 +248,7 @@ def ProjectiveSpace(n, R=None, names=None): sage: P.gens() == R.gens() True """ - if (is_MPolynomialRing(n) or is_PolynomialRing(n)) and R is None: + if (isinstance(n, MPolynomialRing_base) or isinstance(n, PolynomialRing_general)) and R is None: if names is not None: # Check for the case that the user provided a variable name # That does not match what we wanted to use from R @@ -365,7 +370,7 @@ def ngens(self): def _check_satisfies_equations(self, v): """ Return ``True`` if ``v`` defines a point on the scheme; raise a - :class:`TypeError` otherwise. + :exc:`TypeError` otherwise. EXAMPLES:: @@ -446,19 +451,17 @@ def coordinate_ring(self): def _validate(self, polynomials): """ - If ``polynomials`` is a tuple of valid polynomial functions on self, - return ``polynomials``, otherwise raise TypeError. + If ``polynomials`` is a tuple of valid polynomial functions on + ``self``, return ``polynomials``, otherwise raise :exc:`TypeError`. Since this is a projective space, polynomials must be homogeneous. INPUT: - ``polynomials`` -- tuple of polynomials in the coordinate ring of - this space. - - OUTPUT: + this space - - tuple of polynomials in the coordinate ring of this space. + OUTPUT: tuple of polynomials in the coordinate ring of this space EXAMPLES:: @@ -493,9 +496,11 @@ def __pow__(self, m): """ Return the Cartesian power of this space. - INPUT: ``m`` -- integer. + INPUT: - OUTPUT: product of projective spaces. + - ``m`` -- integer + + OUTPUT: product of projective spaces EXAMPLES:: @@ -511,7 +516,6 @@ def __pow__(self, m): mm = int(m) if mm != m: raise ValueError("m must be an integer") - from sage.schemes.product_projective.space import ProductProjectiveSpaces return ProductProjectiveSpaces([self.dimension_relative()] * mm, self.base_ring()) def __mul__(self, right): @@ -520,9 +524,9 @@ def __mul__(self, right): INPUT: - - ``right`` -- a projective space, product of projective spaces, or subscheme. + - ``right`` -- a projective space, product of projective spaces, or subscheme - OUTPUT: a product of projective spaces or subscheme. + OUTPUT: a product of projective spaces or subscheme EXAMPLES:: @@ -562,11 +566,7 @@ def __mul__(self, right): if self.base_ring() != right.base_ring(): raise ValueError('Must have the same base ring') - from sage.schemes.product_projective.space import ProductProjectiveSpaces_ring - from sage.schemes.product_projective.space import ProductProjectiveSpaces - from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme - - if isinstance(right, (ProductProjectiveSpaces_ring)): + if isinstance(right, ProductProjectiveSpaces_ring): return ProductProjectiveSpaces([self] + right.components()) elif isinstance(right, ProjectiveSpace_ring): if self is right: @@ -590,15 +590,14 @@ def _latex_(self): EXAMPLES:: sage: print(latex(ProjectiveSpace(1, ZZ, 'x'))) - {\mathbf P}_{\Bold{Z}}^1 + {\mathbf P}_{\Bold{Z}}^{1} TESTS:: - sage: ProjectiveSpace(3, Zp(5), 'y')._latex_() # needs sage.rings.padics - '{\\mathbf P}_{\\Bold{Z}_{5}}^3' + sage: ProjectiveSpace(11, Zp(5), 'y')._latex_() # needs sage.rings.padics + '{\\mathbf P}_{\\Bold{Z}_{5}}^{11}' """ - return "{\\mathbf P}_{%s}^%s" % (latex(self.base_ring()), - self.dimension_relative()) + return "{\\mathbf P}_{%s}^{%s}" % (latex(self.base_ring()), self.dimension_relative()) def _linear_system_as_kernel(self, d, pt, m): """ @@ -608,12 +607,12 @@ def _linear_system_as_kernel(self, d, pt, m): INPUT: - - ``d`` -- a nonnegative integer. + - ``d`` -- nonnegative integer - - ``pt`` -- a point of ``self`` (possibly represented by a list with at \ - least one component equal to 1). + - ``pt`` -- a point of ``self`` (possibly represented by a list with at + least one component equal to 1) - - ``m`` -- a nonnegative integer. + - ``m`` -- nonnegative integer OUTPUT: @@ -687,7 +686,6 @@ def _linear_system_as_kernel(self, d, pt, m): Use this method as starting point to implement a class LinearSystem for linear systems of hypersurfaces. - """ if not isinstance(d, (int, Integer)): raise TypeError('the argument d=%s must be an integer' % d) @@ -786,7 +784,7 @@ def point(self, v, check=True): - ``check`` -- boolean (default: ``True``); whether to check the defining data for consistency - OUTPUT: A point of this projective space. + OUTPUT: a point of this projective space EXAMPLES:: @@ -902,11 +900,9 @@ def change_ring(self, R): INPUT: - - ``R`` -- commutative ring or morphism. + - ``R`` -- commutative ring or morphism - OUTPUT: - - - projective space over ``R``. + OUTPUT: projective space over ``R`` .. NOTE:: @@ -953,7 +949,7 @@ def subscheme(self, X): INPUT: - - ``X`` -- a list or tuple of equations. + - ``X`` -- list or tuple of equations EXAMPLES:: @@ -990,8 +986,6 @@ def subscheme(self, X): "_test_elements_eq_symmetric", "_test_elements_eq_transitive",\ "_test_elements_neq"]) """ - from sage.schemes.projective.projective_subscheme import (AlgebraicScheme_subscheme_projective, - AlgebraicScheme_subscheme_projective_field) R = self.base_ring() if R.is_field() and R.is_exact(): return AlgebraicScheme_subscheme_projective_field(self, X) @@ -1007,17 +1001,13 @@ def points_of_bounded_height(self, **kwds): This is an implementation of Algorithm 6 in [Krumm2016]_. - INPUT: - - kwds: + INPUT: keyword arguments: - ``bound`` -- a real number - ``precision`` -- (default: 53) a positive integer - OUTPUT: - - - an iterator of points of bounded height + OUTPUT: an iterator of points of bounded height EXAMPLES:: @@ -1175,7 +1165,7 @@ def points_of_bounded_height(self, **kwds): elif R in NumberFields(): # True for the rational field as well, so check RationalField first field_type = True - elif (R is ZZ) or (isinstance(R, Order) and R.is_integrally_closed()): # Ensure ring of integers / maximal order + elif R is ZZ or (isinstance(R, sage.rings.abc.Order) and R.is_integrally_closed()): # Ensure ring of integers / maximal order is_ring_of_ints = True else: raise NotImplementedError("self must be a projective space over a number field or a ring of integers") @@ -1230,22 +1220,20 @@ def points_of_bounded_height(self, **kwds): def affine_patch(self, i, AA=None): r""" - Return the `i^{th}` affine patch of this projective space. + Return the `i`-th affine patch of this projective space. This is an ambient affine space `\mathbb{A}^n_R,` where `R` is the base ring of ``self``, whose "projective embedding" - map is `1` in the `i^{th}` factor. + map is `1` in the `i`-th factor. INPUT: - - ``i`` -- integer between 0 and dimension of ``self``, inclusive. + - ``i`` -- integer between 0 and dimension of ``self``, inclusive - - ``AA`` -- (default: None) ambient affine space, this is constructed - if it is not given. - - OUTPUT: + - ``AA`` -- (default: ``None``) ambient affine space, this is constructed + if it is not given - - An ambient affine space with fixed projective_embedding map. + OUTPUT: an ambient affine space with fixed projective_embedding map EXAMPLES:: @@ -1301,11 +1289,11 @@ def affine_patch(self, i, AA=None): def _an_element_(self): r""" - Returns a (preferably typical) element of this space. + Return a (preferably typical) element of this space. This is used both for illustration and testing purposes. - OUTPUT: a point in this projective space. + OUTPUT: a point in this projective space EXAMPLES:: @@ -1329,11 +1317,11 @@ def Lattes_map(self, E, m): INPUT: - - ``E`` -- an elliptic curve. + - ``E`` -- an elliptic curve - - ``m`` -- an integer. + - ``m`` -- integer - OUTPUT: a dynamical system on this projective space. + OUTPUT: a dynamical system on this projective space EXAMPLES:: @@ -1364,7 +1352,6 @@ def Lattes_map(self, E, m): x, y = R.gens() phi = F[0].parent().hom([x], R) F = [phi(F[0]).homogenize(y), phi(F[1]).homogenize(y) * y] - from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective return DynamicalSystem_projective(F, domain=self) def cartesian_product(self, other): @@ -1374,11 +1361,9 @@ def cartesian_product(self, other): INPUT: - - ``other`` -- A projective space with the same base ring as this space. + - ``other`` -- a projective space with the same base ring as this space - OUTPUT: - - - A Cartesian product of projective spaces. + OUTPUT: a Cartesian product of projective spaces EXAMPLES:: @@ -1389,7 +1374,6 @@ def cartesian_product(self, other): sage: PP.gens() (x0, x1, y0, y1, y2) """ - from sage.schemes.product_projective.space import ProductProjectiveSpaces return ProductProjectiveSpaces([self, other]) def chebyshev_polynomial(self, n, kind='first', monic=False): @@ -1404,13 +1388,13 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): INPUT: - - ``n`` -- a non-negative integer. + - ``n`` -- nonnegative integer - - ``kind`` -- ``first`` or ``second`` specifying which kind of chebyshev the user would like - to generate. Defaults to ``first``. + - ``kind`` -- ``'first'`` (default) or ``'second'`` specifying which + kind of Chebyshev the user would like to generate - - ``monic`` -- ``True`` or ``False`` specifying if the polynomial defining the system - should be monic or not. Defaults to ``False``. + - ``monic`` -- boolean (default: ``False``) specifying if the + polynomial defining the system should be monic or not OUTPUT: :class:`DynamicalSystem_projective` @@ -1444,7 +1428,7 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): sage: P.chebyshev_polynomial(-4, 'second') Traceback (most recent call last): ... - ValueError: first parameter 'n' must be a non-negative integer + ValueError: first parameter 'n' must be a nonnegative integer :: @@ -1476,7 +1460,7 @@ def chebyshev_polynomial(self, n, kind='first', monic=False): raise TypeError("projective space must be of dimension 1") n = ZZ(n) if (n < 0): - raise ValueError("first parameter 'n' must be a non-negative integer") + raise ValueError("first parameter 'n' must be a nonnegative integer") # use the affine version and then homogenize. A = self.affine_patch(1) f = A.chebyshev_polynomial(n, kind) @@ -1491,18 +1475,18 @@ def veronese_embedding(self, d, CS=None, order='lex'): INPUT: - - ``d`` -- a positive integer. - - - ``CS`` -- a projective ambient space to embed into. If this projective space has dimension `N`, the - dimension of ``CS`` must be `\binom{N + d}{d} - 1`. This is constructed if not specified. Default: - ``None``. + - ``d`` -- positive integer - - ``order`` -- a monomial order to use to arrange the monomials defining the embedding. The monomials - will be arranged from greatest to least with respect to this order. Default: ``'lex'``. + - ``CS`` -- (default: ``None``) a projective ambient space to embed + into. If this projective space has dimension `N`, the dimension of + ``CS`` must be `\binom{N + d}{d} - 1`. This is constructed if not + specified. - OUTPUT: + - ``order`` -- string (default: ``'lex'``); a monomial order to use to + arrange the monomials defining the embedding. The monomials will be + arranged from greatest to least with respect to this order. - - a scheme morphism from this projective space to ``CS``. + OUTPUT: a scheme morphism from this projective space to ``CS`` EXAMPLES:: @@ -1556,7 +1540,6 @@ def veronese_embedding(self, d, CS=None, order='lex'): def point_transformation_matrix(self, points_source, points_target, normalize=True): r""" - Returns a unique element of PGL that transforms one set of points to another. Given a projective space of dimension n and a set of n+2 source points and a set of n+2 target @@ -1569,16 +1552,17 @@ def point_transformation_matrix(self, points_source, points_target, normalize=Tr INPUT: - - ``points_source`` -- points in source projective space. + - ``points_source`` -- points in source projective space - - ``points_target`` -- points in target projective space. + - ``points_target`` -- points in target projective space - - ``normalize`` -- (default: ``True``) If the returned matrix should be normalized. - Only works over exact rings. If the base ring is a field, the matrix is normalized so - that the last nonzero entry in the last row is 1. If the base ring is a ring, then - the matrix is normalized so that the entries are elements of the base ring. + - ``normalize`` -- boolean (default: ``True``); if the returned matrix + should be normalized. Only works over exact rings. If the base ring + is a field, the matrix is normalized so that the last nonzero entry + in the last row is 1. If the base ring is a ring, then the matrix is + normalized so that the entries are elements of the base ring. - OUTPUT: Transformation matrix - element of PGL. + OUTPUT: transformation matrix - element of PGL ALGORITHM: @@ -1794,7 +1778,7 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): - ``plane_1``, ``plane_2`` -- hyperplanes of this projective space - OUTPUT: An element of PGL + OUTPUT: an element of PGL EXAMPLES:: @@ -1898,7 +1882,6 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): ... ValueError: plane_1 must be defined by a single degree 1 equation """ - from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective if not isinstance(plane_1, AlgebraicScheme_subscheme_projective): raise TypeError('plane_1 must be a subscheme') if not isinstance(plane_2, AlgebraicScheme_subscheme_projective): @@ -1935,7 +1918,7 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): source_points.append(self(L)) else: nonzero_places.append(i) - # next we add a point for each variable with non-zero coefficient, except the last + # next we add a point for each variable with nonzero coefficient, except the last # giving us a total of (N+1) - J - 1 = N - J points added in this loop # resulting in exactly J + (N-J) = N points on the plane for i in range(len(nonzero_places)-1): @@ -1974,15 +1957,13 @@ def is_linearly_independent(self, points, n=None): INPUT: - - ``points`` -- a list of points in this projective space. + - ``points`` -- list of points in this projective space - - ``n`` -- (Optional) A positive integer less than or equal to the length + - ``n`` -- (optional) positive integer less than or equal to the length of ``points``. Specifies the size of the subsets to check for linear independence. - OUTPUT: - - - ``True`` if ``points`` is linearly independent, ``False`` otherwise. + OUTPUT: ``True`` if ``points`` is linearly independent, ``False`` otherwise EXAMPLES:: @@ -2036,7 +2017,7 @@ def is_linearly_independent(self, points, n=None): sage: P.is_linearly_independent(points, 5) Traceback (most recent call last): ... - ValueError: n must be a non negative integer not greater than the length of points + ValueError: n must be a nonnegative integer not greater than the length of points """ if not isinstance(points, list): raise TypeError("points must be a list") @@ -2049,7 +2030,7 @@ def is_linearly_independent(self, points, n=None): return M.rank() == len(points) n = Integer(n) if n < 1 or n > len(points): - raise ValueError('n must be a non negative integer not greater than the length of points') + raise ValueError('n must be a nonnegative integer not greater than the length of points') all_subsets = Subsets(range(len(points)), n) linearly_independent = True for subset in all_subsets: @@ -2111,7 +2092,7 @@ def _morphism(self, *args, **kwds): def subscheme_from_Chow_form(self, Ch, dim): r""" - Returns the subscheme defined by the Chow equations associated to the Chow form ``Ch``. + Return the subscheme defined by the Chow equations associated to the Chow form ``Ch``. These equations define the subscheme set-theoretically, but only for smooth subschemes and hypersurfaces do they define the subscheme as a scheme. @@ -2126,11 +2107,11 @@ def subscheme_from_Chow_form(self, Ch, dim): INPUT: - - ``Ch`` -- a homogeneous polynomial. + - ``Ch`` -- a homogeneous polynomial - - ``dim`` -- the dimension of the associated scheme. + - ``dim`` -- the dimension of the associated scheme - OUTPUT: a projective subscheme. + OUTPUT: a projective subscheme EXAMPLES:: @@ -2261,7 +2242,6 @@ def line_through(self, p, q): Traceback (most recent call last): ... ValueError: not distinct points - """ if p == q: raise ValueError("not distinct points") @@ -2385,9 +2365,7 @@ def rational_points_dictionary(self): r""" Return dictionary of points. - OUTPUT: - - - dictionary + OUTPUT: dictionary EXAMPLES:: @@ -2435,7 +2413,7 @@ def rational_points_dictionary(self): class ProjectiveSpace_rational_field(ProjectiveSpace_field): def rational_points(self, bound=0): r""" - Returns the projective points `(x_0:\cdots:x_n)` over + Return the projective points `(x_0:\cdots:x_n)` over `\QQ` with `|x_i| \leq` bound. ALGORITHM: @@ -2451,7 +2429,7 @@ def rational_points(self, bound=0): INPUT: - - ``bound`` -- integer. + - ``bound`` -- integer EXAMPLES:: diff --git a/src/sage/schemes/projective/projective_subscheme.py b/src/sage/schemes/projective/projective_subscheme.py old mode 100644 new mode 100755 index 6135a62b1cb..a0c571de25b --- a/src/sage/schemes/projective/projective_subscheme.py +++ b/src/sage/schemes/projective/projective_subscheme.py @@ -22,19 +22,19 @@ # **************************************************************************** from sage.arith.misc import binomial - from sage.categories.fields import Fields from sage.categories.homset import Hom - -from sage.matrix.constructor import matrix - +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField - from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme from sage.schemes.projective.projective_morphism import SchemeMorphism_polynomial_projective_subscheme_field +lazy_import('sage.dynamics.arithmetic_dynamics.generic_ds', 'DynamicalSystem') +lazy_import('sage.matrix.constructor', 'matrix') +lazy_import('sage.schemes.elliptic_curves.ell_generic', 'EllipticCurve_generic', as_='EllipticCurve') + class AlgebraicScheme_subscheme_projective(AlgebraicScheme_subscheme): r""" @@ -51,10 +51,10 @@ class AlgebraicScheme_subscheme_projective(AlgebraicScheme_subscheme): INPUT: - ``A`` -- ambient :class:`projective space - `. + ` - ``polynomials`` -- single polynomial, ideal or iterable of - defining homogeneous polynomials. + defining homogeneous polynomials EXAMPLES:: @@ -81,7 +81,7 @@ def point(self, v, check=True): - ``check`` -- boolean (default: ``True``); whether to check the defining data for consistency - OUTPUT: A point of the subscheme. + OUTPUT: a point of the subscheme EXAMPLES:: @@ -135,9 +135,7 @@ def _morphism(self, *args, **kwds): - same as for :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space`. - OUTPUT: - - - :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space`. + OUTPUT: :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space` TESTS:: @@ -161,9 +159,7 @@ def dimension(self): """ Return the dimension of the projective algebraic subscheme. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -183,8 +179,8 @@ def dimension(self): Something less obvious:: sage: P3. = ProjectiveSpace(4, QQ) - sage: X = P3.subscheme([x^2, x^2*y^2 + z^2*t^2, z^2 - w^2, 10*x^2 + w^2 - z^2]) - sage: X + sage: X = P3.subscheme([x^2, x^2*y^2 + z^2*t^2, + ....: z^2 - w^2, 10*x^2 + w^2 - z^2]); X Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: x^2, x^2*y^2 + z^2*t^2, @@ -201,17 +197,17 @@ def dimension(self): def affine_patch(self, i, AA=None): r""" - Return the `i^{th}` affine patch of this projective scheme. + Return the `i`-th affine patch of this projective scheme. - This is the intersection with this `i^{th}` affine patch of + This is the intersection with this `i`-th affine patch of its ambient space. INPUT: - - ``i`` -- integer between 0 and dimension of ``self``, inclusive. + - ``i`` -- integer between 0 and dimension of ``self``, inclusive - ``AA`` -- (default: ``None``) ambient affine space, this - is constructed if it is not given. + is constructed if it is not given OUTPUT: @@ -293,11 +289,9 @@ def _best_affine_patch(self, point): INPUT: - - ``point`` -- a point of the algebraic subscheme. + - ``point`` -- a point of the algebraic subscheme - OUTPUT: - - Integer. The index of the patch. See :meth:`affine_patch`. + OUTPUT: integer. The index of the patch. See :meth:`affine_patch` EXAMPLES:: @@ -337,7 +331,7 @@ def neighborhood(self, point): INPUT: - - ``point`` -- a point of the projective subscheme. + - ``point`` -- a point of the projective subscheme OUTPUT: @@ -400,12 +394,12 @@ def is_smooth(self, point=None) -> bool: INPUT: - - ``point`` -- A point or ``None`` (default). The point to - test smoothness at. + - ``point`` -- a point or ``None`` (default); the point to + test smoothness at OUTPUT: - Boolean. If no point was specified, returns whether the + boolean; if no point was specified, returns whether the algebraic subscheme is smooth everywhere. Otherwise, smoothness at the specified point is tested. @@ -461,11 +455,9 @@ def orbit(self, f, N) -> list: - ``f`` -- a :class:`DynamicalSystem_projective` with ``self`` in ``f.domain()`` - - ``N`` -- a non-negative integer or list or tuple of two non-negative integers + - ``N`` -- nonnegative integer or list or tuple of two nonnegative integers - OUTPUT: - - - a list of projective subschemes + OUTPUT: list of projective subschemes EXAMPLES:: @@ -507,9 +499,8 @@ def orbit(self, f, N) -> list: sage: X.orbit(f, [-1,2]) # needs sage.schemes Traceback (most recent call last): ... - TypeError: orbit bounds must be non-negative + TypeError: orbit bounds must be nonnegative """ - from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem if not isinstance(f, DynamicalSystem): raise TypeError("map must be a dynamical system for iteration") if not isinstance(N, (list, tuple)): @@ -517,7 +508,7 @@ def orbit(self, f, N) -> list: N[0] = ZZ(N[0]) N[1] = ZZ(N[1]) if N[0] < 0 or N[1] < 0: - raise TypeError("orbit bounds must be non-negative") + raise TypeError("orbit bounds must be nonnegative") if N[0] > N[1]: return [] @@ -533,13 +524,13 @@ def orbit(self, f, N) -> list: def nth_iterate(self, f, n): r""" - The nth forward image of this scheme by the map ``f``. + The `n`-th forward image of this scheme by the map ``f``. INPUT: - ``f`` -- a :class:`DynamicalSystem_projective` with ``self`` in ``f.domain()`` - - ``n`` -- a positive integer. + - ``n`` -- positive integer OUTPUT: @@ -607,11 +598,9 @@ def _forward_image(self, f, check=True): - ``f`` -- a map whose domain contains ``self`` - - ``check`` -- Boolean, if `False` no input checking is done + - ``check`` -- boolean, if ``False`` no input checking is done - OUTPUT: - - - a subscheme in the codomain of ``f``. + OUTPUT: a subscheme in the codomain of ``f`` EXAMPLES:: @@ -753,11 +742,12 @@ def _forward_image(self, f, check=True): ... TypeError: subscheme must be in ambient space of domain of map """ - dom = f.domain() - codom = f.codomain() if check: if not f.is_morphism(): raise TypeError("map must be a morphism") + dom = f.domain() + codom = f.codomain() + if check: if self.ambient_space() != dom: raise TypeError("subscheme must be in ambient space of domain of map") CR_dom = dom.coordinate_ring() @@ -793,13 +783,11 @@ def preimage(self, f, k=1, check=True): - ``f`` -- a map whose codomain contains this scheme - - ``k`` -- a positive integer + - ``k`` -- positive integer - - ``check`` -- Boolean, if ``False`` no input checking is done + - ``check`` -- boolean; if ``False`` no input checking is done - OUTPUT: - - a subscheme in the domain of ``f`` + OUTPUT: a subscheme in the domain of ``f`` EXAMPLES:: @@ -907,13 +895,11 @@ def dual(self): INPUT: - - ``X`` -- A subscheme of projective space. At present, ``X`` is + - ``X`` -- a subscheme of projective space. At present, ``X`` is required to be an irreducible and reduced hypersurface defined over `\QQ` or a finite field. - OUTPUT: - - - The dual of ``X`` as a subscheme of the dual projective space. + OUTPUT: the dual of ``X`` as a subscheme of the dual projective space EXAMPLES: @@ -1023,7 +1009,7 @@ def degree(self): If `P(t) = a_{m}t^m + \ldots + a_{0}` is the Hilbert polynomial of this subscheme, then the degree is `a_{m} m!`. - OUTPUT: Integer. + OUTPUT: integer EXAMPLES:: @@ -1055,11 +1041,11 @@ def intersection_multiplicity(self, X, P): INPUT: - - ``X`` -- subscheme in the same ambient space as this subscheme. + - ``X`` -- subscheme in the same ambient space as this subscheme - - ``P`` -- a point in the intersection of this subscheme with ``X``. + - ``P`` -- a point in the intersection of this subscheme with ``X`` - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -1125,11 +1111,9 @@ def multiplicity(self, P): INPUT: - - ``P`` -- a point on this subscheme. - - OUTPUT: + - ``P`` -- a point on this subscheme - An integer. + OUTPUT: integer EXAMPLES:: @@ -1185,18 +1169,19 @@ def veronese_embedding(self, d, CS=None, order='lex'): INPUT: - - ``d`` -- a positive integer. - - - ``CS`` -- a projective ambient space to embed into. If the projective ambient space of this subscheme - is of dimension `N`, the dimension of ``CS`` must be `\binom{N + d}{d} - 1`. This is constructed if - not specified. Default: ``None``. + - ``d`` -- positive integer - - ``order`` -- a monomial order to use to arrange the monomials defining the embedding. The monomials - will be arranged from greatest to least with respect to this order. Default: ``'lex'``. + - ``CS`` -- (default: ``None``) a projective ambient space to embed + into. If the projective ambient space of this subscheme is of + dimension `N`, the dimension of ``CS`` must be + `\binom{N + d}{d} - 1`. This is constructed if not specified. - OUTPUT: + - ``order`` -- string (default: ``'lex'``); a monomial order to use to + arrange the monomials defining the embedding. The monomials will be + arranged from greatest to least with respect to this order. - - a scheme morphism from this subscheme to its image by the degree ``d`` Veronese embedding. + OUTPUT: a scheme morphism from this subscheme to its image by the + degree ``d`` Veronese embedding EXAMPLES:: @@ -1257,9 +1242,7 @@ def _morphism(self, *args, **kwds): - same as for :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space`. - OUTPUT: - - - :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space`. + OUTPUT: :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space` TESTS:: @@ -1302,7 +1285,7 @@ def Chow_form(self): writing `R` as a polynomial in Plucker coordinates (i.e. bracket polynomials). [DS1994]_. - OUTPUT: a homogeneous polynomial. + OUTPUT: a homogeneous polynomial EXAMPLES:: @@ -1422,11 +1405,9 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default ``RealField`` precision). - - OUTPUT: + default ``RealField`` precision) - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -1442,7 +1423,7 @@ def global_height(self, prec=None): sage: P. = ProjectiveSpace(QQ, 2) sage: X = P.subscheme([z^2 - 101*y^2 - 3*x*z]) - sage: X.global_height() # long time # needs sage.libs.singular + sage: X.global_height() # long time # needs sage.libs.singular 4.61512051684126 """ return self.Chow_form().global_height(prec) @@ -1453,14 +1434,12 @@ def local_height(self, v, prec=None): INPUT: - - ``v`` -- a prime or prime ideal of the base ring. + - ``v`` -- a prime or prime ideal of the base ring - ``prec`` -- desired floating point precision (default: - default ``RealField`` precision). + default ``RealField`` precision) - OUTPUT: - - - a real number. + OUTPUT: a real number EXAMPLES:: @@ -1488,14 +1467,12 @@ def local_height_arch(self, i, prec=None): INPUT: - - ``i`` -- an integer. + - ``i`` -- integer - ``prec`` -- desired floating point precision (default: - default ``RealField`` precision). - - OUTPUT: + default ``RealField`` precision) - - a real number. + OUTPUT: a real number EXAMPLES:: diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py old mode 100644 new mode 100755 index b50cc038f47..ff14a7a7b10 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -116,7 +116,6 @@ from sage.arith.functions import lcm from sage.arith.misc import GCD, algdep from sage.ext.fast_callable import fast_callable -from sage.functions.log import lambert_w from sage.graphs.graph import Graph from sage.groups.matrix_gps.finitely_generated import MatrixGroup from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -157,7 +156,7 @@ def voronoi_ghost(cpoints, n=6, CC=CDF): INPUT: - - ``cpoints`` -- a list of complex numbers + - ``cpoints`` -- list of complex numbers OUTPUT: @@ -201,14 +200,12 @@ def bisect(L, t): INPUT: - - ``L`` -- A list of tuples such that the first term of each tuple is a real - number between 0 and 1. These real numbers must be increasing. + - ``L`` -- list of tuples such that the first term of each tuple is a real + number between 0 and 1. These real numbers must be increasing - - ``t`` -- A real number between `t_0` and `t_n`. + - ``t`` -- real number between `t_0` and `t_n` - OUTPUT: - - An integer i, giving the position in L where t would be in + OUTPUT: integer i, giving the position in L where t would be in EXAMPLES: @@ -253,11 +250,11 @@ def bisect(L, t): def numerical_inverse(C): """ - Compute numerical inverse of a matrix via LU decomposition + Compute numerical inverse of a matrix via LU decomposition. INPUT: - - ``C`` -- A real or complex invertible square matrix + - ``C`` -- a real or complex invertible square matrix EXAMPLES:: @@ -305,7 +302,7 @@ class ConvergenceError(ValueError): def differential_basis_baker(f): r""" - Compute a differential basis for a curve that is nonsingular outside (1:0:0),(0:1:0),(0:0:1) + Compute a differential basis for a curve that is nonsingular outside (1:0:0),(0:1:0),(0:0:1). Baker's theorem tells us that if a curve has its singularities at the coordinate vertices and meets some further easily tested genericity criteria, @@ -322,7 +319,7 @@ def differential_basis_baker(f): INPUT: - - `f` -- a bivariate polynomial + - ``f`` -- a bivariate polynomial EXAMPLES:: @@ -344,7 +341,6 @@ def differential_basis_baker(f): sage: f = y^12 - x*(x - 1)^7 sage: differential_basis_baker(f) is None True - """ k = f.base_ring() R = PolynomialRing(k, 3, "x,y,z") @@ -362,7 +358,7 @@ def differential_basis_baker(f): return None from sage.geometry.polyhedron.constructor import Polyhedron - D = {(k[0], k[1]): v for k, v in f.dict().items()} + D = {(k[0], k[1]): v for k, v in f.monomial_coefficients().items()} P = Polyhedron(D) kT = k["t"] # here we check the additional genericity conditions: that the polynomials @@ -424,9 +420,7 @@ def reparameterize_differential_minpoly(minpoly, z0): - ``z0`` -- complex number or infinity; the point about which to reparameterize - OUTPUT: - - A polynomial in two variables giving the reparameterize minimal polynomial. + OUTPUT: a polynomial in two variables giving the reparameterize minimal polynomial EXAMPLES: @@ -495,11 +489,11 @@ class RiemannSurface: - ``prec`` -- the desired precision of computations on the surface in bits (default: 53) - - ``certification`` -- a boolean (default: ``True``) value indicating + - ``certification`` -- boolean (default: ``True``); value indicating whether homotopy continuation is certified or not. Uncertified homotopy continuation can be faster. - - ``differentials`` -- (default: ``None``). If specified, provides a list + - ``differentials`` -- (default: ``None``) if specified, provides a list of polynomials `h` such that `h/(df/dw) dz` is a regular differential on the Riemann surface. This is taken as a basis of the regular differentials, so the genus is assumed to be equal @@ -776,7 +770,7 @@ def w_values(self, z0): INPUT: - - ``z0`` -- (complex) a point in the complex z-plane. + - ``z0`` -- complex number; a point in the complex z-plane OUTPUT: @@ -864,9 +858,7 @@ def downstairs_graph(self): The result of this routine can be useful to interpret the labelling of the vertices. See also :meth:`upstairs_graph`. - OUTPUT: - - The Voronoi decomposition as a graph, with appropriate planar embedding. + OUTPUT: the Voronoi decomposition as a graph, with appropriate planar embedding EXAMPLES:: @@ -926,17 +918,15 @@ def _compute_delta(self, z1, epsilon, wvalues=None): INPUT: - - ``z1`` -- a complex number in the z-plane + - ``z1`` -- complex number in the z-plane - - ``epsilon`` -- a real number, which is the minimum distance between + - ``epsilon`` -- real number which is the minimum distance between the w-values above ``z1`` - - ``wvalues`` -- a list (default: ``None``). If specified, saves - recomputation. + - ``wvalues`` -- list (default: ``None``); if specified, saves + recomputation - OUTPUT: - - A real number, which is a step size for moving along a path. + OUTPUT: a real number, which is a step size for moving along a path EXAMPLES: @@ -1019,8 +1009,8 @@ def homotopy_continuation(self, edge): INPUT: - - ``edge`` -- a tuple ``(z_start, z_end)`` indicating the straight line - over which to perform the homotopy continutation + - ``edge`` -- tuple ``(z_start, z_end)`` indicating the straight line + over which to perform the homotopy continuation OUTPUT: @@ -1102,10 +1092,10 @@ def _determine_new_w(self, z0, oldw, epsilon): INPUT: - - ``z0`` -- a complex number + - ``z0`` -- complex number - - ``oldw`` -- a list of w-values which are presumed to be guesses of - the w-values above ``z0``. + - ``oldw`` -- list of w-values which are presumed to be guesses of + the w-values above ``z0`` - ``epsilon`` -- the minimum distance between the points of ``oldw`` divided by 3 @@ -1204,12 +1194,12 @@ def _newton_iteration(self, z0, oldw, epsilon): INPUT: - - ``z0`` -- a complex number. + - ``z0`` -- complex number - ``oldw`` -- a w-value which is presumed to be a guess of one of - the w-values above ``z0``. + the w-values above ``z0`` - - ``epsilon`` -- the minimum distance between the w-values divided by 3. + - ``epsilon`` -- the minimum distance between the w-values divided by 3 OUTPUT: @@ -1684,7 +1674,7 @@ def direction(center, neighbour): # Range over the size of the Gram matrix. for j in range(cn): # Forms the acycles and bcycles. If the entry in the - # transformation matrix is non-zero, it adds the coefficient at + # transformation matrix is nonzero, it adds the coefficient at # that entry, and the corresponding cycle. (also, forms it # into a loop) if P[i][j] != 0: @@ -1793,18 +1783,16 @@ def simple_vector_line_integral(self, upstairs_edge, differentials): INPUT: - - ``upstairs_edge`` -- tuple. Either a pair of integer tuples + - ``upstairs_edge`` -- tuple; either a pair of integer tuples corresponding to an edge of the upstairs graph, or a tuple ``((z_start, sb), (z_end, ))`` as in the input of - ``make_zw_interpolator``. + ``make_zw_interpolator`` - - ``differentials`` -- a list of polynomials; a polynomial `g` + - ``differentials`` -- list of polynomials; a polynomial `g` represents the differential `g(z,w)/(df/dw) dz` where `f(z,w)=0` is - the equation defining the Riemann surface. - - OUTPUT: + the equation defining the Riemann surface - A complex number, the value of the line integral. + OUTPUT: a complex number, the value of the line integral EXAMPLES:: @@ -1856,7 +1844,7 @@ def cohomology_basis(self, option=1): INPUT: - - ``option`` -- Presently, this routine uses Singular's ``adjointIdeal`` + - ``option`` -- presently, this routine uses Singular's ``adjointIdeal`` and passes the ``option`` parameter on. Legal values are 1, 2, 3 ,4, where 1 is the default. See the Singular documentation for the meaning. The backend for this function may change, and support for @@ -1886,7 +1874,7 @@ def cohomology_basis(self, option=1): base = self.f.base_ring() # It's important we use a degree ordering; see below. R = self._R - k = PolynomialRing(base, names="Z,W,U", order="degrevlex") + k = PolynomialRing(base, names='Z,W,U', order='degrevlex') dehom = k.Hom(R)([R.gen(0), R.gen(1), R.one()]) fnew = self.f(k.gen(0) / k.gen(2), k.gen(1) / k.gen(2)).numerator() @@ -1943,19 +1931,19 @@ def _bounding_data(self, differentials, exact=False): notation ``RBzg = PolynomialRing(self._R, ['z','g'])`` and ``CCzg = PolynomialRing(self._CC, ['z','g'])``, we have that: - - ``Rzg`` is either ``RBzg`` or ``CCzg`` depending on the value of - ``exact``, - - ``g`` is the full rational function in ``self._R.fraction_field()`` - giving the differential, - - ``dgdz`` is the derivative of ``g`` with respect to ``self._R.gen(0)``, - written in terms of ``self._R.gen(0)`` and ``g``, hence laying in - ``RBzg``, - - ``F`` is the minimal polynomial of ``g`` over ``self._R.gen(0)``, - laying in the polynomial ring ``Rzg``, - - ``a0_info`` is a tuple ``(lc, roots)`` where ``lc`` and ``roots`` are - the leading coefficient and roots of the polynomial in ``CCzg.gen(0)`` - that is the coefficient of the term of ``F`` of highest degree in - ``CCzg.gen(1)``. + - ``Rzg`` is either ``RBzg`` or ``CCzg`` depending on the value of + ``exact``, + - ``g`` is the full rational function in ``self._R.fraction_field()`` + giving the differential, + - ``dgdz`` is the derivative of ``g`` with respect to ``self._R.gen(0)``, + written in terms of ``self._R.gen(0)`` and ``g``, hence laying in + ``RBzg``, + - ``F`` is the minimal polynomial of ``g`` over ``self._R.gen(0)``, + laying in the polynomial ring ``Rzg``, + - ``a0_info`` is a tuple ``(lc, roots)`` where ``lc`` and ``roots`` are + the leading coefficient and roots of the polynomial in ``CCzg.gen(0)`` + that is the coefficient of the term of ``F`` of highest degree in + ``CCzg.gen(1)``. EXAMPLES:: @@ -2057,22 +2045,20 @@ def rigorous_line_integral(self, upstairs_edge, differentials, bounding_data): INPUT: - - ``upstairs_edge`` -- tuple. Either a pair of integer tuples + - ``upstairs_edge`` -- tuple; either a pair of integer tuples corresponding to an edge of the upstairs graph, or a tuple ``((z_start, sb), (z_end, ))`` as in the input of - ``make_zw_interpolator``. + ``make_zw_interpolator`` - - ``differentials`` -- a list of polynomials; a polynomial `g` + - ``differentials`` -- list of polynomials; a polynomial `g` represents the differential `g(z,w)/(df/dw) dz` where `f(z,w)=0` is - the equation defining the Riemann surface. + the equation defining the Riemann surface - ``bounding_data`` -- tuple containing the data required for bounding the integrands. This should be in the form of the output from :meth:`_bounding_data`. - OUTPUT: - - A complex number, the value of the line integral. + OUTPUT: a complex number, the value of the line integral EXAMPLES:: @@ -2274,7 +2260,7 @@ def integrand(t): return output * z1_minus_z0 - def matrix_of_integral_values(self, differentials, integration_method="heuristic"): + def matrix_of_integral_values(self, differentials, integration_method='heuristic'): r""" Compute the path integrals of the given differentials along the homology basis. @@ -2286,9 +2272,9 @@ def matrix_of_integral_values(self, differentials, integration_method="heuristic INPUT: - - ``differentials`` -- a list of polynomials. + - ``differentials`` -- list of polynomials - - ``integration_method`` -- (default: ``'heuristic'``). String specifying + - ``integration_method`` -- (default: ``'heuristic'``) string specifying the integration method to use. The options are ``'heuristic'`` and ``'rigorous'``. @@ -2315,7 +2301,6 @@ def matrix_of_integral_values(self, differentials, integration_method="heuristic of the integrals along the edges are written to ``self._integral_dict``. This is as this data will be required when computing the Abel-Jacobi map, and so it is helpful to have is stored rather than recomputing. - """ cycles = self.homology_basis() @@ -2373,9 +2358,7 @@ def period_matrix(self): r""" Compute the period matrix of the surface. - OUTPUT: - - A matrix of complex values. + OUTPUT: a matrix of complex values EXAMPLES:: @@ -2400,8 +2383,8 @@ def period_matrix(self): sage: from sage.schemes.riemann_surfaces.riemann_surface import RiemannSurface sage: R. = QQ[] sage: f = y^2 - x^3 + 1 - sage: S = RiemannSurface(f, integration_method="rigorous") - sage: T = RiemannSurface(f, integration_method="heuristic") + sage: S = RiemannSurface(f, integration_method='rigorous') + sage: T = RiemannSurface(f, integration_method='heuristic') sage: RM_S = S.riemann_matrix() sage: RM_T = T.riemann_matrix() sage: (RM_S-RM_T).norm() < 1e-10 @@ -2414,9 +2397,7 @@ def riemann_matrix(self): r""" Compute the Riemann matrix. - OUTPUT: - - A matrix of complex values. + OUTPUT: a matrix of complex values EXAMPLES:: @@ -2476,7 +2457,7 @@ def path(t): T = self._L[e] P += [path(t[0]) for t in T] - return point2d(P, size=1) + point2d(self.branch_locus, color="red") + return point2d(P, size=1) + point2d(self.branch_locus, color='red') def plot_paths3d(self, thickness=0.01): r""" @@ -2526,7 +2507,7 @@ def path(t): for w in ws: P += point3d( [z.real_part(), z.imag_part(), w.imag_part()], - color="purple", + color='purple', size=20, ) return P @@ -2545,12 +2526,12 @@ def endomorphism_basis(self, b=None, r=None): INPUT: - - ``b`` -- integer (default provided). The equation coefficients are - scaled by `2^b` before rounding to integers. + - ``b`` -- integer (default provided); the equation coefficients are + scaled by `2^b` before rounding to integers - - ``r`` -- integer (default: ``b/4``). Solutions that have all + - ``r`` -- integer (default: ``b/4``); solutions that have all coefficients smaller than `2^r` in absolute value are reported as - actual solutions. + actual solutions OUTPUT: @@ -2569,7 +2550,6 @@ def endomorphism_basis(self, b=None, r=None): ] sage: sorted([b.minpoly().disc() for b in B]) [-3, 1] - """ M = self.riemann_matrix() return integer_matrix_relations(M, M, b, r) @@ -2590,12 +2570,12 @@ def homomorphism_basis(self, other, b=None, r=None): INPUT: - - ``b`` -- integer (default provided). The equation coefficients are - scaled by `2^b` before rounding to integers. + - ``b`` -- integer (default provided); the equation coefficients are + scaled by `2^b` before rounding to integers - - ``r`` -- integer (default: ``b/4``). Solutions that have all + - ``r`` -- integer (default: ``b/4``); solutions that have all coefficients smaller than `2^r` in absolute value are reported as - actual solutions. + actual solutions OUTPUT: @@ -2629,15 +2609,13 @@ def tangent_representation_numerical(self, Rs, other=None): INPUT: - - ``Rs`` -- a set of matrices on homology to be converted to their - tangent representations. - - - ``other`` (default: ``self``) -- the codomain, another Riemann - surface. + - ``Rs`` -- set of matrices on homology to be converted to their + tangent representations - OUTPUT: + - ``other`` -- (default: ``self``) the codomain; another Riemann + surface - The numerical tangent representations of the matrices in ``Rs``. + OUTPUT: the numerical tangent representations of the matrices in ``Rs`` EXAMPLES:: @@ -2681,19 +2659,17 @@ def tangent_representation_algebraic(self, Rs, other=None, epscomp=None): INPUT: - - ``Rs`` -- a set of matrices on homology to be converted to their - tangent representations. + - ``Rs`` -- set of matrices on homology to be converted to their + tangent representations - - ``other`` (default: ``self``) -- the codomain, another Riemann - surface. + - ``other`` -- (default: ``self``) the codomain; another Riemann + surface - ``epscomp`` -- real number (default: ``2^(-prec + 30)``). Used to determine whether a complex number is close enough to a root of a polynomial. - OUTPUT: - - The algebraic tangent representations of the matrices in ``Rs``. + OUTPUT: the algebraic tangent representations of the matrices in ``Rs`` EXAMPLES:: @@ -2751,11 +2727,9 @@ def rosati_involution(self, R): INPUT: - - ``R`` -- integral matrix. - - OUTPUT: + - ``R`` -- integral matrix - The result of applying the Rosati involution to ``R``. + OUTPUT: the result of applying the Rosati involution to ``R`` EXAMPLES:: @@ -2786,22 +2760,22 @@ def symplectic_isomorphisms(self, other=None, hom_basis=None, b=None, r=None): INPUT: - - ``other`` (default: ``self``) -- the codomain, another Riemann - surface. + - ``other`` -- (default: ``self``) the codomain; another Riemann + surface - - ``hom_basis`` (default: ``None``) -- a `\ZZ`-basis of the + - ``hom_basis`` -- (default: ``None``) a `\ZZ`-basis of the homomorphisms from ``self`` to ``other``, as obtained from :meth:`homomorphism_basis`. If you have already calculated this basis, it saves time to pass it via this keyword argument. Otherwise the method will calculate it. - - ``b`` -- integer (default provided): as for + - ``b`` -- integer (default provided); as for :meth:`homomorphism_basis`, and used in its invocation if - (re)calculating said basis. + (re)calculating said basis - - ``r`` -- integer (default: ``b/4``). as for + - ``r`` -- integer (default: ``b/4``); as for :meth:`homomorphism_basis`, and used in its invocation if - (re)calculating said basis. + (re)calculating said basis OUTPUT: @@ -2865,19 +2839,19 @@ def symplectic_automorphism_group(self, endo_basis=None, b=None, r=None): INPUT: - - ``endo_basis`` (default: ``None``) -- a `\ZZ`-basis of the + - ``endo_basis`` -- (default: ``None``) a `\ZZ`-basis of the endomorphisms of ``self``, as obtained from :meth:`endomorphism_basis`. If you have already calculated this basis, it saves time to pass it via this keyword argument. Otherwise the method will calculate it. - - ``b`` -- integer (default provided): as for + - ``b`` -- integer (default provided); as for :meth:`homomorphism_basis`, and used in its invocation if - (re)calculating said basis. + (re)calculating said basis - - ``r`` -- integer (default: ``b/4``). as for + - ``r`` -- integer (default: ``b/4``); as for :meth:`homomorphism_basis`, and used in its invocation if - (re)calculating said basis. + (re)calculating said basis OUTPUT: @@ -2939,17 +2913,17 @@ def _integrate_differentials_iteratively( along, where ``z_start`` may be infinite, in which case ``w_start`` must be an integer specifying the branch. - - ``cutoff_individually`` -- boolean (default: ``False``). Whether to truncate - the integrand uniformly or not. If ``None``, then no truncation is - applied. + - ``cutoff_individually`` -- boolean (default: ``False``); whether to + truncate the integrand uniformly or not. If ``None``, then no + truncation is applied - - ``raise_errors`` -- boolean (default: ``True``). By default the code uses - convergence errors to ensure any answers returned are accurate. This - can be turned off to return answers faster that are not necessarily - correct. + - ``raise_errors`` -- boolean (default: ``True``); by default the code + uses convergence errors to ensure any answers returned are accurate. + This can be turned off to return answers faster that are not + necessarily correct. - - ``prec`` -- integer (default: ``self._prec``). The precision to try - and achieve, defined as `2^{-\text{prec}+3}`. + - ``prec`` -- integer (default: ``self._prec``); the precision to try + and achieve, defined as `2^{-\text{prec}+3}` OUTPUT: @@ -3039,7 +3013,7 @@ def initialise(z, i): return newg # As multiple calls of the minimal polynomial and it's derivative will - # be required for the homotopy continuaiton, we create fast-callable + # be required for the homotopy continuation, we create fast-callable # versions of these. fc_mp_list = [fast_callable(mp, domain=self._CC) for mp in mp_list] fc_dmp_list = [ @@ -3050,7 +3024,7 @@ def initialise(z, i): prec = self._prec # tau here is playing the role of the desired error. tau = self._RR(2)**(-prec + 3) - one = self._RR(1) + one = self._RR.one() la = self._RR.pi() / 2 # Cutoffs are used to allow us to not have to integrate as close into @@ -3070,7 +3044,7 @@ def initialise(z, i): A = PolynomialRing(self._CC, "xyz") aes = [] for mp in mp_list: - d = mp.dict() + d = mp.monomial_coefficients() mp = sum( [ d[k] * CCzg.gen(0)**k[0] * CCzg.gen(1)**k[1] @@ -3108,6 +3082,8 @@ def initialise(z, i): else: n_steps = 15 + from sage.functions.log import lambert_w + V = VectorSpace(self._CC, self.genus) h = one Nh = (-lambert_w(-1, -tau / 2) / la).log().ceil() @@ -3284,7 +3260,7 @@ def _aj_based(self, P): we are using the convention that the `w` value over `\infty` is given by the limit as ``z`` tends to `\infty` of ``self.w_values(z)[branch]``. - OUTPUT: A vector of length ``self.genus``. + OUTPUT: a vector of length ``self.genus`` EXAMPLES: @@ -3311,7 +3287,6 @@ def _aj_based(self, P): sage: AJx2 = [2*z for z in AJ] sage: bool(S.reduce_over_period_lattice(AJx2).norm() < 1e-10) True - """ ##### fcd = self._fastcall_cohomology_basis @@ -3510,11 +3485,11 @@ def abel_jacobi(self, divisor, verbose=False): where ``v`` is the valuation of the divisor at point ``P``, ``P`` as per the input to :meth:`_aj_based`. - - ``verbose`` -- logical (default: ``False``). Whether to report the progress + - ``verbose`` -- logical (default: ``False``); whether to report the progress of the computation, in terms of how many elements of the list ``divisor`` - have been completed. + have been completed - OUTPUT: A vector of length ``self.genus``. + OUTPUT: a vector of length ``self.genus`` EXAMPLES: @@ -3547,7 +3522,7 @@ def abel_jacobi(self, divisor, verbose=False): return ans def reduce_over_period_lattice( - self, vector, method="ip", b=None, r=None, normalised=False + self, vector, method='ip', b=None, r=None, normalised=False ): r""" Reduce a vector over the period lattice. @@ -3563,20 +3538,20 @@ def reduce_over_period_lattice( INPUT: - ``vector`` -- vector. A vector of length ``self.genus`` to reduce over - the lattice. + the lattice - - ``method`` -- string (default: ``'ip'``). String specifying the method - to use to reduce the vector. THe options are ``'ip'`` and ``'svp'``. + - ``method`` -- string (default: ``'ip'``) specifying the method + to use to reduce the vector; the options are ``'ip'`` and ``'svp'`` - - ``b`` -- integer (default provided): as for + - ``b`` -- integer (default provided); as for :meth:`homomorphism_basis`, and used in its invocation if - (re)calculating said basis. + (re)calculating said basis - - ``r`` -- integer (default: ``b/4``). as for + - ``r`` -- integer (default: ``b/4``); as for :meth:`homomorphism_basis`, and used in its invocation if - (re)calculating said basis. + (re)calculating said basis - - ``normalised`` -- logical (default: ``False``). Whether to use the + - ``normalised`` -- logical (default: ``False``); whether to use the period matrix with the differentials normalised s.t. the `A`-matrix is the identity. @@ -3606,7 +3581,7 @@ def reduce_over_period_lattice( sage: for vector in S.period_matrix().columns(): ....: n1 = S.reduce_over_period_lattice(vector).norm() - ....: n2 = S.reduce_over_period_lattice(vector, method="svp").norm() + ....: n2 = S.reduce_over_period_lattice(vector, method='svp').norm() ....: print(bool(n2<=n1)) True True @@ -3681,7 +3656,7 @@ def curve(self): For others, the curve is constructed and cached, so that an identical curve is returned upon subsequent calls. - OUTPUT: Curve from which Riemann surface is obtained. + OUTPUT: curve from which Riemann surface is obtained EXAMPLES:: @@ -3946,11 +3921,11 @@ def integer_matrix_relations(M1, M2, b=None, r=None): - ``M2`` -- square complex valued matrix of same size as ``M1`` - - ``b`` -- integer (default provided). The equation coefficients are scaled - by `2^b` before rounding to integers. + - ``b`` -- integer (default provided); the equation coefficients are scaled + by `2^b` before rounding to integers - - ``r`` -- integer (default: ``b/4``). The vectors found by LLL that satisfy - the scaled equations to within `2^r` are reported as solutions. + - ``r`` -- integer (default: ``b/4``); the vectors found by LLL that satisfy + the scaled equations to within `2^r` are reported as solutions OUTPUT: @@ -4026,7 +4001,7 @@ class RiemannSurfaceSum(RiemannSurface): INPUT: - - L -- list of RiemannSurface objects + - ``L`` -- list of RiemannSurface objects EXAMPLES:: diff --git a/src/sage/schemes/toric/chow_group.py b/src/sage/schemes/toric/chow_group.py old mode 100644 new mode 100755 index d11d70e135b..3087ed5b301 --- a/src/sage/schemes/toric/chow_group.py +++ b/src/sage/schemes/toric/chow_group.py @@ -132,7 +132,7 @@ import sage.geometry.abc from sage.schemes.toric.variety import ToricVariety_field -from sage.schemes.toric.divisor import is_ToricDivisor +from sage.schemes.toric.divisor import ToricDivisor_generic class ChowCycle(FGP_Element): @@ -163,12 +163,12 @@ def __init__(self, parent, v, check=True): INPUT: - - ``parent`` -- a :class:`ChowGroup_class`. + - ``parent`` -- a :class:`ChowGroup_class` - ``v`` -- a vector in the covering module, that is, with one - entry for each cone of the toric variety. + entry for each cone of the toric variety - - ``check`` -- boolean (default: ``True``). Verify that ``v`` + - ``check`` -- boolean (default: ``True``); verify that ``v`` is in the covering module. Set to ``False`` if you want to initialize from a coordinate vector. @@ -186,9 +186,7 @@ def _repr_(self) -> str: r""" Return a string representation of the Chow cycle. - OUTPUT: - - See the module-level documentation for details. + OUTPUT: see the module-level documentation for details EXAMPLES:: @@ -237,7 +235,7 @@ def degree(self) -> int: Integer. The complex dimension of the subvariety representing the Chow cycle. - This raises a :class:`ValueError` if the Chow cycle is a + This raises a :exc:`ValueError` if the Chow cycle is a sum of mixed degree cycles. EXAMPLES:: @@ -266,7 +264,7 @@ def project_to_degree(self, degree): INPUT: - - ``degree`` -- integer. The degree to project to. + - ``degree`` -- integer; the degree to project to OUTPUT: @@ -356,7 +354,7 @@ def intersection_with_divisor(self, divisor): OUTPUT: A new :class:`ChowCycle`. If the divisor is not Cartier then - this method potentially raises a :class:`ValueError`, indicating + this method potentially raises a :exc:`ValueError`, indicating that the divisor cannot be made transversal to the Chow cycle. EXAMPLES:: @@ -408,7 +406,7 @@ def intersection_with_divisor(self, divisor): (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)] """ - assert is_ToricDivisor(divisor), f'{divisor} is not a toric divisor' + assert isinstance(divisor, ToricDivisor_generic), f'{divisor} is not a toric divisor' A = self.parent() # the Chow group X = A._variety # the toric variety @@ -473,7 +471,7 @@ def cohomology_class(self): If the toric variety is not simplicial, that is, has worse than orbifold singularities, there is no way to associate a cohomology class of the correct degree. In this case, - :meth:`cohomology_class` raises a :class:`ValueError`. + :meth:`cohomology_class` raises a :exc:`ValueError`. EXAMPLES:: @@ -534,12 +532,12 @@ def create_key_and_extra_args(self, toric_variety, base_ring=ZZ, check=True): INPUT: - - ``toric_variety`` -- a toric variety. + - ``toric_variety`` -- a toric variety - - ``base_ring`` -- either `\ZZ` (default) or `\QQ`. The - coefficient ring of the Chow group. + - ``base_ring`` -- either `\ZZ` (default) or `\QQ`; the + coefficient ring of the Chow group - - ``check`` -- boolean (default: ``True``). + - ``check`` -- boolean (default: ``True``) EXAMPLES:: @@ -564,11 +562,11 @@ def create_object(self, version, key, **extra_args): INPUT: - - ``version`` -- object version. Currently not used. + - ``version`` -- object version; currently not used - - ``key`` -- a key created by :meth:`create_key_and_extra_args`. + - ``key`` -- a key created by :meth:`create_key_and_extra_args` - - ``**extra_args`` -- Currently not used. + - ``**extra_args`` -- currently not used EXAMPLES:: @@ -610,7 +608,7 @@ def __init__(self, toric_variety, base_ring, check): Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches sage: isinstance(A, ChowGroup_class) True - sage: is_ChowCycle(A.an_element()) + sage: isinstance(A.an_element(), ChowCycle) True TESTS:: @@ -658,7 +656,7 @@ def scheme(self): r""" Return the underlying toric variety. - OUTPUT: A :class:`ToricVariety + OUTPUT: a :class:`ToricVariety `. EXAMPLES:: @@ -680,10 +678,10 @@ def _element_constructor_(self, x, check=True): - ``x`` -- a cone of the fan, a toric divisor, or a valid input for - :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class`. + :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class` - - ``check`` -- bool (default: ``True``). See - :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class`. + - ``check`` -- boolean (default: ``True``); see + :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class` EXAMPLES:: @@ -701,7 +699,7 @@ def _element_constructor_(self, x, check=True): if isinstance(x, sage.geometry.abc.ConvexRationalPolyhedralCone): cone = fan.embed(x) return self.element_class(self, self._cone_to_V(cone), False) - if is_ToricDivisor(x): + if isinstance(x, ToricDivisor_generic): v = sum(x.coefficient(i) * self._cone_to_V(onecone) for i, onecone in enumerate(fan(1))) return self.element_class(self, v, False) @@ -763,9 +761,7 @@ def __truediv__(self, other): r""" Return the quotient of the Chow group by a subgroup. - OUTPUT: - - Currently not implemented. + OUTPUT: currently not implemented EXAMPLES:: @@ -800,15 +796,13 @@ def _repr_(self) -> str: def _cone_to_V(self, cone): r""" - Convert a cone into the corresponding vector in ``self._V`` + Convert a cone into the corresponding vector in ``self._V``. INPUT: - - ``cone`` -- a :class:`sage.geometry.cone.ConvexRationalPolyhedralCone`. + - ``cone`` -- a :class:`sage.geometry.cone.ConvexRationalPolyhedralCone` - OUTPUT: - - The corresponding element of ``self.V()``. + OUTPUT: the corresponding element of ``self.V()`` EXAMPLES:: @@ -829,8 +823,8 @@ def degree(self, k=None): INPUT: - - ``k`` -- an integer or ``None`` (default). The degree of the - Chow group. + - ``k`` -- integer or ``None`` (default); the degree of the + Chow group OUTPUT: @@ -933,12 +927,12 @@ def coordinate_vector(self, chow_cycle, degree=None, reduce=True): INPUT: - - ``chow_cycle`` -- a :class:`ChowCycle`. + - ``chow_cycle`` -- a :class:`ChowCycle` - - ``degree`` -- None (default) or an integer. + - ``degree`` -- ``None`` (default) or integer - - ``reduce`` -- boolean (default: ``True``). Whether to reduce - modulo the invariants. + - ``reduce`` -- boolean (default: ``True``); whether to reduce + modulo the invariants OUTPUT: @@ -970,8 +964,8 @@ def gens(self, degree=None): INPUT: - - ``degree`` -- integer (optional). The degree of the Chow - group. + - ``degree`` -- integer (optional); the degree of the Chow + group OUTPUT: @@ -1067,9 +1061,9 @@ def __init__(self, A, d): INPUT: - - ``A`` -- A :class:`ChowGroup_class`. + - ``A`` -- a :class:`ChowGroup_class` - - ``d`` -- integer. The degree of the Chow group. + - ``d`` -- integer; the degree of the Chow group EXAMPLES:: @@ -1101,7 +1095,7 @@ def _repr_(self) -> str: """ Return a string representation. - OUTPUT: A string. + OUTPUT: string EXAMPLES:: @@ -1138,7 +1132,7 @@ def module(self): """ Return the submodule of the toric Chow group generated. - OUTPUT: A :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class`. + OUTPUT: a :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class` EXAMPLES:: @@ -1153,7 +1147,7 @@ def ngens(self) -> int: """ Return the number of generators. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -1170,9 +1164,9 @@ def gen(self, i): INPUT: - - ``i`` -- integer. The index of the generator to be returned. + - ``i`` -- integer; the index of the generator to be returned - OUTPUT: A Chow cycle. + OUTPUT: a Chow cycle EXAMPLES:: @@ -1187,7 +1181,7 @@ def gens(self): """ Return the generators of the Chow group of fixed degree. - OUTPUT: A tuple of Chow cycles of fixed degree generating + OUTPUT: a tuple of Chow cycles of fixed degree generating :meth:`module`. EXAMPLES:: @@ -1206,9 +1200,9 @@ def is_ChowGroup(x) -> bool: INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -1234,9 +1228,9 @@ def is_ChowCycle(x) -> bool: INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: ``True`` or ``False``. + OUTPUT: boolean EXAMPLES:: @@ -1244,10 +1238,18 @@ def is_ChowCycle(x) -> bool: sage: A = P2.Chow_group() sage: from sage.schemes.toric.chow_group import * sage: is_ChowCycle(A) + doctest:warning... + DeprecationWarning: The function is_ChowCycle is deprecated; + use 'isinstance(..., ChowCycle)' instead. + See https://github.com/sagemath/sage/issues/38277 for details. False sage: is_ChowCycle(A.an_element()) True sage: is_ChowCycle('Victoria') False """ + from sage.misc.superseded import deprecation + deprecation(38277, + "The function is_ChowCycle is deprecated; " + "use 'isinstance(..., ChowCycle)' instead.") return isinstance(x, ChowCycle) diff --git a/src/sage/schemes/toric/divisor.py b/src/sage/schemes/toric/divisor.py old mode 100644 new mode 100755 index ff0373b3bef..1da707e0cb6 --- a/src/sage/schemes/toric/divisor.py +++ b/src/sage/schemes/toric/divisor.py @@ -171,11 +171,11 @@ import sage.geometry.abc from sage.geometry.polyhedron.constructor import Polyhedron from sage.geometry.toric_lattice_element import ToricLatticeElement -from sage.topology.simplicial_complex import SimplicialComplex from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.misc.flatten import flatten from sage.misc.latex import latex +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.modules.free_module_element import vector from sage.modules.free_module import (FreeModule_ambient_field, @@ -189,6 +189,8 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.structure.element import Vector +lazy_import('sage.topology.simplicial_complex', 'SimplicialComplex') + def is_ToricDivisor(x): r""" @@ -196,7 +198,7 @@ def is_ToricDivisor(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: @@ -207,6 +209,10 @@ def is_ToricDivisor(x): sage: from sage.schemes.toric.divisor import is_ToricDivisor sage: is_ToricDivisor(1) + doctest:warning... + DeprecationWarning: The function is_ToricDivisor is deprecated; + use 'isinstance(..., ToricDivisor_generic)' instead. + See https://github.com/sagemath/sage/issues/38277 for details. False sage: P2 = toric_varieties.P2() sage: D = P2.divisor(0); D @@ -214,6 +220,10 @@ def is_ToricDivisor(x): sage: is_ToricDivisor(D) True """ + from sage.misc.superseded import deprecation + deprecation(38277, + "The function is_ToricDivisor is deprecated; " + "use 'isinstance(..., ToricDivisor_generic)' instead.") return isinstance(x, ToricDivisor_generic) @@ -225,7 +235,7 @@ def ToricDivisor(toric_variety, arg=None, ring=None, check=True, reduce=True): INPUT: - ``toric_variety`` -- a :class:`toric variety - `; + ` - ``arg`` -- one of the following description of the toric divisor to be constructed: @@ -244,11 +254,11 @@ def ToricDivisor(toric_variety, arg=None, ring=None, check=True, reduce=True): divisor group. If ``ring`` is not specified, a coefficient ring suitable for ``arg`` is derived. - - ``check`` -- bool (default: ``True``). Whether to coerce + - ``check`` -- boolean (default: ``True``); whether to coerce coefficients into base ring. Setting it to ``False`` can speed up construction. - - ``reduce`` -- reduce (default: ``True``). Whether to combine common + - ``reduce`` -- reduce (default: ``True``); whether to combine common terms. Setting it to ``False`` can speed up construction. .. WARNING:: @@ -258,7 +268,7 @@ def ToricDivisor(toric_variety, arg=None, ring=None, check=True, reduce=True): ``reduce=False`` it is your responsibility to pass valid input data ``arg``. - OUTPUT: A :class:`sage.schemes.toric.divisor.ToricDivisor_generic`. + OUTPUT: a :class:`sage.schemes.toric.divisor.ToricDivisor_generic` EXAMPLES:: @@ -378,15 +388,15 @@ class ToricDivisor_generic(Divisor_generic): INPUT: - - ``v`` -- a list of tuples (multiplicity, coordinate). + - ``v`` -- list of tuples (multiplicity, coordinate) - - ``parent`` -- :class:`ToricDivisorGroup`. The parent divisor group. + - ``parent`` -- :class:`ToricDivisorGroup`; the parent divisor group - - ``check`` -- boolean. Type-check the entries of ``v``, see - :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic`. + - ``check`` -- boolean; type-check the entries of ``v``, see + :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic` - - ``reduce`` -- boolean. Combine coefficients in ``v``, see - :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic`. + - ``reduce`` -- boolean; combine coefficients in ``v``, see + :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic` .. WARNING:: @@ -476,11 +486,9 @@ def coefficient(self, x): INPUT: - ``x`` -- one of the homogeneous coordinates, either given by - the variable or its index. - - OUTPUT: + the variable or its index - The coefficient of ``x``. + OUTPUT: the coefficient of ``x`` EXAMPLES:: @@ -515,9 +523,9 @@ def function_value(self, point): INPUT: - ``point`` -- either an integer, interpreted as the index of a ray of - `\Sigma`, or a point of the lattice `N`. + `\Sigma`, or a point of the lattice `N` - OUTPUT: An integer or a rational number. + OUTPUT: integer or a rational number EXAMPLES:: @@ -557,17 +565,15 @@ def m(self, cone): INPUT: - - ``cone`` -- A cone in the fan of the toric variety. - - OUTPUT: + - ``cone`` -- a cone in the fan of the toric variety - - If possible, a point of lattice `M`. + OUTPUT: if possible, a point of lattice `M` - If the dual vector cannot be chosen integral, a rational vector is returned. - If there is no such vector (i.e. ``self`` is not even a - `\QQ`-Cartier divisor), a :class:`ValueError` is raised. + `\QQ`-Cartier divisor), a :exc:`ValueError` is raised. EXAMPLES:: @@ -773,7 +779,7 @@ def move_away_from(self, cone): .. NOTE:: A divisor that is Weil but not Cartier might be impossible - to move away. In this case, a :class:`ValueError` is raised. + to move away. In this case, a :exc:`ValueError` is raised. EXAMPLES:: @@ -873,12 +879,12 @@ def divisor_class(self): def Chow_cycle(self, ring=ZZ): r""" - Returns the Chow homology class of the divisor. + Return the Chow homology class of the divisor. INPUT: - - ``ring`` -- Either ``ZZ`` (default) or ``QQ``. The base ring - of the Chow group. + - ``ring`` -- either ``ZZ`` (default) or ``QQ``; the base ring + of the Chow group OUTPUT: @@ -906,9 +912,7 @@ def is_ample(self): r""" Return whether a `\QQ`-Cartier divisor is ample. - OUTPUT: - - - ``True`` if the divisor is in the ample cone, ``False`` otherwise. + OUTPUT: ``True`` if the divisor is in the ample cone, ``False`` otherwise .. NOTE:: @@ -1049,9 +1053,7 @@ def polyhedron(self): Return the polyhedron `P_D\subset M` associated to a toric divisor `D`. - OUTPUT: - - `P_D` as an instance of :class:`~sage.geometry.polyhedron.base.Polyhedron_base`. + OUTPUT: `P_D` as an instance of :class:`~sage.geometry.polyhedron.base.Polyhedron_base` EXAMPLES:: @@ -1135,7 +1137,7 @@ def sections(self): the line bundle (or reflexive sheaf) associated to the divisor. - OUTPUT: A :class:`tuple` of points of lattice `M`. + OUTPUT: a :class:`tuple` of points of lattice `M` EXAMPLES:: @@ -1181,9 +1183,7 @@ def sections_monomials(self): The sections are described as monomials in the generalized homogeneous coordinates. - OUTPUT: - - - tuple of monomials in the coordinate ring of ``self``. + OUTPUT: tuple of monomials in the coordinate ring of ``self`` EXAMPLES:: @@ -1220,7 +1220,7 @@ def monomial(self, point): INPUT: - - ``point`` -- a point in ``self.variety().fan().dual_lattice()``. + - ``point`` -- a point in ``self.variety().fan().dual_lattice()`` OUTPUT: @@ -1260,8 +1260,8 @@ def Kodaira_map(self, names='z'): INPUT: - - ``names`` -- string (optional; default ``'z'``). The - variable names for the destination projective space. + - ``names`` -- string (default: ``'z'``); the + variable names for the destination projective space EXAMPLES:: @@ -1311,9 +1311,9 @@ def _sheaf_complex(self, m): INPUT: - - `m` -- a point in ``self.scheme().fan().dual_lattice()``. + - ``m`` -- a point in ``self.scheme().fan().dual_lattice()`` - OUTPUT: A :class:`simplicial complex `. + OUTPUT: a :class:`simplicial complex ` EXAMPLES:: @@ -1340,16 +1340,16 @@ def cone_is_negative(cone): # and non-trivial def _sheaf_cohomology(self, cplx): """ - Returns the sheaf cohomology as the shifted, reduced cohomology + Return the sheaf cohomology as the shifted, reduced cohomology of the complex. Helper for :meth:`cohomology`. INPUT: - - ``cplx`` -- simplicial complex. + - ``cplx`` -- simplicial complex - OUTPUT: An integer vector. + OUTPUT: integer vector EXAMPLES:: @@ -1447,11 +1447,11 @@ def cohomology(self, weight=None, deg=None, dim=False): INPUT: - - ``weight`` -- (optional) a point of the `M`-lattice. + - ``weight`` -- (optional) a point of the `M`-lattice - - ``deg`` -- (optional) the degree of the cohomology group. + - ``deg`` -- (optional) the degree of the cohomology group - - ``dim`` -- boolean. If ``False`` (default), the cohomology + - ``dim`` -- boolean; if ``False`` (default), the cohomology groups are returned as vector spaces. If ``True``, only the dimension of the vector space(s) is returned. @@ -1660,17 +1660,15 @@ def __init__(self, toric_variety, base_ring): - ``toric_variety`` -- a :class:`toric variety - ``; + `` - ``base_ring`` -- the coefficient ring of this divisor group, - usually `\ZZ` (default) or `\QQ`. + usually `\ZZ` (default) or `\QQ` Implementation note: :meth:`__classcall__` sets the default value for ``base_ring``. - OUTPUT: - - Divisor group of the toric variety. + OUTPUT: divisor group of the toric variety EXAMPLES:: @@ -1694,7 +1692,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: A string. + OUTPUT: string TESTS:: @@ -1708,9 +1706,7 @@ def _repr_(self): """ Return a string representation of the toric divisor group. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -1767,7 +1763,7 @@ def gen(self, i): INPUT: - - ``i`` -- integer. + - ``i`` -- integer OUTPUT: @@ -1785,15 +1781,15 @@ def gen(self, i): def _element_constructor_(self, x, check=True, reduce=True): r""" - Construct a :class:`ToricDivisor_generic` + Construct a :class:`ToricDivisor_generic`. INPUT: - ``x`` -- something defining a toric divisor, see - :func:`ToricDivisor`. + :func:`ToricDivisor` - - ``check``, ``reduce`` -- boolean. See - :meth:`ToricDivisor_generic.__init__`. + - ``check``, ``reduce`` -- boolean; See + :meth:`ToricDivisor_generic.__init__` EXAMPLES:: @@ -1817,7 +1813,7 @@ def _element_constructor_(self, x, check=True, reduce=True): sage: TDiv(TDiv.gen(0), check=True) V(x) """ - if is_ToricDivisor(x): + if isinstance(x, ToricDivisor_generic): if x.parent() is self: return x else: @@ -1830,11 +1826,9 @@ def base_extend(self, R): INPUT: - - ``R`` -- ring. + - ``R`` -- ring - OUTPUT: - - - toric divisor group. + OUTPUT: toric divisor group EXAMPLES:: @@ -1886,11 +1880,9 @@ class ToricRationalDivisorClassGroup(FreeModule_ambient_field, UniqueRepresentat INPUT: - ``toric_variety`` -- :class:`toric variety - `. - - OUTPUT: + ` - - the basis lattice of ``group``. + OUTPUT: the basis lattice of ``group`` EXAMPLES:: @@ -2069,9 +2053,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -2087,9 +2069,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: diff --git a/src/sage/schemes/toric/divisor_class.pyx b/src/sage/schemes/toric/divisor_class.pyx old mode 100644 new mode 100755 index ccf70e51811..98ed1b377b3 --- a/src/sage/schemes/toric/divisor_class.pyx +++ b/src/sage/schemes/toric/divisor_class.pyx @@ -73,11 +73,9 @@ def is_ToricRationalDivisorClass(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything - OUTPUT: - - - ``True`` if ``x`` is a toric rational divisor class, ``False`` otherwise. + OUTPUT: ``True`` if ``x`` is a toric rational divisor class, ``False`` otherwise EXAMPLES:: @@ -106,9 +104,7 @@ cdef class ToricRationalDivisorClass(Vector_rational_dense): - same as for :class:`~sage.modules.vector_rational_dense.Vector_rational_dense`. - OUTPUT: - - - toric rational divisor class. + OUTPUT: toric rational divisor class TESTS:: @@ -204,17 +200,15 @@ cdef class ToricRationalDivisorClass(Vector_rational_dense): cpdef _dot_product_(self, Vector right): r""" - Raise a :class:`TypeError` exception. + Raise a :exc:`TypeError` exception. Dot product is not defined on toric rational divisor classes. INPUT: - - ``right`` -- vector. - - OUTPUT: + - ``right`` -- vector - A :class:`TypeError` exception is raised. + OUTPUT: a :exc:`TypeError` exception is raised TESTS:: @@ -234,9 +228,7 @@ cdef class ToricRationalDivisorClass(Vector_rational_dense): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -251,9 +243,7 @@ cdef class ToricRationalDivisorClass(Vector_rational_dense): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -266,9 +256,7 @@ cdef class ToricRationalDivisorClass(Vector_rational_dense): r""" Return a divisor representing this divisor class. - OUTPUT: - - An instance of :class:`ToricDivisor` representing ``self``. + OUTPUT: an instance of :class:`ToricDivisor` representing ``self`` EXAMPLES:: @@ -296,17 +284,15 @@ def _ToricRationalDivisorClass_unpickle_v1(parent, entries, INPUT: - - ``parent`` -- rational divisor class group of a toric variety; - - - ``entries`` -- list of rationals specifying the divisor class; + - ``parent`` -- rational divisor class group of a toric variety - - ``degree`` -- integer, dimension of the ``parent``; + - ``entries`` -- list of rationals specifying the divisor class - - ``is_mutable`` -- boolean, whether the divisor class is mutable. + - ``degree`` -- integer; dimension of the ``parent`` - OUTPUT: + - ``is_mutable`` -- boolean, whether the divisor class is mutable - - :class:`toric rational divisor class `. + OUTPUT: :class:`toric rational divisor class ` TESTS:: diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py old mode 100644 new mode 100755 index c17cf7c37d7..113399a9c38 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -54,7 +54,7 @@ Its anticanonical "hypersurface" is a one-dimensional Calabi-Yau manifold:: - sage: P2.anticanonical_hypersurface(monomial_points="all") + sage: P2.anticanonical_hypersurface(monomial_points='all') Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 + a4*z1^2*z2 + a5*z0*z2^2 + a3*z1*z2^2 + a2*z2^3 @@ -62,15 +62,15 @@ In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: - sage: P2.anticanonical_hypersurface(monomial_points="simplified") + sage: P2.anticanonical_hypersurface(monomial_points='simplified') Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric variety obtained using ``simplex`` as ``Delta`` instead of ``Delta_polar``:: - sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points="all") - sage: FTV.anticanonical_hypersurface(monomial_points="simplified") + sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points='all') + sage: FTV.anticanonical_hypersurface(monomial_points='simplified') Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: a2*z2^3*z3^2*z4*z5^2*z8 + a1*z1^3*z3*z4^2*z7^2*z9 + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + a0*z0^3*z5*z7*z8^2*z9^2 @@ -81,7 +81,7 @@ points which do not lie on a generic anticanonical hypersurface:: sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points="all but facets") - sage: FTV.anticanonical_hypersurface(monomial_points="simplified") + sage: FTV.anticanonical_hypersurface(monomial_points='simplified') Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 @@ -128,8 +128,8 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing -from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base +from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.fraction_field import FractionField_generic from sage.schemes.toric.toric_subscheme import AlgebraicScheme_subscheme_toric @@ -153,7 +153,7 @@ def is_CPRFanoToricVariety(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: @@ -218,7 +218,7 @@ def CPRFanoToricVariety(Delta=None, *normal fan* of ``Delta``. Either ``Delta`` or ``Delta_polar`` must be given, but not both at the same time, since one is completely determined by another via :meth:`polar - ` method; + ` method. - ``Delta_polar`` -- reflexive :class:`lattice polytope `. The fan of the @@ -226,7 +226,7 @@ def CPRFanoToricVariety(Delta=None, *face fan* of ``Delta_polar``. Either ``Delta`` or ``Delta_polar`` must be given, but not both at the same time, since one is completely determined by another via :meth:`polar - ` method; + ` method. - ``coordinate_points`` -- list of integers or string. A list will be interpreted as indices of (boundary) points of ``Delta_polar`` which @@ -243,26 +243,26 @@ def CPRFanoToricVariety(Delta=None, of these lists must define a generating cone of a fan subdividing the normal fan of ``Delta``. Default ``charts`` correspond to the normal fan of ``Delta`` without subdivision. The fan specified by ``charts`` will - be subdivided to include all of the requested ``coordinate_points``; + be subdivided to include all of the requested ``coordinate_points``. - ``coordinate_names`` -- names of variables for the coordinate ring, see :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. If not given, indexed variable names will be - created automatically; + created automatically. - ``names`` -- an alias of ``coordinate_names`` for internal use. You may specify either ``names`` or ``coordinate_names``, - but not both; + but not both. - ``coordinate_name_indices`` -- list of integers, indices for indexed variables. If not given, the index of each variable will coincide with - the index of the corresponding point of ``Delta_polar``; + the index of the corresponding point of ``Delta_polar``. - ``make_simplicial`` -- if ``True``, the underlying fan will be made - simplicial (default: ``False``); + simplicial (default: ``False``) - ``base_ring`` -- base field of the CPR-Fano toric variety - (default: `\QQ`); + (default: `\QQ`) - ``base_field`` -- alias for ``base_ring``. Takes precedence if both are specified. @@ -272,7 +272,7 @@ def CPRFanoToricVariety(Delta=None, ``Delta``). If you know for sure that the input is valid, you may significantly decrease construction time using ``check=False`` option. - OUTPUT: :class:`CPR-Fano toric variety `. + OUTPUT: :class:`CPR-Fano toric variety ` EXAMPLES: @@ -330,7 +330,7 @@ def CPRFanoToricVariety(Delta=None, sage: FTV = CPRFanoToricVariety(Delta_polar=square, ....: coordinate_points=[8,0,2,1,3], - ....: coordinate_names="x+") + ....: coordinate_names='x+') sage: FTV.fan().rays() N( 1, 0), N( 1, 1), N(-1, -1), N( 1, -1), N(-1, 1) @@ -339,7 +339,7 @@ def CPRFanoToricVariety(Delta=None, (x8, x0, x2, x1, x3) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", + ....: coordinate_points='all', ....: coordinate_names="x y Z+") sage: FTV.fan().rays() N( 1, 1), N( 1, -1), N(-1, -1), N(-1, 1), @@ -357,7 +357,7 @@ def CPRFanoToricVariety(Delta=None, you want:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", + ....: coordinate_points='all', ....: coordinate_names="x y Z+", ....: coordinate_name_indices=list(range(8))) sage: FTV.gens() @@ -369,7 +369,7 @@ def CPRFanoToricVariety(Delta=None, much "automatic" ones:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", + ....: coordinate_points='all', ....: coordinate_names="x Z+", ....: coordinate_name_indices=list(range(8))) sage: FTV.gens() @@ -379,14 +379,14 @@ def CPRFanoToricVariety(Delta=None, accordingly:: sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", + ....: coordinate_points='all', ....: coordinate_names="x Z+", ....: coordinate_name_indices=[0] + list(range(7))) sage: FTV.gens() (x, Z0, Z1, Z2, Z3, Z4, Z5, Z6) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all", + ....: coordinate_points='all', ....: coordinate_names="x y Z+", ....: coordinate_name_indices=[0]*2 + list(range(6))) sage: FTV.gens() @@ -532,9 +532,8 @@ def CPRFanoToricVariety(Delta=None, raise ValueError("the origin (point #%d) cannot be used for a " "coordinate!\nGot: %s" % (Delta_polar.origin(), coordinate_points)) - point_to_ray = {} - for n, point in enumerate(coordinate_points): - point_to_ray[point] = n + point_to_ray = {point: n + for n, point in enumerate(coordinate_points)} # This can be simplified if LatticePolytopeClass is adjusted. rays = [Delta_polar.point(p) for p in coordinate_points] # Check/normalize charts and construct the fan based on them. @@ -612,27 +611,27 @@ class CPRFanoToricVariety_field(ToricVariety_field): INPUT: - - ``Delta_polar`` -- reflexive polytope; + - ``Delta_polar`` -- reflexive polytope - ``fan`` -- rational polyhedral fan subdividing the face fan of - ``Delta_polar``; + ``Delta_polar`` - ``coordinate_points`` -- list of indices of points of ``Delta_polar`` - used for rays of ``fan``; + used for rays of ``fan`` - ``point_to_ray`` -- dictionary mapping the index of a coordinate point - to the index of the corresponding ray; + to the index of the corresponding ray - ``coordinate_names`` -- names of the variables of the coordinate ring in the format accepted by - :func:`~sage.schemes.toric.variety.normalize_names`; + :func:`~sage.schemes.toric.variety.normalize_names` - ``coordinate_name_indices`` -- indices for indexed variables, - if ``None``, will be equal to ``coordinate_points``; + if ``None``, will be equal to ``coordinate_points`` - - ``base_field`` -- base field of the CPR-Fano toric variety. + - ``base_field`` -- base field of the CPR-Fano toric variety - OUTPUT: :class:`CPR-Fano toric variety `. + OUTPUT: :class:`CPR-Fano toric variety ` TESTS:: @@ -669,9 +668,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -685,9 +682,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -715,7 +710,7 @@ def anticanonical_hypersurface(self, **kwds): INPUT: - - ``monomial points`` -- a list of integers or a string. A list will be + - ``monomial points`` -- list of integers or a string. A list will be interpreted as indices of points of `\Delta` which should be used for monomials of this hypersurface. A string must be one of the following descriptions of points of `\Delta`: @@ -731,11 +726,11 @@ def anticanonical_hypersurface(self, **kwds): - ``coefficient_names`` -- names for the monomial coefficients, see :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. If not given, indexed coefficient names will - be created automatically; + be created automatically. - - ``coefficient_name_indices`` -- a list of integers, indices for + - ``coefficient_name_indices`` -- list of integers, indices for indexed coefficients. If not given, the index of each coefficient - will coincide with the index of the corresponding point of `\Delta`; + will coincide with the index of the corresponding point of `\Delta`. - ``coefficients`` -- as an alternative to specifying coefficient names and/or indices, you can give the coefficients themselves as @@ -758,7 +753,7 @@ def anticanonical_hypersurface(self, **kwds): Its anticanonical "hypersurface" is a one-dimensional Calabi-Yau manifold:: - sage: P2.anticanonical_hypersurface(monomial_points="all") + sage: P2.anticanonical_hypersurface(monomial_points='all') Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 @@ -767,7 +762,7 @@ def anticanonical_hypersurface(self, **kwds): In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: - sage: P2.anticanonical_hypersurface(monomial_points="simplified") + sage: P2.anticanonical_hypersurface(monomial_points='simplified') Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 @@ -777,8 +772,8 @@ def anticanonical_hypersurface(self, **kwds): ``Delta_polar``:: sage: FTV = CPRFanoToricVariety(Delta=simplex, - ....: coordinate_points="all") - sage: FTV.anticanonical_hypersurface(monomial_points="simplified") + ....: coordinate_points='all') + sage: FTV.anticanonical_hypersurface(monomial_points='simplified') Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: a2*z2^3*z3^2*z4*z5^2*z8 + a1*z1^3*z3*z4^2*z7^2*z9 @@ -791,7 +786,7 @@ def anticanonical_hypersurface(self, **kwds): sage: FTV = CPRFanoToricVariety(Delta=simplex, ....: coordinate_points="all but facets") - sage: FTV.anticanonical_hypersurface(monomial_points="simplified") + sage: FTV.anticanonical_hypersurface(monomial_points='simplified') Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 @@ -840,9 +835,9 @@ def change_ring(self, F): INPUT: - - ``F`` -- field. + - ``F`` -- field - OUTPUT: :class:`CPR-Fano toric variety ` over ``F``. + OUTPUT: :class:`CPR-Fano toric variety ` over ``F`` .. NOTE:: @@ -891,11 +886,9 @@ def coordinate_point_to_coordinate(self, point): INPUT: - - ``point`` -- integer from the list of :meth:`coordinate_points`. + - ``point`` -- integer from the list of :meth:`coordinate_points` - OUTPUT: - - - the corresponding generator of the coordinate ring of ``self``. + OUTPUT: the corresponding generator of the coordinate ring of ``self`` EXAMPLES:: @@ -914,7 +907,7 @@ def coordinate_points(self): r""" Return indices of points of :meth:`Delta_polar` used for coordinates. - OUTPUT: :class:`tuple` of integers. + OUTPUT: :class:`tuple` of integers EXAMPLES:: @@ -928,7 +921,7 @@ def coordinate_points(self): (z0, z1, z2, z3, z8) sage: FTV = CPRFanoToricVariety(Delta_polar=square, - ....: coordinate_points="all") + ....: coordinate_points='all') sage: FTV.coordinate_points() (0, 1, 2, 3, 4, 5, 7, 8) sage: FTV.gens() @@ -1012,7 +1005,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): - ``nef_partition`` -- a `k`-part :class:`nef-partition ` of `\Delta^\circ`, all - other parameters (if given) must be lists of length `k`; + other parameters (if given) must be lists of length `k` - ``monomial_points`` -- the `i`-th element of this list is either a list of integers or a string. A list will be interpreted as indices @@ -1025,18 +1018,18 @@ def nef_complete_intersection(self, nef_partition, **kwds): * "all" (default), when using this description, it is also OK to pass a single string as - ``monomial_points`` instead of repeating it `k` times; + ``monomial_points`` instead of repeating it `k` times. - ``coefficient_names`` -- the `i`-th element of this list specifies names for the monomial coefficients of the `i`-th polynomial, see :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. If not given, indexed coefficient names will - be created automatically; + be created automatically. - - ``coefficient_name_indices`` -- the `i`-th element of this list + - ``coefficient_name_indices`` -- the `i`-th element of this list specifies indices for indexed coefficients of the `i`-th polynomial. If not given, the index of each coefficient will coincide with the - index of the corresponding point of `\Delta_i`; + index of the corresponding point of `\Delta_i`. - ``coefficients`` -- as an alternative to specifying coefficient names and/or indices, you can give the coefficients themselves as @@ -1069,7 +1062,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): Now we include only monomials associated to vertices of `\Delta_i`:: - sage: X.nef_complete_intersection(np, monomial_points="vertices") + sage: X.nef_complete_intersection(np, monomial_points='vertices') Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 @@ -1081,7 +1074,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): instead of using default generic names:: sage: X.nef_complete_intersection(np, - ....: monomial_points="vertices", + ....: monomial_points='vertices', ....: coefficients=[("a", "a^2", "a/e", "c_i"), list(range(1,6))]) Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: @@ -1094,7 +1087,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): intersections in a completely resolved ambient toric variety:: sage: X = CPRFanoToricVariety(Delta_polar=p, - ....: coordinate_points="all") + ....: coordinate_points='all') sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 22 affine patches defined by: @@ -1118,11 +1111,11 @@ def cartesian_product(self, other, - ``other`` -- a (possibly :class:`CPR-Fano `) :class:`toric variety - `; + ` - ``coordinate_names`` -- names of variables for the coordinate ring, see :func:`normalize_names` for acceptable formats. If not given, - indexed variable names will be created automatically; + indexed variable names will be created automatically. - ``coordinate_indices`` -- list of integers, indices for indexed variables. If not given, the index of each variable will coincide @@ -1176,12 +1169,12 @@ def resolve(self, **kwds): - ``new_points`` -- list of integers, indices of boundary points of :meth:`Delta_polar`, which should be added as rays to the - subdividing fan; + subdividing fan - all other arguments will be passed to :meth:`~sage.schemes.toric.variety.ToricVariety_field.resolve` - method of (general) toric varieties, see its documentation for - details. + method of (general) toric varieties; see its documentation for + details OUTPUT: @@ -1235,9 +1228,8 @@ def resolve(self, **kwds): "subdivision!" % Delta_polar.origin()) if new_points: coordinate_points = coordinate_points + new_points - point_to_ray = {} - for n, point in enumerate(coordinate_points): - point_to_ray[point] = n + point_to_ray = {point: n + for n, point in enumerate(coordinate_points)} else: point_to_ray = self._point_to_ray new_rays = [Delta_polar.point(point) for point in new_points] @@ -1270,16 +1262,15 @@ class AnticanonicalHypersurface(AlgebraicScheme_subscheme_toric): INPUT: - ``P_Delta`` -- :class:`CPR-Fano toric variety - ` associated to a reflexive polytope - `\Delta`; + ` associated to a reflexive polytope `\Delta` - - see :meth:`CPRFanoToricVariety_field.anticanonical_hypersurface` for - documentation on all other acceptable parameters. + - see :meth:`CPRFanoToricVariety_field.anticanonical_hypersurface` for + documentation on all other acceptable parameters OUTPUT: - - :class:`anticanonical hypersurface ` of - ``P_Delta`` (with the extended base field, if necessary). + :class:`anticanonical hypersurface ` of + ``P_Delta`` (with the extended base field, if necessary). EXAMPLES:: @@ -1312,7 +1303,7 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, sage: F = GF(5^2, "a") # needs sage.rings.finite_rings sage: X = P1xP1.change_ring(F) # needs sage.rings.finite_rings - sage: X.anticanonical_hypersurface(monomial_points="all", # needs sage.rings.finite_rings + sage: X.anticanonical_hypersurface(monomial_points='all', # needs sage.rings.finite_rings ....: coefficients=[1]*X.Delta().npoints()) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: @@ -1384,11 +1375,10 @@ class NefCompleteIntersection(AlgebraicScheme_subscheme_toric): INPUT: - ``P_Delta`` -- a :class:`CPR-Fano toric variety - ` associated to a reflexive polytope - `\Delta`; + ` associated to a reflexive polytope `\Delta` - see :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for - documentation on all other acceptable parameters. + documentation on all other acceptable parameters OUTPUT: @@ -1411,7 +1401,7 @@ class NefCompleteIntersection(AlgebraicScheme_subscheme_toric): more elaborate example. """ def __init__(self, P_Delta, nef_partition, - monomial_points="all", coefficient_names=None, + monomial_points='all', coefficient_names=None, coefficient_name_indices=None, coefficients=None): r""" See :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for @@ -1510,7 +1500,7 @@ def cohomology_class(self): r""" Return the class of ``self`` in the ambient space cohomology ring. - OUTPUT: A :class:`cohomology class `. + OUTPUT: a :class:`cohomology class ` EXAMPLES:: @@ -1536,7 +1526,7 @@ def nef_partition(self): r""" Return the nef-partition associated to ``self``. - OUTPUT: A :class:`nef-partition `. + OUTPUT: a :class:`nef-partition ` EXAMPLES:: @@ -1563,9 +1553,9 @@ def add_variables(field, variables): INPUT: - - ``field`` -- a field; + - ``field`` -- a field - - ``variables`` -- a list of strings. + - ``variables`` -- list of strings OUTPUT: @@ -1593,7 +1583,7 @@ def add_variables(field, variables): if isinstance(field, FractionField_generic): # Q(a) ---> Q(a, b) rather than Q(a)(b) R = field.ring() - if is_PolynomialRing(R) or is_MPolynomialRing(R): + if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base): new_variables = list(R.variable_names()) for v in variables: if v not in new_variables: diff --git a/src/sage/schemes/toric/homset.py b/src/sage/schemes/toric/homset.py old mode 100644 new mode 100755 index 830eb09de44..87f648e1a9d --- a/src/sage/schemes/toric/homset.py +++ b/src/sage/schemes/toric/homset.py @@ -13,7 +13,7 @@ done by :class:`~sage.schemes.generic.homset.SchemeHomset_points` and its subclasses. -.. note:: +.. NOTE:: You should not create the Hom-sets manually. Instead, use the :meth:`~sage.structure.parent.Hom` method that is inherited by all @@ -176,17 +176,15 @@ def _element_constructor_(self, x, check=True): INPUT: - - `x` -- anything that defines a morphism of toric + - ``x`` -- anything that defines a morphism of toric varieties. A matrix, fan morphism, or a list or tuple of homogeneous polynomials that define a morphism. - - ``check`` -- boolean (default: ``True``) passed onto + - ``check`` -- boolean (default: ``True``); passed onto functions called by this to be more careful about input argument type checking - OUTPUT: - - The morphism of toric varieties determined by ``x``. + OUTPUT: the morphism of toric varieties determined by ``x`` EXAMPLES: @@ -271,9 +269,7 @@ def _an_element_(self): """ Construct a sample morphism. - OUTPUT: - - An element of the homset. + OUTPUT: an element of the homset EXAMPLES:: @@ -298,7 +294,7 @@ class SchemeHomset_points_toric_base(SchemeHomset_points): - same as for :class:`SchemeHomset_points`. - OUTPUT: A scheme morphism of type :class:`SchemeHomset_points_toric_base`. + OUTPUT: a scheme morphism of type :class:`SchemeHomset_points_toric_base` EXAMPLES:: @@ -318,7 +314,7 @@ def is_finite(self): """ Return whether there are finitely many points. - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -432,7 +428,7 @@ class SchemeHomset_points_toric_field(SchemeHomset_points_toric_base): - same as for :class:`~sage.schemes.generic.homset.SchemeHomset_points`. - OUTPUT: A scheme morphism of type :class:`SchemeHomset_points_toric_field`. + OUTPUT: a scheme morphism of type :class:`SchemeHomset_points_toric_field` EXAMPLES:: @@ -493,9 +489,7 @@ def cardinality(self): r""" Return the number of points of the toric variety. - OUTPUT: - - An integer or infinity. The cardinality of the set of points. + OUTPUT: integer or infinity; the cardinality of the set of points EXAMPLES:: @@ -568,7 +562,7 @@ def __iter__(self): """ Iterate over the points of the variety. - OUTPUT: Iterator over points. + OUTPUT: iterator over points EXAMPLES:: @@ -615,9 +609,7 @@ def __iter__(self): """ Iterate over the points of the variety. - OUTPUT: - - Iterator over points. + OUTPUT: iterator over points EXAMPLES:: @@ -636,9 +628,7 @@ def cardinality(self): """ Return the number of points of the toric variety. - OUTPUT: - - An integer or infinity. The cardinality of the set of points. + OUTPUT: integer or infinity; the cardinality of the set of points EXAMPLES:: diff --git a/src/sage/schemes/toric/ideal.py b/src/sage/schemes/toric/ideal.py old mode 100644 new mode 100755 index 8feca9114ad..4c171595e6a --- a/src/sage/schemes/toric/ideal.py +++ b/src/sage/schemes/toric/ideal.py @@ -147,24 +147,24 @@ class ToricIdeal(MPolynomialIdeal): INPUT: - - ``A`` -- integer matrix. The defining matrix of the toric ideal. + - ``A`` -- integer matrix; the defining matrix of the toric ideal - - ``names`` -- string (optional). Names for the variables. By + - ``names`` -- string (optional); names for the variables. By default, this is ``'z'`` and the variables will be named ``z0``, ``z1``, ... - - ``base_ring`` -- a ring (optional). Default: `\QQ`. The base + - ``base_ring`` -- a ring (default: `\QQ`); the base ring of the ideal. A toric ideal uses only coefficients `\pm 1`. - - ``polynomial_ring`` -- a polynomial ring (optional). The - polynomial ring to construct the ideal in. + - ``polynomial_ring`` -- a polynomial ring (optional); the + polynomial ring to construct the ideal in You may specify the ambient polynomial ring via the ``polynomial_ring`` parameter or via the ``names`` and - ``base_ring`` parameter. A :class:`ValueError` is raised if you + ``base_ring`` parameter. A :exc:`ValueError` is raised if you specify both. - - ``algorithm`` -- string (optional). The algorithm to use. For + - ``algorithm`` -- string (optional); the algorithm to use. For now, must be ``'HostenSturmfels'`` which is the algorithm proposed by Hosten and Sturmfels in [SH1995b]_. @@ -250,7 +250,7 @@ def A(self): """ Return the defining matrix. - OUTPUT: An integer matrix. + OUTPUT: integer matrix EXAMPLES:: @@ -266,7 +266,7 @@ def ker(self): """ Return the kernel of the defining matrix. - OUTPUT: The kernel of ``self.A()``. + OUTPUT: the kernel of ``self.A()``. EXAMPLES:: @@ -286,8 +286,7 @@ def nvariables(self): r""" Return the number of variables of the ambient polynomial ring. - OUTPUT: An integer. The number of columns of the defining matrix - :meth:`A`. + OUTPUT: integer; the number of columns of the defining matrix :meth:`A` EXAMPLES:: @@ -304,12 +303,10 @@ def _init_ring(self, term_order): INPUT: - - ``term_order`` -- string. The order of the variables, for - example ``'neglex'`` and ``'degrevlex'``. + - ``term_order`` -- string; the order of the variables, for + example ``'neglex'`` and ``'degrevlex'`` - OUTPUT: - - A polynomial ring with the given term order. + OUTPUT: a polynomial ring with the given term order .. NOTE:: @@ -340,11 +337,9 @@ def _naive_ideal(self, ring): INPUT: - - ``ring`` -- the ambient ring of the ideal. - - OUTPUT: + - ``ring`` -- the ambient ring of the ideal - A subideal of the toric ideal in the polynomial ring ``ring``. + OUTPUT: a subideal of the toric ideal in the polynomial ring ``ring`` EXAMPLES:: @@ -359,8 +354,8 @@ def _naive_ideal(self, ring): x = ring.gens() binomials = [] for row in self.ker().matrix().rows(): - xpos = prod(x[i]**max( row[i],0) for i in range(0,len(x))) - xneg = prod(x[i]**max(-row[i],0) for i in range(0,len(x))) + xpos = prod(x[i]**max(row[i], 0) for i in range(len(x))) + xneg = prod(x[i]**max(-row[i], 0) for i in range(len(x))) binomials.append(xpos - xneg) return ring.ideal(binomials) @@ -370,15 +365,13 @@ def _ideal_quotient_by_variable(self, ring, ideal, n): INPUT: - - ``ring`` -- the ambient polynomial ring in neglex order. - - - ``ideal`` -- the ideal `J`. + - ``ring`` -- the ambient polynomial ring in neglex order - - ``n`` -- Integer. The index of the next variable to divide by. + - ``ideal`` -- the ideal `J` - OUTPUT: + - ``n`` -- integer; the index of the next variable to divide by - The ideal quotient `(J:x_n^\infty)`. + OUTPUT: the ideal quotient `(J:x_n^\infty)` ALGORITHM: @@ -414,7 +407,7 @@ def subtract(e, power): return tuple([l[0] - power] + l[1:]) def divide_by_x_n(p): - d_old = p.dict() + d_old = p.monomial_coefficients() power = min(e[0] for e in d_old) d_new = {subtract(exponent, power): coefficient for exponent, coefficient in d_old.items()} @@ -452,6 +445,6 @@ def _ideal_HostenSturmfels(self): J = self._naive_ideal(ring) if J.is_zero(): return J - for i in range(0,self.nvariables()): + for i in range(self.nvariables()): J = self._ideal_quotient_by_variable(ring, J, i) return J diff --git a/src/sage/schemes/toric/library.py b/src/sage/schemes/toric/library.py old mode 100644 new mode 100755 index c09c404d64a..6f833c5c5d2 --- a/src/sage/schemes/toric/library.py +++ b/src/sage/schemes/toric/library.py @@ -58,44 +58,44 @@ # The combinatorial data of the toric varieties is stored separately here # since we might want to use it later on to do the reverse lookup. toric_varieties_rays_cones = { - 'dP6':[ + 'dP6': [ [(0, 1), (-1, 0), (-1, -1), (0, -1), (1, 0), (1, 1)], - [[0,1],[1,2],[2,3],[3,4],[4,5],[5,0]] ], - 'dP7':[ + [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]]], + 'dP7': [ [(0, 1), (-1, 0), (-1, -1), (0, -1), (1, 0)], - [[0,1],[1,2],[2,3],[3,4],[4,0]] ], - 'dP8':[ - [(1,1), (0, 1), (-1, -1), (1, 0)], - [[0,1],[1,2],[2,3],[3,0]] + [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]]], + 'dP8': [ + [(1, 1), (0, 1), (-1, -1), (1, 0)], + [[0, 1], [1, 2], [2, 3], [3, 0]] ], - 'P1xP1':[ + 'P1xP1': [ [(1, 0), (-1, 0), (0, 1), (0, -1)], - [[0,2],[2,1],[1,3],[3,0]] ], - 'P1xP1_Z2':[ + [[0, 2], [2, 1], [1, 3], [3, 0]]], + 'P1xP1_Z2': [ [(1, 1), (-1, -1), (-1, 1), (1, -1)], - [[0,2],[2,1],[1,3],[3,0]] ], - 'P1':[ + [[0, 2], [2, 1], [1, 3], [3, 0]]], + 'P1': [ [(1,), (-1,)], - [[0],[1]] ], - 'P2':[ - [(1,0), (0, 1), (-1, -1)], - [[0,1],[1,2],[2,0]] ], - 'A1':[ + [[0], [1]]], + 'P2': [ + [(1, 0), (0, 1), (-1, -1)], + [[0, 1], [1, 2], [2, 0]]], + 'A1': [ [(1,)], - [[0]] ], - 'A2':[ + [[0]]], + 'A2': [ [(1, 0), (0, 1)], - [[0,1]] ], - 'A2_Z2':[ + [[0, 1]]], + 'A2_Z2': [ [(1, 0), (1, 2)], - [[0,1]] ], - 'P1xA1':[ + [[0, 1]]], + 'P1xA1': [ [(1, 0), (-1, 0), (0, 1)], - [[0,2],[2,1]] ], - 'Conifold':[ + [[0, 2], [2, 1]]], + 'Conifold': [ [(0, 0, 1), (0, 1, 1), (1, 0, 1), (1, 1, 1)], - [[0,1,2,3]] ], - 'dP6xdP6':[ + [[0, 1, 2, 3]]], + 'dP6xdP6': [ [(0, 1, 0, 0), (-1, 0, 0, 0), (-1, -1, 0, 0), (0, -1, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (0, 0, 0, 1), (0, 0, -1, 0), (0, 0, -1, -1), @@ -108,74 +108,74 @@ [3, 4, 8, 9], [3, 4, 9, 10], [3, 4, 10, 11], [3, 4, 6, 11], [4, 5, 6, 7], [4, 5, 7, 8], [4, 5, 8, 9], [4, 5, 9, 10], [4, 5, 10, 11], [4, 5, 6, 11], [0, 5, 6, 7], [0, 5, 7, 8], - [0, 5, 8, 9], [0, 5, 9, 10], [0, 5, 10, 11], [0, 5, 6, 11]] ], - 'Cube_face_fan':[ + [0, 5, 8, 9], [0, 5, 9, 10], [0, 5, 10, 11], [0, 5, 6, 11]]], + 'Cube_face_fan': [ [(1, 1, 1), (1, -1, 1), (-1, 1, 1), (-1, -1, 1), (-1, -1, -1), (-1, 1, -1), (1, -1, -1), (1, 1, -1)], - [[0,1,2,3], [4,5,6,7], [0,1,7,6], [4,5,3,2], [0,2,5,7], [4,6,1,3]] ], - 'Cube_sublattice':[ + [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 7, 6], [4, 5, 3, 2], [0, 2, 5, 7], [4, 6, 1, 3]]], + 'Cube_sublattice': [ [(1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 1, 1), (-1, 0, 0), (0, -1, 0), (0, 0, -1), (1, -1, -1)], - [[0,1,2,3],[4,5,6,7],[0,1,7,6],[4,5,3,2],[0,2,5,7],[4,6,1,3]] ], - 'Cube_nonpolyhedral':[ + [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 7, 6], [4, 5, 3, 2], [0, 2, 5, 7], [4, 6, 1, 3]]], + 'Cube_nonpolyhedral': [ [(1, 2, 3), (1, -1, 1), (-1, 1, 1), (-1, -1, 1), (-1, -1, -1), (-1, 1, -1), (1, -1, -1), (1, 1, -1)], - [[0,1,2,3],[4,5,6,7],[0,1,7,6],[4,5,3,2],[0,2,5,7],[4,6,1,3]] ], - 'BCdlOG':[ + [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 7, 6], [4, 5, 3, 2], [0, 2, 5, 7], [4, 6, 1, 3]]], + 'BCdlOG': [ [(-1, 0, 0, 2, 3), # 0 - ( 0,-1, 0, 2, 3), # 1 - ( 0, 0,-1, 2, 3), # 2 - ( 0, 0,-1, 1, 2), # 3 - ( 0, 0, 0,-1, 0), # 4 - ( 0, 0, 0, 0,-1), # 5 - ( 0, 0, 0, 2, 3), # 6 - ( 0, 0, 1, 2, 3), # 7 - ( 0, 0, 2, 2, 3), # 8 - ( 0, 0, 1, 1, 1), # 9 - ( 0, 1, 2, 2, 3), # 10 - ( 0, 1, 3, 2, 3), # 11 - ( 1, 0, 4, 2, 3)], # 12 - [ [0,6,7,1,4], [0,6,10,2,4], [0,6,1,2,4], [0,9,7,1,5], [0,6,7,1,5], - [0,6,10,2,5], [0,6,1,2,5], [0,9,1,4,5], [0,6,10,4,11],[0,6,7,4,11], - [0,6,10,5,11], [0,9,7,5,11], [0,6,7,5,11], [0,9,4,5,11], [0,10,4,5,11], - [0,9,7,1,8], [0,9,1,4,8], [0,7,1,4,8], [0,9,7,11,8], [0,9,4,11,8], - [0,7,4,11,8], [0,10,2,4,3], [0,1,2,4,3], [0,10,2,5,3], [0,1,2,5,3], - [0,10,4,5,3], [0,1,4,5,3], [12,6,7,1,4], [12,6,10,2,4],[12,6,1,2,4], - [12,9,7,1,5], [12,6,7,1,5], [12,6,10,2,5], [12,6,1,2,5], [12,9,1,4,5], - [12,6,10,4,11],[12,6,7,4,11], [12,6,10,5,11],[12,9,7,5,11],[12,6,7,5,11], - [12,9,4,5,11], [12,10,4,5,11],[12,9,7,1,8], [12,9,1,4,8], [12,7,1,4,8], - [12,9,7,11,8], [12,9,4,11,8], [12,7,4,11,8], [12,10,2,4,3],[12,1,2,4,3], - [12,10,2,5,3], [12,1,2,5,3], [12,10,4,5,3], [12,1,4,5,3] ] ], - 'BCdlOG_base':[ + (0, -1, 0, 2, 3), # 1 + (0, 0, -1, 2, 3), # 2 + (0, 0, -1, 1, 2), # 3 + (0, 0, 0, -1, 0), # 4 + (0, 0, 0, 0, -1), # 5 + (0, 0, 0, 2, 3), # 6 + (0, 0, 1, 2, 3), # 7 + (0, 0, 2, 2, 3), # 8 + (0, 0, 1, 1, 1), # 9 + (0, 1, 2, 2, 3), # 10 + (0, 1, 3, 2, 3), # 11 + (1, 0, 4, 2, 3)], # 12 + [[0, 6, 7, 1, 4], [0, 6, 10, 2, 4], [0, 6, 1, 2, 4], [0, 9, 7, 1, 5], [0, 6, 7, 1, 5], + [0, 6, 10, 2, 5], [0, 6, 1, 2, 5], [0, 9, 1, 4, 5], [0, 6, 10, 4, 11], [0, 6, 7, 4, 11], + [0, 6, 10, 5, 11], [0, 9, 7, 5, 11], [0, 6, 7, 5, 11], [0, 9, 4, 5, 11], [0, 10, 4, 5, 11], + [0, 9, 7, 1, 8], [0, 9, 1, 4, 8], [0, 7, 1, 4, 8], [0, 9, 7, 11, 8], [0, 9, 4, 11, 8], + [0, 7, 4, 11, 8], [0, 10, 2, 4, 3], [0, 1, 2, 4, 3], [0, 10, 2, 5, 3], [0, 1, 2, 5, 3], + [0, 10, 4, 5, 3], [0, 1, 4, 5, 3], [12, 6, 7, 1, 4], [12, 6, 10, 2, 4], [12, 6, 1, 2, 4], + [12, 9, 7, 1, 5], [12, 6, 7, 1, 5], [12, 6, 10, 2, 5], [12, 6, 1, 2, 5], [12, 9, 1, 4, 5], + [12, 6, 10, 4, 11], [12, 6, 7, 4, 11], [12, 6, 10, 5, 11], [12, 9, 7, 5, 11], [12, 6, 7, 5, 11], + [12, 9, 4, 5, 11], [12, 10, 4, 5, 11], [12, 9, 7, 1, 8], [12, 9, 1, 4, 8], [12, 7, 1, 4, 8], + [12, 9, 7, 11, 8], [12, 9, 4, 11, 8], [12, 7, 4, 11, 8], [12, 10, 2, 4, 3], [12, 1, 2, 4, 3], + [12, 10, 2, 5, 3], [12, 1, 2, 5, 3], [12, 10, 4, 5, 3], [12, 1, 4, 5, 3]]], + 'BCdlOG_base': [ [(-1, 0, 0), - ( 0,-1, 0), - ( 0, 0,-1), - ( 0, 0, 1), - ( 0, 1, 2), - ( 0, 1, 3), - ( 1, 0, 4)], - [[0,4,2],[0,4,5],[0,5,3],[0,1,3],[0,1,2], - [6,4,2],[6,4,5],[6,5,3],[6,1,3],[6,1,2]] ], - 'P2_112':[ - [(1,0), (0, 1), (-1, -2)], - [[0,1],[1,2],[2,0]] ], - 'P2_123':[ - [(1,0), (0, 1), (-2, -3)], - [[0,1],[1,2],[2,0]] ], - 'P4_11169':[ + (0, -1, 0), + (0, 0, -1), + (0, 0, 1), + (0, 1, 2), + (0, 1, 3), + (1, 0, 4)], + [[0, 4, 2], [0, 4, 5], [0, 5, 3], [0, 1, 3], [0, 1, 2], + [6, 4, 2], [6, 4, 5], [6, 5, 3], [6, 1, 3], [6, 1, 2]]], + 'P2_112': [ + [(1, 0), (0, 1), (-1, -2)], + [[0, 1], [1, 2], [2, 0]]], + 'P2_123': [ + [(1, 0), (0, 1), (-2, -3)], + [[0, 1], [1, 2], [2, 0]]], + 'P4_11169': [ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-9, -6, -1, -1)], - [[0,1,2,3],[0,1,2,4],[0,1,3,4],[0,2,3,4],[1,2,3,4]] ], - 'P4_11169_resolved':[ + [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]]], + 'P4_11169_resolved': [ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-9, -6, -1, -1), (-3, -2, 0, 0)], [[0, 1, 2, 3], [0, 1, 3, 4], [0, 1, 2, 4], [1, 3, 4, 5], [0, 3, 4, 5], - [1, 2, 4, 5], [0, 2, 4, 5], [1, 2, 3, 5], [0, 2, 3, 5]] ], - 'P4_11133':[ + [1, 2, 4, 5], [0, 2, 4, 5], [1, 2, 3, 5], [0, 2, 3, 5]]], + 'P4_11133': [ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-3, -3, -1, -1)], - [[0,1,2,3],[0,1,2,4],[0,1,3,4],[0,2,3,4],[1,2,3,4]] ], - 'P4_11133_resolved':[ + [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]]], + 'P4_11133_resolved': [ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-3, -3, -1, -1), (-1, -1, 0, 0)], [[0, 1, 2, 3], [0, 1, 3, 4], [0, 1, 2, 4], [1, 3, 4, 5], [0, 3, 4, 5], - [1, 2, 4, 5], [0, 2, 4, 5], [1, 2, 3, 5], [0, 2, 3, 5]] ] + [1, 2, 4, 5], [0, 2, 4, 5], [1, 2, 3, 5], [0, 2, 3, 5]]] } @@ -197,16 +197,16 @@ def _make_ToricVariety(self, name, coordinate_names, base_ring): INPUT: - - ``name`` -- string. One of the pre-defined names in the - ``toric_varieties_rays_cones`` data structure. + - ``name`` -- string; one of the pre-defined names in the + ``toric_varieties_rays_cones`` data structure - - ``coordinate_names`` -- A string describing the names of the - homogeneous coordinates of the toric variety. + - ``coordinate_names`` -- string describing the names of the + homogeneous coordinates of the toric variety - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -236,16 +236,16 @@ def _make_CPRFanoToricVariety(self, name, coordinate_names, base_ring): INPUT: - - ``name`` -- string. One of the pre-defined names in the - ``toric_varieties_rays_cones`` data structure. + - ``name`` -- string; one of the pre-defined names in the + ``toric_varieties_rays_cones`` data structure - - ``coordinate_names`` -- A string describing the names of the - homogeneous coordinates of the toric variety. + - ``coordinate_names`` -- string describing the names of the + homogeneous coordinates of the toric variety - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -264,7 +264,7 @@ def _make_CPRFanoToricVariety(self, name, coordinate_names, base_ring): polytope = LatticePolytope(rays, lattice=ToricLattice(len(rays[0]))) points = [tuple(_) for _ in polytope.points()] ray2point = [points.index(r) for r in rays] - charts = [ [ray2point[i] for i in c] for c in cones ] + charts = [[ray2point[i] for i in c] for c in cones] self.__dict__[dict_key] = \ CPRFanoToricVariety(Delta_polar=polytope, coordinate_points=ray2point, @@ -281,15 +281,14 @@ def dP6(self, names='x u y v z w', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -312,15 +311,14 @@ def dP7(self, names='x u y v z', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -343,15 +341,14 @@ def dP8(self, names='t x y z', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -374,15 +371,14 @@ def P1xP1(self, names='s t x y', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -405,15 +401,14 @@ def P1xP1_Z2(self, names='s t x y', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -438,15 +433,14 @@ def P1(self, names='s t', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -469,15 +463,14 @@ def P2(self, names='x y z', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -500,17 +493,16 @@ def P(self, n, names='z+', base_ring=QQ): INPUT: - - ``n`` -- positive integer. The dimension of the projective space. + - ``n`` -- positive integer; the dimension of the projective space - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -550,15 +542,14 @@ def A1(self, names='z', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -579,15 +570,14 @@ def A2(self, names='x y', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -609,17 +599,16 @@ def A(self, n, names='z+', base_ring=QQ): INPUT: - - ``n`` -- positive integer. The dimension of the affine space. + - ``n`` -- positive integer; the dimension of the affine space - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -656,15 +645,14 @@ def A2_Z2(self, names='x y', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -687,15 +675,14 @@ def P1xA1(self, names='s t z', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -718,15 +705,14 @@ def Conifold(self, names='u x y v', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -749,15 +735,14 @@ def dP6xdP6(self, names='x0 x1 x2 x3 x4 x5 y0 y1 y2 y3 y4 y5', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -785,15 +770,14 @@ def Cube_face_fan(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -820,15 +804,14 @@ def Cube_sublattice(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -855,15 +838,14 @@ def Cube_nonpolyhedral(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. .. NOTE:: @@ -886,7 +868,7 @@ def Cube_nonpolyhedral(self, names='z+', base_ring=QQ): """ return self._make_ToricVariety('Cube_nonpolyhedral', names, base_ring) - def Cube_deformation(self,k, names=None, base_ring=QQ): + def Cube_deformation(self, k, names=None, base_ring=QQ): r""" Construct, for each `k\in\ZZ_{\geq 0}`, a toric variety with `\ZZ_k`-torsion in the Chow group. @@ -898,16 +880,15 @@ def Cube_deformation(self,k, names=None, base_ring=QQ): INPUT: - - ``k`` -- integer. The case ``k=0`` is the same as - :meth:`Cube_face_fan`. + - ``k`` -- integer; the case ``k=0`` is the same as + :meth:`Cube_face_fan` - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety OUTPUT: @@ -932,10 +913,10 @@ def Cube_deformation(self,k, names=None, base_ring=QQ): k = ZZ(k) # make sure that we got a "mathematical" integer except TypeError: raise TypeError("cube deformations X_k are defined only for " - "non-negative integer k!\nGot: %s" % k) + "nonnegative integer k!\nGot: %s" % k) if k < 0: raise ValueError("cube deformations X_k are defined only for " - "non-negative k!\nGot: %s" % k) + "nonnegative k!\nGot: %s" % k) def rays(kappa): return matrix([[1, 1, 2 * kappa + 1], [1, -1, 1], @@ -955,15 +936,14 @@ def BCdlOG(self, names='v1 v2 c1 c2 v4 v5 b e1 e2 e3 f g v6', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -991,15 +971,14 @@ def BCdlOG_base(self, names='d4 d3 r2 r1 d2 u d1', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -1022,15 +1001,14 @@ def P2_112(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1054,15 +1032,14 @@ def P2_123(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1086,15 +1063,14 @@ def P4_11169(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1118,15 +1094,14 @@ def P4_11169_resolved(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1150,15 +1125,14 @@ def P4_11133(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1181,15 +1155,14 @@ def P4_11133_resolved(self, names='z+', base_ring=QQ): INPUT: - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`CPR-Fano toric variety + OUTPUT: a :class:`CPR-Fano toric variety `. EXAMPLES:: @@ -1221,10 +1194,10 @@ def WP(self, *q, **kw): Two keyword arguments: - - ``base_ring`` -- a field (default: `\QQ`). + - ``base_ring`` -- a field (default: `\QQ`) - - ``names`` -- string or list (tuple) of strings (default 'z+'). See - :func:`~sage.schemes.toric.variety.normalize_names` for + - ``names`` -- string or list (tuple) of strings (default: ``'z+'``); + see :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. OUTPUT: @@ -1295,7 +1268,7 @@ def WP(self, *q, **kw): rays = rays + [v] w_c = w[:i] + w[i + 1:] cones = cones + [tuple(w_c)] - fan = Fan(cones,rays) + fan = Fan(cones, rays) return ToricVariety(fan, coordinate_names=names, base_ring=base_ring) def torus(self, n, names='z+', base_ring=QQ): @@ -1304,17 +1277,16 @@ def torus(self, n, names='z+', base_ring=QQ): INPUT: - - ``n`` -- non-negative integer. The dimension of the algebraic torus. + - ``n`` -- nonnegative integer. The dimension of the algebraic torus - - ``names`` -- string. Names for the homogeneous - coordinates. See - :func:`~sage.schemes.toric.variety.normalize_names` - for acceptable formats. + - ``names`` -- string; names for the homogeneous coordinates. See + :func:`~sage.schemes.toric.variety.normalize_names` for acceptable + formats. - - ``base_ring`` -- a ring (default: `\QQ`). The base ring for - the toric variety. + - ``base_ring`` -- a ring (default: `\QQ`); the base ring for + the toric variety - OUTPUT: A :class:`toric variety + OUTPUT: a :class:`toric variety `. EXAMPLES:: @@ -1340,7 +1312,7 @@ def torus(self, n, names='z+', base_ring=QQ): except TypeError: raise TypeError('dimension of the torus must be an integer') if n < 0: - raise ValueError('dimension must be non-negative') + raise ValueError('dimension must be nonnegative') N = ToricLattice(n) fan = Fan([], lattice=N) return ToricVariety(fan, coordinate_names=names, base_field=base_ring) diff --git a/src/sage/schemes/toric/meson.build b/src/sage/schemes/toric/meson.build new file mode 100644 index 00000000000..d9dea45fcc8 --- /dev/null +++ b/src/sage/schemes/toric/meson.build @@ -0,0 +1,32 @@ +py.install_sources( + 'all.py', + 'chow_group.py', + 'divisor.py', + 'fano_variety.py', + 'homset.py', + 'ideal.py', + 'library.py', + 'morphism.py', + 'points.py', + 'toric_subscheme.py', + 'variety.py', + 'weierstrass.py', + 'weierstrass_covering.py', + 'weierstrass_higher.py', + subdir: 'sage/schemes/toric', +) + +extension_data = {'divisor_class' : files('divisor_class.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/schemes/toric', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, gmp], + ) +endforeach + +install_subdir('sheaf', install_dir: sage_install_dir / 'schemes/toric') diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py old mode 100644 new mode 100755 index e95e071d864..f226aa61790 --- a/src/sage/schemes/toric/morphism.py +++ b/src/sage/schemes/toric/morphism.py @@ -35,7 +35,7 @@ is a functor from the category of fans and fan morphisms to the category of toric varieties and toric morphisms. -.. note:: +.. NOTE:: Do not create the toric morphisms (or any morphism of schemes) directly from the ``SchemeMorphism...`` classes. Instead, use the @@ -362,9 +362,7 @@ # the toric varieties level from Morphism. See # https://groups.google.com/d/msg/sage-devel/qF4yU6Vdmao/wQlNrneSmWAJ from sage.categories.morphism import Morphism - from sage.structure.richcmp import richcmp_not_equal, richcmp - from sage.structure.sequence import Sequence from sage.rings.integer_ring import ZZ from sage.arith.misc import GCD as gcd @@ -376,7 +374,6 @@ from sage.schemes.generic.scheme import Scheme from sage.schemes.generic.morphism import ( - is_SchemeMorphism, SchemeMorphism, SchemeMorphism_point, SchemeMorphism_polynomial ) @@ -398,14 +395,14 @@ class SchemeMorphism_point_toric_field(SchemeMorphism_point, Morphism): INPUT: - - ``X`` -- toric variety or subscheme of a toric variety. + - ``X`` -- toric variety or subscheme of a toric variety - - ``coordinates`` -- list of coordinates in the base field of ``X``. + - ``coordinates`` -- list of coordinates in the base field of ``X`` - ``check`` -- if ``True`` (default), the input will be checked for - correctness. + correctness - OUTPUT: A :class:`SchemeMorphism_point_toric_field`. + OUTPUT: a :class:`SchemeMorphism_point_toric_field` TESTS:: @@ -431,7 +428,7 @@ def __init__(self, X, coordinates, check=True): if check: # Verify that there are the right number of coords # Why is it not done in the parent? - if is_SchemeMorphism(coordinates): + if isinstance(coordinates, SchemeMorphism): coordinates = list(coordinates) if not isinstance(coordinates, (list, tuple)): raise TypeError("coordinates must be a scheme point, list, " @@ -466,7 +463,7 @@ class SchemeMorphism_polynomial_toric_variety(SchemeMorphism_polynomial, Morphis Same as for :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial`. - OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. + OUTPUT: a :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety` TESTS:: @@ -519,9 +516,9 @@ def as_fan_morphism(self): """ Express the morphism as a map defined by a fan morphism. - OUTPUT: A :class:`SchemeMorphism_polynomial_toric_variety`. + OUTPUT: a :class:`SchemeMorphism_polynomial_toric_variety` - This raises a :class:`TypeError` if the morphism cannot be written + This raises a :exc:`TypeError` if the morphism cannot be written in such a way. EXAMPLES:: @@ -547,11 +544,11 @@ class SchemeMorphism_orbit_closure_toric_variety(SchemeMorphism, Morphism): INPUT: - - ``parent`` -- the parent homset. + - ``parent`` -- the parent homset - - ``defining_cone`` -- the defining cone. + - ``defining_cone`` -- the defining cone - - ``ray_map`` -- a dictionary ``{ambient ray generator: orbit ray + - ``ray_map`` -- dictionary ``{ambient ray generator: orbit ray generator}``. Note that the image of the ambient ray generator is not necessarily primitive. @@ -605,7 +602,7 @@ def defining_cone(self): r""" Return the cone corresponding to the torus orbit. - OUTPUT: A cone of the fan of the ambient toric variety. + OUTPUT: a cone of the fan of the ambient toric variety EXAMPLES:: @@ -657,9 +654,7 @@ def _repr_defn(self): """ Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -679,11 +674,9 @@ def as_polynomial_map(self): """ Express the morphism via homogeneous polynomials. - OUTPUT: + OUTPUT: a :class:`SchemeMorphism_polynomial_toric_variety` - A :class:`SchemeMorphism_polynomial_toric_variety`. - - This raises a :class:`TypeError` if the morphism cannot be + This raises a :exc:`TypeError` if the morphism cannot be written in terms of homogeneous polynomials. The defining polynomials are not necessarily unique. There are @@ -737,7 +730,7 @@ def pullback_divisor(self, divisor): INPUT: - ``divisor`` -- a torus-invariant `\QQ`-Cartier divisor on the - codomain of the embedding map. + codomain of the embedding map OUTPUT: @@ -755,8 +748,8 @@ def pullback_divisor(self, divisor): sage: f.pullback_divisor(D) 4*V(z0) + 2*V(z1) """ - from sage.schemes.toric.divisor import is_ToricDivisor - if not (is_ToricDivisor(divisor) and divisor.is_QQ_Cartier()): + from sage.schemes.toric.divisor import ToricDivisor_generic + if not (isinstance(divisor, ToricDivisor_generic) and divisor.is_QQ_Cartier()): raise ValueError('the divisor must be torus-invariant and QQ-Cartier') m = divisor.m(self._defining_cone) values = [] @@ -772,7 +765,7 @@ def pullback_divisor(self, divisor): # A morphism of toric varieties determined by a fan morphism class SchemeMorphism_fan_toric_variety(SchemeMorphism, Morphism): """ - Construct a morphism determined by a fan morphism + Construct a morphism determined by a fan morphism. .. WARNING:: @@ -784,14 +777,14 @@ class SchemeMorphism_fan_toric_variety(SchemeMorphism, Morphism): INPUT: - - ``parent`` -- Hom-set whose domain and codomain are toric varieties. + - ``parent`` -- Hom-set whose domain and codomain are toric varieties - - ``fan_morphism`` -- A morphism of fans whose domain and codomain + - ``fan_morphism`` -- a morphism of fans whose domain and codomain fans equal the fans of the domain and codomain in the ``parent`` Hom-set. - - ``check`` -- boolean (default:``True``). Whether to - check the input for consistency. + - ``check`` -- boolean (default: ``True``); whether to + check the input for consistency .. WARNING:: @@ -803,7 +796,7 @@ class SchemeMorphism_fan_toric_variety(SchemeMorphism, Morphism): :class:`SchemeMorphism_fan_toric_variety_dominant` for additional functionality for fibrations. - OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety`. + OUTPUT: a :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety` EXAMPLES:: @@ -872,7 +865,7 @@ def _richcmp_(self, right, op): - ``right`` -- another toric morphism - OUTPUT: A boolean. + OUTPUT: boolean Comparison is done first by domain, then by codomain, then by fan morphism. @@ -911,9 +904,9 @@ def _composition_(self, right, homset): INPUT: - - ``right`` -- a toric morphism defined by a fan morphism. + - ``right`` -- a toric morphism defined by a fan morphism - OUTPUT: A toric morphism. + OUTPUT: a toric morphism EXAMPLES:: @@ -938,9 +931,7 @@ def _repr_defn(self): """ Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1050,7 +1041,7 @@ def fan_morphism(self): """ Return the defining fan morphism. - OUTPUT: A :class:`~sage.geometry.fan_morphism.FanMorphism`. + OUTPUT: a :class:`~sage.geometry.fan_morphism.FanMorphism` EXAMPLES:: @@ -1070,9 +1061,9 @@ def as_polynomial_map(self): """ Express the morphism via homogeneous polynomials. - OUTPUT: A :class:`SchemeMorphism_polynomial_toric_variety`. + OUTPUT: a :class:`SchemeMorphism_polynomial_toric_variety` - This raises a :class:`TypeError` if the morphism cannot be written + This raises a :exc:`TypeError` if the morphism cannot be written in terms of homogeneous polynomials. EXAMPLES:: @@ -1117,9 +1108,7 @@ def is_bundle(self): See :meth:`~sage.geometry.fan_morphism.FanMorphism.is_bundle` for fan morphisms for details. - OUTPUT: - - - ``True`` if ``self`` is a bundle, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is a bundle, ``False`` otherwise EXAMPLES:: @@ -1138,9 +1127,7 @@ def is_fibration(self): :meth:`~sage.geometry.fan_morphism.FanMorphism.is_fibration` for fan morphisms for details. - OUTPUT: - - - ``True`` if ``self`` is a fibration, ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is a fibration, ``False`` otherwise EXAMPLES:: @@ -1159,9 +1146,7 @@ def is_injective(self): :meth:`~sage.geometry.fan_morphism.FanMorphism.is_injective` for fan morphisms for a description of the toric algorithm. - OUTPUT: - - Boolean. Whether ``self`` is injective. + OUTPUT: boolean; whether ``self`` is injective EXAMPLES:: @@ -1191,9 +1176,7 @@ def is_surjective(self): :meth:`~sage.geometry.fan_morphism.FanMorphism.is_surjective` for fan morphisms for a description of the toric algorithm. - OUTPUT: - - Boolean. Whether ``self`` is surjective. + OUTPUT: boolean; whether ``self`` is surjective EXAMPLES:: @@ -1223,9 +1206,7 @@ def is_birational(self): :meth:`~sage.geometry.fan_morphism.FanMorphism.is_birational` for fan morphisms for a description of the toric algorithm. - OUTPUT: - - Boolean. Whether ``self`` is birational. + OUTPUT: boolean; whether ``self`` is birational EXAMPLES:: @@ -1251,9 +1232,7 @@ def is_dominant(self): :meth:`~sage.geometry.fan_morphism.FanMorphism.is_dominant` for fan morphisms for a description of the toric algorithm. - OUTPUT: - - Boolean. Whether ``self`` is a dominant scheme morphism. + OUTPUT: boolean; whether ``self`` is a dominant scheme morphism EXAMPLES:: @@ -1279,11 +1258,9 @@ def pullback_divisor(self, divisor): INPUT: - ``divisor`` -- a torus-invariant `\QQ`-Cartier divisor on the - codomain of ``self``. + codomain of ``self`` - OUTPUT: - - The pull-back divisor `f^*(D)`. + OUTPUT: the pull-back divisor `f^*(D)` EXAMPLES:: @@ -1300,8 +1277,8 @@ def pullback_divisor(self, divisor): sage: square.pullback_divisor(D) 2*V(z) """ - from sage.schemes.toric.divisor import is_ToricDivisor - if not (is_ToricDivisor(divisor) and divisor.is_QQ_Cartier()): + from sage.schemes.toric.divisor import ToricDivisor_generic + if not (isinstance(divisor, ToricDivisor_generic) and divisor.is_QQ_Cartier()): raise ValueError('the divisor must be torus-invariant and QQ-Cartier') fm = self.fan_morphism() values = [] @@ -1335,7 +1312,7 @@ class SchemeMorphism_fan_toric_variety_dominant(SchemeMorphism_fan_toric_variety morphism :meth:`must be dominant `. - OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety_dominant`. + OUTPUT: a :class:`~sage.schemes.toric.morphism.SchemeMorphism_fan_toric_variety_dominant` EXAMPLES:: @@ -1405,7 +1382,6 @@ def fiber_generic(self): (2-d affine toric variety, 1) sage: _[0].fan().generating_cones() (0-d cone of Rational polyhedral fan in Sublattice ,) - """ from sage.schemes.toric.variety import ToricVariety fm = self.fan_morphism() @@ -1422,10 +1398,10 @@ def fiber_component(self, domain_cone, multiplicity=False): INPUT: - - ``domain_cone`` -- a cone of the domain fan of ``self``. + - ``domain_cone`` -- a cone of the domain fan of ``self`` - - ``multiplicity`` (default: ``False``) -- whether to return the number - of fiber components corresponding to ``domain_cone`` as well. + - ``multiplicity`` -- boolean (default: ``False``); whether to return + the number of fiber components corresponding to ``domain_cone`` as well OUTPUT: @@ -1492,7 +1468,7 @@ def fiber_dimension(self, codomain_cone): INPUT: - ``codomain_cone`` -- a cone `\sigma` of the codomain, - specifying a torus orbit `O(\sigma)`. + specifying a torus orbit `O(\sigma)` OUTPUT: @@ -1550,7 +1526,7 @@ def fiber_graph(self, codomain_cone): INPUT: - ``codomain_cone`` -- a cone `\sigma` of the codomain, - specifying a torus orbit `O(\sigma)`. + specifying a torus orbit `O(\sigma)` OUTPUT: @@ -1632,13 +1608,13 @@ class SchemeMorphism_fan_fiber_component_toric_variety(SchemeMorphism): INPUT: - - ``toric_morphism`` -- a toric morphism. The toric morphism whose - fiber component we are describing. + - ``toric_morphism`` -- a toric morphism; the toric morphism whose + fiber component we are describing - ``defining_cone`` -- a cone of the fan of the domain of - ``toric_morphism``. See + ``toric_morphism``; see :meth:`~SchemeMorphism_fan_toric_variety_dominant.fiber_component` for - details. + details EXAMPLES:: @@ -1708,9 +1684,7 @@ def _repr_defn(self): """ Return a string representation of the definition of ``self``. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -1726,11 +1700,9 @@ def as_polynomial_map(self): """ Express the embedding morphism via homogeneous polynomials. - OUTPUT: - - A :class:`SchemeMorphism_polynomial_toric_variety`. + OUTPUT: a :class:`SchemeMorphism_polynomial_toric_variety` - This raises a :class:`ValueError` if the morphism cannot be + This raises a :exc:`ValueError` if the morphism cannot be written in terms of homogeneous polynomials. EXAMPLES:: @@ -1778,9 +1750,7 @@ def _make_fiber_component(self): """ Construct the fiber component as a toric variety. - OUTPUT: - - The fiber component as a toric variety. + OUTPUT: the fiber component as a toric variety EXAMPLES:: @@ -1854,9 +1824,7 @@ def defining_cone(self): r""" Return the cone corresponding to the fiber torus orbit. - OUTPUT: - - A cone of the fan of the total space of the toric fibration. + OUTPUT: a cone of the fan of the total space of the toric fibration EXAMPLES:: @@ -1879,9 +1847,7 @@ def base_cone(self): The fiber is constant over the base orbit closure `V(\sigma)`. - OUTPUT: - - A cone of the base of the toric fibration. + OUTPUT: a cone of the base of the toric fibration EXAMPLES:: @@ -1904,11 +1870,9 @@ def _image_ray_multiplicity(self, fiber_ray): INPUT: - A ray of the domain fan (the fiber component). - - OUTPUT: + - ``fiber_ray`` -- a ray of the domain fan (the fiber component) - A pair ``(codomain ray index, multiplicity)`` + OUTPUT: a pair ``(codomain ray index, multiplicity)`` EXAMPLES:: @@ -1955,7 +1919,7 @@ def pullback_divisor(self, divisor): INPUT: - ``divisor`` -- a torus-invariant `\QQ`-Cartier divisor on the - codomain of the embedding map. + codomain of the embedding map OUTPUT: @@ -1978,8 +1942,8 @@ def pullback_divisor(self, divisor): sage: fc.embedding_morphism().pullback_divisor(D) -V(z0) - 3*V(z1) - 3*V(z2) """ - from sage.schemes.toric.divisor import is_ToricDivisor - if not (is_ToricDivisor(divisor) and divisor.is_QQ_Cartier()): + from sage.schemes.toric.divisor import ToricDivisor_generic + if not (isinstance(divisor, ToricDivisor_generic) and divisor.is_QQ_Cartier()): raise ValueError('the divisor must be torus-invariant and QQ-Cartier') m = divisor.m(self.defining_cone()) values = [] diff --git a/src/sage/schemes/toric/points.py b/src/sage/schemes/toric/points.py old mode 100644 new mode 100755 index 799606a4d1f..ea2f09405a3 --- a/src/sage/schemes/toric/points.py +++ b/src/sage/schemes/toric/points.py @@ -52,10 +52,9 @@ def __init__(self, fan, ring): INPUT: - - ``fan`` -- fan of the toric variety. + - ``fan`` -- fan of the toric variety - - ``ring`` -- infinite base ring over which to enumerate - points. + - ``ring`` -- infinite base ring over which to enumerate points TESTS:: @@ -82,7 +81,7 @@ def __iter__(self): """ Iterate over the points. - OUTPUT: Iterator over points. + OUTPUT: iterator over points EXAMPLES:: @@ -115,9 +114,9 @@ def __init__(self, fan, ring): INPUT: - - ``fan`` -- fan of the toric variety. + - ``fan`` -- fan of the toric variety - - ``ring`` -- finite base ring over which to enumerate points. + - ``ring`` -- finite base ring over which to enumerate points EXAMPLES:: @@ -136,7 +135,7 @@ def rays(self): """ Return all rays (real and virtual). - OUTPUT: Tuple of rays of the fan. + OUTPUT: tuple of rays of the fan EXAMPLES:: @@ -170,15 +169,15 @@ def units(self): @cached_method def roots(self, n): """ - Return the n-th roots in the base field + Return the `n`-th roots in the base field. INPUT: - - ``n`` integer. + - ``n`` -- integer OUTPUT: - Tuple containing all n-th roots (not only the primitive + Tuple containing all `n`-th roots (not only the primitive ones). In particular, 1 is included. EXAMPLES:: @@ -196,7 +195,7 @@ def roots(self, n): def _Chow_group_free(self): r""" - Return the relations coming from the free part of the Chow group + Return the relations coming from the free part of the Chow group. OUTPUT: @@ -297,9 +296,7 @@ def orbit(self, point): """ Return the orbit of homogeneous coordinates under rescalings. - OUTPUT: - - The set of all homogeneous coordinates that are equivalent to ``point``. + OUTPUT: the set of all homogeneous coordinates that are equivalent to ``point`` EXAMPLES:: @@ -322,7 +319,7 @@ def orbit(self, point): def cone_iter(self): """ - Iterate over all cones of the fan + Iterate over all cones of the fan. OUTPUT: @@ -360,7 +357,7 @@ def coordinate_iter(self): This method does NOT identify homogeneous coordinates that are equivalent by a homogeneous rescaling. - OUTPUT: An iterator over the points. + OUTPUT: an iterator over the points EXAMPLES:: @@ -402,7 +399,7 @@ def __iter__(self): rescalings, and returns precisely one representative per orbit. - OUTPUT: An iterator over points. + OUTPUT: an iterator over points EXAMPLES:: @@ -435,7 +432,7 @@ def multiplicative_generator(self): """ Return the multiplicative generator of the finite field. - OUTPUT: A finite field element. + OUTPUT: a finite field element EXAMPLES:: @@ -457,9 +454,9 @@ def root_generator(self, n): INPUT: - - ``n`` integer. + - ``n`` -- integer - OUTPUT: A multiplicative generator for :meth:`roots`. + OUTPUT: a multiplicative generator for :meth:`roots` EXAMPLES:: @@ -490,7 +487,7 @@ def root_generator(self, n): def _Chow_group_free_generators(self): r""" - Return generators for :meth:`_Chow_group_free_generators` + Return generators for :meth:`_Chow_group_free_generators`. OUTPUT: @@ -519,7 +516,7 @@ def _Chow_group_free_generators(self): def _Chow_group_torsion_generators(self): r""" - Return generators for :meth:`Chow_group_torsion` + Return generators for :meth:`Chow_group_torsion`. OUTPUT: @@ -555,12 +552,12 @@ def _Chow_group_torsion_generators(self): def log(self, z): """ - Return the component-wise log of ``z`` + Return the component-wise log of ``z``. INPUT: - - ``z`` -- a list/tuple/iterable of non-zero finite field - elements. + - ``z`` -- list/tuple/iterable of nonzero finite field + elements OUTPUT: @@ -590,11 +587,11 @@ def log(self, z): def exp(self, powers): """ - Return the component-wise exp of ``z`` + Return the component-wise exp of ``z``. INPUT: - - ``powers`` -- a list/tuple/iterable of integers. + - ``powers`` -- list/tuple/iterable of integers OUTPUT: @@ -703,7 +700,7 @@ def __iter__(self): rescalings, and returns precisely one representative per orbit. - OUTPUT: Iterator over points. + OUTPUT: iterator over points EXAMPLES:: @@ -739,7 +736,7 @@ def cardinality(self): """ Return the cardinality of the point set. - OUTPUT: An integer. The number of points. + OUTPUT: integer; the number of points EXAMPLES:: @@ -764,10 +761,10 @@ def __init__(self, polynomials, ambient): INPUT: - - ``polynomials`` -- list/tuple/iterable of polynomials. The - defining polynomials. + - ``polynomials`` -- list/tuple/iterable of polynomials; the + defining polynomials - - ``ambient`` -- enumerator for ambient space points. + - ``ambient`` -- enumerator for ambient space points TESTS:: @@ -812,15 +809,15 @@ class FiniteFieldSubschemePointEnumerator(NaiveSubschemePointEnumerator): def inhomogeneous_equations(self, ring, nonzero_coordinates, cokernel): """ - Inhomogenize the defining polynomials + Inhomogenize the defining polynomials. INPUT: - ``ring`` -- the polynomial ring for inhomogeneous - coordinates. + coordinates - ``nonzero_coordinates`` -- list of integers. The indices of - the non-zero homogeneous coordinates in the patch. + the nonzero homogeneous coordinates in the patch - ``cokernel`` -- the logs of the nonzero coordinates of all distinct points as a cokernel. See @@ -888,7 +885,7 @@ def solutions_serial(self, inhomogeneous_equations, log_range): def solutions(self, inhomogeneous_equations, log_range): """ - Parallel version of :meth:`solutions_serial` + Parallel version of :meth:`solutions_serial`. INPUT/OUTPUT: @@ -925,22 +922,20 @@ def partial_solution(work_range): def homogeneous_coordinates(self, log_t, nonzero_coordinates, cokernel): """ - Convert the log of inhomogeneous coordinates back to homogeneous coordinates + Convert the log of inhomogeneous coordinates back to homogeneous coordinates. INPUT: - - ``log_t`` -- log of inhomogeneous coordinates of a point. + - ``log_t`` -- log of inhomogeneous coordinates of a point - ``nonzero_coordinates`` -- the nonzero homogeneous - coordinates in the patch. + coordinates in the patch - ``cokernel`` -- the logs of the nonzero coordinates of all distinct points as a cokernel. See :meth:`FiniteFieldPointEnumerator.cone_points_iter`. - OUTPUT: - - The same point, but as a tuple of homogeneous coordinates. + OUTPUT: the same point, but as a tuple of homogeneous coordinates EXAMPLES:: @@ -999,7 +994,7 @@ def cardinality(self): """ Return the cardinality of the point set. - OUTPUT: An integer. The number of points. + OUTPUT: integer; the number of points EXAMPLES:: diff --git a/src/sage/schemes/toric/sheaf/constructor.py b/src/sage/schemes/toric/sheaf/constructor.py old mode 100644 new mode 100755 index 3b23c4d9213..925451654ad --- a/src/sage/schemes/toric/sheaf/constructor.py +++ b/src/sage/schemes/toric/sheaf/constructor.py @@ -23,11 +23,9 @@ def TangentBundle(X): INPUT: - - ``X`` -- a toric variety. The base space of the bundle. + - ``X`` -- a toric variety; the base space of the bundle - OUTPUT: - - The tangent bundle as a Klyachko bundle. + OUTPUT: the tangent bundle as a Klyachko bundle EXAMPLES:: @@ -55,11 +53,9 @@ def CotangentBundle(X): INPUT: - - ``X`` -- a toric variety. The base space of the bundle. - - OUTPUT: + - ``X`` -- a toric variety; the base space of the bundle - The cotangent bundle as a Klyachko bundle. + OUTPUT: the cotangent bundle as a Klyachko bundle EXAMPLES:: @@ -77,13 +73,11 @@ def TrivialBundle(X, rank=1): INPUT: - - ``X`` -- a toric variety. The base space of the bundle. + - ``X`` -- a toric variety; the base space of the bundle - - ``rank`` -- the rank of the bundle. + - ``rank`` -- the rank of the bundle - OUTPUT: - - The trivial bundle as a Klyachko bundle. + OUTPUT: the trivial bundle as a Klyachko bundle EXAMPLES:: @@ -110,9 +104,9 @@ def LineBundle(X, D): INPUT: - - ``X`` -- a toric variety. The base space of the bundle. + - ``X`` -- a toric variety; the base space of the bundle - - ``D`` -- a toric divisor. + - ``D`` -- a toric divisor OUTPUT: @@ -162,9 +156,7 @@ def __repr__(self): """ Return a string representation. - OUTPUT: - - String. + OUTPUT: string EXAMPLES:: @@ -179,12 +171,9 @@ def trivial_bundle(self, rank=1): INPUT: - - ``rank`` -- integer (optional; default: `1`). The rank of - the bundle. + - ``rank`` -- integer (default: `1`); the rank of the bundle - OUTPUT: - - The trivial bundle as a Klyachko bundle. + OUTPUT: the trivial bundle as a Klyachko bundle EXAMPLES:: @@ -202,7 +191,7 @@ def line_bundle(self, divisor): INPUT: - - ``divisor`` -- a toric divisor. + - ``divisor`` -- a toric divisor OUTPUT: @@ -223,9 +212,7 @@ def tangent_bundle(self): r""" Return the tangent bundle of the toric variety. - OUTPUT: - - The tangent bundle as a Klyachko bundle. + OUTPUT: the tangent bundle as a Klyachko bundle EXAMPLES:: @@ -238,9 +225,7 @@ def cotangent_bundle(self): r""" Return the cotangent bundle of the toric variety. - OUTPUT: - - The cotangent bundle as a Klyachko bundle. + OUTPUT: the cotangent bundle as a Klyachko bundle EXAMPLES:: @@ -301,9 +286,7 @@ def divisor(self, *args, **kwds): By abuse of notation, you can usually use the divisor `D` interchangeably with the line bundle `O(D)`. - OUTPUT: - - A toric divisor. + OUTPUT: a toric divisor EXAMPLES:: diff --git a/src/sage/schemes/toric/sheaf/klyachko.py b/src/sage/schemes/toric/sheaf/klyachko.py old mode 100644 new mode 100755 index b6c7147140c..a2e80dd7fa6 --- a/src/sage/schemes/toric/sheaf/klyachko.py +++ b/src/sage/schemes/toric/sheaf/klyachko.py @@ -57,13 +57,13 @@ def is_KlyachkoBundle(X): """ - Test whether ``X`` is a Klyachko bundle + Test whether ``X`` is a Klyachko bundle. INPUT: - - ``X`` -- anything. + - ``X`` -- anything - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -81,11 +81,11 @@ def is_KlyachkoBundle(X): def Bundle(toric_variety, multi_filtration, check=True): r""" - Construct a Klyacho bundle + Construct a Klyacho bundle. INPUT: - - ``toric_variety`` -- a toric variety. The base space of the bundle. + - ``toric_variety`` -- a toric variety; the base space of the bundle - ``multi_filtration`` -- a multi-filtered vectors space with multiple filtrations being indexed by the one-dimensional cones @@ -147,14 +147,14 @@ def __init__(self, toric_variety, multi_filtration, check=True): INPUT: - - ``toric_variety`` -- a toric variety. The base space of the bundle. + - ``toric_variety`` -- a toric variety; the base space of the bundle - ``multi_filtration`` -- a :func:`~sage.modules.multi_filtered_vector_space.MultiFilteredVectorSpace` with index set the rays of the fan. - - ``check`` -- boolean (default: ``True``). Whether to perform - consistency checks. + - ``check`` -- boolean (default: ``True``); whether to perform + consistency checks EXAMPLES:: @@ -187,7 +187,7 @@ def variety(self): r""" Return the base toric variety. - OUTPUT: A toric variety. + OUTPUT: a toric variety EXAMPLES:: @@ -203,7 +203,7 @@ def base_ring(self): r""" Return the base field. - OUTPUT: A field. + OUTPUT: a field EXAMPLES:: @@ -217,7 +217,7 @@ def fiber(self): r""" Return the generic fiber of the vector bundle. - OUTPUT: A vector space over :meth:`base_ring`. + OUTPUT: a vector space over :meth:`base_ring` EXAMPLES:: @@ -232,7 +232,7 @@ def rank(self): r""" Return the rank of the vector bundle. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -246,7 +246,7 @@ def _repr_(self): r""" Return a string representation. - OUTPUT: A string. + OUTPUT: string EXAMPLES:: @@ -262,7 +262,7 @@ def get_filtration(self, ray=None): INPUT: - - ``ray`` -- Integer, a `N`-lattice point, a one-dimensional + - ``ray`` -- integer; a `N`-lattice point, a one-dimensional cone, or ``None`` (default). Specifies a ray of the fan of the toric variety, either via its index or its generator. @@ -309,11 +309,11 @@ def get_degree(self, ray, i): r""" Return the vector subspace ``E^\alpha(i)``. - - ``ray`` -- Integer, a `N`-lattice point, a one-dimensional + - ``ray`` -- integer; a `N`-lattice point, a one-dimensional cone, or ``None`` (default). Specifies a ray of the fan of the toric variety, either via its index or its generator. - - ``i`` -- integer. The filtration degree. + - ``i`` -- integer; the filtration degree OUTPUT: @@ -335,9 +335,9 @@ def filtration_intersection(self, sigma, i): INPUT: - - ``sigma`` -- a cone of the fan of the base toric variety. + - ``sigma`` -- a cone of the fan of the base toric variety - - ``i`` -- integer. The filtration degree. + - ``i`` -- integer; the filtration degree OUTPUT: @@ -424,12 +424,12 @@ def E_intersection(self, sigma, m): INPUT: - - ``sigma`` -- a cone of the fan of the base toric variety. + - ``sigma`` -- a cone of the fan of the base toric variety - ``m`` -- tuple of integers or `M`-lattice point. A point in the dual lattice of the fan. Must be immutable. - OUTPUT: The subspace `E^\sigma(m)`. + OUTPUT: the subspace `E^\sigma(m)`. EXAMPLES:: @@ -463,12 +463,12 @@ def E_quotient(self, sigma, m): INPUT: - - ``sigma`` -- a cone of the fan of the base toric variety. + - ``sigma`` -- a cone of the fan of the base toric variety - ``m`` -- tuple of integers or `M`-lattice point. A point in the dual lattice of the fan. Must be immutable. - OUTPUT: The subspace `E_\sigma(m)`. + OUTPUT: the subspace `E_\sigma(m)`. EXAMPLES:: @@ -507,16 +507,14 @@ def E_quotient_projection(self, sigma, tau, m): INPUT: - - ``sigma`` -- a cone of the fan of the base toric variety. + - ``sigma`` -- a cone of the fan of the base toric variety - - ``tau`` -- a cone of the fan containing ``sigma``. + - ``tau`` -- a cone of the fan containing ``sigma`` - ``m`` -- tuple of integers or `M`-lattice point. A point in the dual lattice of the fan. Must be immutable. - OUTPUT: - - The restriction map + OUTPUT: the restriction map .. MATH:: @@ -567,7 +565,7 @@ def E_quotient_projection(self, sigma, tau, m): def cohomology_complex(self, m): r""" - Return the "cohomology complex" `C^*(m)` + Return the "cohomology complex" `C^*(m)`. See [Kly1990]_, equation 4.2. @@ -607,7 +605,7 @@ def cohomology_complex(self, m): C = fan.complex() CV = [] F = self.base_ring() - for dim in range(1,fan.dim()+1): + for dim in range(1, fan.dim()+1): codim = fan.dim() - dim d_C = C.differential(codim) d_V = [] @@ -618,7 +616,7 @@ def cohomology_complex(self, m): sigma = fan(dim-1)[i] if sigma.is_face_of(tau): pr = self.E_quotient_projection(sigma, tau, m) - d = d_C[i,j] * pr.matrix().transpose() + d = d_C[i, j] * pr.matrix().transpose() else: E_sigma = self.E_quotient(sigma, m) E_tau = self.E_quotient(tau, m) @@ -636,16 +634,16 @@ def cohomology(self, degree=None, weight=None, dim=False): INPUT: - - ``degree`` -- ``None`` (default) or an integer. The degree of - the cohomology group. + - ``degree`` -- ``None`` (default) or an integer; the degree of + the cohomology group - ``weight`` -- ``None`` (default) or a tuple of integers or a `M`-lattice point. A point in the dual lattice of the fan defining a torus character. The weight of the cohomology group. - - ``dim`` -- Boolean (default: ``False``). Whether to return - vector spaces or only their dimension. + - ``dim`` -- boolean (default: ``False``); whether to return + vector spaces or only their dimension OUTPUT: @@ -697,7 +695,7 @@ def cohomology(self, degree=None, weight=None, dim=False): except KeyError: HH[d] = FreeModule(self.base_ring(), 0) if dim: - HH = vector(ZZ, [HH[i].rank() for i in range(space_dim+1) ]) + HH = vector(ZZ, [HH[i].rank() for i in range(space_dim+1)]) return HH def __richcmp__(self, other, op): @@ -712,9 +710,9 @@ def __richcmp__(self, other, op): INPUT: - - ``other`` -- anything. + - ``other`` -- anything - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -747,9 +745,9 @@ def is_isomorphic(self, other): INPUT: - - ``other`` -- anything. + - ``other`` -- anything - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -771,9 +769,9 @@ def direct_sum(self, other): INPUT: - - ``other`` -- a Klyachko bundle over the same base. + - ``other`` -- a Klyachko bundle over the same base - OUTPUT: The direct sum as a new Klyachko bundle. + OUTPUT: the direct sum as a new Klyachko bundle EXAMPLES:: @@ -801,9 +799,9 @@ def tensor_product(self, other): INPUT: - - ``other`` -- a Klyachko bundle over the same base. + - ``other`` -- a Klyachko bundle over the same base - OUTPUT: The tensor product as a new Klyachko bundle. + OUTPUT: the tensor product as a new Klyachko bundle EXAMPLES:: @@ -827,7 +825,7 @@ def exterior_power(self, n): INPUT: - - ``n`` -- integer. + - ``n`` -- integer OUTPUT: @@ -855,9 +853,9 @@ def symmetric_power(self, n): INPUT: - - ``n`` -- integer. + - ``n`` -- integer - OUTPUT: The `n`-th symmetric power as a new Klyachko bundle. + OUTPUT: the `n`-th symmetric power as a new Klyachko bundle EXAMPLES:: @@ -876,7 +874,7 @@ def dual(self): """ Return the dual bundle. - OUTPUT: The dual bundle as a new Klyachko bundle. + OUTPUT: the dual bundle as a new Klyachko bundle EXAMPLES:: @@ -897,8 +895,8 @@ def random_deformation(self, epsilon=None): INPUT: - - ``epsilon`` -- an element of the base ring. Scales the - random deformation. + - ``epsilon`` -- an element of the base ring; scales the + random deformation OUTPUT: diff --git a/src/sage/schemes/toric/toric_subscheme.py b/src/sage/schemes/toric/toric_subscheme.py old mode 100644 new mode 100755 index cddcc91f474..908ef979984 --- a/src/sage/schemes/toric/toric_subscheme.py +++ b/src/sage/schemes/toric/toric_subscheme.py @@ -20,10 +20,12 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.calculus.functions import jacobian +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme +lazy_import("sage.calculus.functions", "jacobian") + class AlgebraicScheme_subscheme_toric(AlgebraicScheme_subscheme): r""" @@ -39,12 +41,12 @@ class AlgebraicScheme_subscheme_toric(AlgebraicScheme_subscheme): INPUT: - ``toric_variety`` -- ambient :class:`toric variety - `. + ` - ``polynomials`` -- single polynomial, list, or ideal of defining - polynomials in the coordinate ring of ``toric_variety``. + polynomials in the coordinate ring of ``toric_variety`` - OUTPUT: An :class:`algebraic subscheme of a toric variety + OUTPUT: an :class:`algebraic subscheme of a toric variety `. TESTS:: @@ -104,7 +106,7 @@ def _morphism(self, *args, **kwds): - same as for :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. - OUTPUT: A :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety`. + OUTPUT: a :class:`~sage.schemes.toric.morphism.SchemeMorphism_polynomial_toric_variety` TESTS:: @@ -144,7 +146,7 @@ def _point_homset(self, *args, **kwds): - same as for :class:`~sage.schemes.toric.homset.SchemeHomset_points_toric_field`. - OUTPUT: A :class:`~sage.schemes.toric.homset.SchemeHomset_points_subscheme_toric_field`. + OUTPUT: a :class:`~sage.schemes.toric.homset.SchemeHomset_points_subscheme_toric_field` TESTS:: @@ -164,7 +166,7 @@ def fan(self): """ Return the fan of the ambient space. - OUTPUT: A fan. + OUTPUT: a fan EXAMPLES:: @@ -182,8 +184,8 @@ def affine_patch(self, i): INPUT: - - ``i`` -- integer, index of a generating cone of the fan of the - ambient space of ``self``. + - ``i`` -- integer; index of a generating cone of the fan of the + ambient space of ``self`` OUTPUT: @@ -326,14 +328,14 @@ def pullback_polynomial(p): result = R.zero() for coefficient, monomial in p: exponent = monomial.exponents()[0] - exponent = [ exponent[i] for i in cone.ambient_ray_indices() ] - exponent = vector(ZZ,exponent) + exponent = [exponent[i] for i in cone.ambient_ray_indices()] + exponent = vector(ZZ, exponent) m = n_rho_matrix.solve_right(exponent) assert all(x in ZZ for x in m), \ - 'The polynomial '+str(p)+' does not define a ZZ-divisor!' + f'The polynomial {p} does not define a ZZ-divisor!' m_coeffs = dualcone.Hilbert_coefficients(m) result += coefficient * prod(R.gen(i)**m_coeffs[i] - for i in range(0,R.ngens())) + for i in range(R.ngens())) return result # construct the affine algebraic scheme to use as patch @@ -351,7 +353,7 @@ def pullback_polynomial(p): if cone.is_smooth(): x = ambient.coordinate_ring().gens() phi = [] - for i in range(0,fan.nrays()): + for i in range(fan.nrays()): if i in cone.ambient_ray_indices(): phi.append(pullback_polynomial(x[i])) else: @@ -369,11 +371,10 @@ def pullback_polynomial(p): # it remains to find the preimage of point # map m to the monomial x^{D_m}, see reference. F = ambient.coordinate_ring().fraction_field() - image = [] - for m in dualcone.Hilbert_basis(): - x_Dm = prod([ F.gen(i)**(m*n) for i,n in enumerate(fan.rays()) ]) - image.append(x_Dm) - patch._embedding_center = tuple( f(list(point)) for f in image ) + image = [prod([F.gen(i)**(m * n) + for i, n in enumerate(fan.rays())]) + for m in dualcone.Hilbert_basis()] + patch._embedding_center = tuple(f(list(point)) for f in image) return patch def _best_affine_patch(self, point): @@ -382,11 +383,9 @@ def _best_affine_patch(self, point): INPUT: - - ``point`` -- a point of the algebraic subscheme. - - OUTPUT: + - ``point`` -- a point of the algebraic subscheme - Integer. The index of the patch. See :meth:`affine_patch`. + OUTPUT: integer. The index of the patch. See :meth:`affine_patch` EXAMPLES:: @@ -414,7 +413,7 @@ def neighborhood(self, point): INPUT: - - ``point`` -- a point of the toric algebraic scheme. + - ``point`` -- a point of the toric algebraic scheme OUTPUT: @@ -487,14 +486,14 @@ def neighborhood(self, point): phi_reduced = [S(t) for t in phi] patch._embedding_center = patch(point_preimage) - patch._embedding_morphism = patch.hom(phi_reduced,self) + patch._embedding_morphism = patch.hom(phi_reduced, self) return patch def dimension(self): """ Return the dimension of ``self``. - OUTPUT: An integer. If ``self`` is empty, `-1` is returned. + OUTPUT: integer; if ``self`` is empty, `-1` is returned EXAMPLES:: @@ -513,7 +512,7 @@ def dimension(self): if '_dimension' in self.__dict__: return self._dimension npatches = self.ambient_space().fan().ngenerating_cones() - dims = [ self.affine_patch(i).dimension() for i in range(0,npatches) ] + dims = [self.affine_patch(i).dimension() for i in range(npatches)] self._dimension = max(dims) return self._dimension @@ -523,12 +522,12 @@ def is_smooth(self, point=None): INPUT: - - ``point`` -- A point or ``None`` (default). The point to - test smoothness at. + - ``point`` -- a point or ``None`` (default); the point to + test smoothness at OUTPUT: - Boolean. If no point was specified, returns whether the + boolean; if no point was specified, returns whether the algebraic subscheme is smooth everywhere. Otherwise, smoothness at the specified point is tested. @@ -582,7 +581,8 @@ def is_smooth(self, point=None): if '_smooth' in self.__dict__: return self._smooth npatches = self.ambient_space().fan().ngenerating_cones() - self._smooth = all(self.affine_patch(i).is_smooth() for i in range(0,npatches)) + self._smooth = all(self.affine_patch(i).is_smooth() + for i in range(npatches)) return self._smooth def is_nondegenerate(self): @@ -665,7 +665,6 @@ def is_nondegenerate(self): False sage: P2.subscheme([x]).is_nondegenerate() False - """ X = self.ambient_space() fan = X.fan() @@ -693,7 +692,7 @@ def restrict(cone): enumerate(SR.subs(divide).gens())]) return ideal, Jac_patch + SR_patch - for dim in range(0, fan.dim() + 1): + for dim in range(fan.dim() + 1): for cone in fan(dim): ideal1, ideal2 = restrict(cone) if ideal1.is_zero() or ideal2.dimension() != -1: @@ -716,7 +715,6 @@ def is_schon(self): True sage: X.is_schon() False - """ return self.is_nondegenerate() @@ -735,10 +733,10 @@ class AlgebraicScheme_subscheme_affine_toric(AlgebraicScheme_subscheme_toric): INPUT: - ``toric_variety`` -- ambient :class:`affine toric variety - `; + ` - ``polynomials`` -- single polynomial, list, or ideal of defining - polynomials in the coordinate ring of ``toric_variety``. + polynomials in the coordinate ring of ``toric_variety`` OUTPUT: @@ -794,7 +792,7 @@ def dimension(self): """ Return the dimension of ``self``. - OUTPUT: An integer. + OUTPUT: integer EXAMPLES:: @@ -833,12 +831,12 @@ def is_smooth(self, point=None): INPUT: - - ``point`` -- A point or ``None`` (default). The point to - test smoothness at. + - ``point`` -- a point or ``None`` (default); the point to + test smoothness at OUTPUT: - Boolean. If no point was specified, returns whether the + boolean; if no point was specified, returns whether the algebraic subscheme is smooth everywhere. Otherwise, smoothness at the specified point is tested. diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py old mode 100644 new mode 100755 index c1ca8351263..2bc696b4183 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -236,6 +236,7 @@ Every cone defines a torus orbit closure, and hence a (co)homology class:: + sage: # needs sage.libs.singular sage: HH.gens() ([3*z4], [3*z4], [z4], [z4], [z4]) sage: list(map(HH, P4_11133.fan(1))) @@ -248,6 +249,7 @@ We can compute intersection numbers by integrating top-dimensional cohomology classes:: + sage: # needs sage.libs.singular sage: D = P4_11133.divisor(0) sage: HH(D) [3*z4] @@ -261,12 +263,14 @@ sage: AA = P4_11133.Chow_group(QQ) sage: list(map(AA, P4_11133.fan(1))) # long time (5s on sage.math, 2012) - [( 0 | 0 | 0 | 3 | 0 ), ( 0 | 0 | 0 | 3 | 0 ), ( 0 | 0 | 0 | 1 | 0 ), ( 0 | 0 | 0 | 1 | 0 ), ( 0 | 0 | 0 | 1 | 0 )] + [( 0 | 0 | 0 | 3 | 0 ), ( 0 | 0 | 0 | 3 | 0 ), + ( 0 | 0 | 0 | 1 | 0 ), ( 0 | 0 | 0 | 1 | 0 ), ( 0 | 0 | 0 | 1 | 0 )] sage: list(map(AA, P4_11133.fan(4))) # long time (5s on sage.math, 2012) - [( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 )] - sage: AA(cone).intersection_with_divisor(D) # long time (4s on sage.math, 2013) + [( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), + ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 )] + sage: AA(cone).intersection_with_divisor(D) # long time (4s on sage.math, 2013) # needs sage.libs.singular ( 1 | 0 | 0 | 0 | 0 ) - sage: AA(cone).intersection_with_divisor(D).count_points() # long time + sage: AA(cone).intersection_with_divisor(D).count_points() # long time # needs sage.libs.singular 1 The real advantage of the Chow group is that @@ -302,25 +306,29 @@ import sys -from sage.functions.all import factorial import sage.geometry.abc + +from sage.categories.fields import Fields from sage.geometry.cone import Cone from sage.geometry.fan import Fan +from sage.misc.cachefunc import cached_method from sage.misc.latex import latex +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod -from sage.misc.cachefunc import cached_method -from sage.structure.unique_representation import UniqueRepresentation from sage.modules.free_module_element import vector -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ -from sage.rings.quotient_ring_element import QuotientRingElement +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.quotient_ring import QuotientRing_generic +from sage.rings.quotient_ring_element import QuotientRingElement +from sage.rings.rational_field import QQ from sage.schemes.affine.affine_space import AffineSpace from sage.schemes.generic.ambient_space import AmbientSpace from sage.schemes.toric.homset import SchemeHomset_points_toric_field from sage.structure.category_object import certify_names -from sage.categories.fields import Fields +from sage.structure.unique_representation import UniqueRepresentation + +lazy_import("sage.functions.all", "factorial") + _Fields = Fields() @@ -334,7 +342,7 @@ def is_ToricVariety(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: @@ -380,27 +388,27 @@ def ToricVariety(fan, INPUT: - ``fan`` -- :class:`rational polyhedral fan - `; + ` - ``coordinate_names`` -- names of variables for the coordinate ring, see :func:`normalize_names` for acceptable formats. If not given, indexed - variable names will be created automatically; + variable names will be created automatically. - ``names`` -- an alias of ``coordinate_names`` for internal use. You may specify either ``names`` or ``coordinate_names``, - but not both; + but not both. - ``coordinate_indices`` -- list of integers, indices for indexed variables. If not given, the index of each variable will coincide with - the index of the corresponding ray of the fan; + the index of the corresponding ray of the fan. - ``base_ring`` -- base ring of the toric variety (default: - `\QQ`). Must be a field. + `\QQ`); must be a field - - ``base_field`` -- alias for ``base_ring``. Takes precedence if - both are specified. + - ``base_field`` -- alias for ``base_ring``; takes precedence if + both are specified - OUTPUT: A :class:`toric variety `. + OUTPUT: a :class:`toric variety ` EXAMPLES: @@ -470,13 +478,13 @@ def AffineToricVariety(cone, *args, **kwds): INPUT: - ``cone`` -- :class:`strictly convex rational polyhedral cone - `. + ` This cone will be used to construct a :class:`rational polyhedral fan `, which will be passed to :func:`ToricVariety` with the rest of positional and keyword arguments. - OUTPUT: A :class:`toric variety `. + OUTPUT: a :class:`toric variety ` .. NOTE:: @@ -521,19 +529,19 @@ class ToricVariety_field(AmbientSpace): INPUT: - ``fan`` -- :class:`rational polyhedral fan - `; + ` - ``coordinate_names`` -- names of variables, see :func:`normalize_names` for acceptable formats. If ``None``, indexed variable names will be - created automatically; + created automatically. - ``coordinate_indices`` -- list of integers, indices for indexed variables. If ``None``, the index of each variable will coincide with - the index of the corresponding ray of the fan; + the index of the corresponding ray of the fan. - - ``base_field`` -- base field of the toric variety. + - ``base_field`` -- base field of the toric variety - OUTPUT: A :class:`toric variety `. + OUTPUT: a :class:`toric variety ` TESTS:: @@ -568,7 +576,7 @@ def __eq__(self, right): - ``right`` -- anything - OUTPUT: A boolean. + OUTPUT: boolean ``True`` if and only if ``right`` is of the same type as ``self``, their fans are the same, names of variables are the same and @@ -604,7 +612,7 @@ def __ne__(self, other): - ``other`` -- anything - OUTPUT: A boolean. + OUTPUT: boolean ``True`` if and only if ``other`` is of the same type as ``self``, their fans are the same, names of variables are the same and @@ -648,9 +656,7 @@ def _an_element_(self): This function is needed (in particular) for the test framework. - OUTPUT: - - - a point of ``self`` with coordinates [1 : 2: ... : n]. + OUTPUT: a point of ``self`` with coordinates [1 : 2: ... : n] TESTS:: @@ -666,12 +672,12 @@ def _check_satisfies_equations(self, coordinates): INPUT: - - ``coordinates`` -- list of elements of the base field of ``self``. + - ``coordinates`` -- list of elements of the base field of ``self`` OUTPUT: - ``True`` if ``coordinates`` do define a valid point of ``self``, - otherwise a :class:`TypeError` or :class:`ValueError` exception + otherwise a :exc:`TypeError` or :exc:`ValueError` exception is raised. TESTS:: @@ -760,9 +766,7 @@ def _latex_(self): r""" Return a LaTeX representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -778,12 +782,10 @@ def _latex_generic_point(self, coordinates=None): INPUT: - - ``coordinates`` -- list of coordinates of a point of ``self``. - If not given, names of coordinates of ``self`` will be used. - - OUTPUT: + - ``coordinates`` -- list of coordinates of a point of ``self``; + if not given, names of coordinates of ``self`` will be used - string. + OUTPUT: string EXAMPLES:: @@ -807,9 +809,7 @@ def _point(self, *args, **kwds): - same as for :class:`~sage.schemes.generic.morphism.SchemeMorphism_point_toric_field`. - OUTPUT: - - :class:`~sage.schemes.generic.morphism.SchemeMorphism_point_toric_field`. + OUTPUT: :class:`~sage.schemes.generic.morphism.SchemeMorphism_point_toric_field` TESTS:: @@ -828,9 +828,7 @@ def _homset(self, *args, **kwds): Same as :class:`sage.schemes.generic.homset.SchemeHomset_generic`. - OUTPUT: - - A :class:`sage.schemes.toric.homset.SchemeHomset_toric_variety`. + OUTPUT: a :class:`sage.schemes.toric.homset.SchemeHomset_toric_variety` EXAMPLES:: @@ -874,9 +872,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - - string. + OUTPUT: string TESTS:: @@ -898,12 +894,10 @@ def _repr_generic_point(self, coordinates=None): INPUT: - - ``coordinates`` -- list of coordinates of a point of ``self``. - If not given, names of coordinates of ``self`` will be used. + - ``coordinates`` -- list of coordinates of a point of ``self``; + if not given, names of coordinates of ``self`` will be used - OUTPUT: - - - string. + OUTPUT: string EXAMPLES:: @@ -927,13 +921,13 @@ def _validate(self, polynomials): INPUT: - ``polynomials`` -- list of polynomials in the coordinate ring of - ``self`` (this function does not perform any conversions). + ``self`` (this function does not perform any conversions) OUTPUT: - - ``polynomials`` (the input parameter without any modifications) if + - ``polynomials`` -- the input parameter without any modifications if ``polynomials`` do define valid polynomial functions on ``self``, - otherwise a :class:`ValueError` exception is raised. + otherwise a :exc:`ValueError` exception is raised. TESTS: @@ -962,7 +956,7 @@ def affine_patch(self, i): INPUT: - - ``i`` -- integer, index of a generating cone of the fan of ``self``. + - ``i`` -- integer; index of a generating cone of the fan of ``self`` OUTPUT: @@ -1027,9 +1021,9 @@ def change_ring(self, F): INPUT: - - ``F`` -- field. + - ``F`` -- field - OUTPUT: :class:`toric variety ` over ``F``. + OUTPUT: :class:`toric variety ` over ``F`` .. NOTE:: @@ -1076,7 +1070,7 @@ def coordinate_ring(self): For toric varieties this is the homogeneous coordinate ring (a.k.a. Cox's ring and total ring). - OUTPUT: A polynomial ring. + OUTPUT: a polynomial ring EXAMPLES:: @@ -1108,7 +1102,7 @@ def embedding_morphism(self): - :class:`scheme morphism ` if the default embedding morphism was defined for ``self``, - otherwise a :class:`ValueError` exception is raised. + otherwise a :exc:`ValueError` exception is raised. EXAMPLES:: @@ -1139,9 +1133,9 @@ def fan(self, dim=None, codim=None): INPUT: - - ``dim`` -- dimension of the requested cones; + - ``dim`` -- dimension of the requested cones - - ``codim`` -- codimension of the requested cones. + - ``codim`` -- codimension of the requested cones OUTPUT: @@ -1173,12 +1167,12 @@ def inject_coefficients(self, scope=None, verbose=True): INPUT: - ``scope`` -- namespace (default: global, not just the scope from - which this function was called); + which this function was called) - ``verbose`` -- if ``True`` (default), names of injected generators - will be printed. + will be printed - OUTPUT: None. + OUTPUT: none EXAMPLES:: @@ -1248,11 +1242,9 @@ def is_homogeneous(self, polynomial): INPUT: - ``polynomial`` -- polynomial in the coordinate ring of ``self`` or - its quotient. - - OUTPUT: + its quotient - - ``True`` if ``polynomial`` is homogeneous and ``False`` otherwise. + OUTPUT: ``True`` if ``polynomial`` is homogeneous and ``False`` otherwise EXAMPLES: @@ -1321,7 +1313,7 @@ def is_isomorphic(self, another): INPUT: - - ``another`` -- :class:`toric variety `. + - ``another`` -- :class:`toric variety ` OUTPUT: @@ -1358,7 +1350,7 @@ def is_affine(self): face lattice of a single cone. See also :func:`AffineToricVariety`. - OUTPUT: A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1373,9 +1365,7 @@ def is_complete(self): r""" Check if ``self`` is complete. - OUTPUT: - - - ``True`` if ``self`` is complete and ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is complete and ``False`` otherwise EXAMPLES:: @@ -1418,9 +1408,7 @@ def is_smooth(self): r""" Check if ``self`` is smooth. - OUTPUT: - - - ``True`` if ``self`` is smooth and ``False`` otherwise. + OUTPUT: ``True`` if ``self`` is smooth and ``False`` otherwise EXAMPLES:: @@ -1440,7 +1428,7 @@ def Kaehler_cone(self): r""" Return the closure of the Kähler cone of ``self``. - OUTPUT: :class:`cone `. + OUTPUT: :class:`cone ` .. NOTE:: @@ -1485,7 +1473,7 @@ def Mori_cone(self): r""" Return the Mori cone of ``self``. - OUTPUT: :class:`cone `. + OUTPUT: :class:`cone ` .. NOTE:: @@ -1532,7 +1520,7 @@ def plot(self, **options): - any options for toric plots (see :func:`toric_plotter.options `), none are mandatory. - OUTPUT: A plot. + OUTPUT: a plot .. NOTE:: @@ -1597,10 +1585,10 @@ def Chow_group(self, base_ring=ZZ): INPUT: - - ``base_ring`` -- either ``ZZ`` (default) or ``QQ``. The - coefficient ring of the Chow group. + - ``base_ring`` -- either ``ZZ`` (default) or ``QQ``; the + coefficient ring of the Chow group - OUTPUT: A :class:`sage.schemes.toric.chow_group.ChowGroup_class`. + OUTPUT: a :class:`sage.schemes.toric.chow_group.ChowGroup_class` EXAMPLES:: @@ -1619,17 +1607,17 @@ def cartesian_product(self, other, INPUT: - - ``other`` -- a :class:`toric variety `; + - ``other`` -- a :class:`toric variety ` - ``coordinate_names`` -- names of variables for the coordinate ring, see :func:`normalize_names` for acceptable formats. If not given, - indexed variable names will be created automatically; + indexed variable names will be created automatically. - ``coordinate_indices`` -- list of integers, indices for indexed variables. If not given, the index of each variable will coincide with the index of the corresponding ray of the fan. - OUTPUT: A :class:`toric variety `. + OUTPUT: a :class:`toric variety ` EXAMPLES:: @@ -1661,10 +1649,10 @@ def resolve(self, **kwds): - ``coordinate_names`` -- names for coordinates of the new variety. If not given, will be constructed from the coordinate names of ``self`` and necessary indexed ones. See :func:`normalize_names` for the - description of acceptable formats; + description of acceptable formats. - ``coordinate_indices`` -- coordinate indices which should be used - for indexed variables of the new variety; + for indexed variables of the new variety - all other arguments will be passed to :meth:`~sage.geometry.fan.RationalPolyhedralFan.subdivide` method of @@ -1672,7 +1660,7 @@ def resolve(self, **kwds): `, see its documentation for the available options. - OUTPUT: A :class:`toric variety `. + OUTPUT: a :class:`toric variety ` EXAMPLES: @@ -1719,7 +1707,7 @@ def resolve(self, **kwds): (z0, z1, z2, z3, z4, z5, z6, z7) sage: TV_res.gens() (z0, z1, z2, z3, z4, z5, z6, z7) - sage: TV_res = TV.resolve(coordinate_names="x+", + sage: TV_res = TV.resolve(coordinate_names='x+', ....: make_simplicial=True) sage: TV_res.gens() (x0, x1, x2, x3, x4, x5, x6, x7) @@ -1774,7 +1762,7 @@ def resolve_to_orbifold(self, **kwds): - this function accepts only keyword arguments. See :meth:`resolve` for documentation. - OUTPUT: A :class:`toric variety `. + OUTPUT: a :class:`toric variety ` EXAMPLES:: @@ -1803,9 +1791,9 @@ def subscheme(self, polynomials): INPUT: - ``polynomials`` -- list of polynomials in the coordinate ring of - ``self``. + ``self`` - OUTPUT: A :class:`subscheme of a toric variety + OUTPUT: a :class:`subscheme of a toric variety `. EXAMPLES: @@ -1868,7 +1856,7 @@ def Stanley_Reisner_ideal(self): def linear_equivalence_ideal(self): r""" - Return the ideal generated by linear relations + Return the ideal generated by linear relations. OUTPUT: @@ -1955,11 +1943,11 @@ def cohomology_basis(self, d=None): INPUT: - - ``d`` (optional) -- integer. + - ``d`` -- (optional) integer OUTPUT: - - Without the optional argument, a list whose d-th entry is a + - Without the optional argument, a list whose `d`-th entry is a basis for `H^{2d}(X,\QQ)` - If the argument is an integer ``d``, returns basis for @@ -2000,14 +1988,14 @@ def volume_class(self): the variety is non-compact this is dual to homology without any support condition. In particular, for non-compact varieties the volume form `\mathrm{dVol}=\wedge_i(dx_i \wedge - dy_i)` does not define a (non-zero) cohomology class. + dy_i)` does not define a (nonzero) cohomology class. OUTPUT: A :class:`CohomologyClass`. If it exists, it is the class of the (properly normalized) volume form, that is, it is the Poincaré dual of a single point. If it does not exist, a - :class:`ValueError` is raised. + :exc:`ValueError` is raised. EXAMPLES:: @@ -2071,7 +2059,7 @@ def integrate(self, cohomology_class): INPUT: - - ``cohomology_class`` -- A cohomology class given as a + - ``cohomology_class`` -- a cohomology class given as a polynomial in ``self.cohomology_ring()`` OUTPUT: @@ -2153,11 +2141,9 @@ def Chern_class(self, deg=None): INPUT: - - ``deg`` -- integer (optional). The degree of the Chern class. + - ``deg`` -- integer (optional); the degree of the Chern class - OUTPUT: - - - If the degree is specified, the ``deg``-th Chern class. + OUTPUT: if the degree is specified, the ``deg``-th Chern class - If no degree is specified, the total Chern class. @@ -2195,8 +2181,8 @@ def Chern_character(self, deg=None): INPUT: - - ``deg`` -- integer (optional). The degree of the Chern - character. + - ``deg`` -- integer (optional); the degree of the Chern + character OUTPUT: @@ -2233,7 +2219,7 @@ def Todd_class(self, deg=None): INPUT: - - ``deg`` -- integer (optional). The desired degree part. + - ``deg`` -- integer (optional); the desired degree part OUTPUT: @@ -2342,9 +2328,7 @@ def divisor(self, arg, base_ring=None, check=True, reduce=True): exception of defining a divisor with a single integer: this method considers it to be the index of a ray of the :meth:`fan` of ``self``. - OUTPUT: - - - A :class:`sage.schemes.toric.divisor.ToricDivisor_generic` + OUTPUT: a :class:`sage.schemes.toric.divisor.ToricDivisor_generic` EXAMPLES:: @@ -2395,7 +2379,7 @@ def divisor_group(self, base_ring=ZZ): INPUT: - ``base_ring`` -- the coefficient ring, usually ``ZZ`` - (default) or ``QQ``. + (default) or ``QQ`` OUTPUT: @@ -2432,7 +2416,7 @@ def toric_divisor_group(self, base_ring=ZZ): INPUT: - ``base_ring`` -- the coefficient ring, usually ``ZZ`` - (default) or ``QQ``. + (default) or ``QQ`` OUTPUT: @@ -2552,9 +2536,7 @@ def Spec(self, cone=None, names=None): formats. If not given, indexed variable names will be created automatically. - OUTPUT: - - The spectrum of the semigroup ring `\CC[\sigma^\vee \cap M]`. + OUTPUT: the spectrum of the semigroup ring `\CC[\sigma^\vee \cap M]` EXAMPLES:: @@ -2619,9 +2601,9 @@ def _orbit_closure_projection(self, cone, x): - ``cone`` -- a :class:`cone ` of the :meth:`fan` - of ``self``; + of ``self`` - - ``x`` -- a lattice point or a cone of the :meth:`fan` of ``self``. + - ``x`` -- a lattice point or a cone of the :meth:`fan` of ``self`` OUTPUT: @@ -2630,7 +2612,7 @@ def _orbit_closure_projection(self, cone, x): This quotient lattice is the ambient lattice for the fan of the orbit closure corresponding to ``cone``. - If ``x`` is a cone not in the star of ``cone``, an :class:`IndexError` + If ``x`` is a cone not in the star of ``cone``, an :exc:`IndexError` is raised. See :meth:`orbit_closure` for more details. @@ -2686,7 +2668,7 @@ def orbit_closure(self, cone): INPUT: - ``cone`` -- a :class:`cone - ` of the fan. + ` of the fan OUTPUT: @@ -2759,9 +2741,7 @@ def Demazure_roots(self): r""" Return the Demazure roots. - OUTPUT: - - The roots as points of the `M`-lattice. + OUTPUT: the roots as points of the `M`-lattice REFERENCES: @@ -2811,7 +2791,7 @@ def Demazure_roots(self): def Aut_dimension(self): r""" - Return the dimension of the automorphism group + Return the dimension of the automorphism group. There are three kinds of symmetries of toric varieties: @@ -2861,24 +2841,22 @@ def normalize_names(names=None, ngens=None, prefix=None, indices=None, names separated by commas or spaces) or a list of strings with each string specifying a name. If the last name ends with the plus sign, "+", this name will be used as ``prefix`` (even if ``prefix`` was - given explicitly); + given explicitly). - - ``ngens`` -- number of names to be returned; + - ``ngens`` -- number of names to be returned - - ``prefix`` -- prefix for the indexed names given as a string; + - ``prefix`` -- prefix for the indexed names given as a string - ``indices`` -- list of integers (default: ``range(ngens)``) used as indices for names with ``prefix``. If given, must be of length - ``ngens``; + ``ngens``. - ``return_prefix`` -- if ``True``, the last element of the returned list will contain the prefix determined from ``names`` or given as the parameter ``prefix``. This is useful if you may need more names in the future. - OUTPUT: - - - list of names given as strings. + OUTPUT: list of names given as strings These names are constructed in the following way: @@ -2933,18 +2911,18 @@ def normalize_names(names=None, ngens=None, prefix=None, indices=None, This is especially useful if you get ``names`` from a user but want to specify all default names:: - sage: normalize_names("x, y", 4, prefix="t") + sage: normalize_names("x, y", 4, prefix='t') ['x', 'y', 't2', 't3'] In this format, the user can easily override your choice for automatic names:: - sage: normalize_names("x y s+", 4, prefix="t") + sage: normalize_names("x y s+", 4, prefix='t') ['x', 'y', 's2', 's3'] Let's now use all parameters at once:: - sage: normalize_names("x, y, s+", 4, prefix="t", + sage: normalize_names("x, y, s+", 4, prefix='t', ....: indices=list(range(1,5)), return_prefix=True) ['x', 'y', 's3', 's4', 's'] @@ -2967,7 +2945,7 @@ def normalize_names(names=None, ngens=None, prefix=None, indices=None, A more subtle one:: - sage: normalize_names("x1", 4, prefix="x") + sage: normalize_names("x1", 4, prefix='x') Traceback (most recent call last): ... ValueError: variable name 'x1' appears more than once @@ -3107,9 +3085,7 @@ def _repr_(self): r""" Return a string representation of the cohomology ring. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3122,9 +3098,7 @@ def _latex_(self): r""" Return a latex representation of the cohomology ring. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3145,9 +3119,7 @@ def _element_constructor_(self, x): be converted into a polynomial in the homogeneous coordinates. - OUTPUT: - - The :class:`CohomologyClass` defined by ``x``. + OUTPUT: the :class:`CohomologyClass` defined by ``x`` EXAMPLES:: @@ -3267,7 +3239,7 @@ def gen(self, i): INPUT: - - ``i`` -- integer. + - ``i`` -- integer OUTPUT: @@ -3292,7 +3264,7 @@ def is_CohomologyClass(x): INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: @@ -3305,12 +3277,20 @@ def is_CohomologyClass(x): sage: HH = P2.cohomology_ring() sage: from sage.schemes.toric.variety import is_CohomologyClass sage: is_CohomologyClass( HH.one() ) # needs sage.libs.singular + doctest:warning... + DeprecationWarning: The function is_CohomologyClass is deprecated; + use 'isinstance(..., CohomologyClass)' instead. + See https://github.com/sagemath/sage/issues/38277 for details. True sage: is_CohomologyClass( HH(P2.fan(1)[0]) ) # needs sage.libs.singular True sage: is_CohomologyClass('z') False """ + from sage.misc.superseded import deprecation + deprecation(38277, + "The function is_CohomologyClass is deprecated; " + "use 'isinstance(..., CohomologyClass)' instead.") return isinstance(x, CohomologyClass) @@ -3345,13 +3325,11 @@ def __init__(self, cohomology_ring, representative): INPUT: - - ``cohomology_ring`` -- :class:`CohomologyRing`. + - ``cohomology_ring`` -- :class:`CohomologyRing` - - ``representative`` -- a polynomial in the generators of the cohomology ring. + - ``representative`` -- a polynomial in the generators of the cohomology ring - OUTPUT: - - An instance of :class:`CohomologyClass`. + OUTPUT: an instance of :class:`CohomologyClass` EXAMPLES:: @@ -3369,9 +3347,7 @@ def _repr_(self): r""" Return a string representation of the cohomology class. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3384,9 +3360,7 @@ def _latex_(self): r""" Return a latex representation of the cohomology class. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -3428,9 +3402,7 @@ def part_of_degree(self, d): - An integer ``d`` - OUTPUT: - - - The degree-``2d`` part of the cohomology class. + OUTPUT: the degree-``2d`` part of the cohomology class EXAMPLES:: @@ -3467,7 +3439,7 @@ def exp(self): OUTPUT: The cohomology class `\exp(` ``self`` `)` if the constant part - vanishes, otherwise a :class:`ValueError` is raised. + vanishes, otherwise a :exc:`ValueError` is raised. EXAMPLES:: diff --git a/src/sage/schemes/toric/weierstrass.py b/src/sage/schemes/toric/weierstrass.py old mode 100644 new mode 100755 index 492f6b41126..8e0feb88c2c --- a/src/sage/schemes/toric/weierstrass.py +++ b/src/sage/schemes/toric/weierstrass.py @@ -160,7 +160,7 @@ def Discriminant(polynomial, variables=None): See :func:`WeierstrassForm` for how to specify the input polynomial(s) and variables. - OUTPUT: The discriminant of the elliptic curve. + OUTPUT: the discriminant of the elliptic curve EXAMPLES:: @@ -199,7 +199,7 @@ def j_invariant(polynomial, variables=None): * A nodal cubic: `j(-y^2 + x^2 + x^3) = \infty` * A cuspidal cubic `y^2=x^3` has undefined `j`-invariant. In this - case, a :class:`ValueError` is raised. + case, a :exc:`ValueError` is raised. EXAMPLES:: @@ -364,16 +364,16 @@ def WeierstrassForm(polynomial, variables=None, transformation=False): If two polynomials are passed, they must both be quadratics in `\mathbb{P}^3`. - - ``variables`` -- a list of variables of the parent polynomial + - ``variables`` -- list of variables of the parent polynomial ring or ``None`` (default). In the latter case, all variables are taken to be polynomial ring variables. If a subset of polynomial ring variables are given, the Weierstrass form is determined over the function field generated by the remaining variables. - - ``transformation`` -- boolean (default: ``False``). Whether to + - ``transformation`` -- boolean (default: ``False``); whether to return the new variables that bring ``polynomial`` into - Weierstrass form. + Weierstrass form OUTPUT: @@ -505,28 +505,28 @@ def WeierstrassForm(polynomial, variables=None, transformation=False): ###################################################################### def _check_homogeneity(polynomial, variables, weights, total_weight=None): """ - Raise :class:`ValueError` if the polynomial is not weighted + Raise :exc:`ValueError` if the polynomial is not weighted homogeneous. INPUT: - - ``polynomial`` -- the input polynomial. See - :func:`WeierstrassForm` for details. + - ``polynomial`` -- the input polynomial; see + :func:`WeierstrassForm` for details - - ``variables`` -- the variables. See :func:`WeierstrassForm` for - details. + - ``variables`` -- the variables; see :func:`WeierstrassForm` for + details - - ``weights`` -- list of integers, one per variable. the weights - of the variables. + - ``weights`` -- list of integers, one per variable; the weights + of the variables - - ``total_weight`` -- an integer or ``None`` (default). If an + - ``total_weight`` -- integer or ``None`` (default); if an integer is passed, it is also checked that the weighted total - degree of polynomial is this value. + degree of polynomial is this value OUTPUT: This function returns nothing. If the polynomial is not weighted - homogeneous, a :class:`ValueError` is raised. + homogeneous, a :exc:`ValueError` is raised. EXAMPLES:: @@ -565,9 +565,9 @@ def _extract_coefficients(polynomial, monomials, variables): - ``polynomial`` -- the input polynomial - - ``monomials`` -- a list of monomials in the polynomial ring + - ``monomials`` -- list of monomials in the polynomial ring - - ``variables`` -- a list of variables in the polynomial ring + - ``variables`` -- list of variables in the polynomial ring OUTPUT: @@ -614,16 +614,16 @@ def _check_polynomial_P2(cubic, variables): INPUT: - - ``cubic`` -- the input polynomial. See - :func:`WeierstrassForm` for details. + - ``cubic`` -- the input polynomial; see + :func:`WeierstrassForm` for details - - ``variables`` -- the variables or ``None``. See - :func:`WeierstrassForm` for details. + - ``variables`` -- the variables or ``None``; see + :func:`WeierstrassForm` for details OUTPUT: This functions returns ``variables``, potentially guessed from the - polynomial ring. A :class:`ValueError` is raised if the polynomial is + polynomial ring. A :exc:`ValueError` is raised if the polynomial is not homogeneous. EXAMPLES:: @@ -771,16 +771,16 @@ def _check_polynomial_P1xP1(biquadric, variables): INPUT: - - ``biquadric`` -- the input polynomial. See - :func:`WeierstrassForm` for details. + - ``biquadric`` -- the input polynomial; see + :func:`WeierstrassForm` for details - - ``variables`` -- the variables or ``None``. See - :func:`WeierstrassForm` for details. + - ``variables`` -- the variables or ``None``; see + :func:`WeierstrassForm` for details OUTPUT: This functions returns ``variables``, potentially guessed from the - polynomial ring. A :class:`ValueError` is raised if the polynomial is + polynomial ring. A :exc:`ValueError` is raised if the polynomial is not homogeneous. EXAMPLES:: @@ -820,14 +820,12 @@ def _partial_discriminant(quadric, y0, y1=None): INPUT: - - ``quadric`` -- a biquadric. + - ``quadric`` -- a biquadric - - ``y_0``, ``y_1`` -- the variables of the quadric. The ``y_1`` - variable can be omitted if the quadric is inhomogeneous. + - ``y_0``, ``y_1`` -- the variables of the quadric; the ``y_1`` + variable can be omitted if the quadric is inhomogeneous - OUTPUT: - - A plane quartic in ``x0``, ``x1``. + OUTPUT: a plane quartic in ``x0``, ``x1`` EXAMPLES:: @@ -862,7 +860,7 @@ def _partial_discriminant(quadric, y0, y1=None): ###################################################################### def WeierstrassForm_P1xP1(biquadric, variables=None): r""" - Bring a biquadric into Weierstrass form + Bring a biquadric into Weierstrass form. Input/output is the same as :func:`WeierstrassForm`, except that the input polynomial must be a standard biquadric in `\mathbb{P}^2`, @@ -955,16 +953,16 @@ def _check_polynomial_P2_112(polynomial, variables): INPUT: - - ``polynomial`` -- the input polynomial. See - :func:`WeierstrassForm` for details. + - ``polynomial`` -- the input polynomial; see + :func:`WeierstrassForm` for details - - ``variables`` -- the variables or ``None``. See - :func:`WeierstrassForm` for details. + - ``variables`` -- the variables or ``None``; see + :func:`WeierstrassForm` for details OUTPUT: This functions returns ``variables``, potentially guessed from the - polynomial ring. A :class:`ValueError` is raised if the polynomial is + polynomial ring. A :exc:`ValueError` is raised if the polynomial is not homogeneous. EXAMPLES:: diff --git a/src/sage/schemes/toric/weierstrass_covering.py b/src/sage/schemes/toric/weierstrass_covering.py old mode 100644 new mode 100755 index 128c30d33a8..82c300c1f7a --- a/src/sage/schemes/toric/weierstrass_covering.py +++ b/src/sage/schemes/toric/weierstrass_covering.py @@ -134,7 +134,7 @@ def WeierstrassMap(polynomial, variables=None): hypersurface in `\mathbb{P}^2[1,1,2]`. The equation need not be in any standard form, only its Newton polyhedron is used. - - ``variables`` -- a list of variables of the parent polynomial + - ``variables`` -- list of variables of the parent polynomial ring or ``None`` (default). In the latter case, all variables are taken to be polynomial ring variables. If a subset of polynomial ring variables are given, the Weierstrass form is @@ -255,10 +255,10 @@ def homogenize(inhomog, degree): result = vector(ZZ, result) result.set_immutable() return result - X_dict = {homogenize(e, 2): v for e, v in X.dict().items()} - Y_dict = {homogenize(e, 3): v for e, v in Y.dict().items()} - Z_dict = {homogenize(e, 1): v for e, v in Z.dict().items()} - # shift to non-negative exponents if necessary + X_dict = {homogenize(e, 2): v for e, v in X.monomial_coefficients().items()} + Y_dict = {homogenize(e, 3): v for e, v in Y.monomial_coefficients().items()} + Z_dict = {homogenize(e, 1): v for e, v in Z.monomial_coefficients().items()} + # shift to nonnegative exponents if necessary min_deg = [0] * R.ngens() for var in variables: i = R.gens().index(var) diff --git a/src/sage/schemes/toric/weierstrass_higher.py b/src/sage/schemes/toric/weierstrass_higher.py old mode 100644 new mode 100755 index 48d683d53a4..1e88b1dd952 --- a/src/sage/schemes/toric/weierstrass_higher.py +++ b/src/sage/schemes/toric/weierstrass_higher.py @@ -38,14 +38,12 @@ ###################################################################### def WeierstrassForm2(polynomial, variables=None, transformation=False): r""" - Helper function for :func:`~sage.schemes.toric.weierstrass.WeierstrassForm` + Helper function for :func:`~sage.schemes.toric.weierstrass.WeierstrassForm`. Currently, only the case of the complete intersection of two quadratic equations in `\mathbb{P}^3` is supported. - INPUT / OUTPUT: - - See :func:`~sage.schemes.toric.weierstrass.WeierstrassForm` + INPUT / OUTPUT: see :func:`~sage.schemes.toric.weierstrass.WeierstrassForm` TESTS:: @@ -74,14 +72,14 @@ def _check_polynomials_P3(quadratic1, quadratic2, variables): INPUT: - ``quadratic1``, ``quadratic2`` -- two quadratic polynomials in 4 - homogeneous or 3 inhomogeneous variables. + homogeneous or 3 inhomogeneous variables - - ``variables`` -- the variables or ``None`` (default). + - ``variables`` -- the variables or ``None`` (default) OUTPUT: This function returns ``variables``, potentially guessed from the - polynomial ring. A :class:`ValueError` is raised if the polynomial is + polynomial ring. A :exc:`ValueError` is raised if the polynomial is not homogeneous. EXAMPLES:: @@ -124,7 +122,7 @@ def _check_polynomials_P3(quadratic1, quadratic2, variables): ###################################################################### def _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=None): r""" - Helper function for the Weierstrass form of a biquadratic in `\mathbb{P}^3` + Helper function for the Weierstrass form of a biquadratic in `\mathbb{P}^3`. The invariants and covariants of a quaternary biquadratic satisfy the relation @@ -139,11 +137,9 @@ def _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=None): INPUT: - See :func:`WeierstrassForm_P3` - - OUTPUT: + See :func:`WeierstrassForm_P3`. - A triple consisting of + OUTPUT: a triple consisting of - The quaternary biquadratic as an algebraic form :class:`~sage.rings.invariant_theory.TwoQuaternaryQuadratics` diff --git a/src/sage/sets/cartesian_product.py b/src/sage/sets/cartesian_product.py index 47b94b6d222..e29a4fb1a2f 100644 --- a/src/sage/sets/cartesian_product.py +++ b/src/sage/sets/cartesian_product.py @@ -55,9 +55,9 @@ def __init__(self, sets, category, flatten=False): r""" INPUT: - - ``sets`` -- a tuple of parents - - ``category`` -- a subcategory of ``Sets().CartesianProducts()`` - - ``flatten`` -- a boolean (default: ``False``) + - ``sets`` -- tuple of parents + - ``category`` -- a subcategory of ``Sets().CartesianProducts()`` + - ``flatten`` -- boolean (default: ``False``) ``flatten`` is current ignored, and reserved for future use. @@ -82,11 +82,11 @@ def __init__(self, sets, category, flatten=False): def _element_constructor_(self, x): r""" - Construct an element of a Cartesian product from a list or iterable + Construct an element of a Cartesian product from a list or iterable. INPUT: - - ``x`` -- a list (or iterable) + - ``x`` -- list (or iterable) Each component of `x` is converted to the corresponding Cartesian factor. @@ -211,7 +211,7 @@ def cartesian_projection(self, i): EXAMPLES:: sage: C = Sets().CartesianProducts().example(); C - The Cartesian product of (Set of prime numbers (basic implementation), An example of an infinite enumerated set: the non negative integers, An example of a finite enumerated set: {1,2,3}) + The Cartesian product of (Set of prime numbers (basic implementation), An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) sage: x = C.an_element(); x (47, 42, 1) sage: pi = C.cartesian_projection(1) @@ -316,7 +316,7 @@ def cartesian_projection(self, i): EXAMPLES:: sage: C = Sets().CartesianProducts().example(); C - The Cartesian product of (Set of prime numbers (basic implementation), An example of an infinite enumerated set: the non negative integers, An example of a finite enumerated set: {1,2,3}) + The Cartesian product of (Set of prime numbers (basic implementation), An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) sage: x = C.an_element(); x (47, 42, 1) sage: x.cartesian_projection(1) @@ -335,7 +335,7 @@ def __iter__(self): sage: C = Sets().CartesianProducts().example(); C The Cartesian product of (Set of prime numbers (basic implementation), - An example of an infinite enumerated set: the non negative integers, + An example of an infinite enumerated set: the nonnegative integers, An example of a finite enumerated set: {1,2,3}) sage: c = C.an_element(); c (47, 42, 1) diff --git a/src/sage/sets/condition_set.py b/src/sage/sets/condition_set.py index e29f0124224..a0d618ebdde 100644 --- a/src/sage/sets/condition_set.py +++ b/src/sage/sets/condition_set.py @@ -26,11 +26,11 @@ class ConditionSet(Set_generic, Set_base, Set_boolean_operators, Set_add_sub_operators, UniqueRepresentation): r""" - Set of elements of a universe that satisfy given predicates + Set of elements of a universe that satisfy given predicates. INPUT: - - ``universe`` -- a set + - ``universe`` -- set - ``*predicates`` -- callables @@ -70,7 +70,7 @@ class ConditionSet(Set_generic, Set_base, Set_boolean_operators, Set_add_sub_ope sage: # needs sage.geometry.polyhedron sage: P = polytopes.cube(); P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: P.rename("P") + sage: P.rename('P') sage: P_inter_B = ConditionSet(P, lambda x: x.norm() < 1.2); P_inter_B { x ∈ P : at 0x...>(x) } sage: vector([1, 0, 0]) in P_inter_B @@ -217,7 +217,6 @@ def _first_ngens(self, n): sage: preparse("Q3. = ConditionSet(QQ^3)") "Q3 = ConditionSet(QQ**Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = Q3._first_ngens(3)" - """ return self.arguments() @@ -321,7 +320,6 @@ def _element_constructor_(self, *args, **kwds): Traceback (most recent call last): ... ValueError: 3 does not satisfy the condition - """ try: universe_element_constructor = self._universe._element_constructor_ @@ -375,7 +373,7 @@ def _an_element_(self): r""" Return an element of ``self``. - This may raise :class:`NotImplementedError`. + This may raise :exc:`NotImplementedError`. TESTS:: @@ -520,7 +518,6 @@ def __iter__(self): { x ∈ Integer Ring : (x) } sage: list(Odds.iterator_range(stop=6)) [1, -1, 3, -3, 5, -5] - """ for x in self._universe: if x in self: diff --git a/src/sage/sets/disjoint_set.pxd b/src/sage/sets/disjoint_set.pxd index 3c8351983e7..4d981718568 100644 --- a/src/sage/sets/disjoint_set.pxd +++ b/src/sage/sets/disjoint_set.pxd @@ -19,8 +19,8 @@ cdef class DisjointSet_class(SageObject): cpdef number_of_subsets(self) cdef class DisjointSet_of_integers(DisjointSet_class): - cpdef int find(self, int i) - cpdef void union(self, int i, int j) + cpdef int find(self, int i) except -1 + cpdef void union(self, int i, int j) except * cpdef root_to_elements_dict(self) cpdef element_to_root_dict(self) cpdef to_digraph(self) @@ -29,7 +29,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef list _int_to_el cdef dict _el_to_int cpdef find(self, e) - cpdef void union(self, e, f) + cpdef void union(self, e, f) noexcept cpdef root_to_elements_dict(self) cpdef element_to_root_dict(self) cpdef to_digraph(self) diff --git a/src/sage/sets/disjoint_set.pyx b/src/sage/sets/disjoint_set.pyx index 1c2d93fea2a..ddd9a95a310 100644 --- a/src/sage/sets/disjoint_set.pyx +++ b/src/sage/sets/disjoint_set.pyx @@ -62,6 +62,10 @@ from sage.rings.integer cimport Integer from sage.structure.sage_object cimport SageObject from cpython.object cimport PyObject_RichCompare from sage.groups.perm_gps.partn_ref.data_structures cimport * +from sage.misc.lazy_import import LazyImport + +SetPartition = LazyImport('sage.combinat.set_partition', 'SetPartition') + cpdef DisjointSet(arg): r""" @@ -103,6 +107,14 @@ cpdef DisjointSet(arg): sage: DisjointSet(['yi', 45, 'cheval']) {{'cheval'}, {'yi'}, {45}} + From a set partition (see :issue:`38693`):: + + sage: SP = SetPartition(DisjointSet(5)) + sage: DisjointSet(SP) + {{0}, {1}, {2}, {3}, {4}} + sage: DisjointSet(SP) == DisjointSet(5) + True + TESTS:: sage: DisjointSet(0) @@ -137,6 +149,8 @@ cpdef DisjointSet(arg): if arg < 0: raise ValueError('arg must be a nonnegative integer (%s given)' % arg) return DisjointSet_of_integers(arg) + elif isinstance(arg, SetPartition): + return DisjointSet(arg.base_set()) else: return DisjointSet_of_hashables(arg) @@ -448,7 +462,7 @@ cdef class DisjointSet_of_integers(DisjointSet_class): for i, parent in enumerate(l): self.union(parent, i) - cpdef int find(self, int i): + cpdef int find(self, int i) except -1: r""" Return the representative of the set that ``i`` currently belongs to. @@ -479,8 +493,9 @@ cdef class DisjointSet_of_integers(DisjointSet_class): sage: [e.find(i) for i in range(5)] [0, 1, 1, 1, 1] sage: e.find(2**10) - ValueError: i must be between 0 and 4 (1024 given) + Traceback (most recent call last): ... + ValueError: i must be between 0 and 4 (1024 given) .. NOTE:: @@ -492,7 +507,7 @@ cdef class DisjointSet_of_integers(DisjointSet_class): raise ValueError('i must be between 0 and %s (%s given)' % (card - 1, i)) return OP_find(self._nodes, i) - cpdef void union(self, int i, int j): + cpdef void union(self, int i, int j) except *: r""" Combine the set of ``i`` and the set of ``j`` into one. @@ -520,8 +535,9 @@ cdef class DisjointSet_of_integers(DisjointSet_class): sage: d {{0, 1, 2, 4}, {3}} sage: d.union(1, 5) - ValueError: j must be between 0 and 4 (5 given) + Traceback (most recent call last): ... + ValueError: j must be between 0 and 4 (5 given) .. NOTE:: @@ -535,6 +551,26 @@ cdef class DisjointSet_of_integers(DisjointSet_class): raise ValueError('j must be between 0 and %s (%s given)' % (card - 1, j)) OP_join(self._nodes, i, j) + def make_set(self): + r""" + Add a new element into a new set containing only the new element. + + According to :wikipedia:`Disjoint-set_data_structure#Making_new_sets` the + `make_set` operation adds a new element into a new set containing only + the new element. The new set is added at the end of `self`. + + EXAMPLES:: + sage: d = DisjointSet(5) + sage: d.union(1, 2) + sage: d.union(0, 1) + sage: d.make_set() + sage: d + {{0, 1, 2}, {3}, {4}, {5}} + sage: d.find(1) + 1 + """ + OP_make_set(self._nodes) + cpdef root_to_elements_dict(self): r""" Return the dictionary where the keys are the roots of ``self`` and the @@ -797,7 +833,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef int r = OP_find(self._nodes, i) return self._int_to_el[r] - cpdef void union(self, e, f): + cpdef void union(self, e, f) noexcept: r""" Combine the set of ``e`` and the set of ``f`` into one. @@ -832,6 +868,43 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef int j = self._el_to_int[f] OP_join(self._nodes, i, j) + def make_set(self, new_elt=None): + r""" + Add a new element into a new set containing only the new element. + + According to :wikipedia:`Disjoint-set_data_structure#Making_new_sets` + the `make_set` operation adds a new element into a new set containing + only the new element. The new set is added at the end of `self`. + + INPUT: + + - ``new_elt`` -- (optional) element to add. If `None`, then an integer + is added. + + EXAMPLES:: + + sage: e = DisjointSet('abcde') + sage: e.union('d', 'c') + sage: e.union('c', 'e') + sage: e.make_set('f') + sage: e + {{'a'}, {'b'}, {'c', 'd', 'e'}, {'f'}} + sage: e.union('f', 'b') + sage: e + {{'a'}, {'b', 'f'}, {'c', 'd', 'e'}} + sage: e.make_set('e'); e + {{'a'}, {'b', 'f'}, {'c', 'd', 'e'}} + sage: e.make_set(); e + {{'a'}, {'b', 'f'}, {'c', 'd', 'e'}, {6}} + """ + if new_elt is None: + new_elt = self._nodes.degree + if new_elt not in self._int_to_el: + d = self._nodes.degree + self._int_to_el.append(new_elt) + self._el_to_int[new_elt] = d + OP_make_set(self._nodes) + cpdef root_to_elements_dict(self): r""" Return the dictionary where the keys are the roots of ``self`` and the diff --git a/src/sage/sets/disjoint_union_enumerated_sets.py b/src/sage/sets/disjoint_union_enumerated_sets.py index 030834993fa..97243f90d11 100644 --- a/src/sage/sets/disjoint_union_enumerated_sets.py +++ b/src/sage/sets/disjoint_union_enumerated_sets.py @@ -32,9 +32,9 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): INPUT: - - ``family`` -- a list (or iterable or family) of enumerated sets - - ``keepkey`` -- a boolean - - ``facade`` -- a boolean + - ``family`` -- list (or iterable or family) of enumerated sets + - ``keepkey`` -- boolean + - ``facade`` -- boolean This models the enumerated set obtained by concatenating together the specified ordered sets. The latter are supposed to be pairwise @@ -227,7 +227,7 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): We skip ``_test_an_element`` because the coercion framework does not currently allow a tuple to be returned for facade parents:: - sage: TestSuite(Ukeep).run(skip="_test_an_element") # needs sage.combinat + sage: TestSuite(Ukeep).run(skip='_test_an_element') # needs sage.combinat The following three lines are required for the pickling tests, because the classes ``MyUnion`` and ``UnionOfSpecialSets`` have @@ -239,7 +239,6 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): sage: TestSuite(pp).run() sage: TestSuite(psp).run() - """ @staticmethod @@ -437,7 +436,7 @@ def an_element(self): @cached_method def cardinality(self): """ - Returns the cardinality of this disjoint union. + Return the cardinality of this disjoint union. EXAMPLES: @@ -465,7 +464,6 @@ def cardinality(self): ....: Family(NonNegativeIntegers(), lambda x: [])) sage: U.cardinality() # Should be 0! +Infinity - """ if self._family.cardinality() == Infinity: return Infinity diff --git a/src/sage/sets/family.pyx b/src/sage/sets/family.pyx index 0810b07f17a..f87768f3989 100644 --- a/src/sage/sets/family.pyx +++ b/src/sage/sets/family.pyx @@ -421,13 +421,13 @@ def Family(indices, function=None, hidden_keys=[], hidden_function=None, lazy=Fa cdef class AbstractFamily(Parent): """ - The abstract class for family + The abstract class for family. Any family belongs to a class which inherits from :class:`AbstractFamily`. """ def hidden_keys(self): """ - Returns the hidden keys of the family, if any. + Return the hidden keys of the family, if any. EXAMPLES:: @@ -500,9 +500,7 @@ cdef class AbstractFamily(Parent): def map(self, f, name=None): r""" Return the family `( f(\mathtt{self}[i]) )_{i \in I}`, where - `I` is the index set of self. - - .. TODO:: good name? + `I` is the index set of ``self``. EXAMPLES:: @@ -519,9 +517,8 @@ cdef class AbstractFamily(Parent): @cached_method def inverse_family(self): """ - Returns the inverse family, with keys and values - exchanged. This presumes that there are no duplicate values in - ``self``. + Return the inverse family, with keys and values exchanged. This + presumes that there are no duplicate values in ``self``. This default implementation is not lazy and therefore will only work with not too big finite families. It is also cached @@ -575,7 +572,6 @@ cdef class FiniteFamily(AbstractFamily): sage: f = FiniteFamily({"a": "aa", "b": "bb", "c" : "cc" }, keys = ["c", "a", "b"]) sage: list(f) ['cc', 'aa', 'bb'] - """ def __init__(self, dictionary, keys=None): @@ -649,7 +645,7 @@ cdef class FiniteFamily(AbstractFamily): def keys(self): """ - Returns the index set of this family + Return the index set of this family. EXAMPLES:: @@ -662,7 +658,7 @@ cdef class FiniteFamily(AbstractFamily): def values(self): """ - Returns the elements of this family + Return the elements of this family. EXAMPLES:: @@ -677,7 +673,7 @@ cdef class FiniteFamily(AbstractFamily): def has_key(self, k): """ - Returns whether ``k`` is a key of ``self`` + Return whether ``k`` is a key of ``self``. EXAMPLES:: @@ -753,7 +749,7 @@ cdef class FiniteFamily(AbstractFamily): def __len__(self): """ - Returns the number of elements in self. + Return the number of elements in ``self``. EXAMPLES:: @@ -766,7 +762,7 @@ cdef class FiniteFamily(AbstractFamily): def cardinality(self): """ - Returns the number of elements in self. + Return the number of elements in ``self``. EXAMPLES:: @@ -884,7 +880,7 @@ class FiniteFamilyWithHiddenKeys(FiniteFamily): def hidden_keys(self): """ - Returns self's hidden keys. + Return ``self``'s hidden keys. EXAMPLES:: @@ -1090,7 +1086,7 @@ class LazyFamily(AbstractFamily): def keys(self): """ - Returns self's keys. + Return ``self``'s keys. EXAMPLES:: @@ -1103,7 +1099,7 @@ class LazyFamily(AbstractFamily): def cardinality(self): """ - Return the number of elements in self. + Return the number of elements in ``self``. EXAMPLES:: @@ -1306,7 +1302,7 @@ class TrivialFamily(AbstractFamily): def keys(self): """ - Returns self's keys. + Return ``self``'s keys. EXAMPLES:: @@ -1319,7 +1315,7 @@ class TrivialFamily(AbstractFamily): def cardinality(self): """ - Return the number of elements in self. + Return the number of elements in ``self``. EXAMPLES:: @@ -1487,7 +1483,7 @@ class EnumeratedFamily(LazyFamily): def cardinality(self): """ - Return the number of elements in self. + Return the number of elements in ``self``. EXAMPLES:: diff --git a/src/sage/sets/finite_enumerated_set.py b/src/sage/sets/finite_enumerated_set.py index 6f205e5b70e..ce959031800 100644 --- a/src/sage/sets/finite_enumerated_set.py +++ b/src/sage/sets/finite_enumerated_set.py @@ -36,7 +36,6 @@ class FiniteEnumeratedSet(UniqueRepresentation, Parent): ``EnumeratedSets`` and has unique representation. The list of the elements is expanded in memory. - EXAMPLES:: sage: S = FiniteEnumeratedSet([1, 2, 3]) @@ -163,7 +162,7 @@ def __contains__(self, x): def __iter__(self): r""" - Iterator over the element of self. + Iterator over the element of ``self``. EXAMPLES:: @@ -198,8 +197,8 @@ def an_element(self): def first(self): r""" - Return the first element of the enumeration or raise an EmptySetError if - the set is empty. + Return the first element of the enumeration or raise an + :exc:`EmptySetError` if the set is empty. EXAMPLES:: @@ -213,8 +212,8 @@ def first(self): def last(self): r""" - Returns the last element of the iteration or raise an EmptySetError if - the set is empty. + Return the last element of the iteration or raise an + :exc:`EmptySetError` if the set is empty. EXAMPLES:: @@ -259,7 +258,7 @@ def cardinality(self): def rank(self, x): """ - Returns the index of ``x`` in this finite enumerated set. + Return the index of ``x`` in this finite enumerated set. EXAMPLES:: @@ -381,7 +380,7 @@ def _element_constructor_(self, el): - ``el`` -- an element of ``self`` - If ``el`` is not an element of ``self``, a :class:`ValueError` + If ``el`` is not an element of ``self``, a :exc:`ValueError` is raised. TESTS:: diff --git a/src/sage/sets/finite_set_map_cy.pyx b/src/sage/sets/finite_set_map_cy.pyx index a06dc0a2bd9..335e4cfb5e7 100644 --- a/src/sage/sets/finite_set_map_cy.pyx +++ b/src/sage/sets/finite_set_map_cy.pyx @@ -60,11 +60,11 @@ from sage.sets.set import Set_object_enumerated cpdef fibers(f, domain): r""" - Returns the fibers of the function ``f`` on the finite set ``domain`` + Return the fibers of the function ``f`` on the finite set ``domain``. INPUT: - - ``f`` -- a function or callable + - ``f`` -- a function or callable - ``domain`` -- a finite iterable OUTPUT: @@ -98,7 +98,7 @@ cpdef fibers(f, domain): def fibers_args(f, domain, *args, **opts): r""" - Returns the fibers of the function ``f`` on the finite set ``domain`` + Return the fibers of the function ``f`` on the finite set ``domain``. It is the same as :func:`fibers` except that one can pass extra argument for ``f`` (with a small overhead) @@ -118,23 +118,21 @@ cdef class FiniteSetMap_MN(ClonableIntArray): We assume that the parent given as argument is such that: - - ``m`` is stored in ``self.parent()._m`` - - ``n`` is stored in ``self.parent()._n`` + - ``m`` -- stored in ``self.parent()._m`` + - ``n`` -- stored in ``self.parent()._n`` - the domain is in ``self.parent().domain()`` - the codomain is in ``self.parent().codomain()`` """ def __call__(self, int i): """ - Returns the image of ``i`` under the map ``self`` + Return the image of ``i`` under the map ``self``. INPUT: - - ``i`` -- an int + - ``i`` -- integer - OUTPUT: - - an int + OUTPUT: integer EXAMPLES:: @@ -147,7 +145,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): # Needed by generic power which refuses to compute 0^0 def __bool__(self): """ - Returns whether ``self`` is non zero; this is always ``True``. + Return whether ``self`` is nonzero; this is always ``True``. EXAMPLES:: @@ -159,7 +157,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef domain(self): """ - Returns the domain of ``self`` + Return the domain of ``self``. EXAMPLES:: @@ -170,7 +168,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef codomain(self): """ - Returns the codomain of ``self`` + Return the codomain of ``self``. EXAMPLES:: @@ -181,7 +179,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef _setimage(self, int i, int j): """ - Set the image of ``i`` as ``j`` in ``self`` + Set the image of ``i`` as ``j`` in ``self``. This is a fast internal version where ``i`` and ``j`` are both int's. @@ -189,9 +187,9 @@ cdef class FiniteSetMap_MN(ClonableIntArray): INPUT: - - ``i``, ``j`` -- two ``int``'s + - ``i``, ``j`` -- integers - OUTPUT: ``None`` + OUTPUT: none EXAMPLES:: @@ -223,13 +221,13 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef _getimage(self, int i): """ - Returns the image of ``i`` by ``self`` + Return the image of ``i`` by ``self``. - This is a fast internal version where ``i`` is an int. + This is a fast internal version where ``i`` is integer. INPUT: - - ``i`` -- an ``int`` + - ``i`` -- integer EXAMPLES:: @@ -241,7 +239,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef setimage(self, i, j): """ - Set the image of ``i`` as ``j`` in ``self`` + Set the image of ``i`` as ``j`` in ``self``. .. warning:: ``self`` must be mutable; otherwise an exception is raised. @@ -249,7 +247,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): - ``i``, ``j`` -- two ``object``'s - OUTPUT: ``None`` + OUTPUT: none .. NOTE:: if you need speed, please use instead :meth:`_setimage` @@ -270,11 +268,11 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef getimage(self, i): """ - Returns the image of ``i`` by ``self`` + Return the image of ``i`` by ``self``. INPUT: - - ``i`` -- any object. + - ``i`` -- any object .. NOTE:: if you need speed, please use instead :meth:`_getimage` @@ -288,7 +286,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef image_set(self): """ - Returns the image set of ``self`` + Return the image set of ``self``. EXAMPLES:: @@ -301,7 +299,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef fibers(self): """ - Returns the fibers of ``self`` + Return the fibers of ``self``. OUTPUT: @@ -320,7 +318,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef items(self): """ - The items of ``self`` + The items of ``self``. Return the list of the ordered pairs ``(x, self(x))`` @@ -333,7 +331,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef check(self): """ - Performs checks on ``self`` + Perform checks on ``self``. Check that ``self`` is a proper function and then calls ``parent.check_element(self)`` where ``parent`` is the parent @@ -385,7 +383,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): cpdef FiniteSetMap_Set FiniteSetMap_Set_from_list(t, parent, lst): """ - Creates a ``FiniteSetMap`` from a list + Create a ``FiniteSetMap`` from a list. .. warning:: no check is performed ! @@ -408,7 +406,7 @@ cpdef FiniteSetMap_Set FiniteSetMap_Set_from_list(t, parent, lst): cpdef FiniteSetMap_Set FiniteSetMap_Set_from_dict(t, parent, d): """ - Creates a ``FiniteSetMap`` from a dictionary + Create a ``FiniteSetMap`` from a dictionary. .. warning:: no check is performed ! @@ -432,7 +430,7 @@ cpdef FiniteSetMap_Set FiniteSetMap_Set_from_dict(t, parent, d): cdef class FiniteSetMap_Set(FiniteSetMap_MN): """ - Data structure for maps + Data structure for maps. We assume that the parent given as argument is such that: @@ -471,15 +469,13 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): def __call__(self, i): """ - Returns the image of ``i`` under the map ``self`` + Return the image of ``i`` under the map ``self``. INPUT: - - ``i`` -- an int + - ``i`` -- integer - OUTPUT: - - an int + OUTPUT: integer EXAMPLES:: @@ -493,7 +489,7 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): cpdef image_set(self): """ - Returns the image set of ``self`` + Return the image set of ``self``. EXAMPLES:: @@ -509,7 +505,7 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): cpdef setimage(self, i, j): """ - Set the image of ``i`` as ``j`` in ``self`` + Set the image of ``i`` as ``j`` in ``self``. .. warning:: ``self`` must be mutable otherwise an exception is raised. @@ -517,7 +513,7 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): - ``i``, ``j`` -- two ``object``'s - OUTPUT: ``None`` + OUTPUT: none EXAMPLES:: @@ -552,11 +548,11 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): cpdef getimage(self, i): """ - Returns the image of ``i`` by ``self`` + Return the image of ``i`` by ``self``. INPUT: - - ``i`` -- an ``int`` + - ``i`` -- integer EXAMPLES:: @@ -570,7 +566,7 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): cpdef items(self): """ - The items of ``self`` + The items of ``self``. Return the list of the couple ``(x, self(x))`` @@ -604,7 +600,7 @@ cdef class FiniteSetMap_Set(FiniteSetMap_MN): cdef class FiniteSetEndoMap_N(FiniteSetMap_MN): """ - Maps from ``range(n)`` to itself. + Map from ``range(n)`` to itself. .. SEEALSO:: :class:`FiniteSetMap_MN` for assumptions on the parent @@ -621,7 +617,7 @@ cdef class FiniteSetEndoMap_N(FiniteSetMap_MN): sage: F = FiniteSetMaps(3) sage: F([1, 0, 2]) * F([2, 1, 0]) [2, 0, 1] - sage: F = FiniteSetMaps(3, action="right") + sage: F = FiniteSetMaps(3, action='right') sage: F([1, 0, 2]) * F([2, 1, 0]) [1, 2, 0] """ @@ -637,8 +633,8 @@ cdef class FiniteSetEndoMap_N(FiniteSetMap_MN): INPUT: - - ``n`` -- a positive integer - - ``dummy`` -- not used; must be set to ``None`` (for compatibility only). + - ``n`` -- positive integer + - ``dummy`` -- not used; must be set to ``None`` (for compatibility only) EXAMPLES:: @@ -657,7 +653,7 @@ cdef class FiniteSetEndoMap_N(FiniteSetMap_MN): cdef class FiniteSetEndoMap_Set(FiniteSetMap_Set): """ - Maps from a set to itself + Map from a set to itself. .. SEEALSO:: :class:`FiniteSetMap_Set` for assumptions on the parent @@ -691,12 +687,12 @@ cdef class FiniteSetEndoMap_Set(FiniteSetMap_Set): def __pow__(self, n, dummy): """ - Return the ``n``-th power of self. + Return the ``n``-th power of ``self``. INPUT: - - ``n`` -- a positive integer - - ``dummy`` -- not used; must be set to None (for compatibility only). + - ``n`` -- positive integer + - ``dummy`` -- not used; must be set to None (for compatibility only) EXAMPLES:: diff --git a/src/sage/sets/finite_set_maps.py b/src/sage/sets/finite_set_maps.py index b0faa1ddd95..290e32d5e3c 100644 --- a/src/sage/sets/finite_set_maps.py +++ b/src/sage/sets/finite_set_maps.py @@ -37,7 +37,7 @@ class FiniteSetMaps(UniqueRepresentation, Parent): r""" - Maps between finite sets + Maps between finite sets. Constructs the set of all maps between two sets. The sets can be given using any of the three following ways: @@ -54,12 +54,12 @@ class FiniteSetMaps(UniqueRepresentation, Parent): INPUT: - - ``domain`` -- a set, finite iterable, or integer. + - ``domain`` -- set, finite iterable, or integer - - ``codomain`` -- a set, finite iterable, integer, or ``None`` + - ``codomain`` -- set, finite iterable, integer, or ``None`` (default). In this last case, the maps are endo-maps of the domain. - - ``action`` -- ``"left"`` (default) or ``"right"``. The side + - ``action`` -- ``'left'`` (default) or ``'right'``. The side where the maps act on the domain. This is used in particular to define the meaning of the product (composition) of two maps. @@ -156,7 +156,7 @@ class FiniteSetMaps(UniqueRepresentation, Parent): sage: TestSuite(FiniteSetMaps([], [1, 2])).run() """ @staticmethod - def __classcall_private__(cls, domain, codomain=None, action="left", category=None): + def __classcall_private__(cls, domain, codomain=None, action='left', category=None): """ TESTS:: @@ -195,7 +195,7 @@ def __classcall_private__(cls, domain, codomain=None, action="left", category=No def cardinality(self): """ - The cardinality of ``self`` + The cardinality of ``self``. EXAMPLES:: @@ -239,7 +239,7 @@ def __init__(self, m, n, category=None): def domain(self): """ - The domain of ``self`` + The domain of ``self``. EXAMPLES:: @@ -250,7 +250,7 @@ def domain(self): def codomain(self): """ - The codomain of ``self`` + The codomain of ``self``. EXAMPLES:: @@ -291,7 +291,7 @@ def __contains__(self, x): def an_element(self): """ - Returns a map in ``self`` + Return a map in ``self``. EXAMPLES:: @@ -368,16 +368,16 @@ def _element_constructor_(self, *args, **keywords): class FiniteSetMaps_Set(FiniteSetMaps_MN): """ - The sets of all maps between two sets + The sets of all maps between two sets. Users should use the factory class :class:`FiniteSetMaps` to create instances of this class. INPUT: - - ``domain`` -- an object in the category ``FiniteSets()``. + - ``domain`` -- an object in the category ``FiniteSets()`` - - ``codomain`` -- an object in the category ``FiniteSets()``. + - ``codomain`` -- an object in the category ``FiniteSets()`` - ``category`` -- the category in which the sets of maps is constructed. It must be a sub-category of @@ -428,7 +428,7 @@ def __init__(self, domain, codomain, category=None): def domain(self): """ - The domain of ``self`` + The domain of ``self``. EXAMPLES:: @@ -439,7 +439,7 @@ def domain(self): def codomain(self): """ - The codomain of ``self`` + The codomain of ``self``. EXAMPLES:: @@ -451,7 +451,7 @@ def codomain(self): # TODO: consistency from_dict / from_list def _from_list_(self, v): """ - Create a function from a list + Create a function from a list. The list gives in the order of the element of the domain the rank (index) of its image in the codomain. @@ -466,7 +466,7 @@ def _from_list_(self, v): def from_dict(self, d): """ - Create a map from a dictionary + Create a map from a dictionary. EXAMPLES:: @@ -481,14 +481,14 @@ def from_dict(self, d): class FiniteSetEndoMaps_N(FiniteSetMaps_MN): r""" - The sets of all maps from `\{1, 2, \dots, n\}` to itself + The sets of all maps from `\{1, 2, \dots, n\}` to itself. Users should use the factory class :class:`FiniteSetMaps` to create instances of this class. INPUT: - - ``n`` -- an integer. + - ``n`` -- integer - ``category`` -- the category in which the sets of maps is constructed. It must be a sub-category of ``Monoids().Finite()`` @@ -523,7 +523,7 @@ def one(self): def an_element(self): """ - Returns a map in ``self`` + Return a map in ``self``. EXAMPLES:: @@ -547,14 +547,14 @@ def _repr_(self): class FiniteSetEndoMaps_Set(FiniteSetMaps_Set, FiniteSetEndoMaps_N): """ - The sets of all maps from a set to itself + The sets of all maps from a set to itself. Users should use the factory class :class:`FiniteSetMaps` to create instances of this class. INPUT: - - ``domain`` -- an object in the category ``FiniteSets()``. + - ``domain`` -- an object in the category ``FiniteSets()`` - ``category`` -- the category in which the sets of maps is constructed. It must be a sub-category of ``Monoids().Finite()`` diff --git a/src/sage/sets/image_set.py b/src/sage/sets/image_set.py index e2780d523c8..a518dc58f93 100644 --- a/src/sage/sets/image_set.py +++ b/src/sage/sets/image_set.py @@ -16,7 +16,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from typing import Iterator +from collections.abc import Iterator from sage.categories.map import Map from sage.categories.poor_man_map import PoorManMap @@ -25,7 +25,6 @@ from sage.misc.cachefunc import cached_method from sage.rings.infinity import Infinity from sage.rings.integer import Integer -from sage.modules.free_module import FreeModule from sage.structure.element import Expression from sage.structure.parent import Parent @@ -52,7 +51,7 @@ class ImageSubobject(Parent): - ``None`` (default): infer from ``map`` or default to ``False`` - ``False``: do not assume that ``map`` is injective - ``True``: ``map`` is known to be injective - - ``"check"``: raise an error when ``map`` is not injective + - ``'check'``: raise an error when ``map`` is not injective - ``inverse`` -- a function (optional); a map from `f(X)` to `X` @@ -91,6 +90,7 @@ def __init__(self, map, domain_subset, *, category=None, is_injective=None, inve if isinstance(map, Expression) and map.is_callable(): domain = map.parent().base() if len(map.arguments()) != 1: + from sage.modules.free_module import FreeModule domain = FreeModule(domain, len(map.arguments())) function = map diff --git a/src/sage/sets/integer_range.py b/src/sage/sets/integer_range.py index 31602abb5a6..3b95506f591 100644 --- a/src/sage/sets/integer_range.py +++ b/src/sage/sets/integer_range.py @@ -27,16 +27,16 @@ class IntegerRange(UniqueRepresentation, Parent): r""" - The class of :class:`Integer ` ranges + The class of :class:`Integer ` ranges. Returns an enumerated set containing an arithmetic progression of integers. INPUT: - - ``begin`` -- an integer, Infinity or -Infinity - - ``end`` -- an integer, Infinity or -Infinity - - ``step`` -- a non zero integer (default to 1) - - ``middle_point`` -- an integer inside the set (default to ``None``) + - ``begin`` -- integer, Infinity or -Infinity + - ``end`` -- integer, Infinity or -Infinity + - ``step`` -- a nonzero integer (default: 1) + - ``middle_point`` -- integer inside the set (default: ``None``) OUTPUT: @@ -156,7 +156,7 @@ class IntegerRange(UniqueRepresentation, Parent): [0, 10, -10, 20, -20, 30, -30, 40, -40, 50, -50, 60, -60, 70, -70, 80, -80, 90, -90, -100] - .. note:: + .. NOTE:: The input is normalized so that:: @@ -290,7 +290,7 @@ def _element_constructor_(self, el): class IntegerRangeEmpty(IntegerRange, FiniteEnumeratedSet): r""" - A singleton class for empty integer ranges + A singleton class for empty integer ranges. See :class:`IntegerRange` for more details. """ @@ -338,7 +338,7 @@ def __init__(self, begin, end, step=Integer(1)): def __contains__(self, elt): r""" - Returns True if ``elt`` is in ``self``. + Return ``True`` if ``elt`` is in ``self``. EXAMPLES:: @@ -373,7 +373,7 @@ def __contains__(self, elt): def cardinality(self): """ - Return the cardinality of ``self`` + Return the cardinality of ``self``. EXAMPLES:: @@ -384,7 +384,7 @@ def cardinality(self): sage: IntegerRange(123,12,4).cardinality() 0 """ - return (abs((self._end+self._step-self._begin))-1) // abs(self._step) + return (abs(self._end+self._step-self._begin)-1) // abs(self._step) def _repr_(self): """ @@ -482,7 +482,7 @@ def __getitem__(self, i): def __iter__(self): r""" - Returns an iterator over the elements of ``self`` + Return an iterator over the elements of ``self``. EXAMPLES:: @@ -507,7 +507,7 @@ def __iter__(self): def _an_element_(self): r""" - Returns an element of ``self``. + Return an element of ``self``. EXAMPLES:: @@ -564,7 +564,7 @@ def _repr_(self): def __contains__(self, elt): r""" - Returns True if ``elt`` is in ``self``. + Return ``True`` if ``elt`` is in ``self``. EXAMPLES:: @@ -608,7 +608,7 @@ def rank(self, x): def __getitem__(self, i): r""" - Returns the ``i``-th element of self. + Return the ``i``-th element of ``self``. EXAMPLES:: @@ -633,7 +633,7 @@ def __getitem__(self, i): def __iter__(self): r""" - Returns an iterator over the elements of ``self``. + Return an iterator over the elements of ``self``. EXAMPLES:: @@ -654,7 +654,7 @@ def __iter__(self): def _an_element_(self): r""" - Returns an element of ``self``. + Return an element of ``self``. EXAMPLES:: @@ -725,7 +725,7 @@ def _repr_(self): def __contains__(self, elt): r""" - Returns True if ``elt`` is in ``self``. + Return ``True`` if ``elt`` is in ``self``. EXAMPLES:: @@ -792,7 +792,7 @@ def next(self, elt): def __iter__(self): r""" - Returns an iterator over the elements of ``self``. + Return an iterator over the elements of ``self``. EXAMPLES:: @@ -813,7 +813,7 @@ def __iter__(self): def _an_element_(self): r""" - Returns an element of ``self``. + Return an element of ``self``. EXAMPLES:: diff --git a/src/sage/sets/meson.build b/src/sage/sets/meson.build new file mode 100644 index 00000000000..73faddaf9c7 --- /dev/null +++ b/src/sage/sets/meson.build @@ -0,0 +1,44 @@ +py.install_sources( + 'all.py', + 'all__sagemath_objects.py', + 'cartesian_product.py', + 'condition_set.py', + 'disjoint_set.pxd', + 'disjoint_union_enumerated_sets.py', + 'family.pxd', + 'finite_enumerated_set.py', + 'finite_set_map_cy.pxd', + 'finite_set_maps.py', + 'image_set.py', + 'integer_range.py', + 'non_negative_integers.py', + 'positive_integers.py', + 'primes.py', + 'pythonclass.pxd', + 'real_set.py', + 'recursively_enumerated_set.pxd', + 'set.py', + 'set_from_iterator.py', + 'totally_ordered_finite_set.py', + subdir: 'sage/sets', +) + +extension_data = { + 'disjoint_set' : files('disjoint_set.pyx'), + 'family' : files('family.pyx'), + 'finite_set_map_cy' : files('finite_set_map_cy.pyx'), + 'pythonclass' : files('pythonclass.pyx'), + 'recursively_enumerated_set' : files('recursively_enumerated_set.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/sets', + install: true, + include_directories: [inc_cpython, inc_data_structures], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/sets/non_negative_integers.py b/src/sage/sets/non_negative_integers.py index a7995ff3e1e..ab7960df3d1 100644 --- a/src/sage/sets/non_negative_integers.py +++ b/src/sage/sets/non_negative_integers.py @@ -16,9 +16,9 @@ class NonNegativeIntegers(UniqueRepresentation, Parent): r""" - The enumerated set of non negative integers. + The enumerated set of nonnegative integers. - This class implements the set of non negative integers, as an + This class implements the set of nonnegative integers, as an enumerated set (see :class:`InfiniteEnumeratedSets `). @@ -123,8 +123,8 @@ def __contains__(self, elt): def _element_constructor_(self, i): """ - Constructs an element of self from an integer, testing that - this integer is indeed non negative. + Construct an element of ``self`` from an integer, testing that + this integer is indeed nonnegative. EXAMPLES:: diff --git a/src/sage/sets/positive_integers.py b/src/sage/sets/positive_integers.py index 70625fb53b7..31502df53d8 100644 --- a/src/sage/sets/positive_integers.py +++ b/src/sage/sets/positive_integers.py @@ -68,7 +68,7 @@ def _repr_(self): def an_element(self): r""" - Returns an element of ``self``. + Return an element of ``self``. EXAMPLES:: diff --git a/src/sage/sets/pythonclass.pyx b/src/sage/sets/pythonclass.pyx index 7b75bd7bf26..02f34931b64 100644 --- a/src/sage/sets/pythonclass.pyx +++ b/src/sage/sets/pythonclass.pyx @@ -106,7 +106,7 @@ cdef class Set_PythonType_class(Set_generic): def __reduce__(self): r""" - Pickling support + Pickling support. TESTS:: diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index 168521ce6a8..d502dbc4a4a 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -120,20 +120,17 @@ class InternalRealInterval(UniqueRepresentation, Parent): INPUT: - - ``lower`` -- real or minus infinity; the lower bound of the - interval. + - ``lower`` -- real or minus infinity; the lower bound of the interval - - ``lower_closed`` -- boolean; whether the interval is closed - at the lower bound + - ``lower_closed`` -- boolean; whether the interval is closed at the lower + bound - - ``upper`` -- real or (plus) infinity; the upper bound of the - interval + - ``upper`` -- real or (plus) infinity; the upper bound of the interval - - ``upper_closed`` -- boolean; whether the interval is closed - at the upper bound + - ``upper_closed`` -- boolean; whether the interval is closed at the upper + bound - - ``check`` -- boolean; whether to check the other arguments - for validity + - ``check`` -- boolean; whether to check the other arguments for validity """ def __init__(self, lower, lower_closed, upper, upper_closed, check=True): @@ -170,14 +167,12 @@ def __init__(self, lower, lower_closed, upper, upper_closed, check=True): def is_empty(self): """ - Return whether the interval is empty + Return whether the interval is empty. The normalized form of :class:`RealSet` has all intervals non-empty, so this method usually returns ``False``. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -189,11 +184,9 @@ def is_empty(self): def is_point(self): """ - Return whether the interval consists of a single point + Return whether the interval consists of a single point. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -205,11 +198,9 @@ def is_point(self): def lower(self): """ - Return the lower bound - - OUTPUT: + Return the lower bound. - The lower bound as it was originally specified. + OUTPUT: the lower bound as it was originally specified EXAMPLES:: @@ -226,11 +217,9 @@ def lower(self): def upper(self): """ - Return the upper bound - - OUTPUT: + Return the upper bound. - The upper bound as it was originally specified. + OUTPUT: the upper bound as it was originally specified EXAMPLES:: @@ -247,11 +236,9 @@ def upper(self): def lower_closed(self): """ - Return whether the interval is open at the lower bound - - OUTPUT: + Return whether the interval is open at the lower bound. - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -270,11 +257,9 @@ def lower_closed(self): def upper_closed(self): """ - Return whether the interval is closed at the lower bound + Return whether the interval is closed at the lower bound. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -293,11 +278,9 @@ def upper_closed(self): def lower_open(self): """ - Return whether the interval is closed at the upper bound + Return whether the interval is closed at the upper bound. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -316,11 +299,9 @@ def lower_open(self): def upper_open(self): """ - Return whether the interval is closed at the upper bound - - OUTPUT: + Return whether the interval is closed at the upper bound. - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -339,11 +320,9 @@ def upper_open(self): def __richcmp__(self, other, op): """ - Intervals are sorted by lower bound, then upper bound - - OUTPUT: + Intervals are sorted by lower bound, then upper bound. - `-1`, `0`, or `+1` depending on how the intervals compare. + OUTPUT: `-1`, `0`, or `+1` depending on how the intervals compare EXAMPLES:: @@ -373,11 +352,9 @@ def __richcmp__(self, other, op): def _repr_(self): """ - Return a string representation - - OUTPUT: + Return a string representation. - String. + OUTPUT: string EXAMPLES:: @@ -401,7 +378,7 @@ def _repr_(self): s += ']' if self._upper_closed else ')' return s - def _latex_(self): + def _latex_(self) -> str: """ Return a latex representation of ``self``. @@ -415,7 +392,7 @@ def _latex_(self): from sage.misc.latex import latex if self.is_point(): # Converting to str avoids the extra whitespace - # that LatexExpr add on concenation. We do not need + # that LatexExpr add on concatenation. We do not need # the whitespace because we are wrapping it in # non-letter characters. return r'\{' + str(latex(self.lower())) + r'\}' @@ -521,11 +498,9 @@ def _giac_condition_(self, variable): def closure(self): """ - Return the closure - - OUTPUT: + Return the closure. - The closure as a new :class:`InternalRealInterval` + OUTPUT: the closure as a new :class:`InternalRealInterval` EXAMPLES:: @@ -546,11 +521,9 @@ def closure(self): def interior(self): """ - Return the interior - - OUTPUT: + Return the interior. - The interior as a new :class:`InternalRealInterval` + OUTPUT: the interior as a new :class:`InternalRealInterval` EXAMPLES:: @@ -565,7 +538,7 @@ def interior(self): def boundary_points(self): """ - Generate the boundary points of ``self`` + Generate the boundary points of ``self``. EXAMPLES:: @@ -573,7 +546,6 @@ def boundary_points(self): [1] sage: list(RealSet.open(1, 2)[0].boundary_points()) [1, 2] - """ if self._lower != minus_infinity: yield self._lower @@ -582,11 +554,11 @@ def boundary_points(self): def is_connected(self, other): """ - Test whether two intervals are connected + Test whether two intervals are connected. OUTPUT: - Boolean. Whether the set-theoretic union of the two intervals + boolean; whether the set-theoretic union of the two intervals has a single connected component. EXAMPLES:: @@ -631,11 +603,9 @@ def is_connected(self, other): def convex_hull(self, other): """ - Return the convex hull of the two intervals - - OUTPUT: + Return the convex hull of the two intervals. - The convex hull as a new :class:`InternalRealInterval`. + OUTPUT: the convex hull as a new :class:`InternalRealInterval` EXAMPLES:: @@ -680,15 +650,13 @@ def convex_hull(self, other): def intersection(self, other): """ - Return the intersection of the two intervals + Return the intersection of the two intervals. INPUT: - ``other`` -- a :class:`InternalRealInterval` - OUTPUT: - - The intersection as a new :class:`InternalRealInterval` + OUTPUT: the intersection as a new :class:`InternalRealInterval` EXAMPLES:: @@ -739,15 +707,13 @@ def intersection(self, other): def contains(self, x): """ - Return whether `x` is contained in the interval + Return whether `x` is contained in the interval. INPUT: - - ``x`` -- a real number. + - ``x`` -- a real number - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -850,7 +816,7 @@ def __rmul__(self, other): def _scan_lower(self): r""" - Helper function for the scan-line method of :class:`RealSet` + Helper function for the scan-line method of :class:`RealSet`. OUTPUT: @@ -886,7 +852,7 @@ def _scan_lower(self): def _scan_upper(self): r""" - Helper function for the scan-line method of :class:`RealSet` + Helper function for the scan-line method of :class:`RealSet`. OUTPUT: @@ -925,7 +891,7 @@ def _scan_upper(self): class RealSet(UniqueRepresentation, Parent, Set_base, Set_boolean_operators, Set_add_sub_operators): r""" - A subset of the real line, a finite union of intervals + A subset of the real line, a finite union of intervals. INPUT: @@ -941,7 +907,7 @@ class RealSet(UniqueRepresentation, Parent, Set_base, - an :class:`~sage.manifolds.differentiable.examples.real_line.OpenInterval`. - ``structure`` -- (default: ``None``) if ``None``, construct the real set as an - instance of :class:`RealSet`; if ``"differentiable"``, construct it as a subset of + instance of :class:`RealSet`; if ``'differentiable'``, construct it as a subset of an instance of :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`, representing the differentiable manifold `\RR`. - ``ambient`` -- (default: ``None``) an instance of @@ -951,7 +917,7 @@ class RealSet(UniqueRepresentation, Parent, Set_base, :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`. Using these keywords implies ``structure='differentiable'``. - ``name``, ``latex_name``, ``start_index`` -- see - :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`. + :class:`~sage.manifolds.differentiable.examples.real_line.RealLine` - ``normalized`` -- (default: ``None``) if ``True``, the input is already normalized, i.e., ``*args`` are the connected components (type :class:`InternalRealInterval`) of the real set in ascending order; no other keyword is provided. @@ -1087,7 +1053,7 @@ class RealSet(UniqueRepresentation, Parent, Set_base, Set {(0, +oo), (0, 1), ℝ} of open subsets of the Real number line ℝ sage: F = RealSet.point(0).union(RealSet.point(1)).union(RealSet.point(2)); F {0} ∪ {1} ∪ {2} - sage: F_tau = RealSet(F, names="τ"); F_tau + sage: F_tau = RealSet(F, names='τ'); F_tau Subset {0} ∪ {1} ∪ {2} of the Real number line ℝ sage: F_tau.manifold().canonical_chart() Chart (ℝ, (τ,)) @@ -1117,9 +1083,7 @@ def __classcall__(cls, *args, **kwds): See :class:`RealSet`. - OUTPUT: - - A :class:`RealSet`. + OUTPUT: a :class:`RealSet` EXAMPLES:: @@ -1354,11 +1318,9 @@ def __init__(self, *intervals, normalized=True): def __richcmp__(self, other, op): r""" - Intervals are sorted by lower bound, then upper bound - - OUTPUT: + Intervals are sorted by lower bound, then upper bound. - `-1`, `0`, or `+1` depending on how the intervals compare. + OUTPUT: `-1`, `0`, or `+1` depending on how the intervals compare EXAMPLES:: @@ -1381,11 +1343,9 @@ def __richcmp__(self, other, op): def __iter__(self): r""" - Iterate over the component intervals is ascending order - - OUTPUT: + Iterate over the component intervals is ascending order. - An iterator over the intervals. + OUTPUT: an iterator over the intervals EXAMPLES:: @@ -1400,9 +1360,9 @@ def __iter__(self): def n_components(self): r""" - Return the number of connected components + Return the number of connected components. - See also :meth:`get_interval` + See also :meth:`get_interval`. EXAMPLES:: @@ -1418,7 +1378,7 @@ def cardinality(self): OUTPUT: - Integer or infinity. The size of a discrete set is the number + Integer or infinity; the size of a discrete set is the number of points; the size of a real interval is Infinity. EXAMPLES:: @@ -1438,7 +1398,7 @@ def cardinality(self): def is_empty(self): r""" - Return whether the set is empty + Return whether the set is empty. EXAMPLES:: @@ -1473,11 +1433,9 @@ def get_interval(self, i): INPUT: - - ``i`` -- integer. - - OUTPUT: + - ``i`` -- integer - The `i`-th connected component as a :class:`InternalRealInterval`. + OUTPUT: the `i`-th connected component as a :class:`InternalRealInterval` EXAMPLES:: @@ -1561,15 +1519,13 @@ def retract(self, x): def normalize(intervals): r""" - Bring a collection of intervals into canonical form + Bring a collection of intervals into canonical form. INPUT: - - ``intervals`` -- a list/tuple/iterable of intervals. + - ``intervals`` -- list/tuple/iterable of intervals - OUTPUT: - - A tuple of intervals such that + OUTPUT: a tuple of intervals such that * they are sorted in ascending order (by lower bound) @@ -1593,9 +1549,7 @@ def _repr_(self): r""" Return a string representation of ``self``. - OUTPUT: - - A string representation. + OUTPUT: string representation EXAMPLES:: @@ -1698,7 +1652,7 @@ def _giac_condition_(self, variable): @staticmethod def _prep(lower, upper=None): r""" - Helper to prepare the lower and upper bounds + Helper to prepare the lower and upper bounds. EXAMPLES:: @@ -1735,21 +1689,19 @@ def _prep(lower, upper=None): @staticmethod def interval(lower, upper, *, lower_closed=None, upper_closed=None, **kwds): r""" - Construct an interval + Construct an interval. INPUT: - - ``lower``, ``upper`` -- two real numbers or infinity. They - will be sorted if necessary. + - ``lower``, ``upper`` -- two real numbers or infinity; they + will be sorted if necessary - ``lower_closed``, ``upper_closed`` -- boolean; whether the interval - is closed at the lower and upper bound of the interval, respectively. - - - ``**kwds`` -- see :class:`RealSet`. + is closed at the lower and upper bound of the interval, respectively - OUTPUT: + - ``**kwds`` -- see :class:`RealSet` - A new :class:`RealSet`. + OUTPUT: a new :class:`RealSet` EXAMPLES:: @@ -1764,18 +1716,16 @@ def interval(lower, upper, *, lower_closed=None, upper_closed=None, **kwds): @staticmethod def open(lower, upper, **kwds): r""" - Construct an open interval + Construct an open interval. INPUT: - - ``lower``, ``upper`` -- two real numbers or infinity. They - will be sorted if necessary. - - - ``**kwds`` -- see :class:`RealSet`. + - ``lower``, ``upper`` -- two real numbers or infinity; they + will be sorted if necessary - OUTPUT: + - ``**kwds`` -- see :class:`RealSet` - A new :class:`RealSet`. + OUTPUT: a new :class:`RealSet` EXAMPLES:: @@ -1788,18 +1738,16 @@ def open(lower, upper, **kwds): @staticmethod def closed(lower, upper, **kwds): r""" - Construct a closed interval + Construct a closed interval. INPUT: - - ``lower``, ``upper`` -- two real numbers or infinity. They - will be sorted if necessary. + - ``lower``, ``upper`` -- two real numbers or infinity; they + will be sorted if necessary - - ``**kwds`` -- see :class:`RealSet`. - - OUTPUT: + - ``**kwds`` -- see :class:`RealSet` - A new :class:`RealSet`. + OUTPUT: a new :class:`RealSet` EXAMPLES:: @@ -1812,17 +1760,15 @@ def closed(lower, upper, **kwds): @staticmethod def point(p, **kwds): r""" - Construct an interval containing a single point + Construct an interval containing a single point. INPUT: - - ``p`` -- a real number. + - ``p`` -- a real number - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` - OUTPUT: - - A new :class:`RealSet`. + OUTPUT: a new :class:`RealSet` EXAMPLES:: @@ -1835,14 +1781,14 @@ def point(p, **kwds): @staticmethod def open_closed(lower, upper, **kwds): r""" - Construct a half-open interval + Construct a half-open interval. INPUT: - - ``lower``, ``upper`` -- two real numbers or infinity. They - will be sorted if necessary. + - ``lower``, ``upper`` -- two real numbers or infinity; they + will be sorted if necessary - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` OUTPUT: @@ -1860,14 +1806,14 @@ def open_closed(lower, upper, **kwds): @staticmethod def closed_open(lower, upper, **kwds): r""" - Construct a half-open interval + Construct a half-open interval. INPUT: - - ``lower``, ``upper`` -- two real numbers or infinity. They - will be sorted if necessary. + - ``lower``, ``upper`` -- two real numbers or infinity; they + will be sorted if necessary - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` OUTPUT: @@ -1885,17 +1831,17 @@ def closed_open(lower, upper, **kwds): @staticmethod def unbounded_below_closed(bound, **kwds): r""" - Construct a semi-infinite interval + Construct a semi-infinite interval. INPUT: - - ``bound`` -- a real number. + - ``bound`` -- a real number OUTPUT: A new :class:`RealSet` from minus infinity to the bound (including). - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` EXAMPLES:: @@ -1908,17 +1854,17 @@ def unbounded_below_closed(bound, **kwds): @staticmethod def unbounded_below_open(bound, **kwds): r""" - Construct a semi-infinite interval + Construct a semi-infinite interval. INPUT: - - ``bound`` -- a real number. + - ``bound`` -- a real number OUTPUT: A new :class:`RealSet` from minus infinity to the bound (excluding). - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` EXAMPLES:: @@ -1931,13 +1877,13 @@ def unbounded_below_open(bound, **kwds): @staticmethod def unbounded_above_closed(bound, **kwds): r""" - Construct a semi-infinite interval + Construct a semi-infinite interval. INPUT: - - ``bound`` -- a real number. + - ``bound`` -- a real number - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` OUTPUT: @@ -1955,13 +1901,13 @@ def unbounded_above_closed(bound, **kwds): @staticmethod def unbounded_above_open(bound, **kwds): r""" - Construct a semi-infinite interval + Construct a semi-infinite interval. INPUT: - - ``bound`` -- a real number. + - ``bound`` -- a real number - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` OUTPUT: @@ -1979,11 +1925,11 @@ def unbounded_above_open(bound, **kwds): @staticmethod def real_line(**kwds): r""" - Construct the real line + Construct the real line. INPUT: - - ``**kwds`` -- see :class:`RealSet`. + - ``**kwds`` -- see :class:`RealSet` EXAMPLES:: @@ -1994,7 +1940,7 @@ def real_line(**kwds): def _scan(self): r""" - Helper function for the scan-line method of :class:`RealSet` + Helper function for the scan-line method of :class:`RealSet`. OUTPUT: @@ -2040,7 +1986,7 @@ def _scan(self): @staticmethod def _scan_to_intervals(scan, condition): r""" - Helper function for the scan-line method of :class:`RealSet` + Helper function for the scan-line method of :class:`RealSet`. INPUT: @@ -2048,9 +1994,7 @@ def _scan_to_intervals(scan, condition): ``(x, epsilon), delta``, see :meth:`_scan` - ``condition`` -- a function indicating the on or off boundary points - OUTPUT: - - Generate :class:`InternalRealInterval` objects. + OUTPUT: generate :class:`InternalRealInterval` objects EXAMPLES:: @@ -2088,16 +2032,14 @@ def _scan_to_intervals(scan, condition): def union(self, *real_set_collection): """ - Return the union of real sets + Return the union of real sets. INPUT: - - ``*real_set_collection`` -- a list/tuple/iterable of :class:`RealSet` - or data that defines one. - - OUTPUT: + - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet` + or data that defines one - The set-theoretic union as a new :class:`RealSet`. + OUTPUT: the set-theoretic union as a new :class:`RealSet` EXAMPLES:: @@ -2142,16 +2084,14 @@ def union(self, *real_set_collection): def intersection(self, *real_set_collection): """ - Return the intersection of real sets + Return the intersection of real sets. INPUT: - - ``*real_set_collection`` -- a list/tuple/iterable of :class:`RealSet` - or data that defines one. - - OUTPUT: + - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet` + or data that defines one - The set-theoretic intersection as a new :class:`RealSet`. + OUTPUT: the set-theoretic intersection as a new :class:`RealSet` EXAMPLES:: @@ -2222,11 +2162,9 @@ def intersection(self, *real_set_collection): def inf(self): """ - Return the infimum - - OUTPUT: + Return the infimum. - A real number or infinity. + OUTPUT: a real number or infinity EXAMPLES:: @@ -2246,11 +2184,9 @@ def inf(self): def sup(self): """ - Return the supremum + Return the supremum. - OUTPUT: - - A real number or infinity. + OUTPUT: a real number or infinity EXAMPLES:: @@ -2270,11 +2206,9 @@ def sup(self): def complement(self): """ - Return the complement + Return the complement. - OUTPUT: - - The set-theoretic complement as a new :class:`RealSet`. + OUTPUT: the set-theoretic complement as a new :class:`RealSet` EXAMPLES:: @@ -2304,11 +2238,11 @@ def complement(self): def difference(self, *other): """ - Return ``self`` with ``other`` subtracted + Return ``self`` with ``other`` subtracted. INPUT: - - ``other`` -- a :class:`RealSet` or data that defines one. + - ``other`` -- a :class:`RealSet` or data that defines one OUTPUT: @@ -2342,11 +2276,11 @@ def difference(self, *other): def symmetric_difference(self, *other): r""" - Returns the symmetric difference of ``self`` and ``other``. + Return the symmetric difference of ``self`` and ``other``. INPUT: - - ``other`` -- a :class:`RealSet` or data that defines one. + - ``other`` -- a :class:`RealSet` or data that defines one OUTPUT: @@ -2368,15 +2302,13 @@ def symmetric_difference(self, *other): def contains(self, x): """ - Return whether `x` is contained in the set + Return whether `x` is contained in the set. INPUT: - - ``x`` -- a real number. - - OUTPUT: + - ``x`` -- a real number - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -2409,12 +2341,9 @@ def is_subset(self, *other): INPUT: - - ``*other`` -- a :class:`RealSet` or something that defines - one. - - OUTPUT: + - ``*other`` -- a :class:`RealSet` or something that defines one - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -2432,11 +2361,9 @@ def is_subset(self, *other): def _an_element_(self): """ - Return a point of the set - - OUTPUT: + Return a point of the set. - A real number. + OUTPUT: a real number It raises an :class:`~sage.categories.sets_cat.EmptySetError` if the set is empty. @@ -2564,7 +2491,6 @@ def boundary(self): {1} ∪ {2} ∪ {3} ∪ {4} sage: RealSet((1, 2), (2, 3)).boundary() {1} ∪ {2} ∪ {3} - """ return RealSet(*[RealSet.point(x) for i in self._intervals for x in i.boundary_points()]) @@ -2575,12 +2501,10 @@ def convex_hull(*real_set_collection): INPUT: - - ``*real_set_collection`` -- a list/tuple/iterable of :class:`RealSet` - or data that defines one. - - OUTPUT: + - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet` + or data that defines one - The convex hull as a new :class:`RealSet`. + OUTPUT: the convex hull as a new :class:`RealSet` EXAMPLES:: @@ -2613,11 +2537,9 @@ def convex_hull(*real_set_collection): s = RealSet(real_set) if s.n_components() > 0: lower_s = s[0]._scan_lower() - if lower_s < lower_scan: - lower_scan = lower_s + lower_scan = min(lower_s, lower_scan) upper_s = s[-1]._scan_upper() - if upper_s > upper_scan: - upper_scan = upper_s + upper_scan = max(upper_s, upper_scan) if lower_scan < upper_scan: lower, lower_closed = lower_scan[0][0], lower_scan[0][1] == 0 upper, upper_closed = upper_scan[0][0], upper_scan[0][1] > 0 @@ -2629,9 +2551,7 @@ def is_connected(self): """ Return whether ``self`` is a connected set. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -2658,15 +2578,13 @@ def is_connected(self): def is_disjoint(self, *other): """ - Test whether the two sets are disjoint + Test whether the two sets are disjoint. INPUT: - - ``other`` -- a :class:`RealSet` or data defining one. + - ``other`` -- a :class:`RealSet` or data defining one - OUTPUT: - - Boolean. + OUTPUT: boolean .. SEEALSO:: :meth:`are_pairwise_disjoint` @@ -2691,16 +2609,14 @@ def is_disjoint(self, *other): @staticmethod def are_pairwise_disjoint(*real_set_collection): """ - Test whether the real sets are pairwise disjoint + Test whether the real sets are pairwise disjoint. INPUT: - - ``*real_set_collection`` -- a list/tuple/iterable of :class:`RealSet` - or data that defines one. - - OUTPUT: + - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet` + or data that defines one - Boolean. + OUTPUT: boolean .. SEEALSO:: :meth:`is_disjoint` diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index c125d151867..3d9d4a00f75 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -29,7 +29,7 @@ structure, such as not containing an oriented cycle, that does not help with the enumeration. In this example, the seed is 0 and the successor function is either ``+2`` -or ``+3``. This is the set of non negative linear combinations of 2 and 3:: +or ``+3``. This is the set of nonnegative linear combinations of 2 and 3:: sage: succ = lambda a:[a+2,a+3] sage: C = RecursivelyEnumeratedSet([0], succ) @@ -310,24 +310,24 @@ def RecursivelyEnumeratedSet(seeds, successors, structure=None, - ``seeds`` -- list (or iterable) of hashable objects - ``successors`` -- function (or callable) returning a list (or iterable) of hashable objects - - ``structure`` -- string (default: ``None``), structure of the + - ``structure`` -- string (default: ``None``); structure of the set, possible values are: - - ``None`` -- nothing is known about the structure of the set. + - ``None`` -- nothing is known about the structure of the set - ``'forest'`` -- if the ``successors`` function generates a *forest*, that - is, each element can be reached uniquely from a seed. + is, each element can be reached uniquely from a seed - ``'graded'`` -- if the ``successors`` function is *graded*, that is, all - paths from a seed to a given element have equal length. + paths from a seed to a given element have equal length - ``'symmetric'`` -- if the relation is *symmetric*, that is, ``y in successors(x)`` if and only if ``x in successors(y)`` - ``enumeration`` -- ``'depth'``, ``'breadth'``, ``'naive'`` or ``None`` - (default: ``None``). The default enumeration for the - ``__iter__`` function. - - ``max_depth`` -- integer (default: ``float("inf")``), limit + (default: ``None``); the default enumeration for the + ``__iter__`` function + - ``max_depth`` -- integer (default: ``float("inf")``); limit the search to a certain depth, currently works only for breadth first search - - ``post_process`` -- (default: ``None``), for forest only + - ``post_process`` -- (default: ``None``) for forest only - ``facade`` -- (default: ``None``) - ``category`` -- (default: ``None``) @@ -705,9 +705,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): It is currently implemented only for graded or symmetric structure. - OUTPUT: - - An iterator of sets. + OUTPUT: an iterator of sets EXAMPLES:: @@ -733,9 +731,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): - ``depth`` -- integer - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -760,9 +756,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): - ``depth`` -- integer - OUTPUT: - - An iterator. + OUTPUT: an iterator EXAMPLES:: @@ -913,12 +907,10 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): - ``max_depth`` -- (default: ``self._max_depth``) specifies the maximal depth for which outgoing edges of elements are computed - - ``loops`` -- (default: ``True``) option for the digraph - - ``multiedges`` -- (default: ``True``) option of the digraph + - ``loops`` -- boolean (default: ``True``); option for the digraph + - ``multiedges`` -- boolean (default: ``True``); option of the digraph - OUTPUT: - - A directed graph + OUTPUT: a directed graph .. WARNING:: @@ -1079,9 +1071,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): The enumeration remembers only the last two graded components generated since the structure is symmetric. - OUTPUT: - - An iterator of sets. + OUTPUT: an iterator of sets EXAMPLES:: @@ -1162,9 +1152,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): - ``depth`` -- integer - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -1223,9 +1211,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): - ``A`` -- set, the set of elements of depth n-1 - ``B`` -- set, the set of elements of depth n - OUTPUT: - - - ``C`` -- set, the set of elements of depth n+1 + OUTPUT: ``C``; the set of elements of depth n+1 .. TODO:: @@ -1331,9 +1317,7 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): The algorithm remembers only the current graded component generated since the structure is graded. - OUTPUT: - - An iterator of sets. + OUTPUT: an iterator of sets EXAMPLES:: @@ -1384,9 +1368,7 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): - ``depth`` -- integer - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -1440,9 +1422,7 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): - ``B`` -- set, the set of elements of depth `n` - OUTPUT: - - - ``C`` -- set, the set of elements of depth `n+1` + OUTPUT: ``C``; the set of elements of depth `n+1` .. TODO:: @@ -1498,7 +1478,7 @@ def search_forest_iterator(roots, children, algorithm='depth'): INPUT: - - ``roots`` -- a list (or iterable) + - ``roots`` -- list (or iterable) - ``children`` -- a function returning a list (or iterable) - ``algorithm`` -- ``'depth'`` or ``'breadth'`` (default: ``'depth'``) @@ -1590,7 +1570,7 @@ class RecursivelyEnumeratedSet_forest(Parent): INPUT: - - ``roots`` -- a list (or iterable) + - ``roots`` -- list (or iterable) - ``children`` -- a function returning a list (or iterable, or iterator) - ``post_process`` -- a function defined over the nodes of the forest (default: no post processing) @@ -1812,7 +1792,7 @@ class RecursivelyEnumeratedSet_forest(Parent): @abstract_method def children(self, x): r""" - Return the children of the element ``x`` + Return the children of the element ``x``. The result can be a list, an iterable, an iterator, or even a generator. @@ -1860,7 +1840,7 @@ class RecursivelyEnumeratedSet_forest(Parent): def depth_first_search_iterator(self): r""" - Return a depth first search iterator over the elements of ``self`` + Return a depth first search iterator over the elements of ``self``. EXAMPLES:: @@ -1875,7 +1855,7 @@ class RecursivelyEnumeratedSet_forest(Parent): def breadth_first_search_iterator(self): r""" - Return a breadth first search iterator over the elements of ``self`` + Return a breadth first search iterator over the elements of ``self``. EXAMPLES:: @@ -2052,7 +2032,7 @@ class RecursivelyEnumeratedSet_forest(Parent): reduce_function = None, reduce_init = None): r""" - Apply a Map/Reduce algorithm on ``self`` + Apply a Map/Reduce algorithm on ``self``. INPUT: @@ -2061,12 +2041,12 @@ class RecursivelyEnumeratedSet_forest(Parent): the constant function ``1``. - ``reduce_function`` -- the reduce function (e.g.: the addition of a - monoid). The default value is ``+``. + monoid); the default value is ``+`` - ``reduce_init`` -- the initialisation of the reduction (e.g.: the - neutral element of the monoid). The default value is ``0``. + neutral element of the monoid); the default value is ``0`` - .. note:: + .. NOTE:: the effect of the default values is to compute the cardinality of ``self``. diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index 2a5c8c86f23..5bda2d79169 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -209,7 +209,7 @@ def Set(X=None, category=None): return Set_object_enumerated(X, category=category) -class Set_base(): +class Set_base: r""" Abstract base class for sets, not necessarily parents. """ @@ -303,7 +303,7 @@ def difference(self, X): def symmetric_difference(self, X): r""" - Returns the symmetric difference of ``self`` and ``X``. + Return the symmetric difference of ``self`` and ``X``. EXAMPLES:: @@ -342,7 +342,7 @@ def _test_as_set_object(self, tester=None, **options): if set_self is not self: from sage.misc.sage_unittest import TestSuite tester.info("\n Running the test suite of Set(self)") - TestSuite(set_self).run(skip="_test_pickling", # see Issue #32025 + TestSuite(set_self).run(skip='_test_pickling', # see Issue #32025 verbose=tester._verbose, prefix=tester._prefix + " ") tester.info(tester._prefix + " ", newline=False) @@ -371,7 +371,7 @@ def __or__(self, X): def __and__(self, X): """ - Returns the intersection of ``self`` and ``X``. + Return the intersection of ``self`` and ``X``. EXAMPLES:: @@ -384,7 +384,7 @@ def __and__(self, X): def __xor__(self, X): """ - Returns the symmetric difference of ``self`` and ``X``. + Return the symmetric difference of ``self`` and ``X``. EXAMPLES:: @@ -470,7 +470,7 @@ class Set_object(Set_generic, Set_base, Set_boolean_operators, Set_add_sub_opera def __init__(self, X, category=None): """ - Create a Set_object + Create a Set_object. This function is called by the Set function; users shouldn't call this directly. @@ -704,9 +704,7 @@ def is_empty(self): """ Return boolean representing emptiness of the set. - OUTPUT: - - True if the set is empty, False if otherwise. + OUTPUT: ``True`` if the set is empty, ``False`` otherwise EXAMPLES:: @@ -806,7 +804,6 @@ def subsets_lattice(self): sage: Y = Set() sage: Y.subsets_lattice() # needs sage.graphs Finite lattice containing 1 elements - """ if not self.is_finite(): raise NotImplementedError( @@ -1094,7 +1091,7 @@ def issubset(self, other): INPUT: - - ``other`` -- a finite Set + - ``other`` -- a finite Set EXAMPLES:: @@ -1122,7 +1119,7 @@ def issuperset(self, other): INPUT: - - ``other`` -- a finite Set + - ``other`` -- a finite Set EXAMPLES:: @@ -1267,9 +1264,9 @@ class Set_object_binary(Set_object, metaclass=ClasscallMetaclass): - ``X``, ``Y`` -- sets, the operands to ``op`` - - ``op`` -- a string describing the binary operation + - ``op`` -- string describing the binary operation - - ``latex_op`` -- a string used for rendering this object in LaTeX + - ``latex_op`` -- string used for rendering this object in LaTeX EXAMPLES:: @@ -1961,7 +1958,6 @@ def __richcmp__(self, right, op): True sage: Y == X True - """ if not isinstance(right, Set_generic): return rich_to_bool(op, -1) diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 81cb4f11bbc..6f68f1245b8 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -10,7 +10,7 @@ sage: from sage.sets.set_from_iterator import EnumeratedSetFromIterator sage: E = EnumeratedSetFromIterator( ....: graphs, - ....: name="Graphs", + ....: name='Graphs', ....: category=InfiniteEnumeratedSets(), ....: cache=True) sage: E @@ -78,9 +78,9 @@ class EnumeratedSetFromIterator(Parent): - ``f`` -- a function that returns an iterable from which the set is built from - - ``args`` -- tuple -- arguments to be sent to the function ``f`` + - ``args`` -- tuple; arguments to be sent to the function `f` - - ``kwds`` -- dictionary -- keywords to be sent to the function ``f`` + - ``kwds`` -- dictionary; keywords to be sent to the function `f` - ``name`` -- an optional name for the set @@ -90,11 +90,10 @@ class EnumeratedSetFromIterator(Parent): you know that your iterator will run over and over you should set it as :class:`InfiniteEnumeratedSets`. - - ``cache`` -- boolean (default: ``False``) -- Whether or not use a cache - mechanism for the iterator. If ``True``, then the function ``f`` is called + - ``cache`` -- boolean (default: ``False``); whether or not use a cache + mechanism for the iterator. If ``True``, then the function `f` is called only once. - EXAMPLES:: sage: from sage.sets.set_from_iterator import EnumeratedSetFromIterator @@ -362,7 +361,7 @@ def __ne__(self, other): def __iter__(self): r""" - Returns an iterator over the element of ``self``. + Return an iterator over the element of ``self``. EXAMPLES:: @@ -383,7 +382,7 @@ def __iter__(self): def unrank(self, i): r""" - Returns the element at position ``i``. + Return the element at position ``i``. EXAMPLES:: @@ -451,7 +450,7 @@ def clear_cache(self): # TODO: move it in sage.misc ? @instancedoc -class Decorator(): +class Decorator: r""" Abstract class that manage documentation and sources of the wrapped object. @@ -488,7 +487,7 @@ def _instancedoc_(self): def _sage_src_(self): r""" - Returns the source code for the wrapped function. + Return the source code for the wrapped function. TESTS:: @@ -506,7 +505,7 @@ def is_square(self): def _sage_src_lines_(self): r""" - Returns the list of source lines and the first line number + Return the list of source lines and the first line number of the wrapped function. TESTS:: @@ -724,8 +723,8 @@ class EnumeratedSetFromIterator_method_caller(Decorator): - ``f`` -- a method of a class of ``inst`` (and not of the instance itself) - - ``name`` -- optional -- either a string (which may contains substitution - rules from argument or a function ``args, kwds -> string``. + - ``name`` -- (optional) either a string (which may contains substitution + rules from argument or a function ``args, kwds -> string`` - ``options`` -- any option accepted by :class:`EnumeratedSetFromIterator` """ @@ -839,17 +838,17 @@ def __get__(self, inst, cls): **self.options) -class EnumeratedSetFromIterator_method_decorator(): +class EnumeratedSetFromIterator_method_decorator: r""" Decorator for enumerated set built from a method. INPUT: - - ``f`` -- Optional function from which are built the enumerated sets at + - ``f`` -- (optional) function from which are built the enumerated sets at each call - - ``name`` -- Optional string (which may contains substitution rules from - argument) or a function ``(args,kwds) -> string``. + - ``name`` -- (optional) string (which may contains substitution rules from + argument) or a function ``(args,kwds) -> string`` - any option accepted by :class:`EnumeratedSetFromIterator`. @@ -1003,7 +1002,7 @@ class DummyExampleForPicklingTest: @set_from_method def f(self): r""" - Returns the set between ``self.start`` and ``self.stop``. + Return the set between ``self.start`` and ``self.stop``. EXAMPLES:: diff --git a/src/sage/sets/totally_ordered_finite_set.py b/src/sage/sets/totally_ordered_finite_set.py index 9191992c285..757146ed323 100644 --- a/src/sage/sets/totally_ordered_finite_set.py +++ b/src/sage/sets/totally_ordered_finite_set.py @@ -118,13 +118,12 @@ def _repr_(self): sage: A = TotallyOrderedFiniteSet(['gaga',1], facade=False) sage: repr(A('gaga')) #indirect doctest "'gaga'" - """ return repr(self.value) def __str__(self): r""" - String that represents self. + String that represents ``self``. EXAMPLES:: @@ -144,10 +143,10 @@ class TotallyOrderedFiniteSet(FiniteEnumeratedSet): INPUT: - - ``elements`` -- A list of elements in the set + - ``elements`` -- list of elements in the set - - ``facade`` -- (default: ``True``) if ``True``, a facade is used; it - should be set to ``False`` if the elements do not inherit from + - ``facade`` -- boolean (default: ``True``); if ``True``, a facade is used. + It should be set to ``False`` if the elements do not inherit from :class:`~sage.structure.element.Element` or if you want a funny order. See examples for more details. diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index b2e6b301bf7..47d890cf0ab 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -60,11 +60,9 @@ def mean(v): INPUT: - - ``v`` -- a list of numbers + - ``v`` -- list of numbers - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: @@ -116,11 +114,9 @@ def mode(v): INPUT: - - ``v`` -- a list - - OUTPUT: + - ``v`` -- list - - a list (sorted if possible) + OUTPUT: list (sorted if possible) EXAMPLES:: @@ -186,15 +182,13 @@ def std(v, bias=False): INPUT: - - ``v`` -- a list of numbers + - ``v`` -- list of numbers - - ``bias`` -- bool (default: ``False``); if ``False``, divide by + - ``bias`` -- boolean (default: ``False``); if ``False``, divide by ``len(v) - 1`` instead of ``len(v)`` to give a less biased estimator (sample) for the standard deviation. - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: @@ -227,6 +221,8 @@ def std(v, bias=False): sage: # needs numpy sage: import numpy + sage: if int(numpy.version.short_version[0]) > 1: + ....: numpy.set_printoptions(legacy="1.25") sage: x = numpy.array([1,2,3,4,5]) sage: std(x, bias=False) 1.5811388300841898 @@ -274,15 +270,13 @@ def variance(v, bias=False): INPUT: - - ``v`` -- a list of numbers + - ``v`` -- list of numbers - - ``bias`` -- bool (default: ``False``); if ``False``, divide by + - ``bias`` -- boolean (default: ``False``); if ``False``, divide by ``len(v) - 1`` instead of ``len(v)`` to give a less biased estimator (sample) for the standard deviation. - OUTPUT: - - - a number + OUTPUT: a number EXAMPLES:: @@ -304,6 +298,8 @@ def variance(v, bias=False): sage: variance([RIF(1.0103, 1.0103), RIF(2)]) 0.4897530450000000? sage: import numpy # needs numpy + sage: if int(numpy.version.short_version[0]) > 1: # needs numpy + ....: numpy.set_printoptions(legacy="1.25") # needs numpy sage: x = numpy.array([1,2,3,4,5]) # needs numpy sage: variance(x, bias=False) # needs numpy 2.5 @@ -372,11 +368,11 @@ def variance(v, bias=False): def median(v): """ - Return the median (middle value) of the elements of `v` + Return the median (middle value) of the elements of `v`. If `v` is empty, we define the median to be NaN, which is consistent with NumPy (note that R returns NULL). - If `v` is comprised of strings, :class:`TypeError` occurs. + If `v` is comprised of strings, :exc:`TypeError` occurs. For elements other than numbers, the median is a result of :func:`sorted`. This function is deprecated. Use :func:`numpy.median` or :func:`numpy.nanmedian` @@ -384,11 +380,9 @@ def median(v): INPUT: - - ``v`` -- a list + - ``v`` -- list - OUTPUT: - - - median element of `v` + OUTPUT: median element of `v` EXAMPLES:: @@ -439,13 +433,11 @@ def moving_average(v, n): INPUT: - - ``v`` -- a list - - - ``n`` -- the number of values used in computing each average. + - ``v`` -- list - OUTPUT: + - ``n`` -- the number of values used in computing each average - - a list of length ``len(v)-n+1``, since we do not fabric any values + OUTPUT: list of length ``len(v)-n+1``, since we do not fabric any values EXAMPLES:: @@ -473,7 +465,6 @@ def moving_average(v, n): [2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000] sage: stats.moving_average(list(a), 3) # needs numpy [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] - """ deprecation(29662, 'sage.stats.basic_stats.moving_average is deprecated; use pandas.Series.rolling instead') diff --git a/src/sage/stats/distributions/dgs_bern.h b/src/sage/stats/distributions/dgs_bern.h index 09406616bff..a120cb292ca 100644 --- a/src/sage/stats/distributions/dgs_bern.h +++ b/src/sage/stats/distributions/dgs_bern.h @@ -51,7 +51,7 @@ /** Number of bits sampled at once in ``dgs_bern_uniform_t`` - .. note:: + .. NOTE:: We want machine independent behaviour at least for the MP functions, so we pick 32. */ @@ -73,7 +73,7 @@ /** Balanced Bernoulli distribution. - .. note:: + .. NOTE:: This implementation is faster than ``dgs_bern_mp_t`` @@ -111,7 +111,7 @@ typedef struct { :param length: number of bits to sample from GMP (or 0 for automatic choice) - .. note:: + .. NOTE:: Clear with ``dgs_bern_uniform_clear()``. @@ -200,7 +200,7 @@ typedef struct { :param p: sampler will return 1 with probability `p` and 0 with probability `1-p`. - .. note:: + .. NOTE:: Clear with ``dgs_bern_mp_clear()``. @@ -245,7 +245,7 @@ typedef struct { :param p: sampler will return 1 with probability `p` and 0 with probability `1-p`. - .. note:: + .. NOTE:: Clear with ``dgs_bern_dp_clear()``. @@ -259,7 +259,7 @@ dgs_bern_dp_t *dgs_bern_dp_init(double p); :param self: Bernoulli state - .. note:: + .. NOTE:: Uses libc ``random()``. @@ -307,7 +307,7 @@ typedef struct { :param f: samplers return 1 with probability `exp(-x/f)` :param l: we support inputs to call `x` up to `2^l-1` - .. note:: + .. NOTE:: Clear ``dgs_bern_exp_mp_clear()``. @@ -367,7 +367,7 @@ typedef struct { :param f: samplers return 1 with probability `exp(-x/f)` :param l: we support inputs to call `x` up to `2^l-1` - .. note:: + .. NOTE:: Clear ``dgs_bern_exp_mp_clear()``. diff --git a/src/sage/stats/distributions/dgs_gauss.h b/src/sage/stats/distributions/dgs_gauss.h index 6353d5f52eb..4e3d310e196 100644 --- a/src/sage/stats/distributions/dgs_gauss.h +++ b/src/sage/stats/distributions/dgs_gauss.h @@ -36,7 +36,7 @@ - ``mp`` -- multi-precision using MPFR, cf. ``dgs_gauss_mp.c`` - - ``dp`` -- double precision using machine doubles, cf. ``dgs_gauss_dp.c``. + - ``dp`` -- double precision using machine doubles, cf. ``dgs_gauss_dp.c`` For readers unfamiliar with the implemented algorithms it makes sense to start with ``dgs_gauss_dp.c`` which implements the same algorithms as @@ -94,7 +94,7 @@ /** We consider a double ``x`` an integer if ``fmod(x,1.0) <= DGS_DISC_GAUSS_INTEGER_CUTOFF`` - .. note:: + .. NOTE:: it is okay put 0.0 here as for typical inputs the above inequality holds exactly @@ -105,7 +105,7 @@ /** We consider two doubles ``x`` and ``y`` equal if ``abs(x-y) <= DGS_DISC_GAUSS_EQUAL_DIFF`` - .. note:: + .. NOTE:: the value picked here is somewhat arbitrary */ @@ -322,7 +322,7 @@ long dgs_disc_gauss_dp_call_uniform_online(dgs_disc_gauss_dp_t *self); :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: `c` must be an integer in this algorithm */ @@ -335,7 +335,7 @@ long dgs_disc_gauss_dp_call_uniform_table(dgs_disc_gauss_dp_t *self); :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: This function makes no assumptions about `c` but requires more resources than ``dgs_disc_gauss_dp_call_uniform_table()``. @@ -351,7 +351,7 @@ long dgs_disc_gauss_dp_call_uniform_table_offset(dgs_disc_gauss_dp_t *self); :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: `c` must be an integer in this algorithm */ @@ -365,7 +365,7 @@ long dgs_disc_gauss_dp_call_uniform_logtable(dgs_disc_gauss_dp_t *self); :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: `c` must be an integer in this algorithm @@ -531,7 +531,7 @@ dgs_disc_gauss_mp_t *dgs_disc_gauss_mp_init(mpfr_t sigma, mpfr_t c, size_t tau, :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: `c` must be an integer in this algorithm @@ -545,7 +545,7 @@ void dgs_disc_gauss_mp_call_uniform_table(mpz_t rop, dgs_disc_gauss_mp_t *self, :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: This function makes no assumptions about `c` but requires more resources than ``dgs_disc_gauss_dp_call_uniform_table()``. @@ -560,7 +560,7 @@ void dgs_disc_gauss_mp_call_uniform_table_offset(mpz_t rop, dgs_disc_gauss_mp_t :param self: discrete Gaussian sampler - .. note:: + .. NOTE:: `c` must be an integer in this algorithm */ @@ -582,7 +582,7 @@ void dgs_disc_gauss_mp_call_uniform_online(mpz_t rop, dgs_disc_gauss_mp_t *self, :param self: Discrete Gaussian sampler - .. note:: + .. NOTE:: `c` must be an integer in this algorithm. */ diff --git a/src/sage/stats/distributions/discrete_gaussian_integer.pyx b/src/sage/stats/distributions/discrete_gaussian_integer.pyx index e74b3e8e741..4fd8d24b1f4 100644 --- a/src/sage/stats/distributions/discrete_gaussian_integer.pyx +++ b/src/sage/stats/distributions/discrete_gaussian_integer.pyx @@ -162,7 +162,7 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): # We use tables for σt ≤ table_cutoff table_cutoff = 10**6 - def __init__(self, sigma, c=0, tau=6, algorithm=None, precision="mp"): + def __init__(self, sigma, c=0, tau=6, algorithm=None, precision='mp'): r""" Construct a new sampler for a discrete Gaussian distribution. @@ -179,34 +179,34 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): considered to have probability zero. This bound applies to algorithms which sample from the uniform distribution (default: ``6``) - - ``algorithm`` -- see list below (default: ``"uniform+table"`` for + - ``algorithm`` -- see list below (default: ``'uniform+table'`` for `σt` bounded by ``DiscreteGaussianDistributionIntegerSampler.table_cutoff`` and - ``"uniform+online"`` for bigger `στ`) + ``'uniform+online'`` for bigger `στ`) - - ``precision`` -- either ``"mp"`` for multi-precision where the actual - precision used is taken from sigma or ``"dp"`` for double precision. In - the latter case results are not reproducible. (default: ``"mp"``) + - ``precision`` -- either ``'mp'`` for multi-precision where the actual + precision used is taken from sigma or ``'dp'`` for double precision. In + the latter case results are not reproducible. (default: ``'mp'``) ALGORITHMS: - - ``"uniform+table"`` -- classical rejection sampling, sampling from the + - ``'uniform+table'`` -- classical rejection sampling, sampling from the uniform distribution and accepted with probability proportional to `\exp(-(x-c)²/(2σ²))` where `\exp(-(x-c)²/(2σ²))` is precomputed and stored in a table. Any real-valued `c` is supported. - - ``"uniform+logtable"`` -- samples are drawn from a uniform distribution and + - ``'uniform+logtable'`` -- samples are drawn from a uniform distribution and accepted with probability proportional to `\exp(-(x-c)²/(2σ²))` where `\exp(-(x-c)²/(2σ²))` is computed using logarithmically many calls to Bernoulli distributions. See [DDLL2013]_ for details. Only integer-valued `c` are supported. - - ``"uniform+online"`` -- samples are drawn from a uniform distribution and + - ``'uniform+online'`` -- samples are drawn from a uniform distribution and accepted with probability proportional to `\exp(-(x-c)²/(2σ²))` where `\exp(-(x-c)²/(2σ²))` is computed in each invocation. Typically this is very slow. See [DDLL2013]_ for details. Any real-valued `c` is accepted. - - ``"sigma2+logtable"`` -- samples are drawn from an easily samplable + - ``'sigma2+logtable'`` -- samples are drawn from an easily samplable distribution with `σ = k·σ_2` with `σ_2 = \sqrt{1/(2\log 2)}` and accepted with probability proportional to `\exp(-(x-c)²/(2σ²))` where `\exp(-(x-c)²/(2σ²))` is computed using logarithmically many calls to Bernoulli @@ -217,16 +217,16 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): EXAMPLES:: sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+online") + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+online') Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000 - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+table") + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+table') Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000 - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+logtable") + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+logtable') Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000 - Note that ``"sigma2+logtable"`` adjusts `σ`:: + Note that ``'sigma2+logtable'`` adjusts `σ`:: - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="sigma2+logtable") + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='sigma2+logtable') Discrete Gaussian sampler over the Integers with sigma = 3.397287 and c = 0.000000 TESTS: @@ -244,12 +244,12 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): ... ValueError: tau must be >= 1 but got -1 - sage: DiscreteGaussianDistributionIntegerSampler(3.0, tau=2, algorithm="superfastalgorithmyouneverheardof") + sage: DiscreteGaussianDistributionIntegerSampler(3.0, tau=2, algorithm='superfastalgorithmyouneverheardof') Traceback (most recent call last): ... ValueError: Algorithm 'superfastalgorithmyouneverheardof' not supported by class 'DiscreteGaussianDistributionIntegerSampler' - sage: DiscreteGaussianDistributionIntegerSampler(3.0, c=1.5, algorithm="sigma2+logtable") + sage: DiscreteGaussianDistributionIntegerSampler(3.0, c=1.5, algorithm='sigma2+logtable') Traceback (most recent call last): ... ValueError: algorithm 'uniform+logtable' requires c%1 == 0 @@ -296,19 +296,19 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): ....: n += 1 sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler - sage: D = DiscreteGaussianDistributionIntegerSampler(1.0, c=0, tau=2, precision="dp") + sage: D = DiscreteGaussianDistributionIntegerSampler(1.0, c=0, tau=2, precision='dp') sage: mini = 1000; maxi = -1000; s = 0; n = 0 sage: add_samples(2^16) sage: while mini != 0 - 2*1.0 or maxi != 0 + 2*1.0 or abs(float(s)/n) >= 0.05: ....: add_samples(2^16) - sage: D = DiscreteGaussianDistributionIntegerSampler(1.0, c=2.5, tau=2, precision="dp") + sage: D = DiscreteGaussianDistributionIntegerSampler(1.0, c=2.5, tau=2, precision='dp') sage: mini = 1000; maxi = -1000; s = 0; n = 0 sage: add_samples(2^16) sage: while mini != 2 - 2*1.0 or maxi != 2 + 2*1.0 or abs(float(s)/n - 2.45) >= 0.01: ....: add_samples(2^16) - sage: D = DiscreteGaussianDistributionIntegerSampler(1.0, c=2.5, tau=6, precision="dp") + sage: D = DiscreteGaussianDistributionIntegerSampler(1.0, c=2.5, tau=6, precision='dp') sage: mini = 1000; maxi = -1000; s = 0; n = 0 sage: add_samples(2^16) sage: while mini > -1 or maxi < 6 or abs(float(s)/n - 2.5) >= 0.1: @@ -443,7 +443,7 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): TESTS:: sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler - sage: D = DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+online") + sage: D = DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+online') sage: del D """ if self._gen_mp: @@ -458,15 +458,15 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): EXAMPLES:: sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+online")() # random + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+online')() # random -3 - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+table")() # random + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+table')() # random 3 TESTS:: sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler - sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+logtable", precision="dp")() # random output + sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm='uniform+logtable', precision='dp')() # random output 13 """ cdef randstate rstate diff --git a/src/sage/stats/distributions/discrete_gaussian_lattice.py b/src/sage/stats/distributions/discrete_gaussian_lattice.py index 428ca30855b..78f21d29fbb 100644 --- a/src/sage/stats/distributions/discrete_gaussian_lattice.py +++ b/src/sage/stats/distributions/discrete_gaussian_lattice.py @@ -82,17 +82,16 @@ def _iter_vectors(n, lower, upper, step=None): INPUT: - - ``n`` -- length, integer ``>0``, - - ``lower`` -- lower bound (inclusive), integer ``< upper``. - - ``upper`` -- upper bound (exclusive), integer ``> lower``. - - ``step`` -- used for recursion, ignore. + - ``n`` -- integer ``>0``; length + - ``lower`` -- integer ``< upper``; lower bound (inclusive) + - ``upper`` -- integer ``> lower``; upper bound (exclusive) + - ``step`` -- used for recursion, ignore EXAMPLES:: sage: from sage.stats.distributions.discrete_gaussian_lattice import _iter_vectors sage: list(_iter_vectors(2, -1, 2)) [(-1, -1), (0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] - """ if step is None: if ZZ(lower) >= ZZ(upper): @@ -160,9 +159,9 @@ def compute_precision(precision, sigma): INPUT: - - ``precision`` -- an integer `>= 53` nor ``None``. + - ``precision`` -- integer `>= 53` nor ``None`` - ``sigma`` -- if ``precision`` is ``None`` then the precision of - ``sigma`` is used. + ``sigma`` is used EXAMPLES:: @@ -179,7 +178,6 @@ def compute_precision(precision, sigma): 200 sage: DGL.compute_precision(None, 3) 53 - """ if precision is None: try: @@ -250,7 +248,9 @@ def _normalisation_factor_zz(self, tau=None, prec=None): sage: M = Matrix(ZZ, [[1, 3, 0], [-2, 5, 1], [3, -4, 2]]) sage: D = DGL(M, 1.7) sage: D._normalisation_factor_zz() # long time - 7247.1975... + Traceback (most recent call last): + ... + NotImplementedError: center must be at zero and basis must be trivial sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]]) sage: D = DGL(ZZ^3, Sigma, [7, 2, 5]) @@ -262,19 +262,19 @@ def _normalisation_factor_zz(self, tau=None, prec=None): sage: D._normalisation_factor_zz() Traceback (most recent call last): ... - NotImplementedError: basis must be a square matrix for now + NotImplementedError: basis must be a square matrix sage: D = DGL(ZZ^3, c=(1/2, 0, 0)) sage: D._normalisation_factor_zz() Traceback (most recent call last): ... - NotImplementedError: lattice must contain 0 for now + NotImplementedError: center must be at zero and basis must be trivial sage: D = DGL(Matrix(3, 3, 1/2)) sage: D._normalisation_factor_zz() Traceback (most recent call last): ... - NotImplementedError: lattice must be integral for now + NotImplementedError: lattice must be integral """ # If σ > 1: # We use the Fourier transform g(t) of f(x) = exp(-k^2 / 2σ^2), but @@ -308,19 +308,18 @@ def f_or_hat(x): # However, this might still drift from true value for larger lattices # So optimally one should fix the TODO above BOUND = max(1, (self._RR(10**(4 / self.n)).ceil() - 1) // 2) - if BOUND > 10: - BOUND = 10 + BOUND = min(BOUND, 10) coords = itertools.product(range(-BOUND, BOUND + 1), repeat=self.n) return sum(self.f((vector(u) + base) * self.B) for u in coords) if self.B.nrows() != self.B.ncols(): - raise NotImplementedError("basis must be a square matrix for now") - - if self.is_spherical and not self._c_in_lattice: - raise NotImplementedError("lattice must contain 0 for now") + raise NotImplementedError("basis must be a square matrix") if self.B.base_ring() != ZZ: - raise NotImplementedError("lattice must be integral for now") + raise NotImplementedError("lattice must be integral") + + if self.is_spherical and not self._c_in_lattice_and_lattice_trivial: + raise NotImplementedError("center must be at zero and basis must be trivial") sigma = self._sigma prec = DiscreteGaussianDistributionLatticeSampler.compute_precision( @@ -434,8 +433,8 @@ def __init__(self, B, sigma=1, c=0, r=None, precision=None, sigma_basis=False): [Pei2010]_; ignored for spherical Gaussian parameter; if not provided, set to be the maximal possible such that `\Sigma - rBB^T` is positive definite - - ``precision`` -- bit precision `\geq 53`. - - ``sigma_basis`` -- (default: ``False``) When set, ``sigma`` is treated as + - ``precision`` -- bit precision `\geq 53` + - ``sigma_basis`` -- boolean (default: ``False``); when set, ``sigma`` is treated as a (row) basis, i.e. the covariance matrix is computed by `\Sigma = SS^T` .. TODO:: @@ -560,7 +559,7 @@ def __init__(self, B, sigma=1, c=0, r=None, precision=None, sigma_basis=False): except TypeError: self._sigma = matrix(self._RR, sigma) # Will it be "annoying" if a matrix Sigma has different behaviour - # sometimes? There should be a parameter in the consrtuctor + # sometimes? There should be a parameter in the constructor if self._sigma == self._sigma[0, 0]: self._sigma = self._RR(self._sigma[0, 0]) else: @@ -585,7 +584,7 @@ def __init__(self, B, sigma=1, c=0, r=None, precision=None, sigma_basis=False): self.B = B self.Q = B * B.T self._G = B.gram_schmidt()[0] - self._c_in_lattice = False + self._c_in_lattice_and_lattice_trivial = False self.D = None self.VS = None @@ -614,18 +613,19 @@ def _precompute_data(self): Do not call this method directly, it is called automatically from :func:`DiscreteGaussianDistributionLatticeSampler.__init__`. """ + if self.is_spherical: # deal with trivial case first, it is common - if self._G == 1 and self._c == 0: - self._c_in_lattice = True + if self._c == 0 and self._G == 1: + self._c_in_lattice_and_lattice_trivial = True D = DiscreteGaussianDistributionIntegerSampler(sigma=self._sigma) self.D = tuple([D for _ in range(self.B.nrows())]) self.VS = FreeModule(ZZ, self.B.nrows()) else: w = self.B.solve_left(self._c) - if w in ZZ ** self.B.nrows(): - self._c_in_lattice = True + if w in ZZ ** self.B.nrows() and self._G == 1: + self._c_in_lattice_and_lattice_trivial = True D = [] for i in range(self.B.nrows()): sigma_ = self._sigma / self._G[i].norm() @@ -675,11 +675,20 @@ def __call__(self): sage: mean_L = sum(L) / len(L) # long time sage: norm(mean_L.n() - D.c()) < 0.25 # long time True + + sage: import numpy + sage: M = matrix(ZZ, [[1,2],[0,1]]) + sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(M, 20.0) + sage: L = [D() for _ in range(2^12)] # long time + sage: div = numpy.mean([abs(x) for x,y in L]) / numpy.mean([abs(y) for x,y, in L]) # long time + sage: 0.9 < div < 1.1 # long time + True + """ if not self.is_spherical: v = self._call_non_spherical() - elif self._c_in_lattice: - v = self._call_in_lattice() + elif self._c_in_lattice_and_lattice_trivial: + v = self._call_simple() else: v = self._call() v.set_immutable() @@ -809,14 +818,14 @@ def __repr__(self): sigma_str = f"Σ =\n{self._sigma}" return f"Discrete Gaussian sampler with Gaussian parameter {sigma_str}, c={self._c} over lattice with basis\n\n{self.B}" - def _call_in_lattice(self): + def _call_simple(self): r""" - Return a new sample assuming `c \in \Lambda(B)`. + Return a new sample assuming `c \in \Lambda(B)` and `B^* = 1`. EXAMPLES:: sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0)) - sage: L = [D._call_in_lattice() for _ in range(2^12)] + sage: L = [D._call_simple() for _ in range(2^12)] sage: mean_L = sum(L) / len(L) sage: norm(mean_L.n() - D.c()) < 0.25 True @@ -856,7 +865,7 @@ def _call(self): c_ = c.dot_product(b_) / b_.dot_product(b_) sigma_ = sigma / b_.norm() assert sigma_ > 0 - z = DiscreteGaussianDistributionIntegerSampler(sigma=sigma_, c=c_, algorithm="uniform+online")() + z = DiscreteGaussianDistributionIntegerSampler(sigma=sigma_, c=c_, algorithm='uniform+online')() c = c - z * B[i] v = v + z * B[i] return v diff --git a/src/sage/stats/distributions/meson.build b/src/sage/stats/distributions/meson.build new file mode 100644 index 00000000000..129d5f74d13 --- /dev/null +++ b/src/sage/stats/distributions/meson.build @@ -0,0 +1,31 @@ +py.install_sources( + 'all.py', + 'catalog.py', + 'dgs.pxd', + 'discrete_gaussian_integer.pxd', + 'discrete_gaussian_lattice.py', + 'discrete_gaussian_polynomial.py', + subdir: 'sage/stats/distributions', +) + +extension_data = { + 'discrete_gaussian_integer' : files( + 'dgs_bern.c', + 'dgs_gauss_dp.c', + 'dgs_gauss_mp.c', + 'discrete_gaussian_integer.pyx', + ), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + c_args: ['-D_XOPEN_SOURCE=600'], + subdir: 'sage/stats/distributions', + install: true, + include_directories: [inc_cpython, inc_rings, inc_src], + dependencies: [py_dep, cypari2, cysignals, gmp, mpfr], + ) +endforeach + diff --git a/src/sage/stats/hmm/chmm.pyx b/src/sage/stats/hmm/chmm.pyx index c7c2ab25b4e..540f91356d0 100644 --- a/src/sage/stats/hmm/chmm.pyx +++ b/src/sage/stats/hmm/chmm.pyx @@ -76,7 +76,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): - ``A`` -- matrix; the `N \times N` transition matrix - ``B`` -- list of pairs ``(mu, sigma)`` that define the distributions - ``pi`` -- initial state probabilities - - ``normalize`` -- bool (default: ``True``) + - ``normalize`` -- boolean (default: ``True``) EXAMPLES: @@ -164,11 +164,11 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``A`` -- a list of lists or a square `N \times N` matrix, whose + - ``A`` -- list of lists or a square `N \times N` matrix, whose `(i,j)` entry gives the probability of transitioning from state `i` to state `j`. - - ``B`` -- a list of `N` pairs ``(mu, std)``, where if ``B[i]=(mu,std)``, + - ``B`` -- list of `N` pairs ``(mu, std)``, where if ``B[i]=(mu,std)``, then the probability distribution associated with state `i` normal with mean ``mu`` and standard deviation ``std``. @@ -176,7 +176,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): state, i.e., ``pi[i]`` is the probability of starting in state `i`. - - ``normalize`` -- bool (default: ``True``); if given, input is + - ``normalize`` -- boolean (default: ``True``); if given, input is normalized to define valid probability distributions, e.g., the entries of `A` are made nonnegative and the rows sum to 1. @@ -343,8 +343,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - ``length`` -- positive integer - - ``starting_state`` -- int (or ``None``); if specified then generate - a sequence using this model starting with the given state + - ``starting_state`` -- integer (or ``None``); if specified then + generate a sequence using this model starting with the given state instead of the initial probabilities to determine the starting state. @@ -534,9 +534,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): - ``obs`` -- sequence of observations - OUTPUT: - - float + OUTPUT: float EXAMPLES:: @@ -561,7 +559,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- an integer list of observation states. + - ``obs`` -- integer list of observation states OUTPUT: @@ -624,11 +622,11 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - list -- "the" most probable sequence of hidden states, i.e., - the Viterbi path. + - ``list`` -- "the" most probable sequence of hidden states, i.e., + the Viterbi path - - float -- log of probability that the observed sequence - was produced by the Viterbi sequence of states. + - ``float`` -- log of probability that the observed sequence + was produced by the Viterbi sequence of states EXAMPLES: @@ -772,8 +770,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): - TimeSeries alpha with alpha_t(i) = alpha[t*N + i] - TimeSeries scale with scale[t] the scaling at step t - - float -- log_probability of the observation sequence - being produced by the model. + - ``float`` -- log_probability of the observation sequence + being produced by the model """ cdef Py_ssize_t i, j, t, T = len(obs) cdef int N = self.N @@ -861,7 +859,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): - ``obs`` -- a time series of emissions - - ``max_iter`` -- integer (default: 500) maximum number + - ``max_iter`` -- integer (default: 500); maximum number of Baum-Welch steps to take - ``log_likelihood_cutoff`` -- positive float (default: 1e-4); @@ -873,7 +871,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): reestimating, the standard deviation of emissions is not allowed to be less than ``min_sd``. - - ``fix_emissions`` -- bool (default: ``False``); if ``True``, do not + - ``fix_emissions`` -- boolean (default: ``False``); if ``True``, do not change emissions when updating OUTPUT: @@ -1049,7 +1047,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - ``A`` -- matrix; the `N \times N` transition matrix + - ``A`` -- matrix; the `N \times N` transition matrix - ``B`` -- list of mixture definitions for each state. Each state may have a varying number of gaussians with selection @@ -1057,7 +1055,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): - ``pi`` -- initial state probabilities - - ``normalize`` -- bool (default: ``True``); if given, input is + - ``normalize`` -- boolean (default: ``True``); if given, input is normalized to define valid probability distributions, e.g., the entries of `A` are made nonnegative and the rows sum to 1, and the probabilities in ``pi`` are normalized. @@ -1166,7 +1164,8 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): def __richcmp__(self, other, op): r""" - Compare self and other, which must both be GaussianMixtureHiddenMarkovModel's. + Compare ``self`` and ``other``, which must both be + ``GaussianMixtureHiddenMarkovModel``s. EXAMPLES:: @@ -1195,9 +1194,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): - ``i`` -- integer - OUTPUT: - - a Gaussian mixture distribution object + OUTPUT: a Gaussian mixture distribution object EXAMPLES:: @@ -1231,11 +1228,9 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): def emission_parameters(self): r""" - Returns a list of all the emission distributions. - - OUTPUT: + Return a list of all the emission distributions. - list of Gaussian mixtures + OUTPUT: list of Gaussian mixtures EXAMPLES:: @@ -1303,7 +1298,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): - ``alpha`` -- TimeSeries - ``beta`` -- TimeSeries - ``obs`` -- TimeSeries - - ``j`` -- int + - ``j`` -- integer OUTPUT: @@ -1351,7 +1346,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - ``obs`` -- a time series of emissions - - ``max_iter`` -- integer (default: 1000) maximum number + - ``max_iter`` -- integer (default: 1000); maximum number of Baum-Welch steps to take - ``log_likelihood_cutoff`` -- positive float (default: 1e-12); the minimal improvement in likelihood with respect to @@ -1360,7 +1355,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): - ``min_sd`` -- positive float (default: 0.01); when reestimating, the standard deviation of emissions is not allowed to be less than ``min_sd``. - - ``fix_emissions`` -- bool (default: ``False``); if ``True``, do not + - ``fix_emissions`` -- boolean (default: ``False``); if ``True``, do not change emissions when updating OUTPUT: diff --git a/src/sage/stats/hmm/distributions.pyx b/src/sage/stats/hmm/distributions.pyx index 1b04dff21cb..ed79d289ed6 100644 --- a/src/sage/stats/hmm/distributions.pyx +++ b/src/sage/stats/hmm/distributions.pyx @@ -78,9 +78,7 @@ cdef class Distribution: - ``n`` -- ``None`` or a positive integer - OUTPUT: - - - a single sample if `n` is 1; otherwise many samples + OUTPUT: a single sample if `n` is 1; otherwise many samples EXAMPLES: @@ -102,9 +100,7 @@ cdef class Distribution: - ``x`` -- object - OUTPUT: - - - float + OUTPUT: float EXAMPLES: @@ -126,9 +122,7 @@ cdef class Distribution: - ``args`` and ``kwds``, passed to the Sage :func:`plot` function - OUTPUT: - - - a :class:`Graphics` object + OUTPUT: a :class:`Graphics` object EXAMPLES:: @@ -165,12 +159,12 @@ cdef class GaussianMixtureDistribution(Distribution): r""" INPUT: - - ``B`` -- a list of triples ``(c_i, mean_i, std_i)``, where + - ``B`` -- list of triples ``(c_i, mean_i, std_i)``, where the ``c_i`` and ``std_i`` are positive and the sum of the - ``c_i`` is `1`. + ``c_i`` is `1` - ``eps`` -- positive real number; any standard deviation in B - less than eps is replaced by eps. + less than eps is replaced by eps - ``normalize`` -- if ``True``, ensure that the ``c_i`` are nonnegative @@ -209,9 +203,7 @@ cdef class GaussianMixtureDistribution(Distribution): - ``i`` -- integer - OUTPUT: - - - triple of floats + OUTPUT: triple of floats EXAMPLES:: @@ -361,7 +353,6 @@ cdef class GaussianMixtureDistribution(Distribution): True sage: P.unfix(); P.is_fixed() False - """ cdef int j if i is None: @@ -469,9 +460,7 @@ cdef class GaussianMixtureDistribution(Distribution): - ``x`` -- float - OUTPUT: - - - float + OUTPUT: float EXAMPLES:: @@ -503,9 +492,7 @@ cdef class GaussianMixtureDistribution(Distribution): - ``x`` -- float - ``m`` -- integer - OUTPUT: - - - float + OUTPUT: float EXAMPLES:: diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 39fb342710d..e471a42d97f 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -171,11 +171,11 @@ cdef class HiddenMarkovModel: INPUT: - ``length`` -- positive integer - - ``number`` -- (default: ``None``) if given, compute list of this many sample sequences - - ``starting_state`` -- int (or ``None``); if specified, generate - a sequence using this model starting with the given state - instead of the initial probabilities to determine the - starting state. + - ``number`` -- (default: ``None``) if given, compute list of this many + sample sequences + - ``starting_state`` -- integer (or ``None``); if specified, generate a + sequence using this model starting with the given state instead of + the initial probabilities to determine the starting state OUTPUT: @@ -261,11 +261,11 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``A`` -- a list of lists or a square `N \times N` matrix, whose + - ``A`` -- list of lists or a square `N \times N` matrix, whose `(i,j)` entry gives the probability of transitioning from state `i` to state `j`. - - ``B`` -- a list of `N` lists or a matrix with `N` rows, such that + - ``B`` -- list of `N` lists or a matrix with `N` rows, such that `B[i,k]` gives the probability of emitting symbol `k` while in state `i`. @@ -278,7 +278,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): is the number of states. Otherwise, they are the entries of the list ``emissions_symbols``, which must all be hashable. - - ``normalize`` -- bool (default: ``True``); if given, input is + - ``normalize`` -- boolean (default: ``True``); if given, input is normalized to define valid probability distributions, e.g., the entries of `A` are made nonnegative and the rows sum to 1, and the probabilities in ``pi`` are normalized. @@ -347,7 +347,6 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): sage: hmm.DiscreteHiddenMarkovModel([1,2,.1,1.2], [[1],[1]],[.5,.5]).transition_matrix() [ 0.3333333333333333 0.6666666666666666] [0.07692307692307693 0.923076923076923] - """ self.pi = util.initial_probs_to_TimeSeries(pi, normalize) self.N = len(self.pi) @@ -459,7 +458,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- a list of objects + - ``obs`` -- list of objects OUTPUT: an IntList @@ -478,7 +477,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- a list of objects + - ``obs`` -- list of objects OUTPUT: an IntList @@ -494,7 +493,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): def log_likelihood(self, obs, bint scale=True): r""" Return the logarithm of the probability that this model produced the given - observation sequence. Thus the output is a non-positive number. + observation sequence. Thus the output is a nonpositive number. INPUT: @@ -548,15 +547,15 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): def _forward(self, IntList obs): r""" - Memory-efficient implementation of the forward algorithm, without scaling. + Memory-efficient implementation of the forward algorithm, without + scaling. INPUT: - - ``obs`` -- an integer list of observation states. - - OUTPUT: + - ``obs`` -- integer list of observation states - ``float`` -- the log of the probability that the model produced this sequence + OUTPUT: ``float`` -- the log of the probability that the model produced + this sequence EXAMPLES:: @@ -607,11 +606,10 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- an integer list of observation states. + - ``obs`` -- integer list of observation states - OUTPUT: - - ``float`` -- the log of the probability that the model produced this sequence + OUTPUT: ``float`` -- the log of the probability that the model produced + this sequence EXAMPLES:: @@ -697,10 +695,9 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - ``length`` -- positive integer - - ``starting_state`` -- int (or ``None``); if specified, generate - a sequence using this model starting with the given state - instead of the initial probabilities to determine the - starting state. + - ``starting_state`` -- integer (or ``None``); if specified, generate a + sequence using this model starting with the given state instead of + the initial probabilities to determine the starting state OUTPUT: @@ -815,12 +812,10 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``q`` -- a nonnegative integer, which specifies a state + - ``q`` -- nonnegative integer, which specifies a state - ``r`` -- a real number between 0 and 1 - OUTPUT: - - a nonnegative int + OUTPUT: a nonnegative int EXAMPLES:: @@ -855,16 +850,16 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): - ``seq`` -- sequence of emitted ints or symbols - - ``log_scale`` -- bool (default: ``True``) whether to scale the - sequence in order to avoid numerical overflow. + - ``log_scale`` -- boolean (default: ``True``); whether to scale the + sequence in order to avoid numerical overflow OUTPUT: - ``list`` -- "the" most probable sequence of hidden states, i.e., - the Viterbi path. + the Viterbi path - ``float`` -- log of probability that the observed sequence - was produced by the Viterbi sequence of states. + was produced by the Viterbi sequence of states EXAMPLES:: @@ -1118,8 +1113,8 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): - TimeSeries alpha with alpha_t(i) = alpha[t*N + i] - TimeSeries scale with scale[t] the scaling at step t - - float -- log_probability of the observation sequence - being produced by the model. + - ``float`` -- log_probability of the observation sequence + being produced by the model """ cdef Py_ssize_t i, j, t, T = len(obs) cdef int N = self.N @@ -1208,7 +1203,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): - ``obs`` -- list of emissions - - ``max_iter`` -- integer (default: 100) maximum number + - ``max_iter`` -- integer (default: 100); maximum number of Baum-Welch steps to take - ``log_likelihood_cutoff`` -- positive float (default: 1e-4); @@ -1216,8 +1211,8 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): the last iteration required to continue. Relative value to log likelihood. - - ``fix_emissions`` -- bool (default: ``False``); if ``True``, do not - change emissions when updating + - ``fix_emissions`` -- boolean (default: ``False``); if ``True``, do + not change emissions when updating OUTPUT: diff --git a/src/sage/stats/hmm/meson.build b/src/sage/stats/hmm/meson.build new file mode 100644 index 00000000000..cbf4a30caa5 --- /dev/null +++ b/src/sage/stats/hmm/meson.build @@ -0,0 +1,26 @@ +py.install_sources( + 'all.py', + 'distributions.pxd', + 'hmm.pxd', + 'util.pxd', + subdir: 'sage/stats/hmm', +) + +extension_data = { + 'chmm' : files('chmm.pyx'), + 'distributions' : files('distributions.pyx'), + 'hmm' : files('hmm.pyx'), + 'util' : files('util.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/stats/hmm', + install: true, + include_directories: [], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + diff --git a/src/sage/stats/hmm/util.pyx b/src/sage/stats/hmm/util.pyx index a2d34d55e1d..c43abc73f75 100644 --- a/src/sage/stats/hmm/util.pyx +++ b/src/sage/stats/hmm/util.pyx @@ -38,9 +38,7 @@ cdef class HMM_Util: - ``i`` -- nonnegative integer - ``j`` -- nonnegative integer - OUTPUT: - - - ``T`` is modified + OUTPUT: ``T`` is modified EXAMPLES:: @@ -97,9 +95,7 @@ cdef class HMM_Util: equal to 1. If the sum of the entries in a row is 0, replace them all by `1/N`. - OUTPUT: - - - a :class:`TimeSeries` of length `N` + OUTPUT: a :class:`TimeSeries` of length `N` EXAMPLES:: @@ -137,9 +133,7 @@ cdef class HMM_Util: equal to 1. If the sum of the entries in a row is 0, replace them all by `1/N`. - OUTPUT: - - - a :class:`TimeSeries` + OUTPUT: a :class:`TimeSeries` EXAMPLES:: diff --git a/src/sage/stats/intlist.pyx b/src/sage/stats/intlist.pyx index fccbb56e680..6f337badad5 100644 --- a/src/sage/stats/intlist.pyx +++ b/src/sage/stats/intlist.pyx @@ -52,7 +52,6 @@ cdef class IntList: sage: stats.IntList(5) # indirect test [0, 0, 0, 0, 0] - """ self._values = NULL @@ -62,7 +61,7 @@ cdef class IntList: INPUT: - - values -- int, long, Integer, list of integers, or a TimeSeries + - ``values`` -- int, long, Integer, list of integers, or a TimeSeries If the input is a time series or list of floats, then the integer parts of the entries are taken (not the floor). @@ -121,7 +120,7 @@ cdef class IntList: def __richcmp__(IntList self, other, int op): """ - Compare self and other. This has the same semantics + Compare ``self`` and ``other``. This has the same semantics as list comparison. EXAMPLES:: @@ -188,7 +187,7 @@ cdef class IntList: INPUT: - - i -- integer or slice + - ``i`` -- integer or slice EXAMPLES:: @@ -252,8 +251,8 @@ cdef class IntList: INPUT: - - i -- an integer - - x -- an int + - ``i`` -- integer + - ``x`` -- integer EXAMPLES:: @@ -295,8 +294,8 @@ cdef class IntList: sage: loads(dumps(v)) == v True - Note that dumping and loading with compress False is much faster, though - dumping with compress True can save a lot of space:: + Note that dumping and loading with compress ``False`` is much faster, + though dumping with compress ``True`` can save a lot of space:: sage: v = stats.IntList([1..10^5]) sage: loads(dumps(v, compress=False),compress=False) == v @@ -379,9 +378,7 @@ cdef class IntList: """ Return the number of entries in this time series. - OUTPUT: - - Python integer + OUTPUT: Python integer EXAMPLES:: @@ -396,7 +393,7 @@ cdef class IntList: def __add__(left, right): """ - Concatenate the integer lists self and right. + Concatenate the integer lists ``self`` and ``right``. EXAMPLES:: @@ -417,17 +414,17 @@ cdef class IntList: def min(self, bint index=False): """ Return the smallest value in this integer list. If this - series has length 0 we raise a :class:`ValueError`. + series has length 0 we raise a :exc:`ValueError`. INPUT: - - ``index`` -- bool (default: ``False``); if ``True``, also return - index of minimal entry. + - ``index`` -- boolean (default: ``False``); if ``True``, also return + index of minimal entry OUTPUT: - - float -- smallest value - - integer -- index of smallest value; only returned if + - ``float`` -- smallest value + - ``integer`` -- index of smallest value; only returned if ``index=True`` EXAMPLES:: @@ -455,17 +452,17 @@ cdef class IntList: def max(self, bint index=False): """ Return the largest value in this time series. If this series - has length 0 we raise a :class:`ValueError` + has length 0 we raise a :exc:`ValueError` INPUT: - - ``index`` -- bool (default: ``False``); if ``True``, also return - index of maximum entry. + - ``index`` -- boolean (default: ``False``); if ``True``, also return + index of maximum entry OUTPUT: - - int -- largest value - - int -- index of largest value; only returned if ``index=True`` + - integer -- largest value + - integer -- index of largest value; only returned if ``index=True`` EXAMPLES:: @@ -551,11 +548,9 @@ cdef IntList new_int_list(Py_ssize_t length): INPUT: - - length -- a nonnegative integer - - OUTPUT: + - ``length`` -- nonnegative integer - - an IntList. + OUTPUT: an IntList """ if length < 0: raise ValueError("length must be nonnegative") diff --git a/src/sage/stats/meson.build b/src/sage/stats/meson.build new file mode 100644 index 00000000000..414a909270c --- /dev/null +++ b/src/sage/stats/meson.build @@ -0,0 +1,27 @@ +py.install_sources( + 'all.py', + 'basic_stats.py', + 'intlist.pxd', + 'r.py', + 'time_series.pxd', + subdir: 'sage/stats', +) + +extension_data = { + 'intlist' : files('intlist.pyx'), + 'time_series' : files('time_series.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/stats', + install: true, + include_directories: [inc_cpython, inc_numpy], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +subdir('distributions') +subdir('hmm') diff --git a/src/sage/stats/r.py b/src/sage/stats/r.py index 47f492eff61..63398fb1a44 100644 --- a/src/sage/stats/r.py +++ b/src/sage/stats/r.py @@ -24,12 +24,12 @@ def ttest(x, y, conf_level=0.95, **kw): """ - T-Test using R + T-Test using R. INPUT: - ``x``, ``y`` -- vectors of same length - - conf_level -- confidence level of the interval, [0,1) in percent + - ``conf_level`` -- confidence level of the interval, [0,1) in percent OUTPUT: diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 2e22ec45c69..e4845126012 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -86,9 +86,9 @@ cdef class TimeSeries: INPUT: - ``values`` -- integer (number of values) or an iterable of - floats. + floats - - ``initialize`` -- bool (default: ``True``); if ``False``, do not + - ``initialize`` -- boolean (default: ``True``); if ``False``, do not bother to zero out the entries of the new time series. For large series that you are going to just fill in, this can be way faster. @@ -243,9 +243,7 @@ cdef class TimeSeries: time series. This is useful since vectors have standard algebraic structure and play well with matrices. - OUTPUT: - - A real double vector. + OUTPUT: a real double vector EXAMPLES:: @@ -292,9 +290,7 @@ cdef class TimeSeries: ``None``. If ``None`` use the default ``sage.stats.time_series.digits``. - OUTPUT: - - A string. + OUTPUT: string EXAMPLES:: @@ -320,9 +316,7 @@ cdef class TimeSeries: r""" Return the number of entries in this time series. - OUTPUT: - - Python integer. + OUTPUT: Python integer EXAMPLES:: @@ -426,9 +420,9 @@ cdef class TimeSeries: INPUT: - - ``i`` -- a nonnegative integer. + - ``i`` -- nonnegative integer - - ``x`` -- a float. + - ``x`` -- a float EXAMPLES:: @@ -486,11 +480,9 @@ cdef class TimeSeries: INPUT: - - ``right`` -- a time series. - - OUTPUT: + - ``right`` -- a time series - A time series. + OUTPUT: a time series EXAMPLES:: @@ -534,11 +526,9 @@ cdef class TimeSeries: INPUT: - - ``left``, ``right`` -- an integer and a time series. + - ``left``, ``right`` -- integer and a time series - OUTPUT: - - A time series. + OUTPUT: a time series EXAMPLES:: @@ -589,11 +579,9 @@ cdef class TimeSeries: INPUT: - - ``M`` -- an integer. - - OUTPUT: + - ``M`` -- integer - A time series -- the coefficients of the autoregressive process. + OUTPUT: a time series -- the coefficients of the autoregressive process EXAMPLES:: @@ -632,7 +620,7 @@ cdef class TimeSeries: INPUT: - ``filter`` -- a time series outputted by the ``autoregressive_fit`` - command. + command EXAMPLES:: @@ -662,9 +650,7 @@ cdef class TimeSeries: Return new time series obtain from this time series by reversing the order of the entries in this time series. - OUTPUT: - - A time series. + OUTPUT: a time series EXAMPLES:: @@ -686,7 +672,7 @@ cdef class TimeSeries: INPUT: - - ``right`` -- iterable that can be converted to a time series. + - ``right`` -- iterable that can be converted to a time series EXAMPLES:: @@ -728,9 +714,7 @@ cdef class TimeSeries: Return new time series got by taking the logarithms of all the terms in the time series. - OUTPUT: - - A new time series. + OUTPUT: a new time series EXAMPLES: @@ -760,9 +744,7 @@ cdef class TimeSeries: Return new time series got by applying the exponential map to all the terms in the time series. - OUTPUT: - - A new time series. + OUTPUT: a new time series EXAMPLES:: @@ -784,9 +766,7 @@ cdef class TimeSeries: Return new time series got by replacing all entries of ``self`` by their absolute value. - OUTPUT: - - A new time series. + OUTPUT: a new time series EXAMPLES:: @@ -815,9 +795,7 @@ cdef class TimeSeries: - ``k`` -- positive integer (default: 1) - OUTPUT: - - A new time series. + OUTPUT: a new time series EXAMPLES:: @@ -842,11 +820,9 @@ cdef class TimeSeries: INPUT: - - ``k`` -- a positive integer. - - OUTPUT: + - ``k`` -- positive integer - A new time series. + OUTPUT: a new time series EXAMPLES:: @@ -897,7 +873,7 @@ cdef class TimeSeries: INPUT: - - ``s`` -- a float. + - ``s`` -- a float EXAMPLES:: @@ -917,11 +893,9 @@ cdef class TimeSeries: INPUT: - - ``s`` -- a float. - - OUTPUT: + - ``s`` -- a float - A new time series with all values multiplied by ``s``. + OUTPUT: a new time series with all values multiplied by ``s`` EXAMPLES:: @@ -946,11 +920,9 @@ cdef class TimeSeries: INPUT: - - ``s`` -- a float. - - OUTPUT: + - ``s`` -- a float - A new time series with ``s`` added to all values. + OUTPUT: a new time series with ``s`` added to all values EXAMPLES:: @@ -967,7 +939,7 @@ cdef class TimeSeries: def add_entries(self, t): r""" Add corresponding entries of ``self`` and ``t`` together, - extending either ``self`` or ``t`` by 0's if they do + extending either ``self`` or ``t`` by 0s if they do not have the same length. .. NOTE:: @@ -977,7 +949,7 @@ cdef class TimeSeries: INPUT: - - ``t`` -- a time series. + - ``t`` -- a time series OUTPUT: @@ -1050,10 +1022,10 @@ cdef class TimeSeries: plot the given number of equally spaced points in the time series. If 0, plot all points. - - ``points`` -- bool (default: ``False``). If ``True``, return just - the points of the time series. + - ``points`` -- boolean (default: ``False``); if ``True``, return just + the points of the time series - - ``**kwds`` -- passed to the line or point command. + - ``**kwds`` -- passed to the line or point command EXAMPLES:: @@ -1102,11 +1074,9 @@ cdef class TimeSeries: INPUT: - - ``k`` -- positive integer. - - OUTPUT: + - ``k`` -- positive integer - A time series with the same number of steps as ``self``. + OUTPUT: a time series with the same number of steps as ``self`` EXAMPLES:: @@ -1156,11 +1126,9 @@ cdef class TimeSeries: INPUT: - - ``alpha`` -- float; a smoothing factor with ``0 <= alpha <= 1``. - - OUTPUT: + - ``alpha`` -- float; a smoothing factor with ``0 <= alpha <= 1`` - A time series with the same number of steps as ``self``. + OUTPUT: a time series with the same number of steps as ``self`` EXAMPLES:: @@ -1202,11 +1170,9 @@ cdef class TimeSeries: INPUT: - - ``s`` -- starting value for partial sums. - - OUTPUT: + - ``s`` -- starting value for partial sums - A time series. + OUTPUT: a time series EXAMPLES:: @@ -1228,9 +1194,7 @@ cdef class TimeSeries: If ``self`` has length 0, returns 0. - OUTPUT: - - A double. + OUTPUT: double EXAMPLES:: @@ -1251,9 +1215,7 @@ cdef class TimeSeries: If ``self`` has length 0, returns 1. - OUTPUT: - - A double. + OUTPUT: double EXAMPLES:: @@ -1272,9 +1234,7 @@ cdef class TimeSeries: r""" Return the mean (average) of the elements of ``self``. - OUTPUT: - - A double. + OUTPUT: double EXAMPLES:: @@ -1292,11 +1252,9 @@ cdef class TimeSeries: INPUT: - - ``k`` -- a float. - - OUTPUT: + - ``k`` -- a float - A time series. + OUTPUT: a time series EXAMPLES:: @@ -1318,11 +1276,9 @@ cdef class TimeSeries: INPUT: - - ``k`` -- a positive integer. + - ``k`` -- positive integer - OUTPUT: - - A double. + OUTPUT: double EXAMPLES:: @@ -1351,11 +1307,9 @@ cdef class TimeSeries: INPUT: - - ``k`` -- a positive integer. - - OUTPUT: + - ``k`` -- positive integer - A double. + OUTPUT: double EXAMPLES:: @@ -1389,7 +1343,7 @@ cdef class TimeSeries: INPUT: - - ``self``, ``other`` -- time series. + - ``self``, ``other`` -- time series Whichever time series has more terms is truncated. @@ -1430,11 +1384,9 @@ cdef class TimeSeries: INPUT: - - ``k`` -- a nonnegative integer (default: 0) + - ``k`` -- nonnegative integer (default: 0) - OUTPUT: - - A float. + OUTPUT: float EXAMPLES:: @@ -1486,7 +1438,7 @@ cdef class TimeSeries: INPUT: - - ``self``, ``other`` -- time series. + - ``self``, ``other`` -- time series Whichever time series has more terms is truncated. @@ -1514,15 +1466,13 @@ cdef class TimeSeries: {\sum_{t=0}^{n-1} (x_t - \mu)^2}. Note that the variance must be nonzero or you will get a - :class:`ZeroDivisionError`. + :exc:`ZeroDivisionError`. INPUT: - - ``k`` -- a nonnegative integer (default: 1) - - OUTPUT: + - ``k`` -- nonnegative integer (default: 1) - A time series. + OUTPUT: a time series EXAMPLES:: @@ -1550,13 +1500,11 @@ cdef class TimeSeries: INPUT: - - ``bias`` -- bool (default: ``False``); if ``False``, divide by + - ``bias`` -- boolean (default: ``False``); if ``False``, divide by ``self.length() - 1`` instead of ``self.length()`` to give a less biased estimator for the variance. - OUTPUT: - - A double. + OUTPUT: double EXAMPLES:: @@ -1594,13 +1542,11 @@ cdef class TimeSeries: INPUT: - - ``bias`` -- bool (default: ``False``); if ``False``, divide by + - ``bias`` -- boolean (default: ``False``); if ``False``, divide by ``self.length() - 1`` instead of ``self.length()`` to give a less biased estimator for the variance. - OUTPUT: - - A double. + OUTPUT: double EXAMPLES:: @@ -1642,16 +1588,14 @@ cdef class TimeSeries: INPUT: - - ``self`` -- a time series (*not* the series of differences). + - ``self`` -- a time series (*not* the series of differences) - ``b`` -- integer (default: ``None``); if given instead divide the input time series up into ``j = floor(n/b)`` disjoint blocks, compute the `R/S` statistic for each block, and return the average of those `R/S` statistics. - OUTPUT: - - A float. + OUTPUT: float EXAMPLES: @@ -1718,6 +1662,8 @@ cdef class TimeSeries: if len(v0) == 1: return v1[0]/v0[0] import numpy + if int(numpy.version.short_version[0]) > 1: + numpy.set_printoptions(legacy="1.25") coeffs = numpy.polyfit(v0,v1,1) return coeffs[0] @@ -1725,18 +1671,18 @@ cdef class TimeSeries: r""" Return the smallest value in this time series. - If this series has length 0, we raise a :class:`ValueError`. + If this series has length 0, we raise a :exc:`ValueError`. INPUT: - - ``index`` -- bool (default: ``False``); if ``True``, also return - index of minimal entry. + - ``index`` -- boolean (default: ``False``); if ``True``, also return + index of minimal entry OUTPUT: - - float -- smallest value. + - float; smallest value - - integer -- index of smallest value; only returned if ``index=True``. + - integer; index of smallest value (only returned if ``index=True``) EXAMPLES:: @@ -1763,18 +1709,18 @@ cdef class TimeSeries: def max(self, bint index=False): r""" Return the largest value in this time series. If this series - has length 0 we raise a :class:`ValueError`. + has length 0 we raise a :exc:`ValueError`. INPUT: - - ``index`` -- bool (default: ``False``); if ``True``, also return - index of maximum entry. + - ``index`` -- boolean (default: ``False``); if ``True``, also return + index of maximum entry OUTPUT: - - float -- largest value. + - float; largest value - - integer -- index of largest value; only returned if ``index=True``. + - integer; index of largest value (only returned if ``index=True``) EXAMPLES:: @@ -1805,13 +1751,11 @@ cdef class TimeSeries: INPUT: - - ``min`` -- (default: ``None``) ``None`` or double. + - ``min`` -- (default: ``None``) ``None`` or double - - ``max`` -- (default: ``None``) ``None`` or double. - - OUTPUT: + - ``max`` -- (default: ``None``) ``None`` or double - A time series. + OUTPUT: a time series EXAMPLES:: @@ -1883,18 +1827,16 @@ cdef class TimeSeries: INPUT: - - ``bins`` -- a positive integer (default: 50) + - ``bins`` -- positive integer (default: 50) - - ``normalize`` -- (default: ``False``) whether to normalize so the - total area in the bars of the histogram is 1. + - ``normalize`` -- boolean (default: ``False``); whether to normalize so the + total area in the bars of the histogram is 1 OUTPUT: - - counts -- list of counts of numbers of elements in - each bin. + - counts -- list of counts of numbers of elements in each bin - - endpoints -- list of 2-tuples (a,b) that give the - endpoints of the bins. + - endpoints -- list of 2-tuples (a,b) that give the endpoints of the bins EXAMPLES:: @@ -1952,12 +1894,10 @@ cdef class TimeSeries: - ``bins`` -- positive integer (default: 50) - - ``normalize`` -- (default: ``True``) whether to normalize so the - total area in the bars of the histogram is 1. - - OUTPUT: + - ``normalize`` -- boolean (default: ``True``); whether to normalize so the + total area in the bars of the histogram is 1 - A histogram plot. + OUTPUT: a histogram plot EXAMPLES:: @@ -1994,12 +1934,10 @@ cdef class TimeSeries: INPUT: - - ``bins`` -- positive integer (default: 30), the number of bins - or candles. - - OUTPUT: + - ``bins`` -- positive integer (default: 30); the number of bins + or candles - A candlestick plot. + OUTPUT: a candlestick plot EXAMPLES: @@ -2056,11 +1994,9 @@ cdef class TimeSeries: INPUT: - - ``copy`` -- bool (default: ``True``) - - OUTPUT: + - ``copy`` -- boolean (default: ``True``) - A numpy 1-D array. + OUTPUT: a numpy 1-D array EXAMPLES:: @@ -2088,7 +2024,7 @@ cdef class TimeSeries: sage: v [20.0000, -3.0000, 4.5000, -2.0000] """ - cnumpy.import_array() #This must be called before using the numpy C/api or you will get segfault + cnumpy.import_array() # This must be called before using the numpy C/api or you will get segfault cdef cnumpy.npy_intp dims[1] dims[0] = self._length cdef cnumpy.ndarray n = cnumpy.PyArray_SimpleNewFromData(1, dims, cnumpy.NPY_DOUBLE, self._values) @@ -2107,7 +2043,7 @@ cdef class TimeSeries: INPUT: - - ``distribution`` -- (default: ``"uniform"``); supported values are: + - ``distribution`` -- (default: ``'uniform'``) supported values are: - ``'uniform'`` -- from ``loc`` to ``loc + scale`` @@ -2207,9 +2143,9 @@ cdef class TimeSeries: INPUT: - - ``left`` -- left bound on random distribution. + - ``left`` -- left bound on random distribution - - ``right`` -- right bound on random distribution. + - ``right`` -- right bound on random distribution EXAMPLES: @@ -2301,7 +2237,7 @@ cdef class TimeSeries: INPUT: - - ``center`` -- the center of the semicircle distribution. + - ``center`` -- the center of the semicircle distribution EXAMPLES: @@ -2521,9 +2457,7 @@ cdef new_time_series(Py_ssize_t length): - ``length`` -- integer - OUTPUT: - - A time series. + OUTPUT: a time series EXAMPLES: diff --git a/src/sage/structure/__init__.py b/src/sage/structure/__init__.py index bf977ccc379..2534e5a71f8 100644 --- a/src/sage/structure/__init__.py +++ b/src/sage/structure/__init__.py @@ -1,3 +1,3 @@ # sage_setup: distribution = sagemath-objects # Resolve a cyclic import -import sage.structure.element +import sage.structure.element \ No newline at end of file diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index 3a7d6e7204e..a72d3fcd887 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -84,11 +84,11 @@ cdef class CategoryObject(SageObject): INPUT: - - ``category`` -- The category this object belongs to. If this object + - ``category`` -- the category this object belongs to; if this object belongs to multiple categories, those can be passed as a tuple - - ``base`` -- If this object has another object that should be + - ``base`` -- if this object has another object that should be considered a base in its primary category, you can include that base - here. + here EXAMPLES:: @@ -238,7 +238,7 @@ cdef class CategoryObject(SageObject): Return the underlying class (class without the attached categories) of the given object. - OUTPUT: A class + OUTPUT: a class EXAMPLES:: @@ -429,7 +429,6 @@ cdef class CategoryObject(SageObject): This can only be done once because objects with generators are immutable, and is typically done during creation of the object. - EXAMPLES: When we create this polynomial ring, self._assign_names is called by the constructor:: @@ -490,7 +489,7 @@ cdef class CategoryObject(SageObject): """ Return the first variable name. - OUTPUT: a string + OUTPUT: string EXAMPLES:: @@ -521,7 +520,6 @@ cdef class CategoryObject(SageObject): sage: a #indirect doctest [1 0] [0 0] - """ # old = self._names, self._latex_names # We cannot assume that self *has* _latex_variable_names. @@ -546,7 +544,7 @@ cdef class CategoryObject(SageObject): Thus, e.g., if the generators of ``self`` are labeled 'a', 'b', and 'c', then after calling this method the variables a, b, and c in the current scope will be set - equal to the generators of self. + equal to the generators of ``self``. NOTE: If Foo is a constructor for a Sage object with generators, and Foo is defined in Cython, then it would typically call @@ -670,7 +668,7 @@ cdef class CategoryObject(SageObject): def latex_variable_names(self): """ - Returns the list of variable names suitable for latex output. + Return the list of variable names suitable for latex output. All ``_SOMETHING`` substrings are replaced by ``_{SOMETHING}`` recursively so that subscripts of subscripts work. @@ -773,7 +771,7 @@ cdef class CategoryObject(SageObject): sage: h1 = hash(bla) sage: h1 # random -5279516879544852222 - sage: bla.rename("toto") + sage: bla.rename('toto') sage: h2 = hash(bla) sage: h2 # random -5279516879544852222 @@ -913,7 +911,6 @@ cdef class CategoryObject(SageObject): sage: F = GF(9,'a') # needs sage.rings.finite_rings sage: dir(F) # needs sage.rings.finite_rings [..., '__class__', ..., '_test_pickling', ..., 'extension', ...] - """ return dir_with_other_class(self, self.category().parent_class) @@ -924,7 +921,7 @@ cpdef normalize_names(Py_ssize_t ngens, names): INPUT: - - ``ngens`` -- integer: number of generators. The value ``ngens=-1`` + - ``ngens`` -- integer; number of generators. The value ``ngens=-1`` means that the number of generators is unknown a priori. - ``names`` -- any of the following: @@ -937,7 +934,7 @@ cpdef normalize_names(Py_ssize_t ngens, names): - a string of single character names, such as 'xyz' - OUTPUT: a tuple of ``ngens`` strings to be used as variable names. + OUTPUT: a tuple of ``ngens`` strings to be used as variable names EXAMPLES:: diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index dfbd5ff82fa..7ee41f74a04 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -31,7 +31,7 @@ If there is a coercion (see below) from one of the parents to the other, the operation is always performed in the codomain of that coercion. Otherwise a reasonable attempt to create a new parent with coercion maps from both original parents is made. The results of these discoveries are cached. -On failure, a :class:`TypeError` is always raised. +On failure, a :exc:`TypeError` is always raised. Some arithmetic operations (such as multiplication) can indicate an action rather than arithmetic in a common parent. For example:: @@ -103,8 +103,8 @@ cdef type FractionType = Fraction cpdef py_scalar_parent(py_type): """ - Returns the Sage equivalent of the given python type, if one exists. - If there is no equivalent, return None. + Return the Sage equivalent of the given python type, if one exists. + If there is no equivalent, return ``None``. EXAMPLES:: @@ -520,6 +520,8 @@ cdef class CoercionModel: Check that :issue:`8426` is fixed (see also :issue:`18076`):: sage: import numpy # needs numpy + sage: if int(numpy.version.short_version[0]) > 1: # needs numpy + ....: numpy.set_printoptions(legacy="1.25") # needs numpy sage: # needs sage.rings.real_mpfr sage: x = polygen(RR) @@ -683,7 +685,7 @@ cdef class CoercionModel: sage: cm.record_exceptions() sage: cm._test_exception_stack() sage: cm.exception_stack() - ['Traceback (most recent call last):\n File "sage/structure/coerce.pyx", line ...TypeError: just a test'] + ['Traceback (most recent call last):\n File "...coerce.pyx", line ...TypeError: just a test'] sage: cm.record_exceptions(False) sage: cm._test_exception_stack() sage: cm.exception_stack() @@ -695,7 +697,7 @@ cdef class CoercionModel: cpdef _record_exception(self): r""" - Pushes the last exception that occurred onto the stack for later reference, + Push the last exception that occurred onto the stack for later reference, for internal use. If the stack has not yet been flagged as cleared, we clear it now (rather @@ -711,7 +713,7 @@ cdef class CoercionModel: [] sage: cm._test_exception_stack() sage: cm.exception_stack() - ['Traceback (most recent call last):\n File "sage/structure/coerce.pyx", line ...TypeError: just a test'] + ['Traceback (most recent call last):\n File "...coerce.pyx", line ...TypeError: just a test'] The function _test_exception_stack is executing the following code:: @@ -741,7 +743,7 @@ cdef class CoercionModel: [] sage: cm._test_exception_stack() sage: cm.exception_stack() - ['Traceback (most recent call last):\n File "sage/structure/coerce.pyx", line ...TypeError: just a test'] + ['Traceback (most recent call last):\n File "...coerce.pyx", line ...TypeError: just a test'] """ try: raise TypeError("just a test") @@ -750,7 +752,7 @@ cdef class CoercionModel: def exception_stack(self): r""" - Returns the list of exceptions that were caught in the course of + Return the list of exceptions that were caught in the course of executing the last binary operation. Useful for diagnosis when user-defined maps or actions raise exceptions that are caught in the course of coercion detection. @@ -1033,12 +1035,12 @@ cdef class CoercionModel: INPUT: - - ``args`` -- a set of elements and/or parents + - ``args`` -- set of elements and/or parents OUTPUT: A :class:`Parent` into which each input should coerce, or raises a - :class:`TypeError` if no such :class:`Parent` can be found. + :exc:`TypeError` if no such :class:`Parent` can be found. EXAMPLES:: @@ -1139,7 +1141,7 @@ cdef class CoercionModel: corresponding to ``op``, and failing that, it tries to coerce `x` and `y` into a common parent and calls ``op`` on them. - If it cannot make sense of the operation, a :class:`TypeError` is raised. + If it cannot make sense of the operation, a :exc:`TypeError` is raised. INPUT: @@ -1523,7 +1525,6 @@ cdef class CoercionModel: sage: N2 = len(list(o for o in gc.get_objects() if type(o) is T)) sage: N2 - N0 0 - """ try: refs = self._coercion_maps.get(R, S, None) @@ -1829,11 +1830,9 @@ cdef class CoercionModel: - ``S`` -- the right :class:`Parent` (or type) - ``op`` -- the operand, typically an element of the :mod:`operator` module - ``r`` -- (optional) element of `R` - - ``s`` -- (optional) element of `S`. - - OUTPUT: + - ``s`` -- (optional) element of `S` - - An action `A` such that `s` ``op`` `r` is given by `A(s,r)`. + OUTPUT: an action `A` such that `s` ``op`` `r` is given by `A(s,r)` The steps taken are illustrated below. diff --git a/src/sage/structure/coerce_actions.pyx b/src/sage/structure/coerce_actions.pyx index 2a9c56174e7..b25abdf328a 100644 --- a/src/sage/structure/coerce_actions.pyx +++ b/src/sage/structure/coerce_actions.pyx @@ -73,7 +73,6 @@ cdef class GenericAction(Action): sage: GenericAction(QQ, Z6, True, check=False) Left action by Rational Field on Ring of integers modulo 6 - """ Action.__init__(self, G, S, is_left, operator.mul) if check: @@ -84,7 +83,7 @@ cdef class GenericAction(Action): def codomain(self): """ - Returns the "codomain" of this action, i.e. the Parent in which the + Return the "codomain" of this action, i.e. the Parent in which the result elements live. Typically, this should be the same as the acted upon set. @@ -107,7 +106,6 @@ cdef class GenericAction(Action): sage: A = sage.structure.coerce_actions.ActOnAction(S3, QQxyz, False) sage: A.codomain() Multivariate Polynomial Ring in x, y, z over Rational Field - """ if self._codomain is None: self._codomain = parent(self.act(an_element(self.G), @@ -253,12 +251,12 @@ cdef class ModuleAction(Action): INPUT: - - ``G`` -- the actor, an instance of :class:`~sage.structure.parent.Parent`. - - ``S`` -- the object that is acted upon. - - ``g`` -- optional, an element of ``G``. - - ``a`` -- optional, an element of ``S``. - - ``check`` -- if True (default), then there will be no consistency tests - performed on sample elements. + - ``G`` -- the actor, an instance of :class:`~sage.structure.parent.Parent` + - ``S`` -- the object that is acted upon + - ``g`` -- (optional) an element of ``G`` + - ``a`` -- (optional) an element of ``S`` + - ``check`` -- if ``True`` (default), then there will be no consistency tests + performed on sample elements NOTE: @@ -275,7 +273,6 @@ cdef class ModuleAction(Action): assumption that the inputs lie exactly in the base ring and may segfault otherwise. Thus we handle all possible base extensions manually here. - """ def __init__(self, G, S, g=None, a=None, check=True): """ @@ -332,7 +329,6 @@ cdef class ModuleAction(Action): sage: G.gen() * S.gen() [x 0] [0 x]*y - """ Action.__init__(self, G, S, not isinstance(self, RightModuleAction), operator.mul) if not isinstance(G, Parent): @@ -431,7 +427,6 @@ cdef class ModuleAction(Action): sage: RightModuleAction(GF5, GF5t) Right scalar multiplication by Finite Field of size 5 on Power Series Ring in t over Finite Field of size 5 - """ return "scalar multiplication" diff --git a/src/sage/structure/coerce_dict.pyx b/src/sage/structure/coerce_dict.pyx index 768d2488dca..e060bc73a28 100644 --- a/src/sage/structure/coerce_dict.pyx +++ b/src/sage/structure/coerce_dict.pyx @@ -204,7 +204,7 @@ cdef class MonoDictEraser: """ INPUT: - A :class:`MonoDict`. + - ``D`` -- a :class:`MonoDict` EXAMPLES:: @@ -222,7 +222,7 @@ cdef class MonoDictEraser: """ INPUT: - A weak reference with key. + - ``r`` -- a weak reference with key For internal use only. @@ -273,12 +273,12 @@ cdef class MonoDict: INPUT: - - ``data`` -- optional iterable defining initial data, as dict or - iterable of (key, value) pairs. + - ``data`` -- (optional) iterable defining initial data, as dict or + iterable of (key, value) pairs - - ``weak_values`` -- optional bool (default: ``False``). If it is true, - weak references to the values in this dictionary will be used, - when possible. + - ``weak_values`` -- boolean (default: ``False``); if it is + ``True``, weak references to the values in this dictionary will be used, + when possible EXAMPLES:: @@ -520,7 +520,7 @@ cdef class MonoDict: def __cinit__(self): """ - Setup basic data structure + Setup basic data structure. TESTS:: @@ -555,7 +555,6 @@ cdef class MonoDict: sage: L = MonoDict([(a, 1)]) sage: L[a] 1 - """ self.weak_values = weak_values if data: @@ -572,7 +571,7 @@ cdef class MonoDict: def __len__(self): """ - The number of items in self. + The number of items in ``self``. EXAMPLES:: sage: from sage.structure.coerce_dict import MonoDict @@ -924,7 +923,7 @@ cdef class TripleDictEraser: """ INPUT: - A :class:`TripleDict`. For internal use only. + - ``D`` -- a :class:`TripleDict`. For internal use only. EXAMPLES:: @@ -936,7 +935,6 @@ cdef class TripleDictEraser: sage: del k sage: len(D) # indirect doctest 0 - """ self.D = ref(D) @@ -944,7 +942,7 @@ cdef class TripleDictEraser: """ INPUT: - A weak reference with key. + - ``r`` -- a weak reference with key For internal use only. @@ -1003,23 +1001,20 @@ cdef class TripleDict: It is bare-bones in the sense that not all dictionary methods are implemented. - INPUT: - - ``data`` -- optional iterable defining initial data, as dict or - iterable of (key, value) pairs. - - - ``weak_values`` -- optional bool (default: ``False``). If it is true, - weak references to the values in this dictionary will be used, - when possible. + - ``data`` -- (optional) iterable defining initial data, as dict or + iterable of (key, value) pairs + - ``weak_values`` -- boolean (default: ``False``); if it is + ``True``, weak references to the values in this dictionary will be used, + when possible IMPLEMENTATION: It is implemented as a hash table with open addressing, similar to python's dict. - EXAMPLES:: sage: from sage.structure.coerce_dict import TripleDict @@ -1190,7 +1185,7 @@ cdef class TripleDict: def __cinit__(self): """ - Setup basic data structure + Setup basic data structure. TESTS:: @@ -1226,7 +1221,6 @@ cdef class TripleDict: sage: L = TripleDict({key: 42}) sage: L[key] 42 - """ self.weak_values = weak_values if data: @@ -1243,7 +1237,7 @@ cdef class TripleDict: def __len__(self): """ - The number of items in self. + The number of items in ``self``. EXAMPLES:: diff --git a/src/sage/structure/debug_options.pyx b/src/sage/structure/debug_options.pyx index 3afe5ca835a..78e12faa0ce 100644 --- a/src/sage/structure/debug_options.pyx +++ b/src/sage/structure/debug_options.pyx @@ -26,7 +26,7 @@ EXAMPLES:: cdef class DebugOptions_class: def __cinit__(self): """ - Initializer for the debug options + Initializer for the debug options. TESTS:: diff --git a/src/sage/structure/dynamic_class.py b/src/sage/structure/dynamic_class.py index 1beb2a8210f..36488c76f99 100644 --- a/src/sage/structure/dynamic_class.py +++ b/src/sage/structure/dynamic_class.py @@ -131,23 +131,23 @@ def dynamic_class(name, bases, cls=None, reduction=None, doccls=None, r""" INPUT: - - ``name`` -- a string - - ``bases`` -- a tuple of classes + - ``name`` -- string + - ``bases`` -- tuple of classes - ``cls`` -- a class or ``None`` - - ``reduction`` -- a tuple or ``None`` + - ``reduction`` -- tuple or ``None`` - ``doccls`` -- a class or ``None`` - - ``prepend_cls_bases`` -- a boolean (default: ``True``) - - ``cache`` -- a boolean or ``"ignore_reduction"`` (default: ``True``) + - ``prepend_cls_bases`` -- boolean (default: ``True``) + - ``cache`` -- boolean or ``'ignore_reduction'`` (default: ``True``) Constructs dynamically a new class ``C`` with name ``name``, and bases ``bases``. If ``cls`` is provided, then its methods will be inserted into ``C``, and its bases will be prepended to ``bases`` (unless ``prepend_cls_bases`` is ``False``). - The module, documentation and source instrospection is taken from + The module, documentation and source introspection is taken from ``doccls``, or ``cls`` if ``doccls`` is ``None``, or ``bases[0]`` if both are ``None`` (therefore ``bases`` should be non empty if - ``cls` is ``None``). + ``cls`` is ``None``). The constructed class can safely be pickled (assuming the arguments themselves can). @@ -236,7 +236,7 @@ class also has a zero ``__dictoffset__``. This means that the The following (meaningless) example illustrates how to customize the result of the reduction:: - sage: BarFoo = dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (3,))) + sage: BarFoo = dynamic_class('BarFoo', (Foo,), Bar, reduction = (str, (3,))) sage: type(BarFoo).__reduce__(BarFoo) (, (3,)) sage: loads(dumps(BarFoo)) @@ -253,9 +253,9 @@ class also has a zero ``__dictoffset__``. This means that the and the result depends on the reduction:: - sage: dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (3,))) is BarFoo + sage: dynamic_class('BarFoo', (Foo,), Bar, reduction = (str, (3,))) is BarFoo True - sage: dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (2,))) is BarFoo + sage: dynamic_class('BarFoo', (Foo,), Bar, reduction = (str, (2,))) is BarFoo False With ``cache=False``, a new class is created each time:: @@ -272,14 +272,14 @@ class also has a zero ``__dictoffset__``. This means that the With ``cache="ignore_reduction"``, the class does not depend on the reduction:: - sage: BarFoo = dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (3,)), cache="ignore_reduction") - sage: dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (2,)), cache="ignore_reduction") is BarFoo + sage: BarFoo = dynamic_class('BarFoo', (Foo,), Bar, reduction = (str, (3,)), cache='ignore_reduction') + sage: dynamic_class('BarFoo', (Foo,), Bar, reduction = (str, (2,)), cache='ignore_reduction') is BarFoo True In particular, the reduction used is that provided upon creating the first class:: - sage: dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (2,)), cache="ignore_reduction")._reduction + sage: dynamic_class('BarFoo', (Foo,), Bar, reduction = (str, (2,)), cache='ignore_reduction')._reduction (, (3,)) .. WARNING:: @@ -305,7 +305,7 @@ class also has a zero ``__dictoffset__``. This means that the sage: pickle.loads(pickle.dumps(FooBar)) == FooBar True - We check that instrospection works reasonably:: + We check that introspection works reasonably:: sage: sage.misc.sageinspect.sage_getdoc(FooBar) 'The Foo class\n' @@ -363,7 +363,7 @@ def dynamic_class_internal(name, bases, cls=None, reduction=None, doccls=None, p sage: Foo3.__doc__ == sage.structure.dynamic_class.TestClass.__doc__ True - We check that instrospection works reasonably:: + We check that introspection works reasonably:: sage: from sage.misc.sageinspect import sage_getfile, sage_getsourcelines sage: sage_getfile(Foo2) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index a53c70a3f60..18a58f46103 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -573,10 +573,10 @@ cdef class Element(SageObject): def __setstate__(self, state): """ - Initializes the state of the object from data saved in a pickle. + Initialize the state of the object from data saved in a pickle. - During unpickling __init__ methods of classes are not called, the saved - data is passed to the class via this function instead. + During unpickling ``__init__`` methods of classes are not called, the + saved data is passed to the class via this function instead. TESTS:: @@ -595,9 +595,7 @@ cdef class Element(SageObject): """ Return a copy of ``self``. - OUTPUT: - - - a new object which is a copy of ``self``. + OUTPUT: a new object which is a copy of ``self`` This implementation ensures that ``self.__dict__`` is properly copied when it exists (typically for instances of classes deriving from @@ -627,7 +625,7 @@ cdef class Element(SageObject): D = self.__dict__ except AttributeError: return res - for k,v in D.iteritems(): + for k, v in D.iteritems(): try: setattr(res, k, v) except AttributeError: @@ -713,7 +711,7 @@ cdef class Element(SageObject): AssertionError: self.an_element() is not in self """ tester = self._tester(**options) - SageObject._test_category(self, tester = tester) + SageObject._test_category(self, tester=tester) category = self.category() # Tests that self inherits methods from the categories if can_assign_class(self): @@ -762,13 +760,13 @@ cdef class Element(SageObject): # 100% sure we indeed call the operators == and !=, whatever # the version of Python is (see #11236) tester.assertTrue(self == self, - LazyFormat("broken equality: %s == itself is False")%self) + LazyFormat("broken equality: %s == itself is False") % self) tester.assertFalse(self == None, - LazyFormat("broken equality: %s == None")%self) + LazyFormat("broken equality: %s == None") % self) tester.assertFalse(self != self, - LazyFormat("broken non-equality: %s != itself")%self) + LazyFormat("broken non-equality: %s != itself") % self) tester.assertTrue(self != None, - LazyFormat("broken non-equality: %s is not != None")%self) + LazyFormat("broken non-equality: %s is not != None") % self) def parent(self, x=None): """ @@ -795,9 +793,7 @@ cdef class Element(SageObject): - ``**kwds`` -- named parameters - OUTPUT: - - - new object if substitution is possible, otherwise self. + OUTPUT: new object if substitution is possible, otherwise ``self`` EXAMPLES:: @@ -963,9 +959,9 @@ cdef class Element(SageObject): if self._is_atomic(): s = repr(self) else: - s = "(%s)"%repr(self) + s = "(%s)" % repr(self) if no_space: - return s.replace(' ','') + return s.replace(' ', '') return s def _latex_coeff_repr(self): @@ -976,7 +972,7 @@ cdef class Element(SageObject): if self._is_atomic(): return s else: - return "\\left(%s\\right)"%s + return "\\left(%s\\right)" % s def _is_atomic(self): """ @@ -1032,12 +1028,11 @@ cdef class Element(SageObject): True sage: bool(v + w) False - """ try: zero = self._parent.zero() except Exception: - return True # by convention + return True # by convention return self != zero @@ -1252,7 +1247,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_add_`` calls the Python method ``self._add_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1364,7 +1359,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_sub_`` calls the Python method ``self._sub_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1418,7 +1413,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_neg_`` calls the Python method ``self._neg_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1532,7 +1527,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_mul_`` calls the Python method ``self._mul_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1645,7 +1640,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_matmul_`` calls the Python method ``self._matmul_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the - parent. If the method is not found, a ``TypeError`` is raised + parent. If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1748,7 +1743,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_div_`` calls the Python method ``self._div_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1848,7 +1843,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_floordiv_`` calls the Python method ``self._floordiv_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -1948,7 +1943,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_mod_`` calls the Python method ``self._mod_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -2075,7 +2070,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_pow_`` calls the Python method ``self._pow_`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -2105,7 +2100,7 @@ cdef class Element(SageObject): This default Cython implementation of ``_pow_int`` calls the Python method ``self._pow_int`` if it exists. This method may be defined in the ``ElementMethods`` of the category of the parent. - If the method is not found, a ``TypeError`` is raised + If the method is not found, a :exc:`TypeError` is raised indicating that the operation is not supported. See :ref:`element_arithmetic`. @@ -2309,7 +2304,6 @@ cdef class ElementWithCachedMethod(Element): <-5> sage: epython.element_cache_test() is epython.element_cache_test() # needs sage.misc.cython True - """ cdef getattr_from_category(self, name): """ @@ -2371,7 +2365,7 @@ cdef class ElementWithCachedMethod(Element): attr = getattr_from_other_class(self, self._parent.category().element_class, name) - self._cached_methods = {name : attr} + self._cached_methods = {name: attr} return attr @@ -2381,7 +2375,7 @@ cdef class ModuleElement(Element): """ cpdef _add_(self, other): """ - Abstract addition method + Abstract addition method. TESTS:: @@ -2440,22 +2434,23 @@ cdef class ModuleElement(Element): Scalar multiplication for module elements with the module element on the left and the scalar on the right. - Returning None indicates that this action is not implemented here. + Returning ``None`` indicates that this action is not implemented here. """ return None ################################################## # Other properties ################################################## - def order(self): ### DO NOT OVERRIDE THIS!!! Instead, override additive_order. + def order(self): + # DO NOT OVERRIDE THIS!!! Instead, override additive_order. """ - Return the additive order of self. + Return the additive order of ``self``. """ return self.additive_order() def additive_order(self): """ - Return the additive order of self. + Return the additive order of ``self``. """ raise NotImplementedError @@ -2495,7 +2490,7 @@ cdef class ModuleElementWithMutability(ModuleElement): cpdef bint is_mutable(self) noexcept: """ - Return True if this vector is mutable, i.e., the entries can be + Return ``True`` if this vector is mutable, i.e., the entries can be changed. EXAMPLES:: @@ -2510,7 +2505,7 @@ cdef class ModuleElementWithMutability(ModuleElement): cpdef bint is_immutable(self) noexcept: """ - Return True if this vector is immutable, i.e., the entries cannot + Return ``True`` if this vector is immutable, i.e., the entries cannot be changed. EXAMPLES:: @@ -2548,19 +2543,19 @@ cdef class MonoidElement(Element): ############################################################# def order(self): """ - Return the multiplicative order of self. + Return the multiplicative order of ``self``. """ return self.multiplicative_order() def multiplicative_order(self): """ - Return the multiplicative order of self. + Return the multiplicative order of ``self``. """ raise NotImplementedError cpdef _pow_int(self, n): """ - Return the (integral) power of self. + Return the (integral) power of ``self``. """ return arith_generic_power(self, n) @@ -2628,7 +2623,7 @@ cdef class MultiplicativeGroupElement(MonoidElement): """ def order(self): """ - Return the multiplicative order of self. + Return the multiplicative order of ``self``. """ return self.multiplicative_order() @@ -2661,7 +2656,7 @@ def is_RingElement(x): cdef class RingElement(ModuleElement): cpdef _mul_(self, other): """ - Abstract multiplication method + Abstract multiplication method. TESTS:: @@ -2721,10 +2716,10 @@ cdef class RingElement(ModuleElement): sage: 2r^(1/2) # needs sage.symbolic sqrt(2) - Exponent overflow should throw an :class:`OverflowError` (:issue:`2956`):: + Exponent overflow should throw an :exc:`OverflowError` (:issue:`2956`):: sage: K. = AA[] # needs sage.rings.number_field - sage: x^(2^64 + 12345) # needs sage.rings.number_field + sage: x^(2^64 + 12345) # known bug: macos # needs sage.rings.number_field Traceback (most recent call last): ... OverflowError: exponent overflow (2147483648) @@ -2847,8 +2842,9 @@ cdef class RingElement(ModuleElement): def multiplicative_order(self): r""" - Return the multiplicative order of ``self``, if ``self`` is a unit, - or raise ``ArithmeticError`` otherwise. + Return the multiplicative order of ``self``, if ``self`` is a unit. + + This raises an :class:`ArithmeticError` otherwise. """ if not self.is_unit(): raise ArithmeticError("self (=%s) must be a unit to have a multiplicative order.") @@ -2899,9 +2895,9 @@ cdef class RingElement(ModuleElement): def is_prime(self): """ - Is ``self`` a prime element? + Check whether ``self`` is a prime element. - A *prime* element is a non-zero, non-unit element `p` such that, + A *prime* element is a nonzero, non-unit element `p` such that, whenever `p` divides `ab` for some `a` and `b`, then `p` divides `a` or `p` divides `b`. @@ -3086,7 +3082,7 @@ cdef class CommutativeRingElement(RingElement): If ``x`` has different parent than ``self``, they are first coerced to a common parent if possible. If this coercion fails, it returns a - TypeError. This fixes :issue:`5759`. :: + :exc:`TypeError`. This fixes :issue:`5759`. :: sage: Zmod(2)(0).divides(Zmod(2)(0)) True @@ -3106,26 +3102,27 @@ cdef class CommutativeRingElement(RingElement): # First we test some generic conditions: try: if x.is_zero(): - return True # everything divides 0 + return True # everything divides 0 except (AttributeError, NotImplementedError): pass try: if self.is_zero(): - return False # 0 divides nothing else + return False # 0 divides nothing else except (AttributeError, NotImplementedError): pass try: if self.is_unit(): - return True # units divide everything + return True # units divide everything except (AttributeError, NotImplementedError): pass try: if self.is_one(): - return True # 1 divides everything - # (is_unit() may not be implemented) + return True + # 1 divides everything + # (is_unit() may not be implemented) except (AttributeError, NotImplementedError): pass @@ -3137,7 +3134,7 @@ cdef class CommutativeRingElement(RingElement): raise NotImplementedError else: - #Different parents, use coercion + # Different parents, use coercion a, b = coercion_model.canonical_coercion(self, x) return a.divides(b) @@ -3165,7 +3162,6 @@ cdef class CommutativeRingElement(RingElement): sage: n.mod([15,6]) 2 - EXAMPLES: Univariate polynomials :: @@ -3208,10 +3204,9 @@ cdef class CommutativeRingElement(RingElement): sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) ) # needs sage.libs.singular x^2 + 2*z^2 """ - from sage.rings.ideal import is_Ideal - if not is_Ideal(I) or not I.ring() is self._parent: + from sage.rings.ideal import Ideal_generic + if not isinstance(I, Ideal_generic) or not I.ring() is self._parent: I = self._parent.ideal(I) - #raise TypeError, "I = %s must be an ideal in %s"%(I, self.parent()) return I.reduce(self) ################################################## @@ -3227,15 +3222,15 @@ cdef class CommutativeRingElement(RingElement): INPUT: - - ``root`` -- whether or not to also return a square - root (default: ``False``) + - ``root`` -- boolean (default: ``False``); whether or not to also + return a square root OUTPUT: - - ``bool`` -- whether or not a square + - boolean; whether or not a square - - ``object`` -- (optional) an actual square root if - found, and ``None`` otherwise. + - object; (optional) an actual square root if found, and ``None`` + otherwise EXAMPLES:: @@ -3253,11 +3248,10 @@ cdef class CommutativeRingElement(RingElement): .. NOTE:: - This is the is_square implementation for general - commutative ring elements. It's implementation is to raise - a NotImplementedError. The function definition is here to - show what functionality is expected and provide a general - framework. + This is the is_square implementation for general commutative ring + elements. It's implementation is to raise a + :exc:`NotImplementedError`. The function definition is here to show + what functionality is expected and provide a general framework. """ raise NotImplementedError("is_square() not implemented for elements of %s" % self.parent()) @@ -3268,13 +3262,13 @@ cdef class CommutativeRingElement(RingElement): INPUT: - ``extend`` -- boolean (default: ``True``); whether to make a ring - extension containing a square root if ``self`` is not a square + extension containing a square root if ``self`` is not a square - ``all`` -- boolean (default: ``False``); whether to return a list of - all square roots or just a square root + all square roots or just a square root - ``name`` -- required when ``extend=True`` and ``self`` is not a - square. This will be the name of the generator of the extension. + square; this will be the name of the generator of the extension OUTPUT: @@ -3297,11 +3291,11 @@ cdef class CommutativeRingElement(RingElement): x sage: f = x^2 - 4*x + 4; f.sqrt(all=True) [x - 2, -x + 2] - sage: sqrtx = x.sqrt(name="y"); sqrtx + sage: sqrtx = x.sqrt(name='y'); sqrtx y sage: sqrtx^2 x - sage: x.sqrt(all=true, name="y") + sage: x.sqrt(all=true, name='y') [y, -y] sage: x.sqrt(extend=False, all=True) [] @@ -3342,11 +3336,11 @@ cdef class CommutativeRingElement(RingElement): sage: R. = QQ[] sage: a = 2*(x+1)^2 / (2*(x-1)^2); a.sqrt() (x + 1)/(x - 1) - sage: sqrtx=(1/x).sqrt(name="y"); sqrtx + sage: sqrtx=(1/x).sqrt(name='y'); sqrtx y sage: sqrtx^2 1/x - sage: (1/x).sqrt(all=true, name="y") + sage: (1/x).sqrt(all=true, name='y') [y, -y] sage: (1/x).sqrt(extend=False, all=True) [] @@ -3360,8 +3354,8 @@ cdef class CommutativeRingElement(RingElement): ... ValueError: trying to take square root of non-square 1/(x^2 - 3) with extend = False """ - #This code is very general, it works for all integral domains that have the - #is_square(root = True) option + # This code is very general, it works for all integral domains that have the + # is_square(root = True) option from sage.categories.integral_domains import IntegralDomains P = self._parent @@ -3371,15 +3365,15 @@ cdef class CommutativeRingElement(RingElement): if P not in IntegralDomains(): raise NotImplementedError('sqrt() with all=True is only implemented for integral domains, not for %s' % P) if P.characteristic()==2 or sq_rt==0: - #0 has only one square root, and in characteristic 2 everything also has only 1 root - return [ sq_rt ] - return [ sq_rt, -sq_rt ] + # 0 has only one square root, and in characteristic 2 everything also has only 1 root + return [sq_rt] + return [sq_rt, -sq_rt] return sq_rt - #from now on we know that self is not a square + # from now on we know that self is not a square if P not in IntegralDomains(): raise NotImplementedError('sqrt() of non squares is only implemented for integral domains, not for %s' % P) if not extend: - #all square roots of a non-square should be an empty list + # all square roots of a non-square should be an empty list if all: return [] raise ValueError('trying to take square root of non-square %s with extend = False' % self) @@ -3392,8 +3386,8 @@ cdef class CommutativeRingElement(RingElement): sq_rt = PY.quotient(y**2-self, names = name)(y) if all: if P.characteristic() == 2: - return [ sq_rt ] - return [ sq_rt, -sq_rt ] + return [sq_rt] + return [sq_rt, -sq_rt] return sq_rt ############################################## @@ -3430,7 +3424,7 @@ cdef class Vector(ModuleElementWithMutability): def __mul__(left, right): """ - Multiplication of vector by vector, matrix, or scalar + Multiplication of vector by vector, matrix, or scalar. AUTHOR: @@ -3710,7 +3704,7 @@ cdef class Vector(ModuleElementWithMutability): raise bin_op_exception('*', left, right) cpdef _pairwise_product_(Vector left, Vector right): - raise TypeError("unsupported operation for '%s' and '%s'"%(parent(left), parent(right))) + raise TypeError("unsupported operation for '%s' and '%s'" % (parent(left), parent(right))) def __truediv__(self, right): """ @@ -3786,7 +3780,7 @@ cdef class Vector(ModuleElementWithMutability): """ V = magma(self._parent) v = [x._magma_init_(magma) for x in self.list()] - return '%s![%s]'%(V.name(), ','.join(v)) + return '%s![%s]' % (V.name(), ','.join(v)) def is_Vector(x): @@ -3805,7 +3799,7 @@ cdef class Matrix(ModuleElement): def __mul__(left, right): """ - Multiplication of matrix by matrix, vector, or scalar + Multiplication of matrix by matrix, vector, or scalar. AUTHOR: @@ -4330,7 +4324,7 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): cpdef _floordiv_(self, right): """ - Quotient of division of ``self`` by other. This is denoted //. + Quotient of division of ``self`` by ``other``. This is denoted ``//``. This default implementation assumes that ``quo_rem`` has been implemented. @@ -4353,7 +4347,7 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): cpdef _mod_(self, other): """ - Remainder of division of ``self`` by other. + Remainder of division of ``self`` by ``other``. This default implementation assumes that ``quo_rem`` has been implemented. @@ -4395,7 +4389,7 @@ def is_FieldElement(x): cdef class FieldElement(CommutativeRingElement): cpdef _floordiv_(self, right): """ - Return the quotient of self and other. Since these are field + Return the quotient of ``self`` and ``other``. Since these are field elements, the floor division is exactly the same as usual division. EXAMPLES:: @@ -4439,7 +4433,7 @@ cdef class FieldElement(CommutativeRingElement): def _lcm(self, FieldElement other): """ - Return the least common multiple of ``self`` and other. + Return the least common multiple of ``self`` and ``other``. """ if self.is_zero() and other.is_zero(): return self @@ -4470,10 +4464,10 @@ cdef class FieldElement(CommutativeRingElement): def divides(self, FieldElement other): r""" - Check whether ``self`` divides other, for field elements. + Check whether ``self`` divides ``other``, for field elements. Since this is a field, all values divide all other values, - except that zero does not divide any non-zero values. + except that zero does not divide any nonzero values. EXAMPLES:: @@ -4583,7 +4577,7 @@ cpdef canonical_coercion(x, y): [1 0], [0 1] ) """ - return coercion_model.canonical_coercion(x,y) + return coercion_model.canonical_coercion(x, y) cpdef bin_op(x, y, op): diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 61a544e1352..ab3fa717031 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -6,7 +6,7 @@ general lists of objects with integer multiplicities. These may hold the results of an arithmetic or algebraic factorization, where the objects may be primes or irreducible polynomials and the -multiplicities are the (non-zero) exponents in the factorization. For +multiplicities are the (nonzero) exponents in the factorization. For other types of examples, see below. :class:`Factorization` class objects contain a ``list``, so can be @@ -227,25 +227,23 @@ def __init__(self, x, unit=None, cr=False, sort=True, simplify=True): INPUT: - - ``x`` -- a list of pairs (p, e) with e an integer; - otherwise a :class:`TypeError` is raised + - ``x`` -- list of pairs (p, e) with e an integer + otherwise a :exc:`TypeError` is raised - - ``unit`` -- (default: 1); the unit part of the factorization. + - ``unit`` -- (default: 1) the unit part of the factorization - - ``cr`` -- (default: ``False``); if ``True``, print the factorization - with carriage returns between factors. + - ``cr`` -- (default: ``False``) if ``True``, print the factorization + with carriage returns between factors - - ``sort`` -- (default: ``True``); if ``True``, sort the factors by + - ``sort`` -- (default: ``True``) if ``True``, sort the factors by calling the sort function ``self.sort()`` after creating the factorization - - ``simplify`` -- (default: ``True``); if ``True``, remove duplicate + - ``simplify`` -- (default: ``True``) if ``True``, remove duplicate factors from the factorization. See the documentation for self.simplify. - OUTPUT: - - a Factorization object + OUTPUT: a Factorization object EXAMPLES: @@ -328,7 +326,7 @@ def __init__(self, x, unit=None, cr=False, sort=True, simplify=True): def __getitem__(self, i): """ - Return `i^{th}` factor of ``self``. + Return `i`-th factor of ``self``. EXAMPLES:: @@ -349,7 +347,7 @@ def __getitem__(self, i): def __setitem__(self, i, v): """ - Set the `i^{th}` factor of ``self``. + Set the `i`-th factor of ``self``. .. warning:: @@ -520,7 +518,7 @@ def universe(self): r""" Return the parent structure of my factors. - .. note:: + .. NOTE:: This used to be called ``base_ring``, but the universe of a factorization need not be a ring. @@ -558,7 +556,7 @@ def base_change(self, U): sage: F.base_change(P).universe() Univariate Polynomial Ring in x over Integer Ring - This method will return a :class:`TypeError` if the coercion is not + This method will return a :exc:`TypeError` if the coercion is not possible:: sage: g = x^2 - 1 @@ -664,11 +662,9 @@ def sort(self, key=None): INPUT: - - ``key`` -- (default: ``None``); comparison key - - OUTPUT: + - ``key`` -- (default: ``None``) comparison key - - changes this factorization to be sorted (inplace) + OUTPUT: changes this factorization to be sorted (inplace) If ``key`` is ``None``, we determine the comparison key as follows: @@ -921,7 +917,6 @@ def __pari__(self): sage: g = factor(x^10 - 1) # needs sage.libs.pari sage: pari(g) # needs sage.libs.pari [x - 1, 1; x + 1, 1; x^4 - x^3 + x^2 - x + 1, 1; x^4 + x^3 + x^2 + x + 1, 1] - """ from sage.libs.pari.all import pari from itertools import chain @@ -1042,7 +1037,7 @@ def __mul__(self, other): If the two factorizations have different universes, this method will attempt to find a common universe for the - product. A :class:`TypeError` is raised if this is impossible. + product. A :exc:`TypeError` is raised if this is impossible. EXAMPLES:: @@ -1102,7 +1097,7 @@ def __mul__(self, other): def __pow__(self, n): """ - Return the `n^{th}` power of a factorization, which is got by + Return the `n`-th power of a factorization, which is got by combining together like factors. EXAMPLES:: @@ -1206,7 +1201,7 @@ def __call__(self, *args, **kwds): sage: R. = FreeAlgebra(QQ, 2) sage: F = Factorization([(x,3), (y, 2), (x,1)]) sage: F(x=4) - (1) * 4^3 * y^2 * 4 + 4^3 * y^2 * 4 sage: F.subs({y:2}) x^3 * 2^2 * x @@ -1279,7 +1274,7 @@ def gcd(self, other): If the two factorizations have different universes, this method will attempt to find a common universe for the - gcd. A :class:`TypeError` is raised if this is impossible. + gcd. A :exc:`TypeError` is raised if this is impossible. EXAMPLES:: @@ -1321,7 +1316,7 @@ def lcm(self, other): If the two factorizations have different universes, this method will attempt to find a common universe for the - lcm. A :class:`TypeError` is raised if this is impossible. + lcm. A :exc:`TypeError` is raised if this is impossible. EXAMPLES:: @@ -1359,7 +1354,7 @@ def lcm(self, other): def is_integral(self) -> bool: r""" - Return whether all exponents of this Factorization are non-negative. + Return whether all exponents of this Factorization are nonnegative. EXAMPLES:: @@ -1380,7 +1375,7 @@ def radical(self): Return the factorization of the radical of the value of ``self``. First, check that all exponents in the factorization are - positive, raise :class:`ValueError` otherwise. If all exponents are + positive, raise :exc:`ValueError` otherwise. If all exponents are positive, return ``self`` with all exponents set to 1 and with the unit set to 1. @@ -1405,7 +1400,7 @@ def radical_value(self): Return the product of the prime factors in ``self``. First, check that all exponents in the factorization are - positive, raise :class:`ValueError` otherwise. If all exponents are + positive, raise :exc:`ValueError` otherwise. If all exponents are positive, return the product of the prime factors in ``self``. This should be functionally equivalent to ``self.radical().value()``. diff --git a/src/sage/structure/factory.pyx b/src/sage/structure/factory.pyx index ab8b5afa4a1..bde82e5d18f 100644 --- a/src/sage/structure/factory.pyx +++ b/src/sage/structure/factory.pyx @@ -171,15 +171,15 @@ cdef class UniqueFactory(SageObject): ....: return args, {'impl':kwds.get('impl', None)} ....: def create_object(self, version, key, **extra_args): ....: impl = extra_args['impl'] - ....: if impl=='C': + ....: if impl == 'C': ....: return C(*key) - ....: if impl=='D': + ....: if impl == 'D': ....: return D(*key) ....: return E(*key) ....: Now we can create a factory instance. It is supposed to be found under the - name ``"F"`` in the ``"__main__"`` module. Note that in an interactive + name ``'F'`` in the ``__main__`` module. Note that in an interactive session, ``F`` would automatically be in the ``__main__`` module. Hence, the second and third of the following four lines are only needed in doctests. :: @@ -237,7 +237,7 @@ cdef class UniqueFactory(SageObject): only considered an "extra argument" that does not count for the key. :: - sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # needs sage.misc.cython + sage: c is F(1, impl='C') is F(1, impl='D') is F(1) # needs sage.misc.cython True However, pickling and unpickling does not use the cache. This is because @@ -292,9 +292,9 @@ cdef class UniqueFactory(SageObject): """ INPUT: - - ``name`` -- string. A name in the global namespace referring - to self or a fully qualified path name to self, which is - used to locate the factory on unpickling. + - ``name`` -- string; a name in the global namespace referring to + ``self`` or a fully qualified path name to ``self``, which is used to + locate the factory on unpickling EXAMPLES:: @@ -374,7 +374,7 @@ cdef class UniqueFactory(SageObject): cpdef get_object(self, version, key, extra_args): """ - Returns the object corresponding to ``key``, creating it with + Return the object corresponding to ``key``, creating it with ``extra_args`` if necessary (for example, it isn't in the cache or it is unpickling from an older version of Sage). @@ -403,7 +403,6 @@ cdef class UniqueFactory(SageObject): Making object (1 + O(2^20), 'c') sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # needs sage.rings.padics True - """ cache_key = key try: @@ -715,7 +714,6 @@ def generic_factory_unpickle(factory, *args): False sage: loads(dumps(b)) is b True - """ cdef UniqueFactory F if factory is not None: diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index f037f71042e..ab72ff5eb2d 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -17,9 +17,9 @@ FUNCTIONS: - ``FormalSums(ring)`` -- create the module of formal finite sums with - coefficients in the given ring. + coefficients in the given ring -- ``FormalSum(list of pairs (coeff, number))`` -- create a formal sum. +- ``FormalSum(list of pairs (coeff, number))`` -- create a formal sum EXAMPLES:: @@ -90,10 +90,9 @@ def __init__(self, x, parent=None, check=True, reduce=True): - ``x`` -- object - ``parent`` -- FormalSums(R) module (default: FormalSums(ZZ)) - - ``check`` -- bool (default: ``True``) if ``False``, might not coerce - coefficients into base ring, which can speed - up constructing a formal sum. - - ``reduce`` -- reduce (default: ``True``) if ``False``, do not + - ``check`` -- boolean (default: ``True``); if ``False``, might not coerce + coefficients into base ring, which can speed up constructing a formal sum + - ``reduce`` -- boolean (default: ``True``); if ``False``, do not combine common terms .. WARNING:: @@ -342,7 +341,6 @@ class FormalSums(UniqueRepresentation, Module): TESTS:: sage: TestSuite(FormalSums(QQ)).run() - """ Element = FormalSum @@ -371,15 +369,15 @@ def _repr_(self): def _element_constructor_(self, x, check=True, reduce=True): """ - Make a formal sum in self from x. + Make a formal sum in ``self`` from x. INPUT: - ``x`` -- formal sum, list or number - - ``check`` -- bool (default: ``True``) + - ``check`` -- boolean (default: ``True``) - - ``reduce`` -- bool (default: ``True``); whether to combine terms + - ``reduce`` -- boolean (default: ``True``); whether to combine terms EXAMPLES:: @@ -402,7 +400,7 @@ def _element_constructor_(self, x, check=True, reduce=True): def _coerce_map_from_(self, X): r""" - Return whether there is a coercion from ``X`` + Return whether there is a coercion from ``X``. EXAMPLES:: diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index 437554b4130..0f3308cc80f 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -49,13 +49,13 @@ The options constructed by :class:`GlobalOptions` have to be explicitly associated to the class that they control using the following arguments: -- ``NAME`` -- A descriptive name for the options class. This is - optional; the default is the name of the constructed class. +- ``NAME`` -- a descriptive name for the options class; this is + optional. The default is the name of the constructed class. -- ``module`` -- The sage module containing the options class (optional) +- ``module`` -- the sage module containing the options class (optional) -- ``option_class`` -- The name of the options class. This is optional and - defaults to ``NAME`` if not explicitly set. +- ``option_class`` -- the name of the options class; this is optional and + defaults to ``NAME`` if not explicitly set It is only possible to pickle a :class:`GlobalOptions` class if the corresponding module is specified *and* if the options are explicitly @@ -65,31 +65,31 @@ values for the option and its documentation. The possible entries in this dictionary are: -- ``alias`` -- Allows for several option values to do the same thing. +- ``alias`` -- allows for several option values to do the same thing -- ``alt_name`` -- An alternative name for this option. +- ``alt_name`` -- an alternative name for this option -- ``checker`` -- A validation function which returns whether a user +- ``checker`` -- a validation function which returns whether a user supplied value is valid or not. This is typically useful for large lists of legal values such as :class:`~sage.rings.semirings.non_negative_integer_semiring.NN`. -- ``default`` -- Gives the default value for the option. +- ``default`` -- gives the default value for the option -- ``description`` -- A one line description of the option. +- ``description`` -- a one line description of the option -- ``link_to`` -- Links this option to another one in another set of +- ``link_to`` -- links this option to another one in another set of global options. This is used for example to allow :class:`Partitions` and :class:`Tableaux` to share the same ``convention`` option. -- ``setter`` -- A function which is called **after** the value of the - option is changed. +- ``setter`` -- a function which is called **after** the value of the + option is changed -- ``values`` -- A dictionary assigning each valid value for the option - to a short description of what it does. +- ``values`` -- dictionary assigning each valid value for the option + to a short description of what it does -- ``case_sensitive`` -- (Default: ``True``) ``True`` or ``False`` depending on - whether the values of the option are case sensitive. +- ``case_sensitive`` -- boolean (default: ``True``); depending on + whether the values of the option are case sensitive For each option, either a complete list of possible values, via ``values``, or a validation function, via ``checker``, must be given. The values can be quite @@ -429,9 +429,9 @@ class options(GlobalOptions): Check that the ``name`` and ``NAME`` keywords are both supported with this syntax:: - sage: GlobalOptions(name="menu") + sage: GlobalOptions(name='menu') Current options for menu - sage: GlobalOptions(NAME="menu") + sage: GlobalOptions(NAME='menu') Current options for menu sage: GlobalOptions() Traceback (most recent call last): @@ -514,7 +514,7 @@ class options(GlobalOptions): from sage.misc.instancedoc import instancedoc -class Option(): +class Option: r""" An option. @@ -827,7 +827,7 @@ def __call__(self, name, bases, dict): class GlobalOptionsMeta(type, metaclass=GlobalOptionsMetaMeta): """ - Metaclass for :class:`GlobalOptions` + Metaclass for :class:`GlobalOptions`. This class is itself an instance of :class:`GlobalOptionsMetaMeta`, which implements the subclass magic. @@ -871,12 +871,12 @@ class GlobalOptions(metaclass=GlobalOptionsMeta): option in another :class:`GlobalOptions` - ``setter`` -- a function (class method) which is called whenever this option changes - - ``values`` -- a dictionary of the legal values for this option (this + - ``values`` -- dictionary of the legal values for this option (this automatically defines the corresponding ``checker``); this dictionary gives the possible options, as keys, together with a brief description of them - - ``case_sensitive`` -- (default: ``True``) ``True`` or ``False`` - depending on whether the values of the option are case sensitive + - ``case_sensitive`` -- boolean (default: ``True``); depending on whether + the values of the option are case sensitive Options and their values can be abbreviated provided that this abbreviation is a prefix of a unique option. @@ -1026,12 +1026,12 @@ def __init__(self, NAME=None, module='', option_class='', doc='', end_doc='', ** sage: class alias_test(GlobalOptions): ....: "Test aliases with case sensitivity" - ....: test_opt = dict(default="Upper", + ....: test_opt = dict(default='Upper', ....: description = 'Starts with an uppercase', ....: values = dict(Upper="Starts with uppercase", ....: lower="only lowercase"), ....: case_sensitive = False, - ....: alias = dict(UpperAlias="Upper", lower_alias="lower")) + ....: alias = dict(UpperAlias='Upper', lower_alias='lower')) sage: alias_test['test_opt'] = 'Lower_Alias' sage: alias_test['test_opt'] 'lower' @@ -1129,13 +1129,13 @@ def __call__(self, *get_value, **set_value): - food: apple sage: FoodOptions('food') 'apple' - sage: FoodOptions(food="pair"); FoodOptions() + sage: FoodOptions(food='pair'); FoodOptions() Current options for daily meal - drink: water - food: pair sage: FoodOptions('beverage') 'water' - sage: FoodOptions(food="apple", drink="coffee"); FoodOptions() + sage: FoodOptions(food='apple', drink='coffee'); FoodOptions() Current options for daily meal - drink: coffee - food: apple @@ -1237,7 +1237,7 @@ def _instancedoc_(self): sage: print(Partitions.options.__doc__) # needs sage.combinat - Sets and displays the global options for elements of the partition, + Set and display the global options for elements of the partition, skew partition, and partition tuple classes. If no parameters are set, then the function returns a copy of the options dictionary. @@ -1267,7 +1267,7 @@ def _instancedoc_(self): def __setattr__(self, name, value=None): r""" - Set the attribute ``name`` of the option class self equal to + Set the attribute ``name`` of the option class ``self`` equal to ``value``, if the attribute ``name`` exists. As the attributes of an option class are the actual options we need @@ -1330,7 +1330,7 @@ def __setstate__(self, state): for setting in unpickle.__dict__: self.__dict__[setting] = unpickle.__dict__[setting] - # reset the options in `self` to their defaults + # reset the options in ``self`` to their defaults self._reset() # apply the options stored in state for opt in state: @@ -1402,8 +1402,8 @@ def _add_option(self, option, specifications): INPUT: - - ``option`` -- a string - - ``specifications`` -- a dictionary + - ``option`` -- string + - ``specifications`` -- dictionary .. SEEALSO:: @@ -1519,7 +1519,7 @@ def _match_option(self, option): INPUT: - - ``option`` -- a string + - ``option`` -- string EXAMPLES:: @@ -1562,8 +1562,8 @@ def _match_value(self, option, value): INPUT: - - ``option`` -- a string: the name of an option, or prefix thereof - - ``value`` -- a value or ``'?'`` + - ``option`` -- string: the name of an option, or prefix thereof + - ``value`` -- a value or ``'?'`` EXAMPLES:: @@ -1642,8 +1642,6 @@ def _default_value(self, option): def _dispatch(self, obj, dispatch_to, option, *args, **kargs): r""" - .. TODO:: title - The *dispatchable* options are options which dispatch related methods of the corresponding class - or user defined methods which are passed to :class:`GlobalOptions`. The format for specifying a dispatchable option @@ -1701,7 +1699,7 @@ def _reset(self, option=None): INPUT: - - ``option`` -- (Default: ``None``) The name of an option as a string + - ``option`` -- (default: ``None``) the name of an option as a string or ``None``. If ``option`` is specified only this option is reset to its default value; otherwise all options are reset. diff --git a/src/sage/structure/indexed_generators.py b/src/sage/structure/indexed_generators.py index 16349837cd0..7586eb06aaf 100644 --- a/src/sage/structure/indexed_generators.py +++ b/src/sage/structure/indexed_generators.py @@ -14,7 +14,7 @@ from sage.structure.category_object import normalize_names -class IndexedGenerators(): +class IndexedGenerators: r"""nodetex Abstract base class for parents whose elements consist of generators indexed by an arbitrary set. @@ -22,11 +22,11 @@ class IndexedGenerators(): Options controlling the printing of elements: - ``prefix`` -- string, prefix used for printing elements of this - module (default: 'x'). With the default, a monomial + module (default: ``'x'``). With the default, a monomial indexed by 'a' would be printed as ``x['a']``. - ``latex_prefix`` -- string or ``None``, prefix used in the `\LaTeX` - representation of elements (default: ``None``). If this is + representation of elements (default: ``None``); if this is anything except the empty string, it prints the index as a subscript. If this is ``None``, it uses the setting for ``prefix``, so if ``prefix`` is set to "B", then a monomial indexed by 'a' @@ -35,16 +35,16 @@ class IndexedGenerators(): would be printed as ``a``, or as ``[a]`` if ``latex_bracket`` is ``True``. - - ``names`` -- dict with strings as values or list of strings (optional): + - ``names`` -- dictionary with strings as values or list of strings (optional); a mapping from the indices of the generators to strings giving the generators explicit names. This is used instead of the print options ``prefix`` and ``bracket`` when ``names`` is specified. - - ``latex_names`` -- dict with strings as values or list of strings - (optional): same as ``names`` except using the `\LaTeX` representation + - ``latex_names`` -- dictionary with strings as values or list of strings + (optional); same as ``names`` except using the `\LaTeX` representation - - ``bracket`` -- ``None``, bool, string, or list or tuple of - strings (default: ``None``): if ``None``, use the value of the + - ``bracket`` -- ``None``, boolean, string, or list or tuple of + strings (default: ``None``); if ``None``, use the value of the attribute ``self._repr_option_bracket``, which has default value ``True``. (``self._repr_option_bracket`` is available for backwards compatibility. Users should set ``bracket`` instead. If @@ -52,15 +52,15 @@ class IndexedGenerators(): the value of ``self._repr_option_bracket``.) If ``False``, do not include brackets when printing elements: a monomial indexed by 'a' would be printed as ``B'a'``, and a monomial indexed by - (1,2,3) would be printed as ``B(1,2,3)``. If True, use "[" and + (1,2,3) would be printed as ``B(1,2,3)``. If ``True``, use "[" and "]" as brackets. If it is one of "[", "(", or "{", use it and its partner as brackets. If it is any other string, use it as both brackets. If it is a list or tuple of strings, use the first entry as the left bracket and the second entry as the right bracket. - - ``latex_bracket`` -- bool, string, or list or tuple of strings - (default: ``False``): if ``False``, do not include brackets in + - ``latex_bracket`` -- boolean, string, or list or tuple of strings + (default: ``False``); if ``False``, do not include brackets in the LaTeX representation of elements. This option is only relevant if ``latex_prefix`` is the empty string; otherwise, brackets are not used regardless. If ``True``, use "\left[" and @@ -72,28 +72,28 @@ class IndexedGenerators(): right bracket. - ``scalar_mult`` -- string to use for scalar multiplication in - the print representation (default: "*") + the print representation (default: ``'*'``) - - ``latex_scalar_mult`` -- string or ``None`` (default: ``None``), + - ``latex_scalar_mult`` -- string or ``None`` (default: ``None``); string to use for scalar multiplication in the latex - representation. If None, use the empty string if ``scalar_mult`` + representation. If ``None``, use the empty string if ``scalar_mult`` is set to "*", otherwise use the value of ``scalar_mult``. - - ``tensor_symbol`` -- string or ``None`` (default: ``None``), + - ``tensor_symbol`` -- string or ``None`` (default: ``None``); string to use for tensor product in the print representation. If ``None``, use ``sage.categories.tensor.symbol`` and ``sage.categories.tensor.unicode_symbol``. - - ``sorting_key`` -- a key function (default: ``lambda x: x``), + - ``sorting_key`` -- a key function (default: ``lambda x: x``); to use for sorting elements in the output of elements - - ``sorting_reverse`` -- bool (default: ``False``), if ``True`` + - ``sorting_reverse`` -- boolean (default: ``False``); if ``True`` sort elements in reverse order in the output of elements - - ``string_quotes`` -- bool (default: ``True``), if ``True`` then + - ``string_quotes`` -- boolean (default: ``True``); if ``True`` then display string indices with quotes - - ``iterate_key`` -- bool (default: ``False``) iterate through + - ``iterate_key`` -- boolean (default: ``False``); iterate through the elements of the key and print the result as comma separated objects for string output @@ -119,7 +119,7 @@ class IndexedGenerators(): sage: I._latex_generator(2) 'x_{2}' - sage: I = IndexedGenerators(ZZ, prefix="", latex_bracket='(') + sage: I = IndexedGenerators(ZZ, prefix='', latex_bracket='(') sage: I._repr_generator(2) '[2]' sage: I._latex_generator(2) @@ -129,7 +129,7 @@ class IndexedGenerators(): sage: I._repr_generator(2) 'x|2>' """ - def __init__(self, indices, prefix="x", **kwds): + def __init__(self, indices, prefix='x', **kwds): """ Initialize ``self``. @@ -182,7 +182,7 @@ def indices(self): def prefix(self): """ - Return the prefix used when displaying elements of self. + Return the prefix used when displaying elements of ``self``. EXAMPLES:: @@ -202,7 +202,9 @@ def print_options(self, **kwds): """ Return the current print options, or set an option. - INPUT: all of the input is optional; if present, it should be + INPUT: + + All of the input is optional; if present, it should be in the form of keyword pairs, such as ``latex_bracket='('``. The allowable keywords are: @@ -358,7 +360,7 @@ def _repr_generator(self, m): B['a'] + 2*B['b'] sage: # needs sage.modules - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix='F') sage: e = F.basis() sage: e['a'] + 2*e['b'] # indirect doctest F['a'] + 2*F['b'] @@ -367,7 +369,7 @@ def _repr_generator(self, m): F[a] + 2*F[b] sage: # needs sage.modules - sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") + sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix='F') sage: e = F.basis() sage: F.print_options(iterate_key=True) sage: e['aa'] + 2*e['bb'] @@ -472,7 +474,7 @@ def _ascii_art_generator(self, m): ** ** * - sage: Partitions.options(diagram_str="#", convention="french") + sage: Partitions.options(diagram_str='#', convention='french') sage: ascii_art(R[1,2,2,4]) R # @@ -564,14 +566,14 @@ def _latex_generator(self, m): sage: latex(e['a'] + 2*e['b']) # indirect doctest # needs sage.modules B_{a} + 2 B_{b} - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") # needs sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix='C') # needs sage.modules sage: e = F.basis() # needs sage.modules sage: latex(e['a'] + 2*e['b']) # indirect doctest # needs sage.modules C_{a} + 2 C_{b} sage: # needs sage.combinat sage.modules sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), - ....: prefix="", scalar_mult="*") + ....: prefix='', scalar_mult='*') sage: original_print_options = QS3.print_options() sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) sage: latex(a) # indirect doctest @@ -648,6 +650,7 @@ def _latex_generator(self, m): return left + s + right return "%s_{%s}" % (prefix, s) + def split_index_keywords(kwds): """ Split the dictionary ``kwds`` into two dictionaries, one containing diff --git a/src/sage/structure/list_clone.pyx b/src/sage/structure/list_clone.pyx index 5a217166bcd..03c0cd23530 100644 --- a/src/sage/structure/list_clone.pyx +++ b/src/sage/structure/list_clone.pyx @@ -157,7 +157,7 @@ from sage.structure.richcmp cimport richcmp, rich_to_bool ############################################################################ cdef class ClonableElement(Element): r""" - Abstract class for elements with clone protocol + Abstract class for elements with clone protocol. This class is a subclass of :class:`Element` and implements the "prototype" design pattern (see [Prototype_pattern]_, [GHJV1994]_). The role @@ -179,7 +179,7 @@ cdef class ClonableElement(Element): Additionally, one can also implement - - ``obj._hash_()`` -- return the hash value of ``obj``. + - ``obj._hash_()`` -- return the hash value of ``obj`` Then, given an instance ``obj`` of ``C``, the following sequences of instructions ensures that the invariants of ``new_obj`` are properly @@ -295,7 +295,7 @@ cdef class ClonableElement(Element): """ Check that ``self`` is mutable. - Raise a ``ValueError`` if ``self`` is immutable. + Raise a :exc:`ValueError` if ``self`` is immutable. TESTS:: @@ -422,8 +422,8 @@ cdef class ClonableElement(Element): INPUT: - - ``check`` -- a boolean indicating if ``self.check()`` must be called - after modifications. + - ``check`` -- boolean indicating if ``self.check()`` must be called + after modifications EXAMPLES:: @@ -441,7 +441,7 @@ cdef class ClonableElement(Element): def __enter__(self): """ - Implement the self guarding clone protocol. + Implement the ``self`` guarding clone protocol. TESTS:: @@ -455,7 +455,7 @@ cdef class ClonableElement(Element): def __exit__(self, typ, value, tracback): """ - Implement the self guarding clone protocol. + Implement the ``self`` guarding clone protocol. .. NOTE:: The input argument are required by the ``with`` protocol but are ignored. @@ -489,7 +489,7 @@ cdef class ClonableElement(Element): ############################################################################ cdef class ClonableArray(ClonableElement): """ - Array with clone protocol + Array with clone protocol. The class of objects which are :class:`Element` behave as arrays @@ -499,11 +499,11 @@ cdef class ClonableArray(ClonableElement): INPUT: - ``parent`` -- a :class:`Parent` - - ``lst`` -- a list - - ``check`` -- a boolean specifying if the invariant must be checked - using method :meth:`check`. - - ``immutable`` -- a boolean telling whether the created element is - immutable (defaults to ``True``) + - ``lst`` -- list + - ``check`` -- boolean specifying if the invariant must be checked + using method :meth:`check` + - ``immutable`` -- boolean (default: ``True``); whether the created element + is immutable .. SEEALSO:: :class:`~sage.structure.list_clone_demo.IncreasingArray` for an example of usage. @@ -526,7 +526,7 @@ cdef class ClonableArray(ClonableElement): """ def __init__(self, Parent parent, lst, check=True, immutable=True): """ - Initialize ``self`` + Initialize ``self``. TESTS:: @@ -567,7 +567,7 @@ cdef class ClonableArray(ClonableElement): def __bool__(self): """ - Tests if self is not empty. + Test if ``self`` is not empty. EXAMPLES:: @@ -614,7 +614,7 @@ cdef class ClonableArray(ClonableElement): def __len__(self): """ - Return the len of ``self`` + Return the ``len`` of ``self``. EXAMPLES:: @@ -626,7 +626,7 @@ cdef class ClonableArray(ClonableElement): def __getitem__(self, key): """ - Return the ``key``-th element of ``self`` + Return the ``key``-th element of ``self``. It also works with slice returning a python list in this case. @@ -654,7 +654,7 @@ cdef class ClonableArray(ClonableElement): def __setitem__(self, int key, value): """ - Set the ``i``-th element of ``self`` + Set the ``i``-th element of ``self``. An exception is raised if ``self`` is immutable. @@ -679,7 +679,7 @@ cdef class ClonableArray(ClonableElement): cpdef object _getitem(self, int key): """ - Same as :meth:`__getitem__` + Same as :meth:`__getitem__`. This is much faster when used with Cython and ``key`` is known to be an ``int``. @@ -698,7 +698,7 @@ cdef class ClonableArray(ClonableElement): cpdef _setitem(self, int key, value): """ - Same as :meth:`__setitem__` + Same as :meth:`__setitem__`. This is much faster when used with Cython and ``key`` is known to be an ``int``. @@ -848,7 +848,7 @@ cdef class ClonableArray(ClonableElement): cpdef ClonableArray __copy__(self): """ - Return a copy of ``self`` + Return a copy of ``self``. TESTS:: @@ -892,7 +892,7 @@ cdef class ClonableArray(ClonableElement): cpdef check(self): """ - Check that ``self`` fulfill the invariants + Check that ``self`` fulfill the invariants. This is an abstract method. Subclasses are supposed to overload ``check``. @@ -997,7 +997,7 @@ def _make_array_clone(clas, parent, list, needs_check, is_immutable, dic): ############################################################################ cdef class ClonableList(ClonableArray): """ - List with clone protocol + List with clone protocol. The class of objects which are :class:`Element` behave as lists and @@ -1009,9 +1009,11 @@ cdef class ClonableList(ClonableArray): """ cpdef append(self, el): """ - Appends ``el`` to ``self`` + Appends ``el`` to ``self``. + + INPUT: - INPUT: ``el`` -- any object + - ``el`` -- any object EXAMPLES:: @@ -1038,9 +1040,11 @@ cdef class ClonableList(ClonableArray): cpdef extend(self, it): """ - Extends ``self`` by the content of the iterable ``it`` + Extend ``self`` by the content of the iterable ``it``. - INPUT: ``it`` -- any iterable + INPUT: + + - ``it`` -- any iterable EXAMPLES:: @@ -1073,12 +1077,12 @@ cdef class ClonableList(ClonableArray): cpdef insert(self, int index, el): """ - Inserts ``el`` in ``self`` at position ``index`` + Inserts ``el`` in ``self`` at position ``index``. INPUT: - - ``el`` -- any object - - ``index`` -- any int + - ``el`` -- any object + - ``index`` -- any int EXAMPLES:: @@ -1103,9 +1107,11 @@ cdef class ClonableList(ClonableArray): cpdef pop(self, int index=-1): """ - Remove ``self[index]`` from ``self`` and returns it + Remove ``self[index]`` from ``self`` and returns it. - INPUT: ``index`` -- any int, default to -1 + INPUT: + + - ``index`` -- integer (default: -1) EXAMPLES:: @@ -1131,9 +1137,11 @@ cdef class ClonableList(ClonableArray): cpdef remove(self, el): """ - Remove the first occurrence of ``el`` from ``self`` + Remove the first occurrence of ``el`` from ``self``. + + INPUT: - INPUT: ``el`` -- any object + - ``el`` -- any object EXAMPLES:: @@ -1158,7 +1166,7 @@ cdef class ClonableList(ClonableArray): def __setitem__(self, key, value): """ - Set the ith element of ``self`` + Set the i-th element of ``self``. An exception is raised if ``self`` is immutable. @@ -1186,7 +1194,7 @@ cdef class ClonableList(ClonableArray): def __delitem__(self, key): """ - Remove the ith element of ``self`` + Remove the i-th element of ``self``. An exception is raised if ``self`` is immutable. @@ -1216,7 +1224,7 @@ cdef class ClonableList(ClonableArray): ############################################################################ cdef class ClonableIntArray(ClonableElement): """ - Array of int with clone protocol + Array of integers with clone protocol. The class of objects which are :class:`Element` behave as list of int and @@ -1227,11 +1235,11 @@ cdef class ClonableIntArray(ClonableElement): INPUT: - ``parent`` -- a :class:`Parent` - - ``lst`` -- a list - - ``check`` -- a boolean specifying if the invariant must be checked + - ``lst`` -- list + - ``check`` -- boolean specifying if the invariant must be checked using method :meth:`check` - - ``immutable`` -- a boolean telling whether the created element is - immutable (defaults to ``True``) + - ``immutable`` -- boolean (default: ``True``); whether the created element + is immutable .. SEEALSO:: :class:`~sage.structure.list_clone_demo.IncreasingIntArray` for an example of usage. @@ -1242,7 +1250,7 @@ cdef class ClonableIntArray(ClonableElement): def __init__(self, Parent parent, lst, check=True, immutable=True): """ - Initialize ``self`` + Initialize ``self``. TESTS:: @@ -1288,11 +1296,13 @@ cdef class ClonableIntArray(ClonableElement): cpdef _alloc_(self, int size): """ - Allocate the array part of ``self`` for a given size + Allocate the array part of ``self`` for a given size. This can be used to initialize ``self`` without passing a list - INPUT: ``size`` -- an int + INPUT: + + - ``size`` -- integer EXAMPLES:: @@ -1347,7 +1357,7 @@ cdef class ClonableIntArray(ClonableElement): def __len__(self): """ - Return the len of ``self`` + Return the len of ``self``. EXAMPLES:: @@ -1359,7 +1369,7 @@ cdef class ClonableIntArray(ClonableElement): def __iter__(self): """ - Iterate over the items of self. + Iterate over the items of ``self``. EXAMPLES:: @@ -1374,7 +1384,7 @@ cdef class ClonableIntArray(ClonableElement): cpdef list list(self): """ - Convert self into a Python list. + Convert ``self`` into a Python list. EXAMPLES:: @@ -1399,7 +1409,7 @@ cdef class ClonableIntArray(ClonableElement): def __getitem__(self, key): """ - Return the ith element of ``self`` + Return the i-th element of ``self``. EXAMPLES:: @@ -1448,7 +1458,7 @@ cdef class ClonableIntArray(ClonableElement): def __setitem__(self, int key, value): """ - Set the ith element of ``self`` + Set the i-th element of ``self``. An exception is raised if ``self`` is immutable. @@ -1472,7 +1482,7 @@ cdef class ClonableIntArray(ClonableElement): cpdef object _getitem(self, int key): """ - Same as :meth:`__getitem__` + Same as :meth:`__getitem__`. This is much faster when used with Cython and the index is known to be an int. @@ -1490,7 +1500,7 @@ cdef class ClonableIntArray(ClonableElement): cpdef _setitem(self, int key, value): """ - Same as :meth:`__setitem__` + Same as :meth:`__setitem__`. This is much faster when used with Cython and the index is known to be an int. @@ -1626,7 +1636,7 @@ cdef class ClonableIntArray(ClonableElement): cpdef ClonableIntArray __copy__(self): """ - Return a copy of ``self`` + Return a copy of ``self``. TESTS:: @@ -1673,7 +1683,7 @@ cdef class ClonableIntArray(ClonableElement): cpdef check(self): """ - Check that ``self`` fulfill the invariants + Check that ``self`` fulfill the invariants. This is an abstract method. Subclasses are supposed to overload ``check``. @@ -1777,7 +1787,7 @@ def _make_int_array_clone(clas, parent, lst, needs_check, is_immutable, dic): cdef class NormalizedClonableList(ClonableList): """ - List with clone protocol and normal form + List with clone protocol and normal form. This is a subclass of :class:`ClonableList` which call a method :meth:`normalize` at creation and after any modification of its instance. @@ -1834,7 +1844,7 @@ cdef class NormalizedClonableList(ClonableList): cpdef normalize(self): """ - Normalize ``self`` + Normalize ``self``. This is an abstract method. Subclasses are supposed to overload :meth:`normalize`. The call ``self.normalize()`` is supposed to diff --git a/src/sage/structure/list_clone_demo.pyx b/src/sage/structure/list_clone_demo.pyx index 4899bcf5cc2..dbd199fa317 100644 --- a/src/sage/structure/list_clone_demo.pyx +++ b/src/sage/structure/list_clone_demo.pyx @@ -116,7 +116,7 @@ cdef class IncreasingList(ClonableList): cpdef check(self): """ - Check that ``self`` is increasing + Check that ``self`` is increasing. EXAMPLES:: @@ -195,7 +195,7 @@ cdef class SortedList(NormalizedClonableList): """ cpdef normalize(self): """ - Normalize ``self`` + Normalize ``self``. Sort the list stored in ``self``. @@ -215,7 +215,7 @@ cdef class SortedList(NormalizedClonableList): cpdef check(self): """ - Check that ``self`` is strictly increasing + Check that ``self`` is strictly increasing. EXAMPLES:: diff --git a/src/sage/structure/list_clone_timings.py b/src/sage/structure/list_clone_timings.py index 05320d6bc77..a072b7287a5 100644 --- a/src/sage/structure/list_clone_timings.py +++ b/src/sage/structure/list_clone_timings.py @@ -88,7 +88,7 @@ class IncreasingArraysPy(IncreasingArrays): class Element(ClonableArray): """ - A small class for testing :class:`ClonableArray`: Increasing Lists + A small class for testing :class:`ClonableArray`: Increasing Lists. TESTS:: @@ -134,6 +134,7 @@ def add1_internal(bla): blo.check() return blo + def add1_immutable(bla): """ TESTS:: @@ -147,6 +148,7 @@ def add1_immutable(bla): lbla[i] += 1 return bla.__class__(bla.parent(), lbla) + def add1_mutable(bla): """ TESTS:: @@ -162,6 +164,7 @@ def add1_mutable(bla): blo.check() return blo + def add1_with(bla): """ TESTS:: diff --git a/src/sage/structure/meson.build b/src/sage/structure/meson.build new file mode 100644 index 00000000000..6f4c75d58a4 --- /dev/null +++ b/src/sage/structure/meson.build @@ -0,0 +1,73 @@ +py.install_sources( + '__init__.py', + 'all.py', + 'category_object.pxd', + 'coerce.pxd', + 'coerce_actions.pxd', + 'coerce_dict.pxd', + 'coerce_exceptions.py', + 'coerce_maps.pxd', + 'debug_options.pxd', + 'dynamic_class.py', + 'element.pxd', + 'element_wrapper.pxd', + 'factorization.py', + 'factorization_integer.py', + 'formal_sum.py', + 'gens_py.py', + 'global_options.py', + 'indexed_generators.py', + 'list_clone.pxd', + 'list_clone_timings.py', + 'mutability.pxd', + 'nonexact.py', + 'parent.pxd', + 'parent_base.pxd', + 'parent_gens.pxd', + 'parent_old.pxd', + 'richcmp.pxd', + 'sage_object.pxd', + 'sage_object_test.py', + 'sequence.py', + 'set_factories.py', + 'set_factories_example.py', + 'support_view.py', + 'test_factory.py', + 'unique_representation.py', + subdir: 'sage/structure', +) + +extension_data = { + 'category_object' : files('category_object.pyx'), + 'coerce' : files('coerce.pyx'), + 'coerce_actions' : files('coerce_actions.pyx'), + 'coerce_dict' : files('coerce_dict.pyx'), + 'coerce_maps' : files('coerce_maps.pyx'), + 'debug_options' : files('debug_options.pyx'), + 'element' : files('element.pyx'), + 'element_wrapper' : files('element_wrapper.pyx'), + 'factory' : files('factory.pyx'), + 'list_clone' : files('list_clone.pyx'), + 'list_clone_demo' : files('list_clone_demo.pyx'), + 'list_clone_timings_cy' : files('list_clone_timings_cy.pyx'), + 'mutability' : files('mutability.pyx'), + 'parent' : files('parent.pyx'), + 'parent_base' : files('parent_base.pyx'), + 'parent_gens' : files('parent_gens.pyx'), + 'parent_old' : files('parent_old.pyx'), + 'richcmp' : files('richcmp.pyx'), + 'sage_object' : files('sage_object.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/structure', + install: true, + include_directories: [inc_cpython, inc_ext, inc_rings], + dependencies: [py_dep, cysignals, gmp, gmpy2, mpc, mpfr], + ) +endforeach + +install_subdir('proof', install_dir: sage_install_dir / 'structure') diff --git a/src/sage/structure/mutability.pyx b/src/sage/structure/mutability.pyx index db6a331fa4c..69d034bd8c3 100644 --- a/src/sage/structure/mutability.pyx +++ b/src/sage/structure/mutability.pyx @@ -45,7 +45,6 @@ cdef class Mutability: ValueError: object is immutable; please change a copy instead sage: hash(a) 6 - """ def __init__(self, is_immutable=False): @@ -62,8 +61,7 @@ cdef class Mutability: ....: self._require_immutable() ....: return hash(self._val) sage: a = A(4) - sage: TestSuite(a).run(skip ="_test_pickling") - + sage: TestSuite(a).run(skip ='_test_pickling') """ self._is_immutable = is_immutable @@ -88,7 +86,6 @@ cdef class Mutability: Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead - """ if self._is_immutable: raise ValueError("object is immutable; please change a copy instead") @@ -113,7 +110,6 @@ cdef class Mutability: Traceback (most recent call last): ... ValueError: object is mutable; please make it immutable first - """ if not self._is_immutable: raise ValueError("object is mutable; please make it immutable first") @@ -204,7 +200,6 @@ cdef class Mutability: , ), {'_is_immutable': False, '_val': 4}) - """ state = getattr(self, '__dict__', {}) state['_is_immutable'] = self._is_immutable @@ -237,7 +232,6 @@ cdef class Mutability: True sage: a.__getstate__() {'_is_immutable': True, '_val': 4} - """ if hasattr(self, '__dict__'): self.__dict__ = state diff --git a/src/sage/structure/nonexact.py b/src/sage/structure/nonexact.py index cef7a641f26..8bde0763a9e 100644 --- a/src/sage/structure/nonexact.py +++ b/src/sage/structure/nonexact.py @@ -37,12 +37,12 @@ class Nonexact: INPUT: - - ``prec`` -- a non-negative integer representing the default precision of - ``self`` (default: ``20``) + - ``prec`` -- nonnegative integer representing the default precision of + ``self`` (default: 20) """ def __init__(self, prec=20): if prec < 0: - raise ValueError(f"prec (= {prec}) must be non-negative") + raise ValueError(f"prec (= {prec}) must be nonnegative") self._default_prec = Integer(prec) def default_prec(self): diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index dd57aa02787..8e8940b5846 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -222,25 +222,22 @@ cdef class Parent(sage.structure.category_object.CategoryObject): INPUT: - - ``base`` -- An algebraic structure considered to be the - "base" of this parent (e.g. the base field for a vector - space). - - - ``category`` -- a category or list/tuple of categories. The - category in which this parent lies (or list or tuple - thereof). Since categories support more general - super-categories, this should be the most specific category - possible. If category is a list or tuple, a JoinCategory is - created out of them. If category is not specified, the - category will be guessed (see - :class:`~sage.structure.category_object.CategoryObject`), - but will not be used to inherit parent's or element's code from - this category. - - - ``names`` -- Names of generators. - - - ``normalize`` -- Whether to standardize the names (remove - punctuation, etc) + - ``base`` -- an algebraic structure considered to be the "base" of + this parent (e.g. the base field for a vector space) + + - ``category`` -- a category or list/tuple of categories. The category + in which this parent lies (or list or tuple thereof). Since + categories support more general super-categories, this should be the + most specific category possible. If category is a list or tuple, a + ``JoinCategory`` is created out of them. If category is not + specified, the category will be guessed (see + :class:`~sage.structure.category_object.CategoryObject`), but will + not be used to inherit parent's or element's code from this category. + + - ``names`` -- names of generators + + - ``normalize`` -- whether to standardize the names (remove + punctuation, etc.) - ``facade`` -- a parent, or tuple thereof, or ``True`` @@ -411,7 +408,6 @@ cdef class Parent(sage.structure.category_object.CategoryObject): True sage: hash(a) != h_a True - """ cdef Py_hash_t hash_old = -1 if debug.refine_category_hash_check: @@ -506,7 +502,6 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: P._init_category_(Rings()) sage: type(P) == C True - """ self._category = None if can_assign_class(self): @@ -541,7 +536,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): @lazy_attribute def element_class(self): """ - The (default) class for the elements of this parent + The (default) class for the elements of this parent. FIXME's and design issues: @@ -565,7 +560,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): It used to be the case that this did not work for extension types, which used to never support a ``__dict__`` for instances. So for backwards compatibility, we only use dynamic classes by - default if the class has a non-zero ``__dictoffset__``. But it + default if the class has a nonzero ``__dictoffset__``. But it works regardless: just pass ``inherit=True`` to ``__make_element_class__``. See also :issue:`24715`. @@ -812,8 +807,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): INPUT: - - ``key`` -- string. A key for different metadata informations - that can be inquired about. + - ``key`` -- string; a key for different metadata informations + that can be inquired about Valid ``key`` arguments are: @@ -828,9 +823,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): is, parenthesis are not required when *printing* out any of `x - y`, `x + y`, `x^y` and `x/y`. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -979,7 +972,6 @@ cdef class Parent(sage.structure.category_object.CategoryObject): [0 2] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - """ # generic multiplication method. It defers to # _mul_, which may be defined via categories. @@ -1067,12 +1059,13 @@ cdef class Parent(sage.structure.category_object.CategoryObject): ############################################################################# def __contains__(self, x): r""" - True if there is an element of self that is equal to x under - ==, or if x is already an element of self. Also, True in other - cases involving the Symbolic Ring, which is handled specially. + ``True`` if there is an element of ``self`` that is equal to ``x`` + under ``==``, or if ``x`` is already an element of ``self``. Also, + ``True`` in other cases involving the Symbolic Ring, which is handled + specially. For many structures we test this by using :meth:`__call__` and - then testing equality between x and the result. + then testing equality between ``x`` and the result. The Symbolic Ring is treated differently because it is ultra-permissive about letting other rings coerce in, but @@ -1197,8 +1190,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef coerce(self, x): """ - Return x as an element of self, if and only if there is a canonical - coercion from the parent of x to self. + Return x as an element of ``self``, if and only if there is a + canonical coercion from the parent of x to ``self``. EXAMPLES:: @@ -1245,8 +1238,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): # Should be moved and merged into the EnumeratedSets() category (#12955) def __getitem__(self, n): """ - Returns the `n^{th}` item or slice `n` of self, - by getting self as a list. + Return the `n`-th item or slice `n` of ``self``, + by getting ``self`` as a list. EXAMPLES:: @@ -1295,12 +1288,12 @@ cdef class Parent(sage.structure.category_object.CategoryObject): def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): r""" - Return True if ``im_gens`` defines a valid homomorphism - from self to codomain; otherwise return False. + Return ``True`` if ``im_gens`` defines a valid homomorphism + from ``self`` to ``codomain``; otherwise return ``False``. If determining whether or not a homomorphism is valid has not - been implemented for this ring, then a NotImplementedError exception - is raised. + been implemented for this ring, then a :exc:`NotImplementedError` + exception is raised. """ raise NotImplementedError("Verification of correctness of homomorphisms from %s not yet implemented." % self) @@ -1349,10 +1342,10 @@ cdef class Parent(sage.structure.category_object.CategoryObject): def hom(self, im_gens, codomain=None, check=None, base_map=None, category=None, **kwds): r""" - Return the unique homomorphism from self to codomain that + Return the unique homomorphism from ``self`` to ``codomain`` that sends ``self.gens()`` to the entries of ``im_gens``. - This raises a :class:`TypeError` if there is no such homomorphism. + This raises a :exc:`TypeError` if there is no such homomorphism. INPUT: @@ -1361,15 +1354,13 @@ cdef class Parent(sage.structure.category_object.CategoryObject): - ``codomain`` -- the codomain of the homomorphism - - ``base_map`` -- a map from the base ring to the codomain. - If not given, coercion is used. + - ``base_map`` -- a map from the base ring to the codomain; if not + given, coercion is used - ``check`` -- whether to verify that the images of generators - extend to define a map (using only canonical coercions). + extend to define a map (using only canonical coercions) - OUTPUT: - - A homomorphism self --> codomain + OUTPUT: a homomorphism ``self --> codomain`` .. NOTE:: @@ -1418,7 +1409,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): To: Finite Field of size 5 There might not be a natural morphism, in which case a - ``TypeError`` is raised:: + :exc:`TypeError` is raised:: sage: QQ.hom(ZZ) Traceback (most recent call last): @@ -1466,24 +1457,23 @@ cdef class Parent(sage.structure.category_object.CategoryObject): INPUT: - - ``coerce_list`` -- a list of coercion Morphisms to self and - parents with canonical coercions to self + - ``coerce_list`` -- list of coercion Morphisms to ``self`` and + parents with canonical coercions to ``self`` - - ``action_list`` -- a list of actions on and by self + - ``action_list`` -- list of actions on and by ``self`` - - ``convert_list`` -- a list of conversion Maps to self and - parents with conversions to self + - ``convert_list`` -- list of conversion Maps to ``self`` and + parents with conversions to ``self`` - - ``embedding`` -- a single Morphism from self + - ``embedding`` -- a single Morphism from ``self`` - ``convert_method_name`` -- a name to look for that other elements - can implement to create elements of self (e.g. _integer_) + can implement to create elements of ``self`` (e.g. ``_integer_``) - - ``init_no_parent`` -- if True omit passing self in as the + - ``init_no_parent`` -- if ``True`` omit passing ``self`` in as the first argument of element_constructor for conversion. This is useful if parents are unique, or element_constructor is a - bound method (this latter case can be detected - automatically). + bound method (this latter case can be detected automatically). """ self.init_coerce(False) @@ -1585,7 +1575,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): def _remove_from_coerce_cache(self, domain): r""" - Remove the coercion and the conversion from ``domain`` to self from the cache. + Remove the coercion and the conversion from ``domain`` to ``self`` from + the cache. EXAMPLES:: @@ -1673,7 +1664,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef register_action(self, action): r""" - Update the coercion model to use ``action`` to act on self. + Update the coercion model to use ``action`` to act on ``self``. ``action`` should be of type ``sage.categories.action.Action``. @@ -1689,7 +1680,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): ....: ....: def _act_(self, g, a): ....: D = {} - ....: for k, v in a.dict().items(): + ....: for k, v in a.monomial_coefficients().items(): ....: nk = [0]*len(k) ....: for i in range(len(k)): ....: nk[g(i+1)-1] = k[i] @@ -1909,7 +1900,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef _generic_coerce_map(self, S): r""" - Returns a default coercion map based on the data provided to + Return a default coercion map based on the data provided to :meth:`_populate_coercion_lists_`. This method differs from :meth:`_generic_convert_map` only in setting @@ -1940,7 +1931,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef _generic_convert_map(self, S, category=None): r""" - Returns the default conversion map based on the data provided to + Return the default conversion map based on the data provided to :meth:`_populate_coercion_lists_`. This is called when :meth:`_coerce_map_from_` returns ``True``. @@ -2014,18 +2005,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): def _coerce_map_via(self, v, S): """ - This attempts to construct a morphism from S to self by passing through - one of the items in v (tried in order). + This attempts to construct a morphism from ``S`` to ``self`` by passing + through one of the items in ``v`` (tried in order). - S may appear in the list, in which case algorithm will never progress - beyond that point. + ``S`` may appear in the list, in which case algorithm will never + progress beyond that point. - This is useful when defining _coerce_map_from_. + This is useful when defining ``_coerce_map_from_``. INPUT: - - ``v`` -- A list (iterator) of parents with coercions into self. There - MUST be maps provided from each item in the list to self. + - ``v`` -- list (iterator) of parents with coercions into ``self``; + there *must* be maps provided from each item in the list to ``self`` - ``S`` -- the starting parent @@ -2100,11 +2091,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef _coerce_map_from_(self, S): """ Override this method to specify coercions beyond those specified - in coerce_list. + in ``coerce_list``. - If no such coercion exists, return None or False. Otherwise, it may - return either an actual Map to use for the coercion, a callable - (in which case it will be wrapped in a Map), or True (in which case + If no such coercion exists, return ``None`` or ``False``. Otherwise, it + may return either an actual Map to use for the coercion, a callable + (in which case it will be wrapped in a Map), or ``True`` (in which case a generic map will be provided). """ try: @@ -2276,11 +2267,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cdef discover_coerce_map_from(self, S): """ - Precedence for discovering a coercion S -> self goes as follows: + Precedence for discovering a coercion ``S -> self`` goes as follows: - 1. If S has an embedding into self, return that embedding. + 1. If ``S`` has an embedding into ``self``, return that embedding. - 2. If self._coerce_map_from_(S) is NOT exactly one of + 2. If ``self._coerce_map_from_(S)`` is not exactly one of - DefaultConvertMap - DefaultConvertMap_unique @@ -2291,8 +2282,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): 3. Traverse the coercion lists looking for another map returning the map from step (2) if none is found. - 4. If S has an embedding into some parent T, look for T -> self and - return composition. + 4. If ``S`` has an embedding into some parent ``T``, look for + ``T -> self`` and return composition. In the future, multiple paths may be discovered and compared. @@ -2453,14 +2444,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef convert_map_from(self, S): """ - This function returns a :class:`Map` from `S` to `self`, + This function returns a :class:`Map` from `S` to ``self``, which may or may not succeed on all inputs. - If a coercion map from S to self exists, - then the it will be returned. If a coercion from `self` to `S` exists, + If a coercion map from S to ``self`` exists, + then the it will be returned. If a coercion from ``self`` to `S` exists, then it will attempt to return a section of that map. Under the new coercion model, this is the fastest way to convert - elements of `S` to elements of `self` (short of manually constructing + elements of `S` to elements of ``self`` (short of manually constructing the elements) and is used by :meth:`__call__`. EXAMPLES:: @@ -2479,14 +2470,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef _internal_convert_map_from(self, S): """ - This function returns a :class:`Map` from `S` to `self`, + This function returns a :class:`Map` from `S` to ``self``, which may or may not succeed on all inputs. - If a coercion map from S to self exists, - then the it will be returned. If a coercion from `self` to `S` exists, + If a coercion map from S to ``self`` exists, + then the it will be returned. If a coercion from ``self`` to `S` exists, then it will attempt to return a section of that map. Under the new coercion model, this is the fastest way to convert - elements of `S` to elements of `self` (short of manually constructing + elements of `S` to elements of ``self`` (short of manually constructing the elements) and is used by :func:`__call__`. EXAMPLES:: @@ -2554,20 +2545,20 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef _convert_map_from_(self, S): """ Override this method to provide additional conversions beyond those - given in convert_list. + given in ``convert_list``. This function is called after coercions are attempted. If there is a coercion morphism in the opposite direction, one should consider adding a section method to that. - This MUST return a Map from S to self, or None. If None is returned - then a generic map will be provided. + This MUST return a Map from ``S`` to ``self``, or ``None``. If ``None`` + is returned then a generic map will be provided. """ return None cpdef get_action(self, S, op=operator.mul, bint self_on_left=True, self_el=None, S_el=None): """ - Returns an action of self on S or S on self. + Return an action of ``self`` on ``S`` or ``S`` on ``self``. To provide additional actions, override :meth:`_get_action_`. @@ -2759,11 +2750,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef _get_action_(self, S, op, bint self_on_left): """ - Override this method to provide an action of self on S or S on self - beyond what was specified in action_list. + Override this method to provide an action of ``self`` on ``S`` or ``S`` + on ``self`` beyond what was specified in ``action_list``. - This must return an action which accepts an element of self and an - element of S (in the order specified by self_on_left). + This must return an action which accepts an element of ``self`` and an + element of ``S`` (in the order specified by ``self_on_left``). """ return None @@ -2771,11 +2762,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): # Sets().ParentMethods.an_element cpdef an_element(self): r""" - Returns a (preferably typical) element of this parent. + Return a (preferably typical) element of this parent. This is used both for illustration and testing purposes. If the set ``self`` is empty, :meth:`an_element` raises the - exception :class:`EmptySetError`. + exception :exc:`EmptySetError`. This calls :meth:`_an_element_` (which see), and caches the result. Parent are thus encouraged to override :meth:`_an_element_`. @@ -2787,7 +2778,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: ZZ[['t']].an_element() t - In case the set is empty, an :class:`EmptySetError` is raised:: + In case the set is empty, an :exc:`EmptySetError` is raised:: sage: Set([]).an_element() Traceback (most recent call last): @@ -2880,7 +2871,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): OUTPUT: - Return True if elements of this ring are represented exactly, i.e., + Return ``True`` if elements of this ring are represented exactly, i.e., there is no precision loss when doing arithmetic. EXAMPLES:: @@ -2986,7 +2977,6 @@ cdef class Set_generic(Parent): sage: Set(QQ).category() Category of infinite sets - """ def object(self): """ @@ -3001,8 +2991,8 @@ cdef class Set_generic(Parent): def __bool__(self): """ - A set is considered True unless it is empty, in which case it is - considered to be False. + A set is considered ``True`` unless it is empty, in which case it is + considered to be ``False``. EXAMPLES:: diff --git a/src/sage/structure/parent_gens.pyx b/src/sage/structure/parent_gens.pyx index 6f12c36670f..b27002d1254 100644 --- a/src/sage/structure/parent_gens.pyx +++ b/src/sage/structure/parent_gens.pyx @@ -11,7 +11,7 @@ Base class for old-style parent objects with generators Many parent objects in Sage are equipped with generators, which are special elements of the object. For example, the polynomial ring -`\ZZ[x,y,z]` is generated by `x`, `y`, and `z`. In Sage the `i^{th}` +`\ZZ[x,y,z]` is generated by `x`, `y`, and `z`. In Sage the `i`-th generator of an object ``X`` is obtained using the notation ``X.gen(i)``. From the Sage interactive prompt, the shorthand notation ``X.i`` is also allowed. @@ -127,7 +127,6 @@ cdef class ParentWithGens(ParentWithBase): This can only be done once because objects with generators are immutable, and is typically done during creation of the object. - EXAMPLES: When we create this polynomial ring, self._assign_names is called by the constructor: @@ -204,7 +203,7 @@ cdef class ParentWithGens(ParentWithBase): sends ``self.gens()`` to the entries of ``im_gens`` and induces the map ``base_map`` on the base ring. - This raises a :class:`TypeError` if there is no such homomorphism. + This raises a :exc:`TypeError` if there is no such homomorphism. INPUT: @@ -221,9 +220,7 @@ cdef class ParentWithGens(ParentWithBase): - ``check`` -- whether to verify that the images of generators extend to define a map (using only canonical coercions) - OUTPUT: - - - a homomorphism self --> codomain + OUTPUT: a homomorphism ``self --> codomain`` .. NOTE:: @@ -275,7 +272,7 @@ cdef class ParentWithGens(ParentWithBase): To: Finite Field of size 5 There might not be a natural morphism, in which case a - :class:`TypeError` exception is raised. + :exc:`TypeError` exception is raised. :: diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index a34928ff8a2..202e8247fe1 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -203,16 +203,16 @@ cdef class Parent(parent.Parent): cdef _coerce_c_impl(self, x): # OVERRIDE THIS FOR CYTHON CLASSES """ - Canonically coerce x in assuming that the parent of x is not - equal to self. + Canonically coerce ``x`` in assuming that the parent of ``x`` is not + equal to ``self``. """ check_old_coerce(self) raise TypeError def _coerce_impl(self, x): # OVERRIDE THIS FOR PYTHON CLASSES """ - Canonically coerce x in assuming that the parent of x is not - equal to self. + Canonically coerce ``x`` in assuming that the parent of ``x`` is not + equal to ``self``. """ check_old_coerce(self) return self._coerce_c_impl(x) diff --git a/src/sage/structure/proof/all.py b/src/sage/structure/proof/all.py index d3a72dc1400..0db573b93ce 100644 --- a/src/sage/structure/proof/all.py +++ b/src/sage/structure/proof/all.py @@ -8,7 +8,7 @@ def arithmetic(t=None): INPUT: - t -- boolean or ``None`` + - ``t`` -- boolean or ``None`` OUTPUT: @@ -46,7 +46,7 @@ def elliptic_curve(t=None): INPUT: - t -- boolean or ``None`` + - ``t`` -- boolean or ``None`` OUTPUT: @@ -84,7 +84,7 @@ def linear_algebra(t=None): INPUT: - t -- boolean or ``None`` + - ``t`` -- boolean or ``None`` OUTPUT: @@ -122,7 +122,7 @@ def number_field(t=None): INPUT: - t -- boolean or ``None`` + - ``t`` -- boolean or ``None`` OUTPUT: @@ -159,7 +159,7 @@ def polynomial(t=None): INPUT: - t -- boolean or ``None`` + - ``t`` -- boolean or ``None`` OUTPUT: @@ -196,7 +196,7 @@ def all(t=None): INPUT: - t -- boolean or ``None`` + - ``t`` -- boolean or ``None`` OUTPUT: diff --git a/src/sage/structure/proof/proof.py b/src/sage/structure/proof/proof.py index 4a459551837..c8c2df4cafe 100644 --- a/src/sage/structure/proof/proof.py +++ b/src/sage/structure/proof/proof.py @@ -3,11 +3,20 @@ from sage.structure.sage_object import SageObject + class _ProofPref(SageObject): """ - An object that holds global proof preferences. For now these are merely True/False flags for various parts of Sage that use probabilistic algorithms. - A True flag means that the subsystem (such as linear algebra or number fields) should return results that are true unconditionally: the correctness should not depend on an algorithm with a nonzero probability of returning an incorrect answer or on the truth of any unproven conjectures. - A False flag means that the subsystem can use faster methods to return answers that have a very small probability of being wrong. + An object that holds global proof preferences. For now these are merely + boolean flags for various parts of Sage that use probabilistic + algorithms. + + A ``True`` flag means that the subsystem (such as linear algebra or number + fields) should return results that are true unconditionally: the + correctness should not depend on an algorithm with a nonzero probability of + returning an incorrect answer or on the truth of any unproven conjectures. + + A ``False`` flag means that the subsystem can use faster methods to return + answers that have a very small probability of being wrong. """ def __init__(self, proof=True): self._require_proof = {} @@ -24,13 +33,20 @@ def arithmetic(self, t=None): INPUT: - t -- boolean or None + - ``t`` -- boolean or ``None`` OUTPUT: - If t == True, requires integer arithmetic operations to (by default) return results that are true unconditionally: the correctness will not depend on an algorithm with a nonzero probability of returning an incorrect answer or on the truth of any unproven conjectures. - If t == False, allows integer arithmetic operations to (by default) return results that may depend on unproven conjectures or on probabilistic algorithms. Such algorithms often have a substantial speed improvement over those requiring proof. - If t is None, returns the integer arithmetic proof status. + - if ``t == True``, requires integer arithmetic operations to (by + default) return results that are true unconditionally: the + correctness will not depend on an algorithm with a nonzero + probability of returning an incorrect answer or on the truth of any + unproven conjectures. + - if ``t == False``, allows integer arithmetic operations to (by + default) return results that may depend on unproven conjectures or on + probabilistic algorithms. Such algorithms often have a substantial + speed improvement over those requiring proof. + - if ``t == None``, returns the integer arithmetic proof status. EXAMPLES:: @@ -53,13 +69,19 @@ def elliptic_curve(self, t=None): INPUT: - t -- boolean or None + - ``t`` -- boolean or ``None`` OUTPUT: - If t == True, requires elliptic curve algorithms to (by default) return results that are true unconditionally: the correctness will not depend on an algorithm with a nonzero probability of returning an incorrect answer or on the truth of any unproven conjectures. - If t == False, allows elliptic curve algorithms to (by default) return results that may depend on unproven conjectures or on probabilistic algorithms. Such algorithms often have a substantial speed improvement over those requiring proof. - If t is None, returns the current elliptic curve proof status. + - if ``t == True``, requires elliptic curve algorithms to (by default) + return results that are true unconditionally: the correctness will + not depend on an algorithm with a nonzero probability of returning an + incorrect answer or on the truth of any unproven conjectures. + - if ``t == False``, allows elliptic curve algorithms to (by default) + return results that may depend on unproven conjectures or on + probabilistic algorithms. Such algorithms often have a substantial + speed improvement over those requiring proof. + - if ``t == None``, returns the current elliptic curve proof status. EXAMPLES:: @@ -82,13 +104,19 @@ def linear_algebra(self, t=None): INPUT: - t -- boolean or None + - ``t`` -- boolean or ``None`` OUTPUT: - If t == True, requires linear algebra algorithms to (by default) return results that are true unconditionally: the correctness will not depend on an algorithm with a nonzero probability of returning an incorrect answer or on the truth of any unproven conjectures. - If t == False, allows linear algebra algorithms to (by default) return results that may depend on unproven conjectures or on probabilistic algorithms. Such algorithms often have a substantial speed improvement over those requiring proof. - If t is None, returns the current linear algebra proof status. + - if ``t == True``, requires linear algebra algorithms to (by default) + return results that are true unconditionally: the correctness will + not depend on an algorithm with a nonzero probability of returning an + incorrect answer or on the truth of any unproven conjectures. + - if ``t == False``, allows linear algebra algorithms to (by default) + return results that may depend on unproven conjectures or on + probabilistic algorithms. Such algorithms often have a substantial + speed improvement over those requiring proof. + - if ``t == None``, returns the current linear algebra proof status. EXAMPLES:: @@ -111,13 +139,19 @@ def number_field(self, t=None): INPUT: - t -- boolean or None + - ``t`` -- boolean or ``None`` OUTPUT: - If t == True, requires number field algorithms to (by default) return results that are true unconditionally: the correctness will not depend on an algorithm with a nonzero probability of returning an incorrect answer or on the truth of any unproven conjectures. - If t == False, allows number field algorithms to (by default) return results that may depend on unproven conjectures or on probabilistic algorithms. Such algorithms often have a substantial speed improvement over those requiring proof. - If t is None, returns the current number field proof status. + - if ``t == True``, requires number field algorithms to (by default) + return results that are true unconditionally: the correctness will + not depend on an algorithm with a nonzero probability of returning an + incorrect answer or on the truth of any unproven conjectures. + - if ``t == False``, allows number field algorithms to (by default) + return results that may depend on unproven conjectures or on + probabilistic algorithms. Such algorithms often have a substantial + speed improvement over those requiring proof. + - if ``t == None``, returns the current number field proof status. EXAMPLES:: @@ -140,13 +174,19 @@ def polynomial(self, t=None): INPUT: - t -- boolean or None + - ``t`` -- boolean or ``None`` OUTPUT: - If t == True, requires polynomial algorithms to (by default) return results that are true unconditionally: the correctness will not depend on an algorithm with a nonzero probability of returning an incorrect answer or on the truth of any unproven conjectures. - If t == False, allows polynomial algorithms to (by default) return results that may depend on unproven conjectures or on probabilistic algorithms. Such algorithms often have a substantial speed improvement over those requiring proof. - If t is None, returns the current polynomial proof status. + - if ``t == True``, requires polynomial algorithms to (by default) + return results that are true unconditionally: the correctness will + not depend on an algorithm with a nonzero probability of returning an + incorrect answer or on the truth of any unproven conjectures. + - if ``t == False``, allows polynomial algorithms to (by default) + return results that may depend on unproven conjectures or on + probabilistic algorithms. Such algorithms often have a substantial + speed improvement over those requiring proof. + - if ``t == None``, returns the current polynomial proof status. EXAMPLES:: @@ -164,7 +204,8 @@ def polynomial(self, t=None): self._require_proof["polynomial"] = bool(t) -_proof_prefs = _ProofPref(True) #Creates the global object that stores proof preferences. +_proof_prefs = _ProofPref(True) # Creates the global object that stores proof preferences. + def get_flag(t=None, subsystem=None): """ @@ -191,7 +232,7 @@ def get_flag(t=None, subsystem=None): return t -class WithProof(): +class WithProof: """ Use :class:`WithProof` to temporarily set the value of one of the proof systems for a block of code, with a guarantee that it will be set diff --git a/src/sage/structure/richcmp.pxd b/src/sage/structure/richcmp.pxd index ecbeaef391e..1ff9c16dee0 100644 --- a/src/sage/structure/richcmp.pxd +++ b/src/sage/structure/richcmp.pxd @@ -13,8 +13,8 @@ cpdef inline richcmp(x, y, int op): - ``x``, ``y`` -- arbitrary Python objects - - ``op`` -- comparison operator (one of ``op_LT`, ``op_LE``, - ``op_EQ``, ``op_NE``, ``op_GT``, ``op_GE``). + - ``op`` -- comparison operator (one of ``op_LT``, ``op_LE``, + ``op_EQ``, ``op_NE``, ``op_GT``, ``op_GE``) EXAMPLES:: @@ -127,7 +127,7 @@ cpdef inline bint rich_to_bool(int op, int c) noexcept: - ``op`` -- a rich comparison operation (e.g. ``Py_EQ``) - - ``c`` -- the result of an old-style comparison: -1, 0 or 1. + - ``c`` -- the result of an old-style comparison: -1, 0 or 1 OUTPUT: 1 or 0 (corresponding to ``True`` and ``False``) diff --git a/src/sage/structure/richcmp.pyx b/src/sage/structure/richcmp.pyx index 934a49e7600..d3e8cb3e41d 100644 --- a/src/sage/structure/richcmp.pyx +++ b/src/sage/structure/richcmp.pyx @@ -78,15 +78,13 @@ cpdef richcmp_item(x, y, int op): INPUT: - - ``x``, ``y`` -- arbitrary Python objects. Typically, these are - ``X[i]`` and ``Y[i]`` for sequences ``X`` and ``Y``. + - ``x``, ``y`` -- arbitrary Python objects; typically, these are + ``X[i]`` and ``Y[i]`` for sequences ``X`` and ``Y`` - - ``op`` -- comparison operator (one of ``op_LT`, ``op_LE``, + - ``op`` -- comparison operator (one of ``op_LT``, ``op_LE``, ``op_EQ``, ``op_NE``, ``op_GT``, ``op_GE``) - OUTPUT: - - Assuming that ``x = X[i]`` and ``y = Y[i]``: + OUTPUT: assuming that ``x = X[i]`` and ``y = Y[i]``: - if the comparison ``X {op} Y`` (where ``op`` is the given operation) could not be decided yet (i.e. we should compare the diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 4c4bd56678e..7102316be70 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -67,7 +67,7 @@ cdef class SageObject: def rename(self, x=None): r""" - Change self so it prints as x, where x is a string. + Change ``self`` so it prints as x, where x is a string. If x is ``None``, the existing custom name is removed. @@ -362,7 +362,7 @@ cdef class SageObject: def __hash__(self): r""" - Not implemented: mutable objects inherit from this class + Not implemented: mutable objects inherit from this class. EXAMPLES:: @@ -431,7 +431,6 @@ cdef class SageObject: sage: d = a + O(2) # needs sage.rings.padics sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # needs sage.rings.padics False - """ try: hash(self) @@ -446,7 +445,7 @@ cdef class SageObject: def save(self, filename=None, compress=True): """ - Save self to the given filename. + Save ``self`` to the given filename. EXAMPLES:: @@ -454,7 +453,7 @@ cdef class SageObject: sage: x = SR.var("x") sage: f = x^3 + 5 sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".sobj") as t: + sage: with NamedTemporaryFile(suffix='.sobj') as t: ....: f.save(t.name) ....: load(t.name) x^3 + 5 @@ -606,7 +605,7 @@ cdef class SageObject: def _test_not_implemented_methods(self, **options): """ - Checks that all required methods for this object are implemented + Check that all required methods for this object are implemented. TESTS:: @@ -653,7 +652,7 @@ cdef class SageObject: def _test_pickling(self, **options): """ - Checks that this object can be pickled and unpickled properly. + Check that this object can be pickled and unpickled properly. EXAMPLES:: @@ -689,11 +688,10 @@ cdef class SageObject: def _interface_(self, I): """ - Return coercion of self to an object of the interface I. + Return coercion of ``self`` to an object of the interface I. - The result of coercion is cached, unless self is a C - extension class or ``self._interface_is_cached_()`` returns - False. + The result of coercion is cached, unless ``self`` is a C extension + class or ``self._interface_is_cached_()`` returns ``False``. """ c = self._interface_is_cached_() if c: @@ -721,7 +719,7 @@ cdef class SageObject: try: s = self._interface_init_(I) except Exception: - raise NotImplementedError("coercion of object %s to %s not implemented:\n%s\n%s" % (repr(self), I)) + raise NotImplementedError("coercion of object %s to %s not implemented" % (repr(self), I)) X = I(s) if c: try: @@ -735,7 +733,7 @@ cdef class SageObject: def _interface_is_cached_(self): """ - Return True if the interface objects are cached. + Return ``True`` if the interface objects are cached. If you have an object x and do gp(x), the result is cached if this function returns True. @@ -831,16 +829,14 @@ cdef class SageObject: def _magma_init_(self, magma): """ Given a Magma interpreter M, return a string that evaluates in - that interpreter to the Magma object corresponding to self. + that interpreter to the Magma object corresponding to ``self``. This function may call the magma interpreter when it runs. INPUT: - ``magma`` -- a Magma interface - OUTPUT: - - - string + OUTPUT: string EXAMPLES:: @@ -946,9 +942,7 @@ cdef class SageObject: Return default string expression that evaluates in R to this object. - OUTPUT: - - - string + OUTPUT: string EXAMPLES:: diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 0a4563d27e4..cc9fcedadfe 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -85,33 +85,29 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non INPUT: - - ``x`` -- a list or tuple instance + - ``x`` -- list or tuple instance - - ``universe`` -- (default: None) the universe of elements; if None - determined using canonical coercions and the entire list of - elements. If list is empty, is category Objects() of all - objects. + - ``universe`` -- (default: ``None``) the universe of elements; if ``None`` + determined using canonical coercions and the entire list of elements. + If list is empty, is category ``Objects()`` of all objects. - - ``check`` -- (default: ``True``) whether to coerce the elements of x + - ``check`` -- boolean (default: ``True``); whether to coerce the elements of x into the universe - - ``immutable`` -- (default: ``True``) whether or not this sequence is + - ``immutable`` -- boolean (default: ``True``); whether or not this sequence is immutable - - ``cr`` -- (default: ``False``) if True, then print a carriage return - after each comma when printing this sequence. + - ``cr`` -- boolean (default: ``False``); if ``True``, then print a carriage return + after each comma when printing this sequence - - ``cr_str`` -- (default: ``False``) if True, then print a carriage return - after each comma when calling ``str()`` on this sequence. + - ``cr_str`` -- boolean (default: ``False``); if ``True``, then print a carriage return + after each comma when calling ``str()`` on this sequence - - ``use_sage_types`` -- (default: ``False``) if True, coerce the - built-in Python numerical types int, float, complex to the - corresponding Sage types (this makes functions like vector() - more flexible) + - ``use_sage_types`` -- boolean (default: ``False``); if ``True``, coerce the + built-in Python numerical types int, float, complex to the corresponding + Sage types (this makes functions like ``vector()`` more flexible) - OUTPUT: - - - a sequence + OUTPUT: a sequence EXAMPLES:: @@ -256,12 +252,12 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non try: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing - from sage.rings.quotient_ring import is_QuotientRing + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base + from sage.rings.quotient_ring import QuotientRing_nc except ImportError: pass else: - if is_MPolynomialRing(universe) or isinstance(universe, BooleanMonomialMonoid) or (is_QuotientRing(universe) and is_MPolynomialRing(universe.cover_ring())): + if isinstance(universe, MPolynomialRing_base) or isinstance(universe, BooleanMonomialMonoid) or (isinstance(universe, QuotientRing_nc) and isinstance(universe.cover_ring(), MPolynomialRing_base)): return PolynomialSequence(x, universe, immutable=immutable, cr=cr, cr_str=cr_str) return Sequence_generic(x, universe, check, immutable, cr, cr_str, use_sage_types) @@ -277,30 +273,26 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): INPUT: - - ``x`` -- a list or tuple instance + - ``x`` -- list or tuple instance - - ``universe`` -- (default: None) the universe of elements; if None - determined using canonical coercions and the entire list of - elements. If list is empty, is category Objects() of all - objects. + - ``universe`` -- (default: ``None``) the universe of elements; if ``None`` + determined using canonical coercions and the entire list of elements. + If list is empty, is category ``Objects()`` of all objects. - - ``check`` -- (default: ``True``) whether to coerce the elements of x + - ``check`` -- boolean (default: ``True``); whether to coerce the elements of x into the universe - - ``immutable`` -- (default: ``True``) whether or not this sequence is + - ``immutable`` -- boolean (default: ``True``); whether or not this sequence is immutable - - ``cr`` -- (default: ``False``) if True, then print a carriage return - after each comma when printing this sequence. - - - ``use_sage_types`` -- (default: ``False``) if True, coerce the - built-in Python numerical types int, float, complex to the - corresponding Sage types (this makes functions like vector() - more flexible) + - ``cr`` -- boolean (default: ``False``); if ``True``, then print a carriage return + after each comma when printing this sequence - OUTPUT: + - ``use_sage_types`` -- boolean (default: ``False``); if ``True``, coerce the + built-in Python numerical types int, float, complex to the corresponding + Sage types (this makes functions like ``vector()`` more flexible) - - a sequence + OUTPUT: a sequence EXAMPLES:: @@ -402,7 +394,6 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): [1, 2, 1, 3] sage: v.universe() Finite Field of size 5 - """ def __init__(self, x, universe=None, check=True, immutable=False, cr=False, cr_str=None, use_sage_types=False): @@ -584,7 +575,7 @@ def insert(self, index, object): def pop(self, index=-1): """ - Remove and return item at index (default last) + Remove and return item at index ``index`` (default: last). EXAMPLES:: @@ -599,7 +590,7 @@ def pop(self, index=-1): def remove(self, value): """ - Remove first occurrence of value + Remove first occurrence of ``value``. EXAMPLES:: @@ -753,8 +744,8 @@ def set_immutable(self): def is_immutable(self): """ - Return True if this object is immutable (can not be changed) - and False if it is not. + Return ``True`` if this object is immutable (can not be changed) + and ``False`` if it is not. To make this object immutable use :meth:`set_immutable`. @@ -821,7 +812,7 @@ def __reduce__(self): def __copy__(self): """ - Return a copy of this sequence + Return a copy of this sequence. EXAMPLES:: @@ -833,7 +824,6 @@ def __copy__(self): True sage: t.is_mutable() == s.is_mutable() True - """ return Sequence(self, universe=self.__universe, check=False, @@ -842,7 +832,7 @@ def __copy__(self): def __getattr__(self, name): """ - Strictly for unpickling old 'Sequences' + Strictly for unpickling old 'Sequences'. INPUT: diff --git a/src/sage/structure/set_factories.py b/src/sage/structure/set_factories.py index 46d8870379c..c65a31089e8 100644 --- a/src/sage/structure/set_factories.py +++ b/src/sage/structure/set_factories.py @@ -625,7 +625,7 @@ class TopMostParentPolicy(SetFactoryPolicy): INPUT: - ``factory`` -- an instance of :class:`SetFactory` - - ``top_constraints`` -- the empty set of constraints. + - ``top_constraints`` -- the empty set of constraints - ``Element`` -- a subclass of :class:`~.element.Element` Given a factory ``F`` and a class ``E``, returns a policy for @@ -871,9 +871,9 @@ class ParentWithSetFactory(Parent): INPUT: - - ``constraints`` -- a set of constraints + - ``constraints`` -- set of constraints - ``policy`` -- the policy for element construction - - ``category`` -- the category of the parent (default to ``None``) + - ``category`` -- the category of the parent (default: ``None``) Depending on the constraints and the policy, initialize the parent in a proper category to set up element construction. @@ -1018,8 +1018,7 @@ def subset(self, *args, **options): def _test_subset(self, **options): r""" - Tests that subsets with no extra parameters returns - ``self``. + Test that subsets with no extra parameters returns ``self``. Currently, only the test that one gets the same parent when no more constraints are given, is performed. @@ -1045,10 +1044,10 @@ def check_element(self, x, check): INPUT: - - ``x`` -- an instance of ``self.element_class``. + - ``x`` -- an instance of ``self.element_class`` - ``check`` -- the level of checking to be performed (usually a - boolean). + boolean) This method may assume that ``x`` was properly constructed by ``self`` or a possible super-set of ``self`` for which diff --git a/src/sage/structure/set_factories_example.py b/src/sage/structure/set_factories_example.py index 860137250e9..df4db63ef89 100644 --- a/src/sage/structure/set_factories_example.py +++ b/src/sage/structure/set_factories_example.py @@ -63,9 +63,9 @@ def __call__(self, x=None, y=None, policy=None): INPUT: - - ``x=a`` -- where ``a`` is an integer (default to ``None``). - - ``y=b`` -- where ``b`` is an integer (default to ``None``). - - ``policy`` -- the policy passed to the created set. + - ``x=a`` -- where ``a`` is an integer (default: ``None``) + - ``y=b`` -- where ``b`` is an integer (default: ``None``) + - ``policy`` -- the policy passed to the created set .. SEEALSO:: @@ -91,7 +91,6 @@ def __call__(self, x=None, y=None, policy=None): TESTS:: sage: TestSuite(P).run() - """ if policy is None: policy = self._default_policy @@ -248,10 +247,9 @@ def __init__(self, policy): def pairs_y(self, letter): r""" - Construct the parent for the disjoint union + Construct the parent for the disjoint union. - Construct a parent in :class:`Pairs_Y` as a facade parent for - ``self``. + Construct a parent in :class:`Pairs_Y` as a facade parent for ``self``. This is an internal function which should be hidden from the user (typically under the name ``_pairs_y``. We put it here for @@ -432,7 +430,7 @@ def an_element(self): def single_pair(self, letter): r""" - Construct the singleton pair parent + Construct the singleton pair parent. Construct a singleton pair for ``(self.y, letter)`` as a facade parent for ``self``. diff --git a/src/sage/structure/support_view.py b/src/sage/structure/support_view.py index bebae1a31f5..5daf8c2e496 100644 --- a/src/sage/structure/support_view.py +++ b/src/sage/structure/support_view.py @@ -10,7 +10,8 @@ class SupportView(MappingView, Sequence, Set): r""" - Dynamic view of the set of keys of a dictionary that are associated with nonzero values + Dynamic view of the set of keys of a dictionary that are associated with + nonzero values. It behaves like the objects returned by the :meth:`keys`, :meth:`values`, :meth:`items` of a dictionary (or other :class:`collections.abc.Mapping` @@ -18,9 +19,9 @@ class SupportView(MappingView, Sequence, Set): INPUT: - - ``mapping`` -- a :class:`dict` or another :class:`collections.abc.Mapping`. + - ``mapping`` -- a :class:`dict` or another :class:`collections.abc.Mapping` - - ``zero`` -- (optional) test for zeroness by comparing with this value. + - ``zero`` -- (optional) test for zeroness by comparing with this value EXAMPLES:: diff --git a/src/sage/structure/test_factory.py b/src/sage/structure/test_factory.py index 9835a06f909..707feb0d409 100644 --- a/src/sage/structure/test_factory.py +++ b/src/sage/structure/test_factory.py @@ -21,10 +21,11 @@ from sage.structure.factory import UniqueFactory -class A(): +class A: # something we can weakref pass + class UniqueFactoryTester(UniqueFactory): def create_key(self, *args, **kwds): diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index 7f769522caf..c7bb3783658 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -343,7 +343,7 @@ class will by default also be used as keys for the cache:: ....: return C(key) Now, we define an instance of the factory, stating that it can be found under -the name ``"F"`` in the ``__main__`` module. By consequence, pickling works:: +the name ``'F'`` in the ``__main__`` module. By consequence, pickling works:: sage: F = MyFactory("__main__.F") sage: __main__.F = F # not needed in an interactive session @@ -1201,7 +1201,7 @@ def _clear_cache_(cls): del cache[k] -class UniqueRepresentation(CachedRepresentation, WithEqualityById): +class UniqueRepresentation(WithEqualityById, CachedRepresentation): r""" Classes derived from ``UniqueRepresentation`` inherit a unique representation behavior for their instances. diff --git a/src/sage/symbolic/assumptions.py b/src/sage/symbolic/assumptions.py index 9ef8dd39212..9eef304c6fc 100644 --- a/src/sage/symbolic/assumptions.py +++ b/src/sage/symbolic/assumptions.py @@ -96,11 +96,10 @@ class GenericDeclaration(UniqueRepresentation): INPUT: - - ``var`` -- the variable about which assumptions are - being made + - ``var`` -- the variable about which assumptions are being made - - ``assumption`` -- a string containing a Maxima feature, either user - defined or in the list given by ``maxima('features')`` + - ``assumption`` -- string containing a Maxima feature, either user + defined or in the list given by ``maxima('features')`` EXAMPLES:: @@ -127,7 +126,6 @@ class GenericDeclaration(UniqueRepresentation): sage: GenericDeclaration(x, 'integer') is GenericDeclaration(SR.var("x"), 'integer') True - """ def __init__(self, var, assumption): @@ -139,11 +137,10 @@ def __init__(self, var, assumption): INPUT: - - ``var`` -- the variable about which assumptions are - being made + - ``var`` -- the variable about which assumptions are being made - - ``assumption`` -- a Maxima feature, either user - defined or in the list given by ``maxima('features')`` + - ``assumption`` -- a Maxima feature, either user + defined or in the list given by ``maxima('features')`` EXAMPLES:: @@ -197,7 +194,7 @@ def has(self, arg): def _validate_feature(self): """ - Check if this assumption is a known maxima feature, raise an error otherwise + Check if this assumption is a known maxima feature, raise an error otherwise. EXAMPLES:: @@ -330,8 +327,8 @@ def contradicts(self, soln): INPUT: - - ``soln`` -- Either a dictionary with variables as keys or a symbolic - relation with a variable on the left hand side. + - ``soln`` -- either a dictionary with variables as keys or a symbolic + relation with a variable on the left hand side EXAMPLES:: @@ -456,16 +453,14 @@ def assume(*args): The two types can be combined, but a symbolic inequality cannot appear in the middle of a list of variables. - OUTPUT: - - If everything goes as planned, there is no output. + OUTPUT: if everything goes as planned, there is no output If you assume something that is not one of the two forms above, then - an ``AttributeError`` is raised as we try to call its ``assume`` + an :exc:`AttributeError` is raised as we try to call its ``assume`` method. If you make inconsistent assumptions (for example, that ``x`` is - both even and odd), then a ``ValueError`` is raised. + both even and odd), then a :exc:`ValueError` is raised. .. WARNING:: @@ -630,7 +625,7 @@ def assume(*args): True sage: forget() - Ensure that an ``AttributeError`` is raised if we are given junk:: + Ensure that an :exc:`AttributeError` is raised if we are given junk:: sage: assume(3) Traceback (most recent call last): @@ -686,8 +681,7 @@ def forget(*args): INPUT: - - ``*args`` -- assumptions (default: forget all - assumptions) + - ``*args`` -- assumptions (default: forget all assumptions) EXAMPLES: @@ -735,11 +729,9 @@ def assumptions(*args): INPUT: - - ``args`` -- list of variables which can be empty. - - OUTPUT: + - ``args`` -- list of variables which can be empty - - list of assumptions on variables. If args is empty it returns all + OUTPUT: list of assumptions on variables; if ``args`` is empty it returns all assumptions EXAMPLES:: @@ -861,11 +853,11 @@ class assuming: INPUT: - - ``*args`` -- assumptions (same format as for :func:`assume`). + - ``*args`` -- assumptions (same format as for :func:`assume`) - - ``replace`` -- a boolean (default : ``False``). - Specifies whether the new assumptions are added to (default) - or replace (if ``replace=True``) the current assumption set. + - ``replace`` -- boolean (default: ``False``); specifies whether the new + assumptions are added to (default) or replace (if ``replace=True``) the + current assumption set OUTPUT: diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index 41ae61bfc72..3a7b7f553a6 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -146,10 +146,9 @@ def arguments(self): def unify_arguments(self, x): r""" - Takes the variable list from another - ``CallableSymbolicExpression`` object and compares it with the - current ``CallableSymbolicExpression`` object's variable list, - combining them according to the following rules: + Take the variable list from another ``CallableSymbolicExpression`` + object and compare it with the current ``CallableSymbolicExpression`` + object's variable list, combining them according to the following rules: Let ``a`` be ``self``'s variable list, let ``b`` be ``y``'s variable list. @@ -176,9 +175,9 @@ def unify_arguments(self, x): INPUT: - - ``x`` -- A CallableSymbolicExpression + - ``x`` -- a ``CallableSymbolicExpression`` - OUTPUT: A tuple of variables. + OUTPUT: a tuple of variables EXAMPLES:: @@ -214,11 +213,11 @@ def unify_arguments(self, x): temp = set() # Sorting remaining variables. for j in range(i, len(a)): - if not a[j] in temp: + if a[j] not in temp: temp.add(a[j]) for j in range(i, len(b)): - if not b[j] in temp: + if b[j] not in temp: temp.add(b[j]) new_list.extend(sorted(temp, key=repr)) @@ -348,7 +347,6 @@ def _repr_element_(self, x): (y, x) |--> x + y sage: f.parent() Callable function ring with arguments (y, x) - """ args = self.arguments() repr_x = SymbolicRing._repr_element_(self, x) diff --git a/src/sage/symbolic/comparison_impl.pxi b/src/sage/symbolic/comparison_impl.pxi index a1ef76bd778..8d1bd2e03d6 100644 --- a/src/sage/symbolic/comparison_impl.pxi +++ b/src/sage/symbolic/comparison_impl.pxi @@ -52,7 +52,7 @@ cpdef int print_order(lhs, rhs) except -2: INPUT: - ``lhs``, ``rhs`` -- two symbolic expressions or something that - can be converted to one. + can be converted to one OUTPUT: @@ -95,7 +95,7 @@ class _print_key(): INPUT: - ``ex`` -- symbolic expression or something that can be - converted into one. + converted into one EXAMPLES:: @@ -114,11 +114,9 @@ class _print_key(): INPUT: - - ``other`` -- another :class:`_print_key` instance. + - ``other`` -- another :class:`_print_key` instance - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -137,16 +135,14 @@ class _print_key(): cpdef print_sorted(expressions): """ - Sort a list in print order + Sort a list in print order. INPUT: - - ``expressions`` -- a list/tuple/iterable of symbolic - expressions, or something that can be converted to one. - - OUTPUT: + - ``expressions`` -- list/tuple/iterable of symbolic + expressions, or something that can be converted to one - The list sorted by :meth:`print_order`. + OUTPUT: the list sorted by :meth:`print_order` EXAMPLES:: @@ -166,7 +162,7 @@ class _math_key(): INPUT: - ``ex`` -- symbolic expression or something that can be - converted into one. + converted into one EXAMPLES:: @@ -185,12 +181,10 @@ class _math_key(): INPUT: - - ``other`` -- another :class:`_print_key` instance. + - ``other`` -- another :class:`_print_key` instance - OUTPUT: - - Boolean. A ``ValueError`` is raised if we do not know how to - perform the comparison. + OUTPUT: boolean; a :exc:`ValueError` is raised if we do not know how to + perform the comparison EXAMPLES:: @@ -221,18 +215,18 @@ class _math_key(): cpdef math_sorted(expressions): """ - Sort a list of symbolic numbers in the "Mathematics" order + Sort a list of symbolic numbers in the "Mathematics" order. INPUT: - - ``expressions`` -- a list/tuple/iterable of symbolic - expressions, or something that can be converted to one. + - ``expressions`` -- list/tuple/iterable of symbolic + expressions, or something that can be converted to one OUTPUT: The list sorted by ascending (real) value. If an entry does not define a real value (or plus/minus infinity), or if the comparison - is not known, a ``ValueError`` is raised. + is not known, a :exc:`ValueError` is raised. EXAMPLES:: @@ -250,7 +244,7 @@ cpdef int mixed_order(lhs, rhs) except -2: INPUT: - ``lhs``, ``rhs`` -- two symbolic expressions or something that - can be converted to one. + can be converted to one OUTPUT: @@ -285,7 +279,6 @@ cpdef int mixed_order(lhs, rhs) except -2: 1 sage: mixed_order(log2, 0) 1 - """ if lhs is rhs: return 0 @@ -318,7 +311,7 @@ class _mixed_key(): INPUT: - ``ex`` -- symbolic expression or something that can be - converted into one. + converted into one EXAMPLES:: @@ -337,12 +330,10 @@ class _mixed_key(): INPUT: - - ``other`` -- another :class:`_mixed_key` instance. - - OUTPUT: + - ``other`` -- another :class:`_mixed_key` instance - Boolean. A ``ValueError`` is raised if we do not know how to - perform the comparison. + OUTPUT: boolean; a :exc:`ValueError` is raised if we do not know how to + perform the comparison EXAMPLES:: @@ -411,12 +402,12 @@ class _mixed_key(): cpdef mixed_sorted(expressions): """ - Sort a list of symbolic numbers in the "Mixed" order + Sort a list of symbolic numbers in the "Mixed" order. INPUT: - - ``expressions`` -- a list/tuple/iterable of symbolic - expressions, or something that can be converted to one. + - ``expressions`` -- list/tuple/iterable of symbolic + expressions, or something that can be converted to one OUTPUT: @@ -424,7 +415,7 @@ cpdef mixed_sorted(expressions): and the expressions with variables according to print order. If an entry does not define a real value (or plus/minus infinity), or if the comparison - is not known, a ``ValueError`` is raised. + is not known, a :exc:`ValueError` is raised. EXAMPLES:: diff --git a/src/sage/symbolic/complexity_measures.py b/src/sage/symbolic/complexity_measures.py index 528d1bf6906..a7b66fa5db0 100644 --- a/src/sage/symbolic/complexity_measures.py +++ b/src/sage/symbolic/complexity_measures.py @@ -9,15 +9,13 @@ def string_length(expr): """ - Returns the length of ``expr`` after converting it to a string. + Return the length of ``expr`` after converting it to a string. INPUT: - - ``expr`` -- the expression whose complexity we want to measure. + - ``expr`` -- the expression whose complexity we want to measure - OUTPUT: - - A real number representing the complexity of ``expr``. + OUTPUT: a real number representing the complexity of ``expr`` RATIONALE: @@ -32,6 +30,5 @@ def string_length(expr): sage: f = x^2 sage: string_length(f) 3 - """ return len(str(expr)) diff --git a/src/sage/symbolic/constants.py b/src/sage/symbolic/constants.py index f00cb29eedb..20a293fbb7b 100644 --- a/src/sage/symbolic/constants.py +++ b/src/sage/symbolic/constants.py @@ -273,8 +273,8 @@ def unpickle_Constant(class_name, name, conversions, latex, mathml, domain): @richcmp_method -class Constant(): - def __init__(self, name, conversions=None, latex=None, mathml="", +class Constant: + def __init__(self, name, conversions=None, latex=None, mathml='', domain='complex'): """ EXAMPLES:: @@ -323,7 +323,7 @@ def __richcmp__(self, other, op): def __reduce__(self): """ - Adds support for pickling constants. + Add support for pickling constants. EXAMPLES:: @@ -345,7 +345,6 @@ def __reduce__(self): 'positive')) sage: loads(dumps(pi.pyobject())) pi - """ return (unpickle_Constant, (self.__class__.__name__, self._name, self._conversions, self._latex, @@ -353,7 +352,7 @@ def __reduce__(self): def domain(self): """ - Returns the domain of this constant. This is either positive, + Return the domain of this constant. This is either positive, real, or complex, and is used by Pynac to make inferences about expressions containing this constant. @@ -370,7 +369,7 @@ def domain(self): def expression(self): """ - Returns an expression for this constant. + Return an expression for this constant. EXAMPLES:: @@ -387,7 +386,7 @@ def expression(self): def _symbolic_(self, SR): """ - Returns an expression for this constant. + Return an expression for this constant. INPUT: @@ -407,7 +406,7 @@ def _symbolic_(self, SR): def name(self): """ - Returns the name of this constant. + Return the name of this constant. EXAMPLES:: @@ -469,7 +468,6 @@ def _generic_interface(self, value, I): sage: m = partial(p._generic_interface, '%pi') sage: m(maxima) %pi - """ return I(value) @@ -491,7 +489,6 @@ def _generic_interface_init(self, value): sage: mi = partial(p._generic_interface_init, '%pi') sage: mi() '%pi' - """ return value @@ -519,7 +516,7 @@ def _interface_(self, I): def _gap_(self, gap): """ - Returns the constant as a string in GAP. Since GAP does not + Return the constant as a string in GAP. Since GAP does not have floating point numbers, we simply return the constant as a string. @@ -534,7 +531,7 @@ def _gap_(self, gap): def _singular_(self, singular): """ - Returns the constant as a string in Singular. Since Singular + Return the constant as a string in Singular. Since Singular does not always support floating point numbers, we simply return the constant as a string. (Singular allows floating point numbers if the current ring has floating point coefficients, @@ -551,7 +548,7 @@ def _singular_(self, singular): class Pi(Constant): - def __init__(self, name="pi"): + def __init__(self, name='pi'): r""" TESTS:: @@ -739,7 +736,7 @@ def _real_double_(self, R): def _sympy_(self): """ - Converts NaN to SymPy NaN. + Convert ``NaN`` to SymPy NaN. EXAMPLES:: @@ -758,7 +755,7 @@ def _sympy_(self): class GoldenRatio(Constant): """ - The number (1+sqrt(5))/2 + The number (1+sqrt(5))/2. EXAMPLES:: @@ -845,7 +842,7 @@ def _algebraic_(self, field): def _sympy_(self): """ - Converts golden_ratio to SymPy GoldenRation. + Convert ``golden_ratio`` to SymPy GoldenRatio. EXAMPLES:: @@ -1002,7 +999,7 @@ def _real_double_(self, R): def _sympy_(self): """ - Converts euler_gamma to SymPy EulerGamma. + Convert ``euler_gamma`` to SymPy EulerGamma. EXAMPLES:: @@ -1072,7 +1069,7 @@ def __float__(self): def _sympy_(self): """ - Converts catalan to SymPy Catalan. + Convert ``catalan`` to SymPy Catalan. EXAMPLES:: @@ -1123,7 +1120,6 @@ def _mpfr_(self, R): 2.6854520010653064453097148355 sage: RealField(100)(khinchin) 2.6854520010653064453097148355 - """ import sage.libs.mpmath.all as a return a.eval_constant('khinchin', R) @@ -1152,7 +1148,6 @@ class TwinPrime(Constant): 0.6601618158468696 sage: twinprime.n(digits=60) 0.660161815846869573927812110014555778432623360284733413319448 - """ def __init__(self, name='twinprime'): """ @@ -1201,7 +1196,6 @@ class Mertens(Constant): 0.26149721284764277 sage: mertens.n(digits=60) 0.261497212847642783755426838608695859051566648261199206192064 - """ def __init__(self, name='mertens'): """ @@ -1222,7 +1216,6 @@ def _mpfr_(self, R): 0.26149721284764278375542683861 sage: RealField(100)(mertens) 0.26149721284764278375542683861 - """ import sage.libs.mpmath.all as a return a.eval_constant('mertens', R) @@ -1255,7 +1248,6 @@ class Glaisher(Constant): glaisher + 2 sage: parent(a) Symbolic Ring - """ def __init__(self, name='glaisher'): """ @@ -1277,7 +1269,6 @@ def _mpfr_(self, R): 1.2824271291006226368753425689 sage: RealField(100)(glaisher) 1.2824271291006226368753425689 - """ import sage.libs.mpmath.all as a return a.eval_constant('glaisher', R) diff --git a/src/sage/symbolic/constants_c_impl.pxi b/src/sage/symbolic/constants_c_impl.pxi index 63a90c71fd9..0ebd28e8aa3 100644 --- a/src/sage/symbolic/constants_c_impl.pxi +++ b/src/sage/symbolic/constants_c_impl.pxi @@ -159,7 +159,7 @@ cdef class E(Expression): [e 0] [0 e] sage: A = matrix(RDF, [[1,2],[3,4]]) - sage: e^A # rel tol 1e-14 + sage: e^A # rel tol 5e-14 [51.968956198705044 74.73656456700327] [112.10484685050491 164.07380304920997] """ diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index a92fe241355..f221fd64de0 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -1,4 +1,4 @@ -# distutils: sources = sage/symbolic/ginac/add.cpp sage/symbolic/ginac/archive.cpp sage/symbolic/ginac/assume.cpp sage/symbolic/ginac/basic.cpp sage/symbolic/ginac/cmatcher.cpp sage/symbolic/ginac/constant.cpp sage/symbolic/ginac/context.cpp sage/symbolic/ginac/ex.cpp sage/symbolic/ginac/expair.cpp sage/symbolic/ginac/expairseq.cpp sage/symbolic/ginac/exprseq.cpp sage/symbolic/ginac/fderivative.cpp sage/symbolic/ginac/function.cpp sage/symbolic/ginac/function_info.cpp sage/symbolic/ginac/infinity.cpp sage/symbolic/ginac/infoflagbase.cpp sage/symbolic/ginac/inifcns.cpp sage/symbolic/ginac/inifcns_comb.cpp sage/symbolic/ginac/inifcns_gamma.cpp sage/symbolic/ginac/inifcns_hyperb.cpp sage/symbolic/ginac/inifcns_hyperg.cpp sage/symbolic/ginac/inifcns_nstdsums.cpp sage/symbolic/ginac/inifcns_orthopoly.cpp sage/symbolic/ginac/inifcns_trans.cpp sage/symbolic/ginac/inifcns_trig.cpp sage/symbolic/ginac/inifcns_zeta.cpp sage/symbolic/ginac/lst.cpp sage/symbolic/ginac/matrix.cpp sage/symbolic/ginac/mpoly-giac.cpp sage/symbolic/ginac/mpoly-ginac.cpp sage/symbolic/ginac/mpoly-singular.cpp sage/symbolic/ginac/mpoly.cpp sage/symbolic/ginac/mul.cpp sage/symbolic/ginac/normal.cpp sage/symbolic/ginac/numeric.cpp sage/symbolic/ginac/operators.cpp sage/symbolic/ginac/order.cpp sage/symbolic/ginac/power.cpp sage/symbolic/ginac/print.cpp sage/symbolic/ginac/pseries.cpp sage/symbolic/ginac/py_funcs.cpp sage/symbolic/ginac/registrar.cpp sage/symbolic/ginac/relational.cpp sage/symbolic/ginac/remember.cpp sage/symbolic/ginac/sum.cpp sage/symbolic/ginac/symbol.cpp sage/symbolic/ginac/templates.cpp sage/symbolic/ginac/upoly-ginac.cpp sage/symbolic/ginac/useries.cpp sage/symbolic/ginac/utils.cpp sage/symbolic/ginac/wildcard.cpp +# distutils: sources = sage/symbolic/ginac/add.cpp sage/symbolic/ginac/archive.cpp sage/symbolic/ginac/assume.cpp sage/symbolic/ginac/basic.cpp sage/symbolic/ginac/cmatcher.cpp sage/symbolic/ginac/constant.cpp sage/symbolic/ginac/context.cpp sage/symbolic/ginac/ex.cpp sage/symbolic/ginac/expair.cpp sage/symbolic/ginac/expairseq.cpp sage/symbolic/ginac/exprseq.cpp sage/symbolic/ginac/fderivative.cpp sage/symbolic/ginac/function.cpp sage/symbolic/ginac/function_info.cpp sage/symbolic/ginac/infinity.cpp sage/symbolic/ginac/infoflagbase.cpp sage/symbolic/ginac/inifcns.cpp sage/symbolic/ginac/inifcns_comb.cpp sage/symbolic/ginac/inifcns_gamma.cpp sage/symbolic/ginac/inifcns_hyperb.cpp sage/symbolic/ginac/inifcns_hyperg.cpp sage/symbolic/ginac/inifcns_nstdsums.cpp sage/symbolic/ginac/inifcns_orthopoly.cpp sage/symbolic/ginac/inifcns_trans.cpp sage/symbolic/ginac/inifcns_trig.cpp sage/symbolic/ginac/inifcns_zeta.cpp sage/symbolic/ginac/lst.cpp sage/symbolic/ginac/matrix.cpp sage/symbolic/ginac/mpoly-ginac.cpp sage/symbolic/ginac/mpoly-singular.cpp sage/symbolic/ginac/mpoly.cpp sage/symbolic/ginac/mul.cpp sage/symbolic/ginac/normal.cpp sage/symbolic/ginac/numeric.cpp sage/symbolic/ginac/operators.cpp sage/symbolic/ginac/order.cpp sage/symbolic/ginac/power.cpp sage/symbolic/ginac/print.cpp sage/symbolic/ginac/pseries.cpp sage/symbolic/ginac/py_funcs.cpp sage/symbolic/ginac/registrar.cpp sage/symbolic/ginac/relational.cpp sage/symbolic/ginac/remember.cpp sage/symbolic/ginac/sum.cpp sage/symbolic/ginac/symbol.cpp sage/symbolic/ginac/templates.cpp sage/symbolic/ginac/upoly-ginac.cpp sage/symbolic/ginac/useries.cpp sage/symbolic/ginac/utils.cpp sage/symbolic/ginac/wildcard.cpp # distutils: language = c++ # distutils: libraries = flint gmp SINGULAR_LIBRARIES # distutils: extra_compile_args = -std=c++11 SINGULAR_CFLAGS @@ -156,8 +156,8 @@ Test that :issue:`20784` is fixed (equations should stay unevaluated):: Many tests about comparison. -Use :func:`sage.symbolic.expression.mixed_order`` instead of -the operators <=, <, etc. to compare symbolic expressions when +Use :func:`sage.symbolic.expression.mixed_order` instead of +the operators ``<=``, ``<``, etc. to compare symbolic expressions when you do not want to get a formal inequality:: sage: from sage.symbolic.expression import mixed_order @@ -410,7 +410,7 @@ from sage.symbolic.symbols import symbol_table, register_symbol # used to be de cpdef bint is_SymbolicEquation(x) noexcept: """ - Return True if *x* is a symbolic equation. + Return ``True`` if ``x`` is a symbolic equation. This function is deprecated. @@ -441,7 +441,6 @@ cpdef bint is_SymbolicEquation(x) noexcept: sage: is_SymbolicEquation(SR(2) == SR(3)) True - """ from sage.misc.superseded import deprecation deprecation(35505, @@ -484,7 +483,7 @@ def _dict_update_check_duplicate(dict d1, dict d2): Merge the dictionary ``d2`` into ``d1`` and check for duplicates. The two dictionaries must be of the form ``{expr: replacement}``. This - function throws a :class:`ValueError` if any expressions are substituted + function throws a :exc:`ValueError` if any expressions are substituted for twice. EXAMPLES: @@ -519,7 +518,6 @@ def _dict_update_check_duplicate(dict d1, dict d2): Traceback (most recent call last): ... ValueError: duplicate substitution for a, got values 1 and 2 - """ # We need to check for duplicates in a predictable order so that # errors are reported reliably. We only need to sort one of the @@ -552,11 +550,9 @@ def _subs_make_dict(s): INPUT: - - ``s`` -- A representation of a substitution. + - ``s`` -- a representation of a substitution - OUTPUT: - - A dictionary of substitutions. + OUTPUT: a dictionary of substitutions EXAMPLES: @@ -587,7 +583,7 @@ def _subs_make_dict(s): sage: actual == expected True - Check that a :class:`TypeError` is raised if the input is not valid:: + Check that a :exc:`TypeError` is raised if the input is not valid:: sage: _subs_make_dict(1) Traceback (most recent call last): @@ -629,11 +625,9 @@ def _subs_fun_make_dict(s): INPUT: - - ``s`` -- A representation of a substitution. - - OUTPUT: + - ``s`` -- a representation of a substitution - A dictionary of substitutions. + OUTPUT: a dictionary of substitutions EXAMPLES: @@ -666,7 +660,7 @@ def _subs_fun_make_dict(s): sage: actual == expected True - Check that a :class:`TypeError` is raised if the input is not valid:: + Check that a :exc:`TypeError` is raised if the input is not valid:: sage: _subs_fun_make_dict(1) Traceback (most recent call last): @@ -711,7 +705,7 @@ cdef class Expression(Expression_abc): The Python object corresponding to this expression, assuming this expression is a single numerical value or an infinity - representable in Python. Otherwise, a :class:`TypeError` is raised. + representable in Python. Otherwise, a :exc:`TypeError` is raised. EXAMPLES:: @@ -804,7 +798,7 @@ cdef class Expression(Expression_abc): * 0 - as pickle version number in case we decide to change the pickle format in the feature * names of symbols of this expression - * a string representation of self stored in a Pynac archive. + * a string representation of ``self`` stored in a Pynac archive. TESTS:: @@ -963,7 +957,6 @@ cdef class Expression(Expression_abc): sage: with SR.temp_var() as t: pass sage: symbols_copy == SR.symbols True - """ from sage.symbolic.ring import SR SR.cleanup_var(self) @@ -1066,12 +1059,10 @@ cdef class Expression(Expression_abc): INPUT: - - ``use_unicode`` -- boolean. Whether to allow unicode instead - of 7-bit clean output. - - OUTPUT: + - ``use_unicode`` -- boolean; whether to allow unicode instead + of 7-bit clean output - String. + OUTPUT: string EXAMPLES:: @@ -1167,7 +1158,7 @@ cdef class Expression(Expression_abc): sage: unicode_art(SR(13 - I)) 13 - ⅈ sage: unicode_art(SR(1.3 - I)) - 1.3 - ⅈ + 1.3 - ...ⅈ sage: unicode_art(cos(I)) cosh(1) @@ -1218,7 +1209,6 @@ cdef class Expression(Expression_abc): sage: var('ξ')._maxima_() _SAGE_VAR_ξ - """ if session is None: # This chooses the Maxima interface used by calculus @@ -1463,7 +1453,6 @@ cdef class Expression(Expression_abc): π sage: mathml(pi+2) MATHML version of the string pi + 2 - """ from sage.misc.mathml import mathml try: @@ -1925,11 +1914,9 @@ cdef class Expression(Expression_abc): """ Return float conversion of ``self``, assuming ``self`` is constant. - Otherwise, raise a :class:`TypeError`. - - OUTPUT: + Otherwise, raise a :exc:`TypeError`. - A ``float``. Double precision evaluation of ``self``. + OUTPUT: a ``float``. Double precision evaluation of ``self`` EXAMPLES:: @@ -1989,7 +1976,6 @@ cdef class Expression(Expression_abc): pi sage: type(_) - """ from sage.symbolic.expression_conversions import sympy_converter return sympy_converter(self) @@ -2002,7 +1988,6 @@ cdef class Expression(Expression_abc): sage: pi._fricas_() # optional - fricas %pi - """ from sage.symbolic.expression_conversions import fricas_converter return fricas_converter(self) @@ -2308,7 +2293,7 @@ cdef class Expression(Expression_abc): sage: x == 0 x == 0 - In particular, it does not return a bool, so the following check does + In particular, it does not return a boolean, so the following check does not hold anymore:: sage: (not x) == (x != 0) @@ -2317,7 +2302,6 @@ cdef class Expression(Expression_abc): TESTS:: sage: x._test_nonzero_equal() - """ pass @@ -2330,8 +2314,8 @@ cdef class Expression(Expression_abc): sage: (x > 2).assume() - Bool returns True below if the inequality is *definitely* known to - be True. + ``bool`` returns ``True`` below if the inequality is *definitely* known + to be true. :: @@ -2340,7 +2324,7 @@ cdef class Expression(Expression_abc): sage: bool(x < 0) False - This may or may not be True, so bool returns False:: + This may or may not be True, so ``bool`` returns False:: sage: bool(x > 3) False @@ -2523,7 +2507,7 @@ cdef class Expression(Expression_abc): def is_algebraic(self): """ - Return True if this expression is known to be algebraic. + Return ``True`` if this expression is known to be algebraic. EXAMPLES:: @@ -2582,7 +2566,7 @@ cdef class Expression(Expression_abc): def is_real(self): """ - Return True if this expression is known to be a real number. + Return ``True`` if this expression is known to be a real number. EXAMPLES:: @@ -2657,7 +2641,7 @@ cdef class Expression(Expression_abc): def is_positive(self): """ - Return True if this expression is known to be positive. + Return ``True`` if this expression is known to be positive. EXAMPLES:: @@ -2753,7 +2737,7 @@ cdef class Expression(Expression_abc): def is_negative(self): """ - Return True if this expression is known to be negative. + Return ``True`` if this expression is known to be negative. EXAMPLES:: @@ -2784,7 +2768,7 @@ cdef class Expression(Expression_abc): def is_integer(self): """ - Return True if this expression is known to be an integer. + Return ``True`` if this expression is known to be an integer. EXAMPLES:: @@ -2811,7 +2795,7 @@ cdef class Expression(Expression_abc): def is_symbol(self): """ - Return True if this symbolic expression consists of only a symbol, i.e., + Return ``True`` if this symbolic expression consists of only a symbol, i.e., a symbolic variable. EXAMPLES:: @@ -2898,7 +2882,7 @@ cdef class Expression(Expression_abc): """ A Pynac numeric is an object you can do arithmetic with that is not a symbolic variable, function, or constant. - Return True if this expression only consists of a numeric object. + Return ``True`` if this expression only consists of a numeric object. EXAMPLES:: @@ -2915,17 +2899,15 @@ cdef class Expression(Expression_abc): def is_terminating_series(self): """ - Return True if ``self`` is a series without order term. + Return ``True`` if ``self`` is a series without order term. A series is terminating if it can be represented exactly, without requiring an order term. You can explicitly request terminating series by setting the order to positive infinity. - OUTPUT: - - Boolean. Whether ``self`` was constructed by :meth:`series` - and has no order term. + OUTPUT: boolean; whether ``self`` was constructed by :meth:`series` + and has no order term EXAMPLES:: @@ -3134,7 +3116,6 @@ cdef class Expression(Expression_abc): ... NotImplementedError: is_square() not implemented for non-constant or relational elements of Symbolic Ring - """ if self.is_constant() and not self.is_relational(): # The square root of any "number" is in SR... just call @@ -3167,7 +3148,7 @@ cdef class Expression(Expression_abc): def left_hand_side(self): """ If ``self`` is a relational expression, return the left hand side - of the relation. Otherwise, raise a :class:`ValueError`. + of the relation. Otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -3189,7 +3170,7 @@ cdef class Expression(Expression_abc): def right_hand_side(self): """ If ``self`` is a relational expression, return the right hand side - of the relation. Otherwise, raise a :class:`ValueError`. + of the relation. Otherwise, raise a :exc:`ValueError`. EXAMPLES:: @@ -3301,7 +3282,7 @@ cdef class Expression(Expression_abc): def __bool__(self): """ - Return True unless this symbolic expression can be shown by Sage + Return ``True`` unless this symbolic expression can be shown by Sage to be zero. Note that deciding if an expression is zero is undecidable in general. @@ -3541,28 +3522,26 @@ cdef class Expression(Expression_abc): test this relation after casting into the domain. Because the interval fields never return false positives, we can be - assured that if True or False is returned (and proof is False) then - the answer is correct. + assured that if ``True`` or ``False`` is returned (and proof is + ``False``) then the answer is correct. INPUT: - - ``ntests`` -- (default ``20``) the number of iterations to run + - ``ntests`` -- (default: 20) the number of iterations to run - ``domain`` -- (optional) the domain from which to draw the random values defaults to ``CIF`` for equality testing and ``RIF`` for order testing - - ``proof`` -- (default ``True``) if ``False`` and the domain is an + - ``proof`` -- (default: ``True``) if ``False`` and the domain is an interval field, regard overlapping (potentially equal) intervals as equal, and return ``True`` if all tests succeeded. - OUTPUT: - - Boolean or ``NotImplemented``, meaning + OUTPUT: boolean or ``NotImplemented``, meaning - - ``True`` -- this relation holds in the domain and has no variables. + - ``True`` -- this relation holds in the domain and has no variables - - ``False`` -- a contradiction was found. + - ``False`` -- a contradiction was found - - ``NotImplemented`` -- no contradiction found. + - ``NotImplemented`` -- no contradiction found EXAMPLES:: @@ -3623,7 +3602,6 @@ cdef class Expression(Expression_abc): sage: v = -53985/17179869184 sage: bool(abs(t) < 1.213*2^-56*v^4) True - """ cdef int k, eq_count = 0 cdef bint is_interval @@ -3727,7 +3705,7 @@ cdef class Expression(Expression_abc): """ Return the negated version of ``self``. - This is the relation that is ``False`` iff self is ``True``. + This is the relation that is ``False`` iff ``self`` is ``True``. EXAMPLES:: @@ -3777,7 +3755,7 @@ cdef class Expression(Expression_abc): def is_unit(self): """ - Return True if this expression is a unit of the symbolic ring. + Return ``True`` if this expression is a unit of the symbolic ring. Note that a proof may be attempted to get the result. To avoid this use ``(ex-1).is_trivial_zero()``. @@ -4250,11 +4228,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``right`` -- A :class:`Expression` instance. - - OUTPUT: + - ``right`` -- a :class:`Expression` instance - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -4278,11 +4254,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``right`` -- A :class:`Expression` instance. + - ``right`` -- a :class:`Expression` instance - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -4304,9 +4278,7 @@ cdef class Expression(Expression_abc): r""" Return ``self`` raised to the power ``other``. - OUTPUT: - - A symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -4492,7 +4464,7 @@ cdef class Expression(Expression_abc): Check that :issue:`31137` is also fixed:: - sage: _ = var('A, L, G, R, f, k, n, q, u, beta, gamma', domain="positive") + sage: _ = var('A, L, G, R, f, k, n, q, u, beta, gamma', domain='positive') sage: a = I*R^2*f^3*k*q*A*u sage: b = 2*pi*L*R^2*G*f^4*k^2*q - 2*pi*L*R^2*G*f^4*q - 2*pi*L*R^2*beta^2*G*q sage: c = (2*I*pi*L*R^2*beta*gamma*q + 2*I*pi*L*R*(beta + q))*G*f^3 @@ -4758,7 +4730,6 @@ cdef class Expression(Expression_abc): of scalar fields on Euclidean spaces (and more generally pseudo-Riemannian manifolds), in particular for computing the gradient in curvilinear coordinates. - """ from sage.modules.free_module_element import vector if variables is None: @@ -4797,13 +4768,11 @@ cdef class Expression(Expression_abc): such as ``x == 5``; if an equality is given, the expansion is around the value on the right hand side of the equality - - ``order`` -- an integer; if nothing given, it is set + - ``order`` -- integer; if nothing given, it is set to the global default (``20``), which can be changed using :func:`set_series_precision` - OUTPUT: - - A power series. + OUTPUT: a power series To truncate the power series and obtain a normal expression, use the :meth:`truncate` command. @@ -4938,9 +4907,7 @@ cdef class Expression(Expression_abc): around the value on the right hand side of the equality, otherwise at ``0``. - OUTPUT: - - The residue of ``self``. + OUTPUT: the residue of ``self`` Say, ``symbol`` is ``x == a``, then this function calculates the residue of ``self`` at `x=a`, i.e., the coefficient of @@ -5008,7 +4975,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``*args`` -- the following notation is supported + - ``*args`` -- the following notation is supported - ``x``, ``a``, ``n`` -- variable, point, degree @@ -5084,11 +5051,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``self`` -- a series as output by the :meth:`series` command. + - ``self`` -- a series as output by the :meth:`series` command - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -5252,26 +5217,24 @@ cdef class Expression(Expression_abc): INPUT: - - ``full`` -- (default: ``False``) To enhance user control - of simplification, this function expands only one level at a time - by default, expanding sums of angles or multiple angles. To obtain - full expansion into sines and cosines immediately, set the optional - parameter full to ``True``. - - - ``half_angles`` -- (default: ``False``) If ``True``, causes - half-angles to be simplified away. + - ``full`` -- boolean (default: ``False``); to enhance user control + of simplification, this function expands only one level at a time + by default, expanding sums of angles or multiple angles. To obtain + full expansion into sines and cosines immediately, set the optional + parameter full to ``True``. - - ``plus`` -- (default: ``True``) Controls the sum rule; - expansion of sums (e.g. `\sin(x + y)`) will take place only - if ``plus`` is ``True``. + - ``half_angles`` -- boolean (default: ``False``); if ``True``, causes + half-angles to be simplified away - - ``times`` -- (default: ``True``) Controls the product - rule, expansion of products (e.g. `\sin(2 x)`) will take place only - if ``times`` is ``True``. + - ``plus`` -- boolean (default: ``True``); controls the sum rule. + Expansion of sums (e.g. `\sin(x + y)`) will take place only if + ``plus`` is ``True``. - OUTPUT: + - ``times`` -- boolean (default: ``True``); controls the product + rule, expansion of products (e.g. `\sin(2 x)`) will take place only + if ``times`` is ``True``. - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -5339,9 +5302,7 @@ cdef class Expression(Expression_abc): these transformations. If not specified, all variables are used. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -5377,13 +5338,11 @@ cdef class Expression(Expression_abc): INPUT: - - ``pattern`` -- a symbolic expression, possibly containing wildcards - to match for + - ``pattern`` -- a symbolic expression, possibly containing wildcards + to match for OUTPUT: - One of - ``None`` if there is no match, or a dictionary mapping the wildcards to the matching values if a match was found. Note that the dictionary is empty if there were no wildcards in the @@ -5887,12 +5846,12 @@ cdef class Expression(Expression_abc): if kwds: # Ensure that the keys are symbolic variables. - varkwds = {self._parent.var(k): v for k,v in kwds.iteritems()} + varkwds = {self._parent.var(k): v for k,v in kwds.items()} # Check for duplicate _dict_update_check_duplicate(sdict, varkwds) cdef GExMap smap - for k, v in sdict.iteritems(): + for k, v in sdict.items(): smap.insert(make_pair((self.coerce_in(k))._gobj, (self.coerce_in(v))._gobj)) res = self._gobj.subs_map(smap, 0) @@ -6040,7 +5999,7 @@ cdef class Expression(Expression_abc): if kwds: # Ensure that the keys are functions. - funkwds = {_find_func(k): v for k,v in kwds.iteritems()} + funkwds = {_find_func(k): v for k,v in kwds.items()} # Check for duplicate _dict_update_check_duplicate(sdict, funkwds) @@ -6123,6 +6082,44 @@ cdef class Expression(Expression_abc): from sage.symbolic.expression_conversions import DeMoivre return DeMoivre(self, force)() + def half_angle(self): + """ + Replace all occurrences of trigonometric (or hyperbolic) + functions by rational fractions of the (hyperbolic) tangent + of half the original argument. + + This can help highlight the algebraic structure of an expression, + which can be useful e.g. for integration. + + This method has no direct relation with the ``half_angles`` + argument of the :meth:`trig_expand` method. + + EXAMPLES:: + + sage: x, t = var("x, t") + sage: cos(x).half_angle().subs(tan(x/2) == t) + -(t^2 - 1)/(t^2 + 1) + + Note that this structure highlighting works better after expansion:: + + sage: x, t = var("x, t") + sage: a = (cos(3*x)/(4-cos(x))) + sage: b = a.trig_expand() + sage: a.half_angle().subs(tan(x/2) == t).simplify_full() + (2*(t^2 + 1)*cos(3/2*x)^2 - t^2 - 1)/(5*t^2 + 3) + sage: b.half_angle().subs(tan(x/2) == t).simplify_full() + -(t^6 - 15*t^4 + 15*t^2 - 1)/(5*t^6 + 13*t^4 + 11*t^2 + 3) + + TESTS:: + + sage: all((u(x) == u(x).half_angle()).subs(x == 2*x).trig_simplify() + ....: for u in (sin, cos, tan, csc, sec, cot, + ....: sinh, cosh, tanh, csch, sech, coth)) + True + """ + from sage.symbolic.expression_conversions import HalfAngle + return HalfAngle(self)() + def substitution_delayed(self, pattern, replacement): """ Replace all occurrences of pattern by the result of replacement. @@ -6133,18 +6130,15 @@ cdef class Expression(Expression_abc): INPUT: - - ``pattern`` -- an :class:`Expression`, usually - containing wildcards. + - ``pattern`` -- an :class:`Expression`, usually containing wildcards - - ``replacement`` -- a function. Its argument is a dictionary + - ``replacement`` -- a function; its argument is a dictionary mapping the wildcard occurring in ``pattern`` to the actual values. If it returns ``None``, this occurrence of ``pattern`` is not replaced. Otherwise, it is replaced by the output of ``replacement``. - OUTPUT: - - An :class:`Expression`. + OUTPUT: an :class:`Expression` EXAMPLES:: @@ -6200,7 +6194,6 @@ cdef class Expression(Expression_abc): (x, y) sage: sin(x+y^z).variables() (x, y, z) - """ from sage.symbolic.ring import SR cdef GExSet sym_set @@ -6258,7 +6251,6 @@ cdef class Expression(Expression_abc): sage: g = f.function(x) sage: g.arguments() (x,) - """ try: return self._parent.arguments() @@ -6812,7 +6804,6 @@ cdef class Expression(Expression_abc): sage: a = (x^2).power(2, hold=True); a.unhold() x^4 - """ cdef Expression nexp = self.coerce_in(exp) return new_Expression_from_GEx(self._parent, @@ -6874,7 +6865,6 @@ cdef class Expression(Expression_abc): sage: a = x.mul(x, hold=True); a.unhold() x^2 - """ nargs = [self.coerce_in(x) for x in args] cdef GExVector vec @@ -6897,9 +6887,7 @@ cdef class Expression(Expression_abc): - ``n`` -- expression, default 1 - OUTPUT: - - A symbolic expression. The coefficient of `s^n`. + OUTPUT: a symbolic expression. The coefficient of `s^n` Sometimes it may be necessary to expand or factor first, since this is not done automatically. @@ -6996,17 +6984,15 @@ cdef class Expression(Expression_abc): INPUT: - - ``x`` -- optional variable. + - ``x`` -- (optional) variable - OUTPUT: - - Depending on the value of ``sparse``, + OUTPUT: depending on the value of ``sparse``, - A list of pairs ``(expr, n)``, where ``expr`` is a symbolic expression and ``n`` is a power (``sparse=True``, default) - A list of expressions where the ``n``-th element is the coefficient of - ``x^n`` when self is seen as polynomial in ``x`` (``sparse=False``). + ``x^n`` when ``self`` is seen as polynomial in ``x`` (``sparse=False``). EXAMPLES:: @@ -7123,12 +7109,12 @@ cdef class Expression(Expression_abc): INPUT: - - ``x`` -- optional variable. + - ``x`` -- (optional) variable OUTPUT: A list of expressions where the ``n``-th element is the coefficient of - ``x^n`` when self is seen as polynomial in ``x``. + ``x^n`` when ``self`` is seen as polynomial in ``x``. EXAMPLES:: @@ -7180,8 +7166,8 @@ cdef class Expression(Expression_abc): def trailing_coefficient(self, s): """ - Return the trailing coefficient of s in self, i.e., the coefficient - of the smallest power of s in self. + Return the trailing coefficient of s in ``self``, i.e., the coefficient + of the smallest power of s in ``self``. EXAMPLES:: @@ -7211,9 +7197,7 @@ cdef class Expression(Expression_abc): """ Return the exponent of the lowest power of ``s`` in ``self``. - OUTPUT: - - An integer + OUTPUT: integer EXAMPLES:: @@ -7244,9 +7228,7 @@ cdef class Expression(Expression_abc): """ Return the exponent of the highest power of ``s`` in ``self``. - OUTPUT: - - An integer + OUTPUT: integer EXAMPLES:: @@ -7283,7 +7265,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``s`` -- a symbolic expression. + - ``s`` -- a symbolic expression OUTPUT: @@ -7322,7 +7304,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``s`` -- a symbolic expression. + - ``s`` -- a symbolic expression OUTPUT: @@ -7367,7 +7349,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``s`` -- a symbolic expression. + - ``s`` -- a symbolic expression OUTPUT: @@ -7496,9 +7478,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``base_ring`` -- (optional) the base ring for the polynomial + - ``base_ring`` -- (optional) the base ring for the polynomial - - ``ring`` -- (optional) the parent for the polynomial + - ``ring`` -- (optional) the parent for the polynomial .. warning:: @@ -7521,7 +7503,7 @@ cdef class Expression(Expression_abc): [[-5, 0], [6, 2]] sage: g.polynomial(QQ).list() [-5, 0, 6] - sage: g.polynomial(QQ).dict() + sage: g.polynomial(QQ).monomial_coefficients() {0: -5, 2: 6} :: @@ -7588,7 +7570,6 @@ cdef class Expression(Expression_abc): sage: B = f.polynomial(ring=SR['x,y']) sage: B.coefficients() [a, 3] - """ from sage.symbolic.expression_conversions import polynomial return polynomial(self, base_ring=base_ring, ring=ring) @@ -7600,9 +7581,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``base_ring`` -- (optional) the base ring for the polynomial + - ``base_ring`` -- (optional) the base ring for the polynomial - - ``ring`` -- (optional) the parent for the polynomial + - ``ring`` -- (optional) the parent for the polynomial You can specify either the base ring (``base_ring``) you want the output Laurent polynomial to be over, or you can specify the full @@ -7710,10 +7691,10 @@ cdef class Expression(Expression_abc): TypeError: y is not a variable of Multivariate Polynomial Ring in x over Ring of integers modulo 4 """ from sage.symbolic.ring import SR - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base base_ring = R.base_ring() if base_ring == SR: - if is_MPolynomialRing(R): + if isinstance(R, MPolynomialRing_base): return R({tuple([0]*R.ngens()):self}) else: return R([self]) @@ -8027,15 +8008,14 @@ cdef class Expression(Expression_abc): """ Return the lcm of ``self`` and ``b``. - The lcm is computed from the gcd of ``self`` and ``b`` - implicitly from the - relation self * b = gcd(self, b) * lcm(self, b). + The lcm is computed from the gcd of ``self`` and ``b`` implicitly from + the relation ``self * b = gcd(self, b) * lcm(self, b)``. .. NOTE:: In agreement with the convention in use for integers, if - self * b == 0, then gcd(self, b) == max(self, b) and - lcm(self, b) == 0. + ``self * b == 0``, then ``gcd(self, b) == max(self, b)`` and + ``lcm(self, b) == 0``. .. NOTE:: @@ -8086,7 +8066,6 @@ cdef class Expression(Expression_abc): (x, 0) sage: gcd(SR(0), SR(0)), lcm(SR(0), SR(0)) (0, 0) - """ sb = self * b try: @@ -8132,7 +8111,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``s`` -- the symbol whose coefficients will be collected. + - ``s`` -- the symbol whose coefficients will be collected OUTPUT: @@ -8430,20 +8409,19 @@ cdef class Expression(Expression_abc): 1 sage: SR(2).step(hold=True) unit_step(2) - """ return new_Expression_from_GEx(self._parent, g_hold_wrapper(g_step, self._gobj, hold)) def csgn(self, hold=False): """ - Return the sign of self, which is -1 if self < 0, 0 if self == - 0, and 1 if self > 0, or unevaluated when self is a nonconstant - symbolic expression. + Return the sign of ``self``, which is -1 if ``self < 0``, 0 if + ``self == 0``, and 1 if ``self > 0``, or unevaluated when ``self`` is a + nonconstant symbolic expression. - If self is not real, return the complex half-plane (left or right) - in which the number lies. If self is pure imaginary, return the sign - of the imaginary part of self. + If ``self`` is not real, return the complex half-plane (left or right) + in which the number lies. If ``self`` is pure imaginary, return the sign + of the imaginary part of ``self``. EXAMPLES:: @@ -8476,7 +8454,6 @@ cdef class Expression(Expression_abc): sage: SR(I).csgn(hold=True) csgn(I) - """ return new_Expression_from_GEx(self._parent, g_hold_wrapper(g_csgn, self._gobj, hold)) @@ -8525,7 +8502,6 @@ cdef class Expression(Expression_abc): sage: a = SR(I).conjugate(hold=True); a.unhold() -I - """ return new_Expression_from_GEx(self._parent, g_hold_wrapper(g_conjugate, self._gobj, hold)) @@ -8709,7 +8685,7 @@ cdef class Expression(Expression_abc): def sqrt(self, hold=False): """ - Return the square root of this expression + Return the square root of this expression. EXAMPLES:: @@ -8830,7 +8806,7 @@ cdef class Expression(Expression_abc): def cos(self, hold=False): """ - Return the cosine of self. + Return the cosine of ``self``. EXAMPLES:: @@ -8996,7 +8972,7 @@ cdef class Expression(Expression_abc): def arccos(self, hold=False): """ - Return the arc cosine of self. + Return the arc cosine of ``self``. EXAMPLES:: @@ -9046,7 +9022,7 @@ cdef class Expression(Expression_abc): def arctan(self, hold=False): """ - Return the arc tangent of self. + Return the arc tangent of ``self``. EXAMPLES:: @@ -9095,7 +9071,7 @@ cdef class Expression(Expression_abc): def arctan2(self, x, hold=False): """ - Return the inverse of the 2-variable tan function on self and x. + Return the inverse of the 2-variable tan function on ``self`` and ``x``. EXAMPLES:: @@ -9199,7 +9175,7 @@ cdef class Expression(Expression_abc): def sinh(self, hold=False): r""" - Return sinh of self. + Return sinh of ``self``. We have `\sinh(x) = (e^{x} - e^{-x})/2`. @@ -9257,7 +9233,7 @@ cdef class Expression(Expression_abc): def cosh(self, hold=False): r""" - Return cosh of self. + Return cosh of ``self``. We have `\cosh(x) = (e^{x} + e^{-x})/2`. @@ -9313,7 +9289,7 @@ cdef class Expression(Expression_abc): def tanh(self, hold=False): r""" - Return tanh of self. + Return tanh of ``self``. We have `\tanh(x) = \sinh(x) / \cosh(x)`. @@ -9367,7 +9343,7 @@ cdef class Expression(Expression_abc): def arcsinh(self, hold=False): """ - Return the inverse hyperbolic sine of self. + Return the inverse hyperbolic sine of ``self``. EXAMPLES:: @@ -9469,7 +9445,7 @@ cdef class Expression(Expression_abc): def arctanh(self, hold=False): """ - Return the inverse hyperbolic tangent of self. + Return the inverse hyperbolic tangent of ``self``. EXAMPLES:: @@ -9525,9 +9501,9 @@ cdef class Expression(Expression_abc): g_hold_wrapper(g_atanh, self._gobj, hold)) def exp(self, hold=False): - """ - Return exponential function of self, i.e., e to the - power of self. + r""" + Return exponential function of ``self``, i.e., `e` to the + power of ``self``. EXAMPLES:: @@ -9582,7 +9558,7 @@ cdef class Expression(Expression_abc): def log(self, b=None, hold=False): """ - Return the logarithm of self. + Return the logarithm of ``self``. EXAMPLES:: @@ -9687,11 +9663,9 @@ cdef class Expression(Expression_abc): def factorial(self, hold=False): """ - Return the factorial of self. + Return the factorial of ``self``. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -9733,9 +9707,7 @@ cdef class Expression(Expression_abc): """ Return binomial coefficient "self choose k". - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -9787,9 +9759,7 @@ cdef class Expression(Expression_abc): """ Return the order of the expression, as in big oh notation. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -9809,7 +9779,7 @@ cdef class Expression(Expression_abc): def gamma(self, *, hold=False): """ - Return the Gamma function evaluated at self. + Return the Gamma function evaluated at ``self``. EXAMPLES:: @@ -9919,7 +9889,7 @@ cdef class Expression(Expression_abc): def default_variable(self): """ Return the default variable, which is by definition the first - variable in self, or `x` is there are no variables in self. + variable in ``self``, or `x` if there are no variables in ``self``. The result is cached. EXAMPLES:: @@ -9985,7 +9955,7 @@ cdef class Expression(Expression_abc): def normalize(self): """ - Return this expression normalized as a fraction + Return this expression normalized as a fraction. .. SEEALSO:: @@ -10031,7 +10001,6 @@ cdef class Expression(Expression_abc): (e^(4*pi) - 1)/e^(2*pi) ALGORITHM: Uses GiNaC. - """ cdef GEx r sig_on() @@ -10043,11 +10012,11 @@ cdef class Expression(Expression_abc): def numerator(self, bint normalize = True): """ - Return the numerator of this symbolic expression + Return the numerator of this symbolic expression. INPUT: - - ``normalize`` -- (default: ``True``) a boolean. + - ``normalize`` -- boolean (default: ``True``) If ``normalize`` is ``True``, the expression is first normalized to have it as a fraction before getting the numerator. @@ -10139,11 +10108,11 @@ cdef class Expression(Expression_abc): def denominator(self, bint normalize=True): """ - Return the denominator of this symbolic expression + Return the denominator of this symbolic expression. INPUT: - - ``normalize`` -- (default: ``True``) a boolean. + - ``normalize`` -- boolean (default: ``True``) If ``normalize`` is ``True``, the expression is first normalized to have it as a fraction before getting the denominator. @@ -10230,11 +10199,11 @@ cdef class Expression(Expression_abc): def numerator_denominator(self, bint normalize=True): """ - Return the numerator and the denominator of this symbolic expression + Return the numerator and the denominator of this symbolic expression. INPUT: - - ``normalize`` -- (default: ``True``) a boolean. + - ``normalize`` -- boolean (default: ``True``) If ``normalize`` is ``True``, the expression is first normalized to have it as a fraction before getting the numerator and denominator. @@ -10339,11 +10308,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``var`` -- variable name or string (default: first variable) - - OUTPUT: + - ``var`` -- variable name or string (default: first variable) - A symbolic expression + OUTPUT: a symbolic expression .. SEEALSO:: :meth:`partial_fraction_decomposition` @@ -10381,11 +10348,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``var`` -- variable name or string (default: first variable) + - ``var`` -- variable name or string (default: first variable) - OUTPUT: - - A list of symbolic expressions + OUTPUT: list of symbolic expressions .. SEEALSO:: :meth:`partial_fraction` @@ -10449,7 +10414,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``self`` -- the expression to convert. + - ``self`` -- the expression to convert OUTPUT: @@ -10531,7 +10496,7 @@ cdef class Expression(Expression_abc): INPUT: - ``self`` -- an expression with held operations - - ``exclude`` -- (default: None) a list of operators to exclude from + - ``exclude`` -- (default: ``None``) a list of operators to exclude from evaluation. Excluding arithmetic operators does not yet work (see :issue:`10169`). @@ -10622,11 +10587,11 @@ cdef class Expression(Expression_abc): 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) sage: ex.simplify() 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) - sage: ex.simplify(algorithm="sympy") + sage: ex.simplify(algorithm='sympy') I*(x^2 + sqrt(x^2 - 1)*x - 1)/(x + sqrt(x^2 - 1)) - sage: ex.simplify(algorithm="giac") + sage: ex.simplify(algorithm='giac') # needs giac I*sqrt(x^2 - 1) - sage: ex.simplify(algorithm="fricas") # optional - fricas + sage: ex.simplify(algorithm='fricas') # optional - fricas (I*x^2 + I*sqrt(x^2 - 1)*x - I)/(x + sqrt(x^2 - 1)) TESTS: @@ -10658,7 +10623,7 @@ cdef class Expression(Expression_abc): """ Apply :meth:`simplify_factorial`, :meth:`simplify_rectform`, :meth:`simplify_trig`, :meth:`simplify_rational`, and - then :meth:`expand_sum` to self (in that order). + then :meth:`expand_sum` to ``self`` (in that order). ALIAS: ``simplify_full`` and ``full_simplify`` are the same. @@ -10776,7 +10741,6 @@ cdef class Expression(Expression_abc): -2*((x + 1)*e^(-x) - 1)*e^x/x^2 sage: (2 * hypergeometric_U(1, 3, x)).simplify_hypergeometric() 2*(x + 1)/x^2 - """ from sage.functions.hypergeometric import (hypergeometric, hypergeometric_M, @@ -10827,7 +10791,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``self`` -- the expression to simplify. + - ``self`` -- the expression to simplify - ``complexity_measure`` -- (default: ``sage.symbolic.complexity_measures.string_length``) a @@ -10883,7 +10847,6 @@ cdef class Expression(Expression_abc): sage: g = f.simplify_rectform(complexity_measure = None) sage: bool(g == f.rectform()) True - """ simplified_expr = self.rectform() @@ -10903,7 +10866,7 @@ cdef class Expression(Expression_abc): INPUT: - - ``self`` -- the expression to convert. + - ``self`` -- the expression to convert OUTPUT: @@ -10971,7 +10934,6 @@ cdef class Expression(Expression_abc): x sage: assumptions() [] - """ from sage.symbolic.assumptions import assume, assumptions, forget from sage.calculus.calculus import maxima @@ -11016,9 +10978,9 @@ cdef class Expression(Expression_abc): - ``self`` -- symbolic expression - - ``expand`` -- (default: ``True``) if True, expands trigonometric - and hyperbolic functions of sums of angles and of multiple - angles occurring in ``self`` first. For best results, + - ``expand`` -- boolean (default: ``True``); if ``True``, expands + trigonometric and hyperbolic functions of sums of angles and of + multiple angles occurring in ``self`` first. For best results, ``self`` should be expanded. See also :meth:`expand_trig` to get more controls on this expansion. @@ -11064,18 +11026,18 @@ cdef class Expression(Expression_abc): - ``self`` -- symbolic expression - - ``algorithm`` -- (default: 'full') string which switches the + - ``algorithm`` -- (default: ``'full'``) string which switches the algorithm for simplifications. Possible values are - - 'simple' (simplify rational functions into quotient of two - polynomials), + - ``'simple'`` (simplify rational functions into quotient of two + polynomials) - - 'full' (apply repeatedly, if necessary) + - ``'full'`` (apply repeatedly, if necessary) - - 'noexpand' (convert to common denominator and add) + - ``'noexpand'`` (convert to common denominator and add) - - ``map`` -- (default: ``False``) if ``True``, the result is an - expression whose leading operator is the same as that of the + - ``map`` -- boolean (default: ``False``); if ``True``, the result is + an expression whose leading operator is the same as that of the expression ``self`` but whose subparts are the results of applying simplification rules to the corresponding subparts of the expressions. @@ -11212,7 +11174,6 @@ cdef class Expression(Expression_abc): gamma(4/3) sage: gamma(4/3).full_simplify() 1/3*gamma(1/3) - """ return self.parent()(self._maxima_().makefact().factcomb().minfactorial()) @@ -11507,7 +11468,7 @@ cdef class Expression(Expression_abc): - ``self`` -- expression to be simplified - - ``algorithm`` -- (default: None) optional, governs the condition + - ``algorithm`` -- (default: ``None``) governs the condition on `a` and `c` which must be satisfied to contract expression `a \log(b) + c \log(d)`. Values are @@ -11655,16 +11616,16 @@ cdef class Expression(Expression_abc): - ``self`` -- expression to be simplified - - ``algorithm`` -- (default: 'products') optional, governs which + - ``algorithm`` -- (default: ``'products'``) governs which expression is expanded. Possible values are - - 'nothing' (no expansion), + - ``'nothing'`` (no expansion), - - 'powers' (log(a^r) is expanded), + - ``'powers'`` (log(a^r) is expanded), - - 'products' (like 'powers' and also log(a*b) are expanded), + - ``'products'`` (like 'powers' and also log(a*b) are expanded), - - 'all' (all possible expansion). + - ``'all'`` (all possible expansion). See also examples below. @@ -11778,12 +11739,12 @@ cdef class Expression(Expression_abc): INPUT: - - ``recursive`` -- (default : True) the distribution proceeds - along the subtrees of the expression. + - ``recursive`` -- (default: ``True``) the distribution proceeds + along the subtrees of the expression TESTS: - sage: var("j,k,p,q", domain="integer") + sage: var("j,k,p,q", domain='integer') (j, k, p, q) sage: X,Y,Z,f,g = function("X,Y,Z,f,g") sage: var("x,a,b") @@ -11874,15 +11835,13 @@ cdef class Expression(Expression_abc): INPUT: + - ``self`` -- a symbolic expression - - ``self`` -- a symbolic expression - - - ``dontfactor`` -- list (default: ``[]``), a list of - variables with respect to which factoring is not to occur. - Factoring also will not take place with respect to any variables - which are less important (using the variable ordering assumed for - CRE form) than those on the 'dontfactor' list. - + - ``dontfactor`` -- list (default: ``[]``); a list of + variables with respect to which factoring is not to occur. + Factoring also will not take place with respect to any variables + which are less important (using the variable ordering assumed for + CRE form) than those on the 'dontfactor' list. EXAMPLES:: @@ -11964,9 +11923,9 @@ cdef class Expression(Expression_abc): INPUT: - - ``self`` -- a symbolic expression + - ``self`` -- a symbolic expression - - ``dontfactor`` -- see docs for :meth:`factor` + - ``dontfactor`` -- see docs for :meth:`factor` .. NOTE:: @@ -12060,12 +12019,10 @@ cdef class Expression(Expression_abc): INPUT: - ``self`` -- the symbolic expression converting from - - ``target`` -- (default None) the symbolic expression + - ``target`` -- (default: ``None``) the symbolic expression converting to - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -12080,7 +12037,7 @@ cdef class Expression(Expression_abc): sage: a - a.convert() 0 - Raises ValueError if self and target are not convertible:: + Raises :exc:`ValueError` if ``self`` and ``target`` are not convertible:: sage: units.mass.kilogram.convert(units.length.foot) Traceback (most recent call last): @@ -12149,13 +12106,13 @@ cdef class Expression(Expression_abc): - ``x`` -- variable to view the function in terms of (use default variable if not given) - - ``explicit_solutions`` -- bool (default ``True``); require that + - ``explicit_solutions`` -- boolean (default: ``True``); require that roots be explicit rather than implicit - - ``multiplicities`` -- bool (default ``True``); when ``True``, return + - ``multiplicities`` -- boolean (default: ``True``); when ``True``, return multiplicities - - ``ring`` -- a ring (default ``None``): if not ``None``, convert + - ``ring`` -- a ring (default: ``None``); if not ``None``, convert ``self`` to a polynomial over ``ring`` and find roots over ``ring`` OUTPUT: @@ -12324,28 +12281,28 @@ cdef class Expression(Expression_abc): INPUT: - - ``x`` -- variable(s) to solve for + - ``x`` -- variable(s) to solve for - - ``multiplicities`` -- bool (default: ``False``); if ``True``, - return corresponding multiplicities. This keyword is - incompatible with ``to_poly_solve=True`` and does not make - any sense when solving an inequality. + - ``multiplicities`` -- boolean (default: ``False``); if ``True``, + return corresponding multiplicities. This keyword is + incompatible with ``to_poly_solve=True`` and does not make + any sense when solving an inequality. - - ``solution_dict`` -- bool (default: ``False``); if ``True`` or non-zero, - return a list of dictionaries containing solutions. Not used - when solving an inequality. + - ``solution_dict`` -- boolean (default: ``False``); if ``True`` or nonzero, + return a list of dictionaries containing solutions. Not used + when solving an inequality. - - ``explicit_solutions`` -- bool (default: ``False``); require that - all roots be explicit rather than implicit. Not used - when solving an inequality. + - ``explicit_solutions`` -- boolean (default: ``False``); require that + all roots be explicit rather than implicit. Not used + when solving an inequality. - - ``to_poly_solve`` -- bool (default: ``False``) or string; use - Maxima's ``to_poly_solver`` package to search for more possible - solutions, but possibly encounter approximate solutions. - This keyword is incompatible with ``multiplicities=True`` - and is not used when solving an inequality. Setting ``to_poly_solve`` - to ``'force'`` omits Maxima's solve command (useful when - some solutions of trigonometric equations are lost). + - ``to_poly_solve`` -- boolean (default: ``False``) or string; use + Maxima's ``to_poly_solver`` package to search for more possible + solutions, but possibly encounter approximate solutions. + This keyword is incompatible with ``multiplicities=True`` + and is not used when solving an inequality. Setting ``to_poly_solve`` + to ``'force'`` omits Maxima's solve command (useful when + some solutions of trigonometric equations are lost). EXAMPLES:: @@ -12511,22 +12468,22 @@ cdef class Expression(Expression_abc): INPUT: - - ``a``, ``b`` -- endpoints of the interval + - ``a``, ``b`` -- endpoints of the interval - - ``var`` -- optional variable + - ``var`` -- (optional) variable - - ``xtol, rtol`` -- the routine converges when a root - is known to lie within ``xtol`` of the value return. Should be >= 0. The - routine modifies this to take into account the relative precision - of doubles. + - ``xtol, rtol`` -- the routine converges when a root is known to lie + within ``xtol`` of the value return. Should be nonnegative. The + routine modifies this to take into account the relative precision of + doubles. - - ``maxiter`` -- integer; if convergence is not - achieved in maxiter iterations, an error is raised. Must be >= 0. + - ``maxiter`` -- integer; if convergence is not achieved in maxiter + iterations, an error is raised. Must be nonnegative. - - ``full_output`` -- bool (default: ``False``), if ``True``, - also return object that contains information about convergence. + - ``full_output`` -- boolean (default: ``False``); if ``True``, + also return object that contains information about convergence - - ``imaginary_tolerance`` -- (default: ``1e-8``); if an imaginary + - ``imaginary_tolerance`` -- (default: ``1e-8``) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than @@ -12640,7 +12597,6 @@ cdef class Expression(Expression_abc): sage: f = (sqrt(x) - I).abs() sage: f.find_root(-2, 2, rtol=1e-6) # abs tol 1e-6 # needs scipy -1.0000000049668551 - """ if is_a_relational(self._gobj) and self.operator() is not operator.eq: raise ValueError("Symbolic equation must be an equality.") @@ -12697,22 +12653,20 @@ cdef class Expression(Expression_abc): INPUT: - - ``a`` -- real number; left endpoint of interval on which to - minimize + - ``a`` -- real number; left endpoint of interval on which to minimize - - ``b`` -- real number; right endpoint of interval on which to - minimize + - ``b`` -- real number; right endpoint of interval on which to minimize - - ``var`` -- variable (default: first variable in self); the - variable in self to maximize over + - ``var`` -- variable (default: first variable in ``self``); the + variable in ``self`` to maximize over - - ``tol`` -- positive real (default: 1.48e-08); the convergence - tolerance + - ``tol`` -- positive real (default: 1.48e-08); the convergence + tolerance - - ``maxfun`` -- natural number (default: 500); maximum function - evaluations + - ``maxfun`` -- natural number (default: 500); maximum function + evaluations - - ``imaginary_tolerance`` -- (default: ``1e-8``); if an imaginary + - ``imaginary_tolerance`` -- (default: ``1e-8``) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than @@ -12722,11 +12676,11 @@ cdef class Expression(Expression_abc): A tuple ``(minval, x)``, where - - ``minval`` -- float. The minimum value that self takes on in - the interval ``[a,b]``. + - ``minval`` -- float; the minimum value that ``self`` takes on in + the interval ``[a,b]`` - - ``x`` -- float. The point at which self takes on the minimum - value. + - ``x`` -- float; the point at which ``self`` takes on the minimum + value EXAMPLES:: @@ -12977,18 +12931,18 @@ cdef class Expression(Expression_abc): ############ def sum(self, *args, **kwds): r""" - Return the symbolic sum `\sum_{v = a}^b` ``self`` + Return the symbolic sum `\sum_{v = a}^b` ``self``. with respect to the variable `v` with endpoints `a` and `b`. INPUT: - - ``v`` -- a variable or variable name + - ``v`` -- a variable or variable name - - ``a`` -- lower endpoint of the sum + - ``a`` -- lower endpoint of the sum - - ``b`` -- upper endpoint of the sum + - ``b`` -- upper endpoint of the sum - ``algorithm`` -- (default: ``'maxima'``) one of @@ -13091,6 +13045,7 @@ cdef class Expression(Expression_abc): Use Giac to perform this summation:: + sage: # needs giac sage: (sum(1/(1+k^2), k, -oo, oo, algorithm = 'giac')).factor() pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1)) @@ -13177,7 +13132,7 @@ cdef class Expression(Expression_abc): - ``'giac'`` -- (optional) use Giac - ``'sympy'`` -- use SymPy - - ``hold`` -- (default: ``False``) if ``True``, don't evaluate + - ``hold`` -- boolean (default: ``False``); if ``True``, don't evaluate TESTS: @@ -13242,9 +13197,16 @@ cdef class Expression(Expression_abc): sage: integral(f, z) (x, y) |--> (x + y)*z - We check that :issue:`13097` is resolved:: + We check that :issue:`13097` is resolved (sage doesn't + crash). If giac is available, you may even get a usable + answer:: - sage: integrate(ln(1+4/5*sin(x)), x, -3.1415, 3.1415) # tol 10e-6 + sage: f = ln(1+4/5*sin(x)) + sage: integrate(f, x, -3.1415, 3.1415) # random + integrate(log(4/5*sin(x) + 1), x, -3.14150000000000, + 3.14150000000000) + sage: # needs sage.libs.giac + sage: integrate(f, x, -3.1415, 3.1415) # tol 10e-6 -1.40205228301000 """ from sage.symbolic.integration.integral import \ @@ -13462,15 +13424,17 @@ cdef class Expression(Expression_abc): def implicit_derivative(self, Y, X, n=1): """ - Return the `n`-th derivative of `Y` with respect to `X` given implicitly by this expression. + Return the `n`-th derivative of `Y` with respect to `X` given + implicitly by this expression. INPUT: - - ``Y`` -- The dependent variable of the implicit expression. + - ``Y`` -- the dependent variable of the implicit expression - - ``X`` -- The independent variable with respect to which the derivative is taken. + - ``X`` -- the independent variable with respect to which the + derivative is taken - - ``n`` -- (default: 1) the order of the derivative. + - ``n`` -- (default: 1) the order of the derivative EXAMPLES:: @@ -13826,15 +13790,15 @@ cpdef new_Expression_from_pyobject(parent, x, bint force=True, bint recursive=Tr INPUT: - - ``parent`` -- a symbolic ring. + - ``parent`` -- a symbolic ring - - ``x`` -- a Python object. + - ``x`` -- a Python object - - ``force`` -- bool, default ``True``, if True, the Python object - is taken as is without attempting coercion or list traversal. + - ``force`` -- boolean (default: ``True``); if ``True``, the Python object + is taken as is without attempting coercion or list traversal - - ``recursive`` -- bool, default ``True``, disables recursive - traversal of lists. + - ``recursive`` -- boolean (default: ``True``); disables recursive + traversal of lists EXAMPLES:: @@ -13896,13 +13860,11 @@ cpdef new_Expression_wild(parent, unsigned int n=0): INPUT: - - ``parent`` -- a symbolic ring. - - - ``n`` -- a nonnegative integer. + - ``parent`` -- a symbolic ring - OUTPUT: + - ``n`` -- nonnegative integer - - ``n``-th wildcard expression. + OUTPUT: n-th wildcard expression EXAMPLES:: diff --git a/src/sage/symbolic/expression_conversion_algebraic.py b/src/sage/symbolic/expression_conversion_algebraic.py index 11314aaeb70..9772fb8d94a 100644 --- a/src/sage/symbolic/expression_conversion_algebraic.py +++ b/src/sage/symbolic/expression_conversion_algebraic.py @@ -146,9 +146,9 @@ def composition(self, ex, operator): sage: a.composition(complex_root_of(x^5 - 1, 3), complex_root_of) 0.3090169943749474? - 0.9510565162951536?*I sage: a.composition(complex_root_of(x^2 + 1, 0), complex_root_of) - 1.?e-884 - 0.9999999999999999?*I + 1.?e-683 - 0.9999999999999999?*I sage: a.composition(complex_root_of(x^2 + 1, 1), complex_root_of) - 1.?e-884 + 0.9999999999999999?*I + 1.?e-683 + 0.9999999999999999?*I TESTS:: @@ -264,8 +264,8 @@ def composition(self, ex, operator): def algebraic(ex, field): """ - Returns the symbolic expression *ex* as a element of the algebraic - field *field*. + Return the symbolic expression ``ex`` as a element of the algebraic + field ``field``. EXAMPLES:: diff --git a/src/sage/symbolic/expression_conversion_sympy.py b/src/sage/symbolic/expression_conversion_sympy.py index e7aaf3bd656..df7fda7fbed 100644 --- a/src/sage/symbolic/expression_conversion_sympy.py +++ b/src/sage/symbolic/expression_conversion_sympy.py @@ -26,9 +26,11 @@ ######### # Sympy # ######### + + class SympyConverter(Converter): """ - Converts any expression to SymPy. + Convert any expression to SymPy. EXAMPLES:: @@ -52,7 +54,6 @@ class SympyConverter(Converter): True sage: (x+I)._sympy_() x + I - """ def __init__(self): """ @@ -60,7 +61,7 @@ def __init__(self): sage: from sage.symbolic.expression_conversions import SympyConverter sage: s = SympyConverter() # indirect doctest - sage: TestSuite(s).run(skip="_test_pickling") + sage: TestSuite(s).run(skip='_test_pickling') """ from sage.interfaces.sympy import sympy_init sympy_init() diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 486bb4324b1..2d59c66293c 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -32,7 +32,7 @@ lazy_import('sage.symbolic.expression_conversion_algebraic', ['AlgebraicConverter', 'algebraic']) -class FakeExpression(): +class FakeExpression: r""" Pynac represents `x/y` as `xy^{-1}`. Often, tree-walkers would prefer to see divisions instead of multiplications and negative exponents. @@ -130,7 +130,7 @@ def _fast_callable_(self, etb): return fast_callable(self, etb) -class Converter(): +class Converter: def __init__(self, use_fake_div=False): """ If use_fake_div is set to True, then the converter will try to @@ -278,7 +278,7 @@ def pyobject(self, ex, obj): The input to this method is the result of calling :meth:`pyobject` on a symbolic expression. - .. note:: + .. NOTE:: Note that if a constant such as ``pi`` is encountered in the expression tree, its corresponding pyobject which is an @@ -400,7 +400,6 @@ def __init__(self, interface): 'sin((%pi)+(2))' sage: m(exp(x^2) + pi + 2) '(%pi)+(exp((_SAGE_VAR_x)^(2)))+(2)' - """ self.name_init = "_%s_init_" % interface.name() self.interface = interface @@ -662,7 +661,7 @@ def composition(self, ex, operator): ########## class FriCASConverter(InterfaceInit): """ - Converts any expression to FriCAS. + Convert any expression to FriCAS. EXAMPLES:: @@ -675,7 +674,6 @@ class FriCASConverter(InterfaceInit): y %e - asin(x + %pi) ---------------------- y - """ def __init__(self): import sage.interfaces.fricas @@ -729,7 +727,6 @@ def pyobject(self, ex, obj): sage: (ex^2)._fricas_() # optional - fricas +-+ (4 + 2 %i)\|2 + 5 + 4 %i - """ try: result = getattr(obj, self.name_init)() @@ -764,7 +761,6 @@ def symbol(self, ex): sage: (2*x)._fricas_().integrate(x) # optional - fricas 2 x - """ return repr(ex) @@ -780,7 +776,6 @@ def derivative(self, ex, operator): Note that ``ex.operator() == operator``. - EXAMPLES:: sage: var('x,y,z') @@ -797,10 +792,10 @@ def derivative(self, ex, operator): sage: var('x') x sage: F = function('F') - sage: integrate(F(x), x, algorithm="fricas") # optional - fricas + sage: integrate(F(x), x, algorithm='fricas') # optional - fricas integral(F(x), x) - sage: integrate(diff(F(x), x)*sin(F(x)), x, algorithm="fricas") # optional - fricas + sage: integrate(diff(F(x), x)*sin(F(x)), x, algorithm='fricas') # optional - fricas -cos(F(x)) Check that :issue:`27310` is fixed:: @@ -813,7 +808,6 @@ def derivative(self, ex, operator): sage: fricas(ex) # optional - fricas F (x,y + x) ,1,1,2 - """ args = ex.operands() # the arguments the derivative is evaluated at params = operator.parameter_set() @@ -914,7 +908,7 @@ def __init__(self, ex, base_ring=None, ring=None): def symbol(self, ex): """ - Returns a variable in the polynomial ring. + Return a variable in the polynomial ring. EXAMPLES:: @@ -1034,15 +1028,13 @@ def polynomial(ex, base_ring=None, ring=None): - ``ex`` -- a symbolic expression - - ``base_ring``, ``ring`` -- Either a + - ``base_ring``, ``ring`` -- either a ``base_ring`` or a polynomial ``ring`` can be specified for the parent of result. If just a ``base_ring`` is given, then the variables of the ``base_ring`` will be the variables of the expression ``ex``. - OUTPUT: - - A polynomial. + OUTPUT: a polynomial EXAMPLES:: @@ -1123,15 +1115,13 @@ def laurent_polynomial(ex, base_ring=None, ring=None): - ``ex`` -- a symbolic expression - - ``base_ring``, ``ring`` -- Either a + - ``base_ring``, ``ring`` -- either a ``base_ring`` or a Laurent polynomial ``ring`` can be specified for the parent of result. If just a ``base_ring`` is given, then the variables of the ``base_ring`` will be the variables of the expression ``ex``. - OUTPUT: - - A Laurent polynomial. + OUTPUT: a Laurent polynomial EXAMPLES:: @@ -1338,7 +1328,6 @@ def fast_callable(ex, etb): sage: f = (2*x^3+2*x-1)/((x-2)*(x+1)) sage: f._fast_callable_(etb) div(add(add(mul(ipow(v_0, 3), 2), mul(v_0, 2)), -1), mul(add(v_0, 1), add(v_0, -2))) - """ return FastCallableConverter(ex, etb)() @@ -1425,7 +1414,7 @@ def arithmetic(self, ex, operator): from sage.rings.rational import Rational base, expt = operands - if expt == Rational(((1, 2))): + if expt == Rational((1, 2)): from sage.misc.functional import sqrt return sqrt(self(base)) try: @@ -1648,7 +1637,6 @@ def derivative(self, ex, operator): sage: g = function('g') sage: f(g(x)).diff(x).substitute_function({g: sin}) cos(x)*D[0](f)(sin(x)) - """ new = self.substitutions.get(operator.function()) if new is not None: @@ -1661,13 +1649,13 @@ class Exponentialize(ExpressionTreeWalker): # Implementation note: this code is executed once at first # reference in the code using it, therefore avoiding rebuilding # the same canned results dictionary at each call. + from sage.calculus.var import function from sage.functions.hyperbolic import sinh, cosh, sech, csch, tanh, coth from sage.functions.log import exp from sage.functions.trig import sin, cos, sec, csc, tan, cot - from sage.symbolic.constants import e, I from sage.rings.integer import Integer + from sage.symbolic.constants import e, I from sage.symbolic.ring import SR - from sage.calculus.var import function half = Integer(1) / Integer(2) two = Integer(2) x = SR.var("x") @@ -1685,7 +1673,7 @@ class Exponentialize(ExpressionTreeWalker): tanh: (-(exp(-x) - exp(x))/(exp(x) + exp(-x))).function(x), coth: (-(exp(-x) + exp(x))/(exp(-x) - exp(x))).function(x) } - Circs = list(CircDict.keys()) + Circs = list(CircDict) def __init__(self, ex): """ @@ -1785,6 +1773,75 @@ def composition(self, ex, op): return exp(arg) +# Half_angle transformation. Sometimes useful in integration + +class HalfAngle(ExpressionTreeWalker): + """ + A class that walks a symbolic expression tree, replacing each + occurrence of a trigonometric or hyperbolic function by its + expression as a rational fraction in the (hyperbolic) tangent + of half the original argument. + """ + # Code executed once at first class reference: create canned formulae. + from sage.calculus.var import function + from sage.functions.hyperbolic import sinh, cosh, sech, csch, tanh, coth + from sage.functions.trig import sin, cos, sec, csc, tan, cot + from sage.rings.integer import Integer + from sage.symbolic.ring import SR + x = SR.var("x") + one = Integer(1) + two = Integer(2) + half = one / two + halfx = half * x + HalvesDict = { + sin: two * tan(halfx) / (tan(halfx)**2 + one).function(x), + cos: -(tan(halfx)**2 - one) / (tan(halfx)**2 + one).function(x), + tan: -two * tan(halfx) / (tan(halfx)**2 - one).function(x), + csc: half * (tan(halfx)**2 + one) / tan(halfx).function(x), + sec: -(tan(halfx)**2 + one) / (tan(halfx)**2 - one).function(x), + cot: -half * (tan(halfx)**2 - one) / tan(halfx).function(x), + sinh: -two * tanh(halfx) / (tanh(halfx)**2 - one).function(x), + cosh: -(tanh(halfx)**2 + one) / (tanh(halfx)**2 - one).function(x), + tanh: two * tanh(halfx) / (tanh(halfx)**2 + one).function(x), + csch: -half * (tanh(halfx)**2 - one) / tanh(halfx).function(x), + sech: -(tanh(halfx)**2 - one) / (tanh(halfx)**2 + one).function(x), + coth: half * (tanh(halfx)**2 + one) / tanh(halfx).function(x) + } + Halves = list(HalvesDict) + + def __init__(self, ex): + """ + A class that walks a symbolic expression tree, replacing each + occurrence of a trigonometric or hyperbolic function by its + expression as a rational fraction in the (hyperbolic) tangent + of half the original argument. + + EXAMPLES:: + + sage: a, b = SR.var("a, b") + sage: from sage.symbolic.expression_conversions import HalfAngle + sage: HalfAngle(tan(a))(tan(a)+4) + -2*tan(1/2*a)/(tan(1/2*a)^2 - 1) + 4 + """ + self.ex = ex + + def composition(self, ex, op): + """ + Compose. + + EXAMPLES:: + + sage: from sage.symbolic.expression_conversions import HalfAngle + sage: x, t = SR.var("x, t") + sage: a = HalfAngle(cos(3*x)/(4-cos(x)).trig_expand())() + sage: a.subs(tan(x/2) == t).simplify_full() + (2*(t^2 + 1)*cos(3/2*x)^2 - t^2 - 1)/(5*t^2 + 3) + """ + if op in self.Halves: + return self.HalvesDict.get(op)(*[self(x) for x in ex.operands()]) + return super().composition(ex, op) + + class HoldRemover(ExpressionTreeWalker): def __init__(self, ex, exclude=None): """ @@ -1829,8 +1886,8 @@ def composition(self, ex, operator): sage: h() 0 """ - from sage.functions.other import Function_sum, Function_prod from sage.calculus.calculus import symbolic_sum, symbolic_product + from sage.functions.other import Function_sum, Function_prod if not operator: return self if isinstance(operator, Function_sum): diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 2cb2f09c715..362d01ea297 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -267,7 +267,6 @@ cdef class Function(SageObject): f(x) sage: deepcopy(f) f(x) - """ self._serial = register_or_update_function(self, self._name, self._latex_name, self._nargs, self._evalf_params_first, @@ -397,7 +396,6 @@ cdef class Function(SageObject): False sage: foo(1, 2).operator() == foo True - """ try: return richcmp((self)._serial, @@ -610,7 +608,7 @@ cdef class Function(SageObject): def _is_numerical(self, x): """ - Return True if `x` is a numerical object. + Return ``True`` if `x` is a numerical object. This is used to determine whether to call the :meth:`_evalf_` method instead of the :meth:`_eval_` method. @@ -805,7 +803,6 @@ cdef class Function(SageObject): sage: with mpmath.workprec(64): noMpmathFn(sqrt(mpmath.mpf('2'))) 123 sage: del mpmath.noMpmathFn - """ import mpmath from sage.libs.mpmath.utils import mpmath_to_sage, sage_to_mpmath @@ -964,6 +961,9 @@ cdef class BuiltinFunction(Function): mpc(real='0.83373002513114902', imag='-0.98889770576286506') sage: import numpy # needs numpy + sage: if int(numpy.version.short_version[0]) > 1: # needs numpy + ....: numpy.set_printoptions(legacy="1.25") # needs numpy + sage: sin(numpy.int32(0)) # needs numpy 0.0 sage: type(_) # needs numpy diff --git a/src/sage/symbolic/function_factory.py b/src/sage/symbolic/function_factory.py index 7c5b660f3bb..057d1e07811 100644 --- a/src/sage/symbolic/function_factory.py +++ b/src/sage/symbolic/function_factory.py @@ -150,7 +150,7 @@ def unpickle_function(name, nargs, latex_name, conversions, evalf_params_first, return function_factory(*args) -def function(s, **kwds) -> Union[SymbolicFunction, list[SymbolicFunction]]: +def function(s, **kwds) -> SymbolicFunction | list[SymbolicFunction]: r""" Create a formal symbolic function with the name *s*. @@ -159,11 +159,11 @@ def function(s, **kwds) -> Union[SymbolicFunction, list[SymbolicFunction]]: - ``nargs=0`` -- number of arguments the function accepts, defaults to variable number of arguments, or 0 - ``latex_name`` -- name used when printing in latex mode - - ``conversions`` -- a dictionary specifying names of this function in + - ``conversions`` -- dictionary specifying names of this function in other systems, this is used by the interfaces internally during conversion - ``eval_func`` -- method used for automatic evaluation - ``evalf_func`` -- method used for numeric evaluation - - ``evalf_params_first`` -- bool to indicate if parameters should be + - ``evalf_params_first`` -- boolean to indicate if parameters should be evaluated numerically before calling the custom evalf function - ``conjugate_func`` -- method used for complex conjugation - ``real_part_func`` -- method used when taking real parts diff --git a/src/sage/symbolic/getitem_impl.pxi b/src/sage/symbolic/getitem_impl.pxi index c20cf1e6e31..cbc5f6b9c97 100644 --- a/src/sage/symbolic/getitem_impl.pxi +++ b/src/sage/symbolic/getitem_impl.pxi @@ -188,6 +188,7 @@ cdef class OperandsWrapper(SageObject): """ return restore_op_wrapper, (self._expr,) + def restore_op_wrapper(expr): """ TESTS:: diff --git a/src/sage/symbolic/ginac/basic.h b/src/sage/symbolic/ginac/basic.h index b4d572e5c52..d7adf245b33 100644 --- a/src/sage/symbolic/ginac/basic.h +++ b/src/sage/symbolic/ginac/basic.h @@ -43,19 +43,6 @@ 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; @@ -315,9 +302,6 @@ class basic : public refcounted 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 diff --git a/src/sage/symbolic/ginac/ex.h b/src/sage/symbolic/ginac/ex.h index 6a164af270f..7b53b283b49 100644 --- a/src/sage/symbolic/ginac/ex.h +++ b/src/sage/symbolic/ginac/ex.h @@ -230,9 +230,6 @@ class ex { ex to_rational(lst & repl_lst) const; ex to_polynomial(exmap & repl) const; ex to_polynomial(lst & repl_lst) const; -#ifdef PYNAC_HAVE_LIBGIAC - const giac::polynome to_polynome(ex_int_map& map, exvector& revmap) const; -#endif const CanonicalForm to_canonical(ex_int_umap& map, power_ocvector_map& pomap, exvector& revmap) const; void collect_powers(power_ocvector_map& pomap) const; diff --git a/src/sage/symbolic/ginac/matrix.cpp b/src/sage/symbolic/ginac/matrix.cpp index c42f8f68c41..4955ddb26be 100644 --- a/src/sage/symbolic/ginac/matrix.cpp +++ b/src/sage/symbolic/ginac/matrix.cpp @@ -1108,7 +1108,7 @@ unsigned matrix::rank() const * more than once. According to W.M.Gentleman and S.C.Johnson this algorithm * is better than elimination schemes for matrices of sparse multivariate * polynomials and also for matrices of dense univariate polynomials if the - * matrix' dimesion is larger than 7. + * matrix' dimension is larger than 7. * * @return the determinant as a new expression (in expanded form) * @see matrix::determinant() */ diff --git a/src/sage/symbolic/ginac/mpoly-giac.cpp b/src/sage/symbolic/ginac/mpoly-giac.cpp deleted file mode 100644 index e980d542c65..00000000000 --- a/src/sage/symbolic/ginac/mpoly-giac.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/** @file mpoly-giac.cpp - * - * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany - * Copyright (C) 2016 Ralf Stephan - * - * 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 "pynac-config.h" - -#ifdef PYNAC_HAVE_LIBGIAC - -#include -#include -#include -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE - -#include "upoly.h" -#include "basic.h" -#include "ex.h" -#include "add.h" -#include "constant.h" -#include "expairseq.h" -#include "mul.h" -#include "numeric.h" -#include "power.h" -#include "operators.h" -#include "pseries.h" -#include "relational.h" -#include "symbol.h" -#include "function.h" -#include "utils.h" - -#include -#include - -namespace GiNaC { - -static unsigned int the_dimension = 7; - -static giac::context * context_ptr=nullptr; -static giac::gen giac_zero; -static giac::gen giac_one; - - -inline giac::polynome gen2pol(const giac::gen& g) { - return giac::polynome(giac::monomial(g, the_dimension)); -} - -inline giac::gen num2gen(const numeric& n) { - auto gp = n.to_giacgen(context_ptr); - if (gp != nullptr) - return std::move(*gp); - else { - std::stringstream ss; - ss << n; - return giac::gen(std::string(ss.str()), context_ptr); - } -} - -static giac::polynome replace_with_symbol(const ex& e, ex_int_map& map, exvector& revmap) -{ - // Expression already replaced? Then return the assigned symbol - auto it = map.find(e); - if (it != map.end()) { - const int index = it->second; - giac::monomial mon(giac_one, index, the_dimension); - return giac::polynome(mon); - } - - // Otherwise create new symbol and add to dict - const int index = revmap.size() + 1; - map.insert(std::make_pair(e, index)); - revmap.push_back(e); - giac::monomial mon(giac_one, index, the_dimension); - return giac::polynome(mon); -} - -const giac::polynome basic::to_polynome(ex_int_map& map, exvector& revmap) -{ - std::cerr << *this << std::endl; - throw std::runtime_error("basic::to_polynome: can't happen"); -} - -const giac::polynome num_to_polynome(const numeric& num, - ex_int_map& map, exvector& revmap) -{ - if (num.is_real()) { - if (num.is_integer() or num.is_rational()) - return gen2pol(num2gen(num)); - else - return replace_with_symbol(num, map, revmap); - } else { // complex - numeric re = num.real(); - numeric im = num.imag(); - giac::polynome re_p(the_dimension); - giac::polynome im_p(the_dimension); - if (re.is_integer() or re.is_rational()) - re_p = gen2pol(num2gen(re)); - else - re_p = replace_with_symbol(re, map, revmap); - if (im.is_integer() or im.is_rational()) - im_p = gen2pol(num2gen(im)); - else - im_p = replace_with_symbol(im, map, revmap); - giac::polynome r = re_p + im_p * replace_with_symbol(I, map, revmap); - return r; - } -} - -// Convert to giac polynomial over QQ, filling replacement dicts -// TODO: special case numeric mpz_t, int instead of string interface -const giac::polynome ex::to_polynome(ex_int_map& map, exvector& revmap) const -{ - if (is_exactly_a(*this)) - { - const add& a = ex_to(*this); - giac::polynome p = gen2pol(giac_zero); - for (const auto& termex : a.seq) { - p = p + a.recombine_pair_to_ex(termex).to_polynome(map, revmap); - } - p = p + num_to_polynome(a.overall_coeff, map, revmap); - return p; - } - else if (is_exactly_a(*this)) - { - return num_to_polynome(ex_to(*this), map, revmap); - } - else if (is_exactly_a(*this)) - { - const mul& m = ex_to(*this); - giac::polynome p = gen2pol(giac_one); - for (const auto& termex : m.seq) { - p *= m.recombine_pair_to_ex(termex).to_polynome(map, revmap); - } - p *= num_to_polynome(m.overall_coeff, map, revmap); - return p; - } - else if (is_exactly_a(*this)) - { - const power& pow = ex_to(*this); - if (is_exactly_a(pow.exponent)) { - numeric expo = ex_to(pow.exponent); - if (pow.exponent.info(info_flags::posint)) - return std::move(giac::pow(pow.basis.to_polynome(map, revmap), expo.to_int())); - } - return replace_with_symbol(*this, map, revmap); - } - - return replace_with_symbol(*this, map, revmap); -} - -static ex gen2ex(const giac::gen& gen) -{ - // we need to handle giac types _INT_, _ZINT, and _CPLX - switch (gen.type) { - case giac::_INT_: - return numeric(gen.val); - case giac::_ZINT: - mpz_t bigint; - mpz_init_set(bigint, *(gen.ref_ZINTptr())); - return numeric(bigint); - case giac::_CPLX: - return (gen2ex(gen.ref_CPLXptr()[0]) - + I * gen2ex(gen.ref_CPLXptr()[1])); - case giac::_FRAC: - return (gen2ex(gen.ref_FRACptr()->num) - / gen2ex(gen.ref_FRACptr()->den)); - default: - std::ostringstream os; - os << "gen2ex: can't happen: " << int(gen.type) << std::flush; - throw std::runtime_error(os.str()); - } -} - -static ex polynome_to_ex(const giac::polynome& p, const exvector& revmap) -{ - ex e = _ex0; - for (const auto& mon : p.coord) { - ex prod = _ex1; - for (unsigned int varno=0; varno(a) && is_exactly_a(b)) { - numeric g = gcd(ex_to(a), ex_to(b)); - if ((ca != nullptr) || (cb != nullptr)) { - if (g.is_zero()) { - if (ca != nullptr) - *ca = _ex0; - if (cb != nullptr) - *cb = _ex0; - } else { - if (ca != nullptr) - *ca = ex_to(a) / g; - if (cb != nullptr) - *cb = ex_to(b) / g; - } - } - return g; - } - - // Partially factored cases (to avoid expanding large expressions) - if (is_exactly_a(a)) { - if (is_exactly_a(b) && b.nops() > a.nops()) - goto factored_b; -factored_a: - size_t num = a.nops(); - exvector g; g.reserve(num); - exvector acc_ca; acc_ca.reserve(num); - ex part_b = b; - for (size_t i=0; isetflag(status_flags::dynallocated); - if (cb != nullptr) - *cb = part_b; - return (new mul(g))->setflag(status_flags::dynallocated); - } else if (is_exactly_a(b)) { - if (is_exactly_a(a) && a.nops() > b.nops()) - goto factored_a; -factored_b: - size_t num = b.nops(); - exvector g; g.reserve(num); - exvector acc_cb; acc_cb.reserve(num); - ex part_a = a; - for (size_t i=0; isetflag(status_flags::dynallocated); - return (new mul(g))->setflag(status_flags::dynallocated); - } - - // Input polynomials of the form poly^n are sometimes also trivial - if (is_exactly_a(a)) { - ex p = a.op(0); - const ex& exp_a = a.op(1); - if (is_exactly_a(b)) { - ex pb = b.op(0); - const ex& exp_b = b.op(1); - if (p.is_equal(pb)) { - // a = p^n, b = p^m, gcd = p^min(n, m) - if (exp_a < exp_b) { - if (ca != nullptr) - *ca = _ex1; - if (cb != nullptr) - *cb = power(p, exp_b - exp_a); - return power(p, exp_a); - } else { - if (ca != nullptr) - *ca = power(p, exp_a - exp_b); - if (cb != nullptr) - *cb = _ex1; - return power(p, exp_b); - } - } else { - ex p_co, pb_co; - ex p_gcd = gcdpoly(p, pb, &p_co, &pb_co, check_args); - if (p_gcd.is_one()) { - // a(x) = p(x)^n, b(x) = p_b(x)^m, gcd (p, p_b) = 1 ==> - // gcd(a,b) = 1 - if (ca != nullptr) - *ca = a; - if (cb != nullptr) - *cb = b; - return _ex1; - // XXX: do I need to check for p_gcd = -1? - } else { - // there are common factors: - // a(x) = g(x)^n A(x)^n, b(x) = g(x)^m B(x)^m ==> - // gcd(a, b) = g(x)^n gcd(A(x)^n, g(x)^(n-m) B(x)^m - if (exp_a < exp_b) { - return power(p_gcd, exp_a)* - gcdpoly(power(p_co, exp_a), power(p_gcd, exp_b-exp_a)*power(pb_co, exp_b), ca, cb, false); - } else { - return power(p_gcd, exp_b)* - gcdpoly(power(p_gcd, exp_a - exp_b)*power(p_co, exp_a), power(pb_co, exp_b), ca, cb, false); - } - } // p_gcd.is_equal(_ex1) - } // p.is_equal(pb) - - } else { - if (p.is_equal(b)) { - // a = p^n, b = p, gcd = p - if (ca != nullptr) - *ca = power(p, a.op(1) - 1); - if (cb != nullptr) - *cb = _ex1; - return p; - } - - ex p_co, bpart_co; - ex p_gcd = gcdpoly(p, b, &p_co, &bpart_co, false); - - if (p_gcd.is_one()) { - // a(x) = p(x)^n, gcd(p, b) = 1 ==> gcd(a, b) = 1 - if (ca != nullptr) - *ca = a; - if (cb != nullptr) - *cb = b; - return _ex1; - } else { - // a(x) = g(x)^n A(x)^n, b(x) = g(x) B(x) ==> gcd(a, b) = g(x) gcd(g(x)^(n-1) A(x)^n, B(x)) - return p_gcd*gcdpoly(power(p_gcd, exp_a-1)*power(p_co, exp_a), bpart_co, ca, cb, false); - } - } // is_exactly_a(b) - - } else if (is_exactly_a(b)) { - ex p = b.op(0); - if (p.is_equal(a)) { - // a = p, b = p^n, gcd = p - if (ca != nullptr) - *ca = _ex1; - if (cb != nullptr) - *cb = power(p, b.op(1) - 1); - return p; - } - - ex p_co, apart_co; - const ex& exp_b(b.op(1)); - ex p_gcd = gcdpoly(a, p, &apart_co, &p_co, false); - if (p_gcd.is_one()) { - // b=p(x)^n, gcd(a, p) = 1 ==> gcd(a, b) == 1 - if (ca != nullptr) - *ca = a; - if (cb != nullptr) - *cb = b; - return _ex1; - } else { - // there are common factors: - // a(x) = g(x) A(x), b(x) = g(x)^n B(x)^n ==> gcd = g(x) gcd(g(x)^(n-1) A(x)^n, B(x)) - - return p_gcd*gcdpoly(apart_co, power(p_gcd, exp_b-1)*power(p_co, exp_b), ca, cb, false); - } // p_gcd.is_equal(_ex1) - } - - // Conversion necessary to count needed symbols beforehand - exmap repl; - ex poly_a = a.to_rational(repl); - ex poly_b = b.to_rational(repl); - - symbolset s1 = poly_a.symbols(); - const symbolset& s2 = poly_b.symbols(); - s1.insert(s2.begin(), s2.end()); - the_dimension = s1.size(); - - ex_int_map map; - exvector revmap; - - giac::polynome p = poly_a.to_polynome(map, revmap); - giac::polynome q = poly_b.to_polynome(map, revmap); - giac::polynome d(the_dimension); - giac::gcd(p, q, d); - - if (ca != nullptr) { - giac::polynome quo(the_dimension); - if (giac::exactquotient(p, d, quo)) - *ca = polynome_to_ex(quo, revmap).subs(repl, subs_options::no_pattern); - else - throw(std::runtime_error("can't happen in gcdpoly")); - } - if (cb != nullptr) { - giac::polynome quo(the_dimension); - if (giac::exactquotient(q, d, quo)) - *cb = polynome_to_ex(quo, revmap).subs(repl, subs_options::no_pattern); - else - throw(std::runtime_error("can't happen in gcdpoly")); - } - return polynome_to_ex(d, revmap).subs(repl, subs_options::no_pattern); -} - -#if 0 -ex resultantpoly(const ex & ee1, const ex & ee2, const ex & s) -{ - // Conversion necessary to count needed symbols beforehand - exmap repl; - ex poly_a = ee1.to_rational(repl); - ex poly_b = ee2.to_rational(repl); - - symbolset s1 = poly_a.symbols(); - const symbolset& s2 = poly_b.symbols(); - s1.insert(s2.begin(), s2.end()); - s1.insert(ex_to(s)); - the_dimension = s1.size(); - - ex_int_map map; - exvector revmap; - - giac::polynome p = poly_a.to_polynome(map, revmap); - giac::polynome q = poly_b.to_polynome(map, revmap); - giac::polynome d = giac::resultant(p, q); - return polynome_to_ex(d, revmap).subs(repl, subs_options::no_pattern); -} -#endif - -bool factorpoly(const ex& the_ex, ex& res_prod) -{ - if (is_exactly_a(the_ex) - or is_exactly_a(the_ex) - or is_exactly_a(the_ex) - or is_exactly_a(the_ex)) - return false; - - if (is_exactly_a(the_ex)) { - const mul& m = ex_to(the_ex); - exvector ev; - bool mchanged = false; - for (size_t i=0; i(the_ex)) { - const power& pow = ex_to(the_ex); - ex prod; - bool res = factorpoly(pow.op(0), prod); - if (not res) - return false; - res_prod = power(prod, pow.op(1)); - return true; - } - - if (not is_exactly_a(the_ex)) - throw(std::runtime_error("can't happen in factor")); - - if (context_ptr == nullptr) { - context_ptr=new giac::context(); - giac_zero = giac::gen(std::string("0"), context_ptr); - giac_one = giac::gen(std::string("1"), context_ptr); - } - - exmap repl; - ex poly = the_ex.to_rational(repl); - symbolset s1 = poly.symbols(); - the_dimension = s1.size(); - - ex_int_map map; - exvector revmap; - giac::polynome p = the_ex.to_polynome(map, revmap); - giac::polynome p_content(the_dimension); - giac::factorization f; - bool res = factor(p, p_content, f, - false, false, false, giac_one, giac_one); - if (not res) - return false; - res_prod = polynome_to_ex(p_content, revmap).subs(repl, subs_options::no_pattern); - for (auto fpair : f) - res_prod = mul(res_prod, - power(polynome_to_ex(fpair.fact, revmap).subs(repl, subs_options::no_pattern), - fpair.mult)); - return true; -} - -ex poly_mul_expand(const ex& a, const ex& b) -{ - exmap repl; - ex poly_a = a.to_rational(repl); - ex poly_b = b.to_rational(repl); - - symbolset s1 = poly_a.symbols(); - const symbolset& s2 = poly_b.symbols(); - s1.insert(s2.begin(), s2.end()); - the_dimension = s1.size(); - - ex_int_map map; - exvector revmap; - - giac::polynome p = poly_a.to_polynome(map, revmap); - giac::polynome q = poly_b.to_polynome(map, revmap); - giac::polynome d(the_dimension); - d = p * q; - - return polynome_to_ex(d, revmap).subs(repl, subs_options::no_pattern); -} - -} // namespace GiNaC - -#endif // HAVE_LIBGIAC diff --git a/src/sage/symbolic/ginac/mpoly-ginac.cpp b/src/sage/symbolic/ginac/mpoly-ginac.cpp index 608e0f6f207..02a07504a73 100644 --- a/src/sage/symbolic/ginac/mpoly-ginac.cpp +++ b/src/sage/symbolic/ginac/mpoly-ginac.cpp @@ -51,8 +51,6 @@ namespace GiNaC { -#ifndef PYNAC_HAVE_LIBGIAC - // If comparing expressions (ex::compare()) is fast, you can set this to 1. // Some routines like quo(), rem() and gcd() will then return a quick answer // when they are called with two identical arguments. @@ -547,7 +545,5 @@ ex sqrfree(const ex &a, const lst &l) #endif -#endif // HAVE_LIBGIAC - } // namespace GiNaC diff --git a/src/sage/symbolic/ginac/mpoly-singular.cpp b/src/sage/symbolic/ginac/mpoly-singular.cpp index 3050a96bac6..e66694ec1e0 100644 --- a/src/sage/symbolic/ginac/mpoly-singular.cpp +++ b/src/sage/symbolic/ginac/mpoly-singular.cpp @@ -344,8 +344,6 @@ static ex canonical_to_ex(const CanonicalForm& f, const exvector& revmap) } // GCD of two exes which are in polynomial form -// If giac is requested we stand back -#ifndef PYNAC_HAVE_LIBGIAC ex gcdpoly(const ex &a, const ex &b, ex *ca=nullptr, ex *cb=nullptr, bool check_args=true) { if (a.is_zero()) @@ -648,8 +646,6 @@ ex poly_mul_expand(const ex& a, const ex& b) return res; } -#endif //PYNAC_HAVE_LIBGIAC - ex resultantpoly(const ex & ee1, const ex & ee2, const ex & s) { ex_int_umap map; diff --git a/src/sage/symbolic/ginac/normal.cpp b/src/sage/symbolic/ginac/normal.cpp index d2c9e7be637..303f12d1aa7 100644 --- a/src/sage/symbolic/ginac/normal.cpp +++ b/src/sage/symbolic/ginac/normal.cpp @@ -1093,13 +1093,6 @@ static ex find_common_factor(const ex & e, ex & factor, exmap & repl) if (gc.is_one()) return e; -#ifdef PYNAC_HAVE_LIBGIAC - else { - ex f = 1; - gc = find_common_factor(gc, f, repl); - gc *= f; - } -#endif // The GCD is the factor we pull out factor *= gc; diff --git a/src/sage/symbolic/ginac/numeric.cpp b/src/sage/symbolic/ginac/numeric.cpp index 4bcf45e8793..a9bbfba9e15 100644 --- a/src/sage/symbolic/ginac/numeric.cpp +++ b/src/sage/symbolic/ginac/numeric.cpp @@ -74,15 +74,6 @@ #include "factory/factory.h" #pragma clang diagnostic pop -#ifdef PYNAC_HAVE_LIBGIAC -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE - -#include -#include -#include -#endif - //#define Logging_refctr #if defined(Logging_refctr) #undef Py_INCREF @@ -3258,33 +3249,6 @@ void numeric::canonicalize() } } -#ifdef PYNAC_HAVE_LIBGIAC -giac::gen* numeric::to_giacgen(giac::context* cptr) const -{ - if (t == LONG) - return new giac::gen(v._long); - if (t == MPZ) { - mpz_t bigint; - mpz_init_set(bigint, v._bigint); - auto ret = new giac::gen(bigint); - mpz_clear(bigint); - return ret; - } - if (t == MPQ) { - mpz_t bigint; - mpz_init_set(bigint, mpq_numref(v._bigrat)); - giac::gen gn(bigint); - mpz_set(bigint, mpq_denref(v._bigrat)); - giac::gen gd(bigint); - giac::Tfraction frac(gn, gd); - mpz_clear(bigint); - return new giac::gen(frac); - } - else - return nullptr; -} -#endif - CanonicalForm numeric::to_canonical() const { if (t == LONG) diff --git a/src/sage/symbolic/ginac/numeric.h b/src/sage/symbolic/ginac/numeric.h index 50b2b3d5e31..03697b2a474 100644 --- a/src/sage/symbolic/ginac/numeric.h +++ b/src/sage/symbolic/ginac/numeric.h @@ -64,12 +64,6 @@ PyObject* CC_get(); class CanonicalForm; -#ifdef PYNAC_HAVE_LIBGIAC -namespace giac { - class context; -} -#endif - namespace GiNaC { enum Type { @@ -246,9 +240,6 @@ class numeric : public basic { const numeric try_py_method(const std::string& s, const numeric& x2) const; const numeric to_dict_parent(PyObject* dict) const; -#ifdef PYNAC_HAVE_LIBGIAC - giac::gen* to_giacgen(giac::context*) const; -#endif CanonicalForm to_canonical() const; const numeric real() const; diff --git a/src/sage/symbolic/ginac/pseries.h b/src/sage/symbolic/ginac/pseries.h index 17a85f258b9..6073d1d360f 100644 --- a/src/sage/symbolic/ginac/pseries.h +++ b/src/sage/symbolic/ginac/pseries.h @@ -29,7 +29,7 @@ namespace GiNaC { /** This class holds a extended truncated power series (positive and negative - * integer powers). It consists of expression coefficients (only non-zero + * integer powers). It consists of expression coefficients (only nonzero * coefficients are stored), an expansion variable and an expansion point. * Other classes must provide members to convert into this type. */ class pseries : public basic diff --git a/src/sage/symbolic/ginac/pynac-config.h b/src/sage/symbolic/ginac/pynac-config.h index 4d686828c7f..00d7445049a 100644 --- a/src/sage/symbolic/ginac/pynac-config.h +++ b/src/sage/symbolic/ginac/pynac-config.h @@ -7,8 +7,5 @@ /* Current GiNaC archive file version number */ #define PYNAC_ARCHIVE_VERSION 3 -/* Define if you have libgiac */ -/* #undef PYNAC_HAVE_LIBGIAC */ - /* once: _PYNAC_CONFIG_H */ #endif diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index ea73c69ff74..5f647228564 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -12,7 +12,7 @@ def maxima_integrator(expression, v, a=None, b=None): """ - Integration using Maxima + Integration using Maxima. EXAMPLES:: @@ -49,7 +49,7 @@ def maxima_integrator(expression, v, a=None, b=None): def sympy_integrator(expression, v, a=None, b=None): """ - Integration using SymPy + Integration using SymPy. EXAMPLES:: @@ -71,7 +71,7 @@ def sympy_integrator(expression, v, a=None, b=None): def mma_free_integrator(expression, v, a=None, b=None): """ - Integration using Mathematica's online integrator + Integration using Mathematica's online integrator. EXAMPLES:: @@ -96,19 +96,17 @@ def mma_free_integrator(expression, v, a=None, b=None): Check that :issue:`14764` is resolved:: - sage: integrate(x^2, x, 0, 1, algorithm="mathematica_free") # optional - internet + sage: integrate(x^2, x, 0, 1, algorithm='mathematica_free') # optional - internet 1/3 - sage: integrate(sin(x), [x, 0, pi], algorithm="mathematica_free") # optional - internet + sage: integrate(sin(x), [x, 0, pi], algorithm='mathematica_free') # optional - internet 2 - sage: integrate(sqrt(x), (x, 0, 1), algorithm="mathematica_free") # optional - internet + sage: integrate(sqrt(x), (x, 0, 1), algorithm='mathematica_free') # optional - internet 2/3 :: sage: mma_free_integrator(exp(-x^2)*log(x), x) # optional - internet 1/2*sqrt(pi)*erf(x)*log(x) - x*hypergeometric((1/2, 1/2), (3/2, 3/2), -x^2) - - """ from sage.interfaces.mathematica import request_wolfram_alpha, parse_moutput_from_json, symbolic_expression_from_mathematica_string math_expr = expression._mathematica_init_() @@ -132,7 +130,7 @@ def mma_free_integrator(expression, v, a=None, b=None): def fricas_integrator(expression, v, a=None, b=None, noPole=True): """ - Integration using FriCAS + Integration using FriCAS. EXAMPLES:: @@ -151,7 +149,7 @@ def fricas_integrator(expression, v, a=None, b=None, noPole=True): Check that :issue:`25220` is fixed:: - sage: integral(sqrt(1-cos(x)), x, 0, 2*pi, algorithm="fricas") # optional - fricas + sage: integral(sqrt(1-cos(x)), x, 0, 2*pi, algorithm='fricas') # optional - fricas 4*sqrt(2) Check that in case of failure one gets unevaluated integral:: @@ -164,13 +162,13 @@ def fricas_integrator(expression, v, a=None, b=None, noPole=True): Check that :issue:`28641` is fixed:: - sage: integrate(sqrt(2)*x^2 + 2*x, x, algorithm="fricas") # optional - fricas + sage: integrate(sqrt(2)*x^2 + 2*x, x, algorithm='fricas') # optional - fricas 1/3*sqrt(2)*x^3 + x^2 - sage: integrate(sqrt(2), x, algorithm="fricas") # optional - fricas + sage: integrate(sqrt(2), x, algorithm='fricas') # optional - fricas sqrt(2)*x - sage: integrate(1, x, algorithm="fricas") # optional - fricas + sage: integrate(1, x, algorithm='fricas') # optional - fricas x Check that :issue:`28630` is fixed:: @@ -183,7 +181,7 @@ def fricas_integrator(expression, v, a=None, b=None, noPole=True): sage: var("a c d"); f = (I*a*tan(d*x + c) + a)*sec(d*x + c)^10 (a, c, d) - sage: ii = integrate(f, x, algorithm="fricas") # optional - fricas + sage: ii = integrate(f, x, algorithm='fricas') # optional - fricas sage: 1/315*(64512*I*a*e^(10*I*d*x + 10*I*c) + 53760*I*a*e^(8*I*d*x + 8*I*c) + 30720*I*a*e^(6*I*d*x + 6*I*c) + 11520*I*a*e^(4*I*d*x + 4*I*c) + 2560*I*a*e^(2*I*d*x + 2*I*c) + 256*I*a)/(d*e^(20*I*d*x + 20*I*c) + 10*d*e^(18*I*d*x + 18*I*c) + 45*d*e^(16*I*d*x + 16*I*c) + 120*d*e^(14*I*d*x + 14*I*c) + 210*d*e^(12*I*d*x + 12*I*c) + 252*d*e^(10*I*d*x + 10*I*c) + 210*d*e^(8*I*d*x + 8*I*c) + 120*d*e^(6*I*d*x + 6*I*c) + 45*d*e^(4*I*d*x + 4*I*c) + 10*d*e^(2*I*d*x + 2*I*c) + d) - ii # optional - fricas 0 """ @@ -218,7 +216,7 @@ def fricas_integrator(expression, v, a=None, b=None, noPole=True): def giac_integrator(expression, v, a=None, b=None): r""" - Integration using Giac + Integration using Giac. EXAMPLES:: @@ -259,7 +257,7 @@ def giac_integrator(expression, v, a=None, b=None): def libgiac_integrator(expression, v, a=None, b=None): r""" - Integration using libgiac + Integration using libgiac. EXAMPLES:: @@ -287,7 +285,15 @@ def libgiac_integrator(expression, v, a=None, b=None): sage: (F.derivative(x) - f).simplify_trig() 0 """ - from sage.libs.giac import libgiac + try: + from sage.libs.giac import libgiac + except ImportError: + # If libgiac isn't available, return a symbolic answer + # (without actually integrating anything). This is essentially + # the failure case of any integration: see below for what we + # do if libgiac is *available* but unable to do much. + return expression.integrate(v, a, b, hold=True) + from sage.libs.giac.giac import Pygen # We call Pygen on first argument because otherwise some expressions # involving derivatives result in doctest failures in interfaces/sympy.py diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index ebf0048dfe8..0877d132030 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -60,7 +60,7 @@ def __init__(self): Check for :issue:`28913`:: sage: Ex = (1-2*x^(1/3))^(3/4)/x - sage: integrate(Ex, x, algorithm="giac") # long time + sage: integrate(Ex, x, algorithm='giac') # long time 4*(-2*x^(1/3) + 1)^(3/4) + 6*arctan((-2*x^(1/3) + 1)^(1/4)) - 3*log((-2*x^(1/3) + 1)^(1/4) + 1) + 3*log(abs((-2*x^(1/3) + 1)^(1/4) - 1)) Check for :issue:`29833`:: @@ -68,20 +68,25 @@ def __init__(self): sage: (x,a,b)=var('x a b') sage: assume(b > 0) sage: f = (exp((x-a)/b) + 1)**(-1) - sage: (f*f).integrate(x, algorithm="mathematica_free") # optional -- internet + sage: (f*f).integrate(x, algorithm='mathematica_free') # optional -- internet -b*log(e^(a/b) + e^(x/b)) + x + b/(e^(-(a - x)/b) + 1) - Check for :issue:`25119`:: + After :issue:`25119` we can integrate the following function, + although giac and sympy give different-looking answers:: sage: result = integrate(sqrt(x^2)/x,x) ... - sage: result - x*sgn(x) + sage: result in [x*sgn(x), sqrt(x^2)] + True """ # The automatic evaluation routine will try these integrators # in the given order. This is an attribute of the class instead of # a global variable in this module to enable customization by # creating a subclasses which define a different set of integrators + # + # The libgiac integrator may immediately return a symbolic + # (unevaluated) answer if libgiac is unavailable. This essentially + # causes it to be skipped. self.integrators = [external.maxima_integrator, external.libgiac_integrator, external.sympy_integrator] @@ -106,8 +111,10 @@ def _eval_(self, f, x): sage: integrate(1/(x^4 + x^3 + 1), x) integrate(1/(x^4 + x^3 + 1), x) - Check that :issue:`32002` is fixed:: + Check that :issue:`32002` is fixed. This needs giac since only + giac can integrate it in any case:: + sage: # needs sage.libs.giac sage: result = integral(2*min_symbolic(x,2*x),x) ... sage: result @@ -392,9 +399,7 @@ def _normalize_integral_input(f, v, a=None, b=None): If the input contains endpoints, both endpoints must be given. - OUTPUT: - - - a tuple of ``f``, ``v``, ``a``, and ``b``. + OUTPUT: a tuple of ``f``, ``v``, ``a``, and ``b`` EXAMPLES:: @@ -452,8 +457,8 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): INPUT: - - ``v`` -- a variable or variable name. This can also be a tuple of - the variable (optional) and endpoints (i.e., ``(x,0,1)`` or ``(0,1)``). + - ``v`` -- a variable or variable name; this can also be a tuple of + the variable (optional) and endpoints (i.e., ``(x,0,1)`` or ``(0,1)``) - ``a`` -- (optional) lower endpoint of definite integral @@ -615,7 +620,7 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: _ = var('x, y, z') # optional - internet sage: f = sin(x^2) + y^z # optional - internet - sage: f.integrate(x, algorithm="mathematica_free") # optional - internet + sage: f.integrate(x, algorithm='mathematica_free') # optional - internet x*y^z + sqrt(1/2)*sqrt(pi)*fresnel_sin(sqrt(2)*x/sqrt(pi)) We can also use Sympy:: @@ -627,7 +632,7 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: _ = var('y, z') sage: (x^y - z).integrate(y) -y*z + x^y/log(x) - sage: (x^y - z).integrate(y, algorithm="sympy") # needs sympy + sage: (x^y - z).integrate(y, algorithm='sympy') # needs sympy -y*z + cases(((log(x) != 0, x^y/log(x)), (1, y))) We integrate the above function in Maple now:: @@ -661,7 +666,7 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): An example of an integral that fricas can integrate:: sage: f(x) = sqrt(x+sqrt(1+x^2))/x - sage: integrate(f(x), x, algorithm="fricas") # optional - fricas + sage: integrate(f(x), x, algorithm='fricas') # optional - fricas 2*sqrt(x + sqrt(x^2 + 1)) - 2*arctan(sqrt(x + sqrt(x^2 + 1))) - log(sqrt(x + sqrt(x^2 + 1)) + 1) + log(sqrt(x + sqrt(x^2 + 1)) - 1) @@ -685,9 +690,9 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): Both fricas and sympy give the correct result:: - sage: integrate(f(x), x, 1, 2, algorithm="fricas") # optional - fricas + sage: integrate(f(x), x, 1, 2, algorithm='fricas') # optional - fricas -1/2*pi + arctan(8) + arctan(5) + arctan(2) + arctan(1/2) - sage: integrate(f(x), x, 1, 2, algorithm="sympy") # needs sympy + sage: integrate(f(x), x, 1, 2, algorithm='sympy') # needs sympy -1/2*pi + arctan(8) + arctan(5) + arctan(2) + arctan(1/2) Using Giac to integrate the absolute value of a trigonometric expression:: @@ -872,7 +877,7 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: N(integrate(sin(x^2)/(x^2), x, 1, infinity), prec=54) 0.285736646322853 - sage: N(integrate(sin(x^2)/(x^2), x, 1, infinity)) # known bug (non-zero imag part) + sage: N(integrate(sin(x^2)/(x^2), x, 1, infinity)) # known bug (nonzero imag part) 0.285736646322853 Check that :issue:`14209` is fixed:: @@ -944,21 +949,38 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): Some integrals are now working (:issue:`27958`, using giac or sympy):: - sage: result = integrate(1/(1 + abs(x)), x) + sage: result = integrate(abs(x^2 - 1), x, -2, 2) ... sage: result - log(abs(x*sgn(x) + 1))/sgn(x) + 4 - sage: result = integrate(cos(x + abs(x)), x) + sage: result = integrate(sgn(x) - sgn(1-x), x) ... sage: result - sin(x*sgn(x) + x)/(sgn(x) + 1) + abs(x - 1) + abs(x) + + sage: result = integrate(1 / (1 + abs(x-5)), x, -5, 6) + ... + sage: result + log(11) + log(2) sage: result = integrate(abs(x^2 - 1), x, -2, 2) ... sage: result 4 + Examples that only giac can correctly integrate (for now):: + + sage: # needs sage.libs.giac + sage: g = abs(sin(x)*cos(x)) + sage: result = g.integrate(x, 0, 2*pi) + ... + sage: result + 2 + + :: + + sage: # needs sage.libs.giac sage: f = sqrt(x + 1/x^2) sage: actual = integrate(f, x) ... @@ -967,42 +989,46 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: bool(actual == expected) True - sage: g = abs(sin(x)*cos(x)) - sage: result = g.integrate(x, 0, 2*pi) - ... - sage: result - 2 + :: - sage: result = integrate(1/sqrt(abs(x)), x) + sage: # needs sage.libs.giac + sage: result = integrate(cos(x + abs(x)), x) ... sage: result - 2*sqrt(x*sgn(x))/sgn(x) + sin(x*sgn(x) + x)/(sgn(x) + 1) - sage: result = integrate(sgn(x) - sgn(1-x), x) + :: + + sage: # needs sage.libs.giac + sage: result = integrate(1/(1 + abs(x)), x) ... sage: result - abs(x - 1) + abs(x) + log(abs(x*sgn(x) + 1))/sgn(x) - sage: result = integrate(1 / (1 + abs(x-5)), x, -5, 6) + :: + + sage: # needs sage.libs.giac + sage: result = integrate(1/sqrt(abs(x)), x) ... sage: result - log(11) + log(2) + 2*sqrt(x*sgn(x))/sgn(x) + + :: + sage: # needs sage.libs.giac sage: result = integrate(1/(1 + abs(x)), x) ... sage: result log(abs(x*sgn(x) + 1))/sgn(x) + :: + + sage: # needs sage.libs.giac sage: result = integrate(cos(x + abs(x)), x) ... sage: result sin(x*sgn(x) + x)/(sgn(x) + 1) - sage: result = integrate(abs(x^2 - 1), x, -2, 2) - ... - sage: result - 4 - Some tests for :issue:`17468`:: sage: integral(log(abs(2*sin(x))), x, 0, pi/3) @@ -1047,7 +1073,7 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: var('a d x c') (a, d, x, c) sage: f = (I*a*tan(d*x + c) + a)^3*tan(d*x + c) - sage: integrate(f, x, algorithm="fricas") # optional - fricas + sage: integrate(f, x, algorithm='fricas') # optional - fricas -2/3*(24*a^3*e^(4*I*d*x + 4*I*c) + 33*a^3*e^(2*I*d*x + 2*I*c) + 13*a^3 + 6*(a^3*e^(6*I*d*x + 6*I*c) + 3*a^3*e^(4*I*d*x + 4*I*c) + 3*a^3*e^(2*I*d*x + 2*I*c) + a^3)*log(e^(2*I*d*x + 2*I*c) + 1))/(d*e^(6*I*d*x + 6*I*c) + 3*d*e^(4*I*d*x + 4*I*c) + 3*d*e^(2*I*d*x + 2*I*c) + d) The fundamental theorem of calculus holds for elliptic integrals diff --git a/src/sage/symbolic/meson.build b/src/sage/symbolic/meson.build new file mode 100644 index 00000000000..a9ca57ebf43 --- /dev/null +++ b/src/sage/symbolic/meson.build @@ -0,0 +1,152 @@ +inc_ginac = include_directories('ginac') +inc_pynac = include_directories('.') + +py.install_sources( + 'all.py', + 'assumptions.py', + 'benchmark.py', + 'callable.py', + 'complexity_measures.py', + 'constants.py', + 'expression.pxd', + 'expression_conversion_algebraic.py', + 'expression_conversion_sympy.py', + 'expression_conversions.py', + 'function.pxd', + 'function_factory.py', + 'maxima_wrapper.py', + 'operators.py', + 'pynac_wrap.h', + 'random_tests.py', + 'relation.py', + 'ring.pxd', + 'subring.py', + 'symbols.py', + 'symengine.py', + 'tests.py', + 'units.py', + subdir: 'sage/symbolic', +) + +extension_data = { + 'function' : files('function.pyx'), + 'ring' : files('ring.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/symbolic', + install: true, + include_directories: [ + inc_cpython, + inc_ext, + inc_ginac, + inc_gsl, + inc_pynac, + inc_rings, + ], + dependencies: [ + py_dep, + cypari2, + cysignals, + flint, + gmp, + gsl, + mpfr, + pari, + singular, + ], + ) +endforeach + +extension_data_cpp = { + 'expression': files( + 'expression.pyx', + 'ginac/add.cpp', + 'ginac/archive.cpp', + 'ginac/assume.cpp', + 'ginac/basic.cpp', + 'ginac/cmatcher.cpp', + 'ginac/constant.cpp', + 'ginac/context.cpp', + 'ginac/ex.cpp', + 'ginac/expair.cpp', + 'ginac/expairseq.cpp', + 'ginac/exprseq.cpp', + 'ginac/fderivative.cpp', + 'ginac/function.cpp', + 'ginac/function_info.cpp', + 'ginac/infinity.cpp', + 'ginac/infoflagbase.cpp', + 'ginac/inifcns.cpp', + 'ginac/inifcns_comb.cpp', + 'ginac/inifcns_gamma.cpp', + 'ginac/inifcns_hyperb.cpp', + 'ginac/inifcns_hyperg.cpp', + 'ginac/inifcns_nstdsums.cpp', + 'ginac/inifcns_orthopoly.cpp', + 'ginac/inifcns_trans.cpp', + 'ginac/inifcns_trig.cpp', + 'ginac/inifcns_zeta.cpp', + 'ginac/lst.cpp', + 'ginac/matrix.cpp', + 'ginac/mpoly-ginac.cpp', + 'ginac/mpoly-singular.cpp', + 'ginac/mpoly.cpp', + 'ginac/mul.cpp', + 'ginac/normal.cpp', + 'ginac/numeric.cpp', + 'ginac/operators.cpp', + 'ginac/order.cpp', + 'ginac/power.cpp', + 'ginac/print.cpp', + 'ginac/pseries.cpp', + 'ginac/py_funcs.cpp', + 'ginac/registrar.cpp', + 'ginac/relational.cpp', + 'ginac/remember.cpp', + 'ginac/sum.cpp', + 'ginac/symbol.cpp', + 'ginac/templates.cpp', + 'ginac/upoly-ginac.cpp', + 'ginac/useries.cpp', + 'ginac/utils.cpp', + 'ginac/wildcard.cpp', + ), +} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/symbolic', + install: true, + override_options: ['cython_language=cpp'], + cpp_args: '-std=c++11', + include_directories: [ + inc_cpython, + inc_ext, + inc_ginac, + inc_gsl, + inc_pynac, + inc_rings, + include_directories('../libs/gmp'), + ], + dependencies: [ + py_dep, + cypari2, + cysignals, + gmp, + flint, + gsl, + m, + mpfr, + pari, + singular, + ], + ) +endforeach + +install_subdir('integration', install_dir: sage_install_dir / 'symbolic') diff --git a/src/sage/symbolic/operators.py b/src/sage/symbolic/operators.py index 07add13f71e..fcada6cdcdf 100644 --- a/src/sage/symbolic/operators.py +++ b/src/sage/symbolic/operators.py @@ -72,7 +72,7 @@ def mul_vararg(first, *rest): operator.ge: '>='} -class FDerivativeOperator(): +class FDerivativeOperator: r""" Function derivative operators. @@ -123,7 +123,6 @@ def __call__(self, *args): sage: op = FDerivativeOperator(f, [0]) sage: op(1) D[0](f)(1) - """ if (not all(isinstance(x, Expression) and x.is_symbol() for x in args) or len(args) != len(set(args))): @@ -202,7 +201,7 @@ def parameter_set(self): return self._parameter_set -class DerivativeOperator(): +class DerivativeOperator: """ Derivative operator. @@ -226,9 +225,8 @@ class DerivativeOperator(): diff(f(x, y), x, y) sage: D[0, 1](f)(x, x^2) D[0, 1](f)(x, x^2) - """ - class DerivativeOperatorWithParameters(): + class DerivativeOperatorWithParameters: def __init__(self, parameter_set): self._parameter_set = parameter_set diff --git a/src/sage/symbolic/pynac_constant_impl.pxi b/src/sage/symbolic/pynac_constant_impl.pxi index 442afbafbc3..a158bbae1d9 100644 --- a/src/sage/symbolic/pynac_constant_impl.pxi +++ b/src/sage/symbolic/pynac_constant_impl.pxi @@ -25,7 +25,7 @@ cdef class PynacConstant: def __cinit__(self, name, texname, domain_string): """ - Creates a constant in Pynac. + Create a constant in Pynac. EXAMPLES:: @@ -75,7 +75,7 @@ cdef class PynacConstant: def serial(self): """ - Returns the underlying Pynac serial for this constant. + Return the underlying Pynac serial for this constant. EXAMPLES:: @@ -88,7 +88,7 @@ cdef class PynacConstant: def name(self): """ - Returns the name of this constant. + Return the name of this constant. EXAMPLES:: @@ -111,7 +111,7 @@ cdef class PynacConstant: def expression(self): """ - Returns this constant as an Expression. + Return this constant as an Expression. EXAMPLES:: diff --git a/src/sage/symbolic/pynac_function_impl.pxi b/src/sage/symbolic/pynac_function_impl.pxi index 6be7e7d4a16..a9faf2e7de7 100644 --- a/src/sage/symbolic/pynac_function_impl.pxi +++ b/src/sage/symbolic/pynac_function_impl.pxi @@ -13,7 +13,7 @@ cpdef call_registered_function(unsigned serial, - ``nargs`` -- declared number of args (0 is variadic) - - ``args`` -- a list of arguments to pass to the function; + - ``args`` -- list of arguments to pass to the function; each must be an :class:`Expression` - ``hold`` -- whether to leave the call unevaluated @@ -66,11 +66,9 @@ cpdef unsigned find_registered_function(name, int nargs) except -1: r""" Look up a function registered with Pynac (GiNaC). - Raise a ``ValueError`` if the function is not registered. + Raise a :exc:`ValueError` if the function is not registered. - OUTPUT: - - - serial number of the function, for use in :func:`call_registered_function` + OUTPUT: serial number of the function, for use in :func:`call_registered_function` EXAMPLES:: @@ -93,9 +91,7 @@ cpdef unsigned register_or_update_function(self, name, latex_name, int nargs, r""" Register the function ``self`` with Pynac (GiNaC). - OUTPUT: - - - serial number of the function, for use in :func:`call_registered_function` + OUTPUT: serial number of the function, for use in :func:`call_registered_function` EXAMPLES:: diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index f31a5498218..967ff18d020 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -136,7 +136,7 @@ def unpack_operands(Expression ex): cdef exvector_to_PyTuple(GExVector seq): """ - Converts arguments list given to a function to a PyTuple. + Convert arguments list given to a function to a PyTuple. Used to pass arguments to python methods assigned to custom evaluation, derivative, etc. functions of symbolic functions. @@ -167,7 +167,6 @@ cdef exvector_to_PyTuple(GExVector seq): len(args): 2, types: [, ] len(args): 2, types: [, ] tfunc(sin(x), tfunc(1, x^2)) - """ from sage.symbolic.ring import SR res = [] @@ -182,7 +181,7 @@ cdef exvector_to_PyTuple(GExVector seq): cdef GEx pyExpression_to_ex(res) except *: """ - Converts an Expression object to a GiNaC::ex. + Convert an Expression object to a GiNaC::ex. Used to pass return values of custom python evaluation, derivation functions back to C++ level. @@ -198,7 +197,7 @@ cdef GEx pyExpression_to_ex(res) except *: cdef paramset_to_PyTuple(const_paramset_ref s): """ - Converts a std::multiset to a PyTuple. + Convert a std::multiset to a PyTuple. Used to pass a list of parameter numbers with respect to which a function is differentiated to the printing functions py_print_fderivative and @@ -238,7 +237,7 @@ cdef set_ginac_fn_serial(): cdef int py_get_ginac_serial() noexcept: """ - Returns the number of C++ level functions defined by GiNaC. + Return the number of C++ level functions defined by GiNaC. EXAMPLES:: @@ -378,7 +377,7 @@ cdef stdstring* py_latex(o, int level) noexcept: cdef stdstring* string_from_pystr(py_str) except NULL: """ - Creates a C++ string with the same contents as the given python string. + Create a C++ string with the same contents as the given python string. Used when passing string output to Pynac for printing, since we don't want to mess with reference counts of the python objects and we cannot guarantee @@ -448,10 +447,10 @@ def py_print_function_pystring(id, args, fname_paren=False): INPUT: - - id -- serial number of the corresponding symbolic function - - params -- Set of parameter numbers with respect to which to take the - derivative. - - args -- arguments of the function. + - ``id`` -- serial number of the corresponding symbolic function + - ``params`` -- set of parameter numbers with respect to which to take the + derivative + - ``args`` -- arguments of the function EXAMPLES:: @@ -558,8 +557,6 @@ def py_latex_function_pystring(id, args, fname_paren=False): True sage: py_latex_function_pystring(i, (x,y^z)) 'my args are: x, y^z' - - """ cdef Function func = get_sfunction_from_serial(id) # This function is called from two places, from function::print in Pynac @@ -635,10 +632,10 @@ cdef stdstring* py_print_fderivative(unsigned id, params, INPUT: - - id -- serial number of the corresponding symbolic function - - params -- Set of parameter numbers with respect to which to take the - derivative. - - args -- arguments of the function. + - ``id`` -- serial number of the corresponding symbolic function + - ``params`` -- set of parameter numbers with respect to which to take the + derivative + - ``args`` -- arguments of the function """ if all(tolerant_is_symbol(a) for a in args) and len(set(args)) == len(args): diffvarstr = ', '.join(repr(args[i]) for i in params) @@ -681,7 +678,6 @@ def py_print_fderivative_for_doctests(id, params, args): True sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z)) D[0, 1, 0, 1]func_with_args(x, y^z) - """ cdef stdstring* ostr = py_print_fderivative(id, params, args) print(char_to_str(ostr.c_str())) @@ -695,7 +691,6 @@ cdef stdstring* py_latex_fderivative(unsigned id, params, symbolic function specified by the given id, lists of params and args. See documentation of py_print_fderivative for more information. - """ if all(tolerant_is_symbol(a) for a in args) and len(set(args)) == len(args): param_iter = iter(params) @@ -927,11 +922,9 @@ def test_binomial(n, k): INPUT: - - n, k -- integers, with k >= 0. + - ``n``, ``k`` -- integers, with ``k >= 0`` - OUTPUT: - - integer + OUTPUT: integer EXAMPLES:: @@ -989,7 +982,7 @@ cdef py_lcm(n, k): ################################################################# cdef py_real(x): """ - Returns the real part of x. + Return the real part of x. TESTS:: @@ -1118,14 +1111,14 @@ cdef bint py_is_rational(x) noexcept: cdef bint py_is_equal(x, y) noexcept: """ - Return True precisely if x and y are equal. + Return ``True`` precisely if x and y are equal. """ return bool(x == y) cdef bint py_is_integer(x) noexcept: r""" - Returns True if pynac should treat this object as an integer. + Return ``True`` if pynac should treat this object as an integer. EXAMPLES:: @@ -1195,7 +1188,7 @@ cdef bint py_is_crational(x) noexcept: def py_is_crational_for_doctest(x): r""" - Return True if pynac should treat this object as an element of `\QQ(i)`. + Return ``True`` if pynac should treat this object as an element of `\QQ(i)`. TESTS:: @@ -1286,6 +1279,7 @@ cdef py_numer(n): except AttributeError: return n + def py_numer_for_doctests(n): """ This function is used to test py_numer(). @@ -1341,7 +1335,7 @@ cdef bint py_is_cinteger(x) noexcept: def py_is_cinteger_for_doctest(x): r""" - Returns True if pynac should treat this object as an element of `\ZZ(i)`. + Return ``True`` if pynac should treat this object as an element of `\ZZ(i)`. TESTS:: @@ -1397,6 +1391,7 @@ cdef py_float(n, PyObject* kwds): except TypeError: return CC(n) + def py_float_for_doctests(n, kwds): """ This function is for testing py_float. @@ -1457,6 +1452,7 @@ cdef py_tgamma(x): return CC(res) return res + def py_tgamma_for_doctests(x): """ This function is for testing py_tgamma(). @@ -1481,8 +1477,8 @@ cdef py_factorial(x): sage: py_factorial(-2/3) 2.67893853470775 """ - # factorial(x) is only defined for non-negative integers x - # so we first test if x can be coerced into ZZ and is non-negative. + # factorial(x) is only defined for nonnegative integers x + # so we first test if x can be coerced into ZZ and is nonnegative. # If this is not the case then we return the symbolic expression gamma(x+1) # This fixes Issue 9240 try: @@ -1496,6 +1492,7 @@ cdef py_factorial(x): else: return py_tgamma(x+1) + def py_factorial_py(x): """ This function is a python wrapper around py_factorial(). This wrapper @@ -1517,6 +1514,7 @@ cdef py_doublefactorial(x): from sage.misc.misc_c import prod # fast balanced product return prod([n - 2*i for i in range(n//2)]) + def doublefactorial(n): """ The double factorial combinatorial function: @@ -1525,7 +1523,7 @@ def doublefactorial(n): INPUT: - - n -- an integer > = 1 + - ``n`` -- integer ``>= 1`` EXAMPLES:: @@ -1611,7 +1609,7 @@ cdef py_stieltjes(x): """ Return the Stieltjes constant of the given index. - The value is expected to be a non-negative integer. + The value is expected to be a nonnegative integer. TESTS:: @@ -1637,6 +1635,7 @@ cdef py_stieltjes(x): prec = 53 return mpmath_utils.call(mpmath.stieltjes, n, prec=prec) + def py_stieltjes_for_doctests(x): """ This function is for testing py_stieltjes(). @@ -1671,6 +1670,7 @@ cdef py_zeta(x): except AttributeError: return CC(x).zeta() + def py_zeta_for_doctests(x): """ This function is for testing py_zeta(). @@ -1712,6 +1712,7 @@ cdef py_exp(x): except (TypeError, ValueError): return CC(x).exp() + def py_exp_for_doctests(x): """ This function tests py_exp. @@ -1781,6 +1782,7 @@ cdef py_log(x): except (TypeError, ValueError): return CC(x).log() + def py_log_for_doctests(x): """ This function tests py_log. @@ -2117,7 +2119,7 @@ cdef int py_int_length(x) except -1: cdef py_li(x, n, parent): """ - Returns a numerical approximation of polylog(n, x) with precision given + Return a numerical approximation of polylog(n, x) with precision given by the ``parent`` argument. EXAMPLES:: @@ -2202,6 +2204,7 @@ cdef py_psi2(n, x): prec = 53 return mpmath_utils.call(mpmath.psi, n, x, prec=prec) + def py_psi2_for_doctests(n, x): """ This function is a python wrapper so py_psi2 can be tested. The real tests @@ -2251,9 +2254,8 @@ def py_li2_for_doctests(x): cdef GConstant py_get_constant(const char* name) noexcept: """ - Returns a constant given its name. This is called by - constant::unarchive in constant.cpp in Pynac and is used for - pickling. + Return a constant given its name. This is called by constant::unarchive in + constant.cpp in Pynac and is used for pickling. """ from sage.symbolic.constants import constants_name_table cdef PynacConstant pc @@ -2271,11 +2273,12 @@ cdef py_eval_constant(unsigned serial, kwds): cdef py_eval_unsigned_infinity(): """ - Returns unsigned_infinity. + Return ``unsigned_infinity``. """ from sage.rings.infinity import unsigned_infinity return unsigned_infinity + def py_eval_unsigned_infinity_for_doctests(): """ This function tests py_eval_unsigned_infinity. @@ -2290,11 +2293,12 @@ def py_eval_unsigned_infinity_for_doctests(): cdef py_eval_infinity(): """ - Returns positive infinity, i.e., oo. + Return positive infinity, i.e., oo. """ from sage.rings.infinity import infinity return infinity + def py_eval_infinity_for_doctests(): """ This function tests py_eval_infinity. @@ -2309,11 +2313,12 @@ def py_eval_infinity_for_doctests(): cdef py_eval_neg_infinity(): """ - Returns minus_infinity. + Return ``minus_infinity``. """ from sage.rings.infinity import minus_infinity return minus_infinity + def py_eval_neg_infinity_for_doctests(): """ This function tests py_eval_neg_infinity. @@ -2385,7 +2390,7 @@ def init_pynac_I(): sage: symbolic_I^2 -1 - Note that conversions to real fields will give :class:`TypeError`:: + Note that conversions to real fields will give :exc:`TypeError`:: sage: float(symbolic_I) Traceback (most recent call last): @@ -2472,7 +2477,7 @@ def init_pynac_I(): def init_function_table(): """ - Initializes the function pointer table in Pynac. This must be + Initialize the function pointer table in Pynac. This must be called before Pynac is used; otherwise, there will be segfaults. """ diff --git a/src/sage/symbolic/random_tests.py b/src/sage/symbolic/random_tests.py index 6410f797521..3291fe3cea0 100644 --- a/src/sage/symbolic/random_tests.py +++ b/src/sage/symbolic/random_tests.py @@ -80,11 +80,11 @@ def normalize_prob_list(pl, extra=()): r""" INPUT: - - ``pl`` -- A list of tuples, where the first element of each tuple is + - ``pl`` -- list of tuples, where the first element of each tuple is a floating-point number (representing a relative probability). The second element of each tuple may be a list or any other kind of object. - - ``extra`` -- A tuple which is to be appended to every tuple in ``pl``. + - ``extra`` -- tuple which is to be appended to every tuple in ``pl`` This function takes such a list of tuples (a "probability list") and normalizes the probabilities so that they sum to one. If any of the @@ -131,9 +131,9 @@ def choose_from_prob_list(lst): r""" INPUT: - - ``lst`` -- A list of tuples, where the first element of each tuple + - ``lst`` -- list of tuples, where the first element of each tuple is a nonnegative float (a probability), and the probabilities sum - to one. + to one OUTPUT: @@ -250,7 +250,6 @@ def random_expr_helper(n_nodes, internal, leaves, verbose): sage: our_exprs = set() sage: while our_exprs != all_exprs: ....: our_exprs.add(next_expr()) - """ if n_nodes == 1: return choose_from_prob_list(leaves)[1] @@ -259,8 +258,7 @@ def random_expr_helper(n_nodes, internal, leaves, verbose): n_nodes -= 1 n_children = r[2] n_spare_nodes = n_nodes - n_children - if n_spare_nodes <= 0: - n_spare_nodes = 0 + n_spare_nodes = max(0, n_spare_nodes) nodes_per_child = random_integer_vector(n_spare_nodes, n_children) children = [random_expr_helper(n + 1, internal, leaves, verbose) for n in nodes_per_child] @@ -311,7 +309,6 @@ def random_expr(size, nvars=1, ncoeffs=None, var_frac=0.5, About to apply sgn to [v1] About to apply to [1/31, sgn(v1)] sgn(v1) + 1/31 - """ vars = [(1.0, SR.var('v%d' % (n + 1))) for n in range(nvars)] if ncoeffs is None: @@ -349,14 +346,14 @@ def assert_strict_weak_order(a, b, c, cmp_func): INPUT: - - ``a``, ``b``, ``c`` -- anything that can be compared by ``cmp_func``. + - ``a``, ``b``, ``c`` -- anything that can be compared by ``cmp_func`` - ``cmp_func`` -- function of two arguments that returns their - comparison (i.e. either ``True`` or ``False``). + comparison (i.e. either ``True`` or ``False``) OUTPUT: - Does not return anything. Raises a ``ValueError`` if ``cmp_func`` + Nothing. Raises a :exc:`ValueError` if ``cmp_func`` is not a strict weak order on the three given elements. REFERENCES: @@ -423,7 +420,7 @@ def incomparable(i, j): def test_symbolic_expression_order(repetitions=100): r""" - Tests whether the comparison of random symbolic expressions + Test whether the comparison of random symbolic expressions satisfies the strict weak order axioms. This is important because the C++ extension class uses diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 5e2b3bd7c9f..d0098871834 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -362,9 +362,8 @@ def test_relation_maxima(relation): """ - Return True if this (in)equality is definitely true. Return False - if it is false or the algorithm for testing (in)equality is - inconclusive. + Return ``True`` if this (in)equality is definitely true. Return ``False`` + if it is false or the algorithm for testing (in)equality is inconclusive. EXAMPLES:: @@ -590,42 +589,42 @@ def solve(f, *args, **kwds): INPUT: - - ``f`` -- equation or system of equations (given by a - list or tuple) + - ``f`` -- equation or system of equations (given by a list or tuple) - - ``*args`` -- variables to solve for. + - ``*args`` -- variables to solve for - - ``solution_dict`` -- bool (default: ``False``); if True or non-zero, - return a list of dictionaries containing the solutions. If there - are no solutions, return an empty list (rather than a list containing - an empty dictionary). Likewise, if there's only a single solution, - return a list containing one dictionary with that solution. + - ``solution_dict`` -- boolean (default: ``False``); if ``True`` or nonzero, + return a list of dictionaries containing the solutions. If there + are no solutions, return an empty list (rather than a list containing + an empty dictionary). Likewise, if there's only a single solution, + return a list containing one dictionary with that solution. There are a few optional keywords if you are trying to solve a single equation. They may only be used in that context. - - ``multiplicities`` -- bool (default: ``False``); if True, - return corresponding multiplicities. This keyword is - incompatible with ``to_poly_solve=True`` and does not make - any sense when solving inequalities. + - ``multiplicities`` -- boolean (default: ``False``); if True, + return corresponding multiplicities. This keyword is + incompatible with ``to_poly_solve=True`` and does not make + any sense when solving inequalities. - - ``explicit_solutions`` -- bool (default: ``False``); require that - all roots be explicit rather than implicit. Not used - when solving inequalities. + - ``explicit_solutions`` -- boolean (default: ``False``); require that + all roots be explicit rather than implicit. Not used + when solving inequalities. - - ``to_poly_solve`` -- bool (default: ``False``) or string; use - Maxima's ``to_poly_solver`` package to search for more possible - solutions, but possibly encounter approximate solutions. - This keyword is incompatible with ``multiplicities=True`` - and is not used when solving inequalities. Setting ``to_poly_solve`` - to 'force' (string) omits Maxima's solve command (useful when - some solutions of trigonometric equations are lost). + - ``to_poly_solve`` -- boolean (default: ``False``) or string; use + Maxima's ``to_poly_solver`` package to search for more possible + solutions, but possibly encounter approximate solutions. + This keyword is incompatible with ``multiplicities=True`` + and is not used when solving inequalities. Setting ``to_poly_solve`` + to 'force' (string) omits Maxima's solve command (useful when + some solutions of trigonometric equations are lost). - - ``algorithm`` -- string (default: 'maxima'); to use SymPy's + - ``algorithm`` -- string (default: ``'maxima'``); to use SymPy's solvers set this to 'sympy'. Note that SymPy is always used - for diophantine equations. Another choice is 'giac'. + for diophantine equations. Another choice, if it is installed, + is 'giac'. - - ``domain`` -- string (default: 'complex'); setting this to 'real' + - ``domain`` -- string (default: ``'complex'``); setting this to 'real' changes the way SymPy solves single equations; inequalities are always solved in the real domain. @@ -928,13 +927,16 @@ def solve(f, *args, **kwds): A basic interface to Giac is provided:: + sage: # needs sage.libs.giac sage: solve([(2/3)^x-2], [x], algorithm='giac') ...[[-log(2)/(log(3) - log(2))]] + sage: # needs sage.libs.giac sage: f = (sin(x) - 8*cos(x)*sin(x))*(sin(x)^2 + cos(x)) - (2*cos(x)*sin(x) - sin(x))*(-2*sin(x)^2 + 2*cos(x)^2 - cos(x)) sage: solve(f, x, algorithm='giac') ...[-2*arctan(sqrt(2)), 0, 2*arctan(sqrt(2)), pi] + sage: # needs sage.libs.giac sage: x, y = SR.var('x,y') sage: solve([x+y-4,x*y-3],[x,y],algorithm='giac') [[1, 3], [3, 1]] @@ -1432,21 +1434,24 @@ def _giac_solver(f, x, solution_dict=False): - ``f`` -- equation or list of equations - ``x`` -- variable or list of variables - - ``solution_dict`` -- optional boolean (default ``False``) + - ``solution_dict`` -- boolean (default: ``False``) EXAMPLES:: + sage: # needs sage.libs.giac sage: solve([(2/3)^x-2], [x], algorithm='giac') ...[[-log(2)/(log(3) - log(2))]] sage: solve([(2/3)^x-2], [x], algorithm='giac', solution_dict=True) ...[{x: -log(2)/(log(3) - log(2))}] + sage: # needs sage.libs.giac sage: f = (sin(x) - 8*cos(x)*sin(x))*(sin(x)^2 + cos(x)) - (2*cos(x)*sin(x) - sin(x))*(-2*sin(x)^2 + 2*cos(x)^2 - cos(x)) sage: solve(f, x, algorithm='giac') ...[-2*arctan(sqrt(2)), 0, 2*arctan(sqrt(2)), pi] sage: solve(f, x, algorithm='giac', solution_dict=True) ...[{x: -2*arctan(sqrt(2))}, {x: 0}, {x: 2*arctan(sqrt(2))}, {x: pi}] + sage: # needs sage.libs.giac sage: x, y = SR.var('x,y') sage: solve([x+y-7,x*y-10],[x,y],algorithm='giac') [[2, 5], [5, 2]] @@ -1460,7 +1465,7 @@ def _giac_solver(f, x, solution_dict=False): if not sols: return [] if isinstance(sols[0], list): - return [{v: sv for v, sv in zip(x, solution)} for solution in sols] + return [dict(zip(x, solution)) for solution in sols] return [{x: sx} for sx in sols] return sols @@ -1477,17 +1482,15 @@ def solve_mod(eqns, modulus, solution_dict=False): INPUT: + - ``eqns`` -- equation or list of equations - - ``eqns`` -- equation or list of equations - - - ``modulus`` -- an integer - - - ``solution_dict`` -- bool (default: ``False``); if True or non-zero, - return a list of dictionaries containing the solutions. If there - are no solutions, return an empty list (rather than a list containing - an empty dictionary). Likewise, if there's only a single solution, - return a list containing one dictionary with that solution. + - ``modulus`` -- integer + - ``solution_dict`` -- boolean (default: ``False``); if ``True`` or nonzero, + return a list of dictionaries containing the solutions. If there + are no solutions, return an empty list (rather than a list containing + an empty dictionary). Likewise, if there's only a single solution, + return a list containing one dictionary with that solution. EXAMPLES:: @@ -1625,15 +1628,13 @@ def _solve_mod_prime_power(eqns, p, m, vars): INPUT: + - ``eqns`` -- equation or list of equations - - ``eqns`` -- equation or list of equations - - - ``p`` -- a prime - - - ``i`` -- an integer > 0 + - ``p`` -- a prime - - ``vars`` -- a list of variables to solve for + - ``i`` -- integer > 0 + - ``vars`` -- list of variables to solve for EXAMPLES:: @@ -1753,7 +1754,7 @@ def solve_ineq_univar(ineq): def solve_ineq_fourier(ineq, vars=None): """ - Solves system of inequalities using Maxima and Fourier elimination + Solve system of inequalities using Maxima and Fourier elimination. Can be used for system of linear inequalities and for some types of nonlinear inequalities. For examples, see the example section @@ -1764,7 +1765,7 @@ def solve_ineq_fourier(ineq, vars=None): - ``ineq`` -- list with system of inequalities - - ``vars`` -- optionally list with variables for Fourier elimination. + - ``vars`` -- optionally list with variables for Fourier elimination OUTPUT: @@ -1809,7 +1810,7 @@ def solve_ineq_fourier(ineq, vars=None): setvars = set([]) for i in (ineq): setvars = setvars.union(set(i.variables())) - vars = [i for i in setvars] + vars = list(setvars) ineq0 = [i._maxima_() for i in ineq] ineq0[0].parent().eval("if fourier_elim_loaded#true then (fourier_elim_loaded:true,load(\"fourier_elim\"))") sol = ineq0[0].parent().fourier_elim(ineq0, vars) @@ -1827,7 +1828,7 @@ def solve_ineq_fourier(ineq, vars=None): def solve_ineq(ineq, vars=None): """ - Solves inequalities and systems of inequalities using Maxima. + Solve inequalities and systems of inequalities using Maxima. Switches between rational inequalities (sage.symbolic.relation.solve_ineq_rational) and Fourier elimination (sage.symbolic.relation.solve_ineq_fouried). @@ -1849,7 +1850,7 @@ def solve_ineq(ineq, vars=None): http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/contrib/fourier_elim/rtest_fourier_elim.mac for a big gallery of problems covered by this algorithm. - - ``vars`` -- optional parameter with list of variables. This list + - ``vars`` -- (optional) parameter with list of variables. This list is used only if Fourier elimination is used. If omitted or if rational inequality is solved, then variables are determined automatically. diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 501b0920898..32afe8d3a62 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -83,7 +83,6 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): sage: isinstance(SR, sage.symbolic.ring.SymbolicRing) True sage: TestSuite(SR).run(skip=['_test_divides']) - """ if base_ring is None: base_ring = self @@ -208,8 +207,8 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): return False else: from sage.rings.fraction_field import FractionField_generic - from sage.rings.polynomial.polynomial_ring import is_PolynomialRing - from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing + from sage.rings.polynomial.polynomial_ring import PolynomialRing_general + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic from sage.rings.infinity import InfinityRing, UnsignedInfinityRing from sage.rings.real_lazy import RLF, CLF @@ -220,7 +219,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): if R._is_numerical(): # Almost anything with a coercion into any precision of CC return R not in (RLF, CLF) - elif is_PolynomialRing(R) or is_MPolynomialRing(R) or isinstance(R, FractionField_generic) or isinstance(R, LaurentPolynomialRing_generic): + elif isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base) or isinstance(R, FractionField_generic) or isinstance(R, LaurentPolynomialRing_generic): base = R.base_ring() return base is not self and self.has_coerce_map_from(base) elif (R is InfinityRing or R is UnsignedInfinityRing @@ -384,13 +383,13 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): INPUT: - - ``x`` -- a Python object. + - ``x`` -- a Python object - - ``force`` -- bool, default ``False``, if True, the Python object - is taken as is without attempting coercion or list traversal. + - ``force`` -- boolean (default: ``False``); if ``True``, the Python object + is taken as is without attempting coercion or list traversal - - ``recursive`` -- bool, default ``True``, disables recursive - traversal of lists. + - ``recursive`` -- boolean (default: ``True``); disables recursive + traversal of lists EXAMPLES:: @@ -442,11 +441,9 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): INPUT: - - ``n`` -- a nonnegative integer - - OUTPUT: + - ``n`` -- nonnegative integer - - ``n``-th wildcard expression + OUTPUT: n-th wildcard expression EXAMPLES:: @@ -477,7 +474,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): def __contains__(self, x): r""" - True if there is an element of the symbolic ring that is equal to x + ``True`` if there is an element of the symbolic ring that is equal to x under ``==``. EXAMPLES: @@ -511,9 +508,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): """ Return the characteristic of the symbolic ring, which is 0. - OUTPUT: - - - a Sage integer + OUTPUT: a Sage integer EXAMPLES:: @@ -538,7 +533,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): def is_field(self, proof=True): """ - Returns True, since the symbolic expression ring is (for the most + Return ``True``, since the symbolic expression ring is (for the most part) a field. EXAMPLES:: @@ -766,9 +761,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): by default, and possible options are (non-exhaustive list, see note below): ``'real'``, ``'complex'``, ``'positive'``, ``'integer'`` and ``'noninteger'`` - OUTPUT: - - Symbolic expression or tuple of symbolic expressions. + OUTPUT: symbolic expression or tuple of symbolic expressions .. SEEALSO:: @@ -1052,22 +1045,20 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): Choose one of the following keywords to create a subring. - - ``accepting_variables`` (default: ``None``) -- a tuple or other + - ``accepting_variables`` -- (default: ``None``) a tuple or other iterable of variables. If specified, then a symbolic subring of expressions in only these variables is created. - - ``rejecting_variables`` (default: ``None``) -- a tuple or other + - ``rejecting_variables`` -- (default: ``None``) a tuple or other iterable of variables. If specified, then a symbolic subring of expressions in variables distinct to these variables is created. - - ``no_variables`` (default: ``False``) -- a boolean. If set, + - ``no_variables`` -- boolean (default: ``False``); if set, then a symbolic subring of constant expressions (i.e., expressions without a variable) is created. - OUTPUT: - - A ring. + OUTPUT: a ring EXAMPLES: @@ -1162,6 +1153,8 @@ cdef class NumpyToSRMorphism(Morphism): We check that :issue:`8949` and :issue:`9769` are fixed (see also :issue:`18076`):: sage: import numpy # needs numpy + sage: if int(numpy.version.short_version[0]) > 1: # needs numpy + ....: numpy.set_printoptions(legacy="1.25") # needs numpy sage: f(x) = x^2 sage: f(numpy.int8('2')) # needs numpy 4 @@ -1340,11 +1333,9 @@ def isidentifier(x): INPUT: - - ``x`` -- a string - - OUTPUT: + - ``x`` -- string - Boolean. Whether the string ``x`` can be used as a variable name. + OUTPUT: boolean; whether the string ``x`` can be used as a variable name This function should return ``False`` for keywords, so we can not just use the ``isidentifier`` method of strings, diff --git a/src/sage/symbolic/series_impl.pxi b/src/sage/symbolic/series_impl.pxi index 3f869920d6b..b66e43aae86 100644 --- a/src/sage/symbolic/series_impl.pxi +++ b/src/sage/symbolic/series_impl.pxi @@ -141,16 +141,14 @@ cdef class SymbolicSeries(Expression): def is_terminating_series(self): """ - Return True if the series is without order term. + Return ``True`` if the series is without order term. A series is terminating if it can be represented exactly, without requiring an order term. You can explicitly request terminating series by setting the order to positive infinity. - OUTPUT: - - Boolean. ``True`` if the series has no order term. + OUTPUT: boolean; ``True`` if the series has no order term EXAMPLES:: @@ -170,9 +168,7 @@ cdef class SymbolicSeries(Expression): Given a power series or expression, return the corresponding expression without the big oh. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression EXAMPLES:: @@ -209,20 +205,18 @@ cdef class SymbolicSeries(Expression): INPUT: - - ``x`` -- optional variable. - - - ``sparse`` -- Boolean. If ``False`` return a list with as much - entries as the order of the series. + - ``x`` -- (optional) variable - OUTPUT: + - ``sparse`` -- boolean (default: ``True``); if ``False`` return a list + with as much entries as the order of the series - Depending on the value of ``sparse``, + OUTPUT: depending on the value of ``sparse``, - A list of pairs ``(expr, n)``, where ``expr`` is a symbolic expression and ``n`` is a power (``sparse=True``, default) - A list of expressions where the ``n``-th element is the coefficient of - ``x^n`` when self is seen as polynomial in ``x`` (``sparse=False``). + ``x^n`` when ``self`` is seen as polynomial in ``x`` (``sparse=False``). EXAMPLES:: diff --git a/src/sage/symbolic/subring.py b/src/sage/symbolic/subring.py index 2db60e8f915..20f5bf62287 100644 --- a/src/sage/symbolic/subring.py +++ b/src/sage/symbolic/subring.py @@ -111,16 +111,16 @@ class SymbolicSubringFactory(UniqueFactory): Specify one of the following keywords to create a subring. - - ``accepting_variables`` (default: ``None``) -- a tuple or other + - ``accepting_variables`` -- (default: ``None``) a tuple or other iterable of variables. If specified, then a symbolic subring of expressions in only these variables is created. - - ``rejecting_variables`` (default: ``None``) -- a tuple or other + - ``rejecting_variables`` -- (default: ``None``) a tuple or other iterable of variables. If specified, then a symbolic subring of expressions in variables distinct to these variables is created. - - ``no_variables`` (default: ``False``) -- a boolean. If set, + - ``no_variables`` -- boolean (default: ``False``); if set, then a symbolic subring of constant expressions (i.e., expressions without a variable) is created. @@ -254,7 +254,7 @@ def __init__(self, vars): INPUT: - - ``vars`` -- a tuple of symbolic variables. + - ``vars`` -- tuple of symbolic variables TESTS:: @@ -286,9 +286,7 @@ def _repr_variables_(self): r""" Return a representation string of the variables. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -314,11 +312,9 @@ def has_valid_variable(self, variable): INPUT: - - ``variable`` -- a symbolic variable. - - OUTPUT: + - ``variable`` -- a symbolic variable - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -332,15 +328,13 @@ def has_valid_variable(self, variable): def _element_constructor_(self, x): r""" - Creates the element of this subring specified by the input ``x``. + Create the element of this subring specified by the input ``x``. INPUT: - - ``x`` -- an object. - - OUTPUT: + - ``x`` -- an object - An element of this symbolic subring. + OUTPUT: an element of this symbolic subring TESTS:: @@ -368,11 +362,9 @@ def _coerce_map_from_(self, P): INPUT: - - ``P`` -- a parent. + - ``P`` -- a parent - OUTPUT: - - A boolean or ``None``. + OUTPUT: boolean or ``None`` TESTS:: @@ -487,7 +479,7 @@ class GenericSymbolicSubringFunctor(ConstructionFunctor): INPUT: - - ``vars`` -- a tuple, set, or other iterable of symbolic variables. + - ``vars`` -- tuple, set, or other iterable of symbolic variables EXAMPLES:: @@ -528,9 +520,7 @@ def _repr_variables_(self): r""" Return a representation string of the variables. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -545,9 +535,7 @@ def _repr_(self): r""" Return a representation string of this functor. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -569,11 +557,9 @@ def merge(self, other): INPUT: - - ``other`` -- a functor. + - ``other`` -- a functor - OUTPUT: - - A functor or ``None``. + OUTPUT: a functor or ``None`` EXAMPLES:: @@ -591,11 +577,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -612,11 +596,9 @@ def __ne__(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -637,9 +619,7 @@ def _repr_(self): r""" Return a representation string of this symbolic subring. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -656,11 +636,9 @@ def has_valid_variable(self, variable): INPUT: - - ``variable`` -- a symbolic variable. - - OUTPUT: + - ``variable`` -- a symbolic variable - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -698,11 +676,9 @@ def _coerce_map_from_(self, P): INPUT: - - ``P`` -- a parent. - - OUTPUT: + - ``P`` -- a parent - A boolean or ``None``. + OUTPUT: boolean or ``None`` TESTS:: @@ -722,9 +698,7 @@ def _an_element_(self): r""" Return an element of this symbolic subring. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression TESTS:: @@ -749,11 +723,9 @@ def merge(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A functor or ``None``. + OUTPUT: a functor or ``None`` EXAMPLES:: @@ -779,11 +751,9 @@ def _apply_functor(self, R): INPUT: - - ``R`` -- a symbolic ring. - - OUTPUT: + - ``R`` -- a symbolic ring - A subring of ``R``. + OUTPUT: a subring of ``R`` EXAMPLES:: @@ -816,9 +786,7 @@ def _repr_(self): r""" Return a representation string of this symbolic subring. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -835,11 +803,9 @@ def has_valid_variable(self, variable): INPUT: - - ``variable`` -- a symbolic variable. - - OUTPUT: + - ``variable`` -- a symbolic variable - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -877,11 +843,9 @@ def _coerce_map_from_(self, P): INPUT: - - ``P`` -- a parent. - - OUTPUT: + - ``P`` -- a parent - A boolean or ``None``. + OUTPUT: boolean or ``None`` TESTS:: @@ -908,9 +872,7 @@ def _an_element_(self): r""" Return an element of this symbolic subring. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression TESTS:: @@ -950,11 +912,9 @@ def merge(self, other): INPUT: - - ``other`` -- a functor. - - OUTPUT: + - ``other`` -- a functor - A functor or ``None``. + OUTPUT: a functor or ``None`` EXAMPLES:: @@ -980,11 +940,9 @@ def _apply_functor(self, R): INPUT: - - ``R`` -- a symbolic ring. - - OUTPUT: + - ``R`` -- a symbolic ring - A subring of ``R``. + OUTPUT: a subring of ``R`` EXAMPLES:: @@ -1016,9 +974,7 @@ def _repr_(self): r""" Return a representation string of this symbolic subring. - OUTPUT: - - A string. + OUTPUT: string TESTS:: @@ -1034,11 +990,9 @@ def has_valid_variable(self, variable): INPUT: - - ``variable`` -- a symbolic variable. - - OUTPUT: + - ``variable`` -- a symbolic variable - A boolean. + OUTPUT: boolean EXAMPLES:: @@ -1057,9 +1011,7 @@ def _an_element_(self): r""" Return an element of this symbolic subring. - OUTPUT: - - A symbolic expression. + OUTPUT: a symbolic expression TESTS:: diff --git a/src/sage/symbolic/substitution_map_impl.pxi b/src/sage/symbolic/substitution_map_impl.pxi index 7d9e35cf630..4db772ec930 100644 --- a/src/sage/symbolic/substitution_map_impl.pxi +++ b/src/sage/symbolic/substitution_map_impl.pxi @@ -57,11 +57,9 @@ cdef SubstitutionMap new_SubstitutionMap_from_GExMap(const GExMap& smap): INPUT: - - ``smap`` -- a Pynac ``exmap``. + - ``smap`` -- a Pynac ``exmap`` - OUTPUT: - - A new Python :class:`SubstitutionMap` + OUTPUT: a new Python :class:`SubstitutionMap` EXAMPLES:: @@ -79,9 +77,7 @@ cpdef SubstitutionMap make_map(subs_dict): """ Construct a new substitution map. - OUTPUT: - - A new :class:`SubstitutionMap` for doctesting + OUTPUT: a new :class:`SubstitutionMap` for doctesting EXAMPLES:: diff --git a/src/sage/symbolic/symbols.py b/src/sage/symbolic/symbols.py index 7fe7cdb4472..1669aee6e67 100644 --- a/src/sage/symbolic/symbols.py +++ b/src/sage/symbolic/symbols.py @@ -22,14 +22,14 @@ def register_symbol(obj, conversions, nargs=None): INPUT: - - ``obj`` -- a symbolic object or function. + - ``obj`` -- a symbolic object or function - - ``conversions`` -- a dictionary of conversions, where the keys + - ``conversions`` -- dictionary of conversions, where the keys are the names of interfaces (e.g., ``'maxima'``), and the values - are the string representation of ``obj`` in that system. + are the string representation of ``obj`` in that system - - ``nargs`` -- optional number of arguments. For most functions, - this can be deduced automatically. + - ``nargs`` -- (optional) number of arguments; for most functions, + this can be deduced automatically EXAMPLES:: diff --git a/src/sage/symbolic/tests.py b/src/sage/symbolic/tests.py index a7c6a9a6cb2..6743f0b4205 100644 --- a/src/sage/symbolic/tests.py +++ b/src/sage/symbolic/tests.py @@ -15,11 +15,9 @@ def rational_powers_memleak(): """ - Check that there is no memory leak in rational powers + Check that there is no memory leak in rational powers. - OUTPUT: - - Boolean. Whether the memory leak was detected. + OUTPUT: boolean; whether the memory leak was detected See :issue:`9129`. diff --git a/src/sage/symbolic/units.py b/src/sage/symbolic/units.py index 5e1abf675c9..2593b67476e 100644 --- a/src/sage/symbolic/units.py +++ b/src/sage/symbolic/units.py @@ -40,7 +40,7 @@ sage: t.convert() 1/100000*kilogram*meter/second^2 -Giving improper units to convert to raises a ValueError:: +Giving improper units to convert to raises a :exc:`ValueError`:: sage: t.convert(units.charge.coulomb) Traceback (most recent call last): @@ -55,7 +55,7 @@ sage: s.convert() 293.150000000000*kelvin -Trying to multiply temperatures by another unit then converting raises a ValueError:: +Trying to multiply temperatures by another unit then converting raises a :exc:`ValueError`:: sage: wrong = 50*units.temperature.celsius*units.length.foot sage: wrong.convert() @@ -94,20 +94,23 @@ from .expression import Expression from sage.interfaces.tab_completion import ExtraTabCompletion from sage.misc.instancedoc import instancedoc +from sage.rings.rational_field import QQ ############################################################################### # Unit conversions dictionary. ############################################################################### +one = QQ.one() + unitdict = { 'acceleration': - {'gal': '1/100', - 'galileo': '1/100', + {'gal': one / 100, + 'galileo': one / 100, 'gravity': '9.80665000000000'}, 'amount_of_substance': {'elementary_entity': '1/6.02214129000000e23', - 'mole': '1'}, + 'mole': 1}, 'angles': {'arc_minute': '1/10800*pi', @@ -115,173 +118,173 @@ 'degree': '1/180*pi', 'grade': '1/200*pi', 'quadrant': '1/2*pi', - 'radian': '1', + 'radian': 1, 'right_angle': '1/2*pi'}, 'area': - {'acre': '316160658/78125', - 'are': '100', - 'barn': '1/10000000000000000000000000000', - 'hectare': '10000', - 'rood': '158080329/156250', - 'section': '40468564224/15625', - 'square_chain': '158080329/390625', - 'square_meter': '1', - 'township': '1456868312064/15625'}, + {'acre': QQ(316160658) / 78125, + 'are': 100, + 'barn': one / 10000000000000000000000000000, + 'hectare': 10000, + 'rood': QQ(158080329) / 156250, + 'section': QQ(40468564224) / 15625, + 'square_chain': QQ(158080329) / 390625, + 'square_meter': 1, + 'township': QQ(1456868312064) / 15625}, 'capacitance': - {'abfarad': '1000000000', - 'farad': '1', - 'statfarad': '25000/22468879468420441'}, + {'abfarad': 1000000000, + 'farad': 1, + 'statfarad': QQ(25000) / 22468879468420441}, 'charge': - {'abcoulomb': '10', - 'coulomb': '1', + {'abcoulomb': 10, + 'coulomb': 1, 'elementary_charge': '1.60217646200000e-19', 'faraday': '96485.3399000000', - 'franklin': '1/2997924580', - 'statcoulomb': '1/2997924580'}, + 'franklin': one / 2997924580, + 'statcoulomb': one / 2997924580}, 'conductance': - {'abmho': '1000000000', - 'mho': '1', - 'siemens': '1'}, + {'abmho': 1000000000, + 'mho': 1, + 'siemens': 1}, 'current': - {'abampere': '10', - 'amp': '1', - 'ampere': '1', - 'biot': '10', - 'statampere': '1/2997924580'}, + {'abampere': 10, + 'amp': 1, + 'ampere': 1, + 'biot': 10, + 'statampere': one / 2997924580}, 'electric_potential': - {'abvolt': '1/100000000', - 'statvolt': '149896229/500000', - 'volt': '1'}, + {'abvolt': one / 100000000, + 'statvolt': QQ(149896229) / 500000, + 'volt': 1}, 'energy': - {'british_thermal_unit': '52752792631/50000000', - 'btu': '52752792631/50000000', - 'calorie': '10467/2500', + {'british_thermal_unit': QQ(52752792631) / 50000000, + 'btu': QQ(52752792631) / 50000000, + 'calorie': QQ(10467) / 2500, 'electron_volt': '1.60217733000000e-19', - 'erg': '1/10000000', + 'erg': one / 10000000, 'ev': '1.60217733000000e-19', - 'joule': '1', + 'joule': 1, 'rydberg': '2.17987200000000e-18', - 'therm': '52752792631/500'}, + 'therm': QQ(52752792631) / 500}, 'fiber_linear_mass_density': - {'denier': '1/9000000', - 'tex': '1/1000000'}, + {'denier': one / 9000000, + 'tex': one / 1000000}, 'force': - {'dyne': '1/100000', - 'gram_weight': '196133/20000000', - 'kilogram_force': '196133/20000', - 'kilogram_weight': '196133/20000', - 'newton': '1', - 'pound_force': '8896443230521/2000000000000', - 'pound_weight': '8896443230521/2000000000000', - 'poundal': '17281869297/125000000000', - 'ton_force': '8896443230521/1000000000'}, + {'dyne': one / 100000, + 'gram_weight': QQ(196133) / 20000000, + 'kilogram_force': QQ(196133) / 20000, + 'kilogram_weight': QQ(196133) / 20000, + 'newton': 1, + 'pound_force': QQ(8896443230521) / 2000000000000, + 'pound_weight': QQ(8896443230521) / 2000000000000, + 'poundal': QQ(17281869297) / 125000000000, + 'ton_force': QQ(8896443230521) / 1000000000}, 'frequency': - {'1/second': '1', - 'hertz': '1'}, + {'1/second': 1, + 'hertz': 1}, 'illuminance': - {'foot_candle': '1562500/145161', - 'lux': '1', - 'phot': '10000'}, + {'foot_candle': QQ(1562500) / 145161, + 'lux': 1, + 'phot': 10000}, 'inductance': - {'abhenry': '1/1000000000', - 'henry': '1', - 'stathenry': '22468879468420441/25000'}, + {'abhenry': one / 1000000000, + 'henry': 1, + 'stathenry': QQ(22468879468420441) / 25000}, 'information': - {'bit': '1', - 'byte': '8', - 'nibble': '4'}, + {'bit': 1, + 'byte': 8, + 'nibble': 4}, 'information_rate': - {'baud': '1'}, + {'baud': 1}, 'inverse_length': - {'diopter': '1', - 'kayser': '100'}, + {'diopter': 1, + 'kayser': 100}, 'length': - {'angstrom': '1/10000000000', - 'astronomical_unit': '149597870691', - 'bolt': '4572/125', - 'cable_international': '926/5', - 'cable_us': '27432/125', - 'caliber': '127/500000', - 'centimeter': '1/100', - 'chain': '12573/625', - 'cicero': '125/27706', - 'cubit': '1143/2500', - 'didot': '125/332472', - 'dtp_point': '127/360000', - 'ell': '1143/1000', - 'fathom': '1143/625', - 'feet': '381/1250', - 'fermi': '1/1000000000000000', - 'foot': '381/1250', - 'furlong': '25146/125', - 'hand': '127/1250', - 'inch': '127/5000', - 'kilometer': '1000', - 'league': '603504/125', - 'light_year': '9460730472580800', - 'link': '12573/62500', - 'meter': '1', - 'micron': '1/1000000', - 'mil': '127/5000000', - 'millimeter': '1/1000', - 'mile': '201168/125', - 'nautical_mile': '1852', + {'angstrom': one / 10000000000, + 'astronomical_unit': 149597870691, + 'bolt': QQ(4572) / 125, + 'cable_international': QQ(926) / 5, + 'cable_us': QQ(27432) / 125, + 'caliber': QQ(127) / 500000, + 'centimeter': one / 100, + 'chain': QQ(12573) / 625, + 'cicero': QQ(125) / 27706, + 'cubit': QQ(1143) / 2500, + 'didot': QQ(125) / 332472, + 'dtp_point': QQ(127) / 360000, + 'ell': QQ(1143) / 1000, + 'fathom': QQ(1143) / 625, + 'feet': QQ(381) / 1250, + 'fermi': one / 1000000000000000, + 'foot': QQ(381) / 1250, + 'furlong': QQ(25146) / 125, + 'hand': QQ(127) / 1250, + 'inch': QQ(127) / 5000, + 'kilometer': 1000, + 'league': QQ(603504) / 125, + 'light_year': 9460730472580800, + 'link': QQ(12573) / 62500, + 'meter': 1, + 'micron': one / 1000000, + 'mil': QQ(127) / 5000000, + 'millimeter': one / 1000, + 'mile': QQ(201168) / 125, + 'nautical_mile': 1852, 'parsec': '3.08570000000000e16', - 'perch': '12573/2500', - 'pica': '127/30000', - 'pole': '12573/2500', - 'rod': '12573/2500', - 'rope': '762/125', - 'skein': '13716/125', - 'stadion': '118491/625', - 'stadium': '115443/625', - 'statute_mile': '201168/125', - 'survey_foot': '1200/3937', - 'survey_mile': '6336000/3937', + 'perch': QQ(12573) / 2500, + 'pica': QQ(127) / 30000, + 'pole': QQ(12573) / 2500, + 'rod': QQ(12573) / 2500, + 'rope': QQ(762) / 125, + 'skein': QQ(13716) / 125, + 'stadion': QQ(118491) / 625, + 'stadium': QQ(115443) / 625, + 'statute_mile': QQ(201168) / 125, + 'survey_foot': QQ(1200) / 3937, + 'survey_mile': QQ(6336000) / 3937, 'x_unit': '1.00210000000000e-13', - 'yard': '1143/1250'}, + 'yard': QQ(1143) / 1250}, 'luminance': {'apostilb': '1/pi', 'lambert': '10000/pi', - 'nit': '1', - 'stilb': '10000'}, + 'nit': 1, + 'stilb': 10000}, 'luminous_energy': - {'lumerg': '1', - 'talbot': '1'}, + {'lumerg': 1, + 'talbot': 1}, 'luminous_flux': - {'lumen': '1'}, + {'lumen': 1}, 'luminous_intensity': - {'candela': '1', - 'candle': '1', - 'hefnerkerze': '1019/1128'}, + {'candela': 1, + 'candle': 1, + 'hefnerkerze': QQ(1019) / 1128}, 'magnetic_field': - {'gauss': '1/10000', - 'tesla': '1'}, + {'gauss': one / 10000, + 'tesla': 1}, 'magnetic_flux': - {'maxwell': '1/100000000', - 'weber': '1'}, + {'maxwell': one / 100000000, + 'weber': 1}, 'magnetic_intensity': {'oersted': '250/pi'}, @@ -291,110 +294,110 @@ 'nuclear_magneton': '5.05078324000000e-27'}, 'magnetomotive_force': - {'ampere_turn': '1', + {'ampere_turn': 1, 'gilbert': '5/2/pi'}, 'mass': {'amu': '1.66053878200000e-27', - 'assay_ton': '7/240', + 'assay_ton': QQ(7) / 240, 'atomic_mass_unit': '1.66053878200000e-27', - 'avoirdupois_ounce': '45359237/1600000000', - 'avoirdupois_pound': '45359237/100000000', - 'bale': '45359237/200000', - 'carat': '1/5000', - 'cental': '45359237/1000000', + 'avoirdupois_ounce': QQ(45359237) / 1600000000, + 'avoirdupois_pound': QQ(45359237) / 100000000, + 'bale': QQ(45359237) / 200000, + 'carat': one / 5000, + 'cental': QQ(45359237) / 1000000, 'dalton': '1.66053878200000e-27', 'drachma': "(0.00429234000000000, {'greek':1})", - 'geepound': '14593903/1000000', - 'grain': '6479891/100000000000', - 'gram': '1/1000', - 'gross_hundredweight': '317514659/6250000', - 'hundredweight': '317514659/6250000', - 'kilogram': '1', + 'geepound': QQ(14593903) / 1000000, + 'grain': QQ(6479891) / 100000000000, + 'gram': one / 1000, + 'gross_hundredweight': QQ(317514659) / 6250000, + 'hundredweight': QQ(317514659) / 6250000, + 'kilogram': 1, 'libra': '0.325971000000000', - 'long_ton': '317514659/312500', + 'long_ton': QQ(317514659) / 312500, 'metric_ton': '1000', 'mina': "(0.429234000000000, {'greek':100})", - 'net_hundredweight': '45359237/1000000', + 'net_hundredweight': QQ(45359237) / 1000000, 'obol': "(0.000715380000000000,{'greek':1/6})", - 'ounce': '45359237/1600000000', - 'ounce_troy': '19439673/625000000', - 'pennyweight': '19439673/12500000000', + 'ounce': QQ(45359237) / 1600000000, + 'ounce_troy': QQ(19439673) / 625000000, + 'pennyweight': QQ(19439673) / 12500000000, 'pondus': '0.325969000000000', - 'pound': '45359237/100000000', - 'pound_troy': '58319019/156250000', - 'quintal': '100', + 'pound': QQ(45359237) / 100000000, + 'pound_troy': QQ(58319019) / 156250000, + 'quintal': 100, 'shekel': '0.0141000000000000', - 'short_hundredweight': '45359237/1000000', - 'short_ton': '45359237/50000', - 'slug': '14593903/1000000', + 'short_hundredweight': QQ(45359237) / 1000000, + 'short_ton': QQ(45359237) / 50000, + 'slug': QQ(14593903) / 1000000, 'solar_mass': '1.98892000000000e30', - 'stone': '317514659/50000000', + 'stone': QQ(317514659) / 50000000, 'talent': "(25.7540400000000, {'greek':6000})", - 'ton': '45359237/50000', - 'tonne': '1000', - 'wey': '2857631931/25000000'}, + 'ton': QQ(45359237) / 50000, + 'tonne': 1000, + 'wey': QQ(2857631931) / 25000000}, 'power': - {'cheval_vapeur': '588399/800', - 'horsepower': '37284993579113511/50000000000000', - 'watt': '1'}, + {'cheval_vapeur': QQ(588399) / 800, + 'horsepower': QQ(37284993579113511) / 50000000000000, + 'watt': 1}, 'pressure': - {'atmosphere': '101325', - 'bar': '100000', - 'barye': '1/10', + {'atmosphere': 101325, + 'bar': 100000, + 'barye': QQ((1, 10)), 'inch_mercury': '3386.38900000000', 'millimeter_mercury': '133.322400000000', 'mmhg': '133.322400000000', - 'pa': '1', - 'pascal': '1', - 'pounds_per_square_inch': '8896443230521/1290320000', - 'psi': '8896443230521/1290320000', - 'torr': '20265/152'}, + 'pa': 1, + 'pascal': 1, + 'pounds_per_square_inch': QQ(8896443230521) / 1290320000, + 'psi': QQ(8896443230521) / 1290320000, + 'torr': QQ(20265) / 152}, 'radiation': - {'becquerel': '1', - 'curie': '37000000000', - 'rutherford': '1000000'}, + {'becquerel': 1, + 'curie': 37000000000, + 'rutherford': 1000000}, 'radiation_absorbed': - {'gray': '1', - 'rad': '1/100'}, + {'gray': 1, + 'rad': one / 100}, 'radiation_ionizing': {'roentgen': '0.000258000000000000', 'rontgen': '0.000258000000000000'}, 'resistance': - {'abohm': '1/1000000000', - 'ohm': '1', - 'statohm': '22468879468420441/25000'}, + {'abohm': one / 1000000000, + 'ohm': 1, + 'statohm': QQ(22468879468420441) / 25000}, 'si_prefixes': - {'atto': '1/1000000000000000000', - 'centi': '1/100', - 'deca': '10', - 'deci': '1/10', - 'exa': '1000000000000000000', - 'femto': '1/1000000000000000', - 'giga': '1000000000', - 'hecto': '100', - 'kilo': '1000', - 'mega': '1000000', - 'micro': '1/1000000', - 'milli': '1/1000', - 'nano': '1/1000000000', - 'peta': '1000000000000000', - 'pico': '1/1000000000000', - 'tera': '1000000000000', - 'yocto': '1/1000000000000000000000000', - 'yotta': '1000000000000000000000000', - 'zepto': '1/1000000000000000000000', - 'zetta': '1000000000000000000000'}, + {'atto': one / 1000000000000000000, + 'centi': one / 100, + 'deca': 10, + 'deci': QQ((1, 10)), + 'exa': 1000000000000000000, + 'femto': one / 1000000000000000, + 'giga': 1000000000, + 'hecto': 100, + 'kilo': 1000, + 'mega': 1000000, + 'micro': one / 1000000, + 'milli': one / 1000, + 'nano': one / 1000000000, + 'peta': 1000000000000000, + 'pico': one / 1000000000000, + 'tera': 1000000000000, + 'yocto': one / 1000000000000000000000000, + 'yotta': 1000000000000000000000000, + 'zepto': one / 1000000000000000000000, + 'zetta': 1000000000000000000000}, 'solid_angle': - {'steradian': '1'}, + {'steradian': 1}, 'temperature': {'celsius': '(x + 273.15), (x), (x*9/5 + 32), ((x+273.15)*9/5)', @@ -404,83 +407,83 @@ 'rankine': '(5/9*x), ((x-491.67)*5/9), (x-459.67), (x)'}, 'time': - {'century': '3153600000', - 'day': '86400', - 'decade': '315360000', - 'fortnight': '1209600', - 'hour': '3600', - 'millenium': '31536000000', - 'minute': '60', - 'month': '2628000', - 'second': '1', + {'century': 3153600000, + 'day': 86400, + 'decade': 315360000, + 'fortnight': 1209600, + 'hour': 3600, + 'millenium': 31536000000, + 'minute': 60, + 'month': 2628000, + 'second': 1, 'sidereal_day': "(86164.0905308330, {'sidereal':86400})", 'sidereal_second': "(0.997269566329086, {'sidereal':1})", 'sidereal_year': '3.15581497632000e7', 'tropical_year': '3.15569251779840e7', - 'week': '604800', - 'year': '31536000'}, + 'week': 604800, + 'year': 31536000}, 'unit_multipliers': - {'bakers_dozen': '13', - 'dozen': '12', - 'gross': '144', - 'percent': '1/100'}, + {'bakers_dozen': 13, + 'dozen': 12, + 'gross': 144, + 'percent': one / 100}, 'velocity': {'knot': '463/900'}, 'viscosity_absolute': - {'poise': '1/10', - 'reyn': '8896443230521/1290320000'}, + {'poise': one / 10, + 'reyn': QQ(8896443230521) / 1290320000}, 'viscosity_kinematic': - {'stokes': '1/10000'}, + {'stokes': one / 10000}, 'viscosity_other': - {'rhes': '10'}, + {'rhes': 10}, 'volume': - {'bag': '660732565629/6250000000000', - 'barrel': '9936705933/62500000000', - 'board_foot': '18435447/7812500000', - 'bucket': '473176473/31250000000', - 'bushel': '220244188543/6250000000000', - 'butt': '29810117799/62500000000', - 'cord': '884901456/244140625', - 'cubic_meter': '1', - 'cup': '473176473/2000000000000', - 'ephah': '1982197696887/50000000000000', - 'fifth': '473176473/625000000000', - 'firkin': '4091481/100000000', - 'fluid_dram': '473176473/128000000000000', - 'fluid_ounce': '473176473/16000000000000', - 'gallon': '473176473/125000000000', - 'gill': '473176473/4000000000000', - 'hogshead': '29810117799/125000000000', - 'imperial_gallon': '454609/100000000', - 'imperial_pint': '454609/800000000', - 'jeroboam': '473176473/156250000000', - 'jigger': '1419529419/32000000000000', - 'liter': '1/1000', - 'magnum': '473176473/250000000000', - 'minim': '157725491/2560000000000000', - 'noggin': '473176473/4000000000000', - 'omer': '1982197696887/500000000000000', - 'peck': '220244188543/25000000000000', - 'pint': '473176473/1000000000000', - 'pony': '1419529419/64000000000000', - 'puncheon': '9936705933/31250000000', - 'quart': '473176473/500000000000', - 'register_ton': '55306341/19531250', - 'seam': '220244188543/781250000000', - 'shot': '473176473/16000000000000', - 'stere': '1', - 'tablespoon': '473176473/32000000000000', - 'teaspoon': '157725491/32000000000000', - 'tun': '29810117799/31250000000', - 'uk_gallon': '454609/100000000', - 'uk_pint': '454609/800000000', - 'wine_bottle': '3/4000'} + {'bag': QQ(660732565629) / 6250000000000, + 'barrel': QQ(9936705933) / 62500000000, + 'board_foot': QQ(18435447) / 7812500000, + 'bucket': QQ(473176473) / 31250000000, + 'bushel': QQ(220244188543) / 6250000000000, + 'butt': QQ(29810117799) / 62500000000, + 'cord': QQ(884901456) / 244140625, + 'cubic_meter': 1, + 'cup': QQ(473176473) / 2000000000000, + 'ephah': QQ(1982197696887) / 50000000000000, + 'fifth': QQ(473176473) / 625000000000, + 'firkin': QQ(4091481) / 100000000, + 'fluid_dram': QQ(473176473) / 128000000000000, + 'fluid_ounce': QQ(473176473) / 16000000000000, + 'gallon': QQ(473176473) / 125000000000, + 'gill': QQ(473176473) / 4000000000000, + 'hogshead': QQ(29810117799) / 125000000000, + 'imperial_gallon': QQ(454609) / 100000000, + 'imperial_pint': QQ(454609) / 800000000, + 'jeroboam': QQ(473176473) / 156250000000, + 'jigger': QQ(1419529419) / 32000000000000, + 'liter': one / 1000, + 'magnum': QQ(473176473) / 250000000000, + 'minim': QQ(157725491) / 2560000000000000, + 'noggin': QQ(473176473) / 4000000000000, + 'omer': QQ(1982197696887) / 500000000000000, + 'peck': QQ(220244188543) / 25000000000000, + 'pint': QQ(473176473) / 1000000000000, + 'pony': QQ(1419529419) / 64000000000000, + 'puncheon': QQ(9936705933) / 31250000000, + 'quart': QQ(473176473) / 500000000000, + 'register_ton': QQ(55306341) / 19531250, + 'seam': QQ(220244188543) / 781250000000, + 'shot': QQ(473176473) / 16000000000000, + 'stere': 1, + 'tablespoon': QQ(473176473) / 32000000000000, + 'teaspoon': QQ(157725491) / 32000000000000, + 'tun': QQ(29810117799) / 31250000000, + 'uk_gallon': QQ(454609) / 100000000, + 'uk_pint': QQ(454609) / 800000000, + 'wine_bottle': QQ(3) / 4000} } unit_to_type = {} @@ -500,7 +503,8 @@ def evalunitdict(): """ from sage.misc.sage_eval import sage_eval for key, value in unitdict.items(): - unitdict[key] = {a: sage_eval(repr(b)) for a, b in value.items()} + unitdict[key] = {a: (sage_eval(repr(b)) if isinstance(b, str) else b) + for a, b in value.items()} # FEATURE IDEA: create a function that would allow users to add # new entries to the table without having to know anything about @@ -928,16 +932,14 @@ def evalunitdict(): def vars_in_str(s): """ - Given a string like 'mass/(length*time)', return the list - ['mass', 'length', 'time']. + Given a string like ``'mass/(length*time)'``, return the list + ``['mass', 'length', 'time']``. INPUT: - - ``s`` -- a string - - OUTPUT: + - ``s`` -- string - - a list of strings (unit names) + OUTPUT: list of strings (unit names) EXAMPLES:: @@ -949,17 +951,16 @@ def vars_in_str(s): def unit_derivations_expr(v): """ - Given derived units name, returns the corresponding units - expression. For example, given 'acceleration' output the symbolic - expression length/time^2. + Given derived units name, returns the corresponding units expression. - INPUT: + For example, given ``'acceleration'`` output the symbolic expression + ``length/time^2``. - - ``v`` -- a string, name of a unit type such as 'area', 'volume', etc. + INPUT: - OUTPUT: + - ``v`` -- string; name of a unit type such as ``'area'``, ``'volume'``, etc. - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -968,7 +969,7 @@ def unit_derivations_expr(v): sage: sage.symbolic.units.unit_derivations_expr('electric_potential') length^2*mass/(current*time^3) - If the unit name is unknown, a :class:`KeyError` is raised:: + If the unit name is unknown, a :exc:`KeyError` is raised:: sage: sage.symbolic.units.unit_derivations_expr('invalid') Traceback (most recent call last): @@ -1024,12 +1025,9 @@ class that derives from symbolic expression, and has a specialized INPUT: - - ``name`` -- a string - - OUTPUT: - - - a :class:`UnitExpression` + - ``name`` -- string + OUTPUT: a :class:`UnitExpression` EXAMPLES:: @@ -1168,7 +1166,6 @@ def __getattr__(self, name): sage: units.area.acre is units.area.acre True - """ if name in self.__units: return self.__units[name] @@ -1205,15 +1202,13 @@ def __repr__(self): def unitdocs(unit): r""" - Returns docstring for the given unit. + Return docstring for the given unit. INPUT: - ``unit`` -- a unit - OUTPUT: - - - a string + OUTPUT: string EXAMPLES:: @@ -1222,7 +1217,7 @@ def unitdocs(unit): sage: sage.symbolic.units.unitdocs('amu') 'Abbreviation for atomic mass unit.\nApproximately equal to 1.660538782*10^-27 kilograms.' - Units not in the list unit_docs will raise a ValueError:: + Units not in the list unit_docs will raise a :exc:`ValueError`:: sage: sage.symbolic.units.unitdocs('earth') Traceback (most recent call last): @@ -1242,9 +1237,7 @@ def is_unit(s) -> bool: - ``s`` -- an object - OUTPUT: - - - a boolean + OUTPUT: boolean EXAMPLES:: @@ -1269,17 +1262,16 @@ def is_unit(s) -> bool: def convert(expr, target): """ - Converts units between expr and target. If target is None then converts to SI base units. + Convert units between ``expr`` and ``target``. If ``target`` is ``None`` + then converts to SI base units. INPUT: - ``expr`` -- the symbolic expression converting from - - ``target`` -- (default None) the symbolic expression converting to - - OUTPUT: + - ``target`` -- (default: ``None``) the symbolic expression converting to - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -1288,7 +1280,7 @@ def convert(expr, target): sage: sage.symbolic.units.convert(units.mass.kilogram, units.mass.pound) 100000000/45359237*pound - Raises ValueError if expr and target are not convertible:: + This raises :exc:`ValueError` if expr and target are not convertible:: sage: sage.symbolic.units.convert(units.mass.kilogram, units.length.foot) Traceback (most recent call last): @@ -1362,15 +1354,13 @@ def convert(expr, target): def base_units(unit): """ - Converts unit to base SI units. + Convert unit to base SI units. INPUT: - ``unit`` -- a unit - OUTPUT: - - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -1389,7 +1379,7 @@ def base_units(unit): sage: sage.symbolic.units.base_units(units.volume.liter) 1/1000*meter^3 - Returns variable if 'unit' is not a unit:: + Returns variable if ``unit`` is not a unit:: sage: sage.symbolic.units.base_units(var('x')) x @@ -1397,18 +1387,21 @@ def base_units(unit): from sage.misc.sage_eval import sage_eval if str(unit) not in unit_to_type: return unit - elif unit_to_type[str(unit)] == 'si_prefixes' or unit_to_type[str(unit)] == 'unit_multipliers': - return sage_eval(unitdict[unit_to_type[str(unit)]][str(unit)]) + if unit_to_type[str(unit)] in ['si_prefixes', 'unit_multipliers']: + number = unitdict[unit_to_type[str(unit)]][str(unit)] + return (sage_eval(number) if isinstance(number, str) else number) + + v = SR.var(unit_to_type[str(unit)]) + if str(v) in unit_derivations: + base = unit_derivations_expr(v) + for i in base.variables(): + base = base.subs({i: SR.var(value_to_unit[str(i)][1])}) + number = unitdict[str(v)][str(unit)] + return base * (sage_eval(number) if isinstance(number, str) else number) else: - v = SR.var(unit_to_type[str(unit)]) - if str(v) in unit_derivations: - base = unit_derivations_expr(v) - for i in base.variables(): - base = base.subs({i: SR.var(value_to_unit[str(i)]['1'])}) - return base * sage_eval(unitdict[str(v)][str(unit)]) - else: - base = SR.var(value_to_unit[str(v)]['1']) * sage_eval(unitdict[str(v)][str(unit)]) - return base + base = SR.var(value_to_unit[str(v)][1]) + number = unitdict[str(v)][str(unit)] + return base * (sage_eval(number) if isinstance(number, str) else number) def convert_temperature(expr, target): @@ -1420,9 +1413,7 @@ def convert_temperature(expr, target): - ``expr`` -- a unit of temperature - ``target`` -- a units of temperature - OUTPUT: - - - a symbolic expression + OUTPUT: a symbolic expression EXAMPLES:: @@ -1432,12 +1423,12 @@ def convert_temperature(expr, target): sage: t.convert(units.temperature.kelvin) 273.150000000000*kelvin - If target is None then it defaults to kelvin:: + If target is ``None`` then it defaults to kelvin:: sage: t.convert() 273.150000000000*kelvin - Raises ValueError when either input is not a unit of temperature:: + This raises :exc:`ValueError` when either input is not a unit of temperature:: sage: t.convert(units.length.foot) Traceback (most recent call last): diff --git a/src/sage/tensor/modules/alternating_contr_tensor.py b/src/sage/tensor/modules/alternating_contr_tensor.py index a2cacf8492f..ca03cbfa14f 100644 --- a/src/sage/tensor/modules/alternating_contr_tensor.py +++ b/src/sage/tensor/modules/alternating_contr_tensor.py @@ -39,6 +39,7 @@ class :class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`. from sage.tensor.modules.free_module_tensor import FreeModuleTensor from sage.tensor.modules.comp import Components, CompFullyAntiSym + class AlternatingContrTensor(FreeModuleTensor): r""" Alternating contravariant tensor on a free module of finite rank @@ -176,7 +177,6 @@ class AlternatingContrTensor(FreeModuleTensor): module M over the Integer Ring sage: s.display(e) b∧b = 0 - """ def __init__(self, fmodule, degree, name=None, latex_name=None): r""" @@ -189,7 +189,7 @@ def __init__(self, fmodule, degree, name=None, latex_name=None): sage: e = M.basis('e') sage: a = AlternatingContrTensor(M, 2, name='a') sage: a[e,0,1] = 2 - sage: TestSuite(a).run(skip="_test_category") # see below + sage: TestSuite(a).run(skip='_test_category') # see below In the above test suite, _test_category fails because a is not an instance of a.parent().category().element_class. Actually alternating @@ -199,7 +199,6 @@ def __init__(self, fmodule, degree, name=None, latex_name=None): sage: a1 = M.exterior_power(2).element_class(M, 2, name='a') sage: a1[e,0,1] = 2 sage: TestSuite(a1).run() - """ FreeModuleTensor.__init__(self, fmodule, (degree,0), name=name, latex_name=latex_name, @@ -251,7 +250,6 @@ def _new_instance(self): module M over the Integer Ring sage: a._new_instance().parent() is a.parent() True - """ return self.__class__(self._fmodule, self._tensor_rank) @@ -284,7 +282,6 @@ def _new_comp(self, basis): sage: a._new_comp(e) 1-index components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring - """ fmodule = self._fmodule # the base free module if self._tensor_rank == 1: @@ -306,7 +303,6 @@ def degree(self): sage: a = M.alternating_contravariant_tensor(2, name='a') sage: a.degree() 2 - """ return self._tensor_rank @@ -392,7 +388,6 @@ def display(self, basis=None, format_spec=None): sage: a.display(format_spec=10) # 10 bits of precision a = 0.33 e_1∧e_2 + 2.5 e_1∧e_3 + 4.0 e_2∧e_3 - """ from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_wedge @@ -532,7 +527,6 @@ def wedge(self, other): True sage: d.wedge(c) == c.wedge(d) True - """ from sage.typeset.unicode_characters import unicode_wedge from .format_utilities import is_atomic @@ -712,7 +706,6 @@ def interior_product(self, form): -240 sage: c == a.contract(0, 1, 2, 3, b, 0, 1, 2, 3) True - """ from .format_utilities import is_atomic from .free_module_alt_form import FreeModuleAltForm diff --git a/src/sage/tensor/modules/comp.py b/src/sage/tensor/modules/comp.py index 6021997c3b0..32ac954c7b4 100644 --- a/src/sage/tensor/modules/comp.py +++ b/src/sage/tensor/modules/comp.py @@ -211,7 +211,7 @@ [ 0 0 0] Internally, the components are stored as a dictionary (:attr:`_comp`) whose -keys are the indices; only the non-zero components are stored:: +keys are the indices; only the nonzero components are stored:: sage: a[:] [0.000000000000000 0.000000000000000 0.000000000000000] @@ -402,7 +402,7 @@ class Components(SageObject): [ 0 0 0] Internally, the components are stored as a dictionary (:attr:`_comp`) whose - keys are the indices; only the non-zero components are stored:: + keys are the indices; only the nonzero components are stored:: sage: a[:] [0.000000000000000 0.000000000000000 0.000000000000000] @@ -490,7 +490,6 @@ class Components(SageObject): [[-6, 0, 18], [-3, 0, 9], [-12, 0, 36]]] sage: d[0,1,2] == a[0]*b[1]*a[2] True - """ def __init__(self, ring, frame, nb_indices, start_index=0, output_formatter=None): @@ -500,7 +499,6 @@ def __init__(self, ring, frame, nb_indices, start_index=0, sage: from sage.tensor.modules.comp import Components sage: Components(ZZ, [1,2,3], 2) 2-indices components w.r.t. [1, 2, 3] - """ # For efficiency, no test is performed regarding the type and range of # the arguments: @@ -562,13 +560,12 @@ def _repr_symmetry(self): sage: c = Components(ZZ, [1,2,3], 2) sage: c._repr_symmetry() ('', '') - """ return "", "" def _new_instance(self): r""" - Creates a :class:`Components` instance of the same number of indices + Create a :class:`Components` instance of the same number of indices and w.r.t. the same frame. This method must be redefined by derived classes of @@ -580,7 +577,6 @@ def _new_instance(self): sage: c = Components(ZZ, [1,2,3], 2) sage: c._new_instance() 2-indices components w.r.t. [1, 2, 3] - """ return Components(self._ring, self._frame, self._nid, self._sindex, self._output_formatter) @@ -609,7 +605,6 @@ def copy(self): True sage: b is a # b is a distinct object False - """ result = self._new_instance() for ind, val in self._comp.items(): @@ -621,7 +616,7 @@ def copy(self): def _del_zeros(self): r""" - Deletes all the zeros in the dictionary :attr:`_comp` + Delete all the zeros in the dictionary :attr:`_comp`. NB: The use case of this method must be rare because zeros are not stored in :attr:`_comp`. @@ -634,7 +629,6 @@ def _del_zeros(self): sage: c._del_zeros() sage: c._comp {(0, 1): 3, (1, 2): -5} - """ # The zeros are first searched; they are deleted in a second stage, to # avoid changing the dictionary while it is read @@ -647,16 +641,14 @@ def _del_zeros(self): def _check_indices(self, indices): r""" - Check the validity of a list of indices and returns a tuple from it + Check the validity of a list of indices and returns a tuple from it. INPUT: - ``indices`` -- list of indices (possibly a single integer if - self is a 1-index object) - - OUTPUT: + ``self`` is a 1-index object) - - a tuple containing valid indices + OUTPUT: a tuple containing valid indices EXAMPLES:: @@ -680,7 +672,6 @@ def _check_indices(self, indices): Traceback (most recent call last): ... ValueError: wrong number of indices: 2 expected, while 3 are provided - """ if isinstance(indices, (int, Integer)): ind = (indices,) @@ -700,12 +691,12 @@ def _check_indices(self, indices): def __getitem__(self, args): r""" - Returns the component corresponding to the given indices. + Return the component corresponding to the given indices. INPUT: - ``args`` -- list of indices (possibly a single integer if - self is a 1-index object) or the character ``:`` for the full list + ``self`` is a 1-index object) or the character ``:`` for the full list of components OUTPUT: @@ -737,7 +728,6 @@ def __getitem__(self, args): [ 0 0 0] [ 0 0 -4] [ 0 0 0] - """ no_format = self._output_formatter is None format_type = None # default value, possibly redefined below @@ -788,9 +778,9 @@ def _get_list(self, ind_slice, no_format=True, format_type=None): INPUT: - - ``ind_slice`` -- a slice object. Unless the dimension is 1, - this must be ``[:]``. - - ``no_format`` -- (default: ``True``) determines whether some + - ``ind_slice`` -- a slice object; unless the dimension is 1, + this must be ``[:]`` + - ``no_format`` -- boolean (default: ``True``); determines whether some formatting of the components is to be performed - ``format_type`` -- (default: ``None``) argument to be passed to the formatting function ``self._output_formatter``, as the @@ -879,7 +869,6 @@ def _gen_list(self, ind, no_format=True, format_type=None): [0, 0, 0] sage: c._gen_list([0,1]) 5 - """ if len(ind) == self._nid: if no_format: @@ -895,12 +884,12 @@ def _gen_list(self, ind, no_format=True, format_type=None): def __setitem__(self, args, value): r""" - Sets the component corresponding to the given indices. + Set the component corresponding to the given indices. INPUT: - ``args`` -- list of indices (possibly a single integer if - self is a 1-index object); if ``[:]`` is provided, all the + ``self`` is a 1-index object); if ``[:]`` is provided, all the components are set - ``value`` -- the value to be set or a list of values if ``args = [:]`` (``slice(None)``) @@ -924,7 +913,6 @@ def __setitem__(self, args, value): [0 1 2] [3 4 5] [6 7 8] - """ format_type = None # default value, possibly redefined below if isinstance(args, list): # case of [[...]] syntax @@ -980,7 +968,7 @@ def _set_list(self, ind_slice, format_type, values): INPUT: - - ``ind_slice`` -- a slice object + - ``ind_slice`` -- a slice object - ``format_type`` -- format possibly used to construct a ring element - ``values`` -- list of values for the components : the full list if ``ind_slice = [:]``, in the form ``T[i][j]...`` for the @@ -996,7 +984,6 @@ def _set_list(self, ind_slice, format_type, values): [0 1 2] [3 4 5] [6 7 8] - """ si = self._sindex nsi = si + self._dim @@ -1043,7 +1030,6 @@ def _set_value_list(self, ind, format_type, val): [-1 -2 -3] [ 4 5 6] [ 7 -8 9] - """ if len(ind) == self._nid: if format_type is not None: @@ -1078,7 +1064,6 @@ def items(self): ((1, 0, 1), 5), ((1, 1, 0), 5), ((1, 1, 1), 3)] - """ for ind in self.index_generator(): val = self[ind] @@ -1120,9 +1105,9 @@ def display(self, symbol, latex_symbol=None, index_positions=None, ``None``, integers labels are used - ``format_spec`` -- (default: ``None``) format specification passed to the output formatter declared at the construction of the object - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero components are displayed - - ``only_nonredundant`` -- (default: ``False``) boolean; if ``True``, + - ``only_nonredundant`` -- boolean (default: ``False``); if ``True``, only nonredundant components are displayed in case of symmetries EXAMPLES: @@ -1238,7 +1223,6 @@ def display(self, symbol, latex_symbol=None, index_positions=None, sage: c[0] = SR.var('t', domain='real') # needs sage.symbolic sage: c.display('c') # needs sage.symbolic c_0 = t - """ from sage.misc.latex import latex from sage.tensor.modules.format_utilities import FormattedExpansion @@ -1337,9 +1321,7 @@ def swap_adjacent_indices(self, pos1, pos2, pos3): position of the last index of set 1 (since the two sets are adjacent) - ``pos3`` -- 1 plus position of the last index of set 2 - OUTPUT: - - - Components with index set 1 permuted with index set 2. + OUTPUT: components with index set 1 permuted with index set 2 EXAMPLES: @@ -1374,7 +1356,6 @@ def swap_adjacent_indices(self, pos1, pos2, pos3): 24 sage: d[1,2,0,1] 24 - """ result = self._new_instance() for ind, val in self._comp.items(): @@ -1423,7 +1404,6 @@ def is_zero(self): Traceback (most recent call last): ... TypeError: cannot compare a set of components to a number - """ if not self._comp: return True @@ -1443,11 +1423,9 @@ def __eq__(self, other): INPUT: - - ``other`` -- a set of components or 0 + - ``other`` -- set of components or 0 - OUTPUT: - - - ``True`` if ``self`` is equal to ``other``, or ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other``, or ``False`` otherwise EXAMPLES:: @@ -1468,7 +1446,6 @@ def __eq__(self, other): sage: v = Components(ZZ, [1,2,3], 1) sage: c.__eq__(v) False - """ if isinstance(other, (int, Integer)): # other is 0 if other == 0: @@ -1494,11 +1471,10 @@ def __ne__(self, other): INPUT: - - ``other`` -- a set of components or 0 + - ``other`` -- set of components or 0 - OUTPUT: - - - True if ``self`` is different from ``other``, or False otherwise + OUTPUT: ``True`` if ``self`` is different from ``other``, or ``False`` + otherwise EXAMPLES:: @@ -1514,7 +1490,6 @@ def __ne__(self, other): True sage: c.__ne__(c1) True - """ return not self == other @@ -1522,9 +1497,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of ``self`` + OUTPUT: an exact copy of ``self`` EXAMPLES:: @@ -1539,7 +1512,6 @@ def __pos__(self): True sage: a == c True - """ return self.copy() @@ -1547,9 +1519,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the opposite of the components represented by ``self`` + OUTPUT: the opposite of the components represented by ``self`` EXAMPLES:: @@ -1562,7 +1532,6 @@ def __neg__(self): [-5, 0, 4] sage: a == -c True - """ result = self._new_instance() for ind, val in self._comp.items(): @@ -1578,9 +1547,7 @@ def __add__(self, other): - ``other`` -- components of the same number of indices and defined on the same frame as ``self`` - OUTPUT: - - - components resulting from the addition of ``self`` and ``other`` + OUTPUT: components resulting from the addition of ``self`` and ``other`` EXAMPLES:: @@ -1608,7 +1575,6 @@ def __add__(self, other): sage: b.__add__(a) == s # test of commutativity of parallel comput. True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if isinstance(other, (int, Integer)) and other == 0: return +self @@ -1633,7 +1599,7 @@ def __add__(self, other): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in other._comp] + ind_list = list(other._comp) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) # list of input parameters @@ -1659,7 +1625,7 @@ def paral_sum(a, b, local_list_ind): def __radd__(self, other): r""" - Reflected addition (addition on the right to `other``) + Reflected addition (addition on the right to ``other``). EXAMPLES:: @@ -1678,7 +1644,6 @@ def __radd__(self, other): 1-index components w.r.t. [1, 2, 3] sage: s == a True - """ return self + other @@ -1690,9 +1655,7 @@ def __sub__(self, other): - ``other`` -- components, of the same type as ``self`` - OUTPUT: - - - components resulting from the subtraction of ``other`` from ``self`` + OUTPUT: components resulting from the subtraction of ``other`` from ``self`` EXAMPLES:: @@ -1722,7 +1685,6 @@ def __sub__(self, other): sage: b.__sub__(a) == -s # test of parallel comput. True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if isinstance(other, (int, Integer)) and other == 0: return +self @@ -1752,7 +1714,6 @@ def __rsub__(self, other): [-1, 0, 3] sage: s == -a True - """ return (-self) + other @@ -1764,9 +1725,7 @@ def __mul__(self, other): - ``other`` -- components, on the same frame as ``self`` - OUTPUT: - - - the tensor product of ``self`` by ``other`` + OUTPUT: the tensor product of ``self`` by ``other`` EXAMPLES:: @@ -1824,7 +1783,6 @@ def __mul__(self, other): sage: s_par[:] == s[:] True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if not isinstance(other, Components): raise TypeError("the second argument for the tensor product " + @@ -1864,7 +1822,7 @@ def __mul__(self, other): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in result.non_redundant_index_generator()] + ind_list = list(result.non_redundant_index_generator()) ind_step = max(1, int(len(ind_list)/nproc)) local_list = lol(ind_list, ind_step) # list of input parameters: @@ -1895,8 +1853,8 @@ def paral_mul(a, local_list_ind): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in self._comp] - ind_step = max(1, int(len(ind_list)/nproc)) + ind_list = list(self._comp) + ind_step = max(1, len(ind_list) // nproc) local_list = lol(ind_list, ind_step) # list of input parameters: listParalInput = [(self, other, ind_part) for ind_part in local_list] @@ -1936,7 +1894,6 @@ def __rmul__(self, other): True sage: a.__rmul__(0) == 0 True - """ if isinstance(other, Components): raise NotImplementedError("left tensor product not implemented") @@ -1965,7 +1922,6 @@ def __truediv__(self, other): True sage: 3*s == a True - """ if isinstance(other, Components): raise NotImplementedError("division by an object of type " + @@ -2030,7 +1986,6 @@ def trace(self, pos1, pos2): [12, 24, 36] sage: [sum(a[i,j,j] for j in range(3)) for i in range(3)] # check [12, 24, 36] - """ if self._nid < 2: raise ValueError("contraction can be performed only on " + @@ -2080,9 +2035,7 @@ def contract(self, *args): is not provided, a single contraction on the first index position of ``other`` is assumed - OUTPUT: - - - set of components resulting from the contraction + OUTPUT: set of components resulting from the contraction EXAMPLES: @@ -2218,7 +2171,6 @@ def contract(self, *args): sage: a.contract(1, 0, b, 1, 0) 4 sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ # # Treatment of the input @@ -2392,7 +2344,7 @@ def compprod(a, b): # parallel computation nproc = Parallelism().get('tensor') lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in res.non_redundant_index_generator()] + ind_list = list(res.non_redundant_index_generator()) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) @@ -2454,9 +2406,7 @@ def index_generator(self): r""" Generator of indices. - OUTPUT: - - - an iterable index + OUTPUT: an iterable index EXAMPLES: @@ -2474,7 +2424,6 @@ def index_generator(self): sage: list(c.index_generator()) [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] - """ si = self._sindex imax = self._dim - 1 + si @@ -2499,9 +2448,7 @@ def non_redundant_index_generator(self): Only versions for derived classes with symmetries or antisymmetries are not trivial. - OUTPUT: - - - an iterable index + OUTPUT: an iterable index EXAMPLES: @@ -2631,7 +2578,6 @@ def symmetrize(self, *pos): sage: all(s[i,j,k] == (c[i,j,k]+c[k,j,i])/2 # Check of the result: ....: for i in range(3) for j in range(3) for k in range(3)) True - """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup if not pos: @@ -2664,7 +2610,7 @@ def symmetrize(self, *pos): def antisymmetrize(self, *pos): r""" - Antisymmetrization over the given index positions + Antisymmetrization over the given index positions. INPUT: @@ -2672,10 +2618,8 @@ def antisymmetrize(self, *pos): (with the convention position=0 for the first slot); if none, the antisymmetrization is performed over all the indices - OUTPUT: - - - an instance of :class:`CompWithSym` describing the antisymmetrized - components. + OUTPUT: an instance of :class:`CompWithSym` describing the + antisymmetrized components EXAMPLES: @@ -2782,7 +2726,6 @@ def antisymmetrize(self, *pos): True sage: c.antisymmetrize(2,0) == c.antisymmetrize(0,2) True - """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup if not pos: @@ -2833,7 +2776,6 @@ def _matrix_(self): sage: matrix(c) == c._matrix_() True - """ from sage.matrix.constructor import matrix if self._nid != 2: @@ -3051,7 +2993,6 @@ def __init__(self, ring, frame, nb_indices, start_index=0, sage: from sage.tensor.modules.comp import CompWithSym sage: C = CompWithSym(ZZ, [1,2,3], 4, sym=(0,1), antisym=(2,3)) sage: TestSuite(C).run() - """ Components.__init__(self, ring, frame, nb_indices, start_index, output_formatter) @@ -3189,7 +3130,6 @@ def _new_instance(self): sage: c = CompWithSym(ZZ, [1,2,3], 4, sym=(0,1)) sage: a = c._new_instance() ; a 4-indices components w.r.t. [1, 2, 3], with symmetry on the index positions (0, 1) - """ return CompWithSym(self._ring, self._frame, self._nid, self._sindex, self._output_formatter, self._sym, self._antisym) @@ -3203,7 +3143,7 @@ def _ordered_indices(self, indices): INPUT: - ``indices`` -- list of indices (possibly a single integer if - self is a 1-index object) + ``self`` is a 1-index object) OUTPUT: @@ -3230,7 +3170,6 @@ def _ordered_indices(self, indices): (-1, (0, 1, 1, 2)) sage: c._ordered_indices([0,1,2,2]) (0, None) - """ from sage.combinat.permutation import Permutation ind = list(self._check_indices(indices)) @@ -3271,7 +3210,7 @@ def __getitem__(self, args): INPUT: - ``args`` -- list of indices (possibly a single integer if - self is a 1-index object) or the character ``:`` for the full list + ``self`` is a 1-index object) or the character ``:`` for the full list of components OUTPUT: @@ -3295,7 +3234,6 @@ def __getitem__(self, args): -5 sage: c[0,1,2,1] -5 - """ no_format = self._output_formatter is None format_type = None # default value, possibly redefined below @@ -3332,7 +3270,7 @@ def __getitem__(self, args): else: return self._output_formatter(self._ring.zero(), format_type) - else: # non zero value + else: # nonzero value if no_format: if sign == 1: return self._comp[ind] @@ -3353,12 +3291,12 @@ def __getitem__(self, args): def __setitem__(self, args, value): r""" - Sets the component corresponding to the given indices. + Set the component corresponding to the given indices. INPUT: - ``args`` -- list of indices (possibly a single integer if - self is a 1-index object) ; if ``[:]`` is provided, all the + ``self`` is a 1-index object) ; if ``[:]`` is provided, all the components are set - ``value`` -- the value to be set or a list of values if ``args = [:]`` @@ -3382,7 +3320,6 @@ def __setitem__(self, args, value): Traceback (most recent call last): ... ValueError: by antisymmetry, the component cannot have a nonzero value for the indices (2, 2) - """ format_type = None # default value, possibly redefined below if isinstance(args, list): # case of [[...]] syntax @@ -3456,9 +3393,7 @@ def swap_adjacent_indices(self, pos1, pos2, pos3): the last index of set 1 (since the two sets are adjacent) - ``pos3`` -- 1 + position of the last index of set 2 - OUTPUT: - - - Components with index set 1 permuted with index set 2. + OUTPUT: components with index set 1 permuted with index set 2 EXAMPLES: @@ -3487,7 +3422,6 @@ def swap_adjacent_indices(self, pos1, pos2, pos3): 3 sage: c1[2,1,0] -3 - """ result = self._new_instance() # The symmetries: @@ -3518,9 +3452,7 @@ def __add__(self, other): - ``other`` -- components of the same number of indices and defined on the same frame as ``self`` - OUTPUT: - - - components resulting from the addition of ``self`` and ``other`` + OUTPUT: components resulting from the addition of ``self`` and ``other`` EXAMPLES:: @@ -3566,7 +3498,6 @@ def __add__(self, other): sage: s_par[:] == s[:] True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if isinstance(other, (int, Integer)) and other == 0: return +self @@ -3595,7 +3526,7 @@ def __add__(self, other): # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in other._comp] + ind_list = list(other._comp) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) # list of input parameters @@ -3649,7 +3580,7 @@ def paral_sum(a, b, local_list_ind): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in result.non_redundant_index_generator()] + ind_list = list(result.non_redundant_index_generator()) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) # definition of the list of input parameters @@ -3679,9 +3610,7 @@ def __mul__(self, other): - ``other`` -- components, on the same frame as ``self`` - OUTPUT: - - - the tensor product of ``self`` by ``other`` + OUTPUT: the tensor product of ``self`` by ``other`` EXAMPLES:: @@ -3727,7 +3656,6 @@ def __mul__(self, other): sage: s2_par[:] == s2[:] True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if not isinstance(other, Components): raise TypeError("the second argument for the tensor product " + @@ -3755,7 +3683,7 @@ def __mul__(self, other): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in self._comp] + ind_list = list(self._comp) ind_step = max(1, int(len(ind_list)/nproc)) local_list = lol(ind_list, ind_step) # list of input parameters: @@ -3888,7 +3816,6 @@ def trace(self, pos1, pos2): [-3 3 -1] sage: [[sum(c[i,k,k,j] for k in range(3)) for j in range(3)] for i in range(3)] # check [[0, 0, 0], [-2, 1, 0], [-3, 3, -1]] - """ if self._nid < 2: raise TypeError("contraction can be performed only on " + @@ -3994,9 +3921,7 @@ def non_redundant_index_generator(self): Generator of indices, with only ordered indices in case of symmetries, so that only non-redundant indices are generated. - OUTPUT: - - - an iterable index + OUTPUT: an iterable index EXAMPLES: @@ -4063,7 +3988,6 @@ def non_redundant_index_generator(self): sage: c = CompFullyAntiSym(QQ, V.basis(), 5) sage: list(c.non_redundant_index_generator()) # nothing since c is identically zero in this case (for 5 > 4) [] - """ if self._nid == 0 or self._dim == 0: return @@ -4079,7 +4003,7 @@ def non_redundant_index_generator(self): if ind[isym[k-1]] == imax: return ind[pos] = ind[isym[k-1]] + 1 - if not any([pos in isym for isym in sym]) and not any([pos in isym for isym in antisym]): + if not any(pos in isym for isym in sym) and not any(pos in isym for isym in antisym): sym.append([pos]) # treat non-symmetrized indices as being symmetrized with themselves while True: yield tuple(ind) @@ -4334,7 +4258,6 @@ def symmetrize(self, *pos): ], with symmetry on the index positions (1, 2) sage: s == 0 # because (1,2) are involved in the original antisymmetry True - """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup if not pos: @@ -4595,7 +4518,6 @@ def antisymmetrize(self, *pos): -2 sage: s[2,1,0,1] # the antisymmetry (0,2) holds -27/2 - """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup if not pos: @@ -4740,7 +4662,7 @@ class CompFullySym(CompWithSym): [-2 0 3] [ 0 3 0] - Internally, only non-redundant and non-zero components are stored:: + Internally, only non-redundant and nonzero components are stored:: sage: c._comp # random output order of the component dictionary {(0, 0): 1, (0, 1): -2, (1, 2): 3} @@ -4827,7 +4749,6 @@ class CompFullySym(CompWithSym): ], with symmetry on the index positions (0, 1) sage: 2*b1 + a == a + 2*b1 True - """ def __init__(self, ring, frame, nb_indices, start_index=0, output_formatter=None): @@ -4837,7 +4758,6 @@ def __init__(self, ring, frame, nb_indices, start_index=0, sage: from sage.tensor.modules.comp import CompFullySym sage: C = CompFullySym(ZZ, (1,2,3), 2) sage: TestSuite(C).run() - """ CompWithSym.__init__(self, ring, frame, nb_indices, start_index, output_formatter, sym=range(nb_indices)) @@ -4852,13 +4772,12 @@ def _repr_symmetry(self): sage: c = CompFullySym(ZZ, (1,2,3), 4) sage: c._repr_symmetry() ('Fully symmetric ', '') - """ return "Fully symmetric ", "" def _new_instance(self): r""" - Creates a :class:`CompFullySym` instance w.r.t. the same frame, + Create a :class:`CompFullySym` instance w.r.t. the same frame, and with the same number of indices. EXAMPLES:: @@ -4867,7 +4786,6 @@ def _new_instance(self): sage: c = CompFullySym(ZZ, (1,2,3), 4) sage: c._new_instance() Fully symmetric 4-indices components w.r.t. (1, 2, 3) - """ return CompFullySym(self._ring, self._frame, self._nid, self._sindex, self._output_formatter) @@ -4879,7 +4797,7 @@ def __getitem__(self, args): INPUT: - ``args`` -- list of indices (possibly a single integer if - self is a 1-index object) or the character ``:`` for the full list + ``self`` is a 1-index object) or the character ``:`` for the full list of components OUTPUT: @@ -4901,7 +4819,6 @@ def __getitem__(self, args): [0 4 0] [4 0 0] [0 0 0] - """ no_format = self._output_formatter is None format_type = None # default value, possibly redefined below @@ -4931,7 +4848,7 @@ def __getitem__(self, args): return self._get_list(indices, no_format, format_type) ind = self._ordered_indices(indices)[1] # [0]=sign is not used - if ind in self._comp: # non zero value + if ind in self._comp: # nonzero value if no_format: return self._comp[ind] elif format_type is None: @@ -4950,13 +4867,13 @@ def __getitem__(self, args): def __setitem__(self, args, value): r""" - Sets the component corresponding to the given indices. + Set the component corresponding to the given indices. INPUT: - ``indices`` -- list of indices (possibly a single integer if - self is a 1-index object) ; if [:] is provided, all the components - are set. + ``self`` is a 1-index object); if [:] is provided, all the components + are set - ``value`` -- the value to be set or a list of values if ``args = [:]`` @@ -4979,7 +4896,6 @@ def __setitem__(self, args, value): [1 2 3] [2 4 5] [3 5 6] - """ format_type = None # default value, possibly redefined below if isinstance(args, list): # case of [[...]] syntax @@ -5033,9 +4949,7 @@ def __add__(self, other): - ``other`` -- components of the same number of indices and defined on the same frame as ``self`` - OUTPUT: - - - components resulting from the addition of ``self`` and ``other`` + OUTPUT: components resulting from the addition of ``self`` and ``other`` EXAMPLES:: @@ -5100,7 +5014,6 @@ def __add__(self, other): sage: s_par == c.__add__(a) # test of commutativity of parallel comput. True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if isinstance(other, (int, Integer)) and other == 0: return +self @@ -5125,7 +5038,7 @@ def __add__(self, other): # parallel sum lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in other._comp] + ind_list = list(other._comp) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) # definition of the list of input parameters @@ -5194,7 +5107,7 @@ class CompFullyAntiSym(CompWithSym): [ -3 0 -1] [-1/2 1 0] - Internally, only non-redundant and non-zero components are stored:: + Internally, only non-redundant and nonzero components are stored:: sage: c._comp # random output order of the component dictionary {(0, 1): 3, (0, 2): 1/2, (1, 2): -1} @@ -5286,7 +5199,6 @@ class CompFullyAntiSym(CompWithSym): ], with antisymmetry on the index positions (0, 1) sage: 2*b1 + a == a + 2*b1 True - """ def __init__(self, ring, frame, nb_indices, start_index=0, output_formatter=None): @@ -5296,7 +5208,6 @@ def __init__(self, ring, frame, nb_indices, start_index=0, sage: from sage.tensor.modules.comp import CompFullyAntiSym sage: C = CompFullyAntiSym(ZZ, (1,2,3), 2) sage: TestSuite(C).run() - """ CompWithSym.__init__(self, ring, frame, nb_indices, start_index, output_formatter, antisym=range(nb_indices)) @@ -5311,13 +5222,12 @@ def _repr_symmetry(self): sage: c = CompFullyAntiSym(ZZ, (1,2,3), 4) sage: c._repr_symmetry() ('Fully antisymmetric ', '') - """ return "Fully antisymmetric ", "" def _new_instance(self): r""" - Creates a :class:`CompFullyAntiSym` instance w.r.t. the same frame, + Create a :class:`CompFullyAntiSym` instance w.r.t. the same frame, and with the same number of indices. EXAMPLES:: @@ -5326,7 +5236,6 @@ def _new_instance(self): sage: c = CompFullyAntiSym(ZZ, (1,2,3), 4) sage: c._new_instance() Fully antisymmetric 4-indices components w.r.t. (1, 2, 3) - """ return CompFullyAntiSym(self._ring, self._frame, self._nid, self._sindex, self._output_formatter) @@ -5340,9 +5249,7 @@ def __add__(self, other): - ``other`` -- components of the same number of indices and defined on the same frame as ``self`` - OUTPUT: - - - components resulting from the addition of ``self`` and ``other`` + OUTPUT: components resulting from the addition of ``self`` and ``other`` EXAMPLES:: @@ -5399,7 +5306,6 @@ def __add__(self, other): sage: s_par == a + c True sage: Parallelism().set('tensor', nproc=1) # switch off parallelization - """ if isinstance(other, (int, Integer)) and other == 0: return +self @@ -5423,7 +5329,7 @@ def __add__(self, other): if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in other._comp] + ind_list = list(other._comp) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) # list of input parameters @@ -5554,7 +5460,6 @@ def interior_product(self, other): 360 sage: c == a.contract(0, 1, 2, 3, b, 0, 1, 2, 3) True - """ from sage.arith.misc import factorial # Sanity checks: @@ -5599,6 +5504,7 @@ def interior_product(self, other): #****************************************************************************** + class KroneckerDelta(CompFullySym): r""" Kronecker delta `\delta_{ij}`. @@ -5655,7 +5561,6 @@ class KroneckerDelta(CompFullySym): sage: d = KroneckerDelta(QQ, V.basis(), output_formatter=str) sage: d[:] [['1', '0', '0'], ['0', '1', '0'], ['0', '0', '1']] - """ def __init__(self, ring, frame, start_index=0, output_formatter=None): r""" @@ -5664,7 +5569,6 @@ def __init__(self, ring, frame, start_index=0, output_formatter=None): sage: from sage.tensor.modules.comp import KroneckerDelta sage: d = KroneckerDelta(ZZ, (1,2,3)) sage: TestSuite(d).run() - """ CompFullySym.__init__(self, ring, frame, 2, start_index, output_formatter) @@ -5680,14 +5584,13 @@ def _repr_(self): sage: from sage.tensor.modules.comp import KroneckerDelta sage: KroneckerDelta(ZZ, (1,2,3)) Kronecker delta of size 3x3 - """ n = str(self._dim) return "Kronecker delta of size " + n + "x" + n def __setitem__(self, args, value): r""" - Should not be used (the components of a Kronecker delta are constant) + Should not be used (the components of a Kronecker delta are constant). EXAMPLES:: @@ -5697,6 +5600,5 @@ def __setitem__(self, args, value): Traceback (most recent call last): ... TypeError: the components of a Kronecker delta cannot be changed - """ raise TypeError("the components of a Kronecker delta cannot be changed") diff --git a/src/sage/tensor/modules/ext_pow_free_module.py b/src/sage/tensor/modules/ext_pow_free_module.py index fb708df8345..e5218372a8f 100644 --- a/src/sage/tensor/modules/ext_pow_free_module.py +++ b/src/sage/tensor/modules/ext_pow_free_module.py @@ -62,6 +62,7 @@ from sage.tensor.modules.alternating_contr_tensor import AlternatingContrTensor from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm + class ExtPowerFreeModule(FiniteRankFreeModule_abstract): r""" Exterior power of a free module of finite rank over a commutative @@ -159,7 +160,7 @@ class ExtPowerFreeModule(FiniteRankFreeModule_abstract): sage: A(0) is A.zero() True - while non-zero elements are constructed by providing their components in a + while nonzero elements are constructed by providing their components in a given basis:: sage: e @@ -217,7 +218,6 @@ class ExtPowerFreeModule(FiniteRankFreeModule_abstract): no symmetry; antisymmetry: (0, 1) sage: ta == a # equality as type-(2,0) tensors True - """ Element = AlternatingContrTensor @@ -233,7 +233,6 @@ def __init__(self, fmodule, degree, name=None, latex_name=None): 2nd exterior power of the Rank-3 free module M over the Integer Ring sage: TestSuite(A).run() - """ from sage.arith.misc import binomial from sage.typeset.unicode_characters import unicode_bigwedge @@ -290,7 +289,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, sage: a[e,0,2], a[e,1,2] = 3, -1 sage: a.display() a = 3 e_0∧e_2 - e_1∧e_2 - """ if isinstance(comp, (int, Integer)) and comp == 0: return self.zero() @@ -338,7 +336,6 @@ def _an_element_(self): on the 4-dimensional vector space M2 over the Rational Field sage: M2.default_basis() Basis (e_0,e_1,e_2,e_3) on the 4-dimensional vector space M2 over the Rational Field - """ resu = self.element_class(self._fmodule, self._degree) # Make sure that the base module has a default basis @@ -365,7 +362,6 @@ def zero(self): module M over the Integer Ring sage: A(0) is A.zero() True - """ resu = self._element_constructor_(name='zero', latex_name='0') for basis in self._fmodule._known_bases: @@ -414,7 +410,6 @@ def base_module(self): Rank-5 free module M over the Integer Ring sage: A.base_module() is M True - """ return self._fmodule @@ -435,7 +430,6 @@ def degree(self): 2 sage: M.exterior_power(4).degree() 4 - """ return self._degree @@ -539,7 +533,7 @@ class ExtPowerDualFreeModule(FiniteRankFreeModule_abstract): sage: A(0) is A.zero() True - while non-zero elements are constructed by providing their components in a + while nonzero elements are constructed by providing their components in a given basis:: sage: e @@ -601,7 +595,6 @@ class ExtPowerDualFreeModule(FiniteRankFreeModule_abstract): a = 3 e^0∧e^1 - e^0∧e^2 + 4 e^1∧e^2 sage: ta.symmetries() # the antisymmetry is of course preserved no symmetry; antisymmetry: (0, 1) - """ Element = FreeModuleAltForm @@ -617,7 +610,6 @@ def __init__(self, fmodule, degree, name=None, latex_name=None): 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring sage: TestSuite(A).run() - """ from sage.arith.misc import binomial from sage.typeset.unicode_characters import unicode_bigwedge @@ -674,7 +666,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, sage: a[e,0,2], a[e,1,2] = 3, -1 sage: a.display() a = 3 e^0∧e^2 - e^1∧e^2 - """ if isinstance(comp, (int, Integer)) and comp == 0: return self.zero() @@ -734,7 +725,6 @@ def _an_element_(self): Alternating form of degree 2 on the 4-dimensional vector space M2 over the Rational Field sage: M2.default_basis() Basis (e_0,e_1,e_2,e_3) on the 4-dimensional vector space M2 over the Rational Field - """ resu = self.element_class(self._fmodule, self._degree) # Make sure that the base module has a default basis @@ -761,7 +751,6 @@ def zero(self): the Integer Ring sage: A(0) is A.zero() True - """ resu = self._element_constructor_(name='zero', latex_name='0') for basis in self._fmodule._known_bases: @@ -788,7 +777,6 @@ def _repr_(self): '5th exterior power of the dual of the Rank-5 free module M over the Integer Ring' sage: M.dual_exterior_power(21)._repr_() '21st exterior power of the dual of the Rank-5 free module M over the Integer Ring' - """ description = "{}".format(self._degree.ordinal_str()) description += " exterior power of the dual of the {}".format( @@ -812,7 +800,6 @@ def base_module(self): Rank-5 free module M over the Integer Ring sage: A.base_module() is M True - """ return self._fmodule @@ -832,6 +819,5 @@ def degree(self): 2 sage: M.dual_exterior_power(4).degree() 4 - """ return self._degree diff --git a/src/sage/tensor/modules/finite_rank_free_module.py b/src/sage/tensor/modules/finite_rank_free_module.py index 3525745f331..9a4e44f0f12 100644 --- a/src/sage/tensor/modules/finite_rank_free_module.py +++ b/src/sage/tensor/modules/finite_rank_free_module.py @@ -535,7 +535,8 @@ class :class:`~sage.modules.free_module.FreeModule_generic` # ****************************************************************************** from __future__ import annotations -from typing import Generator, Optional +from typing import Optional +from collections.abc import Generator from sage.categories.fields import Fields from sage.categories.homset import Hom @@ -582,7 +583,6 @@ def __init__( sage: TestSuite(M).run() sage: f = M.basis('f') sage: TestSuite(M).run() - """ # This duplicates the normalization done in __classcall_private__, # but it is needed for various subclasses. @@ -620,7 +620,6 @@ def _latex_(self): '\\mathcal{M}' sage: latex(M1) \mathcal{M} - """ if self._latex_name is None: return r'\mbox{' + str(self) + r'}' @@ -654,7 +653,6 @@ def rank(self) -> int: 27 sage: M.tensor_module(2,2).rank() 81 - """ return self._rank @@ -697,7 +695,6 @@ def zero(self): [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]] - """ resu = self._element_constructor_(name='zero', latex_name='0') for basis in self._known_bases: @@ -1234,7 +1231,6 @@ class :class:`~sage.modules.module.Module`. 0.333333333333333 e_0 - 2.00000000000000 e_2 sage: v.display(e, format_spec=10) # 10 bits of precision 0.33 e_0 - 2.0 e_2 - """ Element = FiniteRankFreeModuleElement @@ -1244,7 +1240,7 @@ class :class:`~sage.modules.module.Module`. def __classcall_private__(cls, ring, rank, name=None, latex_name=None, start_index=0, output_formatter=None, category=None, ambient=None): r""" - Normalize init arguments for ``UniqueRepresentation`` + Normalize init arguments for ``UniqueRepresentation``. TESTS:: @@ -1289,7 +1285,6 @@ def __init__( sage: TestSuite(M).run() sage: f = M.basis('f') sage: TestSuite(M).run() - """ super().__init__(ring, rank, name=name, latex_name=latex_name, category=category, ambient=ambient) @@ -1320,7 +1315,7 @@ def __init__( def construction(self): """ - The construction functor and base ring for self. + The construction functor and base ring for ``self``. EXAMPLES:: @@ -1373,7 +1368,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, Element zero of the Rank-3 free module M over the Integer Ring sage: v = M._element_constructor_() ; v Element of the Rank-3 free module M over the Integer Ring - """ if isinstance(comp, (int, Integer)) and comp == 0: return self.zero() @@ -1398,7 +1392,6 @@ def _an_element_(self): True sage: v.parent() Rank-3 free module M over the Integer Ring - """ if self._def_basis is None: self.basis('e') @@ -1418,7 +1411,6 @@ def _repr_(self): sage: FiniteRankFreeModule(ZZ, 3, name='M') Rank-3 free module M over the Integer Ring - """ if self._ring in Fields(): description = "{}-dimensional vector space ".format(self._rank) @@ -1456,7 +1448,6 @@ def _Hom_(self, other, category=None): Set of Morphisms from Rank-3 free module M over the Integer Ring to Rank-2 free module N over the Integer Ring in Category of finite dimensional modules over Integer Ring - """ from .free_module_homset import FreeModuleHomset return FreeModuleHomset(self, other) @@ -1468,9 +1459,9 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): INPUT: - - ``k`` -- non-negative integer; the contravariant rank, the tensor + - ``k`` -- nonnegative integer; the contravariant rank, the tensor type being `(k, l)` - - ``l`` -- non-negative integer; the covariant rank, the tensor type + - ``l`` -- nonnegative integer; the covariant rank, the tensor type being `(k, l)` - ``sym`` -- (default: ``None``) a symmetry or a list of symmetries among the tensor arguments: each symmetry is described by a tuple @@ -1650,7 +1641,7 @@ def exterior_power(self, p): INPUT: - - ``p`` -- non-negative integer + - ``p`` -- nonnegative integer OUTPUT: @@ -1690,7 +1681,6 @@ def exterior_power(self, p): See :class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerFreeModule` for more documentation. - """ try: return self._exterior_powers[p] @@ -1725,7 +1715,7 @@ def dual_exterior_power(self, p): INPUT: - - ``p`` -- non-negative integer + - ``p`` -- nonnegative integer OUTPUT: @@ -1831,7 +1821,6 @@ def general_linear_group(self): See :class:`~sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup` for more documentation. - """ from sage.tensor.modules.free_module_linear_group import \ FreeModuleLinearGroup @@ -1999,7 +1988,6 @@ def basis(self, symbol, latex_symbol=None, from_family=None, For more documentation on bases see :class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`. - """ from .free_module_basis import FreeModuleBasis for other in self._known_bases: @@ -2053,7 +2041,6 @@ def _test_basis(self, tester=None, **options): running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass running ._test_some_elements() . . . pass - """ from sage.misc.sage_unittest import TestSuite # The intention is to raise an exception only if this is @@ -2288,7 +2275,6 @@ def tensor_from_comp(self, tensor_type, comp, name=None, latex_name=None): Rank-3 free module M over the Integer Ring sage: t.display(e) 4 e^0∧e^1 + 5 e^1∧e^2 - """ from .comp import CompWithSym, CompFullyAntiSym @@ -2378,7 +2364,6 @@ def alternating_contravariant_tensor(self, degree, name=None, See :class:`~sage.tensor.modules.alternating_contr_tensor.AlternatingContrTensor` for more documentation. - """ if degree == 1: return self.element_class(self, name=name, @@ -2438,7 +2423,6 @@ def alternating_form(self, degree, name=None, latex_name=None): See :class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm` for more documentation. - """ if degree == 0: try: @@ -2498,7 +2482,6 @@ def linear_form(self, name=None, latex_name=None): See :class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm` for more documentation. - """ return self.dual_exterior_power(1).element_class(self, 1, name=name, latex_name=latex_name) @@ -2584,7 +2567,6 @@ def automorphism(self, matrix=None, basis=None, name=None, See :class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism` for more documentation. - """ resu = self.general_linear_group().element_class(self, name=name, latex_name=latex_name) @@ -2689,7 +2671,6 @@ def sym_bilinear_form(self, name=None, latex_name=None): See :class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor` for more documentation. - """ return self.tensor_module(0,2).element_class(self, (0,2), name=name, latex_name=latex_name, sym=(0,1)) @@ -2733,11 +2714,10 @@ def dual(self): sage: e = M.basis('e') sage: e.dual_basis()[0] in M.dual() True - """ return self.dual_exterior_power(1) - def irange(self, start: Optional[int] = None) -> Generator[int, None, None]: + def irange(self, start: int | None = None) -> Generator[int, None, None]: r""" Single index generator, labelling the elements of a basis of ``self``. @@ -2770,7 +2750,6 @@ def irange(self, start: Optional[int] = None) -> Generator[int, None, None]: sage: M2 = FiniteRankFreeModule(ZZ, 3, start_index=-4) sage: list(M2.irange()) [-4, -3, -2] - """ si = self._sindex imax = self._rank + si @@ -2815,7 +2794,6 @@ def default_basis(self): Basis (f_1,f_2) on the Rank-2 free module M over the Integer Ring sage: M.default_basis() Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring - """ if self._def_basis is None: print("No default basis has been defined on the {}".format(self)) @@ -2823,7 +2801,7 @@ def default_basis(self): def set_default_basis(self, basis): r""" - Sets the default basis of ``self``. + Set the default basis of ``self``. The *default basis* is simply a basis whose name can be skipped in methods requiring a basis as an argument. By default, it is the first @@ -2849,7 +2827,6 @@ def set_default_basis(self, basis): sage: M.set_default_basis(f) sage: M.default_basis() Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring - """ from .free_module_basis import FreeModuleBasis if not isinstance(basis, FreeModuleBasis): @@ -2925,7 +2902,6 @@ def bases(self): sage: M.bases() [Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring, Basis (f_1,f_2,f_3) on the Rank-3 free module M_3 over the Integer Ring] - """ return list(self._known_bases) @@ -3030,7 +3006,6 @@ def change_of_basis(self, basis1, basis2): sage: R == Q*P^(-1) True - """ if basis1 == basis2: return self.identity_map() @@ -3084,8 +3059,8 @@ def set_change_of_basis(self, basis1, basis2, change_of_basis, :class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism` describing the automorphism `P` that relates the basis `(e_i)` to the basis `(f_i)` according to `f_i = P(e_i)` - - ``compute_inverse`` (default: ``True``) -- if set to ``True``, the - inverse automorphism is computed and the change from basis `(f_i)` + - ``compute_inverse`` -- boolean (default: ``True``); if set to ``True``, + the inverse automorphism is computed and the change from basis `(f_i)` to `(e_i)` is set to it in the internal dictionary ``self._basis_changes`` @@ -3115,7 +3090,6 @@ def set_change_of_basis(self, basis1, basis2, change_of_basis, f_0 = e_0 - e_1 sage: e[0].display(f) e_0 = 3/5 f_0 + 1/5 f_1 - """ if basis1 not in self._known_bases: raise TypeError("{} is not a basis of the {}".format(basis1, @@ -3167,7 +3141,7 @@ def hom(self, codomain, matrix_rep, bases=None, name=None, - ``name`` -- (default: ``None``) string; name given to the homomorphism - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote - the homomorphism; if None, ``name`` will be used. + the homomorphism. If ``None``, ``name`` will be used. OUTPUT: @@ -3211,7 +3185,6 @@ def hom(self, codomain, matrix_rep, bases=None, name=None, See class :class:`~sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism` for more documentation. - """ homset = Hom(self, codomain) return homset(matrix_rep, bases=bases, name=name, @@ -3238,7 +3211,7 @@ def endomorphism(self, matrix_rep, basis=None, name=None, latex_name=None): - ``name`` -- (default: ``None``) string; name given to the endomorphism - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote - the endomorphism; if none is provided, ``name`` will be used. + the endomorphism. If none is provided, ``name`` will be used. OUTPUT: @@ -3277,7 +3250,6 @@ def endomorphism(self, matrix_rep, basis=None, name=None, latex_name=None): See :class:`~sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism` for more documentation. - """ from sage.categories.homset import End if basis is None: @@ -3355,7 +3327,6 @@ def identity_map(self, name='Id', latex_name=None): Identity map of the Rank-3 free module N over the Integer Ring sage: latex(Id) \mathrm{Id}_N - """ if self._identity_map is None: self._identity_map = self.general_linear_group().one() @@ -3432,7 +3403,7 @@ class FiniteRankDualFreeModule(ReflexiveModule_dual, FiniteRankFreeModule_abstra sage: A(0) is A.zero() True - while non-zero elements are constructed by providing their components in a + while nonzero elements are constructed by providing their components in a given basis:: sage: e @@ -3481,7 +3452,6 @@ def __init__(self, fmodule, name=None, latex_name=None): sage: A = FiniteRankDualFreeModule(M) ; A Dual of the Rank-3 free module M over the Integer Ring sage: TestSuite(A).run() - """ self._fmodule = fmodule rank = fmodule._rank @@ -3559,7 +3529,6 @@ def _an_element_(self): Linear form on the 4-dimensional vector space M2 over the Rational Field sage: M2.default_basis() Basis (e_0,e_1,e_2,e_3) on the 4-dimensional vector space M2 over the Rational Field - """ resu = self.element_class(self._fmodule, 1) # Make sure that the base module has a default basis @@ -3585,7 +3554,6 @@ def zero(self): Linear form zero on the Rank-3 free module M over the Integer Ring sage: A(0) is A.zero() True - """ resu = self._element_constructor_(name='zero', latex_name='0') for basis in self._fmodule._known_bases: @@ -3624,6 +3592,5 @@ def base_module(self): Rank-5 free module M over the Integer Ring sage: A.base_module() is M True - """ return self._fmodule diff --git a/src/sage/tensor/modules/format_utilities.py b/src/sage/tensor/modules/format_utilities.py index 1cc0e383f1e..d00e00f8071 100644 --- a/src/sage/tensor/modules/format_utilities.py +++ b/src/sage/tensor/modules/format_utilities.py @@ -70,7 +70,6 @@ def is_atomic(expr, sep=['+', '-']): False sage: is_atomic("(a mod b)", sep=['mod']) True - """ if not isinstance(expr, str): raise TypeError("The argument must be a string") @@ -125,7 +124,6 @@ def is_atomic_wedge_txt(expression): False sage: is_atomic_wedge_txt(r"(a∧b∧c)") True - """ return is_atomic(expression, sep=['∧']) @@ -171,7 +169,6 @@ def is_atomic_wedge_latex(expression): True sage: is_atomic_wedge_latex(r"\omega\wedge(\theta+a)") False - """ return is_atomic(expression, sep=['\\wedge']) @@ -194,7 +191,6 @@ def format_mul_txt(name1, operator, name2): '(a+b)*(c+d)' sage: format_mul_txt(None, '*', 'b') sage: format_mul_txt('a', '*', None) - """ if name1 is None or name2 is None: return None @@ -223,7 +219,6 @@ def format_mul_latex(name1, operator, name2): '\\left(a+b\\right)*\\left(c+d\\right)' sage: format_mul_latex(None, '*', 'b') sage: format_mul_latex('a', '*', None) - """ if name1 is None or name2 is None: return None @@ -248,7 +243,6 @@ def format_unop_txt(operator, name): sage: format_unop_txt('-', '(a+b)') '-(a+b)' sage: format_unop_txt('-', None) - """ if name is None: return None @@ -272,7 +266,6 @@ def format_unop_latex(operator, name): sage: format_unop_latex('-', '(a+b)') '-(a+b)' sage: format_unop_latex('-', None) - """ if name is None: return None @@ -299,7 +292,6 @@ class FormattedExpansion(SageObject): x/2 sage: latex(f) \frac{x}{2} - """ def __init__(self, txt=None, latex=None): r""" @@ -309,7 +301,6 @@ def __init__(self, txt=None, latex=None): sage: f = FormattedExpansion('v', r'\tilde v') sage: f v - """ self._txt = txt self._latex = latex @@ -324,7 +315,6 @@ def _repr_(self): sage: f = FormattedExpansion('v', r'\tilde v') sage: f._repr_() 'v' - """ return self._txt @@ -338,6 +328,5 @@ def _latex_(self) -> LatexExpr: sage: f = FormattedExpansion('v', r'\tilde v') sage: f._latex_() '\\tilde v' - """ return self._latex diff --git a/src/sage/tensor/modules/free_module_alt_form.py b/src/sage/tensor/modules/free_module_alt_form.py index 994980e02c8..b9d9f98ef63 100644 --- a/src/sage/tensor/modules/free_module_alt_form.py +++ b/src/sage/tensor/modules/free_module_alt_form.py @@ -40,6 +40,7 @@ from sage.tensor.modules.free_module_tensor import FreeModuleTensor from sage.tensor.modules.comp import Components, CompFullyAntiSym + class FreeModuleAltForm(FreeModuleTensor): r""" Alternating form on a free module of finite rank over a commutative ring. @@ -210,7 +211,6 @@ class FreeModuleAltForm(FreeModuleTensor): Integer Ring sage: s.display(e) zero = 0 - """ def __init__(self, fmodule, degree, name=None, latex_name=None): r""" @@ -223,7 +223,7 @@ def __init__(self, fmodule, degree, name=None, latex_name=None): sage: e = M.basis('e') sage: a = FreeModuleAltForm(M, 2, name='a') sage: a[e,0,1] = 2 - sage: TestSuite(a).run(skip="_test_category") # see below + sage: TestSuite(a).run(skip='_test_category') # see below In the above test suite, _test_category fails because a is not an instance of a.parent().category().element_class. Actually alternating @@ -233,7 +233,6 @@ def __init__(self, fmodule, degree, name=None, latex_name=None): sage: a1 = M.dual_exterior_power(2).element_class(M, 2, name='a') sage: a1[e,0,1] = 2 sage: TestSuite(a1).run() - """ FreeModuleTensor.__init__(self, fmodule, (0,degree), name=name, latex_name=latex_name, @@ -289,7 +288,6 @@ def _new_instance(self): Rank-3 free module M over the Integer Ring sage: b._new_instance().parent() is b.parent() True - """ return self.__class__(self._fmodule, self._tensor_rank) @@ -322,7 +320,6 @@ def _new_comp(self, basis): sage: a._new_comp(e) 1-index components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring - """ fmodule = self._fmodule # the base free module if self._tensor_rank == 1: @@ -344,7 +341,6 @@ def degree(self): sage: a = M.alternating_form(2, name='a') sage: a.degree() 2 - """ return self._tensor_rank @@ -382,7 +378,6 @@ def _display_expansion(self, basis=None, format_spec=None): e^0 - 3 e^1 + 4 e^2 sage: latex(a._display_expansion()) # display in the notebook e^{0} -3 e^{1} + 4 e^{2} - """ from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_wedge @@ -560,7 +555,6 @@ def display(self, basis=None, format_spec=None): sage: a[0,1] = SR.var('t', domain='real') sage: a.display() t e^0∧e^1 - """ from sage.misc.latex import latex from sage.tensor.modules.format_utilities import FormattedExpansion @@ -641,7 +635,6 @@ def wedge(self, other): True sage: d.wedge(c) == c.wedge(d) True - """ from sage.typeset.unicode_characters import unicode_wedge from .format_utilities import is_atomic @@ -809,11 +802,10 @@ def interior_product(self, alt_tensor): -60 sage: c == a.contract(0, 1, 2, b, 0, 1, 2) True - """ from .format_utilities import is_atomic from .alternating_contr_tensor import AlternatingContrTensor - if not isinstance(alt_tensor, AlternatingContrTensor): + if not isinstance(alt_tensor, AlternatingContrTensor): raise TypeError("{} is not an alternating ".format(alt_tensor) + "contravariant tensor") p_res = alt_tensor._tensor_rank - self._tensor_rank # degree of result diff --git a/src/sage/tensor/modules/free_module_automorphism.py b/src/sage/tensor/modules/free_module_automorphism.py index e8a779482f4..3a826b1e0ef 100644 --- a/src/sage/tensor/modules/free_module_automorphism.py +++ b/src/sage/tensor/modules/free_module_automorphism.py @@ -56,7 +56,7 @@ class FreeModuleAutomorphism(FreeModuleTensor, MultiplicativeGroupElement): - ``name`` -- (default: ``None``) name given to the automorphism - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the automorphism; if none is provided, the LaTeX symbol is set to ``name`` - - ``is_identity`` -- (default: ``False``) determines whether the + - ``is_identity`` -- boolean (default: ``False``); determines whether the constructed object is the identity automorphism, i.e. the identity map of `M` considered as an automorphism (the identity element of the general linear group) @@ -254,7 +254,6 @@ class FreeModuleAutomorphism(FreeModuleTensor, MultiplicativeGroupElement): True sage: s.matrix(f) == a.matrix(f) + b.matrix(f) True - """ def __init__(self, fmodule, name=None, latex_name=None): r""" @@ -265,7 +264,7 @@ def __init__(self, fmodule, name=None, latex_name=None): sage: from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism sage: a = FreeModuleAutomorphism(M, name='a') sage: a[e,:] = [[-1,0,0],[0,1,2],[0,1,3]] - sage: TestSuite(a).run(skip="_test_category") # see below + sage: TestSuite(a).run(skip='_test_category') # see below In the above test suite, _test_category fails because a is not an instance of a.parent().category().element_class. Actually automorphism @@ -285,7 +284,6 @@ def __init__(self, fmodule, name=None, latex_name=None): sage: b = M.general_linear_group().an_element() sage: TestSuite(b).run() - """ FreeModuleTensor.__init__(self, fmodule, (1,1), name=name, latex_name=latex_name, @@ -312,7 +310,6 @@ def _repr_(self): Automorphism a of the 3-dimensional vector space M over the Rational Field sage: M.identity_map() Identity map of the 3-dimensional vector space M over the Rational Field - """ if self._is_identity: description = "Identity map " @@ -340,7 +337,6 @@ def _new_instance(self): sage: Id = M.identity_map() sage: Id._new_instance() Automorphism of the Rank-3 free module M over the Integer Ring - """ return self.__class__(self._fmodule) @@ -360,7 +356,6 @@ def _del_derived(self): Rational Field sage: a._del_derived() sage: a._inverse # has been reset to None - """ # First delete the derived quantities pertaining to FreeModuleTensor: FreeModuleTensor._del_derived(self) @@ -479,7 +474,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such Kronecker delta of size 3x3 sage: id.comp(f) Kronecker delta of size 3x3 - """ if self._is_identity: raise ValueError("the components of the identity map cannot be " @@ -551,7 +545,6 @@ class :class:`~sage.tensor.modules.comp.Components`; Kronecker delta of size 3x3 sage: id.comp(f) Kronecker delta of size 3x3 - """ if self._is_identity: raise ValueError("the components of the identity map cannot be " @@ -613,7 +606,6 @@ def __call__(self, *arg): True sage: id(b,v) == b(v) True - """ from .free_module_element import FiniteRankFreeModuleElement if len(arg) > 1: @@ -752,7 +744,6 @@ def __invert__(self): sage: c.inverse() Automorphism (a^(-1)*b)^(-1) of the Rank-3 free module M over the Integer Ring - """ from .comp import Components if self._is_identity: @@ -845,7 +836,6 @@ def _mul_(self, other): True sage: a.inverse()._mul_(a) == id True - """ # No need for consistency check since self and other are guaranteed # to have the same parent. In particular, they are defined on the same @@ -1027,7 +1017,6 @@ def matrix(self, basis1=None, basis2=None): [1 0 0] [0 1 0] [0 0 1] - """ from sage.matrix.constructor import matrix fmodule = self._fmodule @@ -1131,7 +1120,6 @@ def det(self): sage: id = M.identity_map() sage: id.det() 1 - """ return self._some_matrix().det @@ -1213,6 +1201,5 @@ def trace(self): sage: id = M.identity_map() sage: id.trace() 2 - """ return self._some_matrix().trace diff --git a/src/sage/tensor/modules/free_module_basis.py b/src/sage/tensor/modules/free_module_basis.py index 1f67d8b2e81..f882b88e300 100644 --- a/src/sage/tensor/modules/free_module_basis.py +++ b/src/sage/tensor/modules/free_module_basis.py @@ -35,6 +35,7 @@ from sage.sets.family import AbstractFamily from sage.structure.unique_representation import UniqueRepresentation + class Basis_abstract(UniqueRepresentation, AbstractFamily): """ Abstract base class for (dual) bases of free modules. @@ -174,7 +175,6 @@ def _test_iter_len(self, **options): sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: e._test_iter_len() - """ tester = self._tester(**options) g = iter(self) @@ -257,7 +257,6 @@ def __getitem__(self, index): Element e_2 of the Rank-3 free module M over the Integer Ring sage: e1.__getitem__(3) Element e_3 of the Rank-3 free module M over the Integer Ring - """ si = self._fmodule._sindex if isinstance(index, slice): @@ -300,7 +299,6 @@ def _latex_(self): sage: f = e.dual_basis() sage: f._latex_() '\\left(e^{0},e^{1},e^{2}\\right)' - """ return self._latex_name @@ -371,7 +369,6 @@ def set_name(self, symbol, latex_symbol=None, indices=None, sage: latex(e) \left(E_{\alpha},E_{\beta},E_{\gamma}\right) sage: e.set_name('e') # back to the default - """ n = self._fmodule._rank if index_position == "down": @@ -423,6 +420,7 @@ def set_name(self, symbol, latex_symbol=None, indices=None, #****************************************************************************** + class FreeModuleCoBasis(Basis_abstract): r""" Dual basis of a free module over a commutative ring. @@ -486,7 +484,6 @@ class FreeModuleCoBasis(Basis_abstract): TESTS:: sage: TestSuite(f).run() - """ def __init__(self, basis, symbol, latex_symbol=None, indices=None, latex_indices=None): @@ -498,7 +495,6 @@ def __init__(self, basis, symbol, latex_symbol=None, indices=None, sage: e = M.basis('e') sage: f = FreeModuleCoBasis(e, 'f') sage: TestSuite(f).run() - """ self._basis = basis Basis_abstract.__init__(self, basis._fmodule, symbol, latex_symbol, @@ -550,12 +546,12 @@ def _repr_(self): sage: f Dual basis (e^0,e^1,e^2) on the Rank-3 free module M over the Integer Ring - """ return "Dual basis {} on the {}".format(self._name, self._fmodule) #****************************************************************************** + class FreeModuleBasis(Basis_abstract): r""" Basis of a free module over a commutative ring `R`. @@ -663,7 +659,6 @@ class FreeModuleBasis(Basis_abstract): sage: TestSuite(e).run() sage: TestSuite(f).run() sage: TestSuite(g).run() - """ # The following class attribute must be redefined by any derived class: _cobasis_class = FreeModuleCoBasis @@ -718,7 +713,6 @@ def __init__(self, fmodule, symbol, latex_symbol=None, indices=None, sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = FreeModuleBasis(M, 'e', latex_symbol=r'\epsilon') sage: TestSuite(e).run() - """ Basis_abstract.__init__(self, fmodule, symbol, latex_symbol, indices, latex_indices) @@ -786,7 +780,6 @@ def _repr_(self): sage: e1 = M1.basis('e') sage: e1 Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring - """ return "Basis {} on the {}".format(self._name, self._fmodule) @@ -820,9 +813,7 @@ def _new_instance(self, symbol, latex_symbol=None, indices=None, - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol`` but for the dual basis - OUTPUT: - - - instance of :class:`FreeModuleBasis` + OUTPUT: instance of :class:`FreeModuleBasis` EXAMPLES:: @@ -838,7 +829,6 @@ def _new_instance(self, symbol, latex_symbol=None, indices=None, Basis (E_x,E_y,E_z) on the Rank-3 free module M over the Integer Ring sage: _.dual_basis() Dual basis (E^x,E^y,E^z) on the Rank-3 free module M over the Integer Ring - """ return FreeModuleBasis(self._fmodule, symbol, latex_symbol=latex_symbol, indices=indices, latex_indices=latex_indices, @@ -854,7 +844,7 @@ def _init_from_family(self, family): INPUT: - - ``family``: a family of elements of ``self.free_module()`` that are + - ``family`` -- a family of elements of ``self.free_module()`` that are linearly independent and spanning ``self.free_module()`` EXAMPLES:: @@ -875,7 +865,6 @@ def _init_from_family(self, family): e_1 = 1/2 f_1 + 1/2 f_2 sage: e[2].display(f) e_2 = 1/2 f_1 - 1/2 f_2 - """ fmodule = self._fmodule n = fmodule.rank() @@ -922,7 +911,6 @@ def module(self): Rank-3 free module M over the Integer Ring sage: e.module() is M True - """ return self._fmodule @@ -960,7 +948,6 @@ def dual_basis(self): (0, 1, 0) sage: f[3](e[1]), f[3](e[2]), f[3](e[3]) (0, 0, 1) - """ return self._dual_basis @@ -1035,7 +1022,6 @@ def new_basis(self, change_of_basis, symbol, latex_symbol=None, sage: b.dual_basis() Dual basis (A,B) on the 2-dimensional vector space M over the Rational Field - """ from .free_module_automorphism import FreeModuleAutomorphism if not isinstance(change_of_basis, FreeModuleAutomorphism): diff --git a/src/sage/tensor/modules/free_module_element.py b/src/sage/tensor/modules/free_module_element.py index 3acba1a9fb0..4b49dcab975 100644 --- a/src/sage/tensor/modules/free_module_element.py +++ b/src/sage/tensor/modules/free_module_element.py @@ -191,14 +191,13 @@ class FiniteRankFreeModuleElement(AlternatingContrTensor): module M over the Integer Ring sage: s.display() a∧b = -2 e_0∧e_1 - 6 e_0∧e_2 + 7 e_1∧e_2 - """ def __init__( self, fmodule: FiniteRankFreeModule, - name: Optional[str] = None, - latex_name: Optional[str] = None, + name: str | None = None, + latex_name: str | None = None, ): r""" TESTS:: @@ -208,7 +207,7 @@ def __init__( sage: e = M.basis('e') sage: v = FiniteRankFreeModuleElement(M, name='v') sage: v[e,:] = (-2, 1, 3) - sage: TestSuite(v).run(skip="_test_category") # see below + sage: TestSuite(v).run(skip='_test_category') # see below In the above test suite, _test_category fails because v is not an instance of v.parent().category().element_class. Actually module @@ -218,7 +217,6 @@ def __init__( sage: v1 = M.element_class(M, name='v') sage: v1[e,:] = (-2, 1, 3) sage: TestSuite(v1).run() - """ AlternatingContrTensor.__init__(self, fmodule, 1, name=name, latex_name=latex_name) @@ -233,7 +231,6 @@ def _repr_(self) -> str: sage: e = M.basis('e') sage: M([1,-2,3], name='v') Element v of the Rank-3 free module M over the Integer Ring - """ description = "Element " if self._name is not None: @@ -252,9 +249,7 @@ def _new_comp(self, basis: FreeModuleBasis) -> Components: - ``basis`` -- basis of the free module on which ``self`` is defined - OUTPUT: - - - an instance of :class:`~sage.tensor.modules.comp.Components` + OUTPUT: an instance of :class:`~sage.tensor.modules.comp.Components` EXAMPLES:: @@ -266,7 +261,6 @@ def _new_comp(self, basis: FreeModuleBasis) -> Components: Rank-3 free module M over the Integer Ring sage: type(v._new_comp(e)) - """ fmodule = self._fmodule # the base free module return Components(fmodule._ring, basis, 1, start_index=fmodule._sindex, @@ -285,6 +279,5 @@ def _new_instance(self): Element of the Rank-3 free module M over the Integer Ring sage: v._new_instance().parent() is v.parent() True - """ return self.__class__(self._fmodule) diff --git a/src/sage/tensor/modules/free_module_homset.py b/src/sage/tensor/modules/free_module_homset.py index 5ea2ffb4427..18311ae3373 100644 --- a/src/sage/tensor/modules/free_module_homset.py +++ b/src/sage/tensor/modules/free_module_homset.py @@ -179,7 +179,6 @@ def __init__(self, fmodule1, fmodule2, name, latex_name): ....: latex_name=r'\mathcal{L}(M,N)') sage: latex(H) \mathcal{L}(M,N) - """ Homset.__init__(self, fmodule1, fmodule2) self._name = name @@ -198,7 +197,6 @@ def _latex_(self): '\\mathrm{Hom}\\left(M,N\\right)' sage: latex(H) # indirect doctest \mathrm{Hom}\left(M,N\right) - """ if self._latex_name is None: return r'\mbox{' + str(self) + r'}' @@ -237,7 +235,6 @@ def __call__(self, *args, **kwds): [5 6] sage: a == H([[1,2],[3,4],[5,6]], bases=(e,f)) True - """ from sage.structure.parent import Parent return Parent.__call__(self, *args, **kwds) @@ -262,10 +259,10 @@ def _element_constructor_(self, matrix_rep, bases=None, name=None, by the default bases of each module is assumed. - ``name`` -- (default: ``None``) string; name given to the homomorphism - - ``latex_name`` -- (default: ``None``)string; LaTeX symbol to denote - the homomorphism; if none is provided, ``name`` will be used. - - ``is_identity`` -- (default: ``False``) determines whether the - constructed object is the identity endomorphism; if set to ``True``, + - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote + the homomorphism. If none is provided, ``name`` will be used. + - ``is_identity`` -- boolean (default: ``False``); determines whether the + constructed object is the identity endomorphism. If set to ``True``, then N must be M and the entry ``matrix_rep`` is not used. EXAMPLES: @@ -318,7 +315,6 @@ def _element_constructor_(self, matrix_rep, bases=None, name=None, Generic endomorphism of Rank-3 free module M over the Integer Ring sage: phi_a1 == phi True - """ # Standard construction: return self.element_class(self, matrix_rep, bases=bases, name=name, @@ -343,7 +339,6 @@ def _an_element_(self): [1 1 1] sage: phi == Hom(M,N).an_element() True - """ ring = self.base_ring() m = self.domain().rank() @@ -469,7 +464,6 @@ def __init__(self, fmodule, name, latex_name): ....: latex_name=r'\mathcal{L}(M,N)') sage: latex(H) \mathcal{L}(M,N) - """ FreeModuleHomset.__init__(self, fmodule, fmodule, name, latex_name) self._one = None # to be set by self.one() @@ -495,7 +489,6 @@ def _coerce_map_from_(self, other): sage: End(M)._coerce_map_from_(M.general_linear_group()) True - """ from sage.tensor.modules.tensor_free_module import TensorFreeModule from sage.tensor.modules.free_module_linear_group import \ @@ -531,10 +524,10 @@ def _element_constructor_(self, matrix_rep, bases=None, name=None, by the default bases of each module is assumed. - ``name`` -- (default: ``None``) string; name given to the homomorphism - - ``latex_name`` -- (default: ``None``)string; LaTeX symbol to denote - the homomorphism; if none is provided, ``name`` will be used. - - ``is_identity`` -- (default: ``False``) determines whether the - constructed object is the identity endomorphism; if set to ``True``, + - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote + the homomorphism. If none is provided, ``name`` will be used. + - ``is_identity`` -- boolean (default: ``False``); determines whether the + constructed object is the identity endomorphism. If set to ``True``, then N must be M and the entry ``matrix_rep`` is not used. EXAMPLES: @@ -570,7 +563,6 @@ def _element_constructor_(self, matrix_rep, bases=None, name=None, Generic endomorphism of Rank-3 free module M over the Integer Ring sage: phi_a1 == phi True - """ if isinstance(matrix_rep, FreeModuleTensor): # coercion of a type-(1,1) tensor to an endomorphism @@ -651,7 +643,6 @@ def one(self): sage: GL = M.general_linear_group() sage: M.identity_map() == GL(H.one()) True - """ if self._one is None: self._one = self.element_class(self, [], is_identity=True) diff --git a/src/sage/tensor/modules/free_module_linear_group.py b/src/sage/tensor/modules/free_module_linear_group.py index e9a6ac60655..9893ba32420 100644 --- a/src/sage/tensor/modules/free_module_linear_group.py +++ b/src/sage/tensor/modules/free_module_linear_group.py @@ -35,6 +35,7 @@ from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism + class FreeModuleLinearGroup(UniqueRepresentation, Parent): r""" General linear group of a free module of finite rank over a commutative @@ -258,7 +259,6 @@ class FreeModuleLinearGroup(UniqueRepresentation, Parent): ... TypeError: the Type-(1,1) tensor t_0 on the Rank-3 free module M over the Integer Ring is not invertible - """ Element = FreeModuleAutomorphism @@ -277,7 +277,6 @@ def __init__(self, fmodule): sage: GL.category() Category of groups sage: TestSuite(GL).run() - """ if not isinstance(fmodule, FiniteRankFreeModule): raise TypeError("{} is not a free module of finite rank".format( @@ -357,7 +356,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, Automorphism t of the Rank-2 free module M over the Integer Ring sage: a.matrix(e) == t[e,:] True - """ from sage.tensor.modules.free_module_tensor import FreeModuleTensor from sage.tensor.modules.free_module_morphism import \ @@ -425,7 +423,6 @@ def _an_element_(self): sage: a.matrix(e) [ 1 0] [ 0 -1] - """ resu = self.element_class(self._fmodule) # Make sure that the base module has a default basis @@ -503,7 +500,6 @@ def one(self): sage: GL.one().matrix(f) [1 0] [0 1] - """ resu = self._element_constructor_(name='Id', latex_name=r'\mathrm{Id}') # Initialization of the components (Kronecker delta) in some basis: @@ -529,7 +525,6 @@ def _repr_(self): sage: GL = M.general_linear_group() sage: GL._repr_() 'General linear group of the Rank-2 free module M over the Integer Ring' - """ return "General linear group of the {}".format(self._fmodule) @@ -543,7 +538,6 @@ def _latex_(self): sage: GL = M.general_linear_group() sage: GL._latex_() \mathrm{GL}\left( M \right) - """ from sage.misc.latex import latex return r"\mathrm{GL}\left(" + latex(self._fmodule) + r"\right)" @@ -565,6 +559,5 @@ def base_module(self): Rank-2 free module M over the Integer Ring sage: GL.base_module() is M True - """ return self._fmodule diff --git a/src/sage/tensor/modules/free_module_morphism.py b/src/sage/tensor/modules/free_module_morphism.py index d575601392b..cb119b3eecb 100644 --- a/src/sage/tensor/modules/free_module_morphism.py +++ b/src/sage/tensor/modules/free_module_morphism.py @@ -59,7 +59,7 @@ class FiniteRankFreeModuleMorphism(Morphism): INPUT: - - ``parent`` -- hom-set Hom(M,N) to which the homomorphism belongs + - ``parent`` -- Hom-set Hom(M,N) to which the homomorphism belongs - ``matrix_rep`` -- matrix representation of the homomorphism with respect to the bases ``bases``; this entry can actually be any material from which a matrix of size rank(N)*rank(M) of @@ -71,7 +71,7 @@ class FiniteRankFreeModuleMorphism(Morphism): default bases of each module is assumed. - ``name`` -- (default: ``None``) string; name given to the homomorphism - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the - homomorphism; if ``None``, ``name`` will be used. + homomorphism. If ``None``, ``name`` will be used. EXAMPLES: @@ -268,7 +268,6 @@ def _latex_(self): sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) sage: phi._latex_() '\\mbox{Generic morphism:\n From: Rank-3 free module M over the Integer Ring\n To: Rank-2 free module N over the Integer Ring}' - """ if self._latex_name is None: return r'\mbox{' + str(self) + r'}' @@ -283,9 +282,7 @@ def __eq__(self, other): - ``other`` -- a free module morphism (or 0) - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise EXAMPLES:: @@ -341,7 +338,6 @@ def __eq__(self, other): True sage: phi.__eq__(Hom(M,N).zero()) True - """ if isinstance(other, (int, Integer)): # other should be 0 if other == 0: @@ -391,7 +387,6 @@ def __ne__(self, other): True sage: Hom(M,N).zero().__ne__(0) False - """ return not self == other @@ -435,9 +430,7 @@ def _add_(self, other): - ``other`` -- a free module morphism (same parent as ``self``) - OUTPUT: - - - the homomorphism resulting from the addition of ``self`` and ``other`` + OUTPUT: the homomorphism resulting from the addition of ``self`` and ``other`` EXAMPLES:: @@ -482,7 +475,6 @@ def _add_(self, other): sage: phi._add_(Hom(M,N).zero()) == phi True - """ # No need for consistency checks since self and other are guaranteed # to have the same parents @@ -563,7 +555,6 @@ def _sub_(self, other): True sage: phi._sub_(phi).is_zero() True - """ # No need for consistency checks since self and other are guaranteed # to have the same parents @@ -591,12 +582,10 @@ def _lmul_(self, scalar): INPUT: - ``scalar`` -- element of the ring over which the parent of ``self`` - is a module. - - OUTPUT: + is a module - - the homomorphism resulting from the multiplication of ``self`` by - ``scalar`` + OUTPUT: the homomorphism resulting from the multiplication of ``self`` + by ``scalar`` EXAMPLES:: @@ -628,9 +617,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of ``self`` + OUTPUT: an exact copy of ``self`` EXAMPLES:: @@ -649,7 +636,6 @@ def __pos__(self): True sage: s is phi False - """ resu = self.__class__(self.parent(), 0, is_identity=self._is_identity) # 0 = provisory value @@ -665,9 +651,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the homomorphism `-f`, where `f` is ``self`` + OUTPUT: the homomorphism `-f`, where `f` is ``self`` EXAMPLES:: @@ -687,7 +671,6 @@ def __neg__(self): [-5 -1 -2] sage: s.matrix() == -phi.matrix() True - """ resu = self.__class__(self.parent(), 0) # 0 = provisory value for bases, mat in self._matrices.items(): @@ -712,9 +695,7 @@ def _call_( - ``element`` -- element of the domain of ``self`` - OUTPUT: - - - the image of ``element`` by ``self`` + OUTPUT: the image of ``element`` by ``self`` EXAMPLES: @@ -761,7 +742,6 @@ def _call_( sage: phi(M.zero()) == N.zero() True - """ if self._is_identity: return element @@ -847,7 +827,6 @@ def is_injective(self): True sage: End(N).one().is_injective() True - """ # Some matrix representation is picked at random: matrix_rep = next(iter(self._matrices.values())) @@ -882,7 +861,6 @@ def is_surjective(self): True sage: End(N).one().is_surjective() True - """ if self._is_identity: return True @@ -931,7 +909,6 @@ def is_identity(self): sage: phi.matrix(ep) [1 0] [0 1] - """ if self._is_identity: return True @@ -1089,7 +1066,6 @@ def matrix(self, basis1=None, basis2=None): [ 1 -3 1] [-18 39 -18] [-25 54 -25] - """ from sage.matrix.constructor import matrix fmodule1, fmodule2, basis1, basis2 = self._modules_and_bases(basis1, basis2) @@ -1198,7 +1174,6 @@ def _common_bases(self, other): sage: psi._common_bases(phi) # matrix of phi w.r.t. (ep,f) computed (Basis (ep_0,ep_1,ep_2) on the Rank-3 free module M over the Integer Ring, Basis (f_0,f_1) on the Rank-2 free module N over the Integer Ring) - """ resu = None for bases in self._matrices: @@ -1306,7 +1281,7 @@ class FiniteRankFreeModuleEndomorphism(FiniteRankFreeModuleMorphism): INPUT: - - ``parent`` -- hom-set Hom(M,M) to which the endomorphism belongs + - ``parent`` -- Hom-set Hom(M,M) to which the endomorphism belongs - ``matrix_rep`` -- matrix representation of the endomorphism with respect to the basis ``bases``; this entry can actually be any material from which a matrix of size rank(N)*rank(M) of @@ -1318,9 +1293,9 @@ class FiniteRankFreeModuleEndomorphism(FiniteRankFreeModuleMorphism): the default basis of `M` is used for both. - ``name`` -- (default: ``None``) string; name given to the endomorphism - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the - endomorphism; if ``None``, ``name`` will be used. - - ``is_identity`` -- (default: ``False``) determines whether the - constructed object is the identity endomorphism; if set to ``True``, + endomorphism. If ``None``, ``name`` will be used. + - ``is_identity`` -- boolean (default: ``False``); determines whether the + constructed object is the identity endomorphism. If set to ``True``, then the entry ``matrix_rep`` is not used. EXAMPLES: @@ -1602,6 +1577,5 @@ def trace(self): sage: id = M.identity_map() sage: id.trace() 3 - """ return self._some_matrix().trace diff --git a/src/sage/tensor/modules/free_module_tensor.py b/src/sage/tensor/modules/free_module_tensor.py index 5dbc661fa53..94974e6059b 100644 --- a/src/sage/tensor/modules/free_module_tensor.py +++ b/src/sage/tensor/modules/free_module_tensor.py @@ -145,7 +145,7 @@ class being: sage: type(t.comp(e)) -Only non-zero components are actually stored, in the dictionary :attr:`_comp` +Only nonzero components are actually stored, in the dictionary :attr:`_comp` of class :class:`~sage.tensor.modules.comp.Components`, whose keys are the indices:: @@ -193,7 +193,7 @@ class being: # ***************************************************************************** from __future__ import annotations -from typing import TYPE_CHECKING, Dict, Optional, Union +from typing import TYPE_CHECKING, Optional, Union from sage.parallel.decorate import parallel from sage.parallel.parallelism import Parallelism @@ -263,7 +263,6 @@ class FreeModuleTensor(ModuleElementWithMutability): Rank-3 free module M over the Integer Ring sage: t.parent() is M.tensor_module(1,1) True - """ _fmodule: FiniteRankFreeModule @@ -285,7 +284,7 @@ def __init__( sage: e = M.basis('e') sage: t = FreeModuleTensor(M, (2,1), name='t', latex_name=r'\tau', sym=(0,1)) sage: t[e,0,0,0] = -3 - sage: TestSuite(t).run(skip="_test_category") # see below + sage: TestSuite(t).run(skip='_test_category') # see below In the above test suite, _test_category fails because t is not an instance of t.parent().category().element_class. Actually tensors @@ -297,7 +296,6 @@ def __init__( ....: sym=(0,1)) sage: t1[e,0,0,0] = -3 sage: TestSuite(t1).run() - """ if parent is None: parent = fmodule.tensor_module(*tensor_type) @@ -312,7 +310,7 @@ def __init__( self._latex_name = self._name else: self._latex_name = latex_name - self._components: Dict[FreeModuleBasis, Components] = {} # dict. of the sets of components on various + self._components: dict[FreeModuleBasis, Components] = {} # dict. of the sets of components on various # bases, with the bases as keys (initially empty) # Treatment of symmetry declarations: @@ -342,7 +340,7 @@ def __bool__(self): False sage: t == 0 True - sage: t[e,1,0,2] = 4 # setting a non-zero component in basis e + sage: t[e,1,0,2] = 4 # setting a nonzero component in basis e sage: t.display() 4 e_1⊗e_0⊗e^2 sage: bool(t) @@ -376,7 +374,6 @@ def _repr_(self): sage: t = M.tensor((2,1), name='t') sage: t Type-(2,1) tensor t on the Rank-3 free module M over the Integer Ring - """ # Special cases if self._tensor_type == (0,2) and self._sym == ((0,1),): @@ -410,7 +407,6 @@ def _latex_(self): sage: t = M.tensor((2,1)) # unnamed tensor sage: t._latex_() '\\mbox{Type-(2,1) tensor on the Rank-3 free module M over the Integer Ring}' - """ if self._latex_name is None: return r'\mbox{' + str(self) + r'}' @@ -418,27 +414,25 @@ def _latex_(self): def _init_derived(self): r""" - Initialize the derived quantities + Initialize the derived quantities. EXAMPLES:: sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: t = M.tensor((2,1), name='t') sage: t._init_derived() - """ pass # no derived quantities def _del_derived(self): r""" - Delete the derived quantities + Delete the derived quantities. EXAMPLES:: sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: t = M.tensor((2,1), name='t') sage: t._del_derived() - """ pass # no derived quantities @@ -461,7 +455,6 @@ def tensor_type(self): sage: t = M.tensor((2,1)) sage: t.tensor_type() (2, 1) - """ return self._tensor_type @@ -482,7 +475,6 @@ def tensor_rank(self): sage: t = M.tensor((2,1)) sage: t.tensor_rank() 3 - """ return self._tensor_rank @@ -505,7 +497,6 @@ def base_module(self): Rank-3 free module M over the Integer Ring sage: t.base_module() is M True - """ return self._fmodule @@ -530,7 +521,6 @@ def symmetries(self): sage: t = M.tensor((4,0), name='T', sym=(0,1), antisym=(2,3)) sage: t.symmetries() symmetry: (0, 1); antisymmetry: (2, 3) - """ if len(self._sym) == 0: s = "no symmetry; " @@ -567,7 +557,6 @@ def _preparse_display(self, basis=None, format_spec=None): (Basis (e_0,e_1) on the Rank-2 free module M over the Integer Ring, 10) sage: v._preparse_display(format_spec=10) (Basis (e_0,e_1) on the Rank-2 free module M over the Integer Ring, 10) - """ if basis is None: basis = self._fmodule._def_basis @@ -685,7 +674,6 @@ def display(self, basis=None, format_spec=None): sage: t = SR.var('t', domain='real') sage: (t*e[0]).display() t e_0 - """ from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_otimes @@ -796,9 +784,9 @@ def display_comp(self, basis=None, format_spec=None, symbol=None, - ``index_latex_labels`` -- (default: ``None``) list of strings representing the LaTeX labels of each of the individual indices; if ``None``, integers labels are used - - ``only_nonzero`` -- (default: ``True``) boolean; if ``True``, only + - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only nonzero components are displayed - - ``only_nonredundant`` -- (default: ``False``) boolean; if ``True``, + - ``only_nonredundant`` -- boolean (default: ``False``); if ``True``, only nonredundant components are displayed in case of symmetries EXAMPLES: @@ -875,7 +863,6 @@ def display_comp(self, basis=None, format_spec=None, symbol=None, T^21_2 = 3/4 T^22_1 = 7/24 T^22_2 = 23/24 - """ if basis is None: basis = self._fmodule._def_basis @@ -923,7 +910,6 @@ def set_name(self, name: Optional[str] = None, latex_name: Optional[str] = None) Type-(2,1) tensor t on the Rank-3 free module M over the Integer Ring sage: latex(t) \tau - """ if name is not None: self._name = name @@ -945,7 +931,6 @@ def _new_instance(self): Type-(2,1) tensor on the Rank-3 free module M over the Integer Ring sage: t._new_instance().parent() is t.parent() True - """ return self.__class__(self._fmodule, self._tensor_type, sym=self._sym, antisym=self._antisym) @@ -981,7 +966,6 @@ def _new_comp(self, basis): 3-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring, with symmetry on the index positions (0, 1) - """ fmodule = self._fmodule # the base free module if not self._sym and not self._antisym: @@ -1071,7 +1055,6 @@ class :class:`~sage.tensor.modules.comp.Components` [ 0 0 0] [ 0 2 0] [-3 0 0] - """ fmodule = self._fmodule if basis is None: @@ -1125,7 +1108,7 @@ class :class:`~sage.tensor.modules.comp.Components` if nproc != 1: # Parallel computation lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] - ind_list = [ind for ind in new_comp.non_redundant_index_generator()] + ind_list = list(new_comp.non_redundant_index_generator()) ind_step = max(1, int(len(ind_list)/nproc/2)) local_list = lol(ind_list, ind_step) # list of input parameters @@ -1232,7 +1215,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such sage: sorted(t._components, key=repr) [Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring, Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring] - """ if basis is None: basis = self._fmodule._def_basis @@ -1311,7 +1293,6 @@ class :class:`~sage.tensor.modules.comp.Components`; if such Traceback (most recent call last): ... ValueError: the components of an immutable element cannot be changed - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1371,7 +1352,6 @@ class :class:`~sage.tensor.modules.comp.Components`; t = 4 f_0⊗f^1 sage: t.display(e) t = -3 e_0⊗e^1 + 2 e_1⊗e^2 - """ if basis is None: basis = self._fmodule._def_basis @@ -1448,7 +1428,6 @@ class :class:`~sage.tensor.modules.comp.Components`; Traceback (most recent call last): ... ValueError: the components of an immutable element cannot be changed - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1490,7 +1469,6 @@ def del_other_comp(self, basis=None): sage: u.del_other_comp() # default argument: basis = e sage: list(u._components) [Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring] - """ if basis is None: basis = self._fmodule._def_basis @@ -1539,7 +1517,6 @@ def __getitem__(self, args) -> Components: True sage: v.__getitem__((e, slice(None))) [3, -5, 2] - """ if isinstance(args, str): # tensor with specified indices return TensorWithIndices(self, args).update() @@ -1593,7 +1570,6 @@ def __setitem__(self, args, value): [ 1 -2 3] [-4 5 -6] [ 7 -8 9] - """ if isinstance(args, list): # case of [[...]] syntax if isinstance(args[0], (int, Integer, slice, tuple)): @@ -1650,7 +1626,6 @@ def copy_from(self, other): [ 0 0 2] sage: s == t False - """ if self.is_immutable(): raise ValueError("the components of an immutable element " @@ -1765,7 +1740,6 @@ def common_basis(self, other): sage: sorted(v._components, key=repr) [Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring, Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring] - """ # Compatibility checks: if not isinstance(other, FreeModuleTensor): @@ -1859,7 +1833,6 @@ def pick_a_basis(self): sage: t.set_comp(f)[2,1] = -4 # the components in basis e not erased sage: t.pick_a_basis() Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring - """ if self._fmodule._def_basis in self._components: return self._fmodule._def_basis # the default basis is privileged @@ -1875,9 +1848,7 @@ def __eq__(self, other): - ``other`` -- a tensor or 0 - OUTPUT: - - - ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise + OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise EXAMPLES:: @@ -1905,7 +1876,6 @@ def __eq__(self, other): sage: a[0,1] = 7 sage: t.__eq__(a) True - """ if self is other: return True @@ -1960,7 +1930,6 @@ def __ne__(self, other): sage: t[0,1] = 7 sage: t.__ne__(a) False - """ return not self == other @@ -1968,9 +1937,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of ``self`` + OUTPUT: an exact copy of ``self`` EXAMPLES:: @@ -1986,7 +1953,6 @@ def __pos__(self): True sage: p is t False - """ result = self._new_instance() for basis in self._components: @@ -2001,9 +1967,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - the tensor `-T`, where `T` is ``self`` + OUTPUT: the tensor `-T`, where `T` is ``self`` EXAMPLES:: @@ -2019,7 +1983,6 @@ def __neg__(self): -t = -7 e_0⊗e_1 + 4 e_1⊗e_2 sage: a == -t True - """ result = self._new_instance() for basis in self._components: @@ -2040,9 +2003,7 @@ def _add_(self, other): - ``other`` -- a tensor, of the same type as ``self`` - OUTPUT: - - - the tensor resulting from the addition of ``self`` and ``other`` + OUTPUT: the tensor resulting from the addition of ``self`` and ``other`` EXAMPLES:: @@ -2061,7 +2022,6 @@ def _add_(self, other): True sage: a._add_(a) == 2*a True - """ # No need for consistency check since self and other are guaranteed # to belong to the same tensor module @@ -2091,9 +2051,7 @@ def _sub_(self, other): - ``other`` -- a tensor, of the same type as ``self`` - OUTPUT: - - - the tensor resulting from the subtraction of ``other`` from ``self`` + OUTPUT: the tensor resulting from the subtraction of ``other`` from ``self`` EXAMPLES:: @@ -2123,7 +2081,6 @@ def _sub_(self, other): sage: t = M.tensor((2,1), name='t') sage: t == t True - """ # No need for consistency check since self and other are guaranteed # to belong to the same tensor module @@ -2170,7 +2127,6 @@ def _rmul_(self, other): True sage: a._rmul_(-1) == -a True - """ #!# The following test is probably not necessary: if isinstance(other, FreeModuleTensor): @@ -2211,7 +2167,6 @@ def __mul__(self, other): sage: s[:] [[[[0, 12], [-12, 0]], [[0, 0], [0, 0]]], [[[0, -6], [6, 0]], [[0, 15], [-15, 0]]]] - """ from sage.typeset.unicode_characters import unicode_otimes from .format_utilities import format_mul_txt, format_mul_latex @@ -2259,7 +2214,6 @@ def __truediv__(self, other): True sage: s == a/4 True - """ result = self._new_instance() for basis in self._components: @@ -2319,7 +2273,6 @@ def __call__(self, *args) -> Expression: 0 sage: v.__call__(b) -7 - """ # Consistency checks: p = len(args) @@ -2579,7 +2532,6 @@ def trace( True sage: t['^k_..k'] == t.trace(0,3) True - """ if using is not None: if self.tensor_type() != (0, 2): @@ -2799,7 +2751,6 @@ def contract(self, *args): [-204 170 85] sage: s == a['^.k_l']*b['^l_k.'] # the same thing in index notation True - """ # # Treatment of the input @@ -3068,7 +3019,6 @@ def symmetrize(self, *pos, **kwargs): sage: t['^{i}_{(jk)}'] == t.symmetrize(1,2) True - """ if not pos: pos = range(self._tensor_rank) @@ -3308,7 +3258,6 @@ def antisymmetrize(self, *pos, **kwargs): sage: t['i_[jk]'] == t.antisymmetrize(1,2) True - """ if not pos: pos = range(self._tensor_rank) diff --git a/src/sage/tensor/modules/tensor_free_module.py b/src/sage/tensor/modules/tensor_free_module.py index e12b0f0b756..8a02751c471 100644 --- a/src/sage/tensor/modules/tensor_free_module.py +++ b/src/sage/tensor/modules/tensor_free_module.py @@ -70,6 +70,7 @@ from .tensor_free_submodule_basis import TensorFreeSubmoduleBasis_sym + class TensorFreeModule(ReflexiveModule_tensor, FiniteRankFreeModule_abstract): r""" Class for the free modules over a commutative ring `R` that are @@ -159,7 +160,7 @@ class TensorFreeModule(ReflexiveModule_tensor, FiniteRankFreeModule_abstract): sage: T(0) is T.zero() True - while non-zero elements are constructed by providing their components in + while nonzero elements are constructed by providing their components in a given basis:: sage: e @@ -333,7 +334,6 @@ class TensorFreeModule(ReflexiveModule_tensor, FiniteRankFreeModule_abstract): sage: GL.has_coerce_map_from(T11) False - """ Element = FreeModuleTensor @@ -345,7 +345,6 @@ def __init__(self, fmodule, tensor_type, name=None, latex_name=None, category=No sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: T = M.tensor_module(2, 3) sage: TestSuite(T).run() - """ self._fmodule = fmodule self._tensor_type = tuple(tensor_type) @@ -393,7 +392,6 @@ def _element_constructor_(self, comp=[], basis=None, name=None, space M over the Rational Field sage: t.parent() is T True - """ from sage.rings.integer import Integer if isinstance(comp, (int, Integer)) and comp == 0: @@ -501,7 +499,6 @@ def zero(self): sage: T11.zero() is T11(0) True - """ resu = self._element_constructor_(name='zero', latex_name='0') for basis in self._fmodule._known_bases: @@ -600,7 +597,6 @@ def _coerce_map_from_(self, other): sage: Sym01M = M.tensor_module(2, 0, sym=((0, 1))) sage: M.tensor_module(2,0)._coerce_map_from_(Sym01M) True - """ from .free_module_homset import FreeModuleHomset from .ext_pow_free_module import (ExtPowerFreeModule, @@ -645,7 +641,6 @@ def _repr_(self): sage: M.tensor_module(1,1) Free module of type-(1,1) tensors on the 2-dimensional vector space M over the Rational Field - """ description = "Free module of type-({},{}) tensors on the {}".format( self._tensor_type[0], self._tensor_type[1], self._fmodule) @@ -670,7 +665,6 @@ def base_module(self): Rank-3 free module M over the Integer Ring sage: T.base_module() is M True - """ return self._fmodule @@ -689,7 +683,6 @@ def tensor_type(self): sage: T = M.tensor_module(1,2) sage: T.tensor_type() (1, 2) - """ return self._tensor_type @@ -759,7 +752,6 @@ def basis(self, symbol, latex_symbol=None, from_family=None, f_0⊗f_0 f_0⊗f_1 + f_1⊗f_0 f_1⊗f_1 - """ return TensorFreeSubmoduleBasis_sym(self, symbol=symbol, latex_symbol=latex_symbol, indices=indices, latex_indices=latex_indices, @@ -781,7 +773,6 @@ def _basis_sym(self): sage: T = M.tensor_module(1,1) sage: c = T._basis_sym(); c 2-indices components w.r.t. (0, 1, 2) - """ frame = tuple(self.base_module().irange()) tensor = self.ambient()() diff --git a/src/sage/tensor/modules/tensor_free_submodule.py b/src/sage/tensor/modules/tensor_free_submodule.py index 97d0446bc55..576d411fd8c 100644 --- a/src/sage/tensor/modules/tensor_free_submodule.py +++ b/src/sage/tensor/modules/tensor_free_submodule.py @@ -95,7 +95,6 @@ class TensorFreeSubmodule_sym(TensorFreeModule): 'T^{2,3}(M)⊗T^{6,7}(M*)⊗Sym^{0,1}(M)⊗ASym^{4,5}(M*)' sage: latex(T) T^{\{2,3\}}(M) \otimes T^{\{6,7\}}(M^*) \otimes \mathrm{Sym}^{\{0,1\}}(M) \otimes \mathrm{ASym}^{\{4,5\}}(M^*) - """ def __init__(self, fmodule, tensor_type, name=None, latex_name=None, sym=None, antisym=None, *, category=None, ambient=None): @@ -211,7 +210,6 @@ def _basis_sym(self): Free module of fully symmetric type-(2,0) tensors on the Rank-3 free module M over the Integer Ring sage: c = Sym2M._basis_sym(); c Fully symmetric 2-indices components w.r.t. (0, 1, 2) - """ frame = tuple(self.base_module().irange()) # Need to call _element_constructor_ explicitly, or the passed arguments are dropped @@ -228,7 +226,6 @@ def _repr_(self): sage: Sym2M = M.tensor_module(2, 0, sym=range(2)); Sym2M Free module of fully symmetric type-(2,0) tensors on the Rank-3 free module M over the Integer Ring - """ prefix, suffix = self._basis_sym()._repr_symmetry() return "Free module of {}type-({},{}) tensors on the {}{}".format( @@ -240,7 +237,7 @@ def _is_symmetry_coarsening_of(self, coarser_comp, finer_comp): INPUT: - - ``coarser_comp``, ``finer_comp``: :class:`~sage.tensor.modules.comp.Components` + - ``coarser_comp``, ``finer_comp`` -- :class:`~sage.tensor.modules.comp.Components` EXAMPLES:: @@ -386,7 +383,6 @@ def is_submodule(self, other): False sage: all(S.is_submodule(T60M) for S in (Sym0123x45M, Sym012x345M, Sym012345M)) True - """ if super().is_submodule(other): return True diff --git a/src/sage/tensor/modules/tensor_free_submodule_basis.py b/src/sage/tensor/modules/tensor_free_submodule_basis.py index 6c88b05af23..8cf2602e4ab 100644 --- a/src/sage/tensor/modules/tensor_free_submodule_basis.py +++ b/src/sage/tensor/modules/tensor_free_submodule_basis.py @@ -37,7 +37,6 @@ class TensorFreeSubmoduleBasis_sym(Basis_abstract): e_2⊗e^0 e_2⊗e^1 e_2⊗e^2 - """ def __init__(self, tensor_module, symbol, latex_symbol=None, indices=None, @@ -132,7 +131,6 @@ def __getitem__(self, index): e_1⊗e_1 sage: eSym2M[1, 2].display() e_1⊗e_2 + e_2⊗e_1 - """ tensor_module = self._fmodule base_module_basis = self._base_module_basis diff --git a/src/sage/tensor/modules/tensor_with_indices.py b/src/sage/tensor/modules/tensor_with_indices.py index 97e46cb9bd1..e65277935a7 100644 --- a/src/sage/tensor/modules/tensor_with_indices.py +++ b/src/sage/tensor/modules/tensor_with_indices.py @@ -27,6 +27,7 @@ # The dot is special syntax for unnamed index positions. _alph_or_dot_pattern = r"([.]|[^\d\W_])" + class TensorWithIndices(SageObject): r""" Index notation for tensors. @@ -224,7 +225,7 @@ class TensorWithIndices(SageObject): a^μξ Conventions are checked and non acceptable indices raise - :class:`ValueError`, for instance:: + :exc:`ValueError`, for instance:: sage: a['([..])'] # nested symmetries Traceback (most recent call last): @@ -246,7 +247,6 @@ class TensorWithIndices(SageObject): Traceback (most recent call last): ... ValueError: index conventions not satisfied - """ @staticmethod @@ -257,19 +257,19 @@ def _parse_indices(indices, tensor_type=None, allow_contraction=True, indices. Parse ``indices`` checking usual conventions on repeating indices, - wildcard, balanced parentheses/brackets and raises a :class:`ValueError` + wildcard, balanced parentheses/brackets and raises a :exc:`ValueError` if not. Return a couple contravariant/covariant indices. INPUT: - - ``indices`` -- a string of index notation - - ``tensor_type`` -- (default : ``None``) a valid tensor type - (a couple of non-negative integers). If not ``None``, the indices + - ``indices`` -- string of index notation + - ``tensor_type`` -- (default: ``None``) a valid tensor type + (a couple of nonnegative integers). If not ``None``, the indices are checked to have the correct type. - - ``allow_contraction`` -- (default : ``True``) Determines if - repeated indices are allowed in the index notation. - - ``allow_symmetries`` -- (default : ``True``) Determines if - symmetries ()/[] are allowed in the index notation. + - ``allow_contraction`` -- (default: ``True``) determines if + repeated indices are allowed in the index notation + - ``allow_symmetries`` -- (default: ``True``) determines if + symmetries ()/[] are allowed in the index notation OUTPUT: @@ -329,7 +329,6 @@ def _parse_indices(indices, tensor_type=None, allow_contraction=True, Traceback (most recent call last): ... IndexError: no symmetry allowed - """ # Suppress all '{' and '}' coming from LaTeX notations: indices = indices.replace('{','').replace('}','') @@ -395,7 +394,7 @@ def __init__(self, tensor, indices): We need to skip the pickling test because we can't check equality unless the tensor was defined w.r.t. a basis:: - sage: TestSuite(ti).run(skip="_test_pickling") + sage: TestSuite(ti).run(skip='_test_pickling') :: @@ -405,7 +404,6 @@ def __init__(self, tensor, indices): ....: [[19,-20,-21], [-22,23,24], [25,26,-27]]] sage: ti = TensorWithIndices(t, 'ab_c') sage: TestSuite(ti).run() - """ self._tensor = tensor # may be changed below self._changed = False # indicates whether self contains an altered @@ -504,7 +502,6 @@ def _repr_(self): sage: ti = TensorWithIndices(t, '_{ij}') sage: ti._repr_() 't_ij' - """ name = 'X' if hasattr(self._tensor, '_name'): @@ -542,7 +539,6 @@ def update(self): scalar sage: a_ind.update() 15 - """ if self._changed: return self._tensor @@ -568,7 +564,6 @@ def __eq__(self, other): Traceback (most recent call last): ... ValueError: no common basis for the comparison - """ if not isinstance(other, TensorWithIndices): return False @@ -590,7 +585,6 @@ def __ne__(self, other): False sage: ti != TensorWithIndices(t, 'ac_b') True - """ return not self == other @@ -673,7 +667,6 @@ def __rmul__(self, other): X^ij_k sage: s._tensor == 3*a True - """ return TensorWithIndices(other*self._tensor, self._con + '_' + self._cov) @@ -685,7 +678,7 @@ def __add__(self, other): The underlying tensor of the output is the sum of the underlying tensor of ``self`` with the underlying tensor of ``other`` whose entries have be permuted to respect Einstein summation usual conventions. The - indices names of the output are those of self. + indices names of the output are those of ``self``. TESTS:: @@ -701,7 +694,6 @@ def __add__(self, other): sage: 1/4*(T["ijkl_abcd"] + T["jikl_abcd"] + T["ijkl_abdc"]\ + T["jikl_abdc"]) == T["(..).._..(..)"]["ijkl_abcd"] True - """ # Check tensor types are compatible if self._tensor.tensor_type() != other._tensor.tensor_type(): @@ -744,7 +736,7 @@ def __sub__(self, other): The underlying tensor of the output is the underlying tensor of ``self`` minus the underlying tensor of ``other`` whose entries have be permuted to respect Einstein summation usual conventions. The - indices names of the output are those of self. + indices names of the output are those of ``self``. EXAMPLES:: @@ -780,7 +772,6 @@ def __sub__(self, other): sage: 1/4*(T["ijkl_abcd"]-T["jikl_abcd"] - T["ijkl_abdc"]\ + T["jikl_abdc"] ) == T["[..].._..[..]"]["ijkl_abcd"] True - """ return self + (-other) @@ -823,7 +814,6 @@ def __getitem__(self, args): [1 3 5] [3 5 7] [5 7 9] - """ if isinstance(args, str): result = +self @@ -858,7 +848,6 @@ def __setitem__(self, args, value): sage: b["ij"] = a["ji"] sage: b[:] == a[:].transpose() True - """ if isinstance(args, str): if not isinstance(value,TensorWithIndices): @@ -1012,9 +1001,7 @@ def __pos__(self): r""" Unary plus operator. - OUTPUT: - - - an exact copy of ``self`` + OUTPUT: an exact copy of ``self`` EXAMPLES:: @@ -1028,7 +1015,6 @@ def __pos__(self): +a^ij_k sage: s._tensor == a True - """ return TensorWithIndices(+self._tensor, self._con + '_' + self._cov) @@ -1037,9 +1023,7 @@ def __neg__(self): r""" Unary minus operator. - OUTPUT: - - - negative of ``self`` + OUTPUT: negative of ``self`` EXAMPLES:: @@ -1053,7 +1037,6 @@ def __neg__(self): -a^ij_k sage: s._tensor == -a True - """ return TensorWithIndices(-self._tensor, self._con + '_' + self._cov) diff --git a/src/sage/tests/arxiv_0812_2725.py b/src/sage/tests/arxiv_0812_2725.py index cfeb7321e71..9bacb5c18aa 100644 --- a/src/sage/tests/arxiv_0812_2725.py +++ b/src/sage/tests/arxiv_0812_2725.py @@ -44,7 +44,7 @@ def CompleteMatchings(n): INPUT: - n -- nonnegative integer + - ``n`` -- nonnegative integer OUTPUT: @@ -85,8 +85,8 @@ def matchingsset(L): INPUT: - L -- a sequence. Lists, tuples, et cetera; anything that - supports len() and slicing should work. + - ``L`` -- a sequence. Lists, tuples, et cetera; anything that + supports ``len()`` and slicing should work. OUTPUT: @@ -121,10 +121,10 @@ def dcrossing(m_): INPUT: - m -- a matching or set partition, as a list of 2-element tuples - representing the edges. You'll need to call setp_to_edges() on - the objects returned by SetPartitions() to put them into the - proper format. + - ``m`` -- a matching or set partition, as a list of 2-element tuples + representing the edges. You'll need to call ``setp_to_edges()`` on + the objects returned by ``SetPartitions()`` to put them into the + proper format. OUTPUT: @@ -188,7 +188,7 @@ def setp_to_edges(p): INPUT: - p -- a Sage set partition. + - ``p`` -- a Sage set partition OUTPUT: @@ -213,7 +213,7 @@ def dcrossvec_setp(n): INPUT: - n -- a nonnegative integer. + - ``n`` -- nonnegative integer OUTPUT: @@ -255,7 +255,7 @@ def dcrossvec_cm(n): INPUT: - n -- a nonnegative integer. + - ``n`` -- nonnegative integer OUTPUT: @@ -310,10 +310,10 @@ def tablecolumn(n, k): INPUT: - n -- positive integer. + - ``n`` -- positive integer - k -- integer for which table you want: Table 1 is complete - matchings, Table 2 is set partitions. + - ``k`` -- integer for which table you want: Table 1 is complete + matchings, Table 2 is set partitions OUTPUT: diff --git a/src/sage/tests/benchmark.py b/src/sage/tests/benchmark.py index 8fcc8772b40..8a481a2b959 100644 --- a/src/sage/tests/benchmark.py +++ b/src/sage/tests/benchmark.py @@ -81,7 +81,6 @@ class Benchmark: sage.tests.benchmark.Benchmark instance System min avg max trials cpu or wall * python ... - """ def run(self, systems=None, timeout=60, trials=1, sort=False, optional=False): """ @@ -90,15 +89,14 @@ def run(self, systems=None, timeout=60, trials=1, sort=False, optional=False): INPUT: - - systems -- optional list of strings of which systems to run tests on; + - ``systems`` -- (optional) list of strings of which systems to run tests on; if ``None``, runs the standard systems - - timeout -- optional integer (default 60); how long (in seconds) + - ``timeout`` -- integer (default: 60); how long (in seconds) to run each test for - - trials -- optional integer (default 1); number of trials - - sort -- optional boolean (default ``False``); whether to sort - system names - - optional -- optional boolean (default ``False``); - if systems is ``None``, whether to test optional systems + - ``trials`` -- integer (default: 1); number of trials + - ``sort`` -- boolean (default: ``False``); whether to sort system names + - ``optional`` -- boolean (default: ``False``); if systems is ``None``, + whether to test optional systems EXAMPLES:: @@ -108,7 +106,6 @@ def run(self, systems=None, timeout=60, trials=1, sort=False, optional=False): System min avg max trials cpu or wall * sage ... * gp ... - """ if sort: systems.sort() @@ -219,7 +216,6 @@ def magma(self): sage: B = Divpoly(3) sage: isinstance(B.magma(), float) # optional - magma True - """ n = self.__n t = magma.cputime() @@ -278,7 +274,6 @@ def maple(self): sage: B = PolySquare(3, QQ) sage: isinstance(B.maple()[1], float) # optional - maple True - """ R = self.__R if not (R == ZZ or R == QQ): @@ -312,7 +307,6 @@ def sage(self): sage: B = MPolynomialPower() sage: isinstance(B.sage()[1], float) True - """ R = PolynomialRing(self.base, self.nvars, 'x') z = sum(R.gens()) @@ -335,7 +329,6 @@ def macaulay2(self): sage: B = MPolynomialPower() sage: isinstance(B.macaulay2()[1], float) # optional - macaulay2 True - """ R = PolynomialRing(self.base, self.nvars, 'x') z = macaulay2(sum(R.gens())) @@ -353,7 +346,6 @@ def maxima(self): sage: B = MPolynomialPower() sage: isinstance(B.maxima()[1], float) True - """ R = PolynomialRing(self.base, self.nvars, 'x') z = maxima(str(sum(R.gens()))) @@ -371,7 +363,6 @@ def maple(self): sage: B = MPolynomialPower() sage: isinstance(B.maple()[1], float) # optional - maple True - """ R = PolynomialRing(self.base, self.nvars, 'x') z = maple(str(sum(R.gens()))) @@ -389,7 +380,6 @@ def mathematica(self): sage: B = MPolynomialPower() sage: isinstance(B.mathematica()[1], float) # optional - mathematica True - """ R = PolynomialRing(self.base, self.nvars, 'x') z = mathematica(str(sum(R.gens()))) @@ -416,7 +406,6 @@ def magma(self): sage: B = MPolynomialPower() sage: isinstance(B.magma(), float) # optional - magma True - """ R = magma.PolynomialRing(self.base, self.nvars) z = R.gen(1) @@ -488,7 +477,6 @@ def mathematica(self): sage: B = MPolynomialMult() sage: isinstance(B.mathematica()[1], float) # optional - mathematica True - """ R = PolynomialRing(self.base, self.nvars, 'x') k = self.nvars // 2 @@ -517,7 +505,6 @@ def sage(self): sage: B = MPolynomialMult() sage: isinstance(B.sage()[1], float) True - """ R = PolynomialRing(self.base, self.nvars, 'x') k = self.nvars // 2 @@ -563,7 +550,6 @@ def magma(self): sage: B = MPolynomialMult() sage: isinstance(B.magma(), float) # optional - magma True - """ R = magma.PolynomialRing(self.base, self.nvars) z0 = R.gen(1) @@ -717,7 +703,6 @@ def sage(self): sage: B = MPolynomialMult2() sage: isinstance(B.sage()[1], float) True - """ R = PolynomialRing(self.base, self.nvars, 'x') k = self.nvars // 2 @@ -787,7 +772,6 @@ def sage(self): sage: B = CharPolyTp() sage: isinstance(B.sage(), float) True - """ m = self.matrix() t = cputime() @@ -804,7 +788,6 @@ def gp(self): sage: B = CharPolyTp() sage: isinstance(B.gp(), float) True - """ m = gp(self.matrix()) gp.eval('gettime') @@ -821,7 +804,6 @@ def pari(self): sage: B = CharPolyTp() sage: isinstance(B.pari(), float) True - """ m = pari(self.matrix()) t = cputime() @@ -838,7 +820,6 @@ def magma(self): sage: B = CharPolyTp() sage: isinstance(B.magma(), float) # optional - magma True - """ m = magma(self.matrix()) t = magma.cputime() @@ -928,7 +909,6 @@ def sage(self): sage: B = SquareInts() sage: isinstance(B.sage(), float) True - """ n = Integer(self.base)**self.__ndigits t = cputime() @@ -993,7 +973,6 @@ def python(self): sage: B = SquareInts() sage: isinstance(B.python(), float) True - """ n = self.base**self.__ndigits t = cputime() @@ -1143,7 +1122,6 @@ def sage(self): sage: B = Factorial(10) sage: isinstance(B.sage(), float) True - """ t = cputime() factorial(self.__n) @@ -1174,7 +1152,6 @@ def maple(self): sage: B = Factorial(10) sage: isinstance(B.maple()[1], float) # optional - maple True - """ n = maple(self.__n) t = walltime() @@ -1212,7 +1189,6 @@ def sage(self): sage: B = Fibonacci(10) sage: isinstance(B.sage(), float) True - """ t = cputime() fibonacci(self.__n) @@ -1464,7 +1440,6 @@ def sage(self): sage: B = ModularSymbols1(11) sage: isinstance(B.sage(), float) True - """ t = cputime() ModularSymbols(self.__N, self.__k) @@ -1601,7 +1576,6 @@ def magma(self): sage: B = EllipticCurvePointMul(11) sage: isinstance(B.magma(), float) # optional - magma True - """ E = magma.EllipticCurve('[0, 0, 1, -1, 0]') P = E('[0,0]') @@ -1659,7 +1633,6 @@ def sage(self): sage: B = EllipticCurveMW([1,2,3,4,5]) sage: isinstance(B.sage()[1], float) True - """ E = EllipticCurve(self.ainvs) t = walltime() @@ -1676,7 +1649,6 @@ def magma(self): sage: B = EllipticCurveMW([1,2,3,4,5]) sage: isinstance(B.magma(), float) # optional - magma True - """ E = magma.EllipticCurve(str(self.ainvs)) t = magma.cputime() @@ -1883,7 +1855,7 @@ def mpoly(): def mpoly_all(include_maple=False): """ - Runs benchmarks for multipoly arithmetic on all systems (except + Run benchmarks for multipoly arithmetic on all systems (except Maxima, since it is very very slow). You must have mathematica, maple, and magma. @@ -1903,7 +1875,6 @@ def mpoly_all(include_maple=False): ...System min avg max trials cpu or wall ... * sage... - """ systems = ['sage', 'magma', 'mathematica', 'macaulay2'] if include_maple: diff --git a/src/sage/tests/books/__init__.py b/src/sage/tests/books/__init__.py index e69de29bb2d..1b10e244496 100644 --- a/src/sage/tests/books/__init__.py +++ b/src/sage/tests/books/__init__.py @@ -0,0 +1 @@ +# Here so that cython creates the correct module name diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py index 49fb2b34db5..7b6587ecaf6 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py @@ -262,7 +262,7 @@ sage: r3 = RIF(sqrt(3)); r3 1.732050807568877? - sage: print(r3.str(style="brackets")) + sage: print(r3.str(style='brackets')) [1.7320508075688769 .. 1.7320508075688775] Sage example in ./float.tex, line 1602:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py index b66c6d0c88f..cd467529f20 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py @@ -158,7 +158,7 @@ sage: L = [graphs.CompleteGraph(i) for i in range(3,3+10)] sage: for number, G in enumerate(L): - ....: G.plot().save(tmp_filename(ext=".png")) + ....: G.plot().save(tmp_filename(ext='.png')) Sage example in ./graphtheory.tex, line 782:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py index 7c9e0183efe..e5f90964e0c 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py @@ -398,7 +398,7 @@ sage: n = 1000 sage: m = 5 sage: # build a stochastic matrix of size n - sage: # with m non-zero coefficients per row + sage: # with m nonzero coefficients per row sage: A1 = sparse.lil_matrix((n, n)) sage: for i in range(0,n): ....: for j in range(0,m): diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/domaines_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/domaines_doctest.py index b71053c71ea..8746bdf0a1e 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/domaines_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/domaines_doctest.py @@ -39,12 +39,12 @@ Sage example in ./sol/domaines.tex, line 80:: sage: E = CombinatorialFreeModule(QQ, [1,2,3]) - sage: H = Hom(E,E); H.rename("H") + sage: H = Hom(E,E); H.rename('H') sage: C = E.category(); C Category of finite dimensional vector spaces with basis over Rational Field sage: phi1 = E.module_morphism(on_basis=lambda i: E.term(i), codomain=E) sage: phi2 = E.module_morphism(on_basis=lambda i: E.term(i), - ....: triangular="lower", codomain=E) + ....: triangular='lower', codomain=E) sage: phi3 = E.module_morphism(diagonal=lambda i: 1, codomain=E, ....: category=C) sage: phi1.parent() == phi2.parent() == phi3.parent() == H diff --git a/src/sage/tests/cmdline.py b/src/sage/tests/cmdline.py index 5bfe85f6e4c..406bf1befab 100644 --- a/src/sage/tests/cmdline.py +++ b/src/sage/tests/cmdline.py @@ -57,21 +57,21 @@ import select -def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False, **kwds): +def test_executable(args, input='', timeout=100.0, pydebug_ignore_warnings=False, **kwds): r""" Run the program defined by ``args`` using the string ``input`` on the standard input. INPUT: - - ``args`` -- a list of program arguments, the first being the - executable. + - ``args`` -- list of program arguments, the first being the + executable - - ``input`` -- a string serving as standard input. Usually, this - should end with a newline. + - ``input`` -- string serving as standard input; usually, this + should end with a newline - ``timeout`` -- if the program produces no output for ``timeout`` - seconds, a :class:`RuntimeError` is raised. + seconds, a :exc:`RuntimeError` is raised - ``pydebug_ignore_warnings`` -- boolean. Set the PYTHONWARNINGS environment variable to ignore Python warnings when on a Python debug build (`--with-pydebug`, e.g. from building with @@ -80,13 +80,12 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False so the filter will catch a bit more than the default filters. Hence we only enable it on debug builds. - - ``**kwds`` -- Additional keyword arguments passed to the - :class:`Popen` constructor. + - ``**kwds`` -- additional keyword arguments passed to the + :class:`Popen` constructor OUTPUT: a tuple ``(out, err, ret)`` with the standard output, standard error and exitcode of the program run. - EXAMPLES:: sage: from sage.tests.cmdline import test_executable diff --git a/src/sage/tests/finite_poset.py b/src/sage/tests/finite_poset.py index d04221dcc13..3d4cec06129 100644 --- a/src/sage/tests/finite_poset.py +++ b/src/sage/tests/finite_poset.py @@ -91,6 +91,7 @@ sublattice_closed = ['distributive', 'modular', 'semidistributive', 'join_semidistributive', 'meet_semidistributive'] + def test_attrcall(name, L): """ Return a function by name. @@ -122,6 +123,7 @@ def test_attrcall(name, L): return L.is_orthocomplemented(unique=True) return attrcall(name)(L) + def test_finite_lattice(L): """ Test several functions on a given finite lattice. diff --git a/src/sage/tests/functools_partial_src.py b/src/sage/tests/functools_partial_src.py index d352d160230..e8c983356aa 100644 --- a/src/sage/tests/functools_partial_src.py +++ b/src/sage/tests/functools_partial_src.py @@ -4,6 +4,7 @@ """ from functools import partial + def base(x): """ Test function to make sure diff --git a/src/sage/tests/memcheck/verify_no_leak.py b/src/sage/tests/memcheck/verify_no_leak.py index 89ca90cf89c..17a3b4975aa 100644 --- a/src/sage/tests/memcheck/verify_no_leak.py +++ b/src/sage/tests/memcheck/verify_no_leak.py @@ -1,4 +1,4 @@ -from typing import Tuple, Sequence, List, Callable, Any +from typing import Callable, Any import valgrind diff --git a/src/sage/tests/meson.build b/src/sage/tests/meson.build new file mode 100644 index 00000000000..4592d9d9d4e --- /dev/null +++ b/src/sage/tests/meson.build @@ -0,0 +1,54 @@ +py.install_sources( + '__init__.py', + 'all.py', + 'article_heuberger_krenn_kropf_fsm-in-sage.py', + 'arxiv_0812_2725.py', + 'benchmark.py', + 'book_schilling_zabrocki_kschur_primer.py', + 'book_stein_ent.py', + 'book_stein_modform.py', + 'cmdline.py', + 'combinatorial_hopf_algebras.py', + 'finite_poset.py', + 'functools_partial_src.py', + 'gosper-sum.py', + 'lazy_imports.py', + 'modular_group_cohomology.py', + 'numpy.py', + 'parigp.py', + 'startup.py', + 'symbolic-series.py', + 'sympy.py', + 'test_deprecation.py', + subdir: 'sage/tests', +) + +extension_data = {'cython' : files('cython.pyx')} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'sage/tests', + install: true, + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +extension_data_cpp = {'stl_vector': files('stl_vector.pyx')} + +foreach name, pyx : extension_data_cpp + py.extension_module( + name, + sources: pyx, + subdir: 'sage/tests', + install: true, + override_options: ['cython_language=cpp'], + include_directories: [inc_cpython, inc_rings], + dependencies: [py_dep, cysignals, gmp], + ) +endforeach + +install_subdir('books', install_dir: sage_install_dir / 'tests') +install_subdir('memcheck', install_dir: sage_install_dir / 'tests') diff --git a/src/sage/tests/modular_group_cohomology.py b/src/sage/tests/modular_group_cohomology.py index 35bc8b5387f..0ef6d7f2b96 100644 --- a/src/sage/tests/modular_group_cohomology.py +++ b/src/sage/tests/modular_group_cohomology.py @@ -63,7 +63,7 @@ characteristic 2:: sage: H = CohomologyRing(libgap.AlternatingGroup(6), - ....: GroupName="A(6)", prime=2, + ....: GroupName='A(6)', prime=2, ....: from_scratch=True) sage: H.make() sage: print(H) diff --git a/src/sage/tests/stl_vector.pyx b/src/sage/tests/stl_vector.pyx index 88de4fac4cd..e7b3ec06cb6 100644 --- a/src/sage/tests/stl_vector.pyx +++ b/src/sage/tests/stl_vector.pyx @@ -38,7 +38,7 @@ from sage.cpython.string cimport char_to_str cdef class stl_int_vector(SageObject): """ - Example class wrapping an STL vector + Example class wrapping an STL vector. EXAMPLES:: diff --git a/src/sage/topology/cell_complex.py b/src/sage/topology/cell_complex.py index 48f5eb66f6f..7b64a3d36dd 100644 --- a/src/sage/topology/cell_complex.py +++ b/src/sage/topology/cell_complex.py @@ -122,9 +122,10 @@ def cells(self, subcomplex=None): optional argument ``subcomplex`` is present, then return only the cells which are *not* in the subcomplex. - :param subcomplex: a subcomplex of this cell complex. Return - the cells which are not in this subcomplex. - :type subcomplex: optional, default None + INPUT: + + - ``subcomplex`` -- subcomplex (default: ``None``); a subcomplex of + this cell complex; return the cells which are not in this subcomplex This is not implemented in general; it should be implemented in any derived class. When implementing, see the warning in @@ -174,16 +175,16 @@ def dimension(self): def n_cells(self, n, subcomplex=None): """ - List of cells of dimension ``n`` of this cell complex. + List of cells of dimension `n` of this cell complex. If the optional argument ``subcomplex`` is present, then - return the ``n``-dimensional cells which are *not* in the + return the `n`-dimensional cells which are *not* in the subcomplex. - :param n: the dimension - :type n: non-negative integer - :param subcomplex: a subcomplex of this cell complex. Return - the cells which are not in this subcomplex. - :type subcomplex: optional, default ``None`` + INPUT: + + - ``n`` -- nonnegative integer; the dimension + - ``subcomplex`` -- (optional) a subcomplex of this cell complex; + return the cells which are not in this subcomplex .. NOTE:: @@ -205,16 +206,16 @@ def n_cells(self, n, subcomplex=None): def _n_cells_sorted(self, n, subcomplex=None): """ - Sorted list of cells of dimension ``n`` of this cell complex. + Sorted list of cells of dimension `n` of this cell complex. If the optional argument ``subcomplex`` is present, then - return the ``n``-dimensional cells which are *not* in the + return the `n`-dimensional cells which are *not* in the subcomplex. - :param n: the dimension - :type n: non-negative integer - :param subcomplex: a subcomplex of this cell complex. Return - the cells which are not in this subcomplex. - :type subcomplex: optional, default ``None`` + INPUT: + + - ``n`` -- the dimension + - ``subcomplex`` -- (default: ``None``) a subcomplex of this cell + complex; return the cells which are not in this subcomplex EXAMPLES:: @@ -241,7 +242,7 @@ def _n_cells_sorted(self, n, subcomplex=None): def f_vector(self): """ - The `f`-vector of this cell complex: a list whose `n^{th}` + The `f`-vector of this cell complex: a list whose `n`-th item is the number of `(n-1)`-cells. Note that, like all lists in Sage, this is indexed starting at 0: the 0th element in this list is the number of `(-1)`-cells (which is 1: the @@ -322,7 +323,9 @@ def disjoint_union(self, right): """ The disjoint union of this cell complex with another one. - :param right: the other cell complex (the right-hand factor) + INPUT: + + - ``right`` -- the other cell complex (the right-hand factor) Disjoint unions are not implemented for general cell complexes. @@ -342,7 +345,9 @@ def wedge(self, right): The wedge (one-point union) of this cell complex with another one. - :param right: the other cell complex (the right-hand factor) + INPUT: + + - ``right`` -- the other cell complex (the right-hand factor) Wedges are not implemented for general cell complexes. @@ -365,7 +370,9 @@ def join(self, right): """ The join of this cell complex with another one. - :param right: the other cell complex (the right-hand factor) + INPUT: + + - ``right`` -- the other cell complex (the right-hand factor) Joins are not implemented for general cell complexes. They may be implemented in some derived classes (like simplicial @@ -400,8 +407,7 @@ def join(self, right): # # INPUT: # - # - ``n`` -- positive integer (default: 1): suspend this - # many times. + # - ``n`` -- positive integer (default: 1); suspend this many times. # """ # raise NotImplementedError @@ -429,14 +435,14 @@ def chain_complex(self, subcomplex=None, augmented=False, - ``check`` -- a bool: whether to check that the each composite of two consecutive differentials is zero - ``dimensions`` -- if ``None``, compute the chain complex in all - dimensions. If a list or tuple of integers, compute the - chain complex in those dimensions, setting the chain groups - in all other dimensions to zero. + dimensions. If a list or tuple of integers, compute the + chain complex in those dimensions, setting the chain groups + in all other dimensions to zero. Definitely implement the following: - - ``base_ring`` -- commutative ring (default: ZZ) - - ``cochain`` -- a bool: whether to return the cochain complex + - ``base_ring`` -- commutative ring (default: ZZ) + - ``cochain`` -- a bool: whether to return the cochain complex EXAMPLES:: @@ -454,31 +460,29 @@ def homology(self, dim=None, base_ring=ZZ, subcomplex=None, r""" The (reduced) homology of this cell complex. - :param dim: If None, then return the homology in every - dimension. If ``dim`` is an integer or list, return the - homology in the given dimensions. (Actually, if ``dim`` is - a list, return the homology in the range from ``min(dim)`` - to ``max(dim)``.) - :type dim: integer or list of integers or None; optional, - default None - :param base_ring: commutative ring, must be ZZ or a field. - :type base_ring: optional, default ZZ - :param subcomplex: a subcomplex of this simplicial complex. - Compute homology relative to this subcomplex. - :type subcomplex: optional, default empty - :param generators: If ``True``, return generators for the homology - groups along with the groups. - :type generators: boolean; optional, default: ``False`` - :param cohomology: If True, compute cohomology rather than homology. - :type cohomology: boolean; optional, default: ``False`` - :param algorithm: The options are 'auto', 'dhsw', or 'pari'. - See below for a description of what they mean. - :type algorithm: string; optional, default 'pari' - :param verbose: If True, print some messages as the homology is - computed. - :type verbose: boolean; optional, default: ``False`` - :param reduced: If ``True``, return the reduced homology. - :type reduced: boolean; optional, default ``True`` + INPUT: + + - ``dim`` -- integer or list of integers or ``None`` (default: + ``None``); if ``None``, then return the homology in every + dimension. If ``dim`` is an integer or list, return the + homology in the given dimensions. (Actually, if ``dim`` is + a list, return the homology in the range from ``min(dim)`` + to ``max(dim)``.) + - ``base_ring`` -- commutative ring (default: ``ZZ``); must be `\ZZ` or + a field + - ``subcomplex`` -- (default: empty) a subcomplex of this simplicial + complex. Compute the homology relative to this subcomplex. + - ``generators`` -- boolean (default: ``False``); if ``True``, return + generators for the homology groups along with the groups. + - ``cohomology`` -- boolean (default: ``False``); if ``True``, compute + cohomology rather than homology + - ``algorithm`` -- string (default: ``'pari'``); the algorithm options + are 'auto', 'dhsw', or 'pari'. See below for a description of what + they mean. + - ``verbose`` -- boolean (default: ``False``); if True, print some + messages as the homology is computed + - ``reduced`` -- boolean (default: ``True``); if ``True``, return the + reduced homology ALGORITHM: @@ -610,12 +614,14 @@ def cohomology(self, dim=None, base_ring=ZZ, subcomplex=None, automatically true here. Indeed, this function just calls :meth:`homology` with ``cohomology`` set to ``True``. - :param dim: - :param base_ring: - :param subcomplex: - :param algorithm: - :param verbose: - :param reduced: + INPUT: + + - ``dim`` + - ``base_ring`` + - ``subcomplex`` + - ``algorithm`` + - ``verbose`` + - ``reduced`` EXAMPLES:: @@ -662,20 +668,21 @@ def betti(self, dim=None, subcomplex=None): r""" The Betti numbers of this simplicial complex as a dictionary (or a single Betti number, if only one dimension is given): - the ith Betti number is the rank of the ith homology group. - - :param dim: If ``None``, then return every Betti number, as - a dictionary with keys the non-negative integers. If - ``dim`` is an integer or list, return the Betti number for - each given dimension. (Actually, if ``dim`` is a list, - return the Betti numbers, as a dictionary, in the range - from ``min(dim)`` to ``max(dim)``. If ``dim`` is a number, - return the Betti number in that dimension.) - :type dim: integer or list of integers or ``None``; optional, - default ``None`` - :param subcomplex: a subcomplex of this cell complex. Compute - the Betti numbers of the homology relative to this subcomplex. - :type subcomplex: optional, default ``None`` + the `i`-th Betti number is the rank of the `i`-th homology group. + + INPUT: + + - ``dim`` -- integer or list of integers or ``None`` (default: + ``None``); if ``None``, then return every Betti number, as + a dictionary with keys the non-negative integers. If + ``dim`` is an integer or list, return the Betti number for + each given dimension. (Actually, if ``dim`` is a list, + return the Betti numbers, as a dictionary, in the range + from ``min(dim)`` to ``max(dim)``. If ``dim`` is a number, + return the Betti number in that dimension.) + - ``subcomplex`` -- a subcomplex (default: ``None``) of this cell + complex; compute the Betti numbers of the homology relative to this + subcomplex EXAMPLES: @@ -702,26 +709,27 @@ def betti(self, dim=None, subcomplex=None): sage: S2c.betti(2) # needs sage.modules 1 """ - dict = {} + dic = {} H = self.homology(dim, base_ring=QQ, subcomplex=subcomplex) try: for n in H.keys(): - dict[n] = H[n].dimension() + dic[n] = H[n].dimension() if n == 0: - dict[n] += 1 - return dict + dic[n] += 1 except AttributeError: return H.dimension() + else: + return dic def is_acyclic(self, base_ring=ZZ): """ - True if the reduced homology with coefficients in ``base_ring`` of - this cell complex is zero. + Return ``True`` if the reduced homology with coefficients in + ``base_ring`` of this cell complex is zero. INPUT: - - ``base_ring`` -- optional, default ``ZZ``. Compute homology - with coefficients in this ring. + - ``base_ring`` -- (default: ``ZZ``) compute homology + with coefficients in this ring EXAMPLES:: @@ -1005,7 +1013,7 @@ def alexander_whitney(self, cell, dim_left): - ``dim_left`` -- the dimension of the left-hand factors in the decomposition - OUTPUT: a list containing triples ``(c, left, right)``. + OUTPUT: list containing triples ``(c, left, right)``. ``left`` and ``right`` should be cells in this complex, and ``c`` an integer. In the cellular approximation of the diagonal map, the chain represented by ``cell`` should get @@ -1098,7 +1106,7 @@ def graph(self): def is_connected(self): """ - True if this cell complex is connected. + Return ``True`` if this cell complex is connected. EXAMPLES:: @@ -1133,7 +1141,9 @@ def n_skeleton(self, n): complex obtained by discarding all of the simplices in dimensions larger than `n`. - :param n: non-negative integer + INPUT: + + - ``n`` -- nonnegative integer This is not implemented for general cell complexes. @@ -1153,7 +1163,7 @@ def _string_constants(self): singular and plural of the name of the cells from which it is built. This is used in constructing the string representation. - :return: tuple of strings + OUTPUT: tuple of strings This returns ``('Cell', 'cell', 'cells')``, as in "Cell complex", "1 cell", and "24 cells", but in other classes it @@ -1178,7 +1188,7 @@ def _repr_(self): """ Print representation. - :return: string + OUTPUT: string EXAMPLES:: diff --git a/src/sage/topology/cubical_complex.py b/src/sage/topology/cubical_complex.py index 8a6bde9abf1..055a597776e 100644 --- a/src/sage/topology/cubical_complex.py +++ b/src/sage/topology/cubical_complex.py @@ -59,7 +59,7 @@ ``S1`` (in fact, they're "cubically equivalent"), and this is reflected in the fact that they have isomorphic homology groups. -.. note:: +.. NOTE:: This class derives from :class:`~sage.homology.cell_complex.GenericCellComplex`, and so @@ -99,14 +99,17 @@ class Cube(SageObject): is a 3-dimensional cube (since one of the intervals is degenerate) embedded in `\RR^4`. - :param data: list or tuple of terms of the form ``(i,i+1)`` or - ``(i,i)`` or ``(i,)`` -- the last two are degenerate intervals. - :return: an elementary cube + INPUT: + + - ``data`` -- list or tuple of terms of the form ``(i,i+1)`` or + ``(i,i)`` or ``(i,)``; the last two are degenerate intervals + + OUTPUT: an elementary cube Each cube is stored in a standard form: a tuple of tuples, with a nondegenerate interval ``[j,j]`` represented by ``(j,j)``, not ``(j,)``. (This is so that for any interval ``I``, ``I[1]`` will - produce a value, not an :class:`IndexError`.) + produce a value, not an :exc:`IndexError`.) EXAMPLES:: @@ -178,7 +181,7 @@ def tuple(self): def is_face(self, other): """ - Return True iff this cube is a face of other. + Return ``True`` iff this cube is a face of other. EXAMPLES:: @@ -209,9 +212,11 @@ def _translate(self, vec): """ Translate ``self`` by ``vec``. - :param vec: anything which can be converted to a tuple of integers - :return: the translation of ``self`` by ``vec`` - :rtype: Cube + INPUT: + + - ``vec`` -- anything which can be converted to a tuple of integers + + OUTPUT: cube; the translation of ``self`` by ``vec`` If ``vec`` is shorter than the list of intervals forming the cube, pad with zeroes, and similarly if the cube's defining @@ -237,10 +242,13 @@ def _translate(self, vec): def __getitem__(self, n): """ - Return the nth interval in this cube. + Return the `n`-th interval in this cube. - :param n: an integer - :return: tuple representing the `n`-th interval in the cube. + INPUT: + + - ``n`` -- integer + + OUTPUT: tuple representing the `n`-th interval in the cube EXAMPLES:: @@ -271,8 +279,11 @@ def __add__(self, other): Cube obtained by concatenating the underlying tuples of the two arguments. - :param other: another cube - :return: the product of ``self`` and ``other``, as a Cube + INPUT: + + - ``other`` -- another cube + + OUTPUT: the product of ``self`` and ``other``, as a Cube EXAMPLES:: @@ -333,15 +344,18 @@ def dimension(self): def face(self, n, upper=True): """ - The nth primary face of this cube. + The `n`-th primary face of this cube. + + INPUT: - :param n: an integer between 0 and one less than the dimension + - ``n`` -- integer between 0 and one less than the dimension of this cube - :param upper: if True, return the "upper" nth primary face; - otherwise, return the "lower" nth primary face. - :type upper: boolean; optional, default=True - :return: the cube obtained by replacing the nth non-degenerate - interval with either its upper or lower endpoint. + - ``upper`` -- boolean (default=True);if ``True``, return the "upper" + `n`-th primary face; otherwise, return the "lower" `n`-th primary + face + + OUTPUT: the cube obtained by replacing the `n`-th non-degenerate + interval with either its upper or lower endpoint. EXAMPLES:: @@ -359,10 +373,10 @@ def face(self, n, upper=True): sage: C.face(3) Traceback (most recent call last): ... - ValueError: can only compute the nth face if 0 <= n < dim + ValueError: can only compute the n-th face if 0 <= n < dim """ if n < 0 or n >= self.dimension(): - raise ValueError("can only compute the nth face if 0 <= n < dim") + raise ValueError("can only compute the n-th face if 0 <= n < dim") idx = self.nondegenerate_intervals()[n] t = self.__tuple if upper: @@ -407,12 +421,15 @@ def _compare_for_gluing(self, other): Given two cubes ``self`` and ``other``, describe how to transform them so that they become equal. - :param other: a cube of the same dimension as ``self`` - :return: a triple ``(insert_self, insert_other, translate)``. - ``insert_self`` is a tuple with entries ``(index, (list of - degenerate intervals))``. ``insert_other`` is similar. - ``translate`` is a tuple of integers, suitable as a second - argument for the ``_translate`` method. + INPUT: + + - ``other`` -- a cube of the same dimension as ``self`` + + OUTPUT: a triple ``(insert_self, insert_other, translate)``. + ``insert_self`` is a tuple with entries ``(index, (list of + degenerate intervals))``. ``insert_other`` is similar. + ``translate`` is a tuple of integers, suitable as a second + argument for the ``_translate`` method. To do this, ``self`` and ``other`` must have the same dimension; degenerate intervals from ``other`` are added to @@ -615,11 +632,13 @@ def alexander_whitney(self, dim): def __eq__(self, other): """ - Return True iff this cube is the same as ``other``: that is, + Return ``True`` iff this cube is the same as ``other``: that is, if they are the product of the same intervals in the same order. - :param other: another cube + INPUT: + + - ``other`` -- another cube EXAMPLES:: @@ -636,9 +655,11 @@ def __eq__(self, other): def __ne__(self, other): """ - Return True iff this cube is not equal to ``other``. + Return ``True`` iff this cube is not equal to ``other``. + + INPUT: - :param other: another cube + - ``other`` -- another cube EXAMPLES:: @@ -655,10 +676,12 @@ def __ne__(self, other): def __lt__(self, other): """ - Return True iff the tuple for this cube is less than that for + Return ``True`` iff the tuple for this cube is less than that for ``other``. - :param other: another cube + INPUT: + + - ``other`` -- another cube EXAMPLES:: @@ -741,10 +764,12 @@ class CubicalComplex(GenericCellComplex): r""" Define a cubical complex. - :param maximal_faces: set of maximal faces - :param maximality_check: see below - :type maximality_check: boolean; optional, default: ``True`` - :return: a cubical complex + INPUT: + + - ``maximal_faces`` -- set of maximal faces + - ``maximality_check`` -- boolean (default: ``True``); see below + + OUTPUT: a cubical complex ``maximal_faces`` should be a list or tuple or set (or anything which may be converted to a set) of "cubes": instances of the @@ -918,7 +943,7 @@ def maximal_cells(self): The set of maximal cells (with respect to inclusion) of this cubical complex. - :return: Set of maximal cells + OUTPUT: set of maximal cells This just returns the set of cubes used in defining the cubical complex, so if the complex was defined with no @@ -938,12 +963,12 @@ def maximal_cells(self): def __eq__(self, other): r""" - Return True if the set of maximal cells is the same for + Return ``True`` if the set of maximal cells is the same for ``self`` and ``other``. - :param other: another cubical complex - :return: True if the set of maximal cells is the same for ``self`` and ``other`` - :rtype: bool + INPUT: + + - ``other`` -- another cubical complex EXAMPLES:: @@ -961,11 +986,11 @@ def __eq__(self, other): def __ne__(self, other): r""" - Return True if ``self`` and ``other`` are not equal. + Return ``True`` if ``self`` and ``other`` are not equal. + + INPUT: - :param other: another cubical complex - :return: True if the complexes are not equal - :rtype: bool + - ``other`` -- another cubical complex EXAMPLES:: @@ -996,9 +1021,11 @@ def __hash__(self): def is_subcomplex(self, other): r""" - Return True if ``self`` is a subcomplex of ``other``. + Return ``True`` if ``self`` is a subcomplex of ``other``. - :param other: a cubical complex + INPUT: + + - ``other`` -- a cubical complex Each maximal cube of ``self`` must be a face of a maximal cube of ``other`` for this to be True. @@ -1048,10 +1075,13 @@ def cells(self, subcomplex=None): If the optional argument ``subcomplex`` is present, then return only the faces which are *not* in the subcomplex. - :param subcomplex: a subcomplex of this cubical complex - :type subcomplex: a cubical complex; optional, default None - :return: cells of this complex not contained in ``subcomplex`` - :rtype: dictionary + INPUT: + + - ``subcomplex`` -- a subcomplex of this cubical complex (default: + ``None``) + + OUTPUT: dictionary; the cells of this complex not contained in + ``subcomplex`` EXAMPLES:: @@ -1107,12 +1137,13 @@ def n_cubes(self, n, subcomplex=None): return the ``n``-dimensional cubes which are *not* in the subcomplex. - :param n: dimension - :type n: integer - :param subcomplex: a subcomplex of this cubical complex - :type subcomplex: a cubical complex; optional, default None - :return: cells in dimension ``n`` - :rtype: set + INPUT: + + - ``n`` -- integer; dimension + - ``subcomplex`` -- a subcomplex of this cubical complex (default: + ``None``) + + OUTPUT: set; cells in dimension ``n`` EXAMPLES:: @@ -1135,33 +1166,29 @@ def chain_complex(self, subcomplex=None, augmented=False, r""" The chain complex associated to this cubical complex. - :param dimensions: if None, compute the chain complex in all - dimensions. If a list or tuple of integers, compute the - chain complex in those dimensions, setting the chain groups - in all other dimensions to zero. NOT IMPLEMENTED YET: this - function always returns the entire chain complex - :param base_ring: commutative ring - :type base_ring: optional, default ZZ - :param subcomplex: a subcomplex of this cubical complex. - Compute the chain complex relative to this subcomplex. - :type subcomplex: optional, default empty - :param augmented: If True, return the augmented chain complex - (that is, include a class in dimension `-1` corresponding - to the empty cell). This is ignored if ``dimensions`` is - specified. - :type augmented: boolean; optional, default: ``False`` - :param cochain: If True, return the cochain complex (that is, - the dual of the chain complex). - :type cochain: boolean; optional, default: ``False`` - :param verbose: If True, print some messages as the chain - complex is computed. - :type verbose: boolean; optional, default: ``False`` - :param check: If True, make sure that the chain complex - is actually a chain complex: the differentials are - composable and their product is zero. - :type check: boolean; optional, default: ``False`` - - .. note:: + INPUT: + + - ``dimensions`` -- if ``None``, compute the chain complex in all + dimensions. If a list or tuple of integers, compute the + chain complex in those dimensions, setting the chain groups + in all other dimensions to zero. NOT IMPLEMENTED YET: this + function always returns the entire chain complex + - ``base_ring`` -- commutative ring (default: ZZ) + - ``subcomplex`` -- a subcomplex of this cubical complex (default: empty). + Compute the chain complex relative to this subcomplex. + - ``augmented`` -- boolean (default: ``False``); if ``True``, return + the augmented chain complex (that is, include a class in dimension + `-1` corresponding to the empty cell). This is ignored if + ``dimensions`` is specified. + - ``cochain`` -- boolean (default: ``False``); if ``True``, return the + cochain complex (that is, the dual of the chain complex). + - ``verbose`` -- boolean (default: ``False``); if ``True``, print some + messages as the chain complex is computed. + - ``check`` -- boolean (default: ``False``); if ``True``, make sure + that the chain complex is actually a chain complex: the differentials + are composable and their product is zero. + + .. NOTE:: If subcomplex is nonempty, then the argument ``augmented`` has no effect: the chain complex relative to a nonempty @@ -1292,7 +1319,7 @@ def alexander_whitney(self, cube, dim_left): - ``dim`` -- integer between 0 and one more than the dimension of this cube - OUTPUT: a list containing triples ``(coeff, left, right)`` + OUTPUT: list containing triples ``(coeff, left, right)`` EXAMPLES:: @@ -1310,9 +1337,11 @@ def n_skeleton(self, n): r""" The n-skeleton of this cubical complex. - :param n: dimension - :type n: non-negative integer - :return: cubical complex + INPUT: + + - ``n`` -- nonnegative integer; dimension + + OUTPUT: cubical complex EXAMPLES:: @@ -1355,10 +1384,10 @@ def graph(self): def is_pure(self): """ - True iff this cubical complex is pure: that is, + Return ``True`` iff this cubical complex is pure: that is, all of its maximal faces have the same dimension. - .. warning:: + .. WARNING:: This may give the wrong answer if the cubical complex was constructed with ``maximality_check`` set to False. @@ -1381,7 +1410,9 @@ def join(self, other): NOT IMPLEMENTED. - :param other: another cubical complex + INPUT: + + - ``other`` -- another cubical complex EXAMPLES:: @@ -1424,8 +1455,9 @@ def suspension(self, n=1): NOT IMPLEMENTED - :param n: suspend this many times - :type n: positive integer; optional, default 1 + INPUT: + + - ``n`` -- positive integer (default: 1); suspend this many times The suspension is the complex formed by taking the join of the original complex with a two-point complex (the 0-sphere). @@ -1441,7 +1473,7 @@ def suspension(self, n=1): NotImplementedError: suspensions are not implemented for cubical complexes """ # if n<0: -# raise ValueError, "n must be non-negative." +# raise ValueError, "n must be nonnegative." # if n==0: # return self # if n==1: @@ -1453,7 +1485,9 @@ def product(self, other): r""" Return the product of this cubical complex with another one. - :param other: another cubical complex + INPUT: + + - ``other`` -- another cubical complex EXAMPLES:: @@ -1469,7 +1503,9 @@ def disjoint_union(self, other): """ The disjoint union of this cubical complex with another one. - :param right: the other cubical complex (the right-hand factor) + INPUT: + + - ``right`` -- the other cubical complex (the right-hand factor) Algorithm: first embed both complexes in d-dimensional Euclidean space. Then embed in (1+d)-dimensional space, @@ -1499,7 +1535,9 @@ def wedge(self, other): The wedge (one-point union) of this cubical complex with another one. - :param right: the other cubical complex (the right-hand factor) + INPUT: + + - ``right`` -- the other cubical complex (the right-hand factor) Algorithm: if ``self`` is embedded in `d` dimensions and ``other`` in `n` dimensions, embed them in `d+n` dimensions: @@ -1507,7 +1545,7 @@ def wedge(self, other): last `n`, translating them so that they have the origin as a common vertex. - .. note:: + .. NOTE:: This operation is not well-defined if ``self`` or ``other`` is not path-connected. @@ -1532,14 +1570,17 @@ def wedge(self, other): def connected_sum(self, other): """ - Return the connected sum of self with other. + Return the connected sum of ``self`` with ``other``. - :param other: another cubical complex - :return: the connected sum ``self # other`` + INPUT: + + - ``other`` -- another cubical complex + + OUTPUT: the connected sum ``self # other`` .. warning:: - This does not check that self and other are manifolds, only + This does not check that ``self`` and ``other`` are manifolds, only that their facets all have the same dimension. Since a (more or less) random facet is chosen from each complex and then glued together, this method may return random @@ -1609,9 +1650,11 @@ def _translate(self, vec): """ Translate ``self`` by ``vec``. - :param vec: anything which can be converted to a tuple of integers - :return: the translation of ``self`` by ``vec`` - :rtype: cubical complex + INPUT: + + - ``vec`` -- anything which can be converted to a tuple of integers + + OUTPUT: cubical complex; the translation of ``self`` by ``vec`` If ``vec`` is shorter than the list of intervals forming the complex, pad with zeroes, and similarly if the complexes @@ -1640,8 +1683,7 @@ def algebraic_topological_model(self, base_ring=None): INPUT: - - ``base_ring`` -- coefficient ring (default: - ``QQ``). Must be a field. + - ``base_ring`` -- coefficient ring (default: ``QQ``); must be a field Denote by `C` the chain complex associated to this cubical complex. The algebraic topological model is a chain complex @@ -1691,7 +1733,7 @@ def algebraic_topological_model(self, base_ring=None): def _simplicial_(self): r""" - Simplicial complex constructed from self. + Simplicial complex constructed from ``self``. ALGORITHM: @@ -1794,8 +1836,9 @@ def Sphere(self, n): A cubical complex representation of the `n`-dimensional sphere, formed by taking the boundary of an `(n+1)`-dimensional cube. - :param n: the dimension of the sphere - :type n: non-negative integer + INPUT: + + - ``n`` -- nonnegative integer; the dimension of the sphere EXAMPLES:: @@ -1866,12 +1909,13 @@ def KleinBottle(self): def SurfaceOfGenus(self, g, orientable=True): """ - A surface of genus g as a cubical complex. + A surface of genus `g` as a cubical complex. - :param g: the genus - :type g: non-negative integer - :param orientable: whether the surface should be orientable - :type orientable: bool, optional, default: ``True`` + INPUT: + + - ``g`` -- nonnegative integer; the genus + - ``orientable`` -- boolean (default: ``True``); whether the surface + should be orientable In the orientable case, return a sphere if `g` is zero, and otherwise return a `g`-fold connected sum of a torus with @@ -1891,9 +1935,9 @@ def SurfaceOfGenus(self, g, orientable=True): try: g = Integer(g) except TypeError: - raise ValueError("genus must be a non-negative integer") + raise ValueError("genus must be a nonnegative integer") if g < 0: - raise ValueError("genus must be a non-negative integer") + raise ValueError("genus must be a nonnegative integer") if g == 0: if not orientable: raise ValueError("no non-orientable surface of genus zero") @@ -1912,8 +1956,9 @@ def Cube(self, n): r""" A cubical complex representation of an `n`-dimensional cube. - :param n: the dimension - :type n: non-negative integer + INPUT: + + - ``n`` -- nonnegative integer; the dimension EXAMPLES:: diff --git a/src/sage/topology/delta_complex.py b/src/sage/topology/delta_complex.py index a02002adcb3..b9ce4d5fb62 100644 --- a/src/sage/topology/delta_complex.py +++ b/src/sage/topology/delta_complex.py @@ -14,7 +14,7 @@ A `\Delta`-complex is a generalization of a :mod:`simplicial complex `; a `\Delta`-complex `X` consists -of sets `X_n` for each non-negative integer `n`, the elements of which +of sets `X_n` for each nonnegative integer `n`, the elements of which are called *n-simplices*, along with *face maps* between these sets of simplices: for each `n` and for all `0 \leq i \leq n`, there are functions `d_i` from `X_n` to `X_{n-1}`, with `d_i(s)` equal to the @@ -40,7 +40,7 @@ representation of a torus using only 2 triangles, 3 edges, and 1 vertex. -.. note:: +.. NOTE:: This class derives from :class:`~sage.homology.cell_complex.GenericCellComplex`, and so @@ -66,10 +66,13 @@ class DeltaComplex(GenericCellComplex): r""" Define a `\Delta`-complex. - :param data: see below for a description of the options - :param check_validity: If True, check that the simplicial identities hold. - :type check_validity: boolean; optional, default: ``True`` - :return: a `\Delta`-complex + INPUT: + + - ``data`` -- see below for a description of the options + - ``check_validity`` -- boolean (default: ``True``); if ``True``, check + that the simplicial identities hold + + OUTPUT: a `\Delta`-complex Use ``data`` to define a `\Delta`-complex. It may be in any of three forms: @@ -77,16 +80,15 @@ class DeltaComplex(GenericCellComplex): - ``data`` may be a dictionary indexed by simplices. The value associated to a d-simplex `S` can be any of: - - a list or tuple of (d-1)-simplices, where the ith entry is the - ith face of S, given as a simplex, + - a list or tuple of (d-1)-simplices, where the i-th entry is the + i-th face of S, given as a simplex, - - another d-simplex `T`, in which case the ith face of `S` is - declared to be the same as the ith face of `T`: `S` and `T` + - another d-simplex `T`, in which case the i-th face of `S` is + declared to be the same as the i-th face of `T`: `S` and `T` are glued along their entire boundary, - - None or True or False or anything other than the previous two - options, in which case the faces are just the ordinary faces - of `S`. + - ``None`` or ``True`` or ``False`` or anything other than the previous two + options, in which case the faces are just the ordinary faces of `S`. For example, consider the following:: @@ -139,8 +141,8 @@ class DeltaComplex(GenericCellComplex): by omitting the lowest numbered vertex, etc., and so the boundary consists of the edges ``[1,2]``, ``[0,2]``, and ``[0,1]``, in that order. The boundary of the second is, on the - one hand, computed the same way: the nth face is obtained by - omitting the nth vertex. On the other hand, the boundary is + one hand, computed the same way: the n-th face is obtained by + omitting the n-th vertex. On the other hand, the boundary is explicitly declared to be edges ``[0,1]``, ``[0,2]``, and ``[1,2]``, in that order. This glues the second triangle to the first in the prescribed way. The three edges each start and end @@ -148,10 +150,10 @@ class DeltaComplex(GenericCellComplex): .. image:: ../../media/torus_labelled.png - - ``data`` may be nested lists or tuples. The nth entry in the + - ``data`` may be nested lists or tuples. The n-th entry in the list is a list of the n-simplices in the complex, and each - n-simplex is encoded as a list, the ith entry of which is its - ith face. Each face is represented by an integer, giving its + n-simplex is encoded as a list, the i-th entry of which is its + i-th face. Each face is represented by an integer, giving its index in the list of (n-1)-faces. For example, consider this:: sage: P = DeltaComplex( [ [(), ()], [(1,0), (1,0), (0,0)], @@ -392,10 +394,12 @@ def subcomplex(self, data): r""" Create a subcomplex. - :param data: a dictionary indexed by dimension or a list (or + INPUT: + + - ``data`` -- dictionary indexed by dimension or a list (or tuple); in either case, data[n] should be the list (or tuple or set) of the indices of the simplices to be included in - the subcomplex. + the subcomplex This automatically includes all faces of the simplices in ``data``, so you only have to specify the simplices which are @@ -515,14 +519,15 @@ def cells(self, subcomplex=None): r""" The cells of this `\Delta`-complex. - :param subcomplex: a subcomplex of this complex - :type subcomplex: optional, default None + INPUT: + + - ``subcomplex`` -- a subcomplex of this complex (default: ``None``) The cells of this `\Delta`-complex, in the form of a dictionary: the keys are integers, representing dimension, and the value associated to an integer d is the list of d-cells. Each - d-cell is further represented by a list, the ith entry of - which gives the index of its ith face in the list of + d-cell is further represented by a list, the i-th entry of + which gives the index of its i-th face in the list of (d-1)-cells. If the optional argument ``subcomplex`` is present, then @@ -573,33 +578,29 @@ def chain_complex(self, subcomplex=None, augmented=False, r""" The chain complex associated to this `\Delta`-complex. - :param dimensions: if None, compute the chain complex in all - dimensions. If a list or tuple of integers, compute the - chain complex in those dimensions, setting the chain groups - in all other dimensions to zero. NOT IMPLEMENTED YET: this - function always returns the entire chain complex - :param base_ring: commutative ring - :type base_ring: optional, default ZZ - :param subcomplex: a subcomplex of this simplicial complex. - Compute the chain complex relative to this subcomplex. - :type subcomplex: optional, default empty - :param augmented: If True, return the augmented chain complex - (that is, include a class in dimension `-1` corresponding - to the empty cell). This is ignored if ``dimensions`` is - specified or if ``subcomplex`` is nonempty. - :type augmented: boolean; optional, default: ``False`` - :param cochain: If True, return the cochain complex (that is, - the dual of the chain complex). - :type cochain: boolean; optional, default: ``False`` - :param verbose: If True, print some messages as the chain - complex is computed. - :type verbose: boolean; optional, default: ``False`` - :param check: If True, make sure that the chain complex - is actually a chain complex: the differentials are - composable and their product is zero. - :type check: boolean; optional, default: ``False`` - - .. note:: + INPUT: + + - ``dimensions`` -- if ``None``, compute the chain complex in all + dimensions. If a list or tuple of integers, compute the + chain complex in those dimensions, setting the chain groups + in all other dimensions to zero. NOT IMPLEMENTED YET: this + function always returns the entire chain complex + - ``base_ring`` -- commutative ring (default: ``ZZ``) + - ``subcomplex`` -- a subcomplex of this simplicial complex (default: + empty). Compute the chain complex relative to this subcomplex. + - ``augmented`` -- boolean (default: ``False``); if ``True``, return the + augmented chain complex (that is, include a class in dimension `-1` + corresponding to the empty cell). This is ignored if ``dimensions`` + is specified or if ``subcomplex`` is nonempty. + - ``cochain`` -- boolean (default: ``False``); if ``True``, return the + cochain complex (that is, the dual of the chain complex) + - ``verbose`` -- boolean (default: ``False``); if ``True``, print some + messages as the chain complex is computed + - ``check`` -- boolean (default: ``False``); if ``True``, make sure that + the chain complex is actually a chain complex: the differentials are + composable and their product is zero + + .. NOTE:: If subcomplex is nonempty, then the argument ``augmented`` has no effect: the chain complex relative to a nonempty @@ -709,7 +710,7 @@ def alexander_whitney(self, cell, dim_left): - ``dim_left`` -- integer between 0 and one more than the dimension of this simplex - OUTPUT: a list containing just the triple ``(1, left, + OUTPUT: list containing just the triple ``(1, left, right)``, where ``left`` and ``right`` are the two cells described above, each given as pairs ``(idx, tuple)``. @@ -742,8 +743,7 @@ def n_skeleton(self, n): r""" The n-skeleton of this `\Delta`-complex. - :param n: dimension - :type n: non-negative integer + - ``n`` -- nonnegative integer; dimension EXAMPLES:: @@ -788,15 +788,17 @@ def join(self, other): r""" The join of this `\Delta`-complex with another one. - :param other: another `\Delta`-complex (the right-hand - factor) - :return: the join ``self * other`` + INPUT: + + - ``other`` -- another `\Delta`-complex (the right-hand factor) + + OUTPUT: the join ``self * other`` The join of two `\Delta`-complexes `S` and `T` is the `\Delta`-complex `S*T` with simplices of the form `[v_0, ..., v_k, w_0, ..., w_n]` for all simplices `[v_0, ..., v_k]` in `S` and `[w_0, ..., w_n]` in `T`. The faces are computed - accordingly: the ith face of such a simplex is either `(d_i S) + accordingly: the i-th face of such a simplex is either `(d_i S) * T` if `i \leq k`, or `S * (d_{i-k-1} T)` if `i > k`. EXAMPLES:: @@ -902,8 +904,7 @@ def suspension(self, n=1): r""" The suspension of this `\Delta`-complex. - :param n: suspend this many times. - :type n: positive integer; optional, default 1 + - ``n`` -- positive integer (default: 1); suspend this many times The suspension is the complex formed by adding two new vertices `S_0` and `S_1` and simplices of the form `[S_0, v_0, @@ -920,7 +921,7 @@ def suspension(self, n=1): {0: 0, 1: 0, 2: 0, 3: Z} """ if n < 0: - raise ValueError("n must be non-negative") + raise ValueError("n must be nonnegative") if n == 0: return self if n == 1: @@ -931,11 +932,13 @@ def product(self, other): r""" The product of this `\Delta`-complex with another one. - :param other: another `\Delta`-complex (the right-hand - factor) - :return: the product ``self x other`` + INPUT: - .. warning:: + - ``other`` -- another `\Delta`-complex (the right-hand factor) + + OUTPUT: the product ``self x other`` + + .. WARNING:: If ``X`` and ``Y`` are `\Delta`-complexes, then ``X*Y`` returns their join, not their product. @@ -1060,7 +1063,9 @@ def disjoint_union(self, right): r""" The disjoint union of this `\Delta`-complex with another one. - :param right: the other `\Delta`-complex (the right-hand factor) + INPUT: + + - ``right`` -- the other `\Delta`-complex (the right-hand factor) EXAMPLES:: @@ -1087,9 +1092,9 @@ def wedge(self, right): The wedge (one-point union) of this `\Delta`-complex with another one. - :param right: the other `\Delta`-complex (the right-hand factor) + - ``right`` -- the other `\Delta`-complex (the right-hand factor) - .. note:: + .. NOTE:: This operation is not well-defined if ``self`` or ``other`` is not path-connected. @@ -1114,15 +1119,18 @@ def wedge(self, right): def connected_sum(self, other): r""" - Return the connected sum of self with other. + Return the connected sum of ``self`` with ``other``. - :param other: another `\Delta`-complex - :return: the connected sum ``self # other`` + INPUT: + + - ``other`` -- another `\Delta`-complex + + OUTPUT: the connected sum ``self # other`` .. warning:: - This does not check that self and other are manifolds. It - doesn't even check that their facets all have the same + This does not check that ``self`` and ``other`` are manifolds. + It doesn't even check that their facets all have the same dimension. It just chooses top-dimensional simplices from each complex, checks that they have the same dimension, removes them, and glues the remaining pieces together. @@ -1219,9 +1227,12 @@ def elementary_subdivision(self, idx=-1): top-dimensional simplices) of the simplex to subdivide. If not present, subdivide the last entry in this list. - :param idx: index specifying which simplex to subdivide - :type idx: integer; optional, default -1 - :return: `\Delta`-complex with one simplex subdivided. + INPUT: + + - ``idx`` -- integer (default: -1); index specifying which simplex to + subdivide + + OUTPUT: `\Delta`-complex with one simplex subdivided *Elementary subdivision* of a simplex means replacing that simplex with the cone on its boundary. That is, given a @@ -1331,12 +1342,15 @@ def _epi_from_standard_simplex(self, idx=-1, dim=None): This is used by :meth:`elementary_subdivision`. - :param idx: index specifying which simplex to examine - :type idx: integer; optional, default -1 - :return: boolean, True if the boundary of the simplex has any - identifications - :param dim: dimension of simplex to consider - :type dim: integer; optional, default = dim of complex + INPUT: + + - ``idx`` -- integer (default: -1); index specifying which simplex to + examine + - ``dim`` -- integer (default: dimension of complex); dimension of simplex + to consider + + OUTPUT: boolean; whether the boundary of the simplex has any + identifications Suppose that the dimension is `d`. The map is given by a dictionary indexed by dimension: in dimension `i`, its value @@ -1367,17 +1381,17 @@ def _epi_from_standard_simplex(self, idx=-1, dim=None): """ if dim is None: dim = self.dimension() - # the output is easier to read if the entries are non-negative. + # the output is easier to read if the entries are nonnegative. if idx == -1: idx = len(self.n_cells(dim)) - 1 simplex = SimplicialComplex([Simplex(dim)]).delta_complex(sort_simplices=True) simplex_cells = simplex.cells() self_cells = self.cells() if dim > 0: - map = {dim: {tuple(simplex_cells[dim][0]): idx}} + mapping = {dim: {tuple(simplex_cells[dim][0]): idx}} else: - map = {dim: {(0,): idx}} - faces_dict = map[dim] + mapping = {dim: {(0,): idx}} + faces_dict = mapping[dim] for n in range(dim, 0, -1): n_cells = faces_dict faces_dict = {} @@ -1393,12 +1407,12 @@ def _epi_from_standard_simplex(self, idx=-1, dim=None): for j in one_cell: if j not in faces_dict: faces_dict[j] = one_cell[j] - map[n-1] = faces_dict - return map + mapping[n-1] = faces_dict + return mapping def _is_glued(self, idx=-1, dim=None): r""" - ``True`` if there is any gluing along the boundary of a + Return ``True`` if there is any gluing along the boundary of a top-dimensional simplex in this `\Delta`-complex. If the optional argument ``idx`` is present, it specifies @@ -1410,12 +1424,15 @@ def _is_glued(self, idx=-1, dim=None): This is used by :meth:`connected_sum`. - :param idx: index specifying which simplex to examine - :type idx: integer; optional, default -1 - :return: boolean, True if the boundary of the simplex has any - identifications - :param dim: dimension of simplex to consider - :type dim: integer; optional, default = dim of complex + INPUT: + + - ``idx`` -- integer (default: -1); index specifying which simplex to + examine + - ``dim`` -- integer (default: dimension of complex); dimension of simplex + to consider + + OUTPUT: boolean; whether the boundary of the simplex has any + identifications EXAMPLES:: @@ -1551,8 +1568,7 @@ def algebraic_topological_model(self, base_ring=None): INPUT: - - ``base_ring`` -- coefficient ring (default: - ``QQ``). Must be a field. + - ``base_ring`` -- coefficient ring (default: ``QQ``); must be a field Denote by `C` the chain complex associated to this `\Delta`-complex. The algebraic topological model is a chain complex @@ -1647,7 +1663,9 @@ def Sphere(self, n): except in dimension 1, in which case it is a single 1-simplex starting and ending at the same vertex. - :param n: dimension of the sphere + INPUT: + + - ``n`` -- dimension of the sphere EXAMPLES:: @@ -1729,10 +1747,11 @@ def SurfaceOfGenus(self, g, orientable=True): r""" A surface of genus g as a `\Delta`-complex. - :param g: the genus - :type g: non-negative integer - :param orientable: whether the surface should be orientable - :type orientable: bool, optional, default ``True`` + INPUT: + + - ``g`` -- nonnegative integer; the genus + - ``orientable`` -- boolean (default: ``True``); whether the surface + should be orientable In the orientable case, return a sphere if `g` is zero, and otherwise return a `g`-fold connected sum of a torus with @@ -1765,9 +1784,9 @@ def SurfaceOfGenus(self, g, orientable=True): try: g = Integer(g) except TypeError: - raise ValueError("genus must be a non-negative integer") + raise ValueError("genus must be a nonnegative integer") if g < 0: - raise ValueError("genus must be a non-negative integer") + raise ValueError("genus must be a nonnegative integer") if g == 0: if not orientable: raise ValueError("no non-orientable surface of genus zero") diff --git a/src/sage/topology/filtered_simplicial_complex.py b/src/sage/topology/filtered_simplicial_complex.py index 95191dd1cd4..e468b80c662 100644 --- a/src/sage/topology/filtered_simplicial_complex.py +++ b/src/sage/topology/filtered_simplicial_complex.py @@ -101,7 +101,7 @@ class FilteredSimplicialComplex(SageObject): INPUT: - ``simplices`` -- list of simplices and filtration values - - ``verbose`` -- (default: ``False``) if ``True``, any change to + - ``verbose`` -- boolean (default: ``False``); if ``True``, any change to the filtration value of a simplex will be printed ``simplices`` should be a list of tuples ``(l, v)``, where @@ -381,9 +381,9 @@ def _persistent_homology(self, field=2, strict=True, verbose=False): - ``field`` -- (default: 2) prime number modulo which the homology is computed - - ``strict`` -- (default: ``True``) if ``False``, takes into account + - ``strict`` -- boolean (default: ``True``); if ``False``, takes into account intervals of persistence 0 - - ``verbose`` -- (default: ``False``) if ``True``, prints the + - ``verbose`` -- boolean (default: ``False``); if ``True``, prints the progress of computation This method is called whenever Betti numbers or intervals are @@ -582,7 +582,7 @@ def _remove_pivot_rows(self, s, simplices): # Reduce d until it is empty or until the simplex # with maximum index in the complex among all - # non-zero terms is not in T. + # nonzero terms is not in T. while d != 0: max_index = self._max_index(d) t = simplices[max_index] @@ -620,8 +620,7 @@ def _max_index(self, d): currmax = -1 for s, x_s in d: j = self._index_of_simplex[s] - if j > currmax: - currmax = j + currmax = max(j, currmax) return currmax def persistence_intervals(self, dimension, field=2, strict=True, verbose=None): @@ -634,7 +633,7 @@ def persistence_intervals(self, dimension, field=2, strict=True, verbose=None): return intervals - ``field`` -- prime number (default: 2); modulo which persistent homology is computed - - ``strict`` -- (default: ``True``) if ``False``, takes into account + - ``strict`` -- boolean (default: ``True``); if ``False``, takes into account intervals of persistence 0 - ``verbose`` -- (optional) if ``True``, print the steps of the persistent homology computation; the default is the verbosity @@ -665,7 +664,7 @@ def betti_number(self, k, a, b, field=2, strict=True, verbose=None): - ``b`` -- the size of the interval - ``field`` -- prime number (default: 2); modulo which persistent homology is computed - - ``strict`` -- (default: ``True``) if ``False``, takes into account + - ``strict`` -- boolean (default: ``True``); if ``False``, takes into account intervals of persistence 0 - ``verbose`` -- (optional) if ``True``, print the steps of the persistent homology computation; the default is the verbosity diff --git a/src/sage/topology/moment_angle_complex.py b/src/sage/topology/moment_angle_complex.py index d2b986a6a1d..3291b9ef104 100644 --- a/src/sage/topology/moment_angle_complex.py +++ b/src/sage/topology/moment_angle_complex.py @@ -200,7 +200,7 @@ def __classcall_private__(cls, simplicial_complex): immutable_complex = SimplicialComplex(is_mutable=False) return super().__classcall__(cls, immutable_complex) - def __init__(self, simplicial_complex): + def __init__(self, simplicial_complex) -> None: """ Initialize ``self``. @@ -295,7 +295,7 @@ def cubical_complex(self): .. WARNING:: - The construction can be very slow, it is not reccomended unless + The construction can be very slow, it is not recommended unless the corresponding simplicial complex has 5 or less vertices. EXAMPLES:: @@ -343,14 +343,14 @@ def simplicial_complex(self): """ return self._simplicial_complex - def components(self): + def components(self) -> dict: r""" Return the dictionary of components of ``self``, indexed by facets of the associated simplicial complex. OUTPUT: - A dictonary, whose values are lists, representing spheres + A dictionary, whose values are lists, representing spheres and disks described in the construction of the moment-angle complex. ``The 2-simplex`` represents a 2-disk, and ``Minimal triangulation of the 1-sphere`` represents a 1-sphere. @@ -507,13 +507,13 @@ def _homology_group(self, i, base_ring, cohomology, algorithm, verbose, reduced) return HomologyGroup(m, base_ring, invfac) def homology(self, dim=None, base_ring=ZZ, cohomology=False, - algorithm='pari', verbose=False, reduced=True): + algorithm='pari', verbose=False, reduced=True) -> dict: r""" The (reduced) homology of ``self``. INPUT: - - ``dim`` -- integer, or a list of integers; represents the + - ``dim`` -- integer or a list of integers; represents the homology (or homologies) we want to compute - ``base_ring`` -- commutative ring (default: ``ZZ``); must be ``ZZ`` or a field @@ -615,15 +615,15 @@ def homology(self, dim=None, base_ring=ZZ, cohomology=False, 17: 0} sage: Z = MomentAngleComplex([[0,1,2,3], [0,1,2,4], [0,1,3,5], ....: [0,1,4,5], [0,2,3,6], [0,2,4,6]]) - sage: Z.homology(dim=range(0,5), reduced=True) + sage: Z.homology(dim=range(5), reduced=True) {0: 0, 1: 0, 2: 0, 3: Z x Z x Z x Z, 4: Z x Z} - sage: Z.homology(dim=range(0,5), reduced=False) + sage: Z.homology(dim=range(5), reduced=False) {0: Z, 1: 0, 2: 0, 3: Z x Z x Z x Z, 4: Z x Z} sage: all(Z.homology(i,reduced=True) == Z.homology(i,reduced=False) ....: for i in range(1, dim(Z))) True sage: all(Z.homology(i,reduced=True) == Z.homology(i,reduced=False) - ....: for i in range(0, dim(Z))) + ....: for i in range(dim(Z))) False """ if dim is not None: @@ -641,7 +641,7 @@ def homology(self, dim=None, base_ring=ZZ, cohomology=False, algorithm=algorithm, verbose=verbose, reduced=reduced) for i in dims} def cohomology(self, dim=None, base_ring=ZZ, algorithm='pari', - verbose=False, reduced=True): + verbose=False, reduced=True) -> dict: r""" The reduced cohomology of ``self``. @@ -672,7 +672,7 @@ def cohomology(self, dim=None, base_ring=ZZ, algorithm='pari', return self.homology(dim=dim, cohomology=True, base_ring=base_ring, algorithm=algorithm, verbose=verbose, reduced=reduced) - def betti(self, dim=None): + def betti(self, dim=None) -> dict: r""" Return the Betti number (or numbers) of ``self``. @@ -698,16 +698,17 @@ def betti(self, dim=None): sage: Z.betti(dim=6) {6: 2} """ - dict = {} + dic = {} H = self.homology(dim=dim, base_ring=QQ) try: for n in H: - dict[n] = H[n].dimension() + dic[n] = H[n].dimension() if n == 0: - dict[n] += 1 - return dict + dic[n] += 1 except AttributeError: return H.dimension() + else: + return dic def euler_characteristic(self): """ @@ -762,7 +763,7 @@ def product(self, other): simplicial_complex = self._simplicial_complex.join(other._simplicial_complex, rename_vertices=True) return MomentAngleComplex(simplicial_complex) - def has_trivial_lowest_deg_massey_product(self): + def has_trivial_lowest_deg_massey_product(self) -> bool: """ Return whether ``self`` has a non-trivial lowest degree triple Massey product. diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index a6d5cbf56f3..54166cf4f1f 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -55,10 +55,10 @@ For any simplicial complex `K` and any commutative ring `R` there is an associated chain complex, with differential of degree `-1`. The -`n^{th}` term is the free `R`-module with basis given by the +`n`-th term is the free `R`-module with basis given by the `n`-simplices of `K`. The differential is determined by its value on any simplex: on the `n`-simplex with vertices `(v_0, v_1, ..., v_n)`, -the differential is the alternating sum with `i^{th}` summand `(-1)^i` +the differential is the alternating sum with `i`-th summand `(-1)^i` multiplied by the `(n-1)`-simplex obtained by omitting vertex `v_i`. In the implementation here, the vertex set must be finite. To define a @@ -192,15 +192,14 @@ def lattice_paths(t1, t2, length=None): ``(t1[last], t2[last])``, and at each grid point, going either right or up. See the examples. - :param t1: labeling for vertices - :param t2: labeling for vertices - :param length: if not ``None``, then an integer, the length of the desired - path. - :type length: integer or ``None``; optional, default ``None`` - :type t1: list, other iterable - :type t2: list, other iterable - :return: list of lists of vertices making up the paths as described above - :rtype: list of lists + INPUT: + + - ``t1`` -- list or other iterable; labeling for vertices + - ``t2`` -- list or other iterable; labeling for vertices + - ``length`` -- integer or ``None`` (default: ``None``); if not ``None``, then + an integer, the length of the desired path + + OUTPUT: list of lists of vertices making up the paths This is used when triangulating the product of simplices. The optional argument ``length`` is used for `\Delta`-complexes, to @@ -301,10 +300,12 @@ def rename_vertex(n, keep, left=True): renamed to by prepending an 'L' or an 'R' (thus to either 'L4' or 'R4'), depending on whether the argument left is ``True`` or ``False``. - :param n: a 'vertex': either an integer or a string - :param keep: a list of three vertices - :param left: if ``True``, rename for use in left factor - :type left: boolean; optional, default ``True`` + INPUT: + + - ``n`` -- a 'vertex'; either an integer or a string + - ``keep`` -- list of three vertices + - ``left`` -- boolean (default: ``True``); if ``True``, rename for use in + left factor This is used by the :meth:`~SimplicialComplex.connected_sum` method for simplicial complexes. @@ -336,11 +337,13 @@ class Simplex(SageObject): by specifying a set of vertices. It is represented in Sage by the tuple of the vertices. - :param X: set of vertices - :type X: integer, list, other iterable - :return: simplex with those vertices + INPUT: - ``X`` may be a non-negative integer `n`, in which case the + - ``X`` -- set of vertices (integer, list, or other iterable) + + OUTPUT: simplex with those vertices + + ``X`` may be a nonnegative integer `n`, in which case the simplicial complex will have `n+1` vertices `(0, 1, ..., n)`, or it may be anything which may be converted to a tuple, in which case the vertices will be that tuple. In the second case, each @@ -486,7 +489,9 @@ def __add__(self, other): Simplex obtained by concatenating the underlying tuples of the two arguments. - :param other: another simplex + INPUT: + + - ``other`` -- another simplex EXAMPLES:: @@ -499,10 +504,12 @@ def face(self, n): """ The `n`-th face of this simplex. - :param n: an integer between 0 and the dimension of this simplex - :type n: integer - :return: the simplex obtained by removing the `n`-th vertex from this - simplex + INPUT: + + - ``n`` -- integer between 0 and the dimension of this simplex + + OUTPUT: the simplex obtained by removing the `n`-th vertex from this + simplex EXAMPLES:: @@ -515,7 +522,7 @@ def face(self, n): if n >= 0 and n <= self.dimension(): return Simplex(self.__tuple[:n] + self.__tuple[n+1:]) else: - raise IndexError("{} does not have an nth face for n={}".format(self, n)) + raise IndexError("{} does not have an n-th face for n={}".format(self, n)) def faces(self): """ @@ -564,17 +571,17 @@ def join(self, right, rename_vertices=True): The join of two simplices `[v_0, ..., v_k]` and `[w_0, ..., w_n]` is the simplex `[v_0, ..., v_k, w_0, ..., w_n]`. - :param right: the other simplex (the right-hand factor) + INPUT: - :param rename_vertices: If this is ``True``, the vertices in the - join will be renamed by this formula: vertex "v" in the - left-hand factor --> vertex "Lv" in the join, vertex "w" - in the right-hand factor --> vertex "Rw" in the join. If - this is false, this tries to construct the join without - renaming the vertices; this may cause problems if the two - factors have any vertices with names in common. + - ``right`` -- the other simplex (the right-hand factor) - :type rename_vertices: boolean; optional, default ``True`` + - ``rename_vertices`` -- boolean (default: ``True``); if this is ``True``, + the vertices in the join will be renamed by this formula: vertex "v" + in the left-hand factor --> vertex "Lv" in the join, vertex "w" in + the right-hand factor --> vertex "Rw" in the join. If this is + ``False``, this tries to construct the join without renaming the + vertices; this may cause problems if the two factors have any + vertices with names in common. EXAMPLES:: @@ -596,27 +603,26 @@ def product(self, other, rename_vertices=True): r""" The product of this simplex with another one, as a list of simplices. - :param other: the other simplex + INPUT: - :param rename_vertices: If this is ``False``, then the vertices in - the product are the set of ordered pairs `(v,w)` where `v` - is a vertex in the left-hand factor (``self``) and `w` is - a vertex in the right-hand factor (``other``). If this is - ``True``, then the vertices are renamed as "LvRw" (e.g., the - vertex (1,2) would become "L1R2"). This is useful if you - want to define the Stanley-Reisner ring of the complex: - vertex names like (0,1) are not suitable for that, while - vertex names like "L0R1" are. + - ``other`` -- the other simplex - :type rename_vertices: boolean; optional, default ``True`` + - ``rename_vertices`` -- boolean (default: ``True``); if this is + ``False``, then the vertices in the product are the set of ordered + pairs `(v,w)` where `v` is a vertex in the left-hand factor + (``self``) and `w` is a vertex in the right-hand factor (``other``). + If this is ``True``, then the vertices are renamed as "LvRw" (e.g., + the vertex (1,2) would become "L1R2"). This is useful if you want to + define the Stanley-Reisner ring of the complex: vertex names like + (0,1) are not suitable for that, while vertex names like "L0R1" are. - Algorithm: see Hatcher, p. 277-278 [Hat2002]_ (who in turn refers to + ALGORITHM: see Hatcher, p. 277-278 [Hat2002]_ (who in turn refers to Eilenberg-Steenrod, p. 68): given ``S = Simplex(m)`` and ``T = Simplex(n)``, then `S \times T` can be triangulated as follows: for each path `f` from `(0,0)` to `(m,n)` along the integer grid in the plane, going up or right at each lattice point, associate an `(m+n)`-simplex with - vertices `v_0`, `v_1`, ..., where `v_k` is the `k^{th}` vertex + vertices `v_0`, `v_1`, ..., where `v_k` is the `k`-th vertex in the path `f`. Note that there are `m+n` choose `n` such paths. Note also @@ -697,7 +703,9 @@ def __eq__(self, other): is, if the vertices of the two are the same, even with a different ordering - :param other: the other simplex + INPUT: + + - ``other`` -- the other simplex EXAMPLES:: @@ -718,7 +726,9 @@ def __ne__(self, other): """ Return ``True`` iff this simplex is not equal to ``other``. - :param other: the other simplex + INPUT: + + - ``other`` -- the other simplex EXAMPLES:: @@ -734,7 +744,9 @@ def __lt__(self, other): Return ``True`` iff the sorted tuple for this simplex is less than that for ``other``. - :param other: the other simplex + INPUT: + + - ``other`` -- the other simplex EXAMPLES:: @@ -821,25 +833,25 @@ class SimplicialComplex(Parent, GenericCellComplex): r""" Define a simplicial complex. - :param maximal_faces: set of maximal faces - :param from_characteristic_function: see below - :param maximality_check: see below - :type maximality_check: boolean; optional, default ``True`` - :param sort_facets: see below - :type sort_facets: dict - :param name_check: see below - :type name_check: boolean; optional, default ``False`` - :param is_mutable: Set to ``False`` to make this immutable - :type is_mutable: boolean; optional, default ``True`` - :param category: the category of the simplicial complex - :type category: category; optional, default finite simplicial complexes - :return: a simplicial complex + INPUT: + + - ``maximal_faces`` -- set of maximal faces + - ``from_characteristic_function`` -- see below + - ``maximality_check`` -- boolean (default: ``True``); see below + - ``sort_facets`` -- dictionary; see below + - ``name_check`` -- boolean (default: ``False``); see below + - ``is_mutable`` -- boolean (default: ``True``); set to ``False`` to make + this immutable + - ``category`` -- the category of the simplicial complex (default: finite + simplicial complexes) + + OUTPUT: a simplicial complex ``maximal_faces`` should be a list or tuple or set (indeed, anything which may be converted to a set) whose elements are lists (or tuples, etc.) of vertices. Maximal faces are also known as 'facets'. ``maximal_faces`` can also be a list containing a single - non-negative integer `n`, in which case this constructs the + nonnegative integer `n`, in which case this constructs the simplicial complex with a single `n`-simplex as the only facet. Alternatively, the maximal faces can be defined from a monotone boolean @@ -1025,7 +1037,7 @@ def __init__(self, # Convert it into a list (in case it is an iterable) maximal_faces = list(maximal_faces) if len(maximal_faces) == 1 and isinstance(maximal_faces[0], (int, Integer)): - # list containing a single non-negative integer n; + # list containing a single nonnegative integer n; # construct the simplicial complex with a single n-simplex as the only facet. vertices = tuple(range(maximal_faces[0] + 1)) maximal_faces = [vertices] @@ -1247,7 +1259,7 @@ def _an_element_(self): def __contains__(self, x): """ - True if ``x`` is a simplex which is contained in this complex. + Return ``True`` if ``x`` is a simplex which is contained in this complex. EXAMPLES:: @@ -1268,7 +1280,7 @@ def __call__(self, simplex): """ If ``simplex`` is a simplex in this complex, return it. - Otherwise, this raises a :class:`ValueError`. + Otherwise, this raises a :exc:`ValueError`. EXAMPLES:: @@ -1315,10 +1327,10 @@ def faces(self, subcomplex=None): argument ``subcomplex`` is present, then return only the faces which are *not* in the subcomplex. - :param subcomplex: a subcomplex of this simplicial complex. - Return faces which are not in this subcomplex. + INPUT: - :type subcomplex: optional, default ``None`` + - ``subcomplex`` -- a subcomplex of this simplicial complex (default: + ``None``); return faces which are not in this subcomplex EXAMPLES:: @@ -1373,7 +1385,7 @@ def face_iterator(self, increasing=True): INPUT: - - ``increasing`` -- (default: ``True``) if ``True``, return + - ``increasing`` -- boolean (default: ``True``); if ``True``, return faces in increasing order of dimension, thus starting with the empty face. Otherwise it returns faces in decreasing order of dimension. @@ -1501,7 +1513,7 @@ def g_vector(self): def face(self, simplex, i): """ - The `i`-th face of ``simplex`` in this simplicial complex + The `i`-th face of ``simplex`` in this simplicial complex. INPUT: @@ -1600,9 +1612,7 @@ def F_triangle(self, S): This is the bivariate generating polynomial of all faces, according to the number of elements in ``S`` and outside ``S``. - OUTPUT: - - an :class:`~sage.combinat.triangles_FHM.F_triangle` + OUTPUT: an :class:`~sage.combinat.triangles_FHM.F_triangle` .. SEEALSO:: @@ -1711,7 +1721,7 @@ def flip_graph(self): def is_pseudomanifold(self): """ - Return True if ``self`` is a pseudomanifold. + Return ``True`` if ``self`` is a pseudomanifold. A pseudomanifold is a simplicial complex with the following properties: @@ -1768,25 +1778,24 @@ def product(self, right, rename_vertices=True, is_mutable=True): """ The product of this simplicial complex with another one. - :param right: the other simplicial complex (the right-hand - factor) + INPUT: - :param rename_vertices: If this is False, then the vertices in - the product are the set of ordered pairs `(v,w)` where `v` - is a vertex in ``self`` and `w` is a vertex in - ``right``. If this is ``True``, then the vertices are renamed - as "LvRw" (e.g., the vertex (1,2) would become "L1R2"). - This is useful if you want to define the Stanley-Reisner - ring of the complex: vertex names like (0,1) are not - suitable for that, while vertex names like "L0R1" are. + - ``right`` -- the other simplicial complex (the right-hand factor) - :type rename_vertices: boolean; optional, default ``True`` + - ``rename_vertices`` -- boolean (default: ``True``); if this is + ``False``, then the vertices in the product are the set of ordered + pairs `(v,w)` where `v` is a vertex in ``self`` and `w` is a vertex + in ``right``. If this is ``True``, then the vertices are renamed as + "LvRw" (e.g., the vertex (1,2) would become "L1R2"). This is useful + if you want to define the Stanley-Reisner ring of the complex: vertex + names like (0,1) are not suitable for that, while vertex names like + "L0R1" are. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + - ``is_mutable`` -- boolean (default: ``True``); determines whether the + output is mutable The vertices in the product will be the set of ordered pairs - `(v,w)` where `v` is a vertex in self and `w` is a vertex in + `(v,w)` where `v` is a vertex in ``self`` and `w` is a vertex in right. .. WARNING:: @@ -1848,20 +1857,20 @@ def join(self, right, rename_vertices=True, is_mutable=True): ..., v_k, w_0, ..., w_n]` for all simplices `[v_0, ..., v_k]` in `S` and `[w_0, ..., w_n]` in `T`. - :param right: the other simplicial complex (the right-hand factor) + INPUT: - :param rename_vertices: If this is True, the vertices in the - join will be renamed by the formula: vertex "v" in the - left-hand factor --> vertex "Lv" in the join, vertex "w" in - the right-hand factor --> vertex "Rw" in the join. If this - is false, this tries to construct the join without renaming - the vertices; this will cause problems if the two factors - have any vertices with names in common. + - ``right`` -- the other simplicial complex (the right-hand factor) - :type rename_vertices: boolean; optional, default ``True`` + - ``rename_vertices`` -- boolean (default: ``True``); if this is + ``True``, the vertices in the join will be renamed by the formula: + vertex "v" in the left-hand factor --> vertex "Lv" in the join, + vertex "w" in the right-hand factor --> vertex "Rw" in the join. + If this is ``False``, this tries to construct the join without + renaming the vertices; this will cause problems if the two factors + have any vertices with names in common. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + - ``is_mutable`` -- boolean (default: ``True``); determine whether the + output is mutable EXAMPLES:: @@ -1893,8 +1902,10 @@ def cone(self, is_mutable=True): """ The cone on this simplicial complex. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + INPUT: + + - ``is_mutable`` -- boolean (default: ``True``); determines whether + the output is mutable The cone is the simplicial complex formed by adding a new vertex `C` and simplices of the form `[C, v_0, ..., v_k]` for @@ -1920,12 +1931,12 @@ def suspension(self, n=1, is_mutable=True): r""" The suspension of this simplicial complex. - :param n: positive integer -- suspend this many times. + INPUT: - :type n: optional, default 1 + - ``n`` -- positive integer (default: 1); suspend this many times - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + - ``is_mutable`` -- boolean (default: ``True``); determine whether + the output is mutable The suspension is the simplicial complex formed by adding two new vertices `S_0` and `S_1` and simplices of the form `[S_0, @@ -1967,7 +1978,7 @@ def suspension(self, n=1, is_mutable=True): (0, 1, 2, 3, 4, 5, 6, 7) """ if n < 0: - raise ValueError("n must be non-negative") + raise ValueError("n must be nonnegative") if n == 0: return self if n == 1: @@ -1996,18 +2007,17 @@ def disjoint_union(self, right, rename_vertices=None, is_mutable=True): """ The disjoint union of this simplicial complex with another one. - :param right: the other simplicial complex (the right-hand factor) + INPUT: - :param rename_vertices: If this is True, the vertices in the - disjoint union will be renamed by the formula: vertex "v" - in the left-hand factor --> vertex "Lv" in the disjoint - union, vertex "w" in the right-hand factor --> vertex "Rw" - in the disjoint union. If this is false, this tries to - construct the disjoint union without renaming the vertices; - this will cause problems if the two factors have any - vertices with names in common. + - ``right`` -- the other simplicial complex (the right-hand factor) - :type rename_vertices: boolean; optional, default: ``True`` + - ``rename_vertices`` -- boolean (default: ``True``); if this is + ``True``, the vertices in the disjoint union will be renamed by the + formula: vertex "v" in the left-hand factor --> vertex "Lv" in the + disjoint union, vertex "w" in the right-hand factor --> vertex "Rw" + in the disjoint union. If this is false, this tries to construct the + disjoint union without renaming the vertices; this will cause + problems if the two factors have any vertices with names in common. EXAMPLES:: @@ -2032,21 +2042,21 @@ def wedge(self, right, rename_vertices=True, is_mutable=True): The wedge (one-point union) of this simplicial complex with another one. - :param right: the other simplicial complex (the right-hand factor) + INPUT: - :param rename_vertices: If this is ``True``, the vertices in the - wedge will be renamed by the formula: first vertex in each - are glued together and called "0". Otherwise, each vertex - "v" in the left-hand factor --> vertex "Lv" in the wedge, - vertex "w" in the right-hand factor --> vertex "Rw" in the - wedge. If this is ``False``, this tries to construct the wedge - without renaming the vertices; this will cause problems if - the two factors have any vertices with names in common. + - ``right`` -- the other simplicial complex (the right-hand factor) - :type rename_vertices: boolean; optional, default ``True`` + - ``rename_vertices`` -- boolean (default: ``True``); if this is + ``True``, the vertices in the wedge will be renamed by the formula: + first vertex in each are glued together and called "0". Otherwise, + each vertex "v" in the left-hand factor --> vertex "Lv" in the wedge, + vertex "w" in the right-hand factor --> vertex "Rw" in the wedge. If + this is ``False``, this tries to construct the wedge without renaming + the vertices; this will cause problems if the two factors have any + vertices with names in common. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + - ``is_mutable`` -- boolean (default: ``True``); determine whether + the output is mutable .. NOTE:: @@ -2087,30 +2097,26 @@ def chain_complex(self, subcomplex=None, augmented=False, r""" The chain complex associated to this simplicial complex. - :param dimensions: if ``None``, compute the chain complex in all - dimensions. If a list or tuple of integers, compute the - chain complex in those dimensions, setting the chain groups - in all other dimensions to zero. - :param base_ring: commutative ring - :type base_ring: optional, default ``ZZ`` - :param subcomplex: a subcomplex of this simplicial complex. - Compute the chain complex relative to this subcomplex. - :type subcomplex: optional, default empty - :param augmented: If ``True``, return the augmented chain complex - (that is, include a class in dimension `-1` corresponding - to the empty cell). This is ignored if ``dimensions`` is - specified. - :type augmented: boolean; optional, default ``False`` - :param cochain: If ``True``, return the cochain complex (that is, - the dual of the chain complex). - :type cochain: boolean; optional, default ``False`` - :param verbose: If ``True``, print some messages as the chain - complex is computed. - :type verbose: boolean; optional, default ``False`` - :param check: If ``True``, make sure that the chain complex - is actually a chain complex: the differentials are - composable and their product is zero. - :type check: boolean; optional, default ``False`` + INPUT: + + - ``dimensions`` -- if ``None``, compute the chain complex in all + dimensions. If a list or tuple of integers, compute the + chain complex in those dimensions, setting the chain groups + in all other dimensions to zero. + - ``base_ring`` -- commutative ring (default: ``ZZ``) + - ``subcomplex`` -- a subcomplex of this simplicial complex (default: + empty); compute the chain complex relative to this subcomplex + - ``augmented`` -- boolean (default: ``False``); if ``True``, return + the augmented chain complex (that is, include a class in dimension + `-1` corresponding to the empty cell). This is ignored if + ``dimensions`` is specified + - ``cochain`` -- boolean (default: ``False``); if ``True``, return the + cochain complex (that is, the dual of the chain complex) + - ``verbose`` -- boolean (default: ``False``); if ``True``, print some + messages as the chain complex is computed + - ``check`` -- boolean (default: ``False``); if ``True``, make sure + that the chain complex is actually a chain complex: the differentials + are composable and their product is zero .. NOTE:: @@ -2249,62 +2255,47 @@ def _homology_(self, dim=None, base_ring=ZZ, subcomplex=None, """ The (reduced) homology of this simplicial complex. - :param dim: If ``None``, then return the homology in every - dimension. If ``dim`` is an integer or list, return the - homology in the given dimensions. (Actually, if ``dim`` is - a list, return the homology in the range from ``min(dim)`` - to ``max(dim)``.) - - :type dim: integer or list of integers or ``None``; optional, - default ``None`` - - :param base_ring: commutative ring. Must be ``ZZ`` or a field. - - :type base_ring: optional, default ``ZZ`` - - :param subcomplex: a subcomplex of this simplicial complex. - Compute homology relative to this subcomplex. - - :type subcomplex: optional, default ``None`` - - :param cohomology: If ``True``, compute cohomology rather than - homology. - - :type cohomology: boolean; optional, default ``False`` - - :param enlarge: If ``True``, find a new subcomplex homotopy - equivalent to, and probably larger than, the given one. - - :type enlarge: boolean; optional, default ``True`` + INPUT: - :param algorithm: The options are ``'auto'``, ``'dhsw'``, or - ``'pari'``. (``'no_chomp'`` is a synomym for ``'auto'``, - maintained for backward compatibility.) If ``'auto'``, - use the Dumas, Heckenbach, Saunders, and Welker elimination - algorithm for large matrices, Pari for small ones. - If ``'pari'``, then compute elementary divisors - using Pari. If ``'dhsw'``, then use the DHSW algorithm to - compute elementary divisors. (As of this writing, ``'pari'`` - is the fastest standard option.) + - ``dim`` -- integer or list of integers or ``None`` (default: + ``None``); if ``None``, then return the homology in every dimension. + If ``dim`` is an integer or list, return the homology in the given + dimensions. (Actually, if ``dim`` is a list, return the homology in + the range from ``min(dim)`` to ``max(dim)``.) - :type algorithm: string; optional, default ``'pari'`` + - ``base_ring`` -- commutative ring (default: ``ZZ``); must be ``ZZ`` + or a field - :param verbose: If ``True``, print some messages as the homology - is computed. + - ``subcomplex`` -- a subcomplex of this simplicial complex (default: + ``None``); compute homology relative to this subcomplex - :type verbose: boolean; optional, default ``False`` + - ``cohomology`` -- boolean (default: ``False``); if ``True``, compute + cohomology rather than homology - :param reduced: If ``True``, return the reduced homology. + - ``enlarge`` -- boolean (default: ``True``); if ``True``, find a new + subcomplex homotopy equivalent to, and probably larger than, the + given one - :type reduced: boolean; optional, default ``True`` + - ``algorithm`` -- string (default: ``'pari'``); the options are + ``'auto'``, ``'dhsw'``, or ``'pari'``. (``'no_chomp'`` is a synonym + for ``'auto'``, maintained for backward compatibility.) If + ``'auto'``, use the Dumas, Heckenbach, Saunders, and Welker + elimination algorithm for large matrices, Pari for small ones. If + ``'pari'``, then compute elementary divisors using Pari. If + ``'dhsw'``, then use the DHSW algorithm to compute elementary + divisors. (As of this writing, ``'pari'`` is the fastest standard + option.) - :param generators: If ``True``, return the homology groups and - also generators for them. + - ``verbose`` -- boolean (default: ``False``); if ``True``, print some + messages as the homology is computed - :type reduced: boolean; optional, default ``False`` + - ``reduced`` -- boolean (default: ``Trues``); if ``True``, return the + reduced homology + - ``generators`` -- boolean (default: ``False``); if ``True``, return + the homology groups and also generators for them - Algorithm: if ``generators`` is ``True``, directly compute the + ALGORITHM: if ``generators`` is ``True``, directly compute the chain complex, compute its homology along with its generators, and then convert the chain complex generators to chains in the simplicial complex. @@ -2472,8 +2463,7 @@ def algebraic_topological_model(self, base_ring=None): INPUT: - - ``base_ring`` -- coefficient ring (default: - ``QQ``). Must be a field. + - ``base_ring`` -- coefficient ring (default: ``QQ``); must be a field Denote by `C` the chain complex associated to this simplicial complex. The algebraic topological model is a chain complex @@ -2538,7 +2528,7 @@ def alexander_whitney(self, simplex, dim_left): - ``dim`` -- integer between 0 and one more than the dimension of this simplex - OUTPUT: a list containing just the triple ``(1, left, + OUTPUT: list containing just the triple ``(1, left, right)``, where ``left`` and ``right`` are the two simplices described above. @@ -2557,7 +2547,9 @@ def add_face(self, face): """ Add a face to this simplicial complex. - :param face: a subset of the vertex set + INPUT: + + - ``face`` -- a subset of the vertex set This *changes* the simplicial complex, adding a new face and all of its subfaces. @@ -2690,11 +2682,13 @@ def remove_face(self, face, check=False): """ Remove a face from this simplicial complex. - :param face: a face of the simplicial complex + INPUT: + + - ``face`` -- a face of the simplicial complex - :param check: boolean; optional, default ``False``. If - ``True``, raise an error if ``face`` is not a - face of this simplicial complex + - ``check`` -- boolean (default: ``False``); if + ``True``, raise an error if ``face`` is not a + face of this simplicial complex This does not return anything; instead, it *changes* the simplicial complex. @@ -2819,12 +2813,14 @@ def remove_faces(self, faces, check=False): """ Remove a collection of faces from this simplicial complex. - :param faces: a list (or any iterable) of faces of the - simplicial complex + INPUT: + + - ``faces`` -- list (or any iterable) of faces of the simplicial + complex - :param check: boolean; optional, default ``False``. If - ``True``, raise an error if any element of ``faces`` is not a - face of this simplicial complex + - ``check`` -- boolean (default: ``False``); if ``True``, raise an + error if any element of ``faces`` is not a face of this simplicial + complex This does not return anything; instead, it *changes* the simplicial complex. @@ -2867,7 +2863,9 @@ def is_subcomplex(self, other): """ Return ``True`` if this is a subcomplex of ``other``. - :param other: another simplicial complex + INPUT: + + - ``other`` -- another simplicial complex EXAMPLES:: @@ -2896,10 +2894,13 @@ def connected_sum(self, other, is_mutable=True): """ The connected sum of this simplicial complex with another one. - :param other: another simplicial complex - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` - :return: the connected sum ``self # other`` + INPUT: + + - ``other`` -- another simplicial complex + - ``is_mutable`` -- boolean (default: ``True``); determine whether + the output is mutable + + OUTPUT: the connected sum ``self # other`` .. WARNING:: @@ -2960,9 +2961,11 @@ def link(self, simplex, is_mutable=True): all simplices `G` which are disjoint from `F` but for which `F \cup G` is a simplex. - :param simplex: a simplex in this simplicial complex. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + INPUT: + + - ``simplex`` -- a simplex in this simplicial complex + - ``is_mutable`` -- boolean (default: ``True``); determine whether + the output is mutable EXAMPLES:: @@ -2992,7 +2995,7 @@ def star(self, simplex, is_mutable=True): INPUT: - ``simplex`` -- a simplex in this simplicial complex - - ``is_mutable`` -- (default: ``True``) boolean; determines if the output + - ``is_mutable`` -- boolean (default: ``True``); determines if the output is mutable EXAMPLES:: @@ -3026,7 +3029,7 @@ def is_cohen_macaulay(self, base_ring=QQ, ncpus=0): INPUT: - - ``base_ring`` -- (default: ``QQ``) the base ring. + - ``base_ring`` -- (default: ``QQ``) the base ring - ``ncpus`` -- (default: 0) number of cpus used for the computation. If this is 0, determine the number of cpus @@ -3091,9 +3094,11 @@ def generated_subcomplex(self, sub_vertex_set, is_mutable=True): Return the largest sub-simplicial complex of ``self`` containing exactly ``sub_vertex_set`` as vertices. - :param sub_vertex_set: The sub-vertex set. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + INPUT: + + - ``sub_vertex_set`` -- the sub-vertex set + - ``is_mutable`` -- boolean (default: ``True``); determine whether + the output is mutable EXAMPLES:: @@ -3102,7 +3107,6 @@ def generated_subcomplex(self, sub_vertex_set, is_mutable=True): Minimal triangulation of the 2-sphere sage: S.generated_subcomplex([0,1,2]) Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)} - """ if not set(self.vertices()).issuperset(sub_vertex_set): raise ValueError("input must be a subset of the vertex set") @@ -3132,7 +3136,7 @@ def is_shelling_order(self, shelling_order, certificate=False): INPUT: - ``shelling_order`` -- an ordering of the facets of ``self`` - - ``certificate`` -- (default: ``False``) if ``True`` then returns + - ``certificate`` -- boolean (default: ``False``); if ``True`` then returns the index of the first facet that violate the condition .. SEEALSO:: @@ -3205,7 +3209,7 @@ def is_shellable(self, certificate=False): INPUT: - - ``certificate`` -- (default: ``False``) if ``True`` then + - ``certificate`` -- boolean (default: ``False``); if ``True`` then returns the shelling order (if it exists) EXAMPLES:: @@ -3341,7 +3345,9 @@ def _complement(self, simplex): Return the complement of a simplex in the vertex set of this simplicial complex. - :param simplex: a simplex (need not be in the simplicial complex) + INPUT: + + - ``simplex`` -- a simplex (need not be in the simplicial complex) OUTPUT: its complement: the simplex formed by the vertices not contained in ``simplex``. @@ -3367,7 +3373,9 @@ def _transpose_simplices(self, *simplices): simplex is formed by taking a vertex from each simplex from ``L``. - :param simplices: a bunch of simplices + INPUT: + + - ``simplices`` -- a bunch of simplices If ``simplices`` consists of `(f_0, f_1, f_2, ...)`, then the output consists of all possible simplices of the form `(v_0, @@ -3505,10 +3513,12 @@ def _stanley_reisner_base_ring(self, base_ring=ZZ): The polynomial algebra of which the Stanley-Reisner ring is a quotient. - :param base_ring: a commutative ring - :type base_ring: optional, default ``ZZ`` - :return: a polynomial algebra with coefficients in base_ring, - with one generator for each vertex in the simplicial complex. + INPUT: + + - ``base_ring`` -- a commutative ring (default: ``ZZ``) + + OUTPUT: a polynomial algebra with coefficients in base_ring, + with one generator for each vertex in the simplicial complex. See the documentation for :meth:`stanley_reisner_ring` for a warning about the names of the vertices. @@ -3533,12 +3543,14 @@ def stanley_reisner_ring(self, base_ring=ZZ): """ The Stanley-Reisner ring of this simplicial complex. - :param base_ring: a commutative ring - :type base_ring: optional, default ``ZZ`` - :return: a quotient of a polynomial algebra with coefficients - in ``base_ring``, with one generator for each vertex in the - simplicial complex, by the ideal generated by the products - of those vertices which do not form faces in it. + INPUT: + + - ``base_ring`` -- a commutative ring (default: ``ZZ``) + + OUTPUT: a quotient of a polynomial algebra with coefficients + in ``base_ring``, with one generator for each vertex in the + simplicial complex, by the ideal generated by the products + of those vertices which do not form faces in it Thus the ideal is generated by the products corresponding to the minimal nonfaces of the simplicial complex. @@ -3553,7 +3565,7 @@ def stanley_reisner_ring(self, base_ring=ZZ): More precisely, this is a quotient of a polynomial ring with one generator for each vertex. If the name of a - vertex is a non-negative integer, then the corresponding + vertex is a nonnegative integer, then the corresponding polynomial generator is named ``'x'`` followed by that integer (e.g., ``'x2'``, ``'x3'``, ``'x5'``, ...). Otherwise, the polynomial generators are given the same names as the vertices. @@ -3589,8 +3601,10 @@ def alexander_dual(self, is_mutable=True): Thus find the minimal nonfaces and take their complements to find the facets in the Alexander dual. - :param is_mutable: Determines if the output is mutable - :type is_mutable: boolean; optional, default ``True`` + INPUT: + + - ``is_mutable`` -- boolean (default: ``True``); determine whether + the output is mutable EXAMPLES:: @@ -3643,9 +3657,9 @@ def stellar_subdivision(self, simplex, inplace=False, is_mutable=True): INPUT: - ``simplex`` -- a simplex face of ``self`` - - ``inplace`` -- (default: ``False``) boolean; determines if the + - ``inplace`` -- boolean (default: ``False``); determines if the operation is done on ``self`` or on a copy - - ``is_mutable`` -- (default: ``True``) boolean; determines if the + - ``is_mutable`` -- boolean (default: ``True``); determines if the output is mutable OUTPUT: @@ -3693,7 +3707,7 @@ def stellar_subdivision(self, simplex, inplace=False, is_mutable=True): if inplace and self._is_immutable: raise ValueError("this simplicial complex is not mutable") - if not Simplex(simplex) in self: + if Simplex(simplex) not in self: raise ValueError("the face to subdivide is not a face of self") if inplace: @@ -3772,9 +3786,10 @@ def delta_complex(self, sort_simplices=False): simplicial complex: it has same simplices with the same boundaries. - :param sort_simplices: if ``True``, sort the list of simplices in - each dimension - :type sort_simplices: boolean; optional, default ``False`` + INPUT: + + - ``sort_simplices`` -- boolean (default: ``False``); if ``True``, sort + the list of simplices in each dimension EXAMPLES:: @@ -3831,7 +3846,9 @@ def n_skeleton(self, n): The `n`-skeleton of a simplicial complex is obtained by discarding all of the simplices in dimensions larger than `n`. - :param n: non-negative integer + INPUT: + + - ``n`` -- nonnegative integer EXAMPLES:: @@ -3859,9 +3876,10 @@ def _contractible_subcomplex(self, verbose=False): Find a contractible subcomplex `L` of this simplicial complex, preferably one which is as large as possible. - :param verbose: If ``True``, print some messages as the simplicial - complex is computed. - :type verbose: boolean; optional, default ``False`` + INPUT: + + - ``verbose`` -- boolean (default: ``False``); if ``True``, print some + messages as the simplicial complex is computed Motivation: if `K` is the original complex and if `L` is contractible, then the relative homology `H_*(K,L)` is @@ -3905,12 +3923,14 @@ def _enlarge_subcomplex(self, subcomplex, verbose=False): `H_{*}(K,L)` will be smaller than that for computing `H_{*}(K,S)`, so the computations should be faster. - :param subcomplex: a subcomplex of this simplicial complex - :param verbose: If ``True``, print some messages as the simplicial - complex is computed. - :type verbose: boolean; optional, default ``False`` - :return: a complex `L` containing ``subcomplex`` and contained - in ``self``, homotopy equivalent to ``subcomplex``. + INPUT: + + - ``subcomplex`` -- a subcomplex of this simplicial complex + - ``verbose`` -- boolean (default: ``False``); if ``True``, print some + messages as the simplicial complex is computed + + OUTPUT: a complex `L` containing ``subcomplex`` and contained + in ``self``, homotopy equivalent to ``subcomplex`` Algorithm: start with the subcomplex `S` and loop through the facets of `K` which are not in `S`. For each one, see whether @@ -4096,16 +4116,16 @@ def fundamental_group(self, base_point=None, simplify=True): INPUT: - - ``base_point`` (default: None) -- if this complex is + - ``base_point`` -- (default: ``None``) if this complex is not path-connected, then specify a vertex; the fundamental group is computed with that vertex as a base point. If the complex is path-connected, then you may specify a vertex or leave this as its default setting of ``None``. (If this complex is path-connected, then this argument is ignored.) - - ``simplify`` (bool, optional True) -- if False, then return a + - ``simplify`` -- boolean (default: ``True``); then return a presentation of the group in terms of generators and - relations. If True, the default, simplify as much as GAP is + relations. If ``True``, the default, simplify as much as GAP is able to. Algorithm: we compute the edge-path group -- see @@ -4420,12 +4440,10 @@ def _Hom_(self, other, category=None): # @cached_method when we switch to immutable SimplicialComplex def _is_numeric(self): """ - Test whether all vertices are labeled by integers - - OUTPUT: + Test whether all vertices are labeled by integers. - Boolean. Whether all vertices are labeled by (not necessarily - consecutive) integers. + OUTPUT: boolean; whether all vertices are labeled by (not necessarily + consecutive) integers EXAMPLES:: @@ -4442,7 +4460,7 @@ def _is_numeric(self): # @cached_method when we switch to immutable SimplicialComplex def _translation_to_numeric(self): """ - Return a dictionary enumerating the vertices + Return a dictionary enumerating the vertices. See also :meth:`_translation_from_numeric`, which returns the inverse map. @@ -4470,7 +4488,7 @@ def _translation_to_numeric(self): # @cached_method when we switch to immutable SimplicialComplex def _translation_from_numeric(self): """ - Return a dictionary mapping vertex indices to vertices + Return a dictionary mapping vertex indices to vertices. See also :meth:`_translation_to_numeric`, which returns the inverse map. @@ -4644,11 +4662,11 @@ def is_balanced(self, check_purity=False, certificate=False): INPUT: - - ``check_purity`` -- (default: ``False``) if this is ``True``, + - ``check_purity`` -- boolean (default: ``False``); if this is ``True``, require that ``self`` be pure as well as balanced - - ``certificate`` -- (default: ``False``) if this is ``True`` and - ``self`` is balanced, then return a `d`-coloring of the 1-skeleton. + - ``certificate`` -- boolean (default: ``False``); if this is ``True`` and + ``self`` is balanced, then return a `d`-coloring of the 1-skeleton EXAMPLES: @@ -4712,11 +4730,11 @@ def is_partitionable(self, certificate=False, INPUT: - - ``certificate`` -- (default: ``False``) If ``True``, + - ``certificate`` -- boolean (default: ``False``); if ``True``, and ``self`` is partitionable, then return a list of pairs `(R,F)` that form a partitioning. - - ``solver`` -- (default: ``None``) Specify a Mixed Integer Linear Programming + - ``solver`` -- (default: ``None``) specifies a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the default one is used. For more information on MILP solvers and which default solver is used, see the method @@ -4725,7 +4743,7 @@ def is_partitionable(self, certificate=False, :class:`MixedIntegerLinearProgram `. - ``integrality_tolerance`` -- parameter for use with MILP solvers over an - inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values` EXAMPLES: @@ -4817,7 +4835,7 @@ def bigraded_betti_numbers(self, base_ring=ZZ, verbose=False): - ``base_ring`` -- (default: ``ZZ``) the base ring used when computing homology - - ``verbose`` -- (default: ``False``) if ``True``, print + - ``verbose`` -- boolean (default: ``False``); if ``True``, print messages during the computation, which indicate in which subcomplexes non-trivial homologies appear @@ -4923,7 +4941,7 @@ def bigraded_betti_number(self, a, b, base_ring=ZZ, verbose=False): - ``base_ring`` -- (default: ``ZZ``) the base ring used when computing homology - - ``verbose`` -- (default: ``False``) if ``True``, print + - ``verbose`` -- boolean (default: ``False``); if ``True``, print messages during the computation, which indicate in which subcomplexes non-trivial homologies appear diff --git a/src/sage/topology/simplicial_complex_examples.py b/src/sage/topology/simplicial_complex_examples.py index aa9c704f765..97958848bb0 100644 --- a/src/sage/topology/simplicial_complex_examples.py +++ b/src/sage/topology/simplicial_complex_examples.py @@ -168,8 +168,8 @@ def matching(A, B): INPUT: - - ``A``, ``B`` -- list, tuple, or indeed anything which can be - converted to a set. + - ``A``, ``B`` -- list, tuple, or indeed anything which can be + converted to a set EXAMPLES:: @@ -204,7 +204,7 @@ class UniqueSimplicialComplex(SimplicialComplex, UniqueRepresentation): ``is_mutable`` and ``is_immutable`` are ignored: all instances of this class are immutable. The addition: - - ``name`` -- string (optional), the string representation for this complex. + - ``name`` -- string (optional); the string representation for this complex EXAMPLES:: @@ -274,7 +274,7 @@ def __init__(self, maximal_faces=None, name=None, **kwds): def _repr_(self): """ - Print representation + Print representation. If the argument ``name`` was specified when defining the complex, use that. Otherwise, use the print representation @@ -301,7 +301,7 @@ def Sphere(n): INPUT: - - ``n`` -- positive integer + - ``n`` -- positive integer EXAMPLES:: @@ -331,7 +331,7 @@ def Simplex(n): INPUT: - - ``n`` -- a non-negative integer + - ``n`` -- nonnegative integer OUTPUT: the simplicial complex consisting of the `n`-simplex on vertices `(0, 1, ..., n)` and all of its faces. @@ -435,11 +435,11 @@ def SurfaceOfGenus(g, orientable=True): INPUT: - - ``g`` -- a non-negative integer. The desired genus + - ``g`` -- nonnegative integer; the desired genus - - ``orientable`` -- boolean (default: ``True``). If - ``True``, return an orientable surface, and if ``False``, - return a non-orientable surface. + - ``orientable`` -- boolean (default: ``True``); if + ``True``, return an orientable surface, and if ``False``, + return a non-orientable surface. In the orientable case, return a sphere if `g` is zero, and otherwise return a `g`-fold connected sum of a torus with itself. @@ -481,7 +481,7 @@ def MooreSpace(q): INPUT: - - ``q`` -- integer, at least 2 + - ``q`` -- integer; at least 2 This is a simplicial complex with simplices of dimension 0, 1, and 2, such that its reduced homology is isomorphic to @@ -614,8 +614,8 @@ def QuaternionicProjectivePlane(): (3, 4, 6, 7, 11, 12, 13, 14, 15), # L (3, 4, 6, 7, 10, 12, 13, 14, 15)] # N - return UniqueSimplicialComplex([[g(index) for index in tuple] - for tuple in start_list + return UniqueSimplicialComplex([[g(index) for index in tup] + for tup in start_list for g in PermutationGroup([P, S])]) @@ -674,7 +674,7 @@ def RealProjectiveSpace(n): INPUT: - - ``n`` -- integer, the dimension of the real projective space + - ``n`` -- integer; the dimension of the real projective space to construct The first few cases are pretty trivial: @@ -1069,7 +1069,7 @@ def NotIConnectedGraphs(n, i): INPUT: - - ``n``, ``i`` -- non-negative integers with `i` at most `n` + - ``n``, ``i`` -- nonnegative integers with `i` at most `n` See Dumas et al. [DHSW2003]_ for information on computing its homology by computer, and see Babson et al. [BBLSW1999]_ for theory. For @@ -1124,7 +1124,7 @@ def MatchingComplex(n): INPUT: - - ``n`` -- positive integer. + - ``n`` -- positive integer See Dumas et al. [DHSW2003]_ for information on computing its homology by computer, and see Wachs [Wac2003]_ for an expository article about @@ -1201,7 +1201,7 @@ def ChessboardComplex(n, i): INPUT: - - ``n, i`` -- positive integers. + - ``n``, ``i`` -- positive integers See Dumas et al. [DHSW2003]_ for information on computing its homology by computer, and see Wachs [Wac2003]_ for an expository article about @@ -1234,7 +1234,7 @@ def ChessboardComplex(n, i): def RandomComplex(n, d, p=0.5): """ - A random ``d``-dimensional simplicial complex on ``n`` vertices. + A random `d`-dimensional simplicial complex on `n` vertices. INPUT: @@ -1242,8 +1242,7 @@ def RandomComplex(n, d, p=0.5): - ``d`` -- dimension of the complex - - ``p`` -- floating point number between 0 and 1 - (default: 0.5) + - ``p`` -- floating point number between 0 and 1 (default: 0.5) A random `d`-dimensional simplicial complex on `n` vertices, as defined for example by Meshulam and Wallach [MW2009]_, is @@ -1308,7 +1307,7 @@ def SumComplex(n, A): INPUT: - - ``n`` -- a positive integer + - ``n`` -- positive integer - ``A`` -- a subset of `\ZZ/(n)` @@ -1387,7 +1386,7 @@ def RandomTwoSphere(n): INPUT: - `n` -- an integer + - ``n`` -- integer OUTPUT: @@ -1466,7 +1465,7 @@ def ShiftedComplex(generators): INPUT: - - ``generators`` -- a list of generators of the order ideal, which may + - ``generators`` -- list of generators of the order ideal, which may be lists, tuples or simplices EXAMPLES:: @@ -1586,9 +1585,9 @@ def FareyMap(p): INPUT: - - `p` -- a prime number + - ``p`` -- a prime number - The vertices are the non-zero pairs `(x,y)` in `\GF(p)^2` modulo + The vertices are the nonzero pairs `(x,y)` in `\GF(p)^2` modulo the identification of `(-x, -y)` with `(x,y)`. The triangles are the images of the base triangle ((1,0),(0,1),(1,1)) diff --git a/src/sage/topology/simplicial_complex_homset.py b/src/sage/topology/simplicial_complex_homset.py index 5a8052eeb4d..7b9aceb8b64 100644 --- a/src/sage/topology/simplicial_complex_homset.py +++ b/src/sage/topology/simplicial_complex_homset.py @@ -92,7 +92,7 @@ def __call__(self, f): """ INPUT: - - ``f`` -- a dictionary with keys exactly the vertices of the domain + - ``f`` -- dictionary with keys exactly the vertices of the domain and values vertices of the codomain EXAMPLES:: diff --git a/src/sage/topology/simplicial_complex_morphism.py b/src/sage/topology/simplicial_complex_morphism.py index e1f87f3ddd2..52a2d6e82b4 100644 --- a/src/sage/topology/simplicial_complex_morphism.py +++ b/src/sage/topology/simplicial_complex_morphism.py @@ -131,7 +131,6 @@ def is_SimplicialComplexMorphism(x): use 'isinstance(..., SimplicialComplexMorphism)' instead. See https://github.com/sagemath/sage/issues/38103 for details. True - """ from sage.misc.superseded import deprecation deprecation(38103, @@ -461,7 +460,7 @@ def associated_chain_complex_morphism(self, base_ring=ZZ, def image(self): """ - Computes the image simplicial complex of `f`. + Compute the image simplicial complex of `f`. EXAMPLES:: @@ -499,7 +498,6 @@ def image(self): Simplicial complex with vertex set (0, 1) and facets {(0, 1)} sage: z.image() Simplicial complex with vertex set (0, 2) and facets {(0, 2)} - """ fa = [self(i) for i in self.domain().facets()] return SimplicialComplex(fa, maximality_check=True) @@ -550,7 +548,6 @@ def is_injective(self): False sage: y.is_injective() True - """ v = [self._vertex_dictionary[i[0]] for i in self.domain().faces()[0]] for i in v: @@ -558,7 +555,7 @@ def is_injective(self): return False return True - def is_identity(self): + def is_identity(self) -> bool: """ If ``self`` is an identity morphism, returns ``True``. Otherwise, ``False``. @@ -591,18 +588,15 @@ def is_identity(self): """ if self.domain() != self.codomain(): return False - else: - f = {} - for i in self.domain().vertices(): - f[i] = i - if self._vertex_dictionary != f: - return False - else: - return True + + f = {i: i for i in self.domain().vertices()} + return self._vertex_dictionary == f def fiber_product(self, other, rename_vertices=True): """ - Fiber product of ``self`` and ``other``. Both morphisms should have + Fiber product of ``self`` and ``other``. + + Both morphisms should have the same codomain. The method returns a morphism of simplicial complexes, which is the morphism from the space of the fiber product to the codomain. @@ -648,7 +642,7 @@ def fiber_product(self, other, rename_vertices=True): def mapping_torus(self): r""" - The mapping torus of a simplicial complex endomorphism + The mapping torus of a simplicial complex endomorphism. The mapping torus is the simplicial complex formed by taking the product of the domain of ``self`` with a `4` point @@ -701,8 +695,8 @@ def induced_homology_morphism(self, base_ring=None, cohomology=False): - ``base_ring`` -- must be a field (default: ``QQ``) - - ``cohomology`` -- boolean (default: ``False``). If - ``True``, the map induced in cohomology rather than homology. + - ``cohomology`` -- boolean (default: ``False``); if + ``True``, the map induced in cohomology rather than homology EXAMPLES:: diff --git a/src/sage/topology/simplicial_set.py b/src/sage/topology/simplicial_set.py index 346de85f0b7..974feac8510 100644 --- a/src/sage/topology/simplicial_set.py +++ b/src/sage/topology/simplicial_set.py @@ -9,7 +9,7 @@ This module implements simplicial sets. A *simplicial set* `X` is a collection of sets `X_n` indexed by the -non-negative integers; the set `X_n` is called the set of +nonnegative integers; the set `X_n` is called the set of `n`-simplices. These sets are connected by maps .. MATH:: @@ -284,12 +284,12 @@ class AbstractSimplex_class(SageObject): INPUT: - - ``dim`` -- integer, the dimension - - ``degeneracies`` (optional) -- iterable, the indices of the + - ``dim`` -- integer; the dimension + - ``degeneracies`` -- (optional) iterable, the indices of the degeneracy maps - - ``underlying`` (optional) -- a non-degenerate simplex - - ``name`` (optional) -- string - - ``latex_name`` (optional) -- string + - ``underlying`` -- (optional) a non-degenerate simplex + - ``name`` -- (optional) string + - ``latex_name`` -- (optional) string Users should not call this directly, but instead use :func:`AbstractSimplex`. See that function for more documentation. @@ -302,11 +302,11 @@ def __init__(self, dim, degeneracies=(), underlying=None, name=None, INPUT: - - ``dim`` -- integer, the dimension - - ``degeneracies`` (optional) -- iterable, the indices of the degeneracy maps - - ``underlying`` (optional) -- a non-degenerate simplex - - ``name`` (optional) -- string - - ``latex_name`` (optional) -- string + - ``dim`` -- integer; the dimension + - ``degeneracies`` -- (optional) iterable, the indices of the degeneracy maps + - ``underlying`` -- (optional) a non-degenerate simplex + - ``name`` -- (optional) string + - ``latex_name`` -- (optional) string Users should not call this directly, but instead use :func:`AbstractSimplex`. See that function for more @@ -334,7 +334,7 @@ def __init__(self, dim, degeneracies=(), underlying=None, name=None, sage: AbstractSimplex(-3, None) Traceback (most recent call last): ... - ValueError: the dimension must be non-negative + ValueError: the dimension must be nonnegative sage: AbstractSimplex(0, (1,)) Traceback (most recent call last): @@ -378,7 +378,7 @@ def __init__(self, dim, degeneracies=(), underlying=None, name=None, except TypeError: raise ValueError('the dimension must be an integer') if dim < 0: - raise ValueError('the dimension must be non-negative') + raise ValueError('the dimension must be nonnegative') self._dim = dim if degeneracies: self._degens = standardize_degeneracies(*degeneracies) @@ -667,7 +667,7 @@ def degeneracies(self): def is_degenerate(self): """ - True if this simplex is degenerate. + Return ``True`` if this simplex is degenerate. EXAMPLES:: @@ -681,7 +681,7 @@ def is_degenerate(self): def is_nondegenerate(self): """ - True if this simplex is non-degenerate. + Return ``True`` if this simplex is non-degenerate. EXAMPLES:: @@ -717,7 +717,7 @@ def apply_degeneracies(self, *args): INPUT: - - ``args`` -- integers + - ``args`` -- integer EXAMPLES:: @@ -748,7 +748,7 @@ def apply_degeneracies(self, *args): sage: e.apply_degeneracies([1,0]) Traceback (most recent call last): ... - TypeError: degeneracies are indexed by non-negative integers; do not use an explicit list or tuple + TypeError: degeneracies are indexed by nonnegative integers; do not use an explicit list or tuple """ if not args: return self @@ -922,12 +922,12 @@ def __init__(self, dim, name=None, latex_name=None): INPUT: - - ``dim`` -- non-negative integer, the dimension + - ``dim`` -- nonnegative integer; the dimension - - ``name`` (optional) -- string, a name for this simplex. + - ``name`` -- (optional) string; a name for this simplex - - ``latex_name`` (optional) -- string, a name for this simplex to - use in the LaTeX representation. + - ``latex_name`` -- (optional) string; a name for this simplex to + use in the LaTeX representation EXAMPLES:: @@ -970,19 +970,19 @@ def AbstractSimplex(dim, degeneracies=(), underlying=None, INPUT: - - ``dim`` -- a non-negative integer, the dimension of the - underlying non-degenerate simplex. + - ``dim`` -- nonnegative integer; the dimension of the + underlying non-degenerate simplex - - ``degeneracies`` (default: ``None``) -- a list or tuple of - non-negative integers, the degeneracies to be applied. + - ``degeneracies`` -- (default: ``None``) list or tuple of + nonnegative integers, the degeneracies to be applied - - ``underlying`` (optional) -- a non-degenerate simplex to which - the degeneracies are being applied. + - ``underlying`` -- (optional) a non-degenerate simplex to which + the degeneracies are being applied - - ``name`` (optional) -- string, a name for this simplex. + - ``name`` -- (optional) string; a name for this simplex - - ``latex_name`` (optional) -- string, a name for this simplex to - use in the LaTeX representation. + - ``latex_name`` -- (optional) string; a name for this simplex to + use in the LaTeX representation So to define a simplex formed by applying the degeneracy maps `s_2 s_1` to a 1-simplex, call ``AbstractSimplex(1, (2, 1))``. @@ -1099,7 +1099,7 @@ class SimplicialSet_arbitrary(Parent): A simplicial set. A simplicial set `X` is a collection of sets `X_n`, the - *n-simplices*, indexed by the non-negative integers, together with + *n-simplices*, indexed by the nonnegative integers, together with maps .. MATH:: @@ -1278,9 +1278,9 @@ def alexander_whitney(self, simplex, dim_left): INPUT: - - ``dim_left`` -- integer, the dimension of the left-hand factor + - ``dim_left`` -- integer; the dimension of the left-hand factor - OUTPUT: a list containing the triple ``(c, left, right)``, + OUTPUT: list containing the triple ``(c, left, right)``, where ``left`` and ``right`` are the two simplices described above. If either ``left`` or ``right`` is degenerate, ``c`` is 0; otherwise, ``c`` is 1. This is so that, when used to @@ -1318,7 +1318,7 @@ def nondegenerate_simplices(self, max_dim=None): INPUT: - - ``max_dim`` -- optional, default ``None``. If specified, + - ``max_dim`` -- (default: ``None``) if specified, return the non-degenerate simplices of this dimension or smaller. This argument is required if this simplicial set is infinite. @@ -1388,11 +1388,11 @@ def cells(self, subcomplex=None, max_dim=None): INPUT: - - ``subcomplex`` (optional) -- a subsimplicial set of this + - ``subcomplex`` -- (optional) a subsimplicial set of this simplicial set. If ``subcomplex`` is specified, then return the simplices in the quotient by the subcomplex. - - ``max_dim`` -- optional, default ``None``. If specified, + - ``max_dim`` -- (default: ``None``) if specified, return the non-degenerate simplices of this dimension or smaller. This argument is required if this simplicial set is infinite. @@ -1469,7 +1469,7 @@ def n_cells(self, n, subcomplex=None): - ``n`` -- the dimension - - ``subcomplex`` (default: ``None``) -- a subcomplex + - ``subcomplex`` -- (default: ``None``) a subcomplex of this cell complex. Return the cells which are in the quotient by this subcomplex. @@ -1603,14 +1603,14 @@ def constant_map(self, codomain=None, point=None): INPUT: - - ``codomain`` -- optional, default ``None``. If ``None``, the + - ``codomain`` -- (default: ``None``) if ``None``, the codomain is the standard one-point space constructed by :func:`Point`. Otherwise, either the codomain must be a pointed simplicial set, in which case the map is constant at the base point, or ``point`` must be specified. - - ``point`` -- optional, default ``None``. If specified, it + - ``point`` -- (default: ``None``) if specified, it must be a 0-simplex in the codomain, and it will be the - target of the constant map. + target of the constant map EXAMPLES:: @@ -1896,24 +1896,24 @@ def chain_complex(self, dimensions=None, base_ring=ZZ, augmented=False, chain complex in those dimensions, setting the chain groups in all other dimensions to zero. - - ``base_ring`` (default: ``ZZ``) -- commutative ring + - ``base_ring`` -- (default: `\ZZ`) commutative ring - - ``augmented`` (default: ``False``) -- if ``True``, + - ``augmented`` -- boolean (default: ``False``); if ``True``, return the augmented chain complex (that is, include a class - in dimension `-1` corresponding to the empty cell). + in dimension `-1` corresponding to the empty cell) - - ``cochain`` (default: ``False``) -- if ``True``, + - ``cochain`` -- boolean (default: ``False``); if ``True``, return the cochain complex (that is, the dual of the chain - complex). + complex) - - ``verbose`` (default: ``False``) -- ignored. + - ``verbose`` -- boolean (default: ``False``); ignored - - ``subcomplex`` (default: ``None``) -- if present, - compute the chain complex relative to this subcomplex. + - ``subcomplex`` -- (default: ``None``) if present, + compute the chain complex relative to this subcomplex - - ``check`` (default: ``False``) -- If ``True``, make + - ``check`` -- boolean (default: ``False``); if ``True``, make sure that the chain complex is actually a chain complex: - the differentials are composable and their product is zero. + the differentials are composable and their product is zero .. NOTE:: @@ -1959,14 +1959,14 @@ def homology(self, dim=None, **kwds): INPUT: - - ``dim`` (default: ``None`` -- If ``None``, then + - ``dim`` -- (default: ``None``) if ``None``, then return the homology in every dimension. If ``dim`` is an integer or list, return the homology in the given dimensions. (Actually, if ``dim`` is a list, return the homology in the range from ``min(dim)`` to ``max(dim)``.) - - ``base_ring`` (default: ``ZZ``) -- commutative - ring, must be ``ZZ`` or a field. + - ``base_ring`` -- (default: ``ZZ``) commutative + ring; must be ``ZZ`` or a field Other arguments are also allowed: see the documentation for :meth:`.cell_complex.GenericCellComplex.homology`. @@ -2037,14 +2037,14 @@ def cohomology(self, dim=None, **kwds): INPUT: - - ``dim`` (default: ``None`` -- If ``None``, then + - ``dim`` -- (default: ``None``) if ``None``, then return the homology in every dimension. If ``dim`` is an integer or list, return the homology in the given dimensions. (Actually, if ``dim`` is a list, return the homology in the range from ``min(dim)`` to ``max(dim)``.) - - ``base_ring`` (default: ``ZZ``) -- commutative - ring, must be ``ZZ`` or a field. + - ``base_ring`` -- (default: ``ZZ``) commutative + ring; must be ``ZZ`` or a field Other arguments are also allowed, the same as for the :meth:`homology` method -- see @@ -2086,19 +2086,19 @@ def betti(self, dim=None, subcomplex=None): r""" The Betti numbers of this simplicial complex as a dictionary (or a single Betti number, if only one dimension is given): - the ith Betti number is the rank of the ith homology group. + the `i`-th Betti number is the rank of the `i`-th homology group. INPUT: - - ``dim`` (default: ``None`` -- If ``None``, then + - ``dim`` -- (default: ``None``) if ``None``, then return the homology in every dimension. If ``dim`` is an integer or list, return the homology in the given dimensions. (Actually, if ``dim`` is a list, return the homology in the range from ``min(dim)`` to ``max(dim)``.) - - ``subcomplex`` (default: ``None``) -- a subcomplex - of this cell complex. Compute the Betti numbers of the - homology relative to this subcomplex. + - ``subcomplex`` -- (default: ``None``) a subcomplex + of this cell complex. Compute the Betti numbers of the + homology relative to this subcomplex. .. NOTE:: @@ -2119,16 +2119,17 @@ def betti(self, dim=None, subcomplex=None): sage: BC3.betti(range(4)) # needs sage.groups sage.modules {0: 1, 1: 0, 2: 0, 3: 0} """ - dict = {} + dic = {} H = self.homology(dim, base_ring=QQ, subcomplex=subcomplex) try: for n in H.keys(): - dict[n] = H[n].dimension() + dic[n] = H[n].dimension() if n == 0: - dict[n] += 1 - return dict + dic[n] += 1 except AttributeError: return H.dimension() + else: + return dic def n_chains(self, n, base_ring=ZZ, cochains=False): r""" @@ -2147,7 +2148,7 @@ def n_chains(self, n, base_ring=ZZ, cochains=False): The only difference between chains and cochains is notation: the generator corresponding to the dual of a simplex - ``sigma`` is written as ``"\chi_sigma"`` in the group of + ``sigma`` is written as ``'\chi_sigma'`` in the group of cochains. EXAMPLES:: @@ -2188,10 +2189,10 @@ def quotient(self, subcomplex, vertex_name='*'): - ``subcomplex`` -- subsimplicial set of this simplicial set, or a list, tuple, or set of simplices defining a - subsimplicial set. + subsimplicial set - - ``vertex_name`` (optional) -- string, name to be given to the new - vertex. By default, use ``'*'``. + - ``vertex_name`` -- string (default: ``'*'``); name to be given to the + new vertex In Sage, from a quotient simplicial set, you can recover the ambient space, the subcomplex, and (if the ambient space is @@ -2898,8 +2899,7 @@ def suspension(self, n=1): INPUT: - - ``n`` (default: 1) -- integer, suspend this many - times. + - ``n`` -- integer (default: 1); suspend this many times If this simplicial set `X` is not pointed, return the suspension: the quotient `CX/X`, where `CX` is the (ordinary, @@ -2930,12 +2930,12 @@ def suspension(self, n=1): sage: RP4.suspension(-3) # needs sage.groups Traceback (most recent call last): ... - ValueError: n must be non-negative + ValueError: n must be nonnegative """ from .simplicial_set_constructions import \ SuspensionOfSimplicialSet, SuspensionOfSimplicialSet_finite if n < 0: - raise ValueError('n must be non-negative') + raise ValueError('n must be nonnegative') if n == 0: return self if self.is_finite(): @@ -3020,7 +3020,7 @@ def _Hom_(self, other, category=None): INPUT: - ``other`` -- another simplicial set - - ``category`` -- optional, the category in which to compute + - ``category`` -- (optional) the category in which to compute the maps. By default this is ``SimplicialSets``, and it must be a subcategory of this or else an error is raised. @@ -3059,7 +3059,7 @@ def rename_latex(self, s): INPUT: - - ``s`` -- string, the LaTeX representation. Or ``s`` can be + - ``s`` -- string; the LaTeX representation. Or ``s`` can be ``None``, in which case the LaTeX name is unset. EXAMPLES:: @@ -3140,7 +3140,7 @@ class SimplicialSet_finite(SimplicialSet_arbitrary, GenericCellComplex): A finite simplicial set. A simplicial set `X` is a collection of sets `X_n`, the - *n-simplices*, indexed by the non-negative integers, together with + *n-simplices*, indexed by the nonnegative integers, together with face maps `d_i` and degeneracy maps `s_j`. A simplex is *degenerate* if it is in the image of some `s_j`, and a simplicial set is *finite* if there are only finitely many non-degenerate @@ -3148,26 +3148,26 @@ class SimplicialSet_finite(SimplicialSet_arbitrary, GenericCellComplex): INPUT: - - ``data`` -- the data defining the simplicial set. See below for - details. + - ``data`` -- the data defining the simplicial set; see below for + details - - ``base_point`` (default: ``None``) -- 0-simplex in this + - ``base_point`` -- (default: ``None``) 0-simplex in this simplicial set, its base point - - ``name`` (default: ``None``) -- string, the name of the + - ``name`` -- string (default: ``None``); the name of the simplicial set - - ``check`` (default: ``True``) -- boolean. If ``True``, + - ``check`` -- boolean (default: ``True``); if ``True``, check the simplicial identity on the face maps when defining the - simplicial set. + simplicial set - - ``category`` (default: ``None``) -- the category in + - ``category`` -- (default: ``None``) the category in which to define this simplicial set. The default is either finite simplicial sets or finite pointed simplicial sets, depending on whether a base point is defined. - - ``latex_name`` (default: ``None``) -- string, the LaTeX - representation of the simplicial set. + - ``latex_name`` -- string (default: ``None``); the LaTeX + representation of the simplicial set ``data`` should have one of the following forms: it could be a simplicial complex or `\Delta`-complex, in case it is converted to @@ -3617,22 +3617,22 @@ def chain_complex(self, dimensions=None, base_ring=ZZ, augmented=False, chain complex in those dimensions, setting the chain groups in all other dimensions to zero. - - ``base_ring`` (default: ``ZZ``) -- commutative ring + - ``base_ring`` -- commutative ring (default: `\ZZ`) - - ``augmented`` (default: ``False``) -- if ``True``, + - ``augmented`` -- boolean (default: ``False``); if ``True``, return the augmented chain complex (that is, include a class in dimension `-1` corresponding to the empty cell). - - ``cochain`` (default: ``False``) -- if ``True``, + - ``cochain`` -- boolean (default: ``False``); if ``True``, return the cochain complex (that is, the dual of the chain complex). - - ``verbose`` (default: ``False``) -- ignored. + - ``verbose`` -- boolean (default: ``False``); ignored - - ``subcomplex`` (default: ``None``) -- if present, - compute the chain complex relative to this subcomplex. + - ``subcomplex`` -- (default: ``None``) if present, + compute the chain complex relative to this subcomplex - - ``check`` (default: ``False``) -- If ``True``, make + - ``check`` -- boolean (default: ``False``); if ``True``, make sure that the chain complex is actually a chain complex: the differentials are composable and their product is zero. @@ -3784,8 +3784,7 @@ def algebraic_topological_model(self, base_ring=None): INPUT: - - ``base_ring`` -- coefficient ring (default: - ``QQ``). Must be a field. + - ``base_ring`` -- coefficient ring (default: ``QQ``); must be a field Denote by `C` the chain complex associated to this simplicial set. The algebraic topological model is a chain complex `M` @@ -3850,8 +3849,8 @@ def standardize_degeneracies(*L): INPUT: - - ``L`` -- list of integers, representing a composition of - degeneracies in a simplicial set. + - ``L`` -- list of integers representing a composition of + degeneracies in a simplicial set OUTPUT: @@ -3881,21 +3880,21 @@ def standardize_degeneracies(*L): sage: standardize_degeneracies(2, -1) Traceback (most recent call last): ... - ValueError: degeneracies are indexed by non-negative integers + ValueError: degeneracies are indexed by nonnegative integers sage: standardize_degeneracies([2, 1]) Traceback (most recent call last): ... - TypeError: degeneracies are indexed by non-negative integers; do not use an explicit list or tuple + TypeError: degeneracies are indexed by nonnegative integers; do not use an explicit list or tuple """ J = list(L) for m in J: try: if Integer(m) < 0: - raise ValueError('degeneracies are indexed by non-negative integers') + raise ValueError('degeneracies are indexed by nonnegative integers') except TypeError: # Likely if called via standard_degeneracies([1,2,3]) # rather than standard_degeneracies(1,2,3). - raise TypeError('degeneracies are indexed by non-negative integers; do not use an explicit list or tuple') + raise TypeError('degeneracies are indexed by nonnegative integers; do not use an explicit list or tuple') inadmissible = True while inadmissible: inadmissible = False @@ -3958,8 +3957,8 @@ def standardize_face_maps(*L): INPUT: - - ``L`` -- list of integers, representing a composition of - face maps in a simplicial set. + - ``L`` -- list of integers representing a composition of + face maps in a simplicial set OUTPUT: @@ -3985,7 +3984,7 @@ def standardize_face_maps(*L): J = list(L) for m in J: if Integer(m) < 0: - raise ValueError('faces are indexed by non-negative integers') + raise ValueError('faces are indexed by nonnegative integers') inadmissible = True while inadmissible: inadmissible = False @@ -4006,8 +4005,8 @@ def face_degeneracies(m, I): INPUT: - ``m`` -- integer - - ``I`` -- tuple ``(i_1, i_2, ..., i_n)`` of integers. We assume - that this sequence is strictly decreasing. + - ``I`` -- tuple ``(i_1, i_2, ..., i_n)`` of integers; we assume + that this sequence is strictly decreasing Using the simplicial identities (see :mod:`.simplicial_set`), we can rewrite @@ -4023,9 +4022,8 @@ def face_degeneracies(m, I): s_{j_1} s_{j_2} ... s_{j_n} d_t, \quad s_{j_1} s_{j_2} ... s_{j_{n-1}}. - - OUTPUT: the pair ``(J, t)`` or ``(J, None)``. ``J`` is returned as - a list. + OUTPUT: the pair ``(J, t)`` or ``(J, None)``; ``J`` is returned as + a list EXAMPLES:: diff --git a/src/sage/topology/simplicial_set_constructions.py b/src/sage/topology/simplicial_set_constructions.py index 13f7c27e4f6..4e17179e8bf 100644 --- a/src/sage/topology/simplicial_set_constructions.py +++ b/src/sage/topology/simplicial_set_constructions.py @@ -247,7 +247,7 @@ def __init__(self, maps=None): INPUT: - - ``maps`` -- a list or tuple of morphisms of simplicial sets + - ``maps`` -- list or tuple of morphisms of simplicial sets If only a single map `f: X \to Y` is given, then return `X`. If no maps are given, return the one-point simplicial @@ -381,7 +381,7 @@ def defining_map(self, i): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -437,7 +437,7 @@ def __init__(self, maps=None): INPUT: - - ``maps`` -- a list or tuple of morphisms of simplicial sets + - ``maps`` -- list or tuple of morphisms of simplicial sets EXAMPLES:: @@ -663,7 +663,7 @@ def universal_property(self, *maps): INPUT: - ``maps`` -- maps from a simplicial set `Z` to the "factors" - `X_i` forming the pullback. + `X_i` forming the pullback If the pullback `P` is formed by maps `f_i: X_i \to Y`, then given maps `g_i: Z \to X_i` such that `f_i g_i = f_j g_j` for @@ -741,7 +741,7 @@ def factor(self, i): INPUT: - - ``i`` -- integer, the index of the factor + - ``i`` -- integer; the index of the factor EXAMPLES:: @@ -784,7 +784,7 @@ def __init__(self, factors=None): INPUT: - - ``factors`` -- a list or tuple of simplicial sets + - ``factors`` -- list or tuple of simplicial sets Return the product of the simplicial sets in ``factors``. @@ -922,9 +922,9 @@ def factor(self, i, as_subset=False): INPUT: - - ``i`` -- integer, the index of the factor + - ``i`` -- integer; the index of the factor - - ``as_subset`` -- boolean, optional (default ``False``) + - ``as_subset`` -- boolean (default: ``False``) If ``as_subset`` is ``True``, return the `i`-th factor as a subsimplicial set of the product, identifying it with its @@ -972,7 +972,7 @@ def factor(self, i, as_subset=False): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -989,7 +989,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -1051,7 +1051,7 @@ def projection_map(self, i): INPUT: - - ``i`` -- integer, the index of the projection map + - ``i`` -- integer; the index of the projection map EXAMPLES:: @@ -1158,8 +1158,8 @@ def __init__(self, maps=None, vertex_name=None): INPUT: - - ``maps`` -- a list or tuple of morphisms of simplicial sets - - ``vertex_name`` -- optional, default ``None`` + - ``maps`` -- list or tuple of morphisms of simplicial sets + - ``vertex_name`` -- (default: ``None``) If only a single map `f: X \to Y` is given, then return `Y`. If no maps are given, return the empty simplicial @@ -1366,7 +1366,7 @@ def defining_map(self, i): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -1427,8 +1427,8 @@ def __init__(self, maps=None, vertex_name=None): INPUT: - - ``maps`` -- a list or tuple of morphisms of simplicial sets - - ``vertex_name`` -- optional, default ``None`` + - ``maps`` -- list or tuple of morphisms of simplicial sets + - ``vertex_name`` -- (default: ``None``) EXAMPLES:: @@ -1623,12 +1623,12 @@ def structure_map(self, i): def universal_property(self, *maps): r""" - Return the map induced by ``maps`` + Return the map induced by ``maps``. INPUT: - ``maps`` -- maps "factors" `Y_i` forming the pushout to a - fixed simplicial set `Z`. + fixed simplicial set `Z` If the pushout `P` is formed by maps `f_i: X \to Y_i`, then given maps `g_i: Y_i \to Z` such that `g_i f_i = g_j f_j` for @@ -1697,7 +1697,7 @@ def __init__(self, inclusion, vertex_name='*'): - ``inclusion`` -- inclusion map of a subcomplex (= subsimplicial set) of a simplicial set - - ``vertex_name`` -- optional, default ``'*'`` + - ``vertex_name`` -- string (default: ``'*'``) A subcomplex `A` comes equipped with the inclusion map `A \to X` to its ambient complex `X`, and this constructs the @@ -1829,7 +1829,7 @@ def n_skeleton(self, n): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -1841,7 +1841,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -1937,7 +1937,7 @@ def __init__(self, factors=None): INPUT: - - ``factors`` -- a list or tuple of simplicial sets + - ``factors`` -- list or tuple of simplicial sets Return the smash product of the simplicial sets in ``factors``: the smash product `X \wedge Y` is defined to be @@ -1964,7 +1964,7 @@ def __init__(self, factors=None): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -1980,7 +1980,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2013,7 +2013,7 @@ def __init__(self, factors=None): INPUT: - - ``factors`` -- a list or tuple of simplicial sets + - ``factors`` -- list or tuple of simplicial sets Return the wedge of the simplicial sets in ``factors``: the wedge sum `X \vee Y` is formed by taking the disjoint @@ -2071,7 +2071,7 @@ def __init__(self, factors=None): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -2086,7 +2086,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2108,7 +2108,7 @@ def __init__(self, factors=None): INPUT: - - ``factors`` -- a tuple of simplicial sets + - ``factors`` -- tuple of simplicial sets If there are no factors, a point is returned. @@ -2210,7 +2210,7 @@ def __init__(self, factors=None): INPUT: - - ``factors`` -- a list or tuple of simplicial sets + - ``factors`` -- list or tuple of simplicial sets Discard any factors which are empty and return the disjoint union of the remaining simplicial sets in ``factors``. The @@ -2280,7 +2280,7 @@ def n_skeleton(self, n): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -2296,7 +2296,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2319,7 +2319,7 @@ def __init__(self, factors=None): INPUT: - - ``factors`` -- a tuple of simplicial sets + - ``factors`` -- tuple of simplicial sets Return the disjoint union of the simplicial sets in ``factors``. The disjoint union comes equipped with a map @@ -2372,7 +2372,7 @@ def __init__(self, base): INPUT: - - ``base`` -- return the cone on this simplicial set. + - ``base`` -- return the cone on this simplicial set Add a point `*` (which will become the base point) and for each simplex `\sigma` in ``base``, add both `\sigma` and a @@ -2439,7 +2439,7 @@ def n_skeleton(self, n): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -2450,7 +2450,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2467,7 +2467,7 @@ def __init__(self, base): INPUT: - - ``base`` -- return the cone on this simplicial set. + - ``base`` -- return the cone on this simplicial set Add a point `*` (which will become the base point) and for each simplex `\sigma` in ``base``, add both `\sigma` and a @@ -2561,7 +2561,7 @@ def __init__(self, base): INPUT: - - ``base`` -- return the cone on this simplicial set. + - ``base`` -- return the cone on this simplicial set Start with the unreduced cone: take ``base`` and add a point `*` (which will become the base point) and for each simplex @@ -2629,7 +2629,7 @@ def n_skeleton(self, n): def _repr_(self): """ - Print representation + Print representation. EXAMPLES:: @@ -2641,7 +2641,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -2659,7 +2659,7 @@ def __init__(self, base): INPUT: - - ``base`` -- return the cone on this simplicial set. + - ``base`` -- return the cone on this simplicial set Start with the unreduced cone: take ``base`` and add a point `*` (which will become the base point) and for each simplex @@ -2728,7 +2728,7 @@ def __init__(self, base): INPUT: - - ``base`` -- return the suspension of this simplicial set. + - ``base`` -- return the suspension of this simplicial set If this simplicial set ``X=base`` is not pointed, or if it is itself an unreduced suspension, return the unreduced @@ -2827,8 +2827,8 @@ def __repr_or_latex__(self, output_type=None): INPUT: - - ``output_type`` -- either ``"latex"`` for LaTeX output or - anything else for ``str`` output. + - ``output_type`` -- either ``'latex'`` for LaTeX output or + anything else for ``str`` output We use `S` to denote unreduced suspension, `\Sigma` for reduced suspension. @@ -2869,7 +2869,7 @@ def __repr_or_latex__(self, output_type=None): def _repr_(self): r""" - Print representation + Print representation. We use `S` to denote unreduced suspension, `\Sigma` for reduced suspension. @@ -2889,7 +2889,7 @@ def _repr_(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. We use `S` to denote unreduced suspension, `\Sigma` for reduced suspension. @@ -2919,7 +2919,7 @@ def __init__(self, base): r""" INPUT: - - ``base`` -- return the suspension of this finite simplicial set. + - ``base`` -- return the suspension of this finite simplicial set See :class:`SuspensionOfSimplicialSet` for more information. diff --git a/src/sage/topology/simplicial_set_examples.py b/src/sage/topology/simplicial_set_examples.py index 1fc85df3f6e..367a00413b7 100644 --- a/src/sage/topology/simplicial_set_examples.py +++ b/src/sage/topology/simplicial_set_examples.py @@ -30,7 +30,7 @@ # **************************************************************************** import re -import os +from pathlib import Path from sage.env import SAGE_ENV from sage.misc.cachefunc import cached_method, cached_function @@ -48,6 +48,8 @@ from sage.misc.lazy_import import lazy_import lazy_import('sage.categories.simplicial_sets', 'SimplicialSets') +kenzo_path = Path(SAGE_ENV['SAGE_EXTCODE']) / 'kenzo' + # ###################################################################### # The nerve of a finite monoid, used in sage.categories.finite_monoid. @@ -96,7 +98,7 @@ def __init__(self, monoid): # of monoid elements). Omit the base point. self._simplex_data = () - def __eq__(self, other): + def __eq__(self, other) -> bool: """ Return ``True`` if ``self`` and ``other`` are equal. @@ -119,7 +121,7 @@ def __eq__(self, other): and self._monoid == other._monoid and self.base_point() == other.base_point()) - def __ne__(self, other): + def __ne__(self, other) -> bool: """ Return the negation of `__eq__`. @@ -214,13 +216,13 @@ def n_skeleton(self, n): face_dict[(g,)] = x start = 1 - for d in range(start+1, n+1): + for d in range(start + 1, n + 1): for g in monoid: if g == one: continue new_faces = {} for t in face_dict.keys(): - if len(t) != d-1: + if len(t) != d - 1: continue # chain: chain of group elements to multiply, # as a tuple. @@ -235,8 +237,8 @@ def n_skeleton(self, n): # Compute faces of x. faces = [face_dict[chain[1:]]] - for i in range(d-1): - product = chain[i] * chain[i+1] + for i in range(d - 1): + product = chain[i] * chain[i + 1] if product == one: # Degenerate. if d == 2: @@ -294,11 +296,11 @@ def Sphere(n): w_0 = AbstractSimplex(0, name='w_0') return SimplicialSet_finite({v_0: None, w_0: None}, base_point=v_0, name='S^0') - degens = range(n-2, -1, -1) + degens = range(n - 2, -1, -1) degen_v = v_0.apply_degeneracies(*degens) sigma = AbstractSimplex(n, name='sigma_{}'.format(n), latex_name='\\sigma_{}'.format(n)) - return SimplicialSet_finite({sigma: [degen_v] * (n+1)}, base_point=v_0, + return SimplicialSet_finite({sigma: [degen_v] * (n + 1)}, base_point=v_0, name='S^{}'.format(n), latex_name='S^{{{}}}'.format(n)) @@ -616,22 +618,20 @@ def ComplexProjectiveSpace(n): latex_name='CP^{2}') return K if n == 3: - file = os.path.join(SAGE_ENV['SAGE_EXTCODE'], 'kenzo', 'CP3.txt') + file = kenzo_path / 'CP3.txt' data = simplicial_data_from_kenzo_output(file) - v = [_ for _ in data.keys() if _.dimension() == 0][0] - K = SimplicialSet_finite(data, base_point=v, name='CP^3', - latex_name='CP^{3}') - return K + v = [sigma for sigma in data if sigma.dimension() == 0][0] + return SimplicialSet_finite(data, base_point=v, name='CP^3', + latex_name='CP^{3}') if n == 4: - file = os.path.join(SAGE_ENV['SAGE_EXTCODE'], 'kenzo', 'CP4.txt') + file = kenzo_path / 'CP4.txt' data = simplicial_data_from_kenzo_output(file) - v = [_ for _ in data.keys() if _.dimension() == 0][0] - K = SimplicialSet_finite(data, base_point=v, name='CP^4', - latex_name='CP^{4}') - return K + v = [sigma for sigma in data if sigma.dimension() == 0][0] + return SimplicialSet_finite(data, base_point=v, name='CP^4', + latex_name='CP^{4}') -def simplicial_data_from_kenzo_output(filename): +def simplicial_data_from_kenzo_output(filename) -> dict: """ Return data to construct a simplicial set, given Kenzo output. @@ -649,14 +649,15 @@ def simplicial_data_from_kenzo_output(filename): sage: from sage.topology.simplicial_set_examples import simplicial_data_from_kenzo_output sage: from sage.topology.simplicial_set import SimplicialSet - sage: sphere = os.path.join(SAGE_ENV['SAGE_EXTCODE'], 'kenzo', 'S4.txt') + sage: from pathlib import Path + sage: sphere = Path(SAGE_ENV['SAGE_EXTCODE']) / 'kenzo' /'S4.txt' sage: S4 = SimplicialSet(simplicial_data_from_kenzo_output(sphere)) # needs pyparsing sage: S4.homology(reduced=False) # needs pyparsing {0: Z, 1: 0, 2: 0, 3: 0, 4: Z} """ from pyparsing import OneOrMore, nestedExpr - with open(filename, 'r') as f: + with open(filename) as f: data = f.read() dim = 0 start = 0 @@ -667,7 +668,7 @@ def simplicial_data_from_kenzo_output(filename): dim_idx = data.find('Dimension = {}:'.format(dim), start) while dim_idx != -1: start = dim_idx + len('Dimension = {}:'.format(dim)) - new_dim_idx = data.find('Dimension = {}:'.format(dim+1), start) + new_dim_idx = data.find('Dimension = {}:'.format(dim + 1), start) if new_dim_idx == -1: end = len(data) else: @@ -717,7 +718,7 @@ def simplicial_data_from_kenzo_output(filename): def HopfMap(): r""" - Return a simplicial model of the Hopf map `S^3 \to S^2` + Return a simplicial model of the Hopf map `S^3 \to S^2`. This is taken from Exemple II.1.19 in the thesis of Clemens Berger [Ber1991]_. @@ -813,7 +814,7 @@ def PresentationComplex(G): INPUT: - - "G" -- a finitely presented group + - ``G`` -- a finitely presented group EXAMPLES:: diff --git a/src/sage/topology/simplicial_set_morphism.py b/src/sage/topology/simplicial_set_morphism.py index 483fe4adef6..9d54e2e1b5e 100644 --- a/src/sage/topology/simplicial_set_morphism.py +++ b/src/sage/topology/simplicial_set_morphism.py @@ -81,11 +81,11 @@ def __call__(self, f, check=True): r""" INPUT: - - ``f`` -- a dictionary with keys the simplices of the domain + - ``f`` -- dictionary with keys the simplices of the domain and values simplices of the codomain - - ``check`` -- optional, default ``True``. Pass this to the - morphism constructor. + - ``check`` -- boolean (default ``True``); pass this to the + morphism constructor EXAMPLES:: @@ -151,9 +151,8 @@ def constant_map(self, point=None): INPUT: - - ``point`` -- optional, default ``None``. If specified, it - must be a 0-simplex in the codomain, and it will be the - target of the constant map. + - ``point`` -- (default: ``None``) if specified, it must be a 0-simplex + in the codomain, and it will be the target of the constant map If ``point`` is specified, it is the target of the constant map. Otherwise, if the codomain is pointed, the target is its @@ -300,7 +299,7 @@ def __iter__(self): def _latex_(self): r""" - LaTeX representation + LaTeX representation. EXAMPLES:: @@ -321,17 +320,16 @@ def __init__(self, data=None, domain=None, codomain=None, INPUT: - - ``data`` -- optional. Dictionary defining the map. + - ``data`` -- (optional) dictionary defining the map - ``domain`` -- simplicial set - ``codomain`` -- simplicial set - - ``constant`` -- optional: if not ``None``, then this should + - ``constant`` -- (default: ``None``) if not ``None``, then this should be a vertex in the codomain, in which case return the - constant map with this vertex as the target. - - ``identity`` -- optional: if ``True``, return the identity - morphism. - - ``check`` -- optional, default ``True``. If ``True``, check - that this is actually a morphism: it commutes with the face - maps. + constant map with this vertex as the target + - ``identity`` -- boolean (default: ``False``); if ``True``, return the + identity morphism + - ``check`` -- boolean (default: ``True``); if ``True``, check + that this is actually a morphism: it commutes with the face maps So to define a map, you must specify ``domain`` and ``codomain``. If the map is constant, specify the target (a @@ -600,9 +598,11 @@ def __ne__(self, other): def __call__(self, x): """ - INPUT: a simplex of the domain. + Return the image of ``x`` under this morphism. + + INPUT: - Return its image under this morphism. + - ``x`` -- a simplex of the domain EXAMPLES:: @@ -817,10 +817,11 @@ def is_injective(self): if self._is_identity: return True domain = self.domain() - for n in range(domain.dimension()+1): - input = domain.n_cells(n) - output = {self(sigma) for sigma in input if self(sigma).is_nondegenerate()} - if len(input) > len(output): + for n in range(domain.dimension() + 1): + domain_cells = domain.n_cells(n) + output = {self(sigma) for sigma in domain_cells + if self(sigma).is_nondegenerate()} + if len(domain_cells) > len(output): return False return True @@ -911,7 +912,7 @@ def pushout(self, *others): INPUT: - ``others`` -- morphisms of simplicial sets, the domains of - which must all equal that of ``self``. + which must all equal that of ``self`` This returns the pushout as a simplicial set. See :class:`sage.topology.simplicial_set_constructions.PushoutOfSimplicialSets` @@ -946,7 +947,7 @@ def pullback(self, *others): INPUT: - ``others`` -- morphisms of simplicial sets, the codomains of - which must all equal that of ``self``. + which must all equal that of ``self`` This returns the pullback as a simplicial set. See :class:`sage.topology.simplicial_set_constructions.PullbackOfSimplicialSets` @@ -1126,7 +1127,7 @@ def product(self, *others): r""" Return the product of this map with ``others``. - - ``others`` -- morphisms of simplicial sets. + - ``others`` -- morphisms of simplicial sets If the relevant maps are `f_i: X_i \to Y_i`, this returns the natural map `\prod X_i \to \prod Y_i`. @@ -1152,7 +1153,7 @@ def coproduct(self, *others): r""" Return the coproduct of this map with ``others``. - - ``others`` -- morphisms of simplicial sets. + - ``others`` -- morphisms of simplicial sets If the relevant maps are `f_i: X_i \to Y_i`, this returns the natural map `\amalg X_i \to \amalg Y_i`. @@ -1179,7 +1180,7 @@ def suspension(self, n=1): INPUT: - - ``n`` (optional) -- non-negative integer, default 1 + - ``n`` -- nonnegative integer (default: 1) EXAMPLES:: @@ -1244,7 +1245,7 @@ def n_skeleton(self, n, domain=None, codomain=None): - ``n`` -- the dimension - - ``domain`` -- optional, the domain. Specify this to + - ``domain`` -- (optional) the domain. Specify this to explicitly specify the domain; otherwise, Sage will attempt to compute it. Specifying this can be useful if the domain is built as a pushout or pullback, so trying to compute it @@ -1252,7 +1253,7 @@ def n_skeleton(self, n, domain=None, codomain=None): infinite recursion. (Users should not have to specify this, but it may be useful for developers.) - - ``codomain`` -- optional, the codomain. + - ``codomain`` -- (optional) the codomain EXAMPLES:: @@ -1303,10 +1304,10 @@ def associated_chain_complex_morphism(self, base_ring=ZZ, INPUT: - ``base_ring`` -- default ``ZZ`` - - ``augmented`` -- boolean, default ``False``. If ``True``, - return the augmented complex. - - ``cochain`` -- boolean, default ``False``. If ``True``, - return the cochain complex. + - ``augmented`` -- boolean (default: ``False``); if ``True``, + return the augmented complex + - ``cochain`` -- boolean (default: ``False``); if ``True``, + return the cochain complex EXAMPLES:: @@ -1373,14 +1374,14 @@ def associated_chain_complex_morphism(self, base_ring=ZZ, def induced_homology_morphism(self, base_ring=None, cohomology=False): """ - Return the map in (co)homology induced by this map + Return the map in (co)homology induced by this map. INPUT: - ``base_ring`` -- must be a field (default: ``QQ``) - - ``cohomology`` -- boolean (default: ``False``). If - ``True``, the map induced in cohomology rather than homology. + - ``cohomology`` -- boolean (default: ``False``); if + ``True``, the map induced in cohomology rather than homology EXAMPLES:: diff --git a/src/sage/typeset/ascii_art.py b/src/sage/typeset/ascii_art.py index 28024405d27..cf64d92a0b9 100644 --- a/src/sage/typeset/ascii_art.py +++ b/src/sage/typeset/ascii_art.py @@ -44,11 +44,12 @@ sage: shell.run_cell('%display ascii_art') sage: shell.run_cell("i = var('i')") # needs sage.symbolic sage: shell.run_cell('sum(factorial(i)*x^i, i, 0, 10)') # needs sage.symbolic - 10 9 8 7 6 5 4 3 - 3628800*x + 362880*x + 40320*x + 5040*x + 720*x + 120*x + 24*x + 6*x + 10 9 8 7 6 5 4 3... + 3628800*x + 362880*x + 40320*x + 5040*x + 720*x + 120*x + 24*x + 6*x... - 2 - + 2*x + x + 1 + ...2 + ...+ 2*x + x + 1 + sage: shell.run_cell('3/(7*x)') # needs sage.symbolic 3 --- @@ -196,14 +197,14 @@ class AsciiArt(CharacterArt): def ascii_art(*obj, **kwds): r""" - Return an ASCII art representation + Return an ASCII art representation. INPUT: - ``*obj`` -- any number of positional arguments, of arbitrary type. The objects whose ascii art representation we want. - - ``sep`` -- optional ``'sep=...'`` keyword argument (or ``'separator'``). + - ``sep`` -- (optional) ``'sep=...'`` keyword argument (or ``'separator'``). Anything that can be converted to ascii art (default: empty ascii art). The separator in-between a list of objects. Only used if more than one object given. @@ -212,9 +213,7 @@ def ascii_art(*obj, **kwds): - ``sep_baseline`` -- (default: 0) the baseline for the separator - OUTPUT: - - :class:`AsciiArt` instance. + OUTPUT: :class:`AsciiArt` instance EXAMPLES:: diff --git a/src/sage/typeset/character_art.py b/src/sage/typeset/character_art.py index 389584f3bcf..bc64866ed01 100644 --- a/src/sage/typeset/character_art.py +++ b/src/sage/typeset/character_art.py @@ -39,7 +39,7 @@ class CharacterArt(SageObject): def __init__(self, lines=[], breakpoints=[], baseline=None): r""" - Abstract base class for character art + Abstract base class for character art. INPUT: @@ -96,7 +96,7 @@ def __init__(self, lines=[], breakpoints=[], baseline=None): @classmethod def empty(cls): """ - Return the empty character art object + Return the empty character art object. EXAMPLES:: @@ -242,9 +242,7 @@ def _isatty(self): connected to a terminal. Otherwise you should treat ``stdout`` as being redirected to a file. - OUTPUT: - - Boolean + OUTPUT: boolean EXAMPLES:: @@ -276,7 +274,7 @@ def _terminal_width(self): import fcntl import termios import struct - rc = fcntl.ioctl(int(0), termios.TIOCGWINSZ, + rc = fcntl.ioctl(0, termios.TIOCGWINSZ, struct.pack('HHHH', sys.stdout.fileno(), 0, 0, 0)) h, w, hp, wp = struct.unpack('HHHH', rc) return w @@ -292,7 +290,7 @@ def _splitting_points(self, size, offset=0): - ``size`` -- the maximum width of each chunk - - ``offset`` -- (default: ``0``); the first chunk has width at most + - ``offset`` -- (default: ``0``) the first chunk has width at most ``size - offset`` TESTS:: @@ -303,7 +301,7 @@ def _splitting_points(self, size, offset=0): # We implement a custom iterator instead of repeatedly using # itertools.chain to prepend elements in order to avoid quadratic time # complexity - class PrependIterator(): + class PrependIterator: """ Iterator with support for prepending of elements. """ @@ -560,9 +558,7 @@ def width(self): r""" Return the length (width) of the ASCII art object. - OUTPUT: - - Integer. The number of characters in each line. + OUTPUT: integer; the number of characters in each line TESTS:: @@ -582,9 +578,7 @@ def height(self): r""" Return the height of the ASCII art object. - OUTPUT: - - Integer. The number of lines. + OUTPUT: integer; the number of lines TESTS:: diff --git a/src/sage/typeset/character_art_factory.py b/src/sage/typeset/character_art_factory.py index cbde3611858..d9b13a1cb05 100644 --- a/src/sage/typeset/character_art_factory.py +++ b/src/sage/typeset/character_art_factory.py @@ -26,7 +26,7 @@ def __init__(self, art_type, string_type, magic_method_name, parenthesis, square_bracet, curly_brace): r""" - Abstract base class for character art factory + Abstract base class for character art factory. This class is the common implementation behind :func:`~sage.typeset.ascii_art.ascii_art` and @@ -38,10 +38,10 @@ def __init__(self, :class:`~sage.typeset.character_art.CharacterArt`) - ``string_type`` -- type of strings (the lines in the - character art, e.g. ``str`` or ``unicode``). + character art, e.g. ``str`` or ``unicode``) - ``magic_method_name`` -- name of the Sage magic method (e.g. - ``'_ascii_art_'`` or ``'_unicode_art_'``). + ``'_ascii_art_'`` or ``'_unicode_art_'``) - ``parenthesis`` -- left/right pair of two multi-line symbols. The parenthesis, a.k.a. round brackets (used for printing @@ -78,9 +78,7 @@ def build(self, obj, baseline=None): we want - ``baseline`` -- (optional) the baseline of the object - OUTPUT: - - Character art object. + OUTPUT: character art object EXAMPLES:: @@ -136,11 +134,9 @@ def build(self, obj, baseline=None): def build_empty(self): """ - Return the empty character art object - - OUTPUT: + Return the empty character art object. - Character art instance. + OUTPUT: character art instance EXAMPLES:: @@ -152,11 +148,9 @@ def build_empty(self): def build_from_magic_method(self, obj, baseline=None): """ - Return the character art object created by the object's magic method + Return the character art object created by the object's magic method. - OUTPUT: - - Character art instance. + OUTPUT: character art instance EXAMPLES:: @@ -183,9 +177,7 @@ def build_from_string(self, obj, baseline=0): - ``obj`` -- utf-8 encoded byte string or unicode - ``baseline`` -- (default: 0) the baseline of the object - OUTPUT: - - Character art instance. + OUTPUT: character art instance EXAMPLES:: @@ -416,7 +408,7 @@ def build_tuple(self, t, baseline=0): def concatenate(self, iterable, separator, empty=None, baseline=0, nested=False): r""" - Concatenate multiple character art instances + Concatenate multiple character art instances. The breakpoints are set as the breakpoints of the ``separator`` together with the breakpoints of the objects in ``iterable``. @@ -477,11 +469,9 @@ def concatenate(self, iterable, separator, empty=None, baseline=0, top = separator._h - bot for obj in iterable: bot1 = obj.get_baseline() - if bot1 > bot: - bot = bot1 + bot = max(bot1, bot) top1 = obj._h - bot1 - if top1 > top: - top = top1 + top = max(top1, top) # bot + top is the new height def padded_line(obj, i): @@ -531,7 +521,7 @@ def parse_keywords(self, kwds): INPUT: - - ``kwds`` -- a dict + - ``kwds`` -- dictionary OUTPUT: diff --git a/src/sage/typeset/symbols.py b/src/sage/typeset/symbols.py index 1701603b408..7643880373f 100644 --- a/src/sage/typeset/symbols.py +++ b/src/sage/typeset/symbols.py @@ -63,36 +63,36 @@ def __init__(self, character, top, extension, bottom, middle_top=None, middle_bottom=None, top_2=None, bottom_2=None): """ - A multi-character (ascii/unicode art) symbol + A multi-character (ascii/unicode art) symbol. INPUT: - Instead of string, each of these can be unicode in Python 2: + Instead of a string, each of these can be unicode in Python 2: - - ``character`` -- string. The single-line version of the symbol. + - ``character`` -- string; the single-line version of the symbol - - ``top`` -- string. The top line of a multi-line symbol. + - ``top`` -- string; the top line of a multi-line symbol - - ``extension`` -- string. The extension line of a multi-line symbol (will - be repeated). + - ``extension`` -- string; the extension line of a multi-line symbol (will + be repeated) - - ``bottom`` -- string. The bottom line of a multi-line symbol. + - ``bottom`` -- string; the bottom line of a multi-line symbol - - ``middle`` -- optional string. The middle part, for example + - ``middle`` -- (optional) string; the middle part, for example in curly braces. Will be used only once for the symbol, and only if its height is odd. - - ``middle_top`` -- optional string. The upper half of the + - ``middle_top`` -- (optional) string; the upper half of the 2-line middle part if the height of the symbol is even. Will be used only once for the symbol. - - ``middle_bottom`` -- optional string. The lower half of the + - ``middle_bottom`` -- (optional) string; the lower half of the 2-line middle part if the height of the symbol is even. Will be used only once for the symbol. - - ``top_2`` -- optional string. The upper half of a 2-line symbol. + - ``top_2`` -- (optional) string; the upper half of a 2-line symbol - - ``bottom_2`` -- optional string. The lower half of a 2-line symbol. + - ``bottom_2`` -- (optional) string; the lower half of a 2-line symbol EXAMPLES:: @@ -117,7 +117,7 @@ def __init__(self, character, top, extension, bottom, def _repr_(self): """ - Return string representation + Return string representation. EXAMPLES:: @@ -129,15 +129,13 @@ def _repr_(self): def __call__(self, num_lines): r""" - Return the lines for a multi-line symbol + Return the lines for a multi-line symbol. INPUT: - - ``num_lines`` -- integer. The total number of lines. + - ``num_lines`` -- integer; the total number of lines - OUTPUT: - - List of strings / unicode strings. + OUTPUT: list of strings / unicode strings EXAMPLES:: @@ -162,13 +160,13 @@ def __call__(self, num_lines): def print_to_stdout(self, num_lines): """ - Print the multi-line symbol + Print the multi-line symbol. This method is for testing purposes. INPUT: - - ``num_lines`` -- integer. The total number of lines. + - ``num_lines`` -- integer; the total number of lines EXAMPLES:: @@ -195,7 +193,7 @@ class CompoundAsciiSymbol(CompoundSymbol): def character_art(self, num_lines): """ - Return the ASCII art of the symbol + Return the ASCII art of the symbol. EXAMPLES:: @@ -213,7 +211,7 @@ class CompoundUnicodeSymbol(CompoundSymbol): def character_art(self, num_lines): """ - Return the unicode art of the symbol + Return the unicode art of the symbol. EXAMPLES:: diff --git a/src/sage/typeset/unicode_art.py b/src/sage/typeset/unicode_art.py index 1d8e0933b5b..1fa4243304a 100644 --- a/src/sage/typeset/unicode_art.py +++ b/src/sage/typeset/unicode_art.py @@ -65,15 +65,14 @@ class UnicodeArt(CharacterArt): def unicode_art(*obj, **kwds): r""" - Return an unicode art representation + Return an unicode art representation. INPUT: - - ``*obj`` -- any number of positional arguments, of arbitrary type. The objects whose ascii art representation we want. - - ``sep`` -- optional ``'sep=...'`` keyword argument (or ``'separator'``). + - ``sep`` -- (optional) ``'sep=...'`` keyword argument (or ``'separator'``). Anything that can be converted to unicode art (default: empty unicode art). The separator in-between a list of objects. Only used if more than one object given. @@ -82,9 +81,7 @@ def unicode_art(*obj, **kwds): - ``sep_baseline`` -- (default: 0) the baseline for the separator - OUTPUT: - - :class:`UnicodeArt` instance. + OUTPUT: :class:`UnicodeArt` instance EXAMPLES:: diff --git a/src/sage/version.py b/src/sage/version.py index 0dfb7ac9745..12f1c856da0 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.4' -date = '2024-07-19' -banner = 'SageMath version 10.4, Release Date: 2024-07-19' +version = '10.5.beta8' +date = '2024-10-26' +banner = 'SageMath version 10.5.beta8, Release Date: 2024-10-26' diff --git a/src/sage_docbuild/__main__.py b/src/sage_docbuild/__main__.py index 844e1ebee17..a7b7b39880b 100644 --- a/src/sage_docbuild/__main__.py +++ b/src/sage_docbuild/__main__.py @@ -46,7 +46,7 @@ option: nitpicky) --check-nested check picklability of nested classes in DOCUMENT 'reference' --no-prune-empty-dirs - do not prune empty directories in the documentation sources + do not prune empty directories in the documentation source --use-cdns assume internet connection and use CDNs; in particular, use MathJax CDN -N, --no-colors do not color output; does not affect children @@ -325,7 +325,7 @@ def setup_parser(): help="check picklability of nested classes in DOCUMENT 'reference'") standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", action="store_true", - help="do not prune empty directories in the documentation sources") + help="do not prune empty directories in the documentation source") standard.add_argument("--use-cdns", dest="use_cdns", default=False, action="store_true", help="assume internet connection and use CDNs; in particular, use MathJax CDN") @@ -508,22 +508,24 @@ def excepthook(*exc_info): build_options.ABORT_ON_ERROR = not args.keep_going + # Set up Intersphinx cache + _ = IntersphinxCache() + + builder = get_builder(name) + if not args.no_prune_empty_dirs: # Delete empty directories. This is needed in particular for empty # directories due to "git checkout" which never deletes empty # directories it leaves behind. See Issue #20010. # Issue #31948: This is not parallelization-safe; use the option # --no-prune-empty-dirs to turn it off - for dirpath, dirnames, filenames in os.walk(SAGE_DOC_SRC, topdown=False): + for dirpath, dirnames, filenames in os.walk(builder.dir, topdown=False): if not dirnames + filenames: logger.warning('Deleting empty directory {0}'.format(dirpath)) os.rmdir(dirpath) - # Set up Intersphinx cache - _ = IntersphinxCache() - - builder = getattr(get_builder(name), typ) - builder() + build = getattr(builder, typ) + build() if __name__ == '__main__': diff --git a/src/sage_docbuild/builders.py b/src/sage_docbuild/builders.py index 871cc4705a2..ab39d93c280 100644 --- a/src/sage_docbuild/builders.py +++ b/src/sage_docbuild/builders.py @@ -1054,7 +1054,7 @@ def get_modules(self, filename): try: tag_name = line[line.index('feature_') + 8:].strip() for feature in all_features(): - if tag_name == feature.name.replace('.', '_'): + if tag_name == feature.name.replace('.', '_') and feature.is_present(): break else: skip = True diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 50d56ccfd05..18ce9f7663e 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -27,11 +27,12 @@ import sphinx.ext.intersphinx as intersphinx from sphinx import highlighting from sphinx.transforms import SphinxTransform +from sphinx.util.docutils import SphinxDirective from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer from sage.misc.sagedoc import extlinks from sage.env import SAGE_DOC_SRC, SAGE_DOC, PPLPY_DOCS, MATHJAX_DIR from sage.misc.latex_macros import sage_mathjax_macros -from sage.features import PythonModule +from sage.features.sphinx import JupyterSphinx from sage.features.all import all_features import sage.version @@ -56,12 +57,15 @@ 'sphinx_inline_tabs', 'IPython.sphinxext.ipython_directive', 'matplotlib.sphinxext.plot_directive', - 'jupyter_sphinx', ] +if JupyterSphinx().is_present(): + extensions.append('jupyter_sphinx') + jupyter_execute_default_kernel = 'sagemath' if SAGE_LIVE_DOC == 'yes': + JupyterSphinx().require() SAGE_JUPYTER_SERVER = os.environ.get('SAGE_JUPYTER_SERVER', 'binder') if SAGE_JUPYTER_SERVER.startswith('binder'): # format: "binder" or @@ -183,9 +187,6 @@ def sphinx_plot(graphics, **kwds): # Add any paths that contain templates here, relative to this directory. templates_path = [os.path.join(SAGE_DOC_SRC, 'common', 'templates'), 'templates'] -# The suffix of source filenames. -source_suffix = '.rst' - # The master toctree document. master_doc = 'index' @@ -447,10 +448,11 @@ def linkcode_resolve(domain, info): match = re.search(r'refs/pull/(\d+)/merge', github_ref) if match: pr_number = match.group(1) -is_develop_version = not version.split('.')[-1].isnumeric() +is_for_develop = github_ref.startswith('refs/heads/develop') is_for_github_pr = github_ref and match and pr_number +is_stable_release = version.split('.')[-1].isnumeric() -if is_develop_version or is_for_github_pr: # condition for announcement banner +if is_for_develop or is_for_github_pr or not is_stable_release: # condition for announcement banner # This URL is hardcoded in the file .github/workflows/doc-publish.yml. # See NETLIFY_ALIAS of the "Deploy to Netlify" step. ver = f'{version}' @@ -490,6 +492,7 @@ def linkcode_resolve(domain, info): 'custom-furo.css', 'custom-jupyter-sphinx.css', 'custom-codemirror-monokai.css', + 'custom-tabs.css', ] html_js_files = [ @@ -694,8 +697,8 @@ def add_page_context(app, pagename, templatename, context, doctree): context['reference_root'] = os.path.join(relpath, 'index.html') context['refsub'] = True if pagename.startswith('sage/'): - # This is for adding small edit button using Furo's feature: - # https://pradyunsg.me/furo/customisation/edit-button/#adding-an-edit-button + # This is for adding small view/edit buttons using Furo's feature: + # https://pradyunsg.me/furo/customisation/top-of-page-buttons/ # This works well if the source file is '.rst' file. But the '.rst' # files in the directory 'sage/' are generated by the Sphinx # autodoc from the Python or Cython source files. Hence we tweak @@ -703,7 +706,8 @@ def add_page_context(app, pagename, templatename, context, doctree): # source files are generated. suffix = '.py' if importlib.import_module(pagename.replace('/','.')).__file__.endswith('.py') else '.pyx' context['page_source_suffix'] = suffix - context['theme_source_edit_link'] = os.path.join(source_repository, f'blob/develop/src', '{filename}') + context['theme_source_view_link'] = os.path.join(source_repository, f'blob/develop/src', '{filename}') + context['theme_source_edit_link'] = os.path.join(source_repository, f'edit/develop/src', '{filename}') dangling_debug = False @@ -950,12 +954,13 @@ class SagecodeTransform(SphinxTransform): def apply(self): if self.app.builder.tags.has('html') or self.app.builder.tags.has('inventory'): - for node in self.document.traverse(nodes.literal_block): + for node in self.document.findall(nodes.literal_block): if node.get('language') is None and node.astext().startswith('sage:'): from docutils.nodes import container as Container, label as Label, literal_block as LiteralBlock, Text from sphinx_inline_tabs._impl import TabContainer parent = node.parent index = parent.index(node) + prev_node = node.previous_sibling() if isinstance(node.previous_sibling(), TabContainer): # Make sure not to merge inline tabs for adjacent literal blocks parent.insert(index, Text('')) @@ -970,6 +975,10 @@ def apply(self): content += node container += content parent.insert(index, container) + index += 1 + if isinstance(prev_node, nodes.paragraph): + prev_node['classes'].append('with-sage-tab') + if SAGE_PREPARSED_DOC == 'yes': # Tab for preparsed version from sage.repl.preparse import preparse @@ -1000,7 +1009,10 @@ def apply(self): preparsed_node = LiteralBlock(preparsed, preparsed, language='ipycon') content += preparsed_node container += content - parent.insert(index + 1, container) + parent.insert(index, container) + index += 1 + if isinstance(prev_node, nodes.paragraph): + prev_node['classes'].append('with-python-tab') if SAGE_LIVE_DOC == 'yes': # Tab for Jupyter-sphinx cell from jupyter_sphinx.ast import JupyterCellNode, CellInputNode @@ -1032,7 +1044,18 @@ def apply(self): content = Container("", is_div=True, classes=["tab-content"]) content += cell_node container += content - parent.insert(index + 1, container) + parent.insert(index, container) + index += 1 + if isinstance(prev_node, nodes.paragraph): + prev_node['classes'].append('with-sage-live-tab') + + +class Ignore(SphinxDirective): + + has_content = True + + def run(self): + return [] # This replaces the setup() in sage.misc.sagedoc_conf @@ -1048,6 +1071,12 @@ def setup(app): app.add_transform(SagemathTransform) if SAGE_LIVE_DOC == 'yes' or SAGE_PREPARSED_DOC == 'yes': app.add_transform(SagecodeTransform) + if not JupyterSphinx().is_present(): + app.add_directive("jupyter-execute", Ignore) + app.add_directive("jupyter-kernel", Ignore) + app.add_directive("jupyter-input", Ignore) + app.add_directive("jupyter-output", Ignore) + app.add_directive("thebe-button", Ignore) # When building the standard docs, app.srcdir is set to SAGE_DOC_SRC + # 'LANGUAGE/DOCNAME'. @@ -1069,12 +1098,7 @@ def setup(app): # https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#tags # https://www.sphinx-doc.org/en/master/usage/configuration.html#conf-tags # https://github.com/readthedocs/readthedocs.org/issues/4603#issuecomment-1411594800 -# Workaround to allow importing this file from other confs -if 'tags' not in locals(): - class Tags(set): - has = set.__contains__ - tags = Tags() - - -for feature in all_features(): - tags.add('feature_' + feature.name.replace('.', '_')) +def feature_tags(): + for feature in all_features(): + if feature.is_present(): + yield 'feature_' + feature.name.replace('.', '_') diff --git a/src/sage_docbuild/ext/sage_autodoc.py b/src/sage_docbuild/ext/sage_autodoc.py index d60d5efbf44..87e4e69d7bd 100644 --- a/src/sage_docbuild/ext/sage_autodoc.py +++ b/src/sage_docbuild/ext/sage_autodoc.py @@ -12,7 +12,7 @@ for those who like elaborate docstrings. This module is currently based on :mod:`sphinx.ext.autodoc` from Sphinx version -7.2.6. Compare (do diff) with the upstream source file +8.0.2. Compare (do diff) with the upstream source file `sphinx/ext/autodoc/__init__.py `_. @@ -31,27 +31,30 @@ - Kwankyu Lee (2018-12-26, 2022-11-08): rebased on the latest sphinx.ext.autodoc - Kwankyu Lee (2024-02-14): rebased on Sphinx 7.2.6 + +- François Bissey (2024-08-24): rebased on Sphinx 8.0.2 + +- François Bissey (2024-09-10): Tweaks to support python 3.9 (and older sphinx) as well """ from __future__ import annotations import functools import operator -import re import sys -import warnings +import re from inspect import Parameter, Signature -from typing import TYPE_CHECKING, Any, Callable, TypeVar +from typing import TYPE_CHECKING, Any, ClassVar, NewType, TypeVar from docutils.statemachine import StringList import sphinx from sphinx.config import ENUM, Config -from sphinx.deprecation import RemovedInSphinx80Warning +from sphinx.errors import PycodeError from sphinx.ext.autodoc.importer import get_class_members, import_module, import_object from sphinx.ext.autodoc.mock import ismock, mock, undecorate from sphinx.locale import _, __ -from sphinx.pycode import ModuleAnalyzer, PycodeError +from sphinx.pycode import ModuleAnalyzer from sphinx.util import inspect, logging from sphinx.util.docstrings import prepare_docstring, separate_metadata from sphinx.util.inspect import ( @@ -61,7 +64,13 @@ safe_getattr, stringify_signature, ) -from sphinx.util.typing import OptionSpec, get_type_hints, restify, stringify_annotation +from sphinx.util.typing import ( + ExtensionMetadata, + OptionSpec, + get_type_hints, + restify, + stringify_annotation, +) # ------------------------------------------------------------------ from sage.misc.sageinspect import (sage_getdoc_original, @@ -74,9 +83,8 @@ def getdoc(obj, *args, **kwargs): return sage_getdoc_original(obj) # ------------------------------------------------------------------ - if TYPE_CHECKING: - from collections.abc import Iterator, Sequence + from collections.abc import Callable, Iterator, Sequence from types import ModuleType from sphinx.application import Sphinx @@ -208,7 +216,7 @@ def merge_members_option(options: dict) -> None: return members = options.setdefault('members', []) - for key in {'private-members', 'special-members'}: + for key in ('private-members', 'special-members'): if key in options and options[key] not in (ALL, None): for member in options[key]: if member not in members: @@ -318,13 +326,6 @@ class ObjectMember: This is used for the result of `Documenter.get_module_members()` to represent each member of the object. - - .. Note:: - - An instance of this class behaves as a tuple of (name, object) - for compatibility to old Sphinx. The behavior will be dropped - in the future. Therefore extensions should not use the tuple - interface. """ def __init__(self, name: str, obj: Any, *, docstring: str | None = None, @@ -335,12 +336,6 @@ def __init__(self, name: str, obj: Any, *, docstring: str | None = None, self.skipped = skipped self.class_ = class_ - def __getitem__(self, index: int) -> Any: - warnings.warn('The tuple interface of ObjectMember is deprecated. ' - 'Use (obj.__name__, obj.object) instead.', - RemovedInSphinx80Warning, stacklevel=2) - return (self.__name__, self.object)[index] - class Documenter: """ @@ -370,7 +365,7 @@ class Documenter: #: true if the generated content may contain titles titles_allowed = True - option_spec: OptionSpec = { + option_spec: ClassVar[OptionSpec] = { 'no-index': bool_option, 'noindex': bool_option, } @@ -447,7 +442,7 @@ def parse_name(self) -> bool: # an autogenerated one matched = py_ext_sig_re.match(self.name) if matched is None: - logger.warning(__('invalid signature for auto%s (%r)') % (self.objtype, self.name), + logger.warning(__('invalid signature for auto%s (%r)'), self.objtype, self.name, type='autodoc') return False explicit_modname, path, base, tp_list, args, retann = matched.groups() @@ -512,9 +507,7 @@ def check_module(self) -> bool: subject = inspect.unpartial(self.object) modname = self.get_attr(subject, '__module__', None) - if modname and modname != self.modname: - return False - return True + return not modname or modname == self.modname def format_args(self, **kwargs: Any) -> str: """Format the argument signature of *self.object*. @@ -737,29 +730,16 @@ def is_filtered_inherited_member(name: str, obj: Any) -> bool: # process members and determine which to skip for obj in members: - try: - membername = obj.__name__ - member = obj.object - - # --------------------------------------------------- - # Issue #17455: Immediately skip lazy imports to avoid - # deprecation messages. - from sage.misc.lazy_import import LazyImport - if isinstance(member, LazyImport): - continue - # --------------------------------------------------- - except AttributeError: - if isinstance(obj, ObjectMember): - raise - # To be removed, retained for compatibility. - # See https://github.com/sphinx-doc/sphinx/issues/11631 - membername, member = obj - warnings.warn( - 'Returning tuples of (name, object) as ' - 'the second return value from get_object_members() is deprecated. ' - 'Return ObjectMember(name, object) instances instead.', - RemovedInSphinx80Warning, stacklevel=2, - ) + membername = obj.__name__ + member = obj.object + + # --------------------------------------------------- + # Issue #17455: Immediately skip lazy imports to avoid + # deprecation messages. + from sage.misc.lazy_import import LazyImport + if isinstance(member, LazyImport): + continue + # --------------------------------------------------- # if isattr is True, the member is documented as an attribute isattr = member is INSTANCEATTR or (namespace, membername) in attr_docs @@ -953,7 +933,7 @@ def generate( logger.warning( __("don't know which module to import for autodocumenting " '%r (try placing a "module" or "currentmodule" directive ' - 'in the document, or giving an explicit module name)') % + 'in the document, or giving an explicit module name)'), self.name, type='autodoc') return @@ -1041,7 +1021,7 @@ class ModuleDocumenter(Documenter): content_indent = '' _extra_indent = ' ' - option_spec: OptionSpec = { + option_spec: ClassVar[OptionSpec] = { 'members': members_option, 'undoc-members': bool_option, 'no-index': bool_option, 'inherited-members': inherited_members_option, 'show-inheritance': bool_option, 'synopsis': identity, @@ -1085,7 +1065,7 @@ def parse_name(self) -> bool: ret = super().parse_name() if self.args or self.retann: logger.warning(__('signature arguments or return annotation ' - 'given for automodule %s') % self.fullname, + 'given for automodule %s'), self.fullname, type='autodoc') return ret @@ -1098,8 +1078,8 @@ def import_object(self, raiseerror: bool = False) -> bool: except ValueError as exc: # invalid __all__ found. logger.warning(__('__all__ should be a list of strings, not %r ' - '(in module %s) -- ignoring __all__') % - (exc.args[0], self.fullname), type='autodoc') + '(in module %s) -- ignoring __all__'), + exc.args[0], self.fullname, type='autodoc') return ret @@ -1164,8 +1144,8 @@ def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]: ret.append(members[name]) else: logger.warning(__('missing attribute mentioned in :members: option: ' - 'module %s, attribute %s') % - (safe_getattr(self.object, '__name__', '???'), name), + 'module %s, attribute %s'), + safe_getattr(self.object, '__name__', '???', name), type='autodoc') return False, ret @@ -1203,10 +1183,10 @@ class ModuleLevelDocumenter(Documenter): def resolve_name(self, modname: str | None, parents: Any, path: str, base: str, ) -> tuple[str | None, list[str]]: if modname is not None: - return modname, parents + [base] + return modname, [*parents, base] if path: modname = path.rstrip('.') - return modname, parents + [base] + return modname, [*parents, base] # if documenting a toplevel object without explicit module, # it can be contained in another auto directive ... @@ -1215,7 +1195,7 @@ def resolve_name(self, modname: str | None, parents: Any, path: str, base: str, if not modname: modname = self.env.ref_context.get('py:module') # ... else, it stays None, which means invalid - return modname, parents + [base] + return modname, [*parents, base] class ClassLevelDocumenter(Documenter): @@ -1227,7 +1207,7 @@ class ClassLevelDocumenter(Documenter): def resolve_name(self, modname: str | None, parents: Any, path: str, base: str, ) -> tuple[str | None, list[str]]: if modname is not None: - return modname, parents + [base] + return modname, [*parents, base] if path: mod_cls = path.rstrip('.') @@ -1251,7 +1231,7 @@ def resolve_name(self, modname: str | None, parents: Any, path: str, base: str, if not modname: modname = self.env.ref_context.get('py:module') # ... else, it stays None, which means invalid - return modname, parents + [base] + return modname, [*parents, base] class DocstringSignatureMixin: @@ -1506,7 +1486,7 @@ def annotate_to_first_argument(self, func: Callable, typ: type) -> Callable | No if len(sig.parameters) == 0: return None - def dummy(): # NoQA: ANN202 + def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202 pass params = list(sig.parameters.values()) @@ -1562,7 +1542,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: objtype = 'class' member_order = 20 - option_spec: OptionSpec = { + option_spec: ClassVar[OptionSpec] = { 'members': members_option, 'undoc-members': bool_option, 'no-index': bool_option, 'inherited-members': inherited_members_option, 'show-inheritance': bool_option, 'member-order': member_order_option, @@ -1574,7 +1554,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: # Must be higher than FunctionDocumenter, ClassDocumenter, and # AttributeDocumenter as NewType can be an attribute and is a class - # after Python 3.10. Before 3.10 it is a kind of function object + # after Python 3.10. priority = 15 _signature_class: Any = None @@ -1599,8 +1579,14 @@ def __init__(self, *args: Any) -> None: def can_document_member( cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any, ) -> bool: - return isinstance(member, type) or ( - isattr and (inspect.isNewType(member) or isinstance(member, TypeVar))) + # support both sphinx 8 and py3.9/older sphinx + try: + result_bool = isinstance(member, type) or ( + isattr and isinstance(member, NewType | TypeVar)) + except: + result_bool = isinstance(member, type) or ( + isattr and (inspect.isNewType(member) or isinstance(member, TypeVar))) + return result_bool def import_object(self, raiseerror: bool = False) -> bool: ret = super().import_object(raiseerror) @@ -1673,7 +1659,12 @@ def import_object(self, raiseerror: bool = False) -> bool: # ------------------------------------------------------------------- else: self.doc_as_attr = True - if inspect.isNewType(self.object) or isinstance(self.object, TypeVar): + # support both sphinx 8 and py3.9/older sphinx + try: + test_bool = isinstance(self.object, NewType | TypeVar) + except: + test_bool = inspect.isNewType(self.object) or isinstance(self.object, TypeVar) + if test_bool: modname = getattr(self.object, '__module__', self.modname) if modname != self.modname and self.modname.startswith(modname): bases = self.modname[len(modname):].strip('.').split('.') @@ -1682,7 +1673,12 @@ def import_object(self, raiseerror: bool = False) -> bool: return ret def _get_signature(self) -> tuple[Any | None, str | None, Signature | None]: - if inspect.isNewType(self.object) or isinstance(self.object, TypeVar): + # support both sphinx 8 and py3.9/older sphinx + try: + test_bool = isinstance(self.object, NewType | TypeVar) + except: + test_bool = inspect.isNewType(self.object) or isinstance(self.object, TypeVar) + if test_bool: # Suppress signature return None, None, None @@ -1867,14 +1863,24 @@ def add_directive_header(self, sig: str) -> None: self.directivetype = 'attribute' super().add_directive_header(sig) - if inspect.isNewType(self.object) or isinstance(self.object, TypeVar): + # support both sphinx 8 and py3.9/older sphinx + try: + test_bool = isinstance(self.object, NewType | TypeVar) + except: + test_bool = inspect.isNewType(self.object) or isinstance(self.object, TypeVar) + if test_bool: return if self.analyzer and '.'.join(self.objpath) in self.analyzer.finals: self.add_line(' :final:', sourcename) canonical_fullname = self.get_canonical_fullname() - if (not self.doc_as_attr and not inspect.isNewType(self.object) + # support both sphinx 8 and py3.9/older sphinx + try: + newtype_test = isinstance(self.object, NewType) + except: + newtype_test = inspect.isNewType(self.object) + if (not self.doc_as_attr and not newtype_test and canonical_fullname and self.fullname != canonical_fullname): self.add_line(' :canonical: %s' % canonical_fullname, sourcename) @@ -1914,8 +1920,8 @@ def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]: if name in members: selected.append(members[name]) else: - logger.warning(__('missing attribute %s in object %s') % - (name, self.fullname), type='autodoc') + logger.warning(__('missing attribute %s in object %s'), + name, self.fullname, type='autodoc') return False, selected elif self.options.inherited_members: return False, list(members.values()) @@ -1926,6 +1932,9 @@ def get_doc(self) -> list[list[str]] | None: if isinstance(self.object, TypeVar): if self.object.__doc__ == TypeVar.__doc__: return [] + # ------------------------------------------------------------------ + # This section is kept for compatibility with python 3.9 + # see https://github.com/sagemath/sage/pull/38549#issuecomment-2327790930 if sys.version_info[:2] < (3, 10): if inspect.isNewType(self.object) or isinstance(self.object, TypeVar): parts = self.modname.strip('.').split('.') @@ -1944,6 +1953,7 @@ def get_doc(self) -> list[list[str]] | None: return [comment] except PycodeError: pass + # ------------------------------------------------------------------ if self.doc_as_attr: # Don't show the docstring of the class when it is an alias. if self.get_variable_comment(): @@ -2007,7 +2017,12 @@ def get_variable_comment(self) -> list[str] | None: return None def add_content(self, more_content: StringList | None) -> None: - if inspect.isNewType(self.object): + # support both sphinx 8 and py3.9/older sphinx + try: + newtype_test = isinstance(self.object, NewType) + except: + newtype_test = inspect.isNewType(self.object) + if newtype_test: if self.config.autodoc_typehints_format == "short": supertype = restify(self.object.__supertype__, "smart") else: @@ -2166,7 +2181,8 @@ def import_object(self, raiseerror: bool = False) -> bool: with mock(self.config.autodoc_mock_imports): parent = import_module(self.modname, self.config.autodoc_warningiserror) annotations = get_type_hints(parent, None, - self.config.autodoc_type_aliases) + self.config.autodoc_type_aliases, + include_extras=True) if self.objpath[-1] in annotations: self.object = UNINITIALIZED_ATTR self.parent = parent @@ -2200,7 +2216,7 @@ class DataDocumenter(GenericAliasMixin, objtype = 'data' member_order = 40 priority = -10 - option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec) + option_spec: ClassVar[OptionSpec] = dict(ModuleLevelDocumenter.option_spec) option_spec["annotation"] = annotation_option option_spec["no-value"] = bool_option @@ -2255,7 +2271,8 @@ def add_directive_header(self, sig: str) -> None: if self.config.autodoc_typehints != 'none': # obtain annotation for this data annotations = get_type_hints(self.parent, None, - self.config.autodoc_type_aliases) + self.config.autodoc_type_aliases, + include_extras=True) if self.objpath[-1] in annotations: if self.config.autodoc_typehints_format == "short": objrepr = stringify_annotation(annotations.get(self.objpath[-1]), @@ -2394,7 +2411,8 @@ def add_directive_header(self, sig: str) -> None: self.add_line(' :abstractmethod:', sourcename) if inspect.iscoroutinefunction(obj) or inspect.isasyncgenfunction(obj): self.add_line(' :async:', sourcename) - if inspect.isclassmethod(obj): + if (inspect.isclassmethod(obj) or + inspect.is_singledispatch_method(obj) and inspect.isclassmethod(obj.func)): self.add_line(' :classmethod:', sourcename) if inspect.isstaticmethod(obj, cls=self.parent, name=self.object_name): self.add_line(' :staticmethod:', sourcename) @@ -2434,7 +2452,7 @@ def annotate_to_first_argument(self, func: Callable, typ: type) -> Callable | No if len(sig.parameters) == 1: return None - def dummy(): # NoQA: ANN202 + def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202 pass params = list(sig.parameters.values()) @@ -2550,8 +2568,8 @@ def get_doc(self) -> list[list[str]] | None: if self.object is SLOTSATTR: try: parent___slots__ = inspect.getslots(self.parent) - if parent___slots__ and parent___slots__.get(self.objpath[-1]): - docstring = prepare_docstring(parent___slots__[self.objpath[-1]]) + if parent___slots__ and (docstring := parent___slots__.get(self.objpath[-1])): + docstring = prepare_docstring(docstring) return [docstring] else: return [] @@ -2582,9 +2600,7 @@ def is_runtime_instance_attribute(self, parent: Any) -> bool: # An instance variable defined in __init__(). if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore[attr-defined] return True - if self.is_runtime_instance_attribute_not_commented(parent): - return True - return False + return self.is_runtime_instance_attribute_not_commented(parent) def is_runtime_instance_attribute_not_commented(self, parent: Any) -> bool: """Check the subject is an attribute defined in __init__() without comment.""" @@ -2655,7 +2671,8 @@ class Foo: def is_uninitialized_instance_attribute(self, parent: Any) -> bool: """Check the subject is an annotation only attribute.""" - annotations = get_type_hints(parent, None, self.config.autodoc_type_aliases) + annotations = get_type_hints(parent, None, self.config.autodoc_type_aliases, + include_extras=True) return self.objpath[-1] in annotations def import_object(self, raiseerror: bool = False) -> bool: @@ -2703,7 +2720,7 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc] objtype = 'attribute' member_order = 60 - option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec) + option_spec: ClassVar[OptionSpec] = dict(ModuleLevelDocumenter.option_spec) option_spec["annotation"] = annotation_option option_spec["no-value"] = bool_option @@ -2809,7 +2826,8 @@ def add_directive_header(self, sig: str) -> None: if self.config.autodoc_typehints != 'none': # obtain type annotation for this attribute annotations = get_type_hints(self.parent, None, - self.config.autodoc_type_aliases) + self.config.autodoc_type_aliases, + include_extras=True) if self.objpath[-1] in annotations: if self.config.autodoc_typehints_format == "short": objrepr = stringify_annotation(annotations.get(self.objpath[-1]), @@ -2857,10 +2875,10 @@ def get_doc(self) -> list[list[str]] | None: # a docstring from the value which descriptor returns unexpectedly. # ref: https://github.com/sphinx-doc/sphinx/issues/7805 orig = self.config.autodoc_inherit_docstrings - self.config.autodoc_inherit_docstrings = False # type: ignore[attr-defined] + self.config.autodoc_inherit_docstrings = False return super().get_doc() finally: - self.config.autodoc_inherit_docstrings = orig # type: ignore[attr-defined] + self.config.autodoc_inherit_docstrings = orig def add_content(self, more_content: StringList | None) -> None: # Disable analyzing attribute comment on Documenter.add_content() to control it on @@ -2909,7 +2927,7 @@ def import_object(self, raiseerror: bool = False) -> bool: obj = __dict__.get(self.objpath[-1]) if isinstance(obj, classmethod) and inspect.isproperty(obj.__func__): self.object = obj.__func__ - self.isclassmethod = True + self.isclassmethod: bool = True return True else: return False @@ -2980,7 +2998,7 @@ def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any: return safe_getattr(obj, name, *defargs) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_autodocumenter(ModuleDocumenter) app.add_autodocumenter(ClassDocumenter) app.add_autodocumenter(ExceptionDocumenter) diff --git a/src/sage_docbuild/sphinxbuild.py b/src/sage_docbuild/sphinxbuild.py index 5621fe9e456..62b2d3cb112 100644 --- a/src/sage_docbuild/sphinxbuild.py +++ b/src/sage_docbuild/sphinxbuild.py @@ -307,6 +307,11 @@ def runsphinx(): saved_stdout = sys.stdout saved_stderr = sys.stderr + if not sys.warnoptions: + import warnings + original_filters = warnings.filters[:] + warnings.filterwarnings("ignore", category=DeprecationWarning, module='sphinx.util.inspect') + try: sys.stdout = SageSphinxLogger(sys.stdout, os.path.basename(output_dir)) sys.stderr = SageSphinxLogger(sys.stderr, os.path.basename(output_dir)) @@ -323,3 +328,6 @@ def runsphinx(): sys.stderr = saved_stderr sys.stdout.flush() sys.stderr.flush() + + if not sys.warnoptions: + warnings.filters = original_filters[:] diff --git a/src/sage_setup/autogen/__init__.py b/src/sage_setup/autogen/__init__.py index 380983c06c7..2ec85acde21 100644 --- a/src/sage_setup/autogen/__init__.py +++ b/src/sage_setup/autogen/__init__.py @@ -1,6 +1,6 @@ import os -from . import interpreters +from sage_setup.autogen.interpreters.internal import rebuild def autogen_all(): @@ -11,6 +11,7 @@ def autogen_all(): of packages built/installed by setup.py. """ from sage.env import SAGE_SRC - interpreters.rebuild(os.path.join(SAGE_SRC, "sage", "ext", "interpreters")) - return ['sage.ext.interpreters'] + rebuild(os.path.join(SAGE_SRC, "sage", "ext", "interpreters")) + + return ["sage.ext.interpreters"] diff --git a/src/sage_setup/autogen/interpreters/__main__.py b/src/sage_setup/autogen/interpreters/__main__.py old mode 100644 new mode 100755 index 398a7b30039..3649565e7a0 --- a/src/sage_setup/autogen/interpreters/__main__.py +++ b/src/sage_setup/autogen/interpreters/__main__.py @@ -1,8 +1,9 @@ +#!/usr/bin/env python3 # Usage: python -m sage_setup.autogen.interpreters import argparse -from . import rebuild +from internal import rebuild parser = argparse.ArgumentParser() parser.add_argument("output_dir", help="Output directory") diff --git a/src/sage_setup/autogen/interpreters/__init__.py b/src/sage_setup/autogen/interpreters/internal/__init__.py similarity index 91% rename from src/sage_setup/autogen/interpreters/__init__.py rename to src/sage_setup/autogen/interpreters/internal/__init__.py index 75096d06b80..c2489ecd486 100644 --- a/src/sage_setup/autogen/interpreters/__init__.py +++ b/src/sage_setup/autogen/interpreters/internal/__init__.py @@ -109,20 +109,18 @@ # that will have to be changed. ##################################################################### -from __future__ import print_function, absolute_import +from __future__ import absolute_import, print_function import os - from os.path import getmtime -from .generator import InterpreterGenerator, AUTOGEN_WARN +from .generator import AUTOGEN_WARN, InterpreterGenerator from .instructions import * from .memory import * from .specs.base import * from .storage import * from .utils import * - # Tuple of (filename_root, extension, method) where filename_root is the # root of the filename to be joined with "_".ext and # method is the name of a get_ method on InterpreterGenerator that returns @@ -141,8 +139,8 @@ def build_interp(interp_spec, dir): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: testdir = tmp_dir() sage: rdf_interp = RDFInterpreter() sage: build_interp(rdf_interp, testdir) @@ -183,10 +181,10 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): Monolithic build:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: testdir = tmp_dir() sage: rebuild(testdir) - Building interpreters for fast_callable + Generating interpreters for fast_callable in ... -> First build of interpreters sage: with open(testdir + '/wrapper_el.pyx') as f: ....: f.readline() @@ -197,7 +195,7 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): sage: testdir = tmp_dir() sage: rebuild(testdir, interpreters=['Element', 'Python'], ....: distribution='sagemath-categories') - Building interpreters for fast_callable + Generating interpreters for fast_callable in ... -> First build of interpreters sage: with open(testdir + '/all__sagemath_categories.py') as f: ....: f.readline() @@ -205,16 +203,22 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): """ # This line will show up in "sage -b" (once per upgrade, not every time # you run it). - print("Building interpreters for fast_callable") + print(f"Generating interpreters for fast_callable in {dirname}") if interpreters is None: interpreters = ['CDF', 'Element', 'Python', 'RDF', 'RR', 'CC'] from importlib import import_module - _INTERPRETERS = [getattr(import_module('sage_setup.autogen.interpreters.specs.' + interpreter.lower()), - interpreter + 'Interpreter') - for interpreter in interpreters] + _INTERPRETERS = [ + getattr( + import_module( + ".specs." + interpreter.lower(), package=__name__ + ), + interpreter + "Interpreter", + ) + for interpreter in interpreters + ] if distribution is None: all_py = 'all.py' @@ -226,11 +230,6 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): except OSError: if not os.path.isdir(dirname): raise - # Remove leftover file from before move to namespace packages - try: - os.remove(os.path.join(dirname, '__init__.py')) - except FileNotFoundError: - pass # Although multiple files are generated by this function, since # they are all generated at once it suffices to make sure if just @@ -264,3 +263,6 @@ class NeedToRebuild(Exception): with open(os.path.join(dirname, all_py), 'w') as f: f.write("# " + AUTOGEN_WARN) + + with open(os.path.join(dirname, '__init__.py'), 'w') as f: + f.write("# " + AUTOGEN_WARN) diff --git a/src/sage_setup/autogen/interpreters/generator.py b/src/sage_setup/autogen/interpreters/internal/generator.py similarity index 94% rename from src/sage_setup/autogen/interpreters/generator.py rename to src/sage_setup/autogen/interpreters/internal/generator.py index 33877422a8c..ebfea5478fc 100644 --- a/src/sage_setup/autogen/interpreters/generator.py +++ b/src/sage_setup/autogen/interpreters/internal/generator.py @@ -42,8 +42,8 @@ def __init__(self, spec): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: gen._spec is interp @@ -72,8 +72,8 @@ def gen_code(self, instr_desc, write): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -219,8 +219,8 @@ def func_header(self, cython=False): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.element import ElementInterpreter sage: interp = ElementInterpreter() sage: gen = InterpreterGenerator(interp) sage: print(gen.func_header()) @@ -262,8 +262,8 @@ def write_interpreter(self, write): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -310,8 +310,8 @@ def write_wrapper(self, write): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -480,8 +480,8 @@ def write_pxd(self, write): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -532,10 +532,10 @@ def get_interpreter(self): First we get the InterpreterSpec for several interpreters:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter - sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.element import ElementInterpreter sage: rdf_spec = RDFInterpreter() sage: rr_spec = RRInterpreter() sage: el_spec = ElementInterpreter() @@ -657,10 +657,10 @@ def get_wrapper(self): First we get the InterpreterSpec for several interpreters:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter - sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.element import ElementInterpreter sage: rdf_spec = RDFInterpreter() sage: rr_spec = RRInterpreter() sage: el_spec = ElementInterpreter() @@ -983,10 +983,10 @@ def get_pxd(self): First we get the InterpreterSpec for several interpreters:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter - sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.element import ElementInterpreter sage: rdf_spec = RDFInterpreter() sage: rr_spec = RRInterpreter() sage: el_spec = ElementInterpreter() diff --git a/src/sage_setup/autogen/interpreters/instructions.py b/src/sage_setup/autogen/interpreters/internal/instructions.py similarity index 89% rename from src/sage_setup/autogen/interpreters/instructions.py rename to src/sage_setup/autogen/interpreters/internal/instructions.py index 116f598197c..aad7583196d 100644 --- a/src/sage_setup/autogen/interpreters/instructions.py +++ b/src/sage_setup/autogen/interpreters/internal/instructions.py @@ -56,7 +56,7 @@ def params_gen(**chunks): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc_stack = MemoryChunkScratch('stack', ty_double, is_stack=True) sage: mc_args = MemoryChunkArguments('args', ty_double) sage: mc_code = MemoryChunkConstants('code', ty_int) @@ -186,8 +186,8 @@ class InstrSpec(object): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') add: SS->S = 'o0 = i0+i1;' @@ -213,8 +213,8 @@ def __init__(self, name, io, code=None, uses_error_handler=False, EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') add: SS->S = 'o0 = i0+i1;' @@ -288,8 +288,8 @@ def __repr__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') add: SS->S = 'o0 = i0+i1;' @@ -311,8 +311,8 @@ def instr_infix(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: instr_infix('mul', pg('SS', 'S'), '*') mul: SS->S = 'o0 = i0 * i1;' @@ -327,8 +327,8 @@ def instr_funcall_2args(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: instr_funcall_2args('atan2', pg('SS', 'S'), 'atan2') atan2: SS->S = 'o0 = atan2(i0, i1);' @@ -343,8 +343,8 @@ def instr_unary(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: instr_unary('sin', pg('S','S'), 'sin(i0)') sin: S->S = 'o0 = sin(i0);' @@ -361,8 +361,8 @@ def instr_funcall_2args_mpfr(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter sage: pg = RRInterpreter().pg sage: instr_funcall_2args_mpfr('add', pg('SS','S'), 'mpfr_add') add: SS->S = 'mpfr_add(o0, i0, i1, MPFR_RNDN);' @@ -377,8 +377,8 @@ def instr_funcall_1arg_mpfr(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter sage: pg = RRInterpreter().pg sage: instr_funcall_1arg_mpfr('exp', pg('S','S'), 'mpfr_exp') exp: S->S = 'mpfr_exp(o0, i0, MPFR_RNDN);' @@ -392,8 +392,8 @@ def instr_funcall_2args_mpc(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import CCInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import CCInterpreter sage: pg = CCInterpreter().pg sage: instr_funcall_2args_mpc('add', pg('SS','S'), 'mpc_add') add: SS->S = 'mpc_add(o0, i0, i1, MPC_RNDNN);' @@ -407,8 +407,8 @@ def instr_funcall_1arg_mpc(name, io, op): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import CCInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import CCInterpreter sage: pg = CCInterpreter().pg sage: instr_funcall_1arg_mpc('exp', pg('S','S'), 'mpc_exp') exp: S->S = 'mpc_exp(o0, i0, MPC_RNDNN);' diff --git a/src/sage_setup/autogen/interpreters/memory.py b/src/sage_setup/autogen/interpreters/internal/memory.py similarity index 90% rename from src/sage_setup/autogen/interpreters/memory.py rename to src/sage_setup/autogen/interpreters/internal/memory.py index e719f47d77a..801596e98c8 100644 --- a/src/sage_setup/autogen/interpreters/memory.py +++ b/src/sage_setup/autogen/interpreters/internal/memory.py @@ -27,7 +27,7 @@ def string_of_addr(a): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc_code = MemoryChunkConstants('code', ty_int) sage: string_of_addr(mc_code) '*code++' @@ -72,7 +72,7 @@ def __init__(self, name, storage_type): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: mc.name 'args' @@ -88,7 +88,7 @@ def __repr__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: mc {MC:args} @@ -104,7 +104,7 @@ def declare_class_members(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: mc.declare_class_members() ' cdef int _n_args\n cdef mpfr_t* _args\n' @@ -119,7 +119,7 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: print(mc.init_class_members()) count = args['args'] @@ -139,7 +139,7 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: print(mc.dealloc_class_members()) if self._args: @@ -157,7 +157,7 @@ def declare_parameter(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: mc.declare_parameter() 'mpfr_t* args' @@ -171,8 +171,8 @@ class using this memory chunk, to allocate local variables. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_call_locals() ' cdef RealNumber retval = (self.domain)()\n' @@ -186,7 +186,7 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkConstants('constants', ty_mpfr) sage: mc.pass_argument() 'self._constants' @@ -201,7 +201,7 @@ def pass_call_c_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkConstants('constants', ty_mpfr) sage: mc.pass_call_c_argument() 'self._constants' @@ -221,7 +221,7 @@ def needs_cleanup_on_error(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkConstants('constants', ty_mpfr) sage: mc.needs_cleanup_on_error() False @@ -246,7 +246,7 @@ def is_stack(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkScratch('scratch', ty_mpfr) sage: mc.is_stack() False @@ -268,7 +268,7 @@ def is_python_refcounted_stack(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkScratch('args', ty_python) sage: mc.is_python_refcounted_stack() False @@ -297,7 +297,7 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_double) sage: print(mc.init_class_members()) count = args['args'] @@ -318,7 +318,7 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: print(mc.dealloc_class_members()) if self._args: @@ -336,7 +336,7 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkConstants('constants', ty_mpfr) sage: mc.pass_argument() 'self._constants' @@ -360,7 +360,7 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkConstants('constants', ty_mpfr) sage: print(mc.init_class_members()) val = args['constants'] @@ -398,7 +398,7 @@ def setup_args(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: print(mc.setup_args()) cdef mpfr_t* c_args = self._args @@ -422,7 +422,7 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkArguments('args', ty_mpfr) sage: mc.pass_argument() 'c_args' @@ -449,7 +449,7 @@ def __init__(self, name, storage_type, is_stack=False): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkScratch('stack', ty_double, is_stack=True) sage: mc.name 'stack' @@ -469,7 +469,7 @@ def is_stack(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkScratch('stack', ty_mpfr, is_stack=True) sage: mc.is_stack() True @@ -489,7 +489,7 @@ def needs_cleanup_on_error(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkScratch('registers', ty_python) sage: mc.needs_cleanup_on_error() True @@ -508,7 +508,7 @@ def handle_cleanup(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: mc = MemoryChunkScratch('registers', ty_python) sage: print(mc.handle_cleanup()) for i in range(self._n_registers): diff --git a/src/sage_setup/autogen/interpreters/specs/__init__.py b/src/sage_setup/autogen/interpreters/internal/specs/__init__.py similarity index 100% rename from src/sage_setup/autogen/interpreters/specs/__init__.py rename to src/sage_setup/autogen/interpreters/internal/specs/__init__.py diff --git a/src/sage_setup/autogen/interpreters/specs/base.py b/src/sage_setup/autogen/interpreters/internal/specs/base.py similarity index 87% rename from src/sage_setup/autogen/interpreters/specs/base.py rename to src/sage_setup/autogen/interpreters/internal/specs/base.py index c311c76fb04..6abd2253870 100644 --- a/src/sage_setup/autogen/interpreters/specs/base.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/base.py @@ -48,9 +48,9 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter sage: interp = RDFInterpreter() sage: interp.c_header '#include ' @@ -85,8 +85,8 @@ def _set_opcodes(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: interp.instr_descs[5].opcode 5 @@ -130,10 +130,10 @@ def __init__(self, type, mc_retval=None): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter - sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter - sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.internal.specs.element import ElementInterpreter sage: rdf = RDFInterpreter() sage: rr = RRInterpreter() sage: el = ElementInterpreter() diff --git a/src/sage_setup/autogen/interpreters/specs/cc.py b/src/sage_setup/autogen/interpreters/internal/specs/cc.py similarity index 91% rename from src/sage_setup/autogen/interpreters/specs/cc.py rename to src/sage_setup/autogen/interpreters/internal/specs/cc.py index e16252b0b79..cc42a6defab 100644 --- a/src/sage_setup/autogen/interpreters/specs/cc.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/cc.py @@ -30,8 +30,8 @@ def declare_class_members(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.declare_class_members() '' @@ -45,8 +45,8 @@ class using this memory chunk, to allocate local variables. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.declare_call_locals() ' cdef ComplexNumber retval = (self.domain_element._new())\n' @@ -63,8 +63,8 @@ def declare_parameter(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.declare_parameter() 'mpc_t retval' @@ -78,8 +78,8 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.pass_argument() '((retval.__re))' @@ -93,8 +93,8 @@ def pass_call_c_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.pass_call_c_argument() 'result' @@ -115,8 +115,8 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cc import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cc import * sage: interp = CCInterpreter() sage: interp.name 'cc' @@ -149,7 +149,6 @@ def __init__(self): sage: print(interp.c_header) #include - #include "wrapper_cc.h" So instructions where you need to interact with Python can @@ -171,7 +170,6 @@ def __init__(self): self.c_header = ri(0, ''' #include - #include "wrapper_cc.h" ''') self.pxd_header = ri(0, diff --git a/src/sage_setup/autogen/interpreters/specs/cdf.py b/src/sage_setup/autogen/interpreters/internal/specs/cdf.py similarity index 98% rename from src/sage_setup/autogen/interpreters/specs/cdf.py rename to src/sage_setup/autogen/interpreters/internal/specs/cdf.py index c9ea258e221..1edc1f7abe3 100644 --- a/src/sage_setup/autogen/interpreters/specs/cdf.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/cdf.py @@ -33,8 +33,8 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.cdf import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.cdf import * sage: interp = CDFInterpreter() sage: interp.name 'cdf' @@ -85,7 +85,6 @@ def __init__(self): self.c_header = ri(0,""" #include #include - #include "wrapper_cdf.h" /* On Solaris, we need to define _Imaginary_I when compiling with GCC, * otherwise the constant I doesn't work. The definition below is based diff --git a/src/sage_setup/autogen/interpreters/specs/element.py b/src/sage_setup/autogen/interpreters/internal/specs/element.py similarity index 90% rename from src/sage_setup/autogen/interpreters/specs/element.py rename to src/sage_setup/autogen/interpreters/internal/specs/element.py index 2f280f703f1..5dc7c6592c9 100644 --- a/src/sage_setup/autogen/interpreters/specs/element.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/element.py @@ -37,8 +37,8 @@ def setup_args(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.element import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.element import * sage: mc = MemoryChunkElementArguments('args', ty_python) sage: mc.setup_args() 'mapped_args = [self._domain(a) for a in args]\n' @@ -51,8 +51,8 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.element import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.element import * sage: mc = MemoryChunkElementArguments('args', ty_python) sage: mc.pass_argument() '(mapped_args).ob_item' @@ -81,8 +81,8 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.element import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.element import * sage: interp = ElementInterpreter() sage: interp.name 'el' @@ -105,8 +105,6 @@ def __init__(self): self.chunks = [self.mc_args, self.mc_constants, self.mc_stack, self.mc_domain_info, self.mc_code] self.c_header = ri(0, """ - #include "wrapper_el.h" - #define CHECK(x) do_check(&(x), domain) static inline int do_check(PyObject **x, PyObject *domain) { diff --git a/src/sage_setup/autogen/interpreters/specs/python.py b/src/sage_setup/autogen/interpreters/internal/specs/python.py similarity index 86% rename from src/sage_setup/autogen/interpreters/specs/python.py rename to src/sage_setup/autogen/interpreters/internal/specs/python.py index c185557165f..24bab75f10d 100644 --- a/src/sage_setup/autogen/interpreters/specs/python.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/python.py @@ -31,8 +31,8 @@ def declare_class_members(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) """ return " cdef int _n_%s\n" % self.name @@ -45,8 +45,8 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) sage: mc.init_class_members() " count = args['args']\n self._n_args = count\n" @@ -63,8 +63,8 @@ def setup_args(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) sage: mc.setup_args() '' @@ -77,8 +77,8 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) sage: mc.pass_argument() '(args).ob_item' @@ -100,8 +100,8 @@ def __init__(self, name): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.name 'domain' @@ -117,8 +117,8 @@ def declare_class_members(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.declare_class_members() ' cdef object _domain\n' @@ -136,8 +136,8 @@ class members. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.init_class_members() " self._domain = args['domain']\n" @@ -154,8 +154,8 @@ def declare_parameter(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.declare_parameter() 'PyObject* domain' @@ -169,8 +169,8 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.pass_argument() 'self._domain' @@ -212,8 +212,8 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.python import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.python import * sage: interp = PythonInterpreter() sage: interp.name 'py' diff --git a/src/sage_setup/autogen/interpreters/specs/rdf.py b/src/sage_setup/autogen/interpreters/internal/specs/rdf.py similarity index 97% rename from src/sage_setup/autogen/interpreters/specs/rdf.py rename to src/sage_setup/autogen/interpreters/internal/specs/rdf.py index 95894f8d6d2..83a0ecde012 100644 --- a/src/sage_setup/autogen/interpreters/specs/rdf.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/rdf.py @@ -36,8 +36,8 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rdf import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rdf import * sage: interp = RDFInterpreter() sage: interp.name 'rdf' diff --git a/src/sage_setup/autogen/interpreters/specs/rr.py b/src/sage_setup/autogen/interpreters/internal/specs/rr.py similarity index 91% rename from src/sage_setup/autogen/interpreters/specs/rr.py rename to src/sage_setup/autogen/interpreters/internal/specs/rr.py index 06452e24047..e51262d6196 100644 --- a/src/sage_setup/autogen/interpreters/specs/rr.py +++ b/src/sage_setup/autogen/interpreters/internal/specs/rr.py @@ -30,8 +30,8 @@ def declare_class_members(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_class_members() '' @@ -45,8 +45,8 @@ class using this memory chunk, to allocate local variables. EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_call_locals() ' cdef RealNumber retval = (self.domain)()\n' @@ -63,8 +63,8 @@ def declare_parameter(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_parameter() 'mpfr_t retval' @@ -78,8 +78,8 @@ def pass_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.pass_argument() 'retval.value' @@ -93,8 +93,8 @@ def pass_call_c_argument(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.pass_call_c_argument() 'result' @@ -116,8 +116,8 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * - sage: from sage_setup.autogen.interpreters.specs.rr import * + sage: from sage_setup.autogen.interpreters.internal import * + sage: from sage_setup.autogen.interpreters.internal.specs.rr import * sage: interp = RRInterpreter() sage: interp.name 'rr' @@ -148,7 +148,6 @@ def __init__(self): sage: print(interp.c_header) #include - #include "wrapper_rr.h" The function ``rr_py_call_helper`` is implemented in Cython:: @@ -188,7 +187,6 @@ def __init__(self): self.c_header = ri(0, ''' #include - #include "wrapper_rr.h" ''') self.pxd_header = ri(0, diff --git a/src/sage_setup/autogen/interpreters/storage.py b/src/sage_setup/autogen/interpreters/internal/storage.py similarity index 90% rename from src/sage_setup/autogen/interpreters/storage.py rename to src/sage_setup/autogen/interpreters/internal/storage.py index 291398fd9d9..ce77abbe586 100644 --- a/src/sage_setup/autogen/interpreters/storage.py +++ b/src/sage_setup/autogen/interpreters/internal/storage.py @@ -67,7 +67,7 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.class_member_declarations '' sage: ty_double.class_member_initializations @@ -104,7 +104,7 @@ def cheap_copies(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.cheap_copies() True sage: ty_python.cheap_copies() @@ -126,7 +126,7 @@ def python_refcounted(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.python_refcounted() False sage: ty_python.python_refcounted() @@ -140,7 +140,7 @@ def cython_decl_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.cython_decl_type() 'double' sage: ty_python.cython_decl_type() @@ -157,7 +157,7 @@ def cython_array_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.cython_array_type() 'double*' sage: ty_python.cython_array_type() @@ -180,7 +180,7 @@ def needs_cython_init_clear(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.needs_cython_init_clear() False sage: ty_mpfr.needs_cython_init_clear() @@ -196,7 +196,7 @@ def c_decl_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.c_decl_type() 'double' sage: ty_python.c_decl_type() @@ -213,7 +213,7 @@ def c_ptr_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.c_ptr_type() 'double*' sage: ty_python.c_ptr_type() @@ -231,7 +231,7 @@ def c_reference_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.c_reference_type() 'double*' sage: ty_python.c_reference_type() @@ -248,7 +248,7 @@ def c_local_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.c_local_type() 'double' sage: ty_python.c_local_type() @@ -266,7 +266,7 @@ def assign_c_from_py(self, c, py): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.assign_c_from_py('foo', 'bar') 'foo = bar' sage: ty_python.assign_c_from_py('foo[i]', 'bar[j]') @@ -284,7 +284,7 @@ def declare_chunk_class_members(self, name): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.declare_chunk_class_members('args') ' cdef int _n_args\n cdef mpfr_t* _args\n' """ @@ -302,7 +302,7 @@ def alloc_chunk_data(self, name, len): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: print(ty_mpfr.alloc_chunk_data('args', 'MY_LENGTH')) self._n_args = MY_LENGTH self._args = check_allocarray(self._n_args, sizeof(mpfr_t)) @@ -328,7 +328,7 @@ def dealloc_chunk_data(self, name): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: print(ty_double.dealloc_chunk_data('args')) if self._args: sig_free(self._args) @@ -364,7 +364,7 @@ def __init__(self, ty): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.class_member_declarations '' sage: ty_double.class_member_initializations @@ -391,7 +391,7 @@ def cheap_copies(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.cheap_copies() True sage: ty_python.cheap_copies() @@ -405,7 +405,7 @@ def c_decl_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.c_decl_type() 'double' sage: ty_python.c_decl_type() @@ -422,7 +422,7 @@ def c_local_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_double.c_local_type() 'double' sage: ty_python.c_local_type() @@ -456,7 +456,7 @@ class StorageTypeDoubleComplex(StorageTypeSimple): """ def assign_c_from_py(self, c, py): """ - sage: from sage_setup.autogen.interpreters import ty_double_complex + sage: from sage_setup.autogen.interpreters.internal import ty_double_complex sage: ty_double_complex.assign_c_from_py('z_c', 'z_py') 'z_c = CDE_to_dz(z_py)' """ @@ -500,7 +500,7 @@ def __init__(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.class_member_declarations '' sage: ty_python.class_member_initializations @@ -521,7 +521,7 @@ def python_refcounted(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.python_refcounted() True """ @@ -533,7 +533,7 @@ def cython_decl_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.cython_decl_type() 'object' """ @@ -547,7 +547,7 @@ def declare_chunk_class_members(self, name): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.declare_chunk_class_members('args') ' cdef object _list_args\n cdef int _n_args\n cdef PyObject** _args\n' """ @@ -565,7 +565,7 @@ def alloc_chunk_data(self, name, len): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: print(ty_python.alloc_chunk_data('args', 'MY_LENGTH')) self._n_args = MY_LENGTH self._list_args = PyList_New(self._n_args) @@ -590,7 +590,7 @@ def dealloc_chunk_data(self, name): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.dealloc_chunk_data('args') '' """ @@ -605,7 +605,7 @@ def needs_cython_init_clear(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.needs_cython_init_clear() True """ @@ -619,7 +619,7 @@ def assign_c_from_py(self, c, py): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.assign_c_from_py('foo[i]', 'bar[j]') 'foo[i] = bar[j]; Py_INCREF(foo[i])' """ @@ -633,7 +633,7 @@ def cython_init(self, loc): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.cython_init('foo[i]') 'foo[i] = NULL' """ @@ -646,7 +646,7 @@ def cython_clear(self, loc): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_python.cython_clear('foo[i]') 'Py_CLEAR(foo[i])' """ @@ -674,7 +674,7 @@ def __init__(self, decl_ty, ref_ty): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.class_member_declarations 'cdef RealField_class domain\n' sage: ty_mpfr.class_member_initializations @@ -696,7 +696,7 @@ def c_decl_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.c_decl_type() 'mpfr_t' """ @@ -711,7 +711,7 @@ def c_local_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.c_local_type() 'mpfr_ptr' """ @@ -725,7 +725,7 @@ def c_reference_type(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.c_reference_type() 'mpfr_t' """ @@ -741,7 +741,7 @@ def needs_cython_init_clear(self): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.needs_cython_init_clear() True """ @@ -775,7 +775,7 @@ def __init__(self, id=''): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.class_member_declarations 'cdef RealField_class domain\n' sage: ty_mpfr.class_member_initializations @@ -812,7 +812,7 @@ def cython_init(self, loc): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.cython_init('foo[i]') 'mpfr_init2(foo[i], self.domain.prec())' """ @@ -826,7 +826,7 @@ def cython_clear(self, loc): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.cython_clear('foo[i]') 'mpfr_clear(foo[i])' """ @@ -840,7 +840,7 @@ def assign_c_from_py(self, c, py): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpfr.assign_c_from_py('foo[i]', 'bar[j]') 'rn = self.domain(bar[j])\nmpfr_set(foo[i], rn.value, MPFR_RNDN)' """ @@ -879,7 +879,7 @@ def __init__(self, id=''): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpc.class_member_declarations 'cdef object domain\ncdef ComplexNumber domain_element\n' sage: ty_mpc.class_member_initializations @@ -916,7 +916,7 @@ def cython_init(self, loc): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpc.cython_init('foo[i]') 'mpc_init2(foo[i], self.domain_element._prec)' """ @@ -930,7 +930,7 @@ def cython_clear(self, loc): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpc.cython_clear('foo[i]') 'mpc_clear(foo[i])' """ @@ -944,7 +944,7 @@ def assign_c_from_py(self, c, py): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: ty_mpc.assign_c_from_py('foo[i]', 'bar[j]') 'cn = self.domain(bar[j])\nmpc_set_fr_fr(foo[i], cn.__re, cn.__im, MPC_RNDNN)' """ diff --git a/src/sage_setup/autogen/interpreters/utils.py b/src/sage_setup/autogen/interpreters/internal/utils.py similarity index 93% rename from src/sage_setup/autogen/interpreters/utils.py rename to src/sage_setup/autogen/interpreters/internal/utils.py index 10f239ed2a3..247243ef644 100644 --- a/src/sage_setup/autogen/interpreters/utils.py +++ b/src/sage_setup/autogen/interpreters/internal/utils.py @@ -50,7 +50,7 @@ def je(template, **kwargs): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import je + sage: from sage_setup.autogen.interpreters.internal import je sage: je("{{ a }} > {{ b }} * {{ c }}", a='"a suffusion of yellow"', b=3, c=7) '"a suffusion of yellow" > 3 * 7' """ @@ -76,7 +76,7 @@ def indent_lines(n, text): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import indent_lines + sage: from sage_setup.autogen.interpreters.internal import indent_lines sage: indent_lines(3, "foo") ' foo' sage: indent_lines(3, "foo\nbar") @@ -102,7 +102,7 @@ def reindent_lines(n, text): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import reindent_lines + sage: from sage_setup.autogen.interpreters.internal import reindent_lines sage: print(reindent_lines(3, " foo\n bar")) foo bar @@ -118,7 +118,7 @@ def write_if_changed(fn, value): EXAMPLES:: - sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.internal import * sage: def last_modification(fn): return os.stat(fn).st_mtime sage: fn = tmp_filename('gen_interp') sage: write_if_changed(fn, 'Hello, world') diff --git a/src/sage_setup/find.py b/src/sage_setup/find.py index 8762e08ad0f..e00336b3443 100644 --- a/src/sage_setup/find.py +++ b/src/sage_setup/find.py @@ -53,7 +53,9 @@ def find_python_sources(src_dir, modules=['sage'], distributions=None, ``distribution`` (from a ``# sage_setup: distribution = PACKAGE`` directive in the module source file) is in ``exclude_distributions``. - OUTPUT: Triple consisting of + OUTPUT: + + Triple consisting of - the list of package names (corresponding to ordinary packages or namespace packages, according to @@ -184,7 +186,7 @@ def filter_cython_sources(src_dir, distributions, exclude_distributions=None): directive in the module source file) is an element of ``distributions``. - OUTPUT: List of absolute paths to Cython files (``*.pyx``). + OUTPUT: list of absolute paths to Cython files (``*.pyx``) EXAMPLES:: @@ -341,6 +343,92 @@ def find_extra_files(src_dir, modules, cythonized_dir, special_filenames=[], *, return data_files +def installed_files_by_module(site_packages, modules=('sage',)): + """ + Find all currently installed files + + INPUT: + + - ``site_packages`` -- string. The root Python path where the Sage + library is being installed. If the path doesn't exist, returns + an empty dictionary. + + - ``modules`` -- list/tuple/iterable of strings (default: + ``('sage',)``). The top-level directory name(s) in + ``site_packages``. + + OUTPUT: + + A dictionary whose keys are module names (``'sage.module.foo'``) + and values are list of corresponding file names + ``['sage/module/foo.py', 'sage/module/foo.pyc']`` relative to + ``site_packages``. + + EXAMPLES:: + + sage: site_packages = os.path.dirname(os.path.dirname(os.path.dirname(sage.cpython.__file__))) + sage: from sage_setup.find import installed_files_by_module + sage: files_by_module = installed_files_by_module(site_packages) + sage: (f,) = files_by_module['sage.structure.sage_object']; f + 'sage/structure/sage_object...' + sage: (f1, f2) = sorted(files_by_module['sage.structure']) + sage: f1 + 'sage/structure/__init__.py' + sage: f2 + 'sage/structure/....pyc' + + This takes about 30ms with warm cache:: + + sage: timeit('installed_files_by_module(site_packages)', # random output + ....: number=1, repeat=1) + 1 loops, best of 1: 29.6 ms per loop + """ + + module_files = defaultdict(set) + module_exts = get_extensions() + + def add(module, filename, dirpath): + # Find the longest extension that matches the filename + best_ext = '' + + for ext in module_exts: + if filename.endswith(ext) and len(ext) > len(best_ext): + best_ext = ext + + if not best_ext: + return + + base = filename[:-len(best_ext)] + filename = os.path.join(dirpath, filename) + + if base != '__init__': + module += '.' + base + + module_files[module].add(filename) + + cache_filename = importlib.util.cache_from_source(filename) + if os.path.exists(cache_filename): + module_files[module].add(cache_filename) + + cwd = os.getcwd() + try: + os.chdir(site_packages) + except OSError: + return module_files + try: + for module in modules: + for dirpath, dirnames, filenames in os.walk(module): + module_dir = '.'.join(dirpath.split(os.path.sep)) + + if os.path.basename(dirpath) == '__pycache__': + continue + + for filename in filenames: + add(module_dir, filename, dirpath) + finally: + os.chdir(cwd) + return module_files + def get_extensions(type=None): """ diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index 76aa08f8833..969793209c8 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -33,7 +33,7 @@ dnl From Makefile.in: SAGERUNTIME SPKG_INSTALL_REQUIRES_ipython SPKG_INSTALL_REQUIRES_pexpect dnl From Makefile.in: DOC_DEPENDENCIES - SPKG_INSTALL_REQUIRES_sphinx + sphinx >=5.2, <9 SPKG_INSTALL_REQUIRES_networkx SPKG_INSTALL_REQUIRES_scipy SPKG_INSTALL_REQUIRES_sympy diff --git a/src/tox.ini b/src/tox.ini index 85a033166bb..b6548bc55a4 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -180,8 +180,8 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E21,E221,E222,E225,E227,E228,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} - pycodestyle --select E111,E271,E301,E305,E306,E401,E502,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E21,E221,E222,E225,E227,E228,E25,E271,E275,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} + pycodestyle --select E111,E271,E301,E302,E303,E305,E306,E401,E502,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160 @@ -291,7 +291,6 @@ passenv = RUFF_OUTPUT_FORMAT # 116 PLR0402 [*] Use `from matplotlib import cm` in lieu of alias # 111 PLW0603 [ ] Using the global statement to update `AA_0` is discouraged # 78 F841 [*] Local variable `B` is assigned to but never used -# 64 E713 [*] Test for membership should be `not in` # 48 PLW0602 [ ] Using global for `D` but no assignment is done # 33 PLR1711 [*] Useless `return` statement at end of function # 24 E714 [*] Test for object identity should be `is not` @@ -315,7 +314,7 @@ passenv = RUFF_OUTPUT_FORMAT # 1 F402 [ ] Import `factor` from line 259 shadowed by loop variable # 1 PLC0208 [*] Use a sequence type instead of a `set` when iterating over values # -commands = ruff check --ignore PLR2004,I001,F401,E741,F821,PLR0912,PLR0913,E402,PLR0915,PLW2901,PLR5501,PLR0911,E731,F405,PLR1714,PLR1736,F403,PLR0402,PLW0603,F841,E713,PLW0602,PLR1711,E714,PLR1701,PLR1704,PLW3301,PLW1510,E721,PLW0120,F811,PLC2401,PLC0414,E743,PLE0101,PLR0124,PLW0127,F541,PLW1508,PLC3002,E742,PLE0302,PLW0129,F402,PLC0208 {posargs:{toxinidir}/sage/} +commands = ruff check --ignore PLR2004,I001,F401,E741,F821,PLR0912,PLR0913,E402,PLR0915,PLW2901,PLR5501,PLR0911,E731,F405,PLR1714,PLR1736,F403,PLR0402,PLW0603,F841,PLW0602,PLW0642,PLR1711,E714,SIM101,PLR1704,PLW3301,PLW1510,E721,PLW0211,PLW0120,F811,PLC2401,PLC0414,E743,PLE0101,PLR0124,PLW0127,F541,PLW1508,PLC3002,E742,PLE0302,PLW0129,F402,PLC0208 {posargs:{toxinidir}/sage/} [flake8] rst-roles = @@ -380,7 +379,7 @@ exclude = [pytest] python_files = *_test.py -norecursedirs = local prefix venv build pkgs .git src/doc src/bin +norecursedirs = local prefix venv build builddir pkgs .git src/doc src/bin tools addopts = --import-mode importlib doctest_optionflags = NORMALIZE_WHITESPACE ELLIPSIS # https://docs.pytest.org/en/stable/reference/reference.html#confval-consider_namespace_packages @@ -388,9 +387,11 @@ consider_namespace_packages = True [coverage:run] source = sage -concurrency = multiprocessing +concurrency = multiprocessing,thread data_file = .coverage/.coverage -disable_warnings = no-data-collected +disable_warnings = + no-data-collected + module-not-measured [coverage:report] ignore_errors = True diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 00000000000..b0c2e4bb68b --- /dev/null +++ b/tools/README.md @@ -0,0 +1,13 @@ +# Tools Directory + +This folder contains various command-line tools that are used to facilitate different development tasks. Below is a brief description of each command available in this directory. + +## Update Meson Build Files + +This command is used to updates the Meson build files in the project. It automatically adds new source files (py, pyx) to the Meson files and removes deleted source files. This command is useful when adding or removing source files from the project. + +Within an active virtual environment where Meson is installed, run the following command: + +```bash +tools/update_meson.py +``` diff --git a/tools/update-meson.py b/tools/update-meson.py new file mode 100755 index 00000000000..827b7d9b5a3 --- /dev/null +++ b/tools/update-meson.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python3 + +import argparse +import os +from argparse import Namespace +from pathlib import Path + +from mesonbuild import mlog +from mesonbuild.ast import ( + AstPrinter, + AstVisitor, +) +from mesonbuild.ast.interpreter import MethodNode +from mesonbuild.mformat import ( + run as meson_format, +) +from mesonbuild.mparser import ( + AssignmentNode, + BaseNode, + DictNode, + SymbolNode, +) +from mesonbuild.rewriter import ( + ArgumentNode, + ArrayNode, + FunctionNode, + Rewriter, + StringNode, + Token, +) + +# Get target directory from command line arguments +parser = argparse.ArgumentParser() +parser.add_argument( + "sourcedir", help="Source directory", nargs="?", default=".", type=Path +) +options = parser.parse_args() + + +class AstPython(AstVisitor): + install_sources_calls: list[MethodNode] = [] + extension_data: list[AssignmentNode] = [] + + def visit_MethodNode(self, node: MethodNode) -> None: + if node.name.value == "install_sources": + self.install_sources_calls += [node] + return super().visit_MethodNode(node) + + def visit_AssignmentNode(self, node: AssignmentNode) -> None: + if node.var_name.value in ["extension_data", "extension_data_cpp"]: + self.extension_data += [node] + return super().visit_AssignmentNode(node) + + +# Utility function to get a list of the sources from a node +def arg_list_from_node(n): + args = [] + if isinstance(n, FunctionNode) or isinstance(n, MethodNode): + args = list(n.args.arguments) + # if 'func_name' in n and n.func_name.value in BUILD_TARGET_FUNCTIONS: + # args.pop(0) + elif isinstance(n, ArrayNode): + args = n.args.arguments + elif isinstance(n, ArgumentNode): + args = n.arguments + return args + + +def _symbol(val: str) -> SymbolNode: + return SymbolNode(Token("", "", 0, 0, 0, (0, 0), val)) + + +def update_python_sources(self: Rewriter, visitor: AstPython): + for target in visitor.install_sources_calls: + # Generate the current source list + src_list: list[str] = [] + for arg in arg_list_from_node(target): + if isinstance(arg, StringNode): + src_list += [arg.value] + + folder = Path(target.filename).parent + python_files = sorted( + list(folder.glob("*.py")) + list(folder.glob('*.pxd')) + ) # + list(folder.glob('*.pxd')) + list(folder.glob('*.h'))) + + to_append: list[StringNode] = [] + for file in python_files: + file_name = file.name + if file_name == "__init__.py": + # We don't want to add __init__.py files + continue + if file_name in src_list: + continue + token = Token("string", target.filename, 0, 0, 0, None, file_name) + to_append += [StringNode(token)] + + # Get all deleted files + to_remove = [] + for src in src_list: + if not folder.joinpath(src).exists(): + to_remove += [src] + + if not to_append and not to_remove: + continue + + # Update the source list + target.args.arguments = sorted( + [ + arg + for arg in target.args.arguments + if not (isinstance(arg, StringNode) and arg.value in to_remove) + ] + + to_append, + key=lambda x: x.value, + ) + + # Mark the node as modified + if target not in self.modified_nodes: + self.modified_nodes += [target] + + ext_data: dict[Path, list[str]] = {} + for target in visitor.extension_data: + folder = Path(target.filename).parent + # Generate the current source dict + src_list: dict[str, BaseNode] = {} + if isinstance(target.value, DictNode): + src_list.update({k.value: v for k, v in target.value.args.kwargs.items()}) + ext_data.setdefault(folder, []) + ext_data[folder] += src_list.keys() + + for target in visitor.extension_data: + if target.var_name.value != "extension_data": + continue + folder = Path(target.filename).parent + src_list = ext_data[folder] + + cython_files = sorted(list(folder.glob("*.pyx"))) + # Some cython files are compiled in a special way, so we don't want to add them + special_cython_files = { + "bliss.pyx", + "mcqd.pyx", + "tdlib.pyx", + } + cython_files = [x for x in cython_files if x.name not in special_cython_files] + # Add all cython files that are not in the source list + for file in cython_files: + file_name = file.stem + if file_name in src_list: + continue + token = Token("string", target.filename, 0, 0, 0, None, file_name) + arg = ArgumentNode(Token("", target.filename, 0, 0, 0, None, "[]")) + arg.append( + StringNode(Token("string", target.filename, 0, 0, 0, None, file.name)) + ) + func = FunctionNode(_symbol("files"), _symbol("("), arg, _symbol(")")) + target.value.args.kwargs.update({StringNode(token): func}) + if target not in self.modified_nodes: + self.modified_nodes += [target] + + +def apply_changes(self: Rewriter): + assert all( + hasattr(x, "lineno") and hasattr(x, "colno") and hasattr(x, "filename") + for x in self.modified_nodes + ) + assert all( + hasattr(x, "lineno") and hasattr(x, "colno") and hasattr(x, "filename") + for x in self.to_remove_nodes + ) + assert all( + isinstance(x, (ArrayNode, FunctionNode, MethodNode, AssignmentNode)) + for x in self.modified_nodes + ) + assert all( + isinstance(x, (ArrayNode, AssignmentNode, FunctionNode)) + for x in self.to_remove_nodes + ) + # Sort based on line and column in reversed order + work_nodes = [{"node": x, "action": "modify"} for x in self.modified_nodes] + work_nodes += [{"node": x, "action": "rm"} for x in self.to_remove_nodes] + work_nodes = sorted( + work_nodes, key=lambda x: (x["node"].lineno, x["node"].colno), reverse=True + ) + work_nodes += [{"node": x, "action": "add"} for x in self.to_add_nodes] + + # Generating the new replacement string + str_list = [] + for i in work_nodes: + new_data = "" + if i["action"] == "modify" or i["action"] == "add": + printer = AstPrinter() + i["node"].accept(printer) + printer.post_process() + new_data = printer.result.strip() + data = { + "file": i["node"].filename, + "str": new_data, + "node": i["node"], + "action": i["action"], + } + str_list += [data] + + # Load build files + files = {} + for i in str_list: + if i["file"] in files: + continue + fpath = os.path.realpath(os.path.join(self.sourcedir, i["file"])) + fdata = "" + # Create an empty file if it does not exist + if not os.path.exists(fpath): + with open(fpath, "w", encoding="utf-8"): + pass + with open(fpath, encoding="utf-8") as fp: + fdata = fp.read() + + # Generate line offsets numbers + m_lines = fdata.splitlines(True) + offset = 0 + line_offsets = [] + for j in m_lines: + line_offsets += [offset] + offset += len(j) + + files[i["file"]] = {"path": fpath, "raw": fdata, "offsets": line_offsets} + + # Replace in source code + def remove_node(i): + offsets = files[i["file"]]["offsets"] + raw = files[i["file"]]["raw"] + node = i["node"] + line = node.lineno - 1 + col = node.colno + if isinstance(node, MethodNode): + # The new data contains the source object as well + col = node.source_object.colno + elif isinstance(node, AssignmentNode): + col = node.var_name.colno + start = offsets[line] + col + end = start + if isinstance(node, (ArrayNode, FunctionNode, MethodNode)): + end = offsets[node.end_lineno - 1] + node.end_colno + elif isinstance(node, AssignmentNode): + end = offsets[node.value.end_lineno - 1] + node.value.end_colno + + # Only removal is supported for assignments + elif isinstance(node, AssignmentNode) and i["action"] == "rm": + if isinstance(node.value, (ArrayNode, FunctionNode, MethodNode)): + remove_node( + {"file": i["file"], "str": "", "node": node.value, "action": "rm"} + ) + raw = files[i["file"]]["raw"] + while raw[end] != "=": + end += 1 + end += 1 # Handle the '=' + while raw[end] in {" ", "\n", "\t"}: + end += 1 + + files[i["file"]]["raw"] = raw[:start] + i["str"] + raw[end:] + + for i in str_list: + if i["action"] in {"modify", "rm"}: + remove_node(i) + elif i["action"] == "add": + files[i["file"]]["raw"] += i["str"] + "\n" + + # Write the files back + for key, val in files.items(): + mlog.log("Rewriting", mlog.yellow(key)) + with open(val["path"], "w", encoding="utf-8") as fp: + fp.write(val["raw"]) + + +# Monkey patch the apply_changes method until https://github.com/mesonbuild/meson/pull/12899 is merged +Rewriter.apply_changes = apply_changes +# Monkey patch the update_python_sources method until this is upstreamed +Rewriter.process_update_python_sources = update_python_sources + +rewriter = Rewriter(options.sourcedir) +visitor = AstPython() +rewriter.interpreter.visitors += [visitor] +rewriter.analyze_meson() +rewriter.process_update_python_sources(visitor) +rewriter.apply_changes() +rewriter.print_info() + +# Run meson format +meson_format( + Namespace( + sources=[options.sourcedir], + inplace=True, + recursive=True, + output=None, + configuration=None, + editor_config=None, + ) +) diff --git a/tox.ini b/tox.ini index 2d90a0ba4f8..bb3840cb3ed 100644 --- a/tox.ini +++ b/tox.ini @@ -173,6 +173,7 @@ passenv = local: SKIP_CONFIGURE local: OPENBLAS_CONFIGURE local-direct: * + GITHUB_ACTIONS setenv = # By default, we bootstrap using autotools and do not allow downloads of the configure tarball. @@ -279,19 +280,15 @@ setenv = linuxmint-21.3: BASE_IMAGE=linuxmintd/mint21.3 # # https://hub.docker.com/_/fedora - # as of 2024-01, latest=39, rawhide=40 + # as of 2024-08, latest=40, rawhide=41 fedora: SYSTEM=fedora fedora: BASE_IMAGE=fedora + fedora: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-26: BASE_TAG=26 - fedora-26: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-27: BASE_TAG=27 - fedora-27: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-28: BASE_TAG=28 - fedora-28: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-29: BASE_TAG=29 - fedora-29: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-30: BASE_TAG=30 - fedora-30: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-31: BASE_TAG=31 fedora-32: BASE_TAG=32 fedora-33: BASE_TAG=33 @@ -299,13 +296,10 @@ setenv = fedora-35: BASE_TAG=35 fedora-36: BASE_TAG=36 fedora-37: BASE_TAG=37 - fedora-37: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-38: BASE_TAG=38 - fedora-38: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-39: BASE_TAG=39 - fedora-39: IGNORE_MISSING_SYSTEM_PACKAGES=yes fedora-40: BASE_TAG=40 - fedora-40: IGNORE_MISSING_SYSTEM_PACKAGES=yes + fedora-41: BASE_TAG=41 # # https://hub.docker.com/r/scientificlinux/sl # @@ -830,8 +824,8 @@ commands = local: config*) ;; \ local: *) make -k V=0 base-toolchain ;; \ local: esac && \ - local: make -k V=0 SAGE_CHECK=warn SAGE_CHECK_PACKAGES="!cython,!r,!python3,!gap,!cysignals,!linbox,!git,!ppl,!cmake,!rpy2,!sage_sws2rst" {env:TARGETS_PRE:} {posargs:build} && \ - local: ( [ -z "{env:TARGETS_OPTIONAL:}" ] || make -k V=0 SAGE_CHECK=warn SAGE_CHECK_PACKAGES="!cython,!r,!python3,!gap,!cysignals,!linbox,!git,!ppl,!cmake,!rpy2,!sage_sws2rst" {env:TARGETS_OPTIONAL:} || echo "(error ignored)" ) ' + local: make -k V=0 SAGE_CHECK=warn SAGE_CHECK_PACKAGES="!cython,!python3,!cysignals,!linbox,!ppl,!cmake,!rpy2,!sage_sws2rst" {env:TARGETS_PRE:} {posargs:build} && \ + local: ( [ -z "{env:TARGETS_OPTIONAL:}" ] || make -k V=0 SAGE_CHECK=warn SAGE_CHECK_PACKAGES="!cython,!python3,!cysignals,!linbox,!ppl,!cmake,!rpy2,!sage_sws2rst" {env:TARGETS_OPTIONAL:} || echo "(error ignored)" ) ' [testenv:check_configure] ## Test that configure behaves properly @@ -862,9 +856,8 @@ setenv = ubuntu-{xenial-toolchain-gcc_9,bionic-gcc_8,focal,jammy,lunar,mantic,noble} \ debian-{bullseye,bookworm,trixie,sid} \ linuxmint-{20.1,20.2,20.3,21,21.1,21.2,21.3} \ - fedora-{30,31,32,33,34,35,36,37,38,39,40} \ - centos-7-devtoolset-gcc_11 \ - centos-stream-9-python3.9 \ + fedora-{30,31,32,33,34,35,36,37,38,39,40,41} \ + centos-stream-{9,9-python3.12} \ almalinux-{8-python3.9,9-python3.11} \ gentoo-python{3.10,3.11,3.12} \ archlinux-latest \